aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/matplotlib
diff options
context:
space:
mode:
authormaxim-yurchuk <maxim-yurchuk@yandex-team.com>2025-02-11 13:26:52 +0300
committermaxim-yurchuk <maxim-yurchuk@yandex-team.com>2025-02-11 13:57:59 +0300
commitf895bba65827952ed934b2b46f9a45e30a191fd2 (patch)
tree03260c906d9ec41cdc03e2a496b15d407459cec0 /contrib/python/matplotlib
parent5f7060466f7b9707818c2091e1a25c14f33c3474 (diff)
downloadydb-f895bba65827952ed934b2b46f9a45e30a191fd2.tar.gz
Remove deps on pandas
<https://github.com/ydb-platform/ydb/pull/14418> <https://github.com/ydb-platform/ydb/pull/14419> \-- аналогичные правки в gh Хочу залить в обход синка, чтобы посмотреть удалится ли pandas в нашей gh репе через piglet commit_hash:abca127aa37d4dbb94b07e1e18cdb8eb5b711860
Diffstat (limited to 'contrib/python/matplotlib')
-rw-r--r--contrib/python/matplotlib/py2/.dist-info/METADATA38
-rw-r--r--contrib/python/matplotlib/py2/.dist-info/top_level.txt3
-rw-r--r--contrib/python/matplotlib/py2/LICENSE/LICENSE99
-rw-r--r--contrib/python/matplotlib/py2/LICENSE/LICENSE.PIL12
-rw-r--r--contrib/python/matplotlib/py2/LICENSE/LICENSE_AMSFONTS240
-rw-r--r--contrib/python/matplotlib/py2/LICENSE/LICENSE_BAKOMA40
-rw-r--r--contrib/python/matplotlib/py2/LICENSE/LICENSE_COLORBREWER38
-rw-r--r--contrib/python/matplotlib/py2/LICENSE/LICENSE_CONDA51
-rw-r--r--contrib/python/matplotlib/py2/LICENSE/LICENSE_JQUERY61
-rw-r--r--contrib/python/matplotlib/py2/LICENSE/LICENSE_QT4_EDITOR30
-rw-r--r--contrib/python/matplotlib/py2/LICENSE/LICENSE_STIX71
-rw-r--r--contrib/python/matplotlib/py2/LICENSE/LICENSE_YORICK49
-rw-r--r--contrib/python/matplotlib/py2/LICENSE/LICENSE_enthought.txt29
-rw-r--r--contrib/python/matplotlib/py2/LICENSE/Solarized.txt20
-rw-r--r--contrib/python/matplotlib/py2/LICENSE/pnpoly.license26
-rw-r--r--contrib/python/matplotlib/py2/README.rst83
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_alpha_mask_u8.h499
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_arc.h74
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_array.h1119
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_arrowhead.h82
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_basics.h560
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bezier_arc.h159
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bitset_iterator.h54
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_blur.h1503
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bounding_rect.h116
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bspline.h76
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_clip_liang_barsky.h333
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_color_gray.h1047
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_color_rgba.h1353
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_config.h44
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_adaptor_vcgen.h157
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_adaptor_vpgen.h159
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_bspline.h48
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_clip_polygon.h63
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_clip_polyline.h63
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_close_polygon.h125
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_concat.h73
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_contour.h65
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_curve.h201
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_dash.h68
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_gpc.h432
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_marker.h148
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_marker_adaptor.h51
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_segmentator.h48
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_shorten_path.h50
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_smooth_poly1.h80
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_stroke.h73
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_transform.h68
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_unclose_polygon.h52
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_curves.h693
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_dda_line.h290
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_ellipse.h123
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_ellipse_bresenham.h113
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_embedded_raster_fonts.h59
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_font_cache_manager.h409
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_font_cache_manager2.h311
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gamma_functions.h132
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gamma_lut.h305
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_glyph_raster_bin.h155
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gradient_lut.h244
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gsv_text.h153
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_image_accessors.h481
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_image_filters.h448
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_line_aa_basics.h189
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_math.h437
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_math_stroke.h527
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_path_length.h65
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_path_storage.h1545
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_path_storage_integer.h295
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pattern_filters_rgba.h123
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_amask_adaptor.h240
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_base.h97
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_gray.h737
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_rgb.h994
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_rgb_packed.h1312
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_rgba.h2801
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_transposer.h157
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_cells_aa.h743
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_compound_aa.h663
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_outline.h147
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_outline_aa.h599
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_scanline_aa.h481
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_scanline_aa_nogamma.h482
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_sl_clip.h351
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_base.h731
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_markers.h706
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_mclip.h349
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_outline_aa.h1837
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_outline_image.h1036
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_primitives.h224
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_raster_text.h264
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_scanline.h852
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rendering_buffer.h300
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rendering_buffer_dynarow.h137
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rounded_rect.h72
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_bin.h264
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_boolean_algebra.h1567
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_p.h329
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_storage_aa.h815
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_storage_bin.h586
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_u.h499
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_shorten_path.h66
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_simul_eq.h147
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_allocator.h54
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_converter.h56
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gouraud.h172
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gouraud_gray.h241
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gouraud_rgba.h277
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient.h377
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient_alpha.h126
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient_contour.h362
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient_image.h188
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter.h246
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter_gray.h723
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter_rgb.h861
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter_rgba.h890
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_adaptor.h77
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_linear.h232
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_persp.h462
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_trans.h92
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_pattern_gray.h93
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_pattern_rgb.h96
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_pattern_rgba.h94
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_solid.h53
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_subdiv_adaptor.h141
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_affine.h518
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_bilinear.h166
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_double_path.h131
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_perspective.h731
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_single_path.h97
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_viewport.h303
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_warp_magnifier.h56
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_bspline.h74
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_contour.h94
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_dash.h93
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_markers_term.h66
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_smooth_poly1.h87
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_stroke.h102
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_vertex_sequence.h135
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vertex_sequence.h172
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vpgen_clip_polygon.h83
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vpgen_clip_polyline.h78
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vpgen_segmentator.h61
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_bezier_ctrl.h196
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_cbox_ctrl.h112
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_ctrl.h118
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_gamma_ctrl.h170
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_gamma_spline.h95
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_polygon_ctrl.h166
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_rbox_ctrl.h141
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_scale_ctrl.h146
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_slider_ctrl.h150
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_spline_ctrl.h159
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/platform/agg_platform_support.h686
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/platform/mac/agg_mac_pmap.h87
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/platform/win32/agg_win32_bmp.h117
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/util/agg_color_conv.h128
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/util/agg_color_conv_rgb16.h285
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/include/util/agg_color_conv_rgb8.h476
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ChangeLog0
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_arc.cpp106
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_arrowhead.cpp110
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_bezier_arc.cpp258
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_bspline.cpp284
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_color_rgba.cpp17
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_curves.cpp613
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_embedded_raster_fonts.cpp10426
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_gsv_text.cpp675
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_image_filters.cpp103
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_line_aa_basics.cpp82
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_line_profile_aa.cpp116
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_rounded_rect.cpp164
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_sqrt_tables.cpp115
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_affine.cpp194
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_double_path.cpp273
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_single_path.cpp202
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_warp_magnifier.cpp70
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_bspline.cpp194
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_contour.cpp165
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_dash.cpp235
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_markers_term.cpp103
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_smooth_poly1.cpp225
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_stroke.cpp213
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vpgen_clip_polygon.cpp133
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vpgen_clip_polyline.cpp77
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vpgen_segmentator.cpp67
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/authors0
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/copying11
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp370
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp214
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp433
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp130
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp332
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp325
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp454
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp349
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp407
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp977
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp990
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp1601
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp298
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp1053
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp708
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp1655
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp631
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/ya.make24
-rw-r--r--contrib/python/matplotlib/py2/extern/ttconv/pprdrv.h113
-rw-r--r--contrib/python/matplotlib/py2/extern/ttconv/pprdrv_tt.cpp1484
-rw-r--r--contrib/python/matplotlib/py2/extern/ttconv/pprdrv_tt2.cpp736
-rw-r--r--contrib/python/matplotlib/py2/extern/ttconv/truetype.h129
-rw-r--r--contrib/python/matplotlib/py2/extern/ttconv/ttutil.cpp82
-rw-r--r--contrib/python/matplotlib/py2/extern/ttconv/ya.make15
-rw-r--r--contrib/python/matplotlib/py2/extern/ya.make4
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/__init__.py1928
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/_animation_data.py210
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/_cm.py1445
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/_cm_listed.py1298
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/_color_data.py1147
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/_constrained_layout.py666
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/_layoutbox.py739
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/_mathtext_data.py2548
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/_pylab_helpers.py138
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/_version.py21
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/afm.py547
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/animation.py1778
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/artist.py1482
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/axes/__init__.py5
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/axes/_axes.py8153
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/axes/_base.py4297
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/axes/_subplots.py267
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/axis.py2509
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backend_bases.py3383
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backend_managers.py436
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backend_tools.py1081
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/__init__.py97
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/_backend_tk.py1075
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/_gtk3_compat.py41
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_agg.py606
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_cairo.py520
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_gdk.py438
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_gtk.py1037
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_gtk3.py920
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_gtk3agg.py102
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_gtk3cairo.py55
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_gtkagg.py96
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_gtkcairo.py74
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_macosx.py210
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_mixed.py155
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_nbagg.py270
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_pdf.py2604
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_pgf.py990
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_ps.py1762
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_qt4.py15
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_qt4agg.py15
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_qt4cairo.py6
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_qt5.py1119
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_qt5agg.py105
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_qt5cairo.py49
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_svg.py1261
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_template.py278
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_tkagg.py34
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_tkcairo.py37
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_webagg.py350
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_webagg_core.py543
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_wx.py2002
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_wxagg.py147
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/backend_wxcairo.py53
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/qt_compat.py176
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/qt_editor/__init__.py2
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/qt_editor/figureoptions.py262
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/qt_editor/formlayout.py544
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/qt_editor/formsubplottool.py56
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/tkagg.py44
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/web_backend/all_figures.html43
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/boilerplate.css77
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/fbm.css97
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/page.css82
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/web_backend/ipython_inline_figure.html34
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/web_backend/jquery/js/jquery-1.11.3.js10351
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/web_backend/jquery/js/jquery-1.11.3.min.js5
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/mpl.js554
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/mpl_tornado.js7
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/nbagg_mpl.js208
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/web_backend/nbagg_uat.ipynb640
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/web_backend/single_figure.html30
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/windowing.py31
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/backends/wx_compat.py177
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/bezier.py495
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/blocking_input.py375
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/category.py211
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/cbook/__init__.py2888
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/cbook/_backports.py147
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/cbook/deprecation.py222
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/cm.py392
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/collections.py1994
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/colorbar.py1405
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/colors.py2030
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/compat/__init__.py0
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/compat/subprocess.py51
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/container.py194
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/contour.py1832
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/dates.py1839
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/docstring.py128
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/dviread.py1083
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/figure.py2532
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/font_manager.py1481
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/fontconfig_pattern.py196
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/gridspec.py498
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/hatch.py220
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/image.py1534
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/legend.py1401
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/legend_handler.py730
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/lines.py1507
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/markers.py898
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/mathtext.py3445
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/mlab.py4041
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/offsetbox.py1811
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/patches.py4720
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/path.py1028
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/patheffects.py393
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/projections/__init__.py110
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/projections/geo.py547
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/projections/polar.py1537
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/pylab.py268
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/pyplot.py4099
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/quiver.py1197
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/rcsetup.py1452
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sankey.py833
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/scale.py607
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sphinxext/__init__.py2
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sphinxext/mathmpl.py126
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sphinxext/only_directives.py75
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sphinxext/plot_directive.py849
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/__init__.py1
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/conftest.py6
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/test_tinypages.py64
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/.gitignore1
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/README.md3
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/_static/.gitignore0
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/_static/README.txt7
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/conf.py264
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/index.rst21
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/range4.py5
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/range6.py13
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/some_plots.rst129
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/spines.py542
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/stackplot.py126
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/streamplot.py674
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/style/__init__.py3
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/style/core.py234
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/table.py702
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/__init__.py59
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/_nose/__init__.py78
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/_nose/decorators.py33
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/_nose/exceptions.py10
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/_nose/plugins/__init__.py0
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/_nose/plugins/knownfailure.py49
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/_nose/plugins/performgc.py26
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/compare.py489
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/conftest.py100
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/decorators.py589
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/determinism.py145
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/disable_internet.py150
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/exceptions.py4
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/Duration.py211
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/Epoch.py238
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/EpochConverter.py165
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/StrConverter.py164
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/UnitDbl.py297
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/UnitDblConverter.py159
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/UnitDblFormatter.py47
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/__init__.py88
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/testing/noseclasses.py26
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/texmanager.py505
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/text.py2336
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/textpath.py536
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/ticker.py2628
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/tight_bbox.py87
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/tight_layout.py381
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/transforms.py3025
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/tri/__init__.py16
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/tri/_tri.cpp1999
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/tri/_tri.h815
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/tri/_tri_wrapper.cpp550
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/tri/triangulation.py218
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/tri/tricontour.py283
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/tri/trifinder.py96
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/tri/triinterpolate.py1637
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/tri/tripcolor.py154
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/tri/triplot.py88
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/tri/trirefine.py323
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/tri/tritools.py304
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/tri/ya.make43
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/type1font.py334
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/units.py200
-rw-r--r--contrib/python/matplotlib/py2/matplotlib/widgets.py2818
-rw-r--r--contrib/python/matplotlib/py2/matplotlibrc.template618
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/__init__.py4
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/ChangeLog13
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/__init__.py15
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/anchored_artists.py9
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/angle_helper.py4
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axes_divider.py8
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axes_grid.py30
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axes_rgb.py11
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axes_size.py4
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axis_artist.py4
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axisline_style.py4
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axislines.py4
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/clip_path.py4
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/colorbar.py5
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/floating_axes.py4
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/grid_finder.py4
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/grid_helper_curvelinear.py4
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/inset_locator.py7
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/parasite_axes.py18
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/__init__.py12
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/anchored_artists.py376
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/axes_divider.py975
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/axes_grid.py771
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/axes_rgb.py228
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/axes_size.py323
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/colorbar.py836
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/inset_locator.py659
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/mpl_axes.py154
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/parasite_axes.py486
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/__init__.py26
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/angle_helper.py416
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_divider.py9
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_grid.py30
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_rgb.py11
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axis_artist.py1527
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axisline_style.py168
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axislines.py828
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/clip_path.py135
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/floating_axes.py544
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/grid_finder.py340
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/grid_helper_curvelinear.py475
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/axisartist/parasite_axes.py18
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/__init__.py6
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/art3d.py774
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/axes3d.py2958
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/axis3d.py484
-rw-r--r--contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/proj3d.py203
-rw-r--r--contrib/python/matplotlib/py2/pylab.py3
-rw-r--r--contrib/python/matplotlib/py2/src/_backend_agg.cpp234
-rw-r--r--contrib/python/matplotlib/py2/src/_backend_agg.h1294
-rw-r--r--contrib/python/matplotlib/py2/src/_backend_agg_basic_types.h127
-rw-r--r--contrib/python/matplotlib/py2/src/_backend_agg_wrapper.cpp777
-rw-r--r--contrib/python/matplotlib/py2/src/_backend_gdk.c72
-rw-r--r--contrib/python/matplotlib/py2/src/_contour.cpp1790
-rw-r--r--contrib/python/matplotlib/py2/src/_contour.h530
-rw-r--r--contrib/python/matplotlib/py2/src/_contour_wrapper.cpp203
-rw-r--r--contrib/python/matplotlib/py2/src/_gtkagg.cpp155
-rw-r--r--contrib/python/matplotlib/py2/src/_image.cpp175
-rw-r--r--contrib/python/matplotlib/py2/src/_image.h200
-rw-r--r--contrib/python/matplotlib/py2/src/_image_resample.h1013
-rw-r--r--contrib/python/matplotlib/py2/src/_image_wrapper.cpp510
-rw-r--r--contrib/python/matplotlib/py2/src/_macosx.m3174
-rw-r--r--contrib/python/matplotlib/py2/src/_path.h1316
-rw-r--r--contrib/python/matplotlib/py2/src/_path_wrapper.cpp900
-rw-r--r--contrib/python/matplotlib/py2/src/_png.cpp793
-rw-r--r--contrib/python/matplotlib/py2/src/_tkagg.cpp475
-rw-r--r--contrib/python/matplotlib/py2/src/_tkmini.h128
-rw-r--r--contrib/python/matplotlib/py2/src/_ttconv.cpp307
-rw-r--r--contrib/python/matplotlib/py2/src/_windowing.cpp64
-rw-r--r--contrib/python/matplotlib/py2/src/agg_workaround.h85
-rw-r--r--contrib/python/matplotlib/py2/src/array.h80
-rw-r--r--contrib/python/matplotlib/py2/src/file_compat.h240
-rw-r--r--contrib/python/matplotlib/py2/src/ft2font.cpp808
-rw-r--r--contrib/python/matplotlib/py2/src/ft2font.h139
-rw-r--r--contrib/python/matplotlib/py2/src/ft2font_wrapper.cpp1808
-rw-r--r--contrib/python/matplotlib/py2/src/mplutils.cpp21
-rw-r--r--contrib/python/matplotlib/py2/src/mplutils.h73
-rw-r--r--contrib/python/matplotlib/py2/src/numpy_cpp.h569
-rw-r--r--contrib/python/matplotlib/py2/src/path_cleanup.cpp113
-rw-r--r--contrib/python/matplotlib/py2/src/path_cleanup.h27
-rw-r--r--contrib/python/matplotlib/py2/src/path_converters.h1011
-rw-r--r--contrib/python/matplotlib/py2/src/py_adaptors.h251
-rw-r--r--contrib/python/matplotlib/py2/src/py_converters.cpp619
-rw-r--r--contrib/python/matplotlib/py2/src/py_converters.h49
-rw-r--r--contrib/python/matplotlib/py2/src/py_exceptions.h72
-rw-r--r--contrib/python/matplotlib/py2/src/qhull_wrap.c378
-rw-r--r--contrib/python/matplotlib/py2/src/ya.make68
-rw-r--r--contrib/python/matplotlib/py2/ya.make243
-rw-r--r--contrib/python/matplotlib/py3/.dist-info/METADATA125
-rw-r--r--contrib/python/matplotlib/py3/.dist-info/top_level.txt3
-rw-r--r--contrib/python/matplotlib/py3/.yandex_meta/yamaker.yaml20
-rw-r--r--contrib/python/matplotlib/py3/LICENSE99
-rw-r--r--contrib/python/matplotlib/py3/LICENSE_AMSFONTS240
-rw-r--r--contrib/python/matplotlib/py3/LICENSE_BAKOMA40
-rw-r--r--contrib/python/matplotlib/py3/LICENSE_CARLOGO45
-rw-r--r--contrib/python/matplotlib/py3/LICENSE_COLORBREWER13
-rw-r--r--contrib/python/matplotlib/py3/LICENSE_COURIERTEN18
-rw-r--r--contrib/python/matplotlib/py3/LICENSE_JSXTOOLS_RESIZE_OBSERVER108
-rw-r--r--contrib/python/matplotlib/py3/LICENSE_QHULL39
-rw-r--r--contrib/python/matplotlib/py3/LICENSE_QT4_EDITOR30
-rw-r--r--contrib/python/matplotlib/py3/LICENSE_SOLARIZED20
-rw-r--r--contrib/python/matplotlib/py3/LICENSE_STIX71
-rw-r--r--contrib/python/matplotlib/py3/LICENSE_YORICK49
-rw-r--r--contrib/python/matplotlib/py3/README.md73
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_alpha_mask_u8.h499
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_arc.h74
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_array.h1119
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_arrowhead.h82
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_basics.h560
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bezier_arc.h159
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bitset_iterator.h54
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_blur.h1503
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bounding_rect.h116
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bspline.h76
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_clip_liang_barsky.h333
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_color_gray.h1047
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_color_rgba.h1353
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_config.h44
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_adaptor_vcgen.h157
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_adaptor_vpgen.h159
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_bspline.h48
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_clip_polygon.h63
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_clip_polyline.h63
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_close_polygon.h125
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_concat.h73
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_contour.h65
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_curve.h201
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_dash.h68
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_gpc.h432
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_marker.h148
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_marker_adaptor.h51
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_segmentator.h48
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_shorten_path.h50
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_smooth_poly1.h80
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_stroke.h73
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_transform.h68
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_unclose_polygon.h52
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_curves.h693
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_dda_line.h290
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_ellipse.h123
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_ellipse_bresenham.h113
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_embedded_raster_fonts.h59
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_font_cache_manager.h409
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_font_cache_manager2.h311
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gamma_functions.h132
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gamma_lut.h305
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_glyph_raster_bin.h155
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gradient_lut.h244
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gsv_text.h153
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_image_accessors.h481
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_image_filters.h448
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_line_aa_basics.h189
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_math.h437
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_math_stroke.h527
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_length.h65
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_storage.h1545
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_storage_integer.h295
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pattern_filters_rgba.h123
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_amask_adaptor.h240
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_base.h97
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_gray.h737
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgb.h994
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgb_packed.h1312
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgba.h2801
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_transposer.h157
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_cells_aa.h743
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_compound_aa.h663
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_outline.h147
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_outline_aa.h599
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_scanline_aa.h481
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_scanline_aa_nogamma.h482
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_sl_clip.h351
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_base.h731
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_markers.h706
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_mclip.h349
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_outline_aa.h1837
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_outline_image.h1036
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_primitives.h224
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_raster_text.h264
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_scanline.h852
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rendering_buffer.h300
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rendering_buffer_dynarow.h137
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rounded_rect.h72
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_bin.h264
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_boolean_algebra.h1567
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_p.h329
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_storage_aa.h815
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_storage_bin.h586
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_u.h499
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_shorten_path.h66
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_simul_eq.h147
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_allocator.h54
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_converter.h56
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud.h172
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud_gray.h241
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud_rgba.h277
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient.h377
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_alpha.h126
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_contour.h362
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_image.h188
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter.h246
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_gray.h723
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_rgb.h861
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_rgba.h890
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_adaptor.h77
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_linear.h232
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_persp.h462
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_trans.h92
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_gray.h93
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_rgb.h96
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_rgba.h94
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_solid.h53
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_subdiv_adaptor.h141
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_affine.h518
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_bilinear.h166
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_double_path.h131
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_perspective.h731
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_single_path.h97
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_viewport.h303
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_warp_magnifier.h56
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_bspline.h74
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_contour.h94
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_dash.h93
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_markers_term.h66
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_smooth_poly1.h87
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_stroke.h102
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_vertex_sequence.h135
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vertex_sequence.h172
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_clip_polygon.h83
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_clip_polyline.h78
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_segmentator.h61
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_bezier_ctrl.h196
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_cbox_ctrl.h112
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_ctrl.h118
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_gamma_ctrl.h170
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_gamma_spline.h95
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_polygon_ctrl.h166
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_rbox_ctrl.h141
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_scale_ctrl.h146
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_slider_ctrl.h150
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_spline_ctrl.h159
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/agg_platform_support.h686
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/mac/agg_mac_pmap.h87
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/win32/agg_win32_bmp.h117
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv.h128
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv_rgb16.h285
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv_rgb8.h476
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/ChangeLog0
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_arc.cpp106
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_arrowhead.cpp110
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_bezier_arc.cpp258
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_bspline.cpp284
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_color_rgba.cpp17
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_curves.cpp613
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_embedded_raster_fonts.cpp10426
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_gsv_text.cpp675
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_image_filters.cpp103
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_line_aa_basics.cpp82
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_line_profile_aa.cpp116
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_rounded_rect.cpp164
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_sqrt_tables.cpp115
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_affine.cpp194
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_double_path.cpp273
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_single_path.cpp202
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_warp_magnifier.cpp70
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_bspline.cpp194
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_contour.cpp165
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_dash.cpp235
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_markers_term.cpp103
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_smooth_poly1.cpp225
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_stroke.cpp213
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_clip_polygon.cpp133
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_clip_polyline.cpp77
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_segmentator.cpp67
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/authors0
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/copying11
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp370
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp214
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp433
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp130
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp332
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp325
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp454
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp349
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp407
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp977
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp990
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp1601
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp298
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp1053
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp708
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp1655
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp631
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/ya.make24
-rw-r--r--contrib/python/matplotlib/py3/extern/ttconv/pprdrv.h102
-rw-r--r--contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt.cpp1401
-rw-r--r--contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt2.cpp693
-rw-r--r--contrib/python/matplotlib/py3/extern/ttconv/truetype.h129
-rw-r--r--contrib/python/matplotlib/py3/extern/ttconv/ttutil.cpp71
-rw-r--r--contrib/python/matplotlib/py3/extern/ttconv/ya.make15
-rw-r--r--contrib/python/matplotlib/py3/extern/ya.make4
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/__init__.py1519
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/__init__.pyi113
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_afm.py532
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_animation_data.py262
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_api/__init__.py381
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_api/__init__.pyi59
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_api/deprecation.py510
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_api/deprecation.pyi76
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_blocking_input.py30
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_c_internal_utils.pyi1
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_cm.py1440
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_cm_listed.py2071
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_color_data.py1141
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_color_data.pyi6
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_constrained_layout.py794
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_docstring.py97
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_docstring.pyi29
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_enums.py185
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_enums.pyi18
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_fontconfig_pattern.py120
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_image.pyi0
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_internal_utils.py64
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_layoutgrid.py547
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_mathtext.py2851
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_mathtext_data.py1311
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_path.pyi9
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_pylab_helpers.py135
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_pylab_helpers.pyi29
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_qhull.pyi0
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_text_helpers.py74
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_tight_bbox.py84
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_tight_layout.py301
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_tri.pyi23
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_ttconv.pyi0
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_type1font.py876
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/_version.py16
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/animation.py1804
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/animation.pyi219
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/artist.py1860
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/artist.pyi181
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/axes/__init__.py18
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/axes/__init__.pyi16
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/axes/_axes.py8454
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/axes/_axes.pyi767
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/axes/_base.py4644
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/axes/_base.pyi453
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/axes/_secondary_axes.py283
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/axes/_secondary_axes.pyi42
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/axis.py2766
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/axis.pyi278
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backend_bases.py3483
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backend_bases.pyi490
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backend_managers.py387
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backend_managers.pyi64
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backend_tools.py1003
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backend_tools.pyi121
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/__init__.py3
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/_backend_agg.pyi0
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/_backend_gtk.py332
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/_backend_pdf_ps.py145
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/_backend_tk.py1074
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/_macosx.pyi0
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/_tkagg.pyi0
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_agg.py544
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_cairo.py500
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk3.py587
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk3agg.py69
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk3cairo.py26
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk4.py606
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk4agg.py36
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk4cairo.py28
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_macosx.py236
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_mixed.py119
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_nbagg.py243
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_pdf.py2827
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_pgf.py1009
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_ps.py1340
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_qt.py1022
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_qt5.py28
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_qt5agg.py14
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_qt5cairo.py11
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_qtagg.py86
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_qtcairo.py46
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_svg.py1368
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_template.py213
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_tkagg.py20
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_tkcairo.py26
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_webagg.py352
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_webagg_core.py518
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_wx.py1332
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_wxagg.py43
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/backend_wxcairo.py23
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/qt_compat.py230
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/qt_editor/__init__.py0
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/qt_editor/_formlayout.py592
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/qt_editor/figureoptions.py263
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/web_backend/.eslintrc.js32
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/web_backend/.prettierignore7
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/web_backend/.prettierrc11
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/web_backend/all_figures.html52
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/web_backend/css/boilerplate.css77
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/web_backend/css/fbm.css97
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/web_backend/css/mpl.css84
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/web_backend/css/page.css82
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/web_backend/ipython_inline_figure.html34
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/web_backend/js/mpl.js695
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/web_backend/js/mpl_tornado.js8
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/web_backend/js/nbagg_mpl.js275
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/web_backend/nbagg_uat.ipynb631
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/web_backend/package.json18
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/backends/web_backend/single_figure.html39
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/bezier.py594
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/bezier.pyi74
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/category.py233
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/cbook.py2350
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/cbook.pyi175
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/cm.py745
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/cm.pyi54
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/collections.py2394
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/collections.pyi242
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/colorbar.py1580
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/colorbar.pyi136
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/colors.py2762
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/colors.pyi354
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/container.py141
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/container.pyi56
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/contour.py1902
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/contour.pyi169
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/dates.py1894
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/dviread.py1149
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/dviread.pyi90
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/figure.py3626
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/figure.pyi416
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/font_manager.py1584
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/font_manager.pyi136
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/ft2font.pyi253
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/gridspec.py738
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/gridspec.pyi134
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/hatch.py225
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/hatch.pyi68
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/image.py1785
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/image.pyi209
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/layout_engine.py304
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/layout_engine.pyi62
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/legend.py1384
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/legend.pyi154
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/legend_handler.py813
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/legend_handler.pyi294
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/lines.py1677
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/lines.pyi153
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/markers.py917
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/markers.pyi51
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mathtext.py140
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mathtext.pyi33
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mlab.py914
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mlab.pyi100
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmex10.afm220
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmmi10.afm326
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmr10.afm343
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmsy10.afm195
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmtt10.afm156
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pagd8a.afm576
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pagdo8a.afm576
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pagk8a.afm573
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pagko8a.afm573
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pbkd8a.afm415
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pbkdi8a.afm417
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pbkl8a.afm407
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pbkli8a.afm410
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pcrb8a.afm344
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pcrbo8a.afm344
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pcrr8a.afm344
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pcrro8a.afm344
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvb8a.afm570
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvb8an.afm570
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvbo8a.afm570
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvbo8an.afm570
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvl8a.afm445
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvlo8a.afm445
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvr8a.afm612
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvr8an.afm612
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvro8a.afm612
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvro8an.afm612
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pncb8a.afm472
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pncbi8a.afm602
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pncr8a.afm524
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pncri8a.afm536
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pplb8a.afm434
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pplbi8a.afm441
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pplr8a.afm445
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pplri8a.afm439
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/psyr.afm209
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/ptmb8a.afm648
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/ptmbi8a.afm648
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/ptmr8a.afm648
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/ptmri8a.afm648
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/putb8a.afm1005
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/putbi8a.afm1017
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/putr8a.afm1029
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/putri8a.afm1008
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pzcmi8a.afm480
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pzdr.afm222
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Bold.afm342
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-BoldOblique.afm342
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Oblique.afm342
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Courier.afm342
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Bold.afm2827
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-BoldOblique.afm2827
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Oblique.afm3051
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica.afm3051
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Symbol.afm213
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Bold.afm2588
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Times-BoldItalic.afm2384
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Italic.afm2667
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Roman.afm2419
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/ZapfDingbats.afm225
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/readme.txt15
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Bold.ttfbin704128 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSans-BoldOblique.ttfbin641720 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Oblique.ttfbin633840 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttfbin756072 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansDisplay.ttfbin25712 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Bold.ttfbin331536 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-BoldOblique.ttfbin253116 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Oblique.ttfbin251472 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono.ttfbin340240 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Bold.ttfbin355692 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-BoldItalic.ttfbin347064 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Italic.ttfbin345612 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerif.ttfbin379740 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerifDisplay.ttfbin14300 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/LICENSE_DEJAVU99
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/LICENSE_STIX124
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXGeneral.ttfbin448228 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXGeneralBol.ttfbin237360 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXGeneralBolIta.ttfbin181152 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXGeneralItalic.ttfbin175040 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXNonUni.ttfbin59108 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXNonUniBol.ttfbin30512 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXNonUniBolIta.ttfbin41272 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXNonUniIta.ttfbin46752 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizFiveSymReg.ttfbin13656 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizFourSymBol.ttfbin12228 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizFourSymReg.ttfbin15972 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymBol.ttfbin12556 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymReg.ttfbin19760 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymBol.ttfbin12192 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymReg.ttfbin15836 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymBol.ttfbin12116 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymReg.ttfbin15704 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmb10.ttfbin25680 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmex10.ttfbin21092 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmmi10.ttfbin32560 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmr10.ttfbin26348 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmss10.ttfbin20376 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmsy10.ttfbin29396 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmtt10.ttfbin28136 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back-symbolic.svg46
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back.pdfbin1623 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back.pngbin380 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back.svg46
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back_large.pngbin620 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave-symbolic.svg68
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave.pdf70
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave.pngbin458 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave.svg68
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave_large.pngbin720 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward-symbolic.svg46
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward.pdfbin1630 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward.pngbin357 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward.svg46
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward_large.pngbin593 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/hand.pdfbin4172 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/hand.pngbin979 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/hand.svg130
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help-symbolic.svg52
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help.pdf68
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help.pngbin472 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help.svg52
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help_large.pngbin747 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home-symbolic.svg59
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home.pdfbin1737 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home.pngbin468 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home.svg59
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home_large.pngbin790 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/matplotlib.pdfbin22852 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/matplotlib.pngbin1283 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/matplotlib.svg3171
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/matplotlib_large.pngbin3088 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move-symbolic.svg73
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move.pdfbin1867 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move.pngbin481 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move.svg73
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move_large.pngbin767 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/qt4_editor_options.pdfbin1568 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/qt4_editor_options.pngbin380 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/qt4_editor_options.svg48
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/qt4_editor_options_large.pngbin619 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots-symbolic.svg81
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots.pdfbin1714 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots.pngbin445 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots.svg81
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots_large.pngbin662 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect-symbolic.svg40
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect.pdf68
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect.pngbin530 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect.svg40
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect_large.pngbin1016 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/kpsewhich.lua3
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/matplotlibrc798
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/plot_directive/plot_directive.css16
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/Minduka_Present_Blue_Pack.pngbin13634 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/README.txt2
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/Stocks.csv526
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/axes_grid/bivariate_normal.npybin1880 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/data_x_x2_x3.csv11
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/eeg.datbin25600 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/embedding_in_wx3.xrc65
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/goog.npzbin22845 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/grace_hopper.jpgbin61306 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/jacksboro_fault_dem.npzbin174061 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/logo2.pngbin22279 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/membrane.datbin48000 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/msft.csv66
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/s1045.ima.gzbin33229 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/topobathy.npzbin45224 -> 0 bytes
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/Solarize_Light2.mplstyle53
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/_classic_test_patch.mplstyle6
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/_mpl-gallery-nogrid.mplstyle19
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/_mpl-gallery.mplstyle19
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/bmh.mplstyle29
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/classic.mplstyle492
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/dark_background.mplstyle29
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/fast.mplstyle11
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/fivethirtyeight.mplstyle40
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/ggplot.mplstyle39
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/grayscale.mplstyle29
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-bright.mplstyle3
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-colorblind.mplstyle3
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-dark-palette.mplstyle3
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-dark.mplstyle30
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-darkgrid.mplstyle30
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-deep.mplstyle3
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-muted.mplstyle3
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-notebook.mplstyle21
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-paper.mplstyle21
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-pastel.mplstyle3
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-poster.mplstyle21
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-talk.mplstyle21
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-ticks.mplstyle30
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-white.mplstyle30
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-whitegrid.mplstyle30
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8.mplstyle57
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/tableau-colorblind10.mplstyle3
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/offsetbox.py1604
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/offsetbox.pyi321
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/patches.py4634
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/patches.pyi751
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/path.py1093
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/path.pyi140
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/patheffects.py513
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/patheffects.pyi106
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/projections/__init__.py126
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/projections/__init__.pyi15
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/projections/geo.py510
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/projections/geo.pyi112
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/projections/polar.py1536
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/projections/polar.pyi196
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/py.typed0
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/pylab.py65
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/pyplot.py4373
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/quiver.py1181
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/quiver.pyi187
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/rcsetup.py1346
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/rcsetup.pyi157
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/sankey.py814
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/sankey.pyi61
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/scale.py756
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/scale.pyi178
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/sphinxext/__init__.py0
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/sphinxext/figmpl_directive.py288
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/sphinxext/mathmpl.py239
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/sphinxext/plot_directive.py933
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/spines.py595
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/spines.pyi83
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/stackplot.py127
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/stackplot.pyi17
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/streamplot.py712
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/streamplot.pyi82
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/style/__init__.py4
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/style/core.py245
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/style/core.pyi19
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/table.py831
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/table.pyi85
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/__init__.py174
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/__init__.pyi49
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/_markers.py49
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/compare.py515
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/compare.pyi32
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/conftest.py100
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/conftest.pyi12
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/decorators.py464
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/decorators.pyi25
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/exceptions.py4
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/Duration.py138
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/Epoch.py211
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/EpochConverter.py96
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/StrConverter.py97
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/UnitDbl.py180
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/UnitDblConverter.py85
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/UnitDblFormatter.py28
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/__init__.py76
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/widgets.py119
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/testing/widgets.pyi31
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/texmanager.py368
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/texmanager.pyi38
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/text.py2023
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/text.pyi214
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/textpath.py397
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/textpath.pyi74
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/ticker.py2942
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/ticker.pyi301
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/transforms.py2975
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/transforms.pyi335
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/__init__.py23
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/_triangulation.py247
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/_triangulation.pyi33
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/_tricontour.py272
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/_tricontour.pyi52
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/_trifinder.py96
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/_trifinder.pyi10
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/_triinterpolate.py1574
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/_triinterpolate.pyi30
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/_tripcolor.py149
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/_tripcolor.pyi71
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/_triplot.py86
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/_triplot.pyi15
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/_trirefine.py307
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/_trirefine.pyi31
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/_tritools.py263
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/_tritools.pyi12
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/triangulation.py9
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/tricontour.py9
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/trifinder.py9
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/triinterpolate.py9
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/tripcolor.py9
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/triplot.py9
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/trirefine.py9
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/tri/tritools.py9
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/typing.py60
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/units.py195
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/widgets.py4243
-rw-r--r--contrib/python/matplotlib/py3/matplotlib/widgets.pyi487
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/__init__.py10
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/anchored_artists.py462
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_divider.py694
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_grid.py550
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_rgb.py157
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_size.py248
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/inset_locator.py561
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/mpl_axes.py128
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/parasite_axes.py257
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axisartist/__init__.py13
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axisartist/angle_helper.py394
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axes_divider.py2
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axes_grid.py23
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axes_rgb.py18
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axis_artist.py1115
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axisline_style.py193
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axislines.py531
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axisartist/floating_axes.py298
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axisartist/grid_finder.py335
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axisartist/grid_helper_curvelinear.py336
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/axisartist/parasite_axes.py7
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/__init__.py3
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/art3d.py1252
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/axes3d.py3448
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/axis3d.py753
-rw-r--r--contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/proj3d.py259
-rw-r--r--contrib/python/matplotlib/py3/patches/01-arcadia.patch53
-rw-r--r--contrib/python/matplotlib/py3/patches/02-fix-ya.make.patch16
-rw-r--r--contrib/python/matplotlib/py3/patches/03-add-missing-include.patch11
-rw-r--r--contrib/python/matplotlib/py3/patches/04-fix-relative-paths-web-backend.patch50
-rw-r--r--contrib/python/matplotlib/py3/pylab.py3
-rw-r--r--contrib/python/matplotlib/py3/src/_backend_agg.cpp176
-rw-r--r--contrib/python/matplotlib/py3/src/_backend_agg.h1280
-rw-r--r--contrib/python/matplotlib/py3/src/_backend_agg_basic_types.h123
-rw-r--r--contrib/python/matplotlib/py3/src/_backend_agg_wrapper.cpp646
-rw-r--r--contrib/python/matplotlib/py3/src/_c_internal_utils.c211
-rw-r--r--contrib/python/matplotlib/py3/src/_image_resample.h834
-rw-r--r--contrib/python/matplotlib/py3/src/_image_wrapper.cpp297
-rw-r--r--contrib/python/matplotlib/py3/src/_path.h1251
-rw-r--r--contrib/python/matplotlib/py3/src/_path_wrapper.cpp772
-rw-r--r--contrib/python/matplotlib/py3/src/_qhull_wrapper.cpp340
-rw-r--r--contrib/python/matplotlib/py3/src/_tkagg.cpp370
-rw-r--r--contrib/python/matplotlib/py3/src/_tkmini.h110
-rw-r--r--contrib/python/matplotlib/py3/src/_ttconv.cpp96
-rw-r--r--contrib/python/matplotlib/py3/src/agg_workaround.h85
-rw-r--r--contrib/python/matplotlib/py3/src/array.h80
-rw-r--r--contrib/python/matplotlib/py3/src/checkdep_freetype2.c19
-rw-r--r--contrib/python/matplotlib/py3/src/ft2font.cpp840
-rw-r--r--contrib/python/matplotlib/py3/src/ft2font.h159
-rw-r--r--contrib/python/matplotlib/py3/src/ft2font_wrapper.cpp1578
-rw-r--r--contrib/python/matplotlib/py3/src/mplutils.h99
-rw-r--r--contrib/python/matplotlib/py3/src/numpy_cpp.h578
-rw-r--r--contrib/python/matplotlib/py3/src/path_converters.h1106
-rw-r--r--contrib/python/matplotlib/py3/src/py_adaptors.h248
-rw-r--r--contrib/python/matplotlib/py3/src/py_converters.cpp558
-rw-r--r--contrib/python/matplotlib/py3/src/py_converters.h48
-rw-r--r--contrib/python/matplotlib/py3/src/py_exceptions.h72
-rw-r--r--contrib/python/matplotlib/py3/src/tri/_tri.cpp2074
-rw-r--r--contrib/python/matplotlib/py3/src/tri/_tri.h799
-rw-r--r--contrib/python/matplotlib/py3/src/tri/_tri_wrapper.cpp58
-rw-r--r--contrib/python/matplotlib/py3/ya.make583
-rw-r--r--contrib/python/matplotlib/ya.make20
1213 files changed, 0 insertions, 557887 deletions
diff --git a/contrib/python/matplotlib/py2/.dist-info/METADATA b/contrib/python/matplotlib/py2/.dist-info/METADATA
deleted file mode 100644
index 04815e8628..0000000000
--- a/contrib/python/matplotlib/py2/.dist-info/METADATA
+++ /dev/null
@@ -1,38 +0,0 @@
-Metadata-Version: 2.1
-Name: matplotlib
-Version: 2.2.5
-Summary: Python plotting package
-Home-page: http://matplotlib.org
-Author: John D. Hunter, Michael Droettboom
-Author-email: matplotlib-users@python.org
-License: PSF
-Download-URL: http://matplotlib.org/users/installing.html
-Platform: any
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Science/Research
-Classifier: License :: OSI Approved :: Python Software Foundation License
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Programming Language :: Python :: 3.6
-Classifier: Programming Language :: Python :: 3.7
-Classifier: Topic :: Scientific/Engineering :: Visualization
-Requires-Dist: numpy (>=1.7.1)
-Requires-Dist: cycler (>=0.10)
-Requires-Dist: pyparsing (!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1)
-Requires-Dist: python-dateutil (>=2.1)
-Requires-Dist: pytz
-Requires-Dist: six (>=1.10)
-Requires-Dist: kiwisolver (>=1.0.1)
-Requires-Dist: backports.functools-lru-cache
-Requires-Dist: subprocess32
-
-matplotlib strives to produce publication quality 2D graphics
-for interactive graphing, scientific publishing, user interface
-development and web application servers targeting multiple user
-interfaces and hardcopy output formats. There is a 'pylab' mode
-which emulates matlab graphics.
-
-
diff --git a/contrib/python/matplotlib/py2/.dist-info/top_level.txt b/contrib/python/matplotlib/py2/.dist-info/top_level.txt
deleted file mode 100644
index 0eb77e4d99..0000000000
--- a/contrib/python/matplotlib/py2/.dist-info/top_level.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-matplotlib
-mpl_toolkits
-pylab
diff --git a/contrib/python/matplotlib/py2/LICENSE/LICENSE b/contrib/python/matplotlib/py2/LICENSE/LICENSE
deleted file mode 100644
index ec51537db2..0000000000
--- a/contrib/python/matplotlib/py2/LICENSE/LICENSE
+++ /dev/null
@@ -1,99 +0,0 @@
-License agreement for matplotlib versions 1.3.0 and later
-=========================================================
-
-1. This LICENSE AGREEMENT is between the Matplotlib Development Team
-("MDT"), and the Individual or Organization ("Licensee") accessing and
-otherwise using matplotlib software in source or binary form and its
-associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, MDT
-hereby grants Licensee a nonexclusive, royalty-free, world-wide license
-to reproduce, analyze, test, perform and/or display publicly, prepare
-derivative works, distribute, and otherwise use matplotlib
-alone or in any derivative version, provided, however, that MDT's
-License Agreement and MDT's notice of copyright, i.e., "Copyright (c)
-2012- Matplotlib Development Team; All Rights Reserved" are retained in
-matplotlib alone or in any derivative version prepared by
-Licensee.
-
-3. In the event Licensee prepares a derivative work that is based on or
-incorporates matplotlib or any part thereof, and wants to
-make the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to matplotlib .
-
-4. MDT is making matplotlib available to Licensee on an "AS
-IS" basis. MDT MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, MDT MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB
-WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. MDT SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF MATPLOTLIB
- FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR
-LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING
-MATPLOTLIB , OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF
-THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. Nothing in this License Agreement shall be deemed to create any
-relationship of agency, partnership, or joint venture between MDT and
-Licensee. This License Agreement does not grant permission to use MDT
-trademarks or trade name in a trademark sense to endorse or promote
-products or services of Licensee, or any third party.
-
-8. By copying, installing or otherwise using matplotlib ,
-Licensee agrees to be bound by the terms and conditions of this License
-Agreement.
-
-License agreement for matplotlib versions prior to 1.3.0
-========================================================
-
-1. This LICENSE AGREEMENT is between John D. Hunter ("JDH"), and the
-Individual or Organization ("Licensee") accessing and otherwise using
-matplotlib software in source or binary form and its associated
-documentation.
-
-2. Subject to the terms and conditions of this License Agreement, JDH
-hereby grants Licensee a nonexclusive, royalty-free, world-wide license
-to reproduce, analyze, test, perform and/or display publicly, prepare
-derivative works, distribute, and otherwise use matplotlib
-alone or in any derivative version, provided, however, that JDH's
-License Agreement and JDH's notice of copyright, i.e., "Copyright (c)
-2002-2011 John D. Hunter; All Rights Reserved" are retained in
-matplotlib alone or in any derivative version prepared by
-Licensee.
-
-3. In the event Licensee prepares a derivative work that is based on or
-incorporates matplotlib or any part thereof, and wants to
-make the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to matplotlib.
-
-4. JDH is making matplotlib available to Licensee on an "AS
-IS" basis. JDH MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, JDH MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB
-WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. JDH SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF MATPLOTLIB
- FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR
-LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING
-MATPLOTLIB , OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF
-THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. Nothing in this License Agreement shall be deemed to create any
-relationship of agency, partnership, or joint venture between JDH and
-Licensee. This License Agreement does not grant permission to use JDH
-trademarks or trade name in a trademark sense to endorse or promote
-products or services of Licensee, or any third party.
-
-8. By copying, installing or otherwise using matplotlib,
-Licensee agrees to be bound by the terms and conditions of this License
-Agreement. \ No newline at end of file
diff --git a/contrib/python/matplotlib/py2/LICENSE/LICENSE.PIL b/contrib/python/matplotlib/py2/LICENSE/LICENSE.PIL
deleted file mode 100644
index 3f77350b92..0000000000
--- a/contrib/python/matplotlib/py2/LICENSE/LICENSE.PIL
+++ /dev/null
@@ -1,12 +0,0 @@
-Software License
-
-The Python Imaging Library (PIL) is
-
- Copyright © 1997-2011 by Secret Labs AB
- Copyright © 1995-2011 by Fredrik Lundh
-
-By obtaining, using, and/or copying this software and/or its associated documentation, you agree that you have read, understood, and will comply with the following terms and conditions:
-
-Permission to use, copy, modify, and distribute this software and its associated documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appears in all copies, and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Secret Labs AB or the author not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission.
-
-SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. \ No newline at end of file
diff --git a/contrib/python/matplotlib/py2/LICENSE/LICENSE_AMSFONTS b/contrib/python/matplotlib/py2/LICENSE/LICENSE_AMSFONTS
deleted file mode 100644
index 3627bb9bb6..0000000000
--- a/contrib/python/matplotlib/py2/LICENSE/LICENSE_AMSFONTS
+++ /dev/null
@@ -1,240 +0,0 @@
-The cmr10.pfb file is a Type-1 version of one of Knuth's Computer Modern fonts.
-It is included here as test data only, but the following license applies.
-
-Copyright (c) 1997, 2009, American Mathematical Society (http://www.ams.org).
-All Rights Reserved.
-
-"cmb10" is a Reserved Font Name for this Font Software.
-"cmbsy10" is a Reserved Font Name for this Font Software.
-"cmbsy5" is a Reserved Font Name for this Font Software.
-"cmbsy6" is a Reserved Font Name for this Font Software.
-"cmbsy7" is a Reserved Font Name for this Font Software.
-"cmbsy8" is a Reserved Font Name for this Font Software.
-"cmbsy9" is a Reserved Font Name for this Font Software.
-"cmbx10" is a Reserved Font Name for this Font Software.
-"cmbx12" is a Reserved Font Name for this Font Software.
-"cmbx5" is a Reserved Font Name for this Font Software.
-"cmbx6" is a Reserved Font Name for this Font Software.
-"cmbx7" is a Reserved Font Name for this Font Software.
-"cmbx8" is a Reserved Font Name for this Font Software.
-"cmbx9" is a Reserved Font Name for this Font Software.
-"cmbxsl10" is a Reserved Font Name for this Font Software.
-"cmbxti10" is a Reserved Font Name for this Font Software.
-"cmcsc10" is a Reserved Font Name for this Font Software.
-"cmcsc8" is a Reserved Font Name for this Font Software.
-"cmcsc9" is a Reserved Font Name for this Font Software.
-"cmdunh10" is a Reserved Font Name for this Font Software.
-"cmex10" is a Reserved Font Name for this Font Software.
-"cmex7" is a Reserved Font Name for this Font Software.
-"cmex8" is a Reserved Font Name for this Font Software.
-"cmex9" is a Reserved Font Name for this Font Software.
-"cmff10" is a Reserved Font Name for this Font Software.
-"cmfi10" is a Reserved Font Name for this Font Software.
-"cmfib8" is a Reserved Font Name for this Font Software.
-"cminch" is a Reserved Font Name for this Font Software.
-"cmitt10" is a Reserved Font Name for this Font Software.
-"cmmi10" is a Reserved Font Name for this Font Software.
-"cmmi12" is a Reserved Font Name for this Font Software.
-"cmmi5" is a Reserved Font Name for this Font Software.
-"cmmi6" is a Reserved Font Name for this Font Software.
-"cmmi7" is a Reserved Font Name for this Font Software.
-"cmmi8" is a Reserved Font Name for this Font Software.
-"cmmi9" is a Reserved Font Name for this Font Software.
-"cmmib10" is a Reserved Font Name for this Font Software.
-"cmmib5" is a Reserved Font Name for this Font Software.
-"cmmib6" is a Reserved Font Name for this Font Software.
-"cmmib7" is a Reserved Font Name for this Font Software.
-"cmmib8" is a Reserved Font Name for this Font Software.
-"cmmib9" is a Reserved Font Name for this Font Software.
-"cmr10" is a Reserved Font Name for this Font Software.
-"cmr12" is a Reserved Font Name for this Font Software.
-"cmr17" is a Reserved Font Name for this Font Software.
-"cmr5" is a Reserved Font Name for this Font Software.
-"cmr6" is a Reserved Font Name for this Font Software.
-"cmr7" is a Reserved Font Name for this Font Software.
-"cmr8" is a Reserved Font Name for this Font Software.
-"cmr9" is a Reserved Font Name for this Font Software.
-"cmsl10" is a Reserved Font Name for this Font Software.
-"cmsl12" is a Reserved Font Name for this Font Software.
-"cmsl8" is a Reserved Font Name for this Font Software.
-"cmsl9" is a Reserved Font Name for this Font Software.
-"cmsltt10" is a Reserved Font Name for this Font Software.
-"cmss10" is a Reserved Font Name for this Font Software.
-"cmss12" is a Reserved Font Name for this Font Software.
-"cmss17" is a Reserved Font Name for this Font Software.
-"cmss8" is a Reserved Font Name for this Font Software.
-"cmss9" is a Reserved Font Name for this Font Software.
-"cmssbx10" is a Reserved Font Name for this Font Software.
-"cmssdc10" is a Reserved Font Name for this Font Software.
-"cmssi10" is a Reserved Font Name for this Font Software.
-"cmssi12" is a Reserved Font Name for this Font Software.
-"cmssi17" is a Reserved Font Name for this Font Software.
-"cmssi8" is a Reserved Font Name for this Font Software.
-"cmssi9" is a Reserved Font Name for this Font Software.
-"cmssq8" is a Reserved Font Name for this Font Software.
-"cmssqi8" is a Reserved Font Name for this Font Software.
-"cmsy10" is a Reserved Font Name for this Font Software.
-"cmsy5" is a Reserved Font Name for this Font Software.
-"cmsy6" is a Reserved Font Name for this Font Software.
-"cmsy7" is a Reserved Font Name for this Font Software.
-"cmsy8" is a Reserved Font Name for this Font Software.
-"cmsy9" is a Reserved Font Name for this Font Software.
-"cmtcsc10" is a Reserved Font Name for this Font Software.
-"cmtex10" is a Reserved Font Name for this Font Software.
-"cmtex8" is a Reserved Font Name for this Font Software.
-"cmtex9" is a Reserved Font Name for this Font Software.
-"cmti10" is a Reserved Font Name for this Font Software.
-"cmti12" is a Reserved Font Name for this Font Software.
-"cmti7" is a Reserved Font Name for this Font Software.
-"cmti8" is a Reserved Font Name for this Font Software.
-"cmti9" is a Reserved Font Name for this Font Software.
-"cmtt10" is a Reserved Font Name for this Font Software.
-"cmtt12" is a Reserved Font Name for this Font Software.
-"cmtt8" is a Reserved Font Name for this Font Software.
-"cmtt9" is a Reserved Font Name for this Font Software.
-"cmu10" is a Reserved Font Name for this Font Software.
-"cmvtt10" is a Reserved Font Name for this Font Software.
-"euex10" is a Reserved Font Name for this Font Software.
-"euex7" is a Reserved Font Name for this Font Software.
-"euex8" is a Reserved Font Name for this Font Software.
-"euex9" is a Reserved Font Name for this Font Software.
-"eufb10" is a Reserved Font Name for this Font Software.
-"eufb5" is a Reserved Font Name for this Font Software.
-"eufb7" is a Reserved Font Name for this Font Software.
-"eufm10" is a Reserved Font Name for this Font Software.
-"eufm5" is a Reserved Font Name for this Font Software.
-"eufm7" is a Reserved Font Name for this Font Software.
-"eurb10" is a Reserved Font Name for this Font Software.
-"eurb5" is a Reserved Font Name for this Font Software.
-"eurb7" is a Reserved Font Name for this Font Software.
-"eurm10" is a Reserved Font Name for this Font Software.
-"eurm5" is a Reserved Font Name for this Font Software.
-"eurm7" is a Reserved Font Name for this Font Software.
-"eusb10" is a Reserved Font Name for this Font Software.
-"eusb5" is a Reserved Font Name for this Font Software.
-"eusb7" is a Reserved Font Name for this Font Software.
-"eusm10" is a Reserved Font Name for this Font Software.
-"eusm5" is a Reserved Font Name for this Font Software.
-"eusm7" is a Reserved Font Name for this Font Software.
-"lasy10" is a Reserved Font Name for this Font Software.
-"lasy5" is a Reserved Font Name for this Font Software.
-"lasy6" is a Reserved Font Name for this Font Software.
-"lasy7" is a Reserved Font Name for this Font Software.
-"lasy8" is a Reserved Font Name for this Font Software.
-"lasy9" is a Reserved Font Name for this Font Software.
-"lasyb10" is a Reserved Font Name for this Font Software.
-"lcircle1" is a Reserved Font Name for this Font Software.
-"lcirclew" is a Reserved Font Name for this Font Software.
-"lcmss8" is a Reserved Font Name for this Font Software.
-"lcmssb8" is a Reserved Font Name for this Font Software.
-"lcmssi8" is a Reserved Font Name for this Font Software.
-"line10" is a Reserved Font Name for this Font Software.
-"linew10" is a Reserved Font Name for this Font Software.
-"msam10" is a Reserved Font Name for this Font Software.
-"msam5" is a Reserved Font Name for this Font Software.
-"msam6" is a Reserved Font Name for this Font Software.
-"msam7" is a Reserved Font Name for this Font Software.
-"msam8" is a Reserved Font Name for this Font Software.
-"msam9" is a Reserved Font Name for this Font Software.
-"msbm10" is a Reserved Font Name for this Font Software.
-"msbm5" is a Reserved Font Name for this Font Software.
-"msbm6" is a Reserved Font Name for this Font Software.
-"msbm7" is a Reserved Font Name for this Font Software.
-"msbm8" is a Reserved Font Name for this Font Software.
-"msbm9" is a Reserved Font Name for this Font Software.
-"wncyb10" is a Reserved Font Name for this Font Software.
-"wncyi10" is a Reserved Font Name for this Font Software.
-"wncyr10" is a Reserved Font Name for this Font Software.
-"wncysc10" is a Reserved Font Name for this Font Software.
-"wncyss10" is a Reserved Font Name for this Font Software.
-
-This Font Software is licensed under the SIL Open Font License, Version 1.1.
-This license is copied below, and is also available with a FAQ at:
-http://scripts.sil.org/OFL
-
------------------------------------------------------------
-SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
------------------------------------------------------------
-
-PREAMBLE
-The goals of the Open Font License (OFL) are to stimulate worldwide
-development of collaborative font projects, to support the font creation
-efforts of academic and linguistic communities, and to provide a free and
-open framework in which fonts may be shared and improved in partnership
-with others.
-
-The OFL allows the licensed fonts to be used, studied, modified and
-redistributed freely as long as they are not sold by themselves. The
-fonts, including any derivative works, can be bundled, embedded,
-redistributed and/or sold with any software provided that any reserved
-names are not used by derivative works. The fonts and derivatives,
-however, cannot be released under any other type of license. The
-requirement for fonts to remain under this license does not apply
-to any document created using the fonts or their derivatives.
-
-DEFINITIONS
-"Font Software" refers to the set of files released by the Copyright
-Holder(s) under this license and clearly marked as such. This may
-include source files, build scripts and documentation.
-
-"Reserved Font Name" refers to any names specified as such after the
-copyright statement(s).
-
-"Original Version" refers to the collection of Font Software components as
-distributed by the Copyright Holder(s).
-
-"Modified Version" refers to any derivative made by adding to, deleting,
-or substituting -- in part or in whole -- any of the components of the
-Original Version, by changing formats or by porting the Font Software to a
-new environment.
-
-"Author" refers to any designer, engineer, programmer, technical
-writer or other person who contributed to the Font Software.
-
-PERMISSION & CONDITIONS
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of the Font Software, to use, study, copy, merge, embed, modify,
-redistribute, and sell modified and unmodified copies of the Font
-Software, subject to the following conditions:
-
-1) Neither the Font Software nor any of its individual components,
-in Original or Modified Versions, may be sold by itself.
-
-2) Original or Modified Versions of the Font Software may be bundled,
-redistributed and/or sold with any software, provided that each copy
-contains the above copyright notice and this license. These can be
-included either as stand-alone text files, human-readable headers or
-in the appropriate machine-readable metadata fields within text or
-binary files as long as those fields can be easily viewed by the user.
-
-3) No Modified Version of the Font Software may use the Reserved Font
-Name(s) unless explicit written permission is granted by the corresponding
-Copyright Holder. This restriction only applies to the primary font name as
-presented to the users.
-
-4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
-Software shall not be used to promote, endorse or advertise any
-Modified Version, except to acknowledge the contribution(s) of the
-Copyright Holder(s) and the Author(s) or with their explicit written
-permission.
-
-5) The Font Software, modified or unmodified, in part or in whole,
-must be distributed entirely under this license, and must not be
-distributed under any other license. The requirement for fonts to
-remain under this license does not apply to any document created
-using the Font Software.
-
-TERMINATION
-This license becomes null and void if any of the above conditions are
-not met.
-
-DISCLAIMER
-THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
-COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
-DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
-OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/contrib/python/matplotlib/py2/LICENSE/LICENSE_BAKOMA b/contrib/python/matplotlib/py2/LICENSE/LICENSE_BAKOMA
deleted file mode 100644
index 801e20cd73..0000000000
--- a/contrib/python/matplotlib/py2/LICENSE/LICENSE_BAKOMA
+++ /dev/null
@@ -1,40 +0,0 @@
-
- BaKoMa Fonts Licence
- --------------------
-
- This licence covers two font packs (known as BaKoMa Fonts Colelction,
- which is available at `CTAN:fonts/cm/ps-type1/bakoma/'):
-
- 1) BaKoMa-CM (1.1/12-Nov-94)
- Computer Modern Fonts in PostScript Type 1 and TrueType font formats.
-
- 2) BaKoMa-AMS (1.2/19-Jan-95)
- AMS TeX fonts in PostScript Type 1 and TrueType font formats.
-
- Copyright (C) 1994, 1995, Basil K. Malyshev. All Rights Reserved.
-
- Permission to copy and distribute these fonts for any purpose is
- hereby granted without fee, provided that the above copyright notice,
- author statement and this permission notice appear in all copies of
- these fonts and related documentation.
-
- Permission to modify and distribute modified fonts for any purpose is
- hereby granted without fee, provided that the copyright notice,
- author statement, this permission notice and location of original
- fonts (http://www.ctan.org/tex-archive/fonts/cm/ps-type1/bakoma)
- appear in all copies of modified fonts and related documentation.
-
- Permission to use these fonts (embedding into PostScript, PDF, SVG
- and printing by using any software) is hereby granted without fee.
- It is not required to provide any notices about using these fonts.
-
- Basil K. Malyshev
- INSTITUTE FOR HIGH ENERGY PHYSICS
- IHEP, OMVT
- Moscow Region
- 142281 PROTVINO
- RUSSIA
-
- E-Mail: bakoma@mail.ru
- or malyshev@mail.ihep.ru
-
diff --git a/contrib/python/matplotlib/py2/LICENSE/LICENSE_COLORBREWER b/contrib/python/matplotlib/py2/LICENSE/LICENSE_COLORBREWER
deleted file mode 100644
index 568afe883e..0000000000
--- a/contrib/python/matplotlib/py2/LICENSE/LICENSE_COLORBREWER
+++ /dev/null
@@ -1,38 +0,0 @@
-Apache-Style Software License for ColorBrewer Color Schemes
-
-Version 1.1
-
-Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The Pennsylvania
-State University. All rights reserved. Redistribution and use in source
-and binary forms, with or without modification, are permitted provided
-that the following conditions are met:
-
-1. Redistributions as source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-
-2. The end-user documentation included with the redistribution, if any,
-must include the following acknowledgment: "This product includes color
-specifications and designs developed by Cynthia Brewer
-(http://colorbrewer.org/)." Alternately, this acknowledgment may appear in
-the software itself, if and wherever such third-party acknowledgments
-normally appear.
-
-3. The name "ColorBrewer" must not be used to endorse or promote products
-derived from this software without prior written permission. For written
-permission, please contact Cynthia Brewer at cbrewer@psu.edu.
-
-4. Products derived from this software may not be called "ColorBrewer",
-nor may "ColorBrewer" appear in their name, without prior written
-permission of Cynthia Brewer.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED 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
-CYNTHIA BREWER, MARK HARROWER, OR THE PENNSYLVANIA STATE UNIVERSITY 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/contrib/python/matplotlib/py2/LICENSE/LICENSE_CONDA b/contrib/python/matplotlib/py2/LICENSE/LICENSE_CONDA
deleted file mode 100644
index 8794a6d484..0000000000
--- a/contrib/python/matplotlib/py2/LICENSE/LICENSE_CONDA
+++ /dev/null
@@ -1,51 +0,0 @@
-Except where noted below, conda is released under the following terms:
-
-(c) 2012 Continuum Analytics, Inc. / http://continuum.io
-All Rights Reserved
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * 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.
- * Neither the name of Continuum Analytics, Inc. nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 CONTINUUM ANALYTICS 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.
-
-
-Exceptions
-==========
-
-versioneer.py is Public Domain
-
-The ProgressBar package is released under the following terms:
-
-# progressbar - Text progress bar library for Python.
-# Copyright (c) 2005 Nilton Volpato
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA \ No newline at end of file
diff --git a/contrib/python/matplotlib/py2/LICENSE/LICENSE_JQUERY b/contrib/python/matplotlib/py2/LICENSE/LICENSE_JQUERY
deleted file mode 100644
index f35387a3ab..0000000000
--- a/contrib/python/matplotlib/py2/LICENSE/LICENSE_JQUERY
+++ /dev/null
@@ -1,61 +0,0 @@
-Comment found in jQuery source code:
-
-/*!
- * jQuery JavaScript Library v1.11.3
- * http://jquery.com/
- *
- * Includes Sizzle.js
- * http://sizzlejs.com/
- *
- * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2015-04-28T16:19Z
- */
-
-Comment found in jQuery UI source code:
-
-/*! jQuery UI - v1.11.4 - 2015-03-11
-* http://jqueryui.com
-* Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js
-* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */
-
-Text found at http://jquery.org/license:
-
- jQuery Foundation projects are released under the terms of the license
- specified in the project's repository or if not specified, under the
- MIT license.
-
- The MIT License is simple and easy to understand and it places almost
- no restrictions on what you can do with a jQuery Foundation project.
-
- You are free to use any jQuery Foundation project in any other project
- (even commercial projects) as long as the copyright header is left
- intact.
-
-The text links to https://tldrlegal.com/license/mit-license
-which includes the following as the "Full License Text":
-
- The MIT License (MIT)
-
- Copyright (c) <year> <copyright holders>
-
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files (the
- "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to
- permit persons to whom the Software is furnished to do so, subject to
- the following conditions:
-
- The above copyright notice and this permission notice shall be
- included in all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file
diff --git a/contrib/python/matplotlib/py2/LICENSE/LICENSE_QT4_EDITOR b/contrib/python/matplotlib/py2/LICENSE/LICENSE_QT4_EDITOR
deleted file mode 100644
index 1c9d941973..0000000000
--- a/contrib/python/matplotlib/py2/LICENSE/LICENSE_QT4_EDITOR
+++ /dev/null
@@ -1,30 +0,0 @@
-
-Module creating PyQt4 form dialogs/layouts to edit various type of parameters
-
-
-formlayout License Agreement (MIT License)
-------------------------------------------
-
-Copyright (c) 2009 Pierre Raybaut
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-"""
diff --git a/contrib/python/matplotlib/py2/LICENSE/LICENSE_STIX b/contrib/python/matplotlib/py2/LICENSE/LICENSE_STIX
deleted file mode 100644
index 2f7aeea331..0000000000
--- a/contrib/python/matplotlib/py2/LICENSE/LICENSE_STIX
+++ /dev/null
@@ -1,71 +0,0 @@
-TERMS AND CONDITIONS
-
- 1. Permission is hereby granted, free of charge, to any person
-obtaining a copy of the STIX Fonts-TM set accompanying this license
-(collectively, the "Fonts") and the associated documentation files
-(collectively with the Fonts, the "Font Software"), to reproduce and
-distribute the Font Software, including the rights to use, copy, merge
-and publish copies of the Font Software, and to permit persons to whom
-the Font Software is furnished to do so same, subject to the following
-terms and conditions (the "License").
-
- 2. The following copyright and trademark notice and these Terms and
-Conditions shall be included in all copies of one or more of the Font
-typefaces and any derivative work created as permitted under this
-License:
-
- Copyright (c) 2001-2005 by the STI Pub Companies, consisting of
-the American Institute of Physics, the American Chemical Society, the
-American Mathematical Society, the American Physical Society, Elsevier,
-Inc., and The Institute of Electrical and Electronic Engineers, Inc.
-Portions copyright (c) 1998-2003 by MicroPress, Inc. Portions copyright
-(c) 1990 by Elsevier, Inc. All rights reserved. STIX Fonts-TM is a
-trademark of The Institute of Electrical and Electronics Engineers, Inc.
-
- 3. You may (a) convert the Fonts from one format to another (e.g.,
-from TrueType to PostScript), in which case the normal and reasonable
-distortion that occurs during such conversion shall be permitted and (b)
-embed or include a subset of the Fonts in a document for the purposes of
-allowing users to read text in the document that utilizes the Fonts. In
-each case, you may use the STIX Fonts-TM mark to designate the resulting
-Fonts or subset of the Fonts.
-
- 4. You may also (a) add glyphs or characters to the Fonts, or modify
-the shape of existing glyphs, so long as the base set of glyphs is not
-removed and (b) delete glyphs or characters from the Fonts, provided
-that the resulting font set is distributed with the following
-disclaimer: "This [name] font does not include all the Unicode points
-covered in the STIX Fonts-TM set but may include others." In each case,
-the name used to denote the resulting font set shall not include the
-term "STIX" or any similar term.
-
- 5. You may charge a fee in connection with the distribution of the
-Font Software, provided that no copy of one or more of the individual
-Font typefaces that form the STIX Fonts-TM set may be sold by itself.
-
- 6. THE FONT SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY
-KIND, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-OF COPYRIGHT, PATENT, TRADEMARK OR OTHER RIGHT. IN NO EVENT SHALL
-MICROPRESS OR ANY OF THE STI PUB COMPANIES BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, INCLUDING, BUT NOT LIMITED TO, ANY GENERAL,
-SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES, WHETHER IN AN
-ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM OR OUT OF THE USE OR
-INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT
-SOFTWARE.
-
- 7. Except as contained in the notice set forth in Section 2, the
-names MicroPress Inc. and STI Pub Companies, as well as the names of the
-companies/organizations that compose the STI Pub Companies, shall not be
-used in advertising or otherwise to promote the sale, use or other
-dealings in the Font Software without the prior written consent of the
-respective company or organization.
-
- 8. This License shall become null and void in the event of any
-material breach of the Terms and Conditions herein by licensee.
-
- 9. A substantial portion of the STIX Fonts set was developed by
-MicroPress Inc. for the STI Pub Companies. To obtain additional
-mathematical fonts, please contact MicroPress, Inc., 68-30 Harrow
-Street, Forest Hills, NY 11375, USA - Phone: (718) 575-1816.
-
diff --git a/contrib/python/matplotlib/py2/LICENSE/LICENSE_YORICK b/contrib/python/matplotlib/py2/LICENSE/LICENSE_YORICK
deleted file mode 100644
index 8c908509a7..0000000000
--- a/contrib/python/matplotlib/py2/LICENSE/LICENSE_YORICK
+++ /dev/null
@@ -1,49 +0,0 @@
-BSD-style license for gist/yorick colormaps.
-
-Copyright:
-
- Copyright (c) 1996. The Regents of the University of California.
- All rights reserved.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose without fee is hereby granted, provided that this entire
-notice is included in all copies of any software which is or includes
-a copy or modification of this software and in all copies of the
-supporting documentation for such software.
-
-This work was produced at the University of California, Lawrence
-Livermore National Laboratory under contract no. W-7405-ENG-48 between
-the U.S. Department of Energy and The Regents of the University of
-California for the operation of UC LLNL.
-
-
- DISCLAIMER
-
-This software was prepared as an account of work sponsored by an
-agency of the United States Government. Neither the United States
-Government nor the University of California nor any of their
-employees, makes any warranty, express or implied, or assumes any
-liability or responsibility for the accuracy, completeness, or
-usefulness of any information, apparatus, product, or process
-disclosed, or represents that its use would not infringe
-privately-owned rights. Reference herein to any specific commercial
-products, process, or service by trade name, trademark, manufacturer,
-or otherwise, does not necessarily constitute or imply its
-endorsement, recommendation, or favoring by the United States
-Government or the University of California. The views and opinions of
-authors expressed herein do not necessarily state or reflect those of
-the United States Government or the University of California, and
-shall not be used for advertising or product endorsement purposes.
-
-
- AUTHOR
-
-David H. Munro wrote Yorick and Gist. Berkeley Yacc (byacc) generated
-the Yorick parser. The routines in Math are from LAPACK and FFTPACK;
-MathC contains C translations by David H. Munro. The algorithms for
-Yorick's random number generator and several special functions in
-Yorick/include were taken from Numerical Recipes by Press, et. al.,
-although the Yorick implementations are unrelated to those in
-Numerical Recipes. A small amount of code in Gist was adapted from
-the X11R4 release, copyright M.I.T. -- the complete copyright notice
-may be found in the (unused) file Gist/host.c.
diff --git a/contrib/python/matplotlib/py2/LICENSE/LICENSE_enthought.txt b/contrib/python/matplotlib/py2/LICENSE/LICENSE_enthought.txt
deleted file mode 100644
index 27727c5eae..0000000000
--- a/contrib/python/matplotlib/py2/LICENSE/LICENSE_enthought.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-Copyright (c) 2001, 2002 Enthought, Inc.
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- a. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- b. 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.
- c. Neither the name of the Enthought nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 REGENTS OR CONTRIBUTORS 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/contrib/python/matplotlib/py2/LICENSE/Solarized.txt b/contrib/python/matplotlib/py2/LICENSE/Solarized.txt
deleted file mode 100644
index 6e5a0475dd..0000000000
--- a/contrib/python/matplotlib/py2/LICENSE/Solarized.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-https://github.com/altercation/solarized/blob/master/LICENSE
-Copyright (c) 2011 Ethan Schoonover
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/contrib/python/matplotlib/py2/LICENSE/pnpoly.license b/contrib/python/matplotlib/py2/LICENSE/pnpoly.license
deleted file mode 100644
index 0c838f9b01..0000000000
--- a/contrib/python/matplotlib/py2/LICENSE/pnpoly.license
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright (c) 1970-2003, Wm. Randolph Franklin
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimers.
- 2. Redistributions in binary form must reproduce the above
- copyright notice in the documentation and/or other materials
- provided with the distribution.
- 3. The name of W. Randolph Franklin may not be used to endorse or
- promote products derived from this Software without specific
- prior written permission.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/contrib/python/matplotlib/py2/README.rst b/contrib/python/matplotlib/py2/README.rst
deleted file mode 100644
index b13658c300..0000000000
--- a/contrib/python/matplotlib/py2/README.rst
+++ /dev/null
@@ -1,83 +0,0 @@
-|Travis|_ |AppVeyor|_ |Codecov|_ |PyPi|_ |Gitter|_ |NUMFocus|_
-
-
-.. |Travis| image:: https://travis-ci.org/matplotlib/matplotlib.svg?branch=master
-.. _Travis: https://travis-ci.org/matplotlib/matplotlib
-
-.. |AppVeyor| image:: https://ci.appveyor.com/api/projects/status/github/matplotlib/matplotlib?branch=master&svg=true
-.. _AppVeyor: https://ci.appveyor.com/project/matplotlib/matplotlib
-
-.. |Codecov| image:: https://codecov.io/github/matplotlib/matplotlib/badge.svg?branch=master&service=github
-.. _Codecov: https://codecov.io/github/matplotlib/matplotlib?branch=master
-
-.. |PyPi| image:: https://badge.fury.io/py/matplotlib.svg
-.. _PyPi: https://badge.fury.io/py/matplotlib
-
-.. |Gitter| image:: https://badges.gitter.im/matplotlib/matplotlib.png
-.. _Gitter: https://gitter.im/matplotlib/matplotlib
-
-.. |NUMFocus| image:: https://img.shields.io/badge/powered%20by-NumFOCUS-orange.svg?style=flat&colorA=E1523D&colorB=007D8A
-.. _NUMFocus: http://www.numfocus.org
-
-
-##########
-Matplotlib
-##########
-
-Matplotlib is a Python 2D plotting library which produces publication-quality
-figures in a variety of hardcopy formats and interactive environments across
-platforms. Matplotlib can be used in Python scripts, the Python and IPython
-shell (à la MATLAB or Mathematica), web application servers, and various
-graphical user interface toolkits.
-
-`Home page <http://matplotlib.org/>`_
-
-Installation
-============
-
-For installation instructions and requirements, see the INSTALL.rst file or the
-`install <http://matplotlib.org/users/installing.html>`_ documentation. If you
-think you may want to contribute to matplotlib, check out the `guide to
-working with the source code
-<http://matplotlib.org/devel/gitwash/index.html>`_.
-
-Testing
-=======
-
-After installation, you can launch the test suite::
-
- py.test
-
-Or from the Python interpreter::
-
- import matplotlib
- matplotlib.test()
-
-Consider reading http://matplotlib.org/devel/coding_guide.html#testing for
-more information. Note that the test suite requires pytest and, on Python 2.7,
-mock. Please install with pip or your package manager of choice.
-
-Contact
-=======
-matplotlib's communication channels include active mailing lists:
-
-* `Users <https://mail.python.org/mailman/listinfo/matplotlib-users>`_ mailing list: matplotlib-users@python.org
-* `Announcement <https://mail.python.org/mailman/listinfo/matplotlib-announce>`_ mailing list: matplotlib-announce@python.org
-* `Development <https://mail.python.org/mailman/listinfo/matplotlib-devel>`_ mailing list: matplotlib-devel@python.org
-
-The first is a good starting point for general questions and discussions.
-
-Gitter_ is for coordinating development and asking questions directly related
-to contributing to matplotlib.
-
-Contribute
-==========
-You've discovered a bug or something else you want to change - excellent!
-
-You've worked out a way to fix it – even better!
-
-You want to tell us about it – best of all!
-
-Start at the `contributing guide <http://matplotlib.org/devdocs/devel/contributing.html>`_!
-
-Developer notes are now at `_Developer Discussions <https://github.com/orgs/matplotlib/teams/developers/discussions>`_
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_alpha_mask_u8.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_alpha_mask_u8.h
deleted file mode 100644
index e301c10088..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_alpha_mask_u8.h
+++ /dev/null
@@ -1,499 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
-
- if(x < 0)
- {
- count += x;
- if(count <= 0)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
- 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)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
- 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)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
-
- if(x < 0)
- {
- count += x;
- if(count <= 0)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
- 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)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
- 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)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
-
- if(y < 0)
- {
- count += y;
- if(count <= 0)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
- 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)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
- 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)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
-
- if(y < 0)
- {
- count += y;
- if(count <= 0)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
- 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)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_arc.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_arc.h
deleted file mode 100644
index 17e1d43473..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_arc.h
+++ /dev/null
@@ -1,74 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_array.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_array.h
deleted file mode 100644
index 8d56683840..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_array.h
+++ /dev/null
@@ -1,1119 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <stddef.h>
-#include <string.h>
-#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)
- {
- memcpy(m_array, c, sizeof(T) * Size);
- }
-
- const self_type& operator = (const T* c)
- {
- 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)
- {
- 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());
- 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()
- {
- 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);
- 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)
- {
- 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) 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) 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) 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
- {
- 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);
- 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)
- {
- 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)
- {
- 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++)
- {
- 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();
- 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)
- {
- memcpy(&((*this)[start + i]), data, sizeof(T));
- }
- else
- {
- T* ptr = data_ptr();
- 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((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)
- {
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_arrowhead.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_arrowhead.h
deleted file mode 100644
index 5e029ddee0..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_arrowhead.h
+++ /dev/null
@@ -1,82 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_basics.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_basics.h
deleted file mode 100644
index 309713002b..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_basics.h
+++ /dev/null
@@ -1,560 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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(floor(v));
- }
- AGG_INLINE unsigned ufloor(double v)
- {
- return unsigned(floor(v));
- }
- AGG_INLINE int iceil(double v)
- {
- return int(ceil(v));
- }
- AGG_INLINE unsigned uceil(double v)
- {
- return unsigned(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(ceil(v));
- }
- AGG_INLINE unsigned uceil(double v)
- {
- return unsigned(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)
- {
- return fabs(v1 - v2) <= double(epsilon);
- }
-}
-
-
-#endif
-
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bezier_arc.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bezier_arc.h
deleted file mode 100644
index 6d98d1a9f0..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bezier_arc.h
+++ /dev/null
@@ -1,159 +0,0 @@
-//----------------------------------------------------------------------------
-// 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) ? 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bitset_iterator.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bitset_iterator.h
deleted file mode 100644
index 7382d5c335..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bitset_iterator.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_blur.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_blur.h
deleted file mode 100644
index cd5713f314..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_blur.h
+++ /dev/null
@@ -1,1503 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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 * 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 / 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);
- 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
- {
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bounding_rect.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bounding_rect.h
deleted file mode 100644
index f13b863f0f..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bounding_rect.h
+++ /dev/null
@@ -1,116 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bspline.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bspline.h
deleted file mode 100644
index 2c1ed9a38c..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bspline.h
+++ /dev/null
@@ -1,76 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_clip_liang_barsky.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_clip_liang_barsky.h
deleted file mode 100644
index 4b5fedbab5..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_clip_liang_barsky.h
+++ /dev/null
@@ -1,333 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_color_gray.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_color_gray.h
deleted file mode 100644
index 8d5f2ed8d0..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_color_gray.h
+++ /dev/null
@@ -1,1047 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 = value_type((v_ > base_mask) ? 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); }
- };
-
-
- //===================================================================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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_color_rgba.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_color_rgba.h
deleted file mode 100644
index 74f871be17..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_color_rgba.h
+++ /dev/null
@@ -1,1353 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 = pow(t.r * s, gamma);
- t.g = pow(t.g * s, gamma);
- t.b = 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_config.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_config.h
deleted file mode 100644
index fa1dae2ba7..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_config.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_adaptor_vcgen.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_adaptor_vcgen.h
deleted file mode 100644
index a79f2208c6..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_adaptor_vcgen.h
+++ /dev/null
@@ -1,157 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_adaptor_vpgen.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_adaptor_vpgen.h
deleted file mode 100644
index d6b545ef1f..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_adaptor_vpgen.h
+++ /dev/null
@@ -1,159 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_bspline.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_bspline.h
deleted file mode 100644
index 13d22d9297..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_bspline.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_clip_polygon.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_clip_polygon.h
deleted file mode 100644
index 87537638dc..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_clip_polygon.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_clip_polyline.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_clip_polyline.h
deleted file mode 100644
index f3fc2888c2..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_clip_polyline.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_close_polygon.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_close_polygon.h
deleted file mode 100644
index c46594fdfb..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_close_polygon.h
+++ /dev/null
@@ -1,125 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_concat.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_concat.h
deleted file mode 100644
index 745d349c6f..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_concat.h
+++ /dev/null
@@ -1,73 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_contour.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_contour.h
deleted file mode 100644
index b4b5a9047e..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_contour.h
+++ /dev/null
@@ -1,65 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_curve.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_curve.h
deleted file mode 100644
index d5b475de7a..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_curve.h
+++ /dev/null
@@ -1,201 +0,0 @@
-//----------------------------------------------------------------------------
-// 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;
- double ct2_y;
- double end_x;
- double end_y;
-
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_dash.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_dash.h
deleted file mode 100644
index 23c13ad0ab..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_dash.h
+++ /dev/null
@@ -1,68 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_gpc.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_gpc.h
deleted file mode 100644
index 2acada342d..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_gpc.h
+++ /dev/null
@@ -1,432 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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)
- {
- memset(&m_poly_a, 0, sizeof(m_poly_a));
- memset(&m_poly_b, 0, sizeof(m_poly_b));
- 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);
- 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);
- }
- 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;
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_marker.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_marker.h
deleted file mode 100644
index 2cd3cb403f..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_marker.h
+++ /dev/null
@@ -1,148 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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(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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_marker_adaptor.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_marker_adaptor.h
deleted file mode 100644
index 4486d6ace9..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_marker_adaptor.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_segmentator.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_segmentator.h
deleted file mode 100644
index e69a9e7d7d..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_segmentator.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_shorten_path.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_shorten_path.h
deleted file mode 100644
index 5617e51d17..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_shorten_path.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_smooth_poly1.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_smooth_poly1.h
deleted file mode 100644
index 4ac4e3d6e2..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_smooth_poly1.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_stroke.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_stroke.h
deleted file mode 100644
index e19a6b61f4..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_stroke.h
+++ /dev/null
@@ -1,73 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_transform.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_transform.h
deleted file mode 100644
index 0c88a245bd..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_transform.h
+++ /dev/null
@@ -1,68 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_unclose_polygon.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_unclose_polygon.h
deleted file mode 100644
index fe5c263810..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_unclose_polygon.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_curves.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_curves.h
deleted file mode 100644
index 1ef02e8783..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_curves.h
+++ /dev/null
@@ -1,693 +0,0 @@
-//----------------------------------------------------------------------------
-// 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_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_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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_dda_line.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_dda_line.h
deleted file mode 100644
index f589e76b83..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_dda_line.h
+++ /dev/null
@@ -1,290 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <stdlib.h>
-#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(abs(m_x2_lr - m_x1_lr) < abs(m_y2_lr - m_y1_lr)),
- m_len(m_ver ? abs(m_y2_lr - m_y1_lr) :
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_ellipse.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_ellipse.h
deleted file mode 100644
index e78ce27dd9..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_ellipse.h
+++ /dev/null
@@ -1,123 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-
-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 = (fabs(m_rx) + fabs(m_ry)) / 2;
- double da = 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 + cos(angle) * m_rx;
- *y = m_y + sin(angle) * m_ry;
- m_step++;
- return ((m_step == 1) ? path_cmd_move_to : path_cmd_line_to);
- }
-
-}
-
-
-
-#endif
-
-
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_ellipse_bresenham.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_ellipse_bresenham.h
deleted file mode 100644
index ee3b9c4638..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_ellipse_bresenham.h
+++ /dev/null
@@ -1,113 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_embedded_raster_fonts.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_embedded_raster_fonts.h
deleted file mode 100644
index 9d522d671c..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_embedded_raster_fonts.h
+++ /dev/null
@@ -1,59 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_font_cache_manager.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_font_cache_manager.h
deleted file mode 100644
index fe9a9280fa..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_font_cache_manager.h
+++ /dev/null
@@ -1,409 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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(strlen(font_signature) + 1);
- strcpy(m_font_signature, font_signature);
- memset(m_glyphs, 0, sizeof(m_glyphs));
- }
-
- //--------------------------------------------------------------------
- bool font_is(const char* font_signature) const
- {
- return 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*));
- 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]);
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_font_cache_manager2.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_font_cache_manager2.h
deleted file mode 100644
index 75d311eff7..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_font_cache_manager2.h
+++ /dev/null
@@ -1,311 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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)
- { 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*));
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gamma_functions.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gamma_functions.h
deleted file mode 100644
index 5d720daa9a..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gamma_functions.h
+++ /dev/null
@@ -1,132 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gamma_lut.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gamma_lut.h
deleted file mode 100644
index ef1e38d809..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gamma_lut.h
+++ /dev/null
@@ -1,305 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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(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(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 (unsigned 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 (unsigned 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)
- {
- return float(x / 255.0);
- }
-
- static int8u alpha_to_sRGB(float x)
- {
- if (x <= 0) return 0;
- else if (x >= 1) return 255;
- else 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_glyph_raster_bin.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_glyph_raster_bin.h
deleted file mode 100644
index b0bf858efd..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_glyph_raster_bin.h
+++ /dev/null
@@ -1,155 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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;
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gradient_lut.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gradient_lut.h
deleted file mode 100644
index 9aaa426815..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gradient_lut.h
+++ /dev/null
@@ -1,244 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gsv_text.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gsv_text.h
deleted file mode 100644
index 16b3aeb33d..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gsv_text.h
+++ /dev/null
@@ -1,153 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_image_accessors.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_image_accessors.h
deleted file mode 100644
index c651d6d2e8..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_image_accessors.h
+++ /dev/null
@@ -1,481 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_image_filters.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_image_filters.h
deleted file mode 100644
index 8e1bc8f0db..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_image_filters.h
+++ /dev/null
@@ -1,448 +0,0 @@
-//----------------------------------------------------------------------------
-// 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)
- {
- 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 * 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 * 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 * 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 exp(-2.0 * x * x) * 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 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 (sin(x) / x) * (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 (sin(x) / x) * (0.42 + 0.5*cos(xr) + 0.08*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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_line_aa_basics.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_line_aa_basics.h
deleted file mode 100644
index c5acb18e79..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_line_aa_basics.h
+++ /dev/null
@@ -1,189 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <stdlib.h>
-#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(abs(x2_ - x1_)),
- dy(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 = abs(lp1.x2 - lp1.x1);
- lp1.dy = abs(lp1.y2 - lp1.y1);
-
- lp2.x1 = xmid;
- lp2.y1 = ymid;
- lp2.len = len2;
- lp2.dx = abs(lp2.x2 - lp2.x1);
- lp2.dy = 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_math.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_math.h
deleted file mode 100644
index 2ec49cf3ff..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_math.h
+++ /dev/null
@@ -1,437 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 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 = 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(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 = 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(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(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)fabs(x) + 6;
- if(fabs(x) > 5)
- {
- m1 = (int)(fabs(1.4 * x + 60 / x));
- }
- int m2 = (int)(n + 2 + 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(fabs(b - b1) < d)
- {
- return b;
- }
- b1 = b;
- m2 += 3;
- }
- }
-
-}
-
-
-#endif
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_math_stroke.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_math_stroke.h
deleted file mode 100644
index 4871d96cef..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_math_stroke.h
+++ /dev/null
@@ -1,527 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 / 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 = atan2(dy1 * m_width_sign, dx1 * m_width_sign);
- double a2 = atan2(dy2 * m_width_sign, dx2 * m_width_sign);
- double da = a1 - a2;
- int i, n;
-
- da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
-
- 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 + cos(a1) * m_width, y + 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 + cos(a1) * m_width, y + 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 = 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 = atan2(dy1, -dx1);
- a1 += da;
- for(i = 0; i < n; i++)
- {
- add_vertex(vc, v0.x + cos(a1) * m_width,
- v0.y + sin(a1) * m_width);
- a1 += da;
- }
- }
- else
- {
- a1 = atan2(-dy1, dx1);
- a1 -= da;
- for(i = 0; i < n; i++)
- {
- add_vertex(vc, v0.x + cos(a1) * m_width,
- v0.y + 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 > agg::vertex_dist_epsilon && m_width > 0) ||
- (cp < -agg::vertex_dist_epsilon && 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 = 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_path_length.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_path_length.h
deleted file mode 100644
index 740ba31df2..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_path_length.h
+++ /dev/null
@@ -1,65 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_path_storage.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_path_storage.h
deleted file mode 100644
index c01b867f26..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_path_storage.h
+++ /dev/null
@@ -1,1545 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#include <math.h>
-#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)
- {
- memcpy(new_coords,
- m_coord_blocks,
- m_max_blocks * sizeof(T*));
-
- 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);
- }
- }
- }
-
-
-
- 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 = fabs(rx);
- ry = 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_path_storage_integer.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_path_storage_integer.h
deleted file mode 100644
index 7c48355993..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_path_storage_integer.h
+++ /dev/null
@@ -1,295 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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++)
- {
- 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;
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pattern_filters_rgba.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pattern_filters_rgba.h
deleted file mode 100644
index c1d174cacb..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pattern_filters_rgba.h
+++ /dev/null
@@ -1,123 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_amask_adaptor.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_amask_adaptor.h
deleted file mode 100644
index cf39c54ad5..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_amask_adaptor.h
+++ /dev/null
@@ -1,240 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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);
- memset(&m_span[0], amask_type::cover_full, len * sizeof(cover_type));
- }
-
- void init_span(unsigned len, const cover_type* covers)
- {
- realloc_span(len);
- 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 cover)
- {
- 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 cover)
- {
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_base.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_base.h
deleted file mode 100644
index 57ae19cfe0..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_base.h
+++ /dev/null
@@ -1,97 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_gray.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_gray.h
deleted file mode 100644
index 438f04d33d..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_gray.h
+++ /dev/null
@@ -1,737 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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
- {
- pix_width = sizeof(value_type) * Step,
- pix_step = Step,
- pix_offset = Offset,
- };
- struct pixel_type
- {
- value_type c[pix_step];
-
- 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 this + 1;
- }
-
- const pixel_type* next() const
- {
- return this + 1;
- }
-
- pixel_type* advance(int n)
- {
- return this + n;
- }
-
- const pixel_type* advance(int n) const
- {
- return this + n;
- }
- };
-
- 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))
- {
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_rgb.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_rgb.h
deleted file mode 100644
index 7095fbce58..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_rgb.h
+++ /dev/null
@@ -1,994 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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
- {
- pix_step = Step,
- pix_offset = Offset,
- pix_width = sizeof(value_type) * pix_step
- };
- struct pixel_type
- {
- value_type c[pix_step];
-
- 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 this + 1;
- }
-
- const pixel_type* next() const
- {
- return this + 1;
- }
-
- pixel_type* advance(int n)
- {
- return this + n;
- }
-
- const pixel_type* advance(int n) const
- {
- return this + n;
- }
- };
-
- 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))
- {
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_rgb_packed.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_rgb_packed.h
deleted file mode 100644
index d879517de6..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_rgb_packed.h
+++ /dev/null
@@ -1,1312 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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)
- {
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_rgba.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_rgba.h
deleted file mode 100644
index e9cd523b37..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_rgba.h
+++ /dev/null
@@ -1,2801 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#include <math.h>
-#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 r, value_type g, value_type b, value_type a, 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* p,
- value_type r, value_type g, value_type b, value_type a, cover_type cover)
- {
- // 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 r, value_type g, value_type b, 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 r, value_type g, value_type b, 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) * (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 op, 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 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_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 op, 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 op, 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
- {
- pix_step = 4,
- pix_width = sizeof(value_type) * pix_step,
- };
- struct pixel_type
- {
- value_type c[pix_step];
-
- 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 this + 1;
- }
-
- const pixel_type* next() const
- {
- return this + 1;
- }
-
- pixel_type* advance(int n)
- {
- return this + n;
- }
-
- const pixel_type* advance(int n) const
- {
- return this + n;
- }
- };
-
- 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))
- {
- 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
- {
- pix_step = 4,
- pix_width = sizeof(value_type) * pix_step,
- };
- struct pixel_type
- {
- value_type c[pix_step];
-
- 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 this + 1;
- }
-
- const pixel_type* next() const
- {
- return this + 1;
- }
-
- pixel_type* advance(int n)
- {
- return this + n;
- }
-
- const pixel_type* advance(int n) const
- {
- return this + n;
- }
- };
-
-
- 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)
- {
- make_pix(pix_value_ptr(x, y, 1), 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))
- {
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_transposer.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_transposer.h
deleted file mode 100644
index 64738b6c75..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_transposer.h
+++ /dev/null
@@ -1,157 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_cells_aa.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_cells_aa.h
deleted file mode 100644
index d1cc705405..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_cells_aa.h
+++ /dev/null
@@ -1,743 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <stdexcept>
-#include <string.h>
-#include <math.h>
-#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(0x7FFFFFFF),
- m_min_y(0x7FFFFFFF),
- m_max_x(-0x7FFFFFFF),
- m_max_y(-0x7FFFFFFF),
- 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 = 0x7FFFFFFF;
- m_min_y = 0x7FFFFFFF;
- m_max_x = -0x7FFFFFFF;
- m_max_y = -0x7FFFFFFF;
- }
-
- //------------------------------------------------------------------------
- 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) {
- throw std::overflow_error("Exceeded cell block limit");
- }
- 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, 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 = x2 - x1;
-
- if(dx < 0)
- {
- p = fx1 * (y2 - y1);
- first = 0;
- incr = -1;
- dx = -dx;
- }
-
- delta = p / dx;
- mod = 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 = p / dx;
- rem = 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 };
-
- int dx = x2 - x1;
-
- if(dx >= dx_limit || dx <= -dx_limit)
- {
- int cx = (x1 + x2) >> 1;
- int cy = (y1 + y2) >> 1;
- line(x1, y1, cx, cy);
- line(cx, cy, x2, y2);
- return;
- }
-
- int dy = y2 - 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 p, rem, mod, lift, delta, first, incr;
-
- 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 = p / dy;
- mod = 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 = p / dy;
- rem = 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)
- {
- 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 = 0x7FFFFFFF;
- m_curr_cell.y = 0x7FFFFFFF;
- 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) ? 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) ? 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_compound_aa.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_compound_aa.h
deleted file mode 100644
index 41d508010e..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_compound_aa.h
+++ /dev/null
@@ -1,663 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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 = 0x7FFFFFFF;
- y = 0x7FFFFFFF;
- 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 (ex - x) | (ey - y) | (left - c.left) | (right - 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(unsigned cell_block_limit=1024) :
- m_outline(cell_block_limit),
- 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(0x7FFFFFFF),
- m_max_style(-0x7FFFFFFF),
- m_start_x(0),
- m_start_y(0),
- m_scan_y(0x7FFFFFFF),
- 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 = 0x7FFFFFFF;
- m_max_style = -0x7FFFFFFF;
- m_scan_y = 0x7FFFFFFF;
- 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 = -0x7FFFFFFF;
- }
- ++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 = -0x7FFFFFFF;
-
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_outline.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_outline.h
deleted file mode 100644
index 65203e34c5..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_outline.h
+++ /dev/null
@@ -1,147 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_outline_aa.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_outline_aa.h
deleted file mode 100644
index a06bd1e843..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_outline_aa.h
+++ /dev/null
@@ -1,599 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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(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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_scanline_aa.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_scanline_aa.h
deleted file mode 100644
index 1583216646..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_scanline_aa.h
+++ /dev/null
@@ -1,481 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_scanline_aa_nogamma.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_scanline_aa_nogamma.h
deleted file mode 100644
index 7729b3359a..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_scanline_aa_nogamma.h
+++ /dev/null
@@ -1,482 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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 = 0x7FFFFFFF;
- y = 0x7FFFFFFF;
- cover = 0;
- area = 0;
- }
-
- void style(const cell_aa&) {}
-
- int not_equal(int ex, int ey, const cell_aa&) const
- {
- return ex != x || ey != 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_sl_clip.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_sl_clip.h
deleted file mode 100644
index e7ba065acc..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_sl_clip.h
+++ /dev/null
@@ -1,351 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 x1, coord_type y1, coord_type x2, coord_type y2) {}
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_base.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_base.h
deleted file mode 100644
index 527c62f789..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_base.h
+++ /dev/null
@@ -1,731 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_markers.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_markers.h
deleted file mode 100644
index 820f753079..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_markers.h
+++ /dev/null
@@ -1,706 +0,0 @@
-//----------------------------------------------------------------------------
-// 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;
- }
- }
-
-
- //--------------------------------------------------------------------
- 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;
- }
- }
-
- //--------------------------------------------------------------------
- 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;
- }
- }
-
- //--------------------------------------------------------------------
- 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;
- }
- }
-
- //--------------------------------------------------------------------
- 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;
- }
- }
- };
-
-}
-
-#endif
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_mclip.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_mclip.h
deleted file mode 100644
index 96a7d4e094..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_mclip.h
+++ /dev/null
@@ -1,349 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_outline_aa.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_outline_aa.h
deleted file mode 100644
index ee564f04d5..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_outline_aa.h
+++ /dev/null
@@ -1,1837 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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 ? abs(lp.y2 - lp.y1) :
- 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 ? abs((lp.y2 >> line_subpixel_shift) - m_y) :
- 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; }
- 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(abs(sx - lp.x1) + 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(abs(ex - lp.x2) + 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(abs(sx - lp.x1) + 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(abs(ex - lp.x2) + 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_outline_image.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_outline_image.h
deleted file mode 100644
index 8abb9fa0bd..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_outline_image.h
+++ /dev/null
@@ -1,1036 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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() : m_source.pixel(x, y1);
- rgba pix2 = (y2 > h) ? rgba::no_color() : 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 ? abs(lp.y2 - lp.y1) :
- 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 ? abs((lp.y2 >> line_subpixel_shift) - m_y) :
- 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(abs(sx - lp.x1) + 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(abs(ex - lp.x2) + 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_primitives.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_primitives.h
deleted file mode 100644
index f008db7c94..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_primitives.h
+++ /dev/null
@@ -1,224 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_raster_text.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_raster_text.h
deleted file mode 100644
index 87b43f9600..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_raster_text.h
+++ /dev/null
@@ -1,264 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_scanline.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_scanline.h
deleted file mode 100644
index 6d65056c53..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_scanline.h
+++ /dev/null
@@ -1,852 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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(;;)
- {
- 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)
- {
- memset(mix_buffer + sl_start - min_x,
- 0,
- sl_len * sizeof(color_type));
-
- memset(cover_buffer + sl_start - min_x,
- 0,
- sl_len * sizeof(cover_type));
-
- int sl_y = 0x7FFFFFFF;
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rendering_buffer.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rendering_buffer.h
deleted file mode 100644
index 191347f63e..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rendering_buffer.h
+++ /dev/null
@@ -1,300 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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++)
- {
- 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++)
- {
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rendering_buffer_dynarow.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rendering_buffer_dynarow.h
deleted file mode 100644
index 188746f3d3..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rendering_buffer_dynarow.h
+++ /dev/null
@@ -1,137 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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)
- {
- 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);
- 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;
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rounded_rect.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rounded_rect.h
deleted file mode 100644
index fe8d26f71b..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rounded_rect.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_bin.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_bin.h
deleted file mode 100644
index 660292b613..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_bin.h
+++ /dev/null
@@ -1,264 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 min_x, int max_x)
- {
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_boolean_algebra.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_boolean_algebra.h
deleted file mode 100644
index bc2e9c9d51..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_boolean_algebra.h
+++ /dev/null
@@ -1,1567 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <stdlib.h>
-#include <math.h>
-#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(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, 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 + abs((int)span1->len) - 1;
- int xe2 = xb2 + 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 + abs((int)span1->len) - 1;
- --num1;
- }
-
- // Initialize span2 if there are spans
- //---------------
- if(num2)
- {
- span2 = sl2.begin();
- xb2 = span2->x;
- xe2 = xb2 + 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 + abs((int)span1->len) - 1;
- }
-
- // Retrieve a new span2 if it's invalid
- //----------------
- if(num2 && xb2 > xe2)
- {
- --num2;
- ++span2;
- xb2 = span2->x;
- xe2 = xb2 + 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_p.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_p.h
deleted file mode 100644
index 1d1cbe72f1..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_p.h
+++ /dev/null
@@ -1,329 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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)
- {
- 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)
- {
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_storage_aa.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_storage_aa.h
deleted file mode 100644
index b3471fce76..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_storage_aa.h
+++ /dev/null
@@ -1,815 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#include <stdlib.h>
-#include <math.h>
-#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];
- memcpy(ptr, cells, sizeof(T) * num_cells);
- return idx;
- }
- extra_span s;
- s.len = num_cells;
- s.ptr = pod_allocator<T>::allocate(num_cells);
- 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);
- 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( 0x7FFFFFFF),
- m_min_y( 0x7FFFFFFF),
- m_max_x(-0x7FFFFFFF),
- m_max_y(-0x7FFFFFFF),
- 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 = 0x7FFFFFFF;
- m_min_y = 0x7FFFFFFF;
- m_max_x = -0x7FFFFFFF;
- m_max_y = -0x7FFFFFFF;
- 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 = 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)
- {
- memcpy(data, covers, sizeof(T));
- data += sizeof(T);
- }
- else
- {
- 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(0x7FFFFFFF),
- m_min_y(0x7FFFFFFF),
- m_max_x(-0x7FFFFFFF),
- m_max_y(-0x7FFFFFFF)
- {}
-
- //--------------------------------------------------------------------
- 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(0x7FFFFFFF),
- m_min_y(0x7FFFFFFF),
- m_max_x(-0x7FFFFFFF),
- m_max_y(-0x7FFFFFFF)
- {}
-
- //--------------------------------------------------------------------
- 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 = 0x7FFFFFFF;
- m_min_y = 0x7FFFFFFF;
- m_max_x = -0x7FFFFFFF;
- m_max_y = -0x7FFFFFFF;
- }
-
- 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_int32u() + m_dx;
- m_min_y = read_int32u() + m_dy;
- m_max_x = read_int32u() + m_dx;
- m_max_y = read_int32u() + 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_storage_bin.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_storage_bin.h
deleted file mode 100644
index 3ab1adca51..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_storage_bin.h
+++ /dev/null
@@ -1,586 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#include <stdlib.h>
-#include <math.h>
-#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( 0x7FFFFFFF),
- m_min_y( 0x7FFFFFFF),
- m_max_x(-0x7FFFFFFF),
- m_max_y(-0x7FFFFFFF),
- 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 = 0x7FFFFFFF;
- m_min_y = 0x7FFFFFFF;
- m_max_x = -0x7FFFFFFF;
- m_max_y = -0x7FFFFFFF;
- 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)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(0x7FFFFFFF),
- m_min_y(0x7FFFFFFF),
- m_max_x(-0x7FFFFFFF),
- m_max_y(-0x7FFFFFFF)
- {}
-
- //--------------------------------------------------------------------
- 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(0x7FFFFFFF),
- m_min_y(0x7FFFFFFF),
- m_max_x(-0x7FFFFFFF),
- m_max_y(-0x7FFFFFFF)
- {}
-
- //--------------------------------------------------------------------
- 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 = 0x7FFFFFFF;
- m_min_y = 0x7FFFFFFF;
- m_max_x = -0x7FFFFFFF;
- m_max_y = -0x7FFFFFFF;
- }
-
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_u.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_u.h
deleted file mode 100644
index 2628f55f47..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_u.h
+++ /dev/null
@@ -1,499 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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;
- 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;
- 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;
- 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;
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_shorten_path.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_shorten_path.h
deleted file mode 100644
index dd9929ff97..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_shorten_path.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_simul_eq.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_simul_eq.h
deleted file mode 100644
index 3d0dce4b44..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_simul_eq.h
+++ /dev/null
@@ -1,147 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 = 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_allocator.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_allocator.h
deleted file mode 100644
index 201b69bb01..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_allocator.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_converter.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_converter.h
deleted file mode 100644
index 91d0f87c25..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_converter.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gouraud.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gouraud.h
deleted file mode 100644
index 2986c88fee..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gouraud.h
+++ /dev/null
@@ -1,172 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gouraud_gray.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gouraud_gray.h
deleted file mode 100644
index d5fc39d102..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gouraud_gray.h
+++ /dev/null
@@ -1,241 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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 = (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 = 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gouraud_rgba.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gouraud_rgba.h
deleted file mode 100644
index 1b28572029..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gouraud_rgba.h
+++ /dev/null
@@ -1,277 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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 = 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient.h
deleted file mode 100644
index 58b506dcfe..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient.h
+++ /dev/null
@@ -1,377 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#include <stdlib.h>
-#include <string.h>
-#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(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 + sqrt(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 = abs(x);
- int ay = 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 abs(x) * abs(y) / d;
- }
- };
-
- //========================================================gradient_sqrt_xy
- class gradient_sqrt_xy
- {
- public:
- static AGG_INLINE int calculate(int x, int y, int)
- {
- return fast_sqrt(abs(x) * abs(y));
- }
- };
-
- //==========================================================gradient_conic
- class gradient_conic
- {
- public:
- static AGG_INLINE int calculate(int x, int y, int d)
- {
- return uround(fabs(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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient_alpha.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient_alpha.h
deleted file mode 100644
index 2ec040e3b9..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient_alpha.h
+++ /dev/null
@@ -1,126 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 = &af; }
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient_contour.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient_contour.h
deleted file mode 100644
index 899bb799b6..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient_contour.h
+++ /dev/null
@@ -1,362 +0,0 @@
-//----------------------------------------------------------------------------
-// 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"
-
-#define infinity 1E20
-
-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 ] = float(-infinity );
- spang[1 ] = float(+infinity );
-
- 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 ] = float(+infinity);
-
- }
-
- 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)
- {
- 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 (1e20) 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 ] = float(infinity );
- }
- }
-
- }
-
- // 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 = 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] = sqrt(image[l]);
-
- if (min > image[l])
- {
- min = image[l];
- }
-
- if (max < image[l])
- {
- max = image[l];
- }
-
- }
- }
-
- // III. Convert To Grayscale
- if (min == max)
- {
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient_image.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient_image.h
deleted file mode 100644
index c99eaca166..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient_image.h
+++ /dev/null
@@ -1,188 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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 ];
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter.h
deleted file mode 100644
index 2f613e5d86..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter.h
+++ /dev/null
@@ -1,246 +0,0 @@
-//----------------------------------------------------------------------------
-// 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);
-
- if(scale_x * scale_y > m_scale_limit)
- {
- scale_x = scale_x * m_scale_limit / (scale_x * scale_y);
- scale_y = scale_y * m_scale_limit / (scale_x * scale_y);
- }
-
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter_gray.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter_gray.h
deleted file mode 100644
index e2c688e004..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter_gray.h
+++ /dev/null
@@ -1,723 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter_rgb.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter_rgb.h
deleted file mode 100644
index f78ae19c1b..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter_rgb.h
+++ /dev/null
@@ -1,861 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter_rgba.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter_rgba.h
deleted file mode 100644
index af7a1a2ef0..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter_rgba.h
+++ /dev/null
@@ -1,890 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_adaptor.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_adaptor.h
deleted file mode 100644
index 0fdfa77479..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_adaptor.h
+++ /dev/null
@@ -1,77 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_linear.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_linear.h
deleted file mode 100644
index ef10505ce1..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_linear.h
+++ /dev/null
@@ -1,232 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_persp.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_persp.h
deleted file mode 100644
index cad437e04f..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_persp.h
+++ /dev/null
@@ -1,462 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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/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/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/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/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/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/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/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/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/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/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/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/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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_trans.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_trans.h
deleted file mode 100644
index 32bc678a8e..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_trans.h
+++ /dev/null
@@ -1,92 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_pattern_gray.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_pattern_gray.h
deleted file mode 100644
index ae1a49f879..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_pattern_gray.h
+++ /dev/null
@@ -1,93 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_pattern_rgb.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_pattern_rgb.h
deleted file mode 100644
index 4850508af1..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_pattern_rgb.h
+++ /dev/null
@@ -1,96 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_pattern_rgba.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_pattern_rgba.h
deleted file mode 100644
index d47d2a6c02..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_pattern_rgba.h
+++ /dev/null
@@ -1,94 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_solid.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_solid.h
deleted file mode 100644
index ee46df9991..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_solid.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_subdiv_adaptor.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_subdiv_adaptor.h
deleted file mode 100644
index b5b855ec97..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_subdiv_adaptor.h
+++ /dev/null
@@ -1,141 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_affine.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_affine.h
deleted file mode 100644
index 1a61163883..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_affine.h
+++ /dev/null
@@ -1,518 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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.707106781 * sx + 0.707106781 * shx;
- double y = 0.707106781 * shy + 0.707106781 * sy;
- return 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 = cos(a);
- double sa = 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 = sqrt(sx * sx + shx * shx);
- *y = 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(cos(a), sin(a), -sin(a), 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, tan(y), 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(sqrt(dx * dx + dy * dy) / dist));
- }
- multiply(trans_affine_rotation(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(cos(a), sin(a))
- {}
-
-
- trans_affine_reflection(double x, double y) :
- trans_affine_reflection_unit(x / sqrt(x * x + y * y), y / sqrt(x * x + y * y))
- {}
- };
-
-}
-
-
-#endif
-
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_bilinear.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_bilinear.h
deleted file mode 100644
index f3ab596472..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_bilinear.h
+++ /dev/null
@@ -1,166 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_double_path.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_double_path.h
deleted file mode 100644
index c645a7f869..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_double_path.h
+++ /dev/null
@@ -1,131 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_perspective.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_perspective.h
deleted file mode 100644
index 7d4aa26c79..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_perspective.h
+++ /dev/null
@@ -1,731 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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 fabs(sx) > epsilon && fabs(sy) > epsilon && 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 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 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 = sqrt(sx * sx + shx * shx);
- *y = sqrt(shy * shy + sy * sy);
- }
-
-
-}
-
-#endif
-
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_single_path.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_single_path.h
deleted file mode 100644
index 9f4bf53bdb..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_single_path.h
+++ /dev/null
@@ -1,97 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_viewport.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_viewport.h
deleted file mode 100644
index 7088f99078..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_viewport.h
+++ /dev/null
@@ -1,303 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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
- {
- memcpy(ptr, this, sizeof(*this));
- }
-
- void deserialize(const int8u* ptr)
- {
- 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(fabs(m_world_x1 - m_world_x2) < epsilon ||
- fabs(m_world_y1 - m_world_y2) < epsilon ||
- fabs(m_device_x1 - m_device_x2) < epsilon ||
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_warp_magnifier.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_warp_magnifier.h
deleted file mode 100644
index 38a92dbec8..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_warp_magnifier.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_bspline.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_bspline.h
deleted file mode 100644
index a2944548c0..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_bspline.h
+++ /dev/null
@@ -1,74 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_contour.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_contour.h
deleted file mode 100644
index 8c25da13f5..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_contour.h
+++ /dev/null
@@ -1,94 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_dash.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_dash.h
deleted file mode 100644
index c87dce4c81..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_dash.h
+++ /dev/null
@@ -1,93 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_markers_term.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_markers_term.h
deleted file mode 100644
index ee1e74e3eb..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_markers_term.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_smooth_poly1.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_smooth_poly1.h
deleted file mode 100644
index 80fc0fb796..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_smooth_poly1.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_stroke.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_stroke.h
deleted file mode 100644
index 778223fe40..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_stroke.h
+++ /dev/null
@@ -1,102 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_vertex_sequence.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_vertex_sequence.h
deleted file mode 100644
index 5adc671597..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_vertex_sequence.h
+++ /dev/null
@@ -1,135 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vertex_sequence.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vertex_sequence.h
deleted file mode 100644
index 2ad0701b37..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vertex_sequence.h
+++ /dev/null
@@ -1,172 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vpgen_clip_polygon.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vpgen_clip_polygon.h
deleted file mode 100644
index ded754e211..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vpgen_clip_polygon.h
+++ /dev/null
@@ -1,83 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vpgen_clip_polyline.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vpgen_clip_polyline.h
deleted file mode 100644
index b070a7759e..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vpgen_clip_polyline.h
+++ /dev/null
@@ -1,78 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vpgen_segmentator.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vpgen_segmentator.h
deleted file mode 100644
index 29b3c9fa6f..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vpgen_segmentator.h
+++ /dev/null
@@ -1,61 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_bezier_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_bezier_ctrl.h
deleted file mode 100644
index 01851eb3e1..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_bezier_ctrl.h
+++ /dev/null
@@ -1,196 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 i) 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_cbox_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_cbox_ctrl.h
deleted file mode 100644
index 7ecbce27f4..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_cbox_ctrl.h
+++ /dev/null
@@ -1,112 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_ctrl.h
deleted file mode 100644
index 7e811c63e1..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_ctrl.h
+++ /dev/null
@@ -1,118 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_gamma_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_gamma_ctrl.h
deleted file mode 100644
index 0a645a7146..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_gamma_ctrl.h
+++ /dev/null
@@ -1,170 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_gamma_spline.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_gamma_spline.h
deleted file mode 100644
index 4f21710d9f..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_gamma_spline.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_polygon_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_polygon_ctrl.h
deleted file mode 100644
index 6f465d96b8..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_polygon_ctrl.h
+++ /dev/null
@@ -1,166 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 i) 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_rbox_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_rbox_ctrl.h
deleted file mode 100644
index 4d47bccdbb..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_rbox_ctrl.h
+++ /dev/null
@@ -1,141 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_scale_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_scale_ctrl.h
deleted file mode 100644
index b1e32c2037..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_scale_ctrl.h
+++ /dev/null
@@ -1,146 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_slider_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_slider_ctrl.h
deleted file mode 100644
index b50a95c59d..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_slider_ctrl.h
+++ /dev/null
@@ -1,150 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_spline_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_spline_ctrl.h
deleted file mode 100644
index 8477f27d78..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_spline_ctrl.h
+++ /dev/null
@@ -1,159 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/platform/agg_platform_support.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/platform/agg_platform_support.h
deleted file mode 100644
index 9a63411e50..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/platform/agg_platform_support.h
+++ /dev/null
@@ -1,686 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/platform/mac/agg_mac_pmap.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/platform/mac/agg_mac_pmap.h
deleted file mode 100644
index d7860b6fee..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/platform/mac/agg_mac_pmap.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <stdio.h>
-#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/contrib/python/matplotlib/py2/extern/agg24-svn/include/platform/win32/agg_win32_bmp.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/platform/win32/agg_win32_bmp.h
deleted file mode 100644
index 5391e8bb9b..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/platform/win32/agg_win32_bmp.h
+++ /dev/null
@@ -1,117 +0,0 @@
-//----------------------------------------------------------------------------
-// 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>
-#include <stdio.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/contrib/python/matplotlib/py2/extern/agg24-svn/include/util/agg_color_conv.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/util/agg_color_conv.h
deleted file mode 100644
index 8b8a0a55d2..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/util/agg_color_conv.h
+++ /dev/null
@@ -1,128 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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
- {
- 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
- {
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/util/agg_color_conv_rgb16.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/util/agg_color_conv_rgb16.h
deleted file mode 100644
index aaa41322c5..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/util/agg_color_conv_rgb16.h
+++ /dev/null
@@ -1,285 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/include/util/agg_color_conv_rgb8.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/util/agg_color_conv_rgb8.h
deleted file mode 100644
index 609460dba4..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/include/util/agg_color_conv_rgb8.h
+++ /dev/null
@@ -1,476 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/ChangeLog b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ChangeLog
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ChangeLog
+++ /dev/null
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_arc.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_arc.cpp
deleted file mode 100644
index df2c43a559..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_arc.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 + cos(m_end) * m_rx;
- *y = m_y + sin(m_end) * m_ry;
- m_path_cmd = path_cmd_stop;
- return path_cmd_line_to;
- }
-
- *x = m_x + cos(m_angle) * m_rx;
- *y = m_y + 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 = (fabs(m_rx) + fabs(m_ry)) / 2;
- m_da = 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_arrowhead.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_arrowhead.cpp
deleted file mode 100644
index 1a6f8b4100..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_arrowhead.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_bezier_arc.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_bezier_arc.cpp
deleted file mode 100644
index 844d300c09..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_bezier_arc.cpp
+++ /dev/null
@@ -1,258 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 = cos(sweep_angle / 2.0);
- double y0 = 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 = sin(start_angle + sweep_angle / 2.0);
- double cs = 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 = 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(fabs(sweep_angle) < 1e-10)
- {
- m_num_vertices = 4;
- m_cmd = path_cmd_line_to;
- m_vertices[0] = x + rx * cos(start_angle);
- m_vertices[1] = y + ry * sin(start_angle);
- m_vertices[2] = x + rx * cos(start_angle + sweep_angle);
- m_vertices[3] = y + ry * 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 = cos(angle);
- double sin_a = 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 = sqrt(radii_check) * rx;
- ry = 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 * 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 = 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 * acos(v);
-
- // Calculate the sweep angle
- //------------------------
- n = 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 * 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_bspline.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_bspline.cpp
deleted file mode 100644
index e1fda9f51f..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_bspline.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_color_rgba.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_color_rgba.cpp
deleted file mode 100644
index 9fe1534b03..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_color_rgba.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_curves.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_curves.cpp
deleted file mode 100644
index 4701734718..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_curves.cpp
+++ /dev/null
@@ -1,613 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 = sqrt(dx1 * dx1 + dy1 * dy1) + 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 = 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 = fabs(atan2(y3 - y2, x3 - x2) - 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 = (sqrt(dx1 * dx1 + dy1 * dy1) +
- sqrt(dx2 * dx2 + dy2 * dy2) +
- 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 = fabs(((x2 - x4) * dy - (y2 - y4) * dx));
- double d3 = 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 = fabs(atan2(y4 - y3, x4 - x3) - 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 = fabs(atan2(y3 - y2, x3 - x2) - 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 = atan2(y3 - y2, x3 - x2);
- da1 = fabs(k - atan2(y2 - y1, x2 - x1));
- da2 = fabs(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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_embedded_raster_fonts.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_embedded_raster_fonts.cpp
deleted file mode 100644
index ee4dc65ee4..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_embedded_raster_fonts.cpp
+++ /dev/null
@@ -1,10426 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_gsv_text.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_gsv_text.cpp
deleted file mode 100644
index ffb24eb9b6..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_gsv_text.cpp
+++ /dev/null
@@ -1,675 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#include <stdio.h>
-#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 = fopen(file, "rb");
- if(fd)
- {
- unsigned len;
-
- fseek(fd, 0l, SEEK_END);
- len = ftell(fd);
- fseek(fd, 0l, SEEK_SET);
- if(len > 0)
- {
- m_loaded_font.resize(len);
- fread(&m_loaded_font[0], 1, len, fd);
- m_font = &m_loaded_font[0];
- }
- fclose(fd);
- }
- }
-
- //-------------------------------------------------------------------------
- void gsv_text::text(const char* text)
- {
- if(text == 0)
- {
- m_chr[0] = 0;
- m_text = m_chr;
- return;
- }
- unsigned new_size = strlen(text) + 1;
- if(new_size > m_text_buf.size())
- {
- m_text_buf.resize(new_size);
- }
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_image_filters.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_image_filters.cpp
deleted file mode 100644
index 549d9adbf5..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_image_filters.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_line_aa_basics.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_line_aa_basics.cpp
deleted file mode 100644
index 018d65366f..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_line_aa_basics.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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)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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_line_profile_aa.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_line_profile_aa.cpp
deleted file mode 100644
index 6066662cb9..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_line_profile_aa.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_rounded_rect.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_rounded_rect.cpp
deleted file mode 100644
index bebc063628..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_rounded_rect.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 = fabs(m_y2 - m_y1);
- double dy = 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_sqrt_tables.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_sqrt_tables.cpp
deleted file mode 100644
index 19a1bd8cb7..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_sqrt_tables.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_affine.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_affine.cpp
deleted file mode 100644
index 99febc953a..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_affine.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 fabs(sx) > epsilon && 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 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_double_path.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_double_path.cpp
deleted file mode 100644
index cd40c7f586..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_double_path.cpp
+++ /dev/null
@@ -1,273 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_single_path.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_single_path.cpp
deleted file mode 100644
index 2120fc9b9b..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_single_path.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_warp_magnifier.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_warp_magnifier.cpp
deleted file mode 100644
index e65afabba7..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_warp_magnifier.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 = 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 = 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_bspline.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_bspline.cpp
deleted file mode 100644
index 4a0be6693e..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_bspline.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_contour.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_contour.cpp
deleted file mode 100644
index a6a99405ad..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_contour.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_dash.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_dash.cpp
deleted file mode 100644
index 129505786c..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_dash.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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(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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_markers_term.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_markers_term.cpp
deleted file mode 100644
index 3374ab5e82..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_markers_term.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_smooth_poly1.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_smooth_poly1.cpp
deleted file mode 100644
index ff7d488d39..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_smooth_poly1.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_stroke.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_stroke.cpp
deleted file mode 100644
index 2dae3e122b..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_stroke.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vpgen_clip_polygon.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vpgen_clip_polygon.cpp
deleted file mode 100644
index 4524526017..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vpgen_clip_polygon.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vpgen_clip_polyline.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vpgen_clip_polyline.cpp
deleted file mode 100644
index 6840803a98..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vpgen_clip_polyline.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vpgen_segmentator.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vpgen_segmentator.cpp
deleted file mode 100644
index 49a45b6b13..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vpgen_segmentator.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 = 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/authors b/contrib/python/matplotlib/py2/extern/agg24-svn/src/authors
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/authors
+++ /dev/null
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/copying b/contrib/python/matplotlib/py2/extern/agg24-svn/src/copying
deleted file mode 100644
index a08de15faa..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/copying
+++ /dev/null
@@ -1,11 +0,0 @@
-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.
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp
deleted file mode 100644
index 13a4c15af9..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp
+++ /dev/null
@@ -1,370 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 x, double y) 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 x, double y) 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp
deleted file mode 100644
index 3cf14f6a85..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp
deleted file mode 100644
index 7fd6448cd5..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp
+++ /dev/null
@@ -1,433 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp
deleted file mode 100644
index f720fddd8e..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp
deleted file mode 100644
index 40daee45e8..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp
+++ /dev/null
@@ -1,332 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 x, double y) 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 button_flag)
- {
- 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 x, double y)
- {
- bool ret = (m_node >= 0) || (m_edge >= 0);
- m_node = -1;
- m_edge = -1;
- return ret;
- }
-
-
- bool polygon_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up)
- {
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp
deleted file mode 100644
index 4e36b3b26b..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp
+++ /dev/null
@@ -1,325 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp
deleted file mode 100644
index 7f167792bd..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp
+++ /dev/null
@@ -1,454 +0,0 @@
-//----------------------------------------------------------------------------
-// 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;
- }
-
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp
deleted file mode 100644
index ad0048631c..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp
+++ /dev/null
@@ -1,349 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp
deleted file mode 100644
index 74808d4f87..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp
+++ /dev/null
@@ -1,407 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp
deleted file mode 100644
index b14d09cd1c..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp
+++ /dev/null
@@ -1,977 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp
deleted file mode 100644
index 078e141ccb..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp
+++ /dev/null
@@ -1,990 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <stdio.h>
-
-#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 <string.h>
-#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) {
- sprintf(fAppPath, "%s", path.Path());
- } else {
- fprintf(stderr, "getting app parent folder failed: %s\n", strerror(ret));
- }
- } else {
- fprintf(stderr, "making app path failed: %s\n", strerror(ret));
- }
- } else {
- fprintf(stderr, "GetAppInfo() failed: %s\n", 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)
- {
- strcpy(m_caption, "Anti-Grain Geometry Application");
- }
-
-
- //------------------------------------------------------------------------
- platform_support::~platform_support()
- {
- delete m_specific;
- }
-
- //------------------------------------------------------------------------
- void platform_support::caption(const char* cap)
- {
- 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)
- {
- 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];
- 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()) {
- 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 {
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp
deleted file mode 100644
index 46b874d738..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp
+++ /dev/null
@@ -1,1601 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <time.h>
-#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;
- 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)
- {
- 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 = 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 = 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)
- {
- strcpy(m_caption, "AGG Application");
- }
-
- //------------------------------------------------------------------------
- platform_support::~platform_support()
- {
- delete m_specific;
- }
-
-
-
- //------------------------------------------------------------------------
- void platform_support::caption(const char* cap)
- {
- 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)
- {
- 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;
-
-//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))
-// {
-// // 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))
-// {
-// // 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)
- {
- 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)
- {
- fprintf(stderr,
- "RGB masks are not compatible with AGG pixel formats:\n"
- "R=%08x, R=%08x, B=%08x\n", r_mask, g_mask, b_mask);
- XCloseDisplay(m_specific->m_display);
- return false;
- }
-
-
-
- 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)];
-
- 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];
- strcpy(buf, file);
- int len = strlen(buf);
- if(len < 4 || strcasecmp(buf + len - 4, ".ppm") != 0)
- {
- strcat(buf, ".ppm");
- }
-
- FILE* fd = fopen(buf, "rb");
- if(fd == 0) return false;
-
- if((len = fread(buf, 1, 1022, fd)) == 0)
- {
- fclose(fd);
- return false;
- }
- buf[len] = 0;
-
- if(buf[0] != 'P' && buf[1] != '6')
- {
- fclose(fd);
- return false;
- }
-
- char* ptr = buf + 2;
-
- while(*ptr && !isdigit(*ptr)) ptr++;
- if(*ptr == 0)
- {
- fclose(fd);
- return false;
- }
-
- unsigned width = atoi(ptr);
- if(width == 0 || width > 4096)
- {
- fclose(fd);
- return false;
- }
- while(*ptr && isdigit(*ptr)) ptr++;
- while(*ptr && !isdigit(*ptr)) ptr++;
- if(*ptr == 0)
- {
- fclose(fd);
- return false;
- }
- unsigned height = atoi(ptr);
- if(height == 0 || height > 4096)
- {
- fclose(fd);
- return false;
- }
- while(*ptr && isdigit(*ptr)) ptr++;
- while(*ptr && !isdigit(*ptr)) ptr++;
- if(atoi(ptr) != 255)
- {
- fclose(fd);
- return false;
- }
- while(*ptr && isdigit(*ptr)) ptr++;
- if(*ptr == 0)
- {
- fclose(fd);
- return false;
- }
- ptr++;
- fseek(fd, long(ptr - buf), SEEK_SET);
-
- create_img(idx, width, height);
- bool ret = true;
-
- if(m_format == pix_format_rgb24)
- {
- fread(m_specific->m_buf_img[idx], 1, width * height * 3, fd);
- }
- 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);
-
- fread(buf_img, 1, width * height * 3, fd);
-
- 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;
- }
-
- 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];
- strcpy(buf, file);
- int len = strlen(buf);
- if(len < 4 || strcasecmp(buf + len - 4, ".ppm") != 0)
- {
- strcat(buf, ".ppm");
- }
-
- FILE* fd = fopen(buf, "wb");
- if(fd == 0) return false;
-
- unsigned w = rbuf_img(idx).width();
- unsigned h = rbuf_img(idx).height();
-
- 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;
- }
- fwrite(tmp_buf, 1, w * 3, fd);
- }
- delete [] tmp_buf;
- 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)
- {
- fprintf(stderr, "%s\n", msg);
- }
-
- //------------------------------------------------------------------------
- void platform_support::start_timer()
- {
- m_specific->m_sw_start = clock();
- }
-
- //------------------------------------------------------------------------
- double platform_support::elapsed_time() const
- {
- clock_t stop = 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp
deleted file mode 100644
index dc85fd69ff..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp
+++ /dev/null
@@ -1,298 +0,0 @@
-//----------------------------------------------------------------------------
-//
-//----------------------------------------------------------------------------
-// Contact: mcseemagg@yahoo.com
-// baer@karto.baug.ethz.ch
-//----------------------------------------------------------------------------
-//
-// class pixel_map
-//
-//----------------------------------------------------------------------------
-
-#include <string.h>
-#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)
- {
- memset(m_buf, clear_val, m_img_size);
- }
- }
-
-
-
- //------------------------------------------------------------------------
- void pixel_map::clear(unsigned clear_val)
- {
- if(m_buf) 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp
deleted file mode 100644
index f518dbe1f2..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp
+++ /dev/null
@@ -1,1053 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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)
- {
- 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)
- {
- strcpy(m_caption, "Anti-Grain Geometry Application");
- }
-
-
- //------------------------------------------------------------------------
- platform_support::~platform_support()
- {
- delete m_specific;
- }
-
-
-
- //------------------------------------------------------------------------
- void platform_support::caption(const char* cap)
- {
- 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];
- strcpy(fn, file);
- int len = 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
- {
- 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];
- strcpy(fn, file);
- int len = 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
- {
- 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 && strncmp (argv[1], "-psn", 4) == 0 ) {
- argc = 1;
- }
-
-launch:
- return agg_main(argc, argv);
-} \ No newline at end of file
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp
deleted file mode 100644
index 28c6436baa..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp
+++ /dev/null
@@ -1,708 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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)
- {
- 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);
- strcpy(m_caption, "Anti-Grain Geometry Application");
- }
-
-
- //------------------------------------------------------------------------
- platform_support::~platform_support()
- {
- delete m_specific;
- }
-
-
-
- //------------------------------------------------------------------------
- void platform_support::caption(const char* cap)
- {
- 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)
- {
- 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)
- {
- 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];
- strcpy(fn, file);
- int len = strlen(fn);
- if(len < 4 || strcmp(fn + len - 4, ".bmp") != 0)
- {
- strcat(fn, ".bmp");
- }
-
- SDL_Surface* tmp_surf = SDL_LoadBMP(fn);
- if (tmp_surf == 0)
- {
- 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];
- strcpy(fn, file);
- int len = strlen(fn);
- if(len < 4 || strcmp(fn + len - 4, ".bmp") != 0)
- {
- 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)
- {
- 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)
- {
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp
deleted file mode 100644
index ea9123802f..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp
+++ /dev/null
@@ -1,1655 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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)
- {
- strcpy(m_caption, "Anti-Grain Geometry Application");
- }
-
-
- //------------------------------------------------------------------------
- platform_support::~platform_support()
- {
- delete m_specific;
- }
-
-
-
- //------------------------------------------------------------------------
- void platform_support::caption(const char* cap)
- {
- 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];
- strcpy(fn, file);
- int len = strlen(fn);
- if(len < 4 || _stricmp(fn + len - 4, ".BMP") != 0)
- {
- 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];
- strcpy(fn, file);
- int len = strlen(fn);
- if(len < 4 || _stricmp(fn + len - 4, ".BMP") != 0)
- {
- 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 qotation: find one of separator symbols
- if(quote_chr == 0)
- {
- if(sep_len == 1)
- {
- found = check_chr(m_sep, c);
- }
- else
- {
- found = 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 [strlen(lpszCmdLine) + 3];
- char* argv_ptr = argv_str;
-
- char* argv[64];
- 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)
- {
- 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/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp
deleted file mode 100644
index 8c3bdc83fd..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp
+++ /dev/null
@@ -1,631 +0,0 @@
-//----------------------------------------------------------------------------
-//
-//----------------------------------------------------------------------------
-// Contact: mcseemagg@yahoo.com
-//----------------------------------------------------------------------------
-//
-// class pixel_map
-//
-//----------------------------------------------------------------------------
-
-#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)
- {
- 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)
- {
- memset(m_buf, clear_val, m_img_size);
- }
- return h_bitmap;
- }
-
-
-
- //------------------------------------------------------------------------
- void pixel_map::clear(unsigned clear_val)
- {
- if(m_buf) 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;
-
- fread(&bmf, sizeof(bmf), 1, fd);
- if(bmf.bfType != 0x4D42) goto bmperr;
-
- bmp_size = bmf.bfSize - sizeof(BITMAPFILEHEADER);
-
- bmi = (BITMAPINFO*) new unsigned char [bmp_size];
- if(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 = fopen(filename, "rb");
- bool ret = false;
- if(fd)
- {
- ret = load_from_bmp(fd);
- 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;
-
- fwrite(&bmf, sizeof(bmf), 1, fd);
- fwrite(m_bmp, m_full_size, 1, fd);
- return true;
- }
-
-
-
- //------------------------------------------------------------------------
- bool pixel_map::save_as_bmp(const char *filename) const
- {
- FILE *fd = fopen(filename, "wb");
- bool ret = false;
- if(fd)
- {
- ret = save_as_bmp(fd);
- 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;
- }
-}
-
-
-
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/ya.make b/contrib/python/matplotlib/py2/extern/agg24-svn/ya.make
deleted file mode 100644
index c2ae9ed70f..0000000000
--- a/contrib/python/matplotlib/py2/extern/agg24-svn/ya.make
+++ /dev/null
@@ -1,24 +0,0 @@
-LIBRARY()
-
-VERSION(2.2.5)
-
-LICENSE(PSF-2.0)
-
-ADDINCL(
- contrib/python/matplotlib/py2/extern/agg24-svn/include
-)
-
-NO_COMPILER_WARNINGS()
-
-SRCS(
- src/agg_bezier_arc.cpp
- src/agg_curves.cpp
- src/agg_image_filters.cpp
- src/agg_trans_affine.cpp
- src/agg_vcgen_contour.cpp
- src/agg_vcgen_dash.cpp
- src/agg_vcgen_stroke.cpp
- src/agg_vpgen_segmentator.cpp
-)
-
-END()
diff --git a/contrib/python/matplotlib/py2/extern/ttconv/pprdrv.h b/contrib/python/matplotlib/py2/extern/ttconv/pprdrv.h
deleted file mode 100644
index 39e81fee7f..0000000000
--- a/contrib/python/matplotlib/py2/extern/ttconv/pprdrv.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/*
- * Modified for use within matplotlib
- * 5 July 2007
- * Michael Droettboom
- */
-
-/*
-** ~ppr/src/include/pprdrv.h
-** Copyright 1995, Trinity College Computing Center.
-** Written by David Chappell.
-**
-** Permission to use, copy, modify, and distribute this software and its
-** documentation for any purpose and without fee is hereby granted, provided
-** that the above copyright notice appear in all copies and that both that
-** copyright notice and this permission notice appear in supporting
-** documentation. This software is provided "as is" without express or
-** implied warranty.
-**
-** This file last revised 5 December 1995.
-*/
-
-#include <vector>
-#include <cassert>
-
-/*
- * Encapsulates all of the output to write to an arbitrary output
- * function. This both removes the hardcoding of output to go to stdout
- * and makes output thread-safe. Michael Droettboom [06-07-07]
- */
-class TTStreamWriter
-{
- private:
- // Private copy and assignment
- TTStreamWriter& operator=(const TTStreamWriter& other);
- TTStreamWriter(const TTStreamWriter& other);
-
- public:
- TTStreamWriter() { }
- virtual ~TTStreamWriter() { }
-
- virtual void write(const char*) = 0;
-
- virtual void printf(const char* format, ...);
- virtual void put_char(int val);
- virtual void puts(const char* a);
- virtual void putline(const char* a);
-};
-
-class TTDictionaryCallback
-{
-private:
- // Private copy and assignment
- TTDictionaryCallback& operator=(const TTStreamWriter& other);
- TTDictionaryCallback(const TTStreamWriter& other);
-
-public:
- TTDictionaryCallback() { }
- virtual ~TTDictionaryCallback() { }
-
- virtual void add_pair(const char* key, const char* value) = 0;
-};
-
-void replace_newlines_with_spaces(char* a);
-
-/*
- * A simple class for all ttconv exceptions.
- */
-class TTException
-{
- const char* message;
- TTException& operator=(const TTStreamWriter& other);
- TTException(const TTStreamWriter& other);
-
-public:
- TTException(const char* message_) : message(message_) { }
- const char* getMessage()
- {
- return message;
- }
-};
-
-/*
-** No debug code will be included if this
-** is not defined:
-*/
-/* #define DEBUG 1 */
-
-/*
-** Uncomment the defines for the debugging
-** code you want to have included.
-*/
-#ifdef DEBUG
-#define DEBUG_TRUETYPE /* truetype fonts, conversion to Postscript */
-#endif
-
-/* Do not change anything below this line. */
-
-enum font_type_enum
-{
- PS_TYPE_3 = 3,
- PS_TYPE_42 = 42,
- PS_TYPE_42_3_HYBRID = 43,
- PDF_TYPE_3 = -3
-};
-
-/* routines in pprdrv_tt.c */
-void insert_ttfont(const char *filename, TTStreamWriter& stream, font_type_enum target_type, std::vector<int>& glyph_ids);
-
-void get_pdf_charprocs(const char *filename, std::vector<int>& glyph_ids, TTDictionaryCallback& dict);
-
-/* end of file */
diff --git a/contrib/python/matplotlib/py2/extern/ttconv/pprdrv_tt.cpp b/contrib/python/matplotlib/py2/extern/ttconv/pprdrv_tt.cpp
deleted file mode 100644
index abe209856e..0000000000
--- a/contrib/python/matplotlib/py2/extern/ttconv/pprdrv_tt.cpp
+++ /dev/null
@@ -1,1484 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/*
- * Modified for use within matplotlib
- * 5 July 2007
- * Michael Droettboom
- */
-
-/*
-** ~ppr/src/pprdrv/pprdrv_tt.c
-** Copyright 1995, Trinity College Computing Center.
-** Written by David Chappell.
-**
-** Permission to use, copy, modify, and distribute this software and its
-** documentation for any purpose and without fee is hereby granted, provided
-** that the above copyright notice appear in all copies and that both that
-** copyright notice and this permission notice appear in supporting
-** documentation. This software is provided "as is" without express or
-** implied warranty.
-**
-** TrueType font support. These functions allow PPR to generate
-** PostScript fonts from Microsoft compatible TrueType font files.
-**
-** Last revised 19 December 1995.
-*/
-
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include "pprdrv.h"
-#include "truetype.h"
-#include <sstream>
-#ifdef _POSIX_C_SOURCE
-# undef _POSIX_C_SOURCE
-#endif
-#ifndef _AIX
-#ifdef _XOPEN_SOURCE
-# undef _XOPEN_SOURCE
-#endif
-#endif
-#include <Python.h>
-
-/*==========================================================================
-** Convert the indicated Truetype font file to a type 42 or type 3
-** PostScript font and insert it in the output stream.
-**
-** All the routines from here to the end of file file are involved
-** in this process.
-==========================================================================*/
-
-/*---------------------------------------
-** Endian conversion routines.
-** These routines take a BYTE pointer
-** and return a value formed by reading
-** bytes starting at that point.
-**
-** These routines read the big-endian
-** values which are used in TrueType
-** font files.
----------------------------------------*/
-
-/*
-** Get an Unsigned 32 bit number.
-*/
-ULONG getULONG(BYTE *p)
-{
- int x;
- ULONG val=0;
-
- for (x=0; x<4; x++)
- {
- val *= 0x100;
- val += p[x];
- }
-
- return val;
-} /* end of ftohULONG() */
-
-/*
-** Get an unsigned 16 bit number.
-*/
-USHORT getUSHORT(BYTE *p)
-{
- int x;
- USHORT val=0;
-
- for (x=0; x<2; x++)
- {
- val *= 0x100;
- val += p[x];
- }
-
- return val;
-} /* end of getUSHORT() */
-
-/*
-** Get a 32 bit fixed point (16.16) number.
-** A special structure is used to return the value.
-*/
-Fixed getFixed(BYTE *s)
-{
- Fixed val={0,0};
-
- val.whole = ((s[0] * 256) + s[1]);
- val.fraction = ((s[2] * 256) + s[3]);
-
- return val;
-} /* end of getFixed() */
-
-/*-----------------------------------------------------------------------
-** Load a TrueType font table into memory and return a pointer to it.
-** The font's "file" and "offset_table" fields must be set before this
-** routine is called.
-**
-** This first argument is a TrueType font structure, the second
-** argument is the name of the table to retrieve. A table name
-** is always 4 characters, though the last characters may be
-** padding spaces.
------------------------------------------------------------------------*/
-BYTE *GetTable(struct TTFONT *font, const char *name)
-{
- BYTE *ptr;
- ULONG x;
-
-#ifdef DEBUG_TRUETYPE
- debug("GetTable(file,font,\"%s\")",name);
-#endif
-
- /* We must search the table directory. */
- ptr = font->offset_table + 12;
- x=0;
- while (true)
- {
- if ( strncmp((const char*)ptr,name,4) == 0 )
- {
- ULONG offset,length;
- BYTE *table;
-
- offset = getULONG( ptr + 8 );
- length = getULONG( ptr + 12 );
- table = (BYTE*)calloc( sizeof(BYTE), length + 2 );
-
- try
- {
-#ifdef DEBUG_TRUETYPE
- debug("Loading table \"%s\" from offset %d, %d bytes",name,offset,length);
-#endif
-
- if ( fseek( font->file, (long)offset, SEEK_SET ) )
- {
- throw TTException("TrueType font may be corrupt (reason 3)");
- }
-
- if ( fread(table,sizeof(BYTE),length,font->file) != (sizeof(BYTE) * length))
- {
- throw TTException("TrueType font may be corrupt (reason 4)");
- }
- }
- catch (TTException& )
- {
- free(table);
- throw;
- }
- /* Always NUL-terminate; add two in case of UTF16 strings. */
- table[length] = '\0';
- table[length + 1] = '\0';
- return table;
- }
-
- x++;
- ptr += 16;
- if (x == font->numTables)
- {
- throw TTException("TrueType font is missing table");
- }
- }
-
-} /* end of GetTable() */
-
-static void utf16be_to_ascii(char *dst, char *src, size_t length) {
- ++src;
- for (; *src != 0 && length; dst++, src += 2, --length) {
- *dst = *src;
- }
-}
-
-/*--------------------------------------------------------------------
-** Load the 'name' table, get information from it,
-** and store that information in the font structure.
-**
-** The 'name' table contains information such as the name of
-** the font, and it's PostScript name.
---------------------------------------------------------------------*/
-void Read_name(struct TTFONT *font)
-{
- BYTE *table_ptr,*ptr2;
- int numrecords; /* Number of strings in this table */
- BYTE *strings; /* pointer to start of string storage */
- int x;
- int platform; /* Current platform id */
- int nameid; /* name id, */
- int offset,length; /* offset and length of string. */
-
-#ifdef DEBUG_TRUETYPE
- debug("Read_name()");
-#endif
-
- table_ptr = NULL;
-
- /* Set default values to avoid future references to undefined
- * pointers. Allocate each of PostName, FullName, FamilyName,
- * Version, and Style separately so they can be freed safely. */
- for (char **ptr = &(font->PostName); ptr != NULL; )
- {
- *ptr = (char*) calloc(sizeof(char), strlen("unknown")+1);
- strcpy(*ptr, "unknown");
- if (ptr == &(font->PostName)) ptr = &(font->FullName);
- else if (ptr == &(font->FullName)) ptr = &(font->FamilyName);
- else if (ptr == &(font->FamilyName)) ptr = &(font->Version);
- else if (ptr == &(font->Version)) ptr = &(font->Style);
- else ptr = NULL;
- }
- font->Copyright = font->Trademark = (char*)NULL;
-
- table_ptr = GetTable(font, "name"); /* pointer to table */
- try
- {
- numrecords = getUSHORT( table_ptr + 2 ); /* number of names */
- strings = table_ptr + getUSHORT( table_ptr + 4 ); /* start of string storage */
-
- ptr2 = table_ptr + 6;
- for (x=0; x < numrecords; x++,ptr2+=12)
- {
- platform = getUSHORT(ptr2);
- nameid = getUSHORT(ptr2+6);
- length = getUSHORT(ptr2+8);
- offset = getUSHORT(ptr2+10);
-
-#ifdef DEBUG_TRUETYPE
- debug("platform %d, encoding %d, language 0x%x, name %d, offset %d, length %d",
- platform,encoding,language,nameid,offset,length);
-#endif
-
- /* Copyright notice */
- if ( platform == 1 && nameid == 0 )
- {
- font->Copyright = (char*)calloc(sizeof(char),length+1);
- strncpy(font->Copyright,(const char*)strings+offset,length);
- font->Copyright[length]='\0';
- replace_newlines_with_spaces(font->Copyright);
-
-#ifdef DEBUG_TRUETYPE
- debug("font->Copyright=\"%s\"",font->Copyright);
-#endif
- continue;
- }
-
-
- /* Font Family name */
- if ( platform == 1 && nameid == 1 )
- {
- free(font->FamilyName);
- font->FamilyName = (char*)calloc(sizeof(char),length+1);
- strncpy(font->FamilyName,(const char*)strings+offset,length);
- font->FamilyName[length]='\0';
- replace_newlines_with_spaces(font->FamilyName);
-
-#ifdef DEBUG_TRUETYPE
- debug("font->FamilyName=\"%s\"",font->FamilyName);
-#endif
- continue;
- }
-
-
- /* Font Family name */
- if ( platform == 1 && nameid == 2 )
- {
- free(font->Style);
- font->Style = (char*)calloc(sizeof(char),length+1);
- strncpy(font->Style,(const char*)strings+offset,length);
- font->Style[length]='\0';
- replace_newlines_with_spaces(font->Style);
-
-#ifdef DEBUG_TRUETYPE
- debug("font->Style=\"%s\"",font->Style);
-#endif
- continue;
- }
-
-
- /* Full Font name */
- if ( platform == 1 && nameid == 4 )
- {
- free(font->FullName);
- font->FullName = (char*)calloc(sizeof(char),length+1);
- strncpy(font->FullName,(const char*)strings+offset,length);
- font->FullName[length]='\0';
- replace_newlines_with_spaces(font->FullName);
-
-#ifdef DEBUG_TRUETYPE
- debug("font->FullName=\"%s\"",font->FullName);
-#endif
- continue;
- }
-
-
- /* Version string */
- if ( platform == 1 && nameid == 5 )
- {
- free(font->Version);
- font->Version = (char*)calloc(sizeof(char),length+1);
- strncpy(font->Version,(const char*)strings+offset,length);
- font->Version[length]='\0';
- replace_newlines_with_spaces(font->Version);
-
-#ifdef DEBUG_TRUETYPE
- debug("font->Version=\"%s\"",font->Version);
-#endif
- continue;
- }
-
-
- /* PostScript name */
- if ( platform == 1 && nameid == 6 )
- {
- free(font->PostName);
- font->PostName = (char*)calloc(sizeof(char),length+1);
- strncpy(font->PostName,(const char*)strings+offset,length);
- font->PostName[length]='\0';
- replace_newlines_with_spaces(font->PostName);
-
-#ifdef DEBUG_TRUETYPE
- debug("font->PostName=\"%s\"",font->PostName);
-#endif
- continue;
- }
-
- /* Microsoft-format PostScript name */
- if ( platform == 3 && nameid == 6 )
- {
- free(font->PostName);
- font->PostName = (char*)calloc(sizeof(char),length+1);
- utf16be_to_ascii(font->PostName, (char *)strings+offset, length);
- font->PostName[length/2]='\0';
- replace_newlines_with_spaces(font->PostName);
-
-#ifdef DEBUG_TRUETYPE
- debug("font->PostName=\"%s\"",font->PostName);
-#endif
- continue;
- }
-
-
- /* Trademark string */
- if ( platform == 1 && nameid == 7 )
- {
- font->Trademark = (char*)calloc(sizeof(char),length+1);
- strncpy(font->Trademark,(const char*)strings+offset,length);
- font->Trademark[length]='\0';
- replace_newlines_with_spaces(font->Trademark);
-
-#ifdef DEBUG_TRUETYPE
- debug("font->Trademark=\"%s\"",font->Trademark);
-#endif
- continue;
- }
- }
- }
- catch (TTException& )
- {
- free(table_ptr);
- throw;
- }
-
- free(table_ptr);
-} /* end of Read_name() */
-
-/*---------------------------------------------------------------------
-** Write the header for a PostScript font.
----------------------------------------------------------------------*/
-void ttfont_header(TTStreamWriter& stream, struct TTFONT *font)
-{
- int VMMin;
- int VMMax;
-
- /*
- ** To show that it is a TrueType font in PostScript format,
- ** we will begin the file with a specific string.
- ** This string also indicates the version of the TrueType
- ** specification on which the font is based and the
- ** font manufacturer's revision number for the font.
- */
- if ( font->target_type == PS_TYPE_42 ||
- font->target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.printf("%%!PS-TrueTypeFont-%d.%d-%d.%d\n",
- font->TTVersion.whole, font->TTVersion.fraction,
- font->MfrRevision.whole, font->MfrRevision.fraction);
- }
-
- /* If it is not a Type 42 font, we will use a different format. */
- else
- {
- stream.putline("%!PS-Adobe-3.0 Resource-Font");
- } /* See RBIIp 641 */
-
- /* We will make the title the name of the font. */
- stream.printf("%%%%Title: %s\n",font->FullName);
-
- /* If there is a Copyright notice, put it here too. */
- if ( font->Copyright != (char*)NULL )
- {
- stream.printf("%%%%Copyright: %s\n",font->Copyright);
- }
-
- /* We created this file. */
- if ( font->target_type == PS_TYPE_42 )
- {
- stream.putline("%%Creator: Converted from TrueType to type 42 by PPR");
- }
- else if (font->target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.putline("%%Creator: Converted from TypeType to type 42/type 3 hybrid by PPR");
- }
- else
- {
- stream.putline("%%Creator: Converted from TrueType to type 3 by PPR");
- }
-
- /* If VM usage information is available, print it. */
- if ( font->target_type == PS_TYPE_42 || font->target_type == PS_TYPE_42_3_HYBRID)
- {
- VMMin = (int)getULONG( font->post_table + 16 );
- VMMax = (int)getULONG( font->post_table + 20 );
- if ( VMMin > 0 && VMMax > 0 )
- stream.printf("%%%%VMUsage: %d %d\n",VMMin,VMMax);
- }
-
- /* Start the dictionary which will eventually */
- /* become the font. */
- if (font->target_type == PS_TYPE_42)
- {
- stream.putline("15 dict begin");
- }
- else
- {
- stream.putline("25 dict begin");
-
- /* Type 3 fonts will need some subroutines here. */
- stream.putline("/_d{bind def}bind def");
- stream.putline("/_m{moveto}_d");
- stream.putline("/_l{lineto}_d");
- stream.putline("/_cl{closepath eofill}_d");
- stream.putline("/_c{curveto}_d");
- stream.putline("/_sc{7 -1 roll{setcachedevice}{pop pop pop pop pop pop}ifelse}_d");
- stream.putline("/_e{exec}_d");
- }
-
- stream.printf("/FontName /%s def\n",font->PostName);
- stream.putline("/PaintType 0 def");
-
- if (font->target_type == PS_TYPE_42 || font->target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.putline("/FontMatrix[1 0 0 1 0 0]def");
- }
- else
- {
- stream.putline("/FontMatrix[.001 0 0 .001 0 0]def");
- }
-
- stream.printf("/FontBBox[%d %d %d %d]def\n",font->llx-1,font->lly-1,font->urx,font->ury);
- if (font->target_type == PS_TYPE_42 || font->target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.printf("/FontType 42 def\n", font->target_type );
- }
- else
- {
- stream.printf("/FontType 3 def\n", font->target_type );
- }
-} /* end of ttfont_header() */
-
-/*-------------------------------------------------------------
-** Define the encoding array for this font.
-** Since we don't really want to deal with converting all of
-** the possible font encodings in the wild to a standard PS
-** one, we just explicitly create one for each font.
--------------------------------------------------------------*/
-void ttfont_encoding(TTStreamWriter& stream, struct TTFONT *font, std::vector<int>& glyph_ids, font_type_enum target_type)
-{
- if (target_type == PS_TYPE_3 || target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.printf("/Encoding [ ");
-
- for (std::vector<int>::const_iterator i = glyph_ids.begin();
- i != glyph_ids.end(); ++i)
- {
- const char* name = ttfont_CharStrings_getname(font, *i);
- stream.printf("/%s ", name);
- }
-
- stream.printf("] def\n");
- }
- else
- {
- stream.putline("/Encoding StandardEncoding def");
- }
-} /* end of ttfont_encoding() */
-
-/*-----------------------------------------------------------
-** Create the optional "FontInfo" sub-dictionary.
------------------------------------------------------------*/
-void ttfont_FontInfo(TTStreamWriter& stream, struct TTFONT *font)
-{
- Fixed ItalicAngle;
-
- /* We create a sub dictionary named "FontInfo" where we */
- /* store information which though it is not used by the */
- /* interpreter, is useful to some programs which will */
- /* be printing with the font. */
- stream.putline("/FontInfo 10 dict dup begin");
-
- /* These names come from the TrueType font's "name" table. */
- stream.printf("/FamilyName (%s) def\n",font->FamilyName);
- stream.printf("/FullName (%s) def\n",font->FullName);
-
- if ( font->Copyright != (char*)NULL || font->Trademark != (char*)NULL )
- {
- stream.printf("/Notice (%s",
- font->Copyright != (char*)NULL ? font->Copyright : "");
- stream.printf("%s%s) def\n",
- font->Trademark != (char*)NULL ? " " : "",
- font->Trademark != (char*)NULL ? font->Trademark : "");
- }
-
- /* This information is not quite correct. */
- stream.printf("/Weight (%s) def\n",font->Style);
-
- /* Some fonts have this as "version". */
- stream.printf("/Version (%s) def\n",font->Version);
-
- /* Some information from the "post" table. */
- ItalicAngle = getFixed( font->post_table + 4 );
- stream.printf("/ItalicAngle %d.%d def\n",ItalicAngle.whole,ItalicAngle.fraction);
- stream.printf("/isFixedPitch %s def\n", getULONG( font->post_table + 12 ) ? "true" : "false" );
- stream.printf("/UnderlinePosition %d def\n", (int)getFWord( font->post_table + 8 ) );
- stream.printf("/UnderlineThickness %d def\n", (int)getFWord( font->post_table + 10 ) );
- stream.putline("end readonly def");
-} /* end of ttfont_FontInfo() */
-
-/*-------------------------------------------------------------------
-** sfnts routines
-** These routines generate the PostScript "sfnts" array which
-** contains one or more strings which contain a reduced version
-** of the TrueType font.
-**
-** A number of functions are required to accomplish this rather
-** complicated task.
--------------------------------------------------------------------*/
-int string_len;
-int line_len;
-bool in_string;
-
-/*
-** This is called once at the start.
-*/
-void sfnts_start(TTStreamWriter& stream)
-{
- stream.puts("/sfnts[<");
- in_string=true;
- string_len=0;
- line_len=8;
-} /* end of sfnts_start() */
-
-/*
-** Write a BYTE as a hexadecimal value as part of the sfnts array.
-*/
-void sfnts_pputBYTE(TTStreamWriter& stream, BYTE n)
-{
- static const char hexdigits[]="0123456789ABCDEF";
-
- if (!in_string)
- {
- stream.put_char('<');
- string_len=0;
- line_len++;
- in_string=true;
- }
-
- stream.put_char( hexdigits[ n / 16 ] );
- stream.put_char( hexdigits[ n % 16 ] );
- string_len++;
- line_len+=2;
-
- if (line_len > 70)
- {
- stream.put_char('\n');
- line_len=0;
- }
-
-} /* end of sfnts_pputBYTE() */
-
-/*
-** Write a USHORT as a hexadecimal value as part of the sfnts array.
-*/
-void sfnts_pputUSHORT(TTStreamWriter& stream, USHORT n)
-{
- sfnts_pputBYTE(stream, n / 256);
- sfnts_pputBYTE(stream, n % 256);
-} /* end of sfnts_pputUSHORT() */
-
-/*
-** Write a ULONG as part of the sfnts array.
-*/
-void sfnts_pputULONG(TTStreamWriter& stream, ULONG n)
-{
- int x1,x2,x3;
-
- x1 = n % 256;
- n /= 256;
- x2 = n % 256;
- n /= 256;
- x3 = n % 256;
- n /= 256;
-
- sfnts_pputBYTE(stream, n);
- sfnts_pputBYTE(stream, x3);
- sfnts_pputBYTE(stream, x2);
- sfnts_pputBYTE(stream, x1);
-} /* end of sfnts_pputULONG() */
-
-/*
-** This is called whenever it is
-** necessary to end a string in the sfnts array.
-**
-** (The array must be broken into strings which are
-** no longer than 64K characters.)
-*/
-void sfnts_end_string(TTStreamWriter& stream)
-{
- if (in_string)
- {
- string_len=0; /* fool sfnts_pputBYTE() */
-
-#ifdef DEBUG_TRUETYPE_INLINE
- puts("\n% dummy byte:\n");
-#endif
-
- sfnts_pputBYTE(stream, 0); /* extra byte for pre-2013 compatibility */
- stream.put_char('>');
- line_len++;
- }
- in_string=false;
-} /* end of sfnts_end_string() */
-
-/*
-** This is called at the start of each new table.
-** The argement is the length in bytes of the table
-** which will follow. If the new table will not fit
-** in the current string, a new one is started.
-*/
-void sfnts_new_table(TTStreamWriter& stream, ULONG length)
-{
- if ( (string_len + length) > 65528 )
- sfnts_end_string(stream);
-} /* end of sfnts_new_table() */
-
-/*
-** We may have to break up the 'glyf' table. That is the reason
-** why we provide this special routine to copy it into the sfnts
-** array.
-*/
-void sfnts_glyf_table(TTStreamWriter& stream, struct TTFONT *font, ULONG oldoffset, ULONG correct_total_length)
-{
- ULONG off;
- ULONG length;
- int c;
- ULONG total=0; /* running total of bytes written to table */
- int x;
- bool loca_is_local=false;
-
-#ifdef DEBUG_TRUETYPE
- debug("sfnts_glyf_table(font,%d)", (int)correct_total_length);
-#endif
-
- if (font->loca_table == NULL)
- {
- font->loca_table = GetTable(font,"loca");
- loca_is_local = true;
- }
-
- /* Seek to proper position in the file. */
- fseek( font->file, oldoffset, SEEK_SET );
-
- /* Copy the glyphs one by one */
- for (x=0; x < font->numGlyphs; x++)
- {
- /* Read the glyph offset from the index-to-location table. */
- if (font->indexToLocFormat == 0)
- {
- off = getUSHORT( font->loca_table + (x * 2) );
- off *= 2;
- length = getUSHORT( font->loca_table + ((x+1) * 2) );
- length *= 2;
- length -= off;
- }
- else
- {
- off = getULONG( font->loca_table + (x * 4) );
- length = getULONG( font->loca_table + ((x+1) * 4) );
- length -= off;
- }
-
-#ifdef DEBUG_TRUETYPE
- debug("glyph length=%d",(int)length);
-#endif
-
- /* Start new string if necessary. */
- sfnts_new_table( stream, (int)length );
-
- /*
- ** Make sure the glyph is padded out to a
- ** two byte boundary.
- */
- if ( length % 2 ) {
- throw TTException("TrueType font contains a 'glyf' table without 2 byte padding");
- }
-
- /* Copy the bytes of the glyph. */
- while ( length-- )
- {
- if ( (c = fgetc(font->file)) == EOF ) {
- throw TTException("TrueType font may be corrupt (reason 6)");
- }
-
- sfnts_pputBYTE(stream, c);
- total++; /* add to running total */
- }
-
- }
-
- if (loca_is_local)
- {
- free(font->loca_table);
- font->loca_table = NULL;
- }
-
- /* Pad out to full length from table directory */
- while ( total < correct_total_length )
- {
- sfnts_pputBYTE(stream, 0);
- total++;
- }
-
-} /* end of sfnts_glyf_table() */
-
-/*
-** Here is the routine which ties it all together.
-**
-** Create the array called "sfnts" which
-** holds the actual TrueType data.
-*/
-void ttfont_sfnts(TTStreamWriter& stream, struct TTFONT *font)
-{
- static const char *table_names[] = /* The names of all tables */
- {
- /* which it is worth while */
- "cvt ", /* to include in a Type 42 */
- "fpgm", /* PostScript font. */
- "glyf",
- "head",
- "hhea",
- "hmtx",
- "loca",
- "maxp",
- "prep"
- } ;
-
- struct /* The location of each of */
- {
- ULONG oldoffset; /* the above tables. */
- ULONG newoffset;
- ULONG length;
- ULONG checksum;
- } tables[9];
-
- BYTE *ptr; /* A pointer into the origional table directory. */
- ULONG x,y; /* General use loop countes. */
- int c; /* Input character. */
- int diff;
- ULONG nextoffset;
- int count; /* How many `important' tables did we find? */
-
- ptr = font->offset_table + 12;
- nextoffset=0;
- count=0;
-
- /*
- ** Find the tables we want and store there vital
- ** statistics in tables[].
- */
- ULONG num_tables_read = 0; /* Number of tables read from the directory */
- for (x = 0; x < 9; x++) {
- do {
- if (num_tables_read < font->numTables) {
- /* There are still tables to read from ptr */
- diff = strncmp((char*)ptr, table_names[x], 4);
-
- if (diff > 0) { /* If we are past it. */
- tables[x].length = 0;
- diff = 0;
- } else if (diff < 0) { /* If we haven't hit it yet. */
- ptr += 16;
- num_tables_read++;
- } else if (diff == 0) { /* Here it is! */
- tables[x].newoffset = nextoffset;
- tables[x].checksum = getULONG( ptr + 4 );
- tables[x].oldoffset = getULONG( ptr + 8 );
- tables[x].length = getULONG( ptr + 12 );
- nextoffset += ( ((tables[x].length + 3) / 4) * 4 );
- count++;
- ptr += 16;
- num_tables_read++;
- }
- } else {
- /* We've read the whole table directory already */
- /* Some tables couldn't be found */
- tables[x].length = 0;
- break; /* Proceed to next tables[x] */
- }
- } while (diff != 0);
-
- } /* end of for loop which passes over the table directory */
-
- /* Begin the sfnts array. */
- sfnts_start(stream);
-
- /* Generate the offset table header */
- /* Start by copying the TrueType version number. */
- ptr = font->offset_table;
- for (x=0; x < 4; x++)
- {
- sfnts_pputBYTE( stream, *(ptr++) );
- }
-
- /* Now, generate those silly numTables numbers. */
- sfnts_pputUSHORT(stream, count); /* number of tables */
-
- int search_range = 1;
- int entry_sel = 0;
-
- while (search_range <= count) {
- search_range <<= 1;
- entry_sel++;
- }
- entry_sel = entry_sel > 0 ? entry_sel - 1 : 0;
- search_range = (search_range >> 1) * 16;
- int range_shift = count * 16 - search_range;
-
- sfnts_pputUSHORT(stream, search_range); /* searchRange */
- sfnts_pputUSHORT(stream, entry_sel); /* entrySelector */
- sfnts_pputUSHORT(stream, range_shift); /* rangeShift */
-
-#ifdef DEBUG_TRUETYPE
- debug("only %d tables selected",count);
-#endif
-
- /* Now, emmit the table directory. */
- for (x=0; x < 9; x++)
- {
- if ( tables[x].length == 0 ) /* Skip missing tables */
- {
- continue;
- }
-
- /* Name */
- sfnts_pputBYTE( stream, table_names[x][0] );
- sfnts_pputBYTE( stream, table_names[x][1] );
- sfnts_pputBYTE( stream, table_names[x][2] );
- sfnts_pputBYTE( stream, table_names[x][3] );
-
- /* Checksum */
- sfnts_pputULONG( stream, tables[x].checksum );
-
- /* Offset */
- sfnts_pputULONG( stream, tables[x].newoffset + 12 + (count * 16) );
-
- /* Length */
- sfnts_pputULONG( stream, tables[x].length );
- }
-
- /* Now, send the tables */
- for (x=0; x < 9; x++)
- {
- if ( tables[x].length == 0 ) /* skip tables that aren't there */
- {
- continue;
- }
-
-#ifdef DEBUG_TRUETYPE
- debug("emmiting table '%s'",table_names[x]);
-#endif
-
- /* 'glyf' table gets special treatment */
- if ( strcmp(table_names[x],"glyf")==0 )
- {
- sfnts_glyf_table(stream,font,tables[x].oldoffset,tables[x].length);
- }
- else /* Other tables may not exceed */
- {
- /* 65535 bytes in length. */
- if ( tables[x].length > 65535 )
- {
- throw TTException("TrueType font has a table which is too long");
- }
-
- /* Start new string if necessary. */
- sfnts_new_table(stream, tables[x].length);
-
- /* Seek to proper position in the file. */
- fseek( font->file, tables[x].oldoffset, SEEK_SET );
-
- /* Copy the bytes of the table. */
- for ( y=0; y < tables[x].length; y++ )
- {
- if ( (c = fgetc(font->file)) == EOF )
- {
- throw TTException("TrueType font may be corrupt (reason 7)");
- }
-
- sfnts_pputBYTE(stream, c);
- }
- }
-
- /* Padd it out to a four byte boundary. */
- y=tables[x].length;
- while ( (y % 4) != 0 )
- {
- sfnts_pputBYTE(stream, 0);
- y++;
-#ifdef DEBUG_TRUETYPE_INLINE
- puts("\n% pad byte:\n");
-#endif
- }
-
- } /* End of loop for all tables */
-
- /* Close the array. */
- sfnts_end_string(stream);
- stream.putline("]def");
-} /* end of ttfont_sfnts() */
-
-/*--------------------------------------------------------------
-** Create the CharStrings dictionary which will translate
-** PostScript character names to TrueType font character
-** indexes.
-**
-** If we are creating a type 3 instead of a type 42 font,
-** this array will instead convert PostScript character names
-** to executable proceedures.
---------------------------------------------------------------*/
-const char *Apple_CharStrings[]=
-{
- ".notdef",".null","nonmarkingreturn","space","exclam","quotedbl","numbersign",
- "dollar","percent","ampersand","quotesingle","parenleft","parenright",
- "asterisk","plus", "comma","hyphen","period","slash","zero","one","two",
- "three","four","five","six","seven","eight","nine","colon","semicolon",
- "less","equal","greater","question","at","A","B","C","D","E","F","G","H","I",
- "J","K", "L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
- "bracketleft","backslash","bracketright","asciicircum","underscore","grave",
- "a","b","c","d","e","f","g","h","i","j","k", "l","m","n","o","p","q","r","s",
- "t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde",
- "Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis",
- "aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla",
- "eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex",
- "idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde",
- "uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent",
- "sterling","section","bullet","paragraph","germandbls","registered",
- "copyright","trademark","acute","dieresis","notequal","AE","Oslash",
- "infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff",
- "summation","product","pi","integral","ordfeminine","ordmasculine","Omega",
- "ae","oslash","questiondown","exclamdown","logicalnot","radical","florin",
- "approxequal","Delta","guillemotleft","guillemotright","ellipsis",
- "nobreakspace","Agrave","Atilde","Otilde","OE","oe","endash","emdash",
- "quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge",
- "ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright",
- "fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase",
- "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave",
- "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple",
- "Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde",
- "macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron",
- "Lslash","lslash","Scaron","scaron","Zcaron","zcaron","brokenbar","Eth","eth",
- "Yacute","yacute","Thorn","thorn","minus","multiply","onesuperior",
- "twosuperior","threesuperior","onehalf","onequarter","threequarters","franc",
- "Gbreve","gbreve","Idot","Scedilla","scedilla","Cacute","cacute","Ccaron",
- "ccaron","dmacron","markingspace","capslock","shift","propeller","enter",
- "markingtabrtol","markingtabltor","control","markingdeleteltor",
- "markingdeletertol","option","escape","parbreakltor","parbreakrtol",
- "newpage","checkmark","linebreakltor","linebreakrtol","markingnobreakspace",
- "diamond","appleoutline"
-};
-
-/*
-** This routine is called by the one below.
-** It is also called from pprdrv_tt2.c
-*/
-const char *ttfont_CharStrings_getname(struct TTFONT *font, int charindex)
-{
- int GlyphIndex;
- static char temp[80];
- char *ptr;
- ULONG len;
-
- Fixed post_format;
-
- /* The 'post' table format number. */
- post_format = getFixed( font->post_table );
-
- if ( post_format.whole != 2 || post_format.fraction != 0 )
- {
- /* We don't have a glyph name table, so generate a name.
- This generated name must match exactly the name that is
- generated by FT2Font in get_glyph_name */
- PyOS_snprintf(temp, 80, "uni%08x", charindex);
- return temp;
- }
-
- GlyphIndex = (int)getUSHORT( font->post_table + 34 + (charindex * 2) );
-
- if ( GlyphIndex <= 257 ) /* If a standard Apple name, */
- {
- return Apple_CharStrings[GlyphIndex];
- }
- else /* Otherwise, use one */
- {
- /* of the pascal strings. */
- GlyphIndex -= 258;
-
- /* Set pointer to start of Pascal strings. */
- ptr = (char*)(font->post_table + 34 + (font->numGlyphs * 2));
-
- len = (ULONG)*(ptr++); /* Step thru the strings */
- while (GlyphIndex--) /* until we get to the one */
- {
- /* that we want. */
- ptr += len;
- len = (ULONG)*(ptr++);
- }
-
- if ( len >= sizeof(temp) )
- {
- throw TTException("TrueType font file contains a very long PostScript name");
- }
-
- strncpy(temp,ptr,len); /* Copy the pascal string into */
- temp[len]='\0'; /* a buffer and make it ASCIIz. */
-
- return temp;
- }
-} /* end of ttfont_CharStrings_getname() */
-
-/*
-** This is the central routine of this section.
-*/
-void ttfont_CharStrings(TTStreamWriter& stream, struct TTFONT *font, std::vector<int>& glyph_ids)
-{
- Fixed post_format;
-
- /* The 'post' table format number. */
- post_format = getFixed( font->post_table );
-
- /* Emmit the start of the PostScript code to define the dictionary. */
- stream.printf("/CharStrings %d dict dup begin\n", glyph_ids.size()+1);
- /* Section 5.8.2 table 5.7 of the PS Language Ref says a CharStrings dictionary must contain an entry for .notdef */
- stream.printf("/.notdef 0 def\n");
-
- /* Emmit one key-value pair for each glyph. */
- for (std::vector<int>::const_iterator i = glyph_ids.begin();
- i != glyph_ids.end(); ++i)
- {
- if ((font->target_type == PS_TYPE_42 ||
- font->target_type == PS_TYPE_42_3_HYBRID)
- && *i < 256) /* type 42 */
- {
- stream.printf("/%s %d def\n",ttfont_CharStrings_getname(font, *i), *i);
- }
- else /* type 3 */
- {
- stream.printf("/%s{",ttfont_CharStrings_getname(font, *i));
-
- tt_type3_charproc(stream, font, *i);
-
- stream.putline("}_d"); /* "} bind def" */
- }
- }
-
- stream.putline("end readonly def");
-} /* end of ttfont_CharStrings() */
-
-/*----------------------------------------------------------------
-** Emmit the code to finish up the dictionary and turn
-** it into a font.
-----------------------------------------------------------------*/
-void ttfont_trailer(TTStreamWriter& stream, struct TTFONT *font)
-{
- /* If we are generating a type 3 font, we need to provide */
- /* a BuildGlyph and BuildChar proceedures. */
- if (font->target_type == PS_TYPE_3 ||
- font->target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.put_char('\n');
-
- stream.putline("/BuildGlyph");
- stream.putline(" {exch begin"); /* start font dictionary */
- stream.putline(" CharStrings exch");
- stream.putline(" 2 copy known not{pop /.notdef}if");
- stream.putline(" true 3 1 roll get exec");
- stream.putline(" end}_d");
-
- stream.put_char('\n');
-
- /* This proceedure is for compatibility with */
- /* level 1 interpreters. */
- stream.putline("/BuildChar {");
- stream.putline(" 1 index /Encoding get exch get");
- stream.putline(" 1 index /BuildGlyph get exec");
- stream.putline("}_d");
-
- stream.put_char('\n');
- }
-
- /* If we are generating a type 42 font, we need to check to see */
- /* if this PostScript interpreter understands type 42 fonts. If */
- /* it doesn't, we will hope that the Apple TrueType rasterizer */
- /* has been loaded and we will adjust the font accordingly. */
- /* I found out how to do this by examining a TrueType font */
- /* generated by a Macintosh. That is where the TrueType interpreter */
- /* setup instructions and part of BuildGlyph came from. */
- if (font->target_type == PS_TYPE_42 ||
- font->target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.put_char('\n');
-
- /* If we have no "resourcestatus" command, or FontType 42 */
- /* is unknown, leave "true" on the stack. */
- stream.putline("systemdict/resourcestatus known");
- stream.putline(" {42 /FontType resourcestatus");
- stream.putline(" {pop pop false}{true}ifelse}");
- stream.putline(" {true}ifelse");
-
- /* If true, execute code to produce an error message if */
- /* we can't find Apple's TrueDict in VM. */
- stream.putline("{/TrueDict where{pop}{(%%[ Error: no TrueType rasterizer ]%%)= flush}ifelse");
-
- /* Since we are expected to use Apple's TrueDict TrueType */
- /* reasterizer, change the font type to 3. */
- stream.putline("/FontType 3 def");
-
- /* Define a string to hold the state of the Apple */
- /* TrueType interpreter. */
- stream.putline(" /TrueState 271 string def");
-
- /* It looks like we get information about the resolution */
- /* of the printer and store it in the TrueState string. */
- stream.putline(" TrueDict begin sfnts save");
- stream.putline(" 72 0 matrix defaultmatrix dtransform dup");
- stream.putline(" mul exch dup mul add sqrt cvi 0 72 matrix");
- stream.putline(" defaultmatrix dtransform dup mul exch dup");
- stream.putline(" mul add sqrt cvi 3 -1 roll restore");
- stream.putline(" TrueState initer end");
-
- /* This BuildGlyph procedure will look the name up in the */
- /* CharStrings array, and then check to see if what it gets */
- /* is a procedure. If it is, it executes it, otherwise, it */
- /* lets the TrueType rasterizer loose on it. */
-
- /* When this proceedure is executed the stack contains */
- /* the font dictionary and the character name. We */
- /* exchange arguments and move the dictionary to the */
- /* dictionary stack. */
- stream.putline(" /BuildGlyph{exch begin");
- /* stack: charname */
-
- /* Put two copies of CharStrings on the stack and consume */
- /* one testing to see if the charname is defined in it, */
- /* leave the answer on the stack. */
- stream.putline(" CharStrings dup 2 index known");
- /* stack: charname CharStrings bool */
-
- /* Exchange the CharStrings dictionary and the charname, */
- /* but if the answer was false, replace the character name */
- /* with ".notdef". */
- stream.putline(" {exch}{exch pop /.notdef}ifelse");
- /* stack: CharStrings charname */
-
- /* Get the value from the CharStrings dictionary and see */
- /* if it is executable. */
- stream.putline(" get dup xcheck");
- /* stack: CharStrings_entry */
-
- /* If is a proceedure. Execute according to RBIIp 277-278. */
- stream.putline(" {currentdict systemdict begin begin exec end end}");
-
- /* Is a TrueType character index, let the rasterizer at it. */
- stream.putline(" {TrueDict begin /bander load cvlit exch TrueState render end}");
-
- stream.putline(" ifelse");
-
- /* Pop the font's dictionary off the stack. */
- stream.putline(" end}bind def");
-
- /* This is the level 1 compatibility BuildChar procedure. */
- /* See RBIIp 281. */
- stream.putline(" /BuildChar{");
- stream.putline(" 1 index /Encoding get exch get");
- stream.putline(" 1 index /BuildGlyph get exec");
- stream.putline(" }bind def");
-
- /* Here we close the condition which is true */
- /* if the printer has no built-in TrueType */
- /* rasterizer. */
- stream.putline("}if");
- stream.put_char('\n');
- } /* end of if Type 42 not understood. */
-
- stream.putline("FontName currentdict end definefont pop");
- /* stream.putline("%%EOF"); */
-} /* end of ttfont_trailer() */
-
-/*------------------------------------------------------------------
-** This is the externally callable routine which inserts the font.
-------------------------------------------------------------------*/
-
-void read_font(const char *filename, font_type_enum target_type, std::vector<int>& glyph_ids, TTFONT& font)
-{
- BYTE *ptr;
-
- /* Decide what type of PostScript font we will be generating. */
- font.target_type = target_type;
-
- if (font.target_type == PS_TYPE_42)
- {
- bool has_low = false;
- bool has_high = false;
-
- for (std::vector<int>::const_iterator i = glyph_ids.begin();
- i != glyph_ids.end(); ++i)
- {
- if (*i > 255)
- {
- has_high = true;
- if (has_low) break;
- }
- else
- {
- has_low = true;
- if (has_high) break;
- }
- }
-
- if (has_high && has_low)
- {
- font.target_type = PS_TYPE_42_3_HYBRID;
- }
- else if (has_high && !has_low)
- {
- font.target_type = PS_TYPE_3;
- }
- }
-
- /* Save the file name for error messages. */
- font.filename=filename;
-
- /* Open the font file */
- if ( (font.file = fopen(filename,"rb")) == (FILE*)NULL )
- {
- throw TTException("Failed to open TrueType font");
- }
-
- /* Allocate space for the unvarying part of the offset table. */
- assert(font.offset_table == NULL);
- font.offset_table = (BYTE*)calloc( 12, sizeof(BYTE) );
-
- /* Read the first part of the offset table. */
- if ( fread( font.offset_table, sizeof(BYTE), 12, font.file ) != 12 )
- {
- throw TTException("TrueType font may be corrupt (reason 1)");
- }
-
- /* Determine how many directory entries there are. */
- font.numTables = getUSHORT( font.offset_table + 4 );
-#ifdef DEBUG_TRUETYPE
- debug("numTables=%d",(int)font.numTables);
-#endif
-
- /* Expand the memory block to hold the whole thing. */
- font.offset_table = (BYTE*)realloc( font.offset_table, sizeof(BYTE) * (12 + font.numTables * 16) );
-
- /* Read the rest of the table directory. */
- if ( fread( font.offset_table + 12, sizeof(BYTE), (font.numTables*16), font.file ) != (font.numTables*16) )
- {
- throw TTException("TrueType font may be corrupt (reason 2)");
- }
-
- /* Extract information from the "Offset" table. */
- font.TTVersion = getFixed( font.offset_table );
-
- /* Load the "head" table and extract information from it. */
- ptr = GetTable(&font, "head");
- try
- {
- font.MfrRevision = getFixed( ptr + 4 ); /* font revision number */
- font.unitsPerEm = getUSHORT( ptr + 18 );
- font.HUPM = font.unitsPerEm / 2;
-#ifdef DEBUG_TRUETYPE
- debug("unitsPerEm=%d",(int)font.unitsPerEm);
-#endif
- font.llx = topost2( getFWord( ptr + 36 ) ); /* bounding box info */
- font.lly = topost2( getFWord( ptr + 38 ) );
- font.urx = topost2( getFWord( ptr + 40 ) );
- font.ury = topost2( getFWord( ptr + 42 ) );
- font.indexToLocFormat = getSHORT( ptr + 50 ); /* size of 'loca' data */
- if (font.indexToLocFormat != 0 && font.indexToLocFormat != 1)
- {
- throw TTException("TrueType font is unusable because indexToLocFormat != 0");
- }
- if ( getSHORT(ptr+52) != 0 )
- {
- throw TTException("TrueType font is unusable because glyphDataFormat != 0");
- }
- }
- catch (TTException& )
- {
- free(ptr);
- throw;
- }
- free(ptr);
-
- /* Load information from the "name" table. */
- Read_name(&font);
-
- /* We need to have the PostScript table around. */
- assert(font.post_table == NULL);
- font.post_table = GetTable(&font, "post");
- font.numGlyphs = getUSHORT( font.post_table + 32 );
-
- /* If we are generating a Type 3 font, we will need to */
- /* have the 'loca' and 'glyf' tables arround while */
- /* we are generating the CharStrings. */
- if (font.target_type == PS_TYPE_3 || font.target_type == PDF_TYPE_3 ||
- font.target_type == PS_TYPE_42_3_HYBRID)
- {
- BYTE *ptr; /* We need only one value */
- ptr = GetTable(&font, "hhea");
- font.numberOfHMetrics = getUSHORT(ptr + 34);
- free(ptr);
-
- assert(font.loca_table == NULL);
- font.loca_table = GetTable(&font,"loca");
- assert(font.glyf_table == NULL);
- font.glyf_table = GetTable(&font,"glyf");
- assert(font.hmtx_table == NULL);
- font.hmtx_table = GetTable(&font,"hmtx");
- }
-
- if (glyph_ids.size() == 0)
- {
- glyph_ids.clear();
- glyph_ids.reserve(font.numGlyphs);
- for (int x = 0; x < font.numGlyphs; ++x)
- {
- glyph_ids.push_back(x);
- }
- }
- else if (font.target_type == PS_TYPE_3 ||
- font.target_type == PS_TYPE_42_3_HYBRID)
- {
- ttfont_add_glyph_dependencies(&font, glyph_ids);
- }
-
-} /* end of insert_ttfont() */
-
-void insert_ttfont(const char *filename, TTStreamWriter& stream,
- font_type_enum target_type, std::vector<int>& glyph_ids)
-{
- struct TTFONT font;
-
- read_font(filename, target_type, glyph_ids, font);
-
- /* Write the header for the PostScript font. */
- ttfont_header(stream, &font);
-
- /* Define the encoding. */
- ttfont_encoding(stream, &font, glyph_ids, target_type);
-
- /* Insert FontInfo dictionary. */
- ttfont_FontInfo(stream, &font);
-
- /* If we are generating a type 42 font, */
- /* emmit the sfnts array. */
- if (font.target_type == PS_TYPE_42 ||
- font.target_type == PS_TYPE_42_3_HYBRID)
- {
- ttfont_sfnts(stream, &font);
- }
-
- /* Emmit the CharStrings array. */
- ttfont_CharStrings(stream, &font, glyph_ids);
-
- /* Send the font trailer. */
- ttfont_trailer(stream, &font);
-
-} /* end of insert_ttfont() */
-
-class StringStreamWriter : public TTStreamWriter
-{
- std::ostringstream oss;
-
-public:
- void write(const char* a)
- {
- oss << a;
- }
-
- std::string str()
- {
- return oss.str();
- }
-};
-
-void get_pdf_charprocs(const char *filename, std::vector<int>& glyph_ids, TTDictionaryCallback& dict)
-{
- struct TTFONT font;
-
- read_font(filename, PDF_TYPE_3, glyph_ids, font);
-
- for (std::vector<int>::const_iterator i = glyph_ids.begin();
- i != glyph_ids.end(); ++i)
- {
- StringStreamWriter writer;
- tt_type3_charproc(writer, &font, *i);
- const char* name = ttfont_CharStrings_getname(&font, *i);
- dict.add_pair(name, writer.str().c_str());
- }
-}
-
-TTFONT::TTFONT() :
- file(NULL),
- PostName(NULL),
- FullName(NULL),
- FamilyName(NULL),
- Style(NULL),
- Copyright(NULL),
- Version(NULL),
- Trademark(NULL),
- offset_table(NULL),
- post_table(NULL),
- loca_table(NULL),
- glyf_table(NULL),
- hmtx_table(NULL)
-{
-
-}
-
-TTFONT::~TTFONT()
-{
- if (file)
- {
- fclose(file);
- }
- free(PostName);
- free(FullName);
- free(FamilyName);
- free(Style);
- free(Copyright);
- free(Version);
- free(Trademark);
- free(offset_table);
- free(post_table);
- free(loca_table);
- free(glyf_table);
- free(hmtx_table);
-}
-
-/* end of file */
diff --git a/contrib/python/matplotlib/py2/extern/ttconv/pprdrv_tt2.cpp b/contrib/python/matplotlib/py2/extern/ttconv/pprdrv_tt2.cpp
deleted file mode 100644
index 058bc00534..0000000000
--- a/contrib/python/matplotlib/py2/extern/ttconv/pprdrv_tt2.cpp
+++ /dev/null
@@ -1,736 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/*
- * Modified for use within matplotlib
- * 5 July 2007
- * Michael Droettboom
- */
-
-/*
-** ~ppr/src/pprdrv/pprdrv_tt2.c
-** Copyright 1995, Trinity College Computing Center.
-** Written by David Chappell.
-**
-** Permission to use, copy, modify, and distribute this software and its
-** documentation for any purpose and without fee is hereby granted, provided
-** that the above copyright notice appear in all copies and that both that
-** copyright notice and this permission notice appear in supporting
-** documentation. This software is provided "as is" without express or
-** implied warranty.
-**
-** TrueType font support. These functions allow PPR to generate
-** PostScript fonts from Microsoft compatible TrueType font files.
-**
-** The functions in this file do most of the work to convert a
-** TrueType font to a type 3 PostScript font.
-**
-** Most of the material in this file is derived from a program called
-** "ttf2ps" which L. S. Ng posted to the usenet news group
-** "comp.sources.postscript". The author did not provide a copyright
-** notice or indicate any restrictions on use.
-**
-** Last revised 11 July 1995.
-*/
-
-#include <cstdlib>
-#include <cmath>
-#include <cstring>
-#include <memory>
-#include "pprdrv.h"
-#include "truetype.h"
-#include <algorithm>
-#include <stack>
-#include <list>
-
-class GlyphToType3
-{
-private:
- GlyphToType3& operator=(const GlyphToType3& other);
- GlyphToType3(const GlyphToType3& other);
-
- /* The PostScript bounding box. */
- int llx,lly,urx,ury;
- int advance_width;
-
- /* Variables to hold the character data. */
- int *epts_ctr; /* array of contour endpoints */
- int num_pts, num_ctr; /* number of points, number of coutours */
- FWord *xcoor, *ycoor; /* arrays of x and y coordinates */
- BYTE *tt_flags; /* array of TrueType flags */
-
- int stack_depth; /* A book-keeping variable for keeping track of the depth of the PS stack */
-
- bool pdf_mode;
-
- void load_char(TTFONT* font, BYTE *glyph);
- void stack(TTStreamWriter& stream, int new_elem);
- void stack_end(TTStreamWriter& stream);
- void PSConvert(TTStreamWriter& stream);
- void PSCurveto(TTStreamWriter& stream,
- FWord x0, FWord y0,
- FWord x1, FWord y1,
- FWord x2, FWord y2);
- void PSMoveto(TTStreamWriter& stream, int x, int y);
- void PSLineto(TTStreamWriter& stream, int x, int y);
- void do_composite(TTStreamWriter& stream, struct TTFONT *font, BYTE *glyph);
-
-public:
- GlyphToType3(TTStreamWriter& stream, struct TTFONT *font, int charindex, bool embedded = false);
- ~GlyphToType3();
-};
-
-// Each point on a TrueType contour is either on the path or off it (a
-// control point); here's a simple representation for building such
-// contours. Added by Jouni Seppänen 2012-05-27.
-enum Flag { ON_PATH, OFF_PATH };
-struct FlaggedPoint
-{
- enum Flag flag;
- FWord x;
- FWord y;
- FlaggedPoint(Flag flag_, FWord x_, FWord y_): flag(flag_), x(x_), y(y_) {};
-};
-
-double area(FWord *x, FWord *y, int n);
-#define sqr(x) ((x)*(x))
-
-#define NOMOREINCTR -1
-#define NOMOREOUTCTR -1
-
-/*
-** This routine is used to break the character
-** procedure up into a number of smaller
-** procedures. This is necessary so as not to
-** overflow the stack on certain level 1 interpreters.
-**
-** Prepare to push another item onto the stack,
-** starting a new proceedure if necessary.
-**
-** Not all the stack depth calculations in this routine
-** are perfectly accurate, but they do the job.
-*/
-void GlyphToType3::stack(TTStreamWriter& stream, int new_elem)
-{
- if ( !pdf_mode && num_pts > 25 ) /* Only do something of we will */
- {
- /* have a log of points. */
- if (stack_depth == 0)
- {
- stream.put_char('{');
- stack_depth=1;
- }
-
- stack_depth += new_elem; /* Account for what we propose to add */
-
- if (stack_depth > 100)
- {
- stream.puts("}_e{");
- stack_depth = 3 + new_elem; /* A rough estimate */
- }
- }
-} /* end of stack() */
-
-void GlyphToType3::stack_end(TTStreamWriter& stream) /* called at end */
-{
- if ( !pdf_mode && stack_depth )
- {
- stream.puts("}_e");
- stack_depth=0;
- }
-} /* end of stack_end() */
-
-/*
-** We call this routine to emmit the PostScript code
-** for the character we have loaded with load_char().
-*/
-void GlyphToType3::PSConvert(TTStreamWriter& stream)
-{
- int j, k;
-
- /* Step thru the contours.
- * j = index to xcoor, ycoor, tt_flags (point data)
- * k = index to epts_ctr (which points belong to the same contour) */
- for(j = k = 0; k < num_ctr; k++)
- {
- // A TrueType contour consists of on-path and off-path points.
- // Two consecutive on-path points are to be joined with a
- // line; off-path points between on-path points indicate a
- // quadratic spline, where the off-path point is the control
- // point. Two consecutive off-path points have an implicit
- // on-path point midway between them.
- std::list<FlaggedPoint> points;
-
- // Represent flags and x/y coordinates as a C++ list
- for (; j <= epts_ctr[k]; j++)
- {
- if (!(tt_flags[j] & 1)) {
- points.push_back(FlaggedPoint(OFF_PATH, xcoor[j], ycoor[j]));
- } else {
- points.push_back(FlaggedPoint(ON_PATH, xcoor[j], ycoor[j]));
- }
- }
-
- if (points.size() == 0) {
- // Don't try to access the last element of an empty list
- continue;
- }
-
- // For any two consecutive off-path points, insert the implied
- // on-path point.
- FlaggedPoint prev = points.back();
- for (std::list<FlaggedPoint>::iterator it = points.begin();
- it != points.end();
- it++)
- {
- if (prev.flag == OFF_PATH && it->flag == OFF_PATH)
- {
- points.insert(it,
- FlaggedPoint(ON_PATH,
- (prev.x + it->x) / 2,
- (prev.y + it->y) / 2));
- }
- prev = *it;
- }
- // Handle the wrap-around: insert a point either at the beginning
- // or at the end that has the same coordinates as the opposite point.
- // This also ensures that the initial point is ON_PATH.
- if (points.front().flag == OFF_PATH)
- {
- assert(points.back().flag == ON_PATH);
- points.insert(points.begin(), points.back());
- }
- else
- {
- assert(points.front().flag == ON_PATH);
- points.push_back(points.front());
- }
-
- // The first point
- stack(stream, 3);
- PSMoveto(stream, points.front().x, points.front().y);
-
- // Step through the remaining points
- std::list<FlaggedPoint>::const_iterator it = points.begin();
- for (it++; it != points.end(); /* incremented inside */)
- {
- const FlaggedPoint& point = *it;
- if (point.flag == ON_PATH)
- {
- stack(stream, 3);
- PSLineto(stream, point.x, point.y);
- it++;
- } else {
- std::list<FlaggedPoint>::const_iterator prev = it, next = it;
- prev--;
- next++;
- assert(prev->flag == ON_PATH);
- assert(next->flag == ON_PATH);
- stack(stream, 7);
- PSCurveto(stream,
- prev->x, prev->y,
- point.x, point.y,
- next->x, next->y);
- it++;
- it++;
- }
- }
- }
-
- /* Now, we can fill the whole thing. */
- stack(stream, 1);
- stream.puts( pdf_mode ? "f" : "_cl" );
-} /* end of PSConvert() */
-
-void GlyphToType3::PSMoveto(TTStreamWriter& stream, int x, int y)
-{
- stream.printf(pdf_mode ? "%d %d m\n" : "%d %d _m\n",
- x, y);
-}
-
-void GlyphToType3::PSLineto(TTStreamWriter& stream, int x, int y)
-{
- stream.printf(pdf_mode ? "%d %d l\n" : "%d %d _l\n",
- x, y);
-}
-
-/*
-** Emit a PostScript "curveto" command, assuming the current point
-** is (x0, y0), the control point of a quadratic spline is (x1, y1),
-** and the endpoint is (x2, y2). Note that this requires a conversion,
-** since PostScript splines are cubic.
-*/
-void GlyphToType3::PSCurveto(TTStreamWriter& stream,
- FWord x0, FWord y0,
- FWord x1, FWord y1,
- FWord x2, FWord y2)
-{
- double sx[3], sy[3], cx[3], cy[3];
-
- sx[0] = x0;
- sy[0] = y0;
- sx[1] = x1;
- sy[1] = y1;
- sx[2] = x2;
- sy[2] = y2;
- cx[0] = (2*sx[1]+sx[0])/3;
- cy[0] = (2*sy[1]+sy[0])/3;
- cx[1] = (sx[2]+2*sx[1])/3;
- cy[1] = (sy[2]+2*sy[1])/3;
- cx[2] = sx[2];
- cy[2] = sy[2];
- stream.printf("%d %d %d %d %d %d %s\n",
- (int)cx[0], (int)cy[0], (int)cx[1], (int)cy[1],
- (int)cx[2], (int)cy[2], pdf_mode ? "c" : "_c");
-}
-
-/*
-** Deallocate the structures which stored
-** the data for the last simple glyph.
-*/
-GlyphToType3::~GlyphToType3()
-{
- free(tt_flags); /* The flags array */
- free(xcoor); /* The X coordinates */
- free(ycoor); /* The Y coordinates */
- free(epts_ctr); /* The array of contour endpoints */
-}
-
-/*
-** Load the simple glyph data pointed to by glyph.
-** The pointer "glyph" should point 10 bytes into
-** the glyph data.
-*/
-void GlyphToType3::load_char(TTFONT* font, BYTE *glyph)
-{
- int x;
- BYTE c, ct;
-
- /* Read the contour endpoints list. */
- epts_ctr = (int *)calloc(num_ctr,sizeof(int));
- for (x = 0; x < num_ctr; x++)
- {
- epts_ctr[x] = getUSHORT(glyph);
- glyph += 2;
- }
-
- /* From the endpoint of the last contour, we can */
- /* determine the number of points. */
- num_pts = epts_ctr[num_ctr-1]+1;
-#ifdef DEBUG_TRUETYPE
- debug("num_pts=%d",num_pts);
- stream.printf("%% num_pts=%d\n",num_pts);
-#endif
-
- /* Skip the instructions. */
- x = getUSHORT(glyph);
- glyph += 2;
- glyph += x;
-
- /* Allocate space to hold the data. */
- tt_flags = (BYTE *)calloc(num_pts,sizeof(BYTE));
- xcoor = (FWord *)calloc(num_pts,sizeof(FWord));
- ycoor = (FWord *)calloc(num_pts,sizeof(FWord));
-
- /* Read the flags array, uncompressing it as we go. */
- /* There is danger of overflow here. */
- for (x = 0; x < num_pts; )
- {
- tt_flags[x++] = c = *(glyph++);
-
- if (c&8) /* If next byte is repeat count, */
- {
- ct = *(glyph++);
-
- if ( (x + ct) > num_pts )
- {
- throw TTException("Error in TT flags");
- }
-
- while (ct--)
- {
- tt_flags[x++] = c;
- }
- }
- }
-
- /* Read the x coordinates */
- for (x = 0; x < num_pts; x++)
- {
- if (tt_flags[x] & 2) /* one byte value with */
- {
- /* external sign */
- c = *(glyph++);
- xcoor[x] = (tt_flags[x] & 0x10) ? c : (-1 * (int)c);
- }
- else if (tt_flags[x] & 0x10) /* repeat last */
- {
- xcoor[x] = 0;
- }
- else /* two byte signed value */
- {
- xcoor[x] = getFWord(glyph);
- glyph+=2;
- }
- }
-
- /* Read the y coordinates */
- for (x = 0; x < num_pts; x++)
- {
- if (tt_flags[x] & 4) /* one byte value with */
- {
- /* external sign */
- c = *(glyph++);
- ycoor[x] = (tt_flags[x] & 0x20) ? c : (-1 * (int)c);
- }
- else if (tt_flags[x] & 0x20) /* repeat last value */
- {
- ycoor[x] = 0;
- }
- else /* two byte signed value */
- {
- ycoor[x] = getUSHORT(glyph);
- glyph+=2;
- }
- }
-
- /* Convert delta values to absolute values. */
- for (x = 1; x < num_pts; x++)
- {
- xcoor[x] += xcoor[x-1];
- ycoor[x] += ycoor[x-1];
- }
-
- for (x=0; x < num_pts; x++)
- {
- xcoor[x] = topost(xcoor[x]);
- ycoor[x] = topost(ycoor[x]);
- }
-
-} /* end of load_char() */
-
-/*
-** Emmit PostScript code for a composite character.
-*/
-void GlyphToType3::do_composite(TTStreamWriter& stream, struct TTFONT *font, BYTE *glyph)
-{
- USHORT flags;
- USHORT glyphIndex;
- int arg1;
- int arg2;
-
- /* Once around this loop for each component. */
- do
- {
- flags = getUSHORT(glyph); /* read the flags word */
- glyph += 2;
-
- glyphIndex = getUSHORT(glyph); /* read the glyphindex word */
- glyph += 2;
-
- if (flags & ARG_1_AND_2_ARE_WORDS)
- {
- /* The tt spec. seems to say these are signed. */
- arg1 = getSHORT(glyph);
- glyph += 2;
- arg2 = getSHORT(glyph);
- glyph += 2;
- }
- else /* The tt spec. does not clearly indicate */
- {
- /* whether these values are signed or not. */
- arg1 = *(signed char *)(glyph++);
- arg2 = *(signed char *)(glyph++);
- }
-
- if (flags & WE_HAVE_A_SCALE)
- {
- glyph += 2;
- }
- else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
- {
- glyph += 4;
- }
- else if (flags & WE_HAVE_A_TWO_BY_TWO)
- {
- glyph += 8;
- }
- else
- {
- }
-
- /* Debugging */
-#ifdef DEBUG_TRUETYPE
- stream.printf("%% flags=%d, arg1=%d, arg2=%d\n",
- (int)flags,arg1,arg2);
-#endif
-
- if (pdf_mode)
- {
- if ( flags & ARGS_ARE_XY_VALUES )
- {
- /* We should have been able to use 'Do' to reference the
- subglyph here. However, that doesn't seem to work with
- xpdf or gs (only acrobat), so instead, this just includes
- the subglyph here inline. */
- stream.printf("q 1 0 0 1 %d %d cm\n", topost(arg1), topost(arg2));
- }
- else
- {
- stream.printf("%% unimplemented shift, arg1=%d, arg2=%d\n",arg1,arg2);
- }
- GlyphToType3(stream, font, glyphIndex, true);
- if ( flags & ARGS_ARE_XY_VALUES )
- {
- stream.printf("\nQ\n");
- }
- }
- else
- {
- /* If we have an (X,Y) shif and it is non-zero, */
- /* translate the coordinate system. */
- if ( flags & ARGS_ARE_XY_VALUES )
- {
- if ( arg1 != 0 || arg2 != 0 )
- stream.printf("gsave %d %d translate\n", topost(arg1), topost(arg2) );
- }
- else
- {
- stream.printf("%% unimplemented shift, arg1=%d, arg2=%d\n",arg1,arg2);
- }
-
- /* Invoke the CharStrings procedure to print the component. */
- stream.printf("false CharStrings /%s get exec\n",
- ttfont_CharStrings_getname(font,glyphIndex));
-
- /* If we translated the coordinate system, */
- /* put it back the way it was. */
- if ( flags & ARGS_ARE_XY_VALUES && (arg1 != 0 || arg2 != 0) )
- {
- stream.puts("grestore ");
- }
- }
-
- }
- while (flags & MORE_COMPONENTS);
-
-} /* end of do_composite() */
-
-/*
-** Return a pointer to a specific glyph's data.
-*/
-BYTE *find_glyph_data(struct TTFONT *font, int charindex)
-{
- ULONG off;
- ULONG length;
-
- /* Read the glyph offset from the index to location table. */
- if (font->indexToLocFormat == 0)
- {
- off = getUSHORT( font->loca_table + (charindex * 2) );
- off *= 2;
- length = getUSHORT( font->loca_table + ((charindex+1) * 2) );
- length *= 2;
- length -= off;
- }
- else
- {
- off = getULONG( font->loca_table + (charindex * 4) );
- length = getULONG( font->loca_table + ((charindex+1) * 4) );
- length -= off;
- }
-
- if (length > 0)
- {
- return font->glyf_table + off;
- }
- else
- {
- return (BYTE*)NULL;
- }
-
-} /* end of find_glyph_data() */
-
-GlyphToType3::GlyphToType3(TTStreamWriter& stream, struct TTFONT *font, int charindex, bool embedded /* = false */)
-{
- BYTE *glyph;
-
- tt_flags = NULL;
- xcoor = NULL;
- ycoor = NULL;
- epts_ctr = NULL;
- stack_depth = 0;
- pdf_mode = font->target_type < 0;
-
- /* Get a pointer to the data. */
- glyph = find_glyph_data( font, charindex );
-
- /* If the character is blank, it has no bounding box, */
- /* otherwise read the bounding box. */
- if ( glyph == (BYTE*)NULL )
- {
- llx=lly=urx=ury=0; /* A blank char has an all zero BoundingBox */
- num_ctr=0; /* Set this for later if()s */
- }
- else
- {
- /* Read the number of contours. */
- num_ctr = getSHORT(glyph);
-
- /* Read PostScript bounding box. */
- llx = getFWord(glyph + 2);
- lly = getFWord(glyph + 4);
- urx = getFWord(glyph + 6);
- ury = getFWord(glyph + 8);
-
- /* Advance the pointer. */
- glyph += 10;
- }
-
- /* If it is a simple character, load its data. */
- if (num_ctr > 0)
- {
- load_char(font, glyph);
- }
- else
- {
- num_pts=0;
- }
-
- /* Consult the horizontal metrics table to determine */
- /* the character width. */
- if ( charindex < font->numberOfHMetrics )
- {
- advance_width = getuFWord( font->hmtx_table + (charindex * 4) );
- }
- else
- {
- advance_width = getuFWord( font->hmtx_table + ((font->numberOfHMetrics-1) * 4) );
- }
-
- /* Execute setcachedevice in order to inform the font machinery */
- /* of the character bounding box and advance width. */
- stack(stream, 7);
- if (pdf_mode)
- {
- if (!embedded) {
- stream.printf("%d 0 %d %d %d %d d1\n",
- topost(advance_width),
- topost(llx), topost(lly), topost(urx), topost(ury) );
- }
- }
- else if (font->target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.printf("pop gsave .001 .001 scale %d 0 %d %d %d %d setcachedevice\n",
- topost(advance_width),
- topost(llx), topost(lly), topost(urx), topost(ury) );
- }
- else
- {
- stream.printf("%d 0 %d %d %d %d _sc\n",
- topost(advance_width),
- topost(llx), topost(lly), topost(urx), topost(ury) );
- }
-
- /* If it is a simple glyph, convert it, */
- /* otherwise, close the stack business. */
- if ( num_ctr > 0 ) /* simple */
- {
- PSConvert(stream);
- }
- else if ( num_ctr < 0 ) /* composite */
- {
- do_composite(stream, font, glyph);
- }
-
- if (font->target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.printf("\ngrestore\n");
- }
-
- stack_end(stream);
-}
-
-/*
-** This is the routine which is called from pprdrv_tt.c.
-*/
-void tt_type3_charproc(TTStreamWriter& stream, struct TTFONT *font, int charindex)
-{
- GlyphToType3 glyph(stream, font, charindex);
-} /* end of tt_type3_charproc() */
-
-/*
-** Some of the given glyph ids may refer to composite glyphs.
-** This function adds all of the dependencies of those composite
-** glyphs to the glyph id vector. Michael Droettboom [06-07-07]
-*/
-void ttfont_add_glyph_dependencies(struct TTFONT *font, std::vector<int>& glyph_ids)
-{
- std::sort(glyph_ids.begin(), glyph_ids.end());
-
- std::stack<int> glyph_stack;
- for (std::vector<int>::iterator i = glyph_ids.begin();
- i != glyph_ids.end(); ++i)
- {
- glyph_stack.push(*i);
- }
-
- while (glyph_stack.size())
- {
- int gind = glyph_stack.top();
- glyph_stack.pop();
-
- BYTE* glyph = find_glyph_data( font, gind );
- if (glyph != (BYTE*)NULL)
- {
-
- int num_ctr = getSHORT(glyph);
- if (num_ctr <= 0) // This is a composite glyph
- {
-
- glyph += 10;
- USHORT flags = 0;
-
- do
- {
- flags = getUSHORT(glyph);
- glyph += 2;
- gind = (int)getUSHORT(glyph);
- glyph += 2;
-
- std::vector<int>::iterator insertion =
- std::lower_bound(glyph_ids.begin(), glyph_ids.end(), gind);
- if (insertion == glyph_ids.end() || *insertion != gind)
- {
- glyph_ids.insert(insertion, gind);
- glyph_stack.push(gind);
- }
-
- if (flags & ARG_1_AND_2_ARE_WORDS)
- {
- glyph += 4;
- }
- else
- {
- glyph += 2;
- }
-
- if (flags & WE_HAVE_A_SCALE)
- {
- glyph += 2;
- }
- else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
- {
- glyph += 4;
- }
- else if (flags & WE_HAVE_A_TWO_BY_TWO)
- {
- glyph += 8;
- }
- }
- while (flags & MORE_COMPONENTS);
- }
- }
- }
-}
-
-/* end of file */
diff --git a/contrib/python/matplotlib/py2/extern/ttconv/truetype.h b/contrib/python/matplotlib/py2/extern/ttconv/truetype.h
deleted file mode 100644
index 86be14fe37..0000000000
--- a/contrib/python/matplotlib/py2/extern/ttconv/truetype.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4 -*- */
-
-/*
- * Modified for use within matplotlib
- * 5 July 2007
- * Michael Droettboom
- */
-
-#include <stdio.h>
-
-/*
-** ~ppr/src/include/typetype.h
-**
-** Permission to use, copy, modify, and distribute this software and its
-** documentation for any purpose and without fee is hereby granted, provided
-** that the above copyright notice appear in all copies and that both that
-** copyright notice and this permission notice appear in supporting
-** documentation. This software is provided "as is" without express or
-** implied warranty.
-**
-** This include file is shared by the source files
-** "pprdrv/pprdrv_tt.c" and "pprdrv/pprdrv_tt2.c".
-**
-** Last modified 19 April 1995.
-*/
-
-/* Types used in TrueType font files. */
-#define BYTE unsigned char
-#define USHORT unsigned short int
-#define SHORT short signed int
-#define ULONG unsigned int
-#define FIXED long signed int
-#define FWord short signed int
-#define uFWord short unsigned int
-
-/* This structure stores a 16.16 bit fixed */
-/* point number. */
-typedef struct
- {
- short int whole;
- unsigned short int fraction;
- } Fixed;
-
-/* This structure tells what we have found out about */
-/* the current font. */
-struct TTFONT
- {
- // A quick-and-dirty way to create a minimum level of exception safety
- // Added by Michael Droettboom
- TTFONT();
- ~TTFONT();
-
- const char *filename; /* Name of TT file */
- FILE *file; /* the open TT file */
- font_type_enum target_type; /* 42 or 3 for PS, or -3 for PDF */
-
- ULONG numTables; /* number of tables present */
- char *PostName; /* Font's PostScript name */
- char *FullName; /* Font's full name */
- char *FamilyName; /* Font's family name */
- char *Style; /* Font's style string */
- char *Copyright; /* Font's copyright string */
- char *Version; /* Font's version string */
- char *Trademark; /* Font's trademark string */
- int llx,lly,urx,ury; /* bounding box */
-
- Fixed TTVersion; /* Truetype version number from offset table */
- Fixed MfrRevision; /* Revision number of this font */
-
- BYTE *offset_table; /* Offset table in memory */
- BYTE *post_table; /* 'post' table in memory */
-
- BYTE *loca_table; /* 'loca' table in memory */
- BYTE *glyf_table; /* 'glyf' table in memory */
- BYTE *hmtx_table; /* 'hmtx' table in memory */
-
- USHORT numberOfHMetrics;
- int unitsPerEm; /* unitsPerEm converted to int */
- int HUPM; /* half of above */
-
- int numGlyphs; /* from 'post' table */
-
- int indexToLocFormat; /* short or long offsets */
-};
-
-ULONG getULONG(BYTE *p);
-USHORT getUSHORT(BYTE *p);
-Fixed getFixed(BYTE *p);
-
-/*
-** Get an funits word.
-** since it is 16 bits long, we can
-** use getUSHORT() to do the real work.
-*/
-#define getFWord(x) (FWord)getUSHORT(x)
-#define getuFWord(x) (uFWord)getUSHORT(x)
-
-/*
-** We can get a SHORT by making USHORT signed.
-*/
-#define getSHORT(x) (SHORT)getUSHORT(x)
-
-/* This is the one routine in pprdrv_tt.c that is */
-/* called from pprdrv_tt.c. */
-const char *ttfont_CharStrings_getname(struct TTFONT *font, int charindex);
-
-void tt_type3_charproc(TTStreamWriter& stream, struct TTFONT *font, int charindex);
-
-/* Added 06-07-07 Michael Droettboom */
-void ttfont_add_glyph_dependencies(struct TTFONT *font, std::vector<int>& glypy_ids);
-
-/* This routine converts a number in the font's character coordinate */
-/* system to a number in a 1000 unit character system. */
-#define topost(x) (int)( ((int)(x) * 1000 + font->HUPM) / font->unitsPerEm )
-#define topost2(x) (int)( ((int)(x) * 1000 + font.HUPM) / font.unitsPerEm )
-
-/* Composite glyph values. */
-#define ARG_1_AND_2_ARE_WORDS 1
-#define ARGS_ARE_XY_VALUES 2
-#define ROUND_XY_TO_GRID 4
-#define WE_HAVE_A_SCALE 8
-/* RESERVED 16 */
-#define MORE_COMPONENTS 32
-#define WE_HAVE_AN_X_AND_Y_SCALE 64
-#define WE_HAVE_A_TWO_BY_TWO 128
-#define WE_HAVE_INSTRUCTIONS 256
-#define USE_MY_METRICS 512
-
-/* end of file */
diff --git a/contrib/python/matplotlib/py2/extern/ttconv/ttutil.cpp b/contrib/python/matplotlib/py2/extern/ttconv/ttutil.cpp
deleted file mode 100644
index 85e7e23c4f..0000000000
--- a/contrib/python/matplotlib/py2/extern/ttconv/ttutil.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/*
- * Modified for use within matplotlib
- * 5 July 2007
- * Michael Droettboom
- */
-
-/* Very simple interface to the ppr TT routines */
-/* (c) Frank Siegert 1996 */
-
-#include <cstdio>
-#include <cstdarg>
-#include <cstdlib>
-#include "pprdrv.h"
-
-#if DEBUG_TRUETYPE
-void debug(const char *format, ... )
-{
- va_list arg_list;
- va_start(arg_list, format);
-
- printf(format, arg_list);
-
- va_end(arg_list);
-}
-#endif
-
-#define PRINTF_BUFFER_SIZE 512
-void TTStreamWriter::printf(const char* format, ...)
-{
- va_list arg_list;
- va_start(arg_list, format);
- char buffer[PRINTF_BUFFER_SIZE];
-
-#if defined(WIN32) || defined(_MSC_VER)
- int size = _vsnprintf(buffer, PRINTF_BUFFER_SIZE, format, arg_list);
-#else
- int size = vsnprintf(buffer, PRINTF_BUFFER_SIZE, format, arg_list);
-#endif
- if (size >= PRINTF_BUFFER_SIZE) {
- char* buffer2 = (char*)malloc(size);
-#if defined(WIN32) || defined(_MSC_VER)
- _vsnprintf(buffer2, size, format, arg_list);
-#else
- vsnprintf(buffer2, size, format, arg_list);
-#endif
- free(buffer2);
- } else {
- this->write(buffer);
- }
-
- va_end(arg_list);
-}
-
-void TTStreamWriter::put_char(int val)
-{
- char c[2];
- c[0] = (char)val;
- c[1] = 0;
- this->write(c);
-}
-
-void TTStreamWriter::puts(const char *a)
-{
- this->write(a);
-}
-
-void TTStreamWriter::putline(const char *a)
-{
- this->write(a);
- this->write("\n");
-}
-
-void replace_newlines_with_spaces(char *a) {
- char* i = a;
- while (*i != 0) {
- if (*i == '\r' || *i == '\n')
- *i = ' ';
- i++;
- }
-}
diff --git a/contrib/python/matplotlib/py2/extern/ttconv/ya.make b/contrib/python/matplotlib/py2/extern/ttconv/ya.make
deleted file mode 100644
index c36ec960b9..0000000000
--- a/contrib/python/matplotlib/py2/extern/ttconv/ya.make
+++ /dev/null
@@ -1,15 +0,0 @@
-PY23_LIBRARY()
-
-VERSION(2.2.5)
-
-LICENSE(PSF-2.0)
-
-NO_WSHADOW()
-
-SRCS(
- pprdrv_tt.cpp
- pprdrv_tt2.cpp
- ttutil.cpp
-)
-
-END()
diff --git a/contrib/python/matplotlib/py2/extern/ya.make b/contrib/python/matplotlib/py2/extern/ya.make
deleted file mode 100644
index ef8acb58ea..0000000000
--- a/contrib/python/matplotlib/py2/extern/ya.make
+++ /dev/null
@@ -1,4 +0,0 @@
-RECURSE(
- agg24-svn
- ttconv
-)
diff --git a/contrib/python/matplotlib/py2/matplotlib/__init__.py b/contrib/python/matplotlib/py2/matplotlib/__init__.py
deleted file mode 100644
index 506f634d4d..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/__init__.py
+++ /dev/null
@@ -1,1928 +0,0 @@
-"""
-This is an object-oriented plotting library.
-
-A procedural interface is provided by the companion pyplot module,
-which may be imported directly, e.g.::
-
- import matplotlib.pyplot as plt
-
-or using ipython::
-
- ipython
-
-at your terminal, followed by::
-
- In [1]: %matplotlib
- In [2]: import matplotlib.pyplot as plt
-
-at the ipython shell prompt.
-
-For the most part, direct use of the object-oriented library is
-encouraged when programming; pyplot is primarily for working
-interactively. The
-exceptions are the pyplot commands :func:`~matplotlib.pyplot.figure`,
-:func:`~matplotlib.pyplot.subplot`,
-:func:`~matplotlib.pyplot.subplots`, and
-:func:`~pyplot.savefig`, which can greatly simplify scripting.
-
-Modules include:
-
- :mod:`matplotlib.axes`
- defines the :class:`~matplotlib.axes.Axes` class. Most pylab
- commands are wrappers for :class:`~matplotlib.axes.Axes`
- methods. The axes module is the highest level of OO access to
- the library.
-
- :mod:`matplotlib.figure`
- defines the :class:`~matplotlib.figure.Figure` class.
-
- :mod:`matplotlib.artist`
- defines the :class:`~matplotlib.artist.Artist` base class for
- all classes that draw things.
-
- :mod:`matplotlib.lines`
- defines the :class:`~matplotlib.lines.Line2D` class for
- drawing lines and markers
-
- :mod:`matplotlib.patches`
- defines classes for drawing polygons
-
- :mod:`matplotlib.text`
- defines the :class:`~matplotlib.text.Text`,
- :class:`~matplotlib.text.TextWithDash`, and
- :class:`~matplotlib.text.Annotate` classes
-
- :mod:`matplotlib.image`
- defines the :class:`~matplotlib.image.AxesImage` and
- :class:`~matplotlib.image.FigureImage` classes
-
- :mod:`matplotlib.collections`
- classes for efficient drawing of groups of lines or polygons
-
- :mod:`matplotlib.colors`
- classes for interpreting color specifications and for making
- colormaps
-
- :mod:`matplotlib.cm`
- colormaps and the :class:`~matplotlib.image.ScalarMappable`
- mixin class for providing color mapping functionality to other
- classes
-
- :mod:`matplotlib.ticker`
- classes for calculating tick mark locations and for formatting
- tick labels
-
- :mod:`matplotlib.backends`
- a subpackage with modules for various gui libraries and output
- formats
-
-The base matplotlib namespace includes:
-
- :data:`~matplotlib.rcParams`
- a global dictionary of default configuration settings. It is
- initialized by code which may be overridden by a matplotlibrc
- file.
-
- :func:`~matplotlib.rc`
- a function for setting groups of rcParams values
-
- :func:`~matplotlib.use`
- a function for setting the matplotlib backend. If used, this
- function must be called immediately after importing matplotlib
- for the first time. In particular, it must be called
- **before** importing pylab (if pylab is imported).
-
-matplotlib was initially written by John D. Hunter (1968-2012) and is now
-developed and maintained by a host of others.
-
-Occasionally the internal documentation (python docstrings) will refer
-to MATLAB&reg;, a registered trademark of The MathWorks, Inc.
-
-"""
-from __future__ import absolute_import, division, print_function
-
-import six
-
-import atexit
-try:
- from collections.abc import MutableMapping
-except ImportError:
- from collections import MutableMapping
-import contextlib
-import distutils.version
-import functools
-import io
-import inspect
-import itertools
-import locale
-import logging
-import os
-import re
-import shutil
-import stat
-import sys
-import tempfile
-import warnings
-
-# cbook must import matplotlib only within function
-# definitions, so it is safe to import from it here.
-from . import cbook
-from matplotlib.cbook import (
- _backports, mplDeprecation, dedent, get_label, sanitize_sequence)
-from matplotlib.compat import subprocess
-from matplotlib.rcsetup import defaultParams, validate_backend, cycler
-
-import numpy
-from six.moves.urllib.request import urlopen
-from six.moves import reload_module as reload
-
-# Get the version from the _version.py versioneer file. For a git checkout,
-# this is computed based on the number of commits since the last tag.
-from ._version import get_versions
-__version__ = str(get_versions()['version'])
-del get_versions
-
-_log = logging.getLogger(__name__)
-
-__version__numpy__ = str('1.7.1') # minimum required numpy version
-
-__bibtex__ = r"""@Article{Hunter:2007,
- Author = {Hunter, J. D.},
- Title = {Matplotlib: A 2D graphics environment},
- Journal = {Computing In Science \& Engineering},
- Volume = {9},
- Number = {3},
- Pages = {90--95},
- abstract = {Matplotlib is a 2D graphics package used for Python
- for application development, interactive scripting, and
- publication-quality image generation across user
- interfaces and operating systems.},
- publisher = {IEEE COMPUTER SOC},
- year = 2007
-}"""
-
-
-_python27 = (sys.version_info.major == 2 and sys.version_info.minor >= 7)
-_python34 = (sys.version_info.major == 3 and sys.version_info.minor >= 4)
-if not (_python27 or _python34):
- raise ImportError("Matplotlib requires Python 2.7 or 3.4 or later")
-
-if _python27:
- _log.addHandler(logging.NullHandler())
-
-
-def compare_versions(a, b):
- "return True if a is greater than or equal to b"
- if a:
- if six.PY3:
- if isinstance(a, bytes):
- a = a.decode('ascii')
- if isinstance(b, bytes):
- b = b.decode('ascii')
- a = distutils.version.LooseVersion(a)
- b = distutils.version.LooseVersion(b)
- return a >= b
- else:
- return False
-
-
-try:
- import dateutil
-except ImportError:
- raise ImportError("Matplotlib requires dateutil")
-
-
-if not compare_versions(six.__version__, '1.10'):
- raise ImportError(
- "Matplotlib requires six>=1.10; you have %s" % six.__version__)
-
-
-try:
- import pyparsing
-except ImportError:
- raise ImportError("Matplotlib requires pyparsing")
-else:
- if not compare_versions(pyparsing.__version__, '2.0.1'):
- raise ImportError(
- "Matplotlib requires pyparsing>=2.0.1; you have %s"
- % pyparsing.__version__)
-
-
-if not compare_versions(numpy.__version__, __version__numpy__):
- raise ImportError(
- "Matplotlib requires numpy>=%s; you have %s" % (
- __version__numpy__, numpy.__version__))
-
-
-if not hasattr(sys, 'argv'): # for modpython
- sys.argv = [str('modpython')]
-
-
-def _is_writable_dir(p):
- """
- p is a string pointing to a putative writable dir -- return True p
- is such a string, else False
- """
- return os.access(p, os.W_OK) and os.path.isdir(p)
-
-_verbose_msg = """\
-matplotlib.verbose is deprecated;
-Command line argument --verbose-LEVEL is deprecated.
-This functionality is now provided by the standard
-python logging library. To get more (or less) logging output:
- import logging
- logger = logging.getLogger('matplotlib')
- logger.set_level(logging.INFO)"""
-
-
-def _set_logger_verbose_level(level_str='silent', file_str='sys.stdout'):
- """
- Use a --verbose-LEVEL level to set the logging level:
-
- """
- levelmap = {'silent': logging.WARNING, 'helpful': logging.INFO,
- 'debug': logging.DEBUG, 'debug-annoying': logging.DEBUG,
- 'info': logging.INFO, 'warning': logging.WARNING}
- # Check that current state of logger isn't already more verbose
- # than the requested level. If it is more verbose, then leave more
- # verbose.
- newlev = levelmap[level_str]
- oldlev = _log.getEffectiveLevel()
- if newlev < oldlev:
- _log.setLevel(newlev)
- std = {
- 'sys.stdout': sys.stdout,
- 'sys.stderr': sys.stderr,
- }
- if file_str in std:
- fileo = std[file_str]
- else:
- fileo = sys.stdout
- try:
- fileo = open(file_str, 'w')
- # if this fails, we will just write to stdout
- except IOError:
- warnings.warn('could not open log file "{0}"'
- 'for writing. Check your '
- 'matplotlibrc'.format(file_str))
- console = logging.StreamHandler(fileo)
- console.setLevel(newlev)
- _log.addHandler(console)
-
-
-def _parse_commandline():
- """
- Check for --verbose-LEVEL type command line arguments and
- set logging level appropriately.
- """
-
- levels = ('silent', 'helpful', 'debug', 'debug-annoying',
- 'info', 'warning')
-
- for arg in sys.argv[1:]:
- if arg.startswith('--verbose-'):
- level_str = arg[10:]
- # If it doesn't match one of ours, then don't even
- # bother noting it, we are just a 3rd-party library
- # to somebody else's script.
- if level_str in levels:
- _set_logger_verbose_level(level_str)
-
-_parse_commandline()
-
-
-class Verbose(object):
- """
- A class to handle reporting. Set the fileo attribute to any file
- instance to handle the output. Default is sys.stdout
- """
- levels = ('silent', 'helpful', 'debug', 'debug-annoying')
- vald = {level: i for i, level in enumerate(levels)}
-
- # parse the verbosity from the command line; flags look like
- # --verbose-silent or --verbose-helpful
- _commandLineVerbose = None
-
- for arg in sys.argv[1:]:
- if not arg.startswith('--verbose-'):
- continue
- level_str = arg[10:]
- # If it doesn't match one of ours, then don't even
- # bother noting it, we are just a 3rd-party library
- # to somebody else's script.
- if level_str in levels:
- _commandLineVerbose = level_str
-
- @cbook.deprecated("2.2", message=_verbose_msg)
- def __init__(self):
- self.set_level('silent')
- self.fileo = sys.stdout
-
- @cbook.deprecated("2.2", message=_verbose_msg)
- def set_level(self, level):
- 'set the verbosity to one of the Verbose.levels strings'
-
- if self._commandLineVerbose is not None:
- level = self._commandLineVerbose
- if level not in self.levels:
- warnings.warn('matplotlib: unrecognized --verbose-* string "%s".'
- ' Legal values are %s' % (level, self.levels))
- else:
- self.level = level
-
- @cbook.deprecated("2.2", message=_verbose_msg)
- def set_fileo(self, fname):
- std = {
- 'sys.stdout': sys.stdout,
- 'sys.stderr': sys.stderr,
- }
- if fname in std:
- self.fileo = std[fname]
- else:
- try:
- fileo = open(fname, 'w')
- except IOError:
- raise ValueError('Verbose object could not open log file "{0}"'
- ' for writing.\nCheck your matplotlibrc '
- 'verbose.fileo setting'.format(fname))
- else:
- self.fileo = fileo
-
- @cbook.deprecated("2.2", message=_verbose_msg)
- def report(self, s, level='helpful'):
- """
- print message s to self.fileo if self.level>=level. Return
- value indicates whether a message was issued
-
- """
- if self.ge(level):
- print(s, file=self.fileo)
- return True
- return False
-
- @cbook.deprecated("2.2", message=_verbose_msg)
- def wrap(self, fmt, func, level='helpful', always=True):
- """
- return a callable function that wraps func and reports it
- output through the verbose handler if current verbosity level
- is higher than level
-
- if always is True, the report will occur on every function
- call; otherwise only on the first time the function is called
- """
- assert callable(func)
-
- def wrapper(*args, **kwargs):
- ret = func(*args, **kwargs)
-
- if (always or not wrapper._spoke):
- spoke = self.report(fmt % ret, level)
- if not wrapper._spoke:
- wrapper._spoke = spoke
- return ret
- wrapper._spoke = False
- wrapper.__doc__ = func.__doc__
- return wrapper
-
- @cbook.deprecated("2.2", message=_verbose_msg)
- def ge(self, level):
- 'return true if self.level is >= level'
- return self.vald[self.level] >= self.vald[level]
-
-
-with warnings.catch_warnings():
- warnings.simplefilter("ignore")
- verbose = Verbose()
-
-
-def _wrap(fmt, func, level=logging.DEBUG, always=True):
- """
- return a callable function that wraps func and reports its
- output through logger
-
- if always is True, the report will occur on every function
- call; otherwise only on the first time the function is called
- """
- assert callable(func)
-
- def wrapper(*args, **kwargs):
- ret = func(*args, **kwargs)
-
- if (always or not wrapper._spoke):
- _log.log(level, fmt % ret)
- spoke = True
- if not wrapper._spoke:
- wrapper._spoke = spoke
- return ret
- wrapper._spoke = False
- wrapper.__doc__ = func.__doc__
- return wrapper
-
-
-def checkdep_dvipng():
- try:
- s = subprocess.Popen([str('dvipng'), '-version'],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = s.communicate()
- line = stdout.decode('ascii').split('\n')[1]
- v = line.split()[-1]
- return v
- except (IndexError, ValueError, OSError):
- return None
-
-
-def checkdep_ghostscript():
- if checkdep_ghostscript.executable is None:
- if sys.platform == 'win32':
- # mgs is the name in miktex
- gs_execs = ['gswin32c', 'gswin64c', 'mgs', 'gs']
- else:
- gs_execs = ['gs']
- for gs_exec in gs_execs:
- try:
- s = subprocess.Popen(
- [str(gs_exec), '--version'], stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = s.communicate()
- if s.returncode == 0:
- v = stdout[:-1].decode('ascii')
- checkdep_ghostscript.executable = gs_exec
- checkdep_ghostscript.version = v
- except (IndexError, ValueError, OSError):
- pass
- return checkdep_ghostscript.executable, checkdep_ghostscript.version
-checkdep_ghostscript.executable = None
-checkdep_ghostscript.version = None
-
-
-# Deprecated, as it is unneeded and some distributions (e.g. MiKTeX 2.9.6350)
-# do not actually report the TeX version.
-@cbook.deprecated("2.1")
-def checkdep_tex():
- try:
- s = subprocess.Popen([str('tex'), '-version'], stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = s.communicate()
- line = stdout.decode('ascii').split('\n')[0]
- pattern = r'3\.1\d+'
- match = re.search(pattern, line)
- v = match.group(0)
- return v
- except (IndexError, ValueError, AttributeError, OSError):
- return None
-
-
-def checkdep_pdftops():
- try:
- s = subprocess.Popen([str('pdftops'), '-v'], stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = s.communicate()
- lines = stderr.decode('ascii').split('\n')
- for line in lines:
- if 'version' in line:
- v = line.split()[-1]
- return v
- except (IndexError, ValueError, UnboundLocalError, OSError):
- return None
-
-
-def checkdep_inkscape():
- if checkdep_inkscape.version is None:
- try:
- s = subprocess.Popen([str('inkscape'), '-V'],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = s.communicate()
- lines = stdout.decode('ascii').split('\n')
- for line in lines:
- if 'Inkscape' in line:
- v = line.split()[1]
- break
- checkdep_inkscape.version = v
- except (IndexError, ValueError, UnboundLocalError, OSError):
- pass
- return checkdep_inkscape.version
-checkdep_inkscape.version = None
-
-
-@cbook.deprecated("2.1")
-def checkdep_xmllint():
- try:
- s = subprocess.Popen([str('xmllint'), '--version'],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- stdout, stderr = s.communicate()
- lines = stderr.decode('ascii').split('\n')
- for line in lines:
- if 'version' in line:
- v = line.split()[-1]
- break
- return v
- except (IndexError, ValueError, UnboundLocalError, OSError):
- return None
-
-
-def checkdep_ps_distiller(s):
- if not s:
- return False
-
- flag = True
- gs_req = '8.60'
- gs_exec, gs_v = checkdep_ghostscript()
- if not compare_versions(gs_v, gs_req):
- flag = False
- warnings.warn(('matplotlibrc ps.usedistiller option can not be used '
- 'unless ghostscript-%s or later is installed on your '
- 'system') % gs_req)
-
- if s == 'xpdf':
- pdftops_req = '3.0'
- pdftops_req_alt = '0.9' # poppler version numbers, ugh
- pdftops_v = checkdep_pdftops()
- if compare_versions(pdftops_v, pdftops_req):
- pass
- elif (compare_versions(pdftops_v, pdftops_req_alt) and not
- compare_versions(pdftops_v, '1.0')):
- pass
- else:
- flag = False
- warnings.warn(('matplotlibrc ps.usedistiller can not be set to '
- 'xpdf unless xpdf-%s or later is installed on '
- 'your system') % pdftops_req)
-
- if flag:
- return s
- else:
- return False
-
-
-def checkdep_usetex(s):
- if not s:
- return False
-
- gs_req = '8.60'
- dvipng_req = '1.6'
- flag = True
-
- if _backports.which("tex") is None:
- flag = False
- warnings.warn('matplotlibrc text.usetex option can not be used unless '
- 'TeX is installed on your system')
-
- dvipng_v = checkdep_dvipng()
- if not compare_versions(dvipng_v, dvipng_req):
- flag = False
- warnings.warn('matplotlibrc text.usetex can not be used with *Agg '
- 'backend unless dvipng-%s or later is installed on '
- 'your system' % dvipng_req)
-
- gs_exec, gs_v = checkdep_ghostscript()
- if not compare_versions(gs_v, gs_req):
- flag = False
- warnings.warn('matplotlibrc text.usetex can not be used unless '
- 'ghostscript-%s or later is installed on your system'
- % gs_req)
-
- return flag
-
-
-def _get_home():
- """Find user's home directory if possible.
- Otherwise, returns None.
-
- :see:
- http://mail.python.org/pipermail/python-list/2005-February/325395.html
- """
- if six.PY2 and sys.platform == 'win32':
- path = os.path.expanduser(b"~").decode(sys.getfilesystemencoding())
- else:
- path = os.path.expanduser("~")
- if os.path.isdir(path):
- return path
- for evar in ('HOME', 'USERPROFILE', 'TMP'):
- path = os.environ.get(evar)
- if path is not None and os.path.isdir(path):
- return path
- return None
-
-
-def _create_tmp_config_dir():
- """
- If the config directory can not be created, create a temporary
- directory.
- """
- configdir = os.environ['MPLCONFIGDIR'] = (
- tempfile.mkdtemp(prefix='matplotlib-'))
- atexit.register(shutil.rmtree, configdir)
- return configdir
-
-
-get_home = _wrap('$HOME=%s', _get_home, always=False)
-
-
-def _get_xdg_config_dir():
- """
- Returns the XDG configuration directory, according to the `XDG
- base directory spec
- <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_.
- """
- path = os.environ.get('XDG_CONFIG_HOME')
- if path is None:
- path = get_home()
- if path is not None:
- path = os.path.join(path, '.config')
- return path
-
-
-def _get_xdg_cache_dir():
- """
- Returns the XDG cache directory, according to the `XDG
- base directory spec
- <http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html>`_.
- """
- path = os.environ.get('XDG_CACHE_HOME')
- if path is None:
- path = get_home()
- if path is not None:
- path = os.path.join(path, '.cache')
- return path
-
-
-def _get_config_or_cache_dir(xdg_base):
- from matplotlib.cbook import mkdirs
-
- configdir = os.environ.get('MPLCONFIGDIR')
- if configdir is not None:
- configdir = os.path.abspath(configdir)
- if not os.path.exists(configdir):
- mkdirs(configdir)
-
- if not _is_writable_dir(configdir):
- return _create_tmp_config_dir()
- return configdir
-
- p = None
- h = get_home()
- if h is not None:
- p = os.path.join(h, '.matplotlib')
- if sys.platform.startswith(('linux', 'freebsd')):
- p = None
- if xdg_base is not None:
- p = os.path.join(xdg_base, 'matplotlib')
-
- if p is not None:
- if os.path.exists(p):
- if _is_writable_dir(p):
- return p
- else:
- try:
- mkdirs(p)
- except OSError:
- pass
- else:
- return p
-
- return _create_tmp_config_dir()
-
-
-def _get_configdir():
- """
- Return the string representing the configuration directory.
-
- The directory is chosen as follows:
-
- 1. If the MPLCONFIGDIR environment variable is supplied, choose that.
-
- 2a. On Linux, follow the XDG specification and look first in
- `$XDG_CONFIG_HOME`, if defined, or `$HOME/.config`.
-
- 2b. On other platforms, choose `$HOME/.matplotlib`.
-
- 3. If the chosen directory exists and is writable, use that as the
- configuration directory.
- 4. If possible, create a temporary directory, and use it as the
- configuration directory.
- 5. A writable directory could not be found or created; return None.
- """
- return _get_config_or_cache_dir(_get_xdg_config_dir())
-
-get_configdir = _wrap('CONFIGDIR=%s', _get_configdir, always=False)
-
-
-def _get_cachedir():
- """
- Return the location of the cache directory.
-
- The procedure used to find the directory is the same as for
- _get_config_dir, except using `$XDG_CACHE_HOME`/`~/.cache` instead.
- """
- return _get_config_or_cache_dir(_get_xdg_cache_dir())
-
-get_cachedir = _wrap('CACHEDIR=%s', _get_cachedir, always=False)
-
-
-def _decode_filesystem_path(path):
- if not isinstance(path, str):
- return path.decode(sys.getfilesystemencoding())
- else:
- return path
-
-
-def _get_internal_mpl_data():
- import tempfile
- import hashlib
- import errno
-
- def mpl_archive():
- import __res
- res_name = '/mpl-data/mpl-data.tar.gz'
- return __res.find(res_name)
-
- def extract_to(data, path):
- import tarfile
- string = six.BytesIO(data)
- tar = tarfile.open(fileobj=string)
- try:
- tar.extractall(path)
- finally:
- tar.close()
-
- data = mpl_archive()
- if not data:
- return None
-
- mpl_path = os.path.join(tempfile.gettempdir(), 'mpl-data_{}_{}'.format(hashlib.md5(data).hexdigest(), os.geteuid()))
- if os.path.exists(mpl_path):
- return mpl_path
-
- tmp_dir = tempfile.mkdtemp(prefix='mpl-temp', dir=tempfile.gettempdir())
- extract_to(data, tmp_dir)
-
- try:
- os.rename(tmp_dir, mpl_path)
- except OSError as e:
- if e.errno not in [errno.EEXIST, errno.ENOTEMPTY]:
- raise
-
- return mpl_path
-
-
-def _get_data_path():
- 'get the path to matplotlib data'
-
- if 'MATPLOTLIBDATA' in os.environ:
- path = os.environ['MATPLOTLIBDATA']
- if not os.path.isdir(path):
- raise RuntimeError('Path in environment MATPLOTLIBDATA not a '
- 'directory')
- return path
-
- _file = _decode_filesystem_path(__file__)
- path = os.sep.join([os.path.dirname(_file), 'mpl-data'])
- if os.path.isdir(path):
- return path
-
- # setuptools' namespace_packages may highjack this init file
- # so need to try something known to be in matplotlib, not basemap
- import matplotlib.afm
- _file = _decode_filesystem_path(matplotlib.afm.__file__)
- path = os.sep.join([os.path.dirname(_file), 'mpl-data'])
- if os.path.isdir(path):
- return path
-
- # py2exe zips pure python, so still need special check
- if getattr(sys, 'frozen', None):
- exe_path = os.path.dirname(_decode_filesystem_path(sys.executable))
- path = os.path.join(exe_path, 'mpl-data')
- if os.path.isdir(path):
- return path
-
- # Try again assuming we need to step up one more directory
- path = os.path.join(os.path.split(exe_path)[0], 'mpl-data')
- if os.path.isdir(path):
- return path
-
- # Try again assuming sys.path[0] is a dir not a exe
- path = os.path.join(sys.path[0], 'mpl-data')
- if os.path.isdir(path):
- return path
-
- path = _get_internal_mpl_data()
- if path:
- return path
-
- raise RuntimeError('Could not find the matplotlib data files')
-
-
-def _get_data_path_cached():
- if defaultParams['datapath'][0] is None:
- defaultParams['datapath'][0] = _get_data_path()
- return defaultParams['datapath'][0]
-
-get_data_path = _wrap('matplotlib data path %s', _get_data_path_cached,
- always=False)
-
-
-def get_py2exe_datafiles():
- datapath = get_data_path()
- _, tail = os.path.split(datapath)
- d = {}
- for root, _, files in os.walk(datapath):
- # Need to explicitly remove cocoa_agg files or py2exe complains
- # NOTE I don't know why, but do as previous version
- if 'Matplotlib.nib' in files:
- files.remove('Matplotlib.nib')
- files = [os.path.join(root, filename) for filename in files]
- root = root.replace(tail, 'mpl-data')
- root = root[root.index('mpl-data'):]
- d[root] = files
- return list(d.items())
-
-
-def matplotlib_fname():
- """
- Get the location of the config file.
-
- The file location is determined in the following order
-
- - `$PWD/matplotlibrc`
-
- - `$MATPLOTLIBRC` if it is a file (or a named pipe, which can be created
- e.g. by process substitution)
-
- - `$MATPLOTLIBRC/matplotlibrc`
-
- - `$MPLCONFIGDIR/matplotlibrc`
-
- - On Linux,
-
- - `$XDG_CONFIG_HOME/matplotlib/matplotlibrc` (if
- $XDG_CONFIG_HOME is defined)
-
- - or `$HOME/.config/matplotlib/matplotlibrc` (if
- $XDG_CONFIG_HOME is not defined)
-
- - On other platforms,
-
- - `$HOME/.matplotlib/matplotlibrc` if `$HOME` is defined.
-
- - Lastly, it looks in `$MATPLOTLIBDATA/matplotlibrc` for a
- system-defined copy.
- """
-
- def gen_candidates():
- yield os.path.join(six.moves.getcwd(), 'matplotlibrc')
- try:
- matplotlibrc = os.environ['MATPLOTLIBRC']
- except KeyError:
- pass
- else:
- yield matplotlibrc
- yield os.path.join(matplotlibrc, 'matplotlibrc')
- yield os.path.join(_get_configdir(), 'matplotlibrc')
- yield os.path.join(get_data_path(), 'matplotlibrc')
-
- for fname in gen_candidates():
- if os.path.exists(fname):
- st_mode = os.stat(fname).st_mode
- if stat.S_ISREG(st_mode) or stat.S_ISFIFO(st_mode):
- break
- # Return first candidate that is a file, or last candidate if none is
- # valid (in that case, a warning is raised at startup by `rc_params`).
- return fname
-
-
-# names of keys to deprecate
-# the values are a tuple of (new_name, f_old_2_new, f_new_2_old)
-# the inverse function may be `None`
-_deprecated_map = {}
-
-_deprecated_ignore_map = {'nbagg.transparent': 'figure.facecolor'}
-
-_obsolete_set = {'plugins.directory', 'text.dvipnghack'}
-
-# The following may use a value of None to suppress the warning.
-# do NOT include in _all_deprecated
-_deprecated_set = {'axes.hold',
- 'backend.qt4',
- 'backend.qt5'}
-
-_all_deprecated = set(itertools.chain(
- _deprecated_ignore_map, _deprecated_map, _obsolete_set))
-
-
-class RcParams(MutableMapping, dict):
-
- """
- A dictionary object including validation
-
- validating functions are defined and associated with rc parameters in
- :mod:`matplotlib.rcsetup`
- """
-
- validate = dict((key, converter) for key, (default, converter) in
- six.iteritems(defaultParams)
- if key not in _all_deprecated)
- msg_depr = "%s is deprecated and replaced with %s; please use the latter."
- msg_depr_set = ("%s is deprecated. Please remove it from your "
- "matplotlibrc and/or style files.")
- msg_depr_ignore = "%s is deprecated and ignored. Use %s instead."
- msg_obsolete = ("%s is obsolete. Please remove it from your matplotlibrc "
- "and/or style files.")
- msg_backend_obsolete = ("The {} rcParam was deprecated in version 2.2. In"
- " order to force the use of a specific Qt binding,"
- " either import that binding first, or set the "
- "QT_API environment variable.")
-
- # validate values on the way in
- def __init__(self, *args, **kwargs):
- self.update(*args, **kwargs)
-
- def __setitem__(self, key, val):
- try:
- if key in _deprecated_map:
- alt_key, alt_val, inverse_alt = _deprecated_map[key]
- warnings.warn(self.msg_depr % (key, alt_key),
- mplDeprecation)
- key = alt_key
- val = alt_val(val)
- elif key in _deprecated_set and val is not None:
- if key.startswith('backend'):
- warnings.warn(self.msg_backend_obsolete.format(key),
- mplDeprecation)
- else:
- warnings.warn(self.msg_depr_set % key,
- mplDeprecation)
- elif key in _deprecated_ignore_map:
- alt = _deprecated_ignore_map[key]
- warnings.warn(self.msg_depr_ignore % (key, alt),
- mplDeprecation)
- return
- elif key in _obsolete_set:
- warnings.warn(self.msg_obsolete % (key, ),
- mplDeprecation)
- return
- try:
- cval = self.validate[key](val)
- except ValueError as ve:
- raise ValueError("Key %s: %s" % (key, str(ve)))
- dict.__setitem__(self, key, cval)
- except KeyError:
- raise KeyError(
- '%s is not a valid rc parameter. See rcParams.keys() for a '
- 'list of valid parameters.' % (key,))
-
- def __getitem__(self, key):
- inverse_alt = None
- if key in _deprecated_map:
- alt_key, alt_val, inverse_alt = _deprecated_map[key]
- warnings.warn(self.msg_depr % (key, alt_key),
- mplDeprecation)
- key = alt_key
-
- elif key in _deprecated_ignore_map:
- alt = _deprecated_ignore_map[key]
- warnings.warn(self.msg_depr_ignore % (key, alt),
- mplDeprecation)
- key = alt
-
- elif key in _obsolete_set:
- warnings.warn(self.msg_obsolete % (key, ),
- mplDeprecation)
- return None
-
- val = dict.__getitem__(self, key)
- if inverse_alt is not None:
- return inverse_alt(val)
- else:
- return val
-
- def __repr__(self):
- import pprint
- class_name = self.__class__.__name__
- indent = len(class_name) + 1
- repr_split = pprint.pformat(dict(self), indent=1,
- width=80 - indent).split('\n')
- repr_indented = ('\n' + ' ' * indent).join(repr_split)
- return '{0}({1})'.format(class_name, repr_indented)
-
- def __str__(self):
- return '\n'.join('{0}: {1}'.format(k, v)
- for k, v in sorted(self.items()))
-
- def __iter__(self):
- """
- Yield sorted list of keys.
- """
- for k in sorted(dict.__iter__(self)):
- yield k
-
- def find_all(self, pattern):
- """
- Return the subset of this RcParams dictionary whose keys match,
- using :func:`re.search`, the given ``pattern``.
-
- .. note::
-
- Changes to the returned dictionary are *not* propagated to
- the parent RcParams dictionary.
-
- """
- pattern_re = re.compile(pattern)
- return RcParams((key, value)
- for key, value in self.items()
- if pattern_re.search(key))
-
-
-def rc_params(fail_on_error=False):
- """Return a :class:`matplotlib.RcParams` instance from the
- default matplotlib rc file.
- """
- fname = matplotlib_fname()
- if not os.path.exists(fname):
- # this should never happen, default in mpl-data should always be found
- message = 'could not find rc file; returning defaults'
- ret = RcParams([(key, default) for key, (default, _) in
- six.iteritems(defaultParams)
- if key not in _all_deprecated])
- warnings.warn(message)
- return ret
-
- return rc_params_from_file(fname, fail_on_error)
-
-
-URL_REGEX = re.compile(r'http://|https://|ftp://|file://|file:\\')
-
-
-def is_url(filename):
- """Return True if string is an http, ftp, or file URL path."""
- return URL_REGEX.match(filename) is not None
-
-
-def _url_lines(f):
- # Compatibility for urlopen in python 3, which yields bytes.
- for line in f:
- yield line.decode('utf8')
-
-
-@contextlib.contextmanager
-def _open_file_or_url(fname):
- if is_url(fname):
- f = urlopen(fname)
- yield _url_lines(f)
- f.close()
- else:
- fname = os.path.expanduser(fname)
- encoding = locale.getpreferredencoding(do_setlocale=False)
- if encoding is None:
- encoding = "utf-8"
- with io.open(fname, encoding=encoding) as f:
- yield f
-
-
-_error_details_fmt = 'line #%d\n\t"%s"\n\tin file "%s"'
-
-
-def _rc_params_in_file(fname, fail_on_error=False):
- """Return :class:`matplotlib.RcParams` from the contents of the given file.
-
- Unlike `rc_params_from_file`, the configuration class only contains the
- parameters specified in the file (i.e. default values are not filled in).
- """
- cnt = 0
- rc_temp = {}
- with _open_file_or_url(fname) as fd:
- try:
- for line in fd:
- cnt += 1
- strippedline = line.split('#', 1)[0].strip()
- if not strippedline:
- continue
- tup = strippedline.split(':', 1)
- if len(tup) != 2:
- error_details = _error_details_fmt % (cnt, line, fname)
- warnings.warn('Illegal %s' % error_details)
- continue
- key, val = tup
- key = key.strip()
- val = val.strip()
- if key in rc_temp:
- warnings.warn('Duplicate key in file "%s", line #%d' %
- (fname, cnt))
- rc_temp[key] = (val, line, cnt)
- except UnicodeDecodeError:
- warnings.warn(
- ('Cannot decode configuration file %s with '
- 'encoding %s, check LANG and LC_* variables')
- % (fname, locale.getpreferredencoding(do_setlocale=False) or
- 'utf-8 (default)'))
- raise
-
- config = RcParams()
-
- for key in ('verbose.level', 'verbose.fileo'):
- if key in rc_temp:
- val, line, cnt = rc_temp.pop(key)
- if fail_on_error:
- config[key] = val # try to convert to proper type or raise
- else:
- try:
- config[key] = val # try to convert to proper type or skip
- except Exception as msg:
- error_details = _error_details_fmt % (cnt, line, fname)
- warnings.warn('Bad val "%s" on %s\n\t%s' %
- (val, error_details, msg))
-
- for key, (val, line, cnt) in six.iteritems(rc_temp):
- if key in defaultParams:
- if fail_on_error:
- config[key] = val # try to convert to proper type or raise
- else:
- try:
- config[key] = val # try to convert to proper type or skip
- except Exception as msg:
- error_details = _error_details_fmt % (cnt, line, fname)
- warnings.warn('Bad val "%s" on %s\n\t%s' %
- (val, error_details, msg))
- elif key in _deprecated_ignore_map:
- warnings.warn('%s is deprecated. Update your matplotlibrc to use '
- '%s instead.' % (key, _deprecated_ignore_map[key]),
- mplDeprecation)
-
- else:
- print("""
-Bad key "%s" on line %d in
-%s.
-You probably need to get an updated matplotlibrc file from
-http://github.com/matplotlib/matplotlib/blob/master/matplotlibrc.template
-or from the matplotlib source distribution""" % (key, cnt, fname),
- file=sys.stderr)
-
- return config
-
-
-def rc_params_from_file(fname, fail_on_error=False, use_default_template=True):
- """Return :class:`matplotlib.RcParams` from the contents of the given file.
-
- Parameters
- ----------
- fname : str
- Name of file parsed for matplotlib settings.
- fail_on_error : bool
- If True, raise an error when the parser fails to convert a parameter.
- use_default_template : bool
- If True, initialize with default parameters before updating with those
- in the given file. If False, the configuration class only contains the
- parameters specified in the file. (Useful for updating dicts.)
- """
- config_from_file = _rc_params_in_file(fname, fail_on_error)
-
- if not use_default_template:
- return config_from_file
-
- iter_params = six.iteritems(defaultParams)
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", mplDeprecation)
- config = RcParams([(key, default) for key, (default, _) in iter_params
- if key not in _all_deprecated])
- config.update(config_from_file)
-
- if config['datapath'] is None:
- config['datapath'] = get_data_path()
-
- if "".join(config['text.latex.preamble']):
- _log.info("""
-*****************************************************************
-You have the following UNSUPPORTED LaTeX preamble customizations:
-%s
-Please do not ask for support with these customizations active.
-*****************************************************************
-""", '\n'.join(config['text.latex.preamble']))
- _log.debug('loaded rc file %s', fname)
-
- return config
-
-
-# this is the instance used by the matplotlib classes
-rcParams = rc_params()
-
-if rcParams['examples.directory']:
- # paths that are intended to be relative to matplotlib_fname()
- # are allowed for the examples.directory parameter.
- # However, we will need to fully qualify the path because
- # Sphinx requires absolute paths.
- if not os.path.isabs(rcParams['examples.directory']):
- _basedir, _fname = os.path.split(matplotlib_fname())
- # Sometimes matplotlib_fname() can return relative paths,
- # Also, using realpath() guarantees that Sphinx will use
- # the same path that matplotlib sees (in case of weird symlinks).
- _basedir = os.path.realpath(_basedir)
- _fullpath = os.path.join(_basedir, rcParams['examples.directory'])
- rcParams['examples.directory'] = _fullpath
-
-rcParamsOrig = rcParams.copy()
-
-with warnings.catch_warnings():
- warnings.simplefilter("ignore", mplDeprecation)
- rcParamsDefault = RcParams([(key, default) for key, (default, converter) in
- six.iteritems(defaultParams)
- if key not in _all_deprecated])
-
-rcParams['ps.usedistiller'] = checkdep_ps_distiller(
- rcParams['ps.usedistiller'])
-
-rcParams['text.usetex'] = checkdep_usetex(rcParams['text.usetex'])
-
-if rcParams['axes.formatter.use_locale']:
- locale.setlocale(locale.LC_ALL, '')
-
-
-def rc(group, **kwargs):
- """
- Set the current rc params. Group is the grouping for the rc, e.g.,
- for ``lines.linewidth`` the group is ``lines``, for
- ``axes.facecolor``, the group is ``axes``, and so on. Group may
- also be a list or tuple of group names, e.g., (*xtick*, *ytick*).
- *kwargs* is a dictionary attribute name/value pairs, e.g.,::
-
- rc('lines', linewidth=2, color='r')
-
- sets the current rc params and is equivalent to::
-
- rcParams['lines.linewidth'] = 2
- rcParams['lines.color'] = 'r'
-
- The following aliases are available to save typing for interactive
- users:
-
- ===== =================
- Alias Property
- ===== =================
- 'lw' 'linewidth'
- 'ls' 'linestyle'
- 'c' 'color'
- 'fc' 'facecolor'
- 'ec' 'edgecolor'
- 'mew' 'markeredgewidth'
- 'aa' 'antialiased'
- ===== =================
-
- Thus you could abbreviate the above rc command as::
-
- rc('lines', lw=2, c='r')
-
-
- Note you can use python's kwargs dictionary facility to store
- dictionaries of default parameters. e.g., you can customize the
- font rc as follows::
-
- font = {'family' : 'monospace',
- 'weight' : 'bold',
- 'size' : 'larger'}
-
- rc('font', **font) # pass in the font dict as kwargs
-
- This enables you to easily switch between several configurations. Use
- ``matplotlib.style.use('default')`` or :func:`~matplotlib.rcdefaults` to
- restore the default rc params after changes.
- """
-
- aliases = {
- 'lw': 'linewidth',
- 'ls': 'linestyle',
- 'c': 'color',
- 'fc': 'facecolor',
- 'ec': 'edgecolor',
- 'mew': 'markeredgewidth',
- 'aa': 'antialiased',
- }
-
- if isinstance(group, six.string_types):
- group = (group,)
- for g in group:
- for k, v in six.iteritems(kwargs):
- name = aliases.get(k) or k
- key = '%s.%s' % (g, name)
- try:
- rcParams[key] = v
- except KeyError:
- raise KeyError(('Unrecognized key "%s" for group "%s" and '
- 'name "%s"') % (key, g, name))
-
-
-def rcdefaults():
- """Restore the rc params from Matplotlib's internal defaults.
-
- See Also
- --------
- rc_file_defaults :
- Restore the rc params from the rc file originally loaded by Matplotlib.
- matplotlib.style.use :
- Use a specific style file. Call ``style.use('default')`` to restore
- the default style.
- """
- rcParams.clear()
- rcParams.update(rcParamsDefault)
-
-
-def rc_file_defaults():
- """Restore the rc params from the original rc file loaded by Matplotlib.
- """
- rcParams.update(rcParamsOrig)
-
-
-def rc_file(fname):
- """
- Update rc params from file.
- """
- rcParams.update(rc_params_from_file(fname))
-
-
-class rc_context(object):
- """
- Return a context manager for managing rc settings.
-
- This allows one to do::
-
- with mpl.rc_context(fname='screen.rc'):
- plt.plot(x, a)
- with mpl.rc_context(fname='print.rc'):
- plt.plot(x, b)
- plt.plot(x, c)
-
- The 'a' vs 'x' and 'c' vs 'x' plots would have settings from
- 'screen.rc', while the 'b' vs 'x' plot would have settings from
- 'print.rc'.
-
- A dictionary can also be passed to the context manager::
-
- with mpl.rc_context(rc={'text.usetex': True}, fname='screen.rc'):
- plt.plot(x, a)
-
- The 'rc' dictionary takes precedence over the settings loaded from
- 'fname'. Passing a dictionary only is also valid. For example a
- common usage is::
-
- with mpl.rc_context(rc={'interactive': False}):
- fig, ax = plt.subplots()
- ax.plot(range(3), range(3))
- fig.savefig('A.png', format='png')
- plt.close(fig)
- """
- # While it may seem natural to implement rc_context using
- # contextlib.contextmanager, that would entail always calling the finally:
- # clause of the contextmanager (which restores the original rcs) including
- # during garbage collection; as a result, something like `plt.xkcd();
- # gc.collect()` would result in the style being lost (as `xkcd()` is
- # implemented on top of rc_context, and nothing is holding onto context
- # manager except possibly circular references.
-
- def __init__(self, rc=None, fname=None):
- self._orig = rcParams.copy()
- try:
- if fname:
- rc_file(fname)
- if rc:
- rcParams.update(rc)
- except Exception:
- # If anything goes wrong, revert to the original rcs.
- dict.update(rcParams, self._orig)
- raise
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_value, exc_tb):
- # No need to revalidate the original values.
- dict.update(rcParams, self._orig)
-
-
-_use_error_msg = """
-This call to matplotlib.use() has no effect because the backend has already
-been chosen; matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
-or matplotlib.backends is imported for the first time.
-
-The backend was *originally* set to {backend!r} by the following code:
-{tb}
-"""
-
-
-def use(arg, warn=True, force=False):
- """
- Set the matplotlib backend to one of the known backends.
-
- The argument is case-insensitive. *warn* specifies whether a
- warning should be issued if a backend has already been set up.
- *force* is an **experimental** flag that tells matplotlib to
- attempt to initialize a new backend by reloading the backend
- module.
-
- .. note::
-
- This function must be called *before* importing pyplot for
- the first time; or, if you are not using pyplot, it must be called
- before importing matplotlib.backends. If warn is True, a warning
- is issued if you try and call this after pylab or pyplot have been
- loaded. In certain black magic use cases, e.g.
- :func:`pyplot.switch_backend`, we are doing the reloading necessary to
- make the backend switch work (in some cases, e.g., pure image
- backends) so one can set warn=False to suppress the warnings.
-
- To find out which backend is currently set, see
- :func:`matplotlib.get_backend`.
-
- """
- # Lets determine the proper backend name first
- if arg.startswith('module://'):
- name = arg
- else:
- # Lowercase only non-module backend names (modules are case-sensitive)
- arg = arg.lower()
- name = validate_backend(arg)
-
- # Check if we've already set up a backend
- if 'matplotlib.backends' in sys.modules:
- # Warn only if called with a different name
- if (rcParams['backend'] != name) and warn:
- import matplotlib.backends
- warnings.warn(
- _use_error_msg.format(
- backend=rcParams['backend'],
- tb=matplotlib.backends._backend_loading_tb),
- stacklevel=2)
-
- # Unless we've been told to force it, just return
- if not force:
- return
- need_reload = True
- else:
- need_reload = False
-
- # Store the backend name
- rcParams['backend'] = name
-
- # If needed we reload here because a lot of setup code is triggered on
- # module import. See backends/__init__.py for more detail.
- if need_reload:
- reload(sys.modules['matplotlib.backends'])
-
-
-try:
- use(os.environ['MPLBACKEND'])
-except KeyError:
- pass
-
-
-def get_backend():
- """Return the name of the current backend."""
- return rcParams['backend']
-
-
-def interactive(b):
- """
- Set interactive mode to boolean b.
-
- If b is True, then draw after every plotting command, e.g., after xlabel
- """
- rcParams['interactive'] = b
-
-
-def is_interactive():
- 'Return true if plot mode is interactive'
- return rcParams['interactive']
-
-
-def tk_window_focus():
- """Return true if focus maintenance under TkAgg on win32 is on.
- This currently works only for python.exe and IPython.exe.
- Both IDLE and Pythonwin.exe fail badly when tk_window_focus is on."""
- if rcParams['backend'] != 'TkAgg':
- return False
- return rcParams['tk.window_focus']
-
-
-default_test_modules = [
- 'matplotlib.tests',
- 'matplotlib.sphinxext.tests',
- 'mpl_toolkits.tests',
-]
-
-
-def _init_tests():
- try:
- import faulthandler
- except ImportError:
- pass
- else:
- # CPython's faulthandler since v3.6 handles exceptions on Windows
- # https://bugs.python.org/issue23848 but until v3.6.4 it was
- # printing non-fatal exceptions https://bugs.python.org/issue30557
- import platform
- if not (sys.platform == 'win32' and
- (3, 6) < sys.version_info < (3, 6, 4) and
- platform.python_implementation() == 'CPython'):
- faulthandler.enable()
-
- # The version of FreeType to install locally for running the
- # tests. This must match the value in `setupext.py`
- LOCAL_FREETYPE_VERSION = '2.6.1'
-
- from matplotlib import ft2font
- if (ft2font.__freetype_version__ != LOCAL_FREETYPE_VERSION or
- ft2font.__freetype_build_type__ != 'local'):
- warnings.warn(
- "Matplotlib is not built with the correct FreeType version to run "
- "tests. Set local_freetype=True in setup.cfg and rebuild. "
- "Expect many image comparison failures below. "
- "Expected freetype version {0}. "
- "Found freetype version {1}. "
- "Freetype build type is {2}local".format(
- LOCAL_FREETYPE_VERSION,
- ft2font.__freetype_version__,
- "" if ft2font.__freetype_build_type__ == 'local' else "not "
- )
- )
-
- try:
- import pytest
- try:
- from unittest import mock
- except ImportError:
- import mock
- except ImportError:
- print("matplotlib.test requires pytest and mock to run.")
- raise
-
-
-def test(verbosity=None, coverage=False, switch_backend_warn=True,
- recursionlimit=0, **kwargs):
- """run the matplotlib test suite"""
- _init_tests()
- if not os.path.isdir(os.path.join(os.path.dirname(__file__), 'tests')):
- raise ImportError("Matplotlib test data is not installed")
-
- old_backend = get_backend()
- old_recursionlimit = sys.getrecursionlimit()
- try:
- use('agg')
- if recursionlimit:
- sys.setrecursionlimit(recursionlimit)
- import pytest
-
- args = kwargs.pop('argv', [])
- provide_default_modules = True
- use_pyargs = True
- for arg in args:
- if any(arg.startswith(module_path)
- for module_path in default_test_modules):
- provide_default_modules = False
- break
- if os.path.exists(arg):
- provide_default_modules = False
- use_pyargs = False
- break
- if use_pyargs:
- args += ['--pyargs']
- if provide_default_modules:
- args += default_test_modules
-
- if coverage:
- args += ['--cov']
-
- if verbosity:
- args += ['-' + 'v' * verbosity]
-
- retcode = pytest.main(args, **kwargs)
- finally:
- if old_backend.lower() != 'agg':
- use(old_backend, warn=switch_backend_warn)
- if recursionlimit:
- sys.setrecursionlimit(old_recursionlimit)
-
- return retcode
-
-
-test.__test__ = False # pytest: this function is not a test
-
-
-def _replacer(data, key):
- """Either returns data[key] or passes data back. Also
- converts input data to a sequence as needed.
- """
- # if key isn't a string don't bother
- if not isinstance(key, six.string_types):
- return (key)
- # try to use __getitem__
- try:
- return sanitize_sequence(data[key])
- # key does not exist, silently fall back to key
- except KeyError:
- return key
-
-
-_DATA_DOC_APPENDIX = """
-
-.. note::
- In addition to the above described arguments, this function can take a
- **data** keyword argument. If such a **data** argument is given, the
- following arguments are replaced by **data[<arg>]**:
-
- {replaced}
-"""
-
-
-def _add_data_doc(docstring, replace_names, replace_all_args):
- """Add documentation for a *data* field to the given docstring.
-
- Parameters
- ----------
- docstring : str
- The input docstring.
- replace_names : list of strings or None
- The list of parameter names which arguments should be replaced by
- `data[name]`. If None, all arguments are replaced if they are
- included in `data`.
- replace_all_args : bool
- If True, all arguments in *args get replaced, even if they are not
- in replace_names.
-
- Returns
- -------
- The augmented docstring.
- """
- if docstring is None:
- docstring = ''
- else:
- docstring = dedent(docstring)
- _repl = ""
- if replace_names is None:
- _repl = "* All positional and all keyword arguments."
- else:
- if len(replace_names) != 0:
- _repl = "* All arguments with the following names: '{names}'."
- if replace_all_args:
- _repl += "\n * All positional arguments."
- _repl = _repl.format(names="', '".join(sorted(replace_names)))
- return docstring + _DATA_DOC_APPENDIX.format(replaced=_repl)
-
-
-def _preprocess_data(replace_names=None, replace_all_args=False,
- label_namer=None, positional_parameter_names=None):
- """
- A decorator to add a 'data' kwarg to any a function. The signature
- of the input function must include the ax argument at the first position ::
-
- def foo(ax, *args, **kwargs)
-
- so this is suitable for use with Axes methods.
-
- Parameters
- ----------
- replace_names : list of strings, optional, default: None
- The list of parameter names which arguments should be replaced by
- `data[name]`. If None, all arguments are replaced if they are
- included in `data`.
- replace_all_args : bool, default: False
- If True, all arguments in *args get replaced, even if they are not
- in replace_names.
- label_namer : string, optional, default: None
- The name of the parameter which argument should be used as label, if
- label is not set. If None, the label keyword argument is not set.
- positional_parameter_names : list of strings or callable, optional
- The full list of positional parameter names (excluding an explicit
- `ax`/'self' argument at the first place and including all possible
- positional parameter in `*args`), in the right order. Can also include
- all other keyword parameter. Only needed if the wrapped function does
- contain `*args` and (replace_names is not None or replace_all_args is
- False). If it is a callable, it will be called with the actual
- tuple of *args and the data and should return a list like
- above.
- NOTE: callables should only be used when the names and order of *args
- can only be determined at runtime. Please use list of names
- when the order and names of *args is clear before runtime!
-
- .. note:: decorator also converts MappingView input data to list.
- """
- if replace_names is not None:
- replace_names = set(replace_names)
-
- def param(func):
- new_sig = None
- # signature is since 3.3 and wrapped since 3.2, but we support 3.4+.
- python_has_signature = python_has_wrapped = six.PY3
-
- # if in a legacy version of python and IPython is already imported
- # try to use their back-ported signature
- if not python_has_signature and 'IPython' in sys.modules:
- try:
- import IPython.utils.signatures
- signature = IPython.utils.signatures.signature
- Parameter = IPython.utils.signatures.Parameter
- except ImportError:
- pass
- else:
- python_has_signature = True
- else:
- if python_has_signature:
- signature = inspect.signature
- Parameter = inspect.Parameter
-
- if not python_has_signature:
- arg_spec = inspect.getargspec(func)
- _arg_names = arg_spec.args
- _has_varargs = arg_spec.varargs is not None
- _has_varkwargs = arg_spec.keywords is not None
- else:
- sig = signature(func)
- _has_varargs = False
- _has_varkwargs = False
- _arg_names = []
- params = list(sig.parameters.values())
- for p in params:
- if p.kind is Parameter.VAR_POSITIONAL:
- _has_varargs = True
- elif p.kind is Parameter.VAR_KEYWORD:
- _has_varkwargs = True
- else:
- _arg_names.append(p.name)
- data_param = Parameter('data',
- Parameter.KEYWORD_ONLY,
- default=None)
- if _has_varkwargs:
- params.insert(-1, data_param)
- else:
- params.append(data_param)
- new_sig = sig.replace(parameters=params)
- # Import-time check: do we have enough information to replace *args?
- arg_names_at_runtime = False
- # there can't be any positional arguments behind *args and no
- # positional args can end up in **kwargs, so only *varargs make
- # problems.
- # http://stupidpythonideas.blogspot.de/2013/08/arguments-and-parameters.html
- if not _has_varargs:
- # all args are "named", so no problem
- # remove the first "ax" / self arg
- arg_names = _arg_names[1:]
- else:
- # Here we have "unnamed" variables and we need a way to determine
- # whether to replace a arg or not
- if replace_names is None:
- # all argnames should be replaced
- arg_names = None
- elif len(replace_names) == 0:
- # No argnames should be replaced
- arg_names = []
- elif len(_arg_names) > 1 and (positional_parameter_names is None):
- # we got no manual parameter names but more than an 'ax' ...
- if len(replace_names - set(_arg_names[1:])) == 0:
- # all to be replaced arguments are in the list
- arg_names = _arg_names[1:]
- else:
- raise AssertionError(
- "Got unknown 'replace_names' and wrapped function "
- "{!r} uses '*args', need 'positional_parameter_names'"
- .format(func.__name__))
- else:
- if positional_parameter_names is not None:
- if callable(positional_parameter_names):
- # determined by the function at runtime
- arg_names_at_runtime = True
- # so that we don't compute the label_pos at import time
- arg_names = []
- else:
- arg_names = positional_parameter_names
- else:
- if replace_all_args:
- arg_names = []
- else:
- raise AssertionError(
- "Got 'replace_names' and wrapped function {!r} "
- "uses *args, need 'positional_parameter_names' or "
- "'replace_all_args'".format(func.__name__))
-
- # compute the possible label_namer and label position in positional
- # arguments
- label_pos = 9999 # bigger than all "possible" argument lists
- label_namer_pos = 9999 # bigger than all "possible" argument lists
- if (label_namer and # we actually want a label here ...
- arg_names and # and we can determine a label in *args ...
- (label_namer in arg_names)): # and it is in *args
- label_namer_pos = arg_names.index(label_namer)
- if "label" in arg_names:
- label_pos = arg_names.index("label")
-
- # Check the case we know a label_namer but we can't find it the
- # arg_names... Unfortunately the label_namer can be in **kwargs,
- # which we can't detect here and which results in a non-set label
- # which might surprise the user :-(
- if label_namer and not arg_names_at_runtime and not _has_varkwargs:
- if not arg_names:
- raise AssertionError(
- "label_namer {!r} can't be found as the parameter without "
- "'positional_parameter_names'".format(label_namer))
- elif label_namer not in arg_names:
- raise AssertionError(
- "label_namer {!r} can't be found in the parameter names "
- "(known argnames: %s).".format(label_namer, arg_names))
- else:
- # this is the case when the name is in arg_names
- pass
-
- @functools.wraps(func)
- def inner(ax, *args, **kwargs):
- # this is needed because we want to change these values if
- # arg_names_at_runtime==True, but python does not allow assigning
- # to a variable in a outer scope. So use some new local ones and
- # set them to the already computed values.
- _label_pos = label_pos
- _label_namer_pos = label_namer_pos
- _arg_names = arg_names
-
- label = None
-
- data = kwargs.pop('data', None)
-
- if data is None: # data validation
- args = tuple(sanitize_sequence(a) for a in args)
- else:
- if arg_names_at_runtime:
- # update the information about replace names and
- # label position
- _arg_names = positional_parameter_names(args, data)
- if (label_namer and # we actually want a label here ...
- _arg_names and # and we can find a label in *args
- (label_namer in _arg_names)): # and it is in *args
- _label_namer_pos = _arg_names.index(label_namer)
- if "label" in _arg_names:
- _label_pos = arg_names.index("label")
-
- # save the current label_namer value so that it can be used as
- # a label
- if _label_namer_pos < len(args):
- label = args[_label_namer_pos]
- else:
- label = kwargs.get(label_namer, None)
- # ensure a string, as label can't be anything else
- if not isinstance(label, six.string_types):
- label = None
-
- if (replace_names is None) or (replace_all_args is True):
- # all should be replaced
- args = tuple(_replacer(data, a) for
- j, a in enumerate(args))
- else:
- # An arg is replaced if the arg_name of that position is
- # in replace_names ...
- if len(_arg_names) < len(args):
- raise RuntimeError(
- "Got more args than function expects")
- args = tuple(_replacer(data, a)
- if _arg_names[j] in replace_names else a
- for j, a in enumerate(args))
-
- if replace_names is None:
- # replace all kwargs ...
- kwargs = dict((k, _replacer(data, v))
- for k, v in six.iteritems(kwargs))
- else:
- # ... or only if a kwarg of that name is in replace_names
- kwargs = dict((k, _replacer(data, v)
- if k in replace_names else v)
- for k, v in six.iteritems(kwargs))
-
- # replace the label if this func "wants" a label arg and the user
- # didn't set one. Note: if the user puts in "label=None", it does
- # *NOT* get replaced!
- user_supplied_label = (
- (len(args) >= _label_pos) or # label is included in args
- ('label' in kwargs) # ... or in kwargs
- )
- if (label_namer and not user_supplied_label):
- if _label_namer_pos < len(args):
- kwargs['label'] = get_label(args[_label_namer_pos], label)
- elif label_namer in kwargs:
- kwargs['label'] = get_label(kwargs[label_namer], label)
- else:
- warnings.warn(
- "Tried to set a label via parameter %r in func %r but "
- "couldn't find such an argument.\n"
- "(This is a programming error, please report to "
- "the Matplotlib list!)" % (label_namer, func.__name__),
- RuntimeWarning, stacklevel=2)
- return func(ax, *args, **kwargs)
-
- inner.__doc__ = _add_data_doc(inner.__doc__,
- replace_names, replace_all_args)
- if not python_has_wrapped:
- inner.__wrapped__ = func
- if new_sig is not None:
- inner.__signature__ = new_sig
- return inner
-
- return param
-
-_log.debug('matplotlib version %s', __version__)
-_log.debug('interactive is %s', is_interactive())
-_log.debug('platform is %s', sys.platform)
-_log.debug('loaded modules: %s', list(sys.modules))
diff --git a/contrib/python/matplotlib/py2/matplotlib/_animation_data.py b/contrib/python/matplotlib/py2/matplotlib/_animation_data.py
deleted file mode 100644
index 4c3f2c75b6..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/_animation_data.py
+++ /dev/null
@@ -1,210 +0,0 @@
-# Javascript template for HTMLWriter
-JS_INCLUDE = """
-<link rel="stylesheet"
-href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/
-css/font-awesome.min.css">
-<script language="javascript">
- /* Define the Animation class */
- function Animation(frames, img_id, slider_id, interval, loop_select_id){
- this.img_id = img_id;
- this.slider_id = slider_id;
- this.loop_select_id = loop_select_id;
- this.interval = interval;
- this.current_frame = 0;
- this.direction = 0;
- this.timer = null;
- this.frames = new Array(frames.length);
-
- for (var i=0; i<frames.length; i++)
- {
- this.frames[i] = new Image();
- this.frames[i].src = frames[i];
- }
- document.getElementById(this.slider_id).max = this.frames.length - 1;
- this.set_frame(this.current_frame);
- }
-
- Animation.prototype.get_loop_state = function(){
- var button_group = document[this.loop_select_id].state;
- for (var i = 0; i < button_group.length; i++) {
- var button = button_group[i];
- if (button.checked) {
- return button.value;
- }
- }
- return undefined;
- }
-
- Animation.prototype.set_frame = function(frame){
- this.current_frame = frame;
- document.getElementById(this.img_id).src =
- this.frames[this.current_frame].src;
- document.getElementById(this.slider_id).value = this.current_frame;
- }
-
- Animation.prototype.next_frame = function()
- {
- this.set_frame(Math.min(this.frames.length - 1, this.current_frame + 1));
- }
-
- Animation.prototype.previous_frame = function()
- {
- this.set_frame(Math.max(0, this.current_frame - 1));
- }
-
- Animation.prototype.first_frame = function()
- {
- this.set_frame(0);
- }
-
- Animation.prototype.last_frame = function()
- {
- this.set_frame(this.frames.length - 1);
- }
-
- Animation.prototype.slower = function()
- {
- this.interval /= 0.7;
- if(this.direction > 0){this.play_animation();}
- else if(this.direction < 0){this.reverse_animation();}
- }
-
- Animation.prototype.faster = function()
- {
- this.interval *= 0.7;
- if(this.direction > 0){this.play_animation();}
- else if(this.direction < 0){this.reverse_animation();}
- }
-
- Animation.prototype.anim_step_forward = function()
- {
- this.current_frame += 1;
- if(this.current_frame < this.frames.length){
- this.set_frame(this.current_frame);
- }else{
- var loop_state = this.get_loop_state();
- if(loop_state == "loop"){
- this.first_frame();
- }else if(loop_state == "reflect"){
- this.last_frame();
- this.reverse_animation();
- }else{
- this.pause_animation();
- this.last_frame();
- }
- }
- }
-
- Animation.prototype.anim_step_reverse = function()
- {
- this.current_frame -= 1;
- if(this.current_frame >= 0){
- this.set_frame(this.current_frame);
- }else{
- var loop_state = this.get_loop_state();
- if(loop_state == "loop"){
- this.last_frame();
- }else if(loop_state == "reflect"){
- this.first_frame();
- this.play_animation();
- }else{
- this.pause_animation();
- this.first_frame();
- }
- }
- }
-
- Animation.prototype.pause_animation = function()
- {
- this.direction = 0;
- if (this.timer){
- clearInterval(this.timer);
- this.timer = null;
- }
- }
-
- Animation.prototype.play_animation = function()
- {
- this.pause_animation();
- this.direction = 1;
- var t = this;
- if (!this.timer) this.timer = setInterval(function() {
- t.anim_step_forward();
- }, this.interval);
- }
-
- Animation.prototype.reverse_animation = function()
- {
- this.pause_animation();
- this.direction = -1;
- var t = this;
- if (!this.timer) this.timer = setInterval(function() {
- t.anim_step_reverse();
- }, this.interval);
- }
-</script>
-"""
-
-
-# HTML template for HTMLWriter
-DISPLAY_TEMPLATE = """
-<div class="animation" align="center">
- <img id="_anim_img{id}">
- <br>
- <input id="_anim_slider{id}" type="range" style="width:350px"
- name="points" min="0" max="1" step="1" value="0"
- onchange="anim{id}.set_frame(parseInt(this.value));"></input>
- <br>
- <button onclick="anim{id}.slower()"><i class="fa fa-minus"></i></button>
- <button onclick="anim{id}.first_frame()"><i class="fa fa-fast-backward">
- </i></button>
- <button onclick="anim{id}.previous_frame()">
- <i class="fa fa-step-backward"></i></button>
- <button onclick="anim{id}.reverse_animation()">
- <i class="fa fa-play fa-flip-horizontal"></i></button>
- <button onclick="anim{id}.pause_animation()"><i class="fa fa-pause">
- </i></button>
- <button onclick="anim{id}.play_animation()"><i class="fa fa-play"></i>
- </button>
- <button onclick="anim{id}.next_frame()"><i class="fa fa-step-forward">
- </i></button>
- <button onclick="anim{id}.last_frame()"><i class="fa fa-fast-forward">
- </i></button>
- <button onclick="anim{id}.faster()"><i class="fa fa-plus"></i></button>
- <form action="#n" name="_anim_loop_select{id}" class="anim_control">
- <input type="radio" name="state"
- value="once" {once_checked}> Once </input>
- <input type="radio" name="state"
- value="loop" {loop_checked}> Loop </input>
- <input type="radio" name="state"
- value="reflect" {reflect_checked}> Reflect </input>
- </form>
-</div>
-
-
-<script language="javascript">
- /* Instantiate the Animation class. */
- /* The IDs given should match those used in the template above. */
- (function() {{
- var img_id = "_anim_img{id}";
- var slider_id = "_anim_slider{id}";
- var loop_select_id = "_anim_loop_select{id}";
- var frames = new Array({Nframes});
- {fill_frames}
-
- /* set a timeout to make sure all the above elements are created before
- the object is initialized. */
- setTimeout(function() {{
- anim{id} = new Animation(frames, img_id, slider_id, {interval},
- loop_select_id);
- }}, 0);
- }})()
-</script>
-"""
-
-INCLUDED_FRAMES = """
- for (var i=0; i<{Nframes}; i++){{
- frames[i] = "{frame_dir}/frame" + ("0000000" + i).slice(-7) +
- ".{frame_format}";
- }}
-"""
diff --git a/contrib/python/matplotlib/py2/matplotlib/_cm.py b/contrib/python/matplotlib/py2/matplotlib/_cm.py
deleted file mode 100644
index a32229cb63..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/_cm.py
+++ /dev/null
@@ -1,1445 +0,0 @@
-"""
-Nothing here but dictionaries for generating LinearSegmentedColormaps,
-and a dictionary of these dictionaries.
-
-Documentation for each is in pyplot.colormaps(). Please update this
-with the purpose and type of your colormap if you add data for one here.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import numpy as np
-
-_binary_data = {
- 'red': ((0., 1., 1.), (1., 0., 0.)),
- 'green': ((0., 1., 1.), (1., 0., 0.)),
- 'blue': ((0., 1., 1.), (1., 0., 0.))
- }
-
-_autumn_data = {'red': ((0., 1.0, 1.0), (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.), (1.0, 1.0, 1.0)),
- 'blue': ((0., 0., 0.), (1.0, 0., 0.))}
-
-_bone_data = {'red': ((0., 0., 0.),
- (0.746032, 0.652778, 0.652778),
- (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.),
- (0.365079, 0.319444, 0.319444),
- (0.746032, 0.777778, 0.777778),
- (1.0, 1.0, 1.0)),
- 'blue': ((0., 0., 0.),
- (0.365079, 0.444444, 0.444444),
- (1.0, 1.0, 1.0))}
-
-_cool_data = {'red': ((0., 0., 0.), (1.0, 1.0, 1.0)),
- 'green': ((0., 1., 1.), (1.0, 0., 0.)),
- 'blue': ((0., 1., 1.), (1.0, 1., 1.))}
-
-_copper_data = {'red': ((0., 0., 0.),
- (0.809524, 1.000000, 1.000000),
- (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.),
- (1.0, 0.7812, 0.7812)),
- 'blue': ((0., 0., 0.),
- (1.0, 0.4975, 0.4975))}
-
-_flag_data = {
- 'red': lambda x: 0.75 * np.sin((x * 31.5 + 0.25) * np.pi) + 0.5,
- 'green': lambda x: np.sin(x * 31.5 * np.pi),
- 'blue': lambda x: 0.75 * np.sin((x * 31.5 - 0.25) * np.pi) + 0.5,
-}
-
-_prism_data = {
- 'red': lambda x: 0.75 * np.sin((x * 20.9 + 0.25) * np.pi) + 0.67,
- 'green': lambda x: 0.75 * np.sin((x * 20.9 - 0.25) * np.pi) + 0.33,
- 'blue': lambda x: -1.1 * np.sin((x * 20.9) * np.pi),
-}
-
-
-def cubehelix(gamma=1.0, s=0.5, r=-1.5, h=1.0):
- """Return custom data dictionary of (r,g,b) conversion functions, which
- can be used with :func:`register_cmap`, for the cubehelix color scheme.
-
- Unlike most other color schemes cubehelix was designed by D.A. Green to
- be monotonically increasing in terms of perceived brightness.
- Also, when printed on a black and white postscript printer, the scheme
- results in a greyscale with monotonically increasing brightness.
- This color scheme is named cubehelix because the r,g,b values produced
- can be visualised as a squashed helix around the diagonal in the
- r,g,b color cube.
-
- For a unit color cube (i.e. 3-D coordinates for r,g,b each in the
- range 0 to 1) the color scheme starts at (r,g,b) = (0,0,0), i.e. black,
- and finishes at (r,g,b) = (1,1,1), i.e. white. For some fraction *x*,
- between 0 and 1, the color is the corresponding grey value at that
- fraction along the black to white diagonal (x,x,x) plus a color
- element. This color element is calculated in a plane of constant
- perceived intensity and controlled by the following parameters.
-
- Optional keyword arguments:
-
- ========= =======================================================
- Keyword Description
- ========= =======================================================
- gamma gamma factor to emphasise either low intensity values
- (gamma < 1), or high intensity values (gamma > 1);
- defaults to 1.0.
- s the start color; defaults to 0.5 (i.e. purple).
- r the number of r,g,b rotations in color that are made
- from the start to the end of the color scheme; defaults
- to -1.5 (i.e. -> B -> G -> R -> B).
- h the hue parameter which controls how saturated the
- colors are. If this parameter is zero then the color
- scheme is purely a greyscale; defaults to 1.0.
- ========= =======================================================
-
- """
-
- def get_color_function(p0, p1):
-
- def color(x):
- # Apply gamma factor to emphasise low or high intensity values
- xg = x ** gamma
-
- # Calculate amplitude and angle of deviation from the black
- # to white diagonal in the plane of constant
- # perceived intensity.
- a = h * xg * (1 - xg) / 2
-
- phi = 2 * np.pi * (s / 3 + r * x)
-
- return xg + a * (p0 * np.cos(phi) + p1 * np.sin(phi))
- return color
-
- return {
- 'red': get_color_function(-0.14861, 1.78277),
- 'green': get_color_function(-0.29227, -0.90649),
- 'blue': get_color_function(1.97294, 0.0),
- }
-
-_cubehelix_data = cubehelix()
-
-_bwr_data = ((0.0, 0.0, 1.0), (1.0, 1.0, 1.0), (1.0, 0.0, 0.0))
-_brg_data = ((0.0, 0.0, 1.0), (1.0, 0.0, 0.0), (0.0, 1.0, 0.0))
-
-# Gnuplot palette functions
-gfunc = {
- 0: lambda x: 0,
- 1: lambda x: 0.5,
- 2: lambda x: 1,
- 3: lambda x: x,
- 4: lambda x: x ** 2,
- 5: lambda x: x ** 3,
- 6: lambda x: x ** 4,
- 7: lambda x: np.sqrt(x),
- 8: lambda x: np.sqrt(np.sqrt(x)),
- 9: lambda x: np.sin(x * np.pi / 2),
- 10: lambda x: np.cos(x * np.pi / 2),
- 11: lambda x: np.abs(x - 0.5),
- 12: lambda x: (2 * x - 1) ** 2,
- 13: lambda x: np.sin(x * np.pi),
- 14: lambda x: np.abs(np.cos(x * np.pi)),
- 15: lambda x: np.sin(x * 2 * np.pi),
- 16: lambda x: np.cos(x * 2 * np.pi),
- 17: lambda x: np.abs(np.sin(x * 2 * np.pi)),
- 18: lambda x: np.abs(np.cos(x * 2 * np.pi)),
- 19: lambda x: np.abs(np.sin(x * 4 * np.pi)),
- 20: lambda x: np.abs(np.cos(x * 4 * np.pi)),
- 21: lambda x: 3 * x,
- 22: lambda x: 3 * x - 1,
- 23: lambda x: 3 * x - 2,
- 24: lambda x: np.abs(3 * x - 1),
- 25: lambda x: np.abs(3 * x - 2),
- 26: lambda x: (3 * x - 1) / 2,
- 27: lambda x: (3 * x - 2) / 2,
- 28: lambda x: np.abs((3 * x - 1) / 2),
- 29: lambda x: np.abs((3 * x - 2) / 2),
- 30: lambda x: x / 0.32 - 0.78125,
- 31: lambda x: 2 * x - 0.84,
- 32: lambda x: gfunc32(x),
- 33: lambda x: np.abs(2 * x - 0.5),
- 34: lambda x: 2 * x,
- 35: lambda x: 2 * x - 0.5,
- 36: lambda x: 2 * x - 1.
-}
-
-
-def gfunc32(x):
- ret = np.zeros(len(x))
- m = (x < 0.25)
- ret[m] = 4 * x[m]
- m = (x >= 0.25) & (x < 0.92)
- ret[m] = -2 * x[m] + 1.84
- m = (x >= 0.92)
- ret[m] = x[m] / 0.08 - 11.5
- return ret
-
-_gnuplot_data = {
- 'red': gfunc[7],
- 'green': gfunc[5],
- 'blue': gfunc[15],
-}
-
-_gnuplot2_data = {
- 'red': gfunc[30],
- 'green': gfunc[31],
- 'blue': gfunc[32],
-}
-
-_ocean_data = {
- 'red': gfunc[23],
- 'green': gfunc[28],
- 'blue': gfunc[3],
-}
-
-_afmhot_data = {
- 'red': gfunc[34],
- 'green': gfunc[35],
- 'blue': gfunc[36],
-}
-
-_rainbow_data = {
- 'red': gfunc[33],
- 'green': gfunc[13],
- 'blue': gfunc[10],
-}
-
-_seismic_data = (
- (0.0, 0.0, 0.3), (0.0, 0.0, 1.0),
- (1.0, 1.0, 1.0), (1.0, 0.0, 0.0),
- (0.5, 0.0, 0.0))
-
-_terrain_data = (
- (0.00, (0.2, 0.2, 0.6)),
- (0.15, (0.0, 0.6, 1.0)),
- (0.25, (0.0, 0.8, 0.4)),
- (0.50, (1.0, 1.0, 0.6)),
- (0.75, (0.5, 0.36, 0.33)),
- (1.00, (1.0, 1.0, 1.0)))
-
-_gray_data = {'red': ((0., 0, 0), (1., 1, 1)),
- 'green': ((0., 0, 0), (1., 1, 1)),
- 'blue': ((0., 0, 0), (1., 1, 1))}
-
-_hot_data = {'red': ((0., 0.0416, 0.0416),
- (0.365079, 1.000000, 1.000000),
- (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.),
- (0.365079, 0.000000, 0.000000),
- (0.746032, 1.000000, 1.000000),
- (1.0, 1.0, 1.0)),
- 'blue': ((0., 0., 0.),
- (0.746032, 0.000000, 0.000000),
- (1.0, 1.0, 1.0))}
-
-_hsv_data = {'red': ((0., 1., 1.),
- (0.158730, 1.000000, 1.000000),
- (0.174603, 0.968750, 0.968750),
- (0.333333, 0.031250, 0.031250),
- (0.349206, 0.000000, 0.000000),
- (0.666667, 0.000000, 0.000000),
- (0.682540, 0.031250, 0.031250),
- (0.841270, 0.968750, 0.968750),
- (0.857143, 1.000000, 1.000000),
- (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.),
- (0.158730, 0.937500, 0.937500),
- (0.174603, 1.000000, 1.000000),
- (0.507937, 1.000000, 1.000000),
- (0.666667, 0.062500, 0.062500),
- (0.682540, 0.000000, 0.000000),
- (1.0, 0., 0.)),
- 'blue': ((0., 0., 0.),
- (0.333333, 0.000000, 0.000000),
- (0.349206, 0.062500, 0.062500),
- (0.507937, 1.000000, 1.000000),
- (0.841270, 1.000000, 1.000000),
- (0.857143, 0.937500, 0.937500),
- (1.0, 0.09375, 0.09375))}
-
-_jet_data = {'red': ((0., 0, 0), (0.35, 0, 0), (0.66, 1, 1), (0.89, 1, 1),
- (1, 0.5, 0.5)),
- 'green': ((0., 0, 0), (0.125, 0, 0), (0.375, 1, 1), (0.64, 1, 1),
- (0.91, 0, 0), (1, 0, 0)),
- 'blue': ((0., 0.5, 0.5), (0.11, 1, 1), (0.34, 1, 1),
- (0.65, 0, 0), (1, 0, 0))}
-
-_pink_data = {'red': ((0., 0.1178, 0.1178), (0.015873, 0.195857, 0.195857),
- (0.031746, 0.250661, 0.250661),
- (0.047619, 0.295468, 0.295468),
- (0.063492, 0.334324, 0.334324),
- (0.079365, 0.369112, 0.369112),
- (0.095238, 0.400892, 0.400892),
- (0.111111, 0.430331, 0.430331),
- (0.126984, 0.457882, 0.457882),
- (0.142857, 0.483867, 0.483867),
- (0.158730, 0.508525, 0.508525),
- (0.174603, 0.532042, 0.532042),
- (0.190476, 0.554563, 0.554563),
- (0.206349, 0.576204, 0.576204),
- (0.222222, 0.597061, 0.597061),
- (0.238095, 0.617213, 0.617213),
- (0.253968, 0.636729, 0.636729),
- (0.269841, 0.655663, 0.655663),
- (0.285714, 0.674066, 0.674066),
- (0.301587, 0.691980, 0.691980),
- (0.317460, 0.709441, 0.709441),
- (0.333333, 0.726483, 0.726483),
- (0.349206, 0.743134, 0.743134),
- (0.365079, 0.759421, 0.759421),
- (0.380952, 0.766356, 0.766356),
- (0.396825, 0.773229, 0.773229),
- (0.412698, 0.780042, 0.780042),
- (0.428571, 0.786796, 0.786796),
- (0.444444, 0.793492, 0.793492),
- (0.460317, 0.800132, 0.800132),
- (0.476190, 0.806718, 0.806718),
- (0.492063, 0.813250, 0.813250),
- (0.507937, 0.819730, 0.819730),
- (0.523810, 0.826160, 0.826160),
- (0.539683, 0.832539, 0.832539),
- (0.555556, 0.838870, 0.838870),
- (0.571429, 0.845154, 0.845154),
- (0.587302, 0.851392, 0.851392),
- (0.603175, 0.857584, 0.857584),
- (0.619048, 0.863731, 0.863731),
- (0.634921, 0.869835, 0.869835),
- (0.650794, 0.875897, 0.875897),
- (0.666667, 0.881917, 0.881917),
- (0.682540, 0.887896, 0.887896),
- (0.698413, 0.893835, 0.893835),
- (0.714286, 0.899735, 0.899735),
- (0.730159, 0.905597, 0.905597),
- (0.746032, 0.911421, 0.911421),
- (0.761905, 0.917208, 0.917208),
- (0.777778, 0.922958, 0.922958),
- (0.793651, 0.928673, 0.928673),
- (0.809524, 0.934353, 0.934353),
- (0.825397, 0.939999, 0.939999),
- (0.841270, 0.945611, 0.945611),
- (0.857143, 0.951190, 0.951190),
- (0.873016, 0.956736, 0.956736),
- (0.888889, 0.962250, 0.962250),
- (0.904762, 0.967733, 0.967733),
- (0.920635, 0.973185, 0.973185),
- (0.936508, 0.978607, 0.978607),
- (0.952381, 0.983999, 0.983999),
- (0.968254, 0.989361, 0.989361),
- (0.984127, 0.994695, 0.994695), (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.), (0.015873, 0.102869, 0.102869),
- (0.031746, 0.145479, 0.145479),
- (0.047619, 0.178174, 0.178174),
- (0.063492, 0.205738, 0.205738),
- (0.079365, 0.230022, 0.230022),
- (0.095238, 0.251976, 0.251976),
- (0.111111, 0.272166, 0.272166),
- (0.126984, 0.290957, 0.290957),
- (0.142857, 0.308607, 0.308607),
- (0.158730, 0.325300, 0.325300),
- (0.174603, 0.341178, 0.341178),
- (0.190476, 0.356348, 0.356348),
- (0.206349, 0.370899, 0.370899),
- (0.222222, 0.384900, 0.384900),
- (0.238095, 0.398410, 0.398410),
- (0.253968, 0.411476, 0.411476),
- (0.269841, 0.424139, 0.424139),
- (0.285714, 0.436436, 0.436436),
- (0.301587, 0.448395, 0.448395),
- (0.317460, 0.460044, 0.460044),
- (0.333333, 0.471405, 0.471405),
- (0.349206, 0.482498, 0.482498),
- (0.365079, 0.493342, 0.493342),
- (0.380952, 0.517549, 0.517549),
- (0.396825, 0.540674, 0.540674),
- (0.412698, 0.562849, 0.562849),
- (0.428571, 0.584183, 0.584183),
- (0.444444, 0.604765, 0.604765),
- (0.460317, 0.624669, 0.624669),
- (0.476190, 0.643958, 0.643958),
- (0.492063, 0.662687, 0.662687),
- (0.507937, 0.680900, 0.680900),
- (0.523810, 0.698638, 0.698638),
- (0.539683, 0.715937, 0.715937),
- (0.555556, 0.732828, 0.732828),
- (0.571429, 0.749338, 0.749338),
- (0.587302, 0.765493, 0.765493),
- (0.603175, 0.781313, 0.781313),
- (0.619048, 0.796819, 0.796819),
- (0.634921, 0.812029, 0.812029),
- (0.650794, 0.826960, 0.826960),
- (0.666667, 0.841625, 0.841625),
- (0.682540, 0.856040, 0.856040),
- (0.698413, 0.870216, 0.870216),
- (0.714286, 0.884164, 0.884164),
- (0.730159, 0.897896, 0.897896),
- (0.746032, 0.911421, 0.911421),
- (0.761905, 0.917208, 0.917208),
- (0.777778, 0.922958, 0.922958),
- (0.793651, 0.928673, 0.928673),
- (0.809524, 0.934353, 0.934353),
- (0.825397, 0.939999, 0.939999),
- (0.841270, 0.945611, 0.945611),
- (0.857143, 0.951190, 0.951190),
- (0.873016, 0.956736, 0.956736),
- (0.888889, 0.962250, 0.962250),
- (0.904762, 0.967733, 0.967733),
- (0.920635, 0.973185, 0.973185),
- (0.936508, 0.978607, 0.978607),
- (0.952381, 0.983999, 0.983999),
- (0.968254, 0.989361, 0.989361),
- (0.984127, 0.994695, 0.994695), (1.0, 1.0, 1.0)),
- 'blue': ((0., 0., 0.), (0.015873, 0.102869, 0.102869),
- (0.031746, 0.145479, 0.145479),
- (0.047619, 0.178174, 0.178174),
- (0.063492, 0.205738, 0.205738),
- (0.079365, 0.230022, 0.230022),
- (0.095238, 0.251976, 0.251976),
- (0.111111, 0.272166, 0.272166),
- (0.126984, 0.290957, 0.290957),
- (0.142857, 0.308607, 0.308607),
- (0.158730, 0.325300, 0.325300),
- (0.174603, 0.341178, 0.341178),
- (0.190476, 0.356348, 0.356348),
- (0.206349, 0.370899, 0.370899),
- (0.222222, 0.384900, 0.384900),
- (0.238095, 0.398410, 0.398410),
- (0.253968, 0.411476, 0.411476),
- (0.269841, 0.424139, 0.424139),
- (0.285714, 0.436436, 0.436436),
- (0.301587, 0.448395, 0.448395),
- (0.317460, 0.460044, 0.460044),
- (0.333333, 0.471405, 0.471405),
- (0.349206, 0.482498, 0.482498),
- (0.365079, 0.493342, 0.493342),
- (0.380952, 0.503953, 0.503953),
- (0.396825, 0.514344, 0.514344),
- (0.412698, 0.524531, 0.524531),
- (0.428571, 0.534522, 0.534522),
- (0.444444, 0.544331, 0.544331),
- (0.460317, 0.553966, 0.553966),
- (0.476190, 0.563436, 0.563436),
- (0.492063, 0.572750, 0.572750),
- (0.507937, 0.581914, 0.581914),
- (0.523810, 0.590937, 0.590937),
- (0.539683, 0.599824, 0.599824),
- (0.555556, 0.608581, 0.608581),
- (0.571429, 0.617213, 0.617213),
- (0.587302, 0.625727, 0.625727),
- (0.603175, 0.634126, 0.634126),
- (0.619048, 0.642416, 0.642416),
- (0.634921, 0.650600, 0.650600),
- (0.650794, 0.658682, 0.658682),
- (0.666667, 0.666667, 0.666667),
- (0.682540, 0.674556, 0.674556),
- (0.698413, 0.682355, 0.682355),
- (0.714286, 0.690066, 0.690066),
- (0.730159, 0.697691, 0.697691),
- (0.746032, 0.705234, 0.705234),
- (0.761905, 0.727166, 0.727166),
- (0.777778, 0.748455, 0.748455),
- (0.793651, 0.769156, 0.769156),
- (0.809524, 0.789314, 0.789314),
- (0.825397, 0.808969, 0.808969),
- (0.841270, 0.828159, 0.828159),
- (0.857143, 0.846913, 0.846913),
- (0.873016, 0.865261, 0.865261),
- (0.888889, 0.883229, 0.883229),
- (0.904762, 0.900837, 0.900837),
- (0.920635, 0.918109, 0.918109),
- (0.936508, 0.935061, 0.935061),
- (0.952381, 0.951711, 0.951711),
- (0.968254, 0.968075, 0.968075),
- (0.984127, 0.984167, 0.984167), (1.0, 1.0, 1.0))}
-
-_spring_data = {'red': ((0., 1., 1.), (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.), (1.0, 1.0, 1.0)),
- 'blue': ((0., 1., 1.), (1.0, 0.0, 0.0))}
-
-
-_summer_data = {'red': ((0., 0., 0.), (1.0, 1.0, 1.0)),
- 'green': ((0., 0.5, 0.5), (1.0, 1.0, 1.0)),
- 'blue': ((0., 0.4, 0.4), (1.0, 0.4, 0.4))}
-
-
-_winter_data = {'red': ((0., 0., 0.), (1.0, 0.0, 0.0)),
- 'green': ((0., 0., 0.), (1.0, 1.0, 1.0)),
- 'blue': ((0., 1., 1.), (1.0, 0.5, 0.5))}
-
-_nipy_spectral_data = {
- 'red': [(0.0, 0.0, 0.0), (0.05, 0.4667, 0.4667),
- (0.10, 0.5333, 0.5333), (0.15, 0.0, 0.0),
- (0.20, 0.0, 0.0), (0.25, 0.0, 0.0),
- (0.30, 0.0, 0.0), (0.35, 0.0, 0.0),
- (0.40, 0.0, 0.0), (0.45, 0.0, 0.0),
- (0.50, 0.0, 0.0), (0.55, 0.0, 0.0),
- (0.60, 0.0, 0.0), (0.65, 0.7333, 0.7333),
- (0.70, 0.9333, 0.9333), (0.75, 1.0, 1.0),
- (0.80, 1.0, 1.0), (0.85, 1.0, 1.0),
- (0.90, 0.8667, 0.8667), (0.95, 0.80, 0.80),
- (1.0, 0.80, 0.80)],
- 'green': [(0.0, 0.0, 0.0), (0.05, 0.0, 0.0),
- (0.10, 0.0, 0.0), (0.15, 0.0, 0.0),
- (0.20, 0.0, 0.0), (0.25, 0.4667, 0.4667),
- (0.30, 0.6000, 0.6000), (0.35, 0.6667, 0.6667),
- (0.40, 0.6667, 0.6667), (0.45, 0.6000, 0.6000),
- (0.50, 0.7333, 0.7333), (0.55, 0.8667, 0.8667),
- (0.60, 1.0, 1.0), (0.65, 1.0, 1.0),
- (0.70, 0.9333, 0.9333), (0.75, 0.8000, 0.8000),
- (0.80, 0.6000, 0.6000), (0.85, 0.0, 0.0),
- (0.90, 0.0, 0.0), (0.95, 0.0, 0.0),
- (1.0, 0.80, 0.80)],
- 'blue': [(0.0, 0.0, 0.0), (0.05, 0.5333, 0.5333),
- (0.10, 0.6000, 0.6000), (0.15, 0.6667, 0.6667),
- (0.20, 0.8667, 0.8667), (0.25, 0.8667, 0.8667),
- (0.30, 0.8667, 0.8667), (0.35, 0.6667, 0.6667),
- (0.40, 0.5333, 0.5333), (0.45, 0.0, 0.0),
- (0.5, 0.0, 0.0), (0.55, 0.0, 0.0),
- (0.60, 0.0, 0.0), (0.65, 0.0, 0.0),
- (0.70, 0.0, 0.0), (0.75, 0.0, 0.0),
- (0.80, 0.0, 0.0), (0.85, 0.0, 0.0),
- (0.90, 0.0, 0.0), (0.95, 0.0, 0.0),
- (1.0, 0.80, 0.80)],
-}
-
-
-# 34 colormaps based on color specifications and designs
-# developed by Cynthia Brewer (http://colorbrewer.org).
-# The ColorBrewer palettes have been included under the terms
-# of an Apache-stype license (for details, see the file
-# LICENSE_COLORBREWER in the license directory of the matplotlib
-# source distribution).
-
-# RGB values taken from Brewer's Excel sheet, divided by 255
-
-_Blues_data = (
- (0.96862745098039216, 0.98431372549019602, 1.0 ),
- (0.87058823529411766, 0.92156862745098034, 0.96862745098039216),
- (0.77647058823529413, 0.85882352941176465, 0.93725490196078431),
- (0.61960784313725492, 0.792156862745098 , 0.88235294117647056),
- (0.41960784313725491, 0.68235294117647061, 0.83921568627450982),
- (0.25882352941176473, 0.5725490196078431 , 0.77647058823529413),
- (0.12941176470588237, 0.44313725490196076, 0.70980392156862748),
- (0.03137254901960784, 0.31764705882352939, 0.61176470588235299),
- (0.03137254901960784, 0.18823529411764706, 0.41960784313725491)
- )
-
-_BrBG_data = (
- (0.32941176470588235, 0.18823529411764706, 0.0196078431372549 ),
- (0.5490196078431373 , 0.31764705882352939, 0.0392156862745098 ),
- (0.74901960784313726, 0.50588235294117645, 0.17647058823529413),
- (0.87450980392156863, 0.76078431372549016, 0.49019607843137253),
- (0.96470588235294119, 0.90980392156862744, 0.76470588235294112),
- (0.96078431372549022, 0.96078431372549022, 0.96078431372549022),
- (0.7803921568627451 , 0.91764705882352937, 0.89803921568627454),
- (0.50196078431372548, 0.80392156862745101, 0.75686274509803919),
- (0.20784313725490197, 0.59215686274509804, 0.5607843137254902 ),
- (0.00392156862745098, 0.4 , 0.36862745098039218),
- (0.0 , 0.23529411764705882, 0.18823529411764706)
- )
-
-_BuGn_data = (
- (0.96862745098039216, 0.9882352941176471 , 0.99215686274509807),
- (0.89803921568627454, 0.96078431372549022, 0.97647058823529409),
- (0.8 , 0.92549019607843142, 0.90196078431372551),
- (0.6 , 0.84705882352941175, 0.78823529411764703),
- (0.4 , 0.76078431372549016, 0.64313725490196083),
- (0.25490196078431371, 0.68235294117647061, 0.46274509803921571),
- (0.13725490196078433, 0.54509803921568623, 0.27058823529411763),
- (0.0 , 0.42745098039215684, 0.17254901960784313),
- (0.0 , 0.26666666666666666, 0.10588235294117647)
- )
-
-_BuPu_data = (
- (0.96862745098039216, 0.9882352941176471 , 0.99215686274509807),
- (0.8784313725490196 , 0.92549019607843142, 0.95686274509803926),
- (0.74901960784313726, 0.82745098039215681, 0.90196078431372551),
- (0.61960784313725492, 0.73725490196078436, 0.85490196078431369),
- (0.5490196078431373 , 0.58823529411764708, 0.77647058823529413),
- (0.5490196078431373 , 0.41960784313725491, 0.69411764705882351),
- (0.53333333333333333, 0.25490196078431371, 0.61568627450980395),
- (0.50588235294117645, 0.05882352941176471, 0.48627450980392156),
- (0.30196078431372547, 0.0 , 0.29411764705882354)
- )
-
-_GnBu_data = (
- (0.96862745098039216, 0.9882352941176471 , 0.94117647058823528),
- (0.8784313725490196 , 0.95294117647058818, 0.85882352941176465),
- (0.8 , 0.92156862745098034, 0.77254901960784317),
- (0.6588235294117647 , 0.8666666666666667 , 0.70980392156862748),
- (0.4823529411764706 , 0.8 , 0.7686274509803922 ),
- (0.30588235294117649, 0.70196078431372544, 0.82745098039215681),
- (0.16862745098039217, 0.5490196078431373 , 0.74509803921568629),
- (0.03137254901960784, 0.40784313725490196, 0.67450980392156867),
- (0.03137254901960784, 0.25098039215686274, 0.50588235294117645)
- )
-
-_Greens_data = (
- (0.96862745098039216, 0.9882352941176471 , 0.96078431372549022),
- (0.89803921568627454, 0.96078431372549022, 0.8784313725490196 ),
- (0.7803921568627451 , 0.9137254901960784 , 0.75294117647058822),
- (0.63137254901960782, 0.85098039215686272, 0.60784313725490191),
- (0.45490196078431372, 0.7686274509803922 , 0.46274509803921571),
- (0.25490196078431371, 0.6705882352941176 , 0.36470588235294116),
- (0.13725490196078433, 0.54509803921568623, 0.27058823529411763),
- (0.0 , 0.42745098039215684, 0.17254901960784313),
- (0.0 , 0.26666666666666666, 0.10588235294117647)
- )
-
-_Greys_data = (
- (1.0 , 1.0 , 1.0 ),
- (0.94117647058823528, 0.94117647058823528, 0.94117647058823528),
- (0.85098039215686272, 0.85098039215686272, 0.85098039215686272),
- (0.74117647058823533, 0.74117647058823533, 0.74117647058823533),
- (0.58823529411764708, 0.58823529411764708, 0.58823529411764708),
- (0.45098039215686275, 0.45098039215686275, 0.45098039215686275),
- (0.32156862745098042, 0.32156862745098042, 0.32156862745098042),
- (0.14509803921568629, 0.14509803921568629, 0.14509803921568629),
- (0.0 , 0.0 , 0.0 )
- )
-
-_Oranges_data = (
- (1.0 , 0.96078431372549022, 0.92156862745098034),
- (0.99607843137254903, 0.90196078431372551, 0.80784313725490198),
- (0.99215686274509807, 0.81568627450980391, 0.63529411764705879),
- (0.99215686274509807, 0.68235294117647061, 0.41960784313725491),
- (0.99215686274509807, 0.55294117647058827, 0.23529411764705882),
- (0.94509803921568625, 0.41176470588235292, 0.07450980392156863),
- (0.85098039215686272, 0.28235294117647058, 0.00392156862745098),
- (0.65098039215686276, 0.21176470588235294, 0.01176470588235294),
- (0.49803921568627452, 0.15294117647058825, 0.01568627450980392)
- )
-
-_OrRd_data = (
- (1.0 , 0.96862745098039216, 0.92549019607843142),
- (0.99607843137254903, 0.90980392156862744, 0.78431372549019607),
- (0.99215686274509807, 0.83137254901960789, 0.61960784313725492),
- (0.99215686274509807, 0.73333333333333328, 0.51764705882352946),
- (0.9882352941176471 , 0.55294117647058827, 0.34901960784313724),
- (0.93725490196078431, 0.396078431372549 , 0.28235294117647058),
- (0.84313725490196079, 0.18823529411764706, 0.12156862745098039),
- (0.70196078431372544, 0.0 , 0.0 ),
- (0.49803921568627452, 0.0 , 0.0 )
- )
-
-_PiYG_data = (
- (0.55686274509803924, 0.00392156862745098, 0.32156862745098042),
- (0.77254901960784317, 0.10588235294117647, 0.49019607843137253),
- (0.87058823529411766, 0.46666666666666667, 0.68235294117647061),
- (0.94509803921568625, 0.71372549019607845, 0.85490196078431369),
- (0.99215686274509807, 0.8784313725490196 , 0.93725490196078431),
- (0.96862745098039216, 0.96862745098039216, 0.96862745098039216),
- (0.90196078431372551, 0.96078431372549022, 0.81568627450980391),
- (0.72156862745098038, 0.88235294117647056, 0.52549019607843139),
- (0.49803921568627452, 0.73725490196078436, 0.25490196078431371),
- (0.30196078431372547, 0.5725490196078431 , 0.12941176470588237),
- (0.15294117647058825, 0.39215686274509803, 0.09803921568627451)
- )
-
-_PRGn_data = (
- (0.25098039215686274, 0.0 , 0.29411764705882354),
- (0.46274509803921571, 0.16470588235294117, 0.51372549019607838),
- (0.6 , 0.4392156862745098 , 0.6705882352941176 ),
- (0.76078431372549016, 0.6470588235294118 , 0.81176470588235294),
- (0.90588235294117647, 0.83137254901960789, 0.90980392156862744),
- (0.96862745098039216, 0.96862745098039216, 0.96862745098039216),
- (0.85098039215686272, 0.94117647058823528, 0.82745098039215681),
- (0.65098039215686276, 0.85882352941176465, 0.62745098039215685),
- (0.35294117647058826, 0.68235294117647061, 0.38039215686274508),
- (0.10588235294117647, 0.47058823529411764, 0.21568627450980393),
- (0.0 , 0.26666666666666666, 0.10588235294117647)
- )
-
-_PuBu_data = (
- (1.0 , 0.96862745098039216, 0.98431372549019602),
- (0.92549019607843142, 0.90588235294117647, 0.94901960784313721),
- (0.81568627450980391, 0.81960784313725488, 0.90196078431372551),
- (0.65098039215686276, 0.74117647058823533, 0.85882352941176465),
- (0.45490196078431372, 0.66274509803921566, 0.81176470588235294),
- (0.21176470588235294, 0.56470588235294117, 0.75294117647058822),
- (0.0196078431372549 , 0.4392156862745098 , 0.69019607843137254),
- (0.01568627450980392, 0.35294117647058826, 0.55294117647058827),
- (0.00784313725490196, 0.2196078431372549 , 0.34509803921568627)
- )
-
-_PuBuGn_data = (
- (1.0 , 0.96862745098039216, 0.98431372549019602),
- (0.92549019607843142, 0.88627450980392153, 0.94117647058823528),
- (0.81568627450980391, 0.81960784313725488, 0.90196078431372551),
- (0.65098039215686276, 0.74117647058823533, 0.85882352941176465),
- (0.40392156862745099, 0.66274509803921566, 0.81176470588235294),
- (0.21176470588235294, 0.56470588235294117, 0.75294117647058822),
- (0.00784313725490196, 0.50588235294117645, 0.54117647058823526),
- (0.00392156862745098, 0.42352941176470588, 0.34901960784313724),
- (0.00392156862745098, 0.27450980392156865, 0.21176470588235294)
- )
-
-_PuOr_data = (
- (0.49803921568627452, 0.23137254901960785, 0.03137254901960784),
- (0.70196078431372544, 0.34509803921568627, 0.02352941176470588),
- (0.8784313725490196 , 0.50980392156862742, 0.07843137254901961),
- (0.99215686274509807, 0.72156862745098038, 0.38823529411764707),
- (0.99607843137254903, 0.8784313725490196 , 0.71372549019607845),
- (0.96862745098039216, 0.96862745098039216, 0.96862745098039216),
- (0.84705882352941175, 0.85490196078431369, 0.92156862745098034),
- (0.69803921568627447, 0.6705882352941176 , 0.82352941176470584),
- (0.50196078431372548, 0.45098039215686275, 0.67450980392156867),
- (0.32941176470588235, 0.15294117647058825, 0.53333333333333333),
- (0.17647058823529413, 0.0 , 0.29411764705882354)
- )
-
-_PuRd_data = (
- (0.96862745098039216, 0.95686274509803926, 0.97647058823529409),
- (0.90588235294117647, 0.88235294117647056, 0.93725490196078431),
- (0.83137254901960789, 0.72549019607843135, 0.85490196078431369),
- (0.78823529411764703, 0.58039215686274515, 0.7803921568627451 ),
- (0.87450980392156863, 0.396078431372549 , 0.69019607843137254),
- (0.90588235294117647, 0.16078431372549021, 0.54117647058823526),
- (0.80784313725490198, 0.07058823529411765, 0.33725490196078434),
- (0.59607843137254901, 0.0 , 0.2627450980392157 ),
- (0.40392156862745099, 0.0 , 0.12156862745098039)
- )
-
-_Purples_data = (
- (0.9882352941176471 , 0.98431372549019602, 0.99215686274509807),
- (0.93725490196078431, 0.92941176470588238, 0.96078431372549022),
- (0.85490196078431369, 0.85490196078431369, 0.92156862745098034),
- (0.73725490196078436, 0.74117647058823533, 0.86274509803921573),
- (0.61960784313725492, 0.60392156862745094, 0.78431372549019607),
- (0.50196078431372548, 0.49019607843137253, 0.72941176470588232),
- (0.41568627450980394, 0.31764705882352939, 0.63921568627450975),
- (0.32941176470588235, 0.15294117647058825, 0.5607843137254902 ),
- (0.24705882352941178, 0.0 , 0.49019607843137253)
- )
-
-_RdBu_data = (
- (0.40392156862745099, 0.0 , 0.12156862745098039),
- (0.69803921568627447, 0.09411764705882353, 0.16862745098039217),
- (0.83921568627450982, 0.37647058823529411, 0.30196078431372547),
- (0.95686274509803926, 0.6470588235294118 , 0.50980392156862742),
- (0.99215686274509807, 0.85882352941176465, 0.7803921568627451 ),
- (0.96862745098039216, 0.96862745098039216, 0.96862745098039216),
- (0.81960784313725488, 0.89803921568627454, 0.94117647058823528),
- (0.5725490196078431 , 0.77254901960784317, 0.87058823529411766),
- (0.2627450980392157 , 0.57647058823529407, 0.76470588235294112),
- (0.12941176470588237, 0.4 , 0.67450980392156867),
- (0.0196078431372549 , 0.18823529411764706, 0.38039215686274508)
- )
-
-_RdGy_data = (
- (0.40392156862745099, 0.0 , 0.12156862745098039),
- (0.69803921568627447, 0.09411764705882353, 0.16862745098039217),
- (0.83921568627450982, 0.37647058823529411, 0.30196078431372547),
- (0.95686274509803926, 0.6470588235294118 , 0.50980392156862742),
- (0.99215686274509807, 0.85882352941176465, 0.7803921568627451 ),
- (1.0 , 1.0 , 1.0 ),
- (0.8784313725490196 , 0.8784313725490196 , 0.8784313725490196 ),
- (0.72941176470588232, 0.72941176470588232, 0.72941176470588232),
- (0.52941176470588236, 0.52941176470588236, 0.52941176470588236),
- (0.30196078431372547, 0.30196078431372547, 0.30196078431372547),
- (0.10196078431372549, 0.10196078431372549, 0.10196078431372549)
- )
-
-_RdPu_data = (
- (1.0 , 0.96862745098039216, 0.95294117647058818),
- (0.99215686274509807, 0.8784313725490196 , 0.86666666666666667),
- (0.9882352941176471 , 0.77254901960784317, 0.75294117647058822),
- (0.98039215686274506, 0.62352941176470589, 0.70980392156862748),
- (0.96862745098039216, 0.40784313725490196, 0.63137254901960782),
- (0.86666666666666667, 0.20392156862745098, 0.59215686274509804),
- (0.68235294117647061, 0.00392156862745098, 0.49411764705882355),
- (0.47843137254901963, 0.00392156862745098, 0.46666666666666667),
- (0.28627450980392155, 0.0 , 0.41568627450980394)
- )
-
-_RdYlBu_data = (
- (0.6470588235294118 , 0.0 , 0.14901960784313725),
- (0.84313725490196079, 0.18823529411764706 , 0.15294117647058825),
- (0.95686274509803926, 0.42745098039215684 , 0.2627450980392157 ),
- (0.99215686274509807, 0.68235294117647061 , 0.38039215686274508),
- (0.99607843137254903, 0.8784313725490196 , 0.56470588235294117),
- (1.0 , 1.0 , 0.74901960784313726),
- (0.8784313725490196 , 0.95294117647058818 , 0.97254901960784312),
- (0.6705882352941176 , 0.85098039215686272 , 0.9137254901960784 ),
- (0.45490196078431372, 0.67843137254901964 , 0.81960784313725488),
- (0.27058823529411763, 0.45882352941176469 , 0.70588235294117652),
- (0.19215686274509805, 0.21176470588235294 , 0.58431372549019611)
- )
-
-_RdYlGn_data = (
- (0.6470588235294118 , 0.0 , 0.14901960784313725),
- (0.84313725490196079, 0.18823529411764706 , 0.15294117647058825),
- (0.95686274509803926, 0.42745098039215684 , 0.2627450980392157 ),
- (0.99215686274509807, 0.68235294117647061 , 0.38039215686274508),
- (0.99607843137254903, 0.8784313725490196 , 0.54509803921568623),
- (1.0 , 1.0 , 0.74901960784313726),
- (0.85098039215686272, 0.93725490196078431 , 0.54509803921568623),
- (0.65098039215686276, 0.85098039215686272 , 0.41568627450980394),
- (0.4 , 0.74117647058823533 , 0.38823529411764707),
- (0.10196078431372549, 0.59607843137254901 , 0.31372549019607843),
- (0.0 , 0.40784313725490196 , 0.21568627450980393)
- )
-
-_Reds_data = (
- (1.0 , 0.96078431372549022 , 0.94117647058823528),
- (0.99607843137254903, 0.8784313725490196 , 0.82352941176470584),
- (0.9882352941176471 , 0.73333333333333328 , 0.63137254901960782),
- (0.9882352941176471 , 0.5725490196078431 , 0.44705882352941179),
- (0.98431372549019602, 0.41568627450980394 , 0.29019607843137257),
- (0.93725490196078431, 0.23137254901960785 , 0.17254901960784313),
- (0.79607843137254897, 0.094117647058823528, 0.11372549019607843),
- (0.6470588235294118 , 0.058823529411764705, 0.08235294117647058),
- (0.40392156862745099, 0.0 , 0.05098039215686274)
- )
-
-_Spectral_data = (
- (0.61960784313725492, 0.003921568627450980, 0.25882352941176473),
- (0.83529411764705885, 0.24313725490196078 , 0.30980392156862746),
- (0.95686274509803926, 0.42745098039215684 , 0.2627450980392157 ),
- (0.99215686274509807, 0.68235294117647061 , 0.38039215686274508),
- (0.99607843137254903, 0.8784313725490196 , 0.54509803921568623),
- (1.0 , 1.0 , 0.74901960784313726),
- (0.90196078431372551, 0.96078431372549022 , 0.59607843137254901),
- (0.6705882352941176 , 0.8666666666666667 , 0.64313725490196083),
- (0.4 , 0.76078431372549016 , 0.6470588235294118 ),
- (0.19607843137254902, 0.53333333333333333 , 0.74117647058823533),
- (0.36862745098039218, 0.30980392156862746 , 0.63529411764705879)
- )
-
-_YlGn_data = (
- (1.0 , 1.0 , 0.89803921568627454),
- (0.96862745098039216, 0.9882352941176471 , 0.72549019607843135),
- (0.85098039215686272, 0.94117647058823528 , 0.63921568627450975),
- (0.67843137254901964, 0.8666666666666667 , 0.55686274509803924),
- (0.47058823529411764, 0.77647058823529413 , 0.47450980392156861),
- (0.25490196078431371, 0.6705882352941176 , 0.36470588235294116),
- (0.13725490196078433, 0.51764705882352946 , 0.2627450980392157 ),
- (0.0 , 0.40784313725490196 , 0.21568627450980393),
- (0.0 , 0.27058823529411763 , 0.16078431372549021)
- )
-
-_YlGnBu_data = (
- (1.0 , 1.0 , 0.85098039215686272),
- (0.92941176470588238, 0.97254901960784312 , 0.69411764705882351),
- (0.7803921568627451 , 0.9137254901960784 , 0.70588235294117652),
- (0.49803921568627452, 0.80392156862745101 , 0.73333333333333328),
- (0.25490196078431371, 0.71372549019607845 , 0.7686274509803922 ),
- (0.11372549019607843, 0.56862745098039214 , 0.75294117647058822),
- (0.13333333333333333, 0.36862745098039218 , 0.6588235294117647 ),
- (0.14509803921568629, 0.20392156862745098 , 0.58039215686274515),
- (0.03137254901960784, 0.11372549019607843 , 0.34509803921568627)
- )
-
-_YlOrBr_data = (
- (1.0 , 1.0 , 0.89803921568627454),
- (1.0 , 0.96862745098039216 , 0.73725490196078436),
- (0.99607843137254903, 0.8901960784313725 , 0.56862745098039214),
- (0.99607843137254903, 0.7686274509803922 , 0.30980392156862746),
- (0.99607843137254903, 0.6 , 0.16078431372549021),
- (0.92549019607843142, 0.4392156862745098 , 0.07843137254901961),
- (0.8 , 0.29803921568627451 , 0.00784313725490196),
- (0.6 , 0.20392156862745098 , 0.01568627450980392),
- (0.4 , 0.14509803921568629 , 0.02352941176470588)
- )
-
-_YlOrRd_data = (
- (1.0 , 1.0 , 0.8 ),
- (1.0 , 0.92941176470588238 , 0.62745098039215685),
- (0.99607843137254903, 0.85098039215686272 , 0.46274509803921571),
- (0.99607843137254903, 0.69803921568627447 , 0.29803921568627451),
- (0.99215686274509807, 0.55294117647058827 , 0.23529411764705882),
- (0.9882352941176471 , 0.30588235294117649 , 0.16470588235294117),
- (0.8901960784313725 , 0.10196078431372549 , 0.10980392156862745),
- (0.74117647058823533, 0.0 , 0.14901960784313725),
- (0.50196078431372548, 0.0 , 0.14901960784313725)
- )
-
-
-# ColorBrewer's qualitative maps, implemented using ListedColormap
-# for use with mpl.colors.NoNorm
-
-_Accent_data = (
- (0.49803921568627452, 0.78823529411764703, 0.49803921568627452),
- (0.74509803921568629, 0.68235294117647061, 0.83137254901960789),
- (0.99215686274509807, 0.75294117647058822, 0.52549019607843139),
- (1.0, 1.0, 0.6 ),
- (0.2196078431372549, 0.42352941176470588, 0.69019607843137254),
- (0.94117647058823528, 0.00784313725490196, 0.49803921568627452),
- (0.74901960784313726, 0.35686274509803922, 0.09019607843137254),
- (0.4, 0.4, 0.4 ),
- )
-
-_Dark2_data = (
- (0.10588235294117647, 0.61960784313725492, 0.46666666666666667),
- (0.85098039215686272, 0.37254901960784315, 0.00784313725490196),
- (0.45882352941176469, 0.4392156862745098, 0.70196078431372544),
- (0.90588235294117647, 0.16078431372549021, 0.54117647058823526),
- (0.4, 0.65098039215686276, 0.11764705882352941),
- (0.90196078431372551, 0.6705882352941176, 0.00784313725490196),
- (0.65098039215686276, 0.46274509803921571, 0.11372549019607843),
- (0.4, 0.4, 0.4 ),
- )
-
-_Paired_data = (
- (0.65098039215686276, 0.80784313725490198, 0.8901960784313725 ),
- (0.12156862745098039, 0.47058823529411764, 0.70588235294117652),
- (0.69803921568627447, 0.87450980392156863, 0.54117647058823526),
- (0.2, 0.62745098039215685, 0.17254901960784313),
- (0.98431372549019602, 0.60392156862745094, 0.6 ),
- (0.8901960784313725, 0.10196078431372549, 0.10980392156862745),
- (0.99215686274509807, 0.74901960784313726, 0.43529411764705883),
- (1.0, 0.49803921568627452, 0.0 ),
- (0.792156862745098, 0.69803921568627447, 0.83921568627450982),
- (0.41568627450980394, 0.23921568627450981, 0.60392156862745094),
- (1.0, 1.0, 0.6 ),
- (0.69411764705882351, 0.34901960784313724, 0.15686274509803921),
- )
-
-_Pastel1_data = (
- (0.98431372549019602, 0.70588235294117652, 0.68235294117647061),
- (0.70196078431372544, 0.80392156862745101, 0.8901960784313725 ),
- (0.8, 0.92156862745098034, 0.77254901960784317),
- (0.87058823529411766, 0.79607843137254897, 0.89411764705882357),
- (0.99607843137254903, 0.85098039215686272, 0.65098039215686276),
- (1.0, 1.0, 0.8 ),
- (0.89803921568627454, 0.84705882352941175, 0.74117647058823533),
- (0.99215686274509807, 0.85490196078431369, 0.92549019607843142),
- (0.94901960784313721, 0.94901960784313721, 0.94901960784313721),
- )
-
-_Pastel2_data = (
- (0.70196078431372544, 0.88627450980392153, 0.80392156862745101),
- (0.99215686274509807, 0.80392156862745101, 0.67450980392156867),
- (0.79607843137254897, 0.83529411764705885, 0.90980392156862744),
- (0.95686274509803926, 0.792156862745098, 0.89411764705882357),
- (0.90196078431372551, 0.96078431372549022, 0.78823529411764703),
- (1.0, 0.94901960784313721, 0.68235294117647061),
- (0.94509803921568625, 0.88627450980392153, 0.8 ),
- (0.8, 0.8, 0.8 ),
- )
-
-_Set1_data = (
- (0.89411764705882357, 0.10196078431372549, 0.10980392156862745),
- (0.21568627450980393, 0.49411764705882355, 0.72156862745098038),
- (0.30196078431372547, 0.68627450980392157, 0.29019607843137257),
- (0.59607843137254901, 0.30588235294117649, 0.63921568627450975),
- (1.0, 0.49803921568627452, 0.0 ),
- (1.0, 1.0, 0.2 ),
- (0.65098039215686276, 0.33725490196078434, 0.15686274509803921),
- (0.96862745098039216, 0.50588235294117645, 0.74901960784313726),
- (0.6, 0.6, 0.6),
- )
-
-_Set2_data = (
- (0.4, 0.76078431372549016, 0.6470588235294118 ),
- (0.9882352941176471, 0.55294117647058827, 0.3843137254901961 ),
- (0.55294117647058827, 0.62745098039215685, 0.79607843137254897),
- (0.90588235294117647, 0.54117647058823526, 0.76470588235294112),
- (0.65098039215686276, 0.84705882352941175, 0.32941176470588235),
- (1.0, 0.85098039215686272, 0.18431372549019609),
- (0.89803921568627454, 0.7686274509803922, 0.58039215686274515),
- (0.70196078431372544, 0.70196078431372544, 0.70196078431372544),
- )
-
-_Set3_data = (
- (0.55294117647058827, 0.82745098039215681, 0.7803921568627451 ),
- (1.0, 1.0, 0.70196078431372544),
- (0.74509803921568629, 0.72941176470588232, 0.85490196078431369),
- (0.98431372549019602, 0.50196078431372548, 0.44705882352941179),
- (0.50196078431372548, 0.69411764705882351, 0.82745098039215681),
- (0.99215686274509807, 0.70588235294117652, 0.3843137254901961 ),
- (0.70196078431372544, 0.87058823529411766, 0.41176470588235292),
- (0.9882352941176471, 0.80392156862745101, 0.89803921568627454),
- (0.85098039215686272, 0.85098039215686272, 0.85098039215686272),
- (0.73725490196078436, 0.50196078431372548, 0.74117647058823533),
- (0.8, 0.92156862745098034, 0.77254901960784317),
- (1.0, 0.92941176470588238, 0.43529411764705883),
- )
-
-
-# The next 7 palettes are from the Yorick scientific visalisation package,
-# an evolution of the GIST package, both by David H. Munro.
-# They are released under a BSD-like license (see LICENSE_YORICK in
-# the license directory of the matplotlib source distribution).
-#
-# Most palette functions have been reduced to simple function descriptions
-# by Reinier Heeres, since the rgb components were mostly straight lines.
-# gist_earth_data and gist_ncar_data were simplified by a script and some
-# manual effort.
-
-_gist_earth_data = \
-{'red': (
-(0.0, 0.0, 0.0000),
-(0.2824, 0.1882, 0.1882),
-(0.4588, 0.2714, 0.2714),
-(0.5490, 0.4719, 0.4719),
-(0.6980, 0.7176, 0.7176),
-(0.7882, 0.7553, 0.7553),
-(1.0000, 0.9922, 0.9922),
-), 'green': (
-(0.0, 0.0, 0.0000),
-(0.0275, 0.0000, 0.0000),
-(0.1098, 0.1893, 0.1893),
-(0.1647, 0.3035, 0.3035),
-(0.2078, 0.3841, 0.3841),
-(0.2824, 0.5020, 0.5020),
-(0.5216, 0.6397, 0.6397),
-(0.6980, 0.7171, 0.7171),
-(0.7882, 0.6392, 0.6392),
-(0.7922, 0.6413, 0.6413),
-(0.8000, 0.6447, 0.6447),
-(0.8078, 0.6481, 0.6481),
-(0.8157, 0.6549, 0.6549),
-(0.8667, 0.6991, 0.6991),
-(0.8745, 0.7103, 0.7103),
-(0.8824, 0.7216, 0.7216),
-(0.8902, 0.7323, 0.7323),
-(0.8980, 0.7430, 0.7430),
-(0.9412, 0.8275, 0.8275),
-(0.9569, 0.8635, 0.8635),
-(0.9647, 0.8816, 0.8816),
-(0.9961, 0.9733, 0.9733),
-(1.0000, 0.9843, 0.9843),
-), 'blue': (
-(0.0, 0.0, 0.0000),
-(0.0039, 0.1684, 0.1684),
-(0.0078, 0.2212, 0.2212),
-(0.0275, 0.4329, 0.4329),
-(0.0314, 0.4549, 0.4549),
-(0.2824, 0.5004, 0.5004),
-(0.4667, 0.2748, 0.2748),
-(0.5451, 0.3205, 0.3205),
-(0.7843, 0.3961, 0.3961),
-(0.8941, 0.6651, 0.6651),
-(1.0000, 0.9843, 0.9843),
-)}
-
-_gist_gray_data = {
- 'red': gfunc[3],
- 'green': gfunc[3],
- 'blue': gfunc[3],
-}
-
-_gist_heat_data = {
- 'red': lambda x: 1.5 * x,
- 'green': lambda x: 2 * x - 1,
- 'blue': lambda x: 4 * x - 3,
-}
-
-_gist_ncar_data = \
-{'red': (
-(0.0, 0.0, 0.0000),
-(0.3098, 0.0000, 0.0000),
-(0.3725, 0.3993, 0.3993),
-(0.4235, 0.5003, 0.5003),
-(0.5333, 1.0000, 1.0000),
-(0.7922, 1.0000, 1.0000),
-(0.8471, 0.6218, 0.6218),
-(0.8980, 0.9235, 0.9235),
-(1.0000, 0.9961, 0.9961),
-), 'green': (
-(0.0, 0.0, 0.0000),
-(0.0510, 0.3722, 0.3722),
-(0.1059, 0.0000, 0.0000),
-(0.1569, 0.7202, 0.7202),
-(0.1608, 0.7537, 0.7537),
-(0.1647, 0.7752, 0.7752),
-(0.2157, 1.0000, 1.0000),
-(0.2588, 0.9804, 0.9804),
-(0.2706, 0.9804, 0.9804),
-(0.3176, 1.0000, 1.0000),
-(0.3686, 0.8081, 0.8081),
-(0.4275, 1.0000, 1.0000),
-(0.5216, 1.0000, 1.0000),
-(0.6314, 0.7292, 0.7292),
-(0.6863, 0.2796, 0.2796),
-(0.7451, 0.0000, 0.0000),
-(0.7922, 0.0000, 0.0000),
-(0.8431, 0.1753, 0.1753),
-(0.8980, 0.5000, 0.5000),
-(1.0000, 0.9725, 0.9725),
-), 'blue': (
-(0.0, 0.5020, 0.5020),
-(0.0510, 0.0222, 0.0222),
-(0.1098, 1.0000, 1.0000),
-(0.2039, 1.0000, 1.0000),
-(0.2627, 0.6145, 0.6145),
-(0.3216, 0.0000, 0.0000),
-(0.4157, 0.0000, 0.0000),
-(0.4745, 0.2342, 0.2342),
-(0.5333, 0.0000, 0.0000),
-(0.5804, 0.0000, 0.0000),
-(0.6314, 0.0549, 0.0549),
-(0.6902, 0.0000, 0.0000),
-(0.7373, 0.0000, 0.0000),
-(0.7922, 0.9738, 0.9738),
-(0.8000, 1.0000, 1.0000),
-(0.8431, 1.0000, 1.0000),
-(0.8980, 0.9341, 0.9341),
-(1.0000, 0.9961, 0.9961),
-)}
-
-_gist_rainbow_data = (
- (0.000, (1.00, 0.00, 0.16)),
- (0.030, (1.00, 0.00, 0.00)),
- (0.215, (1.00, 1.00, 0.00)),
- (0.400, (0.00, 1.00, 0.00)),
- (0.586, (0.00, 1.00, 1.00)),
- (0.770, (0.00, 0.00, 1.00)),
- (0.954, (1.00, 0.00, 1.00)),
- (1.000, (1.00, 0.00, 0.75))
-)
-
-_gist_stern_data = {
- 'red': (
- (0.000, 0.000, 0.000), (0.0547, 1.000, 1.000),
- (0.250, 0.027, 0.250), # (0.2500, 0.250, 0.250),
- (1.000, 1.000, 1.000)),
- 'green': ((0, 0, 0), (1, 1, 1)),
- 'blue': (
- (0.000, 0.000, 0.000), (0.500, 1.000, 1.000),
- (0.735, 0.000, 0.000), (1.000, 1.000, 1.000))
-}
-
-_gist_yarg_data = {
- 'red': lambda x: 1 - x,
- 'green': lambda x: 1 - x,
- 'blue': lambda x: 1 - x,
-}
-
-# This bipolar color map was generated from CoolWarmFloat33.csv of
-# "Diverging Color Maps for Scientific Visualization" by Kenneth Moreland.
-# <http://www.kennethmoreland.com/color-maps/>
-_coolwarm_data = {
- 'red': [
- (0.0, 0.2298057, 0.2298057),
- (0.03125, 0.26623388, 0.26623388),
- (0.0625, 0.30386891, 0.30386891),
- (0.09375, 0.342804478, 0.342804478),
- (0.125, 0.38301334, 0.38301334),
- (0.15625, 0.424369608, 0.424369608),
- (0.1875, 0.46666708, 0.46666708),
- (0.21875, 0.509635204, 0.509635204),
- (0.25, 0.552953156, 0.552953156),
- (0.28125, 0.596262162, 0.596262162),
- (0.3125, 0.639176211, 0.639176211),
- (0.34375, 0.681291281, 0.681291281),
- (0.375, 0.722193294, 0.722193294),
- (0.40625, 0.761464949, 0.761464949),
- (0.4375, 0.798691636, 0.798691636),
- (0.46875, 0.833466556, 0.833466556),
- (0.5, 0.865395197, 0.865395197),
- (0.53125, 0.897787179, 0.897787179),
- (0.5625, 0.924127593, 0.924127593),
- (0.59375, 0.944468518, 0.944468518),
- (0.625, 0.958852946, 0.958852946),
- (0.65625, 0.96732803, 0.96732803),
- (0.6875, 0.969954137, 0.969954137),
- (0.71875, 0.966811177, 0.966811177),
- (0.75, 0.958003065, 0.958003065),
- (0.78125, 0.943660866, 0.943660866),
- (0.8125, 0.923944917, 0.923944917),
- (0.84375, 0.89904617, 0.89904617),
- (0.875, 0.869186849, 0.869186849),
- (0.90625, 0.834620542, 0.834620542),
- (0.9375, 0.795631745, 0.795631745),
- (0.96875, 0.752534934, 0.752534934),
- (1.0, 0.705673158, 0.705673158)],
- 'green': [
- (0.0, 0.298717966, 0.298717966),
- (0.03125, 0.353094838, 0.353094838),
- (0.0625, 0.406535296, 0.406535296),
- (0.09375, 0.458757618, 0.458757618),
- (0.125, 0.50941904, 0.50941904),
- (0.15625, 0.558148092, 0.558148092),
- (0.1875, 0.604562568, 0.604562568),
- (0.21875, 0.648280772, 0.648280772),
- (0.25, 0.688929332, 0.688929332),
- (0.28125, 0.726149107, 0.726149107),
- (0.3125, 0.759599947, 0.759599947),
- (0.34375, 0.788964712, 0.788964712),
- (0.375, 0.813952739, 0.813952739),
- (0.40625, 0.834302879, 0.834302879),
- (0.4375, 0.849786142, 0.849786142),
- (0.46875, 0.860207984, 0.860207984),
- (0.5, 0.86541021, 0.86541021),
- (0.53125, 0.848937047, 0.848937047),
- (0.5625, 0.827384882, 0.827384882),
- (0.59375, 0.800927443, 0.800927443),
- (0.625, 0.769767752, 0.769767752),
- (0.65625, 0.734132809, 0.734132809),
- (0.6875, 0.694266682, 0.694266682),
- (0.71875, 0.650421156, 0.650421156),
- (0.75, 0.602842431, 0.602842431),
- (0.78125, 0.551750968, 0.551750968),
- (0.8125, 0.49730856, 0.49730856),
- (0.84375, 0.439559467, 0.439559467),
- (0.875, 0.378313092, 0.378313092),
- (0.90625, 0.312874446, 0.312874446),
- (0.9375, 0.24128379, 0.24128379),
- (0.96875, 0.157246067, 0.157246067),
- (1.0, 0.01555616, 0.01555616)],
- 'blue': [
- (0.0, 0.753683153, 0.753683153),
- (0.03125, 0.801466763, 0.801466763),
- (0.0625, 0.84495867, 0.84495867),
- (0.09375, 0.883725899, 0.883725899),
- (0.125, 0.917387822, 0.917387822),
- (0.15625, 0.945619588, 0.945619588),
- (0.1875, 0.968154911, 0.968154911),
- (0.21875, 0.98478814, 0.98478814),
- (0.25, 0.995375608, 0.995375608),
- (0.28125, 0.999836203, 0.999836203),
- (0.3125, 0.998151185, 0.998151185),
- (0.34375, 0.990363227, 0.990363227),
- (0.375, 0.976574709, 0.976574709),
- (0.40625, 0.956945269, 0.956945269),
- (0.4375, 0.931688648, 0.931688648),
- (0.46875, 0.901068838, 0.901068838),
- (0.5, 0.865395561, 0.865395561),
- (0.53125, 0.820880546, 0.820880546),
- (0.5625, 0.774508472, 0.774508472),
- (0.59375, 0.726736146, 0.726736146),
- (0.625, 0.678007945, 0.678007945),
- (0.65625, 0.628751763, 0.628751763),
- (0.6875, 0.579375448, 0.579375448),
- (0.71875, 0.530263762, 0.530263762),
- (0.75, 0.481775914, 0.481775914),
- (0.78125, 0.434243684, 0.434243684),
- (0.8125, 0.387970225, 0.387970225),
- (0.84375, 0.343229596, 0.343229596),
- (0.875, 0.300267182, 0.300267182),
- (0.90625, 0.259301199, 0.259301199),
- (0.9375, 0.220525627, 0.220525627),
- (0.96875, 0.184115123, 0.184115123),
- (1.0, 0.150232812, 0.150232812)]
- }
-
-# Implementation of Carey Rappaport's CMRmap.
-# See `A Color Map for Effective Black-and-White Rendering of Color-Scale
-# Images' by Carey Rappaport
-# http://www.mathworks.com/matlabcentral/fileexchange/2662-cmrmap-m
-_CMRmap_data = {'red': ((0.000, 0.00, 0.00),
- (0.125, 0.15, 0.15),
- (0.250, 0.30, 0.30),
- (0.375, 0.60, 0.60),
- (0.500, 1.00, 1.00),
- (0.625, 0.90, 0.90),
- (0.750, 0.90, 0.90),
- (0.875, 0.90, 0.90),
- (1.000, 1.00, 1.00)),
- 'green': ((0.000, 0.00, 0.00),
- (0.125, 0.15, 0.15),
- (0.250, 0.15, 0.15),
- (0.375, 0.20, 0.20),
- (0.500, 0.25, 0.25),
- (0.625, 0.50, 0.50),
- (0.750, 0.75, 0.75),
- (0.875, 0.90, 0.90),
- (1.000, 1.00, 1.00)),
- 'blue': ((0.000, 0.00, 0.00),
- (0.125, 0.50, 0.50),
- (0.250, 0.75, 0.75),
- (0.375, 0.50, 0.50),
- (0.500, 0.15, 0.15),
- (0.625, 0.00, 0.00),
- (0.750, 0.10, 0.10),
- (0.875, 0.50, 0.50),
- (1.000, 1.00, 1.00))}
-
-
-# An MIT licensed, colorblind-friendly heatmap from Wistia:
-# https://github.com/wistia/heatmap-palette
-# http://wistia.com/blog/heatmaps-for-colorblindness
-#
-# >>> import matplotlib.colors as c
-# >>> colors = ["#e4ff7a", "#ffe81a", "#ffbd00", "#ffa000", "#fc7f00"]
-# >>> cm = c.LinearSegmentedColormap.from_list('wistia', colors)
-# >>> _wistia_data = cm._segmentdata
-# >>> del _wistia_data['alpha']
-#
-_wistia_data = {
- 'red': [(0.0, 0.8941176470588236, 0.8941176470588236),
- (0.25, 1.0, 1.0),
- (0.5, 1.0, 1.0),
- (0.75, 1.0, 1.0),
- (1.0, 0.9882352941176471, 0.9882352941176471)],
- 'green': [(0.0, 1.0, 1.0),
- (0.25, 0.9098039215686274, 0.9098039215686274),
- (0.5, 0.7411764705882353, 0.7411764705882353),
- (0.75, 0.6274509803921569, 0.6274509803921569),
- (1.0, 0.4980392156862745, 0.4980392156862745)],
- 'blue': [(0.0, 0.47843137254901963, 0.47843137254901963),
- (0.25, 0.10196078431372549, 0.10196078431372549),
- (0.5, 0.0, 0.0),
- (0.75, 0.0, 0.0),
- (1.0, 0.0, 0.0)],
-}
-
-
-# Categorical palettes from Vega:
-# https://github.com/vega/vega/wiki/Scales
-# (divided by 255)
-#
-
-_tab10_data = (
- (0.12156862745098039, 0.4666666666666667, 0.7058823529411765 ), # 1f77b4
- (1.0, 0.4980392156862745, 0.054901960784313725), # ff7f0e
- (0.17254901960784313, 0.6274509803921569, 0.17254901960784313 ), # 2ca02c
- (0.8392156862745098, 0.15294117647058825, 0.1568627450980392 ), # d62728
- (0.5803921568627451, 0.403921568627451, 0.7411764705882353 ), # 9467bd
- (0.5490196078431373, 0.33725490196078434, 0.29411764705882354 ), # 8c564b
- (0.8901960784313725, 0.4666666666666667, 0.7607843137254902 ), # e377c2
- (0.4980392156862745, 0.4980392156862745, 0.4980392156862745 ), # 7f7f7f
- (0.7372549019607844, 0.7411764705882353, 0.13333333333333333 ), # bcbd22
- (0.09019607843137255, 0.7450980392156863, 0.8117647058823529), # 17becf
-)
-
-_tab20_data = (
- (0.12156862745098039, 0.4666666666666667, 0.7058823529411765 ), # 1f77b4
- (0.6823529411764706, 0.7803921568627451, 0.9098039215686274 ), # aec7e8
- (1.0, 0.4980392156862745, 0.054901960784313725), # ff7f0e
- (1.0, 0.7333333333333333, 0.47058823529411764 ), # ffbb78
- (0.17254901960784313, 0.6274509803921569, 0.17254901960784313 ), # 2ca02c
- (0.596078431372549, 0.8745098039215686, 0.5411764705882353 ), # 98df8a
- (0.8392156862745098, 0.15294117647058825, 0.1568627450980392 ), # d62728
- (1.0, 0.596078431372549, 0.5882352941176471 ), # ff9896
- (0.5803921568627451, 0.403921568627451, 0.7411764705882353 ), # 9467bd
- (0.7725490196078432, 0.6901960784313725, 0.8352941176470589 ), # c5b0d5
- (0.5490196078431373, 0.33725490196078434, 0.29411764705882354 ), # 8c564b
- (0.7686274509803922, 0.611764705882353, 0.5803921568627451 ), # c49c94
- (0.8901960784313725, 0.4666666666666667, 0.7607843137254902 ), # e377c2
- (0.9686274509803922, 0.7137254901960784, 0.8235294117647058 ), # f7b6d2
- (0.4980392156862745, 0.4980392156862745, 0.4980392156862745 ), # 7f7f7f
- (0.7803921568627451, 0.7803921568627451, 0.7803921568627451 ), # c7c7c7
- (0.7372549019607844, 0.7411764705882353, 0.13333333333333333 ), # bcbd22
- (0.8588235294117647, 0.8588235294117647, 0.5529411764705883 ), # dbdb8d
- (0.09019607843137255, 0.7450980392156863, 0.8117647058823529 ), # 17becf
- (0.6196078431372549, 0.8549019607843137, 0.8980392156862745), # 9edae5
-)
-
-_tab20b_data = (
- (0.2235294117647059, 0.23137254901960785, 0.4745098039215686 ), # 393b79
- (0.3215686274509804, 0.32941176470588235, 0.6392156862745098 ), # 5254a3
- (0.4196078431372549, 0.43137254901960786, 0.8117647058823529 ), # 6b6ecf
- (0.611764705882353, 0.6196078431372549, 0.8705882352941177 ), # 9c9ede
- (0.38823529411764707, 0.4745098039215686, 0.2235294117647059 ), # 637939
- (0.5490196078431373, 0.6352941176470588, 0.3215686274509804 ), # 8ca252
- (0.7098039215686275, 0.8117647058823529, 0.4196078431372549 ), # b5cf6b
- (0.807843137254902, 0.8588235294117647, 0.611764705882353 ), # cedb9c
- (0.5490196078431373, 0.42745098039215684, 0.19215686274509805), # 8c6d31
- (0.7411764705882353, 0.6196078431372549, 0.2235294117647059 ), # bd9e39
- (0.9058823529411765, 0.7294117647058823, 0.3215686274509804 ), # e7ba52
- (0.9058823529411765, 0.796078431372549, 0.5803921568627451 ), # e7cb94
- (0.5176470588235295, 0.23529411764705882, 0.2235294117647059 ), # 843c39
- (0.6784313725490196, 0.28627450980392155, 0.2901960784313726 ), # ad494a
- (0.8392156862745098, 0.3803921568627451, 0.4196078431372549 ), # d6616b
- (0.9058823529411765, 0.5882352941176471, 0.611764705882353 ), # e7969c
- (0.4823529411764706, 0.2549019607843137, 0.45098039215686275), # 7b4173
- (0.6470588235294118, 0.3176470588235294, 0.5803921568627451 ), # a55194
- (0.807843137254902, 0.42745098039215684, 0.7411764705882353 ), # ce6dbd
- (0.8705882352941177, 0.6196078431372549, 0.8392156862745098 ), # de9ed6
-)
-
-_tab20c_data = (
- (0.19215686274509805, 0.5098039215686274, 0.7411764705882353 ), # 3182bd
- (0.4196078431372549, 0.6823529411764706, 0.8392156862745098 ), # 6baed6
- (0.6196078431372549, 0.792156862745098, 0.8823529411764706 ), # 9ecae1
- (0.7764705882352941, 0.8588235294117647, 0.9372549019607843 ), # c6dbef
- (0.9019607843137255, 0.3333333333333333, 0.050980392156862744), # e6550d
- (0.9921568627450981, 0.5529411764705883, 0.23529411764705882 ), # fd8d3c
- (0.9921568627450981, 0.6823529411764706, 0.4196078431372549 ), # fdae6b
- (0.9921568627450981, 0.8156862745098039, 0.6352941176470588 ), # fdd0a2
- (0.19215686274509805, 0.6392156862745098, 0.32941176470588235 ), # 31a354
- (0.4549019607843137, 0.7686274509803922, 0.4627450980392157 ), # 74c476
- (0.6313725490196078, 0.8509803921568627, 0.6078431372549019 ), # a1d99b
- (0.7803921568627451, 0.9137254901960784, 0.7529411764705882 ), # c7e9c0
- (0.4588235294117647, 0.4196078431372549, 0.6941176470588235 ), # 756bb1
- (0.6196078431372549, 0.6039215686274509, 0.7843137254901961 ), # 9e9ac8
- (0.7372549019607844, 0.7411764705882353, 0.8627450980392157 ), # bcbddc
- (0.8549019607843137, 0.8549019607843137, 0.9215686274509803 ), # dadaeb
- (0.38823529411764707, 0.38823529411764707, 0.38823529411764707 ), # 636363
- (0.5882352941176471, 0.5882352941176471, 0.5882352941176471 ), # 969696
- (0.7411764705882353, 0.7411764705882353, 0.7411764705882353 ), # bdbdbd
- (0.8509803921568627, 0.8509803921568627, 0.8509803921568627 ), # d9d9d9
-)
-
-
-datad = {
- 'Blues': _Blues_data,
- 'BrBG': _BrBG_data,
- 'BuGn': _BuGn_data,
- 'BuPu': _BuPu_data,
- 'CMRmap': _CMRmap_data,
- 'GnBu': _GnBu_data,
- 'Greens': _Greens_data,
- 'Greys': _Greys_data,
- 'OrRd': _OrRd_data,
- 'Oranges': _Oranges_data,
- 'PRGn': _PRGn_data,
- 'PiYG': _PiYG_data,
- 'PuBu': _PuBu_data,
- 'PuBuGn': _PuBuGn_data,
- 'PuOr': _PuOr_data,
- 'PuRd': _PuRd_data,
- 'Purples': _Purples_data,
- 'RdBu': _RdBu_data,
- 'RdGy': _RdGy_data,
- 'RdPu': _RdPu_data,
- 'RdYlBu': _RdYlBu_data,
- 'RdYlGn': _RdYlGn_data,
- 'Reds': _Reds_data,
- 'Spectral': _Spectral_data,
- 'Wistia': _wistia_data,
- 'YlGn': _YlGn_data,
- 'YlGnBu': _YlGnBu_data,
- 'YlOrBr': _YlOrBr_data,
- 'YlOrRd': _YlOrRd_data,
- 'afmhot': _afmhot_data,
- 'autumn': _autumn_data,
- 'binary': _binary_data,
- 'bone': _bone_data,
- 'brg': _brg_data,
- 'bwr': _bwr_data,
- 'cool': _cool_data,
- 'coolwarm': _coolwarm_data,
- 'copper': _copper_data,
- 'cubehelix': _cubehelix_data,
- 'flag': _flag_data,
- 'gist_earth': _gist_earth_data,
- 'gist_gray': _gist_gray_data,
- 'gist_heat': _gist_heat_data,
- 'gist_ncar': _gist_ncar_data,
- 'gist_rainbow': _gist_rainbow_data,
- 'gist_stern': _gist_stern_data,
- 'gist_yarg': _gist_yarg_data,
- 'gnuplot': _gnuplot_data,
- 'gnuplot2': _gnuplot2_data,
- 'gray': _gray_data,
- 'hot': _hot_data,
- 'hsv': _hsv_data,
- 'jet': _jet_data,
- 'nipy_spectral': _nipy_spectral_data,
- 'ocean': _ocean_data,
- 'pink': _pink_data,
- 'prism': _prism_data,
- 'rainbow': _rainbow_data,
- 'seismic': _seismic_data,
- 'spring': _spring_data,
- 'summer': _summer_data,
- 'terrain': _terrain_data,
- 'winter': _winter_data,
- # Qualitative
- 'Accent': {'listed': _Accent_data},
- 'Dark2': {'listed': _Dark2_data},
- 'Paired': {'listed': _Paired_data},
- 'Pastel1': {'listed': _Pastel1_data},
- 'Pastel2': {'listed': _Pastel2_data},
- 'Set1': {'listed': _Set1_data},
- 'Set2': {'listed': _Set2_data},
- 'Set3': {'listed': _Set3_data},
- 'tab10': {'listed': _tab10_data},
- 'tab20': {'listed': _tab20_data},
- 'tab20b': {'listed': _tab20b_data},
- 'tab20c': {'listed': _tab20c_data},
-}
diff --git a/contrib/python/matplotlib/py2/matplotlib/_cm_listed.py b/contrib/python/matplotlib/py2/matplotlib/_cm_listed.py
deleted file mode 100644
index c4a4e13e4d..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/_cm_listed.py
+++ /dev/null
@@ -1,1298 +0,0 @@
-from .colors import ListedColormap
-
-_magma_data = [[0.001462, 0.000466, 0.013866],
- [0.002258, 0.001295, 0.018331],
- [0.003279, 0.002305, 0.023708],
- [0.004512, 0.003490, 0.029965],
- [0.005950, 0.004843, 0.037130],
- [0.007588, 0.006356, 0.044973],
- [0.009426, 0.008022, 0.052844],
- [0.011465, 0.009828, 0.060750],
- [0.013708, 0.011771, 0.068667],
- [0.016156, 0.013840, 0.076603],
- [0.018815, 0.016026, 0.084584],
- [0.021692, 0.018320, 0.092610],
- [0.024792, 0.020715, 0.100676],
- [0.028123, 0.023201, 0.108787],
- [0.031696, 0.025765, 0.116965],
- [0.035520, 0.028397, 0.125209],
- [0.039608, 0.031090, 0.133515],
- [0.043830, 0.033830, 0.141886],
- [0.048062, 0.036607, 0.150327],
- [0.052320, 0.039407, 0.158841],
- [0.056615, 0.042160, 0.167446],
- [0.060949, 0.044794, 0.176129],
- [0.065330, 0.047318, 0.184892],
- [0.069764, 0.049726, 0.193735],
- [0.074257, 0.052017, 0.202660],
- [0.078815, 0.054184, 0.211667],
- [0.083446, 0.056225, 0.220755],
- [0.088155, 0.058133, 0.229922],
- [0.092949, 0.059904, 0.239164],
- [0.097833, 0.061531, 0.248477],
- [0.102815, 0.063010, 0.257854],
- [0.107899, 0.064335, 0.267289],
- [0.113094, 0.065492, 0.276784],
- [0.118405, 0.066479, 0.286321],
- [0.123833, 0.067295, 0.295879],
- [0.129380, 0.067935, 0.305443],
- [0.135053, 0.068391, 0.315000],
- [0.140858, 0.068654, 0.324538],
- [0.146785, 0.068738, 0.334011],
- [0.152839, 0.068637, 0.343404],
- [0.159018, 0.068354, 0.352688],
- [0.165308, 0.067911, 0.361816],
- [0.171713, 0.067305, 0.370771],
- [0.178212, 0.066576, 0.379497],
- [0.184801, 0.065732, 0.387973],
- [0.191460, 0.064818, 0.396152],
- [0.198177, 0.063862, 0.404009],
- [0.204935, 0.062907, 0.411514],
- [0.211718, 0.061992, 0.418647],
- [0.218512, 0.061158, 0.425392],
- [0.225302, 0.060445, 0.431742],
- [0.232077, 0.059889, 0.437695],
- [0.238826, 0.059517, 0.443256],
- [0.245543, 0.059352, 0.448436],
- [0.252220, 0.059415, 0.453248],
- [0.258857, 0.059706, 0.457710],
- [0.265447, 0.060237, 0.461840],
- [0.271994, 0.060994, 0.465660],
- [0.278493, 0.061978, 0.469190],
- [0.284951, 0.063168, 0.472451],
- [0.291366, 0.064553, 0.475462],
- [0.297740, 0.066117, 0.478243],
- [0.304081, 0.067835, 0.480812],
- [0.310382, 0.069702, 0.483186],
- [0.316654, 0.071690, 0.485380],
- [0.322899, 0.073782, 0.487408],
- [0.329114, 0.075972, 0.489287],
- [0.335308, 0.078236, 0.491024],
- [0.341482, 0.080564, 0.492631],
- [0.347636, 0.082946, 0.494121],
- [0.353773, 0.085373, 0.495501],
- [0.359898, 0.087831, 0.496778],
- [0.366012, 0.090314, 0.497960],
- [0.372116, 0.092816, 0.499053],
- [0.378211, 0.095332, 0.500067],
- [0.384299, 0.097855, 0.501002],
- [0.390384, 0.100379, 0.501864],
- [0.396467, 0.102902, 0.502658],
- [0.402548, 0.105420, 0.503386],
- [0.408629, 0.107930, 0.504052],
- [0.414709, 0.110431, 0.504662],
- [0.420791, 0.112920, 0.505215],
- [0.426877, 0.115395, 0.505714],
- [0.432967, 0.117855, 0.506160],
- [0.439062, 0.120298, 0.506555],
- [0.445163, 0.122724, 0.506901],
- [0.451271, 0.125132, 0.507198],
- [0.457386, 0.127522, 0.507448],
- [0.463508, 0.129893, 0.507652],
- [0.469640, 0.132245, 0.507809],
- [0.475780, 0.134577, 0.507921],
- [0.481929, 0.136891, 0.507989],
- [0.488088, 0.139186, 0.508011],
- [0.494258, 0.141462, 0.507988],
- [0.500438, 0.143719, 0.507920],
- [0.506629, 0.145958, 0.507806],
- [0.512831, 0.148179, 0.507648],
- [0.519045, 0.150383, 0.507443],
- [0.525270, 0.152569, 0.507192],
- [0.531507, 0.154739, 0.506895],
- [0.537755, 0.156894, 0.506551],
- [0.544015, 0.159033, 0.506159],
- [0.550287, 0.161158, 0.505719],
- [0.556571, 0.163269, 0.505230],
- [0.562866, 0.165368, 0.504692],
- [0.569172, 0.167454, 0.504105],
- [0.575490, 0.169530, 0.503466],
- [0.581819, 0.171596, 0.502777],
- [0.588158, 0.173652, 0.502035],
- [0.594508, 0.175701, 0.501241],
- [0.600868, 0.177743, 0.500394],
- [0.607238, 0.179779, 0.499492],
- [0.613617, 0.181811, 0.498536],
- [0.620005, 0.183840, 0.497524],
- [0.626401, 0.185867, 0.496456],
- [0.632805, 0.187893, 0.495332],
- [0.639216, 0.189921, 0.494150],
- [0.645633, 0.191952, 0.492910],
- [0.652056, 0.193986, 0.491611],
- [0.658483, 0.196027, 0.490253],
- [0.664915, 0.198075, 0.488836],
- [0.671349, 0.200133, 0.487358],
- [0.677786, 0.202203, 0.485819],
- [0.684224, 0.204286, 0.484219],
- [0.690661, 0.206384, 0.482558],
- [0.697098, 0.208501, 0.480835],
- [0.703532, 0.210638, 0.479049],
- [0.709962, 0.212797, 0.477201],
- [0.716387, 0.214982, 0.475290],
- [0.722805, 0.217194, 0.473316],
- [0.729216, 0.219437, 0.471279],
- [0.735616, 0.221713, 0.469180],
- [0.742004, 0.224025, 0.467018],
- [0.748378, 0.226377, 0.464794],
- [0.754737, 0.228772, 0.462509],
- [0.761077, 0.231214, 0.460162],
- [0.767398, 0.233705, 0.457755],
- [0.773695, 0.236249, 0.455289],
- [0.779968, 0.238851, 0.452765],
- [0.786212, 0.241514, 0.450184],
- [0.792427, 0.244242, 0.447543],
- [0.798608, 0.247040, 0.444848],
- [0.804752, 0.249911, 0.442102],
- [0.810855, 0.252861, 0.439305],
- [0.816914, 0.255895, 0.436461],
- [0.822926, 0.259016, 0.433573],
- [0.828886, 0.262229, 0.430644],
- [0.834791, 0.265540, 0.427671],
- [0.840636, 0.268953, 0.424666],
- [0.846416, 0.272473, 0.421631],
- [0.852126, 0.276106, 0.418573],
- [0.857763, 0.279857, 0.415496],
- [0.863320, 0.283729, 0.412403],
- [0.868793, 0.287728, 0.409303],
- [0.874176, 0.291859, 0.406205],
- [0.879464, 0.296125, 0.403118],
- [0.884651, 0.300530, 0.400047],
- [0.889731, 0.305079, 0.397002],
- [0.894700, 0.309773, 0.393995],
- [0.899552, 0.314616, 0.391037],
- [0.904281, 0.319610, 0.388137],
- [0.908884, 0.324755, 0.385308],
- [0.913354, 0.330052, 0.382563],
- [0.917689, 0.335500, 0.379915],
- [0.921884, 0.341098, 0.377376],
- [0.925937, 0.346844, 0.374959],
- [0.929845, 0.352734, 0.372677],
- [0.933606, 0.358764, 0.370541],
- [0.937221, 0.364929, 0.368567],
- [0.940687, 0.371224, 0.366762],
- [0.944006, 0.377643, 0.365136],
- [0.947180, 0.384178, 0.363701],
- [0.950210, 0.390820, 0.362468],
- [0.953099, 0.397563, 0.361438],
- [0.955849, 0.404400, 0.360619],
- [0.958464, 0.411324, 0.360014],
- [0.960949, 0.418323, 0.359630],
- [0.963310, 0.425390, 0.359469],
- [0.965549, 0.432519, 0.359529],
- [0.967671, 0.439703, 0.359810],
- [0.969680, 0.446936, 0.360311],
- [0.971582, 0.454210, 0.361030],
- [0.973381, 0.461520, 0.361965],
- [0.975082, 0.468861, 0.363111],
- [0.976690, 0.476226, 0.364466],
- [0.978210, 0.483612, 0.366025],
- [0.979645, 0.491014, 0.367783],
- [0.981000, 0.498428, 0.369734],
- [0.982279, 0.505851, 0.371874],
- [0.983485, 0.513280, 0.374198],
- [0.984622, 0.520713, 0.376698],
- [0.985693, 0.528148, 0.379371],
- [0.986700, 0.535582, 0.382210],
- [0.987646, 0.543015, 0.385210],
- [0.988533, 0.550446, 0.388365],
- [0.989363, 0.557873, 0.391671],
- [0.990138, 0.565296, 0.395122],
- [0.990871, 0.572706, 0.398714],
- [0.991558, 0.580107, 0.402441],
- [0.992196, 0.587502, 0.406299],
- [0.992785, 0.594891, 0.410283],
- [0.993326, 0.602275, 0.414390],
- [0.993834, 0.609644, 0.418613],
- [0.994309, 0.616999, 0.422950],
- [0.994738, 0.624350, 0.427397],
- [0.995122, 0.631696, 0.431951],
- [0.995480, 0.639027, 0.436607],
- [0.995810, 0.646344, 0.441361],
- [0.996096, 0.653659, 0.446213],
- [0.996341, 0.660969, 0.451160],
- [0.996580, 0.668256, 0.456192],
- [0.996775, 0.675541, 0.461314],
- [0.996925, 0.682828, 0.466526],
- [0.997077, 0.690088, 0.471811],
- [0.997186, 0.697349, 0.477182],
- [0.997254, 0.704611, 0.482635],
- [0.997325, 0.711848, 0.488154],
- [0.997351, 0.719089, 0.493755],
- [0.997351, 0.726324, 0.499428],
- [0.997341, 0.733545, 0.505167],
- [0.997285, 0.740772, 0.510983],
- [0.997228, 0.747981, 0.516859],
- [0.997138, 0.755190, 0.522806],
- [0.997019, 0.762398, 0.528821],
- [0.996898, 0.769591, 0.534892],
- [0.996727, 0.776795, 0.541039],
- [0.996571, 0.783977, 0.547233],
- [0.996369, 0.791167, 0.553499],
- [0.996162, 0.798348, 0.559820],
- [0.995932, 0.805527, 0.566202],
- [0.995680, 0.812706, 0.572645],
- [0.995424, 0.819875, 0.579140],
- [0.995131, 0.827052, 0.585701],
- [0.994851, 0.834213, 0.592307],
- [0.994524, 0.841387, 0.598983],
- [0.994222, 0.848540, 0.605696],
- [0.993866, 0.855711, 0.612482],
- [0.993545, 0.862859, 0.619299],
- [0.993170, 0.870024, 0.626189],
- [0.992831, 0.877168, 0.633109],
- [0.992440, 0.884330, 0.640099],
- [0.992089, 0.891470, 0.647116],
- [0.991688, 0.898627, 0.654202],
- [0.991332, 0.905763, 0.661309],
- [0.990930, 0.912915, 0.668481],
- [0.990570, 0.920049, 0.675675],
- [0.990175, 0.927196, 0.682926],
- [0.989815, 0.934329, 0.690198],
- [0.989434, 0.941470, 0.697519],
- [0.989077, 0.948604, 0.704863],
- [0.988717, 0.955742, 0.712242],
- [0.988367, 0.962878, 0.719649],
- [0.988033, 0.970012, 0.727077],
- [0.987691, 0.977154, 0.734536],
- [0.987387, 0.984288, 0.742002],
- [0.987053, 0.991438, 0.749504]]
-
-_inferno_data = [[0.001462, 0.000466, 0.013866],
- [0.002267, 0.001270, 0.018570],
- [0.003299, 0.002249, 0.024239],
- [0.004547, 0.003392, 0.030909],
- [0.006006, 0.004692, 0.038558],
- [0.007676, 0.006136, 0.046836],
- [0.009561, 0.007713, 0.055143],
- [0.011663, 0.009417, 0.063460],
- [0.013995, 0.011225, 0.071862],
- [0.016561, 0.013136, 0.080282],
- [0.019373, 0.015133, 0.088767],
- [0.022447, 0.017199, 0.097327],
- [0.025793, 0.019331, 0.105930],
- [0.029432, 0.021503, 0.114621],
- [0.033385, 0.023702, 0.123397],
- [0.037668, 0.025921, 0.132232],
- [0.042253, 0.028139, 0.141141],
- [0.046915, 0.030324, 0.150164],
- [0.051644, 0.032474, 0.159254],
- [0.056449, 0.034569, 0.168414],
- [0.061340, 0.036590, 0.177642],
- [0.066331, 0.038504, 0.186962],
- [0.071429, 0.040294, 0.196354],
- [0.076637, 0.041905, 0.205799],
- [0.081962, 0.043328, 0.215289],
- [0.087411, 0.044556, 0.224813],
- [0.092990, 0.045583, 0.234358],
- [0.098702, 0.046402, 0.243904],
- [0.104551, 0.047008, 0.253430],
- [0.110536, 0.047399, 0.262912],
- [0.116656, 0.047574, 0.272321],
- [0.122908, 0.047536, 0.281624],
- [0.129285, 0.047293, 0.290788],
- [0.135778, 0.046856, 0.299776],
- [0.142378, 0.046242, 0.308553],
- [0.149073, 0.045468, 0.317085],
- [0.155850, 0.044559, 0.325338],
- [0.162689, 0.043554, 0.333277],
- [0.169575, 0.042489, 0.340874],
- [0.176493, 0.041402, 0.348111],
- [0.183429, 0.040329, 0.354971],
- [0.190367, 0.039309, 0.361447],
- [0.197297, 0.038400, 0.367535],
- [0.204209, 0.037632, 0.373238],
- [0.211095, 0.037030, 0.378563],
- [0.217949, 0.036615, 0.383522],
- [0.224763, 0.036405, 0.388129],
- [0.231538, 0.036405, 0.392400],
- [0.238273, 0.036621, 0.396353],
- [0.244967, 0.037055, 0.400007],
- [0.251620, 0.037705, 0.403378],
- [0.258234, 0.038571, 0.406485],
- [0.264810, 0.039647, 0.409345],
- [0.271347, 0.040922, 0.411976],
- [0.277850, 0.042353, 0.414392],
- [0.284321, 0.043933, 0.416608],
- [0.290763, 0.045644, 0.418637],
- [0.297178, 0.047470, 0.420491],
- [0.303568, 0.049396, 0.422182],
- [0.309935, 0.051407, 0.423721],
- [0.316282, 0.053490, 0.425116],
- [0.322610, 0.055634, 0.426377],
- [0.328921, 0.057827, 0.427511],
- [0.335217, 0.060060, 0.428524],
- [0.341500, 0.062325, 0.429425],
- [0.347771, 0.064616, 0.430217],
- [0.354032, 0.066925, 0.430906],
- [0.360284, 0.069247, 0.431497],
- [0.366529, 0.071579, 0.431994],
- [0.372768, 0.073915, 0.432400],
- [0.379001, 0.076253, 0.432719],
- [0.385228, 0.078591, 0.432955],
- [0.391453, 0.080927, 0.433109],
- [0.397674, 0.083257, 0.433183],
- [0.403894, 0.085580, 0.433179],
- [0.410113, 0.087896, 0.433098],
- [0.416331, 0.090203, 0.432943],
- [0.422549, 0.092501, 0.432714],
- [0.428768, 0.094790, 0.432412],
- [0.434987, 0.097069, 0.432039],
- [0.441207, 0.099338, 0.431594],
- [0.447428, 0.101597, 0.431080],
- [0.453651, 0.103848, 0.430498],
- [0.459875, 0.106089, 0.429846],
- [0.466100, 0.108322, 0.429125],
- [0.472328, 0.110547, 0.428334],
- [0.478558, 0.112764, 0.427475],
- [0.484789, 0.114974, 0.426548],
- [0.491022, 0.117179, 0.425552],
- [0.497257, 0.119379, 0.424488],
- [0.503493, 0.121575, 0.423356],
- [0.509730, 0.123769, 0.422156],
- [0.515967, 0.125960, 0.420887],
- [0.522206, 0.128150, 0.419549],
- [0.528444, 0.130341, 0.418142],
- [0.534683, 0.132534, 0.416667],
- [0.540920, 0.134729, 0.415123],
- [0.547157, 0.136929, 0.413511],
- [0.553392, 0.139134, 0.411829],
- [0.559624, 0.141346, 0.410078],
- [0.565854, 0.143567, 0.408258],
- [0.572081, 0.145797, 0.406369],
- [0.578304, 0.148039, 0.404411],
- [0.584521, 0.150294, 0.402385],
- [0.590734, 0.152563, 0.400290],
- [0.596940, 0.154848, 0.398125],
- [0.603139, 0.157151, 0.395891],
- [0.609330, 0.159474, 0.393589],
- [0.615513, 0.161817, 0.391219],
- [0.621685, 0.164184, 0.388781],
- [0.627847, 0.166575, 0.386276],
- [0.633998, 0.168992, 0.383704],
- [0.640135, 0.171438, 0.381065],
- [0.646260, 0.173914, 0.378359],
- [0.652369, 0.176421, 0.375586],
- [0.658463, 0.178962, 0.372748],
- [0.664540, 0.181539, 0.369846],
- [0.670599, 0.184153, 0.366879],
- [0.676638, 0.186807, 0.363849],
- [0.682656, 0.189501, 0.360757],
- [0.688653, 0.192239, 0.357603],
- [0.694627, 0.195021, 0.354388],
- [0.700576, 0.197851, 0.351113],
- [0.706500, 0.200728, 0.347777],
- [0.712396, 0.203656, 0.344383],
- [0.718264, 0.206636, 0.340931],
- [0.724103, 0.209670, 0.337424],
- [0.729909, 0.212759, 0.333861],
- [0.735683, 0.215906, 0.330245],
- [0.741423, 0.219112, 0.326576],
- [0.747127, 0.222378, 0.322856],
- [0.752794, 0.225706, 0.319085],
- [0.758422, 0.229097, 0.315266],
- [0.764010, 0.232554, 0.311399],
- [0.769556, 0.236077, 0.307485],
- [0.775059, 0.239667, 0.303526],
- [0.780517, 0.243327, 0.299523],
- [0.785929, 0.247056, 0.295477],
- [0.791293, 0.250856, 0.291390],
- [0.796607, 0.254728, 0.287264],
- [0.801871, 0.258674, 0.283099],
- [0.807082, 0.262692, 0.278898],
- [0.812239, 0.266786, 0.274661],
- [0.817341, 0.270954, 0.270390],
- [0.822386, 0.275197, 0.266085],
- [0.827372, 0.279517, 0.261750],
- [0.832299, 0.283913, 0.257383],
- [0.837165, 0.288385, 0.252988],
- [0.841969, 0.292933, 0.248564],
- [0.846709, 0.297559, 0.244113],
- [0.851384, 0.302260, 0.239636],
- [0.855992, 0.307038, 0.235133],
- [0.860533, 0.311892, 0.230606],
- [0.865006, 0.316822, 0.226055],
- [0.869409, 0.321827, 0.221482],
- [0.873741, 0.326906, 0.216886],
- [0.878001, 0.332060, 0.212268],
- [0.882188, 0.337287, 0.207628],
- [0.886302, 0.342586, 0.202968],
- [0.890341, 0.347957, 0.198286],
- [0.894305, 0.353399, 0.193584],
- [0.898192, 0.358911, 0.188860],
- [0.902003, 0.364492, 0.184116],
- [0.905735, 0.370140, 0.179350],
- [0.909390, 0.375856, 0.174563],
- [0.912966, 0.381636, 0.169755],
- [0.916462, 0.387481, 0.164924],
- [0.919879, 0.393389, 0.160070],
- [0.923215, 0.399359, 0.155193],
- [0.926470, 0.405389, 0.150292],
- [0.929644, 0.411479, 0.145367],
- [0.932737, 0.417627, 0.140417],
- [0.935747, 0.423831, 0.135440],
- [0.938675, 0.430091, 0.130438],
- [0.941521, 0.436405, 0.125409],
- [0.944285, 0.442772, 0.120354],
- [0.946965, 0.449191, 0.115272],
- [0.949562, 0.455660, 0.110164],
- [0.952075, 0.462178, 0.105031],
- [0.954506, 0.468744, 0.099874],
- [0.956852, 0.475356, 0.094695],
- [0.959114, 0.482014, 0.089499],
- [0.961293, 0.488716, 0.084289],
- [0.963387, 0.495462, 0.079073],
- [0.965397, 0.502249, 0.073859],
- [0.967322, 0.509078, 0.068659],
- [0.969163, 0.515946, 0.063488],
- [0.970919, 0.522853, 0.058367],
- [0.972590, 0.529798, 0.053324],
- [0.974176, 0.536780, 0.048392],
- [0.975677, 0.543798, 0.043618],
- [0.977092, 0.550850, 0.039050],
- [0.978422, 0.557937, 0.034931],
- [0.979666, 0.565057, 0.031409],
- [0.980824, 0.572209, 0.028508],
- [0.981895, 0.579392, 0.026250],
- [0.982881, 0.586606, 0.024661],
- [0.983779, 0.593849, 0.023770],
- [0.984591, 0.601122, 0.023606],
- [0.985315, 0.608422, 0.024202],
- [0.985952, 0.615750, 0.025592],
- [0.986502, 0.623105, 0.027814],
- [0.986964, 0.630485, 0.030908],
- [0.987337, 0.637890, 0.034916],
- [0.987622, 0.645320, 0.039886],
- [0.987819, 0.652773, 0.045581],
- [0.987926, 0.660250, 0.051750],
- [0.987945, 0.667748, 0.058329],
- [0.987874, 0.675267, 0.065257],
- [0.987714, 0.682807, 0.072489],
- [0.987464, 0.690366, 0.079990],
- [0.987124, 0.697944, 0.087731],
- [0.986694, 0.705540, 0.095694],
- [0.986175, 0.713153, 0.103863],
- [0.985566, 0.720782, 0.112229],
- [0.984865, 0.728427, 0.120785],
- [0.984075, 0.736087, 0.129527],
- [0.983196, 0.743758, 0.138453],
- [0.982228, 0.751442, 0.147565],
- [0.981173, 0.759135, 0.156863],
- [0.980032, 0.766837, 0.166353],
- [0.978806, 0.774545, 0.176037],
- [0.977497, 0.782258, 0.185923],
- [0.976108, 0.789974, 0.196018],
- [0.974638, 0.797692, 0.206332],
- [0.973088, 0.805409, 0.216877],
- [0.971468, 0.813122, 0.227658],
- [0.969783, 0.820825, 0.238686],
- [0.968041, 0.828515, 0.249972],
- [0.966243, 0.836191, 0.261534],
- [0.964394, 0.843848, 0.273391],
- [0.962517, 0.851476, 0.285546],
- [0.960626, 0.859069, 0.298010],
- [0.958720, 0.866624, 0.310820],
- [0.956834, 0.874129, 0.323974],
- [0.954997, 0.881569, 0.337475],
- [0.953215, 0.888942, 0.351369],
- [0.951546, 0.896226, 0.365627],
- [0.950018, 0.903409, 0.380271],
- [0.948683, 0.910473, 0.395289],
- [0.947594, 0.917399, 0.410665],
- [0.946809, 0.924168, 0.426373],
- [0.946392, 0.930761, 0.442367],
- [0.946403, 0.937159, 0.458592],
- [0.946903, 0.943348, 0.474970],
- [0.947937, 0.949318, 0.491426],
- [0.949545, 0.955063, 0.507860],
- [0.951740, 0.960587, 0.524203],
- [0.954529, 0.965896, 0.540361],
- [0.957896, 0.971003, 0.556275],
- [0.961812, 0.975924, 0.571925],
- [0.966249, 0.980678, 0.587206],
- [0.971162, 0.985282, 0.602154],
- [0.976511, 0.989753, 0.616760],
- [0.982257, 0.994109, 0.631017],
- [0.988362, 0.998364, 0.644924]]
-
-_plasma_data = [[0.050383, 0.029803, 0.527975],
- [0.063536, 0.028426, 0.533124],
- [0.075353, 0.027206, 0.538007],
- [0.086222, 0.026125, 0.542658],
- [0.096379, 0.025165, 0.547103],
- [0.105980, 0.024309, 0.551368],
- [0.115124, 0.023556, 0.555468],
- [0.123903, 0.022878, 0.559423],
- [0.132381, 0.022258, 0.563250],
- [0.140603, 0.021687, 0.566959],
- [0.148607, 0.021154, 0.570562],
- [0.156421, 0.020651, 0.574065],
- [0.164070, 0.020171, 0.577478],
- [0.171574, 0.019706, 0.580806],
- [0.178950, 0.019252, 0.584054],
- [0.186213, 0.018803, 0.587228],
- [0.193374, 0.018354, 0.590330],
- [0.200445, 0.017902, 0.593364],
- [0.207435, 0.017442, 0.596333],
- [0.214350, 0.016973, 0.599239],
- [0.221197, 0.016497, 0.602083],
- [0.227983, 0.016007, 0.604867],
- [0.234715, 0.015502, 0.607592],
- [0.241396, 0.014979, 0.610259],
- [0.248032, 0.014439, 0.612868],
- [0.254627, 0.013882, 0.615419],
- [0.261183, 0.013308, 0.617911],
- [0.267703, 0.012716, 0.620346],
- [0.274191, 0.012109, 0.622722],
- [0.280648, 0.011488, 0.625038],
- [0.287076, 0.010855, 0.627295],
- [0.293478, 0.010213, 0.629490],
- [0.299855, 0.009561, 0.631624],
- [0.306210, 0.008902, 0.633694],
- [0.312543, 0.008239, 0.635700],
- [0.318856, 0.007576, 0.637640],
- [0.325150, 0.006915, 0.639512],
- [0.331426, 0.006261, 0.641316],
- [0.337683, 0.005618, 0.643049],
- [0.343925, 0.004991, 0.644710],
- [0.350150, 0.004382, 0.646298],
- [0.356359, 0.003798, 0.647810],
- [0.362553, 0.003243, 0.649245],
- [0.368733, 0.002724, 0.650601],
- [0.374897, 0.002245, 0.651876],
- [0.381047, 0.001814, 0.653068],
- [0.387183, 0.001434, 0.654177],
- [0.393304, 0.001114, 0.655199],
- [0.399411, 0.000859, 0.656133],
- [0.405503, 0.000678, 0.656977],
- [0.411580, 0.000577, 0.657730],
- [0.417642, 0.000564, 0.658390],
- [0.423689, 0.000646, 0.658956],
- [0.429719, 0.000831, 0.659425],
- [0.435734, 0.001127, 0.659797],
- [0.441732, 0.001540, 0.660069],
- [0.447714, 0.002080, 0.660240],
- [0.453677, 0.002755, 0.660310],
- [0.459623, 0.003574, 0.660277],
- [0.465550, 0.004545, 0.660139],
- [0.471457, 0.005678, 0.659897],
- [0.477344, 0.006980, 0.659549],
- [0.483210, 0.008460, 0.659095],
- [0.489055, 0.010127, 0.658534],
- [0.494877, 0.011990, 0.657865],
- [0.500678, 0.014055, 0.657088],
- [0.506454, 0.016333, 0.656202],
- [0.512206, 0.018833, 0.655209],
- [0.517933, 0.021563, 0.654109],
- [0.523633, 0.024532, 0.652901],
- [0.529306, 0.027747, 0.651586],
- [0.534952, 0.031217, 0.650165],
- [0.540570, 0.034950, 0.648640],
- [0.546157, 0.038954, 0.647010],
- [0.551715, 0.043136, 0.645277],
- [0.557243, 0.047331, 0.643443],
- [0.562738, 0.051545, 0.641509],
- [0.568201, 0.055778, 0.639477],
- [0.573632, 0.060028, 0.637349],
- [0.579029, 0.064296, 0.635126],
- [0.584391, 0.068579, 0.632812],
- [0.589719, 0.072878, 0.630408],
- [0.595011, 0.077190, 0.627917],
- [0.600266, 0.081516, 0.625342],
- [0.605485, 0.085854, 0.622686],
- [0.610667, 0.090204, 0.619951],
- [0.615812, 0.094564, 0.617140],
- [0.620919, 0.098934, 0.614257],
- [0.625987, 0.103312, 0.611305],
- [0.631017, 0.107699, 0.608287],
- [0.636008, 0.112092, 0.605205],
- [0.640959, 0.116492, 0.602065],
- [0.645872, 0.120898, 0.598867],
- [0.650746, 0.125309, 0.595617],
- [0.655580, 0.129725, 0.592317],
- [0.660374, 0.134144, 0.588971],
- [0.665129, 0.138566, 0.585582],
- [0.669845, 0.142992, 0.582154],
- [0.674522, 0.147419, 0.578688],
- [0.679160, 0.151848, 0.575189],
- [0.683758, 0.156278, 0.571660],
- [0.688318, 0.160709, 0.568103],
- [0.692840, 0.165141, 0.564522],
- [0.697324, 0.169573, 0.560919],
- [0.701769, 0.174005, 0.557296],
- [0.706178, 0.178437, 0.553657],
- [0.710549, 0.182868, 0.550004],
- [0.714883, 0.187299, 0.546338],
- [0.719181, 0.191729, 0.542663],
- [0.723444, 0.196158, 0.538981],
- [0.727670, 0.200586, 0.535293],
- [0.731862, 0.205013, 0.531601],
- [0.736019, 0.209439, 0.527908],
- [0.740143, 0.213864, 0.524216],
- [0.744232, 0.218288, 0.520524],
- [0.748289, 0.222711, 0.516834],
- [0.752312, 0.227133, 0.513149],
- [0.756304, 0.231555, 0.509468],
- [0.760264, 0.235976, 0.505794],
- [0.764193, 0.240396, 0.502126],
- [0.768090, 0.244817, 0.498465],
- [0.771958, 0.249237, 0.494813],
- [0.775796, 0.253658, 0.491171],
- [0.779604, 0.258078, 0.487539],
- [0.783383, 0.262500, 0.483918],
- [0.787133, 0.266922, 0.480307],
- [0.790855, 0.271345, 0.476706],
- [0.794549, 0.275770, 0.473117],
- [0.798216, 0.280197, 0.469538],
- [0.801855, 0.284626, 0.465971],
- [0.805467, 0.289057, 0.462415],
- [0.809052, 0.293491, 0.458870],
- [0.812612, 0.297928, 0.455338],
- [0.816144, 0.302368, 0.451816],
- [0.819651, 0.306812, 0.448306],
- [0.823132, 0.311261, 0.444806],
- [0.826588, 0.315714, 0.441316],
- [0.830018, 0.320172, 0.437836],
- [0.833422, 0.324635, 0.434366],
- [0.836801, 0.329105, 0.430905],
- [0.840155, 0.333580, 0.427455],
- [0.843484, 0.338062, 0.424013],
- [0.846788, 0.342551, 0.420579],
- [0.850066, 0.347048, 0.417153],
- [0.853319, 0.351553, 0.413734],
- [0.856547, 0.356066, 0.410322],
- [0.859750, 0.360588, 0.406917],
- [0.862927, 0.365119, 0.403519],
- [0.866078, 0.369660, 0.400126],
- [0.869203, 0.374212, 0.396738],
- [0.872303, 0.378774, 0.393355],
- [0.875376, 0.383347, 0.389976],
- [0.878423, 0.387932, 0.386600],
- [0.881443, 0.392529, 0.383229],
- [0.884436, 0.397139, 0.379860],
- [0.887402, 0.401762, 0.376494],
- [0.890340, 0.406398, 0.373130],
- [0.893250, 0.411048, 0.369768],
- [0.896131, 0.415712, 0.366407],
- [0.898984, 0.420392, 0.363047],
- [0.901807, 0.425087, 0.359688],
- [0.904601, 0.429797, 0.356329],
- [0.907365, 0.434524, 0.352970],
- [0.910098, 0.439268, 0.349610],
- [0.912800, 0.444029, 0.346251],
- [0.915471, 0.448807, 0.342890],
- [0.918109, 0.453603, 0.339529],
- [0.920714, 0.458417, 0.336166],
- [0.923287, 0.463251, 0.332801],
- [0.925825, 0.468103, 0.329435],
- [0.928329, 0.472975, 0.326067],
- [0.930798, 0.477867, 0.322697],
- [0.933232, 0.482780, 0.319325],
- [0.935630, 0.487712, 0.315952],
- [0.937990, 0.492667, 0.312575],
- [0.940313, 0.497642, 0.309197],
- [0.942598, 0.502639, 0.305816],
- [0.944844, 0.507658, 0.302433],
- [0.947051, 0.512699, 0.299049],
- [0.949217, 0.517763, 0.295662],
- [0.951344, 0.522850, 0.292275],
- [0.953428, 0.527960, 0.288883],
- [0.955470, 0.533093, 0.285490],
- [0.957469, 0.538250, 0.282096],
- [0.959424, 0.543431, 0.278701],
- [0.961336, 0.548636, 0.275305],
- [0.963203, 0.553865, 0.271909],
- [0.965024, 0.559118, 0.268513],
- [0.966798, 0.564396, 0.265118],
- [0.968526, 0.569700, 0.261721],
- [0.970205, 0.575028, 0.258325],
- [0.971835, 0.580382, 0.254931],
- [0.973416, 0.585761, 0.251540],
- [0.974947, 0.591165, 0.248151],
- [0.976428, 0.596595, 0.244767],
- [0.977856, 0.602051, 0.241387],
- [0.979233, 0.607532, 0.238013],
- [0.980556, 0.613039, 0.234646],
- [0.981826, 0.618572, 0.231287],
- [0.983041, 0.624131, 0.227937],
- [0.984199, 0.629718, 0.224595],
- [0.985301, 0.635330, 0.221265],
- [0.986345, 0.640969, 0.217948],
- [0.987332, 0.646633, 0.214648],
- [0.988260, 0.652325, 0.211364],
- [0.989128, 0.658043, 0.208100],
- [0.989935, 0.663787, 0.204859],
- [0.990681, 0.669558, 0.201642],
- [0.991365, 0.675355, 0.198453],
- [0.991985, 0.681179, 0.195295],
- [0.992541, 0.687030, 0.192170],
- [0.993032, 0.692907, 0.189084],
- [0.993456, 0.698810, 0.186041],
- [0.993814, 0.704741, 0.183043],
- [0.994103, 0.710698, 0.180097],
- [0.994324, 0.716681, 0.177208],
- [0.994474, 0.722691, 0.174381],
- [0.994553, 0.728728, 0.171622],
- [0.994561, 0.734791, 0.168938],
- [0.994495, 0.740880, 0.166335],
- [0.994355, 0.746995, 0.163821],
- [0.994141, 0.753137, 0.161404],
- [0.993851, 0.759304, 0.159092],
- [0.993482, 0.765499, 0.156891],
- [0.993033, 0.771720, 0.154808],
- [0.992505, 0.777967, 0.152855],
- [0.991897, 0.784239, 0.151042],
- [0.991209, 0.790537, 0.149377],
- [0.990439, 0.796859, 0.147870],
- [0.989587, 0.803205, 0.146529],
- [0.988648, 0.809579, 0.145357],
- [0.987621, 0.815978, 0.144363],
- [0.986509, 0.822401, 0.143557],
- [0.985314, 0.828846, 0.142945],
- [0.984031, 0.835315, 0.142528],
- [0.982653, 0.841812, 0.142303],
- [0.981190, 0.848329, 0.142279],
- [0.979644, 0.854866, 0.142453],
- [0.977995, 0.861432, 0.142808],
- [0.976265, 0.868016, 0.143351],
- [0.974443, 0.874622, 0.144061],
- [0.972530, 0.881250, 0.144923],
- [0.970533, 0.887896, 0.145919],
- [0.968443, 0.894564, 0.147014],
- [0.966271, 0.901249, 0.148180],
- [0.964021, 0.907950, 0.149370],
- [0.961681, 0.914672, 0.150520],
- [0.959276, 0.921407, 0.151566],
- [0.956808, 0.928152, 0.152409],
- [0.954287, 0.934908, 0.152921],
- [0.951726, 0.941671, 0.152925],
- [0.949151, 0.948435, 0.152178],
- [0.946602, 0.955190, 0.150328],
- [0.944152, 0.961916, 0.146861],
- [0.941896, 0.968590, 0.140956],
- [0.940015, 0.975158, 0.131326]]
-
-_viridis_data = [[0.267004, 0.004874, 0.329415],
- [0.268510, 0.009605, 0.335427],
- [0.269944, 0.014625, 0.341379],
- [0.271305, 0.019942, 0.347269],
- [0.272594, 0.025563, 0.353093],
- [0.273809, 0.031497, 0.358853],
- [0.274952, 0.037752, 0.364543],
- [0.276022, 0.044167, 0.370164],
- [0.277018, 0.050344, 0.375715],
- [0.277941, 0.056324, 0.381191],
- [0.278791, 0.062145, 0.386592],
- [0.279566, 0.067836, 0.391917],
- [0.280267, 0.073417, 0.397163],
- [0.280894, 0.078907, 0.402329],
- [0.281446, 0.084320, 0.407414],
- [0.281924, 0.089666, 0.412415],
- [0.282327, 0.094955, 0.417331],
- [0.282656, 0.100196, 0.422160],
- [0.282910, 0.105393, 0.426902],
- [0.283091, 0.110553, 0.431554],
- [0.283197, 0.115680, 0.436115],
- [0.283229, 0.120777, 0.440584],
- [0.283187, 0.125848, 0.444960],
- [0.283072, 0.130895, 0.449241],
- [0.282884, 0.135920, 0.453427],
- [0.282623, 0.140926, 0.457517],
- [0.282290, 0.145912, 0.461510],
- [0.281887, 0.150881, 0.465405],
- [0.281412, 0.155834, 0.469201],
- [0.280868, 0.160771, 0.472899],
- [0.280255, 0.165693, 0.476498],
- [0.279574, 0.170599, 0.479997],
- [0.278826, 0.175490, 0.483397],
- [0.278012, 0.180367, 0.486697],
- [0.277134, 0.185228, 0.489898],
- [0.276194, 0.190074, 0.493001],
- [0.275191, 0.194905, 0.496005],
- [0.274128, 0.199721, 0.498911],
- [0.273006, 0.204520, 0.501721],
- [0.271828, 0.209303, 0.504434],
- [0.270595, 0.214069, 0.507052],
- [0.269308, 0.218818, 0.509577],
- [0.267968, 0.223549, 0.512008],
- [0.266580, 0.228262, 0.514349],
- [0.265145, 0.232956, 0.516599],
- [0.263663, 0.237631, 0.518762],
- [0.262138, 0.242286, 0.520837],
- [0.260571, 0.246922, 0.522828],
- [0.258965, 0.251537, 0.524736],
- [0.257322, 0.256130, 0.526563],
- [0.255645, 0.260703, 0.528312],
- [0.253935, 0.265254, 0.529983],
- [0.252194, 0.269783, 0.531579],
- [0.250425, 0.274290, 0.533103],
- [0.248629, 0.278775, 0.534556],
- [0.246811, 0.283237, 0.535941],
- [0.244972, 0.287675, 0.537260],
- [0.243113, 0.292092, 0.538516],
- [0.241237, 0.296485, 0.539709],
- [0.239346, 0.300855, 0.540844],
- [0.237441, 0.305202, 0.541921],
- [0.235526, 0.309527, 0.542944],
- [0.233603, 0.313828, 0.543914],
- [0.231674, 0.318106, 0.544834],
- [0.229739, 0.322361, 0.545706],
- [0.227802, 0.326594, 0.546532],
- [0.225863, 0.330805, 0.547314],
- [0.223925, 0.334994, 0.548053],
- [0.221989, 0.339161, 0.548752],
- [0.220057, 0.343307, 0.549413],
- [0.218130, 0.347432, 0.550038],
- [0.216210, 0.351535, 0.550627],
- [0.214298, 0.355619, 0.551184],
- [0.212395, 0.359683, 0.551710],
- [0.210503, 0.363727, 0.552206],
- [0.208623, 0.367752, 0.552675],
- [0.206756, 0.371758, 0.553117],
- [0.204903, 0.375746, 0.553533],
- [0.203063, 0.379716, 0.553925],
- [0.201239, 0.383670, 0.554294],
- [0.199430, 0.387607, 0.554642],
- [0.197636, 0.391528, 0.554969],
- [0.195860, 0.395433, 0.555276],
- [0.194100, 0.399323, 0.555565],
- [0.192357, 0.403199, 0.555836],
- [0.190631, 0.407061, 0.556089],
- [0.188923, 0.410910, 0.556326],
- [0.187231, 0.414746, 0.556547],
- [0.185556, 0.418570, 0.556753],
- [0.183898, 0.422383, 0.556944],
- [0.182256, 0.426184, 0.557120],
- [0.180629, 0.429975, 0.557282],
- [0.179019, 0.433756, 0.557430],
- [0.177423, 0.437527, 0.557565],
- [0.175841, 0.441290, 0.557685],
- [0.174274, 0.445044, 0.557792],
- [0.172719, 0.448791, 0.557885],
- [0.171176, 0.452530, 0.557965],
- [0.169646, 0.456262, 0.558030],
- [0.168126, 0.459988, 0.558082],
- [0.166617, 0.463708, 0.558119],
- [0.165117, 0.467423, 0.558141],
- [0.163625, 0.471133, 0.558148],
- [0.162142, 0.474838, 0.558140],
- [0.160665, 0.478540, 0.558115],
- [0.159194, 0.482237, 0.558073],
- [0.157729, 0.485932, 0.558013],
- [0.156270, 0.489624, 0.557936],
- [0.154815, 0.493313, 0.557840],
- [0.153364, 0.497000, 0.557724],
- [0.151918, 0.500685, 0.557587],
- [0.150476, 0.504369, 0.557430],
- [0.149039, 0.508051, 0.557250],
- [0.147607, 0.511733, 0.557049],
- [0.146180, 0.515413, 0.556823],
- [0.144759, 0.519093, 0.556572],
- [0.143343, 0.522773, 0.556295],
- [0.141935, 0.526453, 0.555991],
- [0.140536, 0.530132, 0.555659],
- [0.139147, 0.533812, 0.555298],
- [0.137770, 0.537492, 0.554906],
- [0.136408, 0.541173, 0.554483],
- [0.135066, 0.544853, 0.554029],
- [0.133743, 0.548535, 0.553541],
- [0.132444, 0.552216, 0.553018],
- [0.131172, 0.555899, 0.552459],
- [0.129933, 0.559582, 0.551864],
- [0.128729, 0.563265, 0.551229],
- [0.127568, 0.566949, 0.550556],
- [0.126453, 0.570633, 0.549841],
- [0.125394, 0.574318, 0.549086],
- [0.124395, 0.578002, 0.548287],
- [0.123463, 0.581687, 0.547445],
- [0.122606, 0.585371, 0.546557],
- [0.121831, 0.589055, 0.545623],
- [0.121148, 0.592739, 0.544641],
- [0.120565, 0.596422, 0.543611],
- [0.120092, 0.600104, 0.542530],
- [0.119738, 0.603785, 0.541400],
- [0.119512, 0.607464, 0.540218],
- [0.119423, 0.611141, 0.538982],
- [0.119483, 0.614817, 0.537692],
- [0.119699, 0.618490, 0.536347],
- [0.120081, 0.622161, 0.534946],
- [0.120638, 0.625828, 0.533488],
- [0.121380, 0.629492, 0.531973],
- [0.122312, 0.633153, 0.530398],
- [0.123444, 0.636809, 0.528763],
- [0.124780, 0.640461, 0.527068],
- [0.126326, 0.644107, 0.525311],
- [0.128087, 0.647749, 0.523491],
- [0.130067, 0.651384, 0.521608],
- [0.132268, 0.655014, 0.519661],
- [0.134692, 0.658636, 0.517649],
- [0.137339, 0.662252, 0.515571],
- [0.140210, 0.665859, 0.513427],
- [0.143303, 0.669459, 0.511215],
- [0.146616, 0.673050, 0.508936],
- [0.150148, 0.676631, 0.506589],
- [0.153894, 0.680203, 0.504172],
- [0.157851, 0.683765, 0.501686],
- [0.162016, 0.687316, 0.499129],
- [0.166383, 0.690856, 0.496502],
- [0.170948, 0.694384, 0.493803],
- [0.175707, 0.697900, 0.491033],
- [0.180653, 0.701402, 0.488189],
- [0.185783, 0.704891, 0.485273],
- [0.191090, 0.708366, 0.482284],
- [0.196571, 0.711827, 0.479221],
- [0.202219, 0.715272, 0.476084],
- [0.208030, 0.718701, 0.472873],
- [0.214000, 0.722114, 0.469588],
- [0.220124, 0.725509, 0.466226],
- [0.226397, 0.728888, 0.462789],
- [0.232815, 0.732247, 0.459277],
- [0.239374, 0.735588, 0.455688],
- [0.246070, 0.738910, 0.452024],
- [0.252899, 0.742211, 0.448284],
- [0.259857, 0.745492, 0.444467],
- [0.266941, 0.748751, 0.440573],
- [0.274149, 0.751988, 0.436601],
- [0.281477, 0.755203, 0.432552],
- [0.288921, 0.758394, 0.428426],
- [0.296479, 0.761561, 0.424223],
- [0.304148, 0.764704, 0.419943],
- [0.311925, 0.767822, 0.415586],
- [0.319809, 0.770914, 0.411152],
- [0.327796, 0.773980, 0.406640],
- [0.335885, 0.777018, 0.402049],
- [0.344074, 0.780029, 0.397381],
- [0.352360, 0.783011, 0.392636],
- [0.360741, 0.785964, 0.387814],
- [0.369214, 0.788888, 0.382914],
- [0.377779, 0.791781, 0.377939],
- [0.386433, 0.794644, 0.372886],
- [0.395174, 0.797475, 0.367757],
- [0.404001, 0.800275, 0.362552],
- [0.412913, 0.803041, 0.357269],
- [0.421908, 0.805774, 0.351910],
- [0.430983, 0.808473, 0.346476],
- [0.440137, 0.811138, 0.340967],
- [0.449368, 0.813768, 0.335384],
- [0.458674, 0.816363, 0.329727],
- [0.468053, 0.818921, 0.323998],
- [0.477504, 0.821444, 0.318195],
- [0.487026, 0.823929, 0.312321],
- [0.496615, 0.826376, 0.306377],
- [0.506271, 0.828786, 0.300362],
- [0.515992, 0.831158, 0.294279],
- [0.525776, 0.833491, 0.288127],
- [0.535621, 0.835785, 0.281908],
- [0.545524, 0.838039, 0.275626],
- [0.555484, 0.840254, 0.269281],
- [0.565498, 0.842430, 0.262877],
- [0.575563, 0.844566, 0.256415],
- [0.585678, 0.846661, 0.249897],
- [0.595839, 0.848717, 0.243329],
- [0.606045, 0.850733, 0.236712],
- [0.616293, 0.852709, 0.230052],
- [0.626579, 0.854645, 0.223353],
- [0.636902, 0.856542, 0.216620],
- [0.647257, 0.858400, 0.209861],
- [0.657642, 0.860219, 0.203082],
- [0.668054, 0.861999, 0.196293],
- [0.678489, 0.863742, 0.189503],
- [0.688944, 0.865448, 0.182725],
- [0.699415, 0.867117, 0.175971],
- [0.709898, 0.868751, 0.169257],
- [0.720391, 0.870350, 0.162603],
- [0.730889, 0.871916, 0.156029],
- [0.741388, 0.873449, 0.149561],
- [0.751884, 0.874951, 0.143228],
- [0.762373, 0.876424, 0.137064],
- [0.772852, 0.877868, 0.131109],
- [0.783315, 0.879285, 0.125405],
- [0.793760, 0.880678, 0.120005],
- [0.804182, 0.882046, 0.114965],
- [0.814576, 0.883393, 0.110347],
- [0.824940, 0.884720, 0.106217],
- [0.835270, 0.886029, 0.102646],
- [0.845561, 0.887322, 0.099702],
- [0.855810, 0.888601, 0.097452],
- [0.866013, 0.889868, 0.095953],
- [0.876168, 0.891125, 0.095250],
- [0.886271, 0.892374, 0.095374],
- [0.896320, 0.893616, 0.096335],
- [0.906311, 0.894855, 0.098125],
- [0.916242, 0.896091, 0.100717],
- [0.926106, 0.897330, 0.104071],
- [0.935904, 0.898570, 0.108131],
- [0.945636, 0.899815, 0.112838],
- [0.955300, 0.901065, 0.118128],
- [0.964894, 0.902323, 0.123941],
- [0.974417, 0.903590, 0.130215],
- [0.983868, 0.904867, 0.136897],
- [0.993248, 0.906157, 0.143936]]
-
-_cividis_data = [[0.000000, 0.135112, 0.304751],
- [0.000000, 0.138068, 0.311105],
- [0.000000, 0.141013, 0.317579],
- [0.000000, 0.143951, 0.323982],
- [0.000000, 0.146877, 0.330479],
- [0.000000, 0.149791, 0.337065],
- [0.000000, 0.152673, 0.343704],
- [0.000000, 0.155377, 0.350500],
- [0.000000, 0.157932, 0.357521],
- [0.000000, 0.160495, 0.364534],
- [0.000000, 0.163058, 0.371608],
- [0.000000, 0.165621, 0.378769],
- [0.000000, 0.168204, 0.385902],
- [0.000000, 0.170800, 0.393100],
- [0.000000, 0.173420, 0.400353],
- [0.000000, 0.176082, 0.407577],
- [0.000000, 0.178802, 0.414764],
- [0.000000, 0.181610, 0.421859],
- [0.000000, 0.184550, 0.428802],
- [0.000000, 0.186915, 0.435532],
- [0.000000, 0.188769, 0.439563],
- [0.000000, 0.190950, 0.441085],
- [0.000000, 0.193366, 0.441561],
- [0.003602, 0.195911, 0.441564],
- [0.017852, 0.198528, 0.441248],
- [0.032110, 0.201199, 0.440785],
- [0.046205, 0.203903, 0.440196],
- [0.058378, 0.206629, 0.439531],
- [0.068968, 0.209372, 0.438863],
- [0.078624, 0.212122, 0.438105],
- [0.087465, 0.214879, 0.437342],
- [0.095645, 0.217643, 0.436593],
- [0.103401, 0.220406, 0.435790],
- [0.110658, 0.223170, 0.435067],
- [0.117612, 0.225935, 0.434308],
- [0.124291, 0.228697, 0.433547],
- [0.130669, 0.231458, 0.432840],
- [0.136830, 0.234216, 0.432148],
- [0.142852, 0.236972, 0.431404],
- [0.148638, 0.239724, 0.430752],
- [0.154261, 0.242475, 0.430120],
- [0.159733, 0.245221, 0.429528],
- [0.165113, 0.247965, 0.428908],
- [0.170362, 0.250707, 0.428325],
- [0.175490, 0.253444, 0.427790],
- [0.180503, 0.256180, 0.427299],
- [0.185453, 0.258914, 0.426788],
- [0.190303, 0.261644, 0.426329],
- [0.195057, 0.264372, 0.425924],
- [0.199764, 0.267099, 0.425497],
- [0.204385, 0.269823, 0.425126],
- [0.208926, 0.272546, 0.424809],
- [0.213431, 0.275266, 0.424480],
- [0.217863, 0.277985, 0.424206],
- [0.222264, 0.280702, 0.423914],
- [0.226598, 0.283419, 0.423678],
- [0.230871, 0.286134, 0.423498],
- [0.235120, 0.288848, 0.423304],
- [0.239312, 0.291562, 0.423167],
- [0.243485, 0.294274, 0.423014],
- [0.247605, 0.296986, 0.422917],
- [0.251675, 0.299698, 0.422873],
- [0.255731, 0.302409, 0.422814],
- [0.259740, 0.305120, 0.422810],
- [0.263738, 0.307831, 0.422789],
- [0.267693, 0.310542, 0.422821],
- [0.271639, 0.313253, 0.422837],
- [0.275513, 0.315965, 0.422979],
- [0.279411, 0.318677, 0.423031],
- [0.283240, 0.321390, 0.423211],
- [0.287065, 0.324103, 0.423373],
- [0.290884, 0.326816, 0.423517],
- [0.294669, 0.329531, 0.423716],
- [0.298421, 0.332247, 0.423973],
- [0.302169, 0.334963, 0.424213],
- [0.305886, 0.337681, 0.424512],
- [0.309601, 0.340399, 0.424790],
- [0.313287, 0.343120, 0.425120],
- [0.316941, 0.345842, 0.425512],
- [0.320595, 0.348565, 0.425889],
- [0.324250, 0.351289, 0.426250],
- [0.327875, 0.354016, 0.426670],
- [0.331474, 0.356744, 0.427144],
- [0.335073, 0.359474, 0.427605],
- [0.338673, 0.362206, 0.428053],
- [0.342246, 0.364939, 0.428559],
- [0.345793, 0.367676, 0.429127],
- [0.349341, 0.370414, 0.429685],
- [0.352892, 0.373153, 0.430226],
- [0.356418, 0.375896, 0.430823],
- [0.359916, 0.378641, 0.431501],
- [0.363446, 0.381388, 0.432075],
- [0.366923, 0.384139, 0.432796],
- [0.370430, 0.386890, 0.433428],
- [0.373884, 0.389646, 0.434209],
- [0.377371, 0.392404, 0.434890],
- [0.380830, 0.395164, 0.435653],
- [0.384268, 0.397928, 0.436475],
- [0.387705, 0.400694, 0.437305],
- [0.391151, 0.403464, 0.438096],
- [0.394568, 0.406236, 0.438986],
- [0.397991, 0.409011, 0.439848],
- [0.401418, 0.411790, 0.440708],
- [0.404820, 0.414572, 0.441642],
- [0.408226, 0.417357, 0.442570],
- [0.411607, 0.420145, 0.443577],
- [0.414992, 0.422937, 0.444578],
- [0.418383, 0.425733, 0.445560],
- [0.421748, 0.428531, 0.446640],
- [0.425120, 0.431334, 0.447692],
- [0.428462, 0.434140, 0.448864],
- [0.431817, 0.436950, 0.449982],
- [0.435168, 0.439763, 0.451134],
- [0.438504, 0.442580, 0.452341],
- [0.441810, 0.445402, 0.453659],
- [0.445148, 0.448226, 0.454885],
- [0.448447, 0.451053, 0.456264],
- [0.451759, 0.453887, 0.457582],
- [0.455072, 0.456718, 0.458976],
- [0.458366, 0.459552, 0.460457],
- [0.461616, 0.462405, 0.461969],
- [0.464947, 0.465241, 0.463395],
- [0.468254, 0.468083, 0.464908],
- [0.471501, 0.470960, 0.466357],
- [0.474812, 0.473832, 0.467681],
- [0.478186, 0.476699, 0.468845],
- [0.481622, 0.479573, 0.469767],
- [0.485141, 0.482451, 0.470384],
- [0.488697, 0.485318, 0.471008],
- [0.492278, 0.488198, 0.471453],
- [0.495913, 0.491076, 0.471751],
- [0.499552, 0.493960, 0.472032],
- [0.503185, 0.496851, 0.472305],
- [0.506866, 0.499743, 0.472432],
- [0.510540, 0.502643, 0.472550],
- [0.514226, 0.505546, 0.472640],
- [0.517920, 0.508454, 0.472707],
- [0.521643, 0.511367, 0.472639],
- [0.525348, 0.514285, 0.472660],
- [0.529086, 0.517207, 0.472543],
- [0.532829, 0.520135, 0.472401],
- [0.536553, 0.523067, 0.472352],
- [0.540307, 0.526005, 0.472163],
- [0.544069, 0.528948, 0.471947],
- [0.547840, 0.531895, 0.471704],
- [0.551612, 0.534849, 0.471439],
- [0.555393, 0.537807, 0.471147],
- [0.559181, 0.540771, 0.470829],
- [0.562972, 0.543741, 0.470488],
- [0.566802, 0.546715, 0.469988],
- [0.570607, 0.549695, 0.469593],
- [0.574417, 0.552682, 0.469172],
- [0.578236, 0.555673, 0.468724],
- [0.582087, 0.558670, 0.468118],
- [0.585916, 0.561674, 0.467618],
- [0.589753, 0.564682, 0.467090],
- [0.593622, 0.567697, 0.466401],
- [0.597469, 0.570718, 0.465821],
- [0.601354, 0.573743, 0.465074],
- [0.605211, 0.576777, 0.464441],
- [0.609105, 0.579816, 0.463638],
- [0.612977, 0.582861, 0.462950],
- [0.616852, 0.585913, 0.462237],
- [0.620765, 0.588970, 0.461351],
- [0.624654, 0.592034, 0.460583],
- [0.628576, 0.595104, 0.459641],
- [0.632506, 0.598180, 0.458668],
- [0.636412, 0.601264, 0.457818],
- [0.640352, 0.604354, 0.456791],
- [0.644270, 0.607450, 0.455886],
- [0.648222, 0.610553, 0.454801],
- [0.652178, 0.613664, 0.453689],
- [0.656114, 0.616780, 0.452702],
- [0.660082, 0.619904, 0.451534],
- [0.664055, 0.623034, 0.450338],
- [0.668008, 0.626171, 0.449270],
- [0.671991, 0.629316, 0.448018],
- [0.675981, 0.632468, 0.446736],
- [0.679979, 0.635626, 0.445424],
- [0.683950, 0.638793, 0.444251],
- [0.687957, 0.641966, 0.442886],
- [0.691971, 0.645145, 0.441491],
- [0.695985, 0.648334, 0.440072],
- [0.700008, 0.651529, 0.438624],
- [0.704037, 0.654731, 0.437147],
- [0.708067, 0.657942, 0.435647],
- [0.712105, 0.661160, 0.434117],
- [0.716177, 0.664384, 0.432386],
- [0.720222, 0.667618, 0.430805],
- [0.724274, 0.670859, 0.429194],
- [0.728334, 0.674107, 0.427554],
- [0.732422, 0.677364, 0.425717],
- [0.736488, 0.680629, 0.424028],
- [0.740589, 0.683900, 0.422131],
- [0.744664, 0.687181, 0.420393],
- [0.748772, 0.690470, 0.418448],
- [0.752886, 0.693766, 0.416472],
- [0.756975, 0.697071, 0.414659],
- [0.761096, 0.700384, 0.412638],
- [0.765223, 0.703705, 0.410587],
- [0.769353, 0.707035, 0.408516],
- [0.773486, 0.710373, 0.406422],
- [0.777651, 0.713719, 0.404112],
- [0.781795, 0.717074, 0.401966],
- [0.785965, 0.720438, 0.399613],
- [0.790116, 0.723810, 0.397423],
- [0.794298, 0.727190, 0.395016],
- [0.798480, 0.730580, 0.392597],
- [0.802667, 0.733978, 0.390153],
- [0.806859, 0.737385, 0.387684],
- [0.811054, 0.740801, 0.385198],
- [0.815274, 0.744226, 0.382504],
- [0.819499, 0.747659, 0.379785],
- [0.823729, 0.751101, 0.377043],
- [0.827959, 0.754553, 0.374292],
- [0.832192, 0.758014, 0.371529],
- [0.836429, 0.761483, 0.368747],
- [0.840693, 0.764962, 0.365746],
- [0.844957, 0.768450, 0.362741],
- [0.849223, 0.771947, 0.359729],
- [0.853515, 0.775454, 0.356500],
- [0.857809, 0.778969, 0.353259],
- [0.862105, 0.782494, 0.350011],
- [0.866421, 0.786028, 0.346571],
- [0.870717, 0.789572, 0.343333],
- [0.875057, 0.793125, 0.339685],
- [0.879378, 0.796687, 0.336241],
- [0.883720, 0.800258, 0.332599],
- [0.888081, 0.803839, 0.328770],
- [0.892440, 0.807430, 0.324968],
- [0.896818, 0.811030, 0.320982],
- [0.901195, 0.814639, 0.317021],
- [0.905589, 0.818257, 0.312889],
- [0.910000, 0.821885, 0.308594],
- [0.914407, 0.825522, 0.304348],
- [0.918828, 0.829168, 0.299960],
- [0.923279, 0.832822, 0.295244],
- [0.927724, 0.836486, 0.290611],
- [0.932180, 0.840159, 0.285880],
- [0.936660, 0.843841, 0.280876],
- [0.941147, 0.847530, 0.275815],
- [0.945654, 0.851228, 0.270532],
- [0.950178, 0.854933, 0.265085],
- [0.954725, 0.858646, 0.259365],
- [0.959284, 0.862365, 0.253563],
- [0.963872, 0.866089, 0.247445],
- [0.968469, 0.869819, 0.241310],
- [0.973114, 0.873550, 0.234677],
- [0.977780, 0.877281, 0.227954],
- [0.982497, 0.881008, 0.220878],
- [0.987293, 0.884718, 0.213336],
- [0.992218, 0.888385, 0.205468],
- [0.994847, 0.892954, 0.203445],
- [0.995249, 0.898384, 0.207561],
- [0.995503, 0.903866, 0.212370],
- [0.995737, 0.909344, 0.217772]]
-
-cmaps = {}
-for (name, data) in (('magma', _magma_data),
- ('inferno', _inferno_data),
- ('plasma', _plasma_data),
- ('viridis', _viridis_data),
- ('cividis', _cividis_data)):
-
- cmaps[name] = ListedColormap(data, name=name)
- # generate reversed colormap
- name = name + '_r'
- cmaps[name] = ListedColormap(list(reversed(data)), name=name)
diff --git a/contrib/python/matplotlib/py2/matplotlib/_color_data.py b/contrib/python/matplotlib/py2/matplotlib/_color_data.py
deleted file mode 100644
index 774e251d72..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/_color_data.py
+++ /dev/null
@@ -1,1147 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-from collections import OrderedDict
-import six
-
-
-BASE_COLORS = {
- 'b': (0, 0, 1),
- 'g': (0, 0.5, 0),
- 'r': (1, 0, 0),
- 'c': (0, 0.75, 0.75),
- 'm': (0.75, 0, 0.75),
- 'y': (0.75, 0.75, 0),
- 'k': (0, 0, 0),
- 'w': (1, 1, 1)}
-
-
-# These colors are from Tableau
-TABLEAU_COLORS = (
- ('blue', '#1f77b4'),
- ('orange', '#ff7f0e'),
- ('green', '#2ca02c'),
- ('red', '#d62728'),
- ('purple', '#9467bd'),
- ('brown', '#8c564b'),
- ('pink', '#e377c2'),
- ('gray', '#7f7f7f'),
- ('olive', '#bcbd22'),
- ('cyan', '#17becf'),
-)
-
-# Normalize name to "tab:<name>" to avoid name collisions.
-TABLEAU_COLORS = OrderedDict(
- ('tab:' + name, value) for name, value in TABLEAU_COLORS)
-
-# This mapping of color names -> hex values is taken from
-# a survey run by Randel Monroe see:
-# http://blog.xkcd.com/2010/05/03/color-survey-results/
-# for more details. The results are hosted at
-# https://xkcd.com/color/rgb.txt
-#
-# License: http://creativecommons.org/publicdomain/zero/1.0/
-XKCD_COLORS = {
- 'cloudy blue': '#acc2d9',
- 'dark pastel green': '#56ae57',
- 'dust': '#b2996e',
- 'electric lime': '#a8ff04',
- 'fresh green': '#69d84f',
- 'light eggplant': '#894585',
- 'nasty green': '#70b23f',
- 'really light blue': '#d4ffff',
- 'tea': '#65ab7c',
- 'warm purple': '#952e8f',
- 'yellowish tan': '#fcfc81',
- 'cement': '#a5a391',
- 'dark grass green': '#388004',
- 'dusty teal': '#4c9085',
- 'grey teal': '#5e9b8a',
- 'macaroni and cheese': '#efb435',
- 'pinkish tan': '#d99b82',
- 'spruce': '#0a5f38',
- 'strong blue': '#0c06f7',
- 'toxic green': '#61de2a',
- 'windows blue': '#3778bf',
- 'blue blue': '#2242c7',
- 'blue with a hint of purple': '#533cc6',
- 'booger': '#9bb53c',
- 'bright sea green': '#05ffa6',
- 'dark green blue': '#1f6357',
- 'deep turquoise': '#017374',
- 'green teal': '#0cb577',
- 'strong pink': '#ff0789',
- 'bland': '#afa88b',
- 'deep aqua': '#08787f',
- 'lavender pink': '#dd85d7',
- 'light moss green': '#a6c875',
- 'light seafoam green': '#a7ffb5',
- 'olive yellow': '#c2b709',
- 'pig pink': '#e78ea5',
- 'deep lilac': '#966ebd',
- 'desert': '#ccad60',
- 'dusty lavender': '#ac86a8',
- 'purpley grey': '#947e94',
- 'purply': '#983fb2',
- 'candy pink': '#ff63e9',
- 'light pastel green': '#b2fba5',
- 'boring green': '#63b365',
- 'kiwi green': '#8ee53f',
- 'light grey green': '#b7e1a1',
- 'orange pink': '#ff6f52',
- 'tea green': '#bdf8a3',
- 'very light brown': '#d3b683',
- 'egg shell': '#fffcc4',
- 'eggplant purple': '#430541',
- 'powder pink': '#ffb2d0',
- 'reddish grey': '#997570',
- 'baby shit brown': '#ad900d',
- 'liliac': '#c48efd',
- 'stormy blue': '#507b9c',
- 'ugly brown': '#7d7103',
- 'custard': '#fffd78',
- 'darkish pink': '#da467d',
- 'deep brown': '#410200',
- 'greenish beige': '#c9d179',
- 'manilla': '#fffa86',
- 'off blue': '#5684ae',
- 'battleship grey': '#6b7c85',
- 'browny green': '#6f6c0a',
- 'bruise': '#7e4071',
- 'kelley green': '#009337',
- 'sickly yellow': '#d0e429',
- 'sunny yellow': '#fff917',
- 'azul': '#1d5dec',
- 'darkgreen': '#054907',
- 'green/yellow': '#b5ce08',
- 'lichen': '#8fb67b',
- 'light light green': '#c8ffb0',
- 'pale gold': '#fdde6c',
- 'sun yellow': '#ffdf22',
- 'tan green': '#a9be70',
- 'burple': '#6832e3',
- 'butterscotch': '#fdb147',
- 'toupe': '#c7ac7d',
- 'dark cream': '#fff39a',
- 'indian red': '#850e04',
- 'light lavendar': '#efc0fe',
- 'poison green': '#40fd14',
- 'baby puke green': '#b6c406',
- 'bright yellow green': '#9dff00',
- 'charcoal grey': '#3c4142',
- 'squash': '#f2ab15',
- 'cinnamon': '#ac4f06',
- 'light pea green': '#c4fe82',
- 'radioactive green': '#2cfa1f',
- 'raw sienna': '#9a6200',
- 'baby purple': '#ca9bf7',
- 'cocoa': '#875f42',
- 'light royal blue': '#3a2efe',
- 'orangeish': '#fd8d49',
- 'rust brown': '#8b3103',
- 'sand brown': '#cba560',
- 'swamp': '#698339',
- 'tealish green': '#0cdc73',
- 'burnt siena': '#b75203',
- 'camo': '#7f8f4e',
- 'dusk blue': '#26538d',
- 'fern': '#63a950',
- 'old rose': '#c87f89',
- 'pale light green': '#b1fc99',
- 'peachy pink': '#ff9a8a',
- 'rosy pink': '#f6688e',
- 'light bluish green': '#76fda8',
- 'light bright green': '#53fe5c',
- 'light neon green': '#4efd54',
- 'light seafoam': '#a0febf',
- 'tiffany blue': '#7bf2da',
- 'washed out green': '#bcf5a6',
- 'browny orange': '#ca6b02',
- 'nice blue': '#107ab0',
- 'sapphire': '#2138ab',
- 'greyish teal': '#719f91',
- 'orangey yellow': '#fdb915',
- 'parchment': '#fefcaf',
- 'straw': '#fcf679',
- 'very dark brown': '#1d0200',
- 'terracota': '#cb6843',
- 'ugly blue': '#31668a',
- 'clear blue': '#247afd',
- 'creme': '#ffffb6',
- 'foam green': '#90fda9',
- 'grey/green': '#86a17d',
- 'light gold': '#fddc5c',
- 'seafoam blue': '#78d1b6',
- 'topaz': '#13bbaf',
- 'violet pink': '#fb5ffc',
- 'wintergreen': '#20f986',
- 'yellow tan': '#ffe36e',
- 'dark fuchsia': '#9d0759',
- 'indigo blue': '#3a18b1',
- 'light yellowish green': '#c2ff89',
- 'pale magenta': '#d767ad',
- 'rich purple': '#720058',
- 'sunflower yellow': '#ffda03',
- 'green/blue': '#01c08d',
- 'leather': '#ac7434',
- 'racing green': '#014600',
- 'vivid purple': '#9900fa',
- 'dark royal blue': '#02066f',
- 'hazel': '#8e7618',
- 'muted pink': '#d1768f',
- 'booger green': '#96b403',
- 'canary': '#fdff63',
- 'cool grey': '#95a3a6',
- 'dark taupe': '#7f684e',
- 'darkish purple': '#751973',
- 'true green': '#089404',
- 'coral pink': '#ff6163',
- 'dark sage': '#598556',
- 'dark slate blue': '#214761',
- 'flat blue': '#3c73a8',
- 'mushroom': '#ba9e88',
- 'rich blue': '#021bf9',
- 'dirty purple': '#734a65',
- 'greenblue': '#23c48b',
- 'icky green': '#8fae22',
- 'light khaki': '#e6f2a2',
- 'warm blue': '#4b57db',
- 'dark hot pink': '#d90166',
- 'deep sea blue': '#015482',
- 'carmine': '#9d0216',
- 'dark yellow green': '#728f02',
- 'pale peach': '#ffe5ad',
- 'plum purple': '#4e0550',
- 'golden rod': '#f9bc08',
- 'neon red': '#ff073a',
- 'old pink': '#c77986',
- 'very pale blue': '#d6fffe',
- 'blood orange': '#fe4b03',
- 'grapefruit': '#fd5956',
- 'sand yellow': '#fce166',
- 'clay brown': '#b2713d',
- 'dark blue grey': '#1f3b4d',
- 'flat green': '#699d4c',
- 'light green blue': '#56fca2',
- 'warm pink': '#fb5581',
- 'dodger blue': '#3e82fc',
- 'gross green': '#a0bf16',
- 'ice': '#d6fffa',
- 'metallic blue': '#4f738e',
- 'pale salmon': '#ffb19a',
- 'sap green': '#5c8b15',
- 'algae': '#54ac68',
- 'bluey grey': '#89a0b0',
- 'greeny grey': '#7ea07a',
- 'highlighter green': '#1bfc06',
- 'light light blue': '#cafffb',
- 'light mint': '#b6ffbb',
- 'raw umber': '#a75e09',
- 'vivid blue': '#152eff',
- 'deep lavender': '#8d5eb7',
- 'dull teal': '#5f9e8f',
- 'light greenish blue': '#63f7b4',
- 'mud green': '#606602',
- 'pinky': '#fc86aa',
- 'red wine': '#8c0034',
- 'shit green': '#758000',
- 'tan brown': '#ab7e4c',
- 'darkblue': '#030764',
- 'rosa': '#fe86a4',
- 'lipstick': '#d5174e',
- 'pale mauve': '#fed0fc',
- 'claret': '#680018',
- 'dandelion': '#fedf08',
- 'orangered': '#fe420f',
- 'poop green': '#6f7c00',
- 'ruby': '#ca0147',
- 'dark': '#1b2431',
- 'greenish turquoise': '#00fbb0',
- 'pastel red': '#db5856',
- 'piss yellow': '#ddd618',
- 'bright cyan': '#41fdfe',
- 'dark coral': '#cf524e',
- 'algae green': '#21c36f',
- 'darkish red': '#a90308',
- 'reddy brown': '#6e1005',
- 'blush pink': '#fe828c',
- 'camouflage green': '#4b6113',
- 'lawn green': '#4da409',
- 'putty': '#beae8a',
- 'vibrant blue': '#0339f8',
- 'dark sand': '#a88f59',
- 'purple/blue': '#5d21d0',
- 'saffron': '#feb209',
- 'twilight': '#4e518b',
- 'warm brown': '#964e02',
- 'bluegrey': '#85a3b2',
- 'bubble gum pink': '#ff69af',
- 'duck egg blue': '#c3fbf4',
- 'greenish cyan': '#2afeb7',
- 'petrol': '#005f6a',
- 'royal': '#0c1793',
- 'butter': '#ffff81',
- 'dusty orange': '#f0833a',
- 'off yellow': '#f1f33f',
- 'pale olive green': '#b1d27b',
- 'orangish': '#fc824a',
- 'leaf': '#71aa34',
- 'light blue grey': '#b7c9e2',
- 'dried blood': '#4b0101',
- 'lightish purple': '#a552e6',
- 'rusty red': '#af2f0d',
- 'lavender blue': '#8b88f8',
- 'light grass green': '#9af764',
- 'light mint green': '#a6fbb2',
- 'sunflower': '#ffc512',
- 'velvet': '#750851',
- 'brick orange': '#c14a09',
- 'lightish red': '#fe2f4a',
- 'pure blue': '#0203e2',
- 'twilight blue': '#0a437a',
- 'violet red': '#a50055',
- 'yellowy brown': '#ae8b0c',
- 'carnation': '#fd798f',
- 'muddy yellow': '#bfac05',
- 'dark seafoam green': '#3eaf76',
- 'deep rose': '#c74767',
- 'dusty red': '#b9484e',
- 'grey/blue': '#647d8e',
- 'lemon lime': '#bffe28',
- 'purple/pink': '#d725de',
- 'brown yellow': '#b29705',
- 'purple brown': '#673a3f',
- 'wisteria': '#a87dc2',
- 'banana yellow': '#fafe4b',
- 'lipstick red': '#c0022f',
- 'water blue': '#0e87cc',
- 'brown grey': '#8d8468',
- 'vibrant purple': '#ad03de',
- 'baby green': '#8cff9e',
- 'barf green': '#94ac02',
- 'eggshell blue': '#c4fff7',
- 'sandy yellow': '#fdee73',
- 'cool green': '#33b864',
- 'pale': '#fff9d0',
- 'blue/grey': '#758da3',
- 'hot magenta': '#f504c9',
- 'greyblue': '#77a1b5',
- 'purpley': '#8756e4',
- 'baby shit green': '#889717',
- 'brownish pink': '#c27e79',
- 'dark aquamarine': '#017371',
- 'diarrhea': '#9f8303',
- 'light mustard': '#f7d560',
- 'pale sky blue': '#bdf6fe',
- 'turtle green': '#75b84f',
- 'bright olive': '#9cbb04',
- 'dark grey blue': '#29465b',
- 'greeny brown': '#696006',
- 'lemon green': '#adf802',
- 'light periwinkle': '#c1c6fc',
- 'seaweed green': '#35ad6b',
- 'sunshine yellow': '#fffd37',
- 'ugly purple': '#a442a0',
- 'medium pink': '#f36196',
- 'puke brown': '#947706',
- 'very light pink': '#fff4f2',
- 'viridian': '#1e9167',
- 'bile': '#b5c306',
- 'faded yellow': '#feff7f',
- 'very pale green': '#cffdbc',
- 'vibrant green': '#0add08',
- 'bright lime': '#87fd05',
- 'spearmint': '#1ef876',
- 'light aquamarine': '#7bfdc7',
- 'light sage': '#bcecac',
- 'yellowgreen': '#bbf90f',
- 'baby poo': '#ab9004',
- 'dark seafoam': '#1fb57a',
- 'deep teal': '#00555a',
- 'heather': '#a484ac',
- 'rust orange': '#c45508',
- 'dirty blue': '#3f829d',
- 'fern green': '#548d44',
- 'bright lilac': '#c95efb',
- 'weird green': '#3ae57f',
- 'peacock blue': '#016795',
- 'avocado green': '#87a922',
- 'faded orange': '#f0944d',
- 'grape purple': '#5d1451',
- 'hot green': '#25ff29',
- 'lime yellow': '#d0fe1d',
- 'mango': '#ffa62b',
- 'shamrock': '#01b44c',
- 'bubblegum': '#ff6cb5',
- 'purplish brown': '#6b4247',
- 'vomit yellow': '#c7c10c',
- 'pale cyan': '#b7fffa',
- 'key lime': '#aeff6e',
- 'tomato red': '#ec2d01',
- 'lightgreen': '#76ff7b',
- 'merlot': '#730039',
- 'night blue': '#040348',
- 'purpleish pink': '#df4ec8',
- 'apple': '#6ecb3c',
- 'baby poop green': '#8f9805',
- 'green apple': '#5edc1f',
- 'heliotrope': '#d94ff5',
- 'yellow/green': '#c8fd3d',
- 'almost black': '#070d0d',
- 'cool blue': '#4984b8',
- 'leafy green': '#51b73b',
- 'mustard brown': '#ac7e04',
- 'dusk': '#4e5481',
- 'dull brown': '#876e4b',
- 'frog green': '#58bc08',
- 'vivid green': '#2fef10',
- 'bright light green': '#2dfe54',
- 'fluro green': '#0aff02',
- 'kiwi': '#9cef43',
- 'seaweed': '#18d17b',
- 'navy green': '#35530a',
- 'ultramarine blue': '#1805db',
- 'iris': '#6258c4',
- 'pastel orange': '#ff964f',
- 'yellowish orange': '#ffab0f',
- 'perrywinkle': '#8f8ce7',
- 'tealish': '#24bca8',
- 'dark plum': '#3f012c',
- 'pear': '#cbf85f',
- 'pinkish orange': '#ff724c',
- 'midnight purple': '#280137',
- 'light urple': '#b36ff6',
- 'dark mint': '#48c072',
- 'greenish tan': '#bccb7a',
- 'light burgundy': '#a8415b',
- 'turquoise blue': '#06b1c4',
- 'ugly pink': '#cd7584',
- 'sandy': '#f1da7a',
- 'electric pink': '#ff0490',
- 'muted purple': '#805b87',
- 'mid green': '#50a747',
- 'greyish': '#a8a495',
- 'neon yellow': '#cfff04',
- 'banana': '#ffff7e',
- 'carnation pink': '#ff7fa7',
- 'tomato': '#ef4026',
- 'sea': '#3c9992',
- 'muddy brown': '#886806',
- 'turquoise green': '#04f489',
- 'buff': '#fef69e',
- 'fawn': '#cfaf7b',
- 'muted blue': '#3b719f',
- 'pale rose': '#fdc1c5',
- 'dark mint green': '#20c073',
- 'amethyst': '#9b5fc0',
- 'blue/green': '#0f9b8e',
- 'chestnut': '#742802',
- 'sick green': '#9db92c',
- 'pea': '#a4bf20',
- 'rusty orange': '#cd5909',
- 'stone': '#ada587',
- 'rose red': '#be013c',
- 'pale aqua': '#b8ffeb',
- 'deep orange': '#dc4d01',
- 'earth': '#a2653e',
- 'mossy green': '#638b27',
- 'grassy green': '#419c03',
- 'pale lime green': '#b1ff65',
- 'light grey blue': '#9dbcd4',
- 'pale grey': '#fdfdfe',
- 'asparagus': '#77ab56',
- 'blueberry': '#464196',
- 'purple red': '#990147',
- 'pale lime': '#befd73',
- 'greenish teal': '#32bf84',
- 'caramel': '#af6f09',
- 'deep magenta': '#a0025c',
- 'light peach': '#ffd8b1',
- 'milk chocolate': '#7f4e1e',
- 'ocher': '#bf9b0c',
- 'off green': '#6ba353',
- 'purply pink': '#f075e6',
- 'lightblue': '#7bc8f6',
- 'dusky blue': '#475f94',
- 'golden': '#f5bf03',
- 'light beige': '#fffeb6',
- 'butter yellow': '#fffd74',
- 'dusky purple': '#895b7b',
- 'french blue': '#436bad',
- 'ugly yellow': '#d0c101',
- 'greeny yellow': '#c6f808',
- 'orangish red': '#f43605',
- 'shamrock green': '#02c14d',
- 'orangish brown': '#b25f03',
- 'tree green': '#2a7e19',
- 'deep violet': '#490648',
- 'gunmetal': '#536267',
- 'blue/purple': '#5a06ef',
- 'cherry': '#cf0234',
- 'sandy brown': '#c4a661',
- 'warm grey': '#978a84',
- 'dark indigo': '#1f0954',
- 'midnight': '#03012d',
- 'bluey green': '#2bb179',
- 'grey pink': '#c3909b',
- 'soft purple': '#a66fb5',
- 'blood': '#770001',
- 'brown red': '#922b05',
- 'medium grey': '#7d7f7c',
- 'berry': '#990f4b',
- 'poo': '#8f7303',
- 'purpley pink': '#c83cb9',
- 'light salmon': '#fea993',
- 'snot': '#acbb0d',
- 'easter purple': '#c071fe',
- 'light yellow green': '#ccfd7f',
- 'dark navy blue': '#00022e',
- 'drab': '#828344',
- 'light rose': '#ffc5cb',
- 'rouge': '#ab1239',
- 'purplish red': '#b0054b',
- 'slime green': '#99cc04',
- 'baby poop': '#937c00',
- 'irish green': '#019529',
- 'pink/purple': '#ef1de7',
- 'dark navy': '#000435',
- 'greeny blue': '#42b395',
- 'light plum': '#9d5783',
- 'pinkish grey': '#c8aca9',
- 'dirty orange': '#c87606',
- 'rust red': '#aa2704',
- 'pale lilac': '#e4cbff',
- 'orangey red': '#fa4224',
- 'primary blue': '#0804f9',
- 'kermit green': '#5cb200',
- 'brownish purple': '#76424e',
- 'murky green': '#6c7a0e',
- 'wheat': '#fbdd7e',
- 'very dark purple': '#2a0134',
- 'bottle green': '#044a05',
- 'watermelon': '#fd4659',
- 'deep sky blue': '#0d75f8',
- 'fire engine red': '#fe0002',
- 'yellow ochre': '#cb9d06',
- 'pumpkin orange': '#fb7d07',
- 'pale olive': '#b9cc81',
- 'light lilac': '#edc8ff',
- 'lightish green': '#61e160',
- 'carolina blue': '#8ab8fe',
- 'mulberry': '#920a4e',
- 'shocking pink': '#fe02a2',
- 'auburn': '#9a3001',
- 'bright lime green': '#65fe08',
- 'celadon': '#befdb7',
- 'pinkish brown': '#b17261',
- 'poo brown': '#885f01',
- 'bright sky blue': '#02ccfe',
- 'celery': '#c1fd95',
- 'dirt brown': '#836539',
- 'strawberry': '#fb2943',
- 'dark lime': '#84b701',
- 'copper': '#b66325',
- 'medium brown': '#7f5112',
- 'muted green': '#5fa052',
- "robin's egg": '#6dedfd',
- 'bright aqua': '#0bf9ea',
- 'bright lavender': '#c760ff',
- 'ivory': '#ffffcb',
- 'very light purple': '#f6cefc',
- 'light navy': '#155084',
- 'pink red': '#f5054f',
- 'olive brown': '#645403',
- 'poop brown': '#7a5901',
- 'mustard green': '#a8b504',
- 'ocean green': '#3d9973',
- 'very dark blue': '#000133',
- 'dusty green': '#76a973',
- 'light navy blue': '#2e5a88',
- 'minty green': '#0bf77d',
- 'adobe': '#bd6c48',
- 'barney': '#ac1db8',
- 'jade green': '#2baf6a',
- 'bright light blue': '#26f7fd',
- 'light lime': '#aefd6c',
- 'dark khaki': '#9b8f55',
- 'orange yellow': '#ffad01',
- 'ocre': '#c69c04',
- 'maize': '#f4d054',
- 'faded pink': '#de9dac',
- 'british racing green': '#05480d',
- 'sandstone': '#c9ae74',
- 'mud brown': '#60460f',
- 'light sea green': '#98f6b0',
- 'robin egg blue': '#8af1fe',
- 'aqua marine': '#2ee8bb',
- 'dark sea green': '#11875d',
- 'soft pink': '#fdb0c0',
- 'orangey brown': '#b16002',
- 'cherry red': '#f7022a',
- 'burnt yellow': '#d5ab09',
- 'brownish grey': '#86775f',
- 'camel': '#c69f59',
- 'purplish grey': '#7a687f',
- 'marine': '#042e60',
- 'greyish pink': '#c88d94',
- 'pale turquoise': '#a5fbd5',
- 'pastel yellow': '#fffe71',
- 'bluey purple': '#6241c7',
- 'canary yellow': '#fffe40',
- 'faded red': '#d3494e',
- 'sepia': '#985e2b',
- 'coffee': '#a6814c',
- 'bright magenta': '#ff08e8',
- 'mocha': '#9d7651',
- 'ecru': '#feffca',
- 'purpleish': '#98568d',
- 'cranberry': '#9e003a',
- 'darkish green': '#287c37',
- 'brown orange': '#b96902',
- 'dusky rose': '#ba6873',
- 'melon': '#ff7855',
- 'sickly green': '#94b21c',
- 'silver': '#c5c9c7',
- 'purply blue': '#661aee',
- 'purpleish blue': '#6140ef',
- 'hospital green': '#9be5aa',
- 'shit brown': '#7b5804',
- 'mid blue': '#276ab3',
- 'amber': '#feb308',
- 'easter green': '#8cfd7e',
- 'soft blue': '#6488ea',
- 'cerulean blue': '#056eee',
- 'golden brown': '#b27a01',
- 'bright turquoise': '#0ffef9',
- 'red pink': '#fa2a55',
- 'red purple': '#820747',
- 'greyish brown': '#7a6a4f',
- 'vermillion': '#f4320c',
- 'russet': '#a13905',
- 'steel grey': '#6f828a',
- 'lighter purple': '#a55af4',
- 'bright violet': '#ad0afd',
- 'prussian blue': '#004577',
- 'slate green': '#658d6d',
- 'dirty pink': '#ca7b80',
- 'dark blue green': '#005249',
- 'pine': '#2b5d34',
- 'yellowy green': '#bff128',
- 'dark gold': '#b59410',
- 'bluish': '#2976bb',
- 'darkish blue': '#014182',
- 'dull red': '#bb3f3f',
- 'pinky red': '#fc2647',
- 'bronze': '#a87900',
- 'pale teal': '#82cbb2',
- 'military green': '#667c3e',
- 'barbie pink': '#fe46a5',
- 'bubblegum pink': '#fe83cc',
- 'pea soup green': '#94a617',
- 'dark mustard': '#a88905',
- 'shit': '#7f5f00',
- 'medium purple': '#9e43a2',
- 'very dark green': '#062e03',
- 'dirt': '#8a6e45',
- 'dusky pink': '#cc7a8b',
- 'red violet': '#9e0168',
- 'lemon yellow': '#fdff38',
- 'pistachio': '#c0fa8b',
- 'dull yellow': '#eedc5b',
- 'dark lime green': '#7ebd01',
- 'denim blue': '#3b5b92',
- 'teal blue': '#01889f',
- 'lightish blue': '#3d7afd',
- 'purpley blue': '#5f34e7',
- 'light indigo': '#6d5acf',
- 'swamp green': '#748500',
- 'brown green': '#706c11',
- 'dark maroon': '#3c0008',
- 'hot purple': '#cb00f5',
- 'dark forest green': '#002d04',
- 'faded blue': '#658cbb',
- 'drab green': '#749551',
- 'light lime green': '#b9ff66',
- 'snot green': '#9dc100',
- 'yellowish': '#faee66',
- 'light blue green': '#7efbb3',
- 'bordeaux': '#7b002c',
- 'light mauve': '#c292a1',
- 'ocean': '#017b92',
- 'marigold': '#fcc006',
- 'muddy green': '#657432',
- 'dull orange': '#d8863b',
- 'steel': '#738595',
- 'electric purple': '#aa23ff',
- 'fluorescent green': '#08ff08',
- 'yellowish brown': '#9b7a01',
- 'blush': '#f29e8e',
- 'soft green': '#6fc276',
- 'bright orange': '#ff5b00',
- 'lemon': '#fdff52',
- 'purple grey': '#866f85',
- 'acid green': '#8ffe09',
- 'pale lavender': '#eecffe',
- 'violet blue': '#510ac9',
- 'light forest green': '#4f9153',
- 'burnt red': '#9f2305',
- 'khaki green': '#728639',
- 'cerise': '#de0c62',
- 'faded purple': '#916e99',
- 'apricot': '#ffb16d',
- 'dark olive green': '#3c4d03',
- 'grey brown': '#7f7053',
- 'green grey': '#77926f',
- 'true blue': '#010fcc',
- 'pale violet': '#ceaefa',
- 'periwinkle blue': '#8f99fb',
- 'light sky blue': '#c6fcff',
- 'blurple': '#5539cc',
- 'green brown': '#544e03',
- 'bluegreen': '#017a79',
- 'bright teal': '#01f9c6',
- 'brownish yellow': '#c9b003',
- 'pea soup': '#929901',
- 'forest': '#0b5509',
- 'barney purple': '#a00498',
- 'ultramarine': '#2000b1',
- 'purplish': '#94568c',
- 'puke yellow': '#c2be0e',
- 'bluish grey': '#748b97',
- 'dark periwinkle': '#665fd1',
- 'dark lilac': '#9c6da5',
- 'reddish': '#c44240',
- 'light maroon': '#a24857',
- 'dusty purple': '#825f87',
- 'terra cotta': '#c9643b',
- 'avocado': '#90b134',
- 'marine blue': '#01386a',
- 'teal green': '#25a36f',
- 'slate grey': '#59656d',
- 'lighter green': '#75fd63',
- 'electric green': '#21fc0d',
- 'dusty blue': '#5a86ad',
- 'golden yellow': '#fec615',
- 'bright yellow': '#fffd01',
- 'light lavender': '#dfc5fe',
- 'umber': '#b26400',
- 'poop': '#7f5e00',
- 'dark peach': '#de7e5d',
- 'jungle green': '#048243',
- 'eggshell': '#ffffd4',
- 'denim': '#3b638c',
- 'yellow brown': '#b79400',
- 'dull purple': '#84597e',
- 'chocolate brown': '#411900',
- 'wine red': '#7b0323',
- 'neon blue': '#04d9ff',
- 'dirty green': '#667e2c',
- 'light tan': '#fbeeac',
- 'ice blue': '#d7fffe',
- 'cadet blue': '#4e7496',
- 'dark mauve': '#874c62',
- 'very light blue': '#d5ffff',
- 'grey purple': '#826d8c',
- 'pastel pink': '#ffbacd',
- 'very light green': '#d1ffbd',
- 'dark sky blue': '#448ee4',
- 'evergreen': '#05472a',
- 'dull pink': '#d5869d',
- 'aubergine': '#3d0734',
- 'mahogany': '#4a0100',
- 'reddish orange': '#f8481c',
- 'deep green': '#02590f',
- 'vomit green': '#89a203',
- 'purple pink': '#e03fd8',
- 'dusty pink': '#d58a94',
- 'faded green': '#7bb274',
- 'camo green': '#526525',
- 'pinky purple': '#c94cbe',
- 'pink purple': '#db4bda',
- 'brownish red': '#9e3623',
- 'dark rose': '#b5485d',
- 'mud': '#735c12',
- 'brownish': '#9c6d57',
- 'emerald green': '#028f1e',
- 'pale brown': '#b1916e',
- 'dull blue': '#49759c',
- 'burnt umber': '#a0450e',
- 'medium green': '#39ad48',
- 'clay': '#b66a50',
- 'light aqua': '#8cffdb',
- 'light olive green': '#a4be5c',
- 'brownish orange': '#cb7723',
- 'dark aqua': '#05696b',
- 'purplish pink': '#ce5dae',
- 'dark salmon': '#c85a53',
- 'greenish grey': '#96ae8d',
- 'jade': '#1fa774',
- 'ugly green': '#7a9703',
- 'dark beige': '#ac9362',
- 'emerald': '#01a049',
- 'pale red': '#d9544d',
- 'light magenta': '#fa5ff7',
- 'sky': '#82cafc',
- 'light cyan': '#acfffc',
- 'yellow orange': '#fcb001',
- 'reddish purple': '#910951',
- 'reddish pink': '#fe2c54',
- 'orchid': '#c875c4',
- 'dirty yellow': '#cdc50a',
- 'orange red': '#fd411e',
- 'deep red': '#9a0200',
- 'orange brown': '#be6400',
- 'cobalt blue': '#030aa7',
- 'neon pink': '#fe019a',
- 'rose pink': '#f7879a',
- 'greyish purple': '#887191',
- 'raspberry': '#b00149',
- 'aqua green': '#12e193',
- 'salmon pink': '#fe7b7c',
- 'tangerine': '#ff9408',
- 'brownish green': '#6a6e09',
- 'red brown': '#8b2e16',
- 'greenish brown': '#696112',
- 'pumpkin': '#e17701',
- 'pine green': '#0a481e',
- 'charcoal': '#343837',
- 'baby pink': '#ffb7ce',
- 'cornflower': '#6a79f7',
- 'blue violet': '#5d06e9',
- 'chocolate': '#3d1c02',
- 'greyish green': '#82a67d',
- 'scarlet': '#be0119',
- 'green yellow': '#c9ff27',
- 'dark olive': '#373e02',
- 'sienna': '#a9561e',
- 'pastel purple': '#caa0ff',
- 'terracotta': '#ca6641',
- 'aqua blue': '#02d8e9',
- 'sage green': '#88b378',
- 'blood red': '#980002',
- 'deep pink': '#cb0162',
- 'grass': '#5cac2d',
- 'moss': '#769958',
- 'pastel blue': '#a2bffe',
- 'bluish green': '#10a674',
- 'green blue': '#06b48b',
- 'dark tan': '#af884a',
- 'greenish blue': '#0b8b87',
- 'pale orange': '#ffa756',
- 'vomit': '#a2a415',
- 'forrest green': '#154406',
- 'dark lavender': '#856798',
- 'dark violet': '#34013f',
- 'purple blue': '#632de9',
- 'dark cyan': '#0a888a',
- 'olive drab': '#6f7632',
- 'pinkish': '#d46a7e',
- 'cobalt': '#1e488f',
- 'neon purple': '#bc13fe',
- 'light turquoise': '#7ef4cc',
- 'apple green': '#76cd26',
- 'dull green': '#74a662',
- 'wine': '#80013f',
- 'powder blue': '#b1d1fc',
- 'off white': '#ffffe4',
- 'electric blue': '#0652ff',
- 'dark turquoise': '#045c5a',
- 'blue purple': '#5729ce',
- 'azure': '#069af3',
- 'bright red': '#ff000d',
- 'pinkish red': '#f10c45',
- 'cornflower blue': '#5170d7',
- 'light olive': '#acbf69',
- 'grape': '#6c3461',
- 'greyish blue': '#5e819d',
- 'purplish blue': '#601ef9',
- 'yellowish green': '#b0dd16',
- 'greenish yellow': '#cdfd02',
- 'medium blue': '#2c6fbb',
- 'dusty rose': '#c0737a',
- 'light violet': '#d6b4fc',
- 'midnight blue': '#020035',
- 'bluish purple': '#703be7',
- 'red orange': '#fd3c06',
- 'dark magenta': '#960056',
- 'greenish': '#40a368',
- 'ocean blue': '#03719c',
- 'coral': '#fc5a50',
- 'cream': '#ffffc2',
- 'reddish brown': '#7f2b0a',
- 'burnt sienna': '#b04e0f',
- 'brick': '#a03623',
- 'sage': '#87ae73',
- 'grey green': '#789b73',
- 'white': '#ffffff',
- "robin's egg blue": '#98eff9',
- 'moss green': '#658b38',
- 'steel blue': '#5a7d9a',
- 'eggplant': '#380835',
- 'light yellow': '#fffe7a',
- 'leaf green': '#5ca904',
- 'light grey': '#d8dcd6',
- 'puke': '#a5a502',
- 'pinkish purple': '#d648d7',
- 'sea blue': '#047495',
- 'pale purple': '#b790d4',
- 'slate blue': '#5b7c99',
- 'blue grey': '#607c8e',
- 'hunter green': '#0b4008',
- 'fuchsia': '#ed0dd9',
- 'crimson': '#8c000f',
- 'pale yellow': '#ffff84',
- 'ochre': '#bf9005',
- 'mustard yellow': '#d2bd0a',
- 'light red': '#ff474c',
- 'cerulean': '#0485d1',
- 'pale pink': '#ffcfdc',
- 'deep blue': '#040273',
- 'rust': '#a83c09',
- 'light teal': '#90e4c1',
- 'slate': '#516572',
- 'goldenrod': '#fac205',
- 'dark yellow': '#d5b60a',
- 'dark grey': '#363737',
- 'army green': '#4b5d16',
- 'grey blue': '#6b8ba4',
- 'seafoam': '#80f9ad',
- 'puce': '#a57e52',
- 'spring green': '#a9f971',
- 'dark orange': '#c65102',
- 'sand': '#e2ca76',
- 'pastel green': '#b0ff9d',
- 'mint': '#9ffeb0',
- 'light orange': '#fdaa48',
- 'bright pink': '#fe01b1',
- 'chartreuse': '#c1f80a',
- 'deep purple': '#36013f',
- 'dark brown': '#341c02',
- 'taupe': '#b9a281',
- 'pea green': '#8eab12',
- 'puke green': '#9aae07',
- 'kelly green': '#02ab2e',
- 'seafoam green': '#7af9ab',
- 'blue green': '#137e6d',
- 'khaki': '#aaa662',
- 'burgundy': '#610023',
- 'dark teal': '#014d4e',
- 'brick red': '#8f1402',
- 'royal purple': '#4b006e',
- 'plum': '#580f41',
- 'mint green': '#8fff9f',
- 'gold': '#dbb40c',
- 'baby blue': '#a2cffe',
- 'yellow green': '#c0fb2d',
- 'bright purple': '#be03fd',
- 'dark red': '#840000',
- 'pale blue': '#d0fefe',
- 'grass green': '#3f9b0b',
- 'navy': '#01153e',
- 'aquamarine': '#04d8b2',
- 'burnt orange': '#c04e01',
- 'neon green': '#0cff0c',
- 'bright blue': '#0165fc',
- 'rose': '#cf6275',
- 'light pink': '#ffd1df',
- 'mustard': '#ceb301',
- 'indigo': '#380282',
- 'lime': '#aaff32',
- 'sea green': '#53fca1',
- 'periwinkle': '#8e82fe',
- 'dark pink': '#cb416b',
- 'olive green': '#677a04',
- 'peach': '#ffb07c',
- 'pale green': '#c7fdb5',
- 'light brown': '#ad8150',
- 'hot pink': '#ff028d',
- 'black': '#000000',
- 'lilac': '#cea2fd',
- 'navy blue': '#001146',
- 'royal blue': '#0504aa',
- 'beige': '#e6daa6',
- 'salmon': '#ff796c',
- 'olive': '#6e750e',
- 'maroon': '#650021',
- 'bright green': '#01ff07',
- 'dark purple': '#35063e',
- 'mauve': '#ae7181',
- 'forest green': '#06470c',
- 'aqua': '#13eac9',
- 'cyan': '#00ffff',
- 'tan': '#d1b26f',
- 'dark blue': '#00035b',
- 'lavender': '#c79fef',
- 'turquoise': '#06c2ac',
- 'dark green': '#033500',
- 'violet': '#9a0eea',
- 'light purple': '#bf77f6',
- 'lime green': '#89fe05',
- 'grey': '#929591',
- 'sky blue': '#75bbfd',
- 'yellow': '#ffff14',
- 'magenta': '#c20078',
- 'light green': '#96f97b',
- 'orange': '#f97306',
- 'teal': '#029386',
- 'light blue': '#95d0fc',
- 'red': '#e50000',
- 'brown': '#653700',
- 'pink': '#ff81c0',
- 'blue': '#0343df',
- 'green': '#15b01a',
- 'purple': '#7e1e9c'}
-
-# Normalize name to "xkcd:<name>" to avoid name collisions.
-XKCD_COLORS = {'xkcd:' + name: value for name, value in XKCD_COLORS.items()}
-
-
-# https://drafts.csswg.org/css-color-4/#named-colors
-CSS4_COLORS = {
- 'aliceblue': '#F0F8FF',
- 'antiquewhite': '#FAEBD7',
- 'aqua': '#00FFFF',
- 'aquamarine': '#7FFFD4',
- 'azure': '#F0FFFF',
- 'beige': '#F5F5DC',
- 'bisque': '#FFE4C4',
- 'black': '#000000',
- 'blanchedalmond': '#FFEBCD',
- 'blue': '#0000FF',
- 'blueviolet': '#8A2BE2',
- 'brown': '#A52A2A',
- 'burlywood': '#DEB887',
- 'cadetblue': '#5F9EA0',
- 'chartreuse': '#7FFF00',
- 'chocolate': '#D2691E',
- 'coral': '#FF7F50',
- 'cornflowerblue': '#6495ED',
- 'cornsilk': '#FFF8DC',
- 'crimson': '#DC143C',
- 'cyan': '#00FFFF',
- 'darkblue': '#00008B',
- 'darkcyan': '#008B8B',
- 'darkgoldenrod': '#B8860B',
- 'darkgray': '#A9A9A9',
- 'darkgreen': '#006400',
- 'darkgrey': '#A9A9A9',
- 'darkkhaki': '#BDB76B',
- 'darkmagenta': '#8B008B',
- 'darkolivegreen': '#556B2F',
- 'darkorange': '#FF8C00',
- 'darkorchid': '#9932CC',
- 'darkred': '#8B0000',
- 'darksalmon': '#E9967A',
- 'darkseagreen': '#8FBC8F',
- 'darkslateblue': '#483D8B',
- 'darkslategray': '#2F4F4F',
- 'darkslategrey': '#2F4F4F',
- 'darkturquoise': '#00CED1',
- 'darkviolet': '#9400D3',
- 'deeppink': '#FF1493',
- 'deepskyblue': '#00BFFF',
- 'dimgray': '#696969',
- 'dimgrey': '#696969',
- 'dodgerblue': '#1E90FF',
- 'firebrick': '#B22222',
- 'floralwhite': '#FFFAF0',
- 'forestgreen': '#228B22',
- 'fuchsia': '#FF00FF',
- 'gainsboro': '#DCDCDC',
- 'ghostwhite': '#F8F8FF',
- 'gold': '#FFD700',
- 'goldenrod': '#DAA520',
- 'gray': '#808080',
- 'green': '#008000',
- 'greenyellow': '#ADFF2F',
- 'grey': '#808080',
- 'honeydew': '#F0FFF0',
- 'hotpink': '#FF69B4',
- 'indianred': '#CD5C5C',
- 'indigo': '#4B0082',
- 'ivory': '#FFFFF0',
- 'khaki': '#F0E68C',
- 'lavender': '#E6E6FA',
- 'lavenderblush': '#FFF0F5',
- 'lawngreen': '#7CFC00',
- 'lemonchiffon': '#FFFACD',
- 'lightblue': '#ADD8E6',
- 'lightcoral': '#F08080',
- 'lightcyan': '#E0FFFF',
- 'lightgoldenrodyellow': '#FAFAD2',
- 'lightgray': '#D3D3D3',
- 'lightgreen': '#90EE90',
- 'lightgrey': '#D3D3D3',
- 'lightpink': '#FFB6C1',
- 'lightsalmon': '#FFA07A',
- 'lightseagreen': '#20B2AA',
- 'lightskyblue': '#87CEFA',
- 'lightslategray': '#778899',
- 'lightslategrey': '#778899',
- 'lightsteelblue': '#B0C4DE',
- 'lightyellow': '#FFFFE0',
- 'lime': '#00FF00',
- 'limegreen': '#32CD32',
- 'linen': '#FAF0E6',
- 'magenta': '#FF00FF',
- 'maroon': '#800000',
- 'mediumaquamarine': '#66CDAA',
- 'mediumblue': '#0000CD',
- 'mediumorchid': '#BA55D3',
- 'mediumpurple': '#9370DB',
- 'mediumseagreen': '#3CB371',
- 'mediumslateblue': '#7B68EE',
- 'mediumspringgreen': '#00FA9A',
- 'mediumturquoise': '#48D1CC',
- 'mediumvioletred': '#C71585',
- 'midnightblue': '#191970',
- 'mintcream': '#F5FFFA',
- 'mistyrose': '#FFE4E1',
- 'moccasin': '#FFE4B5',
- 'navajowhite': '#FFDEAD',
- 'navy': '#000080',
- 'oldlace': '#FDF5E6',
- 'olive': '#808000',
- 'olivedrab': '#6B8E23',
- 'orange': '#FFA500',
- 'orangered': '#FF4500',
- 'orchid': '#DA70D6',
- 'palegoldenrod': '#EEE8AA',
- 'palegreen': '#98FB98',
- 'paleturquoise': '#AFEEEE',
- 'palevioletred': '#DB7093',
- 'papayawhip': '#FFEFD5',
- 'peachpuff': '#FFDAB9',
- 'peru': '#CD853F',
- 'pink': '#FFC0CB',
- 'plum': '#DDA0DD',
- 'powderblue': '#B0E0E6',
- 'purple': '#800080',
- 'rebeccapurple': '#663399',
- 'red': '#FF0000',
- 'rosybrown': '#BC8F8F',
- 'royalblue': '#4169E1',
- 'saddlebrown': '#8B4513',
- 'salmon': '#FA8072',
- 'sandybrown': '#F4A460',
- 'seagreen': '#2E8B57',
- 'seashell': '#FFF5EE',
- 'sienna': '#A0522D',
- 'silver': '#C0C0C0',
- 'skyblue': '#87CEEB',
- 'slateblue': '#6A5ACD',
- 'slategray': '#708090',
- 'slategrey': '#708090',
- 'snow': '#FFFAFA',
- 'springgreen': '#00FF7F',
- 'steelblue': '#4682B4',
- 'tan': '#D2B48C',
- 'teal': '#008080',
- 'thistle': '#D8BFD8',
- 'tomato': '#FF6347',
- 'turquoise': '#40E0D0',
- 'violet': '#EE82EE',
- 'wheat': '#F5DEB3',
- 'white': '#FFFFFF',
- 'whitesmoke': '#F5F5F5',
- 'yellow': '#FFFF00',
- 'yellowgreen': '#9ACD32'}
diff --git a/contrib/python/matplotlib/py2/matplotlib/_constrained_layout.py b/contrib/python/matplotlib/py2/matplotlib/_constrained_layout.py
deleted file mode 100644
index b8325f5d63..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/_constrained_layout.py
+++ /dev/null
@@ -1,666 +0,0 @@
-"""
-This module provides the routine to adjust subplot layouts so that there are
-no overlapping axes or axes decorations. All axes decorations are dealt with
-(labels, ticks, titles, ticklabels) and some dependent artists are also dealt
-with (colorbar, suptitle, legend).
-
-Layout is done via :meth:`~matplotlib.gridspec`, with one constraint per
-gridspec, so it is possible to have overlapping axes if the gridspecs
-overlap (i.e. using :meth:`~matplotlib.gridspec.GridSpecFromSubplotSpec`).
-Axes placed using ``figure.subplots()`` or ``figure.add_subplots()`` will
-participate in the layout. Axes manually placed via ``figure.add_axes()``
-will not.
-
-See Tutorial: :doc:`/tutorials/intermediate/constrainedlayout_guide`
-
-"""
-
-# Development Notes:
-
-# What gets a layoutbox:
-# - figure
-# - gridspec
-# - subplotspec
-# EITHER:
-# - axes + pos for the axes (i.e. the total area taken by axis and
-# the actual "position" argument that needs to be sent to
-# ax.set_position.)
-# - The axes layout box will also encomapss the legend, and that is
-# how legends get included (axes legeneds, not figure legends)
-# - colorbars are sibblings of the axes if they are single-axes
-# colorbars
-# OR:
-# - a gridspec can be inside a subplotspec.
-# - subplotspec
-# EITHER:
-# - axes...
-# OR:
-# - gridspec... with arbitrary nesting...
-# - colorbars are siblings of the subplotspecs if they are multi-axes
-# colorbars.
-# - suptitle:
-# - right now suptitles are just stacked atop everything else in figure.
-# Could imagine suptitles being gridspec suptitles, but not implimented
-#
-# Todo: AnchoredOffsetbox connected to gridspecs or axes. This would
-# be more general way to add extra-axes annotations.
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import numpy as np
-import logging
-import warnings
-
-from matplotlib.legend import Legend
-import matplotlib.transforms as transforms
-import matplotlib._layoutbox as layoutbox
-
-_log = logging.getLogger(__name__)
-
-
-def get_axall_tightbbox(ax, renderer):
- '''
- Get the tight_bbox of the axis ax, and any dependent decorations, like
- a `Legend` instance.
- '''
-
- # main bbox of the axis....
- bbox = ax.get_tightbbox(renderer=renderer)
- # now add the possibility of the legend...
- for child in ax.get_children():
- if isinstance(child, Legend):
- bboxn = child._legend_box.get_window_extent(renderer)
- bbox = transforms.Bbox.union([bbox, bboxn])
- # add other children here....
- return bbox
-
-
-def in_same_column(colnum0min, colnum0max, colnumCmin, colnumCmax):
- if colnum0min >= colnumCmin and colnum0min <= colnumCmax:
- return True
- if colnum0max >= colnumCmin and colnum0max <= colnumCmax:
- return True
- return False
-
-
-def in_same_row(rownum0min, rownum0max, rownumCmin, rownumCmax):
- if rownum0min >= rownumCmin and rownum0min <= rownumCmax:
- return True
- if rownum0max >= rownumCmin and rownum0max <= rownumCmax:
- return True
- return False
-
-
-######################################################
-def do_constrained_layout(fig, renderer, h_pad, w_pad,
- hspace=None, wspace=None):
-
- """
- Do the constrained_layout. Called at draw time in
- ``figure.constrained_layout()``
-
- Parameters
- ----------
-
-
- fig: Figure
- is the ``figure`` instance to do the layout in.
-
- renderer: Renderer
- the renderer to use.
-
- h_pad, w_pad : float
- are in figure-normalized units, and are a padding around the axes
- elements.
-
- hspace, wspace : float
- are in fractions of the subplot sizes.
-
- """
-
- ''' Steps:
-
- 1. get a list of unique gridspecs in this figure. Each gridspec will be
- constrained separately.
- 2. Check for gaps in the gridspecs. i.e. if not every axes slot in the
- gridspec has been filled. If empty, add a ghost axis that is made so
- that it cannot be seen (though visible=True). This is needed to make
- a blank spot in the layout.
- 3. Compare the tight_bbox of each axes to its `position`, and assume that
- the difference is the space needed by the elements around the edge of
- the axes (decorations) like the title, ticklabels, x-labels, etc. This
- can include legends who overspill the axes boundaries.
- 4. Constrain gridspec elements to line up:
- a) if colnum0 neq colnumC, the two subplotspecs are stacked next to
- each other, with the appropriate order.
- b) if colnum0 == columnC line up the left or right side of the
- _poslayoutbox (depending if it is the min or max num that is equal).
- c) do the same for rows...
- 5. The above doesn't constrain relative sizes of the _poslayoutboxes at
- all, and indeed zero-size is a solution that the solver often finds more
- convenient than expanding the sizes. Right now the solution is to compare
- subplotspec sizes (i.e. drowsC and drows0) and constrain the larger
- _poslayoutbox to be larger than the ratio of the sizes. i.e. if drows0 >
- drowsC, then ax._poslayoutbox > axc._poslayoutbox * drowsC / drows0. This
- works fine *if* the decorations are similar between the axes. If the
- larger subplotspec has much larger axes decorations, then the constraint
- above is incorrect.
-
- We need the greater than in the above, in general, rather than an equals
- sign. Consider the case of the left column having 2 rows, and the right
- column having 1 row. We want the top and bottom of the _poslayoutboxes to
- line up. So that means if there are decorations on the left column axes
- they will be smaller than half as large as the right hand axis.
-
- This can break down if the decoration size for the right hand axis (the
- margins) is very large. There must be a math way to check for this case.
-
- '''
-
- invTransFig = fig.transFigure.inverted().transform_bbox
-
- # list of unique gridspecs that contain child axes:
- gss = set([])
- for ax in fig.axes:
- if hasattr(ax, 'get_subplotspec'):
- gs = ax.get_subplotspec().get_gridspec()
- if gs._layoutbox is not None:
- gss.add(gs)
- if len(gss) == 0:
- warnings.warn('There are no gridspecs with layoutboxes. '
- 'Possibly did not call parent GridSpec with the figure= '
- 'keyword')
-
- # check for unoccupied gridspec slots and make ghost axes for these
- # slots... Do for each gs separately. This is a pretty big kludge
- # but shoudn't have too much ill effect. The worst is that
- # someone querrying the figure will wonder why there are more
- # axes than they thought.
- if fig._layoutbox.constrained_layout_called < 1:
- for gs in gss:
- nrows, ncols = gs.get_geometry()
- hassubplotspec = np.zeros(nrows * ncols, dtype=bool)
- axs = []
- for ax in fig.axes:
- if (hasattr(ax, 'get_subplotspec')
- and ax._layoutbox is not None
- and ax.get_subplotspec().get_gridspec() == gs):
- axs += [ax]
- for ax in axs:
- ss0 = ax.get_subplotspec()
- if ss0.num2 is None:
- ss0.num2 = ss0.num1
- hassubplotspec[ss0.num1:(ss0.num2 + 1)] = True
- for nn, hss in enumerate(hassubplotspec):
- if not hss:
- # this gridspec slot doesn't have an axis so we
- # make a "ghost".
- ax = fig.add_subplot(gs[nn])
- ax.set_frame_on(False)
- ax.set_xticks([])
- ax.set_yticks([])
- ax.set_facecolor((1, 0, 0, 0))
-
- # for each axes, make a margin between the *pos* layoutbox and the
- # *axes* layoutbox be a minimum size that can accomodate the
- # decorations on the axis.
- for ax in fig.axes:
- _log.debug(ax._layoutbox)
- if ax._layoutbox is not None:
- pos = ax.get_position(original=True)
- tightbbox = get_axall_tightbbox(ax, renderer)
- bbox = invTransFig(tightbbox)
- # use stored h_pad if it exists
- h_padt = ax._poslayoutbox.h_pad
- if h_padt is None:
- h_padt = h_pad
- w_padt = ax._poslayoutbox.w_pad
- if w_padt is None:
- w_padt = w_pad
- ax._poslayoutbox.edit_left_margin_min(-bbox.x0 +
- pos.x0 + w_padt)
- ax._poslayoutbox.edit_right_margin_min(bbox.x1 -
- pos.x1 + w_padt)
- ax._poslayoutbox.edit_bottom_margin_min(
- -bbox.y0 + pos.y0 + h_padt)
- ax._poslayoutbox.edit_top_margin_min(bbox.y1-pos.y1+h_padt)
- _log.debug('left %f', (-bbox.x0 + pos.x0 + w_pad))
- _log.debug('right %f', (bbox.x1 - pos.x1 + w_pad))
- _log.debug('bottom %f', (-bbox.y0 + pos.y0 + h_padt))
- # Sometimes its possible for the solver to collapse
- # rather than expand axes, so they all have zero height
- # or width. This stops that... It *should* have been
- # taken into account w/ pref_width...
- if fig._layoutbox.constrained_layout_called < 1:
- ax._poslayoutbox.constrain_height_min(20, strength='weak')
- ax._poslayoutbox.constrain_width_min(20, strength='weak')
- ax._layoutbox.constrain_height_min(20, strength='weak')
- ax._layoutbox.constrain_width_min(20, strength='weak')
- ax._poslayoutbox.constrain_top_margin(0, strength='weak')
- ax._poslayoutbox.constrain_bottom_margin(0,
- strength='weak')
- ax._poslayoutbox.constrain_right_margin(0, strength='weak')
- ax._poslayoutbox.constrain_left_margin(0, strength='weak')
-
- # do layout for suptitle.
- if fig._suptitle is not None and fig._suptitle._layoutbox is not None:
- sup = fig._suptitle
- bbox = invTransFig(sup.get_window_extent(renderer=renderer))
- height = bbox.y1 - bbox.y0
- sup._layoutbox.edit_height(height+h_pad)
-
- # OK, the above lines up ax._poslayoutbox with ax._layoutbox
- # now we need to
- # 1) arrange the subplotspecs. We do it at this level because
- # the subplotspecs are meant to contain other dependent axes
- # like colorbars or legends.
- # 2) line up the right and left side of the ax._poslayoutbox
- # that have the same subplotspec maxes.
-
- if fig._layoutbox.constrained_layout_called < 1:
-
- # arrange the subplotspecs... This is all done relative to each
- # other. Some subplotspecs conatain axes, and others contain gridspecs
- # the ones that contain gridspecs are a set proportion of their
- # parent gridspec. The ones that contain axes are not so constrained.
- figlb = fig._layoutbox
- for child in figlb.children:
- if child._is_gridspec_layoutbox():
- # farm the gridspec layout out.
- #
- # This routine makes all the subplot spec containers
- # have the correct arrangement. It just stacks the
- # subplot layoutboxes in the correct order...
- _arange_subplotspecs(child, hspace=hspace, wspace=wspace)
-
- # - Align right/left and bottom/top spines of appropriate subplots.
- # - Compare size of subplotspec including height and width ratios
- # and make sure that the axes spines are at least as large
- # as they should be.
- for gs in gss:
- # for each gridspec...
- nrows, ncols = gs.get_geometry()
- width_ratios = gs.get_width_ratios()
- height_ratios = gs.get_height_ratios()
- if width_ratios is None:
- width_ratios = np.ones(ncols)
- if height_ratios is None:
- height_ratios = np.ones(nrows)
-
- # get axes in this gridspec....
- axs = []
- for ax in fig.axes:
- if (hasattr(ax, 'get_subplotspec')
- and ax._layoutbox is not None):
- if ax.get_subplotspec().get_gridspec() == gs:
- axs += [ax]
- rownummin = np.zeros(len(axs), dtype=np.int8)
- rownummax = np.zeros(len(axs), dtype=np.int8)
- colnummin = np.zeros(len(axs), dtype=np.int8)
- colnummax = np.zeros(len(axs), dtype=np.int8)
- width = np.zeros(len(axs))
- height = np.zeros(len(axs))
-
- for n, ax in enumerate(axs):
- ss0 = ax.get_subplotspec()
- if ss0.num2 is None:
- ss0.num2 = ss0.num1
- rownummin[n], colnummin[n] = divmod(ss0.num1, ncols)
- rownummax[n], colnummax[n] = divmod(ss0.num2, ncols)
- width[n] = np.sum(
- width_ratios[colnummin[n]:(colnummax[n] + 1)])
- height[n] = np.sum(
- height_ratios[rownummin[n]:(rownummax[n] + 1)])
-
- for nn, ax in enumerate(axs[:-1]):
- ss0 = ax.get_subplotspec()
-
- # now compare ax to all the axs:
- #
- # If the subplotspecs have the same colnumXmax, then line
- # up their right sides. If they have the same min, then
- # line up their left sides (and vertical equivalents).
- rownum0min, colnum0min = rownummin[nn], colnummin[nn]
- rownum0max, colnum0max = rownummax[nn], colnummax[nn]
- width0, height0 = width[nn], height[nn]
- alignleft = False
- alignright = False
- alignbot = False
- aligntop = False
- alignheight = False
- alignwidth = False
- for mm in range(nn+1, len(axs)):
- axc = axs[mm]
- rownumCmin, colnumCmin = rownummin[mm], colnummin[mm]
- rownumCmax, colnumCmax = rownummax[mm], colnummax[mm]
- widthC, heightC = width[mm], height[mm]
- # Horizontally align axes spines if they have the
- # same min or max:
- if not alignleft and colnum0min == colnumCmin:
- # we want the _poslayoutboxes to line up on left
- # side of the axes spines...
- layoutbox.align([ax._poslayoutbox,
- axc._poslayoutbox],
- 'left')
- alignleft = True
-
- if not alignright and colnum0max == colnumCmax:
- # line up right sides of _poslayoutbox
- layoutbox.align([ax._poslayoutbox,
- axc._poslayoutbox],
- 'right')
- alignright = True
- # Vertically align axes spines if they have the
- # same min or max:
- if not aligntop and rownum0min == rownumCmin:
- # line up top of _poslayoutbox
- _log.debug('rownum0min == rownumCmin')
- layoutbox.align([ax._poslayoutbox, axc._poslayoutbox],
- 'top')
- aligntop = True
-
- if not alignbot and rownum0max == rownumCmax:
- # line up bottom of _poslayoutbox
- _log.debug('rownum0max == rownumCmax')
- layoutbox.align([ax._poslayoutbox, axc._poslayoutbox],
- 'bottom')
- alignbot = True
- ###########
- # Now we make the widths and heights of position boxes
- # similar. (i.e the spine locations)
- # This allows vertically stacked subplots to have
- # different sizes if they occupy different amounts
- # of the gridspec: i.e.
- # gs = gridspec.GridSpec(3,1)
- # ax1 = gs[0,:]
- # ax2 = gs[1:,:]
- # then drows0 = 1, and drowsC = 2, and ax2
- # should be at least twice as large as ax1.
- # But it can be more than twice as large because
- # it needs less room for the labeling.
- #
- # For height, this only needs to be done if the
- # subplots share a column. For width if they
- # share a row.
-
- drowsC = (rownumCmax - rownumCmin + 1)
- drows0 = (rownum0max - rownum0min + 1)
- dcolsC = (colnumCmax - colnumCmin + 1)
- dcols0 = (colnum0max - colnum0min + 1)
-
- if not alignheight and drows0 == drowsC:
- ax._poslayoutbox.constrain_height(
- axc._poslayoutbox.height * height0 / heightC)
- alignheight = True
- elif in_same_column(colnum0min, colnum0max,
- colnumCmin, colnumCmax):
- if height0 > heightC:
- ax._poslayoutbox.constrain_height_min(
- axc._poslayoutbox.height * height0 / heightC)
- # these constraints stop the smaller axes from
- # being allowed to go to zero height...
- axc._poslayoutbox.constrain_height_min(
- ax._poslayoutbox.height * heightC /
- (height0*1.8))
- elif height0 < heightC:
- axc._poslayoutbox.constrain_height_min(
- ax._poslayoutbox.height * heightC / height0)
- ax._poslayoutbox.constrain_height_min(
- ax._poslayoutbox.height * height0 /
- (heightC*1.8))
- # widths...
- if not alignwidth and dcols0 == dcolsC:
- ax._poslayoutbox.constrain_width(
- axc._poslayoutbox.width * width0 / widthC)
- alignwidth = True
- elif in_same_row(rownum0min, rownum0max,
- rownumCmin, rownumCmax):
- if width0 > widthC:
- ax._poslayoutbox.constrain_width_min(
- axc._poslayoutbox.width * width0 / widthC)
- axc._poslayoutbox.constrain_width_min(
- ax._poslayoutbox.width * widthC /
- (width0*1.8))
- elif width0 < widthC:
- axc._poslayoutbox.constrain_width_min(
- ax._poslayoutbox.width * widthC / width0)
- ax._poslayoutbox.constrain_width_min(
- axc._poslayoutbox.width * width0 /
- (widthC*1.8))
-
- fig._layoutbox.constrained_layout_called += 1
- fig._layoutbox.update_variables()
- # Now set the position of the axes...
- for ax in fig.axes:
- if ax._layoutbox is not None:
- newpos = ax._poslayoutbox.get_rect()
- _log.debug('newpos %r', newpos)
- # Now set the new position.
- # ax.set_position will zero out the layout for
- # this axis, allowing users to hard-code the position,
- # so this does the same w/o zeroing layout.
- ax._set_position(newpos, which='original')
-
-
-def _arange_subplotspecs(gs, hspace=0, wspace=0):
- """
- arange the subplotspec children of this gridspec, and then recursively
- do the same of any gridspec children of those gridspecs...
- """
- sschildren = []
- for child in gs.children:
- if child._is_subplotspec_layoutbox():
- for child2 in child.children:
- # check for gridspec children...
- if child2._is_gridspec_layoutbox():
- _arange_subplotspecs(child2, hspace=hspace, wspace=wspace)
- sschildren += [child]
- # now arrange the subplots...
- for child0 in sschildren:
- ss0 = child0.artist
- nrows, ncols = ss0.get_gridspec().get_geometry()
- if ss0.num2 is None:
- ss0.num2 = ss0.num1
- rowNum0min, colNum0min = divmod(ss0.num1, ncols)
- rowNum0max, colNum0max = divmod(ss0.num2, ncols)
- sschildren = sschildren[1:]
- for childc in sschildren:
- ssc = childc.artist
- rowNumCmin, colNumCmin = divmod(ssc.num1, ncols)
- if ssc.num2 is None:
- ssc.num2 = ssc.num1
- rowNumCmax, colNumCmax = divmod(ssc.num2, ncols)
- # OK, this tells us the relative layout of ax
- # with axc
- thepad = wspace / ncols
- if colNum0max < colNumCmin:
- layoutbox.hstack([ss0._layoutbox, ssc._layoutbox],
- padding=thepad)
- if colNumCmax < colNum0min:
- layoutbox.hstack([ssc._layoutbox, ss0._layoutbox],
- padding=thepad)
-
- ####
- # vertical alignment
- thepad = hspace / nrows
- if rowNum0max < rowNumCmin:
- layoutbox.vstack([ss0._layoutbox,
- ssc._layoutbox],
- padding=thepad)
- if rowNumCmax < rowNum0min:
- layoutbox.vstack([ssc._layoutbox,
- ss0._layoutbox],
- padding=thepad)
-
-
-def layoutcolorbarsingle(ax, cax, shrink, aspect, location, pad=0.05):
- """
- Do the layout for a colorbar, to not oeverly pollute colorbar.py
-
- `pad` is in fraction of the original axis size.
- """
- axlb = ax._layoutbox
- axpos = ax._poslayoutbox
- axsslb = ax.get_subplotspec()._layoutbox
- lb = layoutbox.LayoutBox(
- parent=axsslb,
- name=axsslb.name + '.cbar',
- artist=cax)
-
- if location in ('left', 'right'):
- lbpos = layoutbox.LayoutBox(
- parent=lb,
- name=lb.name + '.pos',
- tightwidth=False,
- pos=True,
- subplot=False,
- artist=cax)
-
- if location == 'right':
- # arrange to right of parent axis
- layoutbox.hstack([axlb, lb], padding=pad * axlb.width,
- strength='strong')
- else:
- layoutbox.hstack([lb, axlb], padding=pad * axlb.width)
- # constrain the height and center...
- layoutbox.match_heights([axpos, lbpos], [1, shrink])
- layoutbox.align([axpos, lbpos], 'v_center')
- # set the width of the pos box
- lbpos.constrain_width(shrink * axpos.height * (1/aspect),
- strength='strong')
- elif location in ('bottom', 'top'):
- lbpos = layoutbox.LayoutBox(
- parent=lb,
- name=lb.name + '.pos',
- tightheight=True,
- pos=True,
- subplot=False,
- artist=cax)
-
- if location == 'bottom':
- layoutbox.vstack([axlb, lb], padding=pad * axlb.height)
- else:
- layoutbox.vstack([lb, axlb], padding=pad * axlb.height)
- # constrain the height and center...
- layoutbox.match_widths([axpos, lbpos],
- [1, shrink], strength='strong')
- layoutbox.align([axpos, lbpos], 'h_center')
- # set the height of the pos box
- lbpos.constrain_height(axpos.width * aspect * shrink,
- strength='medium')
-
- return lb, lbpos
-
-
-def layoutcolorbargridspec(parents, cax, shrink, aspect, location, pad=0.05):
- """
- Do the layout for a colorbar, to not oeverly pollute colorbar.py
-
- `pad` is in fraction of the original axis size.
- """
-
- gs = parents[0].get_subplotspec().get_gridspec()
- # parent layout box....
- gslb = gs._layoutbox
-
- lb = layoutbox.LayoutBox(parent=gslb.parent,
- name=gslb.parent.name + '.cbar',
- artist=cax)
- if location in ('left', 'right'):
- lbpos = layoutbox.LayoutBox(
- parent=lb,
- name=lb.name + '.pos',
- tightwidth=False,
- pos=True,
- subplot=False,
- artist=cax)
-
- if location == 'right':
- # arrange to right of the gridpec sibbling
- layoutbox.hstack([gslb, lb], padding=pad * gslb.width,
- strength='strong')
- else:
- layoutbox.hstack([lb, gslb], padding=pad * gslb.width)
- # constrain the height and center...
- # This isn't quite right. We'd like the colorbar
- # pos to line up w/ the axes poss, not the size of the
- # gs.
- maxrow = -100000
- minrow = 1000000
- maxax = None
- minax = None
-
- for ax in parents:
- subspec = ax.get_subplotspec()
- nrows, ncols = subspec.get_gridspec().get_geometry()
- for num in [subspec.num1, subspec.num2]:
- rownum1, colnum1 = divmod(subspec.num1, ncols)
- if rownum1 > maxrow:
- maxrow = rownum1
- maxax = ax
- if rownum1 < minrow:
- minrow = rownum1
- minax = ax
- # invert the order so these are bottom to top:
- maxposlb = minax._poslayoutbox
- minposlb = maxax._poslayoutbox
- # now we want the height of the colorbar pos to be
- # set by the top and bottom of these poss
- # bottom top
- # b t
- # h = (top-bottom)*shrink
- # b = bottom + (top-bottom - h) / 2.
- lbpos.constrain_height(
- (maxposlb.top - minposlb.bottom) *
- shrink, strength='strong')
- lbpos.constrain_bottom(
- (maxposlb.top - minposlb.bottom) *
- (1 - shrink)/2 + minposlb.bottom,
- strength='strong')
-
- # set the width of the pos box
- lbpos.constrain_width(lbpos.height * (shrink / aspect),
- strength='strong')
- elif location in ('bottom', 'top'):
- lbpos = layoutbox.LayoutBox(
- parent=lb,
- name=lb.name + '.pos',
- tightheight=True,
- pos=True,
- subplot=False,
- artist=cax)
-
- if location == 'bottom':
- layoutbox.vstack([gslb, lb], padding=pad * gslb.width)
- else:
- layoutbox.vstack([lb, gslb], padding=pad * gslb.width)
-
- maxcol = -100000
- mincol = 1000000
- maxax = None
- minax = None
-
- for ax in parents:
- subspec = ax.get_subplotspec()
- nrows, ncols = subspec.get_gridspec().get_geometry()
- for num in [subspec.num1, subspec.num2]:
- rownum1, colnum1 = divmod(subspec.num1, ncols)
- if colnum1 > maxcol:
- maxcol = colnum1
- maxax = ax
- if rownum1 < mincol:
- mincol = colnum1
- minax = ax
- maxposlb = maxax._poslayoutbox
- minposlb = minax._poslayoutbox
- lbpos.constrain_width((maxposlb.right - minposlb.left) *
- shrink)
- lbpos.constrain_left(
- (maxposlb.right - minposlb.left) *
- (1-shrink)/2 + minposlb.left)
- # set the height of the pos box
- lbpos.constrain_height(lbpos.width * shrink * aspect,
- strength='medium')
-
- return lb, lbpos
diff --git a/contrib/python/matplotlib/py2/matplotlib/_layoutbox.py b/contrib/python/matplotlib/py2/matplotlib/_layoutbox.py
deleted file mode 100644
index cb6f031580..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/_layoutbox.py
+++ /dev/null
@@ -1,739 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-
-Conventions:
-
-"constrain_x" means to constrain the variable with either
-another kiwisolver variable, or a float. i.e. `constrain_width(0.2)`
-will set a constraint that the width has to be 0.2 and this constraint is
-permanent - i.e. it will not be removed if it becomes obsolete.
-
-"edit_x" means to set x to a value (just a float), and that this value can
-change. So `edit_width(0.2)` will set width to be 0.2, but `edit_width(0.3)`
-will allow it to change to 0.3 later. Note that these values are still just
-"suggestions" in `kiwisolver` parlance, and could be over-ridden by
-other constrains.
-
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import itertools
-import kiwisolver as kiwi
-import logging
-import numpy as np
-import warnings
-
-import matplotlib
-
-_log = logging.getLogger(__name__)
-
-
-# renderers can be complicated
-def get_renderer(fig):
- if fig._cachedRenderer:
- renderer = fig._cachedRenderer
- else:
- canvas = fig.canvas
- if canvas and hasattr(canvas, "get_renderer"):
- renderer = canvas.get_renderer()
- else:
- # not sure if this can happen
- # seems to with PDF...
- _log.info("constrained_layout : falling back to Agg renderer")
- from matplotlib.backends.backend_agg import FigureCanvasAgg
- canvas = FigureCanvasAgg(fig)
- renderer = canvas.get_renderer()
-
- return renderer
-
-
-class LayoutBox(object):
- """
- Basic rectangle representation using kiwi solver variables
- """
-
- def __init__(self, parent=None, name='', tightwidth=False,
- tightheight=False, artist=None,
- lower_left=(0, 0), upper_right=(1, 1), pos=False,
- subplot=False, h_pad=None, w_pad=None):
- Variable = kiwi.Variable
- self.parent = parent
- self.name = name
- sn = self.name + '_'
- if parent is None:
- self.solver = kiwi.Solver()
- self.constrained_layout_called = 0
- else:
- self.solver = parent.solver
- self.constrained_layout_called = None
- # parent wants to know about this child!
- parent.add_child(self)
- # keep track of artist associated w/ this layout. Can be none
- self.artist = artist
- # keep track if this box is supposed to be a pos that is constrained
- # by the parent.
- self.pos = pos
- # keep track of whether we need to match this subplot up with others.
- self.subplot = subplot
-
- # we need the str below for Py 2 which complains the string is unicode
- self.top = Variable(str(sn + 'top'))
- self.bottom = Variable(str(sn + 'bottom'))
- self.left = Variable(str(sn + 'left'))
- self.right = Variable(str(sn + 'right'))
-
- self.width = Variable(str(sn + 'width'))
- self.height = Variable(str(sn + 'height'))
- self.h_center = Variable(str(sn + 'h_center'))
- self.v_center = Variable(str(sn + 'v_center'))
-
- self.min_width = Variable(str(sn + 'min_width'))
- self.min_height = Variable(str(sn + 'min_height'))
- self.pref_width = Variable(str(sn + 'pref_width'))
- self.pref_height = Variable(str(sn + 'pref_height'))
- # margis are only used for axes-position layout boxes. maybe should
- # be a separate subclass:
- self.left_margin = Variable(str(sn + 'left_margin'))
- self.right_margin = Variable(str(sn + 'right_margin'))
- self.bottom_margin = Variable(str(sn + 'bottom_margin'))
- self.top_margin = Variable(str(sn + 'top_margin'))
- # mins
- self.left_margin_min = Variable(str(sn + 'left_margin_min'))
- self.right_margin_min = Variable(str(sn + 'right_margin_min'))
- self.bottom_margin_min = Variable(str(sn + 'bottom_margin_min'))
- self.top_margin_min = Variable(str(sn + 'top_margin_min'))
-
- right, top = upper_right
- left, bottom = lower_left
- self.tightheight = tightheight
- self.tightwidth = tightwidth
- self.add_constraints()
- self.children = []
- self.subplotspec = None
- if self.pos:
- self.constrain_margins()
- self.h_pad = h_pad
- self.w_pad = w_pad
-
- def constrain_margins(self):
- """
- Only do this for pos. This sets a variable distance
- margin between the position of the axes and the outer edge of
- the axes.
-
- Margins are variable because they change with the fogure size.
-
- Margin minimums are set to make room for axes decorations. However,
- the margins can be larger if we are mathicng the position size to
- otehr axes.
- """
- sol = self.solver
-
- # left
- if not sol.hasEditVariable(self.left_margin_min):
- sol.addEditVariable(self.left_margin_min, 'strong')
- sol.suggestValue(self.left_margin_min, 0.0001)
- c = (self.left_margin == self.left - self.parent.left)
- self.solver.addConstraint(c | 'required')
- c = (self.left_margin >= self.left_margin_min)
- self.solver.addConstraint(c | 'strong')
-
- # right
- if not sol.hasEditVariable(self.right_margin_min):
- sol.addEditVariable(self.right_margin_min, 'strong')
- sol.suggestValue(self.right_margin_min, 0.0001)
- c = (self.right_margin == self.parent.right - self.right)
- self.solver.addConstraint(c | 'required')
- c = (self.right_margin >= self.right_margin_min)
- self.solver.addConstraint(c | 'required')
- # bottom
- if not sol.hasEditVariable(self.bottom_margin_min):
- sol.addEditVariable(self.bottom_margin_min, 'strong')
- sol.suggestValue(self.bottom_margin_min, 0.0001)
- c = (self.bottom_margin == self.bottom - self.parent.bottom)
- self.solver.addConstraint(c | 'required')
- c = (self.bottom_margin >= self.bottom_margin_min)
- self.solver.addConstraint(c | 'required')
- # top
- if not sol.hasEditVariable(self.top_margin_min):
- sol.addEditVariable(self.top_margin_min, 'strong')
- sol.suggestValue(self.top_margin_min, 0.0001)
- c = (self.top_margin == self.parent.top - self.top)
- self.solver.addConstraint(c | 'required')
- c = (self.top_margin >= self.top_margin_min)
- self.solver.addConstraint(c | 'required')
-
- def add_child(self, child):
- self.children += [child]
-
- def remove_child(self, child):
- try:
- self.children.remove(child)
- except ValueError:
- _log.info("Tried to remove child that doesn't belong to parent")
-
- def add_constraints(self):
- sol = self.solver
- # never let width and height go negative.
- for i in [self.min_width, self.min_height]:
- sol.addEditVariable(i, 1e9)
- sol.suggestValue(i, 0.0)
- # define relation ships between things thing width and right and left
- self.hard_constraints()
- # self.soft_constraints()
- if self.parent:
- self.parent_constrain()
- # sol.updateVariables()
-
- def parent_constrain(self):
- parent = self.parent
- hc = [self.left >= parent.left,
- self.bottom >= parent.bottom,
- self.top <= parent.top,
- self.right <= parent.right]
- for c in hc:
- self.solver.addConstraint(c | 'required')
-
- def hard_constraints(self):
- hc = [self.width == self.right - self.left,
- self.height == self.top - self.bottom,
- self.h_center == (self.left + self.right) * 0.5,
- self.v_center == (self.top + self.bottom) * 0.5,
- self.width >= self.min_width,
- self.height >= self.min_height]
- for c in hc:
- self.solver.addConstraint(c | 'required')
-
- def soft_constraints(self):
- sol = self.solver
- if self.tightwidth:
- suggest = 0.
- else:
- suggest = 20.
- c = (self.pref_width == suggest)
- for i in c:
- sol.addConstraint(i | 'required')
- if self.tightheight:
- suggest = 0.
- else:
- suggest = 20.
- c = (self.pref_height == suggest)
- for i in c:
- sol.addConstraint(i | 'required')
-
- c = [(self.width >= suggest),
- (self.height >= suggest)]
- for i in c:
- sol.addConstraint(i | 150000)
-
- def set_parent(self, parent):
- ''' replace the parent of this with the new parent
- '''
- self.parent = parent
- self.parent_constrain()
-
- def constrain_geometry(self, left, bottom, right, top, strength='strong'):
- hc = [self.left == left,
- self.right == right,
- self.bottom == bottom,
- self.top == top]
- for c in hc:
- self.solver.addConstraint((c | strength))
- # self.solver.updateVariables()
-
- def constrain_same(self, other, strength='strong'):
- """
- Make the layoutbox have same position as other layoutbox
- """
- hc = [self.left == other.left,
- self.right == other.right,
- self.bottom == other.bottom,
- self.top == other.top]
- for c in hc:
- self.solver.addConstraint((c | strength))
-
- def constrain_left_margin(self, margin, strength='strong'):
- c = (self.left == self.parent.left + margin)
- self.solver.addConstraint(c | strength)
-
- def edit_left_margin_min(self, margin):
- self.solver.suggestValue(self.left_margin_min, margin)
-
- def constrain_right_margin(self, margin, strength='strong'):
- c = (self.right == self.parent.right - margin)
- self.solver.addConstraint(c | strength)
-
- def edit_right_margin_min(self, margin):
- self.solver.suggestValue(self.right_margin_min, margin)
-
- def constrain_bottom_margin(self, margin, strength='strong'):
- c = (self.bottom == self.parent.bottom + margin)
- self.solver.addConstraint(c | strength)
-
- def edit_bottom_margin_min(self, margin):
- self.solver.suggestValue(self.bottom_margin_min, margin)
-
- def constrain_top_margin(self, margin, strength='strong'):
- c = (self.top == self.parent.top - margin)
- self.solver.addConstraint(c | strength)
-
- def edit_top_margin_min(self, margin):
- self.solver.suggestValue(self.top_margin_min, margin)
-
- def get_rect(self):
- return (self.left.value(), self.bottom.value(),
- self.width.value(), self.height.value())
-
- def update_variables(self):
- '''
- Update *all* the variables that are part of the solver this LayoutBox
- is created with
- '''
- self.solver.updateVariables()
-
- def edit_height(self, height, strength='strong'):
- '''
- Set the height of the layout box.
-
- This is done as an editable variable so that the value can change
- due to resizing.
- '''
- sol = self.solver
- for i in [self.height]:
- if not sol.hasEditVariable(i):
- sol.addEditVariable(i, strength)
- sol.suggestValue(self.height, height)
-
- def constrain_height(self, height, strength='strong'):
- '''
- Constrain the height of the layout box. height is
- either a float or a layoutbox.height.
- '''
- c = (self.height == height)
- self.solver.addConstraint(c | strength)
-
- def constrain_height_min(self, height, strength='strong'):
- c = (self.height >= height)
- self.solver.addConstraint(c | strength)
-
- def edit_width(self, width, strength='strong'):
- sol = self.solver
- for i in [self.width]:
- if not sol.hasEditVariable(i):
- sol.addEditVariable(i, strength)
- sol.suggestValue(self.width, width)
-
- def constrain_width(self, width, strength='strong'):
- '''
- Constrain the width of the layout box. `width` is
- either a float or a layoutbox.width.
- '''
- c = (self.width == width)
- self.solver.addConstraint(c | strength)
-
- def constrain_width_min(self, width, strength='strong'):
- c = (self.width >= width)
- self.solver.addConstraint(c | strength)
-
- def constrain_left(self, left, strength='strong'):
- c = (self.left == left)
- self.solver.addConstraint(c | strength)
-
- def constrain_bottom(self, bottom, strength='strong'):
- c = (self.bottom == bottom)
- self.solver.addConstraint(c | strength)
-
- def constrain_right(self, right, strength='strong'):
- c = (self.right == right)
- self.solver.addConstraint(c | strength)
-
- def constrain_top(self, top, strength='strong'):
- c = (self.top == top)
- self.solver.addConstraint(c | strength)
-
- def _is_subplotspec_layoutbox(self):
- '''
- Helper to check if this layoutbox is the layoutbox of a
- subplotspec
- '''
- name = (self.name).split('.')[-1]
- return name[:2] == 'ss'
-
- def _is_gridspec_layoutbox(self):
- '''
- Helper to check if this layoutbox is the layoutbox of a
- gridspec
- '''
- name = (self.name).split('.')[-1]
- return name[:8] == 'gridspec'
-
- def find_child_subplots(self):
- '''
- Find children of this layout box that are subplots. We want to line
- poss up, and this is an easy way to find them all.
- '''
- if self.subplot:
- subplots = [self]
- else:
- subplots = []
- for child in self.children:
- subplots += child.find_child_subplots()
- return subplots
-
- def layout_from_subplotspec(self, subspec,
- name='', artist=None, pos=False):
- ''' Make a layout box from a subplotspec. The layout box is
- constrained to be a fraction of the width/height of the parent,
- and be a fraction of the parent width/height from the left/bottom
- of the parent. Therefore the parent can move around and the
- layout for the subplot spec should move with it.
-
- The parent is *usually* the gridspec that made the subplotspec.??
- '''
- lb = LayoutBox(parent=self, name=name, artist=artist, pos=pos)
- gs = subspec.get_gridspec()
- nrows, ncols = gs.get_geometry()
- parent = self.parent
-
- # OK, now, we want to set the position of this subplotspec
- # based on its subplotspec parameters. The new gridspec will inherit.
-
- # from gridspec. prob should be new method in gridspec
- left = 0.0
- right = 1.0
- bottom = 0.0
- top = 1.0
- totWidth = right-left
- totHeight = top-bottom
- hspace = 0.
- wspace = 0.
-
- # calculate accumulated heights of columns
- cellH = totHeight / (nrows + hspace * (nrows - 1))
- sepH = hspace*cellH
-
- if gs._row_height_ratios is not None:
- netHeight = cellH * nrows
- tr = float(sum(gs._row_height_ratios))
- cellHeights = [netHeight*r/tr for r in gs._row_height_ratios]
- else:
- cellHeights = [cellH] * nrows
-
- sepHeights = [0] + ([sepH] * (nrows - 1))
- cellHs = np.add.accumulate(np.ravel(
- list(zip(sepHeights, cellHeights))))
-
- # calculate accumulated widths of rows
- cellW = totWidth/(ncols + wspace * (ncols - 1))
- sepW = wspace*cellW
-
- if gs._col_width_ratios is not None:
- netWidth = cellW * ncols
- tr = float(sum(gs._col_width_ratios))
- cellWidths = [netWidth * r / tr for r in gs._col_width_ratios]
- else:
- cellWidths = [cellW] * ncols
-
- sepWidths = [0] + ([sepW] * (ncols - 1))
- cellWs = np.add.accumulate(np.ravel(list(zip(sepWidths, cellWidths))))
-
- figTops = [top - cellHs[2 * rowNum] for rowNum in range(nrows)]
- figBottoms = [top - cellHs[2 * rowNum + 1] for rowNum in range(nrows)]
- figLefts = [left + cellWs[2 * colNum] for colNum in range(ncols)]
- figRights = [left + cellWs[2 * colNum + 1] for colNum in range(ncols)]
-
- rowNum, colNum = divmod(subspec.num1, ncols)
- figBottom = figBottoms[rowNum]
- figTop = figTops[rowNum]
- figLeft = figLefts[colNum]
- figRight = figRights[colNum]
-
- if subspec.num2 is not None:
-
- rowNum2, colNum2 = divmod(subspec.num2, ncols)
- figBottom2 = figBottoms[rowNum2]
- figTop2 = figTops[rowNum2]
- figLeft2 = figLefts[colNum2]
- figRight2 = figRights[colNum2]
-
- figBottom = min(figBottom, figBottom2)
- figLeft = min(figLeft, figLeft2)
- figTop = max(figTop, figTop2)
- figRight = max(figRight, figRight2)
- # These are numbers relative to 0,0,1,1. Need to constrain
- # relative to parent.
-
- width = figRight - figLeft
- height = figTop - figBottom
- parent = self.parent
- cs = [self.left == parent.left + parent.width * figLeft,
- self.bottom == parent.bottom + parent.height * figBottom,
- self.width == parent.width * width,
- self.height == parent.height * height]
- for c in cs:
- self.solver.addConstraint((c | 'required'))
-
- return lb
-
- def __repr__(self):
- args = (self.name, self.left.value(), self.bottom.value(),
- self.right.value(), self.top.value())
- return ('LayoutBox: %25s, (left: %1.3f) (bot: %1.3f) '
- '(right: %1.3f) (top: %1.3f) ') % args
-
-
-# Utility functions that act on layoutboxes...
-def hstack(boxes, padding=0, strength='strong'):
- '''
- Stack LayoutBox instances from left to right.
- `padding` is in figure-relative units.
- '''
-
- for i in range(1, len(boxes)):
- c = (boxes[i-1].right + padding <= boxes[i].left)
- boxes[i].solver.addConstraint(c | strength)
-
-
-def hpack(boxes, padding=0, strength='strong'):
- '''
- Stack LayoutBox instances from left to right.
- '''
-
- for i in range(1, len(boxes)):
- c = (boxes[i-1].right + padding == boxes[i].left)
- boxes[i].solver.addConstraint(c | strength)
-
-
-def vstack(boxes, padding=0, strength='strong'):
- '''
- Stack LayoutBox instances from top to bottom
- '''
-
- for i in range(1, len(boxes)):
- c = (boxes[i-1].bottom - padding >= boxes[i].top)
- boxes[i].solver.addConstraint(c | strength)
-
-
-def vpack(boxes, padding=0, strength='strong'):
- '''
- Stack LayoutBox instances from top to bottom
- '''
-
- for i in range(1, len(boxes)):
- c = (boxes[i-1].bottom - padding >= boxes[i].top)
- boxes[i].solver.addConstraint(c | strength)
-
-
-def match_heights(boxes, height_ratios=None, strength='medium'):
- '''
- Stack LayoutBox instances from top to bottom
- '''
-
- if height_ratios is None:
- height_ratios = np.ones(len(boxes))
- for i in range(1, len(boxes)):
- c = (boxes[i-1].height ==
- boxes[i].height*height_ratios[i-1]/height_ratios[i])
- boxes[i].solver.addConstraint(c | strength)
-
-
-def match_widths(boxes, width_ratios=None, strength='medium'):
- '''
- Stack LayoutBox instances from top to bottom
- '''
-
- if width_ratios is None:
- width_ratios = np.ones(len(boxes))
- for i in range(1, len(boxes)):
- c = (boxes[i-1].width ==
- boxes[i].width*width_ratios[i-1]/width_ratios[i])
- boxes[i].solver.addConstraint(c | strength)
-
-
-def vstackeq(boxes, padding=0, height_ratios=None):
- vstack(boxes, padding=padding)
- match_heights(boxes, height_ratios=height_ratios)
-
-
-def hstackeq(boxes, padding=0, width_ratios=None):
- hstack(boxes, padding=padding)
- match_widths(boxes, width_ratios=width_ratios)
-
-
-def align(boxes, attr, strength='strong'):
- cons = []
- for box in boxes[1:]:
- cons = (getattr(boxes[0], attr) == getattr(box, attr))
- boxes[0].solver.addConstraint(cons | strength)
-
-
-def match_top_margins(boxes, levels=1):
- box0 = boxes[0]
- top0 = box0
- for n in range(levels):
- top0 = top0.parent
- for box in boxes[1:]:
- topb = box
- for n in range(levels):
- topb = topb.parent
- c = (box0.top-top0.top == box.top-topb.top)
- box0.solver.addConstraint(c | 'strong')
-
-
-def match_bottom_margins(boxes, levels=1):
- box0 = boxes[0]
- top0 = box0
- for n in range(levels):
- top0 = top0.parent
- for box in boxes[1:]:
- topb = box
- for n in range(levels):
- topb = topb.parent
- c = (box0.bottom-top0.bottom == box.bottom-topb.bottom)
- box0.solver.addConstraint(c | 'strong')
-
-
-def match_left_margins(boxes, levels=1):
- box0 = boxes[0]
- top0 = box0
- for n in range(levels):
- top0 = top0.parent
- for box in boxes[1:]:
- topb = box
- for n in range(levels):
- topb = topb.parent
- c = (box0.left-top0.left == box.left-topb.left)
- box0.solver.addConstraint(c | 'strong')
-
-
-def match_right_margins(boxes, levels=1):
- box0 = boxes[0]
- top0 = box0
- for n in range(levels):
- top0 = top0.parent
- for box in boxes[1:]:
- topb = box
- for n in range(levels):
- topb = topb.parent
- c = (box0.right-top0.right == box.right-topb.right)
- box0.solver.addConstraint(c | 'strong')
-
-
-def match_width_margins(boxes, levels=1):
- match_left_margins(boxes, levels=levels)
- match_right_margins(boxes, levels=levels)
-
-
-def match_height_margins(boxes, levels=1):
- match_top_margins(boxes, levels=levels)
- match_bottom_margins(boxes, levels=levels)
-
-
-def match_margins(boxes, levels=1):
- match_width_margins(boxes, levels=levels)
- match_height_margins(boxes, levels=levels)
-
-
-_layoutboxobjnum = itertools.count()
-
-
-def seq_id():
- '''
- Generate a short sequential id for layoutbox objects...
- '''
-
- global _layoutboxobjnum
-
- return ('%06d' % (next(_layoutboxobjnum)))
-
-
-def print_children(lb):
- '''
- Print the children of the layoutbox
- '''
- print(lb)
- for child in lb.children:
- print_children(child)
-
-
-def nonetree(lb):
- '''
- Make all elements in this tree none... This signals not to do any more
- layout.
- '''
- if lb is not None:
- if lb.parent is None:
- # Clear the solver. Hopefully this garbage collects.
- lb.solver.reset()
- nonechildren(lb)
- else:
- nonetree(lb.parent)
-
-
-def nonechildren(lb):
- for child in lb.children:
- nonechildren(child)
- lb.artist._layoutbox = None
- lb = None
-
-
-def print_tree(lb):
- '''
- Print the tree of layoutboxes
- '''
-
- if lb.parent is None:
- print('LayoutBox Tree\n')
- print('==============\n')
- print_children(lb)
- print('\n')
- else:
- print_tree(lb.parent)
-
-
-def plot_children(fig, box, level=0, printit=True):
- '''
- Simple plotting to show where boxes are
- '''
- import matplotlib
- import matplotlib.pyplot as plt
-
- if isinstance(fig, matplotlib.figure.Figure):
- ax = fig.add_axes([0., 0., 1., 1.])
- ax.set_facecolor([1., 1., 1., 0.7])
- ax.set_alpha(0.3)
- fig.draw(fig.canvas.get_renderer())
- else:
- ax = fig
-
- import matplotlib.patches as patches
- colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
- if printit:
- print("Level:", level)
- for child in box.children:
- rect = child.get_rect()
- if printit:
- print(child)
- ax.add_patch(
- patches.Rectangle(
- (child.left.value(), child.bottom.value()), # (x,y)
- child.width.value(), # width
- child.height.value(), # height
- fc='none',
- alpha=0.8,
- ec=colors[level]
- )
- )
- if level > 0:
- name = child.name.split('.')[-1]
- if level % 2 == 0:
- ax.text(child.left.value(), child.bottom.value(), name,
- size=12-level, color=colors[level])
- else:
- ax.text(child.right.value(), child.top.value(), name,
- ha='right', va='top', size=12-level,
- color=colors[level])
-
- plot_children(ax, child, level=level+1, printit=printit)
diff --git a/contrib/python/matplotlib/py2/matplotlib/_mathtext_data.py b/contrib/python/matplotlib/py2/matplotlib/_mathtext_data.py
deleted file mode 100644
index d042d25892..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/_mathtext_data.py
+++ /dev/null
@@ -1,2548 +0,0 @@
-"""
-font data tables for truetype and afm computer modern fonts
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-latex_to_bakoma = {
- '\\__sqrt__' : ('cmex10', 0x70),
- '\\bigcap' : ('cmex10', 0x5c),
- '\\bigcup' : ('cmex10', 0x5b),
- '\\bigodot' : ('cmex10', 0x4b),
- '\\bigoplus' : ('cmex10', 0x4d),
- '\\bigotimes' : ('cmex10', 0x4f),
- '\\biguplus' : ('cmex10', 0x5d),
- '\\bigvee' : ('cmex10', 0x5f),
- '\\bigwedge' : ('cmex10', 0x5e),
- '\\coprod' : ('cmex10', 0x61),
- '\\int' : ('cmex10', 0x5a),
- '\\langle' : ('cmex10', 0xad),
- '\\leftangle' : ('cmex10', 0xad),
- '\\leftbrace' : ('cmex10', 0xa9),
- '\\oint' : ('cmex10', 0x49),
- '\\prod' : ('cmex10', 0x59),
- '\\rangle' : ('cmex10', 0xae),
- '\\rightangle' : ('cmex10', 0xae),
- '\\rightbrace' : ('cmex10', 0xaa),
- '\\sum' : ('cmex10', 0x58),
- '\\widehat' : ('cmex10', 0x62),
- '\\widetilde' : ('cmex10', 0x65),
- '\\{' : ('cmex10', 0xa9),
- '\\}' : ('cmex10', 0xaa),
- '{' : ('cmex10', 0xa9),
- '}' : ('cmex10', 0xaa),
-
- ',' : ('cmmi10', 0x3b),
- '.' : ('cmmi10', 0x3a),
- '/' : ('cmmi10', 0x3d),
- '<' : ('cmmi10', 0x3c),
- '>' : ('cmmi10', 0x3e),
- '\\alpha' : ('cmmi10', 0xae),
- '\\beta' : ('cmmi10', 0xaf),
- '\\chi' : ('cmmi10', 0xc2),
- '\\combiningrightarrowabove' : ('cmmi10', 0x7e),
- '\\delta' : ('cmmi10', 0xb1),
- '\\ell' : ('cmmi10', 0x60),
- '\\epsilon' : ('cmmi10', 0xb2),
- '\\eta' : ('cmmi10', 0xb4),
- '\\flat' : ('cmmi10', 0x5b),
- '\\frown' : ('cmmi10', 0x5f),
- '\\gamma' : ('cmmi10', 0xb0),
- '\\imath' : ('cmmi10', 0x7b),
- '\\iota' : ('cmmi10', 0xb6),
- '\\jmath' : ('cmmi10', 0x7c),
- '\\kappa' : ('cmmi10', 0x2219),
- '\\lambda' : ('cmmi10', 0xb8),
- '\\leftharpoondown' : ('cmmi10', 0x29),
- '\\leftharpoonup' : ('cmmi10', 0x28),
- '\\mu' : ('cmmi10', 0xb9),
- '\\natural' : ('cmmi10', 0x5c),
- '\\nu' : ('cmmi10', 0xba),
- '\\omega' : ('cmmi10', 0x21),
- '\\phi' : ('cmmi10', 0xc1),
- '\\pi' : ('cmmi10', 0xbc),
- '\\psi' : ('cmmi10', 0xc3),
- '\\rho' : ('cmmi10', 0xbd),
- '\\rightharpoondown' : ('cmmi10', 0x2b),
- '\\rightharpoonup' : ('cmmi10', 0x2a),
- '\\sharp' : ('cmmi10', 0x5d),
- '\\sigma' : ('cmmi10', 0xbe),
- '\\smile' : ('cmmi10', 0x5e),
- '\\tau' : ('cmmi10', 0xbf),
- '\\theta' : ('cmmi10', 0xb5),
- '\\triangleleft' : ('cmmi10', 0x2f),
- '\\triangleright' : ('cmmi10', 0x2e),
- '\\upsilon' : ('cmmi10', 0xc0),
- '\\varepsilon' : ('cmmi10', 0x22),
- '\\varphi' : ('cmmi10', 0x27),
- '\\varrho' : ('cmmi10', 0x25),
- '\\varsigma' : ('cmmi10', 0x26),
- '\\vartheta' : ('cmmi10', 0x23),
- '\\wp' : ('cmmi10', 0x7d),
- '\\xi' : ('cmmi10', 0xbb),
- '\\zeta' : ('cmmi10', 0xb3),
-
- '!' : ('cmr10', 0x21),
- '%' : ('cmr10', 0x25),
- '&' : ('cmr10', 0x26),
- '(' : ('cmr10', 0x28),
- ')' : ('cmr10', 0x29),
- '+' : ('cmr10', 0x2b),
- '0' : ('cmr10', 0x30),
- '1' : ('cmr10', 0x31),
- '2' : ('cmr10', 0x32),
- '3' : ('cmr10', 0x33),
- '4' : ('cmr10', 0x34),
- '5' : ('cmr10', 0x35),
- '6' : ('cmr10', 0x36),
- '7' : ('cmr10', 0x37),
- '8' : ('cmr10', 0x38),
- '9' : ('cmr10', 0x39),
- ':' : ('cmr10', 0x3a),
- ';' : ('cmr10', 0x3b),
- '=' : ('cmr10', 0x3d),
- '?' : ('cmr10', 0x3f),
- '@' : ('cmr10', 0x40),
- '[' : ('cmr10', 0x5b),
- '\\#' : ('cmr10', 0x23),
- '\\$' : ('cmr10', 0x24),
- '\\%' : ('cmr10', 0x25),
- '\\Delta' : ('cmr10', 0xa2),
- '\\Gamma' : ('cmr10', 0xa1),
- '\\Lambda' : ('cmr10', 0xa4),
- '\\Omega' : ('cmr10', 0xad),
- '\\Phi' : ('cmr10', 0xa9),
- '\\Pi' : ('cmr10', 0xa6),
- '\\Psi' : ('cmr10', 0xaa),
- '\\Sigma' : ('cmr10', 0xa7),
- '\\Theta' : ('cmr10', 0xa3),
- '\\Upsilon' : ('cmr10', 0xa8),
- '\\Xi' : ('cmr10', 0xa5),
- '\\circumflexaccent' : ('cmr10', 0x5e),
- '\\combiningacuteaccent' : ('cmr10', 0xb6),
- '\\combiningbreve' : ('cmr10', 0xb8),
- '\\combiningdiaeresis' : ('cmr10', 0xc4),
- '\\combiningdotabove' : ('cmr10', 0x5f),
- '\\combininggraveaccent' : ('cmr10', 0xb5),
- '\\combiningoverline' : ('cmr10', 0xb9),
- '\\combiningtilde' : ('cmr10', 0x7e),
- '\\leftbracket' : ('cmr10', 0x5b),
- '\\leftparen' : ('cmr10', 0x28),
- '\\rightbracket' : ('cmr10', 0x5d),
- '\\rightparen' : ('cmr10', 0x29),
- '\\widebar' : ('cmr10', 0xb9),
- ']' : ('cmr10', 0x5d),
-
- '*' : ('cmsy10', 0xa4),
- '-' : ('cmsy10', 0xa1),
- '\\Downarrow' : ('cmsy10', 0x2b),
- '\\Im' : ('cmsy10', 0x3d),
- '\\Leftarrow' : ('cmsy10', 0x28),
- '\\Leftrightarrow' : ('cmsy10', 0x2c),
- '\\P' : ('cmsy10', 0x7b),
- '\\Re' : ('cmsy10', 0x3c),
- '\\Rightarrow' : ('cmsy10', 0x29),
- '\\S' : ('cmsy10', 0x78),
- '\\Uparrow' : ('cmsy10', 0x2a),
- '\\Updownarrow' : ('cmsy10', 0x6d),
- '\\Vert' : ('cmsy10', 0x6b),
- '\\aleph' : ('cmsy10', 0x40),
- '\\approx' : ('cmsy10', 0xbc),
- '\\ast' : ('cmsy10', 0xa4),
- '\\asymp' : ('cmsy10', 0xb3),
- '\\backslash' : ('cmsy10', 0x6e),
- '\\bigcirc' : ('cmsy10', 0xb0),
- '\\bigtriangledown' : ('cmsy10', 0x35),
- '\\bigtriangleup' : ('cmsy10', 0x34),
- '\\bot' : ('cmsy10', 0x3f),
- '\\bullet' : ('cmsy10', 0xb2),
- '\\cap' : ('cmsy10', 0x5c),
- '\\cdot' : ('cmsy10', 0xa2),
- '\\circ' : ('cmsy10', 0xb1),
- '\\clubsuit' : ('cmsy10', 0x7c),
- '\\cup' : ('cmsy10', 0x5b),
- '\\dag' : ('cmsy10', 0x79),
- '\\dashv' : ('cmsy10', 0x61),
- '\\ddag' : ('cmsy10', 0x7a),
- '\\diamond' : ('cmsy10', 0xa6),
- '\\diamondsuit' : ('cmsy10', 0x7d),
- '\\div' : ('cmsy10', 0xa5),
- '\\downarrow' : ('cmsy10', 0x23),
- '\\emptyset' : ('cmsy10', 0x3b),
- '\\equiv' : ('cmsy10', 0xb4),
- '\\exists' : ('cmsy10', 0x39),
- '\\forall' : ('cmsy10', 0x38),
- '\\geq' : ('cmsy10', 0xb8),
- '\\gg' : ('cmsy10', 0xc0),
- '\\heartsuit' : ('cmsy10', 0x7e),
- '\\in' : ('cmsy10', 0x32),
- '\\infty' : ('cmsy10', 0x31),
- '\\lbrace' : ('cmsy10', 0x66),
- '\\lceil' : ('cmsy10', 0x64),
- '\\leftarrow' : ('cmsy10', 0xc3),
- '\\leftrightarrow' : ('cmsy10', 0x24),
- '\\leq' : ('cmsy10', 0x2219),
- '\\lfloor' : ('cmsy10', 0x62),
- '\\ll' : ('cmsy10', 0xbf),
- '\\mid' : ('cmsy10', 0x6a),
- '\\mp' : ('cmsy10', 0xa8),
- '\\nabla' : ('cmsy10', 0x72),
- '\\nearrow' : ('cmsy10', 0x25),
- '\\neg' : ('cmsy10', 0x3a),
- '\\ni' : ('cmsy10', 0x33),
- '\\nwarrow' : ('cmsy10', 0x2d),
- '\\odot' : ('cmsy10', 0xaf),
- '\\ominus' : ('cmsy10', 0xaa),
- '\\oplus' : ('cmsy10', 0xa9),
- '\\oslash' : ('cmsy10', 0xae),
- '\\otimes' : ('cmsy10', 0xad),
- '\\pm' : ('cmsy10', 0xa7),
- '\\prec' : ('cmsy10', 0xc1),
- '\\preceq' : ('cmsy10', 0xb9),
- '\\prime' : ('cmsy10', 0x30),
- '\\propto' : ('cmsy10', 0x2f),
- '\\rbrace' : ('cmsy10', 0x67),
- '\\rceil' : ('cmsy10', 0x65),
- '\\rfloor' : ('cmsy10', 0x63),
- '\\rightarrow' : ('cmsy10', 0x21),
- '\\searrow' : ('cmsy10', 0x26),
- '\\sim' : ('cmsy10', 0xbb),
- '\\simeq' : ('cmsy10', 0x27),
- '\\slash' : ('cmsy10', 0x36),
- '\\spadesuit' : ('cmsy10', 0xc4),
- '\\sqcap' : ('cmsy10', 0x75),
- '\\sqcup' : ('cmsy10', 0x74),
- '\\sqsubseteq' : ('cmsy10', 0x76),
- '\\sqsupseteq' : ('cmsy10', 0x77),
- '\\subset' : ('cmsy10', 0xbd),
- '\\subseteq' : ('cmsy10', 0xb5),
- '\\succ' : ('cmsy10', 0xc2),
- '\\succeq' : ('cmsy10', 0xba),
- '\\supset' : ('cmsy10', 0xbe),
- '\\supseteq' : ('cmsy10', 0xb6),
- '\\swarrow' : ('cmsy10', 0x2e),
- '\\times' : ('cmsy10', 0xa3),
- '\\to' : ('cmsy10', 0x21),
- '\\top' : ('cmsy10', 0x3e),
- '\\uparrow' : ('cmsy10', 0x22),
- '\\updownarrow' : ('cmsy10', 0x6c),
- '\\uplus' : ('cmsy10', 0x5d),
- '\\vdash' : ('cmsy10', 0x60),
- '\\vee' : ('cmsy10', 0x5f),
- '\\vert' : ('cmsy10', 0x6a),
- '\\wedge' : ('cmsy10', 0x5e),
- '\\wr' : ('cmsy10', 0x6f),
- '\\|' : ('cmsy10', 0x6b),
- '|' : ('cmsy10', 0x6a),
-
- '\\_' : ('cmtt10', 0x5f)
-}
-
-latex_to_cmex = {
- r'\__sqrt__' : 112,
- r'\bigcap' : 92,
- r'\bigcup' : 91,
- r'\bigodot' : 75,
- r'\bigoplus' : 77,
- r'\bigotimes' : 79,
- r'\biguplus' : 93,
- r'\bigvee' : 95,
- r'\bigwedge' : 94,
- r'\coprod' : 97,
- r'\int' : 90,
- r'\leftangle' : 173,
- r'\leftbrace' : 169,
- r'\oint' : 73,
- r'\prod' : 89,
- r'\rightangle' : 174,
- r'\rightbrace' : 170,
- r'\sum' : 88,
- r'\widehat' : 98,
- r'\widetilde' : 101,
-}
-
-latex_to_standard = {
- r'\cong' : ('psyr', 64),
- r'\Delta' : ('psyr', 68),
- r'\Phi' : ('psyr', 70),
- r'\Gamma' : ('psyr', 89),
- r'\alpha' : ('psyr', 97),
- r'\beta' : ('psyr', 98),
- r'\chi' : ('psyr', 99),
- r'\delta' : ('psyr', 100),
- r'\varepsilon' : ('psyr', 101),
- r'\phi' : ('psyr', 102),
- r'\gamma' : ('psyr', 103),
- r'\eta' : ('psyr', 104),
- r'\iota' : ('psyr', 105),
- r'\varpsi' : ('psyr', 106),
- r'\kappa' : ('psyr', 108),
- r'\nu' : ('psyr', 110),
- r'\pi' : ('psyr', 112),
- r'\theta' : ('psyr', 113),
- r'\rho' : ('psyr', 114),
- r'\sigma' : ('psyr', 115),
- r'\tau' : ('psyr', 116),
- '\\upsilon' : ('psyr', 117),
- r'\varpi' : ('psyr', 118),
- r'\omega' : ('psyr', 119),
- r'\xi' : ('psyr', 120),
- r'\psi' : ('psyr', 121),
- r'\zeta' : ('psyr', 122),
- r'\sim' : ('psyr', 126),
- r'\leq' : ('psyr', 163),
- r'\infty' : ('psyr', 165),
- r'\clubsuit' : ('psyr', 167),
- r'\diamondsuit' : ('psyr', 168),
- r'\heartsuit' : ('psyr', 169),
- r'\spadesuit' : ('psyr', 170),
- r'\leftrightarrow' : ('psyr', 171),
- r'\leftarrow' : ('psyr', 172),
- '\\uparrow' : ('psyr', 173),
- r'\rightarrow' : ('psyr', 174),
- r'\downarrow' : ('psyr', 175),
- r'\pm' : ('psyr', 176),
- r'\geq' : ('psyr', 179),
- r'\times' : ('psyr', 180),
- r'\propto' : ('psyr', 181),
- r'\partial' : ('psyr', 182),
- r'\bullet' : ('psyr', 183),
- r'\div' : ('psyr', 184),
- r'\neq' : ('psyr', 185),
- r'\equiv' : ('psyr', 186),
- r'\approx' : ('psyr', 187),
- r'\ldots' : ('psyr', 188),
- r'\aleph' : ('psyr', 192),
- r'\Im' : ('psyr', 193),
- r'\Re' : ('psyr', 194),
- r'\wp' : ('psyr', 195),
- r'\otimes' : ('psyr', 196),
- r'\oplus' : ('psyr', 197),
- r'\oslash' : ('psyr', 198),
- r'\cap' : ('psyr', 199),
- r'\cup' : ('psyr', 200),
- r'\supset' : ('psyr', 201),
- r'\supseteq' : ('psyr', 202),
- r'\subset' : ('psyr', 204),
- r'\subseteq' : ('psyr', 205),
- r'\in' : ('psyr', 206),
- r'\notin' : ('psyr', 207),
- r'\angle' : ('psyr', 208),
- r'\nabla' : ('psyr', 209),
- r'\textregistered' : ('psyr', 210),
- r'\copyright' : ('psyr', 211),
- r'\texttrademark' : ('psyr', 212),
- r'\Pi' : ('psyr', 213),
- r'\prod' : ('psyr', 213),
- r'\surd' : ('psyr', 214),
- r'\__sqrt__' : ('psyr', 214),
- r'\cdot' : ('psyr', 215),
- '\\urcorner' : ('psyr', 216),
- r'\vee' : ('psyr', 217),
- r'\wedge' : ('psyr', 218),
- r'\Leftrightarrow' : ('psyr', 219),
- r'\Leftarrow' : ('psyr', 220),
- '\\Uparrow' : ('psyr', 221),
- r'\Rightarrow' : ('psyr', 222),
- r'\Downarrow' : ('psyr', 223),
- r'\Diamond' : ('psyr', 224),
- r'\Sigma' : ('psyr', 229),
- r'\sum' : ('psyr', 229),
- r'\forall' : ('psyr', 34),
- r'\exists' : ('psyr', 36),
- r'\lceil' : ('psyr', 233),
- r'\lbrace' : ('psyr', 123),
- r'\Psi' : ('psyr', 89),
- r'\bot' : ('psyr', 0o136),
- r'\Omega' : ('psyr', 0o127),
- r'\leftbracket' : ('psyr', 0o133),
- r'\rightbracket' : ('psyr', 0o135),
- r'\leftbrace' : ('psyr', 123),
- r'\leftparen' : ('psyr', 0o50),
- r'\prime' : ('psyr', 0o242),
- r'\sharp' : ('psyr', 0o43),
- r'\slash' : ('psyr', 0o57),
- r'\Lamda' : ('psyr', 0o114),
- r'\neg' : ('psyr', 0o330),
- '\\Upsilon' : ('psyr', 0o241),
- r'\rightbrace' : ('psyr', 0o175),
- r'\rfloor' : ('psyr', 0o373),
- r'\lambda' : ('psyr', 0o154),
- r'\to' : ('psyr', 0o256),
- r'\Xi' : ('psyr', 0o130),
- r'\emptyset' : ('psyr', 0o306),
- r'\lfloor' : ('psyr', 0o353),
- r'\rightparen' : ('psyr', 0o51),
- r'\rceil' : ('psyr', 0o371),
- r'\ni' : ('psyr', 0o47),
- r'\epsilon' : ('psyr', 0o145),
- r'\Theta' : ('psyr', 0o121),
- r'\langle' : ('psyr', 0o341),
- r'\leftangle' : ('psyr', 0o341),
- r'\rangle' : ('psyr', 0o361),
- r'\rightangle' : ('psyr', 0o361),
- r'\rbrace' : ('psyr', 0o175),
- r'\circ' : ('psyr', 0o260),
- r'\diamond' : ('psyr', 0o340),
- r'\mu' : ('psyr', 0o155),
- r'\mid' : ('psyr', 0o352),
- r'\imath' : ('pncri8a', 105),
- r'\%' : ('pncr8a', 37),
- r'\$' : ('pncr8a', 36),
- r'\{' : ('pncr8a', 123),
- r'\}' : ('pncr8a', 125),
- r'\backslash' : ('pncr8a', 92),
- r'\ast' : ('pncr8a', 42),
- r'\#' : ('pncr8a', 35),
-
- r'\circumflexaccent' : ('pncri8a', 124), # for \hat
- r'\combiningbreve' : ('pncri8a', 81), # for \breve
- r'\combininggraveaccent' : ('pncri8a', 114), # for \grave
- r'\combiningacuteaccent' : ('pncri8a', 63), # for \accute
- r'\combiningdiaeresis' : ('pncri8a', 91), # for \ddot
- r'\combiningtilde' : ('pncri8a', 75), # for \tilde
- r'\combiningrightarrowabove' : ('pncri8a', 110), # for \vec
- r'\combiningdotabove' : ('pncri8a', 26), # for \dot
-}
-
-# Automatically generated.
-
-type12uni = {
- 'uni24C8' : 9416,
- 'aring' : 229,
- 'uni22A0' : 8864,
- 'uni2292' : 8850,
- 'quotedblright' : 8221,
- 'uni03D2' : 978,
- 'uni2215' : 8725,
- 'uni03D0' : 976,
- 'V' : 86,
- 'dollar' : 36,
- 'uni301E' : 12318,
- 'uni03D5' : 981,
- 'four' : 52,
- 'uni25A0' : 9632,
- 'uni013C' : 316,
- 'uni013B' : 315,
- 'uni013E' : 318,
- 'Yacute' : 221,
- 'uni25DE' : 9694,
- 'uni013F' : 319,
- 'uni255A' : 9562,
- 'uni2606' : 9734,
- 'uni0180' : 384,
- 'uni22B7' : 8887,
- 'uni044F' : 1103,
- 'uni22B5' : 8885,
- 'uni22B4' : 8884,
- 'uni22AE' : 8878,
- 'uni22B2' : 8882,
- 'uni22B1' : 8881,
- 'uni22B0' : 8880,
- 'uni25CD' : 9677,
- 'uni03CE' : 974,
- 'uni03CD' : 973,
- 'uni03CC' : 972,
- 'uni03CB' : 971,
- 'uni03CA' : 970,
- 'uni22B8' : 8888,
- 'uni22C9' : 8905,
- 'uni0449' : 1097,
- 'uni20DD' : 8413,
- 'uni20DC' : 8412,
- 'uni20DB' : 8411,
- 'uni2231' : 8753,
- 'uni25CF' : 9679,
- 'uni306E' : 12398,
- 'uni03D1' : 977,
- 'uni01A1' : 417,
- 'uni20D7' : 8407,
- 'uni03D6' : 982,
- 'uni2233' : 8755,
- 'uni20D2' : 8402,
- 'uni20D1' : 8401,
- 'uni20D0' : 8400,
- 'P' : 80,
- 'uni22BE' : 8894,
- 'uni22BD' : 8893,
- 'uni22BC' : 8892,
- 'uni22BB' : 8891,
- 'underscore' : 95,
- 'uni03C8' : 968,
- 'uni03C7' : 967,
- 'uni0328' : 808,
- 'uni03C5' : 965,
- 'uni03C4' : 964,
- 'uni03C3' : 963,
- 'uni03C2' : 962,
- 'uni03C1' : 961,
- 'uni03C0' : 960,
- 'uni2010' : 8208,
- 'uni0130' : 304,
- 'uni0133' : 307,
- 'uni0132' : 306,
- 'uni0135' : 309,
- 'uni0134' : 308,
- 'uni0137' : 311,
- 'uni0136' : 310,
- 'uni0139' : 313,
- 'uni0138' : 312,
- 'uni2244' : 8772,
- 'uni229A' : 8858,
- 'uni2571' : 9585,
- 'uni0278' : 632,
- 'uni2239' : 8761,
- 'p' : 112,
- 'uni3019' : 12313,
- 'uni25CB' : 9675,
- 'uni03DB' : 987,
- 'uni03DC' : 988,
- 'uni03DA' : 986,
- 'uni03DF' : 991,
- 'uni03DD' : 989,
- 'uni013D' : 317,
- 'uni220A' : 8714,
- 'uni220C' : 8716,
- 'uni220B' : 8715,
- 'uni220E' : 8718,
- 'uni220D' : 8717,
- 'uni220F' : 8719,
- 'uni22CC' : 8908,
- 'Otilde' : 213,
- 'uni25E5' : 9701,
- 'uni2736' : 10038,
- 'perthousand' : 8240,
- 'zero' : 48,
- 'uni279B' : 10139,
- 'dotlessi' : 305,
- 'uni2279' : 8825,
- 'Scaron' : 352,
- 'zcaron' : 382,
- 'uni21D8' : 8664,
- 'egrave' : 232,
- 'uni0271' : 625,
- 'uni01AA' : 426,
- 'uni2332' : 9010,
- 'section' : 167,
- 'uni25E4' : 9700,
- 'Icircumflex' : 206,
- 'ntilde' : 241,
- 'uni041E' : 1054,
- 'ampersand' : 38,
- 'uni041C' : 1052,
- 'uni041A' : 1050,
- 'uni22AB' : 8875,
- 'uni21DB' : 8667,
- 'dotaccent' : 729,
- 'uni0416' : 1046,
- 'uni0417' : 1047,
- 'uni0414' : 1044,
- 'uni0415' : 1045,
- 'uni0412' : 1042,
- 'uni0413' : 1043,
- 'degree' : 176,
- 'uni0411' : 1041,
- 'K' : 75,
- 'uni25EB' : 9707,
- 'uni25EF' : 9711,
- 'uni0418' : 1048,
- 'uni0419' : 1049,
- 'uni2263' : 8803,
- 'uni226E' : 8814,
- 'uni2251' : 8785,
- 'uni02C8' : 712,
- 'uni2262' : 8802,
- 'acircumflex' : 226,
- 'uni22B3' : 8883,
- 'uni2261' : 8801,
- 'uni2394' : 9108,
- 'Aring' : 197,
- 'uni2260' : 8800,
- 'uni2254' : 8788,
- 'uni0436' : 1078,
- 'uni2267' : 8807,
- 'k' : 107,
- 'uni22C8' : 8904,
- 'uni226A' : 8810,
- 'uni231F' : 8991,
- 'smalltilde' : 732,
- 'uni2201' : 8705,
- 'uni2200' : 8704,
- 'uni2203' : 8707,
- 'uni02BD' : 701,
- 'uni2205' : 8709,
- 'uni2204' : 8708,
- 'Agrave' : 192,
- 'uni2206' : 8710,
- 'uni2209' : 8713,
- 'uni2208' : 8712,
- 'uni226D' : 8813,
- 'uni2264' : 8804,
- 'uni263D' : 9789,
- 'uni2258' : 8792,
- 'uni02D3' : 723,
- 'uni02D2' : 722,
- 'uni02D1' : 721,
- 'uni02D0' : 720,
- 'uni25E1' : 9697,
- 'divide' : 247,
- 'uni02D5' : 725,
- 'uni02D4' : 724,
- 'ocircumflex' : 244,
- 'uni2524' : 9508,
- 'uni043A' : 1082,
- 'uni24CC' : 9420,
- 'asciitilde' : 126,
- 'uni22B9' : 8889,
- 'uni24D2' : 9426,
- 'uni211E' : 8478,
- 'uni211D' : 8477,
- 'uni24DD' : 9437,
- 'uni211A' : 8474,
- 'uni211C' : 8476,
- 'uni211B' : 8475,
- 'uni25C6' : 9670,
- 'uni017F' : 383,
- 'uni017A' : 378,
- 'uni017C' : 380,
- 'uni017B' : 379,
- 'uni0346' : 838,
- 'uni22F1' : 8945,
- 'uni22F0' : 8944,
- 'two' : 50,
- 'uni2298' : 8856,
- 'uni24D1' : 9425,
- 'E' : 69,
- 'uni025D' : 605,
- 'scaron' : 353,
- 'uni2322' : 8994,
- 'uni25E3' : 9699,
- 'uni22BF' : 8895,
- 'F' : 70,
- 'uni0440' : 1088,
- 'uni255E' : 9566,
- 'uni22BA' : 8890,
- 'uni0175' : 373,
- 'uni0174' : 372,
- 'uni0177' : 375,
- 'uni0176' : 374,
- 'bracketleft' : 91,
- 'uni0170' : 368,
- 'uni0173' : 371,
- 'uni0172' : 370,
- 'asciicircum' : 94,
- 'uni0179' : 377,
- 'uni2590' : 9616,
- 'uni25E2' : 9698,
- 'uni2119' : 8473,
- 'uni2118' : 8472,
- 'uni25CC' : 9676,
- 'f' : 102,
- 'ordmasculine' : 186,
- 'uni229B' : 8859,
- 'uni22A1' : 8865,
- 'uni2111' : 8465,
- 'uni2110' : 8464,
- 'uni2113' : 8467,
- 'uni2112' : 8466,
- 'mu' : 181,
- 'uni2281' : 8833,
- 'paragraph' : 182,
- 'nine' : 57,
- 'uni25EC' : 9708,
- 'v' : 118,
- 'uni040C' : 1036,
- 'uni0113' : 275,
- 'uni22D0' : 8912,
- 'uni21CC' : 8652,
- 'uni21CB' : 8651,
- 'uni21CA' : 8650,
- 'uni22A5' : 8869,
- 'uni21CF' : 8655,
- 'uni21CE' : 8654,
- 'uni21CD' : 8653,
- 'guilsinglleft' : 8249,
- 'backslash' : 92,
- 'uni2284' : 8836,
- 'uni224E' : 8782,
- 'uni224D' : 8781,
- 'uni224F' : 8783,
- 'uni224A' : 8778,
- 'uni2287' : 8839,
- 'uni224C' : 8780,
- 'uni224B' : 8779,
- 'uni21BD' : 8637,
- 'uni2286' : 8838,
- 'uni030F' : 783,
- 'uni030D' : 781,
- 'uni030E' : 782,
- 'uni030B' : 779,
- 'uni030C' : 780,
- 'uni030A' : 778,
- 'uni026E' : 622,
- 'uni026D' : 621,
- 'six' : 54,
- 'uni026A' : 618,
- 'uni026C' : 620,
- 'uni25C1' : 9665,
- 'uni20D6' : 8406,
- 'uni045B' : 1115,
- 'uni045C' : 1116,
- 'uni256B' : 9579,
- 'uni045A' : 1114,
- 'uni045F' : 1119,
- 'uni045E' : 1118,
- 'A' : 65,
- 'uni2569' : 9577,
- 'uni0458' : 1112,
- 'uni0459' : 1113,
- 'uni0452' : 1106,
- 'uni0453' : 1107,
- 'uni2562' : 9570,
- 'uni0451' : 1105,
- 'uni0456' : 1110,
- 'uni0457' : 1111,
- 'uni0454' : 1108,
- 'uni0455' : 1109,
- 'icircumflex' : 238,
- 'uni0307' : 775,
- 'uni0304' : 772,
- 'uni0305' : 773,
- 'uni0269' : 617,
- 'uni0268' : 616,
- 'uni0300' : 768,
- 'uni0301' : 769,
- 'uni0265' : 613,
- 'uni0264' : 612,
- 'uni0267' : 615,
- 'uni0266' : 614,
- 'uni0261' : 609,
- 'uni0260' : 608,
- 'uni0263' : 611,
- 'uni0262' : 610,
- 'a' : 97,
- 'uni2207' : 8711,
- 'uni2247' : 8775,
- 'uni2246' : 8774,
- 'uni2241' : 8769,
- 'uni2240' : 8768,
- 'uni2243' : 8771,
- 'uni2242' : 8770,
- 'uni2312' : 8978,
- 'ogonek' : 731,
- 'uni2249' : 8777,
- 'uni2248' : 8776,
- 'uni3030' : 12336,
- 'q' : 113,
- 'uni21C2' : 8642,
- 'uni21C1' : 8641,
- 'uni21C0' : 8640,
- 'uni21C7' : 8647,
- 'uni21C6' : 8646,
- 'uni21C5' : 8645,
- 'uni21C4' : 8644,
- 'uni225F' : 8799,
- 'uni212C' : 8492,
- 'uni21C8' : 8648,
- 'uni2467' : 9319,
- 'oacute' : 243,
- 'uni028F' : 655,
- 'uni028E' : 654,
- 'uni026F' : 623,
- 'uni028C' : 652,
- 'uni028B' : 651,
- 'uni028A' : 650,
- 'uni2510' : 9488,
- 'ograve' : 242,
- 'edieresis' : 235,
- 'uni22CE' : 8910,
- 'uni22CF' : 8911,
- 'uni219F' : 8607,
- 'comma' : 44,
- 'uni22CA' : 8906,
- 'uni0429' : 1065,
- 'uni03C6' : 966,
- 'uni0427' : 1063,
- 'uni0426' : 1062,
- 'uni0425' : 1061,
- 'uni0424' : 1060,
- 'uni0423' : 1059,
- 'uni0422' : 1058,
- 'uni0421' : 1057,
- 'uni0420' : 1056,
- 'uni2465' : 9317,
- 'uni24D0' : 9424,
- 'uni2464' : 9316,
- 'uni0430' : 1072,
- 'otilde' : 245,
- 'uni2661' : 9825,
- 'uni24D6' : 9430,
- 'uni2466' : 9318,
- 'uni24D5' : 9429,
- 'uni219A' : 8602,
- 'uni2518' : 9496,
- 'uni22B6' : 8886,
- 'uni2461' : 9313,
- 'uni24D4' : 9428,
- 'uni2460' : 9312,
- 'uni24EA' : 9450,
- 'guillemotright' : 187,
- 'ecircumflex' : 234,
- 'greater' : 62,
- 'uni2011' : 8209,
- 'uacute' : 250,
- 'uni2462' : 9314,
- 'L' : 76,
- 'bullet' : 8226,
- 'uni02A4' : 676,
- 'uni02A7' : 679,
- 'cedilla' : 184,
- 'uni02A2' : 674,
- 'uni2015' : 8213,
- 'uni22C4' : 8900,
- 'uni22C5' : 8901,
- 'uni22AD' : 8877,
- 'uni22C7' : 8903,
- 'uni22C0' : 8896,
- 'uni2016' : 8214,
- 'uni22C2' : 8898,
- 'uni22C3' : 8899,
- 'uni24CF' : 9423,
- 'uni042F' : 1071,
- 'uni042E' : 1070,
- 'uni042D' : 1069,
- 'ydieresis' : 255,
- 'l' : 108,
- 'logicalnot' : 172,
- 'uni24CA' : 9418,
- 'uni0287' : 647,
- 'uni0286' : 646,
- 'uni0285' : 645,
- 'uni0284' : 644,
- 'uni0283' : 643,
- 'uni0282' : 642,
- 'uni0281' : 641,
- 'uni027C' : 636,
- 'uni2664' : 9828,
- 'exclamdown' : 161,
- 'uni25C4' : 9668,
- 'uni0289' : 649,
- 'uni0288' : 648,
- 'uni039A' : 922,
- 'endash' : 8211,
- 'uni2640' : 9792,
- 'uni20E4' : 8420,
- 'uni0473' : 1139,
- 'uni20E1' : 8417,
- 'uni2642' : 9794,
- 'uni03B8' : 952,
- 'uni03B9' : 953,
- 'agrave' : 224,
- 'uni03B4' : 948,
- 'uni03B5' : 949,
- 'uni03B6' : 950,
- 'uni03B7' : 951,
- 'uni03B0' : 944,
- 'uni03B1' : 945,
- 'uni03B2' : 946,
- 'uni03B3' : 947,
- 'uni2555' : 9557,
- 'Adieresis' : 196,
- 'germandbls' : 223,
- 'Odieresis' : 214,
- 'space' : 32,
- 'uni0126' : 294,
- 'uni0127' : 295,
- 'uni0124' : 292,
- 'uni0125' : 293,
- 'uni0122' : 290,
- 'uni0123' : 291,
- 'uni0120' : 288,
- 'uni0121' : 289,
- 'quoteright' : 8217,
- 'uni2560' : 9568,
- 'uni2556' : 9558,
- 'ucircumflex' : 251,
- 'uni2561' : 9569,
- 'uni2551' : 9553,
- 'uni25B2' : 9650,
- 'uni2550' : 9552,
- 'uni2563' : 9571,
- 'uni2553' : 9555,
- 'G' : 71,
- 'uni2564' : 9572,
- 'uni2552' : 9554,
- 'quoteleft' : 8216,
- 'uni2565' : 9573,
- 'uni2572' : 9586,
- 'uni2568' : 9576,
- 'uni2566' : 9574,
- 'W' : 87,
- 'uni214A' : 8522,
- 'uni012F' : 303,
- 'uni012D' : 301,
- 'uni012E' : 302,
- 'uni012B' : 299,
- 'uni012C' : 300,
- 'uni255C' : 9564,
- 'uni012A' : 298,
- 'uni2289' : 8841,
- 'Q' : 81,
- 'uni2320' : 8992,
- 'uni2321' : 8993,
- 'g' : 103,
- 'uni03BD' : 957,
- 'uni03BE' : 958,
- 'uni03BF' : 959,
- 'uni2282' : 8834,
- 'uni2285' : 8837,
- 'uni03BA' : 954,
- 'uni03BB' : 955,
- 'uni03BC' : 956,
- 'uni2128' : 8488,
- 'uni25B7' : 9655,
- 'w' : 119,
- 'uni0302' : 770,
- 'uni03DE' : 990,
- 'uni25DA' : 9690,
- 'uni0303' : 771,
- 'uni0463' : 1123,
- 'uni0462' : 1122,
- 'uni3018' : 12312,
- 'uni2514' : 9492,
- 'question' : 63,
- 'uni25B3' : 9651,
- 'uni24E1' : 9441,
- 'one' : 49,
- 'uni200A' : 8202,
- 'uni2278' : 8824,
- 'ring' : 730,
- 'uni0195' : 405,
- 'figuredash' : 8210,
- 'uni22EC' : 8940,
- 'uni0339' : 825,
- 'uni0338' : 824,
- 'uni0337' : 823,
- 'uni0336' : 822,
- 'uni0335' : 821,
- 'uni0333' : 819,
- 'uni0332' : 818,
- 'uni0331' : 817,
- 'uni0330' : 816,
- 'uni01C1' : 449,
- 'uni01C0' : 448,
- 'uni01C3' : 451,
- 'uni01C2' : 450,
- 'uni2353' : 9043,
- 'uni0308' : 776,
- 'uni2218' : 8728,
- 'uni2219' : 8729,
- 'uni2216' : 8726,
- 'uni2217' : 8727,
- 'uni2214' : 8724,
- 'uni0309' : 777,
- 'uni2609' : 9737,
- 'uni2213' : 8723,
- 'uni2210' : 8720,
- 'uni2211' : 8721,
- 'uni2245' : 8773,
- 'B' : 66,
- 'uni25D6' : 9686,
- 'iacute' : 237,
- 'uni02E6' : 742,
- 'uni02E7' : 743,
- 'uni02E8' : 744,
- 'uni02E9' : 745,
- 'uni221D' : 8733,
- 'uni221E' : 8734,
- 'Ydieresis' : 376,
- 'uni221C' : 8732,
- 'uni22D7' : 8919,
- 'uni221A' : 8730,
- 'R' : 82,
- 'uni24DC' : 9436,
- 'uni033F' : 831,
- 'uni033E' : 830,
- 'uni033C' : 828,
- 'uni033B' : 827,
- 'uni033A' : 826,
- 'b' : 98,
- 'uni228A' : 8842,
- 'uni22DB' : 8923,
- 'uni2554' : 9556,
- 'uni046B' : 1131,
- 'uni046A' : 1130,
- 'r' : 114,
- 'uni24DB' : 9435,
- 'Ccedilla' : 199,
- 'minus' : 8722,
- 'uni24DA' : 9434,
- 'uni03F0' : 1008,
- 'uni03F1' : 1009,
- 'uni20AC' : 8364,
- 'uni2276' : 8822,
- 'uni24C0' : 9408,
- 'uni0162' : 354,
- 'uni0163' : 355,
- 'uni011E' : 286,
- 'uni011D' : 285,
- 'uni011C' : 284,
- 'uni011B' : 283,
- 'uni0164' : 356,
- 'uni0165' : 357,
- 'Lslash' : 321,
- 'uni0168' : 360,
- 'uni0169' : 361,
- 'uni25C9' : 9673,
- 'uni02E5' : 741,
- 'uni21C3' : 8643,
- 'uni24C4' : 9412,
- 'uni24E2' : 9442,
- 'uni2277' : 8823,
- 'uni013A' : 314,
- 'uni2102' : 8450,
- 'Uacute' : 218,
- 'uni2317' : 8983,
- 'uni2107' : 8455,
- 'uni221F' : 8735,
- 'yacute' : 253,
- 'uni3012' : 12306,
- 'Ucircumflex' : 219,
- 'uni015D' : 349,
- 'quotedbl' : 34,
- 'uni25D9' : 9689,
- 'uni2280' : 8832,
- 'uni22AF' : 8879,
- 'onehalf' : 189,
- 'uni221B' : 8731,
- 'Thorn' : 222,
- 'uni2226' : 8742,
- 'M' : 77,
- 'uni25BA' : 9658,
- 'uni2463' : 9315,
- 'uni2336' : 9014,
- 'eight' : 56,
- 'uni2236' : 8758,
- 'multiply' : 215,
- 'uni210C' : 8460,
- 'uni210A' : 8458,
- 'uni21C9' : 8649,
- 'grave' : 96,
- 'uni210E' : 8462,
- 'uni0117' : 279,
- 'uni016C' : 364,
- 'uni0115' : 277,
- 'uni016A' : 362,
- 'uni016F' : 367,
- 'uni0112' : 274,
- 'uni016D' : 365,
- 'uni016E' : 366,
- 'Ocircumflex' : 212,
- 'uni2305' : 8965,
- 'm' : 109,
- 'uni24DF' : 9439,
- 'uni0119' : 281,
- 'uni0118' : 280,
- 'uni20A3' : 8355,
- 'uni20A4' : 8356,
- 'uni20A7' : 8359,
- 'uni2288' : 8840,
- 'uni24C3' : 9411,
- 'uni251C' : 9500,
- 'uni228D' : 8845,
- 'uni222F' : 8751,
- 'uni222E' : 8750,
- 'uni222D' : 8749,
- 'uni222C' : 8748,
- 'uni222B' : 8747,
- 'uni222A' : 8746,
- 'uni255B' : 9563,
- 'Ugrave' : 217,
- 'uni24DE' : 9438,
- 'guilsinglright' : 8250,
- 'uni250A' : 9482,
- 'Ntilde' : 209,
- 'uni0279' : 633,
- 'questiondown' : 191,
- 'uni256C' : 9580,
- 'Atilde' : 195,
- 'uni0272' : 626,
- 'uni0273' : 627,
- 'uni0270' : 624,
- 'ccedilla' : 231,
- 'uni0276' : 630,
- 'uni0277' : 631,
- 'uni0274' : 628,
- 'uni0275' : 629,
- 'uni2252' : 8786,
- 'uni041F' : 1055,
- 'uni2250' : 8784,
- 'Z' : 90,
- 'uni2256' : 8790,
- 'uni2257' : 8791,
- 'copyright' : 169,
- 'uni2255' : 8789,
- 'uni043D' : 1085,
- 'uni043E' : 1086,
- 'uni043F' : 1087,
- 'yen' : 165,
- 'uni041D' : 1053,
- 'uni043B' : 1083,
- 'uni043C' : 1084,
- 'uni21B0' : 8624,
- 'uni21B1' : 8625,
- 'uni21B2' : 8626,
- 'uni21B3' : 8627,
- 'uni21B4' : 8628,
- 'uni21B5' : 8629,
- 'uni21B6' : 8630,
- 'uni21B7' : 8631,
- 'uni21B8' : 8632,
- 'Eacute' : 201,
- 'uni2311' : 8977,
- 'uni2310' : 8976,
- 'uni228F' : 8847,
- 'uni25DB' : 9691,
- 'uni21BA' : 8634,
- 'uni21BB' : 8635,
- 'uni21BC' : 8636,
- 'uni2017' : 8215,
- 'uni21BE' : 8638,
- 'uni21BF' : 8639,
- 'uni231C' : 8988,
- 'H' : 72,
- 'uni0293' : 659,
- 'uni2202' : 8706,
- 'uni22A4' : 8868,
- 'uni231E' : 8990,
- 'uni2232' : 8754,
- 'uni225B' : 8795,
- 'uni225C' : 8796,
- 'uni24D9' : 9433,
- 'uni225A' : 8794,
- 'uni0438' : 1080,
- 'uni0439' : 1081,
- 'uni225D' : 8797,
- 'uni225E' : 8798,
- 'uni0434' : 1076,
- 'X' : 88,
- 'uni007F' : 127,
- 'uni0437' : 1079,
- 'Idieresis' : 207,
- 'uni0431' : 1073,
- 'uni0432' : 1074,
- 'uni0433' : 1075,
- 'uni22AC' : 8876,
- 'uni22CD' : 8909,
- 'uni25A3' : 9635,
- 'bar' : 124,
- 'uni24BB' : 9403,
- 'uni037E' : 894,
- 'uni027B' : 635,
- 'h' : 104,
- 'uni027A' : 634,
- 'uni027F' : 639,
- 'uni027D' : 637,
- 'uni027E' : 638,
- 'uni2227' : 8743,
- 'uni2004' : 8196,
- 'uni2225' : 8741,
- 'uni2224' : 8740,
- 'uni2223' : 8739,
- 'uni2222' : 8738,
- 'uni2221' : 8737,
- 'uni2220' : 8736,
- 'x' : 120,
- 'uni2323' : 8995,
- 'uni2559' : 9561,
- 'uni2558' : 9560,
- 'uni2229' : 8745,
- 'uni2228' : 8744,
- 'udieresis' : 252,
- 'uni029D' : 669,
- 'ordfeminine' : 170,
- 'uni22CB' : 8907,
- 'uni233D' : 9021,
- 'uni0428' : 1064,
- 'uni24C6' : 9414,
- 'uni22DD' : 8925,
- 'uni24C7' : 9415,
- 'uni015C' : 348,
- 'uni015B' : 347,
- 'uni015A' : 346,
- 'uni22AA' : 8874,
- 'uni015F' : 351,
- 'uni015E' : 350,
- 'braceleft' : 123,
- 'uni24C5' : 9413,
- 'uni0410' : 1040,
- 'uni03AA' : 938,
- 'uni24C2' : 9410,
- 'uni03AC' : 940,
- 'uni03AB' : 939,
- 'macron' : 175,
- 'uni03AD' : 941,
- 'uni03AF' : 943,
- 'uni0294' : 660,
- 'uni0295' : 661,
- 'uni0296' : 662,
- 'uni0297' : 663,
- 'uni0290' : 656,
- 'uni0291' : 657,
- 'uni0292' : 658,
- 'atilde' : 227,
- 'Acircumflex' : 194,
- 'uni2370' : 9072,
- 'uni24C1' : 9409,
- 'uni0298' : 664,
- 'uni0299' : 665,
- 'Oslash' : 216,
- 'uni029E' : 670,
- 'C' : 67,
- 'quotedblleft' : 8220,
- 'uni029B' : 667,
- 'uni029C' : 668,
- 'uni03A9' : 937,
- 'uni03A8' : 936,
- 'S' : 83,
- 'uni24C9' : 9417,
- 'uni03A1' : 929,
- 'uni03A0' : 928,
- 'exclam' : 33,
- 'uni03A5' : 933,
- 'uni03A4' : 932,
- 'uni03A7' : 935,
- 'Zcaron' : 381,
- 'uni2133' : 8499,
- 'uni2132' : 8498,
- 'uni0159' : 345,
- 'uni0158' : 344,
- 'uni2137' : 8503,
- 'uni2005' : 8197,
- 'uni2135' : 8501,
- 'uni2134' : 8500,
- 'uni02BA' : 698,
- 'uni2033' : 8243,
- 'uni0151' : 337,
- 'uni0150' : 336,
- 'uni0157' : 343,
- 'equal' : 61,
- 'uni0155' : 341,
- 'uni0154' : 340,
- 's' : 115,
- 'uni233F' : 9023,
- 'eth' : 240,
- 'uni24BE' : 9406,
- 'uni21E9' : 8681,
- 'uni2060' : 8288,
- 'Egrave' : 200,
- 'uni255D' : 9565,
- 'uni24CD' : 9421,
- 'uni21E1' : 8673,
- 'uni21B9' : 8633,
- 'hyphen' : 45,
- 'uni01BE' : 446,
- 'uni01BB' : 443,
- 'period' : 46,
- 'igrave' : 236,
- 'uni01BA' : 442,
- 'uni2296' : 8854,
- 'uni2297' : 8855,
- 'uni2294' : 8852,
- 'uni2295' : 8853,
- 'colon' : 58,
- 'uni2293' : 8851,
- 'uni2290' : 8848,
- 'uni2291' : 8849,
- 'uni032D' : 813,
- 'uni032E' : 814,
- 'uni032F' : 815,
- 'uni032A' : 810,
- 'uni032B' : 811,
- 'uni032C' : 812,
- 'uni231D' : 8989,
- 'Ecircumflex' : 202,
- 'uni24D7' : 9431,
- 'uni25DD' : 9693,
- 'trademark' : 8482,
- 'Aacute' : 193,
- 'cent' : 162,
- 'uni0445' : 1093,
- 'uni266E' : 9838,
- 'uni266D' : 9837,
- 'uni266B' : 9835,
- 'uni03C9' : 969,
- 'uni2003' : 8195,
- 'uni2047' : 8263,
- 'lslash' : 322,
- 'uni03A6' : 934,
- 'uni2043' : 8259,
- 'uni250C' : 9484,
- 'uni2040' : 8256,
- 'uni255F' : 9567,
- 'uni24CB' : 9419,
- 'uni0472' : 1138,
- 'uni0446' : 1094,
- 'uni0474' : 1140,
- 'uni0475' : 1141,
- 'uni2508' : 9480,
- 'uni2660' : 9824,
- 'uni2506' : 9478,
- 'uni2502' : 9474,
- 'c' : 99,
- 'uni2500' : 9472,
- 'N' : 78,
- 'uni22A6' : 8870,
- 'uni21E7' : 8679,
- 'uni2130' : 8496,
- 'uni2002' : 8194,
- 'breve' : 728,
- 'uni0442' : 1090,
- 'Oacute' : 211,
- 'uni229F' : 8863,
- 'uni25C7' : 9671,
- 'uni229D' : 8861,
- 'uni229E' : 8862,
- 'guillemotleft' : 171,
- 'uni0329' : 809,
- 'uni24E5' : 9445,
- 'uni011F' : 287,
- 'uni0324' : 804,
- 'uni0325' : 805,
- 'uni0326' : 806,
- 'uni0327' : 807,
- 'uni0321' : 801,
- 'uni0322' : 802,
- 'n' : 110,
- 'uni2032' : 8242,
- 'uni2269' : 8809,
- 'uni2268' : 8808,
- 'uni0306' : 774,
- 'uni226B' : 8811,
- 'uni21EA' : 8682,
- 'uni0166' : 358,
- 'uni203B' : 8251,
- 'uni01B5' : 437,
- 'idieresis' : 239,
- 'uni02BC' : 700,
- 'uni01B0' : 432,
- 'braceright' : 125,
- 'seven' : 55,
- 'uni02BB' : 699,
- 'uni011A' : 282,
- 'uni29FB' : 10747,
- 'brokenbar' : 166,
- 'uni2036' : 8246,
- 'uni25C0' : 9664,
- 'uni0156' : 342,
- 'uni22D5' : 8917,
- 'uni0258' : 600,
- 'ugrave' : 249,
- 'uni22D6' : 8918,
- 'uni22D1' : 8913,
- 'uni2034' : 8244,
- 'uni22D3' : 8915,
- 'uni22D2' : 8914,
- 'uni203C' : 8252,
- 'uni223E' : 8766,
- 'uni02BF' : 703,
- 'uni22D9' : 8921,
- 'uni22D8' : 8920,
- 'uni25BD' : 9661,
- 'uni25BE' : 9662,
- 'uni25BF' : 9663,
- 'uni041B' : 1051,
- 'periodcentered' : 183,
- 'uni25BC' : 9660,
- 'uni019E' : 414,
- 'uni019B' : 411,
- 'uni019A' : 410,
- 'uni2007' : 8199,
- 'uni0391' : 913,
- 'uni0390' : 912,
- 'uni0393' : 915,
- 'uni0392' : 914,
- 'uni0395' : 917,
- 'uni0394' : 916,
- 'uni0397' : 919,
- 'uni0396' : 918,
- 'uni0399' : 921,
- 'uni0398' : 920,
- 'uni25C8' : 9672,
- 'uni2468' : 9320,
- 'sterling' : 163,
- 'uni22EB' : 8939,
- 'uni039C' : 924,
- 'uni039B' : 923,
- 'uni039E' : 926,
- 'uni039D' : 925,
- 'uni039F' : 927,
- 'I' : 73,
- 'uni03E1' : 993,
- 'uni03E0' : 992,
- 'uni2319' : 8985,
- 'uni228B' : 8843,
- 'uni25B5' : 9653,
- 'uni25B6' : 9654,
- 'uni22EA' : 8938,
- 'uni24B9' : 9401,
- 'uni044E' : 1102,
- 'uni0199' : 409,
- 'uni2266' : 8806,
- 'Y' : 89,
- 'uni22A2' : 8866,
- 'Eth' : 208,
- 'uni266F' : 9839,
- 'emdash' : 8212,
- 'uni263B' : 9787,
- 'uni24BD' : 9405,
- 'uni22DE' : 8926,
- 'uni0360' : 864,
- 'uni2557' : 9559,
- 'uni22DF' : 8927,
- 'uni22DA' : 8922,
- 'uni22DC' : 8924,
- 'uni0361' : 865,
- 'i' : 105,
- 'uni24BF' : 9407,
- 'uni0362' : 866,
- 'uni263E' : 9790,
- 'uni028D' : 653,
- 'uni2259' : 8793,
- 'uni0323' : 803,
- 'uni2265' : 8805,
- 'daggerdbl' : 8225,
- 'y' : 121,
- 'uni010A' : 266,
- 'plusminus' : 177,
- 'less' : 60,
- 'uni21AE' : 8622,
- 'uni0315' : 789,
- 'uni230B' : 8971,
- 'uni21AF' : 8623,
- 'uni21AA' : 8618,
- 'uni21AC' : 8620,
- 'uni21AB' : 8619,
- 'uni01FB' : 507,
- 'uni01FC' : 508,
- 'uni223A' : 8762,
- 'uni01FA' : 506,
- 'uni01FF' : 511,
- 'uni01FD' : 509,
- 'uni01FE' : 510,
- 'uni2567' : 9575,
- 'uni25E0' : 9696,
- 'uni0104' : 260,
- 'uni0105' : 261,
- 'uni0106' : 262,
- 'uni0107' : 263,
- 'uni0100' : 256,
- 'uni0101' : 257,
- 'uni0102' : 258,
- 'uni0103' : 259,
- 'uni2038' : 8248,
- 'uni2009' : 8201,
- 'uni2008' : 8200,
- 'uni0108' : 264,
- 'uni0109' : 265,
- 'uni02A1' : 673,
- 'uni223B' : 8763,
- 'uni226C' : 8812,
- 'uni25AC' : 9644,
- 'uni24D3' : 9427,
- 'uni21E0' : 8672,
- 'uni21E3' : 8675,
- 'Udieresis' : 220,
- 'uni21E2' : 8674,
- 'D' : 68,
- 'uni21E5' : 8677,
- 'uni2621' : 9761,
- 'uni21D1' : 8657,
- 'uni203E' : 8254,
- 'uni22C6' : 8902,
- 'uni21E4' : 8676,
- 'uni010D' : 269,
- 'uni010E' : 270,
- 'uni010F' : 271,
- 'five' : 53,
- 'T' : 84,
- 'uni010B' : 267,
- 'uni010C' : 268,
- 'uni2605' : 9733,
- 'uni2663' : 9827,
- 'uni21E6' : 8678,
- 'uni24B6' : 9398,
- 'uni22C1' : 8897,
- 'oslash' : 248,
- 'acute' : 180,
- 'uni01F0' : 496,
- 'd' : 100,
- 'OE' : 338,
- 'uni22E3' : 8931,
- 'Igrave' : 204,
- 'uni2308' : 8968,
- 'uni2309' : 8969,
- 'uni21A9' : 8617,
- 't' : 116,
- 'uni2313' : 8979,
- 'uni03A3' : 931,
- 'uni21A4' : 8612,
- 'uni21A7' : 8615,
- 'uni21A6' : 8614,
- 'uni21A1' : 8609,
- 'uni21A0' : 8608,
- 'uni21A3' : 8611,
- 'uni21A2' : 8610,
- 'parenright' : 41,
- 'uni256A' : 9578,
- 'uni25DC' : 9692,
- 'uni24CE' : 9422,
- 'uni042C' : 1068,
- 'uni24E0' : 9440,
- 'uni042B' : 1067,
- 'uni0409' : 1033,
- 'uni0408' : 1032,
- 'uni24E7' : 9447,
- 'uni25B4' : 9652,
- 'uni042A' : 1066,
- 'uni228E' : 8846,
- 'uni0401' : 1025,
- 'adieresis' : 228,
- 'uni0403' : 1027,
- 'quotesingle' : 39,
- 'uni0405' : 1029,
- 'uni0404' : 1028,
- 'uni0407' : 1031,
- 'uni0406' : 1030,
- 'uni229C' : 8860,
- 'uni2306' : 8966,
- 'uni2253' : 8787,
- 'twodotenleader' : 8229,
- 'uni2131' : 8497,
- 'uni21DA' : 8666,
- 'uni2234' : 8756,
- 'uni2235' : 8757,
- 'uni01A5' : 421,
- 'uni2237' : 8759,
- 'uni2230' : 8752,
- 'uni02CC' : 716,
- 'slash' : 47,
- 'uni01A0' : 416,
- 'ellipsis' : 8230,
- 'uni2299' : 8857,
- 'uni2238' : 8760,
- 'numbersign' : 35,
- 'uni21A8' : 8616,
- 'uni223D' : 8765,
- 'uni01AF' : 431,
- 'uni223F' : 8767,
- 'uni01AD' : 429,
- 'uni01AB' : 427,
- 'odieresis' : 246,
- 'uni223C' : 8764,
- 'uni227D' : 8829,
- 'uni0280' : 640,
- 'O' : 79,
- 'uni227E' : 8830,
- 'uni21A5' : 8613,
- 'uni22D4' : 8916,
- 'uni25D4' : 9684,
- 'uni227F' : 8831,
- 'uni0435' : 1077,
- 'uni2302' : 8962,
- 'uni2669' : 9833,
- 'uni24E3' : 9443,
- 'uni2720' : 10016,
- 'uni22A8' : 8872,
- 'uni22A9' : 8873,
- 'uni040A' : 1034,
- 'uni22A7' : 8871,
- 'oe' : 339,
- 'uni040B' : 1035,
- 'uni040E' : 1038,
- 'uni22A3' : 8867,
- 'o' : 111,
- 'uni040F' : 1039,
- 'Edieresis' : 203,
- 'uni25D5' : 9685,
- 'plus' : 43,
- 'uni044D' : 1101,
- 'uni263C' : 9788,
- 'uni22E6' : 8934,
- 'uni2283' : 8835,
- 'uni258C' : 9612,
- 'uni219E' : 8606,
- 'uni24E4' : 9444,
- 'uni2136' : 8502,
- 'dagger' : 8224,
- 'uni24B7' : 9399,
- 'uni219B' : 8603,
- 'uni22E5' : 8933,
- 'three' : 51,
- 'uni210B' : 8459,
- 'uni2534' : 9524,
- 'uni24B8' : 9400,
- 'uni230A' : 8970,
- 'hungarumlaut' : 733,
- 'parenleft' : 40,
- 'uni0148' : 328,
- 'uni0149' : 329,
- 'uni2124' : 8484,
- 'uni2125' : 8485,
- 'uni2126' : 8486,
- 'uni2127' : 8487,
- 'uni0140' : 320,
- 'uni2129' : 8489,
- 'uni25C5' : 9669,
- 'uni0143' : 323,
- 'uni0144' : 324,
- 'uni0145' : 325,
- 'uni0146' : 326,
- 'uni0147' : 327,
- 'uni210D' : 8461,
- 'fraction' : 8260,
- 'uni2031' : 8241,
- 'uni2196' : 8598,
- 'uni2035' : 8245,
- 'uni24E6' : 9446,
- 'uni016B' : 363,
- 'uni24BA' : 9402,
- 'uni266A' : 9834,
- 'uni0116' : 278,
- 'uni2115' : 8469,
- 'registered' : 174,
- 'J' : 74,
- 'uni25DF' : 9695,
- 'uni25CE' : 9678,
- 'uni273D' : 10045,
- 'dieresis' : 168,
- 'uni212B' : 8491,
- 'uni0114' : 276,
- 'uni212D' : 8493,
- 'uni212E' : 8494,
- 'uni212F' : 8495,
- 'uni014A' : 330,
- 'uni014B' : 331,
- 'uni014C' : 332,
- 'uni014D' : 333,
- 'uni014E' : 334,
- 'uni014F' : 335,
- 'uni025E' : 606,
- 'uni24E8' : 9448,
- 'uni0111' : 273,
- 'uni24E9' : 9449,
- 'Ograve' : 210,
- 'j' : 106,
- 'uni2195' : 8597,
- 'uni2194' : 8596,
- 'uni2197' : 8599,
- 'uni2037' : 8247,
- 'uni2191' : 8593,
- 'uni2190' : 8592,
- 'uni2193' : 8595,
- 'uni2192' : 8594,
- 'uni29FA' : 10746,
- 'uni2713' : 10003,
- 'z' : 122,
- 'uni2199' : 8601,
- 'uni2198' : 8600,
- 'uni2667' : 9831,
- 'ae' : 230,
- 'uni0448' : 1096,
- 'semicolon' : 59,
- 'uni2666' : 9830,
- 'uni038F' : 911,
- 'uni0444' : 1092,
- 'uni0447' : 1095,
- 'uni038E' : 910,
- 'uni0441' : 1089,
- 'uni038C' : 908,
- 'uni0443' : 1091,
- 'uni038A' : 906,
- 'uni0250' : 592,
- 'uni0251' : 593,
- 'uni0252' : 594,
- 'uni0253' : 595,
- 'uni0254' : 596,
- 'at' : 64,
- 'uni0256' : 598,
- 'uni0257' : 599,
- 'uni0167' : 359,
- 'uni0259' : 601,
- 'uni228C' : 8844,
- 'uni2662' : 9826,
- 'uni0319' : 793,
- 'uni0318' : 792,
- 'uni24BC' : 9404,
- 'uni0402' : 1026,
- 'uni22EF' : 8943,
- 'Iacute' : 205,
- 'uni22ED' : 8941,
- 'uni22EE' : 8942,
- 'uni0311' : 785,
- 'uni0310' : 784,
- 'uni21E8' : 8680,
- 'uni0312' : 786,
- 'percent' : 37,
- 'uni0317' : 791,
- 'uni0316' : 790,
- 'uni21D6' : 8662,
- 'uni21D7' : 8663,
- 'uni21D4' : 8660,
- 'uni21D5' : 8661,
- 'uni21D2' : 8658,
- 'uni21D3' : 8659,
- 'uni21D0' : 8656,
- 'uni2138' : 8504,
- 'uni2270' : 8816,
- 'uni2271' : 8817,
- 'uni2272' : 8818,
- 'uni2273' : 8819,
- 'uni2274' : 8820,
- 'uni2275' : 8821,
- 'bracketright' : 93,
- 'uni21D9' : 8665,
- 'uni21DF' : 8671,
- 'uni21DD' : 8669,
- 'uni21DE' : 8670,
- 'AE' : 198,
- 'uni03AE' : 942,
- 'uni227A' : 8826,
- 'uni227B' : 8827,
- 'uni227C' : 8828,
- 'asterisk' : 42,
- 'aacute' : 225,
- 'uni226F' : 8815,
- 'uni22E2' : 8930,
- 'uni0386' : 902,
- 'uni22E0' : 8928,
- 'uni22E1' : 8929,
- 'U' : 85,
- 'uni22E7' : 8935,
- 'uni22E4' : 8932,
- 'uni0387' : 903,
- 'uni031A' : 794,
- 'eacute' : 233,
- 'uni22E8' : 8936,
- 'uni22E9' : 8937,
- 'uni24D8' : 9432,
- 'uni025A' : 602,
- 'uni025B' : 603,
- 'uni025C' : 604,
- 'e' : 101,
- 'uni0128' : 296,
- 'uni025F' : 607,
- 'uni2665' : 9829,
- 'thorn' : 254,
- 'uni0129' : 297,
- 'uni253C' : 9532,
- 'uni25D7' : 9687,
- 'u' : 117,
- 'uni0388' : 904,
- 'uni0389' : 905,
- 'uni0255' : 597,
- 'uni0171' : 369,
- 'uni0384' : 900,
- 'uni0385' : 901,
- 'uni044A' : 1098,
- 'uni252C' : 9516,
- 'uni044C' : 1100,
- 'uni044B' : 1099
-}
-
-uni2type1 = dict(((v,k) for k,v in six.iteritems(type12uni)))
-
-tex2uni = {
- 'widehat' : 0x0302,
- 'widetilde' : 0x0303,
- 'widebar' : 0x0305,
- 'langle' : 0x27e8,
- 'rangle' : 0x27e9,
- 'perp' : 0x27c2,
- 'neq' : 0x2260,
- 'Join' : 0x2a1d,
- 'leqslant' : 0x2a7d,
- 'geqslant' : 0x2a7e,
- 'lessapprox' : 0x2a85,
- 'gtrapprox' : 0x2a86,
- 'lesseqqgtr' : 0x2a8b,
- 'gtreqqless' : 0x2a8c,
- 'triangleeq' : 0x225c,
- 'eqslantless' : 0x2a95,
- 'eqslantgtr' : 0x2a96,
- 'backepsilon' : 0x03f6,
- 'precapprox' : 0x2ab7,
- 'succapprox' : 0x2ab8,
- 'fallingdotseq' : 0x2252,
- 'subseteqq' : 0x2ac5,
- 'supseteqq' : 0x2ac6,
- 'varpropto' : 0x221d,
- 'precnapprox' : 0x2ab9,
- 'succnapprox' : 0x2aba,
- 'subsetneqq' : 0x2acb,
- 'supsetneqq' : 0x2acc,
- 'lnapprox' : 0x2ab9,
- 'gnapprox' : 0x2aba,
- 'longleftarrow' : 0x27f5,
- 'longrightarrow' : 0x27f6,
- 'longleftrightarrow' : 0x27f7,
- 'Longleftarrow' : 0x27f8,
- 'Longrightarrow' : 0x27f9,
- 'Longleftrightarrow' : 0x27fa,
- 'longmapsto' : 0x27fc,
- 'leadsto' : 0x21dd,
- 'dashleftarrow' : 0x290e,
- 'dashrightarrow' : 0x290f,
- 'circlearrowleft' : 0x21ba,
- 'circlearrowright' : 0x21bb,
- 'leftrightsquigarrow' : 0x21ad,
- 'leftsquigarrow' : 0x219c,
- 'rightsquigarrow' : 0x219d,
- 'Game' : 0x2141,
- 'hbar' : 0x0127,
- 'hslash' : 0x210f,
- 'ldots' : 0x2026,
- 'vdots' : 0x22ee,
- 'doteqdot' : 0x2251,
- 'doteq' : 8784,
- 'partial' : 8706,
- 'gg' : 8811,
- 'asymp' : 8781,
- 'blacktriangledown' : 9662,
- 'otimes' : 8855,
- 'nearrow' : 8599,
- 'varpi' : 982,
- 'vee' : 8744,
- 'vec' : 8407,
- 'smile' : 8995,
- 'succnsim' : 8937,
- 'gimel' : 8503,
- 'vert' : 124,
- '|' : 124,
- 'varrho' : 1009,
- 'P' : 182,
- 'approxident' : 8779,
- 'Swarrow' : 8665,
- 'textasciicircum' : 94,
- 'imageof' : 8887,
- 'ntriangleleft' : 8938,
- 'nleq' : 8816,
- 'div' : 247,
- 'nparallel' : 8742,
- 'Leftarrow' : 8656,
- 'lll' : 8920,
- 'oiint' : 8751,
- 'ngeq' : 8817,
- 'Theta' : 920,
- 'origof' : 8886,
- 'blacksquare' : 9632,
- 'solbar' : 9023,
- 'neg' : 172,
- 'sum' : 8721,
- 'Vdash' : 8873,
- 'coloneq' : 8788,
- 'degree' : 176,
- 'bowtie' : 8904,
- 'blacktriangleright' : 9654,
- 'varsigma' : 962,
- 'leq' : 8804,
- 'ggg' : 8921,
- 'lneqq' : 8808,
- 'scurel' : 8881,
- 'stareq' : 8795,
- 'BbbN' : 8469,
- 'nLeftarrow' : 8653,
- 'nLeftrightarrow' : 8654,
- 'k' : 808,
- 'bot' : 8869,
- 'BbbC' : 8450,
- 'Lsh' : 8624,
- 'leftleftarrows' : 8647,
- 'BbbZ' : 8484,
- 'digamma' : 989,
- 'BbbR' : 8477,
- 'BbbP' : 8473,
- 'BbbQ' : 8474,
- 'vartriangleright' : 8883,
- 'succsim' : 8831,
- 'wedge' : 8743,
- 'lessgtr' : 8822,
- 'veebar' : 8891,
- 'mapsdown' : 8615,
- 'Rsh' : 8625,
- 'chi' : 967,
- 'prec' : 8826,
- 'nsubseteq' : 8840,
- 'therefore' : 8756,
- 'eqcirc' : 8790,
- 'textexclamdown' : 161,
- 'nRightarrow' : 8655,
- 'flat' : 9837,
- 'notin' : 8713,
- 'llcorner' : 8990,
- 'varepsilon' : 949,
- 'bigtriangleup' : 9651,
- 'aleph' : 8501,
- 'dotminus' : 8760,
- 'upsilon' : 965,
- 'Lambda' : 923,
- 'cap' : 8745,
- 'barleftarrow' : 8676,
- 'mu' : 956,
- 'boxplus' : 8862,
- 'mp' : 8723,
- 'circledast' : 8859,
- 'tau' : 964,
- 'in' : 8712,
- 'backslash' : 92,
- 'varnothing' : 8709,
- 'sharp' : 9839,
- 'eqsim' : 8770,
- 'gnsim' : 8935,
- 'Searrow' : 8664,
- 'updownarrows' : 8645,
- 'heartsuit' : 9825,
- 'trianglelefteq' : 8884,
- 'ddag' : 8225,
- 'sqsubseteq' : 8849,
- 'mapsfrom' : 8612,
- 'boxbar' : 9707,
- 'sim' : 8764,
- 'Nwarrow' : 8662,
- 'nequiv' : 8802,
- 'succ' : 8827,
- 'vdash' : 8866,
- 'Leftrightarrow' : 8660,
- 'parallel' : 8741,
- 'invnot' : 8976,
- 'natural' : 9838,
- 'ss' : 223,
- 'uparrow' : 8593,
- 'nsim' : 8769,
- 'hookrightarrow' : 8618,
- 'Equiv' : 8803,
- 'approx' : 8776,
- 'Vvdash' : 8874,
- 'nsucc' : 8833,
- 'leftrightharpoons' : 8651,
- 'Re' : 8476,
- 'boxminus' : 8863,
- 'equiv' : 8801,
- 'Lleftarrow' : 8666,
- 'll' : 8810,
- 'Cup' : 8915,
- 'measeq' : 8798,
- 'upharpoonleft' : 8639,
- 'lq' : 8216,
- 'Upsilon' : 933,
- 'subsetneq' : 8842,
- 'greater' : 62,
- 'supsetneq' : 8843,
- 'Cap' : 8914,
- 'L' : 321,
- 'spadesuit' : 9824,
- 'lrcorner' : 8991,
- 'not' : 824,
- 'bar' : 772,
- 'rightharpoonaccent' : 8401,
- 'boxdot' : 8865,
- 'l' : 322,
- 'leftharpoondown' : 8637,
- 'bigcup' : 8899,
- 'iint' : 8748,
- 'bigwedge' : 8896,
- 'downharpoonleft' : 8643,
- 'textasciitilde' : 126,
- 'subset' : 8834,
- 'leqq' : 8806,
- 'mapsup' : 8613,
- 'nvDash' : 8877,
- 'looparrowleft' : 8619,
- 'nless' : 8814,
- 'rightarrowbar' : 8677,
- 'Vert' : 8214,
- 'downdownarrows' : 8650,
- 'uplus' : 8846,
- 'simeq' : 8771,
- 'napprox' : 8777,
- 'ast' : 8727,
- 'twoheaduparrow' : 8607,
- 'doublebarwedge' : 8966,
- 'Sigma' : 931,
- 'leftharpoonaccent' : 8400,
- 'ntrianglelefteq' : 8940,
- 'nexists' : 8708,
- 'times' : 215,
- 'measuredangle' : 8737,
- 'bumpeq' : 8783,
- 'carriagereturn' : 8629,
- 'adots' : 8944,
- 'checkmark' : 10003,
- 'lambda' : 955,
- 'xi' : 958,
- 'rbrace' : 125,
- 'rbrack' : 93,
- 'Nearrow' : 8663,
- 'maltese' : 10016,
- 'clubsuit' : 9827,
- 'top' : 8868,
- 'overarc' : 785,
- 'varphi' : 966,
- 'Delta' : 916,
- 'iota' : 953,
- 'nleftarrow' : 8602,
- 'candra' : 784,
- 'supset' : 8835,
- 'triangleleft' : 9665,
- 'gtreqless' : 8923,
- 'ntrianglerighteq' : 8941,
- 'quad' : 8195,
- 'Xi' : 926,
- 'gtrdot' : 8919,
- 'leftthreetimes' : 8907,
- 'minus' : 8722,
- 'preccurlyeq' : 8828,
- 'nleftrightarrow' : 8622,
- 'lambdabar' : 411,
- 'blacktriangle' : 9652,
- 'kernelcontraction' : 8763,
- 'Phi' : 934,
- 'angle' : 8736,
- 'spadesuitopen' : 9828,
- 'eqless' : 8924,
- 'mid' : 8739,
- 'varkappa' : 1008,
- 'Ldsh' : 8626,
- 'updownarrow' : 8597,
- 'beta' : 946,
- 'textquotedblleft' : 8220,
- 'rho' : 961,
- 'alpha' : 945,
- 'intercal' : 8890,
- 'beth' : 8502,
- 'grave' : 768,
- 'acwopencirclearrow' : 8634,
- 'nmid' : 8740,
- 'nsupset' : 8837,
- 'sigma' : 963,
- 'dot' : 775,
- 'Rightarrow' : 8658,
- 'turnednot' : 8985,
- 'backsimeq' : 8909,
- 'leftarrowtail' : 8610,
- 'approxeq' : 8778,
- 'curlyeqsucc' : 8927,
- 'rightarrowtail' : 8611,
- 'Psi' : 936,
- 'copyright' : 169,
- 'yen' : 165,
- 'vartriangleleft' : 8882,
- 'rasp' : 700,
- 'triangleright' : 9655,
- 'precsim' : 8830,
- 'infty' : 8734,
- 'geq' : 8805,
- 'updownarrowbar' : 8616,
- 'precnsim' : 8936,
- 'H' : 779,
- 'ulcorner' : 8988,
- 'looparrowright' : 8620,
- 'ncong' : 8775,
- 'downarrow' : 8595,
- 'circeq' : 8791,
- 'subseteq' : 8838,
- 'bigstar' : 9733,
- 'prime' : 8242,
- 'lceil' : 8968,
- 'Rrightarrow' : 8667,
- 'oiiint' : 8752,
- 'curlywedge' : 8911,
- 'vDash' : 8872,
- 'lfloor' : 8970,
- 'ddots' : 8945,
- 'exists' : 8707,
- 'underbar' : 817,
- 'Pi' : 928,
- 'leftrightarrows' : 8646,
- 'sphericalangle' : 8738,
- 'coprod' : 8720,
- 'circledcirc' : 8858,
- 'gtrsim' : 8819,
- 'gneqq' : 8809,
- 'between' : 8812,
- 'theta' : 952,
- 'complement' : 8705,
- 'arceq' : 8792,
- 'nVdash' : 8878,
- 'S' : 167,
- 'wr' : 8768,
- 'wp' : 8472,
- 'backcong' : 8780,
- 'lasp' : 701,
- 'c' : 807,
- 'nabla' : 8711,
- 'dotplus' : 8724,
- 'eta' : 951,
- 'forall' : 8704,
- 'eth' : 240,
- 'colon' : 58,
- 'sqcup' : 8852,
- 'rightrightarrows' : 8649,
- 'sqsupset' : 8848,
- 'mapsto' : 8614,
- 'bigtriangledown' : 9661,
- 'sqsupseteq' : 8850,
- 'propto' : 8733,
- 'pi' : 960,
- 'pm' : 177,
- 'dots' : 0x2026,
- 'nrightarrow' : 8603,
- 'textasciiacute' : 180,
- 'Doteq' : 8785,
- 'breve' : 774,
- 'sqcap' : 8851,
- 'twoheadrightarrow' : 8608,
- 'kappa' : 954,
- 'vartriangle' : 9653,
- 'diamondsuit' : 9826,
- 'pitchfork' : 8916,
- 'blacktriangleleft' : 9664,
- 'nprec' : 8832,
- 'curvearrowright' : 8631,
- 'barwedge' : 8892,
- 'multimap' : 8888,
- 'textquestiondown' : 191,
- 'cong' : 8773,
- 'rtimes' : 8906,
- 'rightzigzagarrow' : 8669,
- 'rightarrow' : 8594,
- 'leftarrow' : 8592,
- '__sqrt__' : 8730,
- 'twoheaddownarrow' : 8609,
- 'oint' : 8750,
- 'bigvee' : 8897,
- 'eqdef' : 8797,
- 'sterling' : 163,
- 'phi' : 981,
- 'Updownarrow' : 8661,
- 'backprime' : 8245,
- 'emdash' : 8212,
- 'Gamma' : 915,
- 'i' : 305,
- 'rceil' : 8969,
- 'leftharpoonup' : 8636,
- 'Im' : 8465,
- 'curvearrowleft' : 8630,
- 'wedgeq' : 8793,
- 'curlyeqprec' : 8926,
- 'questeq' : 8799,
- 'less' : 60,
- 'upuparrows' : 8648,
- 'tilde' : 771,
- 'textasciigrave' : 96,
- 'smallsetminus' : 8726,
- 'ell' : 8467,
- 'cup' : 8746,
- 'danger' : 9761,
- 'nVDash' : 8879,
- 'cdotp' : 183,
- 'cdots' : 8943,
- 'hat' : 770,
- 'eqgtr' : 8925,
- 'psi' : 968,
- 'frown' : 8994,
- 'acute' : 769,
- 'downzigzagarrow' : 8623,
- 'ntriangleright' : 8939,
- 'cupdot' : 8845,
- 'circleddash' : 8861,
- 'oslash' : 8856,
- 'mho' : 8487,
- 'd' : 803,
- 'sqsubset' : 8847,
- 'cdot' : 8901,
- 'Omega' : 937,
- 'OE' : 338,
- 'veeeq' : 8794,
- 'Finv' : 8498,
- 't' : 865,
- 'leftrightarrow' : 8596,
- 'swarrow' : 8601,
- 'rightthreetimes' : 8908,
- 'rightleftharpoons' : 8652,
- 'lesssim' : 8818,
- 'searrow' : 8600,
- 'because' : 8757,
- 'gtrless' : 8823,
- 'star' : 8902,
- 'nsubset' : 8836,
- 'zeta' : 950,
- 'dddot' : 8411,
- 'bigcirc' : 9675,
- 'Supset' : 8913,
- 'circ' : 8728,
- 'slash' : 8725,
- 'ocirc' : 778,
- 'prod' : 8719,
- 'twoheadleftarrow' : 8606,
- 'daleth' : 8504,
- 'upharpoonright' : 8638,
- 'odot' : 8857,
- 'Uparrow' : 8657,
- 'O' : 216,
- 'hookleftarrow' : 8617,
- 'trianglerighteq' : 8885,
- 'nsime' : 8772,
- 'oe' : 339,
- 'nwarrow' : 8598,
- 'o' : 248,
- 'ddddot' : 8412,
- 'downharpoonright' : 8642,
- 'succcurlyeq' : 8829,
- 'gamma' : 947,
- 'scrR' : 8475,
- 'dag' : 8224,
- 'thickspace' : 8197,
- 'frakZ' : 8488,
- 'lessdot' : 8918,
- 'triangledown' : 9663,
- 'ltimes' : 8905,
- 'scrB' : 8492,
- 'endash' : 8211,
- 'scrE' : 8496,
- 'scrF' : 8497,
- 'scrH' : 8459,
- 'scrI' : 8464,
- 'rightharpoondown' : 8641,
- 'scrL' : 8466,
- 'scrM' : 8499,
- 'frakC' : 8493,
- 'nsupseteq' : 8841,
- 'circledR' : 174,
- 'circledS' : 9416,
- 'ngtr' : 8815,
- 'bigcap' : 8898,
- 'scre' : 8495,
- 'Downarrow' : 8659,
- 'scrg' : 8458,
- 'overleftrightarrow' : 8417,
- 'scro' : 8500,
- 'lnsim' : 8934,
- 'eqcolon' : 8789,
- 'curlyvee' : 8910,
- 'urcorner' : 8989,
- 'lbrace' : 123,
- 'Bumpeq' : 8782,
- 'delta' : 948,
- 'boxtimes' : 8864,
- 'overleftarrow' : 8406,
- 'prurel' : 8880,
- 'clubsuitopen' : 9831,
- 'cwopencirclearrow' : 8635,
- 'geqq' : 8807,
- 'rightleftarrows' : 8644,
- 'ac' : 8766,
- 'ae' : 230,
- 'int' : 8747,
- 'rfloor' : 8971,
- 'risingdotseq' : 8787,
- 'nvdash' : 8876,
- 'diamond' : 8900,
- 'ddot' : 776,
- 'backsim' : 8765,
- 'oplus' : 8853,
- 'triangleq' : 8796,
- 'check' : 780,
- 'ni' : 8715,
- 'iiint' : 8749,
- 'ne' : 8800,
- 'lesseqgtr' : 8922,
- 'obar' : 9021,
- 'supseteq' : 8839,
- 'nu' : 957,
- 'AA' : 197,
- 'AE' : 198,
- 'models' : 8871,
- 'ominus' : 8854,
- 'dashv' : 8867,
- 'omega' : 969,
- 'rq' : 8217,
- 'Subset' : 8912,
- 'rightharpoonup' : 8640,
- 'Rdsh' : 8627,
- 'bullet' : 8729,
- 'divideontimes' : 8903,
- 'lbrack' : 91,
- 'textquotedblright' : 8221,
- 'Colon' : 8759,
- '%' : 37,
- '$' : 36,
- '{' : 123,
- '}' : 125,
- '_' : 95,
- '#' : 35,
- 'imath' : 0x131,
- 'circumflexaccent' : 770,
- 'combiningbreve' : 774,
- 'combiningoverline' : 772,
- 'combininggraveaccent' : 768,
- 'combiningacuteaccent' : 769,
- 'combiningdiaeresis' : 776,
- 'combiningtilde' : 771,
- 'combiningrightarrowabove' : 8407,
- 'combiningdotabove' : 775,
- 'to' : 8594,
- 'succeq' : 8829,
- 'emptyset' : 8709,
- 'leftparen' : 40,
- 'rightparen' : 41,
- 'bigoplus' : 10753,
- 'leftangle' : 10216,
- 'rightangle' : 10217,
- 'leftbrace' : 124,
- 'rightbrace' : 125,
- 'jmath' : 567,
- 'bigodot' : 10752,
- 'preceq' : 8828,
- 'biguplus' : 10756,
- 'epsilon' : 949,
- 'vartheta' : 977,
- 'bigotimes' : 10754,
- 'guillemotleft' : 171,
- 'ring' : 730,
- 'Thorn' : 222,
- 'guilsinglright' : 8250,
- 'perthousand' : 8240,
- 'macron' : 175,
- 'cent' : 162,
- 'guillemotright' : 187,
- 'equal' : 61,
- 'asterisk' : 42,
- 'guilsinglleft' : 8249,
- 'plus' : 43,
- 'thorn' : 254,
- 'dagger' : 8224
-}
-
-# Each element is a 4-tuple of the form:
-# src_start, src_end, dst_font, dst_start
-#
-stix_virtual_fonts = {
- 'bb':
- {
- 'rm':
- [
- (0x0030, 0x0039, 'rm', 0x1d7d8), # 0-9
- (0x0041, 0x0042, 'rm', 0x1d538), # A-B
- (0x0043, 0x0043, 'rm', 0x2102), # C
- (0x0044, 0x0047, 'rm', 0x1d53b), # D-G
- (0x0048, 0x0048, 'rm', 0x210d), # H
- (0x0049, 0x004d, 'rm', 0x1d540), # I-M
- (0x004e, 0x004e, 'rm', 0x2115), # N
- (0x004f, 0x004f, 'rm', 0x1d546), # O
- (0x0050, 0x0051, 'rm', 0x2119), # P-Q
- (0x0052, 0x0052, 'rm', 0x211d), # R
- (0x0053, 0x0059, 'rm', 0x1d54a), # S-Y
- (0x005a, 0x005a, 'rm', 0x2124), # Z
- (0x0061, 0x007a, 'rm', 0x1d552), # a-z
- (0x0393, 0x0393, 'rm', 0x213e), # \Gamma
- (0x03a0, 0x03a0, 'rm', 0x213f), # \Pi
- (0x03a3, 0x03a3, 'rm', 0x2140), # \Sigma
- (0x03b3, 0x03b3, 'rm', 0x213d), # \gamma
- (0x03c0, 0x03c0, 'rm', 0x213c), # \pi
- ],
- 'it':
- [
- (0x0030, 0x0039, 'rm', 0x1d7d8), # 0-9
- (0x0041, 0x0042, 'it', 0xe154), # A-B
- (0x0043, 0x0043, 'it', 0x2102), # C
- (0x0044, 0x0044, 'it', 0x2145), # D
- (0x0045, 0x0047, 'it', 0xe156), # E-G
- (0x0048, 0x0048, 'it', 0x210d), # H
- (0x0049, 0x004d, 'it', 0xe159), # I-M
- (0x004e, 0x004e, 'it', 0x2115), # N
- (0x004f, 0x004f, 'it', 0xe15e), # O
- (0x0050, 0x0051, 'it', 0x2119), # P-Q
- (0x0052, 0x0052, 'it', 0x211d), # R
- (0x0053, 0x0059, 'it', 0xe15f), # S-Y
- (0x005a, 0x005a, 'it', 0x2124), # Z
- (0x0061, 0x0063, 'it', 0xe166), # a-c
- (0x0064, 0x0065, 'it', 0x2146), # d-e
- (0x0066, 0x0068, 'it', 0xe169), # f-h
- (0x0069, 0x006a, 'it', 0x2148), # i-j
- (0x006b, 0x007a, 'it', 0xe16c), # k-z
- (0x0393, 0x0393, 'it', 0x213e), # \Gamma (not in beta STIX fonts)
- (0x03a0, 0x03a0, 'it', 0x213f), # \Pi
- (0x03a3, 0x03a3, 'it', 0x2140), # \Sigma (not in beta STIX fonts)
- (0x03b3, 0x03b3, 'it', 0x213d), # \gamma (not in beta STIX fonts)
- (0x03c0, 0x03c0, 'it', 0x213c), # \pi
- ],
- 'bf':
- [
- (0x0030, 0x0039, 'rm', 0x1d7d8), # 0-9
- (0x0041, 0x0042, 'bf', 0xe38a), # A-B
- (0x0043, 0x0043, 'bf', 0x2102), # C
- (0x0044, 0x0044, 'bf', 0x2145), # D
- (0x0045, 0x0047, 'bf', 0xe38d), # E-G
- (0x0048, 0x0048, 'bf', 0x210d), # H
- (0x0049, 0x004d, 'bf', 0xe390), # I-M
- (0x004e, 0x004e, 'bf', 0x2115), # N
- (0x004f, 0x004f, 'bf', 0xe395), # O
- (0x0050, 0x0051, 'bf', 0x2119), # P-Q
- (0x0052, 0x0052, 'bf', 0x211d), # R
- (0x0053, 0x0059, 'bf', 0xe396), # S-Y
- (0x005a, 0x005a, 'bf', 0x2124), # Z
- (0x0061, 0x0063, 'bf', 0xe39d), # a-c
- (0x0064, 0x0065, 'bf', 0x2146), # d-e
- (0x0066, 0x0068, 'bf', 0xe3a2), # f-h
- (0x0069, 0x006a, 'bf', 0x2148), # i-j
- (0x006b, 0x007a, 'bf', 0xe3a7), # k-z
- (0x0393, 0x0393, 'bf', 0x213e), # \Gamma
- (0x03a0, 0x03a0, 'bf', 0x213f), # \Pi
- (0x03a3, 0x03a3, 'bf', 0x2140), # \Sigma
- (0x03b3, 0x03b3, 'bf', 0x213d), # \gamma
- (0x03c0, 0x03c0, 'bf', 0x213c), # \pi
- ],
- },
- 'cal':
- [
- (0x0041, 0x005a, 'it', 0xe22d), # A-Z
- ],
- 'circled':
- {
- 'rm':
- [
- (0x0030, 0x0030, 'rm', 0x24ea), # 0
- (0x0031, 0x0039, 'rm', 0x2460), # 1-9
- (0x0041, 0x005a, 'rm', 0x24b6), # A-Z
- (0x0061, 0x007a, 'rm', 0x24d0) # a-z
- ],
- 'it':
- [
- (0x0030, 0x0030, 'rm', 0x24ea), # 0
- (0x0031, 0x0039, 'rm', 0x2460), # 1-9
- (0x0041, 0x005a, 'it', 0x24b6), # A-Z
- (0x0061, 0x007a, 'it', 0x24d0) # a-z
- ],
- 'bf':
- [
- (0x0030, 0x0030, 'bf', 0x24ea), # 0
- (0x0031, 0x0039, 'bf', 0x2460), # 1-9
- (0x0041, 0x005a, 'bf', 0x24b6), # A-Z
- (0x0061, 0x007a, 'bf', 0x24d0) # a-z
- ],
- },
- 'frak':
- {
- 'rm':
- [
- (0x0041, 0x0042, 'rm', 0x1d504), # A-B
- (0x0043, 0x0043, 'rm', 0x212d), # C
- (0x0044, 0x0047, 'rm', 0x1d507), # D-G
- (0x0048, 0x0048, 'rm', 0x210c), # H
- (0x0049, 0x0049, 'rm', 0x2111), # I
- (0x004a, 0x0051, 'rm', 0x1d50d), # J-Q
- (0x0052, 0x0052, 'rm', 0x211c), # R
- (0x0053, 0x0059, 'rm', 0x1d516), # S-Y
- (0x005a, 0x005a, 'rm', 0x2128), # Z
- (0x0061, 0x007a, 'rm', 0x1d51e), # a-z
- ],
- 'it':
- [
- (0x0041, 0x0042, 'rm', 0x1d504), # A-B
- (0x0043, 0x0043, 'rm', 0x212d), # C
- (0x0044, 0x0047, 'rm', 0x1d507), # D-G
- (0x0048, 0x0048, 'rm', 0x210c), # H
- (0x0049, 0x0049, 'rm', 0x2111), # I
- (0x004a, 0x0051, 'rm', 0x1d50d), # J-Q
- (0x0052, 0x0052, 'rm', 0x211c), # R
- (0x0053, 0x0059, 'rm', 0x1d516), # S-Y
- (0x005a, 0x005a, 'rm', 0x2128), # Z
- (0x0061, 0x007a, 'rm', 0x1d51e), # a-z
- ],
- 'bf':
- [
- (0x0041, 0x005a, 'bf', 0x1d56c), # A-Z
- (0x0061, 0x007a, 'bf', 0x1d586), # a-z
- ],
- },
- 'scr':
- [
- (0x0041, 0x0041, 'it', 0x1d49c), # A
- (0x0042, 0x0042, 'it', 0x212c), # B
- (0x0043, 0x0044, 'it', 0x1d49e), # C-D
- (0x0045, 0x0046, 'it', 0x2130), # E-F
- (0x0047, 0x0047, 'it', 0x1d4a2), # G
- (0x0048, 0x0048, 'it', 0x210b), # H
- (0x0049, 0x0049, 'it', 0x2110), # I
- (0x004a, 0x004b, 'it', 0x1d4a5), # J-K
- (0x004c, 0x004c, 'it', 0x2112), # L
- (0x004d, 0x004d, 'it', 0x2133), # M
- (0x004e, 0x0051, 'it', 0x1d4a9), # N-Q
- (0x0052, 0x0052, 'it', 0x211b), # R
- (0x0053, 0x005a, 'it', 0x1d4ae), # S-Z
- (0x0061, 0x0064, 'it', 0x1d4b6), # a-d
- (0x0065, 0x0065, 'it', 0x212f), # e
- (0x0066, 0x0066, 'it', 0x1d4bb), # f
- (0x0067, 0x0067, 'it', 0x210a), # g
- (0x0068, 0x006e, 'it', 0x1d4bd), # h-n
- (0x006f, 0x006f, 'it', 0x2134), # o
- (0x0070, 0x007a, 'it', 0x1d4c5), # p-z
- ],
- 'sf':
- {
- 'rm':
- [
- (0x0030, 0x0039, 'rm', 0x1d7e2), # 0-9
- (0x0041, 0x005a, 'rm', 0x1d5a0), # A-Z
- (0x0061, 0x007a, 'rm', 0x1d5ba), # a-z
- (0x0391, 0x03a9, 'rm', 0xe17d), # \Alpha-\Omega
- (0x03b1, 0x03c9, 'rm', 0xe196), # \alpha-\omega
- (0x03d1, 0x03d1, 'rm', 0xe1b0), # theta variant
- (0x03d5, 0x03d5, 'rm', 0xe1b1), # phi variant
- (0x03d6, 0x03d6, 'rm', 0xe1b3), # pi variant
- (0x03f1, 0x03f1, 'rm', 0xe1b2), # rho variant
- (0x03f5, 0x03f5, 'rm', 0xe1af), # lunate epsilon
- (0x2202, 0x2202, 'rm', 0xe17c), # partial differential
- ],
- 'it':
- [
- # These numerals are actually upright. We don't actually
- # want italic numerals ever.
- (0x0030, 0x0039, 'rm', 0x1d7e2), # 0-9
- (0x0041, 0x005a, 'it', 0x1d608), # A-Z
- (0x0061, 0x007a, 'it', 0x1d622), # a-z
- (0x0391, 0x03a9, 'rm', 0xe17d), # \Alpha-\Omega
- (0x03b1, 0x03c9, 'it', 0xe1d8), # \alpha-\omega
- (0x03d1, 0x03d1, 'it', 0xe1f2), # theta variant
- (0x03d5, 0x03d5, 'it', 0xe1f3), # phi variant
- (0x03d6, 0x03d6, 'it', 0xe1f5), # pi variant
- (0x03f1, 0x03f1, 'it', 0xe1f4), # rho variant
- (0x03f5, 0x03f5, 'it', 0xe1f1), # lunate epsilon
- ],
- 'bf':
- [
- (0x0030, 0x0039, 'bf', 0x1d7ec), # 0-9
- (0x0041, 0x005a, 'bf', 0x1d5d4), # A-Z
- (0x0061, 0x007a, 'bf', 0x1d5ee), # a-z
- (0x0391, 0x03a9, 'bf', 0x1d756), # \Alpha-\Omega
- (0x03b1, 0x03c9, 'bf', 0x1d770), # \alpha-\omega
- (0x03d1, 0x03d1, 'bf', 0x1d78b), # theta variant
- (0x03d5, 0x03d5, 'bf', 0x1d78d), # phi variant
- (0x03d6, 0x03d6, 'bf', 0x1d78f), # pi variant
- (0x03f0, 0x03f0, 'bf', 0x1d78c), # kappa variant
- (0x03f1, 0x03f1, 'bf', 0x1d78e), # rho variant
- (0x03f5, 0x03f5, 'bf', 0x1d78a), # lunate epsilon
- (0x2202, 0x2202, 'bf', 0x1d789), # partial differential
- (0x2207, 0x2207, 'bf', 0x1d76f), # \Nabla
- ],
- },
- 'tt':
- [
- (0x0030, 0x0039, 'rm', 0x1d7f6), # 0-9
- (0x0041, 0x005a, 'rm', 0x1d670), # A-Z
- (0x0061, 0x007a, 'rm', 0x1d68a) # a-z
- ],
- }
diff --git a/contrib/python/matplotlib/py2/matplotlib/_pylab_helpers.py b/contrib/python/matplotlib/py2/matplotlib/_pylab_helpers.py
deleted file mode 100644
index a1d37f21e2..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/_pylab_helpers.py
+++ /dev/null
@@ -1,138 +0,0 @@
-"""
-Manage figures for pyplot interface.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import atexit
-import gc
-import sys
-
-
-class Gcf(object):
- """
- Singleton to manage a set of integer-numbered figures.
-
- This class is never instantiated; it consists of two class
- attributes (a list and a dictionary), and a set of static
- methods that operate on those attributes, accessing them
- directly as class attributes.
-
- Attributes:
-
- *figs*:
- dictionary of the form {*num*: *manager*, ...}
-
- *_activeQue*:
- list of *managers*, with active one at the end
-
- """
- _activeQue = []
- figs = {}
-
- @classmethod
- def get_fig_manager(cls, num):
- """
- If figure manager *num* exists, make it the active
- figure and return the manager; otherwise return *None*.
- """
- manager = cls.figs.get(num, None)
- if manager is not None:
- cls.set_active(manager)
- return manager
-
- @classmethod
- def destroy(cls, num):
- """
- Try to remove all traces of figure *num*.
-
- In the interactive backends, this is bound to the
- window "destroy" and "delete" events.
- """
- if not cls.has_fignum(num):
- return
- manager = cls.figs[num]
- manager.canvas.mpl_disconnect(manager._cidgcf)
- cls._activeQue.remove(manager)
- del cls.figs[num]
- manager.destroy()
- gc.collect(1)
-
- @classmethod
- def destroy_fig(cls, fig):
- "*fig* is a Figure instance"
- num = next((manager.num for manager in six.itervalues(cls.figs)
- if manager.canvas.figure == fig), None)
- if num is not None:
- cls.destroy(num)
-
- @classmethod
- def destroy_all(cls):
- # this is need to ensure that gc is available in corner cases
- # where modules are being torn down after install with easy_install
- import gc # noqa
- for manager in list(cls.figs.values()):
- manager.canvas.mpl_disconnect(manager._cidgcf)
- manager.destroy()
-
- cls._activeQue = []
- cls.figs.clear()
- gc.collect(1)
-
- @classmethod
- def has_fignum(cls, num):
- """
- Return *True* if figure *num* exists.
- """
- return num in cls.figs
-
- @classmethod
- def get_all_fig_managers(cls):
- """
- Return a list of figure managers.
- """
- return list(cls.figs.values())
-
- @classmethod
- def get_num_fig_managers(cls):
- """
- Return the number of figures being managed.
- """
- return len(cls.figs)
-
- @classmethod
- def get_active(cls):
- """
- Return the manager of the active figure, or *None*.
- """
- if len(cls._activeQue) == 0:
- return None
- else:
- return cls._activeQue[-1]
-
- @classmethod
- def set_active(cls, manager):
- """
- Make the figure corresponding to *manager* the active one.
- """
- oldQue = cls._activeQue[:]
- cls._activeQue = []
- for m in oldQue:
- if m != manager:
- cls._activeQue.append(m)
- cls._activeQue.append(manager)
- cls.figs[manager.num] = manager
-
- @classmethod
- def draw_all(cls, force=False):
- """
- Redraw all figures registered with the pyplot
- state machine.
- """
- for f_mgr in cls.get_all_fig_managers():
- if force or f_mgr.canvas.figure.stale:
- f_mgr.canvas.draw_idle()
-
-atexit.register(Gcf.destroy_all)
diff --git a/contrib/python/matplotlib/py2/matplotlib/_version.py b/contrib/python/matplotlib/py2/matplotlib/_version.py
deleted file mode 100644
index ea4bce57c9..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/_version.py
+++ /dev/null
@@ -1,21 +0,0 @@
-
-# This file was generated by 'versioneer.py' (0.15) from
-# revision-control system data, or from the parent directory name of an
-# unpacked source archive. Distribution tarballs contain a pre-generated copy
-# of this file.
-
-import json
-import sys
-
-version_json = '''
-{
- "dirty": false,
- "error": null,
- "full-revisionid": "61e004913460345d108b60506a4deb9f8380eeab",
- "version": "2.2.5"
-}
-''' # END VERSION_JSON
-
-
-def get_versions():
- return json.loads(version_json)
diff --git a/contrib/python/matplotlib/py2/matplotlib/afm.py b/contrib/python/matplotlib/py2/matplotlib/afm.py
deleted file mode 100644
index 1b5f4d5f6a..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/afm.py
+++ /dev/null
@@ -1,547 +0,0 @@
-"""
-This is a python interface to Adobe Font Metrics Files. Although a
-number of other python implementations exist, and may be more complete
-than this, it was decided not to go with them because they were
-either:
-
- 1) copyrighted or used a non-BSD compatible license
-
- 2) had too many dependencies and a free standing lib was needed
-
- 3) Did more than needed and it was easier to write afresh rather than
- figure out how to get just what was needed.
-
-It is pretty easy to use, and requires only built-in python libs:
-
- >>> from matplotlib import rcParams
- >>> import os.path
- >>> afm_fname = os.path.join(rcParams['datapath'],
- ... 'fonts', 'afm', 'ptmr8a.afm')
- >>>
- >>> from matplotlib.afm import AFM
- >>> with open(afm_fname, 'rb') as fh:
- ... afm = AFM(fh)
- >>> afm.string_width_height('What the heck?')
- (6220.0, 694)
- >>> afm.get_fontname()
- 'Times-Roman'
- >>> afm.get_kern_dist('A', 'f')
- 0
- >>> afm.get_kern_dist('A', 'y')
- -92.0
- >>> afm.get_bbox_char('!')
- [130, -9, 238, 676]
-
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import map
-
-import sys
-import re
-from ._mathtext_data import uni2type1
-
-# Convert string the a python type
-
-# some afm files have floats where we are expecting ints -- there is
-# probably a better way to handle this (support floats, round rather
-# than truncate). But I don't know what the best approach is now and
-# this change to _to_int should at least prevent mpl from crashing on
-# these JDH (2009-11-06)
-
-
-def _to_int(x):
- return int(float(x))
-
-
-_to_float = float
-
-
-def _to_str(x):
- return x.decode('utf8')
-
-
-def _to_list_of_ints(s):
- s = s.replace(b',', b' ')
- return [_to_int(val) for val in s.split()]
-
-
-def _to_list_of_floats(s):
- return [_to_float(val) for val in s.split()]
-
-
-def _to_bool(s):
- if s.lower().strip() in (b'false', b'0', b'no'):
- return False
- else:
- return True
-
-
-def _sanity_check(fh):
- """
- Check if the file at least looks like AFM.
- If not, raise :exc:`RuntimeError`.
- """
-
- # Remember the file position in case the caller wants to
- # do something else with the file.
- pos = fh.tell()
- try:
- line = next(fh)
- finally:
- fh.seek(pos, 0)
-
- # AFM spec, Section 4: The StartFontMetrics keyword [followed by a
- # version number] must be the first line in the file, and the
- # EndFontMetrics keyword must be the last non-empty line in the
- # file. We just check the first line.
- if not line.startswith(b'StartFontMetrics'):
- raise RuntimeError('Not an AFM file')
-
-
-def _parse_header(fh):
- """
- Reads the font metrics header (up to the char metrics) and returns
- a dictionary mapping *key* to *val*. *val* will be converted to the
- appropriate python type as necessary; e.g.:
-
- * 'False'->False
- * '0'->0
- * '-168 -218 1000 898'-> [-168, -218, 1000, 898]
-
- Dictionary keys are
-
- StartFontMetrics, FontName, FullName, FamilyName, Weight,
- ItalicAngle, IsFixedPitch, FontBBox, UnderlinePosition,
- UnderlineThickness, Version, Notice, EncodingScheme, CapHeight,
- XHeight, Ascender, Descender, StartCharMetrics
-
- """
- headerConverters = {
- b'StartFontMetrics': _to_float,
- b'FontName': _to_str,
- b'FullName': _to_str,
- b'FamilyName': _to_str,
- b'Weight': _to_str,
- b'ItalicAngle': _to_float,
- b'IsFixedPitch': _to_bool,
- b'FontBBox': _to_list_of_ints,
- b'UnderlinePosition': _to_int,
- b'UnderlineThickness': _to_int,
- b'Version': _to_str,
- b'Notice': _to_str,
- b'EncodingScheme': _to_str,
- b'CapHeight': _to_float, # Is the second version a mistake, or
- b'Capheight': _to_float, # do some AFM files contain 'Capheight'? -JKS
- b'XHeight': _to_float,
- b'Ascender': _to_float,
- b'Descender': _to_float,
- b'StdHW': _to_float,
- b'StdVW': _to_float,
- b'StartCharMetrics': _to_int,
- b'CharacterSet': _to_str,
- b'Characters': _to_int,
- }
-
- d = {}
- for line in fh:
- line = line.rstrip()
- if line.startswith(b'Comment'):
- continue
- lst = line.split(b' ', 1)
-
- key = lst[0]
- if len(lst) == 2:
- val = lst[1]
- else:
- val = b''
-
- try:
- d[key] = headerConverters[key](val)
- except ValueError:
- print('Value error parsing header in AFM:',
- key, val, file=sys.stderr)
- continue
- except KeyError:
- print('Found an unknown keyword in AFM header (was %r)' % key,
- file=sys.stderr)
- continue
- if key == b'StartCharMetrics':
- return d
- raise RuntimeError('Bad parse')
-
-
-def _parse_char_metrics(fh):
- """
- Return a character metric dictionary. Keys are the ASCII num of
- the character, values are a (*wx*, *name*, *bbox*) tuple, where
- *wx* is the character width, *name* is the postscript language
- name, and *bbox* is a (*llx*, *lly*, *urx*, *ury*) tuple.
-
- This function is incomplete per the standard, but thus far parses
- all the sample afm files tried.
- """
-
- ascii_d = {}
- name_d = {}
- for line in fh:
- # We are defensively letting values be utf8. The spec requires
- # ascii, but there are non-compliant fonts in circulation
- line = _to_str(line.rstrip()) # Convert from byte-literal
- if line.startswith('EndCharMetrics'):
- return ascii_d, name_d
- # Split the metric line into a dictionary, keyed by metric identifiers
- vals = dict(s.strip().split(' ', 1) for s in line.split(';') if s)
- # There may be other metrics present, but only these are needed
- if not {'C', 'WX', 'N', 'B'}.issubset(vals):
- raise RuntimeError('Bad char metrics line: %s' % line)
- num = _to_int(vals['C'])
- wx = _to_float(vals['WX'])
- name = vals['N']
- bbox = _to_list_of_floats(vals['B'])
- bbox = list(map(int, bbox))
- # Workaround: If the character name is 'Euro', give it the
- # corresponding character code, according to WinAnsiEncoding (see PDF
- # Reference).
- if name == 'Euro':
- num = 128
- if num != -1:
- ascii_d[num] = (wx, name, bbox)
- name_d[name] = (wx, bbox)
- raise RuntimeError('Bad parse')
-
-
-def _parse_kern_pairs(fh):
- """
- Return a kern pairs dictionary; keys are (*char1*, *char2*) tuples and
- values are the kern pair value. For example, a kern pairs line like
- ``KPX A y -50``
-
- will be represented as::
-
- d[ ('A', 'y') ] = -50
-
- """
-
- line = next(fh)
- if not line.startswith(b'StartKernPairs'):
- raise RuntimeError('Bad start of kern pairs data: %s' % line)
-
- d = {}
- for line in fh:
- line = line.rstrip()
- if not line:
- continue
- if line.startswith(b'EndKernPairs'):
- next(fh) # EndKernData
- return d
- vals = line.split()
- if len(vals) != 4 or vals[0] != b'KPX':
- raise RuntimeError('Bad kern pairs line: %s' % line)
- c1, c2, val = _to_str(vals[1]), _to_str(vals[2]), _to_float(vals[3])
- d[(c1, c2)] = val
- raise RuntimeError('Bad kern pairs parse')
-
-
-def _parse_composites(fh):
- """
- Return a composites dictionary. Keys are the names of the
- composites. Values are a num parts list of composite information,
- with each element being a (*name*, *dx*, *dy*) tuple. Thus a
- composites line reading:
-
- CC Aacute 2 ; PCC A 0 0 ; PCC acute 160 170 ;
-
- will be represented as::
-
- d['Aacute'] = [ ('A', 0, 0), ('acute', 160, 170) ]
-
- """
- d = {}
- for line in fh:
- line = line.rstrip()
- if not line:
- continue
- if line.startswith(b'EndComposites'):
- return d
- vals = line.split(b';')
- cc = vals[0].split()
- name, numParts = cc[1], _to_int(cc[2])
- pccParts = []
- for s in vals[1:-1]:
- pcc = s.split()
- name, dx, dy = pcc[1], _to_float(pcc[2]), _to_float(pcc[3])
- pccParts.append((name, dx, dy))
- d[name] = pccParts
-
- raise RuntimeError('Bad composites parse')
-
-
-def _parse_optional(fh):
- """
- Parse the optional fields for kern pair data and composites
-
- return value is a (*kernDict*, *compositeDict*) which are the
- return values from :func:`_parse_kern_pairs`, and
- :func:`_parse_composites` if the data exists, or empty dicts
- otherwise
- """
- optional = {
- b'StartKernData': _parse_kern_pairs,
- b'StartComposites': _parse_composites,
- }
-
- d = {b'StartKernData': {}, b'StartComposites': {}}
- for line in fh:
- line = line.rstrip()
- if not line:
- continue
- key = line.split()[0]
-
- if key in optional:
- d[key] = optional[key](fh)
-
- l = (d[b'StartKernData'], d[b'StartComposites'])
- return l
-
-
-def parse_afm(fh):
- """
- Parse the Adobe Font Metics file in file handle *fh*. Return value
- is a (*dhead*, *dcmetrics_ascii*, *dmetrics_name*, *dkernpairs*,
- *dcomposite*) tuple where
- *dhead* is a :func:`_parse_header` dict,
- *dcmetrics_ascii* and *dcmetrics_name* are the two resulting dicts
- from :func:`_parse_char_metrics`,
- *dkernpairs* is a :func:`_parse_kern_pairs` dict (possibly {}) and
- *dcomposite* is a :func:`_parse_composites` dict (possibly {})
- """
- _sanity_check(fh)
- dhead = _parse_header(fh)
- dcmetrics_ascii, dcmetrics_name = _parse_char_metrics(fh)
- doptional = _parse_optional(fh)
- return dhead, dcmetrics_ascii, dcmetrics_name, doptional[0], doptional[1]
-
-
-class AFM(object):
-
- def __init__(self, fh):
- """
- Parse the AFM file in file object *fh*
- """
- (dhead, dcmetrics_ascii, dcmetrics_name, dkernpairs, dcomposite) = \
- parse_afm(fh)
- self._header = dhead
- self._kern = dkernpairs
- self._metrics = dcmetrics_ascii
- self._metrics_by_name = dcmetrics_name
- self._composite = dcomposite
-
- def get_bbox_char(self, c, isord=False):
- if not isord:
- c = ord(c)
- wx, name, bbox = self._metrics[c]
- return bbox
-
- def string_width_height(self, s):
- """
- Return the string width (including kerning) and string height
- as a (*w*, *h*) tuple.
- """
- if not len(s):
- return 0, 0
- totalw = 0
- namelast = None
- miny = 1e9
- maxy = 0
- for c in s:
- if c == '\n':
- continue
- wx, name, bbox = self._metrics[ord(c)]
- l, b, w, h = bbox
-
- # find the width with kerning
- try:
- kp = self._kern[(namelast, name)]
- except KeyError:
- kp = 0
- totalw += wx + kp
-
- # find the max y
- thismax = b + h
- if thismax > maxy:
- maxy = thismax
-
- # find the min y
- thismin = b
- if thismin < miny:
- miny = thismin
- namelast = name
-
- return totalw, maxy - miny
-
- def get_str_bbox_and_descent(self, s):
- """
- Return the string bounding box
- """
- if not len(s):
- return 0, 0, 0, 0
- totalw = 0
- namelast = None
- miny = 1e9
- maxy = 0
- left = 0
- if not isinstance(s, six.text_type):
- s = _to_str(s)
- for c in s:
- if c == '\n':
- continue
- name = uni2type1.get(ord(c), 'question')
- try:
- wx, bbox = self._metrics_by_name[name]
- except KeyError:
- name = 'question'
- wx, bbox = self._metrics_by_name[name]
- l, b, w, h = bbox
- if l < left:
- left = l
- # find the width with kerning
- try:
- kp = self._kern[(namelast, name)]
- except KeyError:
- kp = 0
- totalw += wx + kp
-
- # find the max y
- thismax = b + h
- if thismax > maxy:
- maxy = thismax
-
- # find the min y
- thismin = b
- if thismin < miny:
- miny = thismin
- namelast = name
-
- return left, miny, totalw, maxy - miny, -miny
-
- def get_str_bbox(self, s):
- """
- Return the string bounding box
- """
- return self.get_str_bbox_and_descent(s)[:4]
-
- def get_name_char(self, c, isord=False):
- """
- Get the name of the character, i.e., ';' is 'semicolon'
- """
- if not isord:
- c = ord(c)
- wx, name, bbox = self._metrics[c]
- return name
-
- def get_width_char(self, c, isord=False):
- """
- Get the width of the character from the character metric WX
- field
- """
- if not isord:
- c = ord(c)
- wx, name, bbox = self._metrics[c]
- return wx
-
- def get_width_from_char_name(self, name):
- """
- Get the width of the character from a type1 character name
- """
- wx, bbox = self._metrics_by_name[name]
- return wx
-
- def get_height_char(self, c, isord=False):
- """
- Get the height of character *c* from the bounding box. This
- is the ink height (space is 0)
- """
- if not isord:
- c = ord(c)
- wx, name, bbox = self._metrics[c]
- return bbox[-1]
-
- def get_kern_dist(self, c1, c2):
- """
- Return the kerning pair distance (possibly 0) for chars *c1*
- and *c2*
- """
- name1, name2 = self.get_name_char(c1), self.get_name_char(c2)
- return self.get_kern_dist_from_name(name1, name2)
-
- def get_kern_dist_from_name(self, name1, name2):
- """
- Return the kerning pair distance (possibly 0) for chars
- *name1* and *name2*
- """
- return self._kern.get((name1, name2), 0)
-
- def get_fontname(self):
- "Return the font name, e.g., 'Times-Roman'"
- return self._header[b'FontName']
-
- def get_fullname(self):
- "Return the font full name, e.g., 'Times-Roman'"
- name = self._header.get(b'FullName')
- if name is None: # use FontName as a substitute
- name = self._header[b'FontName']
- return name
-
- def get_familyname(self):
- "Return the font family name, e.g., 'Times'"
- name = self._header.get(b'FamilyName')
- if name is not None:
- return name
-
- # FamilyName not specified so we'll make a guess
- name = self.get_fullname()
- extras = (r'(?i)([ -](regular|plain|italic|oblique|bold|semibold|'
- r'light|ultralight|extra|condensed))+$')
- return re.sub(extras, '', name)
-
- @property
- def family_name(self):
- return self.get_familyname()
-
- def get_weight(self):
- "Return the font weight, e.g., 'Bold' or 'Roman'"
- return self._header[b'Weight']
-
- def get_angle(self):
- "Return the fontangle as float"
- return self._header[b'ItalicAngle']
-
- def get_capheight(self):
- "Return the cap height as float"
- return self._header[b'CapHeight']
-
- def get_xheight(self):
- "Return the xheight as float"
- return self._header[b'XHeight']
-
- def get_underline_thickness(self):
- "Return the underline thickness as float"
- return self._header[b'UnderlineThickness']
-
- def get_horizontal_stem_width(self):
- """
- Return the standard horizontal stem width as float, or *None* if
- not specified in AFM file.
- """
- return self._header.get(b'StdHW', None)
-
- def get_vertical_stem_width(self):
- """
- Return the standard vertical stem width as float, or *None* if
- not specified in AFM file.
- """
- return self._header.get(b'StdVW', None)
diff --git a/contrib/python/matplotlib/py2/matplotlib/animation.py b/contrib/python/matplotlib/py2/matplotlib/animation.py
deleted file mode 100644
index e2e6f51e70..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/animation.py
+++ /dev/null
@@ -1,1778 +0,0 @@
-# TODO:
-# * Loop Delay is broken on GTKAgg. This is because source_remove() is not
-# working as we want. PyGTK bug?
-# * Documentation -- this will need a new section of the User's Guide.
-# Both for Animations and just timers.
-# - Also need to update http://www.scipy.org/Cookbook/Matplotlib/Animations
-# * Blit
-# * Currently broken with Qt4 for widgets that don't start on screen
-# * Still a few edge cases that aren't working correctly
-# * Can this integrate better with existing matplotlib animation artist flag?
-# - If animated removes from default draw(), perhaps we could use this to
-# simplify initial draw.
-# * Example
-# * Frameless animation - pure procedural with no loop
-# * Need example that uses something like inotify or subprocess
-# * Complex syncing examples
-# * Movies
-# * Can blit be enabled for movies?
-# * Need to consider event sources to allow clicking through multiple figures
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange, zip
-
-import abc
-import contextlib
-from io import BytesIO
-import itertools
-import logging
-import os
-import platform
-import sys
-import tempfile
-import uuid
-
-import numpy as np
-
-from matplotlib._animation_data import (DISPLAY_TEMPLATE, INCLUDED_FRAMES,
- JS_INCLUDE)
-from matplotlib.compat import subprocess
-from matplotlib import cbook, rcParams, rcParamsDefault, rc_context
-
-if six.PY2:
- from base64 import encodestring as encodebytes
-else:
- from base64 import encodebytes
-
-
-_log = logging.getLogger(__name__)
-
-# Process creation flag for subprocess to prevent it raising a terminal
-# window. See for example:
-# https://stackoverflow.com/questions/24130623/using-python-subprocess-popen-cant-prevent-exe-stopped-working-prompt
-if platform.system() == 'Windows':
- subprocess_creation_flags = CREATE_NO_WINDOW = 0x08000000
-else:
- # Apparently None won't work here
- subprocess_creation_flags = 0
-
-# Other potential writing methods:
-# * http://pymedia.org/
-# * libmng (produces swf) python wrappers: https://github.com/libming/libming
-# * Wrap x264 API:
-
-# (http://stackoverflow.com/questions/2940671/
-# how-to-encode-series-of-images-into-h264-using-x264-api-c-c )
-
-
-def adjusted_figsize(w, h, dpi, n):
- '''Compute figure size so that pixels are a multiple of n
-
- Parameters
- ----------
- w, h : float
- Size in inches
-
- dpi : float
- The dpi
-
- n : int
- The target multiple
-
- Returns
- -------
- wnew, hnew : float
- The new figure size in inches.
- '''
-
- # this maybe simplified if / when we adopt consistent rounding for
- # pixel size across the whole library
- def correct_roundoff(x, dpi, n):
- if int(x*dpi) % n != 0:
- if int(np.nextafter(x, np.inf)*dpi) % n == 0:
- x = np.nextafter(x, np.inf)
- elif int(np.nextafter(x, -np.inf)*dpi) % n == 0:
- x = np.nextafter(x, -np.inf)
- return x
-
- wnew = int(w * dpi / n) * n / dpi
- hnew = int(h * dpi / n) * n / dpi
- return (correct_roundoff(wnew, dpi, n), correct_roundoff(hnew, dpi, n))
-
-
-# A registry for available MovieWriter classes
-class MovieWriterRegistry(object):
- '''Registry of available writer classes by human readable name.'''
- def __init__(self):
- self.avail = dict()
- self._registered = dict()
- self._dirty = False
-
- def set_dirty(self):
- """Sets a flag to re-setup the writers."""
- self._dirty = True
-
- def register(self, name):
- """Decorator for registering a class under a name.
-
- Example use::
-
- @registry.register(name)
- class Foo:
- pass
- """
- def wrapper(writerClass):
- self._registered[name] = writerClass
- if writerClass.isAvailable():
- self.avail[name] = writerClass
- return writerClass
- return wrapper
-
- def ensure_not_dirty(self):
- """If dirty, reasks the writers if they are available"""
- if self._dirty:
- self.reset_available_writers()
-
- def reset_available_writers(self):
- """Reset the available state of all registered writers"""
- self.avail = {}
- for name, writerClass in self._registered.items():
- if writerClass.isAvailable():
- self.avail[name] = writerClass
- self._dirty = False
-
- def list(self):
- '''Get a list of available MovieWriters.'''
- self.ensure_not_dirty()
- return list(self.avail)
-
- def is_available(self, name):
- '''Check if given writer is available by name.
-
- Parameters
- ----------
- name : str
-
- Returns
- -------
- available : bool
- '''
- self.ensure_not_dirty()
- return name in self.avail
-
- def __getitem__(self, name):
- self.ensure_not_dirty()
- if not self.avail:
- raise RuntimeError("No MovieWriters available!")
- try:
- return self.avail[name]
- except KeyError:
- raise RuntimeError(
- 'Requested MovieWriter ({}) not available'.format(name))
-
-
-writers = MovieWriterRegistry()
-
-
-class AbstractMovieWriter(six.with_metaclass(abc.ABCMeta)):
- '''
- Abstract base class for writing movies. Fundamentally, what a MovieWriter
- does is provide is a way to grab frames by calling grab_frame().
-
- setup() is called to start the process and finish() is called afterwards.
-
- This class is set up to provide for writing movie frame data to a pipe.
- saving() is provided as a context manager to facilitate this process as::
-
- with moviewriter.saving(fig, outfile='myfile.mp4', dpi=100):
- # Iterate over frames
- moviewriter.grab_frame(**savefig_kwargs)
-
- The use of the context manager ensures that setup() and finish() are
- performed as necessary.
-
- An instance of a concrete subclass of this class can be given as the
- ``writer`` argument of `Animation.save()`.
- '''
-
- @abc.abstractmethod
- def setup(self, fig, outfile, dpi=None):
- '''
- Perform setup for writing the movie file.
-
- Parameters
- ----------
- fig: `matplotlib.figure.Figure` instance
- The figure object that contains the information for frames
- outfile: string
- The filename of the resulting movie file
- dpi: int, optional
- The DPI (or resolution) for the file. This controls the size
- in pixels of the resulting movie file. Default is ``fig.dpi``.
- '''
-
- @abc.abstractmethod
- def grab_frame(self, **savefig_kwargs):
- '''
- Grab the image information from the figure and save as a movie frame.
-
- All keyword arguments in savefig_kwargs are passed on to the `savefig`
- command that saves the figure.
- '''
-
- @abc.abstractmethod
- def finish(self):
- '''Finish any processing for writing the movie.'''
-
- @contextlib.contextmanager
- def saving(self, fig, outfile, dpi, *args, **kwargs):
- '''
- Context manager to facilitate writing the movie file.
-
- ``*args, **kw`` are any parameters that should be passed to `setup`.
- '''
- # This particular sequence is what contextlib.contextmanager wants
- self.setup(fig, outfile, dpi, *args, **kwargs)
- try:
- yield self
- finally:
- self.finish()
-
-
-class MovieWriter(AbstractMovieWriter):
- '''Base class for writing movies.
-
- This class is set up to provide for writing movie frame data to a pipe.
- See examples for how to use these classes.
-
- Attributes
- ----------
- frame_format : str
- The format used in writing frame data, defaults to 'rgba'
- fig : `~matplotlib.figure.Figure`
- The figure to capture data from.
- This must be provided by the sub-classes.
-
- '''
-
- def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None,
- metadata=None):
- '''MovieWriter
-
- Parameters
- ----------
- fps: int
- Framerate for movie.
- codec: string or None, optional
- The codec to use. If ``None`` (the default) the ``animation.codec``
- rcParam is used.
- bitrate: int or None, optional
- The bitrate for the saved movie file, which is one way to control
- the output file size and quality. The default value is ``None``,
- which uses the ``animation.bitrate`` rcParam. A value of -1
- implies that the bitrate should be determined automatically by the
- underlying utility.
- extra_args: list of strings or None, optional
- A list of extra string arguments to be passed to the underlying
- movie utility. The default is ``None``, which passes the additional
- arguments in the ``animation.extra_args`` rcParam.
- metadata: Dict[str, str] or None
- A dictionary of keys and values for metadata to include in the
- output file. Some keys that may be of use include:
- title, artist, genre, subject, copyright, srcform, comment.
- '''
- self.fps = fps
- self.frame_format = 'rgba'
-
- if codec is None:
- self.codec = rcParams['animation.codec']
- else:
- self.codec = codec
-
- if bitrate is None:
- self.bitrate = rcParams['animation.bitrate']
- else:
- self.bitrate = bitrate
-
- if extra_args is None:
- self.extra_args = list(rcParams[self.args_key])
- else:
- self.extra_args = extra_args
-
- if metadata is None:
- self.metadata = dict()
- else:
- self.metadata = metadata
-
- @property
- def frame_size(self):
- '''A tuple ``(width, height)`` in pixels of a movie frame.'''
- w, h = self.fig.get_size_inches()
- return int(w * self.dpi), int(h * self.dpi)
-
- def _adjust_frame_size(self):
- if self.codec == 'h264':
- wo, ho = self.fig.get_size_inches()
- w, h = adjusted_figsize(wo, ho, self.dpi, 2)
- if not (wo, ho) == (w, h):
- self.fig.set_size_inches(w, h, forward=True)
- _log.info('figure size (inches) has been adjusted '
- 'from %s x %s to %s x %s', wo, ho, w, h)
- else:
- w, h = self.fig.get_size_inches()
- _log.debug('frame size in pixels is %s x %s', *self.frame_size)
- return w, h
-
- def setup(self, fig, outfile, dpi=None):
- '''
- Perform setup for writing the movie file.
-
- Parameters
- ----------
- fig : matplotlib.figure.Figure
- The figure object that contains the information for frames
- outfile : string
- The filename of the resulting movie file
- dpi : int, optional
- The DPI (or resolution) for the file. This controls the size
- in pixels of the resulting movie file. Default is fig.dpi.
- '''
- self.outfile = outfile
- self.fig = fig
- if dpi is None:
- dpi = self.fig.dpi
- self.dpi = dpi
- self._w, self._h = self._adjust_frame_size()
-
- # Run here so that grab_frame() can write the data to a pipe. This
- # eliminates the need for temp files.
- self._run()
-
- def _run(self):
- # Uses subprocess to call the program for assembling frames into a
- # movie file. *args* returns the sequence of command line arguments
- # from a few configuration options.
- command = self._args()
- output = subprocess.PIPE
- _log.info('MovieWriter.run: running command: %s', command)
- self._proc = subprocess.Popen(command, shell=False,
- stdout=output, stderr=output,
- stdin=subprocess.PIPE,
- creationflags=subprocess_creation_flags)
-
- def finish(self):
- '''Finish any processing for writing the movie.'''
- self.cleanup()
-
- def grab_frame(self, **savefig_kwargs):
- '''
- Grab the image information from the figure and save as a movie frame.
-
- All keyword arguments in savefig_kwargs are passed on to the `savefig`
- command that saves the figure.
- '''
- _log.debug('MovieWriter.grab_frame: Grabbing frame.')
- try:
- # re-adjust the figure size in case it has been changed by the
- # user. We must ensure that every frame is the same size or
- # the movie will not save correctly.
- self.fig.set_size_inches(self._w, self._h)
- # Tell the figure to save its data to the sink, using the
- # frame format and dpi.
- self.fig.savefig(self._frame_sink(), format=self.frame_format,
- dpi=self.dpi, **savefig_kwargs)
- except (RuntimeError, IOError) as e:
- out, err = self._proc.communicate()
- _log.info('MovieWriter -- Error '
- 'running proc:\n%s\n%s' % (out, err))
- raise IOError('Error saving animation to file (cause: {0}) '
- 'Stdout: {1} StdError: {2}. It may help to re-run '
- 'with logging level set to '
- 'DEBUG.'.format(e, out, err))
-
- def _frame_sink(self):
- '''Returns the place to which frames should be written.'''
- return self._proc.stdin
-
- def _args(self):
- '''Assemble list of utility-specific command-line arguments.'''
- return NotImplementedError("args needs to be implemented by subclass.")
-
- def cleanup(self):
- '''Clean-up and collect the process used to write the movie file.'''
- out, err = self._proc.communicate()
- self._frame_sink().close()
- _log.debug('MovieWriter -- Command stdout:\n%s', out)
- _log.debug('MovieWriter -- Command stderr:\n%s', err)
-
- @classmethod
- def bin_path(cls):
- '''
- Returns the binary path to the commandline tool used by a specific
- subclass. This is a class method so that the tool can be looked for
- before making a particular MovieWriter subclass available.
- '''
- return str(rcParams[cls.exec_key])
-
- @classmethod
- def isAvailable(cls):
- '''
- Check to see if a MovieWriter subclass is actually available by
- running the commandline tool.
- '''
- bin_path = cls.bin_path()
- if not bin_path:
- return False
- try:
- p = subprocess.Popen(
- bin_path,
- shell=False,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- creationflags=subprocess_creation_flags)
- return cls._handle_subprocess(p)
- except OSError:
- return False
-
- @classmethod
- def _handle_subprocess(cls, process):
- process.communicate()
- return True
-
-
-class FileMovieWriter(MovieWriter):
- '''`MovieWriter` for writing to individual files and stitching at the end.
-
- This must be sub-classed to be useful.
- '''
- def __init__(self, *args, **kwargs):
- MovieWriter.__init__(self, *args, **kwargs)
- self.frame_format = rcParams['animation.frame_format']
-
- def setup(self, fig, outfile, dpi=None, frame_prefix='_tmp',
- clear_temp=True):
- '''Perform setup for writing the movie file.
-
- Parameters
- ----------
- fig : matplotlib.figure.Figure
- The figure to grab the rendered frames from.
- outfile : str
- The filename of the resulting movie file.
- dpi : number, optional
- The dpi of the output file. This, with the figure size,
- controls the size in pixels of the resulting movie file.
- Default is fig.dpi.
- frame_prefix : str, optional
- The filename prefix to use for temporary files. Defaults to
- ``'_tmp'``.
- clear_temp : bool, optional
- If the temporary files should be deleted after stitching
- the final result. Setting this to ``False`` can be useful for
- debugging. Defaults to ``True``.
-
- '''
- self.fig = fig
- self.outfile = outfile
- if dpi is None:
- dpi = self.fig.dpi
- self.dpi = dpi
- self._adjust_frame_size()
-
- self.clear_temp = clear_temp
- self.temp_prefix = frame_prefix
- self._frame_counter = 0 # used for generating sequential file names
- self._temp_names = list()
- self.fname_format_str = '%s%%07d.%s'
-
- @property
- def frame_format(self):
- '''
- Format (png, jpeg, etc.) to use for saving the frames, which can be
- decided by the individual subclasses.
- '''
- return self._frame_format
-
- @frame_format.setter
- def frame_format(self, frame_format):
- if frame_format in self.supported_formats:
- self._frame_format = frame_format
- else:
- self._frame_format = self.supported_formats[0]
-
- def _base_temp_name(self):
- # Generates a template name (without number) given the frame format
- # for extension and the prefix.
- return self.fname_format_str % (self.temp_prefix, self.frame_format)
-
- def _frame_sink(self):
- # Creates a filename for saving using the basename and the current
- # counter.
- fname = self._base_temp_name() % self._frame_counter
-
- # Save the filename so we can delete it later if necessary
- self._temp_names.append(fname)
- _log.debug('FileMovieWriter.frame_sink: saving frame %d to fname=%s',
- self._frame_counter, fname)
- self._frame_counter += 1 # Ensures each created name is 'unique'
-
- # This file returned here will be closed once it's used by savefig()
- # because it will no longer be referenced and will be gc-ed.
- return open(fname, 'wb')
-
- def grab_frame(self, **savefig_kwargs):
- '''
- Grab the image information from the figure and save as a movie frame.
- All keyword arguments in savefig_kwargs are passed on to the `savefig`
- command that saves the figure.
- '''
- # Overloaded to explicitly close temp file.
- _log.debug('MovieWriter.grab_frame: Grabbing frame.')
- try:
- # Tell the figure to save its data to the sink, using the
- # frame format and dpi.
- with self._frame_sink() as myframesink:
- self.fig.savefig(myframesink, format=self.frame_format,
- dpi=self.dpi, **savefig_kwargs)
-
- except RuntimeError:
- out, err = self._proc.communicate()
- _log.info('MovieWriter -- Error '
- 'running proc:\n%s\n%s' % (out, err))
- raise
-
- def finish(self):
- # Call run here now that all frame grabbing is done. All temp files
- # are available to be assembled.
- self._run()
- MovieWriter.finish(self) # Will call clean-up
-
- # Check error code for creating file here, since we just run
- # the process here, rather than having an open pipe.
- if self._proc.returncode:
- try:
- stdout = [s.decode() for s in self._proc._stdout_buff]
- stderr = [s.decode() for s in self._proc._stderr_buff]
- _log.info("MovieWriter.finish: stdout: %s", stdout)
- _log.info("MovieWriter.finish: stderr: %s", stderr)
- except Exception as e:
- pass
- raise RuntimeError('Error creating movie, return code: {}'
- .format(self._proc.returncode))
-
- def cleanup(self):
- MovieWriter.cleanup(self)
-
- # Delete temporary files
- if self.clear_temp:
- _log.debug('MovieWriter: clearing temporary fnames=%s',
- self._temp_names)
- for fname in self._temp_names:
- os.remove(fname)
-
-
-@writers.register('pillow')
-class PillowWriter(MovieWriter):
- @classmethod
- def isAvailable(cls):
- try:
- import PIL
- except ImportError:
- return False
- return True
-
- def __init__(self, *args, **kwargs):
- if kwargs.get("extra_args") is None:
- kwargs["extra_args"] = ()
- super(PillowWriter, self).__init__(*args, **kwargs)
-
- def setup(self, fig, outfile, dpi=None):
- self._frames = []
- self._outfile = outfile
- self._dpi = dpi
- self._fig = fig
-
- def grab_frame(self, **savefig_kwargs):
- from PIL import Image
- buf = BytesIO()
- self._fig.savefig(buf, **dict(savefig_kwargs, format="rgba"))
- renderer = self._fig.canvas.get_renderer()
- # Using frombuffer / getbuffer may be slightly more efficient, but
- # Py3-only.
- self._frames.append(Image.frombytes(
- "RGBA",
- (int(renderer.width), int(renderer.height)),
- buf.getvalue()))
-
- def finish(self):
- self._frames[0].save(
- self._outfile, save_all=True, append_images=self._frames[1:],
- duration=int(1000 / self.fps))
-
-
-# Base class of ffmpeg information. Has the config keys and the common set
-# of arguments that controls the *output* side of things.
-class FFMpegBase(object):
- '''Mixin class for FFMpeg output.
-
- To be useful this must be multiply-inherited from with a
- `MovieWriterBase` sub-class.
- '''
-
- exec_key = 'animation.ffmpeg_path'
- args_key = 'animation.ffmpeg_args'
-
- @property
- def output_args(self):
- args = ['-vcodec', self.codec]
- # For h264, the default format is yuv444p, which is not compatible
- # with quicktime (and others). Specifying yuv420p fixes playback on
- # iOS,as well as HTML5 video in firefox and safari (on both Win and
- # OSX). Also fixes internet explorer. This is as of 2015/10/29.
- if self.codec == 'h264' and '-pix_fmt' not in self.extra_args:
- args.extend(['-pix_fmt', 'yuv420p'])
- # The %dk adds 'k' as a suffix so that ffmpeg treats our bitrate as in
- # kbps
- if self.bitrate > 0:
- args.extend(['-b', '%dk' % self.bitrate])
- if self.extra_args:
- args.extend(self.extra_args)
- for k, v in six.iteritems(self.metadata):
- args.extend(['-metadata', '%s=%s' % (k, v)])
-
- return args + ['-y', self.outfile]
-
- @classmethod
- def _handle_subprocess(cls, process):
- _, err = process.communicate()
- # Ubuntu 12.04 ships a broken ffmpeg binary which we shouldn't use
- # NOTE : when removed, remove the same method in AVConvBase.
- if 'Libav' in err.decode():
- return False
- return True
-
-
-# Combine FFMpeg options with pipe-based writing
-@writers.register('ffmpeg')
-class FFMpegWriter(FFMpegBase, MovieWriter):
- '''Pipe-based ffmpeg writer.
-
- Frames are streamed directly to ffmpeg via a pipe and written in a single
- pass.
- '''
- def _args(self):
- # Returns the command line parameters for subprocess to use
- # ffmpeg to create a movie using a pipe.
- args = [self.bin_path(), '-f', 'rawvideo', '-vcodec', 'rawvideo',
- '-s', '%dx%d' % self.frame_size, '-pix_fmt', self.frame_format,
- '-r', str(self.fps)]
- # Logging is quieted because subprocess.PIPE has limited buffer size.
- # If you have a lot of frames in your animation and set logging to
- # DEBUG, you will have a buffer overrun.
- if (_log.getEffectiveLevel() > logging.DEBUG):
- args += ['-loglevel', 'quiet']
- args += ['-i', 'pipe:'] + self.output_args
- return args
-
-
-# Combine FFMpeg options with temp file-based writing
-@writers.register('ffmpeg_file')
-class FFMpegFileWriter(FFMpegBase, FileMovieWriter):
- '''File-based ffmpeg writer.
-
- Frames are written to temporary files on disk and then stitched
- together at the end.
-
- '''
- supported_formats = ['png', 'jpeg', 'ppm', 'tiff', 'sgi', 'bmp',
- 'pbm', 'raw', 'rgba']
-
- def _args(self):
- # Returns the command line parameters for subprocess to use
- # ffmpeg to create a movie using a collection of temp images
- return [self.bin_path(), '-r', str(self.fps),
- '-i', self._base_temp_name(),
- '-vframes', str(self._frame_counter)] + self.output_args
-
-
-# Base class of avconv information. AVConv has identical arguments to
-# FFMpeg
-class AVConvBase(FFMpegBase):
- '''Mixin class for avconv output.
-
- To be useful this must be multiply-inherited from with a
- `MovieWriterBase` sub-class.
- '''
-
- exec_key = 'animation.avconv_path'
- args_key = 'animation.avconv_args'
-
- # NOTE : should be removed when the same method is removed in FFMpegBase.
- @classmethod
- def _handle_subprocess(cls, process):
- return MovieWriter._handle_subprocess(process)
-
-
-# Combine AVConv options with pipe-based writing
-@writers.register('avconv')
-class AVConvWriter(AVConvBase, FFMpegWriter):
- '''Pipe-based avconv writer.
-
- Frames are streamed directly to avconv via a pipe and written in a single
- pass.
- '''
-
-
-# Combine AVConv options with file-based writing
-@writers.register('avconv_file')
-class AVConvFileWriter(AVConvBase, FFMpegFileWriter):
- '''File-based avconv writer.
-
- Frames are written to temporary files on disk and then stitched
- together at the end.
- '''
-
-
-# Base class for animated GIFs with convert utility
-class ImageMagickBase(object):
- '''Mixin class for ImageMagick output.
-
- To be useful this must be multiply-inherited from with a
- `MovieWriterBase` sub-class.
- '''
-
- exec_key = 'animation.convert_path'
- args_key = 'animation.convert_args'
-
- @property
- def delay(self):
- return 100. / self.fps
-
- @property
- def output_args(self):
- return [self.outfile]
-
- @classmethod
- def _init_from_registry(cls):
- if sys.platform != 'win32' or rcParams[cls.exec_key] != 'convert':
- return
- from six.moves import winreg
- for flag in (0, winreg.KEY_WOW64_32KEY, winreg.KEY_WOW64_64KEY):
- try:
- hkey = winreg.OpenKeyEx(winreg.HKEY_LOCAL_MACHINE,
- 'Software\\Imagemagick\\Current',
- 0, winreg.KEY_QUERY_VALUE | flag)
- binpath = winreg.QueryValueEx(hkey, 'BinPath')[0]
- winreg.CloseKey(hkey)
- binpath += '\\convert.exe'
- break
- except Exception:
- binpath = ''
- rcParams[cls.exec_key] = rcParamsDefault[cls.exec_key] = binpath
-
- @classmethod
- def isAvailable(cls):
- '''
- Check to see if a ImageMagickWriter is actually available.
-
- Done by first checking the windows registry (if applicable) and then
- running the commandline tool.
- '''
- bin_path = cls.bin_path()
- if bin_path == "convert":
- cls._init_from_registry()
- return super(ImageMagickBase, cls).isAvailable()
-
-ImageMagickBase._init_from_registry()
-
-
-# Note: the base classes need to be in that order to get
-# isAvailable() from ImageMagickBase called and not the
-# one from MovieWriter. The latter is then called by the
-# former.
-@writers.register('imagemagick')
-class ImageMagickWriter(ImageMagickBase, MovieWriter):
- '''Pipe-based animated gif.
-
- Frames are streamed directly to ImageMagick via a pipe and written
- in a single pass.
-
- '''
- def _args(self):
- return ([self.bin_path(),
- '-size', '%ix%i' % self.frame_size, '-depth', '8',
- '-delay', str(self.delay), '-loop', '0',
- '%s:-' % self.frame_format]
- + self.output_args)
-
-
-# Note: the base classes need to be in that order to get
-# isAvailable() from ImageMagickBase called and not the
-# one from MovieWriter. The latter is then called by the
-# former.
-@writers.register('imagemagick_file')
-class ImageMagickFileWriter(ImageMagickBase, FileMovieWriter):
- '''File-based animated gif writer.
-
- Frames are written to temporary files on disk and then stitched
- together at the end.
-
- '''
-
- supported_formats = ['png', 'jpeg', 'ppm', 'tiff', 'sgi', 'bmp',
- 'pbm', 'raw', 'rgba']
-
- def _args(self):
- return ([self.bin_path(), '-delay', str(self.delay), '-loop', '0',
- '%s*.%s' % (self.temp_prefix, self.frame_format)]
- + self.output_args)
-
-
-# Taken directly from jakevdp's JSAnimation package at
-# http://github.com/jakevdp/JSAnimation
-def _included_frames(frame_list, frame_format):
- """frame_list should be a list of filenames"""
- return INCLUDED_FRAMES.format(Nframes=len(frame_list),
- frame_dir=os.path.dirname(frame_list[0]),
- frame_format=frame_format)
-
-
-def _embedded_frames(frame_list, frame_format):
- """frame_list should be a list of base64-encoded png files"""
- template = ' frames[{0}] = "data:image/{1};base64,{2}"\n'
- return "\n" + "".join(
- template.format(i, frame_format, frame_data.replace('\n', '\\\n'))
- for i, frame_data in enumerate(frame_list))
-
-
-@writers.register('html')
-class HTMLWriter(FileMovieWriter):
- supported_formats = ['png', 'jpeg', 'tiff', 'svg']
- args_key = 'animation.html_args'
-
- @classmethod
- def isAvailable(cls):
- return True
-
- def __init__(self, fps=30, codec=None, bitrate=None, extra_args=None,
- metadata=None, embed_frames=False, default_mode='loop',
- embed_limit=None):
- self.embed_frames = embed_frames
- self.default_mode = default_mode.lower()
-
- # Save embed limit, which is given in MB
- if embed_limit is None:
- self._bytes_limit = rcParams['animation.embed_limit']
- else:
- self._bytes_limit = embed_limit
-
- # Convert from MB to bytes
- self._bytes_limit *= 1024 * 1024
-
- if self.default_mode not in ['loop', 'once', 'reflect']:
- self.default_mode = 'loop'
- _log.warning("unrecognized default_mode: using 'loop'")
-
- self._saved_frames = []
- self._total_bytes = 0
- self._hit_limit = False
- super(HTMLWriter, self).__init__(fps, codec, bitrate,
- extra_args, metadata)
-
- def setup(self, fig, outfile, dpi, frame_dir=None):
- root, ext = os.path.splitext(outfile)
- if ext not in ['.html', '.htm']:
- raise ValueError("outfile must be *.htm or *.html")
-
- if not self.embed_frames:
- if frame_dir is None:
- frame_dir = root + '_frames'
- if not os.path.exists(frame_dir):
- os.makedirs(frame_dir)
- frame_prefix = os.path.join(frame_dir, 'frame')
- else:
- frame_prefix = None
-
- super(HTMLWriter, self).setup(fig, outfile, dpi,
- frame_prefix, clear_temp=False)
-
- def grab_frame(self, **savefig_kwargs):
- if self.embed_frames:
- # Just stop processing if we hit the limit
- if self._hit_limit:
- return
- suffix = '.' + self.frame_format
- f = BytesIO()
- self.fig.savefig(f, format=self.frame_format,
- dpi=self.dpi, **savefig_kwargs)
- imgdata64 = encodebytes(f.getvalue()).decode('ascii')
- self._total_bytes += len(imgdata64)
- if self._total_bytes >= self._bytes_limit:
- _log.warning(
- "Animation size has reached %s bytes, exceeding the limit "
- "of %s. If you're sure you want a larger animation "
- "embedded, set the animation.embed_limit rc parameter to "
- "a larger value (in MB). This and further frames will be "
- "dropped.", self._total_bytes, self._bytes_limit)
- self._hit_limit = True
- else:
- self._saved_frames.append(imgdata64)
- else:
- return super(HTMLWriter, self).grab_frame(**savefig_kwargs)
-
- def _run(self):
- # make a duck-typed subprocess stand in
- # this is called by the MovieWriter base class, but not used here.
- class ProcessStandin(object):
- returncode = 0
-
- def communicate(self):
- return '', ''
-
- self._proc = ProcessStandin()
-
- # save the frames to an html file
- if self.embed_frames:
- fill_frames = _embedded_frames(self._saved_frames,
- self.frame_format)
- else:
- # temp names is filled by FileMovieWriter
- fill_frames = _included_frames(self._temp_names,
- self.frame_format)
-
- mode_dict = dict(once_checked='',
- loop_checked='',
- reflect_checked='')
- mode_dict[self.default_mode + '_checked'] = 'checked'
-
- interval = 1000 // self.fps
-
- with open(self.outfile, 'w') as of:
- of.write(JS_INCLUDE)
- of.write(DISPLAY_TEMPLATE.format(id=uuid.uuid4().hex,
- Nframes=len(self._temp_names),
- fill_frames=fill_frames,
- interval=interval,
- **mode_dict))
-
-
-class Animation(object):
- '''This class wraps the creation of an animation using matplotlib.
-
- It is only a base class which should be subclassed to provide
- needed behavior.
-
- This class is not typically used directly.
-
- Parameters
- ----------
- fig : matplotlib.figure.Figure
- The figure object that is used to get draw, resize, and any
- other needed events.
-
- event_source : object, optional
- A class that can run a callback when desired events
- are generated, as well as be stopped and started.
-
- Examples include timers (see :class:`TimedAnimation`) and file
- system notifications.
-
- blit : bool, optional
- controls whether blitting is used to optimize drawing. Defaults
- to ``False``.
-
- See Also
- --------
- FuncAnimation, ArtistAnimation
-
- '''
- def __init__(self, fig, event_source=None, blit=False):
- self._fig = fig
- # Disables blitting for backends that don't support it. This
- # allows users to request it if available, but still have a
- # fallback that works if it is not.
- self._blit = blit and fig.canvas.supports_blit
-
- # These are the basics of the animation. The frame sequence represents
- # information for each frame of the animation and depends on how the
- # drawing is handled by the subclasses. The event source fires events
- # that cause the frame sequence to be iterated.
- self.frame_seq = self.new_frame_seq()
- self.event_source = event_source
-
- # Instead of starting the event source now, we connect to the figure's
- # draw_event, so that we only start once the figure has been drawn.
- self._first_draw_id = fig.canvas.mpl_connect('draw_event', self._start)
-
- # Connect to the figure's close_event so that we don't continue to
- # fire events and try to draw to a deleted figure.
- self._close_id = self._fig.canvas.mpl_connect('close_event',
- self._stop)
- if self._blit:
- self._setup_blit()
-
- def _start(self, *args):
- '''
- Starts interactive animation. Adds the draw frame command to the GUI
- handler, calls show to start the event loop.
- '''
- # First disconnect our draw event handler
- self._fig.canvas.mpl_disconnect(self._first_draw_id)
- self._first_draw_id = None # So we can check on save
-
- # Now do any initial draw
- self._init_draw()
-
- # Add our callback for stepping the animation and
- # actually start the event_source.
- self.event_source.add_callback(self._step)
- self.event_source.start()
-
- def _stop(self, *args):
- # On stop we disconnect all of our events.
- if self._blit:
- self._fig.canvas.mpl_disconnect(self._resize_id)
- self._fig.canvas.mpl_disconnect(self._close_id)
- self.event_source.remove_callback(self._step)
- self.event_source = None
-
- def save(self, filename, writer=None, fps=None, dpi=None, codec=None,
- bitrate=None, extra_args=None, metadata=None, extra_anim=None,
- savefig_kwargs=None):
- '''Saves a movie file by drawing every frame.
-
- Parameters
- ----------
-
- filename : str
- The output filename, e.g., :file:`mymovie.mp4`.
-
- writer : :class:`MovieWriter` or str, optional
- A `MovieWriter` instance to use or a key that identifies a
- class to use, such as 'ffmpeg'. If ``None``, defaults to
- :rc:`animation.writer`.
-
- fps : number, optional
- Frames per second in the movie. Defaults to ``None``, which will use
- the animation's specified interval to set the frames per second.
-
- dpi : number, optional
- Controls the dots per inch for the movie frames. This combined with
- the figure's size in inches controls the size of the movie. If
- ``None``, defaults to :rc:`savefig.dpi`.
-
- codec : str, optional
- The video codec to be used. Not all codecs are supported
- by a given :class:`MovieWriter`. If ``None``, default to
- :rc:`animation.codec`.
-
- bitrate : number, optional
- Specifies the number of bits used per second in the compressed
- movie, in kilobits per second. A higher number means a higher
- quality movie, but at the cost of increased file size. If ``None``,
- defaults to :rc:`animation.bitrate`.
-
- extra_args : list, optional
- List of extra string arguments to be passed to the underlying movie
- utility. If ``None``, defaults to :rc:`animation.extra_args`.
-
- metadata : Dict[str, str], optional
- Dictionary of keys and values for metadata to include in
- the output file. Some keys that may be of use include:
- title, artist, genre, subject, copyright, srcform, comment.
-
- extra_anim : list, optional
- Additional `Animation` objects that should be included
- in the saved movie file. These need to be from the same
- `matplotlib.figure.Figure` instance. Also, animation frames will
- just be simply combined, so there should be a 1:1 correspondence
- between the frames from the different animations.
-
- savefig_kwargs : dict, optional
- Is a dictionary containing keyword arguments to be passed
- on to the `savefig` command which is called repeatedly to
- save the individual frames.
-
- Notes
- -----
- fps, codec, bitrate, extra_args, metadata are used to
- construct a :class:`MovieWriter` instance and can only be
- passed if `writer` is a string. If they are passed as
- non-`None` and ``writer`` is a :class:`MovieWriter`, a
- `RuntimeError` will be raised.
-
- '''
- # If the writer is None, use the rc param to find the name of the one
- # to use
- if writer is None:
- writer = rcParams['animation.writer']
- elif (not isinstance(writer, six.string_types) and
- any(arg is not None
- for arg in (fps, codec, bitrate, extra_args, metadata))):
- raise RuntimeError('Passing in values for arguments '
- 'fps, codec, bitrate, extra_args, or metadata '
- 'is not supported when writer is an existing '
- 'MovieWriter instance. These should instead be '
- 'passed as arguments when creating the '
- 'MovieWriter instance.')
-
- if savefig_kwargs is None:
- savefig_kwargs = {}
-
- # Need to disconnect the first draw callback, since we'll be doing
- # draws. Otherwise, we'll end up starting the animation.
- if self._first_draw_id is not None:
- self._fig.canvas.mpl_disconnect(self._first_draw_id)
- reconnect_first_draw = True
- else:
- reconnect_first_draw = False
-
- if fps is None and hasattr(self, '_interval'):
- # Convert interval in ms to frames per second
- fps = 1000. / self._interval
-
- # Re-use the savefig DPI for ours if none is given
- if dpi is None:
- dpi = rcParams['savefig.dpi']
- if dpi == 'figure':
- dpi = self._fig.dpi
-
- if codec is None:
- codec = rcParams['animation.codec']
-
- if bitrate is None:
- bitrate = rcParams['animation.bitrate']
-
- all_anim = [self]
- if extra_anim is not None:
- all_anim.extend(anim
- for anim
- in extra_anim if anim._fig is self._fig)
-
- # If we have the name of a writer, instantiate an instance of the
- # registered class.
- if isinstance(writer, six.string_types):
- if writer in writers.avail:
- writer = writers[writer](fps, codec, bitrate,
- extra_args=extra_args,
- metadata=metadata)
- else:
- _log.warning("MovieWriter %s unavailable.", writer)
-
- try:
- writer = writers[writers.list()[0]](fps, codec, bitrate,
- extra_args=extra_args,
- metadata=metadata)
- except IndexError:
- raise ValueError("Cannot save animation: no writers are "
- "available. Please install ffmpeg to "
- "save animations.")
- _log.info('Animation.save using %s', type(writer))
-
- if 'bbox_inches' in savefig_kwargs:
- _log.warning("Warning: discarding the 'bbox_inches' argument in "
- "'savefig_kwargs' as it may cause frame size "
- "to vary, which is inappropriate for animation.")
- savefig_kwargs.pop('bbox_inches')
-
- # Create a new sequence of frames for saved data. This is different
- # from new_frame_seq() to give the ability to save 'live' generated
- # frame information to be saved later.
- # TODO: Right now, after closing the figure, saving a movie won't work
- # since GUI widgets are gone. Either need to remove extra code to
- # allow for this non-existent use case or find a way to make it work.
- with rc_context():
- if rcParams['savefig.bbox'] == 'tight':
- _log.info("Disabling savefig.bbox = 'tight', as it may cause "
- "frame size to vary, which is inappropriate for "
- "animation.")
- rcParams['savefig.bbox'] = None
- with writer.saving(self._fig, filename, dpi):
- for anim in all_anim:
- # Clear the initial frame
- anim._init_draw()
- for data in zip(*[a.new_saved_frame_seq() for a in all_anim]):
- for anim, d in zip(all_anim, data):
- # TODO: See if turning off blit is really necessary
- anim._draw_next_frame(d, blit=False)
- writer.grab_frame(**savefig_kwargs)
-
- # Reconnect signal for first draw if necessary
- if reconnect_first_draw:
- self._first_draw_id = self._fig.canvas.mpl_connect('draw_event',
- self._start)
-
- def _step(self, *args):
- '''
- Handler for getting events. By default, gets the next frame in the
- sequence and hands the data off to be drawn.
- '''
- # Returns True to indicate that the event source should continue to
- # call _step, until the frame sequence reaches the end of iteration,
- # at which point False will be returned.
- try:
- framedata = next(self.frame_seq)
- self._draw_next_frame(framedata, self._blit)
- return True
- except StopIteration:
- return False
-
- def new_frame_seq(self):
- '''Creates a new sequence of frame information.'''
- # Default implementation is just an iterator over self._framedata
- return iter(self._framedata)
-
- def new_saved_frame_seq(self):
- '''Creates a new sequence of saved/cached frame information.'''
- # Default is the same as the regular frame sequence
- return self.new_frame_seq()
-
- def _draw_next_frame(self, framedata, blit):
- # Breaks down the drawing of the next frame into steps of pre- and
- # post- draw, as well as the drawing of the frame itself.
- self._pre_draw(framedata, blit)
- self._draw_frame(framedata)
- self._post_draw(framedata, blit)
-
- def _init_draw(self):
- # Initial draw to clear the frame. Also used by the blitting code
- # when a clean base is required.
- pass
-
- def _pre_draw(self, framedata, blit):
- # Perform any cleaning or whatnot before the drawing of the frame.
- # This default implementation allows blit to clear the frame.
- if blit:
- self._blit_clear(self._drawn_artists, self._blit_cache)
-
- def _draw_frame(self, framedata):
- # Performs actual drawing of the frame.
- raise NotImplementedError('Needs to be implemented by subclasses to'
- ' actually make an animation.')
-
- def _post_draw(self, framedata, blit):
- # After the frame is rendered, this handles the actual flushing of
- # the draw, which can be a direct draw_idle() or make use of the
- # blitting.
- if blit and self._drawn_artists:
- self._blit_draw(self._drawn_artists, self._blit_cache)
- else:
- self._fig.canvas.draw_idle()
-
- # The rest of the code in this class is to facilitate easy blitting
- def _blit_draw(self, artists, bg_cache):
- # Handles blitted drawing, which renders only the artists given instead
- # of the entire figure.
- updated_ax = []
- for a in artists:
- # If we haven't cached the background for this axes object, do
- # so now. This might not always be reliable, but it's an attempt
- # to automate the process.
- if a.axes not in bg_cache:
- bg_cache[a.axes] = a.figure.canvas.copy_from_bbox(a.axes.bbox)
- a.axes.draw_artist(a)
- updated_ax.append(a.axes)
-
- # After rendering all the needed artists, blit each axes individually.
- for ax in set(updated_ax):
- ax.figure.canvas.blit(ax.bbox)
-
- def _blit_clear(self, artists, bg_cache):
- # Get a list of the axes that need clearing from the artists that
- # have been drawn. Grab the appropriate saved background from the
- # cache and restore.
- axes = set(a.axes for a in artists)
- for a in axes:
- if a in bg_cache:
- a.figure.canvas.restore_region(bg_cache[a])
-
- def _setup_blit(self):
- # Setting up the blit requires: a cache of the background for the
- # axes
- self._blit_cache = dict()
- self._drawn_artists = []
- self._resize_id = self._fig.canvas.mpl_connect('resize_event',
- self._handle_resize)
- self._post_draw(None, self._blit)
-
- def _handle_resize(self, *args):
- # On resize, we need to disable the resize event handling so we don't
- # get too many events. Also stop the animation events, so that
- # we're paused. Reset the cache and re-init. Set up an event handler
- # to catch once the draw has actually taken place.
- self._fig.canvas.mpl_disconnect(self._resize_id)
- self.event_source.stop()
- self._blit_cache.clear()
- self._init_draw()
- self._resize_id = self._fig.canvas.mpl_connect('draw_event',
- self._end_redraw)
-
- def _end_redraw(self, evt):
- # Now that the redraw has happened, do the post draw flushing and
- # blit handling. Then re-enable all of the original events.
- self._post_draw(None, False)
- self.event_source.start()
- self._fig.canvas.mpl_disconnect(self._resize_id)
- self._resize_id = self._fig.canvas.mpl_connect('resize_event',
- self._handle_resize)
-
- def to_html5_video(self, embed_limit=None):
- '''Returns animation as an HTML5 video tag.
-
- This saves the animation as an h264 video, encoded in base64
- directly into the HTML5 video tag. This respects the rc parameters
- for the writer as well as the bitrate. This also makes use of the
- ``interval`` to control the speed, and uses the ``repeat``
- parameter to decide whether to loop.
- '''
- VIDEO_TAG = r'''<video {size} {options}>
- <source type="video/mp4" src="data:video/mp4;base64,{video}">
- Your browser does not support the video tag.
-</video>'''
- # Cache the rendering of the video as HTML
- if not hasattr(self, '_base64_video'):
- # Save embed limit, which is given in MB
- if embed_limit is None:
- embed_limit = rcParams['animation.embed_limit']
-
- # Convert from MB to bytes
- embed_limit *= 1024 * 1024
-
- # First write the video to a tempfile. Set delete to False
- # so we can re-open to read binary data.
- with tempfile.NamedTemporaryFile(suffix='.m4v',
- delete=False) as f:
- # We create a writer manually so that we can get the
- # appropriate size for the tag
- Writer = writers[rcParams['animation.writer']]
- writer = Writer(codec='h264',
- bitrate=rcParams['animation.bitrate'],
- fps=1000. / self._interval)
- self.save(f.name, writer=writer)
-
- # Now open and base64 encode
- with open(f.name, 'rb') as video:
- vid64 = encodebytes(video.read())
- vid_len = len(vid64)
- if vid_len >= embed_limit:
- _log.warning(
- "Animation movie is %s bytes, exceeding the limit of "
- "%s. If you're sure you want a large animation "
- "embedded, set the animation.embed_limit rc parameter "
- "to a larger value (in MB).", vid_len, embed_limit)
- else:
- self._base64_video = vid64.decode('ascii')
- self._video_size = 'width="{}" height="{}"'.format(
- *writer.frame_size)
-
- # Now we can remove
- os.remove(f.name)
-
- # If we exceeded the size, this attribute won't exist
- if hasattr(self, '_base64_video'):
- # Default HTML5 options are to autoplay and display video controls
- options = ['controls', 'autoplay']
-
- # If we're set to repeat, make it loop
- if hasattr(self, 'repeat') and self.repeat:
- options.append('loop')
-
- return VIDEO_TAG.format(video=self._base64_video,
- size=self._video_size,
- options=' '.join(options))
- else:
- return 'Video too large to embed.'
-
- def to_jshtml(self, fps=None, embed_frames=True, default_mode=None):
- """Generate HTML representation of the animation"""
- if fps is None and hasattr(self, '_interval'):
- # Convert interval in ms to frames per second
- fps = 1000 / self._interval
-
- # If we're not given a default mode, choose one base on the value of
- # the repeat attribute
- if default_mode is None:
- default_mode = 'loop' if self.repeat else 'once'
-
- if hasattr(self, "_html_representation"):
- return self._html_representation
- else:
- # Can't open a second time while opened on windows. So we avoid
- # deleting when closed, and delete manually later.
- with tempfile.NamedTemporaryFile(suffix='.html',
- delete=False) as f:
- self.save(f.name, writer=HTMLWriter(fps=fps,
- embed_frames=embed_frames,
- default_mode=default_mode))
- # Re-open and get content
- with open(f.name) as fobj:
- html = fobj.read()
-
- # Now we can delete
- os.remove(f.name)
-
- self._html_representation = html
- return html
-
- def _repr_html_(self):
- '''IPython display hook for rendering.'''
- fmt = rcParams['animation.html']
- if fmt == 'html5':
- return self.to_html5_video()
- elif fmt == 'jshtml':
- return self.to_jshtml()
-
-
-class TimedAnimation(Animation):
- ''':class:`Animation` subclass for time-based animation.
-
- A new frame is drawn every *interval* milliseconds.
-
- Parameters
- ----------
- fig : matplotlib.figure.Figure
- The figure object that is used to get draw, resize, and any
- other needed events.
-
- interval : number, optional
- Delay between frames in milliseconds. Defaults to 200.
-
- repeat_delay : number, optional
- If the animation in repeated, adds a delay in milliseconds
- before repeating the animation. Defaults to ``None``.
-
- repeat : bool, optional
- Controls whether the animation should repeat when the sequence
- of frames is completed. Defaults to ``True``.
-
- blit : bool, optional
- Controls whether blitting is used to optimize drawing. Defaults
- to ``False``.
-
- '''
- def __init__(self, fig, interval=200, repeat_delay=None, repeat=True,
- event_source=None, *args, **kwargs):
- # Store the timing information
- self._interval = interval
- self._repeat_delay = repeat_delay
- self.repeat = repeat
-
- # If we're not given an event source, create a new timer. This permits
- # sharing timers between animation objects for syncing animations.
- if event_source is None:
- event_source = fig.canvas.new_timer()
- event_source.interval = self._interval
-
- Animation.__init__(self, fig, event_source=event_source,
- *args, **kwargs)
-
- def _step(self, *args):
- '''
- Handler for getting events.
- '''
- # Extends the _step() method for the Animation class. If
- # Animation._step signals that it reached the end and we want to
- # repeat, we refresh the frame sequence and return True. If
- # _repeat_delay is set, change the event_source's interval to our loop
- # delay and set the callback to one which will then set the interval
- # back.
- still_going = Animation._step(self, *args)
- if not still_going and self.repeat:
- self._init_draw()
- self.frame_seq = self.new_frame_seq()
- if self._repeat_delay:
- self.event_source.remove_callback(self._step)
- self.event_source.add_callback(self._loop_delay)
- self.event_source.interval = self._repeat_delay
- return True
- else:
- return Animation._step(self, *args)
- else:
- return still_going
-
- def _stop(self, *args):
- # If we stop in the middle of a loop delay (which is relatively likely
- # given the potential pause here, remove the loop_delay callback as
- # well.
- self.event_source.remove_callback(self._loop_delay)
- Animation._stop(self)
-
- def _loop_delay(self, *args):
- # Reset the interval and change callbacks after the delay.
- self.event_source.remove_callback(self._loop_delay)
- self.event_source.interval = self._interval
- self.event_source.add_callback(self._step)
- Animation._step(self)
-
-
-class ArtistAnimation(TimedAnimation):
- '''Animation using a fixed set of `Artist` objects.
-
- Before creating an instance, all plotting should have taken place
- and the relevant artists saved.
-
- Parameters
- ----------
- fig : matplotlib.figure.Figure
- The figure object that is used to get draw, resize, and any
- other needed events.
-
- artists : list
- Each list entry a collection of artists that represent what
- needs to be enabled on each frame. These will be disabled for
- other frames.
-
- interval : number, optional
- Delay between frames in milliseconds. Defaults to 200.
-
- repeat_delay : number, optional
- If the animation in repeated, adds a delay in milliseconds
- before repeating the animation. Defaults to ``None``.
-
- repeat : bool, optional
- Controls whether the animation should repeat when the sequence
- of frames is completed. Defaults to ``True``.
-
- blit : bool, optional
- Controls whether blitting is used to optimize drawing. Defaults
- to ``False``.
-
- '''
- def __init__(self, fig, artists, *args, **kwargs):
- # Internal list of artists drawn in the most recent frame.
- self._drawn_artists = []
-
- # Use the list of artists as the framedata, which will be iterated
- # over by the machinery.
- self._framedata = artists
- TimedAnimation.__init__(self, fig, *args, **kwargs)
-
- def _init_draw(self):
- # Make all the artists involved in *any* frame invisible
- figs = set()
- for f in self.new_frame_seq():
- for artist in f:
- artist.set_visible(False)
- artist.set_animated(self._blit)
- # Assemble a list of unique figures that need flushing
- if artist.get_figure() not in figs:
- figs.add(artist.get_figure())
-
- # Flush the needed figures
- for fig in figs:
- fig.canvas.draw_idle()
-
- def _pre_draw(self, framedata, blit):
- '''
- Clears artists from the last frame.
- '''
- if blit:
- # Let blit handle clearing
- self._blit_clear(self._drawn_artists, self._blit_cache)
- else:
- # Otherwise, make all the artists from the previous frame invisible
- for artist in self._drawn_artists:
- artist.set_visible(False)
-
- def _draw_frame(self, artists):
- # Save the artists that were passed in as framedata for the other
- # steps (esp. blitting) to use.
- self._drawn_artists = artists
-
- # Make all the artists from the current frame visible
- for artist in artists:
- artist.set_visible(True)
-
-
-class FuncAnimation(TimedAnimation):
- '''
- Makes an animation by repeatedly calling a function ``func``.
-
- Parameters
- ----------
- fig : matplotlib.figure.Figure
- The figure object that is used to get draw, resize, and any
- other needed events.
-
- func : callable
- The function to call at each frame. The first argument will
- be the next value in ``frames``. Any additional positional
- arguments can be supplied via the ``fargs`` parameter.
-
- The required signature is::
-
- def func(frame, *fargs) -> iterable_of_artists:
-
- frames : iterable, int, generator function, or None, optional
- Source of data to pass ``func`` and each frame of the animation
-
- If an iterable, then simply use the values provided. If the
- iterable has a length, it will override the ``save_count`` kwarg.
-
- If an integer, then equivalent to passing ``range(frames)``
-
- If a generator function, then must have the signature::
-
- def gen_function() -> obj:
-
- If ``None``, then equivalent to passing ``itertools.count``.
-
- In all of these cases, the values in *frames* is simply passed through
- to the user-supplied *func* and thus can be of any type.
-
- init_func : callable, optional
- A function used to draw a clear frame. If not given, the
- results of drawing from the first item in the frames sequence
- will be used. This function will be called once before the
- first frame.
-
- If ``blit == True``, ``init_func`` must return an iterable of artists
- to be re-drawn.
-
- The required signature is::
-
- def init_func() -> iterable_of_artists:
-
- fargs : tuple or None, optional
- Additional arguments to pass to each call to *func*.
-
- save_count : int, optional
- The number of values from *frames* to cache.
-
- interval : number, optional
- Delay between frames in milliseconds. Defaults to 200.
-
- repeat_delay : number, optional
- If the animation in repeated, adds a delay in milliseconds
- before repeating the animation. Defaults to ``None``.
-
- repeat : bool, optional
- Controls whether the animation should repeat when the sequence
- of frames is completed. Defaults to ``True``.
-
- blit : bool, optional
- Controls whether blitting is used to optimize drawing. Defaults
- to ``False``.
-
- '''
- def __init__(self, fig, func, frames=None, init_func=None, fargs=None,
- save_count=None, **kwargs):
- if fargs:
- self._args = fargs
- else:
- self._args = ()
- self._func = func
-
- # Amount of framedata to keep around for saving movies. This is only
- # used if we don't know how many frames there will be: in the case
- # of no generator or in the case of a callable.
- self.save_count = save_count
- # Set up a function that creates a new iterable when needed. If nothing
- # is passed in for frames, just use itertools.count, which will just
- # keep counting from 0. A callable passed in for frames is assumed to
- # be a generator. An iterable will be used as is, and anything else
- # will be treated as a number of frames.
- if frames is None:
- self._iter_gen = itertools.count
- elif callable(frames):
- self._iter_gen = frames
- elif cbook.iterable(frames):
- self._iter_gen = lambda: iter(frames)
- if hasattr(frames, '__len__'):
- self.save_count = len(frames)
- else:
- self._iter_gen = lambda: iter(xrange(frames))
- self.save_count = frames
-
- if self.save_count is None:
- # If we're passed in and using the default, set save_count to 100.
- self.save_count = 100
- else:
- # itertools.islice returns an error when passed a numpy int instead
- # of a native python int (http://bugs.python.org/issue30537).
- # As a workaround, convert save_count to a native python int.
- self.save_count = int(self.save_count)
-
- self._init_func = init_func
-
- # Needs to be initialized so the draw functions work without checking
- self._save_seq = []
-
- TimedAnimation.__init__(self, fig, **kwargs)
-
- # Need to reset the saved seq, since right now it will contain data
- # for a single frame from init, which is not what we want.
- self._save_seq = []
-
- def new_frame_seq(self):
- # Use the generating function to generate a new frame sequence
- return self._iter_gen()
-
- def new_saved_frame_seq(self):
- # Generate an iterator for the sequence of saved data. If there are
- # no saved frames, generate a new frame sequence and take the first
- # save_count entries in it.
- if self._save_seq:
- # While iterating we are going to update _save_seq
- # so make a copy to safely iterate over
- self._old_saved_seq = list(self._save_seq)
- return iter(self._old_saved_seq)
- else:
- if self.save_count is not None:
- return itertools.islice(self.new_frame_seq(), self.save_count)
-
- else:
- frame_seq = self.new_frame_seq()
-
- def gen():
- try:
- for _ in range(100):
- yield next(frame_seq)
- except StopIteration:
- pass
- else:
- cbook.warn_deprecated(
- "2.2", "FuncAnimation.save has truncated your "
- "animation to 100 frames. In the future, no such "
- "truncation will occur; please pass 'save_count' "
- "accordingly.")
-
- return gen()
-
- def _init_draw(self):
- # Initialize the drawing either using the given init_func or by
- # calling the draw function with the first item of the frame sequence.
- # For blitting, the init_func should return a sequence of modified
- # artists.
- if self._init_func is None:
- self._draw_frame(next(self.new_frame_seq()))
-
- else:
- self._drawn_artists = self._init_func()
- if self._blit:
- if self._drawn_artists is None:
- raise RuntimeError('The init_func must return a '
- 'sequence of Artist objects.')
- for a in self._drawn_artists:
- a.set_animated(self._blit)
- self._save_seq = []
-
- def _draw_frame(self, framedata):
- # Save the data for potential saving of movies.
- self._save_seq.append(framedata)
-
- # Make sure to respect save_count (keep only the last save_count
- # around)
- self._save_seq = self._save_seq[-self.save_count:]
-
- # Call the func with framedata and args. If blitting is desired,
- # func needs to return a sequence of any artists that were modified.
- self._drawn_artists = self._func(framedata, *self._args)
- if self._blit:
- if self._drawn_artists is None:
- raise RuntimeError('The animation function must return a '
- 'sequence of Artist objects.')
- for a in self._drawn_artists:
- a.set_animated(self._blit)
diff --git a/contrib/python/matplotlib/py2/matplotlib/artist.py b/contrib/python/matplotlib/py2/matplotlib/artist.py
deleted file mode 100644
index 8dc1034bc7..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/artist.py
+++ /dev/null
@@ -1,1482 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from collections import OrderedDict, namedtuple
-from functools import wraps
-import inspect
-import re
-import warnings
-
-import numpy as np
-
-import matplotlib
-from . import cbook, docstring, rcParams
-from .path import Path
-from .transforms import (Bbox, IdentityTransform, Transform, TransformedBbox,
- TransformedPatchPath, TransformedPath)
-# Note, matplotlib artists use the doc strings for set and get
-# methods to enable the introspection methods of setp and getp. Every
-# set_* method should have a docstring containing the line
-#
-# ACCEPTS: [ legal | values ]
-#
-# and aliases for setters and getters should have a docstring that
-# starts with 'alias for ', as in 'alias for set_somemethod'
-#
-# You may wonder why we use so much boiler-plate manually defining the
-# set_alias and get_alias functions, rather than using some clever
-# python trick. The answer is that I need to be able to manipulate
-# the docstring, and there is no clever way to do that in python 2.2,
-# as far as I can see - see
-#
-# https://mail.python.org/pipermail/python-list/2004-October/242925.html
-
-
-def allow_rasterization(draw):
- """
- Decorator for Artist.draw method. Provides routines
- that run before and after the draw call. The before and after functions
- are useful for changing artist-dependent renderer attributes or making
- other setup function calls, such as starting and flushing a mixed-mode
- renderer.
- """
-
- # the axes class has a second argument inframe for its draw method.
- @wraps(draw)
- def draw_wrapper(artist, renderer, *args, **kwargs):
- try:
- if artist.get_rasterized():
- renderer.start_rasterizing()
- if artist.get_agg_filter() is not None:
- renderer.start_filter()
-
- return draw(artist, renderer, *args, **kwargs)
- finally:
- if artist.get_agg_filter() is not None:
- renderer.stop_filter(artist.get_agg_filter())
- if artist.get_rasterized():
- renderer.stop_rasterizing()
-
- draw_wrapper._supports_rasterization = True
- return draw_wrapper
-
-
-def _stale_axes_callback(self, val):
- if self.axes:
- self.axes.stale = val
-
-
-_XYPair = namedtuple("_XYPair", "x y")
-
-
-class Artist(object):
- """
- Abstract base class for someone who renders into a
- :class:`FigureCanvas`.
- """
-
- aname = 'Artist'
- zorder = 0
- # order of precedence when bulk setting/updating properties
- # via update. The keys should be property names and the values
- # integers
- _prop_order = dict(color=-1)
-
- def __init__(self):
- self._stale = True
- self.stale_callback = None
- self._axes = None
- self.figure = None
-
- self._transform = None
- self._transformSet = False
- self._visible = True
- self._animated = False
- self._alpha = None
- self.clipbox = None
- self._clippath = None
- self._clipon = True
- self._label = ''
- self._picker = None
- self._contains = None
- self._rasterized = None
- self._agg_filter = None
- self._mouseover = False
- self.eventson = False # fire events only if eventson
- self._oid = 0 # an observer id
- self._propobservers = {} # a dict from oids to funcs
- try:
- self.axes = None
- except AttributeError:
- # Handle self.axes as a read-only property, as in Figure.
- pass
- self._remove_method = None
- self._url = None
- self._gid = None
- self._snap = None
- self._sketch = rcParams['path.sketch']
- self._path_effects = rcParams['path.effects']
- self._sticky_edges = _XYPair([], [])
-
- def __getstate__(self):
- d = self.__dict__.copy()
- # remove the unpicklable remove method, this will get re-added on load
- # (by the axes) if the artist lives on an axes.
- d['_remove_method'] = None
- d['stale_callback'] = None
- return d
-
- def remove(self):
- """
- Remove the artist from the figure if possible. The effect
- will not be visible until the figure is redrawn, e.g., with
- :meth:`matplotlib.axes.Axes.draw_idle`. Call
- :meth:`matplotlib.axes.Axes.relim` to update the axes limits
- if desired.
-
- Note: :meth:`~matplotlib.axes.Axes.relim` will not see
- collections even if the collection was added to axes with
- *autolim* = True.
-
- Note: there is no support for removing the artist's legend entry.
- """
-
- # There is no method to set the callback. Instead the parent should
- # set the _remove_method attribute directly. This would be a
- # protected attribute if Python supported that sort of thing. The
- # callback has one parameter, which is the child to be removed.
- if self._remove_method is not None:
- self._remove_method(self)
- # clear stale callback
- self.stale_callback = None
- _ax_flag = False
- if hasattr(self, 'axes') and self.axes:
- # remove from the mouse hit list
- self.axes.mouseover_set.discard(self)
- # mark the axes as stale
- self.axes.stale = True
- # decouple the artist from the axes
- self.axes = None
- _ax_flag = True
-
- if self.figure:
- self.figure = None
- if not _ax_flag:
- self.figure = True
-
- else:
- raise NotImplementedError('cannot remove artist')
- # TODO: the fix for the collections relim problem is to move the
- # limits calculation into the artist itself, including the property of
- # whether or not the artist should affect the limits. Then there will
- # be no distinction between axes.add_line, axes.add_patch, etc.
- # TODO: add legend support
-
- def have_units(self):
- 'Return *True* if units are set on the *x* or *y* axes'
- ax = self.axes
- if ax is None or ax.xaxis is None:
- return False
- return ax.xaxis.have_units() or ax.yaxis.have_units()
-
- def convert_xunits(self, x):
- """For artists in an axes, if the xaxis has units support,
- convert *x* using xaxis unit type
- """
- ax = getattr(self, 'axes', None)
- if ax is None or ax.xaxis is None:
- return x
- return ax.xaxis.convert_units(x)
-
- def convert_yunits(self, y):
- """For artists in an axes, if the yaxis has units support,
- convert *y* using yaxis unit type
- """
- ax = getattr(self, 'axes', None)
- if ax is None or ax.yaxis is None:
- return y
- return ax.yaxis.convert_units(y)
-
- @property
- def axes(self):
- """
- The :class:`~matplotlib.axes.Axes` instance the artist
- resides in, or *None*.
- """
- return self._axes
-
- @axes.setter
- def axes(self, new_axes):
- if (new_axes is not None and self._axes is not None
- and new_axes != self._axes):
- raise ValueError("Can not reset the axes. You are probably "
- "trying to re-use an artist in more than one "
- "Axes which is not supported")
- self._axes = new_axes
- if new_axes is not None and new_axes is not self:
- self.stale_callback = _stale_axes_callback
- return new_axes
-
- @property
- def stale(self):
- """
- If the artist is 'stale' and needs to be re-drawn for the output to
- match the internal state of the artist.
- """
- return self._stale
-
- @stale.setter
- def stale(self, val):
- self._stale = val
-
- # if the artist is animated it does not take normal part in the
- # draw stack and is not expected to be drawn as part of the normal
- # draw loop (when not saving) so do not propagate this change
- if self.get_animated():
- return
-
- if val and self.stale_callback is not None:
- self.stale_callback(self, val)
-
- def get_window_extent(self, renderer):
- """
- Get the axes bounding box in display space.
- Subclasses should override for inclusion in the bounding box
- "tight" calculation. Default is to return an empty bounding
- box at 0, 0.
-
- Be careful when using this function, the results will not update
- if the artist window extent of the artist changes. The extent
- can change due to any changes in the transform stack, such as
- changing the axes limits, the figure size, or the canvas used
- (as is done when saving a figure). This can lead to unexpected
- behavior where interactive figures will look fine on the screen,
- but will save incorrectly.
- """
- return Bbox([[0, 0], [0, 0]])
-
- def add_callback(self, func):
- """
- Adds a callback function that will be called whenever one of
- the :class:`Artist`'s properties changes.
-
- Returns an *id* that is useful for removing the callback with
- :meth:`remove_callback` later.
- """
- oid = self._oid
- self._propobservers[oid] = func
- self._oid += 1
- return oid
-
- def remove_callback(self, oid):
- """
- Remove a callback based on its *id*.
-
- .. seealso::
-
- :meth:`add_callback`
- For adding callbacks
-
- """
- try:
- del self._propobservers[oid]
- except KeyError:
- pass
-
- def pchanged(self):
- """
- Fire an event when property changed, calling all of the
- registered callbacks.
- """
- for oid, func in six.iteritems(self._propobservers):
- func(self)
-
- def is_transform_set(self):
- """
- Returns *True* if :class:`Artist` has a transform explicitly
- set.
- """
- return self._transformSet
-
- def set_transform(self, t):
- """
- Set the artist transform.
-
- Parameters
- ----------
- t : `.Transform`
- .. ACCEPTS: `.Transform`
- """
- self._transform = t
- self._transformSet = True
- self.pchanged()
- self.stale = True
-
- def get_transform(self):
- """
- Return the :class:`~matplotlib.transforms.Transform`
- instance used by this artist.
- """
- if self._transform is None:
- self._transform = IdentityTransform()
- elif (not isinstance(self._transform, Transform)
- and hasattr(self._transform, '_as_mpl_transform')):
- self._transform = self._transform._as_mpl_transform(self.axes)
- return self._transform
-
- @cbook.deprecated("2.2")
- def hitlist(self, event):
- """
- List the children of the artist which contain the mouse event *event*.
- """
- L = []
- try:
- hascursor, info = self.contains(event)
- if hascursor:
- L.append(self)
- except:
- import traceback
- traceback.print_exc()
- print("while checking", self.__class__)
-
- for a in self.get_children():
- L.extend(a.hitlist(event))
- return L
-
- def get_children(self):
- """
- Return a list of the child :class:`Artist`s this
- :class:`Artist` contains.
- """
- return []
-
- def contains(self, mouseevent):
- """Test whether the artist contains the mouse event.
-
- Returns the truth value and a dictionary of artist specific details of
- selection, such as which points are contained in the pick radius. See
- individual artists for details.
- """
- if callable(self._contains):
- return self._contains(self, mouseevent)
- warnings.warn("'%s' needs 'contains' method" % self.__class__.__name__)
- return False, {}
-
- def set_contains(self, picker):
- """
- Replace the contains test used by this artist. The new picker
- should be a callable function which determines whether the
- artist is hit by the mouse event::
-
- hit, props = picker(artist, mouseevent)
-
- If the mouse event is over the artist, return *hit* = *True*
- and *props* is a dictionary of properties you want returned
- with the contains test.
-
- Parameters
- ----------
- picker : callable
- .. ACCEPTS: a callable function
- """
- self._contains = picker
-
- def get_contains(self):
- """
- Return the _contains test used by the artist, or *None* for default.
- """
- return self._contains
-
- def pickable(self):
- 'Return *True* if :class:`Artist` is pickable.'
- return (self.figure is not None and
- self.figure.canvas is not None and
- self._picker is not None)
-
- def pick(self, mouseevent):
- """
- Process pick event
-
- each child artist will fire a pick event if *mouseevent* is over
- the artist and the artist has picker set
- """
- # Pick self
- if self.pickable():
- picker = self.get_picker()
- if callable(picker):
- inside, prop = picker(self, mouseevent)
- else:
- inside, prop = self.contains(mouseevent)
- if inside:
- self.figure.canvas.pick_event(mouseevent, self, **prop)
-
- # Pick children
- for a in self.get_children():
- # make sure the event happened in the same axes
- ax = getattr(a, 'axes', None)
- if (mouseevent.inaxes is None or ax is None
- or mouseevent.inaxes == ax):
- # we need to check if mouseevent.inaxes is None
- # because some objects associated with an axes (e.g., a
- # tick label) can be outside the bounding box of the
- # axes and inaxes will be None
- # also check that ax is None so that it traverse objects
- # which do no have an axes property but children might
- a.pick(mouseevent)
-
- def set_picker(self, picker):
- """
- Set the epsilon for picking used by this artist
-
- *picker* can be one of the following:
-
- * *None*: picking is disabled for this artist (default)
-
- * A boolean: if *True* then picking will be enabled and the
- artist will fire a pick event if the mouse event is over
- the artist
-
- * A float: if picker is a number it is interpreted as an
- epsilon tolerance in points and the artist will fire
- off an event if it's data is within epsilon of the mouse
- event. For some artists like lines and patch collections,
- the artist may provide additional data to the pick event
- that is generated, e.g., the indices of the data within
- epsilon of the pick event
-
- * A function: if picker is callable, it is a user supplied
- function which determines whether the artist is hit by the
- mouse event::
-
- hit, props = picker(artist, mouseevent)
-
- to determine the hit test. if the mouse event is over the
- artist, return *hit=True* and props is a dictionary of
- properties you want added to the PickEvent attributes.
-
- Parameters
- ----------
- picker : None or bool or float or callable
- .. ACCEPTS: [None | bool | float | callable]
- """
- self._picker = picker
-
- def get_picker(self):
- """Return the picker object used by this artist."""
- return self._picker
-
- @cbook.deprecated("2.2", "artist.figure is not None")
- def is_figure_set(self):
- """Returns whether the artist is assigned to a `.Figure`."""
- return self.figure is not None
-
- def get_url(self):
- """Returns the url."""
- return self._url
-
- def set_url(self, url):
- """
- Sets the url for the artist.
-
- Parameters
- ----------
- url : str
- .. ACCEPTS: a url string
- """
- self._url = url
-
- def get_gid(self):
- """Returns the group id."""
- return self._gid
-
- def set_gid(self, gid):
- """
- Sets the (group) id for the artist.
-
- Parameters
- ----------
- gid : str
- .. ACCEPTS: an id string
- """
- self._gid = gid
-
- def get_snap(self):
- """
- Returns the snap setting which may be:
-
- * True: snap vertices to the nearest pixel center
-
- * False: leave vertices as-is
-
- * None: (auto) If the path contains only rectilinear line
- segments, round to the nearest pixel center
-
- Only supported by the Agg and MacOSX backends.
- """
- if rcParams['path.snap']:
- return self._snap
- else:
- return False
-
- def set_snap(self, snap):
- """
- Sets the snap setting which may be:
-
- * True: snap vertices to the nearest pixel center
-
- * False: leave vertices as-is
-
- * None: (auto) If the path contains only rectilinear line
- segments, round to the nearest pixel center
-
- Only supported by the Agg and MacOSX backends.
-
- Parameters
- ----------
- snap : bool or None
- .. ACCEPTS: bool or None
- """
- self._snap = snap
- self.stale = True
-
- def get_sketch_params(self):
- """
- Returns the sketch parameters for the artist.
-
- Returns
- -------
- sketch_params : tuple or `None`
-
- A 3-tuple with the following elements:
-
- * `scale`: The amplitude of the wiggle perpendicular to the
- source line.
-
- * `length`: The length of the wiggle along the line.
-
- * `randomness`: The scale factor by which the length is
- shrunken or expanded.
-
- May return `None` if no sketch parameters were set.
- """
- return self._sketch
-
- def set_sketch_params(self, scale=None, length=None, randomness=None):
- """
- Sets the sketch parameters.
-
- Parameters
- ----------
-
- scale : float, optional
- The amplitude of the wiggle perpendicular to the source
- line, in pixels. If scale is `None`, or not provided, no
- sketch filter will be provided.
-
- length : float, optional
- The length of the wiggle along the line, in pixels
- (default 128.0)
-
- randomness : float, optional
- The scale factor by which the length is shrunken or
- expanded (default 16.0)
-
- .. ACCEPTS: (scale: float, length: float, randomness: float)
- """
- if scale is None:
- self._sketch = None
- else:
- self._sketch = (scale, length or 128.0, randomness or 16.0)
- self.stale = True
-
- def set_path_effects(self, path_effects):
- """Set the path effects.
-
- Parameters
- ----------
- path_effects : `.AbstractPathEffect`
- .. ACCEPTS: `.AbstractPathEffect`
- """
- self._path_effects = path_effects
- self.stale = True
-
- def get_path_effects(self):
- return self._path_effects
-
- def get_figure(self):
- """Return the `.Figure` instance the artist belongs to."""
- return self.figure
-
- def set_figure(self, fig):
- """
- Set the `.Figure` instance the artist belongs to.
-
- Parameters
- ----------
- fig : `.Figure`
- .. ACCEPTS: a `.Figure` instance
- """
- # if this is a no-op just return
- if self.figure is fig:
- return
- # if we currently have a figure (the case of both `self.figure`
- # and `fig` being none is taken care of above) we then user is
- # trying to change the figure an artist is associated with which
- # is not allowed for the same reason as adding the same instance
- # to more than one Axes
- if self.figure is not None:
- raise RuntimeError("Can not put single artist in "
- "more than one figure")
- self.figure = fig
- if self.figure and self.figure is not self:
- self.pchanged()
- self.stale = True
-
- def set_clip_box(self, clipbox):
- """
- Set the artist's clip `.Bbox`.
-
- Parameters
- ----------
- clipbox : `.Bbox`
- .. ACCEPTS: a `.Bbox` instance
- """
- self.clipbox = clipbox
- self.pchanged()
- self.stale = True
-
- def set_clip_path(self, path, transform=None):
- """
- Set the artist's clip path, which may be:
-
- - a :class:`~matplotlib.patches.Patch` (or subclass) instance; or
- - a :class:`~matplotlib.path.Path` instance, in which case a
- :class:`~matplotlib.transforms.Transform` instance, which will be
- applied to the path before using it for clipping, must be provided;
- or
- - ``None``, to remove a previously set clipping path.
-
- For efficiency, if the path happens to be an axis-aligned rectangle,
- this method will set the clipping box to the corresponding rectangle
- and set the clipping path to ``None``.
-
- ACCEPTS: [(`~matplotlib.path.Path`, `.Transform`) | `.Patch` | None]
- """
- from matplotlib.patches import Patch, Rectangle
-
- success = False
- if transform is None:
- if isinstance(path, Rectangle):
- self.clipbox = TransformedBbox(Bbox.unit(),
- path.get_transform())
- self._clippath = None
- success = True
- elif isinstance(path, Patch):
- self._clippath = TransformedPatchPath(path)
- success = True
- elif isinstance(path, tuple):
- path, transform = path
-
- if path is None:
- self._clippath = None
- success = True
- elif isinstance(path, Path):
- self._clippath = TransformedPath(path, transform)
- success = True
- elif isinstance(path, TransformedPatchPath):
- self._clippath = path
- success = True
- elif isinstance(path, TransformedPath):
- self._clippath = path
- success = True
-
- if not success:
- raise TypeError(
- "Invalid arguments to set_clip_path, of type {} and {}"
- .format(type(path).__name__, type(transform).__name__))
- # This may result in the callbacks being hit twice, but guarantees they
- # will be hit at least once.
- self.pchanged()
- self.stale = True
-
- def get_alpha(self):
- """
- Return the alpha value used for blending - not supported on all
- backends
- """
- return self._alpha
-
- def get_visible(self):
- "Return the artist's visiblity"
- return self._visible
-
- def get_animated(self):
- "Return the artist's animated state"
- return self._animated
-
- def get_clip_on(self):
- 'Return whether artist uses clipping'
- return self._clipon
-
- def get_clip_box(self):
- 'Return artist clipbox'
- return self.clipbox
-
- def get_clip_path(self):
- 'Return artist clip path'
- return self._clippath
-
- def get_transformed_clip_path_and_affine(self):
- '''
- Return the clip path with the non-affine part of its
- transformation applied, and the remaining affine part of its
- transformation.
- '''
- if self._clippath is not None:
- return self._clippath.get_transformed_path_and_affine()
- return None, None
-
- def set_clip_on(self, b):
- """
- Set whether artist uses clipping.
-
- When False artists will be visible out side of the axes which
- can lead to unexpected results.
-
- Parameters
- ----------
- b : bool
- .. ACCEPTS: bool
- """
- self._clipon = b
- # This may result in the callbacks being hit twice, but ensures they
- # are hit at least once
- self.pchanged()
- self.stale = True
-
- def _set_gc_clip(self, gc):
- 'Set the clip properly for the gc'
- if self._clipon:
- if self.clipbox is not None:
- gc.set_clip_rectangle(self.clipbox)
- gc.set_clip_path(self._clippath)
- else:
- gc.set_clip_rectangle(None)
- gc.set_clip_path(None)
-
- def get_rasterized(self):
- """Return whether the artist is to be rasterized."""
- return self._rasterized
-
- def set_rasterized(self, rasterized):
- """
- Force rasterized (bitmap) drawing in vector backend output.
-
- Defaults to None, which implies the backend's default behavior.
-
- Parameters
- ----------
- rasterized : bool or None
- .. ACCEPTS: bool or None
- """
- if rasterized and not hasattr(self.draw, "_supports_rasterization"):
- warnings.warn("Rasterization of '%s' will be ignored" % self)
-
- self._rasterized = rasterized
-
- def get_agg_filter(self):
- """Return filter function to be used for agg filter."""
- return self._agg_filter
-
- def set_agg_filter(self, filter_func):
- """Set the agg filter.
-
- Parameters
- ----------
- filter_func : callable
- A filter function, which takes a (m, n, 3) float array and a dpi
- value, and returns a (m, n, 3) array.
-
- .. ACCEPTS: a filter function, which takes a (m, n, 3) float array
- and a dpi value, and returns a (m, n, 3) array
- """
- self._agg_filter = filter_func
- self.stale = True
-
- def draw(self, renderer, *args, **kwargs):
- 'Derived classes drawing method'
- if not self.get_visible():
- return
- self.stale = False
-
- def set_alpha(self, alpha):
- """
- Set the alpha value used for blending - not supported on
- all backends.
-
- Parameters
- ----------
- alpha : float
- .. ACCEPTS: float (0.0 transparent through 1.0 opaque)
- """
- self._alpha = alpha
- self.pchanged()
- self.stale = True
-
- def set_visible(self, b):
- """
- Set the artist's visibility.
-
- Parameters
- ----------
- b : bool
- .. ACCEPTS: bool
- """
- self._visible = b
- self.pchanged()
- self.stale = True
-
- def set_animated(self, b):
- """
- Set the artist's animation state.
-
- Parameters
- ----------
- b : bool
- .. ACCEPTS: bool
- """
- if self._animated != b:
- self._animated = b
- self.pchanged()
-
- def update(self, props):
- """
- Update this artist's properties from the dictionary *prop*.
- """
- def _update_property(self, k, v):
- """Sorting out how to update property (setter or setattr).
-
- Parameters
- ----------
- k : str
- The name of property to update
- v : obj
- The value to assign to the property
-
- Returns
- -------
- ret : obj or None
- If using a `set_*` method return it's return, else None.
- """
- k = k.lower()
- # white list attributes we want to be able to update through
- # art.update, art.set, setp
- if k in {'axes'}:
- return setattr(self, k, v)
- else:
- func = getattr(self, 'set_' + k, None)
- if not callable(func):
- raise AttributeError('Unknown property %s' % k)
- return func(v)
-
- store = self.eventson
- self.eventson = False
- try:
- ret = [_update_property(self, k, v)
- for k, v in props.items()]
- finally:
- self.eventson = store
-
- if len(ret):
- self.pchanged()
- self.stale = True
- return ret
-
- def get_label(self):
- """Get the label used for this artist in the legend."""
- return self._label
-
- def set_label(self, s):
- """
- Set the label to *s* for auto legend.
-
- Parameters
- ----------
- s : object
- *s* will be converted to a string by calling `str` (`unicode` on
- Py2).
-
- .. ACCEPTS: object
- """
- if s is not None:
- self._label = six.text_type(s)
- else:
- self._label = None
- self.pchanged()
- self.stale = True
-
- def get_zorder(self):
- """Return the artist's zorder."""
- return self.zorder
-
- def set_zorder(self, level):
- """
- Set the zorder for the artist. Artists with lower zorder
- values are drawn first.
-
- Parameters
- ----------
- level : float
- .. ACCEPTS: float
- """
- if level is None:
- level = self.__class__.zorder
- self.zorder = level
- self.pchanged()
- self.stale = True
-
- @property
- def sticky_edges(self):
- """
- `x` and `y` sticky edge lists.
-
- When performing autoscaling, if a data limit coincides with a value in
- the corresponding sticky_edges list, then no margin will be added--the
- view limit "sticks" to the edge. A typical usecase is histograms,
- where one usually expects no margin on the bottom edge (0) of the
- histogram.
-
- This attribute cannot be assigned to; however, the `x` and `y` lists
- can be modified in place as needed.
-
- Examples
- --------
-
- >>> artist.sticky_edges.x[:] = (xmin, xmax)
- >>> artist.sticky_edges.y[:] = (ymin, ymax)
-
- """
- return self._sticky_edges
-
- def update_from(self, other):
- 'Copy properties from *other* to *self*.'
- self._transform = other._transform
- self._transformSet = other._transformSet
- self._visible = other._visible
- self._alpha = other._alpha
- self.clipbox = other.clipbox
- self._clipon = other._clipon
- self._clippath = other._clippath
- self._label = other._label
- self._sketch = other._sketch
- self._path_effects = other._path_effects
- self.sticky_edges.x[:] = other.sticky_edges.x[:]
- self.sticky_edges.y[:] = other.sticky_edges.y[:]
- self.pchanged()
- self.stale = True
-
- def properties(self):
- """
- return a dictionary mapping property name -> value for all Artist props
- """
- return ArtistInspector(self).properties()
-
- def set(self, **kwargs):
- """A property batch setter. Pass *kwargs* to set properties.
- """
- props = OrderedDict(
- sorted(kwargs.items(), reverse=True,
- key=lambda x: (self._prop_order.get(x[0], 0), x[0])))
-
- return self.update(props)
-
- def findobj(self, match=None, include_self=True):
- """
- Find artist objects.
-
- Recursively find all :class:`~matplotlib.artist.Artist` instances
- contained in self.
-
- *match* can be
-
- - None: return all objects contained in artist.
-
- - function with signature ``boolean = match(artist)``
- used to filter matches
-
- - class instance: e.g., Line2D. Only return artists of class type.
-
- If *include_self* is True (default), include self in the list to be
- checked for a match.
-
- """
- if match is None: # always return True
- def matchfunc(x):
- return True
- elif isinstance(match, type) and issubclass(match, Artist):
- def matchfunc(x):
- return isinstance(x, match)
- elif callable(match):
- matchfunc = match
- else:
- raise ValueError('match must be None, a matplotlib.artist.Artist '
- 'subclass, or a callable')
-
- artists = sum([c.findobj(matchfunc) for c in self.get_children()], [])
- if include_self and matchfunc(self):
- artists.append(self)
- return artists
-
- def get_cursor_data(self, event):
- """
- Get the cursor data for a given event.
- """
- return None
-
- def format_cursor_data(self, data):
- """
- Return *cursor data* string formatted.
- """
- try:
- data[0]
- except (TypeError, IndexError):
- data = [data]
- return ', '.join('{:0.3g}'.format(item) for item in data if
- isinstance(item, (np.floating, np.integer, int, float)))
-
- @property
- def mouseover(self):
- return self._mouseover
-
- @mouseover.setter
- def mouseover(self, val):
- val = bool(val)
- self._mouseover = val
- ax = self.axes
- if ax:
- if val:
- ax.mouseover_set.add(self)
- else:
- ax.mouseover_set.discard(self)
-
-
-class ArtistInspector(object):
- """
- A helper class to inspect an :class:`~matplotlib.artist.Artist`
- and return information about it's settable properties and their
- current values.
- """
- def __init__(self, o):
- r"""
- Initialize the artist inspector with an `Artist` or an iterable of
- `Artist`\s. If an iterable is used, we assume it is a homogeneous
- sequence (all `Artists` are of the same type) and it is your
- responsibility to make sure this is so.
- """
- if not isinstance(o, Artist):
- if cbook.iterable(o):
- o = list(o)
- if len(o):
- o = o[0]
-
- self.oorig = o
- if not inspect.isclass(o):
- o = type(o)
- self.o = o
-
- self.aliasd = self.get_aliases()
-
- def get_aliases(self):
- """
- Get a dict mapping *fullname* -> *alias* for each *alias* in
- the :class:`~matplotlib.artist.ArtistInspector`.
-
- e.g., for lines::
-
- {'markerfacecolor': 'mfc',
- 'linewidth' : 'lw',
- }
-
- """
- names = [name for name in dir(self.o)
- if name.startswith(('set_', 'get_'))
- and callable(getattr(self.o, name))]
- aliases = {}
- for name in names:
- func = getattr(self.o, name)
- if not self.is_alias(func):
- continue
- docstring = func.__doc__
- fullname = docstring[10:]
- aliases.setdefault(fullname[4:], {})[name[4:]] = None
- return aliases
-
- _get_valid_values_regex = re.compile(
- r"\n\s*(?:\.\.\s+)?ACCEPTS:\s*((?:.|\n)*?)(?:$|(?:\n\n))"
- )
-
- def get_valid_values(self, attr):
- """
- Get the legal arguments for the setter associated with *attr*.
-
- This is done by querying the docstring of the function *set_attr*
- for a line that begins with "ACCEPTS" or ".. ACCEPTS":
-
- e.g., for a line linestyle, return
- "[ ``'-'`` | ``'--'`` | ``'-.'`` | ``':'`` | ``'steps'`` | ``'None'``
- ]"
- """
-
- name = 'set_%s' % attr
- if not hasattr(self.o, name):
- raise AttributeError('%s has no function %s' % (self.o, name))
- func = getattr(self.o, name)
-
- docstring = func.__doc__
- if docstring is None:
- return 'unknown'
-
- if docstring.startswith('alias for '):
- return None
-
- match = self._get_valid_values_regex.search(docstring)
- if match is not None:
- return re.sub("\n *", " ", match.group(1))
- return 'unknown'
-
- def _get_setters_and_targets(self):
- """
- Get the attribute strings and a full path to where the setter
- is defined for all setters in an object.
- """
-
- setters = []
- for name in dir(self.o):
- if not name.startswith('set_'):
- continue
- func = getattr(self.o, name)
- if not callable(func):
- continue
- if six.PY2:
- nargs = len(inspect.getargspec(func)[0])
- else:
- nargs = len(inspect.getfullargspec(func)[0])
- if nargs < 2 or self.is_alias(func):
- continue
- source_class = self.o.__module__ + "." + self.o.__name__
- for cls in self.o.mro():
- if name in cls.__dict__:
- source_class = cls.__module__ + "." + cls.__name__
- break
- setters.append((name[4:], source_class + "." + name))
- return setters
-
- def get_setters(self):
- """
- Get the attribute strings with setters for object. e.g., for a line,
- return ``['markerfacecolor', 'linewidth', ....]``.
- """
-
- return [prop for prop, target in self._get_setters_and_targets()]
-
- def is_alias(self, o):
- """
- Return *True* if method object *o* is an alias for another
- function.
- """
- ds = o.__doc__
- if ds is None:
- return False
- return ds.startswith('alias for ')
-
- def aliased_name(self, s):
- """
- return 'PROPNAME or alias' if *s* has an alias, else return
- PROPNAME.
-
- e.g., for the line markerfacecolor property, which has an
- alias, return 'markerfacecolor or mfc' and for the transform
- property, which does not, return 'transform'
- """
-
- if s in self.aliasd:
- return s + ''.join([' or %s' % x
- for x in sorted(self.aliasd[s])])
- else:
- return s
-
- def aliased_name_rest(self, s, target):
- """
- return 'PROPNAME or alias' if *s* has an alias, else return
- PROPNAME formatted for ReST
-
- e.g., for the line markerfacecolor property, which has an
- alias, return 'markerfacecolor or mfc' and for the transform
- property, which does not, return 'transform'
- """
-
- if s in self.aliasd:
- aliases = ''.join([' or %s' % x
- for x in sorted(self.aliasd[s])])
- else:
- aliases = ''
- return ':meth:`%s <%s>`%s' % (s, target, aliases)
-
- def pprint_setters(self, prop=None, leadingspace=2):
- """
- If *prop* is *None*, return a list of strings of all settable
- properties and their valid values.
-
- If *prop* is not *None*, it is a valid property name and that
- property will be returned as a string of property : valid
- values.
- """
- if leadingspace:
- pad = ' ' * leadingspace
- else:
- pad = ''
- if prop is not None:
- accepts = self.get_valid_values(prop)
- return '%s%s: %s' % (pad, prop, accepts)
-
- attrs = self._get_setters_and_targets()
- attrs.sort()
- lines = []
-
- for prop, path in attrs:
- accepts = self.get_valid_values(prop)
- name = self.aliased_name(prop)
-
- lines.append('%s%s: %s' % (pad, name, accepts))
- return lines
-
- def pprint_setters_rest(self, prop=None, leadingspace=4):
- """
- If *prop* is *None*, return a list of strings of all settable
- properties and their valid values. Format the output for ReST
-
- If *prop* is not *None*, it is a valid property name and that
- property will be returned as a string of property : valid
- values.
- """
- if leadingspace:
- pad = ' ' * leadingspace
- else:
- pad = ''
- if prop is not None:
- accepts = self.get_valid_values(prop)
- return '%s%s: %s' % (pad, prop, accepts)
-
- attrs = self._get_setters_and_targets()
- attrs.sort()
- lines = []
-
- ########
- names = [self.aliased_name_rest(prop, target)
- for prop, target in attrs]
- accepts = [self.get_valid_values(prop) for prop, target in attrs]
-
- col0_len = max(len(n) for n in names)
- col1_len = max(len(a) for a in accepts)
-
- lines.append('')
- lines.append(pad + '.. table::')
- lines.append(pad + ' :class: property-table')
- pad += ' '
-
- table_formatstr = pad + '=' * col0_len + ' ' + '=' * col1_len
-
- lines.append('')
- lines.append(table_formatstr)
- lines.append(pad + 'Property'.ljust(col0_len + 3) +
- 'Description'.ljust(col1_len))
- lines.append(table_formatstr)
-
- lines.extend([pad + n.ljust(col0_len + 3) + a.ljust(col1_len)
- for n, a in zip(names, accepts)])
-
- lines.append(table_formatstr)
- lines.append('')
- return lines
-
- def properties(self):
- """
- return a dictionary mapping property name -> value
- """
- o = self.oorig
- getters = [name for name in dir(o)
- if name.startswith('get_') and callable(getattr(o, name))]
- getters.sort()
- d = dict()
- for name in getters:
- func = getattr(o, name)
- if self.is_alias(func):
- continue
-
- try:
- with warnings.catch_warnings():
- warnings.simplefilter('ignore')
- val = func()
- except:
- continue
- else:
- d[name[4:]] = val
-
- return d
-
- def pprint_getters(self):
- """
- Return the getters and actual values as list of strings.
- """
-
- lines = []
- for name, val in sorted(six.iteritems(self.properties())):
- if getattr(val, 'shape', ()) != () and len(val) > 6:
- s = str(val[:6]) + '...'
- else:
- s = str(val)
- s = s.replace('\n', ' ')
- if len(s) > 50:
- s = s[:50] + '...'
- name = self.aliased_name(name)
- lines.append(' %s = %s' % (name, s))
- return lines
-
-
-def getp(obj, property=None):
- """
- Return the value of object's property. *property* is an optional string
- for the property you want to return
-
- Example usage::
-
- getp(obj) # get all the object properties
- getp(obj, 'linestyle') # get the linestyle property
-
- *obj* is a :class:`Artist` instance, e.g.,
- :class:`~matplotllib.lines.Line2D` or an instance of a
- :class:`~matplotlib.axes.Axes` or :class:`matplotlib.text.Text`.
- If the *property* is 'somename', this function returns
-
- obj.get_somename()
-
- :func:`getp` can be used to query all the gettable properties with
- ``getp(obj)``. Many properties have aliases for shorter typing, e.g.
- 'lw' is an alias for 'linewidth'. In the output, aliases and full
- property names will be listed as:
-
- property or alias = value
-
- e.g.:
-
- linewidth or lw = 2
- """
- if property is None:
- insp = ArtistInspector(obj)
- ret = insp.pprint_getters()
- print('\n'.join(ret))
- return
-
- func = getattr(obj, 'get_' + property)
- return func()
-
-# alias
-get = getp
-
-
-def setp(obj, *args, **kwargs):
- """
- Set a property on an artist object.
-
- matplotlib supports the use of :func:`setp` ("set property") and
- :func:`getp` to set and get object properties, as well as to do
- introspection on the object. For example, to set the linestyle of a
- line to be dashed, you can do::
-
- >>> line, = plot([1,2,3])
- >>> setp(line, linestyle='--')
-
- If you want to know the valid types of arguments, you can provide
- the name of the property you want to set without a value::
-
- >>> setp(line, 'linestyle')
- linestyle: [ '-' | '--' | '-.' | ':' | 'steps' | 'None' ]
-
- If you want to see all the properties that can be set, and their
- possible values, you can do::
-
- >>> setp(line)
- ... long output listing omitted
-
- You may specify another output file to `setp` if `sys.stdout` is not
- acceptable for some reason using the `file` keyword-only argument::
-
- >>> with fopen('output.log') as f:
- >>> setp(line, file=f)
-
- :func:`setp` operates on a single instance or a iterable of
- instances. If you are in query mode introspecting the possible
- values, only the first instance in the sequence is used. When
- actually setting values, all the instances will be set. e.g.,
- suppose you have a list of two lines, the following will make both
- lines thicker and red::
-
- >>> x = arange(0,1.0,0.01)
- >>> y1 = sin(2*pi*x)
- >>> y2 = sin(4*pi*x)
- >>> lines = plot(x, y1, x, y2)
- >>> setp(lines, linewidth=2, color='r')
-
- :func:`setp` works with the MATLAB style string/value pairs or
- with python kwargs. For example, the following are equivalent::
-
- >>> setp(lines, 'linewidth', 2, 'color', 'r') # MATLAB style
- >>> setp(lines, linewidth=2, color='r') # python style
- """
-
- if isinstance(obj, Artist):
- objs = [obj]
- else:
- objs = list(cbook.flatten(obj))
-
- if not objs:
- return
-
- insp = ArtistInspector(objs[0])
-
- # file has to be popped before checking if kwargs is empty
- printArgs = {}
- if 'file' in kwargs:
- printArgs['file'] = kwargs.pop('file')
-
- if not kwargs and len(args) < 2:
- if args:
- print(insp.pprint_setters(prop=args[0]), **printArgs)
- else:
- print('\n'.join(insp.pprint_setters()), **printArgs)
- return
-
- if len(args) % 2:
- raise ValueError('The set args must be string, value pairs')
-
- # put args into ordereddict to maintain order
- funcvals = OrderedDict()
- for i in range(0, len(args) - 1, 2):
- funcvals[args[i]] = args[i + 1]
-
- ret = [o.update(funcvals) for o in objs]
- ret.extend([o.set(**kwargs) for o in objs])
- return [x for x in cbook.flatten(ret)]
-
-
-def kwdoc(a):
- hardcopy = matplotlib.rcParams['docstring.hardcopy']
- if hardcopy:
- return '\n'.join(ArtistInspector(a).pprint_setters_rest(
- leadingspace=4))
- else:
- return '\n'.join(ArtistInspector(a).pprint_setters(leadingspace=2))
-
-docstring.interpd.update(Artist=kwdoc(Artist))
diff --git a/contrib/python/matplotlib/py2/matplotlib/axes/__init__.py b/contrib/python/matplotlib/py2/matplotlib/axes/__init__.py
deleted file mode 100644
index 82c5438919..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/axes/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from ._subplots import *
-from ._axes import *
diff --git a/contrib/python/matplotlib/py2/matplotlib/axes/_axes.py b/contrib/python/matplotlib/py2/matplotlib/axes/_axes.py
deleted file mode 100644
index 2027d250a8..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/axes/_axes.py
+++ /dev/null
@@ -1,8153 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange, zip, zip_longest
-
-import functools
-import itertools
-import logging
-import math
-import warnings
-
-import numpy as np
-from numpy import ma
-
-import matplotlib
-from matplotlib import _preprocess_data
-
-import matplotlib.cbook as cbook
-import matplotlib.collections as mcoll
-import matplotlib.colors as mcolors
-import matplotlib.contour as mcontour
-import matplotlib.category as _ # <-registers a category unit converter
-import matplotlib.dates as _ # <-registers a date unit converter
-import matplotlib.docstring as docstring
-import matplotlib.image as mimage
-import matplotlib.legend as mlegend
-import matplotlib.lines as mlines
-import matplotlib.markers as mmarkers
-import matplotlib.mlab as mlab
-import matplotlib.path as mpath
-import matplotlib.patches as mpatches
-import matplotlib.quiver as mquiver
-import matplotlib.stackplot as mstack
-import matplotlib.streamplot as mstream
-import matplotlib.table as mtable
-import matplotlib.text as mtext
-import matplotlib.ticker as mticker
-import matplotlib.transforms as mtransforms
-import matplotlib.tri as mtri
-from matplotlib.cbook import (
- _backports, mplDeprecation, warn_deprecated,
- STEP_LOOKUP_MAP, iterable, safe_first_element)
-from matplotlib.container import BarContainer, ErrorbarContainer, StemContainer
-from matplotlib.axes._base import _AxesBase, _process_plot_format
-
-_log = logging.getLogger(__name__)
-
-rcParams = matplotlib.rcParams
-
-_alias_map = {'color': ['c'],
- 'linewidth': ['lw'],
- 'linestyle': ['ls'],
- 'facecolor': ['fc'],
- 'edgecolor': ['ec'],
- 'markerfacecolor': ['mfc'],
- 'markeredgecolor': ['mec'],
- 'markeredgewidth': ['mew'],
- 'markersize': ['ms'],
- }
-
-
-def _plot_args_replacer(args, data):
- if len(args) == 1:
- return ["y"]
- elif len(args) == 2:
- # this can be two cases: x,y or y,c
- if not args[1] in data:
- # this is not in data, so just assume that it is something which
- # will not get replaced (color spec or array like).
- return ["y", "c"]
- # it's data, but could be a color code like 'ro' or 'b--'
- # -> warn the user in that case...
- try:
- _process_plot_format(args[1])
- except ValueError:
- pass
- else:
- warnings.warn(
- "Second argument {!r} is ambiguous: could be a color spec but "
- "is in data; using as data. Either rename the entry in data "
- "or use three arguments to plot.".format(args[1]),
- RuntimeWarning, stacklevel=3)
- return ["x", "y"]
- elif len(args) == 3:
- return ["x", "y", "c"]
- else:
- raise ValueError("Using arbitrary long args with data is not "
- "supported due to ambiguity of arguments.\nUse "
- "multiple plotting calls instead.")
-
-
-# The axes module contains all the wrappers to plotting functions.
-# All the other methods should go in the _AxesBase class.
-
-class Axes(_AxesBase):
- """
- The :class:`Axes` contains most of the figure elements:
- :class:`~matplotlib.axis.Axis`, :class:`~matplotlib.axis.Tick`,
- :class:`~matplotlib.lines.Line2D`, :class:`~matplotlib.text.Text`,
- :class:`~matplotlib.patches.Polygon`, etc., and sets the
- coordinate system.
-
- The :class:`Axes` instance supports callbacks through a callbacks
- attribute which is a :class:`~matplotlib.cbook.CallbackRegistry`
- instance. The events you can connect to are 'xlim_changed' and
- 'ylim_changed' and the callback will be called with func(*ax*)
- where *ax* is the :class:`Axes` instance.
- """
- ### Labelling, legend and texts
-
- aname = 'Axes'
-
- def get_title(self, loc="center"):
- """
- Get an axes title.
-
- Get one of the three available axes titles. The available titles
- are positioned above the axes in the center, flush with the left
- edge, and flush with the right edge.
-
- Parameters
- ----------
- loc : {'center', 'left', 'right'}, str, optional
- Which title to get, defaults to 'center'.
-
- Returns
- -------
- title : str
- The title text string.
-
- """
- try:
- title = {'left': self._left_title,
- 'center': self.title,
- 'right': self._right_title}[loc.lower()]
- except KeyError:
- raise ValueError("'%s' is not a valid location" % loc)
- return title.get_text()
-
- def set_title(self, label, fontdict=None, loc="center", pad=None,
- **kwargs):
- """
- Set a title for the axes.
-
- Set one of the three available axes titles. The available titles
- are positioned above the axes in the center, flush with the left
- edge, and flush with the right edge.
-
- Parameters
- ----------
- label : str
- Text to use for the title
-
- fontdict : dict
- A dictionary controlling the appearance of the title text,
- the default `fontdict` is::
-
- {'fontsize': rcParams['axes.titlesize'],
- 'fontweight' : rcParams['axes.titleweight'],
- 'verticalalignment': 'baseline',
- 'horizontalalignment': loc}
-
- loc : {'center', 'left', 'right'}, str, optional
- Which title to set, defaults to 'center'
-
- pad : float
- The offset of the title from the top of the axes, in points.
- Default is ``None`` to use rcParams['axes.titlepad'].
-
- Returns
- -------
- text : :class:`~matplotlib.text.Text`
- The matplotlib text instance representing the title
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.text.Text` properties
- Other keyword arguments are text properties, see
- :class:`~matplotlib.text.Text` for a list of valid text
- properties.
- """
- try:
- title = {'left': self._left_title,
- 'center': self.title,
- 'right': self._right_title}[loc.lower()]
- except KeyError:
- raise ValueError("'%s' is not a valid location" % loc)
- default = {
- 'fontsize': rcParams['axes.titlesize'],
- 'fontweight': rcParams['axes.titleweight'],
- 'verticalalignment': 'baseline',
- 'horizontalalignment': loc.lower()}
- if pad is None:
- pad = rcParams['axes.titlepad']
- self._set_title_offset_trans(float(pad))
- title.set_text(label)
- title.update(default)
- if fontdict is not None:
- title.update(fontdict)
- title.update(kwargs)
- return title
-
- def get_xlabel(self):
- """
- Get the xlabel text string.
- """
- label = self.xaxis.get_label()
- return label.get_text()
-
- def set_xlabel(self, xlabel, fontdict=None, labelpad=None, **kwargs):
- """
- Set the label for the x-axis.
-
- Parameters
- ----------
- xlabel : str
- The label text.
-
- labelpad : scalar, optional, default: None
- Spacing in points between the label and the x-axis.
-
- Other Parameters
- ----------------
- **kwargs : `.Text` properties
- `.Text` properties control the appearance of the label.
-
- See also
- --------
- text : for information on how override and the optional args work
- """
- if labelpad is not None:
- self.xaxis.labelpad = labelpad
- return self.xaxis.set_label_text(xlabel, fontdict, **kwargs)
-
- def get_ylabel(self):
- """
- Get the ylabel text string.
- """
- label = self.yaxis.get_label()
- return label.get_text()
-
- def set_ylabel(self, ylabel, fontdict=None, labelpad=None, **kwargs):
- """
- Set the label for the y-axis.
-
- Parameters
- ----------
- ylabel : str
- The label text.
-
- labelpad : scalar, optional, default: None
- Spacing in points between the label and the y-axis.
-
- Other Parameters
- ----------------
- **kwargs : `.Text` properties
- `.Text` properties control the appearance of the label.
-
- See also
- --------
- text : for information on how override and the optional args work
-
- """
- if labelpad is not None:
- self.yaxis.labelpad = labelpad
- return self.yaxis.set_label_text(ylabel, fontdict, **kwargs)
-
- def get_legend_handles_labels(self, legend_handler_map=None):
- """
- Return handles and labels for legend
-
- ``ax.legend()`` is equivalent to ::
-
- h, l = ax.get_legend_handles_labels()
- ax.legend(h, l)
-
- """
-
- # pass through to legend.
- handles, labels = mlegend._get_legend_handles_labels([self],
- legend_handler_map)
- return handles, labels
-
- @docstring.dedent_interpd
- def legend(self, *args, **kwargs):
- """
- Places a legend on the axes.
-
- Call signatures::
-
- legend()
- legend(labels)
- legend(handles, labels)
-
- The call signatures correspond to three different ways how to use
- this method.
-
- **1. Automatic detection of elements to be shown in the legend**
-
- The elements to be added to the legend are automatically determined,
- when you do not pass in any extra arguments.
-
- In this case, the labels are taken from the artist. You can specify
- them either at artist creation or by calling the
- :meth:`~.Artist.set_label` method on the artist::
-
- line, = ax.plot([1, 2, 3], label='Inline label')
- ax.legend()
-
- or::
-
- line.set_label('Label via method')
- line, = ax.plot([1, 2, 3])
- ax.legend()
-
- Specific lines can be excluded from the automatic legend element
- selection by defining a label starting with an underscore.
- This is default for all artists, so calling `Axes.legend` without
- any arguments and without setting the labels manually will result in
- no legend being drawn.
-
-
- **2. Labeling existing plot elements**
-
- To make a legend for lines which already exist on the axes
- (via plot for instance), simply call this function with an iterable
- of strings, one for each legend item. For example::
-
- ax.plot([1, 2, 3])
- ax.legend(['A simple line'])
-
- Note: This way of using is discouraged, because the relation between
- plot elements and labels is only implicit by their order and can
- easily be mixed up.
-
-
- **3. Explicitly defining the elements in the legend**
-
- For full control of which artists have a legend entry, it is possible
- to pass an iterable of legend artists followed by an iterable of
- legend labels respectively::
-
- legend((line1, line2, line3), ('label1', 'label2', 'label3'))
-
- Parameters
- ----------
-
- handles : sequence of `.Artist`, optional
- A list of Artists (lines, patches) to be added to the legend.
- Use this together with *labels*, if you need full control on what
- is shown in the legend and the automatic mechanism described above
- is not sufficient.
-
- The length of handles and labels should be the same in this
- case. If they are not, they are truncated to the smaller length.
-
- labels : sequence of strings, optional
- A list of labels to show next to the artists.
- Use this together with *handles*, if you need full control on what
- is shown in the legend and the automatic mechanism described above
- is not sufficient.
-
- Other Parameters
- ----------------
-
- loc : int or string or pair of floats, default: 'upper right'
- The location of the legend. Possible codes are:
-
- =============== =============
- Location String Location Code
- =============== =============
- 'best' 0
- 'upper right' 1
- 'upper left' 2
- 'lower left' 3
- 'lower right' 4
- 'right' 5
- 'center left' 6
- 'center right' 7
- 'lower center' 8
- 'upper center' 9
- 'center' 10
- =============== =============
-
-
- Alternatively can be a 2-tuple giving ``x, y`` of the lower-left
- corner of the legend in axes coordinates (in which case
- ``bbox_to_anchor`` will be ignored).
-
- bbox_to_anchor : `.BboxBase` or pair of floats
- Specify any arbitrary location for the legend in `bbox_transform`
- coordinates (default Axes coordinates).
-
- For example, to put the legend's upper right hand corner in the
- center of the axes the following keywords can be used::
-
- loc='upper right', bbox_to_anchor=(0.5, 0.5)
-
- ncol : integer
- The number of columns that the legend has. Default is 1.
-
- prop : None or :class:`matplotlib.font_manager.FontProperties` or dict
- The font properties of the legend. If None (default), the current
- :data:`matplotlib.rcParams` will be used.
-
- fontsize : int or float or {'xx-small', 'x-small', 'small', 'medium', \
-'large', 'x-large', 'xx-large'}
- Controls the font size of the legend. If the value is numeric the
- size will be the absolute font size in points. String values are
- relative to the current default font size. This argument is only
- used if `prop` is not specified.
-
- numpoints : None or int
- The number of marker points in the legend when creating a legend
- entry for a `.Line2D` (line).
- Default is ``None``, which will take the value from
- :rc:`legend.numpoints`.
-
- scatterpoints : None or int
- The number of marker points in the legend when creating
- a legend entry for a `.PathCollection` (scatter plot).
- Default is ``None``, which will take the value from
- :rc:`legend.scatterpoints`.
-
- scatteryoffsets : iterable of floats
- The vertical offset (relative to the font size) for the markers
- created for a scatter plot legend entry. 0.0 is at the base the
- legend text, and 1.0 is at the top. To draw all markers at the
- same height, set to ``[0.5]``. Default is ``[0.375, 0.5, 0.3125]``.
-
- markerscale : None or int or float
- The relative size of legend markers compared with the originally
- drawn ones.
- Default is ``None``, which will take the value from
- :rc:`legend.markerscale`.
-
- markerfirst : bool
- If *True*, legend marker is placed to the left of the legend label.
- If *False*, legend marker is placed to the right of the legend
- label.
- Default is *True*.
-
- frameon : None or bool
- Control whether the legend should be drawn on a patch
- (frame).
- Default is ``None``, which will take the value from
- :rc:`legend.frameon`.
-
- fancybox : None or bool
- Control whether round edges should be enabled around the
- :class:`~matplotlib.patches.FancyBboxPatch` which makes up the
- legend's background.
- Default is ``None``, which will take the value from
- :rc:`legend.fancybox`.
-
- shadow : None or bool
- Control whether to draw a shadow behind the legend.
- Default is ``None``, which will take the value from
- :rc:`legend.shadow`.
-
- framealpha : None or float
- Control the alpha transparency of the legend's background.
- Default is ``None``, which will take the value from
- :rc:`legend.framealpha`. If shadow is activated and
- *framealpha* is ``None``, the default value is ignored.
-
- facecolor : None or "inherit" or a color spec
- Control the legend's background color.
- Default is ``None``, which will take the value from
- :rc:`legend.facecolor`. If ``"inherit"``, it will take
- :rc:`axes.facecolor`.
-
- edgecolor : None or "inherit" or a color spec
- Control the legend's background patch edge color.
- Default is ``None``, which will take the value from
- :rc:`legend.edgecolor` If ``"inherit"``, it will take
- :rc:`axes.edgecolor`.
-
- mode : {"expand", None}
- If `mode` is set to ``"expand"`` the legend will be horizontally
- expanded to fill the axes area (or `bbox_to_anchor` if defines
- the legend's size).
-
- bbox_transform : None or :class:`matplotlib.transforms.Transform`
- The transform for the bounding box (`bbox_to_anchor`). For a value
- of ``None`` (default) the Axes'
- :data:`~matplotlib.axes.Axes.transAxes` transform will be used.
-
- title : str or None
- The legend's title. Default is no title (``None``).
-
- borderpad : float or None
- The fractional whitespace inside the legend border.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.borderpad`.
-
- labelspacing : float or None
- The vertical space between the legend entries.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.labelspacing`.
-
- handlelength : float or None
- The length of the legend handles.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.handlelength`.
-
- handletextpad : float or None
- The pad between the legend handle and text.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.handletextpad`.
-
- borderaxespad : float or None
- The pad between the axes and legend border.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.borderaxespad`.
-
- columnspacing : float or None
- The spacing between columns.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.columnspacing`.
-
- handler_map : dict or None
- The custom dictionary mapping instances or types to a legend
- handler. This `handler_map` updates the default handler map
- found at :func:`matplotlib.legend.Legend.get_legend_handler_map`.
-
- Returns
- -------
-
- :class:`matplotlib.legend.Legend` instance
-
- Notes
- -----
-
- Not all kinds of artist are supported by the legend command. See
- :doc:`/tutorials/intermediate/legend_guide` for details.
-
- Examples
- --------
-
- .. plot:: gallery/api/legend.py
-
- """
- handles, labels, extra_args, kwargs = mlegend._parse_legend_args(
- [self],
- *args,
- **kwargs)
- if len(extra_args):
- raise TypeError('legend only accepts two non-keyword arguments')
- self.legend_ = mlegend.Legend(self, handles, labels, **kwargs)
- self.legend_._remove_method = lambda h: setattr(self, 'legend_', None)
- return self.legend_
-
- def text(self, x, y, s, fontdict=None, withdash=False, **kwargs):
- """
- Add text to the axes.
-
- Add the text *s* to the axes at location *x*, *y* in data coordinates.
-
- Parameters
- ----------
- x, y : scalars
- The position to place the text. By default, this is in data
- coordinates. The coordinate system can be changed using the
- *transform* parameter.
-
- s : str
- The text.
-
- fontdict : dictionary, optional, default: None
- A dictionary to override the default text properties. If fontdict
- is None, the defaults are determined by your rc parameters.
-
- withdash : boolean, optional, default: False
- Creates a `~matplotlib.text.TextWithDash` instance instead of a
- `~matplotlib.text.Text` instance.
-
- Returns
- -------
- text : `.Text`
- The created `.Text` instance.
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.text.Text` properties.
- Other miscellaneous text parameters.
-
- Examples
- --------
- Individual keyword arguments can be used to override any given
- parameter::
-
- >>> text(x, y, s, fontsize=12)
-
- The default transform specifies that text is in data coords,
- alternatively, you can specify text in axis coords (0,0 is
- lower-left and 1,1 is upper-right). The example below places
- text in the center of the axes::
-
- >>> text(0.5, 0.5, 'matplotlib', horizontalalignment='center',
- ... verticalalignment='center', transform=ax.transAxes)
-
- You can put a rectangular box around the text instance (e.g., to
- set a background color) by using the keyword `bbox`. `bbox` is
- a dictionary of `~matplotlib.patches.Rectangle`
- properties. For example::
-
- >>> text(x, y, s, bbox=dict(facecolor='red', alpha=0.5))
- """
- default = {
- 'verticalalignment': 'baseline',
- 'horizontalalignment': 'left',
- 'transform': self.transData,
- 'clip_on': False}
-
- # At some point if we feel confident that TextWithDash
- # is robust as a drop-in replacement for Text and that
- # the performance impact of the heavier-weight class
- # isn't too significant, it may make sense to eliminate
- # the withdash kwarg and simply delegate whether there's
- # a dash to TextWithDash and dashlength.
- if withdash:
- t = mtext.TextWithDash(
- x=x, y=y, text=s)
- else:
- t = mtext.Text(
- x=x, y=y, text=s)
-
- t.update(default)
- if fontdict is not None:
- t.update(fontdict)
- t.update(kwargs)
-
- t.set_clip_path(self.patch)
- self._add_text(t)
- return t
-
- @docstring.dedent_interpd
- def annotate(self, *args, **kwargs):
- a = mtext.Annotation(*args, **kwargs)
- a.set_transform(mtransforms.IdentityTransform())
- if 'clip_on' in kwargs:
- a.set_clip_path(self.patch)
- self._add_text(a)
- return a
- annotate.__doc__ = mtext.Annotation.__init__.__doc__
- #### Lines and spans
-
- @docstring.dedent_interpd
- def axhline(self, y=0, xmin=0, xmax=1, **kwargs):
- """
- Add a horizontal line across the axis.
-
- Parameters
- ----------
- y : scalar, optional, default: 0
- y position in data coordinates of the horizontal line.
-
- xmin : scalar, optional, default: 0
- Should be between 0 and 1, 0 being the far left of the plot, 1 the
- far right of the plot.
-
- xmax : scalar, optional, default: 1
- Should be between 0 and 1, 0 being the far left of the plot, 1 the
- far right of the plot.
-
- Returns
- -------
- line : :class:`~matplotlib.lines.Line2D`
-
- Other Parameters
- ----------------
- **kwargs :
- Valid kwargs are :class:`~matplotlib.lines.Line2D` properties,
- with the exception of 'transform':
-
- %(Line2D)s
-
- See also
- --------
- hlines : Add horizontal lines in data coordinates.
- axhspan : Add a horizontal span (rectangle) across the axis.
-
- Examples
- --------
-
- * draw a thick red hline at 'y' = 0 that spans the xrange::
-
- >>> axhline(linewidth=4, color='r')
-
- * draw a default hline at 'y' = 1 that spans the xrange::
-
- >>> axhline(y=1)
-
- * draw a default hline at 'y' = .5 that spans the middle half of
- the xrange::
-
- >>> axhline(y=.5, xmin=0.25, xmax=0.75)
-
- """
- if "transform" in kwargs:
- raise ValueError(
- "'transform' is not allowed as a kwarg;"
- + "axhline generates its own transform.")
- ymin, ymax = self.get_ybound()
-
- # We need to strip away the units for comparison with
- # non-unitized bounds
- self._process_unit_info(ydata=y, kwargs=kwargs)
- yy = self.convert_yunits(y)
- scaley = (yy < ymin) or (yy > ymax)
-
- trans = self.get_yaxis_transform(which='grid')
- l = mlines.Line2D([xmin, xmax], [y, y], transform=trans, **kwargs)
- self.add_line(l)
- self.autoscale_view(scalex=False, scaley=scaley)
- return l
-
- @docstring.dedent_interpd
- def axvline(self, x=0, ymin=0, ymax=1, **kwargs):
- """
- Add a vertical line across the axes.
-
- Parameters
- ----------
- x : scalar, optional, default: 0
- x position in data coordinates of the vertical line.
-
- ymin : scalar, optional, default: 0
- Should be between 0 and 1, 0 being the bottom of the plot, 1 the
- top of the plot.
-
- ymax : scalar, optional, default: 1
- Should be between 0 and 1, 0 being the bottom of the plot, 1 the
- top of the plot.
-
- Returns
- -------
- line : :class:`~matplotlib.lines.Line2D`
-
- Other Parameters
- ----------------
- **kwargs :
- Valid kwargs are :class:`~matplotlib.lines.Line2D` properties,
- with the exception of 'transform':
-
- %(Line2D)s
-
- Examples
- --------
- * draw a thick red vline at *x* = 0 that spans the yrange::
-
- >>> axvline(linewidth=4, color='r')
-
- * draw a default vline at *x* = 1 that spans the yrange::
-
- >>> axvline(x=1)
-
- * draw a default vline at *x* = .5 that spans the middle half of
- the yrange::
-
- >>> axvline(x=.5, ymin=0.25, ymax=0.75)
-
- See also
- --------
- vlines : Add vertical lines in data coordinates.
- axvspan : Add a vertical span (rectangle) across the axis.
- """
-
- if "transform" in kwargs:
- raise ValueError(
- "'transform' is not allowed as a kwarg;"
- + "axvline generates its own transform.")
- xmin, xmax = self.get_xbound()
-
- # We need to strip away the units for comparison with
- # non-unitized bounds
- self._process_unit_info(xdata=x, kwargs=kwargs)
- xx = self.convert_xunits(x)
- scalex = (xx < xmin) or (xx > xmax)
-
- trans = self.get_xaxis_transform(which='grid')
- l = mlines.Line2D([x, x], [ymin, ymax], transform=trans, **kwargs)
- self.add_line(l)
- self.autoscale_view(scalex=scalex, scaley=False)
- return l
-
- @docstring.dedent_interpd
- def axhspan(self, ymin, ymax, xmin=0, xmax=1, **kwargs):
- """
- Add a horizontal span (rectangle) across the axis.
-
- Draw a horizontal span (rectangle) from *ymin* to *ymax*.
- With the default values of *xmin* = 0 and *xmax* = 1, this
- always spans the xrange, regardless of the xlim settings, even
- if you change them, e.g., with the :meth:`set_xlim` command.
- That is, the horizontal extent is in axes coords: 0=left,
- 0.5=middle, 1.0=right but the *y* location is in data
- coordinates.
-
- Parameters
- ----------
- ymin : float
- Lower limit of the horizontal span in data units.
- ymax : float
- Upper limit of the horizontal span in data units.
- xmin : float, optional, default: 0
- Lower limit of the vertical span in axes (relative
- 0-1) units.
- xmax : float, optional, default: 1
- Upper limit of the vertical span in axes (relative
- 0-1) units.
-
- Returns
- -------
- Polygon : `~matplotlib.patches.Polygon`
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.patches.Polygon` properties.
-
- %(Polygon)s
-
- See Also
- --------
- axvspan : Add a vertical span across the axes.
- """
- trans = self.get_yaxis_transform(which='grid')
-
- # process the unit information
- self._process_unit_info([xmin, xmax], [ymin, ymax], kwargs=kwargs)
-
- # first we need to strip away the units
- xmin, xmax = self.convert_xunits([xmin, xmax])
- ymin, ymax = self.convert_yunits([ymin, ymax])
-
- verts = (xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)
- p = mpatches.Polygon(verts, **kwargs)
- p.set_transform(trans)
- self.add_patch(p)
- self.autoscale_view(scalex=False)
- return p
-
- def axvspan(self, xmin, xmax, ymin=0, ymax=1, **kwargs):
- """
- Add a vertical span (rectangle) across the axes.
-
- Draw a vertical span (rectangle) from `xmin` to `xmax`. With
- the default values of `ymin` = 0 and `ymax` = 1. This always
- spans the yrange, regardless of the ylim settings, even if you
- change them, e.g., with the :meth:`set_ylim` command. That is,
- the vertical extent is in axes coords: 0=bottom, 0.5=middle,
- 1.0=top but the y location is in data coordinates.
-
- Parameters
- ----------
- xmin : scalar
- Number indicating the first X-axis coordinate of the vertical
- span rectangle in data units.
- xmax : scalar
- Number indicating the second X-axis coordinate of the vertical
- span rectangle in data units.
- ymin : scalar, optional
- Number indicating the first Y-axis coordinate of the vertical
- span rectangle in relative Y-axis units (0-1). Default to 0.
- ymax : scalar, optional
- Number indicating the second Y-axis coordinate of the vertical
- span rectangle in relative Y-axis units (0-1). Default to 1.
-
- Returns
- -------
- rectangle : matplotlib.patches.Polygon
- Vertical span (rectangle) from (xmin, ymin) to (xmax, ymax).
-
- Other Parameters
- ----------------
- **kwargs
- Optional parameters are properties of the class
- matplotlib.patches.Polygon.
-
- See Also
- --------
- axhspan : Add a horizontal span across the axes.
-
- Examples
- --------
- Draw a vertical, green, translucent rectangle from x = 1.25 to
- x = 1.55 that spans the yrange of the axes.
-
- >>> axvspan(1.25, 1.55, facecolor='g', alpha=0.5)
-
- """
- trans = self.get_xaxis_transform(which='grid')
-
- # process the unit information
- self._process_unit_info([xmin, xmax], [ymin, ymax], kwargs=kwargs)
-
- # first we need to strip away the units
- xmin, xmax = self.convert_xunits([xmin, xmax])
- ymin, ymax = self.convert_yunits([ymin, ymax])
-
- verts = [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)]
- p = mpatches.Polygon(verts, **kwargs)
- p.set_transform(trans)
- self.add_patch(p)
- self.autoscale_view(scaley=False)
- return p
-
- @_preprocess_data(replace_names=["y", "xmin", "xmax", "colors"],
- label_namer="y")
- def hlines(self, y, xmin, xmax, colors='k', linestyles='solid',
- label='', **kwargs):
- """
- Plot horizontal lines at each *y* from *xmin* to *xmax*.
-
- Parameters
- ----------
- y : scalar or sequence of scalar
- y-indexes where to plot the lines.
-
- xmin, xmax : scalar or 1D array_like
- Respective beginning and end of each line. If scalars are
- provided, all lines will have same length.
-
- colors : array_like of colors, optional, default: 'k'
-
- linestyles : ['solid' | 'dashed' | 'dashdot' | 'dotted'], optional
-
- label : string, optional, default: ''
-
- Returns
- -------
- lines : `~matplotlib.collections.LineCollection`
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.collections.LineCollection` properties.
-
- See also
- --------
- vlines : vertical lines
- axhline: horizontal line across the axes
- """
-
- # We do the conversion first since not all unitized data is uniform
- # process the unit information
- self._process_unit_info([xmin, xmax], y, kwargs=kwargs)
- y = self.convert_yunits(y)
- xmin = self.convert_xunits(xmin)
- xmax = self.convert_xunits(xmax)
-
- if not iterable(y):
- y = [y]
- if not iterable(xmin):
- xmin = [xmin]
- if not iterable(xmax):
- xmax = [xmax]
-
- y, xmin, xmax = cbook.delete_masked_points(y, xmin, xmax)
-
- y = np.ravel(y)
- xmin = np.resize(xmin, y.shape)
- xmax = np.resize(xmax, y.shape)
-
- verts = [((thisxmin, thisy), (thisxmax, thisy))
- for thisxmin, thisxmax, thisy in zip(xmin, xmax, y)]
- lines = mcoll.LineCollection(verts, colors=colors,
- linestyles=linestyles, label=label)
- self.add_collection(lines, autolim=False)
- lines.update(kwargs)
-
- if len(y) > 0:
- minx = min(xmin.min(), xmax.min())
- maxx = max(xmin.max(), xmax.max())
- miny = y.min()
- maxy = y.max()
-
- corners = (minx, miny), (maxx, maxy)
-
- self.update_datalim(corners)
- self.autoscale_view()
-
- return lines
-
- @_preprocess_data(replace_names=["x", "ymin", "ymax", "colors"],
- label_namer="x")
- def vlines(self, x, ymin, ymax, colors='k', linestyles='solid',
- label='', **kwargs):
- """
- Plot vertical lines.
-
- Plot vertical lines at each *x* from *ymin* to *ymax*.
-
- Parameters
- ----------
- x : scalar or 1D array_like
- x-indexes where to plot the lines.
-
- ymin, ymax : scalar or 1D array_like
- Respective beginning and end of each line. If scalars are
- provided, all lines will have same length.
-
- colors : array_like of colors, optional, default: 'k'
-
- linestyles : ['solid' | 'dashed' | 'dashdot' | 'dotted'], optional
-
- label : string, optional, default: ''
-
- Returns
- -------
- lines : `~matplotlib.collections.LineCollection`
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.collections.LineCollection` properties.
-
- See also
- --------
- hlines : horizontal lines
- axvline: vertical line across the axes
- """
-
- self._process_unit_info(xdata=x, ydata=[ymin, ymax], kwargs=kwargs)
-
- # We do the conversion first since not all unitized data is uniform
- x = self.convert_xunits(x)
- ymin = self.convert_yunits(ymin)
- ymax = self.convert_yunits(ymax)
-
- if not iterable(x):
- x = [x]
- if not iterable(ymin):
- ymin = [ymin]
- if not iterable(ymax):
- ymax = [ymax]
-
- x, ymin, ymax = cbook.delete_masked_points(x, ymin, ymax)
-
- x = np.ravel(x)
- ymin = np.resize(ymin, x.shape)
- ymax = np.resize(ymax, x.shape)
-
- verts = [((thisx, thisymin), (thisx, thisymax))
- for thisx, thisymin, thisymax in zip(x, ymin, ymax)]
- lines = mcoll.LineCollection(verts, colors=colors,
- linestyles=linestyles, label=label)
- self.add_collection(lines, autolim=False)
- lines.update(kwargs)
-
- if len(x) > 0:
- minx = x.min()
- maxx = x.max()
- miny = min(ymin.min(), ymax.min())
- maxy = max(ymin.max(), ymax.max())
-
- corners = (minx, miny), (maxx, maxy)
- self.update_datalim(corners)
- self.autoscale_view()
-
- return lines
-
- @_preprocess_data(replace_names=["positions", "lineoffsets",
- "linelengths", "linewidths",
- "colors", "linestyles"],
- label_namer=None)
- @docstring.dedent_interpd
- def eventplot(self, positions, orientation='horizontal', lineoffsets=1,
- linelengths=1, linewidths=None, colors=None,
- linestyles='solid', **kwargs):
- """
- Plot identical parallel lines at the given positions.
-
- *positions* should be a 1D or 2D array-like object, with each row
- corresponding to a row or column of lines.
-
- This type of plot is commonly used in neuroscience for representing
- neural events, where it is usually called a spike raster, dot raster,
- or raster plot.
-
- However, it is useful in any situation where you wish to show the
- timing or position of multiple sets of discrete events, such as the
- arrival times of people to a business on each day of the month or the
- date of hurricanes each year of the last century.
-
- Parameters
- ----------
- positions : 1D or 2D array-like object
- Each value is an event. If *positions* is a 2D array-like, each
- row corresponds to a row or a column of lines (depending on the
- *orientation* parameter).
-
- orientation : {'horizontal', 'vertical'}, optional
- Controls the direction of the event collections:
-
- - 'horizontal' : the lines are arranged horizontally in rows,
- and are vertical.
- - 'vertical' : the lines are arranged vertically in columns,
- and are horizontal.
-
- lineoffsets : scalar or sequence of scalars, optional, default: 1
- The offset of the center of the lines from the origin, in the
- direction orthogonal to *orientation*.
-
- linelengths : scalar or sequence of scalars, optional, default: 1
- The total height of the lines (i.e. the lines stretches from
- ``lineoffset - linelength/2`` to ``lineoffset + linelength/2``).
-
- linewidths : scalar, scalar sequence or None, optional, default: None
- The line width(s) of the event lines, in points. If it is None,
- defaults to its rcParams setting.
-
- colors : color, sequence of colors or None, optional, default: None
- The color(s) of the event lines. If it is None, defaults to its
- rcParams setting.
-
- linestyles : str or tuple or a sequence of such values, optional
- Default is 'solid'. Valid strings are ['solid', 'dashed',
- 'dashdot', 'dotted', '-', '--', '-.', ':']. Dash tuples
- should be of the form::
-
- (offset, onoffseq),
-
- where *onoffseq* is an even length tuple of on and off ink
- in points.
-
- **kwargs : optional
- Other keyword arguments are line collection properties. See
- :class:`~matplotlib.collections.LineCollection` for a list of
- the valid properties.
-
- Returns
- -------
-
- list : A list of :class:`~.collections.EventCollection` objects.
- Contains the :class:`~.collections.EventCollection` that
- were added.
-
- Notes
- -----
-
- For *linelengths*, *linewidths*, *colors*, and *linestyles*, if only
- a single value is given, that value is applied to all lines. If an
- array-like is given, it must have the same length as *positions*, and
- each value will be applied to the corresponding row of the array.
-
- Examples
- --------
-
- .. plot:: gallery/lines_bars_and_markers/eventplot_demo.py
- """
- self._process_unit_info(xdata=positions,
- ydata=[lineoffsets, linelengths],
- kwargs=kwargs)
-
- # We do the conversion first since not all unitized data is uniform
- positions = self.convert_xunits(positions)
- lineoffsets = self.convert_yunits(lineoffsets)
- linelengths = self.convert_yunits(linelengths)
-
- if not iterable(positions):
- positions = [positions]
- elif any(iterable(position) for position in positions):
- positions = [np.asanyarray(position) for position in positions]
- else:
- positions = [np.asanyarray(positions)]
-
- if len(positions) == 0:
- return []
-
- # prevent 'singular' keys from **kwargs dict from overriding the effect
- # of 'plural' keyword arguments (e.g. 'color' overriding 'colors')
- colors = cbook.local_over_kwdict(colors, kwargs, 'color')
- linewidths = cbook.local_over_kwdict(linewidths, kwargs, 'linewidth')
- linestyles = cbook.local_over_kwdict(linestyles, kwargs, 'linestyle')
-
- if not iterable(lineoffsets):
- lineoffsets = [lineoffsets]
- if not iterable(linelengths):
- linelengths = [linelengths]
- if not iterable(linewidths):
- linewidths = [linewidths]
- if not iterable(colors):
- colors = [colors]
- if hasattr(linestyles, 'lower') or not iterable(linestyles):
- linestyles = [linestyles]
-
- lineoffsets = np.asarray(lineoffsets)
- linelengths = np.asarray(linelengths)
- linewidths = np.asarray(linewidths)
-
- if len(lineoffsets) == 0:
- lineoffsets = [None]
- if len(linelengths) == 0:
- linelengths = [None]
- if len(linewidths) == 0:
- lineoffsets = [None]
- if len(linewidths) == 0:
- lineoffsets = [None]
- if len(colors) == 0:
- colors = [None]
- try:
- # Early conversion of the colors into RGBA values to take care
- # of cases like colors='0.5' or colors='C1'. (Issue #8193)
- colors = mcolors.to_rgba_array(colors)
- except ValueError:
- # Will fail if any element of *colors* is None. But as long
- # as len(colors) == 1 or len(positions), the rest of the
- # code should process *colors* properly.
- pass
-
- if len(lineoffsets) == 1 and len(positions) != 1:
- lineoffsets = np.tile(lineoffsets, len(positions))
- lineoffsets[0] = 0
- lineoffsets = np.cumsum(lineoffsets)
- if len(linelengths) == 1:
- linelengths = np.tile(linelengths, len(positions))
- if len(linewidths) == 1:
- linewidths = np.tile(linewidths, len(positions))
- if len(colors) == 1:
- colors = list(colors)
- colors = colors * len(positions)
- if len(linestyles) == 1:
- linestyles = [linestyles] * len(positions)
-
- if len(lineoffsets) != len(positions):
- raise ValueError('lineoffsets and positions are unequal sized '
- 'sequences')
- if len(linelengths) != len(positions):
- raise ValueError('linelengths and positions are unequal sized '
- 'sequences')
- if len(linewidths) != len(positions):
- raise ValueError('linewidths and positions are unequal sized '
- 'sequences')
- if len(colors) != len(positions):
- raise ValueError('colors and positions are unequal sized '
- 'sequences')
- if len(linestyles) != len(positions):
- raise ValueError('linestyles and positions are unequal sized '
- 'sequences')
-
- colls = []
- for position, lineoffset, linelength, linewidth, color, linestyle in \
- zip(positions, lineoffsets, linelengths, linewidths,
- colors, linestyles):
- coll = mcoll.EventCollection(position,
- orientation=orientation,
- lineoffset=lineoffset,
- linelength=linelength,
- linewidth=linewidth,
- color=color,
- linestyle=linestyle)
- self.add_collection(coll, autolim=False)
- coll.update(kwargs)
- colls.append(coll)
-
- if len(positions) > 0:
- # try to get min/max
- min_max = [(np.min(_p), np.max(_p)) for _p in positions
- if len(_p) > 0]
- # if we have any non-empty positions, try to autoscale
- if len(min_max) > 0:
- mins, maxes = zip(*min_max)
- minpos = np.min(mins)
- maxpos = np.max(maxes)
-
- minline = (lineoffsets - linelengths).min()
- maxline = (lineoffsets + linelengths).max()
-
- if (orientation is not None and
- orientation.lower() == "vertical"):
- corners = (minline, minpos), (maxline, maxpos)
- else: # "horizontal", None or "none" (see EventCollection)
- corners = (minpos, minline), (maxpos, maxline)
- self.update_datalim(corners)
- self.autoscale_view()
-
- return colls
-
- # ### Basic plotting
- # The label_naming happens in `matplotlib.axes._base._plot_args`
- @_preprocess_data(replace_names=["x", "y"],
- positional_parameter_names=_plot_args_replacer,
- label_namer=None)
- @docstring.dedent_interpd
- def plot(self, *args, **kwargs):
- """
- Plot y versus x as lines and/or markers.
-
- Call signatures::
-
- plot([x], y, [fmt], data=None, **kwargs)
- plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
-
- The coordinates of the points or line nodes are given by *x*, *y*.
-
- The optional parameter *fmt* is a convenient way for defining basic
- formatting like color, marker and linestyle. It's a shortcut string
- notation described in the *Notes* section below.
-
- >>> plot(x, y) # plot x and y using default line style and color
- >>> plot(x, y, 'bo') # plot x and y using blue circle markers
- >>> plot(y) # plot y using x as index array 0..N-1
- >>> plot(y, 'r+') # ditto, but with red plusses
-
- You can use `.Line2D` properties as keyword arguments for more
- control on the appearance. Line properties and *fmt* can be mixed.
- The following two calls yield identical results:
-
- >>> plot(x, y, 'go--', linewidth=2, markersize=12)
- >>> plot(x, y, color='green', marker='o', linestyle='dashed',
- linewidth=2, markersize=12)
-
- When conflicting with *fmt*, keyword arguments take precedence.
-
- **Plotting labelled data**
-
- There's a convenient way for plotting objects with labelled data (i.e.
- data that can be accessed by index ``obj['y']``). Instead of giving
- the data in *x* and *y*, you can provide the object in the *data*
- parameter and just give the labels for *x* and *y*::
-
- >>> plot('xlabel', 'ylabel', data=obj)
-
- All indexable objects are supported. This could e.g. be a `dict`, a
- `pandas.DataFame` or a structured numpy array.
-
-
- **Plotting multiple sets of data**
-
- There are various ways to plot multiple sets of data.
-
- - The most straight forward way is just to call `plot` multiple times.
- Example:
-
- >>> plot(x1, y1, 'bo')
- >>> plot(x2, y2, 'go')
-
- - Alternatively, if your data is already a 2d array, you can pass it
- directly to *x*, *y*. A separate data set will be drawn for every
- column.
-
- Example: an array ``a`` where the first column represents the *x*
- values and the other columns are the *y* columns::
-
- >>> plot(a[0], a[1:])
-
- - The third way is to specify multiple sets of *[x]*, *y*, *[fmt]*
- groups::
-
- >>> plot(x1, y1, 'g^', x2, y2, 'g-')
-
- In this case, any additional keyword argument applies to all
- datasets. Also this syntax cannot be combined with the *data*
- parameter.
-
- By default, each line is assigned a different style specified by a
- 'style cycle'. The *fmt* and line property parameters are only
- necessary if you want explicit deviations from these defaults.
- Alternatively, you can also change the style cycle using the
- 'axes.prop_cycle' rcParam.
-
- Parameters
- ----------
- x, y : array-like or scalar
- The horizontal / vertical coordinates of the data points.
- *x* values are optional. If not given, they default to
- ``[0, ..., N-1]``.
-
- Commonly, these parameters are arrays of length N. However,
- scalars are supported as well (equivalent to an array with
- constant value).
-
- The parameters can also be 2-dimensional. Then, the columns
- represent separate data sets.
-
- fmt : str, optional
- A format string, e.g. 'ro' for red circles. See the *Notes*
- section for a full description of the format strings.
-
- Format strings are just an abbreviation for quickly setting
- basic line properties. All of these and more can also be
- controlled by keyword arguments.
-
- data : indexable object, optional
- An object with labelled data. If given, provide the label names to
- plot in *x* and *y*.
-
- .. note::
- Technically there's a slight ambiguity in calls where the
- second label is a valid *fmt*. `plot('n', 'o', data=obj)`
- could be `plt(x, y)` or `plt(y, fmt)`. In such cases,
- the former interpretation is chosen, but a warning is issued.
- You may suppress the warning by adding an empty format string
- `plot('n', 'o', '', data=obj)`.
-
-
- Other Parameters
- ----------------
- scalex, scaley : bool, optional, default: True
- These parameters determined if the view limits are adapted to
- the data limits. The values are passed on to `autoscale_view`.
-
- **kwargs : `.Line2D` properties, optional
- *kwargs* are used to specify properties like a line label (for
- auto legends), linewidth, antialiasing, marker face color.
- Example::
-
- >>> plot([1,2,3], [1,2,3], 'go-', label='line 1', linewidth=2)
- >>> plot([1,2,3], [1,4,9], 'rs', label='line 2')
-
- If you make multiple lines with one plot command, the kwargs
- apply to all those lines.
-
- Here is a list of available `.Line2D` properties:
-
- %(Line2D)s
-
- Returns
- -------
- lines
- A list of `.Line2D` objects representing the plotted data.
-
-
- See Also
- --------
- scatter : XY scatter plot with markers of variing size and/or color (
- sometimes also called bubble chart).
-
-
- Notes
- -----
- **Format Strings**
-
- A format string consists of a part for color, marker and line::
-
- fmt = '[color][marker][line]'
-
- Each of them is optional. If not provided, the value from the style
- cycle is used. Exception: If ``line`` is given, but no ``marker``,
- the data will be a line without markers.
-
- **Colors**
-
- The following color abbreviations are supported:
-
- ============= ===============================
- character color
- ============= ===============================
- ``'b'`` blue
- ``'g'`` green
- ``'r'`` red
- ``'c'`` cyan
- ``'m'`` magenta
- ``'y'`` yellow
- ``'k'`` black
- ``'w'`` white
- ============= ===============================
-
- If the color is the only part of the format string, you can
- additionally use any `matplotlib.colors` spec, e.g. full names
- (``'green'``) or hex strings (``'#008000'``).
-
- **Markers**
-
- ============= ===============================
- character description
- ============= ===============================
- ``'.'`` point marker
- ``','`` pixel marker
- ``'o'`` circle marker
- ``'v'`` triangle_down marker
- ``'^'`` triangle_up marker
- ``'<'`` triangle_left marker
- ``'>'`` triangle_right marker
- ``'1'`` tri_down marker
- ``'2'`` tri_up marker
- ``'3'`` tri_left marker
- ``'4'`` tri_right marker
- ``'s'`` square marker
- ``'p'`` pentagon marker
- ``'*'`` star marker
- ``'h'`` hexagon1 marker
- ``'H'`` hexagon2 marker
- ``'+'`` plus marker
- ``'x'`` x marker
- ``'D'`` diamond marker
- ``'d'`` thin_diamond marker
- ``'|'`` vline marker
- ``'_'`` hline marker
- ============= ===============================
-
- **Line Styles**
-
- ============= ===============================
- character description
- ============= ===============================
- ``'-'`` solid line style
- ``'--'`` dashed line style
- ``'-.'`` dash-dot line style
- ``':'`` dotted line style
- ============= ===============================
-
- Example format strings::
-
- 'b' # blue markers with default shape
- 'ro' # red circles
- 'g-' # green solid line
- '--' # dashed line with default color
- 'k^:' # black triangle_up markers connected by a dotted line
-
- """
- scalex = kwargs.pop('scalex', True)
- scaley = kwargs.pop('scaley', True)
-
- if not self._hold:
- self.cla()
- lines = []
-
- kwargs = cbook.normalize_kwargs(kwargs, _alias_map)
-
- for line in self._get_lines(*args, **kwargs):
- self.add_line(line)
- lines.append(line)
-
- self.autoscale_view(scalex=scalex, scaley=scaley)
- return lines
-
- @_preprocess_data(replace_names=["x", "y"], label_namer="y")
- @docstring.dedent_interpd
- def plot_date(self, x, y, fmt='o', tz=None, xdate=True, ydate=False,
- **kwargs):
- """
- Plot data that contains dates.
-
- Similar to `.plot`, this plots *y* vs. *x* as lines or markers.
- However, the axis labels are formatted as dates depending on *xdate*
- and *ydate*.
-
- Parameters
- ----------
- x, y : array-like
- The coordinates of the data points. If *xdate* or *ydate* is
- *True*, the respective values *x* or *y* are interpreted as
- :ref:`Matplotlib dates <date-format>`.
-
- fmt : str, optional
- The plot format string. For details, see the corresponding
- parameter in `.plot`.
-
- tz : [ *None* | timezone string | :class:`tzinfo` instance]
- The time zone to use in labeling dates. If *None*, defaults to
- rcParam ``timezone``.
-
- xdate : bool, optional, default: True
- If *True*, the *x*-axis will be interpreted as Matplotlib dates.
-
- ydate : bool, optional, default: False
- If *True*, the *y*-axis will be interpreted as Matplotlib dates.
-
-
- Returns
- -------
- lines
- A list of `~.Line2D` objects representing the plotted data.
-
-
- Other Parameters
- ----------------
- **kwargs
- Keyword arguments control the :class:`~matplotlib.lines.Line2D`
- properties:
-
- %(Line2D)s
-
-
- See Also
- --------
- matplotlib.dates : Helper functions on dates.
- matplotlib.dates.date2num : Convert dates to num.
- matplotlib.dates.num2date : Convert num to dates.
- matplotlib.dates.drange : Create an equally spaced sequence of dates.
-
-
- Notes
- -----
- If you are using custom date tickers and formatters, it may be
- necessary to set the formatters/locators after the call to
- `.plot_date`. `.plot_date` will set the default tick locator to
- `.AutoDateLocator` (if the tick locator is not already set to a
- `.DateLocator` instance) and the default tick formatter to
- `.AutoDateFormatter` (if the tick formatter is not already set to a
- `.DateFormatter` instance).
- """
-
- if not self._hold:
- self.cla()
-
- if xdate:
- self.xaxis_date(tz)
- if ydate:
- self.yaxis_date(tz)
-
- ret = self.plot(x, y, fmt, **kwargs)
-
- self.autoscale_view()
-
- return ret
-
- # @_preprocess_data() # let 'plot' do the unpacking..
- @docstring.dedent_interpd
- def loglog(self, *args, **kwargs):
- """
- Make a plot with log scaling on both the x and y axis.
-
- Call signatures::
-
- loglog([x], y, [fmt], data=None, **kwargs)
- loglog([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
-
- This is just a thin wrapper around `.plot` which additionally changes
- both the x-axis and the y-axis to log scaling. All of the concepts and
- parameters of plot can be used here as well.
-
- The additional parameters *basex/y*, *subsx/y* and *nonposx/y* control
- the x/y-axis properties. They are just forwarded to `.Axes.set_xscale`
- and `.Axes.set_yscale`.
-
- Parameters
- ----------
- basex, basey : scalar, optional, default 10
- Base of the x/y logarithm.
-
- subsx, subsy : sequence, optional
- The location of the minor x/y ticks. If *None*, reasonable
- locations are automatically chosen depending on the number of
- decades in the plot.
- See `.Axes.set_xscale` / `.Axes.set_yscale` for details.
-
- nonposx, nonposy : {'mask', 'clip'}, optional, default 'mask'
- Non-positive values in x or y can be masked as invalid, or clipped
- to a very small positive number.
-
- Returns
- -------
- lines
- A list of `~.Line2D` objects representing the plotted data.
-
- Other Parameters
- ----------------
- **kwargs
- All parameters supported by `.plot`.
- """
- if not self._hold:
- self.cla()
-
- dx = {k: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx']
- if k in kwargs}
- dy = {k: kwargs.pop(k) for k in ['basey', 'subsy', 'nonposy']
- if k in kwargs}
-
- self.set_xscale('log', **dx)
- self.set_yscale('log', **dy)
-
- b = self._hold
- self._hold = True # we've already processed the hold
- l = self.plot(*args, **kwargs)
- self._hold = b # restore the hold
-
- return l
-
- # @_preprocess_data() # let 'plot' do the unpacking..
- @docstring.dedent_interpd
- def semilogx(self, *args, **kwargs):
- """
- Make a plot with log scaling on the x axis.
-
- Call signatures::
-
- semilogx([x], y, [fmt], data=None, **kwargs)
- semilogx([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
-
- This is just a thin wrapper around `.plot` which additionally changes
- the x-axis to log scaling. All of the concepts and parameters of plot
- can be used here as well.
-
- The additional parameters *basex*, *subsx* and *nonposx* control the
- x-axis properties. They are just forwarded to `.Axes.set_xscale`.
-
- Parameters
- ----------
- basex : scalar, optional, default 10
- Base of the x logarithm.
-
- subsx : array_like, optional
- The location of the minor xticks. If *None*, reasonable locations
- are automatically chosen depending on the number of decades in the
- plot. See `.Axes.set_xscale` for details.
-
- nonposx : {'mask', 'clip'}, optional, default 'mask'
- Non-positive values in x can be masked as invalid, or clipped to a
- very small positive number.
-
- Returns
- -------
- lines
- A list of `~.Line2D` objects representing the plotted data.
-
- Other Parameters
- ----------------
- **kwargs
- All parameters supported by `.plot`.
- """
- if not self._hold:
- self.cla()
- d = {k: kwargs.pop(k) for k in ['basex', 'subsx', 'nonposx']
- if k in kwargs}
-
- self.set_xscale('log', **d)
- b = self._hold
- self._hold = True # we've already processed the hold
- l = self.plot(*args, **kwargs)
- self._hold = b # restore the hold
- return l
-
- # @_preprocess_data() # let 'plot' do the unpacking..
- @docstring.dedent_interpd
- def semilogy(self, *args, **kwargs):
- """
- Make a plot with log scaling on the y axis.
-
- Call signatures::
-
- semilogy([x], y, [fmt], data=None, **kwargs)
- semilogy([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
-
- This is just a thin wrapper around `.plot` which additionally changes
- the y-axis to log scaling. All of the concepts and parameters of plot
- can be used here as well.
-
- The additional parameters *basey*, *subsy* and *nonposy* control the
- y-axis properties. They are just forwarded to `.Axes.set_yscale`.
-
- Parameters
- ----------
- basey : scalar, optional, default 10
- Base of the y logarithm.
-
- subsy : array_like, optional
- The location of the minor yticks. If *None*, reasonable locations
- are automatically chosen depending on the number of decades in the
- plot. See `.Axes.set_yscale` for details.
-
- nonposy : {'mask', 'clip'}, optional, default 'mask'
- Non-positive values in y can be masked as invalid, or clipped to a
- very small positive number.
-
- Returns
- -------
- lines
- A list of `~.Line2D` objects representing the plotted data.
-
- Other Parameters
- ----------------
- **kwargs
- All parameters supported by `.plot`.
- """
- if not self._hold:
- self.cla()
- d = {k: kwargs.pop(k) for k in ['basey', 'subsy', 'nonposy']
- if k in kwargs}
- self.set_yscale('log', **d)
- b = self._hold
- self._hold = True # we've already processed the hold
- l = self.plot(*args, **kwargs)
- self._hold = b # restore the hold
-
- return l
-
- @_preprocess_data(replace_names=["x"], label_namer="x")
- def acorr(self, x, **kwargs):
- """
- Plot the autocorrelation of *x*.
-
- Parameters
- ----------
-
- x : sequence of scalar
-
- hold : bool, optional, *deprecated*, default: True
-
- detrend : callable, optional, default: `mlab.detrend_none`
- *x* is detrended by the *detrend* callable. Default is no
- normalization.
-
- normed : bool, optional, default: True
- If ``True``, input vectors are normalised to unit length.
-
- usevlines : bool, optional, default: True
- If ``True``, `Axes.vlines` is used to plot the vertical lines from
- the origin to the acorr. Otherwise, `Axes.plot` is used.
-
- maxlags : integer, optional, default: 10
- Number of lags to show. If ``None``, will return all
- ``2 * len(x) - 1`` lags.
-
- Returns
- -------
- lags : array (lenth ``2*maxlags+1``)
- lag vector.
- c : array (length ``2*maxlags+1``)
- auto correlation vector.
- line : `.LineCollection` or `.Line2D`
- `.Artist` added to the axes of the correlation.
-
- `.LineCollection` if *usevlines* is True
- `.Line2D` if *usevlines* is False
- b : `.Line2D` or None
- Horizontal line at 0 if *usevlines* is True
- None *usevlines* is False
-
- Other Parameters
- ----------------
- linestyle : `~matplotlib.lines.Line2D` prop, optional, default: None
- Only used if usevlines is ``False``.
-
- marker : string, optional, default: 'o'
-
- Notes
- -----
- The cross correlation is performed with :func:`numpy.correlate` with
- ``mode = 2``.
- """
- if "hold" in kwargs:
- warnings.warn("the 'hold' kwarg is deprecated", mplDeprecation)
- return self.xcorr(x, x, **kwargs)
-
- @_preprocess_data(replace_names=["x", "y"], label_namer="y")
- def xcorr(self, x, y, normed=True, detrend=mlab.detrend_none,
- usevlines=True, maxlags=10, **kwargs):
- r"""
- Plot the cross correlation between *x* and *y*.
-
- The correlation with lag k is defined as sum_n x[n+k] * conj(y[n]).
-
- Parameters
- ----------
- x : sequence of scalars of length n
-
- y : sequence of scalars of length n
-
- hold : bool, optional, *deprecated*, default: True
-
- detrend : callable, optional, default: `mlab.detrend_none`
- *x* is detrended by the *detrend* callable. Default is no
- normalization.
-
- normed : bool, optional, default: True
- If ``True``, input vectors are normalised to unit length.
-
- usevlines : bool, optional, default: True
- If ``True``, `Axes.vlines` is used to plot the vertical lines from
- the origin to the acorr. Otherwise, `Axes.plot` is used.
-
- maxlags : int, optional
- Number of lags to show. If None, will return all ``2 * len(x) - 1``
- lags. Default is 10.
-
- Returns
- -------
- lags : array (lenth ``2*maxlags+1``)
- lag vector.
- c : array (length ``2*maxlags+1``)
- auto correlation vector.
- line : `.LineCollection` or `.Line2D`
- `.Artist` added to the axes of the correlation
-
- `.LineCollection` if *usevlines* is True
- `.Line2D` if *usevlines* is False
- b : `.Line2D` or None
- Horizontal line at 0 if *usevlines* is True
- None *usevlines* is False
-
- Other Parameters
- ----------------
- linestyle : `~matplotlib.lines.Line2D` property, optional
- Only used if usevlines is ``False``.
-
- marker : string, optional
- Default is 'o'.
-
- Notes
- -----
- The cross correlation is performed with :func:`numpy.correlate` with
- ``mode = 2``.
- """
- if "hold" in kwargs:
- warnings.warn("the 'hold' kwarg is deprecated", mplDeprecation)
-
- Nx = len(x)
- if Nx != len(y):
- raise ValueError('x and y must be equal length')
-
- x = detrend(np.asarray(x))
- y = detrend(np.asarray(y))
-
- correls = np.correlate(x, y, mode=2)
-
- if normed:
- correls /= np.sqrt(np.dot(x, x) * np.dot(y, y))
-
- if maxlags is None:
- maxlags = Nx - 1
-
- if maxlags >= Nx or maxlags < 1:
- raise ValueError('maxlags must be None or strictly '
- 'positive < %d' % Nx)
-
- lags = np.arange(-maxlags, maxlags + 1)
- correls = correls[Nx - 1 - maxlags:Nx + maxlags]
-
- if usevlines:
- a = self.vlines(lags, [0], correls, **kwargs)
- # Make label empty so only vertical lines get a legend entry
- kwargs.pop('label', '')
- b = self.axhline(**kwargs)
- else:
- kwargs.setdefault('marker', 'o')
- kwargs.setdefault('linestyle', 'None')
- a, = self.plot(lags, correls, **kwargs)
- b = None
- return lags, correls, a, b
-
- #### Specialized plotting
-
- @_preprocess_data(replace_names=["x", "y"], label_namer="y")
- def step(self, x, y, *args, **kwargs):
- """
- Make a step plot.
-
- Call signatures::
-
- step(x, y, [fmt], *, data=None, where='pre', **kwargs)
- step(x, y, [fmt], x2, y2, [fmt2], ..., *, where='pre', **kwargs)
-
- This is just a thin wrapper around `.plot` which changes some
- formatting options. Most of the concepts and parameters of plot can be
- used here as well.
-
- Parameters
- ----------
- x : array_like
- 1-D sequence of x positions. It is assumed, but not checked, that
- it is uniformly increasing.
-
- y : array_like
- 1-D sequence of y levels.
-
- fmt : str, optional
- A format string, e.g. 'g' for a green line. See `.plot` for a more
- detailed description.
-
- Note: While full format strings are accepted, it is recommended to
- only specify the color. Line styles are currently ignored (use
- the keyword argument *linestyle* instead). Markers are accepted
- and plotted on the given positions, however, this is a rarely
- needed feature for step plots.
-
- data : indexable object, optional
- An object with labelled data. If given, provide the label names to
- plot in *x* and *y*.
-
- where : {'pre', 'post', 'mid'}, optional, default 'pre'
- Define where the steps should be placed:
-
- - 'pre': The y value is continued constantly to the left from
- every *x* position, i.e. the interval ``(x[i-1], x[i]]`` has the
- value ``y[i]``.
- - 'post': The y value is continued constantly to the right from
- every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the
- value ``y[i]``.
- - 'mid': Steps occur half-way between the *x* positions.
-
- Returns
- -------
- lines
- A list of `.Line2D` objects representing the plotted data.
-
- Other Parameters
- ----------------
- **kwargs
- Additional parameters are the same as those for `.plot`.
-
- Notes
- -----
- .. [notes section required to get data note injection right]
- """
- where = kwargs.pop('where', 'pre')
- if where not in ('pre', 'post', 'mid'):
- raise ValueError("'where' argument to step must be "
- "'pre', 'post' or 'mid'")
- usr_linestyle = kwargs.pop('linestyle', '')
- kwargs['linestyle'] = 'steps-' + where + usr_linestyle
-
- return self.plot(x, y, *args, **kwargs)
-
- @_preprocess_data(replace_names=["x", "left",
- "height", "width",
- "y", "bottom",
- "color", "edgecolor", "linewidth",
- "tick_label", "xerr", "yerr",
- "ecolor"],
- label_namer=None,
- replace_all_args=True
- )
- @docstring.dedent_interpd
- def bar(self, *args, **kwargs):
- r"""
- Make a bar plot.
-
- Call signatures::
-
- bar(x, height, *, align='center', **kwargs)
- bar(x, height, width, *, align='center', **kwargs)
- bar(x, height, width, bottom, *, align='center', **kwargs)
-
- The bars are positioned at *x* with the given *align* ment. Their
- dimensions are given by *width* and *height*. The vertical baseline
- is *bottom* (default 0).
-
- Each of *x*, *height*, *width*, and *bottom* may either be a scalar
- applying to all bars, or it may be a sequence of length N providing a
- separate value for each bar.
-
-
- Parameters
- ----------
- x : sequence of scalars
- The x coordinates of the bars. See also *align* for the
- alignment of the bars to the coordinates.
-
- height : scalar or sequence of scalars
- The height(s) of the bars.
-
- width : scalar or array-like, optional
- The width(s) of the bars (default: 0.8).
-
- bottom : scalar or array-like, optional
- The y coordinate(s) of the bars bases (default: 0).
-
- align : {'center', 'edge'}, optional, default: 'center'
- Alignment of the bars to the *x* coordinates:
-
- - 'center': Center the base on the *x* positions.
- - 'edge': Align the left edges of the bars with the *x* positions.
-
- To align the bars on the right edge pass a negative *width* and
- ``align='edge'``.
-
- Returns
- -------
- container : `.BarContainer`
- Container with all the bars and optionally errorbars.
-
- Other Parameters
- ----------------
- color : scalar or array-like, optional
- The colors of the bar faces.
-
- edgecolor : scalar or array-like, optional
- The colors of the bar edges.
-
- linewidth : scalar or array-like, optional
- Width of the bar edge(s). If 0, don't draw edges.
-
- tick_label : string or array-like, optional
- The tick labels of the bars.
- Default: None (Use default numeric labels.)
-
- xerr, yerr : scalar or array-like of shape(N,) or shape(2,N), optional
- If not *None*, add horizontal / vertical errorbars to the bar tips.
- The values are +/- sizes relative to the data:
-
- - scalar: symmetric +/- values for all bars
- - shape(N,): symmetric +/- values for each bar
- - shape(2,N): Separate - and + values for each bar. First row
- contains the lower errors, the second row contains the
- upper errors.
- - *None*: No errorbar. (Default)
-
- See :doc:`/gallery/statistics/errorbar_features`
- for an example on the usage of ``xerr`` and ``yerr``.
-
- ecolor : scalar or array-like, optional, default: 'black'
- The line color of the errorbars.
-
- capsize : scalar, optional
- The length of the error bar caps in points.
- Default: None, which will take the value from
- :rc:`errorbar.capsize`.
-
- error_kw : dict, optional
- Dictionary of kwargs to be passed to the `~.Axes.errorbar`
- method. Values of *ecolor* or *capsize* defined here take
- precedence over the independent kwargs.
-
- log : bool, optional, default: False
- If *True*, set the y-axis to be log scale.
-
- orientation : {'vertical', 'horizontal'}, optional
- *This is for internal use only.* Please use `barh` for
- horizontal bar plots. Default: 'vertical'.
-
- See also
- --------
- barh: Plot a horizontal bar plot.
-
- Notes
- -----
- The optional arguments *color*, *edgecolor*, *linewidth*,
- *xerr*, and *yerr* can be either scalars or sequences of
- length equal to the number of bars. This enables you to use
- bar as the basis for stacked bar charts, or candlestick plots.
- Detail: *xerr* and *yerr* are passed directly to
- :meth:`errorbar`, so they can also have shape 2xN for
- independent specification of lower and upper errors.
-
- Other optional kwargs:
-
- %(Rectangle)s
-
- """
- kwargs = cbook.normalize_kwargs(kwargs, mpatches._patch_alias_map)
- # this is using the lambdas to do the arg/kwarg unpacking rather
- # than trying to re-implement all of that logic our selves.
- matchers = [
- (lambda x, height, width=0.8, bottom=None, **kwargs:
- (False, x, height, width, bottom, kwargs)),
- (lambda left, height, width=0.8, bottom=None, **kwargs:
- (True, left, height, width, bottom, kwargs)),
- ]
- exps = []
- for matcher in matchers:
- try:
- dp, x, height, width, y, kwargs = matcher(*args, **kwargs)
- except TypeError as e:
- # This can only come from a no-match as there is
- # no other logic in the matchers.
- exps.append(e)
- else:
- break
- else:
- raise exps[0]
- # if we matched the second-case, then the user passed in
- # left=val as a kwarg which we want to deprecate
- if dp:
- warnings.warn(
- "The *left* kwarg to `bar` is deprecated use *x* instead. "
- "Support for *left* will be removed in Matplotlib 3.0",
- mplDeprecation, stacklevel=2)
- if not self._hold:
- self.cla()
- color = kwargs.pop('color', None)
- if color is None:
- color = self._get_patches_for_fill.get_next_color()
- edgecolor = kwargs.pop('edgecolor', None)
- linewidth = kwargs.pop('linewidth', None)
-
- # Because xerr and yerr will be passed to errorbar,
- # most dimension checking and processing will be left
- # to the errorbar method.
- xerr = kwargs.pop('xerr', None)
- yerr = kwargs.pop('yerr', None)
- error_kw = kwargs.pop('error_kw', dict())
- ecolor = kwargs.pop('ecolor', 'k')
- capsize = kwargs.pop('capsize', rcParams["errorbar.capsize"])
- error_kw.setdefault('ecolor', ecolor)
- error_kw.setdefault('capsize', capsize)
-
- if rcParams['_internal.classic_mode']:
- align = kwargs.pop('align', 'edge')
- else:
- align = kwargs.pop('align', 'center')
-
- orientation = kwargs.pop('orientation', 'vertical')
- log = kwargs.pop('log', False)
- label = kwargs.pop('label', '')
- tick_labels = kwargs.pop('tick_label', None)
-
- adjust_ylim = False
- adjust_xlim = False
-
- if orientation == 'vertical':
- if y is None:
- if self.get_yscale() == 'log':
- adjust_ylim = True
- y = 0
-
- elif orientation == 'horizontal':
- if x is None:
- if self.get_xscale() == 'log':
- adjust_xlim = True
- x = 0
-
- if orientation == 'vertical':
- self._process_unit_info(xdata=x, ydata=height, kwargs=kwargs)
- if log:
- self.set_yscale('log', nonposy='clip')
- elif orientation == 'horizontal':
- self._process_unit_info(xdata=width, ydata=y, kwargs=kwargs)
- if log:
- self.set_xscale('log', nonposx='clip')
- else:
- raise ValueError('invalid orientation: %s' % orientation)
-
- # lets do some conversions now since some types cannot be
- # subtracted uniformly
- if self.xaxis is not None:
- x = self.convert_xunits(x)
- width = self.convert_xunits(width)
- if xerr is not None:
- xerr = self.convert_xunits(xerr)
-
- if self.yaxis is not None:
- y = self.convert_yunits(y)
- height = self.convert_yunits(height)
- if yerr is not None:
- yerr = self.convert_yunits(yerr)
-
- x, height, width, y, linewidth = np.broadcast_arrays(
- # Make args iterable too.
- np.atleast_1d(x), height, width, y, linewidth)
-
- # Now that units have been converted, set the tick locations.
- if orientation == 'vertical':
- tick_label_axis = self.xaxis
- tick_label_position = x
- elif orientation == 'horizontal':
- tick_label_axis = self.yaxis
- tick_label_position = y
-
- linewidth = itertools.cycle(np.atleast_1d(linewidth))
- color = itertools.chain(itertools.cycle(mcolors.to_rgba_array(color)),
- # Fallback if color == "none".
- itertools.repeat([0, 0, 0, 0]))
- if edgecolor is None:
- edgecolor = itertools.repeat(None)
- else:
- edgecolor = itertools.chain(
- itertools.cycle(mcolors.to_rgba_array(edgecolor)),
- # Fallback if edgecolor == "none".
- itertools.repeat([0, 0, 0, 0]))
-
- # We will now resolve the alignment and really have
- # left, bottom, width, height vectors
- if align == 'center':
- if orientation == 'vertical':
- left = x - width / 2
- bottom = y
- elif orientation == 'horizontal':
- bottom = y - height / 2
- left = x
- elif align == 'edge':
- left = x
- bottom = y
- else:
- raise ValueError('invalid alignment: %s' % align)
-
- patches = []
- args = zip(left, bottom, width, height, color, edgecolor, linewidth)
- for l, b, w, h, c, e, lw in args:
- r = mpatches.Rectangle(
- xy=(l, b), width=w, height=h,
- facecolor=c,
- edgecolor=e,
- linewidth=lw,
- label='_nolegend_',
- )
- r.update(kwargs)
- r.get_path()._interpolation_steps = 100
- if orientation == 'vertical':
- r.sticky_edges.y.append(b)
- elif orientation == 'horizontal':
- r.sticky_edges.x.append(l)
- self.add_patch(r)
- patches.append(r)
-
- holdstate = self._hold
- self._hold = True # ensure hold is on before plotting errorbars
-
- if xerr is not None or yerr is not None:
- if orientation == 'vertical':
- # using list comps rather than arrays to preserve unit info
- ex = [l + 0.5 * w for l, w in zip(left, width)]
- ey = [b + h for b, h in zip(bottom, height)]
-
- elif orientation == 'horizontal':
- # using list comps rather than arrays to preserve unit info
- ex = [l + w for l, w in zip(left, width)]
- ey = [b + 0.5 * h for b, h in zip(bottom, height)]
-
- error_kw.setdefault("label", '_nolegend_')
-
- errorbar = self.errorbar(ex, ey,
- yerr=yerr, xerr=xerr,
- fmt='none', **error_kw)
- else:
- errorbar = None
-
- self._hold = holdstate # restore previous hold state
-
- if adjust_xlim:
- xmin, xmax = self.dataLim.intervalx
- xmin = min(w for w in width if w > 0)
- if xerr is not None:
- xmin = xmin - np.max(xerr)
- xmin = max(xmin * 0.9, 1e-100)
- self.dataLim.intervalx = (xmin, xmax)
-
- if adjust_ylim:
- ymin, ymax = self.dataLim.intervaly
- ymin = min(h for h in height if h > 0)
- if yerr is not None:
- ymin = ymin - np.max(yerr)
- ymin = max(ymin * 0.9, 1e-100)
- self.dataLim.intervaly = (ymin, ymax)
- self.autoscale_view()
-
- bar_container = BarContainer(patches, errorbar, label=label)
- self.add_container(bar_container)
-
- if tick_labels is not None:
- tick_labels = _backports.broadcast_to(tick_labels, len(patches))
- tick_label_axis.set_ticks(tick_label_position)
- tick_label_axis.set_ticklabels(tick_labels)
-
- return bar_container
-
- @docstring.dedent_interpd
- def barh(self, *args, **kwargs):
- r"""
- Make a horizontal bar plot.
-
- Call signatures::
-
- bar(y, width, *, align='center', **kwargs)
- bar(y, width, height, *, align='center', **kwargs)
- bar(y, width, height, left, *, align='center', **kwargs)
-
- The bars are positioned at *y* with the given *align*. Their
- dimensions are given by *width* and *height*. The horizontal baseline
- is *left* (default 0).
-
- Each of *y*, *width*, *height*, and *left* may either be a scalar
- applying to all bars, or it may be a sequence of length N providing a
- separate value for each bar.
-
-
- Parameters
- ----------
- y : scalar or array-like
- The y coordinates of the bars. See also *align* for the
- alignment of the bars to the coordinates.
-
- width : scalar or array-like
- The width(s) of the bars.
-
- height : sequence of scalars, optional, default: 0.8
- The heights of the bars.
-
- left : sequence of scalars
- The x coordinates of the left sides of the bars (default: 0).
-
- align : {'center', 'edge'}, optional, default: 'center'
- Alignment of the base to the *y* coordinates*:
-
- - 'center': Center the bars on the *y* positions.
- - 'edge': Align the bottom edges of the bars with the *y*
- positions.
-
- To align the bars on the top edge pass a negative *height* and
- ``align='edge'``.
-
- Returns
- -------
- container : `.BarContainer`
- Container with all the bars and optionally errorbars.
-
- Other Parameters
- ----------------
- color : scalar or array-like, optional
- The colors of the bar faces.
-
- edgecolor : scalar or array-like, optional
- The colors of the bar edges.
-
- linewidth : scalar or array-like, optional
- Width of the bar edge(s). If 0, don't draw edges.
-
- tick_label : string or array-like, optional
- The tick labels of the bars.
- Default: None (Use default numeric labels.)
-
- xerr, yerr : scalar or array-like of shape(N,) or shape(2,N), optional
- If not ``None``, add horizontal / vertical errorbars to the
- bar tips. The values are +/- sizes relative to the data:
-
- - scalar: symmetric +/- values for all bars
- - shape(N,): symmetric +/- values for each bar
- - shape(2,N): Separate - and + values for each bar. First row
- contains the lower errors, the second row contains the
- upper errors.
- - *None*: No errorbar. (default)
-
- See :doc:`/gallery/statistics/errorbar_features`
- for an example on the usage of ``xerr`` and ``yerr``.
-
- ecolor : scalar or array-like, optional, default: 'black'
- The line color of the errorbars.
-
- capsize : scalar, optional
- The length of the error bar caps in points.
- Default: None, which will take the value from
- :rc:`errorbar.capsize`.
-
- error_kw : dict, optional
- Dictionary of kwargs to be passed to the `~.Axes.errorbar`
- method. Values of *ecolor* or *capsize* defined here take
- precedence over the independent kwargs.
-
- log : bool, optional, default: False
- If ``True``, set the x-axis to be log scale.
-
- See also
- --------
- bar: Plot a vertical bar plot.
-
- Notes
- -----
- The optional arguments *color*, *edgecolor*, *linewidth*,
- *xerr*, and *yerr* can be either scalars or sequences of
- length equal to the number of bars. This enables you to use
- bar as the basis for stacked bar charts, or candlestick plots.
- Detail: *xerr* and *yerr* are passed directly to
- :meth:`errorbar`, so they can also have shape 2xN for
- independent specification of lower and upper errors.
-
- Other optional kwargs:
-
- %(Rectangle)s
-
- """
- # this is using the lambdas to do the arg/kwarg unpacking rather
- # than trying to re-implement all of that logic our selves.
- matchers = [
- (lambda y, width, height=0.8, left=None, **kwargs:
- (False, y, width, height, left, kwargs)),
- (lambda bottom, width, height=0.8, left=None, **kwargs:
- (True, bottom, width, height, left, kwargs)),
- ]
- excs = []
- for matcher in matchers:
- try:
- dp, y, width, height, left, kwargs = matcher(*args, **kwargs)
- except TypeError as e:
- # This can only come from a no-match as there is
- # no other logic in the matchers.
- excs.append(e)
- else:
- break
- else:
- raise excs[0]
-
- if dp:
- warnings.warn(
- "The *bottom* kwarg to `barh` is deprecated use *y* instead. "
- "Support for *bottom* will be removed in Matplotlib 3.0",
- mplDeprecation, stacklevel=2)
- kwargs.setdefault('orientation', 'horizontal')
- patches = self.bar(x=left, height=height, width=width,
- bottom=y, **kwargs)
- return patches
-
- @_preprocess_data(label_namer=None)
- @docstring.dedent_interpd
- def broken_barh(self, xranges, yrange, **kwargs):
- """
- Plot a horizontal sequence of rectangles.
-
- A rectangle is drawn for each element of *xranges*. All rectangles
- have the same vertical position and size defined by *yrange*.
-
- This is a convenience function for instantiating a
- `.BrokenBarHCollection`, adding it to the axes and autoscaling the
- view.
-
- Parameters
- ----------
- xranges : sequence of tuples (*xmin*, *xwidth*)
- The x-positions and extends of the rectangles. For each tuple
- (*xmin*, *xwidth*) a rectangle is drawn from *xmin* to *xmin* +
- *xwidth*.
- yranges : (*ymin*, *ymax*)
- The y-position and extend for all the rectangles.
-
- Other Parameters
- ----------------
- **kwargs : :class:`.BrokenBarHCollection` properties
-
- Each *kwarg* can be either a single argument applying to all
- rectangles, e.g.::
-
- facecolors='black'
-
- or a sequence of arguments over which is cycled, e.g.::
-
- facecolors=('black', 'blue')
-
- would create interleaving black and blue rectangles.
-
- Supported keywords:
-
- %(BrokenBarHCollection)s
-
- Returns
- -------
- collection : A :class:`~.collections.BrokenBarHCollection`
-
- Notes
- -----
- .. [Notes section required for data comment. See #10189.]
-
- """
- # process the unit information
- if len(xranges):
- xdata = cbook.safe_first_element(xranges)
- else:
- xdata = None
- if len(yrange):
- ydata = cbook.safe_first_element(yrange)
- else:
- ydata = None
- self._process_unit_info(xdata=xdata,
- ydata=ydata,
- kwargs=kwargs)
- xranges = self.convert_xunits(xranges)
- yrange = self.convert_yunits(yrange)
-
- col = mcoll.BrokenBarHCollection(xranges, yrange, **kwargs)
- self.add_collection(col, autolim=True)
- self.autoscale_view()
-
- return col
-
- @_preprocess_data(replace_all_args=True, label_namer=None)
- def stem(self, *args, **kwargs):
- """
- Create a stem plot.
-
- A stem plot plots vertical lines at each *x* location from the baseline
- to *y*, and places a marker there.
-
- Call signature::
-
- stem([x,] y, linefmt=None, markerfmt=None, basefmt=None)
-
- The x-positions are optional. The formats may be provided either as
- positional or as keyword-arguments.
-
- Parameters
- ----------
- x : array-like, optional
- The x-positions of the stems. Default: (0, 1, ..., len(y) - 1).
-
- y : array-like
- The y-values of the stem heads.
-
- linefmt : str, optional
- A string defining the properties of the vertical lines. Usually,
- this will be a color or a color and a linestyle:
-
- ========= =============
- Character Line Style
- ========= =============
- ``'-'`` solid line
- ``'--'`` dashed line
- ``'-.'`` dash-dot line
- ``':'`` dotted line
- ========= =============
-
- Default: 'C0-', i.e. solid line with the first color of the color
- cycle.
-
- Note: While it is technically possible to specify valid formats
- other than color or color and linestyle (e.g. 'rx' or '-.'), this
- is beyond the intention of the method and will most likely not
- result in a reasonable reasonable plot.
-
- markerfmt : str, optional
- A string defining the properties of the markers at the stem heads.
- Default: 'C0o', i.e. filled circles with the first color of the
- color cycle.
-
- basefmt : str, optional
- A format string defining the properties of the baseline.
-
- Default: 'C3-' ('C2-' in classic mode).
-
- bottom : float, optional, default: 0
- The y-position of the baseline.
-
- label : str, optional, default: None
- The label to use for the stems in legends.
-
-
- Other Parameters
- ----------------
- **kwargs
- No other parameters are supported. They are currently ignored
- silently for backward compatibility. This behavior is deprecated.
- Future versions will not accept any other parameters and will
- raise a TypeError instead.
-
-
- Returns
- -------
- container : :class:`~matplotlib.container.StemContainer`
- The container may be treated like a tuple
- (*markerline*, *stemlines*, *baseline*)
-
-
- Notes
- -----
-
- .. seealso::
- The MATLAB function
- `stem <http://www.mathworks.com/help/techdoc/ref/stem.html>`_
- which inspired this method.
-
- """
-
- # kwargs handling
- # We would like to have a signature with explicit kewords:
- # stem(*args, linefmt=None, markerfmt=None, basefmt=None,
- # bottom=0, label=None)
- # Unfortunately, this is not supported in Python 2.x. There, *args
- # can only exist after keyword arguments.
- linefmt = kwargs.pop('linefmt', None)
- markerfmt = kwargs.pop('markerfmt', None)
- basefmt = kwargs.pop('basefmt', None)
- bottom = kwargs.pop('bottom', None)
- if bottom is None:
- bottom = 0
- label = kwargs.pop('label', None)
- if kwargs:
- warn_deprecated(since='2.2',
- message="stem() got an unexpected keyword "
- "argument '%s'. This will raise a "
- "TypeError in future versions." % (
- next(k for k in kwargs), )
- )
-
- remember_hold = self._hold
- if not self._hold:
- self.cla()
- self._hold = True
-
- # Assume there's at least one data array
- y = np.asarray(args[0])
- args = args[1:]
-
- # Try a second one
- try:
- second = np.asarray(args[0], dtype=float)
- x, y = y, second
- args = args[1:]
- except (IndexError, ValueError):
- # The second array doesn't make sense, or it doesn't exist
- second = np.arange(len(y))
- x = second
-
- # defaults for formats
- if linefmt is None:
- try:
- # fallback to positional argument
- linefmt = args[0]
- except IndexError:
- linecolor = 'C0'
- linemarker = 'None'
- linestyle = '-'
- else:
- linestyle, linemarker, linecolor = \
- _process_plot_format(linefmt)
- else:
- linestyle, linemarker, linecolor = _process_plot_format(linefmt)
-
- if markerfmt is None:
- try:
- # fallback to positional argument
- markerfmt = args[1]
- except IndexError:
- markercolor = 'C0'
- markermarker = 'o'
- markerstyle = 'None'
- else:
- markerstyle, markermarker, markercolor = \
- _process_plot_format(markerfmt)
- else:
- markerstyle, markermarker, markercolor = \
- _process_plot_format(markerfmt)
-
- if basefmt is None:
- try:
- # fallback to positional argument
- basefmt = args[2]
- except IndexError:
- if rcParams['_internal.classic_mode']:
- basecolor = 'C2'
- else:
- basecolor = 'C3'
- basemarker = 'None'
- basestyle = '-'
- else:
- basestyle, basemarker, basecolor = \
- _process_plot_format(basefmt)
- else:
- basestyle, basemarker, basecolor = _process_plot_format(basefmt)
-
- markerline, = self.plot(x, y, color=markercolor, linestyle=markerstyle,
- marker=markermarker, label="_nolegend_")
-
- stemlines = []
- for thisx, thisy in zip(x, y):
- l, = self.plot([thisx, thisx], [bottom, thisy],
- color=linecolor, linestyle=linestyle,
- marker=linemarker, label="_nolegend_")
- stemlines.append(l)
-
- baseline, = self.plot([np.min(x), np.max(x)], [bottom, bottom],
- color=basecolor, linestyle=basestyle,
- marker=basemarker, label="_nolegend_")
-
- self._hold = remember_hold
-
- stem_container = StemContainer((markerline, stemlines, baseline),
- label=label)
- self.add_container(stem_container)
-
- return stem_container
-
- @_preprocess_data(replace_names=["x", "explode", "labels", "colors"],
- label_namer=None)
- def pie(self, x, explode=None, labels=None, colors=None,
- autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1,
- startangle=None, radius=None, counterclock=True,
- wedgeprops=None, textprops=None, center=(0, 0),
- frame=False, rotatelabels=False):
- """
- Plot a pie chart.
-
- Make a pie chart of array *x*. The fractional area of each wedge is
- given by ``x/sum(x)``. If ``sum(x) < 1``, then the values of *x* give
- the fractional area directly and the array will not be normalized. The
- resulting pie will have an empty wedge of size ``1 - sum(x)``.
-
- The wedges are plotted counterclockwise, by default starting from the
- x-axis.
-
- Parameters
- ----------
- x : array-like
- The wedge sizes.
-
- explode : array-like, optional, default: None
- If not *None*, is a ``len(x)`` array which specifies the fraction
- of the radius with which to offset each wedge.
-
- labels : list, optional, default: None
- A sequence of strings providing the labels for each wedge
-
- colors : array-like, optional, default: None
- A sequence of matplotlib color args through which the pie chart
- will cycle. If *None*, will use the colors in the currently
- active cycle.
-
- autopct : None (default), string, or function, optional
- If not *None*, is a string or function used to label the wedges
- with their numeric value. The label will be placed inside the
- wedge. If it is a format string, the label will be ``fmt%pct``.
- If it is a function, it will be called.
-
- pctdistance : float, optional, default: 0.6
- The ratio between the center of each pie slice and the start of
- the text generated by *autopct*. Ignored if *autopct* is *None*.
-
- shadow : bool, optional, default: False
- Draw a shadow beneath the pie.
-
- labeldistance : float, optional, default: 1.1
- The radial distance at which the pie labels are drawn
-
- startangle : float, optional, default: None
- If not *None*, rotates the start of the pie chart by *angle*
- degrees counterclockwise from the x-axis.
-
- radius : float, optional, default: None
- The radius of the pie, if *radius* is *None* it will be set to 1.
-
- counterclock : bool, optional, default: True
- Specify fractions direction, clockwise or counterclockwise.
-
- wedgeprops : dict, optional, default: None
- Dict of arguments passed to the wedge objects making the pie.
- For example, you can pass in ``wedgeprops = {'linewidth': 3}``
- to set the width of the wedge border lines equal to 3.
- For more details, look at the doc/arguments of the wedge object.
- By default ``clip_on=False``.
-
- textprops : dict, optional, default: None
- Dict of arguments to pass to the text objects.
-
- center : list of float, optional, default: (0, 0)
- Center position of the chart. Takes value (0, 0) or is a sequence
- of 2 scalars.
-
- frame : bool, optional, default: False
- Plot axes frame with the chart if true.
-
- rotatelabels : bool, optional, default: False
- Rotate each label to the angle of the corresponding slice if true.
-
- Returns
- -------
- patches : list
- A sequence of :class:`matplotlib.patches.Wedge` instances
-
- texts : list
- A list of the label :class:`matplotlib.text.Text` instances.
-
- autotexts : list
- A list of :class:`~matplotlib.text.Text` instances for the numeric
- labels. This will only be returned if the parameter *autopct* is
- not *None*.
-
- Notes
- -----
- The pie chart will probably look best if the figure and axes are
- square, or the Axes aspect is equal.
- """
- x = np.array(x, np.float32)
-
- sx = x.sum()
- if sx > 1:
- x /= sx
-
- if labels is None:
- labels = [''] * len(x)
- if explode is None:
- explode = [0] * len(x)
- if len(x) != len(labels):
- raise ValueError("'label' must be of length 'x'")
- if len(x) != len(explode):
- raise ValueError("'explode' must be of length 'x'")
- if colors is None:
- get_next_color = self._get_patches_for_fill.get_next_color
- else:
- color_cycle = itertools.cycle(colors)
-
- def get_next_color():
- return next(color_cycle)
-
- if radius is None:
- radius = 1
-
- # Starting theta1 is the start fraction of the circle
- if startangle is None:
- theta1 = 0
- else:
- theta1 = startangle / 360.0
-
- # set default values in wedge_prop
- if wedgeprops is None:
- wedgeprops = {}
- wedgeprops.setdefault('clip_on', False)
-
- if textprops is None:
- textprops = {}
- textprops.setdefault('clip_on', False)
-
- texts = []
- slices = []
- autotexts = []
-
- i = 0
- for frac, label, expl in zip(x, labels, explode):
- x, y = center
- theta2 = (theta1 + frac) if counterclock else (theta1 - frac)
- thetam = 2 * np.pi * 0.5 * (theta1 + theta2)
- x += expl * math.cos(thetam)
- y += expl * math.sin(thetam)
-
- w = mpatches.Wedge((x, y), radius, 360. * min(theta1, theta2),
- 360. * max(theta1, theta2),
- facecolor=get_next_color(),
- **wedgeprops)
- slices.append(w)
- self.add_patch(w)
- w.set_label(label)
-
- if shadow:
- # make sure to add a shadow after the call to
- # add_patch so the figure and transform props will be
- # set
- shad = mpatches.Shadow(w, -0.02, -0.02)
- shad.set_zorder(0.9 * w.get_zorder())
- shad.set_label('_nolegend_')
- self.add_patch(shad)
-
- xt = x + labeldistance * radius * math.cos(thetam)
- yt = y + labeldistance * radius * math.sin(thetam)
- label_alignment_h = xt > 0 and 'left' or 'right'
- label_alignment_v = 'center'
- label_rotation = 'horizontal'
- if rotatelabels:
- label_alignment_v = yt > 0 and 'bottom' or 'top'
- label_rotation = np.rad2deg(thetam) + (0 if xt > 0 else 180)
-
- t = self.text(xt, yt, label,
- size=rcParams['xtick.labelsize'],
- horizontalalignment=label_alignment_h,
- verticalalignment=label_alignment_v,
- rotation=label_rotation,
- **textprops)
-
- texts.append(t)
-
- if autopct is not None:
- xt = x + pctdistance * radius * math.cos(thetam)
- yt = y + pctdistance * radius * math.sin(thetam)
- if isinstance(autopct, six.string_types):
- s = autopct % (100. * frac)
- elif callable(autopct):
- s = autopct(100. * frac)
- else:
- raise TypeError(
- 'autopct must be callable or a format string')
-
- t = self.text(xt, yt, s,
- horizontalalignment='center',
- verticalalignment='center',
- **textprops)
-
- autotexts.append(t)
-
- theta1 = theta2
- i += 1
-
- if not frame:
- self.set_frame_on(False)
-
- self.set_xlim((-1.25 + center[0],
- 1.25 + center[0]))
- self.set_ylim((-1.25 + center[1],
- 1.25 + center[1]))
- self.set_xticks([])
- self.set_yticks([])
-
- if autopct is None:
- return slices, texts
- else:
- return slices, texts, autotexts
-
- @_preprocess_data(replace_names=["x", "y", "xerr", "yerr"],
- label_namer="y")
- @docstring.dedent_interpd
- def errorbar(self, x, y, yerr=None, xerr=None,
- fmt='', ecolor=None, elinewidth=None, capsize=None,
- barsabove=False, lolims=False, uplims=False,
- xlolims=False, xuplims=False, errorevery=1, capthick=None,
- **kwargs):
- """
- Plot y versus x as lines and/or markers with attached errorbars.
-
- *x*, *y* define the data locations, *xerr*, *yerr* define the errorbar
- sizes. By default, this draws the data markers/lines as well the
- errorbars. Use fmt='none' to draw errorbars without any data markers.
-
- Parameters
- ----------
- x, y : scalar or array-like
- The data positions.
-
- xerr, yerr : scalar or array-like, shape(N,) or shape(2,N), optional
- The errorbar sizes:
-
- - scalar: Symmetric +/- values for all data points.
- - shape(N,): Symmetric +/-values for each data point.
- - shape(2,N): Separate - and + values for each bar. First row
- contains the lower errors, the second row contains the
- upper errors.
- - *None*: No errorbar.
-
- See :doc:`/gallery/statistics/errorbar_features`
- for an example on the usage of ``xerr`` and ``yerr``.
-
- fmt : plot format string, optional, default: ''
- The format for the data points / data lines. See `.plot` for
- details.
-
- Use 'none' (case insensitive) to plot errorbars without any data
- markers.
-
- ecolor : mpl color, optional, default: None
- A matplotlib color arg which gives the color the errorbar lines.
- If None, use the color of the line connecting the markers.
-
- elinewidth : scalar, optional, default: None
- The linewidth of the errorbar lines. If None, the linewidth of
- the current style is used.
-
- capsize : scalar, optional, default: None
- The length of the error bar caps in points. If None, it will take
- the value from :rc:`errorbar.capsize`.
-
- capthick : scalar, optional, default: None
- An alias to the keyword argument *markeredgewidth* (a.k.a. *mew*).
- This setting is a more sensible name for the property that
- controls the thickness of the error bar cap in points. For
- backwards compatibility, if *mew* or *markeredgewidth* are given,
- then they will over-ride *capthick*. This may change in future
- releases.
-
- barsabove : bool, optional, default: False
- If True, will plot the errorbars above the plot
- symbols. Default is below.
-
- lolims, uplims, xlolims, xuplims : bool, optional, default: None
- These arguments can be used to indicate that a value gives only
- upper/lower limits. In that case a caret symbol is used to
- indicate this. *lims*-arguments may be of the same type as *xerr*
- and *yerr*. To use limits with inverted axes, :meth:`set_xlim`
- or :meth:`set_ylim` must be called before :meth:`errorbar`.
-
- errorevery : positive integer, optional, default: 1
- Subsamples the errorbars. e.g., if errorevery=5, errorbars for
- every 5-th datapoint will be plotted. The data plot itself still
- shows all data points.
-
- Returns
- -------
- container : :class:`~.container.ErrorbarContainer`
- The container contains:
-
- - plotline: :class:`~matplotlib.lines.Line2D` instance of
- x, y plot markers and/or line.
- - caplines: A tuple of :class:`~matplotlib.lines.Line2D` instances
- of the error bar caps.
- - barlinecols: A tuple of
- :class:`~matplotlib.collections.LineCollection` with the
- horizontal and vertical error ranges.
-
- Other Parameters
- ----------------
- **kwargs :
- All other keyword arguments are passed on to the plot
- command for the markers. For example, this code makes big red
- squares with thick green edges::
-
- x,y,yerr = rand(3,10)
- errorbar(x, y, yerr, marker='s', mfc='red',
- mec='green', ms=20, mew=4)
-
- where *mfc*, *mec*, *ms* and *mew* are aliases for the longer
- property names, *markerfacecolor*, *markeredgecolor*, *markersize*
- and *markeredgewidth*.
-
- Valid kwargs for the marker properties are `.Lines2D` properties:
-
- %(Line2D)s
-
- Notes
- -----
- .. [Notes section required for data comment. See #10189.]
-
- """
- kwargs = cbook.normalize_kwargs(kwargs, _alias_map)
- # anything that comes in as 'None', drop so the default thing
- # happens down stream
- kwargs = {k: v for k, v in kwargs.items() if v is not None}
- kwargs.setdefault('zorder', 2)
-
- if errorevery < 1:
- raise ValueError(
- 'errorevery has to be a strictly positive integer')
-
- self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs)
- if not self._hold:
- self.cla()
- holdstate = self._hold
- self._hold = True
-
- plot_line = (fmt.lower() != 'none')
- label = kwargs.pop("label", None)
-
- if fmt == '':
- fmt_style_kwargs = {}
- else:
- fmt_style_kwargs = {k: v for k, v in
- zip(('linestyle', 'marker', 'color'),
- _process_plot_format(fmt)) if v is not None}
- if fmt == 'none':
- # Remove alpha=0 color that _process_plot_format returns
- fmt_style_kwargs.pop('color')
-
- if ('color' in kwargs or 'color' in fmt_style_kwargs or
- ecolor is not None):
- base_style = {}
- if 'color' in kwargs:
- base_style['color'] = kwargs.pop('color')
- else:
- base_style = next(self._get_lines.prop_cycler)
-
- base_style['label'] = '_nolegend_'
- base_style.update(fmt_style_kwargs)
- if 'color' not in base_style:
- base_style['color'] = 'C0'
- if ecolor is None:
- ecolor = base_style['color']
- # make sure all the args are iterable; use lists not arrays to
- # preserve units
- if not iterable(x):
- x = [x]
-
- if not iterable(y):
- y = [y]
-
- if xerr is not None:
- if not iterable(xerr):
- xerr = [xerr] * len(x)
-
- if yerr is not None:
- if not iterable(yerr):
- yerr = [yerr] * len(y)
-
- # make the style dict for the 'normal' plot line
- plot_line_style = dict(base_style)
- plot_line_style.update(**kwargs)
- if barsabove:
- plot_line_style['zorder'] = kwargs['zorder'] - .1
- else:
- plot_line_style['zorder'] = kwargs['zorder'] + .1
-
- # make the style dict for the line collections (the bars)
- eb_lines_style = dict(base_style)
- eb_lines_style.pop('marker', None)
- eb_lines_style.pop('linestyle', None)
- eb_lines_style['color'] = ecolor
-
- if elinewidth:
- eb_lines_style['linewidth'] = elinewidth
- elif 'linewidth' in kwargs:
- eb_lines_style['linewidth'] = kwargs['linewidth']
-
- for key in ('transform', 'alpha', 'zorder', 'rasterized'):
- if key in kwargs:
- eb_lines_style[key] = kwargs[key]
-
- # set up cap style dictionary
- eb_cap_style = dict(base_style)
- # eject any marker information from format string
- eb_cap_style.pop('marker', None)
- eb_lines_style.pop('markerfacecolor', None)
- eb_lines_style.pop('markeredgewidth', None)
- eb_lines_style.pop('markeredgecolor', None)
- eb_cap_style.pop('ls', None)
- eb_cap_style['linestyle'] = 'none'
- if capsize is None:
- capsize = rcParams["errorbar.capsize"]
- if capsize > 0:
- eb_cap_style['markersize'] = 2. * capsize
- if capthick is not None:
- eb_cap_style['markeredgewidth'] = capthick
-
- # For backwards-compat, allow explicit setting of
- # 'markeredgewidth' to over-ride capthick.
- for key in ('markeredgewidth', 'transform', 'alpha',
- 'zorder', 'rasterized'):
- if key in kwargs:
- eb_cap_style[key] = kwargs[key]
- eb_cap_style['color'] = ecolor
-
- data_line = None
- if plot_line:
- data_line = mlines.Line2D(x, y, **plot_line_style)
- self.add_line(data_line)
-
- barcols = []
- caplines = []
-
- # arrays fine here, they are booleans and hence not units
- def _bool_asarray_helper(d, expected):
- if not iterable(d):
- return np.asarray([d] * expected, bool)
- else:
- return np.asarray(d, bool)
-
- lolims = _bool_asarray_helper(lolims, len(x))
- uplims = _bool_asarray_helper(uplims, len(x))
- xlolims = _bool_asarray_helper(xlolims, len(x))
- xuplims = _bool_asarray_helper(xuplims, len(x))
-
- everymask = np.arange(len(x)) % errorevery == 0
-
- def xywhere(xs, ys, mask):
- """
- return xs[mask], ys[mask] where mask is True but xs and
- ys are not arrays
- """
- assert len(xs) == len(ys)
- assert len(xs) == len(mask)
- xs = [thisx for thisx, b in zip(xs, mask) if b]
- ys = [thisy for thisy, b in zip(ys, mask) if b]
- return xs, ys
-
- def extract_err(err, data):
- '''private function to compute error bars
-
- Parameters
- ----------
- err : iterable
- xerr or yerr from errorbar
- data : iterable
- x or y from errorbar
- '''
- try:
- a, b = err
- except (TypeError, ValueError):
- pass
- else:
- if iterable(a) and iterable(b):
- # using list comps rather than arrays to preserve units
- low = [thisx - thiserr for (thisx, thiserr)
- in cbook.safezip(data, a)]
- high = [thisx + thiserr for (thisx, thiserr)
- in cbook.safezip(data, b)]
- return low, high
- # Check if xerr is scalar or symmetric. Asymmetric is handled
- # above. This prevents Nx2 arrays from accidentally
- # being accepted, when the user meant the 2xN transpose.
- # special case for empty lists
- if len(err) > 1:
- fe = safe_first_element(err)
- if (len(err) != len(data) or np.size(fe) > 1):
- raise ValueError("err must be [ scalar | N, Nx1 "
- "or 2xN array-like ]")
- # using list comps rather than arrays to preserve units
- low = [thisx - thiserr for (thisx, thiserr)
- in cbook.safezip(data, err)]
- high = [thisx + thiserr for (thisx, thiserr)
- in cbook.safezip(data, err)]
- return low, high
-
- if xerr is not None:
- left, right = extract_err(xerr, x)
- # select points without upper/lower limits in x and
- # draw normal errorbars for these points
- noxlims = ~(xlolims | xuplims)
- if noxlims.any() or len(noxlims) == 0:
- yo, _ = xywhere(y, right, noxlims & everymask)
- lo, ro = xywhere(left, right, noxlims & everymask)
- barcols.append(self.hlines(yo, lo, ro, **eb_lines_style))
- if capsize > 0:
- caplines.append(mlines.Line2D(lo, yo, marker='|',
- **eb_cap_style))
- caplines.append(mlines.Line2D(ro, yo, marker='|',
- **eb_cap_style))
-
- if xlolims.any():
- yo, _ = xywhere(y, right, xlolims & everymask)
- lo, ro = xywhere(x, right, xlolims & everymask)
- barcols.append(self.hlines(yo, lo, ro, **eb_lines_style))
- rightup, yup = xywhere(right, y, xlolims & everymask)
- if self.xaxis_inverted():
- marker = mlines.CARETLEFTBASE
- else:
- marker = mlines.CARETRIGHTBASE
- caplines.append(
- mlines.Line2D(rightup, yup, ls='None', marker=marker,
- **eb_cap_style))
- if capsize > 0:
- xlo, ylo = xywhere(x, y, xlolims & everymask)
- caplines.append(mlines.Line2D(xlo, ylo, marker='|',
- **eb_cap_style))
-
- if xuplims.any():
- yo, _ = xywhere(y, right, xuplims & everymask)
- lo, ro = xywhere(left, x, xuplims & everymask)
- barcols.append(self.hlines(yo, lo, ro, **eb_lines_style))
- leftlo, ylo = xywhere(left, y, xuplims & everymask)
- if self.xaxis_inverted():
- marker = mlines.CARETRIGHTBASE
- else:
- marker = mlines.CARETLEFTBASE
- caplines.append(
- mlines.Line2D(leftlo, ylo, ls='None', marker=marker,
- **eb_cap_style))
- if capsize > 0:
- xup, yup = xywhere(x, y, xuplims & everymask)
- caplines.append(mlines.Line2D(xup, yup, marker='|',
- **eb_cap_style))
-
- if yerr is not None:
- lower, upper = extract_err(yerr, y)
- # select points without upper/lower limits in y and
- # draw normal errorbars for these points
- noylims = ~(lolims | uplims)
- if noylims.any() or len(noylims) == 0:
- xo, _ = xywhere(x, lower, noylims & everymask)
- lo, uo = xywhere(lower, upper, noylims & everymask)
- barcols.append(self.vlines(xo, lo, uo, **eb_lines_style))
- if capsize > 0:
- caplines.append(mlines.Line2D(xo, lo, marker='_',
- **eb_cap_style))
- caplines.append(mlines.Line2D(xo, uo, marker='_',
- **eb_cap_style))
-
- if lolims.any():
- xo, _ = xywhere(x, lower, lolims & everymask)
- lo, uo = xywhere(y, upper, lolims & everymask)
- barcols.append(self.vlines(xo, lo, uo, **eb_lines_style))
- xup, upperup = xywhere(x, upper, lolims & everymask)
- if self.yaxis_inverted():
- marker = mlines.CARETDOWNBASE
- else:
- marker = mlines.CARETUPBASE
- caplines.append(
- mlines.Line2D(xup, upperup, ls='None', marker=marker,
- **eb_cap_style))
- if capsize > 0:
- xlo, ylo = xywhere(x, y, lolims & everymask)
- caplines.append(mlines.Line2D(xlo, ylo, marker='_',
- **eb_cap_style))
-
- if uplims.any():
- xo, _ = xywhere(x, lower, uplims & everymask)
- lo, uo = xywhere(lower, y, uplims & everymask)
- barcols.append(self.vlines(xo, lo, uo, **eb_lines_style))
- xlo, lowerlo = xywhere(x, lower, uplims & everymask)
- if self.yaxis_inverted():
- marker = mlines.CARETUPBASE
- else:
- marker = mlines.CARETDOWNBASE
- caplines.append(
- mlines.Line2D(xlo, lowerlo, ls='None', marker=marker,
- **eb_cap_style))
- if capsize > 0:
- xup, yup = xywhere(x, y, uplims & everymask)
- caplines.append(mlines.Line2D(xup, yup, marker='_',
- **eb_cap_style))
- for l in caplines:
- self.add_line(l)
-
- self.autoscale_view()
- self._hold = holdstate
-
- errorbar_container = ErrorbarContainer((data_line, tuple(caplines),
- tuple(barcols)),
- has_xerr=(xerr is not None),
- has_yerr=(yerr is not None),
- label=label)
- self.containers.append(errorbar_container)
-
- return errorbar_container # (l0, caplines, barcols)
-
- @_preprocess_data(label_namer=None)
- def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
- positions=None, widths=None, patch_artist=None,
- bootstrap=None, usermedians=None, conf_intervals=None,
- meanline=None, showmeans=None, showcaps=None,
- showbox=None, showfliers=None, boxprops=None,
- labels=None, flierprops=None, medianprops=None,
- meanprops=None, capprops=None, whiskerprops=None,
- manage_xticks=True, autorange=False, zorder=None):
- """
- Make a box and whisker plot.
-
- Make a box and whisker plot for each column of ``x`` or each
- vector in sequence ``x``. The box extends from the lower to
- upper quartile values of the data, with a line at the median.
- The whiskers extend from the box to show the range of the
- data. Flier points are those past the end of the whiskers.
-
- Parameters
- ----------
- x : Array or a sequence of vectors.
- The input data.
-
- notch : bool, optional (False)
- If `True`, will produce a notched box plot. Otherwise, a
- rectangular boxplot is produced. The notches represent the
- confidence interval (CI) around the median. See the entry
- for the ``bootstrap`` parameter for information regarding
- how the locations of the notches are computed.
-
- .. note::
-
- In cases where the values of the CI are less than the
- lower quartile or greater than the upper quartile, the
- notches will extend beyond the box, giving it a
- distinctive "flipped" appearance. This is expected
- behavior and consistent with other statistical
- visualization packages.
-
- sym : str, optional
- The default symbol for flier points. Enter an empty string
- ('') if you don't want to show fliers. If `None`, then the
- fliers default to 'b+' If you want more control use the
- flierprops kwarg.
-
- vert : bool, optional (True)
- If `True` (default), makes the boxes vertical. If `False`,
- everything is drawn horizontally.
-
- whis : float, sequence, or string (default = 1.5)
- As a float, determines the reach of the whiskers to the beyond the
- first and third quartiles. In other words, where IQR is the
- interquartile range (`Q3-Q1`), the upper whisker will extend to
- last datum less than `Q3 + whis*IQR`). Similarly, the lower whisker
- will extend to the first datum greater than `Q1 - whis*IQR`.
- Beyond the whiskers, data
- are considered outliers and are plotted as individual
- points. Set this to an unreasonably high value to force the
- whiskers to show the min and max values. Alternatively, set
- this to an ascending sequence of percentile (e.g., [5, 95])
- to set the whiskers at specific percentiles of the data.
- Finally, ``whis`` can be the string ``'range'`` to force the
- whiskers to the min and max of the data.
-
- bootstrap : int, optional
- Specifies whether to bootstrap the confidence intervals
- around the median for notched boxplots. If ``bootstrap`` is
- None, no bootstrapping is performed, and notches are
- calculated using a Gaussian-based asymptotic approximation
- (see McGill, R., Tukey, J.W., and Larsen, W.A., 1978, and
- Kendall and Stuart, 1967). Otherwise, bootstrap specifies
- the number of times to bootstrap the median to determine its
- 95% confidence intervals. Values between 1000 and 10000 are
- recommended.
-
- usermedians : array-like, optional
- An array or sequence whose first dimension (or length) is
- compatible with ``x``. This overrides the medians computed
- by matplotlib for each element of ``usermedians`` that is not
- `None`. When an element of ``usermedians`` is None, the median
- will be computed by matplotlib as normal.
-
- conf_intervals : array-like, optional
- Array or sequence whose first dimension (or length) is
- compatible with ``x`` and whose second dimension is 2. When
- the an element of ``conf_intervals`` is not None, the
- notch locations computed by matplotlib are overridden
- (provided ``notch`` is `True`). When an element of
- ``conf_intervals`` is `None`, the notches are computed by the
- method specified by the other kwargs (e.g., ``bootstrap``).
-
- positions : array-like, optional
- Sets the positions of the boxes. The ticks and limits are
- automatically set to match the positions. Defaults to
- `range(1, N+1)` where N is the number of boxes to be drawn.
-
- widths : scalar or array-like
- Sets the width of each box either with a scalar or a
- sequence. The default is 0.5, or ``0.15*(distance between
- extreme positions)``, if that is smaller.
-
- patch_artist : bool, optional (False)
- If `False` produces boxes with the Line2D artist. Otherwise,
- boxes and drawn with Patch artists.
-
- labels : sequence, optional
- Labels for each dataset. Length must be compatible with
- dimensions of ``x``.
-
- manage_xticks : bool, optional (True)
- If the function should adjust the xlim and xtick locations.
-
- autorange : bool, optional (False)
- When `True` and the data are distributed such that the 25th and
- 75th percentiles are equal, ``whis`` is set to ``'range'`` such
- that the whisker ends are at the minimum and maximum of the
- data.
-
- meanline : bool, optional (False)
- If `True` (and ``showmeans`` is `True`), will try to render
- the mean as a line spanning the full width of the box
- according to ``meanprops`` (see below). Not recommended if
- ``shownotches`` is also True. Otherwise, means will be shown
- as points.
-
- zorder : scalar, optional (None)
- Sets the zorder of the boxplot.
-
- Other Parameters
- ----------------
- showcaps : bool, optional (True)
- Show the caps on the ends of whiskers.
- showbox : bool, optional (True)
- Show the central box.
- showfliers : bool, optional (True)
- Show the outliers beyond the caps.
- showmeans : bool, optional (False)
- Show the arithmetic means.
- capprops : dict, optional (None)
- Specifies the style of the caps.
- boxprops : dict, optional (None)
- Specifies the style of the box.
- whiskerprops : dict, optional (None)
- Specifies the style of the whiskers.
- flierprops : dict, optional (None)
- Specifies the style of the fliers.
- medianprops : dict, optional (None)
- Specifies the style of the median.
- meanprops : dict, optional (None)
- Specifies the style of the mean.
-
- Returns
- -------
- result : dict
- A dictionary mapping each component of the boxplot to a list
- of the :class:`matplotlib.lines.Line2D` instances
- created. That dictionary has the following keys (assuming
- vertical boxplots):
-
- - ``boxes``: the main body of the boxplot showing the
- quartiles and the median's confidence intervals if
- enabled.
-
- - ``medians``: horizontal lines at the median of each box.
-
- - ``whiskers``: the vertical lines extending to the most
- extreme, non-outlier data points.
-
- - ``caps``: the horizontal lines at the ends of the
- whiskers.
-
- - ``fliers``: points representing data that extend beyond
- the whiskers (fliers).
-
- - ``means``: points or lines representing the means.
-
- Notes
- -----
- .. [Notes section required for data comment. See #10189.]
-
- """
-
- # If defined in matplotlibrc, apply the value from rc file
- # Overridden if argument is passed
- if whis is None:
- whis = rcParams['boxplot.whiskers']
- if bootstrap is None:
- bootstrap = rcParams['boxplot.bootstrap']
-
- bxpstats = cbook.boxplot_stats(x, whis=whis, bootstrap=bootstrap,
- labels=labels, autorange=autorange)
- if notch is None:
- notch = rcParams['boxplot.notch']
- if vert is None:
- vert = rcParams['boxplot.vertical']
- if patch_artist is None:
- patch_artist = rcParams['boxplot.patchartist']
- if meanline is None:
- meanline = rcParams['boxplot.meanline']
- if showmeans is None:
- showmeans = rcParams['boxplot.showmeans']
- if showcaps is None:
- showcaps = rcParams['boxplot.showcaps']
- if showbox is None:
- showbox = rcParams['boxplot.showbox']
- if showfliers is None:
- showfliers = rcParams['boxplot.showfliers']
-
- def _update_dict(dictionary, rc_name, properties):
- """ Loads properties in the dictionary from rc file if not already
- in the dictionary"""
- rc_str = 'boxplot.{0}.{1}'
- if dictionary is None:
- dictionary = dict()
- for prop_dict in properties:
- dictionary.setdefault(prop_dict,
- rcParams[rc_str.format(rc_name, prop_dict)])
- return dictionary
-
- # Common property dictionnaries loading from rc
- flier_props = ['color', 'marker', 'markerfacecolor', 'markeredgecolor',
- 'markersize', 'linestyle', 'linewidth']
- default_props = ['color', 'linewidth', 'linestyle']
-
- boxprops = _update_dict(boxprops, 'boxprops', default_props)
- whiskerprops = _update_dict(whiskerprops, 'whiskerprops',
- default_props)
- capprops = _update_dict(capprops, 'capprops', default_props)
- medianprops = _update_dict(medianprops, 'medianprops', default_props)
- meanprops = _update_dict(meanprops, 'meanprops', default_props)
- flierprops = _update_dict(flierprops, 'flierprops', flier_props)
-
- if patch_artist:
- boxprops['linestyle'] = 'solid'
- boxprops['edgecolor'] = boxprops.pop('color')
-
- # if non-default sym value, put it into the flier dictionary
- # the logic for providing the default symbol ('b+') now lives
- # in bxp in the initial value of final_flierprops
- # handle all of the `sym` related logic here so we only have to pass
- # on the flierprops dict.
- if sym is not None:
- # no-flier case, which should really be done with
- # 'showfliers=False' but none-the-less deal with it to keep back
- # compatibility
- if sym == '':
- # blow away existing dict and make one for invisible markers
- flierprops = dict(linestyle='none', marker='', color='none')
- # turn the fliers off just to be safe
- showfliers = False
- # now process the symbol string
- else:
- # process the symbol string
- # discarded linestyle
- _, marker, color = _process_plot_format(sym)
- # if we have a marker, use it
- if marker is not None:
- flierprops['marker'] = marker
- # if we have a color, use it
- if color is not None:
- # assume that if color is passed in the user want
- # filled symbol, if the users want more control use
- # flierprops
- flierprops['color'] = color
- flierprops['markerfacecolor'] = color
- flierprops['markeredgecolor'] = color
-
- # replace medians if necessary:
- if usermedians is not None:
- if (len(np.ravel(usermedians)) != len(bxpstats) or
- np.shape(usermedians)[0] != len(bxpstats)):
- raise ValueError('usermedians length not compatible with x')
- else:
- # reassign medians as necessary
- for stats, med in zip(bxpstats, usermedians):
- if med is not None:
- stats['med'] = med
-
- if conf_intervals is not None:
- if np.shape(conf_intervals)[0] != len(bxpstats):
- err_mess = 'conf_intervals length not compatible with x'
- raise ValueError(err_mess)
- else:
- for stats, ci in zip(bxpstats, conf_intervals):
- if ci is not None:
- if len(ci) != 2:
- raise ValueError('each confidence interval must '
- 'have two values')
- else:
- if ci[0] is not None:
- stats['cilo'] = ci[0]
- if ci[1] is not None:
- stats['cihi'] = ci[1]
-
- artists = self.bxp(bxpstats, positions=positions, widths=widths,
- vert=vert, patch_artist=patch_artist,
- shownotches=notch, showmeans=showmeans,
- showcaps=showcaps, showbox=showbox,
- boxprops=boxprops, flierprops=flierprops,
- medianprops=medianprops, meanprops=meanprops,
- meanline=meanline, showfliers=showfliers,
- capprops=capprops, whiskerprops=whiskerprops,
- manage_xticks=manage_xticks, zorder=zorder)
- return artists
-
- def bxp(self, bxpstats, positions=None, widths=None, vert=True,
- patch_artist=False, shownotches=False, showmeans=False,
- showcaps=True, showbox=True, showfliers=True,
- boxprops=None, whiskerprops=None, flierprops=None,
- medianprops=None, capprops=None, meanprops=None,
- meanline=False, manage_xticks=True, zorder=None):
- """
- Drawing function for box and whisker plots.
-
- Make a box and whisker plot for each column of *x* or each
- vector in sequence *x*. The box extends from the lower to
- upper quartile values of the data, with a line at the median.
- The whiskers extend from the box to show the range of the
- data. Flier points are those past the end of the whiskers.
-
- Parameters
- ----------
-
- bxpstats : list of dicts
- A list of dictionaries containing stats for each boxplot.
- Required keys are:
-
- - ``med``: The median (scalar float).
-
- - ``q1``: The first quartile (25th percentile) (scalar
- float).
-
- - ``q3``: The third quartile (75th percentile) (scalar
- float).
-
- - ``whislo``: Lower bound of the lower whisker (scalar
- float).
-
- - ``whishi``: Upper bound of the upper whisker (scalar
- float).
-
- Optional keys are:
-
- - ``mean``: The mean (scalar float). Needed if
- ``showmeans=True``.
-
- - ``fliers``: Data beyond the whiskers (sequence of floats).
- Needed if ``showfliers=True``.
-
- - ``cilo`` & ``cihi``: Lower and upper confidence intervals
- about the median. Needed if ``shownotches=True``.
-
- - ``label``: Name of the dataset (string). If available,
- this will be used a tick label for the boxplot
-
- positions : array-like, default = [1, 2, ..., n]
- Sets the positions of the boxes. The ticks and limits
- are automatically set to match the positions.
-
- widths : array-like, default = None
- Either a scalar or a vector and sets the width of each
- box. The default is ``0.15*(distance between extreme
- positions)``, clipped to no less than 0.15 and no more than
- 0.5.
-
- vert : bool, default = False
- If `True` (default), makes the boxes vertical. If `False`,
- makes horizontal boxes.
-
- patch_artist : bool, default = False
- If `False` produces boxes with the
- `~matplotlib.lines.Line2D` artist. If `True` produces boxes
- with the `~matplotlib.patches.Patch` artist.
-
- shownotches : bool, default = False
- If `False` (default), produces a rectangular box plot.
- If `True`, will produce a notched box plot
-
- showmeans : bool, default = False
- If `True`, will toggle on the rendering of the means
-
- showcaps : bool, default = True
- If `True`, will toggle on the rendering of the caps
-
- showbox : bool, default = True
- If `True`, will toggle on the rendering of the box
-
- showfliers : bool, default = True
- If `True`, will toggle on the rendering of the fliers
-
- boxprops : dict or None (default)
- If provided, will set the plotting style of the boxes
-
- whiskerprops : dict or None (default)
- If provided, will set the plotting style of the whiskers
-
- capprops : dict or None (default)
- If provided, will set the plotting style of the caps
-
- flierprops : dict or None (default)
- If provided will set the plotting style of the fliers
-
- medianprops : dict or None (default)
- If provided, will set the plotting style of the medians
-
- meanprops : dict or None (default)
- If provided, will set the plotting style of the means
-
- meanline : bool, default = False
- If `True` (and *showmeans* is `True`), will try to render the mean
- as a line spanning the full width of the box according to
- *meanprops*. Not recommended if *shownotches* is also True.
- Otherwise, means will be shown as points.
-
- manage_xticks : bool, default = True
- If the function should adjust the xlim and xtick locations.
-
- zorder : scalar, default = None
- The zorder of the resulting boxplot
-
- Returns
- -------
- result : dict
- A dictionary mapping each component of the boxplot to a list
- of the :class:`matplotlib.lines.Line2D` instances
- created. That dictionary has the following keys (assuming
- vertical boxplots):
-
- - ``boxes``: the main body of the boxplot showing the
- quartiles and the median's confidence intervals if
- enabled.
-
- - ``medians``: horizontal lines at the median of each box.
-
- - ``whiskers``: the vertical lines extending to the most
- extreme, non-outlier data points.
-
- - ``caps``: the horizontal lines at the ends of the
- whiskers.
-
- - ``fliers``: points representing data that extend beyond
- the whiskers (fliers).
-
- - ``means``: points or lines representing the means.
-
- Examples
- --------
-
- .. plot:: gallery/statistics/bxp.py
-
- """
- # lists of artists to be output
- whiskers = []
- caps = []
- boxes = []
- medians = []
- means = []
- fliers = []
-
- # empty list of xticklabels
- datalabels = []
-
- # Use default zorder if none specified
- if zorder is None:
- zorder = mlines.Line2D.zorder
-
- zdelta = 0.1
- # box properties
- if patch_artist:
- final_boxprops = dict(
- linestyle=rcParams['boxplot.boxprops.linestyle'],
- edgecolor=rcParams['boxplot.boxprops.color'],
- facecolor=rcParams['patch.facecolor'],
- linewidth=rcParams['boxplot.boxprops.linewidth']
- )
- if rcParams['_internal.classic_mode']:
- final_boxprops['facecolor'] = 'white'
- else:
- final_boxprops = dict(
- linestyle=rcParams['boxplot.boxprops.linestyle'],
- color=rcParams['boxplot.boxprops.color'],
- )
-
- final_boxprops['zorder'] = zorder
- if boxprops is not None:
- final_boxprops.update(boxprops)
-
- # other (cap, whisker) properties
- final_whiskerprops = dict(
- linestyle=rcParams['boxplot.whiskerprops.linestyle'],
- linewidth=rcParams['boxplot.whiskerprops.linewidth'],
- color=rcParams['boxplot.whiskerprops.color'],
- )
-
- final_capprops = dict(
- linestyle=rcParams['boxplot.capprops.linestyle'],
- linewidth=rcParams['boxplot.capprops.linewidth'],
- color=rcParams['boxplot.capprops.color'],
- )
-
- final_capprops['zorder'] = zorder
- if capprops is not None:
- final_capprops.update(capprops)
-
- final_whiskerprops['zorder'] = zorder
- if whiskerprops is not None:
- final_whiskerprops.update(whiskerprops)
-
- # set up the default flier properties
- final_flierprops = dict(
- linestyle=rcParams['boxplot.flierprops.linestyle'],
- linewidth=rcParams['boxplot.flierprops.linewidth'],
- color=rcParams['boxplot.flierprops.color'],
- marker=rcParams['boxplot.flierprops.marker'],
- markerfacecolor=rcParams['boxplot.flierprops.markerfacecolor'],
- markeredgecolor=rcParams['boxplot.flierprops.markeredgecolor'],
- markersize=rcParams['boxplot.flierprops.markersize'],
- )
-
- final_flierprops['zorder'] = zorder
- # flier (outlier) properties
- if flierprops is not None:
- final_flierprops.update(flierprops)
-
- # median line properties
- final_medianprops = dict(
- linestyle=rcParams['boxplot.medianprops.linestyle'],
- linewidth=rcParams['boxplot.medianprops.linewidth'],
- color=rcParams['boxplot.medianprops.color'],
- )
- final_medianprops['zorder'] = zorder + zdelta
- if medianprops is not None:
- final_medianprops.update(medianprops)
-
- # mean (line or point) properties
- if meanline:
- final_meanprops = dict(
- linestyle=rcParams['boxplot.meanprops.linestyle'],
- linewidth=rcParams['boxplot.meanprops.linewidth'],
- color=rcParams['boxplot.meanprops.color'],
- )
- else:
- final_meanprops = dict(
- linestyle='',
- marker=rcParams['boxplot.meanprops.marker'],
- markerfacecolor=rcParams['boxplot.meanprops.markerfacecolor'],
- markeredgecolor=rcParams['boxplot.meanprops.markeredgecolor'],
- markersize=rcParams['boxplot.meanprops.markersize'],
- )
- final_meanprops['zorder'] = zorder + zdelta
- if meanprops is not None:
- final_meanprops.update(meanprops)
-
- def to_vc(xs, ys):
- # convert arguments to verts and codes, append (0, 0) (ignored).
- verts = np.append(np.column_stack([xs, ys]), [(0, 0)], 0)
- codes = ([mpath.Path.MOVETO]
- + [mpath.Path.LINETO] * (len(verts) - 2)
- + [mpath.Path.CLOSEPOLY])
- return verts, codes
-
- def patch_list(xs, ys, **kwargs):
- verts, codes = to_vc(xs, ys)
- path = mpath.Path(verts, codes)
- patch = mpatches.PathPatch(path, **kwargs)
- self.add_artist(patch)
- return [patch]
-
- # vertical or horizontal plot?
- if vert:
- def doplot(*args, **kwargs):
- return self.plot(*args, **kwargs)
-
- def dopatch(xs, ys, **kwargs):
- return patch_list(xs, ys, **kwargs)
-
- else:
- def doplot(*args, **kwargs):
- shuffled = []
- for i in xrange(0, len(args), 2):
- shuffled.extend([args[i + 1], args[i]])
- return self.plot(*shuffled, **kwargs)
-
- def dopatch(xs, ys, **kwargs):
- xs, ys = ys, xs # flip X, Y
- return patch_list(xs, ys, **kwargs)
-
- # input validation
- N = len(bxpstats)
- datashape_message = ("List of boxplot statistics and `{0}` "
- "values must have same the length")
- # check position
- if positions is None:
- positions = list(xrange(1, N + 1))
- elif len(positions) != N:
- raise ValueError(datashape_message.format("positions"))
-
- # width
- if widths is None:
- widths = [np.clip(0.15 * np.ptp(positions), 0.15, 0.5)] * N
- elif np.isscalar(widths):
- widths = [widths] * N
- elif len(widths) != N:
- raise ValueError(datashape_message.format("widths"))
-
- # check and save the `hold` state of the current axes
- if not self._hold:
- self.cla()
- holdStatus = self._hold
- for pos, width, stats in zip(positions, widths, bxpstats):
- # try to find a new label
- datalabels.append(stats.get('label', pos))
-
- # whisker coords
- whisker_x = np.ones(2) * pos
- whiskerlo_y = np.array([stats['q1'], stats['whislo']])
- whiskerhi_y = np.array([stats['q3'], stats['whishi']])
-
- # cap coords
- cap_left = pos - width * 0.25
- cap_right = pos + width * 0.25
- cap_x = np.array([cap_left, cap_right])
- cap_lo = np.ones(2) * stats['whislo']
- cap_hi = np.ones(2) * stats['whishi']
-
- # box and median coords
- box_left = pos - width * 0.5
- box_right = pos + width * 0.5
- med_y = [stats['med'], stats['med']]
-
- # notched boxes
- if shownotches:
- box_x = [box_left, box_right, box_right, cap_right, box_right,
- box_right, box_left, box_left, cap_left, box_left,
- box_left]
- box_y = [stats['q1'], stats['q1'], stats['cilo'],
- stats['med'], stats['cihi'], stats['q3'],
- stats['q3'], stats['cihi'], stats['med'],
- stats['cilo'], stats['q1']]
- med_x = cap_x
-
- # plain boxes
- else:
- box_x = [box_left, box_right, box_right, box_left, box_left]
- box_y = [stats['q1'], stats['q1'], stats['q3'], stats['q3'],
- stats['q1']]
- med_x = [box_left, box_right]
-
- # maybe draw the box:
- if showbox:
- if patch_artist:
- boxes.extend(dopatch(box_x, box_y, **final_boxprops))
- else:
- boxes.extend(doplot(box_x, box_y, **final_boxprops))
-
- # draw the whiskers
- whiskers.extend(doplot(
- whisker_x, whiskerlo_y, **final_whiskerprops
- ))
- whiskers.extend(doplot(
- whisker_x, whiskerhi_y, **final_whiskerprops
- ))
-
- # maybe draw the caps:
- if showcaps:
- caps.extend(doplot(cap_x, cap_lo, **final_capprops))
- caps.extend(doplot(cap_x, cap_hi, **final_capprops))
-
- # draw the medians
- medians.extend(doplot(med_x, med_y, **final_medianprops))
-
- # maybe draw the means
- if showmeans:
- if meanline:
- means.extend(doplot(
- [box_left, box_right], [stats['mean'], stats['mean']],
- **final_meanprops
- ))
- else:
- means.extend(doplot(
- [pos], [stats['mean']], **final_meanprops
- ))
-
- # maybe draw the fliers
- if showfliers:
- # fliers coords
- flier_x = np.ones(len(stats['fliers'])) * pos
- flier_y = stats['fliers']
-
- fliers.extend(doplot(
- flier_x, flier_y, **final_flierprops
- ))
-
- # fix our axes/ticks up a little
- if vert:
- setticks = self.set_xticks
- setlim = self.set_xlim
- setlabels = self.set_xticklabels
- else:
- setticks = self.set_yticks
- setlim = self.set_ylim
- setlabels = self.set_yticklabels
-
- if manage_xticks:
- newlimits = min(positions) - 0.5, max(positions) + 0.5
- setlim(newlimits)
- setticks(positions)
- setlabels(datalabels)
-
- # reset hold status
- self._hold = holdStatus
-
- return dict(whiskers=whiskers, caps=caps, boxes=boxes,
- medians=medians, fliers=fliers, means=means)
-
- @_preprocess_data(replace_names=["x", "y", "s", "linewidths",
- "edgecolors", "c", "facecolor",
- "facecolors", "color"],
- label_namer="y")
- def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
- vmin=None, vmax=None, alpha=None, linewidths=None,
- verts=None, edgecolors=None,
- **kwargs):
- """
- A scatter plot of *y* vs *x* with varying marker size and/or color.
-
- Parameters
- ----------
- x, y : array_like, shape (n, )
- The data positions.
-
- s : scalar or array_like, shape (n, ), optional
- The marker size in points**2.
- Default is ``rcParams['lines.markersize'] ** 2``.
-
- c : color, sequence, or sequence of color, optional, default: 'b'
- The marker color. Possible values:
-
- - A single color format string.
- - A sequence of color specifications of length n.
- - A sequence of n numbers to be mapped to colors using *cmap* and
- *norm*.
- - A 2-D array in which the rows are RGB or RGBA.
-
- Note that *c* should not be a single numeric RGB or RGBA sequence
- because that is indistinguishable from an array of values to be
- colormapped. If you want to specify the same RGB or RGBA value for
- all points, use a 2-D array with a single row.
-
- marker : `~matplotlib.markers.MarkerStyle`, optional, default: 'o'
- The marker style. *marker* can be either an instance of the class
- or the text shorthand for a particular marker.
- See `~matplotlib.markers` for more information marker styles.
-
- cmap : `~matplotlib.colors.Colormap`, optional, default: None
- A `.Colormap` instance or registered colormap name. *cmap* is only
- used if *c* is an array of floats. If ``None``, defaults to rc
- ``image.cmap``.
-
- norm : `~matplotlib.colors.Normalize`, optional, default: None
- A `.Normalize` instance is used to scale luminance data to 0, 1.
- *norm* is only used if *c* is an array of floats. If *None*, use
- the default `.colors.Normalize`.
-
- vmin, vmax : scalar, optional, default: None
- *vmin* and *vmax* are used in conjunction with *norm* to normalize
- luminance data. If None, the respective min and max of the color
- array is used. *vmin* and *vmax* are ignored if you pass a *norm*
- instance.
-
- alpha : scalar, optional, default: None
- The alpha blending value, between 0 (transparent) and 1 (opaque).
-
- linewidths : scalar or array_like, optional, default: None
- The linewidth of the marker edges. Note: The default *edgecolors*
- is 'face'. You may want to change this as well.
- If *None*, defaults to rcParams ``lines.linewidth``.
-
- verts : sequence of (x, y), optional
- If *marker* is *None*, these vertices will be used to construct
- the marker. The center of the marker is located at (0, 0) in
- normalized units. The overall marker is rescaled by *s*.
-
- edgecolors : color or sequence of color, optional, default: 'face'
- The edge color of the marker. Possible values:
-
- - 'face': The edge color will always be the same as the face color.
- - 'none': No patch boundary will be drawn.
- - A matplotib color.
-
- For non-filled markers, the *edgecolors* kwarg is ignored and
- forced to 'face' internally.
-
- Returns
- -------
- paths : `~matplotlib.collections.PathCollection`
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.collections.Collection` properties
-
- See Also
- --------
- plot : To plot scatter plots when markers are identical in size and
- color.
-
- Notes
- -----
-
- * The `.plot` function will be faster for scatterplots where markers
- don't vary in size or color.
-
- * Any or all of *x*, *y*, *s*, and *c* may be masked arrays, in which
- case all masks will be combined and only unmasked points will be
- plotted.
-
- * Fundamentally, scatter works with 1-D arrays; *x*, *y*, *s*, and *c*
- may be input as 2-D arrays, but within scatter they will be
- flattened. The exception is *c*, which will be flattened only if its
- size matches the size of *x* and *y*.
-
- """
-
- if not self._hold:
- self.cla()
-
- # Process **kwargs to handle aliases, conflicts with explicit kwargs:
-
- facecolors = None
- edgecolors = kwargs.pop('edgecolor', edgecolors)
- fc = kwargs.pop('facecolors', None)
- fc = kwargs.pop('facecolor', fc)
- if fc is not None:
- facecolors = fc
- co = kwargs.pop('color', None)
- if co is not None:
- try:
- mcolors.to_rgba_array(co)
- except ValueError:
- raise ValueError("'color' kwarg must be an mpl color"
- " spec or sequence of color specs.\n"
- "For a sequence of values to be"
- " color-mapped, use the 'c' kwarg instead.")
- if edgecolors is None:
- edgecolors = co
- if facecolors is None:
- facecolors = co
- if c is not None:
- raise ValueError("Supply a 'c' kwarg or a 'color' kwarg"
- " but not both; they differ but"
- " their functionalities overlap.")
- if c is None:
- if facecolors is not None:
- c = facecolors
- else:
- if rcParams['_internal.classic_mode']:
- c = 'b' # The original default
- else:
- c = self._get_patches_for_fill.get_next_color()
- c_none = True
- else:
- c_none = False
-
- if edgecolors is None and not rcParams['_internal.classic_mode']:
- edgecolors = 'face'
-
- self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs)
- x = self.convert_xunits(x)
- y = self.convert_yunits(y)
-
- # np.ma.ravel yields an ndarray, not a masked array,
- # unless its argument is a masked array.
- xy_shape = (np.shape(x), np.shape(y))
- x = np.ma.ravel(x)
- y = np.ma.ravel(y)
- if x.size != y.size:
- raise ValueError("x and y must be the same size")
-
- if s is None:
- if rcParams['_internal.classic_mode']:
- s = 20
- else:
- s = rcParams['lines.markersize'] ** 2.0
-
- s = np.ma.ravel(s) # This doesn't have to match x, y in size.
-
- # After this block, c_array will be None unless
- # c is an array for mapping. The potential ambiguity
- # with a sequence of 3 or 4 numbers is resolved in
- # favor of mapping, not rgb or rgba.
- if c_none or co is not None:
- c_array = None
- else:
- try:
- c_array = np.asanyarray(c, dtype=float)
- if c_array.shape in xy_shape:
- c = np.ma.ravel(c_array)
- else:
- # Wrong size; it must not be intended for mapping.
- c_array = None
- except ValueError:
- # Failed to make a floating-point array; c must be color specs.
- c_array = None
-
- if c_array is None:
- try:
- # must be acceptable as PathCollection facecolors
- colors = mcolors.to_rgba_array(c)
- except ValueError:
- # c not acceptable as PathCollection facecolor
- raise ValueError("c of shape {} not acceptable as a color "
- "sequence for x with size {}, y with size {}"
- .format(c.shape, x.size, y.size))
- else:
- colors = None # use cmap, norm after collection is created
-
- # `delete_masked_points` only modifies arguments of the same length as
- # `x`.
- x, y, s, c, colors, edgecolors, linewidths =\
- cbook.delete_masked_points(
- x, y, s, c, colors, edgecolors, linewidths)
-
- scales = s # Renamed for readability below.
-
- # to be API compatible
- if marker is None and verts is not None:
- marker = (verts, 0)
- verts = None
-
- # load default marker from rcParams
- if marker is None:
- marker = rcParams['scatter.marker']
-
- if isinstance(marker, mmarkers.MarkerStyle):
- marker_obj = marker
- else:
- marker_obj = mmarkers.MarkerStyle(marker)
-
- path = marker_obj.get_path().transformed(
- marker_obj.get_transform())
- if not marker_obj.is_filled():
- edgecolors = 'face'
- linewidths = rcParams['lines.linewidth']
-
- offsets = np.column_stack([x, y])
-
- collection = mcoll.PathCollection(
- (path,), scales,
- facecolors=colors,
- edgecolors=edgecolors,
- linewidths=linewidths,
- offsets=offsets,
- transOffset=kwargs.pop('transform', self.transData),
- alpha=alpha
- )
- collection.set_transform(mtransforms.IdentityTransform())
- collection.update(kwargs)
-
- if colors is None:
- if norm is not None and not isinstance(norm, mcolors.Normalize):
- raise ValueError(
- "'norm' must be an instance of 'mcolors.Normalize'")
- collection.set_array(np.asarray(c))
- collection.set_cmap(cmap)
- collection.set_norm(norm)
-
- if vmin is not None or vmax is not None:
- collection.set_clim(vmin, vmax)
- else:
- collection.autoscale_None()
-
- # Classic mode only:
- # ensure there are margins to allow for the
- # finite size of the symbols. In v2.x, margins
- # are present by default, so we disable this
- # scatter-specific override.
- if rcParams['_internal.classic_mode']:
- if self._xmargin < 0.05 and x.size > 0:
- self.set_xmargin(0.05)
- if self._ymargin < 0.05 and x.size > 0:
- self.set_ymargin(0.05)
-
- self.add_collection(collection)
- self.autoscale_view()
-
- return collection
-
- @_preprocess_data(replace_names=["x", "y"], label_namer="y")
- @docstring.dedent_interpd
- def hexbin(self, x, y, C=None, gridsize=100, bins=None,
- xscale='linear', yscale='linear', extent=None,
- cmap=None, norm=None, vmin=None, vmax=None,
- alpha=None, linewidths=None, edgecolors='face',
- reduce_C_function=np.mean, mincnt=None, marginals=False,
- **kwargs):
- """
- Make a hexagonal binning plot.
-
- Make a hexagonal binning plot of *x* versus *y*, where *x*,
- *y* are 1-D sequences of the same length, *N*. If *C* is *None*
- (the default), this is a histogram of the number of occurrences
- of the observations at (x[i],y[i]).
-
- If *C* is specified, it specifies values at the coordinate
- (x[i],y[i]). These values are accumulated for each hexagonal
- bin and then reduced according to *reduce_C_function*, which
- defaults to numpy's mean function (np.mean). (If *C* is
- specified, it must also be a 1-D sequence of the same length
- as *x* and *y*.)
-
- Parameters
- ----------
- x, y : array or masked array
-
- C : array or masked array, optional, default is *None*
-
- gridsize : int or (int, int), optional, default is 100
- The number of hexagons in the *x*-direction, default is
- 100. The corresponding number of hexagons in the
- *y*-direction is chosen such that the hexagons are
- approximately regular. Alternatively, gridsize can be a
- tuple with two elements specifying the number of hexagons
- in the *x*-direction and the *y*-direction.
-
- bins : {'log'} or int or sequence, optional, default is *None*
- If *None*, no binning is applied; the color of each hexagon
- directly corresponds to its count value.
-
- If 'log', use a logarithmic scale for the color
- map. Internally, :math:`log_{10}(i+1)` is used to
- determine the hexagon color.
-
- If an integer, divide the counts in the specified number
- of bins, and color the hexagons accordingly.
-
- If a sequence of values, the values of the lower bound of
- the bins to be used.
-
- xscale : {'linear', 'log'}, optional, default is 'linear'
- Use a linear or log10 scale on the horizontal axis.
-
- yscale : {'linear', 'log'}, optional, default is 'linear'
- Use a linear or log10 scale on the vertical axis.
-
- mincnt : int > 0, optional, default is *None*
- If not *None*, only display cells with more than *mincnt*
- number of points in the cell
-
- marginals : bool, optional, default is *False*
- if marginals is *True*, plot the marginal density as
- colormapped rectagles along the bottom of the x-axis and
- left of the y-axis
-
- extent : scalar, optional, default is *None*
- The limits of the bins. The default assigns the limits
- based on *gridsize*, *x*, *y*, *xscale* and *yscale*.
-
- If *xscale* or *yscale* is set to 'log', the limits are
- expected to be the exponent for a power of 10. E.g. for
- x-limits of 1 and 50 in 'linear' scale and y-limits
- of 10 and 1000 in 'log' scale, enter (1, 50, 1, 3).
-
- Order of scalars is (left, right, bottom, top).
-
- Other Parameters
- ----------------
- cmap : object, optional, default is *None*
- a :class:`matplotlib.colors.Colormap` instance. If *None*,
- defaults to rc ``image.cmap``.
-
- norm : object, optional, default is *None*
- :class:`matplotlib.colors.Normalize` instance is used to
- scale luminance data to 0,1.
-
- vmin, vmax : scalar, optional, default is *None*
- *vmin* and *vmax* are used in conjunction with *norm* to
- normalize luminance data. If *None*, the min and max of the
- color array *C* are used. Note if you pass a norm instance
- your settings for *vmin* and *vmax* will be ignored.
-
- alpha : scalar between 0 and 1, optional, default is *None*
- the alpha value for the patches
-
- linewidths : scalar, optional, default is *None*
- If *None*, defaults to 1.0.
-
- edgecolors : {'face', 'none', *None*} or color, optional
-
- If 'face' (the default), draws the edges in the same color as the
- fill color.
-
- If 'none', no edge is drawn; this can sometimes lead to unsightly
- unpainted pixels between the hexagons.
-
- If *None*, draws outlines in the default color.
-
- If a matplotlib color arg, draws outlines in the specified color.
-
- Returns
- -------
- object
- a :class:`~matplotlib.collections.PolyCollection` instance; use
- :meth:`~matplotlib.collections.PolyCollection.get_array` on
- this :class:`~matplotlib.collections.PolyCollection` to get
- the counts in each hexagon.
-
- If *marginals* is *True*, horizontal
- bar and vertical bar (both PolyCollections) will be attached
- to the return collection as attributes *hbar* and *vbar*.
-
- Notes
- -----
- The standard descriptions of all the
- :class:`~matplotlib.collections.Collection` parameters:
-
- %(Collection)s
-
- """
-
- if not self._hold:
- self.cla()
-
- self._process_unit_info(xdata=x, ydata=y, kwargs=kwargs)
-
- x, y, C = cbook.delete_masked_points(x, y, C)
-
- # Set the size of the hexagon grid
- if iterable(gridsize):
- nx, ny = gridsize
- else:
- nx = gridsize
- ny = int(nx / math.sqrt(3))
- # Count the number of data in each hexagon
- x = np.array(x, float)
- y = np.array(y, float)
- if xscale == 'log':
- if np.any(x <= 0.0):
- raise ValueError("x contains non-positive values, so can not"
- " be log-scaled")
- x = np.log10(x)
- if yscale == 'log':
- if np.any(y <= 0.0):
- raise ValueError("y contains non-positive values, so can not"
- " be log-scaled")
- y = np.log10(y)
- if extent is not None:
- xmin, xmax, ymin, ymax = extent
- else:
- xmin, xmax = (np.min(x), np.max(x)) if len(x) else (0, 1)
- ymin, ymax = (np.min(y), np.max(y)) if len(y) else (0, 1)
-
- # to avoid issues with singular data, expand the min/max pairs
- xmin, xmax = mtransforms.nonsingular(xmin, xmax, expander=0.1)
- ymin, ymax = mtransforms.nonsingular(ymin, ymax, expander=0.1)
-
- # In the x-direction, the hexagons exactly cover the region from
- # xmin to xmax. Need some padding to avoid roundoff errors.
- padding = 1.e-9 * (xmax - xmin)
- xmin -= padding
- xmax += padding
- sx = (xmax - xmin) / nx
- sy = (ymax - ymin) / ny
-
- if marginals:
- xorig = x.copy()
- yorig = y.copy()
-
- x = (x - xmin) / sx
- y = (y - ymin) / sy
- ix1 = np.round(x).astype(int)
- iy1 = np.round(y).astype(int)
- ix2 = np.floor(x).astype(int)
- iy2 = np.floor(y).astype(int)
-
- nx1 = nx + 1
- ny1 = ny + 1
- nx2 = nx
- ny2 = ny
- n = nx1 * ny1 + nx2 * ny2
-
- d1 = (x - ix1) ** 2 + 3.0 * (y - iy1) ** 2
- d2 = (x - ix2 - 0.5) ** 2 + 3.0 * (y - iy2 - 0.5) ** 2
- bdist = (d1 < d2)
- if C is None:
- lattice1 = np.zeros((nx1, ny1))
- lattice2 = np.zeros((nx2, ny2))
-
- cond1 = (0 <= ix1) * (ix1 < nx1) * (0 <= iy1) * (iy1 < ny1)
- cond2 = (0 <= ix2) * (ix2 < nx2) * (0 <= iy2) * (iy2 < ny2)
-
- cond1 *= bdist
- cond2 *= np.logical_not(bdist)
- ix1, iy1 = ix1[cond1], iy1[cond1]
- ix2, iy2 = ix2[cond2], iy2[cond2]
-
- for ix, iy in zip(ix1, iy1):
- lattice1[ix, iy] += 1
- for ix, iy in zip(ix2, iy2):
- lattice2[ix, iy] += 1
-
- # threshold
- if mincnt is not None:
- lattice1[lattice1 < mincnt] = np.nan
- lattice2[lattice2 < mincnt] = np.nan
- accum = np.hstack((lattice1.ravel(),
- lattice2.ravel()))
- good_idxs = ~np.isnan(accum)
-
- else:
- if mincnt is None:
- mincnt = 0
-
- # create accumulation arrays
- lattice1 = np.empty((nx1, ny1), dtype=object)
- for i in xrange(nx1):
- for j in xrange(ny1):
- lattice1[i, j] = []
- lattice2 = np.empty((nx2, ny2), dtype=object)
- for i in xrange(nx2):
- for j in xrange(ny2):
- lattice2[i, j] = []
-
- for i in xrange(len(x)):
- if bdist[i]:
- if 0 <= ix1[i] < nx1 and 0 <= iy1[i] < ny1:
- lattice1[ix1[i], iy1[i]].append(C[i])
- else:
- if 0 <= ix2[i] < nx2 and 0 <= iy2[i] < ny2:
- lattice2[ix2[i], iy2[i]].append(C[i])
-
- for i in xrange(nx1):
- for j in xrange(ny1):
- vals = lattice1[i, j]
- if len(vals) > mincnt:
- lattice1[i, j] = reduce_C_function(vals)
- else:
- lattice1[i, j] = np.nan
- for i in xrange(nx2):
- for j in xrange(ny2):
- vals = lattice2[i, j]
- if len(vals) > mincnt:
- lattice2[i, j] = reduce_C_function(vals)
- else:
- lattice2[i, j] = np.nan
-
- accum = np.hstack((lattice1.astype(float).ravel(),
- lattice2.astype(float).ravel()))
- good_idxs = ~np.isnan(accum)
-
- offsets = np.zeros((n, 2), float)
- offsets[:nx1 * ny1, 0] = np.repeat(np.arange(nx1), ny1)
- offsets[:nx1 * ny1, 1] = np.tile(np.arange(ny1), nx1)
- offsets[nx1 * ny1:, 0] = np.repeat(np.arange(nx2) + 0.5, ny2)
- offsets[nx1 * ny1:, 1] = np.tile(np.arange(ny2), nx2) + 0.5
- offsets[:, 0] *= sx
- offsets[:, 1] *= sy
- offsets[:, 0] += xmin
- offsets[:, 1] += ymin
- # remove accumulation bins with no data
- offsets = offsets[good_idxs, :]
- accum = accum[good_idxs]
-
- polygon = np.zeros((6, 2), float)
- polygon[:, 0] = sx * np.array([0.5, 0.5, 0.0, -0.5, -0.5, 0.0])
- polygon[:, 1] = sy * np.array([-0.5, 0.5, 1.0, 0.5, -0.5, -1.0]) / 3.0
-
- if linewidths is None:
- linewidths = [1.0]
-
- if xscale == 'log' or yscale == 'log':
- polygons = np.expand_dims(polygon, 0) + np.expand_dims(offsets, 1)
- if xscale == 'log':
- polygons[:, :, 0] = 10.0 ** polygons[:, :, 0]
- xmin = 10.0 ** xmin
- xmax = 10.0 ** xmax
- self.set_xscale(xscale)
- if yscale == 'log':
- polygons[:, :, 1] = 10.0 ** polygons[:, :, 1]
- ymin = 10.0 ** ymin
- ymax = 10.0 ** ymax
- self.set_yscale(yscale)
- collection = mcoll.PolyCollection(
- polygons,
- edgecolors=edgecolors,
- linewidths=linewidths,
- )
- else:
- collection = mcoll.PolyCollection(
- [polygon],
- edgecolors=edgecolors,
- linewidths=linewidths,
- offsets=offsets,
- transOffset=mtransforms.IdentityTransform(),
- offset_position="data"
- )
-
- if isinstance(norm, mcolors.LogNorm):
- if (accum == 0).any():
- # make sure we have not zeros
- accum += 1
-
- # autoscale the norm with curren accum values if it hasn't
- # been set
- if norm is not None:
- if norm.vmin is None and norm.vmax is None:
- norm.autoscale(accum)
-
- # Transform accum if needed
- if bins == 'log':
- accum = np.log10(accum + 1)
- elif bins is not None:
- if not iterable(bins):
- minimum, maximum = min(accum), max(accum)
- bins -= 1 # one less edge than bins
- bins = minimum + (maximum - minimum) * np.arange(bins) / bins
- bins = np.sort(bins)
- accum = bins.searchsorted(accum)
-
- if norm is not None and not isinstance(norm, mcolors.Normalize):
- raise ValueError(
- "'norm' must be an instance of 'mcolors.Normalize'")
- collection.set_array(accum)
- collection.set_cmap(cmap)
- collection.set_norm(norm)
- collection.set_alpha(alpha)
- collection.update(kwargs)
-
- if vmin is not None or vmax is not None:
- collection.set_clim(vmin, vmax)
- else:
- collection.autoscale_None()
-
- corners = ((xmin, ymin), (xmax, ymax))
- self.update_datalim(corners)
- collection.sticky_edges.x[:] = [xmin, xmax]
- collection.sticky_edges.y[:] = [ymin, ymax]
- self.autoscale_view(tight=True)
-
- # add the collection last
- self.add_collection(collection, autolim=False)
- if not marginals:
- return collection
-
- if C is None:
- C = np.ones(len(x))
-
- def coarse_bin(x, y, coarse):
- ind = coarse.searchsorted(x).clip(0, len(coarse) - 1)
- mus = np.zeros(len(coarse))
- for i in range(len(coarse)):
- yi = y[ind == i]
- if len(yi) > 0:
- mu = reduce_C_function(yi)
- else:
- mu = np.nan
- mus[i] = mu
- return mus
-
- coarse = np.linspace(xmin, xmax, gridsize)
-
- xcoarse = coarse_bin(xorig, C, coarse)
- valid = ~np.isnan(xcoarse)
- verts, values = [], []
- for i, val in enumerate(xcoarse):
- thismin = coarse[i]
- if i < len(coarse) - 1:
- thismax = coarse[i + 1]
- else:
- thismax = thismin + np.diff(coarse)[-1]
-
- if not valid[i]:
- continue
-
- verts.append([(thismin, 0),
- (thismin, 0.05),
- (thismax, 0.05),
- (thismax, 0)])
- values.append(val)
-
- values = np.array(values)
- trans = self.get_xaxis_transform(which='grid')
-
- hbar = mcoll.PolyCollection(verts, transform=trans, edgecolors='face')
-
- hbar.set_array(values)
- hbar.set_cmap(cmap)
- hbar.set_norm(norm)
- hbar.set_alpha(alpha)
- hbar.update(kwargs)
- self.add_collection(hbar, autolim=False)
-
- coarse = np.linspace(ymin, ymax, gridsize)
- ycoarse = coarse_bin(yorig, C, coarse)
- valid = ~np.isnan(ycoarse)
- verts, values = [], []
- for i, val in enumerate(ycoarse):
- thismin = coarse[i]
- if i < len(coarse) - 1:
- thismax = coarse[i + 1]
- else:
- thismax = thismin + np.diff(coarse)[-1]
- if not valid[i]:
- continue
- verts.append([(0, thismin), (0.0, thismax),
- (0.05, thismax), (0.05, thismin)])
- values.append(val)
-
- values = np.array(values)
-
- trans = self.get_yaxis_transform(which='grid')
-
- vbar = mcoll.PolyCollection(verts, transform=trans, edgecolors='face')
- vbar.set_array(values)
- vbar.set_cmap(cmap)
- vbar.set_norm(norm)
- vbar.set_alpha(alpha)
- vbar.update(kwargs)
- self.add_collection(vbar, autolim=False)
-
- collection.hbar = hbar
- collection.vbar = vbar
-
- def on_changed(collection):
- hbar.set_cmap(collection.get_cmap())
- hbar.set_clim(collection.get_clim())
- vbar.set_cmap(collection.get_cmap())
- vbar.set_clim(collection.get_clim())
-
- collection.callbacksSM.connect('changed', on_changed)
-
- return collection
-
- @docstring.dedent_interpd
- def arrow(self, x, y, dx, dy, **kwargs):
- """
- Add an arrow to the axes.
-
- This draws an arrow from ``(x, y)`` to ``(x+dx, y+dy)``.
-
- Parameters
- ----------
- x, y : float
- The x/y-coordinate of the arrow base.
- dx, dy : float
- The length of the arrow along x/y-direction.
-
- Returns
- -------
- arrow : `.FancyArrow`
- The created `.FancyArrow` object.
-
- Other Parameters
- ----------------
- **kwargs
- Optional kwargs (inherited from `.FancyArrow` patch) control the
- arrow construction and properties:
-
- %(FancyArrow)s
-
- Notes
- -----
- The resulting arrow is affected by the axes aspect ratio and limits.
- This may produce an arrow whose head is not square with its stem. To
- create an arrow whose head is square with its stem,
- use :meth:`annotate` for example:
-
- >>> ax.annotate("", xy=(0.5, 0.5), xytext=(0, 0),
- ... arrowprops=dict(arrowstyle="->"))
-
- """
- # Strip away units for the underlying patch since units
- # do not make sense to most patch-like code
- x = self.convert_xunits(x)
- y = self.convert_yunits(y)
- dx = self.convert_xunits(dx)
- dy = self.convert_yunits(dy)
-
- a = mpatches.FancyArrow(x, y, dx, dy, **kwargs)
- self.add_artist(a)
- return a
-
- def quiverkey(self, *args, **kw):
- qk = mquiver.QuiverKey(*args, **kw)
- self.add_artist(qk)
- return qk
- quiverkey.__doc__ = mquiver.QuiverKey.quiverkey_doc
-
- # Handle units for x and y, if they've been passed
- def _quiver_units(self, args, kw):
- if len(args) > 3:
- x, y = args[0:2]
- self._process_unit_info(xdata=x, ydata=y, kwargs=kw)
- x = self.convert_xunits(x)
- y = self.convert_yunits(y)
- return (x, y) + args[2:]
- return args
-
- # args can by a combination if X, Y, U, V, C and all should be replaced
- @_preprocess_data(replace_all_args=True, label_namer=None)
- def quiver(self, *args, **kw):
- if not self._hold:
- self.cla()
-
- # Make sure units are handled for x and y values
- args = self._quiver_units(args, kw)
-
- q = mquiver.Quiver(self, *args, **kw)
-
- self.add_collection(q, autolim=True)
- self.autoscale_view()
- return q
- quiver.__doc__ = mquiver.Quiver.quiver_doc
-
- # args can by either Y or y1,y2,... and all should be replaced
- @_preprocess_data(replace_all_args=True, label_namer=None)
- def stackplot(self, x, *args, **kwargs):
- return mstack.stackplot(self, x, *args, **kwargs)
- stackplot.__doc__ = mstack.stackplot.__doc__
-
- @_preprocess_data(replace_names=["x", "y", "u", "v", "start_points"],
- label_namer=None)
- def streamplot(self, x, y, u, v, density=1, linewidth=None, color=None,
- cmap=None, norm=None, arrowsize=1, arrowstyle='-|>',
- minlength=0.1, transform=None, zorder=None,
- start_points=None, maxlength=4.0,
- integration_direction='both'):
- if not self._hold:
- self.cla()
- stream_container = mstream.streamplot(
- self, x, y, u, v,
- density=density,
- linewidth=linewidth,
- color=color,
- cmap=cmap,
- norm=norm,
- arrowsize=arrowsize,
- arrowstyle=arrowstyle,
- minlength=minlength,
- start_points=start_points,
- transform=transform,
- zorder=zorder,
- maxlength=maxlength,
- integration_direction=integration_direction)
- return stream_container
- streamplot.__doc__ = mstream.streamplot.__doc__
-
- # args can be some combination of X, Y, U, V, C and all should be replaced
- @_preprocess_data(replace_all_args=True, label_namer=None)
- @docstring.dedent_interpd
- def barbs(self, *args, **kw):
- """
- %(barbs_doc)s
- """
- if not self._hold:
- self.cla()
-
- # Make sure units are handled for x and y values
- args = self._quiver_units(args, kw)
-
- b = mquiver.Barbs(self, *args, **kw)
- self.add_collection(b, autolim=True)
- self.autoscale_view()
- return b
-
- @_preprocess_data(replace_names=["x", "y"], label_namer=None,
- positional_parameter_names=["x", "y", "c"])
- def fill(self, *args, **kwargs):
- """
- Plot filled polygons.
-
- Parameters
- ----------
- args : sequence of x, y, [color]
- Each polygon is defined by the lists of *x* and *y* positions of
- its nodes, optionally followed by by a *color* specifier. See
- :mod:`matplotlib.colors` for supported color specifiers. The
- standard color cycle is used for polygons without a color
- specifier.
-
- You can plot multiple polygons by providing multiple *x*, *y*,
- *[color]* groups.
-
- For example, each of the following is legal::
-
- ax.fill(x, y) # a polygon with default color
- ax.fill(x, y, "b") # a blue polygon
- ax.fill(x, y, x2, y2) # two polygons
- ax.fill(x, y, "b", x2, y2, "r") # a blue and a red polygon
-
- Returns
- -------
- a list of :class:`~matplotlib.patches.Polygon`
-
- Other Parameters
- ----------------
- **kwargs : :class:`~matplotlib.patches.Polygon` properties
-
- Notes
- -----
- Use :meth:`fill_between` if you would like to fill the region between
- two curves.
- """
- if not self._hold:
- self.cla()
-
- kwargs = cbook.normalize_kwargs(kwargs, _alias_map)
-
- patches = []
- for poly in self._get_patches_for_fill(*args, **kwargs):
- self.add_patch(poly)
- patches.append(poly)
- self.autoscale_view()
- return patches
-
- @_preprocess_data(replace_names=["x", "y1", "y2", "where"],
- label_namer=None)
- @docstring.dedent_interpd
- def fill_between(self, x, y1, y2=0, where=None, interpolate=False,
- step=None, **kwargs):
- """
- Fill the area between two horizontal curves.
-
- The curves are defined by the points (*x*, *y1*) and (*x*, *y2*). This
- creates one or multiple polygons describing the filled area.
-
- You may exclude some horizontal sections from filling using *where*.
-
- By default, the edges connect the given points directly. Use *step* if
- the filling should be a step function, i.e. constant in between *x*.
-
-
- Parameters
- ----------
- x : array (length N)
- The x coordinates of the nodes defining the curves.
-
- y1 : array (length N) or scalar
- The y coordinates of the nodes defining the first curve.
-
- y2 : array (length N) or scalar, optional, default: 0
- The y coordinates of the nodes defining the second curve.
-
- where : array of bool (length N), optional, default: None
- Define *where* to exclude some horizontal regions from being
- filled. The filled regions are defined by the coordinates
- ``x[where]``. More precisely, fill between ``x[i]`` and ``x[i+1]``
- if ``where[i] and where[i+1]``. Note that this definition implies
- that an isolated *True* value between two *False* values in
- *where* will not result in filling. Both sides of the *True*
- position remain unfilled due to the adjacent *False* values.
-
- interpolate : bool, optional
- This option is only relvant if *where* is used and the two curves
- are crossing each other.
-
- Semantically, *where* is often used for *y1* > *y2* or similar.
- By default, the nodes of the polygon defining the filled region
- will only be placed at the positions in the *x* array. Such a
- polygon cannot describe the above semantics close to the
- intersection. The x-sections containing the intersection are
- simply clipped.
-
- Setting *interpolate* to *True* will calculate the actual
- intersection point and extend the filled region up to this point.
-
- step : {'pre', 'post', 'mid'}, optional
- Define *step* if the filling should be a step function,
- i.e. constant in between *x*. The value determines where the
- step will occur:
-
- - 'pre': The y value is continued constantly to the left from
- every *x* position, i.e. the interval ``(x[i-1], x[i]]`` has the
- value ``y[i]``.
- - 'post': The y value is continued constantly to the right from
- every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the
- value ``y[i]``.
- - 'mid': Steps occur half-way between the *x* positions.
-
- Other Parameters
- ----------------
- **kwargs
- All other keyword arguments are passed on to `.PolyCollection`.
- They control the `.Polygon` properties:
-
- %(PolyCollection)s
-
- Returns
- -------
- `.PolyCollection`
- A `.PolyCollection` containing the plotted polygons.
-
- See Also
- --------
- fill_betweenx : Fill between two sets of x-values.
-
- Notes
- -----
- .. [notes section required to get data note injection right]
-
- """
- if not rcParams['_internal.classic_mode']:
- color_aliases = mcoll._color_aliases
- kwargs = cbook.normalize_kwargs(kwargs, color_aliases)
-
- if not any(c in kwargs for c in ('color', 'facecolors')):
- fc = self._get_patches_for_fill.get_next_color()
- kwargs['facecolors'] = fc
-
- # Handle united data, such as dates
- self._process_unit_info(xdata=x, ydata=y1, kwargs=kwargs)
- self._process_unit_info(ydata=y2)
-
- # Convert the arrays so we can work with them
- x = ma.masked_invalid(self.convert_xunits(x))
- y1 = ma.masked_invalid(self.convert_yunits(y1))
- y2 = ma.masked_invalid(self.convert_yunits(y2))
-
- for name, array in [('x', x), ('y1', y1), ('y2', y2)]:
- if array.ndim > 1:
- raise ValueError('Input passed into argument "%r"' % name +
- 'is not 1-dimensional.')
-
- if where is None:
- where = True
- where = where & ~functools.reduce(np.logical_or,
- map(np.ma.getmask, [x, y1, y2]))
-
- x, y1, y2 = np.broadcast_arrays(np.atleast_1d(x), y1, y2)
-
- polys = []
- for ind0, ind1 in cbook.contiguous_regions(where):
- xslice = x[ind0:ind1]
- y1slice = y1[ind0:ind1]
- y2slice = y2[ind0:ind1]
- if step is not None:
- step_func = STEP_LOOKUP_MAP["steps-" + step]
- xslice, y1slice, y2slice = step_func(xslice, y1slice, y2slice)
-
- if not len(xslice):
- continue
-
- N = len(xslice)
- X = np.zeros((2 * N + 2, 2), float)
-
- if interpolate:
- def get_interp_point(ind):
- im1 = max(ind - 1, 0)
- x_values = x[im1:ind + 1]
- diff_values = y1[im1:ind + 1] - y2[im1:ind + 1]
- y1_values = y1[im1:ind + 1]
-
- if len(diff_values) == 2:
- if np.ma.is_masked(diff_values[1]):
- return x[im1], y1[im1]
- elif np.ma.is_masked(diff_values[0]):
- return x[ind], y1[ind]
-
- diff_order = diff_values.argsort()
- diff_root_x = np.interp(
- 0, diff_values[diff_order], x_values[diff_order])
- x_order = x_values.argsort()
- diff_root_y = np.interp(diff_root_x, x_values[x_order],
- y1_values[x_order])
- return diff_root_x, diff_root_y
-
- start = get_interp_point(ind0)
- end = get_interp_point(ind1)
- else:
- # the purpose of the next two lines is for when y2 is a
- # scalar like 0 and we want the fill to go all the way
- # down to 0 even if none of the y1 sample points do
- start = xslice[0], y2slice[0]
- end = xslice[-1], y2slice[-1]
-
- X[0] = start
- X[N + 1] = end
-
- X[1:N + 1, 0] = xslice
- X[1:N + 1, 1] = y1slice
- X[N + 2:, 0] = xslice[::-1]
- X[N + 2:, 1] = y2slice[::-1]
-
- polys.append(X)
-
- collection = mcoll.PolyCollection(polys, **kwargs)
-
- # now update the datalim and autoscale
- XY1 = np.array([x[where], y1[where]]).T
- XY2 = np.array([x[where], y2[where]]).T
- self.dataLim.update_from_data_xy(XY1, self.ignore_existing_data_limits,
- updatex=True, updatey=True)
- self.ignore_existing_data_limits = False
- self.dataLim.update_from_data_xy(XY2, self.ignore_existing_data_limits,
- updatex=False, updatey=True)
- self.add_collection(collection, autolim=False)
- self.autoscale_view()
- return collection
-
- @_preprocess_data(replace_names=["y", "x1", "x2", "where"],
- label_namer=None)
- @docstring.dedent_interpd
- def fill_betweenx(self, y, x1, x2=0, where=None,
- step=None, interpolate=False, **kwargs):
- """
- Fill the area between two vertical curves.
-
- The curves are defined by the points (*x1*, *y*) and (*x2*, *y*). This
- creates one or multiple polygons describing the filled area.
-
- You may exclude some vertical sections from filling using *where*.
-
- By default, the edges connect the given points directly. Use *step* if
- the filling should be a step function, i.e. constant in between *y*.
-
-
- Parameters
- ----------
- y : array (length N)
- The y coordinates of the nodes defining the curves.
-
- x1 : array (length N) or scalar
- The x coordinates of the nodes defining the first curve.
-
- x2 : array (length N) or scalar, optional, default: 0
- The x coordinates of the nodes defining the second curve.
-
- where : array of bool (length N), optional, default: None
- Define *where* to exclude some vertical regions from being
- filled. The filled regions are defined by the coordinates
- ``y[where]``. More precisely, fill between ``y[i]`` and ``y[i+1]``
- if ``where[i] and where[i+1]``. Note that this definition implies
- that an isolated *True* value between two *False* values in
- *where* will not result in filling. Both sides of the *True*
- position remain unfilled due to the adjacent *False* values.
-
- interpolate : bool, optional
- This option is only relvant if *where* is used and the two curves
- are crossing each other.
-
- Semantically, *where* is often used for *x1* > *x2* or similar.
- By default, the nodes of the polygon defining the filled region
- will only be placed at the positions in the *y* array. Such a
- polygon cannot describe the above semantics close to the
- intersection. The y-sections containing the intersecion are
- simply clipped.
-
- Setting *interpolate* to *True* will calculate the actual
- interscection point and extend the filled region up to this point.
-
- step : {'pre', 'post', 'mid'}, optional
- Define *step* if the filling should be a step function,
- i.e. constant in between *y*. The value determines where the
- step will occur:
-
- - 'pre': The y value is continued constantly to the left from
- every *x* position, i.e. the interval ``(x[i-1], x[i]]`` has the
- value ``y[i]``.
- - 'post': The y value is continued constantly to the right from
- every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the
- value ``y[i]``.
- - 'mid': Steps occur half-way between the *x* positions.
-
- Other Parameters
- ----------------
- **kwargs
- All other keyword arguments are passed on to `.PolyCollection`.
- They control the `.Polygon` properties:
-
- %(PolyCollection)s
-
- Returns
- -------
- `.PolyCollection`
- A `.PolyCollection` containing the plotted polygons.
-
- See Also
- --------
- fill_between : Fill between two sets of y-values.
-
- Notes
- -----
- .. [notes section required to get data note injection right]
-
- """
- if not rcParams['_internal.classic_mode']:
- color_aliases = mcoll._color_aliases
- kwargs = cbook.normalize_kwargs(kwargs, color_aliases)
-
- if not any(c in kwargs for c in ('color', 'facecolors')):
- fc = self._get_patches_for_fill.get_next_color()
- kwargs['facecolors'] = fc
- # Handle united data, such as dates
- self._process_unit_info(ydata=y, xdata=x1, kwargs=kwargs)
- self._process_unit_info(xdata=x2)
-
- # Convert the arrays so we can work with them
- y = ma.masked_invalid(self.convert_yunits(y))
- x1 = ma.masked_invalid(self.convert_xunits(x1))
- x2 = ma.masked_invalid(self.convert_xunits(x2))
-
- for name, array in [('y', y), ('x1', x1), ('x2', x2)]:
- if array.ndim > 1:
- raise ValueError('Input passed into argument "%r"' % name +
- 'is not 1-dimensional.')
-
- if where is None:
- where = True
- where = where & ~functools.reduce(np.logical_or,
- map(np.ma.getmask, [y, x1, x2]))
-
- y, x1, x2 = np.broadcast_arrays(np.atleast_1d(y), x1, x2)
-
- polys = []
- for ind0, ind1 in cbook.contiguous_regions(where):
- yslice = y[ind0:ind1]
- x1slice = x1[ind0:ind1]
- x2slice = x2[ind0:ind1]
- if step is not None:
- step_func = STEP_LOOKUP_MAP["steps-" + step]
- yslice, x1slice, x2slice = step_func(yslice, x1slice, x2slice)
-
- if not len(yslice):
- continue
-
- N = len(yslice)
- Y = np.zeros((2 * N + 2, 2), float)
- if interpolate:
- def get_interp_point(ind):
- im1 = max(ind - 1, 0)
- y_values = y[im1:ind + 1]
- diff_values = x1[im1:ind + 1] - x2[im1:ind + 1]
- x1_values = x1[im1:ind + 1]
-
- if len(diff_values) == 2:
- if np.ma.is_masked(diff_values[1]):
- return x1[im1], y[im1]
- elif np.ma.is_masked(diff_values[0]):
- return x1[ind], y[ind]
-
- diff_order = diff_values.argsort()
- diff_root_y = np.interp(
- 0, diff_values[diff_order], y_values[diff_order])
- y_order = y_values.argsort()
- diff_root_x = np.interp(diff_root_y, y_values[y_order],
- x1_values[y_order])
- return diff_root_x, diff_root_y
-
- start = get_interp_point(ind0)
- end = get_interp_point(ind1)
- else:
- # the purpose of the next two lines is for when x2 is a
- # scalar like 0 and we want the fill to go all the way
- # down to 0 even if none of the x1 sample points do
- start = x2slice[0], yslice[0]
- end = x2slice[-1], yslice[-1]
-
- Y[0] = start
- Y[N + 1] = end
-
- Y[1:N + 1, 0] = x1slice
- Y[1:N + 1, 1] = yslice
- Y[N + 2:, 0] = x2slice[::-1]
- Y[N + 2:, 1] = yslice[::-1]
-
- polys.append(Y)
-
- collection = mcoll.PolyCollection(polys, **kwargs)
-
- # now update the datalim and autoscale
- X1Y = np.array([x1[where], y[where]]).T
- X2Y = np.array([x2[where], y[where]]).T
- self.dataLim.update_from_data_xy(X1Y, self.ignore_existing_data_limits,
- updatex=True, updatey=True)
- self.ignore_existing_data_limits = False
- self.dataLim.update_from_data_xy(X2Y, self.ignore_existing_data_limits,
- updatex=True, updatey=False)
- self.add_collection(collection, autolim=False)
- self.autoscale_view()
- return collection
-
- #### plotting z(x,y): imshow, pcolor and relatives, contour
- @_preprocess_data(label_namer=None)
- def imshow(self, X, cmap=None, norm=None, aspect=None,
- interpolation=None, alpha=None, vmin=None, vmax=None,
- origin=None, extent=None, shape=None, filternorm=1,
- filterrad=4.0, imlim=None, resample=None, url=None, **kwargs):
- """
- Display an image on the axes.
-
- Parameters
- ----------
- X : array_like, shape (n, m) or (n, m, 3) or (n, m, 4)
- Display the image in `X` to current axes. `X` may be an
- array or a PIL image. If `X` is an array, it
- can have the following shapes and types:
-
- - MxN -- values to be mapped (float or int)
- - MxNx3 -- RGB (float or uint8)
- - MxNx4 -- RGBA (float or uint8)
-
- MxN arrays are mapped to colors based on the `norm` (mapping
- scalar to scalar) and the `cmap` (mapping the normed scalar to
- a color).
-
- Elements of RGB and RGBA arrays represent pixels of an MxN image.
- All values should be in the range [0 .. 1] for floats or
- [0 .. 255] for integers. Out-of-range values will be clipped to
- these bounds.
-
- cmap : `~matplotlib.colors.Colormap`, optional, default: None
- If None, default to rc `image.cmap` value. `cmap` is ignored
- if `X` is 3-D, directly specifying RGB(A) values.
-
- aspect : ['auto' | 'equal' | scalar], optional, default: None
- If 'auto', changes the image aspect ratio to match that of the
- axes.
-
- If 'equal', and `extent` is None, changes the axes aspect ratio to
- match that of the image. If `extent` is not `None`, the axes
- aspect ratio is changed to match that of the extent.
-
- If None, default to rc ``image.aspect`` value.
-
- interpolation : string, optional, default: None
- Acceptable values are 'none', 'nearest', 'bilinear', 'bicubic',
- 'spline16', 'spline36', 'hanning', 'hamming', 'hermite', 'kaiser',
- 'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc',
- 'lanczos'
-
- If `interpolation` is None, default to rc `image.interpolation`.
- See also the `filternorm` and `filterrad` parameters.
- If `interpolation` is 'none', then no interpolation is performed
- on the Agg, ps and pdf backends. Other backends will fall back to
- 'nearest'.
-
- norm : `~matplotlib.colors.Normalize`, optional, default: None
- A `~matplotlib.colors.Normalize` instance is used to scale
- a 2-D float `X` input to the (0, 1) range for input to the
- `cmap`. If `norm` is None, use the default func:`normalize`.
- If `norm` is an instance of `~matplotlib.colors.NoNorm`,
- `X` must be an array of integers that index directly into
- the lookup table of the `cmap`.
-
- vmin, vmax : scalar, optional, default: None
- `vmin` and `vmax` are used in conjunction with norm to normalize
- luminance data. Note if you pass a `norm` instance, your
- settings for `vmin` and `vmax` will be ignored.
-
- alpha : scalar, optional, default: None
- The alpha blending value, between 0 (transparent) and 1 (opaque).
- The ``alpha`` argument is ignored for RGBA input data.
-
- origin : ['upper' | 'lower'], optional, default: None
- Place the [0,0] index of the array in the upper left or lower left
- corner of the axes. If None, default to rc `image.origin`.
-
- extent : scalars (left, right, bottom, top), optional, default: None
- The location, in data-coordinates, of the lower-left and
- upper-right corners. If `None`, the image is positioned such that
- the pixel centers fall on zero-based (row, column) indices.
-
- shape : scalars (columns, rows), optional, default: None
- For raw buffer images
-
- filternorm : scalar, optional, default: 1
- A parameter for the antigrain image resize filter. From the
- antigrain documentation, if `filternorm` = 1, the filter
- normalizes integer values and corrects the rounding errors. It
- doesn't do anything with the source floating point values, 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.
-
- filterrad : scalar, optional, default: 4.0
- The filter radius for filters that have a radius parameter, i.e.
- when interpolation is one of: 'sinc', 'lanczos' or 'blackman'
-
- Returns
- -------
- image : `~matplotlib.image.AxesImage`
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.artist.Artist` properties.
-
- See also
- --------
- matshow : Plot a matrix or an array as an image.
-
- Notes
- -----
- Unless *extent* is used, pixel centers will be located at integer
- coordinates. In other words: the origin will coincide with the center
- of pixel (0, 0).
-
- Two typical representations are used for RGB images with an alpha
- channel:
-
- - Straight (unassociated) alpha: R, G, and B channels represent the
- color of the pixel, disregarding its opacity.
- - Premultiplied (associated) alpha: R, G, and B channels represent
- the color of the pixel, adjusted for its opacity by multiplication.
-
- `~matplotlib.pyplot.imshow` expects RGB images adopting the straight
- (unassociated) alpha representation.
- """
-
- if not self._hold:
- self.cla()
-
- if norm is not None and not isinstance(norm, mcolors.Normalize):
- raise ValueError(
- "'norm' must be an instance of 'mcolors.Normalize'")
- if aspect is None:
- aspect = rcParams['image.aspect']
- self.set_aspect(aspect)
- im = mimage.AxesImage(self, cmap, norm, interpolation, origin, extent,
- filternorm=filternorm, filterrad=filterrad,
- resample=resample, **kwargs)
-
- im.set_data(X)
- im.set_alpha(alpha)
- if im.get_clip_path() is None:
- # image does not already have clipping set, clip to axes patch
- im.set_clip_path(self.patch)
- #if norm is None and shape is None:
- # im.set_clim(vmin, vmax)
- if vmin is not None or vmax is not None:
- im.set_clim(vmin, vmax)
- else:
- im.autoscale_None()
- im.set_url(url)
-
- # update ax.dataLim, and, if autoscaling, set viewLim
- # to tightly fit the image, regardless of dataLim.
- im.set_extent(im.get_extent())
-
- self.add_image(im)
- return im
-
- @staticmethod
- def _pcolorargs(funcname, *args, **kw):
- # This takes one kwarg, allmatch.
- # If allmatch is True, then the incoming X, Y, C must
- # have matching dimensions, taking into account that
- # X and Y can be 1-D rather than 2-D. This perfect
- # match is required for Gouroud shading. For flat
- # shading, X and Y specify boundaries, so we need
- # one more boundary than color in each direction.
- # For convenience, and consistent with Matlab, we
- # discard the last row and/or column of C if necessary
- # to meet this condition. This is done if allmatch
- # is False.
-
- allmatch = kw.pop("allmatch", False)
-
- if len(args) == 1:
- C = np.asanyarray(args[0])
- numRows, numCols = C.shape
- if allmatch:
- X, Y = np.meshgrid(np.arange(numCols), np.arange(numRows))
- else:
- X, Y = np.meshgrid(np.arange(numCols + 1),
- np.arange(numRows + 1))
- C = cbook.safe_masked_invalid(C)
- return X, Y, C
-
- if len(args) == 3:
- # Check x and y for bad data...
- C = np.asanyarray(args[2])
- X, Y = [cbook.safe_masked_invalid(a) for a in args[:2]]
- if funcname == 'pcolormesh':
- if np.ma.is_masked(X) or np.ma.is_masked(Y):
- raise ValueError(
- 'x and y arguments to pcolormesh cannot have '
- 'non-finite values or be of type '
- 'numpy.ma.core.MaskedArray with masked values')
- # safe_masked_invalid() returns an ndarray for dtypes other
- # than floating point.
- if isinstance(X, np.ma.core.MaskedArray):
- X = X.data # strip mask as downstream doesn't like it...
- if isinstance(Y, np.ma.core.MaskedArray):
- Y = Y.data
- numRows, numCols = C.shape
- else:
- raise TypeError(
- 'Illegal arguments to %s; see help(%s)' % (funcname, funcname))
-
- Nx = X.shape[-1]
- Ny = Y.shape[0]
- if X.ndim != 2 or X.shape[0] == 1:
- x = X.reshape(1, Nx)
- X = x.repeat(Ny, axis=0)
- if Y.ndim != 2 or Y.shape[1] == 1:
- y = Y.reshape(Ny, 1)
- Y = y.repeat(Nx, axis=1)
- if X.shape != Y.shape:
- raise TypeError(
- 'Incompatible X, Y inputs to %s; see help(%s)' % (
- funcname, funcname))
- if allmatch:
- if not (Nx == numCols and Ny == numRows):
- raise TypeError('Dimensions of C %s are incompatible with'
- ' X (%d) and/or Y (%d); see help(%s)' % (
- C.shape, Nx, Ny, funcname))
- else:
- if not (numCols in (Nx, Nx - 1) and numRows in (Ny, Ny - 1)):
- raise TypeError('Dimensions of C %s are incompatible with'
- ' X (%d) and/or Y (%d); see help(%s)' % (
- C.shape, Nx, Ny, funcname))
- C = C[:Ny - 1, :Nx - 1]
- C = cbook.safe_masked_invalid(C)
- return X, Y, C
-
- @_preprocess_data(label_namer=None)
- @docstring.dedent_interpd
- def pcolor(self, *args, **kwargs):
- r"""
- Create a pseudocolor plot with a non-regular rectangular grid.
-
- Call signature::
-
- pcolor([X, Y,] C, **kwargs)
-
- *X* and *Y* can be used to specify the corners of the quadrilaterals.
-
- .. hint::
-
- ``pcolor()`` can be very slow for large arrays. In most
- cases you should use the the similar but much faster
- `~.Axes.pcolormesh` instead. See there for a discussion of the
- differences.
-
- Parameters
- ----------
- C : array_like
- A scalar 2-D array. The values will be color-mapped.
-
- X, Y : array_like, optional
- The coordinates of the quadrilateral corners. The quadrilateral
- for ``C[i,j]`` has corners at::
-
- (X[i+1, j], Y[i+1, j]) (X[i+1, j+1], Y[i+1, j+1])
- +--------+
- | C[i,j] |
- +--------+
- (X[i, j], Y[i, j]) (X[i, j+1], Y[i, j+1]),
-
- Note that the column index corresponds to the
- x-coordinate, and the row index corresponds to y. For
- details, see the :ref:`Notes <axes-pcolor-grid-orientation>`
- section below.
-
- The dimensions of *X* and *Y* should be one greater than those of
- *C*. Alternatively, *X*, *Y* and *C* may have equal dimensions, in
- which case the last row and column of *C* will be ignored.
-
- If *X* and/or *Y* are 1-D arrays or column vectors they will be
- expanded as needed into the appropriate 2-D arrays, making a
- rectangular grid.
-
- cmap : str or `~matplotlib.colors.Colormap`, optional
- A Colormap instance or registered colormap name. The colormap
- maps the *C* values to colors. Defaults to :rc:`image.cmap`.
-
- norm : `~matplotlib.colors.Normalize`, optional
- The Normalize instance scales the data values to the canonical
- colormap range [0, 1] for mapping to colors. By default, the data
- range is mapped to the colorbar range using linear scaling.
-
- vmin, vmax : scalar, optional, default: None
- The colorbar range. If *None*, suitable min/max values are
- automatically chosen by the `~.Normalize` instance (defaults to
- the respective min/max values of *C* in case of the default linear
- scaling).
-
- edgecolors : {'none', None, 'face', color, color sequence}, optional
- The color of the edges. Defaults to 'none'. Possible values:
-
- - 'none' or '': No edge.
- - *None*: :rc:`patch.edgecolor` will be used. Note that currently
- :rc:`patch.force_edgecolor` has to be True for this to work.
- - 'face': Use the adjacent face color.
- - An mpl color or sequence of colors will set the edge color.
-
- The singular form *edgecolor* works as an alias.
-
- alpha : scalar, optional, default: None
- The alpha blending value of the face color, between 0 (transparent)
- and 1 (opaque). Note: The edgecolor is currently not affected by
- this.
-
- snap : bool, optional, default: False
- Whether to snap the mesh to pixel boundaries.
-
- Returns
- -------
- collection : `matplotlib.collections.Collection`
-
- Other Parameters
- ----------------
- antialiaseds : bool, optional, default: False
- The default *antialiaseds* is False if the default
- *edgecolors*\ ="none" is used. This eliminates artificial lines
- at patch boundaries, and works regardless of the value of alpha.
- If *edgecolors* is not "none", then the default *antialiaseds*
- is taken from :rc:`patch.antialiased`, which defaults to True.
- Stroking the edges may be preferred if *alpha* is 1, but will
- cause artifacts otherwise.
-
- **kwargs :
- Additionally, the following arguments are allowed. They are passed
- along to the `~matplotlib.collections.PolyCollection` constructor:
-
- %(PolyCollection)s
-
- See Also
- --------
- pcolormesh : for an explanation of the differences between
- pcolor and pcolormesh.
- imshow : If *X* and *Y* are each equidistant, `~.Axes.imshow` can be a
- faster alternative.
-
- Notes
- -----
-
- **Masked arrays**
-
- *X*, *Y* and *C* may be masked arrays. If either ``C[i, j]``, or one
- of the vertices surrounding ``C[i,j]`` (*X* or *Y* at
- ``[i, j], [i+1, j], [i, j+1], [i+1, j+1]``) is masked, nothing is
- plotted.
-
- .. _axes-pcolor-grid-orientation:
-
- **Grid orientation**
-
- The grid orientation follows the standard matrix convention: An array
- *C* with shape (nrows, ncolumns) is plotted with the column number as
- *X* and the row number as *Y*.
-
- **Handling of pcolor() end-cases**
-
- ``pcolor()`` displays all columns of *C* if *X* and *Y* are not
- specified, or if *X* and *Y* have one more column than *C*.
- If *X* and *Y* have the same number of columns as *C* then the last
- column of *C* is dropped. Similarly for the rows.
-
- Note: This behavior is different from MATLAB's ``pcolor()``, which
- always discards the last row and column of *C*.
- """
-
- if not self._hold:
- self.cla()
-
- alpha = kwargs.pop('alpha', None)
- norm = kwargs.pop('norm', None)
- cmap = kwargs.pop('cmap', None)
- vmin = kwargs.pop('vmin', None)
- vmax = kwargs.pop('vmax', None)
-
- X, Y, C = self._pcolorargs('pcolor', *args, allmatch=False)
- Ny, Nx = X.shape
-
- # unit conversion allows e.g. datetime objects as axis values
- self._process_unit_info(xdata=X, ydata=Y, kwargs=kwargs)
- X = self.convert_xunits(X)
- Y = self.convert_yunits(Y)
-
- # convert to MA, if necessary.
- C = ma.asarray(C)
- X = ma.asarray(X)
- Y = ma.asarray(Y)
-
- mask = ma.getmaskarray(X) + ma.getmaskarray(Y)
- xymask = (mask[0:-1, 0:-1] + mask[1:, 1:] +
- mask[0:-1, 1:] + mask[1:, 0:-1])
- # don't plot if C or any of the surrounding vertices are masked.
- mask = ma.getmaskarray(C) + xymask
-
- newaxis = np.newaxis
- compress = np.compress
-
- ravelmask = (mask == 0).ravel()
- X1 = compress(ravelmask, ma.filled(X[0:-1, 0:-1]).ravel())
- Y1 = compress(ravelmask, ma.filled(Y[0:-1, 0:-1]).ravel())
- X2 = compress(ravelmask, ma.filled(X[1:, 0:-1]).ravel())
- Y2 = compress(ravelmask, ma.filled(Y[1:, 0:-1]).ravel())
- X3 = compress(ravelmask, ma.filled(X[1:, 1:]).ravel())
- Y3 = compress(ravelmask, ma.filled(Y[1:, 1:]).ravel())
- X4 = compress(ravelmask, ma.filled(X[0:-1, 1:]).ravel())
- Y4 = compress(ravelmask, ma.filled(Y[0:-1, 1:]).ravel())
- npoly = len(X1)
-
- xy = np.concatenate((X1[:, newaxis], Y1[:, newaxis],
- X2[:, newaxis], Y2[:, newaxis],
- X3[:, newaxis], Y3[:, newaxis],
- X4[:, newaxis], Y4[:, newaxis],
- X1[:, newaxis], Y1[:, newaxis]),
- axis=1)
- verts = xy.reshape((npoly, 5, 2))
-
- C = compress(ravelmask, ma.filled(C[0:Ny - 1, 0:Nx - 1]).ravel())
-
- linewidths = (0.25,)
- if 'linewidth' in kwargs:
- kwargs['linewidths'] = kwargs.pop('linewidth')
- kwargs.setdefault('linewidths', linewidths)
-
- if 'edgecolor' in kwargs:
- kwargs['edgecolors'] = kwargs.pop('edgecolor')
- ec = kwargs.setdefault('edgecolors', 'none')
-
- # aa setting will default via collections to patch.antialiased
- # unless the boundary is not stroked, in which case the
- # default will be False; with unstroked boundaries, aa
- # makes artifacts that are often disturbing.
- if 'antialiased' in kwargs:
- kwargs['antialiaseds'] = kwargs.pop('antialiased')
- if 'antialiaseds' not in kwargs and (
- isinstance(ec, six.string_types) and ec.lower() == "none"):
- kwargs['antialiaseds'] = False
-
- kwargs.setdefault('snap', False)
-
- collection = mcoll.PolyCollection(verts, **kwargs)
-
- collection.set_alpha(alpha)
- collection.set_array(C)
- if norm is not None and not isinstance(norm, mcolors.Normalize):
- raise ValueError(
- "'norm' must be an instance of 'mcolors.Normalize'")
- collection.set_cmap(cmap)
- collection.set_norm(norm)
- collection.set_clim(vmin, vmax)
- collection.autoscale_None()
- self.grid(False)
-
- x = X.compressed()
- y = Y.compressed()
-
- # Transform from native to data coordinates?
- t = collection._transform
- if (not isinstance(t, mtransforms.Transform) and
- hasattr(t, '_as_mpl_transform')):
- t = t._as_mpl_transform(self.axes)
-
- if t and any(t.contains_branch_seperately(self.transData)):
- trans_to_data = t - self.transData
- pts = np.vstack([x, y]).T.astype(float)
- transformed_pts = trans_to_data.transform(pts)
- x = transformed_pts[..., 0]
- y = transformed_pts[..., 1]
-
- self.add_collection(collection, autolim=False)
-
- minx = np.min(x)
- maxx = np.max(x)
- miny = np.min(y)
- maxy = np.max(y)
- collection.sticky_edges.x[:] = [minx, maxx]
- collection.sticky_edges.y[:] = [miny, maxy]
- corners = (minx, miny), (maxx, maxy)
- self.update_datalim(corners)
- self.autoscale_view()
- return collection
-
- @_preprocess_data(label_namer=None)
- @docstring.dedent_interpd
- def pcolormesh(self, *args, **kwargs):
- """
- Create a pseudocolor plot with a non-regular rectangular grid.
-
- Call signature::
-
- pcolor([X, Y,] C, **kwargs)
-
- *X* and *Y* can be used to specify the corners of the quadrilaterals.
-
- .. note::
-
- ``pcolormesh()`` is similar to :func:`~Axes.pcolor`. It's much
- faster and preferred in most cases. For a detailed discussion on
- the differences see
- :ref:`Differences between pcolor() and pcolormesh()
- <differences-pcolor-pcolormesh>`.
-
- Parameters
- ----------
- C : array_like
- A scalar 2-D array. The values will be color-mapped.
-
- X, Y : array_like, optional
- The coordinates of the quadrilateral corners. The quadrilateral
- for ``C[i,j]`` has corners at::
-
- (X[i+1, j], Y[i+1, j]) (X[i+1, j+1], Y[i+1, j+1])
- +--------+
- | C[i,j] |
- +--------+
- (X[i, j], Y[i, j]) (X[i, j+1], Y[i, j+1]),
-
- Note that the column index corresponds to the
- x-coordinate, and the row index corresponds to y. For
- details, see the :ref:`Notes <axes-pcolormesh-grid-orientation>`
- section below.
-
- The dimensions of *X* and *Y* should be one greater than those of
- *C*. Alternatively, *X*, *Y* and *C* may have equal dimensions, in
- which case the last row and column of *C* will be ignored.
-
- If *X* and/or *Y* are 1-D arrays or column vectors they will be
- expanded as needed into the appropriate 2-D arrays, making a
- rectangular grid.
-
- cmap : str or `~matplotlib.colors.Colormap`, optional
- A Colormap instance or registered colormap name. The colormap
- maps the *C* values to colors. Defaults to :rc:`image.cmap`.
-
- norm : `~matplotlib.colors.Normalize`, optional
- The Normalize instance scales the data values to the canonical
- colormap range [0, 1] for mapping to colors. By default, the data
- range is mapped to the colorbar range using linear scaling.
-
- vmin, vmax : scalar, optional, default: None
- The colorbar range. If *None*, suitable min/max values are
- automatically chosen by the `~.Normalize` instance (defaults to
- the respective min/max values of *C* in case of the default linear
- scaling).
-
- edgecolors : {'none', None, 'face', color, color sequence}, optional
- The color of the edges. Defaults to 'none'. Possible values:
-
- - 'none' or '': No edge.
- - *None*: :rc:`patch.edgecolor` will be used. Note that currently
- :rc:`patch.force_edgecolor` has to be True for this to work.
- - 'face': Use the adjacent face color.
- - An mpl color or sequence of colors will set the edge color.
-
- The singular form *edgecolor* works as an alias.
-
- alpha : scalar, optional, default: None
- The alpha blending value, between 0 (transparent) and 1 (opaque).
-
- shading : {'flat', 'gouraud'}, optional
- The fill style, Possible values:
-
- - 'flat': A solid color is used for each quad. The color of the
- quad (i, j), (i+1, j), (i, j+1), (i+1, j+1) is given by
- ``C[i,j]``.
- - 'gouraud': Each quad will be Gouraud shaded: The color of the
- corners (i', j') are given by ``C[i',j']``. The color values of
- the area in between is interpolated from the corner values.
- When Gouraud shading is used, *edgecolors* is ignored.
-
- snap : bool, optional, default: False
- Whether to snap the mesh to pixel boundaries.
-
- Returns
- -------
- mesh : `matplotlib.collections.QuadMesh`
-
- Other Parameters
- ----------------
- **kwargs
- Additionally, the following arguments are allowed. They are passed
- along to the `~matplotlib.collections.QuadMesh` constructor:
-
- %(QuadMesh)s
-
-
- See Also
- --------
- pcolor : An alternative implementation with slightly different
- features. For a detailed discussion on the differences see
- :ref:`Differences between pcolor() and pcolormesh()
- <differences-pcolor-pcolormesh>`.
- imshow : If *X* and *Y* are each equidistant, `~.Axes.imshow` can be a
- faster alternative.
-
- Notes
- -----
-
- **Masked arrays**
-
- *C* may be a masked array. If ``C[i, j]`` is masked, the corresponding
- quadrilateral will be transparent. Masking of *X* and *Y* is not
- supported. Use `~.Axes.pcolor` if you need this functionality.
-
- .. _axes-pcolormesh-grid-orientation:
-
- **Grid orientation**
-
- The grid orientation follows the standard matrix convention: An array
- *C* with shape (nrows, ncolumns) is plotted with the column number as
- *X* and the row number as *Y*.
-
- .. _differences-pcolor-pcolormesh:
-
- **Differences between pcolor() and pcolormesh()**
-
- Both methods are used to create a pseudocolor plot of a 2-D array
- using quadrilaterals.
-
- The main difference lies in the created object and internal data
- handling:
- While `~.Axes.pcolor` returns a `.PolyCollection`, `~.Axes.pcolormesh`
- returns a `.QuadMesh`. The latter is more specialized for the given
- purpose and thus is faster. It should almost always be preferred.
-
- There is also a slight difference in the handling of masked arrays.
- Both `~.Axes.pcolor` and `~.Axes.pcolormesh` support masked arrays
- for *C*. However, only `~.Axes.pcolor` supports masked arrays for *X*
- and *Y*. The reason lies in the internal handling of the masked values.
- `~.Axes.pcolor` leaves out the respective polygons from the
- PolyCollection. `~.Axes.pcolormesh` sets the facecolor of the masked
- elements to transparent. You can see the difference when using
- edgecolors. While all edges are drawn irrespective of masking in a
- QuadMesh, the edge between two adjacent masked quadrilaterals in
- `~.Axes.pcolor` is not drawn as the corresponding polygons do not
- exist in the PolyCollection.
-
- Another difference is the support of Gouraud shading in
- `~.Axes.pcolormesh`, which is not available with `~.Axes.pcolor`.
-
- """
- if not self._hold:
- self.cla()
-
- alpha = kwargs.pop('alpha', None)
- norm = kwargs.pop('norm', None)
- cmap = kwargs.pop('cmap', None)
- vmin = kwargs.pop('vmin', None)
- vmax = kwargs.pop('vmax', None)
- shading = kwargs.pop('shading', 'flat').lower()
- antialiased = kwargs.pop('antialiased', False)
- kwargs.setdefault('edgecolors', 'None')
-
- allmatch = (shading == 'gouraud')
-
- X, Y, C = self._pcolorargs('pcolormesh', *args, allmatch=allmatch)
- Ny, Nx = X.shape
- X = X.ravel()
- Y = Y.ravel()
- # unit conversion allows e.g. datetime objects as axis values
- self._process_unit_info(xdata=X, ydata=Y, kwargs=kwargs)
- X = self.convert_xunits(X)
- Y = self.convert_yunits(Y)
-
- # convert to one dimensional arrays
- C = C.ravel()
- coords = np.column_stack((X, Y)).astype(float, copy=False)
- collection = mcoll.QuadMesh(Nx - 1, Ny - 1, coords,
- antialiased=antialiased, shading=shading,
- **kwargs)
- collection.set_alpha(alpha)
- collection.set_array(C)
- if norm is not None and not isinstance(norm, mcolors.Normalize):
- raise ValueError(
- "'norm' must be an instance of 'mcolors.Normalize'")
- collection.set_cmap(cmap)
- collection.set_norm(norm)
- collection.set_clim(vmin, vmax)
- collection.autoscale_None()
-
- self.grid(False)
-
- # Transform from native to data coordinates?
- t = collection._transform
- if (not isinstance(t, mtransforms.Transform) and
- hasattr(t, '_as_mpl_transform')):
- t = t._as_mpl_transform(self.axes)
-
- if t and any(t.contains_branch_seperately(self.transData)):
- trans_to_data = t - self.transData
- coords = trans_to_data.transform(coords)
-
- self.add_collection(collection, autolim=False)
-
- minx, miny = np.min(coords, axis=0)
- maxx, maxy = np.max(coords, axis=0)
- collection.sticky_edges.x[:] = [minx, maxx]
- collection.sticky_edges.y[:] = [miny, maxy]
- corners = (minx, miny), (maxx, maxy)
- self.update_datalim(corners)
- self.autoscale_view()
- return collection
-
- @_preprocess_data(label_namer=None)
- @docstring.dedent_interpd
- def pcolorfast(self, *args, **kwargs):
- """
- Create a pseudocolor plot with a non-regular rectangular grid.
-
- Call signatures::
-
- ax.pcolorfast(C, **kwargs)
- ax.pcolorfast(xr, yr, C, **kwargs)
- ax.pcolorfast(x, y, C, **kwargs)
- ax.pcolorfast(X, Y, C, **kwargs)
-
- This method is similar to ~.Axes.pcolor` and `~.Axes.pcolormesh`.
- It's designed to provide the fastest pcolor-type plotting with the
- Agg backend. To achieve this, it uses different algorithms internally
- depending on the complexity of the input grid (regular rectangular,
- non-regular rectangular or arbitrary quadrilateral).
-
- .. warning::
-
- This method is experimental. Compared to `~.Axes.pcolor` or
- `~.Axes.pcolormesh` it has some limitations:
-
- - It supports only flat shading (no outlines)
- - It lacks support for log scaling of the axes.
- - It does not have a have a pyplot wrapper.
-
- Parameters
- ----------
- C : array-like(M, N)
- A scalar 2D array. The values will be color-mapped.
- *C* may be a masked array.
-
- x, y : tuple or array-like
- *X* and *Y* are used to specify the coordinates of the
- quadilaterals. There are different ways to do this:
-
- - Use tuples ``xr=(xmin, xmax)`` and ``yr=(ymin, ymax)`` to define
- a *uniform rectiangular grid*.
-
- The tuples define the outer edges of the grid. All individual
- quadrilaterals will be of the same size. This is the fastest
- version.
-
- - Use 1D arrays *x*, *y* to specify a *non-uniform rectangular
- grid*.
-
- In this case *x* and *y* have to be monotonic 1D arrays of length
- *N+1* and *M+1*, specifying the x and y boundaries of the cells.
-
- The speed is intermediate. Note: The grid is checked, and if
- found to be uniform the fast version is used.
-
- - Use 2D arrays *X*, *Y* if you need an *arbitrary quadrilateral
- grid* (i.e. if the quadrilaterals are not rectangular).
-
- In this case *X* and *Y* are 2D arrays with shape (M, N),
- specifying the x and y coordinates of the corners of the colored
- quadrilaterals. See `~.Axes.pcolormesh` for details.
-
- This is the most general, but the slowest to render. It may
- produce faster and more compact output using ps, pdf, and
- svg backends, however.
-
- Leaving out *x* and *y* defaults to ``xr=(0, N)``, ``yr=(O, M)``.
-
- cmap : str or `~matplotlib.colors.Colormap`, optional
- A Colormap instance or registered colormap name. The colormap
- maps the *C* values to colors. Defaults to :rc:`image.cmap`.
-
- norm : `~matplotlib.colors.Normalize`, optional
- The Normalize instance scales the data values to the canonical
- colormap range [0, 1] for mapping to colors. By default, the data
- range is mapped to the colorbar range using linear scaling.
-
- vmin, vmax : scalar, optional, default: None
- The colorbar range. If *None*, suitable min/max values are
- automatically chosen by the `~.Normalize` instance (defaults to
- the respective min/max values of *C* in case of the default linear
- scaling).
-
- alpha : scalar, optional, default: None
- The alpha blending value, between 0 (transparent) and 1 (opaque).
-
- snap : bool, optional, default: False
- Whether to snap the mesh to pixel boundaries.
-
- Returns
- -------
- image : `.AxesImage` or `.PcolorImage` or `.QuadMesh`
- The return type depends on the type of grid:
-
- - `.AxesImage` for a regular rectangular grid.
- - `.PcolorImage` for a non-regular rectangular grid.
- - `.QuadMesh` for a non-rectangular grid.
-
- Notes
- -----
- .. [notes section required to get data note injection right]
-
- """
-
- if not self._hold:
- self.cla()
-
- alpha = kwargs.pop('alpha', None)
- norm = kwargs.pop('norm', None)
- cmap = kwargs.pop('cmap', None)
- vmin = kwargs.pop('vmin', None)
- vmax = kwargs.pop('vmax', None)
- if norm is not None and not isinstance(norm, mcolors.Normalize):
- raise ValueError(
- "'norm' must be an instance of 'mcolors.Normalize'")
-
- C = args[-1]
- nr, nc = C.shape
- if len(args) == 1:
- style = "image"
- x = [0, nc]
- y = [0, nr]
- elif len(args) == 3:
- x, y = args[:2]
- x = np.asarray(x)
- y = np.asarray(y)
- if x.ndim == 1 and y.ndim == 1:
- if x.size == 2 and y.size == 2:
- style = "image"
- else:
- dx = np.diff(x)
- dy = np.diff(y)
- if (np.ptp(dx) < 0.01 * np.abs(dx.mean()) and
- np.ptp(dy) < 0.01 * np.abs(dy.mean())):
- style = "image"
- else:
- style = "pcolorimage"
- elif x.ndim == 2 and y.ndim == 2:
- style = "quadmesh"
- else:
- raise TypeError("arguments do not match valid signatures")
- else:
- raise TypeError("need 1 argument or 3 arguments")
-
- if style == "quadmesh":
-
- # convert to one dimensional arrays
- # This should also be moved to the QuadMesh class
-
- # data point in each cell is value at lower left corner
- C = ma.ravel(C)
- X = x.ravel()
- Y = y.ravel()
- Nx = nc + 1
- Ny = nr + 1
-
- # The following needs to be cleaned up; the renderer
- # requires separate contiguous arrays for X and Y,
- # but the QuadMesh class requires the 2D array.
- coords = np.empty(((Nx * Ny), 2), np.float64)
- coords[:, 0] = X
- coords[:, 1] = Y
-
- # The QuadMesh class can also be changed to
- # handle relevant superclass kwargs; the initializer
- # should do much more than it does now.
- collection = mcoll.QuadMesh(nc, nr, coords, 0, edgecolors="None")
- collection.set_alpha(alpha)
- collection.set_array(C)
- collection.set_cmap(cmap)
- collection.set_norm(norm)
- self.add_collection(collection, autolim=False)
- xl, xr, yb, yt = X.min(), X.max(), Y.min(), Y.max()
- ret = collection
-
- else: # It's one of the two image styles.
- xl, xr, yb, yt = x[0], x[-1], y[0], y[-1]
-
- if style == "image":
- im = mimage.AxesImage(self, cmap, norm,
- interpolation='nearest',
- origin='lower',
- extent=(xl, xr, yb, yt),
- **kwargs)
- im.set_data(C)
- im.set_alpha(alpha)
- elif style == "pcolorimage":
- im = mimage.PcolorImage(self, x, y, C,
- cmap=cmap,
- norm=norm,
- alpha=alpha,
- **kwargs)
- im.set_extent((xl, xr, yb, yt))
- self.add_image(im)
- ret = im
-
- if vmin is not None or vmax is not None:
- ret.set_clim(vmin, vmax)
- else:
- ret.autoscale_None()
-
- ret.sticky_edges.x[:] = [xl, xr]
- ret.sticky_edges.y[:] = [yb, yt]
- self.update_datalim(np.array([[xl, yb], [xr, yt]]))
- self.autoscale_view(tight=True)
- return ret
-
- @_preprocess_data()
- def contour(self, *args, **kwargs):
- if not self._hold:
- self.cla()
- kwargs['filled'] = False
- contours = mcontour.QuadContourSet(self, *args, **kwargs)
- self.autoscale_view()
- return contours
- contour.__doc__ = mcontour.QuadContourSet._contour_doc
-
- @_preprocess_data()
- def contourf(self, *args, **kwargs):
- if not self._hold:
- self.cla()
- kwargs['filled'] = True
- contours = mcontour.QuadContourSet(self, *args, **kwargs)
- self.autoscale_view()
- return contours
- contourf.__doc__ = mcontour.QuadContourSet._contour_doc
-
- def clabel(self, CS, *args, **kwargs):
- return CS.clabel(*args, **kwargs)
- clabel.__doc__ = mcontour.ContourSet.clabel.__doc__
-
- @docstring.dedent_interpd
- def table(self, **kwargs):
- """
- Add a table to the current axes.
-
- Call signature::
-
- table(cellText=None, cellColours=None,
- cellLoc='right', colWidths=None,
- rowLabels=None, rowColours=None, rowLoc='left',
- colLabels=None, colColours=None, colLoc='center',
- loc='bottom', bbox=None)
-
- Returns a :class:`matplotlib.table.Table` instance. Either `cellText`
- or `cellColours` must be provided. For finer grained control over
- tables, use the :class:`~matplotlib.table.Table` class and add it to
- the axes with :meth:`~matplotlib.axes.Axes.add_table`.
-
- Thanks to John Gill for providing the class and table.
-
- kwargs control the :class:`~matplotlib.table.Table`
- properties:
-
- %(Table)s
- """
- return mtable.table(self, **kwargs)
-
- #### Data analysis
-
- @_preprocess_data(replace_names=["x", 'weights'], label_namer="x")
- def hist(self, x, bins=None, range=None, density=None, weights=None,
- cumulative=False, bottom=None, histtype='bar', align='mid',
- orientation='vertical', rwidth=None, log=False,
- color=None, label=None, stacked=False, normed=None,
- **kwargs):
- """
- Plot a histogram.
-
- Compute and draw the histogram of *x*. The return value is a
- tuple (*n*, *bins*, *patches*) or ([*n0*, *n1*, ...], *bins*,
- [*patches0*, *patches1*,...]) if the input contains multiple
- data.
-
- Multiple data can be provided via *x* as a list of datasets
- of potentially different length ([*x0*, *x1*, ...]), or as
- a 2-D ndarray in which each column is a dataset. Note that
- the ndarray form is transposed relative to the list form.
-
- Masked arrays are not supported at present.
-
- Parameters
- ----------
- x : (n,) array or sequence of (n,) arrays
- Input values, this takes either a single array or a sequence of
- arrays which are not required to be of the same length
-
- bins : integer or sequence or 'auto', optional
- If an integer is given, ``bins + 1`` bin edges are calculated and
- returned, consistent with :func:`numpy.histogram`.
-
- If `bins` is a sequence, gives bin edges, including left edge of
- first bin and right edge of last bin. In this case, `bins` is
- returned unmodified.
-
- All but the last (righthand-most) bin is half-open. In other
- words, if `bins` is::
-
- [1, 2, 3, 4]
-
- then the first bin is ``[1, 2)`` (including 1, but excluding 2) and
- the second ``[2, 3)``. The last bin, however, is ``[3, 4]``, which
- *includes* 4.
-
- Unequally spaced bins are supported if *bins* is a sequence.
-
- If Numpy 1.11 is installed, may also be ``'auto'``.
-
- Default is taken from the rcParam ``hist.bins``.
-
- range : tuple or None, optional
- The lower and upper range of the bins. Lower and upper outliers
- are ignored. If not provided, *range* is ``(x.min(), x.max())``.
- Range has no effect if *bins* is a sequence.
-
- If *bins* is a sequence or *range* is specified, autoscaling
- is based on the specified bin range instead of the
- range of x.
-
- Default is ``None``
-
- density : boolean, optional
- If ``True``, the first element of the return tuple will
- be the counts normalized to form a probability density, i.e.,
- the area (or integral) under the histogram will sum to 1.
- This is achieved by dividing the count by the number of
- observations times the bin width and not dividing by the total
- number of observations. If *stacked* is also ``True``, the sum of
- the histograms is normalized to 1.
-
- Default is ``None`` for both *normed* and *density*. If either is
- set, then that value will be used. If neither are set, then the
- args will be treated as ``False``.
-
- If both *density* and *normed* are set an error is raised.
-
- weights : (n, ) array_like or None, optional
- An array of weights, of the same shape as *x*. Each value in *x*
- only contributes its associated weight towards the bin count
- (instead of 1). If *normed* or *density* is ``True``,
- the weights are normalized, so that the integral of the density
- over the range remains 1.
-
- Default is ``None``
-
- cumulative : boolean, optional
- If ``True``, then a histogram is computed where each bin gives the
- counts in that bin plus all bins for smaller values. The last bin
- gives the total number of datapoints. If *normed* or *density*
- is also ``True`` then the histogram is normalized such that the
- last bin equals 1. If *cumulative* evaluates to less than 0
- (e.g., -1), the direction of accumulation is reversed.
- In this case, if *normed* and/or *density* is also ``True``, then
- the histogram is normalized such that the first bin equals 1.
-
- Default is ``False``
-
- bottom : array_like, scalar, or None
- Location of the bottom baseline of each bin. If a scalar,
- the base line for each bin is shifted by the same amount.
- If an array, each bin is shifted independently and the length
- of bottom must match the number of bins. If None, defaults to 0.
-
- Default is ``None``
-
- histtype : {'bar', 'barstacked', 'step', 'stepfilled'}, optional
- The type of histogram to draw.
-
- - 'bar' is a traditional bar-type histogram. If multiple data
- are given the bars are arranged side by side.
-
- - 'barstacked' is a bar-type histogram where multiple
- data are stacked on top of each other.
-
- - 'step' generates a lineplot that is by default
- unfilled.
-
- - 'stepfilled' generates a lineplot that is by default
- filled.
-
- Default is 'bar'
-
- align : {'left', 'mid', 'right'}, optional
- Controls how the histogram is plotted.
-
- - 'left': bars are centered on the left bin edges.
-
- - 'mid': bars are centered between the bin edges.
-
- - 'right': bars are centered on the right bin edges.
-
- Default is 'mid'
-
- orientation : {'horizontal', 'vertical'}, optional
- If 'horizontal', `~matplotlib.pyplot.barh` will be used for
- bar-type histograms and the *bottom* kwarg will be the left edges.
-
- rwidth : scalar or None, optional
- The relative width of the bars as a fraction of the bin width. If
- ``None``, automatically compute the width.
-
- Ignored if *histtype* is 'step' or 'stepfilled'.
-
- Default is ``None``
-
- log : boolean, optional
- If ``True``, the histogram axis will be set to a log scale. If
- *log* is ``True`` and *x* is a 1D array, empty bins will be
- filtered out and only the non-empty ``(n, bins, patches)``
- will be returned.
-
- Default is ``False``
-
- color : color or array_like of colors or None, optional
- Color spec or sequence of color specs, one per dataset. Default
- (``None``) uses the standard line color sequence.
-
- Default is ``None``
-
- label : string or None, optional
- String, or sequence of strings to match multiple datasets. Bar
- charts yield multiple patches per dataset, but only the first gets
- the label, so that the legend command will work as expected.
-
- default is ``None``
-
- stacked : boolean, optional
- If ``True``, multiple data are stacked on top of each other If
- ``False`` multiple data are arranged side by side if histtype is
- 'bar' or on top of each other if histtype is 'step'
-
- Default is ``False``
-
- normed : bool, optional
- Deprecated; use the density keyword argument instead.
-
- Returns
- -------
- n : array or list of arrays
- The values of the histogram bins. See *normed* or *density*
- and *weights* for a description of the possible semantics.
- If input *x* is an array, then this is an array of length
- *nbins*. If input is a sequence arrays
- ``[data1, data2,..]``, then this is a list of arrays with
- the values of the histograms for each of the arrays in the
- same order.
-
- bins : array
- The edges of the bins. Length nbins + 1 (nbins left edges and right
- edge of last bin). Always a single array even when multiple data
- sets are passed in.
-
- patches : list or list of lists
- Silent list of individual patches used to create the histogram
- or list of such list if multiple input datasets.
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.patches.Patch` properties
-
- See also
- --------
- hist2d : 2D histograms
-
- Notes
- -----
- .. [Notes section required for data comment. See #10189.]
-
- """
- # Avoid shadowing the builtin.
- bin_range = range
- del range
-
- if not self._hold:
- self.cla()
-
- if np.isscalar(x):
- x = [x]
-
- if bins is None:
- bins = rcParams['hist.bins']
-
- # Validate string inputs here so we don't have to clutter
- # subsequent code.
- if histtype not in ['bar', 'barstacked', 'step', 'stepfilled']:
- raise ValueError("histtype %s is not recognized" % histtype)
-
- if align not in ['left', 'mid', 'right']:
- raise ValueError("align kwarg %s is not recognized" % align)
-
- if orientation not in ['horizontal', 'vertical']:
- raise ValueError(
- "orientation kwarg %s is not recognized" % orientation)
-
- if histtype == 'barstacked' and not stacked:
- stacked = True
-
- if density is not None and normed is not None:
- raise ValueError("kwargs 'density' and 'normed' cannot be used "
- "simultaneously. "
- "Please only use 'density', since 'normed'"
- "is deprecated.")
- if normed is not None:
- warnings.warn("The 'normed' kwarg is deprecated, and has been "
- "replaced by the 'density' kwarg.")
-
- # basic input validation
- input_empty = np.size(x) == 0
- # Massage 'x' for processing.
- if input_empty:
- x = [np.array([])]
- else:
- x = cbook._reshape_2D(x, 'x')
- nx = len(x) # number of datasets
-
- # Process unit information
- # Unit conversion is done individually on each dataset
- self._process_unit_info(xdata=x[0], kwargs=kwargs)
- x = [self.convert_xunits(xi) for xi in x]
-
- if bin_range is not None:
- bin_range = self.convert_xunits(bin_range)
-
- # Check whether bins or range are given explicitly.
- binsgiven = (cbook.iterable(bins) or bin_range is not None)
-
- # We need to do to 'weights' what was done to 'x'
- if weights is not None:
- w = cbook._reshape_2D(weights, 'weights')
- else:
- w = [None] * nx
-
- if len(w) != nx:
- raise ValueError('weights should have the same shape as x')
-
- for xi, wi in zip(x, w):
- if wi is not None and len(wi) != len(xi):
- raise ValueError(
- 'weights should have the same shape as x')
-
- if color is None:
- color = [self._get_lines.get_next_color() for i in xrange(nx)]
- else:
- color = mcolors.to_rgba_array(color)
- if len(color) != nx:
- raise ValueError("color kwarg must have one color per dataset")
-
- # If bins are not specified either explicitly or via range,
- # we need to figure out the range required for all datasets,
- # and supply that to np.histogram.
- if not binsgiven and not input_empty:
- xmin = np.inf
- xmax = -np.inf
- for xi in x:
- if len(xi) > 0:
- xmin = min(xmin, xi.min())
- xmax = max(xmax, xi.max())
- bin_range = (xmin, xmax)
- density = bool(density) or bool(normed)
- if density and not stacked:
- hist_kwargs = dict(range=bin_range, density=density)
- else:
- hist_kwargs = dict(range=bin_range)
-
- # List to store all the top coordinates of the histograms
- tops = []
- mlast = None
- # Loop through datasets
- for i in xrange(nx):
- # this will automatically overwrite bins,
- # so that each histogram uses the same bins
- m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs)
- m = m.astype(float) # causes problems later if it's an int
- if mlast is None:
- mlast = np.zeros(len(bins)-1, m.dtype)
- if stacked:
- m += mlast
- mlast[:] = m
- tops.append(m)
-
- # If a stacked density plot, normalize so the area of all the stacked
- # histograms together is 1
- if stacked and density:
- db = np.diff(bins)
- for m in tops:
- m[:] = (m / db) / tops[-1].sum()
- if cumulative:
- slc = slice(None)
- if cbook.is_numlike(cumulative) and cumulative < 0:
- slc = slice(None, None, -1)
-
- if density:
- tops = [(m * np.diff(bins))[slc].cumsum()[slc] for m in tops]
- else:
- tops = [m[slc].cumsum()[slc] for m in tops]
-
- patches = []
-
- # Save autoscale state for later restoration; turn autoscaling
- # off so we can do it all a single time at the end, instead
- # of having it done by bar or fill and then having to be redone.
- _saved_autoscalex = self.get_autoscalex_on()
- _saved_autoscaley = self.get_autoscaley_on()
- self.set_autoscalex_on(False)
- self.set_autoscaley_on(False)
-
- if histtype.startswith('bar'):
-
- totwidth = np.diff(bins)
-
- if rwidth is not None:
- dr = np.clip(rwidth, 0, 1)
- elif (len(tops) > 1 and
- ((not stacked) or rcParams['_internal.classic_mode'])):
- dr = 0.8
- else:
- dr = 1.0
-
- if histtype == 'bar' and not stacked:
- width = dr * totwidth / nx
- dw = width
- boffset = -0.5 * dr * totwidth * (1 - 1 / nx)
- elif histtype == 'barstacked' or stacked:
- width = dr * totwidth
- boffset, dw = 0.0, 0.0
-
- if align == 'mid' or align == 'edge':
- boffset += 0.5 * totwidth
- elif align == 'right':
- boffset += totwidth
-
- if orientation == 'horizontal':
- _barfunc = self.barh
- bottom_kwarg = 'left'
- else: # orientation == 'vertical'
- _barfunc = self.bar
- bottom_kwarg = 'bottom'
-
- for m, c in zip(tops, color):
- if bottom is None:
- bottom = np.zeros(len(m))
- if stacked:
- height = m - bottom
- else:
- height = m
- patch = _barfunc(bins[:-1]+boffset, height, width,
- align='center', log=log,
- color=c, **{bottom_kwarg: bottom})
- patches.append(patch)
- if stacked:
- bottom[:] = m
- boffset += dw
-
- elif histtype.startswith('step'):
- # these define the perimeter of the polygon
- x = np.zeros(4 * len(bins) - 3)
- y = np.zeros(4 * len(bins) - 3)
-
- x[0:2*len(bins)-1:2], x[1:2*len(bins)-1:2] = bins, bins[:-1]
- x[2*len(bins)-1:] = x[1:2*len(bins)-1][::-1]
-
- if bottom is None:
- bottom = np.zeros(len(bins) - 1)
-
- y[1:2*len(bins)-1:2], y[2:2*len(bins):2] = bottom, bottom
- y[2*len(bins)-1:] = y[1:2*len(bins)-1][::-1]
-
- if log:
- if orientation == 'horizontal':
- self.set_xscale('log', nonposx='clip')
- logbase = self.xaxis._scale.base
- else: # orientation == 'vertical'
- self.set_yscale('log', nonposy='clip')
- logbase = self.yaxis._scale.base
-
- # Setting a minimum of 0 results in problems for log plots
- if np.min(bottom) > 0:
- minimum = np.min(bottom)
- elif density or weights is not None:
- # For data that is normed to form a probability density,
- # set to minimum data value / logbase
- # (gives 1 full tick-label unit for the lowest filled bin)
- ndata = np.array(tops)
- minimum = (np.min(ndata[ndata > 0])) / logbase
- else:
- # For non-normed (density = False) data,
- # set the min to 1 / log base,
- # again so that there is 1 full tick-label unit
- # for the lowest bin
- minimum = 1.0 / logbase
-
- y[0], y[-1] = minimum, minimum
- else:
- minimum = 0
-
- if align == 'left' or align == 'center':
- x -= 0.5*(bins[1]-bins[0])
- elif align == 'right':
- x += 0.5*(bins[1]-bins[0])
-
- # If fill kwarg is set, it will be passed to the patch collection,
- # overriding this
- fill = (histtype == 'stepfilled')
-
- xvals, yvals = [], []
- for m in tops:
- if stacked:
- # starting point for drawing polygon
- y[0] = y[1]
- # top of the previous polygon becomes the bottom
- y[2*len(bins)-1:] = y[1:2*len(bins)-1][::-1]
- # set the top of this polygon
- y[1:2*len(bins)-1:2], y[2:2*len(bins):2] = (m + bottom,
- m + bottom)
- if log:
- y[y < minimum] = minimum
- if orientation == 'horizontal':
- xvals.append(y.copy())
- yvals.append(x.copy())
- else:
- xvals.append(x.copy())
- yvals.append(y.copy())
-
- # stepfill is closed, step is not
- split = -1 if fill else 2 * len(bins)
- # add patches in reverse order so that when stacking,
- # items lower in the stack are plotted on top of
- # items higher in the stack
- for x, y, c in reversed(list(zip(xvals, yvals, color))):
- patches.append(self.fill(
- x[:split], y[:split],
- closed=True if fill else None,
- facecolor=c,
- edgecolor=None if fill else c,
- fill=fill if fill else None))
- for patch_list in patches:
- for patch in patch_list:
- if orientation == 'vertical':
- patch.sticky_edges.y.append(minimum)
- elif orientation == 'horizontal':
- patch.sticky_edges.x.append(minimum)
-
- # we return patches, so put it back in the expected order
- patches.reverse()
-
- self.set_autoscalex_on(_saved_autoscalex)
- self.set_autoscaley_on(_saved_autoscaley)
- self.autoscale_view()
-
- if label is None:
- labels = [None]
- elif isinstance(label, six.string_types):
- labels = [label]
- else:
- labels = [six.text_type(lab) for lab in label]
-
- for patch, lbl in zip_longest(patches, labels, fillvalue=None):
- if patch:
- p = patch[0]
- p.update(kwargs)
- if lbl is not None:
- p.set_label(lbl)
-
- for p in patch[1:]:
- p.update(kwargs)
- p.set_label('_nolegend_')
-
- if nx == 1:
- return tops[0], bins, cbook.silent_list('Patch', patches[0])
- else:
- return tops, bins, cbook.silent_list('Lists of Patches', patches)
-
- @_preprocess_data(replace_names=["x", "y", "weights"], label_namer=None)
- def hist2d(self, x, y, bins=10, range=None, normed=False, weights=None,
- cmin=None, cmax=None, **kwargs):
- """
- Make a 2D histogram plot.
-
- Parameters
- ----------
- x, y: array_like, shape (n, )
- Input values
-
- bins: [None | int | [int, int] | array_like | [array, array]]
-
- The bin specification:
-
- - If int, the number of bins for the two dimensions
- (nx=ny=bins).
-
- - If ``[int, int]``, the number of bins in each dimension
- (nx, ny = bins).
-
- - If array_like, the bin edges for the two dimensions
- (x_edges=y_edges=bins).
-
- - If ``[array, array]``, the bin edges in each dimension
- (x_edges, y_edges = bins).
-
- The default value is 10.
-
- range : array_like shape(2, 2), optional, default: None
- The leftmost and rightmost edges of the bins along each dimension
- (if not specified explicitly in the bins parameters): ``[[xmin,
- xmax], [ymin, ymax]]``. All values outside of this range will be
- considered outliers and not tallied in the histogram.
-
- normed : boolean, optional, default: False
- Normalize histogram.
-
- weights : array_like, shape (n, ), optional, default: None
- An array of values w_i weighing each sample (x_i, y_i).
-
- cmin : scalar, optional, default: None
- All bins that has count less than cmin will not be displayed and
- these count values in the return value count histogram will also
- be set to nan upon return
-
- cmax : scalar, optional, default: None
- All bins that has count more than cmax will not be displayed (set
- to none before passing to imshow) and these count values in the
- return value count histogram will also be set to nan upon return
-
- Returns
- -------
- h : 2D array
- The bi-dimensional histogram of samples x and y. Values in x are
- histogrammed along the first dimension and values in y are
- histogrammed along the second dimension.
- xedges : 1D array
- The bin edges along the x axis.
- yedges : 1D array
- The bin edges along the y axis.
- image : AxesImage
-
- Other Parameters
- ----------------
- cmap : Colormap or str, optional
- A `.colors.Colormap` instance. If not set, use rc settings.
-
- norm : Normalize, optional
- A `.colors.Normalize` instance is used to
- scale luminance data to ``[0, 1]``. If not set, defaults to
- `.colors.Normalize()`.
-
- vmin/vmax : None or scalar, optional
- Arguments passed to the `~.colors.Normalize` instance.
-
- alpha : ``0 <= scalar <= 1`` or ``None``, optional
- The alpha blending value.
-
- See also
- --------
- hist : 1D histogram plotting
-
- Notes
- -----
- - Currently ``hist2d`` calculates it's own axis limits, and any limits
- previously set are ignored.
- - Rendering the histogram with a logarithmic color scale is
- accomplished by passing a `.colors.LogNorm` instance to the *norm*
- keyword argument. Likewise, power-law normalization (similar
- in effect to gamma correction) can be accomplished with
- `.colors.PowerNorm`.
- """
-
- h, xedges, yedges = np.histogram2d(x, y, bins=bins, range=range,
- normed=normed, weights=weights)
-
- if cmin is not None:
- h[h < cmin] = None
- if cmax is not None:
- h[h > cmax] = None
-
- pc = self.pcolorfast(xedges, yedges, h.T, **kwargs)
- self.set_xlim(xedges[0], xedges[-1])
- self.set_ylim(yedges[0], yedges[-1])
-
- return h, xedges, yedges, pc
-
- @_preprocess_data(replace_names=["x"], label_namer=None)
- @docstring.dedent_interpd
- def psd(self, x, NFFT=None, Fs=None, Fc=None, detrend=None,
- window=None, noverlap=None, pad_to=None,
- sides=None, scale_by_freq=None, return_line=None, **kwargs):
- r"""
- Plot the power spectral density.
-
- Call signature::
-
- psd(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
- window=mlab.window_hanning, noverlap=0, pad_to=None,
- sides='default', scale_by_freq=None, return_line=None, **kwargs)
-
- The power spectral density :math:`P_{xx}` by Welch's average
- periodogram method. The vector *x* is divided into *NFFT* length
- segments. Each segment is detrended by function *detrend* and
- windowed by function *window*. *noverlap* gives the length of
- the overlap between segments. The :math:`|\mathrm{fft}(i)|^2`
- of each segment :math:`i` are averaged to compute :math:`P_{xx}`,
- with a scaling to correct for power loss due to windowing.
-
- If len(*x*) < *NFFT*, it will be zero padded to *NFFT*.
-
- Parameters
- ----------
- x : 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(PSD)s
-
- noverlap : integer
- The number of points of overlap between segments.
- The default value is 0 (no overlap).
-
- Fc : integer
- The center frequency of *x* (defaults to 0), which offsets
- the x extents of the plot to reflect the frequency range used
- when a signal is acquired and then filtered and downsampled to
- baseband.
-
- return_line : bool
- Whether to include the line object plotted in the returned values.
- Default is False.
-
- Returns
- -------
- Pxx : 1-D array
- The values for the power spectrum `P_{xx}` before scaling
- (real valued)
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *Pxx*
-
- line : a :class:`~matplotlib.lines.Line2D` instance
- The line created by this function.
- Only returned if *return_line* is True.
-
- Other Parameters
- ----------------
- **kwargs :
- Keyword arguments control the :class:`~matplotlib.lines.Line2D`
- properties:
-
- %(Line2D)s
-
- See Also
- --------
- :func:`specgram`
- :func:`specgram` differs in the default overlap; in not returning
- the mean of the segment periodograms; in returning the times of the
- segments; and in plotting a colormap instead of a line.
-
- :func:`magnitude_spectrum`
- :func:`magnitude_spectrum` plots the magnitude spectrum.
-
- :func:`csd`
- :func:`csd` plots the spectral density between two signals.
-
- Notes
- -----
- For plotting, the power is plotted as
- :math:`10\log_{10}(P_{xx})` for decibels, though *Pxx* itself
- is returned.
-
- References
- ----------
- Bendat & Piersol -- Random Data: Analysis and Measurement Procedures,
- John Wiley & Sons (1986)
- """
- if not self._hold:
- self.cla()
-
- if Fc is None:
- Fc = 0
-
- pxx, freqs = mlab.psd(x=x, NFFT=NFFT, Fs=Fs, detrend=detrend,
- window=window, noverlap=noverlap, pad_to=pad_to,
- sides=sides, scale_by_freq=scale_by_freq)
- freqs += Fc
-
- if scale_by_freq in (None, True):
- psd_units = 'dB/Hz'
- else:
- psd_units = 'dB'
-
- line = self.plot(freqs, 10 * np.log10(pxx), **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Power Spectral Density (%s)' % psd_units)
- self.grid(True)
- vmin, vmax = self.viewLim.intervaly
- intv = vmax - vmin
- logi = int(np.log10(intv))
- if logi == 0:
- logi = .1
- step = 10 * logi
- ticks = np.arange(math.floor(vmin), math.ceil(vmax) + 1, step)
- self.set_yticks(ticks)
-
- if return_line is None or not return_line:
- return pxx, freqs
- else:
- return pxx, freqs, line
-
- @_preprocess_data(replace_names=["x", "y"], label_namer="y")
- @docstring.dedent_interpd
- def csd(self, x, y, NFFT=None, Fs=None, Fc=None, detrend=None,
- window=None, noverlap=None, pad_to=None,
- sides=None, scale_by_freq=None, return_line=None, **kwargs):
- """
- Plot the cross-spectral density.
-
- Call signature::
-
- csd(x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
- window=mlab.window_hanning, noverlap=0, pad_to=None,
- sides='default', scale_by_freq=None, return_line=None, **kwargs)
-
- The cross spectral density :math:`P_{xy}` by Welch's average
- periodogram method. The vectors *x* and *y* are divided into
- *NFFT* length segments. Each segment is detrended by function
- *detrend* and windowed by function *window*. *noverlap* gives
- the length of the overlap between segments. The product of
- the direct FFTs of *x* and *y* are averaged over each segment
- to compute :math:`P_{xy}`, with a scaling to correct for power
- loss due to windowing.
-
- If len(*x*) < *NFFT* or len(*y*) < *NFFT*, they will be zero
- padded to *NFFT*.
-
- Parameters
- ----------
- x, y : 1-D arrays or sequences
- Arrays or sequences containing the data
-
- %(Spectral)s
-
- %(PSD)s
-
- noverlap : integer
- The number of points of overlap between segments.
- The default value is 0 (no overlap).
-
- Fc : integer
- The center frequency of *x* (defaults to 0), which offsets
- the x extents of the plot to reflect the frequency range used
- when a signal is acquired and then filtered and downsampled to
- baseband.
-
- return_line : bool
- Whether to include the line object plotted in the returned values.
- Default is False.
-
- Returns
- -------
- Pxy : 1-D array
- The values for the cross spectrum `P_{xy}` before scaling
- (complex valued)
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *Pxy*
-
- line : a :class:`~matplotlib.lines.Line2D` instance
- The line created by this function.
- Only returned if *return_line* is True.
-
- Other Parameters
- ----------------
- **kwargs :
- Keyword arguments control the :class:`~matplotlib.lines.Line2D`
- properties:
-
- %(Line2D)s
-
- See Also
- --------
- :func:`psd`
- :func:`psd` is the equivalent to setting y=x.
-
- Notes
- -----
- For plotting, the power is plotted as
- :math:`10\\log_{10}(P_{xy})` for decibels, though `P_{xy}` itself
- is returned.
-
- References
- ----------
- Bendat & Piersol -- Random Data: Analysis and Measurement Procedures,
- John Wiley & Sons (1986)
- """
- if not self._hold:
- self.cla()
-
- if Fc is None:
- Fc = 0
-
- pxy, freqs = mlab.csd(x=x, y=y, NFFT=NFFT, Fs=Fs, detrend=detrend,
- window=window, noverlap=noverlap, pad_to=pad_to,
- sides=sides, scale_by_freq=scale_by_freq)
- # pxy is complex
- freqs += Fc
-
- line = self.plot(freqs, 10 * np.log10(np.abs(pxy)), **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Cross Spectrum Magnitude (dB)')
- self.grid(True)
- vmin, vmax = self.viewLim.intervaly
-
- intv = vmax - vmin
- step = 10 * int(np.log10(intv))
-
- ticks = np.arange(math.floor(vmin), math.ceil(vmax) + 1, step)
- self.set_yticks(ticks)
-
- if return_line is None or not return_line:
- return pxy, freqs
- else:
- return pxy, freqs, line
-
- @_preprocess_data(replace_names=["x"], label_namer=None)
- @docstring.dedent_interpd
- def magnitude_spectrum(self, x, Fs=None, Fc=None, window=None,
- pad_to=None, sides=None, scale=None,
- **kwargs):
- """
- Plot the magnitude spectrum.
-
- Call signature::
-
- magnitude_spectrum(x, Fs=2, Fc=0, window=mlab.window_hanning,
- pad_to=None, sides='default', **kwargs)
-
- Compute the magnitude spectrum of *x*. Data is padded to a
- length of *pad_to* and the windowing function *window* is applied to
- the signal.
-
- Parameters
- ----------
- x : 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(Single_Spectrum)s
-
- scale : [ 'default' | 'linear' | 'dB' ]
- The scaling of the values in the *spec*. 'linear' is no scaling.
- 'dB' returns the values in dB scale, i.e., the dB amplitude
- (20 * log10). 'default' is 'linear'.
-
- Fc : integer
- The center frequency of *x* (defaults to 0), which offsets
- the x extents of the plot to reflect the frequency range used
- when a signal is acquired and then filtered and downsampled to
- baseband.
-
- Returns
- -------
- spectrum : 1-D array
- The values for the magnitude spectrum before scaling (real valued)
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *spectrum*
-
- line : a :class:`~matplotlib.lines.Line2D` instance
- The line created by this function
-
- Other Parameters
- ----------------
- **kwargs :
- Keyword arguments control the :class:`~matplotlib.lines.Line2D`
- properties:
-
- %(Line2D)s
-
- See Also
- --------
- :func:`psd`
- :func:`psd` plots the power spectral density.`.
-
- :func:`angle_spectrum`
- :func:`angle_spectrum` plots the angles of the corresponding
- frequencies.
-
- :func:`phase_spectrum`
- :func:`phase_spectrum` plots the phase (unwrapped angle) of the
- corresponding frequencies.
-
- :func:`specgram`
- :func:`specgram` can plot the magnitude spectrum of segments within
- the signal in a colormap.
-
- Notes
- -----
- .. [Notes section required for data comment. See #10189.]
-
- """
- if not self._hold:
- self.cla()
-
- if Fc is None:
- Fc = 0
-
- if scale is None or scale == 'default':
- scale = 'linear'
-
- spec, freqs = mlab.magnitude_spectrum(x=x, Fs=Fs, window=window,
- pad_to=pad_to, sides=sides)
- freqs += Fc
-
- if scale == 'linear':
- Z = spec
- yunits = 'energy'
- elif scale == 'dB':
- Z = 20. * np.log10(spec)
- yunits = 'dB'
- else:
- raise ValueError('Unknown scale %s', scale)
-
- lines = self.plot(freqs, Z, **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Magnitude (%s)' % yunits)
-
- return spec, freqs, lines[0]
-
- @_preprocess_data(replace_names=["x"], label_namer=None)
- @docstring.dedent_interpd
- def angle_spectrum(self, x, Fs=None, Fc=None, window=None,
- pad_to=None, sides=None, **kwargs):
- """
- Plot the angle spectrum.
-
- Call signature::
-
- angle_spectrum(x, Fs=2, Fc=0, window=mlab.window_hanning,
- pad_to=None, sides='default', **kwargs)
-
- Compute the angle spectrum (wrapped phase spectrum) of *x*.
- Data is padded to a length of *pad_to* and the windowing function
- *window* is applied to the signal.
-
- Parameters
- ----------
- x : 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(Single_Spectrum)s
-
- Fc : integer
- The center frequency of *x* (defaults to 0), which offsets
- the x extents of the plot to reflect the frequency range used
- when a signal is acquired and then filtered and downsampled to
- baseband.
-
- Returns
- -------
- spectrum : 1-D array
- The values for the angle spectrum in radians (real valued)
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *spectrum*
-
- line : a :class:`~matplotlib.lines.Line2D` instance
- The line created by this function
-
- Other Parameters
- ----------------
- **kwargs :
- Keyword arguments control the :class:`~matplotlib.lines.Line2D`
- properties:
-
- %(Line2D)s
-
- See Also
- --------
- :func:`magnitude_spectrum`
- :func:`angle_spectrum` plots the magnitudes of the corresponding
- frequencies.
-
- :func:`phase_spectrum`
- :func:`phase_spectrum` plots the unwrapped version of this
- function.
-
- :func:`specgram`
- :func:`specgram` can plot the angle spectrum of segments within the
- signal in a colormap.
-
- Notes
- -----
- .. [Notes section required for data comment. See #10189.]
-
- """
- if not self._hold:
- self.cla()
-
- if Fc is None:
- Fc = 0
-
- spec, freqs = mlab.angle_spectrum(x=x, Fs=Fs, window=window,
- pad_to=pad_to, sides=sides)
- freqs += Fc
-
- lines = self.plot(freqs, spec, **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Angle (radians)')
-
- return spec, freqs, lines[0]
-
- @_preprocess_data(replace_names=["x"], label_namer=None)
- @docstring.dedent_interpd
- def phase_spectrum(self, x, Fs=None, Fc=None, window=None,
- pad_to=None, sides=None, **kwargs):
- """
- Plot the phase spectrum.
-
- Call signature::
-
- phase_spectrum(x, Fs=2, Fc=0, window=mlab.window_hanning,
- pad_to=None, sides='default', **kwargs)
-
- Compute the phase spectrum (unwrapped angle spectrum) of *x*.
- Data is padded to a length of *pad_to* and the windowing function
- *window* is applied to the signal.
-
- Parameters
- ----------
- x : 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(Single_Spectrum)s
-
- Fc : integer
- The center frequency of *x* (defaults to 0), which offsets
- the x extents of the plot to reflect the frequency range used
- when a signal is acquired and then filtered and downsampled to
- baseband.
-
- Returns
- -------
- spectrum : 1-D array
- The values for the phase spectrum in radians (real valued)
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *spectrum*
-
- line : a :class:`~matplotlib.lines.Line2D` instance
- The line created by this function
-
- Other Parameters
- ----------------
- **kwargs :
- Keyword arguments control the :class:`~matplotlib.lines.Line2D`
- properties:
-
- %(Line2D)s
-
- See Also
- --------
- :func:`magnitude_spectrum`
- :func:`magnitude_spectrum` plots the magnitudes of the
- corresponding frequencies.
-
- :func:`angle_spectrum`
- :func:`angle_spectrum` plots the wrapped version of this function.
-
- :func:`specgram`
- :func:`specgram` can plot the phase spectrum of segments within the
- signal in a colormap.
-
- Notes
- -----
- .. [Notes section required for data comment. See #10189.]
-
- """
- if not self._hold:
- self.cla()
-
- if Fc is None:
- Fc = 0
-
- spec, freqs = mlab.phase_spectrum(x=x, Fs=Fs, window=window,
- pad_to=pad_to, sides=sides)
- freqs += Fc
-
- lines = self.plot(freqs, spec, **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Phase (radians)')
-
- return spec, freqs, lines[0]
-
- @_preprocess_data(replace_names=["x", "y"], label_namer=None)
- @docstring.dedent_interpd
- def cohere(self, x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
- window=mlab.window_hanning, noverlap=0, pad_to=None,
- sides='default', scale_by_freq=None, **kwargs):
- """
- Plot the coherence between *x* and *y*.
-
- Plot the coherence between *x* and *y*. Coherence is the
- normalized cross spectral density:
-
- .. math::
-
- C_{xy} = \\frac{|P_{xy}|^2}{P_{xx}P_{yy}}
-
- Parameters
- ----------
- %(Spectral)s
-
- %(PSD)s
-
- noverlap : integer
- The number of points of overlap between blocks. The
- default value is 0 (no overlap).
-
- Fc : integer
- The center frequency of *x* (defaults to 0), which offsets
- the x extents of the plot to reflect the frequency range used
- when a signal is acquired and then filtered and downsampled to
- baseband.
-
-
- Returns
- -------
- The return value is a tuple (*Cxy*, *f*), where *f* are the
- frequencies of the coherence vector.
-
- kwargs are applied to the lines.
-
- Other Parameters
- ----------------
- **kwargs :
- Keyword arguments control the :class:`~matplotlib.lines.Line2D`
- properties:
-
- %(Line2D)s
-
- References
- ----------
- Bendat & Piersol -- Random Data: Analysis and Measurement Procedures,
- John Wiley & Sons (1986)
- """
- if not self._hold:
- self.cla()
- cxy, freqs = mlab.cohere(x=x, y=y, NFFT=NFFT, Fs=Fs, detrend=detrend,
- window=window, noverlap=noverlap,
- scale_by_freq=scale_by_freq)
- freqs += Fc
-
- self.plot(freqs, cxy, **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Coherence')
- self.grid(True)
-
- return cxy, freqs
-
- @_preprocess_data(replace_names=["x"], label_namer=None)
- @docstring.dedent_interpd
- def specgram(self, x, NFFT=None, Fs=None, Fc=None, detrend=None,
- window=None, noverlap=None,
- cmap=None, xextent=None, pad_to=None, sides=None,
- scale_by_freq=None, mode=None, scale=None,
- vmin=None, vmax=None, **kwargs):
- """
- Plot a spectrogram.
-
- Call signature::
-
- specgram(x, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
- window=mlab.window_hanning, noverlap=128,
- cmap=None, xextent=None, pad_to=None, sides='default',
- scale_by_freq=None, mode='default', scale='default',
- **kwargs)
-
- Compute and plot a spectrogram of data in *x*. Data are split into
- *NFFT* length segments and the spectrum of each section is
- computed. The windowing function *window* is applied to each
- segment, and the amount of overlap of each segment is
- specified with *noverlap*. The spectrogram is plotted as a colormap
- (using imshow).
-
- Parameters
- ----------
- x : 1-D array or sequence
- Array or sequence containing the data.
-
- %(Spectral)s
-
- %(PSD)s
-
- mode : [ 'default' | 'psd' | 'magnitude' | 'angle' | 'phase' ]
- What sort of spectrum to use. Default is 'psd', which takes
- the power spectral density. 'complex' returns the complex-valued
- frequency spectrum. 'magnitude' returns the magnitude spectrum.
- 'angle' returns the phase spectrum without unwrapping. 'phase'
- returns the phase spectrum with unwrapping.
-
- noverlap : integer
- The number of points of overlap between blocks. The
- default value is 128.
-
- scale : [ 'default' | 'linear' | 'dB' ]
- The scaling of the values in the *spec*. 'linear' is no scaling.
- 'dB' returns the values in dB scale. When *mode* is 'psd',
- this is dB power (10 * log10). Otherwise this is dB amplitude
- (20 * log10). 'default' is 'dB' if *mode* is 'psd' or
- 'magnitude' and 'linear' otherwise. This must be 'linear'
- if *mode* is 'angle' or 'phase'.
-
- Fc : integer
- The center frequency of *x* (defaults to 0), which offsets
- the x extents of the plot to reflect the frequency range used
- when a signal is acquired and then filtered and downsampled to
- baseband.
-
- cmap :
- A :class:`matplotlib.colors.Colormap` instance; if *None*, use
- default determined by rc
-
- xextent : [None | (xmin, xmax)]
- The image extent along the x-axis. The default sets *xmin* to the
- left border of the first bin (*spectrum* column) and *xmax* to the
- right border of the last bin. Note that for *noverlap>0* the width
- of the bins is smaller than those of the segments.
-
- **kwargs :
- Additional kwargs are passed on to imshow which makes the
- specgram image
-
- Returns
- -------
- spectrum : 2-D array
- Columns are the periodograms of successive segments.
-
- freqs : 1-D array
- The frequencies corresponding to the rows in *spectrum*.
-
- t : 1-D array
- The times corresponding to midpoints of segments (i.e., the columns
- in *spectrum*).
-
- im : instance of class :class:`~matplotlib.image.AxesImage`
- The image created by imshow containing the spectrogram
-
- See Also
- --------
- :func:`psd`
- :func:`psd` differs in the default overlap; in returning the mean
- of the segment periodograms; in not returning times; and in
- generating a line plot instead of colormap.
-
- :func:`magnitude_spectrum`
- A single spectrum, similar to having a single segment when *mode*
- is 'magnitude'. Plots a line instead of a colormap.
-
- :func:`angle_spectrum`
- A single spectrum, similar to having a single segment when *mode*
- is 'angle'. Plots a line instead of a colormap.
-
- :func:`phase_spectrum`
- A single spectrum, similar to having a single segment when *mode*
- is 'phase'. Plots a line instead of a colormap.
-
- Notes
- -----
- The parameters *detrend* and *scale_by_freq* do only apply when *mode*
- is set to 'psd'.
- """
- if not self._hold:
- self.cla()
-
- if NFFT is None:
- NFFT = 256 # same default as in mlab.specgram()
- if Fc is None:
- Fc = 0 # same default as in mlab._spectral_helper()
- if noverlap is None:
- noverlap = 128 # same default as in mlab.specgram()
-
- if mode == 'complex':
- raise ValueError('Cannot plot a complex specgram')
-
- if scale is None or scale == 'default':
- if mode in ['angle', 'phase']:
- scale = 'linear'
- else:
- scale = 'dB'
- elif mode in ['angle', 'phase'] and scale == 'dB':
- raise ValueError('Cannot use dB scale with angle or phase mode')
-
- spec, freqs, t = mlab.specgram(x=x, NFFT=NFFT, Fs=Fs,
- detrend=detrend, window=window,
- noverlap=noverlap, pad_to=pad_to,
- sides=sides,
- scale_by_freq=scale_by_freq,
- mode=mode)
-
- if scale == 'linear':
- Z = spec
- elif scale == 'dB':
- if mode is None or mode == 'default' or mode == 'psd':
- Z = 10. * np.log10(spec)
- else:
- Z = 20. * np.log10(spec)
- else:
- raise ValueError('Unknown scale %s', scale)
-
- Z = np.flipud(Z)
-
- if xextent is None:
- # padding is needed for first and last segment:
- pad_xextent = (NFFT-noverlap) / Fs / 2
- xextent = np.min(t) - pad_xextent, np.max(t) + pad_xextent
- xmin, xmax = xextent
- freqs += Fc
- extent = xmin, xmax, freqs[0], freqs[-1]
- im = self.imshow(Z, cmap, extent=extent, vmin=vmin, vmax=vmax,
- **kwargs)
- self.axis('auto')
-
- return spec, freqs, t, im
-
- def spy(self, Z, precision=0, marker=None, markersize=None,
- aspect='equal', origin="upper", **kwargs):
- """
- Plot the sparsity pattern on a 2-D array.
-
- ``spy(Z)`` plots the sparsity pattern of the 2-D array *Z*.
-
- Parameters
- ----------
-
- Z : sparse array (n, m)
- The array to be plotted.
-
- precision : float, optional, default: 0
- If *precision* is 0, any non-zero value will be plotted; else,
- values of :math:`|Z| > precision` will be plotted.
-
- For :class:`scipy.sparse.spmatrix` instances, there is a special
- case: if *precision* is 'present', any value present in the array
- will be plotted, even if it is identically zero.
-
- origin : ["upper", "lower"], optional, default: "upper"
- Place the [0,0] index of the array in the upper left or lower left
- corner of the axes.
-
- aspect : ['auto' | 'equal' | scalar], optional, default: "equal"
-
- If 'equal', and `extent` is None, changes the axes aspect ratio to
- match that of the image. If `extent` is not `None`, the axes
- aspect ratio is changed to match that of the extent.
-
-
- If 'auto', changes the image aspect ratio to match that of the
- axes.
-
- If None, default to rc ``image.aspect`` value.
-
- Two plotting styles are available: image or marker. Both
- are available for full arrays, but only the marker style
- works for :class:`scipy.sparse.spmatrix` instances.
-
- If *marker* and *markersize* are *None*, an image will be
- returned and any remaining kwargs are passed to
- :func:`~matplotlib.pyplot.imshow`; else, a
- :class:`~matplotlib.lines.Line2D` object will be returned with
- the value of marker determining the marker type, and any
- remaining kwargs passed to the
- :meth:`~matplotlib.axes.Axes.plot` method.
-
- If *marker* and *markersize* are *None*, useful kwargs include:
-
- * *cmap*
- * *alpha*
-
- See also
- --------
- imshow : for image options.
- plot : for plotting options
- """
- if marker is None and markersize is None and hasattr(Z, 'tocoo'):
- marker = 's'
- if marker is None and markersize is None:
- Z = np.asarray(Z)
- mask = np.abs(Z) > precision
-
- if 'cmap' not in kwargs:
- kwargs['cmap'] = mcolors.ListedColormap(['w', 'k'],
- name='binary')
- nr, nc = Z.shape
- extent = [-0.5, nc - 0.5, nr - 0.5, -0.5]
- ret = self.imshow(mask, interpolation='nearest', aspect=aspect,
- extent=extent, origin=origin, **kwargs)
- else:
- if hasattr(Z, 'tocoo'):
- c = Z.tocoo()
- if precision == 'present':
- y = c.row
- x = c.col
- else:
- nonzero = np.abs(c.data) > precision
- y = c.row[nonzero]
- x = c.col[nonzero]
- else:
- Z = np.asarray(Z)
- nonzero = np.abs(Z) > precision
- y, x = np.nonzero(nonzero)
- if marker is None:
- marker = 's'
- if markersize is None:
- markersize = 10
- marks = mlines.Line2D(x, y, linestyle='None',
- marker=marker, markersize=markersize, **kwargs)
- self.add_line(marks)
- nr, nc = Z.shape
- self.set_xlim(xmin=-0.5, xmax=nc - 0.5)
- self.set_ylim(ymin=nr - 0.5, ymax=-0.5)
- self.set_aspect(aspect)
- ret = marks
- self.title.set_y(1.05)
- self.xaxis.tick_top()
- self.xaxis.set_ticks_position('both')
- self.xaxis.set_major_locator(mticker.MaxNLocator(nbins=9,
- steps=[1, 2, 5, 10],
- integer=True))
- self.yaxis.set_major_locator(mticker.MaxNLocator(nbins=9,
- steps=[1, 2, 5, 10],
- integer=True))
- return ret
-
- def matshow(self, Z, **kwargs):
- """
- Plot the values of a 2D matrix or array as color-coded image.
-
- The matrix will be shown the way it would be printed, with the first
- row at the top. Row and column numbering is zero-based.
-
- Parameters
- ----------
- Z : array-like(N, M)
- The matrix to be displayed.
-
- Returns
- -------
- image : `~matplotlib.image.AxesImage`
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.axes.Axes.imshow` arguments
-
- See Also
- --------
- imshow : More general function to plot data on a 2D regular raster.
-
- Notes
- -----
- This is just a convenience function wrapping `.imshow` to set useful
- defaults for a displaying a matrix. In particular:
-
- - Set ``origin='upper'``.
- - Set ``interpolation='nearest'``.
- - Set ``aspect='equal'``.
- - Ticks are placed to the left and above.
- - Ticks are formatted to show integer indices.
-
- """
- Z = np.asanyarray(Z)
- nr, nc = Z.shape
- kw = {'origin': 'upper',
- 'interpolation': 'nearest',
- 'aspect': 'equal'} # (already the imshow default)
- kw.update(kwargs)
- im = self.imshow(Z, **kw)
- self.title.set_y(1.05)
- self.xaxis.tick_top()
- self.xaxis.set_ticks_position('both')
- self.xaxis.set_major_locator(mticker.MaxNLocator(nbins=9,
- steps=[1, 2, 5, 10],
- integer=True))
- self.yaxis.set_major_locator(mticker.MaxNLocator(nbins=9,
- steps=[1, 2, 5, 10],
- integer=True))
- return im
-
- @_preprocess_data(replace_names=["dataset"], label_namer=None)
- def violinplot(self, dataset, positions=None, vert=True, widths=0.5,
- showmeans=False, showextrema=True, showmedians=False,
- points=100, bw_method=None):
- """
- Make a violin plot.
-
- Make a violin plot for each column of *dataset* or each vector in
- sequence *dataset*. Each filled area extends to represent the
- entire data range, with optional lines at the mean, the median,
- the minimum, and the maximum.
-
- Parameters
- ----------
- dataset : Array or a sequence of vectors.
- The input data.
-
- positions : array-like, default = [1, 2, ..., n]
- Sets the positions of the violins. The ticks and limits are
- automatically set to match the positions.
-
- vert : bool, default = True.
- If true, creates a vertical violin plot.
- Otherwise, creates a horizontal violin plot.
-
- widths : array-like, default = 0.5
- Either a scalar or a vector that sets the maximal width of
- each violin. The default is 0.5, which uses about half of the
- available horizontal space.
-
- showmeans : bool, default = False
- If `True`, will toggle rendering of the means.
-
- showextrema : bool, default = True
- If `True`, will toggle rendering of the extrema.
-
- showmedians : bool, default = False
- If `True`, will toggle rendering of the medians.
-
- points : scalar, default = 100
- Defines the number of points to evaluate each of the
- gaussian kernel density estimations at.
-
- bw_method : str, scalar or callable, optional
- The method used to calculate the estimator bandwidth. This can be
- 'scott', 'silverman', a scalar constant or a callable. If a
- scalar, this will be used directly as `kde.factor`. If a
- callable, it should take a `GaussianKDE` instance as its only
- parameter and return a scalar. If None (default), 'scott' is used.
-
- Returns
- -------
-
- result : dict
- A dictionary mapping each component of the violinplot to a
- list of the corresponding collection instances created. The
- dictionary has the following keys:
-
- - ``bodies``: A list of the
- :class:`matplotlib.collections.PolyCollection` instances
- containing the filled area of each violin.
-
- - ``cmeans``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the mean values of each of the
- violin's distribution.
-
- - ``cmins``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the bottom of each violin's
- distribution.
-
- - ``cmaxes``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the top of each violin's
- distribution.
-
- - ``cbars``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the centers of each violin's
- distribution.
-
- - ``cmedians``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the median values of each of the
- violin's distribution.
-
- Notes
- -----
- .. [Notes section required for data comment. See #10189.]
-
- """
-
- def _kde_method(X, coords):
- # fallback gracefully if the vector contains only one value
- if np.all(X[0] == X):
- return (X[0] == coords).astype(float)
- kde = mlab.GaussianKDE(X, bw_method)
- return kde.evaluate(coords)
-
- vpstats = cbook.violin_stats(dataset, _kde_method, points=points)
- return self.violin(vpstats, positions=positions, vert=vert,
- widths=widths, showmeans=showmeans,
- showextrema=showextrema, showmedians=showmedians)
-
- def violin(self, vpstats, positions=None, vert=True, widths=0.5,
- showmeans=False, showextrema=True, showmedians=False):
- """Drawing function for violin plots.
-
- Draw a violin plot for each column of `vpstats`. Each filled area
- extends to represent the entire data range, with optional lines at the
- mean, the median, the minimum, and the maximum.
-
- Parameters
- ----------
-
- vpstats : list of dicts
- A list of dictionaries containing stats for each violin plot.
- Required keys are:
-
- - ``coords``: A list of scalars containing the coordinates that
- the violin's kernel density estimate were evaluated at.
-
- - ``vals``: A list of scalars containing the values of the
- kernel density estimate at each of the coordinates given
- in *coords*.
-
- - ``mean``: The mean value for this violin's dataset.
-
- - ``median``: The median value for this violin's dataset.
-
- - ``min``: The minimum value for this violin's dataset.
-
- - ``max``: The maximum value for this violin's dataset.
-
- positions : array-like, default = [1, 2, ..., n]
- Sets the positions of the violins. The ticks and limits are
- automatically set to match the positions.
-
- vert : bool, default = True.
- If true, plots the violins veritcally.
- Otherwise, plots the violins horizontally.
-
- widths : array-like, default = 0.5
- Either a scalar or a vector that sets the maximal width of
- each violin. The default is 0.5, which uses about half of the
- available horizontal space.
-
- showmeans : bool, default = False
- If true, will toggle rendering of the means.
-
- showextrema : bool, default = True
- If true, will toggle rendering of the extrema.
-
- showmedians : bool, default = False
- If true, will toggle rendering of the medians.
-
- Returns
- -------
- result : dict
- A dictionary mapping each component of the violinplot to a
- list of the corresponding collection instances created. The
- dictionary has the following keys:
-
- - ``bodies``: A list of the
- :class:`matplotlib.collections.PolyCollection` instances
- containing the filled area of each violin.
-
- - ``cmeans``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the mean values of each of the
- violin's distribution.
-
- - ``cmins``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the bottom of each violin's
- distribution.
-
- - ``cmaxes``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the top of each violin's
- distribution.
-
- - ``cbars``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the centers of each violin's
- distribution.
-
- - ``cmedians``: A
- :class:`matplotlib.collections.LineCollection` instance
- created to identify the median values of each of the
- violin's distribution.
-
- """
-
- # Statistical quantities to be plotted on the violins
- means = []
- mins = []
- maxes = []
- medians = []
-
- # Collections to be returned
- artists = {}
-
- N = len(vpstats)
- datashape_message = ("List of violinplot statistics and `{0}` "
- "values must have the same length")
-
- # Validate positions
- if positions is None:
- positions = range(1, N + 1)
- elif len(positions) != N:
- raise ValueError(datashape_message.format("positions"))
-
- # Validate widths
- if np.isscalar(widths):
- widths = [widths] * N
- elif len(widths) != N:
- raise ValueError(datashape_message.format("widths"))
-
- # Calculate ranges for statistics lines
- pmins = -0.25 * np.array(widths) + positions
- pmaxes = 0.25 * np.array(widths) + positions
-
- # Check whether we are rendering vertically or horizontally
- if vert:
- fill = self.fill_betweenx
- perp_lines = self.hlines
- par_lines = self.vlines
- else:
- fill = self.fill_between
- perp_lines = self.vlines
- par_lines = self.hlines
-
- if rcParams['_internal.classic_mode']:
- fillcolor = 'y'
- edgecolor = 'r'
- else:
- fillcolor = edgecolor = self._get_lines.get_next_color()
-
- # Render violins
- bodies = []
- for stats, pos, width in zip(vpstats, positions, widths):
- # The 0.5 factor reflects the fact that we plot from v-p to
- # v+p
- vals = np.array(stats['vals'])
- vals = 0.5 * width * vals / vals.max()
- bodies += [fill(stats['coords'],
- -vals + pos,
- vals + pos,
- facecolor=fillcolor,
- alpha=0.3)]
- means.append(stats['mean'])
- mins.append(stats['min'])
- maxes.append(stats['max'])
- medians.append(stats['median'])
- artists['bodies'] = bodies
-
- # Render means
- if showmeans:
- artists['cmeans'] = perp_lines(means, pmins, pmaxes,
- colors=edgecolor)
-
- # Render extrema
- if showextrema:
- artists['cmaxes'] = perp_lines(maxes, pmins, pmaxes,
- colors=edgecolor)
- artists['cmins'] = perp_lines(mins, pmins, pmaxes,
- colors=edgecolor)
- artists['cbars'] = par_lines(positions, mins, maxes,
- colors=edgecolor)
-
- # Render medians
- if showmedians:
- artists['cmedians'] = perp_lines(medians,
- pmins,
- pmaxes,
- colors=edgecolor)
-
- return artists
-
- def tricontour(self, *args, **kwargs):
- return mtri.tricontour(self, *args, **kwargs)
- tricontour.__doc__ = mtri.tricontour.__doc__
-
- def tricontourf(self, *args, **kwargs):
- return mtri.tricontourf(self, *args, **kwargs)
- tricontourf.__doc__ = mtri.tricontour.__doc__
-
- def tripcolor(self, *args, **kwargs):
- return mtri.tripcolor(self, *args, **kwargs)
- tripcolor.__doc__ = mtri.tripcolor.__doc__
-
- def triplot(self, *args, **kwargs):
- return mtri.triplot(self, *args, **kwargs)
- triplot.__doc__ = mtri.triplot.__doc__
diff --git a/contrib/python/matplotlib/py2/matplotlib/axes/_base.py b/contrib/python/matplotlib/py2/matplotlib/axes/_base.py
deleted file mode 100644
index 5265f11270..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/axes/_base.py
+++ /dev/null
@@ -1,4297 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from collections import OrderedDict
-
-import six
-from six.moves import xrange
-
-import itertools
-import warnings
-import math
-from operator import attrgetter
-
-import numpy as np
-
-import matplotlib
-
-from matplotlib import cbook
-from matplotlib.cbook import (_check_1d, _string_to_bool, iterable,
- index_of, get_label)
-from matplotlib import docstring
-import matplotlib.colors as mcolors
-import matplotlib.lines as mlines
-import matplotlib.patches as mpatches
-import matplotlib.artist as martist
-import matplotlib.transforms as mtransforms
-import matplotlib.ticker as mticker
-import matplotlib.axis as maxis
-import matplotlib.scale as mscale
-import matplotlib.spines as mspines
-import matplotlib.font_manager as font_manager
-import matplotlib.text as mtext
-import matplotlib.image as mimage
-from matplotlib.offsetbox import OffsetBox
-from matplotlib.artist import allow_rasterization
-from matplotlib.legend import Legend
-
-from matplotlib.rcsetup import cycler
-from matplotlib.rcsetup import validate_axisbelow
-
-rcParams = matplotlib.rcParams
-
-is_string_like = cbook.is_string_like
-is_sequence_of_strings = cbook.is_sequence_of_strings
-
-_hold_msg = """axes.hold is deprecated.
- See the API Changes document (http://matplotlib.org/api/api_changes.html)
- for more details."""
-
-
-def _process_plot_format(fmt):
- """
- Process a MATLAB style color/line style format string. Return a
- (*linestyle*, *color*) tuple as a result of the processing. Default
- values are ('-', 'b'). Example format strings include:
-
- * 'ko': black circles
- * '.b': blue dots
- * 'r--': red dashed lines
- * 'C2--': the third color in the color cycle, dashed lines
-
- .. seealso::
-
- :func:`~matplotlib.Line2D.lineStyles` and
- :func:`~matplotlib.pyplot.colors`
- for all possible styles and color format string.
- """
-
- linestyle = None
- marker = None
- color = None
-
- # Is fmt just a colorspec?
- try:
- color = mcolors.to_rgba(fmt)
-
- # We need to differentiate grayscale '1.0' from tri_down marker '1'
- try:
- fmtint = str(int(fmt))
- except ValueError:
- return linestyle, marker, color # Yes
- else:
- if fmt != fmtint:
- # user definitely doesn't want tri_down marker
- return linestyle, marker, color # Yes
- else:
- # ignore converted color
- color = None
- except ValueError:
- pass # No, not just a color.
-
- # handle the multi char special cases and strip them from the
- # string
- if fmt.find('--') >= 0:
- linestyle = '--'
- fmt = fmt.replace('--', '')
- if fmt.find('-.') >= 0:
- linestyle = '-.'
- fmt = fmt.replace('-.', '')
- if fmt.find(' ') >= 0:
- linestyle = 'None'
- fmt = fmt.replace(' ', '')
-
- chars = [c for c in fmt]
-
- i = 0
- while i < len(chars):
- c = chars[i]
- if c in mlines.lineStyles:
- if linestyle is not None:
- raise ValueError(
- 'Illegal format string "%s"; two linestyle symbols' % fmt)
- linestyle = c
- elif c in mlines.lineMarkers:
- if marker is not None:
- raise ValueError(
- 'Illegal format string "%s"; two marker symbols' % fmt)
- marker = c
- elif c in mcolors.get_named_colors_mapping():
- if color is not None:
- raise ValueError(
- 'Illegal format string "%s"; two color symbols' % fmt)
- color = c
- elif c == 'C' and i < len(chars) - 1:
- color_cycle_number = int(chars[i + 1])
- color = mcolors.to_rgba("C{}".format(color_cycle_number))
- i += 1
- else:
- raise ValueError(
- 'Unrecognized character %c in format string' % c)
- i += 1
-
- if linestyle is None and marker is None:
- linestyle = rcParams['lines.linestyle']
- if linestyle is None:
- linestyle = 'None'
- if marker is None:
- marker = 'None'
-
- return linestyle, marker, color
-
-
-class _process_plot_var_args(object):
- """
- Process variable length arguments to the plot command, so that
- plot commands like the following are supported::
-
- plot(t, s)
- plot(t1, s1, t2, s2)
- plot(t1, s1, 'ko', t2, s2)
- plot(t1, s1, 'ko', t2, s2, 'r--', t3, e3)
-
- an arbitrary number of *x*, *y*, *fmt* are allowed
- """
- def __init__(self, axes, command='plot'):
- self.axes = axes
- self.command = command
- self.set_prop_cycle()
-
- def __getstate__(self):
- # note: it is not possible to pickle a itertools.cycle instance
- return {'axes': self.axes, 'command': self.command}
-
- def __setstate__(self, state):
- self.__dict__ = state.copy()
- self.set_prop_cycle()
-
- def set_prop_cycle(self, *args, **kwargs):
- if not (args or kwargs) or (len(args) == 1 and args[0] is None):
- prop_cycler = rcParams['axes.prop_cycle']
- else:
- prop_cycler = cycler(*args, **kwargs)
-
- self.prop_cycler = itertools.cycle(prop_cycler)
- # This should make a copy
- self._prop_keys = prop_cycler.keys
-
- def __call__(self, *args, **kwargs):
- if self.axes.xaxis is not None and self.axes.yaxis is not None:
- xunits = kwargs.pop('xunits', self.axes.xaxis.units)
-
- if self.axes.name == 'polar':
- xunits = kwargs.pop('thetaunits', xunits)
-
- yunits = kwargs.pop('yunits', self.axes.yaxis.units)
-
- if self.axes.name == 'polar':
- yunits = kwargs.pop('runits', yunits)
-
- if xunits != self.axes.xaxis.units:
- self.axes.xaxis.set_units(xunits)
-
- if yunits != self.axes.yaxis.units:
- self.axes.yaxis.set_units(yunits)
-
- ret = self._grab_next_args(*args, **kwargs)
- return ret
-
- def get_next_color(self):
- """Return the next color in the cycle."""
- if 'color' not in self._prop_keys:
- return 'k'
- return next(self.prop_cycler)['color']
-
- def set_lineprops(self, line, **kwargs):
- assert self.command == 'plot', 'set_lineprops only works with "plot"'
- line.set(**kwargs)
-
- def set_patchprops(self, fill_poly, **kwargs):
- assert self.command == 'fill', 'set_patchprops only works with "fill"'
- fill_poly.set(**kwargs)
-
- def _xy_from_xy(self, x, y):
- if self.axes.xaxis is not None and self.axes.yaxis is not None:
- bx = self.axes.xaxis.update_units(x)
- by = self.axes.yaxis.update_units(y)
-
- if self.command != 'plot':
- # the Line2D class can handle unitized data, with
- # support for post hoc unit changes etc. Other mpl
- # artists, e.g., Polygon which _process_plot_var_args
- # also serves on calls to fill, cannot. So this is a
- # hack to say: if you are not "plot", which is
- # creating Line2D, then convert the data now to
- # floats. If you are plot, pass the raw data through
- # to Line2D which will handle the conversion. So
- # polygons will not support post hoc conversions of
- # the unit type since they are not storing the orig
- # data. Hopefully we can rationalize this at a later
- # date - JDH
- if bx:
- x = self.axes.convert_xunits(x)
- if by:
- y = self.axes.convert_yunits(y)
-
- # like asanyarray, but converts scalar to array, and doesn't change
- # existing compatible sequences
- x = _check_1d(x)
- y = _check_1d(y)
- if x.shape[0] != y.shape[0]:
- raise ValueError("x and y must have same first dimension, but "
- "have shapes {} and {}".format(x.shape, y.shape))
- if x.ndim > 2 or y.ndim > 2:
- raise ValueError("x and y can be no greater than 2-D, but have "
- "shapes {} and {}".format(x.shape, y.shape))
-
- if x.ndim == 1:
- x = x[:, np.newaxis]
- if y.ndim == 1:
- y = y[:, np.newaxis]
- return x, y
-
- def _getdefaults(self, ignore, *kwargs):
- """
- Only advance the cycler if the cycler has information that
- is not specified in any of the supplied tuple of dicts.
- Ignore any keys specified in the `ignore` set.
-
- Returns a copy of defaults dictionary if there are any
- keys that are not found in any of the supplied dictionaries.
- If the supplied dictionaries have non-None values for
- everything the property cycler has, then just return
- an empty dictionary. Ignored keys are excluded from the
- returned dictionary.
-
- """
- prop_keys = self._prop_keys
- if ignore is None:
- ignore = set()
- prop_keys = prop_keys - ignore
-
- if any(all(kw.get(k, None) is None for kw in kwargs)
- for k in prop_keys):
- # Need to copy this dictionary or else the next time around
- # in the cycle, the dictionary could be missing entries.
- default_dict = next(self.prop_cycler).copy()
- for p in ignore:
- default_dict.pop(p, None)
- else:
- default_dict = {}
- return default_dict
-
- def _setdefaults(self, defaults, *kwargs):
- """
- Given a defaults dictionary, and any other dictionaries,
- update those other dictionaries with information in defaults if
- none of the other dictionaries contains that information.
-
- """
- for k in defaults:
- if all(kw.get(k, None) is None for kw in kwargs):
- for kw in kwargs:
- kw[k] = defaults[k]
-
- def _makeline(self, x, y, kw, kwargs):
- kw = kw.copy() # Don't modify the original kw.
- kw.update(kwargs)
- default_dict = self._getdefaults(None, kw)
- self._setdefaults(default_dict, kw)
- seg = mlines.Line2D(x, y, **kw)
- return seg
-
- def _makefill(self, x, y, kw, kwargs):
- kw = kw.copy() # Don't modify the original kw.
- kwargs = kwargs.copy()
-
- # Ignore 'marker'-related properties as they aren't Polygon
- # properties, but they are Line2D properties, and so they are
- # likely to appear in the default cycler construction.
- # This is done here to the defaults dictionary as opposed to the
- # other two dictionaries because we do want to capture when a
- # *user* explicitly specifies a marker which should be an error.
- # We also want to prevent advancing the cycler if there are no
- # defaults needed after ignoring the given properties.
- ignores = {'marker', 'markersize', 'markeredgecolor',
- 'markerfacecolor', 'markeredgewidth'}
- # Also ignore anything provided by *kwargs*.
- for k, v in six.iteritems(kwargs):
- if v is not None:
- ignores.add(k)
-
- # Only using the first dictionary to use as basis
- # for getting defaults for back-compat reasons.
- # Doing it with both seems to mess things up in
- # various places (probably due to logic bugs elsewhere).
- default_dict = self._getdefaults(ignores, kw)
- self._setdefaults(default_dict, kw)
-
- # Looks like we don't want "color" to be interpreted to
- # mean both facecolor and edgecolor for some reason.
- # So the "kw" dictionary is thrown out, and only its
- # 'color' value is kept and translated as a 'facecolor'.
- # This design should probably be revisited as it increases
- # complexity.
- facecolor = kw.get('color', None)
-
- # Throw out 'color' as it is now handled as a facecolor
- default_dict.pop('color', None)
-
- # To get other properties set from the cycler
- # modify the kwargs dictionary.
- self._setdefaults(default_dict, kwargs)
-
- seg = mpatches.Polygon(np.hstack((x[:, np.newaxis],
- y[:, np.newaxis])),
- facecolor=facecolor,
- fill=kwargs.get('fill', True),
- closed=kw['closed'])
- self.set_patchprops(seg, **kwargs)
- return seg
-
- def _plot_args(self, tup, kwargs):
- ret = []
- if len(tup) > 1 and isinstance(tup[-1], six.string_types):
- linestyle, marker, color = _process_plot_format(tup[-1])
- tup = tup[:-1]
- elif len(tup) == 3:
- raise ValueError('third arg must be a format string')
- else:
- linestyle, marker, color = None, None, None
-
- # Don't allow any None value; These will be up-converted
- # to one element array of None which causes problems
- # downstream.
- if any(v is None for v in tup):
- raise ValueError("x and y must not be None")
-
- kw = {}
- for k, v in zip(('linestyle', 'marker', 'color'),
- (linestyle, marker, color)):
- if v is not None:
- kw[k] = v
-
- if 'label' not in kwargs or kwargs['label'] is None:
- kwargs['label'] = get_label(tup[-1], None)
-
- if len(tup) == 2:
- x = _check_1d(tup[0])
- y = _check_1d(tup[-1])
- else:
- x, y = index_of(tup[-1])
-
- x, y = self._xy_from_xy(x, y)
-
- if self.command == 'plot':
- func = self._makeline
- else:
- kw['closed'] = kwargs.get('closed', True)
- func = self._makefill
-
- ncx, ncy = x.shape[1], y.shape[1]
- if ncx > 1 and ncy > 1 and ncx != ncy:
- cbook.warn_deprecated("2.2", "cycling among columns of inputs "
- "with non-matching shapes is deprecated.")
- for j in xrange(max(ncx, ncy)):
- seg = func(x[:, j % ncx], y[:, j % ncy], kw, kwargs)
- ret.append(seg)
- return ret
-
- def _grab_next_args(self, *args, **kwargs):
- while args:
- this, args = args[:2], args[2:]
- if args and isinstance(args[0], six.string_types):
- this += args[0],
- args = args[1:]
- for seg in self._plot_args(this, kwargs):
- yield seg
-
-
-class _AxesBase(martist.Artist):
- """
- """
- name = "rectilinear"
-
- _shared_x_axes = cbook.Grouper()
- _shared_y_axes = cbook.Grouper()
- _twinned_axes = cbook.Grouper()
-
- def __str__(self):
- return "{0}({1[0]:g},{1[1]:g};{1[2]:g}x{1[3]:g})".format(
- type(self).__name__, self._position.bounds)
-
- @docstring.Substitution(scale=' | '.join(
- [repr(x) for x in mscale.get_scale_names()]))
- def __init__(self, fig, rect,
- facecolor=None, # defaults to rc axes.facecolor
- frameon=True,
- sharex=None, # use Axes instance's xaxis info
- sharey=None, # use Axes instance's yaxis info
- label='',
- xscale=None,
- yscale=None,
- **kwargs
- ):
- """
- Build an `~axes.Axes` instance in
- `~matplotlib.figure.Figure` *fig* with
- *rect=[left, bottom, width, height]* in
- `~matplotlib.figure.Figure` coordinates
-
- Optional keyword arguments:
-
- ================ =========================================
- Keyword Description
- ================ =========================================
- *adjustable* [ 'box' | 'datalim' ]
- *alpha* float: the alpha transparency (can be None)
- *anchor* [ 'C', 'SW', 'S', 'SE', 'E', 'NE', 'N',
- 'NW', 'W' ]
- *aspect* [ 'auto' | 'equal' | aspect_ratio ]
- *autoscale_on* bool; whether to autoscale the *viewlim*
- *axisbelow* [ bool | 'line' ] draw the grids
- and ticks below or above most other artists,
- or below lines but above patches
- *cursor_props* a (*float*, *color*) tuple
- *figure* a :class:`~matplotlib.figure.Figure`
- instance
- *frame_on* bool; whether to draw the axes frame
- *label* the axes label
- *navigate* bool
- *navigate_mode* [ 'PAN' | 'ZOOM' | None ] the navigation
- toolbar button status
- *position* [left, bottom, width, height] in
- class:`~matplotlib.figure.Figure` coords
- *sharex* an class:`~matplotlib.axes.Axes` instance
- to share the x-axis with
- *sharey* an class:`~matplotlib.axes.Axes` instance
- to share the y-axis with
- *title* the title string
- *visible* bool, whether the axes is visible
- *xlabel* the xlabel
- *xlim* (*xmin*, *xmax*) view limits
- *xscale* [%(scale)s]
- *xticklabels* sequence of strings
- *xticks* sequence of floats
- *ylabel* the ylabel strings
- *ylim* (*ymin*, *ymax*) view limits
- *yscale* [%(scale)s]
- *yticklabels* sequence of strings
- *yticks* sequence of floats
- ================ =========================================
- """
-
- martist.Artist.__init__(self)
- if isinstance(rect, mtransforms.Bbox):
- self._position = rect
- else:
- self._position = mtransforms.Bbox.from_bounds(*rect)
- if self._position.width < 0 or self._position.height < 0:
- raise ValueError('Width and height specified must be non-negative')
- self._originalPosition = self._position.frozen()
- # self.set_axes(self)
- self.axes = self
- self._aspect = 'auto'
- self._adjustable = 'box'
- self._anchor = 'C'
- self._sharex = sharex
- self._sharey = sharey
- if sharex is not None:
- self._shared_x_axes.join(self, sharex)
- if sharey is not None:
- self._shared_y_axes.join(self, sharey)
- self.set_label(label)
- self.set_figure(fig)
-
- self.set_axes_locator(kwargs.get("axes_locator", None))
-
- self.spines = self._gen_axes_spines()
-
- # this call may differ for non-sep axes, e.g., polar
- self._init_axis()
- if facecolor is None:
- facecolor = rcParams['axes.facecolor']
- self._facecolor = facecolor
- self._frameon = frameon
- self._axisbelow = rcParams['axes.axisbelow']
-
- self._rasterization_zorder = None
-
- self._hold = rcParams['axes.hold']
- if self._hold is None:
- self._hold = True
-
- self._connected = {} # a dict from events to (id, func)
- self.cla()
-
- # funcs used to format x and y - fall back on major formatters
- self.fmt_xdata = None
- self.fmt_ydata = None
-
- self._cachedRenderer = None
- self.set_navigate(True)
- self.set_navigate_mode(None)
-
- if xscale:
- self.set_xscale(xscale)
- if yscale:
- self.set_yscale(yscale)
-
- if len(kwargs):
- self.update(kwargs)
-
- if self.xaxis is not None:
- self._xcid = self.xaxis.callbacks.connect(
- 'units finalize', lambda: self._on_units_changed(scalex=True))
-
- if self.yaxis is not None:
- self._ycid = self.yaxis.callbacks.connect(
- 'units finalize', lambda: self._on_units_changed(scaley=True))
-
- self.tick_params(
- top=rcParams['xtick.top'] and rcParams['xtick.minor.top'],
- bottom=rcParams['xtick.bottom'] and rcParams['xtick.minor.bottom'],
- labeltop=(rcParams['xtick.labeltop'] and
- rcParams['xtick.minor.top']),
- labelbottom=(rcParams['xtick.labelbottom'] and
- rcParams['xtick.minor.bottom']),
- left=rcParams['ytick.left'] and rcParams['ytick.minor.left'],
- right=rcParams['ytick.right'] and rcParams['ytick.minor.right'],
- labelleft=(rcParams['ytick.labelleft'] and
- rcParams['ytick.minor.left']),
- labelright=(rcParams['ytick.labelright'] and
- rcParams['ytick.minor.right']),
- which='minor')
-
- self.tick_params(
- top=rcParams['xtick.top'] and rcParams['xtick.major.top'],
- bottom=rcParams['xtick.bottom'] and rcParams['xtick.major.bottom'],
- labeltop=(rcParams['xtick.labeltop'] and
- rcParams['xtick.major.top']),
- labelbottom=(rcParams['xtick.labelbottom'] and
- rcParams['xtick.major.bottom']),
- left=rcParams['ytick.left'] and rcParams['ytick.major.left'],
- right=rcParams['ytick.right'] and rcParams['ytick.major.right'],
- labelleft=(rcParams['ytick.labelleft'] and
- rcParams['ytick.major.left']),
- labelright=(rcParams['ytick.labelright'] and
- rcParams['ytick.major.right']),
- which='major')
-
- self._layoutbox = None
- self._poslayoutbox = None
-
- def __getstate__(self):
- # The renderer should be re-created by the figure, and then cached at
- # that point.
- state = super(_AxesBase, self).__getstate__()
- state['_cachedRenderer'] = None
- state.pop('_layoutbox')
- state.pop('_poslayoutbox')
-
- return state
-
- def __setstate__(self, state):
- self.__dict__ = state
- # put the _remove_method back on all artists contained within the axes
- for container_name in ['lines', 'collections', 'tables', 'patches',
- 'texts', 'images']:
- container = getattr(self, container_name)
- for artist in container:
- artist._remove_method = container.remove
- self._stale = True
- self._layoutbox = None
- self._poslayoutbox = None
-
- def get_window_extent(self, *args, **kwargs):
- """
- get the axes bounding box in display space; *args* and
- *kwargs* are empty
- """
- bbox = self.bbox
- x_pad = self.xaxis.get_tick_padding()
- y_pad = self.yaxis.get_tick_padding()
- return mtransforms.Bbox([[bbox.x0 - x_pad, bbox.y0 - y_pad],
- [bbox.x1 + x_pad, bbox.y1 + y_pad]])
-
- def _init_axis(self):
- "move this out of __init__ because non-separable axes don't use it"
- self.xaxis = maxis.XAxis(self)
- self.spines['bottom'].register_axis(self.xaxis)
- self.spines['top'].register_axis(self.xaxis)
- self.yaxis = maxis.YAxis(self)
- self.spines['left'].register_axis(self.yaxis)
- self.spines['right'].register_axis(self.yaxis)
- self._update_transScale()
-
- def set_figure(self, fig):
- """
- Set the `.Figure` for this `.Axes`.
-
- .. ACCEPTS: `.Figure`
-
- Parameters
- ----------
- fig : `.Figure`
- """
- martist.Artist.set_figure(self, fig)
-
- self.bbox = mtransforms.TransformedBbox(self._position,
- fig.transFigure)
- # these will be updated later as data is added
- self.dataLim = mtransforms.Bbox.null()
- self.viewLim = mtransforms.Bbox.unit()
- self.transScale = mtransforms.TransformWrapper(
- mtransforms.IdentityTransform())
-
- self._set_lim_and_transforms()
-
- def _set_lim_and_transforms(self):
- """
- set the *_xaxis_transform*, *_yaxis_transform*,
- *transScale*, *transData*, *transLimits* and *transAxes*
- transformations.
-
- .. note::
-
- This method is primarily used by rectilinear projections
- of the :class:`~matplotlib.axes.Axes` class, and is meant
- to be overridden by new kinds of projection axes that need
- different transformations and limits. (See
- :class:`~matplotlib.projections.polar.PolarAxes` for an
- example.
-
- """
- self.transAxes = mtransforms.BboxTransformTo(self.bbox)
-
- # Transforms the x and y axis separately by a scale factor.
- # It is assumed that this part will have non-linear components
- # (e.g., for a log scale).
- self.transScale = mtransforms.TransformWrapper(
- mtransforms.IdentityTransform())
-
- # An affine transformation on the data, generally to limit the
- # range of the axes
- self.transLimits = mtransforms.BboxTransformFrom(
- mtransforms.TransformedBbox(self.viewLim, self.transScale))
-
- # The parentheses are important for efficiency here -- they
- # group the last two (which are usually affines) separately
- # from the first (which, with log-scaling can be non-affine).
- self.transData = self.transScale + (self.transLimits + self.transAxes)
-
- self._xaxis_transform = mtransforms.blended_transform_factory(
- self.transData, self.transAxes)
- self._yaxis_transform = mtransforms.blended_transform_factory(
- self.transAxes, self.transData)
-
- def get_xaxis_transform(self, which='grid'):
- """
- Get the transformation used for drawing x-axis labels, ticks
- and gridlines. The x-direction is in data coordinates and the
- y-direction is in axis coordinates.
-
- .. note::
-
- This transformation is primarily used by the
- :class:`~matplotlib.axis.Axis` class, and is meant to be
- overridden by new kinds of projections that may need to
- place axis elements in different locations.
-
- """
- if which == 'grid':
- return self._xaxis_transform
- elif which == 'tick1':
- # for cartesian projection, this is bottom spine
- return self.spines['bottom'].get_spine_transform()
- elif which == 'tick2':
- # for cartesian projection, this is top spine
- return self.spines['top'].get_spine_transform()
- else:
- raise ValueError('unknown value for which')
-
- def get_xaxis_text1_transform(self, pad_points):
- """
- Get the transformation used for drawing x-axis labels, which
- will add the given amount of padding (in points) between the
- axes and the label. The x-direction is in data coordinates
- and the y-direction is in axis coordinates. Returns a
- 3-tuple of the form::
-
- (transform, valign, halign)
-
- where *valign* and *halign* are requested alignments for the
- text.
-
- .. note::
-
- This transformation is primarily used by the
- :class:`~matplotlib.axis.Axis` class, and is meant to be
- overridden by new kinds of projections that may need to
- place axis elements in different locations.
-
- """
- labels_align = matplotlib.rcParams["xtick.alignment"]
-
- return (self.get_xaxis_transform(which='tick1') +
- mtransforms.ScaledTranslation(0, -1 * pad_points / 72.0,
- self.figure.dpi_scale_trans),
- "top", labels_align)
-
- def get_xaxis_text2_transform(self, pad_points):
- """
- Get the transformation used for drawing the secondary x-axis
- labels, which will add the given amount of padding (in points)
- between the axes and the label. The x-direction is in data
- coordinates and the y-direction is in axis coordinates.
- Returns a 3-tuple of the form::
-
- (transform, valign, halign)
-
- where *valign* and *halign* are requested alignments for the
- text.
-
- .. note::
-
- This transformation is primarily used by the
- :class:`~matplotlib.axis.Axis` class, and is meant to be
- overridden by new kinds of projections that may need to
- place axis elements in different locations.
-
- """
- labels_align = matplotlib.rcParams["xtick.alignment"]
- return (self.get_xaxis_transform(which='tick2') +
- mtransforms.ScaledTranslation(0, pad_points / 72.0,
- self.figure.dpi_scale_trans),
- "bottom", labels_align)
-
- def get_yaxis_transform(self, which='grid'):
- """
- Get the transformation used for drawing y-axis labels, ticks
- and gridlines. The x-direction is in axis coordinates and the
- y-direction is in data coordinates.
-
- .. note::
-
- This transformation is primarily used by the
- :class:`~matplotlib.axis.Axis` class, and is meant to be
- overridden by new kinds of projections that may need to
- place axis elements in different locations.
-
- """
- if which == 'grid':
- return self._yaxis_transform
- elif which == 'tick1':
- # for cartesian projection, this is bottom spine
- return self.spines['left'].get_spine_transform()
- elif which == 'tick2':
- # for cartesian projection, this is top spine
- return self.spines['right'].get_spine_transform()
- else:
- raise ValueError('unknown value for which')
-
- def get_yaxis_text1_transform(self, pad_points):
- """
- Get the transformation used for drawing y-axis labels, which
- will add the given amount of padding (in points) between the
- axes and the label. The x-direction is in axis coordinates
- and the y-direction is in data coordinates. Returns a 3-tuple
- of the form::
-
- (transform, valign, halign)
-
- where *valign* and *halign* are requested alignments for the
- text.
-
- .. note::
-
- This transformation is primarily used by the
- :class:`~matplotlib.axis.Axis` class, and is meant to be
- overridden by new kinds of projections that may need to
- place axis elements in different locations.
-
- """
- labels_align = matplotlib.rcParams["ytick.alignment"]
- return (self.get_yaxis_transform(which='tick1') +
- mtransforms.ScaledTranslation(-1 * pad_points / 72.0, 0,
- self.figure.dpi_scale_trans),
- labels_align, "right")
-
- def get_yaxis_text2_transform(self, pad_points):
- """
- Get the transformation used for drawing the secondary y-axis
- labels, which will add the given amount of padding (in points)
- between the axes and the label. The x-direction is in axis
- coordinates and the y-direction is in data coordinates.
- Returns a 3-tuple of the form::
-
- (transform, valign, halign)
-
- where *valign* and *halign* are requested alignments for the
- text.
-
- .. note::
-
- This transformation is primarily used by the
- :class:`~matplotlib.axis.Axis` class, and is meant to be
- overridden by new kinds of projections that may need to
- place axis elements in different locations.
-
- """
- labels_align = matplotlib.rcParams["ytick.alignment"]
-
- return (self.get_yaxis_transform(which='tick2') +
- mtransforms.ScaledTranslation(pad_points / 72.0, 0,
- self.figure.dpi_scale_trans),
- labels_align, "left")
-
- def _update_transScale(self):
- self.transScale.set(
- mtransforms.blended_transform_factory(
- self.xaxis.get_transform(), self.yaxis.get_transform()))
- if hasattr(self, "lines"):
- for line in self.lines:
- try:
- line._transformed_path.invalidate()
- except AttributeError:
- pass
-
- def get_position(self, original=False):
- """
- Get a copy of the axes rectangle as a `.Bbox`.
-
- Parameters
- ----------
- original : bool
- If ``True``, return the original position. Otherwise return the
- active position. For an explanation of the positions see
- `.set_position`.
-
- Returns
- -------
- pos : `.Bbox`
-
- """
- if original:
- return self._originalPosition.frozen()
- else:
- return self._position.frozen()
-
- def set_position(self, pos, which='both'):
- """
- Set the axes position.
-
- Axes have two position attributes. The 'original' position is the
- position allocated for the Axes. The 'active' position is the
- position the Axes is actually drawn at. These positions are usually
- the same unless a fixed aspect is set to the Axes. See `.set_aspect`
- for details.
-
- Parameters
- ----------
- pos : [left, bottom, width, height] or `~matplotlib.transforms.Bbox`
- The new position of the in `.Figure` coordinates.
-
- which : ['both' | 'active' | 'original'], optional
- Determines which position variables to change.
-
- """
- self._set_position(pos, which='both')
- # because this is being called externally to the library we
- # zero the constrained layout parts.
- self._layoutbox = None
- self._poslayoutbox = None
-
- def _set_position(self, pos, which='both'):
- """
- private version of set_position. Call this internally
- to get the same functionality of `get_position`, but not
- to take the axis out of the constrained_layout
- hierarchy.
- """
- if not isinstance(pos, mtransforms.BboxBase):
- pos = mtransforms.Bbox.from_bounds(*pos)
- for ax in self._twinned_axes.get_siblings(self):
- if which in ('both', 'active'):
- ax._position.set(pos)
- if which in ('both', 'original'):
- ax._originalPosition.set(pos)
- self.stale = True
-
- def reset_position(self):
- """
- Reset the active position to the original position.
-
- This resets the a possible position change due to aspect constraints.
- For an explanation of the positions see `.set_position`.
- """
- for ax in self._twinned_axes.get_siblings(self):
- pos = ax.get_position(original=True)
- ax.set_position(pos, which='active')
-
- def set_axes_locator(self, locator):
- """
- Set the axes locator.
-
- .. ACCEPTS: a callable object which takes an axes instance and
- renderer and returns a bbox.
-
- Parameters
- ----------
- locator : callable
- A locator function, which takes an axes and a renderer and returns
- a bbox.
- """
- self._axes_locator = locator
- self.stale = True
-
- def get_axes_locator(self):
- """
- Return the axes_locator.
- """
- return self._axes_locator
-
- def _set_artist_props(self, a):
- """set the boilerplate props for artists added to axes"""
- a.set_figure(self.figure)
- if not a.is_transform_set():
- a.set_transform(self.transData)
-
- a.axes = self
- if a.mouseover:
- self.mouseover_set.add(a)
-
- def _gen_axes_patch(self):
- """
- Returns the patch used to draw the background of the axes. It
- is also used as the clipping path for any data elements on the
- axes.
-
- In the standard axes, this is a rectangle, but in other
- projections it may not be.
-
- .. note::
-
- Intended to be overridden by new projection types.
-
- """
- return mpatches.Rectangle((0.0, 0.0), 1.0, 1.0)
-
- def _gen_axes_spines(self, locations=None, offset=0.0, units='inches'):
- """
- Returns a dict whose keys are spine names and values are
- Line2D or Patch instances. Each element is used to draw a
- spine of the axes.
-
- In the standard axes, this is a single line segment, but in
- other projections it may not be.
-
- .. note::
-
- Intended to be overridden by new projection types.
-
- """
- return OrderedDict([
- ('left', mspines.Spine.linear_spine(self, 'left')),
- ('right', mspines.Spine.linear_spine(self, 'right')),
- ('bottom', mspines.Spine.linear_spine(self, 'bottom')),
- ('top', mspines.Spine.linear_spine(self, 'top'))])
-
- def cla(self):
- """Clear the current axes."""
- # Note: this is called by Axes.__init__()
-
- # stash the current visibility state
- if hasattr(self, 'patch'):
- patch_visible = self.patch.get_visible()
- else:
- patch_visible = True
-
- xaxis_visible = self.xaxis.get_visible()
- yaxis_visible = self.yaxis.get_visible()
-
- self.xaxis.cla()
- self.yaxis.cla()
-
- for name, spine in six.iteritems(self.spines):
- spine.cla()
-
- self.ignore_existing_data_limits = True
- self.callbacks = cbook.CallbackRegistry()
-
- if self._sharex is not None:
- # major and minor are axis.Ticker class instances with
- # locator and formatter attributes
- self.xaxis.major = self._sharex.xaxis.major
- self.xaxis.minor = self._sharex.xaxis.minor
- x0, x1 = self._sharex.get_xlim()
- self.set_xlim(x0, x1, emit=False, auto=None)
- self.xaxis._scale = mscale.scale_factory(
- self._sharex.xaxis.get_scale(), self.xaxis)
- else:
- self.xaxis._set_scale('linear')
- try:
- self.set_xlim(0, 1)
- except TypeError:
- pass
-
- if self._sharey is not None:
- self.yaxis.major = self._sharey.yaxis.major
- self.yaxis.minor = self._sharey.yaxis.minor
- y0, y1 = self._sharey.get_ylim()
- self.set_ylim(y0, y1, emit=False, auto=None)
- self.yaxis._scale = mscale.scale_factory(
- self._sharey.yaxis.get_scale(), self.yaxis)
- else:
- self.yaxis._set_scale('linear')
- try:
- self.set_ylim(0, 1)
- except TypeError:
- pass
- # update the minor locator for x and y axis based on rcParams
- if (rcParams['xtick.minor.visible']):
- self.xaxis.set_minor_locator(mticker.AutoMinorLocator())
-
- if (rcParams['ytick.minor.visible']):
- self.yaxis.set_minor_locator(mticker.AutoMinorLocator())
-
- self._autoscaleXon = True
- self._autoscaleYon = True
- self._xmargin = rcParams['axes.xmargin']
- self._ymargin = rcParams['axes.ymargin']
- self._tight = None
- self._use_sticky_edges = True
- self._update_transScale() # needed?
-
- self._get_lines = _process_plot_var_args(self)
- self._get_patches_for_fill = _process_plot_var_args(self, 'fill')
-
- self._gridOn = rcParams['axes.grid']
- self.lines = []
- self.patches = []
- self.texts = []
- self.tables = []
- self.artists = []
- self.images = []
- self.mouseover_set = set()
- self._current_image = None # strictly for pyplot via _sci, _gci
- self.legend_ = None
- self.collections = [] # collection.Collection instances
- self.containers = []
-
- self.grid(False) # Disable grid on init to use rcParameter
- self.grid(self._gridOn, which=rcParams['axes.grid.which'],
- axis=rcParams['axes.grid.axis'])
- props = font_manager.FontProperties(
- size=rcParams['axes.titlesize'],
- weight=rcParams['axes.titleweight'])
-
- self.title = mtext.Text(
- x=0.5, y=1.0, text='',
- fontproperties=props,
- verticalalignment='baseline',
- horizontalalignment='center',
- )
- self._left_title = mtext.Text(
- x=0.0, y=1.0, text='',
- fontproperties=props.copy(),
- verticalalignment='baseline',
- horizontalalignment='left', )
- self._right_title = mtext.Text(
- x=1.0, y=1.0, text='',
- fontproperties=props.copy(),
- verticalalignment='baseline',
- horizontalalignment='right',
- )
- title_offset_points = rcParams['axes.titlepad']
- # refactor this out so it can be called in ax.set_title if
- # pad argument used...
- self._set_title_offset_trans(title_offset_points)
-
- for _title in (self.title, self._left_title, self._right_title):
- self._set_artist_props(_title)
-
- # The patch draws the background of the axes. We want this to be below
- # the other artists. We use the frame to draw the edges so we are
- # setting the edgecolor to None.
- self.patch = self._gen_axes_patch()
- self.patch.set_figure(self.figure)
- self.patch.set_facecolor(self._facecolor)
- self.patch.set_edgecolor('None')
- self.patch.set_linewidth(0)
- self.patch.set_transform(self.transAxes)
-
- self.set_axis_on()
-
- self.xaxis.set_clip_path(self.patch)
- self.yaxis.set_clip_path(self.patch)
-
- self._shared_x_axes.clean()
- self._shared_y_axes.clean()
- if self._sharex:
- self.xaxis.set_visible(xaxis_visible)
- self.patch.set_visible(patch_visible)
-
- if self._sharey:
- self.yaxis.set_visible(yaxis_visible)
- self.patch.set_visible(patch_visible)
-
- self.stale = True
-
- @property
- @cbook.deprecated("2.1", alternative="Axes.patch")
- def axesPatch(self):
- return self.patch
-
- def clear(self):
- """Clear the axes."""
- self.cla()
-
- def get_facecolor(self):
- """Get the Axes facecolor."""
- return self.patch.get_facecolor()
- get_fc = get_facecolor
-
- def set_facecolor(self, color):
- """Set the Axes facecolor.
-
- .. ACCEPTS: color
-
- Parameters
- ----------
- color : color
- """
- self._facecolor = color
- self.stale = True
- return self.patch.set_facecolor(color)
- set_fc = set_facecolor
-
- def _set_title_offset_trans(self, title_offset_points):
- """
- Set the offset for the title either from rcParams['axes.titlepad']
- or from set_title kwarg ``pad``.
- """
- self.titleOffsetTrans = mtransforms.ScaledTranslation(
- 0.0, title_offset_points / 72.0,
- self.figure.dpi_scale_trans)
- for _title in (self.title, self._left_title, self._right_title):
- _title.set_transform(self.transAxes + self.titleOffsetTrans)
- _title.set_clip_box(None)
-
- def set_prop_cycle(self, *args, **kwargs):
- """
- Set the property cycle of the Axes.
-
- The property cycle controls the style properties such as color,
- marker and linestyle of future plot commands. The style properties
- of data already added to the Axes are not modified.
-
- Call signatures::
-
- set_prop_cycle(cycler)
- set_prop_cycle(label=values[, label2=values2[, ...]])
- set_prop_cycle(label, values)
-
- Form 1 sets given `~cycler.Cycler` object.
-
- Form 2 creates a `~cycler.Cycler` which cycles over one or more
- properties simultaneously and set it as the property cycle of the
- axes. If multiple properties are given, their value lists must have
- the same length. This is just a shortcut for explicitly creating a
- cycler and passing it to the function, i.e. it's short for
- ``set_prop_cycle(cycler(label=values label2=values2, ...))``.
-
- Form 3 creates a `~cycler.Cycler` for a single property and set it
- as the property cycle of the axes. This form exists for compatibility
- with the original `cycler.cycler` interface. Its use is discouraged
- in favor of the kwarg form, i.e. ``set_prop_cycle(label=values)``.
-
- Parameters
- ----------
- cycler : Cycler
- Set the given Cycler. *None* resets to the cycle defined by the
- current style.
-
- label : str
- The property key. Must be a valid `.Artist` property.
- For example, 'color' or 'linestyle'. Aliases are allowed,
- such as 'c' for 'color' and 'lw' for 'linewidth'.
-
- values : iterable
- Finite-length iterable of the property values. These values
- are validated and will raise a ValueError if invalid.
-
- Examples
- --------
- Setting the property cycle for a single property:
-
- >>> ax.set_prop_cycle(color=['red', 'green', 'blue'])
-
- Setting the property cycle for simultaneously cycling over multiple
- properties (e.g. red circle, green plus, blue cross):
-
- >>> ax.set_prop_cycle(color=['red', 'green', 'blue'],
- ... marker=['o', '+', 'x'])
-
- See Also
- --------
- matplotlib.rcsetup.cycler
- Convenience function for creating validated cyclers for properties.
- cycler.cycler
- The original function for creating unvalidated cyclers.
-
- """
- if args and kwargs:
- raise TypeError("Cannot supply both positional and keyword "
- "arguments to this method.")
- if len(args) == 1 and args[0] is None:
- prop_cycle = None
- else:
- prop_cycle = cycler(*args, **kwargs)
- self._get_lines.set_prop_cycle(prop_cycle)
- self._get_patches_for_fill.set_prop_cycle(prop_cycle)
-
- @cbook.deprecated('1.5', alternative='`.set_prop_cycle`')
- def set_color_cycle(self, clist):
- """
- Set the color cycle for any future plot commands on this Axes.
-
- Parameters
- ----------
- clist
- A list of mpl color specifiers.
- """
- if clist is None:
- # Calling set_color_cycle() or set_prop_cycle() with None
- # effectively resets the cycle, but you can't do
- # set_prop_cycle('color', None). So we are special-casing this.
- self.set_prop_cycle(None)
- else:
- self.set_prop_cycle('color', clist)
-
- @cbook.deprecated("2.0")
- def ishold(self):
- """return the HOLD status of the axes
-
- The `hold` mechanism is deprecated and will be removed in
- v3.0.
- """
-
- return self._hold
-
- @cbook.deprecated("2.0", message=_hold_msg)
- def hold(self, b=None):
- """
- Set the hold state.
-
- The ``hold`` mechanism is deprecated and will be removed in
- v3.0. The behavior will remain consistent with the
- long-time default value of True.
-
- If *hold* is *None* (default), toggle the *hold* state. Else
- set the *hold* state to boolean value *b*.
-
- Examples::
-
- # toggle hold
- hold()
-
- # turn hold on
- hold(True)
-
- # turn hold off
- hold(False)
-
- When hold is *True*, subsequent plot commands will be added to
- the current axes. When hold is *False*, the current axes and
- figure will be cleared on the next plot command
-
- """
- if b is None:
- self._hold = not self._hold
- else:
- self._hold = b
-
- def get_aspect(self):
- return self._aspect
-
- def set_aspect(self, aspect, adjustable=None, anchor=None, share=False):
- """
- Set the aspect of the axis scaling, i.e. the ratio of y-unit to x-unit.
-
- Parameters
- ----------
- aspect : ['auto' | 'equal'] or num
- Possible values:
-
- ======== ================================================
- value description
- ======== ================================================
- 'auto' automatic; fill the position rectangle with data
- 'equal' same scaling from data to plot units for x and y
- num a circle will be stretched such that the height
- is num times the width. aspect=1 is the same as
- aspect='equal'.
- ======== ================================================
-
- adjustable : None or ['box' | 'datalim'], optional
- If not ``None``, this defines which parameter will be adjusted to
- meet the required aspect. See `.set_adjustable` for further
- details.
-
- anchor : None or str or 2-tuple of float, optional
- If not ``None``, this defines where the Axes will be drawn if there
- is extra space due to aspect constraints. The most common way to
- to specify the anchor are abbreviations of cardinal directions:
-
- ===== =====================
- value description
- ===== =====================
- 'C' centered
- 'SW' lower left corner
- 'S' middle of bottom edge
- 'SE' lower right corner
- etc.
- ===== =====================
-
- See `.set_anchor` for further details.
-
- share : bool, optional
- If ``True``, apply the settings to all shared Axes.
- Default is ``False``.
-
- See Also
- --------
- matplotlib.axes.Axes.set_adjustable
- defining the parameter to adjust in order to meet the required
- aspect.
- matplotlib.axes.Axes.set_anchor
- defining the position in case of extra space.
- """
- if not (isinstance(aspect, six.string_types)
- and aspect in ('equal', 'auto')):
- aspect = float(aspect) # raise ValueError if necessary
- if share:
- axes = set(self._shared_x_axes.get_siblings(self)
- + self._shared_y_axes.get_siblings(self))
- else:
- axes = [self]
- for ax in axes:
- ax._aspect = aspect
-
- if adjustable is None:
- adjustable = self._adjustable
- self.set_adjustable(adjustable, share=share) # Handle sharing.
-
- if anchor is not None:
- self.set_anchor(anchor, share=share)
- self.stale = True
-
- def get_adjustable(self):
- return self._adjustable
-
- def set_adjustable(self, adjustable, share=False):
- """
- Define which parameter the Axes will change to achieve a given aspect.
-
- Parameters
- ----------
- adjustable : ['box' | 'datalim']
- If 'box', change the physical dimensions of the Axes.
- If 'datalim', change the ``x`` or ``y`` data limits.
-
- share : bool, optional
- If ``True``, apply the settings to all shared Axes.
- Default is ``False``.
-
- .. ACCEPTS: [ 'box' | 'datalim']
-
- See Also
- --------
- matplotlib.axes.Axes.set_aspect
- for a description of aspect handling.
-
- Notes
- -----
- Shared Axes (of which twinned Axes are a special case)
- impose restrictions on how aspect ratios can be imposed.
- For twinned Axes, use 'datalim'. For Axes that share both
- x and y, use 'box'. Otherwise, either 'datalim' or 'box'
- may be used. These limitations are partly a requirement
- to avoid over-specification, and partly a result of the
- particular implementation we are currently using, in
- which the adjustments for aspect ratios are done sequentially
- and independently on each Axes as it is drawn.
- """
- if adjustable == 'box-forced':
- warnings.warn("The 'box-forced' keyword argument is deprecated"
- " since 2.2.", cbook.mplDeprecation)
- if adjustable not in ('box', 'datalim', 'box-forced'):
- raise ValueError("argument must be 'box', or 'datalim'")
- if share:
- axes = set(self._shared_x_axes.get_siblings(self)
- + self._shared_y_axes.get_siblings(self))
- else:
- axes = [self]
- for ax in axes:
- ax._adjustable = adjustable
- self.stale = True
-
- def get_anchor(self):
- """
- Get the anchor location.
-
- See Also
- --------
- matplotlib.axes.Axes.set_anchor
- for a description of the anchor.
- matplotlib.axes.Axes.set_aspect
- for a description of aspect handling.
- """
- return self._anchor
-
- def set_anchor(self, anchor, share=False):
- """
- Define the anchor location.
-
- The actual drawing area (active position) of the Axes may be smaller
- than the Bbox (original position) when a fixed aspect is required. The
- anchor defines where the drawing area will be located within the
- available space.
-
- .. ACCEPTS: [ 'C' | 'SW' | 'S' | 'SE' | 'E' | 'NE' | 'N' | 'NW' | 'W' ]
-
- Parameters
- ----------
- anchor : str or 2-tuple of floats
- The anchor position may be either:
-
- - a sequence (*cx*, *cy*). *cx* and *cy* may range from 0
- to 1, where 0 is left or bottom and 1 is right or top.
-
- - a string using cardinal directions as abbreviation:
-
- - 'C' for centered
- - 'S' (south) for bottom-center
- - 'SW' (south west) for bottom-left
- - etc.
-
- Here is an overview of the possible positions:
-
- +------+------+------+
- | 'NW' | 'N' | 'NE' |
- +------+------+------+
- | 'W' | 'C' | 'E' |
- +------+------+------+
- | 'SW' | 'S' | 'SE' |
- +------+------+------+
-
- share : bool, optional
- If ``True``, apply the settings to all shared Axes.
- Default is ``False``.
-
- See Also
- --------
- matplotlib.axes.Axes.set_aspect
- for a description of aspect handling.
- """
- if not (anchor in mtransforms.Bbox.coefs or len(anchor) == 2):
- raise ValueError('argument must be among %s' %
- ', '.join(mtransforms.Bbox.coefs))
- if share:
- axes = set(self._shared_x_axes.get_siblings(self)
- + self._shared_y_axes.get_siblings(self))
- else:
- axes = [self]
- for ax in axes:
- ax._anchor = anchor
-
- self.stale = True
-
- def get_data_ratio(self):
- """
- Returns the aspect ratio of the raw data.
-
- This method is intended to be overridden by new projection
- types.
- """
- xmin, xmax = self.get_xbound()
- ymin, ymax = self.get_ybound()
-
- xsize = max(abs(xmax - xmin), 1e-30)
- ysize = max(abs(ymax - ymin), 1e-30)
-
- return ysize / xsize
-
- def get_data_ratio_log(self):
- """
- Returns the aspect ratio of the raw data in log scale.
- Will be used when both axis scales are in log.
- """
- xmin, xmax = self.get_xbound()
- ymin, ymax = self.get_ybound()
-
- xsize = max(abs(math.log10(xmax) - math.log10(xmin)), 1e-30)
- ysize = max(abs(math.log10(ymax) - math.log10(ymin)), 1e-30)
-
- return ysize / xsize
-
- def apply_aspect(self, position=None):
- """
- Adjust the Axes for a specified data aspect ratio.
-
- Depending on `.get_adjustable` this will modify either the Axes box
- (position) or the view limits. In the former case, `.get_anchor`
- will affect the position.
-
- Notes
- -----
- This is called automatically when each Axes is drawn. You may need
- to call it yourself if you need to update the Axes position and/or
- view limits before the Figure is drawn.
-
- See Also
- --------
- matplotlib.axes.Axes.set_aspect
- for a description of aspect ratio handling.
- matplotlib.axes.Axes.set_adjustable
- defining the parameter to adjust in order to meet the required
- aspect.
- matplotlib.axes.Axes.set_anchor
- defining the position in case of extra space.
- """
- if position is None:
- position = self.get_position(original=True)
-
- aspect = self.get_aspect()
-
- if self.name != 'polar':
- xscale, yscale = self.get_xscale(), self.get_yscale()
- if xscale == "linear" and yscale == "linear":
- aspect_scale_mode = "linear"
- elif xscale == "log" and yscale == "log":
- aspect_scale_mode = "log"
- elif ((xscale == "linear" and yscale == "log") or
- (xscale == "log" and yscale == "linear")):
- if aspect != "auto":
- warnings.warn(
- 'aspect is not supported for Axes with xscale=%s, '
- 'yscale=%s' % (xscale, yscale))
- aspect = "auto"
- else: # some custom projections have their own scales.
- pass
- else:
- aspect_scale_mode = "linear"
-
- if aspect == 'auto':
- self._set_position(position, which='active')
- return
-
- if aspect == 'equal':
- A = 1
- else:
- A = aspect
-
- figW, figH = self.get_figure().get_size_inches()
- fig_aspect = figH / figW
- if self._adjustable in ['box', 'box-forced']:
- if self in self._twinned_axes:
- raise RuntimeError("Adjustable 'box' is not allowed in a"
- " twinned Axes. Use 'datalim' instead.")
- if aspect_scale_mode == "log":
- box_aspect = A * self.get_data_ratio_log()
- else:
- box_aspect = A * self.get_data_ratio()
- pb = position.frozen()
- pb1 = pb.shrunk_to_aspect(box_aspect, pb, fig_aspect)
- self._set_position(pb1.anchored(self.get_anchor(), pb), 'active')
- return
-
- # reset active to original in case it had been changed
- # by prior use of 'box'
- self._set_position(position, which='active')
-
- xmin, xmax = self.get_xbound()
- ymin, ymax = self.get_ybound()
-
- if aspect_scale_mode == "log":
- xmin, xmax = math.log10(xmin), math.log10(xmax)
- ymin, ymax = math.log10(ymin), math.log10(ymax)
-
- xsize = max(abs(xmax - xmin), 1e-30)
- ysize = max(abs(ymax - ymin), 1e-30)
-
- l, b, w, h = position.bounds
- box_aspect = fig_aspect * (h / w)
- data_ratio = box_aspect / A
-
- y_expander = (data_ratio * xsize / ysize - 1.0)
- # If y_expander > 0, the dy/dx viewLim ratio needs to increase
- if abs(y_expander) < 0.005:
- return
-
- if aspect_scale_mode == "log":
- dL = self.dataLim
- dL_width = math.log10(dL.x1) - math.log10(dL.x0)
- dL_height = math.log10(dL.y1) - math.log10(dL.y0)
- xr = 1.05 * dL_width
- yr = 1.05 * dL_height
- else:
- dL = self.dataLim
- xr = 1.05 * dL.width
- yr = 1.05 * dL.height
-
- xmarg = xsize - xr
- ymarg = ysize - yr
- Ysize = data_ratio * xsize
- Xsize = ysize / data_ratio
- Xmarg = Xsize - xr
- Ymarg = Ysize - yr
- # Setting these targets to, e.g., 0.05*xr does not seem to
- # help.
- xm = 0
- ym = 0
-
- shared_x = self in self._shared_x_axes
- shared_y = self in self._shared_y_axes
- # Not sure whether we need this check:
- if shared_x and shared_y:
- raise RuntimeError("adjustable='datalim' is not allowed when both"
- " axes are shared.")
-
- # If y is shared, then we are only allowed to change x, etc.
- if shared_y:
- adjust_y = False
- else:
- if xmarg > xm and ymarg > ym:
- adjy = ((Ymarg > 0 and y_expander < 0) or
- (Xmarg < 0 and y_expander > 0))
- else:
- adjy = y_expander > 0
- adjust_y = shared_x or adjy # (Ymarg > xmarg)
-
- if adjust_y:
- yc = 0.5 * (ymin + ymax)
- y0 = yc - Ysize / 2.0
- y1 = yc + Ysize / 2.0
- if aspect_scale_mode == "log":
- self.set_ybound((10. ** y0, 10. ** y1))
- else:
- self.set_ybound((y0, y1))
- else:
- xc = 0.5 * (xmin + xmax)
- x0 = xc - Xsize / 2.0
- x1 = xc + Xsize / 2.0
- if aspect_scale_mode == "log":
- self.set_xbound((10. ** x0, 10. ** x1))
- else:
- self.set_xbound((x0, x1))
-
- def axis(self, *v, **kwargs):
- """Set axis properties.
-
- Valid signatures::
-
- xmin, xmax, ymin, ymax = axis()
- xmin, xmax, ymin, ymax = axis(list_arg)
- xmin, xmax, ymin, ymax = axis(string_arg)
- xmin, xmax, ymin, ymax = axis(**kwargs)
-
- Parameters
- ----------
- v : list of float or {'on', 'off', 'equal', 'tight', 'scaled',\
- 'normal', 'auto', 'image', 'square'}
- Optional positional argument
-
- Axis data limits set from a list; or a command relating to axes:
-
- ========== ================================================
- Value Description
- ========== ================================================
- 'on' Toggle axis lines and labels on
- 'off' Toggle axis lines and labels off
- 'equal' Equal scaling by changing limits
- 'scaled' Equal scaling by changing box dimensions
- 'tight' Limits set such that all data is shown
- 'auto' Automatic scaling, fill rectangle with data
- 'normal' Same as 'auto'; deprecated
- 'image' 'scaled' with axis limits equal to data limits
- 'square' Square plot; similar to 'scaled', but initially\
- forcing xmax-xmin = ymax-ymin
- ========== ================================================
-
- emit : bool, optional
- Passed to set_{x,y}lim functions, if observers
- are notified of axis limit change
-
- xmin, ymin, xmax, ymax : float, optional
- The axis limits to be set
-
- Returns
- -------
- xmin, xmax, ymin, ymax : float
- The axis limits
-
- """
-
- if len(v) == 0 and len(kwargs) == 0:
- xmin, xmax = self.get_xlim()
- ymin, ymax = self.get_ylim()
- return xmin, xmax, ymin, ymax
-
- emit = kwargs.get('emit', True)
-
- if len(v) == 1 and isinstance(v[0], six.string_types):
- s = v[0].lower()
- if s == 'on':
- self.set_axis_on()
- elif s == 'off':
- self.set_axis_off()
- elif s in ('equal', 'tight', 'scaled', 'normal',
- 'auto', 'image', 'square'):
- self.set_autoscale_on(True)
- self.set_aspect('auto')
- self.autoscale_view(tight=False)
- # self.apply_aspect()
- if s == 'equal':
- self.set_aspect('equal', adjustable='datalim')
- elif s == 'scaled':
- self.set_aspect('equal', adjustable='box', anchor='C')
- self.set_autoscale_on(False) # Req. by Mark Bakker
- elif s == 'tight':
- self.autoscale_view(tight=True)
- self.set_autoscale_on(False)
- elif s == 'image':
- self.autoscale_view(tight=True)
- self.set_autoscale_on(False)
- self.set_aspect('equal', adjustable='box', anchor='C')
- elif s == 'square':
- self.set_aspect('equal', adjustable='box', anchor='C')
- self.set_autoscale_on(False)
- xlim = self.get_xlim()
- ylim = self.get_ylim()
- edge_size = max(np.diff(xlim), np.diff(ylim))
- self.set_xlim([xlim[0], xlim[0] + edge_size],
- emit=emit, auto=False)
- self.set_ylim([ylim[0], ylim[0] + edge_size],
- emit=emit, auto=False)
- else:
- raise ValueError('Unrecognized string %s to axis; '
- 'try on or off' % s)
- xmin, xmax = self.get_xlim()
- ymin, ymax = self.get_ylim()
- return xmin, xmax, ymin, ymax
-
- try:
- v[0]
- except IndexError:
- xmin = kwargs.get('xmin', None)
- xmax = kwargs.get('xmax', None)
- auto = False # turn off autoscaling, unless...
- if xmin is None and xmax is None:
- auto = None # leave autoscaling state alone
- xmin, xmax = self.set_xlim(xmin, xmax, emit=emit, auto=auto)
-
- ymin = kwargs.get('ymin', None)
- ymax = kwargs.get('ymax', None)
- auto = False # turn off autoscaling, unless...
- if ymin is None and ymax is None:
- auto = None # leave autoscaling state alone
- ymin, ymax = self.set_ylim(ymin, ymax, emit=emit, auto=auto)
- return xmin, xmax, ymin, ymax
-
- v = v[0]
- if len(v) != 4:
- raise ValueError('v must contain [xmin xmax ymin ymax]')
-
- self.set_xlim([v[0], v[1]], emit=emit, auto=False)
- self.set_ylim([v[2], v[3]], emit=emit, auto=False)
-
- return v
-
- def get_legend(self):
- """Return the `Legend` instance, or None if no legend is defined."""
- return self.legend_
-
- def get_images(self):
- """return a list of Axes images contained by the Axes"""
- return cbook.silent_list('AxesImage', self.images)
-
- def get_lines(self):
- """Return a list of lines contained by the Axes"""
- return cbook.silent_list('Line2D', self.lines)
-
- def get_xaxis(self):
- """Return the XAxis instance."""
- return self.xaxis
-
- def get_xgridlines(self):
- """Get the x grid lines as a list of `Line2D` instances."""
- return cbook.silent_list('Line2D xgridline',
- self.xaxis.get_gridlines())
-
- def get_xticklines(self):
- """Get the x tick lines as a list of `Line2D` instances."""
- return cbook.silent_list('Line2D xtickline',
- self.xaxis.get_ticklines())
-
- def get_yaxis(self):
- """Return the YAxis instance."""
- return self.yaxis
-
- def get_ygridlines(self):
- """Get the y grid lines as a list of `Line2D` instances."""
- return cbook.silent_list('Line2D ygridline',
- self.yaxis.get_gridlines())
-
- def get_yticklines(self):
- """Get the y tick lines as a list of `Line2D` instances."""
- return cbook.silent_list('Line2D ytickline',
- self.yaxis.get_ticklines())
-
- # Adding and tracking artists
-
- def _sci(self, im):
- """
- helper for :func:`~matplotlib.pyplot.sci`;
- do not use elsewhere.
- """
- if isinstance(im, matplotlib.contour.ContourSet):
- if im.collections[0] not in self.collections:
- raise ValueError(
- "ContourSet must be in current Axes")
- elif im not in self.images and im not in self.collections:
- raise ValueError(
- "Argument must be an image, collection, or ContourSet in "
- "this Axes")
- self._current_image = im
-
- def _gci(self):
- """
- Helper for :func:`~matplotlib.pyplot.gci`;
- do not use elsewhere.
- """
- return self._current_image
-
- def has_data(self):
- """
- Return *True* if any artists have been added to axes.
-
- This should not be used to determine whether the *dataLim*
- need to be updated, and may not actually be useful for
- anything.
- """
- return (
- len(self.collections) +
- len(self.images) +
- len(self.lines) +
- len(self.patches)) > 0
-
- def add_artist(self, a):
- """Add any :class:`~matplotlib.artist.Artist` to the axes.
-
- Use `add_artist` only for artists for which there is no dedicated
- "add" method; and if necessary, use a method such as `update_datalim`
- to manually update the dataLim if the artist is to be included in
- autoscaling.
-
- Returns the artist.
- """
- a.axes = self
- self.artists.append(a)
- self._set_artist_props(a)
- a.set_clip_path(self.patch)
- a._remove_method = lambda h: self.artists.remove(h)
- self.stale = True
- return a
-
- def add_collection(self, collection, autolim=True):
- """
- Add a :class:`~matplotlib.collections.Collection` instance
- to the axes.
-
- Returns the collection.
- """
- label = collection.get_label()
- if not label:
- collection.set_label('_collection%d' % len(self.collections))
- self.collections.append(collection)
- self._set_artist_props(collection)
-
- if collection.get_clip_path() is None:
- collection.set_clip_path(self.patch)
-
- if autolim:
- self.update_datalim(collection.get_datalim(self.transData))
-
- collection._remove_method = lambda h: self.collections.remove(h)
- self.stale = True
- return collection
-
- def add_image(self, image):
- """
- Add a :class:`~matplotlib.image.AxesImage` to the axes.
-
- Returns the image.
- """
- self._set_artist_props(image)
- if not image.get_label():
- image.set_label('_image%d' % len(self.images))
- self.images.append(image)
- image._remove_method = lambda h: self.images.remove(h)
- self.stale = True
- return image
-
- def _update_image_limits(self, image):
- xmin, xmax, ymin, ymax = image.get_extent()
- self.axes.update_datalim(((xmin, ymin), (xmax, ymax)))
-
- def add_line(self, line):
- """
- Add a :class:`~matplotlib.lines.Line2D` to the list of plot
- lines
-
- Returns the line.
- """
- self._set_artist_props(line)
- if line.get_clip_path() is None:
- line.set_clip_path(self.patch)
-
- self._update_line_limits(line)
- if not line.get_label():
- line.set_label('_line%d' % len(self.lines))
- self.lines.append(line)
- line._remove_method = lambda h: self.lines.remove(h)
- self.stale = True
- return line
-
- def _add_text(self, txt):
- """
-
- """
- self._set_artist_props(txt)
- self.texts.append(txt)
- txt._remove_method = lambda h: self.texts.remove(h)
- self.stale = True
- return txt
-
- def _update_line_limits(self, line):
- """
- Figures out the data limit of the given line, updating self.dataLim.
- """
- path = line.get_path()
- if path.vertices.size == 0:
- return
-
- line_trans = line.get_transform()
-
- if line_trans == self.transData:
- data_path = path
-
- elif any(line_trans.contains_branch_seperately(self.transData)):
- # identify the transform to go from line's coordinates
- # to data coordinates
- trans_to_data = line_trans - self.transData
-
- # if transData is affine we can use the cached non-affine component
- # of line's path. (since the non-affine part of line_trans is
- # entirely encapsulated in trans_to_data).
- if self.transData.is_affine:
- line_trans_path = line._get_transformed_path()
- na_path, _ = line_trans_path.get_transformed_path_and_affine()
- data_path = trans_to_data.transform_path_affine(na_path)
- else:
- data_path = trans_to_data.transform_path(path)
- else:
- # for backwards compatibility we update the dataLim with the
- # coordinate range of the given path, even though the coordinate
- # systems are completely different. This may occur in situations
- # such as when ax.transAxes is passed through for absolute
- # positioning.
- data_path = path
-
- if data_path.vertices.size > 0:
- updatex, updatey = line_trans.contains_branch_seperately(
- self.transData)
- self.dataLim.update_from_path(data_path,
- self.ignore_existing_data_limits,
- updatex=updatex,
- updatey=updatey)
- self.ignore_existing_data_limits = False
-
- def add_patch(self, p):
- """
- Add a :class:`~matplotlib.patches.Patch` *p* to the list of
- axes patches; the clipbox will be set to the Axes clipping
- box. If the transform is not set, it will be set to
- :attr:`transData`.
-
- Returns the patch.
- """
-
- self._set_artist_props(p)
- if p.get_clip_path() is None:
- p.set_clip_path(self.patch)
- self._update_patch_limits(p)
- self.patches.append(p)
- p._remove_method = lambda h: self.patches.remove(h)
- return p
-
- def _update_patch_limits(self, patch):
- """update the data limits for patch *p*"""
- # hist can add zero height Rectangles, which is useful to keep
- # the bins, counts and patches lined up, but it throws off log
- # scaling. We'll ignore rects with zero height or width in
- # the auto-scaling
-
- # cannot check for '==0' since unitized data may not compare to zero
- # issue #2150 - we update the limits if patch has non zero width
- # or height.
- if (isinstance(patch, mpatches.Rectangle) and
- ((not patch.get_width()) and (not patch.get_height()))):
- return
- vertices = patch.get_path().vertices
- if vertices.size > 0:
- xys = patch.get_patch_transform().transform(vertices)
- if patch.get_data_transform() != self.transData:
- patch_to_data = (patch.get_data_transform() -
- self.transData)
- xys = patch_to_data.transform(xys)
-
- updatex, updatey = patch.get_transform().\
- contains_branch_seperately(self.transData)
- self.update_datalim(xys, updatex=updatex,
- updatey=updatey)
-
- def add_table(self, tab):
- """
- Add a :class:`~matplotlib.table.Table` instance to the
- list of axes tables
-
- Parameters
- ----------
- tab: `matplotlib.table.Table`
- Table instance
-
- Returns
- -------
- `matplotlib.table.Table`: the table.
- """
- self._set_artist_props(tab)
- self.tables.append(tab)
- tab.set_clip_path(self.patch)
- tab._remove_method = lambda h: self.tables.remove(h)
- return tab
-
- def add_container(self, container):
- """
- Add a :class:`~matplotlib.container.Container` instance
- to the axes.
-
- Returns the collection.
- """
- label = container.get_label()
- if not label:
- container.set_label('_container%d' % len(self.containers))
- self.containers.append(container)
- container.set_remove_method(lambda h: self.containers.remove(h))
- return container
-
- def _on_units_changed(self, scalex=False, scaley=False):
- """
- Callback for processing changes to axis units.
-
- Currently forces updates of data limits and view limits.
- """
- self.relim()
- self.autoscale_view(scalex=scalex, scaley=scaley)
-
- def relim(self, visible_only=False):
- """
- Recompute the data limits based on current artists. If you want to
- exclude invisible artists from the calculation, set
- ``visible_only=True``
-
- At present, :class:`~matplotlib.collections.Collection`
- instances are not supported.
- """
- # Collections are deliberately not supported (yet); see
- # the TODO note in artists.py.
- self.dataLim.ignore(True)
- self.dataLim.set_points(mtransforms.Bbox.null().get_points())
- self.ignore_existing_data_limits = True
-
- for line in self.lines:
- if not visible_only or line.get_visible():
- self._update_line_limits(line)
-
- for p in self.patches:
- if not visible_only or p.get_visible():
- self._update_patch_limits(p)
-
- for image in self.images:
- if not visible_only or image.get_visible():
- self._update_image_limits(image)
-
- def update_datalim(self, xys, updatex=True, updatey=True):
- """
- Update the data lim bbox with seq of xy tups or equiv. 2-D array
- """
- # if no data is set currently, the bbox will ignore its
- # limits and set the bound to be the bounds of the xydata.
- # Otherwise, it will compute the bounds of it's current data
- # and the data in xydata
- xys = np.asarray(xys)
- if not len(xys):
- return
- self.dataLim.update_from_data_xy(xys, self.ignore_existing_data_limits,
- updatex=updatex, updatey=updatey)
- self.ignore_existing_data_limits = False
-
- def update_datalim_bounds(self, bounds):
- """
- Update the datalim to include the given
- :class:`~matplotlib.transforms.Bbox` *bounds*
- """
- self.dataLim.set(mtransforms.Bbox.union([self.dataLim, bounds]))
-
- def _process_unit_info(self, xdata=None, ydata=None, kwargs=None):
- """Look for unit *kwargs* and update the axis instances as necessary"""
-
- if self.xaxis is None or self.yaxis is None:
- return
-
- if xdata is not None:
- # we only need to update if there is nothing set yet.
- if not self.xaxis.have_units():
- self.xaxis.update_units(xdata)
-
- if ydata is not None:
- # we only need to update if there is nothing set yet.
- if not self.yaxis.have_units():
- self.yaxis.update_units(ydata)
-
- # process kwargs 2nd since these will override default units
- if kwargs is not None:
- xunits = kwargs.pop('xunits', self.xaxis.units)
- if self.name == 'polar':
- xunits = kwargs.pop('thetaunits', xunits)
- if xunits != self.xaxis.units:
- self.xaxis.set_units(xunits)
- # If the units being set imply a different converter,
- # we need to update.
- if xdata is not None:
- self.xaxis.update_units(xdata)
-
- yunits = kwargs.pop('yunits', self.yaxis.units)
- if self.name == 'polar':
- yunits = kwargs.pop('runits', yunits)
- if yunits != self.yaxis.units:
- self.yaxis.set_units(yunits)
- # If the units being set imply a different converter,
- # we need to update.
- if ydata is not None:
- self.yaxis.update_units(ydata)
- return kwargs
-
- def in_axes(self, mouseevent):
- """
- Return *True* if the given *mouseevent* (in display coords)
- is in the Axes
- """
- return self.patch.contains(mouseevent)[0]
-
- def get_autoscale_on(self):
- """
- Get whether autoscaling is applied for both axes on plot commands
- """
- return self._autoscaleXon and self._autoscaleYon
-
- def get_autoscalex_on(self):
- """
- Get whether autoscaling for the x-axis is applied on plot commands
- """
- return self._autoscaleXon
-
- def get_autoscaley_on(self):
- """
- Get whether autoscaling for the y-axis is applied on plot commands
- """
- return self._autoscaleYon
-
- def set_autoscale_on(self, b):
- """
- Set whether autoscaling is applied on plot commands
-
- .. ACCEPTS: bool
-
- Parameters
- ----------
- b : bool
- """
- self._autoscaleXon = b
- self._autoscaleYon = b
-
- def set_autoscalex_on(self, b):
- """
- Set whether autoscaling for the x-axis is applied on plot commands
-
- .. ACCEPTS: bool
-
- Parameters
- ----------
- b : bool
- """
- self._autoscaleXon = b
-
- def set_autoscaley_on(self, b):
- """
- Set whether autoscaling for the y-axis is applied on plot commands
-
- .. ACCEPTS: bool
-
- Parameters
- ----------
- b : bool
- """
- self._autoscaleYon = b
-
- @property
- def use_sticky_edges(self):
- """
- When autoscaling, whether to obey all `Artist.sticky_edges`.
-
- Default is ``True``.
-
- Setting this to ``False`` ensures that the specified margins
- will be applied, even if the plot includes an image, for
- example, which would otherwise force a view limit to coincide
- with its data limit.
-
- The changing this property does not change the plot until
- `autoscale` or `autoscale_view` is called.
- """
- return self._use_sticky_edges
-
- @use_sticky_edges.setter
- def use_sticky_edges(self, b):
- self._use_sticky_edges = bool(b)
- # No effect until next autoscaling, which will mark the axes as stale.
-
- def set_xmargin(self, m):
- """
- Set padding of X data limits prior to autoscaling.
-
- *m* times the data interval will be added to each
- end of that interval before it is used in autoscaling.
- For example, if your data is in the range [0, 2], a factor of
- ``m = 0.1`` will result in a range [-0.2, 2.2].
-
- Negative values -0.5 < m < 0 will result in clipping of the data range.
- I.e. for a data range [0, 2], a factor of ``m = -0.1`` will result in
- a range [0.2, 1.8].
-
- .. ACCEPTS: float greater than -0.5
-
- Parameters
- ----------
- m : float greater than -0.5
- """
- if m <= -0.5:
- raise ValueError("margin must be greater than -0.5")
- self._xmargin = m
- self.stale = True
-
- def set_ymargin(self, m):
- """
- Set padding of Y data limits prior to autoscaling.
-
- *m* times the data interval will be added to each
- end of that interval before it is used in autoscaling.
- For example, if your data is in the range [0, 2], a factor of
- ``m = 0.1`` will result in a range [-0.2, 2.2].
-
- Negative values -0.5 < m < 0 will result in clipping of the data range.
- I.e. for a data range [0, 2], a factor of ``m = -0.1`` will result in
- a range [0.2, 1.8].
-
- .. ACCEPTS: float greater than -0.5
-
- Parameters
- ----------
- m : float greater than -0.5
- """
- if m <= -0.5:
- raise ValueError("margin must be greater than -0.5")
- self._ymargin = m
- self.stale = True
-
- def margins(self, *args, **kw):
- """
- Set or retrieve autoscaling margins.
-
- signatures::
-
- margins()
-
- returns xmargin, ymargin
-
- ::
-
- margins(margin)
-
- margins(xmargin, ymargin)
-
- margins(x=xmargin, y=ymargin)
-
- margins(..., tight=False)
-
- All three forms above set the xmargin and ymargin parameters.
- All keyword parameters are optional. A single argument
- specifies both xmargin and ymargin. The padding added to the end of
- each interval is *margin* times the data interval. The *margin* must
- be a float in the range [0, 1].
-
- The *tight* parameter is passed to :meth:`autoscale_view`
- , which is executed after a margin is changed; the default here is
- *True*, on the assumption that when margins are specified, no
- additional padding to match tick marks is usually desired. Setting
- *tight* to *None* will preserve the previous setting.
-
- Specifying any margin changes only the autoscaling; for example,
- if *xmargin* is not None, then *xmargin* times the X data
- interval will be added to each end of that interval before
- it is used in autoscaling.
-
- """
- if not args and not kw:
- return self._xmargin, self._ymargin
-
- tight = kw.pop('tight', True)
- mx = kw.pop('x', None)
- my = kw.pop('y', None)
- if len(args) == 1:
- mx = my = args[0]
- elif len(args) == 2:
- mx, my = args
- elif len(args) > 2:
- raise ValueError("more than two arguments were supplied")
- if mx is not None:
- self.set_xmargin(mx)
- if my is not None:
- self.set_ymargin(my)
-
- scalex = (mx is not None)
- scaley = (my is not None)
-
- self.autoscale_view(tight=tight, scalex=scalex, scaley=scaley)
-
- def set_rasterization_zorder(self, z):
- """
- Parameters
- ----------
- z : float or None
- zorder below which artists are rasterized. ``None`` means that
- artists do not get rasterized based on zorder.
-
- .. ACCEPTS: float or None
- """
- self._rasterization_zorder = z
- self.stale = True
-
- def get_rasterization_zorder(self):
- """Return the zorder value below which artists will be rasterized."""
- return self._rasterization_zorder
-
- def autoscale(self, enable=True, axis='both', tight=None):
- """
- Autoscale the axis view to the data (toggle).
-
- Convenience method for simple axis view autoscaling.
- It turns autoscaling on or off, and then,
- if autoscaling for either axis is on, it performs
- the autoscaling on the specified axis or axes.
-
- Parameters
- ----------
- enable : bool or None, optional
- True (default) turns autoscaling on, False turns it off.
- None leaves the autoscaling state unchanged.
-
- axis : ['both' | 'x' | 'y'], optional
- which axis to operate on; default is 'both'
-
- tight: bool or None, optional
- If True, set view limits to data limits;
- if False, let the locator and margins expand the view limits;
- if None, use tight scaling if the only artist is an image,
- otherwise treat *tight* as False.
- The *tight* setting is retained for future autoscaling
- until it is explicitly changed.
-
- """
- if enable is None:
- scalex = True
- scaley = True
- else:
- scalex = False
- scaley = False
- if axis in ['x', 'both']:
- self._autoscaleXon = bool(enable)
- scalex = self._autoscaleXon
- if axis in ['y', 'both']:
- self._autoscaleYon = bool(enable)
- scaley = self._autoscaleYon
- if tight and scalex:
- self._xmargin = 0
- if tight and scaley:
- self._ymargin = 0
- self.autoscale_view(tight=tight, scalex=scalex, scaley=scaley)
-
- def autoscale_view(self, tight=None, scalex=True, scaley=True):
- """
- Autoscale the view limits using the data limits.
-
- You can selectively autoscale only a single axis, e.g., the xaxis by
- setting *scaley* to *False*. The autoscaling preserves any
- axis direction reversal that has already been done.
-
- If *tight* is *False*, the axis major locator will be used
- to expand the view limits if rcParams['axes.autolimit_mode']
- is 'round_numbers'. Note that any margins that are in effect
- will be applied first, regardless of whether *tight* is
- *True* or *False*. Specifying *tight* as *True* or *False*
- saves the setting as a private attribute of the Axes; specifying
- it as *None* (the default) applies the previously saved value.
-
- The data limits are not updated automatically when artist data are
- changed after the artist has been added to an Axes instance. In that
- case, use :meth:`matplotlib.axes.Axes.relim` prior to calling
- autoscale_view.
- """
- if tight is not None:
- self._tight = bool(tight)
-
- if self.use_sticky_edges and (self._xmargin or self._ymargin):
- stickies = [artist.sticky_edges for artist in self.get_children()]
- x_stickies = sum([sticky.x for sticky in stickies], [])
- y_stickies = sum([sticky.y for sticky in stickies], [])
- if self.get_xscale().lower() == 'log':
- x_stickies = [xs for xs in x_stickies if xs > 0]
- if self.get_yscale().lower() == 'log':
- y_stickies = [ys for ys in y_stickies if ys > 0]
- else: # Small optimization.
- x_stickies, y_stickies = [], []
-
- def handle_single_axis(scale, autoscaleon, shared_axes, interval,
- minpos, axis, margin, stickies, set_bound):
-
- if not (scale and autoscaleon):
- return # nothing to do...
-
- shared = shared_axes.get_siblings(self)
- dl = [ax.dataLim for ax in shared]
- # ignore non-finite data limits if good limits exist
- finite_dl = [d for d in dl if np.isfinite(d).all()]
- if len(finite_dl):
- # if finite limits exist for atleast one axis (and the
- # other is infinite), restore the finite limits
- x_finite = [d for d in dl
- if (np.isfinite(d.intervalx).all() and
- (d not in finite_dl))]
- y_finite = [d for d in dl
- if (np.isfinite(d.intervaly).all() and
- (d not in finite_dl))]
-
- dl = finite_dl
- dl.extend(x_finite)
- dl.extend(y_finite)
-
- bb = mtransforms.BboxBase.union(dl)
- x0, x1 = getattr(bb, interval)
- locator = axis.get_major_locator()
- try:
- # e.g., DateLocator has its own nonsingular()
- x0, x1 = locator.nonsingular(x0, x1)
- except AttributeError:
- # Default nonsingular for, e.g., MaxNLocator
- x0, x1 = mtransforms.nonsingular(
- x0, x1, increasing=False, expander=0.05)
-
- # Add the margin in figure space and then transform back, to handle
- # non-linear scales.
- minpos = getattr(bb, minpos)
- transform = axis.get_transform()
- inverse_trans = transform.inverted()
- # We cannot use exact equality due to floating point issues e.g.
- # with streamplot.
- do_lower_margin = not np.any(np.isclose(x0, stickies))
- do_upper_margin = not np.any(np.isclose(x1, stickies))
- x0, x1 = axis._scale.limit_range_for_scale(x0, x1, minpos)
- x0t, x1t = transform.transform([x0, x1])
- delta = (x1t - x0t) * margin
- if do_lower_margin:
- x0t -= delta
- if do_upper_margin:
- x1t += delta
- x0, x1 = inverse_trans.transform([x0t, x1t])
-
- if not self._tight:
- x0, x1 = locator.view_limits(x0, x1)
- set_bound(x0, x1)
- # End of definition of internal function 'handle_single_axis'.
-
- handle_single_axis(
- scalex, self._autoscaleXon, self._shared_x_axes, 'intervalx',
- 'minposx', self.xaxis, self._xmargin, x_stickies, self.set_xbound)
- handle_single_axis(
- scaley, self._autoscaleYon, self._shared_y_axes, 'intervaly',
- 'minposy', self.yaxis, self._ymargin, y_stickies, self.set_ybound)
-
- def _get_axis_list(self):
- return (self.xaxis, self.yaxis)
-
- # Drawing
-
- @allow_rasterization
- def draw(self, renderer=None, inframe=False):
- """Draw everything (plot lines, axes, labels)"""
- if renderer is None:
- renderer = self._cachedRenderer
-
- if renderer is None:
- raise RuntimeError('No renderer defined')
- if not self.get_visible():
- return
- renderer.open_group('axes')
- # prevent triggering call backs during the draw process
- self._stale = True
- locator = self.get_axes_locator()
- if locator:
- pos = locator(self, renderer)
- self.apply_aspect(pos)
- else:
- self.apply_aspect()
-
- artists = self.get_children()
- artists.remove(self.patch)
-
- # the frame draws the edges around the axes patch -- we
- # decouple these so the patch can be in the background and the
- # frame in the foreground. Do this before drawing the axis
- # objects so that the spine has the opportunity to update them.
- if not (self.axison and self._frameon):
- for spine in six.itervalues(self.spines):
- artists.remove(spine)
-
- if self.axison and not inframe:
- if self._axisbelow is True:
- self.xaxis.set_zorder(0.5)
- self.yaxis.set_zorder(0.5)
- elif self._axisbelow is False:
- self.xaxis.set_zorder(2.5)
- self.yaxis.set_zorder(2.5)
- else:
- # 'line': above patches, below lines
- self.xaxis.set_zorder(1.5)
- self.yaxis.set_zorder(1.5)
- else:
- for _axis in self._get_axis_list():
- artists.remove(_axis)
-
- if inframe:
- artists.remove(self.title)
- artists.remove(self._left_title)
- artists.remove(self._right_title)
-
- if not self.figure.canvas.is_saving():
- artists = [a for a in artists
- if not a.get_animated() or a in self.images]
- artists = sorted(artists, key=attrgetter('zorder'))
-
- # rasterize artists with negative zorder
- # if the minimum zorder is negative, start rasterization
- rasterization_zorder = self._rasterization_zorder
- if (rasterization_zorder is not None and
- artists and artists[0].zorder < rasterization_zorder):
- renderer.start_rasterizing()
- artists_rasterized = [a for a in artists
- if a.zorder < rasterization_zorder]
- artists = [a for a in artists
- if a.zorder >= rasterization_zorder]
- else:
- artists_rasterized = []
-
- # the patch draws the background rectangle -- the frame below
- # will draw the edges
- if self.axison and self._frameon:
- self.patch.draw(renderer)
-
- if artists_rasterized:
- for a in artists_rasterized:
- a.draw(renderer)
- renderer.stop_rasterizing()
-
- mimage._draw_list_compositing_images(renderer, self, artists)
-
- renderer.close_group('axes')
- self._cachedRenderer = renderer
- self.stale = False
-
- def draw_artist(self, a):
- """
- This method can only be used after an initial draw which
- caches the renderer. It is used to efficiently update Axes
- data (axis ticks, labels, etc are not updated)
- """
- if self._cachedRenderer is None:
- raise AttributeError("draw_artist can only be used after an "
- "initial draw which caches the renderer")
- a.draw(self._cachedRenderer)
-
- def redraw_in_frame(self):
- """
- This method can only be used after an initial draw which
- caches the renderer. It is used to efficiently update Axes
- data (axis ticks, labels, etc are not updated)
- """
- if self._cachedRenderer is None:
- raise AttributeError("redraw_in_frame can only be used after an "
- "initial draw which caches the renderer")
- self.draw(self._cachedRenderer, inframe=True)
-
- def get_renderer_cache(self):
- return self._cachedRenderer
-
- # Axes rectangle characteristics
-
- def get_frame_on(self):
- """
- Get whether the axes rectangle patch is drawn.
- """
- return self._frameon
-
- def set_frame_on(self, b):
- """
- Set whether the axes rectangle patch is drawn.
-
- .. ACCEPTS: bool
-
- Parameters
- ----------
- b : bool
- """
- self._frameon = b
- self.stale = True
-
- def get_axisbelow(self):
- """
- Get whether axis ticks and gridlines are above or below most artists.
- """
- return self._axisbelow
-
- def set_axisbelow(self, b):
- """
- Set whether axis ticks and gridlines are above or below most artists.
-
- .. ACCEPTS: [ bool | 'line' ]
-
- Parameters
- ----------
- b : bool or 'line'
- """
- self._axisbelow = validate_axisbelow(b)
- self.stale = True
-
- @docstring.dedent_interpd
- def grid(self, b=None, which='major', axis='both', **kwargs):
- """
- Turn the axes grids on or off.
-
- Set the axes grids on or off; *b* is a boolean.
-
- If *b* is *None* and ``len(kwargs)==0``, toggle the grid state. If
- *kwargs* are supplied, it is assumed that you want a grid and *b*
- is thus set to *True*.
-
- *which* can be 'major' (default), 'minor', or 'both' to control
- whether major tick grids, minor tick grids, or both are affected.
-
- *axis* can be 'both' (default), 'x', or 'y' to control which
- set of gridlines are drawn.
-
- *kwargs* are used to set the grid line properties, e.g.,::
-
- ax.grid(color='r', linestyle='-', linewidth=2)
-
- Valid :class:`~matplotlib.lines.Line2D` kwargs are
-
- %(Line2D)s
-
- """
- if len(kwargs):
- b = True
- elif b is not None:
- b = _string_to_bool(b)
-
- if axis == 'x' or axis == 'both':
- self.xaxis.grid(b, which=which, **kwargs)
- if axis == 'y' or axis == 'both':
- self.yaxis.grid(b, which=which, **kwargs)
-
- def ticklabel_format(self, **kwargs):
- """
- Change the `~matplotlib.ticker.ScalarFormatter` used by
- default for linear axes.
-
- Optional keyword arguments:
-
- ============== =========================================
- Keyword Description
- ============== =========================================
- *style* [ 'sci' (or 'scientific') | 'plain' ]
- plain turns off scientific notation
- *scilimits* (m, n), pair of integers; if *style*
- is 'sci', scientific notation will
- be used for numbers outside the range
- 10`m`:sup: to 10`n`:sup:.
- Use (0,0) to include all numbers.
- *useOffset* [ bool | offset ]; if True,
- the offset will be calculated as needed;
- if False, no offset will be used; if a
- numeric offset is specified, it will be
- used.
- *axis* [ 'x' | 'y' | 'both' ]
- *useLocale* If True, format the number according to
- the current locale. This affects things
- such as the character used for the
- decimal separator. If False, use
- C-style (English) formatting. The
- default setting is controlled by the
- axes.formatter.use_locale rcparam.
- *useMathText* If True, render the offset and scientific
- notation in mathtext
- ============== =========================================
-
- Only the major ticks are affected.
- If the method is called when the
- :class:`~matplotlib.ticker.ScalarFormatter` is not the
- :class:`~matplotlib.ticker.Formatter` being used, an
- :exc:`AttributeError` will be raised.
-
- """
- style = kwargs.pop('style', '').lower()
- scilimits = kwargs.pop('scilimits', None)
- useOffset = kwargs.pop('useOffset', None)
- useLocale = kwargs.pop('useLocale', None)
- useMathText = kwargs.pop('useMathText', None)
- axis = kwargs.pop('axis', 'both').lower()
- if scilimits is not None:
- try:
- m, n = scilimits
- m + n + 1 # check that both are numbers
- except (ValueError, TypeError):
- raise ValueError("scilimits must be a sequence of 2 integers")
- if style[:3] == 'sci':
- sb = True
- elif style == 'plain':
- sb = False
- elif style == 'comma':
- raise NotImplementedError("comma style remains to be added")
- elif style == '':
- sb = None
- else:
- raise ValueError("%s is not a valid style value")
- try:
- if sb is not None:
- if axis == 'both' or axis == 'x':
- self.xaxis.major.formatter.set_scientific(sb)
- if axis == 'both' or axis == 'y':
- self.yaxis.major.formatter.set_scientific(sb)
- if scilimits is not None:
- if axis == 'both' or axis == 'x':
- self.xaxis.major.formatter.set_powerlimits(scilimits)
- if axis == 'both' or axis == 'y':
- self.yaxis.major.formatter.set_powerlimits(scilimits)
- if useOffset is not None:
- if axis == 'both' or axis == 'x':
- self.xaxis.major.formatter.set_useOffset(useOffset)
- if axis == 'both' or axis == 'y':
- self.yaxis.major.formatter.set_useOffset(useOffset)
- if useLocale is not None:
- if axis == 'both' or axis == 'x':
- self.xaxis.major.formatter.set_useLocale(useLocale)
- if axis == 'both' or axis == 'y':
- self.yaxis.major.formatter.set_useLocale(useLocale)
- if useMathText is not None:
- if axis == 'both' or axis == 'x':
- self.xaxis.major.formatter.set_useMathText(useMathText)
- if axis == 'both' or axis == 'y':
- self.yaxis.major.formatter.set_useMathText(useMathText)
- except AttributeError:
- raise AttributeError(
- "This method only works with the ScalarFormatter.")
-
- def locator_params(self, axis='both', tight=None, **kwargs):
- """
- Control behavior of tick locators.
-
- Parameters
- ----------
- axis : ['both' | 'x' | 'y'], optional
- The axis on which to operate.
-
- tight : bool or None, optional
- Parameter passed to :meth:`autoscale_view`.
- Default is None, for no change.
-
- Other Parameters
- ----------------
- **kw :
- Remaining keyword arguments are passed to directly to the
- :meth:`~matplotlib.ticker.MaxNLocator.set_params` method.
-
- Typically one might want to reduce the maximum number
- of ticks and use tight bounds when plotting small
- subplots, for example::
-
- ax.locator_params(tight=True, nbins=4)
-
- Because the locator is involved in autoscaling,
- :meth:`autoscale_view` is called automatically after
- the parameters are changed.
-
- This presently works only for the
- :class:`~matplotlib.ticker.MaxNLocator` used
- by default on linear axes, but it may be generalized.
- """
- _x = axis in ['x', 'both']
- _y = axis in ['y', 'both']
- if _x:
- self.xaxis.get_major_locator().set_params(**kwargs)
- if _y:
- self.yaxis.get_major_locator().set_params(**kwargs)
- self.autoscale_view(tight=tight, scalex=_x, scaley=_y)
-
- def tick_params(self, axis='both', **kwargs):
- """Change the appearance of ticks, tick labels, and gridlines.
-
- Parameters
- ----------
- axis : {'x', 'y', 'both'}, optional
- Which axis to apply the parameters to.
-
- Other Parameters
- ----------------
-
- axis : {'x', 'y', 'both'}
- Axis on which to operate; default is 'both'.
-
- reset : bool
- If *True*, set all parameters to defaults
- before processing other keyword arguments. Default is
- *False*.
-
- which : {'major', 'minor', 'both'}
- Default is 'major'; apply arguments to *which* ticks.
-
- direction : {'in', 'out', 'inout'}
- Puts ticks inside the axes, outside the axes, or both.
-
- length : float
- Tick length in points.
-
- width : float
- Tick width in points.
-
- color : color
- Tick color; accepts any mpl color spec.
-
- pad : float
- Distance in points between tick and label.
-
- labelsize : float or str
- Tick label font size in points or as a string (e.g., 'large').
-
- labelcolor : color
- Tick label color; mpl color spec.
-
- colors : color
- Changes the tick color and the label color to the same value:
- mpl color spec.
-
- zorder : float
- Tick and label zorder.
-
- bottom, top, left, right : bool
- Whether to draw the respective ticks.
-
- labelbottom, labeltop, labelleft, labelright : bool
- Whether to draw the respective tick labels.
-
- labelrotation : float
- Tick label rotation
-
- grid_color : color
- Changes the gridline color to the given mpl color spec.
-
- grid_alpha : float
- Transparency of gridlines: 0 (transparent) to 1 (opaque).
-
- grid_linewidth : float
- Width of gridlines in points.
-
- grid_linestyle : string
- Any valid :class:`~matplotlib.lines.Line2D` line style spec.
-
- Examples
- --------
-
- Usage ::
-
- ax.tick_params(direction='out', length=6, width=2, colors='r',
- grid_color='r', grid_alpha=0.5)
-
- This will make all major ticks be red, pointing out of the box,
- and with dimensions 6 points by 2 points. Tick labels will
- also be red. Gridlines will be red and translucent.
-
- """
- if axis in ['x', 'both']:
- xkw = dict(kwargs)
- xkw.pop('left', None)
- xkw.pop('right', None)
- xkw.pop('labelleft', None)
- xkw.pop('labelright', None)
- self.xaxis.set_tick_params(**xkw)
- if axis in ['y', 'both']:
- ykw = dict(kwargs)
- ykw.pop('top', None)
- ykw.pop('bottom', None)
- ykw.pop('labeltop', None)
- ykw.pop('labelbottom', None)
- self.yaxis.set_tick_params(**ykw)
-
- def set_axis_off(self):
- """Turn off the axis."""
- self.axison = False
- self.stale = True
-
- def set_axis_on(self):
- """Turn on the axis."""
- self.axison = True
- self.stale = True
-
- # data limits, ticks, tick labels, and formatting
-
- def invert_xaxis(self):
- """Invert the x-axis."""
- self.set_xlim(self.get_xlim()[::-1], auto=None)
-
- def xaxis_inverted(self):
- """Return whether the x-axis is inverted."""
- left, right = self.get_xlim()
- return right < left
-
- def get_xbound(self):
- """Return the lower and upper x-axis bounds, in increasing order."""
- left, right = self.get_xlim()
- if left < right:
- return left, right
- else:
- return right, left
-
- def set_xbound(self, lower=None, upper=None):
- """
- Set the lower and upper numerical bounds of the x-axis.
-
- This method will honor axes inversion regardless of parameter order.
- It will not change the _autoscaleXon attribute.
-
- .. ACCEPTS: (lower: float, upper: float)
- """
- if upper is None and iterable(lower):
- lower, upper = lower
-
- old_lower, old_upper = self.get_xbound()
-
- if lower is None:
- lower = old_lower
- if upper is None:
- upper = old_upper
-
- if self.xaxis_inverted():
- if lower < upper:
- self.set_xlim(upper, lower, auto=None)
- else:
- self.set_xlim(lower, upper, auto=None)
- else:
- if lower < upper:
- self.set_xlim(lower, upper, auto=None)
- else:
- self.set_xlim(upper, lower, auto=None)
-
- def get_xlim(self):
- """
- Get the x-axis range
-
- Returns
- -------
- xlimits : tuple
- Returns the current x-axis limits as the tuple
- (`left`, `right`).
-
- Notes
- -----
- The x-axis may be inverted, in which case the `left` value will
- be greater than the `right` value.
-
- """
- return tuple(self.viewLim.intervalx)
-
- def _validate_converted_limits(self, limit, convert):
- """
- Raise ValueError if converted limits are non-finite.
-
- Note that this function also accepts None as a limit argument.
-
- Returns
- -------
- The limit value after call to convert(), or None if limit is None.
-
- """
- if limit is not None:
- converted_limit = convert(limit)
- if (isinstance(converted_limit, float) and
- (not np.isreal(converted_limit) or
- not np.isfinite(converted_limit))):
- raise ValueError("Axis limits cannot be NaN or Inf")
- return converted_limit
-
- def set_xlim(self, left=None, right=None, emit=True, auto=False, **kw):
- """
- Set the data limits for the x-axis
-
- .. ACCEPTS: (left: float, right: float)
-
- Parameters
- ----------
- left : scalar, optional
- The left xlim (default: None, which leaves the left limit
- unchanged).
-
- right : scalar, optional
- The right xlim (default: None, which leaves the right limit
- unchanged).
-
- emit : bool, optional
- Whether to notify observers of limit change (default: True).
-
- auto : bool or None, optional
- Whether to turn on autoscaling of the x-axis. True turns on,
- False turns off (default action), None leaves unchanged.
-
- xlimits : tuple, optional
- The left and right xlims may be passed as the tuple
- (`left`, `right`) as the first positional argument (or as
- the `left` keyword argument).
-
- Returns
- -------
- xlimits : tuple
- Returns the new x-axis limits as (`left`, `right`).
-
- Notes
- -----
- The `left` value may be greater than the `right` value, in which
- case the x-axis values will decrease from left to right.
-
- Examples
- --------
- >>> set_xlim(left, right)
- >>> set_xlim((left, right))
- >>> left, right = set_xlim(left, right)
-
- One limit may be left unchanged.
-
- >>> set_xlim(right=right_lim)
-
- Limits may be passed in reverse order to flip the direction of
- the x-axis. For example, suppose `x` represents the number of
- years before present. The x-axis limits might be set like the
- following so 5000 years ago is on the left of the plot and the
- present is on the right.
-
- >>> set_xlim(5000, 0)
-
- """
- if 'xmin' in kw:
- left = kw.pop('xmin')
- if 'xmax' in kw:
- right = kw.pop('xmax')
- if kw:
- raise ValueError("unrecognized kwargs: %s" % list(kw))
-
- if right is None and iterable(left):
- left, right = left
-
- self._process_unit_info(xdata=(left, right))
- left = self._validate_converted_limits(left, self.convert_xunits)
- right = self._validate_converted_limits(right, self.convert_xunits)
-
- old_left, old_right = self.get_xlim()
- if left is None:
- left = old_left
- if right is None:
- right = old_right
-
- if left == right:
- warnings.warn(
- ('Attempting to set identical left==right results\n'
- 'in singular transformations; automatically expanding.\n'
- 'left=%s, right=%s') % (left, right))
- left, right = mtransforms.nonsingular(left, right, increasing=False)
-
- if self.get_xscale() == 'log' and (left <= 0.0 or right <= 0.0):
- warnings.warn(
- 'Attempted to set non-positive xlimits for log-scale axis; '
- 'invalid limits will be ignored.')
- left, right = self.xaxis.limit_range_for_scale(left, right)
-
- self.viewLim.intervalx = (left, right)
- if auto is not None:
- self._autoscaleXon = bool(auto)
-
- if emit:
- self.callbacks.process('xlim_changed', self)
- # Call all of the other x-axes that are shared with this one
- for other in self._shared_x_axes.get_siblings(self):
- if other is not self:
- other.set_xlim(self.viewLim.intervalx,
- emit=False, auto=auto)
- if (other.figure != self.figure and
- other.figure.canvas is not None):
- other.figure.canvas.draw_idle()
- self.stale = True
- return left, right
-
- def get_xscale(self):
- return self.xaxis.get_scale()
- get_xscale.__doc__ = "Return the xaxis scale string: %s""" % (
- ", ".join(mscale.get_scale_names()))
-
- def set_xscale(self, value, **kwargs):
- """
- Set the x-axis scale.
-
- .. ACCEPTS: [ 'linear' | 'log' | 'symlog' | 'logit' | ... ]
-
- Parameters
- ----------
- value : {"linear", "log", "symlog", "logit"}
- scaling strategy to apply
-
- Notes
- -----
- Different kwargs are accepted, depending on the scale. See
- the `~matplotlib.scale` module for more information.
-
- See also
- --------
- matplotlib.scale.LinearScale : linear transform
-
- matplotlib.scale.LogTransform : log transform
-
- matplotlib.scale.SymmetricalLogTransform : symlog transform
-
- matplotlib.scale.LogisticTransform : logit transform
- """
- g = self.get_shared_x_axes()
- for ax in g.get_siblings(self):
- ax.xaxis._set_scale(value, **kwargs)
- ax._update_transScale()
- ax.stale = True
-
- self.autoscale_view(scaley=False)
-
- def get_xticks(self, minor=False):
- """Return the x ticks as a list of locations"""
- return self.xaxis.get_ticklocs(minor=minor)
-
- def set_xticks(self, ticks, minor=False):
- """
- Set the x ticks with list of *ticks*
-
- .. ACCEPTS: list of tick locations.
-
- Parameters
- ----------
- ticks : list
- List of x-axis tick locations.
-
- minor : bool, optional
- If ``False`` sets major ticks, if ``True`` sets minor ticks.
- Default is ``False``.
- """
- ret = self.xaxis.set_ticks(ticks, minor=minor)
- self.stale = True
- return ret
-
- def get_xmajorticklabels(self):
- """
- Get the major x tick labels.
-
- Returns
- -------
- labels : list
- List of :class:`~matplotlib.text.Text` instances
- """
- return cbook.silent_list('Text xticklabel',
- self.xaxis.get_majorticklabels())
-
- def get_xminorticklabels(self):
- """
- Get the minor x tick labels.
-
- Returns
- -------
- labels : list
- List of :class:`~matplotlib.text.Text` instances
- """
- return cbook.silent_list('Text xticklabel',
- self.xaxis.get_minorticklabels())
-
- def get_xticklabels(self, minor=False, which=None):
- """
- Get the x tick labels as a list of :class:`~matplotlib.text.Text`
- instances.
-
- Parameters
- ----------
- minor : bool, optional
- If True return the minor ticklabels,
- else return the major ticklabels.
-
- which : None, ('minor', 'major', 'both')
- Overrides `minor`.
-
- Selects which ticklabels to return
-
- Returns
- -------
- ret : list
- List of :class:`~matplotlib.text.Text` instances.
- """
- return cbook.silent_list('Text xticklabel',
- self.xaxis.get_ticklabels(minor=minor,
- which=which))
-
- def set_xticklabels(self, labels, fontdict=None, minor=False, **kwargs):
- """
- Set the x-tick labels with list of string labels.
-
- .. ACCEPTS: list of string labels
-
- Parameters
- ----------
- labels : list of str
- List of string labels.
-
- fontdict : dict, optional
- A dictionary controlling the appearance of the ticklabels.
- The default `fontdict` is::
-
- {'fontsize': rcParams['axes.titlesize'],
- 'fontweight': rcParams['axes.titleweight'],
- 'verticalalignment': 'baseline',
- 'horizontalalignment': loc}
-
- minor : bool, optional
- Whether to set the minor ticklabels rather than the major ones.
-
- Returns
- -------
- A list of `~.text.Text` instances.
-
- Other Parameters
- -----------------
- **kwargs : `~.text.Text` properties.
- """
- if fontdict is not None:
- kwargs.update(fontdict)
- ret = self.xaxis.set_ticklabels(labels,
- minor=minor, **kwargs)
- self.stale = True
- return ret
-
- def invert_yaxis(self):
- """Invert the y-axis."""
- self.set_ylim(self.get_ylim()[::-1], auto=None)
-
- def yaxis_inverted(self):
- """Return whether the y-axis is inverted."""
- bottom, top = self.get_ylim()
- return top < bottom
-
- def get_ybound(self):
- """Return the lower and upper y-axis bounds, in increasing order."""
- bottom, top = self.get_ylim()
- if bottom < top:
- return bottom, top
- else:
- return top, bottom
-
- def set_ybound(self, lower=None, upper=None):
- """
- Set the lower and upper numerical bounds of the y-axis.
- This method will honor axes inversion regardless of parameter order.
- It will not change the _autoscaleYon attribute.
-
- .. ACCEPTS: (lower: float, upper: float)
- """
- if upper is None and iterable(lower):
- lower, upper = lower
-
- old_lower, old_upper = self.get_ybound()
-
- if lower is None:
- lower = old_lower
- if upper is None:
- upper = old_upper
-
- if self.yaxis_inverted():
- if lower < upper:
- self.set_ylim(upper, lower, auto=None)
- else:
- self.set_ylim(lower, upper, auto=None)
- else:
- if lower < upper:
- self.set_ylim(lower, upper, auto=None)
- else:
- self.set_ylim(upper, lower, auto=None)
-
- def get_ylim(self):
- """
- Get the y-axis range
-
- Returns
- -------
- ylimits : tuple
- Returns the current y-axis limits as the tuple
- (`bottom`, `top`).
-
- Notes
- -----
- The y-axis may be inverted, in which case the `bottom` value
- will be greater than the `top` value.
-
- """
- return tuple(self.viewLim.intervaly)
-
- def set_ylim(self, bottom=None, top=None, emit=True, auto=False, **kw):
- """
- Set the data limits for the y-axis
-
- .. ACCEPTS: (bottom: float, top: float)
-
- Parameters
- ----------
- bottom : scalar, optional
- The bottom ylim (default: None, which leaves the bottom
- limit unchanged).
-
- top : scalar, optional
- The top ylim (default: None, which leaves the top limit
- unchanged).
-
- emit : bool, optional
- Whether to notify observers of limit change (default: True).
-
- auto : bool or None, optional
- Whether to turn on autoscaling of the y-axis. True turns on,
- False turns off (default action), None leaves unchanged.
-
- ylimits : tuple, optional
- The bottom and top yxlims may be passed as the tuple
- (`bottom`, `top`) as the first positional argument (or as
- the `bottom` keyword argument).
-
- Returns
- -------
- ylimits : tuple
- Returns the new y-axis limits as (`bottom`, `top`).
-
- Notes
- -----
- The `bottom` value may be greater than the `top` value, in which
- case the y-axis values will decrease from bottom to top.
-
- Examples
- --------
- >>> set_ylim(bottom, top)
- >>> set_ylim((bottom, top))
- >>> bottom, top = set_ylim(bottom, top)
-
- One limit may be left unchanged.
-
- >>> set_ylim(top=top_lim)
-
- Limits may be passed in reverse order to flip the direction of
- the y-axis. For example, suppose `y` represents depth of the
- ocean in m. The y-axis limits might be set like the following
- so 5000 m depth is at the bottom of the plot and the surface,
- 0 m, is at the top.
-
- >>> set_ylim(5000, 0)
- """
- if 'ymin' in kw:
- bottom = kw.pop('ymin')
- if 'ymax' in kw:
- top = kw.pop('ymax')
- if kw:
- raise ValueError("unrecognized kwargs: %s" % list(kw))
-
- if top is None and iterable(bottom):
- bottom, top = bottom
-
- bottom = self._validate_converted_limits(bottom, self.convert_yunits)
- top = self._validate_converted_limits(top, self.convert_yunits)
-
- old_bottom, old_top = self.get_ylim()
-
- if bottom is None:
- bottom = old_bottom
- if top is None:
- top = old_top
-
- if bottom == top:
- warnings.warn(
- ('Attempting to set identical bottom==top results\n'
- 'in singular transformations; automatically expanding.\n'
- 'bottom=%s, top=%s') % (bottom, top))
-
- bottom, top = mtransforms.nonsingular(bottom, top, increasing=False)
-
- if self.get_yscale() == 'log' and (bottom <= 0.0 or top <= 0.0):
- warnings.warn(
- 'Attempted to set non-positive ylimits for log-scale axis; '
- 'invalid limits will be ignored.')
- bottom, top = self.yaxis.limit_range_for_scale(bottom, top)
-
- self.viewLim.intervaly = (bottom, top)
- if auto is not None:
- self._autoscaleYon = bool(auto)
-
- if emit:
- self.callbacks.process('ylim_changed', self)
- # Call all of the other y-axes that are shared with this one
- for other in self._shared_y_axes.get_siblings(self):
- if other is not self:
- other.set_ylim(self.viewLim.intervaly,
- emit=False, auto=auto)
- if (other.figure != self.figure and
- other.figure.canvas is not None):
- other.figure.canvas.draw_idle()
- self.stale = True
- return bottom, top
-
- def get_yscale(self):
- return self.yaxis.get_scale()
- get_yscale.__doc__ = "Return the yaxis scale string: %s""" % (
- ", ".join(mscale.get_scale_names()))
-
- def set_yscale(self, value, **kwargs):
- """
- Set the y-axis scale.
-
- .. ACCEPTS: [ 'linear' | 'log' | 'symlog' | 'logit' | ... ]
-
- Parameters
- ----------
- value : {"linear", "log", "symlog", "logit"}
- scaling strategy to apply
-
- Notes
- -----
- Different kwargs are accepted, depending on the scale. See
- the `~matplotlib.scale` module for more information.
-
- See also
- --------
- matplotlib.scale.LinearScale : linear transform
-
- matplotlib.scale.LogTransform : log transform
-
- matplotlib.scale.SymmetricalLogTransform : symlog transform
-
- matplotlib.scale.LogisticTransform : logit transform
- """
- g = self.get_shared_y_axes()
- for ax in g.get_siblings(self):
- ax.yaxis._set_scale(value, **kwargs)
- ax._update_transScale()
- ax.stale = True
- self.autoscale_view(scalex=False)
-
- def get_yticks(self, minor=False):
- """Return the y ticks as a list of locations"""
- return self.yaxis.get_ticklocs(minor=minor)
-
- def set_yticks(self, ticks, minor=False):
- """
- Set the y ticks with list of *ticks*
-
- .. ACCEPTS: list of tick locations.
-
- Parameters
- ----------
- ticks : sequence
- List of y-axis tick locations
-
- minor : bool, optional
- If ``False`` sets major ticks, if ``True`` sets minor ticks.
- Default is ``False``.
- """
- ret = self.yaxis.set_ticks(ticks, minor=minor)
- return ret
-
- def get_ymajorticklabels(self):
- """
- Get the major y tick labels.
-
- Returns
- -------
- labels : list
- List of :class:`~matplotlib.text.Text` instances
- """
- return cbook.silent_list('Text yticklabel',
- self.yaxis.get_majorticklabels())
-
- def get_yminorticklabels(self):
- """
- Get the minor y tick labels.
-
- Returns
- -------
- labels : list
- List of :class:`~matplotlib.text.Text` instances
- """
- return cbook.silent_list('Text yticklabel',
- self.yaxis.get_minorticklabels())
-
- def get_yticklabels(self, minor=False, which=None):
- """
- Get the y tick labels as a list of :class:`~matplotlib.text.Text`
- instances.
-
- Parameters
- ----------
- minor : bool
- If True return the minor ticklabels,
- else return the major ticklabels
-
- which : None, ('minor', 'major', 'both')
- Overrides `minor`.
-
- Selects which ticklabels to return
-
- Returns
- -------
- ret : list
- List of :class:`~matplotlib.text.Text` instances.
- """
- return cbook.silent_list('Text yticklabel',
- self.yaxis.get_ticklabels(minor=minor,
- which=which))
-
- def set_yticklabels(self, labels, fontdict=None, minor=False, **kwargs):
- """
- Set the y-tick labels with list of strings labels.
-
- .. ACCEPTS: list of string labels
-
- Parameters
- ----------
- labels : list of str
- list of string labels
-
- fontdict : dict, optional
- A dictionary controlling the appearance of the ticklabels.
- The default `fontdict` is::
-
- {'fontsize': rcParams['axes.titlesize'],
- 'fontweight': rcParams['axes.titleweight'],
- 'verticalalignment': 'baseline',
- 'horizontalalignment': loc}
-
- minor : bool, optional
- Whether to set the minor ticklabels rather than the major ones.
-
- Returns
- -------
- A list of `~.text.Text` instances.
-
- Other Parameters
- ----------------
- **kwargs : `~.text.Text` properties.
- """
- if fontdict is not None:
- kwargs.update(fontdict)
- return self.yaxis.set_ticklabels(labels,
- minor=minor, **kwargs)
-
- def xaxis_date(self, tz=None):
- """
- Sets up x-axis ticks and labels that treat the x data as dates.
-
- Parameters
- ----------
- tz : string or :class:`tzinfo` instance, optional
- Timezone string or timezone. Defaults to rc value.
- """
- # should be enough to inform the unit conversion interface
- # dates are coming in
- self.xaxis.axis_date(tz)
-
- def yaxis_date(self, tz=None):
- """
- Sets up y-axis ticks and labels that treat the y data as dates.
-
- Parameters
- ----------
- tz : string or :class:`tzinfo` instance, optional
- Timezone string or timezone. Defaults to rc value.
- """
- self.yaxis.axis_date(tz)
-
- def format_xdata(self, x):
- """
- Return *x* string formatted. This function will use the attribute
- self.fmt_xdata if it is callable, else will fall back on the xaxis
- major formatter
- """
- try:
- return self.fmt_xdata(x)
- except TypeError:
- func = self.xaxis.get_major_formatter().format_data_short
- val = func(x)
- return val
-
- def format_ydata(self, y):
- """
- Return y string formatted. This function will use the
- :attr:`fmt_ydata` attribute if it is callable, else will fall
- back on the yaxis major formatter
- """
- try:
- return self.fmt_ydata(y)
- except TypeError:
- func = self.yaxis.get_major_formatter().format_data_short
- val = func(y)
- return val
-
- def format_coord(self, x, y):
- """Return a format string formatting the *x*, *y* coord"""
- if x is None:
- xs = '???'
- else:
- xs = self.format_xdata(x)
- if y is None:
- ys = '???'
- else:
- ys = self.format_ydata(y)
- return 'x=%s y=%s' % (xs, ys)
-
- def minorticks_on(self):
- 'Add autoscaling minor ticks to the axes.'
- for ax in (self.xaxis, self.yaxis):
- scale = ax.get_scale()
- if scale == 'log':
- s = ax._scale
- ax.set_minor_locator(mticker.LogLocator(s.base, s.subs))
- elif scale == 'symlog':
- s = ax._scale
- ax.set_minor_locator(
- mticker.SymmetricalLogLocator(s._transform, s.subs))
- else:
- ax.set_minor_locator(mticker.AutoMinorLocator())
-
- def minorticks_off(self):
- """Remove minor ticks from the axes."""
- self.xaxis.set_minor_locator(mticker.NullLocator())
- self.yaxis.set_minor_locator(mticker.NullLocator())
-
- # Interactive manipulation
-
- def can_zoom(self):
- """
- Return *True* if this axes supports the zoom box button functionality.
- """
- return True
-
- def can_pan(self):
- """
- Return *True* if this axes supports any pan/zoom button functionality.
- """
- return True
-
- def get_navigate(self):
- """
- Get whether the axes responds to navigation commands
- """
- return self._navigate
-
- def set_navigate(self, b):
- """
- Set whether the axes responds to navigation toolbar commands
-
- .. ACCEPTS: bool
-
- Parameters
- ----------
- b : bool
- """
- self._navigate = b
-
- def get_navigate_mode(self):
- """
- Get the navigation toolbar button status: 'PAN', 'ZOOM', or None
- """
- return self._navigate_mode
-
- def set_navigate_mode(self, b):
- """
- Set the navigation toolbar button status;
-
- .. warning::
- this is not a user-API function.
-
- """
- self._navigate_mode = b
-
- def _get_view(self):
- """
- Save information required to reproduce the current view.
-
- Called before a view is changed, such as during a pan or zoom
- initiated by the user. You may return any information you deem
- necessary to describe the view.
-
- .. note::
-
- Intended to be overridden by new projection types, but if not, the
- default implementation saves the view limits. You *must* implement
- :meth:`_set_view` if you implement this method.
- """
- xmin, xmax = self.get_xlim()
- ymin, ymax = self.get_ylim()
- return (xmin, xmax, ymin, ymax)
-
- def _set_view(self, view):
- """
- Apply a previously saved view.
-
- Called when restoring a view, such as with the navigation buttons.
-
- .. note::
-
- Intended to be overridden by new projection types, but if not, the
- default implementation restores the view limits. You *must*
- implement :meth:`_get_view` if you implement this method.
- """
- xmin, xmax, ymin, ymax = view
- self.set_xlim((xmin, xmax))
- self.set_ylim((ymin, ymax))
-
- def _set_view_from_bbox(self, bbox, direction='in',
- mode=None, twinx=False, twiny=False):
- """
- Update view from a selection bbox.
-
- .. note::
-
- Intended to be overridden by new projection types, but if not, the
- default implementation sets the view limits to the bbox directly.
-
- Parameters
- ----------
-
- bbox : 4-tuple or 3 tuple
- * If bbox is a 4 tuple, it is the selected bounding box limits,
- in *display* coordinates.
- * If bbox is a 3 tuple, it is an (xp, yp, scl) triple, where
- (xp,yp) is the center of zooming and scl the scale factor to
- zoom by.
-
- direction : str
- The direction to apply the bounding box.
- * `'in'` - The bounding box describes the view directly, i.e.,
- it zooms in.
- * `'out'` - The bounding box describes the size to make the
- existing view, i.e., it zooms out.
-
- mode : str or None
- The selection mode, whether to apply the bounding box in only the
- `'x'` direction, `'y'` direction or both (`None`).
-
- twinx : bool
- Whether this axis is twinned in the *x*-direction.
-
- twiny : bool
- Whether this axis is twinned in the *y*-direction.
- """
- Xmin, Xmax = self.get_xlim()
- Ymin, Ymax = self.get_ylim()
-
- if len(bbox) == 3:
- # Zooming code
- xp, yp, scl = bbox
-
- # Should not happen
- if scl == 0:
- scl = 1.
-
- # direction = 'in'
- if scl > 1:
- direction = 'in'
- else:
- direction = 'out'
- scl = 1/scl
-
- # get the limits of the axes
- tranD2C = self.transData.transform
- xmin, ymin = tranD2C((Xmin, Ymin))
- xmax, ymax = tranD2C((Xmax, Ymax))
-
- # set the range
- xwidth = xmax - xmin
- ywidth = ymax - ymin
- xcen = (xmax + xmin)*.5
- ycen = (ymax + ymin)*.5
- xzc = (xp*(scl - 1) + xcen)/scl
- yzc = (yp*(scl - 1) + ycen)/scl
-
- bbox = [xzc - xwidth/2./scl, yzc - ywidth/2./scl,
- xzc + xwidth/2./scl, yzc + ywidth/2./scl]
- elif len(bbox) != 4:
- # should be len 3 or 4 but nothing else
- warnings.warn(
- "Warning in _set_view_from_bbox: bounding box is not a tuple "
- "of length 3 or 4. Ignoring the view change.")
- return
-
- # Just grab bounding box
- lastx, lasty, x, y = bbox
-
- # zoom to rect
- inverse = self.transData.inverted()
- lastx, lasty = inverse.transform_point((lastx, lasty))
- x, y = inverse.transform_point((x, y))
-
- if twinx:
- x0, x1 = Xmin, Xmax
- else:
- if Xmin < Xmax:
- if x < lastx:
- x0, x1 = x, lastx
- else:
- x0, x1 = lastx, x
- if x0 < Xmin:
- x0 = Xmin
- if x1 > Xmax:
- x1 = Xmax
- else:
- if x > lastx:
- x0, x1 = x, lastx
- else:
- x0, x1 = lastx, x
- if x0 > Xmin:
- x0 = Xmin
- if x1 < Xmax:
- x1 = Xmax
-
- if twiny:
- y0, y1 = Ymin, Ymax
- else:
- if Ymin < Ymax:
- if y < lasty:
- y0, y1 = y, lasty
- else:
- y0, y1 = lasty, y
- if y0 < Ymin:
- y0 = Ymin
- if y1 > Ymax:
- y1 = Ymax
- else:
- if y > lasty:
- y0, y1 = y, lasty
- else:
- y0, y1 = lasty, y
- if y0 > Ymin:
- y0 = Ymin
- if y1 < Ymax:
- y1 = Ymax
-
- if direction == 'in':
- if mode == 'x':
- self.set_xlim((x0, x1))
- elif mode == 'y':
- self.set_ylim((y0, y1))
- else:
- self.set_xlim((x0, x1))
- self.set_ylim((y0, y1))
- elif direction == 'out':
- if self.get_xscale() == 'log':
- alpha = np.log(Xmax / Xmin) / np.log(x1 / x0)
- rx1 = pow(Xmin / x0, alpha) * Xmin
- rx2 = pow(Xmax / x0, alpha) * Xmin
- else:
- alpha = (Xmax - Xmin) / (x1 - x0)
- rx1 = alpha * (Xmin - x0) + Xmin
- rx2 = alpha * (Xmax - x0) + Xmin
- if self.get_yscale() == 'log':
- alpha = np.log(Ymax / Ymin) / np.log(y1 / y0)
- ry1 = pow(Ymin / y0, alpha) * Ymin
- ry2 = pow(Ymax / y0, alpha) * Ymin
- else:
- alpha = (Ymax - Ymin) / (y1 - y0)
- ry1 = alpha * (Ymin - y0) + Ymin
- ry2 = alpha * (Ymax - y0) + Ymin
-
- if mode == 'x':
- self.set_xlim((rx1, rx2))
- elif mode == 'y':
- self.set_ylim((ry1, ry2))
- else:
- self.set_xlim((rx1, rx2))
- self.set_ylim((ry1, ry2))
-
- def start_pan(self, x, y, button):
- """
- Called when a pan operation has started.
-
- *x*, *y* are the mouse coordinates in display coords.
- button is the mouse button number:
-
- * 1: LEFT
- * 2: MIDDLE
- * 3: RIGHT
-
- .. note::
-
- Intended to be overridden by new projection types.
-
- """
- self._pan_start = cbook.Bunch(
- lim=self.viewLim.frozen(),
- trans=self.transData.frozen(),
- trans_inverse=self.transData.inverted().frozen(),
- bbox=self.bbox.frozen(),
- x=x,
- y=y)
-
- def end_pan(self):
- """
- Called when a pan operation completes (when the mouse button
- is up.)
-
- .. note::
-
- Intended to be overridden by new projection types.
-
- """
- del self._pan_start
-
- def drag_pan(self, button, key, x, y):
- """
- Called when the mouse moves during a pan operation.
-
- *button* is the mouse button number:
-
- * 1: LEFT
- * 2: MIDDLE
- * 3: RIGHT
-
- *key* is a "shift" key
-
- *x*, *y* are the mouse coordinates in display coords.
-
- .. note::
-
- Intended to be overridden by new projection types.
-
- """
- def format_deltas(key, dx, dy):
- if key == 'control':
- if abs(dx) > abs(dy):
- dy = dx
- else:
- dx = dy
- elif key == 'x':
- dy = 0
- elif key == 'y':
- dx = 0
- elif key == 'shift':
- if 2 * abs(dx) < abs(dy):
- dx = 0
- elif 2 * abs(dy) < abs(dx):
- dy = 0
- elif abs(dx) > abs(dy):
- dy = dy / abs(dy) * abs(dx)
- else:
- dx = dx / abs(dx) * abs(dy)
- return dx, dy
-
- p = self._pan_start
- dx = x - p.x
- dy = y - p.y
- if dx == 0 and dy == 0:
- return
- if button == 1:
- dx, dy = format_deltas(key, dx, dy)
- result = p.bbox.translated(-dx, -dy).transformed(p.trans_inverse)
- elif button == 3:
- try:
- dx = -dx / self.bbox.width
- dy = -dy / self.bbox.height
- dx, dy = format_deltas(key, dx, dy)
- if self.get_aspect() != 'auto':
- dx = dy = 0.5 * (dx + dy)
- alpha = np.power(10.0, (dx, dy))
- start = np.array([p.x, p.y])
- oldpoints = p.lim.transformed(p.trans)
- newpoints = start + alpha * (oldpoints - start)
- result = (mtransforms.Bbox(newpoints)
- .transformed(p.trans_inverse))
- except OverflowError:
- warnings.warn('Overflow while panning')
- return
-
- valid = np.isfinite(result.transformed(p.trans))
- points = result.get_points().astype(object)
- # Just ignore invalid limits (typically, underflow in log-scale).
- points[~valid] = None
- self.set_xlim(points[:, 0])
- self.set_ylim(points[:, 1])
-
- @cbook.deprecated("2.1")
- def get_cursor_props(self):
- """
- Return the cursor propertiess as a (*linewidth*, *color*)
- tuple, where *linewidth* is a float and *color* is an RGBA
- tuple
- """
- return self._cursorProps
-
- @cbook.deprecated("2.1")
- def set_cursor_props(self, *args):
- """Set the cursor property as
-
- Call signature ::
-
- ax.set_cursor_props(linewidth, color)
-
- or::
-
- ax.set_cursor_props((linewidth, color))
-
- ACCEPTS: a (*float*, *color*) tuple
- """
- if len(args) == 1:
- lw, c = args[0]
- elif len(args) == 2:
- lw, c = args
- else:
- raise ValueError('args must be a (linewidth, color) tuple')
- c = mcolors.to_rgba(c)
- self._cursorProps = lw, c
-
- def get_children(self):
- """return a list of child artists"""
- children = []
- children.extend(self.collections)
- children.extend(self.patches)
- children.extend(self.lines)
- children.extend(self.texts)
- children.extend(self.artists)
- children.extend(six.itervalues(self.spines))
- children.append(self.xaxis)
- children.append(self.yaxis)
- children.append(self.title)
- children.append(self._left_title)
- children.append(self._right_title)
- children.extend(self.tables)
- children.extend(self.images)
- if self.legend_ is not None:
- children.append(self.legend_)
- children.append(self.patch)
- return children
-
- def contains(self, mouseevent):
- """
- Test whether the mouse event occurred in the axes.
-
- Returns *True* / *False*, {}
- """
- if callable(self._contains):
- return self._contains(self, mouseevent)
- return self.patch.contains(mouseevent)
-
- def contains_point(self, point):
- """
- Returns *True* if the point (tuple of x,y) is inside the axes
- (the area defined by the its patch). A pixel coordinate is
- required.
-
- """
- return self.patch.contains_point(point, radius=1.0)
-
- def pick(self, *args):
- """Trigger pick event
-
- Call signature::
-
- pick(mouseevent)
-
- each child artist will fire a pick event if mouseevent is over
- the artist and the artist has picker set
- """
- martist.Artist.pick(self, args[0])
-
- def get_default_bbox_extra_artists(self):
- return [artist for artist in self.get_children()
- if artist.get_visible()]
-
- def get_tightbbox(self, renderer, call_axes_locator=True):
- """
- Return the tight bounding box of the axes.
- The dimension of the Bbox in canvas coordinate.
-
- If *call_axes_locator* is *False*, it does not call the
- _axes_locator attribute, which is necessary to get the correct
- bounding box. ``call_axes_locator==False`` can be used if the
- caller is only intereted in the relative size of the tightbbox
- compared to the axes bbox.
- """
-
- bb = []
-
- if not self.get_visible():
- return None
-
- locator = self.get_axes_locator()
- if locator and call_axes_locator:
- pos = locator(self, renderer)
- self.apply_aspect(pos)
- else:
- self.apply_aspect()
-
- bb.append(self.get_window_extent(renderer))
-
- if self.title.get_visible():
- bb.append(self.title.get_window_extent(renderer))
- if self._left_title.get_visible():
- bb.append(self._left_title.get_window_extent(renderer))
- if self._right_title.get_visible():
- bb.append(self._right_title.get_window_extent(renderer))
-
- bb_xaxis = self.xaxis.get_tightbbox(renderer)
- if bb_xaxis:
- bb.append(bb_xaxis)
-
- bb_yaxis = self.yaxis.get_tightbbox(renderer)
- if bb_yaxis:
- bb.append(bb_yaxis)
-
- for child in self.get_children():
- if isinstance(child, OffsetBox) and child.get_visible():
- bb.append(child.get_window_extent(renderer))
- elif isinstance(child, Legend) and child.get_visible():
- bb.append(child._legend_box.get_window_extent(renderer))
-
- _bbox = mtransforms.Bbox.union(
- [b for b in bb if b.width != 0 or b.height != 0])
-
- return _bbox
-
- def _make_twin_axes(self, *kl, **kwargs):
- """
- Make a twinx axes of self. This is used for twinx and twiny.
- """
- # Typically, SubplotBase._make_twin_axes is called instead of this.
- # There is also an override in axes_grid1/axes_divider.py.
- if 'sharex' in kwargs and 'sharey' in kwargs:
- raise ValueError("Twinned Axes may share only one axis.")
- ax2 = self.figure.add_axes(self.get_position(True), *kl, **kwargs)
- self.set_adjustable('datalim')
- ax2.set_adjustable('datalim')
- self._twinned_axes.join(self, ax2)
- return ax2
-
- def twinx(self):
- """
- Create a twin Axes sharing the xaxis
-
- Create a new Axes instance with an invisible x-axis and an independent
- y-axis positioned opposite to the original one (i.e. at right). The
- x-axis autoscale setting will be inherited from the original Axes.
- To ensure that the tick marks of both y-axes align, see
- `~matplotlib.ticker.LinearLocator`
-
- Returns
- -------
- ax_twin : Axes
- The newly created Axes instance
-
- Notes
- -----
- For those who are 'picking' artists while using twinx, pick
- events are only called for the artists in the top-most axes.
- """
- ax2 = self._make_twin_axes(sharex=self)
- ax2.yaxis.tick_right()
- ax2.yaxis.set_label_position('right')
- ax2.yaxis.set_offset_position('right')
- ax2.set_autoscalex_on(self.get_autoscalex_on())
- self.yaxis.tick_left()
- ax2.xaxis.set_visible(False)
- ax2.patch.set_visible(False)
- return ax2
-
- def twiny(self):
- """
- Create a twin Axes sharing the yaxis
-
- Create a new Axes instance with an invisible y-axis and an independent
- x-axis positioned opposite to the original one (i.e. at top). The
- y-axis autoscale setting will be inherited from the original Axes.
- To ensure that the tick marks of both x-axes align, see
- `~matplotlib.ticker.LinearLocator`
-
- Returns
- -------
- ax_twin : Axes
- The newly created Axes instance
-
- Notes
- -----
- For those who are 'picking' artists while using twiny, pick
- events are only called for the artists in the top-most axes.
- """
-
- ax2 = self._make_twin_axes(sharey=self)
- ax2.xaxis.tick_top()
- ax2.xaxis.set_label_position('top')
- ax2.set_autoscaley_on(self.get_autoscaley_on())
- self.xaxis.tick_bottom()
- ax2.yaxis.set_visible(False)
- ax2.patch.set_visible(False)
- return ax2
-
- def get_shared_x_axes(self):
- """Return a reference to the shared axes Grouper object for x axes."""
- return self._shared_x_axes
-
- def get_shared_y_axes(self):
- """Return a reference to the shared axes Grouper object for y axes."""
- return self._shared_y_axes
diff --git a/contrib/python/matplotlib/py2/matplotlib/axes/_subplots.py b/contrib/python/matplotlib/py2/matplotlib/axes/_subplots.py
deleted file mode 100644
index 4c93ed996a..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/axes/_subplots.py
+++ /dev/null
@@ -1,267 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import map
-
-from matplotlib.gridspec import GridSpec, SubplotSpec
-from matplotlib import docstring
-import matplotlib.artist as martist
-from matplotlib.axes._axes import Axes
-
-import matplotlib._layoutbox as layoutbox
-
-import warnings
-from matplotlib.cbook import mplDeprecation
-
-
-class SubplotBase(object):
- """
- Base class for subplots, which are :class:`Axes` instances with
- additional methods to facilitate generating and manipulating a set
- of :class:`Axes` within a figure.
- """
-
- def __init__(self, fig, *args, **kwargs):
- """
- *fig* is a :class:`matplotlib.figure.Figure` instance.
-
- *args* is the tuple (*numRows*, *numCols*, *plotNum*), where
- the array of subplots in the figure has dimensions *numRows*,
- *numCols*, and where *plotNum* is the number of the subplot
- being created. *plotNum* starts at 1 in the upper left
- corner and increases to the right.
-
- If *numRows* <= *numCols* <= *plotNum* < 10, *args* can be the
- decimal integer *numRows* * 100 + *numCols* * 10 + *plotNum*.
- """
-
- self.figure = fig
-
- if len(args) == 1:
- if isinstance(args[0], SubplotSpec):
- self._subplotspec = args[0]
- else:
- try:
- s = str(int(args[0]))
- rows, cols, num = map(int, s)
- except ValueError:
- raise ValueError('Single argument to subplot must be '
- 'a 3-digit integer')
- self._subplotspec = GridSpec(rows, cols,
- figure=self.figure)[num - 1]
- # num - 1 for converting from MATLAB to python indexing
- elif len(args) == 3:
- rows, cols, num = args
- rows = int(rows)
- cols = int(cols)
- if isinstance(num, tuple) and len(num) == 2:
- num = [int(n) for n in num]
- self._subplotspec = GridSpec(
- rows, cols,
- figure=self.figure)[(num[0] - 1):num[1]]
- else:
- if num < 1 or num > rows*cols:
- raise ValueError(
- ("num must be 1 <= num <= {maxn}, not {num}"
- ).format(maxn=rows*cols, num=num))
- self._subplotspec = GridSpec(
- rows, cols, figure=self.figure)[int(num) - 1]
- # num - 1 for converting from MATLAB to python indexing
- else:
- raise ValueError('Illegal argument(s) to subplot: %s' % (args,))
-
- self.update_params()
-
- # _axes_class is set in the subplot_class_factory
- self._axes_class.__init__(self, fig, self.figbox, **kwargs)
- # add a layout box to this, for both the full axis, and the poss
- # of the axis. We need both because the axes may become smaller
- # due to parasitic axes and hence no longer fill the subplotspec.
- if self._subplotspec._layoutbox is None:
- self._layoutbox = None
- self._poslayoutbox = None
- else:
- name = self._subplotspec._layoutbox.name + '.ax'
- name = name + layoutbox.seq_id()
- self._layoutbox = layoutbox.LayoutBox(
- parent=self._subplotspec._layoutbox,
- name=name,
- artist=self)
- self._poslayoutbox = layoutbox.LayoutBox(
- parent=self._layoutbox,
- name=self._layoutbox.name+'.pos',
- pos=True, subplot=True, artist=self)
-
- def __reduce__(self):
- # get the first axes class which does not
- # inherit from a subplotbase
-
- def not_subplotbase(c):
- return issubclass(c, Axes) and not issubclass(c, SubplotBase)
-
- axes_class = [c for c in self.__class__.mro()
- if not_subplotbase(c)][0]
- r = [_PicklableSubplotClassConstructor(),
- (axes_class,),
- self.__getstate__()]
- return tuple(r)
-
- def get_geometry(self):
- """get the subplot geometry, e.g., 2,2,3"""
- rows, cols, num1, num2 = self.get_subplotspec().get_geometry()
- return rows, cols, num1 + 1 # for compatibility
-
- # COVERAGE NOTE: Never used internally or from examples
- def change_geometry(self, numrows, numcols, num):
- """change subplot geometry, e.g., from 1,1,1 to 2,2,3"""
- self._subplotspec = GridSpec(numrows, numcols,
- figure=self.figure)[num - 1]
- self.update_params()
- self.set_position(self.figbox)
-
- def get_subplotspec(self):
- """get the SubplotSpec instance associated with the subplot"""
- return self._subplotspec
-
- def set_subplotspec(self, subplotspec):
- """set the SubplotSpec instance associated with the subplot"""
- self._subplotspec = subplotspec
-
- def update_params(self):
- """update the subplot position from fig.subplotpars"""
-
- self.figbox, self.rowNum, self.colNum, self.numRows, self.numCols = \
- self.get_subplotspec().get_position(self.figure,
- return_all=True)
-
- def is_first_col(self):
- return self.colNum == 0
-
- def is_first_row(self):
- return self.rowNum == 0
-
- def is_last_row(self):
- return self.rowNum == self.numRows - 1
-
- def is_last_col(self):
- return self.colNum == self.numCols - 1
-
- # COVERAGE NOTE: Never used internally.
- def label_outer(self):
- """Only show "outer" labels and tick labels.
-
- x-labels are only kept for subplots on the last row; y-labels only for
- subplots on the first column.
- """
- lastrow = self.is_last_row()
- firstcol = self.is_first_col()
- if not lastrow:
- for label in self.get_xticklabels(which="both"):
- label.set_visible(False)
- self.get_xaxis().get_offset_text().set_visible(False)
- self.set_xlabel("")
- if not firstcol:
- for label in self.get_yticklabels(which="both"):
- label.set_visible(False)
- self.get_yaxis().get_offset_text().set_visible(False)
- self.set_ylabel("")
-
- def _make_twin_axes(self, *kl, **kwargs):
- """
- Make a twinx axes of self. This is used for twinx and twiny.
- """
- from matplotlib.projections import process_projection_requirements
- if 'sharex' in kwargs and 'sharey' in kwargs:
- # The following line is added in v2.2 to avoid breaking Seaborn,
- # which currently uses this internal API.
- if kwargs["sharex"] is not self and kwargs["sharey"] is not self:
- raise ValueError("Twinned Axes may share only one axis.")
- kl = (self.get_subplotspec(),) + kl
- projection_class, kwargs, key = process_projection_requirements(
- self.figure, *kl, **kwargs)
-
- ax2 = subplot_class_factory(projection_class)(self.figure,
- *kl, **kwargs)
- self.figure.add_subplot(ax2)
- self.set_adjustable('datalim')
- ax2.set_adjustable('datalim')
-
- if self._layoutbox is not None and ax2._layoutbox is not None:
- # make the layout boxes be explicitly the same
- ax2._layoutbox.constrain_same(self._layoutbox)
- ax2._poslayoutbox.constrain_same(self._poslayoutbox)
-
- self._twinned_axes.join(self, ax2)
- return ax2
-
-_subplot_classes = {}
-
-
-def subplot_class_factory(axes_class=None):
- # This makes a new class that inherits from SubplotBase and the
- # given axes_class (which is assumed to be a subclass of Axes).
- # This is perhaps a little bit roundabout to make a new class on
- # the fly like this, but it means that a new Subplot class does
- # not have to be created for every type of Axes.
- if axes_class is None:
- axes_class = Axes
-
- new_class = _subplot_classes.get(axes_class)
- if new_class is None:
- new_class = type(str("%sSubplot") % (axes_class.__name__),
- (SubplotBase, axes_class),
- {'_axes_class': axes_class})
- _subplot_classes[axes_class] = new_class
-
- return new_class
-
-# This is provided for backward compatibility
-Subplot = subplot_class_factory()
-
-
-class _PicklableSubplotClassConstructor(object):
- """
- This stub class exists to return the appropriate subplot
- class when __call__-ed with an axes class. This is purely to
- allow Pickling of Axes and Subplots.
- """
- def __call__(self, axes_class):
- # create a dummy object instance
- subplot_instance = _PicklableSubplotClassConstructor()
- subplot_class = subplot_class_factory(axes_class)
- # update the class to the desired subplot class
- subplot_instance.__class__ = subplot_class
- return subplot_instance
-
-
-docstring.interpd.update(Axes=martist.kwdoc(Axes))
-docstring.interpd.update(Subplot=martist.kwdoc(Axes))
-
-"""
-# this is some discarded code I was using to find the minimum positive
-# data point for some log scaling fixes. I realized there was a
-# cleaner way to do it, but am keeping this around as an example for
-# how to get the data out of the axes. Might want to make something
-# like this a method one day, or better yet make get_verts an Artist
-# method
-
- minx, maxx = self.get_xlim()
- if minx<=0 or maxx<=0:
- # find the min pos value in the data
- xs = []
- for line in self.lines:
- xs.extend(line.get_xdata(orig=False))
- for patch in self.patches:
- xs.extend([x for x,y in patch.get_verts()])
- for collection in self.collections:
- xs.extend([x for x,y in collection.get_verts()])
- posx = [x for x in xs if x>0]
- if len(posx):
-
- minx = min(posx)
- maxx = max(posx)
- # warning, probably breaks inverted axis
- self.set_xlim((0.1*minx, maxx))
-
-"""
diff --git a/contrib/python/matplotlib/py2/matplotlib/axis.py b/contrib/python/matplotlib/py2/matplotlib/axis.py
deleted file mode 100644
index 48c31ae6c0..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/axis.py
+++ /dev/null
@@ -1,2509 +0,0 @@
-"""
-Classes for the ticks and x and y axis
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import logging
-
-from matplotlib import rcParams
-import matplotlib.artist as artist
-from matplotlib.artist import allow_rasterization
-import matplotlib.cbook as cbook
-from matplotlib.cbook import _string_to_bool
-import matplotlib.font_manager as font_manager
-import matplotlib.lines as mlines
-import matplotlib.patches as mpatches
-import matplotlib.scale as mscale
-import matplotlib.text as mtext
-import matplotlib.ticker as mticker
-import matplotlib.transforms as mtransforms
-import matplotlib.units as munits
-import numpy as np
-import warnings
-
-_log = logging.getLogger(__name__)
-
-GRIDLINE_INTERPOLATION_STEPS = 180
-
-# This list is being used for compatibility with Axes.grid, which
-# allows all Line2D kwargs.
-_line_AI = artist.ArtistInspector(mlines.Line2D)
-_line_param_names = _line_AI.get_setters()
-_line_param_aliases = [list(d.keys())[0] for d in _line_AI.aliasd.values()]
-_gridline_param_names = ['grid_' + name
- for name in _line_param_names + _line_param_aliases]
-
-
-class Tick(artist.Artist):
- """
- Abstract base class for the axis ticks, grid lines and labels
-
- 1 refers to the bottom of the plot for xticks and the left for yticks
- 2 refers to the top of the plot for xticks and the right for yticks
-
- Attributes
- ----------
- tick1line : Line2D
-
- tick2line : Line2D
-
- gridline : Line2D
-
- label1 : Text
-
- label2 : Text
-
- gridOn : bool
- Determines whether to draw the tickline.
-
- tick1On : bool
- Determines whether to draw the first tickline.
-
- tick2On : bool
- Determines whether to draw the second tickline.
-
- label1On : bool
- Determines whether to draw the first tick label.
-
- label2On : bool
- Determines whether to draw the second tick label.
- """
- def __init__(self, axes, loc, label,
- size=None, # points
- width=None,
- color=None,
- tickdir=None,
- pad=None,
- labelsize=None,
- labelcolor=None,
- zorder=None,
- gridOn=None, # defaults to axes.grid depending on
- # axes.grid.which
- tick1On=True,
- tick2On=True,
- label1On=True,
- label2On=False,
- major=True,
- labelrotation=0,
- grid_color=None,
- grid_linestyle=None,
- grid_linewidth=None,
- grid_alpha=None,
- **kw # Other Line2D kwargs applied to gridlines.
- ):
- """
- bbox is the Bound2D bounding box in display coords of the Axes
- loc is the tick location in data coords
- size is the tick size in points
- """
- artist.Artist.__init__(self)
-
- if gridOn is None:
- if major and (rcParams['axes.grid.which'] in ('both', 'major')):
- gridOn = rcParams['axes.grid']
- elif (not major) and (rcParams['axes.grid.which']
- in ('both', 'minor')):
- gridOn = rcParams['axes.grid']
- else:
- gridOn = False
-
- self.set_figure(axes.figure)
- self.axes = axes
-
- name = self.__name__.lower()
- self._name = name
-
- self._loc = loc
-
- if size is None:
- if major:
- size = rcParams['%s.major.size' % name]
- else:
- size = rcParams['%s.minor.size' % name]
- self._size = size
-
- if width is None:
- if major:
- width = rcParams['%s.major.width' % name]
- else:
- width = rcParams['%s.minor.width' % name]
- self._width = width
-
- if color is None:
- color = rcParams['%s.color' % name]
- self._color = color
-
- if pad is None:
- if major:
- pad = rcParams['%s.major.pad' % name]
- else:
- pad = rcParams['%s.minor.pad' % name]
- self._base_pad = pad
-
- if labelcolor is None:
- labelcolor = rcParams['%s.color' % name]
- self._labelcolor = labelcolor
-
- if labelsize is None:
- labelsize = rcParams['%s.labelsize' % name]
- self._labelsize = labelsize
-
- self._set_labelrotation(labelrotation)
-
- if zorder is None:
- if major:
- zorder = mlines.Line2D.zorder + 0.01
- else:
- zorder = mlines.Line2D.zorder
- self._zorder = zorder
-
- self._grid_color = (rcParams['grid.color']
- if grid_color is None else grid_color)
- self._grid_linestyle = (rcParams['grid.linestyle']
- if grid_linestyle is None else grid_linestyle)
- self._grid_linewidth = (rcParams['grid.linewidth']
- if grid_linewidth is None else grid_linewidth)
- self._grid_alpha = (rcParams['grid.alpha']
- if grid_alpha is None else grid_alpha)
-
- self._grid_kw = {k[5:]: v for k, v in kw.items()}
-
- self.apply_tickdir(tickdir)
-
- self.tick1line = self._get_tick1line()
- self.tick2line = self._get_tick2line()
- self.gridline = self._get_gridline()
-
- self.label1 = self._get_text1()
- self.label = self.label1 # legacy name
- self.label2 = self._get_text2()
-
- self.gridOn = gridOn
- self.tick1On = tick1On
- self.tick2On = tick2On
- self.label1On = label1On
- self.label2On = label2On
-
- self.update_position(loc)
-
- def _set_labelrotation(self, labelrotation):
- if isinstance(labelrotation, six.string_types):
- mode = labelrotation
- angle = 0
- elif isinstance(labelrotation, (tuple, list)):
- mode, angle = labelrotation
- else:
- mode = 'default'
- angle = labelrotation
- if mode not in ('auto', 'default'):
- raise ValueError("Label rotation mode must be 'default' or "
- "'auto', not '{}'.".format(mode))
- self._labelrotation = (mode, angle)
-
- def apply_tickdir(self, tickdir):
- """
- Calculate self._pad and self._tickmarkers
- """
- pass
-
- def get_tickdir(self):
- return self._tickdir
-
- def get_tick_padding(self):
- """
- Get the length of the tick outside of the axes.
- """
- padding = {
- 'in': 0.0,
- 'inout': 0.5,
- 'out': 1.0
- }
- return self._size * padding[self._tickdir]
-
- def get_children(self):
- children = [self.tick1line, self.tick2line,
- self.gridline, self.label1, self.label2]
- return children
-
- def set_clip_path(self, clippath, transform=None):
- artist.Artist.set_clip_path(self, clippath, transform)
- self.gridline.set_clip_path(clippath, transform)
- self.stale = True
-
- set_clip_path.__doc__ = artist.Artist.set_clip_path.__doc__
-
- def get_pad_pixels(self):
- return self.figure.dpi * self._base_pad / 72.0
-
- def contains(self, mouseevent):
- """
- Test whether the mouse event occurred in the Tick marks.
-
- This function always returns false. It is more useful to test if the
- axis as a whole contains the mouse rather than the set of tick marks.
- """
- if callable(self._contains):
- return self._contains(self, mouseevent)
- return False, {}
-
- def set_pad(self, val):
- """
- Set the tick label pad in points
-
- ACCEPTS: float
- """
- self._apply_params(pad=val)
- self.stale = True
-
- def get_pad(self):
- 'Get the value of the tick label pad in points'
- return self._base_pad
-
- def _get_text1(self):
- 'Get the default Text 1 instance'
- pass
-
- def _get_text2(self):
- 'Get the default Text 2 instance'
- pass
-
- def _get_tick1line(self):
- 'Get the default line2D instance for tick1'
- pass
-
- def _get_tick2line(self):
- 'Get the default line2D instance for tick2'
- pass
-
- def _get_gridline(self):
- 'Get the default grid Line2d instance for this tick'
- pass
-
- def get_loc(self):
- 'Return the tick location (data coords) as a scalar'
- return self._loc
-
- @allow_rasterization
- def draw(self, renderer):
- if not self.get_visible():
- self.stale = False
- return
-
- renderer.open_group(self.__name__)
- if self.gridOn:
- self.gridline.draw(renderer)
- if self.tick1On:
- self.tick1line.draw(renderer)
- if self.tick2On:
- self.tick2line.draw(renderer)
-
- if self.label1On:
- self.label1.draw(renderer)
- if self.label2On:
- self.label2.draw(renderer)
- renderer.close_group(self.__name__)
-
- self.stale = False
-
- def set_label1(self, s):
- """
- Set the text of ticklabel
-
- ACCEPTS: str
- """
- self.label1.set_text(s)
- self.stale = True
-
- set_label = set_label1
-
- def set_label2(self, s):
- """
- Set the text of ticklabel2
-
- ACCEPTS: str
- """
- self.label2.set_text(s)
- self.stale = True
-
- def _set_artist_props(self, a):
- a.set_figure(self.figure)
-
- def get_view_interval(self):
- 'return the view Interval instance for the axis this tick is ticking'
- raise NotImplementedError('Derived must override')
-
- def _apply_params(self, **kw):
- switchkw = ['gridOn', 'tick1On', 'tick2On', 'label1On', 'label2On']
- switches = [k for k in kw if k in switchkw]
- for k in switches:
- setattr(self, k, kw.pop(k))
- newmarker = [k for k in kw if k in ['size', 'width', 'pad', 'tickdir']]
- if newmarker:
- self._size = kw.pop('size', self._size)
- # Width could be handled outside this block, but it is
- # convenient to leave it here.
- self._width = kw.pop('width', self._width)
- self._base_pad = kw.pop('pad', self._base_pad)
- # apply_tickdir uses _size and _base_pad to make _pad,
- # and also makes _tickmarkers.
- self.apply_tickdir(kw.pop('tickdir', self._tickdir))
- self.tick1line.set_marker(self._tickmarkers[0])
- self.tick2line.set_marker(self._tickmarkers[1])
- for line in (self.tick1line, self.tick2line):
- line.set_markersize(self._size)
- line.set_markeredgewidth(self._width)
- # _get_text1_transform uses _pad from apply_tickdir.
- trans = self._get_text1_transform()[0]
- self.label1.set_transform(trans)
- trans = self._get_text2_transform()[0]
- self.label2.set_transform(trans)
- tick_kw = {k: v for k, v in six.iteritems(kw)
- if k in ['color', 'zorder']}
- if tick_kw:
- self.tick1line.set(**tick_kw)
- self.tick2line.set(**tick_kw)
- for k, v in six.iteritems(tick_kw):
- setattr(self, '_' + k, v)
-
- if 'labelrotation' in kw:
- self._set_labelrotation(kw.pop('labelrotation'))
- self.label1.set(rotation=self._labelrotation[1])
- self.label2.set(rotation=self._labelrotation[1])
-
- label_list = [k for k in six.iteritems(kw)
- if k[0] in ['labelsize', 'labelcolor']]
- if label_list:
- label_kw = {k[5:]: v for k, v in label_list}
- self.label1.set(**label_kw)
- self.label2.set(**label_kw)
- for k, v in six.iteritems(label_kw):
- # for labelsize the text objects covert str ('small')
- # -> points. grab the integer from the `Text` object
- # instead of saving the string representation
- v = getattr(self.label1, 'get_' + k)()
- setattr(self, '_label' + k, v)
-
- grid_list = [k for k in six.iteritems(kw)
- if k[0] in _gridline_param_names]
- if grid_list:
- grid_kw = {k[5:]: v for k, v in grid_list}
- self.gridline.set(**grid_kw)
- for k, v in six.iteritems(grid_kw):
- setattr(self, '_grid_' + k, v)
-
- def update_position(self, loc):
- 'Set the location of tick in data coords with scalar *loc*'
- raise NotImplementedError('Derived must override')
-
- def _get_text1_transform(self):
- raise NotImplementedError('Derived must override')
-
- def _get_text2_transform(self):
- raise NotImplementedError('Derived must override')
-
-
-class XTick(Tick):
- """
- Contains all the Artists needed to make an x tick - the tick line,
- the label text and the grid line
- """
- __name__ = 'xtick'
-
- def _get_text1_transform(self):
- return self.axes.get_xaxis_text1_transform(self._pad)
-
- def _get_text2_transform(self):
- return self.axes.get_xaxis_text2_transform(self._pad)
-
- def apply_tickdir(self, tickdir):
- if tickdir is None:
- tickdir = rcParams['%s.direction' % self._name]
- self._tickdir = tickdir
-
- if self._tickdir == 'in':
- self._tickmarkers = (mlines.TICKUP, mlines.TICKDOWN)
- elif self._tickdir == 'inout':
- self._tickmarkers = ('|', '|')
- else:
- self._tickmarkers = (mlines.TICKDOWN, mlines.TICKUP)
- self._pad = self._base_pad + self.get_tick_padding()
- self.stale = True
-
- def _get_text1(self):
- 'Get the default Text instance'
- # the y loc is 3 points below the min of y axis
- # get the affine as an a,b,c,d,tx,ty list
- # x in data coords, y in axes coords
- trans, vert, horiz = self._get_text1_transform()
- t = mtext.Text(
- x=0, y=0,
- fontproperties=font_manager.FontProperties(size=self._labelsize),
- color=self._labelcolor,
- verticalalignment=vert,
- horizontalalignment=horiz,
- )
- t.set_transform(trans)
- self._set_artist_props(t)
- return t
-
- def _get_text2(self):
-
- 'Get the default Text 2 instance'
- # x in data coords, y in axes coords
- trans, vert, horiz = self._get_text2_transform()
- t = mtext.Text(
- x=0, y=1,
- fontproperties=font_manager.FontProperties(size=self._labelsize),
- color=self._labelcolor,
- verticalalignment=vert,
- horizontalalignment=horiz,
- )
- t.set_transform(trans)
- self._set_artist_props(t)
- return t
-
- def _get_tick1line(self):
- 'Get the default line2D instance'
- # x in data coords, y in axes coords
- l = mlines.Line2D(xdata=(0,), ydata=(0,), color=self._color,
- linestyle='None', marker=self._tickmarkers[0],
- markersize=self._size,
- markeredgewidth=self._width, zorder=self._zorder)
- l.set_transform(self.axes.get_xaxis_transform(which='tick1'))
- self._set_artist_props(l)
- return l
-
- def _get_tick2line(self):
- 'Get the default line2D instance'
- # x in data coords, y in axes coords
- l = mlines.Line2D(xdata=(0,), ydata=(1,),
- color=self._color,
- linestyle='None',
- marker=self._tickmarkers[1],
- markersize=self._size,
- markeredgewidth=self._width,
- zorder=self._zorder)
-
- l.set_transform(self.axes.get_xaxis_transform(which='tick2'))
- self._set_artist_props(l)
- return l
-
- def _get_gridline(self):
- 'Get the default line2D instance'
- # x in data coords, y in axes coords
- l = mlines.Line2D(xdata=(0.0, 0.0), ydata=(0, 1.0),
- color=self._grid_color,
- linestyle=self._grid_linestyle,
- linewidth=self._grid_linewidth,
- alpha=self._grid_alpha,
- markersize=0,
- **self._grid_kw)
- l.set_transform(self.axes.get_xaxis_transform(which='grid'))
- l.get_path()._interpolation_steps = GRIDLINE_INTERPOLATION_STEPS
- self._set_artist_props(l)
-
- return l
-
- def update_position(self, loc):
- 'Set the location of tick in data coords with scalar *loc*'
- if self.tick1On:
- self.tick1line.set_xdata((loc,))
- if self.tick2On:
- self.tick2line.set_xdata((loc,))
- if self.gridOn:
- self.gridline.set_xdata((loc,))
- if self.label1On:
- self.label1.set_x(loc)
- if self.label2On:
- self.label2.set_x(loc)
-
- self._loc = loc
- self.stale = True
-
- def get_view_interval(self):
- 'return the Interval instance for this axis view limits'
- return self.axes.viewLim.intervalx
-
-
-class YTick(Tick):
- """
- Contains all the Artists needed to make a Y tick - the tick line,
- the label text and the grid line
- """
- __name__ = 'ytick'
-
- def _get_text1_transform(self):
- return self.axes.get_yaxis_text1_transform(self._pad)
-
- def _get_text2_transform(self):
- return self.axes.get_yaxis_text2_transform(self._pad)
-
- def apply_tickdir(self, tickdir):
- if tickdir is None:
- tickdir = rcParams['%s.direction' % self._name]
- self._tickdir = tickdir
-
- if self._tickdir == 'in':
- self._tickmarkers = (mlines.TICKRIGHT, mlines.TICKLEFT)
- elif self._tickdir == 'inout':
- self._tickmarkers = ('_', '_')
- else:
- self._tickmarkers = (mlines.TICKLEFT, mlines.TICKRIGHT)
- self._pad = self._base_pad + self.get_tick_padding()
- self.stale = True
-
- # how far from the y axis line the right of the ticklabel are
- def _get_text1(self):
- 'Get the default Text instance'
- # x in axes coords, y in data coords
- trans, vert, horiz = self._get_text1_transform()
- t = mtext.Text(
- x=0, y=0,
- fontproperties=font_manager.FontProperties(size=self._labelsize),
- color=self._labelcolor,
- verticalalignment=vert,
- horizontalalignment=horiz,
- )
- t.set_transform(trans)
- self._set_artist_props(t)
- return t
-
- def _get_text2(self):
- 'Get the default Text instance'
- # x in axes coords, y in data coords
- trans, vert, horiz = self._get_text2_transform()
- t = mtext.Text(
- x=1, y=0,
- fontproperties=font_manager.FontProperties(size=self._labelsize),
- color=self._labelcolor,
- verticalalignment=vert,
- horizontalalignment=horiz,
- )
- t.set_transform(trans)
- self._set_artist_props(t)
- return t
-
- def _get_tick1line(self):
- 'Get the default line2D instance'
- # x in axes coords, y in data coords
-
- l = mlines.Line2D((0,), (0,),
- color=self._color,
- marker=self._tickmarkers[0],
- linestyle='None',
- markersize=self._size,
- markeredgewidth=self._width,
- zorder=self._zorder)
- l.set_transform(self.axes.get_yaxis_transform(which='tick1'))
- self._set_artist_props(l)
- return l
-
- def _get_tick2line(self):
- 'Get the default line2D instance'
- # x in axes coords, y in data coords
- l = mlines.Line2D((1,), (0,),
- color=self._color,
- marker=self._tickmarkers[1],
- linestyle='None',
- markersize=self._size,
- markeredgewidth=self._width,
- zorder=self._zorder)
- l.set_transform(self.axes.get_yaxis_transform(which='tick2'))
- self._set_artist_props(l)
- return l
-
- def _get_gridline(self):
- 'Get the default line2D instance'
- # x in axes coords, y in data coords
- l = mlines.Line2D(xdata=(0, 1), ydata=(0, 0),
- color=self._grid_color,
- linestyle=self._grid_linestyle,
- linewidth=self._grid_linewidth,
- alpha=self._grid_alpha,
- markersize=0,
- **self._grid_kw)
- l.set_transform(self.axes.get_yaxis_transform(which='grid'))
- l.get_path()._interpolation_steps = GRIDLINE_INTERPOLATION_STEPS
- self._set_artist_props(l)
- return l
-
- def update_position(self, loc):
- 'Set the location of tick in data coords with scalar *loc*'
- if self.tick1On:
- self.tick1line.set_ydata((loc,))
- if self.tick2On:
- self.tick2line.set_ydata((loc,))
- if self.gridOn:
- self.gridline.set_ydata((loc,))
- if self.label1On:
- self.label1.set_y(loc)
- if self.label2On:
- self.label2.set_y(loc)
-
- self._loc = loc
- self.stale = True
-
- def get_view_interval(self):
- 'return the Interval instance for this axis view limits'
- return self.axes.viewLim.intervaly
-
-
-class Ticker(object):
- locator = None
- formatter = None
-
-
-class _LazyTickList(object):
- """
- A descriptor for lazy instantiation of tick lists.
-
- See comment above definition of the ``majorTicks`` and ``minorTicks``
- attributes.
- """
-
- def __init__(self, major):
- self._major = major
-
- def __get__(self, instance, cls):
- if instance is None:
- return self
- else:
- # instance._get_tick() can itself try to access the majorTicks
- # attribute (e.g. in certain projection classes which override
- # e.g. get_xaxis_text1_transform). In order to avoid infinite
- # recursion, first set the majorTicks on the instance to an empty
- # list, then create the tick and append it.
- if self._major:
- instance.majorTicks = []
- tick = instance._get_tick(major=True)
- instance.majorTicks.append(tick)
- return instance.majorTicks
- else:
- instance.minorTicks = []
- tick = instance._get_tick(major=False)
- instance.minorTicks.append(tick)
- return instance.minorTicks
-
-
-class Axis(artist.Artist):
- """
- Public attributes
-
- * :attr:`axes.transData` - transform data coords to display coords
- * :attr:`axes.transAxes` - transform axis coords to display coords
- * :attr:`labelpad` - number of points between the axis and its label
- """
- OFFSETTEXTPAD = 3
-
- def __str__(self):
- return self.__class__.__name__ \
- + "(%f,%f)" % tuple(self.axes.transAxes.transform_point((0, 0)))
-
- def __init__(self, axes, pickradius=15):
- """
- Init the axis with the parent Axes instance
- """
- artist.Artist.__init__(self)
- self.set_figure(axes.figure)
-
- self.isDefault_label = True
-
- self.axes = axes
- self.major = Ticker()
- self.minor = Ticker()
- self.callbacks = cbook.CallbackRegistry()
-
- self._autolabelpos = True
- self._smart_bounds = False
-
- self.label = self._get_label()
- self.labelpad = rcParams['axes.labelpad']
- self.offsetText = self._get_offset_text()
-
- self.pickradius = pickradius
-
- # Initialize here for testing; later add API
- self._major_tick_kw = dict()
- self._minor_tick_kw = dict()
-
- self.cla()
- self._set_scale('linear')
-
- # During initialization, Axis objects often create ticks that are later
- # unused; this turns out to be a very slow step. Instead, use a custom
- # descriptor to make the tick lists lazy and instantiate them as needed.
- majorTicks = _LazyTickList(major=True)
- minorTicks = _LazyTickList(major=False)
-
- def set_label_coords(self, x, y, transform=None):
- """
- Set the coordinates of the label. By default, the x
- coordinate of the y label is determined by the tick label
- bounding boxes, but this can lead to poor alignment of
- multiple ylabels if there are multiple axes. Ditto for the y
- coordinate of the x label.
-
- You can also specify the coordinate system of the label with
- the transform. If None, the default coordinate system will be
- the axes coordinate system (0,0) is (left,bottom), (0.5, 0.5)
- is middle, etc
-
- """
-
- self._autolabelpos = False
- if transform is None:
- transform = self.axes.transAxes
-
- self.label.set_transform(transform)
- self.label.set_position((x, y))
- self.stale = True
-
- def get_transform(self):
- return self._scale.get_transform()
-
- def get_scale(self):
- return self._scale.name
-
- def _set_scale(self, value, **kwargs):
- self._scale = mscale.scale_factory(value, self, **kwargs)
- self._scale.set_default_locators_and_formatters(self)
-
- self.isDefault_majloc = True
- self.isDefault_minloc = True
- self.isDefault_majfmt = True
- self.isDefault_minfmt = True
-
- def limit_range_for_scale(self, vmin, vmax):
- return self._scale.limit_range_for_scale(vmin, vmax, self.get_minpos())
-
- @property
- @cbook.deprecated("2.2.0")
- def unit_data(self):
- return self.units
-
- @unit_data.setter
- @cbook.deprecated("2.2.0")
- def unit_data(self, unit_data):
- self.set_units(unit_data)
-
- def get_children(self):
- children = [self.label, self.offsetText]
- majorticks = self.get_major_ticks()
- minorticks = self.get_minor_ticks()
-
- children.extend(majorticks)
- children.extend(minorticks)
- return children
-
- def cla(self):
- 'clear the current axis'
-
- self.label.set_text('') # self.set_label_text would change isDefault_
-
- self._set_scale('linear')
-
- # Clear the callback registry for this axis, or it may "leak"
- self.callbacks = cbook.CallbackRegistry()
-
- # whether the grids are on
- self._gridOnMajor = (rcParams['axes.grid'] and
- rcParams['axes.grid.which'] in ('both', 'major'))
- self._gridOnMinor = (rcParams['axes.grid'] and
- rcParams['axes.grid.which'] in ('both', 'minor'))
-
- self.reset_ticks()
-
- self.converter = None
- self.units = None
- self.set_units(None)
- self.stale = True
-
- def reset_ticks(self):
- """
- Re-initialize the major and minor Tick lists.
-
- Each list starts with a single fresh Tick.
- """
- # Restore the lazy tick lists.
- try:
- del self.majorTicks
- except AttributeError:
- pass
- try:
- del self.minorTicks
- except AttributeError:
- pass
- try:
- self.set_clip_path(self.axes.patch)
- except AttributeError:
- pass
-
- def set_tick_params(self, which='major', reset=False, **kw):
- """
- Set appearance parameters for ticks, ticklabels, and gridlines.
-
- For documentation of keyword arguments, see
- :meth:`matplotlib.axes.Axes.tick_params`.
- """
- dicts = []
- if which == 'major' or which == 'both':
- dicts.append(self._major_tick_kw)
- if which == 'minor' or which == 'both':
- dicts.append(self._minor_tick_kw)
- kwtrans = self._translate_tick_kw(kw, to_init_kw=True)
- for d in dicts:
- if reset:
- d.clear()
- d.update(kwtrans)
-
- if reset:
- self.reset_ticks()
- else:
- if which == 'major' or which == 'both':
- for tick in self.majorTicks:
- tick._apply_params(**self._major_tick_kw)
- if which == 'minor' or which == 'both':
- for tick in self.minorTicks:
- tick._apply_params(**self._minor_tick_kw)
- if 'labelcolor' in kwtrans:
- self.offsetText.set_color(kwtrans['labelcolor'])
- self.stale = True
-
- @staticmethod
- def _translate_tick_kw(kw, to_init_kw=True):
- # The following lists may be moved to a more
- # accessible location.
- kwkeys0 = ['size', 'width', 'color', 'tickdir', 'pad',
- 'labelsize', 'labelcolor', 'zorder', 'gridOn',
- 'tick1On', 'tick2On', 'label1On', 'label2On']
- kwkeys1 = ['length', 'direction', 'left', 'bottom', 'right', 'top',
- 'labelleft', 'labelbottom', 'labelright', 'labeltop',
- 'labelrotation']
- kwkeys2 = _gridline_param_names
- kwkeys = kwkeys0 + kwkeys1 + kwkeys2
- kwtrans = dict()
- if to_init_kw:
- if 'length' in kw:
- kwtrans['size'] = kw.pop('length')
- if 'direction' in kw:
- kwtrans['tickdir'] = kw.pop('direction')
- if 'rotation' in kw:
- kwtrans['labelrotation'] = kw.pop('rotation')
- if 'left' in kw:
- kwtrans['tick1On'] = _string_to_bool(kw.pop('left'))
- if 'bottom' in kw:
- kwtrans['tick1On'] = _string_to_bool(kw.pop('bottom'))
- if 'right' in kw:
- kwtrans['tick2On'] = _string_to_bool(kw.pop('right'))
- if 'top' in kw:
- kwtrans['tick2On'] = _string_to_bool(kw.pop('top'))
-
- if 'labelleft' in kw:
- kwtrans['label1On'] = _string_to_bool(kw.pop('labelleft'))
- if 'labelbottom' in kw:
- kwtrans['label1On'] = _string_to_bool(kw.pop('labelbottom'))
- if 'labelright' in kw:
- kwtrans['label2On'] = _string_to_bool(kw.pop('labelright'))
- if 'labeltop' in kw:
- kwtrans['label2On'] = _string_to_bool(kw.pop('labeltop'))
- if 'colors' in kw:
- c = kw.pop('colors')
- kwtrans['color'] = c
- kwtrans['labelcolor'] = c
- # Maybe move the checking up to the caller of this method.
- for key in kw:
- if key not in kwkeys:
- raise ValueError(
- "keyword %s is not recognized; valid keywords are %s"
- % (key, kwkeys))
- kwtrans.update(kw)
- else:
- raise NotImplementedError("Inverse translation is deferred")
- return kwtrans
-
- def set_clip_path(self, clippath, transform=None):
- artist.Artist.set_clip_path(self, clippath, transform)
- for child in self.majorTicks + self.minorTicks:
- child.set_clip_path(clippath, transform)
- self.stale = True
-
- def get_view_interval(self):
- 'return the Interval instance for this axis view limits'
- raise NotImplementedError('Derived must override')
-
- def set_view_interval(self, vmin, vmax, ignore=False):
- raise NotImplementedError('Derived must override')
-
- def get_data_interval(self):
- 'return the Interval instance for this axis data limits'
- raise NotImplementedError('Derived must override')
-
- def set_data_interval(self):
- '''set the axis data limits'''
- raise NotImplementedError('Derived must override')
-
- def set_default_intervals(self):
- '''set the default limits for the axis data and view interval if they
- are not mutated'''
-
- # this is mainly in support of custom object plotting. For
- # example, if someone passes in a datetime object, we do not
- # know automagically how to set the default min/max of the
- # data and view limits. The unit conversion AxisInfo
- # interface provides a hook for custom types to register
- # default limits through the AxisInfo.default_limits
- # attribute, and the derived code below will check for that
- # and use it if is available (else just use 0..1)
- pass
-
- def _set_artist_props(self, a):
- if a is None:
- return
- a.set_figure(self.figure)
-
- def iter_ticks(self):
- """
- Iterate through all of the major and minor ticks.
- """
- majorLocs = self.major.locator()
- majorTicks = self.get_major_ticks(len(majorLocs))
- self.major.formatter.set_locs(majorLocs)
- majorLabels = [self.major.formatter(val, i)
- for i, val in enumerate(majorLocs)]
-
- minorLocs = self.minor.locator()
- minorTicks = self.get_minor_ticks(len(minorLocs))
- self.minor.formatter.set_locs(minorLocs)
- minorLabels = [self.minor.formatter(val, i)
- for i, val in enumerate(minorLocs)]
-
- major_minor = [
- (majorTicks, majorLocs, majorLabels),
- (minorTicks, minorLocs, minorLabels)]
-
- for group in major_minor:
- for tick in zip(*group):
- yield tick
-
- def get_ticklabel_extents(self, renderer):
- """
- Get the extents of the tick labels on either side
- of the axes.
- """
-
- ticks_to_draw = self._update_ticks(renderer)
- ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw,
- renderer)
-
- if len(ticklabelBoxes):
- bbox = mtransforms.Bbox.union(ticklabelBoxes)
- else:
- bbox = mtransforms.Bbox.from_extents(0, 0, 0, 0)
- if len(ticklabelBoxes2):
- bbox2 = mtransforms.Bbox.union(ticklabelBoxes2)
- else:
- bbox2 = mtransforms.Bbox.from_extents(0, 0, 0, 0)
- return bbox, bbox2
-
- def set_smart_bounds(self, value):
- """set the axis to have smart bounds"""
- self._smart_bounds = value
- self.stale = True
-
- def get_smart_bounds(self):
- """get whether the axis has smart bounds"""
- return self._smart_bounds
-
- def _update_ticks(self, renderer):
- """
- Update ticks (position and labels) using the current data
- interval of the axes. Returns a list of ticks that will be
- drawn.
- """
-
- interval = self.get_view_interval()
- tick_tups = list(self.iter_ticks()) # iter_ticks calls the locator
- if self._smart_bounds and tick_tups:
- # handle inverted limits
- view_low, view_high = sorted(interval)
- data_low, data_high = sorted(self.get_data_interval())
- locs = np.sort([ti[1] for ti in tick_tups])
- if data_low <= view_low:
- # data extends beyond view, take view as limit
- ilow = view_low
- else:
- # data stops within view, take best tick
- good_locs = locs[locs <= data_low]
- if len(good_locs):
- # last tick prior or equal to first data point
- ilow = good_locs[-1]
- else:
- # No ticks (why not?), take first tick
- ilow = locs[0]
- if data_high >= view_high:
- # data extends beyond view, take view as limit
- ihigh = view_high
- else:
- # data stops within view, take best tick
- good_locs = locs[locs >= data_high]
- if len(good_locs):
- # first tick after or equal to last data point
- ihigh = good_locs[0]
- else:
- # No ticks (why not?), take last tick
- ihigh = locs[-1]
- tick_tups = [ti for ti in tick_tups if ilow <= ti[1] <= ihigh]
-
- # so that we don't lose ticks on the end, expand out the interval ever
- # so slightly. The "ever so slightly" is defined to be the width of a
- # half of a pixel. We don't want to draw a tick that even one pixel
- # outside of the defined axis interval.
- if interval[0] <= interval[1]:
- interval_expanded = interval
- else:
- interval_expanded = interval[1], interval[0]
-
- if hasattr(self, '_get_pixel_distance_along_axis'):
- # normally, one does not want to catch all exceptions that
- # could possibly happen, but it is not clear exactly what
- # exceptions might arise from a user's projection (their
- # rendition of the Axis object). So, we catch all, with
- # the idea that one would rather potentially lose a tick
- # from one side of the axis or another, rather than see a
- # stack trace.
- # We also catch users warnings here. These are the result of
- # invalid numpy calculations that may be the result of out of
- # bounds on axis with finite allowed intervals such as geo
- # projections i.e. Mollweide.
- with np.errstate(invalid='ignore'):
- try:
- ds1 = self._get_pixel_distance_along_axis(
- interval_expanded[0], -0.5)
- except:
- warnings.warn("Unable to find pixel distance along axis "
- "for interval padding of ticks; assuming no "
- "interval padding needed.")
- ds1 = 0.0
- if np.isnan(ds1):
- ds1 = 0.0
- try:
- ds2 = self._get_pixel_distance_along_axis(
- interval_expanded[1], +0.5)
- except:
- warnings.warn("Unable to find pixel distance along axis "
- "for interval padding of ticks; assuming no "
- "interval padding needed.")
- ds2 = 0.0
- if np.isnan(ds2):
- ds2 = 0.0
- interval_expanded = (interval_expanded[0] - ds1,
- interval_expanded[1] + ds2)
-
- ticks_to_draw = []
- for tick, loc, label in tick_tups:
- if tick is None:
- continue
- # NB: always update labels and position to avoid issues like #9397
- tick.update_position(loc)
- tick.set_label1(label)
- tick.set_label2(label)
- if not mtransforms.interval_contains(interval_expanded, loc):
- continue
- ticks_to_draw.append(tick)
-
- return ticks_to_draw
-
- def _get_tick_bboxes(self, ticks, renderer):
- """
- Given the list of ticks, return two lists of bboxes. One for
- tick lable1's and another for tick label2's.
- """
-
- ticklabelBoxes = []
- ticklabelBoxes2 = []
-
- for tick in ticks:
- if tick.label1On and tick.label1.get_visible():
- extent = tick.label1.get_window_extent(renderer)
- ticklabelBoxes.append(extent)
- if tick.label2On and tick.label2.get_visible():
- extent = tick.label2.get_window_extent(renderer)
- ticklabelBoxes2.append(extent)
- return ticklabelBoxes, ticklabelBoxes2
-
- def get_tightbbox(self, renderer):
- """
- Return a bounding box that encloses the axis. It only accounts
- tick labels, axis label, and offsetText.
- """
- if not self.get_visible():
- return
-
- ticks_to_draw = self._update_ticks(renderer)
-
- self._update_label_position(renderer)
-
- # go back to just this axis's tick labels
- ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(
- ticks_to_draw, renderer)
-
- self._update_offset_text_position(ticklabelBoxes, ticklabelBoxes2)
- self.offsetText.set_text(self.major.formatter.get_offset())
-
- bb = []
-
- for a in [self.label, self.offsetText]:
- if a.get_visible():
- bb.append(a.get_window_extent(renderer))
-
- bb.extend(ticklabelBoxes)
- bb.extend(ticklabelBoxes2)
-
- bb = [b for b in bb if b.width != 0 or b.height != 0]
- if bb:
- _bbox = mtransforms.Bbox.union(bb)
- return _bbox
- else:
- return None
-
- def get_tick_padding(self):
- values = []
- if len(self.majorTicks):
- values.append(self.majorTicks[0].get_tick_padding())
- if len(self.minorTicks):
- values.append(self.minorTicks[0].get_tick_padding())
- if len(values):
- return max(values)
- return 0.0
-
- @allow_rasterization
- def draw(self, renderer, *args, **kwargs):
- 'Draw the axis lines, grid lines, tick lines and labels'
-
- if not self.get_visible():
- return
- renderer.open_group(__name__)
-
- ticks_to_draw = self._update_ticks(renderer)
- ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw,
- renderer)
-
- for tick in ticks_to_draw:
- tick.draw(renderer)
-
- # scale up the axis label box to also find the neighbors, not
- # just the tick labels that actually overlap note we need a
- # *copy* of the axis label box because we don't wan't to scale
- # the actual bbox
-
- self._update_label_position(renderer)
-
- self.label.draw(renderer)
-
- self._update_offset_text_position(ticklabelBoxes, ticklabelBoxes2)
- self.offsetText.set_text(self.major.formatter.get_offset())
- self.offsetText.draw(renderer)
-
- if 0: # draw the bounding boxes around the text for debug
- for tick in self.majorTicks:
- label = tick.label1
- mpatches.bbox_artist(label, renderer)
- mpatches.bbox_artist(self.label, renderer)
-
- renderer.close_group(__name__)
- self.stale = False
-
- def _get_label(self):
- raise NotImplementedError('Derived must override')
-
- def _get_offset_text(self):
- raise NotImplementedError('Derived must override')
-
- def get_gridlines(self):
- 'Return the grid lines as a list of Line2D instance'
- ticks = self.get_major_ticks()
- return cbook.silent_list('Line2D gridline',
- [tick.gridline for tick in ticks])
-
- def get_label(self):
- 'Return the axis label as a Text instance'
- return self.label
-
- def get_offset_text(self):
- 'Return the axis offsetText as a Text instance'
- return self.offsetText
-
- def get_pickradius(self):
- 'Return the depth of the axis used by the picker'
- return self.pickradius
-
- def get_majorticklabels(self):
- 'Return a list of Text instances for the major ticklabels'
- ticks = self.get_major_ticks()
- labels1 = [tick.label1 for tick in ticks if tick.label1On]
- labels2 = [tick.label2 for tick in ticks if tick.label2On]
- return cbook.silent_list('Text major ticklabel', labels1 + labels2)
-
- def get_minorticklabels(self):
- 'Return a list of Text instances for the minor ticklabels'
- ticks = self.get_minor_ticks()
- labels1 = [tick.label1 for tick in ticks if tick.label1On]
- labels2 = [tick.label2 for tick in ticks if tick.label2On]
- return cbook.silent_list('Text minor ticklabel', labels1 + labels2)
-
- def get_ticklabels(self, minor=False, which=None):
- """
- Get the tick labels as a list of :class:`~matplotlib.text.Text`
- instances.
-
- Parameters
- ----------
- minor : bool
- If True return the minor ticklabels,
- else return the major ticklabels
-
- which : None, ('minor', 'major', 'both')
- Overrides `minor`.
-
- Selects which ticklabels to return
-
- Returns
- -------
- ret : list
- List of :class:`~matplotlib.text.Text` instances.
- """
-
- if which is not None:
- if which == 'minor':
- return self.get_minorticklabels()
- elif which == 'major':
- return self.get_majorticklabels()
- elif which == 'both':
- return self.get_majorticklabels() + self.get_minorticklabels()
- else:
- raise ValueError("`which` must be one of ('minor', 'major', "
- "'both') not " + str(which))
- if minor:
- return self.get_minorticklabels()
- return self.get_majorticklabels()
-
- def get_majorticklines(self):
- 'Return the major tick lines as a list of Line2D instances'
- lines = []
- ticks = self.get_major_ticks()
- for tick in ticks:
- lines.append(tick.tick1line)
- lines.append(tick.tick2line)
- return cbook.silent_list('Line2D ticklines', lines)
-
- def get_minorticklines(self):
- 'Return the minor tick lines as a list of Line2D instances'
- lines = []
- ticks = self.get_minor_ticks()
- for tick in ticks:
- lines.append(tick.tick1line)
- lines.append(tick.tick2line)
- return cbook.silent_list('Line2D ticklines', lines)
-
- def get_ticklines(self, minor=False):
- 'Return the tick lines as a list of Line2D instances'
- if minor:
- return self.get_minorticklines()
- return self.get_majorticklines()
-
- def get_majorticklocs(self):
- "Get the major tick locations in data coordinates as a numpy array"
- return self.major.locator()
-
- def get_minorticklocs(self):
- "Get the minor tick locations in data coordinates as a numpy array"
- return self.minor.locator()
-
- def get_ticklocs(self, minor=False):
- "Get the tick locations in data coordinates as a numpy array"
- if minor:
- return self.minor.locator()
- return self.major.locator()
-
- def get_ticks_direction(self, minor=False):
- """
- Get the tick directions as a numpy array
-
- Parameters
- ----------
- minor : boolean
- True to return the minor tick directions,
- False to return the major tick directions,
- Default is False
-
- Returns
- -------
- numpy array of tick directions
- """
- if minor:
- return np.array(
- [tick._tickdir for tick in self.get_minor_ticks()])
- else:
- return np.array(
- [tick._tickdir for tick in self.get_major_ticks()])
-
- def _get_tick(self, major):
- 'return the default tick instance'
- raise NotImplementedError('derived must override')
-
- def _copy_tick_props(self, src, dest):
- 'Copy the props from src tick to dest tick'
- if src is None or dest is None:
- return
- dest.label1.update_from(src.label1)
- dest.label2.update_from(src.label2)
-
- dest.tick1line.update_from(src.tick1line)
- dest.tick2line.update_from(src.tick2line)
- dest.gridline.update_from(src.gridline)
-
- dest.tick1On = src.tick1On
- dest.tick2On = src.tick2On
- dest.label1On = src.label1On
- dest.label2On = src.label2On
-
- def get_label_text(self):
- 'Get the text of the label'
- return self.label.get_text()
-
- def get_major_locator(self):
- 'Get the locator of the major ticker'
- return self.major.locator
-
- def get_minor_locator(self):
- 'Get the locator of the minor ticker'
- return self.minor.locator
-
- def get_major_formatter(self):
- 'Get the formatter of the major ticker'
- return self.major.formatter
-
- def get_minor_formatter(self):
- 'Get the formatter of the minor ticker'
- return self.minor.formatter
-
- def get_major_ticks(self, numticks=None):
- 'get the tick instances; grow as necessary'
- if numticks is None:
- numticks = len(self.get_major_locator()())
-
- while len(self.majorTicks) < numticks:
- # update the new tick label properties from the old
- tick = self._get_tick(major=True)
- self.majorTicks.append(tick)
- if self._gridOnMajor:
- tick.gridOn = True
- self._copy_tick_props(self.majorTicks[0], tick)
-
- return self.majorTicks[:numticks]
-
- def get_minor_ticks(self, numticks=None):
- 'get the minor tick instances; grow as necessary'
- if numticks is None:
- numticks = len(self.get_minor_locator()())
-
- while len(self.minorTicks) < numticks:
- # update the new tick label properties from the old
- tick = self._get_tick(major=False)
- self.minorTicks.append(tick)
- if self._gridOnMinor:
- tick.gridOn = True
- self._copy_tick_props(self.minorTicks[0], tick)
-
- return self.minorTicks[:numticks]
-
- def grid(self, b=None, which='major', **kwargs):
- """
- Set the axis grid on or off; b is a boolean. Use *which* =
- 'major' | 'minor' | 'both' to set the grid for major or minor ticks.
-
- If *b* is *None* and len(kwargs)==0, toggle the grid state. If
- *kwargs* are supplied, it is assumed you want the grid on and *b*
- will be set to True.
-
- *kwargs* are used to set the line properties of the grids, e.g.,
-
- xax.grid(color='r', linestyle='-', linewidth=2)
- """
- if len(kwargs):
- b = True
- which = which.lower()
- gridkw = {'grid_' + item[0]: item[1] for item in kwargs.items()}
- if which in ['minor', 'both']:
- if b is None:
- self._gridOnMinor = not self._gridOnMinor
- else:
- self._gridOnMinor = b
- self.set_tick_params(which='minor', gridOn=self._gridOnMinor,
- **gridkw)
- if which in ['major', 'both']:
- if b is None:
- self._gridOnMajor = not self._gridOnMajor
- else:
- self._gridOnMajor = b
- self.set_tick_params(which='major', gridOn=self._gridOnMajor,
- **gridkw)
- self.stale = True
-
- def update_units(self, data):
- """
- introspect *data* for units converter and update the
- axis.converter instance if necessary. Return *True*
- if *data* is registered for unit conversion.
- """
-
- converter = munits.registry.get_converter(data)
- if converter is None:
- return False
-
- neednew = self.converter != converter
- self.converter = converter
- default = self.converter.default_units(data, self)
- if default is not None and self.units is None:
- self.set_units(default)
-
- if neednew:
- self._update_axisinfo()
- self.stale = True
- return True
-
- def _update_axisinfo(self):
- """
- check the axis converter for the stored units to see if the
- axis info needs to be updated
- """
- if self.converter is None:
- return
-
- info = self.converter.axisinfo(self.units, self)
-
- if info is None:
- return
- if info.majloc is not None and \
- self.major.locator != info.majloc and self.isDefault_majloc:
- self.set_major_locator(info.majloc)
- self.isDefault_majloc = True
- if info.minloc is not None and \
- self.minor.locator != info.minloc and self.isDefault_minloc:
- self.set_minor_locator(info.minloc)
- self.isDefault_minloc = True
- if info.majfmt is not None and \
- self.major.formatter != info.majfmt and self.isDefault_majfmt:
- self.set_major_formatter(info.majfmt)
- self.isDefault_majfmt = True
- if info.minfmt is not None and \
- self.minor.formatter != info.minfmt and self.isDefault_minfmt:
- self.set_minor_formatter(info.minfmt)
- self.isDefault_minfmt = True
- if info.label is not None and self.isDefault_label:
- self.set_label_text(info.label)
- self.isDefault_label = True
-
- self.set_default_intervals()
-
- def have_units(self):
- return self.converter is not None or self.units is not None
-
- def convert_units(self, x):
- # If x is already a number, doesn't need converting
- if munits.ConversionInterface.is_numlike(x):
- return x
-
- if self.converter is None:
- self.converter = munits.registry.get_converter(x)
-
- if self.converter is None:
- return x
-
- ret = self.converter.convert(x, self.units, self)
- return ret
-
- def set_units(self, u):
- """
- set the units for axis
-
- ACCEPTS: a units tag
- """
- pchanged = False
- if u is None:
- self.units = None
- pchanged = True
- else:
- if u != self.units:
- self.units = u
- pchanged = True
- if pchanged:
- self._update_axisinfo()
- self.callbacks.process('units')
- self.callbacks.process('units finalize')
- self.stale = True
-
- def get_units(self):
- 'return the units for axis'
- return self.units
-
- def set_label_text(self, label, fontdict=None, **kwargs):
- """ Sets the text value of the axis label
-
- ACCEPTS: A string value for the label
- """
- self.isDefault_label = False
- self.label.set_text(label)
- if fontdict is not None:
- self.label.update(fontdict)
- self.label.update(kwargs)
- self.stale = True
- return self.label
-
- def set_major_formatter(self, formatter):
- """
- Set the formatter of the major ticker
-
- ACCEPTS: A :class:`~matplotlib.ticker.Formatter` instance
- """
- self.isDefault_majfmt = False
- self.major.formatter = formatter
- formatter.set_axis(self)
- self.stale = True
-
- def set_minor_formatter(self, formatter):
- """
- Set the formatter of the minor ticker
-
- ACCEPTS: A :class:`~matplotlib.ticker.Formatter` instance
- """
- self.isDefault_minfmt = False
- self.minor.formatter = formatter
- formatter.set_axis(self)
- self.stale = True
-
- def set_major_locator(self, locator):
- """
- Set the locator of the major ticker
-
- ACCEPTS: a :class:`~matplotlib.ticker.Locator` instance
- """
- self.isDefault_majloc = False
- self.major.locator = locator
- locator.set_axis(self)
- self.stale = True
-
- def set_minor_locator(self, locator):
- """
- Set the locator of the minor ticker
-
- ACCEPTS: a :class:`~matplotlib.ticker.Locator` instance
- """
- self.isDefault_minloc = False
- self.minor.locator = locator
- locator.set_axis(self)
- self.stale = True
-
- def set_pickradius(self, pickradius):
- """
- Set the depth of the axis used by the picker
-
- ACCEPTS: a distance in points
- """
- self.pickradius = pickradius
-
- def set_ticklabels(self, ticklabels, *args, **kwargs):
- """
- Set the text values of the tick labels. Return a list of Text
- instances. Use *kwarg* *minor=True* to select minor ticks.
- All other kwargs are used to update the text object properties.
- As for get_ticklabels, label1 (left or bottom) is
- affected for a given tick only if its label1On attribute
- is True, and similarly for label2. The list of returned
- label text objects consists of all such label1 objects followed
- by all such label2 objects.
-
- The input *ticklabels* is assumed to match the set of
- tick locations, regardless of the state of label1On and
- label2On.
-
- ACCEPTS: sequence of strings or Text objects
- """
- get_labels = []
- for t in ticklabels:
- # try calling get_text() to check whether it is Text object
- # if it is Text, get label content
- try:
- get_labels.append(t.get_text())
- # otherwise add the label to the list directly
- except AttributeError:
- get_labels.append(t)
- # replace the ticklabels list with the processed one
- ticklabels = get_labels
-
- minor = kwargs.pop('minor', False)
- if minor:
- self.set_minor_formatter(mticker.FixedFormatter(ticklabels))
- ticks = self.get_minor_ticks()
- else:
- self.set_major_formatter(mticker.FixedFormatter(ticklabels))
- ticks = self.get_major_ticks()
- ret = []
- for tick_label, tick in zip(ticklabels, ticks):
- # deal with label1
- tick.label1.set_text(tick_label)
- tick.label1.update(kwargs)
- # deal with label2
- tick.label2.set_text(tick_label)
- tick.label2.update(kwargs)
- # only return visible tick labels
- if tick.label1On:
- ret.append(tick.label1)
- if tick.label2On:
- ret.append(tick.label2)
-
- self.stale = True
- return ret
-
- def set_ticks(self, ticks, minor=False):
- """
- Set the locations of the tick marks from sequence ticks
-
- ACCEPTS: sequence of floats
- """
- # XXX if the user changes units, the information will be lost here
- ticks = self.convert_units(ticks)
- if len(ticks) > 1:
- xleft, xright = self.get_view_interval()
- if xright > xleft:
- self.set_view_interval(min(ticks), max(ticks))
- else:
- self.set_view_interval(max(ticks), min(ticks))
- if minor:
- self.set_minor_locator(mticker.FixedLocator(ticks))
- return self.get_minor_ticks(len(ticks))
- else:
- self.set_major_locator(mticker.FixedLocator(ticks))
- return self.get_major_ticks(len(ticks))
-
- def _get_tick_boxes_siblings(self, xdir, renderer):
- """
- Get the bounding boxes for this `.axis` and its siblings
- as set by `.Figure.align_xlabels` or `.Figure.align_ylablels`.
-
- By default it just gets bboxes for self.
- """
- raise NotImplementedError('Derived must override')
-
- def _update_label_position(self, renderer):
- """
- Update the label position based on the bounding box enclosing
- all the ticklabels and axis spine
- """
- raise NotImplementedError('Derived must override')
-
- def _update_offset_text_position(self, bboxes, bboxes2):
- """
- Update the label position based on the sequence of bounding
- boxes of all the ticklabels
- """
- raise NotImplementedError('Derived must override')
-
- def pan(self, numsteps):
- 'Pan *numsteps* (can be positive or negative)'
- self.major.locator.pan(numsteps)
-
- def zoom(self, direction):
- "Zoom in/out on axis; if *direction* is >0 zoom in, else zoom out"
- self.major.locator.zoom(direction)
-
- def axis_date(self, tz=None):
- """
- Sets up x-axis ticks and labels that treat the x data as dates.
- *tz* is a :class:`tzinfo` instance or a timezone string.
- This timezone is used to create date labels.
- """
- # By providing a sample datetime instance with the desired
- # timezone, the registered converter can be selected,
- # and the "units" attribute, which is the timezone, can
- # be set.
- import datetime
- if isinstance(tz, six.string_types):
- import pytz
- tz = pytz.timezone(tz)
- self.update_units(datetime.datetime(2009, 1, 1, 0, 0, 0, 0, tz))
-
- def get_tick_space(self):
- """
- Return the estimated number of ticks that can fit on the axis.
- """
- # Must be overridden in the subclass
- raise NotImplementedError()
-
- def get_label_position(self):
- """
- Return the label position (top or bottom)
- """
- return self.label_position
-
- def set_label_position(self, position):
- """
- Set the label position (top or bottom)
-
- ACCEPTS: [ 'top' | 'bottom' ]
- """
- raise NotImplementedError()
-
- def get_minpos(self):
- raise NotImplementedError()
-
-
-class XAxis(Axis):
- __name__ = 'xaxis'
- axis_name = 'x'
-
- def contains(self, mouseevent):
- """Test whether the mouse event occurred in the x axis.
- """
- if callable(self._contains):
- return self._contains(self, mouseevent)
-
- x, y = mouseevent.x, mouseevent.y
- try:
- trans = self.axes.transAxes.inverted()
- xaxes, yaxes = trans.transform_point((x, y))
- except ValueError:
- return False, {}
- l, b = self.axes.transAxes.transform_point((0, 0))
- r, t = self.axes.transAxes.transform_point((1, 1))
- inaxis = xaxes >= 0 and xaxes <= 1 and (
- (y < b and y > b - self.pickradius) or
- (y > t and y < t + self.pickradius))
- return inaxis, {}
-
- def _get_tick(self, major):
- if major:
- tick_kw = self._major_tick_kw
- else:
- tick_kw = self._minor_tick_kw
- return XTick(self.axes, 0, '', major=major, **tick_kw)
-
- def _get_label(self):
- # x in axes coords, y in display coords (to be updated at draw
- # time by _update_label_positions)
- label = mtext.Text(x=0.5, y=0,
- fontproperties=font_manager.FontProperties(
- size=rcParams['axes.labelsize'],
- weight=rcParams['axes.labelweight']),
- color=rcParams['axes.labelcolor'],
- verticalalignment='top',
- horizontalalignment='center')
-
- label.set_transform(mtransforms.blended_transform_factory(
- self.axes.transAxes, mtransforms.IdentityTransform()))
-
- self._set_artist_props(label)
- self.label_position = 'bottom'
- return label
-
- def _get_offset_text(self):
- # x in axes coords, y in display coords (to be updated at draw time)
- offsetText = mtext.Text(x=1, y=0,
- fontproperties=font_manager.FontProperties(
- size=rcParams['xtick.labelsize']),
- color=rcParams['xtick.color'],
- verticalalignment='top',
- horizontalalignment='right')
- offsetText.set_transform(mtransforms.blended_transform_factory(
- self.axes.transAxes, mtransforms.IdentityTransform())
- )
- self._set_artist_props(offsetText)
- self.offset_text_position = 'bottom'
- return offsetText
-
- def _get_pixel_distance_along_axis(self, where, perturb):
- """
- Returns the amount, in data coordinates, that a single pixel
- corresponds to in the locality given by "where", which is also given
- in data coordinates, and is an x coordinate. "perturb" is the amount
- to perturb the pixel. Usually +0.5 or -0.5.
-
- Implementing this routine for an axis is optional; if present, it will
- ensure that no ticks are lost due to round-off at the extreme ends of
- an axis.
- """
-
- # Note that this routine does not work for a polar axis, because of
- # the 1e-10 below. To do things correctly, we need to use rmax
- # instead of 1e-10 for a polar axis. But since we do not have that
- # kind of information at this point, we just don't try to pad anything
- # for the theta axis of a polar plot.
- if self.axes.name == 'polar':
- return 0.0
-
- #
- # first figure out the pixel location of the "where" point. We use
- # 1e-10 for the y point, so that we remain compatible with log axes.
-
- # transformation from data coords to display coords
- trans = self.axes.transData
- # transformation from display coords to data coords
- transinv = trans.inverted()
- pix = trans.transform_point((where, 1e-10))
- # perturb the pixel
- ptp = transinv.transform_point((pix[0] + perturb, pix[1]))
- dx = abs(ptp[0] - where)
-
- return dx
-
- def set_label_position(self, position):
- """
- Set the label position (top or bottom)
-
- ACCEPTS: [ 'top' | 'bottom' ]
- """
- if position == 'top':
- self.label.set_verticalalignment('baseline')
- elif position == 'bottom':
- self.label.set_verticalalignment('top')
- else:
- raise ValueError("Position accepts only 'top' or 'bottom'")
- self.label_position = position
- self.stale = True
-
- def _get_tick_boxes_siblings(self, renderer):
- """
- Get the bounding boxes for this `.axis` and its siblings
- as set by `.Figure.align_xlabels` or `.Figure.align_ylablels`.
-
- By default it just gets bboxes for self.
- """
- bboxes = []
- bboxes2 = []
- # get the Grouper that keeps track of x-label groups for this figure
- grp = self.figure._align_xlabel_grp
- # if we want to align labels from other axes:
- for nn, axx in enumerate(grp.get_siblings(self.axes)):
- ticks_to_draw = axx.xaxis._update_ticks(renderer)
- tlb, tlb2 = axx.xaxis._get_tick_bboxes(ticks_to_draw, renderer)
- bboxes.extend(tlb)
- bboxes2.extend(tlb2)
- return bboxes, bboxes2
-
- def _update_label_position(self, renderer):
- """
- Update the label position based on the bounding box enclosing
- all the ticklabels and axis spine
- """
- if not self._autolabelpos:
- return
-
- # get bounding boxes for this axis and any siblings
- # that have been set by `fig.align_xlabels()`
- bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
-
- x, y = self.label.get_position()
- if self.label_position == 'bottom':
- try:
- spine = self.axes.spines['bottom']
- spinebbox = spine.get_transform().transform_path(
- spine.get_path()).get_extents()
- except KeyError:
- # use axes if spine doesn't exist
- spinebbox = self.axes.bbox
- bbox = mtransforms.Bbox.union(bboxes + [spinebbox])
- bottom = bbox.y0
-
- self.label.set_position(
- (x, bottom - self.labelpad * self.figure.dpi / 72.0)
- )
-
- else:
- try:
- spine = self.axes.spines['top']
- spinebbox = spine.get_transform().transform_path(
- spine.get_path()).get_extents()
- except KeyError:
- # use axes if spine doesn't exist
- spinebbox = self.axes.bbox
- bbox = mtransforms.Bbox.union(bboxes2 + [spinebbox])
- top = bbox.y1
-
- self.label.set_position(
- (x, top + self.labelpad * self.figure.dpi / 72.0)
- )
-
- def _update_offset_text_position(self, bboxes, bboxes2):
- """
- Update the offset_text position based on the sequence of bounding
- boxes of all the ticklabels
- """
- x, y = self.offsetText.get_position()
- if not len(bboxes):
- bottom = self.axes.bbox.ymin
- else:
- bbox = mtransforms.Bbox.union(bboxes)
- bottom = bbox.y0
- self.offsetText.set_position(
- (x, bottom - self.OFFSETTEXTPAD * self.figure.dpi / 72.0)
- )
-
- def get_text_heights(self, renderer):
- """
- Returns the amount of space one should reserve for text
- above and below the axes. Returns a tuple (above, below)
- """
- bbox, bbox2 = self.get_ticklabel_extents(renderer)
- # MGDTODO: Need a better way to get the pad
- padPixels = self.majorTicks[0].get_pad_pixels()
-
- above = 0.0
- if bbox2.height:
- above += bbox2.height + padPixels
- below = 0.0
- if bbox.height:
- below += bbox.height + padPixels
-
- if self.get_label_position() == 'top':
- above += self.label.get_window_extent(renderer).height + padPixels
- else:
- below += self.label.get_window_extent(renderer).height + padPixels
- return above, below
-
- def set_ticks_position(self, position):
- """
- Set the ticks position (top, bottom, both, default or none)
- both sets the ticks to appear on both positions, but does not
- change the tick labels. 'default' resets the tick positions to
- the default: ticks on both positions, labels at bottom. 'none'
- can be used if you don't want any ticks. 'none' and 'both'
- affect only the ticks, not the labels.
-
- ACCEPTS: [ 'top' | 'bottom' | 'both' | 'default' | 'none' ]
- """
- if position == 'top':
- self.set_tick_params(which='both', top=True, labeltop=True,
- bottom=False, labelbottom=False)
- elif position == 'bottom':
- self.set_tick_params(which='both', top=False, labeltop=False,
- bottom=True, labelbottom=True)
- elif position == 'both':
- self.set_tick_params(which='both', top=True,
- bottom=True)
- elif position == 'none':
- self.set_tick_params(which='both', top=False,
- bottom=False)
- elif position == 'default':
- self.set_tick_params(which='both', top=True, labeltop=False,
- bottom=True, labelbottom=True)
- else:
- raise ValueError("invalid position: %s" % position)
- self.stale = True
-
- def tick_top(self):
- """
- Move ticks and ticklabels (if present) to the top of the axes.
- """
- label = True
- if 'label1On' in self._major_tick_kw:
- label = (self._major_tick_kw['label1On']
- or self._major_tick_kw['label2On'])
- self.set_ticks_position('top')
- # if labels were turned off before this was called
- # leave them off
- self.set_tick_params(which='both', labeltop=label)
-
- def tick_bottom(self):
- """
- Move ticks and ticklabels (if present) to the bottom of the axes.
- """
- label = True
- if 'label1On' in self._major_tick_kw:
- label = (self._major_tick_kw['label1On']
- or self._major_tick_kw['label2On'])
- self.set_ticks_position('bottom')
- # if labels were turned off before this was called
- # leave them off
- self.set_tick_params(which='both', labelbottom=label)
-
- def get_ticks_position(self):
- """
- Return the ticks position (top, bottom, default or unknown)
- """
- majt = self.majorTicks[0]
- mT = self.minorTicks[0]
-
- majorTop = ((not majt.tick1On) and majt.tick2On and
- (not majt.label1On) and majt.label2On)
- minorTop = ((not mT.tick1On) and mT.tick2On and
- (not mT.label1On) and mT.label2On)
- if majorTop and minorTop:
- return 'top'
-
- MajorBottom = (majt.tick1On and (not majt.tick2On) and
- majt.label1On and (not majt.label2On))
- MinorBottom = (mT.tick1On and (not mT.tick2On) and
- mT.label1On and (not mT.label2On))
- if MajorBottom and MinorBottom:
- return 'bottom'
-
- majorDefault = (majt.tick1On and majt.tick2On and
- majt.label1On and (not majt.label2On))
- minorDefault = (mT.tick1On and mT.tick2On and
- mT.label1On and (not mT.label2On))
- if majorDefault and minorDefault:
- return 'default'
-
- return 'unknown'
-
- def get_view_interval(self):
- 'return the Interval instance for this axis view limits'
- return self.axes.viewLim.intervalx
-
- def set_view_interval(self, vmin, vmax, ignore=False):
- """
- If *ignore* is *False*, the order of vmin, vmax
- does not matter; the original axis orientation will
- be preserved. In addition, the view limits can be
- expanded, but will not be reduced. This method is
- for mpl internal use; for normal use, see
- :meth:`~matplotlib.axes.Axes.set_xlim`.
-
- """
- if ignore:
- self.axes.viewLim.intervalx = vmin, vmax
- else:
- Vmin, Vmax = self.get_view_interval()
- if Vmin < Vmax:
- self.axes.viewLim.intervalx = (min(vmin, vmax, Vmin),
- max(vmin, vmax, Vmax))
- else:
- self.axes.viewLim.intervalx = (max(vmin, vmax, Vmin),
- min(vmin, vmax, Vmax))
-
- def get_minpos(self):
- return self.axes.dataLim.minposx
-
- def get_data_interval(self):
- 'return the Interval instance for this axis data limits'
- return self.axes.dataLim.intervalx
-
- def set_data_interval(self, vmin, vmax, ignore=False):
- 'set the axis data limits'
- if ignore:
- self.axes.dataLim.intervalx = vmin, vmax
- else:
- Vmin, Vmax = self.get_data_interval()
- self.axes.dataLim.intervalx = min(vmin, Vmin), max(vmax, Vmax)
- self.stale = True
-
- def set_default_intervals(self):
- 'set the default limits for the axis interval if they are not mutated'
- xmin, xmax = 0., 1.
- dataMutated = self.axes.dataLim.mutatedx()
- viewMutated = self.axes.viewLim.mutatedx()
- if not dataMutated or not viewMutated:
- if self.converter is not None:
- info = self.converter.axisinfo(self.units, self)
- if info.default_limits is not None:
- valmin, valmax = info.default_limits
- xmin = self.converter.convert(valmin, self.units, self)
- xmax = self.converter.convert(valmax, self.units, self)
- if not dataMutated:
- self.axes.dataLim.intervalx = xmin, xmax
- if not viewMutated:
- self.axes.viewLim.intervalx = xmin, xmax
- self.stale = True
-
- def get_tick_space(self):
- ends = self.axes.transAxes.transform([[0, 0], [1, 0]])
- length = ((ends[1][0] - ends[0][0]) / self.axes.figure.dpi) * 72.0
- tick = self._get_tick(True)
- # There is a heuristic here that the aspect ratio of tick text
- # is no more than 3:1
- size = tick.label1.get_size() * 3
- if size > 0:
- return int(np.floor(length / size))
- else:
- return 2**31 - 1
-
-
-class YAxis(Axis):
- __name__ = 'yaxis'
- axis_name = 'y'
-
- def contains(self, mouseevent):
- """Test whether the mouse event occurred in the y axis.
-
- Returns *True* | *False*
- """
- if callable(self._contains):
- return self._contains(self, mouseevent)
-
- x, y = mouseevent.x, mouseevent.y
- try:
- trans = self.axes.transAxes.inverted()
- xaxes, yaxes = trans.transform_point((x, y))
- except ValueError:
- return False, {}
- l, b = self.axes.transAxes.transform_point((0, 0))
- r, t = self.axes.transAxes.transform_point((1, 1))
- inaxis = yaxes >= 0 and yaxes <= 1 and (
- (x < l and x > l - self.pickradius) or
- (x > r and x < r + self.pickradius))
- return inaxis, {}
-
- def _get_tick(self, major):
- if major:
- tick_kw = self._major_tick_kw
- else:
- tick_kw = self._minor_tick_kw
- return YTick(self.axes, 0, '', major=major, **tick_kw)
-
- def _get_label(self):
- # x in display coords (updated by _update_label_position)
- # y in axes coords
- label = mtext.Text(x=0, y=0.5,
- # todo: get the label position
- fontproperties=font_manager.FontProperties(
- size=rcParams['axes.labelsize'],
- weight=rcParams['axes.labelweight']),
- color=rcParams['axes.labelcolor'],
- verticalalignment='bottom',
- horizontalalignment='center',
- rotation='vertical',
- rotation_mode='anchor')
- label.set_transform(mtransforms.blended_transform_factory(
- mtransforms.IdentityTransform(), self.axes.transAxes))
-
- self._set_artist_props(label)
- self.label_position = 'left'
- return label
-
- def _get_offset_text(self):
- # x in display coords, y in axes coords (to be updated at draw time)
- offsetText = mtext.Text(x=0, y=0.5,
- fontproperties=font_manager.FontProperties(
- size=rcParams['ytick.labelsize']
- ),
- color=rcParams['ytick.color'],
- verticalalignment='baseline',
- horizontalalignment='left')
- offsetText.set_transform(mtransforms.blended_transform_factory(
- self.axes.transAxes, mtransforms.IdentityTransform())
- )
- self._set_artist_props(offsetText)
- self.offset_text_position = 'left'
- return offsetText
-
- def _get_pixel_distance_along_axis(self, where, perturb):
- """
- Returns the amount, in data coordinates, that a single pixel
- corresponds to in the locality given by *where*, which is also given
- in data coordinates, and is a y coordinate.
-
- *perturb* is the amount to perturb the pixel. Usually +0.5 or -0.5.
-
- Implementing this routine for an axis is optional; if present, it will
- ensure that no ticks are lost due to round-off at the extreme ends of
- an axis.
- """
-
- #
- # first figure out the pixel location of the "where" point. We use
- # 1e-10 for the x point, so that we remain compatible with log axes.
-
- # transformation from data coords to display coords
- trans = self.axes.transData
- # transformation from display coords to data coords
- transinv = trans.inverted()
- pix = trans.transform_point((1e-10, where))
- # perturb the pixel
- ptp = transinv.transform_point((pix[0], pix[1] + perturb))
- dy = abs(ptp[1] - where)
- return dy
-
- def set_label_position(self, position):
- """
- Set the label position (left or right)
-
- ACCEPTS: [ 'left' | 'right' ]
- """
- self.label.set_rotation_mode('anchor')
- self.label.set_horizontalalignment('center')
- if position == 'left':
- self.label.set_verticalalignment('bottom')
- elif position == 'right':
- self.label.set_verticalalignment('top')
- else:
- raise ValueError("Position accepts only 'left' or 'right'")
- self.label_position = position
- self.stale = True
-
- def _get_tick_boxes_siblings(self, renderer):
- """
- Get the bounding boxes for this `.axis` and its siblings
- as set by `.Figure.align_xlabels` or `.Figure.align_ylablels`.
-
- By default it just gets bboxes for self.
- """
- bboxes = []
- bboxes2 = []
- # get the Grouper that keeps track of y-label groups for this figure
- grp = self.figure._align_ylabel_grp
- # if we want to align labels from other axes:
- for axx in grp.get_siblings(self.axes):
- ticks_to_draw = axx.yaxis._update_ticks(renderer)
- tlb, tlb2 = axx.yaxis._get_tick_bboxes(ticks_to_draw, renderer)
- bboxes.extend(tlb)
- bboxes2.extend(tlb2)
- return bboxes, bboxes2
-
- def _update_label_position(self, renderer):
- """
- Update the label position based on the bounding box enclosing
- all the ticklabels and axis spine
- """
- if not self._autolabelpos:
- return
-
- # get bounding boxes for this axis and any siblings
- # that have been set by `fig.align_ylabels()`
- bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
-
- x, y = self.label.get_position()
- if self.label_position == 'left':
- try:
- spine = self.axes.spines['left']
- spinebbox = spine.get_transform().transform_path(
- spine.get_path()).get_extents()
- except KeyError:
- # use axes if spine doesn't exist
- spinebbox = self.axes.bbox
- bbox = mtransforms.Bbox.union(bboxes + [spinebbox])
- left = bbox.x0
- self.label.set_position(
- (left - self.labelpad * self.figure.dpi / 72.0, y)
- )
-
- else:
- try:
- spine = self.axes.spines['right']
- spinebbox = spine.get_transform().transform_path(
- spine.get_path()).get_extents()
- except KeyError:
- # use axes if spine doesn't exist
- spinebbox = self.axes.bbox
- bbox = mtransforms.Bbox.union(bboxes2 + [spinebbox])
- right = bbox.x1
-
- self.label.set_position(
- (right + self.labelpad * self.figure.dpi / 72.0, y)
- )
-
- def _update_offset_text_position(self, bboxes, bboxes2):
- """
- Update the offset_text position based on the sequence of bounding
- boxes of all the ticklabels
- """
- x, y = self.offsetText.get_position()
- top = self.axes.bbox.ymax
- self.offsetText.set_position(
- (x, top + self.OFFSETTEXTPAD * self.figure.dpi / 72.0)
- )
-
- def set_offset_position(self, position):
- """
- .. ACCEPTS: [ 'left' | 'right' ]
- """
- x, y = self.offsetText.get_position()
- if position == 'left':
- x = 0
- elif position == 'right':
- x = 1
- else:
- raise ValueError("Position accepts only [ 'left' | 'right' ]")
-
- self.offsetText.set_ha(position)
- self.offsetText.set_position((x, y))
- self.stale = True
-
- def get_text_widths(self, renderer):
- bbox, bbox2 = self.get_ticklabel_extents(renderer)
- # MGDTODO: Need a better way to get the pad
- padPixels = self.majorTicks[0].get_pad_pixels()
-
- left = 0.0
- if bbox.width:
- left += bbox.width + padPixels
- right = 0.0
- if bbox2.width:
- right += bbox2.width + padPixels
-
- if self.get_label_position() == 'left':
- left += self.label.get_window_extent(renderer).width + padPixels
- else:
- right += self.label.get_window_extent(renderer).width + padPixels
- return left, right
-
- def set_ticks_position(self, position):
- """
- Set the ticks position (left, right, both, default or none)
- 'both' sets the ticks to appear on both positions, but does not
- change the tick labels. 'default' resets the tick positions to
- the default: ticks on both positions, labels at left. 'none'
- can be used if you don't want any ticks. 'none' and 'both'
- affect only the ticks, not the labels.
-
- ACCEPTS: [ 'left' | 'right' | 'both' | 'default' | 'none' ]
- """
- if position == 'right':
- self.set_tick_params(which='both', right=True, labelright=True,
- left=False, labelleft=False)
- self.set_offset_position(position)
- elif position == 'left':
- self.set_tick_params(which='both', right=False, labelright=False,
- left=True, labelleft=True)
- self.set_offset_position(position)
- elif position == 'both':
- self.set_tick_params(which='both', right=True,
- left=True)
- elif position == 'none':
- self.set_tick_params(which='both', right=False,
- left=False)
- elif position == 'default':
- self.set_tick_params(which='both', right=True, labelright=False,
- left=True, labelleft=True)
- else:
- raise ValueError("invalid position: %s" % position)
- self.stale = True
-
- def tick_right(self):
- """
- Move ticks and ticklabels (if present) to the right of the axes.
- """
- label = True
- if 'label1On' in self._major_tick_kw:
- label = (self._major_tick_kw['label1On']
- or self._major_tick_kw['label2On'])
- self.set_ticks_position('right')
- # if labels were turned off before this was called
- # leave them off
- self.set_tick_params(which='both', labelright=label)
-
- def tick_left(self):
- """
- Move ticks and ticklabels (if present) to the left of the axes.
- """
- label = True
- if 'label1On' in self._major_tick_kw:
- label = (self._major_tick_kw['label1On']
- or self._major_tick_kw['label2On'])
- self.set_ticks_position('left')
- # if labels were turned off before this was called
- # leave them off
- self.set_tick_params(which='both', labelleft=label)
-
- def get_ticks_position(self):
- """
- Return the ticks position (left, right, both or unknown)
- """
- majt = self.majorTicks[0]
- mT = self.minorTicks[0]
-
- majorRight = ((not majt.tick1On) and majt.tick2On and
- (not majt.label1On) and majt.label2On)
- minorRight = ((not mT.tick1On) and mT.tick2On and
- (not mT.label1On) and mT.label2On)
- if majorRight and minorRight:
- return 'right'
-
- majorLeft = (majt.tick1On and (not majt.tick2On) and
- majt.label1On and (not majt.label2On))
- minorLeft = (mT.tick1On and (not mT.tick2On) and
- mT.label1On and (not mT.label2On))
- if majorLeft and minorLeft:
- return 'left'
-
- majorDefault = (majt.tick1On and majt.tick2On and
- majt.label1On and (not majt.label2On))
- minorDefault = (mT.tick1On and mT.tick2On and
- mT.label1On and (not mT.label2On))
- if majorDefault and minorDefault:
- return 'default'
-
- return 'unknown'
-
- def get_view_interval(self):
- 'return the Interval instance for this axis view limits'
- return self.axes.viewLim.intervaly
-
- def set_view_interval(self, vmin, vmax, ignore=False):
- """
- If *ignore* is *False*, the order of vmin, vmax
- does not matter; the original axis orientation will
- be preserved. In addition, the view limits can be
- expanded, but will not be reduced. This method is
- for mpl internal use; for normal use, see
- :meth:`~matplotlib.axes.Axes.set_ylim`.
-
- """
- if ignore:
- self.axes.viewLim.intervaly = vmin, vmax
- else:
- Vmin, Vmax = self.get_view_interval()
- if Vmin < Vmax:
- self.axes.viewLim.intervaly = (min(vmin, vmax, Vmin),
- max(vmin, vmax, Vmax))
- else:
- self.axes.viewLim.intervaly = (max(vmin, vmax, Vmin),
- min(vmin, vmax, Vmax))
- self.stale = True
-
- def get_minpos(self):
- return self.axes.dataLim.minposy
-
- def get_data_interval(self):
- 'return the Interval instance for this axis data limits'
- return self.axes.dataLim.intervaly
-
- def set_data_interval(self, vmin, vmax, ignore=False):
- 'set the axis data limits'
- if ignore:
- self.axes.dataLim.intervaly = vmin, vmax
- else:
- Vmin, Vmax = self.get_data_interval()
- self.axes.dataLim.intervaly = min(vmin, Vmin), max(vmax, Vmax)
- self.stale = True
-
- def set_default_intervals(self):
- 'set the default limits for the axis interval if they are not mutated'
- ymin, ymax = 0., 1.
- dataMutated = self.axes.dataLim.mutatedy()
- viewMutated = self.axes.viewLim.mutatedy()
- if not dataMutated or not viewMutated:
- if self.converter is not None:
- info = self.converter.axisinfo(self.units, self)
- if info.default_limits is not None:
- valmin, valmax = info.default_limits
- ymin = self.converter.convert(valmin, self.units, self)
- ymax = self.converter.convert(valmax, self.units, self)
- if not dataMutated:
- self.axes.dataLim.intervaly = ymin, ymax
- if not viewMutated:
- self.axes.viewLim.intervaly = ymin, ymax
- self.stale = True
-
- def get_tick_space(self):
- ends = self.axes.transAxes.transform([[0, 0], [0, 1]])
- length = ((ends[1][1] - ends[0][1]) / self.axes.figure.dpi) * 72.0
- tick = self._get_tick(True)
- # Having a spacing of at least 2 just looks good.
- size = tick.label1.get_size() * 2.0
- if size > 0:
- return int(np.floor(length / size))
- else:
- return 2**31 - 1
diff --git a/contrib/python/matplotlib/py2/matplotlib/backend_bases.py b/contrib/python/matplotlib/py2/matplotlib/backend_bases.py
deleted file mode 100644
index 136f567ebc..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backend_bases.py
+++ /dev/null
@@ -1,3383 +0,0 @@
-"""
-Abstract base classes define the primitives that renderers and
-graphics contexts must implement to serve as a matplotlib backend
-
-:class:`RendererBase`
- An abstract base class to handle drawing/rendering operations.
-
-:class:`FigureCanvasBase`
- The abstraction layer that separates the
- :class:`matplotlib.figure.Figure` from the backend specific
- details like a user interface drawing area
-
-:class:`GraphicsContextBase`
- An abstract base class that provides color, line styles, etc...
-
-:class:`Event`
- The base class for all of the matplotlib event
- handling. Derived classes such as :class:`KeyEvent` and
- :class:`MouseEvent` store the meta data like keys and buttons
- pressed, x and y locations in pixel and
- :class:`~matplotlib.axes.Axes` coordinates.
-
-:class:`ShowBase`
- The base class for the Show class of each interactive backend;
- the 'show' callable is then set to Show.__call__, inherited from
- ShowBase.
-
-:class:`ToolContainerBase`
- The base class for the Toolbar class of each interactive backend.
-
-:class:`StatusbarBase`
- The base class for the messaging area.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-
-from contextlib import contextmanager
-from functools import partial
-import importlib
-import io
-import os
-import sys
-import time
-import warnings
-from weakref import WeakKeyDictionary
-
-import numpy as np
-
-from matplotlib import (
- backend_tools as tools, cbook, colors, textpath, tight_bbox, transforms,
- widgets, get_backend, is_interactive, rcParams)
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.transforms import Bbox, TransformedBbox, Affine2D
-from matplotlib.path import Path
-
-try:
- from PIL import Image
- _has_pil = True
- del Image
-except ImportError:
- _has_pil = False
-
-
-_default_filetypes = {
- 'ps': 'Postscript',
- 'eps': 'Encapsulated Postscript',
- 'pdf': 'Portable Document Format',
- 'pgf': 'PGF code for LaTeX',
- 'png': 'Portable Network Graphics',
- 'raw': 'Raw RGBA bitmap',
- 'rgba': 'Raw RGBA bitmap',
- 'svg': 'Scalable Vector Graphics',
- 'svgz': 'Scalable Vector Graphics'
-}
-
-
-_default_backends = {
- 'ps': 'matplotlib.backends.backend_ps',
- 'eps': 'matplotlib.backends.backend_ps',
- 'pdf': 'matplotlib.backends.backend_pdf',
- 'pgf': 'matplotlib.backends.backend_pgf',
- 'png': 'matplotlib.backends.backend_agg',
- 'raw': 'matplotlib.backends.backend_agg',
- 'rgba': 'matplotlib.backends.backend_agg',
- 'svg': 'matplotlib.backends.backend_svg',
- 'svgz': 'matplotlib.backends.backend_svg',
-}
-
-
-def register_backend(format, backend, description=None):
- """
- Register a backend for saving to a given file format.
-
- Parameters
- ----------
- format : str
- File extension
-
- backend : module string or canvas class
- Backend for handling file output
-
- description : str, optional
- Description of the file type. Defaults to an empty string
- """
- if description is None:
- description = ''
- _default_backends[format] = backend
- _default_filetypes[format] = description
-
-
-def get_registered_canvas_class(format):
- """
- Return the registered default canvas for given file format.
- Handles deferred import of required backend.
- """
- if format not in _default_backends:
- return None
- backend_class = _default_backends[format]
- if isinstance(backend_class, six.string_types):
- backend_class = importlib.import_module(backend_class).FigureCanvas
- _default_backends[format] = backend_class
- return backend_class
-
-
-class _Backend(object):
- # A backend can be defined by using the following pattern:
- #
- # @_Backend.export
- # class FooBackend(_Backend):
- # # override the attributes and methods documented below.
-
- # The following attributes and methods must be overridden by subclasses.
-
- # The `FigureCanvas` and `FigureManager` classes must be defined.
- FigureCanvas = None
- FigureManager = None
-
- # The following methods must be left as None for non-interactive backends.
- # For interactive backends, `trigger_manager_draw` should be a function
- # taking a manager as argument and triggering a canvas draw, and `mainloop`
- # should be a function taking no argument and starting the backend main
- # loop.
- trigger_manager_draw = None
- mainloop = None
-
- # The following methods will be automatically defined and exported, but
- # can be overridden.
-
- @classmethod
- def new_figure_manager(cls, num, *args, **kwargs):
- """Create a new figure manager instance.
- """
- # This import needs to happen here due to circular imports.
- from matplotlib.figure import Figure
- fig_cls = kwargs.pop('FigureClass', Figure)
- fig = fig_cls(*args, **kwargs)
- return cls.new_figure_manager_given_figure(num, fig)
-
- @classmethod
- def new_figure_manager_given_figure(cls, num, figure):
- """Create a new figure manager instance for the given figure.
- """
- canvas = cls.FigureCanvas(figure)
- manager = cls.FigureManager(canvas, num)
- return manager
-
- @classmethod
- def draw_if_interactive(cls):
- if cls.trigger_manager_draw is not None and is_interactive():
- manager = Gcf.get_active()
- if manager:
- cls.trigger_manager_draw(manager)
-
- @classmethod
- def show(cls, block=None):
- """Show all figures.
-
- `show` blocks by calling `mainloop` if *block* is ``True``, or if it
- is ``None`` and we are neither in IPython's ``%pylab`` mode, nor in
- `interactive` mode.
- """
- if cls.mainloop is None:
- return
- managers = Gcf.get_all_fig_managers()
- if not managers:
- return
- for manager in managers:
- manager.show()
- if block is None:
- # Hack: Are we in IPython's pylab mode?
- from matplotlib import pyplot
- try:
- # IPython versions >= 0.10 tack the _needmain attribute onto
- # pyplot.show, and always set it to False, when in %pylab mode.
- ipython_pylab = not pyplot.show._needmain
- except AttributeError:
- ipython_pylab = False
- block = not ipython_pylab and not is_interactive()
- # TODO: The above is a hack to get the WebAgg backend working with
- # ipython's `%pylab` mode until proper integration is implemented.
- if get_backend() == "WebAgg":
- block = True
- if block:
- cls.mainloop()
-
- # This method is the one actually exporting the required methods.
-
- @staticmethod
- def export(cls):
- for name in ["FigureCanvas",
- "FigureManager",
- "new_figure_manager",
- "new_figure_manager_given_figure",
- "draw_if_interactive",
- "show"]:
- setattr(sys.modules[cls.__module__], name, getattr(cls, name))
-
- # For back-compatibility, generate a shim `Show` class.
-
- class Show(ShowBase):
- def mainloop(self):
- return cls.mainloop()
-
- setattr(sys.modules[cls.__module__], "Show", Show)
- return cls
-
-
-class ShowBase(_Backend):
- """
- Simple base class to generate a show() callable in backends.
-
- Subclass must override mainloop() method.
- """
-
- def __call__(self, block=None):
- return self.show(block=block)
-
-
-class RendererBase(object):
- """An abstract base class to handle drawing/rendering operations.
-
- The following methods must be implemented in the backend for full
- functionality (though just implementing :meth:`draw_path` alone would
- give a highly capable backend):
-
- * :meth:`draw_path`
- * :meth:`draw_image`
- * :meth:`draw_gouraud_triangle`
-
- The following methods *should* be implemented in the backend for
- optimization reasons:
-
- * :meth:`draw_text`
- * :meth:`draw_markers`
- * :meth:`draw_path_collection`
- * :meth:`draw_quad_mesh`
-
- """
- def __init__(self):
- self._texmanager = None
- self._text2path = textpath.TextToPath()
-
- def open_group(self, s, gid=None):
- """
- Open a grouping element with label *s*. If *gid* is given, use
- *gid* as the id of the group. Is only currently used by
- :mod:`~matplotlib.backends.backend_svg`.
- """
-
- def close_group(self, s):
- """
- Close a grouping element with label *s*
- Is only currently used by :mod:`~matplotlib.backends.backend_svg`
- """
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- """
- Draws a :class:`~matplotlib.path.Path` instance using the
- given affine transform.
- """
- raise NotImplementedError
-
- def draw_markers(self, gc, marker_path, marker_trans, path,
- trans, rgbFace=None):
- """
- Draws a marker at each of the vertices in path. This includes
- all vertices, including control points on curves. To avoid
- that behavior, those vertices should be removed before calling
- this function.
-
- This provides a fallback implementation of draw_markers that
- makes multiple calls to :meth:`draw_path`. Some backends may
- want to override this method in order to draw the marker only
- once and reuse it multiple times.
-
- Parameters
- ----------
- gc : `GraphicsContextBase`
- The graphics context
-
- marker_trans : `matplotlib.transforms.Transform`
- An affine transform applied to the marker.
-
- trans : `matplotlib.transforms.Transform`
- An affine transform applied to the path.
-
- """
- for vertices, codes in path.iter_segments(trans, simplify=False):
- if len(vertices):
- x, y = vertices[-2:]
- self.draw_path(gc, marker_path,
- marker_trans +
- transforms.Affine2D().translate(x, y),
- rgbFace)
-
- def draw_path_collection(self, gc, master_transform, paths, all_transforms,
- offsets, offsetTrans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position):
- """
- Draws a collection of paths selecting drawing properties from
- the lists *facecolors*, *edgecolors*, *linewidths*,
- *linestyles* and *antialiaseds*. *offsets* is a list of
- offsets to apply to each of the paths. The offsets in
- *offsets* are first transformed by *offsetTrans* before being
- applied. *offset_position* may be either "screen" or "data"
- depending on the space that the offsets are in.
-
- This provides a fallback implementation of
- :meth:`draw_path_collection` that makes multiple calls to
- :meth:`draw_path`. Some backends may want to override this in
- order to render each set of path data only once, and then
- reference that path multiple times with the different offsets,
- colors, styles etc. The generator methods
- :meth:`_iter_collection_raw_paths` and
- :meth:`_iter_collection` are provided to help with (and
- standardize) the implementation across backends. It is highly
- recommended to use those generators, so that changes to the
- behavior of :meth:`draw_path_collection` can be made globally.
- """
- path_ids = []
- for path, transform in self._iter_collection_raw_paths(
- master_transform, paths, all_transforms):
- path_ids.append((path, transforms.Affine2D(transform)))
-
- for xo, yo, path_id, gc0, rgbFace in self._iter_collection(
- gc, master_transform, all_transforms, path_ids, offsets,
- offsetTrans, facecolors, edgecolors, linewidths, linestyles,
- antialiaseds, urls, offset_position):
- path, transform = path_id
- transform = transforms.Affine2D(
- transform.get_matrix()).translate(xo, yo)
- self.draw_path(gc0, path, transform, rgbFace)
-
- def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight,
- coordinates, offsets, offsetTrans, facecolors,
- antialiased, edgecolors):
- """
- This provides a fallback implementation of
- :meth:`draw_quad_mesh` that generates paths and then calls
- :meth:`draw_path_collection`.
- """
-
- from matplotlib.collections import QuadMesh
- paths = QuadMesh.convert_mesh_to_paths(
- meshWidth, meshHeight, coordinates)
-
- if edgecolors is None:
- edgecolors = facecolors
- linewidths = np.array([gc.get_linewidth()], float)
-
- return self.draw_path_collection(
- gc, master_transform, paths, [], offsets, offsetTrans, facecolors,
- edgecolors, linewidths, [], [antialiased], [None], 'screen')
-
- def draw_gouraud_triangle(self, gc, points, colors, transform):
- """
- Draw a Gouraud-shaded triangle.
-
- Parameters
- ----------
- points : array_like, shape=(3, 2)
- Array of (x, y) points for the triangle.
-
- colors : array_like, shape=(3, 4)
- RGBA colors for each point of the triangle.
-
- transform : `matplotlib.transforms.Transform`
- An affine transform to apply to the points.
-
- """
- raise NotImplementedError
-
- def draw_gouraud_triangles(self, gc, triangles_array, colors_array,
- transform):
- """
- Draws a series of Gouraud triangles.
-
- Parameters
- ----------
- points : array_like, shape=(N, 3, 2)
- Array of *N* (x, y) points for the triangles.
-
- colors : array_like, shape=(N, 3, 4)
- Array of *N* RGBA colors for each point of the triangles.
-
- transform : `matplotlib.transforms.Transform`
- An affine transform to apply to the points.
- """
- transform = transform.frozen()
- for tri, col in zip(triangles_array, colors_array):
- self.draw_gouraud_triangle(gc, tri, col, transform)
-
- def _iter_collection_raw_paths(self, master_transform, paths,
- all_transforms):
- """
- This is a helper method (along with :meth:`_iter_collection`) to make
- it easier to write a space-efficient :meth:`draw_path_collection`
- implementation in a backend.
-
- This method yields all of the base path/transform
- combinations, given a master transform, a list of paths and
- list of transforms.
-
- The arguments should be exactly what is passed in to
- :meth:`draw_path_collection`.
-
- The backend should take each yielded path and transform and
- create an object that can be referenced (reused) later.
- """
- Npaths = len(paths)
- Ntransforms = len(all_transforms)
- N = max(Npaths, Ntransforms)
-
- if Npaths == 0:
- return
-
- transform = transforms.IdentityTransform()
- for i in xrange(N):
- path = paths[i % Npaths]
- if Ntransforms:
- transform = Affine2D(all_transforms[i % Ntransforms])
- yield path, transform + master_transform
-
- def _iter_collection_uses_per_path(self, paths, all_transforms,
- offsets, facecolors, edgecolors):
- """
- Compute how many times each raw path object returned by
- _iter_collection_raw_paths would be used when calling
- _iter_collection. This is intended for the backend to decide
- on the tradeoff between using the paths in-line and storing
- them once and reusing. Rounds up in case the number of uses
- is not the same for every path.
- """
- Npaths = len(paths)
- if Npaths == 0 or (len(facecolors) == 0 and len(edgecolors) == 0):
- return 0
- Npath_ids = max(Npaths, len(all_transforms))
- N = max(Npath_ids, len(offsets))
- return (N + Npath_ids - 1) // Npath_ids
-
- def _iter_collection(self, gc, master_transform, all_transforms,
- path_ids, offsets, offsetTrans, facecolors,
- edgecolors, linewidths, linestyles,
- antialiaseds, urls, offset_position):
- """
- This is a helper method (along with
- :meth:`_iter_collection_raw_paths`) to make it easier to write
- a space-efficient :meth:`draw_path_collection` implementation in a
- backend.
-
- This method yields all of the path, offset and graphics
- context combinations to draw the path collection. The caller
- should already have looped over the results of
- :meth:`_iter_collection_raw_paths` to draw this collection.
-
- The arguments should be the same as that passed into
- :meth:`draw_path_collection`, with the exception of
- *path_ids*, which is a list of arbitrary objects that the
- backend will use to reference one of the paths created in the
- :meth:`_iter_collection_raw_paths` stage.
-
- Each yielded result is of the form::
-
- xo, yo, path_id, gc, rgbFace
-
- where *xo*, *yo* is an offset; *path_id* is one of the elements of
- *path_ids*; *gc* is a graphics context and *rgbFace* is a color to
- use for filling the path.
- """
- Ntransforms = len(all_transforms)
- Npaths = len(path_ids)
- Noffsets = len(offsets)
- N = max(Npaths, Noffsets)
- Nfacecolors = len(facecolors)
- Nedgecolors = len(edgecolors)
- Nlinewidths = len(linewidths)
- Nlinestyles = len(linestyles)
- Naa = len(antialiaseds)
- Nurls = len(urls)
-
- if (Nfacecolors == 0 and Nedgecolors == 0) or Npaths == 0:
- return
- if Noffsets:
- toffsets = offsetTrans.transform(offsets)
-
- gc0 = self.new_gc()
- gc0.copy_properties(gc)
-
- if Nfacecolors == 0:
- rgbFace = None
-
- if Nedgecolors == 0:
- gc0.set_linewidth(0.0)
-
- xo, yo = 0, 0
- for i in xrange(N):
- path_id = path_ids[i % Npaths]
- if Noffsets:
- xo, yo = toffsets[i % Noffsets]
- if offset_position == 'data':
- if Ntransforms:
- transform = (
- Affine2D(all_transforms[i % Ntransforms]) +
- master_transform)
- else:
- transform = master_transform
- xo, yo = transform.transform_point((xo, yo))
- xp, yp = transform.transform_point((0, 0))
- xo = -(xp - xo)
- yo = -(yp - yo)
- if not (np.isfinite(xo) and np.isfinite(yo)):
- continue
- if Nfacecolors:
- rgbFace = facecolors[i % Nfacecolors]
- if Nedgecolors:
- if Nlinewidths:
- gc0.set_linewidth(linewidths[i % Nlinewidths])
- if Nlinestyles:
- gc0.set_dashes(*linestyles[i % Nlinestyles])
- fg = edgecolors[i % Nedgecolors]
- if len(fg) == 4:
- if fg[3] == 0.0:
- gc0.set_linewidth(0)
- else:
- gc0.set_foreground(fg)
- else:
- gc0.set_foreground(fg)
- if rgbFace is not None and len(rgbFace) == 4:
- if rgbFace[3] == 0:
- rgbFace = None
- gc0.set_antialiased(antialiaseds[i % Naa])
- if Nurls:
- gc0.set_url(urls[i % Nurls])
-
- yield xo, yo, path_id, gc0, rgbFace
- gc0.restore()
-
- def get_image_magnification(self):
- """
- Get the factor by which to magnify images passed to :meth:`draw_image`.
- Allows a backend to have images at a different resolution to other
- artists.
- """
- return 1.0
-
- def draw_image(self, gc, x, y, im, transform=None):
- """
- Draw an RGBA image.
-
- Parameters
- ----------
- gc : `GraphicsContextBase`
- a graphics context with clipping information.
-
- x : scalar
- the distance in physical units (i.e., dots or pixels) from the left
- hand side of the canvas.
-
- y : scalar
- the distance in physical units (i.e., dots or pixels) from the
- bottom side of the canvas.
-
- im : array_like, shape=(N, M, 4), dtype=np.uint8
- An array of RGBA pixels.
-
- transform : `matplotlib.transforms.Affine2DBase`
- If and only if the concrete backend is written such that
- :meth:`option_scale_image` returns ``True``, an affine
- transformation *may* be passed to :meth:`draw_image`. It takes the
- form of a :class:`~matplotlib.transforms.Affine2DBase` instance.
- The translation vector of the transformation is given in physical
- units (i.e., dots or pixels). Note that the transformation does not
- override `x` and `y`, and has to be applied *before* translating
- the result by `x` and `y` (this can be accomplished by adding `x`
- and `y` to the translation vector defined by `transform`).
- """
- raise NotImplementedError
-
- def option_image_nocomposite(self):
- """
- override this method for renderers that do not necessarily always
- want to rescale and composite raster images. (like SVG, PDF, or PS)
- """
- return False
-
- def option_scale_image(self):
- """
- override this method for renderers that support arbitrary affine
- transformations in :meth:`draw_image` (most vector backends).
- """
- return False
-
- def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
- """
- """
- self._draw_text_as_path(gc, x, y, s, prop, angle, ismath="TeX")
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- """
- Draw the text instance
-
- Parameters
- ----------
- gc : `GraphicsContextBase`
- the graphics context
-
- x : scalar
- the x location of the text in display coords
-
- y : scalar
- the y location of the text baseline in display coords
-
- s : str
- the text string
-
- prop : `matplotlib.font_manager.FontProperties`
- font properties
-
- angle : scalar
- the rotation angle in degrees
-
- mtext : `matplotlib.text.Text`
- the original text object to be rendered
-
- Notes
- -----
- **backend implementers note**
-
- When you are trying to determine if you have gotten your bounding box
- right (which is what enables the text layout/alignment to work
- properly), it helps to change the line in text.py::
-
- if 0: bbox_artist(self, renderer)
-
- to if 1, and then the actual bounding box will be plotted along with
- your text.
- """
-
- self._draw_text_as_path(gc, x, y, s, prop, angle, ismath)
-
- def _get_text_path_transform(self, x, y, s, prop, angle, ismath):
- """
- return the text path and transform
-
- Parameters
- ----------
- prop : `matplotlib.font_manager.FontProperties`
- font property
-
- s : str
- text to be converted
-
- usetex : bool
- If True, use matplotlib usetex mode.
-
- ismath : bool
- If True, use mathtext parser. If "TeX", use *usetex* mode.
- """
-
- text2path = self._text2path
- fontsize = self.points_to_pixels(prop.get_size_in_points())
-
- if ismath == "TeX":
- verts, codes = text2path.get_text_path(prop, s, ismath=False,
- usetex=True)
- else:
- verts, codes = text2path.get_text_path(prop, s, ismath=ismath,
- usetex=False)
-
- path = Path(verts, codes)
- angle = np.deg2rad(angle)
- if self.flipy():
- transform = Affine2D().scale(fontsize / text2path.FONT_SCALE,
- fontsize / text2path.FONT_SCALE)
- transform = transform.rotate(angle).translate(x, self.height - y)
- else:
- transform = Affine2D().scale(fontsize / text2path.FONT_SCALE,
- fontsize / text2path.FONT_SCALE)
- transform = transform.rotate(angle).translate(x, y)
-
- return path, transform
-
- def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath):
- """
- draw the text by converting them to paths using textpath module.
-
- Parameters
- ----------
- prop : `matplotlib.font_manager.FontProperties`
- font property
-
- s : str
- text to be converted
-
- usetex : bool
- If True, use matplotlib usetex mode.
-
- ismath : bool
- If True, use mathtext parser. If "TeX", use *usetex* mode.
- """
- path, transform = self._get_text_path_transform(
- x, y, s, prop, angle, ismath)
- color = gc.get_rgb()
-
- gc.set_linewidth(0.0)
- self.draw_path(gc, path, transform, rgbFace=color)
-
- def get_text_width_height_descent(self, s, prop, ismath):
- """
- Get the width, height, and descent (offset from the bottom
- to the baseline), in display coords, of the string *s* with
- :class:`~matplotlib.font_manager.FontProperties` *prop*
- """
- if ismath == 'TeX':
- # todo: handle props
- size = prop.get_size_in_points()
- texmanager = self._text2path.get_texmanager()
- fontsize = prop.get_size_in_points()
- w, h, d = texmanager.get_text_width_height_descent(
- s, fontsize, renderer=self)
- return w, h, d
-
- dpi = self.points_to_pixels(72)
- if ismath:
- dims = self._text2path.mathtext_parser.parse(s, dpi, prop)
- return dims[0:3] # return width, height, descent
-
- flags = self._text2path._get_hinting_flag()
- font = self._text2path._get_font(prop)
- size = prop.get_size_in_points()
- font.set_size(size, dpi)
- # the width and height of unrotated string
- font.set_text(s, 0.0, flags=flags)
- w, h = font.get_width_height()
- d = font.get_descent()
- w /= 64.0 # convert from subpixels
- h /= 64.0
- d /= 64.0
- return w, h, d
-
- def flipy(self):
- """
- Return true if y small numbers are top for renderer Is used
- for drawing text (:mod:`matplotlib.text`) and images
- (:mod:`matplotlib.image`) only
- """
- return True
-
- def get_canvas_width_height(self):
- 'return the canvas width and height in display coords'
- return 1, 1
-
- def get_texmanager(self):
- """
- return the :class:`matplotlib.texmanager.TexManager` instance
- """
- if self._texmanager is None:
- from matplotlib.texmanager import TexManager
- self._texmanager = TexManager()
- return self._texmanager
-
- def new_gc(self):
- """
- Return an instance of a :class:`GraphicsContextBase`
- """
- return GraphicsContextBase()
-
- def points_to_pixels(self, points):
- """
- Convert points to display units
-
- You need to override this function (unless your backend
- doesn't have a dpi, e.g., postscript or svg). Some imaging
- systems assume some value for pixels per inch::
-
- points to pixels = points * pixels_per_inch/72.0 * dpi/72.0
-
- Parameters
- ----------
- points : scalar or array_like
- a float or a numpy array of float
-
- Returns
- -------
- Points converted to pixels
- """
- return points
-
- def strip_math(self, s):
- return cbook.strip_math(s)
-
- def start_rasterizing(self):
- """
- Used in MixedModeRenderer. Switch to the raster renderer.
- """
-
- def stop_rasterizing(self):
- """
- Used in MixedModeRenderer. Switch back to the vector renderer
- and draw the contents of the raster renderer as an image on
- the vector renderer.
- """
-
- def start_filter(self):
- """
- Used in AggRenderer. Switch to a temporary renderer for image
- filtering effects.
- """
-
- def stop_filter(self, filter_func):
- """
- Used in AggRenderer. Switch back to the original renderer.
- The contents of the temporary renderer is processed with the
- *filter_func* and is drawn on the original renderer as an
- image.
- """
-
-
-class GraphicsContextBase(object):
- """
- An abstract base class that provides color, line styles, etc...
- """
-
- def __init__(self):
- self._alpha = 1.0
- self._forced_alpha = False # if True, _alpha overrides A from RGBA
- self._antialiased = 1 # use 0,1 not True, False for extension code
- self._capstyle = 'butt'
- self._cliprect = None
- self._clippath = None
- self._dashes = None, None
- self._joinstyle = 'round'
- self._linestyle = 'solid'
- self._linewidth = 1
- self._rgb = (0.0, 0.0, 0.0, 1.0)
- self._hatch = None
- self._hatch_color = colors.to_rgba(rcParams['hatch.color'])
- self._hatch_linewidth = rcParams['hatch.linewidth']
- self._url = None
- self._gid = None
- self._snap = None
- self._sketch = None
-
- def copy_properties(self, gc):
- 'Copy properties from gc to self'
- self._alpha = gc._alpha
- self._forced_alpha = gc._forced_alpha
- self._antialiased = gc._antialiased
- self._capstyle = gc._capstyle
- self._cliprect = gc._cliprect
- self._clippath = gc._clippath
- self._dashes = gc._dashes
- self._joinstyle = gc._joinstyle
- self._linestyle = gc._linestyle
- self._linewidth = gc._linewidth
- self._rgb = gc._rgb
- self._hatch = gc._hatch
- self._hatch_color = gc._hatch_color
- self._hatch_linewidth = gc._hatch_linewidth
- self._url = gc._url
- self._gid = gc._gid
- self._snap = gc._snap
- self._sketch = gc._sketch
-
- def restore(self):
- """
- Restore the graphics context from the stack - needed only
- for backends that save graphics contexts on a stack
- """
-
- def get_alpha(self):
- """
- Return the alpha value used for blending - not supported on
- all backends
- """
- return self._alpha
-
- def get_antialiased(self):
- "Return true if the object should try to do antialiased rendering"
- return self._antialiased
-
- def get_capstyle(self):
- """
- Return the capstyle as a string in ('butt', 'round', 'projecting')
- """
- return self._capstyle
-
- def get_clip_rectangle(self):
- """
- Return the clip rectangle as a :class:`~matplotlib.transforms.Bbox`
- instance
- """
- return self._cliprect
-
- def get_clip_path(self):
- """
- Return the clip path in the form (path, transform), where path
- is a :class:`~matplotlib.path.Path` instance, and transform is
- an affine transform to apply to the path before clipping.
- """
- if self._clippath is not None:
- return self._clippath.get_transformed_path_and_affine()
- return None, None
-
- def get_dashes(self):
- """
- Return the dash information as an offset dashlist tuple.
-
- The dash list is a even size list that gives the ink on, ink
- off in pixels.
-
- See p107 of to PostScript `BLUEBOOK
- <https://www-cdf.fnal.gov/offline/PostScript/BLUEBOOK.PDF>`_
- for more info.
-
- Default value is None
- """
- return self._dashes
-
- def get_forced_alpha(self):
- """
- Return whether the value given by get_alpha() should be used to
- override any other alpha-channel values.
- """
- return self._forced_alpha
-
- def get_joinstyle(self):
- """
- Return the line join style as one of ('miter', 'round', 'bevel')
- """
- return self._joinstyle
-
- @cbook.deprecated("2.1")
- def get_linestyle(self):
- """
- Return the linestyle: one of ('solid', 'dashed', 'dashdot',
- 'dotted').
- """
- return self._linestyle
-
- def get_linewidth(self):
- """
- Return the line width in points as a scalar
- """
- return self._linewidth
-
- def get_rgb(self):
- """
- returns a tuple of three or four floats from 0-1.
- """
- return self._rgb
-
- def get_url(self):
- """
- returns a url if one is set, None otherwise
- """
- return self._url
-
- def get_gid(self):
- """
- Return the object identifier if one is set, None otherwise.
- """
- return self._gid
-
- def get_snap(self):
- """
- returns the snap setting which may be:
-
- * True: snap vertices to the nearest pixel center
-
- * False: leave vertices as-is
-
- * None: (auto) If the path contains only rectilinear line
- segments, round to the nearest pixel center
- """
- return self._snap
-
- def set_alpha(self, alpha):
- """
- Set the alpha value used for blending - not supported on all backends.
- If ``alpha=None`` (the default), the alpha components of the
- foreground and fill colors will be used to set their respective
- transparencies (where applicable); otherwise, ``alpha`` will override
- them.
- """
- if alpha is not None:
- self._alpha = alpha
- self._forced_alpha = True
- else:
- self._alpha = 1.0
- self._forced_alpha = False
- self.set_foreground(self._rgb, isRGBA=True)
-
- def set_antialiased(self, b):
- """
- True if object should be drawn with antialiased rendering
- """
-
- # use 0, 1 to make life easier on extension code trying to read the gc
- if b:
- self._antialiased = 1
- else:
- self._antialiased = 0
-
- def set_capstyle(self, cs):
- """
- Set the capstyle as a string in ('butt', 'round', 'projecting')
- """
- if cs in ('butt', 'round', 'projecting'):
- self._capstyle = cs
- else:
- raise ValueError('Unrecognized cap style. Found %s' % cs)
-
- def set_clip_rectangle(self, rectangle):
- """
- Set the clip rectangle with sequence (left, bottom, width, height)
- """
- self._cliprect = rectangle
-
- def set_clip_path(self, path):
- """
- Set the clip path and transformation. Path should be a
- :class:`~matplotlib.transforms.TransformedPath` instance.
- """
- if (path is not None
- and not isinstance(path, transforms.TransformedPath)):
- raise ValueError("Path should be a "
- "matplotlib.transforms.TransformedPath instance")
- self._clippath = path
-
- def set_dashes(self, dash_offset, dash_list):
- """
- Set the dash style for the gc.
-
- Parameters
- ----------
- dash_offset : float
- is the offset (usually 0).
-
- dash_list : array_like
- specifies the on-off sequence as points.
- ``(None, None)`` specifies a solid line
-
- """
- if dash_list is not None:
- dl = np.asarray(dash_list)
- if np.any(dl < 0.0):
- raise ValueError(
- "All values in the dash list must be positive")
- self._dashes = dash_offset, dash_list
-
- def set_foreground(self, fg, isRGBA=False):
- """
- Set the foreground color. fg can be a MATLAB format string, a
- html hex color string, an rgb or rgba unit tuple, or a float between 0
- and 1. In the latter case, grayscale is used.
-
- If you know fg is rgba, set ``isRGBA=True`` for efficiency.
- """
- if self._forced_alpha and isRGBA:
- self._rgb = fg[:3] + (self._alpha,)
- elif self._forced_alpha:
- self._rgb = colors.to_rgba(fg, self._alpha)
- elif isRGBA:
- self._rgb = fg
- else:
- self._rgb = colors.to_rgba(fg)
-
- def set_joinstyle(self, js):
- """
- Set the join style to be one of ('miter', 'round', 'bevel')
- """
- if js in ('miter', 'round', 'bevel'):
- self._joinstyle = js
- else:
- raise ValueError('Unrecognized join style. Found %s' % js)
-
- def set_linewidth(self, w):
- """
- Set the linewidth in points
- """
- self._linewidth = float(w)
-
- @cbook.deprecated("2.1")
- def set_linestyle(self, style):
- """
- Set the linestyle to be one of ('solid', 'dashed', 'dashdot',
- 'dotted'). These are defined in the rcParams
- `lines.dashed_pattern`, `lines.dashdot_pattern` and
- `lines.dotted_pattern`. One may also specify customized dash
- styles by providing a tuple of (offset, dash pairs).
- """
- self._linestyle = style
-
- def set_url(self, url):
- """
- Sets the url for links in compatible backends
- """
- self._url = url
-
- def set_gid(self, id):
- """
- Sets the id.
- """
- self._gid = id
-
- def set_snap(self, snap):
- """
- Sets the snap setting which may be:
-
- * True: snap vertices to the nearest pixel center
-
- * False: leave vertices as-is
-
- * None: (auto) If the path contains only rectilinear line
- segments, round to the nearest pixel center
- """
- self._snap = snap
-
- def set_hatch(self, hatch):
- """
- Sets the hatch style for filling
- """
- self._hatch = hatch
-
- def get_hatch(self):
- """
- Gets the current hatch style
- """
- return self._hatch
-
- def get_hatch_path(self, density=6.0):
- """
- Returns a Path for the current hatch.
- """
- hatch = self.get_hatch()
- if hatch is None:
- return None
- return Path.hatch(hatch, density)
-
- def get_hatch_color(self):
- """
- Gets the color to use for hatching.
- """
- return self._hatch_color
-
- def set_hatch_color(self, hatch_color):
- """
- sets the color to use for hatching.
- """
- self._hatch_color = hatch_color
-
- def get_hatch_linewidth(self):
- """
- Gets the linewidth to use for hatching.
- """
- return self._hatch_linewidth
-
- def get_sketch_params(self):
- """
- Returns the sketch parameters for the artist.
-
- Returns
- -------
- sketch_params : tuple or `None`
-
- A 3-tuple with the following elements:
-
- * `scale`: The amplitude of the wiggle perpendicular to the
- source line.
-
- * `length`: The length of the wiggle along the line.
-
- * `randomness`: The scale factor by which the length is
- shrunken or expanded.
-
- May return `None` if no sketch parameters were set.
- """
- return self._sketch
-
- def set_sketch_params(self, scale=None, length=None, randomness=None):
- """
- Sets the sketch parameters.
-
- Parameters
- ----------
-
- scale : float, optional
- The amplitude of the wiggle perpendicular to the source
- line, in pixels. If scale is `None`, or not provided, no
- sketch filter will be provided.
-
- length : float, optional
- The length of the wiggle along the line, in pixels
- (default 128)
-
- randomness : float, optional
- The scale factor by which the length is shrunken or
- expanded (default 16)
- """
- self._sketch = (
- None if scale is None
- else (scale, length or 128., randomness or 16.))
-
-
-class TimerBase(object):
- '''
- A base class for providing timer events, useful for things animations.
- Backends need to implement a few specific methods in order to use their
- own timing mechanisms so that the timer events are integrated into their
- event loops.
-
- Mandatory functions that must be implemented:
-
- * `_timer_start`: Contains backend-specific code for starting
- the timer
-
- * `_timer_stop`: Contains backend-specific code for stopping
- the timer
-
- Optional overrides:
-
- * `_timer_set_single_shot`: Code for setting the timer to
- single shot operating mode, if supported by the timer
- object. If not, the `Timer` class itself will store the flag
- and the `_on_timer` method should be overridden to support
- such behavior.
-
- * `_timer_set_interval`: Code for setting the interval on the
- timer, if there is a method for doing so on the timer
- object.
-
- * `_on_timer`: This is the internal function that any timer
- object should call, which will handle the task of running
- all callbacks that have been set.
-
- Attributes
- ----------
- interval : scalar
- The time between timer events in milliseconds. Default is 1000 ms.
-
- single_shot : bool
- Boolean flag indicating whether this timer should operate as single
- shot (run once and then stop). Defaults to `False`.
-
- callbacks : List[Tuple[callable, Tuple, Dict]]
- Stores list of (func, args, kwargs) tuples that will be called upon
- timer events. This list can be manipulated directly, or the
- functions `add_callback` and `remove_callback` can be used.
-
- '''
- def __init__(self, interval=None, callbacks=None):
- #Initialize empty callbacks list and setup default settings if necssary
- if callbacks is None:
- self.callbacks = []
- else:
- self.callbacks = callbacks[:] # Create a copy
-
- if interval is None:
- self._interval = 1000
- else:
- self._interval = interval
-
- self._single = False
-
- # Default attribute for holding the GUI-specific timer object
- self._timer = None
-
- def __del__(self):
- 'Need to stop timer and possibly disconnect timer.'
- self._timer_stop()
-
- def start(self, interval=None):
- '''
- Start the timer object. `interval` is optional and will be used
- to reset the timer interval first if provided.
- '''
- if interval is not None:
- self._set_interval(interval)
- self._timer_start()
-
- def stop(self):
- '''
- Stop the timer.
- '''
- self._timer_stop()
-
- def _timer_start(self):
- pass
-
- def _timer_stop(self):
- pass
-
- def _get_interval(self):
- return self._interval
-
- def _set_interval(self, interval):
- # Force to int since none of the backends actually support fractional
- # milliseconds, and some error or give warnings.
- interval = int(interval)
- self._interval = interval
- self._timer_set_interval()
-
- interval = property(_get_interval, _set_interval)
-
- def _get_single_shot(self):
- return self._single
-
- def _set_single_shot(self, ss=True):
- self._single = ss
- self._timer_set_single_shot()
-
- single_shot = property(_get_single_shot, _set_single_shot)
-
- def add_callback(self, func, *args, **kwargs):
- '''
- Register `func` to be called by timer when the event fires. Any
- additional arguments provided will be passed to `func`.
- '''
- self.callbacks.append((func, args, kwargs))
-
- def remove_callback(self, func, *args, **kwargs):
- '''
- Remove `func` from list of callbacks. `args` and `kwargs` are optional
- and used to distinguish between copies of the same function registered
- to be called with different arguments.
- '''
- if args or kwargs:
- self.callbacks.remove((func, args, kwargs))
- else:
- funcs = [c[0] for c in self.callbacks]
- if func in funcs:
- self.callbacks.pop(funcs.index(func))
-
- def _timer_set_interval(self):
- """Used to set interval on underlying timer object."""
-
- def _timer_set_single_shot(self):
- """Used to set single shot on underlying timer object."""
-
- def _on_timer(self):
- '''
- Runs all function that have been registered as callbacks. Functions
- can return False (or 0) if they should not be called any more. If there
- are no callbacks, the timer is automatically stopped.
- '''
- for func, args, kwargs in self.callbacks:
- ret = func(*args, **kwargs)
- # docstring above explains why we use `if ret == 0` here,
- # instead of `if not ret`.
- # This will also catch `ret == False` as `False == 0`
- # but does not annoy the linters
- # https://docs.python.org/3/library/stdtypes.html#boolean-values
- if ret == 0:
- self.callbacks.remove((func, args, kwargs))
-
- if len(self.callbacks) == 0:
- self.stop()
-
-
-class Event(object):
- """
- A matplotlib event. Attach additional attributes as defined in
- :meth:`FigureCanvasBase.mpl_connect`. The following attributes
- are defined and shown with their default values
-
- Attributes
- ----------
- name : str
- the event name
-
- canvas : `FigureCanvasBase`
- the backend-specific canvas instance generating the event
-
- guiEvent
- the GUI event that triggered the matplotlib event
-
- """
- def __init__(self, name, canvas, guiEvent=None):
- self.name = name
- self.canvas = canvas
- self.guiEvent = guiEvent
-
-
-@cbook.deprecated("2.1")
-class IdleEvent(Event):
- """
- An event triggered by the GUI backend when it is idle -- useful
- for passive animation
- """
-
-
-class DrawEvent(Event):
- """
- An event triggered by a draw operation on the canvas
-
- In most backends callbacks subscribed to this callback will be
- fired after the rendering is complete but before the screen is
- updated. Any extra artists drawn to the canvas's renderer will
- be reflected without an explicit call to ``blit``.
-
- .. warning ::
-
- Calling ``canvas.draw`` and ``canvas.blit`` in these callbacks may
- not be safe with all backends and may cause infinite recursion.
-
- In addition to the :class:`Event` attributes, the following event
- attributes are defined:
-
- Attributes
- ----------
- renderer : `RendererBase`
- the renderer for the draw event
-
- """
- def __init__(self, name, canvas, renderer):
- Event.__init__(self, name, canvas)
- self.renderer = renderer
-
-
-class ResizeEvent(Event):
- """
- An event triggered by a canvas resize
-
- In addition to the :class:`Event` attributes, the following event
- attributes are defined:
-
- Attributes
- ----------
- width : scalar
- width of the canvas in pixels
-
- height : scalar
- height of the canvas in pixels
-
- """
- def __init__(self, name, canvas):
- Event.__init__(self, name, canvas)
- self.width, self.height = canvas.get_width_height()
-
-
-class CloseEvent(Event):
- """
- An event triggered by a figure being closed
-
- """
- def __init__(self, name, canvas, guiEvent=None):
- Event.__init__(self, name, canvas, guiEvent)
-
-
-class LocationEvent(Event):
- """
- An event that has a screen location
-
- The following additional attributes are defined and shown with
- their default values.
-
- In addition to the :class:`Event` attributes, the following
- event attributes are defined:
-
- Attributes
- ----------
- x : scalar
- x position - pixels from left of canvas
-
- y : scalar
- y position - pixels from bottom of canvas
-
- inaxes : bool
- the :class:`~matplotlib.axes.Axes` instance if mouse is over axes
-
- xdata : scalar
- x coord of mouse in data coords
-
- ydata : scalar
- y coord of mouse in data coords
-
- """
- x = None # x position - pixels from left of canvas
- y = None # y position - pixels from right of canvas
- inaxes = None # the Axes instance if mouse us over axes
- xdata = None # x coord of mouse in data coords
- ydata = None # y coord of mouse in data coords
-
- # the last event that was triggered before this one
- lastevent = None
-
- def __init__(self, name, canvas, x, y, guiEvent=None):
- """
- *x*, *y* in figure coords, 0,0 = bottom, left
- """
- Event.__init__(self, name, canvas, guiEvent=guiEvent)
- self.x = x
- self.y = y
-
- if x is None or y is None:
- # cannot check if event was in axes if no x,y info
- self.inaxes = None
- self._update_enter_leave()
- return
-
- # Find all axes containing the mouse
- if self.canvas.mouse_grabber is None:
- axes_list = [a for a in self.canvas.figure.get_axes()
- if a.in_axes(self)]
- else:
- axes_list = [self.canvas.mouse_grabber]
-
- if axes_list:
- self.inaxes = cbook._topmost_artist(axes_list)
- try:
- trans = self.inaxes.transData.inverted()
- xdata, ydata = trans.transform_point((x, y))
- except ValueError:
- self.xdata = None
- self.ydata = None
- else:
- self.xdata = xdata
- self.ydata = ydata
- else:
- self.inaxes = None
-
- self._update_enter_leave()
-
- def _update_enter_leave(self):
- 'process the figure/axes enter leave events'
- if LocationEvent.lastevent is not None:
- last = LocationEvent.lastevent
- if last.inaxes != self.inaxes:
- # process axes enter/leave events
- try:
- if last.inaxes is not None:
- last.canvas.callbacks.process('axes_leave_event', last)
- except:
- pass
- # See ticket 2901582.
- # I think this is a valid exception to the rule
- # against catching all exceptions; if anything goes
- # wrong, we simply want to move on and process the
- # current event.
- if self.inaxes is not None:
- self.canvas.callbacks.process('axes_enter_event', self)
-
- else:
- # process a figure enter event
- if self.inaxes is not None:
- self.canvas.callbacks.process('axes_enter_event', self)
-
- LocationEvent.lastevent = self
-
-
-class MouseEvent(LocationEvent):
- """
- A mouse event ('button_press_event',
- 'button_release_event',
- 'scroll_event',
- 'motion_notify_event').
-
- In addition to the :class:`Event` and :class:`LocationEvent`
- attributes, the following attributes are defined:
-
- Attributes
- ----------
- button : None, scalar, or str
- button pressed None, 1, 2, 3, 'up', 'down' (up and down are used
- for scroll events). Note that in the nbagg backend, both the
- middle and right clicks return 3 since right clicking will bring
- up the context menu in some browsers.
-
- key : None, or str
- the key depressed when the mouse event triggered (see
- :class:`KeyEvent`)
-
- step : scalar
- number of scroll steps (positive for 'up', negative for 'down')
-
- Examples
- --------
- Usage::
-
- def on_press(event):
- print('you pressed', event.button, event.xdata, event.ydata)
-
- cid = fig.canvas.mpl_connect('button_press_event', on_press)
-
- """
- x = None # x position - pixels from left of canvas
- y = None # y position - pixels from right of canvas
- button = None # button pressed None, 1, 2, 3
- dblclick = None # whether or not the event is the result of a double click
- inaxes = None # the Axes instance if mouse us over axes
- xdata = None # x coord of mouse in data coords
- ydata = None # y coord of mouse in data coords
- step = None # scroll steps for scroll events
-
- def __init__(self, name, canvas, x, y, button=None, key=None,
- step=0, dblclick=False, guiEvent=None):
- """
- x, y in figure coords, 0,0 = bottom, left
- button pressed None, 1, 2, 3, 'up', 'down'
- """
- LocationEvent.__init__(self, name, canvas, x, y, guiEvent=guiEvent)
- self.button = button
- self.key = key
- self.step = step
- self.dblclick = dblclick
-
- def __str__(self):
- return ("MPL MouseEvent: xy=(%d,%d) xydata=(%s,%s) button=%s " +
- "dblclick=%s inaxes=%s") % (self.x, self.y, self.xdata,
- self.ydata, self.button,
- self.dblclick, self.inaxes)
-
-
-class PickEvent(Event):
- """
- a pick event, fired when the user picks a location on the canvas
- sufficiently close to an artist.
-
- Attrs: all the :class:`Event` attributes plus
-
- Attributes
- ----------
- mouseevent : `MouseEvent`
- the mouse event that generated the pick
-
- artist : `matplotlib.artist.Artist`
- the picked artist
-
- other
- extra class dependent attrs -- e.g., a
- :class:`~matplotlib.lines.Line2D` pick may define different
- extra attributes than a
- :class:`~matplotlib.collections.PatchCollection` pick event
-
- Examples
- --------
- Usage::
-
- ax.plot(np.rand(100), 'o', picker=5) # 5 points tolerance
-
- def on_pick(event):
- line = event.artist
- xdata, ydata = line.get_data()
- ind = event.ind
- print('on pick line:', np.array([xdata[ind], ydata[ind]]).T)
-
- cid = fig.canvas.mpl_connect('pick_event', on_pick)
-
- """
- def __init__(self, name, canvas, mouseevent, artist,
- guiEvent=None, **kwargs):
- Event.__init__(self, name, canvas, guiEvent)
- self.mouseevent = mouseevent
- self.artist = artist
- self.__dict__.update(kwargs)
-
-
-class KeyEvent(LocationEvent):
- """
- A key event (key press, key release).
-
- Attach additional attributes as defined in
- :meth:`FigureCanvasBase.mpl_connect`.
-
- In addition to the :class:`Event` and :class:`LocationEvent`
- attributes, the following attributes are defined:
-
- Attributes
- ----------
- key : None or str
- the key(s) pressed. Could be **None**, a single case sensitive ascii
- character ("g", "G", "#", etc.), a special key
- ("control", "shift", "f1", "up", etc.) or a
- combination of the above (e.g., "ctrl+alt+g", "ctrl+alt+G").
-
- Notes
- -----
- Modifier keys will be prefixed to the pressed key and will be in the order
- "ctrl", "alt", "super". The exception to this rule is when the pressed key
- is itself a modifier key, therefore "ctrl+alt" and "alt+control" can both
- be valid key values.
-
- Examples
- --------
- Usage::
-
- def on_key(event):
- print('you pressed', event.key, event.xdata, event.ydata)
-
- cid = fig.canvas.mpl_connect('key_press_event', on_key)
-
- """
- def __init__(self, name, canvas, key, x=0, y=0, guiEvent=None):
- LocationEvent.__init__(self, name, canvas, x, y, guiEvent=guiEvent)
- self.key = key
-
-
-class FigureCanvasBase(object):
- """
- The canvas the figure renders into.
-
- Public attributes
-
- Attributes
- ----------
- figure : `matplotlib.figure.Figure`
- A high-level figure instance
-
- """
- events = [
- 'resize_event',
- 'draw_event',
- 'key_press_event',
- 'key_release_event',
- 'button_press_event',
- 'button_release_event',
- 'scroll_event',
- 'motion_notify_event',
- 'pick_event',
- 'idle_event',
- 'figure_enter_event',
- 'figure_leave_event',
- 'axes_enter_event',
- 'axes_leave_event',
- 'close_event'
- ]
-
- supports_blit = True
- fixed_dpi = None
-
- filetypes = _default_filetypes
- if _has_pil:
- # JPEG support
- register_backend('jpg', 'matplotlib.backends.backend_agg',
- 'Joint Photographic Experts Group')
- register_backend('jpeg', 'matplotlib.backends.backend_agg',
- 'Joint Photographic Experts Group')
- # TIFF support
- register_backend('tif', 'matplotlib.backends.backend_agg',
- 'Tagged Image File Format')
- register_backend('tiff', 'matplotlib.backends.backend_agg',
- 'Tagged Image File Format')
-
- def __init__(self, figure):
- self._is_idle_drawing = True
- self._is_saving = False
- figure.set_canvas(self)
- self.figure = figure
- # a dictionary from event name to a dictionary that maps cid->func
- self.callbacks = cbook.CallbackRegistry()
- self.widgetlock = widgets.LockDraw()
- self._button = None # the button pressed
- self._key = None # the key pressed
- self._lastx, self._lasty = None, None
- self.button_pick_id = self.mpl_connect('button_press_event', self.pick)
- self.scroll_pick_id = self.mpl_connect('scroll_event', self.pick)
- self.mouse_grabber = None # the axes currently grabbing mouse
- self.toolbar = None # NavigationToolbar2 will set me
- self._is_idle_drawing = False
-
- @contextmanager
- def _idle_draw_cntx(self):
- self._is_idle_drawing = True
- yield
- self._is_idle_drawing = False
-
- def is_saving(self):
- """
- Returns whether the renderer is in the process of saving
- to a file, rather than rendering for an on-screen buffer.
- """
- return self._is_saving
-
- @cbook.deprecated("2.2")
- def onRemove(self, ev):
- """
- Mouse event processor which removes the top artist
- under the cursor. Connect this to the 'mouse_press_event'
- using::
-
- canvas.mpl_connect('mouse_press_event',canvas.onRemove)
- """
- # Find the top artist under the cursor
- under = cbook._topmost_artist(self.figure.hitlist(ev))
- h = None
- if under:
- h = under[-1]
-
- # Try deleting that artist, or its parent if you
- # can't delete the artist
- while h:
- if h.remove():
- self.draw_idle()
- break
- parent = None
- for p in under:
- if h in p.get_children():
- parent = p
- break
- h = parent
-
- def pick(self, mouseevent):
- if not self.widgetlock.locked():
- self.figure.pick(mouseevent)
-
- def blit(self, bbox=None):
- """Blit the canvas in bbox (default entire canvas)."""
-
- def resize(self, w, h):
- """Set the canvas size in pixels."""
-
- def draw_event(self, renderer):
- """Pass a `DrawEvent` to all functions connected to ``draw_event``."""
- s = 'draw_event'
- event = DrawEvent(s, self, renderer)
- self.callbacks.process(s, event)
-
- def resize_event(self):
- """Pass a `ResizeEvent` to all functions connected to ``resize_event``.
- """
- s = 'resize_event'
- event = ResizeEvent(s, self)
- self.callbacks.process(s, event)
- self.draw_idle()
-
- def close_event(self, guiEvent=None):
- """Pass a `CloseEvent` to all functions connected to ``close_event``.
- """
- s = 'close_event'
- try:
- event = CloseEvent(s, self, guiEvent=guiEvent)
- self.callbacks.process(s, event)
- except (TypeError, AttributeError):
- pass
- # Suppress the TypeError when the python session is being killed.
- # It may be that a better solution would be a mechanism to
- # disconnect all callbacks upon shutdown.
- # AttributeError occurs on OSX with qt4agg upon exiting
- # with an open window; 'callbacks' attribute no longer exists.
-
- def key_press_event(self, key, guiEvent=None):
- """Pass a `KeyEvent` to all functions connected to ``key_press_event``.
- """
- self._key = key
- s = 'key_press_event'
- event = KeyEvent(
- s, self, key, self._lastx, self._lasty, guiEvent=guiEvent)
- self.callbacks.process(s, event)
-
- def key_release_event(self, key, guiEvent=None):
- """
- Pass a `KeyEvent` to all functions connected to ``key_release_event``.
- """
- s = 'key_release_event'
- event = KeyEvent(
- s, self, key, self._lastx, self._lasty, guiEvent=guiEvent)
- self.callbacks.process(s, event)
- self._key = None
-
- def pick_event(self, mouseevent, artist, **kwargs):
- """
- This method will be called by artists who are picked and will
- fire off :class:`PickEvent` callbacks registered listeners
- """
- s = 'pick_event'
- event = PickEvent(s, self, mouseevent, artist,
- guiEvent=mouseevent.guiEvent,
- **kwargs)
- self.callbacks.process(s, event)
-
- def scroll_event(self, x, y, step, guiEvent=None):
- """
- Backend derived classes should call this function on any
- scroll wheel event. x,y are the canvas coords: 0,0 is lower,
- left. button and key are as defined in MouseEvent.
-
- This method will be call all functions connected to the
- 'scroll_event' with a :class:`MouseEvent` instance.
- """
- if step >= 0:
- self._button = 'up'
- else:
- self._button = 'down'
- s = 'scroll_event'
- mouseevent = MouseEvent(s, self, x, y, self._button, self._key,
- step=step, guiEvent=guiEvent)
- self.callbacks.process(s, mouseevent)
-
- def button_press_event(self, x, y, button, dblclick=False, guiEvent=None):
- """
- Backend derived classes should call this function on any mouse
- button press. x,y are the canvas coords: 0,0 is lower, left.
- button and key are as defined in :class:`MouseEvent`.
-
- This method will be call all functions connected to the
- 'button_press_event' with a :class:`MouseEvent` instance.
- """
- self._button = button
- s = 'button_press_event'
- mouseevent = MouseEvent(s, self, x, y, button, self._key,
- dblclick=dblclick, guiEvent=guiEvent)
- self.callbacks.process(s, mouseevent)
-
- def button_release_event(self, x, y, button, guiEvent=None):
- """
- Backend derived classes should call this function on any mouse
- button release.
-
- This method will call all functions connected to the
- 'button_release_event' with a :class:`MouseEvent` instance.
-
- Parameters
- ----------
- x : scalar
- the canvas coordinates where 0=left
-
- y : scalar
- the canvas coordinates where 0=bottom
-
- guiEvent
- the native UI event that generated the mpl event
-
- """
- s = 'button_release_event'
- event = MouseEvent(s, self, x, y, button, self._key, guiEvent=guiEvent)
- self.callbacks.process(s, event)
- self._button = None
-
- def motion_notify_event(self, x, y, guiEvent=None):
- """
- Backend derived classes should call this function on any
- motion-notify-event.
-
- This method will call all functions connected to the
- 'motion_notify_event' with a :class:`MouseEvent` instance.
-
- Parameters
- ----------
- x : scalar
- the canvas coordinates where 0=left
-
- y : scalar
- the canvas coordinates where 0=bottom
-
- guiEvent
- the native UI event that generated the mpl event
-
- """
- self._lastx, self._lasty = x, y
- s = 'motion_notify_event'
- event = MouseEvent(s, self, x, y, self._button, self._key,
- guiEvent=guiEvent)
- self.callbacks.process(s, event)
-
- def leave_notify_event(self, guiEvent=None):
- """
- Backend derived classes should call this function when leaving
- canvas
-
- Parameters
- ----------
- guiEvent
- the native UI event that generated the mpl event
-
- """
-
- self.callbacks.process('figure_leave_event', LocationEvent.lastevent)
- LocationEvent.lastevent = None
- self._lastx, self._lasty = None, None
-
- def enter_notify_event(self, guiEvent=None, xy=None):
- """
- Backend derived classes should call this function when entering
- canvas
-
- Parameters
- ----------
- guiEvent
- the native UI event that generated the mpl event
- xy : tuple of 2 scalars
- the coordinate location of the pointer when the canvas is
- entered
-
- """
- if xy is not None:
- x, y = xy
- self._lastx, self._lasty = x, y
-
- event = Event('figure_enter_event', self, guiEvent)
- self.callbacks.process('figure_enter_event', event)
-
- @cbook.deprecated("2.1")
- def idle_event(self, guiEvent=None):
- """Called when GUI is idle."""
- s = 'idle_event'
- event = IdleEvent(s, self, guiEvent=guiEvent)
- self.callbacks.process(s, event)
-
- def grab_mouse(self, ax):
- """
- Set the child axes which are currently grabbing the mouse events.
- Usually called by the widgets themselves.
- It is an error to call this if the mouse is already grabbed by
- another axes.
- """
- if self.mouse_grabber not in (None, ax):
- raise RuntimeError("Another Axes already grabs mouse input")
- self.mouse_grabber = ax
-
- def release_mouse(self, ax):
- """
- Release the mouse grab held by the axes, ax.
- Usually called by the widgets.
- It is ok to call this even if you ax doesn't have the mouse
- grab currently.
- """
- if self.mouse_grabber is ax:
- self.mouse_grabber = None
-
- def draw(self, *args, **kwargs):
- """Render the :class:`~matplotlib.figure.Figure`."""
-
- def draw_idle(self, *args, **kwargs):
- """
- :meth:`draw` only if idle; defaults to draw but backends can override
- """
- if not self._is_idle_drawing:
- with self._idle_draw_cntx():
- self.draw(*args, **kwargs)
-
- def draw_cursor(self, event):
- """
- Draw a cursor in the event.axes if inaxes is not None. Use
- native GUI drawing for efficiency if possible
- """
-
- def get_width_height(self):
- """
- Return the figure width and height in points or pixels
- (depending on the backend), truncated to integers
- """
- return int(self.figure.bbox.width), int(self.figure.bbox.height)
-
- @classmethod
- def get_supported_filetypes(cls):
- """Return dict of savefig file formats supported by this backend"""
- return cls.filetypes
-
- @classmethod
- def get_supported_filetypes_grouped(cls):
- """Return a dict of savefig file formats supported by this backend,
- where the keys are a file type name, such as 'Joint Photographic
- Experts Group', and the values are a list of filename extensions used
- for that filetype, such as ['jpg', 'jpeg']."""
- groupings = {}
- for ext, name in six.iteritems(cls.filetypes):
- groupings.setdefault(name, []).append(ext)
- groupings[name].sort()
- return groupings
-
- def _get_output_canvas(self, fmt):
- """
- Return a canvas suitable for saving figures to a specified file format.
-
- If necessary, this function will switch to a registered backend that
- supports the format.
- """
- method_name = 'print_%s' % fmt
- # Return the current canvas if it supports the requested format.
- if hasattr(self, method_name):
- return self
- # Return a default canvas for the requested format, if it exists.
- canvas_class = get_registered_canvas_class(fmt)
- if canvas_class:
- return self.switch_backends(canvas_class)
- # Else report error for unsupported format.
- raise ValueError(
- "Format {!r} is not supported (supported formats: {})"
- .format(fmt, ", ".join(sorted(self.get_supported_filetypes()))))
-
- def print_figure(self, filename, dpi=None, facecolor=None, edgecolor=None,
- orientation='portrait', format=None, **kwargs):
- """
- Render the figure to hardcopy. Set the figure patch face and edge
- colors. This is useful because some of the GUIs have a gray figure
- face color background and you'll probably want to override this on
- hardcopy.
-
- Parameters
- ----------
- filename
- can also be a file object on image backends
-
- orientation : {'landscape', 'portrait'}, optional
- only currently applies to PostScript printing.
-
- dpi : scalar, optional
- the dots per inch to save the figure in; if None, use savefig.dpi
-
- facecolor : color spec or None, optional
- the facecolor of the figure; if None, defaults to savefig.facecolor
-
- edgecolor : color spec or None, optional
- the edgecolor of the figure; if None, defaults to savefig.edgecolor
-
- format : str, optional
- when set, forcibly set the file format to save to
-
- bbox_inches : str or `~matplotlib.transforms.Bbox`, optional
- Bbox in inches. Only the given portion of the figure is
- saved. If 'tight', try to figure out the tight bbox of
- the figure. If None, use savefig.bbox
-
- pad_inches : scalar, optional
- Amount of padding around the figure when bbox_inches is
- 'tight'. If None, use savefig.pad_inches
-
- bbox_extra_artists : list of `~matplotlib.artist.Artist`, optional
- A list of extra artists that will be considered when the
- tight bbox is calculated.
-
- """
- self._is_saving = True
- # Remove the figure manager, if any, to avoid resizing the GUI widget.
- # Having *no* manager and a *None* manager are currently different (see
- # Figure.show); should probably be normalized to None at some point.
- _no_manager = object()
- if hasattr(self, 'manager'):
- manager = self.manager
- del self.manager
- else:
- manager = _no_manager
-
- if format is None:
- # get format from filename, or from backend's default filetype
- if isinstance(filename, getattr(os, "PathLike", ())):
- filename = os.fspath(filename)
- if isinstance(filename, six.string_types):
- format = os.path.splitext(filename)[1][1:]
- if format is None or format == '':
- format = self.get_default_filetype()
- if isinstance(filename, six.string_types):
- filename = filename.rstrip('.') + '.' + format
- format = format.lower()
-
- # get canvas object and print method for format
- canvas = self._get_output_canvas(format)
- print_method = getattr(canvas, 'print_%s' % format)
-
- if dpi is None:
- dpi = rcParams['savefig.dpi']
-
- if dpi == 'figure':
- dpi = getattr(self.figure, '_original_dpi', self.figure.dpi)
-
- if facecolor is None:
- facecolor = rcParams['savefig.facecolor']
- if edgecolor is None:
- edgecolor = rcParams['savefig.edgecolor']
-
- origDPI = self.figure.dpi
- origfacecolor = self.figure.get_facecolor()
- origedgecolor = self.figure.get_edgecolor()
-
- self.figure.dpi = dpi
- self.figure.set_facecolor(facecolor)
- self.figure.set_edgecolor(edgecolor)
-
- bbox_inches = kwargs.pop("bbox_inches", None)
- if bbox_inches is None:
- bbox_inches = rcParams['savefig.bbox']
-
- if bbox_inches:
- # call adjust_bbox to save only the given area
- if bbox_inches == "tight":
- # When bbox_inches == "tight", it saves the figure twice. The
- # first save command (to a BytesIO) is just to estimate the
- # bounding box of the figure.
- result = print_method(
- io.BytesIO(),
- dpi=dpi,
- facecolor=facecolor,
- edgecolor=edgecolor,
- orientation=orientation,
- dryrun=True,
- **kwargs)
- renderer = self.figure._cachedRenderer
- bbox_inches = self.figure.get_tightbbox(renderer)
-
- bbox_artists = kwargs.pop("bbox_extra_artists", None)
- if bbox_artists is None:
- bbox_artists = self.figure.get_default_bbox_extra_artists()
-
- bbox_filtered = []
- for a in bbox_artists:
- bbox = a.get_window_extent(renderer)
- if a.get_clip_on():
- clip_box = a.get_clip_box()
- if clip_box is not None:
- bbox = Bbox.intersection(bbox, clip_box)
- clip_path = a.get_clip_path()
- if clip_path is not None and bbox is not None:
- clip_path = clip_path.get_fully_transformed_path()
- bbox = Bbox.intersection(bbox,
- clip_path.get_extents())
- if bbox is not None and (bbox.width != 0 or
- bbox.height != 0):
- bbox_filtered.append(bbox)
-
- if bbox_filtered:
- _bbox = Bbox.union(bbox_filtered)
- trans = Affine2D().scale(1.0 / self.figure.dpi)
- bbox_extra = TransformedBbox(_bbox, trans)
- bbox_inches = Bbox.union([bbox_inches, bbox_extra])
-
- pad = kwargs.pop("pad_inches", None)
- if pad is None:
- pad = rcParams['savefig.pad_inches']
-
- bbox_inches = bbox_inches.padded(pad)
-
- restore_bbox = tight_bbox.adjust_bbox(self.figure, bbox_inches,
- canvas.fixed_dpi)
-
- _bbox_inches_restore = (bbox_inches, restore_bbox)
- else:
- _bbox_inches_restore = None
-
- try:
- result = print_method(
- filename,
- dpi=dpi,
- facecolor=facecolor,
- edgecolor=edgecolor,
- orientation=orientation,
- bbox_inches_restore=_bbox_inches_restore,
- **kwargs)
- finally:
- if bbox_inches and restore_bbox:
- restore_bbox()
-
- self.figure.dpi = origDPI
- self.figure.set_facecolor(origfacecolor)
- self.figure.set_edgecolor(origedgecolor)
- self.figure.set_canvas(self)
- if manager is not _no_manager:
- self.manager = manager
- self._is_saving = False
- return result
-
- @classmethod
- def get_default_filetype(cls):
- """
- Get the default savefig file format as specified in rcParam
- ``savefig.format``. Returned string excludes period. Overridden
- in backends that only support a single file type.
- """
- return rcParams['savefig.format']
-
- def get_window_title(self):
- """
- Get the title text of the window containing the figure.
- Return None if there is no window (e.g., a PS backend).
- """
- if hasattr(self, "manager"):
- return self.manager.get_window_title()
-
- def set_window_title(self, title):
- """
- Set the title text of the window containing the figure. Note that
- this has no effect if there is no window (e.g., a PS backend).
- """
- if hasattr(self, "manager"):
- self.manager.set_window_title(title)
-
- def get_default_filename(self):
- """
- Return a string, which includes extension, suitable for use as
- a default filename.
- """
- default_basename = self.get_window_title() or 'image'
- default_basename = default_basename.replace(' ', '_')
- default_filetype = self.get_default_filetype()
- default_filename = default_basename + '.' + default_filetype
-
- save_dir = os.path.expanduser(rcParams['savefig.directory'])
-
- # ensure non-existing filename in save dir
- i = 1
- while os.path.isfile(os.path.join(save_dir, default_filename)):
- # attach numerical count to basename
- default_filename = (
- '{}-{}.{}'.format(default_basename, i, default_filetype))
- i += 1
-
- return default_filename
-
- def switch_backends(self, FigureCanvasClass):
- """
- Instantiate an instance of FigureCanvasClass
-
- This is used for backend switching, e.g., to instantiate a
- FigureCanvasPS from a FigureCanvasGTK. Note, deep copying is
- not done, so any changes to one of the instances (e.g., setting
- figure size or line props), will be reflected in the other
- """
- newCanvas = FigureCanvasClass(self.figure)
- newCanvas._is_saving = self._is_saving
- return newCanvas
-
- def mpl_connect(self, s, func):
- """
- Connect event with string *s* to *func*. The signature of *func* is::
-
- def func(event)
-
- where event is a :class:`matplotlib.backend_bases.Event`. The
- following events are recognized
-
- - 'button_press_event'
- - 'button_release_event'
- - 'draw_event'
- - 'key_press_event'
- - 'key_release_event'
- - 'motion_notify_event'
- - 'pick_event'
- - 'resize_event'
- - 'scroll_event'
- - 'figure_enter_event',
- - 'figure_leave_event',
- - 'axes_enter_event',
- - 'axes_leave_event'
- - 'close_event'
-
- For the location events (button and key press/release), if the
- mouse is over the axes, the variable ``event.inaxes`` will be
- set to the :class:`~matplotlib.axes.Axes` the event occurs is
- over, and additionally, the variables ``event.xdata`` and
- ``event.ydata`` will be defined. This is the mouse location
- in data coords. See
- :class:`~matplotlib.backend_bases.KeyEvent` and
- :class:`~matplotlib.backend_bases.MouseEvent` for more info.
-
- Return value is a connection id that can be used with
- :meth:`~matplotlib.backend_bases.Event.mpl_disconnect`.
-
- Examples
- --------
- Usage::
-
- def on_press(event):
- print('you pressed', event.button, event.xdata, event.ydata)
-
- cid = canvas.mpl_connect('button_press_event', on_press)
-
- """
- if s == 'idle_event':
- cbook.warn_deprecated(1.5,
- "idle_event is only implemented for the wx backend, and will "
- "be removed in matplotlib 2.1. Use the animations module "
- "instead.")
-
- return self.callbacks.connect(s, func)
-
- def mpl_disconnect(self, cid):
- """
- Disconnect callback id cid
-
- Examples
- --------
- Usage::
-
- cid = canvas.mpl_connect('button_press_event', on_press)
- #...later
- canvas.mpl_disconnect(cid)
- """
- return self.callbacks.disconnect(cid)
-
- def new_timer(self, *args, **kwargs):
- """
- Creates a new backend-specific subclass of
- :class:`backend_bases.Timer`. This is useful for getting periodic
- events through the backend's native event loop. Implemented only for
- backends with GUIs.
-
- Other Parameters
- ----------------
- interval : scalar
- Timer interval in milliseconds
-
- callbacks : List[Tuple[callable, Tuple, Dict]]
- Sequence of (func, args, kwargs) where ``func(*args, **kwargs)``
- will be executed by the timer every *interval*.
-
- callbacks which return ``False`` or ``0`` will be removed from the
- timer.
-
- Examples
- --------
-
- >>> timer = fig.canvas.new_timer(callbacks=[(f1, (1, ), {'a': 3}),])
-
- """
- return TimerBase(*args, **kwargs)
-
- def flush_events(self):
- """Flush the GUI events for the figure.
-
- Interactive backends need to reimplement this method.
- """
-
- def start_event_loop(self, timeout=0):
- """Start a blocking event loop.
-
- Such an event loop is used by interactive functions, such as `ginput`
- and `waitforbuttonpress`, to wait for events.
-
- The event loop blocks until a callback function triggers
- `stop_event_loop`, or *timeout* is reached.
-
- If *timeout* is negative, never timeout.
-
- Only interactive backends need to reimplement this method and it relies
- on `flush_events` being properly implemented.
-
- Interactive backends should implement this in a more native way.
- """
- if timeout <= 0:
- timeout = np.inf
- timestep = 0.01
- counter = 0
- self._looping = True
- while self._looping and counter * timestep < timeout:
- self.flush_events()
- time.sleep(timestep)
- counter += 1
-
- def stop_event_loop(self):
- """Stop the current blocking event loop.
-
- Interactive backends need to reimplement this to match
- `start_event_loop`
- """
- self._looping = False
-
- start_event_loop_default = cbook.deprecated(
- "2.1", name="start_event_loop_default")(start_event_loop)
- stop_event_loop_default = cbook.deprecated(
- "2.1", name="stop_event_loop_default")(stop_event_loop)
-
-
-def key_press_handler(event, canvas, toolbar=None):
- """
- Implement the default mpl key bindings for the canvas and toolbar
- described at :ref:`key-event-handling`
-
- Parameters
- ----------
- event : :class:`KeyEvent`
- a key press/release event
- canvas : :class:`FigureCanvasBase`
- the backend-specific canvas instance
- toolbar : :class:`NavigationToolbar2`
- the navigation cursor toolbar
-
- """
- # these bindings happen whether you are over an axes or not
-
- if event.key is None:
- return
-
- # Load key-mappings from your matplotlibrc file.
- fullscreen_keys = rcParams['keymap.fullscreen']
- home_keys = rcParams['keymap.home']
- back_keys = rcParams['keymap.back']
- forward_keys = rcParams['keymap.forward']
- pan_keys = rcParams['keymap.pan']
- zoom_keys = rcParams['keymap.zoom']
- save_keys = rcParams['keymap.save']
- quit_keys = rcParams['keymap.quit']
- grid_keys = rcParams['keymap.grid']
- grid_minor_keys = rcParams['keymap.grid_minor']
- toggle_yscale_keys = rcParams['keymap.yscale']
- toggle_xscale_keys = rcParams['keymap.xscale']
- all_keys = rcParams['keymap.all_axes']
-
- # toggle fullscreen mode ('f', 'ctrl + f')
- if event.key in fullscreen_keys:
- try:
- canvas.manager.full_screen_toggle()
- except AttributeError:
- pass
-
- # quit the figure (default key 'ctrl+w')
- if event.key in quit_keys:
- Gcf.destroy_fig(canvas.figure)
-
- if toolbar is not None:
- # home or reset mnemonic (default key 'h', 'home' and 'r')
- if event.key in home_keys:
- toolbar.home()
- # forward / backward keys to enable left handed quick navigation
- # (default key for backward: 'left', 'backspace' and 'c')
- elif event.key in back_keys:
- toolbar.back()
- # (default key for forward: 'right' and 'v')
- elif event.key in forward_keys:
- toolbar.forward()
- # pan mnemonic (default key 'p')
- elif event.key in pan_keys:
- toolbar.pan()
- toolbar._set_cursor(event)
- # zoom mnemonic (default key 'o')
- elif event.key in zoom_keys:
- toolbar.zoom()
- toolbar._set_cursor(event)
- # saving current figure (default key 's')
- elif event.key in save_keys:
- toolbar.save_figure()
-
- if event.inaxes is None:
- return
-
- # these bindings require the mouse to be over an axes to trigger
- def _get_uniform_gridstate(ticks):
- # Return True/False if all grid lines are on or off, None if they are
- # not all in the same state.
- if all(tick.gridOn for tick in ticks):
- return True
- elif not any(tick.gridOn for tick in ticks):
- return False
- else:
- return None
-
- ax = event.inaxes
- # toggle major grids in current axes (default key 'g')
- # Both here and below (for 'G'), we do nothing if *any* grid (major or
- # minor, x or y) is not in a uniform state, to avoid messing up user
- # customization.
- if (event.key in grid_keys
- # Exclude minor grids not in a uniform state.
- and None not in [_get_uniform_gridstate(ax.xaxis.minorTicks),
- _get_uniform_gridstate(ax.yaxis.minorTicks)]):
- x_state = _get_uniform_gridstate(ax.xaxis.majorTicks)
- y_state = _get_uniform_gridstate(ax.yaxis.majorTicks)
- cycle = [(False, False), (True, False), (True, True), (False, True)]
- try:
- x_state, y_state = (
- cycle[(cycle.index((x_state, y_state)) + 1) % len(cycle)])
- except ValueError:
- # Exclude major grids not in a uniform state.
- pass
- else:
- # If turning major grids off, also turn minor grids off.
- ax.grid(x_state, which="major" if x_state else "both", axis="x")
- ax.grid(y_state, which="major" if y_state else "both", axis="y")
- canvas.draw_idle()
- # toggle major and minor grids in current axes (default key 'G')
- if (event.key in grid_minor_keys
- # Exclude major grids not in a uniform state.
- and None not in [_get_uniform_gridstate(ax.xaxis.majorTicks),
- _get_uniform_gridstate(ax.yaxis.majorTicks)]):
- x_state = _get_uniform_gridstate(ax.xaxis.minorTicks)
- y_state = _get_uniform_gridstate(ax.yaxis.minorTicks)
- cycle = [(False, False), (True, False), (True, True), (False, True)]
- try:
- x_state, y_state = (
- cycle[(cycle.index((x_state, y_state)) + 1) % len(cycle)])
- except ValueError:
- # Exclude minor grids not in a uniform state.
- pass
- else:
- ax.grid(x_state, which="both", axis="x")
- ax.grid(y_state, which="both", axis="y")
- canvas.draw_idle()
- # toggle scaling of y-axes between 'log and 'linear' (default key 'l')
- elif event.key in toggle_yscale_keys:
- scale = ax.get_yscale()
- if scale == 'log':
- ax.set_yscale('linear')
- ax.figure.canvas.draw_idle()
- elif scale == 'linear':
- try:
- ax.set_yscale('log')
- except ValueError as exc:
- warnings.warn(str(exc))
- ax.set_yscale('linear')
- ax.figure.canvas.draw_idle()
- # toggle scaling of x-axes between 'log and 'linear' (default key 'k')
- elif event.key in toggle_xscale_keys:
- scalex = ax.get_xscale()
- if scalex == 'log':
- ax.set_xscale('linear')
- ax.figure.canvas.draw_idle()
- elif scalex == 'linear':
- try:
- ax.set_xscale('log')
- except ValueError as exc:
- warnings.warn(str(exc))
- ax.set_xscale('linear')
- ax.figure.canvas.draw_idle()
-
- elif (event.key.isdigit() and event.key != '0') or event.key in all_keys:
- # keys in list 'all' enables all axes (default key 'a'),
- # otherwise if key is a number only enable this particular axes
- # if it was the axes, where the event was raised
- if not (event.key in all_keys):
- n = int(event.key) - 1
- for i, a in enumerate(canvas.figure.get_axes()):
- # consider axes, in which the event was raised
- # FIXME: Why only this axes?
- if event.x is not None and event.y is not None \
- and a.in_axes(event):
- if event.key in all_keys:
- a.set_navigate(True)
- else:
- a.set_navigate(i == n)
-
-
-class NonGuiException(Exception):
- pass
-
-
-class FigureManagerBase(object):
- """
- Helper class for pyplot mode, wraps everything up into a neat bundle
-
- Attributes
- ----------
- canvas : :class:`FigureCanvasBase`
- The backend-specific canvas instance
-
- num : int or str
- The figure number
-
- key_press_handler_id : int
- The default key handler cid, when using the toolmanager. Can be used
- to disable default key press handling ::
-
- figure.canvas.mpl_disconnect(
- figure.canvas.manager.key_press_handler_id)
- """
- def __init__(self, canvas, num):
- self.canvas = canvas
- canvas.manager = self # store a pointer to parent
- self.num = num
-
- self.key_press_handler_id = None
- if rcParams['toolbar'] != 'toolmanager':
- self.key_press_handler_id = self.canvas.mpl_connect(
- 'key_press_event',
- self.key_press)
-
- def show(self):
- """
- For GUI backends, show the figure window and redraw.
- For non-GUI backends, raise an exception to be caught
- by :meth:`~matplotlib.figure.Figure.show`, for an
- optional warning.
- """
- raise NonGuiException()
-
- def destroy(self):
- pass
-
- def full_screen_toggle(self):
- pass
-
- def resize(self, w, h):
- """"For GUI backends, resize the window (in pixels)."""
-
- def key_press(self, event):
- """
- Implement the default mpl key bindings defined at
- :ref:`key-event-handling`
- """
- if rcParams['toolbar'] != 'toolmanager':
- key_press_handler(event, self.canvas, self.canvas.toolbar)
-
- @cbook.deprecated("2.2")
- def show_popup(self, msg):
- """Display message in a popup -- GUI only."""
-
- def get_window_title(self):
- """Get the title text of the window containing the figure.
-
- Return None for non-GUI (e.g., PS) backends.
- """
- return 'image'
-
- def set_window_title(self, title):
- """Set the title text of the window containing the figure.
-
- This has no effect for non-GUI (e.g., PS) backends.
- """
-
-
-cursors = tools.cursors
-
-
-class NavigationToolbar2(object):
- """
- Base class for the navigation cursor, version 2
-
- backends must implement a canvas that handles connections for
- 'button_press_event' and 'button_release_event'. See
- :meth:`FigureCanvasBase.mpl_connect` for more information
-
-
- They must also define
-
- :meth:`save_figure`
- save the current figure
-
- :meth:`set_cursor`
- if you want the pointer icon to change
-
- :meth:`_init_toolbar`
- create your toolbar widget
-
- :meth:`draw_rubberband` (optional)
- draw the zoom to rect "rubberband" rectangle
-
- :meth:`press` (optional)
- whenever a mouse button is pressed, you'll be notified with
- the event
-
- :meth:`release` (optional)
- whenever a mouse button is released, you'll be notified with
- the event
-
- :meth:`set_message` (optional)
- display message
-
- :meth:`set_history_buttons` (optional)
- you can change the history back / forward buttons to
- indicate disabled / enabled state.
-
- That's it, we'll do the rest!
- """
-
- # list of toolitems to add to the toolbar, format is:
- # (
- # text, # the text of the button (often not visible to users)
- # tooltip_text, # the tooltip shown on hover (where possible)
- # image_file, # name of the image for the button (without the extension)
- # name_of_method, # name of the method in NavigationToolbar2 to call
- # )
- toolitems = (
- ('Home', 'Reset original view', 'home', 'home'),
- ('Back', 'Back to previous view', 'back', 'back'),
- ('Forward', 'Forward to next view', 'forward', 'forward'),
- (None, None, None, None),
- ('Pan', 'Pan axes with left mouse, zoom with right', 'move', 'pan'),
- ('Zoom', 'Zoom to rectangle', 'zoom_to_rect', 'zoom'),
- ('Subplots', 'Configure subplots', 'subplots', 'configure_subplots'),
- (None, None, None, None),
- ('Save', 'Save the figure', 'filesave', 'save_figure'),
- )
-
- def __init__(self, canvas):
- self.canvas = canvas
- canvas.toolbar = self
- self._nav_stack = cbook.Stack()
- self._xypress = None # the location and axis info at the time
- # of the press
- self._idPress = None
- self._idRelease = None
- self._active = None
- # This cursor will be set after the initial draw.
- self._lastCursor = cursors.POINTER
- self._init_toolbar()
- self._idDrag = self.canvas.mpl_connect(
- 'motion_notify_event', self.mouse_move)
-
- self._ids_zoom = []
- self._zoom_mode = None
-
- self._button_pressed = None # determined by the button pressed
- # at start
-
- self.mode = '' # a mode string for the status bar
- self.set_history_buttons()
-
- def set_message(self, s):
- """Display a message on toolbar or in status bar."""
-
- def back(self, *args):
- """move back up the view lim stack"""
- self._nav_stack.back()
- self.set_history_buttons()
- self._update_view()
-
- @cbook.deprecated("2.1", alternative="canvas.draw_idle")
- def dynamic_update(self):
- self.canvas.draw_idle()
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- """Draw a rectangle rubberband to indicate zoom limits.
-
- Note that it is not guaranteed that ``x0 <= x1`` and ``y0 <= y1``.
- """
-
- def remove_rubberband(self):
- """Remove the rubberband."""
-
- def forward(self, *args):
- """Move forward in the view lim stack."""
- self._nav_stack.forward()
- self.set_history_buttons()
- self._update_view()
-
- def home(self, *args):
- """Restore the original view."""
- self._nav_stack.home()
- self.set_history_buttons()
- self._update_view()
-
- def _init_toolbar(self):
- """
- This is where you actually build the GUI widgets (called by
- __init__). The icons ``home.xpm``, ``back.xpm``, ``forward.xpm``,
- ``hand.xpm``, ``zoom_to_rect.xpm`` and ``filesave.xpm`` are standard
- across backends (there are ppm versions in CVS also).
-
- You just need to set the callbacks
-
- home : self.home
- back : self.back
- forward : self.forward
- hand : self.pan
- zoom_to_rect : self.zoom
- filesave : self.save_figure
-
- You only need to define the last one - the others are in the base
- class implementation.
-
- """
- raise NotImplementedError
-
- def _set_cursor(self, event):
- if not event.inaxes or not self._active:
- if self._lastCursor != cursors.POINTER:
- self.set_cursor(cursors.POINTER)
- self._lastCursor = cursors.POINTER
- else:
- if (self._active == 'ZOOM'
- and self._lastCursor != cursors.SELECT_REGION):
- self.set_cursor(cursors.SELECT_REGION)
- self._lastCursor = cursors.SELECT_REGION
- elif (self._active == 'PAN' and
- self._lastCursor != cursors.MOVE):
- self.set_cursor(cursors.MOVE)
- self._lastCursor = cursors.MOVE
-
- def mouse_move(self, event):
- self._set_cursor(event)
-
- if event.inaxes and event.inaxes.get_navigate():
-
- try:
- s = event.inaxes.format_coord(event.xdata, event.ydata)
- except (ValueError, OverflowError):
- pass
- else:
- artists = [a for a in event.inaxes.mouseover_set
- if a.contains(event) and a.get_visible()]
-
- if artists:
- a = cbook._topmost_artist(artists)
- if a is not event.inaxes.patch:
- data = a.get_cursor_data(event)
- if data is not None:
- s += ' [%s]' % a.format_cursor_data(data)
-
- if len(self.mode):
- self.set_message('%s, %s' % (self.mode, s))
- else:
- self.set_message(s)
- else:
- self.set_message(self.mode)
-
- def pan(self, *args):
- """Activate the pan/zoom tool. pan with left button, zoom with right"""
- # set the pointer icon and button press funcs to the
- # appropriate callbacks
-
- if self._active == 'PAN':
- self._active = None
- else:
- self._active = 'PAN'
- if self._idPress is not None:
- self._idPress = self.canvas.mpl_disconnect(self._idPress)
- self.mode = ''
-
- if self._idRelease is not None:
- self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
- self.mode = ''
-
- if self._active:
- self._idPress = self.canvas.mpl_connect(
- 'button_press_event', self.press_pan)
- self._idRelease = self.canvas.mpl_connect(
- 'button_release_event', self.release_pan)
- self.mode = 'pan/zoom'
- self.canvas.widgetlock(self)
- else:
- self.canvas.widgetlock.release(self)
-
- for a in self.canvas.figure.get_axes():
- a.set_navigate_mode(self._active)
-
- self.set_message(self.mode)
-
- def press(self, event):
- """Called whenever a mouse button is pressed."""
-
- def press_pan(self, event):
- """Callback for mouse button press in pan/zoom mode."""
-
- if event.button == 1:
- self._button_pressed = 1
- elif event.button == 3:
- self._button_pressed = 3
- else:
- self._button_pressed = None
- return
-
- if self._nav_stack() is None:
- # set the home button to this view
- self.push_current()
-
- x, y = event.x, event.y
- self._xypress = []
- for i, a in enumerate(self.canvas.figure.get_axes()):
- if (x is not None and y is not None and a.in_axes(event) and
- a.get_navigate() and a.can_pan()):
- a.start_pan(x, y, event.button)
- self._xypress.append((a, i))
- self.canvas.mpl_disconnect(self._idDrag)
- self._idDrag = self.canvas.mpl_connect('motion_notify_event',
- self.drag_pan)
-
- self.press(event)
-
- def press_zoom(self, event):
- """Callback for mouse button press in zoom to rect mode."""
- # If we're already in the middle of a zoom, pressing another
- # button works to "cancel"
- if self._ids_zoom != []:
- for zoom_id in self._ids_zoom:
- self.canvas.mpl_disconnect(zoom_id)
- self.release(event)
- self.draw()
- self._xypress = None
- self._button_pressed = None
- self._ids_zoom = []
- return
-
- if event.button == 1:
- self._button_pressed = 1
- elif event.button == 3:
- self._button_pressed = 3
- else:
- self._button_pressed = None
- return
-
- if self._nav_stack() is None:
- # set the home button to this view
- self.push_current()
-
- x, y = event.x, event.y
- self._xypress = []
- for i, a in enumerate(self.canvas.figure.get_axes()):
- if (x is not None and y is not None and a.in_axes(event) and
- a.get_navigate() and a.can_zoom()):
- self._xypress.append((x, y, a, i, a._get_view()))
-
- id1 = self.canvas.mpl_connect('motion_notify_event', self.drag_zoom)
- id2 = self.canvas.mpl_connect('key_press_event',
- self._switch_on_zoom_mode)
- id3 = self.canvas.mpl_connect('key_release_event',
- self._switch_off_zoom_mode)
-
- self._ids_zoom = id1, id2, id3
- self._zoom_mode = event.key
-
- self.press(event)
-
- def _switch_on_zoom_mode(self, event):
- self._zoom_mode = event.key
- self.mouse_move(event)
-
- def _switch_off_zoom_mode(self, event):
- self._zoom_mode = None
- self.mouse_move(event)
-
- def push_current(self):
- """Push the current view limits and position onto the stack."""
- self._nav_stack.push(
- WeakKeyDictionary(
- {ax: (ax._get_view(),
- # Store both the original and modified positions.
- (ax.get_position(True).frozen(),
- ax.get_position().frozen()))
- for ax in self.canvas.figure.axes}))
- self.set_history_buttons()
-
- def release(self, event):
- """Callback for mouse button release."""
-
- def release_pan(self, event):
- """Callback for mouse button release in pan/zoom mode."""
-
- if self._button_pressed is None:
- return
- self.canvas.mpl_disconnect(self._idDrag)
- self._idDrag = self.canvas.mpl_connect(
- 'motion_notify_event', self.mouse_move)
- for a, ind in self._xypress:
- a.end_pan()
- if not self._xypress:
- return
- self._xypress = []
- self._button_pressed = None
- self.push_current()
- self.release(event)
- self.draw()
-
- def drag_pan(self, event):
- """Callback for dragging in pan/zoom mode."""
- for a, ind in self._xypress:
- #safer to use the recorded button at the press than current button:
- #multiple button can get pressed during motion...
- a.drag_pan(self._button_pressed, event.key, event.x, event.y)
- self.canvas.draw_idle()
-
- def drag_zoom(self, event):
- """Callback for dragging in zoom mode."""
- if self._xypress:
- x, y = event.x, event.y
- lastx, lasty, a, ind, view = self._xypress[0]
- (x1, y1), (x2, y2) = np.clip(
- [[lastx, lasty], [x, y]], a.bbox.min, a.bbox.max)
- if self._zoom_mode == "x":
- y1, y2 = a.bbox.intervaly
- elif self._zoom_mode == "y":
- x1, x2 = a.bbox.intervalx
- self.draw_rubberband(event, x1, y1, x2, y2)
-
- def release_zoom(self, event):
- """Callback for mouse button release in zoom to rect mode."""
- for zoom_id in self._ids_zoom:
- self.canvas.mpl_disconnect(zoom_id)
- self._ids_zoom = []
-
- self.remove_rubberband()
-
- if not self._xypress:
- return
-
- last_a = []
-
- for cur_xypress in self._xypress:
- x, y = event.x, event.y
- lastx, lasty, a, ind, view = cur_xypress
- # ignore singular clicks - 5 pixels is a threshold
- # allows the user to "cancel" a zoom action
- # by zooming by less than 5 pixels
- if ((abs(x - lastx) < 5 and self._zoom_mode!="y") or
- (abs(y - lasty) < 5 and self._zoom_mode!="x")):
- self._xypress = None
- self.release(event)
- self.draw()
- return
-
- # detect twinx,y axes and avoid double zooming
- twinx, twiny = False, False
- if last_a:
- for la in last_a:
- if a.get_shared_x_axes().joined(a, la):
- twinx = True
- if a.get_shared_y_axes().joined(a, la):
- twiny = True
- last_a.append(a)
-
- if self._button_pressed == 1:
- direction = 'in'
- elif self._button_pressed == 3:
- direction = 'out'
- else:
- continue
-
- a._set_view_from_bbox((lastx, lasty, x, y), direction,
- self._zoom_mode, twinx, twiny)
-
- self.draw()
- self._xypress = None
- self._button_pressed = None
-
- self._zoom_mode = None
-
- self.push_current()
- self.release(event)
-
- def draw(self):
- """Redraw the canvases, update the locators."""
- for a in self.canvas.figure.get_axes():
- xaxis = getattr(a, 'xaxis', None)
- yaxis = getattr(a, 'yaxis', None)
- locators = []
- if xaxis is not None:
- locators.append(xaxis.get_major_locator())
- locators.append(xaxis.get_minor_locator())
- if yaxis is not None:
- locators.append(yaxis.get_major_locator())
- locators.append(yaxis.get_minor_locator())
-
- for loc in locators:
- loc.refresh()
- self.canvas.draw_idle()
-
- def _update_view(self):
- """Update the viewlim and position from the view and
- position stack for each axes.
- """
- nav_info = self._nav_stack()
- if nav_info is None:
- return
- # Retrieve all items at once to avoid any risk of GC deleting an Axes
- # while in the middle of the loop below.
- items = list(nav_info.items())
- for ax, (view, (pos_orig, pos_active)) in items:
- ax._set_view(view)
- # Restore both the original and modified positions
- ax._set_position(pos_orig, 'original')
- ax._set_position(pos_active, 'active')
- self.canvas.draw_idle()
-
- def save_figure(self, *args):
- """Save the current figure."""
- raise NotImplementedError
-
- def set_cursor(self, cursor):
- """Set the current cursor to one of the :class:`Cursors` enums values.
-
- If required by the backend, this method should trigger an update in
- the backend event loop after the cursor is set, as this method may be
- called e.g. before a long-running task during which the GUI is not
- updated.
- """
-
- def update(self):
- """Reset the axes stack."""
- self._nav_stack.clear()
- self.set_history_buttons()
-
- def zoom(self, *args):
- """Activate zoom to rect mode."""
- if self._active == 'ZOOM':
- self._active = None
- else:
- self._active = 'ZOOM'
-
- if self._idPress is not None:
- self._idPress = self.canvas.mpl_disconnect(self._idPress)
- self.mode = ''
-
- if self._idRelease is not None:
- self._idRelease = self.canvas.mpl_disconnect(self._idRelease)
- self.mode = ''
-
- if self._active:
- self._idPress = self.canvas.mpl_connect('button_press_event',
- self.press_zoom)
- self._idRelease = self.canvas.mpl_connect('button_release_event',
- self.release_zoom)
- self.mode = 'zoom rect'
- self.canvas.widgetlock(self)
- else:
- self.canvas.widgetlock.release(self)
-
- for a in self.canvas.figure.get_axes():
- a.set_navigate_mode(self._active)
-
- self.set_message(self.mode)
-
- def set_history_buttons(self):
- """Enable or disable the back/forward button."""
-
-
-class ToolContainerBase(object):
- """
- Base class for all tool containers, e.g. toolbars.
-
- Attributes
- ----------
- toolmanager : `ToolManager`
- The tools with which this `ToolContainer` wants to communicate.
- """
-
- _icon_extension = '.png'
- """
- Toolcontainer button icon image format extension
-
- **String**: Image extension
- """
-
- def __init__(self, toolmanager):
- self.toolmanager = toolmanager
- self.toolmanager.toolmanager_connect('tool_removed_event',
- self._remove_tool_cbk)
-
- def _tool_toggled_cbk(self, event):
- """
- Captures the 'tool_trigger_[name]'
-
- This only gets used for toggled tools
- """
- self.toggle_toolitem(event.tool.name, event.tool.toggled)
-
- def add_tool(self, tool, group, position=-1):
- """
- Adds a tool to this container
-
- Parameters
- ----------
- tool : tool_like
- The tool to add, see `ToolManager.get_tool`.
- group : str
- The name of the group to add this tool to.
- position : int (optional)
- The position within the group to place this tool. Defaults to end.
- """
- tool = self.toolmanager.get_tool(tool)
- image = self._get_image_filename(tool.image)
- toggle = getattr(tool, 'toggled', None) is not None
- self.add_toolitem(tool.name, group, position,
- image, tool.description, toggle)
- if toggle:
- self.toolmanager.toolmanager_connect('tool_trigger_%s' % tool.name,
- self._tool_toggled_cbk)
- # If initially toggled
- if tool.toggled:
- self.toggle_toolitem(tool.name, True)
-
- def _remove_tool_cbk(self, event):
- """Captures the 'tool_removed_event' signal and removes the tool."""
- self.remove_toolitem(event.tool.name)
-
- def _get_image_filename(self, image):
- """Find the image based on its name."""
- if not image:
- return None
-
- basedir = os.path.join(rcParams['datapath'], 'images')
- possible_images = (
- image,
- image + self._icon_extension,
- os.path.join(basedir, image),
- os.path.join(basedir, image) + self._icon_extension)
-
- for fname in possible_images:
- if os.path.isfile(fname):
- return fname
-
- def trigger_tool(self, name):
- """
- Trigger the tool
-
- Parameters
- ----------
- name : String
- Name (id) of the tool triggered from within the container
- """
- self.toolmanager.trigger_tool(name, sender=self)
-
- def add_toolitem(self, name, group, position, image, description, toggle):
- """
- Add a toolitem to the container
-
- This method must get implemented per backend
-
- The callback associated with the button click event,
- must be **EXACTLY** `self.trigger_tool(name)`
-
- Parameters
- ----------
- name : string
- Name of the tool to add, this gets used as the tool's ID and as the
- default label of the buttons
- group : String
- Name of the group that this tool belongs to
- position : Int
- Position of the tool within its group, if -1 it goes at the End
- image_file : String
- Filename of the image for the button or `None`
- description : String
- Description of the tool, used for the tooltips
- toggle : Bool
- * `True` : The button is a toggle (change the pressed/unpressed
- state between consecutive clicks)
- * `False` : The button is a normal button (returns to unpressed
- state after release)
- """
- raise NotImplementedError
-
- def toggle_toolitem(self, name, toggled):
- """
- Toggle the toolitem without firing event
-
- Parameters
- ----------
- name : String
- Id of the tool to toggle
- toggled : bool
- Whether to set this tool as toggled or not.
- """
- raise NotImplementedError
-
- def remove_toolitem(self, name):
- """
- Remove a toolitem from the `ToolContainer`
-
- This method must get implemented per backend
-
- Called when `ToolManager` emits a `tool_removed_event`
-
- Parameters
- ----------
- name : string
- Name of the tool to remove
- """
- raise NotImplementedError
-
-
-class StatusbarBase(object):
- """Base class for the statusbar"""
- def __init__(self, toolmanager):
- self.toolmanager = toolmanager
- self.toolmanager.toolmanager_connect('tool_message_event',
- self._message_cbk)
-
- def _message_cbk(self, event):
- """Captures the 'tool_message_event' and set the message"""
- self.set_message(event.message)
-
- def set_message(self, s):
- """
- Display a message on toolbar or in status bar
-
- Parameters
- ----------
- s : str
- Message text
- """
- pass
diff --git a/contrib/python/matplotlib/py2/matplotlib/backend_managers.py b/contrib/python/matplotlib/py2/matplotlib/backend_managers.py
deleted file mode 100644
index ab9a503fab..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backend_managers.py
+++ /dev/null
@@ -1,436 +0,0 @@
-"""
-`ToolManager`
- Class that makes the bridge between user interaction (key press,
- toolbar clicks, ..) and the actions in response to the user inputs.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-import six
-import warnings
-
-import matplotlib.cbook as cbook
-import matplotlib.widgets as widgets
-from matplotlib.rcsetup import validate_stringlist
-import matplotlib.backend_tools as tools
-
-
-class ToolEvent(object):
- """Event for tool manipulation (add/remove)"""
- def __init__(self, name, sender, tool, data=None):
- self.name = name
- self.sender = sender
- self.tool = tool
- self.data = data
-
-
-class ToolTriggerEvent(ToolEvent):
- """Event to inform that a tool has been triggered"""
- def __init__(self, name, sender, tool, canvasevent=None, data=None):
- ToolEvent.__init__(self, name, sender, tool, data)
- self.canvasevent = canvasevent
-
-
-class ToolManagerMessageEvent(object):
- """
- Event carrying messages from toolmanager
-
- Messages usually get displayed to the user by the toolbar
- """
- def __init__(self, name, sender, message):
- self.name = name
- self.sender = sender
- self.message = message
-
-
-class ToolManager(object):
- """
- Helper class that groups all the user interactions for a Figure
-
- Attributes
- ----------
- figure: `Figure`
- keypresslock: `widgets.LockDraw`
- `LockDraw` object to know if the `canvas` key_press_event is locked
- messagelock: `widgets.LockDraw`
- `LockDraw` object to know if the message is available to write
- """
-
- def __init__(self, figure=None):
- warnings.warn('Treat the new Tool classes introduced in v1.5 as ' +
- 'experimental for now, the API will likely change in ' +
- 'version 2.1 and perhaps the rcParam as well')
-
- self._key_press_handler_id = None
-
- self._tools = {}
- self._keys = {}
- self._toggled = {}
- self._callbacks = cbook.CallbackRegistry()
-
- # to process keypress event
- self.keypresslock = widgets.LockDraw()
- self.messagelock = widgets.LockDraw()
-
- self._figure = None
- self.set_figure(figure)
-
- @property
- def canvas(self):
- """Canvas managed by FigureManager"""
- if not self._figure:
- return None
- return self._figure.canvas
-
- @property
- def figure(self):
- """Figure that holds the canvas"""
- return self._figure
-
- @figure.setter
- def figure(self, figure):
- self.set_figure(figure)
-
- def set_figure(self, figure, update_tools=True):
- """
- Sets the figure to interact with the tools
-
- Parameters
- ==========
- figure: `Figure`
- update_tools: bool
- Force tools to update figure
- """
- if self._key_press_handler_id:
- self.canvas.mpl_disconnect(self._key_press_handler_id)
- self._figure = figure
- if figure:
- self._key_press_handler_id = self.canvas.mpl_connect(
- 'key_press_event', self._key_press)
- if update_tools:
- for tool in self._tools.values():
- tool.figure = figure
-
- def toolmanager_connect(self, s, func):
- """
- Connect event with string *s* to *func*.
-
- Parameters
- ----------
- s : String
- Name of the event
-
- The following events are recognized
-
- - 'tool_message_event'
- - 'tool_removed_event'
- - 'tool_added_event'
-
- For every tool added a new event is created
-
- - 'tool_trigger_TOOLNAME`
- Where TOOLNAME is the id of the tool.
-
- func : function
- Function to be called with signature
- def func(event)
- """
- return self._callbacks.connect(s, func)
-
- def toolmanager_disconnect(self, cid):
- """
- Disconnect callback id *cid*
-
- Example usage::
-
- cid = toolmanager.toolmanager_connect('tool_trigger_zoom',
- on_press)
- #...later
- toolmanager.toolmanager_disconnect(cid)
- """
- return self._callbacks.disconnect(cid)
-
- def message_event(self, message, sender=None):
- """ Emit a `ToolManagerMessageEvent`"""
- if sender is None:
- sender = self
-
- s = 'tool_message_event'
- event = ToolManagerMessageEvent(s, sender, message)
- self._callbacks.process(s, event)
-
- @property
- def active_toggle(self):
- """Currently toggled tools"""
-
- return self._toggled
-
- def get_tool_keymap(self, name):
- """
- Get the keymap associated with the specified tool
-
- Parameters
- ----------
- name : string
- Name of the Tool
-
- Returns
- -------
- list : list of keys associated with the Tool
- """
-
- keys = [k for k, i in six.iteritems(self._keys) if i == name]
- return keys
-
- def _remove_keys(self, name):
- for k in self.get_tool_keymap(name):
- del self._keys[k]
-
- def update_keymap(self, name, *keys):
- """
- Set the keymap to associate with the specified tool
-
- Parameters
- ----------
- name : string
- Name of the Tool
- keys : keys to associate with the Tool
- """
-
- if name not in self._tools:
- raise KeyError('%s not in Tools' % name)
-
- self._remove_keys(name)
-
- for key in keys:
- for k in validate_stringlist(key):
- if k in self._keys:
- warnings.warn('Key %s changed from %s to %s' %
- (k, self._keys[k], name))
- self._keys[k] = name
-
- def remove_tool(self, name):
- """
- Remove tool from `ToolManager`
-
- Parameters
- ----------
- name : string
- Name of the Tool
- """
-
- tool = self.get_tool(name)
- tool.destroy()
-
- # If is a toggle tool and toggled, untoggle
- if getattr(tool, 'toggled', False):
- self.trigger_tool(tool, 'toolmanager')
-
- self._remove_keys(name)
-
- s = 'tool_removed_event'
- event = ToolEvent(s, self, tool)
- self._callbacks.process(s, event)
-
- del self._tools[name]
-
- def add_tool(self, name, tool, *args, **kwargs):
- """
- Add *tool* to `ToolManager`
-
- If successful adds a new event `tool_trigger_name` where **name** is
- the **name** of the tool, this event is fired everytime
- the tool is triggered.
-
- Parameters
- ----------
- name : str
- Name of the tool, treated as the ID, has to be unique
- tool : class_like, i.e. str or type
- Reference to find the class of the Tool to added.
-
- Notes
- -----
- args and kwargs get passed directly to the tools constructor.
-
- See Also
- --------
- matplotlib.backend_tools.ToolBase : The base class for tools.
- """
-
- tool_cls = self._get_cls_to_instantiate(tool)
- if not tool_cls:
- raise ValueError('Impossible to find class for %s' % str(tool))
-
- if name in self._tools:
- warnings.warn('A "Tool class" with the same name already exists, '
- 'not added')
- return self._tools[name]
-
- tool_obj = tool_cls(self, name, *args, **kwargs)
- self._tools[name] = tool_obj
-
- if tool_cls.default_keymap is not None:
- self.update_keymap(name, tool_cls.default_keymap)
-
- # For toggle tools init the radio_group in self._toggled
- if isinstance(tool_obj, tools.ToolToggleBase):
- # None group is not mutually exclusive, a set is used to keep track
- # of all toggled tools in this group
- if tool_obj.radio_group is None:
- self._toggled.setdefault(None, set())
- else:
- self._toggled.setdefault(tool_obj.radio_group, None)
-
- # If initially toggled
- if tool_obj.toggled:
- self._handle_toggle(tool_obj, None, None, None)
- tool_obj.set_figure(self.figure)
-
- self._tool_added_event(tool_obj)
- return tool_obj
-
- def _tool_added_event(self, tool):
- s = 'tool_added_event'
- event = ToolEvent(s, self, tool)
- self._callbacks.process(s, event)
-
- def _handle_toggle(self, tool, sender, canvasevent, data):
- """
- Toggle tools, need to untoggle prior to using other Toggle tool
- Called from trigger_tool
-
- Parameters
- ----------
- tool: Tool object
- sender: object
- Object that wishes to trigger the tool
- canvasevent : Event
- Original Canvas event or None
- data : Object
- Extra data to pass to the tool when triggering
- """
-
- radio_group = tool.radio_group
- # radio_group None is not mutually exclusive
- # just keep track of toggled tools in this group
- if radio_group is None:
- if tool.name in self._toggled[None]:
- self._toggled[None].remove(tool.name)
- else:
- self._toggled[None].add(tool.name)
- return
-
- # If the tool already has a toggled state, untoggle it
- if self._toggled[radio_group] == tool.name:
- toggled = None
- # If no tool was toggled in the radio_group
- # toggle it
- elif self._toggled[radio_group] is None:
- toggled = tool.name
- # Other tool in the radio_group is toggled
- else:
- # Untoggle previously toggled tool
- self.trigger_tool(self._toggled[radio_group],
- self,
- canvasevent,
- data)
- toggled = tool.name
-
- # Keep track of the toggled tool in the radio_group
- self._toggled[radio_group] = toggled
-
- def _get_cls_to_instantiate(self, callback_class):
- # Find the class that corresponds to the tool
- if isinstance(callback_class, six.string_types):
- # FIXME: make more complete searching structure
- if callback_class in globals():
- callback_class = globals()[callback_class]
- else:
- mod = 'backend_tools'
- current_module = __import__(mod,
- globals(), locals(), [mod], 1)
-
- callback_class = getattr(current_module, callback_class, False)
- if callable(callback_class):
- return callback_class
- else:
- return None
-
- def trigger_tool(self, name, sender=None, canvasevent=None,
- data=None):
- """
- Trigger a tool and emit the tool_trigger_[name] event
-
- Parameters
- ----------
- name : string
- Name of the tool
- sender: object
- Object that wishes to trigger the tool
- canvasevent : Event
- Original Canvas event or None
- data : Object
- Extra data to pass to the tool when triggering
- """
- tool = self.get_tool(name)
- if tool is None:
- return
-
- if sender is None:
- sender = self
-
- self._trigger_tool(name, sender, canvasevent, data)
-
- s = 'tool_trigger_%s' % name
- event = ToolTriggerEvent(s, sender, tool, canvasevent, data)
- self._callbacks.process(s, event)
-
- def _trigger_tool(self, name, sender=None, canvasevent=None, data=None):
- """
- Trigger on a tool
-
- Method to actually trigger the tool
- """
- tool = self.get_tool(name)
-
- if isinstance(tool, tools.ToolToggleBase):
- self._handle_toggle(tool, sender, canvasevent, data)
-
- # Important!!!
- # This is where the Tool object gets triggered
- tool.trigger(sender, canvasevent, data)
-
- def _key_press(self, event):
- if event.key is None or self.keypresslock.locked():
- return
-
- name = self._keys.get(event.key, None)
- if name is None:
- return
- self.trigger_tool(name, canvasevent=event)
-
- @property
- def tools(self):
- """Return the tools controlled by `ToolManager`"""
-
- return self._tools
-
- def get_tool(self, name, warn=True):
- """
- Return the tool object, also accepts the actual tool for convenience
-
- Parameters
- ----------
- name : str, ToolBase
- Name of the tool, or the tool itself
- warn : bool, optional
- If this method should give warnings.
- """
- if isinstance(name, tools.ToolBase) and name.name in self._tools:
- return name
- if name not in self._tools:
- if warn:
- warnings.warn("ToolManager does not control tool %s" % name)
- return None
- return self._tools[name]
diff --git a/contrib/python/matplotlib/py2/matplotlib/backend_tools.py b/contrib/python/matplotlib/py2/matplotlib/backend_tools.py
deleted file mode 100644
index 6639763e41..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backend_tools.py
+++ /dev/null
@@ -1,1081 +0,0 @@
-"""
-Abstract base classes define the primitives for Tools.
-These tools are used by `matplotlib.backend_managers.ToolManager`
-
-:class:`ToolBase`
- Simple stateless tool
-
-:class:`ToolToggleBase`
- Tool that has two states, only one Toggle tool can be
- active at any given time for the same
- `matplotlib.backend_managers.ToolManager`
-"""
-
-
-from matplotlib import rcParams
-from matplotlib._pylab_helpers import Gcf
-import matplotlib.cbook as cbook
-from weakref import WeakKeyDictionary
-import six
-import time
-import warnings
-import numpy as np
-
-
-class Cursors(object):
- """Simple namespace for cursor reference"""
- HAND, POINTER, SELECT_REGION, MOVE, WAIT = list(range(5))
-cursors = Cursors()
-
-# Views positions tool
-_views_positions = 'viewpos'
-
-
-class ToolBase(object):
- """
- Base tool class
-
- A base tool, only implements `trigger` method or not method at all.
- The tool is instantiated by `matplotlib.backend_managers.ToolManager`
-
- Attributes
- ----------
- toolmanager: `matplotlib.backend_managers.ToolManager`
- ToolManager that controls this Tool
- figure: `FigureCanvas`
- Figure instance that is affected by this Tool
- name: String
- Used as **Id** of the tool, has to be unique among tools of the same
- ToolManager
- """
-
- default_keymap = None
- """
- Keymap to associate with this tool
-
- **String**: List of comma separated keys that will be used to call this
- tool when the keypress event of *self.figure.canvas* is emitted
- """
-
- description = None
- """
- Description of the Tool
-
- **String**: If the Tool is included in the Toolbar this text is used
- as a Tooltip
- """
-
- image = None
- """
- Filename of the image
-
- **String**: Filename of the image to use in the toolbar. If None, the
- `name` is used as a label in the toolbar button
- """
-
- def __init__(self, toolmanager, name):
- warnings.warn('Treat the new Tool classes introduced in v1.5 as ' +
- 'experimental for now, the API will likely change in ' +
- 'version 2.1, and some tools might change name')
- self._name = name
- self._toolmanager = toolmanager
- self._figure = None
-
- @property
- def figure(self):
- return self._figure
-
- @figure.setter
- def figure(self, figure):
- self.set_figure(figure)
-
- @property
- def canvas(self):
- if not self._figure:
- return None
- return self._figure.canvas
-
- @property
- def toolmanager(self):
- return self._toolmanager
-
- def set_figure(self, figure):
- """
- Assign a figure to the tool
-
- Parameters
- ----------
- figure: `Figure`
- """
- self._figure = figure
-
- def trigger(self, sender, event, data=None):
- """
- Called when this tool gets used
-
- This method is called by
- `matplotlib.backend_managers.ToolManager.trigger_tool`
-
- Parameters
- ----------
- event: `Event`
- The Canvas event that caused this tool to be called
- sender: object
- Object that requested the tool to be triggered
- data: object
- Extra data
- """
-
- pass
-
- @property
- def name(self):
- """Tool Id"""
- return self._name
-
- def destroy(self):
- """
- Destroy the tool
-
- This method is called when the tool is removed by
- `matplotlib.backend_managers.ToolManager.remove_tool`
- """
- pass
-
-
-class ToolToggleBase(ToolBase):
- """
- Toggleable tool
-
- Every time it is triggered, it switches between enable and disable
-
- Parameters
- ----------
- ``*args``
- Variable length argument to be used by the Tool
- ``**kwargs``
- `toggled` if present and True, sets the initial state of the Tool
- Arbitrary keyword arguments to be consumed by the Tool
- """
-
- radio_group = None
- """Attribute to group 'radio' like tools (mutually exclusive)
-
- **String** that identifies the group or **None** if not belonging to a
- group
- """
-
- cursor = None
- """Cursor to use when the tool is active"""
-
- default_toggled = False
- """Default of toggled state"""
-
- def __init__(self, *args, **kwargs):
- self._toggled = kwargs.pop('toggled', self.default_toggled)
- ToolBase.__init__(self, *args, **kwargs)
-
- def trigger(self, sender, event, data=None):
- """Calls `enable` or `disable` based on `toggled` value"""
- if self._toggled:
- self.disable(event)
- else:
- self.enable(event)
- self._toggled = not self._toggled
-
- def enable(self, event=None):
- """
- Enable the toggle tool
-
- `trigger` calls this method when `toggled` is False
- """
-
- pass
-
- def disable(self, event=None):
- """
- Disable the toggle tool
-
- `trigger` call this method when `toggled` is True.
-
- This can happen in different circumstances
-
- * Click on the toolbar tool button
- * Call to `matplotlib.backend_managers.ToolManager.trigger_tool`
- * Another `ToolToggleBase` derived tool is triggered
- (from the same `ToolManager`)
- """
-
- pass
-
- @property
- def toggled(self):
- """State of the toggled tool"""
-
- return self._toggled
-
- def set_figure(self, figure):
- toggled = self.toggled
- if toggled:
- if self.figure:
- self.trigger(self, None)
- else:
- # if no figure the internal state is not changed
- # we change it here so next call to trigger will change it back
- self._toggled = False
- ToolBase.set_figure(self, figure)
- if toggled:
- if figure:
- self.trigger(self, None)
- else:
- # if there is no figure, trigger won't change the internal
- # state we change it back
- self._toggled = True
-
-
-class SetCursorBase(ToolBase):
- """
- Change to the current cursor while inaxes
-
- This tool, keeps track of all `ToolToggleBase` derived tools, and calls
- set_cursor when a tool gets triggered
- """
- def __init__(self, *args, **kwargs):
- ToolBase.__init__(self, *args, **kwargs)
- self._idDrag = None
- self._cursor = None
- self._default_cursor = cursors.POINTER
- self._last_cursor = self._default_cursor
- self.toolmanager.toolmanager_connect('tool_added_event',
- self._add_tool_cbk)
-
- # process current tools
- for tool in self.toolmanager.tools.values():
- self._add_tool(tool)
-
- def set_figure(self, figure):
- if self._idDrag:
- self.canvas.mpl_disconnect(self._idDrag)
- ToolBase.set_figure(self, figure)
- if figure:
- self._idDrag = self.canvas.mpl_connect(
- 'motion_notify_event', self._set_cursor_cbk)
-
- def _tool_trigger_cbk(self, event):
- if event.tool.toggled:
- self._cursor = event.tool.cursor
- else:
- self._cursor = None
-
- self._set_cursor_cbk(event.canvasevent)
-
- def _add_tool(self, tool):
- """set the cursor when the tool is triggered"""
- if getattr(tool, 'cursor', None) is not None:
- self.toolmanager.toolmanager_connect('tool_trigger_%s' % tool.name,
- self._tool_trigger_cbk)
-
- def _add_tool_cbk(self, event):
- """Process every newly added tool"""
- if event.tool is self:
- return
-
- self._add_tool(event.tool)
-
- def _set_cursor_cbk(self, event):
- if not event:
- return
-
- if not getattr(event, 'inaxes', False) or not self._cursor:
- if self._last_cursor != self._default_cursor:
- self.set_cursor(self._default_cursor)
- self._last_cursor = self._default_cursor
- elif self._cursor:
- cursor = self._cursor
- if cursor and self._last_cursor != cursor:
- self.set_cursor(cursor)
- self._last_cursor = cursor
-
- def set_cursor(self, cursor):
- """
- Set the cursor
-
- This method has to be implemented per backend
- """
- raise NotImplementedError
-
-
-class ToolCursorPosition(ToolBase):
- """
- Send message with the current pointer position
-
- This tool runs in the background reporting the position of the cursor
- """
- def __init__(self, *args, **kwargs):
- self._idDrag = None
- ToolBase.__init__(self, *args, **kwargs)
-
- def set_figure(self, figure):
- if self._idDrag:
- self.canvas.mpl_disconnect(self._idDrag)
- ToolBase.set_figure(self, figure)
- if figure:
- self._idDrag = self.canvas.mpl_connect(
- 'motion_notify_event', self.send_message)
-
- def send_message(self, event):
- """Call `matplotlib.backend_managers.ToolManager.message_event`"""
- if self.toolmanager.messagelock.locked():
- return
-
- message = ' '
-
- if event.inaxes and event.inaxes.get_navigate():
- try:
- s = event.inaxes.format_coord(event.xdata, event.ydata)
- except (ValueError, OverflowError):
- pass
- else:
- artists = [a for a in event.inaxes.mouseover_set
- if a.contains(event) and a.get_visible()]
-
- if artists:
- a = cbook._topmost_artist(artists)
- if a is not event.inaxes.patch:
- data = a.get_cursor_data(event)
- if data is not None:
- s += ' [%s]' % a.format_cursor_data(data)
-
- message = s
- self.toolmanager.message_event(message, self)
-
-
-class RubberbandBase(ToolBase):
- """Draw and remove rubberband"""
- def trigger(self, sender, event, data):
- """Call `draw_rubberband` or `remove_rubberband` based on data"""
- if not self.figure.canvas.widgetlock.available(sender):
- return
- if data is not None:
- self.draw_rubberband(*data)
- else:
- self.remove_rubberband()
-
- def draw_rubberband(self, *data):
- """
- Draw rubberband
-
- This method must get implemented per backend
- """
- raise NotImplementedError
-
- def remove_rubberband(self):
- """
- Remove rubberband
-
- This method should get implemented per backend
- """
- pass
-
-
-class ToolQuit(ToolBase):
- """Tool to call the figure manager destroy method"""
-
- description = 'Quit the figure'
- default_keymap = rcParams['keymap.quit']
-
- def trigger(self, sender, event, data=None):
- Gcf.destroy_fig(self.figure)
-
-
-class ToolQuitAll(ToolBase):
- """Tool to call the figure manager destroy method"""
-
- description = 'Quit all figures'
- default_keymap = rcParams['keymap.quit_all']
-
- def trigger(self, sender, event, data=None):
- Gcf.destroy_all()
-
-
-class ToolEnableAllNavigation(ToolBase):
- """Tool to enable all axes for toolmanager interaction"""
-
- description = 'Enables all axes toolmanager'
- default_keymap = rcParams['keymap.all_axes']
-
- def trigger(self, sender, event, data=None):
- if event.inaxes is None:
- return
-
- for a in self.figure.get_axes():
- if (event.x is not None and event.y is not None
- and a.in_axes(event)):
- a.set_navigate(True)
-
-
-class ToolEnableNavigation(ToolBase):
- """Tool to enable a specific axes for toolmanager interaction"""
-
- description = 'Enables one axes toolmanager'
- default_keymap = (1, 2, 3, 4, 5, 6, 7, 8, 9)
-
- def trigger(self, sender, event, data=None):
- if event.inaxes is None:
- return
-
- n = int(event.key) - 1
- for i, a in enumerate(self.figure.get_axes()):
- if (event.x is not None and event.y is not None
- and a.in_axes(event)):
- a.set_navigate(i == n)
-
-
-class _ToolGridBase(ToolBase):
- """Common functionality between ToolGrid and ToolMinorGrid."""
-
- _cycle = [(False, False), (True, False), (True, True), (False, True)]
-
- def trigger(self, sender, event, data=None):
- ax = event.inaxes
- if ax is None:
- return
- try:
- x_state, x_which, y_state, y_which = self._get_next_grid_states(ax)
- except ValueError:
- pass
- else:
- ax.grid(x_state, which=x_which, axis="x")
- ax.grid(y_state, which=y_which, axis="y")
- ax.figure.canvas.draw_idle()
-
- @staticmethod
- def _get_uniform_grid_state(ticks):
- """
- Check whether all grid lines are in the same visibility state.
-
- Returns True/False if all grid lines are on or off, None if they are
- not all in the same state.
- """
- if all(tick.gridOn for tick in ticks):
- return True
- elif not any(tick.gridOn for tick in ticks):
- return False
- else:
- return None
-
-
-class ToolGrid(_ToolGridBase):
- """Tool to toggle the major grids of the figure"""
-
- description = 'Toogle major grids'
- default_keymap = rcParams['keymap.grid']
-
- def _get_next_grid_states(self, ax):
- if None in map(self._get_uniform_grid_state,
- [ax.xaxis.minorTicks, ax.yaxis.minorTicks]):
- # Bail out if minor grids are not in a uniform state.
- raise ValueError
- x_state, y_state = map(self._get_uniform_grid_state,
- [ax.xaxis.majorTicks, ax.yaxis.majorTicks])
- cycle = self._cycle
- # Bail out (via ValueError) if major grids are not in a uniform state.
- x_state, y_state = (
- cycle[(cycle.index((x_state, y_state)) + 1) % len(cycle)])
- return (x_state, "major" if x_state else "both",
- y_state, "major" if y_state else "both")
-
-
-class ToolMinorGrid(_ToolGridBase):
- """Tool to toggle the major and minor grids of the figure"""
-
- description = 'Toogle major and minor grids'
- default_keymap = rcParams['keymap.grid_minor']
-
- def _get_next_grid_states(self, ax):
- if None in map(self._get_uniform_grid_state,
- [ax.xaxis.majorTicks, ax.yaxis.majorTicks]):
- # Bail out if major grids are not in a uniform state.
- raise ValueError
- x_state, y_state = map(self._get_uniform_grid_state,
- [ax.xaxis.minorTicks, ax.yaxis.minorTicks])
- cycle = self._cycle
- # Bail out (via ValueError) if minor grids are not in a uniform state.
- x_state, y_state = (
- cycle[(cycle.index((x_state, y_state)) + 1) % len(cycle)])
- return x_state, "both", y_state, "both"
-
-
-class ToolFullScreen(ToolToggleBase):
- """Tool to toggle full screen"""
-
- description = 'Toogle Fullscreen mode'
- default_keymap = rcParams['keymap.fullscreen']
-
- def enable(self, event):
- self.figure.canvas.manager.full_screen_toggle()
-
- def disable(self, event):
- self.figure.canvas.manager.full_screen_toggle()
-
-
-class AxisScaleBase(ToolToggleBase):
- """Base Tool to toggle between linear and logarithmic"""
-
- def trigger(self, sender, event, data=None):
- if event.inaxes is None:
- return
- ToolToggleBase.trigger(self, sender, event, data)
-
- def enable(self, event):
- self.set_scale(event.inaxes, 'log')
- self.figure.canvas.draw_idle()
-
- def disable(self, event):
- self.set_scale(event.inaxes, 'linear')
- self.figure.canvas.draw_idle()
-
-
-class ToolYScale(AxisScaleBase):
- """Tool to toggle between linear and logarithmic scales on the Y axis"""
-
- description = 'Toogle Scale Y axis'
- default_keymap = rcParams['keymap.yscale']
-
- def set_scale(self, ax, scale):
- ax.set_yscale(scale)
-
-
-class ToolXScale(AxisScaleBase):
- """Tool to toggle between linear and logarithmic scales on the X axis"""
-
- description = 'Toogle Scale X axis'
- default_keymap = rcParams['keymap.xscale']
-
- def set_scale(self, ax, scale):
- ax.set_xscale(scale)
-
-
-class ToolViewsPositions(ToolBase):
- """
- Auxiliary Tool to handle changes in views and positions
-
- Runs in the background and should get used by all the tools that
- need to access the figure's history of views and positions, e.g.
-
- * `ToolZoom`
- * `ToolPan`
- * `ToolHome`
- * `ToolBack`
- * `ToolForward`
- """
-
- def __init__(self, *args, **kwargs):
- self.views = WeakKeyDictionary()
- self.positions = WeakKeyDictionary()
- self.home_views = WeakKeyDictionary()
- ToolBase.__init__(self, *args, **kwargs)
-
- def add_figure(self, figure):
- """Add the current figure to the stack of views and positions"""
-
- if figure not in self.views:
- self.views[figure] = cbook.Stack()
- self.positions[figure] = cbook.Stack()
- self.home_views[figure] = WeakKeyDictionary()
- # Define Home
- self.push_current(figure)
- # Make sure we add a home view for new axes as they're added
- figure.add_axobserver(lambda fig: self.update_home_views(fig))
-
- def clear(self, figure):
- """Reset the axes stack"""
- if figure in self.views:
- self.views[figure].clear()
- self.positions[figure].clear()
- self.home_views[figure].clear()
- self.update_home_views()
-
- def update_view(self):
- """
- Update the view limits and position for each axes from the current
- stack position. If any axes are present in the figure that aren't in
- the current stack position, use the home view limits for those axes and
- don't update *any* positions.
- """
-
- views = self.views[self.figure]()
- if views is None:
- return
- pos = self.positions[self.figure]()
- if pos is None:
- return
- home_views = self.home_views[self.figure]
- all_axes = self.figure.get_axes()
- for a in all_axes:
- if a in views:
- cur_view = views[a]
- else:
- cur_view = home_views[a]
- a._set_view(cur_view)
-
- if set(all_axes).issubset(pos):
- for a in all_axes:
- # Restore both the original and modified positions
- a._set_position(pos[a][0], 'original')
- a._set_position(pos[a][1], 'active')
-
- self.figure.canvas.draw_idle()
-
- def push_current(self, figure=None):
- """
- Push the current view limits and position onto their respective stacks
- """
- if not figure:
- figure = self.figure
- views = WeakKeyDictionary()
- pos = WeakKeyDictionary()
- for a in figure.get_axes():
- views[a] = a._get_view()
- pos[a] = self._axes_pos(a)
- self.views[figure].push(views)
- self.positions[figure].push(pos)
-
- def _axes_pos(self, ax):
- """
- Return the original and modified positions for the specified axes
-
- Parameters
- ----------
- ax : (matplotlib.axes.AxesSubplot)
- The axes to get the positions for
-
- Returns
- -------
- limits : (tuple)
- A tuple of the original and modified positions
- """
-
- return (ax.get_position(True).frozen(),
- ax.get_position().frozen())
-
- def update_home_views(self, figure=None):
- """
- Make sure that self.home_views has an entry for all axes present in the
- figure
- """
-
- if not figure:
- figure = self.figure
- for a in figure.get_axes():
- if a not in self.home_views[figure]:
- self.home_views[figure][a] = a._get_view()
-
- def refresh_locators(self):
- """Redraw the canvases, update the locators"""
- for a in self.figure.get_axes():
- xaxis = getattr(a, 'xaxis', None)
- yaxis = getattr(a, 'yaxis', None)
- zaxis = getattr(a, 'zaxis', None)
- locators = []
- if xaxis is not None:
- locators.append(xaxis.get_major_locator())
- locators.append(xaxis.get_minor_locator())
- if yaxis is not None:
- locators.append(yaxis.get_major_locator())
- locators.append(yaxis.get_minor_locator())
- if zaxis is not None:
- locators.append(zaxis.get_major_locator())
- locators.append(zaxis.get_minor_locator())
-
- for loc in locators:
- loc.refresh()
- self.figure.canvas.draw_idle()
-
- def home(self):
- """Recall the first view and position from the stack"""
- self.views[self.figure].home()
- self.positions[self.figure].home()
-
- def back(self):
- """Back one step in the stack of views and positions"""
- self.views[self.figure].back()
- self.positions[self.figure].back()
-
- def forward(self):
- """Forward one step in the stack of views and positions"""
- self.views[self.figure].forward()
- self.positions[self.figure].forward()
-
-
-class ViewsPositionsBase(ToolBase):
- """Base class for `ToolHome`, `ToolBack` and `ToolForward`"""
-
- _on_trigger = None
-
- def trigger(self, sender, event, data=None):
- self.toolmanager.get_tool(_views_positions).add_figure(self.figure)
- getattr(self.toolmanager.get_tool(_views_positions),
- self._on_trigger)()
- self.toolmanager.get_tool(_views_positions).update_view()
-
-
-class ToolHome(ViewsPositionsBase):
- """Restore the original view lim"""
-
- description = 'Reset original view'
- image = 'home'
- default_keymap = rcParams['keymap.home']
- _on_trigger = 'home'
-
-
-class ToolBack(ViewsPositionsBase):
- """Move back up the view lim stack"""
-
- description = 'Back to previous view'
- image = 'back'
- default_keymap = rcParams['keymap.back']
- _on_trigger = 'back'
-
-
-class ToolForward(ViewsPositionsBase):
- """Move forward in the view lim stack"""
-
- description = 'Forward to next view'
- image = 'forward'
- default_keymap = rcParams['keymap.forward']
- _on_trigger = 'forward'
-
-
-class ConfigureSubplotsBase(ToolBase):
- """Base tool for the configuration of subplots"""
-
- description = 'Configure subplots'
- image = 'subplots'
-
-
-class SaveFigureBase(ToolBase):
- """Base tool for figure saving"""
-
- description = 'Save the figure'
- image = 'filesave'
- default_keymap = rcParams['keymap.save']
-
-
-class ZoomPanBase(ToolToggleBase):
- """Base class for `ToolZoom` and `ToolPan`"""
- def __init__(self, *args):
- ToolToggleBase.__init__(self, *args)
- self._button_pressed = None
- self._xypress = None
- self._idPress = None
- self._idRelease = None
- self._idScroll = None
- self.base_scale = 2.
- self.scrollthresh = .5 # .5 second scroll threshold
- self.lastscroll = time.time()-self.scrollthresh
-
- def enable(self, event):
- """Connect press/release events and lock the canvas"""
- self.figure.canvas.widgetlock(self)
- self._idPress = self.figure.canvas.mpl_connect(
- 'button_press_event', self._press)
- self._idRelease = self.figure.canvas.mpl_connect(
- 'button_release_event', self._release)
- self._idScroll = self.figure.canvas.mpl_connect(
- 'scroll_event', self.scroll_zoom)
-
- def disable(self, event):
- """Release the canvas and disconnect press/release events"""
- self._cancel_action()
- self.figure.canvas.widgetlock.release(self)
- self.figure.canvas.mpl_disconnect(self._idPress)
- self.figure.canvas.mpl_disconnect(self._idRelease)
- self.figure.canvas.mpl_disconnect(self._idScroll)
-
- def trigger(self, sender, event, data=None):
- self.toolmanager.get_tool(_views_positions).add_figure(self.figure)
- ToolToggleBase.trigger(self, sender, event, data)
-
- def scroll_zoom(self, event):
- # https://gist.github.com/tacaswell/3144287
- if event.inaxes is None:
- return
-
- if event.button == 'up':
- # deal with zoom in
- scl = self.base_scale
- elif event.button == 'down':
- # deal with zoom out
- scl = 1/self.base_scale
- else:
- # deal with something that should never happen
- scl = 1
-
- ax = event.inaxes
- ax._set_view_from_bbox([event.x, event.y, scl])
-
- # If last scroll was done within the timing threshold, delete the
- # previous view
- if (time.time()-self.lastscroll) < self.scrollthresh:
- self.toolmanager.get_tool(_views_positions).back()
-
- self.figure.canvas.draw_idle() # force re-draw
-
- self.lastscroll = time.time()
- self.toolmanager.get_tool(_views_positions).push_current()
-
-
-class ToolZoom(ZoomPanBase):
- """Zoom to rectangle"""
-
- description = 'Zoom to rectangle'
- image = 'zoom_to_rect'
- default_keymap = rcParams['keymap.zoom']
- cursor = cursors.SELECT_REGION
- radio_group = 'default'
-
- def __init__(self, *args):
- ZoomPanBase.__init__(self, *args)
- self._ids_zoom = []
-
- def _cancel_action(self):
- for zoom_id in self._ids_zoom:
- self.figure.canvas.mpl_disconnect(zoom_id)
- self.toolmanager.trigger_tool('rubberband', self)
- self.toolmanager.get_tool(_views_positions).refresh_locators()
- self._xypress = None
- self._button_pressed = None
- self._ids_zoom = []
- return
-
- def _press(self, event):
- """the _press mouse button in zoom to rect mode callback"""
-
- # If we're already in the middle of a zoom, pressing another
- # button works to "cancel"
- if self._ids_zoom != []:
- self._cancel_action()
-
- if event.button == 1:
- self._button_pressed = 1
- elif event.button == 3:
- self._button_pressed = 3
- else:
- self._cancel_action()
- return
-
- x, y = event.x, event.y
-
- self._xypress = []
- for i, a in enumerate(self.figure.get_axes()):
- if (x is not None and y is not None and a.in_axes(event) and
- a.get_navigate() and a.can_zoom()):
- self._xypress.append((x, y, a, i, a._get_view()))
-
- id1 = self.figure.canvas.mpl_connect(
- 'motion_notify_event', self._mouse_move)
- id2 = self.figure.canvas.mpl_connect(
- 'key_press_event', self._switch_on_zoom_mode)
- id3 = self.figure.canvas.mpl_connect(
- 'key_release_event', self._switch_off_zoom_mode)
-
- self._ids_zoom = id1, id2, id3
- self._zoom_mode = event.key
-
- def _switch_on_zoom_mode(self, event):
- self._zoom_mode = event.key
- self._mouse_move(event)
-
- def _switch_off_zoom_mode(self, event):
- self._zoom_mode = None
- self._mouse_move(event)
-
- def _mouse_move(self, event):
- """the drag callback in zoom mode"""
-
- if self._xypress:
- x, y = event.x, event.y
- lastx, lasty, a, ind, view = self._xypress[0]
- (x1, y1), (x2, y2) = np.clip(
- [[lastx, lasty], [x, y]], a.bbox.min, a.bbox.max)
- if self._zoom_mode == "x":
- y1, y2 = a.bbox.intervaly
- elif self._zoom_mode == "y":
- x1, x2 = a.bbox.intervalx
- self.toolmanager.trigger_tool(
- 'rubberband', self, data=(x1, y1, x2, y2))
-
- def _release(self, event):
- """the release mouse button callback in zoom to rect mode"""
-
- for zoom_id in self._ids_zoom:
- self.figure.canvas.mpl_disconnect(zoom_id)
- self._ids_zoom = []
-
- if not self._xypress:
- self._cancel_action()
- return
-
- last_a = []
-
- for cur_xypress in self._xypress:
- x, y = event.x, event.y
- lastx, lasty, a, _ind, view = cur_xypress
- # ignore singular clicks - 5 pixels is a threshold
- if abs(x - lastx) < 5 or abs(y - lasty) < 5:
- self._cancel_action()
- return
-
- # detect twinx,y axes and avoid double zooming
- twinx, twiny = False, False
- if last_a:
- for la in last_a:
- if a.get_shared_x_axes().joined(a, la):
- twinx = True
- if a.get_shared_y_axes().joined(a, la):
- twiny = True
- last_a.append(a)
-
- if self._button_pressed == 1:
- direction = 'in'
- elif self._button_pressed == 3:
- direction = 'out'
- else:
- continue
-
- a._set_view_from_bbox((lastx, lasty, x, y), direction,
- self._zoom_mode, twinx, twiny)
-
- self._zoom_mode = None
- self.toolmanager.get_tool(_views_positions).push_current()
- self._cancel_action()
-
-
-class ToolPan(ZoomPanBase):
- """Pan axes with left mouse, zoom with right"""
-
- default_keymap = rcParams['keymap.pan']
- description = 'Pan axes with left mouse, zoom with right'
- image = 'move'
- cursor = cursors.MOVE
- radio_group = 'default'
-
- def __init__(self, *args):
- ZoomPanBase.__init__(self, *args)
- self._idDrag = None
-
- def _cancel_action(self):
- self._button_pressed = None
- self._xypress = []
- self.figure.canvas.mpl_disconnect(self._idDrag)
- self.toolmanager.messagelock.release(self)
- self.toolmanager.get_tool(_views_positions).refresh_locators()
-
- def _press(self, event):
- if event.button == 1:
- self._button_pressed = 1
- elif event.button == 3:
- self._button_pressed = 3
- else:
- self._cancel_action()
- return
-
- x, y = event.x, event.y
-
- self._xypress = []
- for i, a in enumerate(self.figure.get_axes()):
- if (x is not None and y is not None and a.in_axes(event) and
- a.get_navigate() and a.can_pan()):
- a.start_pan(x, y, event.button)
- self._xypress.append((a, i))
- self.toolmanager.messagelock(self)
- self._idDrag = self.figure.canvas.mpl_connect(
- 'motion_notify_event', self._mouse_move)
-
- def _release(self, event):
- if self._button_pressed is None:
- self._cancel_action()
- return
-
- self.figure.canvas.mpl_disconnect(self._idDrag)
- self.toolmanager.messagelock.release(self)
-
- for a, _ind in self._xypress:
- a.end_pan()
- if not self._xypress:
- self._cancel_action()
- return
-
- self.toolmanager.get_tool(_views_positions).push_current()
- self._cancel_action()
-
- def _mouse_move(self, event):
- for a, _ind in self._xypress:
- # safer to use the recorded button at the _press than current
- # button: # multiple button can get pressed during motion...
- a.drag_pan(self._button_pressed, event.key, event.x, event.y)
- self.toolmanager.canvas.draw_idle()
-
-
-default_tools = {'home': ToolHome, 'back': ToolBack, 'forward': ToolForward,
- 'zoom': ToolZoom, 'pan': ToolPan,
- 'subplots': 'ToolConfigureSubplots',
- 'save': 'ToolSaveFigure',
- 'grid': ToolGrid,
- 'grid_minor': ToolMinorGrid,
- 'fullscreen': ToolFullScreen,
- 'quit': ToolQuit,
- 'quit_all': ToolQuitAll,
- 'allnav': ToolEnableAllNavigation,
- 'nav': ToolEnableNavigation,
- 'xscale': ToolXScale,
- 'yscale': ToolYScale,
- 'position': ToolCursorPosition,
- _views_positions: ToolViewsPositions,
- 'cursor': 'ToolSetCursor',
- 'rubberband': 'ToolRubberband',
- }
-"""Default tools"""
-
-default_toolbar_tools = [['navigation', ['home', 'back', 'forward']],
- ['zoompan', ['pan', 'zoom', 'subplots']],
- ['io', ['save']]]
-"""Default tools in the toolbar"""
-
-
-def add_tools_to_manager(toolmanager, tools=default_tools):
- """
- Add multiple tools to `ToolManager`
-
- Parameters
- ----------
- toolmanager: ToolManager
- `backend_managers.ToolManager` object that will get the tools added
- tools : {str: class_like}, optional
- The tools to add in a {name: tool} dict, see `add_tool` for more
- info.
- """
-
- for name, tool in six.iteritems(tools):
- toolmanager.add_tool(name, tool)
-
-
-def add_tools_to_container(container, tools=default_toolbar_tools):
- """
- Add multiple tools to the container.
-
- Parameters
- ----------
- container: Container
- `backend_bases.ToolContainerBase` object that will get the tools added
- tools : list, optional
- List in the form
- [[group1, [tool1, tool2 ...]], [group2, [...]]]
- Where the tools given by tool1, and tool2 will display in group1.
- See `add_tool` for details.
- """
-
- for group, grouptools in tools:
- for position, tool in enumerate(grouptools):
- container.add_tool(tool, group, position)
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/__init__.py b/contrib/python/matplotlib/py2/matplotlib/backends/__init__.py
deleted file mode 100644
index 33c60d8550..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/__init__.py
+++ /dev/null
@@ -1,97 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import matplotlib
-import inspect
-import traceback
-import warnings
-import logging
-
-_log = logging.getLogger(__name__)
-
-backend = matplotlib.get_backend()
-# the `str` calls here are to make non-ascii paths work on python2
-_backend_loading_tb = str("").join(
- line for line in traceback.format_stack()
- # Filter out line noise from importlib line.
- if not line.startswith(str(' File "<frozen importlib._bootstrap')))
-
-
-def pylab_setup(name=None):
- '''return new_figure_manager, draw_if_interactive and show for pyplot
-
- This provides the backend-specific functions that are used by
- pyplot to abstract away the difference between interactive backends.
-
- Parameters
- ----------
- name : str, optional
- The name of the backend to use. If `None`, falls back to
- ``matplotlib.get_backend()`` (which return :rc:`backend`).
-
- Returns
- -------
- backend_mod : module
- The module which contains the backend of choice
-
- new_figure_manager : function
- Create a new figure manager (roughly maps to GUI window)
-
- draw_if_interactive : function
- Redraw the current figure if pyplot is interactive
-
- show : function
- Show (and possibly block) any unshown figures.
-
- '''
- # Import the requested backend into a generic module object
- if name is None:
- # validates, to match all_backends
- name = matplotlib.get_backend()
- if name.startswith('module://'):
- backend_name = name[9:]
- else:
- backend_name = 'backend_' + name
- backend_name = backend_name.lower() # until we banish mixed case
- backend_name = 'matplotlib.backends.%s' % backend_name.lower()
-
- # the last argument is specifies whether to use absolute or relative
- # imports. 0 means only perform absolute imports.
- backend_mod = __import__(backend_name, globals(), locals(),
- [backend_name], 0)
-
- # Things we pull in from all backends
- new_figure_manager = backend_mod.new_figure_manager
-
- # image backends like pdf, agg or svg do not need to do anything
- # for "show" or "draw_if_interactive", so if they are not defined
- # by the backend, just do nothing
- def do_nothing_show(*args, **kwargs):
- frame = inspect.currentframe()
- fname = frame.f_back.f_code.co_filename
- if fname in ('<stdin>', '<ipython console>'):
- warnings.warn("""
-Your currently selected backend, '%s' does not support show().
-Please select a GUI backend in your matplotlibrc file ('%s')
-or with matplotlib.use()""" %
- (name, matplotlib.matplotlib_fname()))
-
- def do_nothing(*args, **kwargs):
- pass
-
- backend_version = getattr(backend_mod, 'backend_version', 'unknown')
-
- show = getattr(backend_mod, 'show', do_nothing_show)
-
- draw_if_interactive = getattr(backend_mod, 'draw_if_interactive',
- do_nothing)
-
- _log.debug('backend %s version %s', name, backend_version)
-
- # need to keep a global reference to the backend for compatibility
- # reasons. See https://github.com/matplotlib/matplotlib/issues/6092
- global backend
- backend = name
- return backend_mod, new_figure_manager, draw_if_interactive, show
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/_backend_tk.py b/contrib/python/matplotlib/py2/matplotlib/backends/_backend_tk.py
deleted file mode 100644
index da404b6e1b..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/_backend_tk.py
+++ /dev/null
@@ -1,1075 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import tkinter as Tk
-
-import logging
-import os.path
-import sys
-
-# Paint image to Tk photo blitter extension
-import matplotlib.backends.tkagg as tkagg
-
-from matplotlib.backends.backend_agg import FigureCanvasAgg
-import matplotlib.backends.windowing as windowing
-
-import matplotlib
-from matplotlib import backend_tools, cbook, rcParams
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2,
- StatusbarBase, TimerBase, ToolContainerBase, cursors)
-from matplotlib.backend_managers import ToolManager
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.figure import Figure
-from matplotlib.widgets import SubplotTool
-
-
-_log = logging.getLogger(__name__)
-
-backend_version = Tk.TkVersion
-
-# the true dots per inch on the screen; should be display dependent
-# see http://groups.google.com/groups?q=screen+dpi+x11&hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=7077.26e81ad5%40swift.cs.tcd.ie&rnum=5 for some info about screen dpi
-PIXELS_PER_INCH = 75
-
-cursord = {
- cursors.MOVE: "fleur",
- cursors.HAND: "hand2",
- cursors.POINTER: "arrow",
- cursors.SELECT_REGION: "tcross",
- cursors.WAIT: "watch",
- }
-
-
-def raise_msg_to_str(msg):
- """msg is a return arg from a raise. Join with new lines"""
- if not isinstance(msg, six.string_types):
- msg = '\n'.join(map(str, msg))
- return msg
-
-def error_msg_tkpaint(msg, parent=None):
- from six.moves import tkinter_messagebox as tkMessageBox
- tkMessageBox.showerror("matplotlib", msg)
-
-
-class TimerTk(TimerBase):
- '''
- Subclass of :class:`backend_bases.TimerBase` that uses Tk's timer events.
-
- Attributes
- ----------
- interval : int
- The time between timer events in milliseconds. Default is 1000 ms.
- single_shot : bool
- Boolean flag indicating whether this timer should operate as single
- shot (run once and then stop). Defaults to False.
- callbacks : list
- Stores list of (func, args) tuples that will be called upon timer
- events. This list can be manipulated directly, or the functions
- `add_callback` and `remove_callback` can be used.
-
- '''
- def __init__(self, parent, *args, **kwargs):
- TimerBase.__init__(self, *args, **kwargs)
- self.parent = parent
- self._timer = None
-
- def _timer_start(self):
- self._timer_stop()
- self._timer = self.parent.after(self._interval, self._on_timer)
-
- def _timer_stop(self):
- if self._timer is not None:
- self.parent.after_cancel(self._timer)
- self._timer = None
-
- def _on_timer(self):
- TimerBase._on_timer(self)
-
- # Tk after() is only a single shot, so we need to add code here to
- # reset the timer if we're not operating in single shot mode. However,
- # if _timer is None, this means that _timer_stop has been called; so
- # don't recreate the timer in that case.
- if not self._single and self._timer:
- self._timer = self.parent.after(self._interval, self._on_timer)
- else:
- self._timer = None
-
-
-class FigureCanvasTk(FigureCanvasBase):
- keyvald = {65507 : 'control',
- 65505 : 'shift',
- 65513 : 'alt',
- 65515 : 'super',
- 65508 : 'control',
- 65506 : 'shift',
- 65514 : 'alt',
- 65361 : 'left',
- 65362 : 'up',
- 65363 : 'right',
- 65364 : 'down',
- 65307 : 'escape',
- 65470 : 'f1',
- 65471 : 'f2',
- 65472 : 'f3',
- 65473 : 'f4',
- 65474 : 'f5',
- 65475 : 'f6',
- 65476 : 'f7',
- 65477 : 'f8',
- 65478 : 'f9',
- 65479 : 'f10',
- 65480 : 'f11',
- 65481 : 'f12',
- 65300 : 'scroll_lock',
- 65299 : 'break',
- 65288 : 'backspace',
- 65293 : 'enter',
- 65379 : 'insert',
- 65535 : 'delete',
- 65360 : 'home',
- 65367 : 'end',
- 65365 : 'pageup',
- 65366 : 'pagedown',
- 65438 : '0',
- 65436 : '1',
- 65433 : '2',
- 65435 : '3',
- 65430 : '4',
- 65437 : '5',
- 65432 : '6',
- 65429 : '7',
- 65431 : '8',
- 65434 : '9',
- 65451 : '+',
- 65453 : '-',
- 65450 : '*',
- 65455 : '/',
- 65439 : 'dec',
- 65421 : 'enter',
- }
-
- _keycode_lookup = {
- 262145: 'control',
- 524320: 'alt',
- 524352: 'alt',
- 1048584: 'super',
- 1048592: 'super',
- 131074: 'shift',
- 131076: 'shift',
- }
- """_keycode_lookup is used for badly mapped (i.e. no event.key_sym set)
- keys on apple keyboards."""
-
- def __init__(self, figure, master=None, resize_callback=None):
- super(FigureCanvasTk, self).__init__(figure)
- self._idle = True
- self._idle_callback = None
- t1,t2,w,h = self.figure.bbox.bounds
- w, h = int(w), int(h)
- self._tkcanvas = Tk.Canvas(
- master=master, background="white",
- width=w, height=h, borderwidth=0, highlightthickness=0)
- self._tkphoto = Tk.PhotoImage(
- master=self._tkcanvas, width=w, height=h)
- self._tkcanvas.create_image(w//2, h//2, image=self._tkphoto)
- self._resize_callback = resize_callback
- self._tkcanvas.bind("<Configure>", self.resize)
- self._tkcanvas.bind("<Key>", self.key_press)
- self._tkcanvas.bind("<Motion>", self.motion_notify_event)
- self._tkcanvas.bind("<KeyRelease>", self.key_release)
- for name in "<Button-1>", "<Button-2>", "<Button-3>":
- self._tkcanvas.bind(name, self.button_press_event)
- for name in "<Double-Button-1>", "<Double-Button-2>", "<Double-Button-3>":
- self._tkcanvas.bind(name, self.button_dblclick_event)
- for name in "<ButtonRelease-1>", "<ButtonRelease-2>", "<ButtonRelease-3>":
- self._tkcanvas.bind(name, self.button_release_event)
-
- # Mouse wheel on Linux generates button 4/5 events
- for name in "<Button-4>", "<Button-5>":
- self._tkcanvas.bind(name, self.scroll_event)
- # Mouse wheel for windows goes to the window with the focus.
- # Since the canvas won't usually have the focus, bind the
- # event to the window containing the canvas instead.
- # See http://wiki.tcl.tk/3893 (mousewheel) for details
- root = self._tkcanvas.winfo_toplevel()
- root.bind("<MouseWheel>", self.scroll_event_windows, "+")
-
- # Can't get destroy events by binding to _tkcanvas. Therefore, bind
- # to the window and filter.
- def filter_destroy(evt):
- if evt.widget is self._tkcanvas:
- self._master.update_idletasks()
- self.close_event()
- root.bind("<Destroy>", filter_destroy, "+")
-
- self._master = master
- self._tkcanvas.focus_set()
-
- def resize(self, event):
- width, height = event.width, event.height
- if self._resize_callback is not None:
- self._resize_callback(event)
-
- # compute desired figure size in inches
- dpival = self.figure.dpi
- winch = width/dpival
- hinch = height/dpival
- self.figure.set_size_inches(winch, hinch, forward=False)
-
-
- self._tkcanvas.delete(self._tkphoto)
- self._tkphoto = Tk.PhotoImage(
- master=self._tkcanvas, width=int(width), height=int(height))
- self._tkcanvas.create_image(int(width/2),int(height/2),image=self._tkphoto)
- self.resize_event()
- self.draw()
-
- # a resizing will in general move the pointer position
- # relative to the canvas, so process it as a motion notify
- # event. An intended side effect of this call is to allow
- # window raises (which trigger a resize) to get the cursor
- # position to the mpl event framework so key presses which are
- # over the axes will work w/o clicks or explicit motion
- self._update_pointer_position(event)
-
- def _update_pointer_position(self, guiEvent=None):
- """
- Figure out if we are inside the canvas or not and update the
- canvas enter/leave events
- """
- # if the pointer if over the canvas, set the lastx and lasty
- # attrs of the canvas so it can process event w/o mouse click
- # or move
-
- # the window's upper, left coords in screen coords
- xw = self._tkcanvas.winfo_rootx()
- yw = self._tkcanvas.winfo_rooty()
- # the pointer's location in screen coords
- xp, yp = self._tkcanvas.winfo_pointerxy()
-
- # not figure out the canvas coordinates of the pointer
- xc = xp - xw
- yc = yp - yw
-
- # flip top/bottom
- yc = self.figure.bbox.height - yc
-
- # JDH: this method was written originally to get the pointer
- # location to the backend lastx and lasty attrs so that events
- # like KeyEvent can be handled without mouse events. e.g., if
- # the cursor is already above the axes, then key presses like
- # 'g' should toggle the grid. In order for this to work in
- # backend_bases, the canvas needs to know _lastx and _lasty.
- # There are three ways to get this info the canvas:
- #
- # 1) set it explicitly
- #
- # 2) call enter/leave events explicitly. The downside of this
- # in the impl below is that enter could be repeatedly
- # triggered if the mouse is over the axes and one is
- # resizing with the keyboard. This is not entirely bad,
- # because the mouse position relative to the canvas is
- # changing, but it may be surprising to get repeated entries
- # without leaves
- #
- # 3) process it as a motion notify event. This also has pros
- # and cons. The mouse is moving relative to the window, but
- # this may surpise an event handler writer who is getting
- # motion_notify_events even if the mouse has not moved
-
- # here are the three scenarios
- if 1:
- # just manually set it
- self._lastx, self._lasty = xc, yc
- elif 0:
- # alternate implementation: process it as a motion
- FigureCanvasBase.motion_notify_event(self, xc, yc, guiEvent)
- elif 0:
- # alternate implementation -- process enter/leave events
- # instead of motion/notify
- if self.figure.bbox.contains(xc, yc):
- self.enter_notify_event(guiEvent, xy=(xc,yc))
- else:
- self.leave_notify_event(guiEvent)
-
- show = cbook.deprecated("2.2", name="FigureCanvasTk.show",
- alternative="FigureCanvasTk.draw")(
- lambda self: self.draw())
-
- def draw_idle(self):
- 'update drawing area only if idle'
- if self._idle is False:
- return
-
- self._idle = False
-
- def idle_draw(*args):
- try:
- self.draw()
- finally:
- self._idle = True
-
- self._idle_callback = self._tkcanvas.after_idle(idle_draw)
-
- def get_tk_widget(self):
- """returns the Tk widget used to implement FigureCanvasTkAgg.
- Although the initial implementation uses a Tk canvas, this routine
- is intended to hide that fact.
- """
- return self._tkcanvas
-
- def motion_notify_event(self, event):
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.figure.bbox.height - event.y
- FigureCanvasBase.motion_notify_event(self, x, y, guiEvent=event)
-
-
- def button_press_event(self, event, dblclick=False):
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.figure.bbox.height - event.y
- num = getattr(event, 'num', None)
-
- if sys.platform=='darwin':
- # 2 and 3 were reversed on the OSX platform I
- # tested under tkagg
- if num==2: num=3
- elif num==3: num=2
-
- FigureCanvasBase.button_press_event(self, x, y, num, dblclick=dblclick, guiEvent=event)
-
- def button_dblclick_event(self,event):
- self.button_press_event(event,dblclick=True)
-
- def button_release_event(self, event):
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.figure.bbox.height - event.y
-
- num = getattr(event, 'num', None)
-
- if sys.platform=='darwin':
- # 2 and 3 were reversed on the OSX platform I
- # tested under tkagg
- if num==2: num=3
- elif num==3: num=2
-
- FigureCanvasBase.button_release_event(self, x, y, num, guiEvent=event)
-
- def scroll_event(self, event):
- x = event.x
- y = self.figure.bbox.height - event.y
- num = getattr(event, 'num', None)
- if num==4: step = +1
- elif num==5: step = -1
- else: step = 0
-
- FigureCanvasBase.scroll_event(self, x, y, step, guiEvent=event)
-
- def scroll_event_windows(self, event):
- """MouseWheel event processor"""
- # need to find the window that contains the mouse
- w = event.widget.winfo_containing(event.x_root, event.y_root)
- if w == self._tkcanvas:
- x = event.x_root - w.winfo_rootx()
- y = event.y_root - w.winfo_rooty()
- y = self.figure.bbox.height - y
- step = event.delta/120.
- FigureCanvasBase.scroll_event(self, x, y, step, guiEvent=event)
-
- def _get_key(self, event):
- val = event.keysym_num
- if val in self.keyvald:
- key = self.keyvald[val]
- elif val == 0 and sys.platform == 'darwin' and \
- event.keycode in self._keycode_lookup:
- key = self._keycode_lookup[event.keycode]
- elif val < 256:
- key = chr(val)
- else:
- key = None
-
- # add modifier keys to the key string. Bit details originate from
- # http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm
- # BIT_SHIFT = 0x001; BIT_CAPSLOCK = 0x002; BIT_CONTROL = 0x004;
- # BIT_LEFT_ALT = 0x008; BIT_NUMLOCK = 0x010; BIT_RIGHT_ALT = 0x080;
- # BIT_MB_1 = 0x100; BIT_MB_2 = 0x200; BIT_MB_3 = 0x400;
- # In general, the modifier key is excluded from the modifier flag,
- # however this is not the case on "darwin", so double check that
- # we aren't adding repeat modifier flags to a modifier key.
- if sys.platform == 'win32':
- modifiers = [(17, 'alt', 'alt'),
- (2, 'ctrl', 'control'),
- ]
- elif sys.platform == 'darwin':
- modifiers = [(3, 'super', 'super'),
- (4, 'alt', 'alt'),
- (2, 'ctrl', 'control'),
- ]
- else:
- modifiers = [(6, 'super', 'super'),
- (3, 'alt', 'alt'),
- (2, 'ctrl', 'control'),
- ]
-
- if key is not None:
- # note, shift is not added to the keys as this is already accounted for
- for bitmask, prefix, key_name in modifiers:
- if event.state & (1 << bitmask) and key_name not in key:
- key = '{0}+{1}'.format(prefix, key)
-
- return key
-
- def key_press(self, event):
- key = self._get_key(event)
- FigureCanvasBase.key_press_event(self, key, guiEvent=event)
-
- def key_release(self, event):
- key = self._get_key(event)
- FigureCanvasBase.key_release_event(self, key, guiEvent=event)
-
- def new_timer(self, *args, **kwargs):
- """
- Creates a new backend-specific subclass of :class:`backend_bases.Timer`.
- This is useful for getting periodic events through the backend's native
- event loop. Implemented only for backends with GUIs.
-
- Other Parameters
- ----------------
- interval : scalar
- Timer interval in milliseconds
- callbacks : list
- Sequence of (func, args, kwargs) where ``func(*args, **kwargs)``
- will be executed by the timer every *interval*.
-
- """
- return TimerTk(self._tkcanvas, *args, **kwargs)
-
- def flush_events(self):
- self._master.update()
-
-
-class FigureManagerTk(FigureManagerBase):
- """
- Attributes
- ----------
- canvas : `FigureCanvas`
- The FigureCanvas instance
- num : int or str
- The Figure number
- toolbar : tk.Toolbar
- The tk.Toolbar
- window : tk.Window
- The tk.Window
-
- """
- def __init__(self, canvas, num, window):
- FigureManagerBase.__init__(self, canvas, num)
- self.window = window
- self.window.withdraw()
- self.set_window_title("Figure %d" % num)
- self.canvas = canvas
- # If using toolmanager it has to be present when initializing the toolbar
- self.toolmanager = self._get_toolmanager()
- # packing toolbar first, because if space is getting low, last packed widget is getting shrunk first (-> the canvas)
- self.toolbar = self._get_toolbar()
- self.canvas._tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
- self._num = num
-
- self.statusbar = None
-
- if self.toolmanager:
- backend_tools.add_tools_to_manager(self.toolmanager)
- if self.toolbar:
- backend_tools.add_tools_to_container(self.toolbar)
- self.statusbar = StatusbarTk(self.window, self.toolmanager)
-
- self._shown = False
-
- def notify_axes_change(fig):
- 'this will be called whenever the current axes is changed'
- if self.toolmanager is not None:
- pass
- elif self.toolbar is not None:
- self.toolbar.update()
- self.canvas.figure.add_axobserver(notify_axes_change)
-
- def _get_toolbar(self):
- if matplotlib.rcParams['toolbar'] == 'toolbar2':
- toolbar = NavigationToolbar2Tk(self.canvas, self.window)
- elif matplotlib.rcParams['toolbar'] == 'toolmanager':
- toolbar = ToolbarTk(self.toolmanager, self.window)
- else:
- toolbar = None
- return toolbar
-
- def _get_toolmanager(self):
- if rcParams['toolbar'] == 'toolmanager':
- toolmanager = ToolManager(self.canvas.figure)
- else:
- toolmanager = None
- return toolmanager
-
- def resize(self, width, height=None):
- # before 09-12-22, the resize method takes a single *event*
- # parameter. On the other hand, the resize method of other
- # FigureManager class takes *width* and *height* parameter,
- # which is used to change the size of the window. For the
- # Figure.set_size_inches with forward=True work with Tk
- # backend, I changed the function signature but tried to keep
- # it backward compatible. -JJL
-
- # when a single parameter is given, consider it as a event
- if height is None:
- cbook.warn_deprecated("2.2", "FigureManagerTkAgg.resize now takes "
- "width and height as separate arguments")
- width = width.width
- else:
- self.canvas._tkcanvas.master.geometry("%dx%d" % (width, height))
-
- if self.toolbar is not None:
- self.toolbar.configure(width=width)
-
- def show(self):
- """
- this function doesn't segfault but causes the
- PyEval_RestoreThread: NULL state bug on win32
- """
- _focus = windowing.FocusManager()
- if not self._shown:
- def destroy(*args):
- self.window = None
- Gcf.destroy(self._num)
- self.canvas._tkcanvas.bind("<Destroy>", destroy)
- self.window.deiconify()
- else:
- self.canvas.draw_idle()
- # Raise the new window.
- self.canvas.manager.window.attributes('-topmost', 1)
- self.canvas.manager.window.attributes('-topmost', 0)
- self._shown = True
-
- def destroy(self, *args):
- if self.window is not None:
- #self.toolbar.destroy()
- if self.canvas._idle_callback:
- self.canvas._tkcanvas.after_cancel(self.canvas._idle_callback)
- self.window.destroy()
- if Gcf.get_num_fig_managers()==0:
- if self.window is not None:
- self.window.quit()
- self.window = None
-
- def get_window_title(self):
- return self.window.wm_title()
-
- def set_window_title(self, title):
- self.window.wm_title(title)
-
- def full_screen_toggle(self):
- is_fullscreen = bool(self.window.attributes('-fullscreen'))
- self.window.attributes('-fullscreen', not is_fullscreen)
-
-
-@cbook.deprecated("2.2")
-class AxisMenu(object):
- def __init__(self, master, naxes):
- self._master = master
- self._naxes = naxes
- self._mbar = Tk.Frame(master=master, relief=Tk.RAISED, borderwidth=2)
- self._mbar.pack(side=Tk.LEFT)
- self._mbutton = Tk.Menubutton(
- master=self._mbar, text="Axes", underline=0)
- self._mbutton.pack(side=Tk.LEFT, padx="2m")
- self._mbutton.menu = Tk.Menu(self._mbutton)
- self._mbutton.menu.add_command(
- label="Select All", command=self.select_all)
- self._mbutton.menu.add_command(
- label="Invert All", command=self.invert_all)
- self._axis_var = []
- self._checkbutton = []
- for i in range(naxes):
- self._axis_var.append(Tk.IntVar())
- self._axis_var[i].set(1)
- self._checkbutton.append(self._mbutton.menu.add_checkbutton(
- label = "Axis %d" % (i+1),
- variable=self._axis_var[i],
- command=self.set_active))
- self._mbutton.menu.invoke(self._mbutton.menu.index("Select All"))
- self._mbutton['menu'] = self._mbutton.menu
- self._mbar.tk_menuBar(self._mbutton)
- self.set_active()
-
- def adjust(self, naxes):
- if self._naxes < naxes:
- for i in range(self._naxes, naxes):
- self._axis_var.append(Tk.IntVar())
- self._axis_var[i].set(1)
- self._checkbutton.append( self._mbutton.menu.add_checkbutton(
- label = "Axis %d" % (i+1),
- variable=self._axis_var[i],
- command=self.set_active))
- elif self._naxes > naxes:
- for i in range(self._naxes-1, naxes-1, -1):
- del self._axis_var[i]
- self._mbutton.menu.forget(self._checkbutton[i])
- del self._checkbutton[i]
- self._naxes = naxes
- self.set_active()
-
- def get_indices(self):
- a = [i for i in range(len(self._axis_var)) if self._axis_var[i].get()]
- return a
-
- def set_active(self):
- self._master.set_active(self.get_indices())
-
- def invert_all(self):
- for a in self._axis_var:
- a.set(not a.get())
- self.set_active()
-
- def select_all(self):
- for a in self._axis_var:
- a.set(1)
- self.set_active()
-
-
-class NavigationToolbar2Tk(NavigationToolbar2, Tk.Frame):
- """
- Attributes
- ----------
- canvas : `FigureCanvas`
- the figure canvas on which to operate
- win : tk.Window
- the tk.Window which owns this toolbar
-
- """
- def __init__(self, canvas, window):
- self.canvas = canvas
- self.window = window
- NavigationToolbar2.__init__(self, canvas)
-
- def destroy(self, *args):
- del self.message
- Tk.Frame.destroy(self, *args)
-
- def set_message(self, s):
- self.message.set(s)
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- height = self.canvas.figure.bbox.height
- y0 = height - y0
- y1 = height - y1
- if hasattr(self, "lastrect"):
- self.canvas._tkcanvas.delete(self.lastrect)
- self.lastrect = self.canvas._tkcanvas.create_rectangle(x0, y0, x1, y1)
-
- #self.canvas.draw()
-
- def release(self, event):
- try: self.lastrect
- except AttributeError: pass
- else:
- self.canvas._tkcanvas.delete(self.lastrect)
- del self.lastrect
-
- def set_cursor(self, cursor):
- self.window.configure(cursor=cursord[cursor])
- self.window.update_idletasks()
-
- def _Button(self, text, file, command, extension='.gif'):
- img_file = os.path.join(
- rcParams['datapath'], 'images', file + extension)
- im = Tk.PhotoImage(master=self, file=img_file)
- b = Tk.Button(
- master=self, text=text, padx=2, pady=2, image=im, command=command)
- b._ntimage = im
- b.pack(side=Tk.LEFT)
- return b
-
- def _Spacer(self):
- # Buttons are 30px high, so make this 26px tall with padding to center it
- s = Tk.Frame(
- master=self, height=26, relief=Tk.RIDGE, pady=2, bg="DarkGray")
- s.pack(side=Tk.LEFT, padx=5)
- return s
-
- def _init_toolbar(self):
- xmin, xmax = self.canvas.figure.bbox.intervalx
- height, width = 50, xmax-xmin
- Tk.Frame.__init__(self, master=self.window,
- width=int(width), height=int(height),
- borderwidth=2)
-
- self.update() # Make axes menu
-
- for text, tooltip_text, image_file, callback in self.toolitems:
- if text is None:
- # Add a spacer; return value is unused.
- self._Spacer()
- else:
- button = self._Button(text=text, file=image_file,
- command=getattr(self, callback))
- if tooltip_text is not None:
- ToolTip.createToolTip(button, tooltip_text)
-
- self.message = Tk.StringVar(master=self)
- self._message_label = Tk.Label(master=self, textvariable=self.message)
- self._message_label.pack(side=Tk.RIGHT)
- self.pack(side=Tk.BOTTOM, fill=Tk.X)
-
- def configure_subplots(self):
- toolfig = Figure(figsize=(6,3))
- window = Tk.Toplevel()
- canvas = type(self.canvas)(toolfig, master=window)
- toolfig.subplots_adjust(top=0.9)
- canvas.tool = SubplotTool(self.canvas.figure, toolfig)
- canvas.draw()
- canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
- window.grab_set()
-
- def save_figure(self, *args):
- from six.moves import tkinter_tkfiledialog, tkinter_messagebox
- filetypes = self.canvas.get_supported_filetypes().copy()
- default_filetype = self.canvas.get_default_filetype()
-
- # Tk doesn't provide a way to choose a default filetype,
- # so we just have to put it first
- default_filetype_name = filetypes.pop(default_filetype)
- sorted_filetypes = ([(default_filetype, default_filetype_name)]
- + sorted(six.iteritems(filetypes)))
- tk_filetypes = [(name, '*.%s' % ext) for ext, name in sorted_filetypes]
-
- # adding a default extension seems to break the
- # asksaveasfilename dialog when you choose various save types
- # from the dropdown. Passing in the empty string seems to
- # work - JDH!
- #defaultextension = self.canvas.get_default_filetype()
- defaultextension = ''
- initialdir = os.path.expanduser(rcParams['savefig.directory'])
- initialfile = self.canvas.get_default_filename()
- fname = tkinter_tkfiledialog.asksaveasfilename(
- master=self.window,
- title='Save the figure',
- filetypes=tk_filetypes,
- defaultextension=defaultextension,
- initialdir=initialdir,
- initialfile=initialfile,
- )
-
- if fname in ["", ()]:
- return
- # Save dir for next time, unless empty str (i.e., use cwd).
- if initialdir != "":
- rcParams['savefig.directory'] = (
- os.path.dirname(six.text_type(fname)))
- try:
- # This method will handle the delegation to the correct type
- self.canvas.figure.savefig(fname)
- except Exception as e:
- tkinter_messagebox.showerror("Error saving file", str(e))
-
- def set_active(self, ind):
- self._ind = ind
- self._active = [self._axes[i] for i in self._ind]
-
- def update(self):
- _focus = windowing.FocusManager()
- self._axes = self.canvas.figure.axes
- NavigationToolbar2.update(self)
-
-
-class ToolTip(object):
- """
- Tooltip recipe from
- http://www.voidspace.org.uk/python/weblog/arch_d7_2006_07_01.shtml#e387
- """
- @staticmethod
- def createToolTip(widget, text):
- toolTip = ToolTip(widget)
- def enter(event):
- toolTip.showtip(text)
- def leave(event):
- toolTip.hidetip()
- widget.bind('<Enter>', enter)
- widget.bind('<Leave>', leave)
-
- def __init__(self, widget):
- self.widget = widget
- self.tipwindow = None
- self.id = None
- self.x = self.y = 0
-
- def showtip(self, text):
- "Display text in tooltip window"
- self.text = text
- if self.tipwindow or not self.text:
- return
- x, y, _, _ = self.widget.bbox("insert")
- x = x + self.widget.winfo_rootx() + 27
- y = y + self.widget.winfo_rooty()
- self.tipwindow = tw = Tk.Toplevel(self.widget)
- tw.wm_overrideredirect(1)
- tw.wm_geometry("+%d+%d" % (x, y))
- try:
- # For Mac OS
- tw.tk.call("::tk::unsupported::MacWindowStyle",
- "style", tw._w,
- "help", "noActivates")
- except Tk.TclError:
- pass
- label = Tk.Label(tw, text=self.text, justify=Tk.LEFT,
- background="#ffffe0", relief=Tk.SOLID, borderwidth=1)
- label.pack(ipadx=1)
-
- def hidetip(self):
- tw = self.tipwindow
- self.tipwindow = None
- if tw:
- tw.destroy()
-
-
-class RubberbandTk(backend_tools.RubberbandBase):
- def __init__(self, *args, **kwargs):
- backend_tools.RubberbandBase.__init__(self, *args, **kwargs)
-
- def draw_rubberband(self, x0, y0, x1, y1):
- height = self.figure.canvas.figure.bbox.height
- y0 = height - y0
- y1 = height - y1
- if hasattr(self, "lastrect"):
- self.figure.canvas._tkcanvas.delete(self.lastrect)
- self.lastrect = self.figure.canvas._tkcanvas.create_rectangle(
- x0, y0, x1, y1)
-
- def remove_rubberband(self):
- if hasattr(self, "lastrect"):
- self.figure.canvas._tkcanvas.delete(self.lastrect)
- del self.lastrect
-
-
-class SetCursorTk(backend_tools.SetCursorBase):
- def set_cursor(self, cursor):
- self.figure.canvas.manager.window.configure(cursor=cursord[cursor])
-
-
-class ToolbarTk(ToolContainerBase, Tk.Frame):
- _icon_extension = '.gif'
- def __init__(self, toolmanager, window):
- ToolContainerBase.__init__(self, toolmanager)
- xmin, xmax = self.toolmanager.canvas.figure.bbox.intervalx
- height, width = 50, xmax - xmin
- Tk.Frame.__init__(self, master=window,
- width=int(width), height=int(height),
- borderwidth=2)
- self._toolitems = {}
- self.pack(side=Tk.TOP, fill=Tk.X)
- self._groups = {}
-
- def add_toolitem(
- self, name, group, position, image_file, description, toggle):
- frame = self._get_groupframe(group)
- button = self._Button(name, image_file, toggle, frame)
- if description is not None:
- ToolTip.createToolTip(button, description)
- self._toolitems.setdefault(name, [])
- self._toolitems[name].append(button)
-
- def _get_groupframe(self, group):
- if group not in self._groups:
- if self._groups:
- self._add_separator()
- frame = Tk.Frame(master=self, borderwidth=0)
- frame.pack(side=Tk.LEFT, fill=Tk.Y)
- self._groups[group] = frame
- return self._groups[group]
-
- def _add_separator(self):
- separator = Tk.Frame(master=self, bd=5, width=1, bg='black')
- separator.pack(side=Tk.LEFT, fill=Tk.Y, padx=2)
-
- def _Button(self, text, image_file, toggle, frame):
- if image_file is not None:
- im = Tk.PhotoImage(master=self, file=image_file)
- else:
- im = None
-
- if not toggle:
- b = Tk.Button(master=frame, text=text, padx=2, pady=2, image=im,
- command=lambda: self._button_click(text))
- else:
- # There is a bug in tkinter included in some python 3.6 versions
- # that without this variable, produces a "visual" toggling of
- # other near checkbuttons
- # https://bugs.python.org/issue29402
- # https://bugs.python.org/issue25684
- var = Tk.IntVar()
- b = Tk.Checkbutton(master=frame, text=text, padx=2, pady=2,
- image=im, indicatoron=False,
- command=lambda: self._button_click(text),
- variable=var)
- b._ntimage = im
- b.pack(side=Tk.LEFT)
- return b
-
- def _button_click(self, name):
- self.trigger_tool(name)
-
- def toggle_toolitem(self, name, toggled):
- if name not in self._toolitems:
- return
- for toolitem in self._toolitems[name]:
- if toggled:
- toolitem.select()
- else:
- toolitem.deselect()
-
- def remove_toolitem(self, name):
- for toolitem in self._toolitems[name]:
- toolitem.pack_forget()
- del self._toolitems[name]
-
-
-class StatusbarTk(StatusbarBase, Tk.Frame):
- def __init__(self, window, *args, **kwargs):
- StatusbarBase.__init__(self, *args, **kwargs)
- xmin, xmax = self.toolmanager.canvas.figure.bbox.intervalx
- height, width = 50, xmax - xmin
- Tk.Frame.__init__(self, master=window,
- width=int(width), height=int(height),
- borderwidth=2)
- self._message = Tk.StringVar(master=self)
- self._message_label = Tk.Label(master=self, textvariable=self._message)
- self._message_label.pack(side=Tk.RIGHT)
- self.pack(side=Tk.TOP, fill=Tk.X)
-
- def set_message(self, s):
- self._message.set(s)
-
-
-class SaveFigureTk(backend_tools.SaveFigureBase):
- def trigger(self, *args):
- from six.moves import tkinter_tkfiledialog, tkinter_messagebox
- filetypes = self.figure.canvas.get_supported_filetypes().copy()
- default_filetype = self.figure.canvas.get_default_filetype()
-
- # Tk doesn't provide a way to choose a default filetype,
- # so we just have to put it first
- default_filetype_name = filetypes.pop(default_filetype)
- sorted_filetypes = ([(default_filetype, default_filetype_name)]
- + sorted(six.iteritems(filetypes)))
- tk_filetypes = [(name, '*.%s' % ext) for ext, name in sorted_filetypes]
-
- # adding a default extension seems to break the
- # asksaveasfilename dialog when you choose various save types
- # from the dropdown. Passing in the empty string seems to
- # work - JDH!
- # defaultextension = self.figure.canvas.get_default_filetype()
- defaultextension = ''
- initialdir = os.path.expanduser(rcParams['savefig.directory'])
- initialfile = self.figure.canvas.get_default_filename()
- fname = tkinter_tkfiledialog.asksaveasfilename(
- master=self.figure.canvas.manager.window,
- title='Save the figure',
- filetypes=tk_filetypes,
- defaultextension=defaultextension,
- initialdir=initialdir,
- initialfile=initialfile,
- )
-
- if fname == "" or fname == ():
- return
- else:
- if initialdir == '':
- # explicitly missing key or empty str signals to use cwd
- rcParams['savefig.directory'] = initialdir
- else:
- # save dir for next time
- rcParams['savefig.directory'] = os.path.dirname(
- six.text_type(fname))
- try:
- # This method will handle the delegation to the correct type
- self.figure.savefig(fname)
- except Exception as e:
- tkinter_messagebox.showerror("Error saving file", str(e))
-
-
-class ConfigureSubplotsTk(backend_tools.ConfigureSubplotsBase):
- def __init__(self, *args, **kwargs):
- backend_tools.ConfigureSubplotsBase.__init__(self, *args, **kwargs)
- self.window = None
-
- def trigger(self, *args):
- self.init_window()
- self.window.lift()
-
- def init_window(self):
- if self.window:
- return
-
- toolfig = Figure(figsize=(6, 3))
- self.window = Tk.Tk()
-
- canvas = type(self.canvas)(toolfig, master=self.window)
- toolfig.subplots_adjust(top=0.9)
- _tool = SubplotTool(self.figure, toolfig)
- canvas.draw()
- canvas.get_tk_widget().pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
- self.window.protocol("WM_DELETE_WINDOW", self.destroy)
-
- def destroy(self, *args, **kwargs):
- self.window.destroy()
- self.window = None
-
-
-backend_tools.ToolSaveFigure = SaveFigureTk
-backend_tools.ToolConfigureSubplots = ConfigureSubplotsTk
-backend_tools.ToolSetCursor = SetCursorTk
-backend_tools.ToolRubberband = RubberbandTk
-Toolbar = ToolbarTk
-
-
-@_Backend.export
-class _BackendTk(_Backend):
- FigureManager = FigureManagerTk
-
- @classmethod
- def new_figure_manager_given_figure(cls, num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- _focus = windowing.FocusManager()
- window = Tk.Tk(className="matplotlib")
- window.withdraw()
-
- # Put a mpl icon on the window rather than the default tk icon.
- # Tkinter doesn't allow colour icons on linux systems, but tk>=8.5 has
- # a iconphoto command which we call directly. Source:
- # http://mail.python.org/pipermail/tkinter-discuss/2006-November/000954.html
- icon_fname = os.path.join(
- rcParams['datapath'], 'images', 'matplotlib.ppm')
- icon_img = Tk.PhotoImage(file=icon_fname)
- try:
- window.tk.call('wm', 'iconphoto', window._w, icon_img)
- except Exception as exc:
- # log the failure (due e.g. to Tk version), but carry on
- _log.info('Could not load matplotlib icon: %s', exc)
-
- canvas = cls.FigureCanvas(figure, master=window)
- manager = cls.FigureManager(canvas, num, window)
- if matplotlib.is_interactive():
- manager.show()
- canvas.draw_idle()
- return manager
-
- @staticmethod
- def trigger_manager_draw(manager):
- manager.show()
-
- @staticmethod
- def mainloop():
- Tk.mainloop()
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/_gtk3_compat.py b/contrib/python/matplotlib/py2/matplotlib/backends/_gtk3_compat.py
deleted file mode 100644
index 825fa2341c..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/_gtk3_compat.py
+++ /dev/null
@@ -1,41 +0,0 @@
-"""
-GObject compatibility loader; supports ``gi`` and ``pgi``.
-
-The binding selection rules are as follows:
-- if ``gi`` has already been imported, use it; else
-- if ``pgi`` has already been imported, use it; else
-- if ``gi`` can be imported, use it; else
-- if ``pgi`` can be imported, use it; else
-- error out.
-
-Thus, to force usage of PGI when both bindings are installed, import it first.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import importlib
-import sys
-
-
-if "gi" in sys.modules:
- import gi
-elif "pgi" in sys.modules:
- import pgi as gi
-else:
- try:
- import gi
- except ImportError:
- try:
- import pgi as gi
- except ImportError:
- raise ImportError("The Gtk3 backend requires PyGObject or pgi")
-
-
-gi.require_version("Gtk", "3.0")
-globals().update(
- {name:
- importlib.import_module("{}.repository.{}".format(gi.__name__, name))
- for name in ["GLib", "GObject", "Gtk", "Gdk"]})
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_agg.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_agg.py
deleted file mode 100644
index 491a9b2c5d..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_agg.py
+++ /dev/null
@@ -1,606 +0,0 @@
-"""
-An agg http://antigrain.com/ backend
-
-Features that are implemented
-
- * capstyles and join styles
- * dashes
- * linewidth
- * lines, rectangles, ellipses
- * clipping to a rectangle
- * output to RGBA and PNG, optionally JPEG and TIFF
- * alpha blending
- * DPI scaling properly - everything scales properly (dashes, linewidths, etc)
- * draw polygon
- * freetype2 w/ ft2font
-
-TODO:
-
- * integrate screen dpi w/ ppi and text
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-try:
- import threading
-except ImportError:
- import dummy_threading as threading
-
-import numpy as np
-from collections import OrderedDict
-from math import radians, cos, sin
-from matplotlib import cbook, rcParams, __version__
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, RendererBase, cursors)
-from matplotlib.cbook import maxdict
-from matplotlib.figure import Figure
-from matplotlib.font_manager import findfont, get_font
-from matplotlib.ft2font import (LOAD_FORCE_AUTOHINT, LOAD_NO_HINTING,
- LOAD_DEFAULT, LOAD_NO_AUTOHINT)
-from matplotlib.mathtext import MathTextParser
-from matplotlib.path import Path
-from matplotlib.transforms import Bbox, BboxBase
-from matplotlib import colors as mcolors
-
-from matplotlib.backends._backend_agg import RendererAgg as _RendererAgg
-from matplotlib import _png
-
-try:
- from PIL import Image
- _has_pil = True
-except ImportError:
- _has_pil = False
-
-backend_version = 'v2.2'
-
-def get_hinting_flag():
- mapping = {
- True: LOAD_FORCE_AUTOHINT,
- False: LOAD_NO_HINTING,
- 'either': LOAD_DEFAULT,
- 'native': LOAD_NO_AUTOHINT,
- 'auto': LOAD_FORCE_AUTOHINT,
- 'none': LOAD_NO_HINTING
- }
- return mapping[rcParams['text.hinting']]
-
-
-class RendererAgg(RendererBase):
- """
- The renderer handles all the drawing primitives using a graphics
- context instance that controls the colors/styles
- """
-
- @property
- @cbook.deprecated("2.2")
- def debug(self):
- return 1
-
- # we want to cache the fonts at the class level so that when
- # multiple figures are created we can reuse them. This helps with
- # a bug on windows where the creation of too many figures leads to
- # too many open file handles. However, storing them at the class
- # level is not thread safe. The solution here is to let the
- # FigureCanvas acquire a lock on the fontd at the start of the
- # draw, and release it when it is done. This allows multiple
- # renderers to share the cached fonts, but only one figure can
- # draw at time and so the font cache is used by only one
- # renderer at a time.
-
- lock = threading.RLock()
-
- def __init__(self, width, height, dpi):
- RendererBase.__init__(self)
-
- self.dpi = dpi
- self.width = width
- self.height = height
- self._renderer = _RendererAgg(int(width), int(height), dpi)
- self._filter_renderers = []
-
- self._update_methods()
- self.mathtext_parser = MathTextParser('Agg')
-
- self.bbox = Bbox.from_bounds(0, 0, self.width, self.height)
-
- def __getstate__(self):
- # We only want to preserve the init keywords of the Renderer.
- # Anything else can be re-created.
- return {'width': self.width, 'height': self.height, 'dpi': self.dpi}
-
- def __setstate__(self, state):
- self.__init__(state['width'], state['height'], state['dpi'])
-
- def _get_hinting_flag(self):
- if rcParams['text.hinting']:
- return LOAD_FORCE_AUTOHINT
- else:
- return LOAD_NO_HINTING
-
- # for filtering to work with rasterization, methods needs to be wrapped.
- # maybe there is better way to do it.
- def draw_markers(self, *kl, **kw):
- return self._renderer.draw_markers(*kl, **kw)
-
- def draw_path_collection(self, *kl, **kw):
- return self._renderer.draw_path_collection(*kl, **kw)
-
- def _update_methods(self):
- self.draw_quad_mesh = self._renderer.draw_quad_mesh
- self.draw_gouraud_triangle = self._renderer.draw_gouraud_triangle
- self.draw_gouraud_triangles = self._renderer.draw_gouraud_triangles
- self.draw_image = self._renderer.draw_image
- self.copy_from_bbox = self._renderer.copy_from_bbox
- self.get_content_extents = self._renderer.get_content_extents
-
- def tostring_rgba_minimized(self):
- extents = self.get_content_extents()
- bbox = [[extents[0], self.height - (extents[1] + extents[3])],
- [extents[0] + extents[2], self.height - extents[1]]]
- region = self.copy_from_bbox(bbox)
- return np.array(region), extents
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- """
- Draw the path
- """
- nmax = rcParams['agg.path.chunksize'] # here at least for testing
- npts = path.vertices.shape[0]
-
- if (nmax > 100 and npts > nmax and path.should_simplify and
- rgbFace is None and gc.get_hatch() is None):
- nch = np.ceil(npts / nmax)
- chsize = int(np.ceil(npts / nch))
- i0 = np.arange(0, npts, chsize)
- i1 = np.zeros_like(i0)
- i1[:-1] = i0[1:] - 1
- i1[-1] = npts
- for ii0, ii1 in zip(i0, i1):
- v = path.vertices[ii0:ii1, :]
- c = path.codes
- if c is not None:
- c = c[ii0:ii1]
- c[0] = Path.MOVETO # move to end of last chunk
- p = Path(v, c)
- try:
- self._renderer.draw_path(gc, p, transform, rgbFace)
- except OverflowError:
- raise OverflowError("Exceeded cell block limit (set "
- "'agg.path.chunksize' rcparam)")
- else:
- try:
- self._renderer.draw_path(gc, path, transform, rgbFace)
- except OverflowError:
- raise OverflowError("Exceeded cell block limit (set "
- "'agg.path.chunksize' rcparam)")
-
-
- def draw_mathtext(self, gc, x, y, s, prop, angle):
- """
- Draw the math text using matplotlib.mathtext
- """
- ox, oy, width, height, descent, font_image, used_characters = \
- self.mathtext_parser.parse(s, self.dpi, prop)
-
- xd = descent * sin(radians(angle))
- yd = descent * cos(radians(angle))
- x = np.round(x + ox + xd)
- y = np.round(y - oy + yd)
- self._renderer.draw_text_image(font_image, x, y + 1, angle, gc)
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- """
- Render the text
- """
- if ismath:
- return self.draw_mathtext(gc, x, y, s, prop, angle)
-
- flags = get_hinting_flag()
- font = self._get_agg_font(prop)
-
- if font is None:
- return None
- if len(s) == 1 and ord(s) > 127:
- font.load_char(ord(s), flags=flags)
- else:
- # We pass '0' for angle here, since it will be rotated (in raster
- # space) in the following call to draw_text_image).
- font.set_text(s, 0, flags=flags)
- font.draw_glyphs_to_bitmap(antialiased=rcParams['text.antialiased'])
- d = font.get_descent() / 64.0
- # The descent needs to be adjusted for the angle.
- xo, yo = font.get_bitmap_offset()
- xo /= 64.0
- yo /= 64.0
- xd = -d * sin(radians(angle))
- yd = d * cos(radians(angle))
-
- self._renderer.draw_text_image(
- font, np.round(x - xd + xo), np.round(y + yd + yo) + 1, angle, gc)
-
- def get_text_width_height_descent(self, s, prop, ismath):
- """
- Get the width, height, and descent (offset from the bottom
- to the baseline), in display coords, of the string *s* with
- :class:`~matplotlib.font_manager.FontProperties` *prop*
- """
- if ismath in ["TeX", "TeX!"]:
- # todo: handle props
- size = prop.get_size_in_points()
- texmanager = self.get_texmanager()
- fontsize = prop.get_size_in_points()
- w, h, d = texmanager.get_text_width_height_descent(
- s, fontsize, renderer=self)
- return w, h, d
-
- if ismath:
- ox, oy, width, height, descent, fonts, used_characters = \
- self.mathtext_parser.parse(s, self.dpi, prop)
- return width, height, descent
-
- flags = get_hinting_flag()
- font = self._get_agg_font(prop)
- font.set_text(s, 0.0, flags=flags)
- w, h = font.get_width_height() # width and height of unrotated string
- d = font.get_descent()
- w /= 64.0 # convert from subpixels
- h /= 64.0
- d /= 64.0
- return w, h, d
-
- def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
- # todo, handle props, angle, origins
- size = prop.get_size_in_points()
-
- texmanager = self.get_texmanager()
-
- Z = texmanager.get_grey(s, size, self.dpi)
- Z = np.array(Z * 255.0, np.uint8)
-
- w, h, d = self.get_text_width_height_descent(s, prop, ismath)
- xd = d * sin(radians(angle))
- yd = d * cos(radians(angle))
- x = np.round(x + xd)
- y = np.round(y + yd)
-
- self._renderer.draw_text_image(Z, x, y, angle, gc)
-
- def get_canvas_width_height(self):
- 'return the canvas width and height in display coords'
- return self.width, self.height
-
- def _get_agg_font(self, prop):
- """
- Get the font for text instance t, cacheing for efficiency
- """
- fname = findfont(prop)
- font = get_font(fname)
-
- font.clear()
- size = prop.get_size_in_points()
- font.set_size(size, self.dpi)
-
- return font
-
- def points_to_pixels(self, points):
- """
- convert point measures to pixes using dpi and the pixels per
- inch of the display
- """
- return points*self.dpi/72.0
-
- def tostring_rgb(self):
- return self._renderer.tostring_rgb()
-
- def tostring_argb(self):
- return self._renderer.tostring_argb()
-
- def buffer_rgba(self):
- return self._renderer.buffer_rgba()
-
- def clear(self):
- self._renderer.clear()
-
- def option_image_nocomposite(self):
- # It is generally faster to composite each image directly to
- # the Figure, and there's no file size benefit to compositing
- # with the Agg backend
- return True
-
- def option_scale_image(self):
- """
- agg backend doesn't support arbitrary scaling of image.
- """
- return False
-
- def restore_region(self, region, bbox=None, xy=None):
- """
- Restore the saved region. If bbox (instance of BboxBase, or
- its extents) is given, only the region specified by the bbox
- will be restored. *xy* (a tuple of two floasts) optionally
- specifies the new position (the LLC of the original region,
- not the LLC of the bbox) where the region will be restored.
-
- >>> region = renderer.copy_from_bbox()
- >>> x1, y1, x2, y2 = region.get_extents()
- >>> renderer.restore_region(region, bbox=(x1+dx, y1, x2, y2),
- ... xy=(x1-dx, y1))
-
- """
- if bbox is not None or xy is not None:
- if bbox is None:
- x1, y1, x2, y2 = region.get_extents()
- elif isinstance(bbox, BboxBase):
- x1, y1, x2, y2 = bbox.extents
- else:
- x1, y1, x2, y2 = bbox
-
- if xy is None:
- ox, oy = x1, y1
- else:
- ox, oy = xy
-
- # The incoming data is float, but the _renderer type-checking wants
- # to see integers.
- self._renderer.restore_region(region, int(x1), int(y1),
- int(x2), int(y2), int(ox), int(oy))
-
- else:
- self._renderer.restore_region(region)
-
- def start_filter(self):
- """
- Start filtering. It simply create a new canvas (the old one is saved).
- """
- self._filter_renderers.append(self._renderer)
- self._renderer = _RendererAgg(int(self.width), int(self.height),
- self.dpi)
- self._update_methods()
-
- def stop_filter(self, post_processing):
- """
- Save the plot in the current canvas as a image and apply
- the *post_processing* function.
-
- def post_processing(image, dpi):
- # ny, nx, depth = image.shape
- # image (numpy array) has RGBA channels and has a depth of 4.
- ...
- # create a new_image (numpy array of 4 channels, size can be
- # different). The resulting image may have offsets from
- # lower-left corner of the original image
- return new_image, offset_x, offset_y
-
- The saved renderer is restored and the returned image from
- post_processing is plotted (using draw_image) on it.
- """
-
- # WARNING: For agg_filter to work, the renderer's method need to
- # overridden in the class. See draw_markers and draw_path_collections.
-
- width, height = int(self.width), int(self.height)
-
- buffer, bounds = self.tostring_rgba_minimized()
-
- l, b, w, h = bounds
-
- self._renderer = self._filter_renderers.pop()
- self._update_methods()
-
- if w > 0 and h > 0:
- img = np.frombuffer(buffer, np.uint8)
- img, ox, oy = post_processing(img.reshape((h, w, 4)) / 255.,
- self.dpi)
- gc = self.new_gc()
- if img.dtype.kind == 'f':
- img = np.asarray(img * 255., np.uint8)
- img = img[::-1]
- self._renderer.draw_image(
- gc, l + ox, height - b - h + oy, img)
-
-
-class FigureCanvasAgg(FigureCanvasBase):
- """
- The canvas the figure renders into. Calls the draw and print fig
- methods, creates the renderers, etc...
-
- Attributes
- ----------
- figure : `matplotlib.figure.Figure`
- A high-level Figure instance
-
- """
-
- def copy_from_bbox(self, bbox):
- renderer = self.get_renderer()
- return renderer.copy_from_bbox(bbox)
-
- def restore_region(self, region, bbox=None, xy=None):
- renderer = self.get_renderer()
- return renderer.restore_region(region, bbox, xy)
-
- def draw(self):
- """
- Draw the figure using the renderer
- """
- self.renderer = self.get_renderer(cleared=True)
- # acquire a lock on the shared font cache
- RendererAgg.lock.acquire()
-
- toolbar = self.toolbar
- try:
- # if toolbar:
- # toolbar.set_cursor(cursors.WAIT)
- self.figure.draw(self.renderer)
- # A GUI class may be need to update a window using this draw, so
- # don't forget to call the superclass.
- super(FigureCanvasAgg, self).draw()
- finally:
- # if toolbar:
- # toolbar.set_cursor(toolbar._lastCursor)
- RendererAgg.lock.release()
-
- def get_renderer(self, cleared=False):
- l, b, w, h = self.figure.bbox.bounds
- key = w, h, self.figure.dpi
- try: self._lastKey, self.renderer
- except AttributeError: need_new_renderer = True
- else: need_new_renderer = (self._lastKey != key)
-
- if need_new_renderer:
- self.renderer = RendererAgg(w, h, self.figure.dpi)
- self._lastKey = key
- elif cleared:
- self.renderer.clear()
- return self.renderer
-
- def tostring_rgb(self):
- '''Get the image as an RGB byte string
-
- `draw` must be called at least once before this function will work and
- to update the renderer for any subsequent changes to the Figure.
-
- Returns
- -------
- bytes
- '''
- return self.renderer.tostring_rgb()
-
- def tostring_argb(self):
- '''Get the image as an ARGB byte string
-
- `draw` must be called at least once before this function will work and
- to update the renderer for any subsequent changes to the Figure.
-
- Returns
- -------
- bytes
-
- '''
- return self.renderer.tostring_argb()
-
- def buffer_rgba(self):
- '''Get the image as an RGBA byte string
-
- `draw` must be called at least once before this function will work and
- to update the renderer for any subsequent changes to the Figure.
-
- Returns
- -------
- bytes
- '''
- return self.renderer.buffer_rgba()
-
- def print_raw(self, filename_or_obj, *args, **kwargs):
- FigureCanvasAgg.draw(self)
- renderer = self.get_renderer()
- original_dpi = renderer.dpi
- renderer.dpi = self.figure.dpi
- if isinstance(filename_or_obj, six.string_types):
- fileobj = open(filename_or_obj, 'wb')
- close = True
- else:
- fileobj = filename_or_obj
- close = False
- try:
- fileobj.write(renderer._renderer.buffer_rgba())
- finally:
- if close:
- fileobj.close()
- renderer.dpi = original_dpi
- print_rgba = print_raw
-
- def print_png(self, filename_or_obj, *args, **kwargs):
- FigureCanvasAgg.draw(self)
- renderer = self.get_renderer()
- original_dpi = renderer.dpi
- renderer.dpi = self.figure.dpi
-
- version_str = 'matplotlib version ' + __version__ + \
- ', http://matplotlib.org/'
- metadata = OrderedDict({'Software': version_str})
- user_metadata = kwargs.pop("metadata", None)
- if user_metadata is not None:
- metadata.update(user_metadata)
-
- try:
- with cbook.open_file_cm(filename_or_obj, "wb") as fh:
- _png.write_png(renderer._renderer, fh,
- self.figure.dpi, metadata=metadata)
- finally:
- renderer.dpi = original_dpi
-
- def print_to_buffer(self):
- FigureCanvasAgg.draw(self)
- renderer = self.get_renderer()
- original_dpi = renderer.dpi
- renderer.dpi = self.figure.dpi
- try:
- result = (renderer._renderer.buffer_rgba(),
- (int(renderer.width), int(renderer.height)))
- finally:
- renderer.dpi = original_dpi
- return result
-
- if _has_pil:
- # add JPEG support
- def print_jpg(self, filename_or_obj, *args, **kwargs):
- """
- Other Parameters
- ----------------
- quality : int
- The image quality, on a scale from 1 (worst) to
- 95 (best). The default is 95, if not given in the
- matplotlibrc file in the savefig.jpeg_quality parameter.
- Values above 95 should be avoided; 100 completely
- disables the JPEG quantization stage.
-
- optimize : bool
- If present, indicates that the encoder should
- make an extra pass over the image in order to select
- optimal encoder settings.
-
- progressive : bool
- If present, indicates that this image
- should be stored as a progressive JPEG file.
- """
- buf, size = self.print_to_buffer()
- if kwargs.pop("dryrun", False):
- return
- # The image is "pasted" onto a white background image to safely
- # handle any transparency
- image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
- rgba = mcolors.to_rgba(rcParams['savefig.facecolor'])
- color = tuple([int(x * 255.0) for x in rgba[:3]])
- background = Image.new('RGB', size, color)
- background.paste(image, image)
- options = {k: kwargs[k]
- for k in ['quality', 'optimize', 'progressive', 'dpi']
- if k in kwargs}
- options.setdefault('quality', rcParams['savefig.jpeg_quality'])
- if 'dpi' in options:
- # Set the same dpi in both x and y directions
- options['dpi'] = (options['dpi'], options['dpi'])
-
- return background.save(filename_or_obj, format='jpeg', **options)
- print_jpeg = print_jpg
-
- # add TIFF support
- def print_tif(self, filename_or_obj, *args, **kwargs):
- buf, size = self.print_to_buffer()
- if kwargs.pop("dryrun", False):
- return
- image = Image.frombuffer('RGBA', size, buf, 'raw', 'RGBA', 0, 1)
- dpi = (self.figure.dpi, self.figure.dpi)
- return image.save(filename_or_obj, format='tiff',
- dpi=dpi)
- print_tiff = print_tif
-
-
-@_Backend.export
-class _BackendAgg(_Backend):
- FigureCanvas = FigureCanvasAgg
- FigureManager = FigureManagerBase
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_cairo.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_cairo.py
deleted file mode 100644
index c870ba60a5..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_cairo.py
+++ /dev/null
@@ -1,520 +0,0 @@
-"""
-A Cairo backend for matplotlib
-==============================
-:Author: Steve Chaplin and others
-
-This backend depends on `cairo <http://cairographics.org>`_, and either on
-cairocffi, or (Python 2 only) on pycairo.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import gzip
-import sys
-import warnings
-
-import numpy as np
-
-# cairocffi is more widely compatible than pycairo (in particular pgi only
-# works with cairocffi) so try it first.
-try:
- import cairocffi as cairo
-except ImportError:
- try:
- import cairo
- except ImportError:
- raise ImportError("cairo backend requires that cairocffi or pycairo "
- "is installed")
- else:
- HAS_CAIRO_CFFI = False
-else:
- HAS_CAIRO_CFFI = True
-
-if cairo.version_info < (1, 4, 0):
- raise ImportError("cairo {} is installed; "
- "cairo>=1.4.0 is required".format(cairo.version))
-backend_version = cairo.version
-
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase,
- RendererBase)
-from matplotlib.mathtext import MathTextParser
-from matplotlib.path import Path
-from matplotlib.transforms import Affine2D
-from matplotlib.font_manager import ttfFontProperty
-
-
-class ArrayWrapper:
- """Thin wrapper around numpy ndarray to expose the interface
- expected by cairocffi. Basically replicates the
- array.array interface.
- """
- def __init__(self, myarray):
- self.__array = myarray
- self.__data = myarray.ctypes.data
- self.__size = len(myarray.flatten())
- self.itemsize = myarray.itemsize
-
- def buffer_info(self):
- return (self.__data, self.__size)
-
-
-class RendererCairo(RendererBase):
- fontweights = {
- 100 : cairo.FONT_WEIGHT_NORMAL,
- 200 : cairo.FONT_WEIGHT_NORMAL,
- 300 : cairo.FONT_WEIGHT_NORMAL,
- 400 : cairo.FONT_WEIGHT_NORMAL,
- 500 : cairo.FONT_WEIGHT_NORMAL,
- 600 : cairo.FONT_WEIGHT_BOLD,
- 700 : cairo.FONT_WEIGHT_BOLD,
- 800 : cairo.FONT_WEIGHT_BOLD,
- 900 : cairo.FONT_WEIGHT_BOLD,
- 'ultralight' : cairo.FONT_WEIGHT_NORMAL,
- 'light' : cairo.FONT_WEIGHT_NORMAL,
- 'normal' : cairo.FONT_WEIGHT_NORMAL,
- 'medium' : cairo.FONT_WEIGHT_NORMAL,
- 'regular' : cairo.FONT_WEIGHT_NORMAL,
- 'semibold' : cairo.FONT_WEIGHT_BOLD,
- 'bold' : cairo.FONT_WEIGHT_BOLD,
- 'heavy' : cairo.FONT_WEIGHT_BOLD,
- 'ultrabold' : cairo.FONT_WEIGHT_BOLD,
- 'black' : cairo.FONT_WEIGHT_BOLD,
- }
- fontangles = {
- 'italic' : cairo.FONT_SLANT_ITALIC,
- 'normal' : cairo.FONT_SLANT_NORMAL,
- 'oblique' : cairo.FONT_SLANT_OBLIQUE,
- }
-
-
- def __init__(self, dpi):
- self.dpi = dpi
- self.gc = GraphicsContextCairo(renderer=self)
- self.text_ctx = cairo.Context(
- cairo.ImageSurface(cairo.FORMAT_ARGB32, 1, 1))
- self.mathtext_parser = MathTextParser('Cairo')
- RendererBase.__init__(self)
-
- def set_ctx_from_surface(self, surface):
- self.gc.ctx = cairo.Context(surface)
- # Although it may appear natural to automatically call
- # `self.set_width_height(surface.get_width(), surface.get_height())`
- # here (instead of having the caller do so separately), this would fail
- # for PDF/PS/SVG surfaces, which have no way to report their extents.
-
- def set_width_height(self, width, height):
- self.width = width
- self.height = height
-
- def _fill_and_stroke(self, ctx, fill_c, alpha, alpha_overrides):
- if fill_c is not None:
- ctx.save()
- if len(fill_c) == 3 or alpha_overrides:
- ctx.set_source_rgba(fill_c[0], fill_c[1], fill_c[2], alpha)
- else:
- ctx.set_source_rgba(fill_c[0], fill_c[1], fill_c[2], fill_c[3])
- ctx.fill_preserve()
- ctx.restore()
- ctx.stroke()
-
- @staticmethod
- def convert_path(ctx, path, transform, clip=None):
- for points, code in path.iter_segments(transform, clip=clip):
- if code == Path.MOVETO:
- ctx.move_to(*points)
- elif code == Path.CLOSEPOLY:
- ctx.close_path()
- elif code == Path.LINETO:
- ctx.line_to(*points)
- elif code == Path.CURVE3:
- ctx.curve_to(points[0], points[1],
- points[0], points[1],
- points[2], points[3])
- elif code == Path.CURVE4:
- ctx.curve_to(*points)
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- ctx = gc.ctx
-
- # We'll clip the path to the actual rendering extents
- # if the path isn't filled.
- if rgbFace is None and gc.get_hatch() is None:
- clip = ctx.clip_extents()
- else:
- clip = None
-
- transform = (transform
- + Affine2D().scale(1.0, -1.0).translate(0, self.height))
-
- ctx.new_path()
- self.convert_path(ctx, path, transform, clip)
-
- self._fill_and_stroke(
- ctx, rgbFace, gc.get_alpha(), gc.get_forced_alpha())
-
- def draw_markers(self, gc, marker_path, marker_trans, path, transform,
- rgbFace=None):
- ctx = gc.ctx
-
- ctx.new_path()
- # Create the path for the marker; it needs to be flipped here already!
- self.convert_path(
- ctx, marker_path, marker_trans + Affine2D().scale(1.0, -1.0))
- marker_path = ctx.copy_path_flat()
-
- # Figure out whether the path has a fill
- x1, y1, x2, y2 = ctx.fill_extents()
- if x1 == 0 and y1 == 0 and x2 == 0 and y2 == 0:
- filled = False
- # No fill, just unset this (so we don't try to fill it later on)
- rgbFace = None
- else:
- filled = True
-
- transform = (transform
- + Affine2D().scale(1.0, -1.0).translate(0, self.height))
-
- ctx.new_path()
- for i, (vertices, codes) in enumerate(
- path.iter_segments(transform, simplify=False)):
- if len(vertices):
- x, y = vertices[-2:]
- ctx.save()
-
- # Translate and apply path
- ctx.translate(x, y)
- ctx.append_path(marker_path)
-
- ctx.restore()
-
- # Slower code path if there is a fill; we need to draw
- # the fill and stroke for each marker at the same time.
- # Also flush out the drawing every once in a while to
- # prevent the paths from getting way too long.
- if filled or i % 1000 == 0:
- self._fill_and_stroke(
- ctx, rgbFace, gc.get_alpha(), gc.get_forced_alpha())
-
- # Fast path, if there is no fill, draw everything in one step
- if not filled:
- self._fill_and_stroke(
- ctx, rgbFace, gc.get_alpha(), gc.get_forced_alpha())
-
- def draw_image(self, gc, x, y, im):
- # bbox - not currently used
- if sys.byteorder == 'little':
- im = im[:, :, (2, 1, 0, 3)]
- else:
- im = im[:, :, (3, 0, 1, 2)]
- if HAS_CAIRO_CFFI:
- # cairocffi tries to use the buffer_info from array.array
- # that we replicate in ArrayWrapper and alternatively falls back
- # on ctypes to get a pointer to the numpy array. This works
- # correctly on a numpy array in python3 but not 2.7. We replicate
- # the array.array functionality here to get cross version support.
- imbuffer = ArrayWrapper(im.flatten())
- else:
- # pycairo uses PyObject_AsWriteBuffer to get a pointer to the
- # numpy array; this works correctly on a regular numpy array but
- # not on a py2 memoryview.
- imbuffer = im.flatten()
- surface = cairo.ImageSurface.create_for_data(
- imbuffer, cairo.FORMAT_ARGB32,
- im.shape[1], im.shape[0], im.shape[1]*4)
- ctx = gc.ctx
- y = self.height - y - im.shape[0]
-
- ctx.save()
- ctx.set_source_surface(surface, float(x), float(y))
- if gc.get_alpha() != 1.0:
- ctx.paint_with_alpha(gc.get_alpha())
- else:
- ctx.paint()
- ctx.restore()
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- # Note: x,y are device/display coords, not user-coords, unlike other
- # draw_* methods
- if ismath:
- self._draw_mathtext(gc, x, y, s, prop, angle)
-
- else:
- ctx = gc.ctx
- ctx.new_path()
- ctx.move_to(x, y)
- ctx.select_font_face(prop.get_name(),
- self.fontangles[prop.get_style()],
- self.fontweights[prop.get_weight()])
-
- size = prop.get_size_in_points() * self.dpi / 72.0
-
- ctx.save()
- if angle:
- ctx.rotate(np.deg2rad(-angle))
- ctx.set_font_size(size)
-
- if HAS_CAIRO_CFFI:
- if not isinstance(s, six.text_type):
- s = six.text_type(s)
- else:
- if six.PY2 and isinstance(s, six.text_type):
- s = s.encode("utf-8")
-
- ctx.show_text(s)
- ctx.restore()
-
- def _draw_mathtext(self, gc, x, y, s, prop, angle):
- ctx = gc.ctx
- width, height, descent, glyphs, rects = self.mathtext_parser.parse(
- s, self.dpi, prop)
-
- ctx.save()
- ctx.translate(x, y)
- if angle:
- ctx.rotate(np.deg2rad(-angle))
-
- for font, fontsize, s, ox, oy in glyphs:
- ctx.new_path()
- ctx.move_to(ox, oy)
-
- fontProp = ttfFontProperty(font)
- ctx.save()
- ctx.select_font_face(fontProp.name,
- self.fontangles[fontProp.style],
- self.fontweights[fontProp.weight])
-
- size = fontsize * self.dpi / 72.0
- ctx.set_font_size(size)
- if not six.PY3 and isinstance(s, six.text_type):
- s = s.encode("utf-8")
- ctx.show_text(s)
- ctx.restore()
-
- for ox, oy, w, h in rects:
- ctx.new_path()
- ctx.rectangle(ox, oy, w, h)
- ctx.set_source_rgb(0, 0, 0)
- ctx.fill_preserve()
-
- ctx.restore()
-
- def get_canvas_width_height(self):
- return self.width, self.height
-
- def get_text_width_height_descent(self, s, prop, ismath):
- if ismath:
- width, height, descent, fonts, used_characters = \
- self.mathtext_parser.parse(s, self.dpi, prop)
- return width, height, descent
-
- ctx = self.text_ctx
- ctx.save()
- ctx.select_font_face(prop.get_name(),
- self.fontangles[prop.get_style()],
- self.fontweights[prop.get_weight()])
-
- # Cairo (says it) uses 1/96 inch user space units, ref: cairo_gstate.c
- # but if /96.0 is used the font is too small
- size = prop.get_size_in_points() * self.dpi / 72
-
- # problem - scale remembers last setting and font can become
- # enormous causing program to crash
- # save/restore prevents the problem
- ctx.set_font_size(size)
-
- y_bearing, w, h = ctx.text_extents(s)[1:4]
- ctx.restore()
-
- return w, h, h + y_bearing
-
- def new_gc(self):
- self.gc.ctx.save()
- self.gc._alpha = 1
- self.gc._forced_alpha = False # if True, _alpha overrides A from RGBA
- return self.gc
-
- def points_to_pixels(self, points):
- return points / 72 * self.dpi
-
-
-class GraphicsContextCairo(GraphicsContextBase):
- _joind = {
- 'bevel' : cairo.LINE_JOIN_BEVEL,
- 'miter' : cairo.LINE_JOIN_MITER,
- 'round' : cairo.LINE_JOIN_ROUND,
- }
-
- _capd = {
- 'butt' : cairo.LINE_CAP_BUTT,
- 'projecting' : cairo.LINE_CAP_SQUARE,
- 'round' : cairo.LINE_CAP_ROUND,
- }
-
- def __init__(self, renderer):
- GraphicsContextBase.__init__(self)
- self.renderer = renderer
-
- def restore(self):
- self.ctx.restore()
-
- def set_alpha(self, alpha):
- GraphicsContextBase.set_alpha(self, alpha)
- _alpha = self.get_alpha()
- rgb = self._rgb
- if self.get_forced_alpha():
- self.ctx.set_source_rgba(rgb[0], rgb[1], rgb[2], _alpha)
- else:
- self.ctx.set_source_rgba(rgb[0], rgb[1], rgb[2], rgb[3])
-
- # def set_antialiased(self, b):
- # cairo has many antialiasing modes, we need to pick one for True and
- # one for False.
-
- def set_capstyle(self, cs):
- if cs in ('butt', 'round', 'projecting'):
- self._capstyle = cs
- self.ctx.set_line_cap(self._capd[cs])
- else:
- raise ValueError('Unrecognized cap style. Found %s' % cs)
-
- def set_clip_rectangle(self, rectangle):
- if not rectangle:
- return
- x, y, w, h = np.round(rectangle.bounds)
- ctx = self.ctx
- ctx.new_path()
- ctx.rectangle(x, self.renderer.height - h - y, w, h)
- ctx.clip()
-
- def set_clip_path(self, path):
- if not path:
- return
- tpath, affine = path.get_transformed_path_and_affine()
- ctx = self.ctx
- ctx.new_path()
- affine = (affine
- + Affine2D().scale(1, -1).translate(0, self.renderer.height))
- RendererCairo.convert_path(ctx, tpath, affine)
- ctx.clip()
-
- def set_dashes(self, offset, dashes):
- self._dashes = offset, dashes
- if dashes == None:
- self.ctx.set_dash([], 0) # switch dashes off
- else:
- self.ctx.set_dash(
- list(self.renderer.points_to_pixels(np.asarray(dashes))),
- offset)
-
- def set_foreground(self, fg, isRGBA=None):
- GraphicsContextBase.set_foreground(self, fg, isRGBA)
- if len(self._rgb) == 3:
- self.ctx.set_source_rgb(*self._rgb)
- else:
- self.ctx.set_source_rgba(*self._rgb)
-
- def get_rgb(self):
- return self.ctx.get_source().get_rgba()[:3]
-
- def set_joinstyle(self, js):
- if js in ('miter', 'round', 'bevel'):
- self._joinstyle = js
- self.ctx.set_line_join(self._joind[js])
- else:
- raise ValueError('Unrecognized join style. Found %s' % js)
-
- def set_linewidth(self, w):
- self._linewidth = float(w)
- self.ctx.set_line_width(self.renderer.points_to_pixels(w))
-
-
-class FigureCanvasCairo(FigureCanvasBase):
- supports_blit = False
-
- def print_png(self, fobj, *args, **kwargs):
- width, height = self.get_width_height()
-
- renderer = RendererCairo(self.figure.dpi)
- renderer.set_width_height(width, height)
- surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
- renderer.set_ctx_from_surface(surface)
-
- self.figure.draw(renderer)
- surface.write_to_png(fobj)
-
- def print_pdf(self, fobj, *args, **kwargs):
- return self._save(fobj, 'pdf', *args, **kwargs)
-
- def print_ps(self, fobj, *args, **kwargs):
- return self._save(fobj, 'ps', *args, **kwargs)
-
- def print_svg(self, fobj, *args, **kwargs):
- return self._save(fobj, 'svg', *args, **kwargs)
-
- def print_svgz(self, fobj, *args, **kwargs):
- return self._save(fobj, 'svgz', *args, **kwargs)
-
- def _save(self, fo, fmt, **kwargs):
- # save PDF/PS/SVG
- orientation = kwargs.get('orientation', 'portrait')
-
- dpi = 72
- self.figure.dpi = dpi
- w_in, h_in = self.figure.get_size_inches()
- width_in_points, height_in_points = w_in * dpi, h_in * dpi
-
- if orientation == 'landscape':
- width_in_points, height_in_points = (
- height_in_points, width_in_points)
-
- if fmt == 'ps':
- if not hasattr(cairo, 'PSSurface'):
- raise RuntimeError('cairo has not been compiled with PS '
- 'support enabled')
- surface = cairo.PSSurface(fo, width_in_points, height_in_points)
- elif fmt == 'pdf':
- if not hasattr(cairo, 'PDFSurface'):
- raise RuntimeError('cairo has not been compiled with PDF '
- 'support enabled')
- surface = cairo.PDFSurface(fo, width_in_points, height_in_points)
- elif fmt in ('svg', 'svgz'):
- if not hasattr(cairo, 'SVGSurface'):
- raise RuntimeError('cairo has not been compiled with SVG '
- 'support enabled')
- if fmt == 'svgz':
- if isinstance(fo, six.string_types):
- fo = gzip.GzipFile(fo, 'wb')
- else:
- fo = gzip.GzipFile(None, 'wb', fileobj=fo)
- surface = cairo.SVGSurface(fo, width_in_points, height_in_points)
- else:
- warnings.warn("unknown format: %s" % fmt)
- return
-
- # surface.set_dpi() can be used
- renderer = RendererCairo(self.figure.dpi)
- renderer.set_width_height(width_in_points, height_in_points)
- renderer.set_ctx_from_surface(surface)
- ctx = renderer.gc.ctx
-
- if orientation == 'landscape':
- ctx.rotate(np.pi / 2)
- ctx.translate(0, -height_in_points)
- # Perhaps add an '%%Orientation: Landscape' comment?
-
- self.figure.draw(renderer)
-
- ctx.show_page()
- surface.finish()
- if fmt == 'svgz':
- fo.close()
-
-
-@_Backend.export
-class _BackendCairo(_Backend):
- FigureCanvas = FigureCanvasCairo
- FigureManager = FigureManagerBase
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_gdk.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_gdk.py
deleted file mode 100644
index 7d18922fc3..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_gdk.py
+++ /dev/null
@@ -1,438 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import warnings
-
-import gobject
-import gtk; gdk = gtk.gdk
-import pango
-pygtk_version_required = (2,2,0)
-if gtk.pygtk_version < pygtk_version_required:
- raise ImportError ("PyGTK %d.%d.%d is installed\n"
- "PyGTK %d.%d.%d or later is required"
- % (gtk.pygtk_version + pygtk_version_required))
-del pygtk_version_required
-
-import numpy as np
-
-import matplotlib
-from matplotlib import rcParams
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase,
- RendererBase)
-from matplotlib.cbook import warn_deprecated
-from matplotlib.mathtext import MathTextParser
-from matplotlib.transforms import Affine2D
-from matplotlib.backends._backend_gdk import pixbuf_get_pixels_array
-
-backend_version = "%d.%d.%d" % gtk.pygtk_version
-
-# Image formats that this backend supports - for FileChooser and print_figure()
-IMAGE_FORMAT = sorted(['bmp', 'eps', 'jpg', 'png', 'ps', 'svg']) # 'raw', 'rgb'
-IMAGE_FORMAT_DEFAULT = 'png'
-
-
-class RendererGDK(RendererBase):
- fontweights = {
- 100 : pango.WEIGHT_ULTRALIGHT,
- 200 : pango.WEIGHT_LIGHT,
- 300 : pango.WEIGHT_LIGHT,
- 400 : pango.WEIGHT_NORMAL,
- 500 : pango.WEIGHT_NORMAL,
- 600 : pango.WEIGHT_BOLD,
- 700 : pango.WEIGHT_BOLD,
- 800 : pango.WEIGHT_HEAVY,
- 900 : pango.WEIGHT_ULTRABOLD,
- 'ultralight' : pango.WEIGHT_ULTRALIGHT,
- 'light' : pango.WEIGHT_LIGHT,
- 'normal' : pango.WEIGHT_NORMAL,
- 'medium' : pango.WEIGHT_NORMAL,
- 'semibold' : pango.WEIGHT_BOLD,
- 'bold' : pango.WEIGHT_BOLD,
- 'heavy' : pango.WEIGHT_HEAVY,
- 'ultrabold' : pango.WEIGHT_ULTRABOLD,
- 'black' : pango.WEIGHT_ULTRABOLD,
- }
-
- # cache for efficiency, these must be at class, not instance level
- layoutd = {} # a map from text prop tups to pango layouts
- rotated = {} # a map from text prop tups to rotated text pixbufs
-
- def __init__(self, gtkDA, dpi):
- # widget gtkDA is used for:
- # '<widget>.create_pango_layout(s)'
- # cmap line below)
- self.gtkDA = gtkDA
- self.dpi = dpi
- self._cmap = gtkDA.get_colormap()
- self.mathtext_parser = MathTextParser("Agg")
-
- def set_pixmap (self, pixmap):
- self.gdkDrawable = pixmap
-
- def set_width_height (self, width, height):
- """w,h is the figure w,h not the pixmap w,h
- """
- self.width, self.height = width, height
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- transform = transform + Affine2D(). \
- scale(1.0, -1.0).translate(0, self.height)
- polygons = path.to_polygons(transform, self.width, self.height)
- for polygon in polygons:
- # draw_polygon won't take an arbitrary sequence -- it must be a list
- # of tuples
- polygon = [(int(np.round(x)), int(np.round(y))) for x, y in polygon]
- if rgbFace is not None:
- saveColor = gc.gdkGC.foreground
- gc.gdkGC.foreground = gc.rgb_to_gdk_color(rgbFace)
- self.gdkDrawable.draw_polygon(gc.gdkGC, True, polygon)
- gc.gdkGC.foreground = saveColor
- if gc.gdkGC.line_width > 0:
- self.gdkDrawable.draw_lines(gc.gdkGC, polygon)
-
- def draw_image(self, gc, x, y, im):
- bbox = gc.get_clip_rectangle()
-
- if bbox != None:
- l,b,w,h = bbox.bounds
- #rectangle = (int(l), self.height-int(b+h),
- # int(w), int(h))
- # set clip rect?
-
- rows, cols = im.shape[:2]
-
- pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,
- has_alpha=True, bits_per_sample=8,
- width=cols, height=rows)
-
- array = pixbuf_get_pixels_array(pixbuf)
- array[:, :, :] = im[::-1]
-
- gc = self.new_gc()
-
-
- y = self.height-y-rows
-
- try: # new in 2.2
- # can use None instead of gc.gdkGC, if don't need clipping
- self.gdkDrawable.draw_pixbuf (gc.gdkGC, pixbuf, 0, 0,
- int(x), int(y), cols, rows,
- gdk.RGB_DITHER_NONE, 0, 0)
- except AttributeError:
- # deprecated in 2.2
- pixbuf.render_to_drawable(self.gdkDrawable, gc.gdkGC, 0, 0,
- int(x), int(y), cols, rows,
- gdk.RGB_DITHER_NONE, 0, 0)
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- x, y = int(x), int(y)
-
- if x < 0 or y < 0: # window has shrunk and text is off the edge
- return
-
- if angle not in (0,90):
- warnings.warn('backend_gdk: unable to draw text at angles ' +
- 'other than 0 or 90')
- elif ismath:
- self._draw_mathtext(gc, x, y, s, prop, angle)
-
- elif angle==90:
- self._draw_rotated_text(gc, x, y, s, prop, angle)
-
- else:
- layout, inkRect, logicalRect = self._get_pango_layout(s, prop)
- l, b, w, h = inkRect
- if (x + w > self.width or y + h > self.height):
- return
-
- self.gdkDrawable.draw_layout(gc.gdkGC, x, y-h-b, layout)
-
- def _draw_mathtext(self, gc, x, y, s, prop, angle):
- ox, oy, width, height, descent, font_image, used_characters = \
- self.mathtext_parser.parse(s, self.dpi, prop)
-
- if angle == 90:
- width, height = height, width
- x -= width
- y -= height
-
- imw = font_image.get_width()
- imh = font_image.get_height()
-
- pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, has_alpha=True,
- bits_per_sample=8, width=imw, height=imh)
-
- array = pixbuf_get_pixels_array(pixbuf)
-
- rgb = gc.get_rgb()
- array[:,:,0] = int(rgb[0]*255)
- array[:,:,1] = int(rgb[1]*255)
- array[:,:,2] = int(rgb[2]*255)
- array[:,:,3] = (
- np.fromstring(font_image.as_str(), np.uint8).reshape((imh, imw)))
-
- # can use None instead of gc.gdkGC, if don't need clipping
- self.gdkDrawable.draw_pixbuf(gc.gdkGC, pixbuf, 0, 0,
- int(x), int(y), imw, imh,
- gdk.RGB_DITHER_NONE, 0, 0)
-
- def _draw_rotated_text(self, gc, x, y, s, prop, angle):
- """
- Draw the text rotated 90 degrees, other angles are not supported
- """
- # this function (and its called functions) is a bottleneck
- # Pango 1.6 supports rotated text, but pygtk 2.4.0 does not yet have
- # wrapper functions
- # GTK+ 2.6 pixbufs support rotation
-
- gdrawable = self.gdkDrawable
- ggc = gc.gdkGC
-
- layout, inkRect, logicalRect = self._get_pango_layout(s, prop)
- l, b, w, h = inkRect
- x = int(x-h)
- y = int(y-w)
-
- if (x < 0 or y < 0 or # window has shrunk and text is off the edge
- x + w > self.width or y + h > self.height):
- return
-
- key = (x,y,s,angle,hash(prop))
- imageVert = self.rotated.get(key)
- if imageVert != None:
- gdrawable.draw_image(ggc, imageVert, 0, 0, x, y, h, w)
- return
-
- imageBack = gdrawable.get_image(x, y, w, h)
- imageVert = gdrawable.get_image(x, y, h, w)
- imageFlip = gtk.gdk.Image(type=gdk.IMAGE_FASTEST,
- visual=gdrawable.get_visual(),
- width=w, height=h)
- if imageFlip == None or imageBack == None or imageVert == None:
- warnings.warn("Could not renderer vertical text")
- return
- imageFlip.set_colormap(self._cmap)
- for i in range(w):
- for j in range(h):
- imageFlip.put_pixel(i, j, imageVert.get_pixel(j,w-i-1) )
-
- gdrawable.draw_image(ggc, imageFlip, 0, 0, x, y, w, h)
- gdrawable.draw_layout(ggc, x, y-b, layout)
-
- imageIn = gdrawable.get_image(x, y, w, h)
- for i in range(w):
- for j in range(h):
- imageVert.put_pixel(j, i, imageIn.get_pixel(w-i-1,j) )
-
- gdrawable.draw_image(ggc, imageBack, 0, 0, x, y, w, h)
- gdrawable.draw_image(ggc, imageVert, 0, 0, x, y, h, w)
- self.rotated[key] = imageVert
-
- def _get_pango_layout(self, s, prop):
- """
- Create a pango layout instance for Text 's' with properties 'prop'.
- Return - pango layout (from cache if already exists)
-
- Note that pango assumes a logical DPI of 96
- Ref: pango/fonts.c/pango_font_description_set_size() manual page
- """
- # problem? - cache gets bigger and bigger, is never cleared out
- # two (not one) layouts are created for every text item s (then they
- # are cached) - why?
-
- key = self.dpi, s, hash(prop)
- value = self.layoutd.get(key)
- if value != None:
- return value
-
- size = prop.get_size_in_points() * self.dpi / 96.0
- size = np.round(size)
-
- font_str = '%s, %s %i' % (prop.get_name(), prop.get_style(), size,)
- font = pango.FontDescription(font_str)
-
- # later - add fontweight to font_str
- font.set_weight(self.fontweights[prop.get_weight()])
-
- layout = self.gtkDA.create_pango_layout(s)
- layout.set_font_description(font)
- inkRect, logicalRect = layout.get_pixel_extents()
-
- self.layoutd[key] = layout, inkRect, logicalRect
- return layout, inkRect, logicalRect
-
- def flipy(self):
- return True
-
- def get_canvas_width_height(self):
- return self.width, self.height
-
- def get_text_width_height_descent(self, s, prop, ismath):
- if ismath:
- ox, oy, width, height, descent, font_image, used_characters = \
- self.mathtext_parser.parse(s, self.dpi, prop)
- return width, height, descent
-
- layout, inkRect, logicalRect = self._get_pango_layout(s, prop)
- l, b, w, h = inkRect
- ll, lb, lw, lh = logicalRect
-
- return w, h + 1, h - lh
-
- def new_gc(self):
- return GraphicsContextGDK(renderer=self)
-
- def points_to_pixels(self, points):
- return points/72.0 * self.dpi
-
-
-class GraphicsContextGDK(GraphicsContextBase):
- # a cache shared by all class instances
- _cached = {} # map: rgb color -> gdk.Color
-
- _joind = {
- 'bevel' : gdk.JOIN_BEVEL,
- 'miter' : gdk.JOIN_MITER,
- 'round' : gdk.JOIN_ROUND,
- }
-
- _capd = {
- 'butt' : gdk.CAP_BUTT,
- 'projecting' : gdk.CAP_PROJECTING,
- 'round' : gdk.CAP_ROUND,
- }
-
-
- def __init__(self, renderer):
- GraphicsContextBase.__init__(self)
- self.renderer = renderer
- self.gdkGC = gtk.gdk.GC(renderer.gdkDrawable)
- self._cmap = renderer._cmap
-
-
- def rgb_to_gdk_color(self, rgb):
- """
- rgb - an RGB tuple (three 0.0-1.0 values)
- return an allocated gtk.gdk.Color
- """
- try:
- return self._cached[tuple(rgb)]
- except KeyError:
- color = self._cached[tuple(rgb)] = \
- self._cmap.alloc_color(
- int(rgb[0]*65535),int(rgb[1]*65535),int(rgb[2]*65535))
- return color
-
-
- #def set_antialiased(self, b):
- # anti-aliasing is not supported by GDK
-
- def set_capstyle(self, cs):
- GraphicsContextBase.set_capstyle(self, cs)
- self.gdkGC.cap_style = self._capd[self._capstyle]
-
-
- def set_clip_rectangle(self, rectangle):
- GraphicsContextBase.set_clip_rectangle(self, rectangle)
- if rectangle is None:
- return
- l,b,w,h = rectangle.bounds
- rectangle = (int(l), self.renderer.height-int(b+h)+1,
- int(w), int(h))
- #rectangle = (int(l), self.renderer.height-int(b+h),
- # int(w+1), int(h+2))
- self.gdkGC.set_clip_rectangle(rectangle)
-
- def set_dashes(self, dash_offset, dash_list):
- GraphicsContextBase.set_dashes(self, dash_offset, dash_list)
-
- if dash_list == None:
- self.gdkGC.line_style = gdk.LINE_SOLID
- else:
- pixels = self.renderer.points_to_pixels(np.asarray(dash_list))
- dl = [max(1, int(np.round(val))) for val in pixels]
- self.gdkGC.set_dashes(dash_offset, dl)
- self.gdkGC.line_style = gdk.LINE_ON_OFF_DASH
-
-
- def set_foreground(self, fg, isRGBA=False):
- GraphicsContextBase.set_foreground(self, fg, isRGBA)
- self.gdkGC.foreground = self.rgb_to_gdk_color(self.get_rgb())
-
-
- def set_joinstyle(self, js):
- GraphicsContextBase.set_joinstyle(self, js)
- self.gdkGC.join_style = self._joind[self._joinstyle]
-
-
- def set_linewidth(self, w):
- GraphicsContextBase.set_linewidth(self, w)
- if w == 0:
- self.gdkGC.line_width = 0
- else:
- pixels = self.renderer.points_to_pixels(w)
- self.gdkGC.line_width = max(1, int(np.round(pixels)))
-
-
-class FigureCanvasGDK (FigureCanvasBase):
- def __init__(self, figure):
- FigureCanvasBase.__init__(self, figure)
- if self.__class__ == matplotlib.backends.backend_gdk.FigureCanvasGDK:
- warn_deprecated('2.0', message="The GDK backend is "
- "deprecated. It is untested, known to be "
- "broken and will be removed in Matplotlib 3.0. "
- "Use the Agg backend instead. "
- "See Matplotlib usage FAQ for"
- " more info on backends.",
- alternative="Agg")
- self._renderer_init()
-
- def _renderer_init(self):
- self._renderer = RendererGDK (gtk.DrawingArea(), self.figure.dpi)
-
- def _render_figure(self, pixmap, width, height):
- self._renderer.set_pixmap (pixmap)
- self._renderer.set_width_height (width, height)
- self.figure.draw (self._renderer)
-
- filetypes = FigureCanvasBase.filetypes.copy()
- filetypes['jpg'] = 'JPEG'
- filetypes['jpeg'] = 'JPEG'
-
- def print_jpeg(self, filename, *args, **kwargs):
- return self._print_image(filename, 'jpeg')
- print_jpg = print_jpeg
-
- def print_png(self, filename, *args, **kwargs):
- return self._print_image(filename, 'png')
-
- def _print_image(self, filename, format, *args, **kwargs):
- width, height = self.get_width_height()
- pixmap = gtk.gdk.Pixmap (None, width, height, depth=24)
- self._render_figure(pixmap, width, height)
-
- # jpg colors don't match the display very well, png colors match
- # better
- pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, 0, 8,
- width, height)
- pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(),
- 0, 0, 0, 0, width, height)
-
- # set the default quality, if we are writing a JPEG.
- # http://www.pygtk.org/docs/pygtk/class-gdkpixbuf.html#method-gdkpixbuf--save
- options = {k: kwargs[k] for k in ['quality'] if k in kwargs}
- if format in ['jpg', 'jpeg']:
- options.setdefault('quality', rcParams['savefig.jpeg_quality'])
- options['quality'] = str(options['quality'])
-
- pixbuf.save(filename, format, options=options)
-
-
-@_Backend.export
-class _BackendGDK(_Backend):
- FigureCanvas = FigureCanvasGDK
- FigureManager = FigureManagerBase
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtk.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtk.py
deleted file mode 100644
index a4ae7cc28b..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtk.py
+++ /dev/null
@@ -1,1037 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import logging
-import os
-import sys
-import warnings
-
-if six.PY3:
- warnings.warn(
- "The gtk* backends have not been tested with Python 3.x",
- ImportWarning)
-
-try:
- import gobject
- import gtk; gdk = gtk.gdk
- import pango
-except ImportError:
- raise ImportError("Gtk* backend requires pygtk to be installed.")
-
-pygtk_version_required = (2,4,0)
-if gtk.pygtk_version < pygtk_version_required:
- raise ImportError ("PyGTK %d.%d.%d is installed\n"
- "PyGTK %d.%d.%d or later is required"
- % (gtk.pygtk_version + pygtk_version_required))
-del pygtk_version_required
-
-_new_tooltip_api = (gtk.pygtk_version[1] >= 12)
-
-import matplotlib
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2,
- TimerBase, cursors)
-
-from matplotlib.backends.backend_gdk import RendererGDK, FigureCanvasGDK
-from matplotlib.cbook import is_writable_file_like, warn_deprecated
-from matplotlib.figure import Figure
-from matplotlib.widgets import SubplotTool
-
-from matplotlib import (
- cbook, colors as mcolors, lines, markers, rcParams)
-
-_log = logging.getLogger(__name__)
-
-backend_version = "%d.%d.%d" % gtk.pygtk_version
-
-# the true dots per inch on the screen; should be display dependent
-# see http://groups.google.com/groups?q=screen+dpi+x11&hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=7077.26e81ad5%40swift.cs.tcd.ie&rnum=5 for some info about screen dpi
-PIXELS_PER_INCH = 96
-
-# Hide the benign warning that it can't stat a file that doesn't
-warnings.filterwarnings('ignore', '.*Unable to retrieve the file info for.*', gtk.Warning)
-
-cursord = {
- cursors.MOVE : gdk.Cursor(gdk.FLEUR),
- cursors.HAND : gdk.Cursor(gdk.HAND2),
- cursors.POINTER : gdk.Cursor(gdk.LEFT_PTR),
- cursors.SELECT_REGION : gdk.Cursor(gdk.TCROSS),
- cursors.WAIT : gdk.Cursor(gdk.WATCH),
- }
-
-# ref gtk+/gtk/gtkwidget.h
-def GTK_WIDGET_DRAWABLE(w):
- flags = w.flags();
- return flags & gtk.VISIBLE != 0 and flags & gtk.MAPPED != 0
-
-
-class TimerGTK(TimerBase):
- '''
- Subclass of :class:`backend_bases.TimerBase` using GTK for timer events.
-
- Attributes
- ----------
- interval : int
- The time between timer events in milliseconds. Default is 1000 ms.
- single_shot : bool
- Boolean flag indicating whether this timer should operate as single
- shot (run once and then stop). Defaults to False.
- callbacks : list
- Stores list of (func, args) tuples that will be called upon timer
- events. This list can be manipulated directly, or the functions
- `add_callback` and `remove_callback` can be used.
-
- '''
- def _timer_start(self):
- # Need to stop it, otherwise we potentially leak a timer id that will
- # never be stopped.
- self._timer_stop()
- self._timer = gobject.timeout_add(self._interval, self._on_timer)
-
- def _timer_stop(self):
- if self._timer is not None:
- gobject.source_remove(self._timer)
- self._timer = None
-
- def _timer_set_interval(self):
- # Only stop and restart it if the timer has already been started
- if self._timer is not None:
- self._timer_stop()
- self._timer_start()
-
- def _on_timer(self):
- TimerBase._on_timer(self)
-
- # Gtk timeout_add() requires that the callback returns True if it
- # is to be called again.
- if len(self.callbacks) > 0 and not self._single:
- return True
- else:
- self._timer = None
- return False
-
-
-class FigureCanvasGTK (gtk.DrawingArea, FigureCanvasBase):
- keyvald = {65507 : 'control',
- 65505 : 'shift',
- 65513 : 'alt',
- 65508 : 'control',
- 65506 : 'shift',
- 65514 : 'alt',
- 65361 : 'left',
- 65362 : 'up',
- 65363 : 'right',
- 65364 : 'down',
- 65307 : 'escape',
- 65470 : 'f1',
- 65471 : 'f2',
- 65472 : 'f3',
- 65473 : 'f4',
- 65474 : 'f5',
- 65475 : 'f6',
- 65476 : 'f7',
- 65477 : 'f8',
- 65478 : 'f9',
- 65479 : 'f10',
- 65480 : 'f11',
- 65481 : 'f12',
- 65300 : 'scroll_lock',
- 65299 : 'break',
- 65288 : 'backspace',
- 65293 : 'enter',
- 65379 : 'insert',
- 65535 : 'delete',
- 65360 : 'home',
- 65367 : 'end',
- 65365 : 'pageup',
- 65366 : 'pagedown',
- 65438 : '0',
- 65436 : '1',
- 65433 : '2',
- 65435 : '3',
- 65430 : '4',
- 65437 : '5',
- 65432 : '6',
- 65429 : '7',
- 65431 : '8',
- 65434 : '9',
- 65451 : '+',
- 65453 : '-',
- 65450 : '*',
- 65455 : '/',
- 65439 : 'dec',
- 65421 : 'enter',
- 65511 : 'super',
- 65512 : 'super',
- 65406 : 'alt',
- 65289 : 'tab',
- }
-
- # Setting this as a static constant prevents
- # this resulting expression from leaking
- event_mask = (gdk.BUTTON_PRESS_MASK |
- gdk.BUTTON_RELEASE_MASK |
- gdk.EXPOSURE_MASK |
- gdk.KEY_PRESS_MASK |
- gdk.KEY_RELEASE_MASK |
- gdk.ENTER_NOTIFY_MASK |
- gdk.LEAVE_NOTIFY_MASK |
- gdk.POINTER_MOTION_MASK |
- gdk.POINTER_MOTION_HINT_MASK)
-
- def __init__(self, figure):
- if self.__class__ == matplotlib.backends.backend_gtk.FigureCanvasGTK:
- warn_deprecated('2.0', message="The GTK backend is "
- "deprecated. It is untested, known to be "
- "broken and will be removed in Matplotlib 3.0. "
- "Use the GTKAgg backend instead. "
- "See Matplotlib usage FAQ for"
- " more info on backends.",
- alternative="GTKAgg")
- FigureCanvasBase.__init__(self, figure)
- gtk.DrawingArea.__init__(self)
-
- self._idle_draw_id = 0
- self._need_redraw = True
- self._pixmap_width = -1
- self._pixmap_height = -1
- self._lastCursor = None
-
- self.connect('scroll_event', self.scroll_event)
- self.connect('button_press_event', self.button_press_event)
- self.connect('button_release_event', self.button_release_event)
- self.connect('configure_event', self.configure_event)
- self.connect('expose_event', self.expose_event)
- self.connect('key_press_event', self.key_press_event)
- self.connect('key_release_event', self.key_release_event)
- self.connect('motion_notify_event', self.motion_notify_event)
- self.connect('leave_notify_event', self.leave_notify_event)
- self.connect('enter_notify_event', self.enter_notify_event)
-
- self.set_events(self.__class__.event_mask)
-
- self.set_double_buffered(False)
- self.set_flags(gtk.CAN_FOCUS)
- self._renderer_init()
-
- self.last_downclick = {}
-
- def destroy(self):
- #gtk.DrawingArea.destroy(self)
- self.close_event()
- if self._idle_draw_id != 0:
- gobject.source_remove(self._idle_draw_id)
-
- def scroll_event(self, widget, event):
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.allocation.height - event.y
- if event.direction==gdk.SCROLL_UP:
- step = 1
- else:
- step = -1
- FigureCanvasBase.scroll_event(self, x, y, step, guiEvent=event)
- return False # finish event propagation?
-
- def button_press_event(self, widget, event):
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.allocation.height - event.y
- dblclick = (event.type == gdk._2BUTTON_PRESS)
- if not dblclick:
- # GTK is the only backend that generates a DOWN-UP-DOWN-DBLCLICK-UP event
- # sequence for a double click. All other backends have a DOWN-UP-DBLCLICK-UP
- # sequence. In order to provide consistency to matplotlib users, we will
- # eat the extra DOWN event in the case that we detect it is part of a double
- # click.
- # first, get the double click time in milliseconds.
- current_time = event.get_time()
- last_time = self.last_downclick.get(event.button,0)
- dblclick_time = gtk.settings_get_for_screen(gdk.screen_get_default()).get_property('gtk-double-click-time')
- delta_time = current_time-last_time
- if delta_time < dblclick_time:
- del self.last_downclick[event.button] # we do not want to eat more than one event.
- return False # eat.
- self.last_downclick[event.button] = current_time
- FigureCanvasBase.button_press_event(self, x, y, event.button, dblclick=dblclick, guiEvent=event)
- return False # finish event propagation?
-
- def button_release_event(self, widget, event):
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.allocation.height - event.y
- FigureCanvasBase.button_release_event(self, x, y, event.button, guiEvent=event)
- return False # finish event propagation?
-
- def key_press_event(self, widget, event):
- key = self._get_key(event)
- FigureCanvasBase.key_press_event(self, key, guiEvent=event)
- return True # stop event propagation
-
- def key_release_event(self, widget, event):
- key = self._get_key(event)
- FigureCanvasBase.key_release_event(self, key, guiEvent=event)
- return True # stop event propagation
-
- def motion_notify_event(self, widget, event):
- if event.is_hint:
- x, y, state = event.window.get_pointer()
- else:
- x, y, state = event.x, event.y, event.state
-
- # flipy so y=0 is bottom of canvas
- y = self.allocation.height - y
- FigureCanvasBase.motion_notify_event(self, x, y, guiEvent=event)
- return False # finish event propagation?
-
- def leave_notify_event(self, widget, event):
- FigureCanvasBase.leave_notify_event(self, event)
-
- def enter_notify_event(self, widget, event):
- x, y, state = event.window.get_pointer()
- FigureCanvasBase.enter_notify_event(self, event, xy=(x, y))
-
- def _get_key(self, event):
- if event.keyval in self.keyvald:
- key = self.keyvald[event.keyval]
- elif event.keyval < 256:
- key = chr(event.keyval)
- else:
- key = None
-
- for key_mask, prefix in (
- [gdk.MOD4_MASK, 'super'],
- [gdk.MOD1_MASK, 'alt'],
- [gdk.CONTROL_MASK, 'ctrl'], ):
- if event.state & key_mask:
- key = '{0}+{1}'.format(prefix, key)
-
- return key
-
- def configure_event(self, widget, event):
- if widget.window is None:
- return
- w, h = event.width, event.height
- if w < 3 or h < 3:
- return # empty fig
-
- # resize the figure (in inches)
- dpi = self.figure.dpi
- self.figure.set_size_inches(w/dpi, h/dpi, forward=False)
- self._need_redraw = True
-
- return False # finish event propagation?
-
- def draw(self):
- # Note: FigureCanvasBase.draw() is inconveniently named as it clashes
- # with the deprecated gtk.Widget.draw()
-
- self._need_redraw = True
- if GTK_WIDGET_DRAWABLE(self):
- self.queue_draw()
- # do a synchronous draw (its less efficient than an async draw,
- # but is required if/when animation is used)
- self.window.process_updates (False)
-
- def draw_idle(self):
- if self._idle_draw_id != 0:
- return
- def idle_draw(*args):
- try:
- self.draw()
- finally:
- self._idle_draw_id = 0
- return False
- self._idle_draw_id = gobject.idle_add(idle_draw)
-
-
- def _renderer_init(self):
- """Override by GTK backends to select a different renderer
- Renderer should provide the methods:
- set_pixmap ()
- set_width_height ()
- that are used by
- _render_figure() / _pixmap_prepare()
- """
- self._renderer = RendererGDK (self, self.figure.dpi)
-
-
- def _pixmap_prepare(self, width, height):
- """
- Make sure _._pixmap is at least width, height,
- create new pixmap if necessary
- """
- create_pixmap = False
- if width > self._pixmap_width:
- # increase the pixmap in 10%+ (rather than 1 pixel) steps
- self._pixmap_width = max (int (self._pixmap_width * 1.1),
- width)
- create_pixmap = True
-
- if height > self._pixmap_height:
- self._pixmap_height = max (int (self._pixmap_height * 1.1),
- height)
- create_pixmap = True
-
- if create_pixmap:
- self._pixmap = gdk.Pixmap (self.window, self._pixmap_width,
- self._pixmap_height)
- self._renderer.set_pixmap (self._pixmap)
-
-
- def _render_figure(self, pixmap, width, height):
- """used by GTK and GTKcairo. GTKAgg overrides
- """
- self._renderer.set_width_height (width, height)
- self.figure.draw (self._renderer)
-
-
- def expose_event(self, widget, event):
- """Expose_event for all GTK backends. Should not be overridden.
- """
- toolbar = self.toolbar
- # if toolbar:
- # toolbar.set_cursor(cursors.WAIT)
- if GTK_WIDGET_DRAWABLE(self):
- if self._need_redraw:
- x, y, w, h = self.allocation
- self._pixmap_prepare (w, h)
- self._render_figure(self._pixmap, w, h)
- self._need_redraw = False
- x, y, w, h = event.area
- self.window.draw_drawable (self.style.fg_gc[self.state],
- self._pixmap, x, y, x, y, w, h)
- # if toolbar:
- # toolbar.set_cursor(toolbar._lastCursor)
- return False # finish event propagation?
-
- filetypes = FigureCanvasBase.filetypes.copy()
- filetypes['jpg'] = 'JPEG'
- filetypes['jpeg'] = 'JPEG'
- filetypes['png'] = 'Portable Network Graphics'
-
- def print_jpeg(self, filename, *args, **kwargs):
- return self._print_image(filename, 'jpeg')
- print_jpg = print_jpeg
-
- def print_png(self, filename, *args, **kwargs):
- return self._print_image(filename, 'png')
-
- def _print_image(self, filename, format, *args, **kwargs):
- if self.flags() & gtk.REALIZED == 0:
- # for self.window(for pixmap) and has a side effect of altering
- # figure width,height (via configure-event?)
- gtk.DrawingArea.realize(self)
-
- width, height = self.get_width_height()
- pixmap = gdk.Pixmap (self.window, width, height)
- self._renderer.set_pixmap (pixmap)
- self._render_figure(pixmap, width, height)
-
- # jpg colors don't match the display very well, png colors match
- # better
- pixbuf = gdk.Pixbuf(gdk.COLORSPACE_RGB, 0, 8, width, height)
- pixbuf.get_from_drawable(pixmap, pixmap.get_colormap(),
- 0, 0, 0, 0, width, height)
-
- # set the default quality, if we are writing a JPEG.
- # http://www.pygtk.org/docs/pygtk/class-gdkpixbuf.html#method-gdkpixbuf--save
- options = {k: kwargs[k] for k in ['quality'] if k in kwargs}
- if format in ['jpg', 'jpeg']:
- options.setdefault('quality', rcParams['savefig.jpeg_quality'])
- options['quality'] = str(options['quality'])
-
- if isinstance(filename, six.string_types):
- try:
- pixbuf.save(filename, format, options=options)
- except gobject.GError as exc:
- error_msg_gtk('Save figure failure:\n%s' % (exc,), parent=self)
- elif is_writable_file_like(filename):
- if hasattr(pixbuf, 'save_to_callback'):
- def save_callback(buf, data=None):
- data.write(buf)
- try:
- pixbuf.save_to_callback(save_callback, format, user_data=filename, options=options)
- except gobject.GError as exc:
- error_msg_gtk('Save figure failure:\n%s' % (exc,), parent=self)
- else:
- raise ValueError("Saving to a Python file-like object is only supported by PyGTK >= 2.8")
- else:
- raise ValueError("filename must be a path or a file-like object")
-
- def new_timer(self, *args, **kwargs):
- """
- Creates a new backend-specific subclass of :class:`backend_bases.Timer`.
- This is useful for getting periodic events through the backend's native
- event loop. Implemented only for backends with GUIs.
-
- Other Parameters
- ----------------
- interval : scalar
- Timer interval in milliseconds
- callbacks : list
- Sequence of (func, args, kwargs) where ``func(*args, **kwargs)``
- will be executed by the timer every *interval*.
- """
- return TimerGTK(*args, **kwargs)
-
- def flush_events(self):
- gtk.gdk.threads_enter()
- while gtk.events_pending():
- gtk.main_iteration(True)
- gtk.gdk.flush()
- gtk.gdk.threads_leave()
-
-
-class FigureManagerGTK(FigureManagerBase):
- """
- Attributes
- ----------
- canvas : `FigureCanvas`
- The FigureCanvas instance
- num : int or str
- The Figure number
- toolbar : gtk.Toolbar
- The gtk.Toolbar (gtk only)
- vbox : gtk.VBox
- The gtk.VBox containing the canvas and toolbar (gtk only)
- window : gtk.Window
- The gtk.Window (gtk only)
-
- """
- def __init__(self, canvas, num):
- FigureManagerBase.__init__(self, canvas, num)
-
- self.window = gtk.Window()
- self.window.set_wmclass("matplotlib", "Matplotlib")
- self.set_window_title("Figure %d" % num)
- if window_icon:
- try:
- self.window.set_icon_from_file(window_icon)
- except:
- # some versions of gtk throw a glib.GError but not
- # all, so I am not sure how to catch it. I am unhappy
- # diong a blanket catch here, but an not sure what a
- # better way is - JDH
- _log.info('Could not load matplotlib '
- 'icon: %s', sys.exc_info()[1])
-
- self.vbox = gtk.VBox()
- self.window.add(self.vbox)
- self.vbox.show()
-
- self.canvas.show()
-
- self.vbox.pack_start(self.canvas, True, True)
-
- self.toolbar = self._get_toolbar(canvas)
-
- # calculate size for window
- w = int (self.canvas.figure.bbox.width)
- h = int (self.canvas.figure.bbox.height)
-
- if self.toolbar is not None:
- self.toolbar.show()
- self.vbox.pack_end(self.toolbar, False, False)
-
- tb_w, tb_h = self.toolbar.size_request()
- h += tb_h
- self.window.set_default_size (w, h)
-
- def destroy(*args):
- Gcf.destroy(num)
- self.window.connect("destroy", destroy)
- self.window.connect("delete_event", destroy)
- if matplotlib.is_interactive():
- self.window.show()
- self.canvas.draw_idle()
-
- def notify_axes_change(fig):
- 'this will be called whenever the current axes is changed'
- if self.toolbar is not None: self.toolbar.update()
- self.canvas.figure.add_axobserver(notify_axes_change)
-
- self.canvas.grab_focus()
-
- def destroy(self, *args):
- if hasattr(self, 'toolbar') and self.toolbar is not None:
- self.toolbar.destroy()
- if hasattr(self, 'vbox'):
- self.vbox.destroy()
- if hasattr(self, 'window'):
- self.window.destroy()
- if hasattr(self, 'canvas'):
- self.canvas.destroy()
- self.__dict__.clear() #Is this needed? Other backends don't have it.
-
- if Gcf.get_num_fig_managers()==0 and \
- not matplotlib.is_interactive() and \
- gtk.main_level() >= 1:
- gtk.main_quit()
-
- def show(self):
- # show the figure window
- self.window.show()
- # raise the window above others and release the "above lock"
- self.window.set_keep_above(True)
- self.window.set_keep_above(False)
-
- def full_screen_toggle(self):
- self._full_screen_flag = not self._full_screen_flag
- if self._full_screen_flag:
- self.window.fullscreen()
- else:
- self.window.unfullscreen()
- _full_screen_flag = False
-
-
- def _get_toolbar(self, canvas):
- # must be inited after the window, drawingArea and figure
- # attrs are set
- if rcParams['toolbar'] == 'toolbar2':
- toolbar = NavigationToolbar2GTK (canvas, self.window)
- else:
- toolbar = None
- return toolbar
-
- def get_window_title(self):
- return self.window.get_title()
-
- def set_window_title(self, title):
- self.window.set_title(title)
-
- def resize(self, width, height):
- 'set the canvas size in pixels'
- #_, _, cw, ch = self.canvas.allocation
- #_, _, ww, wh = self.window.allocation
- #self.window.resize (width-cw+ww, height-ch+wh)
- self.window.resize(width, height)
-
-
-class NavigationToolbar2GTK(NavigationToolbar2, gtk.Toolbar):
- def __init__(self, canvas, window):
- self.win = window
- gtk.Toolbar.__init__(self)
- NavigationToolbar2.__init__(self, canvas)
-
- def set_message(self, s):
- self.message.set_label(s)
-
- def set_cursor(self, cursor):
- self.canvas.window.set_cursor(cursord[cursor])
- gtk.main_iteration()
-
- def release(self, event):
- try: del self._pixmapBack
- except AttributeError: pass
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- 'adapted from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/189744'
- drawable = self.canvas.window
- if drawable is None:
- return
-
- gc = drawable.new_gc()
-
- height = self.canvas.figure.bbox.height
- y1 = height - y1
- y0 = height - y0
-
- w = abs(x1 - x0)
- h = abs(y1 - y0)
-
- rect = [int(val)for val in (min(x0,x1), min(y0, y1), w, h)]
- try:
- lastrect, pixmapBack = self._pixmapBack
- except AttributeError:
- #snap image back
- if event.inaxes is None:
- return
-
- ax = event.inaxes
- l,b,w,h = [int(val) for val in ax.bbox.bounds]
- b = int(height)-(b+h)
- axrect = l,b,w,h
- self._pixmapBack = axrect, gtk.gdk.Pixmap(drawable, w, h)
- self._pixmapBack[1].draw_drawable(gc, drawable, l, b, 0, 0, w, h)
- else:
- drawable.draw_drawable(gc, pixmapBack, 0, 0, *lastrect)
- drawable.draw_rectangle(gc, False, *rect)
-
-
- def _init_toolbar(self):
- self.set_style(gtk.TOOLBAR_ICONS)
- self._init_toolbar2_4()
-
-
- def _init_toolbar2_4(self):
- basedir = os.path.join(rcParams['datapath'],'images')
- if not _new_tooltip_api:
- self.tooltips = gtk.Tooltips()
-
- for text, tooltip_text, image_file, callback in self.toolitems:
- if text is None:
- self.insert( gtk.SeparatorToolItem(), -1 )
- continue
- fname = os.path.join(basedir, image_file + '.png')
- image = gtk.Image()
- image.set_from_file(fname)
- tbutton = gtk.ToolButton(image, text)
- self.insert(tbutton, -1)
- tbutton.connect('clicked', getattr(self, callback))
- if _new_tooltip_api:
- tbutton.set_tooltip_text(tooltip_text)
- else:
- tbutton.set_tooltip(self.tooltips, tooltip_text, 'Private')
-
- toolitem = gtk.SeparatorToolItem()
- self.insert(toolitem, -1)
- # set_draw() not making separator invisible,
- # bug #143692 fixed Jun 06 2004, will be in GTK+ 2.6
- toolitem.set_draw(False)
- toolitem.set_expand(True)
-
- toolitem = gtk.ToolItem()
- self.insert(toolitem, -1)
- self.message = gtk.Label()
- toolitem.add(self.message)
-
- self.show_all()
-
- def get_filechooser(self):
- fc = FileChooserDialog(
- title='Save the figure',
- parent=self.win,
- path=os.path.expanduser(rcParams['savefig.directory']),
- filetypes=self.canvas.get_supported_filetypes(),
- default_filetype=self.canvas.get_default_filetype())
- fc.set_current_name(self.canvas.get_default_filename())
- return fc
-
- def save_figure(self, *args):
- chooser = self.get_filechooser()
- fname, format = chooser.get_filename_from_user()
- chooser.destroy()
- if fname:
- startpath = os.path.expanduser(rcParams['savefig.directory'])
- # Save dir for next time, unless empty str (i.e., use cwd).
- if startpath != "":
- rcParams['savefig.directory'] = (
- os.path.dirname(six.text_type(fname)))
- try:
- self.canvas.figure.savefig(fname, format=format)
- except Exception as e:
- error_msg_gtk(str(e), parent=self)
-
- def configure_subplots(self, button):
- toolfig = Figure(figsize=(6,3))
- canvas = self._get_canvas(toolfig)
- toolfig.subplots_adjust(top=0.9)
- tool = SubplotTool(self.canvas.figure, toolfig)
-
- w = int(toolfig.bbox.width)
- h = int(toolfig.bbox.height)
-
- window = gtk.Window()
- if window_icon:
- try:
- window.set_icon_from_file(window_icon)
- except:
- # we presumably already logged a message on the
- # failure of the main plot, don't keep reporting
- pass
- window.set_title("Subplot Configuration Tool")
- window.set_default_size(w, h)
- vbox = gtk.VBox()
- window.add(vbox)
- vbox.show()
-
- canvas.show()
- vbox.pack_start(canvas, True, True)
- window.show()
-
- def _get_canvas(self, fig):
- return FigureCanvasGTK(fig)
-
-
-class FileChooserDialog(gtk.FileChooserDialog):
- """GTK+ 2.4 file selector which presents the user with a menu
- of supported image formats
- """
- def __init__ (self,
- title = 'Save file',
- parent = None,
- action = gtk.FILE_CHOOSER_ACTION_SAVE,
- buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
- gtk.STOCK_SAVE, gtk.RESPONSE_OK),
- path = None,
- filetypes = [],
- default_filetype = None
- ):
- super(FileChooserDialog, self).__init__(title, parent, action, buttons)
- super(FileChooserDialog, self).set_do_overwrite_confirmation(True)
- self.set_default_response(gtk.RESPONSE_OK)
-
- if not path:
- path = os.getcwd() + os.sep
-
- # create an extra widget to list supported image formats
- self.set_current_folder (path)
- self.set_current_name ('image.' + default_filetype)
-
- hbox = gtk.HBox(spacing=10)
- hbox.pack_start(gtk.Label ("File Format:"), expand=False)
-
- liststore = gtk.ListStore(gobject.TYPE_STRING)
- cbox = gtk.ComboBox(liststore)
- cell = gtk.CellRendererText()
- cbox.pack_start(cell, True)
- cbox.add_attribute(cell, 'text', 0)
- hbox.pack_start(cbox)
-
- self.filetypes = filetypes
- self.sorted_filetypes = sorted(six.iteritems(filetypes))
- default = 0
- for i, (ext, name) in enumerate(self.sorted_filetypes):
- cbox.append_text("%s (*.%s)" % (name, ext))
- if ext == default_filetype:
- default = i
- cbox.set_active(default)
- self.ext = default_filetype
-
- def cb_cbox_changed (cbox, data=None):
- """File extension changed"""
- head, filename = os.path.split(self.get_filename())
- root, ext = os.path.splitext(filename)
- ext = ext[1:]
- new_ext = self.sorted_filetypes[cbox.get_active()][0]
- self.ext = new_ext
-
- if ext in self.filetypes:
- filename = root + '.' + new_ext
- elif ext == '':
- filename = filename.rstrip('.') + '.' + new_ext
-
- self.set_current_name(filename)
- cbox.connect("changed", cb_cbox_changed)
-
- hbox.show_all()
- self.set_extra_widget(hbox)
-
- def get_filename_from_user (self):
- while True:
- filename = None
- if self.run() != int(gtk.RESPONSE_OK):
- break
- filename = self.get_filename()
- break
-
- return filename, self.ext
-
-
-class DialogLineprops(object):
- """
- A GUI dialog for controlling lineprops
- """
- signals = (
- 'on_combobox_lineprops_changed',
- 'on_combobox_linestyle_changed',
- 'on_combobox_marker_changed',
- 'on_colorbutton_linestyle_color_set',
- 'on_colorbutton_markerface_color_set',
- 'on_dialog_lineprops_okbutton_clicked',
- 'on_dialog_lineprops_cancelbutton_clicked',
- )
-
- linestyles = [ls for ls in lines.Line2D.lineStyles if ls.strip()]
- linestyled = {s: i for i, s in enumerate(linestyles)}
-
- markers = [m for m in markers.MarkerStyle.markers
- if isinstance(m, six.string_types)]
- markerd = {s: i for i, s in enumerate(markers)}
-
- def __init__(self, lines):
- import gtk.glade
-
- datadir = matplotlib.get_data_path()
- gladefile = os.path.join(datadir, 'lineprops.glade')
- if not os.path.exists(gladefile):
- raise IOError(
- 'Could not find gladefile lineprops.glade in %s' % datadir)
-
- self._inited = False
- self._updateson = True # suppress updates when setting widgets manually
- self.wtree = gtk.glade.XML(gladefile, 'dialog_lineprops')
- self.wtree.signal_autoconnect(
- {s: getattr(self, s) for s in self.signals})
-
- self.dlg = self.wtree.get_widget('dialog_lineprops')
-
- self.lines = lines
-
- cbox = self.wtree.get_widget('combobox_lineprops')
- cbox.set_active(0)
- self.cbox_lineprops = cbox
-
- cbox = self.wtree.get_widget('combobox_linestyles')
- for ls in self.linestyles:
- cbox.append_text(ls)
- cbox.set_active(0)
- self.cbox_linestyles = cbox
-
- cbox = self.wtree.get_widget('combobox_markers')
- for m in self.markers:
- cbox.append_text(m)
- cbox.set_active(0)
- self.cbox_markers = cbox
- self._lastcnt = 0
- self._inited = True
-
- def show(self):
- 'populate the combo box'
- self._updateson = False
- # flush the old
- cbox = self.cbox_lineprops
- for i in range(self._lastcnt-1,-1,-1):
- cbox.remove_text(i)
-
- # add the new
- for line in self.lines:
- cbox.append_text(line.get_label())
- cbox.set_active(0)
-
- self._updateson = True
- self._lastcnt = len(self.lines)
- self.dlg.show()
-
- def get_active_line(self):
- 'get the active line'
- ind = self.cbox_lineprops.get_active()
- line = self.lines[ind]
- return line
-
- def get_active_linestyle(self):
- 'get the active lineinestyle'
- ind = self.cbox_linestyles.get_active()
- ls = self.linestyles[ind]
- return ls
-
- def get_active_marker(self):
- 'get the active lineinestyle'
- ind = self.cbox_markers.get_active()
- m = self.markers[ind]
- return m
-
- def _update(self):
- 'update the active line props from the widgets'
- if not self._inited or not self._updateson: return
- line = self.get_active_line()
- ls = self.get_active_linestyle()
- marker = self.get_active_marker()
- line.set_linestyle(ls)
- line.set_marker(marker)
-
- button = self.wtree.get_widget('colorbutton_linestyle')
- color = button.get_color()
- r, g, b = [val/65535. for val in (color.red, color.green, color.blue)]
- line.set_color((r,g,b))
-
- button = self.wtree.get_widget('colorbutton_markerface')
- color = button.get_color()
- r, g, b = [val/65535. for val in (color.red, color.green, color.blue)]
- line.set_markerfacecolor((r,g,b))
-
- line.figure.canvas.draw()
-
- def on_combobox_lineprops_changed(self, item):
- 'update the widgets from the active line'
- if not self._inited: return
- self._updateson = False
- line = self.get_active_line()
-
- ls = line.get_linestyle()
- if ls is None: ls = 'None'
- self.cbox_linestyles.set_active(self.linestyled[ls])
-
- marker = line.get_marker()
- if marker is None: marker = 'None'
- self.cbox_markers.set_active(self.markerd[marker])
-
- rgba = mcolors.to_rgba(line.get_color())
- color = gtk.gdk.Color(*[int(val*65535) for val in rgba[:3]])
- button = self.wtree.get_widget('colorbutton_linestyle')
- button.set_color(color)
-
- rgba = mcolors.to_rgba(line.get_markerfacecolor())
- color = gtk.gdk.Color(*[int(val*65535) for val in rgba[:3]])
- button = self.wtree.get_widget('colorbutton_markerface')
- button.set_color(color)
- self._updateson = True
-
- def on_combobox_linestyle_changed(self, item):
- self._update()
-
- def on_combobox_marker_changed(self, item):
- self._update()
-
- def on_colorbutton_linestyle_color_set(self, button):
- self._update()
-
- def on_colorbutton_markerface_color_set(self, button):
- 'called colorbutton marker clicked'
- self._update()
-
- def on_dialog_lineprops_okbutton_clicked(self, button):
- self._update()
- self.dlg.hide()
-
- def on_dialog_lineprops_cancelbutton_clicked(self, button):
- self.dlg.hide()
-
-# set icon used when windows are minimized
-# Unfortunately, the SVG renderer (rsvg) leaks memory under earlier
-# versions of pygtk, so we have to use a PNG file instead.
-try:
- if gtk.pygtk_version < (2, 8, 0) or sys.platform == 'win32':
- icon_filename = 'matplotlib.png'
- else:
- icon_filename = 'matplotlib.svg'
- window_icon = os.path.join(rcParams['datapath'], 'images', icon_filename)
-except:
- window_icon = None
- _log.info('Could not load matplotlib icon: %s', sys.exc_info()[1])
-
-def error_msg_gtk(msg, parent=None):
- if parent is not None: # find the toplevel gtk.Window
- parent = parent.get_toplevel()
- if parent.flags() & gtk.TOPLEVEL == 0:
- parent = None
-
- if not isinstance(msg, six.string_types):
- msg = ','.join(map(str, msg))
-
- dialog = gtk.MessageDialog(
- parent = parent,
- type = gtk.MESSAGE_ERROR,
- buttons = gtk.BUTTONS_OK,
- message_format = msg)
- dialog.run()
- dialog.destroy()
-
-
-@_Backend.export
-class _BackendGTK(_Backend):
- FigureCanvas = FigureCanvasGTK
- FigureManager = FigureManagerGTK
-
- @staticmethod
- def trigger_manager_draw(manager):
- manager.canvas.draw_idle()
-
- @staticmethod
- def mainloop():
- if gtk.main_level() == 0:
- gtk.main()
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtk3.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtk3.py
deleted file mode 100644
index 359b8fd884..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtk3.py
+++ /dev/null
@@ -1,920 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import logging
-import os
-import sys
-
-import matplotlib
-from matplotlib import backend_tools, rcParams
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2,
- StatusbarBase, TimerBase, ToolContainerBase, cursors)
-from matplotlib.backend_managers import ToolManager
-from matplotlib.figure import Figure
-from matplotlib.widgets import SubplotTool
-from ._gtk3_compat import GLib, GObject, Gtk, Gdk
-
-
-_log = logging.getLogger(__name__)
-
-backend_version = "%s.%s.%s" % (
- Gtk.get_major_version(), Gtk.get_micro_version(), Gtk.get_minor_version())
-
-# the true dots per inch on the screen; should be display dependent
-# see http://groups.google.com/groups?q=screen+dpi+x11&hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=7077.26e81ad5%40swift.cs.tcd.ie&rnum=5 for some info about screen dpi
-PIXELS_PER_INCH = 96
-
-cursord = {
- cursors.MOVE : Gdk.Cursor.new(Gdk.CursorType.FLEUR),
- cursors.HAND : Gdk.Cursor.new(Gdk.CursorType.HAND2),
- cursors.POINTER : Gdk.Cursor.new(Gdk.CursorType.LEFT_PTR),
- cursors.SELECT_REGION : Gdk.Cursor.new(Gdk.CursorType.TCROSS),
- cursors.WAIT : Gdk.Cursor.new(Gdk.CursorType.WATCH),
- }
-
-
-class TimerGTK3(TimerBase):
- '''
- Subclass of :class:`backend_bases.TimerBase` using GTK3 for timer events.
-
- Attributes
- ----------
- interval : int
- The time between timer events in milliseconds. Default is 1000 ms.
- single_shot : bool
- Boolean flag indicating whether this timer should operate as single
- shot (run once and then stop). Defaults to False.
- callbacks : list
- Stores list of (func, args) tuples that will be called upon timer
- events. This list can be manipulated directly, or the functions
- `add_callback` and `remove_callback` can be used.
-
- '''
- def _timer_start(self):
- # Need to stop it, otherwise we potentially leak a timer id that will
- # never be stopped.
- self._timer_stop()
- self._timer = GLib.timeout_add(self._interval, self._on_timer)
-
- def _timer_stop(self):
- if self._timer is not None:
- GLib.source_remove(self._timer)
- self._timer = None
-
- def _timer_set_interval(self):
- # Only stop and restart it if the timer has already been started
- if self._timer is not None:
- self._timer_stop()
- self._timer_start()
-
- def _on_timer(self):
- TimerBase._on_timer(self)
-
- # Gtk timeout_add() requires that the callback returns True if it
- # is to be called again.
- if len(self.callbacks) > 0 and not self._single:
- return True
- else:
- self._timer = None
- return False
-
-
-class FigureCanvasGTK3(Gtk.DrawingArea, FigureCanvasBase):
- keyvald = {65507 : 'control',
- 65505 : 'shift',
- 65513 : 'alt',
- 65508 : 'control',
- 65506 : 'shift',
- 65514 : 'alt',
- 65361 : 'left',
- 65362 : 'up',
- 65363 : 'right',
- 65364 : 'down',
- 65307 : 'escape',
- 65470 : 'f1',
- 65471 : 'f2',
- 65472 : 'f3',
- 65473 : 'f4',
- 65474 : 'f5',
- 65475 : 'f6',
- 65476 : 'f7',
- 65477 : 'f8',
- 65478 : 'f9',
- 65479 : 'f10',
- 65480 : 'f11',
- 65481 : 'f12',
- 65300 : 'scroll_lock',
- 65299 : 'break',
- 65288 : 'backspace',
- 65293 : 'enter',
- 65379 : 'insert',
- 65535 : 'delete',
- 65360 : 'home',
- 65367 : 'end',
- 65365 : 'pageup',
- 65366 : 'pagedown',
- 65438 : '0',
- 65436 : '1',
- 65433 : '2',
- 65435 : '3',
- 65430 : '4',
- 65437 : '5',
- 65432 : '6',
- 65429 : '7',
- 65431 : '8',
- 65434 : '9',
- 65451 : '+',
- 65453 : '-',
- 65450 : '*',
- 65455 : '/',
- 65439 : 'dec',
- 65421 : 'enter',
- }
-
- # Setting this as a static constant prevents
- # this resulting expression from leaking
- event_mask = (Gdk.EventMask.BUTTON_PRESS_MASK |
- Gdk.EventMask.BUTTON_RELEASE_MASK |
- Gdk.EventMask.EXPOSURE_MASK |
- Gdk.EventMask.KEY_PRESS_MASK |
- Gdk.EventMask.KEY_RELEASE_MASK |
- Gdk.EventMask.ENTER_NOTIFY_MASK |
- Gdk.EventMask.LEAVE_NOTIFY_MASK |
- Gdk.EventMask.POINTER_MOTION_MASK |
- Gdk.EventMask.POINTER_MOTION_HINT_MASK|
- Gdk.EventMask.SCROLL_MASK)
-
- def __init__(self, figure):
- FigureCanvasBase.__init__(self, figure)
- GObject.GObject.__init__(self)
-
- self._idle_draw_id = 0
- self._lastCursor = None
-
- self.connect('scroll_event', self.scroll_event)
- self.connect('button_press_event', self.button_press_event)
- self.connect('button_release_event', self.button_release_event)
- self.connect('configure_event', self.configure_event)
- self.connect('draw', self.on_draw_event)
- self.connect('key_press_event', self.key_press_event)
- self.connect('key_release_event', self.key_release_event)
- self.connect('motion_notify_event', self.motion_notify_event)
- self.connect('leave_notify_event', self.leave_notify_event)
- self.connect('enter_notify_event', self.enter_notify_event)
- self.connect('size_allocate', self.size_allocate)
-
- self.set_events(self.__class__.event_mask)
-
- self.set_double_buffered(True)
- self.set_can_focus(True)
- self._renderer_init()
- default_context = GLib.main_context_get_thread_default() or GLib.main_context_default()
-
- def destroy(self):
- #Gtk.DrawingArea.destroy(self)
- self.close_event()
- if self._idle_draw_id != 0:
- GLib.source_remove(self._idle_draw_id)
-
- def scroll_event(self, widget, event):
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.get_allocation().height - event.y
- if event.direction==Gdk.ScrollDirection.UP:
- step = 1
- else:
- step = -1
- FigureCanvasBase.scroll_event(self, x, y, step, guiEvent=event)
- return False # finish event propagation?
-
- def button_press_event(self, widget, event):
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.get_allocation().height - event.y
- FigureCanvasBase.button_press_event(self, x, y, event.button, guiEvent=event)
- return False # finish event propagation?
-
- def button_release_event(self, widget, event):
- x = event.x
- # flipy so y=0 is bottom of canvas
- y = self.get_allocation().height - event.y
- FigureCanvasBase.button_release_event(self, x, y, event.button, guiEvent=event)
- return False # finish event propagation?
-
- def key_press_event(self, widget, event):
- key = self._get_key(event)
- FigureCanvasBase.key_press_event(self, key, guiEvent=event)
- return True # stop event propagation
-
- def key_release_event(self, widget, event):
- key = self._get_key(event)
- FigureCanvasBase.key_release_event(self, key, guiEvent=event)
- return True # stop event propagation
-
- def motion_notify_event(self, widget, event):
- if event.is_hint:
- t, x, y, state = event.window.get_pointer()
- else:
- x, y, state = event.x, event.y, event.get_state()
-
- # flipy so y=0 is bottom of canvas
- y = self.get_allocation().height - y
- FigureCanvasBase.motion_notify_event(self, x, y, guiEvent=event)
- return False # finish event propagation?
-
- def leave_notify_event(self, widget, event):
- FigureCanvasBase.leave_notify_event(self, event)
-
- def enter_notify_event(self, widget, event):
- FigureCanvasBase.enter_notify_event(self, event)
-
- def size_allocate(self, widget, allocation):
- dpival = self.figure.dpi
- winch = allocation.width / dpival
- hinch = allocation.height / dpival
- self.figure.set_size_inches(winch, hinch, forward=False)
- FigureCanvasBase.resize_event(self)
- self.draw_idle()
-
- def _get_key(self, event):
- if event.keyval in self.keyvald:
- key = self.keyvald[event.keyval]
- elif event.keyval < 256:
- key = chr(event.keyval)
- else:
- key = None
-
- modifiers = [
- (Gdk.ModifierType.MOD4_MASK, 'super'),
- (Gdk.ModifierType.MOD1_MASK, 'alt'),
- (Gdk.ModifierType.CONTROL_MASK, 'ctrl'),
- ]
- for key_mask, prefix in modifiers:
- if event.state & key_mask:
- key = '{0}+{1}'.format(prefix, key)
-
- return key
-
- def configure_event(self, widget, event):
- if widget.get_property("window") is None:
- return
- w, h = event.width, event.height
- if w < 3 or h < 3:
- return # empty fig
- # resize the figure (in inches)
- dpi = self.figure.dpi
- self.figure.set_size_inches(w/dpi, h/dpi, forward=False)
- return False # finish event propagation?
-
- def on_draw_event(self, widget, ctx):
- # to be overwritten by GTK3Agg or GTK3Cairo
- pass
-
- def draw(self):
- if self.get_visible() and self.get_mapped():
- self.queue_draw()
- # do a synchronous draw (its less efficient than an async draw,
- # but is required if/when animation is used)
- self.get_property("window").process_updates (False)
-
- def draw_idle(self):
- if self._idle_draw_id != 0:
- return
- def idle_draw(*args):
- try:
- self.draw()
- finally:
- self._idle_draw_id = 0
- return False
- self._idle_draw_id = GLib.idle_add(idle_draw)
-
- def new_timer(self, *args, **kwargs):
- """
- Creates a new backend-specific subclass of :class:`backend_bases.Timer`.
- This is useful for getting periodic events through the backend's native
- event loop. Implemented only for backends with GUIs.
-
- Other Parameters
- ----------------
- interval : scalar
- Timer interval in milliseconds
- callbacks : list
- Sequence of (func, args, kwargs) where ``func(*args, **kwargs)``
- will be executed by the timer every *interval*.
- """
- return TimerGTK3(*args, **kwargs)
-
- def flush_events(self):
- Gdk.threads_enter()
- while Gtk.events_pending():
- Gtk.main_iteration()
- Gdk.flush()
- Gdk.threads_leave()
-
-
-class FigureManagerGTK3(FigureManagerBase):
- """
- Attributes
- ----------
- canvas : `FigureCanvas`
- The FigureCanvas instance
- num : int or str
- The Figure number
- toolbar : Gtk.Toolbar
- The Gtk.Toolbar (gtk only)
- vbox : Gtk.VBox
- The Gtk.VBox containing the canvas and toolbar (gtk only)
- window : Gtk.Window
- The Gtk.Window (gtk only)
-
- """
- def __init__(self, canvas, num):
- FigureManagerBase.__init__(self, canvas, num)
-
- self.window = Gtk.Window()
- self.window.set_wmclass("matplotlib", "Matplotlib")
- self.set_window_title("Figure %d" % num)
- try:
- self.window.set_icon_from_file(window_icon)
- except (SystemExit, KeyboardInterrupt):
- # re-raise exit type Exceptions
- raise
- except:
- # some versions of gtk throw a glib.GError but not
- # all, so I am not sure how to catch it. I am unhappy
- # doing a blanket catch here, but am not sure what a
- # better way is - JDH
- _log.info('Could not load matplotlib icon: %s', sys.exc_info()[1])
-
- self.vbox = Gtk.Box()
- self.vbox.set_property("orientation", Gtk.Orientation.VERTICAL)
- self.window.add(self.vbox)
- self.vbox.show()
-
- self.canvas.show()
-
- self.vbox.pack_start(self.canvas, True, True, 0)
- # calculate size for window
- w = int (self.canvas.figure.bbox.width)
- h = int (self.canvas.figure.bbox.height)
-
- self.toolmanager = self._get_toolmanager()
- self.toolbar = self._get_toolbar()
- self.statusbar = None
-
- def add_widget(child, expand, fill, padding):
- child.show()
- self.vbox.pack_end(child, False, False, 0)
- size_request = child.size_request()
- return size_request.height
-
- if self.toolmanager:
- backend_tools.add_tools_to_manager(self.toolmanager)
- if self.toolbar:
- backend_tools.add_tools_to_container(self.toolbar)
- self.statusbar = StatusbarGTK3(self.toolmanager)
- h += add_widget(self.statusbar, False, False, 0)
- h += add_widget(Gtk.HSeparator(), False, False, 0)
-
- if self.toolbar is not None:
- self.toolbar.show()
- h += add_widget(self.toolbar, False, False, 0)
-
- self.window.set_default_size (w, h)
-
- def destroy(*args):
- Gcf.destroy(num)
- self.window.connect("destroy", destroy)
- self.window.connect("delete_event", destroy)
- if matplotlib.is_interactive():
- self.window.show()
- self.canvas.draw_idle()
-
- def notify_axes_change(fig):
- 'this will be called whenever the current axes is changed'
- if self.toolmanager is not None:
- pass
- elif self.toolbar is not None:
- self.toolbar.update()
- self.canvas.figure.add_axobserver(notify_axes_change)
-
- self.canvas.grab_focus()
-
- def destroy(self, *args):
- self.vbox.destroy()
- self.window.destroy()
- self.canvas.destroy()
- if self.toolbar:
- self.toolbar.destroy()
-
- if (Gcf.get_num_fig_managers() == 0 and
- not matplotlib.is_interactive() and
- Gtk.main_level() >= 1):
- Gtk.main_quit()
-
- def show(self):
- # show the figure window
- self.window.show()
- self.window.present()
-
- def full_screen_toggle (self):
- self._full_screen_flag = not self._full_screen_flag
- if self._full_screen_flag:
- self.window.fullscreen()
- else:
- self.window.unfullscreen()
- _full_screen_flag = False
-
- def _get_toolbar(self):
- # must be inited after the window, drawingArea and figure
- # attrs are set
- if rcParams['toolbar'] == 'toolbar2':
- toolbar = NavigationToolbar2GTK3(self.canvas, self.window)
- elif rcParams['toolbar'] == 'toolmanager':
- toolbar = ToolbarGTK3(self.toolmanager)
- else:
- toolbar = None
- return toolbar
-
- def _get_toolmanager(self):
- # must be initialised after toolbar has been set
- if rcParams['toolbar'] == 'toolmanager':
- toolmanager = ToolManager(self.canvas.figure)
- else:
- toolmanager = None
- return toolmanager
-
- def get_window_title(self):
- return self.window.get_title()
-
- def set_window_title(self, title):
- self.window.set_title(title)
-
- def resize(self, width, height):
- 'set the canvas size in pixels'
- #_, _, cw, ch = self.canvas.allocation
- #_, _, ww, wh = self.window.allocation
- #self.window.resize (width-cw+ww, height-ch+wh)
- self.window.resize(width, height)
-
-
-class NavigationToolbar2GTK3(NavigationToolbar2, Gtk.Toolbar):
- def __init__(self, canvas, window):
- self.win = window
- GObject.GObject.__init__(self)
- NavigationToolbar2.__init__(self, canvas)
- self.ctx = None
-
- def set_message(self, s):
- self.message.set_label(s)
-
- def set_cursor(self, cursor):
- self.canvas.get_property("window").set_cursor(cursord[cursor])
- Gtk.main_iteration()
-
- def release(self, event):
- try: del self._pixmapBack
- except AttributeError: pass
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- 'adapted from http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/189744'
- self.ctx = self.canvas.get_property("window").cairo_create()
-
- # todo: instead of redrawing the entire figure, copy the part of
- # the figure that was covered by the previous rubberband rectangle
- self.canvas.draw()
-
- height = self.canvas.figure.bbox.height
- y1 = height - y1
- y0 = height - y0
- w = abs(x1 - x0)
- h = abs(y1 - y0)
- rect = [int(val) for val in (min(x0,x1), min(y0, y1), w, h)]
-
- self.ctx.new_path()
- self.ctx.set_line_width(0.5)
- self.ctx.rectangle(rect[0], rect[1], rect[2], rect[3])
- self.ctx.set_source_rgb(0, 0, 0)
- self.ctx.stroke()
-
- def _init_toolbar(self):
- self.set_style(Gtk.ToolbarStyle.ICONS)
- basedir = os.path.join(rcParams['datapath'],'images')
-
- for text, tooltip_text, image_file, callback in self.toolitems:
- if text is None:
- self.insert( Gtk.SeparatorToolItem(), -1 )
- continue
- fname = os.path.join(basedir, image_file + '.png')
- image = Gtk.Image()
- image.set_from_file(fname)
- tbutton = Gtk.ToolButton()
- tbutton.set_label(text)
- tbutton.set_icon_widget(image)
- self.insert(tbutton, -1)
- tbutton.connect('clicked', getattr(self, callback))
- tbutton.set_tooltip_text(tooltip_text)
-
- toolitem = Gtk.SeparatorToolItem()
- self.insert(toolitem, -1)
- toolitem.set_draw(False)
- toolitem.set_expand(True)
-
- toolitem = Gtk.ToolItem()
- self.insert(toolitem, -1)
- self.message = Gtk.Label()
- toolitem.add(self.message)
-
- self.show_all()
-
- def get_filechooser(self):
- fc = FileChooserDialog(
- title='Save the figure',
- parent=self.win,
- path=os.path.expanduser(rcParams['savefig.directory']),
- filetypes=self.canvas.get_supported_filetypes(),
- default_filetype=self.canvas.get_default_filetype())
- fc.set_current_name(self.canvas.get_default_filename())
- return fc
-
- def save_figure(self, *args):
- chooser = self.get_filechooser()
- fname, format = chooser.get_filename_from_user()
- chooser.destroy()
- if fname:
- startpath = os.path.expanduser(rcParams['savefig.directory'])
- # Save dir for next time, unless empty str (i.e., use cwd).
- if startpath != "":
- rcParams['savefig.directory'] = (
- os.path.dirname(six.text_type(fname)))
- try:
- self.canvas.figure.savefig(fname, format=format)
- except Exception as e:
- error_msg_gtk(str(e), parent=self)
-
- def configure_subplots(self, button):
- toolfig = Figure(figsize=(6,3))
- canvas = self._get_canvas(toolfig)
- toolfig.subplots_adjust(top=0.9)
- tool = SubplotTool(self.canvas.figure, toolfig)
-
- w = int(toolfig.bbox.width)
- h = int(toolfig.bbox.height)
-
- window = Gtk.Window()
- try:
- window.set_icon_from_file(window_icon)
- except (SystemExit, KeyboardInterrupt):
- # re-raise exit type Exceptions
- raise
- except:
- # we presumably already logged a message on the
- # failure of the main plot, don't keep reporting
- pass
- window.set_title("Subplot Configuration Tool")
- window.set_default_size(w, h)
- vbox = Gtk.Box()
- vbox.set_property("orientation", Gtk.Orientation.VERTICAL)
- window.add(vbox)
- vbox.show()
-
- canvas.show()
- vbox.pack_start(canvas, True, True, 0)
- window.show()
-
- def _get_canvas(self, fig):
- return self.canvas.__class__(fig)
-
-
-class FileChooserDialog(Gtk.FileChooserDialog):
- """GTK+ file selector which remembers the last file/directory
- selected and presents the user with a menu of supported image formats
- """
- def __init__ (self,
- title = 'Save file',
- parent = None,
- action = Gtk.FileChooserAction.SAVE,
- buttons = (Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
- Gtk.STOCK_SAVE, Gtk.ResponseType.OK),
- path = None,
- filetypes = [],
- default_filetype = None
- ):
- super (FileChooserDialog, self).__init__ (title, parent, action,
- buttons)
- self.set_default_response (Gtk.ResponseType.OK)
-
- if not path: path = os.getcwd() + os.sep
-
- # create an extra widget to list supported image formats
- self.set_current_folder (path)
- self.set_current_name ('image.' + default_filetype)
-
- hbox = Gtk.Box(spacing=10)
- hbox.pack_start(Gtk.Label(label="File Format:"), False, False, 0)
-
- liststore = Gtk.ListStore(GObject.TYPE_STRING)
- cbox = Gtk.ComboBox() #liststore)
- cbox.set_model(liststore)
- cell = Gtk.CellRendererText()
- cbox.pack_start(cell, True)
- cbox.add_attribute(cell, 'text', 0)
- hbox.pack_start(cbox, False, False, 0)
-
- self.filetypes = filetypes
- self.sorted_filetypes = sorted(six.iteritems(filetypes))
- default = 0
- for i, (ext, name) in enumerate(self.sorted_filetypes):
- liststore.append(["%s (*.%s)" % (name, ext)])
- if ext == default_filetype:
- default = i
- cbox.set_active(default)
- self.ext = default_filetype
-
- def cb_cbox_changed (cbox, data=None):
- """File extension changed"""
- head, filename = os.path.split(self.get_filename())
- root, ext = os.path.splitext(filename)
- ext = ext[1:]
- new_ext = self.sorted_filetypes[cbox.get_active()][0]
- self.ext = new_ext
-
- if ext in self.filetypes:
- filename = root + '.' + new_ext
- elif ext == '':
- filename = filename.rstrip('.') + '.' + new_ext
-
- self.set_current_name (filename)
- cbox.connect ("changed", cb_cbox_changed)
-
- hbox.show_all()
- self.set_extra_widget(hbox)
-
- def get_filename_from_user (self):
- while True:
- filename = None
- if self.run() != int(Gtk.ResponseType.OK):
- break
- filename = self.get_filename()
- break
-
- return filename, self.ext
-
-
-class RubberbandGTK3(backend_tools.RubberbandBase):
- def __init__(self, *args, **kwargs):
- backend_tools.RubberbandBase.__init__(self, *args, **kwargs)
- self.ctx = None
-
- def draw_rubberband(self, x0, y0, x1, y1):
- # 'adapted from http://aspn.activestate.com/ASPN/Cookbook/Python/
- # Recipe/189744'
- self.ctx = self.figure.canvas.get_property("window").cairo_create()
-
- # todo: instead of redrawing the entire figure, copy the part of
- # the figure that was covered by the previous rubberband rectangle
- self.figure.canvas.draw()
-
- height = self.figure.bbox.height
- y1 = height - y1
- y0 = height - y0
- w = abs(x1 - x0)
- h = abs(y1 - y0)
- rect = [int(val) for val in (min(x0, x1), min(y0, y1), w, h)]
-
- self.ctx.new_path()
- self.ctx.set_line_width(0.5)
- self.ctx.rectangle(rect[0], rect[1], rect[2], rect[3])
- self.ctx.set_source_rgb(0, 0, 0)
- self.ctx.stroke()
-
-
-class ToolbarGTK3(ToolContainerBase, Gtk.Box):
- _icon_extension = '.png'
- def __init__(self, toolmanager):
- ToolContainerBase.__init__(self, toolmanager)
- Gtk.Box.__init__(self)
- self.set_property("orientation", Gtk.Orientation.VERTICAL)
-
- self._toolarea = Gtk.Box()
- self._toolarea.set_property('orientation', Gtk.Orientation.HORIZONTAL)
- self.pack_start(self._toolarea, False, False, 0)
- self._toolarea.show_all()
- self._groups = {}
- self._toolitems = {}
-
- def add_toolitem(self, name, group, position, image_file, description,
- toggle):
- if toggle:
- tbutton = Gtk.ToggleToolButton()
- else:
- tbutton = Gtk.ToolButton()
- tbutton.set_label(name)
-
- if image_file is not None:
- image = Gtk.Image()
- image.set_from_file(image_file)
- tbutton.set_icon_widget(image)
-
- if position is None:
- position = -1
-
- self._add_button(tbutton, group, position)
- signal = tbutton.connect('clicked', self._call_tool, name)
- tbutton.set_tooltip_text(description)
- tbutton.show_all()
- self._toolitems.setdefault(name, [])
- self._toolitems[name].append((tbutton, signal))
-
- def _add_button(self, button, group, position):
- if group not in self._groups:
- if self._groups:
- self._add_separator()
- toolbar = Gtk.Toolbar()
- toolbar.set_style(Gtk.ToolbarStyle.ICONS)
- self._toolarea.pack_start(toolbar, False, False, 0)
- toolbar.show_all()
- self._groups[group] = toolbar
- self._groups[group].insert(button, position)
-
- def _call_tool(self, btn, name):
- self.trigger_tool(name)
-
- def toggle_toolitem(self, name, toggled):
- if name not in self._toolitems:
- return
- for toolitem, signal in self._toolitems[name]:
- toolitem.handler_block(signal)
- toolitem.set_active(toggled)
- toolitem.handler_unblock(signal)
-
- def remove_toolitem(self, name):
- if name not in self._toolitems:
- self.toolmanager.message_event('%s Not in toolbar' % name, self)
- return
-
- for group in self._groups:
- for toolitem, _signal in self._toolitems[name]:
- if toolitem in self._groups[group]:
- self._groups[group].remove(toolitem)
- del self._toolitems[name]
-
- def _add_separator(self):
- sep = Gtk.Separator()
- sep.set_property("orientation", Gtk.Orientation.VERTICAL)
- self._toolarea.pack_start(sep, False, True, 0)
- sep.show_all()
-
-
-class StatusbarGTK3(StatusbarBase, Gtk.Statusbar):
- def __init__(self, *args, **kwargs):
- StatusbarBase.__init__(self, *args, **kwargs)
- Gtk.Statusbar.__init__(self)
- self._context = self.get_context_id('message')
-
- def set_message(self, s):
- self.pop(self._context)
- self.push(self._context, s)
-
-
-class SaveFigureGTK3(backend_tools.SaveFigureBase):
-
- def get_filechooser(self):
- fc = FileChooserDialog(
- title='Save the figure',
- parent=self.figure.canvas.manager.window,
- path=os.path.expanduser(rcParams['savefig.directory']),
- filetypes=self.figure.canvas.get_supported_filetypes(),
- default_filetype=self.figure.canvas.get_default_filetype())
- fc.set_current_name(self.figure.canvas.get_default_filename())
- return fc
-
- def trigger(self, *args, **kwargs):
- chooser = self.get_filechooser()
- fname, format_ = chooser.get_filename_from_user()
- chooser.destroy()
- if fname:
- startpath = os.path.expanduser(rcParams['savefig.directory'])
- if startpath == '':
- # explicitly missing key or empty str signals to use cwd
- rcParams['savefig.directory'] = startpath
- else:
- # save dir for next time
- rcParams['savefig.directory'] = os.path.dirname(
- six.text_type(fname))
- try:
- self.figure.canvas.print_figure(fname, format=format_)
- except Exception as e:
- error_msg_gtk(str(e), parent=self)
-
-
-class SetCursorGTK3(backend_tools.SetCursorBase):
- def set_cursor(self, cursor):
- self.figure.canvas.get_property("window").set_cursor(cursord[cursor])
-
-
-class ConfigureSubplotsGTK3(backend_tools.ConfigureSubplotsBase, Gtk.Window):
- def __init__(self, *args, **kwargs):
- backend_tools.ConfigureSubplotsBase.__init__(self, *args, **kwargs)
- self.window = None
-
- def init_window(self):
- if self.window:
- return
- self.window = Gtk.Window(title="Subplot Configuration Tool")
-
- try:
- self.window.window.set_icon_from_file(window_icon)
- except (SystemExit, KeyboardInterrupt):
- # re-raise exit type Exceptions
- raise
- except:
- # we presumably already logged a message on the
- # failure of the main plot, don't keep reporting
- pass
-
- self.vbox = Gtk.Box()
- self.vbox.set_property("orientation", Gtk.Orientation.VERTICAL)
- self.window.add(self.vbox)
- self.vbox.show()
- self.window.connect('destroy', self.destroy)
-
- toolfig = Figure(figsize=(6, 3))
- canvas = self.figure.canvas.__class__(toolfig)
-
- toolfig.subplots_adjust(top=0.9)
- SubplotTool(self.figure, toolfig)
-
- w = int(toolfig.bbox.width)
- h = int(toolfig.bbox.height)
-
- self.window.set_default_size(w, h)
-
- canvas.show()
- self.vbox.pack_start(canvas, True, True, 0)
- self.window.show()
-
- def destroy(self, *args):
- self.window.destroy()
- self.window = None
-
- def _get_canvas(self, fig):
- return self.canvas.__class__(fig)
-
- def trigger(self, sender, event, data=None):
- self.init_window()
- self.window.present()
-
-
-# Define the file to use as the GTk icon
-if sys.platform == 'win32':
- icon_filename = 'matplotlib.png'
-else:
- icon_filename = 'matplotlib.svg'
-window_icon = os.path.join(
- matplotlib.rcParams['datapath'], 'images', icon_filename)
-
-
-def error_msg_gtk(msg, parent=None):
- if parent is not None: # find the toplevel Gtk.Window
- parent = parent.get_toplevel()
- if not parent.is_toplevel():
- parent = None
-
- if not isinstance(msg, six.string_types):
- msg = ','.join(map(str, msg))
-
- dialog = Gtk.MessageDialog(
- parent = parent,
- type = Gtk.MessageType.ERROR,
- buttons = Gtk.ButtonsType.OK,
- message_format = msg)
- dialog.run()
- dialog.destroy()
-
-
-backend_tools.ToolSaveFigure = SaveFigureGTK3
-backend_tools.ToolConfigureSubplots = ConfigureSubplotsGTK3
-backend_tools.ToolSetCursor = SetCursorGTK3
-backend_tools.ToolRubberband = RubberbandGTK3
-
-Toolbar = ToolbarGTK3
-
-
-@_Backend.export
-class _BackendGTK3(_Backend):
- FigureCanvas = FigureCanvasGTK3
- FigureManager = FigureManagerGTK3
-
- @staticmethod
- def trigger_manager_draw(manager):
- manager.canvas.draw_idle()
-
- @staticmethod
- def mainloop():
- if Gtk.main_level() == 0:
- Gtk.main()
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtk3agg.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtk3agg.py
deleted file mode 100644
index 53c625b8a5..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtk3agg.py
+++ /dev/null
@@ -1,102 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import numpy as np
-import warnings
-
-from . import backend_agg, backend_gtk3
-from .backend_cairo import cairo, HAS_CAIRO_CFFI
-from .backend_gtk3 import _BackendGTK3
-from matplotlib import transforms
-
-if six.PY3 and not HAS_CAIRO_CFFI:
- warnings.warn(
- "The Gtk3Agg backend is known to not work on Python 3.x with pycairo. "
- "Try installing cairocffi.")
-
-
-class FigureCanvasGTK3Agg(backend_gtk3.FigureCanvasGTK3,
- backend_agg.FigureCanvasAgg):
- def __init__(self, figure):
- backend_gtk3.FigureCanvasGTK3.__init__(self, figure)
- self._bbox_queue = []
-
- def _renderer_init(self):
- pass
-
- def _render_figure(self, width, height):
- backend_agg.FigureCanvasAgg.draw(self)
-
- def on_draw_event(self, widget, ctx):
- """ GtkDrawable draw event, like expose_event in GTK 2.X
- """
- allocation = self.get_allocation()
- w, h = allocation.width, allocation.height
-
- if not len(self._bbox_queue):
- self._render_figure(w, h)
- bbox_queue = [transforms.Bbox([[0, 0], [w, h]])]
- else:
- bbox_queue = self._bbox_queue
-
- if HAS_CAIRO_CFFI and not isinstance(ctx, cairo.Context):
- ctx = cairo.Context._from_pointer(
- cairo.ffi.cast('cairo_t **',
- id(ctx) + object.__basicsize__)[0],
- incref=True)
-
- for bbox in bbox_queue:
- area = self.copy_from_bbox(bbox)
- buf = np.fromstring(area.to_string_argb(), dtype='uint8')
-
- x = int(bbox.x0)
- y = h - int(bbox.y1)
- width = int(bbox.x1) - int(bbox.x0)
- height = int(bbox.y1) - int(bbox.y0)
-
- if HAS_CAIRO_CFFI:
- image = cairo.ImageSurface.create_for_data(
- buf.data, cairo.FORMAT_ARGB32, width, height)
- else:
- image = cairo.ImageSurface.create_for_data(
- buf, cairo.FORMAT_ARGB32, width, height)
- ctx.set_source_surface(image, x, y)
- ctx.paint()
-
- if len(self._bbox_queue):
- self._bbox_queue = []
-
- return False
-
- def blit(self, bbox=None):
- # If bbox is None, blit the entire canvas to gtk. Otherwise
- # blit only the area defined by the bbox.
- if bbox is None:
- bbox = self.figure.bbox
-
- allocation = self.get_allocation()
- w, h = allocation.width, allocation.height
- x = int(bbox.x0)
- y = h - int(bbox.y1)
- width = int(bbox.x1) - int(bbox.x0)
- height = int(bbox.y1) - int(bbox.y0)
-
- self._bbox_queue.append(bbox)
- self.queue_draw_area(x, y, width, height)
-
- def print_png(self, filename, *args, **kwargs):
- # Do this so we can save the resolution of figure in the PNG file
- agg = self.switch_backends(backend_agg.FigureCanvasAgg)
- return agg.print_png(filename, *args, **kwargs)
-
-
-class FigureManagerGTK3Agg(backend_gtk3.FigureManagerGTK3):
- pass
-
-
-@_BackendGTK3.export
-class _BackendGTK3Cairo(_BackendGTK3):
- FigureCanvas = FigureCanvasGTK3Agg
- FigureManager = FigureManagerGTK3Agg
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtk3cairo.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtk3cairo.py
deleted file mode 100644
index 2591b112d2..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtk3cairo.py
+++ /dev/null
@@ -1,55 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from . import backend_cairo, backend_gtk3
-from .backend_cairo import cairo, HAS_CAIRO_CFFI
-from .backend_gtk3 import _BackendGTK3
-from matplotlib.backend_bases import cursors
-
-
-class RendererGTK3Cairo(backend_cairo.RendererCairo):
- def set_context(self, ctx):
- if HAS_CAIRO_CFFI and not isinstance(ctx, cairo.Context):
- ctx = cairo.Context._from_pointer(
- cairo.ffi.cast(
- 'cairo_t **',
- id(ctx) + object.__basicsize__)[0],
- incref=True)
-
- self.gc.ctx = ctx
-
-
-class FigureCanvasGTK3Cairo(backend_gtk3.FigureCanvasGTK3,
- backend_cairo.FigureCanvasCairo):
-
- def _renderer_init(self):
- """Use cairo renderer."""
- self._renderer = RendererGTK3Cairo(self.figure.dpi)
-
- def _render_figure(self, width, height):
- self._renderer.set_width_height(width, height)
- self.figure.draw(self._renderer)
-
- def on_draw_event(self, widget, ctx):
- """GtkDrawable draw event."""
- toolbar = self.toolbar
- # if toolbar:
- # toolbar.set_cursor(cursors.WAIT)
- self._renderer.set_context(ctx)
- allocation = self.get_allocation()
- self._render_figure(allocation.width, allocation.height)
- # if toolbar:
- # toolbar.set_cursor(toolbar._lastCursor)
- return False # finish event propagation?
-
-
-class FigureManagerGTK3Cairo(backend_gtk3.FigureManagerGTK3):
- pass
-
-
-@_BackendGTK3.export
-class _BackendGTK3Cairo(_BackendGTK3):
- FigureCanvas = FigureCanvasGTK3Cairo
- FigureManager = FigureManagerGTK3Cairo
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtkagg.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtkagg.py
deleted file mode 100644
index 14240647cc..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtkagg.py
+++ /dev/null
@@ -1,96 +0,0 @@
-"""
-Render to gtk from agg
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import matplotlib
-from matplotlib.cbook import warn_deprecated
-from matplotlib.backends.backend_agg import FigureCanvasAgg
-from matplotlib.backends.backend_gtk import (
- gtk, _BackendGTK, FigureCanvasGTK, FigureManagerGTK, NavigationToolbar2GTK,
- backend_version, error_msg_gtk, PIXELS_PER_INCH)
-from matplotlib.backends._gtkagg import agg_to_gtk_drawable
-
-
-class NavigationToolbar2GTKAgg(NavigationToolbar2GTK):
- def _get_canvas(self, fig):
- return FigureCanvasGTKAgg(fig)
-
-
-class FigureManagerGTKAgg(FigureManagerGTK):
- def _get_toolbar(self, canvas):
- # must be inited after the window, drawingArea and figure
- # attrs are set
- if matplotlib.rcParams['toolbar']=='toolbar2':
- toolbar = NavigationToolbar2GTKAgg (canvas, self.window)
- else:
- toolbar = None
- return toolbar
-
-
-class FigureCanvasGTKAgg(FigureCanvasGTK, FigureCanvasAgg):
- filetypes = FigureCanvasGTK.filetypes.copy()
- filetypes.update(FigureCanvasAgg.filetypes)
-
- def __init__(self, *args, **kwargs):
- warn_deprecated('2.2',
- message=('The GTKAgg backend is deprecated. It is '
- 'untested and will be removed in Matplotlib '
- '3.0. Use the GTK3Agg backend instead. See '
- 'Matplotlib usage FAQ for more info on '
- 'backends.'),
- alternative='GTK3Agg')
- super(FigureCanvasGTKAgg, self).__init__(*args, **kwargs)
-
- def configure_event(self, widget, event=None):
-
- if widget.window is None:
- return
- try:
- del self.renderer
- except AttributeError:
- pass
- w,h = widget.window.get_size()
- if w==1 or h==1: return # empty fig
-
- # compute desired figure size in inches
- dpival = self.figure.dpi
- winch = w/dpival
- hinch = h/dpival
- self.figure.set_size_inches(winch, hinch, forward=False)
- self._need_redraw = True
- self.resize_event()
- return True
-
- def _render_figure(self, pixmap, width, height):
- FigureCanvasAgg.draw(self)
-
- buf = self.buffer_rgba()
- ren = self.get_renderer()
- w = int(ren.width)
- h = int(ren.height)
-
- pixbuf = gtk.gdk.pixbuf_new_from_data(
- buf, gtk.gdk.COLORSPACE_RGB, True, 8, w, h, w*4)
- pixmap.draw_pixbuf(pixmap.new_gc(), pixbuf, 0, 0, 0, 0, w, h,
- gtk.gdk.RGB_DITHER_NONE, 0, 0)
-
- def blit(self, bbox=None):
- agg_to_gtk_drawable(self._pixmap, self.renderer._renderer, bbox)
- x, y, w, h = self.allocation
- self.window.draw_drawable(self.style.fg_gc[self.state], self._pixmap,
- 0, 0, 0, 0, w, h)
-
- def print_png(self, filename, *args, **kwargs):
- # Do this so we can save the resolution of figure in the PNG file
- agg = self.switch_backends(FigureCanvasAgg)
- return agg.print_png(filename, *args, **kwargs)
-
-
-@_BackendGTK.export
-class _BackendGTKAgg(_BackendGTK):
- FigureCanvas = FigureCanvasGTKAgg
- FigureManager = FigureManagerGTKAgg
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtkcairo.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtkcairo.py
deleted file mode 100644
index 87e6debae7..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_gtkcairo.py
+++ /dev/null
@@ -1,74 +0,0 @@
-"""
-GTK+ Matplotlib interface using cairo (not GDK) drawing operations.
-Author: Steve Chaplin
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import gtk
-if gtk.pygtk_version < (2, 7, 0):
- import cairo.gtk
-
-from matplotlib import cbook
-from matplotlib.backends import backend_cairo
-from matplotlib.backends.backend_gtk import *
-from matplotlib.backends.backend_gtk import _BackendGTK
-
-backend_version = ('PyGTK(%d.%d.%d) ' % gtk.pygtk_version
- + 'Pycairo(%s)' % backend_cairo.backend_version)
-
-
-class RendererGTKCairo (backend_cairo.RendererCairo):
- if gtk.pygtk_version >= (2,7,0):
- def set_pixmap (self, pixmap):
- self.gc.ctx = pixmap.cairo_create()
- else:
- def set_pixmap (self, pixmap):
- self.gc.ctx = cairo.gtk.gdk_cairo_create (pixmap)
-
-
-class FigureCanvasGTKCairo(backend_cairo.FigureCanvasCairo, FigureCanvasGTK):
- filetypes = FigureCanvasGTK.filetypes.copy()
- filetypes.update(backend_cairo.FigureCanvasCairo.filetypes)
-
- def __init__(self, *args, **kwargs):
- warn_deprecated('2.2',
- message=('The GTKCairo backend is deprecated. It is '
- 'untested and will be removed in Matplotlib '
- '3.0. Use the GTK3Cairo backend instead. See '
- 'Matplotlib usage FAQ for more info on '
- 'backends.'),
- alternative='GTK3Cairo')
- super(FigureCanvasGTKCairo, self).__init__(*args, **kwargs)
-
- def _renderer_init(self):
- """Override to use cairo (rather than GDK) renderer"""
- self._renderer = RendererGTKCairo(self.figure.dpi)
-
-
-# This class has been unused for a while at least.
-@cbook.deprecated("2.1")
-class FigureManagerGTKCairo(FigureManagerGTK):
- def _get_toolbar(self, canvas):
- # must be inited after the window, drawingArea and figure
- # attrs are set
- if matplotlib.rcParams['toolbar']=='toolbar2':
- toolbar = NavigationToolbar2GTKCairo (canvas, self.window)
- else:
- toolbar = None
- return toolbar
-
-
-# This class has been unused for a while at least.
-@cbook.deprecated("2.1")
-class NavigationToolbar2Cairo(NavigationToolbar2GTK):
- def _get_canvas(self, fig):
- return FigureCanvasGTKCairo(fig)
-
-
-@_BackendGTK.export
-class _BackendGTKCairo(_BackendGTK):
- FigureCanvas = FigureCanvasGTKCairo
- FigureManager = FigureManagerGTK
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_macosx.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_macosx.py
deleted file mode 100644
index 4ab5d0c907..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_macosx.py
+++ /dev/null
@@ -1,210 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import os
-
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2,
- TimerBase)
-
-from matplotlib.figure import Figure
-from matplotlib import rcParams
-
-from matplotlib.widgets import SubplotTool
-
-import matplotlib
-from matplotlib.backends import _macosx
-
-from .backend_agg import FigureCanvasAgg
-
-
-########################################################################
-#
-# The following functions and classes are for pylab and implement
-# window/figure managers, etc...
-#
-########################################################################
-
-
-class TimerMac(_macosx.Timer, TimerBase):
- '''
- Subclass of :class:`backend_bases.TimerBase` that uses CoreFoundation
- run loops for timer events.
-
- Attributes
- ----------
- interval : int
- The time between timer events in milliseconds. Default is 1000 ms.
- single_shot : bool
- Boolean flag indicating whether this timer should operate as single
- shot (run once and then stop). Defaults to False.
- callbacks : list
- Stores list of (func, args) tuples that will be called upon timer
- events. This list can be manipulated directly, or the functions
- `add_callback` and `remove_callback` can be used.
-
- '''
- # completely implemented at the C-level (in _macosx.Timer)
-
-
-class FigureCanvasMac(_macosx.FigureCanvas, FigureCanvasAgg):
- """
- The canvas the figure renders into. Calls the draw and print fig
- methods, creates the renderers, etc...
-
- Events such as button presses, mouse movements, and key presses
- are handled in the C code and the base class methods
- button_press_event, button_release_event, motion_notify_event,
- key_press_event, and key_release_event are called from there.
-
- Attributes
- ----------
- figure : `matplotlib.figure.Figure`
- A high-level Figure instance
-
- """
-
- def __init__(self, figure):
- FigureCanvasBase.__init__(self, figure)
- width, height = self.get_width_height()
- _macosx.FigureCanvas.__init__(self, width, height)
- self._device_scale = 1.0
-
- def _set_device_scale(self, value):
- if self._device_scale != value:
- self.figure.dpi = self.figure.dpi / self._device_scale * value
- self._device_scale = value
-
- def _draw(self):
- renderer = self.get_renderer(cleared=self.figure.stale)
-
- if self.figure.stale:
- self.figure.draw(renderer)
-
- return renderer
-
- def draw(self):
- self.invalidate()
- self.flush_events()
-
- def draw_idle(self, *args, **kwargs):
- self.invalidate()
-
- def blit(self, bbox):
- self.invalidate()
-
- def resize(self, width, height):
- dpi = self.figure.dpi
- width /= dpi
- height /= dpi
- self.figure.set_size_inches(width * self._device_scale,
- height * self._device_scale,
- forward=False)
- FigureCanvasBase.resize_event(self)
- self.draw_idle()
-
- def new_timer(self, *args, **kwargs):
- """
- Creates a new backend-specific subclass of `backend_bases.Timer`.
- This is useful for getting periodic events through the backend's native
- event loop. Implemented only for backends with GUIs.
-
- Other Parameters
- ----------------
- interval : scalar
- Timer interval in milliseconds
- callbacks : list
- Sequence of (func, args, kwargs) where ``func(*args, **kwargs)``
- will be executed by the timer every *interval*.
- """
- return TimerMac(*args, **kwargs)
-
-
-class FigureManagerMac(_macosx.FigureManager, FigureManagerBase):
- """
- Wrap everything up into a window for the pylab interface
- """
- def __init__(self, canvas, num):
- FigureManagerBase.__init__(self, canvas, num)
- title = "Figure %d" % num
- _macosx.FigureManager.__init__(self, canvas, title)
- if rcParams['toolbar']=='toolbar2':
- self.toolbar = NavigationToolbar2Mac(canvas)
- else:
- self.toolbar = None
- if self.toolbar is not None:
- self.toolbar.update()
-
- def notify_axes_change(fig):
- 'this will be called whenever the current axes is changed'
- if self.toolbar != None: self.toolbar.update()
- self.canvas.figure.add_axobserver(notify_axes_change)
-
- if matplotlib.is_interactive():
- self.show()
- self.canvas.draw_idle()
-
- def close(self):
- Gcf.destroy(self.num)
-
-
-class NavigationToolbar2Mac(_macosx.NavigationToolbar2, NavigationToolbar2):
-
- def __init__(self, canvas):
- NavigationToolbar2.__init__(self, canvas)
-
- def _init_toolbar(self):
- basedir = os.path.join(rcParams['datapath'], "images")
- _macosx.NavigationToolbar2.__init__(self, basedir)
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- self.canvas.set_rubberband(int(x0), int(y0), int(x1), int(y1))
-
- def release(self, event):
- self.canvas.remove_rubberband()
-
- def set_cursor(self, cursor):
- _macosx.set_cursor(cursor)
-
- def save_figure(self, *args):
- filename = _macosx.choose_save_file('Save the figure',
- self.canvas.get_default_filename())
- if filename is None: # Cancel
- return
- self.canvas.figure.savefig(filename)
-
- def prepare_configure_subplots(self):
- toolfig = Figure(figsize=(6,3))
- canvas = FigureCanvasMac(toolfig)
- toolfig.subplots_adjust(top=0.9)
- tool = SubplotTool(self.canvas.figure, toolfig)
- return canvas
-
- def set_message(self, message):
- _macosx.NavigationToolbar2.set_message(self, message.encode('utf-8'))
-
-
-########################################################################
-#
-# Now just provide the standard names that backend.__init__ is expecting
-#
-########################################################################
-
-@_Backend.export
-class _BackendMac(_Backend):
- FigureCanvas = FigureCanvasMac
- FigureManager = FigureManagerMac
-
- @staticmethod
- def trigger_manager_draw(manager):
- # For performance reasons, we don't want to redraw the figure after
- # each draw command. Instead, we mark the figure as invalid, so that it
- # will be redrawn as soon as the event loop resumes via PyOS_InputHook.
- # This function should be called after each draw event, even if
- # matplotlib is not running interactively.
- manager.canvas.invalidate()
-
- @staticmethod
- def mainloop():
- _macosx.show()
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_mixed.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_mixed.py
deleted file mode 100644
index 8e475bd13c..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_mixed.py
+++ /dev/null
@@ -1,155 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import numpy as np
-
-import six
-
-from matplotlib.backends.backend_agg import RendererAgg
-from matplotlib.tight_bbox import process_figure_for_rasterizing
-
-
-class MixedModeRenderer(object):
- """
- A helper class to implement a renderer that switches between
- vector and raster drawing. An example may be a PDF writer, where
- most things are drawn with PDF vector commands, but some very
- complex objects, such as quad meshes, are rasterised and then
- output as images.
- """
- def __init__(self, figure, width, height, dpi, vector_renderer,
- raster_renderer_class=None,
- bbox_inches_restore=None):
- """
- Parameters
- ----------
- figure : `matplotlib.figure.Figure`
- The figure instance.
-
- width : scalar
- The width of the canvas in logical units
-
- height : scalar
- The height of the canvas in logical units
-
- dpi : scalar
- The dpi of the canvas
-
- vector_renderer : `matplotlib.backend_bases.RendererBase`
- An instance of a subclass of
- `~matplotlib.backend_bases.RendererBase` that will be used for the
- vector drawing.
-
- raster_renderer_class : `matplotlib.backend_bases.RendererBase`
- The renderer class to use for the raster drawing. If not provided,
- this will use the Agg backend (which is currently the only viable
- option anyway.)
-
- """
- if raster_renderer_class is None:
- raster_renderer_class = RendererAgg
-
- self._raster_renderer_class = raster_renderer_class
- self._width = width
- self._height = height
- self.dpi = dpi
-
- self._vector_renderer = vector_renderer
-
- self._raster_renderer = None
- self._rasterizing = 0
-
- # A reference to the figure is needed as we need to change
- # the figure dpi before and after the rasterization. Although
- # this looks ugly, I couldn't find a better solution. -JJL
- self.figure = figure
- self._figdpi = figure.get_dpi()
-
- self._bbox_inches_restore = bbox_inches_restore
-
- self._set_current_renderer(vector_renderer)
-
- _methods = """
- close_group draw_image draw_markers draw_path
- draw_path_collection draw_quad_mesh draw_tex draw_text
- finalize flipy get_canvas_width_height get_image_magnification
- get_texmanager get_text_width_height_descent new_gc open_group
- option_image_nocomposite points_to_pixels strip_math
- start_filter stop_filter draw_gouraud_triangle
- draw_gouraud_triangles option_scale_image
- _text2path _get_text_path_transform height width
- """.split()
-
- def _set_current_renderer(self, renderer):
- self._renderer = renderer
-
- for method in self._methods:
- if hasattr(renderer, method):
- setattr(self, method, getattr(renderer, method))
- renderer.start_rasterizing = self.start_rasterizing
- renderer.stop_rasterizing = self.stop_rasterizing
-
- def start_rasterizing(self):
- """
- Enter "raster" mode. All subsequent drawing commands (until
- stop_rasterizing is called) will be drawn with the raster
- backend.
-
- If start_rasterizing is called multiple times before
- stop_rasterizing is called, this method has no effect.
- """
-
- # change the dpi of the figure temporarily.
- self.figure.set_dpi(self.dpi)
-
- if self._bbox_inches_restore: # when tight bbox is used
- r = process_figure_for_rasterizing(self.figure,
- self._bbox_inches_restore)
- self._bbox_inches_restore = r
-
- if self._rasterizing == 0:
- self._raster_renderer = self._raster_renderer_class(
- self._width*self.dpi, self._height*self.dpi, self.dpi)
- self._set_current_renderer(self._raster_renderer)
- self._rasterizing += 1
-
- def stop_rasterizing(self):
- """
- Exit "raster" mode. All of the drawing that was done since
- the last start_rasterizing command will be copied to the
- vector backend by calling draw_image.
-
- If stop_rasterizing is called multiple times before
- start_rasterizing is called, this method has no effect.
- """
- self._rasterizing -= 1
- if self._rasterizing == 0:
- self._set_current_renderer(self._vector_renderer)
-
- height = self._height * self.dpi
- buffer, bounds = self._raster_renderer.tostring_rgba_minimized()
- l, b, w, h = bounds
- if w > 0 and h > 0:
- image = np.frombuffer(buffer, dtype=np.uint8)
- image = image.reshape((h, w, 4))
- image = image[::-1]
- gc = self._renderer.new_gc()
- # TODO: If the mixedmode resolution differs from the figure's
- # dpi, the image must be scaled (dpi->_figdpi). Not all
- # backends support this.
- self._renderer.draw_image(
- gc,
- l * self._figdpi / self.dpi,
- (height-b-h) * self._figdpi / self.dpi,
- image)
- self._raster_renderer = None
- self._rasterizing = False
-
- # restore the figure dpi.
- self.figure.set_dpi(self._figdpi)
-
- if self._bbox_inches_restore: # when tight bbox is used
- r = process_figure_for_rasterizing(self.figure,
- self._bbox_inches_restore,
- self._figdpi)
- self._bbox_inches_restore = r
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_nbagg.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_nbagg.py
deleted file mode 100644
index 429fb1e7cc..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_nbagg.py
+++ /dev/null
@@ -1,270 +0,0 @@
-"""Interactive figures in the IPython notebook"""
-# Note: There is a notebook in
-# lib/matplotlib/backends/web_backend/nbagg_uat.ipynb to help verify
-# that changes made maintain expected behaviour.
-
-import six
-
-from base64 import b64encode
-import io
-import json
-import os
-import uuid
-
-from IPython.display import display, Javascript, HTML
-try:
- # Jupyter/IPython 4.x or later
- from ipykernel.comm import Comm
-except ImportError:
- # Jupyter/IPython 3.x or earlier
- from IPython.kernel.comm import Comm
-
-from matplotlib import rcParams, is_interactive
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, NavigationToolbar2)
-from matplotlib.backends.backend_webagg_core import (
- FigureCanvasWebAggCore, FigureManagerWebAgg, NavigationToolbar2WebAgg,
- TimerTornado)
-
-
-def connection_info():
- """
- Return a string showing the figure and connection status for
- the backend. This is intended as a diagnostic tool, and not for general
- use.
-
- """
- result = []
- for manager in Gcf.get_all_fig_managers():
- fig = manager.canvas.figure
- result.append('{0} - {0}'.format((fig.get_label() or
- "Figure {0}".format(manager.num)),
- manager.web_sockets))
- if not is_interactive():
- result.append('Figures pending show: {0}'.format(len(Gcf._activeQue)))
- return '\n'.join(result)
-
-
-# Note: Version 3.2 and 4.x icons
-# http://fontawesome.io/3.2.1/icons/
-# http://fontawesome.io/
-# the `fa fa-xxx` part targets font-awesome 4, (IPython 3.x)
-# the icon-xxx targets font awesome 3.21 (IPython 2.x)
-_FONT_AWESOME_CLASSES = {
- 'home': 'fa fa-home icon-home',
- 'back': 'fa fa-arrow-left icon-arrow-left',
- 'forward': 'fa fa-arrow-right icon-arrow-right',
- 'zoom_to_rect': 'fa fa-square-o icon-check-empty',
- 'move': 'fa fa-arrows icon-move',
- 'download': 'fa fa-floppy-o icon-save',
- None: None
-}
-
-
-class NavigationIPy(NavigationToolbar2WebAgg):
-
- # Use the standard toolbar items + download button
- toolitems = [(text, tooltip_text,
- _FONT_AWESOME_CLASSES[image_file], name_of_method)
- for text, tooltip_text, image_file, name_of_method
- in (NavigationToolbar2.toolitems +
- (('Download', 'Download plot', 'download', 'download'),))
- if image_file in _FONT_AWESOME_CLASSES]
-
-
-class FigureManagerNbAgg(FigureManagerWebAgg):
- ToolbarCls = NavigationIPy
-
- def __init__(self, canvas, num):
- self._shown = False
- FigureManagerWebAgg.__init__(self, canvas, num)
-
- def display_js(self):
- # XXX How to do this just once? It has to deal with multiple
- # browser instances using the same kernel (require.js - but the
- # file isn't static?).
- display(Javascript(FigureManagerNbAgg.get_javascript()))
-
- def show(self):
- if not self._shown:
- self.display_js()
- self._create_comm()
- else:
- self.canvas.draw_idle()
- self._shown = True
-
- def reshow(self):
- """
- A special method to re-show the figure in the notebook.
-
- """
- self._shown = False
- self.show()
-
- @property
- def connected(self):
- return bool(self.web_sockets)
-
- @classmethod
- def get_javascript(cls, stream=None):
- if stream is None:
- output = io.StringIO()
- else:
- output = stream
- super(FigureManagerNbAgg, cls).get_javascript(stream=output)
- with io.open(os.path.join(
- os.path.dirname(__file__),
- "web_backend", 'js',
- "nbagg_mpl.js"), encoding='utf8') as fd:
- output.write(fd.read())
- if stream is None:
- return output.getvalue()
-
- def _create_comm(self):
- comm = CommSocket(self)
- self.add_web_socket(comm)
- return comm
-
- def destroy(self):
- self._send_event('close')
- # need to copy comms as callbacks will modify this list
- for comm in list(self.web_sockets):
- comm.on_close()
- self.clearup_closed()
-
- def clearup_closed(self):
- """Clear up any closed Comms."""
- self.web_sockets = set([socket for socket in self.web_sockets
- if socket.is_open()])
-
- if len(self.web_sockets) == 0:
- self.canvas.close_event()
-
- def remove_comm(self, comm_id):
- self.web_sockets = set([socket for socket in self.web_sockets
- if not socket.comm.comm_id == comm_id])
-
-
-class FigureCanvasNbAgg(FigureCanvasWebAggCore):
- def new_timer(self, *args, **kwargs):
- return TimerTornado(*args, **kwargs)
-
-
-class CommSocket(object):
- """
- Manages the Comm connection between IPython and the browser (client).
-
- Comms are 2 way, with the CommSocket being able to publish a message
- via the send_json method, and handle a message with on_message. On the
- JS side figure.send_message and figure.ws.onmessage do the sending and
- receiving respectively.
-
- """
- def __init__(self, manager):
- self.supports_binary = None
- self.manager = manager
- self.uuid = str(uuid.uuid4())
- # Publish an output area with a unique ID. The javascript can then
- # hook into this area.
- display(HTML("<div id=%r></div>" % self.uuid))
- try:
- self.comm = Comm('matplotlib', data={'id': self.uuid})
- except AttributeError:
- raise RuntimeError('Unable to create an IPython notebook Comm '
- 'instance. Are you in the IPython notebook?')
- self.comm.on_msg(self.on_message)
-
- manager = self.manager
- self._ext_close = False
-
- def _on_close(close_message):
- self._ext_close = True
- manager.remove_comm(close_message['content']['comm_id'])
- manager.clearup_closed()
-
- self.comm.on_close(_on_close)
-
- def is_open(self):
- return not (self._ext_close or self.comm._closed)
-
- def on_close(self):
- # When the socket is closed, deregister the websocket with
- # the FigureManager.
- if self.is_open():
- try:
- self.comm.close()
- except KeyError:
- # apparently already cleaned it up?
- pass
-
- def send_json(self, content):
- self.comm.send({'data': json.dumps(content)})
-
- def send_binary(self, blob):
- # The comm is ascii, so we always send the image in base64
- # encoded data URL form.
- data = b64encode(blob)
- if six.PY3:
- data = data.decode('ascii')
- data_uri = "data:image/png;base64,{0}".format(data)
- self.comm.send({'data': data_uri})
-
- def on_message(self, message):
- # The 'supports_binary' message is relevant to the
- # websocket itself. The other messages get passed along
- # to matplotlib as-is.
-
- # Every message has a "type" and a "figure_id".
- message = json.loads(message['content']['data'])
- if message['type'] == 'closing':
- self.on_close()
- self.manager.clearup_closed()
- elif message['type'] == 'supports_binary':
- self.supports_binary = message['value']
- else:
- self.manager.handle_json(message)
-
-
-@_Backend.export
-class _BackendNbAgg(_Backend):
- FigureCanvas = FigureCanvasNbAgg
- FigureManager = FigureManagerNbAgg
-
- @staticmethod
- def new_figure_manager_given_figure(num, figure):
- canvas = FigureCanvasNbAgg(figure)
- manager = FigureManagerNbAgg(canvas, num)
- if is_interactive():
- manager.show()
- figure.canvas.draw_idle()
- canvas.mpl_connect('close_event', lambda event: Gcf.destroy(num))
- return manager
-
- @staticmethod
- def trigger_manager_draw(manager):
- manager.show()
-
- @staticmethod
- def show(*args, **kwargs):
- ## TODO: something to do when keyword block==False ?
- from matplotlib._pylab_helpers import Gcf
-
- managers = Gcf.get_all_fig_managers()
- if not managers:
- return
-
- interactive = is_interactive()
-
- for manager in managers:
- manager.show()
-
- # plt.figure adds an event which puts the figure in focus
- # in the activeQue. Disable this behaviour, as it results in
- # figures being put as the active figure after they have been
- # shown, even in non-interactive mode.
- if hasattr(manager, '_cidgcf'):
- manager.canvas.mpl_disconnect(manager._cidgcf)
-
- if not interactive and manager in Gcf._activeQue:
- Gcf._activeQue.remove(manager)
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_pdf.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_pdf.py
deleted file mode 100644
index 4f248fde9a..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_pdf.py
+++ /dev/null
@@ -1,2604 +0,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-A PDF matplotlib backend
-Author: Jouni K Seppänen <jks@iki.fi>
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six import unichr
-
-import codecs
-import collections
-from datetime import datetime
-from functools import total_ordering
-from io import BytesIO
-import logging
-from math import ceil, cos, floor, pi, sin
-import os
-import re
-import struct
-import sys
-import time
-import warnings
-import zlib
-
-import numpy as np
-
-from matplotlib import cbook, __version__, rcParams
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase,
- RendererBase)
-from matplotlib.backends.backend_mixed import MixedModeRenderer
-from matplotlib.cbook import (Bunch, get_realpath_and_stat,
- is_writable_file_like, maxdict)
-from matplotlib.figure import Figure
-from matplotlib.font_manager import findfont, is_opentype_cff_font, get_font
-from matplotlib.afm import AFM
-import matplotlib.type1font as type1font
-import matplotlib.dviread as dviread
-from matplotlib.ft2font import (FIXED_WIDTH, ITALIC, LOAD_NO_SCALE,
- LOAD_NO_HINTING, KERNING_UNFITTED)
-from matplotlib.mathtext import MathTextParser
-from matplotlib.transforms import Affine2D, BboxBase
-from matplotlib.path import Path
-from matplotlib.dates import UTC
-from matplotlib import _path
-from matplotlib import _png
-from matplotlib import ttconv
-
-_log = logging.getLogger(__name__)
-
-# Overview
-#
-# The low-level knowledge about pdf syntax lies mainly in the pdfRepr
-# function and the classes Reference, Name, Operator, and Stream. The
-# PdfFile class knows about the overall structure of pdf documents.
-# It provides a "write" method for writing arbitrary strings in the
-# file, and an "output" method that passes objects through the pdfRepr
-# function before writing them in the file. The output method is
-# called by the RendererPdf class, which contains the various draw_foo
-# methods. RendererPdf contains a GraphicsContextPdf instance, and
-# each draw_foo calls self.check_gc before outputting commands. This
-# method checks whether the pdf graphics state needs to be modified
-# and outputs the necessary commands. GraphicsContextPdf represents
-# the graphics state, and its "delta" method returns the commands that
-# modify the state.
-
-# Add "pdf.use14corefonts: True" in your configuration file to use only
-# the 14 PDF core fonts. These fonts do not need to be embedded; every
-# PDF viewing application is required to have them. This results in very
-# light PDF files you can use directly in LaTeX or ConTeXt documents
-# generated with pdfTeX, without any conversion.
-
-# These fonts are: Helvetica, Helvetica-Bold, Helvetica-Oblique,
-# Helvetica-BoldOblique, Courier, Courier-Bold, Courier-Oblique,
-# Courier-BoldOblique, Times-Roman, Times-Bold, Times-Italic,
-# Times-BoldItalic, Symbol, ZapfDingbats.
-#
-# Some tricky points:
-#
-# 1. The clip path can only be widened by popping from the state
-# stack. Thus the state must be pushed onto the stack before narrowing
-# the clip path. This is taken care of by GraphicsContextPdf.
-#
-# 2. Sometimes it is necessary to refer to something (e.g., font,
-# image, or extended graphics state, which contains the alpha value)
-# in the page stream by a name that needs to be defined outside the
-# stream. PdfFile provides the methods fontName, imageObject, and
-# alphaState for this purpose. The implementations of these methods
-# should perhaps be generalized.
-
-# TODOs:
-#
-# * encoding of fonts, including mathtext fonts and unicode support
-# * TTF support has lots of small TODOs, e.g., how do you know if a font
-# is serif/sans-serif, or symbolic/non-symbolic?
-# * draw_markers, draw_line_collection, etc.
-
-
-def fill(strings, linelen=75):
- """Make one string from sequence of strings, with whitespace
- in between. The whitespace is chosen to form lines of at most
- linelen characters, if possible."""
- currpos = 0
- lasti = 0
- result = []
- for i, s in enumerate(strings):
- length = len(s)
- if currpos + length < linelen:
- currpos += length + 1
- else:
- result.append(b' '.join(strings[lasti:i]))
- lasti = i
- currpos = length
- result.append(b' '.join(strings[lasti:]))
- return b'\n'.join(result)
-
-# PDF strings are supposed to be able to include any eight-bit data,
-# except that unbalanced parens and backslashes must be escaped by a
-# backslash. However, sf bug #2708559 shows that the carriage return
-# character may get read as a newline; these characters correspond to
-# \gamma and \Omega in TeX's math font encoding. Escaping them fixes
-# the bug.
-_string_escape_regex = re.compile(br'([\\()\r\n])')
-
-
-def _string_escape(match):
- m = match.group(0)
- if m in br'\()':
- return b'\\' + m
- elif m == b'\n':
- return br'\n'
- elif m == b'\r':
- return br'\r'
- assert False
-
-
-def pdfRepr(obj):
- """Map Python objects to PDF syntax."""
-
- # Some objects defined later have their own pdfRepr method.
- if hasattr(obj, 'pdfRepr'):
- return obj.pdfRepr()
-
- # Floats. PDF does not have exponential notation (1.0e-10) so we
- # need to use %f with some precision. Perhaps the precision
- # should adapt to the magnitude of the number?
- elif isinstance(obj, (float, np.floating)):
- if not np.isfinite(obj):
- raise ValueError("Can only output finite numbers in PDF")
- r = ("%.10f" % obj).encode('ascii')
- return r.rstrip(b'0').rstrip(b'.')
-
- # Booleans. Needs to be tested before integers since
- # isinstance(True, int) is true.
- elif isinstance(obj, bool):
- return [b'false', b'true'][obj]
-
- # Integers are written as such.
- elif isinstance(obj, (six.integer_types, np.integer)):
- return ("%d" % obj).encode('ascii')
-
- # Unicode strings are encoded in UTF-16BE with byte-order mark.
- elif isinstance(obj, six.text_type):
- try:
- # But maybe it's really ASCII?
- s = obj.encode('ASCII')
- return pdfRepr(s)
- except UnicodeEncodeError:
- s = codecs.BOM_UTF16_BE + obj.encode('UTF-16BE')
- return pdfRepr(s)
-
- # Strings are written in parentheses, with backslashes and parens
- # escaped. Actually balanced parens are allowed, but it is
- # simpler to escape them all. TODO: cut long strings into lines;
- # I believe there is some maximum line length in PDF.
- elif isinstance(obj, bytes):
- return b'(' + _string_escape_regex.sub(_string_escape, obj) + b')'
-
- # Dictionaries. The keys must be PDF names, so if we find strings
- # there, we make Name objects from them. The values may be
- # anything, so the caller must ensure that PDF names are
- # represented as Name objects.
- elif isinstance(obj, dict):
- r = [b"<<"]
- r.extend([Name(key).pdfRepr() + b" " + pdfRepr(obj[key])
- for key in sorted(obj)])
- r.append(b">>")
- return fill(r)
-
- # Lists.
- elif isinstance(obj, (list, tuple)):
- r = [b"["]
- r.extend([pdfRepr(val) for val in obj])
- r.append(b"]")
- return fill(r)
-
- # The null keyword.
- elif obj is None:
- return b'null'
-
- # A date.
- elif isinstance(obj, datetime):
- r = obj.strftime('D:%Y%m%d%H%M%S')
- z = obj.utcoffset()
- if z is not None:
- z = z.seconds
- else:
- if time.daylight:
- z = time.altzone
- else:
- z = time.timezone
- if z == 0:
- r += 'Z'
- elif z < 0:
- r += "+%02d'%02d'" % ((-z) // 3600, (-z) % 3600)
- else:
- r += "-%02d'%02d'" % (z // 3600, z % 3600)
- return pdfRepr(r)
-
- # A bounding box
- elif isinstance(obj, BboxBase):
- return fill([pdfRepr(val) for val in obj.bounds])
-
- else:
- raise TypeError("Don't know a PDF representation for {} objects"
- .format(type(obj)))
-
-
-class Reference(object):
- """PDF reference object.
- Use PdfFile.reserveObject() to create References.
- """
-
- def __init__(self, id):
- self.id = id
-
- def __repr__(self):
- return "<Reference %d>" % self.id
-
- def pdfRepr(self):
- return ("%d 0 R" % self.id).encode('ascii')
-
- def write(self, contents, file):
- write = file.write
- write(("%d 0 obj\n" % self.id).encode('ascii'))
- write(pdfRepr(contents))
- write(b"\nendobj\n")
-
-
-@total_ordering
-class Name(object):
- """PDF name object."""
- __slots__ = ('name',)
- _regex = re.compile(r'[^!-~]')
-
- def __init__(self, name):
- if isinstance(name, Name):
- self.name = name.name
- else:
- if isinstance(name, bytes):
- name = name.decode('ascii')
- self.name = self._regex.sub(Name.hexify, name).encode('ascii')
-
- def __repr__(self):
- return "<Name %s>" % self.name
-
- def __str__(self):
- return '/' + six.text_type(self.name)
-
- def __eq__(self, other):
- return isinstance(other, Name) and self.name == other.name
-
- def __lt__(self, other):
- return isinstance(other, Name) and self.name < other.name
-
- def __hash__(self):
- return hash(self.name)
-
- @staticmethod
- def hexify(match):
- return '#%02x' % ord(match.group())
-
- def pdfRepr(self):
- return b'/' + self.name
-
-
-class Operator(object):
- """PDF operator object."""
- __slots__ = ('op',)
-
- def __init__(self, op):
- self.op = op
-
- def __repr__(self):
- return '<Operator %s>' % self.op
-
- def pdfRepr(self):
- return self.op
-
-
-class Verbatim(object):
- """Store verbatim PDF command content for later inclusion in the
- stream."""
- def __init__(self, x):
- self._x = x
-
- def pdfRepr(self):
- return self._x
-
-
-# PDF operators (not an exhaustive list)
-_pdfops = dict(
- close_fill_stroke=b'b', fill_stroke=b'B', fill=b'f', closepath=b'h',
- close_stroke=b's', stroke=b'S', endpath=b'n', begin_text=b'BT',
- end_text=b'ET', curveto=b'c', rectangle=b're', lineto=b'l', moveto=b'm',
- concat_matrix=b'cm', use_xobject=b'Do', setgray_stroke=b'G',
- setgray_nonstroke=b'g', setrgb_stroke=b'RG', setrgb_nonstroke=b'rg',
- setcolorspace_stroke=b'CS', setcolorspace_nonstroke=b'cs',
- setcolor_stroke=b'SCN', setcolor_nonstroke=b'scn', setdash=b'd',
- setlinejoin=b'j', setlinecap=b'J', setgstate=b'gs', gsave=b'q',
- grestore=b'Q', textpos=b'Td', selectfont=b'Tf', textmatrix=b'Tm',
- show=b'Tj', showkern=b'TJ', setlinewidth=b'w', clip=b'W', shading=b'sh')
-
-Op = Bunch(**{name: Operator(value) for name, value in six.iteritems(_pdfops)})
-
-
-def _paint_path(fill, stroke):
- """Return the PDF operator to paint a path in the following way:
- fill: fill the path with the fill color
- stroke: stroke the outline of the path with the line color"""
- if stroke:
- if fill:
- return Op.fill_stroke
- else:
- return Op.stroke
- else:
- if fill:
- return Op.fill
- else:
- return Op.endpath
-Op.paint_path = _paint_path
-
-
-class Stream(object):
- """PDF stream object.
-
- This has no pdfRepr method. Instead, call begin(), then output the
- contents of the stream by calling write(), and finally call end().
- """
- __slots__ = ('id', 'len', 'pdfFile', 'file', 'compressobj', 'extra', 'pos')
-
- def __init__(self, id, len, file, extra=None, png=None):
- """id: object id of stream; len: an unused Reference object for the
- length of the stream, or None (to use a memory buffer); file:
- a PdfFile; extra: a dictionary of extra key-value pairs to
- include in the stream header; png: if the data is already
- png compressed, the decode parameters"""
- self.id = id # object id
- self.len = len # id of length object
- self.pdfFile = file
- self.file = file.fh # file to which the stream is written
- self.compressobj = None # compression object
- if extra is None:
- self.extra = dict()
- else:
- self.extra = extra.copy()
- if png is not None:
- self.extra.update({'Filter': Name('FlateDecode'),
- 'DecodeParms': png})
-
- self.pdfFile.recordXref(self.id)
- if rcParams['pdf.compression'] and not png:
- self.compressobj = zlib.compressobj(rcParams['pdf.compression'])
- if self.len is None:
- self.file = BytesIO()
- else:
- self._writeHeader()
- self.pos = self.file.tell()
-
- def _writeHeader(self):
- write = self.file.write
- write(("%d 0 obj\n" % self.id).encode('ascii'))
- dict = self.extra
- dict['Length'] = self.len
- if rcParams['pdf.compression']:
- dict['Filter'] = Name('FlateDecode')
-
- write(pdfRepr(dict))
- write(b"\nstream\n")
-
- def end(self):
- """Finalize stream."""
-
- self._flush()
- if self.len is None:
- contents = self.file.getvalue()
- self.len = len(contents)
- self.file = self.pdfFile.fh
- self._writeHeader()
- self.file.write(contents)
- self.file.write(b"\nendstream\nendobj\n")
- else:
- length = self.file.tell() - self.pos
- self.file.write(b"\nendstream\nendobj\n")
- self.pdfFile.writeObject(self.len, length)
-
- def write(self, data):
- """Write some data on the stream."""
-
- if self.compressobj is None:
- self.file.write(data)
- else:
- compressed = self.compressobj.compress(data)
- self.file.write(compressed)
-
- def _flush(self):
- """Flush the compression object."""
-
- if self.compressobj is not None:
- compressed = self.compressobj.flush()
- self.file.write(compressed)
- self.compressobj = None
-
-
-class PdfFile(object):
- """PDF file object."""
-
- def __init__(self, filename, metadata=None):
- self.nextObject = 1 # next free object id
- self.xrefTable = [[0, 65535, 'the zero object']]
- self.passed_in_file_object = False
- self.original_file_like = None
- self.tell_base = 0
- fh, opened = cbook.to_filehandle(filename, "wb", return_opened=True)
- if not opened:
- try:
- self.tell_base = filename.tell()
- except IOError:
- fh = BytesIO()
- self.original_file_like = filename
- else:
- fh = filename
- self.passed_in_file_object = True
-
- self._core14fontdir = os.path.join(
- rcParams['datapath'], 'fonts', 'pdfcorefonts')
- self.fh = fh
- self.currentstream = None # stream object to write to, if any
- fh.write(b"%PDF-1.4\n") # 1.4 is the first version to have alpha
- # Output some eight-bit chars as a comment so various utilities
- # recognize the file as binary by looking at the first few
- # lines (see note in section 3.4.1 of the PDF reference).
- fh.write(b"%\254\334 \253\272\n")
-
- self.rootObject = self.reserveObject('root')
- self.pagesObject = self.reserveObject('pages')
- self.pageList = []
- self.fontObject = self.reserveObject('fonts')
- self.alphaStateObject = self.reserveObject('extended graphics states')
- self.hatchObject = self.reserveObject('tiling patterns')
- self.gouraudObject = self.reserveObject('Gouraud triangles')
- self.XObjectObject = self.reserveObject('external objects')
- self.resourceObject = self.reserveObject('resources')
-
- root = {'Type': Name('Catalog'),
- 'Pages': self.pagesObject}
- self.writeObject(self.rootObject, root)
-
- # get source date from SOURCE_DATE_EPOCH, if set
- # See https://reproducible-builds.org/specs/source-date-epoch/
- source_date_epoch = os.getenv("SOURCE_DATE_EPOCH")
- if source_date_epoch:
- source_date = datetime.utcfromtimestamp(int(source_date_epoch))
- source_date = source_date.replace(tzinfo=UTC)
- else:
- source_date = datetime.today()
-
- self.infoDict = {
- 'Creator': 'matplotlib %s, http://matplotlib.org' % __version__,
- 'Producer': 'matplotlib pdf backend %s' % __version__,
- 'CreationDate': source_date
- }
- if metadata is not None:
- self.infoDict.update(metadata)
- self.infoDict = {k: v for (k, v) in self.infoDict.items()
- if v is not None}
-
- self.fontNames = {} # maps filenames to internal font names
- self.nextFont = 1 # next free internal font name
- self.dviFontInfo = {} # maps dvi font names to embedding information
- self._texFontMap = None # maps TeX font names to PostScript fonts
- # differently encoded Type-1 fonts may share the same descriptor
- self.type1Descriptors = {}
- self.used_characters = {}
-
- self.alphaStates = {} # maps alpha values to graphics state objects
- self.nextAlphaState = 1
- # reproducible writeHatches needs an ordered dict:
- self.hatchPatterns = collections.OrderedDict()
- self.nextHatch = 1
- self.gouraudTriangles = []
-
- self._images = collections.OrderedDict() # reproducible writeImages
- self.nextImage = 1
-
- self.markers = collections.OrderedDict() # reproducible writeMarkers
- self.multi_byte_charprocs = {}
-
- self.paths = []
-
- self.pageAnnotations = [] # A list of annotations for the
- # current page
-
- # The PDF spec recommends to include every procset
- procsets = [Name(x)
- for x in "PDF Text ImageB ImageC ImageI".split()]
-
- # Write resource dictionary.
- # Possibly TODO: more general ExtGState (graphics state dictionaries)
- # ColorSpace Pattern Shading Properties
- resources = {'Font': self.fontObject,
- 'XObject': self.XObjectObject,
- 'ExtGState': self.alphaStateObject,
- 'Pattern': self.hatchObject,
- 'Shading': self.gouraudObject,
- 'ProcSet': procsets}
- self.writeObject(self.resourceObject, resources)
-
- def newPage(self, width, height):
- self.endStream()
-
- self.width, self.height = width, height
- contentObject = self.reserveObject('page contents')
- thePage = {'Type': Name('Page'),
- 'Parent': self.pagesObject,
- 'Resources': self.resourceObject,
- 'MediaBox': [0, 0, 72 * width, 72 * height],
- 'Contents': contentObject,
- 'Group': {'Type': Name('Group'),
- 'S': Name('Transparency'),
- 'CS': Name('DeviceRGB')},
- 'Annots': self.pageAnnotations,
- }
- pageObject = self.reserveObject('page')
- self.writeObject(pageObject, thePage)
- self.pageList.append(pageObject)
-
- self.beginStream(contentObject.id,
- self.reserveObject('length of content stream'))
- # Initialize the pdf graphics state to match the default mpl
- # graphics context: currently only the join style needs to be set
- self.output(GraphicsContextPdf.joinstyles['round'], Op.setlinejoin)
-
- # Clear the list of annotations for the next page
- self.pageAnnotations = []
-
- def newTextnote(self, text, positionRect=[-100, -100, 0, 0]):
- # Create a new annotation of type text
- theNote = {'Type': Name('Annot'),
- 'Subtype': Name('Text'),
- 'Contents': text,
- 'Rect': positionRect,
- }
- annotObject = self.reserveObject('annotation')
- self.writeObject(annotObject, theNote)
- self.pageAnnotations.append(annotObject)
-
- def finalize(self):
- "Write out the various deferred objects and the pdf end matter."
-
- self.endStream()
- self.writeFonts()
- self.writeObject(
- self.alphaStateObject,
- {val[0]: val[1] for val in six.itervalues(self.alphaStates)})
- self.writeHatches()
- self.writeGouraudTriangles()
- xobjects = {
- name: ob for image, name, ob in six.itervalues(self._images)}
- for tup in six.itervalues(self.markers):
- xobjects[tup[0]] = tup[1]
- for name, value in six.iteritems(self.multi_byte_charprocs):
- xobjects[name] = value
- for name, path, trans, ob, join, cap, padding, filled, stroked \
- in self.paths:
- xobjects[name] = ob
- self.writeObject(self.XObjectObject, xobjects)
- self.writeImages()
- self.writeMarkers()
- self.writePathCollectionTemplates()
- self.writeObject(self.pagesObject,
- {'Type': Name('Pages'),
- 'Kids': self.pageList,
- 'Count': len(self.pageList)})
- self.writeInfoDict()
-
- # Finalize the file
- self.writeXref()
- self.writeTrailer()
-
- def close(self):
- "Flush all buffers and free all resources."
-
- self.endStream()
- if self.passed_in_file_object:
- self.fh.flush()
- else:
- if self.original_file_like is not None:
- self.original_file_like.write(self.fh.getvalue())
- self.fh.close()
-
- def write(self, data):
- if self.currentstream is None:
- self.fh.write(data)
- else:
- self.currentstream.write(data)
-
- def output(self, *data):
- self.write(fill([pdfRepr(x) for x in data]))
- self.write(b'\n')
-
- def beginStream(self, id, len, extra=None, png=None):
- assert self.currentstream is None
- self.currentstream = Stream(id, len, self, extra, png)
-
- def endStream(self):
- if self.currentstream is not None:
- self.currentstream.end()
- self.currentstream = None
-
- def fontName(self, fontprop):
- """
- Select a font based on fontprop and return a name suitable for
- Op.selectfont. If fontprop is a string, it will be interpreted
- as the filename of the font.
- """
-
- if isinstance(fontprop, six.string_types):
- filename = fontprop
- elif rcParams['pdf.use14corefonts']:
- filename = findfont(
- fontprop, fontext='afm', directory=self._core14fontdir)
- if filename is None:
- filename = findfont(
- "Helvetica", fontext='afm', directory=self._core14fontdir)
- else:
- filename = findfont(fontprop)
-
- Fx = self.fontNames.get(filename)
- if Fx is None:
- Fx = Name('F%d' % self.nextFont)
- self.fontNames[filename] = Fx
- self.nextFont += 1
- _log.debug('Assigning font %s = %r', Fx, filename)
-
- return Fx
-
- @property
- def texFontMap(self):
- # lazy-load texFontMap, it takes a while to parse
- # and usetex is a relatively rare use case
- if self._texFontMap is None:
- self._texFontMap = dviread.PsfontsMap(
- dviread.find_tex_file('pdftex.map'))
-
- return self._texFontMap
-
- def dviFontName(self, dvifont):
- """
- Given a dvi font object, return a name suitable for Op.selectfont.
- This registers the font information in self.dviFontInfo if not yet
- registered.
- """
-
- dvi_info = self.dviFontInfo.get(dvifont.texname)
- if dvi_info is not None:
- return dvi_info.pdfname
-
- psfont = self.texFontMap[dvifont.texname]
- if psfont.filename is None:
- raise ValueError(
- "No usable font file found for {} (TeX: {}); "
- "the font may lack a Type-1 version"
- .format(psfont.psname, dvifont.texname))
-
- pdfname = Name('F%d' % self.nextFont)
- self.nextFont += 1
- _log.debug('Assigning font %s = %s (dvi)', pdfname, dvifont.texname)
- self.dviFontInfo[dvifont.texname] = Bunch(
- dvifont=dvifont,
- pdfname=pdfname,
- fontfile=psfont.filename,
- basefont=psfont.psname,
- encodingfile=psfont.encoding,
- effects=psfont.effects)
- return pdfname
-
- def writeFonts(self):
- fonts = {}
- for dviname, info in sorted(self.dviFontInfo.items()):
- Fx = info.pdfname
- _log.debug('Embedding Type-1 font %s from dvi.', dviname)
- fonts[Fx] = self._embedTeXFont(info)
- for filename in sorted(self.fontNames):
- Fx = self.fontNames[filename]
- _log.debug('Embedding font %s.', filename)
- if filename.endswith('.afm'):
- # from pdf.use14corefonts
- _log.debug('Writing AFM font.')
- fonts[Fx] = self._write_afm_font(filename)
- else:
- # a normal TrueType font
- _log.debug('Writing TrueType font.')
- realpath, stat_key = get_realpath_and_stat(filename)
- chars = self.used_characters.get(stat_key)
- if chars is not None and len(chars[1]):
- fonts[Fx] = self.embedTTF(realpath, chars[1])
- self.writeObject(self.fontObject, fonts)
-
- def _write_afm_font(self, filename):
- with open(filename, 'rb') as fh:
- font = AFM(fh)
- fontname = font.get_fontname()
- fontdict = {'Type': Name('Font'),
- 'Subtype': Name('Type1'),
- 'BaseFont': Name(fontname),
- 'Encoding': Name('WinAnsiEncoding')}
- fontdictObject = self.reserveObject('font dictionary')
- self.writeObject(fontdictObject, fontdict)
- return fontdictObject
-
- def _embedTeXFont(self, fontinfo):
- _log.debug('Embedding TeX font %s - fontinfo=%s',
- fontinfo.dvifont.texname, fontinfo.__dict__)
-
- # Widths
- widthsObject = self.reserveObject('font widths')
- self.writeObject(widthsObject, fontinfo.dvifont.widths)
-
- # Font dictionary
- fontdictObject = self.reserveObject('font dictionary')
- fontdict = {
- 'Type': Name('Font'),
- 'Subtype': Name('Type1'),
- 'FirstChar': 0,
- 'LastChar': len(fontinfo.dvifont.widths) - 1,
- 'Widths': widthsObject,
- }
-
- # Encoding (if needed)
- if fontinfo.encodingfile is not None:
- enc = dviread.Encoding(fontinfo.encodingfile)
- differencesArray = [Name(ch) for ch in enc]
- differencesArray = [0] + differencesArray
- fontdict['Encoding'] = \
- {'Type': Name('Encoding'),
- 'Differences': differencesArray}
-
- # If no file is specified, stop short
- if fontinfo.fontfile is None:
- _log.warning(
- "Because of TeX configuration (pdftex.map, see updmap option "
- "pdftexDownloadBase14) the font %s is not embedded. This is "
- "deprecated as of PDF 1.5 and it may cause the consumer "
- "application to show something that was not intended.",
- fontinfo.basefont)
- fontdict['BaseFont'] = Name(fontinfo.basefont)
- self.writeObject(fontdictObject, fontdict)
- return fontdictObject
-
- # We have a font file to embed - read it in and apply any effects
- t1font = type1font.Type1Font(fontinfo.fontfile)
- if fontinfo.effects:
- t1font = t1font.transform(fontinfo.effects)
- fontdict['BaseFont'] = Name(t1font.prop['FontName'])
-
- # Font descriptors may be shared between differently encoded
- # Type-1 fonts, so only create a new descriptor if there is no
- # existing descriptor for this font.
- effects = (fontinfo.effects.get('slant', 0.0),
- fontinfo.effects.get('extend', 1.0))
- fontdesc = self.type1Descriptors.get((fontinfo.fontfile, effects))
- if fontdesc is None:
- fontdesc = self.createType1Descriptor(t1font, fontinfo.fontfile)
- self.type1Descriptors[(fontinfo.fontfile, effects)] = fontdesc
- fontdict['FontDescriptor'] = fontdesc
-
- self.writeObject(fontdictObject, fontdict)
- return fontdictObject
-
- def createType1Descriptor(self, t1font, fontfile):
- # Create and write the font descriptor and the font file
- # of a Type-1 font
- fontdescObject = self.reserveObject('font descriptor')
- fontfileObject = self.reserveObject('font file')
-
- italic_angle = t1font.prop['ItalicAngle']
- fixed_pitch = t1font.prop['isFixedPitch']
-
- flags = 0
- # fixed width
- if fixed_pitch:
- flags |= 1 << 0
- # TODO: serif
- if 0:
- flags |= 1 << 1
- # TODO: symbolic (most TeX fonts are)
- if 1:
- flags |= 1 << 2
- # non-symbolic
- else:
- flags |= 1 << 5
- # italic
- if italic_angle:
- flags |= 1 << 6
- # TODO: all caps
- if 0:
- flags |= 1 << 16
- # TODO: small caps
- if 0:
- flags |= 1 << 17
- # TODO: force bold
- if 0:
- flags |= 1 << 18
-
- ft2font = get_font(fontfile)
-
- descriptor = {
- 'Type': Name('FontDescriptor'),
- 'FontName': Name(t1font.prop['FontName']),
- 'Flags': flags,
- 'FontBBox': ft2font.bbox,
- 'ItalicAngle': italic_angle,
- 'Ascent': ft2font.ascender,
- 'Descent': ft2font.descender,
- 'CapHeight': 1000, # TODO: find this out
- 'XHeight': 500, # TODO: this one too
- 'FontFile': fontfileObject,
- 'FontFamily': t1font.prop['FamilyName'],
- 'StemV': 50, # TODO
- # (see also revision 3874; but not all TeX distros have AFM files!)
- # 'FontWeight': a number where 400 = Regular, 700 = Bold
- }
-
- self.writeObject(fontdescObject, descriptor)
-
- self.beginStream(fontfileObject.id, None,
- {'Length1': len(t1font.parts[0]),
- 'Length2': len(t1font.parts[1]),
- 'Length3': 0})
- self.currentstream.write(t1font.parts[0])
- self.currentstream.write(t1font.parts[1])
- self.endStream()
-
- return fontdescObject
-
- def _get_xobject_symbol_name(self, filename, symbol_name):
- return "%s-%s" % (
- os.path.splitext(os.path.basename(filename))[0],
- symbol_name)
-
- _identityToUnicodeCMap = """/CIDInit /ProcSet findresource begin
-12 dict begin
-begincmap
-/CIDSystemInfo
-<< /Registry (Adobe)
- /Ordering (UCS)
- /Supplement 0
->> def
-/CMapName /Adobe-Identity-UCS def
-/CMapType 2 def
-1 begincodespacerange
-<0000> <ffff>
-endcodespacerange
-%d beginbfrange
-%s
-endbfrange
-endcmap
-CMapName currentdict /CMap defineresource pop
-end
-end"""
-
- def embedTTF(self, filename, characters):
- """Embed the TTF font from the named file into the document."""
-
- font = get_font(filename)
- fonttype = rcParams['pdf.fonttype']
-
- def cvt(length, upe=font.units_per_EM, nearest=True):
- "Convert font coordinates to PDF glyph coordinates"
- value = length / upe * 1000
- if nearest:
- return np.round(value)
- # Perhaps best to round away from zero for bounding
- # boxes and the like
- if value < 0:
- return floor(value)
- else:
- return ceil(value)
-
- def embedTTFType3(font, characters, descriptor):
- """The Type 3-specific part of embedding a Truetype font"""
- widthsObject = self.reserveObject('font widths')
- fontdescObject = self.reserveObject('font descriptor')
- fontdictObject = self.reserveObject('font dictionary')
- charprocsObject = self.reserveObject('character procs')
- differencesArray = []
- firstchar, lastchar = 0, 255
- bbox = [cvt(x, nearest=False) for x in font.bbox]
-
- fontdict = {
- 'Type': Name('Font'),
- 'BaseFont': ps_name,
- 'FirstChar': firstchar,
- 'LastChar': lastchar,
- 'FontDescriptor': fontdescObject,
- 'Subtype': Name('Type3'),
- 'Name': descriptor['FontName'],
- 'FontBBox': bbox,
- 'FontMatrix': [.001, 0, 0, .001, 0, 0],
- 'CharProcs': charprocsObject,
- 'Encoding': {
- 'Type': Name('Encoding'),
- 'Differences': differencesArray},
- 'Widths': widthsObject
- }
-
- # Make the "Widths" array
- from encodings import cp1252
- # The "decoding_map" was changed
- # to a "decoding_table" as of Python 2.5.
- if hasattr(cp1252, 'decoding_map'):
- def decode_char(charcode):
- return cp1252.decoding_map[charcode] or 0
- else:
- def decode_char(charcode):
- return ord(cp1252.decoding_table[charcode])
-
- def get_char_width(charcode):
- s = decode_char(charcode)
- width = font.load_char(
- s, flags=LOAD_NO_SCALE | LOAD_NO_HINTING).horiAdvance
- return cvt(width)
-
- widths = [get_char_width(charcode)
- for charcode in range(firstchar, lastchar+1)]
- descriptor['MaxWidth'] = max(widths)
-
- # Make the "Differences" array, sort the ccodes < 255 from
- # the multi-byte ccodes, and build the whole set of glyph ids
- # that we need from this font.
- glyph_ids = []
- differences = []
- multi_byte_chars = set()
- for c in characters:
- ccode = c
- gind = font.get_char_index(ccode)
- glyph_ids.append(gind)
- glyph_name = font.get_glyph_name(gind)
- if ccode <= 255:
- differences.append((ccode, glyph_name))
- else:
- multi_byte_chars.add(glyph_name)
- differences.sort()
-
- last_c = -2
- for c, name in differences:
- if c != last_c + 1:
- differencesArray.append(c)
- differencesArray.append(Name(name))
- last_c = c
-
- # Make the charprocs array (using ttconv to generate the
- # actual outlines)
- rawcharprocs = ttconv.get_pdf_charprocs(
- filename.encode(sys.getfilesystemencoding()), glyph_ids)
- charprocs = {}
- for charname in sorted(rawcharprocs):
- stream = rawcharprocs[charname]
- charprocDict = {'Length': len(stream)}
- # The 2-byte characters are used as XObjects, so they
- # need extra info in their dictionary
- if charname in multi_byte_chars:
- charprocDict['Type'] = Name('XObject')
- charprocDict['Subtype'] = Name('Form')
- charprocDict['BBox'] = bbox
- # Each glyph includes bounding box information,
- # but xpdf and ghostscript can't handle it in a
- # Form XObject (they segfault!!!), so we remove it
- # from the stream here. It's not needed anyway,
- # since the Form XObject includes it in its BBox
- # value.
- stream = stream[stream.find(b"d1") + 2:]
- charprocObject = self.reserveObject('charProc')
- self.beginStream(charprocObject.id, None, charprocDict)
- self.currentstream.write(stream)
- self.endStream()
-
- # Send the glyphs with ccode > 255 to the XObject dictionary,
- # and the others to the font itself
- if charname in multi_byte_chars:
- name = self._get_xobject_symbol_name(filename, charname)
- self.multi_byte_charprocs[name] = charprocObject
- else:
- charprocs[charname] = charprocObject
-
- # Write everything out
- self.writeObject(fontdictObject, fontdict)
- self.writeObject(fontdescObject, descriptor)
- self.writeObject(widthsObject, widths)
- self.writeObject(charprocsObject, charprocs)
-
- return fontdictObject
-
- def embedTTFType42(font, characters, descriptor):
- """The Type 42-specific part of embedding a Truetype font"""
- fontdescObject = self.reserveObject('font descriptor')
- cidFontDictObject = self.reserveObject('CID font dictionary')
- type0FontDictObject = self.reserveObject('Type 0 font dictionary')
- cidToGidMapObject = self.reserveObject('CIDToGIDMap stream')
- fontfileObject = self.reserveObject('font file stream')
- wObject = self.reserveObject('Type 0 widths')
- toUnicodeMapObject = self.reserveObject('ToUnicode map')
-
- cidFontDict = {
- 'Type': Name('Font'),
- 'Subtype': Name('CIDFontType2'),
- 'BaseFont': ps_name,
- 'CIDSystemInfo': {
- 'Registry': 'Adobe',
- 'Ordering': 'Identity',
- 'Supplement': 0},
- 'FontDescriptor': fontdescObject,
- 'W': wObject,
- 'CIDToGIDMap': cidToGidMapObject
- }
-
- type0FontDict = {
- 'Type': Name('Font'),
- 'Subtype': Name('Type0'),
- 'BaseFont': ps_name,
- 'Encoding': Name('Identity-H'),
- 'DescendantFonts': [cidFontDictObject],
- 'ToUnicode': toUnicodeMapObject
- }
-
- # Make fontfile stream
- descriptor['FontFile2'] = fontfileObject
- length1Object = self.reserveObject('decoded length of a font')
- self.beginStream(
- fontfileObject.id,
- self.reserveObject('length of font stream'),
- {'Length1': length1Object})
- with open(filename, 'rb') as fontfile:
- length1 = 0
- while True:
- data = fontfile.read(4096)
- if not data:
- break
- length1 += len(data)
- self.currentstream.write(data)
- self.endStream()
- self.writeObject(length1Object, length1)
-
- # Make the 'W' (Widths) array, CidToGidMap and ToUnicode CMap
- # at the same time
- cid_to_gid_map = ['\0'] * 65536
- widths = []
- max_ccode = 0
- for c in characters:
- ccode = c
- gind = font.get_char_index(ccode)
- glyph = font.load_char(ccode,
- flags=LOAD_NO_SCALE | LOAD_NO_HINTING)
- widths.append((ccode, cvt(glyph.horiAdvance)))
- if ccode < 65536:
- cid_to_gid_map[ccode] = unichr(gind)
- max_ccode = max(ccode, max_ccode)
- widths.sort()
- cid_to_gid_map = cid_to_gid_map[:max_ccode + 1]
-
- last_ccode = -2
- w = []
- max_width = 0
- unicode_groups = []
- for ccode, width in widths:
- if ccode != last_ccode + 1:
- w.append(ccode)
- w.append([width])
- unicode_groups.append([ccode, ccode])
- else:
- w[-1].append(width)
- unicode_groups[-1][1] = ccode
- max_width = max(max_width, width)
- last_ccode = ccode
-
- unicode_bfrange = []
- for start, end in unicode_groups:
- unicode_bfrange.append(
- "<%04x> <%04x> [%s]" %
- (start, end,
- " ".join(["<%04x>" % x for x in range(start, end+1)])))
- unicode_cmap = (self._identityToUnicodeCMap %
- (len(unicode_groups),
- "\n".join(unicode_bfrange))).encode('ascii')
-
- # CIDToGIDMap stream
- cid_to_gid_map = "".join(cid_to_gid_map).encode("utf-16be")
- self.beginStream(cidToGidMapObject.id,
- None,
- {'Length': len(cid_to_gid_map)})
- self.currentstream.write(cid_to_gid_map)
- self.endStream()
-
- # ToUnicode CMap
- self.beginStream(toUnicodeMapObject.id,
- None,
- {'Length': unicode_cmap})
- self.currentstream.write(unicode_cmap)
- self.endStream()
-
- descriptor['MaxWidth'] = max_width
-
- # Write everything out
- self.writeObject(cidFontDictObject, cidFontDict)
- self.writeObject(type0FontDictObject, type0FontDict)
- self.writeObject(fontdescObject, descriptor)
- self.writeObject(wObject, w)
-
- return type0FontDictObject
-
- # Beginning of main embedTTF function...
-
- # You are lost in a maze of TrueType tables, all different...
- sfnt = font.get_sfnt()
- try:
- ps_name = sfnt[1, 0, 0, 6].decode('mac_roman') # Macintosh scheme
- except KeyError:
- # Microsoft scheme:
- ps_name = sfnt[3, 1, 0x0409, 6].decode('utf-16be')
- # (see freetype/ttnameid.h)
- ps_name = ps_name.encode('ascii', 'replace')
- ps_name = Name(ps_name)
- pclt = font.get_sfnt_table('pclt') or {'capHeight': 0, 'xHeight': 0}
- post = font.get_sfnt_table('post') or {'italicAngle': (0, 0)}
- ff = font.face_flags
- sf = font.style_flags
-
- flags = 0
- symbolic = False # ps_name.name in ('Cmsy10', 'Cmmi10', 'Cmex10')
- if ff & FIXED_WIDTH:
- flags |= 1 << 0
- if 0: # TODO: serif
- flags |= 1 << 1
- if symbolic:
- flags |= 1 << 2
- else:
- flags |= 1 << 5
- if sf & ITALIC:
- flags |= 1 << 6
- if 0: # TODO: all caps
- flags |= 1 << 16
- if 0: # TODO: small caps
- flags |= 1 << 17
- if 0: # TODO: force bold
- flags |= 1 << 18
-
- descriptor = {
- 'Type': Name('FontDescriptor'),
- 'FontName': ps_name,
- 'Flags': flags,
- 'FontBBox': [cvt(x, nearest=False) for x in font.bbox],
- 'Ascent': cvt(font.ascender, nearest=False),
- 'Descent': cvt(font.descender, nearest=False),
- 'CapHeight': cvt(pclt['capHeight'], nearest=False),
- 'XHeight': cvt(pclt['xHeight']),
- 'ItalicAngle': post['italicAngle'][1], # ???
- 'StemV': 0 # ???
- }
-
- # The font subsetting to a Type 3 font does not work for
- # OpenType (.otf) that embed a Postscript CFF font, so avoid that --
- # save as a (non-subsetted) Type 42 font instead.
- if is_opentype_cff_font(filename):
- fonttype = 42
- _log.warning("%r can not be subsetted into a Type 3 font. The "
- "entire font will be embedded in the output.",
- os.path.basename(filename))
-
- if fonttype == 3:
- return embedTTFType3(font, characters, descriptor)
- elif fonttype == 42:
- return embedTTFType42(font, characters, descriptor)
-
- def alphaState(self, alpha):
- """Return name of an ExtGState that sets alpha to the given value."""
-
- state = self.alphaStates.get(alpha, None)
- if state is not None:
- return state[0]
-
- name = Name('A%d' % self.nextAlphaState)
- self.nextAlphaState += 1
- self.alphaStates[alpha] = \
- (name, {'Type': Name('ExtGState'),
- 'CA': alpha[0], 'ca': alpha[1]})
- return name
-
- def hatchPattern(self, hatch_style):
- # The colors may come in as numpy arrays, which aren't hashable
- if hatch_style is not None:
- edge, face, hatch = hatch_style
- if edge is not None:
- edge = tuple(edge)
- if face is not None:
- face = tuple(face)
- hatch_style = (edge, face, hatch)
-
- pattern = self.hatchPatterns.get(hatch_style, None)
- if pattern is not None:
- return pattern
-
- name = Name('H%d' % self.nextHatch)
- self.nextHatch += 1
- self.hatchPatterns[hatch_style] = name
- return name
-
- def writeHatches(self):
- hatchDict = dict()
- sidelen = 72.0
- for hatch_style, name in six.iteritems(self.hatchPatterns):
- ob = self.reserveObject('hatch pattern')
- hatchDict[name] = ob
- res = {'Procsets':
- [Name(x) for x in "PDF Text ImageB ImageC ImageI".split()]}
- self.beginStream(
- ob.id, None,
- {'Type': Name('Pattern'),
- 'PatternType': 1, 'PaintType': 1, 'TilingType': 1,
- 'BBox': [0, 0, sidelen, sidelen],
- 'XStep': sidelen, 'YStep': sidelen,
- 'Resources': res,
- # Change origin to match Agg at top-left.
- 'Matrix': [1, 0, 0, 1, 0, self.height * 72]})
-
- stroke_rgb, fill_rgb, path = hatch_style
- self.output(stroke_rgb[0], stroke_rgb[1], stroke_rgb[2],
- Op.setrgb_stroke)
- if fill_rgb is not None:
- self.output(fill_rgb[0], fill_rgb[1], fill_rgb[2],
- Op.setrgb_nonstroke,
- 0, 0, sidelen, sidelen, Op.rectangle,
- Op.fill)
-
- self.output(rcParams['hatch.linewidth'], Op.setlinewidth)
-
- self.output(*self.pathOperations(
- Path.hatch(path),
- Affine2D().scale(sidelen),
- simplify=False))
- self.output(Op.fill_stroke)
-
- self.endStream()
- self.writeObject(self.hatchObject, hatchDict)
-
- def addGouraudTriangles(self, points, colors):
- name = Name('GT%d' % len(self.gouraudTriangles))
- self.gouraudTriangles.append((name, points, colors))
- return name
-
- def writeGouraudTriangles(self):
- gouraudDict = dict()
- for name, points, colors in self.gouraudTriangles:
- ob = self.reserveObject('Gouraud triangle')
- gouraudDict[name] = ob
- shape = points.shape
- flat_points = points.reshape((shape[0] * shape[1], 2))
- flat_colors = colors.reshape((shape[0] * shape[1], 4))
- points_min = np.min(flat_points, axis=0) - (1 << 8)
- points_max = np.max(flat_points, axis=0) + (1 << 8)
- factor = 0xffffffff / (points_max - points_min)
-
- self.beginStream(
- ob.id, None,
- {'ShadingType': 4,
- 'BitsPerCoordinate': 32,
- 'BitsPerComponent': 8,
- 'BitsPerFlag': 8,
- 'ColorSpace': Name('DeviceRGB'),
- 'AntiAlias': True,
- 'Decode': [points_min[0], points_max[0],
- points_min[1], points_max[1],
- 0, 1, 0, 1, 0, 1]
- })
-
- streamarr = np.empty(
- (shape[0] * shape[1],),
- dtype=[(str('flags'), str('u1')),
- (str('points'), str('>u4'), (2,)),
- (str('colors'), str('u1'), (3,))])
- streamarr['flags'] = 0
- streamarr['points'] = (flat_points - points_min) * factor
- streamarr['colors'] = flat_colors[:, :3] * 255.0
-
- self.write(streamarr.tostring())
- self.endStream()
- self.writeObject(self.gouraudObject, gouraudDict)
-
- def imageObject(self, image):
- """Return name of an image XObject representing the given image."""
-
- entry = self._images.get(id(image), None)
- if entry is not None:
- return entry[1]
-
- name = Name('I%d' % self.nextImage)
- ob = self.reserveObject('image %d' % self.nextImage)
- self.nextImage += 1
- self._images[id(image)] = (image, name, ob)
- return name
-
- def _unpack(self, im):
- """
- Unpack the image object im into height, width, data, alpha,
- where data and alpha are HxWx3 (RGB) or HxWx1 (grayscale or alpha)
- arrays, except alpha is None if the image is fully opaque.
- """
- h, w = im.shape[:2]
- im = im[::-1]
- if im.ndim == 2:
- return h, w, im, None
- else:
- rgb = im[:, :, :3]
- rgb = np.array(rgb, order='C')
- # PDF needs a separate alpha image
- if im.shape[2] == 4:
- alpha = im[:, :, 3][..., None]
- if np.all(alpha == 255):
- alpha = None
- else:
- alpha = np.array(alpha, order='C')
- else:
- alpha = None
- return h, w, rgb, alpha
-
- def _writePng(self, data):
- """
- Write the image *data* into the pdf file using png
- predictors with Flate compression.
- """
-
- buffer = BytesIO()
- _png.write_png(data, buffer)
- buffer.seek(8)
- written = 0
- header = bytearray(8)
- while True:
- n = buffer.readinto(header)
- assert n == 8
- length, type = struct.unpack(b'!L4s', bytes(header))
- if type == b'IDAT':
- data = bytearray(length)
- n = buffer.readinto(data)
- assert n == length
- self.currentstream.write(bytes(data))
- written += n
- elif type == b'IEND':
- break
- else:
- buffer.seek(length, 1)
- buffer.seek(4, 1) # skip CRC
-
- def _writeImg(self, data, height, width, grayscale, id, smask=None):
- """
- Write the image *data* of size *height* x *width*, as grayscale
- if *grayscale* is true and RGB otherwise, as pdf object *id*
- and with the soft mask (alpha channel) *smask*, which should be
- either None or a *height* x *width* x 1 array.
- """
-
- obj = {'Type': Name('XObject'),
- 'Subtype': Name('Image'),
- 'Width': width,
- 'Height': height,
- 'ColorSpace': Name('DeviceGray' if grayscale
- else 'DeviceRGB'),
- 'BitsPerComponent': 8}
- if smask:
- obj['SMask'] = smask
- if rcParams['pdf.compression']:
- png = {'Predictor': 10,
- 'Colors': 1 if grayscale else 3,
- 'Columns': width}
- else:
- png = None
- self.beginStream(
- id,
- self.reserveObject('length of image stream'),
- obj,
- png=png
- )
- if png:
- self._writePng(data)
- else:
- self.currentstream.write(data.tostring())
- self.endStream()
-
- def writeImages(self):
- for img, name, ob in six.itervalues(self._images):
- height, width, data, adata = self._unpack(img)
- if adata is not None:
- smaskObject = self.reserveObject("smask")
- self._writeImg(adata, height, width, True, smaskObject.id)
- else:
- smaskObject = None
- self._writeImg(data, height, width, False,
- ob.id, smaskObject)
-
- def markerObject(self, path, trans, fill, stroke, lw, joinstyle,
- capstyle):
- """Return name of a marker XObject representing the given path."""
- # self.markers used by markerObject, writeMarkers, close:
- # mapping from (path operations, fill?, stroke?) to
- # [name, object reference, bounding box, linewidth]
- # This enables different draw_markers calls to share the XObject
- # if the gc is sufficiently similar: colors etc can vary, but
- # the choices of whether to fill and whether to stroke cannot.
- # We need a bounding box enclosing all of the XObject path,
- # but since line width may vary, we store the maximum of all
- # occurring line widths in self.markers.
- # close() is somewhat tightly coupled in that it expects the
- # first two components of each value in self.markers to be the
- # name and object reference.
- pathops = self.pathOperations(path, trans, simplify=False)
- key = (tuple(pathops), bool(fill), bool(stroke), joinstyle, capstyle)
- result = self.markers.get(key)
- if result is None:
- name = Name('M%d' % len(self.markers))
- ob = self.reserveObject('marker %d' % len(self.markers))
- bbox = path.get_extents(trans)
- self.markers[key] = [name, ob, bbox, lw]
- else:
- if result[-1] < lw:
- result[-1] = lw
- name = result[0]
- return name
-
- def writeMarkers(self):
- for ((pathops, fill, stroke, joinstyle, capstyle),
- (name, ob, bbox, lw)) in six.iteritems(self.markers):
- bbox = bbox.padded(lw * 0.5)
- self.beginStream(
- ob.id, None,
- {'Type': Name('XObject'), 'Subtype': Name('Form'),
- 'BBox': list(bbox.extents)})
- self.output(GraphicsContextPdf.joinstyles[joinstyle],
- Op.setlinejoin)
- self.output(GraphicsContextPdf.capstyles[capstyle], Op.setlinecap)
- self.output(*pathops)
- self.output(Op.paint_path(fill, stroke))
- self.endStream()
-
- def pathCollectionObject(self, gc, path, trans, padding, filled, stroked):
- name = Name('P%d' % len(self.paths))
- ob = self.reserveObject('path %d' % len(self.paths))
- self.paths.append(
- (name, path, trans, ob, gc.get_joinstyle(), gc.get_capstyle(),
- padding, filled, stroked))
- return name
-
- def writePathCollectionTemplates(self):
- for (name, path, trans, ob, joinstyle, capstyle, padding, filled,
- stroked) in self.paths:
- pathops = self.pathOperations(path, trans, simplify=False)
- bbox = path.get_extents(trans)
- if not np.all(np.isfinite(bbox.extents)):
- extents = [0, 0, 0, 0]
- else:
- bbox = bbox.padded(padding)
- extents = list(bbox.extents)
- self.beginStream(
- ob.id, None,
- {'Type': Name('XObject'), 'Subtype': Name('Form'),
- 'BBox': extents})
- self.output(GraphicsContextPdf.joinstyles[joinstyle],
- Op.setlinejoin)
- self.output(GraphicsContextPdf.capstyles[capstyle], Op.setlinecap)
- self.output(*pathops)
- self.output(Op.paint_path(filled, stroked))
- self.endStream()
-
- @staticmethod
- def pathOperations(path, transform, clip=None, simplify=None, sketch=None):
- return [Verbatim(_path.convert_to_string(
- path, transform, clip, simplify, sketch,
- 6,
- [Op.moveto.op, Op.lineto.op, b'', Op.curveto.op, Op.closepath.op],
- True))]
-
- def writePath(self, path, transform, clip=False, sketch=None):
- if clip:
- clip = (0.0, 0.0, self.width * 72, self.height * 72)
- simplify = path.should_simplify
- else:
- clip = None
- simplify = False
- cmds = self.pathOperations(path, transform, clip, simplify=simplify,
- sketch=sketch)
- self.output(*cmds)
-
- def reserveObject(self, name=''):
- """Reserve an ID for an indirect object.
- The name is used for debugging in case we forget to print out
- the object with writeObject.
- """
-
- id = self.nextObject
- self.nextObject += 1
- self.xrefTable.append([None, 0, name])
- return Reference(id)
-
- def recordXref(self, id):
- self.xrefTable[id][0] = self.fh.tell() - self.tell_base
-
- def writeObject(self, object, contents):
- self.recordXref(object.id)
- object.write(contents, self)
-
- def writeXref(self):
- """Write out the xref table."""
-
- self.startxref = self.fh.tell() - self.tell_base
- self.write(("xref\n0 %d\n" % self.nextObject).encode('ascii'))
- i = 0
- borken = False
- for offset, generation, name in self.xrefTable:
- if offset is None:
- print('No offset for object %d (%s)' % (i, name),
- file=sys.stderr)
- borken = True
- else:
- if name == 'the zero object':
- key = "f"
- else:
- key = "n"
- text = "%010d %05d %s \n" % (offset, generation, key)
- self.write(text.encode('ascii'))
- i += 1
- if borken:
- raise AssertionError('Indirect object does not exist')
-
- def writeInfoDict(self):
- """Write out the info dictionary, checking it for good form"""
-
- def is_string_like(x):
- return isinstance(x, six.string_types)
-
- def is_date(x):
- return isinstance(x, datetime)
-
- check_trapped = (lambda x: isinstance(x, Name) and
- x.name in ('True', 'False', 'Unknown'))
-
- keywords = {'Title': is_string_like,
- 'Author': is_string_like,
- 'Subject': is_string_like,
- 'Keywords': is_string_like,
- 'Creator': is_string_like,
- 'Producer': is_string_like,
- 'CreationDate': is_date,
- 'ModDate': is_date,
- 'Trapped': check_trapped}
- for k in self.infoDict:
- if k not in keywords:
- warnings.warn('Unknown infodict keyword: %s' % k)
- else:
- if not keywords[k](self.infoDict[k]):
- warnings.warn('Bad value for infodict keyword %s' % k)
-
- self.infoObject = self.reserveObject('info')
- self.writeObject(self.infoObject, self.infoDict)
-
- def writeTrailer(self):
- """Write out the PDF trailer."""
-
- self.write(b"trailer\n")
- self.write(pdfRepr(
- {'Size': self.nextObject,
- 'Root': self.rootObject,
- 'Info': self.infoObject}))
- # Could add 'ID'
- self.write(("\nstartxref\n%d\n%%%%EOF\n" %
- self.startxref).encode('ascii'))
-
-
-class RendererPdf(RendererBase):
- afm_font_cache = maxdict(50)
-
- def __init__(self, file, image_dpi, height, width):
- RendererBase.__init__(self)
- self.height = height
- self.width = width
- self.file = file
- self.gc = self.new_gc()
- self.mathtext_parser = MathTextParser("Pdf")
- self.image_dpi = image_dpi
-
- def finalize(self):
- self.file.output(*self.gc.finalize())
-
- def check_gc(self, gc, fillcolor=None):
- orig_fill = getattr(gc, '_fillcolor', (0., 0., 0.))
- gc._fillcolor = fillcolor
-
- orig_alphas = getattr(gc, '_effective_alphas', (1.0, 1.0))
-
- if gc.get_rgb() is None:
- # it should not matter what color here
- # since linewidth should be 0
- # unless affected by global settings in rcParams
- # hence setting zero alpha just incase
- gc.set_foreground((0, 0, 0, 0), isRGBA=True)
-
- if gc._forced_alpha:
- gc._effective_alphas = (gc._alpha, gc._alpha)
- elif fillcolor is None or len(fillcolor) < 4:
- gc._effective_alphas = (gc._rgb[3], 1.0)
- else:
- gc._effective_alphas = (gc._rgb[3], fillcolor[3])
-
- delta = self.gc.delta(gc)
- if delta:
- self.file.output(*delta)
-
- # Restore gc to avoid unwanted side effects
- gc._fillcolor = orig_fill
- gc._effective_alphas = orig_alphas
-
- def track_characters(self, font, s):
- """Keeps track of which characters are required from
- each font."""
- if isinstance(font, six.string_types):
- fname = font
- else:
- fname = font.fname
- realpath, stat_key = get_realpath_and_stat(fname)
- used_characters = self.file.used_characters.setdefault(
- stat_key, (realpath, set()))
- used_characters[1].update([ord(x) for x in s])
-
- def merge_used_characters(self, other):
- for stat_key, (realpath, charset) in six.iteritems(other):
- used_characters = self.file.used_characters.setdefault(
- stat_key, (realpath, set()))
- used_characters[1].update(charset)
-
- def get_image_magnification(self):
- return self.image_dpi/72.0
-
- def option_scale_image(self):
- """
- pdf backend support arbitrary scaling of image.
- """
- return True
-
- def option_image_nocomposite(self):
- """
- return whether to generate a composite image from multiple images on
- a set of axes
- """
- return not rcParams['image.composite_image']
-
- def draw_image(self, gc, x, y, im, transform=None):
- h, w = im.shape[:2]
- if w == 0 or h == 0:
- return
-
- if transform is None:
- # If there's no transform, alpha has already been applied
- gc.set_alpha(1.0)
-
- self.check_gc(gc)
-
- w = 72.0 * w / self.image_dpi
- h = 72.0 * h / self.image_dpi
-
- imob = self.file.imageObject(im)
-
- if transform is None:
- self.file.output(Op.gsave,
- w, 0, 0, h, x, y, Op.concat_matrix,
- imob, Op.use_xobject, Op.grestore)
- else:
- tr1, tr2, tr3, tr4, tr5, tr6 = transform.frozen().to_values()
-
- self.file.output(Op.gsave,
- 1, 0, 0, 1, x, y, Op.concat_matrix,
- tr1, tr2, tr3, tr4, tr5, tr6, Op.concat_matrix,
- imob, Op.use_xobject, Op.grestore)
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- self.check_gc(gc, rgbFace)
- self.file.writePath(
- path, transform,
- rgbFace is None and gc.get_hatch_path() is None,
- gc.get_sketch_params())
- self.file.output(self.gc.paint())
-
- def draw_path_collection(self, gc, master_transform, paths, all_transforms,
- offsets, offsetTrans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position):
- # We can only reuse the objects if the presence of fill and
- # stroke (and the amount of alpha for each) is the same for
- # all of them
- can_do_optimization = True
- facecolors = np.asarray(facecolors)
- edgecolors = np.asarray(edgecolors)
-
- if not len(facecolors):
- filled = False
- can_do_optimization = not gc.get_hatch()
- else:
- if np.all(facecolors[:, 3] == facecolors[0, 3]):
- filled = facecolors[0, 3] != 0.0
- else:
- can_do_optimization = False
-
- if not len(edgecolors):
- stroked = False
- else:
- if np.all(np.asarray(linewidths) == 0.0):
- stroked = False
- elif np.all(edgecolors[:, 3] == edgecolors[0, 3]):
- stroked = edgecolors[0, 3] != 0.0
- else:
- can_do_optimization = False
-
- # Is the optimization worth it? Rough calculation:
- # cost of emitting a path in-line is len_path * uses_per_path
- # cost of XObject is len_path + 5 for the definition,
- # uses_per_path for the uses
- len_path = len(paths[0].vertices) if len(paths) > 0 else 0
- uses_per_path = self._iter_collection_uses_per_path(
- paths, all_transforms, offsets, facecolors, edgecolors)
- should_do_optimization = \
- len_path + uses_per_path + 5 < len_path * uses_per_path
-
- if (not can_do_optimization) or (not should_do_optimization):
- return RendererBase.draw_path_collection(
- self, gc, master_transform, paths, all_transforms,
- offsets, offsetTrans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position)
-
- padding = np.max(linewidths)
- path_codes = []
- for i, (path, transform) in enumerate(self._iter_collection_raw_paths(
- master_transform, paths, all_transforms)):
- name = self.file.pathCollectionObject(
- gc, path, transform, padding, filled, stroked)
- path_codes.append(name)
-
- output = self.file.output
- output(*self.gc.push())
- lastx, lasty = 0, 0
- for xo, yo, path_id, gc0, rgbFace in self._iter_collection(
- gc, master_transform, all_transforms, path_codes, offsets,
- offsetTrans, facecolors, edgecolors, linewidths, linestyles,
- antialiaseds, urls, offset_position):
-
- self.check_gc(gc0, rgbFace)
- dx, dy = xo - lastx, yo - lasty
- output(1, 0, 0, 1, dx, dy, Op.concat_matrix, path_id,
- Op.use_xobject)
- lastx, lasty = xo, yo
- output(*self.gc.pop())
-
- def draw_markers(self, gc, marker_path, marker_trans, path, trans,
- rgbFace=None):
- # Same logic as in draw_path_collection
- len_marker_path = len(marker_path)
- uses = len(path)
- if len_marker_path * uses < len_marker_path + uses + 5:
- RendererBase.draw_markers(self, gc, marker_path, marker_trans,
- path, trans, rgbFace)
- return
-
- self.check_gc(gc, rgbFace)
- fill = gc.fill(rgbFace)
- stroke = gc.stroke()
-
- output = self.file.output
- marker = self.file.markerObject(
- marker_path, marker_trans, fill, stroke, self.gc._linewidth,
- gc.get_joinstyle(), gc.get_capstyle())
-
- output(Op.gsave)
- lastx, lasty = 0, 0
- for vertices, code in path.iter_segments(
- trans,
- clip=(0, 0, self.file.width*72, self.file.height*72),
- simplify=False):
- if len(vertices):
- x, y = vertices[-2:]
- if (x < 0 or y < 0 or
- x > self.file.width * 72 or y > self.file.height * 72):
- continue
- dx, dy = x - lastx, y - lasty
- output(1, 0, 0, 1, dx, dy, Op.concat_matrix,
- marker, Op.use_xobject)
- lastx, lasty = x, y
- output(Op.grestore)
-
- def draw_gouraud_triangle(self, gc, points, colors, trans):
- self.draw_gouraud_triangles(gc, points.reshape((1, 3, 2)),
- colors.reshape((1, 3, 4)), trans)
-
- def draw_gouraud_triangles(self, gc, points, colors, trans):
- assert len(points) == len(colors)
- assert points.ndim == 3
- assert points.shape[1] == 3
- assert points.shape[2] == 2
- assert colors.ndim == 3
- assert colors.shape[1] == 3
- assert colors.shape[2] == 4
-
- shape = points.shape
- points = points.reshape((shape[0] * shape[1], 2))
- tpoints = trans.transform(points)
- tpoints = tpoints.reshape(shape)
- name = self.file.addGouraudTriangles(tpoints, colors)
- self.check_gc(gc)
- self.file.output(name, Op.shading)
-
- def _setup_textpos(self, x, y, angle, oldx=0, oldy=0, oldangle=0):
- if angle == oldangle == 0:
- self.file.output(x - oldx, y - oldy, Op.textpos)
- else:
- angle = angle / 180.0 * pi
- self.file.output(cos(angle), sin(angle),
- -sin(angle), cos(angle),
- x, y, Op.textmatrix)
- self.file.output(0, 0, Op.textpos)
-
- def draw_mathtext(self, gc, x, y, s, prop, angle):
- # TODO: fix positioning and encoding
- width, height, descent, glyphs, rects, used_characters = \
- self.mathtext_parser.parse(s, 72, prop)
- self.merge_used_characters(used_characters)
-
- # When using Type 3 fonts, we can't use character codes higher
- # than 255, so we use the "Do" command to render those
- # instead.
- global_fonttype = rcParams['pdf.fonttype']
-
- # Set up a global transformation matrix for the whole math expression
- a = angle / 180.0 * pi
- self.file.output(Op.gsave)
- self.file.output(cos(a), sin(a), -sin(a), cos(a), x, y,
- Op.concat_matrix)
-
- self.check_gc(gc, gc._rgb)
- self.file.output(Op.begin_text)
- prev_font = None, None
- oldx, oldy = 0, 0
- for ox, oy, fontname, fontsize, num, symbol_name in glyphs:
- if is_opentype_cff_font(fontname):
- fonttype = 42
- else:
- fonttype = global_fonttype
-
- if fonttype == 42 or num <= 255:
- self._setup_textpos(ox, oy, 0, oldx, oldy)
- oldx, oldy = ox, oy
- if (fontname, fontsize) != prev_font:
- self.file.output(self.file.fontName(fontname), fontsize,
- Op.selectfont)
- prev_font = fontname, fontsize
- self.file.output(self.encode_string(unichr(num), fonttype),
- Op.show)
- self.file.output(Op.end_text)
-
- # If using Type 3 fonts, render all of the multi-byte characters
- # as XObjects using the 'Do' command.
- if global_fonttype == 3:
- for ox, oy, fontname, fontsize, num, symbol_name in glyphs:
- if is_opentype_cff_font(fontname):
- fonttype = 42
- else:
- fonttype = global_fonttype
-
- if fonttype == 3 and num > 255:
- self.file.fontName(fontname)
- self.file.output(Op.gsave,
- 0.001 * fontsize, 0,
- 0, 0.001 * fontsize,
- ox, oy, Op.concat_matrix)
- name = self.file._get_xobject_symbol_name(
- fontname, symbol_name)
- self.file.output(Name(name), Op.use_xobject)
- self.file.output(Op.grestore)
-
- # Draw any horizontal lines in the math layout
- for ox, oy, width, height in rects:
- self.file.output(Op.gsave, ox, oy, width, height,
- Op.rectangle, Op.fill, Op.grestore)
-
- # Pop off the global transformation
- self.file.output(Op.grestore)
-
- def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
- texmanager = self.get_texmanager()
- fontsize = prop.get_size_in_points()
- dvifile = texmanager.make_dvi(s, fontsize)
- with dviread.Dvi(dvifile, 72) as dvi:
- page = next(iter(dvi))
-
- # Gather font information and do some setup for combining
- # characters into strings. The variable seq will contain a
- # sequence of font and text entries. A font entry is a list
- # ['font', name, size] where name is a Name object for the
- # font. A text entry is ['text', x, y, glyphs, x+w] where x
- # and y are the starting coordinates, w is the width, and
- # glyphs is a list; in this phase it will always contain just
- # one one-character string, but later it may have longer
- # strings interspersed with kern amounts.
- oldfont, seq = None, []
- for x1, y1, dvifont, glyph, width in page.text:
- if dvifont != oldfont:
- pdfname = self.file.dviFontName(dvifont)
- seq += [['font', pdfname, dvifont.size]]
- oldfont = dvifont
- # We need to convert the glyph numbers to bytes, and the easiest
- # way to do this on both Python 2 and 3 is .encode('latin-1')
- seq += [['text', x1, y1,
- [six.unichr(glyph).encode('latin-1')], x1+width]]
-
- # Find consecutive text strings with constant y coordinate and
- # combine into a sequence of strings and kerns, or just one
- # string (if any kerns would be less than 0.1 points).
- i, curx, fontsize = 0, 0, None
- while i < len(seq)-1:
- elt, nxt = seq[i:i+2]
- if elt[0] == 'font':
- fontsize = elt[2]
- elif elt[0] == nxt[0] == 'text' and elt[2] == nxt[2]:
- offset = elt[4] - nxt[1]
- if abs(offset) < 0.1:
- elt[3][-1] += nxt[3][0]
- elt[4] += nxt[4]-nxt[1]
- else:
- elt[3] += [offset*1000.0/fontsize, nxt[3][0]]
- elt[4] = nxt[4]
- del seq[i+1]
- continue
- i += 1
-
- # Create a transform to map the dvi contents to the canvas.
- mytrans = Affine2D().rotate_deg(angle).translate(x, y)
-
- # Output the text.
- self.check_gc(gc, gc._rgb)
- self.file.output(Op.begin_text)
- curx, cury, oldx, oldy = 0, 0, 0, 0
- for elt in seq:
- if elt[0] == 'font':
- self.file.output(elt[1], elt[2], Op.selectfont)
- elif elt[0] == 'text':
- curx, cury = mytrans.transform_point((elt[1], elt[2]))
- self._setup_textpos(curx, cury, angle, oldx, oldy)
- oldx, oldy = curx, cury
- if len(elt[3]) == 1:
- self.file.output(elt[3][0], Op.show)
- else:
- self.file.output(elt[3], Op.showkern)
- else:
- assert False
- self.file.output(Op.end_text)
-
- # Then output the boxes (e.g., variable-length lines of square
- # roots).
- boxgc = self.new_gc()
- boxgc.copy_properties(gc)
- boxgc.set_linewidth(0)
- pathops = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO,
- Path.CLOSEPOLY]
- for x1, y1, h, w in page.boxes:
- path = Path([[x1, y1], [x1+w, y1], [x1+w, y1+h], [x1, y1+h],
- [0, 0]], pathops)
- self.draw_path(boxgc, path, mytrans, gc._rgb)
-
- def encode_string(self, s, fonttype):
- if fonttype in (1, 3):
- return s.encode('cp1252', 'replace')
- return s.encode('utf-16be', 'replace')
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- # TODO: combine consecutive texts into one BT/ET delimited section
-
- # This function is rather complex, since there is no way to
- # access characters of a Type 3 font with codes > 255. (Type
- # 3 fonts can not have a CIDMap). Therefore, we break the
- # string into chunks, where each chunk contains exclusively
- # 1-byte or exclusively 2-byte characters, and output each
- # chunk a separate command. 1-byte characters use the regular
- # text show command (Tj), whereas 2-byte characters use the
- # use XObject command (Do). If using Type 42 fonts, all of
- # this complication is avoided, but of course, those fonts can
- # not be subsetted.
-
- self.check_gc(gc, gc._rgb)
- if ismath:
- return self.draw_mathtext(gc, x, y, s, prop, angle)
-
- fontsize = prop.get_size_in_points()
-
- if rcParams['pdf.use14corefonts']:
- font = self._get_font_afm(prop)
- l, b, w, h = font.get_str_bbox(s)
- fonttype = 1
- else:
- font = self._get_font_ttf(prop)
- self.track_characters(font, s)
- font.set_text(s, 0.0, flags=LOAD_NO_HINTING)
-
- fonttype = rcParams['pdf.fonttype']
-
- # We can't subset all OpenType fonts, so switch to Type 42
- # in that case.
- if is_opentype_cff_font(font.fname):
- fonttype = 42
-
- def check_simple_method(s):
- """Determine if we should use the simple or woven method
- to output this text, and chunks the string into 1-byte and
- 2-byte sections if necessary."""
- use_simple_method = True
- chunks = []
-
- if not rcParams['pdf.use14corefonts']:
- if fonttype == 3 and not isinstance(s, bytes) and len(s) != 0:
- # Break the string into chunks where each chunk is either
- # a string of chars <= 255, or a single character > 255.
- s = six.text_type(s)
- for c in s:
- if ord(c) <= 255:
- char_type = 1
- else:
- char_type = 2
- if len(chunks) and chunks[-1][0] == char_type:
- chunks[-1][1].append(c)
- else:
- chunks.append((char_type, [c]))
- use_simple_method = (len(chunks) == 1 and
- chunks[-1][0] == 1)
- return use_simple_method, chunks
-
- def draw_text_simple():
- """Outputs text using the simple method."""
- self.file.output(Op.begin_text,
- self.file.fontName(prop),
- fontsize,
- Op.selectfont)
- self._setup_textpos(x, y, angle)
- self.file.output(self.encode_string(s, fonttype), Op.show,
- Op.end_text)
-
- def draw_text_woven(chunks):
- """Outputs text using the woven method, alternating
- between chunks of 1-byte characters and 2-byte characters.
- Only used for Type 3 fonts."""
- chunks = [(a, ''.join(b)) for a, b in chunks]
-
- # Do the rotation and global translation as a single matrix
- # concatenation up front
- self.file.output(Op.gsave)
- a = angle / 180.0 * pi
- self.file.output(cos(a), sin(a), -sin(a), cos(a), x, y,
- Op.concat_matrix)
-
- # Output all the 1-byte characters in a BT/ET group, then
- # output all the 2-byte characters.
- for mode in (1, 2):
- newx = oldx = 0
- # Output a 1-byte character chunk
- if mode == 1:
- self.file.output(Op.begin_text,
- self.file.fontName(prop),
- fontsize,
- Op.selectfont)
-
- for chunk_type, chunk in chunks:
- if mode == 1 and chunk_type == 1:
- self._setup_textpos(newx, 0, 0, oldx, 0, 0)
- self.file.output(self.encode_string(chunk, fonttype),
- Op.show)
- oldx = newx
-
- lastgind = None
- for c in chunk:
- ccode = ord(c)
- gind = font.get_char_index(ccode)
- if gind is not None:
- if mode == 2 and chunk_type == 2:
- glyph_name = font.get_glyph_name(gind)
- self.file.output(Op.gsave)
- self.file.output(0.001 * fontsize, 0,
- 0, 0.001 * fontsize,
- newx, 0, Op.concat_matrix)
- name = self.file._get_xobject_symbol_name(
- font.fname, glyph_name)
- self.file.output(Name(name), Op.use_xobject)
- self.file.output(Op.grestore)
-
- # Move the pointer based on the character width
- # and kerning
- glyph = font.load_char(ccode,
- flags=LOAD_NO_HINTING)
- if lastgind is not None:
- kern = font.get_kerning(
- lastgind, gind, KERNING_UNFITTED)
- else:
- kern = 0
- lastgind = gind
- newx += kern/64.0 + glyph.linearHoriAdvance/65536.0
-
- if mode == 1:
- self.file.output(Op.end_text)
-
- self.file.output(Op.grestore)
-
- use_simple_method, chunks = check_simple_method(s)
- if use_simple_method:
- return draw_text_simple()
- else:
- return draw_text_woven(chunks)
-
- def get_text_width_height_descent(self, s, prop, ismath):
- if rcParams['text.usetex']:
- texmanager = self.get_texmanager()
- fontsize = prop.get_size_in_points()
- w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
- renderer=self)
- return w, h, d
-
- if ismath:
- w, h, d, glyphs, rects, used_characters = \
- self.mathtext_parser.parse(s, 72, prop)
-
- elif rcParams['pdf.use14corefonts']:
- font = self._get_font_afm(prop)
- l, b, w, h, d = font.get_str_bbox_and_descent(s)
- scale = prop.get_size_in_points()
- w *= scale / 1000
- h *= scale / 1000
- d *= scale / 1000
- else:
- font = self._get_font_ttf(prop)
- font.set_text(s, 0.0, flags=LOAD_NO_HINTING)
- w, h = font.get_width_height()
- scale = (1.0 / 64.0)
- w *= scale
- h *= scale
- d = font.get_descent()
- d *= scale
- return w, h, d
-
- def _get_font_afm(self, prop):
- key = hash(prop)
- font = self.afm_font_cache.get(key)
- if font is None:
- filename = findfont(
- prop, fontext='afm', directory=self.file._core14fontdir)
- if filename is None:
- filename = findfont(
- "Helvetica", fontext='afm',
- directory=self.file._core14fontdir)
- font = self.afm_font_cache.get(filename)
- if font is None:
- with open(filename, 'rb') as fh:
- font = AFM(fh)
- self.afm_font_cache[filename] = font
- self.afm_font_cache[key] = font
- return font
-
- def _get_font_ttf(self, prop):
- filename = findfont(prop)
- font = get_font(filename)
- font.clear()
- font.set_size(prop.get_size_in_points(), 72)
- return font
-
- def flipy(self):
- return False
-
- def get_canvas_width_height(self):
- return self.file.width * 72.0, self.file.height * 72.0
-
- def new_gc(self):
- return GraphicsContextPdf(self.file)
-
-
-class GraphicsContextPdf(GraphicsContextBase):
-
- def __init__(self, file):
- GraphicsContextBase.__init__(self)
- self._fillcolor = (0.0, 0.0, 0.0)
- self._effective_alphas = (1.0, 1.0)
- self.file = file
- self.parent = None
-
- def __repr__(self):
- d = dict(self.__dict__)
- del d['file']
- del d['parent']
- return repr(d)
-
- def stroke(self):
- """
- Predicate: does the path need to be stroked (its outline drawn)?
- This tests for the various conditions that disable stroking
- the path, in which case it would presumably be filled.
- """
- # _linewidth > 0: in pdf a line of width 0 is drawn at minimum
- # possible device width, but e.g., agg doesn't draw at all
- return (self._linewidth > 0 and self._alpha > 0 and
- (len(self._rgb) <= 3 or self._rgb[3] != 0.0))
-
- def fill(self, *args):
- """
- Predicate: does the path need to be filled?
-
- An optional argument can be used to specify an alternative
- _fillcolor, as needed by RendererPdf.draw_markers.
- """
- if len(args):
- _fillcolor = args[0]
- else:
- _fillcolor = self._fillcolor
- return (self._hatch or
- (_fillcolor is not None and
- (len(_fillcolor) <= 3 or _fillcolor[3] != 0.0)))
-
- def paint(self):
- """
- Return the appropriate pdf operator to cause the path to be
- stroked, filled, or both.
- """
- return Op.paint_path(self.fill(), self.stroke())
-
- capstyles = {'butt': 0, 'round': 1, 'projecting': 2}
- joinstyles = {'miter': 0, 'round': 1, 'bevel': 2}
-
- def capstyle_cmd(self, style):
- return [self.capstyles[style], Op.setlinecap]
-
- def joinstyle_cmd(self, style):
- return [self.joinstyles[style], Op.setlinejoin]
-
- def linewidth_cmd(self, width):
- return [width, Op.setlinewidth]
-
- def dash_cmd(self, dashes):
- offset, dash = dashes
- if dash is None:
- dash = []
- offset = 0
- return [list(dash), offset, Op.setdash]
-
- def alpha_cmd(self, alpha, forced, effective_alphas):
- name = self.file.alphaState(effective_alphas)
- return [name, Op.setgstate]
-
- def hatch_cmd(self, hatch, hatch_color):
- if not hatch:
- if self._fillcolor is not None:
- return self.fillcolor_cmd(self._fillcolor)
- else:
- return [Name('DeviceRGB'), Op.setcolorspace_nonstroke]
- else:
- hatch_style = (hatch_color, self._fillcolor, hatch)
- name = self.file.hatchPattern(hatch_style)
- return [Name('Pattern'), Op.setcolorspace_nonstroke,
- name, Op.setcolor_nonstroke]
-
- def rgb_cmd(self, rgb):
- if rcParams['pdf.inheritcolor']:
- return []
- if rgb[0] == rgb[1] == rgb[2]:
- return [rgb[0], Op.setgray_stroke]
- else:
- return list(rgb[:3]) + [Op.setrgb_stroke]
-
- def fillcolor_cmd(self, rgb):
- if rgb is None or rcParams['pdf.inheritcolor']:
- return []
- elif rgb[0] == rgb[1] == rgb[2]:
- return [rgb[0], Op.setgray_nonstroke]
- else:
- return list(rgb[:3]) + [Op.setrgb_nonstroke]
-
- def push(self):
- parent = GraphicsContextPdf(self.file)
- parent.copy_properties(self)
- parent.parent = self.parent
- self.parent = parent
- return [Op.gsave]
-
- def pop(self):
- assert self.parent is not None
- self.copy_properties(self.parent)
- self.parent = self.parent.parent
- return [Op.grestore]
-
- def clip_cmd(self, cliprect, clippath):
- """Set clip rectangle. Calls self.pop() and self.push()."""
- cmds = []
- # Pop graphics state until we hit the right one or the stack is empty
- while ((self._cliprect, self._clippath) != (cliprect, clippath)
- and self.parent is not None):
- cmds.extend(self.pop())
- # Unless we hit the right one, set the clip polygon
- if ((self._cliprect, self._clippath) != (cliprect, clippath) or
- self.parent is None):
- cmds.extend(self.push())
- if self._cliprect != cliprect:
- cmds.extend([cliprect, Op.rectangle, Op.clip, Op.endpath])
- if self._clippath != clippath:
- path, affine = clippath.get_transformed_path_and_affine()
- cmds.extend(
- PdfFile.pathOperations(path, affine, simplify=False) +
- [Op.clip, Op.endpath])
- return cmds
-
- commands = (
- # must come first since may pop
- (('_cliprect', '_clippath'), clip_cmd),
- (('_alpha', '_forced_alpha', '_effective_alphas'), alpha_cmd),
- (('_capstyle',), capstyle_cmd),
- (('_fillcolor',), fillcolor_cmd),
- (('_joinstyle',), joinstyle_cmd),
- (('_linewidth',), linewidth_cmd),
- (('_dashes',), dash_cmd),
- (('_rgb',), rgb_cmd),
- # must come after fillcolor and rgb
- (('_hatch', '_hatch_color'), hatch_cmd),
- )
-
- def delta(self, other):
- """
- Copy properties of other into self and return PDF commands
- needed to transform self into other.
- """
- cmds = []
- fill_performed = False
- for params, cmd in self.commands:
- different = False
- for p in params:
- ours = getattr(self, p)
- theirs = getattr(other, p)
- try:
- if ours is None or theirs is None:
- different = ours is not theirs
- else:
- different = bool(ours != theirs)
- except ValueError:
- ours = np.asarray(ours)
- theirs = np.asarray(theirs)
- different = (ours.shape != theirs.shape or
- np.any(ours != theirs))
- if different:
- break
-
- # Need to update hatching if we also updated fillcolor
- if params == ('_hatch', '_hatch_color') and fill_performed:
- different = True
-
- if different:
- if params == ('_fillcolor',):
- fill_performed = True
- theirs = [getattr(other, p) for p in params]
- cmds.extend(cmd(self, *theirs))
- for p in params:
- setattr(self, p, getattr(other, p))
- return cmds
-
- def copy_properties(self, other):
- """
- Copy properties of other into self.
- """
- GraphicsContextBase.copy_properties(self, other)
- fillcolor = getattr(other, '_fillcolor', self._fillcolor)
- effective_alphas = getattr(other, '_effective_alphas',
- self._effective_alphas)
- self._fillcolor = fillcolor
- self._effective_alphas = effective_alphas
-
- def finalize(self):
- """
- Make sure every pushed graphics state is popped.
- """
- cmds = []
- while self.parent is not None:
- cmds.extend(self.pop())
- return cmds
-
-########################################################################
-#
-# The following functions and classes are for pylab and implement
-# window/figure managers, etc...
-#
-########################################################################
-
-
-class PdfPages(object):
- """
- A multi-page PDF file.
-
- Examples
- --------
-
- >>> import matplotlib.pyplot as plt
- >>> # Initialize:
- >>> with PdfPages('foo.pdf') as pdf:
- ... # As many times as you like, create a figure fig and save it:
- ... fig = plt.figure()
- ... pdf.savefig(fig)
- ... # When no figure is specified the current figure is saved
- ... pdf.savefig()
-
- Notes
- -----
-
- In reality :class:`PdfPages` is a thin wrapper around :class:`PdfFile`, in
- order to avoid confusion when using :func:`~matplotlib.pyplot.savefig` and
- forgetting the format argument.
- """
- __slots__ = ('_file', 'keep_empty')
-
- def __init__(self, filename, keep_empty=True, metadata=None):
- """
- Create a new PdfPages object.
-
- Parameters
- ----------
-
- filename : str
- Plots using :meth:`PdfPages.savefig` will be written to a file at
- this location. The file is opened at once and any older file with
- the same name is overwritten.
- keep_empty : bool, optional
- If set to False, then empty pdf files will be deleted automatically
- when closed.
- metadata : dictionary, optional
- Information dictionary object (see PDF reference section 10.2.1
- 'Document Information Dictionary'), e.g.:
- `{'Creator': 'My software', 'Author': 'Me',
- 'Title': 'Awesome fig'}`
-
- The standard keys are `'Title'`, `'Author'`, `'Subject'`,
- `'Keywords'`, `'Creator'`, `'Producer'`, `'CreationDate'`,
- `'ModDate'`, and `'Trapped'`. Values have been predefined
- for `'Creator'`, `'Producer'` and `'CreationDate'`. They
- can be removed by setting them to `None`.
-
- """
- self._file = PdfFile(filename, metadata=metadata)
- self.keep_empty = keep_empty
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self.close()
-
- def close(self):
- """
- Finalize this object, making the underlying file a complete
- PDF file.
- """
- self._file.finalize()
- self._file.close()
- if (self.get_pagecount() == 0 and not self.keep_empty and
- not self._file.passed_in_file_object):
- os.remove(self._file.fh.name)
- self._file = None
-
- def infodict(self):
- """
- Return a modifiable information dictionary object
- (see PDF reference section 10.2.1 'Document Information
- Dictionary').
- """
- return self._file.infoDict
-
- def savefig(self, figure=None, **kwargs):
- """
- Saves a :class:`~matplotlib.figure.Figure` to this file as a new page.
-
- Any other keyword arguments are passed to
- :meth:`~matplotlib.figure.Figure.savefig`.
-
- Parameters
- ----------
-
- figure : :class:`~matplotlib.figure.Figure` or int, optional
- Specifies what figure is saved to file. If not specified, the
- active figure is saved. If a :class:`~matplotlib.figure.Figure`
- instance is provided, this figure is saved. If an int is specified,
- the figure instance to save is looked up by number.
- """
- if not isinstance(figure, Figure):
- if figure is None:
- manager = Gcf.get_active()
- else:
- manager = Gcf.get_fig_manager(figure)
- if manager is None:
- raise ValueError("No figure {}".format(figure))
- figure = manager.canvas.figure
- # Force use of pdf backend, as PdfPages is tightly coupled with it.
- try:
- orig_canvas = figure.canvas
- figure.canvas = FigureCanvasPdf(figure)
- figure.savefig(self, format="pdf", **kwargs)
- finally:
- figure.canvas = orig_canvas
-
- def get_pagecount(self):
- """
- Returns the current number of pages in the multipage pdf file.
- """
- return len(self._file.pageList)
-
- def attach_note(self, text, positionRect=[-100, -100, 0, 0]):
- """
- Add a new text note to the page to be saved next. The optional
- positionRect specifies the position of the new note on the
- page. It is outside the page per default to make sure it is
- invisible on printouts.
- """
- self._file.newTextnote(text, positionRect)
-
-
-class FigureCanvasPdf(FigureCanvasBase):
- """
- The canvas the figure renders into. Calls the draw and print fig
- methods, creates the renderers, etc...
-
- Attributes
- ----------
- figure : `matplotlib.figure.Figure`
- A high-level Figure instance
-
- """
-
- fixed_dpi = 72
-
- def draw(self):
- pass
-
- filetypes = {'pdf': 'Portable Document Format'}
-
- def get_default_filetype(self):
- return 'pdf'
-
- def print_pdf(self, filename, **kwargs):
- image_dpi = kwargs.get('dpi', 72) # dpi to use for images
- self.figure.set_dpi(72) # there are 72 pdf points to an inch
- width, height = self.figure.get_size_inches()
- if isinstance(filename, PdfPages):
- file = filename._file
- else:
- file = PdfFile(filename, metadata=kwargs.pop("metadata", None))
- try:
- file.newPage(width, height)
- _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None)
- renderer = MixedModeRenderer(
- self.figure, width, height, image_dpi,
- RendererPdf(file, image_dpi, height, width),
- bbox_inches_restore=_bbox_inches_restore)
- self.figure.draw(renderer)
- renderer.finalize()
- if not isinstance(filename, PdfPages):
- file.finalize()
- finally:
- if isinstance(filename, PdfPages): # finish off this page
- file.endStream()
- else: # we opened the file above; now finish it off
- file.close()
-
-
-class FigureManagerPdf(FigureManagerBase):
- pass
-
-
-@_Backend.export
-class _BackendPdf(_Backend):
- FigureCanvas = FigureCanvasPdf
- FigureManager = FigureManagerPdf
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_pgf.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_pgf.py
deleted file mode 100644
index cec6358452..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_pgf.py
+++ /dev/null
@@ -1,990 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import atexit
-import codecs
-import errno
-import math
-import os
-import re
-import shutil
-import sys
-import tempfile
-import warnings
-import weakref
-
-import matplotlib as mpl
-from matplotlib import _png, rcParams
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase,
- RendererBase)
-from matplotlib.backends.backend_mixed import MixedModeRenderer
-from matplotlib.cbook import is_writable_file_like
-from matplotlib.compat import subprocess
-from matplotlib.compat.subprocess import check_output
-from matplotlib.path import Path
-
-
-###############################################################################
-
-# create a list of system fonts, all of these should work with xe/lua-latex
-system_fonts = []
-if sys.platform.startswith('win'):
- from matplotlib import font_manager
- for f in font_manager.win32InstalledFonts():
- try:
- system_fonts.append(font_manager.get_font(str(f)).family_name)
- except:
- pass # unknown error, skip this font
-else:
- # assuming fontconfig is installed and the command 'fc-list' exists
- try:
- # list scalable (non-bitmap) fonts
- fc_list = check_output([str('fc-list'), ':outline,scalable', 'family'])
- fc_list = fc_list.decode('utf8')
- system_fonts = [f.split(',')[0] for f in fc_list.splitlines()]
- system_fonts = list(set(system_fonts))
- except:
- warnings.warn('error getting fonts from fc-list', UserWarning)
-
-def get_texcommand():
- """Get chosen TeX system from rc."""
- texsystem_options = ["xelatex", "lualatex", "pdflatex"]
- texsystem = rcParams["pgf.texsystem"]
- return texsystem if texsystem in texsystem_options else "xelatex"
-
-
-def get_fontspec():
- """Build fontspec preamble from rc."""
- latex_fontspec = []
- texcommand = get_texcommand()
-
- if texcommand != "pdflatex":
- latex_fontspec.append("\\usepackage{fontspec}")
-
- if texcommand != "pdflatex" and rcParams["pgf.rcfonts"]:
- # try to find fonts from rc parameters
- families = ["serif", "sans-serif", "monospace"]
- fontspecs = [r"\setmainfont{%s}", r"\setsansfont{%s}",
- r"\setmonofont{%s}"]
- for family, fontspec in zip(families, fontspecs):
- matches = [f for f in rcParams["font." + family]
- if f in system_fonts]
- if matches:
- latex_fontspec.append(fontspec % matches[0])
- else:
- pass # no fonts found, fallback to LaTeX defaule
-
- return "\n".join(latex_fontspec)
-
-
-def get_preamble():
- """Get LaTeX preamble from rc."""
- return "\n".join(rcParams["pgf.preamble"])
-
-###############################################################################
-
-# This almost made me cry!!!
-# In the end, it's better to use only one unit for all coordinates, since the
-# arithmetic in latex seems to produce inaccurate conversions.
-latex_pt_to_in = 1. / 72.27
-latex_in_to_pt = 1. / latex_pt_to_in
-mpl_pt_to_in = 1. / 72.
-mpl_in_to_pt = 1. / mpl_pt_to_in
-
-###############################################################################
-# helper functions
-
-NO_ESCAPE = r"(?<!\\)(?:\\\\)*"
-re_mathsep = re.compile(NO_ESCAPE + r"\$")
-re_escapetext = re.compile(NO_ESCAPE + "([_^$%])")
-repl_escapetext = lambda m: "\\" + m.group(1)
-re_mathdefault = re.compile(NO_ESCAPE + r"(\\mathdefault)")
-repl_mathdefault = lambda m: m.group(0)[:-len(m.group(1))]
-
-
-def common_texification(text):
- """
- Do some necessary and/or useful substitutions for texts to be included in
- LaTeX documents.
- """
-
- # Sometimes, matplotlib adds the unknown command \mathdefault.
- # Not using \mathnormal instead since this looks odd for the latex cm font.
- text = re_mathdefault.sub(repl_mathdefault, text)
-
- # split text into normaltext and inline math parts
- parts = re_mathsep.split(text)
- for i, s in enumerate(parts):
- if not i % 2:
- # textmode replacements
- s = re_escapetext.sub(repl_escapetext, s)
- else:
- # mathmode replacements
- s = r"\(\displaystyle %s\)" % s
- parts[i] = s
-
- return "".join(parts)
-
-
-def writeln(fh, line):
- # every line of a file included with \\input must be terminated with %
- # if not, latex will create additional vertical spaces for some reason
- fh.write(line)
- fh.write("%\n")
-
-
-def _font_properties_str(prop):
- # translate font properties to latex commands, return as string
- commands = []
-
- families = {"serif": r"\rmfamily", "sans": r"\sffamily",
- "sans-serif": r"\sffamily", "monospace": r"\ttfamily"}
- family = prop.get_family()[0]
- if family in families:
- commands.append(families[family])
- elif family in system_fonts and get_texcommand() != "pdflatex":
- commands.append(r"\setmainfont{%s}\rmfamily" % family)
- else:
- pass # print warning?
-
- size = prop.get_size_in_points()
- commands.append(r"\fontsize{%f}{%f}" % (size, size * 1.2))
-
- styles = {"normal": r"", "italic": r"\itshape", "oblique": r"\slshape"}
- commands.append(styles[prop.get_style()])
-
- boldstyles = ["semibold", "demibold", "demi", "bold", "heavy",
- "extra bold", "black"]
- if prop.get_weight() in boldstyles:
- commands.append(r"\bfseries")
-
- commands.append(r"\selectfont")
- return "".join(commands)
-
-
-def make_pdf_to_png_converter():
- """
- Returns a function that converts a pdf file to a png file.
- """
-
- tools_available = []
- # check for pdftocairo
- try:
- check_output([str("pdftocairo"), "-v"], stderr=subprocess.STDOUT)
- tools_available.append("pdftocairo")
- except:
- pass
- # check for ghostscript
- gs, ver = mpl.checkdep_ghostscript()
- if gs:
- tools_available.append("gs")
-
- # pick converter
- if "pdftocairo" in tools_available:
- def cairo_convert(pdffile, pngfile, dpi):
- cmd = [str("pdftocairo"), "-singlefile", "-png", "-r", "%d" % dpi,
- pdffile, os.path.splitext(pngfile)[0]]
- check_output(cmd, stderr=subprocess.STDOUT)
- return cairo_convert
- elif "gs" in tools_available:
- def gs_convert(pdffile, pngfile, dpi):
- cmd = [str(gs),
- '-dQUIET', '-dSAFER', '-dBATCH', '-dNOPAUSE', '-dNOPROMPT',
- '-dUseCIEColor', '-dTextAlphaBits=4',
- '-dGraphicsAlphaBits=4', '-dDOINTERPOLATE',
- '-sDEVICE=png16m', '-sOutputFile=%s' % pngfile,
- '-r%d' % dpi, pdffile]
- check_output(cmd, stderr=subprocess.STDOUT)
- return gs_convert
- else:
- raise RuntimeError("No suitable pdf to png renderer found.")
-
-
-class LatexError(Exception):
- def __init__(self, message, latex_output=""):
- Exception.__init__(self, message)
- self.latex_output = latex_output
-
-
-class LatexManagerFactory(object):
- previous_instance = None
-
- @staticmethod
- def get_latex_manager():
- texcommand = get_texcommand()
- latex_header = LatexManager._build_latex_header()
- prev = LatexManagerFactory.previous_instance
-
- # Check if the previous instance of LatexManager can be reused.
- if (prev and prev.latex_header == latex_header
- and prev.texcommand == texcommand):
- if rcParams["pgf.debug"]:
- print("reusing LatexManager")
- return prev
- else:
- if rcParams["pgf.debug"]:
- print("creating LatexManager")
- new_inst = LatexManager()
- LatexManagerFactory.previous_instance = new_inst
- return new_inst
-
-
-class LatexManager(object):
- """
- The LatexManager opens an instance of the LaTeX application for
- determining the metrics of text elements. The LaTeX environment can be
- modified by setting fonts and/or a custem preamble in the rc parameters.
- """
- _unclean_instances = weakref.WeakSet()
-
- @staticmethod
- def _build_latex_header():
- latex_preamble = get_preamble()
- latex_fontspec = get_fontspec()
- # Create LaTeX header with some content, else LaTeX will load some math
- # fonts later when we don't expect the additional output on stdout.
- # TODO: is this sufficient?
- latex_header = [r"\documentclass{minimal}",
- latex_preamble,
- latex_fontspec,
- r"\begin{document}",
- r"text $math \mu$", # force latex to load fonts now
- r"\typeout{pgf_backend_query_start}"]
- return "\n".join(latex_header)
-
- @staticmethod
- def _cleanup_remaining_instances():
- unclean_instances = list(LatexManager._unclean_instances)
- for latex_manager in unclean_instances:
- latex_manager._cleanup()
-
- def _stdin_writeln(self, s):
- self.latex_stdin_utf8.write(s)
- self.latex_stdin_utf8.write("\n")
- self.latex_stdin_utf8.flush()
-
- def _expect(self, s):
- exp = s.encode("utf8")
- buf = bytearray()
- while True:
- b = self.latex.stdout.read(1)
- buf += b
- if buf[-len(exp):] == exp:
- break
- if not len(b):
- raise LatexError("LaTeX process halted", buf.decode("utf8"))
- return buf.decode("utf8")
-
- def _expect_prompt(self):
- return self._expect("\n*")
-
- def __init__(self):
- # store references for __del__
- self._os_path = os.path
- self._shutil = shutil
- self._debug = rcParams["pgf.debug"]
-
- # create a tmp directory for running latex, remember to cleanup
- self.tmpdir = tempfile.mkdtemp(prefix="mpl_pgf_lm_")
- LatexManager._unclean_instances.add(self)
-
- # test the LaTeX setup to ensure a clean startup of the subprocess
- self.texcommand = get_texcommand()
- self.latex_header = LatexManager._build_latex_header()
- latex_end = "\n\\makeatletter\n\\@@end\n"
- try:
- latex = subprocess.Popen([str(self.texcommand), "-halt-on-error"],
- stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- cwd=self.tmpdir)
- except OSError as e:
- if e.errno == errno.ENOENT:
- raise RuntimeError(
- "Latex command not found. Install %r or change "
- "pgf.texsystem to the desired command." % self.texcommand)
- else:
- raise RuntimeError(
- "Error starting process %r" % self.texcommand)
- test_input = self.latex_header + latex_end
- stdout, stderr = latex.communicate(test_input.encode("utf-8"))
- if latex.returncode != 0:
- raise LatexError("LaTeX returned an error, probably missing font "
- "or error in preamble:\n%s" % stdout)
-
- # open LaTeX process for real work
- latex = subprocess.Popen([str(self.texcommand), "-halt-on-error"],
- stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- cwd=self.tmpdir)
- self.latex = latex
- self.latex_stdin_utf8 = codecs.getwriter("utf8")(self.latex.stdin)
- # write header with 'pgf_backend_query_start' token
- self._stdin_writeln(self._build_latex_header())
- # read all lines until our 'pgf_backend_query_start' token appears
- self._expect("*pgf_backend_query_start")
- self._expect_prompt()
-
- # cache for strings already processed
- self.str_cache = {}
-
- def _cleanup(self):
- if not self._os_path.isdir(self.tmpdir):
- return
- try:
- self.latex.communicate()
- self.latex_stdin_utf8.close()
- self.latex.stdout.close()
- except:
- pass
- try:
- self._shutil.rmtree(self.tmpdir)
- LatexManager._unclean_instances.discard(self)
- except:
- sys.stderr.write("error deleting tmp directory %s\n" % self.tmpdir)
-
- def __del__(self):
- if self._debug:
- print("deleting LatexManager")
- self._cleanup()
-
- def get_width_height_descent(self, text, prop):
- """
- Get the width, total height and descent for a text typesetted by the
- current LaTeX environment.
- """
-
- # apply font properties and define textbox
- prop_cmds = _font_properties_str(prop)
- textbox = "\\sbox0{%s %s}" % (prop_cmds, text)
-
- # check cache
- if textbox in self.str_cache:
- return self.str_cache[textbox]
-
- # send textbox to LaTeX and wait for prompt
- self._stdin_writeln(textbox)
- try:
- self._expect_prompt()
- except LatexError as e:
- raise ValueError("Error processing '{}'\nLaTeX Output:\n{}"
- .format(text, e.latex_output))
-
- # typeout width, height and text offset of the last textbox
- self._stdin_writeln(r"\typeout{\the\wd0,\the\ht0,\the\dp0}")
- # read answer from latex and advance to the next prompt
- try:
- answer = self._expect_prompt()
- except LatexError as e:
- raise ValueError("Error processing '{}'\nLaTeX Output:\n{}"
- .format(text, e.latex_output))
-
- # parse metrics from the answer string
- try:
- width, height, offset = answer.splitlines()[0].split(",")
- except:
- raise ValueError("Error processing '{}'\nLaTeX Output:\n{}"
- .format(text, answer))
- w, h, o = float(width[:-2]), float(height[:-2]), float(offset[:-2])
-
- # the height returned from LaTeX goes from base to top.
- # the height matplotlib expects goes from bottom to top.
- self.str_cache[textbox] = (w, h + o, o)
- return w, h + o, o
-
-
-class RendererPgf(RendererBase):
-
- def __init__(self, figure, fh, dummy=False):
- """
- Creates a new PGF renderer that translates any drawing instruction
- into text commands to be interpreted in a latex pgfpicture environment.
-
- Attributes
- ----------
- figure : `matplotlib.figure.Figure`
- Matplotlib figure to initialize height, width and dpi from.
- fh : file-like
- File handle for the output of the drawing commands.
-
- """
- RendererBase.__init__(self)
- self.dpi = figure.dpi
- self.fh = fh
- self.figure = figure
- self.image_counter = 0
-
- # get LatexManager instance
- self.latexManager = LatexManagerFactory.get_latex_manager()
-
- if dummy:
- # dummy==True deactivate all methods
- nop = lambda *args, **kwargs: None
- for m in RendererPgf.__dict__:
- if m.startswith("draw_"):
- self.__dict__[m] = nop
- else:
- # if fh does not belong to a filename, deactivate draw_image
- if not hasattr(fh, 'name') or not os.path.exists(fh.name):
- warnings.warn("streamed pgf-code does not support raster "
- "graphics, consider using the pgf-to-pdf option",
- UserWarning)
- self.__dict__["draw_image"] = lambda *args, **kwargs: None
-
- def draw_markers(self, gc, marker_path, marker_trans, path, trans,
- rgbFace=None):
- writeln(self.fh, r"\begin{pgfscope}")
-
- # convert from display units to in
- f = 1. / self.dpi
-
- # set style and clip
- self._print_pgf_clip(gc)
- self._print_pgf_path_styles(gc, rgbFace)
-
- # build marker definition
- bl, tr = marker_path.get_extents(marker_trans).get_points()
- coords = bl[0] * f, bl[1] * f, tr[0] * f, tr[1] * f
- writeln(self.fh,
- r"\pgfsys@defobject{currentmarker}"
- r"{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}{" % coords)
- self._print_pgf_path(None, marker_path, marker_trans)
- self._pgf_path_draw(stroke=gc.get_linewidth() != 0.0,
- fill=rgbFace is not None)
- writeln(self.fh, r"}")
-
- # draw marker for each vertex
- for point, code in path.iter_segments(trans, simplify=False):
- x, y = point[0] * f, point[1] * f
- writeln(self.fh, r"\begin{pgfscope}")
- writeln(self.fh, r"\pgfsys@transformshift{%fin}{%fin}" % (x, y))
- writeln(self.fh, r"\pgfsys@useobject{currentmarker}{}")
- writeln(self.fh, r"\end{pgfscope}")
-
- writeln(self.fh, r"\end{pgfscope}")
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- writeln(self.fh, r"\begin{pgfscope}")
- # draw the path
- self._print_pgf_clip(gc)
- self._print_pgf_path_styles(gc, rgbFace)
- self._print_pgf_path(gc, path, transform, rgbFace)
- self._pgf_path_draw(stroke=gc.get_linewidth() != 0.0,
- fill=rgbFace is not None)
- writeln(self.fh, r"\end{pgfscope}")
-
- # if present, draw pattern on top
- if gc.get_hatch():
- writeln(self.fh, r"\begin{pgfscope}")
- self._print_pgf_path_styles(gc, rgbFace)
-
- # combine clip and path for clipping
- self._print_pgf_clip(gc)
- self._print_pgf_path(gc, path, transform, rgbFace)
- writeln(self.fh, r"\pgfusepath{clip}")
-
- # build pattern definition
- writeln(self.fh,
- r"\pgfsys@defobject{currentpattern}"
- r"{\pgfqpoint{0in}{0in}}{\pgfqpoint{1in}{1in}}{")
- writeln(self.fh, r"\begin{pgfscope}")
- writeln(self.fh,
- r"\pgfpathrectangle"
- r"{\pgfqpoint{0in}{0in}}{\pgfqpoint{1in}{1in}}")
- writeln(self.fh, r"\pgfusepath{clip}")
- scale = mpl.transforms.Affine2D().scale(self.dpi)
- self._print_pgf_path(None, gc.get_hatch_path(), scale)
- self._pgf_path_draw(stroke=True)
- writeln(self.fh, r"\end{pgfscope}")
- writeln(self.fh, r"}")
- # repeat pattern, filling the bounding rect of the path
- f = 1. / self.dpi
- (xmin, ymin), (xmax, ymax) = \
- path.get_extents(transform).get_points()
- xmin, xmax = f * xmin, f * xmax
- ymin, ymax = f * ymin, f * ymax
- repx, repy = int(math.ceil(xmax-xmin)), int(math.ceil(ymax-ymin))
- writeln(self.fh,
- r"\pgfsys@transformshift{%fin}{%fin}" % (xmin, ymin))
- for iy in range(repy):
- for ix in range(repx):
- writeln(self.fh, r"\pgfsys@useobject{currentpattern}{}")
- writeln(self.fh, r"\pgfsys@transformshift{1in}{0in}")
- writeln(self.fh, r"\pgfsys@transformshift{-%din}{0in}" % repx)
- writeln(self.fh, r"\pgfsys@transformshift{0in}{1in}")
-
- writeln(self.fh, r"\end{pgfscope}")
-
- def _print_pgf_clip(self, gc):
- f = 1. / self.dpi
- # check for clip box
- bbox = gc.get_clip_rectangle()
- if bbox:
- p1, p2 = bbox.get_points()
- w, h = p2 - p1
- coords = p1[0] * f, p1[1] * f, w * f, h * f
- writeln(self.fh,
- r"\pgfpathrectangle"
- r"{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}"
- % coords)
- writeln(self.fh, r"\pgfusepath{clip}")
-
- # check for clip path
- clippath, clippath_trans = gc.get_clip_path()
- if clippath is not None:
- self._print_pgf_path(gc, clippath, clippath_trans)
- writeln(self.fh, r"\pgfusepath{clip}")
-
- def _print_pgf_path_styles(self, gc, rgbFace):
- # cap style
- capstyles = {"butt": r"\pgfsetbuttcap",
- "round": r"\pgfsetroundcap",
- "projecting": r"\pgfsetrectcap"}
- writeln(self.fh, capstyles[gc.get_capstyle()])
-
- # join style
- joinstyles = {"miter": r"\pgfsetmiterjoin",
- "round": r"\pgfsetroundjoin",
- "bevel": r"\pgfsetbeveljoin"}
- writeln(self.fh, joinstyles[gc.get_joinstyle()])
-
- # filling
- has_fill = rgbFace is not None
-
- if gc.get_forced_alpha():
- fillopacity = strokeopacity = gc.get_alpha()
- else:
- strokeopacity = gc.get_rgb()[3]
- fillopacity = rgbFace[3] if has_fill and len(rgbFace) > 3 else 1.0
-
- if has_fill:
- writeln(self.fh,
- r"\definecolor{currentfill}{rgb}{%f,%f,%f}"
- % tuple(rgbFace[:3]))
- writeln(self.fh, r"\pgfsetfillcolor{currentfill}")
- if has_fill and fillopacity != 1.0:
- writeln(self.fh, r"\pgfsetfillopacity{%f}" % fillopacity)
-
- # linewidth and color
- lw = gc.get_linewidth() * mpl_pt_to_in * latex_in_to_pt
- stroke_rgba = gc.get_rgb()
- writeln(self.fh, r"\pgfsetlinewidth{%fpt}" % lw)
- writeln(self.fh,
- r"\definecolor{currentstroke}{rgb}{%f,%f,%f}"
- % stroke_rgba[:3])
- writeln(self.fh, r"\pgfsetstrokecolor{currentstroke}")
- if strokeopacity != 1.0:
- writeln(self.fh, r"\pgfsetstrokeopacity{%f}" % strokeopacity)
-
- # line style
- dash_offset, dash_list = gc.get_dashes()
- if dash_list is None:
- writeln(self.fh, r"\pgfsetdash{}{0pt}")
- else:
- writeln(self.fh,
- r"\pgfsetdash{%s}{%fpt}"
- % ("".join(r"{%fpt}" % dash for dash in dash_list),
- dash_offset))
-
- def _print_pgf_path(self, gc, path, transform, rgbFace=None):
- f = 1. / self.dpi
- # check for clip box / ignore clip for filled paths
- bbox = gc.get_clip_rectangle() if gc else None
- if bbox and (rgbFace is None):
- p1, p2 = bbox.get_points()
- clip = (p1[0], p1[1], p2[0], p2[1])
- else:
- clip = None
- # build path
- for points, code in path.iter_segments(transform, clip=clip):
- if code == Path.MOVETO:
- x, y = tuple(points)
- writeln(self.fh,
- r"\pgfpathmoveto{\pgfqpoint{%fin}{%fin}}" %
- (f * x, f * y))
- elif code == Path.CLOSEPOLY:
- writeln(self.fh, r"\pgfpathclose")
- elif code == Path.LINETO:
- x, y = tuple(points)
- writeln(self.fh,
- r"\pgfpathlineto{\pgfqpoint{%fin}{%fin}}" %
- (f * x, f * y))
- elif code == Path.CURVE3:
- cx, cy, px, py = tuple(points)
- coords = cx * f, cy * f, px * f, py * f
- writeln(self.fh,
- r"\pgfpathquadraticcurveto"
- r"{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}"
- % coords)
- elif code == Path.CURVE4:
- c1x, c1y, c2x, c2y, px, py = tuple(points)
- coords = c1x * f, c1y * f, c2x * f, c2y * f, px * f, py * f
- writeln(self.fh,
- r"\pgfpathcurveto"
- r"{\pgfqpoint{%fin}{%fin}}"
- r"{\pgfqpoint{%fin}{%fin}}"
- r"{\pgfqpoint{%fin}{%fin}}"
- % coords)
-
- def _pgf_path_draw(self, stroke=True, fill=False):
- actions = []
- if stroke:
- actions.append("stroke")
- if fill:
- actions.append("fill")
- writeln(self.fh, r"\pgfusepath{%s}" % ",".join(actions))
-
- def option_scale_image(self):
- """
- pgf backend supports affine transform of image.
- """
- return True
-
- def option_image_nocomposite(self):
- """
- return whether to generate a composite image from multiple images on
- a set of axes
- """
- return not rcParams['image.composite_image']
-
- def draw_image(self, gc, x, y, im, transform=None):
- h, w = im.shape[:2]
- if w == 0 or h == 0:
- return
-
- # save the images to png files
- path = os.path.dirname(self.fh.name)
- fname = os.path.splitext(os.path.basename(self.fh.name))[0]
- fname_img = "%s-img%d.png" % (fname, self.image_counter)
- self.image_counter += 1
- _png.write_png(im[::-1], os.path.join(path, fname_img))
-
- # reference the image in the pgf picture
- writeln(self.fh, r"\begin{pgfscope}")
- self._print_pgf_clip(gc)
- f = 1. / self.dpi # from display coords to inch
- if transform is None:
- writeln(self.fh,
- r"\pgfsys@transformshift{%fin}{%fin}" % (x * f, y * f))
- w, h = w * f, h * f
- else:
- tr1, tr2, tr3, tr4, tr5, tr6 = transform.frozen().to_values()
- writeln(self.fh,
- r"\pgfsys@transformcm{%f}{%f}{%f}{%f}{%fin}{%fin}" %
- (tr1 * f, tr2 * f, tr3 * f, tr4 * f,
- (tr5 + x) * f, (tr6 + y) * f))
- w = h = 1 # scale is already included in the transform
- interp = str(transform is None).lower() # interpolation in PDF reader
- writeln(self.fh,
- r"\pgftext[left,bottom]"
- r"{\pgfimage[interpolate=%s,width=%fin,height=%fin]{%s}}" %
- (interp, w, h, fname_img))
- writeln(self.fh, r"\end{pgfscope}")
-
- def draw_tex(self, gc, x, y, s, prop, angle, ismath="TeX!", mtext=None):
- self.draw_text(gc, x, y, s, prop, angle, ismath, mtext)
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- # prepare string for tex
- s = common_texification(s)
- prop_cmds = _font_properties_str(prop)
- s = r"%s %s" % (prop_cmds, s)
-
-
- writeln(self.fh, r"\begin{pgfscope}")
-
- alpha = gc.get_alpha()
- if alpha != 1.0:
- writeln(self.fh, r"\pgfsetfillopacity{%f}" % alpha)
- writeln(self.fh, r"\pgfsetstrokeopacity{%f}" % alpha)
- rgb = tuple(gc.get_rgb())[:3]
- if rgb != (0, 0, 0):
- writeln(self.fh, r"\definecolor{textcolor}{rgb}{%f,%f,%f}" % rgb)
- writeln(self.fh, r"\pgfsetstrokecolor{textcolor}")
- writeln(self.fh, r"\pgfsetfillcolor{textcolor}")
- s = r"\color{textcolor}" + s
-
- f = 1.0 / self.figure.dpi
- text_args = []
- if mtext and (
- (angle == 0 or
- mtext.get_rotation_mode() == "anchor") and
- mtext.get_va() != "center_baseline"):
- # if text anchoring can be supported, get the original coordinates
- # and add alignment information
- x, y = mtext.get_transform().transform_point(mtext.get_position())
- text_args.append("x=%fin" % (x * f))
- text_args.append("y=%fin" % (y * f))
-
- halign = {"left": "left", "right": "right", "center": ""}
- valign = {"top": "top", "bottom": "bottom",
- "baseline": "base", "center": ""}
- text_args.append(halign[mtext.get_ha()])
- text_args.append(valign[mtext.get_va()])
- else:
- # if not, use the text layout provided by matplotlib
- text_args.append("x=%fin" % (x * f))
- text_args.append("y=%fin" % (y * f))
- text_args.append("left")
- text_args.append("base")
-
- if angle != 0:
- text_args.append("rotate=%f" % angle)
-
- writeln(self.fh, r"\pgftext[%s]{%s}" % (",".join(text_args), s))
- writeln(self.fh, r"\end{pgfscope}")
-
- def get_text_width_height_descent(self, s, prop, ismath):
- # check if the math is supposed to be displaystyled
- s = common_texification(s)
-
- # get text metrics in units of latex pt, convert to display units
- w, h, d = self.latexManager.get_width_height_descent(s, prop)
- # TODO: this should be latex_pt_to_in instead of mpl_pt_to_in
- # but having a little bit more space around the text looks better,
- # plus the bounding box reported by LaTeX is VERY narrow
- f = mpl_pt_to_in * self.dpi
- return w * f, h * f, d * f
-
- def flipy(self):
- return False
-
- def get_canvas_width_height(self):
- return self.figure.get_figwidth(), self.figure.get_figheight()
-
- def points_to_pixels(self, points):
- return points * mpl_pt_to_in * self.dpi
-
- def new_gc(self):
- return GraphicsContextPgf()
-
-
-class GraphicsContextPgf(GraphicsContextBase):
- pass
-
-########################################################################
-
-
-class TmpDirCleaner(object):
- remaining_tmpdirs = set()
-
- @staticmethod
- def add(tmpdir):
- TmpDirCleaner.remaining_tmpdirs.add(tmpdir)
-
- @staticmethod
- def cleanup_remaining_tmpdirs():
- for tmpdir in TmpDirCleaner.remaining_tmpdirs:
- try:
- shutil.rmtree(tmpdir)
- except:
- sys.stderr.write("error deleting tmp directory %s\n" % tmpdir)
-
-
-class FigureCanvasPgf(FigureCanvasBase):
- filetypes = {"pgf": "LaTeX PGF picture",
- "pdf": "LaTeX compiled PGF picture",
- "png": "Portable Network Graphics", }
-
- def get_default_filetype(self):
- return 'pdf'
-
- def _print_pgf_to_fh(self, fh, *args, **kwargs):
- if kwargs.get("dryrun", False):
- renderer = RendererPgf(self.figure, None, dummy=True)
- self.figure.draw(renderer)
- return
-
- header_text = """%% Creator: Matplotlib, PGF backend
-%%
-%% To include the figure in your LaTeX document, write
-%% \\input{<filename>.pgf}
-%%
-%% Make sure the required packages are loaded in your preamble
-%% \\usepackage{pgf}
-%%
-%% Figures using additional raster images can only be included by \\input if
-%% they are in the same directory as the main LaTeX file. For loading figures
-%% from other directories you can use the `import` package
-%% \\usepackage{import}
-%% and then include the figures with
-%% \\import{<path to file>}{<filename>.pgf}
-%%
-"""
-
- # append the preamble used by the backend as a comment for debugging
- header_info_preamble = ["%% Matplotlib used the following preamble"]
- for line in get_preamble().splitlines():
- header_info_preamble.append("%% " + line)
- for line in get_fontspec().splitlines():
- header_info_preamble.append("%% " + line)
- header_info_preamble.append("%%")
- header_info_preamble = "\n".join(header_info_preamble)
-
- # get figure size in inch
- w, h = self.figure.get_figwidth(), self.figure.get_figheight()
- dpi = self.figure.get_dpi()
-
- # create pgfpicture environment and write the pgf code
- fh.write(header_text)
- fh.write(header_info_preamble)
- fh.write("\n")
- writeln(fh, r"\begingroup")
- writeln(fh, r"\makeatletter")
- writeln(fh, r"\begin{pgfpicture}")
- writeln(fh,
- r"\pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{%fin}{%fin}}"
- % (w, h))
- writeln(fh, r"\pgfusepath{use as bounding box, clip}")
- _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None)
- renderer = MixedModeRenderer(self.figure, w, h, dpi,
- RendererPgf(self.figure, fh),
- bbox_inches_restore=_bbox_inches_restore)
- self.figure.draw(renderer)
-
- # end the pgfpicture environment
- writeln(fh, r"\end{pgfpicture}")
- writeln(fh, r"\makeatother")
- writeln(fh, r"\endgroup")
-
- def print_pgf(self, fname_or_fh, *args, **kwargs):
- """
- Output pgf commands for drawing the figure so it can be included and
- rendered in latex documents.
- """
- if kwargs.get("dryrun", False):
- self._print_pgf_to_fh(None, *args, **kwargs)
- return
-
- # figure out where the pgf is to be written to
- if isinstance(fname_or_fh, six.string_types):
- with codecs.open(fname_or_fh, "w", encoding="utf-8") as fh:
- self._print_pgf_to_fh(fh, *args, **kwargs)
- elif is_writable_file_like(fname_or_fh):
- fh = codecs.getwriter("utf-8")(fname_or_fh)
- self._print_pgf_to_fh(fh, *args, **kwargs)
- else:
- raise ValueError("filename must be a path")
-
- def _print_pdf_to_fh(self, fh, *args, **kwargs):
- w, h = self.figure.get_figwidth(), self.figure.get_figheight()
-
- try:
- # create temporary directory for compiling the figure
- tmpdir = tempfile.mkdtemp(prefix="mpl_pgf_")
- fname_pgf = os.path.join(tmpdir, "figure.pgf")
- fname_tex = os.path.join(tmpdir, "figure.tex")
- fname_pdf = os.path.join(tmpdir, "figure.pdf")
-
- # print figure to pgf and compile it with latex
- self.print_pgf(fname_pgf, *args, **kwargs)
-
- latex_preamble = get_preamble()
- latex_fontspec = get_fontspec()
- latexcode = """
-\\documentclass[12pt]{minimal}
-\\usepackage[paperwidth=%fin, paperheight=%fin, margin=0in]{geometry}
-%s
-%s
-\\usepackage{pgf}
-
-\\begin{document}
-\\centering
-\\input{figure.pgf}
-\\end{document}""" % (w, h, latex_preamble, latex_fontspec)
- with codecs.open(fname_tex, "w", "utf-8") as fh_tex:
- fh_tex.write(latexcode)
-
- texcommand = get_texcommand()
- cmdargs = [str(texcommand), "-interaction=nonstopmode",
- "-halt-on-error", "figure.tex"]
- try:
- check_output(cmdargs, stderr=subprocess.STDOUT, cwd=tmpdir)
- except subprocess.CalledProcessError as e:
- raise RuntimeError(
- "%s was not able to process your file.\n\nFull log:\n%s"
- % (texcommand, e.output))
-
- # copy file contents to target
- with open(fname_pdf, "rb") as fh_src:
- shutil.copyfileobj(fh_src, fh)
- finally:
- try:
- shutil.rmtree(tmpdir)
- except:
- TmpDirCleaner.add(tmpdir)
-
- def print_pdf(self, fname_or_fh, *args, **kwargs):
- """
- Use LaTeX to compile a Pgf generated figure to PDF.
- """
- if kwargs.get("dryrun", False):
- self._print_pgf_to_fh(None, *args, **kwargs)
- return
-
- # figure out where the pdf is to be written to
- if isinstance(fname_or_fh, six.string_types):
- with open(fname_or_fh, "wb") as fh:
- self._print_pdf_to_fh(fh, *args, **kwargs)
- elif is_writable_file_like(fname_or_fh):
- self._print_pdf_to_fh(fname_or_fh, *args, **kwargs)
- else:
- raise ValueError("filename must be a path or a file-like object")
-
- def _print_png_to_fh(self, fh, *args, **kwargs):
- converter = make_pdf_to_png_converter()
-
- try:
- # create temporary directory for pdf creation and png conversion
- tmpdir = tempfile.mkdtemp(prefix="mpl_pgf_")
- fname_pdf = os.path.join(tmpdir, "figure.pdf")
- fname_png = os.path.join(tmpdir, "figure.png")
- # create pdf and try to convert it to png
- self.print_pdf(fname_pdf, *args, **kwargs)
- converter(fname_pdf, fname_png, dpi=self.figure.dpi)
- # copy file contents to target
- with open(fname_png, "rb") as fh_src:
- shutil.copyfileobj(fh_src, fh)
- finally:
- try:
- shutil.rmtree(tmpdir)
- except:
- TmpDirCleaner.add(tmpdir)
-
- def print_png(self, fname_or_fh, *args, **kwargs):
- """
- Use LaTeX to compile a pgf figure to pdf and convert it to png.
- """
- if kwargs.get("dryrun", False):
- self._print_pgf_to_fh(None, *args, **kwargs)
- return
-
- if isinstance(fname_or_fh, six.string_types):
- with open(fname_or_fh, "wb") as fh:
- self._print_png_to_fh(fh, *args, **kwargs)
- elif is_writable_file_like(fname_or_fh):
- self._print_png_to_fh(fname_or_fh, *args, **kwargs)
- else:
- raise ValueError("filename must be a path or a file-like object")
-
- def get_renderer(self):
- return RendererPgf(self.figure, None, dummy=True)
-
-
-class FigureManagerPgf(FigureManagerBase):
- def __init__(self, *args):
- FigureManagerBase.__init__(self, *args)
-
-
-@_Backend.export
-class _BackendPgf(_Backend):
- FigureCanvas = FigureCanvasPgf
- FigureManager = FigureManagerPgf
-
-
-def _cleanup_all():
- LatexManager._cleanup_remaining_instances()
- TmpDirCleaner.cleanup_remaining_tmpdirs()
-
-atexit.register(_cleanup_all)
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_ps.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_ps.py
deleted file mode 100644
index 5e475101d3..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_ps.py
+++ /dev/null
@@ -1,1762 +0,0 @@
-"""
-A PostScript backend, which can produce both PostScript .ps and .eps
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import StringIO
-
-import glob, os, shutil, sys, time, datetime
-import io
-import logging
-
-from tempfile import mkstemp
-from matplotlib import cbook, __version__, rcParams, checkdep_ghostscript
-from matplotlib.afm import AFM
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase,
- RendererBase)
-
-from matplotlib.cbook import (get_realpath_and_stat, is_writable_file_like,
- maxdict, file_requires_unicode)
-from matplotlib.compat.subprocess import subprocess
-
-from matplotlib.font_manager import findfont, is_opentype_cff_font, get_font
-from matplotlib.ft2font import KERNING_DEFAULT, LOAD_NO_HINTING
-from matplotlib.ttconv import convert_ttf_to_ps
-from matplotlib.mathtext import MathTextParser
-from matplotlib._mathtext_data import uni2type1
-from matplotlib.path import Path
-from matplotlib import _path
-from matplotlib.transforms import Affine2D
-
-from matplotlib.backends.backend_mixed import MixedModeRenderer
-
-
-import numpy as np
-import binascii
-import re
-
-_log = logging.getLogger(__name__)
-
-backend_version = 'Level II'
-
-debugPS = 0
-
-
-class PsBackendHelper(object):
-
- def __init__(self):
- self._cached = {}
-
- @property
- def gs_exe(self):
- """
- executable name of ghostscript.
- """
- try:
- return self._cached["gs_exe"]
- except KeyError:
- pass
-
- gs_exe, gs_version = checkdep_ghostscript()
- if gs_exe is None:
- gs_exe = 'gs'
-
- self._cached["gs_exe"] = str(gs_exe)
- return str(gs_exe)
-
- @property
- def gs_version(self):
- """
- version of ghostscript.
- """
- try:
- return self._cached["gs_version"]
- except KeyError:
- pass
-
- from matplotlib.compat.subprocess import Popen, PIPE
- s = Popen([self.gs_exe, "--version"], stdout=PIPE)
- pipe, stderr = s.communicate()
- if six.PY3:
- ver = pipe.decode('ascii')
- else:
- ver = pipe
- try:
- gs_version = tuple(map(int, ver.strip().split(".")))
- except ValueError:
- # if something went wrong parsing return null version number
- gs_version = (0, 0)
- self._cached["gs_version"] = gs_version
- return gs_version
-
- @property
- def supports_ps2write(self):
- """
- True if the installed ghostscript supports ps2write device.
- """
- return self.gs_version[0] >= 9
-
-ps_backend_helper = PsBackendHelper()
-
-papersize = {'letter': (8.5,11),
- 'legal': (8.5,14),
- 'ledger': (11,17),
- 'a0': (33.11,46.81),
- 'a1': (23.39,33.11),
- 'a2': (16.54,23.39),
- 'a3': (11.69,16.54),
- 'a4': (8.27,11.69),
- 'a5': (5.83,8.27),
- 'a6': (4.13,5.83),
- 'a7': (2.91,4.13),
- 'a8': (2.07,2.91),
- 'a9': (1.457,2.05),
- 'a10': (1.02,1.457),
- 'b0': (40.55,57.32),
- 'b1': (28.66,40.55),
- 'b2': (20.27,28.66),
- 'b3': (14.33,20.27),
- 'b4': (10.11,14.33),
- 'b5': (7.16,10.11),
- 'b6': (5.04,7.16),
- 'b7': (3.58,5.04),
- 'b8': (2.51,3.58),
- 'b9': (1.76,2.51),
- 'b10': (1.26,1.76)}
-
-def _get_papertype(w, h):
- keys = list(six.iterkeys(papersize))
- keys.sort()
- keys.reverse()
- for key in keys:
- if key.startswith('l'): continue
- pw, ph = papersize[key]
- if (w < pw) and (h < ph): return key
- return 'a0'
-
-def _num_to_str(val):
- if isinstance(val, six.string_types): return val
-
- ival = int(val)
- if val == ival: return str(ival)
-
- s = "%1.3f"%val
- s = s.rstrip("0")
- s = s.rstrip(".")
- return s
-
-def _nums_to_str(*args):
- return ' '.join(map(_num_to_str,args))
-
-
-def quote_ps_string(s):
- "Quote dangerous characters of S for use in a PostScript string constant."
- s = s.replace(b"\\", b"\\\\")
- s = s.replace(b"(", b"\\(")
- s = s.replace(b")", b"\\)")
- s = s.replace(b"'", b"\\251")
- s = s.replace(b"`", b"\\301")
- s = re.sub(br"[^ -~\n]", lambda x: br"\%03o" % ord(x.group()), s)
- return s.decode('ascii')
-
-
-def _move_path_to_path_or_stream(src, dst):
- """Move the contents of file at *src* to path-or-filelike *dst*.
-
- If *dst* is a path, the metadata of *src* are *not* copied.
- """
- if is_writable_file_like(dst):
- fh = (io.open(src, 'r', encoding='latin-1')
- if file_requires_unicode(dst)
- else io.open(src, 'rb'))
- with fh:
- shutil.copyfileobj(fh, dst)
- else:
- # Py3: shutil.move(src, dst, copy_function=shutil.copyfile)
- open(dst, 'w').close()
- mode = os.stat(dst).st_mode
- shutil.move(src, dst)
- os.chmod(dst, mode)
-
-
-class RendererPS(RendererBase):
- """
- The renderer handles all the drawing primitives using a graphics
- context instance that controls the colors/styles.
- """
-
- afmfontd = maxdict(50)
-
- def __init__(self, width, height, pswriter, imagedpi=72):
- """
- Although postscript itself is dpi independent, we need to
- imform the image code about a requested dpi to generate high
- res images and them scale them before embeddin them
- """
- RendererBase.__init__(self)
- self.width = width
- self.height = height
- self._pswriter = pswriter
- if rcParams['text.usetex']:
- self.textcnt = 0
- self.psfrag = []
- self.imagedpi = imagedpi
-
- # current renderer state (None=uninitialised)
- self.color = None
- self.linewidth = None
- self.linejoin = None
- self.linecap = None
- self.linedash = None
- self.fontname = None
- self.fontsize = None
- self._hatches = {}
- self.image_magnification = imagedpi/72.0
- self._clip_paths = {}
- self._path_collection_id = 0
-
- self.used_characters = {}
- self.mathtext_parser = MathTextParser("PS")
-
- self._afm_font_dir = os.path.join(
- rcParams['datapath'], 'fonts', 'afm')
-
- def track_characters(self, font, s):
- """Keeps track of which characters are required from
- each font."""
- realpath, stat_key = get_realpath_and_stat(font.fname)
- used_characters = self.used_characters.setdefault(
- stat_key, (realpath, set()))
- used_characters[1].update([ord(x) for x in s])
-
- def merge_used_characters(self, other):
- for stat_key, (realpath, charset) in six.iteritems(other):
- used_characters = self.used_characters.setdefault(
- stat_key, (realpath, set()))
- used_characters[1].update(charset)
-
- def set_color(self, r, g, b, store=1):
- if (r,g,b) != self.color:
- if r==g and r==b:
- self._pswriter.write("%1.3f setgray\n"%r)
- else:
- self._pswriter.write("%1.3f %1.3f %1.3f setrgbcolor\n"%(r,g,b))
- if store: self.color = (r,g,b)
-
- def set_linewidth(self, linewidth, store=1):
- linewidth = float(linewidth)
- if linewidth != self.linewidth:
- self._pswriter.write("%1.3f setlinewidth\n"%linewidth)
- if store: self.linewidth = linewidth
-
- def set_linejoin(self, linejoin, store=1):
- if linejoin != self.linejoin:
- self._pswriter.write("%d setlinejoin\n"%linejoin)
- if store: self.linejoin = linejoin
-
- def set_linecap(self, linecap, store=1):
- if linecap != self.linecap:
- self._pswriter.write("%d setlinecap\n"%linecap)
- if store: self.linecap = linecap
-
- def set_linedash(self, offset, seq, store=1):
- if self.linedash is not None:
- oldo, oldseq = self.linedash
- if np.array_equal(seq, oldseq) and oldo == offset:
- return
-
- if seq is not None and len(seq):
- s="[%s] %d setdash\n"%(_nums_to_str(*seq), offset)
- self._pswriter.write(s)
- else:
- self._pswriter.write("[] 0 setdash\n")
- if store:
- self.linedash = (offset, seq)
-
- def set_font(self, fontname, fontsize, store=1):
- if rcParams['ps.useafm']: return
- if (fontname,fontsize) != (self.fontname,self.fontsize):
- out = ("/%s findfont\n"
- "%1.3f scalefont\n"
- "setfont\n" % (fontname, fontsize))
-
- self._pswriter.write(out)
- if store: self.fontname = fontname
- if store: self.fontsize = fontsize
-
- def create_hatch(self, hatch):
- sidelen = 72
- if hatch in self._hatches:
- return self._hatches[hatch]
- name = 'H%d' % len(self._hatches)
- linewidth = rcParams['hatch.linewidth']
- pageheight = self.height * 72
- self._pswriter.write("""\
- << /PatternType 1
- /PaintType 2
- /TilingType 2
- /BBox[0 0 %(sidelen)d %(sidelen)d]
- /XStep %(sidelen)d
- /YStep %(sidelen)d
-
- /PaintProc {
- pop
- %(linewidth)f setlinewidth
-""" % locals())
- self._pswriter.write(
- self._convert_path(Path.hatch(hatch), Affine2D().scale(sidelen),
- simplify=False))
- self._pswriter.write("""\
- fill
- stroke
- } bind
- >>
- matrix
- 0.0 %(pageheight)f translate
- makepattern
- /%(name)s exch def
-""" % locals())
- self._hatches[hatch] = name
- return name
-
- def get_canvas_width_height(self):
- 'return the canvas width and height in display coords'
- return self.width * 72.0, self.height * 72.0
-
- def get_text_width_height_descent(self, s, prop, ismath):
- """
- get the width and height in display coords of the string s
- with FontPropertry prop
-
- """
- if rcParams['text.usetex']:
- texmanager = self.get_texmanager()
- fontsize = prop.get_size_in_points()
- w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
- renderer=self)
- return w, h, d
-
- if ismath:
- width, height, descent, pswriter, used_characters = \
- self.mathtext_parser.parse(s, 72, prop)
- return width, height, descent
-
- if rcParams['ps.useafm']:
- if ismath: s = s[1:-1]
- font = self._get_font_afm(prop)
- l,b,w,h,d = font.get_str_bbox_and_descent(s)
-
- fontsize = prop.get_size_in_points()
- scale = 0.001*fontsize
- w *= scale
- h *= scale
- d *= scale
- return w, h, d
-
- font = self._get_font_ttf(prop)
- font.set_text(s, 0.0, flags=LOAD_NO_HINTING)
- w, h = font.get_width_height()
- w /= 64.0 # convert from subpixels
- h /= 64.0
- d = font.get_descent()
- d /= 64.0
- return w, h, d
-
- def flipy(self):
- 'return true if small y numbers are top for renderer'
- return False
-
- def _get_font_afm(self, prop):
- key = hash(prop)
- font = self.afmfontd.get(key)
- if font is None:
- fname = findfont(prop, fontext='afm', directory=self._afm_font_dir)
- if fname is None:
- fname = findfont(
- "Helvetica", fontext='afm', directory=self._afm_font_dir)
- font = self.afmfontd.get(fname)
- if font is None:
- with io.open(fname, 'rb') as fh:
- font = AFM(fh)
- self.afmfontd[fname] = font
- self.afmfontd[key] = font
- return font
-
- def _get_font_ttf(self, prop):
- fname = findfont(prop)
- font = get_font(fname)
- font.clear()
- size = prop.get_size_in_points()
- font.set_size(size, 72.0)
- return font
-
- def _rgb(self, rgba):
- h, w = rgba.shape[:2]
- rgb = rgba[::-1, :, :3]
- return h, w, rgb.tostring()
-
- def _hex_lines(self, s, chars_per_line=128):
- s = binascii.b2a_hex(s)
- nhex = len(s)
- lines = []
- for i in range(0,nhex,chars_per_line):
- limit = min(i+chars_per_line, nhex)
- lines.append(s[i:limit])
- return lines
-
- def get_image_magnification(self):
- """
- Get the factor by which to magnify images passed to draw_image.
- Allows a backend to have images at a different resolution to other
- artists.
- """
- return self.image_magnification
-
- def option_scale_image(self):
- """
- ps backend support arbitrary scaling of image.
- """
- return True
-
- def option_image_nocomposite(self):
- """
- return whether to generate a composite image from multiple images on
- a set of axes
- """
- return not rcParams['image.composite_image']
-
- def _get_image_h_w_bits_command(self, im):
- h, w, bits = self._rgb(im)
- imagecmd = "false 3 colorimage"
-
- return h, w, bits, imagecmd
-
- def draw_image(self, gc, x, y, im, transform=None):
- """
- Draw the Image instance into the current axes; x is the
- distance in pixels from the left hand side of the canvas and y
- is the distance from bottom
- """
-
- h, w, bits, imagecmd = self._get_image_h_w_bits_command(im)
- hexlines = b'\n'.join(self._hex_lines(bits)).decode('ascii')
-
- if transform is None:
- matrix = "1 0 0 1 0 0"
- xscale = w / self.image_magnification
- yscale = h / self.image_magnification
- else:
- matrix = " ".join(map(str, transform.frozen().to_values()))
- xscale = 1.0
- yscale = 1.0
-
- figh = self.height * 72
-
- bbox = gc.get_clip_rectangle()
- clippath, clippath_trans = gc.get_clip_path()
-
- clip = []
- if bbox is not None:
- clipx,clipy,clipw,cliph = bbox.bounds
- clip.append('%s clipbox' % _nums_to_str(clipw, cliph, clipx, clipy))
- if clippath is not None:
- id = self._get_clip_path(clippath, clippath_trans)
- clip.append('%s' % id)
- clip = '\n'.join(clip)
-
- ps = """gsave
-%(clip)s
-%(x)s %(y)s translate
-[%(matrix)s] concat
-%(xscale)s %(yscale)s scale
-/DataString %(w)s string def
-%(w)s %(h)s 8 [ %(w)s 0 0 -%(h)s 0 %(h)s ]
-{
-currentfile DataString readhexstring pop
-} bind %(imagecmd)s
-%(hexlines)s
-grestore
-""" % locals()
- self._pswriter.write(ps)
-
- def _convert_path(self, path, transform, clip=False, simplify=None):
- if clip:
- clip = (0.0, 0.0, self.width * 72.0,
- self.height * 72.0)
- else:
- clip = None
- return _path.convert_to_string(
- path, transform, clip, simplify, None,
- 6, [b'm', b'l', b'', b'c', b'cl'], True).decode('ascii')
-
- def _get_clip_path(self, clippath, clippath_transform):
- key = (clippath, id(clippath_transform))
- pid = self._clip_paths.get(key)
- if pid is None:
- pid = 'c%x' % len(self._clip_paths)
- ps_cmd = ['/%s {' % pid]
- ps_cmd.append(self._convert_path(clippath, clippath_transform,
- simplify=False))
- ps_cmd.extend(['clip', 'newpath', '} bind def\n'])
- self._pswriter.write('\n'.join(ps_cmd))
- self._clip_paths[key] = pid
- return pid
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- """
- Draws a Path instance using the given affine transform.
- """
- clip = rgbFace is None and gc.get_hatch_path() is None
- simplify = path.should_simplify and clip
- ps = self._convert_path(path, transform, clip=clip, simplify=simplify)
- self._draw_ps(ps, gc, rgbFace)
-
- def draw_markers(
- self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
- """
- Draw the markers defined by path at each of the positions in x
- and y. path coordinates are points, x and y coords will be
- transformed by the transform
- """
- if debugPS: self._pswriter.write('% draw_markers \n')
-
- if rgbFace:
- if len(rgbFace) == 4 and rgbFace[3] == 0:
- ps_color = None
- else:
- if rgbFace[0] == rgbFace[1] == rgbFace[2]:
- ps_color = '%1.3f setgray' % rgbFace[0]
- else:
- ps_color = '%1.3f %1.3f %1.3f setrgbcolor' % rgbFace[:3]
-
- # construct the generic marker command:
- ps_cmd = ['/o {', 'gsave', 'newpath', 'translate'] # don't want the translate to be global
-
- lw = gc.get_linewidth()
- alpha = (gc.get_alpha()
- if gc.get_forced_alpha() or len(gc.get_rgb()) == 3
- else gc.get_rgb()[3])
- stroke = lw > 0 and alpha > 0
- if stroke:
- ps_cmd.append('%.1f setlinewidth' % lw)
- jint = gc.get_joinstyle()
- ps_cmd.append('%d setlinejoin' % jint)
- cint = gc.get_capstyle()
- ps_cmd.append('%d setlinecap' % cint)
-
- ps_cmd.append(self._convert_path(marker_path, marker_trans,
- simplify=False))
-
- if rgbFace:
- if stroke:
- ps_cmd.append('gsave')
- if ps_color:
- ps_cmd.extend([ps_color, 'fill'])
- if stroke:
- ps_cmd.append('grestore')
-
- if stroke:
- ps_cmd.append('stroke')
- ps_cmd.extend(['grestore', '} bind def'])
-
- for vertices, code in path.iter_segments(
- trans,
- clip=(0, 0, self.width*72, self.height*72),
- simplify=False):
- if len(vertices):
- x, y = vertices[-2:]
- ps_cmd.append("%g %g o" % (x, y))
-
- ps = '\n'.join(ps_cmd)
- self._draw_ps(ps, gc, rgbFace, fill=False, stroke=False)
-
- def draw_path_collection(self, gc, master_transform, paths, all_transforms,
- offsets, offsetTrans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position):
- # Is the optimization worth it? Rough calculation:
- # cost of emitting a path in-line is
- # (len_path + 2) * uses_per_path
- # cost of definition+use is
- # (len_path + 3) + 3 * uses_per_path
- len_path = len(paths[0].vertices) if len(paths) > 0 else 0
- uses_per_path = self._iter_collection_uses_per_path(
- paths, all_transforms, offsets, facecolors, edgecolors)
- should_do_optimization = \
- len_path + 3 * uses_per_path + 3 < (len_path + 2) * uses_per_path
- if not should_do_optimization:
- return RendererBase.draw_path_collection(
- self, gc, master_transform, paths, all_transforms,
- offsets, offsetTrans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position)
-
- write = self._pswriter.write
-
- path_codes = []
- for i, (path, transform) in enumerate(self._iter_collection_raw_paths(
- master_transform, paths, all_transforms)):
- name = 'p%x_%x' % (self._path_collection_id, i)
- ps_cmd = ['/%s {' % name,
- 'newpath', 'translate']
- ps_cmd.append(self._convert_path(path, transform, simplify=False))
- ps_cmd.extend(['} bind def\n'])
- write('\n'.join(ps_cmd))
- path_codes.append(name)
-
- for xo, yo, path_id, gc0, rgbFace in self._iter_collection(
- gc, master_transform, all_transforms, path_codes, offsets,
- offsetTrans, facecolors, edgecolors, linewidths, linestyles,
- antialiaseds, urls, offset_position):
- ps = "%g %g %s" % (xo, yo, path_id)
- self._draw_ps(ps, gc0, rgbFace)
-
- self._path_collection_id += 1
-
- def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
- """
- draw a Text instance
- """
- w, h, bl = self.get_text_width_height_descent(s, prop, ismath)
- fontsize = prop.get_size_in_points()
- thetext = 'psmarker%d' % self.textcnt
- color = '%1.3f,%1.3f,%1.3f'% gc.get_rgb()[:3]
- fontcmd = {'sans-serif' : r'{\sffamily %s}',
- 'monospace' : r'{\ttfamily %s}'}.get(
- rcParams['font.family'][0], r'{\rmfamily %s}')
- s = fontcmd % s
- tex = r'\color[rgb]{%s} %s' % (color, s)
-
- corr = 0#w/2*(fontsize-10)/10
- if rcParams['text.latex.preview']:
- # use baseline alignment!
- pos = _nums_to_str(x-corr, y)
- self.psfrag.append(r'\psfrag{%s}[Bl][Bl][1][%f]{\fontsize{%f}{%f}%s}'%(thetext, angle, fontsize, fontsize*1.25, tex))
- else:
- # stick to the bottom alignment, but this may give incorrect baseline some times.
- pos = _nums_to_str(x-corr, y-bl)
- self.psfrag.append(r'\psfrag{%s}[bl][bl][1][%f]{\fontsize{%f}{%f}%s}'%(thetext, angle, fontsize, fontsize*1.25, tex))
-
- ps = """\
-gsave
-%(pos)s moveto
-(%(thetext)s)
-show
-grestore
- """ % locals()
-
- self._pswriter.write(ps)
- self.textcnt += 1
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- """
- Draw a Text instance.
- """
- # local to avoid repeated attribute lookups
- write = self._pswriter.write
- if debugPS:
- write("% text\n")
-
- if len(gc.get_rgb()) == 4 and gc.get_rgb()[3] == 0:
- return # Special handling for fully transparent.
-
- if ismath=='TeX':
- return self.draw_tex(gc, x, y, s, prop, angle)
-
- elif ismath:
- return self.draw_mathtext(gc, x, y, s, prop, angle)
-
- elif rcParams['ps.useafm']:
- self.set_color(*gc.get_rgb())
-
- font = self._get_font_afm(prop)
- fontname = font.get_fontname()
- fontsize = prop.get_size_in_points()
- scale = 0.001*fontsize
-
- thisx = 0
- thisy = font.get_str_bbox_and_descent(s)[4] * scale
- last_name = None
- lines = []
- for c in s:
- name = uni2type1.get(ord(c), 'question')
- try:
- width = font.get_width_from_char_name(name)
- except KeyError:
- name = 'question'
- width = font.get_width_char('?')
- if last_name is not None:
- kern = font.get_kern_dist_from_name(last_name, name)
- else:
- kern = 0
- last_name = name
- thisx += kern * scale
-
- lines.append('%f %f m /%s glyphshow'%(thisx, thisy, name))
-
- thisx += width * scale
-
- thetext = "\n".join(lines)
- ps = """\
-gsave
-/%(fontname)s findfont
-%(fontsize)s scalefont
-setfont
-%(x)f %(y)f translate
-%(angle)f rotate
-%(thetext)s
-grestore
- """ % locals()
- self._pswriter.write(ps)
-
- else:
- font = self._get_font_ttf(prop)
- font.set_text(s, 0, flags=LOAD_NO_HINTING)
- self.track_characters(font, s)
-
- self.set_color(*gc.get_rgb())
- sfnt = font.get_sfnt()
- try:
- ps_name = sfnt[1, 0, 0, 6].decode('mac_roman')
- except KeyError:
- ps_name = sfnt[3, 1, 0x0409, 6].decode('utf-16be')
- ps_name = ps_name.encode('ascii', 'replace').decode('ascii')
- self.set_font(ps_name, prop.get_size_in_points())
-
- lastgind = None
- lines = []
- thisx = 0
- thisy = 0
- for c in s:
- ccode = ord(c)
- gind = font.get_char_index(ccode)
- if gind is None:
- ccode = ord('?')
- name = '.notdef'
- gind = 0
- else:
- name = font.get_glyph_name(gind)
- glyph = font.load_char(ccode, flags=LOAD_NO_HINTING)
-
- if lastgind is not None:
- kern = font.get_kerning(lastgind, gind, KERNING_DEFAULT)
- else:
- kern = 0
- lastgind = gind
- thisx += kern/64.0
-
- lines.append('%f %f m /%s glyphshow'%(thisx, thisy, name))
- thisx += glyph.linearHoriAdvance/65536.0
-
-
- thetext = '\n'.join(lines)
- ps = """gsave
-%(x)f %(y)f translate
-%(angle)f rotate
-%(thetext)s
-grestore
-""" % locals()
- self._pswriter.write(ps)
-
- def new_gc(self):
- return GraphicsContextPS()
-
- def draw_mathtext(self, gc,
- x, y, s, prop, angle):
- """
- Draw the math text using matplotlib.mathtext
- """
- if debugPS:
- self._pswriter.write("% mathtext\n")
-
- width, height, descent, pswriter, used_characters = \
- self.mathtext_parser.parse(s, 72, prop)
- self.merge_used_characters(used_characters)
- self.set_color(*gc.get_rgb())
- thetext = pswriter.getvalue()
- ps = """gsave
-%(x)f %(y)f translate
-%(angle)f rotate
-%(thetext)s
-grestore
-""" % locals()
- self._pswriter.write(ps)
-
- def draw_gouraud_triangle(self, gc, points, colors, trans):
- self.draw_gouraud_triangles(gc, points.reshape((1, 3, 2)),
- colors.reshape((1, 3, 4)), trans)
-
- def draw_gouraud_triangles(self, gc, points, colors, trans):
- assert len(points) == len(colors)
- assert points.ndim == 3
- assert points.shape[1] == 3
- assert points.shape[2] == 2
- assert colors.ndim == 3
- assert colors.shape[1] == 3
- assert colors.shape[2] == 4
-
- shape = points.shape
- flat_points = points.reshape((shape[0] * shape[1], 2))
- flat_points = trans.transform(flat_points)
- flat_colors = colors.reshape((shape[0] * shape[1], 4))
- points_min = np.min(flat_points, axis=0) - (1 << 12)
- points_max = np.max(flat_points, axis=0) + (1 << 12)
- factor = np.ceil((2 ** 32 - 1) / (points_max - points_min))
-
- xmin, ymin = points_min
- xmax, ymax = points_max
-
- streamarr = np.empty(
- (shape[0] * shape[1],),
- dtype=[('flags', 'u1'),
- ('points', '>u4', (2,)),
- ('colors', 'u1', (3,))])
- streamarr['flags'] = 0
- streamarr['points'] = (flat_points - points_min) * factor
- streamarr['colors'] = flat_colors[:, :3] * 255.0
-
- stream = quote_ps_string(streamarr.tostring())
-
- self._pswriter.write("""
-gsave
-<< /ShadingType 4
- /ColorSpace [/DeviceRGB]
- /BitsPerCoordinate 32
- /BitsPerComponent 8
- /BitsPerFlag 8
- /AntiAlias true
- /Decode [ %(xmin)f %(xmax)f %(ymin)f %(ymax)f 0 1 0 1 0 1 ]
- /DataSource (%(stream)s)
->>
-shfill
-grestore
-""" % locals())
-
- def _draw_ps(self, ps, gc, rgbFace, fill=True, stroke=True, command=None):
- """
- Emit the PostScript sniplet 'ps' with all the attributes from 'gc'
- applied. 'ps' must consist of PostScript commands to construct a path.
-
- The fill and/or stroke kwargs can be set to False if the
- 'ps' string already includes filling and/or stroking, in
- which case _draw_ps is just supplying properties and
- clipping.
- """
- # local variable eliminates all repeated attribute lookups
- write = self._pswriter.write
- if debugPS and command:
- write("% "+command+"\n")
- mightstroke = gc.shouldstroke()
- stroke = stroke and mightstroke
- fill = (fill and rgbFace is not None and
- (len(rgbFace) <= 3 or rgbFace[3] != 0.0))
- hatch = gc.get_hatch()
-
- if mightstroke:
- self.set_linewidth(gc.get_linewidth())
- jint = gc.get_joinstyle()
- self.set_linejoin(jint)
- cint = gc.get_capstyle()
- self.set_linecap(cint)
- self.set_linedash(*gc.get_dashes())
- self.set_color(*gc.get_rgb()[:3])
- write('gsave\n')
-
- cliprect = gc.get_clip_rectangle()
- if cliprect:
- x,y,w,h=cliprect.bounds
- write('%1.4g %1.4g %1.4g %1.4g clipbox\n' % (w,h,x,y))
- clippath, clippath_trans = gc.get_clip_path()
- if clippath:
- id = self._get_clip_path(clippath, clippath_trans)
- write('%s\n' % id)
-
- # Jochen, is the strip necessary? - this could be a honking big string
- write(ps.strip())
- write("\n")
-
- if fill:
- if stroke or hatch:
- write("gsave\n")
- self.set_color(store=0, *rgbFace[:3])
- write("fill\n")
- if stroke or hatch:
- write("grestore\n")
-
- if hatch:
- hatch_name = self.create_hatch(hatch)
- write("gsave\n")
- write("%f %f %f " % gc.get_hatch_color()[:3])
- write("%s setpattern fill grestore\n" % hatch_name)
-
- if stroke:
- write("stroke\n")
-
- write("grestore\n")
-
-
-class GraphicsContextPS(GraphicsContextBase):
- def get_capstyle(self):
- return {'butt':0,
- 'round':1,
- 'projecting':2}[GraphicsContextBase.get_capstyle(self)]
-
- def get_joinstyle(self):
- return {'miter':0,
- 'round':1,
- 'bevel':2}[GraphicsContextBase.get_joinstyle(self)]
-
- def shouldstroke(self):
- return (self.get_linewidth() > 0.0 and
- (len(self.get_rgb()) <= 3 or self.get_rgb()[3] != 0.0))
-
-
-class FigureCanvasPS(FigureCanvasBase):
- _renderer_class = RendererPS
-
- fixed_dpi = 72
-
- def draw(self):
- pass
-
- filetypes = {'ps' : 'Postscript',
- 'eps' : 'Encapsulated Postscript'}
-
- def get_default_filetype(self):
- return 'ps'
-
- def print_ps(self, outfile, *args, **kwargs):
- return self._print_ps(outfile, 'ps', *args, **kwargs)
-
- def print_eps(self, outfile, *args, **kwargs):
- return self._print_ps(outfile, 'eps', *args, **kwargs)
-
- def _print_ps(self, outfile, format, *args, **kwargs):
- papertype = kwargs.pop("papertype", rcParams['ps.papersize'])
- papertype = papertype.lower()
- if papertype == 'auto':
- pass
- elif papertype not in papersize:
- raise RuntimeError('%s is not a valid papertype. Use one of %s' %
- (papertype, ', '.join(papersize)))
-
- orientation = kwargs.pop("orientation", "portrait").lower()
- if orientation == 'landscape': isLandscape = True
- elif orientation == 'portrait': isLandscape = False
- else: raise RuntimeError('Orientation must be "portrait" or "landscape"')
-
- self.figure.set_dpi(72) # Override the dpi kwarg
- imagedpi = kwargs.pop("dpi", 72)
- facecolor = kwargs.pop("facecolor", "w")
- edgecolor = kwargs.pop("edgecolor", "w")
-
- if rcParams['text.usetex']:
- self._print_figure_tex(outfile, format, imagedpi, facecolor, edgecolor,
- orientation, isLandscape, papertype,
- **kwargs)
- else:
- self._print_figure(outfile, format, imagedpi, facecolor, edgecolor,
- orientation, isLandscape, papertype,
- **kwargs)
-
- def _print_figure(self, outfile, format, dpi=72, facecolor='w', edgecolor='w',
- orientation='portrait', isLandscape=False, papertype=None,
- metadata=None, **kwargs):
- """
- Render the figure to hardcopy. Set the figure patch face and
- edge colors. This is useful because some of the GUIs have a
- gray figure face color background and you'll probably want to
- override this on hardcopy
-
- If outfile is a string, it is interpreted as a file name.
- If the extension matches .ep* write encapsulated postscript,
- otherwise write a stand-alone PostScript file.
-
- If outfile is a file object, a stand-alone PostScript file is
- written into this file object.
-
- metadata must be a dictionary. Currently, only the value for
- the key 'Creator' is used.
- """
- isEPSF = format == 'eps'
- if isinstance(outfile,
- (six.string_types, getattr(os, "PathLike", ()),)):
- outfile = title = getattr(os, "fspath", lambda obj: obj)(outfile)
- passed_in_file_object = False
- elif is_writable_file_like(outfile):
- title = None
- passed_in_file_object = True
- else:
- raise ValueError("outfile must be a path or a file-like object")
-
- # find the appropriate papertype
- width, height = self.figure.get_size_inches()
- if papertype == 'auto':
- if isLandscape: papertype = _get_papertype(height, width)
- else: papertype = _get_papertype(width, height)
-
- if isLandscape: paperHeight, paperWidth = papersize[papertype]
- else: paperWidth, paperHeight = papersize[papertype]
-
- if rcParams['ps.usedistiller'] and not papertype == 'auto':
- # distillers will improperly clip eps files if the pagesize is
- # too small
- if width>paperWidth or height>paperHeight:
- if isLandscape:
- papertype = _get_papertype(height, width)
- paperHeight, paperWidth = papersize[papertype]
- else:
- papertype = _get_papertype(width, height)
- paperWidth, paperHeight = papersize[papertype]
-
- # center the figure on the paper
- xo = 72*0.5*(paperWidth - width)
- yo = 72*0.5*(paperHeight - height)
-
- l, b, w, h = self.figure.bbox.bounds
- llx = xo
- lly = yo
- urx = llx + w
- ury = lly + h
- rotation = 0
- if isLandscape:
- llx, lly, urx, ury = lly, llx, ury, urx
- xo, yo = 72*paperHeight - yo, xo
- rotation = 90
- bbox = (llx, lly, urx, ury)
-
- # generate PostScript code for the figure and store it in a string
- origfacecolor = self.figure.get_facecolor()
- origedgecolor = self.figure.get_edgecolor()
- self.figure.set_facecolor(facecolor)
- self.figure.set_edgecolor(edgecolor)
-
-
- dryrun = kwargs.get("dryrun", False)
- if dryrun:
- class NullWriter(object):
- def write(self, *kl, **kwargs):
- pass
-
- self._pswriter = NullWriter()
- else:
- self._pswriter = io.StringIO()
-
-
- # mixed mode rendering
- _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None)
- ps_renderer = self._renderer_class(width, height, self._pswriter,
- imagedpi=dpi)
- renderer = MixedModeRenderer(self.figure,
- width, height, dpi, ps_renderer,
- bbox_inches_restore=_bbox_inches_restore)
-
- self.figure.draw(renderer)
-
- if dryrun: # return immediately if dryrun (tightbbox=True)
- return
-
- self.figure.set_facecolor(origfacecolor)
- self.figure.set_edgecolor(origedgecolor)
-
- # check for custom metadata
- if metadata is not None and 'Creator' in metadata:
- creator_str = metadata['Creator']
- else:
- creator_str = "matplotlib version " + __version__ + \
- ", http://matplotlib.org/"
-
- def print_figure_impl(fh):
- # write the PostScript headers
- if isEPSF:
- print("%!PS-Adobe-3.0 EPSF-3.0", file=fh)
- else:
- print("%!PS-Adobe-3.0", file=fh)
- if title:
- print("%%Title: "+title, file=fh)
- print("%%Creator: " + creator_str, file=fh)
- # get source date from SOURCE_DATE_EPOCH, if set
- # See https://reproducible-builds.org/specs/source-date-epoch/
- source_date_epoch = os.getenv("SOURCE_DATE_EPOCH")
- if source_date_epoch:
- source_date = datetime.datetime.utcfromtimestamp(
- int(source_date_epoch)).strftime("%a %b %d %H:%M:%S %Y")
- else:
- source_date = time.ctime()
- print("%%CreationDate: "+source_date, file=fh)
- print("%%Orientation: " + orientation, file=fh)
- if not isEPSF:
- print("%%DocumentPaperSizes: "+papertype, file=fh)
- print("%%%%BoundingBox: %d %d %d %d" % bbox, file=fh)
- if not isEPSF:
- print("%%Pages: 1", file=fh)
- print("%%EndComments", file=fh)
-
- Ndict = len(psDefs)
- print("%%BeginProlog", file=fh)
- if not rcParams['ps.useafm']:
- Ndict += len(ps_renderer.used_characters)
- print("/mpldict %d dict def" % Ndict, file=fh)
- print("mpldict begin", file=fh)
- for d in psDefs:
- d = d.strip()
- for l in d.split('\n'):
- print(l.strip(), file=fh)
- if not rcParams['ps.useafm']:
- for font_filename, chars in six.itervalues(
- ps_renderer.used_characters):
- if len(chars):
- font = get_font(font_filename)
- glyph_ids = []
- for c in chars:
- gind = font.get_char_index(c)
- glyph_ids.append(gind)
-
- fonttype = rcParams['ps.fonttype']
-
- # Can not use more than 255 characters from a
- # single font for Type 3
- if len(glyph_ids) > 255:
- fonttype = 42
-
- # The ttf to ps (subsetting) support doesn't work for
- # OpenType fonts that are Postscript inside (like the
- # STIX fonts). This will simply turn that off to avoid
- # errors.
- if is_opentype_cff_font(font_filename):
- raise RuntimeError(
- "OpenType CFF fonts can not be saved using "
- "the internal Postscript backend at this "
- "time; consider using the Cairo backend")
- else:
- fh.flush()
- convert_ttf_to_ps(
- font_filename.encode(
- sys.getfilesystemencoding()),
- fh, fonttype, glyph_ids)
- print("end", file=fh)
- print("%%EndProlog", file=fh)
-
- if not isEPSF:
- print("%%Page: 1 1", file=fh)
- print("mpldict begin", file=fh)
-
- print("%s translate" % _nums_to_str(xo, yo), file=fh)
- if rotation:
- print("%d rotate" % rotation, file=fh)
- print("%s clipbox" % _nums_to_str(width*72, height*72, 0, 0),
- file=fh)
-
- # write the figure
- content = self._pswriter.getvalue()
- if not isinstance(content, six.text_type):
- content = content.decode('ascii')
- print(content, file=fh)
-
- # write the trailer
- print("end", file=fh)
- print("showpage", file=fh)
- if not isEPSF:
- print("%%EOF", file=fh)
- fh.flush()
-
- if rcParams['ps.usedistiller']:
- # We are going to use an external program to process the output.
- # Write to a temporary file.
- fd, tmpfile = mkstemp()
- try:
- with io.open(fd, 'w', encoding='latin-1') as fh:
- print_figure_impl(fh)
- if rcParams['ps.usedistiller'] == 'ghostscript':
- gs_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox)
- elif rcParams['ps.usedistiller'] == 'xpdf':
- xpdf_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox)
-
- _move_path_to_path_or_stream(tmpfile, outfile)
- finally:
- if os.path.isfile(tmpfile):
- os.unlink(tmpfile)
-
- else:
- # Write directly to outfile.
- if passed_in_file_object:
- requires_unicode = file_requires_unicode(outfile)
-
- if (not requires_unicode and
- (six.PY3 or not isinstance(outfile, StringIO))):
- fh = io.TextIOWrapper(outfile, encoding="latin-1")
-
- # Prevent the io.TextIOWrapper from closing the
- # underlying file
- def do_nothing():
- pass
- fh.close = do_nothing
- else:
- fh = outfile
-
- print_figure_impl(fh)
- else:
- with io.open(outfile, 'w', encoding='latin-1') as fh:
- print_figure_impl(fh)
-
- def _print_figure_tex(self, outfile, format, dpi, facecolor, edgecolor,
- orientation, isLandscape, papertype, metadata=None,
- **kwargs):
- """
- If text.usetex is True in rc, a temporary pair of tex/eps files
- are created to allow tex to manage the text layout via the PSFrags
- package. These files are processed to yield the final ps or eps file.
-
- metadata must be a dictionary. Currently, only the value for
- the key 'Creator' is used.
- """
- isEPSF = format == 'eps'
- if isinstance(outfile, six.string_types):
- title = outfile
- elif is_writable_file_like(outfile):
- title = None
- else:
- raise ValueError("outfile must be a path or a file-like object")
-
- self.figure.dpi = 72 # ignore the dpi kwarg
- width, height = self.figure.get_size_inches()
- xo = 0
- yo = 0
-
- l, b, w, h = self.figure.bbox.bounds
- llx = xo
- lly = yo
- urx = llx + w
- ury = lly + h
- bbox = (llx, lly, urx, ury)
-
- # generate PostScript code for the figure and store it in a string
- origfacecolor = self.figure.get_facecolor()
- origedgecolor = self.figure.get_edgecolor()
- self.figure.set_facecolor(facecolor)
- self.figure.set_edgecolor(edgecolor)
-
- dryrun = kwargs.get("dryrun", False)
- if dryrun:
- class NullWriter(object):
- def write(self, *kl, **kwargs):
- pass
-
- self._pswriter = NullWriter()
- else:
- self._pswriter = io.StringIO()
-
- # mixed mode rendering
- _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None)
- ps_renderer = self._renderer_class(width, height,
- self._pswriter, imagedpi=dpi)
- renderer = MixedModeRenderer(self.figure,
- width, height, dpi, ps_renderer,
- bbox_inches_restore=_bbox_inches_restore)
-
- self.figure.draw(renderer)
-
- if dryrun: # return immediately if dryrun (tightbbox=True)
- return
-
- self.figure.set_facecolor(origfacecolor)
- self.figure.set_edgecolor(origedgecolor)
-
- # check for custom metadata
- if metadata is not None and 'Creator' in metadata:
- creator_str = metadata['Creator']
- else:
- creator_str = "matplotlib version " + __version__ + \
- ", http://matplotlib.org/"
-
- # write to a temp file, we'll move it to outfile when done
-
- fd, tmpfile = mkstemp()
- try:
- with io.open(fd, 'w', encoding='latin-1') as fh:
- # write the Encapsulated PostScript headers
- print("%!PS-Adobe-3.0 EPSF-3.0", file=fh)
- if title:
- print("%%Title: "+title, file=fh)
- print("%%Creator: " + creator_str, file=fh)
- # get source date from SOURCE_DATE_EPOCH, if set
- # See https://reproducible-builds.org/specs/source-date-epoch/
- source_date_epoch = os.getenv("SOURCE_DATE_EPOCH")
- if source_date_epoch:
- source_date = datetime.datetime.utcfromtimestamp(
- int(source_date_epoch)).strftime(
- "%a %b %d %H:%M:%S %Y")
- else:
- source_date = time.ctime()
- print("%%CreationDate: "+source_date, file=fh)
- print("%%%%BoundingBox: %d %d %d %d" % bbox, file=fh)
- print("%%EndComments", file=fh)
-
- Ndict = len(psDefs)
- print("%%BeginProlog", file=fh)
- print("/mpldict %d dict def" % Ndict, file=fh)
- print("mpldict begin", file=fh)
- for d in psDefs:
- d = d.strip()
- for l in d.split('\n'):
- print(l.strip(), file=fh)
- print("end", file=fh)
- print("%%EndProlog", file=fh)
-
- print("mpldict begin", file=fh)
- print("%s translate" % _nums_to_str(xo, yo), file=fh)
- print("%s clipbox" % _nums_to_str(width*72, height*72, 0, 0),
- file=fh)
-
- # write the figure
- print(self._pswriter.getvalue(), file=fh)
-
- # write the trailer
- print("end", file=fh)
- print("showpage", file=fh)
- fh.flush()
-
- if isLandscape: # now we are ready to rotate
- isLandscape = True
- width, height = height, width
- bbox = (lly, llx, ury, urx)
-
- # set the paper size to the figure size if isEPSF. The
- # resulting ps file has the given size with correct bounding
- # box so that there is no need to call 'pstoeps'
- if isEPSF:
- paperWidth, paperHeight = self.figure.get_size_inches()
- if isLandscape:
- paperWidth, paperHeight = paperHeight, paperWidth
- else:
- temp_papertype = _get_papertype(width, height)
- if papertype == 'auto':
- papertype = temp_papertype
- paperWidth, paperHeight = papersize[temp_papertype]
- else:
- paperWidth, paperHeight = papersize[papertype]
- if (width > paperWidth or height > paperHeight) and isEPSF:
- paperWidth, paperHeight = papersize[temp_papertype]
- _log.info('Your figure is too big to fit on %s paper. '
- '%s paper will be used to prevent clipping.',
- papertype, temp_papertype)
-
- texmanager = ps_renderer.get_texmanager()
- font_preamble = texmanager.get_font_preamble()
- custom_preamble = texmanager.get_custom_preamble()
-
- psfrag_rotated = convert_psfrags(tmpfile, ps_renderer.psfrag,
- font_preamble,
- custom_preamble, paperWidth,
- paperHeight,
- orientation)
-
- if (rcParams['ps.usedistiller'] == 'ghostscript'
- or rcParams['text.usetex']):
- gs_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox,
- rotated=psfrag_rotated)
- elif rcParams['ps.usedistiller'] == 'xpdf':
- xpdf_distill(tmpfile, isEPSF, ptype=papertype, bbox=bbox,
- rotated=psfrag_rotated)
-
- _move_path_to_path_or_stream(tmpfile, outfile)
- finally:
- if os.path.isfile(tmpfile):
- os.unlink(tmpfile)
-
-
-def convert_psfrags(tmpfile, psfrags, font_preamble, custom_preamble,
- paperWidth, paperHeight, orientation):
- """
- When we want to use the LaTeX backend with postscript, we write PSFrag tags
- to a temporary postscript file, each one marking a position for LaTeX to
- render some text. convert_psfrags generates a LaTeX document containing the
- commands to convert those tags to text. LaTeX/dvips produces the postscript
- file that includes the actual text.
- """
- tmpdir = os.path.split(tmpfile)[0]
- epsfile = tmpfile+'.eps'
- shutil.move(tmpfile, epsfile)
- latexfile = tmpfile+'.tex'
- dvifile = tmpfile+'.dvi'
- psfile = tmpfile+'.ps'
-
- if orientation == 'landscape':
- angle = 90
- else:
- angle = 0
-
- if rcParams['text.latex.unicode']:
- unicode_preamble = """\\usepackage{ucs}
-\\usepackage[utf8x]{inputenc}"""
- else:
- unicode_preamble = ''
-
- s = """\\documentclass{article}
-%s
-%s
-%s
-\\usepackage[dvips, papersize={%sin,%sin}, body={%sin,%sin}, margin={0in,0in}]{geometry}
-\\usepackage{psfrag}
-\\usepackage[dvips]{graphicx}
-\\usepackage{color}
-\\pagestyle{empty}
-\\begin{document}
-\\begin{figure}
-\\centering
-\\leavevmode
-%s
-\\includegraphics*[angle=%s]{%s}
-\\end{figure}
-\\end{document}
-"""% (font_preamble, unicode_preamble, custom_preamble, paperWidth, paperHeight,
- paperWidth, paperHeight,
- '\n'.join(psfrags), angle, os.path.split(epsfile)[-1])
-
- with io.open(latexfile, 'wb') as latexh:
- if rcParams['text.latex.unicode']:
- latexh.write(s.encode('utf8'))
- else:
- try:
- latexh.write(s.encode('ascii'))
- except UnicodeEncodeError:
- _log.info("You are using unicode and latex, but have "
- "not enabled the matplotlib 'text.latex.unicode' "
- "rcParam.")
- raise
-
- # Replace \\ for / so latex does not think there is a function call
- latexfile = latexfile.replace("\\", "/")
- # Replace ~ so Latex does not think it is line break
- latexfile = latexfile.replace("~", "\\string~")
- command = [str("latex"), "-interaction=nonstopmode",
- '"%s"' % latexfile]
- _log.debug('%s', command)
- try:
- report = subprocess.check_output(command, cwd=tmpdir,
- stderr=subprocess.STDOUT)
- except subprocess.CalledProcessError as exc:
- raise RuntimeError(
- ('LaTeX was not able to process the following '
- 'file:\n%s\n\n'
- 'Here is the full report generated by LaTeX:\n%s '
- '\n\n' % (latexfile,
- exc.output.decode("utf-8"))))
- _log.debug(report)
-
- command = [str('dvips'), '-q', '-R0', '-o', os.path.basename(psfile),
- os.path.basename(dvifile)]
- _log.debug(command)
- try:
- report = subprocess.check_output(command, cwd=tmpdir,
- stderr=subprocess.STDOUT)
- except subprocess.CalledProcessError as exc:
- raise RuntimeError(
- ('dvips was not able to process the following '
- 'file:\n%s\n\n'
- 'Here is the full report generated by dvips:\n%s '
- '\n\n' % (dvifile,
- exc.output.decode("utf-8"))))
- _log.debug(report)
- os.remove(epsfile)
- shutil.move(psfile, tmpfile)
-
- # check if the dvips created a ps in landscape paper. Somehow,
- # above latex+dvips results in a ps file in a landscape mode for a
- # certain figure sizes (e.g., 8.3in,5.8in which is a5). And the
- # bounding box of the final output got messed up. We check see if
- # the generated ps file is in landscape and return this
- # information. The return value is used in pstoeps step to recover
- # the correct bounding box. 2010-06-05 JJL
- with io.open(tmpfile) as fh:
- if "Landscape" in fh.read(1000):
- psfrag_rotated = True
- else:
- psfrag_rotated = False
-
- if not debugPS:
- for fname in glob.glob(tmpfile+'.*'):
- os.remove(fname)
-
- return psfrag_rotated
-
-
-def gs_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False):
- """
- Use ghostscript's pswrite or epswrite device to distill a file.
- This yields smaller files without illegal encapsulated postscript
- operators. The output is low-level, converting text to outlines.
- """
-
- if eps:
- paper_option = "-dEPSCrop"
- else:
- paper_option = "-sPAPERSIZE=%s" % ptype
-
- psfile = tmpfile + '.ps'
- dpi = rcParams['ps.distiller.res']
-
- gs_exe = ps_backend_helper.gs_exe
- if ps_backend_helper.supports_ps2write: # gs version >= 9
- device_name = "ps2write"
- else:
- device_name = "pswrite"
-
- command = [str(gs_exe), "-dBATCH", "-dNOPAUSE", "-r%d" % dpi,
- "-sDEVICE=%s" % device_name, paper_option,
- "-sOutputFile=%s" % psfile, tmpfile]
- _log.debug(command)
- try:
- report = subprocess.check_output(command, stderr=subprocess.STDOUT)
- except subprocess.CalledProcessError as exc:
- raise RuntimeError(
- ('ghostscript was not able to process your image.\n'
- 'Here is the full report generated by ghostscript:\n%s '
- '\n\n' % exc.output.decode("utf-8")))
- _log.debug(report)
- os.remove(tmpfile)
- shutil.move(psfile, tmpfile)
-
-
- # While it is best if above steps preserve the original bounding
- # box, there seem to be cases when it is not. For those cases,
- # the original bbox can be restored during the pstoeps step.
-
- if eps:
- # For some versions of gs, above steps result in an ps file
- # where the original bbox is no more correct. Do not adjust
- # bbox for now.
- if ps_backend_helper.supports_ps2write:
- # fo gs version >= 9 w/ ps2write device
- pstoeps(tmpfile, bbox, rotated=rotated)
- else:
- pstoeps(tmpfile)
-
-
-def xpdf_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False):
- """
- Use ghostscript's ps2pdf and xpdf's/poppler's pdftops to distill a file.
- This yields smaller files without illegal encapsulated postscript
- operators. This distiller is preferred, generating high-level postscript
- output that treats text as text.
- """
- pdffile = tmpfile + '.pdf'
- psfile = tmpfile + '.ps'
-
- # Pass options as `-foo#bar` instead of `-foo=bar` to keep Windows happy
- # (https://www.ghostscript.com/doc/9.22/Use.htm#MS_Windows).
- command = [str("ps2pdf"),
- "-dAutoFilterColorImages#false",
- "-dAutoFilterGrayImages#false",
- "-dAutoRotatePages#false",
- "-sGrayImageFilter#FlateEncode",
- "-sColorImageFilter#FlateEncode",
- "-dEPSCrop" if eps else "-sPAPERSIZE#%s" % ptype,
- tmpfile, pdffile]
- _log.debug(command)
-
- try:
- report = subprocess.check_output(command, stderr=subprocess.STDOUT)
- except subprocess.CalledProcessError as exc:
- raise RuntimeError(
- ('ps2pdf was not able to process your image.\n'
- 'Here is the full report generated by ps2pdf:\n%s '
- '\n\n' % exc.output.decode("utf-8")))
- _log.debug(report)
-
- command = [str("pdftops"), "-paper", "match", "-level2", pdffile, psfile]
- _log.debug(command)
- try:
- report = subprocess.check_output(command, stderr=subprocess.STDOUT)
- except subprocess.CalledProcessError as exc:
- raise RuntimeError(
- ('pdftops was not able to process your image.\n'
- 'Here is the full report generated by pdftops:\n%s '
- '\n\n' % exc.output.decode("utf-8")))
- _log.debug(report)
- os.remove(tmpfile)
- shutil.move(psfile, tmpfile)
-
- if eps:
- pstoeps(tmpfile)
-
- for fname in glob.glob(tmpfile+'.*'):
- os.remove(fname)
-
-
-def get_bbox_header(lbrt, rotated=False):
- """
- return a postscript header stringfor the given bbox lbrt=(l, b, r, t).
- Optionally, return rotate command.
- """
-
- l, b, r, t = lbrt
- if rotated:
- rotate = "%.2f %.2f translate\n90 rotate" % (l+r, 0)
- else:
- rotate = ""
- bbox_info = '%%%%BoundingBox: %d %d %d %d' % (l, b, np.ceil(r), np.ceil(t))
- hires_bbox_info = '%%%%HiResBoundingBox: %.6f %.6f %.6f %.6f' % (l, b, r, t)
-
- return '\n'.join([bbox_info, hires_bbox_info]), rotate
-
-
-# get_bbox is deprecated. I don't see any reason to use ghostscript to
-# find the bounding box, as the required bounding box is alread known.
-def get_bbox(tmpfile, bbox):
- """
- Use ghostscript's bbox device to find the center of the bounding box.
- Return an appropriately sized bbox centered around that point. A bit of a
- hack.
- """
-
- gs_exe = ps_backend_helper.gs_exe
- command = [gs_exe, "-dBATCH", "-dNOPAUSE", "-sDEVICE=bbox", "%s" % tmpfile]
- _log.debug(command)
- p = subprocess.Popen(command, stdin=subprocess.PIPE,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- close_fds=True)
- (stdout, stderr) = (p.stdout, p.stderr)
- _log.debug(stdout.read())
- bbox_info = stderr.read()
- _log.info(bbox_info)
- bbox_found = re.search('%%HiResBoundingBox: .*', bbox_info)
- if bbox_found:
- bbox_info = bbox_found.group()
- else:
- raise RuntimeError('Ghostscript was not able to extract a bounding box.\
-Here is the Ghostscript output:\n\n%s' % bbox_info)
- l, b, r, t = [float(i) for i in bbox_info.split()[-4:]]
-
- # this is a hack to deal with the fact that ghostscript does not return the
- # intended bbox, but a tight bbox. For now, we just center the ink in the
- # intended bbox. This is not ideal, users may intend the ink to not be
- # centered.
- if bbox is None:
- l, b, r, t = (l-1, b-1, r+1, t+1)
- else:
- x = (l+r)/2
- y = (b+t)/2
- dx = (bbox[2]-bbox[0])/2
- dy = (bbox[3]-bbox[1])/2
- l,b,r,t = (x-dx, y-dy, x+dx, y+dy)
-
- bbox_info = '%%%%BoundingBox: %d %d %d %d' % (l, b, np.ceil(r), np.ceil(t))
- hires_bbox_info = '%%%%HiResBoundingBox: %.6f %.6f %.6f %.6f' % (l, b, r, t)
-
- return '\n'.join([bbox_info, hires_bbox_info])
-
-
-def pstoeps(tmpfile, bbox=None, rotated=False):
- """
- Convert the postscript to encapsulated postscript. The bbox of
- the eps file will be replaced with the given *bbox* argument. If
- None, original bbox will be used.
- """
-
- # if rotated==True, the output eps file need to be rotated
- if bbox:
- bbox_info, rotate = get_bbox_header(bbox, rotated=rotated)
- else:
- bbox_info, rotate = None, None
-
- epsfile = tmpfile + '.eps'
- with io.open(epsfile, 'wb') as epsh, io.open(tmpfile, 'rb') as tmph:
- write = epsh.write
- # Modify the header:
- for line in tmph:
- if line.startswith(b'%!PS'):
- write(b"%!PS-Adobe-3.0 EPSF-3.0\n")
- if bbox:
- write(bbox_info.encode('ascii') + b'\n')
- elif line.startswith(b'%%EndComments'):
- write(line)
- write(b'%%BeginProlog\n'
- b'save\n'
- b'countdictstack\n'
- b'mark\n'
- b'newpath\n'
- b'/showpage {} def\n'
- b'/setpagedevice {pop} def\n'
- b'%%EndProlog\n'
- b'%%Page 1 1\n')
- if rotate:
- write(rotate.encode('ascii') + b'\n')
- break
- elif bbox and line.startswith((b'%%Bound', b'%%HiResBound',
- b'%%DocumentMedia', b'%%Pages')):
- pass
- else:
- write(line)
- # Now rewrite the rest of the file, and modify the trailer.
- # This is done in a second loop such that the header of the embedded
- # eps file is not modified.
- for line in tmph:
- if line.startswith(b'%%EOF'):
- write(b'cleartomark\n'
- b'countdictstack\n'
- b'exch sub { end } repeat\n'
- b'restore\n'
- b'showpage\n'
- b'%%EOF\n')
- elif line.startswith(b'%%PageBoundingBox'):
- pass
- else:
- write(line)
-
- os.remove(tmpfile)
- shutil.move(epsfile, tmpfile)
-
-
-class FigureManagerPS(FigureManagerBase):
- pass
-
-
-# The following Python dictionary psDefs contains the entries for the
-# PostScript dictionary mpldict. This dictionary implements most of
-# the matplotlib primitives and some abbreviations.
-#
-# References:
-# http://www.adobe.com/products/postscript/pdfs/PLRM.pdf
-# http://www.mactech.com/articles/mactech/Vol.09/09.04/PostscriptTutorial/
-# http://www.math.ubc.ca/people/faculty/cass/graphics/text/www/
-#
-
-# The usage comments use the notation of the operator summary
-# in the PostScript Language reference manual.
-psDefs = [
- # x y *m* -
- "/m { moveto } bind def",
- # x y *l* -
- "/l { lineto } bind def",
- # x y *r* -
- "/r { rlineto } bind def",
- # x1 y1 x2 y2 x y *c* -
- "/c { curveto } bind def",
- # *closepath* -
- "/cl { closepath } bind def",
- # w h x y *box* -
- """/box {
- m
- 1 index 0 r
- 0 exch r
- neg 0 r
- cl
- } bind def""",
- # w h x y *clipbox* -
- """/clipbox {
- box
- clip
- newpath
- } bind def""",
-]
-
-
-@_Backend.export
-class _BackendPS(_Backend):
- FigureCanvas = FigureCanvasPS
- FigureManager = FigureManagerPS
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt4.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt4.py
deleted file mode 100644
index 92463a6573..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt4.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from .backend_qt5 import (
- backend_version, SPECIAL_KEYS, SUPER, ALT, CTRL, SHIFT, MODIFIER_KEYS,
- cursord, _create_qApp, _BackendQT5, TimerQT, MainWindow, FigureManagerQT,
- NavigationToolbar2QT, SubplotToolQt, error_msg_qt, exception_handler)
-from .backend_qt5 import FigureCanvasQT as FigureCanvasQT5
-
-
-@_BackendQT5.export
-class _BackendQT4(_BackendQT5):
- pass
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt4agg.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt4agg.py
deleted file mode 100644
index 7e90a09bf3..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt4agg.py
+++ /dev/null
@@ -1,15 +0,0 @@
-"""
-Render to qt from agg
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from .backend_qt5agg import (
- _BackendQT5Agg, FigureCanvasQTAgg, FigureManagerQT, NavigationToolbar2QT)
-
-
-@_BackendQT5Agg.export
-class _BackendQT4Agg(_BackendQT5Agg):
- pass
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt4cairo.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt4cairo.py
deleted file mode 100644
index f94851da38..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt4cairo.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from .backend_qt5cairo import _BackendQT5Cairo
-
-
-@_BackendQT5Cairo.export
-class _BackendQT4Cairo(_BackendQT5Cairo):
- pass
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt5.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt5.py
deleted file mode 100644
index 20b0b5bc1b..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt5.py
+++ /dev/null
@@ -1,1119 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-import six
-
-import functools
-import os
-import re
-import signal
-import sys
-from six import unichr
-import traceback
-
-import matplotlib
-
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2,
- TimerBase, cursors, ToolContainerBase, StatusbarBase)
-import matplotlib.backends.qt_editor.figureoptions as figureoptions
-from matplotlib.backends.qt_editor.formsubplottool import UiSubplotTool
-from matplotlib.figure import Figure
-from matplotlib.backend_managers import ToolManager
-from matplotlib import backend_tools
-
-from .qt_compat import (
- QtCore, QtGui, QtWidgets, _getSaveFileName, is_pyqt5, __version__, QT_API)
-
-backend_version = __version__
-
-# SPECIAL_KEYS are keys that do *not* return their unicode name
-# instead they have manually specified names
-SPECIAL_KEYS = {QtCore.Qt.Key_Control: 'control',
- QtCore.Qt.Key_Shift: 'shift',
- QtCore.Qt.Key_Alt: 'alt',
- QtCore.Qt.Key_Meta: 'super',
- QtCore.Qt.Key_Return: 'enter',
- QtCore.Qt.Key_Left: 'left',
- QtCore.Qt.Key_Up: 'up',
- QtCore.Qt.Key_Right: 'right',
- QtCore.Qt.Key_Down: 'down',
- QtCore.Qt.Key_Escape: 'escape',
- QtCore.Qt.Key_F1: 'f1',
- QtCore.Qt.Key_F2: 'f2',
- QtCore.Qt.Key_F3: 'f3',
- QtCore.Qt.Key_F4: 'f4',
- QtCore.Qt.Key_F5: 'f5',
- QtCore.Qt.Key_F6: 'f6',
- QtCore.Qt.Key_F7: 'f7',
- QtCore.Qt.Key_F8: 'f8',
- QtCore.Qt.Key_F9: 'f9',
- QtCore.Qt.Key_F10: 'f10',
- QtCore.Qt.Key_F11: 'f11',
- QtCore.Qt.Key_F12: 'f12',
- QtCore.Qt.Key_Home: 'home',
- QtCore.Qt.Key_End: 'end',
- QtCore.Qt.Key_PageUp: 'pageup',
- QtCore.Qt.Key_PageDown: 'pagedown',
- QtCore.Qt.Key_Tab: 'tab',
- QtCore.Qt.Key_Backspace: 'backspace',
- QtCore.Qt.Key_Enter: 'enter',
- QtCore.Qt.Key_Insert: 'insert',
- QtCore.Qt.Key_Delete: 'delete',
- QtCore.Qt.Key_Pause: 'pause',
- QtCore.Qt.Key_SysReq: 'sysreq',
- QtCore.Qt.Key_Clear: 'clear', }
-
-# define which modifier keys are collected on keyboard events.
-# elements are (mpl names, Modifier Flag, Qt Key) tuples
-SUPER = 0
-ALT = 1
-CTRL = 2
-SHIFT = 3
-MODIFIER_KEYS = [('super', QtCore.Qt.MetaModifier, QtCore.Qt.Key_Meta),
- ('alt', QtCore.Qt.AltModifier, QtCore.Qt.Key_Alt),
- ('ctrl', QtCore.Qt.ControlModifier, QtCore.Qt.Key_Control),
- ('shift', QtCore.Qt.ShiftModifier, QtCore.Qt.Key_Shift),
- ]
-
-if sys.platform == 'darwin':
- # in OSX, the control and super (aka cmd/apple) keys are switched, so
- # switch them back.
- SPECIAL_KEYS.update({QtCore.Qt.Key_Control: 'cmd', # cmd/apple key
- QtCore.Qt.Key_Meta: 'control',
- })
- MODIFIER_KEYS[0] = ('cmd', QtCore.Qt.ControlModifier,
- QtCore.Qt.Key_Control)
- MODIFIER_KEYS[2] = ('ctrl', QtCore.Qt.MetaModifier,
- QtCore.Qt.Key_Meta)
-
-
-cursord = {
- cursors.MOVE: QtCore.Qt.SizeAllCursor,
- cursors.HAND: QtCore.Qt.PointingHandCursor,
- cursors.POINTER: QtCore.Qt.ArrowCursor,
- cursors.SELECT_REGION: QtCore.Qt.CrossCursor,
- cursors.WAIT: QtCore.Qt.WaitCursor,
- }
-
-
-# make place holder
-qApp = None
-
-
-def _create_qApp():
- """
- Only one qApp can exist at a time, so check before creating one.
- """
- global qApp
-
- if qApp is None:
- app = QtWidgets.QApplication.instance()
- if app is None:
- # check for DISPLAY env variable on X11 build of Qt
- if is_pyqt5():
- try:
- from PyQt5 import QtX11Extras
- is_x11_build = True
- except ImportError:
- is_x11_build = False
- else:
- is_x11_build = hasattr(QtGui, "QX11Info")
- if is_x11_build:
- display = os.environ.get('DISPLAY')
- if display is None or not re.search(r':\d', display):
- raise RuntimeError('Invalid DISPLAY variable')
-
- qApp = QtWidgets.QApplication([b"matplotlib"])
- qApp.lastWindowClosed.connect(qApp.quit)
- else:
- qApp = app
-
- if is_pyqt5():
- try:
- qApp.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)
- qApp.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
- except AttributeError:
- pass
-
-
-def _allow_super_init(__init__):
- """
- Decorator for ``__init__`` to allow ``super().__init__`` on PyQt4/PySide2.
- """
-
- if QT_API == "PyQt5":
-
- return __init__
-
- else:
- # To work around lack of cooperative inheritance in PyQt4, PySide,
- # and PySide2, when calling FigureCanvasQT.__init__, we temporarily
- # patch QWidget.__init__ by a cooperative version, that first calls
- # QWidget.__init__ with no additional arguments, and then finds the
- # next class in the MRO with an __init__ that does support cooperative
- # inheritance (i.e., not defined by the PyQt4, PySide, PySide2, sip
- # or Shiboken packages), and manually call its `__init__`, once again
- # passing the additional arguments.
-
- qwidget_init = QtWidgets.QWidget.__init__
-
- def cooperative_qwidget_init(self, *args, **kwargs):
- qwidget_init(self)
- mro = type(self).__mro__
- next_coop_init = next(
- cls for cls in mro[mro.index(QtWidgets.QWidget) + 1:]
- if cls.__module__.split(".")[0] not in [
- "PyQt4", "sip", "PySide", "PySide2", "Shiboken"])
- next_coop_init.__init__(self, *args, **kwargs)
-
- @functools.wraps(__init__)
- def wrapper(self, **kwargs):
- try:
- QtWidgets.QWidget.__init__ = cooperative_qwidget_init
- __init__(self, **kwargs)
- finally:
- # Restore __init__
- QtWidgets.QWidget.__init__ = qwidget_init
-
- return wrapper
-
-
-class TimerQT(TimerBase):
- '''
- Subclass of :class:`backend_bases.TimerBase` that uses Qt timer events.
-
- Attributes
- ----------
- interval : int
- The time between timer events in milliseconds. Default is 1000 ms.
- single_shot : bool
- Boolean flag indicating whether this timer should
- operate as single shot (run once and then stop). Defaults to False.
- callbacks : list
- Stores list of (func, args) tuples that will be called upon timer
- events. This list can be manipulated directly, or the functions
- `add_callback` and `remove_callback` can be used.
-
- '''
-
- def __init__(self, *args, **kwargs):
- TimerBase.__init__(self, *args, **kwargs)
-
- # Create a new timer and connect the timeout() signal to the
- # _on_timer method.
- self._timer = QtCore.QTimer()
- self._timer.timeout.connect(self._on_timer)
- self._timer_set_interval()
-
- def _timer_set_single_shot(self):
- self._timer.setSingleShot(self._single)
-
- def _timer_set_interval(self):
- self._timer.setInterval(self._interval)
-
- def _timer_start(self):
- self._timer.start()
-
- def _timer_stop(self):
- self._timer.stop()
-
-
-class FigureCanvasQT(QtWidgets.QWidget, FigureCanvasBase):
-
- # map Qt button codes to MouseEvent's ones:
- buttond = {QtCore.Qt.LeftButton: 1,
- QtCore.Qt.MidButton: 2,
- QtCore.Qt.RightButton: 3,
- # QtCore.Qt.XButton1: None,
- # QtCore.Qt.XButton2: None,
- }
-
- @_allow_super_init
- def __init__(self, figure):
- _create_qApp()
- super(FigureCanvasQT, self).__init__(figure=figure)
-
- self.figure = figure
- # We don't want to scale up the figure DPI more than once.
- # Note, we don't handle a signal for changing DPI yet.
- figure._original_dpi = figure.dpi
- self._update_figure_dpi()
- # In cases with mixed resolution displays, we need to be careful if the
- # dpi_ratio changes - in this case we need to resize the canvas
- # accordingly. We could watch for screenChanged events from Qt, but
- # the issue is that we can't guarantee this will be emitted *before*
- # the first paintEvent for the canvas, so instead we keep track of the
- # dpi_ratio value here and in paintEvent we resize the canvas if
- # needed.
- self._dpi_ratio_prev = None
-
- self._draw_pending = False
- self._is_drawing = False
- self._draw_rect_callback = lambda painter: None
-
- self.setAttribute(QtCore.Qt.WA_OpaquePaintEvent)
- self.setMouseTracking(True)
- self.resize(*self.get_width_height())
- # Key auto-repeat enabled by default
- self._keyautorepeat = True
-
- palette = QtGui.QPalette(QtCore.Qt.white)
- self.setPalette(palette)
-
- def _update_figure_dpi(self):
- dpi = self._dpi_ratio * self.figure._original_dpi
- self.figure._set_dpi(dpi, forward=False)
-
- @property
- def _dpi_ratio(self):
- # Not available on Qt4 or some older Qt5.
- try:
- # self.devicePixelRatio() returns 0 in rare cases
- return self.devicePixelRatio() or 1
- except AttributeError:
- return 1
-
- def _update_dpi(self):
- # As described in __init__ above, we need to be careful in cases with
- # mixed resolution displays if dpi_ratio is changing between painting
- # events.
- # Return whether we triggered a resizeEvent (and thus a paintEvent)
- # from within this function.
- if self._dpi_ratio != self._dpi_ratio_prev:
- # We need to update the figure DPI.
- self._update_figure_dpi()
- self._dpi_ratio_prev = self._dpi_ratio
- # The easiest way to resize the canvas is to emit a resizeEvent
- # since we implement all the logic for resizing the canvas for
- # that event.
- event = QtGui.QResizeEvent(self.size(), self.size())
- self.resizeEvent(event)
- # resizeEvent triggers a paintEvent itself, so we exit this one
- # (after making sure that the event is immediately handled).
- return True
- return False
-
- def get_width_height(self):
- w, h = FigureCanvasBase.get_width_height(self)
- return int(w / self._dpi_ratio), int(h / self._dpi_ratio)
-
- def enterEvent(self, event):
- FigureCanvasBase.enter_notify_event(self, guiEvent=event)
-
- def leaveEvent(self, event):
- QtWidgets.QApplication.restoreOverrideCursor()
- FigureCanvasBase.leave_notify_event(self, guiEvent=event)
-
- def mouseEventCoords(self, pos):
- """Calculate mouse coordinates in physical pixels
-
- Qt5 use logical pixels, but the figure is scaled to physical
- pixels for rendering. Transform to physical pixels so that
- all of the down-stream transforms work as expected.
-
- Also, the origin is different and needs to be corrected.
-
- """
- dpi_ratio = self._dpi_ratio
- x = pos.x()
- # flip y so y=0 is bottom of canvas
- y = self.figure.bbox.height / dpi_ratio - pos.y()
- return x * dpi_ratio, y * dpi_ratio
-
- def mousePressEvent(self, event):
- x, y = self.mouseEventCoords(event.pos())
- button = self.buttond.get(event.button())
- if button is not None:
- FigureCanvasBase.button_press_event(self, x, y, button,
- guiEvent=event)
-
- def mouseDoubleClickEvent(self, event):
- x, y = self.mouseEventCoords(event.pos())
- button = self.buttond.get(event.button())
- if button is not None:
- FigureCanvasBase.button_press_event(self, x, y,
- button, dblclick=True,
- guiEvent=event)
-
- def mouseMoveEvent(self, event):
- x, y = self.mouseEventCoords(event)
- FigureCanvasBase.motion_notify_event(self, x, y, guiEvent=event)
-
- def mouseReleaseEvent(self, event):
- x, y = self.mouseEventCoords(event)
- button = self.buttond.get(event.button())
- if button is not None:
- FigureCanvasBase.button_release_event(self, x, y, button,
- guiEvent=event)
-
- if is_pyqt5():
- def wheelEvent(self, event):
- x, y = self.mouseEventCoords(event)
- # from QWheelEvent::delta doc
- if event.pixelDelta().x() == 0 and event.pixelDelta().y() == 0:
- steps = event.angleDelta().y() / 120
- else:
- steps = event.pixelDelta().y()
- if steps:
- FigureCanvasBase.scroll_event(
- self, x, y, steps, guiEvent=event)
- else:
- def wheelEvent(self, event):
- x = event.x()
- # flipy so y=0 is bottom of canvas
- y = self.figure.bbox.height - event.y()
- # from QWheelEvent::delta doc
- steps = event.delta() / 120
- if event.orientation() == QtCore.Qt.Vertical:
- FigureCanvasBase.scroll_event(
- self, x, y, steps, guiEvent=event)
-
- def keyPressEvent(self, event):
- key = self._get_key(event)
- if key is not None:
- FigureCanvasBase.key_press_event(self, key, guiEvent=event)
-
- def keyReleaseEvent(self, event):
- key = self._get_key(event)
- if key is not None:
- FigureCanvasBase.key_release_event(self, key, guiEvent=event)
-
- @property
- def keyAutoRepeat(self):
- """
- If True, enable auto-repeat for key events.
- """
- return self._keyautorepeat
-
- @keyAutoRepeat.setter
- def keyAutoRepeat(self, val):
- self._keyautorepeat = bool(val)
-
- def resizeEvent(self, event):
- # _dpi_ratio_prev will be set the first time the canvas is painted, and
- # the rendered buffer is useless before anyways.
- if self._dpi_ratio_prev is None:
- return
- w = event.size().width() * self._dpi_ratio
- h = event.size().height() * self._dpi_ratio
- dpival = self.figure.dpi
- winch = w / dpival
- hinch = h / dpival
- self.figure.set_size_inches(winch, hinch, forward=False)
- # pass back into Qt to let it finish
- QtWidgets.QWidget.resizeEvent(self, event)
- # emit our resize events
- FigureCanvasBase.resize_event(self)
-
- def sizeHint(self):
- w, h = self.get_width_height()
- return QtCore.QSize(w, h)
-
- def minumumSizeHint(self):
- return QtCore.QSize(10, 10)
-
- def _get_key(self, event):
- if not self._keyautorepeat and event.isAutoRepeat():
- return None
-
- event_key = event.key()
- event_mods = int(event.modifiers()) # actually a bitmask
-
- # get names of the pressed modifier keys
- # bit twiddling to pick out modifier keys from event_mods bitmask,
- # if event_key is a MODIFIER, it should not be duplicated in mods
- mods = [name for name, mod_key, qt_key in MODIFIER_KEYS
- if event_key != qt_key and (event_mods & mod_key) == mod_key]
- try:
- # for certain keys (enter, left, backspace, etc) use a word for the
- # key, rather than unicode
- key = SPECIAL_KEYS[event_key]
- except KeyError:
- # unicode defines code points up to 0x0010ffff
- # QT will use Key_Codes larger than that for keyboard keys that are
- # are not unicode characters (like multimedia keys)
- # skip these
- # if you really want them, you should add them to SPECIAL_KEYS
- MAX_UNICODE = 0x10ffff
- if event_key > MAX_UNICODE:
- return None
-
- key = unichr(event_key)
- # qt delivers capitalized letters. fix capitalization
- # note that capslock is ignored
- if 'shift' in mods:
- mods.remove('shift')
- else:
- key = key.lower()
-
- mods.reverse()
- return '+'.join(mods + [key])
-
- def new_timer(self, *args, **kwargs):
- """
- Creates a new backend-specific subclass of
- :class:`backend_bases.Timer`. This is useful for getting
- periodic events through the backend's native event
- loop. Implemented only for backends with GUIs.
-
- Other Parameters
- ----------------
- interval : scalar
- Timer interval in milliseconds
-
- callbacks : list
- Sequence of (func, args, kwargs) where ``func(*args, **kwargs)``
- will be executed by the timer every *interval*.
-
- """
- return TimerQT(*args, **kwargs)
-
- def flush_events(self):
- qApp.processEvents()
-
- def start_event_loop(self, timeout=0):
- if hasattr(self, "_event_loop") and self._event_loop.isRunning():
- raise RuntimeError("Event loop already running")
- self._event_loop = event_loop = QtCore.QEventLoop()
- if timeout:
- timer = QtCore.QTimer.singleShot(timeout * 1000, event_loop.quit)
- event_loop.exec_()
-
- def stop_event_loop(self, event=None):
- if hasattr(self, "_event_loop"):
- self._event_loop.quit()
-
- def draw(self):
- """Render the figure, and queue a request for a Qt draw.
- """
- # The renderer draw is done here; delaying causes problems with code
- # that uses the result of the draw() to update plot elements.
- if self._is_drawing:
- return
- self._is_drawing = True
- try:
- super(FigureCanvasQT, self).draw()
- finally:
- self._is_drawing = False
- self.update()
-
- def draw_idle(self):
- """Queue redraw of the Agg buffer and request Qt paintEvent.
- """
- # The Agg draw needs to be handled by the same thread matplotlib
- # modifies the scene graph from. Post Agg draw request to the
- # current event loop in order to ensure thread affinity and to
- # accumulate multiple draw requests from event handling.
- # TODO: queued signal connection might be safer than singleShot
- if not (getattr(self, '_draw_pending', False) or
- getattr(self, '_is_drawing', False)):
- self._draw_pending = True
- QtCore.QTimer.singleShot(0, self._draw_idle)
-
- def _draw_idle(self):
- if self.height() < 0 or self.width() < 0:
- self._draw_pending = False
- if not self._draw_pending:
- return
- try:
- self.draw()
- except Exception:
- # Uncaught exceptions are fatal for PyQt5, so catch them instead.
- traceback.print_exc()
- finally:
- self._draw_pending = False
-
- def drawRectangle(self, rect):
- # Draw the zoom rectangle to the QPainter. _draw_rect_callback needs
- # to be called at the end of paintEvent.
- if rect is not None:
- def _draw_rect_callback(painter):
- pen = QtGui.QPen(QtCore.Qt.black, 1 / self._dpi_ratio,
- QtCore.Qt.DotLine)
- painter.setPen(pen)
- painter.drawRect(*(pt / self._dpi_ratio for pt in rect))
- else:
- def _draw_rect_callback(painter):
- return
- self._draw_rect_callback = _draw_rect_callback
- self.update()
-
-
-class MainWindow(QtWidgets.QMainWindow):
- closing = QtCore.Signal()
-
- def closeEvent(self, event):
- self.closing.emit()
- QtWidgets.QMainWindow.closeEvent(self, event)
-
-
-class FigureManagerQT(FigureManagerBase):
- """
- Attributes
- ----------
- canvas : `FigureCanvas`
- The FigureCanvas instance
- num : int or str
- The Figure number
- toolbar : qt.QToolBar
- The qt.QToolBar
- window : qt.QMainWindow
- The qt.QMainWindow
-
- """
-
- def __init__(self, canvas, num):
- FigureManagerBase.__init__(self, canvas, num)
- self.canvas = canvas
- self.window = MainWindow()
- self.window.closing.connect(canvas.close_event)
- self.window.closing.connect(self._widgetclosed)
-
- self.window.setWindowTitle("Figure %d" % num)
- image = os.path.join(matplotlib.rcParams['datapath'],
- 'images', 'matplotlib.svg')
- self.window.setWindowIcon(QtGui.QIcon(image))
-
- # Give the keyboard focus to the figure instead of the
- # manager; StrongFocus accepts both tab and click to focus and
- # will enable the canvas to process event w/o clicking.
- # ClickFocus only takes the focus is the window has been
- # clicked
- # on. http://qt-project.org/doc/qt-4.8/qt.html#FocusPolicy-enum or
- # http://doc.qt.digia.com/qt/qt.html#FocusPolicy-enum
- self.canvas.setFocusPolicy(QtCore.Qt.StrongFocus)
- self.canvas.setFocus()
-
- self.window._destroying = False
-
- self.toolmanager = self._get_toolmanager()
- self.toolbar = self._get_toolbar(self.canvas, self.window)
- self.statusbar = None
-
- if self.toolmanager:
- backend_tools.add_tools_to_manager(self.toolmanager)
- if self.toolbar:
- backend_tools.add_tools_to_container(self.toolbar)
- self.statusbar = StatusbarQt(self.window, self.toolmanager)
-
- if self.toolbar is not None:
- self.window.addToolBar(self.toolbar)
- if not self.toolmanager:
- # add text label to status bar
- statusbar_label = QtWidgets.QLabel()
- self.window.statusBar().addWidget(statusbar_label)
- self.toolbar.message.connect(statusbar_label.setText)
- tbs_height = self.toolbar.sizeHint().height()
- else:
- tbs_height = 0
-
- # resize the main window so it will display the canvas with the
- # requested size:
- cs = canvas.sizeHint()
- sbs = self.window.statusBar().sizeHint()
- self._status_and_tool_height = tbs_height + sbs.height()
- height = cs.height() + self._status_and_tool_height
- self.window.resize(cs.width(), height)
-
- self.window.setCentralWidget(self.canvas)
-
- if matplotlib.is_interactive():
- self.window.show()
- self.canvas.draw_idle()
-
- def notify_axes_change(fig):
- # This will be called whenever the current axes is changed
- if self.toolbar is not None:
- self.toolbar.update()
- self.canvas.figure.add_axobserver(notify_axes_change)
- self.window.raise_()
-
- def full_screen_toggle(self):
- if self.window.isFullScreen():
- self.window.showNormal()
- else:
- self.window.showFullScreen()
-
- def _widgetclosed(self):
- if self.window._destroying:
- return
- self.window._destroying = True
- try:
- Gcf.destroy(self.num)
- except AttributeError:
- pass
- # It seems that when the python session is killed,
- # Gcf can get destroyed before the Gcf.destroy
- # line is run, leading to a useless AttributeError.
-
- def _get_toolbar(self, canvas, parent):
- # must be inited after the window, drawingArea and figure
- # attrs are set
- if matplotlib.rcParams['toolbar'] == 'toolbar2':
- toolbar = NavigationToolbar2QT(canvas, parent, False)
- elif matplotlib.rcParams['toolbar'] == 'toolmanager':
- toolbar = ToolbarQt(self.toolmanager, self.window)
- else:
- toolbar = None
- return toolbar
-
- def _get_toolmanager(self):
- if matplotlib.rcParams['toolbar'] == 'toolmanager':
- toolmanager = ToolManager(self.canvas.figure)
- else:
- toolmanager = None
- return toolmanager
-
- def resize(self, width, height):
- 'set the canvas size in pixels'
- self.window.resize(width, height + self._status_and_tool_height)
-
- def show(self):
- self.window.show()
- self.window.activateWindow()
- self.window.raise_()
-
- def destroy(self, *args):
- # check for qApp first, as PySide deletes it in its atexit handler
- if QtWidgets.QApplication.instance() is None:
- return
- if self.window._destroying:
- return
- self.window._destroying = True
- if self.toolbar:
- self.toolbar.destroy()
- self.window.close()
-
- def get_window_title(self):
- return six.text_type(self.window.windowTitle())
-
- def set_window_title(self, title):
- self.window.setWindowTitle(title)
-
-
-class NavigationToolbar2QT(NavigationToolbar2, QtWidgets.QToolBar):
- message = QtCore.Signal(str)
-
- def __init__(self, canvas, parent, coordinates=True):
- """ coordinates: should we show the coordinates on the right? """
- self.canvas = canvas
- self.parent = parent
- self.coordinates = coordinates
- self._actions = {}
- """A mapping of toolitem method names to their QActions"""
-
- QtWidgets.QToolBar.__init__(self, parent)
- NavigationToolbar2.__init__(self, canvas)
-
- def _icon(self, name):
- if is_pyqt5():
- name = name.replace('.png', '_large.png')
- pm = QtGui.QPixmap(os.path.join(self.basedir, name))
- if hasattr(pm, 'setDevicePixelRatio'):
- pm.setDevicePixelRatio(self.canvas._dpi_ratio)
- return QtGui.QIcon(pm)
-
- def _init_toolbar(self):
- self.basedir = os.path.join(matplotlib.rcParams['datapath'], 'images')
-
- for text, tooltip_text, image_file, callback in self.toolitems:
- if text is None:
- self.addSeparator()
- else:
- a = self.addAction(self._icon(image_file + '.png'),
- text, getattr(self, callback))
- self._actions[callback] = a
- if callback in ['zoom', 'pan']:
- a.setCheckable(True)
- if tooltip_text is not None:
- a.setToolTip(tooltip_text)
- if text == 'Subplots':
- a = self.addAction(self._icon("qt4_editor_options.png"),
- 'Customize', self.edit_parameters)
- a.setToolTip('Edit axis, curve and image parameters')
-
- self.buttons = {}
-
- # Add the x,y location widget at the right side of the toolbar
- # The stretch factor is 1 which means any resizing of the toolbar
- # will resize this label instead of the buttons.
- if self.coordinates:
- self.locLabel = QtWidgets.QLabel("", self)
- self.locLabel.setAlignment(
- QtCore.Qt.AlignRight | QtCore.Qt.AlignTop)
- self.locLabel.setSizePolicy(
- QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding,
- QtWidgets.QSizePolicy.Ignored))
- labelAction = self.addWidget(self.locLabel)
- labelAction.setVisible(True)
-
- # reference holder for subplots_adjust window
- self.adj_window = None
-
- # Esthetic adjustments - we need to set these explicitly in PyQt5
- # otherwise the layout looks different - but we don't want to set it if
- # not using HiDPI icons otherwise they look worse than before.
- if is_pyqt5():
- self.setIconSize(QtCore.QSize(24, 24))
- self.layout().setSpacing(12)
-
- if is_pyqt5():
- # For some reason, self.setMinimumHeight doesn't seem to carry over to
- # the actual sizeHint, so override it instead in order to make the
- # aesthetic adjustments noted above.
- def sizeHint(self):
- size = super(NavigationToolbar2QT, self).sizeHint()
- size.setHeight(max(48, size.height()))
- return size
-
- def edit_parameters(self):
- allaxes = self.canvas.figure.get_axes()
- if not allaxes:
- QtWidgets.QMessageBox.warning(
- self.parent, "Error", "There are no axes to edit.")
- return
- elif len(allaxes) == 1:
- axes, = allaxes
- else:
- titles = []
- for axes in allaxes:
- name = (axes.get_title() or
- " - ".join(filter(None, [axes.get_xlabel(),
- axes.get_ylabel()])) or
- "<anonymous {} (id: {:#x})>".format(
- type(axes).__name__, id(axes)))
- titles.append(name)
- item, ok = QtWidgets.QInputDialog.getItem(
- self.parent, 'Customize', 'Select axes:', titles, 0, False)
- if ok:
- axes = allaxes[titles.index(six.text_type(item))]
- else:
- return
-
- figureoptions.figure_edit(axes, self)
-
- def _update_buttons_checked(self):
- # sync button checkstates to match active mode
- self._actions['pan'].setChecked(self._active == 'PAN')
- self._actions['zoom'].setChecked(self._active == 'ZOOM')
-
- def pan(self, *args):
- super(NavigationToolbar2QT, self).pan(*args)
- self._update_buttons_checked()
-
- def zoom(self, *args):
- super(NavigationToolbar2QT, self).zoom(*args)
- self._update_buttons_checked()
-
- def set_message(self, s):
- self.message.emit(s)
- if self.coordinates:
- self.locLabel.setText(s)
-
- def set_cursor(self, cursor):
- self.canvas.setCursor(cursord[cursor])
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- height = self.canvas.figure.bbox.height
- y1 = height - y1
- y0 = height - y0
- rect = [int(val) for val in (x0, y0, x1 - x0, y1 - y0)]
- self.canvas.drawRectangle(rect)
-
- def remove_rubberband(self):
- self.canvas.drawRectangle(None)
-
- def configure_subplots(self):
- image = os.path.join(matplotlib.rcParams['datapath'],
- 'images', 'matplotlib.png')
- dia = SubplotToolQt(self.canvas.figure, self.parent)
- dia.setWindowIcon(QtGui.QIcon(image))
- dia.exec_()
-
- def save_figure(self, *args):
- filetypes = self.canvas.get_supported_filetypes_grouped()
- sorted_filetypes = sorted(six.iteritems(filetypes))
- default_filetype = self.canvas.get_default_filetype()
-
- startpath = os.path.expanduser(
- matplotlib.rcParams['savefig.directory'])
- start = os.path.join(startpath, self.canvas.get_default_filename())
- filters = []
- selectedFilter = None
- for name, exts in sorted_filetypes:
- exts_list = " ".join(['*.%s' % ext for ext in exts])
- filter = '%s (%s)' % (name, exts_list)
- if default_filetype in exts:
- selectedFilter = filter
- filters.append(filter)
- filters = ';;'.join(filters)
-
- fname, filter = _getSaveFileName(self.parent,
- "Choose a filename to save to",
- start, filters, selectedFilter)
- if fname:
- # Save dir for next time, unless empty str (i.e., use cwd).
- if startpath != "":
- matplotlib.rcParams['savefig.directory'] = (
- os.path.dirname(six.text_type(fname)))
- try:
- self.canvas.figure.savefig(six.text_type(fname))
- except Exception as e:
- QtWidgets.QMessageBox.critical(
- self, "Error saving file", six.text_type(e),
- QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.NoButton)
-
-
-class SubplotToolQt(UiSubplotTool):
- def __init__(self, targetfig, parent):
- UiSubplotTool.__init__(self, None)
-
- self._figure = targetfig
-
- for lower, higher in [("bottom", "top"), ("left", "right")]:
- self._widgets[lower].valueChanged.connect(
- lambda val: self._widgets[higher].setMinimum(val + .001))
- self._widgets[higher].valueChanged.connect(
- lambda val: self._widgets[lower].setMaximum(val - .001))
-
- self._attrs = ["top", "bottom", "left", "right", "hspace", "wspace"]
- self._defaults = {attr: vars(self._figure.subplotpars)[attr]
- for attr in self._attrs}
-
- # Set values after setting the range callbacks, but before setting up
- # the redraw callbacks.
- self._reset()
-
- for attr in self._attrs:
- self._widgets[attr].valueChanged.connect(self._on_value_changed)
- for action, method in [("Export values", self._export_values),
- ("Tight layout", self._tight_layout),
- ("Reset", self._reset),
- ("Close", self.close)]:
- self._widgets[action].clicked.connect(method)
-
- def _export_values(self):
- # Explicitly round to 3 decimals (which is also the spinbox precision)
- # to avoid numbers of the form 0.100...001.
- dialog = QtWidgets.QDialog()
- layout = QtWidgets.QVBoxLayout()
- dialog.setLayout(layout)
- text = QtWidgets.QPlainTextEdit()
- text.setReadOnly(True)
- layout.addWidget(text)
- text.setPlainText(
- ",\n".join("{}={:.3}".format(attr, self._widgets[attr].value())
- for attr in self._attrs))
- # Adjust the height of the text widget to fit the whole text, plus
- # some padding.
- size = text.maximumSize()
- size.setHeight(
- QtGui.QFontMetrics(text.document().defaultFont())
- .size(0, text.toPlainText()).height() + 20)
- text.setMaximumSize(size)
- dialog.exec_()
-
- def _on_value_changed(self):
- self._figure.subplots_adjust(**{attr: self._widgets[attr].value()
- for attr in self._attrs})
- self._figure.canvas.draw_idle()
-
- def _tight_layout(self):
- self._figure.tight_layout()
- for attr in self._attrs:
- widget = self._widgets[attr]
- widget.blockSignals(True)
- widget.setValue(vars(self._figure.subplotpars)[attr])
- widget.blockSignals(False)
- self._figure.canvas.draw_idle()
-
- def _reset(self):
- for attr, value in self._defaults.items():
- self._widgets[attr].setValue(value)
-
-
-class ToolbarQt(ToolContainerBase, QtWidgets.QToolBar):
- def __init__(self, toolmanager, parent):
- ToolContainerBase.__init__(self, toolmanager)
- QtWidgets.QToolBar.__init__(self, parent)
- self._toolitems = {}
- self._groups = {}
- self._last = None
-
- @property
- def _icon_extension(self):
- if is_pyqt5():
- return '_large.png'
- return '.png'
-
- def add_toolitem(
- self, name, group, position, image_file, description, toggle):
-
- button = QtWidgets.QToolButton(self)
- button.setIcon(self._icon(image_file))
- button.setText(name)
- if description:
- button.setToolTip(description)
-
- def handler():
- self.trigger_tool(name)
- if toggle:
- button.setCheckable(True)
- button.toggled.connect(handler)
- else:
- button.clicked.connect(handler)
-
- self._last = button
- self._toolitems.setdefault(name, [])
- self._add_to_group(group, name, button, position)
- self._toolitems[name].append((button, handler))
-
- def _add_to_group(self, group, name, button, position):
- gr = self._groups.get(group, [])
- if not gr:
- sep = self.addSeparator()
- gr.append(sep)
- before = gr[position]
- widget = self.insertWidget(before, button)
- gr.insert(position, widget)
- self._groups[group] = gr
-
- def _icon(self, name):
- pm = QtGui.QPixmap(name)
- if hasattr(pm, 'setDevicePixelRatio'):
- pm.setDevicePixelRatio(self.toolmanager.canvas._dpi_ratio)
- return QtGui.QIcon(pm)
-
- def toggle_toolitem(self, name, toggled):
- if name not in self._toolitems:
- return
- for button, handler in self._toolitems[name]:
- button.toggled.disconnect(handler)
- button.setChecked(toggled)
- button.toggled.connect(handler)
-
- def remove_toolitem(self, name):
- for button, handler in self._toolitems[name]:
- button.setParent(None)
- del self._toolitems[name]
-
-
-class StatusbarQt(StatusbarBase, QtWidgets.QLabel):
- def __init__(self, window, *args, **kwargs):
- StatusbarBase.__init__(self, *args, **kwargs)
- QtWidgets.QLabel.__init__(self)
- window.statusBar().addWidget(self)
-
- def set_message(self, s):
- self.setText(s)
-
-
-class ConfigureSubplotsQt(backend_tools.ConfigureSubplotsBase):
- def trigger(self, *args):
- image = os.path.join(matplotlib.rcParams['datapath'],
- 'images', 'matplotlib.png')
- parent = self.canvas.manager.window
- dia = SubplotToolQt(self.figure, parent)
- dia.setWindowIcon(QtGui.QIcon(image))
- dia.exec_()
-
-
-class SaveFigureQt(backend_tools.SaveFigureBase):
- def trigger(self, *args):
- filetypes = self.canvas.get_supported_filetypes_grouped()
- sorted_filetypes = sorted(six.iteritems(filetypes))
- default_filetype = self.canvas.get_default_filetype()
-
- startpath = os.path.expanduser(
- matplotlib.rcParams['savefig.directory'])
- start = os.path.join(startpath, self.canvas.get_default_filename())
- filters = []
- selectedFilter = None
- for name, exts in sorted_filetypes:
- exts_list = " ".join(['*.%s' % ext for ext in exts])
- filter = '%s (%s)' % (name, exts_list)
- if default_filetype in exts:
- selectedFilter = filter
- filters.append(filter)
- filters = ';;'.join(filters)
-
- parent = self.canvas.manager.window
- fname, filter = _getSaveFileName(parent,
- "Choose a filename to save to",
- start, filters, selectedFilter)
- if fname:
- # Save dir for next time, unless empty str (i.e., use cwd).
- if startpath != "":
- matplotlib.rcParams['savefig.directory'] = (
- os.path.dirname(six.text_type(fname)))
- try:
- self.canvas.figure.savefig(six.text_type(fname))
- except Exception as e:
- QtWidgets.QMessageBox.critical(
- self, "Error saving file", six.text_type(e),
- QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.NoButton)
-
-
-class SetCursorQt(backend_tools.SetCursorBase):
- def set_cursor(self, cursor):
- self.canvas.setCursor(cursord[cursor])
-
-
-class RubberbandQt(backend_tools.RubberbandBase):
- def draw_rubberband(self, x0, y0, x1, y1):
- height = self.canvas.figure.bbox.height
- y1 = height - y1
- y0 = height - y0
- rect = [int(val) for val in (x0, y0, x1 - x0, y1 - y0)]
- self.canvas.drawRectangle(rect)
-
- def remove_rubberband(self):
- self.canvas.drawRectangle(None)
-
-
-backend_tools.ToolSaveFigure = SaveFigureQt
-backend_tools.ToolConfigureSubplots = ConfigureSubplotsQt
-backend_tools.ToolSetCursor = SetCursorQt
-backend_tools.ToolRubberband = RubberbandQt
-
-
-def error_msg_qt(msg, parent=None):
- if not isinstance(msg, six.string_types):
- msg = ','.join(map(str, msg))
-
- QtWidgets.QMessageBox.warning(None, "Matplotlib",
- msg, QtGui.QMessageBox.Ok)
-
-
-def exception_handler(type, value, tb):
- """Handle uncaught exceptions
- It does not catch SystemExit
- """
- msg = ''
- # get the filename attribute if available (for IOError)
- if hasattr(value, 'filename') and value.filename is not None:
- msg = value.filename + ': '
- if hasattr(value, 'strerror') and value.strerror is not None:
- msg += value.strerror
- else:
- msg += six.text_type(value)
-
- if len(msg):
- error_msg_qt(msg)
-
-
-@_Backend.export
-class _BackendQT5(_Backend):
- FigureCanvas = FigureCanvasQT
- FigureManager = FigureManagerQT
-
- @staticmethod
- def trigger_manager_draw(manager):
- manager.canvas.draw_idle()
-
- @staticmethod
- def mainloop():
- # allow KeyboardInterrupt exceptions to close the plot window.
- signal.signal(signal.SIGINT, signal.SIG_DFL)
- qApp.exec_()
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt5agg.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt5agg.py
deleted file mode 100644
index d2166d58c8..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt5agg.py
+++ /dev/null
@@ -1,105 +0,0 @@
-"""
-Render to qt from agg
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import ctypes
-
-from matplotlib import cbook
-from matplotlib.transforms import Bbox
-
-from .backend_agg import FigureCanvasAgg
-from .backend_qt5 import (
- QtCore, QtGui, QtWidgets, _BackendQT5, FigureCanvasQT, FigureManagerQT,
- NavigationToolbar2QT, backend_version)
-from .qt_compat import QT_API
-
-
-class FigureCanvasQTAgg(FigureCanvasAgg, FigureCanvasQT):
-
- def __init__(self, figure):
- super(FigureCanvasQTAgg, self).__init__(figure=figure)
- self._bbox_queue = []
-
- @property
- @cbook.deprecated("2.1")
- def blitbox(self):
- return self._bbox_queue
-
- def paintEvent(self, e):
- """Copy the image from the Agg canvas to the qt.drawable.
-
- In Qt, all drawing should be done inside of here when a widget is
- shown onscreen.
- """
- if self._update_dpi():
- # The dpi update triggered its own paintEvent.
- return
- self._draw_idle() # Only does something if a draw is pending.
-
- # if the canvas does not have a renderer, then give up and wait for
- # FigureCanvasAgg.draw(self) to be called
- if not hasattr(self, 'renderer'):
- return
-
- painter = QtGui.QPainter(self)
-
- if self._bbox_queue:
- bbox_queue = self._bbox_queue
- else:
- painter.eraseRect(self.rect())
- bbox_queue = [
- Bbox([[0, 0], [self.renderer.width, self.renderer.height]])]
- self._bbox_queue = []
- for bbox in bbox_queue:
- l, b, r, t = map(int, bbox.extents)
- w = r - l
- h = t - b
- reg = self.copy_from_bbox(bbox)
- buf = reg.to_string_argb()
- qimage = QtGui.QImage(buf, w, h, QtGui.QImage.Format_ARGB32)
- # Adjust the buf reference count to work around a memory leak bug
- # in QImage under PySide on Python 3.
- if QT_API in ('PySide', 'PySide2') and six.PY3:
- ctypes.c_long.from_address(id(buf)).value = 1
- if hasattr(qimage, 'setDevicePixelRatio'):
- # Not available on Qt4 or some older Qt5.
- qimage.setDevicePixelRatio(self._dpi_ratio)
- origin = QtCore.QPoint(int(l), int(self.renderer.height - t))
- painter.drawImage(origin / self._dpi_ratio, qimage)
-
- self._draw_rect_callback(painter)
-
- painter.end()
-
- def blit(self, bbox=None):
- """Blit the region in bbox.
- """
- # If bbox is None, blit the entire canvas. Otherwise
- # blit only the area defined by the bbox.
- if bbox is None and self.figure:
- bbox = self.figure.bbox
-
- self._bbox_queue.append(bbox)
-
- # repaint uses logical pixels, not physical pixels like the renderer.
- l, b, w, h = [pt / self._dpi_ratio for pt in bbox.bounds]
- t = b + h
- self.repaint(l, self.renderer.height / self._dpi_ratio - t, w, h)
-
- def print_figure(self, *args, **kwargs):
- super(FigureCanvasQTAgg, self).print_figure(*args, **kwargs)
- self.draw()
-
-
-@cbook.deprecated("2.2")
-class FigureCanvasQTAggBase(FigureCanvasQTAgg):
- pass
-
-
-@_BackendQT5.export
-class _BackendQT5Agg(_BackendQT5):
- FigureCanvas = FigureCanvasQTAgg
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt5cairo.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt5cairo.py
deleted file mode 100644
index 1108707c3a..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_qt5cairo.py
+++ /dev/null
@@ -1,49 +0,0 @@
-
-import six
-
-from .backend_cairo import cairo, FigureCanvasCairo, RendererCairo
-from .backend_qt5 import QtCore, QtGui, _BackendQT5, FigureCanvasQT
-from .qt_compat import QT_API
-
-
-class FigureCanvasQTCairo(FigureCanvasQT, FigureCanvasCairo):
- def __init__(self, figure):
- super(FigureCanvasQTCairo, self).__init__(figure=figure)
- self._renderer = RendererCairo(self.figure.dpi)
- self._renderer.set_width_height(-1, -1) # Invalid values.
-
- def draw(self):
- if hasattr(self._renderer.gc, "ctx"):
- self.figure.draw(self._renderer)
- super(FigureCanvasQTCairo, self).draw()
-
- def paintEvent(self, event):
- self._update_dpi()
- dpi_ratio = self._dpi_ratio
- width = dpi_ratio * self.width()
- height = dpi_ratio * self.height()
- if (width, height) != self._renderer.get_canvas_width_height():
- surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
- self._renderer.set_ctx_from_surface(surface)
- self._renderer.set_width_height(width, height)
- self.figure.draw(self._renderer)
- buf = self._renderer.gc.ctx.get_target().get_data()
- qimage = QtGui.QImage(buf, width, height,
- QtGui.QImage.Format_ARGB32_Premultiplied)
- # Adjust the buf reference count to work around a memory leak bug in
- # QImage under PySide on Python 3.
- if QT_API == 'PySide' and six.PY3:
- import ctypes
- ctypes.c_long.from_address(id(buf)).value = 1
- if hasattr(qimage, 'setDevicePixelRatio'):
- # Not available on Qt4 or some older Qt5.
- qimage.setDevicePixelRatio(dpi_ratio)
- painter = QtGui.QPainter(self)
- painter.drawImage(0, 0, qimage)
- self._draw_rect_callback(painter)
- painter.end()
-
-
-@_BackendQT5.export
-class _BackendQT5Cairo(_BackendQT5):
- FigureCanvas = FigureCanvasQTCairo
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_svg.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_svg.py
deleted file mode 100644
index b38c6850da..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_svg.py
+++ /dev/null
@@ -1,1261 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from collections import OrderedDict
-
-import six
-from six import unichr
-from six.moves import xrange
-
-import base64
-import codecs
-import gzip
-import hashlib
-import io
-import logging
-import re
-import uuid
-
-import numpy as np
-
-from matplotlib import cbook, __version__, rcParams
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, RendererBase)
-from matplotlib.backends.backend_mixed import MixedModeRenderer
-from matplotlib.cbook import is_writable_file_like, maxdict
-from matplotlib.colors import rgb2hex
-from matplotlib.font_manager import findfont, get_font
-from matplotlib.ft2font import LOAD_NO_HINTING
-from matplotlib.mathtext import MathTextParser
-from matplotlib.path import Path
-from matplotlib import _path
-from matplotlib.transforms import Affine2D, Affine2DBase
-from matplotlib import _png
-
-_log = logging.getLogger(__name__)
-
-backend_version = __version__
-
-# ----------------------------------------------------------------------
-# SimpleXMLWriter class
-#
-# Based on an original by Fredrik Lundh, but modified here to:
-# 1. Support modern Python idioms
-# 2. Remove encoding support (it's handled by the file writer instead)
-# 3. Support proper indentation
-# 4. Minify things a little bit
-
-# --------------------------------------------------------------------
-# The SimpleXMLWriter module is
-#
-# Copyright (c) 2001-2004 by Fredrik Lundh
-#
-# By obtaining, using, and/or copying this software and/or its
-# associated documentation, you agree that you have read, understood,
-# and will comply with the following terms and conditions:
-#
-# Permission to use, copy, modify, and distribute this software and
-# its associated documentation for any purpose and without fee is
-# hereby granted, provided that the above copyright notice appears in
-# all copies, and that both that copyright notice and this permission
-# notice appear in supporting documentation, and that the name of
-# Secret Labs AB or the author not be used in advertising or publicity
-# pertaining to distribution of the software without specific, written
-# prior permission.
-#
-# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
-# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
-# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
-# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
-# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
-# OF THIS SOFTWARE.
-# --------------------------------------------------------------------
-
-def escape_cdata(s):
- s = s.replace("&", "&amp;")
- s = s.replace("<", "&lt;")
- s = s.replace(">", "&gt;")
- return s
-
-_escape_xml_comment = re.compile(r'-(?=-)')
-def escape_comment(s):
- s = escape_cdata(s)
- return _escape_xml_comment.sub('- ', s)
-
-def escape_attrib(s):
- s = s.replace("&", "&amp;")
- s = s.replace("'", "&apos;")
- s = s.replace("\"", "&quot;")
- s = s.replace("<", "&lt;")
- s = s.replace(">", "&gt;")
- return s
-
-def short_float_fmt(x):
- """
- Create a short string representation of a float, which is %f
- formatting with trailing zeros and the decimal point removed.
- """
- return '{0:f}'.format(x).rstrip('0').rstrip('.')
-
-##
-# XML writer class.
-#
-# @param file A file or file-like object. This object must implement
-# a <b>write</b> method that takes an 8-bit string.
-
-class XMLWriter(object):
- def __init__(self, file):
- self.__write = file.write
- if hasattr(file, "flush"):
- self.flush = file.flush
- self.__open = 0 # true if start tag is open
- self.__tags = []
- self.__data = []
- self.__indentation = " " * 64
-
- def __flush(self, indent=True):
- # flush internal buffers
- if self.__open:
- if indent:
- self.__write(">\n")
- else:
- self.__write(">")
- self.__open = 0
- if self.__data:
- data = ''.join(self.__data)
- self.__write(escape_cdata(data))
- self.__data = []
-
- ## Opens a new element. Attributes can be given as keyword
- # arguments, or as a string/string dictionary. The method returns
- # an opaque identifier that can be passed to the <b>close</b>
- # method, to close all open elements up to and including this one.
- #
- # @param tag Element tag.
- # @param attrib Attribute dictionary. Alternatively, attributes
- # can be given as keyword arguments.
- # @return An element identifier.
-
- def start(self, tag, attrib={}, **extra):
- self.__flush()
- tag = escape_cdata(tag)
- self.__data = []
- self.__tags.append(tag)
- self.__write(self.__indentation[:len(self.__tags) - 1])
- self.__write("<%s" % tag)
- if attrib or extra:
- attrib = attrib.copy()
- attrib.update(extra)
- attrib = sorted(six.iteritems(attrib))
- for k, v in attrib:
- if not v == '':
- k = escape_cdata(k)
- v = escape_attrib(v)
- self.__write(" %s=\"%s\"" % (k, v))
- self.__open = 1
- return len(self.__tags)-1
-
- ##
- # Adds a comment to the output stream.
- #
- # @param comment Comment text, as a Unicode string.
-
- def comment(self, comment):
- self.__flush()
- self.__write(self.__indentation[:len(self.__tags)])
- self.__write("<!-- %s -->\n" % escape_comment(comment))
-
- ##
- # Adds character data to the output stream.
- #
- # @param text Character data, as a Unicode string.
-
- def data(self, text):
- self.__data.append(text)
-
- ##
- # Closes the current element (opened by the most recent call to
- # <b>start</b>).
- #
- # @param tag Element tag. If given, the tag must match the start
- # tag. If omitted, the current element is closed.
-
- def end(self, tag=None, indent=True):
- if tag:
- assert self.__tags, "unbalanced end(%s)" % tag
- assert escape_cdata(tag) == self.__tags[-1],\
- "expected end(%s), got %s" % (self.__tags[-1], tag)
- else:
- assert self.__tags, "unbalanced end()"
- tag = self.__tags.pop()
- if self.__data:
- self.__flush(indent)
- elif self.__open:
- self.__open = 0
- self.__write("/>\n")
- return
- if indent:
- self.__write(self.__indentation[:len(self.__tags)])
- self.__write("</%s>\n" % tag)
-
- ##
- # Closes open elements, up to (and including) the element identified
- # by the given identifier.
- #
- # @param id Element identifier, as returned by the <b>start</b> method.
-
- def close(self, id):
- while len(self.__tags) > id:
- self.end()
-
- ##
- # Adds an entire element. This is the same as calling <b>start</b>,
- # <b>data</b>, and <b>end</b> in sequence. The <b>text</b> argument
- # can be omitted.
-
- def element(self, tag, text=None, attrib={}, **extra):
- self.start(*(tag, attrib), **extra)
- if text:
- self.data(text)
- self.end(indent=False)
-
- ##
- # Flushes the output stream.
-
- def flush(self):
- pass # replaced by the constructor
-
-# ----------------------------------------------------------------------
-
-def generate_transform(transform_list=[]):
- if len(transform_list):
- output = io.StringIO()
- for type, value in transform_list:
- if type == 'scale' and (value == (1.0,) or value == (1.0, 1.0)):
- continue
- if type == 'translate' and value == (0.0, 0.0):
- continue
- if type == 'rotate' and value == (0.0,):
- continue
- if type == 'matrix' and isinstance(value, Affine2DBase):
- value = value.to_values()
-
- output.write('%s(%s)' % (
- type, ' '.join(short_float_fmt(x) for x in value)))
- return output.getvalue()
- return ''
-
-def generate_css(attrib={}):
- if attrib:
- output = io.StringIO()
- attrib = sorted(six.iteritems(attrib))
- for k, v in attrib:
- k = escape_attrib(k)
- v = escape_attrib(v)
- output.write("%s:%s;" % (k, v))
- return output.getvalue()
- return ''
-
-_capstyle_d = {'projecting' : 'square', 'butt' : 'butt', 'round': 'round',}
-class RendererSVG(RendererBase):
- FONT_SCALE = 100.0
- fontd = maxdict(50)
-
- def __init__(self, width, height, svgwriter, basename=None, image_dpi=72):
- self.width = width
- self.height = height
- self.writer = XMLWriter(svgwriter)
- self.image_dpi = image_dpi # the actual dpi we want to rasterize stuff with
-
- self._groupd = {}
- if not rcParams['svg.image_inline']:
- assert basename is not None
- self.basename = basename
- self._imaged = {}
- self._clipd = OrderedDict()
- self._char_defs = {}
- self._markers = {}
- self._path_collection_id = 0
- self._imaged = {}
- self._hatchd = OrderedDict()
- self._has_gouraud = False
- self._n_gradients = 0
- self._fonts = OrderedDict()
- self.mathtext_parser = MathTextParser('SVG')
-
- RendererBase.__init__(self)
- self._glyph_map = dict()
- str_height = short_float_fmt(height)
- str_width = short_float_fmt(width)
- svgwriter.write(svgProlog)
- self._start_id = self.writer.start(
- 'svg',
- width='%spt' % str_width,
- height='%spt' % str_height,
- viewBox='0 0 %s %s' % (str_width, str_height),
- xmlns="http://www.w3.org/2000/svg",
- version="1.1",
- attrib={'xmlns:xlink': "http://www.w3.org/1999/xlink"})
- self._write_default_style()
-
- def finalize(self):
- self._write_clips()
- self._write_hatches()
- self._write_svgfonts()
- self.writer.close(self._start_id)
- self.writer.flush()
-
- def _write_default_style(self):
- writer = self.writer
- default_style = generate_css({
- 'stroke-linejoin': 'round',
- 'stroke-linecap': 'butt'})
- writer.start('defs')
- writer.start('style', type='text/css')
- writer.data('*{%s}\n' % default_style)
- writer.end('style')
- writer.end('defs')
-
- def _make_id(self, type, content):
- content = str(content)
- if rcParams['svg.hashsalt'] is None:
- salt = str(uuid.uuid4())
- else:
- salt = rcParams['svg.hashsalt']
- if six.PY3:
- content = content.encode('utf8')
- salt = salt.encode('utf8')
- m = hashlib.md5()
- m.update(salt)
- m.update(content)
- return '%s%s' % (type, m.hexdigest()[:10])
-
- def _make_flip_transform(self, transform):
- return (transform +
- Affine2D()
- .scale(1.0, -1.0)
- .translate(0.0, self.height))
-
- def _get_font(self, prop):
- fname = findfont(prop)
- font = get_font(fname)
- font.clear()
- size = prop.get_size_in_points()
- font.set_size(size, 72.0)
- return font
-
- def _get_hatch(self, gc, rgbFace):
- """
- Create a new hatch pattern
- """
- if rgbFace is not None:
- rgbFace = tuple(rgbFace)
- edge = gc.get_hatch_color()
- if edge is not None:
- edge = tuple(edge)
- dictkey = (gc.get_hatch(), rgbFace, edge)
- oid = self._hatchd.get(dictkey)
- if oid is None:
- oid = self._make_id('h', dictkey)
- self._hatchd[dictkey] = ((gc.get_hatch_path(), rgbFace, edge), oid)
- else:
- _, oid = oid
- return oid
-
- def _write_hatches(self):
- if not len(self._hatchd):
- return
- HATCH_SIZE = 72
- writer = self.writer
- writer.start('defs')
- for ((path, face, stroke), oid) in six.itervalues(self._hatchd):
- writer.start(
- 'pattern',
- id=oid,
- patternUnits="userSpaceOnUse",
- x="0", y="0", width=six.text_type(HATCH_SIZE),
- height=six.text_type(HATCH_SIZE))
- path_data = self._convert_path(
- path,
- Affine2D().scale(HATCH_SIZE).scale(1.0, -1.0).translate(0, HATCH_SIZE),
- simplify=False)
- if face is None:
- fill = 'none'
- else:
- fill = rgb2hex(face)
- writer.element(
- 'rect',
- x="0", y="0", width=six.text_type(HATCH_SIZE+1),
- height=six.text_type(HATCH_SIZE+1),
- fill=fill)
- writer.element(
- 'path',
- d=path_data,
- style=generate_css({
- 'fill': rgb2hex(stroke),
- 'stroke': rgb2hex(stroke),
- 'stroke-width': six.text_type(rcParams['hatch.linewidth']),
- 'stroke-linecap': 'butt',
- 'stroke-linejoin': 'miter'
- })
- )
- writer.end('pattern')
- writer.end('defs')
-
- def _get_style_dict(self, gc, rgbFace):
- """
- return the style string. style is generated from the
- GraphicsContext and rgbFace
- """
- attrib = {}
-
- forced_alpha = gc.get_forced_alpha()
-
- if gc.get_hatch() is not None:
- attrib['fill'] = "url(#%s)" % self._get_hatch(gc, rgbFace)
- if rgbFace is not None and len(rgbFace) == 4 and rgbFace[3] != 1.0 and not forced_alpha:
- attrib['fill-opacity'] = short_float_fmt(rgbFace[3])
- else:
- if rgbFace is None:
- attrib['fill'] = 'none'
- else:
- if tuple(rgbFace[:3]) != (0, 0, 0):
- attrib['fill'] = rgb2hex(rgbFace)
- if len(rgbFace) == 4 and rgbFace[3] != 1.0 and not forced_alpha:
- attrib['fill-opacity'] = short_float_fmt(rgbFace[3])
-
- if forced_alpha and gc.get_alpha() != 1.0:
- attrib['opacity'] = short_float_fmt(gc.get_alpha())
-
- offset, seq = gc.get_dashes()
- if seq is not None:
- attrib['stroke-dasharray'] = ','.join([short_float_fmt(val) for val in seq])
- attrib['stroke-dashoffset'] = short_float_fmt(float(offset))
-
- linewidth = gc.get_linewidth()
- if linewidth:
- rgb = gc.get_rgb()
- attrib['stroke'] = rgb2hex(rgb)
- if not forced_alpha and rgb[3] != 1.0:
- attrib['stroke-opacity'] = short_float_fmt(rgb[3])
- if linewidth != 1.0:
- attrib['stroke-width'] = short_float_fmt(linewidth)
- if gc.get_joinstyle() != 'round':
- attrib['stroke-linejoin'] = gc.get_joinstyle()
- if gc.get_capstyle() != 'butt':
- attrib['stroke-linecap'] = _capstyle_d[gc.get_capstyle()]
-
- return attrib
-
- def _get_style(self, gc, rgbFace):
- return generate_css(self._get_style_dict(gc, rgbFace))
-
- def _get_clip(self, gc):
- cliprect = gc.get_clip_rectangle()
- clippath, clippath_trans = gc.get_clip_path()
- if clippath is not None:
- clippath_trans = self._make_flip_transform(clippath_trans)
- dictkey = (id(clippath), str(clippath_trans))
- elif cliprect is not None:
- x, y, w, h = cliprect.bounds
- y = self.height-(y+h)
- dictkey = (x, y, w, h)
- else:
- return None
-
- clip = self._clipd.get(dictkey)
- if clip is None:
- oid = self._make_id('p', dictkey)
- if clippath is not None:
- self._clipd[dictkey] = ((clippath, clippath_trans), oid)
- else:
- self._clipd[dictkey] = (dictkey, oid)
- else:
- clip, oid = clip
- return oid
-
- def _write_clips(self):
- if not len(self._clipd):
- return
- writer = self.writer
- writer.start('defs')
- for clip, oid in six.itervalues(self._clipd):
- writer.start('clipPath', id=oid)
- if len(clip) == 2:
- clippath, clippath_trans = clip
- path_data = self._convert_path(clippath, clippath_trans, simplify=False)
- writer.element('path', d=path_data)
- else:
- x, y, w, h = clip
- writer.element(
- 'rect',
- x=short_float_fmt(x),
- y=short_float_fmt(y),
- width=short_float_fmt(w),
- height=short_float_fmt(h))
- writer.end('clipPath')
- writer.end('defs')
-
- def _write_svgfonts(self):
- if not rcParams['svg.fonttype'] == 'svgfont':
- return
-
- writer = self.writer
- writer.start('defs')
- for font_fname, chars in six.iteritems(self._fonts):
- font = get_font(font_fname)
- font.set_size(72, 72)
- sfnt = font.get_sfnt()
- writer.start('font', id=sfnt[1, 0, 0, 4].decode("mac_roman"))
- writer.element(
- 'font-face',
- attrib={
- 'font-family': font.family_name,
- 'font-style': font.style_name.lower(),
- 'units-per-em': '72',
- 'bbox': ' '.join(
- short_float_fmt(x / 64.0) for x in font.bbox)})
- for char in chars:
- glyph = font.load_char(char, flags=LOAD_NO_HINTING)
- verts, codes = font.get_path()
- path = Path(verts, codes)
- path_data = self._convert_path(path)
- # name = font.get_glyph_name(char)
- writer.element(
- 'glyph',
- d=path_data,
- attrib={
- # 'glyph-name': name,
- 'unicode': unichr(char),
- 'horiz-adv-x':
- short_float_fmt(glyph.linearHoriAdvance / 65536.0)})
- writer.end('font')
- writer.end('defs')
-
- def open_group(self, s, gid=None):
- """
- Open a grouping element with label *s*. If *gid* is given, use
- *gid* as the id of the group.
- """
- if gid:
- self.writer.start('g', id=gid)
- else:
- self._groupd[s] = self._groupd.get(s, 0) + 1
- self.writer.start('g', id="%s_%d" % (s, self._groupd[s]))
-
- def close_group(self, s):
- self.writer.end('g')
-
- def option_image_nocomposite(self):
- """
- return whether to generate a composite image from multiple images on
- a set of axes
- """
- return not rcParams['image.composite_image']
-
- def _convert_path(self, path, transform=None, clip=None, simplify=None,
- sketch=None):
- if clip:
- clip = (0.0, 0.0, self.width, self.height)
- else:
- clip = None
- return _path.convert_to_string(
- path, transform, clip, simplify, sketch, 6,
- [b'M', b'L', b'Q', b'C', b'z'], False).decode('ascii')
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- trans_and_flip = self._make_flip_transform(transform)
- clip = (rgbFace is None and gc.get_hatch_path() is None)
- simplify = path.should_simplify and clip
- path_data = self._convert_path(
- path, trans_and_flip, clip=clip, simplify=simplify,
- sketch=gc.get_sketch_params())
-
- attrib = {}
- attrib['style'] = self._get_style(gc, rgbFace)
-
- clipid = self._get_clip(gc)
- if clipid is not None:
- attrib['clip-path'] = 'url(#%s)' % clipid
-
- if gc.get_url() is not None:
- self.writer.start('a', {'xlink:href': gc.get_url()})
- self.writer.element('path', d=path_data, attrib=attrib)
- if gc.get_url() is not None:
- self.writer.end('a')
-
- def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
- if not len(path.vertices):
- return
-
- writer = self.writer
- path_data = self._convert_path(
- marker_path,
- marker_trans + Affine2D().scale(1.0, -1.0),
- simplify=False)
- style = self._get_style_dict(gc, rgbFace)
- dictkey = (path_data, generate_css(style))
- oid = self._markers.get(dictkey)
- style = generate_css({k: v for k, v in six.iteritems(style)
- if k.startswith('stroke')})
-
- if oid is None:
- oid = self._make_id('m', dictkey)
- writer.start('defs')
- writer.element('path', id=oid, d=path_data, style=style)
- writer.end('defs')
- self._markers[dictkey] = oid
-
- attrib = {}
- clipid = self._get_clip(gc)
- if clipid is not None:
- attrib['clip-path'] = 'url(#%s)' % clipid
- writer.start('g', attrib=attrib)
-
- trans_and_flip = self._make_flip_transform(trans)
- attrib = {'xlink:href': '#%s' % oid}
- clip = (0, 0, self.width*72, self.height*72)
- for vertices, code in path.iter_segments(
- trans_and_flip, clip=clip, simplify=False):
- if len(vertices):
- x, y = vertices[-2:]
- attrib['x'] = short_float_fmt(x)
- attrib['y'] = short_float_fmt(y)
- attrib['style'] = self._get_style(gc, rgbFace)
- writer.element('use', attrib=attrib)
- writer.end('g')
-
- def draw_path_collection(self, gc, master_transform, paths, all_transforms,
- offsets, offsetTrans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position):
- # Is the optimization worth it? Rough calculation:
- # cost of emitting a path in-line is
- # (len_path + 5) * uses_per_path
- # cost of definition+use is
- # (len_path + 3) + 9 * uses_per_path
- len_path = len(paths[0].vertices) if len(paths) > 0 else 0
- uses_per_path = self._iter_collection_uses_per_path(
- paths, all_transforms, offsets, facecolors, edgecolors)
- should_do_optimization = \
- len_path + 9 * uses_per_path + 3 < (len_path + 5) * uses_per_path
- if not should_do_optimization:
- return RendererBase.draw_path_collection(
- self, gc, master_transform, paths, all_transforms,
- offsets, offsetTrans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position)
-
- writer = self.writer
- path_codes = []
- writer.start('defs')
- for i, (path, transform) in enumerate(self._iter_collection_raw_paths(
- master_transform, paths, all_transforms)):
- transform = Affine2D(transform.get_matrix()).scale(1.0, -1.0)
- d = self._convert_path(path, transform, simplify=False)
- oid = 'C%x_%x_%s' % (self._path_collection_id, i,
- self._make_id('', d))
- writer.element('path', id=oid, d=d)
- path_codes.append(oid)
- writer.end('defs')
-
- for xo, yo, path_id, gc0, rgbFace in self._iter_collection(
- gc, master_transform, all_transforms, path_codes, offsets,
- offsetTrans, facecolors, edgecolors, linewidths, linestyles,
- antialiaseds, urls, offset_position):
- clipid = self._get_clip(gc0)
- url = gc0.get_url()
- if url is not None:
- writer.start('a', attrib={'xlink:href': url})
- if clipid is not None:
- writer.start('g', attrib={'clip-path': 'url(#%s)' % clipid})
- attrib = {
- 'xlink:href': '#%s' % path_id,
- 'x': short_float_fmt(xo),
- 'y': short_float_fmt(self.height - yo),
- 'style': self._get_style(gc0, rgbFace)
- }
- writer.element('use', attrib=attrib)
- if clipid is not None:
- writer.end('g')
- if url is not None:
- writer.end('a')
-
- self._path_collection_id += 1
-
- def draw_gouraud_triangle(self, gc, points, colors, trans):
- # This uses a method described here:
- #
- # http://www.svgopen.org/2005/papers/Converting3DFaceToSVG/index.html
- #
- # that uses three overlapping linear gradients to simulate a
- # Gouraud triangle. Each gradient goes from fully opaque in
- # one corner to fully transparent along the opposite edge.
- # The line between the stop points is perpendicular to the
- # opposite edge. Underlying these three gradients is a solid
- # triangle whose color is the average of all three points.
-
- writer = self.writer
- if not self._has_gouraud:
- self._has_gouraud = True
- writer.start(
- 'filter',
- id='colorAdd')
- writer.element(
- 'feComposite',
- attrib={'in': 'SourceGraphic'},
- in2='BackgroundImage',
- operator='arithmetic',
- k2="1", k3="1")
- writer.end('filter')
-
- avg_color = np.sum(colors[:, :], axis=0) / 3.0
- # Just skip fully-transparent triangles
- if avg_color[-1] == 0.0:
- return
-
- trans_and_flip = self._make_flip_transform(trans)
- tpoints = trans_and_flip.transform(points)
-
- writer.start('defs')
- for i in range(3):
- x1, y1 = tpoints[i]
- x2, y2 = tpoints[(i + 1) % 3]
- x3, y3 = tpoints[(i + 2) % 3]
- c = colors[i][:]
-
- if x2 == x3:
- xb = x2
- yb = y1
- elif y2 == y3:
- xb = x1
- yb = y2
- else:
- m1 = (y2 - y3) / (x2 - x3)
- b1 = y2 - (m1 * x2)
- m2 = -(1.0 / m1)
- b2 = y1 - (m2 * x1)
- xb = (-b1 + b2) / (m1 - m2)
- yb = m2 * xb + b2
-
- writer.start(
- 'linearGradient',
- id="GR%x_%d" % (self._n_gradients, i),
- x1=short_float_fmt(x1), y1=short_float_fmt(y1),
- x2=short_float_fmt(xb), y2=short_float_fmt(yb))
- writer.element(
- 'stop',
- offset='0',
- style=generate_css({'stop-color': rgb2hex(c),
- 'stop-opacity': short_float_fmt(c[-1])}))
- writer.element(
- 'stop',
- offset='1',
- style=generate_css({'stop-color': rgb2hex(c),
- 'stop-opacity': "0"}))
- writer.end('linearGradient')
-
- writer.element(
- 'polygon',
- id='GT%x' % self._n_gradients,
- points=" ".join([short_float_fmt(x)
- for x in (x1, y1, x2, y2, x3, y3)]))
- writer.end('defs')
-
- avg_color = np.sum(colors[:, :], axis=0) / 3.0
- href = '#GT%x' % self._n_gradients
- writer.element(
- 'use',
- attrib={'xlink:href': href,
- 'fill': rgb2hex(avg_color),
- 'fill-opacity': short_float_fmt(avg_color[-1])})
- for i in range(3):
- writer.element(
- 'use',
- attrib={'xlink:href': href,
- 'fill': 'url(#GR%x_%d)' % (self._n_gradients, i),
- 'fill-opacity': '1',
- 'filter': 'url(#colorAdd)'})
-
- self._n_gradients += 1
-
- def draw_gouraud_triangles(self, gc, triangles_array, colors_array,
- transform):
- attrib = {}
- clipid = self._get_clip(gc)
- if clipid is not None:
- attrib['clip-path'] = 'url(#%s)' % clipid
-
- self.writer.start('g', attrib=attrib)
-
- transform = transform.frozen()
- for tri, col in zip(triangles_array, colors_array):
- self.draw_gouraud_triangle(gc, tri, col, transform)
-
- self.writer.end('g')
-
- def option_scale_image(self):
- return True
-
- def get_image_magnification(self):
- return self.image_dpi / 72.0
-
- def draw_image(self, gc, x, y, im, transform=None):
- h, w = im.shape[:2]
-
- if w == 0 or h == 0:
- return
-
- attrib = {}
- clipid = self._get_clip(gc)
- if clipid is not None:
- # Can't apply clip-path directly to the image because the
- # image has a transformation, which would also be applied
- # to the clip-path
- self.writer.start('g', attrib={'clip-path': 'url(#%s)' % clipid})
-
- oid = gc.get_gid()
- url = gc.get_url()
- if url is not None:
- self.writer.start('a', attrib={'xlink:href': url})
- if rcParams['svg.image_inline']:
- bytesio = io.BytesIO()
- _png.write_png(im, bytesio)
- oid = oid or self._make_id('image', bytesio.getvalue())
- attrib['xlink:href'] = (
- "data:image/png;base64,\n" +
- base64.b64encode(bytesio.getvalue()).decode('ascii'))
- else:
- self._imaged[self.basename] = self._imaged.get(self.basename, 0) + 1
- filename = '%s.image%d.png'%(self.basename, self._imaged[self.basename])
- _log.info('Writing image file for inclusion: %s', filename)
- _png.write_png(im, filename)
- oid = oid or 'Im_' + self._make_id('image', filename)
- attrib['xlink:href'] = filename
-
- attrib['id'] = oid
-
- if transform is None:
- w = 72.0 * w / self.image_dpi
- h = 72.0 * h / self.image_dpi
-
- self.writer.element(
- 'image',
- transform=generate_transform([
- ('scale', (1, -1)), ('translate', (0, -h))]),
- x=short_float_fmt(x),
- y=short_float_fmt(-(self.height - y - h)),
- width=short_float_fmt(w), height=short_float_fmt(h),
- attrib=attrib)
- else:
- alpha = gc.get_alpha()
- if alpha != 1.0:
- attrib['opacity'] = short_float_fmt(alpha)
-
- flipped = (
- Affine2D().scale(1.0 / w, 1.0 / h) +
- transform +
- Affine2D()
- .translate(x, y)
- .scale(1.0, -1.0)
- .translate(0.0, self.height))
-
- attrib['transform'] = generate_transform(
- [('matrix', flipped.frozen())])
- self.writer.element(
- 'image',
- width=short_float_fmt(w), height=short_float_fmt(h),
- attrib=attrib)
-
- if url is not None:
- self.writer.end('a')
- if clipid is not None:
- self.writer.end('g')
-
- def _adjust_char_id(self, char_id):
- return char_id.replace("%20", "_")
-
- def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath, mtext=None):
- """
- draw the text by converting them to paths using textpath module.
-
- Parameters
- ----------
- prop : `matplotlib.font_manager.FontProperties`
- font property
-
- s : str
- text to be converted
-
- usetex : bool
- If True, use matplotlib usetex mode.
-
- ismath : bool
- If True, use mathtext parser. If "TeX", use *usetex* mode.
-
- """
- writer = self.writer
-
- writer.comment(s)
-
- glyph_map=self._glyph_map
-
- text2path = self._text2path
- color = rgb2hex(gc.get_rgb())
- fontsize = prop.get_size_in_points()
-
- style = {}
- if color != '#000000':
- style['fill'] = color
- if gc.get_alpha() != 1.0:
- style['opacity'] = short_float_fmt(gc.get_alpha())
-
- if not ismath:
- font = text2path._get_font(prop)
- _glyphs = text2path.get_glyphs_with_font(
- font, s, glyph_map=glyph_map, return_new_glyphs_only=True)
- glyph_info, glyph_map_new, rects = _glyphs
-
- if glyph_map_new:
- writer.start('defs')
- for char_id, glyph_path in six.iteritems(glyph_map_new):
- path = Path(*glyph_path)
- path_data = self._convert_path(path, simplify=False)
- writer.element('path', id=char_id, d=path_data)
- writer.end('defs')
-
- glyph_map.update(glyph_map_new)
-
- attrib = {}
- attrib['style'] = generate_css(style)
- font_scale = fontsize / text2path.FONT_SCALE
- attrib['transform'] = generate_transform([
- ('translate', (x, y)),
- ('rotate', (-angle,)),
- ('scale', (font_scale, -font_scale))])
-
- writer.start('g', attrib=attrib)
- for glyph_id, xposition, yposition, scale in glyph_info:
- attrib={'xlink:href': '#%s' % glyph_id}
- if xposition != 0.0:
- attrib['x'] = short_float_fmt(xposition)
- if yposition != 0.0:
- attrib['y'] = short_float_fmt(yposition)
- writer.element(
- 'use',
- attrib=attrib)
-
- writer.end('g')
- else:
- if ismath == "TeX":
- _glyphs = text2path.get_glyphs_tex(prop, s, glyph_map=glyph_map,
- return_new_glyphs_only=True)
- else:
- _glyphs = text2path.get_glyphs_mathtext(prop, s, glyph_map=glyph_map,
- return_new_glyphs_only=True)
-
- glyph_info, glyph_map_new, rects = _glyphs
-
- # we store the character glyphs w/o flipping. Instead, the
- # coordinate will be flipped when this characters are
- # used.
- if glyph_map_new:
- writer.start('defs')
- for char_id, glyph_path in six.iteritems(glyph_map_new):
- char_id = self._adjust_char_id(char_id)
- # Some characters are blank
- if not len(glyph_path[0]):
- path_data = ""
- else:
- path = Path(*glyph_path)
- path_data = self._convert_path(path, simplify=False)
- writer.element('path', id=char_id, d=path_data)
- writer.end('defs')
-
- glyph_map.update(glyph_map_new)
-
- attrib = {}
- font_scale = fontsize / text2path.FONT_SCALE
- attrib['style'] = generate_css(style)
- attrib['transform'] = generate_transform([
- ('translate', (x, y)),
- ('rotate', (-angle,)),
- ('scale', (font_scale, -font_scale))])
-
- writer.start('g', attrib=attrib)
- for char_id, xposition, yposition, scale in glyph_info:
- char_id = self._adjust_char_id(char_id)
-
- writer.element(
- 'use',
- transform=generate_transform([
- ('translate', (xposition, yposition)),
- ('scale', (scale,)),
- ]),
- attrib={'xlink:href': '#%s' % char_id})
-
- for verts, codes in rects:
- path = Path(verts, codes)
- path_data = self._convert_path(path, simplify=False)
- writer.element('path', d=path_data)
-
- writer.end('g')
-
- def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
- writer = self.writer
-
- color = rgb2hex(gc.get_rgb())
- style = {}
- if color != '#000000':
- style['fill'] = color
- if gc.get_alpha() != 1.0:
- style['opacity'] = short_float_fmt(gc.get_alpha())
-
- if not ismath:
- font = self._get_font(prop)
- font.set_text(s, 0.0, flags=LOAD_NO_HINTING)
-
- fontsize = prop.get_size_in_points()
-
- fontfamily = font.family_name
- fontstyle = prop.get_style()
-
- attrib = {}
- # Must add "px" to workaround a Firefox bug
- style['font-size'] = short_float_fmt(fontsize) + 'px'
- style['font-family'] = six.text_type(fontfamily)
- style['font-style'] = prop.get_style().lower()
- style['font-weight'] = six.text_type(prop.get_weight()).lower()
- attrib['style'] = generate_css(style)
-
- if mtext and (angle == 0 or mtext.get_rotation_mode() == "anchor"):
- # If text anchoring can be supported, get the original
- # coordinates and add alignment information.
-
- # Get anchor coordinates.
- transform = mtext.get_transform()
- ax, ay = transform.transform_point(mtext.get_position())
- ay = self.height - ay
-
- # Don't do vertical anchor alignment. Most applications do not
- # support 'alignment-baseline' yet. Apply the vertical layout
- # to the anchor point manually for now.
- angle_rad = np.deg2rad(angle)
- dir_vert = np.array([np.sin(angle_rad), np.cos(angle_rad)])
- v_offset = np.dot(dir_vert, [(x - ax), (y - ay)])
- ax = ax + v_offset * dir_vert[0]
- ay = ay + v_offset * dir_vert[1]
-
- ha_mpl_to_svg = {'left': 'start', 'right': 'end',
- 'center': 'middle'}
- style['text-anchor'] = ha_mpl_to_svg[mtext.get_ha()]
-
- attrib['x'] = short_float_fmt(ax)
- attrib['y'] = short_float_fmt(ay)
- attrib['style'] = generate_css(style)
- attrib['transform'] = "rotate(%s, %s, %s)" % (
- short_float_fmt(-angle),
- short_float_fmt(ax),
- short_float_fmt(ay))
- writer.element('text', s, attrib=attrib)
- else:
- attrib['transform'] = generate_transform([
- ('translate', (x, y)),
- ('rotate', (-angle,))])
-
- writer.element('text', s, attrib=attrib)
-
- if rcParams['svg.fonttype'] == 'svgfont':
- fontset = self._fonts.setdefault(font.fname, set())
- for c in s:
- fontset.add(ord(c))
- else:
- writer.comment(s)
-
- width, height, descent, svg_elements, used_characters = \
- self.mathtext_parser.parse(s, 72, prop)
- svg_glyphs = svg_elements.svg_glyphs
- svg_rects = svg_elements.svg_rects
-
- attrib = {}
- attrib['style'] = generate_css(style)
- attrib['transform'] = generate_transform([
- ('translate', (x, y)),
- ('rotate', (-angle,))])
-
- # Apply attributes to 'g', not 'text', because we likely
- # have some rectangles as well with the same style and
- # transformation
- writer.start('g', attrib=attrib)
-
- writer.start('text')
-
- # Sort the characters by font, and output one tspan for
- # each
- spans = OrderedDict()
- for font, fontsize, thetext, new_x, new_y, metrics in svg_glyphs:
- style = generate_css({
- 'font-size': short_float_fmt(fontsize) + 'px',
- 'font-family': font.family_name,
- 'font-style': font.style_name.lower(),
- 'font-weight': font.style_name.lower()})
- if thetext == 32:
- thetext = 0xa0 # non-breaking space
- spans.setdefault(style, []).append((new_x, -new_y, thetext))
-
- if rcParams['svg.fonttype'] == 'svgfont':
- for font, fontsize, thetext, new_x, new_y, metrics in svg_glyphs:
- fontset = self._fonts.setdefault(font.fname, set())
- fontset.add(thetext)
-
- for style, chars in six.iteritems(spans):
- chars.sort()
-
- same_y = True
- if len(chars) > 1:
- last_y = chars[0][1]
- for i in xrange(1, len(chars)):
- if chars[i][1] != last_y:
- same_y = False
- break
- if same_y:
- ys = six.text_type(chars[0][1])
- else:
- ys = ' '.join(six.text_type(c[1]) for c in chars)
-
- attrib = {
- 'style': style,
- 'x': ' '.join(short_float_fmt(c[0]) for c in chars),
- 'y': ys
- }
-
- writer.element(
- 'tspan',
- ''.join(unichr(c[2]) for c in chars),
- attrib=attrib)
-
- writer.end('text')
-
- if len(svg_rects):
- for x, y, width, height in svg_rects:
- writer.element(
- 'rect',
- x=short_float_fmt(x),
- y=short_float_fmt(-y + height),
- width=short_float_fmt(width),
- height=short_float_fmt(height)
- )
-
- writer.end('g')
-
- def draw_tex(self, gc, x, y, s, prop, angle, ismath='TeX!', mtext=None):
- self._draw_text_as_path(gc, x, y, s, prop, angle, ismath="TeX")
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- clipid = self._get_clip(gc)
- if clipid is not None:
- # Cannot apply clip-path directly to the text, because
- # is has a transformation
- self.writer.start(
- 'g', attrib={'clip-path': 'url(#%s)' % clipid})
-
- if gc.get_url() is not None:
- self.writer.start('a', {'xlink:href': gc.get_url()})
-
- if rcParams['svg.fonttype'] == 'path':
- self._draw_text_as_path(gc, x, y, s, prop, angle, ismath, mtext)
- else:
- self._draw_text_as_text(gc, x, y, s, prop, angle, ismath, mtext)
-
- if gc.get_url() is not None:
- self.writer.end('a')
-
- if clipid is not None:
- self.writer.end('g')
-
- def flipy(self):
- return True
-
- def get_canvas_width_height(self):
- return self.width, self.height
-
- def get_text_width_height_descent(self, s, prop, ismath):
- return self._text2path.get_text_width_height_descent(s, prop, ismath)
-
-
-class FigureCanvasSVG(FigureCanvasBase):
- filetypes = {'svg': 'Scalable Vector Graphics',
- 'svgz': 'Scalable Vector Graphics'}
-
- fixed_dpi = 72
-
- def print_svg(self, filename, *args, **kwargs):
- with cbook.open_file_cm(filename, "w", encoding="utf-8") as fh:
-
- filename = getattr(fh, 'name', '')
- if not isinstance(filename, six.string_types):
- filename = ''
-
- if cbook.file_requires_unicode(fh):
- detach = False
- else:
- if six.PY3:
- fh = io.TextIOWrapper(fh, 'utf-8')
- else:
- fh = codecs.getwriter('utf-8')(fh)
- detach = True
-
- result = self._print_svg(filename, fh, **kwargs)
-
- # Detach underlying stream from wrapper so that it remains open in
- # the caller.
- if detach:
- if six.PY3:
- fh.detach()
- else:
- fh.reset()
- fh.stream = io.BytesIO()
-
- return result
-
- def print_svgz(self, filename, *args, **kwargs):
- with cbook.open_file_cm(filename, "wb") as fh, \
- gzip.GzipFile(mode='w', fileobj=fh) as gzipwriter:
- return self.print_svg(gzipwriter)
-
- def _print_svg(self, filename, fh, **kwargs):
- image_dpi = kwargs.pop("dpi", 72)
- self.figure.set_dpi(72.0)
- width, height = self.figure.get_size_inches()
- w, h = width * 72, height * 72
-
- _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None)
- renderer = MixedModeRenderer(
- self.figure, width, height, image_dpi,
- RendererSVG(w, h, fh, filename, image_dpi),
- bbox_inches_restore=_bbox_inches_restore)
-
- self.figure.draw(renderer)
- renderer.finalize()
-
- def get_default_filetype(self):
- return 'svg'
-
-class FigureManagerSVG(FigureManagerBase):
- pass
-
-
-svgProlog = """\
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-"""
-
-
-@_Backend.export
-class _BackendSVG(_Backend):
- FigureCanvas = FigureCanvasSVG
- FigureManager = FigureManagerSVG
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_template.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_template.py
deleted file mode 100644
index 524ca73285..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_template.py
+++ /dev/null
@@ -1,278 +0,0 @@
-"""
-This is a fully functional do nothing backend to provide a template to
-backend writers. It is fully functional in that you can select it as
-a backend with
-
- import matplotlib
- matplotlib.use('Template')
-
-and your matplotlib scripts will (should!) run without error, though
-no output is produced. This provides a nice starting point for
-backend writers because you can selectively implement methods
-(draw_rectangle, draw_lines, etc...) and slowly see your figure come
-to life w/o having to have a full blown implementation before getting
-any results.
-
-Copy this to backend_xxx.py and replace all instances of 'template'
-with 'xxx'. Then implement the class methods and functions below, and
-add 'xxx' to the switchyard in matplotlib/backends/__init__.py and
-'xxx' to the backends list in the validate_backend methon in
-matplotlib/__init__.py and you're off. You can use your backend with::
-
- import matplotlib
- matplotlib.use('xxx')
- from pylab import *
- plot([1,2,3])
- show()
-
-matplotlib also supports external backends, so you can place you can
-use any module in your PYTHONPATH with the syntax::
-
- import matplotlib
- matplotlib.use('module://my_backend')
-
-where my_backend.py is your module name. This syntax is also
-recognized in the rc file and in the -d argument in pylab, e.g.,::
-
- python simple_plot.py -dmodule://my_backend
-
-If your backend implements support for saving figures (i.e. has a print_xyz()
-method) you can register it as the default handler for a given file type
-
- from matplotlib.backend_bases import register_backend
- register_backend('xyz', 'my_backend', 'XYZ File Format')
- ...
- plt.savefig("figure.xyz")
-
-The files that are most relevant to backend_writers are
-
- matplotlib/backends/backend_your_backend.py
- matplotlib/backend_bases.py
- matplotlib/backends/__init__.py
- matplotlib/__init__.py
- matplotlib/_pylab_helpers.py
-
-Naming Conventions
-
- * classes Upper or MixedUpperCase
-
- * variables lower or lowerUpper
-
- * functions lower or underscore_separated
-
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import (
- FigureCanvasBase, FigureManagerBase, GraphicsContextBase, RendererBase)
-from matplotlib.figure import Figure
-
-
-class RendererTemplate(RendererBase):
- """
- The renderer handles drawing/rendering operations.
-
- This is a minimal do-nothing class that can be used to get started when
- writing a new backend. Refer to backend_bases.RendererBase for
- documentation of the classes methods.
- """
- def __init__(self, dpi):
- self.dpi = dpi
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- pass
-
- # draw_markers is optional, and we get more correct relative
- # timings by leaving it out. backend implementers concerned with
- # performance will probably want to implement it
-# def draw_markers(self, gc, marker_path, marker_trans, path, trans,
-# rgbFace=None):
-# pass
-
- # draw_path_collection is optional, and we get more correct
- # relative timings by leaving it out. backend implementers concerned with
- # performance will probably want to implement it
-# def draw_path_collection(self, gc, master_transform, paths,
-# all_transforms, offsets, offsetTrans,
-# facecolors, edgecolors, linewidths, linestyles,
-# antialiaseds):
-# pass
-
- # draw_quad_mesh is optional, and we get more correct
- # relative timings by leaving it out. backend implementers concerned with
- # performance will probably want to implement it
-# def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight,
-# coordinates, offsets, offsetTrans, facecolors,
-# antialiased, edgecolors):
-# pass
-
- def draw_image(self, gc, x, y, im):
- pass
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- pass
-
- def flipy(self):
- return True
-
- def get_canvas_width_height(self):
- return 100, 100
-
- def get_text_width_height_descent(self, s, prop, ismath):
- return 1, 1, 1
-
- def new_gc(self):
- return GraphicsContextTemplate()
-
- def points_to_pixels(self, points):
- # if backend doesn't have dpi, e.g., postscript or svg
- return points
- # elif backend assumes a value for pixels_per_inch
- #return points/72.0 * self.dpi.get() * pixels_per_inch/72.0
- # else
- #return points/72.0 * self.dpi.get()
-
-
-class GraphicsContextTemplate(GraphicsContextBase):
- """
- The graphics context provides the color, line styles, etc... See the gtk
- and postscript backends for examples of mapping the graphics context
- attributes (cap styles, join styles, line widths, colors) to a particular
- backend. In GTK this is done by wrapping a gtk.gdk.GC object and
- forwarding the appropriate calls to it using a dictionary mapping styles
- to gdk constants. In Postscript, all the work is done by the renderer,
- mapping line styles to postscript calls.
-
- If it's more appropriate to do the mapping at the renderer level (as in
- the postscript backend), you don't need to override any of the GC methods.
- If it's more appropriate to wrap an instance (as in the GTK backend) and
- do the mapping here, you'll need to override several of the setter
- methods.
-
- The base GraphicsContext stores colors as a RGB tuple on the unit
- interval, e.g., (0.5, 0.0, 1.0). You may need to map this to colors
- appropriate for your backend.
- """
- pass
-
-
-
-########################################################################
-#
-# The following functions and classes are for pylab and implement
-# window/figure managers, etc...
-#
-########################################################################
-
-def draw_if_interactive():
- """
- For image backends - is not required
- For GUI backends - this should be overridden if drawing should be done in
- interactive python mode
- """
-
-
-def show(block=None):
- """
- For image backends - is not required
- For GUI backends - show() is usually the last line of a pylab script and
- tells the backend that it is time to draw. In interactive mode, this may
- be a do nothing func. See the GTK backend for an example of how to handle
- interactive versus batch mode
- """
- for manager in Gcf.get_all_fig_managers():
- # do something to display the GUI
- pass
-
-
-def new_figure_manager(num, *args, **kwargs):
- """
- Create a new figure manager instance
- """
- # May be implemented via the `_new_figure_manager_template` helper.
- # If a main-level app must be created, this (and
- # new_figure_manager_given_figure) is the usual place to do it -- see
- # backend_wx, backend_wxagg and backend_tkagg for examples. Not all GUIs
- # require explicit instantiation of a main-level app (egg backend_gtk,
- # backend_gtkagg) for pylab.
- FigureClass = kwargs.pop('FigureClass', Figure)
- thisFig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, thisFig)
-
-
-def new_figure_manager_given_figure(num, figure):
- """
- Create a new figure manager instance for the given figure.
- """
- # May be implemented via the `_new_figure_manager_template` helper.
- canvas = FigureCanvasTemplate(figure)
- manager = FigureManagerTemplate(canvas, num)
- return manager
-
-
-class FigureCanvasTemplate(FigureCanvasBase):
- """
- The canvas the figure renders into. Calls the draw and print fig
- methods, creates the renderers, etc...
-
- Note GUI templates will want to connect events for button presses,
- mouse movements and key presses to functions that call the base
- class methods button_press_event, button_release_event,
- motion_notify_event, key_press_event, and key_release_event. See,
- e.g., backend_gtk.py, backend_wx.py and backend_tkagg.py
-
- Attributes
- ----------
- figure : `matplotlib.figure.Figure`
- A high-level Figure instance
-
- """
-
- def draw(self):
- """
- Draw the figure using the renderer
- """
- renderer = RendererTemplate(self.figure.dpi)
- self.figure.draw(renderer)
-
- # You should provide a print_xxx function for every file format
- # you can write.
-
- # If the file type is not in the base set of filetypes,
- # you should add it to the class-scope filetypes dictionary as follows:
- filetypes = FigureCanvasBase.filetypes.copy()
- filetypes['foo'] = 'My magic Foo format'
-
- def print_foo(self, filename, *args, **kwargs):
- """
- Write out format foo. The dpi, facecolor and edgecolor are restored
- to their original values after this call, so you don't need to
- save and restore them.
- """
- pass
-
- def get_default_filetype(self):
- return 'foo'
-
-
-class FigureManagerTemplate(FigureManagerBase):
- """
- Wrap everything up into a window for the pylab interface
-
- For non interactive backends, the base class does all the work
- """
- pass
-
-########################################################################
-#
-# Now just provide the standard names that backend.__init__ is expecting
-#
-########################################################################
-
-FigureCanvas = FigureCanvasTemplate
-FigureManager = FigureManagerTemplate
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_tkagg.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_tkagg.py
deleted file mode 100644
index 9511326e4a..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_tkagg.py
+++ /dev/null
@@ -1,34 +0,0 @@
-from __future__ import absolute_import, division, print_function
-
-from .. import cbook
-from . import tkagg # Paint image to Tk photo blitter extension.
-from .backend_agg import FigureCanvasAgg
-from ._backend_tk import (
- _BackendTk, FigureCanvasTk, FigureManagerTk, NavigationToolbar2Tk)
-
-
-class FigureCanvasTkAgg(FigureCanvasAgg, FigureCanvasTk):
- def draw(self):
- super(FigureCanvasTkAgg, self).draw()
- tkagg.blit(self._tkphoto, self.renderer._renderer, colormode=2)
- self._master.update_idletasks()
-
- def blit(self, bbox=None):
- tkagg.blit(
- self._tkphoto, self.renderer._renderer, bbox=bbox, colormode=2)
- self._master.update_idletasks()
-
-
-@cbook.deprecated("2.2")
-class FigureManagerTkAgg(FigureManagerTk):
- pass
-
-
-@cbook.deprecated("2.2")
-class NavigationToolbar2TkAgg(NavigationToolbar2Tk):
- pass
-
-
-@_BackendTk.export
-class _BackendTkAgg(_BackendTk):
- FigureCanvas = FigureCanvasTkAgg
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_tkcairo.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_tkcairo.py
deleted file mode 100644
index c4edfb97ed..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_tkcairo.py
+++ /dev/null
@@ -1,37 +0,0 @@
-from __future__ import absolute_import, division, print_function
-
-import sys
-
-import numpy as np
-
-from . import tkagg # Paint image to Tk photo blitter extension.
-from .backend_cairo import cairo, FigureCanvasCairo, RendererCairo
-from ._backend_tk import _BackendTk, FigureCanvasTk
-
-
-class FigureCanvasTkCairo(FigureCanvasCairo, FigureCanvasTk):
- def __init__(self, *args, **kwargs):
- super(FigureCanvasTkCairo, self).__init__(*args, **kwargs)
- self._renderer = RendererCairo(self.figure.dpi)
-
- def draw(self):
- width = int(self.figure.bbox.width)
- height = int(self.figure.bbox.height)
- surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
- self._renderer.set_ctx_from_surface(surface)
- self._renderer.set_width_height(width, height)
- self.figure.draw(self._renderer)
- buf = np.reshape(surface.get_data(), (height, width, 4))
- # Convert from ARGB32 to RGBA8888. Using .take() instead of directly
- # indexing ensures C-contiguity of the result, which is needed by
- # tkagg.
- buf = buf.take(
- [2, 1, 0, 3] if sys.byteorder == "little" else [1, 2, 3, 0],
- axis=2)
- tkagg.blit(self._tkphoto, buf, colormode=2)
- self._master.update_idletasks()
-
-
-@_BackendTk.export
-class _BackendTkCairo(_BackendTk):
- FigureCanvas = FigureCanvasTkCairo
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_webagg.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_webagg.py
deleted file mode 100644
index c917a162ab..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_webagg.py
+++ /dev/null
@@ -1,350 +0,0 @@
-"""
-Displays Agg images in the browser, with interactivity
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-# The WebAgg backend is divided into two modules:
-#
-# - `backend_webagg_core.py` contains code necessary to embed a WebAgg
-# plot inside of a web application, and communicate in an abstract
-# way over a web socket.
-#
-# - `backend_webagg.py` contains a concrete implementation of a basic
-# application, implemented with tornado.
-
-import six
-
-from contextlib import contextmanager
-import errno
-import json
-import os
-import random
-import sys
-import signal
-import socket
-import threading
-
-try:
- import tornado
-except ImportError:
- raise RuntimeError("The WebAgg backend requires Tornado.")
-
-import tornado.web
-import tornado.ioloop
-import tornado.websocket
-
-from matplotlib import rcParams
-from matplotlib.backend_bases import _Backend
-from matplotlib._pylab_helpers import Gcf
-from . import backend_webagg_core as core
-from .backend_webagg_core import TimerTornado
-
-
-class ServerThread(threading.Thread):
- def run(self):
- tornado.ioloop.IOLoop.instance().start()
-
-webagg_server_thread = ServerThread()
-
-
-class FigureCanvasWebAgg(core.FigureCanvasWebAggCore):
- def show(self):
- # show the figure window
- show()
-
- def new_timer(self, *args, **kwargs):
- return TimerTornado(*args, **kwargs)
-
-
-class WebAggApplication(tornado.web.Application):
- initialized = False
- started = False
-
- class FavIcon(tornado.web.RequestHandler):
- def get(self):
- image_path = os.path.join(
- os.path.dirname(os.path.dirname(__file__)),
- 'mpl-data', 'images')
-
- self.set_header('Content-Type', 'image/png')
- with open(os.path.join(image_path,
- 'matplotlib.png'), 'rb') as fd:
- self.write(fd.read())
-
- class SingleFigurePage(tornado.web.RequestHandler):
- def __init__(self, application, request, **kwargs):
- self.url_prefix = kwargs.pop('url_prefix', '')
- tornado.web.RequestHandler.__init__(self, application,
- request, **kwargs)
-
- def get(self, fignum):
- fignum = int(fignum)
- manager = Gcf.get_fig_manager(fignum)
-
- ws_uri = 'ws://{req.host}{prefix}/'.format(req=self.request,
- prefix=self.url_prefix)
- self.render(
- "single_figure.html",
- prefix=self.url_prefix,
- ws_uri=ws_uri,
- fig_id=fignum,
- toolitems=core.NavigationToolbar2WebAgg.toolitems,
- canvas=manager.canvas)
-
- class AllFiguresPage(tornado.web.RequestHandler):
- def __init__(self, application, request, **kwargs):
- self.url_prefix = kwargs.pop('url_prefix', '')
- tornado.web.RequestHandler.__init__(self, application,
- request, **kwargs)
-
- def get(self):
- ws_uri = 'ws://{req.host}{prefix}/'.format(req=self.request,
- prefix=self.url_prefix)
- self.render(
- "all_figures.html",
- prefix=self.url_prefix,
- ws_uri=ws_uri,
- figures=sorted(Gcf.figs.items()),
- toolitems=core.NavigationToolbar2WebAgg.toolitems)
-
- class MplJs(tornado.web.RequestHandler):
- def get(self):
- self.set_header('Content-Type', 'application/javascript')
-
- js_content = core.FigureManagerWebAgg.get_javascript()
-
- self.write(js_content)
-
- class Download(tornado.web.RequestHandler):
- def get(self, fignum, fmt):
- fignum = int(fignum)
- manager = Gcf.get_fig_manager(fignum)
-
- # TODO: Move this to a central location
- mimetypes = {
- 'ps': 'application/postscript',
- 'eps': 'application/postscript',
- 'pdf': 'application/pdf',
- 'svg': 'image/svg+xml',
- 'png': 'image/png',
- 'jpeg': 'image/jpeg',
- 'tif': 'image/tiff',
- 'emf': 'application/emf'
- }
-
- self.set_header('Content-Type', mimetypes.get(fmt, 'binary'))
-
- buff = six.BytesIO()
- manager.canvas.figure.savefig(buff, format=fmt)
- self.write(buff.getvalue())
-
- class WebSocket(tornado.websocket.WebSocketHandler):
- supports_binary = True
-
- def open(self, fignum):
- self.fignum = int(fignum)
- self.manager = Gcf.get_fig_manager(self.fignum)
- self.manager.add_web_socket(self)
- if hasattr(self, 'set_nodelay'):
- self.set_nodelay(True)
-
- def on_close(self):
- self.manager.remove_web_socket(self)
-
- def on_message(self, message):
- message = json.loads(message)
- # The 'supports_binary' message is on a client-by-client
- # basis. The others affect the (shared) canvas as a
- # whole.
- if message['type'] == 'supports_binary':
- self.supports_binary = message['value']
- else:
- manager = Gcf.get_fig_manager(self.fignum)
- # It is possible for a figure to be closed,
- # but a stale figure UI is still sending messages
- # from the browser.
- if manager is not None:
- manager.handle_json(message)
-
- def send_json(self, content):
- self.write_message(json.dumps(content))
-
- def send_binary(self, blob):
- if self.supports_binary:
- self.write_message(blob, binary=True)
- else:
- data_uri = "data:image/png;base64,{0}".format(
- blob.encode('base64').replace('\n', ''))
- self.write_message(data_uri)
-
- def __init__(self, url_prefix=''):
- if url_prefix:
- assert url_prefix[0] == '/' and url_prefix[-1] != '/', \
- 'url_prefix must start with a "/" and not end with one.'
-
- super(WebAggApplication, self).__init__(
- [
- # Static files for the CSS and JS
- (url_prefix + r'/_static/(.*)',
- tornado.web.StaticFileHandler,
- {'path': core.FigureManagerWebAgg.get_static_file_path()}),
-
- # An MPL favicon
- (url_prefix + r'/favicon.ico', self.FavIcon),
-
- # The page that contains all of the pieces
- (url_prefix + r'/([0-9]+)', self.SingleFigurePage,
- {'url_prefix': url_prefix}),
-
- # The page that contains all of the figures
- (url_prefix + r'/?', self.AllFiguresPage,
- {'url_prefix': url_prefix}),
-
- (url_prefix + r'/js/mpl.js', self.MplJs),
-
- # Sends images and events to the browser, and receives
- # events from the browser
- (url_prefix + r'/([0-9]+)/ws', self.WebSocket),
-
- # Handles the downloading (i.e., saving) of static images
- (url_prefix + r'/([0-9]+)/download.([a-z0-9.]+)',
- self.Download),
- ],
- template_path=core.FigureManagerWebAgg.get_static_file_path())
-
- @classmethod
- def initialize(cls, url_prefix='', port=None, address=None):
- if cls.initialized:
- return
-
- # Create the class instance
- app = cls(url_prefix=url_prefix)
-
- cls.url_prefix = url_prefix
-
- # This port selection algorithm is borrowed, more or less
- # verbatim, from IPython.
- def random_ports(port, n):
- """
- Generate a list of n random ports near the given port.
-
- The first 5 ports will be sequential, and the remaining n-5 will be
- randomly selected in the range [port-2*n, port+2*n].
- """
- for i in range(min(5, n)):
- yield port + i
- for i in range(n - 5):
- yield port + random.randint(-2 * n, 2 * n)
-
- success = None
-
- if address is None:
- cls.address = rcParams['webagg.address']
- else:
- cls.address = address
- cls.port = rcParams['webagg.port']
- for port in random_ports(cls.port, rcParams['webagg.port_retries']):
- try:
- app.listen(port, cls.address)
- except socket.error as e:
- if e.errno != errno.EADDRINUSE:
- raise
- else:
- cls.port = port
- success = True
- break
-
- if not success:
- raise SystemExit(
- "The webagg server could not be started because an available "
- "port could not be found")
-
- cls.initialized = True
-
- @classmethod
- def start(cls):
- if cls.started:
- return
-
- """
- IOLoop.running() was removed as of Tornado 2.4; see for example
- https://groups.google.com/forum/#!topic/python-tornado/QLMzkpQBGOY
- Thus there is no correct way to check if the loop has already been
- launched. We may end up with two concurrently running loops in that
- unlucky case with all the expected consequences.
- """
- ioloop = tornado.ioloop.IOLoop.instance()
-
- def shutdown():
- ioloop.stop()
- print("Server is stopped")
- sys.stdout.flush()
- cls.started = False
-
- @contextmanager
- def catch_sigint():
- old_handler = signal.signal(
- signal.SIGINT,
- lambda sig, frame: ioloop.add_callback_from_signal(shutdown))
- try:
- yield
- finally:
- signal.signal(signal.SIGINT, old_handler)
-
- # Set the flag to True *before* blocking on ioloop.start()
- cls.started = True
-
- print("Press Ctrl+C to stop WebAgg server")
- sys.stdout.flush()
- with catch_sigint():
- ioloop.start()
-
-
-def ipython_inline_display(figure):
- import tornado.template
-
- WebAggApplication.initialize()
- if not webagg_server_thread.is_alive():
- webagg_server_thread.start()
-
- with open(os.path.join(
- core.FigureManagerWebAgg.get_static_file_path(),
- 'ipython_inline_figure.html')) as fd:
- tpl = fd.read()
-
- fignum = figure.number
-
- t = tornado.template.Template(tpl)
- return t.generate(
- prefix=WebAggApplication.url_prefix,
- fig_id=fignum,
- toolitems=core.NavigationToolbar2WebAgg.toolitems,
- canvas=figure.canvas,
- port=WebAggApplication.port).decode('utf-8')
-
-
-@_Backend.export
-class _BackendWebAgg(_Backend):
- FigureCanvas = FigureCanvasWebAgg
- FigureManager = core.FigureManagerWebAgg
-
- @staticmethod
- def trigger_manager_draw(manager):
- manager.canvas.draw_idle()
-
- @staticmethod
- def show():
- WebAggApplication.initialize()
-
- url = "http://127.0.0.1:{port}{prefix}".format(
- port=WebAggApplication.port,
- prefix=WebAggApplication.url_prefix)
-
- if rcParams['webagg.open_in_browser']:
- import webbrowser
- webbrowser.open(url)
- else:
- print("To view figure, visit {0}".format(url))
-
- WebAggApplication.start()
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_webagg_core.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_webagg_core.py
deleted file mode 100644
index e75014b1e6..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_webagg_core.py
+++ /dev/null
@@ -1,543 +0,0 @@
-"""
-Displays Agg images in the browser, with interactivity
-"""
-# The WebAgg backend is divided into two modules:
-#
-# - `backend_webagg_core.py` contains code necessary to embed a WebAgg
-# plot inside of a web application, and communicate in an abstract
-# way over a web socket.
-#
-# - `backend_webagg.py` contains a concrete implementation of a basic
-# application, implemented with tornado.
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import datetime
-import io
-import json
-import os
-import warnings
-
-import numpy as np
-import tornado
-
-from matplotlib.backends import backend_agg
-from matplotlib.backend_bases import _Backend
-from matplotlib import backend_bases
-from matplotlib import _png
-
-
-# http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
-_SHIFT_LUT = {59: ':',
- 61: '+',
- 173: '_',
- 186: ':',
- 187: '+',
- 188: '<',
- 189: '_',
- 190: '>',
- 191: '?',
- 192: '~',
- 219: '{',
- 220: '|',
- 221: '}',
- 222: '"'}
-
-_LUT = {8: 'backspace',
- 9: 'tab',
- 13: 'enter',
- 16: 'shift',
- 17: 'control',
- 18: 'alt',
- 19: 'pause',
- 20: 'caps',
- 27: 'escape',
- 32: ' ',
- 33: 'pageup',
- 34: 'pagedown',
- 35: 'end',
- 36: 'home',
- 37: 'left',
- 38: 'up',
- 39: 'right',
- 40: 'down',
- 45: 'insert',
- 46: 'delete',
- 91: 'super',
- 92: 'super',
- 93: 'select',
- 106: '*',
- 107: '+',
- 109: '-',
- 110: '.',
- 111: '/',
- 144: 'num_lock',
- 145: 'scroll_lock',
- 186: ':',
- 187: '=',
- 188: ',',
- 189: '-',
- 190: '.',
- 191: '/',
- 192: '`',
- 219: '[',
- 220: '\\',
- 221: ']',
- 222: "'"}
-
-
-def _handle_key(key):
- """Handle key codes"""
- code = int(key[key.index('k') + 1:])
- value = chr(code)
- # letter keys
- if code >= 65 and code <= 90:
- if 'shift+' in key:
- key = key.replace('shift+', '')
- else:
- value = value.lower()
- # number keys
- elif code >= 48 and code <= 57:
- if 'shift+' in key:
- value = ')!@#$%^&*('[int(value)]
- key = key.replace('shift+', '')
- # function keys
- elif code >= 112 and code <= 123:
- value = 'f%s' % (code - 111)
- # number pad keys
- elif code >= 96 and code <= 105:
- value = '%s' % (code - 96)
- # keys with shift alternatives
- elif code in _SHIFT_LUT and 'shift+' in key:
- key = key.replace('shift+', '')
- value = _SHIFT_LUT[code]
- elif code in _LUT:
- value = _LUT[code]
- key = key[:key.index('k')] + value
- return key
-
-
-class FigureCanvasWebAggCore(backend_agg.FigureCanvasAgg):
- supports_blit = False
-
- def __init__(self, *args, **kwargs):
- backend_agg.FigureCanvasAgg.__init__(self, *args, **kwargs)
-
- # Set to True when the renderer contains data that is newer
- # than the PNG buffer.
- self._png_is_old = True
-
- # Set to True by the `refresh` message so that the next frame
- # sent to the clients will be a full frame.
- self._force_full = True
-
- # Store the current image mode so that at any point, clients can
- # request the information. This should be changed by calling
- # self.set_image_mode(mode) so that the notification can be given
- # to the connected clients.
- self._current_image_mode = 'full'
-
- # Store the DPI ratio of the browser. This is the scaling that
- # occurs automatically for all images on a HiDPI display.
- self._dpi_ratio = 1
-
- def show(self):
- # show the figure window
- from matplotlib.pyplot import show
- show()
-
- def draw(self):
- renderer = self.get_renderer(cleared=True)
-
- self._png_is_old = True
-
- backend_agg.RendererAgg.lock.acquire()
- try:
- self.figure.draw(renderer)
- finally:
- backend_agg.RendererAgg.lock.release()
- # Swap the frames
- self.manager.refresh_all()
-
- def draw_idle(self):
- self.send_event("draw")
-
- def set_image_mode(self, mode):
- """
- Set the image mode for any subsequent images which will be sent
- to the clients. The modes may currently be either 'full' or 'diff'.
-
- Note: diff images may not contain transparency, therefore upon
- draw this mode may be changed if the resulting image has any
- transparent component.
-
- """
- if mode not in ['full', 'diff']:
- raise ValueError('image mode must be either full or diff.')
- if self._current_image_mode != mode:
- self._current_image_mode = mode
- self.handle_send_image_mode(None)
-
- def get_diff_image(self):
- if self._png_is_old:
- renderer = self.get_renderer()
-
- # The buffer is created as type uint32 so that entire
- # pixels can be compared in one numpy call, rather than
- # needing to compare each plane separately.
- buff = (np.frombuffer(renderer.buffer_rgba(), dtype=np.uint32)
- .reshape((renderer.height, renderer.width)))
-
- # If any pixels have transparency, we need to force a full
- # draw as we cannot overlay new on top of old.
- pixels = buff.view(dtype=np.uint8).reshape(buff.shape + (4,))
-
- if self._force_full or np.any(pixels[:, :, 3] != 255):
- self.set_image_mode('full')
- output = buff
- else:
- self.set_image_mode('diff')
- last_buffer = (np.frombuffer(self._last_renderer.buffer_rgba(),
- dtype=np.uint32)
- .reshape((renderer.height, renderer.width)))
- diff = buff != last_buffer
- output = np.where(diff, buff, 0)
-
- # TODO: We should write a new version of write_png that
- # handles the differencing inline
- buff = _png.write_png(
- output.view(dtype=np.uint8).reshape(output.shape + (4,)),
- None, compression=6, filter=_png.PNG_FILTER_NONE)
-
- # Swap the renderer frames
- self._renderer, self._last_renderer = (
- self._last_renderer, renderer)
- self._force_full = False
- self._png_is_old = False
- return buff
-
- def get_renderer(self, cleared=None):
- # Mirrors super.get_renderer, but caches the old one
- # so that we can do things such as produce a diff image
- # in get_diff_image
- _, _, w, h = self.figure.bbox.bounds
- w, h = int(w), int(h)
- key = w, h, self.figure.dpi
- try:
- self._lastKey, self._renderer
- except AttributeError:
- need_new_renderer = True
- else:
- need_new_renderer = (self._lastKey != key)
-
- if need_new_renderer:
- self._renderer = backend_agg.RendererAgg(
- w, h, self.figure.dpi)
- self._last_renderer = backend_agg.RendererAgg(
- w, h, self.figure.dpi)
- self._lastKey = key
-
- elif cleared:
- self._renderer.clear()
-
- return self._renderer
-
- def handle_event(self, event):
- e_type = event['type']
- handler = getattr(self, 'handle_{0}'.format(e_type),
- self.handle_unknown_event)
- return handler(event)
-
- def handle_unknown_event(self, event):
- warnings.warn('Unhandled message type {0}. {1}'.format(
- event['type'], event))
-
- def handle_ack(self, event):
- # Network latency tends to decrease if traffic is flowing
- # in both directions. Therefore, the browser sends back
- # an "ack" message after each image frame is received.
- # This could also be used as a simple sanity check in the
- # future, but for now the performance increase is enough
- # to justify it, even if the server does nothing with it.
- pass
-
- def handle_draw(self, event):
- self.draw()
-
- def _handle_mouse(self, event):
- x = event['x']
- y = event['y']
- y = self.get_renderer().height - y
-
- # Javascript button numbers and matplotlib button numbers are
- # off by 1
- button = event['button'] + 1
-
- # The right mouse button pops up a context menu, which
- # doesn't work very well, so use the middle mouse button
- # instead. It doesn't seem that it's possible to disable
- # the context menu in recent versions of Chrome. If this
- # is resolved, please also adjust the docstring in MouseEvent.
- if button == 2:
- button = 3
-
- e_type = event['type']
- guiEvent = event.get('guiEvent', None)
- if e_type == 'button_press':
- self.button_press_event(x, y, button, guiEvent=guiEvent)
- elif e_type == 'button_release':
- self.button_release_event(x, y, button, guiEvent=guiEvent)
- elif e_type == 'motion_notify':
- self.motion_notify_event(x, y, guiEvent=guiEvent)
- elif e_type == 'figure_enter':
- self.enter_notify_event(xy=(x, y), guiEvent=guiEvent)
- elif e_type == 'figure_leave':
- self.leave_notify_event()
- elif e_type == 'scroll':
- self.scroll_event(x, y, event['step'], guiEvent=guiEvent)
- handle_button_press = handle_button_release = handle_motion_notify = \
- handle_figure_enter = handle_figure_leave = handle_scroll = \
- _handle_mouse
-
- def _handle_key(self, event):
- key = _handle_key(event['key'])
- e_type = event['type']
- guiEvent = event.get('guiEvent', None)
- if e_type == 'key_press':
- self.key_press_event(key, guiEvent=guiEvent)
- elif e_type == 'key_release':
- self.key_release_event(key, guiEvent=guiEvent)
- handle_key_press = handle_key_release = _handle_key
-
- def handle_toolbar_button(self, event):
- # TODO: Be more suspicious of the input
- getattr(self.toolbar, event['name'])()
-
- def handle_refresh(self, event):
- figure_label = self.figure.get_label()
- if not figure_label:
- figure_label = "Figure {0}".format(self.manager.num)
- self.send_event('figure_label', label=figure_label)
- self._force_full = True
- self.draw_idle()
-
- def handle_resize(self, event):
- x, y = event.get('width', 800), event.get('height', 800)
- x, y = int(x) * self._dpi_ratio, int(y) * self._dpi_ratio
- fig = self.figure
- # An attempt at approximating the figure size in pixels.
- fig.set_size_inches(x / fig.dpi, y / fig.dpi, forward=False)
-
- _, _, w, h = self.figure.bbox.bounds
- # Acknowledge the resize, and force the viewer to update the
- # canvas size to the figure's new size (which is hopefully
- # identical or within a pixel or so).
- self._png_is_old = True
- self.manager.resize(w, h)
- self.resize_event()
-
- def handle_send_image_mode(self, event):
- # The client requests notification of what the current image mode is.
- self.send_event('image_mode', mode=self._current_image_mode)
-
- def handle_set_dpi_ratio(self, event):
- dpi_ratio = event.get('dpi_ratio', 1)
- if dpi_ratio != self._dpi_ratio:
- # We don't want to scale up the figure dpi more than once.
- if not hasattr(self.figure, '_original_dpi'):
- self.figure._original_dpi = self.figure.dpi
- self.figure.dpi = dpi_ratio * self.figure._original_dpi
- self._dpi_ratio = dpi_ratio
- self._force_full = True
- self.draw_idle()
-
- def send_event(self, event_type, **kwargs):
- self.manager._send_event(event_type, **kwargs)
-
-
-_JQUERY_ICON_CLASSES = {
- 'home': 'ui-icon ui-icon-home',
- 'back': 'ui-icon ui-icon-circle-arrow-w',
- 'forward': 'ui-icon ui-icon-circle-arrow-e',
- 'zoom_to_rect': 'ui-icon ui-icon-search',
- 'move': 'ui-icon ui-icon-arrow-4',
- 'download': 'ui-icon ui-icon-disk',
- None: None,
-}
-
-
-class NavigationToolbar2WebAgg(backend_bases.NavigationToolbar2):
-
- # Use the standard toolbar items + download button
- toolitems = [(text, tooltip_text, _JQUERY_ICON_CLASSES[image_file],
- name_of_method)
- for text, tooltip_text, image_file, name_of_method
- in (backend_bases.NavigationToolbar2.toolitems +
- (('Download', 'Download plot', 'download', 'download'),))
- if image_file in _JQUERY_ICON_CLASSES]
-
- def _init_toolbar(self):
- self.message = ''
- self.cursor = 0
-
- def set_message(self, message):
- if message != self.message:
- self.canvas.send_event("message", message=message)
- self.message = message
-
- def set_cursor(self, cursor):
- if cursor != self.cursor:
- self.canvas.send_event("cursor", cursor=cursor)
- self.cursor = cursor
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- self.canvas.send_event(
- "rubberband", x0=x0, y0=y0, x1=x1, y1=y1)
-
- def release_zoom(self, event):
- backend_bases.NavigationToolbar2.release_zoom(self, event)
- self.canvas.send_event(
- "rubberband", x0=-1, y0=-1, x1=-1, y1=-1)
-
- def save_figure(self, *args):
- """Save the current figure"""
- self.canvas.send_event('save')
-
-
-class FigureManagerWebAgg(backend_bases.FigureManagerBase):
- ToolbarCls = NavigationToolbar2WebAgg
-
- def __init__(self, canvas, num):
- backend_bases.FigureManagerBase.__init__(self, canvas, num)
-
- self.web_sockets = set()
-
- self.toolbar = self._get_toolbar(canvas)
-
- def show(self):
- pass
-
- def _get_toolbar(self, canvas):
- toolbar = self.ToolbarCls(canvas)
- return toolbar
-
- def resize(self, w, h):
- self._send_event(
- 'resize',
- size=(w / self.canvas._dpi_ratio, h / self.canvas._dpi_ratio))
-
- def set_window_title(self, title):
- self._send_event('figure_label', label=title)
-
- # The following methods are specific to FigureManagerWebAgg
-
- def add_web_socket(self, web_socket):
- assert hasattr(web_socket, 'send_binary')
- assert hasattr(web_socket, 'send_json')
-
- self.web_sockets.add(web_socket)
-
- _, _, w, h = self.canvas.figure.bbox.bounds
- self.resize(w, h)
- self._send_event('refresh')
-
- def remove_web_socket(self, web_socket):
- self.web_sockets.remove(web_socket)
-
- def handle_json(self, content):
- self.canvas.handle_event(content)
-
- def refresh_all(self):
- if self.web_sockets:
- diff = self.canvas.get_diff_image()
- if diff is not None:
- for s in self.web_sockets:
- s.send_binary(diff)
-
- @classmethod
- def get_javascript(cls, stream=None):
- if stream is None:
- output = io.StringIO()
- else:
- output = stream
-
- with io.open(os.path.join(
- os.path.dirname(__file__),
- "web_backend", "js",
- "mpl.js"), encoding='utf8') as fd:
- output.write(fd.read())
-
- toolitems = []
- for name, tooltip, image, method in cls.ToolbarCls.toolitems:
- if name is None:
- toolitems.append(['', '', '', ''])
- else:
- toolitems.append([name, tooltip, image, method])
- output.write("mpl.toolbar_items = {0};\n\n".format(
- json.dumps(toolitems)))
-
- extensions = []
- for filetype, ext in sorted(FigureCanvasWebAggCore.
- get_supported_filetypes_grouped().
- items()):
- if not ext[0] == 'pgf': # pgf does not support BytesIO
- extensions.append(ext[0])
- output.write("mpl.extensions = {0};\n\n".format(
- json.dumps(extensions)))
-
- output.write("mpl.default_extension = {0};".format(
- json.dumps(FigureCanvasWebAggCore.get_default_filetype())))
-
- if stream is None:
- return output.getvalue()
-
- @classmethod
- def get_static_file_path(cls):
- return os.path.join(os.path.dirname(__file__), 'web_backend')
-
- def _send_event(self, event_type, **kwargs):
- payload = {'type': event_type}
- payload.update(kwargs)
- for s in self.web_sockets:
- s.send_json(payload)
-
-
-class TimerTornado(backend_bases.TimerBase):
- def _timer_start(self):
- self._timer_stop()
- if self._single:
- ioloop = tornado.ioloop.IOLoop.instance()
- self._timer = ioloop.add_timeout(
- datetime.timedelta(milliseconds=self.interval),
- self._on_timer)
- else:
- self._timer = tornado.ioloop.PeriodicCallback(
- self._on_timer,
- self.interval)
- self._timer.start()
-
- def _timer_stop(self):
- if self._timer is None:
- return
- elif self._single:
- ioloop = tornado.ioloop.IOLoop.instance()
- ioloop.remove_timeout(self._timer)
- else:
- self._timer.stop()
-
- self._timer = None
-
- def _timer_set_interval(self):
- # Only stop and restart it if the timer has already been started
- if self._timer is not None:
- self._timer_stop()
- self._timer_start()
-
-
-@_Backend.export
-class _BackendWebAggCoreAgg(_Backend):
- FigureCanvas = FigureCanvasWebAggCore
- FigureManager = FigureManagerWebAgg
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_wx.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_wx.py
deleted file mode 100644
index 2ecc1a4b3b..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_wx.py
+++ /dev/null
@@ -1,2002 +0,0 @@
-"""
- A wxPython backend for matplotlib, based (very heavily) on
- backend_template.py and backend_gtk.py
-
- Author: Jeremy O'Donoghue (jeremy@o-donoghue.com)
-
- Derived from original copyright work by John Hunter
- (jdhunter@ace.bsd.uchicago.edu)
-
- Copyright (C) Jeremy O'Donoghue & John Hunter, 2003-4
-
- License: This work is licensed under a PSF compatible license. A copy
- should be included with this source code.
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-import six
-
-import sys
-import os
-import os.path
-import math
-import weakref
-import warnings
-
-import matplotlib
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase,
- NavigationToolbar2, RendererBase, TimerBase, cursors)
-from matplotlib.backend_bases import _has_pil
-
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.cbook import is_writable_file_like, warn_deprecated
-from matplotlib.figure import Figure
-from matplotlib.path import Path
-from matplotlib.transforms import Affine2D
-from matplotlib.widgets import SubplotTool
-from matplotlib import cbook, rcParams, backend_tools
-
-from . import wx_compat as wxc
-import wx
-
-# Debugging settings here...
-# Debug level set here. If the debug level is less than 5, information
-# messages (progressively more info for lower value) are printed. In addition,
-# traceback is performed, and pdb activated, for all uncaught exceptions in
-# this case
-_DEBUG = 5
-if _DEBUG < 5:
- import traceback
- import pdb
-_DEBUG_lvls = {1: 'Low ', 2: 'Med ', 3: 'High', 4: 'Error'}
-
-
-def DEBUG_MSG(string, lvl=3, o=None):
- if lvl >= _DEBUG:
- cls = o.__class__
- # Jeremy, often times the commented line won't print but the
- # one below does. I think WX is redefining stderr, damned
- # beast
- # print("%s- %s in %s" % (_DEBUG_lvls[lvl], string, cls),
- # file=sys.stderr)
- print("%s- %s in %s" % (_DEBUG_lvls[lvl], string, cls))
-
-
-def debug_on_error(type, value, tb):
- """Code due to Thomas Heller - published in Python Cookbook (O'Reilley)"""
- traceback.print_exception(type, value, tb)
- print()
- pdb.pm() # jdh uncomment
-
-
-class fake_stderr(object):
- """
- Wx does strange things with stderr, as it makes the assumption that
- there is probably no console. This redirects stderr to the console, since
- we know that there is one!
- """
-
- def write(self, msg):
- print("Stderr: %s\n\r" % msg)
-
-
-# the True dots per inch on the screen; should be display dependent
-# see
-# http://groups.google.com/groups?q=screen+dpi+x11&hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&selm=7077.26e81ad5%40swift.cs.tcd.ie&rnum=5
-# for some info about screen dpi
-PIXELS_PER_INCH = 75
-
-# Delay time for idle checks
-IDLE_DELAY = 5
-
-
-def error_msg_wx(msg, parent=None):
- """
- Signal an error condition -- in a GUI, popup a error dialog
- """
- dialog = wx.MessageDialog(parent=parent,
- message=msg,
- caption='Matplotlib backend_wx error',
- style=wx.OK | wx.CENTRE)
- dialog.ShowModal()
- dialog.Destroy()
- return None
-
-
-def raise_msg_to_str(msg):
- """msg is a return arg from a raise. Join with new lines."""
- if not isinstance(msg, six.string_types):
- msg = '\n'.join(map(str, msg))
- return msg
-
-
-class TimerWx(TimerBase):
- '''
- Subclass of :class:`backend_bases.TimerBase` that uses WxTimer events.
-
- Attributes
- ----------
- interval : int
- The time between timer events in milliseconds. Default is 1000 ms.
- single_shot : bool
- Boolean flag indicating whether this timer should operate as single
- shot (run once and then stop). Defaults to False.
- callbacks : list
- Stores list of (func, args) tuples that will be called upon timer
- events. This list can be manipulated directly, or the functions
- `add_callback` and `remove_callback` can be used.
-
- '''
-
- def __init__(self, parent, *args, **kwargs):
- TimerBase.__init__(self, *args, **kwargs)
-
- # Create a new timer and connect the timer event to our handler.
- # For WX, the events have to use a widget for binding.
- self.parent = parent
- self._timer = wx.Timer(self.parent, wx.NewId())
- self.parent.Bind(wx.EVT_TIMER, self._on_timer, self._timer)
-
- # Unbinding causes Wx to stop for some reason. Disabling for now.
-# def __del__(self):
-# TimerBase.__del__(self)
-# self.parent.Bind(wx.EVT_TIMER, None, self._timer)
-
- def _timer_start(self):
- self._timer.Start(self._interval, self._single)
-
- def _timer_stop(self):
- self._timer.Stop()
-
- def _timer_set_interval(self):
- self._timer_start()
-
- def _timer_set_single_shot(self):
- self._timer.Start()
-
- def _on_timer(self, *args):
- TimerBase._on_timer(self)
-
-
-class RendererWx(RendererBase):
- """
- The renderer handles all the drawing primitives using a graphics
- context instance that controls the colors/styles. It acts as the
- 'renderer' instance used by many classes in the hierarchy.
- """
- # In wxPython, drawing is performed on a wxDC instance, which will
- # generally be mapped to the client aread of the window displaying
- # the plot. Under wxPython, the wxDC instance has a wx.Pen which
- # describes the colour and weight of any lines drawn, and a wxBrush
- # which describes the fill colour of any closed polygon.
-
- fontweights = wxc.fontweights
- fontangles = wxc.fontangles
-
- # wxPython allows for portable font styles, choosing them appropriately
- # for the target platform. Map some standard font names to the portable
- # styles
- # QUESTION: Is it be wise to agree standard fontnames across all backends?
- fontnames = wxc.fontnames
-
- def __init__(self, bitmap, dpi):
- """
- Initialise a wxWindows renderer instance.
- """
- warn_deprecated('2.0', message="The WX backend is "
- "deprecated. It's untested "
- "and will be removed in Matplotlib 3.0. "
- "Use the WXAgg backend instead. "
- "See Matplotlib usage FAQ for more info on backends.",
- alternative='WXAgg')
- RendererBase.__init__(self)
- DEBUG_MSG("__init__()", 1, self)
- self.width = bitmap.GetWidth()
- self.height = bitmap.GetHeight()
- self.bitmap = bitmap
- self.fontd = {}
- self.dpi = dpi
- self.gc = None
-
- def flipy(self):
- return True
-
- def offset_text_height(self):
- return True
-
- def get_text_width_height_descent(self, s, prop, ismath):
- """
- get the width and height in display coords of the string s
- with FontPropertry prop
- """
- # return 1, 1
- if ismath:
- s = self.strip_math(s)
-
- if self.gc is None:
- gc = self.new_gc()
- else:
- gc = self.gc
- gfx_ctx = gc.gfx_ctx
- font = self.get_wx_font(s, prop)
- gfx_ctx.SetFont(font, wx.BLACK)
- w, h, descent, leading = gfx_ctx.GetFullTextExtent(s)
-
- return w, h, descent
-
- def get_canvas_width_height(self):
- 'return the canvas width and height in display coords'
- return self.width, self.height
-
- def handle_clip_rectangle(self, gc):
- new_bounds = gc.get_clip_rectangle()
- if new_bounds is not None:
- new_bounds = new_bounds.bounds
- gfx_ctx = gc.gfx_ctx
- if gfx_ctx._lastcliprect != new_bounds:
- gfx_ctx._lastcliprect = new_bounds
- if new_bounds is None:
- gfx_ctx.ResetClip()
- else:
- gfx_ctx.Clip(new_bounds[0],
- self.height - new_bounds[1] - new_bounds[3],
- new_bounds[2], new_bounds[3])
-
- @staticmethod
- def convert_path(gfx_ctx, path, transform):
- wxpath = gfx_ctx.CreatePath()
- for points, code in path.iter_segments(transform):
- if code == Path.MOVETO:
- wxpath.MoveToPoint(*points)
- elif code == Path.LINETO:
- wxpath.AddLineToPoint(*points)
- elif code == Path.CURVE3:
- wxpath.AddQuadCurveToPoint(*points)
- elif code == Path.CURVE4:
- wxpath.AddCurveToPoint(*points)
- elif code == Path.CLOSEPOLY:
- wxpath.CloseSubpath()
- return wxpath
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- gc.select()
- self.handle_clip_rectangle(gc)
- gfx_ctx = gc.gfx_ctx
- transform = transform + \
- Affine2D().scale(1.0, -1.0).translate(0.0, self.height)
- wxpath = self.convert_path(gfx_ctx, path, transform)
- if rgbFace is not None:
- gfx_ctx.SetBrush(wx.Brush(gc.get_wxcolour(rgbFace)))
- gfx_ctx.DrawPath(wxpath)
- else:
- gfx_ctx.StrokePath(wxpath)
- gc.unselect()
-
- def draw_image(self, gc, x, y, im):
- bbox = gc.get_clip_rectangle()
- if bbox is not None:
- l, b, w, h = bbox.bounds
- else:
- l = 0
- b = 0
- w = self.width
- h = self.height
- rows, cols = im.shape[:2]
- bitmap = wxc.BitmapFromBuffer(cols, rows, im.tostring())
- gc = self.get_gc()
- gc.select()
- gc.gfx_ctx.DrawBitmap(bitmap, int(l), int(self.height - b),
- int(w), int(-h))
- gc.unselect()
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- if ismath:
- s = self.strip_math(s)
- DEBUG_MSG("draw_text()", 1, self)
- gc.select()
- self.handle_clip_rectangle(gc)
- gfx_ctx = gc.gfx_ctx
-
- font = self.get_wx_font(s, prop)
- color = gc.get_wxcolour(gc.get_rgb())
- gfx_ctx.SetFont(font, color)
-
- w, h, d = self.get_text_width_height_descent(s, prop, ismath)
- x = int(x)
- y = int(y - h)
-
- if angle == 0.0:
- gfx_ctx.DrawText(s, x, y)
- else:
- rads = math.radians(angle)
- xo = h * math.sin(rads)
- yo = h * math.cos(rads)
- gfx_ctx.DrawRotatedText(s, x - xo, y - yo, rads)
-
- gc.unselect()
-
- def new_gc(self):
- """
- Return an instance of a GraphicsContextWx, and sets the current gc copy
- """
- DEBUG_MSG('new_gc()', 2, self)
- self.gc = GraphicsContextWx(self.bitmap, self)
- self.gc.select()
- self.gc.unselect()
- return self.gc
-
- def get_gc(self):
- """
- Fetch the locally cached gc.
- """
- # This is a dirty hack to allow anything with access to a renderer to
- # access the current graphics context
- assert self.gc is not None, "gc must be defined"
- return self.gc
-
- def get_wx_font(self, s, prop):
- """
- Return a wx font. Cache instances in a font dictionary for
- efficiency
- """
- DEBUG_MSG("get_wx_font()", 1, self)
-
- key = hash(prop)
- fontprop = prop
- fontname = fontprop.get_name()
-
- font = self.fontd.get(key)
- if font is not None:
- return font
-
- # Allow use of platform independent and dependent font names
- wxFontname = self.fontnames.get(fontname, wx.ROMAN)
- wxFacename = '' # Empty => wxPython chooses based on wx_fontname
-
- # Font colour is determined by the active wx.Pen
- # TODO: It may be wise to cache font information
- size = self.points_to_pixels(fontprop.get_size_in_points())
-
- font = wx.Font(int(size + 0.5), # Size
- wxFontname, # 'Generic' name
- self.fontangles[fontprop.get_style()], # Angle
- self.fontweights[fontprop.get_weight()], # Weight
- False, # Underline
- wxFacename) # Platform font name
-
- # cache the font and gc and return it
- self.fontd[key] = font
-
- return font
-
- def points_to_pixels(self, points):
- """
- convert point measures to pixes using dpi and the pixels per
- inch of the display
- """
- return points * (PIXELS_PER_INCH / 72.0 * self.dpi / 72.0)
-
-
-class GraphicsContextWx(GraphicsContextBase):
- """
- The graphics context provides the color, line styles, etc...
-
- This class stores a reference to a wxMemoryDC, and a
- wxGraphicsContext that draws to it. Creating a wxGraphicsContext
- seems to be fairly heavy, so these objects are cached based on the
- bitmap object that is passed in.
-
- The base GraphicsContext stores colors as a RGB tuple on the unit
- interval, e.g., (0.5, 0.0, 1.0). wxPython uses an int interval, but
- since wxPython colour management is rather simple, I have not chosen
- to implement a separate colour manager class.
- """
- _capd = {'butt': wx.CAP_BUTT,
- 'projecting': wx.CAP_PROJECTING,
- 'round': wx.CAP_ROUND}
-
- _joind = {'bevel': wx.JOIN_BEVEL,
- 'miter': wx.JOIN_MITER,
- 'round': wx.JOIN_ROUND}
-
- _cache = weakref.WeakKeyDictionary()
-
- def __init__(self, bitmap, renderer):
- GraphicsContextBase.__init__(self)
- # assert self.Ok(), "wxMemoryDC not OK to use"
- DEBUG_MSG("__init__()", 1, self)
- DEBUG_MSG("__init__() 2: %s" % bitmap, 1, self)
-
- dc, gfx_ctx = self._cache.get(bitmap, (None, None))
- if dc is None:
- dc = wx.MemoryDC()
- dc.SelectObject(bitmap)
- gfx_ctx = wx.GraphicsContext.Create(dc)
- gfx_ctx._lastcliprect = None
- self._cache[bitmap] = dc, gfx_ctx
-
- self.bitmap = bitmap
- self.dc = dc
- self.gfx_ctx = gfx_ctx
- self._pen = wx.Pen('BLACK', 1, wx.SOLID)
- gfx_ctx.SetPen(self._pen)
- self._style = wx.SOLID
- self.renderer = renderer
-
- def select(self):
- """
- Select the current bitmap into this wxDC instance
- """
-
- if sys.platform == 'win32':
- self.dc.SelectObject(self.bitmap)
- self.IsSelected = True
-
- def unselect(self):
- """
- Select a Null bitmasp into this wxDC instance
- """
- if sys.platform == 'win32':
- self.dc.SelectObject(wx.NullBitmap)
- self.IsSelected = False
-
- def set_foreground(self, fg, isRGBA=None):
- """
- Set the foreground color. fg can be a matlab format string, a
- html hex color string, an rgb unit tuple, or a float between 0
- and 1. In the latter case, grayscale is used.
- """
- # Implementation note: wxPython has a separate concept of pen and
- # brush - the brush fills any outline trace left by the pen.
- # Here we set both to the same colour - if a figure is not to be
- # filled, the renderer will set the brush to be transparent
- # Same goes for text foreground...
- DEBUG_MSG("set_foreground()", 1, self)
- self.select()
- GraphicsContextBase.set_foreground(self, fg, isRGBA)
-
- self._pen.SetColour(self.get_wxcolour(self.get_rgb()))
- self.gfx_ctx.SetPen(self._pen)
- self.unselect()
-
- def set_linewidth(self, w):
- """
- Set the line width.
- """
- w = float(w)
- DEBUG_MSG("set_linewidth()", 1, self)
- self.select()
- if w > 0 and w < 1:
- w = 1
- GraphicsContextBase.set_linewidth(self, w)
- lw = int(self.renderer.points_to_pixels(self._linewidth))
- if lw == 0:
- lw = 1
- self._pen.SetWidth(lw)
- self.gfx_ctx.SetPen(self._pen)
- self.unselect()
-
- def set_capstyle(self, cs):
- """
- Set the capstyle as a string in ('butt', 'round', 'projecting')
- """
- DEBUG_MSG("set_capstyle()", 1, self)
- self.select()
- GraphicsContextBase.set_capstyle(self, cs)
- self._pen.SetCap(GraphicsContextWx._capd[self._capstyle])
- self.gfx_ctx.SetPen(self._pen)
- self.unselect()
-
- def set_joinstyle(self, js):
- """
- Set the join style to be one of ('miter', 'round', 'bevel')
- """
- DEBUG_MSG("set_joinstyle()", 1, self)
- self.select()
- GraphicsContextBase.set_joinstyle(self, js)
- self._pen.SetJoin(GraphicsContextWx._joind[self._joinstyle])
- self.gfx_ctx.SetPen(self._pen)
- self.unselect()
-
- @cbook.deprecated("2.1")
- def set_linestyle(self, ls):
- """
- Set the line style to be one of
- """
- DEBUG_MSG("set_linestyle()", 1, self)
- self.select()
- GraphicsContextBase.set_linestyle(self, ls)
- try:
- self._style = wxc.dashd_wx[ls]
- except KeyError:
- self._style = wx.LONG_DASH # Style not used elsewhere...
-
- # On MS Windows platform, only line width of 1 allowed for dash lines
- if wx.Platform == '__WXMSW__':
- self.set_linewidth(1)
-
- self._pen.SetStyle(self._style)
- self.gfx_ctx.SetPen(self._pen)
- self.unselect()
-
- def get_wxcolour(self, color):
- """return a wx.Colour from RGB format"""
- DEBUG_MSG("get_wx_color()", 1, self)
- if len(color) == 3:
- r, g, b = color
- r *= 255
- g *= 255
- b *= 255
- return wx.Colour(red=int(r), green=int(g), blue=int(b))
- else:
- r, g, b, a = color
- r *= 255
- g *= 255
- b *= 255
- a *= 255
- return wx.Colour(
- red=int(r),
- green=int(g),
- blue=int(b),
- alpha=int(a))
-
-
-class _FigureCanvasWxBase(FigureCanvasBase, wx.Panel):
- """
- The FigureCanvas contains the figure and does event handling.
-
- In the wxPython backend, it is derived from wxPanel, and (usually) lives
- inside a frame instantiated by a FigureManagerWx. The parent window
- probably implements a wx.Sizer to control the displayed control size - but
- we give a hint as to our preferred minimum size.
- """
-
- keyvald = {
- wx.WXK_CONTROL: 'control',
- wx.WXK_SHIFT: 'shift',
- wx.WXK_ALT: 'alt',
- wx.WXK_LEFT: 'left',
- wx.WXK_UP: 'up',
- wx.WXK_RIGHT: 'right',
- wx.WXK_DOWN: 'down',
- wx.WXK_ESCAPE: 'escape',
- wx.WXK_F1: 'f1',
- wx.WXK_F2: 'f2',
- wx.WXK_F3: 'f3',
- wx.WXK_F4: 'f4',
- wx.WXK_F5: 'f5',
- wx.WXK_F6: 'f6',
- wx.WXK_F7: 'f7',
- wx.WXK_F8: 'f8',
- wx.WXK_F9: 'f9',
- wx.WXK_F10: 'f10',
- wx.WXK_F11: 'f11',
- wx.WXK_F12: 'f12',
- wx.WXK_SCROLL: 'scroll_lock',
- wx.WXK_PAUSE: 'break',
- wx.WXK_BACK: 'backspace',
- wx.WXK_RETURN: 'enter',
- wx.WXK_INSERT: 'insert',
- wx.WXK_DELETE: 'delete',
- wx.WXK_HOME: 'home',
- wx.WXK_END: 'end',
- wx.WXK_PAGEUP: 'pageup',
- wx.WXK_PAGEDOWN: 'pagedown',
- wx.WXK_NUMPAD0: '0',
- wx.WXK_NUMPAD1: '1',
- wx.WXK_NUMPAD2: '2',
- wx.WXK_NUMPAD3: '3',
- wx.WXK_NUMPAD4: '4',
- wx.WXK_NUMPAD5: '5',
- wx.WXK_NUMPAD6: '6',
- wx.WXK_NUMPAD7: '7',
- wx.WXK_NUMPAD8: '8',
- wx.WXK_NUMPAD9: '9',
- wx.WXK_NUMPAD_ADD: '+',
- wx.WXK_NUMPAD_SUBTRACT: '-',
- wx.WXK_NUMPAD_MULTIPLY: '*',
- wx.WXK_NUMPAD_DIVIDE: '/',
- wx.WXK_NUMPAD_DECIMAL: 'dec',
- wx.WXK_NUMPAD_ENTER: 'enter',
- wx.WXK_NUMPAD_UP: 'up',
- wx.WXK_NUMPAD_RIGHT: 'right',
- wx.WXK_NUMPAD_DOWN: 'down',
- wx.WXK_NUMPAD_LEFT: 'left',
- wx.WXK_NUMPAD_PAGEUP: 'pageup',
- wx.WXK_NUMPAD_PAGEDOWN: 'pagedown',
- wx.WXK_NUMPAD_HOME: 'home',
- wx.WXK_NUMPAD_END: 'end',
- wx.WXK_NUMPAD_INSERT: 'insert',
- wx.WXK_NUMPAD_DELETE: 'delete',
- }
-
- def __init__(self, parent, id, figure):
- """
- Initialise a FigureWx instance.
-
- - Initialise the FigureCanvasBase and wxPanel parents.
- - Set event handlers for:
- EVT_SIZE (Resize event)
- EVT_PAINT (Paint event)
- """
-
- FigureCanvasBase.__init__(self, figure)
- # Set preferred window size hint - helps the sizer (if one is
- # connected)
- l, b, w, h = figure.bbox.bounds
- w = int(math.ceil(w))
- h = int(math.ceil(h))
-
- wx.Panel.__init__(self, parent, id, size=wx.Size(w, h))
-
- def do_nothing(*args, **kwargs):
- warnings.warn(
- "could not find a setinitialsize function for backend_wx; "
- "please report your wxpython version=%s "
- "to the matplotlib developers list" %
- wxc.backend_version)
- pass
-
- # try to find the set size func across wx versions
- try:
- getattr(self, 'SetInitialSize')
- except AttributeError:
- self.SetInitialSize = getattr(self, 'SetBestFittingSize',
- do_nothing)
-
- if not hasattr(self, 'IsShownOnScreen'):
- self.IsShownOnScreen = getattr(self, 'IsVisible',
- lambda *args: True)
-
- # Create the drawing bitmap
- self.bitmap = wxc.EmptyBitmap(w, h)
- DEBUG_MSG("__init__() - bitmap w:%d h:%d" % (w, h), 2, self)
- # TODO: Add support for 'point' inspection and plot navigation.
- self._isDrawn = False
-
- self.Bind(wx.EVT_SIZE, self._onSize)
- self.Bind(wx.EVT_PAINT, self._onPaint)
- self.Bind(wx.EVT_KEY_DOWN, self._onKeyDown)
- self.Bind(wx.EVT_KEY_UP, self._onKeyUp)
- self.Bind(wx.EVT_RIGHT_DOWN, self._onRightButtonDown)
- self.Bind(wx.EVT_RIGHT_DCLICK, self._onRightButtonDClick)
- self.Bind(wx.EVT_RIGHT_UP, self._onRightButtonUp)
- self.Bind(wx.EVT_MOUSEWHEEL, self._onMouseWheel)
- self.Bind(wx.EVT_LEFT_DOWN, self._onLeftButtonDown)
- self.Bind(wx.EVT_LEFT_DCLICK, self._onLeftButtonDClick)
- self.Bind(wx.EVT_LEFT_UP, self._onLeftButtonUp)
- self.Bind(wx.EVT_MOTION, self._onMotion)
- self.Bind(wx.EVT_LEAVE_WINDOW, self._onLeave)
- self.Bind(wx.EVT_ENTER_WINDOW, self._onEnter)
- # Add middle button events
- self.Bind(wx.EVT_MIDDLE_DOWN, self._onMiddleButtonDown)
- self.Bind(wx.EVT_MIDDLE_DCLICK, self._onMiddleButtonDClick)
- self.Bind(wx.EVT_MIDDLE_UP, self._onMiddleButtonUp)
-
- self.Bind(wx.EVT_MOUSE_CAPTURE_CHANGED, self._onCaptureLost)
- self.Bind(wx.EVT_MOUSE_CAPTURE_LOST, self._onCaptureLost)
-
- self.SetBackgroundStyle(wx.BG_STYLE_PAINT) # Reduce flicker.
- self.SetBackgroundColour(wx.WHITE)
-
- self.macros = {} # dict from wx id to seq of macros
-
- def Destroy(self, *args, **kwargs):
- wx.Panel.Destroy(self, *args, **kwargs)
-
- def Copy_to_Clipboard(self, event=None):
- "copy bitmap of canvas to system clipboard"
- bmp_obj = wx.BitmapDataObject()
- bmp_obj.SetBitmap(self.bitmap)
-
- if not wx.TheClipboard.IsOpened():
- open_success = wx.TheClipboard.Open()
- if open_success:
- wx.TheClipboard.SetData(bmp_obj)
- wx.TheClipboard.Close()
- wx.TheClipboard.Flush()
-
- def draw_idle(self):
- """
- Delay rendering until the GUI is idle.
- """
- DEBUG_MSG("draw_idle()", 1, self)
- self._isDrawn = False # Force redraw
- # Triggering a paint event is all that is needed to defer drawing
- # until later. The platform will send the event when it thinks it is
- # a good time (usually as soon as there are no other events pending).
- self.Refresh(eraseBackground=False)
-
- def new_timer(self, *args, **kwargs):
- """
- Creates a new backend-specific subclass of
- :class:`backend_bases.Timer`. This is useful for getting periodic
- events through the backend's native event loop. Implemented only
- for backends with GUIs.
-
- Other Parameters
- ----------------
- interval : scalar
- Timer interval in milliseconds
- callbacks : list
- Sequence of (func, args, kwargs) where ``func(*args, **kwargs)``
- will be executed by the timer every *interval*.
-
- """
- return TimerWx(self, *args, **kwargs)
-
- def flush_events(self):
- wx.Yield()
-
- def start_event_loop(self, timeout=0):
- """
- Start an event loop. This is used to start a blocking event
- loop so that interactive functions, such as ginput and
- waitforbuttonpress, can wait for events. This should not be
- confused with the main GUI event loop, which is always running
- and has nothing to do with this.
-
- This call blocks until a callback function triggers
- stop_event_loop() or *timeout* is reached. If *timeout* is
- <=0, never timeout.
-
- Raises RuntimeError if event loop is already running.
- """
- if hasattr(self, '_event_loop'):
- raise RuntimeError("Event loop already running")
- id = wx.NewId()
- timer = wx.Timer(self, id=id)
- if timeout > 0:
- timer.Start(timeout * 1000, oneShot=True)
- self.Bind(wx.EVT_TIMER, self.stop_event_loop, id=id)
-
- # Event loop handler for start/stop event loop
- self._event_loop = wxc.EventLoop()
- self._event_loop.Run()
- timer.Stop()
-
- def stop_event_loop(self, event=None):
- """
- Stop an event loop. This is used to stop a blocking event
- loop so that interactive functions, such as ginput and
- waitforbuttonpress, can wait for events.
-
- """
- if hasattr(self, '_event_loop'):
- if self._event_loop.IsRunning():
- self._event_loop.Exit()
- del self._event_loop
-
- def _get_imagesave_wildcards(self):
- 'return the wildcard string for the filesave dialog'
- default_filetype = self.get_default_filetype()
- filetypes = self.get_supported_filetypes_grouped()
- sorted_filetypes = sorted(filetypes.items())
- wildcards = []
- extensions = []
- filter_index = 0
- for i, (name, exts) in enumerate(sorted_filetypes):
- ext_list = ';'.join(['*.%s' % ext for ext in exts])
- extensions.append(exts[0])
- wildcard = '%s (%s)|%s' % (name, ext_list, ext_list)
- if default_filetype in exts:
- filter_index = i
- wildcards.append(wildcard)
- wildcards = '|'.join(wildcards)
- return wildcards, extensions, filter_index
-
- def gui_repaint(self, drawDC=None, origin='WX'):
- """
- Performs update of the displayed image on the GUI canvas, using the
- supplied wx.PaintDC device context.
-
- The 'WXAgg' backend sets origin accordingly.
- """
- DEBUG_MSG("gui_repaint()", 1, self)
- if self.IsShownOnScreen():
- if not drawDC:
- # not called from OnPaint use a ClientDC
- drawDC = wx.ClientDC(self)
-
- # following is for 'WX' backend on Windows
- # the bitmap can not be in use by another DC,
- # see GraphicsContextWx._cache
- if wx.Platform == '__WXMSW__' and origin == 'WX':
- img = self.bitmap.ConvertToImage()
- bmp = img.ConvertToBitmap()
- drawDC.DrawBitmap(bmp, 0, 0)
- else:
- drawDC.DrawBitmap(self.bitmap, 0, 0)
-
- filetypes = FigureCanvasBase.filetypes.copy()
- filetypes['bmp'] = 'Windows bitmap'
- filetypes['jpeg'] = 'JPEG'
- filetypes['jpg'] = 'JPEG'
- filetypes['pcx'] = 'PCX'
- filetypes['png'] = 'Portable Network Graphics'
- filetypes['tif'] = 'Tagged Image Format File'
- filetypes['tiff'] = 'Tagged Image Format File'
- filetypes['xpm'] = 'X pixmap'
-
- def print_figure(self, filename, *args, **kwargs):
- super(_FigureCanvasWxBase, self).print_figure(
- filename, *args, **kwargs)
- # Restore the current view; this is needed because the artist contains
- # methods rely on particular attributes of the rendered figure for
- # determining things like bounding boxes.
- if self._isDrawn:
- self.draw()
-
- def _onPaint(self, evt):
- """
- Called when wxPaintEvt is generated
- """
-
- DEBUG_MSG("_onPaint()", 1, self)
- drawDC = wx.PaintDC(self)
- if not self._isDrawn:
- self.draw(drawDC=drawDC)
- else:
- self.gui_repaint(drawDC=drawDC)
- drawDC.Destroy()
-
- def _onSize(self, evt):
- """
- Called when wxEventSize is generated.
-
- In this application we attempt to resize to fit the window, so it
- is better to take the performance hit and redraw the whole window.
- """
-
- DEBUG_MSG("_onSize()", 2, self)
- sz = self.GetParent().GetSizer()
- if sz:
- si = sz.GetItem(self)
- if sz and si and not si.Proportion and not si.Flag & wx.EXPAND:
- # managed by a sizer, but with a fixed size
- size = self.GetMinSize()
- else:
- # variable size
- size = self.GetClientSize()
- if getattr(self, "_width", None):
- if size == (self._width, self._height):
- # no change in size
- return
- self._width, self._height = size
- # Create a new, correctly sized bitmap
- self.bitmap = wxc.EmptyBitmap(self._width, self._height)
-
- self._isDrawn = False
-
- if self._width <= 1 or self._height <= 1:
- return # Empty figure
-
- dpival = self.figure.dpi
- winch = self._width / dpival
- hinch = self._height / dpival
- self.figure.set_size_inches(winch, hinch, forward=False)
-
- # Rendering will happen on the associated paint event
- # so no need to do anything here except to make sure
- # the whole background is repainted.
- self.Refresh(eraseBackground=False)
- FigureCanvasBase.resize_event(self)
-
- def _get_key(self, evt):
-
- keyval = evt.KeyCode
- if keyval in self.keyvald:
- key = self.keyvald[keyval]
- elif keyval < 256:
- key = chr(keyval)
- # wx always returns an uppercase, so make it lowercase if the shift
- # key is not depressed (NOTE: this will not handle Caps Lock)
- if not evt.ShiftDown():
- key = key.lower()
- else:
- key = None
-
- for meth, prefix in (
- [evt.AltDown, 'alt'],
- [evt.ControlDown, 'ctrl'], ):
- if meth():
- key = '{0}+{1}'.format(prefix, key)
-
- return key
-
- def _onKeyDown(self, evt):
- """Capture key press."""
- key = self._get_key(evt)
- FigureCanvasBase.key_press_event(self, key, guiEvent=evt)
- if self:
- evt.Skip()
-
- def _onKeyUp(self, evt):
- """Release key."""
- key = self._get_key(evt)
- FigureCanvasBase.key_release_event(self, key, guiEvent=evt)
- if self:
- evt.Skip()
-
- def _set_capture(self, capture=True):
- """control wx mouse capture """
- if self.HasCapture():
- self.ReleaseMouse()
- if capture:
- self.CaptureMouse()
-
- def _onCaptureLost(self, evt):
- """Capture changed or lost"""
- self._set_capture(False)
-
- def _onRightButtonDown(self, evt):
- """Start measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- self._set_capture(True)
- FigureCanvasBase.button_press_event(self, x, y, 3, guiEvent=evt)
-
- def _onRightButtonDClick(self, evt):
- """Start measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- self._set_capture(True)
- FigureCanvasBase.button_press_event(self, x, y, 3,
- dblclick=True, guiEvent=evt)
-
- def _onRightButtonUp(self, evt):
- """End measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- self._set_capture(False)
- FigureCanvasBase.button_release_event(self, x, y, 3, guiEvent=evt)
-
- def _onLeftButtonDown(self, evt):
- """Start measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- self._set_capture(True)
- FigureCanvasBase.button_press_event(self, x, y, 1, guiEvent=evt)
-
- def _onLeftButtonDClick(self, evt):
- """Start measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- self._set_capture(True)
- FigureCanvasBase.button_press_event(self, x, y, 1,
- dblclick=True, guiEvent=evt)
-
- def _onLeftButtonUp(self, evt):
- """End measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- self._set_capture(False)
- FigureCanvasBase.button_release_event(self, x, y, 1, guiEvent=evt)
-
- # Add middle button events
- def _onMiddleButtonDown(self, evt):
- """Start measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- self._set_capture(True)
- FigureCanvasBase.button_press_event(self, x, y, 2, guiEvent=evt)
-
- def _onMiddleButtonDClick(self, evt):
- """Start measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- self._set_capture(True)
- FigureCanvasBase.button_press_event(self, x, y, 2,
- dblclick=True, guiEvent=evt)
-
- def _onMiddleButtonUp(self, evt):
- """End measuring on an axis."""
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- self._set_capture(False)
- FigureCanvasBase.button_release_event(self, x, y, 2, guiEvent=evt)
-
- def _onMouseWheel(self, evt):
- """Translate mouse wheel events into matplotlib events"""
-
- # Determine mouse location
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
-
- # Convert delta/rotation/rate into a floating point step size
- delta = evt.GetWheelDelta()
- rotation = evt.GetWheelRotation()
- rate = evt.GetLinesPerAction()
- step = rate * rotation / delta
-
- # Done handling event
- evt.Skip()
-
- # Mac is giving two events for every wheel event
- # Need to skip every second one
- if wx.Platform == '__WXMAC__':
- if not hasattr(self, '_skipwheelevent'):
- self._skipwheelevent = True
- elif self._skipwheelevent:
- self._skipwheelevent = False
- return # Return without processing event
- else:
- self._skipwheelevent = True
-
- # Convert to mpl event
- FigureCanvasBase.scroll_event(self, x, y, step, guiEvent=evt)
-
- def _onMotion(self, evt):
- """Start measuring on an axis."""
-
- x = evt.GetX()
- y = self.figure.bbox.height - evt.GetY()
- evt.Skip()
- FigureCanvasBase.motion_notify_event(self, x, y, guiEvent=evt)
-
- def _onLeave(self, evt):
- """Mouse has left the window."""
-
- evt.Skip()
- FigureCanvasBase.leave_notify_event(self, guiEvent=evt)
-
- def _onEnter(self, evt):
- """Mouse has entered the window."""
- FigureCanvasBase.enter_notify_event(self, guiEvent=evt)
-
-
-class FigureCanvasWx(_FigureCanvasWxBase):
- # Rendering to a Wx canvas using the deprecated Wx renderer.
-
- def draw(self, drawDC=None):
- """
- Render the figure using RendererWx instance renderer, or using a
- previously defined renderer if none is specified.
- """
- DEBUG_MSG("draw()", 1, self)
- self.renderer = RendererWx(self.bitmap, self.figure.dpi)
- self.figure.draw(self.renderer)
- self._isDrawn = True
- self.gui_repaint(drawDC=drawDC)
-
- def print_bmp(self, filename, *args, **kwargs):
- return self._print_image(filename, wx.BITMAP_TYPE_BMP, *args, **kwargs)
-
- if not _has_pil:
- def print_jpeg(self, filename, *args, **kwargs):
- return self._print_image(filename, wx.BITMAP_TYPE_JPEG,
- *args, **kwargs)
- print_jpg = print_jpeg
-
- def print_pcx(self, filename, *args, **kwargs):
- return self._print_image(filename, wx.BITMAP_TYPE_PCX, *args, **kwargs)
-
- def print_png(self, filename, *args, **kwargs):
- return self._print_image(filename, wx.BITMAP_TYPE_PNG, *args, **kwargs)
-
- if not _has_pil:
- def print_tiff(self, filename, *args, **kwargs):
- return self._print_image(filename, wx.BITMAP_TYPE_TIF,
- *args, **kwargs)
- print_tif = print_tiff
-
- def print_xpm(self, filename, *args, **kwargs):
- return self._print_image(filename, wx.BITMAP_TYPE_XPM, *args, **kwargs)
-
- def _print_image(self, filename, filetype, *args, **kwargs):
- origBitmap = self.bitmap
-
- l, b, width, height = self.figure.bbox.bounds
- width = int(math.ceil(width))
- height = int(math.ceil(height))
-
- self.bitmap = wxc.EmptyBitmap(width, height)
-
- renderer = RendererWx(self.bitmap, self.figure.dpi)
-
- gc = renderer.new_gc()
-
- self.figure.draw(renderer)
-
- # image is the object that we call SaveFile on.
- image = self.bitmap
- # set the JPEG quality appropriately. Unfortunately, it is only
- # possible to set the quality on a wx.Image object. So if we
- # are saving a JPEG, convert the wx.Bitmap to a wx.Image,
- # and set the quality.
- if filetype == wx.BITMAP_TYPE_JPEG:
- jpeg_quality = kwargs.get('quality',
- rcParams['savefig.jpeg_quality'])
- image = self.bitmap.ConvertToImage()
- image.SetOption(wx.IMAGE_OPTION_QUALITY, str(jpeg_quality))
-
- # Now that we have rendered into the bitmap, save it
- # to the appropriate file type and clean up
- if isinstance(filename, six.string_types):
- if not image.SaveFile(filename, filetype):
- DEBUG_MSG('print_figure() file save error', 4, self)
- raise RuntimeError(
- 'Could not save figure to %s\n' %
- (filename))
- elif is_writable_file_like(filename):
- if not isinstance(image, wx.Image):
- image = image.ConvertToImage()
- if not image.SaveStream(filename, filetype):
- DEBUG_MSG('print_figure() file save error', 4, self)
- raise RuntimeError(
- 'Could not save figure to %s\n' %
- (filename))
-
- # Restore everything to normal
- self.bitmap = origBitmap
-
- # Note: draw is required here since bits of state about the
- # last renderer are strewn about the artist draw methods. Do
- # not remove the draw without first verifying that these have
- # been cleaned up. The artist contains() methods will fail
- # otherwise.
- if self._isDrawn:
- self.draw()
- self.Refresh()
-
-
-########################################################################
-#
-# The following functions and classes are for pylab compatibility
-# mode (matplotlib.pylab) and implement figure managers, etc...
-#
-########################################################################
-
-
-class FigureFrameWx(wx.Frame):
- def __init__(self, num, fig):
- # On non-Windows platform, explicitly set the position - fix
- # positioning bug on some Linux platforms
- if wx.Platform == '__WXMSW__':
- pos = wx.DefaultPosition
- else:
- pos = wx.Point(20, 20)
- l, b, w, h = fig.bbox.bounds
- wx.Frame.__init__(self, parent=None, id=-1, pos=pos,
- title="Figure %d" % num)
- # Frame will be sized later by the Fit method
- DEBUG_MSG("__init__()", 1, self)
- self.num = num
-
- statbar = StatusBarWx(self)
- self.SetStatusBar(statbar)
- self.canvas = self.get_canvas(fig)
- self.canvas.SetInitialSize(wx.Size(fig.bbox.width, fig.bbox.height))
- self.canvas.SetFocus()
- self.sizer = wx.BoxSizer(wx.VERTICAL)
- self.sizer.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND)
- # By adding toolbar in sizer, we are able to put it at the bottom
- # of the frame - so appearance is closer to GTK version
-
- self.toolbar = self._get_toolbar(statbar)
-
- if self.toolbar is not None:
- self.toolbar.Realize()
- # On Windows platform, default window size is incorrect, so set
- # toolbar width to figure width.
- if wxc.is_phoenix:
- tw, th = self.toolbar.GetSize()
- fw, fh = self.canvas.GetSize()
- else:
- tw, th = self.toolbar.GetSizeTuple()
- fw, fh = self.canvas.GetSizeTuple()
- # By adding toolbar in sizer, we are able to put it at the bottom
- # of the frame - so appearance is closer to GTK version.
- self.toolbar.SetSize(wx.Size(fw, th))
- self.sizer.Add(self.toolbar, 0, wx.LEFT | wx.EXPAND)
- self.SetSizer(self.sizer)
- self.Fit()
-
- self.canvas.SetMinSize((2, 2))
-
- # give the window a matplotlib icon rather than the stock one.
- # This is not currently working on Linux and is untested elsewhere.
- # icon_path = os.path.join(matplotlib.rcParams['datapath'],
- # 'images', 'matplotlib.png')
- # icon = wx.IconFromBitmap(wx.Bitmap(icon_path))
- # for xpm type icons try:
- # icon = wx.Icon(icon_path, wx.BITMAP_TYPE_XPM)
- # self.SetIcon(icon)
-
- self.figmgr = FigureManagerWx(self.canvas, num, self)
-
- self.Bind(wx.EVT_CLOSE, self._onClose)
-
- def _get_toolbar(self, statbar):
- if rcParams['toolbar'] == 'toolbar2':
- toolbar = NavigationToolbar2Wx(self.canvas)
- toolbar.set_status_bar(statbar)
- else:
- toolbar = None
- return toolbar
-
- def get_canvas(self, fig):
- return FigureCanvasWx(self, -1, fig)
-
- def get_figure_manager(self):
- DEBUG_MSG("get_figure_manager()", 1, self)
- return self.figmgr
-
- def _onClose(self, evt):
- DEBUG_MSG("onClose()", 1, self)
- self.canvas.close_event()
- self.canvas.stop_event_loop()
- Gcf.destroy(self.num)
- # self.Destroy()
-
- def GetToolBar(self):
- """Override wxFrame::GetToolBar as we don't have managed toolbar"""
- return self.toolbar
-
- def Destroy(self, *args, **kwargs):
- try:
- self.canvas.mpl_disconnect(self.toolbar._idDrag)
- # Rationale for line above: see issue 2941338.
- except AttributeError:
- pass # classic toolbar lacks the attribute
- if not self.IsBeingDeleted():
- wx.Frame.Destroy(self, *args, **kwargs)
- if self.toolbar is not None:
- self.toolbar.Destroy()
- wxapp = wx.GetApp()
- if wxapp:
- wxapp.Yield()
- return True
-
-
-class FigureManagerWx(FigureManagerBase):
- """
- This class contains the FigureCanvas and GUI frame
-
- It is instantiated by GcfWx whenever a new figure is created. GcfWx is
- responsible for managing multiple instances of FigureManagerWx.
-
- Attributes
- ----------
- canvas : `FigureCanvas`
- a FigureCanvasWx(wx.Panel) instance
- window : wxFrame
- a wxFrame instance - wxpython.org/Phoenix/docs/html/Frame.html
-
- """
-
- def __init__(self, canvas, num, frame):
- DEBUG_MSG("__init__()", 1, self)
- FigureManagerBase.__init__(self, canvas, num)
- self.frame = frame
- self.window = frame
-
- self.tb = frame.GetToolBar()
- self.toolbar = self.tb # consistent with other backends
-
- def notify_axes_change(fig):
- 'this will be called whenever the current axes is changed'
- if self.tb is not None:
- self.tb.update()
- self.canvas.figure.add_axobserver(notify_axes_change)
-
- def show(self):
- self.frame.Show()
- self.canvas.draw()
-
- def destroy(self, *args):
- DEBUG_MSG("destroy()", 1, self)
- self.frame.Destroy()
- wxapp = wx.GetApp()
- if wxapp:
- wxapp.Yield()
-
- def get_window_title(self):
- return self.window.GetTitle()
-
- def set_window_title(self, title):
- self.window.SetTitle(title)
-
- def resize(self, width, height):
- 'Set the canvas size in pixels'
- self.canvas.SetInitialSize(wx.Size(width, height))
- self.window.GetSizer().Fit(self.window)
-
-# Identifiers for toolbar controls - images_wx contains bitmaps for the images
-# used in the controls. wxWindows does not provide any stock images, so I've
-# 'stolen' those from GTK2, and transformed them into the appropriate format.
-# import images_wx
-
-
-_NTB_AXISMENU = wx.NewId()
-_NTB_AXISMENU_BUTTON = wx.NewId()
-_NTB_X_PAN_LEFT = wx.NewId()
-_NTB_X_PAN_RIGHT = wx.NewId()
-_NTB_X_ZOOMIN = wx.NewId()
-_NTB_X_ZOOMOUT = wx.NewId()
-_NTB_Y_PAN_UP = wx.NewId()
-_NTB_Y_PAN_DOWN = wx.NewId()
-_NTB_Y_ZOOMIN = wx.NewId()
-_NTB_Y_ZOOMOUT = wx.NewId()
-# _NTB_SUBPLOT =wx.NewId()
-_NTB_SAVE = wx.NewId()
-_NTB_CLOSE = wx.NewId()
-
-
-def _load_bitmap(filename):
- """
- Load a bitmap file from the backends/images subdirectory in which the
- matplotlib library is installed. The filename parameter should not
- contain any path information as this is determined automatically.
-
- Returns a wx.Bitmap object
- """
-
- basedir = os.path.join(rcParams['datapath'], 'images')
-
- bmpFilename = os.path.normpath(os.path.join(basedir, filename))
- if not os.path.exists(bmpFilename):
- raise IOError('Could not find bitmap file "%s"; dying' % bmpFilename)
-
- bmp = wx.Bitmap(bmpFilename)
- return bmp
-
-
-class MenuButtonWx(wx.Button):
- """
- wxPython does not permit a menu to be incorporated directly into a toolbar.
- This class simulates the effect by associating a pop-up menu with a button
- in the toolbar, and managing this as though it were a menu.
- """
-
- def __init__(self, parent):
-
- wx.Button.__init__(self, parent, _NTB_AXISMENU_BUTTON, "Axes: ",
- style=wx.BU_EXACTFIT)
- self._toolbar = parent
- self._menu = wx.Menu()
- self._axisId = []
- # First two menu items never change...
- self._allId = wx.NewId()
- self._invertId = wx.NewId()
- self._menu.Append(self._allId, "All", "Select all axes", False)
- self._menu.Append(self._invertId, "Invert", "Invert axes selected",
- False)
- self._menu.AppendSeparator()
-
- self.Bind(wx.EVT_BUTTON, self._onMenuButton, id=_NTB_AXISMENU_BUTTON)
- self.Bind(wx.EVT_MENU, self._handleSelectAllAxes, id=self._allId)
- self.Bind(wx.EVT_MENU, self._handleInvertAxesSelected,
- id=self._invertId)
-
- def Destroy(self):
- self._menu.Destroy()
- self.Destroy()
-
- def _onMenuButton(self, evt):
- """Handle menu button pressed."""
- if wxc.is_phoenix:
- x, y = self.GetPosition()
- w, h = self.GetSize()
- else:
- x, y = self.GetPositionTuple()
- w, h = self.GetSizeTuple()
- self.PopupMenuXY(self._menu, x, y + h - 4)
- # When menu returned, indicate selection in button
- evt.Skip()
-
- def _handleSelectAllAxes(self, evt):
- """Called when the 'select all axes' menu item is selected."""
- if len(self._axisId) == 0:
- return
- for i in range(len(self._axisId)):
- self._menu.Check(self._axisId[i], True)
- self._toolbar.set_active(self.getActiveAxes())
- evt.Skip()
-
- def _handleInvertAxesSelected(self, evt):
- """Called when the invert all menu item is selected"""
- if len(self._axisId) == 0:
- return
- for i in range(len(self._axisId)):
- if self._menu.IsChecked(self._axisId[i]):
- self._menu.Check(self._axisId[i], False)
- else:
- self._menu.Check(self._axisId[i], True)
- self._toolbar.set_active(self.getActiveAxes())
- evt.Skip()
-
- def _onMenuItemSelected(self, evt):
- """Called whenever one of the specific axis menu items is selected"""
- current = self._menu.IsChecked(evt.GetId())
- if current:
- new = False
- else:
- new = True
- self._menu.Check(evt.GetId(), new)
- # Lines above would be deleted based on svn tracker ID 2841525;
- # not clear whether this matters or not.
- self._toolbar.set_active(self.getActiveAxes())
- evt.Skip()
-
- def updateAxes(self, maxAxis):
- """Ensures that there are entries for max_axis axes in the menu
- (selected by default)."""
- if maxAxis > len(self._axisId):
- for i in range(len(self._axisId) + 1, maxAxis + 1, 1):
- menuId = wx.NewId()
- self._axisId.append(menuId)
- self._menu.Append(menuId, "Axis %d" % i,
- "Select axis %d" % i,
- True)
- self._menu.Check(menuId, True)
- self.Bind(wx.EVT_MENU, self._onMenuItemSelected, id=menuId)
- elif maxAxis < len(self._axisId):
- for menuId in self._axisId[maxAxis:]:
- self._menu.Delete(menuId)
- self._axisId = self._axisId[:maxAxis]
- self._toolbar.set_active(list(xrange(maxAxis)))
-
- def getActiveAxes(self):
- """Return a list of the selected axes."""
- active = []
- for i in range(len(self._axisId)):
- if self._menu.IsChecked(self._axisId[i]):
- active.append(i)
- return active
-
- def updateButtonText(self, lst):
- """Update the list of selected axes in the menu button."""
- self.SetLabel(
- 'Axes: ' + ','.join('%d' % (e + 1) for e in lst))
-
-
-cursord = {
- cursors.MOVE: wx.CURSOR_HAND,
- cursors.HAND: wx.CURSOR_HAND,
- cursors.POINTER: wx.CURSOR_ARROW,
- cursors.SELECT_REGION: wx.CURSOR_CROSS,
- cursors.WAIT: wx.CURSOR_WAIT,
-}
-
-
-@cbook.deprecated("2.2")
-class SubplotToolWX(wx.Frame):
- def __init__(self, targetfig):
- wx.Frame.__init__(self, None, -1, "Configure subplots")
-
- toolfig = Figure((6, 3))
- canvas = FigureCanvasWx(self, -1, toolfig)
-
- # Create a figure manager to manage things
- figmgr = FigureManager(canvas, 1, self)
-
- # Now put all into a sizer
- sizer = wx.BoxSizer(wx.VERTICAL)
- # This way of adding to sizer allows resizing
- sizer.Add(canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
- self.SetSizer(sizer)
- self.Fit()
- tool = SubplotTool(targetfig, toolfig)
-
-
-class NavigationToolbar2Wx(NavigationToolbar2, wx.ToolBar):
- def __init__(self, canvas):
- wx.ToolBar.__init__(self, canvas.GetParent(), -1)
- NavigationToolbar2.__init__(self, canvas)
- self.canvas = canvas
- self._idle = True
- self.statbar = None
- self.prevZoomRect = None
- # for now, use alternate zoom-rectangle drawing on all
- # Macs. N.B. In future versions of wx it may be possible to
- # detect Retina displays with window.GetContentScaleFactor()
- # and/or dc.GetContentScaleFactor()
- self.retinaFix = 'wxMac' in wx.PlatformInfo
-
- def get_canvas(self, frame, fig):
- return type(self.canvas)(frame, -1, fig)
-
- def _init_toolbar(self):
- DEBUG_MSG("_init_toolbar", 1, self)
-
- self._parent = self.canvas.GetParent()
-
- self.wx_ids = {}
- for text, tooltip_text, image_file, callback in self.toolitems:
- if text is None:
- self.AddSeparator()
- continue
- self.wx_ids[text] = wx.NewId()
- wxc._AddTool(self, self.wx_ids, text,
- _load_bitmap(image_file + '.png'),
- tooltip_text)
-
- self.Bind(wx.EVT_TOOL, getattr(self, callback),
- id=self.wx_ids[text])
-
- self.Realize()
-
- def zoom(self, *args):
- self.ToggleTool(self.wx_ids['Pan'], False)
- NavigationToolbar2.zoom(self, *args)
-
- def pan(self, *args):
- self.ToggleTool(self.wx_ids['Zoom'], False)
- NavigationToolbar2.pan(self, *args)
-
- def configure_subplots(self, evt):
- frame = wx.Frame(None, -1, "Configure subplots")
-
- toolfig = Figure((6, 3))
- canvas = self.get_canvas(frame, toolfig)
-
- # Create a figure manager to manage things
- figmgr = FigureManager(canvas, 1, frame)
-
- # Now put all into a sizer
- sizer = wx.BoxSizer(wx.VERTICAL)
- # This way of adding to sizer allows resizing
- sizer.Add(canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
- frame.SetSizer(sizer)
- frame.Fit()
- tool = SubplotTool(self.canvas.figure, toolfig)
- frame.Show()
-
- def save_figure(self, *args):
- # Fetch the required filename and file type.
- filetypes, exts, filter_index = self.canvas._get_imagesave_wildcards()
- default_file = self.canvas.get_default_filename()
- dlg = wx.FileDialog(self._parent, "Save to file", "", default_file,
- filetypes,
- wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
- dlg.SetFilterIndex(filter_index)
- if dlg.ShowModal() == wx.ID_OK:
- dirname = dlg.GetDirectory()
- filename = dlg.GetFilename()
- DEBUG_MSG(
- 'Save file dir:%s name:%s' %
- (dirname, filename), 3, self)
- format = exts[dlg.GetFilterIndex()]
- basename, ext = os.path.splitext(filename)
- if ext.startswith('.'):
- ext = ext[1:]
- if ext in ('svg', 'pdf', 'ps', 'eps', 'png') and format != ext:
- # looks like they forgot to set the image type drop
- # down, going with the extension.
- warnings.warn(
- 'extension %s did not match the selected '
- 'image type %s; going with %s' %
- (ext, format, ext), stacklevel=0)
- format = ext
- try:
- self.canvas.figure.savefig(
- os.path.join(dirname, filename), format=format)
- except Exception as e:
- error_msg_wx(str(e))
-
- def set_cursor(self, cursor):
- cursor = wxc.Cursor(cursord[cursor])
- self.canvas.SetCursor(cursor)
- self.canvas.Update()
-
- @cbook.deprecated("2.1", alternative="canvas.draw_idle")
- def dynamic_update(self):
- d = self._idle
- self._idle = False
- if d:
- self.canvas.draw()
- self._idle = True
-
- def press(self, event):
- if self._active == 'ZOOM':
- if not self.retinaFix:
- self.wxoverlay = wx.Overlay()
- else:
- if event.inaxes is not None:
- self.savedRetinaImage = self.canvas.copy_from_bbox(
- event.inaxes.bbox)
- self.zoomStartX = event.xdata
- self.zoomStartY = event.ydata
- self.zoomAxes = event.inaxes
-
- def release(self, event):
- if self._active == 'ZOOM':
- # When the mouse is released we reset the overlay and it
- # restores the former content to the window.
- if not self.retinaFix:
- self.wxoverlay.Reset()
- del self.wxoverlay
- else:
- del self.savedRetinaImage
- if self.prevZoomRect:
- self.prevZoomRect.pop(0).remove()
- self.prevZoomRect = None
- if self.zoomAxes:
- self.zoomAxes = None
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- if self.retinaFix: # On Macs, use the following code
- # wx.DCOverlay does not work properly on Retina displays.
- rubberBandColor = '#C0C0FF'
- if self.prevZoomRect:
- self.prevZoomRect.pop(0).remove()
- self.canvas.restore_region(self.savedRetinaImage)
- X0, X1 = self.zoomStartX, event.xdata
- Y0, Y1 = self.zoomStartY, event.ydata
- lineX = (X0, X0, X1, X1, X0)
- lineY = (Y0, Y1, Y1, Y0, Y0)
- self.prevZoomRect = self.zoomAxes.plot(
- lineX, lineY, '-', color=rubberBandColor)
- self.zoomAxes.draw_artist(self.prevZoomRect[0])
- self.canvas.blit(self.zoomAxes.bbox)
- return
-
- # Use an Overlay to draw a rubberband-like bounding box.
-
- dc = wx.ClientDC(self.canvas)
- odc = wx.DCOverlay(self.wxoverlay, dc)
- odc.Clear()
-
- # Mac's DC is already the same as a GCDC, and it causes
- # problems with the overlay if we try to use an actual
- # wx.GCDC so don't try it.
- if 'wxMac' not in wx.PlatformInfo:
- dc = wx.GCDC(dc)
-
- height = self.canvas.figure.bbox.height
- y1 = height - y1
- y0 = height - y0
-
- if y1 < y0:
- y0, y1 = y1, y0
- if x1 < x0:
- x0, x1 = x1, x0
-
- w = x1 - x0
- h = y1 - y0
- rect = wx.Rect(x0, y0, w, h)
-
- rubberBandColor = '#C0C0FF' # or load from config?
-
- # Set a pen for the border
- color = wxc.NamedColour(rubberBandColor)
- dc.SetPen(wx.Pen(color, 1))
-
- # use the same color, plus alpha for the brush
- r, g, b, a = color.Get(True)
- color.Set(r, g, b, 0x60)
- dc.SetBrush(wx.Brush(color))
- if wxc.is_phoenix:
- dc.DrawRectangle(rect)
- else:
- dc.DrawRectangleRect(rect)
-
- def set_status_bar(self, statbar):
- self.statbar = statbar
-
- def set_message(self, s):
- if self.statbar is not None:
- self.statbar.set_function(s)
-
- def set_history_buttons(self):
- can_backward = self._nav_stack._pos > 0
- can_forward = self._nav_stack._pos < len(self._nav_stack._elements) - 1
- self.EnableTool(self.wx_ids['Back'], can_backward)
- self.EnableTool(self.wx_ids['Forward'], can_forward)
-
-
-@cbook.deprecated("2.2", alternative="NavigationToolbar2Wx")
-class Toolbar(NavigationToolbar2Wx):
- pass
-
-
-class StatusBarWx(wx.StatusBar):
- """
- A status bar is added to _FigureFrame to allow measurements and the
- previously selected scroll function to be displayed as a user
- convenience.
- """
-
- def __init__(self, parent):
- wx.StatusBar.__init__(self, parent, -1)
- self.SetFieldsCount(2)
- self.SetStatusText("None", 1)
- # self.SetStatusText("Measurement: None", 2)
- # self.Reposition()
-
- def set_function(self, string):
- self.SetStatusText("%s" % string, 1)
-
- # def set_measurement(self, string):
- # self.SetStatusText("Measurement: %s" % string, 2)
-
-
-# tools for matplotlib.backend_managers.ToolManager:
-# for now only SaveFigure, SetCursor and Rubberband are implemented
-# once a ToolbarWx is implemented, also FigureManagerWx needs to be
-# modified, similar to pull request #9934
-
-class SaveFigureWx(backend_tools.SaveFigureBase):
- def trigger(self, *args):
- # Fetch the required filename and file type.
- filetypes, exts, filter_index = self.canvas._get_imagesave_wildcards()
- default_dir = os.path.expanduser(
- matplotlib.rcParams['savefig.directory'])
- default_file = self.canvas.get_default_filename()
- dlg = wx.FileDialog(self.canvas.GetTopLevelParent(), "Save to file",
- default_dir, default_file, filetypes,
- wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
- dlg.SetFilterIndex(filter_index)
- if dlg.ShowModal() != wx.ID_OK:
- return
-
- dirname = dlg.GetDirectory()
- filename = dlg.GetFilename()
- DEBUG_MSG('Save file dir:%s name:%s' % (dirname, filename), 3, self)
- format = exts[dlg.GetFilterIndex()]
- basename, ext = os.path.splitext(filename)
- if ext.startswith('.'):
- ext = ext[1:]
- if ext in ('svg', 'pdf', 'ps', 'eps', 'png') and format != ext:
- # looks like they forgot to set the image type drop
- # down, going with the extension.
- warnings.warn(
- 'extension %s did not match the selected '
- 'image type %s; going with %s' %
- (ext, format, ext), stacklevel=0)
- format = ext
- if default_dir != "":
- matplotlib.rcParams['savefig.directory'] = dirname
- try:
- self.canvas.figure.savefig(
- os.path.join(dirname, filename), format=format)
- except Exception as e:
- error_msg_wx(str(e))
-
-
-class SetCursorWx(backend_tools.SetCursorBase):
- def set_cursor(self, cursor):
- cursor = wxc.Cursor(cursord[cursor])
- self.canvas.SetCursor(cursor)
- self.canvas.Update()
-
-
-if 'wxMac' not in wx.PlatformInfo:
- # on most platforms, use overlay
- class RubberbandWx(backend_tools.RubberbandBase):
- def __init__(self, *args, **kwargs):
- backend_tools.RubberbandBase.__init__(self, *args, **kwargs)
- self.wxoverlay = None
-
- def draw_rubberband(self, x0, y0, x1, y1):
- # Use an Overlay to draw a rubberband-like bounding box.
- if self.wxoverlay is None:
- self.wxoverlay = wx.Overlay()
- dc = wx.ClientDC(self.canvas)
- odc = wx.DCOverlay(self.wxoverlay, dc)
- odc.Clear()
-
- dc = wx.GCDC(dc)
-
- height = self.canvas.figure.bbox.height
- y1 = height - y1
- y0 = height - y0
-
- if y1 < y0:
- y0, y1 = y1, y0
- if x1 < x0:
- x0, x1 = x1, x0
-
- w = x1 - x0
- h = y1 - y0
- rect = wx.Rect(x0, y0, w, h)
-
- rubberBandColor = '#C0C0FF' # or load from config?
-
- # Set a pen for the border
- color = wxc.NamedColour(rubberBandColor)
- dc.SetPen(wx.Pen(color, 1))
-
- # use the same color, plus alpha for the brush
- r, g, b, a = color.Get(True)
- color.Set(r, g, b, 0x60)
- dc.SetBrush(wx.Brush(color))
- if wxc.is_phoenix:
- dc.DrawRectangle(rect)
- else:
- dc.DrawRectangleRect(rect)
-
- def remove_rubberband(self):
- if self.wxoverlay is None:
- return
- self.wxoverlay.Reset()
- self.wxoverlay = None
-
-else:
- # on Mac OS retina displays DCOverlay does not work
- # and dc.SetLogicalFunction does not have an effect on any display
- # the workaround is to blit the full image for remove_rubberband
- class RubberbandWx(backend_tools.RubberbandBase):
- def __init__(self, *args, **kwargs):
- backend_tools.RubberbandBase.__init__(self, *args, **kwargs)
- self._rect = None
-
- def draw_rubberband(self, x0, y0, x1, y1):
- dc = wx.ClientDC(self.canvas)
- # this would be required if the Canvas is a ScrolledWindow,
- # which is not the case for now
- # self.PrepareDC(dc)
-
- # delete old rubberband
- if self._rect:
- self.remove_rubberband(dc)
-
- # draw new rubberband
- dc.SetPen(wx.Pen(wx.BLACK, 1, wx.SOLID))
- dc.SetBrush(wx.TRANSPARENT_BRUSH)
- self._rect = (x0, self.canvas._height-y0, x1-x0, -y1+y0)
- if wxc.is_phoenix:
- dc.DrawRectangle(self._rect)
- else:
- dc.DrawRectangleRect(self._rect)
-
- def remove_rubberband(self, dc=None):
- if not self._rect:
- return
- if self.canvas.bitmap:
- if dc is None:
- dc = wx.ClientDC(self.canvas)
- dc.DrawBitmap(self.canvas.bitmap, 0, 0)
- # for testing the method on Windows, use this code instead:
- # img = self.canvas.bitmap.ConvertToImage()
- # bmp = img.ConvertToBitmap()
- # dc.DrawBitmap(bmp, 0, 0)
- self._rect = None
-
-
-backend_tools.ToolSaveFigure = SaveFigureWx
-backend_tools.ToolSetCursor = SetCursorWx
-backend_tools.ToolRubberband = RubberbandWx
-
-
-# < Additions for printing support: Matt Newville
-
-class PrintoutWx(wx.Printout):
- """
- Simple wrapper around wx Printout class -- all the real work
- here is scaling the matplotlib canvas bitmap to the current
- printer's definition.
- """
-
- def __init__(self, canvas, width=5.5, margin=0.5, title='matplotlib'):
- wx.Printout.__init__(self, title=title)
- self.canvas = canvas
- # width, in inches of output figure (approximate)
- self.width = width
- self.margin = margin
-
- def HasPage(self, page):
- # current only supports 1 page print
- return page == 1
-
- def GetPageInfo(self):
- return (1, 1, 1, 1)
-
- def OnPrintPage(self, page):
- self.canvas.draw()
-
- dc = self.GetDC()
- (ppw, pph) = self.GetPPIPrinter() # printer's pixels per in
- (pgw, pgh) = self.GetPageSizePixels() # page size in pixels
- (dcw, dch) = dc.GetSize()
- if wxc.is_phoenix:
- (grw, grh) = self.canvas.GetSize()
- else:
- (grw, grh) = self.canvas.GetSizeTuple()
-
- # save current figure dpi resolution and bg color,
- # so that we can temporarily set them to the dpi of
- # the printer, and the bg color to white
- bgcolor = self.canvas.figure.get_facecolor()
- fig_dpi = self.canvas.figure.dpi
-
- # draw the bitmap, scaled appropriately
- vscale = float(ppw) / fig_dpi
-
- # set figure resolution,bg color for printer
- self.canvas.figure.dpi = ppw
- self.canvas.figure.set_facecolor('#FFFFFF')
-
- renderer = RendererWx(self.canvas.bitmap, self.canvas.figure.dpi)
- self.canvas.figure.draw(renderer)
- self.canvas.bitmap.SetWidth(
- int(self.canvas.bitmap.GetWidth() * vscale))
- self.canvas.bitmap.SetHeight(
- int(self.canvas.bitmap.GetHeight() * vscale))
- self.canvas.draw()
-
- # page may need additional scaling on preview
- page_scale = 1.0
- if self.IsPreview():
- page_scale = float(dcw) / pgw
-
- # get margin in pixels = (margin in in) * (pixels/in)
- top_margin = int(self.margin * pph * page_scale)
- left_margin = int(self.margin * ppw * page_scale)
-
- # set scale so that width of output is self.width inches
- # (assuming grw is size of graph in inches....)
- user_scale = (self.width * fig_dpi * page_scale) / float(grw)
-
- dc.SetDeviceOrigin(left_margin, top_margin)
- dc.SetUserScale(user_scale, user_scale)
-
- # this cute little number avoid API inconsistencies in wx
- try:
- dc.DrawBitmap(self.canvas.bitmap, 0, 0)
- except Exception:
- try:
- dc.DrawBitmap(self.canvas.bitmap, (0, 0))
- except Exception:
- pass
-
- # restore original figure resolution
- self.canvas.figure.set_facecolor(bgcolor)
- self.canvas.figure.dpi = fig_dpi
- self.canvas.draw()
- return True
-# >
-
-
-@_Backend.export
-class _BackendWx(_Backend):
- FigureCanvas = FigureCanvasWx
- FigureManager = FigureManagerWx
- _frame_class = FigureFrameWx
-
- @staticmethod
- def trigger_manager_draw(manager):
- manager.canvas.draw_idle()
-
- @classmethod
- def new_figure_manager(cls, num, *args, **kwargs):
- # Create a wx.App instance if it has not been created sofar.
- wxapp = wx.GetApp()
- if wxapp is None:
- wxapp = wx.App(False)
- wxapp.SetExitOnFrameDelete(True)
- # Retain a reference to the app object so that it does not get
- # garbage collected.
- _BackendWx._theWxApp = wxapp
- return super(_BackendWx, cls).new_figure_manager(num, *args, **kwargs)
-
- @classmethod
- def new_figure_manager_given_figure(cls, num, figure):
- frame = cls._frame_class(num, figure)
- figmgr = frame.get_figure_manager()
- if matplotlib.is_interactive():
- figmgr.frame.Show()
- figure.canvas.draw_idle()
- return figmgr
-
- @staticmethod
- def mainloop():
- if not wx.App.IsMainLoopRunning():
- wxapp = wx.GetApp()
- if wxapp is not None:
- wxapp.MainLoop()
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_wxagg.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_wxagg.py
deleted file mode 100644
index 041f274a78..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_wxagg.py
+++ /dev/null
@@ -1,147 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import wx
-
-import matplotlib
-from matplotlib import cbook
-from . import wx_compat as wxc
-from .backend_agg import FigureCanvasAgg
-from .backend_wx import (
- _BackendWx, _FigureCanvasWxBase, FigureFrameWx,
- NavigationToolbar2Wx as NavigationToolbar2WxAgg)
-
-
-class FigureFrameWxAgg(FigureFrameWx):
- def get_canvas(self, fig):
- return FigureCanvasWxAgg(self, -1, fig)
-
-
-class FigureCanvasWxAgg(FigureCanvasAgg, _FigureCanvasWxBase):
- """
- The FigureCanvas contains the figure and does event handling.
-
- In the wxPython backend, it is derived from wxPanel, and (usually)
- lives inside a frame instantiated by a FigureManagerWx. The parent
- window probably implements a wxSizer to control the displayed
- control size - but we give a hint as to our preferred minimum
- size.
- """
-
- def draw(self, drawDC=None):
- """
- Render the figure using agg.
- """
- FigureCanvasAgg.draw(self)
-
- self.bitmap = _convert_agg_to_wx_bitmap(self.get_renderer(), None)
- self._isDrawn = True
- self.gui_repaint(drawDC=drawDC, origin='WXAgg')
-
- def blit(self, bbox=None):
- """
- Transfer the region of the agg buffer defined by bbox to the display.
- If bbox is None, the entire buffer is transferred.
- """
- if bbox is None:
- self.bitmap = _convert_agg_to_wx_bitmap(self.get_renderer(), None)
- self.gui_repaint()
- return
-
- l, b, w, h = bbox.bounds
- r = l + w
- t = b + h
- x = int(l)
- y = int(self.bitmap.GetHeight() - t)
-
- srcBmp = _convert_agg_to_wx_bitmap(self.get_renderer(), None)
- srcDC = wx.MemoryDC()
- srcDC.SelectObject(srcBmp)
-
- destDC = wx.MemoryDC()
- destDC.SelectObject(self.bitmap)
-
- destDC.Blit(x, y, int(w), int(h), srcDC, x, y)
-
- destDC.SelectObject(wx.NullBitmap)
- srcDC.SelectObject(wx.NullBitmap)
- self.gui_repaint()
-
- filetypes = FigureCanvasAgg.filetypes
-
-
-@cbook.deprecated("2.2", alternative="NavigationToolbar2WxAgg")
-class Toolbar(NavigationToolbar2WxAgg):
- pass
-
-
-# agg/wxPython image conversion functions (wxPython >= 2.8)
-
-def _convert_agg_to_wx_image(agg, bbox):
- """
- Convert the region of the agg buffer bounded by bbox to a wx.Image. If
- bbox is None, the entire buffer is converted.
-
- Note: agg must be a backend_agg.RendererAgg instance.
- """
- if bbox is None:
- # agg => rgb -> image
- image = wxc.EmptyImage(int(agg.width), int(agg.height))
- image.SetData(agg.tostring_rgb())
- return image
- else:
- # agg => rgba buffer -> bitmap => clipped bitmap => image
- return wx.ImageFromBitmap(_WX28_clipped_agg_as_bitmap(agg, bbox))
-
-
-def _convert_agg_to_wx_bitmap(agg, bbox):
- """
- Convert the region of the agg buffer bounded by bbox to a wx.Bitmap. If
- bbox is None, the entire buffer is converted.
-
- Note: agg must be a backend_agg.RendererAgg instance.
- """
- if bbox is None:
- # agg => rgba buffer -> bitmap
- return wxc.BitmapFromBuffer(int(agg.width), int(agg.height),
- agg.buffer_rgba())
- else:
- # agg => rgba buffer -> bitmap => clipped bitmap
- return _WX28_clipped_agg_as_bitmap(agg, bbox)
-
-
-def _WX28_clipped_agg_as_bitmap(agg, bbox):
- """
- Convert the region of a the agg buffer bounded by bbox to a wx.Bitmap.
-
- Note: agg must be a backend_agg.RendererAgg instance.
- """
- l, b, width, height = bbox.bounds
- r = l + width
- t = b + height
-
- srcBmp = wxc.BitmapFromBuffer(int(agg.width), int(agg.height),
- agg.buffer_rgba())
- srcDC = wx.MemoryDC()
- srcDC.SelectObject(srcBmp)
-
- destBmp = wxc.EmptyBitmap(int(width), int(height))
- destDC = wx.MemoryDC()
- destDC.SelectObject(destBmp)
-
- x = int(l)
- y = int(int(agg.height) - t)
- destDC.Blit(0, 0, int(width), int(height), srcDC, x, y)
-
- srcDC.SelectObject(wx.NullBitmap)
- destDC.SelectObject(wx.NullBitmap)
-
- return destBmp
-
-
-@_BackendWx.export
-class _BackendWxAgg(_BackendWx):
- FigureCanvas = FigureCanvasWxAgg
- _frame_class = FigureFrameWxAgg
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/backend_wxcairo.py b/contrib/python/matplotlib/py2/matplotlib/backends/backend_wxcairo.py
deleted file mode 100644
index fb3290f2bb..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/backend_wxcairo.py
+++ /dev/null
@@ -1,53 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import wx
-
-from .backend_cairo import cairo, FigureCanvasCairo, RendererCairo
-from .backend_wx import (
- _BackendWx, _FigureCanvasWxBase, FigureFrameWx,
- NavigationToolbar2Wx as NavigationToolbar2WxCairo)
-import wx.lib.wxcairo as wxcairo
-
-
-class FigureFrameWxCairo(FigureFrameWx):
- def get_canvas(self, fig):
- return FigureCanvasWxCairo(self, -1, fig)
-
-
-class FigureCanvasWxCairo(_FigureCanvasWxBase, FigureCanvasCairo):
- """
- The FigureCanvas contains the figure and does event handling.
-
- In the wxPython backend, it is derived from wxPanel, and (usually) lives
- inside a frame instantiated by a FigureManagerWx. The parent window
- probably implements a wxSizer to control the displayed control size - but
- we give a hint as to our preferred minimum size.
- """
-
- def __init__(self, parent, id, figure):
- # _FigureCanvasWxBase should be fixed to have the same signature as
- # every other FigureCanvas and use cooperative inheritance, but in the
- # meantime the following will make do.
- _FigureCanvasWxBase.__init__(self, parent, id, figure)
- FigureCanvasCairo.__init__(self, figure)
- self._renderer = RendererCairo(self.figure.dpi)
-
- def draw(self, drawDC=None):
- width = int(self.figure.bbox.width)
- height = int(self.figure.bbox.height)
- surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
- self._renderer.set_ctx_from_surface(surface)
- self._renderer.set_width_height(width, height)
- self.figure.draw(self._renderer)
- self.bitmap = wxcairo.BitmapFromImageSurface(surface)
- self._isDrawn = True
- self.gui_repaint(drawDC=drawDC, origin='WXCairo')
-
-
-@_BackendWx.export
-class _BackendWxCairo(_BackendWx):
- FigureCanvas = FigureCanvasWxCairo
- _frame_class = FigureFrameWxCairo
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/qt_compat.py b/contrib/python/matplotlib/py2/matplotlib/backends/qt_compat.py
deleted file mode 100644
index 6b386143a3..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/qt_compat.py
+++ /dev/null
@@ -1,176 +0,0 @@
-"""
-Qt binding and backend selector.
-
-The selection logic is as follows:
-- if any of PyQt5, PySide2, PyQt4 or PySide have already been imported
- (checked in that order), use it;
-- otherwise, if the QT_API environment variable (used by Enthought) is
- set, use it to determine which binding to use (but do not change the
- backend based on it; i.e. if the Qt4Agg backend is requested but QT_API
- is set to "pyqt5", then actually use Qt4 with the binding specified by
- ``rcParams["backend.qt4"]``;
-- otherwise, use whatever the rcParams indicate.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from distutils.version import LooseVersion
-import os
-import sys
-
-from matplotlib import rcParams
-
-QT_API_PYQT5 = "PyQt5"
-QT_API_PYSIDE2 = "PySide2"
-QT_API_PYQTv2 = "PyQt4v2"
-QT_API_PYSIDE = "PySide"
-QT_API_PYQT = "PyQt4" # Use the old sip v1 API (Py3 defaults to v2).
-QT_API_ENV = os.environ.get("QT_API")
-# Mapping of QT_API_ENV to requested binding. ETS does not support PyQt4v1.
-# (https://github.com/enthought/pyface/blob/master/pyface/qt/__init__.py)
-_ETS = {"pyqt5": QT_API_PYQT5, "pyside2": QT_API_PYSIDE2,
- "pyqt": QT_API_PYQTv2, "pyside": QT_API_PYSIDE,
- None: None}
-# First, check if anything is already imported.
-if "PyQt5" in sys.modules:
- QT_API = QT_API_PYQT5
- dict.__setitem__(rcParams, "backend.qt5", QT_API)
-elif "PySide2" in sys.modules:
- QT_API = QT_API_PYSIDE2
- dict.__setitem__(rcParams, "backend.qt5", QT_API)
-elif "PyQt4" in sys.modules:
- QT_API = QT_API_PYQTv2
- dict.__setitem__(rcParams, "backend.qt4", QT_API)
-elif "PySide" in sys.modules:
- QT_API = QT_API_PYSIDE
- dict.__setitem__(rcParams, "backend.qt4", QT_API)
-# Otherwise, check the QT_API environment variable (from Enthought). This can
-# only override the binding, not the backend (in other words, we check that the
-# requested backend actually matches).
-elif rcParams["backend"] in ["Qt5Agg", "Qt5Cairo"]:
- if QT_API_ENV == "pyqt5":
- dict.__setitem__(rcParams, "backend.qt5", QT_API_PYQT5)
- elif QT_API_ENV == "pyside2":
- dict.__setitem__(rcParams, "backend.qt5", QT_API_PYSIDE2)
- QT_API = dict.__getitem__(rcParams, "backend.qt5")
-elif rcParams["backend"] in ["Qt4Agg", "Qt4Cairo"]:
- if QT_API_ENV == "pyqt4":
- dict.__setitem__(rcParams, "backend.qt4", QT_API_PYQTv2)
- elif QT_API_ENV == "pyside":
- dict.__setitem__(rcParams, "backend.qt4", QT_API_PYSIDE)
- QT_API = dict.__getitem__(rcParams, "backend.qt4")
-# A non-Qt backend was selected but we still got there (possible, e.g., when
-# fully manually embedding Matplotlib in a Qt app without using pyplot).
-else:
- try:
- QT_API = _ETS[QT_API_ENV]
- except KeyError:
- raise RuntimeError(
- "The environment variable QT_API has the unrecognized value {!r};"
- "valid values are 'pyqt5', 'pyside2', 'pyqt', and 'pyside'")
-
-
-def _setup_pyqt5():
- global QtCore, QtGui, QtWidgets, __version__, is_pyqt5, _getSaveFileName
-
- if QT_API == QT_API_PYQT5:
- from PyQt5 import QtCore, QtGui, QtWidgets
- __version__ = QtCore.PYQT_VERSION_STR
- QtCore.Signal = QtCore.pyqtSignal
- QtCore.Slot = QtCore.pyqtSlot
- QtCore.Property = QtCore.pyqtProperty
- elif QT_API == QT_API_PYSIDE2:
- from PySide2 import QtCore, QtGui, QtWidgets, __version__
- else:
- raise ValueError("Unexpected value for the 'backend.qt5' rcparam")
- _getSaveFileName = QtWidgets.QFileDialog.getSaveFileName
-
- def is_pyqt5():
- return True
-
-
-def _setup_pyqt4():
- global QtCore, QtGui, QtWidgets, __version__, is_pyqt5, _getSaveFileName
-
- def _setup_pyqt4_internal(api):
- global QtCore, QtGui, QtWidgets, \
- __version__, is_pyqt5, _getSaveFileName
- # List of incompatible APIs:
- # http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html
- _sip_apis = ["QDate", "QDateTime", "QString", "QTextStream", "QTime",
- "QUrl", "QVariant"]
- try:
- import sip
- except ImportError:
- pass
- else:
- for _sip_api in _sip_apis:
- try:
- sip.setapi(_sip_api, api)
- except ValueError:
- pass
- from PyQt4 import QtCore, QtGui
- __version__ = QtCore.PYQT_VERSION_STR
- # PyQt 4.6 introduced getSaveFileNameAndFilter:
- # https://riverbankcomputing.com/news/pyqt-46
- if __version__ < LooseVersion("4.6"):
- raise ImportError("PyQt<4.6 is not supported")
- QtCore.Signal = QtCore.pyqtSignal
- QtCore.Slot = QtCore.pyqtSlot
- QtCore.Property = QtCore.pyqtProperty
- _getSaveFileName = QtGui.QFileDialog.getSaveFileNameAndFilter
-
- if QT_API == QT_API_PYQTv2:
- _setup_pyqt4_internal(api=2)
- elif QT_API == QT_API_PYSIDE:
- from PySide import QtCore, QtGui, __version__, __version_info__
- # PySide 1.0.3 fixed the following:
- # https://srinikom.github.io/pyside-bz-archive/809.html
- if __version_info__ < (1, 0, 3):
- raise ImportError("PySide<1.0.3 is not supported")
- _getSaveFileName = QtGui.QFileDialog.getSaveFileName
- elif QT_API == QT_API_PYQT:
- _setup_pyqt4_internal(api=1)
- else:
- raise ValueError("Unexpected value for the 'backend.qt4' rcparam")
- QtWidgets = QtGui
-
- def is_pyqt5():
- return False
-
-
-if QT_API in [QT_API_PYQT5, QT_API_PYSIDE2]:
- _setup_pyqt5()
-elif QT_API in [QT_API_PYQTv2, QT_API_PYSIDE, QT_API_PYQT]:
- _setup_pyqt4()
-elif QT_API is None:
- if rcParams["backend"] == "Qt4Agg":
- _candidates = [(_setup_pyqt4, QT_API_PYQTv2),
- (_setup_pyqt4, QT_API_PYSIDE),
- (_setup_pyqt4, QT_API_PYQT),
- (_setup_pyqt5, QT_API_PYQT5),
- (_setup_pyqt5, QT_API_PYSIDE2)]
- else:
- _candidates = [(_setup_pyqt5, QT_API_PYQT5),
- (_setup_pyqt5, QT_API_PYSIDE2),
- (_setup_pyqt4, QT_API_PYQTv2),
- (_setup_pyqt4, QT_API_PYSIDE),
- (_setup_pyqt4, QT_API_PYQT)]
- for _setup, QT_API in _candidates:
- try:
- _setup()
- except ImportError:
- continue
- break
- else:
- raise ImportError("Failed to import any qt binding")
-else: # We should not get there.
- raise AssertionError("Unexpected QT_API: {}".format(QT_API))
-
-
-# These globals are only defined for backcompatibilty purposes.
-ETS = dict(pyqt=(QT_API_PYQTv2, 4), pyside=(QT_API_PYSIDE, 4),
- pyqt5=(QT_API_PYQT5, 5), pyside2=(QT_API_PYSIDE2, 5))
-QT_RC_MAJOR_VERSION = 5 if is_pyqt5() else 4
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/qt_editor/__init__.py b/contrib/python/matplotlib/py2/matplotlib/backends/qt_editor/__init__.py
deleted file mode 100644
index 800d82e7ee..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/qt_editor/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/qt_editor/figureoptions.py b/contrib/python/matplotlib/py2/matplotlib/backends/qt_editor/figureoptions.py
deleted file mode 100644
index f0050d3675..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/qt_editor/figureoptions.py
+++ /dev/null
@@ -1,262 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# Copyright © 2009 Pierre Raybaut
-# Licensed under the terms of the MIT License
-# see the mpl licenses directory for a copy of the license
-
-
-"""Module that provides a GUI-based editor for matplotlib's figure options"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import os.path as osp
-import re
-
-import matplotlib
-from matplotlib import cm, colors as mcolors, markers, image as mimage
-import matplotlib.backends.qt_editor.formlayout as formlayout
-from matplotlib.backends.qt_compat import QtGui
-
-
-def get_icon(name):
- basedir = osp.join(matplotlib.rcParams['datapath'], 'images')
- return QtGui.QIcon(osp.join(basedir, name))
-
-
-LINESTYLES = {'-': 'Solid',
- '--': 'Dashed',
- '-.': 'DashDot',
- ':': 'Dotted',
- 'None': 'None',
- }
-
-DRAWSTYLES = {
- 'default': 'Default',
- 'steps-pre': 'Steps (Pre)', 'steps': 'Steps (Pre)',
- 'steps-mid': 'Steps (Mid)',
- 'steps-post': 'Steps (Post)'}
-
-MARKERS = markers.MarkerStyle.markers
-
-
-def figure_edit(axes, parent=None):
- """Edit matplotlib figure options"""
- sep = (None, None) # separator
-
- # Get / General
- # Cast to builtin floats as they have nicer reprs.
- xmin, xmax = map(float, axes.get_xlim())
- ymin, ymax = map(float, axes.get_ylim())
- general = [('Title', axes.get_title()),
- sep,
- (None, "<b>X-Axis</b>"),
- ('Left', xmin), ('Right', xmax),
- ('Label', axes.get_xlabel()),
- ('Scale', [axes.get_xscale(), 'linear', 'log', 'logit']),
- sep,
- (None, "<b>Y-Axis</b>"),
- ('Bottom', ymin), ('Top', ymax),
- ('Label', axes.get_ylabel()),
- ('Scale', [axes.get_yscale(), 'linear', 'log', 'logit']),
- sep,
- ('(Re-)Generate automatic legend', False),
- ]
-
- # Save the unit data
- xconverter = axes.xaxis.converter
- yconverter = axes.yaxis.converter
- xunits = axes.xaxis.get_units()
- yunits = axes.yaxis.get_units()
-
- # Sorting for default labels (_lineXXX, _imageXXX).
- def cmp_key(label):
- match = re.match(r"(_line|_image)(\d+)", label)
- if match:
- return match.group(1), int(match.group(2))
- else:
- return label, 0
-
- # Get / Curves
- linedict = {}
- for line in axes.get_lines():
- label = line.get_label()
- if label == '_nolegend_':
- continue
- linedict[label] = line
- curves = []
-
- def prepare_data(d, init):
- """Prepare entry for FormLayout.
-
- `d` is a mapping of shorthands to style names (a single style may
- have multiple shorthands, in particular the shorthands `None`,
- `"None"`, `"none"` and `""` are synonyms); `init` is one shorthand
- of the initial style.
-
- This function returns an list suitable for initializing a
- FormLayout combobox, namely `[initial_name, (shorthand,
- style_name), (shorthand, style_name), ...]`.
- """
- # Drop duplicate shorthands from dict (by overwriting them during
- # the dict comprehension).
- name2short = {name: short for short, name in d.items()}
- # Convert back to {shorthand: name}.
- short2name = {short: name for name, short in name2short.items()}
- # Find the kept shorthand for the style specified by init.
- canonical_init = name2short[d[init]]
- # Sort by representation and prepend the initial value.
- return ([canonical_init] +
- sorted(short2name.items(),
- key=lambda short_and_name: short_and_name[1]))
-
- curvelabels = sorted(linedict, key=cmp_key)
- for label in curvelabels:
- line = linedict[label]
- color = mcolors.to_hex(
- mcolors.to_rgba(line.get_color(), line.get_alpha()),
- keep_alpha=True)
- ec = mcolors.to_hex(
- mcolors.to_rgba(line.get_markeredgecolor(), line.get_alpha()),
- keep_alpha=True)
- fc = mcolors.to_hex(
- mcolors.to_rgba(line.get_markerfacecolor(), line.get_alpha()),
- keep_alpha=True)
- curvedata = [
- ('Label', label),
- sep,
- (None, '<b>Line</b>'),
- ('Line style', prepare_data(LINESTYLES, line.get_linestyle())),
- ('Draw style', prepare_data(DRAWSTYLES, line.get_drawstyle())),
- ('Width', line.get_linewidth()),
- ('Color (RGBA)', color),
- sep,
- (None, '<b>Marker</b>'),
- ('Style', prepare_data(MARKERS, line.get_marker())),
- ('Size', line.get_markersize()),
- ('Face color (RGBA)', fc),
- ('Edge color (RGBA)', ec)]
- curves.append([curvedata, label, ""])
- # Is there a curve displayed?
- has_curve = bool(curves)
-
- # Get / Images
- imagedict = {}
- for image in axes.get_images():
- label = image.get_label()
- if label == '_nolegend_':
- continue
- imagedict[label] = image
- imagelabels = sorted(imagedict, key=cmp_key)
- images = []
- cmaps = [(cmap, name) for name, cmap in sorted(cm.cmap_d.items())]
- for label in imagelabels:
- image = imagedict[label]
- cmap = image.get_cmap()
- if cmap not in cm.cmap_d.values():
- cmaps = [(cmap, cmap.name)] + cmaps
- low, high = image.get_clim()
- imagedata = [
- ('Label', label),
- ('Colormap', [cmap.name] + cmaps),
- ('Min. value', low),
- ('Max. value', high),
- ('Interpolation',
- [image.get_interpolation()]
- + [(name, name) for name in sorted(mimage.interpolations_names)])]
- images.append([imagedata, label, ""])
- # Is there an image displayed?
- has_image = bool(images)
-
- datalist = [(general, "Axes", "")]
- if curves:
- datalist.append((curves, "Curves", ""))
- if images:
- datalist.append((images, "Images", ""))
-
- def apply_callback(data):
- """This function will be called to apply changes"""
- orig_xlim = axes.get_xlim()
- orig_ylim = axes.get_ylim()
-
- general = data.pop(0)
- curves = data.pop(0) if has_curve else []
- images = data.pop(0) if has_image else []
- if data:
- raise ValueError("Unexpected field")
-
- # Set / General
- (title, xmin, xmax, xlabel, xscale, ymin, ymax, ylabel, yscale,
- generate_legend) = general
-
- if axes.get_xscale() != xscale:
- axes.set_xscale(xscale)
- if axes.get_yscale() != yscale:
- axes.set_yscale(yscale)
-
- axes.set_title(title)
- axes.set_xlim(xmin, xmax)
- axes.set_xlabel(xlabel)
- axes.set_ylim(ymin, ymax)
- axes.set_ylabel(ylabel)
-
- # Restore the unit data
- axes.xaxis.converter = xconverter
- axes.yaxis.converter = yconverter
- axes.xaxis.set_units(xunits)
- axes.yaxis.set_units(yunits)
- axes.xaxis._update_axisinfo()
- axes.yaxis._update_axisinfo()
-
- # Set / Curves
- for index, curve in enumerate(curves):
- line = linedict[curvelabels[index]]
- (label, linestyle, drawstyle, linewidth, color, marker, markersize,
- markerfacecolor, markeredgecolor) = curve
- line.set_label(label)
- line.set_linestyle(linestyle)
- line.set_drawstyle(drawstyle)
- line.set_linewidth(linewidth)
- rgba = mcolors.to_rgba(color)
- line.set_alpha(None)
- line.set_color(rgba)
- if marker != 'none':
- line.set_marker(marker)
- line.set_markersize(markersize)
- line.set_markerfacecolor(markerfacecolor)
- line.set_markeredgecolor(markeredgecolor)
-
- # Set / Images
- for index, image_settings in enumerate(images):
- image = imagedict[imagelabels[index]]
- label, cmap, low, high, interpolation = image_settings
- image.set_label(label)
- image.set_cmap(cm.get_cmap(cmap))
- image.set_clim(*sorted([low, high]))
- image.set_interpolation(interpolation)
-
- # re-generate legend, if checkbox is checked
- if generate_legend:
- draggable = None
- ncol = 1
- if axes.legend_ is not None:
- old_legend = axes.get_legend()
- draggable = old_legend._draggable is not None
- ncol = old_legend._ncol
- new_legend = axes.legend(ncol=ncol)
- if new_legend:
- new_legend.draggable(draggable)
-
- # Redraw
- figure = axes.get_figure()
- figure.canvas.draw()
- if not (axes.get_xlim() == orig_xlim and axes.get_ylim() == orig_ylim):
- figure.canvas.toolbar.push_current()
-
- data = formlayout.fedit(datalist, title="Figure options", parent=parent,
- icon=get_icon('qt4_editor_options.svg'),
- apply=apply_callback)
- if data is not None:
- apply_callback(data)
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/qt_editor/formlayout.py b/contrib/python/matplotlib/py2/matplotlib/backends/qt_editor/formlayout.py
deleted file mode 100644
index d5fcdfc901..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/qt_editor/formlayout.py
+++ /dev/null
@@ -1,544 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-formlayout
-==========
-
-Module creating Qt form dialogs/layouts to edit various type of parameters
-
-
-formlayout License Agreement (MIT License)
-------------------------------------------
-
-Copyright (c) 2009 Pierre Raybaut
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-"""
-
-# History:
-# 1.0.10: added float validator (disable "Ok" and "Apply" button when not valid)
-# 1.0.7: added support for "Apply" button
-# 1.0.6: code cleaning
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-__version__ = '1.0.10'
-__license__ = __doc__
-
-import copy
-import datetime
-import warnings
-
-import six
-
-from matplotlib import colors as mcolors
-from matplotlib.backends.qt_compat import QtGui, QtWidgets, QtCore
-
-
-BLACKLIST = {"title", "label"}
-
-
-class ColorButton(QtWidgets.QPushButton):
- """
- Color choosing push button
- """
- colorChanged = QtCore.Signal(QtGui.QColor)
-
- def __init__(self, parent=None):
- QtWidgets.QPushButton.__init__(self, parent)
- self.setFixedSize(20, 20)
- self.setIconSize(QtCore.QSize(12, 12))
- self.clicked.connect(self.choose_color)
- self._color = QtGui.QColor()
-
- def choose_color(self):
- color = QtWidgets.QColorDialog.getColor(
- self._color, self.parentWidget(), "",
- QtWidgets.QColorDialog.ShowAlphaChannel)
- if color.isValid():
- self.set_color(color)
-
- def get_color(self):
- return self._color
-
- @QtCore.Slot(QtGui.QColor)
- def set_color(self, color):
- if color != self._color:
- self._color = color
- self.colorChanged.emit(self._color)
- pixmap = QtGui.QPixmap(self.iconSize())
- pixmap.fill(color)
- self.setIcon(QtGui.QIcon(pixmap))
-
- color = QtCore.Property(QtGui.QColor, get_color, set_color)
-
-
-def to_qcolor(color):
- """Create a QColor from a matplotlib color"""
- qcolor = QtGui.QColor()
- try:
- rgba = mcolors.to_rgba(color)
- except ValueError:
- warnings.warn('Ignoring invalid color %r' % color)
- return qcolor # return invalid QColor
- qcolor.setRgbF(*rgba)
- return qcolor
-
-
-class ColorLayout(QtWidgets.QHBoxLayout):
- """Color-specialized QLineEdit layout"""
- def __init__(self, color, parent=None):
- QtWidgets.QHBoxLayout.__init__(self)
- assert isinstance(color, QtGui.QColor)
- self.lineedit = QtWidgets.QLineEdit(
- mcolors.to_hex(color.getRgbF(), keep_alpha=True), parent)
- self.lineedit.editingFinished.connect(self.update_color)
- self.addWidget(self.lineedit)
- self.colorbtn = ColorButton(parent)
- self.colorbtn.color = color
- self.colorbtn.colorChanged.connect(self.update_text)
- self.addWidget(self.colorbtn)
-
- def update_color(self):
- color = self.text()
- qcolor = to_qcolor(color)
- self.colorbtn.color = qcolor # defaults to black if not qcolor.isValid()
-
- def update_text(self, color):
- self.lineedit.setText(mcolors.to_hex(color.getRgbF(), keep_alpha=True))
-
- def text(self):
- return self.lineedit.text()
-
-
-def font_is_installed(font):
- """Check if font is installed"""
- return [fam for fam in QtGui.QFontDatabase().families()
- if six.text_type(fam) == font]
-
-
-def tuple_to_qfont(tup):
- """
- Create a QFont from tuple:
- (family [string], size [int], italic [bool], bold [bool])
- """
- if not (isinstance(tup, tuple) and len(tup) == 4
- and font_is_installed(tup[0])
- and isinstance(tup[1], int)
- and isinstance(tup[2], bool)
- and isinstance(tup[3], bool)):
- return None
- font = QtGui.QFont()
- family, size, italic, bold = tup
- font.setFamily(family)
- font.setPointSize(size)
- font.setItalic(italic)
- font.setBold(bold)
- return font
-
-
-def qfont_to_tuple(font):
- return (six.text_type(font.family()), int(font.pointSize()),
- font.italic(), font.bold())
-
-
-class FontLayout(QtWidgets.QGridLayout):
- """Font selection"""
- def __init__(self, value, parent=None):
- QtWidgets.QGridLayout.__init__(self)
- font = tuple_to_qfont(value)
- assert font is not None
-
- # Font family
- self.family = QtWidgets.QFontComboBox(parent)
- self.family.setCurrentFont(font)
- self.addWidget(self.family, 0, 0, 1, -1)
-
- # Font size
- self.size = QtWidgets.QComboBox(parent)
- self.size.setEditable(True)
- sizelist = list(range(6, 12)) + list(range(12, 30, 2)) + [36, 48, 72]
- size = font.pointSize()
- if size not in sizelist:
- sizelist.append(size)
- sizelist.sort()
- self.size.addItems([str(s) for s in sizelist])
- self.size.setCurrentIndex(sizelist.index(size))
- self.addWidget(self.size, 1, 0)
-
- # Italic or not
- self.italic = QtWidgets.QCheckBox(self.tr("Italic"), parent)
- self.italic.setChecked(font.italic())
- self.addWidget(self.italic, 1, 1)
-
- # Bold or not
- self.bold = QtWidgets.QCheckBox(self.tr("Bold"), parent)
- self.bold.setChecked(font.bold())
- self.addWidget(self.bold, 1, 2)
-
- def get_font(self):
- font = self.family.currentFont()
- font.setItalic(self.italic.isChecked())
- font.setBold(self.bold.isChecked())
- font.setPointSize(int(self.size.currentText()))
- return qfont_to_tuple(font)
-
-
-def is_edit_valid(edit):
- text = edit.text()
- state = edit.validator().validate(text, 0)[0]
-
- return state == QtGui.QDoubleValidator.Acceptable
-
-
-class FormWidget(QtWidgets.QWidget):
- update_buttons = QtCore.Signal()
- def __init__(self, data, comment="", parent=None):
- QtWidgets.QWidget.__init__(self, parent)
- self.data = copy.deepcopy(data)
- self.widgets = []
- self.formlayout = QtWidgets.QFormLayout(self)
- if comment:
- self.formlayout.addRow(QtWidgets.QLabel(comment))
- self.formlayout.addRow(QtWidgets.QLabel(" "))
-
- def get_dialog(self):
- """Return FormDialog instance"""
- dialog = self.parent()
- while not isinstance(dialog, QtWidgets.QDialog):
- dialog = dialog.parent()
- return dialog
-
- def setup(self):
- for label, value in self.data:
- if label is None and value is None:
- # Separator: (None, None)
- self.formlayout.addRow(QtWidgets.QLabel(" "), QtWidgets.QLabel(" "))
- self.widgets.append(None)
- continue
- elif label is None:
- # Comment
- self.formlayout.addRow(QtWidgets.QLabel(value))
- self.widgets.append(None)
- continue
- elif tuple_to_qfont(value) is not None:
- field = FontLayout(value, self)
- elif (label.lower() not in BLACKLIST
- and mcolors.is_color_like(value)):
- field = ColorLayout(to_qcolor(value), self)
- elif isinstance(value, six.string_types):
- field = QtWidgets.QLineEdit(value, self)
- elif isinstance(value, (list, tuple)):
- if isinstance(value, tuple):
- value = list(value)
- selindex = value.pop(0)
- field = QtWidgets.QComboBox(self)
- if isinstance(value[0], (list, tuple)):
- keys = [key for key, _val in value]
- value = [val for _key, val in value]
- else:
- keys = value
- field.addItems(value)
- if selindex in value:
- selindex = value.index(selindex)
- elif selindex in keys:
- selindex = keys.index(selindex)
- elif not isinstance(selindex, int):
- warnings.warn(
- "index '%s' is invalid (label: %s, value: %s)" %
- (selindex, label, value))
- selindex = 0
- field.setCurrentIndex(selindex)
- elif isinstance(value, bool):
- field = QtWidgets.QCheckBox(self)
- if value:
- field.setCheckState(QtCore.Qt.Checked)
- else:
- field.setCheckState(QtCore.Qt.Unchecked)
- elif isinstance(value, float):
- field = QtWidgets.QLineEdit(repr(value), self)
- field.setCursorPosition(0)
- field.setValidator(QtGui.QDoubleValidator(field))
- field.validator().setLocale(QtCore.QLocale("C"))
- dialog = self.get_dialog()
- dialog.register_float_field(field)
- field.textChanged.connect(lambda text: dialog.update_buttons())
- elif isinstance(value, int):
- field = QtWidgets.QSpinBox(self)
- field.setRange(-1e9, 1e9)
- field.setValue(value)
- elif isinstance(value, datetime.datetime):
- field = QtWidgets.QDateTimeEdit(self)
- field.setDateTime(value)
- elif isinstance(value, datetime.date):
- field = QtWidgets.QDateEdit(self)
- field.setDate(value)
- else:
- field = QtWidgets.QLineEdit(repr(value), self)
- self.formlayout.addRow(label, field)
- self.widgets.append(field)
-
- def get(self):
- valuelist = []
- for index, (label, value) in enumerate(self.data):
- field = self.widgets[index]
- if label is None:
- # Separator / Comment
- continue
- elif tuple_to_qfont(value) is not None:
- value = field.get_font()
- elif (isinstance(value, six.string_types)
- or mcolors.is_color_like(value)):
- value = six.text_type(field.text())
- elif isinstance(value, (list, tuple)):
- index = int(field.currentIndex())
- if isinstance(value[0], (list, tuple)):
- value = value[index][0]
- else:
- value = value[index]
- elif isinstance(value, bool):
- value = field.checkState() == QtCore.Qt.Checked
- elif isinstance(value, float):
- value = float(str(field.text()))
- elif isinstance(value, int):
- value = int(field.value())
- elif isinstance(value, datetime.datetime):
- value = field.dateTime().toPyDateTime()
- elif isinstance(value, datetime.date):
- value = field.date().toPyDate()
- else:
- value = eval(str(field.text()))
- valuelist.append(value)
- return valuelist
-
-
-class FormComboWidget(QtWidgets.QWidget):
- update_buttons = QtCore.Signal()
-
- def __init__(self, datalist, comment="", parent=None):
- QtWidgets.QWidget.__init__(self, parent)
- layout = QtWidgets.QVBoxLayout()
- self.setLayout(layout)
- self.combobox = QtWidgets.QComboBox()
- layout.addWidget(self.combobox)
-
- self.stackwidget = QtWidgets.QStackedWidget(self)
- layout.addWidget(self.stackwidget)
- self.combobox.currentIndexChanged.connect(self.stackwidget.setCurrentIndex)
-
- self.widgetlist = []
- for data, title, comment in datalist:
- self.combobox.addItem(title)
- widget = FormWidget(data, comment=comment, parent=self)
- self.stackwidget.addWidget(widget)
- self.widgetlist.append(widget)
-
- def setup(self):
- for widget in self.widgetlist:
- widget.setup()
-
- def get(self):
- return [widget.get() for widget in self.widgetlist]
-
-
-class FormTabWidget(QtWidgets.QWidget):
- update_buttons = QtCore.Signal()
-
- def __init__(self, datalist, comment="", parent=None):
- QtWidgets.QWidget.__init__(self, parent)
- layout = QtWidgets.QVBoxLayout()
- self.tabwidget = QtWidgets.QTabWidget()
- layout.addWidget(self.tabwidget)
- self.setLayout(layout)
- self.widgetlist = []
- for data, title, comment in datalist:
- if len(data[0]) == 3:
- widget = FormComboWidget(data, comment=comment, parent=self)
- else:
- widget = FormWidget(data, comment=comment, parent=self)
- index = self.tabwidget.addTab(widget, title)
- self.tabwidget.setTabToolTip(index, comment)
- self.widgetlist.append(widget)
-
- def setup(self):
- for widget in self.widgetlist:
- widget.setup()
-
- def get(self):
- return [widget.get() for widget in self.widgetlist]
-
-
-class FormDialog(QtWidgets.QDialog):
- """Form Dialog"""
- def __init__(self, data, title="", comment="",
- icon=None, parent=None, apply=None):
- QtWidgets.QDialog.__init__(self, parent)
-
- self.apply_callback = apply
-
- # Form
- if isinstance(data[0][0], (list, tuple)):
- self.formwidget = FormTabWidget(data, comment=comment,
- parent=self)
- elif len(data[0]) == 3:
- self.formwidget = FormComboWidget(data, comment=comment,
- parent=self)
- else:
- self.formwidget = FormWidget(data, comment=comment,
- parent=self)
- layout = QtWidgets.QVBoxLayout()
- layout.addWidget(self.formwidget)
-
- self.float_fields = []
- self.formwidget.setup()
-
- # Button box
- self.bbox = bbox = QtWidgets.QDialogButtonBox(
- QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
- self.formwidget.update_buttons.connect(self.update_buttons)
- if self.apply_callback is not None:
- apply_btn = bbox.addButton(QtWidgets.QDialogButtonBox.Apply)
- apply_btn.clicked.connect(self.apply)
-
- bbox.accepted.connect(self.accept)
- bbox.rejected.connect(self.reject)
- layout.addWidget(bbox)
-
- self.setLayout(layout)
-
- self.setWindowTitle(title)
- if not isinstance(icon, QtGui.QIcon):
- icon = QtWidgets.QWidget().style().standardIcon(QtWidgets.QStyle.SP_MessageBoxQuestion)
- self.setWindowIcon(icon)
-
- def register_float_field(self, field):
- self.float_fields.append(field)
-
- def update_buttons(self):
- valid = True
- for field in self.float_fields:
- if not is_edit_valid(field):
- valid = False
- for btn_type in (QtWidgets.QDialogButtonBox.Ok,
- QtWidgets.QDialogButtonBox.Apply):
- btn = self.bbox.button(btn_type)
- if btn is not None:
- btn.setEnabled(valid)
-
- def accept(self):
- self.data = self.formwidget.get()
- QtWidgets.QDialog.accept(self)
-
- def reject(self):
- self.data = None
- QtWidgets.QDialog.reject(self)
-
- def apply(self):
- self.apply_callback(self.formwidget.get())
-
- def get(self):
- """Return form result"""
- return self.data
-
-
-def fedit(data, title="", comment="", icon=None, parent=None, apply=None):
- """
- Create form dialog and return result
- (if Cancel button is pressed, return None)
-
- data: datalist, datagroup
- title: string
- comment: string
- icon: QIcon instance
- parent: parent QWidget
- apply: apply callback (function)
-
- datalist: list/tuple of (field_name, field_value)
- datagroup: list/tuple of (datalist *or* datagroup, title, comment)
-
- -> one field for each member of a datalist
- -> one tab for each member of a top-level datagroup
- -> one page (of a multipage widget, each page can be selected with a combo
- box) for each member of a datagroup inside a datagroup
-
- Supported types for field_value:
- - int, float, str, unicode, bool
- - colors: in Qt-compatible text form, i.e. in hex format or name (red,...)
- (automatically detected from a string)
- - list/tuple:
- * the first element will be the selected index (or value)
- * the other elements can be couples (key, value) or only values
- """
-
- # Create a QApplication instance if no instance currently exists
- # (e.g., if the module is used directly from the interpreter)
- if QtWidgets.QApplication.startingUp():
- _app = QtWidgets.QApplication([])
- dialog = FormDialog(data, title, comment, icon, parent, apply)
- if dialog.exec_():
- return dialog.get()
-
-
-if __name__ == "__main__":
-
- def create_datalist_example():
- return [('str', 'this is a string'),
- ('list', [0, '1', '3', '4']),
- ('list2', ['--', ('none', 'None'), ('--', 'Dashed'),
- ('-.', 'DashDot'), ('-', 'Solid'),
- ('steps', 'Steps'), (':', 'Dotted')]),
- ('float', 1.2),
- (None, 'Other:'),
- ('int', 12),
- ('font', ('Arial', 10, False, True)),
- ('color', '#123409'),
- ('bool', True),
- ('date', datetime.date(2010, 10, 10)),
- ('datetime', datetime.datetime(2010, 10, 10)),
- ]
-
- def create_datagroup_example():
- datalist = create_datalist_example()
- return ((datalist, "Category 1", "Category 1 comment"),
- (datalist, "Category 2", "Category 2 comment"),
- (datalist, "Category 3", "Category 3 comment"))
-
- #--------- datalist example
- datalist = create_datalist_example()
-
- def apply_test(data):
- print("data:", data)
- print("result:", fedit(datalist, title="Example",
- comment="This is just an <b>example</b>.",
- apply=apply_test))
-
- #--------- datagroup example
- datagroup = create_datagroup_example()
- print("result:", fedit(datagroup, "Global title"))
-
- #--------- datagroup inside a datagroup example
- datalist = create_datalist_example()
- datagroup = create_datagroup_example()
- print("result:", fedit(((datagroup, "Title 1", "Tab 1 comment"),
- (datalist, "Title 2", "Tab 2 comment"),
- (datalist, "Title 3", "Tab 3 comment")),
- "Global title"))
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/qt_editor/formsubplottool.py b/contrib/python/matplotlib/py2/matplotlib/backends/qt_editor/formsubplottool.py
deleted file mode 100644
index 4906af588a..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/qt_editor/formsubplottool.py
+++ /dev/null
@@ -1,56 +0,0 @@
-from matplotlib.backends.qt_compat import QtWidgets
-
-
-class UiSubplotTool(QtWidgets.QDialog):
-
- def __init__(self, *args, **kwargs):
- super(UiSubplotTool, self).__init__(*args, **kwargs)
- self.setObjectName("SubplotTool")
- self._widgets = {}
-
- layout = QtWidgets.QHBoxLayout()
- self.setLayout(layout)
-
- left = QtWidgets.QVBoxLayout()
- layout.addLayout(left)
- right = QtWidgets.QVBoxLayout()
- layout.addLayout(right)
-
- box = QtWidgets.QGroupBox("Borders")
- left.addWidget(box)
- inner = QtWidgets.QFormLayout(box)
- for side in ["top", "bottom", "left", "right"]:
- self._widgets[side] = widget = QtWidgets.QDoubleSpinBox()
- widget.setMinimum(0)
- widget.setMaximum(1)
- widget.setDecimals(3)
- widget.setSingleStep(.005)
- widget.setKeyboardTracking(False)
- inner.addRow(side, widget)
- left.addStretch(1)
-
- box = QtWidgets.QGroupBox("Spacings")
- right.addWidget(box)
- inner = QtWidgets.QFormLayout(box)
- for side in ["hspace", "wspace"]:
- self._widgets[side] = widget = QtWidgets.QDoubleSpinBox()
- widget.setMinimum(0)
- widget.setMaximum(1)
- widget.setDecimals(3)
- widget.setSingleStep(.005)
- widget.setKeyboardTracking(False)
- inner.addRow(side, widget)
- right.addStretch(1)
-
- widget = QtWidgets.QPushButton("Export values")
- self._widgets["Export values"] = widget
- # Don't trigger on <enter>, which is used to input values.
- widget.setAutoDefault(False)
- left.addWidget(widget)
-
- for action in ["Tight layout", "Reset", "Close"]:
- self._widgets[action] = widget = QtWidgets.QPushButton(action)
- widget.setAutoDefault(False)
- right.addWidget(widget)
-
- self._widgets["Close"].setFocus()
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/tkagg.py b/contrib/python/matplotlib/py2/matplotlib/backends/tkagg.py
deleted file mode 100644
index 072fcb48fe..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/tkagg.py
+++ /dev/null
@@ -1,44 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import tkinter as Tk
-
-import numpy as np
-
-from matplotlib.backends import _tkagg
-
-def blit(photoimage, aggimage, bbox=None, colormode=1):
- tk = photoimage.tk
-
- if bbox is not None:
- bbox_array = bbox.__array__()
- # x1, x2, y1, y2
- bboxptr = (bbox_array[0, 0], bbox_array[1, 0],
- bbox_array[0, 1], bbox_array[1, 1])
- else:
- bboxptr = 0
- data = np.asarray(aggimage)
- dataptr = (data.shape[0], data.shape[1], data.ctypes.data)
- try:
- tk.call(
- "PyAggImagePhoto", photoimage,
- dataptr, colormode, bboxptr)
- except Tk.TclError:
- if hasattr(tk, 'interpaddr'):
- _tkagg.tkinit(tk.interpaddr(), 1)
- else:
- # very old python?
- _tkagg.tkinit(tk, 0)
- tk.call("PyAggImagePhoto", photoimage,
- dataptr, colormode, bboxptr)
-
-def test(aggimage):
- r = Tk.Tk()
- c = Tk.Canvas(r, width=aggimage.width, height=aggimage.height)
- c.pack()
- p = Tk.PhotoImage(width=aggimage.width, height=aggimage.height)
- blit(p, aggimage)
- c.create_image(aggimage.width,aggimage.height,image=p)
- blit(p, aggimage)
- while True: r.update_idletasks()
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/all_figures.html b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/all_figures.html
deleted file mode 100644
index 41f48dc6d2..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/all_figures.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<html>
- <head>
- <link rel="stylesheet" href="{{ prefix }}/_static/css/page.css" type="text/css">
- <link rel="stylesheet" href="{{ prefix }}/_static/css/boilerplate.css" type="text/css" />
- <link rel="stylesheet" href="{{ prefix }}/_static/css/fbm.css" type="text/css" />
- <link rel="stylesheet" href="{{ prefix }}/_static/jquery-ui-1.12.1/jquery-ui.min.css" >
- <script src="{{ prefix }}/_static/jquery-ui-1.12.1/external/jquery/jquery.js"></script>
- <script src="{{ prefix }}/_static/jquery-ui-1.12.1/jquery-ui.min.js"></script>
- <script src="{{ prefix }}/_static/js/mpl_tornado.js"></script>
- <script src="{{ prefix }}/js/mpl.js"></script>
-
- <script>
- {% for (fig_id, fig_manager) in figures %}
- $(document).ready(
- function() {
- var main_div = $('div#figures');
- var figure_div = $('<div id="figure-div"/>')
- main_div.append(figure_div);
- var websocket_type = mpl.get_websocket_type();
- var websocket = new websocket_type(
- "{{ ws_uri }}" + "{{ fig_id }}" + "/ws");
- var fig = new mpl.figure(
- "{{ fig_id }}", websocket, mpl_ondownload, figure_div);
-
- fig.focus_on_mouseover = true;
-
- $(fig.canvas).attr('tabindex', {{ fig_id }});
- }
- );
-
- {% end %}
- </script>
-
- <title>MPL | WebAgg current figures</title>
-
- </head>
- <body>
- <div id="mpl-warnings" class="mpl-warnings"></div>
-
- <div id="figures" style="margin: 10px 10px;"></div>
-
- </body>
-</html>
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/boilerplate.css b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/boilerplate.css
deleted file mode 100644
index 2b1535f449..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/boilerplate.css
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * HTML5 ✰ Boilerplate
- *
- * style.css contains a reset, font normalization and some base styles.
- *
- * Credit is left where credit is due.
- * Much inspiration was taken from these projects:
- * - yui.yahooapis.com/2.8.1/build/base/base.css
- * - camendesign.com/design/
- * - praegnanz.de/weblog/htmlcssjs-kickstart
- */
-
-
-/**
- * html5doctor.com Reset Stylesheet (Eric Meyer's Reset Reloaded + HTML5 baseline)
- * v1.6.1 2010-09-17 | Authors: Eric Meyer & Richard Clark
- * html5doctor.com/html-5-reset-stylesheet/
- */
-
-html, body, div, span, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
-small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td,
-article, aside, canvas, details, figcaption, figure,
-footer, header, hgroup, menu, nav, section, summary,
-time, mark, audio, video {
- margin: 0;
- padding: 0;
- border: 0;
- font-size: 100%;
- font: inherit;
- vertical-align: baseline;
-}
-
-sup { vertical-align: super; }
-sub { vertical-align: sub; }
-
-article, aside, details, figcaption, figure,
-footer, header, hgroup, menu, nav, section {
- display: block;
-}
-
-blockquote, q { quotes: none; }
-
-blockquote:before, blockquote:after,
-q:before, q:after { content: ""; content: none; }
-
-ins { background-color: #ff9; color: #000; text-decoration: none; }
-
-mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
-
-del { text-decoration: line-through; }
-
-abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
-
-table { border-collapse: collapse; border-spacing: 0; }
-
-hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
-
-input, select { vertical-align: middle; }
-
-
-/**
- * Font normalization inspired by YUI Library's fonts.css: developer.yahoo.com/yui/
- */
-
-body { font:13px/1.231 sans-serif; *font-size:small; } /* Hack retained to preserve specificity */
-select, input, textarea, button { font:99% sans-serif; }
-
-/* Normalize monospace sizing:
- en.wikipedia.org/wiki/MediaWiki_talk:Common.css/Archive_11#Teletype_style_fix_for_Chrome */
-pre, code, kbd, samp { font-family: monospace, sans-serif; }
-
-em,i { font-style: italic; }
-b,strong { font-weight: bold; }
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/fbm.css b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/fbm.css
deleted file mode 100644
index 0e21d19ae8..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/fbm.css
+++ /dev/null
@@ -1,97 +0,0 @@
-
-/* Flexible box model classes */
-/* Taken from Alex Russell http://infrequently.org/2009/08/css-3-progress/ */
-
-.hbox {
- display: -webkit-box;
- -webkit-box-orient: horizontal;
- -webkit-box-align: stretch;
-
- display: -moz-box;
- -moz-box-orient: horizontal;
- -moz-box-align: stretch;
-
- display: box;
- box-orient: horizontal;
- box-align: stretch;
-}
-
-.hbox > * {
- -webkit-box-flex: 0;
- -moz-box-flex: 0;
- box-flex: 0;
-}
-
-.vbox {
- display: -webkit-box;
- -webkit-box-orient: vertical;
- -webkit-box-align: stretch;
-
- display: -moz-box;
- -moz-box-orient: vertical;
- -moz-box-align: stretch;
-
- display: box;
- box-orient: vertical;
- box-align: stretch;
-}
-
-.vbox > * {
- -webkit-box-flex: 0;
- -moz-box-flex: 0;
- box-flex: 0;
-}
-
-.reverse {
- -webkit-box-direction: reverse;
- -moz-box-direction: reverse;
- box-direction: reverse;
-}
-
-.box-flex0 {
- -webkit-box-flex: 0;
- -moz-box-flex: 0;
- box-flex: 0;
-}
-
-.box-flex1, .box-flex {
- -webkit-box-flex: 1;
- -moz-box-flex: 1;
- box-flex: 1;
-}
-
-.box-flex2 {
- -webkit-box-flex: 2;
- -moz-box-flex: 2;
- box-flex: 2;
-}
-
-.box-group1 {
- -webkit-box-flex-group: 1;
- -moz-box-flex-group: 1;
- box-flex-group: 1;
-}
-
-.box-group2 {
- -webkit-box-flex-group: 2;
- -moz-box-flex-group: 2;
- box-flex-group: 2;
-}
-
-.start {
- -webkit-box-pack: start;
- -moz-box-pack: start;
- box-pack: start;
-}
-
-.end {
- -webkit-box-pack: end;
- -moz-box-pack: end;
- box-pack: end;
-}
-
-.center {
- -webkit-box-pack: center;
- -moz-box-pack: center;
- box-pack: center;
-}
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/page.css b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/page.css
deleted file mode 100644
index d284be1f59..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/page.css
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Primary styles
- *
- * Author: IPython Development Team
- */
-
-
-body {
- background-color: white;
- /* This makes sure that the body covers the entire window and needs to
- be in a different element than the display: box in wrapper below */
- position: absolute;
- left: 0px;
- right: 0px;
- top: 0px;
- bottom: 0px;
- overflow: visible;
-}
-
-
-div#header {
- /* Initially hidden to prevent FLOUC */
- display: none;
- position: relative;
- height: 40px;
- padding: 5px;
- margin: 0px;
- width: 100%;
-}
-
-span#ipython_notebook {
- position: absolute;
- padding: 2px 2px 2px 5px;
-}
-
-span#ipython_notebook img {
- font-family: Verdana, "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
- height: 24px;
- text-decoration:none;
- display: inline;
- color: black;
-}
-
-#site {
- width: 100%;
- display: none;
-}
-
-/* We set the fonts by hand here to override the values in the theme */
-.ui-widget {
- font-family: "Lucinda Grande", "Lucinda Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
-}
-
-.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button {
- font-family: "Lucinda Grande", "Lucinda Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
-}
-
-/* Smaller buttons */
-.ui-button .ui-button-text {
- padding: 0.2em 0.8em;
- font-size: 77%;
-}
-
-input.ui-button {
- padding: 0.3em 0.9em;
-}
-
-span#login_widget {
- float: right;
-}
-
-.border-box-sizing {
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
-}
-
-#figure-div {
- display: inline-block;
- margin: 10px;
-}
-
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/ipython_inline_figure.html b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/ipython_inline_figure.html
deleted file mode 100644
index eed5af0f43..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/ipython_inline_figure.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<!-- Within the kernel, we don't know the address of the matplotlib
- websocket server, so we have to get in client-side and fetch our
- resources that way. -->
-<script>
- // We can't proceed until these Javascript files are fetched, so
- // we fetch them synchronously
- $.ajaxSetup({async: false});
- $.getScript("http://" + window.location.hostname + ":{{ port }}{{prefix}}/_static/js/mpl_tornado.js");
- $.getScript("http://" + window.location.hostname + ":{{ port }}{{prefix}}/js/mpl.js");
- $.ajaxSetup({async: true});
-
- function init_figure{{ fig_id }}(e) {
- $('div.output').off('resize');
-
- var output_div = $(e.target).find('div.output_subarea');
- var websocket_type = mpl.get_websocket_type();
- var websocket = new websocket_type(
- "ws://" + window.location.hostname + ":{{ port }}{{ prefix}}/" +
- {{ repr(str(fig_id)) }} + "/ws");
-
- var fig = new mpl.figure(
- {{repr(str(fig_id))}}, websocket, mpl_ondownload, output_div);
-
- // Fetch the first image
- fig.context.drawImage(fig.imageObj, 0, 0);
-
- fig.focus_on_mouseover = true;
- }
-
- // We can't initialize the figure contents until our content
- // has been added to the DOM. This is a bit of hack to get an
- // event for that.
- $('div.output').resize(init_figure{{ fig_id }});
-</script>
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/jquery/js/jquery-1.11.3.js b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/jquery/js/jquery-1.11.3.js
deleted file mode 100644
index 6feb11086f..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/jquery/js/jquery-1.11.3.js
+++ /dev/null
@@ -1,10351 +0,0 @@
-/*!
- * jQuery JavaScript Library v1.11.3
- * http://jquery.com/
- *
- * Includes Sizzle.js
- * http://sizzlejs.com/
- *
- * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2015-04-28T16:19Z
- */
-
-(function( global, factory ) {
-
- if ( typeof module === "object" && typeof module.exports === "object" ) {
- // For CommonJS and CommonJS-like environments where a proper window is present,
- // execute the factory and get jQuery
- // For environments that do not inherently posses a window with a document
- // (such as Node.js), expose a jQuery-making factory as module.exports
- // This accentuates the need for the creation of a real window
- // e.g. var jQuery = require("jquery")(window);
- // See ticket #14549 for more info
- module.exports = global.document ?
- factory( global, true ) :
- function( w ) {
- if ( !w.document ) {
- throw new Error( "jQuery requires a window with a document" );
- }
- return factory( w );
- };
- } else {
- factory( global );
- }
-
-// Pass this if window is not defined yet
-}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
-
-// Can't do this because several apps including ASP.NET trace
-// the stack via arguments.caller.callee and Firefox dies if
-// you try to trace through "use strict" call chains. (#13335)
-// Support: Firefox 18+
-//
-
-var deletedIds = [];
-
-var slice = deletedIds.slice;
-
-var concat = deletedIds.concat;
-
-var push = deletedIds.push;
-
-var indexOf = deletedIds.indexOf;
-
-var class2type = {};
-
-var toString = class2type.toString;
-
-var hasOwn = class2type.hasOwnProperty;
-
-var support = {};
-
-
-
-var
- version = "1.11.3",
-
- // Define a local copy of jQuery
- jQuery = function( selector, context ) {
- // The jQuery object is actually just the init constructor 'enhanced'
- // Need init if jQuery is called (just allow error to be thrown if not included)
- return new jQuery.fn.init( selector, context );
- },
-
- // Support: Android<4.1, IE<9
- // Make sure we trim BOM and NBSP
- rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
-
- // Matches dashed string for camelizing
- rmsPrefix = /^-ms-/,
- rdashAlpha = /-([\da-z])/gi,
-
- // Used by jQuery.camelCase as callback to replace()
- fcamelCase = function( all, letter ) {
- return letter.toUpperCase();
- };
-
-jQuery.fn = jQuery.prototype = {
- // The current version of jQuery being used
- jquery: version,
-
- constructor: jQuery,
-
- // Start with an empty selector
- selector: "",
-
- // The default length of a jQuery object is 0
- length: 0,
-
- toArray: function() {
- return slice.call( this );
- },
-
- // Get the Nth element in the matched element set OR
- // Get the whole matched element set as a clean array
- get: function( num ) {
- return num != null ?
-
- // Return just the one element from the set
- ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
-
- // Return all the elements in a clean array
- slice.call( this );
- },
-
- // Take an array of elements and push it onto the stack
- // (returning the new matched element set)
- pushStack: function( elems ) {
-
- // Build a new jQuery matched element set
- var ret = jQuery.merge( this.constructor(), elems );
-
- // Add the old object onto the stack (as a reference)
- ret.prevObject = this;
- ret.context = this.context;
-
- // Return the newly-formed element set
- return ret;
- },
-
- // Execute a callback for every element in the matched set.
- // (You can seed the arguments with an array of args, but this is
- // only used internally.)
- each: function( callback, args ) {
- return jQuery.each( this, callback, args );
- },
-
- map: function( callback ) {
- return this.pushStack( jQuery.map(this, function( elem, i ) {
- return callback.call( elem, i, elem );
- }));
- },
-
- slice: function() {
- return this.pushStack( slice.apply( this, arguments ) );
- },
-
- first: function() {
- return this.eq( 0 );
- },
-
- last: function() {
- return this.eq( -1 );
- },
-
- eq: function( i ) {
- var len = this.length,
- j = +i + ( i < 0 ? len : 0 );
- return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
- },
-
- end: function() {
- return this.prevObject || this.constructor(null);
- },
-
- // For internal use only.
- // Behaves like an Array's method, not like a jQuery method.
- push: push,
- sort: deletedIds.sort,
- splice: deletedIds.splice
-};
-
-jQuery.extend = jQuery.fn.extend = function() {
- var src, copyIsArray, copy, name, options, clone,
- target = arguments[0] || {},
- i = 1,
- length = arguments.length,
- deep = false;
-
- // Handle a deep copy situation
- if ( typeof target === "boolean" ) {
- deep = target;
-
- // skip the boolean and the target
- target = arguments[ i ] || {};
- i++;
- }
-
- // Handle case when target is a string or something (possible in deep copy)
- if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
- target = {};
- }
-
- // extend jQuery itself if only one argument is passed
- if ( i === length ) {
- target = this;
- i--;
- }
-
- for ( ; i < length; i++ ) {
- // Only deal with non-null/undefined values
- if ( (options = arguments[ i ]) != null ) {
- // Extend the base object
- for ( name in options ) {
- src = target[ name ];
- copy = options[ name ];
-
- // Prevent never-ending loop
- if ( target === copy ) {
- continue;
- }
-
- // Recurse if we're merging plain objects or arrays
- if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
- if ( copyIsArray ) {
- copyIsArray = false;
- clone = src && jQuery.isArray(src) ? src : [];
-
- } else {
- clone = src && jQuery.isPlainObject(src) ? src : {};
- }
-
- // Never move original objects, clone them
- target[ name ] = jQuery.extend( deep, clone, copy );
-
- // Don't bring in undefined values
- } else if ( copy !== undefined ) {
- target[ name ] = copy;
- }
- }
- }
- }
-
- // Return the modified object
- return target;
-};
-
-jQuery.extend({
- // Unique for each copy of jQuery on the page
- expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
-
- // Assume jQuery is ready without the ready module
- isReady: true,
-
- error: function( msg ) {
- throw new Error( msg );
- },
-
- noop: function() {},
-
- // See test/unit/core.js for details concerning isFunction.
- // Since version 1.3, DOM methods and functions like alert
- // aren't supported. They return false on IE (#2968).
- isFunction: function( obj ) {
- return jQuery.type(obj) === "function";
- },
-
- isArray: Array.isArray || function( obj ) {
- return jQuery.type(obj) === "array";
- },
-
- isWindow: function( obj ) {
- /* jshint eqeqeq: false */
- return obj != null && obj == obj.window;
- },
-
- isNumeric: function( obj ) {
- // parseFloat NaNs numeric-cast false positives (null|true|false|"")
- // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
- // subtraction forces infinities to NaN
- // adding 1 corrects loss of precision from parseFloat (#15100)
- return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;
- },
-
- isEmptyObject: function( obj ) {
- var name;
- for ( name in obj ) {
- return false;
- }
- return true;
- },
-
- isPlainObject: function( obj ) {
- var key;
-
- // Must be an Object.
- // Because of IE, we also have to check the presence of the constructor property.
- // Make sure that DOM nodes and window objects don't pass through, as well
- if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
- return false;
- }
-
- try {
- // Not own constructor property must be Object
- if ( obj.constructor &&
- !hasOwn.call(obj, "constructor") &&
- !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
- return false;
- }
- } catch ( e ) {
- // IE8,9 Will throw exceptions on certain host objects #9897
- return false;
- }
-
- // Support: IE<9
- // Handle iteration over inherited properties before own properties.
- if ( support.ownLast ) {
- for ( key in obj ) {
- return hasOwn.call( obj, key );
- }
- }
-
- // Own properties are enumerated firstly, so to speed up,
- // if last one is own, then all properties are own.
- for ( key in obj ) {}
-
- return key === undefined || hasOwn.call( obj, key );
- },
-
- type: function( obj ) {
- if ( obj == null ) {
- return obj + "";
- }
- return typeof obj === "object" || typeof obj === "function" ?
- class2type[ toString.call(obj) ] || "object" :
- typeof obj;
- },
-
- // Evaluates a script in a global context
- // Workarounds based on findings by Jim Driscoll
- // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
- globalEval: function( data ) {
- if ( data && jQuery.trim( data ) ) {
- // We use execScript on Internet Explorer
- // We use an anonymous function so that context is window
- // rather than jQuery in Firefox
- ( window.execScript || function( data ) {
- window[ "eval" ].call( window, data );
- } )( data );
- }
- },
-
- // Convert dashed to camelCase; used by the css and data modules
- // Microsoft forgot to hump their vendor prefix (#9572)
- camelCase: function( string ) {
- return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
- },
-
- nodeName: function( elem, name ) {
- return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
- },
-
- // args is for internal usage only
- each: function( obj, callback, args ) {
- var value,
- i = 0,
- length = obj.length,
- isArray = isArraylike( obj );
-
- if ( args ) {
- if ( isArray ) {
- for ( ; i < length; i++ ) {
- value = callback.apply( obj[ i ], args );
-
- if ( value === false ) {
- break;
- }
- }
- } else {
- for ( i in obj ) {
- value = callback.apply( obj[ i ], args );
-
- if ( value === false ) {
- break;
- }
- }
- }
-
- // A special, fast, case for the most common use of each
- } else {
- if ( isArray ) {
- for ( ; i < length; i++ ) {
- value = callback.call( obj[ i ], i, obj[ i ] );
-
- if ( value === false ) {
- break;
- }
- }
- } else {
- for ( i in obj ) {
- value = callback.call( obj[ i ], i, obj[ i ] );
-
- if ( value === false ) {
- break;
- }
- }
- }
- }
-
- return obj;
- },
-
- // Support: Android<4.1, IE<9
- trim: function( text ) {
- return text == null ?
- "" :
- ( text + "" ).replace( rtrim, "" );
- },
-
- // results is for internal usage only
- makeArray: function( arr, results ) {
- var ret = results || [];
-
- if ( arr != null ) {
- if ( isArraylike( Object(arr) ) ) {
- jQuery.merge( ret,
- typeof arr === "string" ?
- [ arr ] : arr
- );
- } else {
- push.call( ret, arr );
- }
- }
-
- return ret;
- },
-
- inArray: function( elem, arr, i ) {
- var len;
-
- if ( arr ) {
- if ( indexOf ) {
- return indexOf.call( arr, elem, i );
- }
-
- len = arr.length;
- i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;
-
- for ( ; i < len; i++ ) {
- // Skip accessing in sparse arrays
- if ( i in arr && arr[ i ] === elem ) {
- return i;
- }
- }
- }
-
- return -1;
- },
-
- merge: function( first, second ) {
- var len = +second.length,
- j = 0,
- i = first.length;
-
- while ( j < len ) {
- first[ i++ ] = second[ j++ ];
- }
-
- // Support: IE<9
- // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
- if ( len !== len ) {
- while ( second[j] !== undefined ) {
- first[ i++ ] = second[ j++ ];
- }
- }
-
- first.length = i;
-
- return first;
- },
-
- grep: function( elems, callback, invert ) {
- var callbackInverse,
- matches = [],
- i = 0,
- length = elems.length,
- callbackExpect = !invert;
-
- // Go through the array, only saving the items
- // that pass the validator function
- for ( ; i < length; i++ ) {
- callbackInverse = !callback( elems[ i ], i );
- if ( callbackInverse !== callbackExpect ) {
- matches.push( elems[ i ] );
- }
- }
-
- return matches;
- },
-
- // arg is for internal usage only
- map: function( elems, callback, arg ) {
- var value,
- i = 0,
- length = elems.length,
- isArray = isArraylike( elems ),
- ret = [];
-
- // Go through the array, translating each of the items to their new values
- if ( isArray ) {
- for ( ; i < length; i++ ) {
- value = callback( elems[ i ], i, arg );
-
- if ( value != null ) {
- ret.push( value );
- }
- }
-
- // Go through every key on the object,
- } else {
- for ( i in elems ) {
- value = callback( elems[ i ], i, arg );
-
- if ( value != null ) {
- ret.push( value );
- }
- }
- }
-
- // Flatten any nested arrays
- return concat.apply( [], ret );
- },
-
- // A global GUID counter for objects
- guid: 1,
-
- // Bind a function to a context, optionally partially applying any
- // arguments.
- proxy: function( fn, context ) {
- var args, proxy, tmp;
-
- if ( typeof context === "string" ) {
- tmp = fn[ context ];
- context = fn;
- fn = tmp;
- }
-
- // Quick check to determine if target is callable, in the spec
- // this throws a TypeError, but we will just return undefined.
- if ( !jQuery.isFunction( fn ) ) {
- return undefined;
- }
-
- // Simulated bind
- args = slice.call( arguments, 2 );
- proxy = function() {
- return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
- };
-
- // Set the guid of unique handler to the same of original handler, so it can be removed
- proxy.guid = fn.guid = fn.guid || jQuery.guid++;
-
- return proxy;
- },
-
- now: function() {
- return +( new Date() );
- },
-
- // jQuery.support is not used in Core but other projects attach their
- // properties to it so it needs to exist.
- support: support
-});
-
-// Populate the class2type map
-jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
- class2type[ "[object " + name + "]" ] = name.toLowerCase();
-});
-
-function isArraylike( obj ) {
-
- // Support: iOS 8.2 (not reproducible in simulator)
- // `in` check used to prevent JIT error (gh-2145)
- // hasOwn isn't used here due to false negatives
- // regarding Nodelist length in IE
- var length = "length" in obj && obj.length,
- type = jQuery.type( obj );
-
- if ( type === "function" || jQuery.isWindow( obj ) ) {
- return false;
- }
-
- if ( obj.nodeType === 1 && length ) {
- return true;
- }
-
- return type === "array" || length === 0 ||
- typeof length === "number" && length > 0 && ( length - 1 ) in obj;
-}
-var Sizzle =
-/*!
- * Sizzle CSS Selector Engine v2.2.0-pre
- * http://sizzlejs.com/
- *
- * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors
- * Released under the MIT license
- * http://jquery.org/license
- *
- * Date: 2014-12-16
- */
-(function( window ) {
-
-var i,
- support,
- Expr,
- getText,
- isXML,
- tokenize,
- compile,
- select,
- outermostContext,
- sortInput,
- hasDuplicate,
-
- // Local document vars
- setDocument,
- document,
- docElem,
- documentIsHTML,
- rbuggyQSA,
- rbuggyMatches,
- matches,
- contains,
-
- // Instance-specific data
- expando = "sizzle" + 1 * new Date(),
- preferredDoc = window.document,
- dirruns = 0,
- done = 0,
- classCache = createCache(),
- tokenCache = createCache(),
- compilerCache = createCache(),
- sortOrder = function( a, b ) {
- if ( a === b ) {
- hasDuplicate = true;
- }
- return 0;
- },
-
- // General-purpose constants
- MAX_NEGATIVE = 1 << 31,
-
- // Instance methods
- hasOwn = ({}).hasOwnProperty,
- arr = [],
- pop = arr.pop,
- push_native = arr.push,
- push = arr.push,
- slice = arr.slice,
- // Use a stripped-down indexOf as it's faster than native
- // http://jsperf.com/thor-indexof-vs-for/5
- indexOf = function( list, elem ) {
- var i = 0,
- len = list.length;
- for ( ; i < len; i++ ) {
- if ( list[i] === elem ) {
- return i;
- }
- }
- return -1;
- },
-
- booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
-
- // Regular expressions
-
- // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
- whitespace = "[\\x20\\t\\r\\n\\f]",
- // http://www.w3.org/TR/css3-syntax/#characters
- characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
-
- // Loosely modeled on CSS identifier characters
- // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
- // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
- identifier = characterEncoding.replace( "w", "w#" ),
-
- // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
- attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace +
- // Operator (capture 2)
- "*([*^$|!~]?=)" + whitespace +
- // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
- "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
- "*\\]",
-
- pseudos = ":(" + characterEncoding + ")(?:\\((" +
- // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
- // 1. quoted (capture 3; capture 4 or capture 5)
- "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
- // 2. simple (capture 6)
- "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
- // 3. anything else (capture 2)
- ".*" +
- ")\\)|)",
-
- // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
- rwhitespace = new RegExp( whitespace + "+", "g" ),
- rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
-
- rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
- rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
-
- rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
-
- rpseudo = new RegExp( pseudos ),
- ridentifier = new RegExp( "^" + identifier + "$" ),
-
- matchExpr = {
- "ID": new RegExp( "^#(" + characterEncoding + ")" ),
- "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
- "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
- "ATTR": new RegExp( "^" + attributes ),
- "PSEUDO": new RegExp( "^" + pseudos ),
- "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
- "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
- "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
- "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
- // For use in libraries implementing .is()
- // We use this for POS matching in `select`
- "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
- whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
- },
-
- rinputs = /^(?:input|select|textarea|button)$/i,
- rheader = /^h\d$/i,
-
- rnative = /^[^{]+\{\s*\[native \w/,
-
- // Easily-parseable/retrievable ID or TAG or CLASS selectors
- rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
-
- rsibling = /[+~]/,
- rescape = /'|\\/g,
-
- // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
- runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
- funescape = function( _, escaped, escapedWhitespace ) {
- var high = "0x" + escaped - 0x10000;
- // NaN means non-codepoint
- // Support: Firefox<24
- // Workaround erroneous numeric interpretation of +"0x"
- return high !== high || escapedWhitespace ?
- escaped :
- high < 0 ?
- // BMP codepoint
- String.fromCharCode( high + 0x10000 ) :
- // Supplemental Plane codepoint (surrogate pair)
- String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
- },
-
- // Used for iframes
- // See setDocument()
- // Removing the function wrapper causes a "Permission Denied"
- // error in IE
- unloadHandler = function() {
- setDocument();
- };
-
-// Optimize for push.apply( _, NodeList )
-try {
- push.apply(
- (arr = slice.call( preferredDoc.childNodes )),
- preferredDoc.childNodes
- );
- // Support: Android<4.0
- // Detect silently failing push.apply
- arr[ preferredDoc.childNodes.length ].nodeType;
-} catch ( e ) {
- push = { apply: arr.length ?
-
- // Leverage slice if possible
- function( target, els ) {
- push_native.apply( target, slice.call(els) );
- } :
-
- // Support: IE<9
- // Otherwise append directly
- function( target, els ) {
- var j = target.length,
- i = 0;
- // Can't trust NodeList.length
- while ( (target[j++] = els[i++]) ) {}
- target.length = j - 1;
- }
- };
-}
-
-function Sizzle( selector, context, results, seed ) {
- var match, elem, m, nodeType,
- // QSA vars
- i, groups, old, nid, newContext, newSelector;
-
- if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
- setDocument( context );
- }
-
- context = context || document;
- results = results || [];
- nodeType = context.nodeType;
-
- if ( typeof selector !== "string" || !selector ||
- nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
-
- return results;
- }
-
- if ( !seed && documentIsHTML ) {
-
- // Try to shortcut find operations when possible (e.g., not under DocumentFragment)
- if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
- // Speed-up: Sizzle("#ID")
- if ( (m = match[1]) ) {
- if ( nodeType === 9 ) {
- elem = context.getElementById( m );
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document (jQuery #6963)
- if ( elem && elem.parentNode ) {
- // Handle the case where IE, Opera, and Webkit return items
- // by name instead of ID
- if ( elem.id === m ) {
- results.push( elem );
- return results;
- }
- } else {
- return results;
- }
- } else {
- // Context is not a document
- if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
- contains( context, elem ) && elem.id === m ) {
- results.push( elem );
- return results;
- }
- }
-
- // Speed-up: Sizzle("TAG")
- } else if ( match[2] ) {
- push.apply( results, context.getElementsByTagName( selector ) );
- return results;
-
- // Speed-up: Sizzle(".CLASS")
- } else if ( (m = match[3]) && support.getElementsByClassName ) {
- push.apply( results, context.getElementsByClassName( m ) );
- return results;
- }
- }
-
- // QSA path
- if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
- nid = old = expando;
- newContext = context;
- newSelector = nodeType !== 1 && selector;
-
- // qSA works strangely on Element-rooted queries
- // We can work around this by specifying an extra ID on the root
- // and working up from there (Thanks to Andrew Dupont for the technique)
- // IE 8 doesn't work on object elements
- if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
- groups = tokenize( selector );
-
- if ( (old = context.getAttribute("id")) ) {
- nid = old.replace( rescape, "\\$&" );
- } else {
- context.setAttribute( "id", nid );
- }
- nid = "[id='" + nid + "'] ";
-
- i = groups.length;
- while ( i-- ) {
- groups[i] = nid + toSelector( groups[i] );
- }
- newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
- newSelector = groups.join(",");
- }
-
- if ( newSelector ) {
- try {
- push.apply( results,
- newContext.querySelectorAll( newSelector )
- );
- return results;
- } catch(qsaError) {
- } finally {
- if ( !old ) {
- context.removeAttribute("id");
- }
- }
- }
- }
- }
-
- // All others
- return select( selector.replace( rtrim, "$1" ), context, results, seed );
-}
-
-/**
- * Create key-value caches of limited size
- * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
- * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
- * deleting the oldest entry
- */
-function createCache() {
- var keys = [];
-
- function cache( key, value ) {
- // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
- if ( keys.push( key + " " ) > Expr.cacheLength ) {
- // Only keep the most recent entries
- delete cache[ keys.shift() ];
- }
- return (cache[ key + " " ] = value);
- }
- return cache;
-}
-
-/**
- * Mark a function for special use by Sizzle
- * @param {Function} fn The function to mark
- */
-function markFunction( fn ) {
- fn[ expando ] = true;
- return fn;
-}
-
-/**
- * Support testing using an element
- * @param {Function} fn Passed the created div and expects a boolean result
- */
-function assert( fn ) {
- var div = document.createElement("div");
-
- try {
- return !!fn( div );
- } catch (e) {
- return false;
- } finally {
- // Remove from its parent by default
- if ( div.parentNode ) {
- div.parentNode.removeChild( div );
- }
- // release memory in IE
- div = null;
- }
-}
-
-/**
- * Adds the same handler for all of the specified attrs
- * @param {String} attrs Pipe-separated list of attributes
- * @param {Function} handler The method that will be applied
- */
-function addHandle( attrs, handler ) {
- var arr = attrs.split("|"),
- i = attrs.length;
-
- while ( i-- ) {
- Expr.attrHandle[ arr[i] ] = handler;
- }
-}
-
-/**
- * Checks document order of two siblings
- * @param {Element} a
- * @param {Element} b
- * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
- */
-function siblingCheck( a, b ) {
- var cur = b && a,
- diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
- ( ~b.sourceIndex || MAX_NEGATIVE ) -
- ( ~a.sourceIndex || MAX_NEGATIVE );
-
- // Use IE sourceIndex if available on both nodes
- if ( diff ) {
- return diff;
- }
-
- // Check if b follows a
- if ( cur ) {
- while ( (cur = cur.nextSibling) ) {
- if ( cur === b ) {
- return -1;
- }
- }
- }
-
- return a ? 1 : -1;
-}
-
-/**
- * Returns a function to use in pseudos for input types
- * @param {String} type
- */
-function createInputPseudo( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === type;
- };
-}
-
-/**
- * Returns a function to use in pseudos for buttons
- * @param {String} type
- */
-function createButtonPseudo( type ) {
- return function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return (name === "input" || name === "button") && elem.type === type;
- };
-}
-
-/**
- * Returns a function to use in pseudos for positionals
- * @param {Function} fn
- */
-function createPositionalPseudo( fn ) {
- return markFunction(function( argument ) {
- argument = +argument;
- return markFunction(function( seed, matches ) {
- var j,
- matchIndexes = fn( [], seed.length, argument ),
- i = matchIndexes.length;
-
- // Match elements found at the specified indexes
- while ( i-- ) {
- if ( seed[ (j = matchIndexes[i]) ] ) {
- seed[j] = !(matches[j] = seed[j]);
- }
- }
- });
- });
-}
-
-/**
- * Checks a node for validity as a Sizzle context
- * @param {Element|Object=} context
- * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
- */
-function testContext( context ) {
- return context && typeof context.getElementsByTagName !== "undefined" && context;
-}
-
-// Expose support vars for convenience
-support = Sizzle.support = {};
-
-/**
- * Detects XML nodes
- * @param {Element|Object} elem An element or a document
- * @returns {Boolean} True iff elem is a non-HTML XML node
- */
-isXML = Sizzle.isXML = function( elem ) {
- // documentElement is verified for cases where it doesn't yet exist
- // (such as loading iframes in IE - #4833)
- var documentElement = elem && (elem.ownerDocument || elem).documentElement;
- return documentElement ? documentElement.nodeName !== "HTML" : false;
-};
-
-/**
- * Sets document-related variables once based on the current document
- * @param {Element|Object} [doc] An element or document object to use to set the document
- * @returns {Object} Returns the current document
- */
-setDocument = Sizzle.setDocument = function( node ) {
- var hasCompare, parent,
- doc = node ? node.ownerDocument || node : preferredDoc;
-
- // If no document and documentElement is available, return
- if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
- return document;
- }
-
- // Set our document
- document = doc;
- docElem = doc.documentElement;
- parent = doc.defaultView;
-
- // Support: IE>8
- // If iframe document is assigned to "document" variable and if iframe has been reloaded,
- // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
- // IE6-8 do not support the defaultView property so parent will be undefined
- if ( parent && parent !== parent.top ) {
- // IE11 does not have attachEvent, so all must suffer
- if ( parent.addEventListener ) {
- parent.addEventListener( "unload", unloadHandler, false );
- } else if ( parent.attachEvent ) {
- parent.attachEvent( "onunload", unloadHandler );
- }
- }
-
- /* Support tests
- ---------------------------------------------------------------------- */
- documentIsHTML = !isXML( doc );
-
- /* Attributes
- ---------------------------------------------------------------------- */
-
- // Support: IE<8
- // Verify that getAttribute really returns attributes and not properties
- // (excepting IE8 booleans)
- support.attributes = assert(function( div ) {
- div.className = "i";
- return !div.getAttribute("className");
- });
-
- /* getElement(s)By*
- ---------------------------------------------------------------------- */
-
- // Check if getElementsByTagName("*") returns only elements
- support.getElementsByTagName = assert(function( div ) {
- div.appendChild( doc.createComment("") );
- return !div.getElementsByTagName("*").length;
- });
-
- // Support: IE<9
- support.getElementsByClassName = rnative.test( doc.getElementsByClassName );
-
- // Support: IE<10
- // Check if getElementById returns elements by name
- // The broken getElementById methods don't pick up programatically-set names,
- // so use a roundabout getElementsByName test
- support.getById = assert(function( div ) {
- docElem.appendChild( div ).id = expando;
- return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
- });
-
- // ID find and filter
- if ( support.getById ) {
- Expr.find["ID"] = function( id, context ) {
- if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
- var m = context.getElementById( id );
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- return m && m.parentNode ? [ m ] : [];
- }
- };
- Expr.filter["ID"] = function( id ) {
- var attrId = id.replace( runescape, funescape );
- return function( elem ) {
- return elem.getAttribute("id") === attrId;
- };
- };
- } else {
- // Support: IE6/7
- // getElementById is not reliable as a find shortcut
- delete Expr.find["ID"];
-
- Expr.filter["ID"] = function( id ) {
- var attrId = id.replace( runescape, funescape );
- return function( elem ) {
- var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
- return node && node.value === attrId;
- };
- };
- }
-
- // Tag
- Expr.find["TAG"] = support.getElementsByTagName ?
- function( tag, context ) {
- if ( typeof context.getElementsByTagName !== "undefined" ) {
- return context.getElementsByTagName( tag );
-
- // DocumentFragment nodes don't have gEBTN
- } else if ( support.qsa ) {
- return context.querySelectorAll( tag );
- }
- } :
-
- function( tag, context ) {
- var elem,
- tmp = [],
- i = 0,
- // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
- results = context.getElementsByTagName( tag );
-
- // Filter out possible comments
- if ( tag === "*" ) {
- while ( (elem = results[i++]) ) {
- if ( elem.nodeType === 1 ) {
- tmp.push( elem );
- }
- }
-
- return tmp;
- }
- return results;
- };
-
- // Class
- Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
- if ( documentIsHTML ) {
- return context.getElementsByClassName( className );
- }
- };
-
- /* QSA/matchesSelector
- ---------------------------------------------------------------------- */
-
- // QSA and matchesSelector support
-
- // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
- rbuggyMatches = [];
-
- // qSa(:focus) reports false when true (Chrome 21)
- // We allow this because of a bug in IE8/9 that throws an error
- // whenever `document.activeElement` is accessed on an iframe
- // So, we allow :focus to pass through QSA all the time to avoid the IE error
- // See http://bugs.jquery.com/ticket/13378
- rbuggyQSA = [];
-
- if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
- // Build QSA regex
- // Regex strategy adopted from Diego Perini
- assert(function( div ) {
- // Select is set to empty string on purpose
- // This is to test IE's treatment of not explicitly
- // setting a boolean content attribute,
- // since its presence should be enough
- // http://bugs.jquery.com/ticket/12359
- docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" +
- "<select id='" + expando + "-\f]' msallowcapture=''>" +
- "<option selected=''></option></select>";
-
- // Support: IE8, Opera 11-12.16
- // Nothing should be selected when empty strings follow ^= or $= or *=
- // The test attribute must be unknown in Opera but "safe" for WinRT
- // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
- if ( div.querySelectorAll("[msallowcapture^='']").length ) {
- rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
- }
-
- // Support: IE8
- // Boolean attributes and "value" are not treated correctly
- if ( !div.querySelectorAll("[selected]").length ) {
- rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
- }
-
- // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+
- if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
- rbuggyQSA.push("~=");
- }
-
- // Webkit/Opera - :checked should return selected option elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- // IE8 throws error here and will not see later tests
- if ( !div.querySelectorAll(":checked").length ) {
- rbuggyQSA.push(":checked");
- }
-
- // Support: Safari 8+, iOS 8+
- // https://bugs.webkit.org/show_bug.cgi?id=136851
- // In-page `selector#id sibing-combinator selector` fails
- if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
- rbuggyQSA.push(".#.+[+~]");
- }
- });
-
- assert(function( div ) {
- // Support: Windows 8 Native Apps
- // The type and name attributes are restricted during .innerHTML assignment
- var input = doc.createElement("input");
- input.setAttribute( "type", "hidden" );
- div.appendChild( input ).setAttribute( "name", "D" );
-
- // Support: IE8
- // Enforce case-sensitivity of name attribute
- if ( div.querySelectorAll("[name=d]").length ) {
- rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
- }
-
- // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
- // IE8 throws error here and will not see later tests
- if ( !div.querySelectorAll(":enabled").length ) {
- rbuggyQSA.push( ":enabled", ":disabled" );
- }
-
- // Opera 10-11 does not throw on post-comma invalid pseudos
- div.querySelectorAll("*,:x");
- rbuggyQSA.push(",.*:");
- });
- }
-
- if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
- docElem.webkitMatchesSelector ||
- docElem.mozMatchesSelector ||
- docElem.oMatchesSelector ||
- docElem.msMatchesSelector) )) ) {
-
- assert(function( div ) {
- // Check to see if it's possible to do matchesSelector
- // on a disconnected node (IE 9)
- support.disconnectedMatch = matches.call( div, "div" );
-
- // This should fail with an exception
- // Gecko does not error, returns false instead
- matches.call( div, "[s!='']:x" );
- rbuggyMatches.push( "!=", pseudos );
- });
- }
-
- rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
- rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
-
- /* Contains
- ---------------------------------------------------------------------- */
- hasCompare = rnative.test( docElem.compareDocumentPosition );
-
- // Element contains another
- // Purposefully does not implement inclusive descendent
- // As in, an element does not contain itself
- contains = hasCompare || rnative.test( docElem.contains ) ?
- function( a, b ) {
- var adown = a.nodeType === 9 ? a.documentElement : a,
- bup = b && b.parentNode;
- return a === bup || !!( bup && bup.nodeType === 1 && (
- adown.contains ?
- adown.contains( bup ) :
- a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
- ));
- } :
- function( a, b ) {
- if ( b ) {
- while ( (b = b.parentNode) ) {
- if ( b === a ) {
- return true;
- }
- }
- }
- return false;
- };
-
- /* Sorting
- ---------------------------------------------------------------------- */
-
- // Document order sorting
- sortOrder = hasCompare ?
- function( a, b ) {
-
- // Flag for duplicate removal
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
- }
-
- // Sort on method existence if only one input has compareDocumentPosition
- var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
- if ( compare ) {
- return compare;
- }
-
- // Calculate position if both inputs belong to the same document
- compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
- a.compareDocumentPosition( b ) :
-
- // Otherwise we know they are disconnected
- 1;
-
- // Disconnected nodes
- if ( compare & 1 ||
- (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
-
- // Choose the first element that is related to our preferred document
- if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
- return -1;
- }
- if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
- return 1;
- }
-
- // Maintain original order
- return sortInput ?
- ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
- 0;
- }
-
- return compare & 4 ? -1 : 1;
- } :
- function( a, b ) {
- // Exit early if the nodes are identical
- if ( a === b ) {
- hasDuplicate = true;
- return 0;
- }
-
- var cur,
- i = 0,
- aup = a.parentNode,
- bup = b.parentNode,
- ap = [ a ],
- bp = [ b ];
-
- // Parentless nodes are either documents or disconnected
- if ( !aup || !bup ) {
- return a === doc ? -1 :
- b === doc ? 1 :
- aup ? -1 :
- bup ? 1 :
- sortInput ?
- ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
- 0;
-
- // If the nodes are siblings, we can do a quick check
- } else if ( aup === bup ) {
- return siblingCheck( a, b );
- }
-
- // Otherwise we need full lists of their ancestors for comparison
- cur = a;
- while ( (cur = cur.parentNode) ) {
- ap.unshift( cur );
- }
- cur = b;
- while ( (cur = cur.parentNode) ) {
- bp.unshift( cur );
- }
-
- // Walk down the tree looking for a discrepancy
- while ( ap[i] === bp[i] ) {
- i++;
- }
-
- return i ?
- // Do a sibling check if the nodes have a common ancestor
- siblingCheck( ap[i], bp[i] ) :
-
- // Otherwise nodes in our document sort first
- ap[i] === preferredDoc ? -1 :
- bp[i] === preferredDoc ? 1 :
- 0;
- };
-
- return doc;
-};
-
-Sizzle.matches = function( expr, elements ) {
- return Sizzle( expr, null, null, elements );
-};
-
-Sizzle.matchesSelector = function( elem, expr ) {
- // Set document vars if needed
- if ( ( elem.ownerDocument || elem ) !== document ) {
- setDocument( elem );
- }
-
- // Make sure that attribute selectors are quoted
- expr = expr.replace( rattributeQuotes, "='$1']" );
-
- if ( support.matchesSelector && documentIsHTML &&
- ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
- ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
-
- try {
- var ret = matches.call( elem, expr );
-
- // IE 9's matchesSelector returns false on disconnected nodes
- if ( ret || support.disconnectedMatch ||
- // As well, disconnected nodes are said to be in a document
- // fragment in IE 9
- elem.document && elem.document.nodeType !== 11 ) {
- return ret;
- }
- } catch (e) {}
- }
-
- return Sizzle( expr, document, null, [ elem ] ).length > 0;
-};
-
-Sizzle.contains = function( context, elem ) {
- // Set document vars if needed
- if ( ( context.ownerDocument || context ) !== document ) {
- setDocument( context );
- }
- return contains( context, elem );
-};
-
-Sizzle.attr = function( elem, name ) {
- // Set document vars if needed
- if ( ( elem.ownerDocument || elem ) !== document ) {
- setDocument( elem );
- }
-
- var fn = Expr.attrHandle[ name.toLowerCase() ],
- // Don't get fooled by Object.prototype properties (jQuery #13807)
- val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
- fn( elem, name, !documentIsHTML ) :
- undefined;
-
- return val !== undefined ?
- val :
- support.attributes || !documentIsHTML ?
- elem.getAttribute( name ) :
- (val = elem.getAttributeNode(name)) && val.specified ?
- val.value :
- null;
-};
-
-Sizzle.error = function( msg ) {
- throw new Error( "Syntax error, unrecognized expression: " + msg );
-};
-
-/**
- * Document sorting and removing duplicates
- * @param {ArrayLike} results
- */
-Sizzle.uniqueSort = function( results ) {
- var elem,
- duplicates = [],
- j = 0,
- i = 0;
-
- // Unless we *know* we can detect duplicates, assume their presence
- hasDuplicate = !support.detectDuplicates;
- sortInput = !support.sortStable && results.slice( 0 );
- results.sort( sortOrder );
-
- if ( hasDuplicate ) {
- while ( (elem = results[i++]) ) {
- if ( elem === results[ i ] ) {
- j = duplicates.push( i );
- }
- }
- while ( j-- ) {
- results.splice( duplicates[ j ], 1 );
- }
- }
-
- // Clear input after sorting to release objects
- // See https://github.com/jquery/sizzle/pull/225
- sortInput = null;
-
- return results;
-};
-
-/**
- * Utility function for retrieving the text value of an array of DOM nodes
- * @param {Array|Element} elem
- */
-getText = Sizzle.getText = function( elem ) {
- var node,
- ret = "",
- i = 0,
- nodeType = elem.nodeType;
-
- if ( !nodeType ) {
- // If no nodeType, this is expected to be an array
- while ( (node = elem[i++]) ) {
- // Do not traverse comment nodes
- ret += getText( node );
- }
- } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
- // Use textContent for elements
- // innerText usage removed for consistency of new lines (jQuery #11153)
- if ( typeof elem.textContent === "string" ) {
- return elem.textContent;
- } else {
- // Traverse its children
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
- ret += getText( elem );
- }
- }
- } else if ( nodeType === 3 || nodeType === 4 ) {
- return elem.nodeValue;
- }
- // Do not include comment or processing instruction nodes
-
- return ret;
-};
-
-Expr = Sizzle.selectors = {
-
- // Can be adjusted by the user
- cacheLength: 50,
-
- createPseudo: markFunction,
-
- match: matchExpr,
-
- attrHandle: {},
-
- find: {},
-
- relative: {
- ">": { dir: "parentNode", first: true },
- " ": { dir: "parentNode" },
- "+": { dir: "previousSibling", first: true },
- "~": { dir: "previousSibling" }
- },
-
- preFilter: {
- "ATTR": function( match ) {
- match[1] = match[1].replace( runescape, funescape );
-
- // Move the given value to match[3] whether quoted or unquoted
- match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
-
- if ( match[2] === "~=" ) {
- match[3] = " " + match[3] + " ";
- }
-
- return match.slice( 0, 4 );
- },
-
- "CHILD": function( match ) {
- /* matches from matchExpr["CHILD"]
- 1 type (only|nth|...)
- 2 what (child|of-type)
- 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
- 4 xn-component of xn+y argument ([+-]?\d*n|)
- 5 sign of xn-component
- 6 x of xn-component
- 7 sign of y-component
- 8 y of y-component
- */
- match[1] = match[1].toLowerCase();
-
- if ( match[1].slice( 0, 3 ) === "nth" ) {
- // nth-* requires argument
- if ( !match[3] ) {
- Sizzle.error( match[0] );
- }
-
- // numeric x and y parameters for Expr.filter.CHILD
- // remember that false/true cast respectively to 0/1
- match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
- match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
-
- // other types prohibit arguments
- } else if ( match[3] ) {
- Sizzle.error( match[0] );
- }
-
- return match;
- },
-
- "PSEUDO": function( match ) {
- var excess,
- unquoted = !match[6] && match[2];
-
- if ( matchExpr["CHILD"].test( match[0] ) ) {
- return null;
- }
-
- // Accept quoted arguments as-is
- if ( match[3] ) {
- match[2] = match[4] || match[5] || "";
-
- // Strip excess characters from unquoted arguments
- } else if ( unquoted && rpseudo.test( unquoted ) &&
- // Get excess from tokenize (recursively)
- (excess = tokenize( unquoted, true )) &&
- // advance to the next closing parenthesis
- (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
-
- // excess is a negative index
- match[0] = match[0].slice( 0, excess );
- match[2] = unquoted.slice( 0, excess );
- }
-
- // Return only captures needed by the pseudo filter method (type and argument)
- return match.slice( 0, 3 );
- }
- },
-
- filter: {
-
- "TAG": function( nodeNameSelector ) {
- var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
- return nodeNameSelector === "*" ?
- function() { return true; } :
- function( elem ) {
- return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
- };
- },
-
- "CLASS": function( className ) {
- var pattern = classCache[ className + " " ];
-
- return pattern ||
- (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
- classCache( className, function( elem ) {
- return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
- });
- },
-
- "ATTR": function( name, operator, check ) {
- return function( elem ) {
- var result = Sizzle.attr( elem, name );
-
- if ( result == null ) {
- return operator === "!=";
- }
- if ( !operator ) {
- return true;
- }
-
- result += "";
-
- return operator === "=" ? result === check :
- operator === "!=" ? result !== check :
- operator === "^=" ? check && result.indexOf( check ) === 0 :
- operator === "*=" ? check && result.indexOf( check ) > -1 :
- operator === "$=" ? check && result.slice( -check.length ) === check :
- operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
- operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
- false;
- };
- },
-
- "CHILD": function( type, what, argument, first, last ) {
- var simple = type.slice( 0, 3 ) !== "nth",
- forward = type.slice( -4 ) !== "last",
- ofType = what === "of-type";
-
- return first === 1 && last === 0 ?
-
- // Shortcut for :nth-*(n)
- function( elem ) {
- return !!elem.parentNode;
- } :
-
- function( elem, context, xml ) {
- var cache, outerCache, node, diff, nodeIndex, start,
- dir = simple !== forward ? "nextSibling" : "previousSibling",
- parent = elem.parentNode,
- name = ofType && elem.nodeName.toLowerCase(),
- useCache = !xml && !ofType;
-
- if ( parent ) {
-
- // :(first|last|only)-(child|of-type)
- if ( simple ) {
- while ( dir ) {
- node = elem;
- while ( (node = node[ dir ]) ) {
- if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
- return false;
- }
- }
- // Reverse direction for :only-* (if we haven't yet done so)
- start = dir = type === "only" && !start && "nextSibling";
- }
- return true;
- }
-
- start = [ forward ? parent.firstChild : parent.lastChild ];
-
- // non-xml :nth-child(...) stores cache data on `parent`
- if ( forward && useCache ) {
- // Seek `elem` from a previously-cached index
- outerCache = parent[ expando ] || (parent[ expando ] = {});
- cache = outerCache[ type ] || [];
- nodeIndex = cache[0] === dirruns && cache[1];
- diff = cache[0] === dirruns && cache[2];
- node = nodeIndex && parent.childNodes[ nodeIndex ];
-
- while ( (node = ++nodeIndex && node && node[ dir ] ||
-
- // Fallback to seeking `elem` from the start
- (diff = nodeIndex = 0) || start.pop()) ) {
-
- // When found, cache indexes on `parent` and break
- if ( node.nodeType === 1 && ++diff && node === elem ) {
- outerCache[ type ] = [ dirruns, nodeIndex, diff ];
- break;
- }
- }
-
- // Use previously-cached element index if available
- } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
- diff = cache[1];
-
- // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
- } else {
- // Use the same loop as above to seek `elem` from the start
- while ( (node = ++nodeIndex && node && node[ dir ] ||
- (diff = nodeIndex = 0) || start.pop()) ) {
-
- if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
- // Cache the index of each encountered element
- if ( useCache ) {
- (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
- }
-
- if ( node === elem ) {
- break;
- }
- }
- }
- }
-
- // Incorporate the offset, then check against cycle size
- diff -= last;
- return diff === first || ( diff % first === 0 && diff / first >= 0 );
- }
- };
- },
-
- "PSEUDO": function( pseudo, argument ) {
- // pseudo-class names are case-insensitive
- // http://www.w3.org/TR/selectors/#pseudo-classes
- // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
- // Remember that setFilters inherits from pseudos
- var args,
- fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
- Sizzle.error( "unsupported pseudo: " + pseudo );
-
- // The user may use createPseudo to indicate that
- // arguments are needed to create the filter function
- // just as Sizzle does
- if ( fn[ expando ] ) {
- return fn( argument );
- }
-
- // But maintain support for old signatures
- if ( fn.length > 1 ) {
- args = [ pseudo, pseudo, "", argument ];
- return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
- markFunction(function( seed, matches ) {
- var idx,
- matched = fn( seed, argument ),
- i = matched.length;
- while ( i-- ) {
- idx = indexOf( seed, matched[i] );
- seed[ idx ] = !( matches[ idx ] = matched[i] );
- }
- }) :
- function( elem ) {
- return fn( elem, 0, args );
- };
- }
-
- return fn;
- }
- },
-
- pseudos: {
- // Potentially complex pseudos
- "not": markFunction(function( selector ) {
- // Trim the selector passed to compile
- // to avoid treating leading and trailing
- // spaces as combinators
- var input = [],
- results = [],
- matcher = compile( selector.replace( rtrim, "$1" ) );
-
- return matcher[ expando ] ?
- markFunction(function( seed, matches, context, xml ) {
- var elem,
- unmatched = matcher( seed, null, xml, [] ),
- i = seed.length;
-
- // Match elements unmatched by `matcher`
- while ( i-- ) {
- if ( (elem = unmatched[i]) ) {
- seed[i] = !(matches[i] = elem);
- }
- }
- }) :
- function( elem, context, xml ) {
- input[0] = elem;
- matcher( input, null, xml, results );
- // Don't keep the element (issue #299)
- input[0] = null;
- return !results.pop();
- };
- }),
-
- "has": markFunction(function( selector ) {
- return function( elem ) {
- return Sizzle( selector, elem ).length > 0;
- };
- }),
-
- "contains": markFunction(function( text ) {
- text = text.replace( runescape, funescape );
- return function( elem ) {
- return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
- };
- }),
-
- // "Whether an element is represented by a :lang() selector
- // is based solely on the element's language value
- // being equal to the identifier C,
- // or beginning with the identifier C immediately followed by "-".
- // The matching of C against the element's language value is performed case-insensitively.
- // The identifier C does not have to be a valid language name."
- // http://www.w3.org/TR/selectors/#lang-pseudo
- "lang": markFunction( function( lang ) {
- // lang value must be a valid identifier
- if ( !ridentifier.test(lang || "") ) {
- Sizzle.error( "unsupported lang: " + lang );
- }
- lang = lang.replace( runescape, funescape ).toLowerCase();
- return function( elem ) {
- var elemLang;
- do {
- if ( (elemLang = documentIsHTML ?
- elem.lang :
- elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
-
- elemLang = elemLang.toLowerCase();
- return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
- }
- } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
- return false;
- };
- }),
-
- // Miscellaneous
- "target": function( elem ) {
- var hash = window.location && window.location.hash;
- return hash && hash.slice( 1 ) === elem.id;
- },
-
- "root": function( elem ) {
- return elem === docElem;
- },
-
- "focus": function( elem ) {
- return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
- },
-
- // Boolean properties
- "enabled": function( elem ) {
- return elem.disabled === false;
- },
-
- "disabled": function( elem ) {
- return elem.disabled === true;
- },
-
- "checked": function( elem ) {
- // In CSS3, :checked should return both checked and selected elements
- // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
- var nodeName = elem.nodeName.toLowerCase();
- return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
- },
-
- "selected": function( elem ) {
- // Accessing this property makes selected-by-default
- // options in Safari work properly
- if ( elem.parentNode ) {
- elem.parentNode.selectedIndex;
- }
-
- return elem.selected === true;
- },
-
- // Contents
- "empty": function( elem ) {
- // http://www.w3.org/TR/selectors/#empty-pseudo
- // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
- // but not by others (comment: 8; processing instruction: 7; etc.)
- // nodeType < 6 works because attributes (2) do not appear as children
- for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
- if ( elem.nodeType < 6 ) {
- return false;
- }
- }
- return true;
- },
-
- "parent": function( elem ) {
- return !Expr.pseudos["empty"]( elem );
- },
-
- // Element/input types
- "header": function( elem ) {
- return rheader.test( elem.nodeName );
- },
-
- "input": function( elem ) {
- return rinputs.test( elem.nodeName );
- },
-
- "button": function( elem ) {
- var name = elem.nodeName.toLowerCase();
- return name === "input" && elem.type === "button" || name === "button";
- },
-
- "text": function( elem ) {
- var attr;
- return elem.nodeName.toLowerCase() === "input" &&
- elem.type === "text" &&
-
- // Support: IE<8
- // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
- ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
- },
-
- // Position-in-collection
- "first": createPositionalPseudo(function() {
- return [ 0 ];
- }),
-
- "last": createPositionalPseudo(function( matchIndexes, length ) {
- return [ length - 1 ];
- }),
-
- "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
- return [ argument < 0 ? argument + length : argument ];
- }),
-
- "even": createPositionalPseudo(function( matchIndexes, length ) {
- var i = 0;
- for ( ; i < length; i += 2 ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "odd": createPositionalPseudo(function( matchIndexes, length ) {
- var i = 1;
- for ( ; i < length; i += 2 ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
- var i = argument < 0 ? argument + length : argument;
- for ( ; --i >= 0; ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- }),
-
- "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
- var i = argument < 0 ? argument + length : argument;
- for ( ; ++i < length; ) {
- matchIndexes.push( i );
- }
- return matchIndexes;
- })
- }
-};
-
-Expr.pseudos["nth"] = Expr.pseudos["eq"];
-
-// Add button/input type pseudos
-for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
- Expr.pseudos[ i ] = createInputPseudo( i );
-}
-for ( i in { submit: true, reset: true } ) {
- Expr.pseudos[ i ] = createButtonPseudo( i );
-}
-
-// Easy API for creating new setFilters
-function setFilters() {}
-setFilters.prototype = Expr.filters = Expr.pseudos;
-Expr.setFilters = new setFilters();
-
-tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
- var matched, match, tokens, type,
- soFar, groups, preFilters,
- cached = tokenCache[ selector + " " ];
-
- if ( cached ) {
- return parseOnly ? 0 : cached.slice( 0 );
- }
-
- soFar = selector;
- groups = [];
- preFilters = Expr.preFilter;
-
- while ( soFar ) {
-
- // Comma and first run
- if ( !matched || (match = rcomma.exec( soFar )) ) {
- if ( match ) {
- // Don't consume trailing commas as valid
- soFar = soFar.slice( match[0].length ) || soFar;
- }
- groups.push( (tokens = []) );
- }
-
- matched = false;
-
- // Combinators
- if ( (match = rcombinators.exec( soFar )) ) {
- matched = match.shift();
- tokens.push({
- value: matched,
- // Cast descendant combinators to space
- type: match[0].replace( rtrim, " " )
- });
- soFar = soFar.slice( matched.length );
- }
-
- // Filters
- for ( type in Expr.filter ) {
- if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
- (match = preFilters[ type ]( match ))) ) {
- matched = match.shift();
- tokens.push({
- value: matched,
- type: type,
- matches: match
- });
- soFar = soFar.slice( matched.length );
- }
- }
-
- if ( !matched ) {
- break;
- }
- }
-
- // Return the length of the invalid excess
- // if we're just parsing
- // Otherwise, throw an error or return tokens
- return parseOnly ?
- soFar.length :
- soFar ?
- Sizzle.error( selector ) :
- // Cache the tokens
- tokenCache( selector, groups ).slice( 0 );
-};
-
-function toSelector( tokens ) {
- var i = 0,
- len = tokens.length,
- selector = "";
- for ( ; i < len; i++ ) {
- selector += tokens[i].value;
- }
- return selector;
-}
-
-function addCombinator( matcher, combinator, base ) {
- var dir = combinator.dir,
- checkNonElements = base && dir === "parentNode",
- doneName = done++;
-
- return combinator.first ?
- // Check against closest ancestor/preceding element
- function( elem, context, xml ) {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 || checkNonElements ) {
- return matcher( elem, context, xml );
- }
- }
- } :
-
- // Check against all ancestor/preceding elements
- function( elem, context, xml ) {
- var oldCache, outerCache,
- newCache = [ dirruns, doneName ];
-
- // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
- if ( xml ) {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 || checkNonElements ) {
- if ( matcher( elem, context, xml ) ) {
- return true;
- }
- }
- }
- } else {
- while ( (elem = elem[ dir ]) ) {
- if ( elem.nodeType === 1 || checkNonElements ) {
- outerCache = elem[ expando ] || (elem[ expando ] = {});
- if ( (oldCache = outerCache[ dir ]) &&
- oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
-
- // Assign to newCache so results back-propagate to previous elements
- return (newCache[ 2 ] = oldCache[ 2 ]);
- } else {
- // Reuse newcache so results back-propagate to previous elements
- outerCache[ dir ] = newCache;
-
- // A match means we're done; a fail means we have to keep checking
- if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
- return true;
- }
- }
- }
- }
- }
- };
-}
-
-function elementMatcher( matchers ) {
- return matchers.length > 1 ?
- function( elem, context, xml ) {
- var i = matchers.length;
- while ( i-- ) {
- if ( !matchers[i]( elem, context, xml ) ) {
- return false;
- }
- }
- return true;
- } :
- matchers[0];
-}
-
-function multipleContexts( selector, contexts, results ) {
- var i = 0,
- len = contexts.length;
- for ( ; i < len; i++ ) {
- Sizzle( selector, contexts[i], results );
- }
- return results;
-}
-
-function condense( unmatched, map, filter, context, xml ) {
- var elem,
- newUnmatched = [],
- i = 0,
- len = unmatched.length,
- mapped = map != null;
-
- for ( ; i < len; i++ ) {
- if ( (elem = unmatched[i]) ) {
- if ( !filter || filter( elem, context, xml ) ) {
- newUnmatched.push( elem );
- if ( mapped ) {
- map.push( i );
- }
- }
- }
- }
-
- return newUnmatched;
-}
-
-function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
- if ( postFilter && !postFilter[ expando ] ) {
- postFilter = setMatcher( postFilter );
- }
- if ( postFinder && !postFinder[ expando ] ) {
- postFinder = setMatcher( postFinder, postSelector );
- }
- return markFunction(function( seed, results, context, xml ) {
- var temp, i, elem,
- preMap = [],
- postMap = [],
- preexisting = results.length,
-
- // Get initial elements from seed or context
- elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
-
- // Prefilter to get matcher input, preserving a map for seed-results synchronization
- matcherIn = preFilter && ( seed || !selector ) ?
- condense( elems, preMap, preFilter, context, xml ) :
- elems,
-
- matcherOut = matcher ?
- // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
- postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
-
- // ...intermediate processing is necessary
- [] :
-
- // ...otherwise use results directly
- results :
- matcherIn;
-
- // Find primary matches
- if ( matcher ) {
- matcher( matcherIn, matcherOut, context, xml );
- }
-
- // Apply postFilter
- if ( postFilter ) {
- temp = condense( matcherOut, postMap );
- postFilter( temp, [], context, xml );
-
- // Un-match failing elements by moving them back to matcherIn
- i = temp.length;
- while ( i-- ) {
- if ( (elem = temp[i]) ) {
- matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
- }
- }
- }
-
- if ( seed ) {
- if ( postFinder || preFilter ) {
- if ( postFinder ) {
- // Get the final matcherOut by condensing this intermediate into postFinder contexts
- temp = [];
- i = matcherOut.length;
- while ( i-- ) {
- if ( (elem = matcherOut[i]) ) {
- // Restore matcherIn since elem is not yet a final match
- temp.push( (matcherIn[i] = elem) );
- }
- }
- postFinder( null, (matcherOut = []), temp, xml );
- }
-
- // Move matched elements from seed to results to keep them synchronized
- i = matcherOut.length;
- while ( i-- ) {
- if ( (elem = matcherOut[i]) &&
- (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
-
- seed[temp] = !(results[temp] = elem);
- }
- }
- }
-
- // Add elements to results, through postFinder if defined
- } else {
- matcherOut = condense(
- matcherOut === results ?
- matcherOut.splice( preexisting, matcherOut.length ) :
- matcherOut
- );
- if ( postFinder ) {
- postFinder( null, results, matcherOut, xml );
- } else {
- push.apply( results, matcherOut );
- }
- }
- });
-}
-
-function matcherFromTokens( tokens ) {
- var checkContext, matcher, j,
- len = tokens.length,
- leadingRelative = Expr.relative[ tokens[0].type ],
- implicitRelative = leadingRelative || Expr.relative[" "],
- i = leadingRelative ? 1 : 0,
-
- // The foundational matcher ensures that elements are reachable from top-level context(s)
- matchContext = addCombinator( function( elem ) {
- return elem === checkContext;
- }, implicitRelative, true ),
- matchAnyContext = addCombinator( function( elem ) {
- return indexOf( checkContext, elem ) > -1;
- }, implicitRelative, true ),
- matchers = [ function( elem, context, xml ) {
- var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
- (checkContext = context).nodeType ?
- matchContext( elem, context, xml ) :
- matchAnyContext( elem, context, xml ) );
- // Avoid hanging onto element (issue #299)
- checkContext = null;
- return ret;
- } ];
-
- for ( ; i < len; i++ ) {
- if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
- matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
- } else {
- matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
-
- // Return special upon seeing a positional matcher
- if ( matcher[ expando ] ) {
- // Find the next relative operator (if any) for proper handling
- j = ++i;
- for ( ; j < len; j++ ) {
- if ( Expr.relative[ tokens[j].type ] ) {
- break;
- }
- }
- return setMatcher(
- i > 1 && elementMatcher( matchers ),
- i > 1 && toSelector(
- // If the preceding token was a descendant combinator, insert an implicit any-element `*`
- tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
- ).replace( rtrim, "$1" ),
- matcher,
- i < j && matcherFromTokens( tokens.slice( i, j ) ),
- j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
- j < len && toSelector( tokens )
- );
- }
- matchers.push( matcher );
- }
- }
-
- return elementMatcher( matchers );
-}
-
-function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
- var bySet = setMatchers.length > 0,
- byElement = elementMatchers.length > 0,
- superMatcher = function( seed, context, xml, results, outermost ) {
- var elem, j, matcher,
- matchedCount = 0,
- i = "0",
- unmatched = seed && [],
- setMatched = [],
- contextBackup = outermostContext,
- // We must always have either seed elements or outermost context
- elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
- // Use integer dirruns iff this is the outermost matcher
- dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
- len = elems.length;
-
- if ( outermost ) {
- outermostContext = context !== document && context;
- }
-
- // Add elements passing elementMatchers directly to results
- // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
- // Support: IE<9, Safari
- // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
- for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
- if ( byElement && elem ) {
- j = 0;
- while ( (matcher = elementMatchers[j++]) ) {
- if ( matcher( elem, context, xml ) ) {
- results.push( elem );
- break;
- }
- }
- if ( outermost ) {
- dirruns = dirrunsUnique;
- }
- }
-
- // Track unmatched elements for set filters
- if ( bySet ) {
- // They will have gone through all possible matchers
- if ( (elem = !matcher && elem) ) {
- matchedCount--;
- }
-
- // Lengthen the array for every element, matched or not
- if ( seed ) {
- unmatched.push( elem );
- }
- }
- }
-
- // Apply set filters to unmatched elements
- matchedCount += i;
- if ( bySet && i !== matchedCount ) {
- j = 0;
- while ( (matcher = setMatchers[j++]) ) {
- matcher( unmatched, setMatched, context, xml );
- }
-
- if ( seed ) {
- // Reintegrate element matches to eliminate the need for sorting
- if ( matchedCount > 0 ) {
- while ( i-- ) {
- if ( !(unmatched[i] || setMatched[i]) ) {
- setMatched[i] = pop.call( results );
- }
- }
- }
-
- // Discard index placeholder values to get only actual matches
- setMatched = condense( setMatched );
- }
-
- // Add matches to results
- push.apply( results, setMatched );
-
- // Seedless set matches succeeding multiple successful matchers stipulate sorting
- if ( outermost && !seed && setMatched.length > 0 &&
- ( matchedCount + setMatchers.length ) > 1 ) {
-
- Sizzle.uniqueSort( results );
- }
- }
-
- // Override manipulation of globals by nested matchers
- if ( outermost ) {
- dirruns = dirrunsUnique;
- outermostContext = contextBackup;
- }
-
- return unmatched;
- };
-
- return bySet ?
- markFunction( superMatcher ) :
- superMatcher;
-}
-
-compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
- var i,
- setMatchers = [],
- elementMatchers = [],
- cached = compilerCache[ selector + " " ];
-
- if ( !cached ) {
- // Generate a function of recursive functions that can be used to check each element
- if ( !match ) {
- match = tokenize( selector );
- }
- i = match.length;
- while ( i-- ) {
- cached = matcherFromTokens( match[i] );
- if ( cached[ expando ] ) {
- setMatchers.push( cached );
- } else {
- elementMatchers.push( cached );
- }
- }
-
- // Cache the compiled function
- cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
-
- // Save selector and tokenization
- cached.selector = selector;
- }
- return cached;
-};
-
-/**
- * A low-level selection function that works with Sizzle's compiled
- * selector functions
- * @param {String|Function} selector A selector or a pre-compiled
- * selector function built with Sizzle.compile
- * @param {Element} context
- * @param {Array} [results]
- * @param {Array} [seed] A set of elements to match against
- */
-select = Sizzle.select = function( selector, context, results, seed ) {
- var i, tokens, token, type, find,
- compiled = typeof selector === "function" && selector,
- match = !seed && tokenize( (selector = compiled.selector || selector) );
-
- results = results || [];
-
- // Try to minimize operations if there is no seed and only one group
- if ( match.length === 1 ) {
-
- // Take a shortcut and set the context if the root selector is an ID
- tokens = match[0] = match[0].slice( 0 );
- if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
- support.getById && context.nodeType === 9 && documentIsHTML &&
- Expr.relative[ tokens[1].type ] ) {
-
- context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
- if ( !context ) {
- return results;
-
- // Precompiled matchers will still verify ancestry, so step up a level
- } else if ( compiled ) {
- context = context.parentNode;
- }
-
- selector = selector.slice( tokens.shift().value.length );
- }
-
- // Fetch a seed set for right-to-left matching
- i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
- while ( i-- ) {
- token = tokens[i];
-
- // Abort if we hit a combinator
- if ( Expr.relative[ (type = token.type) ] ) {
- break;
- }
- if ( (find = Expr.find[ type ]) ) {
- // Search, expanding context for leading sibling combinators
- if ( (seed = find(
- token.matches[0].replace( runescape, funescape ),
- rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
- )) ) {
-
- // If seed is empty or no tokens remain, we can return early
- tokens.splice( i, 1 );
- selector = seed.length && toSelector( tokens );
- if ( !selector ) {
- push.apply( results, seed );
- return results;
- }
-
- break;
- }
- }
- }
- }
-
- // Compile and execute a filtering function if one is not provided
- // Provide `match` to avoid retokenization if we modified the selector above
- ( compiled || compile( selector, match ) )(
- seed,
- context,
- !documentIsHTML,
- results,
- rsibling.test( selector ) && testContext( context.parentNode ) || context
- );
- return results;
-};
-
-// One-time assignments
-
-// Sort stability
-support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
-
-// Support: Chrome 14-35+
-// Always assume duplicates if they aren't passed to the comparison function
-support.detectDuplicates = !!hasDuplicate;
-
-// Initialize against the default document
-setDocument();
-
-// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
-// Detached nodes confoundingly follow *each other*
-support.sortDetached = assert(function( div1 ) {
- // Should return 1, but returns 4 (following)
- return div1.compareDocumentPosition( document.createElement("div") ) & 1;
-});
-
-// Support: IE<8
-// Prevent attribute/property "interpolation"
-// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
-if ( !assert(function( div ) {
- div.innerHTML = "<a href='#'></a>";
- return div.firstChild.getAttribute("href") === "#" ;
-}) ) {
- addHandle( "type|href|height|width", function( elem, name, isXML ) {
- if ( !isXML ) {
- return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
- }
- });
-}
-
-// Support: IE<9
-// Use defaultValue in place of getAttribute("value")
-if ( !support.attributes || !assert(function( div ) {
- div.innerHTML = "<input/>";
- div.firstChild.setAttribute( "value", "" );
- return div.firstChild.getAttribute( "value" ) === "";
-}) ) {
- addHandle( "value", function( elem, name, isXML ) {
- if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
- return elem.defaultValue;
- }
- });
-}
-
-// Support: IE<9
-// Use getAttributeNode to fetch booleans when getAttribute lies
-if ( !assert(function( div ) {
- return div.getAttribute("disabled") == null;
-}) ) {
- addHandle( booleans, function( elem, name, isXML ) {
- var val;
- if ( !isXML ) {
- return elem[ name ] === true ? name.toLowerCase() :
- (val = elem.getAttributeNode( name )) && val.specified ?
- val.value :
- null;
- }
- });
-}
-
-return Sizzle;
-
-})( window );
-
-
-
-jQuery.find = Sizzle;
-jQuery.expr = Sizzle.selectors;
-jQuery.expr[":"] = jQuery.expr.pseudos;
-jQuery.unique = Sizzle.uniqueSort;
-jQuery.text = Sizzle.getText;
-jQuery.isXMLDoc = Sizzle.isXML;
-jQuery.contains = Sizzle.contains;
-
-
-
-var rneedsContext = jQuery.expr.match.needsContext;
-
-var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/);
-
-
-
-var risSimple = /^.[^:#\[\.,]*$/;
-
-// Implement the identical functionality for filter and not
-function winnow( elements, qualifier, not ) {
- if ( jQuery.isFunction( qualifier ) ) {
- return jQuery.grep( elements, function( elem, i ) {
- /* jshint -W018 */
- return !!qualifier.call( elem, i, elem ) !== not;
- });
-
- }
-
- if ( qualifier.nodeType ) {
- return jQuery.grep( elements, function( elem ) {
- return ( elem === qualifier ) !== not;
- });
-
- }
-
- if ( typeof qualifier === "string" ) {
- if ( risSimple.test( qualifier ) ) {
- return jQuery.filter( qualifier, elements, not );
- }
-
- qualifier = jQuery.filter( qualifier, elements );
- }
-
- return jQuery.grep( elements, function( elem ) {
- return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;
- });
-}
-
-jQuery.filter = function( expr, elems, not ) {
- var elem = elems[ 0 ];
-
- if ( not ) {
- expr = ":not(" + expr + ")";
- }
-
- return elems.length === 1 && elem.nodeType === 1 ?
- jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
- jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
- return elem.nodeType === 1;
- }));
-};
-
-jQuery.fn.extend({
- find: function( selector ) {
- var i,
- ret = [],
- self = this,
- len = self.length;
-
- if ( typeof selector !== "string" ) {
- return this.pushStack( jQuery( selector ).filter(function() {
- for ( i = 0; i < len; i++ ) {
- if ( jQuery.contains( self[ i ], this ) ) {
- return true;
- }
- }
- }) );
- }
-
- for ( i = 0; i < len; i++ ) {
- jQuery.find( selector, self[ i ], ret );
- }
-
- // Needed because $( selector, context ) becomes $( context ).find( selector )
- ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
- ret.selector = this.selector ? this.selector + " " + selector : selector;
- return ret;
- },
- filter: function( selector ) {
- return this.pushStack( winnow(this, selector || [], false) );
- },
- not: function( selector ) {
- return this.pushStack( winnow(this, selector || [], true) );
- },
- is: function( selector ) {
- return !!winnow(
- this,
-
- // If this is a positional/relative selector, check membership in the returned set
- // so $("p:first").is("p:last") won't return true for a doc with two "p".
- typeof selector === "string" && rneedsContext.test( selector ) ?
- jQuery( selector ) :
- selector || [],
- false
- ).length;
- }
-});
-
-
-// Initialize a jQuery object
-
-
-// A central reference to the root jQuery(document)
-var rootjQuery,
-
- // Use the correct document accordingly with window argument (sandbox)
- document = window.document,
-
- // A simple way to check for HTML strings
- // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
- // Strict HTML recognition (#11290: must start with <)
- rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
-
- init = jQuery.fn.init = function( selector, context ) {
- var match, elem;
-
- // HANDLE: $(""), $(null), $(undefined), $(false)
- if ( !selector ) {
- return this;
- }
-
- // Handle HTML strings
- if ( typeof selector === "string" ) {
- if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
- // Assume that strings that start and end with <> are HTML and skip the regex check
- match = [ null, selector, null ];
-
- } else {
- match = rquickExpr.exec( selector );
- }
-
- // Match html or make sure no context is specified for #id
- if ( match && (match[1] || !context) ) {
-
- // HANDLE: $(html) -> $(array)
- if ( match[1] ) {
- context = context instanceof jQuery ? context[0] : context;
-
- // scripts is true for back-compat
- // Intentionally let the error be thrown if parseHTML is not present
- jQuery.merge( this, jQuery.parseHTML(
- match[1],
- context && context.nodeType ? context.ownerDocument || context : document,
- true
- ) );
-
- // HANDLE: $(html, props)
- if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
- for ( match in context ) {
- // Properties of context are called as methods if possible
- if ( jQuery.isFunction( this[ match ] ) ) {
- this[ match ]( context[ match ] );
-
- // ...and otherwise set as attributes
- } else {
- this.attr( match, context[ match ] );
- }
- }
- }
-
- return this;
-
- // HANDLE: $(#id)
- } else {
- elem = document.getElementById( match[2] );
-
- // Check parentNode to catch when Blackberry 4.6 returns
- // nodes that are no longer in the document #6963
- if ( elem && elem.parentNode ) {
- // Handle the case where IE and Opera return items
- // by name instead of ID
- if ( elem.id !== match[2] ) {
- return rootjQuery.find( selector );
- }
-
- // Otherwise, we inject the element directly into the jQuery object
- this.length = 1;
- this[0] = elem;
- }
-
- this.context = document;
- this.selector = selector;
- return this;
- }
-
- // HANDLE: $(expr, $(...))
- } else if ( !context || context.jquery ) {
- return ( context || rootjQuery ).find( selector );
-
- // HANDLE: $(expr, context)
- // (which is just equivalent to: $(context).find(expr)
- } else {
- return this.constructor( context ).find( selector );
- }
-
- // HANDLE: $(DOMElement)
- } else if ( selector.nodeType ) {
- this.context = this[0] = selector;
- this.length = 1;
- return this;
-
- // HANDLE: $(function)
- // Shortcut for document ready
- } else if ( jQuery.isFunction( selector ) ) {
- return typeof rootjQuery.ready !== "undefined" ?
- rootjQuery.ready( selector ) :
- // Execute immediately if ready is not present
- selector( jQuery );
- }
-
- if ( selector.selector !== undefined ) {
- this.selector = selector.selector;
- this.context = selector.context;
- }
-
- return jQuery.makeArray( selector, this );
- };
-
-// Give the init function the jQuery prototype for later instantiation
-init.prototype = jQuery.fn;
-
-// Initialize central reference
-rootjQuery = jQuery( document );
-
-
-var rparentsprev = /^(?:parents|prev(?:Until|All))/,
- // methods guaranteed to produce a unique set when starting from a unique set
- guaranteedUnique = {
- children: true,
- contents: true,
- next: true,
- prev: true
- };
-
-jQuery.extend({
- dir: function( elem, dir, until ) {
- var matched = [],
- cur = elem[ dir ];
-
- while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
- if ( cur.nodeType === 1 ) {
- matched.push( cur );
- }
- cur = cur[dir];
- }
- return matched;
- },
-
- sibling: function( n, elem ) {
- var r = [];
-
- for ( ; n; n = n.nextSibling ) {
- if ( n.nodeType === 1 && n !== elem ) {
- r.push( n );
- }
- }
-
- return r;
- }
-});
-
-jQuery.fn.extend({
- has: function( target ) {
- var i,
- targets = jQuery( target, this ),
- len = targets.length;
-
- return this.filter(function() {
- for ( i = 0; i < len; i++ ) {
- if ( jQuery.contains( this, targets[i] ) ) {
- return true;
- }
- }
- });
- },
-
- closest: function( selectors, context ) {
- var cur,
- i = 0,
- l = this.length,
- matched = [],
- pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
- jQuery( selectors, context || this.context ) :
- 0;
-
- for ( ; i < l; i++ ) {
- for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
- // Always skip document fragments
- if ( cur.nodeType < 11 && (pos ?
- pos.index(cur) > -1 :
-
- // Don't pass non-elements to Sizzle
- cur.nodeType === 1 &&
- jQuery.find.matchesSelector(cur, selectors)) ) {
-
- matched.push( cur );
- break;
- }
- }
- }
-
- return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
- },
-
- // Determine the position of an element within
- // the matched set of elements
- index: function( elem ) {
-
- // No argument, return index in parent
- if ( !elem ) {
- return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;
- }
-
- // index in selector
- if ( typeof elem === "string" ) {
- return jQuery.inArray( this[0], jQuery( elem ) );
- }
-
- // Locate the position of the desired element
- return jQuery.inArray(
- // If it receives a jQuery object, the first element is used
- elem.jquery ? elem[0] : elem, this );
- },
-
- add: function( selector, context ) {
- return this.pushStack(
- jQuery.unique(
- jQuery.merge( this.get(), jQuery( selector, context ) )
- )
- );
- },
-
- addBack: function( selector ) {
- return this.add( selector == null ?
- this.prevObject : this.prevObject.filter(selector)
- );
- }
-});
-
-function sibling( cur, dir ) {
- do {
- cur = cur[ dir ];
- } while ( cur && cur.nodeType !== 1 );
-
- return cur;
-}
-
-jQuery.each({
- parent: function( elem ) {
- var parent = elem.parentNode;
- return parent && parent.nodeType !== 11 ? parent : null;
- },
- parents: function( elem ) {
- return jQuery.dir( elem, "parentNode" );
- },
- parentsUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "parentNode", until );
- },
- next: function( elem ) {
- return sibling( elem, "nextSibling" );
- },
- prev: function( elem ) {
- return sibling( elem, "previousSibling" );
- },
- nextAll: function( elem ) {
- return jQuery.dir( elem, "nextSibling" );
- },
- prevAll: function( elem ) {
- return jQuery.dir( elem, "previousSibling" );
- },
- nextUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "nextSibling", until );
- },
- prevUntil: function( elem, i, until ) {
- return jQuery.dir( elem, "previousSibling", until );
- },
- siblings: function( elem ) {
- return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
- },
- children: function( elem ) {
- return jQuery.sibling( elem.firstChild );
- },
- contents: function( elem ) {
- return jQuery.nodeName( elem, "iframe" ) ?
- elem.contentDocument || elem.contentWindow.document :
- jQuery.merge( [], elem.childNodes );
- }
-}, function( name, fn ) {
- jQuery.fn[ name ] = function( until, selector ) {
- var ret = jQuery.map( this, fn, until );
-
- if ( name.slice( -5 ) !== "Until" ) {
- selector = until;
- }
-
- if ( selector && typeof selector === "string" ) {
- ret = jQuery.filter( selector, ret );
- }
-
- if ( this.length > 1 ) {
- // Remove duplicates
- if ( !guaranteedUnique[ name ] ) {
- ret = jQuery.unique( ret );
- }
-
- // Reverse order for parents* and prev-derivatives
- if ( rparentsprev.test( name ) ) {
- ret = ret.reverse();
- }
- }
-
- return this.pushStack( ret );
- };
-});
-var rnotwhite = (/\S+/g);
-
-
-
-// String to Object options format cache
-var optionsCache = {};
-
-// Convert String-formatted options into Object-formatted ones and store in cache
-function createOptions( options ) {
- var object = optionsCache[ options ] = {};
- jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
- object[ flag ] = true;
- });
- return object;
-}
-
-/*
- * Create a callback list using the following parameters:
- *
- * options: an optional list of space-separated options that will change how
- * the callback list behaves or a more traditional option object
- *
- * By default a callback list will act like an event callback list and can be
- * "fired" multiple times.
- *
- * Possible options:
- *
- * once: will ensure the callback list can only be fired once (like a Deferred)
- *
- * memory: will keep track of previous values and will call any callback added
- * after the list has been fired right away with the latest "memorized"
- * values (like a Deferred)
- *
- * unique: will ensure a callback can only be added once (no duplicate in the list)
- *
- * stopOnFalse: interrupt callings when a callback returns false
- *
- */
-jQuery.Callbacks = function( options ) {
-
- // Convert options from String-formatted to Object-formatted if needed
- // (we check in cache first)
- options = typeof options === "string" ?
- ( optionsCache[ options ] || createOptions( options ) ) :
- jQuery.extend( {}, options );
-
- var // Flag to know if list is currently firing
- firing,
- // Last fire value (for non-forgettable lists)
- memory,
- // Flag to know if list was already fired
- fired,
- // End of the loop when firing
- firingLength,
- // Index of currently firing callback (modified by remove if needed)
- firingIndex,
- // First callback to fire (used internally by add and fireWith)
- firingStart,
- // Actual callback list
- list = [],
- // Stack of fire calls for repeatable lists
- stack = !options.once && [],
- // Fire callbacks
- fire = function( data ) {
- memory = options.memory && data;
- fired = true;
- firingIndex = firingStart || 0;
- firingStart = 0;
- firingLength = list.length;
- firing = true;
- for ( ; list && firingIndex < firingLength; firingIndex++ ) {
- if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
- memory = false; // To prevent further calls using add
- break;
- }
- }
- firing = false;
- if ( list ) {
- if ( stack ) {
- if ( stack.length ) {
- fire( stack.shift() );
- }
- } else if ( memory ) {
- list = [];
- } else {
- self.disable();
- }
- }
- },
- // Actual Callbacks object
- self = {
- // Add a callback or a collection of callbacks to the list
- add: function() {
- if ( list ) {
- // First, we save the current length
- var start = list.length;
- (function add( args ) {
- jQuery.each( args, function( _, arg ) {
- var type = jQuery.type( arg );
- if ( type === "function" ) {
- if ( !options.unique || !self.has( arg ) ) {
- list.push( arg );
- }
- } else if ( arg && arg.length && type !== "string" ) {
- // Inspect recursively
- add( arg );
- }
- });
- })( arguments );
- // Do we need to add the callbacks to the
- // current firing batch?
- if ( firing ) {
- firingLength = list.length;
- // With memory, if we're not firing then
- // we should call right away
- } else if ( memory ) {
- firingStart = start;
- fire( memory );
- }
- }
- return this;
- },
- // Remove a callback from the list
- remove: function() {
- if ( list ) {
- jQuery.each( arguments, function( _, arg ) {
- var index;
- while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
- list.splice( index, 1 );
- // Handle firing indexes
- if ( firing ) {
- if ( index <= firingLength ) {
- firingLength--;
- }
- if ( index <= firingIndex ) {
- firingIndex--;
- }
- }
- }
- });
- }
- return this;
- },
- // Check if a given callback is in the list.
- // If no argument is given, return whether or not list has callbacks attached.
- has: function( fn ) {
- return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
- },
- // Remove all callbacks from the list
- empty: function() {
- list = [];
- firingLength = 0;
- return this;
- },
- // Have the list do nothing anymore
- disable: function() {
- list = stack = memory = undefined;
- return this;
- },
- // Is it disabled?
- disabled: function() {
- return !list;
- },
- // Lock the list in its current state
- lock: function() {
- stack = undefined;
- if ( !memory ) {
- self.disable();
- }
- return this;
- },
- // Is it locked?
- locked: function() {
- return !stack;
- },
- // Call all callbacks with the given context and arguments
- fireWith: function( context, args ) {
- if ( list && ( !fired || stack ) ) {
- args = args || [];
- args = [ context, args.slice ? args.slice() : args ];
- if ( firing ) {
- stack.push( args );
- } else {
- fire( args );
- }
- }
- return this;
- },
- // Call all the callbacks with the given arguments
- fire: function() {
- self.fireWith( this, arguments );
- return this;
- },
- // To know if the callbacks have already been called at least once
- fired: function() {
- return !!fired;
- }
- };
-
- return self;
-};
-
-
-jQuery.extend({
-
- Deferred: function( func ) {
- var tuples = [
- // action, add listener, listener list, final state
- [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
- [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
- [ "notify", "progress", jQuery.Callbacks("memory") ]
- ],
- state = "pending",
- promise = {
- state: function() {
- return state;
- },
- always: function() {
- deferred.done( arguments ).fail( arguments );
- return this;
- },
- then: function( /* fnDone, fnFail, fnProgress */ ) {
- var fns = arguments;
- return jQuery.Deferred(function( newDefer ) {
- jQuery.each( tuples, function( i, tuple ) {
- var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
- // deferred[ done | fail | progress ] for forwarding actions to newDefer
- deferred[ tuple[1] ](function() {
- var returned = fn && fn.apply( this, arguments );
- if ( returned && jQuery.isFunction( returned.promise ) ) {
- returned.promise()
- .done( newDefer.resolve )
- .fail( newDefer.reject )
- .progress( newDefer.notify );
- } else {
- newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
- }
- });
- });
- fns = null;
- }).promise();
- },
- // Get a promise for this deferred
- // If obj is provided, the promise aspect is added to the object
- promise: function( obj ) {
- return obj != null ? jQuery.extend( obj, promise ) : promise;
- }
- },
- deferred = {};
-
- // Keep pipe for back-compat
- promise.pipe = promise.then;
-
- // Add list-specific methods
- jQuery.each( tuples, function( i, tuple ) {
- var list = tuple[ 2 ],
- stateString = tuple[ 3 ];
-
- // promise[ done | fail | progress ] = list.add
- promise[ tuple[1] ] = list.add;
-
- // Handle state
- if ( stateString ) {
- list.add(function() {
- // state = [ resolved | rejected ]
- state = stateString;
-
- // [ reject_list | resolve_list ].disable; progress_list.lock
- }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
- }
-
- // deferred[ resolve | reject | notify ]
- deferred[ tuple[0] ] = function() {
- deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
- return this;
- };
- deferred[ tuple[0] + "With" ] = list.fireWith;
- });
-
- // Make the deferred a promise
- promise.promise( deferred );
-
- // Call given func if any
- if ( func ) {
- func.call( deferred, deferred );
- }
-
- // All done!
- return deferred;
- },
-
- // Deferred helper
- when: function( subordinate /* , ..., subordinateN */ ) {
- var i = 0,
- resolveValues = slice.call( arguments ),
- length = resolveValues.length,
-
- // the count of uncompleted subordinates
- remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
-
- // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
- deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
-
- // Update function for both resolve and progress values
- updateFunc = function( i, contexts, values ) {
- return function( value ) {
- contexts[ i ] = this;
- values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
- if ( values === progressValues ) {
- deferred.notifyWith( contexts, values );
-
- } else if ( !(--remaining) ) {
- deferred.resolveWith( contexts, values );
- }
- };
- },
-
- progressValues, progressContexts, resolveContexts;
-
- // add listeners to Deferred subordinates; treat others as resolved
- if ( length > 1 ) {
- progressValues = new Array( length );
- progressContexts = new Array( length );
- resolveContexts = new Array( length );
- for ( ; i < length; i++ ) {
- if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
- resolveValues[ i ].promise()
- .done( updateFunc( i, resolveContexts, resolveValues ) )
- .fail( deferred.reject )
- .progress( updateFunc( i, progressContexts, progressValues ) );
- } else {
- --remaining;
- }
- }
- }
-
- // if we're not waiting on anything, resolve the master
- if ( !remaining ) {
- deferred.resolveWith( resolveContexts, resolveValues );
- }
-
- return deferred.promise();
- }
-});
-
-
-// The deferred used on DOM ready
-var readyList;
-
-jQuery.fn.ready = function( fn ) {
- // Add the callback
- jQuery.ready.promise().done( fn );
-
- return this;
-};
-
-jQuery.extend({
- // Is the DOM ready to be used? Set to true once it occurs.
- isReady: false,
-
- // A counter to track how many items to wait for before
- // the ready event fires. See #6781
- readyWait: 1,
-
- // Hold (or release) the ready event
- holdReady: function( hold ) {
- if ( hold ) {
- jQuery.readyWait++;
- } else {
- jQuery.ready( true );
- }
- },
-
- // Handle when the DOM is ready
- ready: function( wait ) {
-
- // Abort if there are pending holds or we're already ready
- if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
- return;
- }
-
- // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
- if ( !document.body ) {
- return setTimeout( jQuery.ready );
- }
-
- // Remember that the DOM is ready
- jQuery.isReady = true;
-
- // If a normal DOM Ready event fired, decrement, and wait if need be
- if ( wait !== true && --jQuery.readyWait > 0 ) {
- return;
- }
-
- // If there are functions bound, to execute
- readyList.resolveWith( document, [ jQuery ] );
-
- // Trigger any bound ready events
- if ( jQuery.fn.triggerHandler ) {
- jQuery( document ).triggerHandler( "ready" );
- jQuery( document ).off( "ready" );
- }
- }
-});
-
-/**
- * Clean-up method for dom ready events
- */
-function detach() {
- if ( document.addEventListener ) {
- document.removeEventListener( "DOMContentLoaded", completed, false );
- window.removeEventListener( "load", completed, false );
-
- } else {
- document.detachEvent( "onreadystatechange", completed );
- window.detachEvent( "onload", completed );
- }
-}
-
-/**
- * The ready event handler and self cleanup method
- */
-function completed() {
- // readyState === "complete" is good enough for us to call the dom ready in oldIE
- if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
- detach();
- jQuery.ready();
- }
-}
-
-jQuery.ready.promise = function( obj ) {
- if ( !readyList ) {
-
- readyList = jQuery.Deferred();
-
- // Catch cases where $(document).ready() is called after the browser event has already occurred.
- // we once tried to use readyState "interactive" here, but it caused issues like the one
- // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
- if ( document.readyState === "complete" ) {
- // Handle it asynchronously to allow scripts the opportunity to delay ready
- setTimeout( jQuery.ready );
-
- // Standards-based browsers support DOMContentLoaded
- } else if ( document.addEventListener ) {
- // Use the handy event callback
- document.addEventListener( "DOMContentLoaded", completed, false );
-
- // A fallback to window.onload, that will always work
- window.addEventListener( "load", completed, false );
-
- // If IE event model is used
- } else {
- // Ensure firing before onload, maybe late but safe also for iframes
- document.attachEvent( "onreadystatechange", completed );
-
- // A fallback to window.onload, that will always work
- window.attachEvent( "onload", completed );
-
- // If IE and not a frame
- // continually check to see if the document is ready
- var top = false;
-
- try {
- top = window.frameElement == null && document.documentElement;
- } catch(e) {}
-
- if ( top && top.doScroll ) {
- (function doScrollCheck() {
- if ( !jQuery.isReady ) {
-
- try {
- // Use the trick by Diego Perini
- // http://javascript.nwbox.com/IEContentLoaded/
- top.doScroll("left");
- } catch(e) {
- return setTimeout( doScrollCheck, 50 );
- }
-
- // detach all dom ready events
- detach();
-
- // and execute any waiting functions
- jQuery.ready();
- }
- })();
- }
- }
- }
- return readyList.promise( obj );
-};
-
-
-var strundefined = typeof undefined;
-
-
-
-// Support: IE<9
-// Iteration over object's inherited properties before its own
-var i;
-for ( i in jQuery( support ) ) {
- break;
-}
-support.ownLast = i !== "0";
-
-// Note: most support tests are defined in their respective modules.
-// false until the test is run
-support.inlineBlockNeedsLayout = false;
-
-// Execute ASAP in case we need to set body.style.zoom
-jQuery(function() {
- // Minified: var a,b,c,d
- var val, div, body, container;
-
- body = document.getElementsByTagName( "body" )[ 0 ];
- if ( !body || !body.style ) {
- // Return for frameset docs that don't have a body
- return;
- }
-
- // Setup
- div = document.createElement( "div" );
- container = document.createElement( "div" );
- container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
- body.appendChild( container ).appendChild( div );
-
- if ( typeof div.style.zoom !== strundefined ) {
- // Support: IE<8
- // Check if natively block-level elements act like inline-block
- // elements when setting their display to 'inline' and giving
- // them layout
- div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1";
-
- support.inlineBlockNeedsLayout = val = div.offsetWidth === 3;
- if ( val ) {
- // Prevent IE 6 from affecting layout for positioned elements #11048
- // Prevent IE from shrinking the body in IE 7 mode #12869
- // Support: IE<8
- body.style.zoom = 1;
- }
- }
-
- body.removeChild( container );
-});
-
-
-
-
-(function() {
- var div = document.createElement( "div" );
-
- // Execute the test only if not already executed in another module.
- if (support.deleteExpando == null) {
- // Support: IE<9
- support.deleteExpando = true;
- try {
- delete div.test;
- } catch( e ) {
- support.deleteExpando = false;
- }
- }
-
- // Null elements to avoid leaks in IE.
- div = null;
-})();
-
-
-/**
- * Determines whether an object can have data
- */
-jQuery.acceptData = function( elem ) {
- var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ],
- nodeType = +elem.nodeType || 1;
-
- // Do not set data on non-element DOM nodes because it will not be cleared (#8335).
- return nodeType !== 1 && nodeType !== 9 ?
- false :
-
- // Nodes accept data unless otherwise specified; rejection can be conditional
- !noData || noData !== true && elem.getAttribute("classid") === noData;
-};
-
-
-var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
- rmultiDash = /([A-Z])/g;
-
-function dataAttr( elem, key, data ) {
- // If nothing was found internally, try to fetch any
- // data from the HTML5 data-* attribute
- if ( data === undefined && elem.nodeType === 1 ) {
-
- var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
-
- data = elem.getAttribute( name );
-
- if ( typeof data === "string" ) {
- try {
- data = data === "true" ? true :
- data === "false" ? false :
- data === "null" ? null :
- // Only convert to a number if it doesn't change the string
- +data + "" === data ? +data :
- rbrace.test( data ) ? jQuery.parseJSON( data ) :
- data;
- } catch( e ) {}
-
- // Make sure we set the data so it isn't changed later
- jQuery.data( elem, key, data );
-
- } else {
- data = undefined;
- }
- }
-
- return data;
-}
-
-// checks a cache object for emptiness
-function isEmptyDataObject( obj ) {
- var name;
- for ( name in obj ) {
-
- // if the public data object is empty, the private is still empty
- if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) {
- continue;
- }
- if ( name !== "toJSON" ) {
- return false;
- }
- }
-
- return true;
-}
-
-function internalData( elem, name, data, pvt /* Internal Use Only */ ) {
- if ( !jQuery.acceptData( elem ) ) {
- return;
- }
-
- var ret, thisCache,
- internalKey = jQuery.expando,
-
- // We have to handle DOM nodes and JS objects differently because IE6-7
- // can't GC object references properly across the DOM-JS boundary
- isNode = elem.nodeType,
-
- // Only DOM nodes need the global jQuery cache; JS object data is
- // attached directly to the object so GC can occur automatically
- cache = isNode ? jQuery.cache : elem,
-
- // Only defining an ID for JS objects if its cache already exists allows
- // the code to shortcut on the same path as a DOM node with no cache
- id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;
-
- // Avoid doing any more work than we need to when trying to get data on an
- // object that has no data at all
- if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) {
- return;
- }
-
- if ( !id ) {
- // Only DOM nodes need a new unique ID for each element since their data
- // ends up in the global cache
- if ( isNode ) {
- id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;
- } else {
- id = internalKey;
- }
- }
-
- if ( !cache[ id ] ) {
- // Avoid exposing jQuery metadata on plain JS objects when the object
- // is serialized using JSON.stringify
- cache[ id ] = isNode ? {} : { toJSON: jQuery.noop };
- }
-
- // An object can be passed to jQuery.data instead of a key/value pair; this gets
- // shallow copied over onto the existing cache
- if ( typeof name === "object" || typeof name === "function" ) {
- if ( pvt ) {
- cache[ id ] = jQuery.extend( cache[ id ], name );
- } else {
- cache[ id ].data = jQuery.extend( cache[ id ].data, name );
- }
- }
-
- thisCache = cache[ id ];
-
- // jQuery data() is stored in a separate object inside the object's internal data
- // cache in order to avoid key collisions between internal data and user-defined
- // data.
- if ( !pvt ) {
- if ( !thisCache.data ) {
- thisCache.data = {};
- }
-
- thisCache = thisCache.data;
- }
-
- if ( data !== undefined ) {
- thisCache[ jQuery.camelCase( name ) ] = data;
- }
-
- // Check for both converted-to-camel and non-converted data property names
- // If a data property was specified
- if ( typeof name === "string" ) {
-
- // First Try to find as-is property data
- ret = thisCache[ name ];
-
- // Test for null|undefined property data
- if ( ret == null ) {
-
- // Try to find the camelCased property
- ret = thisCache[ jQuery.camelCase( name ) ];
- }
- } else {
- ret = thisCache;
- }
-
- return ret;
-}
-
-function internalRemoveData( elem, name, pvt ) {
- if ( !jQuery.acceptData( elem ) ) {
- return;
- }
-
- var thisCache, i,
- isNode = elem.nodeType,
-
- // See jQuery.data for more information
- cache = isNode ? jQuery.cache : elem,
- id = isNode ? elem[ jQuery.expando ] : jQuery.expando;
-
- // If there is already no cache entry for this object, there is no
- // purpose in continuing
- if ( !cache[ id ] ) {
- return;
- }
-
- if ( name ) {
-
- thisCache = pvt ? cache[ id ] : cache[ id ].data;
-
- if ( thisCache ) {
-
- // Support array or space separated string names for data keys
- if ( !jQuery.isArray( name ) ) {
-
- // try the string as a key before any manipulation
- if ( name in thisCache ) {
- name = [ name ];
- } else {
-
- // split the camel cased version by spaces unless a key with the spaces exists
- name = jQuery.camelCase( name );
- if ( name in thisCache ) {
- name = [ name ];
- } else {
- name = name.split(" ");
- }
- }
- } else {
- // If "name" is an array of keys...
- // When data is initially created, via ("key", "val") signature,
- // keys will be converted to camelCase.
- // Since there is no way to tell _how_ a key was added, remove
- // both plain key and camelCase key. #12786
- // This will only penalize the array argument path.
- name = name.concat( jQuery.map( name, jQuery.camelCase ) );
- }
-
- i = name.length;
- while ( i-- ) {
- delete thisCache[ name[i] ];
- }
-
- // If there is no data left in the cache, we want to continue
- // and let the cache object itself get destroyed
- if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {
- return;
- }
- }
- }
-
- // See jQuery.data for more information
- if ( !pvt ) {
- delete cache[ id ].data;
-
- // Don't destroy the parent cache unless the internal data object
- // had been the only thing left in it
- if ( !isEmptyDataObject( cache[ id ] ) ) {
- return;
- }
- }
-
- // Destroy the cache
- if ( isNode ) {
- jQuery.cleanData( [ elem ], true );
-
- // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)
- /* jshint eqeqeq: false */
- } else if ( support.deleteExpando || cache != cache.window ) {
- /* jshint eqeqeq: true */
- delete cache[ id ];
-
- // When all else fails, null
- } else {
- cache[ id ] = null;
- }
-}
-
-jQuery.extend({
- cache: {},
-
- // The following elements (space-suffixed to avoid Object.prototype collisions)
- // throw uncatchable exceptions if you attempt to set expando properties
- noData: {
- "applet ": true,
- "embed ": true,
- // ...but Flash objects (which have this classid) *can* handle expandos
- "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
- },
-
- hasData: function( elem ) {
- elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
- return !!elem && !isEmptyDataObject( elem );
- },
-
- data: function( elem, name, data ) {
- return internalData( elem, name, data );
- },
-
- removeData: function( elem, name ) {
- return internalRemoveData( elem, name );
- },
-
- // For internal use only.
- _data: function( elem, name, data ) {
- return internalData( elem, name, data, true );
- },
-
- _removeData: function( elem, name ) {
- return internalRemoveData( elem, name, true );
- }
-});
-
-jQuery.fn.extend({
- data: function( key, value ) {
- var i, name, data,
- elem = this[0],
- attrs = elem && elem.attributes;
-
- // Special expections of .data basically thwart jQuery.access,
- // so implement the relevant behavior ourselves
-
- // Gets all values
- if ( key === undefined ) {
- if ( this.length ) {
- data = jQuery.data( elem );
-
- if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) {
- i = attrs.length;
- while ( i-- ) {
-
- // Support: IE11+
- // The attrs elements can be null (#14894)
- if ( attrs[ i ] ) {
- name = attrs[ i ].name;
- if ( name.indexOf( "data-" ) === 0 ) {
- name = jQuery.camelCase( name.slice(5) );
- dataAttr( elem, name, data[ name ] );
- }
- }
- }
- jQuery._data( elem, "parsedAttrs", true );
- }
- }
-
- return data;
- }
-
- // Sets multiple values
- if ( typeof key === "object" ) {
- return this.each(function() {
- jQuery.data( this, key );
- });
- }
-
- return arguments.length > 1 ?
-
- // Sets one value
- this.each(function() {
- jQuery.data( this, key, value );
- }) :
-
- // Gets one value
- // Try to fetch any internally stored data first
- elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;
- },
-
- removeData: function( key ) {
- return this.each(function() {
- jQuery.removeData( this, key );
- });
- }
-});
-
-
-jQuery.extend({
- queue: function( elem, type, data ) {
- var queue;
-
- if ( elem ) {
- type = ( type || "fx" ) + "queue";
- queue = jQuery._data( elem, type );
-
- // Speed up dequeue by getting out quickly if this is just a lookup
- if ( data ) {
- if ( !queue || jQuery.isArray(data) ) {
- queue = jQuery._data( elem, type, jQuery.makeArray(data) );
- } else {
- queue.push( data );
- }
- }
- return queue || [];
- }
- },
-
- dequeue: function( elem, type ) {
- type = type || "fx";
-
- var queue = jQuery.queue( elem, type ),
- startLength = queue.length,
- fn = queue.shift(),
- hooks = jQuery._queueHooks( elem, type ),
- next = function() {
- jQuery.dequeue( elem, type );
- };
-
- // If the fx queue is dequeued, always remove the progress sentinel
- if ( fn === "inprogress" ) {
- fn = queue.shift();
- startLength--;
- }
-
- if ( fn ) {
-
- // Add a progress sentinel to prevent the fx queue from being
- // automatically dequeued
- if ( type === "fx" ) {
- queue.unshift( "inprogress" );
- }
-
- // clear up the last queue stop function
- delete hooks.stop;
- fn.call( elem, next, hooks );
- }
-
- if ( !startLength && hooks ) {
- hooks.empty.fire();
- }
- },
-
- // not intended for public consumption - generates a queueHooks object, or returns the current one
- _queueHooks: function( elem, type ) {
- var key = type + "queueHooks";
- return jQuery._data( elem, key ) || jQuery._data( elem, key, {
- empty: jQuery.Callbacks("once memory").add(function() {
- jQuery._removeData( elem, type + "queue" );
- jQuery._removeData( elem, key );
- })
- });
- }
-});
-
-jQuery.fn.extend({
- queue: function( type, data ) {
- var setter = 2;
-
- if ( typeof type !== "string" ) {
- data = type;
- type = "fx";
- setter--;
- }
-
- if ( arguments.length < setter ) {
- return jQuery.queue( this[0], type );
- }
-
- return data === undefined ?
- this :
- this.each(function() {
- var queue = jQuery.queue( this, type, data );
-
- // ensure a hooks for this queue
- jQuery._queueHooks( this, type );
-
- if ( type === "fx" && queue[0] !== "inprogress" ) {
- jQuery.dequeue( this, type );
- }
- });
- },
- dequeue: function( type ) {
- return this.each(function() {
- jQuery.dequeue( this, type );
- });
- },
- clearQueue: function( type ) {
- return this.queue( type || "fx", [] );
- },
- // Get a promise resolved when queues of a certain type
- // are emptied (fx is the type by default)
- promise: function( type, obj ) {
- var tmp,
- count = 1,
- defer = jQuery.Deferred(),
- elements = this,
- i = this.length,
- resolve = function() {
- if ( !( --count ) ) {
- defer.resolveWith( elements, [ elements ] );
- }
- };
-
- if ( typeof type !== "string" ) {
- obj = type;
- type = undefined;
- }
- type = type || "fx";
-
- while ( i-- ) {
- tmp = jQuery._data( elements[ i ], type + "queueHooks" );
- if ( tmp && tmp.empty ) {
- count++;
- tmp.empty.add( resolve );
- }
- }
- resolve();
- return defer.promise( obj );
- }
-});
-var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source;
-
-var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
-
-var isHidden = function( elem, el ) {
- // isHidden might be called from jQuery#filter function;
- // in that case, element will be second argument
- elem = el || elem;
- return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
- };
-
-
-
-// Multifunctional method to get and set values of a collection
-// The value/s can optionally be executed if it's a function
-var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
- var i = 0,
- length = elems.length,
- bulk = key == null;
-
- // Sets many values
- if ( jQuery.type( key ) === "object" ) {
- chainable = true;
- for ( i in key ) {
- jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
- }
-
- // Sets one value
- } else if ( value !== undefined ) {
- chainable = true;
-
- if ( !jQuery.isFunction( value ) ) {
- raw = true;
- }
-
- if ( bulk ) {
- // Bulk operations run against the entire set
- if ( raw ) {
- fn.call( elems, value );
- fn = null;
-
- // ...except when executing function values
- } else {
- bulk = fn;
- fn = function( elem, key, value ) {
- return bulk.call( jQuery( elem ), value );
- };
- }
- }
-
- if ( fn ) {
- for ( ; i < length; i++ ) {
- fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
- }
- }
- }
-
- return chainable ?
- elems :
-
- // Gets
- bulk ?
- fn.call( elems ) :
- length ? fn( elems[0], key ) : emptyGet;
-};
-var rcheckableType = (/^(?:checkbox|radio)$/i);
-
-
-
-(function() {
- // Minified: var a,b,c
- var input = document.createElement( "input" ),
- div = document.createElement( "div" ),
- fragment = document.createDocumentFragment();
-
- // Setup
- div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
-
- // IE strips leading whitespace when .innerHTML is used
- support.leadingWhitespace = div.firstChild.nodeType === 3;
-
- // Make sure that tbody elements aren't automatically inserted
- // IE will insert them into empty tables
- support.tbody = !div.getElementsByTagName( "tbody" ).length;
-
- // Make sure that link elements get serialized correctly by innerHTML
- // This requires a wrapper element in IE
- support.htmlSerialize = !!div.getElementsByTagName( "link" ).length;
-
- // Makes sure cloning an html5 element does not cause problems
- // Where outerHTML is undefined, this still works
- support.html5Clone =
- document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>";
-
- // Check if a disconnected checkbox will retain its checked
- // value of true after appended to the DOM (IE6/7)
- input.type = "checkbox";
- input.checked = true;
- fragment.appendChild( input );
- support.appendChecked = input.checked;
-
- // Make sure textarea (and checkbox) defaultValue is properly cloned
- // Support: IE6-IE11+
- div.innerHTML = "<textarea>x</textarea>";
- support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
-
- // #11217 - WebKit loses check when the name is after the checked attribute
- fragment.appendChild( div );
- div.innerHTML = "<input type='radio' checked='checked' name='t'/>";
-
- // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
- // old WebKit doesn't clone checked state correctly in fragments
- support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
-
- // Support: IE<9
- // Opera does not clone events (and typeof div.attachEvent === undefined).
- // IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
- support.noCloneEvent = true;
- if ( div.attachEvent ) {
- div.attachEvent( "onclick", function() {
- support.noCloneEvent = false;
- });
-
- div.cloneNode( true ).click();
- }
-
- // Execute the test only if not already executed in another module.
- if (support.deleteExpando == null) {
- // Support: IE<9
- support.deleteExpando = true;
- try {
- delete div.test;
- } catch( e ) {
- support.deleteExpando = false;
- }
- }
-})();
-
-
-(function() {
- var i, eventName,
- div = document.createElement( "div" );
-
- // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)
- for ( i in { submit: true, change: true, focusin: true }) {
- eventName = "on" + i;
-
- if ( !(support[ i + "Bubbles" ] = eventName in window) ) {
- // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
- div.setAttribute( eventName, "t" );
- support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false;
- }
- }
-
- // Null elements to avoid leaks in IE.
- div = null;
-})();
-
-
-var rformElems = /^(?:input|select|textarea)$/i,
- rkeyEvent = /^key/,
- rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,
- rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
- rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
-
-function returnTrue() {
- return true;
-}
-
-function returnFalse() {
- return false;
-}
-
-function safeActiveElement() {
- try {
- return document.activeElement;
- } catch ( err ) { }
-}
-
-/*
- * Helper functions for managing events -- not part of the public interface.
- * Props to Dean Edwards' addEvent library for many of the ideas.
- */
-jQuery.event = {
-
- global: {},
-
- add: function( elem, types, handler, data, selector ) {
- var tmp, events, t, handleObjIn,
- special, eventHandle, handleObj,
- handlers, type, namespaces, origType,
- elemData = jQuery._data( elem );
-
- // Don't attach events to noData or text/comment nodes (but allow plain objects)
- if ( !elemData ) {
- return;
- }
-
- // Caller can pass in an object of custom data in lieu of the handler
- if ( handler.handler ) {
- handleObjIn = handler;
- handler = handleObjIn.handler;
- selector = handleObjIn.selector;
- }
-
- // Make sure that the handler has a unique ID, used to find/remove it later
- if ( !handler.guid ) {
- handler.guid = jQuery.guid++;
- }
-
- // Init the element's event structure and main handler, if this is the first
- if ( !(events = elemData.events) ) {
- events = elemData.events = {};
- }
- if ( !(eventHandle = elemData.handle) ) {
- eventHandle = elemData.handle = function( e ) {
- // Discard the second event of a jQuery.event.trigger() and
- // when an event is called after a page has unloaded
- return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?
- jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
- undefined;
- };
- // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
- eventHandle.elem = elem;
- }
-
- // Handle multiple events separated by a space
- types = ( types || "" ).match( rnotwhite ) || [ "" ];
- t = types.length;
- while ( t-- ) {
- tmp = rtypenamespace.exec( types[t] ) || [];
- type = origType = tmp[1];
- namespaces = ( tmp[2] || "" ).split( "." ).sort();
-
- // There *must* be a type, no attaching namespace-only handlers
- if ( !type ) {
- continue;
- }
-
- // If event changes its type, use the special event handlers for the changed type
- special = jQuery.event.special[ type ] || {};
-
- // If selector defined, determine special event api type, otherwise given type
- type = ( selector ? special.delegateType : special.bindType ) || type;
-
- // Update special based on newly reset type
- special = jQuery.event.special[ type ] || {};
-
- // handleObj is passed to all event handlers
- handleObj = jQuery.extend({
- type: type,
- origType: origType,
- data: data,
- handler: handler,
- guid: handler.guid,
- selector: selector,
- needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
- namespace: namespaces.join(".")
- }, handleObjIn );
-
- // Init the event handler queue if we're the first
- if ( !(handlers = events[ type ]) ) {
- handlers = events[ type ] = [];
- handlers.delegateCount = 0;
-
- // Only use addEventListener/attachEvent if the special events handler returns false
- if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
- // Bind the global event handler to the element
- if ( elem.addEventListener ) {
- elem.addEventListener( type, eventHandle, false );
-
- } else if ( elem.attachEvent ) {
- elem.attachEvent( "on" + type, eventHandle );
- }
- }
- }
-
- if ( special.add ) {
- special.add.call( elem, handleObj );
-
- if ( !handleObj.handler.guid ) {
- handleObj.handler.guid = handler.guid;
- }
- }
-
- // Add to the element's handler list, delegates in front
- if ( selector ) {
- handlers.splice( handlers.delegateCount++, 0, handleObj );
- } else {
- handlers.push( handleObj );
- }
-
- // Keep track of which events have ever been used, for event optimization
- jQuery.event.global[ type ] = true;
- }
-
- // Nullify elem to prevent memory leaks in IE
- elem = null;
- },
-
- // Detach an event or set of events from an element
- remove: function( elem, types, handler, selector, mappedTypes ) {
- var j, handleObj, tmp,
- origCount, t, events,
- special, handlers, type,
- namespaces, origType,
- elemData = jQuery.hasData( elem ) && jQuery._data( elem );
-
- if ( !elemData || !(events = elemData.events) ) {
- return;
- }
-
- // Once for each type.namespace in types; type may be omitted
- types = ( types || "" ).match( rnotwhite ) || [ "" ];
- t = types.length;
- while ( t-- ) {
- tmp = rtypenamespace.exec( types[t] ) || [];
- type = origType = tmp[1];
- namespaces = ( tmp[2] || "" ).split( "." ).sort();
-
- // Unbind all events (on this namespace, if provided) for the element
- if ( !type ) {
- for ( type in events ) {
- jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
- }
- continue;
- }
-
- special = jQuery.event.special[ type ] || {};
- type = ( selector ? special.delegateType : special.bindType ) || type;
- handlers = events[ type ] || [];
- tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
-
- // Remove matching events
- origCount = j = handlers.length;
- while ( j-- ) {
- handleObj = handlers[ j ];
-
- if ( ( mappedTypes || origType === handleObj.origType ) &&
- ( !handler || handler.guid === handleObj.guid ) &&
- ( !tmp || tmp.test( handleObj.namespace ) ) &&
- ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
- handlers.splice( j, 1 );
-
- if ( handleObj.selector ) {
- handlers.delegateCount--;
- }
- if ( special.remove ) {
- special.remove.call( elem, handleObj );
- }
- }
- }
-
- // Remove generic event handler if we removed something and no more handlers exist
- // (avoids potential for endless recursion during removal of special event handlers)
- if ( origCount && !handlers.length ) {
- if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
- jQuery.removeEvent( elem, type, elemData.handle );
- }
-
- delete events[ type ];
- }
- }
-
- // Remove the expando if it's no longer used
- if ( jQuery.isEmptyObject( events ) ) {
- delete elemData.handle;
-
- // removeData also checks for emptiness and clears the expando if empty
- // so use it instead of delete
- jQuery._removeData( elem, "events" );
- }
- },
-
- trigger: function( event, data, elem, onlyHandlers ) {
- var handle, ontype, cur,
- bubbleType, special, tmp, i,
- eventPath = [ elem || document ],
- type = hasOwn.call( event, "type" ) ? event.type : event,
- namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
-
- cur = tmp = elem = elem || document;
-
- // Don't do events on text and comment nodes
- if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
- return;
- }
-
- // focus/blur morphs to focusin/out; ensure we're not firing them right now
- if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
- return;
- }
-
- if ( type.indexOf(".") >= 0 ) {
- // Namespaced trigger; create a regexp to match event type in handle()
- namespaces = type.split(".");
- type = namespaces.shift();
- namespaces.sort();
- }
- ontype = type.indexOf(":") < 0 && "on" + type;
-
- // Caller can pass in a jQuery.Event object, Object, or just an event type string
- event = event[ jQuery.expando ] ?
- event :
- new jQuery.Event( type, typeof event === "object" && event );
-
- // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
- event.isTrigger = onlyHandlers ? 2 : 3;
- event.namespace = namespaces.join(".");
- event.namespace_re = event.namespace ?
- new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
- null;
-
- // Clean up the event in case it is being reused
- event.result = undefined;
- if ( !event.target ) {
- event.target = elem;
- }
-
- // Clone any incoming data and prepend the event, creating the handler arg list
- data = data == null ?
- [ event ] :
- jQuery.makeArray( data, [ event ] );
-
- // Allow special events to draw outside the lines
- special = jQuery.event.special[ type ] || {};
- if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
- return;
- }
-
- // Determine event propagation path in advance, per W3C events spec (#9951)
- // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
- if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
-
- bubbleType = special.delegateType || type;
- if ( !rfocusMorph.test( bubbleType + type ) ) {
- cur = cur.parentNode;
- }
- for ( ; cur; cur = cur.parentNode ) {
- eventPath.push( cur );
- tmp = cur;
- }
-
- // Only add window if we got to document (e.g., not plain obj or detached DOM)
- if ( tmp === (elem.ownerDocument || document) ) {
- eventPath.push( tmp.defaultView || tmp.parentWindow || window );
- }
- }
-
- // Fire handlers on the event path
- i = 0;
- while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
-
- event.type = i > 1 ?
- bubbleType :
- special.bindType || type;
-
- // jQuery handler
- handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
- if ( handle ) {
- handle.apply( cur, data );
- }
-
- // Native handler
- handle = ontype && cur[ ontype ];
- if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
- event.result = handle.apply( cur, data );
- if ( event.result === false ) {
- event.preventDefault();
- }
- }
- }
- event.type = type;
-
- // If nobody prevented the default action, do it now
- if ( !onlyHandlers && !event.isDefaultPrevented() ) {
-
- if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
- jQuery.acceptData( elem ) ) {
-
- // Call a native DOM method on the target with the same name name as the event.
- // Can't use an .isFunction() check here because IE6/7 fails that test.
- // Don't do default actions on window, that's where global variables be (#6170)
- if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
-
- // Don't re-trigger an onFOO event when we call its FOO() method
- tmp = elem[ ontype ];
-
- if ( tmp ) {
- elem[ ontype ] = null;
- }
-
- // Prevent re-triggering of the same event, since we already bubbled it above
- jQuery.event.triggered = type;
- try {
- elem[ type ]();
- } catch ( e ) {
- // IE<9 dies on focus/blur to hidden element (#1486,#12518)
- // only reproducible on winXP IE8 native, not IE9 in IE8 mode
- }
- jQuery.event.triggered = undefined;
-
- if ( tmp ) {
- elem[ ontype ] = tmp;
- }
- }
- }
- }
-
- return event.result;
- },
-
- dispatch: function( event ) {
-
- // Make a writable jQuery.Event from the native event object
- event = jQuery.event.fix( event );
-
- var i, ret, handleObj, matched, j,
- handlerQueue = [],
- args = slice.call( arguments ),
- handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
- special = jQuery.event.special[ event.type ] || {};
-
- // Use the fix-ed jQuery.Event rather than the (read-only) native event
- args[0] = event;
- event.delegateTarget = this;
-
- // Call the preDispatch hook for the mapped type, and let it bail if desired
- if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
- return;
- }
-
- // Determine handlers
- handlerQueue = jQuery.event.handlers.call( this, event, handlers );
-
- // Run delegates first; they may want to stop propagation beneath us
- i = 0;
- while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
- event.currentTarget = matched.elem;
-
- j = 0;
- while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
-
- // Triggered event must either 1) have no namespace, or
- // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
- if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
-
- event.handleObj = handleObj;
- event.data = handleObj.data;
-
- ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
- .apply( matched.elem, args );
-
- if ( ret !== undefined ) {
- if ( (event.result = ret) === false ) {
- event.preventDefault();
- event.stopPropagation();
- }
- }
- }
- }
- }
-
- // Call the postDispatch hook for the mapped type
- if ( special.postDispatch ) {
- special.postDispatch.call( this, event );
- }
-
- return event.result;
- },
-
- handlers: function( event, handlers ) {
- var sel, handleObj, matches, i,
- handlerQueue = [],
- delegateCount = handlers.delegateCount,
- cur = event.target;
-
- // Find delegate handlers
- // Black-hole SVG <use> instance trees (#13180)
- // Avoid non-left-click bubbling in Firefox (#3861)
- if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
-
- /* jshint eqeqeq: false */
- for ( ; cur != this; cur = cur.parentNode || this ) {
- /* jshint eqeqeq: true */
-
- // Don't check non-elements (#13208)
- // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
- if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
- matches = [];
- for ( i = 0; i < delegateCount; i++ ) {
- handleObj = handlers[ i ];
-
- // Don't conflict with Object.prototype properties (#13203)
- sel = handleObj.selector + " ";
-
- if ( matches[ sel ] === undefined ) {
- matches[ sel ] = handleObj.needsContext ?
- jQuery( sel, this ).index( cur ) >= 0 :
- jQuery.find( sel, this, null, [ cur ] ).length;
- }
- if ( matches[ sel ] ) {
- matches.push( handleObj );
- }
- }
- if ( matches.length ) {
- handlerQueue.push({ elem: cur, handlers: matches });
- }
- }
- }
- }
-
- // Add the remaining (directly-bound) handlers
- if ( delegateCount < handlers.length ) {
- handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
- }
-
- return handlerQueue;
- },
-
- fix: function( event ) {
- if ( event[ jQuery.expando ] ) {
- return event;
- }
-
- // Create a writable copy of the event object and normalize some properties
- var i, prop, copy,
- type = event.type,
- originalEvent = event,
- fixHook = this.fixHooks[ type ];
-
- if ( !fixHook ) {
- this.fixHooks[ type ] = fixHook =
- rmouseEvent.test( type ) ? this.mouseHooks :
- rkeyEvent.test( type ) ? this.keyHooks :
- {};
- }
- copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
-
- event = new jQuery.Event( originalEvent );
-
- i = copy.length;
- while ( i-- ) {
- prop = copy[ i ];
- event[ prop ] = originalEvent[ prop ];
- }
-
- // Support: IE<9
- // Fix target property (#1925)
- if ( !event.target ) {
- event.target = originalEvent.srcElement || document;
- }
-
- // Support: Chrome 23+, Safari?
- // Target should not be a text node (#504, #13143)
- if ( event.target.nodeType === 3 ) {
- event.target = event.target.parentNode;
- }
-
- // Support: IE<9
- // For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
- event.metaKey = !!event.metaKey;
-
- return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
- },
-
- // Includes some event props shared by KeyEvent and MouseEvent
- props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
-
- fixHooks: {},
-
- keyHooks: {
- props: "char charCode key keyCode".split(" "),
- filter: function( event, original ) {
-
- // Add which for key events
- if ( event.which == null ) {
- event.which = original.charCode != null ? original.charCode : original.keyCode;
- }
-
- return event;
- }
- },
-
- mouseHooks: {
- props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
- filter: function( event, original ) {
- var body, eventDoc, doc,
- button = original.button,
- fromElement = original.fromElement;
-
- // Calculate pageX/Y if missing and clientX/Y available
- if ( event.pageX == null && original.clientX != null ) {
- eventDoc = event.target.ownerDocument || document;
- doc = eventDoc.documentElement;
- body = eventDoc.body;
-
- event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
- event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
- }
-
- // Add relatedTarget, if necessary
- if ( !event.relatedTarget && fromElement ) {
- event.relatedTarget = fromElement === event.target ? original.toElement : fromElement;
- }
-
- // Add which for click: 1 === left; 2 === middle; 3 === right
- // Note: button is not normalized, so don't use it
- if ( !event.which && button !== undefined ) {
- event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
- }
-
- return event;
- }
- },
-
- special: {
- load: {
- // Prevent triggered image.load events from bubbling to window.load
- noBubble: true
- },
- focus: {
- // Fire native event if possible so blur/focus sequence is correct
- trigger: function() {
- if ( this !== safeActiveElement() && this.focus ) {
- try {
- this.focus();
- return false;
- } catch ( e ) {
- // Support: IE<9
- // If we error on focus to hidden element (#1486, #12518),
- // let .trigger() run the handlers
- }
- }
- },
- delegateType: "focusin"
- },
- blur: {
- trigger: function() {
- if ( this === safeActiveElement() && this.blur ) {
- this.blur();
- return false;
- }
- },
- delegateType: "focusout"
- },
- click: {
- // For checkbox, fire native event so checked state will be right
- trigger: function() {
- if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
- this.click();
- return false;
- }
- },
-
- // For cross-browser consistency, don't fire native .click() on links
- _default: function( event ) {
- return jQuery.nodeName( event.target, "a" );
- }
- },
-
- beforeunload: {
- postDispatch: function( event ) {
-
- // Support: Firefox 20+
- // Firefox doesn't alert if the returnValue field is not set.
- if ( event.result !== undefined && event.originalEvent ) {
- event.originalEvent.returnValue = event.result;
- }
- }
- }
- },
-
- simulate: function( type, elem, event, bubble ) {
- // Piggyback on a donor event to simulate a different one.
- // Fake originalEvent to avoid donor's stopPropagation, but if the
- // simulated event prevents default then we do the same on the donor.
- var e = jQuery.extend(
- new jQuery.Event(),
- event,
- {
- type: type,
- isSimulated: true,
- originalEvent: {}
- }
- );
- if ( bubble ) {
- jQuery.event.trigger( e, null, elem );
- } else {
- jQuery.event.dispatch.call( elem, e );
- }
- if ( e.isDefaultPrevented() ) {
- event.preventDefault();
- }
- }
-};
-
-jQuery.removeEvent = document.removeEventListener ?
- function( elem, type, handle ) {
- if ( elem.removeEventListener ) {
- elem.removeEventListener( type, handle, false );
- }
- } :
- function( elem, type, handle ) {
- var name = "on" + type;
-
- if ( elem.detachEvent ) {
-
- // #8545, #7054, preventing memory leaks for custom events in IE6-8
- // detachEvent needed property on element, by name of that event, to properly expose it to GC
- if ( typeof elem[ name ] === strundefined ) {
- elem[ name ] = null;
- }
-
- elem.detachEvent( name, handle );
- }
- };
-
-jQuery.Event = function( src, props ) {
- // Allow instantiation without the 'new' keyword
- if ( !(this instanceof jQuery.Event) ) {
- return new jQuery.Event( src, props );
- }
-
- // Event object
- if ( src && src.type ) {
- this.originalEvent = src;
- this.type = src.type;
-
- // Events bubbling up the document may have been marked as prevented
- // by a handler lower down the tree; reflect the correct value.
- this.isDefaultPrevented = src.defaultPrevented ||
- src.defaultPrevented === undefined &&
- // Support: IE < 9, Android < 4.0
- src.returnValue === false ?
- returnTrue :
- returnFalse;
-
- // Event type
- } else {
- this.type = src;
- }
-
- // Put explicitly provided properties onto the event object
- if ( props ) {
- jQuery.extend( this, props );
- }
-
- // Create a timestamp if incoming event doesn't have one
- this.timeStamp = src && src.timeStamp || jQuery.now();
-
- // Mark it as fixed
- this[ jQuery.expando ] = true;
-};
-
-// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
-// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
-jQuery.Event.prototype = {
- isDefaultPrevented: returnFalse,
- isPropagationStopped: returnFalse,
- isImmediatePropagationStopped: returnFalse,
-
- preventDefault: function() {
- var e = this.originalEvent;
-
- this.isDefaultPrevented = returnTrue;
- if ( !e ) {
- return;
- }
-
- // If preventDefault exists, run it on the original event
- if ( e.preventDefault ) {
- e.preventDefault();
-
- // Support: IE
- // Otherwise set the returnValue property of the original event to false
- } else {
- e.returnValue = false;
- }
- },
- stopPropagation: function() {
- var e = this.originalEvent;
-
- this.isPropagationStopped = returnTrue;
- if ( !e ) {
- return;
- }
- // If stopPropagation exists, run it on the original event
- if ( e.stopPropagation ) {
- e.stopPropagation();
- }
-
- // Support: IE
- // Set the cancelBubble property of the original event to true
- e.cancelBubble = true;
- },
- stopImmediatePropagation: function() {
- var e = this.originalEvent;
-
- this.isImmediatePropagationStopped = returnTrue;
-
- if ( e && e.stopImmediatePropagation ) {
- e.stopImmediatePropagation();
- }
-
- this.stopPropagation();
- }
-};
-
-// Create mouseenter/leave events using mouseover/out and event-time checks
-jQuery.each({
- mouseenter: "mouseover",
- mouseleave: "mouseout",
- pointerenter: "pointerover",
- pointerleave: "pointerout"
-}, function( orig, fix ) {
- jQuery.event.special[ orig ] = {
- delegateType: fix,
- bindType: fix,
-
- handle: function( event ) {
- var ret,
- target = this,
- related = event.relatedTarget,
- handleObj = event.handleObj;
-
- // For mousenter/leave call the handler if related is outside the target.
- // NB: No relatedTarget if the mouse left/entered the browser window
- if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
- event.type = handleObj.origType;
- ret = handleObj.handler.apply( this, arguments );
- event.type = fix;
- }
- return ret;
- }
- };
-});
-
-// IE submit delegation
-if ( !support.submitBubbles ) {
-
- jQuery.event.special.submit = {
- setup: function() {
- // Only need this for delegated form submit events
- if ( jQuery.nodeName( this, "form" ) ) {
- return false;
- }
-
- // Lazy-add a submit handler when a descendant form may potentially be submitted
- jQuery.event.add( this, "click._submit keypress._submit", function( e ) {
- // Node name check avoids a VML-related crash in IE (#9807)
- var elem = e.target,
- form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined;
- if ( form && !jQuery._data( form, "submitBubbles" ) ) {
- jQuery.event.add( form, "submit._submit", function( event ) {
- event._submit_bubble = true;
- });
- jQuery._data( form, "submitBubbles", true );
- }
- });
- // return undefined since we don't need an event listener
- },
-
- postDispatch: function( event ) {
- // If form was submitted by the user, bubble the event up the tree
- if ( event._submit_bubble ) {
- delete event._submit_bubble;
- if ( this.parentNode && !event.isTrigger ) {
- jQuery.event.simulate( "submit", this.parentNode, event, true );
- }
- }
- },
-
- teardown: function() {
- // Only need this for delegated form submit events
- if ( jQuery.nodeName( this, "form" ) ) {
- return false;
- }
-
- // Remove delegated handlers; cleanData eventually reaps submit handlers attached above
- jQuery.event.remove( this, "._submit" );
- }
- };
-}
-
-// IE change delegation and checkbox/radio fix
-if ( !support.changeBubbles ) {
-
- jQuery.event.special.change = {
-
- setup: function() {
-
- if ( rformElems.test( this.nodeName ) ) {
- // IE doesn't fire change on a check/radio until blur; trigger it on click
- // after a propertychange. Eat the blur-change in special.change.handle.
- // This still fires onchange a second time for check/radio after blur.
- if ( this.type === "checkbox" || this.type === "radio" ) {
- jQuery.event.add( this, "propertychange._change", function( event ) {
- if ( event.originalEvent.propertyName === "checked" ) {
- this._just_changed = true;
- }
- });
- jQuery.event.add( this, "click._change", function( event ) {
- if ( this._just_changed && !event.isTrigger ) {
- this._just_changed = false;
- }
- // Allow triggered, simulated change events (#11500)
- jQuery.event.simulate( "change", this, event, true );
- });
- }
- return false;
- }
- // Delegated event; lazy-add a change handler on descendant inputs
- jQuery.event.add( this, "beforeactivate._change", function( e ) {
- var elem = e.target;
-
- if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) {
- jQuery.event.add( elem, "change._change", function( event ) {
- if ( this.parentNode && !event.isSimulated && !event.isTrigger ) {
- jQuery.event.simulate( "change", this.parentNode, event, true );
- }
- });
- jQuery._data( elem, "changeBubbles", true );
- }
- });
- },
-
- handle: function( event ) {
- var elem = event.target;
-
- // Swallow native change events from checkbox/radio, we already triggered them above
- if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) {
- return event.handleObj.handler.apply( this, arguments );
- }
- },
-
- teardown: function() {
- jQuery.event.remove( this, "._change" );
-
- return !rformElems.test( this.nodeName );
- }
- };
-}
-
-// Create "bubbling" focus and blur events
-if ( !support.focusinBubbles ) {
- jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
-
- // Attach a single capturing handler on the document while someone wants focusin/focusout
- var handler = function( event ) {
- jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
- };
-
- jQuery.event.special[ fix ] = {
- setup: function() {
- var doc = this.ownerDocument || this,
- attaches = jQuery._data( doc, fix );
-
- if ( !attaches ) {
- doc.addEventListener( orig, handler, true );
- }
- jQuery._data( doc, fix, ( attaches || 0 ) + 1 );
- },
- teardown: function() {
- var doc = this.ownerDocument || this,
- attaches = jQuery._data( doc, fix ) - 1;
-
- if ( !attaches ) {
- doc.removeEventListener( orig, handler, true );
- jQuery._removeData( doc, fix );
- } else {
- jQuery._data( doc, fix, attaches );
- }
- }
- };
- });
-}
-
-jQuery.fn.extend({
-
- on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
- var type, origFn;
-
- // Types can be a map of types/handlers
- if ( typeof types === "object" ) {
- // ( types-Object, selector, data )
- if ( typeof selector !== "string" ) {
- // ( types-Object, data )
- data = data || selector;
- selector = undefined;
- }
- for ( type in types ) {
- this.on( type, selector, data, types[ type ], one );
- }
- return this;
- }
-
- if ( data == null && fn == null ) {
- // ( types, fn )
- fn = selector;
- data = selector = undefined;
- } else if ( fn == null ) {
- if ( typeof selector === "string" ) {
- // ( types, selector, fn )
- fn = data;
- data = undefined;
- } else {
- // ( types, data, fn )
- fn = data;
- data = selector;
- selector = undefined;
- }
- }
- if ( fn === false ) {
- fn = returnFalse;
- } else if ( !fn ) {
- return this;
- }
-
- if ( one === 1 ) {
- origFn = fn;
- fn = function( event ) {
- // Can use an empty set, since event contains the info
- jQuery().off( event );
- return origFn.apply( this, arguments );
- };
- // Use same guid so caller can remove using origFn
- fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
- }
- return this.each( function() {
- jQuery.event.add( this, types, fn, data, selector );
- });
- },
- one: function( types, selector, data, fn ) {
- return this.on( types, selector, data, fn, 1 );
- },
- off: function( types, selector, fn ) {
- var handleObj, type;
- if ( types && types.preventDefault && types.handleObj ) {
- // ( event ) dispatched jQuery.Event
- handleObj = types.handleObj;
- jQuery( types.delegateTarget ).off(
- handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
- handleObj.selector,
- handleObj.handler
- );
- return this;
- }
- if ( typeof types === "object" ) {
- // ( types-object [, selector] )
- for ( type in types ) {
- this.off( type, selector, types[ type ] );
- }
- return this;
- }
- if ( selector === false || typeof selector === "function" ) {
- // ( types [, fn] )
- fn = selector;
- selector = undefined;
- }
- if ( fn === false ) {
- fn = returnFalse;
- }
- return this.each(function() {
- jQuery.event.remove( this, types, fn, selector );
- });
- },
-
- trigger: function( type, data ) {
- return this.each(function() {
- jQuery.event.trigger( type, data, this );
- });
- },
- triggerHandler: function( type, data ) {
- var elem = this[0];
- if ( elem ) {
- return jQuery.event.trigger( type, data, elem, true );
- }
- }
-});
-
-
-function createSafeFragment( document ) {
- var list = nodeNames.split( "|" ),
- safeFrag = document.createDocumentFragment();
-
- if ( safeFrag.createElement ) {
- while ( list.length ) {
- safeFrag.createElement(
- list.pop()
- );
- }
- }
- return safeFrag;
-}
-
-var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" +
- "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",
- rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g,
- rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
- rleadingWhitespace = /^\s+/,
- rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
- rtagName = /<([\w:]+)/,
- rtbody = /<tbody/i,
- rhtml = /<|&#?\w+;/,
- rnoInnerhtml = /<(?:script|style|link)/i,
- // checked="checked" or checked
- rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
- rscriptType = /^$|\/(?:java|ecma)script/i,
- rscriptTypeMasked = /^true\/(.*)/,
- rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
-
- // We have to close these tags to support XHTML (#13200)
- wrapMap = {
- option: [ 1, "<select multiple='multiple'>", "</select>" ],
- legend: [ 1, "<fieldset>", "</fieldset>" ],
- area: [ 1, "<map>", "</map>" ],
- param: [ 1, "<object>", "</object>" ],
- thead: [ 1, "<table>", "</table>" ],
- tr: [ 2, "<table><tbody>", "</tbody></table>" ],
- col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
- td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
-
- // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
- // unless wrapped in a div with non-breaking characters in front of it.
- _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ]
- },
- safeFragment = createSafeFragment( document ),
- fragmentDiv = safeFragment.appendChild( document.createElement("div") );
-
-wrapMap.optgroup = wrapMap.option;
-wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
-wrapMap.th = wrapMap.td;
-
-function getAll( context, tag ) {
- var elems, elem,
- i = 0,
- found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) :
- typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) :
- undefined;
-
- if ( !found ) {
- for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
- if ( !tag || jQuery.nodeName( elem, tag ) ) {
- found.push( elem );
- } else {
- jQuery.merge( found, getAll( elem, tag ) );
- }
- }
- }
-
- return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
- jQuery.merge( [ context ], found ) :
- found;
-}
-
-// Used in buildFragment, fixes the defaultChecked property
-function fixDefaultChecked( elem ) {
- if ( rcheckableType.test( elem.type ) ) {
- elem.defaultChecked = elem.checked;
- }
-}
-
-// Support: IE<8
-// Manipulating tables requires a tbody
-function manipulationTarget( elem, content ) {
- return jQuery.nodeName( elem, "table" ) &&
- jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ?
-
- elem.getElementsByTagName("tbody")[0] ||
- elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
- elem;
-}
-
-// Replace/restore the type attribute of script elements for safe DOM manipulation
-function disableScript( elem ) {
- elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type;
- return elem;
-}
-function restoreScript( elem ) {
- var match = rscriptTypeMasked.exec( elem.type );
- if ( match ) {
- elem.type = match[1];
- } else {
- elem.removeAttribute("type");
- }
- return elem;
-}
-
-// Mark scripts as having already been evaluated
-function setGlobalEval( elems, refElements ) {
- var elem,
- i = 0;
- for ( ; (elem = elems[i]) != null; i++ ) {
- jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
- }
-}
-
-function cloneCopyEvent( src, dest ) {
-
- if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {
- return;
- }
-
- var type, i, l,
- oldData = jQuery._data( src ),
- curData = jQuery._data( dest, oldData ),
- events = oldData.events;
-
- if ( events ) {
- delete curData.handle;
- curData.events = {};
-
- for ( type in events ) {
- for ( i = 0, l = events[ type ].length; i < l; i++ ) {
- jQuery.event.add( dest, type, events[ type ][ i ] );
- }
- }
- }
-
- // make the cloned public data object a copy from the original
- if ( curData.data ) {
- curData.data = jQuery.extend( {}, curData.data );
- }
-}
-
-function fixCloneNodeIssues( src, dest ) {
- var nodeName, e, data;
-
- // We do not need to do anything for non-Elements
- if ( dest.nodeType !== 1 ) {
- return;
- }
-
- nodeName = dest.nodeName.toLowerCase();
-
- // IE6-8 copies events bound via attachEvent when using cloneNode.
- if ( !support.noCloneEvent && dest[ jQuery.expando ] ) {
- data = jQuery._data( dest );
-
- for ( e in data.events ) {
- jQuery.removeEvent( dest, e, data.handle );
- }
-
- // Event data gets referenced instead of copied if the expando gets copied too
- dest.removeAttribute( jQuery.expando );
- }
-
- // IE blanks contents when cloning scripts, and tries to evaluate newly-set text
- if ( nodeName === "script" && dest.text !== src.text ) {
- disableScript( dest ).text = src.text;
- restoreScript( dest );
-
- // IE6-10 improperly clones children of object elements using classid.
- // IE10 throws NoModificationAllowedError if parent is null, #12132.
- } else if ( nodeName === "object" ) {
- if ( dest.parentNode ) {
- dest.outerHTML = src.outerHTML;
- }
-
- // This path appears unavoidable for IE9. When cloning an object
- // element in IE9, the outerHTML strategy above is not sufficient.
- // If the src has innerHTML and the destination does not,
- // copy the src.innerHTML into the dest.innerHTML. #10324
- if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {
- dest.innerHTML = src.innerHTML;
- }
-
- } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
- // IE6-8 fails to persist the checked state of a cloned checkbox
- // or radio button. Worse, IE6-7 fail to give the cloned element
- // a checked appearance if the defaultChecked value isn't also set
-
- dest.defaultChecked = dest.checked = src.checked;
-
- // IE6-7 get confused and end up setting the value of a cloned
- // checkbox/radio button to an empty string instead of "on"
- if ( dest.value !== src.value ) {
- dest.value = src.value;
- }
-
- // IE6-8 fails to return the selected option to the default selected
- // state when cloning options
- } else if ( nodeName === "option" ) {
- dest.defaultSelected = dest.selected = src.defaultSelected;
-
- // IE6-8 fails to set the defaultValue to the correct value when
- // cloning other types of input fields
- } else if ( nodeName === "input" || nodeName === "textarea" ) {
- dest.defaultValue = src.defaultValue;
- }
-}
-
-jQuery.extend({
- clone: function( elem, dataAndEvents, deepDataAndEvents ) {
- var destElements, node, clone, i, srcElements,
- inPage = jQuery.contains( elem.ownerDocument, elem );
-
- if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
- clone = elem.cloneNode( true );
-
- // IE<=8 does not properly clone detached, unknown element nodes
- } else {
- fragmentDiv.innerHTML = elem.outerHTML;
- fragmentDiv.removeChild( clone = fragmentDiv.firstChild );
- }
-
- if ( (!support.noCloneEvent || !support.noCloneChecked) &&
- (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {
-
- // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
- destElements = getAll( clone );
- srcElements = getAll( elem );
-
- // Fix all IE cloning issues
- for ( i = 0; (node = srcElements[i]) != null; ++i ) {
- // Ensure that the destination node is not null; Fixes #9587
- if ( destElements[i] ) {
- fixCloneNodeIssues( node, destElements[i] );
- }
- }
- }
-
- // Copy the events from the original to the clone
- if ( dataAndEvents ) {
- if ( deepDataAndEvents ) {
- srcElements = srcElements || getAll( elem );
- destElements = destElements || getAll( clone );
-
- for ( i = 0; (node = srcElements[i]) != null; i++ ) {
- cloneCopyEvent( node, destElements[i] );
- }
- } else {
- cloneCopyEvent( elem, clone );
- }
- }
-
- // Preserve script evaluation history
- destElements = getAll( clone, "script" );
- if ( destElements.length > 0 ) {
- setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
- }
-
- destElements = srcElements = node = null;
-
- // Return the cloned set
- return clone;
- },
-
- buildFragment: function( elems, context, scripts, selection ) {
- var j, elem, contains,
- tmp, tag, tbody, wrap,
- l = elems.length,
-
- // Ensure a safe fragment
- safe = createSafeFragment( context ),
-
- nodes = [],
- i = 0;
-
- for ( ; i < l; i++ ) {
- elem = elems[ i ];
-
- if ( elem || elem === 0 ) {
-
- // Add nodes directly
- if ( jQuery.type( elem ) === "object" ) {
- jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
-
- // Convert non-html into a text node
- } else if ( !rhtml.test( elem ) ) {
- nodes.push( context.createTextNode( elem ) );
-
- // Convert html into DOM nodes
- } else {
- tmp = tmp || safe.appendChild( context.createElement("div") );
-
- // Deserialize a standard representation
- tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase();
- wrap = wrapMap[ tag ] || wrapMap._default;
-
- tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];
-
- // Descend through wrappers to the right content
- j = wrap[0];
- while ( j-- ) {
- tmp = tmp.lastChild;
- }
-
- // Manually add leading whitespace removed by IE
- if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
- nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
- }
-
- // Remove IE's autoinserted <tbody> from table fragments
- if ( !support.tbody ) {
-
- // String was a <table>, *may* have spurious <tbody>
- elem = tag === "table" && !rtbody.test( elem ) ?
- tmp.firstChild :
-
- // String was a bare <thead> or <tfoot>
- wrap[1] === "<table>" && !rtbody.test( elem ) ?
- tmp :
- 0;
-
- j = elem && elem.childNodes.length;
- while ( j-- ) {
- if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
- elem.removeChild( tbody );
- }
- }
- }
-
- jQuery.merge( nodes, tmp.childNodes );
-
- // Fix #12392 for WebKit and IE > 9
- tmp.textContent = "";
-
- // Fix #12392 for oldIE
- while ( tmp.firstChild ) {
- tmp.removeChild( tmp.firstChild );
- }
-
- // Remember the top-level container for proper cleanup
- tmp = safe.lastChild;
- }
- }
- }
-
- // Fix #11356: Clear elements from fragment
- if ( tmp ) {
- safe.removeChild( tmp );
- }
-
- // Reset defaultChecked for any radios and checkboxes
- // about to be appended to the DOM in IE 6/7 (#8060)
- if ( !support.appendChecked ) {
- jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
- }
-
- i = 0;
- while ( (elem = nodes[ i++ ]) ) {
-
- // #4087 - If origin and destination elements are the same, and this is
- // that element, do not do anything
- if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
- continue;
- }
-
- contains = jQuery.contains( elem.ownerDocument, elem );
-
- // Append to fragment
- tmp = getAll( safe.appendChild( elem ), "script" );
-
- // Preserve script evaluation history
- if ( contains ) {
- setGlobalEval( tmp );
- }
-
- // Capture executables
- if ( scripts ) {
- j = 0;
- while ( (elem = tmp[ j++ ]) ) {
- if ( rscriptType.test( elem.type || "" ) ) {
- scripts.push( elem );
- }
- }
- }
- }
-
- tmp = null;
-
- return safe;
- },
-
- cleanData: function( elems, /* internal */ acceptData ) {
- var elem, type, id, data,
- i = 0,
- internalKey = jQuery.expando,
- cache = jQuery.cache,
- deleteExpando = support.deleteExpando,
- special = jQuery.event.special;
-
- for ( ; (elem = elems[i]) != null; i++ ) {
- if ( acceptData || jQuery.acceptData( elem ) ) {
-
- id = elem[ internalKey ];
- data = id && cache[ id ];
-
- if ( data ) {
- if ( data.events ) {
- for ( type in data.events ) {
- if ( special[ type ] ) {
- jQuery.event.remove( elem, type );
-
- // This is a shortcut to avoid jQuery.event.remove's overhead
- } else {
- jQuery.removeEvent( elem, type, data.handle );
- }
- }
- }
-
- // Remove cache only if it was not already removed by jQuery.event.remove
- if ( cache[ id ] ) {
-
- delete cache[ id ];
-
- // IE does not allow us to delete expando properties from nodes,
- // nor does it have a removeAttribute function on Document nodes;
- // we must handle all of these cases
- if ( deleteExpando ) {
- delete elem[ internalKey ];
-
- } else if ( typeof elem.removeAttribute !== strundefined ) {
- elem.removeAttribute( internalKey );
-
- } else {
- elem[ internalKey ] = null;
- }
-
- deletedIds.push( id );
- }
- }
- }
- }
- }
-});
-
-jQuery.fn.extend({
- text: function( value ) {
- return access( this, function( value ) {
- return value === undefined ?
- jQuery.text( this ) :
- this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
- }, null, value, arguments.length );
- },
-
- append: function() {
- return this.domManip( arguments, function( elem ) {
- if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
- var target = manipulationTarget( this, elem );
- target.appendChild( elem );
- }
- });
- },
-
- prepend: function() {
- return this.domManip( arguments, function( elem ) {
- if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
- var target = manipulationTarget( this, elem );
- target.insertBefore( elem, target.firstChild );
- }
- });
- },
-
- before: function() {
- return this.domManip( arguments, function( elem ) {
- if ( this.parentNode ) {
- this.parentNode.insertBefore( elem, this );
- }
- });
- },
-
- after: function() {
- return this.domManip( arguments, function( elem ) {
- if ( this.parentNode ) {
- this.parentNode.insertBefore( elem, this.nextSibling );
- }
- });
- },
-
- remove: function( selector, keepData /* Internal Use Only */ ) {
- var elem,
- elems = selector ? jQuery.filter( selector, this ) : this,
- i = 0;
-
- for ( ; (elem = elems[i]) != null; i++ ) {
-
- if ( !keepData && elem.nodeType === 1 ) {
- jQuery.cleanData( getAll( elem ) );
- }
-
- if ( elem.parentNode ) {
- if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
- setGlobalEval( getAll( elem, "script" ) );
- }
- elem.parentNode.removeChild( elem );
- }
- }
-
- return this;
- },
-
- empty: function() {
- var elem,
- i = 0;
-
- for ( ; (elem = this[i]) != null; i++ ) {
- // Remove element nodes and prevent memory leaks
- if ( elem.nodeType === 1 ) {
- jQuery.cleanData( getAll( elem, false ) );
- }
-
- // Remove any remaining nodes
- while ( elem.firstChild ) {
- elem.removeChild( elem.firstChild );
- }
-
- // If this is a select, ensure that it displays empty (#12336)
- // Support: IE<9
- if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
- elem.options.length = 0;
- }
- }
-
- return this;
- },
-
- clone: function( dataAndEvents, deepDataAndEvents ) {
- dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
- deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
-
- return this.map(function() {
- return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
- });
- },
-
- html: function( value ) {
- return access( this, function( value ) {
- var elem = this[ 0 ] || {},
- i = 0,
- l = this.length;
-
- if ( value === undefined ) {
- return elem.nodeType === 1 ?
- elem.innerHTML.replace( rinlinejQuery, "" ) :
- undefined;
- }
-
- // See if we can take a shortcut and just use innerHTML
- if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
- ( support.htmlSerialize || !rnoshimcache.test( value ) ) &&
- ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&
- !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) {
-
- value = value.replace( rxhtmlTag, "<$1></$2>" );
-
- try {
- for (; i < l; i++ ) {
- // Remove element nodes and prevent memory leaks
- elem = this[i] || {};
- if ( elem.nodeType === 1 ) {
- jQuery.cleanData( getAll( elem, false ) );
- elem.innerHTML = value;
- }
- }
-
- elem = 0;
-
- // If using innerHTML throws an exception, use the fallback method
- } catch(e) {}
- }
-
- if ( elem ) {
- this.empty().append( value );
- }
- }, null, value, arguments.length );
- },
-
- replaceWith: function() {
- var arg = arguments[ 0 ];
-
- // Make the changes, replacing each context element with the new content
- this.domManip( arguments, function( elem ) {
- arg = this.parentNode;
-
- jQuery.cleanData( getAll( this ) );
-
- if ( arg ) {
- arg.replaceChild( elem, this );
- }
- });
-
- // Force removal if there was no new content (e.g., from empty arguments)
- return arg && (arg.length || arg.nodeType) ? this : this.remove();
- },
-
- detach: function( selector ) {
- return this.remove( selector, true );
- },
-
- domManip: function( args, callback ) {
-
- // Flatten any nested arrays
- args = concat.apply( [], args );
-
- var first, node, hasScripts,
- scripts, doc, fragment,
- i = 0,
- l = this.length,
- set = this,
- iNoClone = l - 1,
- value = args[0],
- isFunction = jQuery.isFunction( value );
-
- // We can't cloneNode fragments that contain checked, in WebKit
- if ( isFunction ||
- ( l > 1 && typeof value === "string" &&
- !support.checkClone && rchecked.test( value ) ) ) {
- return this.each(function( index ) {
- var self = set.eq( index );
- if ( isFunction ) {
- args[0] = value.call( this, index, self.html() );
- }
- self.domManip( args, callback );
- });
- }
-
- if ( l ) {
- fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
- first = fragment.firstChild;
-
- if ( fragment.childNodes.length === 1 ) {
- fragment = first;
- }
-
- if ( first ) {
- scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
- hasScripts = scripts.length;
-
- // Use the original fragment for the last item instead of the first because it can end up
- // being emptied incorrectly in certain situations (#8070).
- for ( ; i < l; i++ ) {
- node = fragment;
-
- if ( i !== iNoClone ) {
- node = jQuery.clone( node, true, true );
-
- // Keep references to cloned scripts for later restoration
- if ( hasScripts ) {
- jQuery.merge( scripts, getAll( node, "script" ) );
- }
- }
-
- callback.call( this[i], node, i );
- }
-
- if ( hasScripts ) {
- doc = scripts[ scripts.length - 1 ].ownerDocument;
-
- // Reenable scripts
- jQuery.map( scripts, restoreScript );
-
- // Evaluate executable scripts on first document insertion
- for ( i = 0; i < hasScripts; i++ ) {
- node = scripts[ i ];
- if ( rscriptType.test( node.type || "" ) &&
- !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
-
- if ( node.src ) {
- // Optional AJAX dependency, but won't run scripts if not present
- if ( jQuery._evalUrl ) {
- jQuery._evalUrl( node.src );
- }
- } else {
- jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
- }
- }
- }
- }
-
- // Fix #11809: Avoid leaking memory
- fragment = first = null;
- }
- }
-
- return this;
- }
-});
-
-jQuery.each({
- appendTo: "append",
- prependTo: "prepend",
- insertBefore: "before",
- insertAfter: "after",
- replaceAll: "replaceWith"
-}, function( name, original ) {
- jQuery.fn[ name ] = function( selector ) {
- var elems,
- i = 0,
- ret = [],
- insert = jQuery( selector ),
- last = insert.length - 1;
-
- for ( ; i <= last; i++ ) {
- elems = i === last ? this : this.clone(true);
- jQuery( insert[i] )[ original ]( elems );
-
- // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
- push.apply( ret, elems.get() );
- }
-
- return this.pushStack( ret );
- };
-});
-
-
-var iframe,
- elemdisplay = {};
-
-/**
- * Retrieve the actual display of a element
- * @param {String} name nodeName of the element
- * @param {Object} doc Document object
- */
-// Called only from within defaultDisplay
-function actualDisplay( name, doc ) {
- var style,
- elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
-
- // getDefaultComputedStyle might be reliably used only on attached element
- display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?
-
- // Use of this method is a temporary fix (more like optmization) until something better comes along,
- // since it was removed from specification and supported only in FF
- style.display : jQuery.css( elem[ 0 ], "display" );
-
- // We don't have any data stored on the element,
- // so use "detach" method as fast way to get rid of the element
- elem.detach();
-
- return display;
-}
-
-/**
- * Try to determine the default display value of an element
- * @param {String} nodeName
- */
-function defaultDisplay( nodeName ) {
- var doc = document,
- display = elemdisplay[ nodeName ];
-
- if ( !display ) {
- display = actualDisplay( nodeName, doc );
-
- // If the simple way fails, read from inside an iframe
- if ( display === "none" || !display ) {
-
- // Use the already-created iframe if possible
- iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement );
-
- // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
- doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;
-
- // Support: IE
- doc.write();
- doc.close();
-
- display = actualDisplay( nodeName, doc );
- iframe.detach();
- }
-
- // Store the correct default display
- elemdisplay[ nodeName ] = display;
- }
-
- return display;
-}
-
-
-(function() {
- var shrinkWrapBlocksVal;
-
- support.shrinkWrapBlocks = function() {
- if ( shrinkWrapBlocksVal != null ) {
- return shrinkWrapBlocksVal;
- }
-
- // Will be changed later if needed.
- shrinkWrapBlocksVal = false;
-
- // Minified: var b,c,d
- var div, body, container;
-
- body = document.getElementsByTagName( "body" )[ 0 ];
- if ( !body || !body.style ) {
- // Test fired too early or in an unsupported environment, exit.
- return;
- }
-
- // Setup
- div = document.createElement( "div" );
- container = document.createElement( "div" );
- container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
- body.appendChild( container ).appendChild( div );
-
- // Support: IE6
- // Check if elements with layout shrink-wrap their children
- if ( typeof div.style.zoom !== strundefined ) {
- // Reset CSS: box-sizing; display; margin; border
- div.style.cssText =
- // Support: Firefox<29, Android 2.3
- // Vendor-prefix box-sizing
- "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
- "box-sizing:content-box;display:block;margin:0;border:0;" +
- "padding:1px;width:1px;zoom:1";
- div.appendChild( document.createElement( "div" ) ).style.width = "5px";
- shrinkWrapBlocksVal = div.offsetWidth !== 3;
- }
-
- body.removeChild( container );
-
- return shrinkWrapBlocksVal;
- };
-
-})();
-var rmargin = (/^margin/);
-
-var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
-
-
-
-var getStyles, curCSS,
- rposition = /^(top|right|bottom|left)$/;
-
-if ( window.getComputedStyle ) {
- getStyles = function( elem ) {
- // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
- // IE throws on elements created in popups
- // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
- if ( elem.ownerDocument.defaultView.opener ) {
- return elem.ownerDocument.defaultView.getComputedStyle( elem, null );
- }
-
- return window.getComputedStyle( elem, null );
- };
-
- curCSS = function( elem, name, computed ) {
- var width, minWidth, maxWidth, ret,
- style = elem.style;
-
- computed = computed || getStyles( elem );
-
- // getPropertyValue is only needed for .css('filter') in IE9, see #12537
- ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;
-
- if ( computed ) {
-
- if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
- ret = jQuery.style( elem, name );
- }
-
- // A tribute to the "awesome hack by Dean Edwards"
- // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right
- // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
- // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
- if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
-
- // Remember the original values
- width = style.width;
- minWidth = style.minWidth;
- maxWidth = style.maxWidth;
-
- // Put in the new values to get a computed value out
- style.minWidth = style.maxWidth = style.width = ret;
- ret = computed.width;
-
- // Revert the changed values
- style.width = width;
- style.minWidth = minWidth;
- style.maxWidth = maxWidth;
- }
- }
-
- // Support: IE
- // IE returns zIndex value as an integer.
- return ret === undefined ?
- ret :
- ret + "";
- };
-} else if ( document.documentElement.currentStyle ) {
- getStyles = function( elem ) {
- return elem.currentStyle;
- };
-
- curCSS = function( elem, name, computed ) {
- var left, rs, rsLeft, ret,
- style = elem.style;
-
- computed = computed || getStyles( elem );
- ret = computed ? computed[ name ] : undefined;
-
- // Avoid setting ret to empty string here
- // so we don't default to auto
- if ( ret == null && style && style[ name ] ) {
- ret = style[ name ];
- }
-
- // From the awesome hack by Dean Edwards
- // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
-
- // If we're not dealing with a regular pixel number
- // but a number that has a weird ending, we need to convert it to pixels
- // but not position css attributes, as those are proportional to the parent element instead
- // and we can't measure the parent instead because it might trigger a "stacking dolls" problem
- if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {
-
- // Remember the original values
- left = style.left;
- rs = elem.runtimeStyle;
- rsLeft = rs && rs.left;
-
- // Put in the new values to get a computed value out
- if ( rsLeft ) {
- rs.left = elem.currentStyle.left;
- }
- style.left = name === "fontSize" ? "1em" : ret;
- ret = style.pixelLeft + "px";
-
- // Revert the changed values
- style.left = left;
- if ( rsLeft ) {
- rs.left = rsLeft;
- }
- }
-
- // Support: IE
- // IE returns zIndex value as an integer.
- return ret === undefined ?
- ret :
- ret + "" || "auto";
- };
-}
-
-
-
-
-function addGetHookIf( conditionFn, hookFn ) {
- // Define the hook, we'll check on the first run if it's really needed.
- return {
- get: function() {
- var condition = conditionFn();
-
- if ( condition == null ) {
- // The test was not ready at this point; screw the hook this time
- // but check again when needed next time.
- return;
- }
-
- if ( condition ) {
- // Hook not needed (or it's not possible to use it due to missing dependency),
- // remove it.
- // Since there are no other hooks for marginRight, remove the whole object.
- delete this.get;
- return;
- }
-
- // Hook needed; redefine it so that the support test is not executed again.
-
- return (this.get = hookFn).apply( this, arguments );
- }
- };
-}
-
-
-(function() {
- // Minified: var b,c,d,e,f,g, h,i
- var div, style, a, pixelPositionVal, boxSizingReliableVal,
- reliableHiddenOffsetsVal, reliableMarginRightVal;
-
- // Setup
- div = document.createElement( "div" );
- div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
- a = div.getElementsByTagName( "a" )[ 0 ];
- style = a && a.style;
-
- // Finish early in limited (non-browser) environments
- if ( !style ) {
- return;
- }
-
- style.cssText = "float:left;opacity:.5";
-
- // Support: IE<9
- // Make sure that element opacity exists (as opposed to filter)
- support.opacity = style.opacity === "0.5";
-
- // Verify style float existence
- // (IE uses styleFloat instead of cssFloat)
- support.cssFloat = !!style.cssFloat;
-
- div.style.backgroundClip = "content-box";
- div.cloneNode( true ).style.backgroundClip = "";
- support.clearCloneStyle = div.style.backgroundClip === "content-box";
-
- // Support: Firefox<29, Android 2.3
- // Vendor-prefix box-sizing
- support.boxSizing = style.boxSizing === "" || style.MozBoxSizing === "" ||
- style.WebkitBoxSizing === "";
-
- jQuery.extend(support, {
- reliableHiddenOffsets: function() {
- if ( reliableHiddenOffsetsVal == null ) {
- computeStyleTests();
- }
- return reliableHiddenOffsetsVal;
- },
-
- boxSizingReliable: function() {
- if ( boxSizingReliableVal == null ) {
- computeStyleTests();
- }
- return boxSizingReliableVal;
- },
-
- pixelPosition: function() {
- if ( pixelPositionVal == null ) {
- computeStyleTests();
- }
- return pixelPositionVal;
- },
-
- // Support: Android 2.3
- reliableMarginRight: function() {
- if ( reliableMarginRightVal == null ) {
- computeStyleTests();
- }
- return reliableMarginRightVal;
- }
- });
-
- function computeStyleTests() {
- // Minified: var b,c,d,j
- var div, body, container, contents;
-
- body = document.getElementsByTagName( "body" )[ 0 ];
- if ( !body || !body.style ) {
- // Test fired too early or in an unsupported environment, exit.
- return;
- }
-
- // Setup
- div = document.createElement( "div" );
- container = document.createElement( "div" );
- container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px";
- body.appendChild( container ).appendChild( div );
-
- div.style.cssText =
- // Support: Firefox<29, Android 2.3
- // Vendor-prefix box-sizing
- "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" +
- "box-sizing:border-box;display:block;margin-top:1%;top:1%;" +
- "border:1px;padding:1px;width:4px;position:absolute";
-
- // Support: IE<9
- // Assume reasonable values in the absence of getComputedStyle
- pixelPositionVal = boxSizingReliableVal = false;
- reliableMarginRightVal = true;
-
- // Check for getComputedStyle so that this code is not run in IE<9.
- if ( window.getComputedStyle ) {
- pixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
- boxSizingReliableVal =
- ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
-
- // Support: Android 2.3
- // Div with explicit width and no margin-right incorrectly
- // gets computed margin-right based on width of container (#3333)
- // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
- contents = div.appendChild( document.createElement( "div" ) );
-
- // Reset CSS: box-sizing; display; margin; border; padding
- contents.style.cssText = div.style.cssText =
- // Support: Firefox<29, Android 2.3
- // Vendor-prefix box-sizing
- "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" +
- "box-sizing:content-box;display:block;margin:0;border:0;padding:0";
- contents.style.marginRight = contents.style.width = "0";
- div.style.width = "1px";
-
- reliableMarginRightVal =
- !parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight );
-
- div.removeChild( contents );
- }
-
- // Support: IE8
- // Check if table cells still have offsetWidth/Height when they are set
- // to display:none and there are still other visible table cells in a
- // table row; if so, offsetWidth/Height are not reliable for use when
- // determining if an element has been hidden directly using
- // display:none (it is still safe to use offsets if a parent element is
- // hidden; don safety goggles and see bug #4512 for more information).
- div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
- contents = div.getElementsByTagName( "td" );
- contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none";
- reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
- if ( reliableHiddenOffsetsVal ) {
- contents[ 0 ].style.display = "";
- contents[ 1 ].style.display = "none";
- reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;
- }
-
- body.removeChild( container );
- }
-
-})();
-
-
-// A method for quickly swapping in/out CSS properties to get correct calculations.
-jQuery.swap = function( elem, options, callback, args ) {
- var ret, name,
- old = {};
-
- // Remember the old values, and insert the new ones
- for ( name in options ) {
- old[ name ] = elem.style[ name ];
- elem.style[ name ] = options[ name ];
- }
-
- ret = callback.apply( elem, args || [] );
-
- // Revert the old values
- for ( name in options ) {
- elem.style[ name ] = old[ name ];
- }
-
- return ret;
-};
-
-
-var
- ralpha = /alpha\([^)]*\)/i,
- ropacity = /opacity\s*=\s*([^)]*)/,
-
- // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
- // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
- rdisplayswap = /^(none|table(?!-c[ea]).+)/,
- rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ),
- rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ),
-
- cssShow = { position: "absolute", visibility: "hidden", display: "block" },
- cssNormalTransform = {
- letterSpacing: "0",
- fontWeight: "400"
- },
-
- cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
-
-
-// return a css property mapped to a potentially vendor prefixed property
-function vendorPropName( style, name ) {
-
- // shortcut for names that are not vendor prefixed
- if ( name in style ) {
- return name;
- }
-
- // check for vendor prefixed names
- var capName = name.charAt(0).toUpperCase() + name.slice(1),
- origName = name,
- i = cssPrefixes.length;
-
- while ( i-- ) {
- name = cssPrefixes[ i ] + capName;
- if ( name in style ) {
- return name;
- }
- }
-
- return origName;
-}
-
-function showHide( elements, show ) {
- var display, elem, hidden,
- values = [],
- index = 0,
- length = elements.length;
-
- for ( ; index < length; index++ ) {
- elem = elements[ index ];
- if ( !elem.style ) {
- continue;
- }
-
- values[ index ] = jQuery._data( elem, "olddisplay" );
- display = elem.style.display;
- if ( show ) {
- // Reset the inline display of this element to learn if it is
- // being hidden by cascaded rules or not
- if ( !values[ index ] && display === "none" ) {
- elem.style.display = "";
- }
-
- // Set elements which have been overridden with display: none
- // in a stylesheet to whatever the default browser style is
- // for such an element
- if ( elem.style.display === "" && isHidden( elem ) ) {
- values[ index ] = jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) );
- }
- } else {
- hidden = isHidden( elem );
-
- if ( display && display !== "none" || !hidden ) {
- jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) );
- }
- }
- }
-
- // Set the display of most of the elements in a second loop
- // to avoid the constant reflow
- for ( index = 0; index < length; index++ ) {
- elem = elements[ index ];
- if ( !elem.style ) {
- continue;
- }
- if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
- elem.style.display = show ? values[ index ] || "" : "none";
- }
- }
-
- return elements;
-}
-
-function setPositiveNumber( elem, value, subtract ) {
- var matches = rnumsplit.exec( value );
- return matches ?
- // Guard against undefined "subtract", e.g., when used as in cssHooks
- Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
- value;
-}
-
-function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
- var i = extra === ( isBorderBox ? "border" : "content" ) ?
- // If we already have the right measurement, avoid augmentation
- 4 :
- // Otherwise initialize for horizontal or vertical properties
- name === "width" ? 1 : 0,
-
- val = 0;
-
- for ( ; i < 4; i += 2 ) {
- // both box models exclude margin, so add it if we want it
- if ( extra === "margin" ) {
- val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
- }
-
- if ( isBorderBox ) {
- // border-box includes padding, so remove it if we want content
- if ( extra === "content" ) {
- val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
- }
-
- // at this point, extra isn't border nor margin, so remove border
- if ( extra !== "margin" ) {
- val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
- }
- } else {
- // at this point, extra isn't content, so add padding
- val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
-
- // at this point, extra isn't content nor padding, so add border
- if ( extra !== "padding" ) {
- val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
- }
- }
- }
-
- return val;
-}
-
-function getWidthOrHeight( elem, name, extra ) {
-
- // Start with offset property, which is equivalent to the border-box value
- var valueIsBorderBox = true,
- val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
- styles = getStyles( elem ),
- isBorderBox = support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
-
- // some non-html elements return undefined for offsetWidth, so check for null/undefined
- // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
- // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
- if ( val <= 0 || val == null ) {
- // Fall back to computed then uncomputed css if necessary
- val = curCSS( elem, name, styles );
- if ( val < 0 || val == null ) {
- val = elem.style[ name ];
- }
-
- // Computed unit is not pixels. Stop here and return.
- if ( rnumnonpx.test(val) ) {
- return val;
- }
-
- // we need the check for style in case a browser which returns unreliable values
- // for getComputedStyle silently falls back to the reliable elem.style
- valueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );
-
- // Normalize "", auto, and prepare for extra
- val = parseFloat( val ) || 0;
- }
-
- // use the active box-sizing model to add/subtract irrelevant styles
- return ( val +
- augmentWidthOrHeight(
- elem,
- name,
- extra || ( isBorderBox ? "border" : "content" ),
- valueIsBorderBox,
- styles
- )
- ) + "px";
-}
-
-jQuery.extend({
- // Add in style property hooks for overriding the default
- // behavior of getting and setting a style property
- cssHooks: {
- opacity: {
- get: function( elem, computed ) {
- if ( computed ) {
- // We should always get a number back from opacity
- var ret = curCSS( elem, "opacity" );
- return ret === "" ? "1" : ret;
- }
- }
- }
- },
-
- // Don't automatically add "px" to these possibly-unitless properties
- cssNumber: {
- "columnCount": true,
- "fillOpacity": true,
- "flexGrow": true,
- "flexShrink": true,
- "fontWeight": true,
- "lineHeight": true,
- "opacity": true,
- "order": true,
- "orphans": true,
- "widows": true,
- "zIndex": true,
- "zoom": true
- },
-
- // Add in properties whose names you wish to fix before
- // setting or getting the value
- cssProps: {
- // normalize float css property
- "float": support.cssFloat ? "cssFloat" : "styleFloat"
- },
-
- // Get and set the style property on a DOM Node
- style: function( elem, name, value, extra ) {
- // Don't set styles on text and comment nodes
- if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
- return;
- }
-
- // Make sure that we're working with the right name
- var ret, type, hooks,
- origName = jQuery.camelCase( name ),
- style = elem.style;
-
- name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
-
- // gets hook for the prefixed version
- // followed by the unprefixed version
- hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
-
- // Check if we're setting a value
- if ( value !== undefined ) {
- type = typeof value;
-
- // convert relative number strings (+= or -=) to relative numbers. #7345
- if ( type === "string" && (ret = rrelNum.exec( value )) ) {
- value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
- // Fixes bug #9237
- type = "number";
- }
-
- // Make sure that null and NaN values aren't set. See: #7116
- if ( value == null || value !== value ) {
- return;
- }
-
- // If a number was passed in, add 'px' to the (except for certain CSS properties)
- if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
- value += "px";
- }
-
- // Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
- // but it would mean to define eight (for every problematic property) identical functions
- if ( !support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
- style[ name ] = "inherit";
- }
-
- // If a hook was provided, use that value, otherwise just set the specified value
- if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
-
- // Support: IE
- // Swallow errors from 'invalid' CSS values (#5509)
- try {
- style[ name ] = value;
- } catch(e) {}
- }
-
- } else {
- // If a hook was provided get the non-computed value from there
- if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
- return ret;
- }
-
- // Otherwise just get the value from the style object
- return style[ name ];
- }
- },
-
- css: function( elem, name, extra, styles ) {
- var num, val, hooks,
- origName = jQuery.camelCase( name );
-
- // Make sure that we're working with the right name
- name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
-
- // gets hook for the prefixed version
- // followed by the unprefixed version
- hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
-
- // If a hook was provided get the computed value from there
- if ( hooks && "get" in hooks ) {
- val = hooks.get( elem, true, extra );
- }
-
- // Otherwise, if a way to get the computed value exists, use that
- if ( val === undefined ) {
- val = curCSS( elem, name, styles );
- }
-
- //convert "normal" to computed value
- if ( val === "normal" && name in cssNormalTransform ) {
- val = cssNormalTransform[ name ];
- }
-
- // Return, converting to number if forced or a qualifier was provided and val looks numeric
- if ( extra === "" || extra ) {
- num = parseFloat( val );
- return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
- }
- return val;
- }
-});
-
-jQuery.each([ "height", "width" ], function( i, name ) {
- jQuery.cssHooks[ name ] = {
- get: function( elem, computed, extra ) {
- if ( computed ) {
- // certain elements can have dimension info if we invisibly show them
- // however, it must have a current display style that would benefit from this
- return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ?
- jQuery.swap( elem, cssShow, function() {
- return getWidthOrHeight( elem, name, extra );
- }) :
- getWidthOrHeight( elem, name, extra );
- }
- },
-
- set: function( elem, value, extra ) {
- var styles = extra && getStyles( elem );
- return setPositiveNumber( elem, value, extra ?
- augmentWidthOrHeight(
- elem,
- name,
- extra,
- support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
- styles
- ) : 0
- );
- }
- };
-});
-
-if ( !support.opacity ) {
- jQuery.cssHooks.opacity = {
- get: function( elem, computed ) {
- // IE uses filters for opacity
- return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?
- ( 0.01 * parseFloat( RegExp.$1 ) ) + "" :
- computed ? "1" : "";
- },
-
- set: function( elem, value ) {
- var style = elem.style,
- currentStyle = elem.currentStyle,
- opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",
- filter = currentStyle && currentStyle.filter || style.filter || "";
-
- // IE has trouble with opacity if it does not have layout
- // Force it by setting the zoom level
- style.zoom = 1;
-
- // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
- // if value === "", then remove inline opacity #12685
- if ( ( value >= 1 || value === "" ) &&
- jQuery.trim( filter.replace( ralpha, "" ) ) === "" &&
- style.removeAttribute ) {
-
- // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
- // if "filter:" is present at all, clearType is disabled, we want to avoid this
- // style.removeAttribute is IE Only, but so apparently is this code path...
- style.removeAttribute( "filter" );
-
- // if there is no filter style applied in a css rule or unset inline opacity, we are done
- if ( value === "" || currentStyle && !currentStyle.filter ) {
- return;
- }
- }
-
- // otherwise, set new filter values
- style.filter = ralpha.test( filter ) ?
- filter.replace( ralpha, opacity ) :
- filter + " " + opacity;
- }
- };
-}
-
-jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,
- function( elem, computed ) {
- if ( computed ) {
- // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
- // Work around by temporarily setting element display to inline-block
- return jQuery.swap( elem, { "display": "inline-block" },
- curCSS, [ elem, "marginRight" ] );
- }
- }
-);
-
-// These hooks are used by animate to expand properties
-jQuery.each({
- margin: "",
- padding: "",
- border: "Width"
-}, function( prefix, suffix ) {
- jQuery.cssHooks[ prefix + suffix ] = {
- expand: function( value ) {
- var i = 0,
- expanded = {},
-
- // assumes a single number if not a string
- parts = typeof value === "string" ? value.split(" ") : [ value ];
-
- for ( ; i < 4; i++ ) {
- expanded[ prefix + cssExpand[ i ] + suffix ] =
- parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
- }
-
- return expanded;
- }
- };
-
- if ( !rmargin.test( prefix ) ) {
- jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
- }
-});
-
-jQuery.fn.extend({
- css: function( name, value ) {
- return access( this, function( elem, name, value ) {
- var styles, len,
- map = {},
- i = 0;
-
- if ( jQuery.isArray( name ) ) {
- styles = getStyles( elem );
- len = name.length;
-
- for ( ; i < len; i++ ) {
- map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
- }
-
- return map;
- }
-
- return value !== undefined ?
- jQuery.style( elem, name, value ) :
- jQuery.css( elem, name );
- }, name, value, arguments.length > 1 );
- },
- show: function() {
- return showHide( this, true );
- },
- hide: function() {
- return showHide( this );
- },
- toggle: function( state ) {
- if ( typeof state === "boolean" ) {
- return state ? this.show() : this.hide();
- }
-
- return this.each(function() {
- if ( isHidden( this ) ) {
- jQuery( this ).show();
- } else {
- jQuery( this ).hide();
- }
- });
- }
-});
-
-
-function Tween( elem, options, prop, end, easing ) {
- return new Tween.prototype.init( elem, options, prop, end, easing );
-}
-jQuery.Tween = Tween;
-
-Tween.prototype = {
- constructor: Tween,
- init: function( elem, options, prop, end, easing, unit ) {
- this.elem = elem;
- this.prop = prop;
- this.easing = easing || "swing";
- this.options = options;
- this.start = this.now = this.cur();
- this.end = end;
- this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
- },
- cur: function() {
- var hooks = Tween.propHooks[ this.prop ];
-
- return hooks && hooks.get ?
- hooks.get( this ) :
- Tween.propHooks._default.get( this );
- },
- run: function( percent ) {
- var eased,
- hooks = Tween.propHooks[ this.prop ];
-
- if ( this.options.duration ) {
- this.pos = eased = jQuery.easing[ this.easing ](
- percent, this.options.duration * percent, 0, 1, this.options.duration
- );
- } else {
- this.pos = eased = percent;
- }
- this.now = ( this.end - this.start ) * eased + this.start;
-
- if ( this.options.step ) {
- this.options.step.call( this.elem, this.now, this );
- }
-
- if ( hooks && hooks.set ) {
- hooks.set( this );
- } else {
- Tween.propHooks._default.set( this );
- }
- return this;
- }
-};
-
-Tween.prototype.init.prototype = Tween.prototype;
-
-Tween.propHooks = {
- _default: {
- get: function( tween ) {
- var result;
-
- if ( tween.elem[ tween.prop ] != null &&
- (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
- return tween.elem[ tween.prop ];
- }
-
- // passing an empty string as a 3rd parameter to .css will automatically
- // attempt a parseFloat and fallback to a string if the parse fails
- // so, simple values such as "10px" are parsed to Float.
- // complex values such as "rotate(1rad)" are returned as is.
- result = jQuery.css( tween.elem, tween.prop, "" );
- // Empty strings, null, undefined and "auto" are converted to 0.
- return !result || result === "auto" ? 0 : result;
- },
- set: function( tween ) {
- // use step hook for back compat - use cssHook if its there - use .style if its
- // available and use plain properties where available
- if ( jQuery.fx.step[ tween.prop ] ) {
- jQuery.fx.step[ tween.prop ]( tween );
- } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
- jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
- } else {
- tween.elem[ tween.prop ] = tween.now;
- }
- }
- }
-};
-
-// Support: IE <=9
-// Panic based approach to setting things on disconnected nodes
-
-Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
- set: function( tween ) {
- if ( tween.elem.nodeType && tween.elem.parentNode ) {
- tween.elem[ tween.prop ] = tween.now;
- }
- }
-};
-
-jQuery.easing = {
- linear: function( p ) {
- return p;
- },
- swing: function( p ) {
- return 0.5 - Math.cos( p * Math.PI ) / 2;
- }
-};
-
-jQuery.fx = Tween.prototype.init;
-
-// Back Compat <1.8 extension point
-jQuery.fx.step = {};
-
-
-
-
-var
- fxNow, timerId,
- rfxtypes = /^(?:toggle|show|hide)$/,
- rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ),
- rrun = /queueHooks$/,
- animationPrefilters = [ defaultPrefilter ],
- tweeners = {
- "*": [ function( prop, value ) {
- var tween = this.createTween( prop, value ),
- target = tween.cur(),
- parts = rfxnum.exec( value ),
- unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
-
- // Starting value computation is required for potential unit mismatches
- start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
- rfxnum.exec( jQuery.css( tween.elem, prop ) ),
- scale = 1,
- maxIterations = 20;
-
- if ( start && start[ 3 ] !== unit ) {
- // Trust units reported by jQuery.css
- unit = unit || start[ 3 ];
-
- // Make sure we update the tween properties later on
- parts = parts || [];
-
- // Iteratively approximate from a nonzero starting point
- start = +target || 1;
-
- do {
- // If previous iteration zeroed out, double until we get *something*
- // Use a string for doubling factor so we don't accidentally see scale as unchanged below
- scale = scale || ".5";
-
- // Adjust and apply
- start = start / scale;
- jQuery.style( tween.elem, prop, start + unit );
-
- // Update scale, tolerating zero or NaN from tween.cur()
- // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
- } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
- }
-
- // Update tween properties
- if ( parts ) {
- start = tween.start = +start || +target || 0;
- tween.unit = unit;
- // If a +=/-= token was provided, we're doing a relative animation
- tween.end = parts[ 1 ] ?
- start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
- +parts[ 2 ];
- }
-
- return tween;
- } ]
- };
-
-// Animations created synchronously will run synchronously
-function createFxNow() {
- setTimeout(function() {
- fxNow = undefined;
- });
- return ( fxNow = jQuery.now() );
-}
-
-// Generate parameters to create a standard animation
-function genFx( type, includeWidth ) {
- var which,
- attrs = { height: type },
- i = 0;
-
- // if we include width, step value is 1 to do all cssExpand values,
- // if we don't include width, step value is 2 to skip over Left and Right
- includeWidth = includeWidth ? 1 : 0;
- for ( ; i < 4 ; i += 2 - includeWidth ) {
- which = cssExpand[ i ];
- attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
- }
-
- if ( includeWidth ) {
- attrs.opacity = attrs.width = type;
- }
-
- return attrs;
-}
-
-function createTween( value, prop, animation ) {
- var tween,
- collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
- index = 0,
- length = collection.length;
- for ( ; index < length; index++ ) {
- if ( (tween = collection[ index ].call( animation, prop, value )) ) {
-
- // we're done with this property
- return tween;
- }
- }
-}
-
-function defaultPrefilter( elem, props, opts ) {
- /* jshint validthis: true */
- var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,
- anim = this,
- orig = {},
- style = elem.style,
- hidden = elem.nodeType && isHidden( elem ),
- dataShow = jQuery._data( elem, "fxshow" );
-
- // handle queue: false promises
- if ( !opts.queue ) {
- hooks = jQuery._queueHooks( elem, "fx" );
- if ( hooks.unqueued == null ) {
- hooks.unqueued = 0;
- oldfire = hooks.empty.fire;
- hooks.empty.fire = function() {
- if ( !hooks.unqueued ) {
- oldfire();
- }
- };
- }
- hooks.unqueued++;
-
- anim.always(function() {
- // doing this makes sure that the complete handler will be called
- // before this completes
- anim.always(function() {
- hooks.unqueued--;
- if ( !jQuery.queue( elem, "fx" ).length ) {
- hooks.empty.fire();
- }
- });
- });
- }
-
- // height/width overflow pass
- if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
- // Make sure that nothing sneaks out
- // Record all 3 overflow attributes because IE does not
- // change the overflow attribute when overflowX and
- // overflowY are set to the same value
- opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
-
- // Set display property to inline-block for height/width
- // animations on inline elements that are having width/height animated
- display = jQuery.css( elem, "display" );
-
- // Test default display if display is currently "none"
- checkDisplay = display === "none" ?
- jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display;
-
- if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) {
-
- // inline-level elements accept inline-block;
- // block-level elements need to be inline with layout
- if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) {
- style.display = "inline-block";
- } else {
- style.zoom = 1;
- }
- }
- }
-
- if ( opts.overflow ) {
- style.overflow = "hidden";
- if ( !support.shrinkWrapBlocks() ) {
- anim.always(function() {
- style.overflow = opts.overflow[ 0 ];
- style.overflowX = opts.overflow[ 1 ];
- style.overflowY = opts.overflow[ 2 ];
- });
- }
- }
-
- // show/hide pass
- for ( prop in props ) {
- value = props[ prop ];
- if ( rfxtypes.exec( value ) ) {
- delete props[ prop ];
- toggle = toggle || value === "toggle";
- if ( value === ( hidden ? "hide" : "show" ) ) {
-
- // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
- if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
- hidden = true;
- } else {
- continue;
- }
- }
- orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
-
- // Any non-fx value stops us from restoring the original display value
- } else {
- display = undefined;
- }
- }
-
- if ( !jQuery.isEmptyObject( orig ) ) {
- if ( dataShow ) {
- if ( "hidden" in dataShow ) {
- hidden = dataShow.hidden;
- }
- } else {
- dataShow = jQuery._data( elem, "fxshow", {} );
- }
-
- // store state if its toggle - enables .stop().toggle() to "reverse"
- if ( toggle ) {
- dataShow.hidden = !hidden;
- }
- if ( hidden ) {
- jQuery( elem ).show();
- } else {
- anim.done(function() {
- jQuery( elem ).hide();
- });
- }
- anim.done(function() {
- var prop;
- jQuery._removeData( elem, "fxshow" );
- for ( prop in orig ) {
- jQuery.style( elem, prop, orig[ prop ] );
- }
- });
- for ( prop in orig ) {
- tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
-
- if ( !( prop in dataShow ) ) {
- dataShow[ prop ] = tween.start;
- if ( hidden ) {
- tween.end = tween.start;
- tween.start = prop === "width" || prop === "height" ? 1 : 0;
- }
- }
- }
-
- // If this is a noop like .hide().hide(), restore an overwritten display value
- } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) {
- style.display = display;
- }
-}
-
-function propFilter( props, specialEasing ) {
- var index, name, easing, value, hooks;
-
- // camelCase, specialEasing and expand cssHook pass
- for ( index in props ) {
- name = jQuery.camelCase( index );
- easing = specialEasing[ name ];
- value = props[ index ];
- if ( jQuery.isArray( value ) ) {
- easing = value[ 1 ];
- value = props[ index ] = value[ 0 ];
- }
-
- if ( index !== name ) {
- props[ name ] = value;
- delete props[ index ];
- }
-
- hooks = jQuery.cssHooks[ name ];
- if ( hooks && "expand" in hooks ) {
- value = hooks.expand( value );
- delete props[ name ];
-
- // not quite $.extend, this wont overwrite keys already present.
- // also - reusing 'index' from above because we have the correct "name"
- for ( index in value ) {
- if ( !( index in props ) ) {
- props[ index ] = value[ index ];
- specialEasing[ index ] = easing;
- }
- }
- } else {
- specialEasing[ name ] = easing;
- }
- }
-}
-
-function Animation( elem, properties, options ) {
- var result,
- stopped,
- index = 0,
- length = animationPrefilters.length,
- deferred = jQuery.Deferred().always( function() {
- // don't match elem in the :animated selector
- delete tick.elem;
- }),
- tick = function() {
- if ( stopped ) {
- return false;
- }
- var currentTime = fxNow || createFxNow(),
- remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
- // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
- temp = remaining / animation.duration || 0,
- percent = 1 - temp,
- index = 0,
- length = animation.tweens.length;
-
- for ( ; index < length ; index++ ) {
- animation.tweens[ index ].run( percent );
- }
-
- deferred.notifyWith( elem, [ animation, percent, remaining ]);
-
- if ( percent < 1 && length ) {
- return remaining;
- } else {
- deferred.resolveWith( elem, [ animation ] );
- return false;
- }
- },
- animation = deferred.promise({
- elem: elem,
- props: jQuery.extend( {}, properties ),
- opts: jQuery.extend( true, { specialEasing: {} }, options ),
- originalProperties: properties,
- originalOptions: options,
- startTime: fxNow || createFxNow(),
- duration: options.duration,
- tweens: [],
- createTween: function( prop, end ) {
- var tween = jQuery.Tween( elem, animation.opts, prop, end,
- animation.opts.specialEasing[ prop ] || animation.opts.easing );
- animation.tweens.push( tween );
- return tween;
- },
- stop: function( gotoEnd ) {
- var index = 0,
- // if we are going to the end, we want to run all the tweens
- // otherwise we skip this part
- length = gotoEnd ? animation.tweens.length : 0;
- if ( stopped ) {
- return this;
- }
- stopped = true;
- for ( ; index < length ; index++ ) {
- animation.tweens[ index ].run( 1 );
- }
-
- // resolve when we played the last frame
- // otherwise, reject
- if ( gotoEnd ) {
- deferred.resolveWith( elem, [ animation, gotoEnd ] );
- } else {
- deferred.rejectWith( elem, [ animation, gotoEnd ] );
- }
- return this;
- }
- }),
- props = animation.props;
-
- propFilter( props, animation.opts.specialEasing );
-
- for ( ; index < length ; index++ ) {
- result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
- if ( result ) {
- return result;
- }
- }
-
- jQuery.map( props, createTween, animation );
-
- if ( jQuery.isFunction( animation.opts.start ) ) {
- animation.opts.start.call( elem, animation );
- }
-
- jQuery.fx.timer(
- jQuery.extend( tick, {
- elem: elem,
- anim: animation,
- queue: animation.opts.queue
- })
- );
-
- // attach callbacks from options
- return animation.progress( animation.opts.progress )
- .done( animation.opts.done, animation.opts.complete )
- .fail( animation.opts.fail )
- .always( animation.opts.always );
-}
-
-jQuery.Animation = jQuery.extend( Animation, {
- tweener: function( props, callback ) {
- if ( jQuery.isFunction( props ) ) {
- callback = props;
- props = [ "*" ];
- } else {
- props = props.split(" ");
- }
-
- var prop,
- index = 0,
- length = props.length;
-
- for ( ; index < length ; index++ ) {
- prop = props[ index ];
- tweeners[ prop ] = tweeners[ prop ] || [];
- tweeners[ prop ].unshift( callback );
- }
- },
-
- prefilter: function( callback, prepend ) {
- if ( prepend ) {
- animationPrefilters.unshift( callback );
- } else {
- animationPrefilters.push( callback );
- }
- }
-});
-
-jQuery.speed = function( speed, easing, fn ) {
- var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
- complete: fn || !fn && easing ||
- jQuery.isFunction( speed ) && speed,
- duration: speed,
- easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
- };
-
- opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
- opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
-
- // normalize opt.queue - true/undefined/null -> "fx"
- if ( opt.queue == null || opt.queue === true ) {
- opt.queue = "fx";
- }
-
- // Queueing
- opt.old = opt.complete;
-
- opt.complete = function() {
- if ( jQuery.isFunction( opt.old ) ) {
- opt.old.call( this );
- }
-
- if ( opt.queue ) {
- jQuery.dequeue( this, opt.queue );
- }
- };
-
- return opt;
-};
-
-jQuery.fn.extend({
- fadeTo: function( speed, to, easing, callback ) {
-
- // show any hidden elements after setting opacity to 0
- return this.filter( isHidden ).css( "opacity", 0 ).show()
-
- // animate to the value specified
- .end().animate({ opacity: to }, speed, easing, callback );
- },
- animate: function( prop, speed, easing, callback ) {
- var empty = jQuery.isEmptyObject( prop ),
- optall = jQuery.speed( speed, easing, callback ),
- doAnimation = function() {
- // Operate on a copy of prop so per-property easing won't be lost
- var anim = Animation( this, jQuery.extend( {}, prop ), optall );
-
- // Empty animations, or finishing resolves immediately
- if ( empty || jQuery._data( this, "finish" ) ) {
- anim.stop( true );
- }
- };
- doAnimation.finish = doAnimation;
-
- return empty || optall.queue === false ?
- this.each( doAnimation ) :
- this.queue( optall.queue, doAnimation );
- },
- stop: function( type, clearQueue, gotoEnd ) {
- var stopQueue = function( hooks ) {
- var stop = hooks.stop;
- delete hooks.stop;
- stop( gotoEnd );
- };
-
- if ( typeof type !== "string" ) {
- gotoEnd = clearQueue;
- clearQueue = type;
- type = undefined;
- }
- if ( clearQueue && type !== false ) {
- this.queue( type || "fx", [] );
- }
-
- return this.each(function() {
- var dequeue = true,
- index = type != null && type + "queueHooks",
- timers = jQuery.timers,
- data = jQuery._data( this );
-
- if ( index ) {
- if ( data[ index ] && data[ index ].stop ) {
- stopQueue( data[ index ] );
- }
- } else {
- for ( index in data ) {
- if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
- stopQueue( data[ index ] );
- }
- }
- }
-
- for ( index = timers.length; index--; ) {
- if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
- timers[ index ].anim.stop( gotoEnd );
- dequeue = false;
- timers.splice( index, 1 );
- }
- }
-
- // start the next in the queue if the last step wasn't forced
- // timers currently will call their complete callbacks, which will dequeue
- // but only if they were gotoEnd
- if ( dequeue || !gotoEnd ) {
- jQuery.dequeue( this, type );
- }
- });
- },
- finish: function( type ) {
- if ( type !== false ) {
- type = type || "fx";
- }
- return this.each(function() {
- var index,
- data = jQuery._data( this ),
- queue = data[ type + "queue" ],
- hooks = data[ type + "queueHooks" ],
- timers = jQuery.timers,
- length = queue ? queue.length : 0;
-
- // enable finishing flag on private data
- data.finish = true;
-
- // empty the queue first
- jQuery.queue( this, type, [] );
-
- if ( hooks && hooks.stop ) {
- hooks.stop.call( this, true );
- }
-
- // look for any active animations, and finish them
- for ( index = timers.length; index--; ) {
- if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
- timers[ index ].anim.stop( true );
- timers.splice( index, 1 );
- }
- }
-
- // look for any animations in the old queue and finish them
- for ( index = 0; index < length; index++ ) {
- if ( queue[ index ] && queue[ index ].finish ) {
- queue[ index ].finish.call( this );
- }
- }
-
- // turn off finishing flag
- delete data.finish;
- });
- }
-});
-
-jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
- var cssFn = jQuery.fn[ name ];
- jQuery.fn[ name ] = function( speed, easing, callback ) {
- return speed == null || typeof speed === "boolean" ?
- cssFn.apply( this, arguments ) :
- this.animate( genFx( name, true ), speed, easing, callback );
- };
-});
-
-// Generate shortcuts for custom animations
-jQuery.each({
- slideDown: genFx("show"),
- slideUp: genFx("hide"),
- slideToggle: genFx("toggle"),
- fadeIn: { opacity: "show" },
- fadeOut: { opacity: "hide" },
- fadeToggle: { opacity: "toggle" }
-}, function( name, props ) {
- jQuery.fn[ name ] = function( speed, easing, callback ) {
- return this.animate( props, speed, easing, callback );
- };
-});
-
-jQuery.timers = [];
-jQuery.fx.tick = function() {
- var timer,
- timers = jQuery.timers,
- i = 0;
-
- fxNow = jQuery.now();
-
- for ( ; i < timers.length; i++ ) {
- timer = timers[ i ];
- // Checks the timer has not already been removed
- if ( !timer() && timers[ i ] === timer ) {
- timers.splice( i--, 1 );
- }
- }
-
- if ( !timers.length ) {
- jQuery.fx.stop();
- }
- fxNow = undefined;
-};
-
-jQuery.fx.timer = function( timer ) {
- jQuery.timers.push( timer );
- if ( timer() ) {
- jQuery.fx.start();
- } else {
- jQuery.timers.pop();
- }
-};
-
-jQuery.fx.interval = 13;
-
-jQuery.fx.start = function() {
- if ( !timerId ) {
- timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
- }
-};
-
-jQuery.fx.stop = function() {
- clearInterval( timerId );
- timerId = null;
-};
-
-jQuery.fx.speeds = {
- slow: 600,
- fast: 200,
- // Default speed
- _default: 400
-};
-
-
-// Based off of the plugin by Clint Helfers, with permission.
-// http://blindsignals.com/index.php/2009/07/jquery-delay/
-jQuery.fn.delay = function( time, type ) {
- time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
- type = type || "fx";
-
- return this.queue( type, function( next, hooks ) {
- var timeout = setTimeout( next, time );
- hooks.stop = function() {
- clearTimeout( timeout );
- };
- });
-};
-
-
-(function() {
- // Minified: var a,b,c,d,e
- var input, div, select, a, opt;
-
- // Setup
- div = document.createElement( "div" );
- div.setAttribute( "className", "t" );
- div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
- a = div.getElementsByTagName("a")[ 0 ];
-
- // First batch of tests.
- select = document.createElement("select");
- opt = select.appendChild( document.createElement("option") );
- input = div.getElementsByTagName("input")[ 0 ];
-
- a.style.cssText = "top:1px";
-
- // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
- support.getSetAttribute = div.className !== "t";
-
- // Get the style information from getAttribute
- // (IE uses .cssText instead)
- support.style = /top/.test( a.getAttribute("style") );
-
- // Make sure that URLs aren't manipulated
- // (IE normalizes it by default)
- support.hrefNormalized = a.getAttribute("href") === "/a";
-
- // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
- support.checkOn = !!input.value;
-
- // Make sure that a selected-by-default option has a working selected property.
- // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
- support.optSelected = opt.selected;
-
- // Tests for enctype support on a form (#6743)
- support.enctype = !!document.createElement("form").enctype;
-
- // Make sure that the options inside disabled selects aren't marked as disabled
- // (WebKit marks them as disabled)
- select.disabled = true;
- support.optDisabled = !opt.disabled;
-
- // Support: IE8 only
- // Check if we can trust getAttribute("value")
- input = document.createElement( "input" );
- input.setAttribute( "value", "" );
- support.input = input.getAttribute( "value" ) === "";
-
- // Check if an input maintains its value after becoming a radio
- input.value = "t";
- input.setAttribute( "type", "radio" );
- support.radioValue = input.value === "t";
-})();
-
-
-var rreturn = /\r/g;
-
-jQuery.fn.extend({
- val: function( value ) {
- var hooks, ret, isFunction,
- elem = this[0];
-
- if ( !arguments.length ) {
- if ( elem ) {
- hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
-
- if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
- return ret;
- }
-
- ret = elem.value;
-
- return typeof ret === "string" ?
- // handle most common string cases
- ret.replace(rreturn, "") :
- // handle cases where value is null/undef or number
- ret == null ? "" : ret;
- }
-
- return;
- }
-
- isFunction = jQuery.isFunction( value );
-
- return this.each(function( i ) {
- var val;
-
- if ( this.nodeType !== 1 ) {
- return;
- }
-
- if ( isFunction ) {
- val = value.call( this, i, jQuery( this ).val() );
- } else {
- val = value;
- }
-
- // Treat null/undefined as ""; convert numbers to string
- if ( val == null ) {
- val = "";
- } else if ( typeof val === "number" ) {
- val += "";
- } else if ( jQuery.isArray( val ) ) {
- val = jQuery.map( val, function( value ) {
- return value == null ? "" : value + "";
- });
- }
-
- hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
-
- // If set returns undefined, fall back to normal setting
- if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
- this.value = val;
- }
- });
- }
-});
-
-jQuery.extend({
- valHooks: {
- option: {
- get: function( elem ) {
- var val = jQuery.find.attr( elem, "value" );
- return val != null ?
- val :
- // Support: IE10-11+
- // option.text throws exceptions (#14686, #14858)
- jQuery.trim( jQuery.text( elem ) );
- }
- },
- select: {
- get: function( elem ) {
- var value, option,
- options = elem.options,
- index = elem.selectedIndex,
- one = elem.type === "select-one" || index < 0,
- values = one ? null : [],
- max = one ? index + 1 : options.length,
- i = index < 0 ?
- max :
- one ? index : 0;
-
- // Loop through all the selected options
- for ( ; i < max; i++ ) {
- option = options[ i ];
-
- // oldIE doesn't update selected after form reset (#2551)
- if ( ( option.selected || i === index ) &&
- // Don't return options that are disabled or in a disabled optgroup
- ( support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
- ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
-
- // Get the specific value for the option
- value = jQuery( option ).val();
-
- // We don't need an array for one selects
- if ( one ) {
- return value;
- }
-
- // Multi-Selects return an array
- values.push( value );
- }
- }
-
- return values;
- },
-
- set: function( elem, value ) {
- var optionSet, option,
- options = elem.options,
- values = jQuery.makeArray( value ),
- i = options.length;
-
- while ( i-- ) {
- option = options[ i ];
-
- if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {
-
- // Support: IE6
- // When new option element is added to select box we need to
- // force reflow of newly added node in order to workaround delay
- // of initialization properties
- try {
- option.selected = optionSet = true;
-
- } catch ( _ ) {
-
- // Will be executed only in IE6
- option.scrollHeight;
- }
-
- } else {
- option.selected = false;
- }
- }
-
- // Force browsers to behave consistently when non-matching value is set
- if ( !optionSet ) {
- elem.selectedIndex = -1;
- }
-
- return options;
- }
- }
- }
-});
-
-// Radios and checkboxes getter/setter
-jQuery.each([ "radio", "checkbox" ], function() {
- jQuery.valHooks[ this ] = {
- set: function( elem, value ) {
- if ( jQuery.isArray( value ) ) {
- return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
- }
- }
- };
- if ( !support.checkOn ) {
- jQuery.valHooks[ this ].get = function( elem ) {
- // Support: Webkit
- // "" is returned instead of "on" if a value isn't specified
- return elem.getAttribute("value") === null ? "on" : elem.value;
- };
- }
-});
-
-
-
-
-var nodeHook, boolHook,
- attrHandle = jQuery.expr.attrHandle,
- ruseDefault = /^(?:checked|selected)$/i,
- getSetAttribute = support.getSetAttribute,
- getSetInput = support.input;
-
-jQuery.fn.extend({
- attr: function( name, value ) {
- return access( this, jQuery.attr, name, value, arguments.length > 1 );
- },
-
- removeAttr: function( name ) {
- return this.each(function() {
- jQuery.removeAttr( this, name );
- });
- }
-});
-
-jQuery.extend({
- attr: function( elem, name, value ) {
- var hooks, ret,
- nType = elem.nodeType;
-
- // don't get/set attributes on text, comment and attribute nodes
- if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
- return;
- }
-
- // Fallback to prop when attributes are not supported
- if ( typeof elem.getAttribute === strundefined ) {
- return jQuery.prop( elem, name, value );
- }
-
- // All attributes are lowercase
- // Grab necessary hook if one is defined
- if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
- name = name.toLowerCase();
- hooks = jQuery.attrHooks[ name ] ||
- ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
- }
-
- if ( value !== undefined ) {
-
- if ( value === null ) {
- jQuery.removeAttr( elem, name );
-
- } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
- return ret;
-
- } else {
- elem.setAttribute( name, value + "" );
- return value;
- }
-
- } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
- return ret;
-
- } else {
- ret = jQuery.find.attr( elem, name );
-
- // Non-existent attributes return null, we normalize to undefined
- return ret == null ?
- undefined :
- ret;
- }
- },
-
- removeAttr: function( elem, value ) {
- var name, propName,
- i = 0,
- attrNames = value && value.match( rnotwhite );
-
- if ( attrNames && elem.nodeType === 1 ) {
- while ( (name = attrNames[i++]) ) {
- propName = jQuery.propFix[ name ] || name;
-
- // Boolean attributes get special treatment (#10870)
- if ( jQuery.expr.match.bool.test( name ) ) {
- // Set corresponding property to false
- if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
- elem[ propName ] = false;
- // Support: IE<9
- // Also clear defaultChecked/defaultSelected (if appropriate)
- } else {
- elem[ jQuery.camelCase( "default-" + name ) ] =
- elem[ propName ] = false;
- }
-
- // See #9699 for explanation of this approach (setting first, then removal)
- } else {
- jQuery.attr( elem, name, "" );
- }
-
- elem.removeAttribute( getSetAttribute ? name : propName );
- }
- }
- },
-
- attrHooks: {
- type: {
- set: function( elem, value ) {
- if ( !support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
- // Setting the type on a radio button after the value resets the value in IE6-9
- // Reset value to default in case type is set after value during creation
- var val = elem.value;
- elem.setAttribute( "type", value );
- if ( val ) {
- elem.value = val;
- }
- return value;
- }
- }
- }
- }
-});
-
-// Hook for boolean attributes
-boolHook = {
- set: function( elem, value, name ) {
- if ( value === false ) {
- // Remove boolean attributes when set to false
- jQuery.removeAttr( elem, name );
- } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
- // IE<8 needs the *property* name
- elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
-
- // Use defaultChecked and defaultSelected for oldIE
- } else {
- elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
- }
-
- return name;
- }
-};
-
-// Retrieve booleans specially
-jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
-
- var getter = attrHandle[ name ] || jQuery.find.attr;
-
- attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?
- function( elem, name, isXML ) {
- var ret, handle;
- if ( !isXML ) {
- // Avoid an infinite loop by temporarily removing this function from the getter
- handle = attrHandle[ name ];
- attrHandle[ name ] = ret;
- ret = getter( elem, name, isXML ) != null ?
- name.toLowerCase() :
- null;
- attrHandle[ name ] = handle;
- }
- return ret;
- } :
- function( elem, name, isXML ) {
- if ( !isXML ) {
- return elem[ jQuery.camelCase( "default-" + name ) ] ?
- name.toLowerCase() :
- null;
- }
- };
-});
-
-// fix oldIE attroperties
-if ( !getSetInput || !getSetAttribute ) {
- jQuery.attrHooks.value = {
- set: function( elem, value, name ) {
- if ( jQuery.nodeName( elem, "input" ) ) {
- // Does not return so that setAttribute is also used
- elem.defaultValue = value;
- } else {
- // Use nodeHook if defined (#1954); otherwise setAttribute is fine
- return nodeHook && nodeHook.set( elem, value, name );
- }
- }
- };
-}
-
-// IE6/7 do not support getting/setting some attributes with get/setAttribute
-if ( !getSetAttribute ) {
-
- // Use this for any attribute in IE6/7
- // This fixes almost every IE6/7 issue
- nodeHook = {
- set: function( elem, value, name ) {
- // Set the existing or create a new attribute node
- var ret = elem.getAttributeNode( name );
- if ( !ret ) {
- elem.setAttributeNode(
- (ret = elem.ownerDocument.createAttribute( name ))
- );
- }
-
- ret.value = value += "";
-
- // Break association with cloned elements by also using setAttribute (#9646)
- if ( name === "value" || value === elem.getAttribute( name ) ) {
- return value;
- }
- }
- };
-
- // Some attributes are constructed with empty-string values when not defined
- attrHandle.id = attrHandle.name = attrHandle.coords =
- function( elem, name, isXML ) {
- var ret;
- if ( !isXML ) {
- return (ret = elem.getAttributeNode( name )) && ret.value !== "" ?
- ret.value :
- null;
- }
- };
-
- // Fixing value retrieval on a button requires this module
- jQuery.valHooks.button = {
- get: function( elem, name ) {
- var ret = elem.getAttributeNode( name );
- if ( ret && ret.specified ) {
- return ret.value;
- }
- },
- set: nodeHook.set
- };
-
- // Set contenteditable to false on removals(#10429)
- // Setting to empty string throws an error as an invalid value
- jQuery.attrHooks.contenteditable = {
- set: function( elem, value, name ) {
- nodeHook.set( elem, value === "" ? false : value, name );
- }
- };
-
- // Set width and height to auto instead of 0 on empty string( Bug #8150 )
- // This is for removals
- jQuery.each([ "width", "height" ], function( i, name ) {
- jQuery.attrHooks[ name ] = {
- set: function( elem, value ) {
- if ( value === "" ) {
- elem.setAttribute( name, "auto" );
- return value;
- }
- }
- };
- });
-}
-
-if ( !support.style ) {
- jQuery.attrHooks.style = {
- get: function( elem ) {
- // Return undefined in the case of empty string
- // Note: IE uppercases css property names, but if we were to .toLowerCase()
- // .cssText, that would destroy case senstitivity in URL's, like in "background"
- return elem.style.cssText || undefined;
- },
- set: function( elem, value ) {
- return ( elem.style.cssText = value + "" );
- }
- };
-}
-
-
-
-
-var rfocusable = /^(?:input|select|textarea|button|object)$/i,
- rclickable = /^(?:a|area)$/i;
-
-jQuery.fn.extend({
- prop: function( name, value ) {
- return access( this, jQuery.prop, name, value, arguments.length > 1 );
- },
-
- removeProp: function( name ) {
- name = jQuery.propFix[ name ] || name;
- return this.each(function() {
- // try/catch handles cases where IE balks (such as removing a property on window)
- try {
- this[ name ] = undefined;
- delete this[ name ];
- } catch( e ) {}
- });
- }
-});
-
-jQuery.extend({
- propFix: {
- "for": "htmlFor",
- "class": "className"
- },
-
- prop: function( elem, name, value ) {
- var ret, hooks, notxml,
- nType = elem.nodeType;
-
- // don't get/set properties on text, comment and attribute nodes
- if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
- return;
- }
-
- notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
-
- if ( notxml ) {
- // Fix name and attach hooks
- name = jQuery.propFix[ name ] || name;
- hooks = jQuery.propHooks[ name ];
- }
-
- if ( value !== undefined ) {
- return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
- ret :
- ( elem[ name ] = value );
-
- } else {
- return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
- ret :
- elem[ name ];
- }
- },
-
- propHooks: {
- tabIndex: {
- get: function( elem ) {
- // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
- // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
- // Use proper attribute retrieval(#12072)
- var tabindex = jQuery.find.attr( elem, "tabindex" );
-
- return tabindex ?
- parseInt( tabindex, 10 ) :
- rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
- 0 :
- -1;
- }
- }
- }
-});
-
-// Some attributes require a special call on IE
-// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
-if ( !support.hrefNormalized ) {
- // href/src property should get the full normalized URL (#10299/#12915)
- jQuery.each([ "href", "src" ], function( i, name ) {
- jQuery.propHooks[ name ] = {
- get: function( elem ) {
- return elem.getAttribute( name, 4 );
- }
- };
- });
-}
-
-// Support: Safari, IE9+
-// mis-reports the default selected property of an option
-// Accessing the parent's selectedIndex property fixes it
-if ( !support.optSelected ) {
- jQuery.propHooks.selected = {
- get: function( elem ) {
- var parent = elem.parentNode;
-
- if ( parent ) {
- parent.selectedIndex;
-
- // Make sure that it also works with optgroups, see #5701
- if ( parent.parentNode ) {
- parent.parentNode.selectedIndex;
- }
- }
- return null;
- }
- };
-}
-
-jQuery.each([
- "tabIndex",
- "readOnly",
- "maxLength",
- "cellSpacing",
- "cellPadding",
- "rowSpan",
- "colSpan",
- "useMap",
- "frameBorder",
- "contentEditable"
-], function() {
- jQuery.propFix[ this.toLowerCase() ] = this;
-});
-
-// IE6/7 call enctype encoding
-if ( !support.enctype ) {
- jQuery.propFix.enctype = "encoding";
-}
-
-
-
-
-var rclass = /[\t\r\n\f]/g;
-
-jQuery.fn.extend({
- addClass: function( value ) {
- var classes, elem, cur, clazz, j, finalValue,
- i = 0,
- len = this.length,
- proceed = typeof value === "string" && value;
-
- if ( jQuery.isFunction( value ) ) {
- return this.each(function( j ) {
- jQuery( this ).addClass( value.call( this, j, this.className ) );
- });
- }
-
- if ( proceed ) {
- // The disjunction here is for better compressibility (see removeClass)
- classes = ( value || "" ).match( rnotwhite ) || [];
-
- for ( ; i < len; i++ ) {
- elem = this[ i ];
- cur = elem.nodeType === 1 && ( elem.className ?
- ( " " + elem.className + " " ).replace( rclass, " " ) :
- " "
- );
-
- if ( cur ) {
- j = 0;
- while ( (clazz = classes[j++]) ) {
- if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
- cur += clazz + " ";
- }
- }
-
- // only assign if different to avoid unneeded rendering.
- finalValue = jQuery.trim( cur );
- if ( elem.className !== finalValue ) {
- elem.className = finalValue;
- }
- }
- }
- }
-
- return this;
- },
-
- removeClass: function( value ) {
- var classes, elem, cur, clazz, j, finalValue,
- i = 0,
- len = this.length,
- proceed = arguments.length === 0 || typeof value === "string" && value;
-
- if ( jQuery.isFunction( value ) ) {
- return this.each(function( j ) {
- jQuery( this ).removeClass( value.call( this, j, this.className ) );
- });
- }
- if ( proceed ) {
- classes = ( value || "" ).match( rnotwhite ) || [];
-
- for ( ; i < len; i++ ) {
- elem = this[ i ];
- // This expression is here for better compressibility (see addClass)
- cur = elem.nodeType === 1 && ( elem.className ?
- ( " " + elem.className + " " ).replace( rclass, " " ) :
- ""
- );
-
- if ( cur ) {
- j = 0;
- while ( (clazz = classes[j++]) ) {
- // Remove *all* instances
- while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
- cur = cur.replace( " " + clazz + " ", " " );
- }
- }
-
- // only assign if different to avoid unneeded rendering.
- finalValue = value ? jQuery.trim( cur ) : "";
- if ( elem.className !== finalValue ) {
- elem.className = finalValue;
- }
- }
- }
- }
-
- return this;
- },
-
- toggleClass: function( value, stateVal ) {
- var type = typeof value;
-
- if ( typeof stateVal === "boolean" && type === "string" ) {
- return stateVal ? this.addClass( value ) : this.removeClass( value );
- }
-
- if ( jQuery.isFunction( value ) ) {
- return this.each(function( i ) {
- jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
- });
- }
-
- return this.each(function() {
- if ( type === "string" ) {
- // toggle individual class names
- var className,
- i = 0,
- self = jQuery( this ),
- classNames = value.match( rnotwhite ) || [];
-
- while ( (className = classNames[ i++ ]) ) {
- // check each className given, space separated list
- if ( self.hasClass( className ) ) {
- self.removeClass( className );
- } else {
- self.addClass( className );
- }
- }
-
- // Toggle whole class name
- } else if ( type === strundefined || type === "boolean" ) {
- if ( this.className ) {
- // store className if set
- jQuery._data( this, "__className__", this.className );
- }
-
- // If the element has a class name or if we're passed "false",
- // then remove the whole classname (if there was one, the above saved it).
- // Otherwise bring back whatever was previously saved (if anything),
- // falling back to the empty string if nothing was stored.
- this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || "";
- }
- });
- },
-
- hasClass: function( selector ) {
- var className = " " + selector + " ",
- i = 0,
- l = this.length;
- for ( ; i < l; i++ ) {
- if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
- return true;
- }
- }
-
- return false;
- }
-});
-
-
-
-
-// Return jQuery for attributes-only inclusion
-
-
-jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
- "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
- "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
-
- // Handle event binding
- jQuery.fn[ name ] = function( data, fn ) {
- return arguments.length > 0 ?
- this.on( name, null, data, fn ) :
- this.trigger( name );
- };
-});
-
-jQuery.fn.extend({
- hover: function( fnOver, fnOut ) {
- return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
- },
-
- bind: function( types, data, fn ) {
- return this.on( types, null, data, fn );
- },
- unbind: function( types, fn ) {
- return this.off( types, null, fn );
- },
-
- delegate: function( selector, types, data, fn ) {
- return this.on( types, selector, data, fn );
- },
- undelegate: function( selector, types, fn ) {
- // ( namespace ) or ( selector, types [, fn] )
- return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
- }
-});
-
-
-var nonce = jQuery.now();
-
-var rquery = (/\?/);
-
-
-
-var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;
-
-jQuery.parseJSON = function( data ) {
- // Attempt to parse using the native JSON parser first
- if ( window.JSON && window.JSON.parse ) {
- // Support: Android 2.3
- // Workaround failure to string-cast null input
- return window.JSON.parse( data + "" );
- }
-
- var requireNonComma,
- depth = null,
- str = jQuery.trim( data + "" );
-
- // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains
- // after removing valid tokens
- return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {
-
- // Force termination if we see a misplaced comma
- if ( requireNonComma && comma ) {
- depth = 0;
- }
-
- // Perform no more replacements after returning to outermost depth
- if ( depth === 0 ) {
- return token;
- }
-
- // Commas must not follow "[", "{", or ","
- requireNonComma = open || comma;
-
- // Determine new depth
- // array/object open ("[" or "{"): depth += true - false (increment)
- // array/object close ("]" or "}"): depth += false - true (decrement)
- // other cases ("," or primitive): depth += true - true (numeric cast)
- depth += !close - !open;
-
- // Remove this token
- return "";
- }) ) ?
- ( Function( "return " + str ) )() :
- jQuery.error( "Invalid JSON: " + data );
-};
-
-
-// Cross-browser xml parsing
-jQuery.parseXML = function( data ) {
- var xml, tmp;
- if ( !data || typeof data !== "string" ) {
- return null;
- }
- try {
- if ( window.DOMParser ) { // Standard
- tmp = new DOMParser();
- xml = tmp.parseFromString( data, "text/xml" );
- } else { // IE
- xml = new ActiveXObject( "Microsoft.XMLDOM" );
- xml.async = "false";
- xml.loadXML( data );
- }
- } catch( e ) {
- xml = undefined;
- }
- if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) {
- jQuery.error( "Invalid XML: " + data );
- }
- return xml;
-};
-
-
-var
- // Document location
- ajaxLocParts,
- ajaxLocation,
-
- rhash = /#.*$/,
- rts = /([?&])_=[^&]*/,
- rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL
- // #7653, #8125, #8152: local protocol detection
- rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
- rnoContent = /^(?:GET|HEAD)$/,
- rprotocol = /^\/\//,
- rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,
-
- /* Prefilters
- * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
- * 2) These are called:
- * - BEFORE asking for a transport
- * - AFTER param serialization (s.data is a string if s.processData is true)
- * 3) key is the dataType
- * 4) the catchall symbol "*" can be used
- * 5) execution will start with transport dataType and THEN continue down to "*" if needed
- */
- prefilters = {},
-
- /* Transports bindings
- * 1) key is the dataType
- * 2) the catchall symbol "*" can be used
- * 3) selection will start with transport dataType and THEN go to "*" if needed
- */
- transports = {},
-
- // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
- allTypes = "*/".concat("*");
-
-// #8138, IE may throw an exception when accessing
-// a field from window.location if document.domain has been set
-try {
- ajaxLocation = location.href;
-} catch( e ) {
- // Use the href attribute of an A element
- // since IE will modify it given document.location
- ajaxLocation = document.createElement( "a" );
- ajaxLocation.href = "";
- ajaxLocation = ajaxLocation.href;
-}
-
-// Segment location into parts
-ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
-
-// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
-function addToPrefiltersOrTransports( structure ) {
-
- // dataTypeExpression is optional and defaults to "*"
- return function( dataTypeExpression, func ) {
-
- if ( typeof dataTypeExpression !== "string" ) {
- func = dataTypeExpression;
- dataTypeExpression = "*";
- }
-
- var dataType,
- i = 0,
- dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];
-
- if ( jQuery.isFunction( func ) ) {
- // For each dataType in the dataTypeExpression
- while ( (dataType = dataTypes[i++]) ) {
- // Prepend if requested
- if ( dataType.charAt( 0 ) === "+" ) {
- dataType = dataType.slice( 1 ) || "*";
- (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
-
- // Otherwise append
- } else {
- (structure[ dataType ] = structure[ dataType ] || []).push( func );
- }
- }
- }
- };
-}
-
-// Base inspection function for prefilters and transports
-function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
-
- var inspected = {},
- seekingTransport = ( structure === transports );
-
- function inspect( dataType ) {
- var selected;
- inspected[ dataType ] = true;
- jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
- var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
- if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
- options.dataTypes.unshift( dataTypeOrTransport );
- inspect( dataTypeOrTransport );
- return false;
- } else if ( seekingTransport ) {
- return !( selected = dataTypeOrTransport );
- }
- });
- return selected;
- }
-
- return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
-}
-
-// A special extend for ajax options
-// that takes "flat" options (not to be deep extended)
-// Fixes #9887
-function ajaxExtend( target, src ) {
- var deep, key,
- flatOptions = jQuery.ajaxSettings.flatOptions || {};
-
- for ( key in src ) {
- if ( src[ key ] !== undefined ) {
- ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
- }
- }
- if ( deep ) {
- jQuery.extend( true, target, deep );
- }
-
- return target;
-}
-
-/* Handles responses to an ajax request:
- * - finds the right dataType (mediates between content-type and expected dataType)
- * - returns the corresponding response
- */
-function ajaxHandleResponses( s, jqXHR, responses ) {
- var firstDataType, ct, finalDataType, type,
- contents = s.contents,
- dataTypes = s.dataTypes;
-
- // Remove auto dataType and get content-type in the process
- while ( dataTypes[ 0 ] === "*" ) {
- dataTypes.shift();
- if ( ct === undefined ) {
- ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
- }
- }
-
- // Check if we're dealing with a known content-type
- if ( ct ) {
- for ( type in contents ) {
- if ( contents[ type ] && contents[ type ].test( ct ) ) {
- dataTypes.unshift( type );
- break;
- }
- }
- }
-
- // Check to see if we have a response for the expected dataType
- if ( dataTypes[ 0 ] in responses ) {
- finalDataType = dataTypes[ 0 ];
- } else {
- // Try convertible dataTypes
- for ( type in responses ) {
- if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
- finalDataType = type;
- break;
- }
- if ( !firstDataType ) {
- firstDataType = type;
- }
- }
- // Or just use first one
- finalDataType = finalDataType || firstDataType;
- }
-
- // If we found a dataType
- // We add the dataType to the list if needed
- // and return the corresponding response
- if ( finalDataType ) {
- if ( finalDataType !== dataTypes[ 0 ] ) {
- dataTypes.unshift( finalDataType );
- }
- return responses[ finalDataType ];
- }
-}
-
-/* Chain conversions given the request and the original response
- * Also sets the responseXXX fields on the jqXHR instance
- */
-function ajaxConvert( s, response, jqXHR, isSuccess ) {
- var conv2, current, conv, tmp, prev,
- converters = {},
- // Work with a copy of dataTypes in case we need to modify it for conversion
- dataTypes = s.dataTypes.slice();
-
- // Create converters map with lowercased keys
- if ( dataTypes[ 1 ] ) {
- for ( conv in s.converters ) {
- converters[ conv.toLowerCase() ] = s.converters[ conv ];
- }
- }
-
- current = dataTypes.shift();
-
- // Convert to each sequential dataType
- while ( current ) {
-
- if ( s.responseFields[ current ] ) {
- jqXHR[ s.responseFields[ current ] ] = response;
- }
-
- // Apply the dataFilter if provided
- if ( !prev && isSuccess && s.dataFilter ) {
- response = s.dataFilter( response, s.dataType );
- }
-
- prev = current;
- current = dataTypes.shift();
-
- if ( current ) {
-
- // There's only work to do if current dataType is non-auto
- if ( current === "*" ) {
-
- current = prev;
-
- // Convert response if prev dataType is non-auto and differs from current
- } else if ( prev !== "*" && prev !== current ) {
-
- // Seek a direct converter
- conv = converters[ prev + " " + current ] || converters[ "* " + current ];
-
- // If none found, seek a pair
- if ( !conv ) {
- for ( conv2 in converters ) {
-
- // If conv2 outputs current
- tmp = conv2.split( " " );
- if ( tmp[ 1 ] === current ) {
-
- // If prev can be converted to accepted input
- conv = converters[ prev + " " + tmp[ 0 ] ] ||
- converters[ "* " + tmp[ 0 ] ];
- if ( conv ) {
- // Condense equivalence converters
- if ( conv === true ) {
- conv = converters[ conv2 ];
-
- // Otherwise, insert the intermediate dataType
- } else if ( converters[ conv2 ] !== true ) {
- current = tmp[ 0 ];
- dataTypes.unshift( tmp[ 1 ] );
- }
- break;
- }
- }
- }
- }
-
- // Apply converter (if not an equivalence)
- if ( conv !== true ) {
-
- // Unless errors are allowed to bubble, catch and return them
- if ( conv && s[ "throws" ] ) {
- response = conv( response );
- } else {
- try {
- response = conv( response );
- } catch ( e ) {
- return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
- }
- }
- }
- }
- }
- }
-
- return { state: "success", data: response };
-}
-
-jQuery.extend({
-
- // Counter for holding the number of active queries
- active: 0,
-
- // Last-Modified header cache for next request
- lastModified: {},
- etag: {},
-
- ajaxSettings: {
- url: ajaxLocation,
- type: "GET",
- isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
- global: true,
- processData: true,
- async: true,
- contentType: "application/x-www-form-urlencoded; charset=UTF-8",
- /*
- timeout: 0,
- data: null,
- dataType: null,
- username: null,
- password: null,
- cache: null,
- throws: false,
- traditional: false,
- headers: {},
- */
-
- accepts: {
- "*": allTypes,
- text: "text/plain",
- html: "text/html",
- xml: "application/xml, text/xml",
- json: "application/json, text/javascript"
- },
-
- contents: {
- xml: /xml/,
- html: /html/,
- json: /json/
- },
-
- responseFields: {
- xml: "responseXML",
- text: "responseText",
- json: "responseJSON"
- },
-
- // Data converters
- // Keys separate source (or catchall "*") and destination types with a single space
- converters: {
-
- // Convert anything to text
- "* text": String,
-
- // Text to html (true = no transformation)
- "text html": true,
-
- // Evaluate text as a json expression
- "text json": jQuery.parseJSON,
-
- // Parse text as xml
- "text xml": jQuery.parseXML
- },
-
- // For options that shouldn't be deep extended:
- // you can add your own custom options here if
- // and when you create one that shouldn't be
- // deep extended (see ajaxExtend)
- flatOptions: {
- url: true,
- context: true
- }
- },
-
- // Creates a full fledged settings object into target
- // with both ajaxSettings and settings fields.
- // If target is omitted, writes into ajaxSettings.
- ajaxSetup: function( target, settings ) {
- return settings ?
-
- // Building a settings object
- ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
-
- // Extending ajaxSettings
- ajaxExtend( jQuery.ajaxSettings, target );
- },
-
- ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
- ajaxTransport: addToPrefiltersOrTransports( transports ),
-
- // Main method
- ajax: function( url, options ) {
-
- // If url is an object, simulate pre-1.5 signature
- if ( typeof url === "object" ) {
- options = url;
- url = undefined;
- }
-
- // Force options to be an object
- options = options || {};
-
- var // Cross-domain detection vars
- parts,
- // Loop variable
- i,
- // URL without anti-cache param
- cacheURL,
- // Response headers as string
- responseHeadersString,
- // timeout handle
- timeoutTimer,
-
- // To know if global events are to be dispatched
- fireGlobals,
-
- transport,
- // Response headers
- responseHeaders,
- // Create the final options object
- s = jQuery.ajaxSetup( {}, options ),
- // Callbacks context
- callbackContext = s.context || s,
- // Context for global events is callbackContext if it is a DOM node or jQuery collection
- globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
- jQuery( callbackContext ) :
- jQuery.event,
- // Deferreds
- deferred = jQuery.Deferred(),
- completeDeferred = jQuery.Callbacks("once memory"),
- // Status-dependent callbacks
- statusCode = s.statusCode || {},
- // Headers (they are sent all at once)
- requestHeaders = {},
- requestHeadersNames = {},
- // The jqXHR state
- state = 0,
- // Default abort message
- strAbort = "canceled",
- // Fake xhr
- jqXHR = {
- readyState: 0,
-
- // Builds headers hashtable if needed
- getResponseHeader: function( key ) {
- var match;
- if ( state === 2 ) {
- if ( !responseHeaders ) {
- responseHeaders = {};
- while ( (match = rheaders.exec( responseHeadersString )) ) {
- responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
- }
- }
- match = responseHeaders[ key.toLowerCase() ];
- }
- return match == null ? null : match;
- },
-
- // Raw string
- getAllResponseHeaders: function() {
- return state === 2 ? responseHeadersString : null;
- },
-
- // Caches the header
- setRequestHeader: function( name, value ) {
- var lname = name.toLowerCase();
- if ( !state ) {
- name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
- requestHeaders[ name ] = value;
- }
- return this;
- },
-
- // Overrides response content-type header
- overrideMimeType: function( type ) {
- if ( !state ) {
- s.mimeType = type;
- }
- return this;
- },
-
- // Status-dependent callbacks
- statusCode: function( map ) {
- var code;
- if ( map ) {
- if ( state < 2 ) {
- for ( code in map ) {
- // Lazy-add the new callback in a way that preserves old ones
- statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
- }
- } else {
- // Execute the appropriate callbacks
- jqXHR.always( map[ jqXHR.status ] );
- }
- }
- return this;
- },
-
- // Cancel the request
- abort: function( statusText ) {
- var finalText = statusText || strAbort;
- if ( transport ) {
- transport.abort( finalText );
- }
- done( 0, finalText );
- return this;
- }
- };
-
- // Attach deferreds
- deferred.promise( jqXHR ).complete = completeDeferred.add;
- jqXHR.success = jqXHR.done;
- jqXHR.error = jqXHR.fail;
-
- // Remove hash character (#7531: and string promotion)
- // Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
- // Handle falsy url in the settings object (#10093: consistency with old signature)
- // We also use the url parameter if available
- s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
-
- // Alias method option to type as per ticket #12004
- s.type = options.method || options.type || s.method || s.type;
-
- // Extract dataTypes list
- s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ];
-
- // A cross-domain request is in order when we have a protocol:host:port mismatch
- if ( s.crossDomain == null ) {
- parts = rurl.exec( s.url.toLowerCase() );
- s.crossDomain = !!( parts &&
- ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
- ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
- ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
- );
- }
-
- // Convert data if not already a string
- if ( s.data && s.processData && typeof s.data !== "string" ) {
- s.data = jQuery.param( s.data, s.traditional );
- }
-
- // Apply prefilters
- inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
-
- // If request was aborted inside a prefilter, stop there
- if ( state === 2 ) {
- return jqXHR;
- }
-
- // We can fire global events as of now if asked to
- // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
- fireGlobals = jQuery.event && s.global;
-
- // Watch for a new set of requests
- if ( fireGlobals && jQuery.active++ === 0 ) {
- jQuery.event.trigger("ajaxStart");
- }
-
- // Uppercase the type
- s.type = s.type.toUpperCase();
-
- // Determine if request has content
- s.hasContent = !rnoContent.test( s.type );
-
- // Save the URL in case we're toying with the If-Modified-Since
- // and/or If-None-Match header later on
- cacheURL = s.url;
-
- // More options handling for requests with no content
- if ( !s.hasContent ) {
-
- // If data is available, append data to url
- if ( s.data ) {
- cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
- // #9682: remove data so that it's not used in an eventual retry
- delete s.data;
- }
-
- // Add anti-cache in url if needed
- if ( s.cache === false ) {
- s.url = rts.test( cacheURL ) ?
-
- // If there is already a '_' parameter, set its value
- cacheURL.replace( rts, "$1_=" + nonce++ ) :
-
- // Otherwise add one to the end
- cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++;
- }
- }
-
- // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
- if ( s.ifModified ) {
- if ( jQuery.lastModified[ cacheURL ] ) {
- jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
- }
- if ( jQuery.etag[ cacheURL ] ) {
- jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
- }
- }
-
- // Set the correct header, if data is being sent
- if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
- jqXHR.setRequestHeader( "Content-Type", s.contentType );
- }
-
- // Set the Accepts header for the server, depending on the dataType
- jqXHR.setRequestHeader(
- "Accept",
- s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
- s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
- s.accepts[ "*" ]
- );
-
- // Check for headers option
- for ( i in s.headers ) {
- jqXHR.setRequestHeader( i, s.headers[ i ] );
- }
-
- // Allow custom headers/mimetypes and early abort
- if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
- // Abort if not done already and return
- return jqXHR.abort();
- }
-
- // aborting is no longer a cancellation
- strAbort = "abort";
-
- // Install callbacks on deferreds
- for ( i in { success: 1, error: 1, complete: 1 } ) {
- jqXHR[ i ]( s[ i ] );
- }
-
- // Get transport
- transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
-
- // If no transport, we auto-abort
- if ( !transport ) {
- done( -1, "No Transport" );
- } else {
- jqXHR.readyState = 1;
-
- // Send global event
- if ( fireGlobals ) {
- globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
- }
- // Timeout
- if ( s.async && s.timeout > 0 ) {
- timeoutTimer = setTimeout(function() {
- jqXHR.abort("timeout");
- }, s.timeout );
- }
-
- try {
- state = 1;
- transport.send( requestHeaders, done );
- } catch ( e ) {
- // Propagate exception as error if not done
- if ( state < 2 ) {
- done( -1, e );
- // Simply rethrow otherwise
- } else {
- throw e;
- }
- }
- }
-
- // Callback for when everything is done
- function done( status, nativeStatusText, responses, headers ) {
- var isSuccess, success, error, response, modified,
- statusText = nativeStatusText;
-
- // Called once
- if ( state === 2 ) {
- return;
- }
-
- // State is "done" now
- state = 2;
-
- // Clear timeout if it exists
- if ( timeoutTimer ) {
- clearTimeout( timeoutTimer );
- }
-
- // Dereference transport for early garbage collection
- // (no matter how long the jqXHR object will be used)
- transport = undefined;
-
- // Cache response headers
- responseHeadersString = headers || "";
-
- // Set readyState
- jqXHR.readyState = status > 0 ? 4 : 0;
-
- // Determine if successful
- isSuccess = status >= 200 && status < 300 || status === 304;
-
- // Get response data
- if ( responses ) {
- response = ajaxHandleResponses( s, jqXHR, responses );
- }
-
- // Convert no matter what (that way responseXXX fields are always set)
- response = ajaxConvert( s, response, jqXHR, isSuccess );
-
- // If successful, handle type chaining
- if ( isSuccess ) {
-
- // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
- if ( s.ifModified ) {
- modified = jqXHR.getResponseHeader("Last-Modified");
- if ( modified ) {
- jQuery.lastModified[ cacheURL ] = modified;
- }
- modified = jqXHR.getResponseHeader("etag");
- if ( modified ) {
- jQuery.etag[ cacheURL ] = modified;
- }
- }
-
- // if no content
- if ( status === 204 || s.type === "HEAD" ) {
- statusText = "nocontent";
-
- // if not modified
- } else if ( status === 304 ) {
- statusText = "notmodified";
-
- // If we have data, let's convert it
- } else {
- statusText = response.state;
- success = response.data;
- error = response.error;
- isSuccess = !error;
- }
- } else {
- // We extract error from statusText
- // then normalize statusText and status for non-aborts
- error = statusText;
- if ( status || !statusText ) {
- statusText = "error";
- if ( status < 0 ) {
- status = 0;
- }
- }
- }
-
- // Set data for the fake xhr object
- jqXHR.status = status;
- jqXHR.statusText = ( nativeStatusText || statusText ) + "";
-
- // Success/Error
- if ( isSuccess ) {
- deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
- } else {
- deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
- }
-
- // Status-dependent callbacks
- jqXHR.statusCode( statusCode );
- statusCode = undefined;
-
- if ( fireGlobals ) {
- globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
- [ jqXHR, s, isSuccess ? success : error ] );
- }
-
- // Complete
- completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
-
- if ( fireGlobals ) {
- globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
- // Handle the global AJAX counter
- if ( !( --jQuery.active ) ) {
- jQuery.event.trigger("ajaxStop");
- }
- }
- }
-
- return jqXHR;
- },
-
- getJSON: function( url, data, callback ) {
- return jQuery.get( url, data, callback, "json" );
- },
-
- getScript: function( url, callback ) {
- return jQuery.get( url, undefined, callback, "script" );
- }
-});
-
-jQuery.each( [ "get", "post" ], function( i, method ) {
- jQuery[ method ] = function( url, data, callback, type ) {
- // shift arguments if data argument was omitted
- if ( jQuery.isFunction( data ) ) {
- type = type || callback;
- callback = data;
- data = undefined;
- }
-
- return jQuery.ajax({
- url: url,
- type: method,
- dataType: type,
- data: data,
- success: callback
- });
- };
-});
-
-
-jQuery._evalUrl = function( url ) {
- return jQuery.ajax({
- url: url,
- type: "GET",
- dataType: "script",
- async: false,
- global: false,
- "throws": true
- });
-};
-
-
-jQuery.fn.extend({
- wrapAll: function( html ) {
- if ( jQuery.isFunction( html ) ) {
- return this.each(function(i) {
- jQuery(this).wrapAll( html.call(this, i) );
- });
- }
-
- if ( this[0] ) {
- // The elements to wrap the target around
- var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);
-
- if ( this[0].parentNode ) {
- wrap.insertBefore( this[0] );
- }
-
- wrap.map(function() {
- var elem = this;
-
- while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {
- elem = elem.firstChild;
- }
-
- return elem;
- }).append( this );
- }
-
- return this;
- },
-
- wrapInner: function( html ) {
- if ( jQuery.isFunction( html ) ) {
- return this.each(function(i) {
- jQuery(this).wrapInner( html.call(this, i) );
- });
- }
-
- return this.each(function() {
- var self = jQuery( this ),
- contents = self.contents();
-
- if ( contents.length ) {
- contents.wrapAll( html );
-
- } else {
- self.append( html );
- }
- });
- },
-
- wrap: function( html ) {
- var isFunction = jQuery.isFunction( html );
-
- return this.each(function(i) {
- jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
- });
- },
-
- unwrap: function() {
- return this.parent().each(function() {
- if ( !jQuery.nodeName( this, "body" ) ) {
- jQuery( this ).replaceWith( this.childNodes );
- }
- }).end();
- }
-});
-
-
-jQuery.expr.filters.hidden = function( elem ) {
- // Support: Opera <= 12.12
- // Opera reports offsetWidths and offsetHeights less than zero on some elements
- return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
- (!support.reliableHiddenOffsets() &&
- ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none");
-};
-
-jQuery.expr.filters.visible = function( elem ) {
- return !jQuery.expr.filters.hidden( elem );
-};
-
-
-
-
-var r20 = /%20/g,
- rbracket = /\[\]$/,
- rCRLF = /\r?\n/g,
- rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
- rsubmittable = /^(?:input|select|textarea|keygen)/i;
-
-function buildParams( prefix, obj, traditional, add ) {
- var name;
-
- if ( jQuery.isArray( obj ) ) {
- // Serialize array item.
- jQuery.each( obj, function( i, v ) {
- if ( traditional || rbracket.test( prefix ) ) {
- // Treat each array item as a scalar.
- add( prefix, v );
-
- } else {
- // Item is non-scalar (array or object), encode its numeric index.
- buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
- }
- });
-
- } else if ( !traditional && jQuery.type( obj ) === "object" ) {
- // Serialize object item.
- for ( name in obj ) {
- buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
- }
-
- } else {
- // Serialize scalar item.
- add( prefix, obj );
- }
-}
-
-// Serialize an array of form elements or a set of
-// key/values into a query string
-jQuery.param = function( a, traditional ) {
- var prefix,
- s = [],
- add = function( key, value ) {
- // If value is a function, invoke it and return its value
- value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
- s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
- };
-
- // Set traditional to true for jQuery <= 1.3.2 behavior.
- if ( traditional === undefined ) {
- traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
- }
-
- // If an array was passed in, assume that it is an array of form elements.
- if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
- // Serialize the form elements
- jQuery.each( a, function() {
- add( this.name, this.value );
- });
-
- } else {
- // If traditional, encode the "old" way (the way 1.3.2 or older
- // did it), otherwise encode params recursively.
- for ( prefix in a ) {
- buildParams( prefix, a[ prefix ], traditional, add );
- }
- }
-
- // Return the resulting serialization
- return s.join( "&" ).replace( r20, "+" );
-};
-
-jQuery.fn.extend({
- serialize: function() {
- return jQuery.param( this.serializeArray() );
- },
- serializeArray: function() {
- return this.map(function() {
- // Can add propHook for "elements" to filter or add form elements
- var elements = jQuery.prop( this, "elements" );
- return elements ? jQuery.makeArray( elements ) : this;
- })
- .filter(function() {
- var type = this.type;
- // Use .is(":disabled") so that fieldset[disabled] works
- return this.name && !jQuery( this ).is( ":disabled" ) &&
- rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
- ( this.checked || !rcheckableType.test( type ) );
- })
- .map(function( i, elem ) {
- var val = jQuery( this ).val();
-
- return val == null ?
- null :
- jQuery.isArray( val ) ?
- jQuery.map( val, function( val ) {
- return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
- }) :
- { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
- }).get();
- }
-});
-
-
-// Create the request object
-// (This is still attached to ajaxSettings for backward compatibility)
-jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?
- // Support: IE6+
- function() {
-
- // XHR cannot access local files, always use ActiveX for that case
- return !this.isLocal &&
-
- // Support: IE7-8
- // oldIE XHR does not support non-RFC2616 methods (#13240)
- // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx
- // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9
- // Although this check for six methods instead of eight
- // since IE also does not support "trace" and "connect"
- /^(get|post|head|put|delete|options)$/i.test( this.type ) &&
-
- createStandardXHR() || createActiveXHR();
- } :
- // For all other browsers, use the standard XMLHttpRequest object
- createStandardXHR;
-
-var xhrId = 0,
- xhrCallbacks = {},
- xhrSupported = jQuery.ajaxSettings.xhr();
-
-// Support: IE<10
-// Open requests must be manually aborted on unload (#5280)
-// See https://support.microsoft.com/kb/2856746 for more info
-if ( window.attachEvent ) {
- window.attachEvent( "onunload", function() {
- for ( var key in xhrCallbacks ) {
- xhrCallbacks[ key ]( undefined, true );
- }
- });
-}
-
-// Determine support properties
-support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
-xhrSupported = support.ajax = !!xhrSupported;
-
-// Create transport if the browser can provide an xhr
-if ( xhrSupported ) {
-
- jQuery.ajaxTransport(function( options ) {
- // Cross domain only allowed if supported through XMLHttpRequest
- if ( !options.crossDomain || support.cors ) {
-
- var callback;
-
- return {
- send: function( headers, complete ) {
- var i,
- xhr = options.xhr(),
- id = ++xhrId;
-
- // Open the socket
- xhr.open( options.type, options.url, options.async, options.username, options.password );
-
- // Apply custom fields if provided
- if ( options.xhrFields ) {
- for ( i in options.xhrFields ) {
- xhr[ i ] = options.xhrFields[ i ];
- }
- }
-
- // Override mime type if needed
- if ( options.mimeType && xhr.overrideMimeType ) {
- xhr.overrideMimeType( options.mimeType );
- }
-
- // X-Requested-With header
- // For cross-domain requests, seeing as conditions for a preflight are
- // akin to a jigsaw puzzle, we simply never set it to be sure.
- // (it can always be set on a per-request basis or even using ajaxSetup)
- // For same-domain requests, won't change header if already provided.
- if ( !options.crossDomain && !headers["X-Requested-With"] ) {
- headers["X-Requested-With"] = "XMLHttpRequest";
- }
-
- // Set headers
- for ( i in headers ) {
- // Support: IE<9
- // IE's ActiveXObject throws a 'Type Mismatch' exception when setting
- // request header to a null-value.
- //
- // To keep consistent with other XHR implementations, cast the value
- // to string and ignore `undefined`.
- if ( headers[ i ] !== undefined ) {
- xhr.setRequestHeader( i, headers[ i ] + "" );
- }
- }
-
- // Do send the request
- // This may raise an exception which is actually
- // handled in jQuery.ajax (so no try/catch here)
- xhr.send( ( options.hasContent && options.data ) || null );
-
- // Listener
- callback = function( _, isAbort ) {
- var status, statusText, responses;
-
- // Was never called and is aborted or complete
- if ( callback && ( isAbort || xhr.readyState === 4 ) ) {
- // Clean up
- delete xhrCallbacks[ id ];
- callback = undefined;
- xhr.onreadystatechange = jQuery.noop;
-
- // Abort manually if needed
- if ( isAbort ) {
- if ( xhr.readyState !== 4 ) {
- xhr.abort();
- }
- } else {
- responses = {};
- status = xhr.status;
-
- // Support: IE<10
- // Accessing binary-data responseText throws an exception
- // (#11426)
- if ( typeof xhr.responseText === "string" ) {
- responses.text = xhr.responseText;
- }
-
- // Firefox throws an exception when accessing
- // statusText for faulty cross-domain requests
- try {
- statusText = xhr.statusText;
- } catch( e ) {
- // We normalize with Webkit giving an empty statusText
- statusText = "";
- }
-
- // Filter status for non standard behaviors
-
- // If the request is local and we have data: assume a success
- // (success with no data won't get notified, that's the best we
- // can do given current implementations)
- if ( !status && options.isLocal && !options.crossDomain ) {
- status = responses.text ? 200 : 404;
- // IE - #1450: sometimes returns 1223 when it should be 204
- } else if ( status === 1223 ) {
- status = 204;
- }
- }
- }
-
- // Call complete if needed
- if ( responses ) {
- complete( status, statusText, responses, xhr.getAllResponseHeaders() );
- }
- };
-
- if ( !options.async ) {
- // if we're in sync mode we fire the callback
- callback();
- } else if ( xhr.readyState === 4 ) {
- // (IE6 & IE7) if it's in cache and has been
- // retrieved directly we need to fire the callback
- setTimeout( callback );
- } else {
- // Add to the list of active xhr callbacks
- xhr.onreadystatechange = xhrCallbacks[ id ] = callback;
- }
- },
-
- abort: function() {
- if ( callback ) {
- callback( undefined, true );
- }
- }
- };
- }
- });
-}
-
-// Functions to create xhrs
-function createStandardXHR() {
- try {
- return new window.XMLHttpRequest();
- } catch( e ) {}
-}
-
-function createActiveXHR() {
- try {
- return new window.ActiveXObject( "Microsoft.XMLHTTP" );
- } catch( e ) {}
-}
-
-
-
-
-// Install script dataType
-jQuery.ajaxSetup({
- accepts: {
- script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
- },
- contents: {
- script: /(?:java|ecma)script/
- },
- converters: {
- "text script": function( text ) {
- jQuery.globalEval( text );
- return text;
- }
- }
-});
-
-// Handle cache's special case and global
-jQuery.ajaxPrefilter( "script", function( s ) {
- if ( s.cache === undefined ) {
- s.cache = false;
- }
- if ( s.crossDomain ) {
- s.type = "GET";
- s.global = false;
- }
-});
-
-// Bind script tag hack transport
-jQuery.ajaxTransport( "script", function(s) {
-
- // This transport only deals with cross domain requests
- if ( s.crossDomain ) {
-
- var script,
- head = document.head || jQuery("head")[0] || document.documentElement;
-
- return {
-
- send: function( _, callback ) {
-
- script = document.createElement("script");
-
- script.async = true;
-
- if ( s.scriptCharset ) {
- script.charset = s.scriptCharset;
- }
-
- script.src = s.url;
-
- // Attach handlers for all browsers
- script.onload = script.onreadystatechange = function( _, isAbort ) {
-
- if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
-
- // Handle memory leak in IE
- script.onload = script.onreadystatechange = null;
-
- // Remove the script
- if ( script.parentNode ) {
- script.parentNode.removeChild( script );
- }
-
- // Dereference the script
- script = null;
-
- // Callback if not abort
- if ( !isAbort ) {
- callback( 200, "success" );
- }
- }
- };
-
- // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
- // Use native DOM manipulation to avoid our domManip AJAX trickery
- head.insertBefore( script, head.firstChild );
- },
-
- abort: function() {
- if ( script ) {
- script.onload( undefined, true );
- }
- }
- };
- }
-});
-
-
-
-
-var oldCallbacks = [],
- rjsonp = /(=)\?(?=&|$)|\?\?/;
-
-// Default jsonp settings
-jQuery.ajaxSetup({
- jsonp: "callback",
- jsonpCallback: function() {
- var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
- this[ callback ] = true;
- return callback;
- }
-});
-
-// Detect, normalize options and install callbacks for jsonp requests
-jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
-
- var callbackName, overwritten, responseContainer,
- jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
- "url" :
- typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
- );
-
- // Handle iff the expected data type is "jsonp" or we have a parameter to set
- if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
-
- // Get callback name, remembering preexisting value associated with it
- callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
- s.jsonpCallback() :
- s.jsonpCallback;
-
- // Insert callback into url or form data
- if ( jsonProp ) {
- s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
- } else if ( s.jsonp !== false ) {
- s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
- }
-
- // Use data converter to retrieve json after script execution
- s.converters["script json"] = function() {
- if ( !responseContainer ) {
- jQuery.error( callbackName + " was not called" );
- }
- return responseContainer[ 0 ];
- };
-
- // force json dataType
- s.dataTypes[ 0 ] = "json";
-
- // Install callback
- overwritten = window[ callbackName ];
- window[ callbackName ] = function() {
- responseContainer = arguments;
- };
-
- // Clean-up function (fires after converters)
- jqXHR.always(function() {
- // Restore preexisting value
- window[ callbackName ] = overwritten;
-
- // Save back as free
- if ( s[ callbackName ] ) {
- // make sure that re-using the options doesn't screw things around
- s.jsonpCallback = originalSettings.jsonpCallback;
-
- // save the callback name for future use
- oldCallbacks.push( callbackName );
- }
-
- // Call if it was a function and we have a response
- if ( responseContainer && jQuery.isFunction( overwritten ) ) {
- overwritten( responseContainer[ 0 ] );
- }
-
- responseContainer = overwritten = undefined;
- });
-
- // Delegate to script
- return "script";
- }
-});
-
-
-
-
-// data: string of html
-// context (optional): If specified, the fragment will be created in this context, defaults to document
-// keepScripts (optional): If true, will include scripts passed in the html string
-jQuery.parseHTML = function( data, context, keepScripts ) {
- if ( !data || typeof data !== "string" ) {
- return null;
- }
- if ( typeof context === "boolean" ) {
- keepScripts = context;
- context = false;
- }
- context = context || document;
-
- var parsed = rsingleTag.exec( data ),
- scripts = !keepScripts && [];
-
- // Single tag
- if ( parsed ) {
- return [ context.createElement( parsed[1] ) ];
- }
-
- parsed = jQuery.buildFragment( [ data ], context, scripts );
-
- if ( scripts && scripts.length ) {
- jQuery( scripts ).remove();
- }
-
- return jQuery.merge( [], parsed.childNodes );
-};
-
-
-// Keep a copy of the old load method
-var _load = jQuery.fn.load;
-
-/**
- * Load a url into a page
- */
-jQuery.fn.load = function( url, params, callback ) {
- if ( typeof url !== "string" && _load ) {
- return _load.apply( this, arguments );
- }
-
- var selector, response, type,
- self = this,
- off = url.indexOf(" ");
-
- if ( off >= 0 ) {
- selector = jQuery.trim( url.slice( off, url.length ) );
- url = url.slice( 0, off );
- }
-
- // If it's a function
- if ( jQuery.isFunction( params ) ) {
-
- // We assume that it's the callback
- callback = params;
- params = undefined;
-
- // Otherwise, build a param string
- } else if ( params && typeof params === "object" ) {
- type = "POST";
- }
-
- // If we have elements to modify, make the request
- if ( self.length > 0 ) {
- jQuery.ajax({
- url: url,
-
- // if "type" variable is undefined, then "GET" method will be used
- type: type,
- dataType: "html",
- data: params
- }).done(function( responseText ) {
-
- // Save response for use in complete callback
- response = arguments;
-
- self.html( selector ?
-
- // If a selector was specified, locate the right elements in a dummy div
- // Exclude scripts to avoid IE 'Permission Denied' errors
- jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
-
- // Otherwise use the full result
- responseText );
-
- }).complete( callback && function( jqXHR, status ) {
- self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
- });
- }
-
- return this;
-};
-
-
-
-
-// Attach a bunch of functions for handling common AJAX events
-jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) {
- jQuery.fn[ type ] = function( fn ) {
- return this.on( type, fn );
- };
-});
-
-
-
-
-jQuery.expr.filters.animated = function( elem ) {
- return jQuery.grep(jQuery.timers, function( fn ) {
- return elem === fn.elem;
- }).length;
-};
-
-
-
-
-
-var docElem = window.document.documentElement;
-
-/**
- * Gets a window from an element
- */
-function getWindow( elem ) {
- return jQuery.isWindow( elem ) ?
- elem :
- elem.nodeType === 9 ?
- elem.defaultView || elem.parentWindow :
- false;
-}
-
-jQuery.offset = {
- setOffset: function( elem, options, i ) {
- var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
- position = jQuery.css( elem, "position" ),
- curElem = jQuery( elem ),
- props = {};
-
- // set position first, in-case top/left are set even on static elem
- if ( position === "static" ) {
- elem.style.position = "relative";
- }
-
- curOffset = curElem.offset();
- curCSSTop = jQuery.css( elem, "top" );
- curCSSLeft = jQuery.css( elem, "left" );
- calculatePosition = ( position === "absolute" || position === "fixed" ) &&
- jQuery.inArray("auto", [ curCSSTop, curCSSLeft ] ) > -1;
-
- // need to be able to calculate position if either top or left is auto and position is either absolute or fixed
- if ( calculatePosition ) {
- curPosition = curElem.position();
- curTop = curPosition.top;
- curLeft = curPosition.left;
- } else {
- curTop = parseFloat( curCSSTop ) || 0;
- curLeft = parseFloat( curCSSLeft ) || 0;
- }
-
- if ( jQuery.isFunction( options ) ) {
- options = options.call( elem, i, curOffset );
- }
-
- if ( options.top != null ) {
- props.top = ( options.top - curOffset.top ) + curTop;
- }
- if ( options.left != null ) {
- props.left = ( options.left - curOffset.left ) + curLeft;
- }
-
- if ( "using" in options ) {
- options.using.call( elem, props );
- } else {
- curElem.css( props );
- }
- }
-};
-
-jQuery.fn.extend({
- offset: function( options ) {
- if ( arguments.length ) {
- return options === undefined ?
- this :
- this.each(function( i ) {
- jQuery.offset.setOffset( this, options, i );
- });
- }
-
- var docElem, win,
- box = { top: 0, left: 0 },
- elem = this[ 0 ],
- doc = elem && elem.ownerDocument;
-
- if ( !doc ) {
- return;
- }
-
- docElem = doc.documentElement;
-
- // Make sure it's not a disconnected DOM node
- if ( !jQuery.contains( docElem, elem ) ) {
- return box;
- }
-
- // If we don't have gBCR, just use 0,0 rather than error
- // BlackBerry 5, iOS 3 (original iPhone)
- if ( typeof elem.getBoundingClientRect !== strundefined ) {
- box = elem.getBoundingClientRect();
- }
- win = getWindow( doc );
- return {
- top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ),
- left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
- };
- },
-
- position: function() {
- if ( !this[ 0 ] ) {
- return;
- }
-
- var offsetParent, offset,
- parentOffset = { top: 0, left: 0 },
- elem = this[ 0 ];
-
- // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent
- if ( jQuery.css( elem, "position" ) === "fixed" ) {
- // we assume that getBoundingClientRect is available when computed position is fixed
- offset = elem.getBoundingClientRect();
- } else {
- // Get *real* offsetParent
- offsetParent = this.offsetParent();
-
- // Get correct offsets
- offset = this.offset();
- if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
- parentOffset = offsetParent.offset();
- }
-
- // Add offsetParent borders
- parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
- parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
- }
-
- // Subtract parent offsets and element margins
- // note: when an element has margin: auto the offsetLeft and marginLeft
- // are the same in Safari causing offset.left to incorrectly be 0
- return {
- top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
- left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
- };
- },
-
- offsetParent: function() {
- return this.map(function() {
- var offsetParent = this.offsetParent || docElem;
-
- while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) {
- offsetParent = offsetParent.offsetParent;
- }
- return offsetParent || docElem;
- });
- }
-});
-
-// Create scrollLeft and scrollTop methods
-jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
- var top = /Y/.test( prop );
-
- jQuery.fn[ method ] = function( val ) {
- return access( this, function( elem, method, val ) {
- var win = getWindow( elem );
-
- if ( val === undefined ) {
- return win ? (prop in win) ? win[ prop ] :
- win.document.documentElement[ method ] :
- elem[ method ];
- }
-
- if ( win ) {
- win.scrollTo(
- !top ? val : jQuery( win ).scrollLeft(),
- top ? val : jQuery( win ).scrollTop()
- );
-
- } else {
- elem[ method ] = val;
- }
- }, method, val, arguments.length, null );
- };
-});
-
-// Add the top/left cssHooks using jQuery.fn.position
-// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
-// getComputedStyle returns percent when specified for top/left/bottom/right
-// rather than make the css module depend on the offset module, we just check for it here
-jQuery.each( [ "top", "left" ], function( i, prop ) {
- jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
- function( elem, computed ) {
- if ( computed ) {
- computed = curCSS( elem, prop );
- // if curCSS returns percentage, fallback to offset
- return rnumnonpx.test( computed ) ?
- jQuery( elem ).position()[ prop ] + "px" :
- computed;
- }
- }
- );
-});
-
-
-// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
-jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
- jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
- // margin is only for outerHeight, outerWidth
- jQuery.fn[ funcName ] = function( margin, value ) {
- var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
- extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
-
- return access( this, function( elem, type, value ) {
- var doc;
-
- if ( jQuery.isWindow( elem ) ) {
- // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
- // isn't a whole lot we can do. See pull request at this URL for discussion:
- // https://github.com/jquery/jquery/pull/764
- return elem.document.documentElement[ "client" + name ];
- }
-
- // Get document width or height
- if ( elem.nodeType === 9 ) {
- doc = elem.documentElement;
-
- // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest
- // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.
- return Math.max(
- elem.body[ "scroll" + name ], doc[ "scroll" + name ],
- elem.body[ "offset" + name ], doc[ "offset" + name ],
- doc[ "client" + name ]
- );
- }
-
- return value === undefined ?
- // Get width or height on the element, requesting but not forcing parseFloat
- jQuery.css( elem, type, extra ) :
-
- // Set width or height on the element
- jQuery.style( elem, type, value, extra );
- }, type, chainable ? margin : undefined, chainable, null );
- };
- });
-});
-
-
-// The number of elements contained in the matched element set
-jQuery.fn.size = function() {
- return this.length;
-};
-
-jQuery.fn.andSelf = jQuery.fn.addBack;
-
-
-
-
-// Register as a named AMD module, since jQuery can be concatenated with other
-// files that may use define, but not via a proper concatenation script that
-// understands anonymous AMD modules. A named AMD is safest and most robust
-// way to register. Lowercase jquery is used because AMD module names are
-// derived from file names, and jQuery is normally delivered in a lowercase
-// file name. Do this after creating the global so that if an AMD module wants
-// to call noConflict to hide this version of jQuery, it will work.
-
-// Note that for maximum portability, libraries that are not jQuery should
-// declare themselves as anonymous modules, and avoid setting a global if an
-// AMD loader is present. jQuery is a special case. For more information, see
-// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
-
-if ( typeof define === "function" && define.amd ) {
- define( "jquery", [], function() {
- return jQuery;
- });
-}
-
-
-
-
-var
- // Map over jQuery in case of overwrite
- _jQuery = window.jQuery,
-
- // Map over the $ in case of overwrite
- _$ = window.$;
-
-jQuery.noConflict = function( deep ) {
- if ( window.$ === jQuery ) {
- window.$ = _$;
- }
-
- if ( deep && window.jQuery === jQuery ) {
- window.jQuery = _jQuery;
- }
-
- return jQuery;
-};
-
-// Expose jQuery and $ identifiers, even in
-// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
-// and CommonJS for browser emulators (#13566)
-if ( typeof noGlobal === strundefined ) {
- window.jQuery = window.$ = jQuery;
-}
-
-
-
-
-return jQuery;
-
-}));
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/jquery/js/jquery-1.11.3.min.js b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/jquery/js/jquery-1.11.3.min.js
deleted file mode 100644
index 0f60b7bd0d..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/jquery/js/jquery-1.11.3.min.js
+++ /dev/null
@@ -1,5 +0,0 @@
-/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */
-!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function qa(){}qa.prototype=d.filters=d.pseudos,d.setFilters=new qa,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function ra(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;
-
-return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[m.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=Z.test(e)?this.mouseHooks:Y.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new m.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||y),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||y,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ca()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ca()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return m.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return m.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=m.extend(new m.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?m.event.trigger(e,null,b):m.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},m.removeEvent=y.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===K&&(a[d]=null),a.detachEvent(d,c))},m.Event=function(a,b){return this instanceof m.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?aa:ba):this.type=a,b&&m.extend(this,b),this.timeStamp=a&&a.timeStamp||m.now(),void(this[m.expando]=!0)):new m.Event(a,b)},m.Event.prototype={isDefaultPrevented:ba,isPropagationStopped:ba,isImmediatePropagationStopped:ba,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=aa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=aa,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=aa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},m.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){m.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!m.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.submitBubbles||(m.event.special.submit={setup:function(){return m.nodeName(this,"form")?!1:void m.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=m.nodeName(b,"input")||m.nodeName(b,"button")?b.form:void 0;c&&!m._data(c,"submitBubbles")&&(m.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),m._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&m.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return m.nodeName(this,"form")?!1:void m.event.remove(this,"._submit")}}),k.changeBubbles||(m.event.special.change={setup:function(){return X.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(m.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),m.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),m.event.simulate("change",this,a,!0)})),!1):void m.event.add(this,"beforeactivate._change",function(a){var b=a.target;X.test(b.nodeName)&&!m._data(b,"changeBubbles")&&(m.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||m.event.simulate("change",this.parentNode,a,!0)}),m._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return m.event.remove(this,"._change"),!X.test(this.nodeName)}}),k.focusinBubbles||m.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){m.event.simulate(b,a.target,m.event.fix(a),!0)};m.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=m._data(d,b);e||d.addEventListener(a,c,!0),m._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=m._data(d,b)-1;e?m._data(d,b,e):(d.removeEventListener(a,c,!0),m._removeData(d,b))}}}),m.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=ba;else if(!d)return this;return 1===e&&(g=d,d=function(a){return m().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=m.guid++)),this.each(function(){m.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,m(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=ba),this.each(function(){m.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){m.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?m.event.trigger(a,b,c,!0):void 0}});function da(a){var b=ea.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var ea="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",fa=/ jQuery\d+="(?:null|\d+)"/g,ga=new RegExp("<(?:"+ea+")[\\s/>]","i"),ha=/^\s+/,ia=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ja=/<([\w:]+)/,ka=/<tbody/i,la=/<|&#?\w+;/,ma=/<(?:script|style|link)/i,na=/checked\s*(?:[^=]|=\s*.checked.)/i,oa=/^$|\/(?:java|ecma)script/i,pa=/^true\/(.*)/,qa=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ra={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:k.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},sa=da(y),ta=sa.appendChild(y.createElement("div"));ra.optgroup=ra.option,ra.tbody=ra.tfoot=ra.colgroup=ra.caption=ra.thead,ra.th=ra.td;function ua(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ua(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function va(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wa(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xa(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function ya(a){var b=pa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function za(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Aa(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Ba(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xa(b).text=a.text,ya(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!ga.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ta.innerHTML=a.outerHTML,ta.removeChild(f=ta.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ua(f),h=ua(a),g=0;null!=(e=h[g]);++g)d[g]&&Ba(e,d[g]);if(b)if(c)for(h=h||ua(a),d=d||ua(f),g=0;null!=(e=h[g]);g++)Aa(e,d[g]);else Aa(a,f);return d=ua(f,"script"),d.length>0&&za(d,!i&&ua(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=da(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(la.test(f)){h=h||o.appendChild(b.createElement("div")),i=(ja.exec(f)||["",""])[1].toLowerCase(),l=ra[i]||ra._default,h.innerHTML=l[1]+f.replace(ia,"<$1></$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&ha.test(f)&&p.push(b.createTextNode(ha.exec(f)[0])),!k.tbody){f="table"!==i||ka.test(f)?"<table>"!==l[1]||ka.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ua(p,"input"),va),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ua(o.appendChild(f),"script"),g&&za(h),c)){e=0;while(f=h[e++])oa.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ua(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&za(ua(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ua(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fa,""):void 0;if(!("string"!=typeof a||ma.test(a)||!k.htmlSerialize&&ga.test(a)||!k.leadingWhitespace&&ha.test(a)||ra[(ja.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ia,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ua(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ua(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&na.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ua(i,"script"),xa),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ua(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,ya),j=0;f>j;j++)d=g[j],oa.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qa,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Ca,Da={};function Ea(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fa(a){var b=y,c=Da[a];return c||(c=Ea(a,b),"none"!==c&&c||(Ca=(Ca||m("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ca[0].contentWindow||Ca[0].contentDocument).document,b.write(),b.close(),c=Ea(a,b),Ca.detach()),Da[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Ga=/^margin/,Ha=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ia,Ja,Ka=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ia=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)},Ja=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ia(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Ha.test(g)&&Ga.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ia=function(a){return a.currentStyle},Ja=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ia(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ha.test(g)&&!Ka.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function La(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight),b.removeChild(i)),b.innerHTML="<table><tr><td></td><td>t</td></tr></table>",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Ma=/alpha\([^)]*\)/i,Na=/opacity\s*=\s*([^)]*)/,Oa=/^(none|table(?!-c[ea]).+)/,Pa=new RegExp("^("+S+")(.*)$","i"),Qa=new RegExp("^([+-])=("+S+")","i"),Ra={position:"absolute",visibility:"hidden",display:"block"},Sa={letterSpacing:"0",fontWeight:"400"},Ta=["Webkit","O","Moz","ms"];function Ua(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ta.length;while(e--)if(b=Ta[e]+c,b in a)return b;return d}function Va(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fa(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wa(a,b,c){var d=Pa.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xa(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Ya(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ia(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Ja(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ha.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xa(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ja(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ua(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qa.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ua(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Ja(a,b,d)),"normal"===f&&b in Sa&&(f=Sa[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Oa.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Ra,function(){return Ya(a,b,d)}):Ya(a,b,d):void 0},set:function(a,c,d){var e=d&&Ia(a);return Wa(a,c,d?Xa(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Na.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Ma,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Ma.test(f)?f.replace(Ma,e):f+" "+e)}}),m.cssHooks.marginRight=La(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Ja,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Ga.test(a)||(m.cssHooks[a+b].set=Wa)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ia(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Va(this,!0)},hide:function(){return Va(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Za(a,b,c,d,e){
-return new Za.prototype.init(a,b,c,d,e)}m.Tween=Za,Za.prototype={constructor:Za,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Za.propHooks[this.prop];return a&&a.get?a.get(this):Za.propHooks._default.get(this)},run:function(a){var b,c=Za.propHooks[this.prop];return this.options.duration?this.pos=b=m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Za.propHooks._default.set(this),this}},Za.prototype.init.prototype=Za.prototype,Za.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Za.propHooks.scrollTop=Za.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Za.prototype.init,m.fx.step={};var $a,_a,ab=/^(?:toggle|show|hide)$/,bb=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cb=/queueHooks$/,db=[ib],eb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bb.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bb.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fb(){return setTimeout(function(){$a=void 0}),$a=m.now()}function gb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hb(a,b,c){for(var d,e=(eb[b]||[]).concat(eb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fa(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fa(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ab.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fa(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hb(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=db.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$a||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$a||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);g>f;f++)if(d=db[f].call(j,a,k,j.opts))return d;return m.map(k,hb,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kb,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],eb[c]=eb[c]||[],eb[c].unshift(b)},prefilter:function(a,b){b?db.unshift(a):db.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kb(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),m.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($a=m.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||m.fx.stop(),$a=void 0},m.fx.timer=function(a){m.timers.push(a),a()?m.fx.start():m.timers.pop()},m.fx.interval=13,m.fx.start=function(){_a||(_a=setInterval(m.fx.tick,m.fx.interval))},m.fx.stop=function(){clearInterval(_a),_a=null},m.fx.speeds={slow:600,fast:200,_default:400},m.fn.delay=function(a,b){return a=m.fx?m.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=y.createElement("div"),b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lb=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lb,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mb,nb,ob=m.expr.attrHandle,pb=/^(?:checked|selected)$/i,qb=k.getSetAttribute,rb=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nb:mb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rb&&qb||!pb.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qb?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nb={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rb&&qb||!pb.test(c)?a.setAttribute(!qb&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ob[b]||m.find.attr;ob[b]=rb&&qb||!pb.test(b)?function(a,b,d){var e,f;return d||(f=ob[b],ob[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,ob[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rb&&qb||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mb&&mb.set(a,b,c)}}),qb||(mb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},ob.id=ob.name=ob.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mb.set},m.attrHooks.contenteditable={set:function(a,b,c){mb.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sb=/^(?:input|select|textarea|button|object)$/i,tb=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sb.test(a.nodeName)||tb.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var ub=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ub," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ub," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ub," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vb=m.now(),wb=/\?/,xb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yb,zb,Ab=/#.*$/,Bb=/([?&])_=[^&]*/,Cb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Db=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Eb=/^(?:GET|HEAD)$/,Fb=/^\/\//,Gb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hb={},Ib={},Jb="*/".concat("*");try{zb=location.href}catch(Kb){zb=y.createElement("a"),zb.href="",zb=zb.href}yb=Gb.exec(zb.toLowerCase())||[];function Lb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mb(a,b,c,d){var e={},f=a===Ib;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nb(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Ob(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zb,type:"GET",isLocal:Db.test(yb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nb(Nb(a,m.ajaxSettings),b):Nb(m.ajaxSettings,a)},ajaxPrefilter:Lb(Hb),ajaxTransport:Lb(Ib),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cb.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zb)+"").replace(Ab,"").replace(Fb,yb[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gb.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yb[1]&&c[2]===yb[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yb[3]||("http:"===yb[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mb(Hb,k,b,v),2===t)return v;h=m.event&&k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Eb.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wb.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bb.test(e)?e.replace(Bb,"$1_="+vb++):e+(wb.test(e)?"&":"?")+"_="+vb++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jb+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mb(Ib,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Ob(k,v,c)),u=Pb(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qb=/%20/g,Rb=/\[\]$/,Sb=/\r?\n/g,Tb=/^(?:submit|button|image|reset|file)$/i,Ub=/^(?:input|select|textarea|keygen)/i;function Vb(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rb.test(a)?d(a,e):Vb(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vb(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vb(c,a[c],b,e);return d.join("&").replace(Qb,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Ub.test(this.nodeName)&&!Tb.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sb,"\r\n")}}):{name:b.name,value:c.replace(Sb,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zb()||$b()}:Zb;var Wb=0,Xb={},Yb=m.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Xb)Xb[a](void 0,!0)}),k.cors=!!Yb&&"withCredentials"in Yb,Yb=k.ajax=!!Yb,Yb&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wb;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xb[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xb[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zb(){try{return new a.XMLHttpRequest}catch(b){}}function $b(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _b=[],ac=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_b.pop()||m.expando+"_"+vb++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ac.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ac.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ac,"$1"+e):b.jsonp!==!1&&(b.url+=(wb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_b.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bc=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bc)return bc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("<div>").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cc=a.document.documentElement;function dc(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cc;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cc})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=La(k.pixelPosition,function(a,c){return c?(c=Ja(a,b),Ha.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ec=a.jQuery,fc=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fc),b&&a.jQuery===m&&(a.jQuery=ec),m},typeof b===K&&(a.jQuery=a.$=m),m});
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/mpl.js b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/mpl.js
deleted file mode 100644
index cde766b88f..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/mpl.js
+++ /dev/null
@@ -1,554 +0,0 @@
-/* Put everything inside the global mpl namespace */
-window.mpl = {};
-
-
-mpl.get_websocket_type = function() {
- if (typeof(WebSocket) !== 'undefined') {
- return WebSocket;
- } else if (typeof(MozWebSocket) !== 'undefined') {
- return MozWebSocket;
- } else {
- alert('Your browser does not have WebSocket support.' +
- 'Please try Chrome, Safari or Firefox ≥ 6. ' +
- 'Firefox 4 and 5 are also supported but you ' +
- 'have to enable WebSockets in about:config.');
- };
-}
-
-mpl.figure = function(figure_id, websocket, ondownload, parent_element) {
- this.id = figure_id;
-
- this.ws = websocket;
-
- this.supports_binary = (this.ws.binaryType != undefined);
-
- if (!this.supports_binary) {
- var warnings = document.getElementById("mpl-warnings");
- if (warnings) {
- warnings.style.display = 'block';
- warnings.textContent = (
- "This browser does not support binary websocket messages. " +
- "Performance may be slow.");
- }
- }
-
- this.imageObj = new Image();
-
- this.context = undefined;
- this.message = undefined;
- this.canvas = undefined;
- this.rubberband_canvas = undefined;
- this.rubberband_context = undefined;
- this.format_dropdown = undefined;
-
- this.image_mode = 'full';
-
- this.root = $('<div/>');
- this._root_extra_style(this.root)
- this.root.attr('style', 'display: inline-block');
-
- $(parent_element).append(this.root);
-
- this._init_header(this);
- this._init_canvas(this);
- this._init_toolbar(this);
-
- var fig = this;
-
- this.waiting = false;
-
- this.ws.onopen = function () {
- fig.send_message("supports_binary", {value: fig.supports_binary});
- fig.send_message("send_image_mode", {});
- if (mpl.ratio != 1) {
- fig.send_message("set_dpi_ratio", {'dpi_ratio': mpl.ratio});
- }
- fig.send_message("refresh", {});
- }
-
- this.imageObj.onload = function() {
- if (fig.image_mode == 'full') {
- // Full images could contain transparency (where diff images
- // almost always do), so we need to clear the canvas so that
- // there is no ghosting.
- fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);
- }
- fig.context.drawImage(fig.imageObj, 0, 0);
- };
-
- this.imageObj.onunload = function() {
- fig.ws.close();
- }
-
- this.ws.onmessage = this._make_on_message_function(this);
-
- this.ondownload = ondownload;
-}
-
-mpl.figure.prototype._init_header = function() {
- var titlebar = $(
- '<div class="ui-dialog-titlebar ui-widget-header ui-corner-all ' +
- 'ui-helper-clearfix"/>');
- var titletext = $(
- '<div class="ui-dialog-title" style="width: 100%; ' +
- 'text-align: center; padding: 3px;"/>');
- titlebar.append(titletext)
- this.root.append(titlebar);
- this.header = titletext[0];
-}
-
-
-
-mpl.figure.prototype._canvas_extra_style = function(canvas_div) {
-
-}
-
-
-mpl.figure.prototype._root_extra_style = function(canvas_div) {
-
-}
-
-mpl.figure.prototype._init_canvas = function() {
- var fig = this;
-
- var canvas_div = $('<div/>');
-
- canvas_div.attr('style', 'position: relative; clear: both; outline: 0');
-
- function canvas_keyboard_event(event) {
- return fig.key_event(event, event['data']);
- }
-
- canvas_div.keydown('key_press', canvas_keyboard_event);
- canvas_div.keyup('key_release', canvas_keyboard_event);
- this.canvas_div = canvas_div
- this._canvas_extra_style(canvas_div)
- this.root.append(canvas_div);
-
- var canvas = $('<canvas/>');
- canvas.addClass('mpl-canvas');
- canvas.attr('style', "left: 0; top: 0; z-index: 0; outline: 0")
-
- this.canvas = canvas[0];
- this.context = canvas[0].getContext("2d");
-
- var backingStore = this.context.backingStorePixelRatio ||
- this.context.webkitBackingStorePixelRatio ||
- this.context.mozBackingStorePixelRatio ||
- this.context.msBackingStorePixelRatio ||
- this.context.oBackingStorePixelRatio ||
- this.context.backingStorePixelRatio || 1;
-
- mpl.ratio = (window.devicePixelRatio || 1) / backingStore;
-
- var rubberband = $('<canvas/>');
- rubberband.attr('style', "position: absolute; left: 0; top: 0; z-index: 1;")
-
- var pass_mouse_events = true;
-
- canvas_div.resizable({
- start: function(event, ui) {
- pass_mouse_events = false;
- },
- resize: function(event, ui) {
- fig.request_resize(ui.size.width, ui.size.height);
- },
- stop: function(event, ui) {
- pass_mouse_events = true;
- fig.request_resize(ui.size.width, ui.size.height);
- },
- });
-
- function mouse_event_fn(event) {
- if (pass_mouse_events)
- return fig.mouse_event(event, event['data']);
- }
-
- rubberband.mousedown('button_press', mouse_event_fn);
- rubberband.mouseup('button_release', mouse_event_fn);
- // Throttle sequential mouse events to 1 every 20ms.
- rubberband.mousemove('motion_notify', mouse_event_fn);
-
- rubberband.mouseenter('figure_enter', mouse_event_fn);
- rubberband.mouseleave('figure_leave', mouse_event_fn);
-
- canvas_div.on("wheel", function (event) {
- event = event.originalEvent;
- event['data'] = 'scroll'
- if (event.deltaY < 0) {
- event.step = 1;
- } else {
- event.step = -1;
- }
- mouse_event_fn(event);
- });
-
- canvas_div.append(canvas);
- canvas_div.append(rubberband);
-
- this.rubberband = rubberband;
- this.rubberband_canvas = rubberband[0];
- this.rubberband_context = rubberband[0].getContext("2d");
- this.rubberband_context.strokeStyle = "#000000";
-
- this._resize_canvas = function(width, height) {
- // Keep the size of the canvas, canvas container, and rubber band
- // canvas in synch.
- canvas_div.css('width', width)
- canvas_div.css('height', height)
-
- canvas.attr('width', width * mpl.ratio);
- canvas.attr('height', height * mpl.ratio);
- canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');
-
- rubberband.attr('width', width);
- rubberband.attr('height', height);
- }
-
- // Set the figure to an initial 600x600px, this will subsequently be updated
- // upon first draw.
- this._resize_canvas(600, 600);
-
- // Disable right mouse context menu.
- $(this.rubberband_canvas).bind("contextmenu",function(e){
- return false;
- });
-
- function set_focus () {
- canvas.focus();
- canvas_div.focus();
- }
-
- window.setTimeout(set_focus, 100);
-}
-
-mpl.figure.prototype._init_toolbar = function() {
- var fig = this;
-
- var nav_element = $('<div/>')
- nav_element.attr('style', 'width: 100%');
- this.root.append(nav_element);
-
- // Define a callback function for later on.
- function toolbar_event(event) {
- return fig.toolbar_button_onclick(event['data']);
- }
- function toolbar_mouse_event(event) {
- return fig.toolbar_button_onmouseover(event['data']);
- }
-
- for(var toolbar_ind in mpl.toolbar_items) {
- var name = mpl.toolbar_items[toolbar_ind][0];
- var tooltip = mpl.toolbar_items[toolbar_ind][1];
- var image = mpl.toolbar_items[toolbar_ind][2];
- var method_name = mpl.toolbar_items[toolbar_ind][3];
-
- if (!name) {
- // put a spacer in here.
- continue;
- }
- var button = $('<button/>');
- button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' +
- 'ui-button-icon-only');
- button.attr('role', 'button');
- button.attr('aria-disabled', 'false');
- button.click(method_name, toolbar_event);
- button.mouseover(tooltip, toolbar_mouse_event);
-
- var icon_img = $('<span/>');
- icon_img.addClass('ui-button-icon-primary ui-icon');
- icon_img.addClass(image);
- icon_img.addClass('ui-corner-all');
-
- var tooltip_span = $('<span/>');
- tooltip_span.addClass('ui-button-text');
- tooltip_span.html(tooltip);
-
- button.append(icon_img);
- button.append(tooltip_span);
-
- nav_element.append(button);
- }
-
- var fmt_picker_span = $('<span/>');
-
- var fmt_picker = $('<select/>');
- fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content');
- fmt_picker_span.append(fmt_picker);
- nav_element.append(fmt_picker_span);
- this.format_dropdown = fmt_picker[0];
-
- for (var ind in mpl.extensions) {
- var fmt = mpl.extensions[ind];
- var option = $(
- '<option/>', {selected: fmt === mpl.default_extension}).html(fmt);
- fmt_picker.append(option)
- }
-
- // Add hover states to the ui-buttons
- $( ".ui-button" ).hover(
- function() { $(this).addClass("ui-state-hover");},
- function() { $(this).removeClass("ui-state-hover");}
- );
-
- var status_bar = $('<span class="mpl-message"/>');
- nav_element.append(status_bar);
- this.message = status_bar[0];
-}
-
-mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) {
- // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,
- // which will in turn request a refresh of the image.
- this.send_message('resize', {'width': x_pixels, 'height': y_pixels});
-}
-
-mpl.figure.prototype.send_message = function(type, properties) {
- properties['type'] = type;
- properties['figure_id'] = this.id;
- this.ws.send(JSON.stringify(properties));
-}
-
-mpl.figure.prototype.send_draw_message = function() {
- if (!this.waiting) {
- this.waiting = true;
- this.ws.send(JSON.stringify({type: "draw", figure_id: this.id}));
- }
-}
-
-
-mpl.figure.prototype.handle_save = function(fig, msg) {
- var format_dropdown = fig.format_dropdown;
- var format = format_dropdown.options[format_dropdown.selectedIndex].value;
- fig.ondownload(fig, format);
-}
-
-
-mpl.figure.prototype.handle_resize = function(fig, msg) {
- var size = msg['size'];
- if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) {
- fig._resize_canvas(size[0], size[1]);
- fig.send_message("refresh", {});
- };
-}
-
-mpl.figure.prototype.handle_rubberband = function(fig, msg) {
- var x0 = msg['x0'] / mpl.ratio;
- var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio;
- var x1 = msg['x1'] / mpl.ratio;
- var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio;
- x0 = Math.floor(x0) + 0.5;
- y0 = Math.floor(y0) + 0.5;
- x1 = Math.floor(x1) + 0.5;
- y1 = Math.floor(y1) + 0.5;
- var min_x = Math.min(x0, x1);
- var min_y = Math.min(y0, y1);
- var width = Math.abs(x1 - x0);
- var height = Math.abs(y1 - y0);
-
- fig.rubberband_context.clearRect(
- 0, 0, fig.canvas.width, fig.canvas.height);
-
- fig.rubberband_context.strokeRect(min_x, min_y, width, height);
-}
-
-mpl.figure.prototype.handle_figure_label = function(fig, msg) {
- // Updates the figure title.
- fig.header.textContent = msg['label'];
-}
-
-mpl.figure.prototype.handle_cursor = function(fig, msg) {
- var cursor = msg['cursor'];
- switch(cursor)
- {
- case 0:
- cursor = 'pointer';
- break;
- case 1:
- cursor = 'default';
- break;
- case 2:
- cursor = 'crosshair';
- break;
- case 3:
- cursor = 'move';
- break;
- }
- fig.rubberband_canvas.style.cursor = cursor;
-}
-
-mpl.figure.prototype.handle_message = function(fig, msg) {
- fig.message.textContent = msg['message'];
-}
-
-mpl.figure.prototype.handle_draw = function(fig, msg) {
- // Request the server to send over a new figure.
- fig.send_draw_message();
-}
-
-mpl.figure.prototype.handle_image_mode = function(fig, msg) {
- fig.image_mode = msg['mode'];
-}
-
-mpl.figure.prototype.updated_canvas_event = function() {
- // Called whenever the canvas gets updated.
- this.send_message("ack", {});
-}
-
-// A function to construct a web socket function for onmessage handling.
-// Called in the figure constructor.
-mpl.figure.prototype._make_on_message_function = function(fig) {
- return function socket_on_message(evt) {
- if (evt.data instanceof Blob) {
- /* FIXME: We get "Resource interpreted as Image but
- * transferred with MIME type text/plain:" errors on
- * Chrome. But how to set the MIME type? It doesn't seem
- * to be part of the websocket stream */
- evt.data.type = "image/png";
-
- /* Free the memory for the previous frames */
- if (fig.imageObj.src) {
- (window.URL || window.webkitURL).revokeObjectURL(
- fig.imageObj.src);
- }
-
- fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(
- evt.data);
- fig.updated_canvas_event();
- fig.waiting = false;
- return;
- }
- else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == "data:image/png;base64") {
- fig.imageObj.src = evt.data;
- fig.updated_canvas_event();
- fig.waiting = false;
- return;
- }
-
- var msg = JSON.parse(evt.data);
- var msg_type = msg['type'];
-
- // Call the "handle_{type}" callback, which takes
- // the figure and JSON message as its only arguments.
- try {
- var callback = fig["handle_" + msg_type];
- } catch (e) {
- console.log("No handler for the '" + msg_type + "' message type: ", msg);
- return;
- }
-
- if (callback) {
- try {
- // console.log("Handling '" + msg_type + "' message: ", msg);
- callback(fig, msg);
- } catch (e) {
- console.log("Exception inside the 'handler_" + msg_type + "' callback:", e, e.stack, msg);
- }
- }
- };
-}
-
-// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas
-mpl.findpos = function(e) {
- //this section is from http://www.quirksmode.org/js/events_properties.html
- var targ;
- if (!e)
- e = window.event;
- if (e.target)
- targ = e.target;
- else if (e.srcElement)
- targ = e.srcElement;
- if (targ.nodeType == 3) // defeat Safari bug
- targ = targ.parentNode;
-
- // jQuery normalizes the pageX and pageY
- // pageX,Y are the mouse positions relative to the document
- // offset() returns the position of the element relative to the document
- var x = e.pageX - $(targ).offset().left;
- var y = e.pageY - $(targ).offset().top;
-
- return {"x": x, "y": y};
-};
-
-/*
- * return a copy of an object with only non-object keys
- * we need this to avoid circular references
- * http://stackoverflow.com/a/24161582/3208463
- */
-function simpleKeys (original) {
- return Object.keys(original).reduce(function (obj, key) {
- if (typeof original[key] !== 'object')
- obj[key] = original[key]
- return obj;
- }, {});
-}
-
-mpl.figure.prototype.mouse_event = function(event, name) {
- var canvas_pos = mpl.findpos(event)
-
- if (name === 'button_press')
- {
- this.canvas.focus();
- this.canvas_div.focus();
- }
-
- var x = canvas_pos.x * mpl.ratio;
- var y = canvas_pos.y * mpl.ratio;
-
- this.send_message(name, {x: x, y: y, button: event.button,
- step: event.step,
- guiEvent: simpleKeys(event)});
-
- /* This prevents the web browser from automatically changing to
- * the text insertion cursor when the button is pressed. We want
- * to control all of the cursor setting manually through the
- * 'cursor' event from matplotlib */
- event.preventDefault();
- return false;
-}
-
-mpl.figure.prototype._key_event_extra = function(event, name) {
- // Handle any extra behaviour associated with a key event
-}
-
-mpl.figure.prototype.key_event = function(event, name) {
-
- // Prevent repeat events
- if (name == 'key_press')
- {
- if (event.which === this._key)
- return;
- else
- this._key = event.which;
- }
- if (name == 'key_release')
- this._key = null;
-
- var value = '';
- if (event.ctrlKey && event.which != 17)
- value += "ctrl+";
- if (event.altKey && event.which != 18)
- value += "alt+";
- if (event.shiftKey && event.which != 16)
- value += "shift+";
-
- value += 'k';
- value += event.which.toString();
-
- this._key_event_extra(event, name);
-
- this.send_message(name, {key: value,
- guiEvent: simpleKeys(event)});
- return false;
-}
-
-mpl.figure.prototype.toolbar_button_onclick = function(name) {
- if (name == 'download') {
- this.handle_save(this, null);
- } else {
- this.send_message("toolbar_button", {name: name});
- }
-};
-
-mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) {
- this.message.textContent = tooltip;
-};
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/mpl_tornado.js b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/mpl_tornado.js
deleted file mode 100644
index 8eb5eedb50..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/mpl_tornado.js
+++ /dev/null
@@ -1,7 +0,0 @@
-/* This .js file contains functions for matplotlib's built-in
- tornado-based server, that are not relevant when embedding WebAgg
- in another web application. */
-
-function mpl_ondownload(figure, format) {
- window.open(figure.id + '/download.' + format, '_blank');
-}
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/nbagg_mpl.js b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/nbagg_mpl.js
deleted file mode 100644
index c421872ad5..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/nbagg_mpl.js
+++ /dev/null
@@ -1,208 +0,0 @@
-var comm_websocket_adapter = function(comm) {
- // Create a "websocket"-like object which calls the given IPython comm
- // object with the appropriate methods. Currently this is a non binary
- // socket, so there is still some room for performance tuning.
- var ws = {};
-
- ws.close = function() {
- comm.close()
- };
- ws.send = function(m) {
- //console.log('sending', m);
- comm.send(m);
- };
- // Register the callback with on_msg.
- comm.on_msg(function(msg) {
- //console.log('receiving', msg['content']['data'], msg);
- // Pass the mpl event to the overridden (by mpl) onmessage function.
- ws.onmessage(msg['content']['data'])
- });
- return ws;
-}
-
-mpl.mpl_figure_comm = function(comm, msg) {
- // This is the function which gets called when the mpl process
- // starts-up an IPython Comm through the "matplotlib" channel.
-
- var id = msg.content.data.id;
- // Get hold of the div created by the display call when the Comm
- // socket was opened in Python.
- var element = $("#" + id);
- var ws_proxy = comm_websocket_adapter(comm)
-
- function ondownload(figure, format) {
- window.open(figure.imageObj.src);
- }
-
- var fig = new mpl.figure(id, ws_proxy,
- ondownload,
- element.get(0));
-
- // Call onopen now - mpl needs it, as it is assuming we've passed it a real
- // web socket which is closed, not our websocket->open comm proxy.
- ws_proxy.onopen();
-
- fig.parent_element = element.get(0);
- fig.cell_info = mpl.find_output_cell("<div id='" + id + "'></div>");
- if (!fig.cell_info) {
- console.error("Failed to find cell for figure", id, fig);
- return;
- }
-
- var output_index = fig.cell_info[2]
- var cell = fig.cell_info[0];
-
-};
-
-mpl.figure.prototype.handle_close = function(fig, msg) {
- var width = fig.canvas.width/mpl.ratio
- fig.root.unbind('remove')
-
- // Update the output cell to use the data from the current canvas.
- fig.push_to_output();
- var dataURL = fig.canvas.toDataURL();
- // Re-enable the keyboard manager in IPython - without this line, in FF,
- // the notebook keyboard shortcuts fail.
- IPython.keyboard_manager.enable()
- $(fig.parent_element).html('<img src="' + dataURL + '" width="' + width + '">');
- fig.close_ws(fig, msg);
-}
-
-mpl.figure.prototype.close_ws = function(fig, msg){
- fig.send_message('closing', msg);
- // fig.ws.close()
-}
-
-mpl.figure.prototype.push_to_output = function(remove_interactive) {
- // Turn the data on the canvas into data in the output cell.
- var width = this.canvas.width/mpl.ratio
- var dataURL = this.canvas.toDataURL();
- this.cell_info[1]['text/html'] = '<img src="' + dataURL + '" width="' + width + '">';
-}
-
-mpl.figure.prototype.updated_canvas_event = function() {
- // Tell IPython that the notebook contents must change.
- IPython.notebook.set_dirty(true);
- this.send_message("ack", {});
- var fig = this;
- // Wait a second, then push the new image to the DOM so
- // that it is saved nicely (might be nice to debounce this).
- setTimeout(function () { fig.push_to_output() }, 1000);
-}
-
-mpl.figure.prototype._init_toolbar = function() {
- var fig = this;
-
- var nav_element = $('<div/>')
- nav_element.attr('style', 'width: 100%');
- this.root.append(nav_element);
-
- // Define a callback function for later on.
- function toolbar_event(event) {
- return fig.toolbar_button_onclick(event['data']);
- }
- function toolbar_mouse_event(event) {
- return fig.toolbar_button_onmouseover(event['data']);
- }
-
- for(var toolbar_ind in mpl.toolbar_items){
- var name = mpl.toolbar_items[toolbar_ind][0];
- var tooltip = mpl.toolbar_items[toolbar_ind][1];
- var image = mpl.toolbar_items[toolbar_ind][2];
- var method_name = mpl.toolbar_items[toolbar_ind][3];
-
- if (!name) { continue; };
-
- var button = $('<button class="btn btn-default" href="#" title="' + name + '"><i class="fa ' + image + ' fa-lg"></i></button>');
- button.click(method_name, toolbar_event);
- button.mouseover(tooltip, toolbar_mouse_event);
- nav_element.append(button);
- }
-
- // Add the status bar.
- var status_bar = $('<span class="mpl-message" style="text-align:right; float: right;"/>');
- nav_element.append(status_bar);
- this.message = status_bar[0];
-
- // Add the close button to the window.
- var buttongrp = $('<div class="btn-group inline pull-right"></div>');
- var button = $('<button class="btn btn-mini btn-primary" href="#" title="Stop Interaction"><i class="fa fa-power-off icon-remove icon-large"></i></button>');
- button.click(function (evt) { fig.handle_close(fig, {}); } );
- button.mouseover('Stop Interaction', toolbar_mouse_event);
- buttongrp.append(button);
- var titlebar = this.root.find($('.ui-dialog-titlebar'));
- titlebar.prepend(buttongrp);
-}
-
-mpl.figure.prototype._root_extra_style = function(el){
- var fig = this
- el.on("remove", function(){
- fig.close_ws(fig, {});
- });
-}
-
-mpl.figure.prototype._canvas_extra_style = function(el){
- // this is important to make the div 'focusable
- el.attr('tabindex', 0)
- // reach out to IPython and tell the keyboard manager to turn it's self
- // off when our div gets focus
-
- // location in version 3
- if (IPython.notebook.keyboard_manager) {
- IPython.notebook.keyboard_manager.register_events(el);
- }
- else {
- // location in version 2
- IPython.keyboard_manager.register_events(el);
- }
-
-}
-
-mpl.figure.prototype._key_event_extra = function(event, name) {
- var manager = IPython.notebook.keyboard_manager;
- if (!manager)
- manager = IPython.keyboard_manager;
-
- // Check for shift+enter
- if (event.shiftKey && event.which == 13) {
- this.canvas_div.blur();
- // select the cell after this one
- var index = IPython.notebook.find_cell_index(this.cell_info[0]);
- IPython.notebook.select(index + 1);
- }
-}
-
-mpl.figure.prototype.handle_save = function(fig, msg) {
- fig.ondownload(fig, null);
-}
-
-
-mpl.find_output_cell = function(html_output) {
- // Return the cell and output element which can be found *uniquely* in the notebook.
- // Note - this is a bit hacky, but it is done because the "notebook_saving.Notebook"
- // IPython event is triggered only after the cells have been serialised, which for
- // our purposes (turning an active figure into a static one), is too late.
- var cells = IPython.notebook.get_cells();
- var ncells = cells.length;
- for (var i=0; i<ncells; i++) {
- var cell = cells[i];
- if (cell.cell_type === 'code'){
- for (var j=0; j<cell.output_area.outputs.length; j++) {
- var data = cell.output_area.outputs[j];
- if (data.data) {
- // IPython >= 3 moved mimebundle to data attribute of output
- data = data.data;
- }
- if (data['text/html'] == html_output) {
- return [cell, data, j];
- }
- }
- }
- }
-}
-
-// Register the function which deals with the matplotlib target/channel.
-// The kernel may be null if the page has been refreshed.
-if (IPython.notebook.kernel != null) {
- IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm);
-}
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/nbagg_uat.ipynb b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/nbagg_uat.ipynb
deleted file mode 100644
index dfb264c375..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/nbagg_uat.ipynb
+++ /dev/null
@@ -1,640 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "from __future__ import print_function\n",
- "from imp import reload"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## UAT for NbAgg backend.\n",
- "\n",
- "The first line simply reloads matplotlib, uses the nbagg backend and then reloads the backend, just to ensure we have the latest modification to the backend code. Note: The underlying JavaScript will not be updated by this process, so a refresh of the browser after clearing the output and saving is necessary to clear everything fully."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "import matplotlib\n",
- "reload(matplotlib)\n",
- "\n",
- "matplotlib.use('nbagg')\n",
- "\n",
- "import matplotlib.backends.backend_nbagg\n",
- "reload(matplotlib.backends.backend_nbagg)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 1 - Simple figure creation using pyplot\n",
- "\n",
- "Should produce a figure window which is interactive with the pan and zoom buttons. (Do not press the close button, but any others may be used)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "import matplotlib.backends.backend_webagg_core\n",
- "reload(matplotlib.backends.backend_webagg_core)\n",
- "\n",
- "import matplotlib.pyplot as plt\n",
- "plt.interactive(False)\n",
- "\n",
- "fig1 = plt.figure()\n",
- "plt.plot(range(10))\n",
- "\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 2 - Creation of another figure, without the need to do plt.figure.\n",
- "\n",
- "As above, a new figure should be created."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "plt.plot([3, 2, 1])\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 3 - Connection info\n",
- "\n",
- "The printout should show that there are two figures which have active CommSockets, and no figures pending show."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "print(matplotlib.backends.backend_nbagg.connection_info())"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 4 - Closing figures\n",
- "\n",
- "Closing a specific figure instance should turn the figure into a plain image - the UI should have been removed. In this case, scroll back to the first figure and assert this is the case."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "plt.close(fig1)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 5 - No show without plt.show in non-interactive mode\n",
- "\n",
- "Simply doing a plt.plot should not show a new figure, nor indeed update an existing one (easily verified in UAT 6).\n",
- "The output should simply be a list of Line2D instances."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "plt.plot(range(10))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 6 - Connection information\n",
- "\n",
- "We just created a new figure, but didn't show it. Connection info should no longer have \"Figure 1\" (as we closed it in UAT 4) and should have figure 2 and 3, with Figure 3 without any connections. There should be 1 figure pending."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "print(matplotlib.backends.backend_nbagg.connection_info())"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 7 - Show of previously created figure\n",
- "\n",
- "We should be able to show a figure we've previously created. The following should produce two figure windows."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "plt.show()\n",
- "plt.figure()\n",
- "plt.plot(range(5))\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 8 - Interactive mode\n",
- "\n",
- "In interactive mode, creating a line should result in a figure being shown."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "plt.interactive(True)\n",
- "plt.figure()\n",
- "plt.plot([3, 2, 1])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Subsequent lines should be added to the existing figure, rather than creating a new one."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "plt.plot(range(3))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Calling connection_info in interactive mode should not show any pending figures."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "print(matplotlib.backends.backend_nbagg.connection_info())"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Disable interactive mode again."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "plt.interactive(False)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 9 - Multiple shows\n",
- "\n",
- "Unlike most of the other matplotlib backends, we may want to see a figure multiple times (with or without synchronisation between the views, though the former is not yet implemented). Assert that plt.gcf().canvas.manager.reshow() results in another figure window which is synchronised upon pan & zoom."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "plt.gcf().canvas.manager.reshow()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 10 - Saving notebook\n",
- "\n",
- "Saving the notebook (with CTRL+S or File->Save) should result in the saved notebook having static versions of the figues embedded within. The image should be the last update from user interaction and interactive plotting. (check by converting with ``ipython nbconvert <notebook>``)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 11 - Creation of a new figure on second show\n",
- "\n",
- "Create a figure, show it, then create a new axes and show it. The result should be a new figure.\n",
- "\n",
- "**BUG: Sometimes this doesn't work - not sure why (@pelson).**"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "fig = plt.figure()\n",
- "plt.axes()\n",
- "plt.show()\n",
- "\n",
- "plt.plot([1, 2, 3])\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 12 - OO interface\n",
- "\n",
- "Should produce a new figure and plot it."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "from matplotlib.backends.backend_nbagg import new_figure_manager,show\n",
- "\n",
- "manager = new_figure_manager(1000)\n",
- "fig = manager.canvas.figure\n",
- "ax = fig.add_subplot(1,1,1)\n",
- "ax.plot([1,2,3])\n",
- "fig.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## UAT 13 - Animation\n",
- "\n",
- "The following should generate an animated line:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "import matplotlib.animation as animation\n",
- "import numpy as np\n",
- "\n",
- "fig, ax = plt.subplots()\n",
- "\n",
- "x = np.arange(0, 2*np.pi, 0.01) # x-array\n",
- "line, = ax.plot(x, np.sin(x))\n",
- "\n",
- "def animate(i):\n",
- " line.set_ydata(np.sin(x+i/10.0)) # update the data\n",
- " return line,\n",
- "\n",
- "#Init only required for blitting to give a clean slate.\n",
- "def init():\n",
- " line.set_ydata(np.ma.array(x, mask=True))\n",
- " return line,\n",
- "\n",
- "ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), init_func=init,\n",
- " interval=32., blit=True)\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 14 - Keyboard shortcuts in IPython after close of figure\n",
- "\n",
- "After closing the previous figure (with the close button above the figure) the IPython keyboard shortcuts should still function.\n",
- "\n",
- "### UAT 15 - Figure face colours\n",
- "\n",
- "The nbagg honours all colours apart from that of the figure.patch. The two plots below should produce a figure with a red background. There should be no yellow figure."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "import matplotlib\n",
- "matplotlib.rcParams.update({'figure.facecolor': 'red',\n",
- " 'savefig.facecolor': 'yellow'})\n",
- "plt.figure()\n",
- "plt.plot([3, 2, 1])\n",
- "\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 16 - Events\n",
- "\n",
- "Pressing any keyboard key or mouse button (or scrolling) should cycle the line line while the figure has focus. The figure should have focus by default when it is created and re-gain it by clicking on the canvas. Clicking anywhere outside of the figure should release focus, but moving the mouse out of the figure should not release focus."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "import itertools\n",
- "fig, ax = plt.subplots()\n",
- "x = np.linspace(0,10,10000)\n",
- "y = np.sin(x)\n",
- "ln, = ax.plot(x,y)\n",
- "evt = []\n",
- "colors = iter(itertools.cycle(['r', 'g', 'b', 'k', 'c']))\n",
- "def on_event(event):\n",
- " if event.name.startswith('key'):\n",
- " fig.suptitle('%s: %s' % (event.name, event.key))\n",
- " elif event.name == 'scroll_event':\n",
- " fig.suptitle('%s: %s' % (event.name, event.step))\n",
- " else:\n",
- " fig.suptitle('%s: %s' % (event.name, event.button))\n",
- " evt.append(event)\n",
- " ln.set_color(next(colors))\n",
- " fig.canvas.draw()\n",
- " fig.canvas.draw_idle()\n",
- "\n",
- "fig.canvas.mpl_connect('button_press_event', on_event)\n",
- "fig.canvas.mpl_connect('button_release_event', on_event)\n",
- "fig.canvas.mpl_connect('scroll_event', on_event)\n",
- "fig.canvas.mpl_connect('key_press_event', on_event)\n",
- "fig.canvas.mpl_connect('key_release_event', on_event)\n",
- "\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 17 - Timers\n",
- "\n",
- "Single-shot timers follow a completely different code path in the nbagg backend than regular timers (such as those used in the animation example above.) The next set of tests ensures that both \"regular\" and \"single-shot\" timers work properly.\n",
- "\n",
- "The following should show a simple clock that updates twice a second:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "import time\n",
- "\n",
- "fig, ax = plt.subplots()\n",
- "text = ax.text(0.5, 0.5, '', ha='center')\n",
- "\n",
- "def update(text):\n",
- " text.set(text=time.ctime())\n",
- " text.axes.figure.canvas.draw()\n",
- " \n",
- "timer = fig.canvas.new_timer(500, [(update, [text], {})])\n",
- "timer.start()\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "However, the following should only update once and then stop:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "fig, ax = plt.subplots()\n",
- "text = ax.text(0.5, 0.5, '', ha='center') \n",
- "timer = fig.canvas.new_timer(500, [(update, [text], {})])\n",
- "\n",
- "timer.single_shot = True\n",
- "timer.start()\n",
- "\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "And the next two examples should never show any visible text at all:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "fig, ax = plt.subplots()\n",
- "text = ax.text(0.5, 0.5, '', ha='center')\n",
- "timer = fig.canvas.new_timer(500, [(update, [text], {})])\n",
- "\n",
- "timer.start()\n",
- "timer.stop()\n",
- "\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "fig, ax = plt.subplots()\n",
- "text = ax.text(0.5, 0.5, '', ha='center')\n",
- "timer = fig.canvas.new_timer(500, [(update, [text], {})])\n",
- "\n",
- "timer.single_shot = True\n",
- "timer.start()\n",
- "timer.stop()\n",
- "\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT17 - stopping figure when removed from DOM\n",
- "\n",
- "When the div that contains from the figure is removed from the DOM the figure should shut down it's comm, and if the python-side figure has no more active comms, it should destroy the figure. Repeatedly running the cell below should always have the same figure number"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "fig, ax = plt.subplots()\n",
- "ax.plot(range(5))\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Running the cell below will re-show the figure. After this, re-running the cell above should result in a new figure number."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": false
- },
- "outputs": [],
- "source": [
- "fig.canvas.manager.reshow()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.4.3"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 0
-}
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/single_figure.html b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/single_figure.html
deleted file mode 100644
index 4d5a366fbd..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/single_figure.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<html>
- <head>
- <link rel="stylesheet" href="{{ prefix }}/_static/css/page.css" type="text/css">
- <link rel="stylesheet" href="{{ prefix }}/_static/css/boilerplate.css" type="text/css" />
- <link rel="stylesheet" href="{{ prefix }}/_static/css/fbm.css" type="text/css" />
- <link rel="stylesheet" href="{{ prefix }}/_static/jquery-ui-1.12.1/jquery-ui.min.css" >
- <script src="{{ prefix }}/_static/jquery-ui-1.12.1/external/jquery/jquery.js"></script>
- <script src="{{ prefix }}/_static/jquery-ui-1.12.1/jquery-ui.min.js"></script>
- <script src="{{ prefix }}/_static/js/mpl_tornado.js"></script>
- <script src="{{ prefix }}/js/mpl.js"></script>
- <script>
- $(document).ready(
- function() {
- var websocket_type = mpl.get_websocket_type();
- var websocket = new websocket_type(
- "{{ ws_uri }}" + {{ repr(str(fig_id)) }} + "/ws");
- var fig = new mpl.figure(
- {{repr(str(fig_id))}}, websocket, mpl_ondownload, $('div#figure'));
- }
- );
- </script>
-
- <title>matplotlib</title>
- </head>
-
- <body>
- <div id="mpl-warnings" class="mpl-warnings"></div>
- <div id="figure" style="margin: 10px 10px;"></div>
- </body>
-</html>
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/windowing.py b/contrib/python/matplotlib/py2/matplotlib/backends/windowing.py
deleted file mode 100644
index 6c2e495906..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/windowing.py
+++ /dev/null
@@ -1,31 +0,0 @@
-"""
-MS Windows-specific helper for the TkAgg backend.
-
-With rcParams['tk.window_focus'] default of False, it is
-effectively disabled.
-
-It uses a tiny C++ extension module to access MS Win functions.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from matplotlib import rcParams
-
-try:
- if not rcParams['tk.window_focus']:
- raise ImportError
- from matplotlib._windowing import GetForegroundWindow, SetForegroundWindow
-except ImportError:
- def GetForegroundWindow():
- return 0
- def SetForegroundWindow(hwnd):
- pass
-
-class FocusManager(object):
- def __init__(self):
- self._shellWindow = GetForegroundWindow()
-
- def __del__(self):
- SetForegroundWindow(self._shellWindow)
diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/wx_compat.py b/contrib/python/matplotlib/py2/matplotlib/backends/wx_compat.py
deleted file mode 100644
index e8467fc15d..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/backends/wx_compat.py
+++ /dev/null
@@ -1,177 +0,0 @@
-"""
-A wx API adapter to hide differences between wxPython classic and phoenix.
-
-It is assumed that the user code is selecting what version it wants to use,
-here we just ensure that it meets the minimum required by matplotlib.
-
-For an example see embedding_in_wx2.py
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from distutils.version import StrictVersion, LooseVersion
-
-missingwx = "Matplotlib backend_wx and backend_wxagg require wxPython>=2.9"
-
-
-try:
- import wx
- backend_version = wx.VERSION_STRING
- is_phoenix = 'phoenix' in wx.PlatformInfo
-except ImportError:
- raise ImportError(missingwx)
-
-try:
- wx_version = StrictVersion(wx.VERSION_STRING)
-except ValueError:
- wx_version = LooseVersion(wx.VERSION_STRING)
-
-# Ensure we have the correct version imported
-if wx_version < str("2.9"):
- raise ImportError(missingwx)
-
-if is_phoenix:
- # define all the wxPython phoenix stuff
-
- # font styles, families and weight
- fontweights = {
- 100: wx.FONTWEIGHT_LIGHT,
- 200: wx.FONTWEIGHT_LIGHT,
- 300: wx.FONTWEIGHT_LIGHT,
- 400: wx.FONTWEIGHT_NORMAL,
- 500: wx.FONTWEIGHT_NORMAL,
- 600: wx.FONTWEIGHT_NORMAL,
- 700: wx.FONTWEIGHT_BOLD,
- 800: wx.FONTWEIGHT_BOLD,
- 900: wx.FONTWEIGHT_BOLD,
- 'ultralight': wx.FONTWEIGHT_LIGHT,
- 'light': wx.FONTWEIGHT_LIGHT,
- 'normal': wx.FONTWEIGHT_NORMAL,
- 'medium': wx.FONTWEIGHT_NORMAL,
- 'semibold': wx.FONTWEIGHT_NORMAL,
- 'bold': wx.FONTWEIGHT_BOLD,
- 'heavy': wx.FONTWEIGHT_BOLD,
- 'ultrabold': wx.FONTWEIGHT_BOLD,
- 'black': wx.FONTWEIGHT_BOLD
- }
- fontangles = {
- 'italic': wx.FONTSTYLE_ITALIC,
- 'normal': wx.FONTSTYLE_NORMAL,
- 'oblique': wx.FONTSTYLE_SLANT}
-
- # wxPython allows for portable font styles, choosing them appropriately
- # for the target platform. Map some standard font names to the portable
- # styles
- # QUESTION: Is it be wise to agree standard fontnames across all backends?
- fontnames = {'Sans': wx.FONTFAMILY_SWISS,
- 'Roman': wx.FONTFAMILY_ROMAN,
- 'Script': wx.FONTFAMILY_SCRIPT,
- 'Decorative': wx.FONTFAMILY_DECORATIVE,
- 'Modern': wx.FONTFAMILY_MODERN,
- 'Courier': wx.FONTFAMILY_MODERN,
- 'courier': wx.FONTFAMILY_MODERN}
-
- dashd_wx = {'solid': wx.PENSTYLE_SOLID,
- 'dashed': wx.PENSTYLE_SHORT_DASH,
- 'dashdot': wx.PENSTYLE_DOT_DASH,
- 'dotted': wx.PENSTYLE_DOT}
-
- # functions changes
- BitmapFromBuffer = wx.Bitmap.FromBufferRGBA
- EmptyBitmap = wx.Bitmap
- EmptyImage = wx.Image
- Cursor = wx.Cursor
- EventLoop = wx.GUIEventLoop
- NamedColour = wx.Colour
- StockCursor = wx.Cursor
-
-else:
- # define all the wxPython classic stuff
-
- # font styles, families and weight
- fontweights = {
- 100: wx.LIGHT,
- 200: wx.LIGHT,
- 300: wx.LIGHT,
- 400: wx.NORMAL,
- 500: wx.NORMAL,
- 600: wx.NORMAL,
- 700: wx.BOLD,
- 800: wx.BOLD,
- 900: wx.BOLD,
- 'ultralight': wx.LIGHT,
- 'light': wx.LIGHT,
- 'normal': wx.NORMAL,
- 'medium': wx.NORMAL,
- 'semibold': wx.NORMAL,
- 'bold': wx.BOLD,
- 'heavy': wx.BOLD,
- 'ultrabold': wx.BOLD,
- 'black': wx.BOLD
- }
- fontangles = {
- 'italic': wx.ITALIC,
- 'normal': wx.NORMAL,
- 'oblique': wx.SLANT}
-
- # wxPython allows for portable font styles, choosing them appropriately
- # for the target platform. Map some standard font names to the portable
- # styles
- # QUESTION: Is it be wise to agree standard fontnames across all backends?
- fontnames = {'Sans': wx.SWISS,
- 'Roman': wx.ROMAN,
- 'Script': wx.SCRIPT,
- 'Decorative': wx.DECORATIVE,
- 'Modern': wx.MODERN,
- 'Courier': wx.MODERN,
- 'courier': wx.MODERN}
-
- dashd_wx = {'solid': wx.SOLID,
- 'dashed': wx.SHORT_DASH,
- 'dashdot': wx.DOT_DASH,
- 'dotted': wx.DOT}
-
- # functions changes
- BitmapFromBuffer = wx.BitmapFromBufferRGBA
- EmptyBitmap = wx.EmptyBitmap
- EmptyImage = wx.EmptyImage
- Cursor = wx.StockCursor
- EventLoop = wx.EventLoop
- NamedColour = wx.NamedColour
- StockCursor = wx.StockCursor
-
-
-# wxPython Classic's DoAddTool has become AddTool in Phoenix. Otherwise
-# they are the same, except for early betas and prerelease builds of
-# Phoenix. This function provides a shim that does the RightThing based on
-# which wxPython is in use.
-def _AddTool(parent, wx_ids, text, bmp, tooltip_text):
- if text in ['Pan', 'Zoom']:
- kind = wx.ITEM_CHECK
- else:
- kind = wx.ITEM_NORMAL
- if is_phoenix:
- add_tool = parent.AddTool
- else:
- add_tool = parent.DoAddTool
-
- if not is_phoenix or wx_version >= str("4.0.0b2"):
- # NOTE: when support for Phoenix prior to 4.0.0b2 is dropped then
- # all that is needed is this clause, and the if and else clause can
- # be removed.
- kwargs = dict(label=text,
- bitmap=bmp,
- bmpDisabled=wx.NullBitmap,
- shortHelp=text,
- longHelp=tooltip_text,
- kind=kind)
- else:
- kwargs = dict(label=text,
- bitmap=bmp,
- bmpDisabled=wx.NullBitmap,
- shortHelpString=text,
- longHelpString=tooltip_text,
- kind=kind)
-
- return add_tool(wx_ids[text], **kwargs)
diff --git a/contrib/python/matplotlib/py2/matplotlib/bezier.py b/contrib/python/matplotlib/py2/matplotlib/bezier.py
deleted file mode 100644
index 80fbd6137e..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/bezier.py
+++ /dev/null
@@ -1,495 +0,0 @@
-"""
-A module providing some utility functions regarding bezier path manipulation.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import numpy as np
-from matplotlib.path import Path
-
-from operator import xor
-import warnings
-
-
-class NonIntersectingPathException(ValueError):
- pass
-
-# some functions
-
-
-def get_intersection(cx1, cy1, cos_t1, sin_t1,
- cx2, cy2, cos_t2, sin_t2):
- """ return a intersecting point between a line through (cx1, cy1)
- and having angle t1 and a line through (cx2, cy2) and angle t2.
- """
-
- # line1 => sin_t1 * (x - cx1) - cos_t1 * (y - cy1) = 0.
- # line1 => sin_t1 * x + cos_t1 * y = sin_t1*cx1 - cos_t1*cy1
-
- line1_rhs = sin_t1 * cx1 - cos_t1 * cy1
- line2_rhs = sin_t2 * cx2 - cos_t2 * cy2
-
- # rhs matrix
- a, b = sin_t1, -cos_t1
- c, d = sin_t2, -cos_t2
-
- ad_bc = a * d - b * c
- if ad_bc == 0.:
- raise ValueError("Given lines do not intersect")
-
- # rhs_inverse
- a_, b_ = d, -b
- c_, d_ = -c, a
- a_, b_, c_, d_ = [k / ad_bc for k in [a_, b_, c_, d_]]
-
- x = a_ * line1_rhs + b_ * line2_rhs
- y = c_ * line1_rhs + d_ * line2_rhs
-
- return x, y
-
-
-def get_normal_points(cx, cy, cos_t, sin_t, length):
- """
- For a line passing through (*cx*, *cy*) and having a angle *t*, return
- locations of the two points located along its perpendicular line at the
- distance of *length*.
- """
-
- if length == 0.:
- return cx, cy, cx, cy
-
- cos_t1, sin_t1 = sin_t, -cos_t
- cos_t2, sin_t2 = -sin_t, cos_t
-
- x1, y1 = length * cos_t1 + cx, length * sin_t1 + cy
- x2, y2 = length * cos_t2 + cx, length * sin_t2 + cy
-
- return x1, y1, x2, y2
-
-
-# BEZIER routines
-
-# subdividing bezier curve
-# http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/bezier-sub.html
-
-
-def _de_casteljau1(beta, t):
- next_beta = beta[:-1] * (1 - t) + beta[1:] * t
- return next_beta
-
-
-def split_de_casteljau(beta, t):
- """split a bezier segment defined by its controlpoints *beta*
- into two separate segment divided at *t* and return their control points.
-
- """
- beta = np.asarray(beta)
- beta_list = [beta]
- while True:
- beta = _de_casteljau1(beta, t)
- beta_list.append(beta)
- if len(beta) == 1:
- break
- left_beta = [beta[0] for beta in beta_list]
- right_beta = [beta[-1] for beta in reversed(beta_list)]
-
- return left_beta, right_beta
-
-
-# FIXME spelling mistake in the name of the parameter ``tolerence``
-def find_bezier_t_intersecting_with_closedpath(bezier_point_at_t,
- inside_closedpath,
- t0=0., t1=1., tolerence=0.01):
- """ Find a parameter t0 and t1 of the given bezier path which
- bounds the intersecting points with a provided closed
- path(*inside_closedpath*). Search starts from *t0* and *t1* and it
- uses a simple bisecting algorithm therefore one of the end point
- must be inside the path while the orther doesn't. The search stop
- when |t0-t1| gets smaller than the given tolerence.
- value for
-
- - bezier_point_at_t : a function which returns x, y coordinates at *t*
-
- - inside_closedpath : return True if the point is inside the path
-
- """
- # inside_closedpath : function
-
- start = bezier_point_at_t(t0)
- end = bezier_point_at_t(t1)
-
- start_inside = inside_closedpath(start)
- end_inside = inside_closedpath(end)
-
- if start_inside == end_inside and start != end:
- raise NonIntersectingPathException(
- "Both points are on the same side of the closed path")
-
- while True:
-
- # return if the distance is smaller than the tolerence
- if np.hypot(start[0] - end[0], start[1] - end[1]) < tolerence:
- return t0, t1
-
- # calculate the middle point
- middle_t = 0.5 * (t0 + t1)
- middle = bezier_point_at_t(middle_t)
- middle_inside = inside_closedpath(middle)
-
- if xor(start_inside, middle_inside):
- t1 = middle_t
- end = middle
- end_inside = middle_inside
- else:
- t0 = middle_t
- start = middle
- start_inside = middle_inside
-
-
-class BezierSegment(object):
- """
- A simple class of a 2-dimensional bezier segment
- """
-
- # Higher order bezier lines can be supported by simplying adding
- # corresponding values.
- _binom_coeff = {1: np.array([1., 1.]),
- 2: np.array([1., 2., 1.]),
- 3: np.array([1., 3., 3., 1.])}
-
- def __init__(self, control_points):
- """
- *control_points* : location of contol points. It needs have a
- shpae of n * 2, where n is the order of the bezier line. 1<=
- n <= 3 is supported.
- """
- _o = len(control_points)
- self._orders = np.arange(_o)
-
- _coeff = BezierSegment._binom_coeff[_o - 1]
- xx, yy = np.asarray(control_points).T
- self._px = xx * _coeff
- self._py = yy * _coeff
-
- def point_at_t(self, t):
- "evaluate a point at t"
- tt = ((1 - t) ** self._orders)[::-1] * t ** self._orders
- _x = np.dot(tt, self._px)
- _y = np.dot(tt, self._py)
- return _x, _y
-
-
-def split_bezier_intersecting_with_closedpath(bezier,
- inside_closedpath,
- tolerence=0.01):
-
- """
- bezier : control points of the bezier segment
- inside_closedpath : a function which returns true if the point is inside
- the path
- """
-
- bz = BezierSegment(bezier)
- bezier_point_at_t = bz.point_at_t
-
- t0, t1 = find_bezier_t_intersecting_with_closedpath(bezier_point_at_t,
- inside_closedpath,
- tolerence=tolerence)
-
- _left, _right = split_de_casteljau(bezier, (t0 + t1) / 2.)
- return _left, _right
-
-
-def find_r_to_boundary_of_closedpath(inside_closedpath, xy,
- cos_t, sin_t,
- rmin=0., rmax=1., tolerence=0.01):
- """
- Find a radius r (centered at *xy*) between *rmin* and *rmax* at
- which it intersect with the path.
-
- inside_closedpath : function
- cx, cy : center
- cos_t, sin_t : cosine and sine for the angle
- rmin, rmax :
- """
-
- cx, cy = xy
-
- def _f(r):
- return cos_t * r + cx, sin_t * r + cy
-
- find_bezier_t_intersecting_with_closedpath(_f, inside_closedpath,
- t0=rmin, t1=rmax,
- tolerence=tolerence)
-
-# matplotlib specific
-
-
-def split_path_inout(path, inside, tolerence=0.01, reorder_inout=False):
- """ divide a path into two segment at the point where inside(x, y)
- becomes False.
- """
-
- path_iter = path.iter_segments()
-
- ctl_points, command = next(path_iter)
- begin_inside = inside(ctl_points[-2:]) # true if begin point is inside
-
- ctl_points_old = ctl_points
-
- concat = np.concatenate
-
- iold = 0
- i = 1
-
- for ctl_points, command in path_iter:
- iold = i
- i += len(ctl_points) // 2
- if inside(ctl_points[-2:]) != begin_inside:
- bezier_path = concat([ctl_points_old[-2:], ctl_points])
- break
- ctl_points_old = ctl_points
- else:
- raise ValueError("The path does not intersect with the patch")
-
- bp = bezier_path.reshape((-1, 2))
- left, right = split_bezier_intersecting_with_closedpath(
- bp, inside, tolerence)
- if len(left) == 2:
- codes_left = [Path.LINETO]
- codes_right = [Path.MOVETO, Path.LINETO]
- elif len(left) == 3:
- codes_left = [Path.CURVE3, Path.CURVE3]
- codes_right = [Path.MOVETO, Path.CURVE3, Path.CURVE3]
- elif len(left) == 4:
- codes_left = [Path.CURVE4, Path.CURVE4, Path.CURVE4]
- codes_right = [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4]
- else:
- raise AssertionError("This should never be reached")
-
- verts_left = left[1:]
- verts_right = right[:]
-
- if path.codes is None:
- path_in = Path(concat([path.vertices[:i], verts_left]))
- path_out = Path(concat([verts_right, path.vertices[i:]]))
-
- else:
- path_in = Path(concat([path.vertices[:iold], verts_left]),
- concat([path.codes[:iold], codes_left]))
-
- path_out = Path(concat([verts_right, path.vertices[i:]]),
- concat([codes_right, path.codes[i:]]))
-
- if reorder_inout and begin_inside is False:
- path_in, path_out = path_out, path_in
-
- return path_in, path_out
-
-
-def inside_circle(cx, cy, r):
- r2 = r ** 2
-
- def _f(xy):
- x, y = xy
- return (x - cx) ** 2 + (y - cy) ** 2 < r2
- return _f
-
-
-# quadratic bezier lines
-
-def get_cos_sin(x0, y0, x1, y1):
- dx, dy = x1 - x0, y1 - y0
- d = (dx * dx + dy * dy) ** .5
- # Account for divide by zero
- if d == 0:
- return 0.0, 0.0
- return dx / d, dy / d
-
-
-def check_if_parallel(dx1, dy1, dx2, dy2, tolerence=1.e-5):
- """ returns
- * 1 if two lines are parralel in same direction
- * -1 if two lines are parralel in opposite direction
- * 0 otherwise
- """
- theta1 = np.arctan2(dx1, dy1)
- theta2 = np.arctan2(dx2, dy2)
- dtheta = np.abs(theta1 - theta2)
- if dtheta < tolerence:
- return 1
- elif np.abs(dtheta - np.pi) < tolerence:
- return -1
- else:
- return False
-
-
-def get_parallels(bezier2, width):
- """
- Given the quadratic bezier control points *bezier2*, returns
- control points of quadratic bezier lines roughly parallel to given
- one separated by *width*.
- """
-
- # The parallel bezier lines are constructed by following ways.
- # c1 and c2 are control points representing the begin and end of the
- # bezier line.
- # cm is the middle point
-
- c1x, c1y = bezier2[0]
- cmx, cmy = bezier2[1]
- c2x, c2y = bezier2[2]
-
- parallel_test = check_if_parallel(c1x - cmx, c1y - cmy,
- cmx - c2x, cmy - c2y)
-
- if parallel_test == -1:
- warnings.warn(
- "Lines do not intersect. A straight line is used instead.")
- cos_t1, sin_t1 = get_cos_sin(c1x, c1y, c2x, c2y)
- cos_t2, sin_t2 = cos_t1, sin_t1
- else:
- # t1 and t2 is the angle between c1 and cm, cm, c2. They are
- # also a angle of the tangential line of the path at c1 and c2
- cos_t1, sin_t1 = get_cos_sin(c1x, c1y, cmx, cmy)
- cos_t2, sin_t2 = get_cos_sin(cmx, cmy, c2x, c2y)
-
- # find c1_left, c1_right which are located along the lines
- # through c1 and perpendicular to the tangential lines of the
- # bezier path at a distance of width. Same thing for c2_left and
- # c2_right with respect to c2.
- c1x_left, c1y_left, c1x_right, c1y_right = (
- get_normal_points(c1x, c1y, cos_t1, sin_t1, width)
- )
- c2x_left, c2y_left, c2x_right, c2y_right = (
- get_normal_points(c2x, c2y, cos_t2, sin_t2, width)
- )
-
- # find cm_left which is the intersectng point of a line through
- # c1_left with angle t1 and a line through c2_left with angle
- # t2. Same with cm_right.
- if parallel_test != 0:
- # a special case for a straight line, i.e., angle between two
- # lines are smaller than some (arbitrtay) value.
- cmx_left, cmy_left = (
- 0.5 * (c1x_left + c2x_left), 0.5 * (c1y_left + c2y_left)
- )
- cmx_right, cmy_right = (
- 0.5 * (c1x_right + c2x_right), 0.5 * (c1y_right + c2y_right)
- )
- else:
- cmx_left, cmy_left = get_intersection(c1x_left, c1y_left, cos_t1,
- sin_t1, c2x_left, c2y_left,
- cos_t2, sin_t2)
-
- cmx_right, cmy_right = get_intersection(c1x_right, c1y_right, cos_t1,
- sin_t1, c2x_right, c2y_right,
- cos_t2, sin_t2)
-
- # the parallel bezier lines are created with control points of
- # [c1_left, cm_left, c2_left] and [c1_right, cm_right, c2_right]
- path_left = [(c1x_left, c1y_left),
- (cmx_left, cmy_left),
- (c2x_left, c2y_left)]
- path_right = [(c1x_right, c1y_right),
- (cmx_right, cmy_right),
- (c2x_right, c2y_right)]
-
- return path_left, path_right
-
-
-def find_control_points(c1x, c1y, mmx, mmy, c2x, c2y):
- """ Find control points of the bezier line through c1, mm, c2. We
- simply assume that c1, mm, c2 which have parametric value 0, 0.5, and 1.
- """
-
- cmx = .5 * (4 * mmx - (c1x + c2x))
- cmy = .5 * (4 * mmy - (c1y + c2y))
-
- return [(c1x, c1y), (cmx, cmy), (c2x, c2y)]
-
-
-def make_wedged_bezier2(bezier2, width, w1=1., wm=0.5, w2=0.):
- """
- Being similar to get_parallels, returns control points of two quadrativ
- bezier lines having a width roughly parallel to given one separated by
- *width*.
- """
-
- # c1, cm, c2
- c1x, c1y = bezier2[0]
- cmx, cmy = bezier2[1]
- c3x, c3y = bezier2[2]
-
- # t1 and t2 is the angle between c1 and cm, cm, c3.
- # They are also a angle of the tangential line of the path at c1 and c3
- cos_t1, sin_t1 = get_cos_sin(c1x, c1y, cmx, cmy)
- cos_t2, sin_t2 = get_cos_sin(cmx, cmy, c3x, c3y)
-
- # find c1_left, c1_right which are located along the lines
- # through c1 and perpendicular to the tangential lines of the
- # bezier path at a distance of width. Same thing for c3_left and
- # c3_right with respect to c3.
- c1x_left, c1y_left, c1x_right, c1y_right = (
- get_normal_points(c1x, c1y, cos_t1, sin_t1, width * w1)
- )
- c3x_left, c3y_left, c3x_right, c3y_right = (
- get_normal_points(c3x, c3y, cos_t2, sin_t2, width * w2)
- )
-
- # find c12, c23 and c123 which are middle points of c1-cm, cm-c3 and
- # c12-c23
- c12x, c12y = (c1x + cmx) * .5, (c1y + cmy) * .5
- c23x, c23y = (cmx + c3x) * .5, (cmy + c3y) * .5
- c123x, c123y = (c12x + c23x) * .5, (c12y + c23y) * .5
-
- # tangential angle of c123 (angle between c12 and c23)
- cos_t123, sin_t123 = get_cos_sin(c12x, c12y, c23x, c23y)
-
- c123x_left, c123y_left, c123x_right, c123y_right = (
- get_normal_points(c123x, c123y, cos_t123, sin_t123, width * wm)
- )
-
- path_left = find_control_points(c1x_left, c1y_left,
- c123x_left, c123y_left,
- c3x_left, c3y_left)
- path_right = find_control_points(c1x_right, c1y_right,
- c123x_right, c123y_right,
- c3x_right, c3y_right)
-
- return path_left, path_right
-
-
-def make_path_regular(p):
- """
- fill in the codes if None.
- """
- c = p.codes
- if c is None:
- c = np.empty(p.vertices.shape[:1], "i")
- c.fill(Path.LINETO)
- c[0] = Path.MOVETO
-
- return Path(p.vertices, c)
- else:
- return p
-
-
-def concatenate_paths(paths):
- """
- concatenate list of paths into a single path.
- """
-
- vertices = []
- codes = []
- for p in paths:
- p = make_path_regular(p)
- vertices.append(p.vertices)
- codes.append(p.codes)
-
- _path = Path(np.concatenate(vertices),
- np.concatenate(codes))
- return _path
diff --git a/contrib/python/matplotlib/py2/matplotlib/blocking_input.py b/contrib/python/matplotlib/py2/matplotlib/blocking_input.py
deleted file mode 100644
index 090ffdb864..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/blocking_input.py
+++ /dev/null
@@ -1,375 +0,0 @@
-"""
-This provides several classes used for blocking interaction with figure
-windows:
-
-:class:`BlockingInput`
- creates a callable object to retrieve events in a blocking way for
- interactive sessions
-
-:class:`BlockingKeyMouseInput`
- creates a callable object to retrieve key or mouse clicks in a blocking
- way for interactive sessions.
- Note: Subclass of BlockingInput. Used by waitforbuttonpress
-
-:class:`BlockingMouseInput`
- creates a callable object to retrieve mouse clicks in a blocking way for
- interactive sessions.
- Note: Subclass of BlockingInput. Used by ginput
-
-:class:`BlockingContourLabeler`
- creates a callable object to retrieve mouse clicks in a blocking way that
- will then be used to place labels on a ContourSet
- Note: Subclass of BlockingMouseInput. Used by clabel
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-import matplotlib.lines as mlines
-
-import logging
-
-_log = logging.getLogger(__name__)
-
-
-class BlockingInput(object):
- """
- Class that creates a callable object to retrieve events in a
- blocking way.
- """
- def __init__(self, fig, eventslist=()):
- self.fig = fig
- self.eventslist = eventslist
-
- def on_event(self, event):
- """
- Event handler that will be passed to the current figure to
- retrieve events.
- """
- # Add a new event to list - using a separate function is
- # overkill for the base class, but this is consistent with
- # subclasses
- self.add_event(event)
- _log.info("Event %i", len(self.events))
-
- # This will extract info from events
- self.post_event()
-
- # Check if we have enough events already
- if len(self.events) >= self.n and self.n > 0:
- self.fig.canvas.stop_event_loop()
-
- def post_event(self):
- """For baseclass, do nothing but collect events"""
- pass
-
- def cleanup(self):
- """Disconnect all callbacks"""
- for cb in self.callbacks:
- self.fig.canvas.mpl_disconnect(cb)
-
- self.callbacks = []
-
- def add_event(self, event):
- """For base class, this just appends an event to events."""
- self.events.append(event)
-
- def pop_event(self, index=-1):
- """
- This removes an event from the event list. Defaults to
- removing last event, but an index can be supplied. Note that
- this does not check that there are events, much like the
- normal pop method. If not events exist, this will throw an
- exception.
- """
- self.events.pop(index)
-
- def pop(self, index=-1):
- self.pop_event(index)
- pop.__doc__ = pop_event.__doc__
-
- def __call__(self, n=1, timeout=30):
- """
- Blocking call to retrieve n events
- """
-
- if not isinstance(n, int):
- raise ValueError("Requires an integer argument")
- self.n = n
-
- self.events = []
- self.callbacks = []
-
- if hasattr(self.fig.canvas, "manager"):
- # Ensure that the figure is shown, if we are managing it.
- self.fig.show()
-
- # connect the events to the on_event function call
- for n in self.eventslist:
- self.callbacks.append(
- self.fig.canvas.mpl_connect(n, self.on_event))
-
- try:
- # Start event loop
- self.fig.canvas.start_event_loop(timeout=timeout)
- finally: # Run even on exception like ctrl-c
- # Disconnect the callbacks
- self.cleanup()
-
- # Return the events in this case
- return self.events
-
-
-class BlockingMouseInput(BlockingInput):
- """
- Class that creates a callable object to retrieve mouse clicks in a
- blocking way.
-
- This class will also retrieve keyboard clicks and treat them like
- appropriate mouse clicks (delete and backspace are like mouse button 3,
- enter is like mouse button 2 and all others are like mouse button 1).
- """
-
- button_add = 1
- button_pop = 3
- button_stop = 2
-
- def __init__(self, fig, mouse_add=1, mouse_pop=3, mouse_stop=2):
- BlockingInput.__init__(self, fig=fig,
- eventslist=('button_press_event',
- 'key_press_event'))
- self.button_add = mouse_add
- self.button_pop = mouse_pop
- self.button_stop = mouse_stop
-
- def post_event(self):
- """
- This will be called to process events
- """
- if len(self.events) == 0:
- _log.warning("No events yet")
- elif self.events[-1].name == 'key_press_event':
- self.key_event()
- else:
- self.mouse_event()
-
- def mouse_event(self):
- '''Process a mouse click event'''
-
- event = self.events[-1]
- button = event.button
-
- if button == self.button_pop:
- self.mouse_event_pop(event)
- elif button == self.button_stop:
- self.mouse_event_stop(event)
- else:
- self.mouse_event_add(event)
-
- def key_event(self):
- '''
- Process a key click event. This maps certain keys to appropriate
- mouse click events.
- '''
-
- event = self.events[-1]
- if event.key is None:
- # at least in mac os X gtk backend some key returns None.
- return
-
- key = event.key.lower()
-
- if key in ['backspace', 'delete']:
- self.mouse_event_pop(event)
- elif key in ['escape', 'enter']:
- # on windows XP and wxAgg, the enter key doesn't seem to register
- self.mouse_event_stop(event)
- else:
- self.mouse_event_add(event)
-
- def mouse_event_add(self, event):
- """
- Will be called for any event involving a button other than
- button 2 or 3. This will add a click if it is inside axes.
- """
- if event.inaxes:
- self.add_click(event)
- else: # If not a valid click, remove from event list
- BlockingInput.pop(self, -1)
-
- def mouse_event_stop(self, event):
- """
- Will be called for any event involving button 2.
- Button 2 ends blocking input.
- """
-
- # Remove last event just for cleanliness
- BlockingInput.pop(self, -1)
-
- # This will exit even if not in infinite mode. This is
- # consistent with MATLAB and sometimes quite useful, but will
- # require the user to test how many points were actually
- # returned before using data.
- self.fig.canvas.stop_event_loop()
-
- def mouse_event_pop(self, event):
- """
- Will be called for any event involving button 3.
- Button 3 removes the last click.
- """
- # Remove this last event
- BlockingInput.pop(self, -1)
-
- # Now remove any existing clicks if possible
- if len(self.events) > 0:
- self.pop(event, -1)
-
- def add_click(self, event):
- """
- This add the coordinates of an event to the list of clicks
- """
- self.clicks.append((event.xdata, event.ydata))
- _log.info("input %i: %f,%f" %
- (len(self.clicks), event.xdata, event.ydata))
-
- # If desired plot up click
- if self.show_clicks:
- line = mlines.Line2D([event.xdata], [event.ydata],
- marker='+', color='r')
- event.inaxes.add_line(line)
- self.marks.append(line)
- self.fig.canvas.draw()
-
- def pop_click(self, event, index=-1):
- """
- This removes a click from the list of clicks. Defaults to
- removing the last click.
- """
- self.clicks.pop(index)
-
- if self.show_clicks:
-
- mark = self.marks.pop(index)
- mark.remove()
-
- self.fig.canvas.draw()
- # NOTE: I do NOT understand why the above 3 lines does not work
- # for the keyboard backspace event on windows XP wxAgg.
- # maybe event.inaxes here is a COPY of the actual axes?
-
- def pop(self, event, index=-1):
- """
- This removes a click and the associated event from the object.
- Defaults to removing the last click, but any index can be
- supplied.
- """
- self.pop_click(event, index)
- BlockingInput.pop(self, index)
-
- def cleanup(self, event=None):
- # clean the figure
- if self.show_clicks:
-
- for mark in self.marks:
- mark.remove()
- self.marks = []
-
- self.fig.canvas.draw()
-
- # Call base class to remove callbacks
- BlockingInput.cleanup(self)
-
- def __call__(self, n=1, timeout=30, show_clicks=True):
- """
- Blocking call to retrieve n coordinate pairs through mouse
- clicks.
- """
- self.show_clicks = show_clicks
- self.clicks = []
- self.marks = []
- BlockingInput.__call__(self, n=n, timeout=timeout)
-
- return self.clicks
-
-
-class BlockingContourLabeler(BlockingMouseInput):
- """
- Class that creates a callable object that uses mouse clicks or key
- clicks on a figure window to place contour labels.
- """
- def __init__(self, cs):
- self.cs = cs
- BlockingMouseInput.__init__(self, fig=cs.ax.figure)
-
- def add_click(self, event):
- self.button1(event)
-
- def pop_click(self, event, index=-1):
- self.button3(event)
-
- def button1(self, event):
- """
- This will be called if an event involving a button other than
- 2 or 3 occcurs. This will add a label to a contour.
- """
-
- # Shorthand
- if event.inaxes == self.cs.ax:
- self.cs.add_label_near(event.x, event.y, self.inline,
- inline_spacing=self.inline_spacing,
- transform=False)
- self.fig.canvas.draw()
- else: # Remove event if not valid
- BlockingInput.pop(self)
-
- def button3(self, event):
- """
- This will be called if button 3 is clicked. This will remove
- a label if not in inline mode. Unfortunately, if one is doing
- inline labels, then there is currently no way to fix the
- broken contour - once humpty-dumpty is broken, he can't be put
- back together. In inline mode, this does nothing.
- """
-
- if self.inline:
- pass
- else:
- self.cs.pop_label()
- self.cs.ax.figure.canvas.draw()
-
- def __call__(self, inline, inline_spacing=5, n=-1, timeout=-1):
- self.inline = inline
- self.inline_spacing = inline_spacing
-
- BlockingMouseInput.__call__(self, n=n, timeout=timeout,
- show_clicks=False)
-
-
-class BlockingKeyMouseInput(BlockingInput):
- """
- Class that creates a callable object to retrieve a single mouse or
- keyboard click
- """
- def __init__(self, fig):
- BlockingInput.__init__(self, fig=fig, eventslist=(
- 'button_press_event', 'key_press_event'))
-
- def post_event(self):
- """
- Determines if it is a key event
- """
- if len(self.events) == 0:
- _log.warning("No events yet")
- else:
- self.keyormouse = self.events[-1].name == 'key_press_event'
-
- def __call__(self, timeout=30):
- """
- Blocking call to retrieve a single mouse or key click
- Returns True if key click, False if mouse, or None if timeout
- """
- self.keyormouse = None
- BlockingInput.__call__(self, n=1, timeout=timeout)
-
- return self.keyormouse
diff --git a/contrib/python/matplotlib/py2/matplotlib/category.py b/contrib/python/matplotlib/py2/matplotlib/category.py
deleted file mode 100644
index b135bff1cc..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/category.py
+++ /dev/null
@@ -1,211 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-Module that allows plotting of string "category" data. i.e.
-``plot(['d', 'f', 'a'],[1, 2, 3])`` will plot three points with x-axis
-values of 'd', 'f', 'a'.
-
-See :doc:`/gallery/lines_bars_and_markers/categorical_variables` for an
-example.
-
-The module uses Matplotlib's `matplotlib.units` mechanism to convert from
-strings to integers, provides a tick locator and formatter, and the
-class:`.UnitData` that creates and stores the string-to-integer mapping.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from collections import OrderedDict
-import itertools
-
-import six
-
-
-import numpy as np
-
-import matplotlib.units as units
-import matplotlib.ticker as ticker
-
-# np 1.6/1.7 support
-from distutils.version import LooseVersion
-
-VALID_TYPES = tuple(set(six.string_types +
- (bytes, six.text_type, np.str_, np.bytes_)))
-
-
-class StrCategoryConverter(units.ConversionInterface):
- @staticmethod
- def convert(value, unit, axis):
- """Converts strings in value to floats using
- mapping information store in the unit object
-
- Parameters
- ----------
- value : string or iterable
- value or list of values to be converted
- unit : :class:`.UnitData`
- object string unit information for value
- axis : :class:`~matplotlib.Axis.axis`
- axis on which the converted value is plotted
-
- Returns
- -------
- mapped_ value : float or ndarray[float]
-
- .. note:: axis is not used in this function
- """
- # dtype = object preserves numerical pass throughs
- values = np.atleast_1d(np.array(value, dtype=object))
-
- # pass through sequence of non binary numbers
- if all((units.ConversionInterface.is_numlike(v) and
- not isinstance(v, VALID_TYPES)) for v in values):
- return np.asarray(values, dtype=float)
-
- # force an update so it also does type checking
- unit.update(values)
-
- str2idx = np.vectorize(unit._mapping.__getitem__,
- otypes=[float])
-
- mapped_value = str2idx(values)
- return mapped_value
-
- @staticmethod
- def axisinfo(unit, axis):
- """Sets the default axis ticks and labels
-
- Parameters
- ---------
- unit : :class:`.UnitData`
- object string unit information for value
- axis : :class:`~matplotlib.Axis.axis`
- axis for which information is being set
-
- Returns
- -------
- :class:~matplotlib.units.AxisInfo~
- Information to support default tick labeling
-
- .. note: axis is not used
- """
- # locator and formatter take mapping dict because
- # args need to be pass by reference for updates
- majloc = StrCategoryLocator(unit._mapping)
- majfmt = StrCategoryFormatter(unit._mapping)
- return units.AxisInfo(majloc=majloc, majfmt=majfmt)
-
- @staticmethod
- def default_units(data, axis):
- """ Sets and updates the :class:`~matplotlib.Axis.axis~ units
-
- Parameters
- ----------
- data : string or iterable of strings
- axis : :class:`~matplotlib.Axis.axis`
- axis on which the data is plotted
-
- Returns
- -------
- class:~.UnitData~
- object storing string to integer mapping
- """
- # the conversion call stack is supposed to be
- # default_units->axis_info->convert
- if axis.units is None:
- axis.set_units(UnitData(data))
- else:
- axis.units.update(data)
- return axis.units
-
-
-class StrCategoryLocator(ticker.Locator):
- """tick at every integer mapping of the string data"""
- def __init__(self, units_mapping):
- """
- Parameters
- -----------
- units_mapping : Dict[str, int]
- string:integer mapping
- """
- self._units = units_mapping
-
- def __call__(self):
- return list(self._units.values())
-
- def tick_values(self, vmin, vmax):
- return self()
-
-
-class StrCategoryFormatter(ticker.Formatter):
- """String representation of the data at every tick"""
- def __init__(self, units_mapping):
- """
- Parameters
- ----------
- units_mapping : Dict[Str, int]
- string:integer mapping
- """
- self._units = units_mapping
-
- def __call__(self, x, pos=None):
- if pos is None:
- return ""
- r_mapping = {v: StrCategoryFormatter._text(k)
- for k, v in self._units.items()}
- return r_mapping.get(int(np.round(x)), '')
-
- @staticmethod
- def _text(value):
- """Converts text values into `utf-8` or `ascii` strings
- """
- if LooseVersion(np.__version__) < LooseVersion('1.7.0'):
- if (isinstance(value, (six.text_type, np.unicode))):
- value = value.encode('utf-8', 'ignore').decode('utf-8')
- if isinstance(value, (np.bytes_, six.binary_type)):
- value = value.decode(encoding='utf-8')
- elif not isinstance(value, (np.str_, six.string_types)):
- value = str(value)
- return value
-
-
-class UnitData(object):
- def __init__(self, data=None):
- """Create mapping between unique categorical values
- and integer identifiers
- ----------
- data: iterable
- sequence of string values
- """
- self._mapping = OrderedDict()
- self._counter = itertools.count(start=0)
- if data is not None:
- self.update(data)
-
- def update(self, data):
- """Maps new values to integer identifiers.
-
- Paramters
- ---------
- data: iterable
- sequence of string values
-
- Raises
- ------
- TypeError
- If the value in data is not a string, unicode, bytes type
- """
- data = np.atleast_1d(np.array(data, dtype=object))
-
- for val in OrderedDict.fromkeys(data):
- if not isinstance(val, VALID_TYPES):
- raise TypeError("{val!r} is not a string".format(val=val))
- if val not in self._mapping:
- self._mapping[val] = next(self._counter)
-
-
-# Connects the convertor to matplotlib
-units.registry[str] = StrCategoryConverter()
-units.registry[np.str_] = StrCategoryConverter()
-units.registry[six.text_type] = StrCategoryConverter()
-units.registry[bytes] = StrCategoryConverter()
-units.registry[np.bytes_] = StrCategoryConverter()
diff --git a/contrib/python/matplotlib/py2/matplotlib/cbook/__init__.py b/contrib/python/matplotlib/py2/matplotlib/cbook/__init__.py
deleted file mode 100644
index 7de81661c5..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/cbook/__init__.py
+++ /dev/null
@@ -1,2888 +0,0 @@
-"""
-A collection of utility functions and classes. Originally, many
-(but not all) were from the Python Cookbook -- hence the name cbook.
-
-This module is safe to import from anywhere within matplotlib;
-it imports matplotlib only at runtime.
-"""
-
-from __future__ import absolute_import, division, print_function
-
-import six
-from six.moves import xrange, zip
-import collections
-try:
- import collections.abc as cabc
-except ImportError:
- import collections as cabc
-
-import contextlib
-import datetime
-import errno
-import functools
-import glob
-import gzip
-import io
-from itertools import repeat
-import locale
-import numbers
-import operator
-import os
-import re
-import sys
-import time
-import traceback
-import types
-import warnings
-from weakref import ref, WeakKeyDictionary
-
-import numpy as np
-
-import matplotlib
-from .deprecation import deprecated, warn_deprecated
-from .deprecation import mplDeprecation, MatplotlibDeprecationWarning
-
-
-def unicode_safe(s):
-
- if isinstance(s, bytes):
- try:
- # On some systems, locale.getpreferredencoding returns None,
- # which can break unicode; and the sage project reports that
- # some systems have incorrect locale specifications, e.g.,
- # an encoding instead of a valid locale name. Another
- # pathological case that has been reported is an empty string.
- # On some systems, getpreferredencoding sets the locale, which has
- # side effects. Passing False eliminates those side effects.
- preferredencoding = locale.getpreferredencoding(
- matplotlib.rcParams['axes.formatter.use_locale']).strip()
- if not preferredencoding:
- preferredencoding = None
- except (ValueError, ImportError, AttributeError):
- preferredencoding = None
-
- if preferredencoding is None:
- return six.text_type(s)
- else:
- return six.text_type(s, preferredencoding)
- return s
-
-
-@deprecated('2.1')
-class converter(object):
- """
- Base class for handling string -> python type with support for
- missing values
- """
- def __init__(self, missing='Null', missingval=None):
- self.missing = missing
- self.missingval = missingval
-
- def __call__(self, s):
- if s == self.missing:
- return self.missingval
- return s
-
- def is_missing(self, s):
- return not s.strip() or s == self.missing
-
-
-@deprecated('2.1')
-class tostr(converter):
- """convert to string or None"""
- def __init__(self, missing='Null', missingval=''):
- converter.__init__(self, missing=missing, missingval=missingval)
-
-
-@deprecated('2.1')
-class todatetime(converter):
- """convert to a datetime or None"""
- def __init__(self, fmt='%Y-%m-%d', missing='Null', missingval=None):
- 'use a :func:`time.strptime` format string for conversion'
- converter.__init__(self, missing, missingval)
- self.fmt = fmt
-
- def __call__(self, s):
- if self.is_missing(s):
- return self.missingval
- tup = time.strptime(s, self.fmt)
- return datetime.datetime(*tup[:6])
-
-
-@deprecated('2.1')
-class todate(converter):
- """convert to a date or None"""
- def __init__(self, fmt='%Y-%m-%d', missing='Null', missingval=None):
- """use a :func:`time.strptime` format string for conversion"""
- converter.__init__(self, missing, missingval)
- self.fmt = fmt
-
- def __call__(self, s):
- if self.is_missing(s):
- return self.missingval
- tup = time.strptime(s, self.fmt)
- return datetime.date(*tup[:3])
-
-
-@deprecated('2.1')
-class tofloat(converter):
- """convert to a float or None"""
- def __init__(self, missing='Null', missingval=None):
- converter.__init__(self, missing)
- self.missingval = missingval
-
- def __call__(self, s):
- if self.is_missing(s):
- return self.missingval
- return float(s)
-
-
-@deprecated('2.1')
-class toint(converter):
- """convert to an int or None"""
- def __init__(self, missing='Null', missingval=None):
- converter.__init__(self, missing)
-
- def __call__(self, s):
- if self.is_missing(s):
- return self.missingval
- return int(s)
-
-
-class _BoundMethodProxy(object):
- """
- Our own proxy object which enables weak references to bound and unbound
- methods and arbitrary callables. Pulls information about the function,
- class, and instance out of a bound method. Stores a weak reference to the
- instance to support garbage collection.
-
- @organization: IBM Corporation
- @copyright: Copyright (c) 2005, 2006 IBM Corporation
- @license: The BSD License
-
- Minor bugfixes by Michael Droettboom
- """
- def __init__(self, cb):
- self._hash = hash(cb)
- self._destroy_callbacks = []
- try:
- try:
- if six.PY3:
- self.inst = ref(cb.__self__, self._destroy)
- else:
- self.inst = ref(cb.im_self, self._destroy)
- except TypeError:
- self.inst = None
- if six.PY3:
- self.func = cb.__func__
- self.klass = cb.__self__.__class__
- else:
- self.func = cb.im_func
- self.klass = cb.im_class
- except AttributeError:
- self.inst = None
- self.func = cb
- self.klass = None
-
- def add_destroy_callback(self, callback):
- self._destroy_callbacks.append(_BoundMethodProxy(callback))
-
- def _destroy(self, wk):
- for callback in self._destroy_callbacks:
- try:
- callback(self)
- except ReferenceError:
- pass
-
- def __getstate__(self):
- d = self.__dict__.copy()
- # de-weak reference inst
- inst = d['inst']
- if inst is not None:
- d['inst'] = inst()
- return d
-
- def __setstate__(self, statedict):
- self.__dict__ = statedict
- inst = statedict['inst']
- # turn inst back into a weakref
- if inst is not None:
- self.inst = ref(inst)
-
- def __call__(self, *args, **kwargs):
- """
- Proxy for a call to the weak referenced object. Take
- arbitrary params to pass to the callable.
-
- Raises `ReferenceError`: When the weak reference refers to
- a dead object
- """
- if self.inst is not None and self.inst() is None:
- raise ReferenceError
- elif self.inst is not None:
- # build a new instance method with a strong reference to the
- # instance
-
- mtd = types.MethodType(self.func, self.inst())
-
- else:
- # not a bound method, just return the func
- mtd = self.func
- # invoke the callable and return the result
- return mtd(*args, **kwargs)
-
- def __eq__(self, other):
- """
- Compare the held function and instance with that held by
- another proxy.
- """
- try:
- if self.inst is None:
- return self.func == other.func and other.inst is None
- else:
- return self.func == other.func and self.inst() == other.inst()
- except Exception:
- return False
-
- def __ne__(self, other):
- """
- Inverse of __eq__.
- """
- return not self.__eq__(other)
-
- def __hash__(self):
- return self._hash
-
-
-def _exception_printer(exc):
- traceback.print_exc()
-
-
-class CallbackRegistry(object):
- """Handle registering and disconnecting for a set of signals and callbacks:
-
- >>> def oneat(x):
- ... print('eat', x)
- >>> def ondrink(x):
- ... print('drink', x)
-
- >>> from matplotlib.cbook import CallbackRegistry
- >>> callbacks = CallbackRegistry()
-
- >>> id_eat = callbacks.connect('eat', oneat)
- >>> id_drink = callbacks.connect('drink', ondrink)
-
- >>> callbacks.process('drink', 123)
- drink 123
- >>> callbacks.process('eat', 456)
- eat 456
- >>> callbacks.process('be merry', 456) # nothing will be called
- >>> callbacks.disconnect(id_eat)
- >>> callbacks.process('eat', 456) # nothing will be called
-
- In practice, one should always disconnect all callbacks when they
- are no longer needed to avoid dangling references (and thus memory
- leaks). However, real code in matplotlib rarely does so, and due
- to its design, it is rather difficult to place this kind of code.
- To get around this, and prevent this class of memory leaks, we
- instead store weak references to bound methods only, so when the
- destination object needs to die, the CallbackRegistry won't keep
- it alive. The Python stdlib weakref module can not create weak
- references to bound methods directly, so we need to create a proxy
- object to handle weak references to bound methods (or regular free
- functions). This technique was shared by Peter Parente on his
- `"Mindtrove" blog
- <http://mindtrove.info/python-weak-references/>`_.
-
-
- Parameters
- ----------
- exception_handler : callable, optional
- If provided must have signature ::
-
- def handler(exc: Exception) -> None:
-
- If not None this function will be called with any `Exception`
- subclass raised by the callbacks in `CallbackRegistry.process`.
- The handler may either consume the exception or re-raise.
-
- The callable must be pickle-able.
-
- The default handler is ::
-
- def h(exc):
- traceback.print_exc()
-
- """
- def __init__(self, exception_handler=_exception_printer):
- self.exception_handler = exception_handler
- self.callbacks = dict()
- self._cid = 0
- self._func_cid_map = {}
-
- # In general, callbacks may not be pickled; thus, we simply recreate an
- # empty dictionary at unpickling. In order to ensure that `__setstate__`
- # (which just defers to `__init__`) is called, `__getstate__` must
- # return a truthy value (for pickle protocol>=3, i.e. Py3, the
- # *actual* behavior is that `__setstate__` will be called as long as
- # `__getstate__` does not return `None`, but this is undocumented -- see
- # http://bugs.python.org/issue12290).
-
- def __getstate__(self):
- return {'exception_handler': self.exception_handler}
-
- def __setstate__(self, state):
- self.__init__(**state)
-
- def connect(self, s, func):
- """Register *func* to be called when signal *s* is generated.
- """
- self._func_cid_map.setdefault(s, WeakKeyDictionary())
- # Note proxy not needed in python 3.
- # TODO rewrite this when support for python2.x gets dropped.
- proxy = _BoundMethodProxy(func)
- if proxy in self._func_cid_map[s]:
- return self._func_cid_map[s][proxy]
-
- proxy.add_destroy_callback(self._remove_proxy)
- self._cid += 1
- cid = self._cid
- self._func_cid_map[s][proxy] = cid
- self.callbacks.setdefault(s, dict())
- self.callbacks[s][cid] = proxy
- return cid
-
- def _remove_proxy(self, proxy):
- for signal, proxies in list(six.iteritems(self._func_cid_map)):
- try:
- del self.callbacks[signal][proxies[proxy]]
- except KeyError:
- pass
-
- if len(self.callbacks[signal]) == 0:
- del self.callbacks[signal]
- del self._func_cid_map[signal]
-
- def disconnect(self, cid):
- """Disconnect the callback registered with callback id *cid*.
- """
- for eventname, callbackd in list(six.iteritems(self.callbacks)):
- try:
- del callbackd[cid]
- except KeyError:
- continue
- else:
- for signal, functions in list(
- six.iteritems(self._func_cid_map)):
- for function, value in list(six.iteritems(functions)):
- if value == cid:
- del functions[function]
- return
-
- def process(self, s, *args, **kwargs):
- """
- Process signal *s*.
-
- All of the functions registered to receive callbacks on *s* will be
- called with ``*args`` and ``**kwargs``.
- """
- if s in self.callbacks:
- for cid, proxy in list(six.iteritems(self.callbacks[s])):
- try:
- proxy(*args, **kwargs)
- except ReferenceError:
- self._remove_proxy(proxy)
- # this does not capture KeyboardInterrupt, SystemExit,
- # and GeneratorExit
- except Exception as exc:
- if self.exception_handler is not None:
- self.exception_handler(exc)
- else:
- raise
-
-
-class silent_list(list):
- """
- override repr when returning a list of matplotlib artists to
- prevent long, meaningless output. This is meant to be used for a
- homogeneous list of a given type
- """
- def __init__(self, type, seq=None):
- self.type = type
- if seq is not None:
- self.extend(seq)
-
- def __repr__(self):
- return '<a list of %d %s objects>' % (len(self), self.type)
-
- def __str__(self):
- return repr(self)
-
- def __getstate__(self):
- # store a dictionary of this SilentList's state
- return {'type': self.type, 'seq': self[:]}
-
- def __setstate__(self, state):
- self.type = state['type']
- self.extend(state['seq'])
-
-
-class IgnoredKeywordWarning(UserWarning):
- """
- A class for issuing warnings about keyword arguments that will be ignored
- by matplotlib
- """
- pass
-
-
-def local_over_kwdict(local_var, kwargs, *keys):
- """
- Enforces the priority of a local variable over potentially conflicting
- argument(s) from a kwargs dict. The following possible output values are
- considered in order of priority:
-
- local_var > kwargs[keys[0]] > ... > kwargs[keys[-1]]
-
- The first of these whose value is not None will be returned. If all are
- None then None will be returned. Each key in keys will be removed from the
- kwargs dict in place.
-
- Parameters
- ----------
- local_var: any object
- The local variable (highest priority)
-
- kwargs: dict
- Dictionary of keyword arguments; modified in place
-
- keys: str(s)
- Name(s) of keyword arguments to process, in descending order of
- priority
-
- Returns
- -------
- out: any object
- Either local_var or one of kwargs[key] for key in keys
-
- Raises
- ------
- IgnoredKeywordWarning
- For each key in keys that is removed from kwargs but not used as
- the output value
-
- """
- out = local_var
- for key in keys:
- kwarg_val = kwargs.pop(key, None)
- if kwarg_val is not None:
- if out is None:
- out = kwarg_val
- else:
- warnings.warn('"%s" keyword argument will be ignored' % key,
- IgnoredKeywordWarning)
- return out
-
-
-def strip_math(s):
- """remove latex formatting from mathtext"""
- remove = (r'\mathdefault', r'\rm', r'\cal', r'\tt', r'\it', '\\', '{', '}')
- s = s[1:-1]
- for r in remove:
- s = s.replace(r, '')
- return s
-
-
-class Bunch(object):
- """
- Often we want to just collect a bunch of stuff together, naming each
- item of the bunch; a dictionary's OK for that, but a small do- nothing
- class is even handier, and prettier to use. Whenever you want to
- group a few variables::
-
- >>> point = Bunch(datum=2, squared=4, coord=12)
- >>> point.datum
-
- By: Alex Martelli
- From: https://code.activestate.com/recipes/121294/
- """
- def __init__(self, **kwds):
- self.__dict__.update(kwds)
-
- def __repr__(self):
- return 'Bunch(%s)' % ', '.join(
- '%s=%s' % kv for kv in six.iteritems(vars(self)))
-
-
-@deprecated('2.1')
-def unique(x):
- """Return a list of unique elements of *x*"""
- return list(set(x))
-
-
-def iterable(obj):
- """return true if *obj* is iterable"""
- try:
- iter(obj)
- except TypeError:
- return False
- return True
-
-
-@deprecated('2.1')
-def is_string_like(obj):
- """Return True if *obj* looks like a string"""
- # (np.str_ == np.unicode_ on Py3).
- return isinstance(obj, (six.string_types, np.str_, np.unicode_))
-
-
-@deprecated('2.1')
-def is_sequence_of_strings(obj):
- """Returns true if *obj* is iterable and contains strings"""
- if not iterable(obj):
- return False
- if is_string_like(obj) and not isinstance(obj, np.ndarray):
- try:
- obj = obj.values
- except AttributeError:
- # not pandas
- return False
- for o in obj:
- if not is_string_like(o):
- return False
- return True
-
-
-def is_hashable(obj):
- """Returns true if *obj* can be hashed"""
- try:
- hash(obj)
- except TypeError:
- return False
- return True
-
-
-def is_writable_file_like(obj):
- """return true if *obj* looks like a file object with a *write* method"""
- return callable(getattr(obj, 'write', None))
-
-
-def file_requires_unicode(x):
- """
- Returns `True` if the given writable file-like object requires Unicode
- to be written to it.
- """
- try:
- x.write(b'')
- except TypeError:
- return True
- else:
- return False
-
-
-@deprecated('2.1')
-def is_scalar(obj):
- """return true if *obj* is not string like and is not iterable"""
- return not isinstance(obj, six.string_types) and not iterable(obj)
-
-
-def is_numlike(obj):
- """return true if *obj* looks like a number"""
- return isinstance(obj, (numbers.Number, np.number))
-
-
-def to_filehandle(fname, flag='rU', return_opened=False, encoding=None):
- """
- *fname* can be an `os.PathLike` or a file handle. Support for gzipped
- files is automatic, if the filename ends in .gz. *flag* is a
- read/write flag for :func:`file`
- """
- if hasattr(os, "PathLike") and isinstance(fname, os.PathLike):
- return to_filehandle(
- os.fspath(fname),
- flag=flag, return_opened=return_opened, encoding=encoding)
- if isinstance(fname, six.string_types):
- if fname.endswith('.gz'):
- # get rid of 'U' in flag for gzipped files.
- flag = flag.replace('U', '')
- fh = gzip.open(fname, flag)
- elif fname.endswith('.bz2'):
- # python may not be complied with bz2 support,
- # bury import until we need it
- import bz2
- # get rid of 'U' in flag for bz2 files
- flag = flag.replace('U', '')
- fh = bz2.BZ2File(fname, flag)
- else:
- fh = io.open(fname, flag, encoding=encoding)
- opened = True
- elif hasattr(fname, 'seek'):
- fh = fname
- opened = False
- else:
- raise ValueError('fname must be a PathLike or file handle')
- if return_opened:
- return fh, opened
- return fh
-
-
-@contextlib.contextmanager
-def open_file_cm(path_or_file, mode="r", encoding=None):
- r"""Pass through file objects and context-manage `.PathLike`\s."""
- fh, opened = to_filehandle(path_or_file, mode, True, encoding)
- if opened:
- with fh:
- yield fh
- else:
- yield fh
-
-
-def is_scalar_or_string(val):
- """Return whether the given object is a scalar or string like."""
- return isinstance(val, six.string_types) or not iterable(val)
-
-
-def _string_to_bool(s):
- """Parses the string argument as a boolean"""
- if not isinstance(s, six.string_types):
- return bool(s)
- warn_deprecated("2.2", "Passing one of 'on', 'true', 'off', 'false' as a "
- "boolean is deprecated; use an actual boolean "
- "(True/False) instead.")
- if s.lower() in ['on', 'true']:
- return True
- if s.lower() in ['off', 'false']:
- return False
- raise ValueError('String "%s" must be one of: '
- '"on", "off", "true", or "false"' % s)
-
-
-def get_sample_data(fname, asfileobj=True):
- """
- Return a sample data file. *fname* is a path relative to the
- `mpl-data/sample_data` directory. If *asfileobj* is `True`
- return a file object, otherwise just a file path.
-
- Set the rc parameter examples.directory to the directory where we should
- look, if sample_data files are stored in a location different than
- default (which is 'mpl-data/sample_data` at the same level of 'matplotlib`
- Python module files).
-
- If the filename ends in .gz, the file is implicitly ungzipped.
- """
- if matplotlib.rcParams['examples.directory']:
- root = matplotlib.rcParams['examples.directory']
- else:
- root = os.path.join(matplotlib._get_data_path(), 'sample_data')
- path = os.path.join(root, fname)
-
- if asfileobj:
- if (os.path.splitext(fname)[-1].lower() in
- ('.csv', '.xrc', '.txt')):
- mode = 'r'
- else:
- mode = 'rb'
-
- base, ext = os.path.splitext(fname)
- if ext == '.gz':
- return gzip.open(path, mode)
- else:
- return open(path, mode)
- else:
- return path
-
-
-def flatten(seq, scalarp=is_scalar_or_string):
- """
- Returns a generator of flattened nested containers
-
- For example:
-
- >>> from matplotlib.cbook import flatten
- >>> l = (('John', ['Hunter']), (1, 23), [[([42, (5, 23)], )]])
- >>> print(list(flatten(l)))
- ['John', 'Hunter', 1, 23, 42, 5, 23]
-
- By: Composite of Holger Krekel and Luther Blissett
- From: https://code.activestate.com/recipes/121294/
- and Recipe 1.12 in cookbook
- """
- for item in seq:
- if scalarp(item) or item is None:
- yield item
- else:
- for subitem in flatten(item, scalarp):
- yield subitem
-
-
-@deprecated('2.1', "sorted(..., key=itemgetter(...))")
-class Sorter(object):
- """
- Sort by attribute or item
-
- Example usage::
-
- sort = Sorter()
-
- list = [(1, 2), (4, 8), (0, 3)]
- dict = [{'a': 3, 'b': 4}, {'a': 5, 'b': 2}, {'a': 0, 'b': 0},
- {'a': 9, 'b': 9}]
-
-
- sort(list) # default sort
- sort(list, 1) # sort by index 1
- sort(dict, 'a') # sort a list of dicts by key 'a'
-
- """
-
- def _helper(self, data, aux, inplace):
- aux.sort()
- result = [data[i] for junk, i in aux]
- if inplace:
- data[:] = result
- return result
-
- def byItem(self, data, itemindex=None, inplace=1):
- if itemindex is None:
- if inplace:
- data.sort()
- result = data
- else:
- result = sorted(data)
- return result
- else:
- aux = [(data[i][itemindex], i) for i in range(len(data))]
- return self._helper(data, aux, inplace)
-
- def byAttribute(self, data, attributename, inplace=1):
- aux = [(getattr(data[i], attributename), i) for i in range(len(data))]
- return self._helper(data, aux, inplace)
-
- # a couple of handy synonyms
- sort = byItem
- __call__ = byItem
-
-
-@deprecated('2.1')
-class Xlator(dict):
- """
- All-in-one multiple-string-substitution class
-
- Example usage::
-
- text = "Larry Wall is the creator of Perl"
- adict = {
- "Larry Wall" : "Guido van Rossum",
- "creator" : "Benevolent Dictator for Life",
- "Perl" : "Python",
- }
-
- print(multiple_replace(adict, text))
-
- xlat = Xlator(adict)
- print(xlat.xlat(text))
- """
-
- def _make_regex(self):
- """ Build re object based on the keys of the current dictionary """
- return re.compile("|".join(map(re.escape, self)))
-
- def __call__(self, match):
- """ Handler invoked for each regex *match* """
- return self[match.group(0)]
-
- def xlat(self, text):
- """ Translate *text*, returns the modified text. """
- return self._make_regex().sub(self, text)
-
-
-@deprecated('2.1')
-def soundex(name, len=4):
- """ soundex module conforming to Odell-Russell algorithm """
-
- # digits holds the soundex values for the alphabet
- soundex_digits = '01230120022455012623010202'
- sndx = ''
- fc = ''
-
- # Translate letters in name to soundex digits
- for c in name.upper():
- if c.isalpha():
- if not fc:
- fc = c # Remember first letter
- d = soundex_digits[ord(c) - ord('A')]
- # Duplicate consecutive soundex digits are skipped
- if not sndx or (d != sndx[-1]):
- sndx += d
-
- # Replace first digit with first letter
- sndx = fc + sndx[1:]
-
- # Remove all 0s from the soundex code
- sndx = sndx.replace('0', '')
-
- # Return soundex code truncated or 0-padded to len characters
- return (sndx + (len * '0'))[:len]
-
-
-@deprecated('2.1')
-class Null(object):
- """ Null objects always and reliably "do nothing." """
-
- def __init__(self, *args, **kwargs):
- pass
-
- def __call__(self, *args, **kwargs):
- return self
-
- def __str__(self):
- return "Null()"
-
- def __repr__(self):
- return "Null()"
-
- if six.PY3:
- def __bool__(self):
- return 0
- else:
- def __nonzero__(self):
- return 0
-
- def __getattr__(self, name):
- return self
-
- def __setattr__(self, name, value):
- return self
-
- def __delattr__(self, name):
- return self
-
-
-def mkdirs(newdir, mode=0o777):
- """
- make directory *newdir* recursively, and set *mode*. Equivalent to ::
-
- > mkdir -p NEWDIR
- > chmod MODE NEWDIR
- """
- # this functionality is now in core python as of 3.2
- # LPY DROP
- if six.PY3:
- os.makedirs(newdir, mode=mode, exist_ok=True)
- else:
- try:
- os.makedirs(newdir, mode=mode)
- except OSError as exception:
- if exception.errno != errno.EEXIST:
- raise
-
-
-class GetRealpathAndStat(object):
- def __init__(self):
- self._cache = {}
-
- def __call__(self, path):
- result = self._cache.get(path)
- if result is None:
- realpath = os.path.realpath(path)
- if sys.platform == 'win32':
- stat_key = realpath
- else:
- stat = os.stat(realpath)
- stat_key = (stat.st_ino, stat.st_dev)
- result = realpath, stat_key
- self._cache[path] = result
- return result
-
-
-get_realpath_and_stat = GetRealpathAndStat()
-
-
-@deprecated('2.1')
-def dict_delall(d, keys):
- """delete all of the *keys* from the :class:`dict` *d*"""
- for key in keys:
- try:
- del d[key]
- except KeyError:
- pass
-
-
-@deprecated('2.1')
-class RingBuffer(object):
- """ class that implements a not-yet-full buffer """
- def __init__(self, size_max):
- self.max = size_max
- self.data = []
-
- class __Full:
- """ class that implements a full buffer """
- def append(self, x):
- """ Append an element overwriting the oldest one. """
- self.data[self.cur] = x
- self.cur = (self.cur + 1) % self.max
-
- def get(self):
- """ return list of elements in correct order """
- return self.data[self.cur:] + self.data[:self.cur]
-
- def append(self, x):
- """append an element at the end of the buffer"""
- self.data.append(x)
- if len(self.data) == self.max:
- self.cur = 0
- # Permanently change self's class from non-full to full
- self.__class__ = __Full
-
- def get(self):
- """ Return a list of elements from the oldest to the newest. """
- return self.data
-
- def __get_item__(self, i):
- return self.data[i % len(self.data)]
-
-
-@deprecated('2.1')
-def get_split_ind(seq, N):
- """
- *seq* is a list of words. Return the index into seq such that::
-
- len(' '.join(seq[:ind])<=N
-
- .
- """
-
- s_len = 0
- # todo: use Alex's xrange pattern from the cbook for efficiency
- for (word, ind) in zip(seq, xrange(len(seq))):
- s_len += len(word) + 1 # +1 to account for the len(' ')
- if s_len >= N:
- return ind
- return len(seq)
-
-
-@deprecated('2.1', alternative='textwrap.TextWrapper')
-def wrap(prefix, text, cols):
- """wrap *text* with *prefix* at length *cols*"""
- pad = ' ' * len(prefix.expandtabs())
- available = cols - len(pad)
-
- seq = text.split(' ')
- Nseq = len(seq)
- ind = 0
- lines = []
- while ind < Nseq:
- lastInd = ind
- ind += get_split_ind(seq[ind:], available)
- lines.append(seq[lastInd:ind])
-
- # add the prefix to the first line, pad with spaces otherwise
- ret = prefix + ' '.join(lines[0]) + '\n'
- for line in lines[1:]:
- ret += pad + ' '.join(line) + '\n'
- return ret
-
-
-# A regular expression used to determine the amount of space to
-# remove. It looks for the first sequence of spaces immediately
-# following the first newline, or at the beginning of the string.
-_find_dedent_regex = re.compile(r"(?:(?:\n\r?)|^)( *)\S")
-# A cache to hold the regexs that actually remove the indent.
-_dedent_regex = {}
-
-
-def dedent(s):
- """
- Remove excess indentation from docstring *s*.
-
- Discards any leading blank lines, then removes up to n whitespace
- characters from each line, where n is the number of leading
- whitespace characters in the first line. It differs from
- textwrap.dedent in its deletion of leading blank lines and its use
- of the first non-blank line to determine the indentation.
-
- It is also faster in most cases.
- """
- # This implementation has a somewhat obtuse use of regular
- # expressions. However, this function accounted for almost 30% of
- # matplotlib startup time, so it is worthy of optimization at all
- # costs.
-
- if not s: # includes case of s is None
- return ''
-
- match = _find_dedent_regex.match(s)
- if match is None:
- return s
-
- # This is the number of spaces to remove from the left-hand side.
- nshift = match.end(1) - match.start(1)
- if nshift == 0:
- return s
-
- # Get a regex that will remove *up to* nshift spaces from the
- # beginning of each line. If it isn't in the cache, generate it.
- unindent = _dedent_regex.get(nshift, None)
- if unindent is None:
- unindent = re.compile("\n\r? {0,%d}" % nshift)
- _dedent_regex[nshift] = unindent
-
- result = unindent.sub("\n", s).strip()
- return result
-
-
-def listFiles(root, patterns='*', recurse=1, return_folders=0):
- """
- Recursively list files
-
- from Parmar and Martelli in the Python Cookbook
- """
- import os.path
- import fnmatch
- # Expand patterns from semicolon-separated string to list
- pattern_list = patterns.split(';')
- results = []
-
- for dirname, dirs, files in os.walk(root):
- # Append to results all relevant files (and perhaps folders)
- for name in files:
- fullname = os.path.normpath(os.path.join(dirname, name))
- if return_folders or os.path.isfile(fullname):
- for pattern in pattern_list:
- if fnmatch.fnmatch(name, pattern):
- results.append(fullname)
- break
- # Block recursion if recursion was disallowed
- if not recurse:
- break
-
- return results
-
-
-@deprecated('2.1')
-def get_recursive_filelist(args):
- """
- Recurse all the files and dirs in *args* ignoring symbolic links
- and return the files as a list of strings
- """
- files = []
-
- for arg in args:
- if os.path.isfile(arg):
- files.append(arg)
- continue
- if os.path.isdir(arg):
- newfiles = listFiles(arg, recurse=1, return_folders=1)
- files.extend(newfiles)
-
- return [f for f in files if not os.path.islink(f)]
-
-
-@deprecated('2.1')
-def pieces(seq, num=2):
- """Break up the *seq* into *num* tuples"""
- start = 0
- while 1:
- item = seq[start:start + num]
- if not len(item):
- break
- yield item
- start += num
-
-
-@deprecated('2.1')
-def exception_to_str(s=None):
- if six.PY3:
- sh = io.StringIO()
- else:
- sh = io.BytesIO()
- if s is not None:
- print(s, file=sh)
- traceback.print_exc(file=sh)
- return sh.getvalue()
-
-
-@deprecated('2.1')
-def allequal(seq):
- """
- Return *True* if all elements of *seq* compare equal. If *seq* is
- 0 or 1 length, return *True*
- """
- if len(seq) < 2:
- return True
- val = seq[0]
- for i in xrange(1, len(seq)):
- thisval = seq[i]
- if thisval != val:
- return False
- return True
-
-
-@deprecated('2.1')
-def alltrue(seq):
- """
- Return *True* if all elements of *seq* evaluate to *True*. If
- *seq* is empty, return *False*.
- """
- if not len(seq):
- return False
- for val in seq:
- if not val:
- return False
- return True
-
-
-@deprecated('2.1')
-def onetrue(seq):
- """
- Return *True* if one element of *seq* is *True*. It *seq* is
- empty, return *False*.
- """
- if not len(seq):
- return False
- for val in seq:
- if val:
- return True
- return False
-
-
-@deprecated('2.1')
-def allpairs(x):
- """
- return all possible pairs in sequence *x*
- """
- return [(s, f) for i, f in enumerate(x) for s in x[i + 1:]]
-
-
-class maxdict(dict):
- """
- A dictionary with a maximum size; this doesn't override all the
- relevant methods to constrain the size, just setitem, so use with
- caution
- """
- def __init__(self, maxsize):
- dict.__init__(self)
- self.maxsize = maxsize
- self._killkeys = []
-
- def __setitem__(self, k, v):
- if k not in self:
- if len(self) >= self.maxsize:
- del self[self._killkeys[0]]
- del self._killkeys[0]
- self._killkeys.append(k)
- dict.__setitem__(self, k, v)
-
-
-class Stack(object):
- """
- Implement a stack where elements can be pushed on and you can move
- back and forth. But no pop. Should mimic home / back / forward
- in a browser
- """
-
- def __init__(self, default=None):
- self.clear()
- self._default = default
-
- def __call__(self):
- """return the current element, or None"""
- if not len(self._elements):
- return self._default
- else:
- return self._elements[self._pos]
-
- def __len__(self):
- return self._elements.__len__()
-
- def __getitem__(self, ind):
- return self._elements.__getitem__(ind)
-
- def forward(self):
- """move the position forward and return the current element"""
- n = len(self._elements)
- if self._pos < n - 1:
- self._pos += 1
- return self()
-
- def back(self):
- """move the position back and return the current element"""
- if self._pos > 0:
- self._pos -= 1
- return self()
-
- def push(self, o):
- """
- push object onto stack at current position - all elements
- occurring later than the current position are discarded
- """
- self._elements = self._elements[:self._pos + 1]
- self._elements.append(o)
- self._pos = len(self._elements) - 1
- return self()
-
- def home(self):
- """push the first element onto the top of the stack"""
- if not len(self._elements):
- return
- self.push(self._elements[0])
- return self()
-
- def empty(self):
- return len(self._elements) == 0
-
- def clear(self):
- """empty the stack"""
- self._pos = -1
- self._elements = []
-
- def bubble(self, o):
- """
- raise *o* to the top of the stack and return *o*. *o* must be
- in the stack
- """
-
- if o not in self._elements:
- raise ValueError('Unknown element o')
- old = self._elements[:]
- self.clear()
- bubbles = []
- for thiso in old:
- if thiso == o:
- bubbles.append(thiso)
- else:
- self.push(thiso)
- for thiso in bubbles:
- self.push(o)
- return o
-
- def remove(self, o):
- 'remove element *o* from the stack'
- if o not in self._elements:
- raise ValueError('Unknown element o')
- old = self._elements[:]
- self.clear()
- for thiso in old:
- if thiso == o:
- continue
- else:
- self.push(thiso)
-
-
-@deprecated('2.1')
-def finddir(o, match, case=False):
- """
- return all attributes of *o* which match string in match. if case
- is True require an exact case match.
- """
- if case:
- names = [(name, name) for name in dir(o)
- if isinstance(name, six.string_types)]
- else:
- names = [(name.lower(), name) for name in dir(o)
- if isinstance(name, six.string_types)]
- match = match.lower()
- return [orig for name, orig in names if name.find(match) >= 0]
-
-
-@deprecated('2.1')
-def reverse_dict(d):
- """reverse the dictionary -- may lose data if values are not unique!"""
- return {v: k for k, v in six.iteritems(d)}
-
-
-@deprecated('2.1')
-def restrict_dict(d, keys):
- """
- Return a dictionary that contains those keys that appear in both
- d and keys, with values from d.
- """
- return {k: v for k, v in six.iteritems(d) if k in keys}
-
-
-def report_memory(i=0): # argument may go away
- """return the memory consumed by process"""
- from matplotlib.compat.subprocess import Popen, PIPE
- pid = os.getpid()
- if sys.platform == 'sunos5':
- try:
- a2 = Popen(['ps', '-p', '%d' % pid, '-o', 'osz'],
- stdout=PIPE).stdout.readlines()
- except OSError:
- raise NotImplementedError(
- "report_memory works on Sun OS only if "
- "the 'ps' program is found")
- mem = int(a2[-1].strip())
- elif sys.platform.startswith('linux'):
- try:
- a2 = Popen(['ps', '-p', '%d' % pid, '-o', 'rss,sz'],
- stdout=PIPE).stdout.readlines()
- except OSError:
- raise NotImplementedError(
- "report_memory works on Linux only if "
- "the 'ps' program is found")
- mem = int(a2[1].split()[1])
- elif sys.platform.startswith('darwin'):
- try:
- a2 = Popen(['ps', '-p', '%d' % pid, '-o', 'rss,vsz'],
- stdout=PIPE).stdout.readlines()
- except OSError:
- raise NotImplementedError(
- "report_memory works on Mac OS only if "
- "the 'ps' program is found")
- mem = int(a2[1].split()[0])
- elif sys.platform.startswith('win'):
- try:
- a2 = Popen([str("tasklist"), "/nh", "/fi", "pid eq %d" % pid],
- stdout=PIPE).stdout.read()
- except OSError:
- raise NotImplementedError(
- "report_memory works on Windows only if "
- "the 'tasklist' program is found")
- mem = int(a2.strip().split()[-2].replace(',', ''))
- else:
- raise NotImplementedError(
- "We don't have a memory monitor for %s" % sys.platform)
- return mem
-
-
-_safezip_msg = 'In safezip, len(args[0])=%d but len(args[%d])=%d'
-
-
-def safezip(*args):
- """make sure *args* are equal len before zipping"""
- Nx = len(args[0])
- for i, arg in enumerate(args[1:]):
- if len(arg) != Nx:
- raise ValueError(_safezip_msg % (Nx, i + 1, len(arg)))
- return list(zip(*args))
-
-
-@deprecated('2.1')
-def issubclass_safe(x, klass):
- """return issubclass(x, klass) and return False on a TypeError"""
-
- try:
- return issubclass(x, klass)
- except TypeError:
- return False
-
-
-def safe_masked_invalid(x, copy=False):
- x = np.array(x, subok=True, copy=copy)
- if not x.dtype.isnative:
- # Note that the argument to `byteswap` is 'inplace',
- # thus if we have already made a copy, do the byteswap in
- # place, else make a copy with the byte order swapped.
- # Be explicit that we are swapping the byte order of the dtype
- x = x.byteswap(copy).newbyteorder('S')
-
- try:
- xm = np.ma.masked_invalid(x, copy=False)
- xm.shrink_mask()
- except TypeError:
- return x
- return xm
-
-
-def print_cycles(objects, outstream=sys.stdout, show_progress=False):
- """
- *objects*
- A list of objects to find cycles in. It is often useful to
- pass in gc.garbage to find the cycles that are preventing some
- objects from being garbage collected.
-
- *outstream*
- The stream for output.
-
- *show_progress*
- If True, print the number of objects reached as they are found.
- """
- import gc
- from types import FrameType
-
- def print_path(path):
- for i, step in enumerate(path):
- # next "wraps around"
- next = path[(i + 1) % len(path)]
-
- outstream.write(" %s -- " % str(type(step)))
- if isinstance(step, dict):
- for key, val in six.iteritems(step):
- if val is next:
- outstream.write("[%s]" % repr(key))
- break
- if key is next:
- outstream.write("[key] = %s" % repr(val))
- break
- elif isinstance(step, list):
- outstream.write("[%d]" % step.index(next))
- elif isinstance(step, tuple):
- outstream.write("( tuple )")
- else:
- outstream.write(repr(step))
- outstream.write(" ->\n")
- outstream.write("\n")
-
- def recurse(obj, start, all, current_path):
- if show_progress:
- outstream.write("%d\r" % len(all))
-
- all[id(obj)] = None
-
- referents = gc.get_referents(obj)
- for referent in referents:
- # If we've found our way back to the start, this is
- # a cycle, so print it out
- if referent is start:
- print_path(current_path)
-
- # Don't go back through the original list of objects, or
- # through temporary references to the object, since those
- # are just an artifact of the cycle detector itself.
- elif referent is objects or isinstance(referent, FrameType):
- continue
-
- # We haven't seen this object before, so recurse
- elif id(referent) not in all:
- recurse(referent, start, all, current_path + [obj])
-
- for obj in objects:
- outstream.write("Examining: %r\n" % (obj,))
- recurse(obj, obj, {}, [])
-
-
-class Grouper(object):
- """
- This class provides a lightweight way to group arbitrary objects
- together into disjoint sets when a full-blown graph data structure
- would be overkill.
-
- Objects can be joined using :meth:`join`, tested for connectedness
- using :meth:`joined`, and all disjoint sets can be retrieved by
- using the object as an iterator.
-
- The objects being joined must be hashable and weak-referenceable.
-
- For example:
-
- >>> from matplotlib.cbook import Grouper
- >>> class Foo(object):
- ... def __init__(self, s):
- ... self.s = s
- ... def __repr__(self):
- ... return self.s
- ...
- >>> a, b, c, d, e, f = [Foo(x) for x in 'abcdef']
- >>> grp = Grouper()
- >>> grp.join(a, b)
- >>> grp.join(b, c)
- >>> grp.join(d, e)
- >>> sorted(map(tuple, grp))
- [(a, b, c), (d, e)]
- >>> grp.joined(a, b)
- True
- >>> grp.joined(a, c)
- True
- >>> grp.joined(a, d)
- False
-
- """
- def __init__(self, init=()):
- mapping = self._mapping = {}
- for x in init:
- mapping[ref(x)] = [ref(x)]
-
- def __contains__(self, item):
- return ref(item) in self._mapping
-
- def clean(self):
- """
- Clean dead weak references from the dictionary
- """
- mapping = self._mapping
- to_drop = [key for key in mapping if key() is None]
- for key in to_drop:
- val = mapping.pop(key)
- val.remove(key)
-
- def join(self, a, *args):
- """
- Join given arguments into the same set. Accepts one or more
- arguments.
- """
- mapping = self._mapping
- set_a = mapping.setdefault(ref(a), [ref(a)])
-
- for arg in args:
- set_b = mapping.get(ref(arg))
- if set_b is None:
- set_a.append(ref(arg))
- mapping[ref(arg)] = set_a
- elif set_b is not set_a:
- if len(set_b) > len(set_a):
- set_a, set_b = set_b, set_a
- set_a.extend(set_b)
- for elem in set_b:
- mapping[elem] = set_a
-
- self.clean()
-
- def joined(self, a, b):
- """
- Returns True if *a* and *b* are members of the same set.
- """
- self.clean()
-
- mapping = self._mapping
- try:
- return mapping[ref(a)] is mapping[ref(b)]
- except KeyError:
- return False
-
- def remove(self, a):
- self.clean()
-
- mapping = self._mapping
- seta = mapping.pop(ref(a), None)
- if seta is not None:
- seta.remove(ref(a))
-
- def __iter__(self):
- """
- Iterate over each of the disjoint sets as a list.
-
- The iterator is invalid if interleaved with calls to join().
- """
- self.clean()
- token = object()
-
- # Mark each group as we come across if by appending a token,
- # and don't yield it twice
- for group in six.itervalues(self._mapping):
- if group[-1] is not token:
- yield [x() for x in group]
- group.append(token)
-
- # Cleanup the tokens
- for group in six.itervalues(self._mapping):
- if group[-1] is token:
- del group[-1]
-
- def get_siblings(self, a):
- """
- Returns all of the items joined with *a*, including itself.
- """
- self.clean()
-
- siblings = self._mapping.get(ref(a), [ref(a)])
- return [x() for x in siblings]
-
-
-def simple_linear_interpolation(a, steps):
- """
- Resample an array with ``steps - 1`` points between original point pairs.
-
- Parameters
- ----------
- a : array, shape (n, ...)
- steps : int
-
- Returns
- -------
- array, shape ``((n - 1) * steps + 1, ...)``
-
- Along each column of *a*, ``(steps - 1)`` points are introduced between
- each original values; the values are linearly interpolated.
- """
- fps = a.reshape((len(a), -1))
- xp = np.arange(len(a)) * steps
- x = np.arange((len(a) - 1) * steps + 1)
- return (np.column_stack([np.interp(x, xp, fp) for fp in fps.T])
- .reshape((len(x),) + a.shape[1:]))
-
-
-@deprecated('2.1', alternative='shutil.rmtree')
-def recursive_remove(path):
- if os.path.isdir(path):
- for fname in (glob.glob(os.path.join(path, '*')) +
- glob.glob(os.path.join(path, '.*'))):
- if os.path.isdir(fname):
- recursive_remove(fname)
- os.removedirs(fname)
- else:
- os.remove(fname)
- # os.removedirs(path)
- else:
- os.remove(path)
-
-
-def delete_masked_points(*args):
- """
- Find all masked and/or non-finite points in a set of arguments,
- and return the arguments with only the unmasked points remaining.
-
- Arguments can be in any of 5 categories:
-
- 1) 1-D masked arrays
- 2) 1-D ndarrays
- 3) ndarrays with more than one dimension
- 4) other non-string iterables
- 5) anything else
-
- The first argument must be in one of the first four categories;
- any argument with a length differing from that of the first
- argument (and hence anything in category 5) then will be
- passed through unchanged.
-
- Masks are obtained from all arguments of the correct length
- in categories 1, 2, and 4; a point is bad if masked in a masked
- array or if it is a nan or inf. No attempt is made to
- extract a mask from categories 2, 3, and 4 if :meth:`np.isfinite`
- does not yield a Boolean array.
-
- All input arguments that are not passed unchanged are returned
- as ndarrays after removing the points or rows corresponding to
- masks in any of the arguments.
-
- A vastly simpler version of this function was originally
- written as a helper for Axes.scatter().
-
- """
- if not len(args):
- return ()
- if (isinstance(args[0], six.string_types) or not iterable(args[0])):
- raise ValueError("First argument must be a sequence")
- nrecs = len(args[0])
- margs = []
- seqlist = [False] * len(args)
- for i, x in enumerate(args):
- if (not isinstance(x, six.string_types) and iterable(x)
- and len(x) == nrecs):
- seqlist[i] = True
- if isinstance(x, np.ma.MaskedArray):
- if x.ndim > 1:
- raise ValueError("Masked arrays must be 1-D")
- else:
- x = np.asarray(x)
- margs.append(x)
- masks = [] # list of masks that are True where good
- for i, x in enumerate(margs):
- if seqlist[i]:
- if x.ndim > 1:
- continue # Don't try to get nan locations unless 1-D.
- if isinstance(x, np.ma.MaskedArray):
- masks.append(~np.ma.getmaskarray(x)) # invert the mask
- xd = x.data
- else:
- xd = x
- try:
- mask = np.isfinite(xd)
- if isinstance(mask, np.ndarray):
- masks.append(mask)
- except: # Fixme: put in tuple of possible exceptions?
- pass
- if len(masks):
- mask = np.logical_and.reduce(masks)
- igood = mask.nonzero()[0]
- if len(igood) < nrecs:
- for i, x in enumerate(margs):
- if seqlist[i]:
- margs[i] = x.take(igood, axis=0)
- for i, x in enumerate(margs):
- if seqlist[i] and isinstance(x, np.ma.MaskedArray):
- margs[i] = x.filled()
- return margs
-
-
-def boxplot_stats(X, whis=1.5, bootstrap=None, labels=None,
- autorange=False):
- """
- Returns list of dictionaries of statistics used to draw a series
- of box and whisker plots. The `Returns` section enumerates the
- required keys of the dictionary. Users can skip this function and
- pass a user-defined set of dictionaries to the new `axes.bxp` method
- instead of relying on MPL to do the calculations.
-
- Parameters
- ----------
- X : array-like
- Data that will be represented in the boxplots. Should have 2 or
- fewer dimensions.
-
- whis : float, string, or sequence (default = 1.5)
- As a float, determines the reach of the whiskers to the beyond the
- first and third quartiles. In other words, where IQR is the
- interquartile range (`Q3-Q1`), the upper whisker will extend to last
- datum less than `Q3 + whis*IQR`). Similarly, the lower whisker will
- extend to the first datum greater than `Q1 - whis*IQR`.
- Beyond the whiskers, data are considered outliers
- and are plotted as individual points. This can be set this to an
- ascending sequence of percentile (e.g., [5, 95]) to set the
- whiskers at specific percentiles of the data. Finally, `whis`
- can be the string ``'range'`` to force the whiskers to the
- minimum and maximum of the data. In the edge case that the 25th
- and 75th percentiles are equivalent, `whis` can be automatically
- set to ``'range'`` via the `autorange` option.
-
- bootstrap : int, optional
- Number of times the confidence intervals around the median
- should be bootstrapped (percentile method).
-
- labels : array-like, optional
- Labels for each dataset. Length must be compatible with
- dimensions of `X`.
-
- autorange : bool, optional (False)
- When `True` and the data are distributed such that the 25th and
- 75th percentiles are equal, ``whis`` is set to ``'range'`` such
- that the whisker ends are at the minimum and maximum of the
- data.
-
- Returns
- -------
- bxpstats : list of dict
- A list of dictionaries containing the results for each column
- of data. Keys of each dictionary are the following:
-
- ======== ===================================
- Key Value Description
- ======== ===================================
- label tick label for the boxplot
- mean arithemetic mean value
- med 50th percentile
- q1 first quartile (25th percentile)
- q3 third quartile (75th percentile)
- cilo lower notch around the median
- cihi upper notch around the median
- whislo end of the lower whisker
- whishi end of the upper whisker
- fliers outliers
- ======== ===================================
-
- Notes
- -----
- Non-bootstrapping approach to confidence interval uses Gaussian-
- based asymptotic approximation:
-
- .. math::
-
- \\mathrm{med} \\pm 1.57 \\times \\frac{\\mathrm{iqr}}{\\sqrt{N}}
-
- General approach from:
- McGill, R., Tukey, J.W., and Larsen, W.A. (1978) "Variations of
- Boxplots", The American Statistician, 32:12-16.
-
- """
-
- def _bootstrap_median(data, N=5000):
- # determine 95% confidence intervals of the median
- M = len(data)
- percentiles = [2.5, 97.5]
-
- bs_index = np.random.randint(M, size=(N, M))
- bsData = data[bs_index]
- estimate = np.median(bsData, axis=1, overwrite_input=True)
-
- CI = np.percentile(estimate, percentiles)
- return CI
-
- def _compute_conf_interval(data, med, iqr, bootstrap):
- if bootstrap is not None:
- # Do a bootstrap estimate of notch locations.
- # get conf. intervals around median
- CI = _bootstrap_median(data, N=bootstrap)
- notch_min = CI[0]
- notch_max = CI[1]
- else:
-
- N = len(data)
- notch_min = med - 1.57 * iqr / np.sqrt(N)
- notch_max = med + 1.57 * iqr / np.sqrt(N)
-
- return notch_min, notch_max
-
- # output is a list of dicts
- bxpstats = []
-
- # convert X to a list of lists
- X = _reshape_2D(X, "X")
-
- ncols = len(X)
- if labels is None:
- labels = repeat(None)
- elif len(labels) != ncols:
- raise ValueError("Dimensions of labels and X must be compatible")
-
- input_whis = whis
- for ii, (x, label) in enumerate(zip(X, labels), start=0):
-
- # empty dict
- stats = {}
- if label is not None:
- stats['label'] = label
-
- # restore whis to the input values in case it got changed in the loop
- whis = input_whis
-
- # note tricksyness, append up here and then mutate below
- bxpstats.append(stats)
-
- # if empty, bail
- if len(x) == 0:
- stats['fliers'] = np.array([])
- stats['mean'] = np.nan
- stats['med'] = np.nan
- stats['q1'] = np.nan
- stats['q3'] = np.nan
- stats['cilo'] = np.nan
- stats['cihi'] = np.nan
- stats['whislo'] = np.nan
- stats['whishi'] = np.nan
- stats['med'] = np.nan
- continue
-
- # up-convert to an array, just to be safe
- x = np.asarray(x)
-
- # arithmetic mean
- stats['mean'] = np.mean(x)
-
- # medians and quartiles
- q1, med, q3 = np.percentile(x, [25, 50, 75])
-
- # interquartile range
- stats['iqr'] = q3 - q1
- if stats['iqr'] == 0 and autorange:
- whis = 'range'
-
- # conf. interval around median
- stats['cilo'], stats['cihi'] = _compute_conf_interval(
- x, med, stats['iqr'], bootstrap
- )
-
- # lowest/highest non-outliers
- if np.isscalar(whis):
- if np.isreal(whis):
- loval = q1 - whis * stats['iqr']
- hival = q3 + whis * stats['iqr']
- elif whis in ['range', 'limit', 'limits', 'min/max']:
- loval = np.min(x)
- hival = np.max(x)
- else:
- raise ValueError('whis must be a float, valid string, or list '
- 'of percentiles')
- else:
- loval = np.percentile(x, whis[0])
- hival = np.percentile(x, whis[1])
-
- # get high extreme
- wiskhi = np.compress(x <= hival, x)
- if len(wiskhi) == 0 or np.max(wiskhi) < q3:
- stats['whishi'] = q3
- else:
- stats['whishi'] = np.max(wiskhi)
-
- # get low extreme
- wisklo = np.compress(x >= loval, x)
- if len(wisklo) == 0 or np.min(wisklo) > q1:
- stats['whislo'] = q1
- else:
- stats['whislo'] = np.min(wisklo)
-
- # compute a single array of outliers
- stats['fliers'] = np.hstack([
- np.compress(x < stats['whislo'], x),
- np.compress(x > stats['whishi'], x)
- ])
-
- # add in the remaining stats
- stats['q1'], stats['med'], stats['q3'] = q1, med, q3
-
- return bxpstats
-
-
-# FIXME I don't think this is used anywhere
-@deprecated('2.1')
-def unmasked_index_ranges(mask, compressed=True):
- """
- Find index ranges where *mask* is *False*.
-
- *mask* will be flattened if it is not already 1-D.
-
- Returns Nx2 :class:`numpy.ndarray` with each row the start and stop
- indices for slices of the compressed :class:`numpy.ndarray`
- corresponding to each of *N* uninterrupted runs of unmasked
- values. If optional argument *compressed* is *False*, it returns
- the start and stop indices into the original :class:`numpy.ndarray`,
- not the compressed :class:`numpy.ndarray`. Returns *None* if there
- are no unmasked values.
-
- Example::
-
- y = ma.array(np.arange(5), mask = [0,0,1,0,0])
- ii = unmasked_index_ranges(ma.getmaskarray(y))
- # returns array [[0,2,] [2,4,]]
-
- y.compressed()[ii[1,0]:ii[1,1]]
- # returns array [3,4,]
-
- ii = unmasked_index_ranges(ma.getmaskarray(y), compressed=False)
- # returns array [[0, 2], [3, 5]]
-
- y.filled()[ii[1,0]:ii[1,1]]
- # returns array [3,4,]
-
- Prior to the transforms refactoring, this was used to support
- masked arrays in Line2D.
- """
- mask = mask.reshape(mask.size)
- m = np.concatenate(((1,), mask, (1,)))
- indices = np.arange(len(mask) + 1)
- mdif = m[1:] - m[:-1]
- i0 = np.compress(mdif == -1, indices)
- i1 = np.compress(mdif == 1, indices)
- assert len(i0) == len(i1)
- if len(i1) == 0:
- return None # Maybe this should be np.zeros((0,2), dtype=int)
- if not compressed:
- return np.concatenate((i0[:, np.newaxis], i1[:, np.newaxis]), axis=1)
- seglengths = i1 - i0
- breakpoints = np.cumsum(seglengths)
- ic0 = np.concatenate(((0,), breakpoints[:-1]))
- ic1 = breakpoints
- return np.concatenate((ic0[:, np.newaxis], ic1[:, np.newaxis]), axis=1)
-
-
-# The ls_mapper maps short codes for line style to their full name used by
-# backends; the reverse mapper is for mapping full names to short ones.
-ls_mapper = {'-': 'solid', '--': 'dashed', '-.': 'dashdot', ':': 'dotted'}
-ls_mapper_r = {v: k for k, v in six.iteritems(ls_mapper)}
-
-
-@deprecated('2.2')
-def align_iterators(func, *iterables):
- """
- This generator takes a bunch of iterables that are ordered by func
- It sends out ordered tuples::
-
- (func(row), [rows from all iterators matching func(row)])
-
- It is used by :func:`matplotlib.mlab.recs_join` to join record arrays
- """
- class myiter:
- def __init__(self, it):
- self.it = it
- self.key = self.value = None
- self.iternext()
-
- def iternext(self):
- try:
- self.value = next(self.it)
- self.key = func(self.value)
- except StopIteration:
- self.value = self.key = None
-
- def __call__(self, key):
- retval = None
- if key == self.key:
- retval = self.value
- self.iternext()
- elif self.key and key > self.key:
- raise ValueError("Iterator has been left behind")
- return retval
-
- # This can be made more efficient by not computing the minimum key for each
- # iteration
- iters = [myiter(it) for it in iterables]
- minvals = minkey = True
- while True:
- minvals = ([_f for _f in [it.key for it in iters] if _f])
- if minvals:
- minkey = min(minvals)
- yield (minkey, [it(minkey) for it in iters])
- else:
- break
-
-
-def contiguous_regions(mask):
- """
- Return a list of (ind0, ind1) such that mask[ind0:ind1].all() is
- True and we cover all such regions
- """
- mask = np.asarray(mask, dtype=bool)
-
- if not mask.size:
- return []
-
- # Find the indices of region changes, and correct offset
- idx, = np.nonzero(mask[:-1] != mask[1:])
- idx += 1
-
- # List operations are faster for moderately sized arrays
- idx = idx.tolist()
-
- # Add first and/or last index if needed
- if mask[0]:
- idx = [0] + idx
- if mask[-1]:
- idx.append(len(mask))
-
- return list(zip(idx[::2], idx[1::2]))
-
-
-def is_math_text(s):
- # Did we find an even number of non-escaped dollar signs?
- # If so, treat is as math text.
- try:
- s = six.text_type(s)
- except UnicodeDecodeError:
- raise ValueError(
- "matplotlib display text must have all code points < 128 or use "
- "Unicode strings")
-
- dollar_count = s.count(r'$') - s.count(r'\$')
- even_dollars = (dollar_count > 0 and dollar_count % 2 == 0)
-
- return even_dollars
-
-
-def _to_unmasked_float_array(x):
- """
- Convert a sequence to a float array; if input was a masked array, masked
- values are converted to nans.
- """
- if hasattr(x, 'mask'):
- return np.ma.asarray(x, float).filled(np.nan)
- else:
- return np.asarray(x, float)
-
-
-def _check_1d(x):
- '''
- Converts a sequence of less than 1 dimension, to an array of 1
- dimension; leaves everything else untouched.
- '''
- if not hasattr(x, 'shape') or len(x.shape) < 1:
- return np.atleast_1d(x)
- else:
- try:
- # work around
- # https://github.com/pandas-dev/pandas/issues/27775 which
- # means the shape of multi-dimensional slicing is not as
- # expected. That this ever worked was an unintentional
- # quirk of pandas and will raise an exception in the
- # future. This slicing warns in pandas >= 1.0rc0 via
- # https://github.com/pandas-dev/pandas/pull/30588
- #
- # < 1.0rc0 : x[:, None].ndim == 1, no warning, custom type
- # >= 1.0rc1 : x[:, None].ndim == 2, warns, numpy array
- # future : x[:, None] -> raises
- #
- # This code should correctly identify and coerce to a
- # numpy array all pandas versions.
- with warnings.catch_warnings(record=True) as w:
- warnings.filterwarnings(
- "always",
- category=DeprecationWarning,
- message='Support for multi-dimensional indexing')
-
- ndim = x[:, None].ndim
- # we have definitely hit a pandas index or series object
- # cast to a numpy array.
- if len(w) > 0:
- return np.asanyarray(x)
- # We have likely hit a pandas object, or at least
- # something where 2D slicing does not result in a 2D
- # object.
- if ndim < 2:
- return np.atleast_1d(x)
- return x
- except (IndexError, TypeError):
- return np.atleast_1d(x)
-
-
-def _reshape_2D(X, name):
- """
- Use Fortran ordering to convert ndarrays and lists of iterables to lists of
- 1D arrays.
-
- Lists of iterables are converted by applying `np.asarray` to each of their
- elements. 1D ndarrays are returned in a singleton list containing them.
- 2D ndarrays are converted to the list of their *columns*.
-
- *name* is used to generate the error message for invalid inputs.
- """
- # Iterate over columns for ndarrays, over rows otherwise.
- X = np.atleast_1d(X.T if isinstance(X, np.ndarray) else np.asarray(X))
- if X.ndim == 1 and X.dtype.type != np.object_:
- # 1D array of scalars: directly return it.
- return [X]
- elif X.ndim in [1, 2]:
- # 2D array, or 1D array of iterables: flatten them first.
- return [np.reshape(x, -1) for x in X]
- else:
- raise ValueError("{} must have 2 or fewer dimensions".format(name))
-
-
-def violin_stats(X, method, points=100):
- """
- Returns a list of dictionaries of data which can be used to draw a series
- of violin plots. See the `Returns` section below to view the required keys
- of the dictionary. Users can skip this function and pass a user-defined set
- of dictionaries to the `axes.vplot` method instead of using MPL to do the
- calculations.
-
- Parameters
- ----------
- X : array-like
- Sample data that will be used to produce the gaussian kernel density
- estimates. Must have 2 or fewer dimensions.
-
- method : callable
- The method used to calculate the kernel density estimate for each
- column of data. When called via `method(v, coords)`, it should
- return a vector of the values of the KDE evaluated at the values
- specified in coords.
-
- points : scalar, default = 100
- Defines the number of points to evaluate each of the gaussian kernel
- density estimates at.
-
- Returns
- -------
-
- A list of dictionaries containing the results for each column of data.
- The dictionaries contain at least the following:
-
- - coords: A list of scalars containing the coordinates this particular
- kernel density estimate was evaluated at.
- - vals: A list of scalars containing the values of the kernel density
- estimate at each of the coordinates given in `coords`.
- - mean: The mean value for this column of data.
- - median: The median value for this column of data.
- - min: The minimum value for this column of data.
- - max: The maximum value for this column of data.
- """
-
- # List of dictionaries describing each of the violins.
- vpstats = []
-
- # Want X to be a list of data sequences
- X = _reshape_2D(X, "X")
-
- for x in X:
- # Dictionary of results for this distribution
- stats = {}
-
- # Calculate basic stats for the distribution
- min_val = np.min(x)
- max_val = np.max(x)
-
- # Evaluate the kernel density estimate
- coords = np.linspace(min_val, max_val, points)
- stats['vals'] = method(x, coords)
- stats['coords'] = coords
-
- # Store additional statistics for this distribution
- stats['mean'] = np.mean(x)
- stats['median'] = np.median(x)
- stats['min'] = min_val
- stats['max'] = max_val
-
- # Append to output
- vpstats.append(stats)
-
- return vpstats
-
-
-class _NestedClassGetter(object):
- # recipe from http://stackoverflow.com/a/11493777/741316
- """
- When called with the containing class as the first argument,
- and the name of the nested class as the second argument,
- returns an instance of the nested class.
- """
- def __call__(self, containing_class, class_name):
- nested_class = getattr(containing_class, class_name)
-
- # make an instance of a simple object (this one will do), for which we
- # can change the __class__ later on.
- nested_instance = _NestedClassGetter()
-
- # set the class of the instance, the __init__ will never be called on
- # the class but the original state will be set later on by pickle.
- nested_instance.__class__ = nested_class
- return nested_instance
-
-
-class _InstanceMethodPickler(object):
- """
- Pickle cannot handle instancemethod saving. _InstanceMethodPickler
- provides a solution to this.
- """
- def __init__(self, instancemethod):
- """Takes an instancemethod as its only argument."""
- if six.PY3:
- self.parent_obj = instancemethod.__self__
- self.instancemethod_name = instancemethod.__func__.__name__
- else:
- self.parent_obj = instancemethod.im_self
- self.instancemethod_name = instancemethod.im_func.__name__
-
- def get_instancemethod(self):
- return getattr(self.parent_obj, self.instancemethod_name)
-
-
-def pts_to_prestep(x, *args):
- """
- Convert continuous line to pre-steps.
-
- Given a set of ``N`` points, convert to ``2N - 1`` points, which when
- connected linearly give a step function which changes values at the
- beginning of the intervals.
-
- Parameters
- ----------
- x : array
- The x location of the steps. May be empty.
-
- y1, ..., yp : array
- y arrays to be turned into steps; all must be the same length as ``x``.
-
- Returns
- -------
- out : array
- The x and y values converted to steps in the same order as the input;
- can be unpacked as ``x_out, y1_out, ..., yp_out``. If the input is
- length ``N``, each of these arrays will be length ``2N + 1``. For
- ``N=0``, the length will be 0.
-
- Examples
- --------
- >> x_s, y1_s, y2_s = pts_to_prestep(x, y1, y2)
- """
- steps = np.zeros((1 + len(args), max(2 * len(x) - 1, 0)))
- # In all `pts_to_*step` functions, only assign *once* using `x` and `args`,
- # as converting to an array may be expensive.
- steps[0, 0::2] = x
- steps[0, 1::2] = steps[0, 0:-2:2]
- steps[1:, 0::2] = args
- steps[1:, 1::2] = steps[1:, 2::2]
- return steps
-
-
-def pts_to_poststep(x, *args):
- """
- Convert continuous line to post-steps.
-
- Given a set of ``N`` points convert to ``2N + 1`` points, which when
- connected linearly give a step function which changes values at the end of
- the intervals.
-
- Parameters
- ----------
- x : array
- The x location of the steps. May be empty.
-
- y1, ..., yp : array
- y arrays to be turned into steps; all must be the same length as ``x``.
-
- Returns
- -------
- out : array
- The x and y values converted to steps in the same order as the input;
- can be unpacked as ``x_out, y1_out, ..., yp_out``. If the input is
- length ``N``, each of these arrays will be length ``2N + 1``. For
- ``N=0``, the length will be 0.
-
- Examples
- --------
- >> x_s, y1_s, y2_s = pts_to_poststep(x, y1, y2)
- """
- steps = np.zeros((1 + len(args), max(2 * len(x) - 1, 0)))
- steps[0, 0::2] = x
- steps[0, 1::2] = steps[0, 2::2]
- steps[1:, 0::2] = args
- steps[1:, 1::2] = steps[1:, 0:-2:2]
- return steps
-
-
-def pts_to_midstep(x, *args):
- """
- Convert continuous line to mid-steps.
-
- Given a set of ``N`` points convert to ``2N`` points which when connected
- linearly give a step function which changes values at the middle of the
- intervals.
-
- Parameters
- ----------
- x : array
- The x location of the steps. May be empty.
-
- y1, ..., yp : array
- y arrays to be turned into steps; all must be the same length as
- ``x``.
-
- Returns
- -------
- out : array
- The x and y values converted to steps in the same order as the input;
- can be unpacked as ``x_out, y1_out, ..., yp_out``. If the input is
- length ``N``, each of these arrays will be length ``2N``.
-
- Examples
- --------
- >> x_s, y1_s, y2_s = pts_to_midstep(x, y1, y2)
- """
- steps = np.zeros((1 + len(args), 2 * len(x)))
- x = np.asanyarray(x)
- steps[0, 1:-1:2] = steps[0, 2::2] = (x[:-1] + x[1:]) / 2
- steps[0, :1] = x[:1] # Also works for zero-sized input.
- steps[0, -1:] = x[-1:]
- steps[1:, 0::2] = args
- steps[1:, 1::2] = steps[1:, 0::2]
- return steps
-
-
-STEP_LOOKUP_MAP = {'default': lambda x, y: (x, y),
- 'steps': pts_to_prestep,
- 'steps-pre': pts_to_prestep,
- 'steps-post': pts_to_poststep,
- 'steps-mid': pts_to_midstep}
-
-
-def index_of(y):
- """
- A helper function to get the index of an input to plot
- against if x values are not explicitly given.
-
- Tries to get `y.index` (works if this is a pd.Series), if that
- fails, return np.arange(y.shape[0]).
-
- This will be extended in the future to deal with more types of
- labeled data.
-
- Parameters
- ----------
- y : scalar or array-like
- The proposed y-value
-
- Returns
- -------
- x, y : ndarray
- The x and y values to plot.
- """
- try:
- return y.index.values, y.values
- except AttributeError:
- y = _check_1d(y)
- return np.arange(y.shape[0], dtype=float), y
-
-
-def safe_first_element(obj):
- if isinstance(obj, cabc.Iterator):
- # needed to accept `array.flat` as input.
- # np.flatiter reports as an instance of collections.Iterator
- # but can still be indexed via [].
- # This has the side effect of re-setting the iterator, but
- # that is acceptable.
- try:
- return obj[0]
- except TypeError:
- pass
- raise RuntimeError("matplotlib does not support generators "
- "as input")
- return next(iter(obj))
-
-
-def sanitize_sequence(data):
- """Converts dictview object to list"""
- return (list(data) if isinstance(data, cabc.MappingView)
- else data)
-
-
-def normalize_kwargs(kw, alias_mapping=None, required=(), forbidden=(),
- allowed=None):
- """Helper function to normalize kwarg inputs
-
- The order they are resolved are:
-
- 1. aliasing
- 2. required
- 3. forbidden
- 4. allowed
-
- This order means that only the canonical names need appear in
- `allowed`, `forbidden`, `required`
-
- Parameters
- ----------
-
- alias_mapping, dict, optional
- A mapping between a canonical name to a list of
- aliases, in order of precedence from lowest to highest.
-
- If the canonical value is not in the list it is assumed to have
- the highest priority.
-
- required : iterable, optional
- A tuple of fields that must be in kwargs.
-
- forbidden : iterable, optional
- A list of keys which may not be in kwargs
-
- allowed : tuple, optional
- A tuple of allowed fields. If this not None, then raise if
- `kw` contains any keys not in the union of `required`
- and `allowed`. To allow only the required fields pass in
- ``()`` for `allowed`
-
- Raises
- ------
- TypeError
- To match what python raises if invalid args/kwargs are passed to
- a callable.
-
- """
- # deal with default value of alias_mapping
- if alias_mapping is None:
- alias_mapping = dict()
-
- # make a local so we can pop
- kw = dict(kw)
- # output dictionary
- ret = dict()
-
- # hit all alias mappings
- for canonical, alias_list in six.iteritems(alias_mapping):
-
- # the alias lists are ordered from lowest to highest priority
- # so we know to use the last value in this list
- tmp = []
- seen = []
- for a in alias_list:
- try:
- tmp.append(kw.pop(a))
- seen.append(a)
- except KeyError:
- pass
- # if canonical is not in the alias_list assume highest priority
- if canonical not in alias_list:
- try:
- tmp.append(kw.pop(canonical))
- seen.append(canonical)
- except KeyError:
- pass
- # if we found anything in this set of aliases put it in the return
- # dict
- if tmp:
- ret[canonical] = tmp[-1]
- if len(tmp) > 1:
- warnings.warn("Saw kwargs {seen!r} which are all aliases for "
- "{canon!r}. Kept value from {used!r}".format(
- seen=seen, canon=canonical, used=seen[-1]))
-
- # at this point we know that all keys which are aliased are removed, update
- # the return dictionary from the cleaned local copy of the input
- ret.update(kw)
-
- fail_keys = [k for k in required if k not in ret]
- if fail_keys:
- raise TypeError("The required keys {keys!r} "
- "are not in kwargs".format(keys=fail_keys))
-
- fail_keys = [k for k in forbidden if k in ret]
- if fail_keys:
- raise TypeError("The forbidden keys {keys!r} "
- "are in kwargs".format(keys=fail_keys))
-
- if allowed is not None:
- allowed_set = set(required) | set(allowed)
- fail_keys = [k for k in ret if k not in allowed_set]
- if fail_keys:
- raise TypeError("kwargs contains {keys!r} which are not in "
- "the required {req!r} or "
- "allowed {allow!r} keys".format(
- keys=fail_keys, req=required,
- allow=allowed))
-
- return ret
-
-
-def get_label(y, default_name):
- try:
- return y.name
- except AttributeError:
- return default_name
-
-
-_lockstr = """\
-LOCKERROR: matplotlib is trying to acquire the lock
- {!r}
-and has failed. This maybe due to any other process holding this
-lock. If you are sure no other matplotlib process is running try
-removing these folders and trying again.
-"""
-
-
-class Locked(object):
- """
- Context manager to handle locks.
-
- Based on code from conda.
-
- (c) 2012-2013 Continuum Analytics, Inc. / https://www.continuum.io/
- All Rights Reserved
-
- conda is distributed under the terms of the BSD 3-clause license.
- Consult LICENSE_CONDA or https://opensource.org/licenses/BSD-3-Clause.
- """
- LOCKFN = '.matplotlib_lock'
-
- class TimeoutError(RuntimeError):
- pass
-
- def __init__(self, path):
- self.path = path
- self.end = "-" + str(os.getpid())
- self.lock_path = os.path.join(self.path, self.LOCKFN + self.end)
- self.pattern = os.path.join(self.path, self.LOCKFN + '-*')
- self.remove = True
-
- def __enter__(self):
- retries = 50
- sleeptime = 0.1
- while retries:
- files = glob.glob(self.pattern)
- if files and not files[0].endswith(self.end):
- time.sleep(sleeptime)
- retries -= 1
- else:
- break
- else:
- err_str = _lockstr.format(self.pattern)
- raise self.TimeoutError(err_str)
-
- if not files:
- try:
- os.makedirs(self.lock_path)
- except OSError:
- pass
- else: # PID lock already here --- someone else will remove it.
- self.remove = False
-
- def __exit__(self, exc_type, exc_value, traceback):
- if self.remove:
- for path in self.lock_path, self.path:
- try:
- os.rmdir(path)
- except OSError:
- pass
-
-
-class _FuncInfo(object):
- """
- Class used to store a function.
-
- """
-
- def __init__(self, function, inverse, bounded_0_1=True, check_params=None):
- """
- Parameters
- ----------
-
- function : callable
- A callable implementing the function receiving the variable as
- first argument and any additional parameters in a list as second
- argument.
- inverse : callable
- A callable implementing the inverse function receiving the variable
- as first argument and any additional parameters in a list as
- second argument. It must satisfy 'inverse(function(x, p), p) == x'.
- bounded_0_1: bool or callable
- A boolean indicating whether the function is bounded in the [0,1]
- interval, or a callable taking a list of values for the additional
- parameters, and returning a boolean indicating whether the function
- is bounded in the [0,1] interval for that combination of
- parameters. Default True.
- check_params: callable or None
- A callable taking a list of values for the additional parameters
- and returning a boolean indicating whether that combination of
- parameters is valid. It is only required if the function has
- additional parameters and some of them are restricted.
- Default None.
-
- """
-
- self.function = function
- self.inverse = inverse
-
- if callable(bounded_0_1):
- self._bounded_0_1 = bounded_0_1
- else:
- self._bounded_0_1 = lambda x: bounded_0_1
-
- if check_params is None:
- self._check_params = lambda x: True
- elif callable(check_params):
- self._check_params = check_params
- else:
- raise ValueError("Invalid 'check_params' argument.")
-
- def is_bounded_0_1(self, params=None):
- """
- Returns a boolean indicating if the function is bounded in the [0,1]
- interval for a particular set of additional parameters.
-
- Parameters
- ----------
-
- params : list
- The list of additional parameters. Default None.
-
- Returns
- -------
-
- out : bool
- True if the function is bounded in the [0,1] interval for
- parameters 'params'. Otherwise False.
-
- """
-
- return self._bounded_0_1(params)
-
- def check_params(self, params=None):
- """
- Returns a boolean indicating if the set of additional parameters is
- valid.
-
- Parameters
- ----------
-
- params : list
- The list of additional parameters. Default None.
-
- Returns
- -------
-
- out : bool
- True if 'params' is a valid set of additional parameters for the
- function. Otherwise False.
-
- """
-
- return self._check_params(params)
-
-
-class _StringFuncParser(object):
- """
- A class used to convert predefined strings into
- _FuncInfo objects, or to directly obtain _FuncInfo
- properties.
-
- """
-
- _funcs = {}
- _funcs['linear'] = _FuncInfo(lambda x: x,
- lambda x: x,
- True)
- _funcs['quadratic'] = _FuncInfo(np.square,
- np.sqrt,
- True)
- _funcs['cubic'] = _FuncInfo(lambda x: x**3,
- lambda x: x**(1. / 3),
- True)
- _funcs['sqrt'] = _FuncInfo(np.sqrt,
- np.square,
- True)
- _funcs['cbrt'] = _FuncInfo(lambda x: x**(1. / 3),
- lambda x: x**3,
- True)
- _funcs['log10'] = _FuncInfo(np.log10,
- lambda x: (10**(x)),
- False)
- _funcs['log'] = _FuncInfo(np.log,
- np.exp,
- False)
- _funcs['log2'] = _FuncInfo(np.log2,
- lambda x: (2**x),
- False)
- _funcs['x**{p}'] = _FuncInfo(lambda x, p: x**p[0],
- lambda x, p: x**(1. / p[0]),
- True)
- _funcs['root{p}(x)'] = _FuncInfo(lambda x, p: x**(1. / p[0]),
- lambda x, p: x**p,
- True)
- _funcs['log{p}(x)'] = _FuncInfo(lambda x, p: (np.log(x) /
- np.log(p[0])),
- lambda x, p: p[0]**(x),
- False,
- lambda p: p[0] > 0)
- _funcs['log10(x+{p})'] = _FuncInfo(lambda x, p: np.log10(x + p[0]),
- lambda x, p: 10**x - p[0],
- lambda p: p[0] > 0)
- _funcs['log(x+{p})'] = _FuncInfo(lambda x, p: np.log(x + p[0]),
- lambda x, p: np.exp(x) - p[0],
- lambda p: p[0] > 0)
- _funcs['log{p}(x+{p})'] = _FuncInfo(lambda x, p: (np.log(x + p[1]) /
- np.log(p[0])),
- lambda x, p: p[0]**(x) - p[1],
- lambda p: p[1] > 0,
- lambda p: p[0] > 0)
-
- def __init__(self, str_func):
- """
- Parameters
- ----------
- str_func : string
- String to be parsed.
-
- """
-
- if not isinstance(str_func, six.string_types):
- raise ValueError("'%s' must be a string." % str_func)
- self._str_func = six.text_type(str_func)
- self._key, self._params = self._get_key_params()
- self._func = self._parse_func()
-
- def _parse_func(self):
- """
- Parses the parameters to build a new _FuncInfo object,
- replacing the relevant parameters if necessary in the lambda
- functions.
-
- """
-
- func = self._funcs[self._key]
-
- if not self._params:
- func = _FuncInfo(func.function, func.inverse,
- func.is_bounded_0_1())
- else:
- m = func.function
- function = (lambda x, m=m: m(x, self._params))
-
- m = func.inverse
- inverse = (lambda x, m=m: m(x, self._params))
-
- is_bounded_0_1 = func.is_bounded_0_1(self._params)
-
- func = _FuncInfo(function, inverse,
- is_bounded_0_1)
- return func
-
- @property
- def func_info(self):
- """
- Returns the _FuncInfo object.
-
- """
- return self._func
-
- @property
- def function(self):
- """
- Returns the callable for the direct function.
-
- """
- return self._func.function
-
- @property
- def inverse(self):
- """
- Returns the callable for the inverse function.
-
- """
- return self._func.inverse
-
- @property
- def is_bounded_0_1(self):
- """
- Returns a boolean indicating if the function is bounded
- in the [0-1 interval].
-
- """
- return self._func.is_bounded_0_1()
-
- def _get_key_params(self):
- str_func = self._str_func
- # Checking if it comes with parameters
- regex = r'\{(.*?)\}'
- params = re.findall(regex, str_func)
-
- for i, param in enumerate(params):
- try:
- params[i] = float(param)
- except ValueError:
- raise ValueError("Parameter %i is '%s', which is "
- "not a number." %
- (i, param))
-
- str_func = re.sub(regex, '{p}', str_func)
-
- try:
- func = self._funcs[str_func]
- except (ValueError, KeyError):
- raise ValueError("'%s' is an invalid string. The only strings "
- "recognized as functions are %s." %
- (str_func, list(self._funcs)))
-
- # Checking that the parameters are valid
- if not func.check_params(params):
- raise ValueError("%s are invalid values for the parameters "
- "in %s." %
- (params, str_func))
-
- return str_func, params
-
-
-def _topmost_artist(
- artists,
- _cached_max=functools.partial(max, key=operator.attrgetter("zorder"))):
- """Get the topmost artist of a list.
-
- In case of a tie, return the *last* of the tied artists, as it will be
- drawn on top of the others. `max` returns the first maximum in case of ties
- (on Py2 this is undocumented but true), so we need to iterate over the list
- in reverse order.
- """
- return _cached_max(reversed(artists))
-
-
-def _str_equal(obj, s):
- """Return whether *obj* is a string equal to string *s*.
-
- This helper solely exists to handle the case where *obj* is a numpy array,
- because in such cases, a naive ``obj == s`` would yield an array, which
- cannot be used in a boolean context.
- """
- return isinstance(obj, six.string_types) and obj == s
-
-
-def _str_lower_equal(obj, s):
- """Return whether *obj* is a string equal, when lowercased, to string *s*.
-
- This helper solely exists to handle the case where *obj* is a numpy array,
- because in such cases, a naive ``obj == s`` would yield an array, which
- cannot be used in a boolean context.
- """
- return isinstance(obj, six.string_types) and obj.lower() == s
-
-
-@contextlib.contextmanager
-def _setattr_cm(obj, **kwargs):
- """Temporarily set some attributes; restore original state at context exit.
- """
- sentinel = object()
- origs = [(attr, getattr(obj, attr, sentinel)) for attr in kwargs]
- try:
- for attr, val in kwargs.items():
- setattr(obj, attr, val)
- yield
- finally:
- for attr, orig in origs:
- if orig is sentinel:
- delattr(obj, attr)
- else:
- setattr(obj, attr, orig)
diff --git a/contrib/python/matplotlib/py2/matplotlib/cbook/_backports.py b/contrib/python/matplotlib/py2/matplotlib/cbook/_backports.py
deleted file mode 100644
index 8383325855..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/cbook/_backports.py
+++ /dev/null
@@ -1,147 +0,0 @@
-from __future__ import absolute_import
-
-import os
-import sys
-
-import numpy as np
-
-
-# Copy-pasted from Python 3.4's shutil.
-def which(cmd, mode=os.F_OK | os.X_OK, path=None):
- """Given a command, mode, and a PATH string, return the path which
- conforms to the given mode on the PATH, or None if there is no such
- file.
-
- `mode` defaults to os.F_OK | os.X_OK. `path` defaults to the result
- of os.environ.get("PATH"), or can be overridden with a custom search
- path.
-
- """
- # Check that a given file can be accessed with the correct mode.
- # Additionally check that `file` is not a directory, as on Windows
- # directories pass the os.access check.
- def _access_check(fn, mode):
- return (os.path.exists(fn) and os.access(fn, mode)
- and not os.path.isdir(fn))
-
- # If we're given a path with a directory part, look it up directly rather
- # than referring to PATH directories. This includes checking relative to the
- # current directory, e.g. ./script
- if os.path.dirname(cmd):
- if _access_check(cmd, mode):
- return cmd
- return None
-
- if path is None:
- path = os.environ.get("PATH", os.defpath)
- if not path:
- return None
- path = path.split(os.pathsep)
-
- if sys.platform == "win32":
- # The current directory takes precedence on Windows.
- if not os.curdir in path:
- path.insert(0, os.curdir)
-
- # PATHEXT is necessary to check on Windows.
- pathext = os.environ.get("PATHEXT", "").split(os.pathsep)
- # See if the given file matches any of the expected path extensions.
- # This will allow us to short circuit when given "python.exe".
- # If it does match, only test that one, otherwise we have to try
- # others.
- if any(cmd.lower().endswith(ext.lower()) for ext in pathext):
- files = [cmd]
- else:
- files = [cmd + ext for ext in pathext]
- else:
- # On other platforms you don't have things like PATHEXT to tell you
- # what file suffixes are executable, so just pass on cmd as-is.
- files = [cmd]
-
- seen = set()
- for dir in path:
- normdir = os.path.normcase(dir)
- if not normdir in seen:
- seen.add(normdir)
- for thefile in files:
- name = os.path.join(dir, thefile)
- if _access_check(name, mode):
- return name
- return None
-
-
-# Copy-pasted from numpy.lib.stride_tricks 1.11.2.
-def _maybe_view_as_subclass(original_array, new_array):
- if type(original_array) is not type(new_array):
- # if input was an ndarray subclass and subclasses were OK,
- # then view the result as that subclass.
- new_array = new_array.view(type=type(original_array))
- # Since we have done something akin to a view from original_array, we
- # should let the subclass finalize (if it has it implemented, i.e., is
- # not None).
- if new_array.__array_finalize__:
- new_array.__array_finalize__(original_array)
- return new_array
-
-
-# Copy-pasted from numpy.lib.stride_tricks 1.11.2.
-def _broadcast_to(array, shape, subok, readonly):
- shape = tuple(shape) if np.iterable(shape) else (shape,)
- array = np.array(array, copy=False, subok=subok)
- if not shape and array.shape:
- raise ValueError('cannot broadcast a non-scalar to a scalar array')
- if any(size < 0 for size in shape):
- raise ValueError('all elements of broadcast shape must be non-'
- 'negative')
- needs_writeable = not readonly and array.flags.writeable
- extras = ['reduce_ok'] if needs_writeable else []
- op_flag = 'readwrite' if needs_writeable else 'readonly'
- broadcast = np.nditer(
- (array,), flags=['multi_index', 'refs_ok', 'zerosize_ok'] + extras,
- op_flags=[op_flag], itershape=shape, order='C').itviews[0]
- result = _maybe_view_as_subclass(array, broadcast)
- if needs_writeable and not result.flags.writeable:
- result.flags.writeable = True
- return result
-
-
-# Copy-pasted from numpy.lib.stride_tricks 1.11.2.
-def broadcast_to(array, shape, subok=False):
- """Broadcast an array to a new shape.
-
- Parameters
- ----------
- array : array_like
- The array to broadcast.
- shape : tuple
- The shape of the desired array.
- subok : bool, optional
- If True, then sub-classes will be passed-through, otherwise
- the returned array will be forced to be a base-class array (default).
-
- Returns
- -------
- broadcast : array
- A readonly view on the original array with the given shape. It is
- typically not contiguous. Furthermore, more than one element of a
- broadcasted array may refer to a single memory location.
-
- Raises
- ------
- ValueError
- If the array is not compatible with the new shape according to NumPy's
- broadcasting rules.
-
- Notes
- -----
- .. versionadded:: 1.10.0
-
- Examples
- --------
- >>> x = np.array([1, 2, 3])
- >>> np.broadcast_to(x, (3, 3))
- array([[1, 2, 3],
- [1, 2, 3],
- [1, 2, 3]])
- """
- return _broadcast_to(array, shape, subok=subok, readonly=True)
diff --git a/contrib/python/matplotlib/py2/matplotlib/cbook/deprecation.py b/contrib/python/matplotlib/py2/matplotlib/cbook/deprecation.py
deleted file mode 100644
index ca7ae333f2..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/cbook/deprecation.py
+++ /dev/null
@@ -1,222 +0,0 @@
-import functools
-import textwrap
-import warnings
-
-
-class MatplotlibDeprecationWarning(UserWarning):
- """
- A class for issuing deprecation warnings for Matplotlib users.
-
- In light of the fact that Python builtin DeprecationWarnings are ignored
- by default as of Python 2.7 (see link below), this class was put in to
- allow for the signaling of deprecation, but via UserWarnings which are not
- ignored by default.
-
- https://docs.python.org/dev/whatsnew/2.7.html#the-future-for-python-2-x
- """
- pass
-
-
-mplDeprecation = MatplotlibDeprecationWarning
-
-
-def _generate_deprecation_message(since, message='', name='',
- alternative='', pending=False,
- obj_type='attribute',
- addendum=''):
-
- if not message:
-
- if pending:
- message = (
- 'The %(name)s %(obj_type)s will be deprecated in a '
- 'future version.')
- else:
- message = (
- 'The %(name)s %(obj_type)s was deprecated in version '
- '%(since)s.')
-
- altmessage = ''
- if alternative:
- altmessage = ' Use %s instead.' % alternative
-
- message = ((message % {
- 'func': name,
- 'name': name,
- 'alternative': alternative,
- 'obj_type': obj_type,
- 'since': since}) +
- altmessage)
-
- if addendum:
- message += addendum
-
- return message
-
-
-def warn_deprecated(
- since, message='', name='', alternative='', pending=False,
- obj_type='attribute', addendum=''):
- """
- Used to display deprecation warning in a standard way.
-
- Parameters
- ----------
- since : str
- The release at which this API became deprecated.
-
- message : str, optional
- Override the default deprecation message. The format
- specifier `%(name)s` may be used for the name of the function,
- and `%(alternative)s` may be used in the deprecation message
- to insert the name of an alternative to the deprecated
- function. `%(obj_type)s` may be used to insert a friendly name
- for the type of object being deprecated.
-
- name : str, optional
- The name of the deprecated object.
-
- alternative : str, optional
- An alternative function that the user may use in place of the
- deprecated function. The deprecation warning will tell the user
- about this alternative if provided.
-
- pending : bool, optional
- If True, uses a PendingDeprecationWarning instead of a
- DeprecationWarning.
-
- obj_type : str, optional
- The object type being deprecated.
-
- addendum : str, optional
- Additional text appended directly to the final message.
-
- Examples
- --------
-
- Basic example::
-
- # To warn of the deprecation of "matplotlib.name_of_module"
- warn_deprecated('1.4.0', name='matplotlib.name_of_module',
- obj_type='module')
-
- """
- message = _generate_deprecation_message(
- since, message, name, alternative, pending, obj_type)
-
- warnings.warn(message, mplDeprecation, stacklevel=1)
-
-
-def deprecated(since, message='', name='', alternative='', pending=False,
- obj_type=None, addendum=''):
- """
- Decorator to mark a function or a class as deprecated.
-
- Parameters
- ----------
- since : str
- The release at which this API became deprecated. This is
- required.
-
- message : str, optional
- Override the default deprecation message. The format
- specifier `%(name)s` may be used for the name of the object,
- and `%(alternative)s` may be used in the deprecation message
- to insert the name of an alternative to the deprecated
- object. `%(obj_type)s` may be used to insert a friendly name
- for the type of object being deprecated.
-
- name : str, optional
- The name of the deprecated object; if not provided the name
- is automatically determined from the passed in object,
- though this is useful in the case of renamed functions, where
- the new function is just assigned to the name of the
- deprecated function. For example::
-
- def new_function():
- ...
- oldFunction = new_function
-
- alternative : str, optional
- An alternative object that the user may use in place of the
- deprecated object. The deprecation warning will tell the user
- about this alternative if provided.
-
- pending : bool, optional
- If True, uses a PendingDeprecationWarning instead of a
- DeprecationWarning.
-
- addendum : str, optional
- Additional text appended directly to the final message.
-
- Examples
- --------
-
- Basic example::
-
- @deprecated('1.4.0')
- def the_function_to_deprecate():
- pass
-
- """
-
- def deprecate(obj, message=message, name=name, alternative=alternative,
- pending=pending, addendum=addendum):
-
- if not name:
- name = obj.__name__
-
- if isinstance(obj, type):
- obj_type = "class"
- old_doc = obj.__doc__
- func = obj.__init__
-
- def finalize(wrapper, new_doc):
- try:
- obj.__doc__ = new_doc
- except (AttributeError, TypeError):
- # cls.__doc__ is not writeable on Py2.
- # TypeError occurs on PyPy
- pass
- obj.__init__ = wrapper
- return obj
- else:
- obj_type = "function"
- if isinstance(obj, classmethod):
- func = obj.__func__
- old_doc = func.__doc__
-
- def finalize(wrapper, new_doc):
- wrapper = functools.wraps(func)(wrapper)
- wrapper.__doc__ = new_doc
- return classmethod(wrapper)
- else:
- func = obj
- old_doc = func.__doc__
-
- def finalize(wrapper, new_doc):
- wrapper = functools.wraps(func)(wrapper)
- wrapper.__doc__ = new_doc
- return wrapper
-
- message = _generate_deprecation_message(
- since, message, name, alternative, pending,
- obj_type, addendum)
-
- def wrapper(*args, **kwargs):
- warnings.warn(message, mplDeprecation, stacklevel=2)
- return func(*args, **kwargs)
-
- old_doc = textwrap.dedent(old_doc or '').strip('\n')
- message = message.strip()
- new_doc = (('\n.. deprecated:: %(since)s'
- '\n %(message)s\n\n' %
- {'since': since, 'message': message}) + old_doc)
- if not old_doc:
- # This is to prevent a spurious 'unexected unindent' warning from
- # docutils when the original docstring was blank.
- new_doc += r'\ '
-
- return finalize(wrapper, new_doc)
-
- return deprecate
diff --git a/contrib/python/matplotlib/py2/matplotlib/cm.py b/contrib/python/matplotlib/py2/matplotlib/cm.py
deleted file mode 100644
index e4e3dca502..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/cm.py
+++ /dev/null
@@ -1,392 +0,0 @@
-"""
-Builtin colormaps, colormap handling utilities, and the `ScalarMappable` mixin.
-
-See :doc:`/gallery/color/colormap_reference` for a list of builtin colormaps.
-See :doc:`/tutorials/colors/colormaps` for an in-depth discussion of colormaps.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import numpy as np
-from numpy import ma
-import matplotlib as mpl
-import matplotlib.colors as colors
-import matplotlib.cbook as cbook
-from matplotlib._cm import datad
-from matplotlib._cm_listed import cmaps as cmaps_listed
-
-
-cmap_d = {}
-
-
-# reverse all the colormaps.
-# reversed colormaps have '_r' appended to the name.
-
-
-def _reverser(f):
- def freversed(x):
- return f(1 - x)
- return freversed
-
-
-def revcmap(data):
- """Can only handle specification *data* in dictionary format."""
- data_r = {}
- for key, val in six.iteritems(data):
- if callable(val):
- valnew = _reverser(val)
- # This doesn't work: lambda x: val(1-x)
- # The same "val" (the first one) is used
- # each time, so the colors are identical
- # and the result is shades of gray.
- else:
- # Flip x and exchange the y values facing x = 0 and x = 1.
- valnew = [(1.0 - x, y1, y0) for x, y0, y1 in reversed(val)]
- data_r[key] = valnew
- return data_r
-
-
-def _reverse_cmap_spec(spec):
- """Reverses cmap specification *spec*, can handle both dict and tuple
- type specs."""
-
- if 'listed' in spec:
- return {'listed': spec['listed'][::-1]}
-
- if 'red' in spec:
- return revcmap(spec)
- else:
- revspec = list(reversed(spec))
- if len(revspec[0]) == 2: # e.g., (1, (1.0, 0.0, 1.0))
- revspec = [(1.0 - a, b) for a, b in revspec]
- return revspec
-
-
-def _generate_cmap(name, lutsize):
- """Generates the requested cmap from its *name*. The lut size is
- *lutsize*."""
-
- spec = datad[name]
-
- # Generate the colormap object.
- if 'red' in spec:
- return colors.LinearSegmentedColormap(name, spec, lutsize)
- elif 'listed' in spec:
- return colors.ListedColormap(spec['listed'], name)
- else:
- return colors.LinearSegmentedColormap.from_list(name, spec, lutsize)
-
-LUTSIZE = mpl.rcParams['image.lut']
-
-# Generate the reversed specifications (all at once, to avoid
-# modify-when-iterating).
-datad.update({cmapname + '_r': _reverse_cmap_spec(spec)
- for cmapname, spec in six.iteritems(datad)})
-
-# Precache the cmaps with ``lutsize = LUTSIZE``.
-# Also add the reversed ones added in the section above:
-for cmapname in datad:
- cmap_d[cmapname] = _generate_cmap(cmapname, LUTSIZE)
-
-cmap_d.update(cmaps_listed)
-
-locals().update(cmap_d)
-
-
-# Continue with definitions ...
-
-
-def register_cmap(name=None, cmap=None, data=None, lut=None):
- """
- Add a colormap to the set recognized by :func:`get_cmap`.
-
- It can be used in two ways::
-
- register_cmap(name='swirly', cmap=swirly_cmap)
-
- register_cmap(name='choppy', data=choppydata, lut=128)
-
- In the first case, *cmap* must be a :class:`matplotlib.colors.Colormap`
- instance. The *name* is optional; if absent, the name will
- be the :attr:`~matplotlib.colors.Colormap.name` attribute of the *cmap*.
-
- In the second case, the three arguments are passed to
- the :class:`~matplotlib.colors.LinearSegmentedColormap` initializer,
- and the resulting colormap is registered.
-
- """
- if name is None:
- try:
- name = cmap.name
- except AttributeError:
- raise ValueError("Arguments must include a name or a Colormap")
-
- if not isinstance(name, six.string_types):
- raise ValueError("Colormap name must be a string")
-
- if isinstance(cmap, colors.Colormap):
- cmap_d[name] = cmap
- return
-
- # For the remainder, let exceptions propagate.
- if lut is None:
- lut = mpl.rcParams['image.lut']
- cmap = colors.LinearSegmentedColormap(name, data, lut)
- cmap_d[name] = cmap
-
-
-def get_cmap(name=None, lut=None):
- """
- Get a colormap instance, defaulting to rc values if *name* is None.
-
- Colormaps added with :func:`register_cmap` take precedence over
- built-in colormaps.
-
- If *name* is a :class:`matplotlib.colors.Colormap` instance, it will be
- returned.
-
- If *lut* is not None it must be an integer giving the number of
- entries desired in the lookup table, and *name* must be a standard
- mpl colormap name.
- """
- if name is None:
- name = mpl.rcParams['image.cmap']
-
- if isinstance(name, colors.Colormap):
- return name
-
- if name in cmap_d:
- if lut is None:
- return cmap_d[name]
- else:
- return cmap_d[name]._resample(lut)
- else:
- raise ValueError(
- "Colormap %s is not recognized. Possible values are: %s"
- % (name, ', '.join(sorted(cmap_d))))
-
-
-class ScalarMappable(object):
- """
- This is a mixin class to support scalar data to RGBA mapping.
- The ScalarMappable makes use of data normalization before returning
- RGBA colors from the given colormap.
-
- """
- def __init__(self, norm=None, cmap=None):
- r"""
-
- Parameters
- ----------
- norm : :class:`matplotlib.colors.Normalize` instance
- The normalizing object which scales data, typically into the
- interval ``[0, 1]``.
- If *None*, *norm* defaults to a *colors.Normalize* object which
- initializes its scaling based on the first data processed.
- cmap : str or :class:`~matplotlib.colors.Colormap` instance
- The colormap used to map normalized data values to RGBA colors.
- """
-
- self.callbacksSM = cbook.CallbackRegistry()
-
- if cmap is None:
- cmap = get_cmap()
- if norm is None:
- norm = colors.Normalize()
-
- self._A = None
- #: The Normalization instance of this ScalarMappable.
- self.norm = norm
- #: The Colormap instance of this ScalarMappable.
- self.cmap = get_cmap(cmap)
- #: The last colorbar associated with this ScalarMappable. May be None.
- self.colorbar = None
- self.update_dict = {'array': False}
-
- def to_rgba(self, x, alpha=None, bytes=False, norm=True):
- """
- Return a normalized rgba array corresponding to *x*.
-
- In the normal case, *x* is a 1-D or 2-D sequence of scalars, and
- the corresponding ndarray of rgba values will be returned,
- based on the norm and colormap set for this ScalarMappable.
-
- There is one special case, for handling images that are already
- rgb or rgba, such as might have been read from an image file.
- If *x* is an ndarray with 3 dimensions,
- and the last dimension is either 3 or 4, then it will be
- treated as an rgb or rgba array, and no mapping will be done.
- The array can be uint8, or it can be floating point with
- values in the 0-1 range; otherwise a ValueError will be raised.
- If it is a masked array, the mask will be ignored.
- If the last dimension is 3, the *alpha* kwarg (defaulting to 1)
- will be used to fill in the transparency. If the last dimension
- is 4, the *alpha* kwarg is ignored; it does not
- replace the pre-existing alpha. A ValueError will be raised
- if the third dimension is other than 3 or 4.
-
- In either case, if *bytes* is *False* (default), the rgba
- array will be floats in the 0-1 range; if it is *True*,
- the returned rgba array will be uint8 in the 0 to 255 range.
-
- If norm is False, no normalization of the input data is
- performed, and it is assumed to be in the range (0-1).
-
- """
- # First check for special case, image input:
- try:
- if x.ndim == 3:
- if x.shape[2] == 3:
- if alpha is None:
- alpha = 1
- if x.dtype == np.uint8:
- alpha = np.uint8(alpha * 255)
- m, n = x.shape[:2]
- xx = np.empty(shape=(m, n, 4), dtype=x.dtype)
- xx[:, :, :3] = x
- xx[:, :, 3] = alpha
- elif x.shape[2] == 4:
- xx = x
- else:
- raise ValueError("third dimension must be 3 or 4")
- if xx.dtype.kind == 'f':
- if norm and (xx.max() > 1 or xx.min() < 0):
- raise ValueError("Floating point image RGB values "
- "must be in the 0..1 range.")
- if bytes:
- xx = (xx * 255).astype(np.uint8)
- elif xx.dtype == np.uint8:
- if not bytes:
- xx = xx.astype(np.float32) / 255
- else:
- raise ValueError("Image RGB array must be uint8 or "
- "floating point; found %s" % xx.dtype)
- return xx
- except AttributeError:
- # e.g., x is not an ndarray; so try mapping it
- pass
-
- # This is the normal case, mapping a scalar array:
- x = ma.asarray(x)
- if norm:
- x = self.norm(x)
- rgba = self.cmap(x, alpha=alpha, bytes=bytes)
- return rgba
-
- def set_array(self, A):
- """Set the image array from numpy array *A*.
-
- .. ACCEPTS: ndarray
-
- Parameters
- ----------
- A : ndarray
- """
- self._A = A
- self.update_dict['array'] = True
-
- def get_array(self):
- 'Return the array'
- return self._A
-
- def get_cmap(self):
- 'return the colormap'
- return self.cmap
-
- def get_clim(self):
- 'return the min, max of the color limits for image scaling'
- return self.norm.vmin, self.norm.vmax
-
- def set_clim(self, vmin=None, vmax=None):
- """
- set the norm limits for image scaling; if *vmin* is a length2
- sequence, interpret it as ``(vmin, vmax)`` which is used to
- support setp
-
- ACCEPTS: a length 2 sequence of floats; may be overridden in methods
- that have ``vmin`` and ``vmax`` kwargs.
- """
- if vmax is None:
- try:
- vmin, vmax = vmin
- except (TypeError, ValueError):
- pass
- if vmin is not None:
- self.norm.vmin = colors._sanitize_extrema(vmin)
- if vmax is not None:
- self.norm.vmax = colors._sanitize_extrema(vmax)
- self.changed()
-
- def set_cmap(self, cmap):
- """
- set the colormap for luminance data
-
- ACCEPTS: a colormap or registered colormap name
- """
- cmap = get_cmap(cmap)
- self.cmap = cmap
- self.changed()
-
- def set_norm(self, norm):
- """Set the normalization instance.
-
- .. ACCEPTS: `.Normalize`
-
- Parameters
- ----------
- norm : `.Normalize`
- """
- if norm is None:
- norm = colors.Normalize()
- self.norm = norm
- self.changed()
-
- def autoscale(self):
- """
- Autoscale the scalar limits on the norm instance using the
- current array
- """
- if self._A is None:
- raise TypeError('You must first set_array for mappable')
- self.norm.autoscale(self._A)
- self.changed()
-
- def autoscale_None(self):
- """
- Autoscale the scalar limits on the norm instance using the
- current array, changing only limits that are None
- """
- if self._A is None:
- raise TypeError('You must first set_array for mappable')
- self.norm.autoscale_None(self._A)
- self.changed()
-
- def add_checker(self, checker):
- """
- Add an entry to a dictionary of boolean flags
- that are set to True when the mappable is changed.
- """
- self.update_dict[checker] = False
-
- def check_update(self, checker):
- """
- If mappable has changed since the last check,
- return True; else return False
- """
- if self.update_dict[checker]:
- self.update_dict[checker] = False
- return True
- return False
-
- def changed(self):
- """
- Call this whenever the mappable is changed to notify all the
- callbackSM listeners to the 'changed' signal
- """
- self.callbacksSM.process('changed', self)
-
- for key in self.update_dict:
- self.update_dict[key] = True
- self.stale = True
diff --git a/contrib/python/matplotlib/py2/matplotlib/collections.py b/contrib/python/matplotlib/py2/matplotlib/collections.py
deleted file mode 100644
index 9e124cdf47..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/collections.py
+++ /dev/null
@@ -1,1994 +0,0 @@
-"""
-Classes for the efficient drawing of large collections of objects that
-share most properties, e.g., a large number of line segments or
-polygons.
-
-The classes are not meant to be as flexible as their single element
-counterparts (e.g., you may not be able to select all line styles) but
-they are meant to be fast for common use cases (e.g., a large set of solid
-line segemnts)
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import warnings
-
-import six
-from six.moves import zip
-try:
- from math import gcd
-except ImportError:
- # LPy workaround
- from fractions import gcd
-
-import numpy as np
-import matplotlib as mpl
-from . import (_path, artist, cbook, cm, colors as mcolors, docstring,
- lines as mlines, path as mpath, transforms)
-
-CIRCLE_AREA_FACTOR = 1.0 / np.sqrt(np.pi)
-
-
-_color_aliases = {'facecolors': ['facecolor'],
- 'edgecolors': ['edgecolor']}
-
-
-class Collection(artist.Artist, cm.ScalarMappable):
- """
- Base class for Collections. Must be subclassed to be usable.
-
- All properties in a collection must be sequences or scalars;
- if scalars, they will be converted to sequences. The
- property of the ith element of the collection is::
-
- prop[i % len(props)]
-
- Exceptions are *capstyle* and *joinstyle* properties, these can
- only be set globally for the whole collection.
-
- Keyword arguments and default values:
-
- * *edgecolors*: None
- * *facecolors*: None
- * *linewidths*: None
- * *capstyle*: None
- * *joinstyle*: None
- * *antialiaseds*: None
- * *offsets*: None
- * *transOffset*: transforms.IdentityTransform()
- * *offset_position*: 'screen' (default) or 'data'
- * *norm*: None (optional for
- :class:`matplotlib.cm.ScalarMappable`)
- * *cmap*: None (optional for
- :class:`matplotlib.cm.ScalarMappable`)
- * *hatch*: None
- * *zorder*: 1
-
-
- *offsets* and *transOffset* are used to translate the patch after
- rendering (default no offsets). If offset_position is 'screen'
- (default) the offset is applied after the master transform has
- been applied, that is, the offsets are in screen coordinates. If
- offset_position is 'data', the offset is applied before the master
- transform, i.e., the offsets are in data coordinates.
-
- If any of *edgecolors*, *facecolors*, *linewidths*, *antialiaseds*
- are None, they default to their :data:`matplotlib.rcParams` patch
- setting, in sequence form.
-
- The use of :class:`~matplotlib.cm.ScalarMappable` is optional. If
- the :class:`~matplotlib.cm.ScalarMappable` matrix _A is not None
- (i.e., a call to set_array has been made), at draw time a call to
- scalar mappable will be made to set the face colors.
- """
- _offsets = np.zeros((0, 2))
- _transOffset = transforms.IdentityTransform()
- #: Either a list of 3x3 arrays or an Nx3x3 array of transforms, suitable
- #: for the `all_transforms` argument to
- #: :meth:`~matplotlib.backend_bases.RendererBase.draw_path_collection`;
- #: each 3x3 array is used to initialize an
- #: :class:`~matplotlib.transforms.Affine2D` object.
- #: Each kind of collection defines this based on its arguments.
- _transforms = np.empty((0, 3, 3))
-
- # Whether to draw an edge by default. Set on a
- # subclass-by-subclass basis.
- _edge_default = False
-
- def __init__(self,
- edgecolors=None,
- facecolors=None,
- linewidths=None,
- linestyles='solid',
- capstyle=None,
- joinstyle=None,
- antialiaseds=None,
- offsets=None,
- transOffset=None,
- norm=None, # optional for ScalarMappable
- cmap=None, # ditto
- pickradius=5.0,
- hatch=None,
- urls=None,
- offset_position='screen',
- zorder=1,
- **kwargs
- ):
- """
- Create a Collection
-
- %(Collection)s
- """
- artist.Artist.__init__(self)
- cm.ScalarMappable.__init__(self, norm, cmap)
- # list of un-scaled dash patterns
- # this is needed scaling the dash pattern by linewidth
- self._us_linestyles = [(None, None)]
- # list of dash patterns
- self._linestyles = [(None, None)]
- # list of unbroadcast/scaled linewidths
- self._us_lw = [0]
- self._linewidths = [0]
- self._is_filled = True # May be modified by set_facecolor().
-
- self._hatch_color = mcolors.to_rgba(mpl.rcParams['hatch.color'])
- self.set_facecolor(facecolors)
- self.set_edgecolor(edgecolors)
- self.set_linewidth(linewidths)
- self.set_linestyle(linestyles)
- self.set_antialiased(antialiaseds)
- self.set_pickradius(pickradius)
- self.set_urls(urls)
- self.set_hatch(hatch)
- self.set_offset_position(offset_position)
- self.set_zorder(zorder)
-
- if capstyle:
- self.set_capstyle(capstyle)
- else:
- self._capstyle = None
-
- if joinstyle:
- self.set_joinstyle(joinstyle)
- else:
- self._joinstyle = None
-
- self._offsets = np.zeros((1, 2))
- self._uniform_offsets = None
- if offsets is not None:
- offsets = np.asanyarray(offsets, float)
- # Broadcast (2,) -> (1, 2) but nothing else.
- if offsets.shape == (2,):
- offsets = offsets[None, :]
- if transOffset is not None:
- self._offsets = offsets
- self._transOffset = transOffset
- else:
- self._uniform_offsets = offsets
-
- self._path_effects = None
- self.update(kwargs)
- self._paths = None
-
- def get_paths(self):
- return self._paths
-
- def set_paths(self):
- raise NotImplementedError
-
- def get_transforms(self):
- return self._transforms
-
- def get_offset_transform(self):
- t = self._transOffset
- if (not isinstance(t, transforms.Transform)
- and hasattr(t, '_as_mpl_transform')):
- t = t._as_mpl_transform(self.axes)
- return t
-
- def get_datalim(self, transData):
- transform = self.get_transform()
- transOffset = self.get_offset_transform()
- offsets = self._offsets
- paths = self.get_paths()
-
- if not transform.is_affine:
- paths = [transform.transform_path_non_affine(p) for p in paths]
- transform = transform.get_affine()
- if not transOffset.is_affine:
- offsets = transOffset.transform_non_affine(offsets)
- transOffset = transOffset.get_affine()
-
- if isinstance(offsets, np.ma.MaskedArray):
- offsets = offsets.filled(np.nan)
- # get_path_collection_extents handles nan but not masked arrays
-
- if len(paths) and len(offsets):
- result = mpath.get_path_collection_extents(
- transform.frozen(), paths, self.get_transforms(),
- offsets, transOffset.frozen())
- result = result.inverse_transformed(transData)
- else:
- result = transforms.Bbox.null()
- return result
-
- def get_window_extent(self, renderer):
- # TODO:check to ensure that this does not fail for
- # cases other than scatter plot legend
- return self.get_datalim(transforms.IdentityTransform())
-
- def _prepare_points(self):
- """Point prep for drawing and hit testing"""
-
- transform = self.get_transform()
- transOffset = self.get_offset_transform()
- offsets = self._offsets
- paths = self.get_paths()
-
- if self.have_units():
- paths = []
- for path in self.get_paths():
- vertices = path.vertices
- xs, ys = vertices[:, 0], vertices[:, 1]
- xs = self.convert_xunits(xs)
- ys = self.convert_yunits(ys)
- paths.append(mpath.Path(np.column_stack([xs, ys]), path.codes))
-
- if offsets.size > 0:
- xs = self.convert_xunits(offsets[:, 0])
- ys = self.convert_yunits(offsets[:, 1])
- offsets = np.column_stack([xs, ys])
-
- if not transform.is_affine:
- paths = [transform.transform_path_non_affine(path)
- for path in paths]
- transform = transform.get_affine()
- if not transOffset.is_affine:
- offsets = transOffset.transform_non_affine(offsets)
- # This might have changed an ndarray into a masked array.
- transOffset = transOffset.get_affine()
-
- if isinstance(offsets, np.ma.MaskedArray):
- offsets = offsets.filled(np.nan)
- # Changing from a masked array to nan-filled ndarray
- # is probably most efficient at this point.
-
- return transform, transOffset, offsets, paths
-
- @artist.allow_rasterization
- def draw(self, renderer):
- if not self.get_visible():
- return
- renderer.open_group(self.__class__.__name__, self.get_gid())
-
- self.update_scalarmappable()
-
- transform, transOffset, offsets, paths = self._prepare_points()
-
- gc = renderer.new_gc()
- self._set_gc_clip(gc)
- gc.set_snap(self.get_snap())
-
- if self._hatch:
- gc.set_hatch(self._hatch)
- try:
- gc.set_hatch_color(self._hatch_color)
- except AttributeError:
- # if we end up with a GC that does not have this method
- warnings.warn("Your backend does not support setting the "
- "hatch color.")
-
- if self.get_sketch_params() is not None:
- gc.set_sketch_params(*self.get_sketch_params())
-
- if self.get_path_effects():
- from matplotlib.patheffects import PathEffectRenderer
- renderer = PathEffectRenderer(self.get_path_effects(), renderer)
-
- # If the collection is made up of a single shape/color/stroke,
- # it can be rendered once and blitted multiple times, using
- # `draw_markers` rather than `draw_path_collection`. This is
- # *much* faster for Agg, and results in smaller file sizes in
- # PDF/SVG/PS.
-
- trans = self.get_transforms()
- facecolors = self.get_facecolor()
- edgecolors = self.get_edgecolor()
- do_single_path_optimization = False
- if (len(paths) == 1 and len(trans) <= 1 and
- len(facecolors) == 1 and len(edgecolors) == 1 and
- len(self._linewidths) == 1 and
- self._linestyles == [(None, None)] and
- len(self._antialiaseds) == 1 and len(self._urls) == 1 and
- self.get_hatch() is None):
- if len(trans):
- combined_transform = (transforms.Affine2D(trans[0]) +
- transform)
- else:
- combined_transform = transform
- extents = paths[0].get_extents(combined_transform)
- width, height = renderer.get_canvas_width_height()
- if (extents.width < width and
- extents.height < height):
- do_single_path_optimization = True
-
- if self._joinstyle:
- gc.set_joinstyle(self._joinstyle)
-
- if self._capstyle:
- gc.set_capstyle(self._capstyle)
-
- if do_single_path_optimization:
- gc.set_foreground(tuple(edgecolors[0]))
- gc.set_linewidth(self._linewidths[0])
- gc.set_dashes(*self._linestyles[0])
- gc.set_antialiased(self._antialiaseds[0])
- gc.set_url(self._urls[0])
- renderer.draw_markers(
- gc, paths[0], combined_transform.frozen(),
- mpath.Path(offsets), transOffset, tuple(facecolors[0]))
- else:
- renderer.draw_path_collection(
- gc, transform.frozen(), paths,
- self.get_transforms(), offsets, transOffset,
- self.get_facecolor(), self.get_edgecolor(),
- self._linewidths, self._linestyles,
- self._antialiaseds, self._urls,
- self._offset_position)
-
- gc.restore()
- renderer.close_group(self.__class__.__name__)
- self.stale = False
-
- def set_pickradius(self, pr):
- """Set the pick radius used for containment tests.
-
- .. ACCEPTS: float distance in points
-
- Parameters
- ----------
- d : float
- Pick radius, in points.
- """
- self._pickradius = pr
-
- def get_pickradius(self):
- return self._pickradius
-
- def contains(self, mouseevent):
- """
- Test whether the mouse event occurred in the collection.
-
- Returns True | False, ``dict(ind=itemlist)``, where every
- item in itemlist contains the event.
- """
- if callable(self._contains):
- return self._contains(self, mouseevent)
-
- if not self.get_visible():
- return False, {}
-
- pickradius = (
- float(self._picker)
- if cbook.is_numlike(self._picker) and
- self._picker is not True # the bool, not just nonzero or 1
- else self._pickradius)
-
- transform, transOffset, offsets, paths = self._prepare_points()
-
- ind = _path.point_in_path_collection(
- mouseevent.x, mouseevent.y, pickradius,
- transform.frozen(), paths, self.get_transforms(),
- offsets, transOffset, pickradius <= 0,
- self.get_offset_position())
-
- return len(ind) > 0, dict(ind=ind)
-
- def set_urls(self, urls):
- """
- Parameters
- ----------
- urls : List[str] or None
- .. ACCEPTS: List[str] or None
- """
- self._urls = urls if urls is not None else [None]
- self.stale = True
-
- def get_urls(self):
- return self._urls
-
- def set_hatch(self, hatch):
- r"""
- Set the hatching pattern
-
- *hatch* can be one of::
-
- / - diagonal hatching
- \ - back diagonal
- | - vertical
- - - horizontal
- + - crossed
- x - crossed diagonal
- o - small circle
- O - large circle
- . - dots
- * - stars
-
- Letters can be combined, in which case all the specified
- hatchings are done. If same letter repeats, it increases the
- density of hatching of that pattern.
-
- Hatching is supported in the PostScript, PDF, SVG and Agg
- backends only.
-
- Unlike other properties such as linewidth and colors, hatching
- can only be specified for the collection as a whole, not separately
- for each member.
-
- ACCEPTS: [ '/' | '\\' | '|' | '-' | '+' | 'x' | 'o' | 'O' | '.' | '*' ]
- """
- self._hatch = hatch
- self.stale = True
-
- def get_hatch(self):
- """Return the current hatching pattern."""
- return self._hatch
-
- def set_offsets(self, offsets):
- """
- Set the offsets for the collection. *offsets* can be a scalar
- or a sequence.
-
- ACCEPTS: float or sequence of floats
- """
- offsets = np.asanyarray(offsets, float)
- if offsets.shape == (2,): # Broadcast (2,) -> (1, 2) but nothing else.
- offsets = offsets[None, :]
- # This decision is based on how they are initialized above in __init__.
- if self._uniform_offsets is None:
- self._offsets = offsets
- else:
- self._uniform_offsets = offsets
- self.stale = True
-
- def get_offsets(self):
- """Return the offsets for the collection."""
- # This decision is based on how they are initialized above in __init__.
- if self._uniform_offsets is None:
- return self._offsets
- else:
- return self._uniform_offsets
-
- def set_offset_position(self, offset_position):
- """
- Set how offsets are applied. If *offset_position* is 'screen'
- (default) the offset is applied after the master transform has
- been applied, that is, the offsets are in screen coordinates.
- If offset_position is 'data', the offset is applied before the
- master transform, i.e., the offsets are in data coordinates.
-
- .. ACCEPTS: [ 'screen' | 'data' ]
- """
- if offset_position not in ('screen', 'data'):
- raise ValueError("offset_position must be 'screen' or 'data'")
- self._offset_position = offset_position
- self.stale = True
-
- def get_offset_position(self):
- """
- Returns how offsets are applied for the collection. If
- *offset_position* is 'screen', the offset is applied after the
- master transform has been applied, that is, the offsets are in
- screen coordinates. If offset_position is 'data', the offset
- is applied before the master transform, i.e., the offsets are
- in data coordinates.
- """
- return self._offset_position
-
- def set_linewidth(self, lw):
- """
- Set the linewidth(s) for the collection. *lw* can be a scalar
- or a sequence; if it is a sequence the patches will cycle
- through the sequence
-
- ACCEPTS: float or sequence of floats
- """
- if lw is None:
- lw = mpl.rcParams['patch.linewidth']
- if lw is None:
- lw = mpl.rcParams['lines.linewidth']
- # get the un-scaled/broadcast lw
- self._us_lw = np.atleast_1d(np.asarray(lw))
-
- # scale all of the dash patterns.
- self._linewidths, self._linestyles = self._bcast_lwls(
- self._us_lw, self._us_linestyles)
- self.stale = True
-
- def set_linewidths(self, lw):
- """alias for set_linewidth"""
- return self.set_linewidth(lw)
-
- def set_lw(self, lw):
- """alias for set_linewidth"""
- return self.set_linewidth(lw)
-
- def set_linestyle(self, ls):
- """
- Set the linestyle(s) for the collection.
-
- =========================== =================
- linestyle description
- =========================== =================
- ``'-'`` or ``'solid'`` solid line
- ``'--'`` or ``'dashed'`` dashed line
- ``'-.'`` or ``'dashdot'`` dash-dotted line
- ``':'`` or ``'dotted'`` dotted line
- =========================== =================
-
- Alternatively a dash tuple of the following form can be provided::
-
- (offset, onoffseq),
-
- where ``onoffseq`` is an even length tuple of on and off ink
- in points.
-
- ACCEPTS: ['solid' | 'dashed', 'dashdot', 'dotted' |
- (offset, on-off-dash-seq) |
- ``'-'`` | ``'--'`` | ``'-.'`` | ``':'`` | ``'None'`` |
- ``' '`` | ``''``]
-
- Parameters
- ----------
- ls : { '-', '--', '-.', ':'} and more see description
- The line style.
- """
- try:
- if isinstance(ls, six.string_types):
- ls = cbook.ls_mapper.get(ls, ls)
- dashes = [mlines._get_dash_pattern(ls)]
- else:
- try:
- dashes = [mlines._get_dash_pattern(ls)]
- except ValueError:
- dashes = [mlines._get_dash_pattern(x) for x in ls]
-
- except ValueError:
- raise ValueError(
- 'Do not know how to convert {!r} to dashes'.format(ls))
-
- # get the list of raw 'unscaled' dash patterns
- self._us_linestyles = dashes
-
- # broadcast and scale the lw and dash patterns
- self._linewidths, self._linestyles = self._bcast_lwls(
- self._us_lw, self._us_linestyles)
-
- def set_capstyle(self, cs):
- """
- Set the capstyle for the collection. The capstyle can
- only be set globally for all elements in the collection
-
- Parameters
- ----------
- cs : ['butt' | 'round' | 'projecting']
- The capstyle
- """
- if cs in ('butt', 'round', 'projecting'):
- self._capstyle = cs
- else:
- raise ValueError('Unrecognized cap style. Found %s' % cs)
-
- def get_capstyle(self):
- return self._capstyle
-
- def set_joinstyle(self, js):
- """
- Set the joinstyle for the collection. The joinstyle can only be
- set globally for all elements in the collection.
-
- Parameters
- ----------
- js : ['miter' | 'round' | 'bevel']
- The joinstyle
- """
- if js in ('miter', 'round', 'bevel'):
- self._joinstyle = js
- else:
- raise ValueError('Unrecognized join style. Found %s' % js)
-
- def get_joinstyle(self):
- return self._joinstyle
-
- @staticmethod
- def _bcast_lwls(linewidths, dashes):
- '''Internal helper function to broadcast + scale ls/lw
-
- In the collection drawing code the linewidth and linestyle are
- cycled through as circular buffers (via v[i % len(v)]). Thus,
- if we are going to scale the dash pattern at set time (not
- draw time) we need to do the broadcasting now and expand both
- lists to be the same length.
-
- Parameters
- ----------
- linewidths : list
- line widths of collection
-
- dashes : list
- dash specification (offset, (dash pattern tuple))
-
- Returns
- -------
- linewidths, dashes : list
- Will be the same length, dashes are scaled by paired linewidth
-
- '''
- if mpl.rcParams['_internal.classic_mode']:
- return linewidths, dashes
- # make sure they are the same length so we can zip them
- if len(dashes) != len(linewidths):
- l_dashes = len(dashes)
- l_lw = len(linewidths)
- GCD = gcd(l_dashes, l_lw)
- dashes = list(dashes) * (l_lw // GCD)
- linewidths = list(linewidths) * (l_dashes // GCD)
-
- # scale the dash patters
- dashes = [mlines._scale_dashes(o, d, lw)
- for (o, d), lw in zip(dashes, linewidths)]
-
- return linewidths, dashes
-
- def set_linestyles(self, ls):
- """alias for set_linestyle"""
- return self.set_linestyle(ls)
-
- def set_dashes(self, ls):
- """alias for set_linestyle"""
- return self.set_linestyle(ls)
-
- def set_antialiased(self, aa):
- """
- Set the antialiasing state for rendering.
-
- ACCEPTS: Boolean or sequence of booleans
- """
- if aa is None:
- aa = mpl.rcParams['patch.antialiased']
- self._antialiaseds = np.atleast_1d(np.asarray(aa, bool))
- self.stale = True
-
- def set_antialiaseds(self, aa):
- """alias for set_antialiased"""
- return self.set_antialiased(aa)
-
- def set_color(self, c):
- """
- Set both the edgecolor and the facecolor.
-
- ACCEPTS: matplotlib color arg or sequence of rgba tuples
-
- .. seealso::
-
- :meth:`set_facecolor`, :meth:`set_edgecolor`
- For setting the edge or face color individually.
- """
- self.set_facecolor(c)
- self.set_edgecolor(c)
-
- def _set_facecolor(self, c):
- if c is None:
- c = mpl.rcParams['patch.facecolor']
-
- self._is_filled = True
- try:
- if c.lower() == 'none':
- self._is_filled = False
- except AttributeError:
- pass
- self._facecolors = mcolors.to_rgba_array(c, self._alpha)
- self.stale = True
-
- def set_facecolor(self, c):
- """
- Set the facecolor(s) of the collection. *c* can be a
- matplotlib color spec (all patches have same color), or a
- sequence of specs; if it is a sequence the patches will
- cycle through the sequence.
-
- If *c* is 'none', the patch will not be filled.
-
- ACCEPTS: matplotlib color spec or sequence of specs
- """
- self._original_facecolor = c
- self._set_facecolor(c)
-
- def set_facecolors(self, c):
- """alias for set_facecolor"""
- return self.set_facecolor(c)
-
- def get_facecolor(self):
- return self._facecolors
- get_facecolors = get_facecolor
-
- def get_edgecolor(self):
- if (isinstance(self._edgecolors, six.string_types)
- and self._edgecolors == str('face')):
- return self.get_facecolors()
- else:
- return self._edgecolors
- get_edgecolors = get_edgecolor
-
- def _set_edgecolor(self, c):
- set_hatch_color = True
- if c is None:
- if (mpl.rcParams['patch.force_edgecolor'] or
- not self._is_filled or self._edge_default):
- c = mpl.rcParams['patch.edgecolor']
- else:
- c = 'none'
- set_hatch_color = False
-
- self._is_stroked = True
- try:
- if c.lower() == 'none':
- self._is_stroked = False
- except AttributeError:
- pass
-
- try:
- if c.lower() == 'face': # Special case: lookup in "get" method.
- self._edgecolors = 'face'
- return
- except AttributeError:
- pass
- self._edgecolors = mcolors.to_rgba_array(c, self._alpha)
- if set_hatch_color and len(self._edgecolors):
- self._hatch_color = tuple(self._edgecolors[0])
- self.stale = True
-
- def set_edgecolor(self, c):
- """
- Set the edgecolor(s) of the collection. *c* can be a
- matplotlib color spec (all patches have same color), or a
- sequence of specs; if it is a sequence the patches will
- cycle through the sequence.
-
- If *c* is 'face', the edge color will always be the same as
- the face color. If it is 'none', the patch boundary will not
- be drawn.
-
- ACCEPTS: matplotlib color spec or sequence of specs
- """
- self._original_edgecolor = c
- self._set_edgecolor(c)
-
- def set_edgecolors(self, c):
- """alias for set_edgecolor"""
- return self.set_edgecolor(c)
-
- def set_alpha(self, alpha):
- """
- Set the alpha tranparencies of the collection. *alpha* must be
- a float or *None*.
-
- ACCEPTS: float or None
- """
- if alpha is not None:
- try:
- float(alpha)
- except TypeError:
- raise TypeError('alpha must be a float or None')
- self.update_dict['array'] = True
- artist.Artist.set_alpha(self, alpha)
- self._set_facecolor(self._original_facecolor)
- self._set_edgecolor(self._original_edgecolor)
-
- def get_linewidths(self):
- return self._linewidths
- get_linewidth = get_linewidths
-
- def get_linestyles(self):
- return self._linestyles
- get_dashes = get_linestyle = get_linestyles
-
- def update_scalarmappable(self):
- """
- If the scalar mappable array is not none, update colors
- from scalar data
- """
- if self._A is None:
- return
- if self._A.ndim > 1:
- raise ValueError('Collections can only map rank 1 arrays')
- if not self.check_update("array"):
- return
- if self._is_filled:
- self._facecolors = self.to_rgba(self._A, self._alpha)
- elif self._is_stroked:
- self._edgecolors = self.to_rgba(self._A, self._alpha)
- self.stale = True
-
- def get_fill(self):
- 'return whether fill is set'
- return self._is_filled
-
- def update_from(self, other):
- 'copy properties from other to self'
-
- artist.Artist.update_from(self, other)
- self._antialiaseds = other._antialiaseds
- self._original_edgecolor = other._original_edgecolor
- self._edgecolors = other._edgecolors
- self._original_facecolor = other._original_facecolor
- self._facecolors = other._facecolors
- self._linewidths = other._linewidths
- self._linestyles = other._linestyles
- self._us_linestyles = other._us_linestyles
- self._pickradius = other._pickradius
- self._hatch = other._hatch
-
- # update_from for scalarmappable
- self._A = other._A
- self.norm = other.norm
- self.cmap = other.cmap
- # self.update_dict = other.update_dict # do we need to copy this? -JJL
- self.stale = True
-
-# these are not available for the object inspector until after the
-# class is built so we define an initial set here for the init
-# function and they will be overridden after object defn
-docstring.interpd.update(Collection="""\
- Valid Collection keyword arguments:
-
- * *edgecolors*: None
- * *facecolors*: None
- * *linewidths*: None
- * *antialiaseds*: None
- * *offsets*: None
- * *transOffset*: transforms.IdentityTransform()
- * *norm*: None (optional for
- :class:`matplotlib.cm.ScalarMappable`)
- * *cmap*: None (optional for
- :class:`matplotlib.cm.ScalarMappable`)
-
- *offsets* and *transOffset* are used to translate the patch after
- rendering (default no offsets)
-
- If any of *edgecolors*, *facecolors*, *linewidths*, *antialiaseds*
- are None, they default to their :data:`matplotlib.rcParams` patch
- setting, in sequence form.
-""")
-
-
-class _CollectionWithSizes(Collection):
- """
- Base class for collections that have an array of sizes.
- """
- _factor = 1.0
-
- def get_sizes(self):
- """
- Returns the sizes of the elements in the collection. The
- value represents the 'area' of the element.
-
- Returns
- -------
- sizes : array
- The 'area' of each element.
- """
- return self._sizes
-
- def set_sizes(self, sizes, dpi=72.0):
- """
- Set the sizes of each member of the collection.
-
- Parameters
- ----------
- sizes : ndarray or None
- The size to set for each element of the collection. The
- value is the 'area' of the element.
-
- dpi : float
- The dpi of the canvas. Defaults to 72.0.
- """
- if sizes is None:
- self._sizes = np.array([])
- self._transforms = np.empty((0, 3, 3))
- else:
- self._sizes = np.asarray(sizes)
- self._transforms = np.zeros((len(self._sizes), 3, 3))
- scale = np.sqrt(self._sizes) * dpi / 72.0 * self._factor
- self._transforms[:, 0, 0] = scale
- self._transforms[:, 1, 1] = scale
- self._transforms[:, 2, 2] = 1.0
- self.stale = True
-
- @artist.allow_rasterization
- def draw(self, renderer):
- self.set_sizes(self._sizes, self.figure.dpi)
- Collection.draw(self, renderer)
-
-
-class PathCollection(_CollectionWithSizes):
- """
- This is the most basic :class:`Collection` subclass.
- """
- @docstring.dedent_interpd
- def __init__(self, paths, sizes=None, **kwargs):
- """
- *paths* is a sequence of :class:`matplotlib.path.Path`
- instances.
-
- %(Collection)s
- """
-
- Collection.__init__(self, **kwargs)
- self.set_paths(paths)
- self.set_sizes(sizes)
- self.stale = True
-
- def set_paths(self, paths):
- self._paths = paths
- self.stale = True
-
- def get_paths(self):
- return self._paths
-
-
-class PolyCollection(_CollectionWithSizes):
- @docstring.dedent_interpd
- def __init__(self, verts, sizes=None, closed=True, **kwargs):
- """
- *verts* is a sequence of ( *verts0*, *verts1*, ...) where
- *verts_i* is a sequence of *xy* tuples of vertices, or an
- equivalent :mod:`numpy` array of shape (*nv*, 2).
-
- *sizes* is *None* (default) or a sequence of floats that
- scale the corresponding *verts_i*. The scaling is applied
- before the Artist master transform; if the latter is an identity
- transform, then the overall scaling is such that if
- *verts_i* specify a unit square, then *sizes_i* is the area
- of that square in points^2.
- If len(*sizes*) < *nv*, the additional values will be
- taken cyclically from the array.
-
- *closed*, when *True*, will explicitly close the polygon.
-
- %(Collection)s
- """
- Collection.__init__(self, **kwargs)
- self.set_sizes(sizes)
- self.set_verts(verts, closed)
- self.stale = True
-
- def set_verts(self, verts, closed=True):
- '''This allows one to delay initialization of the vertices.'''
- if isinstance(verts, np.ma.MaskedArray):
- verts = verts.astype(float).filled(np.nan)
- # This is much faster than having Path do it one at a time.
- if closed:
- self._paths = []
- for xy in verts:
- if len(xy):
- if isinstance(xy, np.ma.MaskedArray):
- xy = np.ma.concatenate([xy, xy[0:1]])
- else:
- xy = np.asarray(xy)
- xy = np.concatenate([xy, xy[0:1]])
- codes = np.empty(xy.shape[0], dtype=mpath.Path.code_type)
- codes[:] = mpath.Path.LINETO
- codes[0] = mpath.Path.MOVETO
- codes[-1] = mpath.Path.CLOSEPOLY
- self._paths.append(mpath.Path(xy, codes))
- else:
- self._paths.append(mpath.Path(xy))
- else:
- self._paths = [mpath.Path(xy) for xy in verts]
- self.stale = True
-
- set_paths = set_verts
-
- def set_verts_and_codes(self, verts, codes):
- '''This allows one to initialize vertices with path codes.'''
- if (len(verts) != len(codes)):
- raise ValueError("'codes' must be a 1D list or array "
- "with the same length of 'verts'")
- self._paths = []
- for xy, cds in zip(verts, codes):
- if len(xy):
- self._paths.append(mpath.Path(xy, cds))
- else:
- self._paths.append(mpath.Path(xy))
- self.stale = True
-
-
-class BrokenBarHCollection(PolyCollection):
- """
- A collection of horizontal bars spanning *yrange* with a sequence of
- *xranges*.
- """
- @docstring.dedent_interpd
- def __init__(self, xranges, yrange, **kwargs):
- """
- *xranges*
- sequence of (*xmin*, *xwidth*)
-
- *yrange*
- *ymin*, *ywidth*
-
- %(Collection)s
- """
- ymin, ywidth = yrange
- ymax = ymin + ywidth
- verts = [[(xmin, ymin),
- (xmin, ymax),
- (xmin + xwidth, ymax),
- (xmin + xwidth, ymin),
- (xmin, ymin)] for xmin, xwidth in xranges]
- PolyCollection.__init__(self, verts, **kwargs)
-
- @staticmethod
- def span_where(x, ymin, ymax, where, **kwargs):
- """
- Create a BrokenBarHCollection to plot horizontal bars from
- over the regions in *x* where *where* is True. The bars range
- on the y-axis from *ymin* to *ymax*
-
- A :class:`BrokenBarHCollection` is returned. *kwargs* are
- passed on to the collection.
- """
- xranges = []
- for ind0, ind1 in cbook.contiguous_regions(where):
- xslice = x[ind0:ind1]
- if not len(xslice):
- continue
- xranges.append((xslice[0], xslice[-1] - xslice[0]))
-
- collection = BrokenBarHCollection(
- xranges, [ymin, ymax - ymin], **kwargs)
- return collection
-
-
-class RegularPolyCollection(_CollectionWithSizes):
- """Draw a collection of regular polygons with *numsides*."""
- _path_generator = mpath.Path.unit_regular_polygon
-
- _factor = CIRCLE_AREA_FACTOR
-
- @docstring.dedent_interpd
- def __init__(self,
- numsides,
- rotation=0,
- sizes=(1,),
- **kwargs):
- """
- *numsides*
- the number of sides of the polygon
-
- *rotation*
- the rotation of the polygon in radians
-
- *sizes*
- gives the area of the circle circumscribing the
- regular polygon in points^2
-
- %(Collection)s
-
- Example: see :file:`examples/dynamic_collection.py` for
- complete example::
-
- offsets = np.random.rand(20,2)
- facecolors = [cm.jet(x) for x in np.random.rand(20)]
- black = (0,0,0,1)
-
- collection = RegularPolyCollection(
- numsides=5, # a pentagon
- rotation=0, sizes=(50,),
- facecolors = facecolors,
- edgecolors = (black,),
- linewidths = (1,),
- offsets = offsets,
- transOffset = ax.transData,
- )
- """
- Collection.__init__(self, **kwargs)
- self.set_sizes(sizes)
- self._numsides = numsides
- self._paths = [self._path_generator(numsides)]
- self._rotation = rotation
- self.set_transform(transforms.IdentityTransform())
-
- def get_numsides(self):
- return self._numsides
-
- def get_rotation(self):
- return self._rotation
-
- @artist.allow_rasterization
- def draw(self, renderer):
- self.set_sizes(self._sizes, self.figure.dpi)
- self._transforms = [
- transforms.Affine2D(x).rotate(-self._rotation).get_matrix()
- for x in self._transforms
- ]
- Collection.draw(self, renderer)
-
-
-class StarPolygonCollection(RegularPolyCollection):
- """
- Draw a collection of regular stars with *numsides* points."""
-
- _path_generator = mpath.Path.unit_regular_star
-
-
-class AsteriskPolygonCollection(RegularPolyCollection):
- """
- Draw a collection of regular asterisks with *numsides* points."""
-
- _path_generator = mpath.Path.unit_regular_asterisk
-
-
-class LineCollection(Collection):
- """
- All parameters must be sequences or scalars; if scalars, they will
- be converted to sequences. The property of the ith line
- segment is::
-
- prop[i % len(props)]
-
- i.e., the properties cycle if the ``len`` of props is less than the
- number of segments.
- """
-
- _edge_default = True
-
- def __init__(self, segments, # Can be None.
- linewidths=None,
- colors=None,
- antialiaseds=None,
- linestyles='solid',
- offsets=None,
- transOffset=None,
- norm=None,
- cmap=None,
- pickradius=5,
- zorder=2,
- facecolors='none',
- **kwargs
- ):
- """
- Parameters
- ----------
- segments :
- A sequence of (*line0*, *line1*, *line2*), where::
-
- linen = (x0, y0), (x1, y1), ... (xm, ym)
-
- or the equivalent numpy array with two columns. Each line
- can be a different length.
-
- colors : sequence, optional
- A sequence of RGBA tuples (e.g., arbitrary color
- strings, etc, not allowed).
-
- antialiaseds : sequence, optional
- A sequence of ones or zeros.
-
- linestyles : string, tuple, optional
- Either one of [ 'solid' | 'dashed' | 'dashdot' | 'dotted' ], or
- a dash tuple. The dash tuple is::
-
- (offset, onoffseq)
-
- where ``onoffseq`` is an even length tuple of on and off ink
- in points.
-
- norm : Normalize, optional
- `~.colors.Normalize` instance.
-
- cmap : string or Colormap, optional
- Colormap name or `~.colors.Colormap` instance.
-
- pickradius : float, optional
- The tolerance in points for mouse clicks picking a line.
- Default is 5 pt.
-
- zorder : int, optional
- zorder of the LineCollection. Default is 2.
-
- facecolors : optional
- The facecolors of the LineCollection. Default is 'none'.
- Setting to a value other than 'none' will lead to a filled
- polygon being drawn between points on each line.
-
- Notes
- -----
- If *linewidths*, *colors*, or *antialiaseds* is None, they
- default to their rcParams setting, in sequence form.
-
- If *offsets* and *transOffset* are not None, then
- *offsets* are transformed by *transOffset* and applied after
- the segments have been transformed to display coordinates.
-
- If *offsets* is not None but *transOffset* is None, then the
- *offsets* are added to the segments before any transformation.
- In this case, a single offset can be specified as::
-
- offsets=(xo,yo)
-
- and this value will be added cumulatively to each successive
- segment, so as to produce a set of successively offset curves.
-
- The use of :class:`~matplotlib.cm.ScalarMappable` is optional.
- If the :class:`~matplotlib.cm.ScalarMappable` array
- :attr:`~matplotlib.cm.ScalarMappable._A` is not None (i.e., a call to
- :meth:`~matplotlib.cm.ScalarMappable.set_array` has been made), at
- draw time a call to scalar mappable will be made to set the colors.
- """
- if colors is None:
- colors = mpl.rcParams['lines.color']
- if linewidths is None:
- linewidths = (mpl.rcParams['lines.linewidth'],)
- if antialiaseds is None:
- antialiaseds = (mpl.rcParams['lines.antialiased'],)
-
- colors = mcolors.to_rgba_array(colors)
-
- Collection.__init__(
- self,
- edgecolors=colors,
- facecolors=facecolors,
- linewidths=linewidths,
- linestyles=linestyles,
- antialiaseds=antialiaseds,
- offsets=offsets,
- transOffset=transOffset,
- norm=norm,
- cmap=cmap,
- pickradius=pickradius,
- zorder=zorder,
- **kwargs)
-
- self.set_segments(segments)
-
- def set_segments(self, segments):
- if segments is None:
- return
- _segments = []
-
- for seg in segments:
- if not isinstance(seg, np.ma.MaskedArray):
- seg = np.asarray(seg, float)
- _segments.append(seg)
-
- if self._uniform_offsets is not None:
- _segments = self._add_offsets(_segments)
-
- self._paths = [mpath.Path(_seg) for _seg in _segments]
- self.stale = True
-
- set_verts = set_segments # for compatibility with PolyCollection
- set_paths = set_segments
-
- def get_segments(self):
- """
- Returns
- -------
- segments : list
- List of segments in the LineCollection. Each list item contains an
- array of vertices.
- """
- segments = []
-
- for path in self._paths:
- vertices = [vertex for vertex, _ in path.iter_segments()]
- vertices = np.asarray(vertices)
- segments.append(vertices)
-
- return segments
-
- def _add_offsets(self, segs):
- offsets = self._uniform_offsets
- Nsegs = len(segs)
- Noffs = offsets.shape[0]
- if Noffs == 1:
- for i in range(Nsegs):
- segs[i] = segs[i] + i * offsets
- else:
- for i in range(Nsegs):
- io = i % Noffs
- segs[i] = segs[i] + offsets[io:io + 1]
- return segs
-
- def set_color(self, c):
- """
- Set the color(s) of the LineCollection.
-
- Parameters
- ----------
- c :
- Matplotlib color argument (all patches have same color), or a
- sequence or rgba tuples; if it is a sequence the patches will
- cycle through the sequence.
- """
- self.set_edgecolor(c)
- self.stale = True
-
- def get_color(self):
- return self._edgecolors
-
- get_colors = get_color # for compatibility with old versions
-
-
-class EventCollection(LineCollection):
- '''
- A collection of discrete events.
-
- The events are given by a 1-dimensional array, usually the position of
- something along an axis, such as time or length. They do not have an
- amplitude and are displayed as vertical or horizontal parallel bars.
- '''
-
- _edge_default = True
-
- def __init__(self,
- positions, # Cannot be None.
- orientation=None,
- lineoffset=0,
- linelength=1,
- linewidth=None,
- color=None,
- linestyle='solid',
- antialiased=None,
- **kwargs
- ):
- """
- Parameters
- ----------
- positions : 1D array-like object
- Each value is an event.
-
- orientation : {None, 'horizontal', 'vertical'}, optional
- The orientation of the **collection** (the event bars are along
- the orthogonal direction). Defaults to 'horizontal' if not
- specified or None.
-
- lineoffset : scalar, optional, default: 0
- The offset of the center of the markers from the origin, in the
- direction orthogonal to *orientation*.
-
- linelength : scalar, optional, default: 1
- The total height of the marker (i.e. the marker stretches from
- ``lineoffset - linelength/2`` to ``lineoffset + linelength/2``).
-
- linewidth : scalar or None, optional, default: None
- If it is None, defaults to its rcParams setting, in sequence form.
-
- color : color, sequence of colors or None, optional, default: None
- If it is None, defaults to its rcParams setting, in sequence form.
-
- linestyle : str or tuple, optional, default: 'solid'
- Valid strings are ['solid', 'dashed', 'dashdot', 'dotted',
- '-', '--', '-.', ':']. Dash tuples should be of the form::
-
- (offset, onoffseq),
-
- where *onoffseq* is an even length tuple of on and off ink
- in points.
-
- antialiased : {None, 1, 2}, optional
- If it is None, defaults to its rcParams setting, in sequence form.
-
- **kwargs : optional
- Other keyword arguments are line collection properties. See
- :class:`~matplotlib.collections.LineCollection` for a list of
- the valid properties.
-
- Examples
- --------
-
- .. plot:: gallery/lines_bars_and_markers/eventcollection_demo.py
- """
-
- segment = (lineoffset + linelength / 2.,
- lineoffset - linelength / 2.)
- if positions is None or len(positions) == 0:
- segments = []
- elif hasattr(positions, 'ndim') and positions.ndim > 1:
- raise ValueError('positions cannot be an array with more than '
- 'one dimension.')
- elif (orientation is None or orientation.lower() == 'none' or
- orientation.lower() == 'horizontal'):
- positions.sort()
- segments = [[(coord1, coord2) for coord2 in segment] for
- coord1 in positions]
- self._is_horizontal = True
- elif orientation.lower() == 'vertical':
- positions.sort()
- segments = [[(coord2, coord1) for coord2 in segment] for
- coord1 in positions]
- self._is_horizontal = False
- else:
- raise ValueError("orientation must be 'horizontal' or 'vertical'")
-
- LineCollection.__init__(self,
- segments,
- linewidths=linewidth,
- colors=color,
- antialiaseds=antialiased,
- linestyles=linestyle,
- **kwargs)
-
- self._linelength = linelength
- self._lineoffset = lineoffset
-
- def get_positions(self):
- '''
- return an array containing the floating-point values of the positions
- '''
- segments = self.get_segments()
- pos = 0 if self.is_horizontal() else 1
- positions = []
- for segment in segments:
- positions.append(segment[0, pos])
- return positions
-
- def set_positions(self, positions):
- '''
- set the positions of the events to the specified value
- '''
- if positions is None or (hasattr(positions, 'len') and
- len(positions) == 0):
- self.set_segments([])
- return
-
- lineoffset = self.get_lineoffset()
- linelength = self.get_linelength()
- segment = (lineoffset + linelength / 2.,
- lineoffset - linelength / 2.)
- positions = np.asanyarray(positions)
- positions.sort()
- if self.is_horizontal():
- segments = [[(coord1, coord2) for coord2 in segment] for
- coord1 in positions]
- else:
- segments = [[(coord2, coord1) for coord2 in segment] for
- coord1 in positions]
- self.set_segments(segments)
-
- def add_positions(self, position):
- '''
- add one or more events at the specified positions
- '''
- if position is None or (hasattr(position, 'len') and
- len(position) == 0):
- return
- positions = self.get_positions()
- positions = np.hstack([positions, np.asanyarray(position)])
- self.set_positions(positions)
- extend_positions = append_positions = add_positions
-
- def is_horizontal(self):
- '''
- True if the eventcollection is horizontal, False if vertical
- '''
- return self._is_horizontal
-
- def get_orientation(self):
- '''
- get the orientation of the event line, may be:
- [ 'horizontal' | 'vertical' ]
- '''
- return 'horizontal' if self.is_horizontal() else 'vertical'
-
- def switch_orientation(self):
- '''
- switch the orientation of the event line, either from vertical to
- horizontal or vice versus
- '''
- segments = self.get_segments()
- for i, segment in enumerate(segments):
- segments[i] = np.fliplr(segment)
- self.set_segments(segments)
- self._is_horizontal = not self.is_horizontal()
- self.stale = True
-
- def set_orientation(self, orientation=None):
- '''
- set the orientation of the event line
- [ 'horizontal' | 'vertical' | None ]
- defaults to 'horizontal' if not specified or None
- '''
- if (orientation is None or orientation.lower() == 'none' or
- orientation.lower() == 'horizontal'):
- is_horizontal = True
- elif orientation.lower() == 'vertical':
- is_horizontal = False
- else:
- raise ValueError("orientation must be 'horizontal' or 'vertical'")
-
- if is_horizontal == self.is_horizontal():
- return
- self.switch_orientation()
-
- def get_linelength(self):
- '''
- get the length of the lines used to mark each event
- '''
- return self._linelength
-
- def set_linelength(self, linelength):
- '''
- set the length of the lines used to mark each event
- '''
- if linelength == self.get_linelength():
- return
- lineoffset = self.get_lineoffset()
- segments = self.get_segments()
- pos = 1 if self.is_horizontal() else 0
- for segment in segments:
- segment[0, pos] = lineoffset + linelength / 2.
- segment[1, pos] = lineoffset - linelength / 2.
- self.set_segments(segments)
- self._linelength = linelength
-
- def get_lineoffset(self):
- '''
- get the offset of the lines used to mark each event
- '''
- return self._lineoffset
-
- def set_lineoffset(self, lineoffset):
- '''
- set the offset of the lines used to mark each event
- '''
- if lineoffset == self.get_lineoffset():
- return
- linelength = self.get_linelength()
- segments = self.get_segments()
- pos = 1 if self.is_horizontal() else 0
- for segment in segments:
- segment[0, pos] = lineoffset + linelength / 2.
- segment[1, pos] = lineoffset - linelength / 2.
- self.set_segments(segments)
- self._lineoffset = lineoffset
-
- def get_linewidth(self):
- '''
- get the width of the lines used to mark each event
- '''
- return self.get_linewidths()[0]
-
- def get_linestyle(self):
- '''
- get the style of the lines used to mark each event
- [ 'solid' | 'dashed' | 'dashdot' | 'dotted' ]
- '''
- return self.get_linestyles()
-
- def get_color(self):
- '''
- get the color of the lines used to mark each event
- '''
- return self.get_colors()[0]
-
-
-class CircleCollection(_CollectionWithSizes):
- """
- A collection of circles, drawn using splines.
- """
- _factor = CIRCLE_AREA_FACTOR
-
- @docstring.dedent_interpd
- def __init__(self, sizes, **kwargs):
- """
- *sizes*
- Gives the area of the circle in points^2
-
- %(Collection)s
- """
- Collection.__init__(self, **kwargs)
- self.set_sizes(sizes)
- self.set_transform(transforms.IdentityTransform())
- self._paths = [mpath.Path.unit_circle()]
-
-
-class EllipseCollection(Collection):
- """
- A collection of ellipses, drawn using splines.
- """
- @docstring.dedent_interpd
- def __init__(self, widths, heights, angles, units='points', **kwargs):
- """
- *widths*: sequence
- lengths of first axes (e.g., major axis lengths)
-
- *heights*: sequence
- lengths of second axes
-
- *angles*: sequence
- angles of first axes, degrees CCW from the X-axis
-
- *units*: ['points' | 'inches' | 'dots' | 'width' | 'height'
- | 'x' | 'y' | 'xy']
-
- units in which majors and minors are given; 'width' and
- 'height' refer to the dimensions of the axes, while 'x'
- and 'y' refer to the *offsets* data units. 'xy' differs
- from all others in that the angle as plotted varies with
- the aspect ratio, and equals the specified angle only when
- the aspect ratio is unity. Hence it behaves the same as
- the :class:`~matplotlib.patches.Ellipse` with
- axes.transData as its transform.
-
- Additional kwargs inherited from the base :class:`Collection`:
-
- %(Collection)s
- """
- Collection.__init__(self, **kwargs)
- self._widths = 0.5 * np.asarray(widths).ravel()
- self._heights = 0.5 * np.asarray(heights).ravel()
- self._angles = np.deg2rad(angles).ravel()
- self._units = units
- self.set_transform(transforms.IdentityTransform())
- self._transforms = np.empty((0, 3, 3))
- self._paths = [mpath.Path.unit_circle()]
-
- def _set_transforms(self):
- """
- Calculate transforms immediately before drawing.
- """
- ax = self.axes
- fig = self.figure
-
- if self._units == 'xy':
- sc = 1
- elif self._units == 'x':
- sc = ax.bbox.width / ax.viewLim.width
- elif self._units == 'y':
- sc = ax.bbox.height / ax.viewLim.height
- elif self._units == 'inches':
- sc = fig.dpi
- elif self._units == 'points':
- sc = fig.dpi / 72.0
- elif self._units == 'width':
- sc = ax.bbox.width
- elif self._units == 'height':
- sc = ax.bbox.height
- elif self._units == 'dots':
- sc = 1.0
- else:
- raise ValueError('unrecognized units: %s' % self._units)
-
- self._transforms = np.zeros((len(self._widths), 3, 3))
- widths = self._widths * sc
- heights = self._heights * sc
- sin_angle = np.sin(self._angles)
- cos_angle = np.cos(self._angles)
- self._transforms[:, 0, 0] = widths * cos_angle
- self._transforms[:, 0, 1] = heights * -sin_angle
- self._transforms[:, 1, 0] = widths * sin_angle
- self._transforms[:, 1, 1] = heights * cos_angle
- self._transforms[:, 2, 2] = 1.0
-
- _affine = transforms.Affine2D
- if self._units == 'xy':
- m = ax.transData.get_affine().get_matrix().copy()
- m[:2, 2:] = 0
- self.set_transform(_affine(m))
-
- @artist.allow_rasterization
- def draw(self, renderer):
- self._set_transforms()
- Collection.draw(self, renderer)
-
-
-class PatchCollection(Collection):
- """
- A generic collection of patches.
-
- This makes it easier to assign a color map to a heterogeneous
- collection of patches.
-
- This also may improve plotting speed, since PatchCollection will
- draw faster than a large number of patches.
- """
-
- def __init__(self, patches, match_original=False, **kwargs):
- """
- *patches*
- a sequence of Patch objects. This list may include
- a heterogeneous assortment of different patch types.
-
- *match_original*
- If True, use the colors and linewidths of the original
- patches. If False, new colors may be assigned by
- providing the standard collection arguments, facecolor,
- edgecolor, linewidths, norm or cmap.
-
- If any of *edgecolors*, *facecolors*, *linewidths*,
- *antialiaseds* are None, they default to their
- :data:`matplotlib.rcParams` patch setting, in sequence form.
-
- The use of :class:`~matplotlib.cm.ScalarMappable` is optional.
- If the :class:`~matplotlib.cm.ScalarMappable` matrix _A is not
- None (i.e., a call to set_array has been made), at draw time a
- call to scalar mappable will be made to set the face colors.
- """
-
- if match_original:
- def determine_facecolor(patch):
- if patch.get_fill():
- return patch.get_facecolor()
- return [0, 0, 0, 0]
-
- kwargs['facecolors'] = [determine_facecolor(p) for p in patches]
- kwargs['edgecolors'] = [p.get_edgecolor() for p in patches]
- kwargs['linewidths'] = [p.get_linewidth() for p in patches]
- kwargs['linestyles'] = [p.get_linestyle() for p in patches]
- kwargs['antialiaseds'] = [p.get_antialiased() for p in patches]
-
- Collection.__init__(self, **kwargs)
-
- self.set_paths(patches)
-
- def set_paths(self, patches):
- paths = [p.get_transform().transform_path(p.get_path())
- for p in patches]
- self._paths = paths
-
-
-class TriMesh(Collection):
- """
- Class for the efficient drawing of a triangular mesh using
- Gouraud shading.
-
- A triangular mesh is a :class:`~matplotlib.tri.Triangulation`
- object.
- """
- def __init__(self, triangulation, **kwargs):
- Collection.__init__(self, **kwargs)
- self._triangulation = triangulation
- self._shading = 'gouraud'
- self._is_filled = True
-
- self._bbox = transforms.Bbox.unit()
-
- # Unfortunately this requires a copy, unless Triangulation
- # was rewritten.
- xy = np.hstack((triangulation.x.reshape(-1, 1),
- triangulation.y.reshape(-1, 1)))
- self._bbox.update_from_data_xy(xy)
-
- def get_paths(self):
- if self._paths is None:
- self.set_paths()
- return self._paths
-
- def set_paths(self):
- self._paths = self.convert_mesh_to_paths(self._triangulation)
-
- @staticmethod
- def convert_mesh_to_paths(tri):
- """
- Converts a given mesh into a sequence of
- :class:`matplotlib.path.Path` objects for easier rendering by
- backends that do not directly support meshes.
-
- This function is primarily of use to backend implementers.
- """
- Path = mpath.Path
- triangles = tri.get_masked_triangles()
- verts = np.concatenate((tri.x[triangles][..., np.newaxis],
- tri.y[triangles][..., np.newaxis]), axis=2)
- return [Path(x) for x in verts]
-
- @artist.allow_rasterization
- def draw(self, renderer):
- if not self.get_visible():
- return
- renderer.open_group(self.__class__.__name__)
- transform = self.get_transform()
-
- # Get a list of triangles and the color at each vertex.
- tri = self._triangulation
- triangles = tri.get_masked_triangles()
-
- verts = np.concatenate((tri.x[triangles][..., np.newaxis],
- tri.y[triangles][..., np.newaxis]), axis=2)
-
- self.update_scalarmappable()
- colors = self._facecolors[triangles]
-
- gc = renderer.new_gc()
- self._set_gc_clip(gc)
- gc.set_linewidth(self.get_linewidth()[0])
- renderer.draw_gouraud_triangles(gc, verts, colors, transform.frozen())
- gc.restore()
- renderer.close_group(self.__class__.__name__)
-
-
-class QuadMesh(Collection):
- """
- Class for the efficient drawing of a quadrilateral mesh.
-
- A quadrilateral mesh consists of a grid of vertices. The
- dimensions of this array are (*meshWidth* + 1, *meshHeight* +
- 1). Each vertex in the mesh has a different set of "mesh
- coordinates" representing its position in the topology of the
- mesh. For any values (*m*, *n*) such that 0 <= *m* <= *meshWidth*
- and 0 <= *n* <= *meshHeight*, the vertices at mesh coordinates
- (*m*, *n*), (*m*, *n* + 1), (*m* + 1, *n* + 1), and (*m* + 1, *n*)
- form one of the quadrilaterals in the mesh. There are thus
- (*meshWidth* * *meshHeight*) quadrilaterals in the mesh. The mesh
- need not be regular and the polygons need not be convex.
-
- A quadrilateral mesh is represented by a (2 x ((*meshWidth* + 1) *
- (*meshHeight* + 1))) numpy array *coordinates*, where each row is
- the *x* and *y* coordinates of one of the vertices. To define the
- function that maps from a data point to its corresponding color,
- use the :meth:`set_cmap` method. Each of these arrays is indexed in
- row-major order by the mesh coordinates of the vertex (or the mesh
- coordinates of the lower left vertex, in the case of the
- colors).
-
- For example, the first entry in *coordinates* is the
- coordinates of the vertex at mesh coordinates (0, 0), then the one
- at (0, 1), then at (0, 2) .. (0, meshWidth), (1, 0), (1, 1), and
- so on.
-
- *shading* may be 'flat', or 'gouraud'
- """
- def __init__(self, meshWidth, meshHeight, coordinates,
- antialiased=True, shading='flat', **kwargs):
- Collection.__init__(self, **kwargs)
- self._meshWidth = meshWidth
- self._meshHeight = meshHeight
- # By converting to floats now, we can avoid that on every draw.
- self._coordinates = np.asarray(coordinates, float).reshape(
- (meshHeight + 1, meshWidth + 1, 2))
- self._antialiased = antialiased
- self._shading = shading
-
- self._bbox = transforms.Bbox.unit()
- self._bbox.update_from_data_xy(coordinates.reshape(
- ((meshWidth + 1) * (meshHeight + 1), 2)))
-
- def get_paths(self):
- if self._paths is None:
- self.set_paths()
- return self._paths
-
- def set_paths(self):
- self._paths = self.convert_mesh_to_paths(
- self._meshWidth, self._meshHeight, self._coordinates)
- self.stale = True
-
- def get_datalim(self, transData):
- return (self.get_transform() - transData).transform_bbox(self._bbox)
-
- @staticmethod
- def convert_mesh_to_paths(meshWidth, meshHeight, coordinates):
- """
- Converts a given mesh into a sequence of
- :class:`matplotlib.path.Path` objects for easier rendering by
- backends that do not directly support quadmeshes.
-
- This function is primarily of use to backend implementers.
- """
- Path = mpath.Path
-
- if isinstance(coordinates, np.ma.MaskedArray):
- c = coordinates.data
- else:
- c = coordinates
-
- points = np.concatenate((
- c[0:-1, 0:-1],
- c[0:-1, 1:],
- c[1:, 1:],
- c[1:, 0:-1],
- c[0:-1, 0:-1]
- ), axis=2)
- points = points.reshape((meshWidth * meshHeight, 5, 2))
- return [Path(x) for x in points]
-
- def convert_mesh_to_triangles(self, meshWidth, meshHeight, coordinates):
- """
- Converts a given mesh into a sequence of triangles, each point
- with its own color. This is useful for experiments using
- `draw_qouraud_triangle`.
- """
- if isinstance(coordinates, np.ma.MaskedArray):
- p = coordinates.data
- else:
- p = coordinates
-
- p_a = p[:-1, :-1]
- p_b = p[:-1, 1:]
- p_c = p[1:, 1:]
- p_d = p[1:, :-1]
- p_center = (p_a + p_b + p_c + p_d) / 4.0
-
- triangles = np.concatenate((
- p_a, p_b, p_center,
- p_b, p_c, p_center,
- p_c, p_d, p_center,
- p_d, p_a, p_center,
- ), axis=2)
- triangles = triangles.reshape((meshWidth * meshHeight * 4, 3, 2))
-
- c = self.get_facecolor().reshape((meshHeight + 1, meshWidth + 1, 4))
- c_a = c[:-1, :-1]
- c_b = c[:-1, 1:]
- c_c = c[1:, 1:]
- c_d = c[1:, :-1]
- c_center = (c_a + c_b + c_c + c_d) / 4.0
-
- colors = np.concatenate((
- c_a, c_b, c_center,
- c_b, c_c, c_center,
- c_c, c_d, c_center,
- c_d, c_a, c_center,
- ), axis=2)
- colors = colors.reshape((meshWidth * meshHeight * 4, 3, 4))
-
- return triangles, colors
-
- @artist.allow_rasterization
- def draw(self, renderer):
- if not self.get_visible():
- return
- renderer.open_group(self.__class__.__name__, self.get_gid())
- transform = self.get_transform()
- transOffset = self.get_offset_transform()
- offsets = self._offsets
-
- if self.have_units():
- if len(self._offsets):
- xs = self.convert_xunits(self._offsets[:, 0])
- ys = self.convert_yunits(self._offsets[:, 1])
- offsets = np.column_stack([xs, ys])
-
- self.update_scalarmappable()
-
- if not transform.is_affine:
- coordinates = self._coordinates.reshape((-1, 2))
- coordinates = transform.transform(coordinates)
- coordinates = coordinates.reshape(self._coordinates.shape)
- transform = transforms.IdentityTransform()
- else:
- coordinates = self._coordinates
-
- if not transOffset.is_affine:
- offsets = transOffset.transform_non_affine(offsets)
- transOffset = transOffset.get_affine()
-
- gc = renderer.new_gc()
- self._set_gc_clip(gc)
- gc.set_linewidth(self.get_linewidth()[0])
-
- if self._shading == 'gouraud':
- triangles, colors = self.convert_mesh_to_triangles(
- self._meshWidth, self._meshHeight, coordinates)
- renderer.draw_gouraud_triangles(
- gc, triangles, colors, transform.frozen())
- else:
- renderer.draw_quad_mesh(
- gc, transform.frozen(), self._meshWidth, self._meshHeight,
- coordinates, offsets, transOffset, self.get_facecolor(),
- self._antialiased, self.get_edgecolors())
- gc.restore()
- renderer.close_group(self.__class__.__name__)
- self.stale = False
-
-
-patchstr = artist.kwdoc(Collection)
-for k in ('QuadMesh', 'TriMesh', 'PolyCollection', 'BrokenBarHCollection',
- 'RegularPolyCollection', 'PathCollection',
- 'StarPolygonCollection', 'PatchCollection',
- 'CircleCollection', 'Collection',):
- docstring.interpd.update({k: patchstr})
-docstring.interpd.update(LineCollection=artist.kwdoc(LineCollection))
diff --git a/contrib/python/matplotlib/py2/matplotlib/colorbar.py b/contrib/python/matplotlib/py2/matplotlib/colorbar.py
deleted file mode 100644
index 80664a99f9..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/colorbar.py
+++ /dev/null
@@ -1,1405 +0,0 @@
-'''
-Colorbar toolkit with two classes and a function:
-
- :class:`ColorbarBase`
- the base class with full colorbar drawing functionality.
- It can be used as-is to make a colorbar for a given colormap;
- a mappable object (e.g., image) is not needed.
-
- :class:`Colorbar`
- the derived class for use with images or contour plots.
-
- :func:`make_axes`
- a function for resizing an axes and adding a second axes
- suitable for a colorbar
-
-The :meth:`~matplotlib.figure.Figure.colorbar` method uses :func:`make_axes`
-and :class:`Colorbar`; the :func:`~matplotlib.pyplot.colorbar` function
-is a thin wrapper over :meth:`~matplotlib.figure.Figure.colorbar`.
-
-'''
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange, zip
-
-import warnings
-
-import numpy as np
-
-import matplotlib as mpl
-import matplotlib.artist as martist
-import matplotlib.cbook as cbook
-import matplotlib.collections as collections
-import matplotlib.colors as colors
-import matplotlib.contour as contour
-import matplotlib.cm as cm
-import matplotlib.gridspec as gridspec
-import matplotlib.patches as mpatches
-import matplotlib.path as mpath
-import matplotlib.ticker as ticker
-import matplotlib.transforms as mtransforms
-import matplotlib._layoutbox as layoutbox
-import matplotlib._constrained_layout as constrained_layout
-from matplotlib import docstring
-
-make_axes_kw_doc = '''
-
- ============= ====================================================
- Property Description
- ============= ====================================================
- *orientation* vertical or horizontal
- *fraction* 0.15; fraction of original axes to use for colorbar
- *pad* 0.05 if vertical, 0.15 if horizontal; fraction
- of original axes between colorbar and new image axes
- *shrink* 1.0; fraction by which to multiply the size of the colorbar
- *aspect* 20; ratio of long to short dimensions
- *anchor* (0.0, 0.5) if vertical; (0.5, 1.0) if horizontal;
- the anchor point of the colorbar axes
- *panchor* (1.0, 0.5) if vertical; (0.5, 0.0) if horizontal;
- the anchor point of the colorbar parent axes. If
- False, the parent axes' anchor will be unchanged
- ============= ====================================================
-
-'''
-
-colormap_kw_doc = '''
-
- ============ ====================================================
- Property Description
- ============ ====================================================
- *extend* [ 'neither' | 'both' | 'min' | 'max' ]
- If not 'neither', make pointed end(s) for out-of-
- range values. These are set for a given colormap
- using the colormap set_under and set_over methods.
- *extendfrac* [ *None* | 'auto' | length | lengths ]
- If set to *None*, both the minimum and maximum
- triangular colorbar extensions with have a length of
- 5% of the interior colorbar length (this is the
- default setting). If set to 'auto', makes the
- triangular colorbar extensions the same lengths as
- the interior boxes (when *spacing* is set to
- 'uniform') or the same lengths as the respective
- adjacent interior boxes (when *spacing* is set to
- 'proportional'). If a scalar, indicates the length
- of both the minimum and maximum triangular colorbar
- extensions as a fraction of the interior colorbar
- length. A two-element sequence of fractions may also
- be given, indicating the lengths of the minimum and
- maximum colorbar extensions respectively as a
- fraction of the interior colorbar length.
- *extendrect* bool
- If *False* the minimum and maximum colorbar extensions
- will be triangular (the default). If *True* the
- extensions will be rectangular.
- *spacing* [ 'uniform' | 'proportional' ]
- Uniform spacing gives each discrete color the same
- space; proportional makes the space proportional to
- the data interval.
- *ticks* [ None | list of ticks | Locator object ]
- If None, ticks are determined automatically from the
- input.
- *format* [ None | format string | Formatter object ]
- If None, the
- :class:`~matplotlib.ticker.ScalarFormatter` is used.
- If a format string is given, e.g., '%.3f', that is
- used. An alternative
- :class:`~matplotlib.ticker.Formatter` object may be
- given instead.
- *drawedges* bool
- Whether to draw lines at color boundaries.
- ============ ====================================================
-
- The following will probably be useful only in the context of
- indexed colors (that is, when the mappable has norm=NoNorm()),
- or other unusual circumstances.
-
- ============ ===================================================
- Property Description
- ============ ===================================================
- *boundaries* None or a sequence
- *values* None or a sequence which must be of length 1 less
- than the sequence of *boundaries*. For each region
- delimited by adjacent entries in *boundaries*, the
- color mapped to the corresponding value in values
- will be used.
- ============ ===================================================
-
-'''
-
-colorbar_doc = '''
-
-Add a colorbar to a plot.
-
-Function signatures for the :mod:`~matplotlib.pyplot` interface; all
-but the first are also method signatures for the
-:meth:`~matplotlib.figure.Figure.colorbar` method::
-
- colorbar(**kwargs)
- colorbar(mappable, **kwargs)
- colorbar(mappable, cax=cax, **kwargs)
- colorbar(mappable, ax=ax, **kwargs)
-
-Parameters
-----------
-mappable :
- The :class:`~matplotlib.image.Image`,
- :class:`~matplotlib.contour.ContourSet`, etc. to
- which the colorbar applies; this argument is mandatory for the Figure
- :meth:`~matplotlib.figure.Figure.colorbar` method but optional for the
- pyplot :func:`~matplotlib.pyplot.colorbar` function, which sets the
- default to the current image.
-
-cax : :class:`~matplotlib.axes.Axes` object, optional
- Axes into which the colorbar will be drawn.
-
-ax : :class:`~matplotlib.axes.Axes`, list of Axes, optional
- Parent axes from which space for a new colorbar axes will be stolen.
- If a list of axes is given they will all be resized to make room for the
- colorbar axes.
-
-use_gridspec : bool, optional
- If *cax* is ``None``, a new *cax* is created as an instance of
- Axes. If *ax* is an instance of Subplot and *use_gridspec* is ``True``,
- *cax* is created as an instance of Subplot using the
- grid_spec module.
-
-
-Returns
--------
-:class:`~matplotlib.colorbar.Colorbar` instance
- See also its base class, :class:`~matplotlib.colorbar.ColorbarBase`.
- Call the :meth:`~matplotlib.colorbar.ColorbarBase.set_label` method
- to label the colorbar.
-
-Notes
------
-Additional keyword arguments are of two kinds:
-
- axes properties:
-%s
- colorbar properties:
-%s
-
-If *mappable* is a :class:`~matplotlib.contours.ContourSet`, its *extend*
-kwarg is included automatically.
-
-The *shrink* kwarg provides a simple way to scale the colorbar with respect
-to the axes. Note that if *cax* is specified it determines the size of the
-colorbar and *shrink* and *aspect* kwargs are ignored.
-
-For more precise control, you can manually specify the positions of
-the axes objects in which the mappable and the colorbar are drawn. In
-this case, do not use any of the axes properties kwargs.
-
-It is known that some vector graphics viewer (svg and pdf) renders white gaps
-between segments of the colorbar. This is due to bugs in the viewers not
-matplotlib. As a workaround the colorbar can be rendered with overlapping
-segments::
-
- cbar = colorbar()
- cbar.solids.set_edgecolor("face")
- draw()
-
-However this has negative consequences in other circumstances. Particularly
-with semi transparent images (alpha < 1) and colorbar extensions and is not
-enabled by default see (issue #1188).
-
-''' % (make_axes_kw_doc, colormap_kw_doc)
-
-docstring.interpd.update(colorbar_doc=colorbar_doc)
-
-
-def _set_ticks_on_axis_warn(*args, **kw):
- # a top level function which gets put in at the axes'
- # set_xticks set_yticks by _patch_ax
- warnings.warn("Use the colorbar set_ticks() method instead.")
-
-
-class ColorbarBase(cm.ScalarMappable):
- '''
- Draw a colorbar in an existing axes.
-
- This is a base class for the :class:`Colorbar` class, which is the
- basis for the :func:`~matplotlib.pyplot.colorbar` function and the
- :meth:`~matplotlib.figure.Figure.colorbar` method, which are the
- usual ways of creating a colorbar.
-
- It is also useful by itself for showing a colormap. If the *cmap*
- kwarg is given but *boundaries* and *values* are left as None,
- then the colormap will be displayed on a 0-1 scale. To show the
- under- and over-value colors, specify the *norm* as::
-
- colors.Normalize(clip=False)
-
- To show the colors versus index instead of on the 0-1 scale,
- use::
-
- norm=colors.NoNorm.
-
- Useful public methods are :meth:`set_label` and :meth:`add_lines`.
-
- Attributes
- ----------
- ax : Axes
- The `Axes` instance in which the colorbar is drawn.
-
- lines : list
- A list of `LineCollection` if lines were drawn, otherwise
- an empty list.
-
- dividers : LineCollection
- A LineCollection if *drawedges* is ``True``, otherwise ``None``.
- '''
- _slice_dict = {'neither': slice(0, None),
- 'both': slice(1, -1),
- 'min': slice(1, None),
- 'max': slice(0, -1)}
-
- n_rasterize = 50 # rasterize solids if number of colors >= n_rasterize
-
- def __init__(self, ax, cmap=None,
- norm=None,
- alpha=None,
- values=None,
- boundaries=None,
- orientation='vertical',
- ticklocation='auto',
- extend='neither',
- spacing='uniform', # uniform or proportional
- ticks=None,
- format=None,
- drawedges=False,
- filled=True,
- extendfrac=None,
- extendrect=False,
- label='',
- ):
- #: The axes that this colorbar lives in.
- self.ax = ax
- self._patch_ax()
- if cmap is None:
- cmap = cm.get_cmap()
- if norm is None:
- norm = colors.Normalize()
- self.alpha = alpha
- cm.ScalarMappable.__init__(self, cmap=cmap, norm=norm)
- self.values = values
- self.boundaries = boundaries
- self.extend = extend
- self._inside = self._slice_dict[extend]
- self.spacing = spacing
- self.orientation = orientation
- self.drawedges = drawedges
- self.filled = filled
- self.extendfrac = extendfrac
- self.extendrect = extendrect
- self.solids = None
- self.lines = list()
- self.outline = None
- self.patch = None
- self.dividers = None
-
- if ticklocation == 'auto':
- ticklocation = 'bottom' if orientation == 'horizontal' else 'right'
- self.ticklocation = ticklocation
-
- self.set_label(label)
- if cbook.iterable(ticks):
- self.locator = ticker.FixedLocator(ticks, nbins=len(ticks))
- else:
- self.locator = ticks # Handle default in _ticker()
- if format is None:
- if isinstance(self.norm, colors.LogNorm):
- self.formatter = ticker.LogFormatterSciNotation()
- elif isinstance(self.norm, colors.SymLogNorm):
- self.formatter = ticker.LogFormatterSciNotation(
- linthresh=self.norm.linthresh)
- else:
- self.formatter = ticker.ScalarFormatter()
- elif isinstance(format, six.string_types):
- self.formatter = ticker.FormatStrFormatter(format)
- else:
- self.formatter = format # Assume it is a Formatter
- # The rest is in a method so we can recalculate when clim changes.
- self.config_axis()
- self.draw_all()
-
- def _extend_lower(self):
- """Returns whether the lower limit is open ended."""
- return self.extend in ('both', 'min')
-
- def _extend_upper(self):
- """Returns whether the uper limit is open ended."""
- return self.extend in ('both', 'max')
-
- def _patch_ax(self):
- # bind some methods to the axes to warn users
- # against using those methods.
- self.ax.set_xticks = _set_ticks_on_axis_warn
- self.ax.set_yticks = _set_ticks_on_axis_warn
-
- def draw_all(self):
- '''
- Calculate any free parameters based on the current cmap and norm,
- and do all the drawing.
- '''
-
- self._process_values()
- self._find_range()
- X, Y = self._mesh()
- C = self._values[:, np.newaxis]
- self._config_axes(X, Y)
- if self.filled:
- self._add_solids(X, Y, C)
-
- def config_axis(self):
- ax = self.ax
- if self.orientation == 'vertical':
- ax.xaxis.set_ticks([])
- # location is either one of 'bottom' or 'top'
- ax.yaxis.set_label_position(self.ticklocation)
- ax.yaxis.set_ticks_position(self.ticklocation)
- else:
- ax.yaxis.set_ticks([])
- # location is either one of 'left' or 'right'
- ax.xaxis.set_label_position(self.ticklocation)
- ax.xaxis.set_ticks_position(self.ticklocation)
-
- self._set_label()
-
- def update_ticks(self):
- """
- Force the update of the ticks and ticklabels. This must be
- called whenever the tick locator and/or tick formatter changes.
- """
- ax = self.ax
- ticks, ticklabels, offset_string = self._ticker()
- if self.orientation == 'vertical':
- ax.yaxis.set_ticks(ticks)
- ax.set_yticklabels(ticklabels)
- ax.yaxis.get_major_formatter().set_offset_string(offset_string)
-
- else:
- ax.xaxis.set_ticks(ticks)
- ax.set_xticklabels(ticklabels)
- ax.xaxis.get_major_formatter().set_offset_string(offset_string)
-
- def set_ticks(self, ticks, update_ticks=True):
- """
- Set tick locations.
-
- Parameters
- ----------
- ticks : {None, sequence, :class:`~matplotlib.ticker.Locator` instance}
- If None, a default Locator will be used.
-
- update_ticks : {True, False}, optional
- If True, tick locations are updated immediately. If False,
- use :meth:`update_ticks` to manually update the ticks.
-
- """
- if cbook.iterable(ticks):
- self.locator = ticker.FixedLocator(ticks, nbins=len(ticks))
- else:
- self.locator = ticks
-
- if update_ticks:
- self.update_ticks()
- self.stale = True
-
- def get_ticks(self, minor=False):
- """Return the x ticks as a list of locations"""
- return self._tick_data_values
-
- def set_ticklabels(self, ticklabels, update_ticks=True):
- """
- set tick labels. Tick labels are updated immediately unless
- update_ticks is *False*. To manually update the ticks, call
- *update_ticks* method explicitly.
- """
- if isinstance(self.locator, ticker.FixedLocator):
- self.formatter = ticker.FixedFormatter(ticklabels)
- if update_ticks:
- self.update_ticks()
- else:
- warnings.warn("set_ticks() must have been called.")
- self.stale = True
-
- def _config_axes(self, X, Y):
- '''
- Make an axes patch and outline.
- '''
- ax = self.ax
- ax.set_frame_on(False)
- ax.set_navigate(False)
- xy = self._outline(X, Y)
- ax.update_datalim(xy)
- ax.set_xlim(*ax.dataLim.intervalx)
- ax.set_ylim(*ax.dataLim.intervaly)
- if self.outline is not None:
- self.outline.remove()
- self.outline = mpatches.Polygon(
- xy, edgecolor=mpl.rcParams['axes.edgecolor'],
- facecolor='none',
- linewidth=mpl.rcParams['axes.linewidth'],
- closed=True,
- zorder=2)
- ax.add_artist(self.outline)
- self.outline.set_clip_box(None)
- self.outline.set_clip_path(None)
- c = mpl.rcParams['axes.facecolor']
- if self.patch is not None:
- self.patch.remove()
- self.patch = mpatches.Polygon(xy, edgecolor=c,
- facecolor=c,
- linewidth=0.01,
- zorder=-1)
- ax.add_artist(self.patch)
-
- self.update_ticks()
-
- def _set_label(self):
- if self.orientation == 'vertical':
- self.ax.set_ylabel(self._label, **self._labelkw)
- else:
- self.ax.set_xlabel(self._label, **self._labelkw)
- self.stale = True
-
- def set_label(self, label, **kw):
- '''
- Label the long axis of the colorbar
- '''
- self._label = '%s' % (label, )
- self._labelkw = kw
- self._set_label()
-
- def _outline(self, X, Y):
- '''
- Return *x*, *y* arrays of colorbar bounding polygon,
- taking orientation into account.
- '''
- N = X.shape[0]
- ii = [0, 1, N - 2, N - 1, 2 * N - 1, 2 * N - 2, N + 1, N, 0]
- x = np.take(np.ravel(np.transpose(X)), ii)
- y = np.take(np.ravel(np.transpose(Y)), ii)
- x = x.reshape((len(x), 1))
- y = y.reshape((len(y), 1))
- if self.orientation == 'horizontal':
- return np.hstack((y, x))
- return np.hstack((x, y))
-
- def _edges(self, X, Y):
- '''
- Return the separator line segments; helper for _add_solids.
- '''
- N = X.shape[0]
- # Using the non-array form of these line segments is much
- # simpler than making them into arrays.
- if self.orientation == 'vertical':
- return [list(zip(X[i], Y[i])) for i in xrange(1, N - 1)]
- else:
- return [list(zip(Y[i], X[i])) for i in xrange(1, N - 1)]
-
- def _add_solids(self, X, Y, C):
- '''
- Draw the colors using :meth:`~matplotlib.axes.Axes.pcolormesh`;
- optionally add separators.
- '''
- if self.orientation == 'vertical':
- args = (X, Y, C)
- else:
- args = (np.transpose(Y), np.transpose(X), np.transpose(C))
- kw = dict(cmap=self.cmap,
- norm=self.norm,
- alpha=self.alpha,
- edgecolors='None')
- # Save, set, and restore hold state to keep pcolor from
- # clearing the axes. Ordinarily this will not be needed,
- # since the axes object should already have hold set.
- _hold = self.ax._hold
- self.ax._hold = True
- col = self.ax.pcolormesh(*args, **kw)
- self.ax._hold = _hold
- #self.add_observer(col) # We should observe, not be observed...
-
- if self.solids is not None:
- self.solids.remove()
- self.solids = col
- if self.dividers is not None:
- self.dividers.remove()
- self.dividers = None
- if self.drawedges:
- linewidths = (0.5 * mpl.rcParams['axes.linewidth'],)
- self.dividers = collections.LineCollection(
- self._edges(X, Y),
- colors=(mpl.rcParams['axes.edgecolor'],),
- linewidths=linewidths)
- self.ax.add_collection(self.dividers)
- elif len(self._y) >= self.n_rasterize:
- self.solids.set_rasterized(True)
-
- def add_lines(self, levels, colors, linewidths, erase=True):
- '''
- Draw lines on the colorbar.
-
- *colors* and *linewidths* must be scalars or
- sequences the same length as *levels*.
-
- Set *erase* to False to add lines without first
- removing any previously added lines.
- '''
- y = self._locate(levels)
- igood = (y < 1.001) & (y > -0.001)
- y = y[igood]
- if cbook.iterable(colors):
- colors = np.asarray(colors)[igood]
- if cbook.iterable(linewidths):
- linewidths = np.asarray(linewidths)[igood]
- N = len(y)
- x = np.array([0.0, 1.0])
- X, Y = np.meshgrid(x, y)
- if self.orientation == 'vertical':
- xy = [list(zip(X[i], Y[i])) for i in xrange(N)]
- else:
- xy = [list(zip(Y[i], X[i])) for i in xrange(N)]
- col = collections.LineCollection(xy, linewidths=linewidths)
-
- if erase and self.lines:
- for lc in self.lines:
- lc.remove()
- self.lines = []
- self.lines.append(col)
- col.set_color(colors)
- self.ax.add_collection(col)
- self.stale = True
-
- def _ticker(self):
- '''
- Return the sequence of ticks (colorbar data locations),
- ticklabels (strings), and the corresponding offset string.
- '''
- locator = self.locator
- formatter = self.formatter
- if locator is None:
- if self.boundaries is None:
- if isinstance(self.norm, colors.NoNorm):
- nv = len(self._values)
- base = 1 + int(nv / 10)
- locator = ticker.IndexLocator(base=base, offset=0)
- elif isinstance(self.norm, colors.BoundaryNorm):
- b = self.norm.boundaries
- locator = ticker.FixedLocator(b, nbins=10)
- elif isinstance(self.norm, colors.LogNorm):
- locator = ticker.LogLocator(subs='all')
- elif isinstance(self.norm, colors.SymLogNorm):
- # The subs setting here should be replaced
- # by logic in the locator.
- locator = ticker.SymmetricalLogLocator(
- subs=np.arange(1, 10),
- linthresh=self.norm.linthresh,
- base=10)
- else:
- if mpl.rcParams['_internal.classic_mode']:
- locator = ticker.MaxNLocator()
- else:
- locator = ticker.AutoLocator()
- else:
- b = self._boundaries[self._inside]
- locator = ticker.FixedLocator(b, nbins=10)
- if isinstance(self.norm, colors.NoNorm) and self.boundaries is None:
- intv = self._values[0], self._values[-1]
- else:
- intv = self.vmin, self.vmax
- locator.create_dummy_axis(minpos=intv[0])
- formatter.create_dummy_axis(minpos=intv[0])
- locator.set_view_interval(*intv)
- locator.set_data_interval(*intv)
- formatter.set_view_interval(*intv)
- formatter.set_data_interval(*intv)
-
- b = np.array(locator())
- if isinstance(locator, ticker.LogLocator):
- eps = 1e-10
- b = b[(b <= intv[1] * (1 + eps)) & (b >= intv[0] * (1 - eps))]
- else:
- eps = (intv[1] - intv[0]) * 1e-10
- b = b[(b <= intv[1] + eps) & (b >= intv[0] - eps)]
- self._tick_data_values = b
- ticks = self._locate(b)
- formatter.set_locs(b)
- ticklabels = [formatter(t, i) for i, t in enumerate(b)]
- offset_string = formatter.get_offset()
- return ticks, ticklabels, offset_string
-
- def _process_values(self, b=None):
- '''
- Set the :attr:`_boundaries` and :attr:`_values` attributes
- based on the input boundaries and values. Input boundaries
- can be *self.boundaries* or the argument *b*.
- '''
- if b is None:
- b = self.boundaries
- if b is not None:
- self._boundaries = np.asarray(b, dtype=float)
- if self.values is None:
- self._values = 0.5 * (self._boundaries[:-1]
- + self._boundaries[1:])
- if isinstance(self.norm, colors.NoNorm):
- self._values = (self._values + 0.00001).astype(np.int16)
- return
- self._values = np.array(self.values)
- return
- if self.values is not None:
- self._values = np.array(self.values)
- if self.boundaries is None:
- b = np.zeros(len(self.values) + 1, 'd')
- b[1:-1] = 0.5 * (self._values[:-1] - self._values[1:])
- b[0] = 2.0 * b[1] - b[2]
- b[-1] = 2.0 * b[-2] - b[-3]
- self._boundaries = b
- return
- self._boundaries = np.array(self.boundaries)
- return
- # Neither boundaries nor values are specified;
- # make reasonable ones based on cmap and norm.
- if isinstance(self.norm, colors.NoNorm):
- b = self._uniform_y(self.cmap.N + 1) * self.cmap.N - 0.5
- v = np.zeros((len(b) - 1,), dtype=np.int16)
- v[self._inside] = np.arange(self.cmap.N, dtype=np.int16)
- if self._extend_lower():
- v[0] = -1
- if self._extend_upper():
- v[-1] = self.cmap.N
- self._boundaries = b
- self._values = v
- return
- elif isinstance(self.norm, colors.BoundaryNorm):
- b = list(self.norm.boundaries)
- if self._extend_lower():
- b = [b[0] - 1] + b
- if self._extend_upper():
- b = b + [b[-1] + 1]
- b = np.array(b)
- v = np.zeros((len(b) - 1,), dtype=float)
- bi = self.norm.boundaries
- v[self._inside] = 0.5 * (bi[:-1] + bi[1:])
- if self._extend_lower():
- v[0] = b[0] - 1
- if self._extend_upper():
- v[-1] = b[-1] + 1
- self._boundaries = b
- self._values = v
- return
- else:
- if not self.norm.scaled():
- self.norm.vmin = 0
- self.norm.vmax = 1
-
- self.norm.vmin, self.norm.vmax = mtransforms.nonsingular(
- self.norm.vmin,
- self.norm.vmax,
- expander=0.1)
-
- b = self.norm.inverse(self._uniform_y(self.cmap.N + 1))
-
- if isinstance(self.norm, colors.LogNorm):
- # If using a lognorm, ensure extensions don't go negative
- if self._extend_lower():
- b[0] = 0.9 * b[0]
- if self._extend_upper():
- b[-1] = 1.1 * b[-1]
- else:
- if self._extend_lower():
- b[0] = b[0] - 1
- if self._extend_upper():
- b[-1] = b[-1] + 1
- self._process_values(b)
-
- def _find_range(self):
- '''
- Set :attr:`vmin` and :attr:`vmax` attributes to the first and
- last boundary excluding extended end boundaries.
- '''
- b = self._boundaries[self._inside]
- self.vmin = b[0]
- self.vmax = b[-1]
-
- def _central_N(self):
- '''number of boundaries **before** extension of ends'''
- nb = len(self._boundaries)
- if self.extend == 'both':
- nb -= 2
- elif self.extend in ('min', 'max'):
- nb -= 1
- return nb
-
- def _extended_N(self):
- '''
- Based on the colormap and extend variable, return the
- number of boundaries.
- '''
- N = self.cmap.N + 1
- if self.extend == 'both':
- N += 2
- elif self.extend in ('min', 'max'):
- N += 1
- return N
-
- def _get_extension_lengths(self, frac, automin, automax, default=0.05):
- '''
- Get the lengths of colorbar extensions.
-
- A helper method for _uniform_y and _proportional_y.
- '''
- # Set the default value.
- extendlength = np.array([default, default])
- if isinstance(frac, six.string_types):
- if frac.lower() == 'auto':
- # Use the provided values when 'auto' is required.
- extendlength[0] = automin
- extendlength[1] = automax
- else:
- # Any other string is invalid.
- raise ValueError('invalid value for extendfrac')
- elif frac is not None:
- try:
- # Try to set min and max extension fractions directly.
- extendlength[:] = frac
- # If frac is a sequence containing None then NaN may
- # be encountered. This is an error.
- if np.isnan(extendlength).any():
- raise ValueError()
- except (TypeError, ValueError):
- # Raise an error on encountering an invalid value for frac.
- raise ValueError('invalid value for extendfrac')
- return extendlength
-
- def _uniform_y(self, N):
- '''
- Return colorbar data coordinates for *N* uniformly
- spaced boundaries, plus ends if required.
- '''
- if self.extend == 'neither':
- y = np.linspace(0, 1, N)
- else:
- automin = automax = 1. / (N - 1.)
- extendlength = self._get_extension_lengths(self.extendfrac,
- automin, automax,
- default=0.05)
- if self.extend == 'both':
- y = np.zeros(N + 2, 'd')
- y[0] = 0. - extendlength[0]
- y[-1] = 1. + extendlength[1]
- elif self.extend == 'min':
- y = np.zeros(N + 1, 'd')
- y[0] = 0. - extendlength[0]
- else:
- y = np.zeros(N + 1, 'd')
- y[-1] = 1. + extendlength[1]
- y[self._inside] = np.linspace(0, 1, N)
- return y
-
- def _proportional_y(self):
- '''
- Return colorbar data coordinates for the boundaries of
- a proportional colorbar.
- '''
- if isinstance(self.norm, colors.BoundaryNorm):
- y = (self._boundaries - self._boundaries[0])
- y = y / (self._boundaries[-1] - self._boundaries[0])
- else:
- y = self.norm(self._boundaries.copy())
- y = np.ma.filled(y, np.nan)
- if self.extend == 'min':
- # Exclude leftmost interval of y.
- clen = y[-1] - y[1]
- automin = (y[2] - y[1]) / clen
- automax = (y[-1] - y[-2]) / clen
- elif self.extend == 'max':
- # Exclude rightmost interval in y.
- clen = y[-2] - y[0]
- automin = (y[1] - y[0]) / clen
- automax = (y[-2] - y[-3]) / clen
- elif self.extend == 'both':
- # Exclude leftmost and rightmost intervals in y.
- clen = y[-2] - y[1]
- automin = (y[2] - y[1]) / clen
- automax = (y[-2] - y[-3]) / clen
- if self.extend in ('both', 'min', 'max'):
- extendlength = self._get_extension_lengths(self.extendfrac,
- automin, automax,
- default=0.05)
- if self.extend in ('both', 'min'):
- y[0] = 0. - extendlength[0]
- if self.extend in ('both', 'max'):
- y[-1] = 1. + extendlength[1]
- yi = y[self._inside]
- norm = colors.Normalize(yi[0], yi[-1])
- y[self._inside] = np.ma.filled(norm(yi), np.nan)
- return y
-
- def _mesh(self):
- '''
- Return X,Y, the coordinate arrays for the colorbar pcolormesh.
- These are suitable for a vertical colorbar; swapping and
- transposition for a horizontal colorbar are done outside
- this function.
- '''
- x = np.array([0.0, 1.0])
- if self.spacing == 'uniform':
- y = self._uniform_y(self._central_N())
- else:
- y = self._proportional_y()
- self._y = y
- X, Y = np.meshgrid(x, y)
- if self._extend_lower() and not self.extendrect:
- X[0, :] = 0.5
- if self._extend_upper() and not self.extendrect:
- X[-1, :] = 0.5
- return X, Y
-
- def _locate(self, x):
- '''
- Given a set of color data values, return their
- corresponding colorbar data coordinates.
- '''
- if isinstance(self.norm, (colors.NoNorm, colors.BoundaryNorm)):
- b = self._boundaries
- xn = x
- else:
- # Do calculations using normalized coordinates so
- # as to make the interpolation more accurate.
- b = self.norm(self._boundaries, clip=False).filled()
- xn = self.norm(x, clip=False).filled()
-
- # The rest is linear interpolation with extrapolation at ends.
- ii = np.searchsorted(b, xn)
- i0 = ii - 1
- itop = (ii == len(b))
- ibot = (ii == 0)
- i0[itop] -= 1
- ii[itop] -= 1
- i0[ibot] += 1
- ii[ibot] += 1
-
- db = np.take(b, ii) - np.take(b, i0)
- y = self._y
- dy = np.take(y, ii) - np.take(y, i0)
- z = np.take(y, i0) + (xn - np.take(b, i0)) * dy / db
- return z
-
- def set_alpha(self, alpha):
- self.alpha = alpha
-
- def remove(self):
- """
- Remove this colorbar from the figure
- """
-
- fig = self.ax.figure
- fig.delaxes(self.ax)
-
-
-class Colorbar(ColorbarBase):
- """
- This class connects a :class:`ColorbarBase` to a
- :class:`~matplotlib.cm.ScalarMappable` such as a
- :class:`~matplotlib.image.AxesImage` generated via
- :meth:`~matplotlib.axes.Axes.imshow`.
-
- It is not intended to be instantiated directly; instead,
- use :meth:`~matplotlib.figure.Figure.colorbar` or
- :func:`~matplotlib.pyplot.colorbar` to make your colorbar.
-
- """
- def __init__(self, ax, mappable, **kw):
- # Ensure the given mappable's norm has appropriate vmin and vmax set
- # even if mappable.draw has not yet been called.
- mappable.autoscale_None()
-
- self.mappable = mappable
- kw['cmap'] = cmap = mappable.cmap
- kw['norm'] = norm = mappable.norm
-
- if isinstance(mappable, contour.ContourSet):
- CS = mappable
- kw['alpha'] = mappable.get_alpha()
- kw['boundaries'] = CS._levels
- kw['values'] = CS.cvalues
- kw['extend'] = CS.extend
- #kw['ticks'] = CS._levels
- kw.setdefault('ticks', ticker.FixedLocator(CS.levels, nbins=10))
- kw['filled'] = CS.filled
- ColorbarBase.__init__(self, ax, **kw)
- if not CS.filled:
- self.add_lines(CS)
- else:
- if getattr(cmap, 'colorbar_extend', False) is not False:
- kw.setdefault('extend', cmap.colorbar_extend)
-
- if isinstance(mappable, martist.Artist):
- kw['alpha'] = mappable.get_alpha()
-
- ColorbarBase.__init__(self, ax, **kw)
-
- def on_mappable_changed(self, mappable):
- """
- Updates this colorbar to match the mappable's properties.
-
- Typically this is automatically registered as an event handler
- by :func:`colorbar_factory` and should not be called manually.
-
- """
- self.set_cmap(mappable.get_cmap())
- self.set_clim(mappable.get_clim())
- self.update_normal(mappable)
-
- def add_lines(self, CS, erase=True):
- '''
- Add the lines from a non-filled
- :class:`~matplotlib.contour.ContourSet` to the colorbar.
-
- Set *erase* to False if these lines should be added to
- any pre-existing lines.
- '''
- if not isinstance(CS, contour.ContourSet) or CS.filled:
- raise ValueError('add_lines is only for a ContourSet of lines')
- tcolors = [c[0] for c in CS.tcolors]
- tlinewidths = [t[0] for t in CS.tlinewidths]
- # The following was an attempt to get the colorbar lines
- # to follow subsequent changes in the contour lines,
- # but more work is needed: specifically, a careful
- # look at event sequences, and at how
- # to make one object track another automatically.
- #tcolors = [col.get_colors()[0] for col in CS.collections]
- #tlinewidths = [col.get_linewidth()[0] for lw in CS.collections]
- ColorbarBase.add_lines(self, CS.levels, tcolors, tlinewidths,
- erase=erase)
-
- def update_normal(self, mappable):
- '''
- update solid, lines, etc. Unlike update_bruteforce, it does
- not clear the axes. This is meant to be called when the image
- or contour plot to which this colorbar belongs is changed.
- '''
- self.draw_all()
- if isinstance(self.mappable, contour.ContourSet):
- CS = self.mappable
- if not CS.filled:
- self.add_lines(CS)
- self.stale = True
-
- def update_bruteforce(self, mappable):
- '''
- Destroy and rebuild the colorbar. This is
- intended to become obsolete, and will probably be
- deprecated and then removed. It is not called when
- the pyplot.colorbar function or the Figure.colorbar
- method are used to create the colorbar.
-
- '''
- # We are using an ugly brute-force method: clearing and
- # redrawing the whole thing. The problem is that if any
- # properties have been changed by methods other than the
- # colorbar methods, those changes will be lost.
- self.ax.cla()
- # clearing the axes will delete outline, patch, solids, and lines:
- self.outline = None
- self.patch = None
- self.solids = None
- self.lines = list()
- self.dividers = None
- self.set_alpha(mappable.get_alpha())
- self.cmap = mappable.cmap
- self.norm = mappable.norm
- self.config_axis()
- self.draw_all()
- if isinstance(self.mappable, contour.ContourSet):
- CS = self.mappable
- if not CS.filled:
- self.add_lines(CS)
- #if self.lines is not None:
- # tcolors = [c[0] for c in CS.tcolors]
- # self.lines.set_color(tcolors)
- #Fixme? Recalculate boundaries, ticks if vmin, vmax have changed.
- #Fixme: Some refactoring may be needed; we should not
- # be recalculating everything if there was a simple alpha
- # change.
-
- def remove(self):
- """
- Remove this colorbar from the figure. If the colorbar was created with
- ``use_gridspec=True`` then restore the gridspec to its previous value.
- """
-
- ColorbarBase.remove(self)
- self.mappable.callbacksSM.disconnect(self.mappable.colorbar_cid)
- self.mappable.colorbar = None
- self.mappable.colorbar_cid = None
-
- try:
- ax = self.mappable.axes
- except AttributeError:
- return
-
- try:
- gs = ax.get_subplotspec().get_gridspec()
- subplotspec = gs.get_topmost_subplotspec()
- except AttributeError:
- # use_gridspec was False
- pos = ax.get_position(original=True)
- ax._set_position(pos)
- else:
- # use_gridspec was True
- ax.set_subplotspec(subplotspec)
-
-
-@docstring.Substitution(make_axes_kw_doc)
-def make_axes(parents, location=None, orientation=None, fraction=0.15,
- shrink=1.0, aspect=20, **kw):
- '''
- Resize and reposition parent axes, and return a child
- axes suitable for a colorbar.
-
- Keyword arguments may include the following (with defaults):
-
- location : [None|'left'|'right'|'top'|'bottom']
- The position, relative to **parents**, where the colorbar axes
- should be created. If None, the value will either come from the
- given ``orientation``, else it will default to 'right'.
-
- orientation : [None|'vertical'|'horizontal']
- The orientation of the colorbar. Typically, this keyword shouldn't
- be used, as it can be derived from the ``location`` keyword.
-
- %s
-
- Returns (cax, kw), the child axes and the reduced kw dictionary to be
- passed when creating the colorbar instance.
- '''
- locations = ["left", "right", "top", "bottom"]
- if orientation is not None and location is not None:
- raise TypeError('position and orientation are mutually exclusive. '
- 'Consider setting the position to any of {}'
- .format(', '.join(locations)))
-
- # provide a default location
- if location is None and orientation is None:
- location = 'right'
-
- # allow the user to not specify the location by specifying the
- # orientation instead
- if location is None:
- location = 'right' if orientation == 'vertical' else 'bottom'
-
- if location not in locations:
- raise ValueError('Invalid colorbar location. Must be one '
- 'of %s' % ', '.join(locations))
-
- default_location_settings = {'left': {'anchor': (1.0, 0.5),
- 'panchor': (0.0, 0.5),
- 'pad': 0.10,
- 'orientation': 'vertical'},
- 'right': {'anchor': (0.0, 0.5),
- 'panchor': (1.0, 0.5),
- 'pad': 0.05,
- 'orientation': 'vertical'},
- 'top': {'anchor': (0.5, 0.0),
- 'panchor': (0.5, 1.0),
- 'pad': 0.05,
- 'orientation': 'horizontal'},
- 'bottom': {'anchor': (0.5, 1.0),
- 'panchor': (0.5, 0.0),
- 'pad': 0.15, # backwards compat
- 'orientation': 'horizontal'},
- }
-
- loc_settings = default_location_settings[location]
-
- # put appropriate values into the kw dict for passing back to
- # the Colorbar class
- kw['orientation'] = loc_settings['orientation']
- kw['ticklocation'] = location
-
- anchor = kw.pop('anchor', loc_settings['anchor'])
- parent_anchor = kw.pop('panchor', loc_settings['panchor'])
-
- parents_iterable = cbook.iterable(parents)
- # turn parents into a list if it is not already. We do this w/ np
- # because `plt.subplots` can return an ndarray and is natural to
- # pass to `colorbar`.
- parents = np.atleast_1d(parents).ravel()
-
- # check if using constrained_layout:
- try:
- gs = parents[0].get_subplotspec().get_gridspec()
- using_constrained_layout = (gs._layoutbox is not None)
- except AttributeError:
- using_constrained_layout = False
-
- # defaults are not appropriate for constrained_layout:
- pad0 = loc_settings['pad']
- if using_constrained_layout:
- pad0 = 0.02
- pad = kw.pop('pad', pad0)
-
- fig = parents[0].get_figure()
- if not all(fig is ax.get_figure() for ax in parents):
- raise ValueError('Unable to create a colorbar axes as not all '
- 'parents share the same figure.')
-
- # take a bounding box around all of the given axes
- parents_bbox = mtransforms.Bbox.union(
- [ax.get_position(original=True).frozen() for ax in parents])
-
- pb = parents_bbox
- if location in ('left', 'right'):
- if location == 'left':
- pbcb, _, pb1 = pb.splitx(fraction, fraction + pad)
- else:
- pb1, _, pbcb = pb.splitx(1 - fraction - pad, 1 - fraction)
- pbcb = pbcb.shrunk(1.0, shrink).anchored(anchor, pbcb)
- else:
- if location == 'bottom':
- pbcb, _, pb1 = pb.splity(fraction, fraction + pad)
- else:
- pb1, _, pbcb = pb.splity(1 - fraction - pad, 1 - fraction)
- pbcb = pbcb.shrunk(shrink, 1.0).anchored(anchor, pbcb)
-
- # define the aspect ratio in terms of y's per x rather than x's per y
- aspect = 1.0 / aspect
-
- # define a transform which takes us from old axes coordinates to
- # new axes coordinates
- shrinking_trans = mtransforms.BboxTransform(parents_bbox, pb1)
-
- # transform each of the axes in parents using the new transform
- for ax in parents:
- new_posn = shrinking_trans.transform(ax.get_position())
- new_posn = mtransforms.Bbox(new_posn)
- ax._set_position(new_posn)
- if parent_anchor is not False:
- ax.set_anchor(parent_anchor)
-
- cax = fig.add_axes(pbcb)
-
- # OK, now make a layoutbox for the cb axis. Later, we will use this
- # to make the colorbar fit nicely.
- if not using_constrained_layout:
- # no layout boxes:
- lb = None
- lbpos = None
- # and we need to set the aspect ratio by hand...
- cax.set_aspect(aspect, anchor=anchor, adjustable='box')
- else:
- if not parents_iterable:
- # this is a single axis...
- ax = parents[0]
- lb, lbpos = constrained_layout.layoutcolorbarsingle(
- ax, cax, shrink, aspect, location, pad=pad)
- else: # there is more than one parent, so lets use gridspec
- # the colorbar will be a sibling of this gridspec, so the
- # parent is the same parent as the gridspec. Either the figure,
- # or a subplotspec.
-
- lb, lbpos = constrained_layout.layoutcolorbargridspec(
- parents, cax, shrink, aspect, location, pad)
-
- cax._layoutbox = lb
- cax._poslayoutbox = lbpos
-
- return cax, kw
-
-
-@docstring.Substitution(make_axes_kw_doc)
-def make_axes_gridspec(parent, **kw):
- '''
- Resize and reposition a parent axes, and return a child axes
- suitable for a colorbar. This function is similar to
- make_axes. Prmary differences are
-
- * *make_axes_gridspec* only handles the *orientation* keyword
- and cannot handle the "location" keyword.
-
- * *make_axes_gridspec* should only be used with a subplot parent.
-
- * *make_axes* creates an instance of Axes. *make_axes_gridspec*
- creates an instance of Subplot.
-
- * *make_axes* updates the position of the
- parent. *make_axes_gridspec* replaces the grid_spec attribute
- of the parent with a new one.
-
- While this function is meant to be compatible with *make_axes*,
- there could be some minor differences.
-
- Keyword arguments may include the following (with defaults):
-
- *orientation*
- 'vertical' or 'horizontal'
-
- %s
-
- All but the first of these are stripped from the input kw set.
-
- Returns (cax, kw), the child axes and the reduced kw dictionary to be
- passed when creating the colorbar instance.
- '''
-
- orientation = kw.setdefault('orientation', 'vertical')
- kw['ticklocation'] = 'auto'
-
- fraction = kw.pop('fraction', 0.15)
- shrink = kw.pop('shrink', 1.0)
- aspect = kw.pop('aspect', 20)
-
- x1 = 1 - fraction
-
- # for shrinking
- pad_s = (1 - shrink) * 0.5
- wh_ratios = [pad_s, shrink, pad_s]
-
- # we need to none the tree of layoutboxes because
- # constrained_layout can't remove and replace the tree
- # hierarchy w/o a seg fault.
- gs = parent.get_subplotspec().get_gridspec()
- layoutbox.nonetree(gs._layoutbox)
- gs_from_subplotspec = gridspec.GridSpecFromSubplotSpec
- if orientation == 'vertical':
- pad = kw.pop('pad', 0.05)
- wh_space = 2 * pad / (1 - pad)
- gs = gs_from_subplotspec(1, 2,
- subplot_spec=parent.get_subplotspec(),
- wspace=wh_space,
- width_ratios=[x1 - pad, fraction])
- gs2 = gs_from_subplotspec(3, 1,
- subplot_spec=gs[1],
- hspace=0.,
- height_ratios=wh_ratios)
- anchor = (0.0, 0.5)
- panchor = (1.0, 0.5)
- else:
- pad = kw.pop('pad', 0.15)
- wh_space = 2 * pad / (1 - pad)
- gs = gs_from_subplotspec(2, 1,
- subplot_spec=parent.get_subplotspec(),
- hspace=wh_space,
- height_ratios=[x1 - pad, fraction])
- gs2 = gs_from_subplotspec(1, 3,
- subplot_spec=gs[1],
- wspace=0.,
- width_ratios=wh_ratios)
- aspect = 1 / aspect
- anchor = (0.5, 1.0)
- panchor = (0.5, 0.0)
-
- parent.set_subplotspec(gs[0])
- parent.update_params()
- parent._set_position(parent.figbox)
- parent.set_anchor(panchor)
-
- fig = parent.get_figure()
- cax = fig.add_subplot(gs2[1])
- cax.set_aspect(aspect, anchor=anchor, adjustable='box')
- return cax, kw
-
-
-class ColorbarPatch(Colorbar):
- """
- A Colorbar which is created using :class:`~matplotlib.patches.Patch`
- rather than the default :func:`~matplotlib.axes.pcolor`.
-
- It uses a list of Patch instances instead of a
- :class:`~matplotlib.collections.PatchCollection` because the
- latter does not allow the hatch pattern to vary among the
- members of the collection.
- """
- def __init__(self, ax, mappable, **kw):
- # we do not want to override the behaviour of solids
- # so add a new attribute which will be a list of the
- # colored patches in the colorbar
- self.solids_patches = []
- Colorbar.__init__(self, ax, mappable, **kw)
-
- def _add_solids(self, X, Y, C):
- """
- Draw the colors using :class:`~matplotlib.patches.Patch`;
- optionally add separators.
- """
- # Save, set, and restore hold state to keep pcolor from
- # clearing the axes. Ordinarily this will not be needed,
- # since the axes object should already have hold set.
- _hold = self.ax._hold
- self.ax._hold = True
-
- kw = {'alpha': self.alpha, }
-
- n_segments = len(C)
-
- # ensure there are sufficient hatches
- hatches = self.mappable.hatches * n_segments
-
- patches = []
- for i in xrange(len(X) - 1):
- val = C[i][0]
- hatch = hatches[i]
-
- xy = np.array([[X[i][0], Y[i][0]],
- [X[i][1], Y[i][0]],
- [X[i + 1][1], Y[i + 1][0]],
- [X[i + 1][0], Y[i + 1][1]]])
-
- if self.orientation == 'horizontal':
- # if horizontal swap the xs and ys
- xy = xy[..., ::-1]
-
- patch = mpatches.PathPatch(mpath.Path(xy),
- facecolor=self.cmap(self.norm(val)),
- hatch=hatch, linewidth=0,
- antialiased=False, **kw)
- self.ax.add_patch(patch)
- patches.append(patch)
-
- if self.solids_patches:
- for solid in self.solids_patches:
- solid.remove()
-
- self.solids_patches = patches
-
- if self.dividers is not None:
- self.dividers.remove()
- self.dividers = None
-
- if self.drawedges:
- self.dividers = collections.LineCollection(
- self._edges(X, Y),
- colors=(mpl.rcParams['axes.edgecolor'],),
- linewidths=(0.5 * mpl.rcParams['axes.linewidth'],))
- self.ax.add_collection(self.dividers)
-
- self.ax._hold = _hold
-
-
-def colorbar_factory(cax, mappable, **kwargs):
- """
- Creates a colorbar on the given axes for the given mappable.
-
- Typically, for automatic colorbar placement given only a mappable use
- :meth:`~matplotlib.figure.Figure.colorbar`.
-
- """
- # if the given mappable is a contourset with any hatching, use
- # ColorbarPatch else use Colorbar
- if (isinstance(mappable, contour.ContourSet)
- and any([hatch is not None for hatch in mappable.hatches])):
- cb = ColorbarPatch(cax, mappable, **kwargs)
- else:
- cb = Colorbar(cax, mappable, **kwargs)
-
- cid = mappable.callbacksSM.connect('changed', cb.on_mappable_changed)
- mappable.colorbar = cb
- mappable.colorbar_cid = cid
-
- return cb
diff --git a/contrib/python/matplotlib/py2/matplotlib/colors.py b/contrib/python/matplotlib/py2/matplotlib/colors.py
deleted file mode 100644
index d6cd04fdbc..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/colors.py
+++ /dev/null
@@ -1,2030 +0,0 @@
-"""
-A module for converting numbers or color arguments to *RGB* or *RGBA*
-
-*RGB* and *RGBA* are sequences of, respectively, 3 or 4 floats in the
-range 0-1.
-
-This module includes functions and classes for color specification
-conversions, and for mapping numbers to colors in a 1-D array of colors called
-a colormap. Colormapping typically involves two steps: a data array is first
-mapped onto the range 0-1 using an instance of :class:`Normalize` or of a
-subclass; then this number in the 0-1 range is mapped to a color using an
-instance of a subclass of :class:`Colormap`. Two are provided here:
-:class:`LinearSegmentedColormap`, which is used to generate all the built-in
-colormap instances, but is also useful for making custom colormaps, and
-:class:`ListedColormap`, which is used for generating a custom colormap from a
-list of color specifications.
-
-The module also provides functions for checking whether an object can be
-interpreted as a color (:func:`is_color_like`), for converting such an object
-to an RGBA tuple (:func:`to_rgba`) or to an HTML-like hex string in the
-`#rrggbb` format (:func:`to_hex`), and a sequence of colors to an `(n, 4)`
-RGBA array (:func:`to_rgba_array`). Caching is used for efficiency.
-
-Matplotlib recognizes the following formats to specify a color:
-
-* an RGB or RGBA tuple of float values in ``[0, 1]`` (e.g., ``(0.1, 0.2, 0.5)``
- or ``(0.1, 0.2, 0.5, 0.3)``);
-* a hex RGB or RGBA string (e.g., ``'#0F0F0F'`` or ``'#0F0F0F0F'``);
-* a string representation of a float value in ``[0, 1]`` inclusive for gray
- level (e.g., ``'0.5'``);
-* one of ``{'b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'}``;
-* a X11/CSS4 color name;
-* a name from the `xkcd color survey <https://xkcd.com/color/rgb/>`__;
- prefixed with ``'xkcd:'`` (e.g., ``'xkcd:sky blue'``);
-* one of ``{'tab:blue', 'tab:orange', 'tab:green',
- 'tab:red', 'tab:purple', 'tab:brown', 'tab:pink',
- 'tab:gray', 'tab:olive', 'tab:cyan'}`` which are the Tableau Colors from the
- 'T10' categorical palette (which is the default color cycle);
-* a "CN" color spec, i.e. `'C'` followed by a single digit, which is an index
- into the default property cycle (``matplotlib.rcParams['axes.prop_cycle']``);
- the indexing occurs at artist creation time and defaults to black if the
- cycle does not include color.
-
-All string specifications of color, other than "CN", are case-insensitive.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import zip
-
-try:
- from collections.abc import Sized
-except ImportError:
- from collections import Sized
-import itertools
-import re
-import warnings
-
-import numpy as np
-import matplotlib.cbook as cbook
-from ._color_data import BASE_COLORS, TABLEAU_COLORS, CSS4_COLORS, XKCD_COLORS
-
-
-class _ColorMapping(dict):
- def __init__(self, mapping):
- super(_ColorMapping, self).__init__(mapping)
- self.cache = {}
-
- def __setitem__(self, key, value):
- super(_ColorMapping, self).__setitem__(key, value)
- self.cache.clear()
-
- def __delitem__(self, key):
- super(_ColorMapping, self).__delitem__(key)
- self.cache.clear()
-
-
-_colors_full_map = {}
-# Set by reverse priority order.
-_colors_full_map.update(XKCD_COLORS)
-_colors_full_map.update({k.replace('grey', 'gray'): v
- for k, v in XKCD_COLORS.items()
- if 'grey' in k})
-_colors_full_map.update(CSS4_COLORS)
-_colors_full_map.update(TABLEAU_COLORS)
-_colors_full_map.update({k.replace('gray', 'grey'): v
- for k, v in TABLEAU_COLORS.items()
- if 'gray' in k})
-_colors_full_map.update(BASE_COLORS)
-_colors_full_map = _ColorMapping(_colors_full_map)
-
-
-def get_named_colors_mapping():
- """Return the global mapping of names to named colors."""
- return _colors_full_map
-
-
-def _sanitize_extrema(ex):
- if ex is None:
- return ex
- try:
- ret = ex.item()
- except AttributeError:
- ret = float(ex)
- return ret
-
-
-def _is_nth_color(c):
- """Return whether *c* can be interpreted as an item in the color cycle."""
- return isinstance(c, six.string_types) and re.match(r"\AC[0-9]\Z", c)
-
-
-def is_color_like(c):
- """Return whether *c* can be interpreted as an RGB(A) color."""
- # Special-case nth color syntax because it cannot be parsed during
- # setup.
- if _is_nth_color(c):
- return True
- try:
- to_rgba(c)
- except ValueError:
- return False
- else:
- return True
-
-
-def same_color(c1, c2):
- """
- Compare two colors to see if they are the same.
-
- Parameters
- ----------
- c1, c2 : Matplotlib colors
-
- Returns
- -------
- bool
- ``True`` if *c1* and *c2* are the same color, otherwise ``False``.
- """
- return (to_rgba_array(c1) == to_rgba_array(c2)).all()
-
-
-def to_rgba(c, alpha=None):
- """
- Convert *c* to an RGBA color.
-
- Parameters
- ----------
- c : Matplotlib color
-
- alpha : scalar, optional
- If *alpha* is not ``None``, it forces the alpha value, except if *c* is
- ``"none"`` (case-insensitive), which always maps to ``(0, 0, 0, 0)``.
-
- Returns
- -------
- tuple
- Tuple of ``(r, g, b, a)`` scalars.
- """
- # Special-case nth color syntax because it should not be cached.
- if _is_nth_color(c):
- from matplotlib import rcParams
- prop_cycler = rcParams['axes.prop_cycle']
- colors = prop_cycler.by_key().get('color', ['k'])
- c = colors[int(c[1]) % len(colors)]
- try:
- rgba = _colors_full_map.cache[c, alpha]
- except (KeyError, TypeError): # Not in cache, or unhashable.
- rgba = _to_rgba_no_colorcycle(c, alpha)
- try:
- _colors_full_map.cache[c, alpha] = rgba
- except TypeError:
- pass
- return rgba
-
-
-def _to_rgba_no_colorcycle(c, alpha=None):
- """Convert *c* to an RGBA color, with no support for color-cycle syntax.
-
- If *alpha* is not ``None``, it forces the alpha value, except if *c* is
- ``"none"`` (case-insensitive), which always maps to ``(0, 0, 0, 0)``.
- """
- orig_c = c
- if isinstance(c, six.string_types):
- if c.lower() == "none":
- return (0., 0., 0., 0.)
- # Named color.
- try:
- # This may turn c into a non-string, so we check again below.
- c = _colors_full_map[c.lower()]
- except KeyError:
- pass
- if isinstance(c, six.string_types):
- # hex color with no alpha.
- match = re.match(r"\A#[a-fA-F0-9]{6}\Z", c)
- if match:
- return (tuple(int(n, 16) / 255
- for n in [c[1:3], c[3:5], c[5:7]])
- + (alpha if alpha is not None else 1.,))
- # hex color with alpha.
- match = re.match(r"\A#[a-fA-F0-9]{8}\Z", c)
- if match:
- color = [int(n, 16) / 255
- for n in [c[1:3], c[3:5], c[5:7], c[7:9]]]
- if alpha is not None:
- color[-1] = alpha
- return tuple(color)
- # string gray.
- try:
- return (float(c),) * 3 + (alpha if alpha is not None else 1.,)
- except ValueError:
- pass
- raise ValueError("Invalid RGBA argument: {!r}".format(orig_c))
- # tuple color.
- c = np.array(c)
- if not np.can_cast(c.dtype, float, "same_kind") or c.ndim != 1:
- # Test the dtype explicitly as `map(float, ...)`, `np.array(...,
- # float)` and `np.array(...).astype(float)` all convert "0.5" to 0.5.
- # Test dimensionality to reject single floats.
- raise ValueError("Invalid RGBA argument: {!r}".format(orig_c))
- # Return a tuple to prevent the cached value from being modified.
- c = tuple(c.astype(float))
- if len(c) not in [3, 4]:
- raise ValueError("RGBA sequence should have length 3 or 4")
- if len(c) == 3 and alpha is None:
- alpha = 1
- if alpha is not None:
- c = c[:3] + (alpha,)
- if any(elem < 0 or elem > 1 for elem in c):
- raise ValueError("RGBA values should be within 0-1 range")
- return c
-
-
-def to_rgba_array(c, alpha=None):
- """Convert *c* to a (n, 4) array of RGBA colors.
-
- If *alpha* is not ``None``, it forces the alpha value. If *c* is
- ``"none"`` (case-insensitive) or an empty list, an empty array is returned.
- """
- # Special-case inputs that are already arrays, for performance. (If the
- # array has the wrong kind or shape, raise the error during one-at-a-time
- # conversion.)
- if (isinstance(c, np.ndarray) and c.dtype.kind in "if"
- and c.ndim == 2 and c.shape[1] in [3, 4]):
- if c.shape[1] == 3:
- result = np.column_stack([c, np.zeros(len(c))])
- result[:, -1] = alpha if alpha is not None else 1.
- elif c.shape[1] == 4:
- result = c.copy()
- if alpha is not None:
- result[:, -1] = alpha
- if np.any((result < 0) | (result > 1)):
- raise ValueError("RGBA values should be within 0-1 range")
- return result
- # Handle single values.
- # Note that this occurs *after* handling inputs that are already arrays, as
- # `to_rgba(c, alpha)` (below) is expensive for such inputs, due to the need
- # to format the array in the ValueError message(!).
- if isinstance(c, six.string_types) and c.lower() == "none":
- return np.zeros((0, 4), float)
- try:
- return np.array([to_rgba(c, alpha)], float)
- except (ValueError, TypeError):
- pass
- # Convert one at a time.
- result = np.empty((len(c), 4), float)
- for i, cc in enumerate(c):
- result[i] = to_rgba(cc, alpha)
- return result
-
-
-def to_rgb(c):
- """Convert *c* to an RGB color, silently dropping the alpha channel."""
- return to_rgba(c)[:3]
-
-
-def to_hex(c, keep_alpha=False):
- """Convert *c* to a hex color.
-
- Uses the ``#rrggbb`` format if *keep_alpha* is False (the default),
- ``#rrggbbaa`` otherwise.
- """
- c = to_rgba(c)
- if not keep_alpha:
- c = c[:3]
- return "#" + "".join(format(int(np.round(val * 255)), "02x")
- for val in c)
-
-
-### Backwards-compatible color-conversion API
-
-
-cnames = CSS4_COLORS
-hexColorPattern = re.compile(r"\A#[a-fA-F0-9]{6}\Z")
-rgb2hex = to_hex
-hex2color = to_rgb
-
-
-class ColorConverter(object):
- """
- Provides methods for converting color specifications to *RGB* or *RGBA*
-
- Caching is used for more efficient conversion upon repeated calls
- with the same argument.
-
- Ordinarily only the single instance instantiated in this module,
- *colorConverter*, is needed.
- """
-
- colors = _colors_full_map
- cache = _colors_full_map.cache
-
- @staticmethod
- def to_rgb(arg):
- """
- Returns an *RGB* tuple of three floats from 0-1.
-
- *arg* can be an *RGB* or *RGBA* sequence or a string in any of
- several forms:
-
- 1) a letter from the set 'rgbcmykw'
- 2) a hex color string, like '#00FFFF'
- 3) a standard name, like 'aqua'
- 4) a string representation of a float, like '0.4',
- indicating gray on a 0-1 scale
-
- if *arg* is *RGBA*, the *A* will simply be discarded.
- """
- return to_rgb(arg)
-
- @staticmethod
- def to_rgba(arg, alpha=None):
- """
- Returns an *RGBA* tuple of four floats from 0-1.
-
- For acceptable values of *arg*, see :meth:`to_rgb`.
- In addition, if *arg* is "none" (case-insensitive),
- then (0,0,0,0) will be returned.
- If *arg* is an *RGBA* sequence and *alpha* is not *None*,
- *alpha* will replace the original *A*.
- """
- return to_rgba(arg, alpha)
-
- @staticmethod
- def to_rgba_array(arg, alpha=None):
- """
- Returns a numpy array of *RGBA* tuples.
-
- Accepts a single mpl color spec or a sequence of specs.
-
- Special case to handle "no color": if *c* is "none" (case-insensitive),
- then an empty array will be returned. Same for an empty list.
- """
- return to_rgba_array(arg, alpha)
-
-
-colorConverter = ColorConverter()
-
-
-### End of backwards-compatible color-conversion API
-
-
-def makeMappingArray(N, data, gamma=1.0):
- """Create an *N* -element 1-d lookup table
-
- *data* represented by a list of x,y0,y1 mapping correspondences.
- Each element in this list represents how a value between 0 and 1
- (inclusive) represented by x is mapped to a corresponding value
- between 0 and 1 (inclusive). The two values of y are to allow
- for discontinuous mapping functions (say as might be found in a
- sawtooth) where y0 represents the value of y for values of x
- <= to that given, and y1 is the value to be used for x > than
- that given). The list must start with x=0, end with x=1, and
- all values of x must be in increasing order. Values between
- the given mapping points are determined by simple linear interpolation.
-
- Alternatively, data can be a function mapping values between 0 - 1
- to 0 - 1.
-
- The function returns an array "result" where ``result[x*(N-1)]``
- gives the closest value for values of x between 0 and 1.
- """
-
- if callable(data):
- xind = np.linspace(0, 1, N) ** gamma
- lut = np.clip(np.array(data(xind), dtype=float), 0, 1)
- return lut
-
- try:
- adata = np.array(data)
- except Exception:
- raise TypeError("data must be convertible to an array")
- shape = adata.shape
- if len(shape) != 2 or shape[1] != 3:
- raise ValueError("data must be nx3 format")
-
- x = adata[:, 0]
- y0 = adata[:, 1]
- y1 = adata[:, 2]
-
- if x[0] != 0. or x[-1] != 1.0:
- raise ValueError(
- "data mapping points must start with x=0 and end with x=1")
- if (np.diff(x) < 0).any():
- raise ValueError("data mapping points must have x in increasing order")
- # begin generation of lookup table
- x = x * (N - 1)
- lut = np.zeros((N,), float)
- xind = (N - 1) * np.linspace(0, 1, N) ** gamma
- ind = np.searchsorted(x, xind)[1:-1]
-
- distance = (xind[1:-1] - x[ind - 1]) / (x[ind] - x[ind - 1])
- lut[1:-1] = distance * (y0[ind] - y1[ind - 1]) + y1[ind - 1]
- lut[0] = y1[0]
- lut[-1] = y0[-1]
- # ensure that the lut is confined to values between 0 and 1 by clipping it
- return np.clip(lut, 0.0, 1.0)
-
-
-class Colormap(object):
- """
- Baseclass for all scalar to RGBA mappings.
-
- Typically Colormap instances are used to convert data values (floats) from
- the interval ``[0, 1]`` to the RGBA color that the respective Colormap
- represents. For scaling of data into the ``[0, 1]`` interval see
- :class:`matplotlib.colors.Normalize`. It is worth noting that
- :class:`matplotlib.cm.ScalarMappable` subclasses make heavy use of this
- ``data->normalize->map-to-color`` processing chain.
-
- """
- def __init__(self, name, N=256):
- """
- Parameters
- ----------
- name : str
- The name of the colormap.
- N : int
- The number of rgb quantization levels.
-
- """
- self.name = name
- self.N = int(N) # ensure that N is always int
- self._rgba_bad = (0.0, 0.0, 0.0, 0.0) # If bad, don't paint anything.
- self._rgba_under = None
- self._rgba_over = None
- self._i_under = self.N
- self._i_over = self.N + 1
- self._i_bad = self.N + 2
- self._isinit = False
-
- #: When this colormap exists on a scalar mappable and colorbar_extend
- #: is not False, colorbar creation will pick up ``colorbar_extend`` as
- #: the default value for the ``extend`` keyword in the
- #: :class:`matplotlib.colorbar.Colorbar` constructor.
- self.colorbar_extend = False
-
- def __call__(self, X, alpha=None, bytes=False):
- """
- Parameters
- ----------
- X : scalar, ndarray
- The data value(s) to convert to RGBA.
- For floats, X should be in the interval ``[0.0, 1.0]`` to
- return the RGBA values ``X*100`` percent along the Colormap line.
- For integers, X should be in the interval ``[0, Colormap.N)`` to
- return RGBA values *indexed* from the Colormap with index ``X``.
- alpha : float, None
- Alpha must be a scalar between 0 and 1, or None.
- bytes : bool
- If False (default), the returned RGBA values will be floats in the
- interval ``[0, 1]`` otherwise they will be uint8s in the interval
- ``[0, 255]``.
-
- Returns
- -------
- Tuple of RGBA values if X is scalar, otherwise an array of
- RGBA values with a shape of ``X.shape + (4, )``.
-
- """
- # See class docstring for arg/kwarg documentation.
- if not self._isinit:
- self._init()
- mask_bad = None
- if not cbook.iterable(X):
- vtype = 'scalar'
- xa = np.array([X])
- else:
- vtype = 'array'
- xma = np.ma.array(X, copy=True) # Copy here to avoid side effects.
- mask_bad = xma.mask # Mask will be used below.
- xa = xma.filled() # Fill to avoid infs, etc.
- del xma
-
- # Calculations with native byteorder are faster, and avoid a
- # bug that otherwise can occur with putmask when the last
- # argument is a numpy scalar.
- if not xa.dtype.isnative:
- xa = xa.byteswap().newbyteorder()
-
- if xa.dtype.kind == "f":
- xa *= self.N
- # Negative values are out of range, but astype(int) would truncate
- # them towards zero.
- xa[xa < 0] = -1
- # xa == 1 (== N after multiplication) is not out of range.
- xa[xa == self.N] = self.N - 1
- # Avoid converting large positive values to negative integers.
- np.clip(xa, -1, self.N, out=xa)
- xa = xa.astype(int)
- # Set the over-range indices before the under-range;
- # otherwise the under-range values get converted to over-range.
- xa[xa > self.N - 1] = self._i_over
- xa[xa < 0] = self._i_under
- if mask_bad is not None:
- if mask_bad.shape == xa.shape:
- np.copyto(xa, self._i_bad, where=mask_bad)
- elif mask_bad:
- xa.fill(self._i_bad)
- if bytes:
- lut = (self._lut * 255).astype(np.uint8)
- else:
- lut = self._lut.copy() # Don't let alpha modify original _lut.
-
- if alpha is not None:
- alpha = min(alpha, 1.0) # alpha must be between 0 and 1
- alpha = max(alpha, 0.0)
- if bytes:
- alpha = int(alpha * 255)
- if (lut[-1] == 0).all():
- lut[:-1, -1] = alpha
- # All zeros is taken as a flag for the default bad
- # color, which is no color--fully transparent. We
- # don't want to override this.
- else:
- lut[:, -1] = alpha
- # If the bad value is set to have a color, then we
- # override its alpha just as for any other value.
-
- rgba = np.empty(shape=xa.shape + (4,), dtype=lut.dtype)
- lut.take(xa, axis=0, mode='clip', out=rgba)
- if vtype == 'scalar':
- rgba = tuple(rgba[0, :])
- return rgba
-
- def __copy__(self):
- """Create new object with the same class, update attributes
- """
- cls = self.__class__
- cmapobject = cls.__new__(cls)
- cmapobject.__dict__.update(self.__dict__)
- if self._isinit:
- cmapobject._lut = np.copy(self._lut)
- return cmapobject
-
- def set_bad(self, color='k', alpha=None):
- """Set color to be used for masked values.
- """
- self._rgba_bad = colorConverter.to_rgba(color, alpha)
- if self._isinit:
- self._set_extremes()
-
- def set_under(self, color='k', alpha=None):
- """Set color to be used for low out-of-range values.
- Requires norm.clip = False
- """
- self._rgba_under = colorConverter.to_rgba(color, alpha)
- if self._isinit:
- self._set_extremes()
-
- def set_over(self, color='k', alpha=None):
- """Set color to be used for high out-of-range values.
- Requires norm.clip = False
- """
- self._rgba_over = colorConverter.to_rgba(color, alpha)
- if self._isinit:
- self._set_extremes()
-
- def _set_extremes(self):
- if self._rgba_under:
- self._lut[self._i_under] = self._rgba_under
- else:
- self._lut[self._i_under] = self._lut[0]
- if self._rgba_over:
- self._lut[self._i_over] = self._rgba_over
- else:
- self._lut[self._i_over] = self._lut[self.N - 1]
- self._lut[self._i_bad] = self._rgba_bad
-
- def _init(self):
- """Generate the lookup table, self._lut"""
- raise NotImplementedError("Abstract class only")
-
- def is_gray(self):
- if not self._isinit:
- self._init()
- return (np.all(self._lut[:, 0] == self._lut[:, 1]) and
- np.all(self._lut[:, 0] == self._lut[:, 2]))
-
- def _resample(self, lutsize):
- """
- Return a new color map with *lutsize* entries.
- """
- raise NotImplementedError()
-
- def reversed(self, name=None):
- """
- Make a reversed instance of the Colormap.
-
- .. note :: Function not implemented for base class.
-
- Parameters
- ----------
- name : str, optional
- The name for the reversed colormap. If it's None the
- name will be the name of the parent colormap + "_r".
-
- Notes
- -----
- See :meth:`LinearSegmentedColormap.reversed` and
- :meth:`ListedColormap.reversed`
- """
- raise NotImplementedError()
-
-
-class LinearSegmentedColormap(Colormap):
- """Colormap objects based on lookup tables using linear segments.
-
- The lookup table is generated using linear interpolation for each
- primary color, with the 0-1 domain divided into any number of
- segments.
- """
- def __init__(self, name, segmentdata, N=256, gamma=1.0):
- """Create color map from linear mapping segments
-
- segmentdata argument is a dictionary with a red, green and blue
- entries. Each entry should be a list of *x*, *y0*, *y1* tuples,
- forming rows in a table. Entries for alpha are optional.
-
- Example: suppose you want red to increase from 0 to 1 over
- the bottom half, green to do the same over the middle half,
- and blue over the top half. Then you would use::
-
- cdict = {'red': [(0.0, 0.0, 0.0),
- (0.5, 1.0, 1.0),
- (1.0, 1.0, 1.0)],
-
- 'green': [(0.0, 0.0, 0.0),
- (0.25, 0.0, 0.0),
- (0.75, 1.0, 1.0),
- (1.0, 1.0, 1.0)],
-
- 'blue': [(0.0, 0.0, 0.0),
- (0.5, 0.0, 0.0),
- (1.0, 1.0, 1.0)]}
-
- Each row in the table for a given color is a sequence of
- *x*, *y0*, *y1* tuples. In each sequence, *x* must increase
- monotonically from 0 to 1. For any input value *z* falling
- between *x[i]* and *x[i+1]*, the output value of a given color
- will be linearly interpolated between *y1[i]* and *y0[i+1]*::
-
- row i: x y0 y1
- /
- /
- row i+1: x y0 y1
-
- Hence y0 in the first row and y1 in the last row are never used.
-
-
- .. seealso::
-
- :meth:`LinearSegmentedColormap.from_list`
- Static method; factory function for generating a
- smoothly-varying LinearSegmentedColormap.
-
- :func:`makeMappingArray`
- For information about making a mapping array.
- """
- # True only if all colors in map are identical; needed for contouring.
- self.monochrome = False
- Colormap.__init__(self, name, N)
- self._segmentdata = segmentdata
- self._gamma = gamma
-
- def _init(self):
- self._lut = np.ones((self.N + 3, 4), float)
- self._lut[:-3, 0] = makeMappingArray(
- self.N, self._segmentdata['red'], self._gamma)
- self._lut[:-3, 1] = makeMappingArray(
- self.N, self._segmentdata['green'], self._gamma)
- self._lut[:-3, 2] = makeMappingArray(
- self.N, self._segmentdata['blue'], self._gamma)
- if 'alpha' in self._segmentdata:
- self._lut[:-3, 3] = makeMappingArray(
- self.N, self._segmentdata['alpha'], 1)
- self._isinit = True
- self._set_extremes()
-
- def set_gamma(self, gamma):
- """
- Set a new gamma value and regenerate color map.
- """
- self._gamma = gamma
- self._init()
-
- @staticmethod
- def from_list(name, colors, N=256, gamma=1.0):
- """
- Make a linear segmented colormap with *name* from a sequence
- of *colors* which evenly transitions from colors[0] at val=0
- to colors[-1] at val=1. *N* is the number of rgb quantization
- levels.
- Alternatively, a list of (value, color) tuples can be given
- to divide the range unevenly.
- """
-
- if not cbook.iterable(colors):
- raise ValueError('colors must be iterable')
-
- if (isinstance(colors[0], Sized) and len(colors[0]) == 2
- and not isinstance(colors[0], six.string_types)):
- # List of value, color pairs
- vals, colors = zip(*colors)
- else:
- vals = np.linspace(0, 1, len(colors))
-
- cdict = dict(red=[], green=[], blue=[], alpha=[])
- for val, color in zip(vals, colors):
- r, g, b, a = colorConverter.to_rgba(color)
- cdict['red'].append((val, r, r))
- cdict['green'].append((val, g, g))
- cdict['blue'].append((val, b, b))
- cdict['alpha'].append((val, a, a))
-
- return LinearSegmentedColormap(name, cdict, N, gamma)
-
- def _resample(self, lutsize):
- """
- Return a new color map with *lutsize* entries.
- """
- return LinearSegmentedColormap(self.name, self._segmentdata, lutsize)
-
- def reversed(self, name=None):
- """
- Make a reversed instance of the Colormap.
-
- Parameters
- ----------
- name : str, optional
- The name for the reversed colormap. If it's None the
- name will be the name of the parent colormap + "_r".
-
- Returns
- -------
- LinearSegmentedColormap
- The reversed colormap.
- """
- if name is None:
- name = self.name + "_r"
-
- # Function factory needed to deal with 'late binding' issue.
- def factory(dat):
- def func_r(x):
- return dat(1.0 - x)
- return func_r
-
- data_r = dict()
- for key, data in six.iteritems(self._segmentdata):
- if callable(data):
- data_r[key] = factory(data)
- else:
- new_data = [(1.0 - x, y1, y0) for x, y0, y1 in reversed(data)]
- data_r[key] = new_data
-
- return LinearSegmentedColormap(name, data_r, self.N, self._gamma)
-
-
-class ListedColormap(Colormap):
- """Colormap object generated from a list of colors.
-
- This may be most useful when indexing directly into a colormap,
- but it can also be used to generate special colormaps for ordinary
- mapping.
- """
- def __init__(self, colors, name='from_list', N=None):
- """
- Make a colormap from a list of colors.
-
- *colors*
- a list of matplotlib color specifications,
- or an equivalent Nx3 or Nx4 floating point array
- (*N* rgb or rgba values)
- *name*
- a string to identify the colormap
- *N*
- the number of entries in the map. The default is *None*,
- in which case there is one colormap entry for each
- element in the list of colors. If::
-
- N < len(colors)
-
- the list will be truncated at *N*. If::
-
- N > len(colors)
-
- the list will be extended by repetition.
- """
- self.monochrome = False # True only if all colors in map are
- # identical; needed for contouring.
- if N is None:
- self.colors = colors
- N = len(colors)
- else:
- if isinstance(colors, six.string_types):
- self.colors = [colors] * N
- self.monochrome = True
- elif cbook.iterable(colors):
- if len(colors) == 1:
- self.monochrome = True
- self.colors = list(
- itertools.islice(itertools.cycle(colors), N))
- else:
- try:
- gray = float(colors)
- except TypeError:
- pass
- else:
- self.colors = [gray] * N
- self.monochrome = True
- Colormap.__init__(self, name, N)
-
- def _init(self):
- rgba = colorConverter.to_rgba_array(self.colors)
- self._lut = np.zeros((self.N + 3, 4), float)
- self._lut[:-3] = rgba
- self._isinit = True
- self._set_extremes()
-
- def _resample(self, lutsize):
- """
- Return a new color map with *lutsize* entries.
- """
- colors = self(np.linspace(0, 1, lutsize))
- return ListedColormap(colors, name=self.name)
-
- def reversed(self, name=None):
- """
- Make a reversed instance of the Colormap.
-
- Parameters
- ----------
- name : str, optional
- The name for the reversed colormap. If it's None the
- name will be the name of the parent colormap + "_r".
-
- Returns
- -------
- ListedColormap
- A reversed instance of the colormap.
- """
- if name is None:
- name = self.name + "_r"
-
- colors_r = list(reversed(self.colors))
- return ListedColormap(colors_r, name=name, N=self.N)
-
-
-class Normalize(object):
- """
- A class which, when called, can normalize data into
- the ``[0.0, 1.0]`` interval.
-
- """
- def __init__(self, vmin=None, vmax=None, clip=False):
- """
- If *vmin* or *vmax* is not given, they are initialized from the
- minimum and maximum value respectively of the first input
- processed. That is, *__call__(A)* calls *autoscale_None(A)*.
- If *clip* is *True* and the given value falls outside the range,
- the returned value will be 0 or 1, whichever is closer.
- Returns 0 if::
-
- vmin==vmax
-
- Works with scalars or arrays, including masked arrays. If
- *clip* is *True*, masked values are set to 1; otherwise they
- remain masked. Clipping silently defeats the purpose of setting
- the over, under, and masked colors in the colormap, so it is
- likely to lead to surprises; therefore the default is
- *clip* = *False*.
- """
- self.vmin = _sanitize_extrema(vmin)
- self.vmax = _sanitize_extrema(vmax)
- self.clip = clip
-
- @staticmethod
- def process_value(value):
- """
- Homogenize the input *value* for easy and efficient normalization.
-
- *value* can be a scalar or sequence.
-
- Returns *result*, *is_scalar*, where *result* is a
- masked array matching *value*. Float dtypes are preserved;
- integer types with two bytes or smaller are converted to
- np.float32, and larger types are converted to np.float64.
- Preserving float32 when possible, and using in-place operations,
- can greatly improve speed for large arrays.
-
- Experimental; we may want to add an option to force the
- use of float32.
- """
- is_scalar = not cbook.iterable(value)
- if is_scalar:
- value = [value]
- dtype = np.min_scalar_type(value)
- if np.issubdtype(dtype, np.integer) or dtype.type is np.bool_:
- # bool_/int8/int16 -> float32; int32/int64 -> float64
- dtype = np.promote_types(dtype, np.float32)
- # ensure data passed in as an ndarray subclass are interpreted as
- # an ndarray. See issue #6622.
- mask = np.ma.getmask(value)
- data = np.asarray(np.ma.getdata(value))
- result = np.ma.array(data, mask=mask, dtype=dtype, copy=True)
- return result, is_scalar
-
- def __call__(self, value, clip=None):
- """
- Normalize *value* data in the ``[vmin, vmax]`` interval into
- the ``[0.0, 1.0]`` interval and return it. *clip* defaults
- to *self.clip* (which defaults to *False*). If not already
- initialized, *vmin* and *vmax* are initialized using
- *autoscale_None(value)*.
- """
- if clip is None:
- clip = self.clip
-
- result, is_scalar = self.process_value(value)
-
- self.autoscale_None(result)
- # Convert at least to float, without losing precision.
- (vmin,), _ = self.process_value(self.vmin)
- (vmax,), _ = self.process_value(self.vmax)
- if vmin == vmax:
- result.fill(0) # Or should it be all masked? Or 0.5?
- elif vmin > vmax:
- raise ValueError("minvalue must be less than or equal to maxvalue")
- else:
- if clip:
- mask = np.ma.getmask(result)
- result = np.ma.array(np.clip(result.filled(vmax), vmin, vmax),
- mask=mask)
- # ma division is very slow; we can take a shortcut
- resdat = result.data
- resdat -= vmin
- resdat /= (vmax - vmin)
- result = np.ma.array(resdat, mask=result.mask, copy=False)
- # Agg cannot handle float128. We actually only need 32-bit of
- # precision, but on Windows, `np.dtype(np.longdouble) == np.float64`,
- # so casting to float32 would lose precision on float64s as well.
- if result.dtype == np.longdouble:
- result = result.astype(np.float64)
- if is_scalar:
- result = result[0]
- return result
-
- def inverse(self, value):
- if not self.scaled():
- raise ValueError("Not invertible until scaled")
- (vmin,), _ = self.process_value(self.vmin)
- (vmax,), _ = self.process_value(self.vmax)
-
- if cbook.iterable(value):
- val = np.ma.asarray(value)
- return vmin + val * (vmax - vmin)
- else:
- return vmin + value * (vmax - vmin)
-
- def autoscale(self, A):
- """
- Set *vmin*, *vmax* to min, max of *A*.
- """
- A = np.asanyarray(A)
- self.vmin = A.min()
- self.vmax = A.max()
-
- def autoscale_None(self, A):
- """autoscale only None-valued vmin or vmax."""
- A = np.asanyarray(A)
- if self.vmin is None and A.size:
- self.vmin = A.min()
- if self.vmax is None and A.size:
- self.vmax = A.max()
-
- def scaled(self):
- 'return true if vmin and vmax set'
- return (self.vmin is not None and self.vmax is not None)
-
-
-class LogNorm(Normalize):
- """
- Normalize a given value to the 0-1 range on a log scale
- """
- def __call__(self, value, clip=None):
- if clip is None:
- clip = self.clip
-
- result, is_scalar = self.process_value(value)
-
- result = np.ma.masked_less_equal(result, 0, copy=False)
-
- self.autoscale_None(result)
- vmin, vmax = self.vmin, self.vmax
- if vmin > vmax:
- raise ValueError("minvalue must be less than or equal to maxvalue")
- elif vmin <= 0:
- raise ValueError("values must all be positive")
- elif vmin == vmax:
- result.fill(0)
- else:
- if clip:
- mask = np.ma.getmask(result)
- result = np.ma.array(np.clip(result.filled(vmax), vmin, vmax),
- mask=mask)
- # in-place equivalent of above can be much faster
- resdat = result.data
- mask = result.mask
- if mask is np.ma.nomask:
- mask = (resdat <= 0)
- else:
- mask |= resdat <= 0
- np.copyto(resdat, 1, where=mask)
- np.log(resdat, resdat)
- resdat -= np.log(vmin)
- resdat /= (np.log(vmax) - np.log(vmin))
- result = np.ma.array(resdat, mask=mask, copy=False)
- if is_scalar:
- result = result[0]
- return result
-
- def inverse(self, value):
- if not self.scaled():
- raise ValueError("Not invertible until scaled")
- vmin, vmax = self.vmin, self.vmax
-
- if cbook.iterable(value):
- val = np.ma.asarray(value)
- return vmin * np.ma.power((vmax / vmin), val)
- else:
- return vmin * pow((vmax / vmin), value)
-
- def autoscale(self, A):
- """
- Set *vmin*, *vmax* to min, max of *A*.
- """
- A = np.ma.masked_less_equal(A, 0, copy=False)
- self.vmin = np.ma.min(A)
- self.vmax = np.ma.max(A)
-
- def autoscale_None(self, A):
- """autoscale only None-valued vmin or vmax."""
- if self.vmin is not None and self.vmax is not None:
- return
- A = np.ma.masked_less_equal(A, 0, copy=False)
- if self.vmin is None and A.size:
- self.vmin = A.min()
- if self.vmax is None and A.size:
- self.vmax = A.max()
-
-
-class SymLogNorm(Normalize):
- """
- The symmetrical logarithmic scale is logarithmic in both the
- positive and negative directions from the origin.
-
- Since the values close to zero tend toward infinity, there is a
- need to have a range around zero that is linear. The parameter
- *linthresh* allows the user to specify the size of this range
- (-*linthresh*, *linthresh*).
- """
- def __init__(self, linthresh, linscale=1.0,
- vmin=None, vmax=None, clip=False):
- """
- *linthresh*:
- The range within which the plot is linear (to
- avoid having the plot go to infinity around zero).
-
- *linscale*:
- This allows the linear range (-*linthresh* to *linthresh*)
- to be stretched relative to the logarithmic range. Its
- value is the number of decades to use for each half of the
- linear range. For example, when *linscale* == 1.0 (the
- default), the space used for the positive and negative
- halves of the linear range will be equal to one decade in
- the logarithmic range. Defaults to 1.
- """
- Normalize.__init__(self, vmin, vmax, clip)
- self.linthresh = float(linthresh)
- self._linscale_adj = (linscale / (1.0 - np.e ** -1))
- if vmin is not None and vmax is not None:
- self._transform_vmin_vmax()
-
- def __call__(self, value, clip=None):
- if clip is None:
- clip = self.clip
-
- result, is_scalar = self.process_value(value)
- self.autoscale_None(result)
- vmin, vmax = self.vmin, self.vmax
-
- if vmin > vmax:
- raise ValueError("minvalue must be less than or equal to maxvalue")
- elif vmin == vmax:
- result.fill(0)
- else:
- if clip:
- mask = np.ma.getmask(result)
- result = np.ma.array(np.clip(result.filled(vmax), vmin, vmax),
- mask=mask)
- # in-place equivalent of above can be much faster
- resdat = self._transform(result.data)
- resdat -= self._lower
- resdat /= (self._upper - self._lower)
-
- if is_scalar:
- result = result[0]
- return result
-
- def _transform(self, a):
- """
- Inplace transformation.
- """
- masked = np.abs(a) > self.linthresh
- sign = np.sign(a[masked])
- log = (self._linscale_adj + np.log(np.abs(a[masked]) / self.linthresh))
- log *= sign * self.linthresh
- a[masked] = log
- a[~masked] *= self._linscale_adj
- return a
-
- def _inv_transform(self, a):
- """
- Inverse inplace Transformation.
- """
- masked = np.abs(a) > (self.linthresh * self._linscale_adj)
- sign = np.sign(a[masked])
- exp = np.exp(sign * a[masked] / self.linthresh - self._linscale_adj)
- exp *= sign * self.linthresh
- a[masked] = exp
- a[~masked] /= self._linscale_adj
- return a
-
- def _transform_vmin_vmax(self):
- """
- Calculates vmin and vmax in the transformed system.
- """
- vmin, vmax = self.vmin, self.vmax
- arr = np.array([vmax, vmin]).astype(float)
- self._upper, self._lower = self._transform(arr)
-
- def inverse(self, value):
- if not self.scaled():
- raise ValueError("Not invertible until scaled")
- val = np.ma.asarray(value)
- val = val * (self._upper - self._lower) + self._lower
- return self._inv_transform(val)
-
- def autoscale(self, A):
- """
- Set *vmin*, *vmax* to min, max of *A*.
- """
- self.vmin = np.ma.min(A)
- self.vmax = np.ma.max(A)
- self._transform_vmin_vmax()
-
- def autoscale_None(self, A):
- """autoscale only None-valued vmin or vmax."""
- if self.vmin is not None and self.vmax is not None:
- pass
- A = np.asanyarray(A)
- if self.vmin is None and A.size:
- self.vmin = A.min()
- if self.vmax is None and A.size:
- self.vmax = A.max()
- self._transform_vmin_vmax()
-
-
-class PowerNorm(Normalize):
- """
- Normalize a given value to the ``[0, 1]`` interval with a power-law
- scaling. This will clip any negative data points to 0.
- """
- def __init__(self, gamma, vmin=None, vmax=None, clip=False):
- Normalize.__init__(self, vmin, vmax, clip)
- self.gamma = gamma
-
- def __call__(self, value, clip=None):
- if clip is None:
- clip = self.clip
-
- result, is_scalar = self.process_value(value)
-
- self.autoscale_None(result)
- gamma = self.gamma
- vmin, vmax = self.vmin, self.vmax
- if vmin > vmax:
- raise ValueError("minvalue must be less than or equal to maxvalue")
- elif vmin == vmax:
- result.fill(0)
- else:
- res_mask = result.data < 0
- if clip:
- mask = np.ma.getmask(result)
- result = np.ma.array(np.clip(result.filled(vmax), vmin, vmax),
- mask=mask)
- resdat = result.data
- resdat -= vmin
- np.power(resdat, gamma, resdat)
- resdat /= (vmax - vmin) ** gamma
-
- result = np.ma.array(resdat, mask=result.mask, copy=False)
- result[res_mask] = 0
- if is_scalar:
- result = result[0]
- return result
-
- def inverse(self, value):
- if not self.scaled():
- raise ValueError("Not invertible until scaled")
- gamma = self.gamma
- vmin, vmax = self.vmin, self.vmax
-
- if cbook.iterable(value):
- val = np.ma.asarray(value)
- return np.ma.power(val, 1. / gamma) * (vmax - vmin) + vmin
- else:
- return pow(value, 1. / gamma) * (vmax - vmin) + vmin
-
- def autoscale(self, A):
- """
- Set *vmin*, *vmax* to min, max of *A*.
- """
- self.vmin = np.ma.min(A)
- if self.vmin < 0:
- self.vmin = 0
- warnings.warn("Power-law scaling on negative values is "
- "ill-defined, clamping to 0.")
- self.vmax = np.ma.max(A)
-
- def autoscale_None(self, A):
- """autoscale only None-valued vmin or vmax."""
- A = np.asanyarray(A)
- if self.vmin is None and A.size:
- self.vmin = A.min()
- if self.vmin < 0:
- self.vmin = 0
- warnings.warn("Power-law scaling on negative values is "
- "ill-defined, clamping to 0.")
- if self.vmax is None and A.size:
- self.vmax = A.max()
-
-
-class BoundaryNorm(Normalize):
- """
- Generate a colormap index based on discrete intervals.
-
- Unlike :class:`Normalize` or :class:`LogNorm`,
- :class:`BoundaryNorm` maps values to integers instead of to the
- interval 0-1.
-
- Mapping to the 0-1 interval could have been done via
- piece-wise linear interpolation, but using integers seems
- simpler, and reduces the number of conversions back and forth
- between integer and floating point.
- """
- def __init__(self, boundaries, ncolors, clip=False):
- """
- Parameters
- ----------
- boundaries : array-like
- Monotonically increasing sequence of boundaries
- ncolors : int
- Number of colors in the colormap to be used
- clip : bool, optional
- If clip is ``True``, out of range values are mapped to 0 if they
- are below ``boundaries[0]`` or mapped to ncolors - 1 if they are
- above ``boundaries[-1]``.
-
- If clip is ``False``, out of range values are mapped to -1 if
- they are below ``boundaries[0]`` or mapped to ncolors if they are
- above ``boundaries[-1]``. These are then converted to valid indices
- by :meth:`Colormap.__call__`.
-
- Notes
- -----
- *boundaries* defines the edges of bins, and data falling within a bin
- is mapped to the color with the same index.
-
- If the number of bins doesn't equal *ncolors*, the color is chosen
- by linear interpolation of the bin number onto color numbers.
- """
- self.clip = clip
- self.vmin = boundaries[0]
- self.vmax = boundaries[-1]
- self.boundaries = np.asarray(boundaries)
- self.N = len(self.boundaries)
- self.Ncmap = ncolors
- if self.N - 1 == self.Ncmap:
- self._interp = False
- else:
- self._interp = True
-
- def __call__(self, value, clip=None):
- if clip is None:
- clip = self.clip
-
- xx, is_scalar = self.process_value(value)
- mask = np.ma.getmaskarray(xx)
- xx = np.atleast_1d(xx.filled(self.vmax + 1))
- if clip:
- np.clip(xx, self.vmin, self.vmax, out=xx)
- max_col = self.Ncmap - 1
- else:
- max_col = self.Ncmap
- iret = np.zeros(xx.shape, dtype=np.int16)
- for i, b in enumerate(self.boundaries):
- iret[xx >= b] = i
- if self._interp:
- scalefac = (self.Ncmap - 1) / (self.N - 2)
- iret = (iret * scalefac).astype(np.int16)
- iret[xx < self.vmin] = -1
- iret[xx >= self.vmax] = max_col
- ret = np.ma.array(iret, mask=mask)
- if is_scalar:
- ret = int(ret[0]) # assume python scalar
- return ret
-
- def inverse(self, value):
- """
- Raises
- ------
- ValueError
- BoundaryNorm is not invertible, so calling this method will always
- raise an error
- """
- return ValueError("BoundaryNorm is not invertible")
-
-
-class NoNorm(Normalize):
- """
- Dummy replacement for Normalize, for the case where we
- want to use indices directly in a
- :class:`~matplotlib.cm.ScalarMappable` .
- """
- def __call__(self, value, clip=None):
- return value
-
- def inverse(self, value):
- return value
-
-
-def rgb_to_hsv(arr):
- """
- convert float rgb values (in the range [0, 1]), in a numpy array to hsv
- values.
-
- Parameters
- ----------
- arr : (..., 3) array-like
- All values must be in the range [0, 1]
-
- Returns
- -------
- hsv : (..., 3) ndarray
- Colors converted to hsv values in range [0, 1]
- """
- # make sure it is an ndarray
- arr = np.asarray(arr)
-
- # check length of the last dimension, should be _some_ sort of rgb
- if arr.shape[-1] != 3:
- raise ValueError("Last dimension of input array must be 3; "
- "shape {} was found.".format(arr.shape))
-
- in_ndim = arr.ndim
- if arr.ndim == 1:
- arr = np.array(arr, ndmin=2)
-
- # make sure we don't have an int image
- arr = arr.astype(np.promote_types(arr.dtype, np.float32))
-
- out = np.zeros_like(arr)
- arr_max = arr.max(-1)
- ipos = arr_max > 0
- delta = arr.ptp(-1)
- s = np.zeros_like(delta)
- s[ipos] = delta[ipos] / arr_max[ipos]
- ipos = delta > 0
- # red is max
- idx = (arr[..., 0] == arr_max) & ipos
- out[idx, 0] = (arr[idx, 1] - arr[idx, 2]) / delta[idx]
- # green is max
- idx = (arr[..., 1] == arr_max) & ipos
- out[idx, 0] = 2. + (arr[idx, 2] - arr[idx, 0]) / delta[idx]
- # blue is max
- idx = (arr[..., 2] == arr_max) & ipos
- out[idx, 0] = 4. + (arr[idx, 0] - arr[idx, 1]) / delta[idx]
-
- out[..., 0] = (out[..., 0] / 6.0) % 1.0
- out[..., 1] = s
- out[..., 2] = arr_max
-
- if in_ndim == 1:
- out.shape = (3,)
-
- return out
-
-
-def hsv_to_rgb(hsv):
- """
- convert hsv values in a numpy array to rgb values
- all values assumed to be in range [0, 1]
-
- Parameters
- ----------
- hsv : (..., 3) array-like
- All values assumed to be in range [0, 1]
-
- Returns
- -------
- rgb : (..., 3) ndarray
- Colors converted to RGB values in range [0, 1]
- """
- hsv = np.asarray(hsv)
-
- # check length of the last dimension, should be _some_ sort of rgb
- if hsv.shape[-1] != 3:
- raise ValueError("Last dimension of input array must be 3; "
- "shape {shp} was found.".format(shp=hsv.shape))
-
- # if we got passed a 1D array, try to treat as
- # a single color and reshape as needed
- in_ndim = hsv.ndim
- if in_ndim == 1:
- hsv = np.array(hsv, ndmin=2)
-
- # make sure we don't have an int image
- hsv = hsv.astype(np.promote_types(hsv.dtype, np.float32))
-
- h = hsv[..., 0]
- s = hsv[..., 1]
- v = hsv[..., 2]
-
- r = np.empty_like(h)
- g = np.empty_like(h)
- b = np.empty_like(h)
-
- i = (h * 6.0).astype(int)
- f = (h * 6.0) - i
- p = v * (1.0 - s)
- q = v * (1.0 - s * f)
- t = v * (1.0 - s * (1.0 - f))
-
- idx = i % 6 == 0
- r[idx] = v[idx]
- g[idx] = t[idx]
- b[idx] = p[idx]
-
- idx = i == 1
- r[idx] = q[idx]
- g[idx] = v[idx]
- b[idx] = p[idx]
-
- idx = i == 2
- r[idx] = p[idx]
- g[idx] = v[idx]
- b[idx] = t[idx]
-
- idx = i == 3
- r[idx] = p[idx]
- g[idx] = q[idx]
- b[idx] = v[idx]
-
- idx = i == 4
- r[idx] = t[idx]
- g[idx] = p[idx]
- b[idx] = v[idx]
-
- idx = i == 5
- r[idx] = v[idx]
- g[idx] = p[idx]
- b[idx] = q[idx]
-
- idx = s == 0
- r[idx] = v[idx]
- g[idx] = v[idx]
- b[idx] = v[idx]
-
- # `np.stack([r, g, b], axis=-1)` (numpy 1.10).
- rgb = np.concatenate([r[..., None], g[..., None], b[..., None]], -1)
-
- if in_ndim == 1:
- rgb.shape = (3,)
-
- return rgb
-
-
-def _vector_magnitude(arr):
- # things that don't work here:
- # * np.linalg.norm
- # - doesn't broadcast in numpy 1.7
- # - drops the mask from ma.array
- # * using keepdims - broken on ma.array until 1.11.2
- # * using sum - discards mask on ma.array unless entire vector is masked
-
- sum_sq = 0
- for i in range(arr.shape[-1]):
- sum_sq += np.square(arr[..., i, np.newaxis])
- return np.sqrt(sum_sq)
-
-
-def _vector_dot(a, b):
- # things that don't work here:
- # * a.dot(b) - fails on masked arrays until 1.10
- # * np.ma.dot(a, b) - doesn't mask enough things
- # * np.ma.dot(a, b, strict=True) - returns a maskedarray with no mask
- dot = 0
- for i in range(a.shape[-1]):
- dot += a[..., i] * b[..., i]
- return dot
-
-
-class LightSource(object):
- """
- Create a light source coming from the specified azimuth and elevation.
- Angles are in degrees, with the azimuth measured
- clockwise from north and elevation up from the zero plane of the surface.
-
- The :meth:`shade` is used to produce "shaded" rgb values for a data array.
- :meth:`shade_rgb` can be used to combine an rgb image with
- The :meth:`shade_rgb`
- The :meth:`hillshade` produces an illumination map of a surface.
- """
- def __init__(self, azdeg=315, altdeg=45, hsv_min_val=0, hsv_max_val=1,
- hsv_min_sat=1, hsv_max_sat=0):
- """
- Specify the azimuth (measured clockwise from south) and altitude
- (measured up from the plane of the surface) of the light source
- in degrees.
-
- Parameters
- ----------
- azdeg : number, optional
- The azimuth (0-360, degrees clockwise from North) of the light
- source. Defaults to 315 degrees (from the northwest).
- altdeg : number, optional
- The altitude (0-90, degrees up from horizontal) of the light
- source. Defaults to 45 degrees from horizontal.
-
- Notes
- -----
- For backwards compatibility, the parameters *hsv_min_val*,
- *hsv_max_val*, *hsv_min_sat*, and *hsv_max_sat* may be supplied at
- initialization as well. However, these parameters will only be used if
- "blend_mode='hsv'" is passed into :meth:`shade` or :meth:`shade_rgb`.
- See the documentation for :meth:`blend_hsv` for more details.
- """
- self.azdeg = azdeg
- self.altdeg = altdeg
- self.hsv_min_val = hsv_min_val
- self.hsv_max_val = hsv_max_val
- self.hsv_min_sat = hsv_min_sat
- self.hsv_max_sat = hsv_max_sat
-
- @property
- def direction(self):
- """ The unit vector direction towards the light source """
-
- # Azimuth is in degrees clockwise from North. Convert to radians
- # counterclockwise from East (mathematical notation).
- az = np.radians(90 - self.azdeg)
- alt = np.radians(self.altdeg)
-
- return np.array([
- np.cos(az) * np.cos(alt),
- np.sin(az) * np.cos(alt),
- np.sin(alt)
- ])
-
- def hillshade(self, elevation, vert_exag=1, dx=1, dy=1, fraction=1.):
- """
- Calculates the illumination intensity for a surface using the defined
- azimuth and elevation for the light source.
-
- This computes the normal vectors for the surface, and then passes them
- on to `shade_normals`
-
- Parameters
- ----------
- elevation : array-like
- A 2d array (or equivalent) of the height values used to generate an
- illumination map
- vert_exag : number, optional
- The amount to exaggerate the elevation values by when calculating
- illumination. This can be used either to correct for differences in
- units between the x-y coordinate system and the elevation
- coordinate system (e.g. decimal degrees vs meters) or to exaggerate
- or de-emphasize topographic effects.
- dx : number, optional
- The x-spacing (columns) of the input *elevation* grid.
- dy : number, optional
- The y-spacing (rows) of the input *elevation* grid.
- fraction : number, optional
- Increases or decreases the contrast of the hillshade. Values
- greater than one will cause intermediate values to move closer to
- full illumination or shadow (and clipping any values that move
- beyond 0 or 1). Note that this is not visually or mathematically
- the same as vertical exaggeration.
- Returns
- -------
- intensity : ndarray
- A 2d array of illumination values between 0-1, where 0 is
- completely in shadow and 1 is completely illuminated.
- """
-
- # Because most image and raster GIS data has the first row in the array
- # as the "top" of the image, dy is implicitly negative. This is
- # consistent to what `imshow` assumes, as well.
- dy = -dy
-
- # compute the normal vectors from the partial derivatives
- e_dy, e_dx = np.gradient(vert_exag * elevation, dy, dx)
-
- # .view is to keep subclasses
- normal = np.empty(elevation.shape + (3,)).view(type(elevation))
- normal[..., 0] = -e_dx
- normal[..., 1] = -e_dy
- normal[..., 2] = 1
- normal /= _vector_magnitude(normal)
-
- return self.shade_normals(normal, fraction)
-
- def shade_normals(self, normals, fraction=1.):
- """
- Calculates the illumination intensity for the normal vectors of a
- surface using the defined azimuth and elevation for the light source.
-
- Imagine an artificial sun placed at infinity in some azimuth and
- elevation position illuminating our surface. The parts of the surface
- that slope toward the sun should brighten while those sides facing away
- should become darker.
-
- Parameters
- ----------
- fraction : number, optional
- Increases or decreases the contrast of the hillshade. Values
- greater than one will cause intermediate values to move closer to
- full illumination or shadow (and clipping any values that move
- beyond 0 or 1). Note that this is not visually or mathematically
- the same as vertical exaggeration.
-
- Returns
- -------
- intensity : ndarray
- A 2d array of illumination values between 0-1, where 0 is
- completely in shadow and 1 is completely illuminated.
- """
-
- intensity = _vector_dot(normals, self.direction)
-
- # Apply contrast stretch
- imin, imax = intensity.min(), intensity.max()
- intensity *= fraction
-
- # Rescale to 0-1, keeping range before contrast stretch
- # If constant slope, keep relative scaling (i.e. flat should be 0.5,
- # fully occluded 0, etc.)
- if (imax - imin) > 1e-6:
- # Strictly speaking, this is incorrect. Negative values should be
- # clipped to 0 because they're fully occluded. However, rescaling
- # in this manner is consistent with the previous implementation and
- # visually appears better than a "hard" clip.
- intensity -= imin
- intensity /= (imax - imin)
- intensity = np.clip(intensity, 0, 1)
-
- return intensity
-
- def shade(self, data, cmap, norm=None, blend_mode='overlay', vmin=None,
- vmax=None, vert_exag=1, dx=1, dy=1, fraction=1, **kwargs):
- """
- Combine colormapped data values with an illumination intensity map
- (a.k.a. "hillshade") of the values.
-
- Parameters
- ----------
- data : array-like
- A 2d array (or equivalent) of the height values used to generate a
- shaded map.
- cmap : `~matplotlib.colors.Colormap` instance
- The colormap used to color the *data* array. Note that this must be
- a `~matplotlib.colors.Colormap` instance. For example, rather than
- passing in `cmap='gist_earth'`, use
- `cmap=plt.get_cmap('gist_earth')` instead.
- norm : `~matplotlib.colors.Normalize` instance, optional
- The normalization used to scale values before colormapping. If
- None, the input will be linearly scaled between its min and max.
- blend_mode : {'hsv', 'overlay', 'soft'} or callable, optional
- The type of blending used to combine the colormapped data
- values with the illumination intensity. Default is
- "overlay". Note that for most topographic surfaces,
- "overlay" or "soft" appear more visually realistic. If a
- user-defined function is supplied, it is expected to
- combine an MxNx3 RGB array of floats (ranging 0 to 1) with
- an MxNx1 hillshade array (also 0 to 1). (Call signature
- `func(rgb, illum, **kwargs)`) Additional kwargs supplied
- to this function will be passed on to the *blend_mode*
- function.
- vmin : scalar or None, optional
- The minimum value used in colormapping *data*. If *None* the
- minimum value in *data* is used. If *norm* is specified, then this
- argument will be ignored.
- vmax : scalar or None, optional
- The maximum value used in colormapping *data*. If *None* the
- maximum value in *data* is used. If *norm* is specified, then this
- argument will be ignored.
- vert_exag : number, optional
- The amount to exaggerate the elevation values by when calculating
- illumination. This can be used either to correct for differences in
- units between the x-y coordinate system and the elevation
- coordinate system (e.g. decimal degrees vs meters) or to exaggerate
- or de-emphasize topography.
- dx : number, optional
- The x-spacing (columns) of the input *elevation* grid.
- dy : number, optional
- The y-spacing (rows) of the input *elevation* grid.
- fraction : number, optional
- Increases or decreases the contrast of the hillshade. Values
- greater than one will cause intermediate values to move closer to
- full illumination or shadow (and clipping any values that move
- beyond 0 or 1). Note that this is not visually or mathematically
- the same as vertical exaggeration.
- Additional kwargs are passed on to the *blend_mode* function.
-
- Returns
- -------
- rgba : ndarray
- An MxNx4 array of floats ranging between 0-1.
- """
- if vmin is None:
- vmin = data.min()
- if vmax is None:
- vmax = data.max()
- if norm is None:
- norm = Normalize(vmin=vmin, vmax=vmax)
-
- rgb0 = cmap(norm(data))
- rgb1 = self.shade_rgb(rgb0, elevation=data, blend_mode=blend_mode,
- vert_exag=vert_exag, dx=dx, dy=dy,
- fraction=fraction, **kwargs)
- # Don't overwrite the alpha channel, if present.
- rgb0[..., :3] = rgb1[..., :3]
- return rgb0
-
- def shade_rgb(self, rgb, elevation, fraction=1., blend_mode='hsv',
- vert_exag=1, dx=1, dy=1, **kwargs):
- """
- Take the input RGB array (ny*nx*3) adjust their color values
- to given the impression of a shaded relief map with a
- specified light source using the elevation (ny*nx).
- A new RGB array ((ny*nx*3)) is returned.
-
- Parameters
- ----------
- rgb : array-like
- An MxNx3 RGB array, assumed to be in the range of 0 to 1.
- elevation : array-like
- A 2d array (or equivalent) of the height values used to generate a
- shaded map.
- fraction : number
- Increases or decreases the contrast of the hillshade. Values
- greater than one will cause intermediate values to move closer to
- full illumination or shadow (and clipping any values that move
- beyond 0 or 1). Note that this is not visually or mathematically
- the same as vertical exaggeration.
- blend_mode : {'hsv', 'overlay', 'soft'} or callable, optional
- The type of blending used to combine the colormapped data values
- with the illumination intensity. For backwards compatibility, this
- defaults to "hsv". Note that for most topographic surfaces,
- "overlay" or "soft" appear more visually realistic. If a
- user-defined function is supplied, it is expected to combine an
- MxNx3 RGB array of floats (ranging 0 to 1) with an MxNx1 hillshade
- array (also 0 to 1). (Call signature `func(rgb, illum, **kwargs)`)
- Additional kwargs supplied to this function will be passed on to
- the *blend_mode* function.
- vert_exag : number, optional
- The amount to exaggerate the elevation values by when calculating
- illumination. This can be used either to correct for differences in
- units between the x-y coordinate system and the elevation
- coordinate system (e.g. decimal degrees vs meters) or to exaggerate
- or de-emphasize topography.
- dx : number, optional
- The x-spacing (columns) of the input *elevation* grid.
- dy : number, optional
- The y-spacing (rows) of the input *elevation* grid.
- Additional kwargs are passed on to the *blend_mode* function.
-
- Returns
- -------
- shaded_rgb : ndarray
- An MxNx3 array of floats ranging between 0-1.
- """
- # Calculate the "hillshade" intensity.
- intensity = self.hillshade(elevation, vert_exag, dx, dy, fraction)
- intensity = intensity[..., np.newaxis]
-
- # Blend the hillshade and rgb data using the specified mode
- lookup = {
- 'hsv': self.blend_hsv,
- 'soft': self.blend_soft_light,
- 'overlay': self.blend_overlay,
- }
- if blend_mode in lookup:
- blend = lookup[blend_mode](rgb, intensity, **kwargs)
- else:
- try:
- blend = blend_mode(rgb, intensity, **kwargs)
- except TypeError:
- raise ValueError('"blend_mode" must be callable or one of {}'
- .format(lookup.keys))
-
- # Only apply result where hillshade intensity isn't masked
- if hasattr(intensity, 'mask'):
- mask = intensity.mask[..., 0]
- for i in range(3):
- blend[..., i][mask] = rgb[..., i][mask]
-
- return blend
-
- def blend_hsv(self, rgb, intensity, hsv_max_sat=None, hsv_max_val=None,
- hsv_min_val=None, hsv_min_sat=None):
- """
- Take the input data array, convert to HSV values in the given colormap,
- then adjust those color values to give the impression of a shaded
- relief map with a specified light source. RGBA values are returned,
- which can then be used to plot the shaded image with imshow.
-
- The color of the resulting image will be darkened by moving the (s,v)
- values (in hsv colorspace) toward (hsv_min_sat, hsv_min_val) in the
- shaded regions, or lightened by sliding (s,v) toward (hsv_max_sat
- hsv_max_val) in regions that are illuminated. The default extremes are
- chose so that completely shaded points are nearly black (s = 1, v = 0)
- and completely illuminated points are nearly white (s = 0, v = 1).
-
- Parameters
- ----------
- rgb : ndarray
- An MxNx3 RGB array of floats ranging from 0 to 1 (color image).
- intensity : ndarray
- An MxNx1 array of floats ranging from 0 to 1 (grayscale image).
- hsv_max_sat : number, optional
- The maximum saturation value that the *intensity* map can shift the
- output image to. Defaults to 1.
- hsv_min_sat : number, optional
- The minimum saturation value that the *intensity* map can shift the
- output image to. Defaults to 0.
- hsv_max_val : number, optional
- The maximum value ("v" in "hsv") that the *intensity* map can shift
- the output image to. Defaults to 1.
- hsv_min_val: number, optional
- The minimum value ("v" in "hsv") that the *intensity* map can shift
- the output image to. Defaults to 0.
-
- Returns
- -------
- rgb : ndarray
- An MxNx3 RGB array representing the combined images.
- """
- # Backward compatibility...
- if hsv_max_sat is None:
- hsv_max_sat = self.hsv_max_sat
- if hsv_max_val is None:
- hsv_max_val = self.hsv_max_val
- if hsv_min_sat is None:
- hsv_min_sat = self.hsv_min_sat
- if hsv_min_val is None:
- hsv_min_val = self.hsv_min_val
-
- # Expects a 2D intensity array scaled between -1 to 1...
- intensity = intensity[..., 0]
- intensity = 2 * intensity - 1
-
- # convert to rgb, then rgb to hsv
- hsv = rgb_to_hsv(rgb[:, :, 0:3])
-
- # modify hsv values to simulate illumination.
- hsv[:, :, 1] = np.where(np.logical_and(np.abs(hsv[:, :, 1]) > 1.e-10,
- intensity > 0),
- ((1. - intensity) * hsv[:, :, 1] +
- intensity * hsv_max_sat),
- hsv[:, :, 1])
-
- hsv[:, :, 2] = np.where(intensity > 0,
- ((1. - intensity) * hsv[:, :, 2] +
- intensity * hsv_max_val),
- hsv[:, :, 2])
-
- hsv[:, :, 1] = np.where(np.logical_and(np.abs(hsv[:, :, 1]) > 1.e-10,
- intensity < 0),
- ((1. + intensity) * hsv[:, :, 1] -
- intensity * hsv_min_sat),
- hsv[:, :, 1])
- hsv[:, :, 2] = np.where(intensity < 0,
- ((1. + intensity) * hsv[:, :, 2] -
- intensity * hsv_min_val),
- hsv[:, :, 2])
- hsv[:, :, 1:] = np.where(hsv[:, :, 1:] < 0., 0, hsv[:, :, 1:])
- hsv[:, :, 1:] = np.where(hsv[:, :, 1:] > 1., 1, hsv[:, :, 1:])
- # convert modified hsv back to rgb.
- return hsv_to_rgb(hsv)
-
- def blend_soft_light(self, rgb, intensity):
- """
- Combines an rgb image with an intensity map using "soft light"
- blending. Uses the "pegtop" formula.
-
- Parameters
- ----------
- rgb : ndarray
- An MxNx3 RGB array of floats ranging from 0 to 1 (color image).
- intensity : ndarray
- An MxNx1 array of floats ranging from 0 to 1 (grayscale image).
-
- Returns
- -------
- rgb : ndarray
- An MxNx3 RGB array representing the combined images.
- """
- return 2 * intensity * rgb + (1 - 2 * intensity) * rgb**2
-
- def blend_overlay(self, rgb, intensity):
- """
- Combines an rgb image with an intensity map using "overlay" blending.
-
- Parameters
- ----------
- rgb : ndarray
- An MxNx3 RGB array of floats ranging from 0 to 1 (color image).
- intensity : ndarray
- An MxNx1 array of floats ranging from 0 to 1 (grayscale image).
-
- Returns
- -------
- rgb : ndarray
- An MxNx3 RGB array representing the combined images.
- """
- low = 2 * intensity * rgb
- high = 1 - 2 * (1 - intensity) * (1 - rgb)
- return np.where(rgb <= 0.5, low, high)
-
-
-def from_levels_and_colors(levels, colors, extend='neither'):
- """
- A helper routine to generate a cmap and a norm instance which
- behave similar to contourf's levels and colors arguments.
-
- Parameters
- ----------
- levels : sequence of numbers
- The quantization levels used to construct the :class:`BoundaryNorm`.
- Values ``v`` are quantizized to level ``i`` if
- ``lev[i] <= v < lev[i+1]``.
- colors : sequence of colors
- The fill color to use for each level. If `extend` is "neither" there
- must be ``n_level - 1`` colors. For an `extend` of "min" or "max" add
- one extra color, and for an `extend` of "both" add two colors.
- extend : {'neither', 'min', 'max', 'both'}, optional
- The behaviour when a value falls out of range of the given levels.
- See :func:`~matplotlib.pyplot.contourf` for details.
-
- Returns
- -------
- (cmap, norm) : tuple containing a :class:`Colormap` and a \
- :class:`Normalize` instance
- """
- colors_i0 = 0
- colors_i1 = None
-
- if extend == 'both':
- colors_i0 = 1
- colors_i1 = -1
- extra_colors = 2
- elif extend == 'min':
- colors_i0 = 1
- extra_colors = 1
- elif extend == 'max':
- colors_i1 = -1
- extra_colors = 1
- elif extend == 'neither':
- extra_colors = 0
- else:
- raise ValueError('Unexpected value for extend: {0!r}'.format(extend))
-
- n_data_colors = len(levels) - 1
- n_expected_colors = n_data_colors + extra_colors
- if len(colors) != n_expected_colors:
- raise ValueError('With extend == {0!r} and n_levels == {1!r} expected'
- ' n_colors == {2!r}. Got {3!r}.'
- ''.format(extend, len(levels), n_expected_colors,
- len(colors)))
-
- cmap = ListedColormap(colors[colors_i0:colors_i1], N=n_data_colors)
-
- if extend in ['min', 'both']:
- cmap.set_under(colors[0])
- else:
- cmap.set_under('none')
-
- if extend in ['max', 'both']:
- cmap.set_over(colors[-1])
- else:
- cmap.set_over('none')
-
- cmap.colorbar_extend = extend
-
- norm = BoundaryNorm(levels, ncolors=n_data_colors)
- return cmap, norm
diff --git a/contrib/python/matplotlib/py2/matplotlib/compat/__init__.py b/contrib/python/matplotlib/py2/matplotlib/compat/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/compat/__init__.py
+++ /dev/null
diff --git a/contrib/python/matplotlib/py2/matplotlib/compat/subprocess.py b/contrib/python/matplotlib/py2/matplotlib/compat/subprocess.py
deleted file mode 100644
index 6607a01183..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/compat/subprocess.py
+++ /dev/null
@@ -1,51 +0,0 @@
-"""
-A replacement wrapper around the subprocess module, with a number of
-work-arounds:
-- Provides a stub implementation of subprocess members on Google App Engine
- (which are missing in subprocess).
-- Use subprocess32, backport from python 3.2 on Linux/Mac work-around for
- https://github.com/matplotlib/matplotlib/issues/5314
-
-Instead of importing subprocess, other modules should use this as follows:
-
-from matplotlib.compat import subprocess
-
-This module is safe to import from anywhere within matplotlib.
-"""
-
-from __future__ import absolute_import # Required to import subprocess
-from __future__ import print_function
-import os
-import sys
-if os.name == 'posix' and sys.version_info[0] < 3:
- # work around for https://github.com/matplotlib/matplotlib/issues/5314
- try:
- import subprocess32 as subprocess
- except ImportError:
- import subprocess
-else:
- import subprocess
-
-__all__ = ['Popen', 'PIPE', 'STDOUT', 'check_output', 'CalledProcessError']
-
-
-if hasattr(subprocess, 'Popen'):
- Popen = subprocess.Popen
- # Assume that it also has the other constants.
- PIPE = subprocess.PIPE
- STDOUT = subprocess.STDOUT
- CalledProcessError = subprocess.CalledProcessError
- check_output = subprocess.check_output
-else:
- # In restricted environments (such as Google App Engine), these are
- # non-existent. Replace them with dummy versions that always raise OSError.
- def Popen(*args, **kwargs):
- raise OSError("subprocess.Popen is not supported")
-
- def check_output(*args, **kwargs):
- raise OSError("subprocess.check_output is not supported")
- PIPE = -1
- STDOUT = -2
- # There is no need to catch CalledProcessError. These stubs cannot raise
- # it. None in an except clause will simply not match any exceptions.
- CalledProcessError = None
diff --git a/contrib/python/matplotlib/py2/matplotlib/container.py b/contrib/python/matplotlib/py2/matplotlib/container.py
deleted file mode 100644
index f96bf9f03f..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/container.py
+++ /dev/null
@@ -1,194 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import matplotlib.cbook as cbook
-import matplotlib.artist as martist
-
-
-class Container(tuple):
- """
- Base class for containers.
-
- Containers are classes that collect semantically related Artists such as
- the bars of a bar plot.
- """
-
- def __repr__(self):
- return ("<{} object of {} artists>"
- .format(type(self).__name__, len(self)))
-
- def __new__(cls, *kl, **kwargs):
- return tuple.__new__(cls, kl[0])
-
- def __init__(self, kl, label=None):
-
- self.eventson = False # fire events only if eventson
- self._oid = 0 # an observer id
- self._propobservers = {} # a dict from oids to funcs
-
- self._remove_method = None
-
- self.set_label(label)
-
- def set_remove_method(self, f):
- self._remove_method = f
-
- def remove(self):
- for c in cbook.flatten(
- self, scalarp=lambda x: isinstance(x, martist.Artist)):
- if c is not None:
- c.remove()
-
- if self._remove_method:
- self._remove_method(self)
-
- def __getstate__(self):
- d = self.__dict__.copy()
- # remove the unpicklable remove method, this will get re-added on load
- # (by the axes) if the artist lives on an axes.
- d['_remove_method'] = None
- return d
-
- def get_label(self):
- """
- Get the label used for this artist in the legend.
- """
- return self._label
-
- def set_label(self, s):
- """
- Set the label to *s* for auto legend.
-
- ACCEPTS: string or anything printable with '%s' conversion.
- """
- if s is not None:
- self._label = '%s' % (s, )
- else:
- self._label = None
- self.pchanged()
-
- def add_callback(self, func):
- """
- Adds a callback function that will be called whenever one of
- the :class:`Artist`'s properties changes.
-
- Returns an *id* that is useful for removing the callback with
- :meth:`remove_callback` later.
- """
- oid = self._oid
- self._propobservers[oid] = func
- self._oid += 1
- return oid
-
- def remove_callback(self, oid):
- """
- Remove a callback based on its *id*.
-
- .. seealso::
-
- :meth:`add_callback`
- For adding callbacks
-
- """
- try:
- del self._propobservers[oid]
- except KeyError:
- pass
-
- def pchanged(self):
- """
- Fire an event when property changed, calling all of the
- registered callbacks.
- """
- for oid, func in list(six.iteritems(self._propobservers)):
- func(self)
-
- def get_children(self):
- return [child for child in cbook.flatten(self) if child is not None]
-
-
-class BarContainer(Container):
- """
- Container for the artists of bar plots (e.g. created by `.Axes.bar`).
-
- The container can be treated as a tuple of the *patches* themselves.
- Additionally, you can access these and further parameters by the
- attributes.
-
- Attributes
- ----------
- patches : list of :class:`~matplotlib.patches.Rectangle`
- The artists of the bars.
-
- errorbar : None or :class:`~matplotlib.container.ErrorbarContainer`
- A container for the error bar artists if error bars are present.
- *None* otherwise.
-
- """
-
- def __init__(self, patches, errorbar=None, **kwargs):
- self.patches = patches
- self.errorbar = errorbar
- Container.__init__(self, patches, **kwargs)
-
-
-class ErrorbarContainer(Container):
- """
- Container for the artists of error bars (e.g. created by `.Axes.errorbar`).
-
- The container can be treated as the *lines* tuple itself.
- Additionally, you can access these and further parameters by the
- attributes.
-
- Attributes
- ----------
- lines : tuple
- Tuple of ``(data_line, caplines, barlinecols)``.
-
- - data_line : :class:`~matplotlib.lines.Line2D` instance of
- x, y plot markers and/or line.
- - caplines : tuple of :class:`~matplotlib.lines.Line2D` instances of
- the error bar caps.
- - barlinecols : list of :class:`~matplotlib.collections.LineCollection`
- with the horizontal and vertical error ranges.
-
- has_xerr, has_yerr : bool
- ``True`` if the errorbar has x/y errors.
-
- """
-
- def __init__(self, lines, has_xerr=False, has_yerr=False, **kwargs):
- self.lines = lines
- self.has_xerr = has_xerr
- self.has_yerr = has_yerr
- Container.__init__(self, lines, **kwargs)
-
-
-class StemContainer(Container):
- """
- Container for the artists created in a :meth:`.Axes.stem` plot.
-
- The container can be treated like a namedtuple ``(markerline, stemlines,
- baseline)``.
-
- Attributes
- ----------
- markerline : :class:`~matplotlib.lines.Line2D`
- The artist of the markers at the stem heads.
-
- stemlines : list of :class:`~matplotlib.lines.Line2D`
- The artists of the vertical lines for all stems.
-
- baseline : :class:`~matplotlib.lines.Line2D`
- The artist of the horizontal baseline.
-
- """
-
- def __init__(self, markerline_stemlines_baseline, **kwargs):
- markerline, stemlines, baseline = markerline_stemlines_baseline
- self.markerline = markerline
- self.stemlines = stemlines
- self.baseline = baseline
- Container.__init__(self, markerline_stemlines_baseline, **kwargs)
diff --git a/contrib/python/matplotlib/py2/matplotlib/contour.py b/contrib/python/matplotlib/py2/matplotlib/contour.py
deleted file mode 100644
index e03bdaeae6..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/contour.py
+++ /dev/null
@@ -1,1832 +0,0 @@
-"""
-These are classes to support contour plotting and labelling for the Axes class.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-
-from numbers import Integral
-import warnings
-
-import matplotlib as mpl
-import numpy as np
-from numpy import ma
-import matplotlib._contour as _contour
-import matplotlib.path as mpath
-import matplotlib.ticker as ticker
-import matplotlib.cm as cm
-import matplotlib.colors as colors
-import matplotlib.collections as mcoll
-import matplotlib.font_manager as font_manager
-import matplotlib.text as text
-import matplotlib.cbook as cbook
-import matplotlib.mathtext as mathtext
-import matplotlib.patches as mpatches
-import matplotlib.texmanager as texmanager
-import matplotlib.transforms as mtransforms
-
-# Import needed for adding manual selection capability to clabel
-from matplotlib.blocking_input import BlockingContourLabeler
-
-# We can't use a single line collection for contour because a line
-# collection can have only a single line style, and we want to be able to have
-# dashed negative contours, for example, and solid positive contours.
-# We could use a single polygon collection for filled contours, but it
-# seems better to keep line and filled contours similar, with one collection
-# per level.
-
-
-class ClabelText(text.Text):
- """
- Unlike the ordinary text, the get_rotation returns an updated
- angle in the pixel coordinate assuming that the input rotation is
- an angle in data coordinate (or whatever transform set).
- """
- def get_rotation(self):
- angle = text.Text.get_rotation(self)
- trans = self.get_transform()
- x, y = self.get_position()
- new_angles = trans.transform_angles(np.array([angle]),
- np.array([[x, y]]))
- return new_angles[0]
-
-
-class ContourLabeler(object):
- """Mixin to provide labelling capability to `.ContourSet`."""
-
- def clabel(self, *args, **kwargs):
- """
- Label a contour plot.
-
- Call signature::
-
- clabel(cs, **kwargs)
-
- Adds labels to line contours in *cs*, where *cs* is a
- :class:`~matplotlib.contour.ContourSet` object returned by
- contour.
-
- ::
-
- clabel(cs, v, **kwargs)
-
- only labels contours listed in *v*.
-
- Parameters
- ----------
- fontsize : string or float, optional
- Size in points or relative size e.g., 'smaller', 'x-large'.
- See `Text.set_size` for accepted string values.
-
- colors :
- Color of each label
-
- - if *None*, the color of each label matches the color of
- the corresponding contour
-
- - if one string color, e.g., *colors* = 'r' or *colors* =
- 'red', all labels will be plotted in this color
-
- - if a tuple of matplotlib color args (string, float, rgb, etc),
- different labels will be plotted in different colors in the order
- specified
-
- inline : bool, optional
- If ``True`` the underlying contour is removed where the label is
- placed. Default is ``True``.
-
- inline_spacing : float, optional
- Space in pixels to leave on each side of label when
- placing inline. Defaults to 5.
-
- This spacing will be exact for labels at locations where the
- contour is straight, less so for labels on curved contours.
-
- fmt : string or dict, optional
- A format string for the label. Default is '%1.3f'
-
- Alternatively, this can be a dictionary matching contour
- levels with arbitrary strings to use for each contour level
- (i.e., fmt[level]=string), or it can be any callable, such
- as a :class:`~matplotlib.ticker.Formatter` instance, that
- returns a string when called with a numeric contour level.
-
- manual : bool or iterable, optional
- If ``True``, contour labels will be placed manually using
- mouse clicks. Click the first button near a contour to
- add a label, click the second button (or potentially both
- mouse buttons at once) to finish adding labels. The third
- button can be used to remove the last label added, but
- only if labels are not inline. Alternatively, the keyboard
- can be used to select label locations (enter to end label
- placement, delete or backspace act like the third mouse button,
- and any other key will select a label location).
-
- *manual* can also be an iterable object of x,y tuples.
- Contour labels will be created as if mouse is clicked at each
- x,y positions.
-
- rightside_up : bool, optional
- If ``True``, label rotations will always be plus
- or minus 90 degrees from level. Default is ``True``.
-
- use_clabeltext : bool, optional
- If ``True``, `ClabelText` class (instead of `Text`) is used to
- create labels. `ClabelText` recalculates rotation angles
- of texts during the drawing time, therefore this can be used if
- aspect of the axes changes. Default is ``False``.
- """
-
- """
- NOTES on how this all works:
-
- clabel basically takes the input arguments and uses them to
- add a list of "label specific" attributes to the ContourSet
- object. These attributes are all of the form label* and names
- should be fairly self explanatory.
-
- Once these attributes are set, clabel passes control to the
- labels method (case of automatic label placement) or
- `BlockingContourLabeler` (case of manual label placement).
- """
-
- fontsize = kwargs.get('fontsize', None)
- inline = kwargs.get('inline', 1)
- inline_spacing = kwargs.get('inline_spacing', 5)
- self.labelFmt = kwargs.get('fmt', '%1.3f')
- _colors = kwargs.get('colors', None)
-
- self._use_clabeltext = kwargs.get('use_clabeltext', False)
-
- # Detect if manual selection is desired and remove from argument list
- self.labelManual = kwargs.get('manual', False)
-
- self.rightside_up = kwargs.get('rightside_up', True)
- if len(args) == 0:
- levels = self.levels
- indices = list(xrange(len(self.cvalues)))
- elif len(args) == 1:
- levlabs = list(args[0])
- indices, levels = [], []
- for i, lev in enumerate(self.levels):
- if lev in levlabs:
- indices.append(i)
- levels.append(lev)
- if len(levels) < len(levlabs):
- raise ValueError("Specified levels {} don't match available "
- "levels {}".format(levlabs, self.levels))
- else:
- raise TypeError("Illegal arguments to clabel, see help(clabel)")
- self.labelLevelList = levels
- self.labelIndiceList = indices
-
- self.labelFontProps = font_manager.FontProperties()
- self.labelFontProps.set_size(fontsize)
- font_size_pts = self.labelFontProps.get_size_in_points()
- self.labelFontSizeList = [font_size_pts] * len(levels)
-
- if _colors is None:
- self.labelMappable = self
- self.labelCValueList = np.take(self.cvalues, self.labelIndiceList)
- else:
- cmap = colors.ListedColormap(_colors, N=len(self.labelLevelList))
- self.labelCValueList = list(xrange(len(self.labelLevelList)))
- self.labelMappable = cm.ScalarMappable(cmap=cmap,
- norm=colors.NoNorm())
-
- self.labelXYs = []
-
- if cbook.iterable(self.labelManual):
- for x, y in self.labelManual:
- self.add_label_near(x, y, inline,
- inline_spacing)
-
- elif self.labelManual:
- print('Select label locations manually using first mouse button.')
- print('End manual selection with second mouse button.')
- if not inline:
- print('Remove last label by clicking third mouse button.')
-
- blocking_contour_labeler = BlockingContourLabeler(self)
- blocking_contour_labeler(inline, inline_spacing)
- else:
- self.labels(inline, inline_spacing)
-
- # Hold on to some old attribute names. These are deprecated and will
- # be removed in the near future (sometime after 2008-08-01), but
- # keeping for now for backwards compatibility
- self.cl = self.labelTexts
- self.cl_xy = self.labelXYs
- self.cl_cvalues = self.labelCValues
-
- self.labelTextsList = cbook.silent_list('text.Text', self.labelTexts)
- return self.labelTextsList
-
- def print_label(self, linecontour, labelwidth):
- "Return *False* if contours are too short for a label."
- return (len(linecontour) > 10 * labelwidth
- or (np.ptp(linecontour, axis=0) > 1.2 * labelwidth).any())
-
- def too_close(self, x, y, lw):
- "Return *True* if a label is already near this location."
- for loc in self.labelXYs:
- d = np.sqrt((x - loc[0]) ** 2 + (y - loc[1]) ** 2)
- if d < 1.2 * lw:
- return True
- return False
-
- def get_label_coords(self, distances, XX, YY, ysize, lw):
- """
- Return x, y, and the index of a label location.
-
- Labels are plotted at a location with the smallest
- deviation of the contour from a straight line
- unless there is another label nearby, in which case
- the next best place on the contour is picked up.
- If all such candidates are rejected, the beginning
- of the contour is chosen.
- """
- hysize = int(ysize / 2)
- adist = np.argsort(distances)
-
- for ind in adist:
- x, y = XX[ind][hysize], YY[ind][hysize]
- if self.too_close(x, y, lw):
- continue
- return x, y, ind
-
- ind = adist[0]
- x, y = XX[ind][hysize], YY[ind][hysize]
- return x, y, ind
-
- def get_label_width(self, lev, fmt, fsize):
- """
- Return the width of the label in points.
- """
- if not isinstance(lev, six.string_types):
- lev = self.get_text(lev, fmt)
-
- lev, ismath = text.Text.is_math_text(lev)
- if ismath == 'TeX':
- if not hasattr(self, '_TeX_manager'):
- self._TeX_manager = texmanager.TexManager()
- lw, _, _ = self._TeX_manager.get_text_width_height_descent(lev,
- fsize)
- elif ismath:
- if not hasattr(self, '_mathtext_parser'):
- self._mathtext_parser = mathtext.MathTextParser('bitmap')
- img, _ = self._mathtext_parser.parse(lev, dpi=72,
- prop=self.labelFontProps)
- lw = img.get_width() # at dpi=72, the units are PostScript points
- else:
- # width is much less than "font size"
- lw = (len(lev)) * fsize * 0.6
-
- return lw
-
- @cbook.deprecated("2.2")
- def get_real_label_width(self, lev, fmt, fsize):
- """
- This computes actual onscreen label width.
- This uses some black magic to determine onscreen extent of non-drawn
- label. This magic may not be very robust.
-
- This method is not being used, and may be modified or removed.
- """
- # Find middle of axes
- xx = np.mean(np.asarray(self.ax.axis()).reshape(2, 2), axis=1)
-
- # Temporarily create text object
- t = text.Text(xx[0], xx[1])
- self.set_label_props(t, self.get_text(lev, fmt), 'k')
-
- # Some black magic to get onscreen extent
- # NOTE: This will only work for already drawn figures, as the canvas
- # does not have a renderer otherwise. This is the reason this function
- # can't be integrated into the rest of the code.
- bbox = t.get_window_extent(renderer=self.ax.figure.canvas.renderer)
-
- # difference in pixel extent of image
- lw = np.diff(bbox.corners()[0::2, 0])[0]
-
- return lw
-
- def set_label_props(self, label, text, color):
- """Set the label properties - color, fontsize, text."""
- label.set_text(text)
- label.set_color(color)
- label.set_fontproperties(self.labelFontProps)
- label.set_clip_box(self.ax.bbox)
-
- def get_text(self, lev, fmt):
- """Get the text of the label."""
- if isinstance(lev, six.string_types):
- return lev
- else:
- if isinstance(fmt, dict):
- return fmt.get(lev, '%1.3f')
- elif callable(fmt):
- return fmt(lev)
- else:
- return fmt % lev
-
- def locate_label(self, linecontour, labelwidth):
- """
- Find good place to draw a label (relatively flat part of the contour).
- """
-
- # Number of contour points
- nsize = len(linecontour)
- if labelwidth > 1:
- xsize = int(np.ceil(nsize / labelwidth))
- else:
- xsize = 1
- if xsize == 1:
- ysize = nsize
- else:
- ysize = int(labelwidth)
-
- XX = np.resize(linecontour[:, 0], (xsize, ysize))
- YY = np.resize(linecontour[:, 1], (xsize, ysize))
- # I might have fouled up the following:
- yfirst = YY[:, :1]
- ylast = YY[:, -1:]
- xfirst = XX[:, :1]
- xlast = XX[:, -1:]
- s = (yfirst - YY) * (xlast - xfirst) - (xfirst - XX) * (ylast - yfirst)
- L = np.hypot(xlast - xfirst, ylast - yfirst)
- # Ignore warning that divide by zero throws, as this is a valid option
- with np.errstate(divide='ignore', invalid='ignore'):
- dist = np.sum(np.abs(s) / L, axis=-1)
- x, y, ind = self.get_label_coords(dist, XX, YY, ysize, labelwidth)
-
- # There must be a more efficient way...
- lc = [tuple(l) for l in linecontour]
- dind = lc.index((x, y))
-
- return x, y, dind
-
- def calc_label_rot_and_inline(self, slc, ind, lw, lc=None, spacing=5):
- """
- This function calculates the appropriate label rotation given
- the linecontour coordinates in screen units, the index of the
- label location and the label width.
-
- It will also break contour and calculate inlining if *lc* is
- not empty (lc defaults to the empty list if None). *spacing*
- is the space around the label in pixels to leave empty.
-
- Do both of these tasks at once to avoid calculating path lengths
- multiple times, which is relatively costly.
-
- The method used here involves calculating the path length
- along the contour in pixel coordinates and then looking
- approximately label width / 2 away from central point to
- determine rotation and then to break contour if desired.
- """
-
- if lc is None:
- lc = []
- # Half the label width
- hlw = lw / 2.0
-
- # Check if closed and, if so, rotate contour so label is at edge
- closed = _is_closed_polygon(slc)
- if closed:
- slc = np.r_[slc[ind:-1], slc[:ind + 1]]
-
- if len(lc): # Rotate lc also if not empty
- lc = np.r_[lc[ind:-1], lc[:ind + 1]]
-
- ind = 0
-
- # Calculate path lengths
- pl = np.zeros(slc.shape[0], dtype=float)
- dx = np.diff(slc, axis=0)
- pl[1:] = np.cumsum(np.hypot(dx[:, 0], dx[:, 1]))
- pl = pl - pl[ind]
-
- # Use linear interpolation to get points around label
- xi = np.array([-hlw, hlw])
- if closed: # Look at end also for closed contours
- dp = np.array([pl[-1], 0])
- else:
- dp = np.zeros_like(xi)
-
- # Get angle of vector between the two ends of the label - must be
- # calculated in pixel space for text rotation to work correctly.
- (dx,), (dy,) = (np.diff(np.interp(dp + xi, pl, slc_col))
- for slc_col in slc.T)
- rotation = np.rad2deg(np.arctan2(dy, dx))
-
- if self.rightside_up:
- # Fix angle so text is never upside-down
- rotation = (rotation + 90) % 180 - 90
-
- # Break contour if desired
- nlc = []
- if len(lc):
- # Expand range by spacing
- xi = dp + xi + np.array([-spacing, spacing])
-
- # Get (integer) indices near points of interest; use -1 as marker
- # for out of bounds.
- I = np.interp(xi, pl, np.arange(len(pl)), left=-1, right=-1)
- I = [np.floor(I[0]).astype(int), np.ceil(I[1]).astype(int)]
- if I[0] != -1:
- xy1 = [np.interp(xi[0], pl, lc_col) for lc_col in lc.T]
- if I[1] != -1:
- xy2 = [np.interp(xi[1], pl, lc_col) for lc_col in lc.T]
-
- # Actually break contours
- if closed:
- # This will remove contour if shorter than label
- if all(i != -1 for i in I):
- nlc.append(np.row_stack([xy2, lc[I[1]:I[0]+1], xy1]))
- else:
- # These will remove pieces of contour if they have length zero
- if I[0] != -1:
- nlc.append(np.row_stack([lc[:I[0]+1], xy1]))
- if I[1] != -1:
- nlc.append(np.row_stack([xy2, lc[I[1]:]]))
-
- # The current implementation removes contours completely
- # covered by labels. Uncomment line below to keep
- # original contour if this is the preferred behavior.
- # if not len(nlc): nlc = [ lc ]
-
- return rotation, nlc
-
- def _get_label_text(self, x, y, rotation):
- dx, dy = self.ax.transData.inverted().transform_point((x, y))
- t = text.Text(dx, dy, rotation=rotation,
- horizontalalignment='center',
- verticalalignment='center')
- return t
-
- def _get_label_clabeltext(self, x, y, rotation):
- # x, y, rotation is given in pixel coordinate. Convert them to
- # the data coordinate and create a label using ClabelText
- # class. This way, the roation of the clabel is along the
- # contour line always.
- transDataInv = self.ax.transData.inverted()
- dx, dy = transDataInv.transform_point((x, y))
- drotation = transDataInv.transform_angles(np.array([rotation]),
- np.array([[x, y]]))
- t = ClabelText(dx, dy, rotation=drotation[0],
- horizontalalignment='center',
- verticalalignment='center')
-
- return t
-
- def _add_label(self, t, x, y, lev, cvalue):
- color = self.labelMappable.to_rgba(cvalue, alpha=self.alpha)
-
- _text = self.get_text(lev, self.labelFmt)
- self.set_label_props(t, _text, color)
- self.labelTexts.append(t)
- self.labelCValues.append(cvalue)
- self.labelXYs.append((x, y))
-
- # Add label to plot here - useful for manual mode label selection
- self.ax.add_artist(t)
-
- def add_label(self, x, y, rotation, lev, cvalue):
- """
- Add contour label using :class:`~matplotlib.text.Text` class.
- """
-
- t = self._get_label_text(x, y, rotation)
- self._add_label(t, x, y, lev, cvalue)
-
- def add_label_clabeltext(self, x, y, rotation, lev, cvalue):
- """
- Add contour label using :class:`ClabelText` class.
- """
- # x, y, rotation is given in pixel coordinate. Convert them to
- # the data coordinate and create a label using ClabelText
- # class. This way, the roation of the clabel is along the
- # contour line always.
-
- t = self._get_label_clabeltext(x, y, rotation)
- self._add_label(t, x, y, lev, cvalue)
-
- def add_label_near(self, x, y, inline=True, inline_spacing=5,
- transform=None):
- """
- Add a label near the point (x, y). If transform is None
- (default), (x, y) is in data coordinates; if transform is
- False, (x, y) is in display coordinates; otherwise, the
- specified transform will be used to translate (x, y) into
- display coordinates.
-
- Parameters
- ----------
- x, y : float
- The approximate location of the label.
-
- inline : bool, optional, default: True
- If *True* remove the segment of the contour beneath the label.
-
- inline_spacing : int, optional, default: 5
- Space in pixels to leave on each side of label when placing
- inline. This spacing will be exact for labels at locations where
- the contour is straight, less so for labels on curved contours.
- """
-
- if transform is None:
- transform = self.ax.transData
-
- if transform:
- x, y = transform.transform_point((x, y))
-
- # find the nearest contour _in screen units_
- conmin, segmin, imin, xmin, ymin = self.find_nearest_contour(
- x, y, self.labelIndiceList)[:5]
-
- # The calc_label_rot_and_inline routine requires that (xmin,ymin)
- # be a vertex in the path. So, if it isn't, add a vertex here
-
- # grab the paths from the collections
- paths = self.collections[conmin].get_paths()
- # grab the correct segment
- active_path = paths[segmin]
- # grab its vertices
- lc = active_path.vertices
- # sort out where the new vertex should be added data-units
- xcmin = self.ax.transData.inverted().transform_point([xmin, ymin])
- # if there isn't a vertex close enough
- if not np.allclose(xcmin, lc[imin]):
- # insert new data into the vertex list
- lc = np.r_[lc[:imin], np.array(xcmin)[None, :], lc[imin:]]
- # replace the path with the new one
- paths[segmin] = mpath.Path(lc)
-
- # Get index of nearest level in subset of levels used for labeling
- lmin = self.labelIndiceList.index(conmin)
-
- # Coordinates of contour
- paths = self.collections[conmin].get_paths()
- lc = paths[segmin].vertices
-
- # In pixel/screen space
- slc = self.ax.transData.transform(lc)
-
- # Get label width for rotating labels and breaking contours
- lw = self.get_label_width(self.labelLevelList[lmin],
- self.labelFmt, self.labelFontSizeList[lmin])
- # lw is in points.
- lw *= self.ax.figure.dpi / 72.0 # scale to screen coordinates
- # now lw in pixels
-
- # Figure out label rotation.
- if inline:
- lcarg = lc
- else:
- lcarg = None
- rotation, nlc = self.calc_label_rot_and_inline(
- slc, imin, lw, lcarg,
- inline_spacing)
-
- self.add_label(xmin, ymin, rotation, self.labelLevelList[lmin],
- self.labelCValueList[lmin])
-
- if inline:
- # Remove old, not looping over paths so we can do this up front
- paths.pop(segmin)
-
- # Add paths if not empty or single point
- for n in nlc:
- if len(n) > 1:
- paths.append(mpath.Path(n))
-
- def pop_label(self, index=-1):
- """Defaults to removing last label, but any index can be supplied"""
- self.labelCValues.pop(index)
- t = self.labelTexts.pop(index)
- t.remove()
-
- def labels(self, inline, inline_spacing):
-
- if self._use_clabeltext:
- add_label = self.add_label_clabeltext
- else:
- add_label = self.add_label
-
- for icon, lev, fsize, cvalue in zip(
- self.labelIndiceList, self.labelLevelList,
- self.labelFontSizeList, self.labelCValueList):
-
- con = self.collections[icon]
- trans = con.get_transform()
- lw = self.get_label_width(lev, self.labelFmt, fsize)
- lw *= self.ax.figure.dpi / 72.0 # scale to screen coordinates
- additions = []
- paths = con.get_paths()
- for segNum, linepath in enumerate(paths):
- lc = linepath.vertices # Line contour
- slc0 = trans.transform(lc) # Line contour in screen coords
-
- # For closed polygons, add extra point to avoid division by
- # zero in print_label and locate_label. Other than these
- # functions, this is not necessary and should probably be
- # eventually removed.
- if _is_closed_polygon(lc):
- slc = np.r_[slc0, slc0[1:2, :]]
- else:
- slc = slc0
-
- # Check if long enough for a label
- if self.print_label(slc, lw):
- x, y, ind = self.locate_label(slc, lw)
-
- if inline:
- lcarg = lc
- else:
- lcarg = None
- rotation, new = self.calc_label_rot_and_inline(
- slc0, ind, lw, lcarg,
- inline_spacing)
-
- # Actually add the label
- add_label(x, y, rotation, lev, cvalue)
-
- # If inline, add new contours
- if inline:
- for n in new:
- # Add path if not empty or single point
- if len(n) > 1:
- additions.append(mpath.Path(n))
- else: # If not adding label, keep old path
- additions.append(linepath)
-
- # After looping over all segments on a contour, remove old
- # paths and add new ones if inlining
- if inline:
- del paths[:]
- paths.extend(additions)
-
-
-def _find_closest_point_on_leg(p1, p2, p0):
- """Find the closest point to p0 on line segment connecting p1 and p2."""
-
- # handle degenerate case
- if np.all(p2 == p1):
- d = np.sum((p0 - p1)**2)
- return d, p1
-
- d21 = p2 - p1
- d01 = p0 - p1
-
- # project on to line segment to find closest point
- proj = np.dot(d01, d21) / np.dot(d21, d21)
- if proj < 0:
- proj = 0
- if proj > 1:
- proj = 1
- pc = p1 + proj * d21
-
- # find squared distance
- d = np.sum((pc-p0)**2)
-
- return d, pc
-
-
-def _is_closed_polygon(X):
- """
- Return whether first and last object in a sequence are the same. These are
- presumably coordinates on a polygonal curve, in which case this function
- tests if that curve is closed.
- """
- return np.all(X[0] == X[-1])
-
-
-def _find_closest_point_on_path(lc, point):
- """
- lc: coordinates of vertices
- point: coordinates of test point
- """
-
- # find index of closest vertex for this segment
- ds = np.sum((lc - point[None, :])**2, 1)
- imin = np.argmin(ds)
-
- dmin = np.inf
- xcmin = None
- legmin = (None, None)
-
- closed = _is_closed_polygon(lc)
-
- # build list of legs before and after this vertex
- legs = []
- if imin > 0 or closed:
- legs.append(((imin-1) % len(lc), imin))
- if imin < len(lc) - 1 or closed:
- legs.append((imin, (imin+1) % len(lc)))
-
- for leg in legs:
- d, xc = _find_closest_point_on_leg(lc[leg[0]], lc[leg[1]], point)
- if d < dmin:
- dmin = d
- xcmin = xc
- legmin = leg
-
- return (dmin, xcmin, legmin)
-
-
-class ContourSet(cm.ScalarMappable, ContourLabeler):
- """
- Store a set of contour lines or filled regions.
-
- User-callable method: `~.axes.Axes.clabel`
-
- Parameters
- ----------
- ax : `~.axes.Axes`
-
- levels : [level0, level1, ..., leveln]
- A list of floating point numbers indicating the contour
- levels.
-
- allsegs : [level0segs, level1segs, ...]
- List of all the polygon segments for all the *levels*.
- For contour lines ``len(allsegs) == len(levels)``, and for
- filled contour regions ``len(allsegs) = len(levels)-1``. The lists
- should look like::
-
- level0segs = [polygon0, polygon1, ...]
- polygon0 = array_like [[x0,y0], [x1,y1], ...]
-
- allkinds : ``None`` or [level0kinds, level1kinds, ...]
- Optional list of all the polygon vertex kinds (code types), as
- described and used in Path. This is used to allow multiply-
- connected paths such as holes within filled polygons.
- If not ``None``, ``len(allkinds) == len(allsegs)``. The lists
- should look like::
-
- level0kinds = [polygon0kinds, ...]
- polygon0kinds = [vertexcode0, vertexcode1, ...]
-
- If *allkinds* is not ``None``, usually all polygons for a
- particular contour level are grouped together so that
- ``level0segs = [polygon0]`` and ``level0kinds = [polygon0kinds]``.
-
- kwargs :
- Keyword arguments are as described in the docstring of
- `~.axes.Axes.contour`.
-
- Attributes
- ----------
- ax:
- The axes object in which the contours are drawn.
-
- collections:
- A silent_list of LineCollections or PolyCollections.
-
- levels:
- Contour levels.
-
- layers:
- Same as levels for line contours; half-way between
- levels for filled contours. See :meth:`_process_colors`.
- """
-
- def __init__(self, ax, *args, **kwargs):
- """
- Draw contour lines or filled regions, depending on
- whether keyword arg *filled* is ``False`` (default) or ``True``.
-
- Call signature::
-
- ContourSet(ax, levels, allsegs, [allkinds], **kwargs)
-
- Parameters
- ----------
- ax :
- The `~.axes.Axes` object to draw on.
-
- levels : [level0, level1, ..., leveln]
- A list of floating point numbers indicating the contour
- levels.
-
- allsegs : [level0segs, level1segs, ...]
- List of all the polygon segments for all the *levels*.
- For contour lines ``len(allsegs) == len(levels)``, and for
- filled contour regions ``len(allsegs) = len(levels)-1``. The lists
- should look like::
-
- level0segs = [polygon0, polygon1, ...]
- polygon0 = array_like [[x0,y0], [x1,y1], ...]
-
- allkinds : [level0kinds, level1kinds, ...], optional
- Optional list of all the polygon vertex kinds (code types), as
- described and used in Path. This is used to allow multiply-
- connected paths such as holes within filled polygons.
- If not ``None``, ``len(allkinds) == len(allsegs)``. The lists
- should look like::
-
- level0kinds = [polygon0kinds, ...]
- polygon0kinds = [vertexcode0, vertexcode1, ...]
-
- If *allkinds* is not ``None``, usually all polygons for a
- particular contour level are grouped together so that
- ``level0segs = [polygon0]`` and ``level0kinds = [polygon0kinds]``.
-
- **kwargs
- Keyword arguments are as described in the docstring of
- `~axes.Axes.contour`.
- """
- self.ax = ax
- self.levels = kwargs.pop('levels', None)
- self.filled = kwargs.pop('filled', False)
- self.linewidths = kwargs.pop('linewidths', None)
- self.linestyles = kwargs.pop('linestyles', None)
-
- self.hatches = kwargs.pop('hatches', [None])
-
- self.alpha = kwargs.pop('alpha', None)
- self.origin = kwargs.pop('origin', None)
- self.extent = kwargs.pop('extent', None)
- cmap = kwargs.pop('cmap', None)
- self.colors = kwargs.pop('colors', None)
- norm = kwargs.pop('norm', None)
- vmin = kwargs.pop('vmin', None)
- vmax = kwargs.pop('vmax', None)
- self.extend = kwargs.pop('extend', 'neither')
- self.antialiased = kwargs.pop('antialiased', None)
- if self.antialiased is None and self.filled:
- self.antialiased = False # eliminate artifacts; we are not
- # stroking the boundaries.
- # The default for line contours will be taken from
- # the LineCollection default, which uses the
- # rcParams['lines.antialiased']
-
- self.nchunk = kwargs.pop('nchunk', 0)
- self.locator = kwargs.pop('locator', None)
- if (isinstance(norm, colors.LogNorm)
- or isinstance(self.locator, ticker.LogLocator)):
- self.logscale = True
- if norm is None:
- norm = colors.LogNorm()
- if self.extend != 'neither':
- raise ValueError('extend kwarg does not work yet with log '
- ' scale')
- else:
- self.logscale = False
-
- if self.origin not in [None, 'lower', 'upper', 'image']:
- raise ValueError("If given, *origin* must be one of [ 'lower' |"
- " 'upper' | 'image']")
- if self.extent is not None and len(self.extent) != 4:
- raise ValueError("If given, *extent* must be '[ *None* |"
- " (x0,x1,y0,y1) ]'")
- if self.colors is not None and cmap is not None:
- raise ValueError('Either colors or cmap must be None')
- if self.origin == 'image':
- self.origin = mpl.rcParams['image.origin']
-
- self._transform = kwargs.pop('transform', None)
-
- kwargs = self._process_args(*args, **kwargs)
- self._process_levels()
-
- if self.colors is not None:
- ncolors = len(self.levels)
- if self.filled:
- ncolors -= 1
- i0 = 0
-
- # Handle the case where colors are given for the extended
- # parts of the contour.
- extend_min = self.extend in ['min', 'both']
- extend_max = self.extend in ['max', 'both']
- use_set_under_over = False
- # if we are extending the lower end, and we've been given enough
- # colors then skip the first color in the resulting cmap. For the
- # extend_max case we don't need to worry about passing more colors
- # than ncolors as ListedColormap will clip.
- total_levels = ncolors + int(extend_min) + int(extend_max)
- if (len(self.colors) == total_levels and
- any([extend_min, extend_max])):
- use_set_under_over = True
- if extend_min:
- i0 = 1
-
- cmap = colors.ListedColormap(self.colors[i0:None], N=ncolors)
-
- if use_set_under_over:
- if extend_min:
- cmap.set_under(self.colors[0])
- if extend_max:
- cmap.set_over(self.colors[-1])
-
- if self.filled:
- self.collections = cbook.silent_list('mcoll.PathCollection')
- else:
- self.collections = cbook.silent_list('mcoll.LineCollection')
- # label lists must be initialized here
- self.labelTexts = []
- self.labelCValues = []
-
- kw = {'cmap': cmap}
- if norm is not None:
- kw['norm'] = norm
- # sets self.cmap, norm if needed;
- cm.ScalarMappable.__init__(self, **kw)
- if vmin is not None:
- self.norm.vmin = vmin
- if vmax is not None:
- self.norm.vmax = vmax
- self._process_colors()
-
- self.allsegs, self.allkinds = self._get_allsegs_and_allkinds()
-
- if self.filled:
- if self.linewidths is not None:
- warnings.warn('linewidths is ignored by contourf')
-
- # Lower and upper contour levels.
- lowers, uppers = self._get_lowers_and_uppers()
-
- # Ensure allkinds can be zipped below.
- if self.allkinds is None:
- self.allkinds = [None] * len(self.allsegs)
-
- # Default zorder taken from Collection
- zorder = kwargs.pop('zorder', 1)
- for level, level_upper, segs, kinds in \
- zip(lowers, uppers, self.allsegs, self.allkinds):
- paths = self._make_paths(segs, kinds)
-
- col = mcoll.PathCollection(
- paths,
- antialiaseds=(self.antialiased,),
- edgecolors='none',
- alpha=self.alpha,
- transform=self.get_transform(),
- zorder=zorder)
- self.ax.add_collection(col, autolim=False)
- self.collections.append(col)
- else:
- tlinewidths = self._process_linewidths()
- self.tlinewidths = tlinewidths
- tlinestyles = self._process_linestyles()
- aa = self.antialiased
- if aa is not None:
- aa = (self.antialiased,)
- # Default zorder taken from LineCollection
- zorder = kwargs.pop('zorder', 2)
- for level, width, lstyle, segs in \
- zip(self.levels, tlinewidths, tlinestyles, self.allsegs):
- col = mcoll.LineCollection(
- segs,
- antialiaseds=aa,
- linewidths=width,
- linestyles=[lstyle],
- alpha=self.alpha,
- transform=self.get_transform(),
- zorder=zorder)
- col.set_label('_nolegend_')
- self.ax.add_collection(col, autolim=False)
- self.collections.append(col)
-
- for col in self.collections:
- col.sticky_edges.x[:] = [self._mins[0], self._maxs[0]]
- col.sticky_edges.y[:] = [self._mins[1], self._maxs[1]]
- self.ax.update_datalim([self._mins, self._maxs])
- self.ax.autoscale_view(tight=True)
-
- self.changed() # set the colors
-
- if kwargs:
- s = ", ".join(map(repr, kwargs))
- warnings.warn('The following kwargs were not used by contour: ' +
- s)
-
- def get_transform(self):
- """
- Return the :class:`~matplotlib.transforms.Transform`
- instance used by this ContourSet.
- """
- if self._transform is None:
- self._transform = self.ax.transData
- elif (not isinstance(self._transform, mtransforms.Transform)
- and hasattr(self._transform, '_as_mpl_transform')):
- self._transform = self._transform._as_mpl_transform(self.ax)
- return self._transform
-
- def __getstate__(self):
- state = self.__dict__.copy()
- # the C object _contour_generator cannot currently be pickled. This
- # isn't a big issue as it is not actually used once the contour has
- # been calculated.
- state['_contour_generator'] = None
- return state
-
- def legend_elements(self, variable_name='x', str_format=str):
- """
- Return a list of artists and labels suitable for passing through
- to :func:`plt.legend` which represent this ContourSet.
-
- The labels have the form "0 < x <= 1" stating the data ranges which
- the artists represent.
-
- Parameters
- ----------
- variable_name : str
- The string used inside the inequality used on the labels.
-
- str_format : function: float -> str
- Function used to format the numbers in the labels.
-
- Returns
- -------
- artists : List[`.Artist`]
- A list of the artists.
-
- labels : List[str]
- A list of the labels.
-
- """
- artists = []
- labels = []
-
- if self.filled:
- lowers, uppers = self._get_lowers_and_uppers()
- n_levels = len(self.collections)
-
- for i, (collection, lower, upper) in enumerate(
- zip(self.collections, lowers, uppers)):
- patch = mpatches.Rectangle(
- (0, 0), 1, 1,
- facecolor=collection.get_facecolor()[0],
- hatch=collection.get_hatch(),
- alpha=collection.get_alpha())
- artists.append(patch)
-
- lower = str_format(lower)
- upper = str_format(upper)
-
- if i == 0 and self.extend in ('min', 'both'):
- labels.append(r'$%s \leq %s$' % (variable_name,
- lower))
- elif i == n_levels - 1 and self.extend in ('max', 'both'):
- labels.append(r'$%s > %s$' % (variable_name,
- upper))
- else:
- labels.append(r'$%s < %s \leq %s$' % (lower,
- variable_name,
- upper))
- else:
- for collection, level in zip(self.collections, self.levels):
-
- patch = mcoll.LineCollection(None)
- patch.update_from(collection)
-
- artists.append(patch)
- # format the level for insertion into the labels
- level = str_format(level)
- labels.append(r'$%s = %s$' % (variable_name, level))
-
- return artists, labels
-
- def _process_args(self, *args, **kwargs):
- """
- Process *args* and *kwargs*; override in derived classes.
-
- Must set self.levels, self.zmin and self.zmax, and update axes
- limits.
- """
- self.levels = args[0]
- self.allsegs = args[1]
- self.allkinds = len(args) > 2 and args[2] or None
- self.zmax = np.max(self.levels)
- self.zmin = np.min(self.levels)
- self._auto = False
-
- # Check lengths of levels and allsegs.
- if self.filled:
- if len(self.allsegs) != len(self.levels) - 1:
- raise ValueError('must be one less number of segments as '
- 'levels')
- else:
- if len(self.allsegs) != len(self.levels):
- raise ValueError('must be same number of segments as levels')
-
- # Check length of allkinds.
- if (self.allkinds is not None and
- len(self.allkinds) != len(self.allsegs)):
- raise ValueError('allkinds has different length to allsegs')
-
- # Determine x,y bounds and update axes data limits.
- flatseglist = [s for seg in self.allsegs for s in seg]
- points = np.concatenate(flatseglist, axis=0)
- self._mins = points.min(axis=0)
- self._maxs = points.max(axis=0)
-
- return kwargs
-
- def _get_allsegs_and_allkinds(self):
- """
- Override in derived classes to create and return allsegs and allkinds.
- allkinds can be None.
- """
- return self.allsegs, self.allkinds
-
- def _get_lowers_and_uppers(self):
- """
- Return (lowers,uppers) for filled contours.
- """
- lowers = self._levels[:-1]
- if self.zmin == lowers[0]:
- # Include minimum values in lowest interval
- lowers = lowers.copy() # so we don't change self._levels
- if self.logscale:
- lowers[0] = 0.99 * self.zmin
- else:
- lowers[0] -= 1
- uppers = self._levels[1:]
- return (lowers, uppers)
-
- def _make_paths(self, segs, kinds):
- if kinds is not None:
- return [mpath.Path(seg, codes=kind)
- for seg, kind in zip(segs, kinds)]
- else:
- return [mpath.Path(seg) for seg in segs]
-
- def changed(self):
- tcolors = [(tuple(rgba),)
- for rgba in self.to_rgba(self.cvalues, alpha=self.alpha)]
- self.tcolors = tcolors
- hatches = self.hatches * len(tcolors)
- for color, hatch, collection in zip(tcolors, hatches,
- self.collections):
- if self.filled:
- collection.set_facecolor(color)
- # update the collection's hatch (may be None)
- collection.set_hatch(hatch)
- else:
- collection.set_color(color)
- for label, cv in zip(self.labelTexts, self.labelCValues):
- label.set_alpha(self.alpha)
- label.set_color(self.labelMappable.to_rgba(cv))
- # add label colors
- cm.ScalarMappable.changed(self)
-
- def _autolev(self, N):
- """
- Select contour levels to span the data.
-
- We need two more levels for filled contours than for
- line contours, because for the latter we need to specify
- the lower and upper boundary of each range. For example,
- a single contour boundary, say at z = 0, requires only
- one contour line, but two filled regions, and therefore
- three levels to provide boundaries for both regions.
- """
- if self.locator is None:
- if self.logscale:
- self.locator = ticker.LogLocator()
- else:
- self.locator = ticker.MaxNLocator(N + 1, min_n_ticks=1)
-
- lev = self.locator.tick_values(self.zmin, self.zmax)
- self._auto = True
- return lev
-
- def _contour_level_args(self, z, args):
- """
- Determine the contour levels and store in self.levels.
- """
- if self.filled:
- fn = 'contourf'
- else:
- fn = 'contour'
- self._auto = False
- if self.levels is None:
- if len(args) == 0:
- levels_arg = 7 # Default, hard-wired.
- else:
- levels_arg = args[0]
- else:
- levels_arg = self.levels
- if isinstance(levels_arg, Integral):
- self.levels = self._autolev(levels_arg)
- else:
- self.levels = np.asarray(levels_arg).astype(np.float64)
-
- if not self.filled:
- inside = (self.levels > self.zmin) & (self.levels < self.zmax)
- self.levels = self.levels[inside]
- if len(self.levels) == 0:
- self.levels = [self.zmin]
- warnings.warn("No contour levels were found"
- " within the data range.")
-
- if self.filled and len(self.levels) < 2:
- raise ValueError("Filled contours require at least 2 levels.")
-
- if len(self.levels) > 1 and np.min(np.diff(self.levels)) <= 0.0:
- raise ValueError("Contour levels must be increasing")
-
- def _process_levels(self):
- """
- Assign values to :attr:`layers` based on :attr:`levels`,
- adding extended layers as needed if contours are filled.
-
- For line contours, layers simply coincide with levels;
- a line is a thin layer. No extended levels are needed
- with line contours.
- """
- # Make a private _levels to include extended regions; we
- # want to leave the original levels attribute unchanged.
- # (Colorbar needs this even for line contours.)
- self._levels = list(self.levels)
-
- if self.extend in ('both', 'min'):
- self._levels.insert(0, min(self.levels[0], self.zmin) - 1)
- if self.extend in ('both', 'max'):
- self._levels.append(max(self.levels[-1], self.zmax) + 1)
- self._levels = np.asarray(self._levels)
-
- if not self.filled:
- self.layers = self.levels
- return
-
- # layer values are mid-way between levels
- self.layers = 0.5 * (self._levels[:-1] + self._levels[1:])
- # ...except that extended layers must be outside the
- # normed range:
- if self.extend in ('both', 'min'):
- self.layers[0] = -1e150
- if self.extend in ('both', 'max'):
- self.layers[-1] = 1e150
-
- def _process_colors(self):
- """
- Color argument processing for contouring.
-
- Note that we base the color mapping on the contour levels
- and layers, not on the actual range of the Z values. This
- means we don't have to worry about bad values in Z, and we
- always have the full dynamic range available for the selected
- levels.
-
- The color is based on the midpoint of the layer, except for
- extended end layers. By default, the norm vmin and vmax
- are the extreme values of the non-extended levels. Hence,
- the layer color extremes are not the extreme values of
- the colormap itself, but approach those values as the number
- of levels increases. An advantage of this scheme is that
- line contours, when added to filled contours, take on
- colors that are consistent with those of the filled regions;
- for example, a contour line on the boundary between two
- regions will have a color intermediate between those
- of the regions.
-
- """
- self.monochrome = self.cmap.monochrome
- if self.colors is not None:
- # Generate integers for direct indexing.
- i0, i1 = 0, len(self.levels)
- if self.filled:
- i1 -= 1
- # Out of range indices for over and under:
- if self.extend in ('both', 'min'):
- i0 -= 1
- if self.extend in ('both', 'max'):
- i1 += 1
- self.cvalues = list(range(i0, i1))
- self.set_norm(colors.NoNorm())
- else:
- self.cvalues = self.layers
- self.set_array(self.levels)
- self.autoscale_None()
- if self.extend in ('both', 'max', 'min'):
- self.norm.clip = False
-
- # self.tcolors are set by the "changed" method
-
- def _process_linewidths(self):
- linewidths = self.linewidths
- Nlev = len(self.levels)
- if linewidths is None:
- tlinewidths = [(mpl.rcParams['lines.linewidth'],)] * Nlev
- else:
- if not cbook.iterable(linewidths):
- linewidths = [linewidths] * Nlev
- else:
- linewidths = list(linewidths)
- if len(linewidths) < Nlev:
- nreps = int(np.ceil(Nlev / len(linewidths)))
- linewidths = linewidths * nreps
- if len(linewidths) > Nlev:
- linewidths = linewidths[:Nlev]
- tlinewidths = [(w,) for w in linewidths]
- return tlinewidths
-
- def _process_linestyles(self):
- linestyles = self.linestyles
- Nlev = len(self.levels)
- if linestyles is None:
- tlinestyles = ['solid'] * Nlev
- if self.monochrome:
- neg_ls = mpl.rcParams['contour.negative_linestyle']
- eps = - (self.zmax - self.zmin) * 1e-15
- for i, lev in enumerate(self.levels):
- if lev < eps:
- tlinestyles[i] = neg_ls
- else:
- if isinstance(linestyles, six.string_types):
- tlinestyles = [linestyles] * Nlev
- elif cbook.iterable(linestyles):
- tlinestyles = list(linestyles)
- if len(tlinestyles) < Nlev:
- nreps = int(np.ceil(Nlev / len(linestyles)))
- tlinestyles = tlinestyles * nreps
- if len(tlinestyles) > Nlev:
- tlinestyles = tlinestyles[:Nlev]
- else:
- raise ValueError("Unrecognized type for linestyles kwarg")
- return tlinestyles
-
- def get_alpha(self):
- """returns alpha to be applied to all ContourSet artists"""
- return self.alpha
-
- def set_alpha(self, alpha):
- """
- Set the alpha blending value for all ContourSet artists.
- *alpha* must be between 0 (transparent) and 1 (opaque).
- """
- self.alpha = alpha
- self.changed()
-
- def find_nearest_contour(self, x, y, indices=None, pixel=True):
- """
- Finds contour that is closest to a point. Defaults to
- measuring distance in pixels (screen space - useful for manual
- contour labeling), but this can be controlled via a keyword
- argument.
-
- Returns a tuple containing the contour, segment, index of
- segment, x & y of segment point and distance to minimum point.
-
- Optional keyword arguments:
-
- *indices*:
- Indexes of contour levels to consider when looking for
- nearest point. Defaults to using all levels.
-
- *pixel*:
- If *True*, measure distance in pixel space, if not, measure
- distance in axes space. Defaults to *True*.
-
- """
-
- # This function uses a method that is probably quite
- # inefficient based on converting each contour segment to
- # pixel coordinates and then comparing the given point to
- # those coordinates for each contour. This will probably be
- # quite slow for complex contours, but for normal use it works
- # sufficiently well that the time is not noticeable.
- # Nonetheless, improvements could probably be made.
-
- if indices is None:
- indices = list(xrange(len(self.levels)))
-
- dmin = np.inf
- conmin = None
- segmin = None
- xmin = None
- ymin = None
-
- point = np.array([x, y])
-
- for icon in indices:
- con = self.collections[icon]
- trans = con.get_transform()
- paths = con.get_paths()
-
- for segNum, linepath in enumerate(paths):
- lc = linepath.vertices
- # transfer all data points to screen coordinates if desired
- if pixel:
- lc = trans.transform(lc)
-
- d, xc, leg = _find_closest_point_on_path(lc, point)
- if d < dmin:
- dmin = d
- conmin = icon
- segmin = segNum
- imin = leg[1]
- xmin = xc[0]
- ymin = xc[1]
-
- return (conmin, segmin, imin, xmin, ymin, dmin)
-
-
-class QuadContourSet(ContourSet):
- """
- Create and store a set of contour lines or filled regions.
-
- User-callable method: `~axes.Axes.clabel`
-
- Attributes
- ----------
- ax:
- The axes object in which the contours are drawn.
-
- collections:
- A silent_list of LineCollections or PolyCollections.
-
- levels:
- Contour levels.
-
- layers:
- Same as levels for line contours; half-way between
- levels for filled contours. See :meth:`_process_colors` method.
- """
-
- def _process_args(self, *args, **kwargs):
- """
- Process args and kwargs.
- """
- if isinstance(args[0], QuadContourSet):
- if self.levels is None:
- self.levels = args[0].levels
- self.zmin = args[0].zmin
- self.zmax = args[0].zmax
- self._corner_mask = args[0]._corner_mask
- contour_generator = args[0]._contour_generator
- self._mins = args[0]._mins
- self._maxs = args[0]._maxs
- else:
- self._corner_mask = kwargs.pop('corner_mask', None)
- if self._corner_mask is None:
- self._corner_mask = mpl.rcParams['contour.corner_mask']
-
- x, y, z = self._contour_args(args, kwargs)
-
- _mask = ma.getmask(z)
- if _mask is ma.nomask or not _mask.any():
- _mask = None
-
- contour_generator = _contour.QuadContourGenerator(
- x, y, z.filled(), _mask, self._corner_mask, self.nchunk)
-
- t = self.get_transform()
-
- # if the transform is not trans data, and some part of it
- # contains transData, transform the xs and ys to data coordinates
- if (t != self.ax.transData and
- any(t.contains_branch_seperately(self.ax.transData))):
- trans_to_data = t - self.ax.transData
- pts = (np.vstack([x.flat, y.flat]).T)
- transformed_pts = trans_to_data.transform(pts)
- x = transformed_pts[..., 0]
- y = transformed_pts[..., 1]
-
- self._mins = [ma.min(x), ma.min(y)]
- self._maxs = [ma.max(x), ma.max(y)]
-
- self._contour_generator = contour_generator
-
- return kwargs
-
- def _get_allsegs_and_allkinds(self):
- """Compute ``allsegs`` and ``allkinds`` using C extension."""
- allsegs = []
- if self.filled:
- lowers, uppers = self._get_lowers_and_uppers()
- allkinds = []
- for level, level_upper in zip(lowers, uppers):
- vertices, kinds = \
- self._contour_generator.create_filled_contour(
- level, level_upper)
- allsegs.append(vertices)
- allkinds.append(kinds)
- else:
- allkinds = None
- for level in self.levels:
- vertices = self._contour_generator.create_contour(level)
- allsegs.append(vertices)
- return allsegs, allkinds
-
- def _contour_args(self, args, kwargs):
- if self.filled:
- fn = 'contourf'
- else:
- fn = 'contour'
- Nargs = len(args)
- if Nargs <= 2:
- z = ma.asarray(args[0], dtype=np.float64)
- x, y = self._initialize_x_y(z)
- args = args[1:]
- elif Nargs <= 4:
- x, y, z = self._check_xyz(args[:3], kwargs)
- args = args[3:]
- else:
- raise TypeError("Too many arguments to %s; see help(%s)" %
- (fn, fn))
- z = ma.masked_invalid(z, copy=False)
- self.zmax = float(z.max())
- self.zmin = float(z.min())
- if self.logscale and self.zmin <= 0:
- z = ma.masked_where(z <= 0, z)
- warnings.warn('Log scale: values of z <= 0 have been masked')
- self.zmin = float(z.min())
- self._contour_level_args(z, args)
- return (x, y, z)
-
- def _check_xyz(self, args, kwargs):
- """
- For functions like contour, check that the dimensions
- of the input arrays match; if x and y are 1D, convert
- them to 2D using meshgrid.
-
- Possible change: I think we should make and use an ArgumentError
- Exception class (here and elsewhere).
- """
- x, y = args[:2]
- kwargs = self.ax._process_unit_info(xdata=x, ydata=y, kwargs=kwargs)
- x = self.ax.convert_xunits(x)
- y = self.ax.convert_yunits(y)
-
- x = np.asarray(x, dtype=np.float64)
- y = np.asarray(y, dtype=np.float64)
- z = ma.asarray(args[2], dtype=np.float64)
-
- if z.ndim != 2:
- raise TypeError("Input z must be a 2D array.")
- elif z.shape[0] < 2 or z.shape[1] < 2:
- raise TypeError("Input z must be at least a 2x2 array.")
- else:
- Ny, Nx = z.shape
-
- if x.ndim != y.ndim:
- raise TypeError("Number of dimensions of x and y should match.")
-
- if x.ndim == 1:
-
- nx, = x.shape
- ny, = y.shape
-
- if nx != Nx:
- raise TypeError("Length of x must be number of columns in z.")
-
- if ny != Ny:
- raise TypeError("Length of y must be number of rows in z.")
-
- x, y = np.meshgrid(x, y)
-
- elif x.ndim == 2:
-
- if x.shape != z.shape:
- raise TypeError("Shape of x does not match that of z: found "
- "{0} instead of {1}.".format(x.shape, z.shape))
-
- if y.shape != z.shape:
- raise TypeError("Shape of y does not match that of z: found "
- "{0} instead of {1}.".format(y.shape, z.shape))
- else:
- raise TypeError("Inputs x and y must be 1D or 2D.")
-
- return x, y, z
-
- def _initialize_x_y(self, z):
- """
- Return X, Y arrays such that contour(Z) will match imshow(Z)
- if origin is not None.
- The center of pixel Z[i,j] depends on origin:
- if origin is None, x = j, y = i;
- if origin is 'lower', x = j + 0.5, y = i + 0.5;
- if origin is 'upper', x = j + 0.5, y = Nrows - i - 0.5
- If extent is not None, x and y will be scaled to match,
- as in imshow.
- If origin is None and extent is not None, then extent
- will give the minimum and maximum values of x and y.
- """
- if z.ndim != 2:
- raise TypeError("Input must be a 2D array.")
- elif z.shape[0] < 2 or z.shape[1] < 2:
- raise TypeError("Input z must be at least a 2x2 array.")
- else:
- Ny, Nx = z.shape
- if self.origin is None: # Not for image-matching.
- if self.extent is None:
- return np.meshgrid(np.arange(Nx), np.arange(Ny))
- else:
- x0, x1, y0, y1 = self.extent
- x = np.linspace(x0, x1, Nx)
- y = np.linspace(y0, y1, Ny)
- return np.meshgrid(x, y)
- # Match image behavior:
- if self.extent is None:
- x0, x1, y0, y1 = (0, Nx, 0, Ny)
- else:
- x0, x1, y0, y1 = self.extent
- dx = (x1 - x0) / Nx
- dy = (y1 - y0) / Ny
- x = x0 + (np.arange(Nx) + 0.5) * dx
- y = y0 + (np.arange(Ny) + 0.5) * dy
- if self.origin == 'upper':
- y = y[::-1]
- return np.meshgrid(x, y)
-
- _contour_doc = """
- Plot contours.
-
- Call signature::
-
- contour([X, Y,] Z, [levels], **kwargs)
-
- :func:`~matplotlib.pyplot.contour` and
- :func:`~matplotlib.pyplot.contourf` draw contour lines and
- filled contours, respectively. Except as noted, function
- signatures and return values are the same for both versions.
-
-
- Parameters
- ----------
- X, Y : array-like, optional
- The coordinates of the values in *Z*.
-
- *X* and *Y* must both be 2-D with the same shape as *Z* (e.g.
- created via :func:`numpy.meshgrid`), or they must both be 1-D such
- that ``len(X) == M`` is the number of columns in *Z* and
- ``len(Y) == N`` is the number of rows in *Z*.
-
- If not given, they are assumed to be integer indices, i.e.
- ``X = range(M)``, ``Y = range(N)``.
-
- Z : array-like(N, M)
- The height values over which the contour is drawn.
-
- levels : int or array-like, optional
- Determines the number and positions of the contour lines / regions.
-
- If an int *n*, use *n* data intervals; i.e. draw *n+1* contour
- lines. The level heights are automatically chosen.
-
- If array-like, draw contour lines at the specified levels.
- The values must be in increasing order.
-
- Returns
- -------
- :class:`~matplotlib.contour.QuadContourSet`
-
- Other Parameters
- ----------------
- corner_mask : bool, optional
- Enable/disable corner masking, which only has an effect if *Z* is
- a masked array. If ``False``, any quad touching a masked point is
- masked out. If ``True``, only the triangular corners of quads
- nearest those points are always masked out, other triangular
- corners comprising three unmasked points are contoured as usual.
-
- Defaults to ``rcParams['contour.corner_mask']``, which defaults to
- ``True``.
-
- colors : color string or sequence of colors, optional
- The colors of the levels, i.e. the lines for `.contour` and the
- areas for `.contourf`.
-
- The sequence is cycled for the levels in ascending order. If the
- sequence is shorter than the number of levels, it's repeated.
-
- As a shortcut, single color strings may be used in place of
- one-element lists, i.e. ``'red'`` instead of ``['red']`` to color
- all levels with the same color. This shortcut does only work for
- color strings, not for other ways of specifying colors.
-
- By default (value *None*), the colormap specified by *cmap*
- will be used.
-
- alpha : float, optional
- The alpha blending value, between 0 (transparent) and 1 (opaque).
-
- cmap : str or `.Colormap`, optional
- A `.Colormap` instance or registered colormap name. The colormap
- maps the level values to colors.
- Defaults to :rc:`image.cmap`.
-
- If given, *colors* take precedence over *cmap*.
-
- norm : `~matplotlib.colors.Normalize`, optional
- If a colormap is used, the `.Normalize` instance scales the level
- values to the canonical colormap range [0, 1] for mapping to
- colors. If not given, the default linear scaling is used.
-
- vmin, vmax : float, optional
- If not *None*, either or both of these values will be supplied to
- the `.Normalize` instance, overriding the default color scaling
- based on *levels*.
-
- origin : {*None*, 'upper', 'lower', 'image'}, optional
- Determines the orientation and exact position of *Z* by specifying
- the position of ``Z[0, 0]``. This is only relevant, if *X*, *Y*
- are not given.
-
- - *None*: ``Z[0, 0]`` is at X=0, Y=0 in the lower left corner.
- - 'lower': ``Z[0, 0]`` is at X=0.5, Y=0.5 in the lower left corner.
- - 'upper': ``Z[0, 0]`` is at X=N+0.5, Y=0.5 in the upper left
- corner.
- - 'image': Use the value from :rc:`image.origin`. Note: The value
- *None* in the rcParam is currently handled as 'lower'.
-
- extent : (x0, x1, y0, y1), optional
- If *origin* is not *None*, then *extent* is interpreted as
- in :func:`matplotlib.pyplot.imshow`: it gives the outer
- pixel boundaries. In this case, the position of Z[0,0]
- is the center of the pixel, not a corner. If *origin* is
- *None*, then (*x0*, *y0*) is the position of Z[0,0], and
- (*x1*, *y1*) is the position of Z[-1,-1].
-
- This keyword is not active if *X* and *Y* are specified in
- the call to contour.
-
- locator : ticker.Locator subclass, optional
- The locator is used to determine the contour levels if they
- are not given explicitly via *levels*.
- Defaults to `~.ticker.MaxNLocator`.
-
- extend : {'neither', 'both', 'min', 'max'}, optional
- Unless this is 'neither', contour levels are automatically
- added to one or both ends of the range so that all data
- are included. These added ranges are then mapped to the
- special colormap values which default to the ends of the
- colormap range, but can be set via
- :meth:`matplotlib.colors.Colormap.set_under` and
- :meth:`matplotlib.colors.Colormap.set_over` methods.
-
- xunits, yunits : registered units, optional
- Override axis units by specifying an instance of a
- :class:`matplotlib.units.ConversionInterface`.
-
- antialiased : bool, optinal
- Enable antialiasing, overriding the defaults. For
- filled contours, the default is *True*. For line contours,
- it is taken from :rc:`lines.antialiased`.
-
- Nchunk : int >= 0, optional
- If 0, no subdivision of the domain. Specify a positive integer to
- divide the domain into subdomains of *nchunk* by *nchunk* quads.
- Chunking reduces the maximum length of polygons generated by the
- contouring algorithm which reduces the rendering workload passed
- on to the backend and also requires slightly less RAM. It can
- however introduce rendering artifacts at chunk boundaries depending
- on the backend, the *antialiased* flag and value of *alpha*.
-
- linewidths : float or sequence of float, optional
- *Only applies to* `.contour`.
-
- The line width of the contour lines.
-
- If a number, all levels will be plotted with this linewidth.
-
- If a sequence, the levels in ascending order will be plotted with
- the linewidths in the order specified.
-
- Defaults to :rc:`lines.linewidth`.
-
- linestyles : {*None*, 'solid', 'dashed', 'dashdot', 'dotted'}, optional
- *Only applies to* `.contour`.
-
- If *linestyles* is *None*, the default is 'solid' unless the lines
- are monochrome. In that case, negative contours will take their
- linestyle from :rc:`contour.negative_linestyle` setting.
-
- *linestyles* can also be an iterable of the above strings
- specifying a set of linestyles to be used. If this
- iterable is shorter than the number of contour levels
- it will be repeated as necessary.
-
- hatches : List[str], optional
- *Only applies to* `.contourf`.
-
- A list of cross hatch patterns to use on the filled areas.
- If None, no hatching will be added to the contour.
- Hatching is supported in the PostScript, PDF, SVG and Agg
- backends only.
-
-
- Notes
- -----
- 1. :func:`~matplotlib.pyplot.contourf` differs from the MATLAB
- version in that it does not draw the polygon edges.
- To draw edges, add line contours with
- calls to :func:`~matplotlib.pyplot.contour`.
-
- 2. contourf fills intervals that are closed at the top; that
- is, for boundaries *z1* and *z2*, the filled region is::
-
- z1 < Z <= z2
-
- There is one exception: if the lowest boundary coincides with
- the minimum value of the *Z* array, then that minimum value
- will be included in the lowest interval.
- """
diff --git a/contrib/python/matplotlib/py2/matplotlib/dates.py b/contrib/python/matplotlib/py2/matplotlib/dates.py
deleted file mode 100644
index 290341146d..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/dates.py
+++ /dev/null
@@ -1,1839 +0,0 @@
-"""
-Matplotlib provides sophisticated date plotting capabilities, standing on the
-shoulders of python :mod:`datetime`, the add-on modules :mod:`pytz` and
-:mod:`dateutil`.
-
-
-.. _date-format:
-
-Matplotlib date format
-----------------------
-Matplotlib represents dates using floating point numbers specifying the number
-of days since 0001-01-01 UTC, plus 1. For example, 0001-01-01, 06:00 is 1.25,
-not 0.25. Values < 1, i.e. dates before 0001-01-01 UTC are not supported.
-
-There are a number of helper functions to convert between :mod:`datetime`
-objects and Matplotlib dates:
-
-.. currentmodule:: matplotlib.dates
-
-.. autosummary::
- :nosignatures:
-
- date2num
- num2date
- num2timedelta
- epoch2num
- num2epoch
- mx2num
- drange
-
-.. note::
-
- Like Python's datetime, mpl uses the Gregorian calendar for all
- conversions between dates and floating point numbers. This practice
- is not universal, and calendar differences can cause confusing
- differences between what Python and mpl give as the number of days
- since 0001-01-01 and what other software and databases yield. For
- example, the US Naval Observatory uses a calendar that switches
- from Julian to Gregorian in October, 1582. Hence, using their
- calculator, the number of days between 0001-01-01 and 2006-04-01 is
- 732403, whereas using the Gregorian calendar via the datetime
- module we find::
-
- In [1]: date(2006, 4, 1).toordinal() - date(1, 1, 1).toordinal()
- Out[1]: 732401
-
-All the Matplotlib date converters, tickers and formatters are timezone aware.
-If no explicit timezone is provided, the rcParam ``timezone`` is assumend. If
-you want to use a custom time zone, pass a :class:`pytz.timezone` instance
-with the tz keyword argument to :func:`num2date`, :func:`.plot_date`, and any
-custom date tickers or locators you create.
-See `pytz <http://pythonhosted.org/pytz/>`_ for information on :mod:`pytz` and
-timezone handling.
-
-A wide range of specific and general purpose date tick locators and
-formatters are provided in this module. See
-:mod:`matplotlib.ticker` for general information on tick locators
-and formatters. These are described below.
-
-
-The `dateutil module <https://dateutil.readthedocs.io/en/stable/>`_ provides
-additional code to handle date ticking, making it easy to place ticks
-on any kinds of dates. See examples below.
-
-Date tickers
-------------
-
-Most of the date tickers can locate single or multiple values. For
-example::
-
- # import constants for the days of the week
- from matplotlib.dates import MO, TU, WE, TH, FR, SA, SU
-
- # tick on mondays every week
- loc = WeekdayLocator(byweekday=MO, tz=tz)
-
- # tick on mondays and saturdays
- loc = WeekdayLocator(byweekday=(MO, SA))
-
-In addition, most of the constructors take an interval argument::
-
- # tick on mondays every second week
- loc = WeekdayLocator(byweekday=MO, interval=2)
-
-The rrule locator allows completely general date ticking::
-
- # tick every 5th easter
- rule = rrulewrapper(YEARLY, byeaster=1, interval=5)
- loc = RRuleLocator(rule)
-
-Here are all the date tickers:
-
- * :class:`MicrosecondLocator`: locate microseconds
-
- * :class:`SecondLocator`: locate seconds
-
- * :class:`MinuteLocator`: locate minutes
-
- * :class:`HourLocator`: locate hours
-
- * :class:`DayLocator`: locate specified days of the month
-
- * :class:`WeekdayLocator`: Locate days of the week, e.g., MO, TU
-
- * :class:`MonthLocator`: locate months, e.g., 7 for july
-
- * :class:`YearLocator`: locate years that are multiples of base
-
- * :class:`RRuleLocator`: locate using a
- :class:`matplotlib.dates.rrulewrapper`. The
- :class:`rrulewrapper` is a simple wrapper around a
- :class:`dateutil.rrule` (`dateutil
- <https://dateutil.readthedocs.io/en/stable/>`_) which allow almost
- arbitrary date tick specifications. See `rrule example
- <../gallery/ticks_and_spines/date_demo_rrule.html>`_.
-
- * :class:`AutoDateLocator`: On autoscale, this class picks the best
- :class:`DateLocator` (e.g., :class:`RRuleLocator`)
- to set the view limits and the tick
- locations. If called with ``interval_multiples=True`` it will
- make ticks line up with sensible multiples of the tick intervals. E.g.
- if the interval is 4 hours, it will pick hours 0, 4, 8, etc as ticks.
- This behaviour is not guaranteed by default.
-
-Date formatters
----------------
-
-Here all all the date formatters:
-
- * :class:`AutoDateFormatter`: attempts to figure out the best format
- to use. This is most useful when used with the :class:`AutoDateLocator`.
-
- * :class:`DateFormatter`: use :func:`strftime` format strings
-
- * :class:`IndexDateFormatter`: date plots with implicit *x*
- indexing.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import zip
-import re
-import time
-import math
-import datetime
-import functools
-
-import warnings
-import logging
-
-from dateutil.rrule import (rrule, MO, TU, WE, TH, FR, SA, SU, YEARLY,
- MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY,
- SECONDLY)
-from dateutil.relativedelta import relativedelta
-import dateutil.parser
-import logging
-import numpy as np
-
-
-import matplotlib
-from matplotlib import rcParams
-import matplotlib.units as units
-import matplotlib.cbook as cbook
-import matplotlib.ticker as ticker
-
-_log = logging.getLogger(__name__)
-
-__all__ = ('date2num', 'num2date', 'num2timedelta', 'drange', 'epoch2num',
- 'num2epoch', 'mx2num', 'DateFormatter',
- 'IndexDateFormatter', 'AutoDateFormatter', 'DateLocator',
- 'RRuleLocator', 'AutoDateLocator', 'YearLocator',
- 'MonthLocator', 'WeekdayLocator',
- 'DayLocator', 'HourLocator', 'MinuteLocator',
- 'SecondLocator', 'MicrosecondLocator',
- 'rrule', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU',
- 'YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY',
- 'HOURLY', 'MINUTELY', 'SECONDLY', 'MICROSECONDLY', 'relativedelta',
- 'seconds', 'minutes', 'hours', 'weeks')
-
-
-_log = logging.getLogger(__name__)
-
-
-# Make a simple UTC instance so we don't always have to import
-# pytz. From the python datetime library docs:
-
-class _UTC(datetime.tzinfo):
- """UTC"""
-
- def utcoffset(self, dt):
- return datetime.timedelta(0)
-
- def tzname(self, dt):
- return str("UTC")
-
- def dst(self, dt):
- return datetime.timedelta(0)
-
-
-UTC = _UTC()
-
-
-def _get_rc_timezone():
- """
- Retrieve the preferred timeszone from the rcParams dictionary.
- """
- s = matplotlib.rcParams['timezone']
- if s == 'UTC':
- return UTC
- import pytz
- return pytz.timezone(s)
-
-
-"""
-Time-related constants.
-"""
-EPOCH_OFFSET = float(datetime.datetime(1970, 1, 1).toordinal())
-JULIAN_OFFSET = 1721424.5 # Julian date at 0001-01-01
-MICROSECONDLY = SECONDLY + 1
-HOURS_PER_DAY = 24.
-MIN_PER_HOUR = 60.
-SEC_PER_MIN = 60.
-MONTHS_PER_YEAR = 12.
-
-DAYS_PER_WEEK = 7.
-DAYS_PER_MONTH = 30.
-DAYS_PER_YEAR = 365.0
-
-MINUTES_PER_DAY = MIN_PER_HOUR * HOURS_PER_DAY
-
-SEC_PER_HOUR = SEC_PER_MIN * MIN_PER_HOUR
-SEC_PER_DAY = SEC_PER_HOUR * HOURS_PER_DAY
-SEC_PER_WEEK = SEC_PER_DAY * DAYS_PER_WEEK
-
-MUSECONDS_PER_DAY = 1e6 * SEC_PER_DAY
-
-MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY = (
- MO, TU, WE, TH, FR, SA, SU)
-WEEKDAYS = (MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY)
-
-
-def _to_ordinalf(dt):
- """
- Convert :mod:`datetime` or :mod:`date` to the Gregorian date as UTC float
- days, preserving hours, minutes, seconds and microseconds. Return value
- is a :func:`float`.
- """
- # Convert to UTC
- tzi = getattr(dt, 'tzinfo', None)
- if tzi is not None:
- dt = dt.astimezone(UTC)
- tzi = UTC
-
- base = float(dt.toordinal())
-
- # If it's sufficiently datetime-like, it will have a `date()` method
- cdate = getattr(dt, 'date', lambda: None)()
- if cdate is not None:
- # Get a datetime object at midnight UTC
- midnight_time = datetime.time(0, tzinfo=tzi)
-
- rdt = datetime.datetime.combine(cdate, midnight_time)
-
- # Append the seconds as a fraction of a day
- base += (dt - rdt).total_seconds() / SEC_PER_DAY
-
- return base
-
-
-# a version of _to_ordinalf that can operate on numpy arrays
-_to_ordinalf_np_vectorized = np.vectorize(_to_ordinalf)
-
-
-def _dt64_to_ordinalf(d):
- """
- Convert `numpy.datetime64` or an ndarray of those types to Gregorian
- date as UTC float. Roundoff is via float64 precision. Practically:
- microseconds for dates between 290301 BC, 294241 AD, milliseconds for
- larger dates (see `numpy.datetime64`). Nanoseconds aren't possible
- because we do times compared to ``0001-01-01T00:00:00`` (plus one day).
- """
-
- # the "extra" ensures that we at least allow the dynamic range out to
- # seconds. That should get out to +/-2e11 years.
- extra = d - d.astype('datetime64[s]')
- extra = extra.astype('timedelta64[ns]')
- t0 = np.datetime64('0001-01-01T00:00:00').astype('datetime64[s]')
- dt = (d.astype('datetime64[s]') - t0).astype(np.float64)
- dt += extra.astype(np.float64) / 1.0e9
- dt = dt / SEC_PER_DAY + 1.0
-
- NaT_int = np.datetime64('NaT').astype(np.int64)
- d_int = d.astype(np.int64)
- try:
- dt[d_int == NaT_int] = np.nan
- except TypeError:
- if d_int == NaT_int:
- dt = np.nan
- return dt
-
-
-def _from_ordinalf(x, tz=None):
- """
- Convert Gregorian float of the date, preserving hours, minutes,
- seconds and microseconds. Return value is a `.datetime`.
-
- The input date *x* is a float in ordinal days at UTC, and the output will
- be the specified `.datetime` object corresponding to that time in
- timezone *tz*, or if *tz* is ``None``, in the timezone specified in
- :rc:`timezone`.
- """
- if tz is None:
- tz = _get_rc_timezone()
-
- ix, remainder = divmod(x, 1)
- ix = int(ix)
- if ix < 1:
- raise ValueError('Cannot convert {} to a date. This often happens if '
- 'non-datetime values are passed to an axis that '
- 'expects datetime objects.'.format(ix))
- dt = datetime.datetime.fromordinal(ix).replace(tzinfo=UTC)
-
- # Since the input date `x` float is unable to preserve microsecond
- # precision of time representation in non-antique years, the
- # resulting datetime is rounded to the nearest multiple of
- # `musec_prec`. A value of 20 is appropriate for current dates.
- musec_prec = 20
- remainder_musec = int(round(remainder * MUSECONDS_PER_DAY / musec_prec)
- * musec_prec)
-
- # For people trying to plot with full microsecond precision, enable
- # an early-year workaround
- if x < 30 * 365:
- remainder_musec = int(round(remainder * MUSECONDS_PER_DAY))
-
- # add hours, minutes, seconds, microseconds
- dt += datetime.timedelta(microseconds=remainder_musec)
-
- return dt.astimezone(tz)
-
-
-# a version of _from_ordinalf that can operate on numpy arrays
-_from_ordinalf_np_vectorized = np.vectorize(_from_ordinalf)
-
-
-class strpdate2num(object):
- """
- Use this class to parse date strings to matplotlib datenums when
- you know the date format string of the date you are parsing.
- """
- def __init__(self, fmt):
- """ fmt: any valid strptime format is supported """
- self.fmt = fmt
-
- def __call__(self, s):
- """s : string to be converted
- return value: a date2num float
- """
- return date2num(datetime.datetime(*time.strptime(s, self.fmt)[:6]))
-
-
-class bytespdate2num(strpdate2num):
- """
- Use this class to parse date strings to matplotlib datenums when
- you know the date format string of the date you are parsing. See
- :file:`examples/misc/load_converter.py`.
- """
- def __init__(self, fmt, encoding='utf-8'):
- """
- Args:
- fmt: any valid strptime format is supported
- encoding: encoding to use on byte input (default: 'utf-8')
- """
- super(bytespdate2num, self).__init__(fmt)
- self.encoding = encoding
-
- def __call__(self, b):
- """
- Args:
- b: byte input to be converted
- Returns:
- A date2num float
- """
- s = b.decode(self.encoding)
- return super(bytespdate2num, self).__call__(s)
-
-
-# a version of dateutil.parser.parse that can operate on nump0y arrays
-_dateutil_parser_parse_np_vectorized = np.vectorize(dateutil.parser.parse)
-
-
-def datestr2num(d, default=None):
- """
- Convert a date string to a datenum using
- :func:`dateutil.parser.parse`.
-
- Parameters
- ----------
- d : string or sequence of strings
- The dates to convert.
-
- default : datetime instance, optional
- The default date to use when fields are missing in *d*.
- """
- if isinstance(d, six.string_types):
- dt = dateutil.parser.parse(d, default=default)
- return date2num(dt)
- else:
- if default is not None:
- d = [dateutil.parser.parse(s, default=default) for s in d]
- d = np.asarray(d)
- if not d.size:
- return d
- return date2num(_dateutil_parser_parse_np_vectorized(d))
-
-
-def date2num(d):
- """
- Convert datetime objects to Matplotlib dates.
-
- Parameters
- ----------
- d : `datetime.datetime` or `numpy.datetime64` or sequences of these
-
- Returns
- -------
- float or sequence of floats
- Number of days (fraction part represents hours, minutes, seconds, ms)
- since 0001-01-01 00:00:00 UTC, plus one.
-
- Notes
- -----
- The addition of one here is a historical artifact. Also, note that the
- Gregorian calendar is assumed; this is not universal practice.
- For details see the module docstring.
- """
-
- if hasattr(d, "values"):
- # this unpacks pandas series or dataframes...
- d = d.values
-
- if ((isinstance(d, np.ndarray) and np.issubdtype(d.dtype, np.datetime64))
- or isinstance(d, np.datetime64)):
- return _dt64_to_ordinalf(d)
- if not cbook.iterable(d):
- return _to_ordinalf(d)
- else:
- d = np.asarray(d)
- if not d.size:
- return d
- return _to_ordinalf_np_vectorized(d)
-
-
-def julian2num(j):
- """
- Convert a Julian date (or sequence) to a Matplotlib date (or sequence).
-
- Parameters
- ----------
- j : float or sequence of floats
- Julian date(s)
-
- Returns
- -------
- float or sequence of floats
- Matplotlib date(s)
- """
- if cbook.iterable(j):
- j = np.asarray(j)
- return j - JULIAN_OFFSET
-
-
-def num2julian(n):
- """
- Convert a Matplotlib date (or sequence) to a Julian date (or sequence).
-
- Parameters
- ----------
- n : float or sequence of floats
- Matplotlib date(s)
-
- Returns
- -------
- float or sequence of floats
- Julian date(s)
- """
- if cbook.iterable(n):
- n = np.asarray(n)
- return n + JULIAN_OFFSET
-
-
-def num2date(x, tz=None):
- """
- Convert Matplotlib dates to `~datetime.datetime` objects.
-
- Parameters
- ----------
- x : float or sequence of floats
- Number of days (fraction part represents hours, minutes, seconds)
- since 0001-01-01 00:00:00 UTC, plus one.
- tz : string, optional
- Timezone of *x* (defaults to rcparams ``timezone``).
-
- Returns
- -------
- `~datetime.datetime` or sequence of `~datetime.datetime`
- Dates are returned in timezone *tz*.
-
- If *x* is a sequence, a sequence of :class:`datetime` objects will
- be returned.
-
- Notes
- -----
- The addition of one here is a historical artifact. Also, note that the
- Gregorian calendar is assumed; this is not universal practice.
- For details, see the module docstring.
- """
- if tz is None:
- tz = _get_rc_timezone()
- if not cbook.iterable(x):
- return _from_ordinalf(x, tz)
- else:
- x = np.asarray(x)
- if not x.size:
- return x
- return _from_ordinalf_np_vectorized(x, tz).tolist()
-
-
-def _ordinalf_to_timedelta(x):
- return datetime.timedelta(days=x)
-
-
-_ordinalf_to_timedelta_np_vectorized = np.vectorize(_ordinalf_to_timedelta)
-
-
-def num2timedelta(x):
- """
- Convert number of days to a `~datetime.timedelta` object.
-
- If *x* is a sequence, a sequence of `~datetime.timedelta` objects will
- be returned.
-
- Parameters
- ----------
- x : float, sequence of floats
- Number of days. The fraction part represents hours, minutes, seconds.
-
- Returns
- -------
- `datetime.timedelta` or list[`datetime.timedelta`]
-
- """
- if not cbook.iterable(x):
- return _ordinalf_to_timedelta(x)
- else:
- x = np.asarray(x)
- if not x.size:
- return x
- return _ordinalf_to_timedelta_np_vectorized(x).tolist()
-
-
-def drange(dstart, dend, delta):
- """
- Return a sequence of equally spaced Matplotlib dates.
-
- The dates start at *dstart* and reach up to, but not including *dend*.
- They are spaced by *delta*.
-
- Parameters
- ----------
- dstart, dend : `~datetime.datetime`
- The date limits.
- delta : `datetime.timedelta`
- Spacing of the dates.
-
- Returns
- -------
- drange : `numpy.array`
- A list floats representing Matplotlib dates.
-
- """
- f1 = date2num(dstart)
- f2 = date2num(dend)
- step = delta.total_seconds() / SEC_PER_DAY
-
- # calculate the difference between dend and dstart in times of delta
- num = int(np.ceil((f2 - f1) / step))
-
- # calculate end of the interval which will be generated
- dinterval_end = dstart + num * delta
-
- # ensure, that an half open interval will be generated [dstart, dend)
- if dinterval_end >= dend:
- # if the endpoint is greated than dend, just subtract one delta
- dinterval_end -= delta
- num -= 1
-
- f2 = date2num(dinterval_end) # new float-endpoint
- return np.linspace(f1, f2, num + 1)
-
-### date tickers and formatters ###
-
-
-class DateFormatter(ticker.Formatter):
- """
- Tick location is seconds since the epoch. Use a :func:`strftime`
- format string.
-
- Python only supports :mod:`datetime` :func:`strftime` formatting
- for years greater than 1900. Thanks to Andrew Dalke, Dalke
- Scientific Software who contributed the :func:`strftime` code
- below to include dates earlier than this year.
- """
-
- illegal_s = re.compile(r"((^|[^%])(%%)*%s)")
-
- def __init__(self, fmt, tz=None):
- """
- *fmt* is a :func:`strftime` format string; *tz* is the
- :class:`tzinfo` instance.
- """
- if tz is None:
- tz = _get_rc_timezone()
- self.fmt = fmt
- self.tz = tz
-
- def __call__(self, x, pos=0):
- if x == 0:
- raise ValueError('DateFormatter found a value of x=0, which is '
- 'an illegal date. This usually occurs because '
- 'you have not informed the axis that it is '
- 'plotting dates, e.g., with ax.xaxis_date()')
- dt = num2date(x, self.tz)
- return self.strftime(dt, self.fmt)
-
- def set_tzinfo(self, tz):
- self.tz = tz
-
- def _replace_common_substr(self, s1, s2, sub1, sub2, replacement):
- """Helper function for replacing substrings sub1 and sub2
- located at the same indexes in strings s1 and s2 respectively,
- with the string replacement. It is expected that sub1 and sub2
- have the same length. Returns the pair s1, s2 after the
- substitutions.
- """
- # Find common indexes of substrings sub1 in s1 and sub2 in s2
- # and make substitutions inplace. Because this is inplace,
- # it is okay if len(replacement) != len(sub1), len(sub2).
- i = 0
- while True:
- j = s1.find(sub1, i)
- if j == -1:
- break
-
- i = j + 1
- if s2[j:j + len(sub2)] != sub2:
- continue
-
- s1 = s1[:j] + replacement + s1[j + len(sub1):]
- s2 = s2[:j] + replacement + s2[j + len(sub2):]
-
- return s1, s2
-
- def strftime_pre_1900(self, dt, fmt=None):
- """Call time.strftime for years before 1900 by rolling
- forward a multiple of 28 years.
-
- *fmt* is a :func:`strftime` format string.
-
- Dalke: I hope I did this math right. Every 28 years the
- calendar repeats, except through century leap years excepting
- the 400 year leap years. But only if you're using the Gregorian
- calendar.
- """
- if fmt is None:
- fmt = self.fmt
-
- # Since python's time module's strftime implementation does not
- # support %f microsecond (but the datetime module does), use a
- # regular expression substitution to replace instances of %f.
- # Note that this can be useful since python's floating-point
- # precision representation for datetime causes precision to be
- # more accurate closer to year 0 (around the year 2000, precision
- # can be at 10s of microseconds).
- fmt = re.sub(r'((^|[^%])(%%)*)%f',
- r'\g<1>{0:06d}'.format(dt.microsecond), fmt)
-
- year = dt.year
- # For every non-leap year century, advance by
- # 6 years to get into the 28-year repeat cycle
- delta = 2000 - year
- off = 6 * (delta // 100 + delta // 400)
- year = year + off
-
- # Move to between the years 1973 and 2000
- year1 = year + ((2000 - year) // 28) * 28
- year2 = year1 + 28
- timetuple = dt.timetuple()
- # Generate timestamp string for year and year+28
- s1 = time.strftime(fmt, (year1,) + timetuple[1:])
- s2 = time.strftime(fmt, (year2,) + timetuple[1:])
-
- # Replace instances of respective years (both 2-digit and 4-digit)
- # that are located at the same indexes of s1, s2 with dt's year.
- # Note that C++'s strftime implementation does not use padded
- # zeros or padded whitespace for %y or %Y for years before 100, but
- # uses padded zeros for %x. (For example, try the runnable examples
- # with .tm_year in the interval [-1900, -1800] on
- # http://en.cppreference.com/w/c/chrono/strftime.) For ease of
- # implementation, we always use padded zeros for %y, %Y, and %x.
- s1, s2 = self._replace_common_substr(s1, s2,
- "{0:04d}".format(year1),
- "{0:04d}".format(year2),
- "{0:04d}".format(dt.year))
- s1, s2 = self._replace_common_substr(s1, s2,
- "{0:02d}".format(year1 % 100),
- "{0:02d}".format(year2 % 100),
- "{0:02d}".format(dt.year % 100))
- return cbook.unicode_safe(s1)
-
- def strftime(self, dt, fmt=None):
- """
- Refer to documentation for :meth:`datetime.datetime.strftime`
-
- *fmt* is a :meth:`datetime.datetime.strftime` format string.
-
- Warning: For years before 1900, depending upon the current
- locale it is possible that the year displayed with %x might
- be incorrect. For years before 100, %y and %Y will yield
- zero-padded strings.
- """
- if fmt is None:
- fmt = self.fmt
- fmt = self.illegal_s.sub(r"\1", fmt)
- fmt = fmt.replace("%s", "s")
- if dt.year >= 1900:
- # Note: in python 3.3 this is okay for years >= 1000,
- # refer to http://bugs.python.org/issue1777412
- return cbook.unicode_safe(dt.strftime(fmt))
-
- return self.strftime_pre_1900(dt, fmt)
-
-
-class IndexDateFormatter(ticker.Formatter):
- """
- Use with :class:`~matplotlib.ticker.IndexLocator` to cycle format
- strings by index.
- """
- def __init__(self, t, fmt, tz=None):
- """
- *t* is a sequence of dates (floating point days). *fmt* is a
- :func:`strftime` format string.
- """
- if tz is None:
- tz = _get_rc_timezone()
- self.t = t
- self.fmt = fmt
- self.tz = tz
-
- def __call__(self, x, pos=0):
- 'Return the label for time *x* at position *pos*'
- ind = int(np.round(x))
- if ind >= len(self.t) or ind <= 0:
- return ''
-
- dt = num2date(self.t[ind], self.tz)
-
- return cbook.unicode_safe(dt.strftime(self.fmt))
-
-
-class AutoDateFormatter(ticker.Formatter):
- """
- This class attempts to figure out the best format to use. This is
- most useful when used with the :class:`AutoDateLocator`.
-
-
- The AutoDateFormatter has a scale dictionary that maps the scale
- of the tick (the distance in days between one major tick) and a
- format string. The default looks like this::
-
- self.scaled = {
- DAYS_PER_YEAR: rcParams['date.autoformat.year'],
- DAYS_PER_MONTH: rcParams['date.autoformat.month'],
- 1.0: rcParams['date.autoformat.day'],
- 1. / HOURS_PER_DAY: rcParams['date.autoformat.hour'],
- 1. / (MINUTES_PER_DAY): rcParams['date.autoformat.minute'],
- 1. / (SEC_PER_DAY): rcParams['date.autoformat.second'],
- 1. / (MUSECONDS_PER_DAY): rcParams['date.autoformat.microsecond'],
- }
-
-
- The algorithm picks the key in the dictionary that is >= the
- current scale and uses that format string. You can customize this
- dictionary by doing::
-
-
- >>> locator = AutoDateLocator()
- >>> formatter = AutoDateFormatter(locator)
- >>> formatter.scaled[1/(24.*60.)] = '%M:%S' # only show min and sec
-
- A custom :class:`~matplotlib.ticker.FuncFormatter` can also be used.
- The following example shows how to use a custom format function to strip
- trailing zeros from decimal seconds and adds the date to the first
- ticklabel::
-
- >>> def my_format_function(x, pos=None):
- ... x = matplotlib.dates.num2date(x)
- ... if pos == 0:
- ... fmt = '%D %H:%M:%S.%f'
- ... else:
- ... fmt = '%H:%M:%S.%f'
- ... label = x.strftime(fmt)
- ... label = label.rstrip("0")
- ... label = label.rstrip(".")
- ... return label
- >>> from matplotlib.ticker import FuncFormatter
- >>> formatter.scaled[1/(24.*60.)] = FuncFormatter(my_format_function)
- """
-
- # This can be improved by providing some user-level direction on
- # how to choose the best format (precedence, etc...)
-
- # Perhaps a 'struct' that has a field for each time-type where a
- # zero would indicate "don't show" and a number would indicate
- # "show" with some sort of priority. Same priorities could mean
- # show all with the same priority.
-
- # Or more simply, perhaps just a format string for each
- # possibility...
-
- def __init__(self, locator, tz=None, defaultfmt='%Y-%m-%d'):
- """
- Autoformat the date labels. The default format is the one to use
- if none of the values in ``self.scaled`` are greater than the unit
- returned by ``locator._get_unit()``.
- """
- self._locator = locator
- self._tz = tz
- self.defaultfmt = defaultfmt
- self._formatter = DateFormatter(self.defaultfmt, tz)
- self.scaled = {DAYS_PER_YEAR: rcParams['date.autoformatter.year'],
- DAYS_PER_MONTH: rcParams['date.autoformatter.month'],
- 1.0: rcParams['date.autoformatter.day'],
- 1. / HOURS_PER_DAY: rcParams['date.autoformatter.hour'],
- 1. / (MINUTES_PER_DAY):
- rcParams['date.autoformatter.minute'],
- 1. / (SEC_PER_DAY):
- rcParams['date.autoformatter.second'],
- 1. / (MUSECONDS_PER_DAY):
- rcParams['date.autoformatter.microsecond']}
-
- def __call__(self, x, pos=None):
- locator_unit_scale = float(self._locator._get_unit())
- # Pick the first scale which is greater than the locator unit.
- fmt = next((fmt for scale, fmt in sorted(self.scaled.items())
- if scale >= locator_unit_scale),
- self.defaultfmt)
-
- if isinstance(fmt, six.string_types):
- self._formatter = DateFormatter(fmt, self._tz)
- result = self._formatter(x, pos)
- elif callable(fmt):
- result = fmt(x, pos)
- else:
- raise TypeError('Unexpected type passed to {0!r}.'.format(self))
-
- return result
-
-
-class rrulewrapper(object):
- def __init__(self, freq, tzinfo=None, **kwargs):
- kwargs['freq'] = freq
- self._base_tzinfo = tzinfo
-
- self._update_rrule(**kwargs)
-
- def set(self, **kwargs):
- self._construct.update(kwargs)
-
- self._update_rrule(**self._construct)
-
- def _update_rrule(self, **kwargs):
- tzinfo = self._base_tzinfo
-
- # rrule does not play nicely with time zones - especially pytz time
- # zones, it's best to use naive zones and attach timezones once the
- # datetimes are returned
- if 'dtstart' in kwargs:
- dtstart = kwargs['dtstart']
- if dtstart.tzinfo is not None:
- if tzinfo is None:
- tzinfo = dtstart.tzinfo
- else:
- dtstart = dtstart.astimezone(tzinfo)
-
- kwargs['dtstart'] = dtstart.replace(tzinfo=None)
-
- if 'until' in kwargs:
- until = kwargs['until']
- if until.tzinfo is not None:
- if tzinfo is not None:
- until = until.astimezone(tzinfo)
- else:
- raise ValueError('until cannot be aware if dtstart '
- 'is naive and tzinfo is None')
-
- kwargs['until'] = until.replace(tzinfo=None)
-
- self._construct = kwargs.copy()
- self._tzinfo = tzinfo
- self._rrule = rrule(**self._construct)
-
- def _attach_tzinfo(self, dt, tzinfo):
- # pytz zones are attached by "localizing" the datetime
- if hasattr(tzinfo, 'localize'):
- return tzinfo.localize(dt, is_dst=True)
-
- return dt.replace(tzinfo=tzinfo)
-
- def _aware_return_wrapper(self, f, returns_list=False):
- """Decorator function that allows rrule methods to handle tzinfo."""
- # This is only necessary if we're actually attaching a tzinfo
- if self._tzinfo is None:
- return f
-
- # All datetime arguments must be naive. If they are not naive, they are
- # converted to the _tzinfo zone before dropping the zone.
- def normalize_arg(arg):
- if isinstance(arg, datetime.datetime) and arg.tzinfo is not None:
- if arg.tzinfo is not self._tzinfo:
- arg = arg.astimezone(self._tzinfo)
-
- return arg.replace(tzinfo=None)
-
- return arg
-
- def normalize_args(args, kwargs):
- args = tuple(normalize_arg(arg) for arg in args)
- kwargs = {kw: normalize_arg(arg) for kw, arg in kwargs.items()}
-
- return args, kwargs
-
- # There are two kinds of functions we care about - ones that return
- # dates and ones that return lists of dates.
- if not returns_list:
- def inner_func(*args, **kwargs):
- args, kwargs = normalize_args(args, kwargs)
- dt = f(*args, **kwargs)
- return self._attach_tzinfo(dt, self._tzinfo)
- else:
- def inner_func(*args, **kwargs):
- args, kwargs = normalize_args(args, kwargs)
- dts = f(*args, **kwargs)
- return [self._attach_tzinfo(dt, self._tzinfo) for dt in dts]
-
- return functools.wraps(f)(inner_func)
-
- def __getattr__(self, name):
- if name in self.__dict__:
- return self.__dict__[name]
-
- f = getattr(self._rrule, name)
-
- if name in {'after', 'before'}:
- return self._aware_return_wrapper(f)
- elif name in {'xafter', 'xbefore', 'between'}:
- return self._aware_return_wrapper(f, returns_list=True)
- else:
- return f
-
- def __setstate__(self, state):
- self.__dict__.update(state)
-
-
-class DateLocator(ticker.Locator):
- """
- Determines the tick locations when plotting dates.
-
- This class is subclassed by other Locators and
- is not meant to be used on its own.
- """
- hms0d = {'byhour': 0, 'byminute': 0, 'bysecond': 0}
-
- def __init__(self, tz=None):
- """
- *tz* is a :class:`tzinfo` instance.
- """
- if tz is None:
- tz = _get_rc_timezone()
- self.tz = tz
-
- def set_tzinfo(self, tz):
- """
- Set time zone info.
- """
- self.tz = tz
-
- def datalim_to_dt(self):
- """
- Convert axis data interval to datetime objects.
- """
- dmin, dmax = self.axis.get_data_interval()
- if dmin > dmax:
- dmin, dmax = dmax, dmin
- if dmin < 1:
- raise ValueError('datalim minimum {} is less than 1 and '
- 'is an invalid Matplotlib date value. This often '
- 'happens if you pass a non-datetime '
- 'value to an axis that has datetime units'
- .format(dmin))
- return num2date(dmin, self.tz), num2date(dmax, self.tz)
-
- def viewlim_to_dt(self):
- """
- Converts the view interval to datetime objects.
- """
- vmin, vmax = self.axis.get_view_interval()
- if vmin > vmax:
- vmin, vmax = vmax, vmin
- if vmin < 1:
- raise ValueError('view limit minimum {} is less than 1 and '
- 'is an invalid Matplotlib date value. This '
- 'often happens if you pass a non-datetime '
- 'value to an axis that has datetime units'
- .format(vmin))
- return num2date(vmin, self.tz), num2date(vmax, self.tz)
-
- def _get_unit(self):
- """
- Return how many days a unit of the locator is; used for
- intelligent autoscaling.
- """
- return 1
-
- def _get_interval(self):
- """
- Return the number of units for each tick.
- """
- return 1
-
- def nonsingular(self, vmin, vmax):
- """
- Given the proposed upper and lower extent, adjust the range
- if it is too close to being singular (i.e. a range of ~0).
-
- """
- unit = self._get_unit()
- interval = self._get_interval()
- if abs(vmax - vmin) < 1e-6:
- vmin -= 2 * unit * interval
- vmax += 2 * unit * interval
- return vmin, vmax
-
-
-class RRuleLocator(DateLocator):
- # use the dateutil rrule instance
-
- def __init__(self, o, tz=None):
- DateLocator.__init__(self, tz)
- self.rule = o
-
- def __call__(self):
- # if no data have been set, this will tank with a ValueError
- try:
- dmin, dmax = self.viewlim_to_dt()
- except ValueError:
- return []
-
- return self.tick_values(dmin, dmax)
-
- def tick_values(self, vmin, vmax):
- delta = relativedelta(vmax, vmin)
-
- # We need to cap at the endpoints of valid datetime
- try:
- start = vmin - delta
- except (ValueError, OverflowError):
- start = _from_ordinalf(1.0)
-
- try:
- stop = vmax + delta
- except (ValueError, OverflowError):
- # The magic number!
- stop = _from_ordinalf(3652059.9999999)
-
- self.rule.set(dtstart=start, until=stop)
-
- dates = self.rule.between(vmin, vmax, True)
- if len(dates) == 0:
- return date2num([vmin, vmax])
- return self.raise_if_exceeds(date2num(dates))
-
- def _get_unit(self):
- """
- Return how many days a unit of the locator is; used for
- intelligent autoscaling.
- """
- freq = self.rule._rrule._freq
- return self.get_unit_generic(freq)
-
- @staticmethod
- def get_unit_generic(freq):
- if freq == YEARLY:
- return DAYS_PER_YEAR
- elif freq == MONTHLY:
- return DAYS_PER_MONTH
- elif freq == WEEKLY:
- return DAYS_PER_WEEK
- elif freq == DAILY:
- return 1.0
- elif freq == HOURLY:
- return 1.0 / HOURS_PER_DAY
- elif freq == MINUTELY:
- return 1.0 / MINUTES_PER_DAY
- elif freq == SECONDLY:
- return 1.0 / SEC_PER_DAY
- else:
- # error
- return -1 # or should this just return '1'?
-
- def _get_interval(self):
- return self.rule._rrule._interval
-
- def autoscale(self):
- """
- Set the view limits to include the data range.
- """
- dmin, dmax = self.datalim_to_dt()
- delta = relativedelta(dmax, dmin)
-
- # We need to cap at the endpoints of valid datetime
- try:
- start = dmin - delta
- except ValueError:
- start = _from_ordinalf(1.0)
-
- try:
- stop = dmax + delta
- except ValueError:
- # The magic number!
- stop = _from_ordinalf(3652059.9999999)
-
- self.rule.set(dtstart=start, until=stop)
- dmin, dmax = self.datalim_to_dt()
-
- vmin = self.rule.before(dmin, True)
- if not vmin:
- vmin = dmin
-
- vmax = self.rule.after(dmax, True)
- if not vmax:
- vmax = dmax
-
- vmin = date2num(vmin)
- vmax = date2num(vmax)
-
- return self.nonsingular(vmin, vmax)
-
-
-class AutoDateLocator(DateLocator):
- """
- On autoscale, this class picks the best
- :class:`DateLocator` to set the view limits and the tick
- locations.
- """
- def __init__(self, tz=None, minticks=5, maxticks=None,
- interval_multiples=False):
- """
- *minticks* is the minimum number of ticks desired, which is used to
- select the type of ticking (yearly, monthly, etc.).
-
- *maxticks* is the maximum number of ticks desired, which controls
- any interval between ticks (ticking every other, every 3, etc.).
- For really fine-grained control, this can be a dictionary mapping
- individual rrule frequency constants (YEARLY, MONTHLY, etc.)
- to their own maximum number of ticks. This can be used to keep
- the number of ticks appropriate to the format chosen in
- :class:`AutoDateFormatter`. Any frequency not specified in this
- dictionary is given a default value.
-
- *tz* is a :class:`tzinfo` instance.
-
- *interval_multiples* is a boolean that indicates whether ticks
- should be chosen to be multiple of the interval. This will lock
- ticks to 'nicer' locations. For example, this will force the
- ticks to be at hours 0,6,12,18 when hourly ticking is done at
- 6 hour intervals.
-
- The AutoDateLocator has an interval dictionary that maps the
- frequency of the tick (a constant from dateutil.rrule) and a
- multiple allowed for that ticking. The default looks like this::
-
- self.intervald = {
- YEARLY : [1, 2, 4, 5, 10, 20, 40, 50, 100, 200, 400, 500,
- 1000, 2000, 4000, 5000, 10000],
- MONTHLY : [1, 2, 3, 4, 6],
- DAILY : [1, 2, 3, 7, 14],
- HOURLY : [1, 2, 3, 4, 6, 12],
- MINUTELY: [1, 5, 10, 15, 30],
- SECONDLY: [1, 5, 10, 15, 30],
- MICROSECONDLY: [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000,
- 5000, 10000, 20000, 50000, 100000, 200000, 500000,
- 1000000],
- }
-
- The interval is used to specify multiples that are appropriate for
- the frequency of ticking. For instance, every 7 days is sensible
- for daily ticks, but for minutes/seconds, 15 or 30 make sense.
- You can customize this dictionary by doing::
-
- locator = AutoDateLocator()
- locator.intervald[HOURLY] = [3] # only show every 3 hours
- """
- DateLocator.__init__(self, tz)
- self._locator = YearLocator()
- self._freq = YEARLY
- self._freqs = [YEARLY, MONTHLY, DAILY, HOURLY, MINUTELY,
- SECONDLY, MICROSECONDLY]
- self.minticks = minticks
-
- self.maxticks = {YEARLY: 11, MONTHLY: 12, DAILY: 11, HOURLY: 12,
- MINUTELY: 11, SECONDLY: 11, MICROSECONDLY: 8}
- if maxticks is not None:
- try:
- self.maxticks.update(maxticks)
- except TypeError:
- # Assume we were given an integer. Use this as the maximum
- # number of ticks for every frequency and create a
- # dictionary for this
- self.maxticks = dict.fromkeys(self._freqs, maxticks)
- self.interval_multiples = interval_multiples
- self.intervald = {
- YEARLY: [1, 2, 4, 5, 10, 20, 40, 50, 100, 200, 400, 500,
- 1000, 2000, 4000, 5000, 10000],
- MONTHLY: [1, 2, 3, 4, 6],
- DAILY: [1, 2, 3, 7, 14, 21],
- HOURLY: [1, 2, 3, 4, 6, 12],
- MINUTELY: [1, 5, 10, 15, 30],
- SECONDLY: [1, 5, 10, 15, 30],
- MICROSECONDLY: [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000,
- 5000, 10000, 20000, 50000, 100000, 200000, 500000,
- 1000000]}
- self._byranges = [None, range(1, 13), range(1, 32),
- range(0, 24), range(0, 60), range(0, 60), None]
-
- def __call__(self):
- 'Return the locations of the ticks'
- self.refresh()
- return self._locator()
-
- def tick_values(self, vmin, vmax):
- return self.get_locator(vmin, vmax).tick_values(vmin, vmax)
-
- def nonsingular(self, vmin, vmax):
- # whatever is thrown at us, we can scale the unit.
- # But default nonsingular date plots at an ~4 year period.
- if vmin == vmax:
- vmin = vmin - DAYS_PER_YEAR * 2
- vmax = vmax + DAYS_PER_YEAR * 2
- return vmin, vmax
-
- def set_axis(self, axis):
- DateLocator.set_axis(self, axis)
- self._locator.set_axis(axis)
-
- def refresh(self):
- 'Refresh internal information based on current limits.'
- dmin, dmax = self.viewlim_to_dt()
- self._locator = self.get_locator(dmin, dmax)
-
- def _get_unit(self):
- if self._freq in [MICROSECONDLY]:
- return 1. / MUSECONDS_PER_DAY
- else:
- return RRuleLocator.get_unit_generic(self._freq)
-
- def autoscale(self):
- 'Try to choose the view limits intelligently.'
- dmin, dmax = self.datalim_to_dt()
- self._locator = self.get_locator(dmin, dmax)
- return self._locator.autoscale()
-
- def get_locator(self, dmin, dmax):
- 'Pick the best locator based on a distance.'
- delta = relativedelta(dmax, dmin)
- tdelta = dmax - dmin
-
- # take absolute difference
- if dmin > dmax:
- delta = -delta
- tdelta = -tdelta
-
- # The following uses a mix of calls to relativedelta and timedelta
- # methods because there is incomplete overlap in the functionality of
- # these similar functions, and it's best to avoid doing our own math
- # whenever possible.
- numYears = float(delta.years)
- numMonths = numYears * MONTHS_PER_YEAR + delta.months
- numDays = tdelta.days # Avoids estimates of days/month, days/year
- numHours = numDays * HOURS_PER_DAY + delta.hours
- numMinutes = numHours * MIN_PER_HOUR + delta.minutes
- numSeconds = np.floor(tdelta.total_seconds())
- numMicroseconds = np.floor(tdelta.total_seconds() * 1e6)
-
- nums = [numYears, numMonths, numDays, numHours, numMinutes,
- numSeconds, numMicroseconds]
-
- use_rrule_locator = [True] * 6 + [False]
-
- # Default setting of bymonth, etc. to pass to rrule
- # [unused (for year), bymonth, bymonthday, byhour, byminute,
- # bysecond, unused (for microseconds)]
- byranges = [None, 1, 1, 0, 0, 0, None]
-
- # Loop over all the frequencies and try to find one that gives at
- # least a minticks tick positions. Once this is found, look for
- # an interval from an list specific to that frequency that gives no
- # more than maxticks tick positions. Also, set up some ranges
- # (bymonth, etc.) as appropriate to be passed to rrulewrapper.
- for i, (freq, num) in enumerate(zip(self._freqs, nums)):
- # If this particular frequency doesn't give enough ticks, continue
- if num < self.minticks:
- # Since we're not using this particular frequency, set
- # the corresponding by_ to None so the rrule can act as
- # appropriate
- byranges[i] = None
- continue
-
- # Find the first available interval that doesn't give too many
- # ticks
- for interval in self.intervald[freq]:
- if num <= interval * (self.maxticks[freq] - 1):
- break
- else:
- # We went through the whole loop without breaking, default to
- # the last interval in the list and raise a warning
- warnings.warn('AutoDateLocator was unable to pick an '
- 'appropriate interval for this date range. '
- 'It may be necessary to add an interval value '
- "to the AutoDateLocator's intervald dictionary."
- ' Defaulting to {0}.'.format(interval))
-
- # Set some parameters as appropriate
- self._freq = freq
-
- if self._byranges[i] and self.interval_multiples:
- byranges[i] = self._byranges[i][::interval]
- interval = 1
- else:
- byranges[i] = self._byranges[i]
-
- break
- else:
- raise ValueError('No sensible date limit could be found in the '
- 'AutoDateLocator.')
-
- if (freq == YEARLY) and self.interval_multiples:
- locator = YearLocator(interval)
- elif use_rrule_locator[i]:
- _, bymonth, bymonthday, byhour, byminute, bysecond, _ = byranges
- rrule = rrulewrapper(self._freq, interval=interval,
- dtstart=dmin, until=dmax,
- bymonth=bymonth, bymonthday=bymonthday,
- byhour=byhour, byminute=byminute,
- bysecond=bysecond)
-
- locator = RRuleLocator(rrule, self.tz)
- else:
- locator = MicrosecondLocator(interval, tz=self.tz)
- if dmin.year > 20 and interval < 1000:
- _log.warning('Plotting microsecond time intervals is not well '
- 'supported. Please see the MicrosecondLocator '
- 'documentation for details.')
-
- locator.set_axis(self.axis)
-
- if self.axis is not None:
- locator.set_view_interval(*self.axis.get_view_interval())
- locator.set_data_interval(*self.axis.get_data_interval())
- return locator
-
-
-class YearLocator(DateLocator):
- """
- Make ticks on a given day of each year that is a multiple of base.
-
- Examples::
-
- # Tick every year on Jan 1st
- locator = YearLocator()
-
- # Tick every 5 years on July 4th
- locator = YearLocator(5, month=7, day=4)
- """
- def __init__(self, base=1, month=1, day=1, tz=None):
- """
- Mark years that are multiple of base on a given month and day
- (default jan 1).
- """
- DateLocator.__init__(self, tz)
- self.base = ticker.Base(base)
- self.replaced = {'month': month,
- 'day': day,
- 'hour': 0,
- 'minute': 0,
- 'second': 0,
- 'tzinfo': tz
- }
-
- def __call__(self):
- # if no data have been set, this will tank with a ValueError
- try:
- dmin, dmax = self.viewlim_to_dt()
- except ValueError:
- return []
-
- return self.tick_values(dmin, dmax)
-
- def tick_values(self, vmin, vmax):
- ymin = self.base.le(vmin.year)
- ymax = self.base.ge(vmax.year)
-
- ticks = [vmin.replace(year=ymin, **self.replaced)]
- while True:
- dt = ticks[-1]
- if dt.year >= ymax:
- return date2num(ticks)
- year = dt.year + self.base.get_base()
- ticks.append(dt.replace(year=year, **self.replaced))
-
- def autoscale(self):
- """
- Set the view limits to include the data range.
- """
- dmin, dmax = self.datalim_to_dt()
-
- ymin = self.base.le(dmin.year)
- ymax = self.base.ge(dmax.year)
- vmin = dmin.replace(year=ymin, **self.replaced)
- vmax = dmax.replace(year=ymax, **self.replaced)
-
- vmin = date2num(vmin)
- vmax = date2num(vmax)
- return self.nonsingular(vmin, vmax)
-
-
-class MonthLocator(RRuleLocator):
- """
- Make ticks on occurrences of each month, e.g., 1, 3, 12.
- """
- def __init__(self, bymonth=None, bymonthday=1, interval=1, tz=None):
- """
- Mark every month in *bymonth*; *bymonth* can be an int or
- sequence. Default is ``range(1,13)``, i.e. every month.
-
- *interval* is the interval between each iteration. For
- example, if ``interval=2``, mark every second occurrence.
- """
- if bymonth is None:
- bymonth = range(1, 13)
- elif isinstance(bymonth, np.ndarray):
- # This fixes a bug in dateutil <= 2.3 which prevents the use of
- # numpy arrays in (among other things) the bymonthday, byweekday
- # and bymonth parameters.
- bymonth = [x.item() for x in bymonth.astype(int)]
-
- rule = rrulewrapper(MONTHLY, bymonth=bymonth, bymonthday=bymonthday,
- interval=interval, **self.hms0d)
- RRuleLocator.__init__(self, rule, tz)
-
-
-class WeekdayLocator(RRuleLocator):
- """
- Make ticks on occurrences of each weekday.
- """
-
- def __init__(self, byweekday=1, interval=1, tz=None):
- """
- Mark every weekday in *byweekday*; *byweekday* can be a number or
- sequence.
-
- Elements of *byweekday* must be one of MO, TU, WE, TH, FR, SA,
- SU, the constants from :mod:`dateutil.rrule`, which have been
- imported into the :mod:`matplotlib.dates` namespace.
-
- *interval* specifies the number of weeks to skip. For example,
- ``interval=2`` plots every second week.
- """
- if isinstance(byweekday, np.ndarray):
- # This fixes a bug in dateutil <= 2.3 which prevents the use of
- # numpy arrays in (among other things) the bymonthday, byweekday
- # and bymonth parameters.
- [x.item() for x in byweekday.astype(int)]
-
- rule = rrulewrapper(DAILY, byweekday=byweekday,
- interval=interval, **self.hms0d)
- RRuleLocator.__init__(self, rule, tz)
-
-
-class DayLocator(RRuleLocator):
- """
- Make ticks on occurrences of each day of the month. For example,
- 1, 15, 30.
- """
- def __init__(self, bymonthday=None, interval=1, tz=None):
- """
- Mark every day in *bymonthday*; *bymonthday* can be an int or
- sequence.
-
- Default is to tick every day of the month: ``bymonthday=range(1,32)``
- """
- if not interval == int(interval) or interval < 1:
- raise ValueError("interval must be an integer greater than 0")
- if bymonthday is None:
- bymonthday = range(1, 32)
- elif isinstance(bymonthday, np.ndarray):
- # This fixes a bug in dateutil <= 2.3 which prevents the use of
- # numpy arrays in (among other things) the bymonthday, byweekday
- # and bymonth parameters.
- bymonthday = [x.item() for x in bymonthday.astype(int)]
-
- rule = rrulewrapper(DAILY, bymonthday=bymonthday,
- interval=interval, **self.hms0d)
- RRuleLocator.__init__(self, rule, tz)
-
-
-class HourLocator(RRuleLocator):
- """
- Make ticks on occurrences of each hour.
- """
- def __init__(self, byhour=None, interval=1, tz=None):
- """
- Mark every hour in *byhour*; *byhour* can be an int or sequence.
- Default is to tick every hour: ``byhour=range(24)``
-
- *interval* is the interval between each iteration. For
- example, if ``interval=2``, mark every second occurrence.
- """
- if byhour is None:
- byhour = range(24)
-
- rule = rrulewrapper(HOURLY, byhour=byhour, interval=interval,
- byminute=0, bysecond=0)
- RRuleLocator.__init__(self, rule, tz)
-
-
-class MinuteLocator(RRuleLocator):
- """
- Make ticks on occurrences of each minute.
- """
- def __init__(self, byminute=None, interval=1, tz=None):
- """
- Mark every minute in *byminute*; *byminute* can be an int or
- sequence. Default is to tick every minute: ``byminute=range(60)``
-
- *interval* is the interval between each iteration. For
- example, if ``interval=2``, mark every second occurrence.
- """
- if byminute is None:
- byminute = range(60)
-
- rule = rrulewrapper(MINUTELY, byminute=byminute, interval=interval,
- bysecond=0)
- RRuleLocator.__init__(self, rule, tz)
-
-
-class SecondLocator(RRuleLocator):
- """
- Make ticks on occurrences of each second.
- """
- def __init__(self, bysecond=None, interval=1, tz=None):
- """
- Mark every second in *bysecond*; *bysecond* can be an int or
- sequence. Default is to tick every second: ``bysecond = range(60)``
-
- *interval* is the interval between each iteration. For
- example, if ``interval=2``, mark every second occurrence.
-
- """
- if bysecond is None:
- bysecond = range(60)
-
- rule = rrulewrapper(SECONDLY, bysecond=bysecond, interval=interval)
- RRuleLocator.__init__(self, rule, tz)
-
-
-class MicrosecondLocator(DateLocator):
- """
- Make ticks on regular intervals of one or more microsecond(s).
-
- .. note::
-
- Due to the floating point representation of time in days since
- 0001-01-01 UTC (plus 1), plotting data with microsecond time
- resolution does not work well with current dates.
-
- If you want microsecond resolution time plots, it is strongly
- recommended to use floating point seconds, not datetime-like
- time representation.
-
- If you really must use datetime.datetime() or similar and still
- need microsecond precision, your only chance is to use very
- early years; using year 0001 is recommended.
-
- """
- def __init__(self, interval=1, tz=None):
- """
- *interval* is the interval between each iteration. For
- example, if ``interval=2``, mark every second microsecond.
-
- """
- self._interval = interval
- self._wrapped_locator = ticker.MultipleLocator(interval)
- self.tz = tz
-
- def set_axis(self, axis):
- self._wrapped_locator.set_axis(axis)
- return DateLocator.set_axis(self, axis)
-
- def set_view_interval(self, vmin, vmax):
- self._wrapped_locator.set_view_interval(vmin, vmax)
- return DateLocator.set_view_interval(self, vmin, vmax)
-
- def set_data_interval(self, vmin, vmax):
- self._wrapped_locator.set_data_interval(vmin, vmax)
- return DateLocator.set_data_interval(self, vmin, vmax)
-
- def __call__(self):
- # if no data have been set, this will tank with a ValueError
- try:
- dmin, dmax = self.viewlim_to_dt()
- except ValueError:
- return []
-
- return self.tick_values(dmin, dmax)
-
- def tick_values(self, vmin, vmax):
- nmin, nmax = date2num((vmin, vmax))
- nmin *= MUSECONDS_PER_DAY
- nmax *= MUSECONDS_PER_DAY
- ticks = self._wrapped_locator.tick_values(nmin, nmax)
- ticks = [tick / MUSECONDS_PER_DAY for tick in ticks]
- return ticks
-
- def _get_unit(self):
- """
- Return how many days a unit of the locator is; used for
- intelligent autoscaling.
- """
- return 1. / MUSECONDS_PER_DAY
-
- def _get_interval(self):
- """
- Return the number of units for each tick.
- """
- return self._interval
-
-
-def _close_to_dt(d1, d2, epsilon=5):
- """
- Assert that datetimes *d1* and *d2* are within *epsilon* microseconds.
- """
- delta = d2 - d1
- mus = abs(delta.total_seconds() * 1e6)
- assert mus < epsilon
-
-
-def _close_to_num(o1, o2, epsilon=5):
- """
- Assert that float ordinals *o1* and *o2* are within *epsilon*
- microseconds.
- """
- delta = abs((o2 - o1) * MUSECONDS_PER_DAY)
- assert delta < epsilon
-
-
-def epoch2num(e):
- """
- Convert an epoch or sequence of epochs to the new date format,
- that is days since 0001.
- """
- return EPOCH_OFFSET + np.asarray(e) / SEC_PER_DAY
-
-
-def num2epoch(d):
- """
- Convert days since 0001 to epoch. *d* can be a number or sequence.
- """
- return (np.asarray(d) - EPOCH_OFFSET) * SEC_PER_DAY
-
-
-def mx2num(mxdates):
- """
- Convert mx :class:`datetime` instance (or sequence of mx
- instances) to the new date format.
- """
- scalar = False
- if not cbook.iterable(mxdates):
- scalar = True
- mxdates = [mxdates]
- ret = epoch2num([m.ticks() for m in mxdates])
- if scalar:
- return ret[0]
- else:
- return ret
-
-
-def date_ticker_factory(span, tz=None, numticks=5):
- """
- Create a date locator with *numticks* (approx) and a date formatter
- for *span* in days. Return value is (locator, formatter).
- """
-
- if span == 0:
- span = 1 / HOURS_PER_DAY
-
- mins = span * MINUTES_PER_DAY
- hrs = span * HOURS_PER_DAY
- days = span
- wks = span / DAYS_PER_WEEK
- months = span / DAYS_PER_MONTH # Approx
- years = span / DAYS_PER_YEAR # Approx
-
- if years > numticks:
- locator = YearLocator(int(years / numticks), tz=tz) # define
- fmt = '%Y'
- elif months > numticks:
- locator = MonthLocator(tz=tz)
- fmt = '%b %Y'
- elif wks > numticks:
- locator = WeekdayLocator(tz=tz)
- fmt = '%a, %b %d'
- elif days > numticks:
- locator = DayLocator(interval=int(math.ceil(days / numticks)), tz=tz)
- fmt = '%b %d'
- elif hrs > numticks:
- locator = HourLocator(interval=int(math.ceil(hrs / numticks)), tz=tz)
- fmt = '%H:%M\n%b %d'
- elif mins > numticks:
- locator = MinuteLocator(interval=int(math.ceil(mins / numticks)),
- tz=tz)
- fmt = '%H:%M:%S'
- else:
- locator = MinuteLocator(tz=tz)
- fmt = '%H:%M:%S'
-
- formatter = DateFormatter(fmt, tz=tz)
- return locator, formatter
-
-
-def seconds(s):
- """
- Return seconds as days.
- """
- return s / SEC_PER_DAY
-
-
-def minutes(m):
- """
- Return minutes as days.
- """
- return m / MINUTES_PER_DAY
-
-
-def hours(h):
- """
- Return hours as days.
- """
- return h / HOURS_PER_DAY
-
-
-def weeks(w):
- """
- Return weeks as days.
- """
- return w * DAYS_PER_WEEK
-
-
-class DateConverter(units.ConversionInterface):
- """
- Converter for datetime.date and datetime.datetime data,
- or for date/time data represented as it would be converted
- by :func:`date2num`.
-
- The 'unit' tag for such data is None or a tzinfo instance.
- """
-
- @staticmethod
- def axisinfo(unit, axis):
- """
- Return the :class:`~matplotlib.units.AxisInfo` for *unit*.
-
- *unit* is a tzinfo instance or None.
- The *axis* argument is required but not used.
- """
- tz = unit
-
- majloc = AutoDateLocator(tz=tz)
- majfmt = AutoDateFormatter(majloc, tz=tz)
- datemin = datetime.date(2000, 1, 1)
- datemax = datetime.date(2010, 1, 1)
-
- return units.AxisInfo(majloc=majloc, majfmt=majfmt, label='',
- default_limits=(datemin, datemax))
-
- @staticmethod
- def convert(value, unit, axis):
- """
- If *value* is not already a number or sequence of numbers,
- convert it with :func:`date2num`.
-
- The *unit* and *axis* arguments are not used.
- """
- return date2num(value)
-
- @staticmethod
- def default_units(x, axis):
- """
- Return the tzinfo instance of *x* or of its first element, or None
- """
- if isinstance(x, np.ndarray):
- x = x.ravel()
-
- try:
- x = cbook.safe_first_element(x)
- except (TypeError, StopIteration):
- pass
-
- try:
- return x.tzinfo
- except AttributeError:
- pass
- return None
-
-
-units.registry[np.datetime64] = DateConverter()
-units.registry[datetime.date] = DateConverter()
-units.registry[datetime.datetime] = DateConverter()
diff --git a/contrib/python/matplotlib/py2/matplotlib/docstring.py b/contrib/python/matplotlib/py2/matplotlib/docstring.py
deleted file mode 100644
index cf9537f0c6..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/docstring.py
+++ /dev/null
@@ -1,128 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from matplotlib import cbook
-import sys
-import types
-
-
-class Substitution(object):
- """
- A decorator to take a function's docstring and perform string
- substitution on it.
-
- This decorator should be robust even if func.__doc__ is None
- (for example, if -OO was passed to the interpreter)
-
- Usage: construct a docstring.Substitution with a sequence or
- dictionary suitable for performing substitution; then
- decorate a suitable function with the constructed object. e.g.
-
- sub_author_name = Substitution(author='Jason')
-
- @sub_author_name
- def some_function(x):
- "%(author)s wrote this function"
-
- # note that some_function.__doc__ is now "Jason wrote this function"
-
- One can also use positional arguments.
-
- sub_first_last_names = Substitution('Edgar Allen', 'Poe')
-
- @sub_first_last_names
- def some_function(x):
- "%s %s wrote the Raven"
- """
- def __init__(self, *args, **kwargs):
- assert not (len(args) and len(kwargs)), \
- "Only positional or keyword args are allowed"
- self.params = args or kwargs
-
- def __call__(self, func):
- func.__doc__ = func.__doc__ and func.__doc__ % self.params
- return func
-
- def update(self, *args, **kwargs):
- "Assume self.params is a dict and update it with supplied args"
- self.params.update(*args, **kwargs)
-
- @classmethod
- def from_params(cls, params):
- """
- In the case where the params is a mutable sequence (list or
- dictionary) and it may change before this class is called, one may
- explicitly use a reference to the params rather than using *args or
- **kwargs which will copy the values and not reference them.
- """
- result = cls()
- result.params = params
- return result
-
-
-class Appender(object):
- """
- A function decorator that will append an addendum to the docstring
- of the target function.
-
- This decorator should be robust even if func.__doc__ is None
- (for example, if -OO was passed to the interpreter).
-
- Usage: construct a docstring.Appender with a string to be joined to
- the original docstring. An optional 'join' parameter may be supplied
- which will be used to join the docstring and addendum. e.g.
-
- add_copyright = Appender("Copyright (c) 2009", join='\n')
-
- @add_copyright
- def my_dog(has='fleas'):
- "This docstring will have a copyright below"
- pass
- """
- def __init__(self, addendum, join=''):
- self.addendum = addendum
- self.join = join
-
- def __call__(self, func):
- docitems = [func.__doc__, self.addendum]
- func.__doc__ = func.__doc__ and self.join.join(docitems)
- return func
-
-
-def dedent(func):
- "Dedent a docstring (if present)"
- func.__doc__ = func.__doc__ and cbook.dedent(func.__doc__)
- return func
-
-
-def copy(source):
- "Copy a docstring from another source function (if present)"
- def do_copy(target):
- if source.__doc__:
- target.__doc__ = source.__doc__
- return target
- return do_copy
-
-# create a decorator that will house the various documentation that
-# is reused throughout matplotlib
-interpd = Substitution()
-
-
-def dedent_interpd(func):
- """A special case of the interpd that first performs a dedent on
- the incoming docstring"""
- if isinstance(func, types.MethodType) and not six.PY3:
- func = func.im_func
- return interpd(dedent(func))
-
-
-def copy_dedent(source):
- """A decorator that will copy the docstring from the source and
- then dedent it"""
- # note the following is ugly because "Python is not a functional
- # language" - GVR. Perhaps one day, functools.compose will exist.
- # or perhaps not.
- # http://mail.python.org/pipermail/patches/2007-February/021687.html
- return lambda target: dedent(copy(source)(target))
diff --git a/contrib/python/matplotlib/py2/matplotlib/dviread.py b/contrib/python/matplotlib/py2/matplotlib/dviread.py
deleted file mode 100644
index b38af56e67..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/dviread.py
+++ /dev/null
@@ -1,1083 +0,0 @@
-"""
-A module for reading dvi files output by TeX. Several limitations make
-this not (currently) useful as a general-purpose dvi preprocessor, but
-it is currently used by the pdf backend for processing usetex text.
-
-Interface::
-
- with Dvi(filename, 72) as dvi:
- # iterate over pages:
- for page in dvi:
- w, h, d = page.width, page.height, page.descent
- for x,y,font,glyph,width in page.text:
- fontname = font.texname
- pointsize = font.size
- ...
- for x,y,height,width in page.boxes:
- ...
-
-"""
-from __future__ import absolute_import, division, print_function
-
-import six
-from six.moves import xrange
-
-from collections import namedtuple
-from functools import partial, wraps
-import logging
-import numpy as np
-import os
-import re
-import struct
-import sys
-import textwrap
-
-from matplotlib import cbook, rcParams
-from matplotlib.compat import subprocess
-
-try:
- from functools import lru_cache
-except ImportError: # Py2
- from backports.functools_lru_cache import lru_cache
-
-if six.PY3:
- def ord(x):
- return x
-
-_log = logging.getLogger(__name__)
-
-# Dvi is a bytecode format documented in
-# http://mirrors.ctan.org/systems/knuth/dist/texware/dvitype.web
-# http://texdoc.net/texmf-dist/doc/generic/knuth/texware/dvitype.pdf
-#
-# The file consists of a preamble, some number of pages, a postamble,
-# and a finale. Different opcodes are allowed in different contexts,
-# so the Dvi object has a parser state:
-#
-# pre: expecting the preamble
-# outer: between pages (followed by a page or the postamble,
-# also e.g. font definitions are allowed)
-# page: processing a page
-# post_post: state after the postamble (our current implementation
-# just stops reading)
-# finale: the finale (unimplemented in our current implementation)
-
-_dvistate = cbook.Bunch(pre=0, outer=1, inpage=2, post_post=3, finale=4)
-
-# The marks on a page consist of text and boxes. A page also has dimensions.
-Page = namedtuple('Page', 'text boxes height width descent')
-Text = namedtuple('Text', 'x y font glyph width')
-Box = namedtuple('Box', 'x y height width')
-
-
-# Opcode argument parsing
-#
-# Each of the following functions takes a Dvi object and delta,
-# which is the difference between the opcode and the minimum opcode
-# with the same meaning. Dvi opcodes often encode the number of
-# argument bytes in this delta.
-
-def _arg_raw(dvi, delta):
- """Return *delta* without reading anything more from the dvi file"""
- return delta
-
-
-def _arg(bytes, signed, dvi, _):
- """Read *bytes* bytes, returning the bytes interpreted as a
- signed integer if *signed* is true, unsigned otherwise."""
- return dvi._arg(bytes, signed)
-
-
-def _arg_slen(dvi, delta):
- """Signed, length *delta*
-
- Read *delta* bytes, returning None if *delta* is zero, and
- the bytes interpreted as a signed integer otherwise."""
- if delta == 0:
- return None
- return dvi._arg(delta, True)
-
-
-def _arg_slen1(dvi, delta):
- """Signed, length *delta*+1
-
- Read *delta*+1 bytes, returning the bytes interpreted as signed."""
- return dvi._arg(delta+1, True)
-
-
-def _arg_ulen1(dvi, delta):
- """Unsigned length *delta*+1
-
- Read *delta*+1 bytes, returning the bytes interpreted as unsigned."""
- return dvi._arg(delta+1, False)
-
-
-def _arg_olen1(dvi, delta):
- """Optionally signed, length *delta*+1
-
- Read *delta*+1 bytes, returning the bytes interpreted as
- unsigned integer for 0<=*delta*<3 and signed if *delta*==3."""
- return dvi._arg(delta + 1, delta == 3)
-
-
-_arg_mapping = dict(raw=_arg_raw,
- u1=partial(_arg, 1, False),
- u4=partial(_arg, 4, False),
- s4=partial(_arg, 4, True),
- slen=_arg_slen,
- olen1=_arg_olen1,
- slen1=_arg_slen1,
- ulen1=_arg_ulen1)
-
-
-def _dispatch(table, min, max=None, state=None, args=('raw',)):
- """Decorator for dispatch by opcode. Sets the values in *table*
- from *min* to *max* to this method, adds a check that the Dvi state
- matches *state* if not None, reads arguments from the file according
- to *args*.
-
- *table*
- the dispatch table to be filled in
-
- *min*
- minimum opcode for calling this function
-
- *max*
- maximum opcode for calling this function, None if only *min* is allowed
-
- *state*
- state of the Dvi object in which these opcodes are allowed
-
- *args*
- sequence of argument specifications:
-
- ``'raw'``: opcode minus minimum
- ``'u1'``: read one unsigned byte
- ``'u4'``: read four bytes, treat as an unsigned number
- ``'s4'``: read four bytes, treat as a signed number
- ``'slen'``: read (opcode - minimum) bytes, treat as signed
- ``'slen1'``: read (opcode - minimum + 1) bytes, treat as signed
- ``'ulen1'``: read (opcode - minimum + 1) bytes, treat as unsigned
- ``'olen1'``: read (opcode - minimum + 1) bytes, treat as unsigned
- if under four bytes, signed if four bytes
- """
- def decorate(method):
- get_args = [_arg_mapping[x] for x in args]
-
- @wraps(method)
- def wrapper(self, byte):
- if state is not None and self.state != state:
- raise ValueError("state precondition failed")
- return method(self, *[f(self, byte-min) for f in get_args])
- if max is None:
- table[min] = wrapper
- else:
- for i in xrange(min, max+1):
- assert table[i] is None
- table[i] = wrapper
- return wrapper
- return decorate
-
-
-class Dvi(object):
- """
- A reader for a dvi ("device-independent") file, as produced by TeX.
- The current implementation can only iterate through pages in order,
- and does not even attempt to verify the postamble.
-
- This class can be used as a context manager to close the underlying
- file upon exit. Pages can be read via iteration. Here is an overly
- simple way to extract text without trying to detect whitespace::
-
- >>> with matplotlib.dviread.Dvi('input.dvi', 72) as dvi:
- >>> for page in dvi:
- >>> print(''.join(unichr(t.glyph) for t in page.text))
- """
- # dispatch table
- _dtable = [None for _ in xrange(256)]
- _dispatch = partial(_dispatch, _dtable)
-
- def __init__(self, filename, dpi):
- """
- Read the data from the file named *filename* and convert
- TeX's internal units to units of *dpi* per inch.
- *dpi* only sets the units and does not limit the resolution.
- Use None to return TeX's internal units.
- """
- _log.debug('Dvi: %s', filename)
- self.file = open(filename, 'rb')
- self.dpi = dpi
- self.fonts = {}
- self.state = _dvistate.pre
- self.baseline = self._get_baseline(filename)
-
- def _get_baseline(self, filename):
- if rcParams['text.latex.preview']:
- base, ext = os.path.splitext(filename)
- baseline_filename = base + ".baseline"
- if os.path.exists(baseline_filename):
- with open(baseline_filename, 'rb') as fd:
- l = fd.read().split()
- height, depth, width = l
- return float(depth)
- return None
-
- def __enter__(self):
- """
- Context manager enter method, does nothing.
- """
- return self
-
- def __exit__(self, etype, evalue, etrace):
- """
- Context manager exit method, closes the underlying file if it is open.
- """
- self.close()
-
- def __iter__(self):
- """
- Iterate through the pages of the file.
-
- Yields
- ------
- Page
- Details of all the text and box objects on the page.
- The Page tuple contains lists of Text and Box tuples and
- the page dimensions, and the Text and Box tuples contain
- coordinates transformed into a standard Cartesian
- coordinate system at the dpi value given when initializing.
- The coordinates are floating point numbers, but otherwise
- precision is not lost and coordinate values are not clipped to
- integers.
- """
- while True:
- have_page = self._read()
- if have_page:
- yield self._output()
- else:
- break
-
- def close(self):
- """
- Close the underlying file if it is open.
- """
- if not self.file.closed:
- self.file.close()
-
- def _output(self):
- """
- Output the text and boxes belonging to the most recent page.
- page = dvi._output()
- """
- minx, miny, maxx, maxy = np.inf, np.inf, -np.inf, -np.inf
- maxy_pure = -np.inf
- for elt in self.text + self.boxes:
- if isinstance(elt, Box):
- x, y, h, w = elt
- e = 0 # zero depth
- else: # glyph
- x, y, font, g, w = elt
- h, e = font._height_depth_of(g)
- minx = min(minx, x)
- miny = min(miny, y - h)
- maxx = max(maxx, x + w)
- maxy = max(maxy, y + e)
- maxy_pure = max(maxy_pure, y)
-
- if self.dpi is None:
- # special case for ease of debugging: output raw dvi coordinates
- return Page(text=self.text, boxes=self.boxes,
- width=maxx-minx, height=maxy_pure-miny,
- descent=maxy-maxy_pure)
-
- # convert from TeX's "scaled points" to dpi units
- d = self.dpi / (72.27 * 2**16)
- if self.baseline is None:
- descent = (maxy - maxy_pure) * d
- else:
- descent = self.baseline
-
- text = [Text((x-minx)*d, (maxy-y)*d - descent, f, g, w*d)
- for (x, y, f, g, w) in self.text]
- boxes = [Box((x-minx)*d, (maxy-y)*d - descent, h*d, w*d)
- for (x, y, h, w) in self.boxes]
-
- return Page(text=text, boxes=boxes, width=(maxx-minx)*d,
- height=(maxy_pure-miny)*d, descent=descent)
-
- def _read(self):
- """
- Read one page from the file. Return True if successful,
- False if there were no more pages.
- """
- while True:
- byte = ord(self.file.read(1)[0])
- self._dtable[byte](self, byte)
- if byte == 140: # end of page
- return True
- if self.state == _dvistate.post_post: # end of file
- self.close()
- return False
-
- def _arg(self, nbytes, signed=False):
- """
- Read and return an integer argument *nbytes* long.
- Signedness is determined by the *signed* keyword.
- """
- str = self.file.read(nbytes)
- value = ord(str[0])
- if signed and value >= 0x80:
- value = value - 0x100
- for i in range(1, nbytes):
- value = 0x100*value + ord(str[i])
- return value
-
- @_dispatch(min=0, max=127, state=_dvistate.inpage)
- def _set_char_immediate(self, char):
- self._put_char_real(char)
- self.h += self.fonts[self.f]._width_of(char)
-
- @_dispatch(min=128, max=131, state=_dvistate.inpage, args=('olen1',))
- def _set_char(self, char):
- self._put_char_real(char)
- self.h += self.fonts[self.f]._width_of(char)
-
- @_dispatch(132, state=_dvistate.inpage, args=('s4', 's4'))
- def _set_rule(self, a, b):
- self._put_rule_real(a, b)
- self.h += b
-
- @_dispatch(min=133, max=136, state=_dvistate.inpage, args=('olen1',))
- def _put_char(self, char):
- self._put_char_real(char)
-
- def _put_char_real(self, char):
- font = self.fonts[self.f]
- if font._vf is None:
- self.text.append(Text(self.h, self.v, font, char,
- font._width_of(char)))
- else:
- scale = font._scale
- for x, y, f, g, w in font._vf[char].text:
- newf = DviFont(scale=_mul2012(scale, f._scale),
- tfm=f._tfm, texname=f.texname, vf=f._vf)
- self.text.append(Text(self.h + _mul2012(x, scale),
- self.v + _mul2012(y, scale),
- newf, g, newf._width_of(g)))
- self.boxes.extend([Box(self.h + _mul2012(x, scale),
- self.v + _mul2012(y, scale),
- _mul2012(a, scale), _mul2012(b, scale))
- for x, y, a, b in font._vf[char].boxes])
-
- @_dispatch(137, state=_dvistate.inpage, args=('s4', 's4'))
- def _put_rule(self, a, b):
- self._put_rule_real(a, b)
-
- def _put_rule_real(self, a, b):
- if a > 0 and b > 0:
- self.boxes.append(Box(self.h, self.v, a, b))
-
- @_dispatch(138)
- def _nop(self, _):
- pass
-
- @_dispatch(139, state=_dvistate.outer, args=('s4',)*11)
- def _bop(self, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, p):
- self.state = _dvistate.inpage
- self.h, self.v, self.w, self.x, self.y, self.z = 0, 0, 0, 0, 0, 0
- self.stack = []
- self.text = [] # list of Text objects
- self.boxes = [] # list of Box objects
-
- @_dispatch(140, state=_dvistate.inpage)
- def _eop(self, _):
- self.state = _dvistate.outer
- del self.h, self.v, self.w, self.x, self.y, self.z, self.stack
-
- @_dispatch(141, state=_dvistate.inpage)
- def _push(self, _):
- self.stack.append((self.h, self.v, self.w, self.x, self.y, self.z))
-
- @_dispatch(142, state=_dvistate.inpage)
- def _pop(self, _):
- self.h, self.v, self.w, self.x, self.y, self.z = self.stack.pop()
-
- @_dispatch(min=143, max=146, state=_dvistate.inpage, args=('slen1',))
- def _right(self, b):
- self.h += b
-
- @_dispatch(min=147, max=151, state=_dvistate.inpage, args=('slen',))
- def _right_w(self, new_w):
- if new_w is not None:
- self.w = new_w
- self.h += self.w
-
- @_dispatch(min=152, max=156, state=_dvistate.inpage, args=('slen',))
- def _right_x(self, new_x):
- if new_x is not None:
- self.x = new_x
- self.h += self.x
-
- @_dispatch(min=157, max=160, state=_dvistate.inpage, args=('slen1',))
- def _down(self, a):
- self.v += a
-
- @_dispatch(min=161, max=165, state=_dvistate.inpage, args=('slen',))
- def _down_y(self, new_y):
- if new_y is not None:
- self.y = new_y
- self.v += self.y
-
- @_dispatch(min=166, max=170, state=_dvistate.inpage, args=('slen',))
- def _down_z(self, new_z):
- if new_z is not None:
- self.z = new_z
- self.v += self.z
-
- @_dispatch(min=171, max=234, state=_dvistate.inpage)
- def _fnt_num_immediate(self, k):
- self.f = k
-
- @_dispatch(min=235, max=238, state=_dvistate.inpage, args=('olen1',))
- def _fnt_num(self, new_f):
- self.f = new_f
-
- @_dispatch(min=239, max=242, args=('ulen1',))
- def _xxx(self, datalen):
- special = self.file.read(datalen)
- if six.PY3:
- chr_ = chr
- else:
- def chr_(x):
- return x
- _log.debug(
- 'Dvi._xxx: encountered special: %s',
- ''.join([chr_(ch) if 32 <= ord(ch) < 127 else '<%02x>' % ord(ch)
- for ch in special]))
-
- @_dispatch(min=243, max=246, args=('olen1', 'u4', 'u4', 'u4', 'u1', 'u1'))
- def _fnt_def(self, k, c, s, d, a, l):
- self._fnt_def_real(k, c, s, d, a, l)
-
- def _fnt_def_real(self, k, c, s, d, a, l):
- n = self.file.read(a + l)
- fontname = n[-l:].decode('ascii')
- tfm = _tfmfile(fontname)
- if tfm is None:
- if six.PY2:
- error_class = OSError
- else:
- error_class = FileNotFoundError
- raise error_class("missing font metrics file: %s" % fontname)
- if c != 0 and tfm.checksum != 0 and c != tfm.checksum:
- raise ValueError('tfm checksum mismatch: %s' % n)
-
- vf = _vffile(fontname)
-
- self.fonts[k] = DviFont(scale=s, tfm=tfm, texname=n, vf=vf)
-
- @_dispatch(247, state=_dvistate.pre, args=('u1', 'u4', 'u4', 'u4', 'u1'))
- def _pre(self, i, num, den, mag, k):
- comment = self.file.read(k)
- if i != 2:
- raise ValueError("Unknown dvi format %d" % i)
- if num != 25400000 or den != 7227 * 2**16:
- raise ValueError("nonstandard units in dvi file")
- # meaning: TeX always uses those exact values, so it
- # should be enough for us to support those
- # (There are 72.27 pt to an inch so 7227 pt =
- # 7227 * 2**16 sp to 100 in. The numerator is multiplied
- # by 10^5 to get units of 10**-7 meters.)
- if mag != 1000:
- raise ValueError("nonstandard magnification in dvi file")
- # meaning: LaTeX seems to frown on setting \mag, so
- # I think we can assume this is constant
- self.state = _dvistate.outer
-
- @_dispatch(248, state=_dvistate.outer)
- def _post(self, _):
- self.state = _dvistate.post_post
- # TODO: actually read the postamble and finale?
- # currently post_post just triggers closing the file
-
- @_dispatch(249)
- def _post_post(self, _):
- raise NotImplementedError
-
- @_dispatch(min=250, max=255)
- def _malformed(self, offset):
- raise ValueError("unknown command: byte %d", 250 + offset)
-
-
-class DviFont(object):
- """
- Encapsulation of a font that a DVI file can refer to.
-
- This class holds a font's texname and size, supports comparison,
- and knows the widths of glyphs in the same units as the AFM file.
- There are also internal attributes (for use by dviread.py) that
- are *not* used for comparison.
-
- The size is in Adobe points (converted from TeX points).
-
- Parameters
- ----------
-
- scale : float
- Factor by which the font is scaled from its natural size.
- tfm : Tfm
- TeX font metrics for this font
- texname : bytes
- Name of the font as used internally by TeX and friends, as an
- ASCII bytestring. This is usually very different from any external
- font names, and :class:`dviread.PsfontsMap` can be used to find
- the external name of the font.
- vf : Vf
- A TeX "virtual font" file, or None if this font is not virtual.
-
- Attributes
- ----------
-
- texname : bytes
- size : float
- Size of the font in Adobe points, converted from the slightly
- smaller TeX points.
- widths : list
- Widths of glyphs in glyph-space units, typically 1/1000ths of
- the point size.
-
- """
- __slots__ = ('texname', 'size', 'widths', '_scale', '_vf', '_tfm')
-
- def __init__(self, scale, tfm, texname, vf):
- if not isinstance(texname, bytes):
- raise ValueError("texname must be a bytestring, got %s"
- % type(texname))
- self._scale, self._tfm, self.texname, self._vf = \
- scale, tfm, texname, vf
- self.size = scale * (72.0 / (72.27 * 2**16))
- try:
- nchars = max(tfm.width) + 1
- except ValueError:
- nchars = 0
- self.widths = [(1000*tfm.width.get(char, 0)) >> 20
- for char in xrange(nchars)]
-
- def __eq__(self, other):
- return self.__class__ == other.__class__ and \
- self.texname == other.texname and self.size == other.size
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def _width_of(self, char):
- """
- Width of char in dvi units. For internal use by dviread.py.
- """
-
- width = self._tfm.width.get(char, None)
- if width is not None:
- return _mul2012(width, self._scale)
- _log.debug('No width for char %d in font %s.', char, self.texname)
- return 0
-
- def _height_depth_of(self, char):
- """
- Height and depth of char in dvi units. For internal use by dviread.py.
- """
-
- result = []
- for metric, name in ((self._tfm.height, "height"),
- (self._tfm.depth, "depth")):
- value = metric.get(char, None)
- if value is None:
- _log.debug('No %s for char %d in font %s',
- name, char, self.texname)
- result.append(0)
- else:
- result.append(_mul2012(value, self._scale))
- return result
-
-
-class Vf(Dvi):
- """
- A virtual font (\\*.vf file) containing subroutines for dvi files.
-
- Usage::
-
- vf = Vf(filename)
- glyph = vf[code]
- glyph.text, glyph.boxes, glyph.width
-
- Parameters
- ----------
-
- filename : string or bytestring
-
- Notes
- -----
-
- The virtual font format is a derivative of dvi:
- http://mirrors.ctan.org/info/knuth/virtual-fonts
- This class reuses some of the machinery of `Dvi`
- but replaces the `_read` loop and dispatch mechanism.
- """
-
- def __init__(self, filename):
- Dvi.__init__(self, filename, 0)
- try:
- self._first_font = None
- self._chars = {}
- self._read()
- finally:
- self.close()
-
- def __getitem__(self, code):
- return self._chars[code]
-
- def _read(self):
- """
- Read one page from the file. Return True if successful,
- False if there were no more pages.
- """
- packet_char, packet_ends = None, None
- packet_len, packet_width = None, None
- while True:
- byte = ord(self.file.read(1)[0])
- # If we are in a packet, execute the dvi instructions
- if self.state == _dvistate.inpage:
- byte_at = self.file.tell()-1
- if byte_at == packet_ends:
- self._finalize_packet(packet_char, packet_width)
- packet_len, packet_char, packet_width = None, None, None
- # fall through to out-of-packet code
- elif byte_at > packet_ends:
- raise ValueError("Packet length mismatch in vf file")
- else:
- if byte in (139, 140) or byte >= 243:
- raise ValueError(
- "Inappropriate opcode %d in vf file" % byte)
- Dvi._dtable[byte](self, byte)
- continue
-
- # We are outside a packet
- if byte < 242: # a short packet (length given by byte)
- packet_len = byte
- packet_char, packet_width = self._arg(1), self._arg(3)
- packet_ends = self._init_packet(byte)
- self.state = _dvistate.inpage
- elif byte == 242: # a long packet
- packet_len, packet_char, packet_width = \
- [self._arg(x) for x in (4, 4, 4)]
- self._init_packet(packet_len)
- elif 243 <= byte <= 246:
- k = self._arg(byte - 242, byte == 246)
- c, s, d, a, l = [self._arg(x) for x in (4, 4, 4, 1, 1)]
- self._fnt_def_real(k, c, s, d, a, l)
- if self._first_font is None:
- self._first_font = k
- elif byte == 247: # preamble
- i, k = self._arg(1), self._arg(1)
- x = self.file.read(k)
- cs, ds = self._arg(4), self._arg(4)
- self._pre(i, x, cs, ds)
- elif byte == 248: # postamble (just some number of 248s)
- break
- else:
- raise ValueError("unknown vf opcode %d" % byte)
-
- def _init_packet(self, pl):
- if self.state != _dvistate.outer:
- raise ValueError("Misplaced packet in vf file")
- self.h, self.v, self.w, self.x, self.y, self.z = 0, 0, 0, 0, 0, 0
- self.stack, self.text, self.boxes = [], [], []
- self.f = self._first_font
- return self.file.tell() + pl
-
- def _finalize_packet(self, packet_char, packet_width):
- self._chars[packet_char] = Page(
- text=self.text, boxes=self.boxes, width=packet_width,
- height=None, descent=None)
- self.state = _dvistate.outer
-
- def _pre(self, i, x, cs, ds):
- if self.state != _dvistate.pre:
- raise ValueError("pre command in middle of vf file")
- if i != 202:
- raise ValueError("Unknown vf format %d" % i)
- if len(x):
- _log.debug('vf file comment: %s', x)
- self.state = _dvistate.outer
- # cs = checksum, ds = design size
-
-
-def _fix2comp(num):
- """
- Convert from two's complement to negative.
- """
- assert 0 <= num < 2**32
- if num & 2**31:
- return num - 2**32
- else:
- return num
-
-
-def _mul2012(num1, num2):
- """
- Multiply two numbers in 20.12 fixed point format.
- """
- # Separated into a function because >> has surprising precedence
- return (num1*num2) >> 20
-
-
-class Tfm(object):
- """
- A TeX Font Metric file.
-
- This implementation covers only the bare minimum needed by the Dvi class.
-
- Parameters
- ----------
- filename : string or bytestring
-
- Attributes
- ----------
- checksum : int
- Used for verifying against the dvi file.
- design_size : int
- Design size of the font (unknown units)
- width, height, depth : dict
- Dimensions of each character, need to be scaled by the factor
- specified in the dvi file. These are dicts because indexing may
- not start from 0.
- """
- __slots__ = ('checksum', 'design_size', 'width', 'height', 'depth')
-
- def __init__(self, filename):
- _log.debug('opening tfm file %s', filename)
- with open(filename, 'rb') as file:
- header1 = file.read(24)
- lh, bc, ec, nw, nh, nd = \
- struct.unpack('!6H', header1[2:14])
- _log.debug('lh=%d, bc=%d, ec=%d, nw=%d, nh=%d, nd=%d',
- lh, bc, ec, nw, nh, nd)
- header2 = file.read(4*lh)
- self.checksum, self.design_size = \
- struct.unpack('!2I', header2[:8])
- # there is also encoding information etc.
- char_info = file.read(4*(ec-bc+1))
- widths = file.read(4*nw)
- heights = file.read(4*nh)
- depths = file.read(4*nd)
-
- self.width, self.height, self.depth = {}, {}, {}
- widths, heights, depths = \
- [struct.unpack('!%dI' % (len(x)/4), x)
- for x in (widths, heights, depths)]
- for idx, char in enumerate(xrange(bc, ec+1)):
- byte0 = ord(char_info[4*idx])
- byte1 = ord(char_info[4*idx+1])
- self.width[char] = _fix2comp(widths[byte0])
- self.height[char] = _fix2comp(heights[byte1 >> 4])
- self.depth[char] = _fix2comp(depths[byte1 & 0xf])
-
-
-PsFont = namedtuple('Font', 'texname psname effects encoding filename')
-
-
-class PsfontsMap(object):
- """
- A psfonts.map formatted file, mapping TeX fonts to PS fonts.
-
- Usage::
-
- >>> map = PsfontsMap(find_tex_file('pdftex.map'))
- >>> entry = map[b'ptmbo8r']
- >>> entry.texname
- b'ptmbo8r'
- >>> entry.psname
- b'Times-Bold'
- >>> entry.encoding
- '/usr/local/texlive/2008/texmf-dist/fonts/enc/dvips/base/8r.enc'
- >>> entry.effects
- {'slant': 0.16700000000000001}
- >>> entry.filename
-
- Parameters
- ----------
-
- filename : string or bytestring
-
- Notes
- -----
-
- For historical reasons, TeX knows many Type-1 fonts by different
- names than the outside world. (For one thing, the names have to
- fit in eight characters.) Also, TeX's native fonts are not Type-1
- but Metafont, which is nontrivial to convert to PostScript except
- as a bitmap. While high-quality conversions to Type-1 format exist
- and are shipped with modern TeX distributions, we need to know
- which Type-1 fonts are the counterparts of which native fonts. For
- these reasons a mapping is needed from internal font names to font
- file names.
-
- A texmf tree typically includes mapping files called e.g.
- :file:`psfonts.map`, :file:`pdftex.map`, or :file:`dvipdfm.map`.
- The file :file:`psfonts.map` is used by :program:`dvips`,
- :file:`pdftex.map` by :program:`pdfTeX`, and :file:`dvipdfm.map`
- by :program:`dvipdfm`. :file:`psfonts.map` might avoid embedding
- the 35 PostScript fonts (i.e., have no filename for them, as in
- the Times-Bold example above), while the pdf-related files perhaps
- only avoid the "Base 14" pdf fonts. But the user may have
- configured these files differently.
- """
- __slots__ = ('_font', '_filename')
-
- def __init__(self, filename):
- self._font = {}
- self._filename = filename
- if six.PY3 and isinstance(filename, bytes):
- encoding = sys.getfilesystemencoding() or 'utf-8'
- self._filename = filename.decode(encoding, errors='replace')
- with open(filename, 'rb') as file:
- self._parse(file)
-
- def __getitem__(self, texname):
- assert isinstance(texname, bytes)
- try:
- result = self._font[texname]
- except KeyError:
- fmt = ('A PostScript file for the font whose TeX name is "{0}" '
- 'could not be found in the file "{1}". The dviread module '
- 'can only handle fonts that have an associated PostScript '
- 'font file. '
- 'This problem can often be solved by installing '
- 'a suitable PostScript font package in your (TeX) '
- 'package manager.')
- msg = fmt.format(texname.decode('ascii'), self._filename)
- msg = textwrap.fill(msg, break_on_hyphens=False,
- break_long_words=False)
- _log.info(msg)
- raise
- fn, enc = result.filename, result.encoding
- if fn is not None and not fn.startswith(b'/'):
- fn = find_tex_file(fn)
- if enc is not None and not enc.startswith(b'/'):
- enc = find_tex_file(result.encoding)
- return result._replace(filename=fn, encoding=enc)
-
- def _parse(self, file):
- """
- Parse the font mapping file.
-
- The format is, AFAIK: texname fontname [effects and filenames]
- Effects are PostScript snippets like ".177 SlantFont",
- filenames begin with one or two less-than signs. A filename
- ending in enc is an encoding file, other filenames are font
- files. This can be overridden with a left bracket: <[foobar
- indicates an encoding file named foobar.
-
- There is some difference between <foo.pfb and <<bar.pfb in
- subsetting, but I have no example of << in my TeX installation.
- """
- # If the map file specifies multiple encodings for a font, we
- # follow pdfTeX in choosing the last one specified. Such
- # entries are probably mistakes but they have occurred.
- # http://tex.stackexchange.com/questions/10826/
- # http://article.gmane.org/gmane.comp.tex.pdftex/4914
-
- empty_re = re.compile(br'%|\s*$')
- word_re = re.compile(
- br'''(?x) (?:
- "<\[ (?P<enc1> [^"]+ )" | # quoted encoding marked by [
- "< (?P<enc2> [^"]+.enc)" | # quoted encoding, ends in .enc
- "<<? (?P<file1> [^"]+ )" | # quoted font file name
- " (?P<eff1> [^"]+ )" | # quoted effects or font name
- <\[ (?P<enc3> \S+ ) | # encoding marked by [
- < (?P<enc4> \S+ .enc) | # encoding, ends in .enc
- <<? (?P<file2> \S+ ) | # font file name
- (?P<eff2> \S+ ) # effects or font name
- )''')
- effects_re = re.compile(
- br'''(?x) (?P<slant> -?[0-9]*(?:\.[0-9]+)) \s* SlantFont
- | (?P<extend>-?[0-9]*(?:\.[0-9]+)) \s* ExtendFont''')
-
- lines = (line.strip()
- for line in file
- if not empty_re.match(line))
- for line in lines:
- effects, encoding, filename = b'', None, None
- words = word_re.finditer(line)
-
- # The named groups are mutually exclusive and are
- # referenced below at an estimated order of probability of
- # occurrence based on looking at my copy of pdftex.map.
- # The font names are probably unquoted:
- w = next(words)
- texname = w.group('eff2') or w.group('eff1')
- w = next(words)
- psname = w.group('eff2') or w.group('eff1')
-
- for w in words:
- # Any effects are almost always quoted:
- eff = w.group('eff1') or w.group('eff2')
- if eff:
- effects = eff
- continue
- # Encoding files usually have the .enc suffix
- # and almost never need quoting:
- enc = (w.group('enc4') or w.group('enc3') or
- w.group('enc2') or w.group('enc1'))
- if enc:
- if encoding is not None:
- _log.debug('Multiple encodings for %s = %s',
- texname, psname)
- encoding = enc
- continue
- # File names are probably unquoted:
- filename = w.group('file2') or w.group('file1')
-
- effects_dict = {}
- for match in effects_re.finditer(effects):
- slant = match.group('slant')
- if slant:
- effects_dict['slant'] = float(slant)
- else:
- effects_dict['extend'] = float(match.group('extend'))
-
- self._font[texname] = PsFont(
- texname=texname, psname=psname, effects=effects_dict,
- encoding=encoding, filename=filename)
-
-
-class Encoding(object):
- """
- Parses a \\*.enc file referenced from a psfonts.map style file.
- The format this class understands is a very limited subset of
- PostScript.
-
- Usage (subject to change)::
-
- for name in Encoding(filename):
- whatever(name)
-
- Parameters
- ----------
- filename : string or bytestring
-
- Attributes
- ----------
- encoding : list
- List of character names
- """
- __slots__ = ('encoding',)
-
- def __init__(self, filename):
- with open(filename, 'rb') as file:
- _log.debug('Parsing TeX encoding %s', filename)
- self.encoding = self._parse(file)
- _log.debug('Result: %s', self.encoding)
-
- def __iter__(self):
- for name in self.encoding:
- yield name
-
- def _parse(self, file):
- result = []
-
- lines = (line.split(b'%', 1)[0].strip() for line in file)
- data = b''.join(lines)
- beginning = data.find(b'[')
- if beginning < 0:
- raise ValueError("Cannot locate beginning of encoding in {}"
- .format(file))
- data = data[beginning:]
- end = data.find(b']')
- if end < 0:
- raise ValueError("Cannot locate end of encoding in {}"
- .format(file))
- data = data[:end]
-
- return re.findall(br'/([^][{}<>\s]+)', data)
-
-
-def find_tex_file(filename, format=None):
- """
- Find a file in the texmf tree.
-
- Calls :program:`kpsewhich` which is an interface to the kpathsea
- library [1]_. Most existing TeX distributions on Unix-like systems use
- kpathsea. It is also available as part of MikTeX, a popular
- distribution on Windows.
-
- Parameters
- ----------
- filename : string or bytestring
- format : string or bytestring
- Used as the value of the `--format` option to :program:`kpsewhich`.
- Could be e.g. 'tfm' or 'vf' to limit the search to that type of files.
-
- References
- ----------
-
- .. [1] `Kpathsea documentation <http://www.tug.org/kpathsea/>`_
- The library that :program:`kpsewhich` is part of.
- """
-
- if six.PY3:
- # we expect these to always be ascii encoded, but use utf-8
- # out of caution
- if isinstance(filename, bytes):
- filename = filename.decode('utf-8', errors='replace')
- if isinstance(format, bytes):
- format = format.decode('utf-8', errors='replace')
-
- cmd = ['kpsewhich']
- if format is not None:
- cmd += ['--format=' + format]
- cmd += [filename]
- _log.debug('find_tex_file(%s): %s', filename, cmd)
- # stderr is unused, but reading it avoids a subprocess optimization
- # that breaks EINTR handling in some Python versions:
- # http://bugs.python.org/issue12493
- # https://github.com/matplotlib/matplotlib/issues/633
- pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- result = pipe.communicate()[0].rstrip()
- _log.debug('find_tex_file result: %s', result)
- return result.decode('ascii')
-
-
-# With multiple text objects per figure (e.g., tick labels) we may end
-# up reading the same tfm and vf files many times, so we implement a
-# simple cache. TODO: is this worth making persistent?
-
-@lru_cache()
-def _fontfile(cls, suffix, texname):
- filename = find_tex_file(texname + suffix)
- return cls(filename) if filename else None
-
-
-_tfmfile = partial(_fontfile, Tfm, ".tfm")
-_vffile = partial(_fontfile, Vf, ".vf")
-
-
-if __name__ == '__main__':
- import sys
- fname = sys.argv[1]
- try:
- dpi = float(sys.argv[2])
- except IndexError:
- dpi = None
- with Dvi(fname, dpi) as dvi:
- fontmap = PsfontsMap(find_tex_file('pdftex.map'))
- for page in dvi:
- print('=== new page ===')
- fPrev = None
- for x, y, f, c, w in page.text:
- if f != fPrev:
- print('font', f.texname, 'scaled', f._scale/pow(2.0, 20))
- fPrev = f
- print(x, y, c, 32 <= c < 128 and chr(c) or '.', w)
- for x, y, w, h in page.boxes:
- print(x, y, 'BOX', w, h)
diff --git a/contrib/python/matplotlib/py2/matplotlib/figure.py b/contrib/python/matplotlib/py2/matplotlib/figure.py
deleted file mode 100644
index d80b16d55a..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/figure.py
+++ /dev/null
@@ -1,2532 +0,0 @@
-"""
-The figure module provides the top-level
-:class:`~matplotlib.artist.Artist`, the :class:`Figure`, which
-contains all the plot elements. The following classes are defined
-
-:class:`SubplotParams`
- control the default spacing of the subplots
-
-:class:`Figure`
- Top level container for all plot elements.
-
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import logging
-import warnings
-
-import numpy as np
-
-from matplotlib import rcParams
-from matplotlib import docstring
-from matplotlib import __version__ as _mpl_version
-
-import matplotlib.artist as martist
-from matplotlib.artist import Artist, allow_rasterization
-
-import matplotlib.cbook as cbook
-
-from matplotlib.cbook import Stack, iterable
-
-from matplotlib import image as mimage
-from matplotlib.image import FigureImage
-
-import matplotlib.colorbar as cbar
-
-from matplotlib.axes import Axes, SubplotBase, subplot_class_factory
-from matplotlib.blocking_input import BlockingMouseInput, BlockingKeyMouseInput
-from matplotlib.gridspec import GridSpec
-import matplotlib.legend as mlegend
-from matplotlib.patches import Rectangle
-from matplotlib.projections import (get_projection_names,
- process_projection_requirements)
-from matplotlib.text import Text, _process_text_args
-from matplotlib.transforms import (Affine2D, Bbox, BboxTransformTo,
- TransformedBbox)
-import matplotlib._layoutbox as layoutbox
-from matplotlib.backend_bases import NonGuiException
-
-_log = logging.getLogger(__name__)
-
-docstring.interpd.update(projection_names=get_projection_names())
-
-
-def _stale_figure_callback(self, val):
- if self.figure:
- self.figure.stale = val
-
-
-class AxesStack(Stack):
- """
- Specialization of the `.Stack` to handle all tracking of
- `~matplotlib.axes.Axes` in a `.Figure`.
- This stack stores ``key, (ind, axes)`` pairs, where:
-
- * **key** should be a hash of the args and kwargs
- used in generating the Axes.
- * **ind** is a serial number for tracking the order
- in which axes were added.
-
- The AxesStack is a callable, where ``ax_stack()`` returns
- the current axes. Alternatively the :meth:`current_key_axes` will
- return the current key and associated axes.
-
- """
- def __init__(self):
- Stack.__init__(self)
- self._ind = 0
-
- def as_list(self):
- """
- Return a list of the Axes instances that have been added to the figure
- """
- ia_list = [a for k, a in self._elements]
- ia_list.sort()
- return [a for i, a in ia_list]
-
- def get(self, key):
- """
- Return the Axes instance that was added with *key*.
- If it is not present, return None.
- """
- item = dict(self._elements).get(key)
- if item is None:
- return None
- cbook.warn_deprecated(
- "2.1",
- "Adding an axes using the same arguments as a previous axes "
- "currently reuses the earlier instance. In a future version, "
- "a new instance will always be created and returned. Meanwhile, "
- "this warning can be suppressed, and the future behavior ensured, "
- "by passing a unique label to each axes instance.")
- return item[1]
-
- def _entry_from_axes(self, e):
- ind, k = {a: (ind, k) for k, (ind, a) in self._elements}[e]
- return (k, (ind, e))
-
- def remove(self, a):
- """Remove the axes from the stack."""
- Stack.remove(self, self._entry_from_axes(a))
-
- def bubble(self, a):
- """
- Move the given axes, which must already exist in the
- stack, to the top.
- """
- return Stack.bubble(self, self._entry_from_axes(a))
-
- def add(self, key, a):
- """
- Add Axes *a*, with key *key*, to the stack, and return the stack.
-
- If *key* is unhashable, replace it by a unique, arbitrary object.
-
- If *a* is already on the stack, don't add it again, but
- return *None*.
- """
- # All the error checking may be unnecessary; but this method
- # is called so seldom that the overhead is negligible.
- if not isinstance(a, Axes):
- raise ValueError("second argument, {!r}, is not an Axes".format(a))
- try:
- hash(key)
- except TypeError:
- key = object()
-
- a_existing = self.get(key)
- if a_existing is not None:
- Stack.remove(self, (key, a_existing))
- warnings.warn(
- "key {!r} already existed; Axes is being replaced".format(key))
- # I don't think the above should ever happen.
-
- if a in self:
- return None
- self._ind += 1
- return Stack.push(self, (key, (self._ind, a)))
-
- def current_key_axes(self):
- """
- Return a tuple of ``(key, axes)`` for the active axes.
-
- If no axes exists on the stack, then returns ``(None, None)``.
- """
- if not len(self._elements):
- return self._default, self._default
- else:
- key, (index, axes) = self._elements[self._pos]
- return key, axes
-
- def __call__(self):
- return self.current_key_axes()[1]
-
- def __contains__(self, a):
- return a in self.as_list()
-
-
-class SubplotParams(object):
- """
- A class to hold the parameters for a subplot.
- """
- def __init__(self, left=None, bottom=None, right=None, top=None,
- wspace=None, hspace=None):
- """
- All dimensions are fractions of the figure width or height.
- Defaults are given by :rc:`figure.subplot.[name]`.
-
- Parameters
- ----------
- left : float
- The left side of the subplots of the figure.
-
- right : float
- The right side of the subplots of the figure.
-
- bottom : float
- The bottom of the subplots of the figure.
-
- top : float
- The top of the subplots of the figure.
-
- wspace : float
- The amount of width reserved for space between subplots,
- expressed as a fraction of the average axis width.
-
- hspace : float
- The amount of height reserved for space between subplots,
- expressed as a fraction of the average axis height.
- """
- self.validate = True
- self.update(left, bottom, right, top, wspace, hspace)
-
- def update(self, left=None, bottom=None, right=None, top=None,
- wspace=None, hspace=None):
- """
- Update the dimensions of the passed parameters. *None* means unchanged.
- """
- thisleft = getattr(self, 'left', None)
- thisright = getattr(self, 'right', None)
- thistop = getattr(self, 'top', None)
- thisbottom = getattr(self, 'bottom', None)
- thiswspace = getattr(self, 'wspace', None)
- thishspace = getattr(self, 'hspace', None)
-
- self._update_this('left', left)
- self._update_this('right', right)
- self._update_this('bottom', bottom)
- self._update_this('top', top)
- self._update_this('wspace', wspace)
- self._update_this('hspace', hspace)
-
- def reset():
- self.left = thisleft
- self.right = thisright
- self.top = thistop
- self.bottom = thisbottom
- self.wspace = thiswspace
- self.hspace = thishspace
-
- if self.validate:
- if self.left >= self.right:
- reset()
- raise ValueError('left cannot be >= right')
-
- if self.bottom >= self.top:
- reset()
- raise ValueError('bottom cannot be >= top')
-
- def _update_this(self, s, val):
- if val is None:
- val = getattr(self, s, None)
- if val is None:
- key = 'figure.subplot.' + s
- val = rcParams[key]
-
- setattr(self, s, val)
-
-
-class Figure(Artist):
- """
- The top level container for all the plot elements.
-
- The Figure instance supports callbacks through a *callbacks* attribute
- which is a `.CallbackRegistry` instance. The events you can connect to
- are 'dpi_changed', and the callback will be called with ``func(fig)`` where
- fig is the `Figure` instance.
-
- Attributes
- ----------
- patch
- The `.Rectangle` instance representing the figure patch.
-
- suppressComposite
- For multiple figure images, the figure will make composite images
- depending on the renderer option_image_nocomposite function. If
- *suppressComposite* is a boolean, this will override the renderer.
- """
-
- def __str__(self):
- return "Figure(%gx%g)" % tuple(self.bbox.size)
-
- def __repr__(self):
- return "<{clsname} size {h:g}x{w:g} with {naxes} Axes>".format(
- clsname=self.__class__.__name__,
- h=self.bbox.size[0], w=self.bbox.size[1],
- naxes=len(self.axes),
- )
-
- def __init__(self,
- figsize=None,
- dpi=None,
- facecolor=None,
- edgecolor=None,
- linewidth=0.0,
- frameon=None,
- subplotpars=None, # default to rc
- tight_layout=None, # default to rc figure.autolayout
- constrained_layout=None, # default to rc
- #figure.constrained_layout.use
- ):
- """
- Parameters
- ----------
- figsize : 2-tuple of floats, default: :rc:`figure.figsize`
- Figure dimension ``(width, height)`` in inches.
-
- dpi : float, default: :rc:`figure.dpi`
- Dots per inch.
-
- facecolor : default: :rc:`figure.facecolor`
- The figure patch facecolor.
-
- edgecolor : default: :rc:`figure.edgecolor`
- The figure patch edge color.
-
- linewidth : float
- The linewidth of the frame (i.e. the edge linewidth of the figure
- patch).
-
- frameon : bool, default: :rc:`figure.frameon`
- If ``False``, suppress drawing the figure frame.
-
- subplotpars : :class:`SubplotParams`
- Subplot parameters. If not given, the default subplot
- parameters :rc:`figure.subplot.*` are used.
-
- tight_layout : bool or dict, default: :rc:`figure.autolayout`
- If ``False`` use *subplotpars*. If ``True`` adjust subplot
- parameters using `.tight_layout` with default padding.
- When providing a dict containing the keys ``pad``, ``w_pad``,
- ``h_pad``, and ``rect``, the default `.tight_layout` paddings
- will be overridden.
-
- constrained_layout : bool
- If ``True`` use constrained layout to adjust positioning of plot
- elements. Like ``tight_layout``, but designed to be more
- flexible. See
- :doc:`/tutorials/intermediate/constrainedlayout_guide`
- for examples. (Note: does not work with :meth:`.subplot` or
- :meth:`.subplot2grid`.)
- Defaults to :rc:`figure.constrained_layout.use`.
- """
- Artist.__init__(self)
- # remove the non-figure artist _axes property
- # as it makes no sense for a figure to be _in_ an axes
- # this is used by the property methods in the artist base class
- # which are over-ridden in this class
- del self._axes
- self.callbacks = cbook.CallbackRegistry()
-
- if figsize is None:
- figsize = rcParams['figure.figsize']
- if dpi is None:
- dpi = rcParams['figure.dpi']
- if facecolor is None:
- facecolor = rcParams['figure.facecolor']
- if edgecolor is None:
- edgecolor = rcParams['figure.edgecolor']
- if frameon is None:
- frameon = rcParams['figure.frameon']
-
- if not np.isfinite(figsize).all():
- raise ValueError('figure size must be finite not '
- '{}'.format(figsize))
- self.bbox_inches = Bbox.from_bounds(0, 0, *figsize)
-
- self.dpi_scale_trans = Affine2D().scale(dpi, dpi)
- # do not use property as it will trigger
- self._dpi = dpi
- self.bbox = TransformedBbox(self.bbox_inches, self.dpi_scale_trans)
-
- self.frameon = frameon
-
- self.transFigure = BboxTransformTo(self.bbox)
-
- self.patch = Rectangle(
- xy=(0, 0), width=1, height=1,
- facecolor=facecolor, edgecolor=edgecolor, linewidth=linewidth)
- self._set_artist_props(self.patch)
- self.patch.set_aa(False)
-
- self._hold = rcParams['axes.hold']
- if self._hold is None:
- self._hold = True
-
- self.canvas = None
- self._suptitle = None
-
- if subplotpars is None:
- subplotpars = SubplotParams()
-
- self.subplotpars = subplotpars
- # constrained_layout:
- self._layoutbox = None
- # set in set_constrained_layout_pads()
- self.set_constrained_layout(constrained_layout)
-
- self.set_tight_layout(tight_layout)
-
- self._axstack = AxesStack() # track all figure axes and current axes
- self.clf()
- self._cachedRenderer = None
-
- # groupers to keep track of x and y labels we want to align.
- # see self.align_xlabels and self.align_ylabels and
- # axis._get_tick_boxes_siblings
- self._align_xlabel_grp = cbook.Grouper()
- self._align_ylabel_grp = cbook.Grouper()
-
- @property
- @cbook.deprecated("2.1", alternative="`.Figure.patch`")
- def figurePatch(self):
- return self.patch
-
- # TODO: I'd like to dynamically add the _repr_html_ method
- # to the figure in the right context, but then IPython doesn't
- # use it, for some reason.
-
- def _repr_html_(self):
- # We can't use "isinstance" here, because then we'd end up importing
- # webagg unconditiionally.
- if (self.canvas is not None and
- 'WebAgg' in self.canvas.__class__.__name__):
- from matplotlib.backends import backend_webagg
- return backend_webagg.ipython_inline_display(self)
-
- def show(self, warn=True):
- """
- If using a GUI backend with pyplot, display the figure window.
-
- If the figure was not created using
- :func:`~matplotlib.pyplot.figure`, it will lack a
- :class:`~matplotlib.backend_bases.FigureManagerBase`, and
- will raise an AttributeError.
-
- Parameters
- ----------
- warm : bool
- If ``True``, issue warning when called on a non-GUI backend
-
- Notes
- -----
- For non-GUI backends, this does nothing, in which case a warning will
- be issued if *warn* is ``True`` (default).
- """
- try:
- manager = getattr(self.canvas, 'manager')
- except AttributeError as err:
- raise AttributeError("%s\n"
- "Figure.show works only "
- "for figures managed by pyplot, normally "
- "created by pyplot.figure()." % err)
-
- if manager is not None:
- try:
- manager.show()
- return
- except NonGuiException:
- pass
- if warn:
- import warnings
- warnings.warn(
- "matplotlib is currently using a non-GUI backend, "
- "so cannot show the figure")
-
- def _get_axes(self):
- return self._axstack.as_list()
-
- axes = property(fget=_get_axes,
- doc="List of axes in the Figure. You can access the "
- "axes in the Figure through this list. "
- "Do not modify the list itself. Instead, use "
- "`~Figure.add_axes`, `~.Figure.subplot` or "
- "`~.Figure.delaxes` to add or remove an axes.")
-
- def _get_dpi(self):
- return self._dpi
-
- def _set_dpi(self, dpi, forward=True):
- """
- Parameters
- ----------
- dpi : float
-
- forward : bool
- Passed on to `~.Figure.set_size_inches`
- """
- self._dpi = dpi
- self.dpi_scale_trans.clear().scale(dpi, dpi)
- w, h = self.get_size_inches()
- self.set_size_inches(w, h, forward=forward)
- self.callbacks.process('dpi_changed', self)
-
- dpi = property(_get_dpi, _set_dpi, doc="The resolution in dots per inch.")
-
- def get_tight_layout(self):
- """Return whether `.tight_layout` is called when drawing."""
- return self._tight
-
- def set_tight_layout(self, tight):
- """
- Set whether and how `.tight_layout` is called when drawing.
-
- Parameters
- ----------
- tight : bool or dict with keys "pad", "w_pad", "h_pad", "rect" or None
- If a bool, sets whether to call `.tight_layout` upon drawing.
- If ``None``, use the ``figure.autolayout`` rcparam instead.
- If a dict, pass it as kwargs to `.tight_layout`, overriding the
- default paddings.
-
- ..
- ACCEPTS: [ bool
- | dict with keys "pad", "w_pad", "h_pad", "rect"
- | None ]
- """
- if tight is None:
- tight = rcParams['figure.autolayout']
- self._tight = bool(tight)
- self._tight_parameters = tight if isinstance(tight, dict) else {}
- self.stale = True
-
- def get_constrained_layout(self):
- """
- Return a boolean: True means constrained layout is being used.
-
- See :doc:`/tutorials/intermediate/constrainedlayout_guide`.
- """
- return self._constrained
-
- def set_constrained_layout(self, constrained):
- """
- Set whether ``constrained_layout`` is used upon drawing. If None,
- the rcParams['figure.constrained_layout.use'] value will be used.
-
- When providing a dict containing the keys `w_pad`, `h_pad`
- the default ``constrained_layout`` paddings will be
- overridden. These pads are in inches and default to 3.0/72.0.
- ``w_pad`` is the width padding and ``h_pad`` is the height padding.
-
- ACCEPTS: [True | False | dict | None ]
-
- See :doc:`/tutorials/intermediate/constrainedlayout_guide`.
- """
- self._constrained_layout_pads = dict()
- self._constrained_layout_pads['w_pad'] = None
- self._constrained_layout_pads['h_pad'] = None
- self._constrained_layout_pads['wspace'] = None
- self._constrained_layout_pads['hspace'] = None
- if constrained is None:
- constrained = rcParams['figure.constrained_layout.use']
- self._constrained = bool(constrained)
- if isinstance(constrained, dict):
- self.set_constrained_layout_pads(**constrained)
- else:
- self.set_constrained_layout_pads()
-
- self.stale = True
-
- def set_constrained_layout_pads(self, **kwargs):
- """
- Set padding for ``constrained_layout``. Note the kwargs can be passed
- as a dictionary ``fig.set_constrained_layout(**paddict)``.
-
- See :doc:`/tutorials/intermediate/constrainedlayout_guide`.
-
- Parameters
- ----------
-
- w_pad : scalar
- Width padding in inches. This is the pad around axes
- and is meant to make sure there is enough room for fonts to
- look good. Defaults to 3 pts = 0.04167 inches
-
- h_pad : scalar
- Height padding in inches. Defaults to 3 pts.
-
- wspace: scalar
- Width padding between subplots, expressed as a fraction of the
- subplot width. The total padding ends up being w_pad + wspace.
-
- hspace: scalar
- Height padding between subplots, expressed as a fraction of the
- subplot width. The total padding ends up being h_pad + hspace.
-
- """
-
- todo = ['w_pad', 'h_pad', 'wspace', 'hspace']
- for td in todo:
- if td in kwargs and kwargs[td] is not None:
- self._constrained_layout_pads[td] = kwargs[td]
- else:
- self._constrained_layout_pads[td] = (
- rcParams['figure.constrained_layout.' + td])
-
- def get_constrained_layout_pads(self, relative=False):
- """
- Get padding for ``constrained_layout``.
-
- Returns a list of `w_pad, h_pad` in inches and
- `wspace` and `hspace` as fractions of the subplot.
-
- See :doc:`/tutorials/intermediate/constrainedlayout_guide`.
-
- Parameters
- ----------
-
- relative : boolean
- If `True`, then convert from inches to figure relative.
- """
- w_pad = self._constrained_layout_pads['w_pad']
- h_pad = self._constrained_layout_pads['h_pad']
- wspace = self._constrained_layout_pads['wspace']
- hspace = self._constrained_layout_pads['hspace']
-
- if relative and ((w_pad is not None) or (h_pad is not None)):
- renderer0 = layoutbox.get_renderer(self)
- dpi = renderer0.dpi
- w_pad = w_pad * dpi / renderer0.width
- h_pad = h_pad * dpi / renderer0.height
-
- return w_pad, h_pad, wspace, hspace
-
- def autofmt_xdate(self, bottom=0.2, rotation=30, ha='right', which=None):
- """
- Date ticklabels often overlap, so it is useful to rotate them
- and right align them. Also, a common use case is a number of
- subplots with shared xaxes where the x-axis is date data. The
- ticklabels are often long, and it helps to rotate them on the
- bottom subplot and turn them off on other subplots, as well as
- turn off xlabels.
-
- Parameters
- ----------
- bottom : scalar
- The bottom of the subplots for :meth:`subplots_adjust`.
-
- rotation : angle in degrees
- The rotation of the xtick labels.
-
- ha : string
- The horizontal alignment of the xticklabels.
-
- which : {None, 'major', 'minor', 'both'}
- Selects which ticklabels to rotate. Default is None which works
- the same as major.
- """
- allsubplots = all(hasattr(ax, 'is_last_row') for ax in self.axes)
- if len(self.axes) == 1:
- for label in self.axes[0].get_xticklabels(which=which):
- label.set_ha(ha)
- label.set_rotation(rotation)
- else:
- if allsubplots:
- for ax in self.get_axes():
- if ax.is_last_row():
- for label in ax.get_xticklabels(which=which):
- label.set_ha(ha)
- label.set_rotation(rotation)
- else:
- for label in ax.get_xticklabels(which=which):
- label.set_visible(False)
- ax.set_xlabel('')
-
- if allsubplots:
- self.subplots_adjust(bottom=bottom)
- self.stale = True
-
- def get_children(self):
- """Get a list of artists contained in the figure."""
- children = [self.patch]
- children.extend(self.artists)
- children.extend(self.axes)
- children.extend(self.lines)
- children.extend(self.patches)
- children.extend(self.texts)
- children.extend(self.images)
- children.extend(self.legends)
- return children
-
- def contains(self, mouseevent):
- """
- Test whether the mouse event occurred on the figure.
-
- Returns
- -------
- bool, {}
- """
- if callable(self._contains):
- return self._contains(self, mouseevent)
- inside = self.bbox.contains(mouseevent.x, mouseevent.y)
- return inside, {}
-
- def get_window_extent(self, *args, **kwargs):
- """
- Return the figure bounding box in display space. Arguments are ignored.
- """
- return self.bbox
-
- def suptitle(self, t, **kwargs):
- """
- Add a centered title to the figure.
-
- kwargs are :class:`matplotlib.text.Text` properties. Using figure
- coordinates, the defaults are:
-
- x : 0.5
- The x location of the text in figure coords
-
- y : 0.98
- The y location of the text in figure coords
-
- horizontalalignment : 'center'
- The horizontal alignment of the text
-
- verticalalignment : 'top'
- The vertical alignment of the text
-
- If the `fontproperties` keyword argument is given then the
- rcParams defaults for `fontsize` (`figure.titlesize`) and
- `fontweight` (`figure.titleweight`) will be ignored in favour
- of the `FontProperties` defaults.
-
- A :class:`matplotlib.text.Text` instance is returned.
-
- Example::
-
- fig.suptitle('this is the figure title', fontsize=12)
- """
- manual_position = ('x' in kwargs or 'y' in kwargs)
-
- x = kwargs.pop('x', 0.5)
- y = kwargs.pop('y', 0.98)
-
- if ('horizontalalignment' not in kwargs) and ('ha' not in kwargs):
- kwargs['horizontalalignment'] = 'center'
- if ('verticalalignment' not in kwargs) and ('va' not in kwargs):
- kwargs['verticalalignment'] = 'top'
-
- if 'fontproperties' not in kwargs:
- if 'fontsize' not in kwargs and 'size' not in kwargs:
- kwargs['size'] = rcParams['figure.titlesize']
- if 'fontweight' not in kwargs and 'weight' not in kwargs:
- kwargs['weight'] = rcParams['figure.titleweight']
-
- sup = self.text(x, y, t, **kwargs)
- if self._suptitle is not None:
- self._suptitle.set_text(t)
- self._suptitle.set_position((x, y))
- self._suptitle.update_from(sup)
- sup.remove()
- else:
- self._suptitle = sup
- self._suptitle._layoutbox = None
- if self._layoutbox is not None and not manual_position:
- w_pad, h_pad, wspace, hspace = \
- self.get_constrained_layout_pads(relative=True)
- figlb = self._layoutbox
- self._suptitle._layoutbox = layoutbox.LayoutBox(
- parent=figlb, artist=self._suptitle,
- name=figlb.name+'.suptitle')
- # stack the suptitle on top of all the children.
- # Some day this should be on top of all the children in the
- # gridspec only.
- for child in figlb.children:
- if child is not self._suptitle._layoutbox:
- layoutbox.vstack([self._suptitle._layoutbox,
- child],
- padding=h_pad*2., strength='required')
- self.stale = True
- return self._suptitle
-
- def set_canvas(self, canvas):
- """
- Set the canvas that contains the figure
-
- ACCEPTS: a FigureCanvas instance
- """
- self.canvas = canvas
-
- @cbook.deprecated("2.0")
- def hold(self, b=None):
- """
- Set the hold state. If hold is None (default), toggle the
- hold state. Else set the hold state to boolean value b.
-
- e.g.::
-
- hold() # toggle hold
- hold(True) # hold is on
- hold(False) # hold is off
-
- All "hold" machinery is deprecated.
- """
- if b is None:
- self._hold = not self._hold
- else:
- self._hold = b
-
- def figimage(self, X, xo=0, yo=0, alpha=None, norm=None, cmap=None,
- vmin=None, vmax=None, origin=None, resize=False, **kwargs):
- """
- Add a non-resampled image to the figure.
-
- The image is attached to the lower or upper left corner depending on
- *origin*.
-
- Parameters
- ----------
- X
- The image data. This is an array of one of the following shapes:
-
- - MxN: luminance (grayscale) values
- - MxNx3: RGB values
- - MxNx4: RGBA values
-
- xo, yo : int
- The *x*/*y* image offset in pixels.
-
- alpha : None or float
- The alpha blending value.
-
- norm : :class:`matplotlib.colors.Normalize`
- A :class:`.Normalize` instance to map the luminance to the
- interval [0, 1].
-
- cmap : str or :class:`matplotlib.colors.Colormap`
- The colormap to use. Default: :rc:`image.cmap`.
-
- vmin, vmax : scalar
- If *norm* is not given, these values set the data limits for the
- colormap.
-
- origin : {'upper', 'lower'}
- Indicates where the [0, 0] index of the array is in the upper left
- or lower left corner of the axes. Defaults to :rc:`image.origin`.
-
- resize : bool
- If *True*, resize the figure to match the given image size.
-
- Returns
- -------
- :class:`matplotlib.image.FigureImage`
-
- Other Parameters
- ----------------
- **kwargs
- Additional kwargs are `.Artist` kwargs passed on to `.FigureImage`.
-
- Notes
- -----
- figimage complements the axes image
- (:meth:`~matplotlib.axes.Axes.imshow`) which will be resampled
- to fit the current axes. If you want a resampled image to
- fill the entire figure, you can define an
- :class:`~matplotlib.axes.Axes` with extent [0,0,1,1].
-
-
- Examples::
-
- f = plt.figure()
- nx = int(f.get_figwidth() * f.dpi)
- ny = int(f.get_figheight() * f.dpi)
- data = np.random.random((ny, nx))
- f.figimage(data)
- plt.show()
-
- """
-
- if not self._hold:
- self.clf()
-
- if resize:
- dpi = self.get_dpi()
- figsize = [x / dpi for x in (X.shape[1], X.shape[0])]
- self.set_size_inches(figsize, forward=True)
-
- im = FigureImage(self, cmap, norm, xo, yo, origin, **kwargs)
- im.stale_callback = _stale_figure_callback
-
- im.set_array(X)
- im.set_alpha(alpha)
- if norm is None:
- im.set_clim(vmin, vmax)
- self.images.append(im)
- im._remove_method = lambda h: self.images.remove(h)
- self.stale = True
- return im
-
- def set_size_inches(self, w, h=None, forward=True):
- """Set the figure size in inches (1in == 2.54cm)
-
- Usage ::
-
- fig.set_size_inches(w, h) # OR
- fig.set_size_inches((w, h))
-
- optional kwarg *forward=True* will cause the canvas size to be
- automatically updated; e.g., you can resize the figure window
- from the shell
-
- ACCEPTS: a w, h tuple with w, h in inches
-
- See Also
- --------
- matplotlib.Figure.get_size_inches
- """
-
- # the width and height have been passed in as a tuple to the first
- # argument, so unpack them
- if h is None:
- w, h = w
- if not all(np.isfinite(_) for _ in (w, h)):
- raise ValueError('figure size must be finite not '
- '({}, {})'.format(w, h))
- self.bbox_inches.p1 = w, h
-
- if forward:
- canvas = getattr(self, 'canvas')
- if canvas is not None:
- ratio = getattr(self.canvas, '_dpi_ratio', 1)
- dpival = self.dpi / ratio
- canvasw = w * dpival
- canvash = h * dpival
- manager = getattr(self.canvas, 'manager', None)
- if manager is not None:
- manager.resize(int(canvasw), int(canvash))
- self.stale = True
-
- def get_size_inches(self):
- """
- Returns the current size of the figure in inches.
-
- Returns
- -------
- size : ndarray
- The size (width, height) of the figure in inches.
-
- See Also
- --------
- matplotlib.Figure.set_size_inches
- """
- return np.array(self.bbox_inches.p1)
-
- def get_edgecolor(self):
- """Get the edge color of the Figure rectangle."""
- return self.patch.get_edgecolor()
-
- def get_facecolor(self):
- """Get the face color of the Figure rectangle."""
- return self.patch.get_facecolor()
-
- def get_figwidth(self):
- """Return the figure width as a float."""
- return self.bbox_inches.width
-
- def get_figheight(self):
- """Return the figure height as a float."""
- return self.bbox_inches.height
-
- def get_dpi(self):
- """Return the resolution in dots per inch as a float."""
- return self.dpi
-
- def get_frameon(self):
- """Return whether the figure frame will be drawn."""
- return self.frameon
-
- def set_edgecolor(self, color):
- """
- Set the edge color of the Figure rectangle.
-
- ACCEPTS: any matplotlib color - see help(colors)
- """
- self.patch.set_edgecolor(color)
-
- def set_facecolor(self, color):
- """
- Set the face color of the Figure rectangle.
-
- ACCEPTS: any matplotlib color - see help(colors)
- """
- self.patch.set_facecolor(color)
-
- def set_dpi(self, val):
- """
- Set the dots-per-inch of the figure.
-
- ACCEPTS: float
- """
- self.dpi = val
- self.stale = True
-
- def set_figwidth(self, val, forward=True):
- """
- Set the width of the figure in inches.
-
- ACCEPTS: float
- """
- self.set_size_inches(val, self.get_figheight(), forward=forward)
-
- def set_figheight(self, val, forward=True):
- """
- Set the height of the figure in inches.
-
- ACCEPTS: float
- """
- self.set_size_inches(self.get_figwidth(), val, forward=forward)
-
- def set_frameon(self, b):
- """
- Set whether the figure frame (background) is displayed or invisible
-
- ACCEPTS: boolean
- """
- self.frameon = b
- self.stale = True
-
- def delaxes(self, ax):
- """
- Remove the `~matplotlib.axes.Axes` *ax* from the figure and update the
- current axes.
- """
- self._axstack.remove(ax)
- for func in self._axobservers:
- func(self)
- self.stale = True
-
- def _make_key(self, *args, **kwargs):
- """Make a hashable key out of args and kwargs."""
-
- def fixitems(items):
- # items may have arrays and lists in them, so convert them
- # to tuples for the key
- ret = []
- for k, v in items:
- # some objects can define __getitem__ without being
- # iterable and in those cases the conversion to tuples
- # will fail. So instead of using the iterable(v) function
- # we simply try and convert to a tuple, and proceed if not.
- try:
- v = tuple(v)
- except Exception:
- pass
- ret.append((k, v))
- return tuple(ret)
-
- def fixlist(args):
- ret = []
- for a in args:
- if iterable(a):
- a = tuple(a)
- ret.append(a)
- return tuple(ret)
-
- key = fixlist(args), fixitems(six.iteritems(kwargs))
- return key
-
- def add_axes(self, *args, **kwargs):
- """
- Add an axes to the figure.
-
- Call signature::
-
- add_axes(rect, projection=None, polar=False, **kwargs)
-
- Parameters
- ----------
- rect : sequence of float
- The dimensions [left, bottom, width, height] of the new axes. All
- quantities are in fractions of figure width and height.
-
- projection : {None, 'aitoff', 'hammer', 'lambert', 'mollweide', \
-'polar', rectilinear'}, optional
- The projection type of the axes.
-
- polar : boolean, optional
- If True, equivalent to projection='polar'.
-
- **kwargs
- This method also takes the keyword arguments for
- :class:`~matplotlib.axes.Axes`.
-
- Returns
- -------
- axes : Axes
- The added axes.
-
- Examples
- --------
- Some simple examples::
-
- rect = l, b, w, h
- fig.add_axes(rect)
- fig.add_axes(rect, frameon=False, facecolor='g')
- fig.add_axes(rect, polar=True)
- fig.add_axes(rect, projection='polar')
- fig.add_axes(ax)
-
- If the figure already has an axes with the same parameters, then it
- will simply make that axes current and return it. This behavior
- has been deprecated as of Matplotlib 2.1. Meanwhile, if you do
- not want this behavior (i.e., you want to force the creation of a
- new Axes), you must use a unique set of args and kwargs. The axes
- :attr:`~matplotlib.axes.Axes.label` attribute has been exposed for this
- purpose: if you want two axes that are otherwise identical to be added
- to the figure, make sure you give them unique labels::
-
- fig.add_axes(rect, label='axes1')
- fig.add_axes(rect, label='axes2')
-
- In rare circumstances, add_axes may be called with a single
- argument, an Axes instance already created in the present
- figure but not in the figure's list of axes. For example,
- if an axes has been removed with :meth:`delaxes`, it can
- be restored with::
-
- fig.add_axes(ax)
-
- In all cases, the :class:`~matplotlib.axes.Axes` instance
- will be returned.
- """
- if not len(args):
- return
-
- # shortcut the projection "key" modifications later on, if an axes
- # with the exact args/kwargs exists, return it immediately.
- key = self._make_key(*args, **kwargs)
- ax = self._axstack.get(key)
- if ax is not None:
- self.sca(ax)
- return ax
-
- if isinstance(args[0], Axes):
- a = args[0]
- if a.get_figure() is not self:
- raise ValueError(
- "The Axes must have been created in the present figure")
- else:
- rect = args[0]
- if not np.isfinite(rect).all():
- raise ValueError('all entries in rect must be finite '
- 'not {}'.format(rect))
- projection_class, kwargs, key = process_projection_requirements(
- self, *args, **kwargs)
-
- # check that an axes of this type doesn't already exist, if it
- # does, set it as active and return it
- ax = self._axstack.get(key)
- if isinstance(ax, projection_class):
- self.sca(ax)
- return ax
-
- # create the new axes using the axes class given
- a = projection_class(self, rect, **kwargs)
-
- self._axstack.add(key, a)
- self.sca(a)
- a._remove_method = self.__remove_ax
- self.stale = True
- a.stale_callback = _stale_figure_callback
- return a
-
- def add_subplot(self, *args, **kwargs):
- """
- Add a subplot.
-
- Call signatures::
-
- add_subplot(nrows, ncols, index, **kwargs)
- add_subplot(pos, **kwargs)
-
- Parameters
- ----------
- *args
- Either a 3-digit integer or three separate integers
- describing the position of the subplot. If the three
- integers are R, C, and P in order, the subplot will take
- the Pth position on a grid with R rows and C columns.
-
- projection : {None, 'aitoff', 'hammer', 'lambert', 'mollweide', \
-'polar', rectilinear'}, optional
- The projection type of the axes.
-
- polar : boolean, optional
- If True, equivalent to projection='polar'.
-
- **kwargs
- This method also takes the keyword arguments for
- :class:`~matplotlib.axes.Axes`.
-
- Returns
- -------
- axes : Axes
- The axes of the subplot.
-
- Notes
- -----
- If the figure already has a subplot with key (*args*,
- *kwargs*) then it will simply make that subplot current and
- return it. This behavior is deprecated.
-
- Examples
- --------
- ::
-
- fig.add_subplot(111)
-
- # equivalent but more general
- fig.add_subplot(1, 1, 1)
-
- # add subplot with red background
- fig.add_subplot(212, facecolor='r')
-
- # add a polar subplot
- fig.add_subplot(111, projection='polar')
-
- # add Subplot instance sub
- fig.add_subplot(sub)
-
- See Also
- --------
- matplotlib.pyplot.subplot : for an explanation of the args.
- """
- if not len(args):
- return
-
- if len(args) == 1 and isinstance(args[0], int):
- if not 100 <= args[0] <= 999:
- raise ValueError("Integer subplot specification must be a "
- "three-digit number, not {}".format(args[0]))
- args = tuple(map(int, str(args[0])))
-
- if isinstance(args[0], SubplotBase):
-
- a = args[0]
- if a.get_figure() is not self:
- raise ValueError(
- "The Subplot must have been created in the present figure")
- # make a key for the subplot (which includes the axes object id
- # in the hash)
- key = self._make_key(*args, **kwargs)
- else:
- projection_class, kwargs, key = process_projection_requirements(
- self, *args, **kwargs)
-
- # try to find the axes with this key in the stack
- ax = self._axstack.get(key)
-
- if ax is not None:
- if isinstance(ax, projection_class):
- # the axes already existed, so set it as active & return
- self.sca(ax)
- return ax
- else:
- # Undocumented convenience behavior:
- # subplot(111); subplot(111, projection='polar')
- # will replace the first with the second.
- # Without this, add_subplot would be simpler and
- # more similar to add_axes.
- self._axstack.remove(ax)
-
- a = subplot_class_factory(projection_class)(self, *args, **kwargs)
- self._axstack.add(key, a)
- self.sca(a)
- a._remove_method = self.__remove_ax
- self.stale = True
- a.stale_callback = _stale_figure_callback
- return a
-
- def subplots(self, nrows=1, ncols=1, sharex=False, sharey=False,
- squeeze=True, subplot_kw=None, gridspec_kw=None):
- """
- Add a set of subplots to this figure.
-
- Parameters
- ----------
- nrows, ncols : int, default: 1
- Number of rows/cols of the subplot grid.
-
- sharex, sharey : bool or {'none', 'all', 'row', 'col'}, default: False
- Controls sharing of properties among x (`sharex`) or y (`sharey`)
- axes:
-
- - True or 'all': x- or y-axis will be shared among all
- subplots.
- - False or 'none': each subplot x- or y-axis will be
- independent.
- - 'row': each subplot row will share an x- or y-axis.
- - 'col': each subplot column will share an x- or y-axis.
-
- When subplots have a shared x-axis along a column, only the x tick
- labels of the bottom subplot are created. Similarly, when subplots
- have a shared y-axis along a row, only the y tick labels of the
- first column subplot are created. To later turn other subplots'
- ticklabels on, use :meth:`~matplotlib.axes.Axes.tick_params`.
-
- squeeze : bool, optional, default: True
- - If True, extra dimensions are squeezed out from the returned
- array of Axes:
-
- - if only one subplot is constructed (nrows=ncols=1), the
- resulting single Axes object is returned as a scalar.
- - for Nx1 or 1xM subplots, the returned object is a 1D numpy
- object array of Axes objects.
- - for NxM, subplots with N>1 and M>1 are returned
- as a 2D array.
-
- - If False, no squeezing at all is done: the returned Axes object
- is always a 2D array containing Axes instances, even if it ends
- up being 1x1.
-
- subplot_kw : dict, default: {}
- Dict with keywords passed to the
- :meth:`~matplotlib.figure.Figure.add_subplot` call used to create
- each subplots.
-
- gridspec_kw : dict, default: {}
- Dict with keywords passed to the
- :class:`~matplotlib.gridspec.GridSpec` constructor used to create
- the grid the subplots are placed on.
-
- Returns
- -------
- ax : single Axes object or array of Axes objects
- The added axes. The dimensions of the resulting array can be
- controlled with the squeeze keyword, see above.
-
- See Also
- --------
- pyplot.subplots : pyplot API; docstring includes examples.
- """
-
- # for backwards compatibility
- if isinstance(sharex, bool):
- sharex = "all" if sharex else "none"
- if isinstance(sharey, bool):
- sharey = "all" if sharey else "none"
- share_values = ["all", "row", "col", "none"]
- if sharex not in share_values:
- # This check was added because it is very easy to type
- # `subplots(1, 2, 1)` when `subplot(1, 2, 1)` was intended.
- # In most cases, no error will ever occur, but mysterious behavior
- # will result because what was intended to be the subplot index is
- # instead treated as a bool for sharex.
- if isinstance(sharex, int):
- warnings.warn(
- "sharex argument to subplots() was an integer. "
- "Did you intend to use subplot() (without 's')?")
-
- raise ValueError("sharex [%s] must be one of %s" %
- (sharex, share_values))
- if sharey not in share_values:
- raise ValueError("sharey [%s] must be one of %s" %
- (sharey, share_values))
- if subplot_kw is None:
- subplot_kw = {}
- if gridspec_kw is None:
- gridspec_kw = {}
-
- if self.get_constrained_layout():
- gs = GridSpec(nrows, ncols, figure=self, **gridspec_kw)
- else:
- # this should turn constrained_layout off if we don't want it
- gs = GridSpec(nrows, ncols, figure=None, **gridspec_kw)
-
- # Create array to hold all axes.
- axarr = np.empty((nrows, ncols), dtype=object)
- for row in range(nrows):
- for col in range(ncols):
- shared_with = {"none": None, "all": axarr[0, 0],
- "row": axarr[row, 0], "col": axarr[0, col]}
- subplot_kw["sharex"] = shared_with[sharex]
- subplot_kw["sharey"] = shared_with[sharey]
- axarr[row, col] = self.add_subplot(gs[row, col], **subplot_kw)
-
- # turn off redundant tick labeling
- if sharex in ["col", "all"]:
- # turn off all but the bottom row
- for ax in axarr[:-1, :].flat:
- ax.xaxis.set_tick_params(which='both',
- labelbottom=False, labeltop=False)
- ax.xaxis.offsetText.set_visible(False)
- if sharey in ["row", "all"]:
- # turn off all but the first column
- for ax in axarr[:, 1:].flat:
- ax.yaxis.set_tick_params(which='both',
- labelleft=False, labelright=False)
- ax.yaxis.offsetText.set_visible(False)
-
- if squeeze:
- # Discarding unneeded dimensions that equal 1. If we only have one
- # subplot, just return it instead of a 1-element array.
- return axarr.item() if axarr.size == 1 else axarr.squeeze()
- else:
- # Returned axis array will be always 2-d, even if nrows=ncols=1.
- return axarr
-
- def __remove_ax(self, ax):
- def _reset_loc_form(axis):
- axis.set_major_formatter(axis.get_major_formatter())
- axis.set_major_locator(axis.get_major_locator())
- axis.set_minor_formatter(axis.get_minor_formatter())
- axis.set_minor_locator(axis.get_minor_locator())
-
- def _break_share_link(ax, grouper):
- siblings = grouper.get_siblings(ax)
- if len(siblings) > 1:
- grouper.remove(ax)
- for last_ax in siblings:
- if ax is last_ax:
- continue
- return last_ax
- return None
-
- self.delaxes(ax)
- last_ax = _break_share_link(ax, ax._shared_y_axes)
- if last_ax is not None:
- _reset_loc_form(last_ax.yaxis)
-
- last_ax = _break_share_link(ax, ax._shared_x_axes)
- if last_ax is not None:
- _reset_loc_form(last_ax.xaxis)
-
- def clf(self, keep_observers=False):
- """
- Clear the figure.
-
- Set *keep_observers* to True if, for example,
- a gui widget is tracking the axes in the figure.
- """
- self.suppressComposite = None
- self.callbacks = cbook.CallbackRegistry()
-
- for ax in tuple(self.axes): # Iterate over the copy.
- ax.cla()
- self.delaxes(ax) # removes ax from self._axstack
-
- toolbar = getattr(self.canvas, 'toolbar', None)
- if toolbar is not None:
- toolbar.update()
- self._axstack.clear()
- self.artists = []
- self.lines = []
- self.patches = []
- self.texts = []
- self.images = []
- self.legends = []
- if not keep_observers:
- self._axobservers = []
- self._suptitle = None
- if self.get_constrained_layout():
- layoutbox.nonetree(self._layoutbox)
- self.stale = True
-
- def clear(self, keep_observers=False):
- """
- Clear the figure -- synonym for :meth:`clf`.
- """
- self.clf(keep_observers=keep_observers)
-
- @allow_rasterization
- def draw(self, renderer):
- """
- Render the figure using :class:`matplotlib.backend_bases.RendererBase`
- instance *renderer*.
- """
-
- # draw the figure bounding box, perhaps none for white figure
- if not self.get_visible():
- return
-
- artists = sorted(
- (artist for artist in (self.patches + self.lines + self.artists
- + self.images + self.axes + self.texts
- + self.legends)
- if not artist.get_animated()),
- key=lambda artist: artist.get_zorder())
-
- try:
- renderer.open_group('figure')
- if self.get_constrained_layout() and self.axes:
- if True:
- self.execute_constrained_layout(renderer)
- else:
- pass
- if self.get_tight_layout() and self.axes:
- try:
- self.tight_layout(renderer,
- **self._tight_parameters)
- except ValueError:
- pass
- # ValueError can occur when resizing a window.
-
- if self.frameon:
- self.patch.draw(renderer)
-
- mimage._draw_list_compositing_images(
- renderer, self, artists, self.suppressComposite)
-
- renderer.close_group('figure')
- finally:
- self.stale = False
-
- self._cachedRenderer = renderer
- self.canvas.draw_event(renderer)
-
- def draw_artist(self, a):
- """
- Draw :class:`matplotlib.artist.Artist` instance *a* only.
- This is available only after the figure is drawn.
- """
- if self._cachedRenderer is None:
- raise AttributeError("draw_artist can only be used after an "
- "initial draw which caches the renderer")
- a.draw(self._cachedRenderer)
-
- def get_axes(self):
- """
- Return a list of axes in the Figure. You can access and modify the
- axes in the Figure through this list.
-
- Do not modify the list itself. Instead, use `~Figure.add_axes`,
- `~.Figure.subplot` or `~.Figure.delaxes` to add or remove an axes.
-
- Note: This is equivalent to the property `~.Figure.axes`.
- """
- return self.axes
-
- @docstring.dedent_interpd
- def legend(self, *args, **kwargs):
- """
- Place a legend on the figure.
-
- To make a legend from existing artists on every axes::
-
- legend()
-
- To make a legend for a list of lines and labels::
-
- legend( (line1, line2, line3),
- ('label1', 'label2', 'label3'),
- loc='upper right')
-
- These can also be specified by keyword::
-
- legend(handles=(line1, line2, line3),
- labels=('label1', 'label2', 'label3'),
- loc='upper right')
-
- Parameters
- ----------
-
- handles : sequence of `.Artist`, optional
- A list of Artists (lines, patches) to be added to the legend.
- Use this together with *labels*, if you need full control on what
- is shown in the legend and the automatic mechanism described above
- is not sufficient.
-
- The length of handles and labels should be the same in this
- case. If they are not, they are truncated to the smaller length.
-
- labels : sequence of strings, optional
- A list of labels to show next to the artists.
- Use this together with *handles*, if you need full control on what
- is shown in the legend and the automatic mechanism described above
- is not sufficient.
-
- Other Parameters
- ----------------
-
- loc : int or string or pair of floats, default: 'upper right'
- The location of the legend. Possible codes are:
-
- =============== =============
- Location String Location Code
- =============== =============
- 'best' 0
- 'upper right' 1
- 'upper left' 2
- 'lower left' 3
- 'lower right' 4
- 'right' 5
- 'center left' 6
- 'center right' 7
- 'lower center' 8
- 'upper center' 9
- 'center' 10
- =============== =============
-
-
- Alternatively can be a 2-tuple giving ``x, y`` of the lower-left
- corner of the legend in axes coordinates (in which case
- ``bbox_to_anchor`` will be ignored).
-
- bbox_to_anchor : `.BboxBase` or pair of floats
- Specify any arbitrary location for the legend in `bbox_transform`
- coordinates (default Axes coordinates).
-
- For example, to put the legend's upper right hand corner in the
- center of the axes the following keywords can be used::
-
- loc='upper right', bbox_to_anchor=(0.5, 0.5)
-
- ncol : integer
- The number of columns that the legend has. Default is 1.
-
- prop : None or :class:`matplotlib.font_manager.FontProperties` or dict
- The font properties of the legend. If None (default), the current
- :data:`matplotlib.rcParams` will be used.
-
- fontsize : int or float or {'xx-small', 'x-small', 'small', 'medium', \
-'large', 'x-large', 'xx-large'}
- Controls the font size of the legend. If the value is numeric the
- size will be the absolute font size in points. String values are
- relative to the current default font size. This argument is only
- used if `prop` is not specified.
-
- numpoints : None or int
- The number of marker points in the legend when creating a legend
- entry for a `.Line2D` (line).
- Default is ``None``, which will take the value from
- :rc:`legend.numpoints`.
-
- scatterpoints : None or int
- The number of marker points in the legend when creating
- a legend entry for a `.PathCollection` (scatter plot).
- Default is ``None``, which will take the value from
- :rc:`legend.scatterpoints`.
-
- scatteryoffsets : iterable of floats
- The vertical offset (relative to the font size) for the markers
- created for a scatter plot legend entry. 0.0 is at the base the
- legend text, and 1.0 is at the top. To draw all markers at the
- same height, set to ``[0.5]``. Default is ``[0.375, 0.5, 0.3125]``.
-
- markerscale : None or int or float
- The relative size of legend markers compared with the originally
- drawn ones.
- Default is ``None``, which will take the value from
- :rc:`legend.markerscale`.
-
- markerfirst : bool
- If *True*, legend marker is placed to the left of the legend label.
- If *False*, legend marker is placed to the right of the legend
- label.
- Default is *True*.
-
- frameon : None or bool
- Control whether the legend should be drawn on a patch
- (frame).
- Default is ``None``, which will take the value from
- :rc:`legend.frameon`.
-
- fancybox : None or bool
- Control whether round edges should be enabled around the
- :class:`~matplotlib.patches.FancyBboxPatch` which makes up the
- legend's background.
- Default is ``None``, which will take the value from
- :rc:`legend.fancybox`.
-
- shadow : None or bool
- Control whether to draw a shadow behind the legend.
- Default is ``None``, which will take the value from
- :rc:`legend.shadow`.
-
- framealpha : None or float
- Control the alpha transparency of the legend's background.
- Default is ``None``, which will take the value from
- :rc:`legend.framealpha`. If shadow is activated and
- *framealpha* is ``None``, the default value is ignored.
-
- facecolor : None or "inherit" or a color spec
- Control the legend's background color.
- Default is ``None``, which will take the value from
- :rc:`legend.facecolor`. If ``"inherit"``, it will take
- :rc:`axes.facecolor`.
-
- edgecolor : None or "inherit" or a color spec
- Control the legend's background patch edge color.
- Default is ``None``, which will take the value from
- :rc:`legend.edgecolor` If ``"inherit"``, it will take
- :rc:`axes.edgecolor`.
-
- mode : {"expand", None}
- If `mode` is set to ``"expand"`` the legend will be horizontally
- expanded to fill the axes area (or `bbox_to_anchor` if defines
- the legend's size).
-
- bbox_transform : None or :class:`matplotlib.transforms.Transform`
- The transform for the bounding box (`bbox_to_anchor`). For a value
- of ``None`` (default) the Axes'
- :data:`~matplotlib.axes.Axes.transAxes` transform will be used.
-
- title : str or None
- The legend's title. Default is no title (``None``).
-
- borderpad : float or None
- The fractional whitespace inside the legend border.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.borderpad`.
-
- labelspacing : float or None
- The vertical space between the legend entries.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.labelspacing`.
-
- handlelength : float or None
- The length of the legend handles.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.handlelength`.
-
- handletextpad : float or None
- The pad between the legend handle and text.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.handletextpad`.
-
- borderaxespad : float or None
- The pad between the axes and legend border.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.borderaxespad`.
-
- columnspacing : float or None
- The spacing between columns.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.columnspacing`.
-
- handler_map : dict or None
- The custom dictionary mapping instances or types to a legend
- handler. This `handler_map` updates the default handler map
- found at :func:`matplotlib.legend.Legend.get_legend_handler_map`.
-
- Returns
- -------
- :class:`matplotlib.legend.Legend` instance
-
- Notes
- -----
- Not all kinds of artist are supported by the legend command. See
- :doc:`/tutorials/intermediate/legend_guide` for details.
- """
-
- handles, labels, extra_args, kwargs = mlegend._parse_legend_args(
- self.axes,
- *args,
- **kwargs)
- # check for third arg
- if len(extra_args):
- # cbook.warn_deprecated(
- # "2.1",
- # "Figure.legend will accept no more than two "
- # "positional arguments in the future. Use "
- # "'fig.legend(handles, labels, loc=location)' "
- # "instead.")
- # kwargs['loc'] = extra_args[0]
- # extra_args = extra_args[1:]
- pass
- l = mlegend.Legend(self, handles, labels, *extra_args, **kwargs)
- self.legends.append(l)
- l._remove_method = lambda h: self.legends.remove(h)
- self.stale = True
- return l
-
- @docstring.dedent_interpd
- def text(self, x, y, s, *args, **kwargs):
- """
- Add text to figure.
-
- Call signature::
-
- text(x, y, s, fontdict=None, **kwargs)
-
- Add text to figure at location *x*, *y* (relative 0-1
- coords). See :func:`~matplotlib.pyplot.text` for the meaning
- of the other arguments.
-
- kwargs control the :class:`~matplotlib.text.Text` properties:
-
- %(Text)s
- """
-
- override = _process_text_args({}, *args, **kwargs)
- t = Text(x=x, y=y, text=s)
-
- t.update(override)
- self._set_artist_props(t)
- self.texts.append(t)
- t._remove_method = lambda h: self.texts.remove(h)
- self.stale = True
- return t
-
- def _set_artist_props(self, a):
- if a != self:
- a.set_figure(self)
- a.stale_callback = _stale_figure_callback
- a.set_transform(self.transFigure)
-
- @docstring.dedent_interpd
- def gca(self, **kwargs):
- """
- Get the current axes, creating one if necessary.
-
- The following kwargs are supported for ensuring the returned axes
- adheres to the given projection etc., and for axes creation if
- the active axes does not exist:
-
- %(Axes)s
-
- """
- ckey, cax = self._axstack.current_key_axes()
- # if there exists an axes on the stack see if it maches
- # the desired axes configuration
- if cax is not None:
-
- # if no kwargs are given just return the current axes
- # this is a convenience for gca() on axes such as polar etc.
- if not kwargs:
- return cax
-
- # if the user has specified particular projection detail
- # then build up a key which can represent this
- else:
- # we don't want to modify the original kwargs
- # so take a copy so that we can do what we like to it
- kwargs_copy = kwargs.copy()
- projection_class, _, key = process_projection_requirements(
- self, **kwargs_copy)
-
- # let the returned axes have any gridspec by removing it from
- # the key
- ckey = ckey[1:]
- key = key[1:]
-
- # if the cax matches this key then return the axes, otherwise
- # continue and a new axes will be created
- if key == ckey and isinstance(cax, projection_class):
- return cax
- else:
- warnings.warn('Requested projection is different from '
- 'current axis projection, creating new axis '
- 'with requested projection.', stacklevel=2)
-
- # no axes found, so create one which spans the figure
- return self.add_subplot(1, 1, 1, **kwargs)
-
- def sca(self, a):
- """Set the current axes to be a and return a."""
- self._axstack.bubble(a)
- for func in self._axobservers:
- func(self)
- return a
-
- def _gci(self):
- """
- Helper for :func:`~matplotlib.pyplot.gci`. Do not use elsewhere.
- """
- # Look first for an image in the current Axes:
- cax = self._axstack.current_key_axes()[1]
- if cax is None:
- return None
- im = cax._gci()
- if im is not None:
- return im
-
- # If there is no image in the current Axes, search for
- # one in a previously created Axes. Whether this makes
- # sense is debatable, but it is the documented behavior.
- for ax in reversed(self.axes):
- im = ax._gci()
- if im is not None:
- return im
- return None
-
- def __getstate__(self):
- state = super(Figure, self).__getstate__()
-
- # print('\n\n\nStarting pickle')
- # the axobservers cannot currently be pickled.
- # Additionally, the canvas cannot currently be pickled, but this has
- # the benefit of meaning that a figure can be detached from one canvas,
- # and re-attached to another.
- for attr_to_pop in ('_axobservers', 'show',
- 'canvas', '_cachedRenderer'):
- state.pop(attr_to_pop, None)
-
- # add version information to the state
- state['__mpl_version__'] = _mpl_version
-
- # check to see if the figure has a manager and whether it is registered
- # with pyplot
- if getattr(self.canvas, 'manager', None) is not None:
- manager = self.canvas.manager
- import matplotlib._pylab_helpers
- if manager in list(six.itervalues(
- matplotlib._pylab_helpers.Gcf.figs)):
- state['_restore_to_pylab'] = True
-
- # set all the layoutbox information to None. kiwisolver
- # objects can't be pickeled, so we lose the layout options
- # at this point.
- state.pop('_layoutbox', None)
- # suptitle:
- if self._suptitle is not None:
- self._suptitle._layoutbox = None
-
- return state
-
- def __setstate__(self, state):
- version = state.pop('__mpl_version__')
- restore_to_pylab = state.pop('_restore_to_pylab', False)
-
- if version != _mpl_version:
- import warnings
- warnings.warn("This figure was saved with matplotlib version %s "
- "and is unlikely to function correctly." %
- (version, ))
-
- self.__dict__ = state
-
- # re-initialise some of the unstored state information
- self._axobservers = []
- self.canvas = None
- self._layoutbox = None
-
- if restore_to_pylab:
- # lazy import to avoid circularity
- import matplotlib.pyplot as plt
- import matplotlib._pylab_helpers as pylab_helpers
- allnums = plt.get_fignums()
- num = max(allnums) + 1 if allnums else 1
- mgr = plt._backend_mod.new_figure_manager_given_figure(num, self)
-
- # XXX The following is a copy and paste from pyplot. Consider
- # factoring to pylab_helpers
-
- if self.get_label():
- mgr.set_window_title(self.get_label())
-
- # make this figure current on button press event
- def make_active(event):
- pylab_helpers.Gcf.set_active(mgr)
-
- mgr._cidgcf = mgr.canvas.mpl_connect('button_press_event',
- make_active)
-
- pylab_helpers.Gcf.set_active(mgr)
- self.number = num
-
- plt.draw_if_interactive()
- self.stale = True
-
- def add_axobserver(self, func):
- """Whenever the axes state change, ``func(self)`` will be called."""
- self._axobservers.append(func)
-
- def savefig(self, fname, **kwargs):
- """
- Save the current figure.
-
- Call signature::
-
- savefig(fname, dpi=None, facecolor='w', edgecolor='w',
- orientation='portrait', papertype=None, format=None,
- transparent=False, bbox_inches=None, pad_inches=0.1,
- frameon=None)
-
- The output formats available depend on the backend being used.
-
- Parameters
- ----------
-
- fname : str or file-like object
- A string containing a path to a filename, or a Python
- file-like object, or possibly some backend-dependent object
- such as :class:`~matplotlib.backends.backend_pdf.PdfPages`.
-
- If *format* is *None* and *fname* is a string, the output
- format is deduced from the extension of the filename. If
- the filename has no extension, the value of the rc parameter
- ``savefig.format`` is used.
-
- If *fname* is not a string, remember to specify *format* to
- ensure that the correct backend is used.
-
- Other Parameters
- ----------------
-
- dpi : [ *None* | scalar > 0 | 'figure']
- The resolution in dots per inch. If *None* it will default to
- the value ``savefig.dpi`` in the matplotlibrc file. If 'figure'
- it will set the dpi to be the value of the figure.
-
- facecolor : color spec or None, optional
- the facecolor of the figure; if None, defaults to savefig.facecolor
-
- edgecolor : color spec or None, optional
- the edgecolor of the figure; if None, defaults to savefig.edgecolor
-
- orientation : {'landscape', 'portrait'}
- not supported on all backends; currently only on postscript output
-
- papertype : str
- One of 'letter', 'legal', 'executive', 'ledger', 'a0' through
- 'a10', 'b0' through 'b10'. Only supported for postscript
- output.
-
- format : str
- One of the file extensions supported by the active
- backend. Most backends support png, pdf, ps, eps and svg.
-
- transparent : bool
- If *True*, the axes patches will all be transparent; the
- figure patch will also be transparent unless facecolor
- and/or edgecolor are specified via kwargs.
- This is useful, for example, for displaying
- a plot on top of a colored background on a web page. The
- transparency of these patches will be restored to their
- original values upon exit of this function.
-
- frameon : bool
- If *True*, the figure patch will be colored, if *False*, the
- figure background will be transparent. If not provided, the
- rcParam 'savefig.frameon' will be used.
-
- bbox_inches : str or `~matplotlib.transforms.Bbox`, optional
- Bbox in inches. Only the given portion of the figure is
- saved. If 'tight', try to figure out the tight bbox of
- the figure. If None, use savefig.bbox
-
- pad_inches : scalar, optional
- Amount of padding around the figure when bbox_inches is
- 'tight'. If None, use savefig.pad_inches
-
- bbox_extra_artists : list of `~matplotlib.artist.Artist`, optional
- A list of extra artists that will be considered when the
- tight bbox is calculated.
-
- """
- kwargs.setdefault('dpi', rcParams['savefig.dpi'])
- frameon = kwargs.pop('frameon', rcParams['savefig.frameon'])
- transparent = kwargs.pop('transparent',
- rcParams['savefig.transparent'])
-
- if transparent:
- kwargs.setdefault('facecolor', 'none')
- kwargs.setdefault('edgecolor', 'none')
- original_axes_colors = []
- for ax in self.axes:
- patch = ax.patch
- original_axes_colors.append((patch.get_facecolor(),
- patch.get_edgecolor()))
- patch.set_facecolor('none')
- patch.set_edgecolor('none')
- else:
- kwargs.setdefault('facecolor', rcParams['savefig.facecolor'])
- kwargs.setdefault('edgecolor', rcParams['savefig.edgecolor'])
-
- if frameon:
- original_frameon = self.get_frameon()
- self.set_frameon(frameon)
-
- self.canvas.print_figure(fname, **kwargs)
-
- if frameon:
- self.set_frameon(original_frameon)
-
- if transparent:
- for ax, cc in zip(self.axes, original_axes_colors):
- ax.patch.set_facecolor(cc[0])
- ax.patch.set_edgecolor(cc[1])
-
- @docstring.dedent_interpd
- def colorbar(self, mappable, cax=None, ax=None, use_gridspec=True, **kw):
- """
- Create a colorbar for a ScalarMappable instance, *mappable*.
-
- Documentation for the pylab thin wrapper:
- %(colorbar_doc)s
- """
- if ax is None:
- ax = self.gca()
-
- # Store the value of gca so that we can set it back later on.
- current_ax = self.gca()
-
- if cax is None:
- if use_gridspec and isinstance(ax, SubplotBase) \
- and (not self.get_constrained_layout()):
- cax, kw = cbar.make_axes_gridspec(ax, **kw)
- else:
- cax, kw = cbar.make_axes(ax, **kw)
- cax._hold = True
-
- # need to remove kws that cannot be passed to Colorbar
- NON_COLORBAR_KEYS = ['fraction', 'pad', 'shrink', 'aspect', 'anchor',
- 'panchor']
- cb_kw = {k: v for k, v in kw.items() if k not in NON_COLORBAR_KEYS}
- cb = cbar.colorbar_factory(cax, mappable, **cb_kw)
-
- self.sca(current_ax)
- self.stale = True
- return cb
-
- def subplots_adjust(self, *args, **kwargs):
- """
- Call signature::
-
- subplots_adjust(left=None, bottom=None, right=None, top=None,
- wspace=None, hspace=None)
-
- Update the :class:`SubplotParams` with *kwargs* (defaulting to rc when
- *None*) and update the subplot locations.
-
- """
- if self.get_constrained_layout():
- self.set_constrained_layout(False)
- warnings.warn("This figure was using constrained_layout==True, "
- "but that is incompatible with subplots_adjust and "
- "or tight_layout: setting "
- "constrained_layout==False. ")
- self.subplotpars.update(*args, **kwargs)
-
- for ax in self.axes:
- if not isinstance(ax, SubplotBase):
- # Check if sharing a subplots axis
- if isinstance(ax._sharex, SubplotBase):
- ax._sharex.update_params()
- ax.set_position(ax._sharex.figbox)
- elif isinstance(ax._sharey, SubplotBase):
- ax._sharey.update_params()
- ax.set_position(ax._sharey.figbox)
- else:
- ax.update_params()
- ax.set_position(ax.figbox)
- self.stale = True
-
- def ginput(self, n=1, timeout=30, show_clicks=True, mouse_add=1,
- mouse_pop=3, mouse_stop=2):
- """
- Blocking call to interact with a figure.
-
- Wait until the user clicks *n* times on the figure, and return the
- coordinates of each click in a list.
-
- The buttons used for the various actions (adding points, removing
- points, terminating the inputs) can be overridden via the
- arguments *mouse_add*, *mouse_pop* and *mouse_stop*, that give
- the associated mouse button: 1 for left, 2 for middle, 3 for
- right.
-
- Parameters
- ----------
- n : int, optional, default: 1
- Number of mouse clicks to accumulate. If negative, accumulate
- clicks until the input is terminated manually.
- timeout : scalar, optional, default: 30
- Number of seconds to wait before timing out. If zero or negative
- will never timeout.
- show_clicks : bool, optional, default: False
- If True, show a red cross at the location of each click.
- mouse_add : int, one of (1, 2, 3), optional, default: 1 (left click)
- Mouse button used to add points.
- mouse_pop : int, one of (1, 2, 3), optional, default: 3 (right click)
- Mouse button used to remove the most recently added point.
- mouse_stop : int, one of (1, 2, 3), optional, default: 2 (middle click)
- Mouse button used to stop input.
-
- Returns
- -------
- points : list of tuples
- A list of the clicked (x, y) coordinates.
-
- Notes
- -----
- The keyboard can also be used to select points in case your mouse
- does not have one or more of the buttons. The delete and backspace
- keys act like right clicking (i.e., remove last point), the enter key
- terminates input and any other key (not already used by the window
- manager) selects a point.
- """
-
- blocking_mouse_input = BlockingMouseInput(self,
- mouse_add=mouse_add,
- mouse_pop=mouse_pop,
- mouse_stop=mouse_stop)
- return blocking_mouse_input(n=n, timeout=timeout,
- show_clicks=show_clicks)
-
- def waitforbuttonpress(self, timeout=-1):
- """
- Blocking call to interact with the figure.
-
- This will return True is a key was pressed, False if a mouse
- button was pressed and None if *timeout* was reached without
- either being pressed.
-
- If *timeout* is negative, does not timeout.
- """
-
- blocking_input = BlockingKeyMouseInput(self)
- return blocking_input(timeout=timeout)
-
- def get_default_bbox_extra_artists(self):
- bbox_artists = [artist for artist in self.get_children()
- if artist.get_visible()]
- for ax in self.axes:
- if ax.get_visible():
- bbox_artists.extend(ax.get_default_bbox_extra_artists())
- # we don't want the figure's patch to influence the bbox calculation
- bbox_artists.remove(self.patch)
- return bbox_artists
-
- def get_tightbbox(self, renderer):
- """
- Return a (tight) bounding box of the figure in inches.
-
- It only accounts axes title, axis labels, and axis
- ticklabels. Needs improvement.
- """
-
- bb = []
- for ax in self.axes:
- if ax.get_visible():
- bb.append(ax.get_tightbbox(renderer))
-
- if len(bb) == 0:
- return self.bbox_inches
-
- _bbox = Bbox.union([b for b in bb if b.width != 0 or b.height != 0])
-
- bbox_inches = TransformedBbox(_bbox,
- Affine2D().scale(1. / self.dpi))
-
- return bbox_inches
-
- def init_layoutbox(self):
- """Initialize the layoutbox for use in constrained_layout."""
- if self._layoutbox is None:
- self._layoutbox = layoutbox.LayoutBox(parent=None,
- name='figlb',
- artist=self)
- self._layoutbox.constrain_geometry(0., 0., 1., 1.)
-
- def execute_constrained_layout(self, renderer=None):
- """
- Use ``layoutbox`` to determine pos positions within axes.
-
- See also `.set_constrained_layout_pads`.
- """
-
- from matplotlib._constrained_layout import (do_constrained_layout)
-
- _log.debug('Executing constrainedlayout')
- if self._layoutbox is None:
- warnings.warn("Calling figure.constrained_layout, but figure "
- "not setup to do constrained layout. "
- " You either called GridSpec without the "
- "fig keyword, you are using plt.subplot, "
- "or you need to call figure or subplots"
- "with the constrained_layout=True kwarg.")
- return
- w_pad, h_pad, wspace, hspace = self.get_constrained_layout_pads()
- # convert to unit-relative lengths
-
- fig = self
- width, height = fig.get_size_inches()
- w_pad = w_pad / width
- h_pad = h_pad / height
- if renderer is None:
- renderer = layoutbox.get_renderer(fig)
- do_constrained_layout(fig, renderer, h_pad, w_pad, hspace, wspace)
-
- def tight_layout(self, renderer=None, pad=1.08, h_pad=None, w_pad=None,
- rect=None):
- """
- Adjust subplot parameters to give specified padding.
-
- Parameters
- ----------
- pad : float
- padding between the figure edge and the edges of subplots,
- as a fraction of the font-size.
-
- h_pad, w_pad : float, optional
- padding (height/width) between edges of adjacent subplots.
- Defaults to `pad_inches`.
-
- rect : tuple (left, bottom, right, top), optional
- a rectangle (left, bottom, right, top) in the normalized
- figure coordinate that the whole subplots area (including
- labels) will fit into. Default is (0, 0, 1, 1).
- """
-
- from .tight_layout import (
- get_renderer, get_subplotspec_list, get_tight_layout_figure)
-
- subplotspec_list = get_subplotspec_list(self.axes)
- if None in subplotspec_list:
- warnings.warn("This figure includes Axes that are not compatible "
- "with tight_layout, so results might be incorrect.")
-
- if renderer is None:
- renderer = get_renderer(self)
-
- kwargs = get_tight_layout_figure(
- self, self.axes, subplotspec_list, renderer,
- pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
- self.subplots_adjust(**kwargs)
-
- def align_xlabels(self, axs=None):
- """
- Align the ylabels of subplots in the same subplot column if label
- alignment is being done automatically (i.e. the label position is
- not manually set).
-
- Alignment persists for draw events after this is called.
-
- If a label is on the bottom, it is aligned with labels on axes that
- also have their label on the bottom and that have the same
- bottom-most subplot row. If the label is on the top,
- it is aligned with labels on axes with the same top-most row.
-
- Parameters
- ----------
- axs : list of `~matplotlib.axes.Axes`
- Optional list of (or ndarray) `~matplotlib.axes.Axes`
- to align the xlabels.
- Default is to align all axes on the figure.
-
- See Also
- --------
- matplotlib.figure.Figure.align_ylabels
-
- matplotlib.figure.Figure.align_labels
-
- Notes
- -----
- This assumes that ``axs`` are from the same `.GridSpec`, so that
- their `.SubplotSpec` positions correspond to figure positions.
-
- Examples
- --------
- Example with rotated xtick labels::
-
- fig, axs = plt.subplots(1, 2)
- for tick in axs[0].get_xticklabels():
- tick.set_rotation(55)
- axs[0].set_xlabel('XLabel 0')
- axs[1].set_xlabel('XLabel 1')
- fig.align_xlabels()
-
- """
-
- if axs is None:
- axs = self.axes
- axs = np.asarray(axs).ravel()
- for ax in axs:
- _log.debug(' Working on: %s', ax.get_xlabel())
- ss = ax.get_subplotspec()
- nrows, ncols, row0, row1, col0, col1 = ss.get_rows_columns()
- labpo = ax.xaxis.get_label_position() # top or bottom
-
- # loop through other axes, and search for label positions
- # that are same as this one, and that share the appropriate
- # row number.
- # Add to a grouper associated with each axes of sibblings.
- # This list is inspected in `axis.draw` by
- # `axis._update_label_position`.
- for axc in axs:
- if axc.xaxis.get_label_position() == labpo:
- ss = axc.get_subplotspec()
- nrows, ncols, rowc0, rowc1, colc, col1 = \
- ss.get_rows_columns()
- if (labpo == 'bottom' and rowc1 == row1 or
- labpo == 'top' and rowc0 == row0):
- # grouper for groups of xlabels to align
- self._align_xlabel_grp.join(ax, axc)
-
- def align_ylabels(self, axs=None):
- """
- Align the ylabels of subplots in the same subplot column if label
- alignment is being done automatically (i.e. the label position is
- not manually set).
-
- Alignment persists for draw events after this is called.
-
- If a label is on the left, it is aligned with labels on axes that
- also have their label on the left and that have the same
- left-most subplot column. If the label is on the right,
- it is aligned with labels on axes with the same right-most column.
-
- Parameters
- ----------
- axs : list of `~matplotlib.axes.Axes`
- Optional list (or ndarray) of `~matplotlib.axes.Axes`
- to align the ylabels.
- Default is to align all axes on the figure.
-
- See Also
- --------
- matplotlib.figure.Figure.align_xlabels
-
- matplotlib.figure.Figure.align_labels
-
- Notes
- -----
- This assumes that ``axs`` are from the same `.GridSpec`, so that
- their `.SubplotSpec` positions correspond to figure positions.
-
- Examples
- --------
- Example with large yticks labels::
-
- fig, axs = plt.subplots(2, 1)
- axs[0].plot(np.arange(0, 1000, 50))
- axs[0].set_ylabel('YLabel 0')
- axs[1].set_ylabel('YLabel 1')
- fig.align_ylabels()
-
- """
-
- if axs is None:
- axs = self.axes
- axs = np.asarray(axs).ravel()
- for ax in axs:
- _log.debug(' Working on: %s', ax.get_ylabel())
- ss = ax.get_subplotspec()
- nrows, ncols, row0, row1, col0, col1 = ss.get_rows_columns()
- same = [ax]
- labpo = ax.yaxis.get_label_position() # left or right
- # loop through other axes, and search for label positions
- # that are same as this one, and that share the appropriate
- # column number.
- # Add to a list associated with each axes of sibblings.
- # This list is inspected in `axis.draw` by
- # `axis._update_label_position`.
- for axc in axs:
- if axc != ax:
- if axc.yaxis.get_label_position() == labpo:
- ss = axc.get_subplotspec()
- nrows, ncols, row0, row1, colc0, colc1 = \
- ss.get_rows_columns()
- if (labpo == 'left' and colc0 == col0 or
- labpo == 'right' and colc1 == col1):
- # grouper for groups of ylabels to align
- self._align_ylabel_grp.join(ax, axc)
-
- def align_labels(self, axs=None):
- """
- Align the xlabels and ylabels of subplots with the same subplots
- row or column (respectively) if label alignment is being
- done automatically (i.e. the label position is not manually set).
-
- Alignment persists for draw events after this is called.
-
- Parameters
- ----------
- axs : list of `~matplotlib.axes.Axes`
- Optional list (or ndarray) of `~matplotlib.axes.Axes`
- to align the labels.
- Default is to align all axes on the figure.
-
- See Also
- --------
- matplotlib.figure.Figure.align_xlabels
-
- matplotlib.figure.Figure.align_ylabels
- """
- self.align_xlabels(axs=axs)
- self.align_ylabels(axs=axs)
-
-
-def figaspect(arg):
- """
- Create a figure with specified aspect ratio. If *arg* is a number,
- use that aspect ratio. If *arg* is an array, figaspect will
- determine the width and height for a figure that would fit array
- preserving aspect ratio. The figure width, height in inches are
- returned. Be sure to create an axes with equal with and height,
- e.g.,
-
- Example usage::
-
- # make a figure twice as tall as it is wide
- w, h = figaspect(2.)
- fig = Figure(figsize=(w,h))
- ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
- ax.imshow(A, **kwargs)
-
-
- # make a figure with the proper aspect for an array
- A = rand(5,3)
- w, h = figaspect(A)
- fig = Figure(figsize=(w,h))
- ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
- ax.imshow(A, **kwargs)
-
- Thanks to Fernando Perez for this function
- """
-
- isarray = hasattr(arg, 'shape') and not np.isscalar(arg)
-
- # min/max sizes to respect when autoscaling. If John likes the idea, they
- # could become rc parameters, for now they're hardwired.
- figsize_min = np.array((4.0, 2.0)) # min length for width/height
- figsize_max = np.array((16.0, 16.0)) # max length for width/height
-
- # Extract the aspect ratio of the array
- if isarray:
- nr, nc = arg.shape[:2]
- arr_ratio = nr / nc
- else:
- arr_ratio = arg
-
- # Height of user figure defaults
- fig_height = rcParams['figure.figsize'][1]
-
- # New size for the figure, keeping the aspect ratio of the caller
- newsize = np.array((fig_height / arr_ratio, fig_height))
-
- # Sanity checks, don't drop either dimension below figsize_min
- newsize /= min(1.0, *(newsize / figsize_min))
-
- # Avoid humongous windows as well
- newsize /= max(1.0, *(newsize / figsize_max))
-
- # Finally, if we have a really funky aspect ratio, break it but respect
- # the min/max dimensions (we don't want figures 10 feet tall!)
- newsize = np.clip(newsize, figsize_min, figsize_max)
- return newsize
-
-docstring.interpd.update(Figure=martist.kwdoc(Figure))
diff --git a/contrib/python/matplotlib/py2/matplotlib/font_manager.py b/contrib/python/matplotlib/py2/matplotlib/font_manager.py
deleted file mode 100644
index 2ba1a50638..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/font_manager.py
+++ /dev/null
@@ -1,1481 +0,0 @@
-"""
-A module for finding, managing, and using fonts across platforms.
-
-This module provides a single :class:`FontManager` instance that can
-be shared across backends and platforms. The :func:`findfont`
-function returns the best TrueType (TTF) font file in the local or
-system font path that matches the specified :class:`FontProperties`
-instance. The :class:`FontManager` also handles Adobe Font Metrics
-(AFM) font files for use by the PostScript backend.
-
-The design is based on the `W3C Cascading Style Sheet, Level 1 (CSS1)
-font specification <http://www.w3.org/TR/1998/REC-CSS2-19980512/>`_.
-Future versions may implement the Level 2 or 2.1 specifications.
-
-Experimental support is included for using `fontconfig` on Unix
-variant platforms (Linux, OS X, Solaris). To enable it, set the
-constant ``USE_FONTCONFIG`` in this file to ``True``. Fontconfig has
-the advantage that it is the standard way to look up fonts on X11
-platforms, so if a font is installed, it is much more likely to be
-found.
-"""
-from __future__ import absolute_import, division, print_function
-
-import six
-
-"""
-KNOWN ISSUES
-
- - documentation
- - font variant is untested
- - font stretch is incomplete
- - font size is incomplete
- - default font algorithm needs improvement and testing
- - setWeights function needs improvement
- - 'light' is an invalid weight value, remove it.
- - update_fonts not implemented
-
-Authors : John Hunter <jdhunter@ace.bsd.uchicago.edu>
- Paul Barrett <Barrett@STScI.Edu>
- Michael Droettboom <mdroe@STScI.edu>
-Copyright : John Hunter (2004,2005), Paul Barrett (2004,2005)
-License : matplotlib license (PSF compatible)
- The font directory code is from ttfquery,
- see license/LICENSE_TTFQUERY.
-"""
-try:
- from collections.abc import Iterable
-except ImportError:
- from collections import Iterable
-import json
-import os
-import sys
-try:
- from threading import Timer
-except ImportError:
- from dummy_threading import Timer
-import warnings
-import logging
-
-from matplotlib import afm, cbook, ft2font, rcParams, get_cachedir
-from matplotlib.compat import subprocess
-from matplotlib.fontconfig_pattern import (
- parse_fontconfig_pattern, generate_fontconfig_pattern)
-
-try:
- from functools import lru_cache
-except ImportError:
- from backports.functools_lru_cache import lru_cache
-
-_log = logging.getLogger(__name__)
-
-USE_FONTCONFIG = False
-
-font_scalings = {
- 'xx-small' : 0.579,
- 'x-small' : 0.694,
- 'small' : 0.833,
- 'medium' : 1.0,
- 'large' : 1.200,
- 'x-large' : 1.440,
- 'xx-large' : 1.728,
- 'larger' : 1.2,
- 'smaller' : 0.833,
- None : 1.0}
-
-stretch_dict = {
- 'ultra-condensed' : 100,
- 'extra-condensed' : 200,
- 'condensed' : 300,
- 'semi-condensed' : 400,
- 'normal' : 500,
- 'semi-expanded' : 600,
- 'expanded' : 700,
- 'extra-expanded' : 800,
- 'ultra-expanded' : 900}
-
-weight_dict = {
- 'ultralight' : 100,
- 'light' : 200,
- 'normal' : 400,
- 'regular' : 400,
- 'book' : 400,
- 'medium' : 500,
- 'roman' : 500,
- 'semibold' : 600,
- 'demibold' : 600,
- 'demi' : 600,
- 'bold' : 700,
- 'heavy' : 800,
- 'extra bold' : 800,
- 'black' : 900}
-
-font_family_aliases = {
- 'serif',
- 'sans-serif',
- 'sans serif',
- 'cursive',
- 'fantasy',
- 'monospace',
- 'sans'}
-
-# OS Font paths
-MSFolders = \
- r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
-
-
-MSFontDirectories = [
- r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts',
- r'SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts']
-
-
-X11FontDirectories = [
- # an old standard installation point
- "/usr/X11R6/lib/X11/fonts/TTF/",
- "/usr/X11/lib/X11/fonts",
- # here is the new standard location for fonts
- "/usr/share/fonts/",
- # documented as a good place to install new fonts
- "/usr/local/share/fonts/",
- # common application, not really useful
- "/usr/lib/openoffice/share/fonts/truetype/",
- ]
-
-OSXFontDirectories = [
- "/Library/Fonts/",
- "/Network/Library/Fonts/",
- "/System/Library/Fonts/",
- # fonts installed via MacPorts
- "/opt/local/share/fonts"
- ""
-]
-
-if not USE_FONTCONFIG and sys.platform != 'win32':
- home = os.environ.get('HOME')
- if home is not None:
- # user fonts on OSX
- path = os.path.join(home, 'Library', 'Fonts')
- OSXFontDirectories.append(path)
- path = os.path.join(home, '.fonts')
- X11FontDirectories.append(path)
-
-
-def get_fontext_synonyms(fontext):
- """
- Return a list of file extensions extensions that are synonyms for
- the given file extension *fileext*.
- """
- return {'ttf': ('ttf', 'otf'),
- 'otf': ('ttf', 'otf'),
- 'afm': ('afm',)}[fontext]
-
-
-def list_fonts(directory, extensions):
- """
- Return a list of all fonts matching any of the extensions,
- possibly upper-cased, found recursively under the directory.
- """
- pattern = ';'.join(['*.%s;*.%s' % (ext, ext.upper())
- for ext in extensions])
- return cbook.listFiles(directory, pattern)
-
-
-def win32FontDirectory():
- """
- Return the user-specified font directory for Win32. This is
- looked up from the registry key::
-
- \\\\HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders\\Fonts
-
- If the key is not found, $WINDIR/Fonts will be returned.
- """
- try:
- from six.moves import winreg
- except ImportError:
- pass # Fall through to default
- else:
- try:
- user = winreg.OpenKey(winreg.HKEY_CURRENT_USER, MSFolders)
- try:
- try:
- return winreg.QueryValueEx(user, 'Fonts')[0]
- except OSError:
- pass # Fall through to default
- finally:
- winreg.CloseKey(user)
- except OSError:
- pass # Fall through to default
- return os.path.join(os.environ['WINDIR'], 'Fonts')
-
-
-def win32InstalledFonts(directory=None, fontext='ttf'):
- """
- Search for fonts in the specified font directory, or use the
- system directories if none given. A list of TrueType font
- filenames are returned by default, or AFM fonts if *fontext* ==
- 'afm'.
- """
-
- from six.moves import winreg
- if directory is None:
- directory = win32FontDirectory()
-
- fontext = get_fontext_synonyms(fontext)
-
- key, items = None, set()
- for fontdir in MSFontDirectories:
- try:
- local = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, fontdir)
- except OSError:
- continue
- if not local:
- return list_fonts(directory, fontext)
- try:
- for j in range(winreg.QueryInfoKey(local)[1]):
- try:
- key, direc, tp = winreg.EnumValue(local, j)
- if not isinstance(direc, six.string_types):
- continue
- # Work around for https://bugs.python.org/issue25778, which
- # is fixed in Py>=3.6.1.
- direc = direc.split("\0", 1)[0]
- if not os.path.dirname(direc):
- direc = os.path.join(directory, direc)
- direc = os.path.abspath(direc).lower()
- if os.path.splitext(direc)[1][1:] in fontext:
- items.add(direc)
- except EnvironmentError:
- continue
- except WindowsError:
- continue
- except MemoryError:
- continue
- return list(items)
- finally:
- winreg.CloseKey(local)
- return None
-
-
-def OSXInstalledFonts(directories=None, fontext='ttf'):
- """
- Get list of font files on OS X - ignores font suffix by default.
- """
- if directories is None:
- directories = OSXFontDirectories
-
- fontext = get_fontext_synonyms(fontext)
-
- files = []
- for path in directories:
- if fontext is None:
- files.extend(cbook.listFiles(path, '*'))
- else:
- files.extend(list_fonts(path, fontext))
- return files
-
-
-@lru_cache()
-def _call_fc_list():
- """Cache and list the font filenames known to `fc-list`.
- """
- # Delay the warning by 5s.
- timer = Timer(5, lambda: warnings.warn(
- 'Matplotlib is building the font cache using fc-list. '
- 'This may take a moment.'))
- timer.start()
- try:
- out = subprocess.check_output([str('fc-list'), '--format=%{file}\\n'])
- except (OSError, subprocess.CalledProcessError):
- return []
- finally:
- timer.cancel()
- fnames = []
- for fname in out.split(b'\n'):
- try:
- fname = six.text_type(fname, sys.getfilesystemencoding())
- except UnicodeDecodeError:
- continue
- fnames.append(fname)
- return fnames
-
-
-def get_fontconfig_fonts(fontext='ttf'):
- """List the font filenames known to `fc-list` having the given extension.
- """
- fontext = get_fontext_synonyms(fontext)
- return [fname for fname in _call_fc_list()
- if os.path.splitext(fname)[1][1:] in fontext]
-
-
-def findSystemFonts(fontpaths=None, fontext='ttf'):
- """
- Search for fonts in the specified font paths. If no paths are
- given, will use a standard set of system paths, as well as the
- list of fonts tracked by fontconfig if fontconfig is installed and
- available. A list of TrueType fonts are returned by default with
- AFM fonts as an option.
- """
- fontfiles = set()
- fontexts = get_fontext_synonyms(fontext)
-
- if fontpaths is None:
- if sys.platform == 'win32':
- fontdir = win32FontDirectory()
-
- fontpaths = [fontdir]
- # now get all installed fonts directly...
- for f in win32InstalledFonts(fontdir):
- base, ext = os.path.splitext(f)
- if len(ext)>1 and ext[1:].lower() in fontexts:
- fontfiles.add(f)
- else:
- fontpaths = X11FontDirectories
- # check for OS X & load its fonts if present
- if sys.platform == 'darwin':
- for f in OSXInstalledFonts(fontext=fontext):
- fontfiles.add(f)
-
- for f in get_fontconfig_fonts(fontext):
- fontfiles.add(f)
-
- elif isinstance(fontpaths, six.string_types):
- fontpaths = [fontpaths]
-
- for path in fontpaths:
- files = list_fonts(path, fontexts)
- for fname in files:
- fontfiles.add(os.path.abspath(fname))
-
- return [fname for fname in fontfiles if os.path.exists(fname)]
-
-
-@cbook.deprecated("2.1")
-def weight_as_number(weight):
- """
- Return the weight property as a numeric value. String values
- are converted to their corresponding numeric value.
- """
- if isinstance(weight, six.string_types):
- try:
- weight = weight_dict[weight.lower()]
- except KeyError:
- weight = 400
- elif weight in range(100, 1000, 100):
- pass
- else:
- raise ValueError('weight not a valid integer')
- return weight
-
-
-class FontEntry(object):
- """
- A class for storing Font properties. It is used when populating
- the font lookup dictionary.
- """
- def __init__(self,
- fname ='',
- name ='',
- style ='normal',
- variant='normal',
- weight ='normal',
- stretch='normal',
- size ='medium',
- ):
- self.fname = fname
- self.name = name
- self.style = style
- self.variant = variant
- self.weight = weight
- self.stretch = stretch
- try:
- self.size = str(float(size))
- except ValueError:
- self.size = size
-
- def __repr__(self):
- return "<Font '%s' (%s) %s %s %s %s>" % (
- self.name, os.path.basename(self.fname), self.style, self.variant,
- self.weight, self.stretch)
-
-
-def ttfFontProperty(font):
- """
- Extract information from a TrueType font file.
-
- Parameters
- ----------
- font : `.FT2Font`
- The TrueType font file from which information will be extracted.
-
- Returns
- -------
- `FontEntry`
- The extracted font properties.
-
- """
- name = font.family_name
-
- # Styles are: italic, oblique, and normal (default)
-
- sfnt = font.get_sfnt()
- sfnt2 = sfnt.get((1,0,0,2))
- sfnt4 = sfnt.get((1,0,0,4))
- if sfnt2:
- sfnt2 = sfnt2.decode('mac_roman').lower()
- else:
- sfnt2 = ''
- if sfnt4:
- sfnt4 = sfnt4.decode('mac_roman').lower()
- else:
- sfnt4 = ''
- if sfnt4.find('oblique') >= 0:
- style = 'oblique'
- elif sfnt4.find('italic') >= 0:
- style = 'italic'
- elif sfnt2.find('regular') >= 0:
- style = 'normal'
- elif font.style_flags & ft2font.ITALIC:
- style = 'italic'
- else:
- style = 'normal'
-
- # Variants are: small-caps and normal (default)
-
- # !!!! Untested
- if name.lower() in ['capitals', 'small-caps']:
- variant = 'small-caps'
- else:
- variant = 'normal'
-
- weight = next((w for w in weight_dict if sfnt4.find(w) >= 0), None)
- if not weight:
- if font.style_flags & ft2font.BOLD:
- weight = 700
- else:
- weight = 400
-
- # Stretch can be absolute and relative
- # Absolute stretches are: ultra-condensed, extra-condensed, condensed,
- # semi-condensed, normal, semi-expanded, expanded, extra-expanded,
- # and ultra-expanded.
- # Relative stretches are: wider, narrower
- # Child value is: inherit
-
- if (sfnt4.find('narrow') >= 0 or sfnt4.find('condensed') >= 0 or
- sfnt4.find('cond') >= 0):
- stretch = 'condensed'
- elif sfnt4.find('demi cond') >= 0:
- stretch = 'semi-condensed'
- elif sfnt4.find('wide') >= 0 or sfnt4.find('expanded') >= 0:
- stretch = 'expanded'
- else:
- stretch = 'normal'
-
- # Sizes can be absolute and relative.
- # Absolute sizes are: xx-small, x-small, small, medium, large, x-large,
- # and xx-large.
- # Relative sizes are: larger, smaller
- # Length value is an absolute font size, e.g., 12pt
- # Percentage values are in 'em's. Most robust specification.
-
- if not font.scalable:
- raise NotImplementedError("Non-scalable fonts are not supported")
- size = 'scalable'
-
- return FontEntry(font.fname, name, style, variant, weight, stretch, size)
-
-
-def afmFontProperty(fontpath, font):
- """
- Extract information from an AFM font file.
-
- Parameters
- ----------
- font : `.AFM`
- The AFM font file from which information will be extracted.
-
- Returns
- -------
- `FontEntry`
- The extracted font properties.
-
- """
-
- name = font.get_familyname()
- fontname = font.get_fontname().lower()
-
- # Styles are: italic, oblique, and normal (default)
-
- if font.get_angle() != 0 or name.lower().find('italic') >= 0:
- style = 'italic'
- elif name.lower().find('oblique') >= 0:
- style = 'oblique'
- else:
- style = 'normal'
-
- # Variants are: small-caps and normal (default)
-
- # !!!! Untested
- if name.lower() in ['capitals', 'small-caps']:
- variant = 'small-caps'
- else:
- variant = 'normal'
-
- weight = font.get_weight().lower()
-
- # Stretch can be absolute and relative
- # Absolute stretches are: ultra-condensed, extra-condensed, condensed,
- # semi-condensed, normal, semi-expanded, expanded, extra-expanded,
- # and ultra-expanded.
- # Relative stretches are: wider, narrower
- # Child value is: inherit
- if fontname.find('narrow') >= 0 or fontname.find('condensed') >= 0 or \
- fontname.find('cond') >= 0:
- stretch = 'condensed'
- elif fontname.find('demi cond') >= 0:
- stretch = 'semi-condensed'
- elif fontname.find('wide') >= 0 or fontname.find('expanded') >= 0:
- stretch = 'expanded'
- else:
- stretch = 'normal'
-
- # Sizes can be absolute and relative.
- # Absolute sizes are: xx-small, x-small, small, medium, large, x-large,
- # and xx-large.
- # Relative sizes are: larger, smaller
- # Length value is an absolute font size, e.g., 12pt
- # Percentage values are in 'em's. Most robust specification.
-
- # All AFM fonts are apparently scalable.
-
- size = 'scalable'
-
- return FontEntry(fontpath, name, style, variant, weight, stretch, size)
-
-
-def createFontList(fontfiles, fontext='ttf'):
- """
- A function to create a font lookup list. The default is to create
- a list of TrueType fonts. An AFM font list can optionally be
- created.
- """
-
- fontlist = []
- # Add fonts from list of known font files.
- seen = set()
- for fpath in fontfiles:
- _log.debug('createFontDict: %s', fpath)
- fname = os.path.split(fpath)[1]
- if fname in seen:
- continue
- else:
- seen.add(fname)
- if fontext == 'afm':
- try:
- fh = open(fpath, 'rb')
- except EnvironmentError:
- _log.info("Could not open font file %s", fpath)
- continue
- try:
- font = afm.AFM(fh)
- except RuntimeError:
- _log.info("Could not parse font file %s", fpath)
- continue
- finally:
- fh.close()
- try:
- prop = afmFontProperty(fpath, font)
- except KeyError:
- continue
- else:
- try:
- font = ft2font.FT2Font(fpath)
- except RuntimeError:
- _log.info("Could not open font file %s", fpath)
- continue
- except UnicodeError:
- _log.info("Cannot handle unicode filenames")
- continue
- except IOError:
- _log.info("IO error - cannot open font file %s", fpath)
- continue
- try:
- prop = ttfFontProperty(font)
- except (KeyError, RuntimeError, ValueError, NotImplementedError):
- continue
-
- fontlist.append(prop)
- return fontlist
-
-
-class FontProperties(object):
- """
- A class for storing and manipulating font properties.
-
- The font properties are those described in the `W3C Cascading
- Style Sheet, Level 1
- <http://www.w3.org/TR/1998/REC-CSS2-19980512/>`_ font
- specification. The six properties are:
-
- - family: A list of font names in decreasing order of priority.
- The items may include a generic font family name, either
- 'serif', 'sans-serif', 'cursive', 'fantasy', or 'monospace'.
- In that case, the actual font to be used will be looked up
- from the associated rcParam in :file:`matplotlibrc`.
-
- - style: Either 'normal', 'italic' or 'oblique'.
-
- - variant: Either 'normal' or 'small-caps'.
-
- - stretch: A numeric value in the range 0-1000 or one of
- 'ultra-condensed', 'extra-condensed', 'condensed',
- 'semi-condensed', 'normal', 'semi-expanded', 'expanded',
- 'extra-expanded' or 'ultra-expanded'
-
- - weight: A numeric value in the range 0-1000 or one of
- 'ultralight', 'light', 'normal', 'regular', 'book', 'medium',
- 'roman', 'semibold', 'demibold', 'demi', 'bold', 'heavy',
- 'extra bold', 'black'
-
- - size: Either an relative value of 'xx-small', 'x-small',
- 'small', 'medium', 'large', 'x-large', 'xx-large' or an
- absolute font size, e.g., 12
-
- The default font property for TrueType fonts (as specified in the
- default :file:`matplotlibrc` file) is::
-
- sans-serif, normal, normal, normal, normal, scalable.
-
- Alternatively, a font may be specified using an absolute path to a
- .ttf file, by using the *fname* kwarg.
-
- The preferred usage of font sizes is to use the relative values,
- e.g., 'large', instead of absolute font sizes, e.g., 12. This
- approach allows all text sizes to be made larger or smaller based
- on the font manager's default font size.
-
- This class will also accept a `fontconfig
- <https://www.freedesktop.org/wiki/Software/fontconfig/>`_ pattern, if it is
- the only argument provided. See the documentation on `fontconfig patterns
- <https://www.freedesktop.org/software/fontconfig/fontconfig-user.html>`_.
- This support does not require fontconfig to be installed. We are merely
- borrowing its pattern syntax for use here.
-
- Note that matplotlib's internal font manager and fontconfig use a
- different algorithm to lookup fonts, so the results of the same pattern
- may be different in matplotlib than in other applications that use
- fontconfig.
- """
-
- def __init__(self,
- family = None,
- style = None,
- variant= None,
- weight = None,
- stretch= None,
- size = None,
- fname = None, # if this is set, it's a hardcoded filename to use
- _init = None # used only by copy()
- ):
- self._family = _normalize_font_family(rcParams['font.family'])
- self._slant = rcParams['font.style']
- self._variant = rcParams['font.variant']
- self._weight = rcParams['font.weight']
- self._stretch = rcParams['font.stretch']
- self._size = rcParams['font.size']
- self._file = None
-
- # This is used only by copy()
- if _init is not None:
- self.__dict__.update(_init.__dict__)
- return
-
- if isinstance(family, six.string_types):
- # Treat family as a fontconfig pattern if it is the only
- # parameter provided.
- if (style is None and
- variant is None and
- weight is None and
- stretch is None and
- size is None and
- fname is None):
- self.set_fontconfig_pattern(family)
- return
-
- self.set_family(family)
- self.set_style(style)
- self.set_variant(variant)
- self.set_weight(weight)
- self.set_stretch(stretch)
- self.set_file(fname)
- self.set_size(size)
-
- def _parse_fontconfig_pattern(self, pattern):
- return parse_fontconfig_pattern(pattern)
-
- def __hash__(self):
- l = (tuple(self.get_family()),
- self.get_slant(),
- self.get_variant(),
- self.get_weight(),
- self.get_stretch(),
- self.get_size_in_points(),
- self.get_file())
- return hash(l)
-
- def __eq__(self, other):
- return hash(self) == hash(other)
-
- def __ne__(self, other):
- return hash(self) != hash(other)
-
- def __str__(self):
- return self.get_fontconfig_pattern()
-
- def get_family(self):
- """
- Return a list of font names that comprise the font family.
- """
- return self._family
-
- def get_name(self):
- """
- Return the name of the font that best matches the font
- properties.
- """
- return get_font(findfont(self)).family_name
-
- def get_style(self):
- """
- Return the font style. Values are: 'normal', 'italic' or
- 'oblique'.
- """
- return self._slant
- get_slant = get_style
-
- def get_variant(self):
- """
- Return the font variant. Values are: 'normal' or
- 'small-caps'.
- """
- return self._variant
-
- def get_weight(self):
- """
- Set the font weight. Options are: A numeric value in the
- range 0-1000 or one of 'light', 'normal', 'regular', 'book',
- 'medium', 'roman', 'semibold', 'demibold', 'demi', 'bold',
- 'heavy', 'extra bold', 'black'
- """
- return self._weight
-
- def get_stretch(self):
- """
- Return the font stretch or width. Options are: 'ultra-condensed',
- 'extra-condensed', 'condensed', 'semi-condensed', 'normal',
- 'semi-expanded', 'expanded', 'extra-expanded', 'ultra-expanded'.
- """
- return self._stretch
-
- def get_size(self):
- """
- Return the font size.
- """
- return self._size
-
- def get_size_in_points(self):
- return self._size
-
- def get_file(self):
- """
- Return the filename of the associated font.
- """
- return self._file
-
- def get_fontconfig_pattern(self):
- """
- Get a fontconfig pattern suitable for looking up the font as
- specified with fontconfig's ``fc-match`` utility.
-
- See the documentation on `fontconfig patterns
- <https://www.freedesktop.org/software/fontconfig/fontconfig-user.html>`_.
-
- This support does not require fontconfig to be installed or
- support for it to be enabled. We are merely borrowing its
- pattern syntax for use here.
- """
- return generate_fontconfig_pattern(self)
-
- def set_family(self, family):
- """
- Change the font family. May be either an alias (generic name
- is CSS parlance), such as: 'serif', 'sans-serif', 'cursive',
- 'fantasy', or 'monospace', a real font name or a list of real
- font names. Real font names are not supported when
- `text.usetex` is `True`.
- """
- if family is None:
- family = rcParams['font.family']
- self._family = _normalize_font_family(family)
- set_name = set_family
-
- def set_style(self, style):
- """
- Set the font style. Values are: 'normal', 'italic' or
- 'oblique'.
- """
- if style is None:
- style = rcParams['font.style']
- if style not in ('normal', 'italic', 'oblique'):
- raise ValueError("style must be normal, italic or oblique")
- self._slant = style
- set_slant = set_style
-
- def set_variant(self, variant):
- """
- Set the font variant. Values are: 'normal' or 'small-caps'.
- """
- if variant is None:
- variant = rcParams['font.variant']
- if variant not in ('normal', 'small-caps'):
- raise ValueError("variant must be normal or small-caps")
- self._variant = variant
-
- def set_weight(self, weight):
- """
- Set the font weight. May be either a numeric value in the
- range 0-1000 or one of 'ultralight', 'light', 'normal',
- 'regular', 'book', 'medium', 'roman', 'semibold', 'demibold',
- 'demi', 'bold', 'heavy', 'extra bold', 'black'
- """
- if weight is None:
- weight = rcParams['font.weight']
- try:
- weight = int(weight)
- if weight < 0 or weight > 1000:
- raise ValueError()
- except ValueError:
- if weight not in weight_dict:
- raise ValueError("weight is invalid")
- self._weight = weight
-
- def set_stretch(self, stretch):
- """
- Set the font stretch or width. Options are: 'ultra-condensed',
- 'extra-condensed', 'condensed', 'semi-condensed', 'normal',
- 'semi-expanded', 'expanded', 'extra-expanded' or
- 'ultra-expanded', or a numeric value in the range 0-1000.
- """
- if stretch is None:
- stretch = rcParams['font.stretch']
- try:
- stretch = int(stretch)
- if stretch < 0 or stretch > 1000:
- raise ValueError()
- except ValueError:
- if stretch not in stretch_dict:
- raise ValueError("stretch is invalid")
- self._stretch = stretch
-
- def set_size(self, size):
- """
- Set the font size. Either an relative value of 'xx-small',
- 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'
- or an absolute font size, e.g., 12.
- """
- if size is None:
- size = rcParams['font.size']
- try:
- size = float(size)
- except ValueError:
- try:
- scale = font_scalings[size]
- except KeyError:
- raise ValueError(
- "Size is invalid. Valid font size are "
- + ", ".join(map(str, font_scalings)))
- else:
- size = scale * FontManager.get_default_size()
- if size < 1.0:
- _log.info('Fontsize %1.2f < 1.0 pt not allowed by FreeType. '
- 'Setting fontsize = 1 pt', size)
- size = 1.0
- self._size = size
-
- def set_file(self, file):
- """
- Set the filename of the fontfile to use. In this case, all
- other properties will be ignored.
- """
- self._file = file
-
- def set_fontconfig_pattern(self, pattern):
- """
- Set the properties by parsing a fontconfig *pattern*.
-
- See the documentation on `fontconfig patterns
- <https://www.freedesktop.org/software/fontconfig/fontconfig-user.html>`_.
-
- This support does not require fontconfig to be installed or
- support for it to be enabled. We are merely borrowing its
- pattern syntax for use here.
- """
- for key, val in six.iteritems(self._parse_fontconfig_pattern(pattern)):
- if type(val) == list:
- getattr(self, "set_" + key)(val[0])
- else:
- getattr(self, "set_" + key)(val)
-
- def copy(self):
- """Return a deep copy of self"""
- return FontProperties(_init=self)
-
-
-@cbook.deprecated("2.1")
-def ttfdict_to_fnames(d):
- """
- flatten a ttfdict to all the filenames it contains
- """
- fnames = []
- for named in six.itervalues(d):
- for styled in six.itervalues(named):
- for variantd in six.itervalues(styled):
- for weightd in six.itervalues(variantd):
- for stretchd in six.itervalues(weightd):
- for fname in six.itervalues(stretchd):
- fnames.append(fname)
- return fnames
-
-
-class JSONEncoder(json.JSONEncoder):
- def default(self, o):
- if isinstance(o, FontManager):
- return dict(o.__dict__, _class='FontManager')
- elif isinstance(o, FontEntry):
- return dict(o.__dict__, _class='FontEntry')
- else:
- return super(JSONEncoder, self).default(o)
-
-
-def _json_decode(o):
- cls = o.pop('_class', None)
- if cls is None:
- return o
- elif cls == 'FontManager':
- r = FontManager.__new__(FontManager)
- r.__dict__.update(o)
- return r
- elif cls == 'FontEntry':
- r = FontEntry.__new__(FontEntry)
- r.__dict__.update(o)
- return r
- else:
- raise ValueError("don't know how to deserialize _class=%s" % cls)
-
-
-def json_dump(data, filename):
- """Dumps a data structure as JSON in the named file.
- Handles FontManager and its fields."""
-
- with open(filename, 'w') as fh:
- try:
- json.dump(data, fh, cls=JSONEncoder, indent=2)
- except IOError as e:
- warnings.warn('Could not save font_manager cache {}'.format(e))
-
-def json_load(filename):
- """Loads a data structure as JSON from the named file.
- Handles FontManager and its fields."""
-
- with open(filename, 'r') as fh:
- return json.load(fh, object_hook=_json_decode)
-
-
-def _normalize_font_family(family):
- if isinstance(family, six.string_types):
- family = [six.text_type(family)]
- elif isinstance(family, Iterable):
- family = [six.text_type(f) for f in family]
- return family
-
-
-class TempCache(object):
- """
- A class to store temporary caches that are (a) not saved to disk
- and (b) invalidated whenever certain font-related
- rcParams---namely the family lookup lists---are changed or the
- font cache is reloaded. This avoids the expensive linear search
- through all fonts every time a font is looked up.
- """
- # A list of rcparam names that, when changed, invalidated this
- # cache.
- invalidating_rcparams = (
- 'font.serif', 'font.sans-serif', 'font.cursive', 'font.fantasy',
- 'font.monospace')
-
- def __init__(self):
- self._lookup_cache = {}
- self._last_rcParams = self.make_rcparams_key()
-
- def make_rcparams_key(self):
- return [id(fontManager)] + [
- rcParams[param] for param in self.invalidating_rcparams]
-
- def get(self, prop):
- key = self.make_rcparams_key()
- if key != self._last_rcParams:
- self._lookup_cache = {}
- self._last_rcParams = key
- return self._lookup_cache.get(prop)
-
- def set(self, prop, value):
- key = self.make_rcparams_key()
- if key != self._last_rcParams:
- self._lookup_cache = {}
- self._last_rcParams = key
- self._lookup_cache[prop] = value
-
-
-class FontManager(object):
- """
- On import, the :class:`FontManager` singleton instance creates a
- list of TrueType fonts based on the font properties: name, style,
- variant, weight, stretch, and size. The :meth:`findfont` method
- does a nearest neighbor search to find the font that most closely
- matches the specification. If no good enough match is found, a
- default font is returned.
- """
- # Increment this version number whenever the font cache data
- # format or behavior has changed and requires a existing font
- # cache files to be rebuilt.
- __version__ = 201
-
- def __init__(self, size=None, weight='normal'):
- self._version = self.__version__
-
- self.__default_weight = weight
- self.default_size = size
-
- paths = [os.path.join(rcParams['datapath'], 'fonts', 'ttf'),
- os.path.join(rcParams['datapath'], 'fonts', 'afm'),
- os.path.join(rcParams['datapath'], 'fonts', 'pdfcorefonts')]
-
- # Create list of font paths
- for pathname in ['TTFPATH', 'AFMPATH']:
- if pathname in os.environ:
- ttfpath = os.environ[pathname]
- if ttfpath.find(';') >= 0: #win32 style
- paths.extend(ttfpath.split(';'))
- elif ttfpath.find(':') >= 0: # unix style
- paths.extend(ttfpath.split(':'))
- else:
- paths.append(ttfpath)
- _log.info('font search path %s', str(paths))
- # Load TrueType fonts and create font dictionary.
-
- self.ttffiles = findSystemFonts(paths) + findSystemFonts()
- self.defaultFamily = {
- 'ttf': 'DejaVu Sans',
- 'afm': 'Helvetica'}
- self.defaultFont = {}
-
- for fname in self.ttffiles:
- _log.debug('trying fontname %s', fname)
- if fname.lower().find('DejaVuSans.ttf')>=0:
- self.defaultFont['ttf'] = fname
- break
- else:
- # use anything
- self.defaultFont['ttf'] = self.ttffiles[0]
-
- self.ttflist = createFontList(self.ttffiles)
-
- self.afmfiles = (findSystemFonts(paths, fontext='afm')
- + findSystemFonts(fontext='afm'))
- self.afmlist = createFontList(self.afmfiles, fontext='afm')
- if len(self.afmfiles):
- self.defaultFont['afm'] = self.afmfiles[0]
- else:
- self.defaultFont['afm'] = None
-
- def get_default_weight(self):
- """
- Return the default font weight.
- """
- return self.__default_weight
-
- @staticmethod
- def get_default_size():
- """
- Return the default font size.
- """
- return rcParams['font.size']
-
- def set_default_weight(self, weight):
- """
- Set the default font weight. The initial value is 'normal'.
- """
- self.__default_weight = weight
-
- def update_fonts(self, filenames):
- """
- Update the font dictionary with new font files.
- Currently not implemented.
- """
- # !!!! Needs implementing
- raise NotImplementedError
-
- # Each of the scoring functions below should return a value between
- # 0.0 (perfect match) and 1.0 (terrible match)
- def score_family(self, families, family2):
- """
- Returns a match score between the list of font families in
- *families* and the font family name *family2*.
-
- An exact match at the head of the list returns 0.0.
-
- A match further down the list will return between 0 and 1.
-
- No match will return 1.0.
- """
- if not isinstance(families, (list, tuple)):
- families = [families]
- elif len(families) == 0:
- return 1.0
- family2 = family2.lower()
- step = 1 / len(families)
- for i, family1 in enumerate(families):
- family1 = family1.lower()
- if family1 in font_family_aliases:
- if family1 in ('sans', 'sans serif'):
- family1 = 'sans-serif'
- options = rcParams['font.' + family1]
- options = [x.lower() for x in options]
- if family2 in options:
- idx = options.index(family2)
- return (i + (idx / len(options))) * step
- elif family1 == family2:
- # The score should be weighted by where in the
- # list the font was found.
- return i * step
- return 1.0
-
- def score_style(self, style1, style2):
- """
- Returns a match score between *style1* and *style2*.
-
- An exact match returns 0.0.
-
- A match between 'italic' and 'oblique' returns 0.1.
-
- No match returns 1.0.
- """
- if style1 == style2:
- return 0.0
- elif style1 in ('italic', 'oblique') and \
- style2 in ('italic', 'oblique'):
- return 0.1
- return 1.0
-
- def score_variant(self, variant1, variant2):
- """
- Returns a match score between *variant1* and *variant2*.
-
- An exact match returns 0.0, otherwise 1.0.
- """
- if variant1 == variant2:
- return 0.0
- else:
- return 1.0
-
- def score_stretch(self, stretch1, stretch2):
- """
- Returns a match score between *stretch1* and *stretch2*.
-
- The result is the absolute value of the difference between the
- CSS numeric values of *stretch1* and *stretch2*, normalized
- between 0.0 and 1.0.
- """
- try:
- stretchval1 = int(stretch1)
- except ValueError:
- stretchval1 = stretch_dict.get(stretch1, 500)
- try:
- stretchval2 = int(stretch2)
- except ValueError:
- stretchval2 = stretch_dict.get(stretch2, 500)
- return abs(stretchval1 - stretchval2) / 1000.0
-
- def score_weight(self, weight1, weight2):
- """
- Returns a match score between *weight1* and *weight2*.
-
- The result is 0.0 if both weight1 and weight 2 are given as strings
- and have the same value.
-
- Otherwise, the result is the absolute value of the difference between the
- CSS numeric values of *weight1* and *weight2*, normalized
- between 0.05 and 1.0.
- """
-
- # exact match of the weight names (e.g. weight1 == weight2 == "regular")
- if (isinstance(weight1, six.string_types) and
- isinstance(weight2, six.string_types) and
- weight1 == weight2):
- return 0.0
- try:
- weightval1 = int(weight1)
- except ValueError:
- weightval1 = weight_dict.get(weight1, 500)
- try:
- weightval2 = int(weight2)
- except ValueError:
- weightval2 = weight_dict.get(weight2, 500)
- return 0.95*(abs(weightval1 - weightval2) / 1000.0) + 0.05
-
- def score_size(self, size1, size2):
- """
- Returns a match score between *size1* and *size2*.
-
- If *size2* (the size specified in the font file) is 'scalable', this
- function always returns 0.0, since any font size can be generated.
-
- Otherwise, the result is the absolute distance between *size1* and
- *size2*, normalized so that the usual range of font sizes (6pt -
- 72pt) will lie between 0.0 and 1.0.
- """
- if size2 == 'scalable':
- return 0.0
- # Size value should have already been
- try:
- sizeval1 = float(size1)
- except ValueError:
- sizeval1 = self.default_size * font_scalings[size1]
- try:
- sizeval2 = float(size2)
- except ValueError:
- return 1.0
- return abs(sizeval1 - sizeval2) / 72.0
-
- def findfont(self, prop, fontext='ttf', directory=None,
- fallback_to_default=True, rebuild_if_missing=True):
- """
- Search the font list for the font that most closely matches
- the :class:`FontProperties` *prop*.
-
- :meth:`findfont` performs a nearest neighbor search. Each
- font is given a similarity score to the target font
- properties. The first font with the highest score is
- returned. If no matches below a certain threshold are found,
- the default font (usually DejaVu Sans) is returned.
-
- `directory`, is specified, will only return fonts from the
- given directory (or subdirectory of that directory).
-
- The result is cached, so subsequent lookups don't have to
- perform the O(n) nearest neighbor search.
-
- If `fallback_to_default` is True, will fallback to the default
- font family (usually "DejaVu Sans" or "Helvetica") if
- the first lookup hard-fails.
-
- See the `W3C Cascading Style Sheet, Level 1
- <http://www.w3.org/TR/1998/REC-CSS2-19980512/>`_ documentation
- for a description of the font finding algorithm.
- """
- if not isinstance(prop, FontProperties):
- prop = FontProperties(prop)
- fname = prop.get_file()
-
- if fname is not None:
- _log.debug('findfont returning %s', fname)
- return fname
-
- if fontext == 'afm':
- fontlist = self.afmlist
- else:
- fontlist = self.ttflist
-
- if directory is None:
- cached = _lookup_cache[fontext].get(prop)
- if cached is not None:
- return cached
- else:
- directory = os.path.normcase(directory)
-
- best_score = 1e64
- best_font = None
-
- for font in fontlist:
- if (directory is not None and
- os.path.commonprefix([os.path.normcase(font.fname),
- directory]) != directory):
- continue
- # Matching family should have highest priority, so it is multiplied
- # by 10.0
- score = \
- self.score_family(prop.get_family(), font.name) * 10.0 + \
- self.score_style(prop.get_style(), font.style) + \
- self.score_variant(prop.get_variant(), font.variant) + \
- self.score_weight(prop.get_weight(), font.weight) + \
- self.score_stretch(prop.get_stretch(), font.stretch) + \
- self.score_size(prop.get_size(), font.size)
- if score < best_score:
- best_score = score
- best_font = font
- if score == 0:
- break
-
- if best_font is None or best_score >= 10.0:
- if fallback_to_default:
- warnings.warn(
- 'findfont: Font family %s not found. Falling back to %s' %
- (prop.get_family(), self.defaultFamily[fontext]))
- default_prop = prop.copy()
- default_prop.set_family(self.defaultFamily[fontext])
- return self.findfont(default_prop, fontext, directory, False)
- else:
- # This is a hard fail -- we can't find anything reasonable,
- # so just return the DejuVuSans.ttf
- warnings.warn(
- 'findfont: Could not match %s. Returning %s' %
- (prop, self.defaultFont[fontext]),
- UserWarning)
- result = self.defaultFont[fontext]
- else:
- _log.debug(
- 'findfont: Matching %s to %s (%s) with score of %f' %
- (prop, best_font.name, repr(best_font.fname), best_score))
- result = best_font.fname
-
- if not os.path.isfile(result):
- if rebuild_if_missing:
- _log.info(
- 'findfont: Found a missing font file. Rebuilding cache.')
- _rebuild()
- return fontManager.findfont(
- prop, fontext, directory, True, False)
- else:
- raise ValueError("No valid font could be found")
-
- if directory is None:
- _lookup_cache[fontext].set(prop, result)
- return result
-
-_is_opentype_cff_font_cache = {}
-def is_opentype_cff_font(filename):
- """
- Returns True if the given font is a Postscript Compact Font Format
- Font embedded in an OpenType wrapper. Used by the PostScript and
- PDF backends that can not subset these fonts.
- """
- if os.path.splitext(filename)[1].lower() == '.otf':
- result = _is_opentype_cff_font_cache.get(filename)
- if result is None:
- with open(filename, 'rb') as fd:
- tag = fd.read(4)
- result = (tag == b'OTTO')
- _is_opentype_cff_font_cache[filename] = result
- return result
- return False
-
-fontManager = None
-_fmcache = None
-
-
-_get_font = lru_cache(64)(ft2font.FT2Font)
-
-def get_font(filename, hinting_factor=None):
- if hinting_factor is None:
- hinting_factor = rcParams['text.hinting_factor']
- return _get_font(filename, hinting_factor)
-
-
-# The experimental fontconfig-based backend.
-if USE_FONTCONFIG and sys.platform != 'win32':
-
- def fc_match(pattern, fontext):
- fontexts = get_fontext_synonyms(fontext)
- ext = "." + fontext
- try:
- pipe = subprocess.Popen(
- ['fc-match', '-s', '--format=%{file}\\n', pattern],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- output = pipe.communicate()[0]
- except (OSError, IOError):
- return None
-
- # The bulk of the output from fc-list is ascii, so we keep the
- # result in bytes and parse it as bytes, until we extract the
- # filename, which is in sys.filesystemencoding().
- if pipe.returncode == 0:
- for fname in output.split(b'\n'):
- try:
- fname = six.text_type(fname, sys.getfilesystemencoding())
- except UnicodeDecodeError:
- continue
- if os.path.splitext(fname)[1][1:] in fontexts:
- return fname
- return None
-
- _fc_match_cache = {}
-
- def findfont(prop, fontext='ttf'):
- if not isinstance(prop, six.string_types):
- prop = prop.get_fontconfig_pattern()
- cached = _fc_match_cache.get(prop)
- if cached is not None:
- return cached
-
- result = fc_match(prop, fontext)
- if result is None:
- result = fc_match(':', fontext)
-
- _fc_match_cache[prop] = result
- return result
-
-else:
- _fmcache = None
-
- cachedir = get_cachedir()
- if cachedir is not None:
- _fmcache = os.path.join(cachedir, 'fontList.json')
-
- fontManager = None
-
- _lookup_cache = {
- 'ttf': TempCache(),
- 'afm': TempCache()
- }
-
- def _rebuild():
- global fontManager
-
- fontManager = FontManager()
-
- if _fmcache:
- with cbook.Locked(cachedir):
- json_dump(fontManager, _fmcache)
- _log.info("generated new fontManager")
-
- if _fmcache:
- try:
- fontManager = json_load(_fmcache)
- if (not hasattr(fontManager, '_version') or
- fontManager._version != FontManager.__version__):
- _rebuild()
- else:
- fontManager.default_size = None
- _log.debug("Using fontManager instance from %s", _fmcache)
- except cbook.Locked.TimeoutError:
- raise
- except:
- _rebuild()
- else:
- _rebuild()
-
- def findfont(prop, **kw):
- global fontManager
- font = fontManager.findfont(prop, **kw)
- return font
diff --git a/contrib/python/matplotlib/py2/matplotlib/fontconfig_pattern.py b/contrib/python/matplotlib/py2/matplotlib/fontconfig_pattern.py
deleted file mode 100644
index 5104c25d36..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/fontconfig_pattern.py
+++ /dev/null
@@ -1,196 +0,0 @@
-"""
-A module for parsing and generating fontconfig patterns.
-
-See the `fontconfig pattern specification
-<https://www.freedesktop.org/software/fontconfig/fontconfig-user.html>`_ for
-more information.
-"""
-
-# This class is defined here because it must be available in:
-# - The old-style config framework (:file:`rcsetup.py`)
-# - The font manager (:file:`font_manager.py`)
-
-# It probably logically belongs in :file:`font_manager.py`, but placing it
-# there would have created cyclical dependency problems.
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import re
-from pyparsing import (Literal, ZeroOrMore, Optional, Regex, StringEnd,
- ParseException, Suppress)
-
-try:
- from functools import lru_cache
-except ImportError:
- from backports.functools_lru_cache import lru_cache
-
-family_punc = r'\\\-:,'
-family_unescape = re.compile(r'\\([%s])' % family_punc).sub
-family_escape = re.compile(r'([%s])' % family_punc).sub
-
-value_punc = r'\\=_:,'
-value_unescape = re.compile(r'\\([%s])' % value_punc).sub
-value_escape = re.compile(r'([%s])' % value_punc).sub
-
-class FontconfigPatternParser(object):
- """A simple pyparsing-based parser for fontconfig-style patterns.
-
- See the `fontconfig pattern specification
- <https://www.freedesktop.org/software/fontconfig/fontconfig-user.html>`_
- for more information.
- """
-
- _constants = {
- 'thin' : ('weight', 'light'),
- 'extralight' : ('weight', 'light'),
- 'ultralight' : ('weight', 'light'),
- 'light' : ('weight', 'light'),
- 'book' : ('weight', 'book'),
- 'regular' : ('weight', 'regular'),
- 'normal' : ('weight', 'normal'),
- 'medium' : ('weight', 'medium'),
- 'demibold' : ('weight', 'demibold'),
- 'semibold' : ('weight', 'semibold'),
- 'bold' : ('weight', 'bold'),
- 'extrabold' : ('weight', 'extra bold'),
- 'black' : ('weight', 'black'),
- 'heavy' : ('weight', 'heavy'),
- 'roman' : ('slant', 'normal'),
- 'italic' : ('slant', 'italic'),
- 'oblique' : ('slant', 'oblique'),
- 'ultracondensed' : ('width', 'ultra-condensed'),
- 'extracondensed' : ('width', 'extra-condensed'),
- 'condensed' : ('width', 'condensed'),
- 'semicondensed' : ('width', 'semi-condensed'),
- 'expanded' : ('width', 'expanded'),
- 'extraexpanded' : ('width', 'extra-expanded'),
- 'ultraexpanded' : ('width', 'ultra-expanded')
- }
-
- def __init__(self):
- family = Regex(r'([^%s]|(\\[%s]))*' %
- (family_punc, family_punc)) \
- .setParseAction(self._family)
- size = Regex(r"([0-9]+\.?[0-9]*|\.[0-9]+)") \
- .setParseAction(self._size)
- name = Regex(r'[a-z]+') \
- .setParseAction(self._name)
- value = Regex(r'([^%s]|(\\[%s]))*' %
- (value_punc, value_punc)) \
- .setParseAction(self._value)
-
- families =(family
- + ZeroOrMore(
- Literal(',')
- + family)
- ).setParseAction(self._families)
-
- point_sizes =(size
- + ZeroOrMore(
- Literal(',')
- + size)
- ).setParseAction(self._point_sizes)
-
- property =( (name
- + Suppress(Literal('='))
- + value
- + ZeroOrMore(
- Suppress(Literal(','))
- + value)
- )
- | name
- ).setParseAction(self._property)
-
- pattern =(Optional(
- families)
- + Optional(
- Literal('-')
- + point_sizes)
- + ZeroOrMore(
- Literal(':')
- + property)
- + StringEnd()
- )
-
- self._parser = pattern
- self.ParseException = ParseException
-
- def parse(self, pattern):
- """
- Parse the given fontconfig *pattern* and return a dictionary
- of key/value pairs useful for initializing a
- :class:`font_manager.FontProperties` object.
- """
- props = self._properties = {}
- try:
- self._parser.parseString(pattern)
- except self.ParseException as e:
- raise ValueError(
- "Could not parse font string: '%s'\n%s" % (pattern, e))
-
- self._properties = None
-
- self._parser.resetCache()
-
- return props
-
- def _family(self, s, loc, tokens):
- return [family_unescape(r'\1', str(tokens[0]))]
-
- def _size(self, s, loc, tokens):
- return [float(tokens[0])]
-
- def _name(self, s, loc, tokens):
- return [str(tokens[0])]
-
- def _value(self, s, loc, tokens):
- return [value_unescape(r'\1', str(tokens[0]))]
-
- def _families(self, s, loc, tokens):
- self._properties['family'] = [str(x) for x in tokens]
- return []
-
- def _point_sizes(self, s, loc, tokens):
- self._properties['size'] = [str(x) for x in tokens]
- return []
-
- def _property(self, s, loc, tokens):
- if len(tokens) == 1:
- if tokens[0] in self._constants:
- key, val = self._constants[tokens[0]]
- self._properties.setdefault(key, []).append(val)
- else:
- key = tokens[0]
- val = tokens[1:]
- self._properties.setdefault(key, []).extend(val)
- return []
-
-
-# `parse_fontconfig_pattern` is a bottleneck during the tests because it is
-# repeatedly called when the rcParams are reset (to validate the default
-# fonts). In practice, the cache size doesn't grow beyond a few dozen entries
-# during the test suite.
-parse_fontconfig_pattern = lru_cache()(FontconfigPatternParser().parse)
-
-
-def generate_fontconfig_pattern(d):
- """
- Given a dictionary of key/value pairs, generates a fontconfig
- pattern string.
- """
- props = []
- families = ''
- size = ''
- for key in 'family style variant weight stretch file size'.split():
- val = getattr(d, 'get_' + key)()
- if val is not None and val != []:
- if type(val) == list:
- val = [value_escape(r'\\\1', str(x)) for x in val
- if x is not None]
- if val != []:
- val = ','.join(val)
- props.append(":%s=%s" % (key, val))
- return ''.join(props)
diff --git a/contrib/python/matplotlib/py2/matplotlib/gridspec.py b/contrib/python/matplotlib/py2/matplotlib/gridspec.py
deleted file mode 100644
index 281d605dda..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/gridspec.py
+++ /dev/null
@@ -1,498 +0,0 @@
-"""
-:mod:`~matplotlib.gridspec` is a module which specifies the location
-of the subplot in the figure.
-
- `GridSpec`
- specifies the geometry of the grid that a subplot will be
- placed. The number of rows and number of columns of the grid
- need to be set. Optionally, the subplot layout parameters
- (e.g., left, right, etc.) can be tuned.
-
- `SubplotSpec`
- specifies the location of the subplot in the given `GridSpec`.
-
-"""
-
-from __future__ import absolute_import, division, print_function
-
-import six
-
-import copy
-import logging
-import warnings
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _pylab_helpers, tight_layout, rcParams
-from matplotlib.transforms import Bbox
-import matplotlib._layoutbox as layoutbox
-from matplotlib.cbook import mplDeprecation
-
-_log = logging.getLogger(__name__)
-
-
-class GridSpecBase(object):
- """
- A base class of GridSpec that specifies the geometry of the grid
- that a subplot will be placed.
- """
-
- def __init__(self, nrows, ncols, height_ratios=None, width_ratios=None):
- """
- The number of rows and number of columns of the grid need to
- be set. Optionally, the ratio of heights and widths of rows and
- columns can be specified.
- """
- self._nrows, self._ncols = nrows, ncols
- self.set_height_ratios(height_ratios)
- self.set_width_ratios(width_ratios)
-
- def get_geometry(self):
- 'get the geometry of the grid, e.g., 2,3'
- return self._nrows, self._ncols
-
- def get_subplot_params(self, figure=None, fig=None):
- pass
-
- def new_subplotspec(self, loc, rowspan=1, colspan=1):
- """
- create and return a SuplotSpec instance.
- """
- loc1, loc2 = loc
- subplotspec = self[loc1:loc1+rowspan, loc2:loc2+colspan]
- return subplotspec
-
- def set_width_ratios(self, width_ratios):
- if width_ratios is not None and len(width_ratios) != self._ncols:
- raise ValueError('Expected the given number of width ratios to '
- 'match the number of columns of the grid')
- self._col_width_ratios = width_ratios
-
- def get_width_ratios(self):
- return self._col_width_ratios
-
- def set_height_ratios(self, height_ratios):
- if height_ratios is not None and len(height_ratios) != self._nrows:
- raise ValueError('Expected the given number of height ratios to '
- 'match the number of rows of the grid')
- self._row_height_ratios = height_ratios
-
- def get_height_ratios(self):
- return self._row_height_ratios
-
- def get_grid_positions(self, fig, raw=False):
- """
- return lists of bottom and top position of rows, left and
- right positions of columns.
-
- If raw=True, then these are all in units relative to the container
- with no margins. (used for constrained_layout).
- """
- nrows, ncols = self.get_geometry()
-
- if raw:
- left = 0.
- right = 1.
- bottom = 0.
- top = 1.
- wspace = 0.
- hspace = 0.
- else:
- subplot_params = self.get_subplot_params(fig)
- left = subplot_params.left
- right = subplot_params.right
- bottom = subplot_params.bottom
- top = subplot_params.top
- wspace = subplot_params.wspace
- hspace = subplot_params.hspace
- tot_width = right - left
- tot_height = top - bottom
-
- # calculate accumulated heights of columns
- cell_h = tot_height / (nrows + hspace*(nrows-1))
- sep_h = hspace * cell_h
- if self._row_height_ratios is not None:
- norm = cell_h * nrows / sum(self._row_height_ratios)
- cell_heights = [r * norm for r in self._row_height_ratios]
- else:
- cell_heights = [cell_h] * nrows
- sep_heights = [0] + ([sep_h] * (nrows-1))
- cell_hs = np.cumsum(np.column_stack([sep_heights, cell_heights]).flat)
-
- # calculate accumulated widths of rows
- cell_w = tot_width / (ncols + wspace*(ncols-1))
- sep_w = wspace * cell_w
- if self._col_width_ratios is not None:
- norm = cell_w * ncols / sum(self._col_width_ratios)
- cell_widths = [r * norm for r in self._col_width_ratios]
- else:
- cell_widths = [cell_w] * ncols
- sep_widths = [0] + ([sep_w] * (ncols-1))
- cell_ws = np.cumsum(np.column_stack([sep_widths, cell_widths]).flat)
-
- fig_tops, fig_bottoms = (top - cell_hs).reshape((-1, 2)).T
- fig_lefts, fig_rights = (left + cell_ws).reshape((-1, 2)).T
- return fig_bottoms, fig_tops, fig_lefts, fig_rights
-
- def __getitem__(self, key):
- """Create and return a SuplotSpec instance.
- """
- nrows, ncols = self.get_geometry()
-
- def _normalize(key, size): # Includes last index.
- if isinstance(key, slice):
- start, stop, _ = key.indices(size)
- if stop > start:
- return start, stop - 1
- else:
- if key < 0:
- key += size
- if 0 <= key < size:
- return key, key
- raise IndexError("invalid index")
-
- if isinstance(key, tuple):
- try:
- k1, k2 = key
- except ValueError:
- raise ValueError("unrecognized subplot spec")
- num1, num2 = np.ravel_multi_index(
- [_normalize(k1, nrows), _normalize(k2, ncols)], (nrows, ncols))
- else: # Single key
- num1, num2 = _normalize(key, nrows * ncols)
-
- return SubplotSpec(self, num1, num2)
-
-
-class GridSpec(GridSpecBase):
- """
- A class that specifies the geometry of the grid that a subplot
- will be placed. The location of grid is determined by similar way
- as the SubplotParams.
- """
-
- def __init__(self, nrows, ncols, figure=None,
- left=None, bottom=None, right=None, top=None,
- wspace=None, hspace=None,
- width_ratios=None, height_ratios=None):
- """
- The number of rows and number of columns of the grid need to be set.
- Optionally, the subplot layout parameters (e.g., left, right, etc.)
- can be tuned.
-
- Parameters
- ----------
- nrows : int
- Number of rows in grid.
-
- ncols : int
- Number or columns in grid.
-
- Notes
- -----
- See `~.figure.SubplotParams` for descriptions of the layout parameters.
- """
- self.left = left
- self.bottom = bottom
- self.right = right
- self.top = top
- self.wspace = wspace
- self.hspace = hspace
- self.figure = figure
-
- GridSpecBase.__init__(self, nrows, ncols,
- width_ratios=width_ratios,
- height_ratios=height_ratios)
-
- if (self.figure is None) or not self.figure.get_constrained_layout():
- self._layoutbox = None
- else:
- self.figure.init_layoutbox()
- self._layoutbox = layoutbox.LayoutBox(
- parent=self.figure._layoutbox,
- name='gridspec' + layoutbox.seq_id(),
- artist=self)
- # by default the layoutbox for a gridsepc will fill a figure.
- # but this can change below if the gridspec is created from a
- # subplotspec. (GridSpecFromSubplotSpec)
-
- _AllowedKeys = ["left", "bottom", "right", "top", "wspace", "hspace"]
-
- def __getstate__(self):
- state = self.__dict__
- try:
- state.pop('_layoutbox')
- except KeyError:
- pass
- return state
-
- def __setstate__(self, state):
- self.__dict__ = state
- # layoutboxes don't survive pickling...
- self._layoutbox = None
-
- def update(self, **kwargs):
- """
- Update the current values. If any kwarg is None, default to
- the current value, if set, otherwise to rc.
- """
-
- for k, v in six.iteritems(kwargs):
- if k in self._AllowedKeys:
- setattr(self, k, v)
- else:
- raise AttributeError("%s is unknown keyword" % (k,))
-
- for figmanager in six.itervalues(_pylab_helpers.Gcf.figs):
- for ax in figmanager.canvas.figure.axes:
- # copied from Figure.subplots_adjust
- if not isinstance(ax, mpl.axes.SubplotBase):
- # Check if sharing a subplots axis
- if isinstance(ax._sharex, mpl.axes.SubplotBase):
- if ax._sharex.get_subplotspec().get_gridspec() == self:
- ax._sharex.update_params()
- ax._set_position(ax._sharex.figbox)
- elif isinstance(ax._sharey, mpl.axes.SubplotBase):
- if ax._sharey.get_subplotspec().get_gridspec() == self:
- ax._sharey.update_params()
- ax._set_position(ax._sharey.figbox)
- else:
- ss = ax.get_subplotspec().get_topmost_subplotspec()
- if ss.get_gridspec() == self:
- ax.update_params()
- ax._set_position(ax.figbox)
-
- def get_subplot_params(self, figure=None, fig=None):
- """
- Return a dictionary of subplot layout parameters. The default
- parameters are from rcParams unless a figure attribute is set.
- """
- if fig is not None:
- warnings.warn("the 'fig' kwarg is deprecated "
- "use 'figure' instead", mplDeprecation)
- if figure is None:
- figure = fig
-
- if figure is None:
- kw = {k: rcParams["figure.subplot."+k] for k in self._AllowedKeys}
- subplotpars = mpl.figure.SubplotParams(**kw)
- else:
- subplotpars = copy.copy(figure.subplotpars)
-
- update_kw = {k: getattr(self, k) for k in self._AllowedKeys}
- subplotpars.update(**update_kw)
-
- return subplotpars
-
- def locally_modified_subplot_params(self):
- return [k for k in self._AllowedKeys if getattr(self, k)]
-
- def tight_layout(self, figure, renderer=None,
- pad=1.08, h_pad=None, w_pad=None, rect=None):
- """
- Adjust subplot parameters to give specified padding.
-
- Parameters
- ----------
-
- pad : float
- Padding between the figure edge and the edges of subplots, as a
- fraction of the font-size.
- h_pad, w_pad : float, optional
- Padding (height/width) between edges of adjacent subplots.
- Defaults to ``pad_inches``.
- rect : tuple of 4 floats, optional
- (left, bottom, right, top) rectangle in normalized figure
- coordinates that the whole subplots area (including labels) will
- fit into. Default is (0, 0, 1, 1).
- """
-
- subplotspec_list = tight_layout.get_subplotspec_list(
- figure.axes, grid_spec=self)
- if None in subplotspec_list:
- warnings.warn("This figure includes Axes that are not compatible "
- "with tight_layout, so results might be incorrect.")
-
- if renderer is None:
- renderer = tight_layout.get_renderer(figure)
-
- kwargs = tight_layout.get_tight_layout_figure(
- figure, figure.axes, subplotspec_list, renderer,
- pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
- self.update(**kwargs)
-
-
-class GridSpecFromSubplotSpec(GridSpecBase):
- """
- GridSpec whose subplot layout parameters are inherited from the
- location specified by a given SubplotSpec.
- """
- def __init__(self, nrows, ncols,
- subplot_spec,
- wspace=None, hspace=None,
- height_ratios=None, width_ratios=None):
- """
- The number of rows and number of columns of the grid need to
- be set. An instance of SubplotSpec is also needed to be set
- from which the layout parameters will be inherited. The wspace
- and hspace of the layout can be optionally specified or the
- default values (from the figure or rcParams) will be used.
- """
- self._wspace = wspace
- self._hspace = hspace
- self._subplot_spec = subplot_spec
- GridSpecBase.__init__(self, nrows, ncols,
- width_ratios=width_ratios,
- height_ratios=height_ratios)
- # do the layoutboxes
- subspeclb = subplot_spec._layoutbox
- if subspeclb is None:
- self._layoutbox = None
- else:
- # OK, this is needed to divide the figure.
- self._layoutbox = subspeclb.layout_from_subplotspec(
- subplot_spec,
- name=subspeclb.name + '.gridspec' + layoutbox.seq_id(),
- artist=self)
-
- def get_subplot_params(self, figure=None, fig=None):
- """Return a dictionary of subplot layout parameters.
- """
- if fig is not None:
- warnings.warn("the 'fig' kwarg is deprecated "
- "use 'figure' instead", mplDeprecation)
- if figure is None:
- figure = fig
-
- hspace = (self._hspace if self._hspace is not None
- else figure.subplotpars.hspace if figure is not None
- else rcParams["figure.subplot.hspace"])
- wspace = (self._wspace if self._wspace is not None
- else figure.subplotpars.wspace if figure is not None
- else rcParams["figure.subplot.wspace"])
-
- figbox = self._subplot_spec.get_position(figure)
- left, bottom, right, top = figbox.extents
-
- return mpl.figure.SubplotParams(left=left, right=right,
- bottom=bottom, top=top,
- wspace=wspace, hspace=hspace)
-
- def get_topmost_subplotspec(self):
- """Get the topmost SubplotSpec instance associated with the subplot."""
- return self._subplot_spec.get_topmost_subplotspec()
-
-
-class SubplotSpec(object):
- """Specifies the location of the subplot in the given `GridSpec`.
- """
-
- def __init__(self, gridspec, num1, num2=None):
- """
- The subplot will occupy the num1-th cell of the given
- gridspec. If num2 is provided, the subplot will span between
- num1-th cell and num2-th cell.
-
- The index starts from 0.
- """
- self._gridspec = gridspec
- self.num1 = num1
- self.num2 = num2
- if gridspec._layoutbox is not None:
- glb = gridspec._layoutbox
- # So note that here we don't assign any layout yet,
- # just make the layoutbox that will conatin all items
- # associated w/ this axis. This can include other axes like
- # a colorbar or a legend.
- self._layoutbox = layoutbox.LayoutBox(
- parent=glb,
- name=glb.name + '.ss' + layoutbox.seq_id(),
- artist=self)
- else:
- self._layoutbox = None
-
- def __getstate__(self):
- state = self.__dict__
- try:
- state.pop('_layoutbox')
- except KeyError:
- pass
- return state
-
- def __setstate__(self, state):
- self.__dict__ = state
- # layoutboxes don't survive pickling...
- self._layoutbox = None
-
- def get_gridspec(self):
- return self._gridspec
-
- def get_geometry(self):
- """
- Get the subplot geometry (``n_rows, n_cols, start, stop``).
-
- start and stop are the index of the start and stop of the
- subplot.
- """
- rows, cols = self.get_gridspec().get_geometry()
- return rows, cols, self.num1, self.num2
-
- def get_rows_columns(self):
- """
- Get the subplot row and column numbers:
- (``n_rows, n_cols, row_start, row_stop, col_start, col_stop``)
- """
- gridspec = self.get_gridspec()
- nrows, ncols = gridspec.get_geometry()
- row_start, col_start = divmod(self.num1, ncols)
- if self.num2 is not None:
- row_stop, col_stop = divmod(self.num2, ncols)
- else:
- row_stop = row_start
- col_stop = col_start
- return nrows, ncols, row_start, row_stop, col_start, col_stop
-
- def get_position(self, figure, return_all=False):
- """Update the subplot position from ``figure.subplotpars``.
- """
- gridspec = self.get_gridspec()
- nrows, ncols = gridspec.get_geometry()
- rows, cols = np.unravel_index(
- [self.num1] if self.num2 is None else [self.num1, self.num2],
- (nrows, ncols))
- fig_bottoms, fig_tops, fig_lefts, fig_rights = \
- gridspec.get_grid_positions(figure)
-
- fig_bottom = fig_bottoms[rows].min()
- fig_top = fig_tops[rows].max()
- fig_left = fig_lefts[cols].min()
- fig_right = fig_rights[cols].max()
- figbox = Bbox.from_extents(fig_left, fig_bottom, fig_right, fig_top)
-
- if return_all:
- return figbox, rows[0], cols[0], nrows, ncols
- else:
- return figbox
-
- def get_topmost_subplotspec(self):
- 'get the topmost SubplotSpec instance associated with the subplot'
- gridspec = self.get_gridspec()
- if hasattr(gridspec, "get_topmost_subplotspec"):
- return gridspec.get_topmost_subplotspec()
- else:
- return self
-
- def __eq__(self, other):
- # other may not even have the attributes we are checking.
- return ((self._gridspec, self.num1, self.num2)
- == (getattr(other, "_gridspec", object()),
- getattr(other, "num1", object()),
- getattr(other, "num2", object())))
-
- if six.PY2:
- def __ne__(self, other):
- return not self == other
-
- def __hash__(self):
- return hash((self._gridspec, self.num1, self.num2))
diff --git a/contrib/python/matplotlib/py2/matplotlib/hatch.py b/contrib/python/matplotlib/py2/matplotlib/hatch.py
deleted file mode 100644
index 94294afdf8..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/hatch.py
+++ /dev/null
@@ -1,220 +0,0 @@
-"""
-Contains a classes for generating hatch patterns.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-
-import numpy as np
-from matplotlib.path import Path
-
-
-class HatchPatternBase(object):
- """
- The base class for a hatch pattern.
- """
- pass
-
-
-class HorizontalHatch(HatchPatternBase):
- def __init__(self, hatch, density):
- self.num_lines = int((hatch.count('-') + hatch.count('+')) * density)
- self.num_vertices = self.num_lines * 2
-
- def set_vertices_and_codes(self, vertices, codes):
- steps, stepsize = np.linspace(0.0, 1.0, self.num_lines, False,
- retstep=True)
- steps += stepsize / 2.
- vertices[0::2, 0] = 0.0
- vertices[0::2, 1] = steps
- vertices[1::2, 0] = 1.0
- vertices[1::2, 1] = steps
- codes[0::2] = Path.MOVETO
- codes[1::2] = Path.LINETO
-
-
-class VerticalHatch(HatchPatternBase):
- def __init__(self, hatch, density):
- self.num_lines = int((hatch.count('|') + hatch.count('+')) * density)
- self.num_vertices = self.num_lines * 2
-
- def set_vertices_and_codes(self, vertices, codes):
- steps, stepsize = np.linspace(0.0, 1.0, self.num_lines, False,
- retstep=True)
- steps += stepsize / 2.
- vertices[0::2, 0] = steps
- vertices[0::2, 1] = 0.0
- vertices[1::2, 0] = steps
- vertices[1::2, 1] = 1.0
- codes[0::2] = Path.MOVETO
- codes[1::2] = Path.LINETO
-
-
-class NorthEastHatch(HatchPatternBase):
- def __init__(self, hatch, density):
- self.num_lines = int((hatch.count('/') + hatch.count('x') +
- hatch.count('X')) * density)
- if self.num_lines:
- self.num_vertices = (self.num_lines + 1) * 2
- else:
- self.num_vertices = 0
-
- def set_vertices_and_codes(self, vertices, codes):
- steps = np.linspace(-0.5, 0.5, self.num_lines + 1, True)
- vertices[0::2, 0] = 0.0 + steps
- vertices[0::2, 1] = 0.0 - steps
- vertices[1::2, 0] = 1.0 + steps
- vertices[1::2, 1] = 1.0 - steps
- codes[0::2] = Path.MOVETO
- codes[1::2] = Path.LINETO
-
-
-class SouthEastHatch(HatchPatternBase):
- def __init__(self, hatch, density):
- self.num_lines = int((hatch.count('\\') + hatch.count('x') +
- hatch.count('X')) * density)
- self.num_vertices = (self.num_lines + 1) * 2
- if self.num_lines:
- self.num_vertices = (self.num_lines + 1) * 2
- else:
- self.num_vertices = 0
-
- def set_vertices_and_codes(self, vertices, codes):
- steps = np.linspace(-0.5, 0.5, self.num_lines + 1, True)
- vertices[0::2, 0] = 0.0 + steps
- vertices[0::2, 1] = 1.0 + steps
- vertices[1::2, 0] = 1.0 + steps
- vertices[1::2, 1] = 0.0 + steps
- codes[0::2] = Path.MOVETO
- codes[1::2] = Path.LINETO
-
-
-class Shapes(HatchPatternBase):
- filled = False
-
- def __init__(self, hatch, density):
- if self.num_rows == 0:
- self.num_shapes = 0
- self.num_vertices = 0
- else:
- self.num_shapes = ((self.num_rows // 2 + 1) * (self.num_rows + 1) +
- (self.num_rows // 2) * (self.num_rows))
- self.num_vertices = (self.num_shapes *
- len(self.shape_vertices) *
- (self.filled and 1 or 2))
-
- def set_vertices_and_codes(self, vertices, codes):
- offset = 1.0 / self.num_rows
- shape_vertices = self.shape_vertices * offset * self.size
- if not self.filled:
- inner_vertices = shape_vertices[::-1] * 0.9
- shape_codes = self.shape_codes
- shape_size = len(shape_vertices)
-
- cursor = 0
- for row in xrange(self.num_rows + 1):
- if row % 2 == 0:
- cols = np.linspace(0.0, 1.0, self.num_rows + 1, True)
- else:
- cols = np.linspace(offset / 2.0, 1.0 - offset / 2.0,
- self.num_rows, True)
- row_pos = row * offset
- for col_pos in cols:
- vertices[cursor:cursor + shape_size] = (shape_vertices +
- (col_pos, row_pos))
- codes[cursor:cursor + shape_size] = shape_codes
- cursor += shape_size
- if not self.filled:
- vertices[cursor:cursor + shape_size] = (inner_vertices +
- (col_pos, row_pos))
- codes[cursor:cursor + shape_size] = shape_codes
- cursor += shape_size
-
-
-class Circles(Shapes):
- def __init__(self, hatch, density):
- path = Path.unit_circle()
- self.shape_vertices = path.vertices
- self.shape_codes = path.codes
- Shapes.__init__(self, hatch, density)
-
-
-class SmallCircles(Circles):
- size = 0.2
-
- def __init__(self, hatch, density):
- self.num_rows = (hatch.count('o')) * density
- Circles.__init__(self, hatch, density)
-
-
-class LargeCircles(Circles):
- size = 0.35
-
- def __init__(self, hatch, density):
- self.num_rows = (hatch.count('O')) * density
- Circles.__init__(self, hatch, density)
-
-
-class SmallFilledCircles(SmallCircles):
- size = 0.1
- filled = True
-
- def __init__(self, hatch, density):
- self.num_rows = (hatch.count('.')) * density
- Circles.__init__(self, hatch, density)
-
-
-class Stars(Shapes):
- size = 1.0 / 3.0
- filled = True
-
- def __init__(self, hatch, density):
- self.num_rows = (hatch.count('*')) * density
- path = Path.unit_regular_star(5)
- self.shape_vertices = path.vertices
- self.shape_codes = np.ones(len(self.shape_vertices)) * Path.LINETO
- self.shape_codes[0] = Path.MOVETO
- Shapes.__init__(self, hatch, density)
-
-_hatch_types = [
- HorizontalHatch,
- VerticalHatch,
- NorthEastHatch,
- SouthEastHatch,
- SmallCircles,
- LargeCircles,
- SmallFilledCircles,
- Stars
- ]
-
-
-def get_path(hatchpattern, density=6):
- """
- Given a hatch specifier, *hatchpattern*, generates Path to render
- the hatch in a unit square. *density* is the number of lines per
- unit square.
- """
- density = int(density)
-
- patterns = [hatch_type(hatchpattern, density)
- for hatch_type in _hatch_types]
- num_vertices = sum([pattern.num_vertices for pattern in patterns])
-
- if num_vertices == 0:
- return Path(np.empty((0, 2)))
-
- vertices = np.empty((num_vertices, 2))
- codes = np.empty((num_vertices,), np.uint8)
-
- cursor = 0
- for pattern in patterns:
- if pattern.num_vertices != 0:
- vertices_chunk = vertices[cursor:cursor + pattern.num_vertices]
- codes_chunk = codes[cursor:cursor + pattern.num_vertices]
- pattern.set_vertices_and_codes(vertices_chunk, codes_chunk)
- cursor += pattern.num_vertices
-
- return Path(vertices, codes)
diff --git a/contrib/python/matplotlib/py2/matplotlib/image.py b/contrib/python/matplotlib/py2/matplotlib/image.py
deleted file mode 100644
index e03778ca9f..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/image.py
+++ /dev/null
@@ -1,1534 +0,0 @@
-"""
-The image module supports basic image loading, rescaling and display
-operations.
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves.urllib.parse import urlparse
-from six.moves.urllib.request import urlopen
-from io import BytesIO
-
-from math import ceil
-import os
-import logging
-
-import numpy as np
-
-from matplotlib import rcParams
-import matplotlib.artist as martist
-from matplotlib.artist import allow_rasterization
-import matplotlib.colors as mcolors
-import matplotlib.cm as cm
-import matplotlib.cbook as cbook
-
-# For clarity, names from _image are given explicitly in this module:
-import matplotlib._image as _image
-import matplotlib._png as _png
-
-# For user convenience, the names from _image are also imported into
-# the image namespace:
-from matplotlib._image import *
-
-from matplotlib.transforms import (Affine2D, BboxBase, Bbox, BboxTransform,
- IdentityTransform, TransformedBbox)
-
-_log = logging.getLogger(__name__)
-
-# map interpolation strings to module constants
-_interpd_ = {
- 'none': _image.NEAREST, # fall back to nearest when not supported
- 'nearest': _image.NEAREST,
- 'bilinear': _image.BILINEAR,
- 'bicubic': _image.BICUBIC,
- 'spline16': _image.SPLINE16,
- 'spline36': _image.SPLINE36,
- 'hanning': _image.HANNING,
- 'hamming': _image.HAMMING,
- 'hermite': _image.HERMITE,
- 'kaiser': _image.KAISER,
- 'quadric': _image.QUADRIC,
- 'catrom': _image.CATROM,
- 'gaussian': _image.GAUSSIAN,
- 'bessel': _image.BESSEL,
- 'mitchell': _image.MITCHELL,
- 'sinc': _image.SINC,
- 'lanczos': _image.LANCZOS,
- 'blackman': _image.BLACKMAN,
-}
-
-interpolations_names = set(_interpd_)
-
-
-def composite_images(images, renderer, magnification=1.0):
- """
- Composite a number of RGBA images into one. The images are
- composited in the order in which they appear in the `images` list.
-
- Parameters
- ----------
- images : list of Images
- Each must have a `make_image` method. For each image,
- `can_composite` should return `True`, though this is not
- enforced by this function. Each image must have a purely
- affine transformation with no shear.
-
- renderer : RendererBase instance
-
- magnification : float
- The additional magnification to apply for the renderer in use.
-
- Returns
- -------
- tuple : image, offset_x, offset_y
- Returns the tuple:
-
- - image: A numpy array of the same type as the input images.
-
- - offset_x, offset_y: The offset of the image (left, bottom)
- in the output figure.
- """
- if len(images) == 0:
- return np.empty((0, 0, 4), dtype=np.uint8), 0, 0
-
- parts = []
- bboxes = []
- for image in images:
- data, x, y, trans = image.make_image(renderer, magnification)
- if data is not None:
- x *= magnification
- y *= magnification
- parts.append((data, x, y, image.get_alpha() or 1.0))
- bboxes.append(
- Bbox([[x, y], [x + data.shape[1], y + data.shape[0]]]))
-
- if len(parts) == 0:
- return np.empty((0, 0, 4), dtype=np.uint8), 0, 0
-
- bbox = Bbox.union(bboxes)
-
- output = np.zeros(
- (int(bbox.height), int(bbox.width), 4), dtype=np.uint8)
-
- for data, x, y, alpha in parts:
- trans = Affine2D().translate(x - bbox.x0, y - bbox.y0)
- _image.resample(data, output, trans, _image.NEAREST,
- resample=False, alpha=alpha)
-
- return output, bbox.x0 / magnification, bbox.y0 / magnification
-
-
-def _draw_list_compositing_images(
- renderer, parent, artists, suppress_composite=None):
- """
- Draw a sorted list of artists, compositing images into a single
- image where possible.
-
- For internal matplotlib use only: It is here to reduce duplication
- between `Figure.draw` and `Axes.draw`, but otherwise should not be
- generally useful.
- """
- has_images = any(isinstance(x, _ImageBase) for x in artists)
-
- # override the renderer default if suppressComposite is not None
- not_composite = (suppress_composite if suppress_composite is not None
- else renderer.option_image_nocomposite())
-
- if not_composite or not has_images:
- for a in artists:
- a.draw(renderer)
- else:
- # Composite any adjacent images together
- image_group = []
- mag = renderer.get_image_magnification()
-
- def flush_images():
- if len(image_group) == 1:
- image_group[0].draw(renderer)
- elif len(image_group) > 1:
- data, l, b = composite_images(image_group, renderer, mag)
- if data.size != 0:
- gc = renderer.new_gc()
- gc.set_clip_rectangle(parent.bbox)
- gc.set_clip_path(parent.get_clip_path())
- renderer.draw_image(gc, np.round(l), np.round(b), data)
- gc.restore()
- del image_group[:]
-
- for a in artists:
- if isinstance(a, _ImageBase) and a.can_composite():
- image_group.append(a)
- else:
- flush_images()
- a.draw(renderer)
- flush_images()
-
-
-def _rgb_to_rgba(A):
- """
- Convert an RGB image to RGBA, as required by the image resample C++
- extension.
- """
- rgba = np.zeros((A.shape[0], A.shape[1], 4), dtype=A.dtype)
- rgba[:, :, :3] = A
- if rgba.dtype == np.uint8:
- rgba[:, :, 3] = 255
- else:
- rgba[:, :, 3] = 1.0
- return rgba
-
-
-class _ImageBase(martist.Artist, cm.ScalarMappable):
- zorder = 0
-
- @property
- @cbook.deprecated("2.1")
- def _interpd(self):
- return _interpd_
-
- @property
- @cbook.deprecated("2.1")
- def _interpdr(self):
- return {v: k for k, v in six.iteritems(_interpd_)}
-
- @property
- @cbook.deprecated("2.1", alternative="mpl.image.interpolation_names")
- def iterpnames(self):
- return interpolations_names
-
- def __str__(self):
- return "AxesImage(%g,%g;%gx%g)" % tuple(self.axes.bbox.bounds)
-
- def __init__(self, ax,
- cmap=None,
- norm=None,
- interpolation=None,
- origin=None,
- filternorm=1,
- filterrad=4.0,
- resample=False,
- **kwargs
- ):
- """
- interpolation and cmap default to their rc settings
-
- cmap is a colors.Colormap instance
- norm is a colors.Normalize instance to map luminance to 0-1
-
- extent is data axes (left, right, bottom, top) for making image plots
- registered with data plots. Default is to label the pixel
- centers with the zero-based row and column indices.
-
- Additional kwargs are matplotlib.artist properties
-
- """
- martist.Artist.__init__(self)
- cm.ScalarMappable.__init__(self, norm, cmap)
- self._mouseover = True
- if origin is None:
- origin = rcParams['image.origin']
- self.origin = origin
- self.set_filternorm(filternorm)
- self.set_filterrad(filterrad)
- self.set_interpolation(interpolation)
- self.set_resample(resample)
- self.axes = ax
-
- self._imcache = None
-
- self.update(kwargs)
-
- def __getstate__(self):
- state = super(_ImageBase, self).__getstate__()
- # We can't pickle the C Image cached object.
- state['_imcache'] = None
- return state
-
- def get_size(self):
- """Get the numrows, numcols of the input image"""
- if self._A is None:
- raise RuntimeError('You must first set the image array')
-
- return self._A.shape[:2]
-
- def set_alpha(self, alpha):
- """
- Set the alpha value used for blending - not supported on
- all backends
-
- ACCEPTS: float
- """
- martist.Artist.set_alpha(self, alpha)
- self._imcache = None
-
- def changed(self):
- """
- Call this whenever the mappable is changed so observers can
- update state
- """
- self._imcache = None
- self._rgbacache = None
- cm.ScalarMappable.changed(self)
-
- def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
- unsampled=False, round_to_pixel_border=True):
- """
- Normalize, rescale and color the image `A` from the given
- in_bbox (in data space), to the given out_bbox (in pixel
- space) clipped to the given clip_bbox (also in pixel space),
- and magnified by the magnification factor.
-
- `A` may be a greyscale image (MxN) with a dtype of `float32`,
- `float64`, `uint16` or `uint8`, or an RGBA image (MxNx4) with
- a dtype of `float32`, `float64`, or `uint8`.
-
- If `unsampled` is True, the image will not be scaled, but an
- appropriate affine transformation will be returned instead.
-
- If `round_to_pixel_border` is True, the output image size will
- be rounded to the nearest pixel boundary. This makes the
- images align correctly with the axes. It should not be used
- in cases where you want exact scaling, however, such as
- FigureImage.
-
- Returns the resulting (image, x, y, trans), where (x, y) is
- the upper left corner of the result in pixel space, and
- `trans` is the affine transformation from the image to pixel
- space.
- """
- if A is None:
- raise RuntimeError('You must first set the image '
- 'array or the image attribute')
- if A.size == 0:
- raise RuntimeError("_make_image must get a non-empty image. "
- "Your Artist's draw method must filter before "
- "this method is called.")
-
- clipped_bbox = Bbox.intersection(out_bbox, clip_bbox)
-
- if clipped_bbox is None:
- return None, 0, 0, None
-
- out_width_base = clipped_bbox.width * magnification
- out_height_base = clipped_bbox.height * magnification
-
- if out_width_base == 0 or out_height_base == 0:
- return None, 0, 0, None
-
- if self.origin == 'upper':
- # Flip the input image using a transform. This avoids the
- # problem with flipping the array, which results in a copy
- # when it is converted to contiguous in the C wrapper
- t0 = Affine2D().translate(0, -A.shape[0]).scale(1, -1)
- else:
- t0 = IdentityTransform()
-
- t0 += (
- Affine2D()
- .scale(
- in_bbox.width / A.shape[1],
- in_bbox.height / A.shape[0])
- .translate(in_bbox.x0, in_bbox.y0)
- + self.get_transform())
-
- t = (t0
- + Affine2D().translate(
- -clipped_bbox.x0,
- -clipped_bbox.y0)
- .scale(magnification, magnification))
-
- # So that the image is aligned with the edge of the axes, we want
- # to round up the output width to the next integer. This also
- # means scaling the transform just slightly to account for the
- # extra subpixel.
- if (t.is_affine and round_to_pixel_border and
- (out_width_base % 1.0 != 0.0 or out_height_base % 1.0 != 0.0)):
- out_width = int(ceil(out_width_base))
- out_height = int(ceil(out_height_base))
- extra_width = (out_width - out_width_base) / out_width_base
- extra_height = (out_height - out_height_base) / out_height_base
- t += Affine2D().scale(1.0 + extra_width, 1.0 + extra_height)
- else:
- out_width = int(out_width_base)
- out_height = int(out_height_base)
-
- if not unsampled:
- if A.ndim not in (2, 3):
- raise ValueError("Invalid dimensions, got {}".format(A.shape))
-
- if A.ndim == 2:
- # if we are a 2D array, then we are running through the
- # norm + colormap transformation. However, in general the
- # input data is not going to match the size on the screen so we
- # have to resample to the correct number of pixels
- # need to
-
- # TODO slice input array first
- inp_dtype = A.dtype
- a_min = A.min()
- a_max = A.max()
- # figure out the type we should scale to. For floats,
- # leave as is. For integers cast to an appropriate-sized
- # float. Small integers get smaller floats in an attempt
- # to keep the memory footprint reasonable.
- if a_min is np.ma.masked:
- # all masked, so values don't matter
- a_min, a_max = np.int32(0), np.int32(1)
- if inp_dtype.kind == 'f':
- scaled_dtype = A.dtype
- else:
- # probably an integer of some type.
- da = a_max.astype(np.float64) - a_min.astype(np.float64)
- if da > 1e8:
- # give more breathing room if a big dynamic range
- scaled_dtype = np.float64
- else:
- scaled_dtype = np.float32
-
- # scale the input data to [.1, .9]. The Agg
- # interpolators clip to [0, 1] internally, use a
- # smaller input scale to identify which of the
- # interpolated points need to be should be flagged as
- # over / under.
- # This may introduce numeric instabilities in very broadly
- # scaled data
- A_scaled = np.empty(A.shape, dtype=scaled_dtype)
- A_scaled[:] = A
- # clip scaled data around norm if necessary.
- # This is necessary for big numbers at the edge of
- # float64's ability to represent changes. Applying
- # a norm first would be good, but ruins the interpolation
- # of over numbers.
- self.norm.autoscale_None(A)
- dv = (np.float64(self.norm.vmax) -
- np.float64(self.norm.vmin))
- vmid = self.norm.vmin + dv / 2
- fact = 1e7 if scaled_dtype == np.float64 else 1e4
- newmin = vmid - dv * fact
- if newmin < a_min:
- newmin = None
- else:
- a_min = np.float64(newmin)
- newmax = vmid + dv * fact
- if newmax > a_max:
- newmax = None
- else:
- a_max = np.float64(newmax)
- if newmax is not None or newmin is not None:
- A_scaled = np.clip(A_scaled, newmin, newmax)
-
- A_scaled -= a_min
- # a_min and a_max might be ndarray subclasses so use
- # item to avoid errors
- a_min = a_min.astype(scaled_dtype).item()
- a_max = a_max.astype(scaled_dtype).item()
-
- if a_min != a_max:
- A_scaled /= ((a_max - a_min) / 0.8)
- A_scaled += 0.1
- A_resampled = np.zeros((out_height, out_width),
- dtype=A_scaled.dtype)
- # resample the input data to the correct resolution and shape
- _image.resample(A_scaled, A_resampled,
- t,
- _interpd_[self.get_interpolation()],
- self.get_resample(), 1.0,
- self.get_filternorm() or 0.0,
- self.get_filterrad() or 0.0)
-
- # we are done with A_scaled now, remove from namespace
- # to be sure!
- del A_scaled
- # un-scale the resampled data to approximately the
- # original range things that interpolated to above /
- # below the original min/max will still be above /
- # below, but possibly clipped in the case of higher order
- # interpolation + drastically changing data.
- A_resampled -= 0.1
- if a_min != a_max:
- A_resampled *= ((a_max - a_min) / 0.8)
- A_resampled += a_min
- # if using NoNorm, cast back to the original datatype
- if isinstance(self.norm, mcolors.NoNorm):
- A_resampled = A_resampled.astype(A.dtype)
-
- mask = np.empty(A.shape, dtype=np.float32)
- if A.mask.shape == A.shape:
- # this is the case of a nontrivial mask
- mask[:] = np.where(A.mask, np.float32(np.nan),
- np.float32(1))
- else:
- mask[:] = 1
-
- # we always have to interpolate the mask to account for
- # non-affine transformations
- out_mask = np.zeros((out_height, out_width),
- dtype=mask.dtype)
- _image.resample(mask, out_mask,
- t,
- _interpd_[self.get_interpolation()],
- True, 1,
- self.get_filternorm() or 0.0,
- self.get_filterrad() or 0.0)
- # we are done with the mask, delete from namespace to be sure!
- del mask
- # Agg updates the out_mask in place. If the pixel has
- # no image data it will not be updated (and still be 0
- # as we initialized it), if input data that would go
- # into that output pixel than it will be `nan`, if all
- # the input data for a pixel is good it will be 1, and
- # if there is _some_ good data in that output pixel it
- # will be between [0, 1] (such as a rotated image).
-
- out_alpha = np.array(out_mask)
- out_mask = np.isnan(out_mask)
- out_alpha[out_mask] = 1
-
- # mask and run through the norm
- output = self.norm(np.ma.masked_array(A_resampled, out_mask))
- else:
- # Always convert to RGBA, even if only RGB input
- if A.shape[2] == 3:
- A = _rgb_to_rgba(A)
- elif A.shape[2] != 4:
- raise ValueError("Invalid dimensions, got %s" % (A.shape,))
-
- output = np.zeros((out_height, out_width, 4), dtype=A.dtype)
-
- alpha = self.get_alpha()
- if alpha is None:
- alpha = 1.0
-
- _image.resample(
- A, output, t, _interpd_[self.get_interpolation()],
- self.get_resample(), alpha,
- self.get_filternorm() or 0.0, self.get_filterrad() or 0.0)
-
- # at this point output is either a 2D array of normed data
- # (of int or float)
- # or an RGBA array of re-sampled input
- output = self.to_rgba(output, bytes=True, norm=False)
- # output is now a correctly sized RGBA array of uint8
-
- # Apply alpha *after* if the input was greyscale without a mask
- if A.ndim == 2:
- alpha = self.get_alpha()
- if alpha is None:
- alpha = 1
- alpha_channel = output[:, :, 3]
- alpha_channel[:] = np.asarray(
- np.asarray(alpha_channel, np.float32) * out_alpha * alpha,
- np.uint8)
-
- else:
- if self._imcache is None:
- self._imcache = self.to_rgba(A, bytes=True, norm=(A.ndim == 2))
- output = self._imcache
-
- # Subset the input image to only the part that will be
- # displayed
- subset = TransformedBbox(
- clip_bbox, t0.frozen().inverted()).frozen()
- output = output[
- int(max(subset.ymin, 0)):
- int(min(subset.ymax + 1, output.shape[0])),
- int(max(subset.xmin, 0)):
- int(min(subset.xmax + 1, output.shape[1]))]
-
- t = Affine2D().translate(
- int(max(subset.xmin, 0)), int(max(subset.ymin, 0))) + t
-
- return output, clipped_bbox.x0, clipped_bbox.y0, t
-
- def make_image(self, renderer, magnification=1.0, unsampled=False):
- raise RuntimeError('The make_image method must be overridden.')
-
- def _draw_unsampled_image(self, renderer, gc):
- """
- draw unsampled image. The renderer should support a draw_image method
- with scale parameter.
- """
-
- im, l, b, trans = self.make_image(renderer, unsampled=True)
-
- if im is None:
- return
-
- trans = Affine2D().scale(im.shape[1], im.shape[0]) + trans
-
- renderer.draw_image(gc, l, b, im, trans)
-
- def _check_unsampled_image(self, renderer):
- """
- return True if the image is better to be drawn unsampled.
- The derived class needs to override it.
- """
- return False
-
- @allow_rasterization
- def draw(self, renderer, *args, **kwargs):
- # if not visible, declare victory and return
- if not self.get_visible():
- self.stale = False
- return
-
- # for empty images, there is nothing to draw!
- if self.get_array().size == 0:
- self.stale = False
- return
-
- # actually render the image.
- gc = renderer.new_gc()
- self._set_gc_clip(gc)
- gc.set_alpha(self.get_alpha())
- gc.set_url(self.get_url())
- gc.set_gid(self.get_gid())
-
- if (self._check_unsampled_image(renderer) and
- self.get_transform().is_affine):
- self._draw_unsampled_image(renderer, gc)
- else:
- im, l, b, trans = self.make_image(
- renderer, renderer.get_image_magnification())
- if im is not None:
- renderer.draw_image(gc, l, b, im)
- gc.restore()
- self.stale = False
-
- def contains(self, mouseevent):
- """
- Test whether the mouse event occurred within the image.
- """
- if callable(self._contains):
- return self._contains(self, mouseevent)
- # TODO: make sure this is consistent with patch and patch
- # collection on nonlinear transformed coordinates.
- # TODO: consider returning image coordinates (shouldn't
- # be too difficult given that the image is rectilinear
- x, y = mouseevent.xdata, mouseevent.ydata
- xmin, xmax, ymin, ymax = self.get_extent()
- if xmin > xmax:
- xmin, xmax = xmax, xmin
- if ymin > ymax:
- ymin, ymax = ymax, ymin
-
- if x is not None and y is not None:
- inside = (xmin <= x <= xmax) and (ymin <= y <= ymax)
- else:
- inside = False
-
- return inside, {}
-
- def write_png(self, fname):
- """Write the image to png file with fname"""
- im = self.to_rgba(self._A[::-1] if self.origin == 'lower' else self._A,
- bytes=True, norm=True)
- _png.write_png(im, fname)
-
- def set_data(self, A):
- """
- Set the image array.
-
- ACCEPTS: numpy/PIL Image A
-
- Note that this function does *not* update the normalization used.
- """
- self._A = cbook.safe_masked_invalid(A, copy=True)
-
- if (self._A.dtype != np.uint8 and
- not np.can_cast(self._A.dtype, float, "same_kind")):
- raise TypeError("Image data cannot be converted to float")
-
- if not (self._A.ndim == 2
- or self._A.ndim == 3 and self._A.shape[-1] in [3, 4]):
- raise TypeError("Invalid dimensions for image data")
-
- if self._A.ndim == 3:
- # If the input data has values outside the valid range (after
- # normalisation), we issue a warning and then clip X to the bounds
- # - otherwise casting wraps extreme values, hiding outliers and
- # making reliable interpretation impossible.
- high = 255 if np.issubdtype(self._A.dtype, np.integer) else 1
- if self._A.min() < 0 or high < self._A.max():
- _log.warning(
- 'Clipping input data to the valid range for imshow with '
- 'RGB data ([0..1] for floats or [0..255] for integers).'
- )
- self._A = np.clip(self._A, 0, high)
- # Cast unsupported integer types to uint8
- if self._A.dtype != np.uint8 and np.issubdtype(self._A.dtype,
- np.integer):
- self._A = self._A.astype(np.uint8)
-
- self._imcache = None
- self._rgbacache = None
- self.stale = True
-
- def set_array(self, A):
- """
- Retained for backwards compatibility - use set_data instead
-
- ACCEPTS: numpy array A or PIL Image
- """
- # This also needs to be here to override the inherited
- # cm.ScalarMappable.set_array method so it is not invoked
- # by mistake.
-
- self.set_data(A)
-
- def get_interpolation(self):
- """
- Return the interpolation method the image uses when resizing.
-
- One of 'nearest', 'bilinear', 'bicubic', 'spline16', 'spline36',
- 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric', 'catrom',
- 'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos', or 'none'.
-
- """
- return self._interpolation
-
- def set_interpolation(self, s):
- """
- Set the interpolation method the image uses when resizing.
-
- if None, use a value from rc setting. If 'none', the image is
- shown as is without interpolating. 'none' is only supported in
- agg, ps and pdf backends and will fall back to 'nearest' mode
- for other backends.
-
- .. ACCEPTS: ['nearest' | 'bilinear' | 'bicubic' | 'spline16' |
- 'spline36' | 'hanning' | 'hamming' | 'hermite' | 'kaiser' |
- 'quadric' | 'catrom' | 'gaussian' | 'bessel' | 'mitchell' |
- 'sinc' | 'lanczos' | 'none' ]
-
- """
- if s is None:
- s = rcParams['image.interpolation']
- s = s.lower()
- if s not in _interpd_:
- raise ValueError('Illegal interpolation string')
- self._interpolation = s
- self.stale = True
-
- def can_composite(self):
- """
- Returns `True` if the image can be composited with its neighbors.
- """
- trans = self.get_transform()
- return (
- self._interpolation != 'none' and
- trans.is_affine and
- trans.is_separable)
-
- def set_resample(self, v):
- """
- Set whether or not image resampling is used.
-
- ACCEPTS: True|False
- """
- if v is None:
- v = rcParams['image.resample']
- self._resample = v
- self.stale = True
-
- def get_resample(self):
- """Return the image resample boolean."""
- return self._resample
-
- def set_filternorm(self, filternorm):
- """
- Set whether the resize filter norms the weights -- see
- help for imshow
-
- ACCEPTS: 0 or 1
- """
- if filternorm:
- self._filternorm = 1
- else:
- self._filternorm = 0
-
- self.stale = True
-
- def get_filternorm(self):
- """Return the filternorm setting."""
- return self._filternorm
-
- def set_filterrad(self, filterrad):
- """
- Set the resize filter radius only applicable to some
- interpolation schemes -- see help for imshow
-
- ACCEPTS: positive float
- """
- r = float(filterrad)
- if r <= 0:
- raise ValueError("The filter radius must be a positive number")
- self._filterrad = r
- self.stale = True
-
- def get_filterrad(self):
- """Return the filterrad setting."""
- return self._filterrad
-
-
-class AxesImage(_ImageBase):
- def __str__(self):
- return "AxesImage(%g,%g;%gx%g)" % tuple(self.axes.bbox.bounds)
-
- def __init__(self, ax,
- cmap=None,
- norm=None,
- interpolation=None,
- origin=None,
- extent=None,
- filternorm=1,
- filterrad=4.0,
- resample=False,
- **kwargs
- ):
-
- """
- interpolation and cmap default to their rc settings
-
- cmap is a colors.Colormap instance
- norm is a colors.Normalize instance to map luminance to 0-1
-
- extent is data axes (left, right, bottom, top) for making image plots
- registered with data plots. Default is to label the pixel
- centers with the zero-based row and column indices.
-
- Additional kwargs are matplotlib.artist properties
-
- """
-
- self._extent = extent
-
- super(AxesImage, self).__init__(
- ax,
- cmap=cmap,
- norm=norm,
- interpolation=interpolation,
- origin=origin,
- filternorm=filternorm,
- filterrad=filterrad,
- resample=resample,
- **kwargs
- )
-
- def get_window_extent(self, renderer=None):
- x0, x1, y0, y1 = self._extent
- bbox = Bbox.from_extents([x0, y0, x1, y1])
- return bbox.transformed(self.axes.transData)
-
- def make_image(self, renderer, magnification=1.0, unsampled=False):
- trans = self.get_transform()
- # image is created in the canvas coordinate.
- x1, x2, y1, y2 = self.get_extent()
- bbox = Bbox(np.array([[x1, y1], [x2, y2]]))
- transformed_bbox = TransformedBbox(bbox, trans)
-
- return self._make_image(
- self._A, bbox, transformed_bbox, self.axes.bbox, magnification,
- unsampled=unsampled)
-
- def _check_unsampled_image(self, renderer):
- """
- Return whether the image would be better drawn unsampled.
- """
- return (self.get_interpolation() == "none"
- and renderer.option_scale_image())
-
- def set_extent(self, extent):
- """
- extent is data axes (left, right, bottom, top) for making image plots
-
- This updates ax.dataLim, and, if autoscaling, sets viewLim
- to tightly fit the image, regardless of dataLim. Autoscaling
- state is not changed, so following this with ax.autoscale_view
- will redo the autoscaling in accord with dataLim.
- """
- self._extent = xmin, xmax, ymin, ymax = extent
- corners = (xmin, ymin), (xmax, ymax)
- self.axes.update_datalim(corners)
- self.sticky_edges.x[:] = [xmin, xmax]
- self.sticky_edges.y[:] = [ymin, ymax]
- if self.axes._autoscaleXon:
- self.axes.set_xlim((xmin, xmax), auto=None)
- if self.axes._autoscaleYon:
- self.axes.set_ylim((ymin, ymax), auto=None)
- self.stale = True
-
- def get_extent(self):
- """Get the image extent: left, right, bottom, top"""
- if self._extent is not None:
- return self._extent
- else:
- sz = self.get_size()
- numrows, numcols = sz
- if self.origin == 'upper':
- return (-0.5, numcols-0.5, numrows-0.5, -0.5)
- else:
- return (-0.5, numcols-0.5, -0.5, numrows-0.5)
-
- def get_cursor_data(self, event):
- """Get the cursor data for a given event"""
- xmin, xmax, ymin, ymax = self.get_extent()
- if self.origin == 'upper':
- ymin, ymax = ymax, ymin
- arr = self.get_array()
- data_extent = Bbox([[ymin, xmin], [ymax, xmax]])
- array_extent = Bbox([[0, 0], arr.shape[:2]])
- trans = BboxTransform(boxin=data_extent, boxout=array_extent)
- y, x = event.ydata, event.xdata
- point = trans.transform_point([y, x])
- if any(np.isnan(point)):
- return None
- i, j = point.astype(int)
- # Clip the coordinates at array bounds
- if not (0 <= i < arr.shape[0]) or not (0 <= j < arr.shape[1]):
- return None
- else:
- return arr[i, j]
-
-
-class NonUniformImage(AxesImage):
- def __init__(self, ax, **kwargs):
- """
- kwargs are identical to those for AxesImage, except
- that 'nearest' and 'bilinear' are the only supported 'interpolation'
- options.
- """
- interp = kwargs.pop('interpolation', 'nearest')
- super(NonUniformImage, self).__init__(ax, **kwargs)
- self.set_interpolation(interp)
-
- def _check_unsampled_image(self, renderer):
- """
- return False. Do not use unsampled image.
- """
- return False
-
- def make_image(self, renderer, magnification=1.0, unsampled=False):
- if self._A is None:
- raise RuntimeError('You must first set the image array')
-
- if unsampled:
- raise ValueError('unsampled not supported on NonUniformImage')
-
- A = self._A
- if A.ndim == 2:
- if A.dtype != np.uint8:
- A = self.to_rgba(A, bytes=True)
- self.is_grayscale = self.cmap.is_gray()
- else:
- A = np.repeat(A[:, :, np.newaxis], 4, 2)
- A[:, :, 3] = 255
- self.is_grayscale = True
- else:
- if A.dtype != np.uint8:
- A = (255*A).astype(np.uint8)
- if A.shape[2] == 3:
- B = np.zeros(tuple(list(A.shape[0:2]) + [4]), np.uint8)
- B[:, :, 0:3] = A
- B[:, :, 3] = 255
- A = B
- self.is_grayscale = False
-
- x0, y0, v_width, v_height = self.axes.viewLim.bounds
- l, b, r, t = self.axes.bbox.extents
- width = (np.round(r) + 0.5) - (np.round(l) - 0.5)
- height = (np.round(t) + 0.5) - (np.round(b) - 0.5)
- width *= magnification
- height *= magnification
- im = _image.pcolor(self._Ax, self._Ay, A,
- int(height), int(width),
- (x0, x0+v_width, y0, y0+v_height),
- _interpd_[self._interpolation])
-
- return im, l, b, IdentityTransform()
-
- def set_data(self, x, y, A):
- """
- Set the grid for the pixel centers, and the pixel values.
-
- *x* and *y* are monotonic 1-D ndarrays of lengths N and M,
- respectively, specifying pixel centers
-
- *A* is an (M,N) ndarray or masked array of values to be
- colormapped, or a (M,N,3) RGB array, or a (M,N,4) RGBA
- array.
- """
- x = np.array(x, np.float32)
- y = np.array(y, np.float32)
- A = cbook.safe_masked_invalid(A, copy=True)
- if not (x.ndim == y.ndim == 1 and A.shape[0:2] == y.shape + x.shape):
- raise TypeError("Axes don't match array shape")
- if A.ndim not in [2, 3]:
- raise TypeError("Can only plot 2D or 3D data")
- if A.ndim == 3 and A.shape[2] not in [1, 3, 4]:
- raise TypeError("3D arrays must have three (RGB) "
- "or four (RGBA) color components")
- if A.ndim == 3 and A.shape[2] == 1:
- A.shape = A.shape[0:2]
- self._A = A
- self._Ax = x
- self._Ay = y
- self._imcache = None
-
- self.stale = True
-
- def set_array(self, *args):
- raise NotImplementedError('Method not supported')
-
- def set_interpolation(self, s):
- """
- Parameters
- ----------
- s : str, None
- Either 'nearest', 'bilinear', or ``None``.
- """
- if s is not None and s not in ('nearest', 'bilinear'):
- raise NotImplementedError('Only nearest neighbor and '
- 'bilinear interpolations are supported')
- AxesImage.set_interpolation(self, s)
-
- def get_extent(self):
- if self._A is None:
- raise RuntimeError('Must set data first')
- return self._Ax[0], self._Ax[-1], self._Ay[0], self._Ay[-1]
-
- def set_filternorm(self, s):
- pass
-
- def set_filterrad(self, s):
- pass
-
- def set_norm(self, norm):
- if self._A is not None:
- raise RuntimeError('Cannot change colors after loading data')
- super(NonUniformImage, self).set_norm(norm)
-
- def set_cmap(self, cmap):
- if self._A is not None:
- raise RuntimeError('Cannot change colors after loading data')
- super(NonUniformImage, self).set_cmap(cmap)
-
-
-class PcolorImage(AxesImage):
- """
- Make a pcolor-style plot with an irregular rectangular grid.
-
- This uses a variation of the original irregular image code,
- and it is used by pcolorfast for the corresponding grid type.
- """
- def __init__(self, ax,
- x=None,
- y=None,
- A=None,
- cmap=None,
- norm=None,
- **kwargs
- ):
- """
- cmap defaults to its rc setting
-
- cmap is a colors.Colormap instance
- norm is a colors.Normalize instance to map luminance to 0-1
-
- Additional kwargs are matplotlib.artist properties
- """
- super(PcolorImage, self).__init__(ax, norm=norm, cmap=cmap)
- self.update(kwargs)
- if A is not None:
- self.set_data(x, y, A)
-
- def make_image(self, renderer, magnification=1.0, unsampled=False):
- if self._A is None:
- raise RuntimeError('You must first set the image array')
- if unsampled:
- raise ValueError('unsampled not supported on PColorImage')
- fc = self.axes.patch.get_facecolor()
- bg = mcolors.to_rgba(fc, 0)
- bg = (np.array(bg)*255).astype(np.uint8)
- l, b, r, t = self.axes.bbox.extents
- width = (np.round(r) + 0.5) - (np.round(l) - 0.5)
- height = (np.round(t) + 0.5) - (np.round(b) - 0.5)
- # The extra cast-to-int is only needed for python2
- width = int(np.round(width * magnification))
- height = int(np.round(height * magnification))
- if self._rgbacache is None:
- A = self.to_rgba(self._A, bytes=True)
- self._rgbacache = A
- if self._A.ndim == 2:
- self.is_grayscale = self.cmap.is_gray()
- else:
- A = self._rgbacache
- vl = self.axes.viewLim
- im = _image.pcolor2(self._Ax, self._Ay, A,
- height,
- width,
- (vl.x0, vl.x1, vl.y0, vl.y1),
- bg)
- return im, l, b, IdentityTransform()
-
- def _check_unsampled_image(self, renderer):
- return False
-
- def set_data(self, x, y, A):
- """
- Set the grid for the rectangle boundaries, and the data values.
-
- *x* and *y* are monotonic 1-D ndarrays of lengths N+1 and M+1,
- respectively, specifying rectangle boundaries. If None,
- they will be created as uniform arrays from 0 through N
- and 0 through M, respectively.
-
- *A* is an (M,N) ndarray or masked array of values to be
- colormapped, or a (M,N,3) RGB array, or a (M,N,4) RGBA
- array.
-
- """
- A = cbook.safe_masked_invalid(A, copy=True)
- if x is None:
- x = np.arange(0, A.shape[1]+1, dtype=np.float64)
- else:
- x = np.array(x, np.float64).ravel()
- if y is None:
- y = np.arange(0, A.shape[0]+1, dtype=np.float64)
- else:
- y = np.array(y, np.float64).ravel()
-
- if A.shape[:2] != (y.size-1, x.size-1):
- raise ValueError(
- "Axes don't match array shape. Got %s, expected %s." %
- (A.shape[:2], (y.size - 1, x.size - 1)))
- if A.ndim not in [2, 3]:
- raise ValueError("A must be 2D or 3D")
- if A.ndim == 3 and A.shape[2] == 1:
- A.shape = A.shape[:2]
- self.is_grayscale = False
- if A.ndim == 3:
- if A.shape[2] in [3, 4]:
- if ((A[:, :, 0] == A[:, :, 1]).all() and
- (A[:, :, 0] == A[:, :, 2]).all()):
- self.is_grayscale = True
- else:
- raise ValueError("3D arrays must have RGB or RGBA as last dim")
-
- # For efficient cursor readout, ensure x and y are increasing.
- if x[-1] < x[0]:
- x = x[::-1]
- A = A[:, ::-1]
- if y[-1] < y[0]:
- y = y[::-1]
- A = A[::-1]
-
- self._A = A
- self._Ax = x
- self._Ay = y
- self._rgbacache = None
- self.stale = True
-
- def set_array(self, *args):
- raise NotImplementedError('Method not supported')
-
- def get_cursor_data(self, event):
- """Get the cursor data for a given event"""
- x, y = event.xdata, event.ydata
- if (x < self._Ax[0] or x > self._Ax[-1] or
- y < self._Ay[0] or y > self._Ay[-1]):
- return None
- j = np.searchsorted(self._Ax, x) - 1
- i = np.searchsorted(self._Ay, y) - 1
- try:
- return self._A[i, j]
- except IndexError:
- return None
-
-
-class FigureImage(_ImageBase):
- zorder = 0
-
- _interpolation = 'nearest'
-
- def __init__(self, fig,
- cmap=None,
- norm=None,
- offsetx=0,
- offsety=0,
- origin=None,
- **kwargs
- ):
- """
- cmap is a colors.Colormap instance
- norm is a colors.Normalize instance to map luminance to 0-1
-
- kwargs are an optional list of Artist keyword args
- """
- super(FigureImage, self).__init__(
- None,
- norm=norm,
- cmap=cmap,
- origin=origin
- )
- self.figure = fig
- self.ox = offsetx
- self.oy = offsety
- self.update(kwargs)
- self.magnification = 1.0
-
- def get_extent(self):
- """Get the image extent: left, right, bottom, top"""
- numrows, numcols = self.get_size()
- return (-0.5 + self.ox, numcols-0.5 + self.ox,
- -0.5 + self.oy, numrows-0.5 + self.oy)
-
- def make_image(self, renderer, magnification=1.0, unsampled=False):
- fac = renderer.dpi/self.figure.dpi
- # fac here is to account for pdf, eps, svg backends where
- # figure.dpi is set to 72. This means we need to scale the
- # image (using magification) and offset it appropriately.
- bbox = Bbox([[self.ox/fac, self.oy/fac],
- [(self.ox/fac + self._A.shape[1]),
- (self.oy/fac + self._A.shape[0])]])
- width, height = self.figure.get_size_inches()
- width *= renderer.dpi
- height *= renderer.dpi
- clip = Bbox([[0, 0], [width, height]])
-
- return self._make_image(
- self._A, bbox, bbox, clip, magnification=magnification / fac,
- unsampled=unsampled, round_to_pixel_border=False)
-
- def set_data(self, A):
- """Set the image array."""
- cm.ScalarMappable.set_array(self,
- cbook.safe_masked_invalid(A, copy=True))
- self.stale = True
-
-
-class BboxImage(_ImageBase):
- """The Image class whose size is determined by the given bbox."""
- def __init__(self, bbox,
- cmap=None,
- norm=None,
- interpolation=None,
- origin=None,
- filternorm=1,
- filterrad=4.0,
- resample=False,
- interp_at_native=True,
- **kwargs
- ):
- """
- cmap is a colors.Colormap instance
- norm is a colors.Normalize instance to map luminance to 0-1
-
- interp_at_native is a flag that determines whether or not
- interpolation should still be applied when the image is
- displayed at its native resolution. A common use case for this
- is when displaying an image for annotational purposes; it is
- treated similarly to Photoshop (interpolation is only used when
- displaying the image at non-native resolutions).
-
-
- kwargs are an optional list of Artist keyword args
-
- """
- super(BboxImage, self).__init__(
- None,
- cmap=cmap,
- norm=norm,
- interpolation=interpolation,
- origin=origin,
- filternorm=filternorm,
- filterrad=filterrad,
- resample=resample,
- **kwargs
- )
-
- self.bbox = bbox
- self.interp_at_native = interp_at_native
- self._transform = IdentityTransform()
-
- def get_transform(self):
- return self._transform
-
- def get_window_extent(self, renderer=None):
- if renderer is None:
- renderer = self.get_figure()._cachedRenderer
-
- if isinstance(self.bbox, BboxBase):
- return self.bbox
- elif callable(self.bbox):
- return self.bbox(renderer)
- else:
- raise ValueError("unknown type of bbox")
-
- def contains(self, mouseevent):
- """Test whether the mouse event occurred within the image."""
- if callable(self._contains):
- return self._contains(self, mouseevent)
-
- if not self.get_visible(): # or self.get_figure()._renderer is None:
- return False, {}
-
- x, y = mouseevent.x, mouseevent.y
- inside = self.get_window_extent().contains(x, y)
-
- return inside, {}
-
- def make_image(self, renderer, magnification=1.0, unsampled=False):
- width, height = renderer.get_canvas_width_height()
-
- bbox_in = self.get_window_extent(renderer).frozen()
- bbox_in._points /= [width, height]
- bbox_out = self.get_window_extent(renderer)
- clip = Bbox([[0, 0], [width, height]])
- self._transform = BboxTransform(Bbox([[0, 0], [1, 1]]), clip)
-
- return self._make_image(
- self._A,
- bbox_in, bbox_out, clip, magnification, unsampled=unsampled)
-
-
-def imread(fname, format=None):
- """
- Read an image from a file into an array.
-
- *fname* may be a string path, a valid URL, or a Python
- file-like object. If using a file object, it must be opened in binary
- mode.
-
- If *format* is provided, will try to read file of that type,
- otherwise the format is deduced from the filename. If nothing can
- be deduced, PNG is tried.
-
- Return value is a :class:`numpy.array`. For grayscale images, the
- return array is MxN. For RGB images, the return value is MxNx3.
- For RGBA images the return value is MxNx4.
-
- matplotlib can only read PNGs natively, but if `PIL
- <http://www.pythonware.com/products/pil/>`_ is installed, it will
- use it to load the image and return an array (if possible) which
- can be used with :func:`~matplotlib.pyplot.imshow`. Note, URL strings
- may not be compatible with PIL. Check the PIL documentation for more
- information.
- """
-
- def pilread(fname):
- """try to load the image with PIL or return None"""
- try:
- from PIL import Image
- except ImportError:
- return None
- with Image.open(fname) as image:
- return pil_to_array(image)
-
- handlers = {'png': _png.read_png, }
- if format is None:
- if isinstance(fname, six.string_types):
- parsed = urlparse(fname)
- # If the string is a URL, assume png
- if len(parsed.scheme) > 1:
- ext = 'png'
- else:
- basename, ext = os.path.splitext(fname)
- ext = ext.lower()[1:]
- elif hasattr(fname, 'name'):
- basename, ext = os.path.splitext(fname.name)
- ext = ext.lower()[1:]
- else:
- ext = 'png'
- else:
- ext = format
-
- if ext not in handlers:
- im = pilread(fname)
- if im is None:
- raise ValueError('Only know how to handle extensions: %s; '
- 'with Pillow installed matplotlib can handle '
- 'more images' % list(handlers))
- return im
-
- handler = handlers[ext]
-
- # To handle Unicode filenames, we pass a file object to the PNG
- # reader extension, since Python handles them quite well, but it's
- # tricky in C.
- if isinstance(fname, six.string_types):
- parsed = urlparse(fname)
- # If fname is a URL, download the data
- if len(parsed.scheme) > 1:
- fd = BytesIO(urlopen(fname).read())
- return handler(fd)
- else:
- with open(fname, 'rb') as fd:
- return handler(fd)
- else:
- return handler(fname)
-
-
-def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None,
- origin=None, dpi=100):
- """
- Save an array as in image file.
-
- The output formats available depend on the backend being used.
-
- Parameters
- ----------
- fname : str or file-like
- Path string to a filename, or a Python file-like object.
- If *format* is *None* and *fname* is a string, the output
- format is deduced from the extension of the filename.
- arr : array-like
- An MxN (luminance), MxNx3 (RGB) or MxNx4 (RGBA) array.
- vmin, vmax: [ None | scalar ]
- *vmin* and *vmax* set the color scaling for the image by fixing the
- values that map to the colormap color limits. If either *vmin*
- or *vmax* is None, that limit is determined from the *arr*
- min/max value.
- cmap : matplotlib.colors.Colormap, optional
- For example, ``cm.viridis``. If ``None``, defaults to the
- ``image.cmap`` rcParam.
- format : str
- One of the file extensions supported by the active backend. Most
- backends support png, pdf, ps, eps and svg.
- origin : [ 'upper' | 'lower' ]
- Indicates whether the ``(0, 0)`` index of the array is in the
- upper left or lower left corner of the axes. Defaults to the
- ``image.origin`` rcParam.
- dpi : int
- The DPI to store in the metadata of the file. This does not affect the
- resolution of the output image.
- """
- from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
- from matplotlib.figure import Figure
- if isinstance(fname, getattr(os, "PathLike", ())):
- fname = os.fspath(fname)
- if (format == 'png'
- or (format is None
- and isinstance(fname, six.string_types)
- and fname.lower().endswith('.png'))):
- image = AxesImage(None, cmap=cmap, origin=origin)
- image.set_data(arr)
- image.set_clim(vmin, vmax)
- image.write_png(fname)
- else:
- fig = Figure(dpi=dpi, frameon=False)
- FigureCanvas(fig)
- fig.figimage(arr, cmap=cmap, vmin=vmin, vmax=vmax, origin=origin,
- resize=True)
- fig.savefig(fname, dpi=dpi, format=format, transparent=True)
-
-
-def pil_to_array(pilImage):
- """Load a PIL image and return it as a numpy array.
-
- Grayscale images are returned as ``(M, N)`` arrays. RGB images are
- returned as ``(M, N, 3)`` arrays. RGBA images are returned as ``(M, N,
- 4)`` arrays.
- """
- if pilImage.mode in ['RGBA', 'RGBX', 'RGB', 'L']:
- # return MxNx4 RGBA, MxNx3 RBA, or MxN luminance array
- return np.asarray(pilImage)
- elif pilImage.mode.startswith('I;16'):
- # return MxN luminance array of uint16
- raw = pilImage.tobytes('raw', pilImage.mode)
- if pilImage.mode.endswith('B'):
- x = np.frombuffer(raw, '>u2')
- else:
- x = np.frombuffer(raw, '<u2')
- return x.reshape(pilImage.size[::-1]).astype('=u2')
- else: # try to convert to an rgba image
- try:
- pilImage = pilImage.convert('RGBA')
- except ValueError:
- raise RuntimeError('Unknown image mode')
- return np.asarray(pilImage) # return MxNx4 RGBA array
-
-
-def thumbnail(infile, thumbfile, scale=0.1, interpolation='bilinear',
- preview=False):
- """
- make a thumbnail of image in *infile* with output filename
- *thumbfile*.
-
- *infile* the image file -- must be PNG or Pillow-readable if you
- have `Pillow <http://python-pillow.org/>`_ installed
-
- *thumbfile*
- the thumbnail filename
-
- *scale*
- the scale factor for the thumbnail
-
- *interpolation*
- the interpolation scheme used in the resampling
-
-
- *preview*
- if True, the default backend (presumably a user interface
- backend) will be used which will cause a figure to be raised
- if :func:`~matplotlib.pyplot.show` is called. If it is False,
- a pure image backend will be used depending on the extension,
- 'png'->FigureCanvasAgg, 'pdf'->FigureCanvasPdf,
- 'svg'->FigureCanvasSVG
-
-
- See examples/misc/image_thumbnail.py.
-
- .. htmlonly::
-
- :ref:`sphx_glr_gallery_misc_image_thumbnail_sgskip.py`
-
- Return value is the figure instance containing the thumbnail
-
- """
- basedir, basename = os.path.split(infile)
- baseout, extout = os.path.splitext(thumbfile)
-
- im = imread(infile)
- rows, cols, depth = im.shape
-
- # this doesn't really matter, it will cancel in the end, but we
- # need it for the mpl API
- dpi = 100
-
- height = rows / dpi * scale
- width = cols / dpi * scale
-
- extension = extout.lower()
-
- if preview:
- # let the UI backend do everything
- import matplotlib.pyplot as plt
- fig = plt.figure(figsize=(width, height), dpi=dpi)
- else:
- if extension == '.png':
- from matplotlib.backends.backend_agg \
- import FigureCanvasAgg as FigureCanvas
- elif extension == '.pdf':
- from matplotlib.backends.backend_pdf \
- import FigureCanvasPdf as FigureCanvas
- elif extension == '.svg':
- from matplotlib.backends.backend_svg \
- import FigureCanvasSVG as FigureCanvas
- else:
- raise ValueError("Can only handle "
- "extensions 'png', 'svg' or 'pdf'")
-
- from matplotlib.figure import Figure
- fig = Figure(figsize=(width, height), dpi=dpi)
- FigureCanvas(fig)
-
- ax = fig.add_axes([0, 0, 1, 1], aspect='auto',
- frameon=False, xticks=[], yticks=[])
-
- basename, ext = os.path.splitext(basename)
- ax.imshow(im, aspect='auto', resample=True, interpolation=interpolation)
- fig.savefig(thumbfile, dpi=dpi)
- return fig
diff --git a/contrib/python/matplotlib/py2/matplotlib/legend.py b/contrib/python/matplotlib/py2/matplotlib/legend.py
deleted file mode 100644
index 4e48a95091..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/legend.py
+++ /dev/null
@@ -1,1401 +0,0 @@
-"""
-The legend module defines the Legend class, which is responsible for
-drawing legends associated with axes and/or figures.
-
-.. important::
-
- It is unlikely that you would ever create a Legend instance
- manually. Most users would normally create a legend via the
- :meth:`~matplotlib.axes.Axes.legend` function. For more details on legends
- there is also a :doc:`legend guide </tutorials/intermediate/legend_guide>`.
-
-The Legend class can be considered as a container of legend handles and
-legend texts. Creation of corresponding legend handles from the plot elements
-in the axes or figures (e.g., lines, patches, etc.) are specified by the
-handler map, which defines the mapping between the plot elements and the
-legend handlers to be used (the default legend handlers are defined in the
-:mod:`~matplotlib.legend_handler` module). Note that not all kinds of
-artist are supported by the legend yet by default but it is possible to
-extend the legend handler's capabilities to support arbitrary objects. See
-the :doc:`legend guide </tutorials/intermediate/legend_guide>` for more
-information.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import logging
-import warnings
-
-import numpy as np
-
-from matplotlib import rcParams
-from matplotlib import docstring
-from matplotlib.artist import Artist, allow_rasterization
-from matplotlib.cbook import silent_list, is_hashable
-import matplotlib.colors as colors
-from matplotlib.font_manager import FontProperties
-from matplotlib.lines import Line2D
-from matplotlib.patches import Patch, Rectangle, Shadow, FancyBboxPatch
-from matplotlib.collections import (LineCollection, RegularPolyCollection,
- CircleCollection, PathCollection,
- PolyCollection)
-from matplotlib.transforms import Bbox, BboxBase, TransformedBbox
-from matplotlib.transforms import BboxTransformTo, BboxTransformFrom
-
-from matplotlib.offsetbox import HPacker, VPacker, TextArea, DrawingArea
-from matplotlib.offsetbox import DraggableOffsetBox
-
-from matplotlib.container import ErrorbarContainer, BarContainer, StemContainer
-from . import legend_handler
-
-
-class DraggableLegend(DraggableOffsetBox):
- def __init__(self, legend, use_blit=False, update="loc"):
- """
- Parameters
- ----------
- update : string
- If "loc", update *loc* parameter of legend upon finalizing.
- If "bbox", update *bbox_to_anchor* parameter.
- """
- self.legend = legend
-
- if update in ["loc", "bbox"]:
- self._update = update
- else:
- raise ValueError("update parameter '%s' is not supported." %
- update)
-
- DraggableOffsetBox.__init__(self, legend, legend._legend_box,
- use_blit=use_blit)
-
- def artist_picker(self, legend, evt):
- return self.legend.contains(evt)
-
- def finalize_offset(self):
- loc_in_canvas = self.get_loc_in_canvas()
-
- if self._update == "loc":
- self._update_loc(loc_in_canvas)
- elif self._update == "bbox":
- self._update_bbox_to_anchor(loc_in_canvas)
- else:
- raise RuntimeError("update parameter '%s' is not supported." %
- self.update)
-
- def _update_loc(self, loc_in_canvas):
- bbox = self.legend.get_bbox_to_anchor()
-
- # if bbox has zero width or height, the transformation is
- # ill-defined. Fall back to the defaul bbox_to_anchor.
- if bbox.width == 0 or bbox.height == 0:
- self.legend.set_bbox_to_anchor(None)
- bbox = self.legend.get_bbox_to_anchor()
-
- _bbox_transform = BboxTransformFrom(bbox)
- self.legend._loc = tuple(
- _bbox_transform.transform_point(loc_in_canvas)
- )
-
- def _update_bbox_to_anchor(self, loc_in_canvas):
-
- tr = self.legend.axes.transAxes
- loc_in_bbox = tr.transform_point(loc_in_canvas)
-
- self.legend.set_bbox_to_anchor(loc_in_bbox)
-
-
-_legend_kw_doc = '''
-loc : int or string or pair of floats, default: :rc:`legend.loc` ('best' for \
-axes, 'upper right' for figures)
- The location of the legend. Possible codes are:
-
- =============== =============
- Location String Location Code
- =============== =============
- 'best' 0
- 'upper right' 1
- 'upper left' 2
- 'lower left' 3
- 'lower right' 4
- 'right' 5
- 'center left' 6
- 'center right' 7
- 'lower center' 8
- 'upper center' 9
- 'center' 10
- =============== =============
-
-
- Alternatively can be a 2-tuple giving ``x, y`` of the lower-left
- corner of the legend in axes coordinates (in which case
- ``bbox_to_anchor`` will be ignored).
-
-bbox_to_anchor : `.BboxBase` or pair of floats
- Specify any arbitrary location for the legend in `bbox_transform`
- coordinates (default Axes coordinates).
-
- For example, to put the legend's upper right hand corner in the
- center of the axes the following keywords can be used::
-
- loc='upper right', bbox_to_anchor=(0.5, 0.5)
-
-ncol : integer
- The number of columns that the legend has. Default is 1.
-
-prop : None or :class:`matplotlib.font_manager.FontProperties` or dict
- The font properties of the legend. If None (default), the current
- :data:`matplotlib.rcParams` will be used.
-
-fontsize : int or float or {'xx-small', 'x-small', 'small', 'medium', \
-'large', 'x-large', 'xx-large'}
- Controls the font size of the legend. If the value is numeric the
- size will be the absolute font size in points. String values are
- relative to the current default font size. This argument is only
- used if `prop` is not specified.
-
-numpoints : None or int
- The number of marker points in the legend when creating a legend
- entry for a `.Line2D` (line).
- Default is ``None``, which will take the value from
- :rc:`legend.numpoints`.
-
-scatterpoints : None or int
- The number of marker points in the legend when creating
- a legend entry for a `.PathCollection` (scatter plot).
- Default is ``None``, which will take the value from
- :rc:`legend.scatterpoints`.
-
-scatteryoffsets : iterable of floats
- The vertical offset (relative to the font size) for the markers
- created for a scatter plot legend entry. 0.0 is at the base the
- legend text, and 1.0 is at the top. To draw all markers at the
- same height, set to ``[0.5]``. Default is ``[0.375, 0.5, 0.3125]``.
-
-markerscale : None or int or float
- The relative size of legend markers compared with the originally
- drawn ones.
- Default is ``None``, which will take the value from
- :rc:`legend.markerscale`.
-
-markerfirst : bool
- If *True*, legend marker is placed to the left of the legend label.
- If *False*, legend marker is placed to the right of the legend
- label.
- Default is *True*.
-
-frameon : None or bool
- Control whether the legend should be drawn on a patch
- (frame).
- Default is ``None``, which will take the value from
- :rc:`legend.frameon`.
-
-fancybox : None or bool
- Control whether round edges should be enabled around the
- :class:`~matplotlib.patches.FancyBboxPatch` which makes up the
- legend's background.
- Default is ``None``, which will take the value from
- :rc:`legend.fancybox`.
-
-shadow : None or bool
- Control whether to draw a shadow behind the legend.
- Default is ``None``, which will take the value from
- :rc:`legend.shadow`.
-
-framealpha : None or float
- Control the alpha transparency of the legend's background.
- Default is ``None``, which will take the value from
- :rc:`legend.framealpha`. If shadow is activated and
- *framealpha* is ``None``, the default value is ignored.
-
-facecolor : None or "inherit" or a color spec
- Control the legend's background color.
- Default is ``None``, which will take the value from
- :rc:`legend.facecolor`. If ``"inherit"``, it will take
- :rc:`axes.facecolor`.
-
-edgecolor : None or "inherit" or a color spec
- Control the legend's background patch edge color.
- Default is ``None``, which will take the value from
- :rc:`legend.edgecolor` If ``"inherit"``, it will take
- :rc:`axes.edgecolor`.
-
-mode : {"expand", None}
- If `mode` is set to ``"expand"`` the legend will be horizontally
- expanded to fill the axes area (or `bbox_to_anchor` if defines
- the legend's size).
-
-bbox_transform : None or :class:`matplotlib.transforms.Transform`
- The transform for the bounding box (`bbox_to_anchor`). For a value
- of ``None`` (default) the Axes'
- :data:`~matplotlib.axes.Axes.transAxes` transform will be used.
-
-title : str or None
- The legend's title. Default is no title (``None``).
-
-borderpad : float or None
- The fractional whitespace inside the legend border.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.borderpad`.
-
-labelspacing : float or None
- The vertical space between the legend entries.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.labelspacing`.
-
-handlelength : float or None
- The length of the legend handles.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.handlelength`.
-
-handletextpad : float or None
- The pad between the legend handle and text.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.handletextpad`.
-
-borderaxespad : float or None
- The pad between the axes and legend border.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.borderaxespad`.
-
-columnspacing : float or None
- The spacing between columns.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.columnspacing`.
-
-handler_map : dict or None
- The custom dictionary mapping instances or types to a legend
- handler. This `handler_map` updates the default handler map
- found at :func:`matplotlib.legend.Legend.get_legend_handler_map`.
-
-'''
-docstring.interpd.update(_legend_kw_doc=_legend_kw_doc)
-
-
-class Legend(Artist):
- """
- Place a legend on the axes at location loc.
-
- """
- codes = {'best': 0, # only implemented for axes legends
- 'upper right': 1,
- 'upper left': 2,
- 'lower left': 3,
- 'lower right': 4,
- 'right': 5,
- 'center left': 6,
- 'center right': 7,
- 'lower center': 8,
- 'upper center': 9,
- 'center': 10,
- }
-
- zorder = 5
-
- def __str__(self):
- return "Legend"
-
- @docstring.dedent_interpd
- def __init__(self, parent, handles, labels,
- loc=None,
- numpoints=None, # the number of points in the legend line
- markerscale=None, # the relative size of legend markers
- # vs. original
- markerfirst=True, # controls ordering (left-to-right) of
- # legend marker and label
- scatterpoints=None, # number of scatter points
- scatteryoffsets=None,
- prop=None, # properties for the legend texts
- fontsize=None, # keyword to set font size directly
-
- # spacing & pad defined as a fraction of the font-size
- borderpad=None, # the whitespace inside the legend border
- labelspacing=None, # the vertical space between the legend
- # entries
- handlelength=None, # the length of the legend handles
- handleheight=None, # the height of the legend handles
- handletextpad=None, # the pad between the legend handle
- # and text
- borderaxespad=None, # the pad between the axes and legend
- # border
- columnspacing=None, # spacing between columns
-
- ncol=1, # number of columns
- mode=None, # mode for horizontal distribution of columns.
- # None, "expand"
-
- fancybox=None, # True use a fancy box, false use a rounded
- # box, none use rc
- shadow=None,
- title=None, # set a title for the legend
-
- framealpha=None, # set frame alpha
- edgecolor=None, # frame patch edgecolor
- facecolor=None, # frame patch facecolor
-
- bbox_to_anchor=None, # bbox that the legend will be anchored.
- bbox_transform=None, # transform for the bbox
- frameon=None, # draw frame
- handler_map=None,
- ):
- """
-
- Parameters
- ----------
- parent : `~matplotlib.axes.Axes` or `.Figure`
- The artist that contains the legend.
-
- handles : sequence of `.Artist`
- A list of Artists (lines, patches) to be added to the legend.
-
- labels : sequence of strings
- A list of labels to show next to the artists. The length of handles
- and labels should be the same. If they are not, they are truncated
- to the smaller of both lengths.
-
- Other Parameters
- ----------------
-
- loc : int or string or pair of floats, default: 'upper right'
- The location of the legend. Possible codes are:
-
- =============== =============
- Location String Location Code
- =============== =============
- 'best' 0
- 'upper right' 1
- 'upper left' 2
- 'lower left' 3
- 'lower right' 4
- 'right' 5
- 'center left' 6
- 'center right' 7
- 'lower center' 8
- 'upper center' 9
- 'center' 10
- =============== =============
-
-
- Alternatively can be a 2-tuple giving ``x, y`` of the lower-left
- corner of the legend in axes coordinates (in which case
- ``bbox_to_anchor`` will be ignored).
-
- bbox_to_anchor : `.BboxBase` or pair of floats
- Specify any arbitrary location for the legend in `bbox_transform`
- coordinates (default Axes coordinates).
-
- For example, to put the legend's upper right hand corner in the
- center of the axes the following keywords can be used::
-
- loc='upper right', bbox_to_anchor=(0.5, 0.5)
-
- ncol : integer
- The number of columns that the legend has. Default is 1.
-
- prop : None or :class:`matplotlib.font_manager.FontProperties` or dict
- The font properties of the legend. If None (default), the current
- :data:`matplotlib.rcParams` will be used.
-
- fontsize : int or float or {'xx-small', 'x-small', 'small', 'medium', \
-'large', 'x-large', 'xx-large'}
- Controls the font size of the legend. If the value is numeric the
- size will be the absolute font size in points. String values are
- relative to the current default font size. This argument is only
- used if `prop` is not specified.
-
- numpoints : None or int
- The number of marker points in the legend when creating a legend
- entry for a `.Line2D` (line).
- Default is ``None``, which will take the value from
- :rc:`legend.numpoints`.
-
- scatterpoints : None or int
- The number of marker points in the legend when creating
- a legend entry for a `.PathCollection` (scatter plot).
- Default is ``None``, which will take the value from
- :rc:`legend.scatterpoints`.
-
- scatteryoffsets : iterable of floats
- The vertical offset (relative to the font size) for the markers
- created for a scatter plot legend entry. 0.0 is at the base the
- legend text, and 1.0 is at the top. To draw all markers at the
- same height, set to ``[0.5]``. Default is ``[0.375, 0.5, 0.3125]``.
-
- markerscale : None or int or float
- The relative size of legend markers compared with the originally
- drawn ones.
- Default is ``None``, which will take the value from
- :rc:`legend.markerscale`.
-
- markerfirst : bool
- If *True*, legend marker is placed to the left of the legend label.
- If *False*, legend marker is placed to the right of the legend
- label.
- Default is *True*.
-
- frameon : None or bool
- Control whether the legend should be drawn on a patch
- (frame).
- Default is ``None``, which will take the value from
- :rc:`legend.frameon`.
-
- fancybox : None or bool
- Control whether round edges should be enabled around the
- :class:`~matplotlib.patches.FancyBboxPatch` which makes up the
- legend's background.
- Default is ``None``, which will take the value from
- :rc:`legend.fancybox`.
-
- shadow : None or bool
- Control whether to draw a shadow behind the legend.
- Default is ``None``, which will take the value from
- :rc:`legend.shadow`.
-
- framealpha : None or float
- Control the alpha transparency of the legend's background.
- Default is ``None``, which will take the value from
- :rc:`legend.framealpha`. If shadow is activated and
- *framealpha* is ``None``, the default value is ignored.
-
- facecolor : None or "inherit" or a color spec
- Control the legend's background color.
- Default is ``None``, which will take the value from
- :rc:`legend.facecolor`. If ``"inherit"``, it will take
- :rc:`axes.facecolor`.
-
- edgecolor : None or "inherit" or a color spec
- Control the legend's background patch edge color.
- Default is ``None``, which will take the value from
- :rc:`legend.edgecolor` If ``"inherit"``, it will take
- :rc:`axes.edgecolor`.
-
- mode : {"expand", None}
- If `mode` is set to ``"expand"`` the legend will be horizontally
- expanded to fill the axes area (or `bbox_to_anchor` if defines
- the legend's size).
-
- bbox_transform : None or :class:`matplotlib.transforms.Transform`
- The transform for the bounding box (`bbox_to_anchor`). For a value
- of ``None`` (default) the Axes'
- :data:`~matplotlib.axes.Axes.transAxes` transform will be used.
-
- title : str or None
- The legend's title. Default is no title (``None``).
-
- borderpad : float or None
- The fractional whitespace inside the legend border.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.borderpad`.
-
- labelspacing : float or None
- The vertical space between the legend entries.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.labelspacing`.
-
- handlelength : float or None
- The length of the legend handles.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.handlelength`.
-
- handletextpad : float or None
- The pad between the legend handle and text.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.handletextpad`.
-
- borderaxespad : float or None
- The pad between the axes and legend border.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.borderaxespad`.
-
- columnspacing : float or None
- The spacing between columns.
- Measured in font-size units.
- Default is ``None``, which will take the value from
- :rc:`legend.columnspacing`.
-
- handler_map : dict or None
- The custom dictionary mapping instances or types to a legend
- handler. This `handler_map` updates the default handler map
- found at :func:`matplotlib.legend.Legend.get_legend_handler_map`.
-
- Notes
- -----
-
- Users can specify any arbitrary location for the legend using the
- *bbox_to_anchor* keyword argument. bbox_to_anchor can be an instance
- of BboxBase(or its derivatives) or a tuple of 2 or 4 floats.
- See :meth:`set_bbox_to_anchor` for more detail.
-
- The legend location can be specified by setting *loc* with a tuple of
- 2 floats, which is interpreted as the lower-left corner of the legend
- in the normalized axes coordinate.
- """
- # local import only to avoid circularity
- from matplotlib.axes import Axes
- from matplotlib.figure import Figure
-
- Artist.__init__(self)
-
- if prop is None:
- if fontsize is not None:
- self.prop = FontProperties(size=fontsize)
- else:
- self.prop = FontProperties(size=rcParams["legend.fontsize"])
- elif isinstance(prop, dict):
- self.prop = FontProperties(**prop)
- if "size" not in prop:
- self.prop.set_size(rcParams["legend.fontsize"])
- else:
- self.prop = prop
-
- self._fontsize = self.prop.get_size_in_points()
-
- self.texts = []
- self.legendHandles = []
- self._legend_title_box = None
-
- #: A dictionary with the extra handler mappings for this Legend
- #: instance.
- self._custom_handler_map = handler_map
-
- locals_view = locals()
- for name in ["numpoints", "markerscale", "shadow", "columnspacing",
- "scatterpoints", "handleheight", 'borderpad',
- 'labelspacing', 'handlelength', 'handletextpad',
- 'borderaxespad']:
- if locals_view[name] is None:
- value = rcParams["legend." + name]
- else:
- value = locals_view[name]
- setattr(self, name, value)
- del locals_view
- # trim handles and labels if illegal label...
- _lab, _hand = [], []
- for label, handle in zip(labels, handles):
- if (isinstance(label, six.string_types) and
- label.startswith('_')):
- warnings.warn('The handle {!r} has a label of {!r} which '
- 'cannot be automatically added to the '
- 'legend.'.format(handle, label))
- else:
- _lab.append(label)
- _hand.append(handle)
- labels, handles = _lab, _hand
-
- handles = list(handles)
- if len(handles) < 2:
- ncol = 1
- self._ncol = ncol
-
- if self.numpoints <= 0:
- raise ValueError("numpoints must be > 0; it was %d" % numpoints)
-
- # introduce y-offset for handles of the scatter plot
- if scatteryoffsets is None:
- self._scatteryoffsets = np.array([3. / 8., 4. / 8., 2.5 / 8.])
- else:
- self._scatteryoffsets = np.asarray(scatteryoffsets)
- reps = self.scatterpoints // len(self._scatteryoffsets) + 1
- self._scatteryoffsets = np.tile(self._scatteryoffsets,
- reps)[:self.scatterpoints]
-
- # _legend_box is an OffsetBox instance that contains all
- # legend items and will be initialized from _init_legend_box()
- # method.
- self._legend_box = None
-
- if isinstance(parent, Axes):
- self.isaxes = True
- self.axes = parent
- self.set_figure(parent.figure)
- elif isinstance(parent, Figure):
- self.isaxes = False
- self.set_figure(parent)
- else:
- raise TypeError("Legend needs either Axes or Figure as parent")
- self.parent = parent
-
- if loc is None:
- loc = rcParams["legend.loc"]
- if not self.isaxes and loc in [0, 'best']:
- loc = 'upper right'
- if isinstance(loc, six.string_types):
- if loc not in self.codes:
- if self.isaxes:
- warnings.warn('Unrecognized location "%s". Falling back '
- 'on "best"; valid locations are\n\t%s\n'
- % (loc, '\n\t'.join(self.codes)))
- loc = 0
- else:
- warnings.warn('Unrecognized location "%s". Falling back '
- 'on "upper right"; '
- 'valid locations are\n\t%s\n'
- % (loc, '\n\t'.join(self.codes)))
- loc = 1
- else:
- loc = self.codes[loc]
- if not self.isaxes and loc == 0:
- warnings.warn('Automatic legend placement (loc="best") not '
- 'implemented for figure legend. '
- 'Falling back on "upper right".')
- loc = 1
-
- self._mode = mode
- self.set_bbox_to_anchor(bbox_to_anchor, bbox_transform)
-
- # We use FancyBboxPatch to draw a legend frame. The location
- # and size of the box will be updated during the drawing time.
-
- if facecolor is None:
- facecolor = rcParams["legend.facecolor"]
- if facecolor == 'inherit':
- facecolor = rcParams["axes.facecolor"]
-
- if edgecolor is None:
- edgecolor = rcParams["legend.edgecolor"]
- if edgecolor == 'inherit':
- edgecolor = rcParams["axes.edgecolor"]
-
- self.legendPatch = FancyBboxPatch(
- xy=(0.0, 0.0), width=1., height=1.,
- facecolor=facecolor,
- edgecolor=edgecolor,
- mutation_scale=self._fontsize,
- snap=True
- )
-
- # The width and height of the legendPatch will be set (in the
- # draw()) to the length that includes the padding. Thus we set
- # pad=0 here.
- if fancybox is None:
- fancybox = rcParams["legend.fancybox"]
-
- if fancybox:
- self.legendPatch.set_boxstyle("round", pad=0,
- rounding_size=0.2)
- else:
- self.legendPatch.set_boxstyle("square", pad=0)
-
- self._set_artist_props(self.legendPatch)
-
- self._drawFrame = frameon
- if frameon is None:
- self._drawFrame = rcParams["legend.frameon"]
-
- # init with null renderer
- self._init_legend_box(handles, labels, markerfirst)
-
- # If shadow is activated use framealpha if not
- # explicitly passed. See Issue 8943
- if framealpha is None:
- if shadow:
- self.get_frame().set_alpha(1)
- else:
- self.get_frame().set_alpha(rcParams["legend.framealpha"])
- else:
- self.get_frame().set_alpha(framealpha)
-
- self._loc = loc
- self.set_title(title)
- self._last_fontsize_points = self._fontsize
- self._draggable = None
-
- def _set_artist_props(self, a):
- """
- Set the boilerplate props for artists added to axes.
- """
- a.set_figure(self.figure)
- if self.isaxes:
- # a.set_axes(self.axes)
- a.axes = self.axes
-
- a.set_transform(self.get_transform())
-
- def _set_loc(self, loc):
- # find_offset function will be provided to _legend_box and
- # _legend_box will draw itself at the location of the return
- # value of the find_offset.
- self._loc_real = loc
- self.stale = True
- self._legend_box.set_offset(self._findoffset)
-
- def _get_loc(self):
- return self._loc_real
-
- _loc = property(_get_loc, _set_loc)
-
- def _findoffset(self, width, height, xdescent, ydescent, renderer):
- "Helper function to locate the legend."
-
- if self._loc == 0: # "best".
- x, y = self._find_best_position(width, height, renderer)
- elif self._loc in Legend.codes.values(): # Fixed location.
- bbox = Bbox.from_bounds(0, 0, width, height)
- x, y = self._get_anchored_bbox(self._loc, bbox,
- self.get_bbox_to_anchor(),
- renderer)
- else: # Axes or figure coordinates.
- fx, fy = self._loc
- bbox = self.get_bbox_to_anchor()
- x, y = bbox.x0 + bbox.width * fx, bbox.y0 + bbox.height * fy
-
- return x + xdescent, y + ydescent
-
- @allow_rasterization
- def draw(self, renderer):
- "Draw everything that belongs to the legend."
- if not self.get_visible():
- return
-
- renderer.open_group('legend')
-
- fontsize = renderer.points_to_pixels(self._fontsize)
-
- # if mode == fill, set the width of the legend_box to the
- # width of the paret (minus pads)
- if self._mode in ["expand"]:
- pad = 2 * (self.borderaxespad + self.borderpad) * fontsize
- self._legend_box.set_width(self.get_bbox_to_anchor().width - pad)
-
- # update the location and size of the legend. This needs to
- # be done in any case to clip the figure right.
- bbox = self._legend_box.get_window_extent(renderer)
- self.legendPatch.set_bounds(bbox.x0, bbox.y0,
- bbox.width, bbox.height)
- self.legendPatch.set_mutation_scale(fontsize)
-
- if self._drawFrame:
- if self.shadow:
- shadow = Shadow(self.legendPatch, 2, -2)
- shadow.draw(renderer)
-
- self.legendPatch.draw(renderer)
-
- self._legend_box.draw(renderer)
-
- renderer.close_group('legend')
- self.stale = False
-
- def _approx_text_height(self, renderer=None):
- """
- Return the approximate height of the text. This is used to place
- the legend handle.
- """
- if renderer is None:
- return self._fontsize
- else:
- return renderer.points_to_pixels(self._fontsize)
-
- # _default_handler_map defines the default mapping between plot
- # elements and the legend handlers.
-
- _default_handler_map = {
- StemContainer: legend_handler.HandlerStem(),
- ErrorbarContainer: legend_handler.HandlerErrorbar(),
- Line2D: legend_handler.HandlerLine2D(),
- Patch: legend_handler.HandlerPatch(),
- LineCollection: legend_handler.HandlerLineCollection(),
- RegularPolyCollection: legend_handler.HandlerRegularPolyCollection(),
- CircleCollection: legend_handler.HandlerCircleCollection(),
- BarContainer: legend_handler.HandlerPatch(
- update_func=legend_handler.update_from_first_child),
- tuple: legend_handler.HandlerTuple(),
- PathCollection: legend_handler.HandlerPathCollection(),
- PolyCollection: legend_handler.HandlerPolyCollection()
- }
-
- # (get|set|update)_default_handler_maps are public interfaces to
- # modify the default handler map.
-
- @classmethod
- def get_default_handler_map(cls):
- """
- A class method that returns the default handler map.
- """
- return cls._default_handler_map
-
- @classmethod
- def set_default_handler_map(cls, handler_map):
- """
- A class method to set the default handler map.
- """
- cls._default_handler_map = handler_map
-
- @classmethod
- def update_default_handler_map(cls, handler_map):
- """
- A class method to update the default handler map.
- """
- cls._default_handler_map.update(handler_map)
-
- def get_legend_handler_map(self):
- """
- Return the handler map.
- """
-
- default_handler_map = self.get_default_handler_map()
-
- if self._custom_handler_map:
- hm = default_handler_map.copy()
- hm.update(self._custom_handler_map)
- return hm
- else:
- return default_handler_map
-
- @staticmethod
- def get_legend_handler(legend_handler_map, orig_handle):
- """
- Return a legend handler from *legend_handler_map* that
- corresponds to *orig_handler*.
-
- *legend_handler_map* should be a dictionary object (that is
- returned by the get_legend_handler_map method).
-
- It first checks if the *orig_handle* itself is a key in the
- *legend_hanler_map* and return the associated value.
- Otherwise, it checks for each of the classes in its
- method-resolution-order. If no matching key is found, it
- returns ``None``.
- """
- if is_hashable(orig_handle):
- try:
- return legend_handler_map[orig_handle]
- except KeyError:
- pass
-
- for handle_type in type(orig_handle).mro():
- try:
- return legend_handler_map[handle_type]
- except KeyError:
- pass
-
- return None
-
- def _init_legend_box(self, handles, labels, markerfirst=True):
- """
- Initialize the legend_box. The legend_box is an instance of
- the OffsetBox, which is packed with legend handles and
- texts. Once packed, their location is calculated during the
- drawing time.
- """
-
- fontsize = self._fontsize
-
- # legend_box is a HPacker, horizontally packed with
- # columns. Each column is a VPacker, vertically packed with
- # legend items. Each legend item is HPacker packed with
- # legend handleBox and labelBox. handleBox is an instance of
- # offsetbox.DrawingArea which contains legend handle. labelBox
- # is an instance of offsetbox.TextArea which contains legend
- # text.
-
- text_list = [] # the list of text instances
- handle_list = [] # the list of text instances
- handles_and_labels = []
-
- label_prop = dict(verticalalignment='baseline',
- horizontalalignment='left',
- fontproperties=self.prop,
- )
-
- # The approximate height and descent of text. These values are
- # only used for plotting the legend handle.
- descent = 0.35 * self._approx_text_height() * (self.handleheight - 0.7)
- # 0.35 and 0.7 are just heuristic numbers and may need to be improved.
- height = self._approx_text_height() * self.handleheight - descent
- # each handle needs to be drawn inside a box of (x, y, w, h) =
- # (0, -descent, width, height). And their coordinates should
- # be given in the display coordinates.
-
- # The transformation of each handle will be automatically set
- # to self.get_trasnform(). If the artist does not use its
- # default transform (e.g., Collections), you need to
- # manually set their transform to the self.get_transform().
- legend_handler_map = self.get_legend_handler_map()
-
- for orig_handle, lab in zip(handles, labels):
- handler = self.get_legend_handler(legend_handler_map, orig_handle)
- if handler is None:
- warnings.warn(
- "Legend does not support {!r} instances.\nA proxy artist "
- "may be used instead.\nSee: "
- "http://matplotlib.org/users/legend_guide.html"
- "#creating-artists-specifically-for-adding-to-the-legend-"
- "aka-proxy-artists".format(orig_handle)
- )
- # We don't have a handle for this artist, so we just defer
- # to None.
- handle_list.append(None)
- else:
- textbox = TextArea(lab, textprops=label_prop,
- multilinebaseline=True,
- minimumdescent=True)
- handlebox = DrawingArea(width=self.handlelength * fontsize,
- height=height,
- xdescent=0., ydescent=descent)
-
- text_list.append(textbox._text)
- # Create the artist for the legend which represents the
- # original artist/handle.
- handle_list.append(handler.legend_artist(self, orig_handle,
- fontsize, handlebox))
- handles_and_labels.append((handlebox, textbox))
-
- if handles_and_labels:
- # We calculate number of rows in each column. The first
- # (num_largecol) columns will have (nrows+1) rows, and remaining
- # (num_smallcol) columns will have (nrows) rows.
- ncol = min(self._ncol, len(handles_and_labels))
- nrows, num_largecol = divmod(len(handles_and_labels), ncol)
- num_smallcol = ncol - num_largecol
- # starting index of each column and number of rows in it.
- rows_per_col = [nrows + 1] * num_largecol + [nrows] * num_smallcol
- start_idxs = np.concatenate([[0], np.cumsum(rows_per_col)[:-1]])
- cols = zip(start_idxs, rows_per_col)
- else:
- cols = []
-
- columnbox = []
- for i0, di in cols:
- # pack handleBox and labelBox into itemBox
- itemBoxes = [HPacker(pad=0,
- sep=self.handletextpad * fontsize,
- children=[h, t] if markerfirst else [t, h],
- align="baseline")
- for h, t in handles_and_labels[i0:i0 + di]]
- # minimumdescent=False for the text of the last row of the column
- if markerfirst:
- itemBoxes[-1].get_children()[1].set_minimumdescent(False)
- else:
- itemBoxes[-1].get_children()[0].set_minimumdescent(False)
-
- # pack columnBox
- alignment = "baseline" if markerfirst else "right"
- columnbox.append(VPacker(pad=0,
- sep=self.labelspacing * fontsize,
- align=alignment,
- children=itemBoxes))
-
- mode = "expand" if self._mode == "expand" else "fixed"
- sep = self.columnspacing * fontsize
- self._legend_handle_box = HPacker(pad=0,
- sep=sep, align="baseline",
- mode=mode,
- children=columnbox)
- self._legend_title_box = TextArea("")
- self._legend_box = VPacker(pad=self.borderpad * fontsize,
- sep=self.labelspacing * fontsize,
- align="center",
- children=[self._legend_title_box,
- self._legend_handle_box])
- self._legend_box.set_figure(self.figure)
- self.texts = text_list
- self.legendHandles = handle_list
-
- def _auto_legend_data(self):
- """
- Returns list of vertices and extents covered by the plot.
-
- Returns a two long list.
-
- First element is a list of (x, y) vertices (in
- display-coordinates) covered by all the lines and line
- collections, in the legend's handles.
-
- Second element is a list of bounding boxes for all the patches in
- the legend's handles.
- """
- # should always hold because function is only called internally
- assert self.isaxes
-
- ax = self.parent
- bboxes = []
- lines = []
- offsets = []
-
- for handle in ax.lines:
- assert isinstance(handle, Line2D)
- path = handle.get_path()
- trans = handle.get_transform()
- tpath = trans.transform_path(path)
- lines.append(tpath)
-
- for handle in ax.patches:
- assert isinstance(handle, Patch)
-
- if isinstance(handle, Rectangle):
- transform = handle.get_data_transform()
- bboxes.append(handle.get_bbox().transformed(transform))
- else:
- transform = handle.get_transform()
- bboxes.append(handle.get_path().get_extents(transform))
-
- for handle in ax.collections:
- transform, transOffset, hoffsets, paths = handle._prepare_points()
-
- if len(hoffsets):
- for offset in transOffset.transform(hoffsets):
- offsets.append(offset)
-
- try:
- vertices = np.concatenate([l.vertices for l in lines])
- except ValueError:
- vertices = np.array([])
-
- return [vertices, bboxes, lines, offsets]
-
- def draw_frame(self, b):
- '''
- Set draw frame to b.
-
- Parameters
- ----------
- b : bool
- '''
- self.set_frame_on(b)
-
- def get_children(self):
- 'Return a list of child artists.'
- children = []
- if self._legend_box:
- children.append(self._legend_box)
- children.append(self.get_frame())
-
- return children
-
- def get_frame(self):
- '''
- Return the `~.patches.Rectangle` instances used to frame the legend.
- '''
- return self.legendPatch
-
- def get_lines(self):
- 'Return a list of `~.lines.Line2D` instances in the legend.'
- return [h for h in self.legendHandles if isinstance(h, Line2D)]
-
- def get_patches(self):
- 'Return a list of `~.patches.Patch` instances in the legend.'
- return silent_list('Patch',
- [h for h in self.legendHandles
- if isinstance(h, Patch)])
-
- def get_texts(self):
- 'Return a list of `~.text.Text` instances in the legend.'
- return silent_list('Text', self.texts)
-
- def set_title(self, title, prop=None):
- """
- Set the legend title. Fontproperties can be optionally set
- with *prop* parameter.
- """
- self._legend_title_box._text.set_text(title)
-
- if prop is not None:
- if isinstance(prop, dict):
- prop = FontProperties(**prop)
- self._legend_title_box._text.set_fontproperties(prop)
-
- if title:
- self._legend_title_box.set_visible(True)
- else:
- self._legend_title_box.set_visible(False)
- self.stale = True
-
- def get_title(self):
- 'Return the `.Text` instance for the legend title.'
- return self._legend_title_box._text
-
- def get_window_extent(self, *args, **kwargs):
- 'Return extent of the legend.'
- return self.legendPatch.get_window_extent(*args, **kwargs)
-
- def get_frame_on(self):
- """Get whether the legend box patch is drawn."""
- return self._drawFrame
-
- def set_frame_on(self, b):
- """
- Set whether the legend box patch is drawn.
-
- Parameters
- ----------
- b : bool
- .. ACCEPTS: bool
- """
- self._drawFrame = b
- self.stale = True
-
- def get_bbox_to_anchor(self):
- """Return the bbox that the legend will be anchored to."""
- if self._bbox_to_anchor is None:
- return self.parent.bbox
- else:
- return self._bbox_to_anchor
-
- def set_bbox_to_anchor(self, bbox, transform=None):
- """
- Set the bbox that the legend will be anchored to.
-
- *bbox* can be
-
- - A `.BboxBase` instance
- - A tuple of ``(left, bottom, width, height)`` in the given transform
- (normalized axes coordinate if None)
- - A tuple of ``(left, bottom)`` where the width and height will be
- assumed to be zero.
- """
- if bbox is None:
- self._bbox_to_anchor = None
- return
- elif isinstance(bbox, BboxBase):
- self._bbox_to_anchor = bbox
- else:
- try:
- l = len(bbox)
- except TypeError:
- raise ValueError("Invalid argument for bbox : %s" % str(bbox))
-
- if l == 2:
- bbox = [bbox[0], bbox[1], 0, 0]
-
- self._bbox_to_anchor = Bbox.from_bounds(*bbox)
-
- if transform is None:
- transform = BboxTransformTo(self.parent.bbox)
-
- self._bbox_to_anchor = TransformedBbox(self._bbox_to_anchor,
- transform)
- self.stale = True
-
- def _get_anchored_bbox(self, loc, bbox, parentbbox, renderer):
- """
- Place the *bbox* inside the *parentbbox* according to a given
- location code. Return the (x,y) coordinate of the bbox.
-
- - loc: a location code in range(1, 11).
- This corresponds to the possible values for self._loc, excluding
- "best".
-
- - bbox: bbox to be placed, display coordinate units.
- - parentbbox: a parent box which will contain the bbox. In
- display coordinates.
- """
- assert loc in range(1, 11) # called only internally
-
- BEST, UR, UL, LL, LR, R, CL, CR, LC, UC, C = range(11)
-
- anchor_coefs = {UR: "NE",
- UL: "NW",
- LL: "SW",
- LR: "SE",
- R: "E",
- CL: "W",
- CR: "E",
- LC: "S",
- UC: "N",
- C: "C"}
-
- c = anchor_coefs[loc]
-
- fontsize = renderer.points_to_pixels(self._fontsize)
- container = parentbbox.padded(-(self.borderaxespad) * fontsize)
- anchored_box = bbox.anchored(c, container=container)
- return anchored_box.x0, anchored_box.y0
-
- def _find_best_position(self, width, height, renderer, consider=None):
- """
- Determine the best location to place the legend.
-
- *consider* is a list of ``(x, y)`` pairs to consider as a potential
- lower-left corner of the legend. All are display coords.
- """
- # should always hold because function is only called internally
- assert self.isaxes
-
- verts, bboxes, lines, offsets = self._auto_legend_data()
-
- bbox = Bbox.from_bounds(0, 0, width, height)
- if consider is None:
- consider = [self._get_anchored_bbox(x, bbox,
- self.get_bbox_to_anchor(),
- renderer)
- for x in range(1, len(self.codes))]
-
- candidates = []
- for idx, (l, b) in enumerate(consider):
- legendBox = Bbox.from_bounds(l, b, width, height)
- badness = 0
- # XXX TODO: If markers are present, it would be good to
- # take them into account when checking vertex overlaps in
- # the next line.
- badness = (legendBox.count_contains(verts)
- + legendBox.count_contains(offsets)
- + legendBox.count_overlaps(bboxes)
- + sum(line.intersects_bbox(legendBox, filled=False)
- for line in lines))
- if badness == 0:
- return l, b
- # Include the index to favor lower codes in case of a tie.
- candidates.append((badness, idx, (l, b)))
-
- _, _, (l, b) = min(candidates)
- return l, b
-
- def contains(self, event):
- return self.legendPatch.contains(event)
-
- def draggable(self, state=None, use_blit=False, update="loc"):
- """
- Set the draggable state -- if state is
-
- * None : toggle the current state
-
- * True : turn draggable on
-
- * False : turn draggable off
-
- If draggable is on, you can drag the legend on the canvas with
- the mouse. The `.DraggableLegend` helper instance is returned if
- draggable is on.
-
- The update parameter control which parameter of the legend changes
- when dragged. If update is "loc", the *loc* parameter of the legend
- is changed. If "bbox", the *bbox_to_anchor* parameter is changed.
- """
- is_draggable = self._draggable is not None
-
- # if state is None we'll toggle
- if state is None:
- state = not is_draggable
-
- if state:
- if self._draggable is None:
- self._draggable = DraggableLegend(self,
- use_blit,
- update=update)
- else:
- if self._draggable is not None:
- self._draggable.disconnect()
- self._draggable = None
-
- return self._draggable
-
-
-# Helper functions to parse legend arguments for both `figure.legend` and
-# `axes.legend`:
-def _get_legend_handles(axs, legend_handler_map=None):
- """
- Return a generator of artists that can be used as handles in
- a legend.
-
- """
- handles_original = []
- for ax in axs:
- handles_original += (ax.lines + ax.patches +
- ax.collections + ax.containers)
- # support parasite axes:
- if hasattr(ax, 'parasites'):
- for axx in ax.parasites:
- handles_original += (axx.lines + axx.patches +
- axx.collections + axx.containers)
-
- handler_map = Legend.get_default_handler_map()
-
- if legend_handler_map is not None:
- handler_map = handler_map.copy()
- handler_map.update(legend_handler_map)
-
- has_handler = Legend.get_legend_handler
-
- for handle in handles_original:
- label = handle.get_label()
- if label != '_nolegend_' and has_handler(handler_map, handle):
- yield handle
-
-
-def _get_legend_handles_labels(axs, legend_handler_map=None):
- """
- Return handles and labels for legend, internal method.
-
- """
- handles = []
- labels = []
-
- for handle in _get_legend_handles(axs, legend_handler_map):
- label = handle.get_label()
- if (label and not label.startswith('_')):
- handles.append(handle)
- labels.append(label)
- return handles, labels
-
-
-def _parse_legend_args(axs, *args, **kwargs):
- """
- Get the handles and labels from the calls to either ``figure.legend``
- or ``axes.legend``.
-
- ``axs`` is a list of axes (to get legend artists from)
- """
- log = logging.getLogger(__name__)
-
- handlers = kwargs.get('handler_map', {}) or {}
-
- # Support handles and labels being passed as keywords.
- handles = kwargs.pop('handles', None)
- labels = kwargs.pop('labels', None)
-
- extra_args = ()
-
- if (handles is not None or labels is not None) and len(args):
- warnings.warn("You have mixed positional and keyword "
- "arguments, some input may be "
- "discarded.")
-
- # if got both handles and labels as kwargs, make same length
- if handles and labels:
- handles, labels = zip(*zip(handles, labels))
-
- elif handles is not None and labels is None:
- labels = [handle.get_label() for handle in handles]
-
- elif labels is not None and handles is None:
- # Get as many handles as there are labels.
- handles = [handle for handle, label
- in zip(_get_legend_handles(axs, handlers), labels)]
-
- # No arguments - automatically detect labels and handles.
- elif len(args) == 0:
- handles, labels = _get_legend_handles_labels(axs, handlers)
- if not handles:
- log.warning('No handles with labels found to put in legend.')
-
- # One argument. User defined labels - automatic handle detection.
- elif len(args) == 1:
- labels, = args
- # Get as many handles as there are labels.
- handles = [handle for handle, label
- in zip(_get_legend_handles(axs, handlers), labels)]
-
- # Two arguments:
- # * user defined handles and labels
- elif len(args) >= 2:
- handles, labels = args[:2]
- extra_args = args[2:]
-
- else:
- raise TypeError('Invalid arguments to legend.')
-
- return handles, labels, extra_args, kwargs
diff --git a/contrib/python/matplotlib/py2/matplotlib/legend_handler.py b/contrib/python/matplotlib/py2/matplotlib/legend_handler.py
deleted file mode 100644
index e1a7e2d03d..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/legend_handler.py
+++ /dev/null
@@ -1,730 +0,0 @@
-"""
-This module defines default legend handlers.
-
-It is strongly encouraged to have read the :doc:`legend guide
-</tutorials/intermediate/legend_guide>` before this documentation.
-
-Legend handlers are expected to be a callable object with a following
-signature. ::
-
- legend_handler(legend, orig_handle, fontsize, handlebox)
-
-Where *legend* is the legend itself, *orig_handle* is the original
-plot, *fontsize* is the fontsize in pixels, and *handlebox* is a
-OffsetBox instance. Within the call, you should create relevant
-artists (using relevant properties from the *legend* and/or
-*orig_handle*) and add them into the handlebox. The artists needs to
-be scaled according to the fontsize (note that the size is in pixel,
-i.e., this is dpi-scaled value).
-
-This module includes definition of several legend handler classes
-derived from the base class (HandlerBase) with the following method::
-
- def legend_artist(self, legend, orig_handle, fontsize, handlebox):
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import zip
-from itertools import cycle
-
-import numpy as np
-
-from matplotlib.lines import Line2D
-from matplotlib.patches import Rectangle
-import matplotlib.collections as mcoll
-import matplotlib.colors as mcolors
-
-
-def update_from_first_child(tgt, src):
- tgt.update_from(src.get_children()[0])
-
-
-class HandlerBase(object):
- """
- A Base class for default legend handlers.
-
- The derived classes are meant to override *create_artists* method, which
- has a following signature.::
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- trans):
-
- The overridden method needs to create artists of the given
- transform that fits in the given dimension (xdescent, ydescent,
- width, height) that are scaled by fontsize if necessary.
-
- """
- def __init__(self, xpad=0., ypad=0., update_func=None):
- self._xpad, self._ypad = xpad, ypad
- self._update_prop_func = update_func
-
- def _update_prop(self, legend_handle, orig_handle):
- if self._update_prop_func is None:
- self._default_update_prop(legend_handle, orig_handle)
- else:
- self._update_prop_func(legend_handle, orig_handle)
-
- def _default_update_prop(self, legend_handle, orig_handle):
- legend_handle.update_from(orig_handle)
-
- def update_prop(self, legend_handle, orig_handle, legend):
-
- self._update_prop(legend_handle, orig_handle)
-
- legend._set_artist_props(legend_handle)
- legend_handle.set_clip_box(None)
- legend_handle.set_clip_path(None)
-
- def adjust_drawing_area(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- ):
- xdescent = xdescent - self._xpad * fontsize
- ydescent = ydescent - self._ypad * fontsize
- width = width - self._xpad * fontsize
- height = height - self._ypad * fontsize
- return xdescent, ydescent, width, height
-
- def legend_artist(self, legend, orig_handle,
- fontsize, handlebox):
- """
- Return the artist that this HandlerBase generates for the given
- original artist/handle.
-
- Parameters
- ----------
- legend : :class:`matplotlib.legend.Legend` instance
- The legend for which these legend artists are being created.
- orig_handle : :class:`matplotlib.artist.Artist` or similar
- The object for which these legend artists are being created.
- fontsize : float or int
- The fontsize in pixels. The artists being created should
- be scaled according to the given fontsize.
- handlebox : :class:`matplotlib.offsetbox.OffsetBox` instance
- The box which has been created to hold this legend entry's
- artists. Artists created in the `legend_artist` method must
- be added to this handlebox inside this method.
-
- """
- xdescent, ydescent, width, height = self.adjust_drawing_area(
- legend, orig_handle,
- handlebox.xdescent, handlebox.ydescent,
- handlebox.width, handlebox.height,
- fontsize)
- artists = self.create_artists(legend, orig_handle,
- xdescent, ydescent, width, height,
- fontsize, handlebox.get_transform())
-
- # create_artists will return a list of artists.
- for a in artists:
- handlebox.add_artist(a)
-
- # we only return the first artist
- return artists[0]
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- trans):
- raise NotImplementedError('Derived must override')
-
-
-class HandlerNpoints(HandlerBase):
- """
- A legend handler that shows *numpoints* points in the legend entry.
- """
- def __init__(self, marker_pad=0.3, numpoints=None, **kw):
- """
- Parameters
- ----------
- marker_pad : float
- Padding between points in legend entry.
-
- numpoints : int
- Number of points to show in legend entry.
-
- Notes
- -----
- Any other keyword arguments are given to `HandlerBase`.
- """
- HandlerBase.__init__(self, **kw)
-
- self._numpoints = numpoints
- self._marker_pad = marker_pad
-
- def get_numpoints(self, legend):
- if self._numpoints is None:
- return legend.numpoints
- else:
- return self._numpoints
-
- def get_xdata(self, legend, xdescent, ydescent, width, height, fontsize):
- numpoints = self.get_numpoints(legend)
- if numpoints > 1:
- # we put some pad here to compensate the size of the marker
- pad = self._marker_pad * fontsize
- xdata = np.linspace(-xdescent + pad,
- -xdescent + width - pad,
- numpoints)
- xdata_marker = xdata
- else:
- xdata = np.linspace(-xdescent, -xdescent + width, 2)
- xdata_marker = [-xdescent + 0.5 * width]
- return xdata, xdata_marker
-
-
-class HandlerNpointsYoffsets(HandlerNpoints):
- """
- A legend handler that shows *numpoints* in the legend, and allows them to
- be individually offest in the y-direction.
- """
- def __init__(self, numpoints=None, yoffsets=None, **kw):
- """
- Parameters
- ----------
- numpoints : int
- Number of points to show in legend entry.
-
- yoffsets : array of floats
- Length *numpoints* list of y offsets for each point in
- legend entry.
-
- Notes
- -----
- Any other keyword arguments are given to `HandlerNpoints`.
- """
- HandlerNpoints.__init__(self, numpoints=numpoints, **kw)
- self._yoffsets = yoffsets
-
- def get_ydata(self, legend, xdescent, ydescent, width, height, fontsize):
- if self._yoffsets is None:
- ydata = height * legend._scatteryoffsets
- else:
- ydata = height * np.asarray(self._yoffsets)
-
- return ydata
-
-
-class HandlerLine2D(HandlerNpoints):
- """
- Handler for `.Line2D` instances.
- """
- def __init__(self, marker_pad=0.3, numpoints=None, **kw):
- """
- Parameters
- ----------
- marker_pad : float
- Padding between points in legend entry.
-
- numpoints : int
- Number of points to show in legend entry.
-
- Notes
- -----
- Any other keyword arguments are given to `HandlerNpoints`.
- """
- HandlerNpoints.__init__(self, marker_pad=marker_pad,
- numpoints=numpoints, **kw)
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- trans):
-
- xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent,
- width, height, fontsize)
-
- ydata = ((height - ydescent) / 2.) * np.ones(xdata.shape, float)
- legline = Line2D(xdata, ydata)
-
- self.update_prop(legline, orig_handle, legend)
- legline.set_drawstyle('default')
- legline.set_marker("")
-
- legline_marker = Line2D(xdata_marker, ydata[:len(xdata_marker)])
- self.update_prop(legline_marker, orig_handle, legend)
- legline_marker.set_linestyle('None')
- if legend.markerscale != 1:
- newsz = legline_marker.get_markersize() * legend.markerscale
- legline_marker.set_markersize(newsz)
- # we don't want to add this to the return list because
- # the texts and handles are assumed to be in one-to-one
- # correspondence.
- legline._legmarker = legline_marker
-
- legline.set_transform(trans)
- legline_marker.set_transform(trans)
-
- return [legline, legline_marker]
-
-
-class HandlerPatch(HandlerBase):
- """
- Handler for `.Patch` instances.
- """
- def __init__(self, patch_func=None, **kw):
- """
- Parameters
- ----------
- patch_func : callable, optional
- The function that creates the legend key artist.
- *patch_func* should have the signature::
-
- def patch_func(legend=legend, orig_handle=orig_handle,
- xdescent=xdescent, ydescent=ydescent,
- width=width, height=height, fontsize=fontsize)
-
- Subsequently the created artist will have its ``update_prop`` method
- called and the appropriate transform will be applied.
-
- Notes
- -----
- Any other keyword arguments are given to `HandlerBase`.
- """
- HandlerBase.__init__(self, **kw)
- self._patch_func = patch_func
-
- def _create_patch(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize):
- if self._patch_func is None:
- p = Rectangle(xy=(-xdescent, -ydescent),
- width=width, height=height)
- else:
- p = self._patch_func(legend=legend, orig_handle=orig_handle,
- xdescent=xdescent, ydescent=ydescent,
- width=width, height=height, fontsize=fontsize)
- return p
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize, trans):
- p = self._create_patch(legend, orig_handle,
- xdescent, ydescent, width, height, fontsize)
- self.update_prop(p, orig_handle, legend)
- p.set_transform(trans)
- return [p]
-
-
-class HandlerLineCollection(HandlerLine2D):
- """
- Handler for `.LineCollection` instances.
- """
- def get_numpoints(self, legend):
- if self._numpoints is None:
- return legend.scatterpoints
- else:
- return self._numpoints
-
- def _default_update_prop(self, legend_handle, orig_handle):
- lw = orig_handle.get_linewidths()[0]
- dashes = orig_handle._us_linestyles[0]
- color = orig_handle.get_colors()[0]
- legend_handle.set_color(color)
- legend_handle.set_linestyle(dashes)
- legend_handle.set_linewidth(lw)
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize, trans):
-
- xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent,
- width, height, fontsize)
- ydata = ((height - ydescent) / 2.) * np.ones(xdata.shape, float)
- legline = Line2D(xdata, ydata)
-
- self.update_prop(legline, orig_handle, legend)
- legline.set_transform(trans)
-
- return [legline]
-
-
-class HandlerRegularPolyCollection(HandlerNpointsYoffsets):
- """
- Handler for `.RegularPolyCollections`.
- """
- def __init__(self, yoffsets=None, sizes=None, **kw):
- HandlerNpointsYoffsets.__init__(self, yoffsets=yoffsets, **kw)
-
- self._sizes = sizes
-
- def get_numpoints(self, legend):
- if self._numpoints is None:
- return legend.scatterpoints
- else:
- return self._numpoints
-
- def get_sizes(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize):
- if self._sizes is None:
- handle_sizes = orig_handle.get_sizes()
- if not len(handle_sizes):
- handle_sizes = [1]
- size_max = max(handle_sizes) * legend.markerscale ** 2
- size_min = min(handle_sizes) * legend.markerscale ** 2
-
- numpoints = self.get_numpoints(legend)
- if numpoints < 4:
- sizes = [.5 * (size_max + size_min), size_max,
- size_min][:numpoints]
- else:
- rng = (size_max - size_min)
- sizes = rng * np.linspace(0, 1, numpoints) + size_min
- else:
- sizes = self._sizes
-
- return sizes
-
- def update_prop(self, legend_handle, orig_handle, legend):
-
- self._update_prop(legend_handle, orig_handle)
-
- legend_handle.set_figure(legend.figure)
- #legend._set_artist_props(legend_handle)
- legend_handle.set_clip_box(None)
- legend_handle.set_clip_path(None)
-
- def create_collection(self, orig_handle, sizes, offsets, transOffset):
- p = type(orig_handle)(orig_handle.get_numsides(),
- rotation=orig_handle.get_rotation(),
- sizes=sizes,
- offsets=offsets,
- transOffset=transOffset,
- )
- return p
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- trans):
- xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent,
- width, height, fontsize)
-
- ydata = self.get_ydata(legend, xdescent, ydescent,
- width, height, fontsize)
-
- sizes = self.get_sizes(legend, orig_handle, xdescent, ydescent,
- width, height, fontsize)
-
- p = self.create_collection(orig_handle, sizes,
- offsets=list(zip(xdata_marker, ydata)),
- transOffset=trans)
-
- self.update_prop(p, orig_handle, legend)
- p._transOffset = trans
- return [p]
-
-
-class HandlerPathCollection(HandlerRegularPolyCollection):
- """
- Handler for `.PathCollections`, which are used by `~.Axes.scatter`.
- """
- def create_collection(self, orig_handle, sizes, offsets, transOffset):
- p = type(orig_handle)([orig_handle.get_paths()[0]],
- sizes=sizes,
- offsets=offsets,
- transOffset=transOffset,
- )
- return p
-
-
-class HandlerCircleCollection(HandlerRegularPolyCollection):
- """
- Handler for `.CircleCollections`.
- """
- def create_collection(self, orig_handle, sizes, offsets, transOffset):
- p = type(orig_handle)(sizes,
- offsets=offsets,
- transOffset=transOffset,
- )
- return p
-
-
-class HandlerErrorbar(HandlerLine2D):
- """
- Handler for Errorbars.
- """
- def __init__(self, xerr_size=0.5, yerr_size=None,
- marker_pad=0.3, numpoints=None, **kw):
-
- self._xerr_size = xerr_size
- self._yerr_size = yerr_size
-
- HandlerLine2D.__init__(self, marker_pad=marker_pad,
- numpoints=numpoints, **kw)
-
- def get_err_size(self, legend, xdescent, ydescent,
- width, height, fontsize):
- xerr_size = self._xerr_size * fontsize
-
- if self._yerr_size is None:
- yerr_size = xerr_size
- else:
- yerr_size = self._yerr_size * fontsize
-
- return xerr_size, yerr_size
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- trans):
-
- plotlines, caplines, barlinecols = orig_handle
-
- xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent,
- width, height, fontsize)
-
- ydata = ((height - ydescent) / 2.) * np.ones(xdata.shape, float)
- legline = Line2D(xdata, ydata)
-
- xdata_marker = np.asarray(xdata_marker)
- ydata_marker = np.asarray(ydata[:len(xdata_marker)])
-
- xerr_size, yerr_size = self.get_err_size(legend, xdescent, ydescent,
- width, height, fontsize)
-
- legline_marker = Line2D(xdata_marker, ydata_marker)
-
- # when plotlines are None (only errorbars are drawn), we just
- # make legline invisible.
- if plotlines is None:
- legline.set_visible(False)
- legline_marker.set_visible(False)
- else:
- self.update_prop(legline, plotlines, legend)
-
- legline.set_drawstyle('default')
- legline.set_marker('None')
-
- self.update_prop(legline_marker, plotlines, legend)
- legline_marker.set_linestyle('None')
-
- if legend.markerscale != 1:
- newsz = legline_marker.get_markersize() * legend.markerscale
- legline_marker.set_markersize(newsz)
-
- handle_barlinecols = []
- handle_caplines = []
-
- if orig_handle.has_xerr:
- verts = [ ((x - xerr_size, y), (x + xerr_size, y))
- for x, y in zip(xdata_marker, ydata_marker)]
- coll = mcoll.LineCollection(verts)
- self.update_prop(coll, barlinecols[0], legend)
- handle_barlinecols.append(coll)
-
- if caplines:
- capline_left = Line2D(xdata_marker - xerr_size, ydata_marker)
- capline_right = Line2D(xdata_marker + xerr_size, ydata_marker)
- self.update_prop(capline_left, caplines[0], legend)
- self.update_prop(capline_right, caplines[0], legend)
- capline_left.set_marker("|")
- capline_right.set_marker("|")
-
- handle_caplines.append(capline_left)
- handle_caplines.append(capline_right)
-
- if orig_handle.has_yerr:
- verts = [ ((x, y - yerr_size), (x, y + yerr_size))
- for x, y in zip(xdata_marker, ydata_marker)]
- coll = mcoll.LineCollection(verts)
- self.update_prop(coll, barlinecols[0], legend)
- handle_barlinecols.append(coll)
-
- if caplines:
- capline_left = Line2D(xdata_marker, ydata_marker - yerr_size)
- capline_right = Line2D(xdata_marker, ydata_marker + yerr_size)
- self.update_prop(capline_left, caplines[0], legend)
- self.update_prop(capline_right, caplines[0], legend)
- capline_left.set_marker("_")
- capline_right.set_marker("_")
-
- handle_caplines.append(capline_left)
- handle_caplines.append(capline_right)
-
- artists = []
- artists.extend(handle_barlinecols)
- artists.extend(handle_caplines)
- artists.append(legline)
- artists.append(legline_marker)
-
- for artist in artists:
- artist.set_transform(trans)
-
- return artists
-
-
-class HandlerStem(HandlerNpointsYoffsets):
- """
- Handler for plots produced by `~.Axes.stem`.
- """
- def __init__(self, marker_pad=0.3, numpoints=None,
- bottom=None, yoffsets=None, **kw):
- """
- Parameters
- ----------
- marker_pad : float
- Padding between points in legend entry. Default is 0.3.
-
- numpoints : int, optional
- Number of points to show in legend entry.
-
- bottom : float, optional
-
- yoffsets : array of floats, optional
- Length *numpoints* list of y offsets for each point in
- legend entry.
-
- Notes
- -----
- Any other keyword arguments are given to `HandlerNpointsYoffsets`.
- """
-
- HandlerNpointsYoffsets.__init__(self, marker_pad=marker_pad,
- numpoints=numpoints,
- yoffsets=yoffsets,
- **kw)
- self._bottom = bottom
-
- def get_ydata(self, legend, xdescent, ydescent, width, height, fontsize):
- if self._yoffsets is None:
- ydata = height * (0.5 * legend._scatteryoffsets + 0.5)
- else:
- ydata = height * np.asarray(self._yoffsets)
-
- return ydata
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- trans):
-
- markerline, stemlines, baseline = orig_handle
-
- xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent,
- width, height, fontsize)
-
- ydata = self.get_ydata(legend, xdescent, ydescent,
- width, height, fontsize)
-
- if self._bottom is None:
- bottom = 0.
- else:
- bottom = self._bottom
-
- leg_markerline = Line2D(xdata_marker, ydata[:len(xdata_marker)])
- self.update_prop(leg_markerline, markerline, legend)
-
- leg_stemlines = []
- for thisx, thisy in zip(xdata_marker, ydata):
- l = Line2D([thisx, thisx], [bottom, thisy])
- leg_stemlines.append(l)
-
- for lm, m in zip(leg_stemlines, stemlines):
- self.update_prop(lm, m, legend)
-
- leg_baseline = Line2D([np.min(xdata), np.max(xdata)],
- [bottom, bottom])
-
- self.update_prop(leg_baseline, baseline, legend)
-
- artists = [leg_markerline]
- artists.extend(leg_stemlines)
- artists.append(leg_baseline)
-
- for artist in artists:
- artist.set_transform(trans)
-
- return artists
-
-
-class HandlerTuple(HandlerBase):
- """
- Handler for Tuple.
-
- Additional kwargs are passed through to `HandlerBase`.
-
- Parameters
- ----------
- ndivide : int, optional
- The number of sections to divide the legend area into. If None,
- use the length of the input tuple. Default is 1.
-
-
- pad : float, optional
- If None, fall back to ``legend.borderpad`` as the default.
- In units of fraction of font size. Default is None.
- """
- def __init__(self, ndivide=1, pad=None, **kwargs):
-
- self._ndivide = ndivide
- self._pad = pad
- HandlerBase.__init__(self, **kwargs)
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- trans):
-
- handler_map = legend.get_legend_handler_map()
-
- if self._ndivide is None:
- ndivide = len(orig_handle)
- else:
- ndivide = self._ndivide
-
- if self._pad is None:
- pad = legend.borderpad * fontsize
- else:
- pad = self._pad * fontsize
-
- if ndivide > 1:
- width = (width - pad * (ndivide - 1)) / ndivide
-
- xds_cycle = cycle(xdescent - (width + pad) * np.arange(ndivide))
-
- a_list = []
- for handle1 in orig_handle:
- handler = legend.get_legend_handler(handler_map, handle1)
- _a_list = handler.create_artists(
- legend, handle1,
- next(xds_cycle), ydescent, width, height, fontsize, trans)
- a_list.extend(_a_list)
-
- return a_list
-
-
-class HandlerPolyCollection(HandlerBase):
- """
- Handler for `.PolyCollection` used in `~.Axes.fill_between` and `~.Axes.stackplot`.
- """
- def _update_prop(self, legend_handle, orig_handle):
- def first_color(colors):
- if colors is None:
- return None
- colors = mcolors.to_rgba_array(colors)
- if len(colors):
- return colors[0]
- else:
- return "none"
-
- def get_first(prop_array):
- if len(prop_array):
- return prop_array[0]
- else:
- return None
- edgecolor = getattr(orig_handle, '_original_edgecolor',
- orig_handle.get_edgecolor())
- legend_handle.set_edgecolor(first_color(edgecolor))
- facecolor = getattr(orig_handle, '_original_facecolor',
- orig_handle.get_facecolor())
- legend_handle.set_facecolor(first_color(facecolor))
- legend_handle.set_fill(orig_handle.get_fill())
- legend_handle.set_hatch(orig_handle.get_hatch())
- legend_handle.set_linewidth(get_first(orig_handle.get_linewidths()))
- legend_handle.set_linestyle(get_first(orig_handle.get_linestyles()))
- legend_handle.set_transform(get_first(orig_handle.get_transforms()))
- legend_handle.set_figure(orig_handle.get_figure())
- legend_handle.set_alpha(orig_handle.get_alpha())
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize, trans):
- p = Rectangle(xy=(-xdescent, -ydescent),
- width=width, height=height)
- self.update_prop(p, orig_handle, legend)
- p.set_transform(trans)
- return [p]
diff --git a/contrib/python/matplotlib/py2/matplotlib/lines.py b/contrib/python/matplotlib/py2/matplotlib/lines.py
deleted file mode 100644
index 91edd5f89d..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/lines.py
+++ /dev/null
@@ -1,1507 +0,0 @@
-"""
-This module contains all the 2D line class which can draw with a
-variety of line styles, markers and colors.
-"""
-
-# TODO: expose cap and join style attrs
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import warnings
-
-import numpy as np
-
-from . import artist, cbook, colors as mcolors, docstring, rcParams
-from .artist import Artist, allow_rasterization
-from .cbook import (
- _to_unmasked_float_array, iterable, is_numlike, ls_mapper, ls_mapper_r,
- STEP_LOOKUP_MAP)
-from .markers import MarkerStyle
-from .path import Path
-from .transforms import Bbox, TransformedPath, IdentityTransform
-
-# Imported here for backward compatibility, even though they don't
-# really belong.
-from . import _path
-from .markers import (
- CARETLEFT, CARETRIGHT, CARETUP, CARETDOWN,
- CARETLEFTBASE, CARETRIGHTBASE, CARETUPBASE, CARETDOWNBASE,
- TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN)
-
-
-def _get_dash_pattern(style):
- """Convert linestyle -> dash pattern
- """
- # go from short hand -> full strings
- if isinstance(style, six.string_types):
- style = ls_mapper.get(style, style)
- # un-dashed styles
- if style in ['solid', 'None']:
- offset, dashes = None, None
- # dashed styles
- elif style in ['dashed', 'dashdot', 'dotted']:
- offset = 0
- dashes = tuple(rcParams['lines.{}_pattern'.format(style)])
- #
- elif isinstance(style, tuple):
- offset, dashes = style
- else:
- raise ValueError('Unrecognized linestyle: %s' % str(style))
-
- # normalize offset to be positive and shorter than the dash cycle
- if dashes is not None and offset is not None:
- dsum = sum(dashes)
- if dsum:
- offset %= dsum
-
- return offset, dashes
-
-
-def _scale_dashes(offset, dashes, lw):
- if not rcParams['lines.scale_dashes']:
- return offset, dashes
-
- scaled_offset = scaled_dashes = None
- if offset is not None:
- scaled_offset = offset * lw
- if dashes is not None:
- scaled_dashes = [x * lw if x is not None else None
- for x in dashes]
-
- return scaled_offset, scaled_dashes
-
-
-def segment_hits(cx, cy, x, y, radius):
- """
- Determine if any line segments are within radius of a
- point. Returns the list of line segments that are within that
- radius.
- """
- # Process single points specially
- if len(x) < 2:
- res, = np.nonzero((cx - x) ** 2 + (cy - y) ** 2 <= radius ** 2)
- return res
-
- # We need to lop the last element off a lot.
- xr, yr = x[:-1], y[:-1]
-
- # Only look at line segments whose nearest point to C on the line
- # lies within the segment.
- dx, dy = x[1:] - xr, y[1:] - yr
- Lnorm_sq = dx ** 2 + dy ** 2 # Possibly want to eliminate Lnorm==0
- u = ((cx - xr) * dx + (cy - yr) * dy) / Lnorm_sq
- candidates = (u >= 0) & (u <= 1)
-
- # Note that there is a little area near one side of each point
- # which will be near neither segment, and another which will
- # be near both, depending on the angle of the lines. The
- # following radius test eliminates these ambiguities.
- point_hits = (cx - x) ** 2 + (cy - y) ** 2 <= radius ** 2
- candidates = candidates & ~(point_hits[:-1] | point_hits[1:])
-
- # For those candidates which remain, determine how far they lie away
- # from the line.
- px, py = xr + u * dx, yr + u * dy
- line_hits = (cx - px) ** 2 + (cy - py) ** 2 <= radius ** 2
- line_hits = line_hits & candidates
- points, = point_hits.ravel().nonzero()
- lines, = line_hits.ravel().nonzero()
- return np.concatenate((points, lines))
-
-
-def _mark_every_path(markevery, tpath, affine, ax_transform):
- """
- Helper function that sorts out how to deal the input
- `markevery` and returns the points where markers should be drawn.
-
- Takes in the `markevery` value and the line path and returns the
- sub-sampled path.
- """
- # pull out the two bits of data we want from the path
- codes, verts = tpath.codes, tpath.vertices
-
- def _slice_or_none(in_v, slc):
- '''
- Helper function to cope with `codes` being an
- ndarray or `None`
- '''
- if in_v is None:
- return None
- return in_v[slc]
-
- # if just a float, assume starting at 0.0 and make a tuple
- if isinstance(markevery, float):
- markevery = (0.0, markevery)
- # if just an int, assume starting at 0 and make a tuple
- elif isinstance(markevery, int):
- markevery = (0, markevery)
- # if just an numpy int, assume starting at 0 and make a tuple
- elif isinstance(markevery, np.integer):
- markevery = (0, markevery.item())
-
- if isinstance(markevery, tuple):
- if len(markevery) != 2:
- raise ValueError('`markevery` is a tuple but its '
- 'len is not 2; '
- 'markevery=%s' % (markevery,))
- start, step = markevery
- # if step is an int, old behavior
- if isinstance(step, int):
- #tuple of 2 int is for backwards compatibility,
- if not(isinstance(start, int)):
- raise ValueError('`markevery` is a tuple with '
- 'len 2 and second element is an int, but '
- 'the first element is not an int; '
- 'markevery=%s' % (markevery,))
- # just return, we are done here
-
- return Path(verts[slice(start, None, step)],
- _slice_or_none(codes, slice(start, None, step)))
-
- elif isinstance(step, float):
- if not (isinstance(start, int) or
- isinstance(start, float)):
- raise ValueError('`markevery` is a tuple with '
- 'len 2 and second element is a float, but '
- 'the first element is not a float or an '
- 'int; '
- 'markevery=%s' % (markevery,))
- #calc cumulative distance along path (in display
- # coords):
- disp_coords = affine.transform(tpath.vertices)
- delta = np.empty((len(disp_coords), 2),
- dtype=float)
- delta[0, :] = 0.0
- delta[1:, :] = (disp_coords[1:, :] -
- disp_coords[:-1, :])
- delta = np.sum(delta**2, axis=1)
- delta = np.sqrt(delta)
- delta = np.cumsum(delta)
- #calc distance between markers along path based on
- # the axes bounding box diagonal being a distance
- # of unity:
- scale = ax_transform.transform(
- np.array([[0, 0], [1, 1]]))
- scale = np.diff(scale, axis=0)
- scale = np.sum(scale**2)
- scale = np.sqrt(scale)
- marker_delta = np.arange(start * scale,
- delta[-1],
- step * scale)
- #find closest actual data point that is closest to
- # the theoretical distance along the path:
- inds = np.abs(delta[np.newaxis, :] -
- marker_delta[:, np.newaxis])
- inds = inds.argmin(axis=1)
- inds = np.unique(inds)
- # return, we are done here
- return Path(verts[inds],
- _slice_or_none(codes, inds))
- else:
- raise ValueError('`markevery` is a tuple with '
- 'len 2, but its second element is not an int '
- 'or a float; '
- 'markevery=%s' % (markevery,))
-
- elif isinstance(markevery, slice):
- # mazol tov, it's already a slice, just return
- return Path(verts[markevery],
- _slice_or_none(codes, markevery))
-
- elif iterable(markevery):
- #fancy indexing
- try:
- return Path(verts[markevery],
- _slice_or_none(codes, markevery))
-
- except (ValueError, IndexError):
- raise ValueError('`markevery` is iterable but '
- 'not a valid form of numpy fancy indexing; '
- 'markevery=%s' % (markevery,))
- else:
- raise ValueError('Value of `markevery` is not '
- 'recognized; '
- 'markevery=%s' % (markevery,))
-
-
-class Line2D(Artist):
- """
- A line - the line can have both a solid linestyle connecting all
- the vertices, and a marker at each vertex. Additionally, the
- drawing of the solid line is influenced by the drawstyle, e.g., one
- can create "stepped" lines in various styles.
-
-
- """
- lineStyles = _lineStyles = { # hidden names deprecated
- '-': '_draw_solid',
- '--': '_draw_dashed',
- '-.': '_draw_dash_dot',
- ':': '_draw_dotted',
- 'None': '_draw_nothing',
- ' ': '_draw_nothing',
- '': '_draw_nothing',
- }
-
- _drawStyles_l = {
- 'default': '_draw_lines',
- 'steps-mid': '_draw_steps_mid',
- 'steps-pre': '_draw_steps_pre',
- 'steps-post': '_draw_steps_post',
- }
-
- _drawStyles_s = {
- 'steps': '_draw_steps_pre',
- }
-
- # drawStyles should now be deprecated.
- drawStyles = {}
- drawStyles.update(_drawStyles_l)
- drawStyles.update(_drawStyles_s)
- # Need a list ordered with long names first:
- drawStyleKeys = list(_drawStyles_l) + list(_drawStyles_s)
-
- # Referenced here to maintain API. These are defined in
- # MarkerStyle
- markers = MarkerStyle.markers
- filled_markers = MarkerStyle.filled_markers
- fillStyles = MarkerStyle.fillstyles
-
- zorder = 2
- validCap = ('butt', 'round', 'projecting')
- validJoin = ('miter', 'round', 'bevel')
-
- def __str__(self):
- if self._label != "":
- return "Line2D(%s)" % (self._label)
- elif self._x is None:
- return "Line2D()"
- elif len(self._x) > 3:
- return "Line2D((%g,%g),(%g,%g),...,(%g,%g))"\
- % (self._x[0], self._y[0], self._x[0],
- self._y[0], self._x[-1], self._y[-1])
- else:
- return "Line2D(%s)"\
- % (",".join(["(%g,%g)" % (x, y) for x, y
- in zip(self._x, self._y)]))
-
- def __init__(self, xdata, ydata,
- linewidth=None, # all Nones default to rc
- linestyle=None,
- color=None,
- marker=None,
- markersize=None,
- markeredgewidth=None,
- markeredgecolor=None,
- markerfacecolor=None,
- markerfacecoloralt='none',
- fillstyle=None,
- antialiased=None,
- dash_capstyle=None,
- solid_capstyle=None,
- dash_joinstyle=None,
- solid_joinstyle=None,
- pickradius=5,
- drawstyle=None,
- markevery=None,
- **kwargs
- ):
- """
- Create a :class:`~matplotlib.lines.Line2D` instance with *x*
- and *y* data in sequences *xdata*, *ydata*.
-
- The kwargs are :class:`~matplotlib.lines.Line2D` properties:
-
- %(Line2D)s
-
- See :meth:`set_linestyle` for a decription of the line styles,
- :meth:`set_marker` for a description of the markers, and
- :meth:`set_drawstyle` for a description of the draw styles.
-
- """
- Artist.__init__(self)
-
- #convert sequences to numpy arrays
- if not iterable(xdata):
- raise RuntimeError('xdata must be a sequence')
- if not iterable(ydata):
- raise RuntimeError('ydata must be a sequence')
-
- if linewidth is None:
- linewidth = rcParams['lines.linewidth']
-
- if linestyle is None:
- linestyle = rcParams['lines.linestyle']
- if marker is None:
- marker = rcParams['lines.marker']
- if color is None:
- color = rcParams['lines.color']
-
- if markersize is None:
- markersize = rcParams['lines.markersize']
- if antialiased is None:
- antialiased = rcParams['lines.antialiased']
- if dash_capstyle is None:
- dash_capstyle = rcParams['lines.dash_capstyle']
- if dash_joinstyle is None:
- dash_joinstyle = rcParams['lines.dash_joinstyle']
- if solid_capstyle is None:
- solid_capstyle = rcParams['lines.solid_capstyle']
- if solid_joinstyle is None:
- solid_joinstyle = rcParams['lines.solid_joinstyle']
-
- if isinstance(linestyle, six.string_types):
- ds, ls = self._split_drawstyle_linestyle(linestyle)
- if ds is not None and drawstyle is not None and ds != drawstyle:
- raise ValueError("Inconsistent drawstyle ({0!r}) and "
- "linestyle ({1!r})".format(drawstyle,
- linestyle)
- )
- linestyle = ls
-
- if ds is not None:
- drawstyle = ds
-
- if drawstyle is None:
- drawstyle = 'default'
-
- self._dashcapstyle = None
- self._dashjoinstyle = None
- self._solidjoinstyle = None
- self._solidcapstyle = None
- self.set_dash_capstyle(dash_capstyle)
- self.set_dash_joinstyle(dash_joinstyle)
- self.set_solid_capstyle(solid_capstyle)
- self.set_solid_joinstyle(solid_joinstyle)
-
- self._linestyles = None
- self._drawstyle = None
- self._linewidth = linewidth
-
- # scaled dash + offset
- self._dashSeq = None
- self._dashOffset = 0
- # unscaled dash + offset
- # this is needed scaling the dash pattern by linewidth
- self._us_dashSeq = None
- self._us_dashOffset = 0
-
- self.set_linestyle(linestyle)
- self.set_drawstyle(drawstyle)
- self.set_linewidth(linewidth)
-
- self._color = None
- self.set_color(color)
- self._marker = MarkerStyle(marker, fillstyle)
-
- self._markevery = None
- self._markersize = None
- self._antialiased = None
-
- self.set_markevery(markevery)
- self.set_antialiased(antialiased)
- self.set_markersize(markersize)
-
- self._markeredgecolor = None
- self._markeredgewidth = None
- self._markerfacecolor = None
- self._markerfacecoloralt = None
-
- self.set_markerfacecolor(markerfacecolor)
- self.set_markerfacecoloralt(markerfacecoloralt)
- self.set_markeredgecolor(markeredgecolor)
- self.set_markeredgewidth(markeredgewidth)
-
- self.verticalOffset = None
-
- # update kwargs before updating data to give the caller a
- # chance to init axes (and hence unit support)
- self.update(kwargs)
- self.pickradius = pickradius
- self.ind_offset = 0
- if is_numlike(self._picker):
- self.pickradius = self._picker
-
- self._xorig = np.asarray([])
- self._yorig = np.asarray([])
- self._invalidx = True
- self._invalidy = True
- self._x = None
- self._y = None
- self._xy = None
- self._path = None
- self._transformed_path = None
- self._subslice = False
- self._x_filled = None # used in subslicing; only x is needed
-
- self.set_data(xdata, ydata)
-
- def contains(self, mouseevent):
- """
- Test whether the mouse event occurred on the line. The pick
- radius determines the precision of the location test (usually
- within five points of the value). Use
- :meth:`~matplotlib.lines.Line2D.get_pickradius` or
- :meth:`~matplotlib.lines.Line2D.set_pickradius` to view or
- modify it.
-
- Returns *True* if any values are within the radius along with
- ``{'ind': pointlist}``, where *pointlist* is the set of points
- within the radius.
-
- TODO: sort returned indices by distance
- """
- if callable(self._contains):
- return self._contains(self, mouseevent)
-
- if not is_numlike(self.pickradius):
- raise ValueError("pick radius should be a distance")
-
- # Make sure we have data to plot
- if self._invalidy or self._invalidx:
- self.recache()
- if len(self._xy) == 0:
- return False, {}
-
- # Convert points to pixels
- transformed_path = self._get_transformed_path()
- path, affine = transformed_path.get_transformed_path_and_affine()
- path = affine.transform_path(path)
- xy = path.vertices
- xt = xy[:, 0]
- yt = xy[:, 1]
-
- # Convert pick radius from points to pixels
- if self.figure is None:
- warnings.warn('no figure set when check if mouse is on line')
- pixels = self.pickradius
- else:
- pixels = self.figure.dpi / 72. * self.pickradius
-
- # the math involved in checking for containment (here and inside of
- # segment_hits) assumes that it is OK to overflow. In case the
- # application has set the error flags such that an exception is raised
- # on overflow, we temporarily set the appropriate error flags here and
- # set them back when we are finished.
- with np.errstate(all='ignore'):
- # Check for collision
- if self._linestyle in ['None', None]:
- # If no line, return the nearby point(s)
- d = (xt - mouseevent.x) ** 2 + (yt - mouseevent.y) ** 2
- ind, = np.nonzero(np.less_equal(d, pixels ** 2))
- else:
- # If line, return the nearby segment(s)
- ind = segment_hits(mouseevent.x, mouseevent.y, xt, yt, pixels)
- if self._drawstyle.startswith("steps"):
- ind //= 2
-
- ind += self.ind_offset
-
- # Return the point(s) within radius
- return len(ind) > 0, dict(ind=ind)
-
- def get_pickradius(self):
- """return the pick radius used for containment tests"""
- return self.pickradius
-
- def set_pickradius(self, d):
- """Set the pick radius used for containment tests.
-
- .. ACCEPTS: float distance in points
-
- Parameters
- ----------
- d : float
- Pick radius, in points.
- """
- self.pickradius = d
-
- def get_fillstyle(self):
- """
- return the marker fillstyle
- """
- return self._marker.get_fillstyle()
-
- def set_fillstyle(self, fs):
- """
- Set the marker fill style; 'full' means fill the whole marker.
- 'none' means no filling; other options are for half-filled markers.
-
- ACCEPTS: ['full' | 'left' | 'right' | 'bottom' | 'top' | 'none']
- """
- self._marker.set_fillstyle(fs)
- self.stale = True
-
- def set_markevery(self, every):
- """Set the markevery property to subsample the plot when using markers.
-
- e.g., if `every=5`, every 5-th marker will be plotted.
-
- ACCEPTS: [None | int | length-2 tuple of int | slice |
- list/array of int | float | length-2 tuple of float]
-
- Parameters
- ----------
- every: None | int | length-2 tuple of int | slice | list/array of int \
-| float | length-2 tuple of float
- Which markers to plot.
-
- - every=None, every point will be plotted.
- - every=N, every N-th marker will be plotted starting with
- marker 0.
- - every=(start, N), every N-th marker, starting at point
- start, will be plotted.
- - every=slice(start, end, N), every N-th marker, starting at
- point start, upto but not including point end, will be plotted.
- - every=[i, j, m, n], only markers at points i, j, m, and n
- will be plotted.
- - every=0.1, (i.e. a float) then markers will be spaced at
- approximately equal distances along the line; the distance
- along the line between markers is determined by multiplying the
- display-coordinate distance of the axes bounding-box diagonal
- by the value of every.
- - every=(0.5, 0.1) (i.e. a length-2 tuple of float), the
- same functionality as every=0.1 is exhibited but the first
- marker will be 0.5 multiplied by the
- display-cordinate-diagonal-distance along the line.
-
- Notes
- -----
- Setting the markevery property will only show markers at actual data
- points. When using float arguments to set the markevery property
- on irregularly spaced data, the markers will likely not appear evenly
- spaced because the actual data points do not coincide with the
- theoretical spacing between markers.
-
- When using a start offset to specify the first marker, the offset will
- be from the first data point which may be different from the first
- the visible data point if the plot is zoomed in.
-
- If zooming in on a plot when using float arguments then the actual
- data points that have markers will change because the distance between
- markers is always determined from the display-coordinates
- axes-bounding-box-diagonal regardless of the actual axes data limits.
-
- """
- if self._markevery != every:
- self.stale = True
- self._markevery = every
-
- def get_markevery(self):
- """return the markevery setting"""
- return self._markevery
-
- def set_picker(self, p):
- """Sets the event picker details for the line.
-
- ACCEPTS: float distance in points or callable pick function
- ``fn(artist, event)``
- """
- if callable(p):
- self._contains = p
- else:
- self.pickradius = p
- self._picker = p
-
- def get_window_extent(self, renderer):
- bbox = Bbox([[0, 0], [0, 0]])
- trans_data_to_xy = self.get_transform().transform
- bbox.update_from_data_xy(trans_data_to_xy(self.get_xydata()),
- ignore=True)
- # correct for marker size, if any
- if self._marker:
- ms = (self._markersize / 72.0 * self.figure.dpi) * 0.5
- bbox = bbox.padded(ms)
- return bbox
-
- @Artist.axes.setter
- def axes(self, ax):
- # call the set method from the base-class property
- Artist.axes.fset(self, ax)
- if ax is not None:
- # connect unit-related callbacks
- if ax.xaxis is not None:
- self._xcid = ax.xaxis.callbacks.connect('units',
- self.recache_always)
- if ax.yaxis is not None:
- self._ycid = ax.yaxis.callbacks.connect('units',
- self.recache_always)
-
- def set_data(self, *args):
- """
- Set the x and y data
-
- ACCEPTS: 2D array (rows are x, y) or two 1D arrays
- """
- if len(args) == 1:
- x, y = args[0]
- else:
- x, y = args
-
- self.set_xdata(x)
- self.set_ydata(y)
-
- def recache_always(self):
- self.recache(always=True)
-
- def recache(self, always=False):
- if always or self._invalidx:
- xconv = self.convert_xunits(self._xorig)
- x = _to_unmasked_float_array(xconv).ravel()
- else:
- x = self._x
- if always or self._invalidy:
- yconv = self.convert_yunits(self._yorig)
- y = _to_unmasked_float_array(yconv).ravel()
- else:
- y = self._y
-
- self._xy = np.column_stack(np.broadcast_arrays(x, y)).astype(float)
- self._x, self._y = self._xy.T # views
-
- self._subslice = False
- if (self.axes and len(x) > 1000 and self._is_sorted(x) and
- self.axes.name == 'rectilinear' and
- self.axes.get_xscale() == 'linear' and
- self._markevery is None and
- self.get_clip_on() is True):
- self._subslice = True
- nanmask = np.isnan(x)
- if nanmask.any():
- self._x_filled = self._x.copy()
- indices = np.arange(len(x))
- self._x_filled[nanmask] = np.interp(indices[nanmask],
- indices[~nanmask], self._x[~nanmask])
- else:
- self._x_filled = self._x
-
- if self._path is not None:
- interpolation_steps = self._path._interpolation_steps
- else:
- interpolation_steps = 1
- xy = STEP_LOOKUP_MAP[self._drawstyle](*self._xy.T)
- self._path = Path(np.asarray(xy).T,
- _interpolation_steps=interpolation_steps)
- self._transformed_path = None
- self._invalidx = False
- self._invalidy = False
-
- def _transform_path(self, subslice=None):
- """
- Puts a TransformedPath instance at self._transformed_path;
- all invalidation of the transform is then handled by the
- TransformedPath instance.
- """
- # Masked arrays are now handled by the Path class itself
- if subslice is not None:
- xy = STEP_LOOKUP_MAP[self._drawstyle](*self._xy[subslice, :].T)
- _path = Path(np.asarray(xy).T,
- _interpolation_steps=self._path._interpolation_steps)
- else:
- _path = self._path
- self._transformed_path = TransformedPath(_path, self.get_transform())
-
- def _get_transformed_path(self):
- """
- Return the :class:`~matplotlib.transforms.TransformedPath` instance
- of this line.
- """
- if self._transformed_path is None:
- self._transform_path()
- return self._transformed_path
-
- def set_transform(self, t):
- """
- set the Transformation instance used by this artist
-
- ACCEPTS: a :class:`matplotlib.transforms.Transform` instance
- """
- Artist.set_transform(self, t)
- self._invalidx = True
- self._invalidy = True
- self.stale = True
-
- def _is_sorted(self, x):
- """return True if x is sorted in ascending order"""
- # We don't handle the monotonically decreasing case.
- return _path.is_sorted(x)
-
- @allow_rasterization
- def draw(self, renderer):
- """draw the Line with `renderer` unless visibility is False"""
- if not self.get_visible():
- return
-
- if self._invalidy or self._invalidx:
- self.recache()
- self.ind_offset = 0 # Needed for contains() method.
- if self._subslice and self.axes:
- x0, x1 = self.axes.get_xbound()
- i0, = self._x_filled.searchsorted([x0], 'left')
- i1, = self._x_filled.searchsorted([x1], 'right')
- subslice = slice(max(i0 - 1, 0), i1 + 1)
- self.ind_offset = subslice.start
- self._transform_path(subslice)
- else:
- subslice = None
-
- if self.get_path_effects():
- from matplotlib.patheffects import PathEffectRenderer
- renderer = PathEffectRenderer(self.get_path_effects(), renderer)
-
- renderer.open_group('line2d', self.get_gid())
- if self._lineStyles[self._linestyle] != '_draw_nothing':
- tpath, affine = (self._get_transformed_path()
- .get_transformed_path_and_affine())
- if len(tpath.vertices):
- gc = renderer.new_gc()
- self._set_gc_clip(gc)
-
- lc_rgba = mcolors.to_rgba(self._color, self._alpha)
- gc.set_foreground(lc_rgba, isRGBA=True)
-
- gc.set_antialiased(self._antialiased)
- gc.set_linewidth(self._linewidth)
-
- if self.is_dashed():
- cap = self._dashcapstyle
- join = self._dashjoinstyle
- else:
- cap = self._solidcapstyle
- join = self._solidjoinstyle
- gc.set_joinstyle(join)
- gc.set_capstyle(cap)
- gc.set_snap(self.get_snap())
- if self.get_sketch_params() is not None:
- gc.set_sketch_params(*self.get_sketch_params())
-
- gc.set_dashes(self._dashOffset, self._dashSeq)
- renderer.draw_path(gc, tpath, affine.frozen())
- gc.restore()
-
- if self._marker and self._markersize > 0:
- gc = renderer.new_gc()
- self._set_gc_clip(gc)
- gc.set_linewidth(self._markeredgewidth)
- gc.set_antialiased(self._antialiased)
-
- ec_rgba = mcolors.to_rgba(
- self.get_markeredgecolor(), self._alpha)
- fc_rgba = mcolors.to_rgba(
- self._get_markerfacecolor(), self._alpha)
- fcalt_rgba = mcolors.to_rgba(
- self._get_markerfacecolor(alt=True), self._alpha)
- # If the edgecolor is "auto", it is set according to the *line*
- # color but inherits the alpha value of the *face* color, if any.
- if (cbook._str_equal(self._markeredgecolor, "auto")
- and not cbook._str_lower_equal(
- self.get_markerfacecolor(), "none")):
- ec_rgba = ec_rgba[:3] + (fc_rgba[3],)
- gc.set_foreground(ec_rgba, isRGBA=True)
-
- marker = self._marker
-
- # Markers *must* be drawn ignoring the drawstyle (but don't pay the
- # recaching if drawstyle is already "default").
- if self.get_drawstyle() != "default":
- with cbook._setattr_cm(
- self, _drawstyle="default", _transformed_path=None):
- self.recache()
- self._transform_path(subslice)
- tpath, affine = (self._get_transformed_path()
- .get_transformed_points_and_affine())
- else:
- tpath, affine = (self._get_transformed_path()
- .get_transformed_points_and_affine())
-
- if len(tpath.vertices):
- # subsample the markers if markevery is not None
- markevery = self.get_markevery()
- if markevery is not None:
- subsampled = _mark_every_path(markevery, tpath,
- affine, self.axes.transAxes)
- else:
- subsampled = tpath
-
- snap = marker.get_snap_threshold()
- if type(snap) == float:
- snap = renderer.points_to_pixels(self._markersize) >= snap
- gc.set_snap(snap)
- gc.set_joinstyle(marker.get_joinstyle())
- gc.set_capstyle(marker.get_capstyle())
- marker_path = marker.get_path()
- marker_trans = marker.get_transform()
- w = renderer.points_to_pixels(self._markersize)
-
- if cbook._str_equal(marker.get_marker(), ","):
- gc.set_linewidth(0)
- else:
- # Don't scale for pixels, and don't stroke them
- marker_trans = marker_trans.scale(w)
-
- renderer.draw_markers(gc, marker_path, marker_trans,
- subsampled, affine.frozen(),
- fc_rgba)
-
- alt_marker_path = marker.get_alt_path()
- if alt_marker_path:
- alt_marker_trans = marker.get_alt_transform()
- alt_marker_trans = alt_marker_trans.scale(w)
- renderer.draw_markers(
- gc, alt_marker_path, alt_marker_trans, subsampled,
- affine.frozen(), fcalt_rgba)
-
- gc.restore()
-
- renderer.close_group('line2d')
- self.stale = False
-
- def get_antialiased(self):
- return self._antialiased
-
- def get_color(self):
- return self._color
-
- def get_drawstyle(self):
- return self._drawstyle
-
- def get_linestyle(self):
- return self._linestyle
-
- def get_linewidth(self):
- return self._linewidth
-
- def get_marker(self):
- return self._marker.get_marker()
-
- def get_markeredgecolor(self):
- mec = self._markeredgecolor
- if isinstance(mec, six.string_types) and mec == 'auto':
- if rcParams['_internal.classic_mode']:
- if self._marker.get_marker() in ('.', ','):
- return self._color
- if self._marker.is_filled() and self.get_fillstyle() != 'none':
- return 'k' # Bad hard-wired default...
- return self._color
- else:
- return mec
-
- def get_markeredgewidth(self):
- return self._markeredgewidth
-
- def _get_markerfacecolor(self, alt=False):
- if alt:
- fc = self._markerfacecoloralt
- else:
- fc = self._markerfacecolor
- if cbook._str_lower_equal(fc, 'auto'):
- if self.get_fillstyle() == 'none':
- return 'none'
- else:
- return self._color
- else:
- return fc
-
- def get_markerfacecolor(self):
- return self._get_markerfacecolor(alt=False)
-
- def get_markerfacecoloralt(self):
- return self._get_markerfacecolor(alt=True)
-
- def get_markersize(self):
- return self._markersize
-
- def get_data(self, orig=True):
- """
- Return the xdata, ydata.
-
- If *orig* is *True*, return the original data.
- """
- return self.get_xdata(orig=orig), self.get_ydata(orig=orig)
-
- def get_xdata(self, orig=True):
- """
- Return the xdata.
-
- If *orig* is *True*, return the original data, else the
- processed data.
- """
- if orig:
- return self._xorig
- if self._invalidx:
- self.recache()
- return self._x
-
- def get_ydata(self, orig=True):
- """
- Return the ydata.
-
- If *orig* is *True*, return the original data, else the
- processed data.
- """
- if orig:
- return self._yorig
- if self._invalidy:
- self.recache()
- return self._y
-
- def get_path(self):
- """
- Return the :class:`~matplotlib.path.Path` object associated
- with this line.
- """
- if self._invalidy or self._invalidx:
- self.recache()
- return self._path
-
- def get_xydata(self):
- """
- Return the *xy* data as a Nx2 numpy array.
- """
- if self._invalidy or self._invalidx:
- self.recache()
- return self._xy
-
- def set_antialiased(self, b):
- """
- Set whether to use antialiased rendering.
-
- Parameters
- ----------
- b : bool
- .. ACCEPTS: bool
- """
- if self._antialiased != b:
- self.stale = True
- self._antialiased = b
-
- def set_color(self, color):
- """
- Set the color of the line
-
- ACCEPTS: any matplotlib color
- """
- self._color = color
- self.stale = True
-
- def set_drawstyle(self, drawstyle):
- """
- Set the drawstyle of the plot
-
- 'default' connects the points with lines. The steps variants
- produce step-plots. 'steps' is equivalent to 'steps-pre' and
- is maintained for backward-compatibility.
-
- ACCEPTS: ['default' | 'steps' | 'steps-pre' | 'steps-mid' |
- 'steps-post']
- """
- if drawstyle is None:
- drawstyle = 'default'
- if drawstyle not in self.drawStyles:
- raise ValueError('Unrecognized drawstyle {!r}'.format(drawstyle))
- if self._drawstyle != drawstyle:
- self.stale = True
- # invalidate to trigger a recache of the path
- self._invalidx = True
- self._drawstyle = drawstyle
-
- def set_linewidth(self, w):
- """
- Set the line width in points
-
- ACCEPTS: float value in points
- """
- w = float(w)
-
- if self._linewidth != w:
- self.stale = True
- self._linewidth = w
- # rescale the dashes + offset
- self._dashOffset, self._dashSeq = _scale_dashes(
- self._us_dashOffset, self._us_dashSeq, self._linewidth)
-
- def _split_drawstyle_linestyle(self, ls):
- '''Split drawstyle from linestyle string
-
- If `ls` is only a drawstyle default to returning a linestyle
- of '-'.
-
- Parameters
- ----------
- ls : str
- The linestyle to be processed
-
- Returns
- -------
- ret_ds : str or None
- If the linestyle string does not contain a drawstyle prefix
- return None, otherwise return it.
-
- ls : str
- The linestyle with the drawstyle (if any) stripped.
- '''
- ret_ds = None
- for ds in self.drawStyleKeys: # long names are first in the list
- if ls.startswith(ds):
- ret_ds = ds
- if len(ls) > len(ds):
- ls = ls[len(ds):]
- else:
- ls = '-'
- break
-
- return ret_ds, ls
-
- def set_linestyle(self, ls):
- """
- Set the linestyle of the line (also accepts drawstyles,
- e.g., ``'steps--'``)
-
-
- =========================== =================
- linestyle description
- =========================== =================
- ``'-'`` or ``'solid'`` solid line
- ``'--'`` or ``'dashed'`` dashed line
- ``'-.'`` or ``'dashdot'`` dash-dotted line
- ``':'`` or ``'dotted'`` dotted line
- ``'None'`` draw nothing
- ``' '`` draw nothing
- ``''`` draw nothing
- =========================== =================
-
- 'steps' is equivalent to 'steps-pre' and is maintained for
- backward-compatibility.
-
- Alternatively a dash tuple of the following form can be provided::
-
- (offset, onoffseq),
-
- where ``onoffseq`` is an even length tuple of on and off ink
- in points.
-
-
- ACCEPTS: ['solid' | 'dashed', 'dashdot', 'dotted' |
- (offset, on-off-dash-seq) |
- ``'-'`` | ``'--'`` | ``'-.'`` | ``':'`` | ``'None'`` |
- ``' '`` | ``''``]
-
- .. seealso::
-
- :meth:`set_drawstyle`
- To set the drawing style (stepping) of the plot.
-
- Parameters
- ----------
- ls : { ``'-'``, ``'--'``, ``'-.'``, ``':'``} and more see description
- The line style.
- """
- if isinstance(ls, six.string_types):
- ds, ls = self._split_drawstyle_linestyle(ls)
- if ds is not None:
- self.set_drawstyle(ds)
-
- if ls in [' ', '', 'none']:
- ls = 'None'
-
- if ls not in self._lineStyles:
- try:
- ls = ls_mapper_r[ls]
- except KeyError:
- raise ValueError(("You passed in an invalid linestyle, "
- "`{0}`. See "
- "docs of Line2D.set_linestyle for "
- "valid values.").format(ls))
- self._linestyle = ls
- else:
- self._linestyle = '--'
-
- # get the unscaled dashes
- self._us_dashOffset, self._us_dashSeq = _get_dash_pattern(ls)
- # compute the linewidth scaled dashes
- self._dashOffset, self._dashSeq = _scale_dashes(
- self._us_dashOffset, self._us_dashSeq, self._linewidth)
-
- @docstring.dedent_interpd
- def set_marker(self, marker):
- """
- Set the line marker
-
- ACCEPTS: :mod:`A valid marker style <matplotlib.markers>`
-
- Parameters
- ----------
-
- marker: marker style
- See `~matplotlib.markers` for full description of possible
- argument
-
- """
- self._marker.set_marker(marker)
- self.stale = True
-
- def set_markeredgecolor(self, ec):
- """
- Set the marker edge color
-
- ACCEPTS: any matplotlib color
- """
- if ec is None:
- ec = 'auto'
- if self._markeredgecolor is None or \
- np.any(self._markeredgecolor != ec):
- self.stale = True
- self._markeredgecolor = ec
-
- def set_markeredgewidth(self, ew):
- """
- Set the marker edge width in points
-
- ACCEPTS: float value in points
- """
- if ew is None:
- ew = rcParams['lines.markeredgewidth']
- if self._markeredgewidth != ew:
- self.stale = True
- self._markeredgewidth = ew
-
- def set_markerfacecolor(self, fc):
- """
- Set the marker face color.
-
- ACCEPTS: any matplotlib color
- """
- if fc is None:
- fc = 'auto'
- if np.any(self._markerfacecolor != fc):
- self.stale = True
- self._markerfacecolor = fc
-
- def set_markerfacecoloralt(self, fc):
- """
- Set the alternate marker face color.
-
- ACCEPTS: any matplotlib color
- """
- if fc is None:
- fc = 'auto'
- if np.any(self._markerfacecoloralt != fc):
- self.stale = True
- self._markerfacecoloralt = fc
-
- def set_markersize(self, sz):
- """
- Set the marker size in points
-
- ACCEPTS: float
- """
- sz = float(sz)
- if self._markersize != sz:
- self.stale = True
- self._markersize = sz
-
- def set_xdata(self, x):
- """
- Set the data np.array for x
-
- ACCEPTS: 1D array
- """
- self._xorig = x
- self._invalidx = True
- self.stale = True
-
- def set_ydata(self, y):
- """
- Set the data np.array for y
-
- ACCEPTS: 1D array
- """
- self._yorig = y
- self._invalidy = True
- self.stale = True
-
- def set_dashes(self, seq):
- """
- Set the dash sequence, sequence of dashes with on off ink in
- points. If seq is empty or if seq = (None, None), the
- linestyle will be set to solid.
-
- ACCEPTS: sequence of on/off ink in points
- """
- if seq == (None, None) or len(seq) == 0:
- self.set_linestyle('-')
- else:
- self.set_linestyle((0, seq))
-
- def update_from(self, other):
- """copy properties from other to self"""
- Artist.update_from(self, other)
- self._linestyle = other._linestyle
- self._linewidth = other._linewidth
- self._color = other._color
- self._markersize = other._markersize
- self._markerfacecolor = other._markerfacecolor
- self._markerfacecoloralt = other._markerfacecoloralt
- self._markeredgecolor = other._markeredgecolor
- self._markeredgewidth = other._markeredgewidth
- self._dashSeq = other._dashSeq
- self._us_dashSeq = other._us_dashSeq
- self._dashOffset = other._dashOffset
- self._us_dashOffset = other._us_dashOffset
- self._dashcapstyle = other._dashcapstyle
- self._dashjoinstyle = other._dashjoinstyle
- self._solidcapstyle = other._solidcapstyle
- self._solidjoinstyle = other._solidjoinstyle
-
- self._linestyle = other._linestyle
- self._marker = MarkerStyle(other._marker.get_marker(),
- other._marker.get_fillstyle())
- self._drawstyle = other._drawstyle
-
- def _get_rgba_face(self, alt=False):
- return mcolors.to_rgba(self._get_markerfacecolor(alt=alt), self._alpha)
-
- def _get_rgba_ln_color(self, alt=False):
- return mcolors.to_rgba(self._color, self._alpha)
-
- # some aliases....
- def set_aa(self, val):
- 'alias for set_antialiased'
- self.set_antialiased(val)
-
- def set_c(self, val):
- 'alias for set_color'
- self.set_color(val)
-
- def set_ls(self, val):
- """alias for set_linestyle"""
- self.set_linestyle(val)
-
- def set_lw(self, val):
- """alias for set_linewidth"""
- self.set_linewidth(val)
-
- def set_mec(self, val):
- """alias for set_markeredgecolor"""
- self.set_markeredgecolor(val)
-
- def set_mew(self, val):
- """alias for set_markeredgewidth"""
- self.set_markeredgewidth(val)
-
- def set_mfc(self, val):
- """alias for set_markerfacecolor"""
- self.set_markerfacecolor(val)
-
- def set_mfcalt(self, val):
- """alias for set_markerfacecoloralt"""
- self.set_markerfacecoloralt(val)
-
- def set_ms(self, val):
- """alias for set_markersize"""
- self.set_markersize(val)
-
- def get_aa(self):
- """alias for get_antialiased"""
- return self.get_antialiased()
-
- def get_c(self):
- """alias for get_color"""
- return self.get_color()
-
- def get_ls(self):
- """alias for get_linestyle"""
- return self.get_linestyle()
-
- def get_lw(self):
- """alias for get_linewidth"""
- return self.get_linewidth()
-
- def get_mec(self):
- """alias for get_markeredgecolor"""
- return self.get_markeredgecolor()
-
- def get_mew(self):
- """alias for get_markeredgewidth"""
- return self.get_markeredgewidth()
-
- def get_mfc(self):
- """alias for get_markerfacecolor"""
- return self.get_markerfacecolor()
-
- def get_mfcalt(self, alt=False):
- """alias for get_markerfacecoloralt"""
- return self.get_markerfacecoloralt()
-
- def get_ms(self):
- """alias for get_markersize"""
- return self.get_markersize()
-
- def set_dash_joinstyle(self, s):
- """
- Set the join style for dashed linestyles
- ACCEPTS: ['miter' | 'round' | 'bevel']
- """
- s = s.lower()
- if s not in self.validJoin:
- raise ValueError('set_dash_joinstyle passed "%s";\n' % (s,)
- + 'valid joinstyles are %s' % (self.validJoin,))
- if self._dashjoinstyle != s:
- self.stale = True
- self._dashjoinstyle = s
-
- def set_solid_joinstyle(self, s):
- """
- Set the join style for solid linestyles
- ACCEPTS: ['miter' | 'round' | 'bevel']
- """
- s = s.lower()
- if s not in self.validJoin:
- raise ValueError('set_solid_joinstyle passed "%s";\n' % (s,)
- + 'valid joinstyles are %s' % (self.validJoin,))
-
- if self._solidjoinstyle != s:
- self.stale = True
- self._solidjoinstyle = s
-
- def get_dash_joinstyle(self):
- """
- Get the join style for dashed linestyles
- """
- return self._dashjoinstyle
-
- def get_solid_joinstyle(self):
- """
- Get the join style for solid linestyles
- """
- return self._solidjoinstyle
-
- def set_dash_capstyle(self, s):
- """
- Set the cap style for dashed linestyles
-
- ACCEPTS: ['butt' | 'round' | 'projecting']
- """
- s = s.lower()
- if s not in self.validCap:
- raise ValueError('set_dash_capstyle passed "%s";\n' % (s,)
- + 'valid capstyles are %s' % (self.validCap,))
- if self._dashcapstyle != s:
- self.stale = True
- self._dashcapstyle = s
-
- def set_solid_capstyle(self, s):
- """
- Set the cap style for solid linestyles
-
- ACCEPTS: ['butt' | 'round' | 'projecting']
- """
- s = s.lower()
- if s not in self.validCap:
- raise ValueError('set_solid_capstyle passed "%s";\n' % (s,)
- + 'valid capstyles are %s' % (self.validCap,))
- if self._solidcapstyle != s:
- self.stale = True
- self._solidcapstyle = s
-
- def get_dash_capstyle(self):
- """
- Get the cap style for dashed linestyles
- """
- return self._dashcapstyle
-
- def get_solid_capstyle(self):
- """
- Get the cap style for solid linestyles
- """
- return self._solidcapstyle
-
- def is_dashed(self):
- 'return True if line is dashstyle'
- return self._linestyle in ('--', '-.', ':')
-
-
-class VertexSelector(object):
- """
- Manage the callbacks to maintain a list of selected vertices for
- :class:`matplotlib.lines.Line2D`. Derived classes should override
- :meth:`~matplotlib.lines.VertexSelector.process_selected` to do
- something with the picks.
-
- Here is an example which highlights the selected verts with red
- circles::
-
- import numpy as np
- import matplotlib.pyplot as plt
- import matplotlib.lines as lines
-
- class HighlightSelected(lines.VertexSelector):
- def __init__(self, line, fmt='ro', **kwargs):
- lines.VertexSelector.__init__(self, line)
- self.markers, = self.axes.plot([], [], fmt, **kwargs)
-
- def process_selected(self, ind, xs, ys):
- self.markers.set_data(xs, ys)
- self.canvas.draw()
-
- fig, ax = plt.subplots()
- x, y = np.random.rand(2, 30)
- line, = ax.plot(x, y, 'bs-', picker=5)
-
- selector = HighlightSelected(line)
- plt.show()
-
- """
- def __init__(self, line):
- """
- Initialize the class with a :class:`matplotlib.lines.Line2D`
- instance. The line should already be added to some
- :class:`matplotlib.axes.Axes` instance and should have the
- picker property set.
- """
- if line.axes is None:
- raise RuntimeError('You must first add the line to the Axes')
-
- if line.get_picker() is None:
- raise RuntimeError('You must first set the picker property '
- 'of the line')
-
- self.axes = line.axes
- self.line = line
- self.canvas = self.axes.figure.canvas
- self.cid = self.canvas.mpl_connect('pick_event', self.onpick)
-
- self.ind = set()
-
- def process_selected(self, ind, xs, ys):
- """
- Default "do nothing" implementation of the
- :meth:`process_selected` method.
-
- *ind* are the indices of the selected vertices. *xs* and *ys*
- are the coordinates of the selected vertices.
- """
- pass
-
- def onpick(self, event):
- """When the line is picked, update the set of selected indices."""
- if event.artist is not self.line:
- return
- self.ind ^= set(event.ind)
- ind = sorted(self.ind)
- xdata, ydata = self.line.get_data()
- self.process_selected(ind, xdata[ind], ydata[ind])
-
-
-lineStyles = Line2D._lineStyles
-lineMarkers = MarkerStyle.markers
-drawStyles = Line2D.drawStyles
-fillStyles = MarkerStyle.fillstyles
-
-docstring.interpd.update(Line2D=artist.kwdoc(Line2D))
-
-# You can not set the docstring of an instancemethod,
-# but you can on the underlying function. Go figure.
-docstring.dedent_interpd(Line2D.__init__)
diff --git a/contrib/python/matplotlib/py2/matplotlib/markers.py b/contrib/python/matplotlib/py2/matplotlib/markers.py
deleted file mode 100644
index 3669922026..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/markers.py
+++ /dev/null
@@ -1,898 +0,0 @@
-"""
-This module contains functions to handle markers. Used by both the
-marker functionality of `~matplotlib.axes.Axes.plot` and
-`~matplotlib.axes.Axes.scatter`.
-
-All possible markers are defined here:
-
-============================== ===============================================
-marker description
-============================== ===============================================
-`"."` point
-`","` pixel
-`"o"` circle
-`"v"` triangle_down
-`"^"` triangle_up
-`"<"` triangle_left
-`">"` triangle_right
-`"1"` tri_down
-`"2"` tri_up
-`"3"` tri_left
-`"4"` tri_right
-`"8"` octagon
-`"s"` square
-`"p"` pentagon
-`"P"` plus (filled)
-`"*"` star
-`"h"` hexagon1
-`"H"` hexagon2
-`"+"` plus
-`"x"` x
-`"X"` x (filled)
-`"D"` diamond
-`"d"` thin_diamond
-`"|"` vline
-`"_"` hline
-TICKLEFT tickleft
-TICKRIGHT tickright
-TICKUP tickup
-TICKDOWN tickdown
-CARETLEFT caretleft (centered at tip)
-CARETRIGHT caretright (centered at tip)
-CARETUP caretup (centered at tip)
-CARETDOWN caretdown (centered at tip)
-CARETLEFTBASE caretleft (centered at base)
-CARETRIGHTBASE caretright (centered at base)
-CARETUPBASE caretup (centered at base)
-`"None"`, `" "` or `""` nothing
-``'$...$'`` render the string using mathtext.
-`verts` a list of (x, y) pairs used for Path vertices.
- The center of the marker is located at (0,0) and
- the size is normalized.
-path a `~matplotlib.path.Path` instance.
-(`numsides`, `style`, `angle`) The marker can also be a tuple (`numsides`,
- `style`, `angle`), which will create a custom,
- regular symbol.
-
- `numsides`:
- the number of sides
-
- `style`:
- the style of the regular symbol:
-
- 0
- a regular polygon
- 1
- a star-like symbol
- 2
- an asterisk
- 3
- a circle (`numsides` and `angle` is
- ignored)
-
- `angle`:
- the angle of rotation of the symbol
-============================== ===============================================
-
-For backward compatibility, the form (`verts`, 0) is also accepted,
-but it is equivalent to just `verts` for giving a raw set of vertices
-that define the shape.
-
-`None` is the default which means 'nothing', however this table is
-referred to from other docs for the valid inputs from marker inputs and in
-those cases `None` still means 'default'.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-try:
- from collections.abc import Sized
-except ImportError:
- from collections import Sized
-
-import numpy as np
-
-from . import rcParams
-from .cbook import is_math_text, is_numlike
-from .path import Path
-from .transforms import IdentityTransform, Affine2D
-
-# special-purpose marker identifiers:
-(TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN,
- CARETLEFT, CARETRIGHT, CARETUP, CARETDOWN,
- CARETLEFTBASE, CARETRIGHTBASE, CARETUPBASE, CARETDOWNBASE) = xrange(12)
-
-_empty_path = Path(np.empty((0, 2)))
-
-
-class MarkerStyle(object):
-
- markers = {
- '.': 'point',
- ',': 'pixel',
- 'o': 'circle',
- 'v': 'triangle_down',
- '^': 'triangle_up',
- '<': 'triangle_left',
- '>': 'triangle_right',
- '1': 'tri_down',
- '2': 'tri_up',
- '3': 'tri_left',
- '4': 'tri_right',
- '8': 'octagon',
- 's': 'square',
- 'p': 'pentagon',
- '*': 'star',
- 'h': 'hexagon1',
- 'H': 'hexagon2',
- '+': 'plus',
- 'x': 'x',
- 'D': 'diamond',
- 'd': 'thin_diamond',
- '|': 'vline',
- '_': 'hline',
- 'P': 'plus_filled',
- 'X': 'x_filled',
- TICKLEFT: 'tickleft',
- TICKRIGHT: 'tickright',
- TICKUP: 'tickup',
- TICKDOWN: 'tickdown',
- CARETLEFT: 'caretleft',
- CARETRIGHT: 'caretright',
- CARETUP: 'caretup',
- CARETDOWN: 'caretdown',
- CARETLEFTBASE: 'caretleftbase',
- CARETRIGHTBASE: 'caretrightbase',
- CARETUPBASE: 'caretupbase',
- CARETDOWNBASE: 'caretdownbase',
- "None": 'nothing',
- None: 'nothing',
- ' ': 'nothing',
- '': 'nothing'
- }
-
- # Just used for informational purposes. is_filled()
- # is calculated in the _set_* functions.
- filled_markers = (
- 'o', 'v', '^', '<', '>', '8', 's', 'p', '*', 'h', 'H', 'D', 'd',
- 'P', 'X')
-
- fillstyles = ('full', 'left', 'right', 'bottom', 'top', 'none')
- _half_fillstyles = ('left', 'right', 'bottom', 'top')
-
- # TODO: Is this ever used as a non-constant?
- _point_size_reduction = 0.5
-
- def __init__(self, marker=None, fillstyle=None):
- """
- MarkerStyle
-
- Attributes
- ----------
- markers : list of known marks
-
- fillstyles : list of known fillstyles
-
- filled_markers : list of known filled markers.
-
- Parameters
- ----------
- marker : string or array_like, optional, default: None
- See the descriptions of possible markers in the module docstring.
-
- fillstyle : string, optional, default: 'full'
- 'full', 'left", 'right', 'bottom', 'top', 'none'
- """
- self._marker_function = None
- self.set_fillstyle(fillstyle)
- self.set_marker(marker)
-
- def __getstate__(self):
- d = self.__dict__.copy()
- d.pop('_marker_function')
- return d
-
- def __setstate__(self, statedict):
- self.__dict__ = statedict
- self.set_marker(self._marker)
-
- def _recache(self):
- if self._marker_function is None:
- return
- self._path = _empty_path
- self._transform = IdentityTransform()
- self._alt_path = None
- self._alt_transform = None
- self._snap_threshold = None
- self._joinstyle = 'round'
- self._capstyle = 'butt'
- self._filled = True
- self._marker_function()
-
- if six.PY3:
- def __bool__(self):
- return bool(len(self._path.vertices))
- else:
- def __nonzero__(self):
- return bool(len(self._path.vertices))
-
- def is_filled(self):
- return self._filled
-
- def get_fillstyle(self):
- return self._fillstyle
-
- def set_fillstyle(self, fillstyle):
- """
- Sets fillstyle
-
- Parameters
- ----------
- fillstyle : string amongst known fillstyles
- """
- if fillstyle is None:
- fillstyle = rcParams['markers.fillstyle']
- if fillstyle not in self.fillstyles:
- raise ValueError("Unrecognized fillstyle %s"
- % ' '.join(self.fillstyles))
- self._fillstyle = fillstyle
- self._recache()
-
- def get_joinstyle(self):
- return self._joinstyle
-
- def get_capstyle(self):
- return self._capstyle
-
- def get_marker(self):
- return self._marker
-
- def set_marker(self, marker):
- if (isinstance(marker, np.ndarray) and marker.ndim == 2 and
- marker.shape[1] == 2):
- self._marker_function = self._set_vertices
- elif (isinstance(marker, Sized) and len(marker) in (2, 3) and
- marker[1] in (0, 1, 2, 3)):
- self._marker_function = self._set_tuple_marker
- elif (not isinstance(marker, (np.ndarray, list)) and
- marker in self.markers):
- self._marker_function = getattr(
- self, '_set_' + self.markers[marker])
- elif isinstance(marker, six.string_types) and is_math_text(marker):
- self._marker_function = self._set_mathtext_path
- elif isinstance(marker, Path):
- self._marker_function = self._set_path_marker
- else:
- try:
- Path(marker)
- self._marker_function = self._set_vertices
- except ValueError:
- raise ValueError('Unrecognized marker style'
- ' {0}'.format(marker))
-
- self._marker = marker
- self._recache()
-
- def get_path(self):
- return self._path
-
- def get_transform(self):
- return self._transform.frozen()
-
- def get_alt_path(self):
- return self._alt_path
-
- def get_alt_transform(self):
- return self._alt_transform.frozen()
-
- def get_snap_threshold(self):
- return self._snap_threshold
-
- def _set_nothing(self):
- self._filled = False
-
- def _set_custom_marker(self, path):
- verts = path.vertices
- rescale = max(np.max(np.abs(verts[:, 0])),
- np.max(np.abs(verts[:, 1])))
- self._transform = Affine2D().scale(0.5 / rescale)
- self._path = path
-
- def _set_path_marker(self):
- self._set_custom_marker(self._marker)
-
- def _set_vertices(self):
- verts = self._marker
- marker = Path(verts)
- self._set_custom_marker(marker)
-
- def _set_tuple_marker(self):
- marker = self._marker
- if is_numlike(marker[0]):
- if len(marker) == 2:
- numsides, rotation = marker[0], 0.0
- elif len(marker) == 3:
- numsides, rotation = marker[0], marker[2]
- symstyle = marker[1]
- if symstyle == 0:
- self._path = Path.unit_regular_polygon(numsides)
- self._joinstyle = 'miter'
- elif symstyle == 1:
- self._path = Path.unit_regular_star(numsides)
- self._joinstyle = 'bevel'
- elif symstyle == 2:
- self._path = Path.unit_regular_asterisk(numsides)
- self._filled = False
- self._joinstyle = 'bevel'
- elif symstyle == 3:
- self._path = Path.unit_circle()
- self._transform = Affine2D().scale(0.5).rotate_deg(rotation)
- else:
- verts = np.asarray(marker[0])
- path = Path(verts)
- self._set_custom_marker(path)
-
- def _set_mathtext_path(self):
- """
- Draws mathtext markers '$...$' using TextPath object.
-
- Submitted by tcb
- """
- from matplotlib.text import TextPath
- from matplotlib.font_manager import FontProperties
-
- # again, the properties could be initialised just once outside
- # this function
- # Font size is irrelevant here, it will be rescaled based on
- # the drawn size later
- props = FontProperties(size=1.0)
- text = TextPath(xy=(0, 0), s=self.get_marker(), fontproperties=props,
- usetex=rcParams['text.usetex'])
- if len(text.vertices) == 0:
- return
-
- xmin, ymin = text.vertices.min(axis=0)
- xmax, ymax = text.vertices.max(axis=0)
- width = xmax - xmin
- height = ymax - ymin
- max_dim = max(width, height)
- self._transform = Affine2D() \
- .translate(-xmin + 0.5 * -width, -ymin + 0.5 * -height) \
- .scale(1.0 / max_dim)
- self._path = text
- self._snap = False
-
- def _half_fill(self):
- fs = self.get_fillstyle()
- result = fs in self._half_fillstyles
- return result
-
- def _set_circle(self, reduction=1.0):
- self._transform = Affine2D().scale(0.5 * reduction)
- self._snap_threshold = np.inf
- fs = self.get_fillstyle()
- if not self._half_fill():
- self._path = Path.unit_circle()
- else:
- # build a right-half circle
- if fs == 'bottom':
- rotate = 270.
- elif fs == 'top':
- rotate = 90.
- elif fs == 'left':
- rotate = 180.
- else:
- rotate = 0.
-
- self._path = self._alt_path = Path.unit_circle_righthalf()
- self._transform.rotate_deg(rotate)
- self._alt_transform = self._transform.frozen().rotate_deg(180.)
-
- def _set_pixel(self):
- self._path = Path.unit_rectangle()
- # Ideally, you'd want -0.5, -0.5 here, but then the snapping
- # algorithm in the Agg backend will round this to a 2x2
- # rectangle from (-1, -1) to (1, 1). By offsetting it
- # slightly, we can force it to be (0, 0) to (1, 1), which both
- # makes it only be a single pixel and places it correctly
- # aligned to 1-width stroking (i.e. the ticks). This hack is
- # the best of a number of bad alternatives, mainly because the
- # backends are not aware of what marker is actually being used
- # beyond just its path data.
- self._transform = Affine2D().translate(-0.49999, -0.49999)
- self._snap_threshold = None
-
- def _set_point(self):
- self._set_circle(reduction=self._point_size_reduction)
-
- _triangle_path = Path(
- [[0.0, 1.0], [-1.0, -1.0], [1.0, -1.0], [0.0, 1.0]],
- [Path.MOVETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY])
- # Going down halfway looks to small. Golden ratio is too far.
- _triangle_path_u = Path(
- [[0.0, 1.0], [-3 / 5., -1 / 5.], [3 / 5., -1 / 5.], [0.0, 1.0]],
- [Path.MOVETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY])
- _triangle_path_d = Path(
- [[-3 / 5., -1 / 5.], [3 / 5., -1 / 5.], [1.0, -1.0], [-1.0, -1.0],
- [-3 / 5., -1 / 5.]],
- [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY])
- _triangle_path_l = Path(
- [[0.0, 1.0], [0.0, -1.0], [-1.0, -1.0], [0.0, 1.0]],
- [Path.MOVETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY])
- _triangle_path_r = Path(
- [[0.0, 1.0], [0.0, -1.0], [1.0, -1.0], [0.0, 1.0]],
- [Path.MOVETO, Path.LINETO, Path.LINETO, Path.CLOSEPOLY])
-
- def _set_triangle(self, rot, skip):
- self._transform = Affine2D().scale(0.5, 0.5).rotate_deg(rot)
- self._snap_threshold = 5.0
- fs = self.get_fillstyle()
-
- if not self._half_fill():
- self._path = self._triangle_path
- else:
- mpaths = [self._triangle_path_u,
- self._triangle_path_l,
- self._triangle_path_d,
- self._triangle_path_r]
-
- if fs == 'top':
- self._path = mpaths[(0 + skip) % 4]
- self._alt_path = mpaths[(2 + skip) % 4]
- elif fs == 'bottom':
- self._path = mpaths[(2 + skip) % 4]
- self._alt_path = mpaths[(0 + skip) % 4]
- elif fs == 'left':
- self._path = mpaths[(1 + skip) % 4]
- self._alt_path = mpaths[(3 + skip) % 4]
- else:
- self._path = mpaths[(3 + skip) % 4]
- self._alt_path = mpaths[(1 + skip) % 4]
-
- self._alt_transform = self._transform
-
- self._joinstyle = 'miter'
-
- def _set_triangle_up(self):
- return self._set_triangle(0.0, 0)
-
- def _set_triangle_down(self):
- return self._set_triangle(180.0, 2)
-
- def _set_triangle_left(self):
- return self._set_triangle(90.0, 3)
-
- def _set_triangle_right(self):
- return self._set_triangle(270.0, 1)
-
- def _set_square(self):
- self._transform = Affine2D().translate(-0.5, -0.5)
- self._snap_threshold = 2.0
- fs = self.get_fillstyle()
- if not self._half_fill():
- self._path = Path.unit_rectangle()
- else:
- # build a bottom filled square out of two rectangles, one
- # filled. Use the rotation to support left, right, bottom
- # or top
- if fs == 'bottom':
- rotate = 0.
- elif fs == 'top':
- rotate = 180.
- elif fs == 'left':
- rotate = 270.
- else:
- rotate = 90.
-
- self._path = Path([[0.0, 0.0], [1.0, 0.0], [1.0, 0.5],
- [0.0, 0.5], [0.0, 0.0]])
- self._alt_path = Path([[0.0, 0.5], [1.0, 0.5], [1.0, 1.0],
- [0.0, 1.0], [0.0, 0.5]])
- self._transform.rotate_deg(rotate)
- self._alt_transform = self._transform
-
- self._joinstyle = 'miter'
-
- def _set_diamond(self):
- self._transform = Affine2D().translate(-0.5, -0.5).rotate_deg(45)
- self._snap_threshold = 5.0
- fs = self.get_fillstyle()
- if not self._half_fill():
- self._path = Path.unit_rectangle()
- else:
- self._path = Path([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 0.0]])
- self._alt_path = Path([[0.0, 0.0], [0.0, 1.0],
- [1.0, 1.0], [0.0, 0.0]])
-
- if fs == 'bottom':
- rotate = 270.
- elif fs == 'top':
- rotate = 90.
- elif fs == 'left':
- rotate = 180.
- else:
- rotate = 0.
-
- self._transform.rotate_deg(rotate)
- self._alt_transform = self._transform
-
- self._joinstyle = 'miter'
-
- def _set_thin_diamond(self):
- self._set_diamond()
- self._transform.scale(0.6, 1.0)
-
- def _set_pentagon(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = 5.0
-
- polypath = Path.unit_regular_polygon(5)
- fs = self.get_fillstyle()
-
- if not self._half_fill():
- self._path = polypath
- else:
- verts = polypath.vertices
-
- y = (1 + np.sqrt(5)) / 4.
- top = Path([verts[0], verts[1], verts[4], verts[0]])
- bottom = Path([verts[1], verts[2], verts[3], verts[4], verts[1]])
- left = Path([verts[0], verts[1], verts[2], [0, -y], verts[0]])
- right = Path([verts[0], verts[4], verts[3], [0, -y], verts[0]])
-
- if fs == 'top':
- mpath, mpath_alt = top, bottom
- elif fs == 'bottom':
- mpath, mpath_alt = bottom, top
- elif fs == 'left':
- mpath, mpath_alt = left, right
- else:
- mpath, mpath_alt = right, left
- self._path = mpath
- self._alt_path = mpath_alt
- self._alt_transform = self._transform
-
- self._joinstyle = 'miter'
-
- def _set_star(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = 5.0
-
- fs = self.get_fillstyle()
- polypath = Path.unit_regular_star(5, innerCircle=0.381966)
-
- if not self._half_fill():
- self._path = polypath
- else:
- verts = polypath.vertices
-
- top = Path(np.vstack((verts[0:4, :], verts[7:10, :], verts[0])))
- bottom = Path(np.vstack((verts[3:8, :], verts[3])))
- left = Path(np.vstack((verts[0:6, :], verts[0])))
- right = Path(np.vstack((verts[0], verts[5:10, :], verts[0])))
-
- if fs == 'top':
- mpath, mpath_alt = top, bottom
- elif fs == 'bottom':
- mpath, mpath_alt = bottom, top
- elif fs == 'left':
- mpath, mpath_alt = left, right
- else:
- mpath, mpath_alt = right, left
- self._path = mpath
- self._alt_path = mpath_alt
- self._alt_transform = self._transform
-
- self._joinstyle = 'bevel'
-
- def _set_hexagon1(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = None
-
- fs = self.get_fillstyle()
- polypath = Path.unit_regular_polygon(6)
-
- if not self._half_fill():
- self._path = polypath
- else:
- verts = polypath.vertices
-
- # not drawing inside lines
- x = np.abs(np.cos(5 * np.pi / 6.))
- top = Path(np.vstack(([-x, 0], verts[(1, 0, 5), :], [x, 0])))
- bottom = Path(np.vstack(([-x, 0], verts[2:5, :], [x, 0])))
- left = Path(verts[(0, 1, 2, 3), :])
- right = Path(verts[(0, 5, 4, 3), :])
-
- if fs == 'top':
- mpath, mpath_alt = top, bottom
- elif fs == 'bottom':
- mpath, mpath_alt = bottom, top
- elif fs == 'left':
- mpath, mpath_alt = left, right
- else:
- mpath, mpath_alt = right, left
-
- self._path = mpath
- self._alt_path = mpath_alt
- self._alt_transform = self._transform
-
- self._joinstyle = 'miter'
-
- def _set_hexagon2(self):
- self._transform = Affine2D().scale(0.5).rotate_deg(30)
- self._snap_threshold = None
-
- fs = self.get_fillstyle()
- polypath = Path.unit_regular_polygon(6)
-
- if not self._half_fill():
- self._path = polypath
- else:
- verts = polypath.vertices
-
- # not drawing inside lines
- x, y = np.sqrt(3) / 4, 3 / 4.
- top = Path(verts[(1, 0, 5, 4, 1), :])
- bottom = Path(verts[(1, 2, 3, 4), :])
- left = Path(np.vstack(([x, y], verts[(0, 1, 2), :],
- [-x, -y], [x, y])))
- right = Path(np.vstack(([x, y], verts[(5, 4, 3), :], [-x, -y])))
-
- if fs == 'top':
- mpath, mpath_alt = top, bottom
- elif fs == 'bottom':
- mpath, mpath_alt = bottom, top
- elif fs == 'left':
- mpath, mpath_alt = left, right
- else:
- mpath, mpath_alt = right, left
-
- self._path = mpath
- self._alt_path = mpath_alt
- self._alt_transform = self._transform
-
- self._joinstyle = 'miter'
-
- def _set_octagon(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = 5.0
-
- fs = self.get_fillstyle()
- polypath = Path.unit_regular_polygon(8)
-
- if not self._half_fill():
- self._transform.rotate_deg(22.5)
- self._path = polypath
- else:
- x = np.sqrt(2.) / 4.
- half = Path([[0, -1], [0, 1], [-x, 1], [-1, x],
- [-1, -x], [-x, -1], [0, -1]])
-
- if fs == 'bottom':
- rotate = 90.
- elif fs == 'top':
- rotate = 270.
- elif fs == 'right':
- rotate = 180.
- else:
- rotate = 0.
-
- self._transform.rotate_deg(rotate)
- self._path = self._alt_path = half
- self._alt_transform = self._transform.frozen().rotate_deg(180.0)
-
- self._joinstyle = 'miter'
-
- _line_marker_path = Path([[0.0, -1.0], [0.0, 1.0]])
-
- def _set_vline(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = 1.0
- self._filled = False
- self._path = self._line_marker_path
-
- def _set_hline(self):
- self._set_vline()
- self._transform = self._transform.rotate_deg(90)
-
- _tickhoriz_path = Path([[0.0, 0.0], [1.0, 0.0]])
-
- def _set_tickleft(self):
- self._transform = Affine2D().scale(-1.0, 1.0)
- self._snap_threshold = 1.0
- self._filled = False
- self._path = self._tickhoriz_path
-
- def _set_tickright(self):
- self._transform = Affine2D().scale(1.0, 1.0)
- self._snap_threshold = 1.0
- self._filled = False
- self._path = self._tickhoriz_path
-
- _tickvert_path = Path([[-0.0, 0.0], [-0.0, 1.0]])
-
- def _set_tickup(self):
- self._transform = Affine2D().scale(1.0, 1.0)
- self._snap_threshold = 1.0
- self._filled = False
- self._path = self._tickvert_path
-
- def _set_tickdown(self):
- self._transform = Affine2D().scale(1.0, -1.0)
- self._snap_threshold = 1.0
- self._filled = False
- self._path = self._tickvert_path
-
- _tri_path = Path([[0.0, 0.0], [0.0, -1.0],
- [0.0, 0.0], [0.8, 0.5],
- [0.0, 0.0], [-0.8, 0.5]],
- [Path.MOVETO, Path.LINETO,
- Path.MOVETO, Path.LINETO,
- Path.MOVETO, Path.LINETO])
-
- def _set_tri_down(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = 5.0
- self._filled = False
- self._path = self._tri_path
-
- def _set_tri_up(self):
- self._set_tri_down()
- self._transform = self._transform.rotate_deg(180)
-
- def _set_tri_left(self):
- self._set_tri_down()
- self._transform = self._transform.rotate_deg(270)
-
- def _set_tri_right(self):
- self._set_tri_down()
- self._transform = self._transform.rotate_deg(90)
-
- _caret_path = Path([[-1.0, 1.5], [0.0, 0.0], [1.0, 1.5]])
-
- def _set_caretdown(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = 3.0
- self._filled = False
- self._path = self._caret_path
- self._joinstyle = 'miter'
-
- def _set_caretup(self):
- self._set_caretdown()
- self._transform = self._transform.rotate_deg(180)
-
- def _set_caretleft(self):
- self._set_caretdown()
- self._transform = self._transform.rotate_deg(270)
-
- def _set_caretright(self):
- self._set_caretdown()
- self._transform = self._transform.rotate_deg(90)
-
- _caret_path_base = Path([[-1.0, 0.0], [0.0, -1.5], [1.0, 0]])
-
- def _set_caretdownbase(self):
- self._set_caretdown()
- self._path = self._caret_path_base
-
- def _set_caretupbase(self):
- self._set_caretdownbase()
- self._transform = self._transform.rotate_deg(180)
-
- def _set_caretleftbase(self):
- self._set_caretdownbase()
- self._transform = self._transform.rotate_deg(270)
-
- def _set_caretrightbase(self):
- self._set_caretdownbase()
- self._transform = self._transform.rotate_deg(90)
-
- _plus_path = Path([[-1.0, 0.0], [1.0, 0.0],
- [0.0, -1.0], [0.0, 1.0]],
- [Path.MOVETO, Path.LINETO,
- Path.MOVETO, Path.LINETO])
-
- def _set_plus(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = 1.0
- self._filled = False
- self._path = self._plus_path
-
- _x_path = Path([[-1.0, -1.0], [1.0, 1.0],
- [-1.0, 1.0], [1.0, -1.0]],
- [Path.MOVETO, Path.LINETO,
- Path.MOVETO, Path.LINETO])
-
- def _set_x(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = 3.0
- self._filled = False
- self._path = self._x_path
-
- _plus_filled_path = Path([(1/3, 0), (2/3, 0), (2/3, 1/3),
- (1, 1/3), (1, 2/3), (2/3, 2/3),
- (2/3, 1), (1/3, 1), (1/3, 2/3),
- (0, 2/3), (0, 1/3), (1/3, 1/3),
- (1/3, 0)],
- [Path.MOVETO, Path.LINETO, Path.LINETO,
- Path.LINETO, Path.LINETO, Path.LINETO,
- Path.LINETO, Path.LINETO, Path.LINETO,
- Path.LINETO, Path.LINETO, Path.LINETO,
- Path.CLOSEPOLY])
-
- _plus_filled_path_t = Path([(1, 1/2), (1, 2/3), (2/3, 2/3),
- (2/3, 1), (1/3, 1), (1/3, 2/3),
- (0, 2/3), (0, 1/2), (1, 1/2)],
- [Path.MOVETO, Path.LINETO, Path.LINETO,
- Path.LINETO, Path.LINETO, Path.LINETO,
- Path.LINETO, Path.LINETO,
- Path.CLOSEPOLY])
-
- def _set_plus_filled(self):
- self._transform = Affine2D().translate(-0.5, -0.5)
- self._snap_threshold = 5.0
- self._joinstyle = 'miter'
- fs = self.get_fillstyle()
- if not self._half_fill():
- self._path = self._plus_filled_path
- else:
- # Rotate top half path to support all partitions
- if fs == 'top':
- rotate, rotate_alt = 0, 180
- elif fs == 'bottom':
- rotate, rotate_alt = 180, 0
- elif fs == 'left':
- rotate, rotate_alt = 90, 270
- else:
- rotate, rotate_alt = 270, 90
-
- self._path = self._plus_filled_path_t
- self._alt_path = self._plus_filled_path_t
- self._alt_transform = Affine2D().translate(-0.5, -0.5)
- self._transform.rotate_deg(rotate)
- self._alt_transform.rotate_deg(rotate_alt)
-
- _x_filled_path = Path([(0.25, 0), (0.5, 0.25), (0.75, 0), (1, 0.25),
- (0.75, 0.5), (1, 0.75), (0.75, 1), (0.5, 0.75),
- (0.25, 1), (0, 0.75), (0.25, 0.5), (0, 0.25),
- (0.25, 0)],
- [Path.MOVETO, Path.LINETO, Path.LINETO,
- Path.LINETO, Path.LINETO, Path.LINETO,
- Path.LINETO, Path.LINETO, Path.LINETO,
- Path.LINETO, Path.LINETO, Path.LINETO,
- Path.CLOSEPOLY])
-
- _x_filled_path_t = Path([(0.75, 0.5), (1, 0.75), (0.75, 1),
- (0.5, 0.75), (0.25, 1), (0, 0.75),
- (0.25, 0.5), (0.75, 0.5)],
- [Path.MOVETO, Path.LINETO, Path.LINETO,
- Path.LINETO, Path.LINETO, Path.LINETO,
- Path.LINETO, Path.CLOSEPOLY])
-
- def _set_x_filled(self):
- self._transform = Affine2D().translate(-0.5, -0.5)
- self._snap_threshold = 5.0
- self._joinstyle = 'miter'
- fs = self.get_fillstyle()
- if not self._half_fill():
- self._path = self._x_filled_path
- else:
- # Rotate top half path to support all partitions
- if fs == 'top':
- rotate, rotate_alt = 0, 180
- elif fs == 'bottom':
- rotate, rotate_alt = 180, 0
- elif fs == 'left':
- rotate, rotate_alt = 90, 270
- else:
- rotate, rotate_alt = 270, 90
-
- self._path = self._x_filled_path_t
- self._alt_path = self._x_filled_path_t
- self._alt_transform = Affine2D().translate(-0.5, -0.5)
- self._transform.rotate_deg(rotate)
- self._alt_transform.rotate_deg(rotate_alt)
diff --git a/contrib/python/matplotlib/py2/matplotlib/mathtext.py b/contrib/python/matplotlib/py2/matplotlib/mathtext.py
deleted file mode 100644
index dee778b0d0..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/mathtext.py
+++ /dev/null
@@ -1,3445 +0,0 @@
-r"""
-:mod:`~matplotlib.mathtext` is a module for parsing a subset of the
-TeX math syntax and drawing them to a matplotlib backend.
-
-For a tutorial of its usage see :doc:`/tutorials/text/mathtext`. This
-document is primarily concerned with implementation details.
-
-The module uses pyparsing_ to parse the TeX expression.
-
-.. _pyparsing: http://pyparsing.wikispaces.com/
-
-The Bakoma distribution of the TeX Computer Modern fonts, and STIX
-fonts are supported. There is experimental support for using
-arbitrary fonts, but results may vary without proper tweaking and
-metrics for those fonts.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six import unichr
-
-import os
-from math import ceil
-import unicodedata
-from warnings import warn
-
-from numpy import inf, isinf
-import numpy as np
-
-from pyparsing import (
- Combine, Empty, FollowedBy, Forward, Group, Literal, oneOf, OneOrMore,
- Optional, ParseBaseException, ParseFatalException, ParserElement,
- QuotedString, Regex, StringEnd, Suppress, ZeroOrMore)
-
-ParserElement.enablePackrat()
-
-from matplotlib import _png, colors as mcolors, get_data_path, rcParams
-from matplotlib.afm import AFM
-from matplotlib.cbook import Bunch, get_realpath_and_stat, maxdict
-from matplotlib.ft2font import FT2Image, KERNING_DEFAULT, LOAD_NO_HINTING
-from matplotlib.font_manager import findfont, FontProperties, get_font
-from matplotlib._mathtext_data import (latex_to_bakoma, latex_to_standard,
- tex2uni, latex_to_cmex,
- stix_virtual_fonts)
-
-####################
-
-
-
-##############################################################################
-# FONTS
-
-def get_unicode_index(symbol, math=True):
- """get_unicode_index(symbol, [bool]) -> integer
-
-Return the integer index (from the Unicode table) of symbol. *symbol*
-can be a single unicode character, a TeX command (i.e. r'\\pi'), or a
-Type1 symbol name (i.e. 'phi').
-If math is False, the current symbol should be treated as a non-math symbol.
-"""
- # for a non-math symbol, simply return its unicode index
- if not math:
- return ord(symbol)
- # From UTF #25: U+2212 minus sign is the preferred
- # representation of the unary and binary minus sign rather than
- # the ASCII-derived U+002D hyphen-minus, because minus sign is
- # unambiguous and because it is rendered with a more desirable
- # length, usually longer than a hyphen.
- if symbol == '-':
- return 0x2212
- try:# This will succeed if symbol is a single unicode char
- return ord(symbol)
- except TypeError:
- pass
- try:# Is symbol a TeX symbol (i.e. \alpha)
- return tex2uni[symbol.strip("\\")]
- except KeyError:
- message = """'%(symbol)s' is not a valid Unicode character or
-TeX/Type1 symbol"""%locals()
- raise ValueError(message)
-
-def unichr_safe(index):
- """Return the Unicode character corresponding to the index,
-or the replacement character if this is a narrow build of Python
-and the requested character is outside the BMP."""
- try:
- return unichr(index)
- except ValueError:
- return unichr(0xFFFD)
-
-class MathtextBackend(object):
- """
- The base class for the mathtext backend-specific code. The
- purpose of :class:`MathtextBackend` subclasses is to interface
- between mathtext and a specific matplotlib graphics backend.
-
- Subclasses need to override the following:
-
- - :meth:`render_glyph`
- - :meth:`render_rect_filled`
- - :meth:`get_results`
-
- And optionally, if you need to use a FreeType hinting style:
-
- - :meth:`get_hinting_type`
- """
- def __init__(self):
- self.width = 0
- self.height = 0
- self.depth = 0
-
- def set_canvas_size(self, w, h, d):
- 'Dimension the drawing canvas'
- self.width = w
- self.height = h
- self.depth = d
-
- def render_glyph(self, ox, oy, info):
- """
- Draw a glyph described by *info* to the reference point (*ox*,
- *oy*).
- """
- raise NotImplementedError()
-
- def render_rect_filled(self, x1, y1, x2, y2):
- """
- Draw a filled black rectangle from (*x1*, *y1*) to (*x2*, *y2*).
- """
- raise NotImplementedError()
-
- def get_results(self, box):
- """
- Return a backend-specific tuple to return to the backend after
- all processing is done.
- """
- raise NotImplementedError()
-
- def get_hinting_type(self):
- """
- Get the FreeType hinting type to use with this particular
- backend.
- """
- return LOAD_NO_HINTING
-
-class MathtextBackendAgg(MathtextBackend):
- """
- Render glyphs and rectangles to an FTImage buffer, which is later
- transferred to the Agg image by the Agg backend.
- """
- def __init__(self):
- self.ox = 0
- self.oy = 0
- self.image = None
- self.mode = 'bbox'
- self.bbox = [0, 0, 0, 0]
- MathtextBackend.__init__(self)
-
- def _update_bbox(self, x1, y1, x2, y2):
- self.bbox = [min(self.bbox[0], x1),
- min(self.bbox[1], y1),
- max(self.bbox[2], x2),
- max(self.bbox[3], y2)]
-
- def set_canvas_size(self, w, h, d):
- MathtextBackend.set_canvas_size(self, w, h, d)
- if self.mode != 'bbox':
- self.image = FT2Image(ceil(w), ceil(h + max(d, 0)))
-
- def render_glyph(self, ox, oy, info):
- if self.mode == 'bbox':
- self._update_bbox(ox + info.metrics.xmin,
- oy - info.metrics.ymax,
- ox + info.metrics.xmax,
- oy - info.metrics.ymin)
- else:
- info.font.draw_glyph_to_bitmap(
- self.image, ox, oy - info.metrics.iceberg, info.glyph,
- antialiased=rcParams['text.antialiased'])
-
- def render_rect_filled(self, x1, y1, x2, y2):
- if self.mode == 'bbox':
- self._update_bbox(x1, y1, x2, y2)
- else:
- height = max(int(y2 - y1) - 1, 0)
- if height == 0:
- center = (y2 + y1) / 2.0
- y = int(center - (height + 1) / 2.0)
- else:
- y = int(y1)
- self.image.draw_rect_filled(int(x1), y, ceil(x2), y + height)
-
- def get_results(self, box, used_characters):
- self.mode = 'bbox'
- orig_height = box.height
- orig_depth = box.depth
- ship(0, 0, box)
- bbox = self.bbox
- bbox = [bbox[0] - 1, bbox[1] - 1, bbox[2] + 1, bbox[3] + 1]
- self.mode = 'render'
- self.set_canvas_size(
- bbox[2] - bbox[0],
- (bbox[3] - bbox[1]) - orig_depth,
- (bbox[3] - bbox[1]) - orig_height)
- ship(-bbox[0], -bbox[1], box)
- result = (self.ox,
- self.oy,
- self.width,
- self.height + self.depth,
- self.depth,
- self.image,
- used_characters)
- self.image = None
- return result
-
- def get_hinting_type(self):
- from matplotlib.backends import backend_agg
- return backend_agg.get_hinting_flag()
-
-class MathtextBackendBitmap(MathtextBackendAgg):
- def get_results(self, box, used_characters):
- ox, oy, width, height, depth, image, characters = \
- MathtextBackendAgg.get_results(self, box, used_characters)
- return image, depth
-
-class MathtextBackendPs(MathtextBackend):
- """
- Store information to write a mathtext rendering to the PostScript
- backend.
- """
- def __init__(self):
- self.pswriter = six.moves.cStringIO()
- self.lastfont = None
-
- def render_glyph(self, ox, oy, info):
- oy = self.height - oy + info.offset
- postscript_name = info.postscript_name
- fontsize = info.fontsize
- symbol_name = info.symbol_name
-
- if (postscript_name, fontsize) != self.lastfont:
- ps = """/%(postscript_name)s findfont
-%(fontsize)s scalefont
-setfont
-""" % locals()
- self.lastfont = postscript_name, fontsize
- self.pswriter.write(ps)
-
- ps = """%(ox)f %(oy)f moveto
-/%(symbol_name)s glyphshow\n
-""" % locals()
- self.pswriter.write(ps)
-
- def render_rect_filled(self, x1, y1, x2, y2):
- ps = "%f %f %f %f rectfill\n" % (x1, self.height - y2, x2 - x1, y2 - y1)
- self.pswriter.write(ps)
-
- def get_results(self, box, used_characters):
- ship(0, 0, box)
- return (self.width,
- self.height + self.depth,
- self.depth,
- self.pswriter,
- used_characters)
-
-class MathtextBackendPdf(MathtextBackend):
- """
- Store information to write a mathtext rendering to the PDF
- backend.
- """
- def __init__(self):
- self.glyphs = []
- self.rects = []
-
- def render_glyph(self, ox, oy, info):
- filename = info.font.fname
- oy = self.height - oy + info.offset
- self.glyphs.append(
- (ox, oy, filename, info.fontsize,
- info.num, info.symbol_name))
-
- def render_rect_filled(self, x1, y1, x2, y2):
- self.rects.append((x1, self.height - y2, x2 - x1, y2 - y1))
-
- def get_results(self, box, used_characters):
- ship(0, 0, box)
- return (self.width,
- self.height + self.depth,
- self.depth,
- self.glyphs,
- self.rects,
- used_characters)
-
-class MathtextBackendSvg(MathtextBackend):
- """
- Store information to write a mathtext rendering to the SVG
- backend.
- """
- def __init__(self):
- self.svg_glyphs = []
- self.svg_rects = []
-
- def render_glyph(self, ox, oy, info):
- oy = self.height - oy + info.offset
-
- self.svg_glyphs.append(
- (info.font, info.fontsize, info.num, ox, oy, info.metrics))
-
- def render_rect_filled(self, x1, y1, x2, y2):
- self.svg_rects.append(
- (x1, self.height - y1 + 1, x2 - x1, y2 - y1))
-
- def get_results(self, box, used_characters):
- ship(0, 0, box)
- svg_elements = Bunch(svg_glyphs = self.svg_glyphs,
- svg_rects = self.svg_rects)
- return (self.width,
- self.height + self.depth,
- self.depth,
- svg_elements,
- used_characters)
-
-class MathtextBackendPath(MathtextBackend):
- """
- Store information to write a mathtext rendering to the text path
- machinery.
- """
-
- def __init__(self):
- self.glyphs = []
- self.rects = []
-
- def render_glyph(self, ox, oy, info):
- oy = self.height - oy + info.offset
- thetext = info.num
- self.glyphs.append(
- (info.font, info.fontsize, thetext, ox, oy))
-
- def render_rect_filled(self, x1, y1, x2, y2):
- self.rects.append(
- (x1, self.height-y2 , x2 - x1, y2 - y1))
-
- def get_results(self, box, used_characters):
- ship(0, 0, box)
- return (self.width,
- self.height + self.depth,
- self.depth,
- self.glyphs,
- self.rects)
-
-class MathtextBackendCairo(MathtextBackend):
- """
- Store information to write a mathtext rendering to the Cairo
- backend.
- """
-
- def __init__(self):
- self.glyphs = []
- self.rects = []
-
- def render_glyph(self, ox, oy, info):
- oy = oy - info.offset - self.height
- thetext = unichr_safe(info.num)
- self.glyphs.append(
- (info.font, info.fontsize, thetext, ox, oy))
-
- def render_rect_filled(self, x1, y1, x2, y2):
- self.rects.append(
- (x1, y1 - self.height, x2 - x1, y2 - y1))
-
- def get_results(self, box, used_characters):
- ship(0, 0, box)
- return (self.width,
- self.height + self.depth,
- self.depth,
- self.glyphs,
- self.rects)
-
-class Fonts(object):
- """
- An abstract base class for a system of fonts to use for mathtext.
-
- The class must be able to take symbol keys and font file names and
- return the character metrics. It also delegates to a backend class
- to do the actual drawing.
- """
-
- def __init__(self, default_font_prop, mathtext_backend):
- """
- *default_font_prop*: A
- :class:`~matplotlib.font_manager.FontProperties` object to use
- for the default non-math font, or the base font for Unicode
- (generic) font rendering.
-
- *mathtext_backend*: A subclass of :class:`MathTextBackend`
- used to delegate the actual rendering.
- """
- self.default_font_prop = default_font_prop
- self.mathtext_backend = mathtext_backend
- self.used_characters = {}
-
- def destroy(self):
- """
- Fix any cyclical references before the object is about
- to be destroyed.
- """
- self.used_characters = None
-
- def get_kern(self, font1, fontclass1, sym1, fontsize1,
- font2, fontclass2, sym2, fontsize2, dpi):
- """
- Get the kerning distance for font between *sym1* and *sym2*.
-
- *fontX*: one of the TeX font names::
-
- tt, it, rm, cal, sf, bf or default/regular (non-math)
-
- *fontclassX*: TODO
-
- *symX*: a symbol in raw TeX form. e.g., '1', 'x' or '\\sigma'
-
- *fontsizeX*: the fontsize in points
-
- *dpi*: the current dots-per-inch
- """
- return 0.
-
- def get_metrics(self, font, font_class, sym, fontsize, dpi, math=True):
- """
- *font*: one of the TeX font names::
-
- tt, it, rm, cal, sf, bf or default/regular (non-math)
-
- *font_class*: TODO
-
- *sym*: a symbol in raw TeX form. e.g., '1', 'x' or '\\sigma'
-
- *fontsize*: font size in points
-
- *dpi*: current dots-per-inch
-
- *math*: whether sym is a math character
-
- Returns an object with the following attributes:
-
- - *advance*: The advance distance (in points) of the glyph.
-
- - *height*: The height of the glyph in points.
-
- - *width*: The width of the glyph in points.
-
- - *xmin*, *xmax*, *ymin*, *ymax* - the ink rectangle of the glyph
-
- - *iceberg* - the distance from the baseline to the top of
- the glyph. This corresponds to TeX's definition of
- "height".
- """
- info = self._get_info(font, font_class, sym, fontsize, dpi, math)
- return info.metrics
-
- def set_canvas_size(self, w, h, d):
- """
- Set the size of the buffer used to render the math expression.
- Only really necessary for the bitmap backends.
- """
- self.width, self.height, self.depth = ceil(w), ceil(h), ceil(d)
- self.mathtext_backend.set_canvas_size(self.width, self.height, self.depth)
-
- def render_glyph(self, ox, oy, facename, font_class, sym, fontsize, dpi):
- """
- Draw a glyph at
-
- - *ox*, *oy*: position
-
- - *facename*: One of the TeX face names
-
- - *font_class*:
-
- - *sym*: TeX symbol name or single character
-
- - *fontsize*: fontsize in points
-
- - *dpi*: The dpi to draw at.
- """
- info = self._get_info(facename, font_class, sym, fontsize, dpi)
- realpath, stat_key = get_realpath_and_stat(info.font.fname)
- used_characters = self.used_characters.setdefault(
- stat_key, (realpath, set()))
- used_characters[1].add(info.num)
- self.mathtext_backend.render_glyph(ox, oy, info)
-
- def render_rect_filled(self, x1, y1, x2, y2):
- """
- Draw a filled rectangle from (*x1*, *y1*) to (*x2*, *y2*).
- """
- self.mathtext_backend.render_rect_filled(x1, y1, x2, y2)
-
- def get_xheight(self, font, fontsize, dpi):
- """
- Get the xheight for the given *font* and *fontsize*.
- """
- raise NotImplementedError()
-
- def get_underline_thickness(self, font, fontsize, dpi):
- """
- Get the line thickness that matches the given font. Used as a
- base unit for drawing lines such as in a fraction or radical.
- """
- raise NotImplementedError()
-
- def get_used_characters(self):
- """
- Get the set of characters that were used in the math
- expression. Used by backends that need to subset fonts so
- they know which glyphs to include.
- """
- return self.used_characters
-
- def get_results(self, box):
- """
- Get the data needed by the backend to render the math
- expression. The return value is backend-specific.
- """
- result = self.mathtext_backend.get_results(box, self.get_used_characters())
- self.destroy()
- return result
-
- def get_sized_alternatives_for_symbol(self, fontname, sym):
- """
- Override if your font provides multiple sizes of the same
- symbol. Should return a list of symbols matching *sym* in
- various sizes. The expression renderer will select the most
- appropriate size for a given situation from this list.
- """
- return [(fontname, sym)]
-
-class TruetypeFonts(Fonts):
- """
- A generic base class for all font setups that use Truetype fonts
- (through FT2Font).
- """
- def __init__(self, default_font_prop, mathtext_backend):
- Fonts.__init__(self, default_font_prop, mathtext_backend)
- self.glyphd = {}
- self._fonts = {}
-
- filename = findfont(default_font_prop)
- default_font = get_font(filename)
- self._fonts['default'] = default_font
- self._fonts['regular'] = default_font
-
- def destroy(self):
- self.glyphd = None
- Fonts.destroy(self)
-
- def _get_font(self, font):
- if font in self.fontmap:
- basename = self.fontmap[font]
- else:
- basename = font
- cached_font = self._fonts.get(basename)
- if cached_font is None and os.path.exists(basename):
- cached_font = get_font(basename)
- self._fonts[basename] = cached_font
- self._fonts[cached_font.postscript_name] = cached_font
- self._fonts[cached_font.postscript_name.lower()] = cached_font
- return cached_font
-
- def _get_offset(self, font, glyph, fontsize, dpi):
- if font.postscript_name == 'Cmex10':
- return ((glyph.height/64.0/2.0) + (fontsize/3.0 * dpi/72.0))
- return 0.
-
- def _get_info(self, fontname, font_class, sym, fontsize, dpi, math=True):
- key = fontname, font_class, sym, fontsize, dpi
- bunch = self.glyphd.get(key)
- if bunch is not None:
- return bunch
-
- font, num, symbol_name, fontsize, slanted = \
- self._get_glyph(fontname, font_class, sym, fontsize, math)
-
- font.set_size(fontsize, dpi)
- glyph = font.load_char(
- num,
- flags=self.mathtext_backend.get_hinting_type())
-
- xmin, ymin, xmax, ymax = [val/64.0 for val in glyph.bbox]
- offset = self._get_offset(font, glyph, fontsize, dpi)
- metrics = Bunch(
- advance = glyph.linearHoriAdvance/65536.0,
- height = glyph.height/64.0,
- width = glyph.width/64.0,
- xmin = xmin,
- xmax = xmax,
- ymin = ymin+offset,
- ymax = ymax+offset,
- # iceberg is the equivalent of TeX's "height"
- iceberg = glyph.horiBearingY/64.0 + offset,
- slanted = slanted
- )
-
- result = self.glyphd[key] = Bunch(
- font = font,
- fontsize = fontsize,
- postscript_name = font.postscript_name,
- metrics = metrics,
- symbol_name = symbol_name,
- num = num,
- glyph = glyph,
- offset = offset
- )
- return result
-
- def get_xheight(self, fontname, fontsize, dpi):
- font = self._get_font(fontname)
- font.set_size(fontsize, dpi)
- pclt = font.get_sfnt_table('pclt')
- if pclt is None:
- # Some fonts don't store the xHeight, so we do a poor man's xHeight
- metrics = self.get_metrics(fontname, rcParams['mathtext.default'], 'x', fontsize, dpi)
- return metrics.iceberg
- xHeight = (pclt['xHeight'] / 64.0) * (fontsize / 12.0) * (dpi / 100.0)
- return xHeight
-
- def get_underline_thickness(self, font, fontsize, dpi):
- # This function used to grab underline thickness from the font
- # metrics, but that information is just too un-reliable, so it
- # is now hardcoded.
- return ((0.75 / 12.0) * fontsize * dpi) / 72.0
-
- def get_kern(self, font1, fontclass1, sym1, fontsize1,
- font2, fontclass2, sym2, fontsize2, dpi):
- if font1 == font2 and fontsize1 == fontsize2:
- info1 = self._get_info(font1, fontclass1, sym1, fontsize1, dpi)
- info2 = self._get_info(font2, fontclass2, sym2, fontsize2, dpi)
- font = info1.font
- return font.get_kerning(info1.num, info2.num, KERNING_DEFAULT) / 64.0
- return Fonts.get_kern(self, font1, fontclass1, sym1, fontsize1,
- font2, fontclass2, sym2, fontsize2, dpi)
-
-class BakomaFonts(TruetypeFonts):
- """
- Use the Bakoma TrueType fonts for rendering.
-
- Symbols are strewn about a number of font files, each of which has
- its own proprietary 8-bit encoding.
- """
- _fontmap = { 'cal' : 'cmsy10',
- 'rm' : 'cmr10',
- 'tt' : 'cmtt10',
- 'it' : 'cmmi10',
- 'bf' : 'cmb10',
- 'sf' : 'cmss10',
- 'ex' : 'cmex10'
- }
-
- def __init__(self, *args, **kwargs):
- self._stix_fallback = StixFonts(*args, **kwargs)
-
- TruetypeFonts.__init__(self, *args, **kwargs)
- self.fontmap = {}
- for key, val in six.iteritems(self._fontmap):
- fullpath = findfont(val)
- self.fontmap[key] = fullpath
- self.fontmap[val] = fullpath
-
-
- _slanted_symbols = set(r"\int \oint".split())
-
- def _get_glyph(self, fontname, font_class, sym, fontsize, math=True):
- symbol_name = None
- font = None
- if fontname in self.fontmap and sym in latex_to_bakoma:
- basename, num = latex_to_bakoma[sym]
- slanted = (basename == "cmmi10") or sym in self._slanted_symbols
- font = self._get_font(basename)
- elif len(sym) == 1:
- slanted = (fontname == "it")
- font = self._get_font(fontname)
- if font is not None:
- num = ord(sym)
-
- if font is not None:
- gid = font.get_char_index(num)
- if gid != 0:
- symbol_name = font.get_glyph_name(gid)
-
- if symbol_name is None:
- return self._stix_fallback._get_glyph(
- fontname, font_class, sym, fontsize, math)
-
- return font, num, symbol_name, fontsize, slanted
-
- # The Bakoma fonts contain many pre-sized alternatives for the
- # delimiters. The AutoSizedChar class will use these alternatives
- # and select the best (closest sized) glyph.
- _size_alternatives = {
- '(' : [('rm', '('), ('ex', '\xa1'), ('ex', '\xb3'),
- ('ex', '\xb5'), ('ex', '\xc3')],
- ')' : [('rm', ')'), ('ex', '\xa2'), ('ex', '\xb4'),
- ('ex', '\xb6'), ('ex', '\x21')],
- '{' : [('cal', '{'), ('ex', '\xa9'), ('ex', '\x6e'),
- ('ex', '\xbd'), ('ex', '\x28')],
- '}' : [('cal', '}'), ('ex', '\xaa'), ('ex', '\x6f'),
- ('ex', '\xbe'), ('ex', '\x29')],
- # The fourth size of '[' is mysteriously missing from the BaKoMa
- # font, so I've omitted it for both '[' and ']'
- '[' : [('rm', '['), ('ex', '\xa3'), ('ex', '\x68'),
- ('ex', '\x22')],
- ']' : [('rm', ']'), ('ex', '\xa4'), ('ex', '\x69'),
- ('ex', '\x23')],
- r'\lfloor' : [('ex', '\xa5'), ('ex', '\x6a'),
- ('ex', '\xb9'), ('ex', '\x24')],
- r'\rfloor' : [('ex', '\xa6'), ('ex', '\x6b'),
- ('ex', '\xba'), ('ex', '\x25')],
- r'\lceil' : [('ex', '\xa7'), ('ex', '\x6c'),
- ('ex', '\xbb'), ('ex', '\x26')],
- r'\rceil' : [('ex', '\xa8'), ('ex', '\x6d'),
- ('ex', '\xbc'), ('ex', '\x27')],
- r'\langle' : [('ex', '\xad'), ('ex', '\x44'),
- ('ex', '\xbf'), ('ex', '\x2a')],
- r'\rangle' : [('ex', '\xae'), ('ex', '\x45'),
- ('ex', '\xc0'), ('ex', '\x2b')],
- r'\__sqrt__' : [('ex', '\x70'), ('ex', '\x71'),
- ('ex', '\x72'), ('ex', '\x73')],
- r'\backslash': [('ex', '\xb2'), ('ex', '\x2f'),
- ('ex', '\xc2'), ('ex', '\x2d')],
- r'/' : [('rm', '/'), ('ex', '\xb1'), ('ex', '\x2e'),
- ('ex', '\xcb'), ('ex', '\x2c')],
- r'\widehat' : [('rm', '\x5e'), ('ex', '\x62'), ('ex', '\x63'),
- ('ex', '\x64')],
- r'\widetilde': [('rm', '\x7e'), ('ex', '\x65'), ('ex', '\x66'),
- ('ex', '\x67')],
- r'<' : [('cal', 'h'), ('ex', 'D')],
- r'>' : [('cal', 'i'), ('ex', 'E')]
- }
-
- for alias, target in [(r'\leftparen', '('),
- (r'\rightparent', ')'),
- (r'\leftbrace', '{'),
- (r'\rightbrace', '}'),
- (r'\leftbracket', '['),
- (r'\rightbracket', ']'),
- (r'\{', '{'),
- (r'\}', '}'),
- (r'\[', '['),
- (r'\]', ']')]:
- _size_alternatives[alias] = _size_alternatives[target]
-
- def get_sized_alternatives_for_symbol(self, fontname, sym):
- return self._size_alternatives.get(sym, [(fontname, sym)])
-
-class UnicodeFonts(TruetypeFonts):
- """
- An abstract base class for handling Unicode fonts.
-
- While some reasonably complete Unicode fonts (such as DejaVu) may
- work in some situations, the only Unicode font I'm aware of with a
- complete set of math symbols is STIX.
-
- This class will "fallback" on the Bakoma fonts when a required
- symbol can not be found in the font.
- """
- use_cmex = True
-
- def __init__(self, *args, **kwargs):
- # This must come first so the backend's owner is set correctly
- if rcParams['mathtext.fallback_to_cm']:
- self.cm_fallback = BakomaFonts(*args, **kwargs)
- else:
- self.cm_fallback = None
- TruetypeFonts.__init__(self, *args, **kwargs)
- self.fontmap = {}
- for texfont in "cal rm tt it bf sf".split():
- prop = rcParams['mathtext.' + texfont]
- font = findfont(prop)
- self.fontmap[texfont] = font
- prop = FontProperties('cmex10')
- font = findfont(prop)
- self.fontmap['ex'] = font
-
- _slanted_symbols = set(r"\int \oint".split())
-
- def _map_virtual_font(self, fontname, font_class, uniindex):
- return fontname, uniindex
-
- def _get_glyph(self, fontname, font_class, sym, fontsize, math=True):
- found_symbol = False
-
- if self.use_cmex:
- uniindex = latex_to_cmex.get(sym)
- if uniindex is not None:
- fontname = 'ex'
- found_symbol = True
-
- if not found_symbol:
- try:
- uniindex = get_unicode_index(sym, math)
- found_symbol = True
- except ValueError:
- uniindex = ord('?')
- warn("No TeX to unicode mapping for '%s'" %
- sym.encode('ascii', 'backslashreplace'),
- MathTextWarning)
-
- fontname, uniindex = self._map_virtual_font(
- fontname, font_class, uniindex)
-
- new_fontname = fontname
-
- # Only characters in the "Letter" class should be italicized in 'it'
- # mode. Greek capital letters should be Roman.
- if found_symbol:
- if fontname == 'it':
- if uniindex < 0x10000:
- unistring = unichr(uniindex)
- if (not unicodedata.category(unistring)[0] == "L"
- or unicodedata.name(unistring).startswith("GREEK CAPITAL")):
- new_fontname = 'rm'
-
- slanted = (new_fontname == 'it') or sym in self._slanted_symbols
- found_symbol = False
- font = self._get_font(new_fontname)
- if font is not None:
- glyphindex = font.get_char_index(uniindex)
- if glyphindex != 0:
- found_symbol = True
-
- if not found_symbol:
- if self.cm_fallback:
- if isinstance(self.cm_fallback, BakomaFonts):
- warn("Substituting with a symbol from Computer Modern.",
- MathTextWarning)
- if (fontname in ('it', 'regular') and
- isinstance(self.cm_fallback, StixFonts)):
- return self.cm_fallback._get_glyph(
- 'rm', font_class, sym, fontsize)
- else:
- return self.cm_fallback._get_glyph(
- fontname, font_class, sym, fontsize)
- else:
- if fontname in ('it', 'regular') and isinstance(self, StixFonts):
- return self._get_glyph('rm', font_class, sym, fontsize)
- warn("Font '%s' does not have a glyph for '%s' [U+%x]" %
- (new_fontname,
- sym.encode('ascii', 'backslashreplace').decode('ascii'),
- uniindex),
- MathTextWarning)
- warn("Substituting with a dummy symbol.", MathTextWarning)
- fontname = 'rm'
- new_fontname = fontname
- font = self._get_font(fontname)
- uniindex = 0xA4 # currency character, for lack of anything better
- glyphindex = font.get_char_index(uniindex)
- slanted = False
-
- symbol_name = font.get_glyph_name(glyphindex)
- return font, uniindex, symbol_name, fontsize, slanted
-
- def get_sized_alternatives_for_symbol(self, fontname, sym):
- if self.cm_fallback:
- return self.cm_fallback.get_sized_alternatives_for_symbol(
- fontname, sym)
- return [(fontname, sym)]
-
-
-class DejaVuFonts(UnicodeFonts):
- use_cmex = False
-
- def __init__(self, *args, **kwargs):
- # This must come first so the backend's owner is set correctly
- if isinstance(self, DejaVuSerifFonts):
- self.cm_fallback = StixFonts(*args, **kwargs)
- else:
- self.cm_fallback = StixSansFonts(*args, **kwargs)
- self.bakoma = BakomaFonts(*args, **kwargs)
- TruetypeFonts.__init__(self, *args, **kwargs)
- self.fontmap = {}
- # Include Stix sized alternatives for glyphs
- self._fontmap.update({
- 1 : 'STIXSizeOneSym',
- 2 : 'STIXSizeTwoSym',
- 3 : 'STIXSizeThreeSym',
- 4 : 'STIXSizeFourSym',
- 5 : 'STIXSizeFiveSym'})
- for key, name in six.iteritems(self._fontmap):
- fullpath = findfont(name)
- self.fontmap[key] = fullpath
- self.fontmap[name] = fullpath
-
- def _get_glyph(self, fontname, font_class, sym, fontsize, math=True):
- """ Override prime symbol to use Bakoma """
- if sym == r'\prime':
- return self.bakoma._get_glyph(fontname,
- font_class, sym, fontsize, math)
- else:
- # check whether the glyph is available in the display font
- uniindex = get_unicode_index(sym)
- font = self._get_font('ex')
- if font is not None:
- glyphindex = font.get_char_index(uniindex)
- if glyphindex != 0:
- return super(DejaVuFonts, self)._get_glyph('ex',
- font_class, sym, fontsize, math)
- # otherwise return regular glyph
- return super(DejaVuFonts, self)._get_glyph(fontname,
- font_class, sym, fontsize, math)
-
-
-class DejaVuSerifFonts(DejaVuFonts):
- """
- A font handling class for the DejaVu Serif fonts
-
- If a glyph is not found it will fallback to Stix Serif
- """
- _fontmap = { 'rm' : 'DejaVu Serif',
- 'it' : 'DejaVu Serif:italic',
- 'bf' : 'DejaVu Serif:weight=bold',
- 'sf' : 'DejaVu Sans',
- 'tt' : 'DejaVu Sans Mono',
- 'ex' : 'DejaVu Serif Display',
- 0 : 'DejaVu Serif',
- }
-
-class DejaVuSansFonts(DejaVuFonts):
- """
- A font handling class for the DejaVu Sans fonts
-
- If a glyph is not found it will fallback to Stix Sans
- """
- _fontmap = { 'rm' : 'DejaVu Sans',
- 'it' : 'DejaVu Sans:italic',
- 'bf' : 'DejaVu Sans:weight=bold',
- 'sf' : 'DejaVu Sans',
- 'tt' : 'DejaVu Sans Mono',
- 'ex' : 'DejaVu Sans Display',
- 0 : 'DejaVu Sans',
- }
-
-class StixFonts(UnicodeFonts):
- """
- A font handling class for the STIX fonts.
-
- In addition to what UnicodeFonts provides, this class:
-
- - supports "virtual fonts" which are complete alpha numeric
- character sets with different font styles at special Unicode
- code points, such as "Blackboard".
-
- - handles sized alternative characters for the STIXSizeX fonts.
- """
- _fontmap = { 'rm' : 'STIXGeneral',
- 'it' : 'STIXGeneral:italic',
- 'bf' : 'STIXGeneral:weight=bold',
- 'nonunirm' : 'STIXNonUnicode',
- 'nonuniit' : 'STIXNonUnicode:italic',
- 'nonunibf' : 'STIXNonUnicode:weight=bold',
-
- 0 : 'STIXGeneral',
- 1 : 'STIXSizeOneSym',
- 2 : 'STIXSizeTwoSym',
- 3 : 'STIXSizeThreeSym',
- 4 : 'STIXSizeFourSym',
- 5 : 'STIXSizeFiveSym'
- }
- use_cmex = False
- cm_fallback = False
- _sans = False
-
- def __init__(self, *args, **kwargs):
- TruetypeFonts.__init__(self, *args, **kwargs)
- self.fontmap = {}
- for key, name in six.iteritems(self._fontmap):
- fullpath = findfont(name)
- self.fontmap[key] = fullpath
- self.fontmap[name] = fullpath
-
- def _map_virtual_font(self, fontname, font_class, uniindex):
- # Handle these "fonts" that are actually embedded in
- # other fonts.
- mapping = stix_virtual_fonts.get(fontname)
- if (self._sans and mapping is None and
- fontname not in ('regular', 'default')):
- mapping = stix_virtual_fonts['sf']
- doing_sans_conversion = True
- else:
- doing_sans_conversion = False
-
- if mapping is not None:
- if isinstance(mapping, dict):
- try:
- mapping = mapping[font_class]
- except KeyError:
- mapping = mapping['rm']
-
- # Binary search for the source glyph
- lo = 0
- hi = len(mapping)
- while lo < hi:
- mid = (lo+hi)//2
- range = mapping[mid]
- if uniindex < range[0]:
- hi = mid
- elif uniindex <= range[1]:
- break
- else:
- lo = mid + 1
-
- if uniindex >= range[0] and uniindex <= range[1]:
- uniindex = uniindex - range[0] + range[3]
- fontname = range[2]
- elif not doing_sans_conversion:
- # This will generate a dummy character
- uniindex = 0x1
- fontname = rcParams['mathtext.default']
-
- # Handle private use area glyphs
- if (fontname in ('it', 'rm', 'bf') and
- uniindex >= 0xe000 and uniindex <= 0xf8ff):
- fontname = 'nonuni' + fontname
-
- return fontname, uniindex
-
- _size_alternatives = {}
- def get_sized_alternatives_for_symbol(self, fontname, sym):
- fixes = {'\\{': '{', '\\}': '}', '\\[': '[', '\\]': ']'}
- sym = fixes.get(sym, sym)
-
- alternatives = self._size_alternatives.get(sym)
- if alternatives:
- return alternatives
-
- alternatives = []
- try:
- uniindex = get_unicode_index(sym)
- except ValueError:
- return [(fontname, sym)]
-
- fix_ups = {
- ord('<'): 0x27e8,
- ord('>'): 0x27e9 }
-
- uniindex = fix_ups.get(uniindex, uniindex)
-
- for i in range(6):
- font = self._get_font(i)
- glyphindex = font.get_char_index(uniindex)
- if glyphindex != 0:
- alternatives.append((i, unichr_safe(uniindex)))
-
- # The largest size of the radical symbol in STIX has incorrect
- # metrics that cause it to be disconnected from the stem.
- if sym == r'\__sqrt__':
- alternatives = alternatives[:-1]
-
- self._size_alternatives[sym] = alternatives
- return alternatives
-
-class StixSansFonts(StixFonts):
- """
- A font handling class for the STIX fonts (that uses sans-serif
- characters by default).
- """
- _sans = True
-
-class StandardPsFonts(Fonts):
- """
- Use the standard postscript fonts for rendering to backend_ps
-
- Unlike the other font classes, BakomaFont and UnicodeFont, this
- one requires the Ps backend.
- """
- basepath = os.path.join( get_data_path(), 'fonts', 'afm' )
-
- fontmap = { 'cal' : 'pzcmi8a', # Zapf Chancery
- 'rm' : 'pncr8a', # New Century Schoolbook
- 'tt' : 'pcrr8a', # Courier
- 'it' : 'pncri8a', # New Century Schoolbook Italic
- 'sf' : 'phvr8a', # Helvetica
- 'bf' : 'pncb8a', # New Century Schoolbook Bold
- None : 'psyr' # Symbol
- }
-
- def __init__(self, default_font_prop):
- Fonts.__init__(self, default_font_prop, MathtextBackendPs())
- self.glyphd = {}
- self.fonts = {}
-
- filename = findfont(default_font_prop, fontext='afm',
- directory=self.basepath)
- if filename is None:
- filename = findfont('Helvetica', fontext='afm',
- directory=self.basepath)
- with open(filename, 'rb') as fd:
- default_font = AFM(fd)
- default_font.fname = filename
-
- self.fonts['default'] = default_font
- self.fonts['regular'] = default_font
- self.pswriter = six.moves.cStringIO()
-
- def _get_font(self, font):
- if font in self.fontmap:
- basename = self.fontmap[font]
- else:
- basename = font
-
- cached_font = self.fonts.get(basename)
- if cached_font is None:
- fname = os.path.join(self.basepath, basename + ".afm")
- with open(fname, 'rb') as fd:
- cached_font = AFM(fd)
- cached_font.fname = fname
- self.fonts[basename] = cached_font
- self.fonts[cached_font.get_fontname()] = cached_font
- return cached_font
-
- def _get_info (self, fontname, font_class, sym, fontsize, dpi, math=True):
- 'load the cmfont, metrics and glyph with caching'
- key = fontname, sym, fontsize, dpi
- tup = self.glyphd.get(key)
-
- if tup is not None:
- return tup
-
- # Only characters in the "Letter" class should really be italicized.
- # This class includes greek letters, so we're ok
- if (fontname == 'it' and
- (len(sym) > 1 or
- not unicodedata.category(six.text_type(sym)).startswith("L"))):
- fontname = 'rm'
-
- found_symbol = False
-
- if sym in latex_to_standard:
- fontname, num = latex_to_standard[sym]
- glyph = chr(num)
- found_symbol = True
- elif len(sym) == 1:
- glyph = sym
- num = ord(glyph)
- found_symbol = True
- else:
- warn("No TeX to built-in Postscript mapping for {!r}".format(sym),
- MathTextWarning)
-
- slanted = (fontname == 'it')
- font = self._get_font(fontname)
-
- if found_symbol:
- try:
- symbol_name = font.get_name_char(glyph)
- except KeyError:
- warn("No glyph in standard Postscript font {!r} for {!r}"
- .format(font.get_fontname(), sym), MathTextWarning)
- found_symbol = False
-
- if not found_symbol:
- glyph = sym = '?'
- num = ord(glyph)
- symbol_name = font.get_name_char(glyph)
-
- offset = 0
-
- scale = 0.001 * fontsize
-
- xmin, ymin, xmax, ymax = [val * scale
- for val in font.get_bbox_char(glyph)]
- metrics = Bunch(
- advance = font.get_width_char(glyph) * scale,
- width = font.get_width_char(glyph) * scale,
- height = font.get_height_char(glyph) * scale,
- xmin = xmin,
- xmax = xmax,
- ymin = ymin+offset,
- ymax = ymax+offset,
- # iceberg is the equivalent of TeX's "height"
- iceberg = ymax + offset,
- slanted = slanted
- )
-
- self.glyphd[key] = Bunch(
- font = font,
- fontsize = fontsize,
- postscript_name = font.get_fontname(),
- metrics = metrics,
- symbol_name = symbol_name,
- num = num,
- glyph = glyph,
- offset = offset
- )
-
- return self.glyphd[key]
-
- def get_kern(self, font1, fontclass1, sym1, fontsize1,
- font2, fontclass2, sym2, fontsize2, dpi):
- if font1 == font2 and fontsize1 == fontsize2:
- info1 = self._get_info(font1, fontclass1, sym1, fontsize1, dpi)
- info2 = self._get_info(font2, fontclass2, sym2, fontsize2, dpi)
- font = info1.font
- return (font.get_kern_dist(info1.glyph, info2.glyph)
- * 0.001 * fontsize1)
- return Fonts.get_kern(self, font1, fontclass1, sym1, fontsize1,
- font2, fontclass2, sym2, fontsize2, dpi)
-
- def get_xheight(self, font, fontsize, dpi):
- font = self._get_font(font)
- return font.get_xheight() * 0.001 * fontsize
-
- def get_underline_thickness(self, font, fontsize, dpi):
- font = self._get_font(font)
- return font.get_underline_thickness() * 0.001 * fontsize
-
-
-##############################################################################
-# TeX-LIKE BOX MODEL
-
-# The following is based directly on the document 'woven' from the
-# TeX82 source code. This information is also available in printed
-# form:
-#
-# Knuth, Donald E.. 1986. Computers and Typesetting, Volume B:
-# TeX: The Program. Addison-Wesley Professional.
-#
-# The most relevant "chapters" are:
-# Data structures for boxes and their friends
-# Shipping pages out (Ship class)
-# Packaging (hpack and vpack)
-# Data structures for math mode
-# Subroutines for math mode
-# Typesetting math formulas
-#
-# Many of the docstrings below refer to a numbered "node" in that
-# book, e.g., node123
-#
-# Note that (as TeX) y increases downward, unlike many other parts of
-# matplotlib.
-
-# How much text shrinks when going to the next-smallest level. GROW_FACTOR
-# must be the inverse of SHRINK_FACTOR.
-SHRINK_FACTOR = 0.7
-GROW_FACTOR = 1.0 / SHRINK_FACTOR
-# The number of different sizes of chars to use, beyond which they will not
-# get any smaller
-NUM_SIZE_LEVELS = 6
-
-
-class FontConstantsBase(object):
- """
- A set of constants that controls how certain things, such as sub-
- and superscripts are laid out. These are all metrics that can't
- be reliably retrieved from the font metrics in the font itself.
- """
- # Percentage of x-height of additional horiz. space after sub/superscripts
- script_space = 0.05
-
- # Percentage of x-height that sub/superscripts drop below the baseline
- subdrop = 0.4
-
- # Percentage of x-height that superscripts are raised from the baseline
- sup1 = 0.7
-
- # Percentage of x-height that subscripts drop below the baseline
- sub1 = 0.3
-
- # Percentage of x-height that subscripts drop below the baseline when a
- # superscript is present
- sub2 = 0.5
-
- # Percentage of x-height that sub/supercripts are offset relative to the
- # nucleus edge for non-slanted nuclei
- delta = 0.025
-
- # Additional percentage of last character height above 2/3 of the
- # x-height that supercripts are offset relative to the subscript
- # for slanted nuclei
- delta_slanted = 0.2
-
- # Percentage of x-height that supercripts and subscripts are offset for
- # integrals
- delta_integral = 0.1
-
-
-class ComputerModernFontConstants(FontConstantsBase):
- script_space = 0.075
- subdrop = 0.2
- sup1 = 0.45
- sub1 = 0.2
- sub2 = 0.3
- delta = 0.075
- delta_slanted = 0.3
- delta_integral = 0.3
-
-
-class STIXFontConstants(FontConstantsBase):
- script_space = 0.1
- sup1 = 0.8
- sub2 = 0.6
- delta = 0.05
- delta_slanted = 0.3
- delta_integral = 0.3
-
-
-class STIXSansFontConstants(FontConstantsBase):
- script_space = 0.05
- sup1 = 0.8
- delta_slanted = 0.6
- delta_integral = 0.3
-
-
-class DejaVuSerifFontConstants(FontConstantsBase):
- pass
-
-
-class DejaVuSansFontConstants(FontConstantsBase):
- pass
-
-
-# Maps font family names to the FontConstantBase subclass to use
-_font_constant_mapping = {
- 'DejaVu Sans': DejaVuSansFontConstants,
- 'DejaVu Sans Mono': DejaVuSansFontConstants,
- 'DejaVu Serif': DejaVuSerifFontConstants,
- 'cmb10': ComputerModernFontConstants,
- 'cmex10': ComputerModernFontConstants,
- 'cmmi10': ComputerModernFontConstants,
- 'cmr10': ComputerModernFontConstants,
- 'cmss10': ComputerModernFontConstants,
- 'cmsy10': ComputerModernFontConstants,
- 'cmtt10': ComputerModernFontConstants,
- 'STIXGeneral': STIXFontConstants,
- 'STIXNonUnicode': STIXFontConstants,
- 'STIXSizeFiveSym': STIXFontConstants,
- 'STIXSizeFourSym': STIXFontConstants,
- 'STIXSizeThreeSym': STIXFontConstants,
- 'STIXSizeTwoSym': STIXFontConstants,
- 'STIXSizeOneSym': STIXFontConstants,
- # Map the fonts we used to ship, just for good measure
- 'Bitstream Vera Sans': DejaVuSansFontConstants,
- 'Bitstream Vera': DejaVuSansFontConstants,
- }
-
-
-def _get_font_constant_set(state):
- constants = _font_constant_mapping.get(
- state.font_output._get_font(state.font).family_name,
- FontConstantsBase)
- # STIX sans isn't really its own fonts, just different code points
- # in the STIX fonts, so we have to detect this one separately.
- if (constants is STIXFontConstants and
- isinstance(state.font_output, StixSansFonts)):
- return STIXSansFontConstants
- return constants
-
-
-class MathTextWarning(Warning):
- pass
-
-class Node(object):
- """
- A node in the TeX box model
- """
- def __init__(self):
- self.size = 0
-
- def __repr__(self):
- return self.__internal_repr__()
-
- def __internal_repr__(self):
- return self.__class__.__name__
-
- def get_kerning(self, next):
- return 0.0
-
- def shrink(self):
- """
- Shrinks one level smaller. There are only three levels of
- sizes, after which things will no longer get smaller.
- """
- self.size += 1
-
- def grow(self):
- """
- Grows one level larger. There is no limit to how big
- something can get.
- """
- self.size -= 1
-
- def render(self, x, y):
- pass
-
-class Box(Node):
- """
- Represents any node with a physical location.
- """
- def __init__(self, width, height, depth):
- Node.__init__(self)
- self.width = width
- self.height = height
- self.depth = depth
-
- def shrink(self):
- Node.shrink(self)
- if self.size < NUM_SIZE_LEVELS:
- self.width *= SHRINK_FACTOR
- self.height *= SHRINK_FACTOR
- self.depth *= SHRINK_FACTOR
-
- def grow(self):
- Node.grow(self)
- self.width *= GROW_FACTOR
- self.height *= GROW_FACTOR
- self.depth *= GROW_FACTOR
-
- def render(self, x1, y1, x2, y2):
- pass
-
-class Vbox(Box):
- """
- A box with only height (zero width).
- """
- def __init__(self, height, depth):
- Box.__init__(self, 0., height, depth)
-
-class Hbox(Box):
- """
- A box with only width (zero height and depth).
- """
- def __init__(self, width):
- Box.__init__(self, width, 0., 0.)
-
-class Char(Node):
- """
- Represents a single character. Unlike TeX, the font information
- and metrics are stored with each :class:`Char` to make it easier
- to lookup the font metrics when needed. Note that TeX boxes have
- a width, height, and depth, unlike Type1 and Truetype which use a
- full bounding box and an advance in the x-direction. The metrics
- must be converted to the TeX way, and the advance (if different
- from width) must be converted into a :class:`Kern` node when the
- :class:`Char` is added to its parent :class:`Hlist`.
- """
- def __init__(self, c, state, math=True):
- Node.__init__(self)
- self.c = c
- self.font_output = state.font_output
- self.font = state.font
- self.font_class = state.font_class
- self.fontsize = state.fontsize
- self.dpi = state.dpi
- self.math = math
- # The real width, height and depth will be set during the
- # pack phase, after we know the real fontsize
- self._update_metrics()
-
- def __internal_repr__(self):
- return '`%s`' % self.c
-
- def _update_metrics(self):
- metrics = self._metrics = self.font_output.get_metrics(
- self.font, self.font_class, self.c, self.fontsize, self.dpi, self.math)
- if self.c == ' ':
- self.width = metrics.advance
- else:
- self.width = metrics.width
- self.height = metrics.iceberg
- self.depth = -(metrics.iceberg - metrics.height)
-
- def is_slanted(self):
- return self._metrics.slanted
-
- def get_kerning(self, next):
- """
- Return the amount of kerning between this and the given
- character. Called when characters are strung together into
- :class:`Hlist` to create :class:`Kern` nodes.
- """
- advance = self._metrics.advance - self.width
- kern = 0.
- if isinstance(next, Char):
- kern = self.font_output.get_kern(
- self.font, self.font_class, self.c, self.fontsize,
- next.font, next.font_class, next.c, next.fontsize,
- self.dpi)
- return advance + kern
-
- def render(self, x, y):
- """
- Render the character to the canvas
- """
- self.font_output.render_glyph(
- x, y,
- self.font, self.font_class, self.c, self.fontsize, self.dpi)
-
- def shrink(self):
- Node.shrink(self)
- if self.size < NUM_SIZE_LEVELS:
- self.fontsize *= SHRINK_FACTOR
- self.width *= SHRINK_FACTOR
- self.height *= SHRINK_FACTOR
- self.depth *= SHRINK_FACTOR
-
- def grow(self):
- Node.grow(self)
- self.fontsize *= GROW_FACTOR
- self.width *= GROW_FACTOR
- self.height *= GROW_FACTOR
- self.depth *= GROW_FACTOR
-
-class Accent(Char):
- """
- The font metrics need to be dealt with differently for accents,
- since they are already offset correctly from the baseline in
- TrueType fonts.
- """
- def _update_metrics(self):
- metrics = self._metrics = self.font_output.get_metrics(
- self.font, self.font_class, self.c, self.fontsize, self.dpi)
- self.width = metrics.xmax - metrics.xmin
- self.height = metrics.ymax - metrics.ymin
- self.depth = 0
-
- def shrink(self):
- Char.shrink(self)
- self._update_metrics()
-
- def grow(self):
- Char.grow(self)
- self._update_metrics()
-
- def render(self, x, y):
- """
- Render the character to the canvas.
- """
- self.font_output.render_glyph(
- x - self._metrics.xmin, y + self._metrics.ymin,
- self.font, self.font_class, self.c, self.fontsize, self.dpi)
-
-class List(Box):
- """
- A list of nodes (either horizontal or vertical).
- """
- def __init__(self, elements):
- Box.__init__(self, 0., 0., 0.)
- self.shift_amount = 0. # An arbitrary offset
- self.children = elements # The child nodes of this list
- # The following parameters are set in the vpack and hpack functions
- self.glue_set = 0. # The glue setting of this list
- self.glue_sign = 0 # 0: normal, -1: shrinking, 1: stretching
- self.glue_order = 0 # The order of infinity (0 - 3) for the glue
-
- def __repr__(self):
- return '[%s <%.02f %.02f %.02f %.02f> %s]' % (
- self.__internal_repr__(),
- self.width, self.height,
- self.depth, self.shift_amount,
- ' '.join([repr(x) for x in self.children]))
-
- def _determine_order(self, totals):
- """
- A helper function to determine the highest order of glue
- used by the members of this list. Used by vpack and hpack.
- """
- o = 0
- for i in range(len(totals) - 1, 0, -1):
- if totals[i] != 0.0:
- o = i
- break
- return o
-
- def _set_glue(self, x, sign, totals, error_type):
- o = self._determine_order(totals)
- self.glue_order = o
- self.glue_sign = sign
- if totals[o] != 0.:
- self.glue_set = x / totals[o]
- else:
- self.glue_sign = 0
- self.glue_ratio = 0.
- if o == 0:
- if len(self.children):
- warn("%s %s: %r" % (error_type, self.__class__.__name__, self),
- MathTextWarning)
-
- def shrink(self):
- for child in self.children:
- child.shrink()
- Box.shrink(self)
- if self.size < NUM_SIZE_LEVELS:
- self.shift_amount *= SHRINK_FACTOR
- self.glue_set *= SHRINK_FACTOR
-
- def grow(self):
- for child in self.children:
- child.grow()
- Box.grow(self)
- self.shift_amount *= GROW_FACTOR
- self.glue_set *= GROW_FACTOR
-
-class Hlist(List):
- """
- A horizontal list of boxes.
- """
- def __init__(self, elements, w=0., m='additional', do_kern=True):
- List.__init__(self, elements)
- if do_kern:
- self.kern()
- self.hpack()
-
- def kern(self):
- """
- Insert :class:`Kern` nodes between :class:`Char` nodes to set
- kerning. The :class:`Char` nodes themselves determine the
- amount of kerning they need (in :meth:`~Char.get_kerning`),
- and this function just creates the linked list in the correct
- way.
- """
- new_children = []
- num_children = len(self.children)
- if num_children:
- for i in range(num_children):
- elem = self.children[i]
- if i < num_children - 1:
- next = self.children[i + 1]
- else:
- next = None
-
- new_children.append(elem)
- kerning_distance = elem.get_kerning(next)
- if kerning_distance != 0.:
- kern = Kern(kerning_distance)
- new_children.append(kern)
- self.children = new_children
-
- # This is a failed experiment to fake cross-font kerning.
-# def get_kerning(self, next):
-# if len(self.children) >= 2 and isinstance(self.children[-2], Char):
-# if isinstance(next, Char):
-# print "CASE A"
-# return self.children[-2].get_kerning(next)
-# elif isinstance(next, Hlist) and len(next.children) and isinstance(next.children[0], Char):
-# print "CASE B"
-# result = self.children[-2].get_kerning(next.children[0])
-# print result
-# return result
-# return 0.0
-
- def hpack(self, w=0., m='additional'):
- """
- The main duty of :meth:`hpack` is to compute the dimensions of
- the resulting boxes, and to adjust the glue if one of those
- dimensions is pre-specified. The computed sizes normally
- enclose all of the material inside the new box; but some items
- may stick out if negative glue is used, if the box is
- overfull, or if a ``\\vbox`` includes other boxes that have
- been shifted left.
-
- - *w*: specifies a width
-
- - *m*: is either 'exactly' or 'additional'.
-
- Thus, ``hpack(w, 'exactly')`` produces a box whose width is
- exactly *w*, while ``hpack(w, 'additional')`` yields a box
- whose width is the natural width plus *w*. The default values
- produce a box with the natural width.
- """
- # I don't know why these get reset in TeX. Shift_amount is pretty
- # much useless if we do.
- #self.shift_amount = 0.
- h = 0.
- d = 0.
- x = 0.
- total_stretch = [0.] * 4
- total_shrink = [0.] * 4
- for p in self.children:
- if isinstance(p, Char):
- x += p.width
- h = max(h, p.height)
- d = max(d, p.depth)
- elif isinstance(p, Box):
- x += p.width
- if not np.isinf(p.height) and not np.isinf(p.depth):
- s = getattr(p, 'shift_amount', 0.)
- h = max(h, p.height - s)
- d = max(d, p.depth + s)
- elif isinstance(p, Glue):
- glue_spec = p.glue_spec
- x += glue_spec.width
- total_stretch[glue_spec.stretch_order] += glue_spec.stretch
- total_shrink[glue_spec.shrink_order] += glue_spec.shrink
- elif isinstance(p, Kern):
- x += p.width
- self.height = h
- self.depth = d
-
- if m == 'additional':
- w += x
- self.width = w
- x = w - x
-
- if x == 0.:
- self.glue_sign = 0
- self.glue_order = 0
- self.glue_ratio = 0.
- return
- if x > 0.:
- self._set_glue(x, 1, total_stretch, "Overfull")
- else:
- self._set_glue(x, -1, total_shrink, "Underfull")
-
-class Vlist(List):
- """
- A vertical list of boxes.
- """
- def __init__(self, elements, h=0., m='additional'):
- List.__init__(self, elements)
- self.vpack()
-
- def vpack(self, h=0., m='additional', l=np.inf):
- """
- The main duty of :meth:`vpack` is to compute the dimensions of
- the resulting boxes, and to adjust the glue if one of those
- dimensions is pre-specified.
-
- - *h*: specifies a height
- - *m*: is either 'exactly' or 'additional'.
- - *l*: a maximum height
-
- Thus, ``vpack(h, 'exactly')`` produces a box whose height is
- exactly *h*, while ``vpack(h, 'additional')`` yields a box
- whose height is the natural height plus *h*. The default
- values produce a box with the natural width.
- """
- # I don't know why these get reset in TeX. Shift_amount is pretty
- # much useless if we do.
- # self.shift_amount = 0.
- w = 0.
- d = 0.
- x = 0.
- total_stretch = [0.] * 4
- total_shrink = [0.] * 4
- for p in self.children:
- if isinstance(p, Box):
- x += d + p.height
- d = p.depth
- if not np.isinf(p.width):
- s = getattr(p, 'shift_amount', 0.)
- w = max(w, p.width + s)
- elif isinstance(p, Glue):
- x += d
- d = 0.
- glue_spec = p.glue_spec
- x += glue_spec.width
- total_stretch[glue_spec.stretch_order] += glue_spec.stretch
- total_shrink[glue_spec.shrink_order] += glue_spec.shrink
- elif isinstance(p, Kern):
- x += d + p.width
- d = 0.
- elif isinstance(p, Char):
- raise RuntimeError("Internal mathtext error: Char node found in Vlist.")
-
- self.width = w
- if d > l:
- x += d - l
- self.depth = l
- else:
- self.depth = d
-
- if m == 'additional':
- h += x
- self.height = h
- x = h - x
-
- if x == 0:
- self.glue_sign = 0
- self.glue_order = 0
- self.glue_ratio = 0.
- return
-
- if x > 0.:
- self._set_glue(x, 1, total_stretch, "Overfull")
- else:
- self._set_glue(x, -1, total_shrink, "Underfull")
-
-class Rule(Box):
- """
- A :class:`Rule` node stands for a solid black rectangle; it has
- *width*, *depth*, and *height* fields just as in an
- :class:`Hlist`. However, if any of these dimensions is inf, the
- actual value will be determined by running the rule up to the
- boundary of the innermost enclosing box. This is called a "running
- dimension." The width is never running in an :class:`Hlist`; the
- height and depth are never running in a :class:`Vlist`.
- """
- def __init__(self, width, height, depth, state):
- Box.__init__(self, width, height, depth)
- self.font_output = state.font_output
-
- def render(self, x, y, w, h):
- self.font_output.render_rect_filled(x, y, x + w, y + h)
-
-class Hrule(Rule):
- """
- Convenience class to create a horizontal rule.
- """
- def __init__(self, state, thickness=None):
- if thickness is None:
- thickness = state.font_output.get_underline_thickness(
- state.font, state.fontsize, state.dpi)
- height = depth = thickness * 0.5
- Rule.__init__(self, np.inf, height, depth, state)
-
-class Vrule(Rule):
- """
- Convenience class to create a vertical rule.
- """
- def __init__(self, state):
- thickness = state.font_output.get_underline_thickness(
- state.font, state.fontsize, state.dpi)
- Rule.__init__(self, thickness, np.inf, np.inf, state)
-
-class Glue(Node):
- """
- Most of the information in this object is stored in the underlying
- :class:`GlueSpec` class, which is shared between multiple glue objects. (This
- is a memory optimization which probably doesn't matter anymore, but it's
- easier to stick to what TeX does.)
- """
- def __init__(self, glue_type, copy=False):
- Node.__init__(self)
- self.glue_subtype = 'normal'
- if isinstance(glue_type, six.string_types):
- glue_spec = GlueSpec.factory(glue_type)
- elif isinstance(glue_type, GlueSpec):
- glue_spec = glue_type
- else:
- raise ValueError("glue_type must be a glue spec name or instance.")
- if copy:
- glue_spec = glue_spec.copy()
- self.glue_spec = glue_spec
-
- def shrink(self):
- Node.shrink(self)
- if self.size < NUM_SIZE_LEVELS:
- if self.glue_spec.width != 0.:
- self.glue_spec = self.glue_spec.copy()
- self.glue_spec.width *= SHRINK_FACTOR
-
- def grow(self):
- Node.grow(self)
- if self.glue_spec.width != 0.:
- self.glue_spec = self.glue_spec.copy()
- self.glue_spec.width *= GROW_FACTOR
-
-class GlueSpec(object):
- """
- See :class:`Glue`.
- """
- def __init__(self, width=0., stretch=0., stretch_order=0, shrink=0., shrink_order=0):
- self.width = width
- self.stretch = stretch
- self.stretch_order = stretch_order
- self.shrink = shrink
- self.shrink_order = shrink_order
-
- def copy(self):
- return GlueSpec(
- self.width,
- self.stretch,
- self.stretch_order,
- self.shrink,
- self.shrink_order)
-
- def factory(cls, glue_type):
- return cls._types[glue_type]
- factory = classmethod(factory)
-
-GlueSpec._types = {
- 'fil': GlueSpec(0., 1., 1, 0., 0),
- 'fill': GlueSpec(0., 1., 2, 0., 0),
- 'filll': GlueSpec(0., 1., 3, 0., 0),
- 'neg_fil': GlueSpec(0., 0., 0, 1., 1),
- 'neg_fill': GlueSpec(0., 0., 0, 1., 2),
- 'neg_filll': GlueSpec(0., 0., 0, 1., 3),
- 'empty': GlueSpec(0., 0., 0, 0., 0),
- 'ss': GlueSpec(0., 1., 1, -1., 1)
-}
-
-# Some convenient ways to get common kinds of glue
-
-class Fil(Glue):
- def __init__(self):
- Glue.__init__(self, 'fil')
-
-class Fill(Glue):
- def __init__(self):
- Glue.__init__(self, 'fill')
-
-class Filll(Glue):
- def __init__(self):
- Glue.__init__(self, 'filll')
-
-class NegFil(Glue):
- def __init__(self):
- Glue.__init__(self, 'neg_fil')
-
-class NegFill(Glue):
- def __init__(self):
- Glue.__init__(self, 'neg_fill')
-
-class NegFilll(Glue):
- def __init__(self):
- Glue.__init__(self, 'neg_filll')
-
-class SsGlue(Glue):
- def __init__(self):
- Glue.__init__(self, 'ss')
-
-class HCentered(Hlist):
- """
- A convenience class to create an :class:`Hlist` whose contents are
- centered within its enclosing box.
- """
- def __init__(self, elements):
- Hlist.__init__(self, [SsGlue()] + elements + [SsGlue()],
- do_kern=False)
-
-class VCentered(Hlist):
- """
- A convenience class to create a :class:`Vlist` whose contents are
- centered within its enclosing box.
- """
- def __init__(self, elements):
- Vlist.__init__(self, [SsGlue()] + elements + [SsGlue()])
-
-class Kern(Node):
- """
- A :class:`Kern` node has a width field to specify a (normally
- negative) amount of spacing. This spacing correction appears in
- horizontal lists between letters like A and V when the font
- designer said that it looks better to move them closer together or
- further apart. A kern node can also appear in a vertical list,
- when its *width* denotes additional spacing in the vertical
- direction.
- """
- height = 0
- depth = 0
-
- def __init__(self, width):
- Node.__init__(self)
- self.width = width
-
- def __repr__(self):
- return "k%.02f" % self.width
-
- def shrink(self):
- Node.shrink(self)
- if self.size < NUM_SIZE_LEVELS:
- self.width *= SHRINK_FACTOR
-
- def grow(self):
- Node.grow(self)
- self.width *= GROW_FACTOR
-
-class SubSuperCluster(Hlist):
- """
- :class:`SubSuperCluster` is a sort of hack to get around that fact
- that this code do a two-pass parse like TeX. This lets us store
- enough information in the hlist itself, namely the nucleus, sub-
- and super-script, such that if another script follows that needs
- to be attached, it can be reconfigured on the fly.
- """
- def __init__(self):
- self.nucleus = None
- self.sub = None
- self.super = None
- Hlist.__init__(self, [])
-
-class AutoHeightChar(Hlist):
- """
- :class:`AutoHeightChar` will create a character as close to the
- given height and depth as possible. When using a font with
- multiple height versions of some characters (such as the BaKoMa
- fonts), the correct glyph will be selected, otherwise this will
- always just return a scaled version of the glyph.
- """
- def __init__(self, c, height, depth, state, always=False, factor=None):
- alternatives = state.font_output.get_sized_alternatives_for_symbol(
- state.font, c)
-
- xHeight = state.font_output.get_xheight(
- state.font, state.fontsize, state.dpi)
-
- state = state.copy()
- target_total = height + depth
- for fontname, sym in alternatives:
- state.font = fontname
- char = Char(sym, state)
- # Ensure that size 0 is chosen when the text is regular sized but
- # with descender glyphs by subtracting 0.2 * xHeight
- if char.height + char.depth >= target_total - 0.2 * xHeight:
- break
-
- shift = 0
- if state.font != 0:
- if factor is None:
- factor = (target_total) / (char.height + char.depth)
- state.fontsize *= factor
- char = Char(sym, state)
-
- shift = (depth - char.depth)
-
- Hlist.__init__(self, [char])
- self.shift_amount = shift
-
-class AutoWidthChar(Hlist):
- """
- :class:`AutoWidthChar` will create a character as close to the
- given width as possible. When using a font with multiple width
- versions of some characters (such as the BaKoMa fonts), the
- correct glyph will be selected, otherwise this will always just
- return a scaled version of the glyph.
- """
- def __init__(self, c, width, state, always=False, char_class=Char):
- alternatives = state.font_output.get_sized_alternatives_for_symbol(
- state.font, c)
-
- state = state.copy()
- for fontname, sym in alternatives:
- state.font = fontname
- char = char_class(sym, state)
- if char.width >= width:
- break
-
- factor = width / char.width
- state.fontsize *= factor
- char = char_class(sym, state)
-
- Hlist.__init__(self, [char])
- self.width = char.width
-
-
-class Ship(object):
- """
- Once the boxes have been set up, this sends them to output. Since
- boxes can be inside of boxes inside of boxes, the main work of
- :class:`Ship` is done by two mutually recursive routines,
- :meth:`hlist_out` and :meth:`vlist_out`, which traverse the
- :class:`Hlist` nodes and :class:`Vlist` nodes inside of horizontal
- and vertical boxes. The global variables used in TeX to store
- state as it processes have become member variables here.
- """
- def __call__(self, ox, oy, box):
- self.max_push = 0 # Deepest nesting of push commands so far
- self.cur_s = 0
- self.cur_v = 0.
- self.cur_h = 0.
- self.off_h = ox
- self.off_v = oy + box.height
- self.hlist_out(box)
-
- def clamp(value):
- if value < -1000000000.:
- return -1000000000.
- if value > 1000000000.:
- return 1000000000.
- return value
- clamp = staticmethod(clamp)
-
- def hlist_out(self, box):
- cur_g = 0
- cur_glue = 0.
- glue_order = box.glue_order
- glue_sign = box.glue_sign
- base_line = self.cur_v
- left_edge = self.cur_h
- self.cur_s += 1
- self.max_push = max(self.cur_s, self.max_push)
- clamp = self.clamp
-
- for p in box.children:
- if isinstance(p, Char):
- p.render(self.cur_h + self.off_h, self.cur_v + self.off_v)
- self.cur_h += p.width
- elif isinstance(p, Kern):
- self.cur_h += p.width
- elif isinstance(p, List):
- # node623
- if len(p.children) == 0:
- self.cur_h += p.width
- else:
- edge = self.cur_h
- self.cur_v = base_line + p.shift_amount
- if isinstance(p, Hlist):
- self.hlist_out(p)
- else:
- # p.vpack(box.height + box.depth, 'exactly')
- self.vlist_out(p)
- self.cur_h = edge + p.width
- self.cur_v = base_line
- elif isinstance(p, Box):
- # node624
- rule_height = p.height
- rule_depth = p.depth
- rule_width = p.width
- if np.isinf(rule_height):
- rule_height = box.height
- if np.isinf(rule_depth):
- rule_depth = box.depth
- if rule_height > 0 and rule_width > 0:
- self.cur_v = base_line + rule_depth
- p.render(self.cur_h + self.off_h,
- self.cur_v + self.off_v,
- rule_width, rule_height)
- self.cur_v = base_line
- self.cur_h += rule_width
- elif isinstance(p, Glue):
- # node625
- glue_spec = p.glue_spec
- rule_width = glue_spec.width - cur_g
- if glue_sign != 0: # normal
- if glue_sign == 1: # stretching
- if glue_spec.stretch_order == glue_order:
- cur_glue += glue_spec.stretch
- cur_g = np.round(clamp(float(box.glue_set) * cur_glue))
- elif glue_spec.shrink_order == glue_order:
- cur_glue += glue_spec.shrink
- cur_g = np.round(clamp(float(box.glue_set) * cur_glue))
- rule_width += cur_g
- self.cur_h += rule_width
- self.cur_s -= 1
-
- def vlist_out(self, box):
- cur_g = 0
- cur_glue = 0.
- glue_order = box.glue_order
- glue_sign = box.glue_sign
- self.cur_s += 1
- self.max_push = max(self.max_push, self.cur_s)
- left_edge = self.cur_h
- self.cur_v -= box.height
- top_edge = self.cur_v
- clamp = self.clamp
-
- for p in box.children:
- if isinstance(p, Kern):
- self.cur_v += p.width
- elif isinstance(p, List):
- if len(p.children) == 0:
- self.cur_v += p.height + p.depth
- else:
- self.cur_v += p.height
- self.cur_h = left_edge + p.shift_amount
- save_v = self.cur_v
- p.width = box.width
- if isinstance(p, Hlist):
- self.hlist_out(p)
- else:
- self.vlist_out(p)
- self.cur_v = save_v + p.depth
- self.cur_h = left_edge
- elif isinstance(p, Box):
- rule_height = p.height
- rule_depth = p.depth
- rule_width = p.width
- if np.isinf(rule_width):
- rule_width = box.width
- rule_height += rule_depth
- if rule_height > 0 and rule_depth > 0:
- self.cur_v += rule_height
- p.render(self.cur_h + self.off_h,
- self.cur_v + self.off_v,
- rule_width, rule_height)
- elif isinstance(p, Glue):
- glue_spec = p.glue_spec
- rule_height = glue_spec.width - cur_g
- if glue_sign != 0: # normal
- if glue_sign == 1: # stretching
- if glue_spec.stretch_order == glue_order:
- cur_glue += glue_spec.stretch
- cur_g = np.round(clamp(float(box.glue_set) * cur_glue))
- elif glue_spec.shrink_order == glue_order: # shrinking
- cur_glue += glue_spec.shrink
- cur_g = np.round(clamp(float(box.glue_set) * cur_glue))
- rule_height += cur_g
- self.cur_v += rule_height
- elif isinstance(p, Char):
- raise RuntimeError("Internal mathtext error: Char node found in vlist")
- self.cur_s -= 1
-
-
-ship = Ship()
-
-##############################################################################
-# PARSER
-
-def Error(msg):
- """
- Helper class to raise parser errors.
- """
- def raise_error(s, loc, toks):
- raise ParseFatalException(s, loc, msg)
-
- empty = Empty()
- empty.setParseAction(raise_error)
- return empty
-
-class Parser(object):
- """
- This is the pyparsing-based parser for math expressions. It
- actually parses full strings *containing* math expressions, in
- that raw text may also appear outside of pairs of ``$``.
-
- The grammar is based directly on that in TeX, though it cuts a few
- corners.
- """
-
- _math_style_dict = dict(displaystyle=0, textstyle=1,
- scriptstyle=2, scriptscriptstyle=3)
-
- _binary_operators = set('''
- + * -
- \\pm \\sqcap \\rhd
- \\mp \\sqcup \\unlhd
- \\times \\vee \\unrhd
- \\div \\wedge \\oplus
- \\ast \\setminus \\ominus
- \\star \\wr \\otimes
- \\circ \\diamond \\oslash
- \\bullet \\bigtriangleup \\odot
- \\cdot \\bigtriangledown \\bigcirc
- \\cap \\triangleleft \\dagger
- \\cup \\triangleright \\ddagger
- \\uplus \\lhd \\amalg'''.split())
-
- _relation_symbols = set('''
- = < > :
- \\leq \\geq \\equiv \\models
- \\prec \\succ \\sim \\perp
- \\preceq \\succeq \\simeq \\mid
- \\ll \\gg \\asymp \\parallel
- \\subset \\supset \\approx \\bowtie
- \\subseteq \\supseteq \\cong \\Join
- \\sqsubset \\sqsupset \\neq \\smile
- \\sqsubseteq \\sqsupseteq \\doteq \\frown
- \\in \\ni \\propto \\vdash
- \\dashv \\dots \\dotplus \\doteqdot'''.split())
-
- _arrow_symbols = set('''
- \\leftarrow \\longleftarrow \\uparrow
- \\Leftarrow \\Longleftarrow \\Uparrow
- \\rightarrow \\longrightarrow \\downarrow
- \\Rightarrow \\Longrightarrow \\Downarrow
- \\leftrightarrow \\longleftrightarrow \\updownarrow
- \\Leftrightarrow \\Longleftrightarrow \\Updownarrow
- \\mapsto \\longmapsto \\nearrow
- \\hookleftarrow \\hookrightarrow \\searrow
- \\leftharpoonup \\rightharpoonup \\swarrow
- \\leftharpoondown \\rightharpoondown \\nwarrow
- \\rightleftharpoons \\leadsto'''.split())
-
- _spaced_symbols = _binary_operators | _relation_symbols | _arrow_symbols
-
- _punctuation_symbols = set(r', ; . ! \ldotp \cdotp'.split())
-
- _overunder_symbols = set(r'''
- \sum \prod \coprod \bigcap \bigcup \bigsqcup \bigvee
- \bigwedge \bigodot \bigotimes \bigoplus \biguplus
- '''.split())
-
- _overunder_functions = set(
- r"lim liminf limsup sup max min".split())
-
- _dropsub_symbols = set(r'''\int \oint'''.split())
-
- _fontnames = set("rm cal it tt sf bf default bb frak circled scr regular".split())
-
- _function_names = set("""
- arccos csc ker min arcsin deg lg Pr arctan det lim sec arg dim
- liminf sin cos exp limsup sinh cosh gcd ln sup cot hom log tan
- coth inf max tanh""".split())
-
- _ambi_delim = set("""
- | \\| / \\backslash \\uparrow \\downarrow \\updownarrow \\Uparrow
- \\Downarrow \\Updownarrow . \\vert \\Vert \\\\|""".split())
-
- _left_delim = set(r"( [ \{ < \lfloor \langle \lceil".split())
-
- _right_delim = set(r") ] \} > \rfloor \rangle \rceil".split())
-
- def __init__(self):
- p = Bunch()
- # All forward declarations are here
- p.accent = Forward()
- p.ambi_delim = Forward()
- p.apostrophe = Forward()
- p.auto_delim = Forward()
- p.binom = Forward()
- p.bslash = Forward()
- p.c_over_c = Forward()
- p.customspace = Forward()
- p.end_group = Forward()
- p.float_literal = Forward()
- p.font = Forward()
- p.frac = Forward()
- p.dfrac = Forward()
- p.function = Forward()
- p.genfrac = Forward()
- p.group = Forward()
- p.int_literal = Forward()
- p.latexfont = Forward()
- p.lbracket = Forward()
- p.left_delim = Forward()
- p.lbrace = Forward()
- p.main = Forward()
- p.math = Forward()
- p.math_string = Forward()
- p.non_math = Forward()
- p.operatorname = Forward()
- p.overline = Forward()
- p.placeable = Forward()
- p.rbrace = Forward()
- p.rbracket = Forward()
- p.required_group = Forward()
- p.right_delim = Forward()
- p.right_delim_safe = Forward()
- p.simple = Forward()
- p.simple_group = Forward()
- p.single_symbol = Forward()
- p.snowflake = Forward()
- p.space = Forward()
- p.sqrt = Forward()
- p.stackrel = Forward()
- p.start_group = Forward()
- p.subsuper = Forward()
- p.subsuperop = Forward()
- p.symbol = Forward()
- p.symbol_name = Forward()
- p.token = Forward()
- p.unknown_symbol = Forward()
-
- # Set names on everything -- very useful for debugging
- for key, val in vars(p).items():
- if not key.startswith('_'):
- val.setName(key)
-
- p.float_literal <<= Regex(r"[-+]?([0-9]+\.?[0-9]*|\.[0-9]+)")
- p.int_literal <<= Regex("[-+]?[0-9]+")
-
- p.lbrace <<= Literal('{').suppress()
- p.rbrace <<= Literal('}').suppress()
- p.lbracket <<= Literal('[').suppress()
- p.rbracket <<= Literal(']').suppress()
- p.bslash <<= Literal('\\')
-
- p.space <<= oneOf(list(self._space_widths))
- p.customspace <<= (Suppress(Literal(r'\hspace'))
- - ((p.lbrace + p.float_literal + p.rbrace)
- | Error(r"Expected \hspace{n}")))
-
- unicode_range = "\U00000080-\U0001ffff"
- p.single_symbol <<= Regex(r"([a-zA-Z0-9 +\-*/<>=:,.;!\?&'@()\[\]|%s])|(\\[%%${}\[\]_|])" %
- unicode_range)
- p.snowflake <<= Suppress(p.bslash) + oneOf(self._snowflake)
- p.symbol_name <<= (Combine(p.bslash + oneOf(list(tex2uni))) +
- FollowedBy(Regex("[^A-Za-z]").leaveWhitespace() | StringEnd()))
- p.symbol <<= (p.single_symbol | p.symbol_name).leaveWhitespace()
-
- p.apostrophe <<= Regex("'+")
-
- p.c_over_c <<= Suppress(p.bslash) + oneOf(list(self._char_over_chars))
-
- p.accent <<= Group(
- Suppress(p.bslash)
- + oneOf(list(self._accent_map) + list(self._wide_accents))
- - p.placeable
- )
-
- p.function <<= Suppress(p.bslash) + oneOf(list(self._function_names))
-
- p.start_group <<= Optional(p.latexfont) + p.lbrace
- p.end_group <<= p.rbrace.copy()
- p.simple_group <<= Group(p.lbrace + ZeroOrMore(p.token) + p.rbrace)
- p.required_group<<= Group(p.lbrace + OneOrMore(p.token) + p.rbrace)
- p.group <<= Group(p.start_group + ZeroOrMore(p.token) + p.end_group)
-
- p.font <<= Suppress(p.bslash) + oneOf(list(self._fontnames))
- p.latexfont <<= Suppress(p.bslash) + oneOf(['math' + x for x in self._fontnames])
-
- p.frac <<= Group(
- Suppress(Literal(r"\frac"))
- - ((p.required_group + p.required_group) | Error(r"Expected \frac{num}{den}"))
- )
-
- p.dfrac <<= Group(
- Suppress(Literal(r"\dfrac"))
- - ((p.required_group + p.required_group) | Error(r"Expected \dfrac{num}{den}"))
- )
-
- p.stackrel <<= Group(
- Suppress(Literal(r"\stackrel"))
- - ((p.required_group + p.required_group) | Error(r"Expected \stackrel{num}{den}"))
- )
-
- p.binom <<= Group(
- Suppress(Literal(r"\binom"))
- - ((p.required_group + p.required_group) | Error(r"Expected \binom{num}{den}"))
- )
-
- p.ambi_delim <<= oneOf(list(self._ambi_delim))
- p.left_delim <<= oneOf(list(self._left_delim))
- p.right_delim <<= oneOf(list(self._right_delim))
- p.right_delim_safe <<= oneOf(list(self._right_delim - {'}'}) + [r'\}'])
-
- p.genfrac <<= Group(
- Suppress(Literal(r"\genfrac"))
- - (((p.lbrace + Optional(p.ambi_delim | p.left_delim, default='') + p.rbrace)
- + (p.lbrace + Optional(p.ambi_delim | p.right_delim_safe, default='') + p.rbrace)
- + (p.lbrace + p.float_literal + p.rbrace)
- + p.simple_group + p.required_group + p.required_group)
- | Error(r"Expected \genfrac{ldelim}{rdelim}{rulesize}{style}{num}{den}"))
- )
-
- p.sqrt <<= Group(
- Suppress(Literal(r"\sqrt"))
- - ((Optional(p.lbracket + p.int_literal + p.rbracket, default=None)
- + p.required_group)
- | Error("Expected \\sqrt{value}"))
- )
-
- p.overline <<= Group(
- Suppress(Literal(r"\overline"))
- - (p.required_group | Error("Expected \\overline{value}"))
- )
-
- p.unknown_symbol<<= Combine(p.bslash + Regex("[A-Za-z]*"))
-
- p.operatorname <<= Group(
- Suppress(Literal(r"\operatorname"))
- - ((p.lbrace + ZeroOrMore(p.simple | p.unknown_symbol) + p.rbrace)
- | Error("Expected \\operatorname{value}"))
- )
-
- p.placeable <<= ( p.snowflake # this needs to be before accent so named symbols
- # that are prefixed with an accent name work
- | p.accent # Must be before symbol as all accents are symbols
- | p.symbol # Must be third to catch all named symbols and single chars not in a group
- | p.c_over_c
- | p.function
- | p.group
- | p.frac
- | p.dfrac
- | p.stackrel
- | p.binom
- | p.genfrac
- | p.sqrt
- | p.overline
- | p.operatorname
- )
-
- p.simple <<= ( p.space
- | p.customspace
- | p.font
- | p.subsuper
- )
-
- p.subsuperop <<= oneOf(["_", "^"])
-
- p.subsuper <<= Group(
- (Optional(p.placeable) + OneOrMore(p.subsuperop - p.placeable) + Optional(p.apostrophe))
- | (p.placeable + Optional(p.apostrophe))
- | p.apostrophe
- )
-
- p.token <<= ( p.simple
- | p.auto_delim
- | p.unknown_symbol # Must be last
- )
-
- p.auto_delim <<= (Suppress(Literal(r"\left"))
- - ((p.left_delim | p.ambi_delim) | Error("Expected a delimiter"))
- + Group(ZeroOrMore(p.simple | p.auto_delim))
- + Suppress(Literal(r"\right"))
- - ((p.right_delim | p.ambi_delim) | Error("Expected a delimiter"))
- )
-
- p.math <<= OneOrMore(p.token)
-
- p.math_string <<= QuotedString('$', '\\', unquoteResults=False)
-
- p.non_math <<= Regex(r"(?:(?:\\[$])|[^$])*").leaveWhitespace()
-
- p.main <<= (p.non_math + ZeroOrMore(p.math_string + p.non_math)) + StringEnd()
-
- # Set actions
- for key, val in vars(p).items():
- if not key.startswith('_'):
- if hasattr(self, key):
- val.setParseAction(getattr(self, key))
-
- self._expression = p.main
- self._math_expression = p.math
-
- def parse(self, s, fonts_object, fontsize, dpi):
- """
- Parse expression *s* using the given *fonts_object* for
- output, at the given *fontsize* and *dpi*.
-
- Returns the parse tree of :class:`Node` instances.
- """
- self._state_stack = [self.State(fonts_object, 'default', 'rm', fontsize, dpi)]
- self._em_width_cache = {}
- try:
- result = self._expression.parseString(s)
- except ParseBaseException as err:
- raise ValueError("\n".join([
- "",
- err.line,
- " " * (err.column - 1) + "^",
- six.text_type(err)]))
- self._state_stack = None
- self._em_width_cache = {}
- self._expression.resetCache()
- return result[0]
-
- # The state of the parser is maintained in a stack. Upon
- # entering and leaving a group { } or math/non-math, the stack
- # is pushed and popped accordingly. The current state always
- # exists in the top element of the stack.
- class State(object):
- """
- Stores the state of the parser.
-
- States are pushed and popped from a stack as necessary, and
- the "current" state is always at the top of the stack.
- """
- def __init__(self, font_output, font, font_class, fontsize, dpi):
- self.font_output = font_output
- self._font = font
- self.font_class = font_class
- self.fontsize = fontsize
- self.dpi = dpi
-
- def copy(self):
- return Parser.State(
- self.font_output,
- self.font,
- self.font_class,
- self.fontsize,
- self.dpi)
-
- def _get_font(self):
- return self._font
- def _set_font(self, name):
- if name in ('rm', 'it', 'bf'):
- self.font_class = name
- self._font = name
- font = property(_get_font, _set_font)
-
- def get_state(self):
- """
- Get the current :class:`State` of the parser.
- """
- return self._state_stack[-1]
-
- def pop_state(self):
- """
- Pop a :class:`State` off of the stack.
- """
- self._state_stack.pop()
-
- def push_state(self):
- """
- Push a new :class:`State` onto the stack which is just a copy
- of the current state.
- """
- self._state_stack.append(self.get_state().copy())
-
- def main(self, s, loc, toks):
- return [Hlist(toks)]
-
- def math_string(self, s, loc, toks):
- return self._math_expression.parseString(toks[0][1:-1])
-
- def math(self, s, loc, toks):
- hlist = Hlist(toks)
- self.pop_state()
- return [hlist]
-
- def non_math(self, s, loc, toks):
- s = toks[0].replace(r'\$', '$')
- symbols = [Char(c, self.get_state(), math=False) for c in s]
- hlist = Hlist(symbols)
- # We're going into math now, so set font to 'it'
- self.push_state()
- self.get_state().font = rcParams['mathtext.default']
- return [hlist]
-
- def _make_space(self, percentage):
- # All spaces are relative to em width
- state = self.get_state()
- key = (state.font, state.fontsize, state.dpi)
- width = self._em_width_cache.get(key)
- if width is None:
- metrics = state.font_output.get_metrics(
- state.font, rcParams['mathtext.default'], 'm', state.fontsize, state.dpi)
- width = metrics.advance
- self._em_width_cache[key] = width
- return Kern(width * percentage)
-
- _space_widths = { r'\,' : 0.16667, # 3/18 em = 3 mu
- r'\thinspace' : 0.16667, # 3/18 em = 3 mu
- r'\/' : 0.16667, # 3/18 em = 3 mu
- r'\>' : 0.22222, # 4/18 em = 4 mu
- r'\:' : 0.22222, # 4/18 em = 4 mu
- r'\;' : 0.27778, # 5/18 em = 5 mu
- r'\ ' : 0.33333, # 6/18 em = 6 mu
- r'\enspace' : 0.5, # 9/18 em = 9 mu
- r'\quad' : 1, # 1 em = 18 mu
- r'\qquad' : 2, # 2 em = 36 mu
- r'\!' : -0.16667, # -3/18 em = -3 mu
- }
- def space(self, s, loc, toks):
- assert len(toks)==1
- num = self._space_widths[toks[0]]
- box = self._make_space(num)
- return [box]
-
- def customspace(self, s, loc, toks):
- return [self._make_space(float(toks[0]))]
-
- def symbol(self, s, loc, toks):
- c = toks[0]
- try:
- char = Char(c, self.get_state())
- except ValueError:
- raise ParseFatalException(s, loc, "Unknown symbol: %s" % c)
-
- if c in self._spaced_symbols:
- # iterate until we find previous character, needed for cases
- # such as ${ -2}$, $ -2$, or $ -2$.
- for i in six.moves.xrange(1, loc + 1):
- prev_char = s[loc-i]
- if prev_char != ' ':
- break
- # Binary operators at start of string should not be spaced
- if (c in self._binary_operators and
- (len(s[:loc].split()) == 0 or prev_char == '{' or
- prev_char in self._left_delim)):
- return [char]
- else:
- return [Hlist([self._make_space(0.2),
- char,
- self._make_space(0.2)] ,
- do_kern = True)]
- elif c in self._punctuation_symbols:
-
- # Do not space commas between brackets
- if c == ',':
- prev_char, next_char = '', ''
- for i in six.moves.xrange(1, loc + 1):
- prev_char = s[loc - i]
- if prev_char != ' ':
- break
- for i in six.moves.xrange(1, len(s) - loc):
- next_char = s[loc + i]
- if next_char != ' ':
- break
- if (prev_char == '{' and next_char == '}'):
- return [char]
-
- # Do not space dots as decimal separators
- if (c == '.' and s[loc - 1].isdigit() and s[loc + 1].isdigit()):
- return [char]
- else:
- return [Hlist([char,
- self._make_space(0.2)],
- do_kern = True)]
- return [char]
-
- snowflake = symbol
-
- def unknown_symbol(self, s, loc, toks):
- c = toks[0]
- raise ParseFatalException(s, loc, "Unknown symbol: %s" % c)
-
- _char_over_chars = {
- # The first 2 entries in the tuple are (font, char, sizescale) for
- # the two symbols under and over. The third element is the space
- # (in multiples of underline height)
- r'AA': (('it', 'A', 1.0), (None, '\\circ', 0.5), 0.0),
- }
-
- def c_over_c(self, s, loc, toks):
- sym = toks[0]
- state = self.get_state()
- thickness = state.font_output.get_underline_thickness(
- state.font, state.fontsize, state.dpi)
-
- under_desc, over_desc, space = \
- self._char_over_chars.get(sym, (None, None, 0.0))
- if under_desc is None:
- raise ParseFatalException("Error parsing symbol")
-
- over_state = state.copy()
- if over_desc[0] is not None:
- over_state.font = over_desc[0]
- over_state.fontsize *= over_desc[2]
- over = Accent(over_desc[1], over_state)
-
- under_state = state.copy()
- if under_desc[0] is not None:
- under_state.font = under_desc[0]
- under_state.fontsize *= under_desc[2]
- under = Char(under_desc[1], under_state)
-
- width = max(over.width, under.width)
-
- over_centered = HCentered([over])
- over_centered.hpack(width, 'exactly')
-
- under_centered = HCentered([under])
- under_centered.hpack(width, 'exactly')
-
- return Vlist([
- over_centered,
- Vbox(0., thickness * space),
- under_centered
- ])
-
- _accent_map = {
- r'hat' : r'\circumflexaccent',
- r'breve' : r'\combiningbreve',
- r'bar' : r'\combiningoverline',
- r'grave' : r'\combininggraveaccent',
- r'acute' : r'\combiningacuteaccent',
- r'tilde' : r'\combiningtilde',
- r'dot' : r'\combiningdotabove',
- r'ddot' : r'\combiningdiaeresis',
- r'vec' : r'\combiningrightarrowabove',
- r'"' : r'\combiningdiaeresis',
- r"`" : r'\combininggraveaccent',
- r"'" : r'\combiningacuteaccent',
- r'~' : r'\combiningtilde',
- r'.' : r'\combiningdotabove',
- r'^' : r'\circumflexaccent',
- r'overrightarrow' : r'\rightarrow',
- r'overleftarrow' : r'\leftarrow',
- r'mathring' : r'\circ'
- }
-
- _wide_accents = set(r"widehat widetilde widebar".split())
-
- # make a lambda and call it to get the namespace right
- _snowflake = (lambda am: [p for p in tex2uni if
- any(p.startswith(a) and a != p for a in am)]
- ) (set(_accent_map))
-
- def accent(self, s, loc, toks):
- assert len(toks)==1
- state = self.get_state()
- thickness = state.font_output.get_underline_thickness(
- state.font, state.fontsize, state.dpi)
- if len(toks[0]) != 2:
- raise ParseFatalException("Error parsing accent")
- accent, sym = toks[0]
- if accent in self._wide_accents:
- accent_box = AutoWidthChar(
- '\\' + accent, sym.width, state, char_class=Accent)
- else:
- accent_box = Accent(self._accent_map[accent], state)
- if accent == 'mathring':
- accent_box.shrink()
- accent_box.shrink()
- centered = HCentered([Hbox(sym.width / 4.0), accent_box])
- centered.hpack(sym.width, 'exactly')
- return Vlist([
- centered,
- Vbox(0., thickness * 2.0),
- Hlist([sym])
- ])
-
- def function(self, s, loc, toks):
- self.push_state()
- state = self.get_state()
- state.font = 'rm'
- hlist = Hlist([Char(c, state) for c in toks[0]])
- self.pop_state()
- hlist.function_name = toks[0]
- return hlist
-
- def operatorname(self, s, loc, toks):
- self.push_state()
- state = self.get_state()
- state.font = 'rm'
- # Change the font of Chars, but leave Kerns alone
- for c in toks[0]:
- if isinstance(c, Char):
- c.font = 'rm'
- c._update_metrics()
- self.pop_state()
- return Hlist(toks[0])
-
- def start_group(self, s, loc, toks):
- self.push_state()
- # Deal with LaTeX-style font tokens
- if len(toks):
- self.get_state().font = toks[0][4:]
- return []
-
- def group(self, s, loc, toks):
- grp = Hlist(toks[0])
- return [grp]
- required_group = simple_group = group
-
- def end_group(self, s, loc, toks):
- self.pop_state()
- return []
-
- def font(self, s, loc, toks):
- assert len(toks)==1
- name = toks[0]
- self.get_state().font = name
- return []
-
- def is_overunder(self, nucleus):
- if isinstance(nucleus, Char):
- return nucleus.c in self._overunder_symbols
- elif isinstance(nucleus, Hlist) and hasattr(nucleus, 'function_name'):
- return nucleus.function_name in self._overunder_functions
- return False
-
- def is_dropsub(self, nucleus):
- if isinstance(nucleus, Char):
- return nucleus.c in self._dropsub_symbols
- return False
-
- def is_slanted(self, nucleus):
- if isinstance(nucleus, Char):
- return nucleus.is_slanted()
- return False
-
- def is_between_brackets(self, s, loc):
- return False
-
- def subsuper(self, s, loc, toks):
- assert len(toks)==1
-
- nucleus = None
- sub = None
- super = None
-
- # Pick all of the apostrophes out, including first apostrophes that have
- # been parsed as characters
- napostrophes = 0
- new_toks = []
- for tok in toks[0]:
- if isinstance(tok, six.string_types) and tok not in ('^', '_'):
- napostrophes += len(tok)
- elif isinstance(tok, Char) and tok.c == "'":
- napostrophes += 1
- else:
- new_toks.append(tok)
- toks = new_toks
-
- if len(toks) == 0:
- assert napostrophes
- nucleus = Hbox(0.0)
- elif len(toks) == 1:
- if not napostrophes:
- return toks[0] # .asList()
- else:
- nucleus = toks[0]
- elif len(toks) in (2, 3):
- # single subscript or superscript
- nucleus = toks[0] if len(toks) == 3 else Hbox(0.0)
- op, next = toks[-2:]
- if op == '_':
- sub = next
- else:
- super = next
- elif len(toks) in (4, 5):
- # subscript and superscript
- nucleus = toks[0] if len(toks) == 5 else Hbox(0.0)
- op1, next1, op2, next2 = toks[-4:]
- if op1 == op2:
- if op1 == '_':
- raise ParseFatalException("Double subscript")
- else:
- raise ParseFatalException("Double superscript")
- if op1 == '_':
- sub = next1
- super = next2
- else:
- super = next1
- sub = next2
- else:
- raise ParseFatalException(
- "Subscript/superscript sequence is too long. "
- "Use braces { } to remove ambiguity.")
-
- state = self.get_state()
- rule_thickness = state.font_output.get_underline_thickness(
- state.font, state.fontsize, state.dpi)
- xHeight = state.font_output.get_xheight(
- state.font, state.fontsize, state.dpi)
-
- if napostrophes:
- if super is None:
- super = Hlist([])
- for i in range(napostrophes):
- super.children.extend(self.symbol(s, loc, ['\\prime']))
- # kern() and hpack() needed to get the metrics right after extending
- super.kern()
- super.hpack()
-
- # Handle over/under symbols, such as sum or integral
- if self.is_overunder(nucleus):
- vlist = []
- shift = 0.
- width = nucleus.width
- if super is not None:
- super.shrink()
- width = max(width, super.width)
- if sub is not None:
- sub.shrink()
- width = max(width, sub.width)
-
- if super is not None:
- hlist = HCentered([super])
- hlist.hpack(width, 'exactly')
- vlist.extend([hlist, Kern(rule_thickness * 3.0)])
- hlist = HCentered([nucleus])
- hlist.hpack(width, 'exactly')
- vlist.append(hlist)
- if sub is not None:
- hlist = HCentered([sub])
- hlist.hpack(width, 'exactly')
- vlist.extend([Kern(rule_thickness * 3.0), hlist])
- shift = hlist.height
- vlist = Vlist(vlist)
- vlist.shift_amount = shift + nucleus.depth
- result = Hlist([vlist])
- return [result]
-
- # We remove kerning on the last character for consistency (otherwise it
- # will compute kerning based on non-shrinked characters and may put them
- # too close together when superscripted)
- # We change the width of the last character to match the advance to
- # consider some fonts with weird metrics: e.g. stix's f has a width of
- # 7.75 and a kerning of -4.0 for an advance of 3.72, and we want to put
- # the superscript at the advance
- last_char = nucleus
- if isinstance(nucleus, Hlist):
- new_children = nucleus.children
- if len(new_children):
- # remove last kern
- if (isinstance(new_children[-1],Kern) and
- hasattr(new_children[-2], '_metrics')):
- new_children = new_children[:-1]
- last_char = new_children[-1]
- if hasattr(last_char, '_metrics'):
- last_char.width = last_char._metrics.advance
- # create new Hlist without kerning
- nucleus = Hlist(new_children, do_kern=False)
- else:
- if isinstance(nucleus, Char):
- last_char.width = last_char._metrics.advance
- nucleus = Hlist([nucleus])
-
- # Handle regular sub/superscripts
- constants = _get_font_constant_set(state)
- lc_height = last_char.height
- lc_baseline = 0
- if self.is_dropsub(last_char):
- lc_baseline = last_char.depth
-
- # Compute kerning for sub and super
- superkern = constants.delta * xHeight
- subkern = constants.delta * xHeight
- if self.is_slanted(last_char):
- superkern += constants.delta * xHeight
- superkern += (constants.delta_slanted *
- (lc_height - xHeight * 2. / 3.))
- if self.is_dropsub(last_char):
- subkern = (3 * constants.delta -
- constants.delta_integral) * lc_height
- superkern = (3 * constants.delta +
- constants.delta_integral) * lc_height
- else:
- subkern = 0
-
- if super is None:
- # node757
- x = Hlist([Kern(subkern), sub])
- x.shrink()
- if self.is_dropsub(last_char):
- shift_down = lc_baseline + constants.subdrop * xHeight
- else:
- shift_down = constants.sub1 * xHeight
- x.shift_amount = shift_down
- else:
- x = Hlist([Kern(superkern), super])
- x.shrink()
- if self.is_dropsub(last_char):
- shift_up = lc_height - constants.subdrop * xHeight
- else:
- shift_up = constants.sup1 * xHeight
- if sub is None:
- x.shift_amount = -shift_up
- else: # Both sub and superscript
- y = Hlist([Kern(subkern),sub])
- y.shrink()
- if self.is_dropsub(last_char):
- shift_down = lc_baseline + constants.subdrop * xHeight
- else:
- shift_down = constants.sub2 * xHeight
- # If sub and superscript collide, move super up
- clr = (2.0 * rule_thickness -
- ((shift_up - x.depth) - (y.height - shift_down)))
- if clr > 0.:
- shift_up += clr
- x = Vlist([x,
- Kern((shift_up - x.depth) - (y.height - shift_down)),
- y])
- x.shift_amount = shift_down
-
- if not self.is_dropsub(last_char):
- x.width += constants.script_space * xHeight
- result = Hlist([nucleus, x])
-
- return [result]
-
- def _genfrac(self, ldelim, rdelim, rule, style, num, den):
- state = self.get_state()
- thickness = state.font_output.get_underline_thickness(
- state.font, state.fontsize, state.dpi)
-
- rule = float(rule)
-
- # If style != displaystyle == 0, shrink the num and den
- if style != self._math_style_dict['displaystyle']:
- num.shrink()
- den.shrink()
- cnum = HCentered([num])
- cden = HCentered([den])
- width = max(num.width, den.width)
- cnum.hpack(width, 'exactly')
- cden.hpack(width, 'exactly')
- vlist = Vlist([cnum, # numerator
- Vbox(0, thickness * 2.0), # space
- Hrule(state, rule), # rule
- Vbox(0, thickness * 2.0), # space
- cden # denominator
- ])
-
- # Shift so the fraction line sits in the middle of the
- # equals sign
- metrics = state.font_output.get_metrics(
- state.font, rcParams['mathtext.default'],
- '=', state.fontsize, state.dpi)
- shift = (cden.height -
- ((metrics.ymax + metrics.ymin) / 2 -
- thickness * 3.0))
- vlist.shift_amount = shift
-
- result = [Hlist([vlist, Hbox(thickness * 2.)])]
- if ldelim or rdelim:
- if ldelim == '':
- ldelim = '.'
- if rdelim == '':
- rdelim = '.'
- return self._auto_sized_delimiter(ldelim, result, rdelim)
- return result
-
- def genfrac(self, s, loc, toks):
- assert len(toks) == 1
- assert len(toks[0]) == 6
-
- return self._genfrac(*tuple(toks[0]))
-
- def frac(self, s, loc, toks):
- assert len(toks) == 1
- assert len(toks[0]) == 2
- state = self.get_state()
-
- thickness = state.font_output.get_underline_thickness(
- state.font, state.fontsize, state.dpi)
- num, den = toks[0]
-
- return self._genfrac('', '', thickness,
- self._math_style_dict['textstyle'], num, den)
-
- def dfrac(self, s, loc, toks):
- assert len(toks) == 1
- assert len(toks[0]) == 2
- state = self.get_state()
-
- thickness = state.font_output.get_underline_thickness(
- state.font, state.fontsize, state.dpi)
- num, den = toks[0]
-
- return self._genfrac('', '', thickness,
- self._math_style_dict['displaystyle'], num, den)
-
- def stackrel(self, s, loc, toks):
- assert len(toks) == 1
- assert len(toks[0]) == 2
- num, den = toks[0]
-
- return self._genfrac('', '', 0.0,
- self._math_style_dict['textstyle'], num, den)
-
- def binom(self, s, loc, toks):
- assert len(toks) == 1
- assert len(toks[0]) == 2
- num, den = toks[0]
-
- return self._genfrac('(', ')', 0.0,
- self._math_style_dict['textstyle'], num, den)
-
- def sqrt(self, s, loc, toks):
- root, body = toks[0]
- state = self.get_state()
- thickness = state.font_output.get_underline_thickness(
- state.font, state.fontsize, state.dpi)
-
- # Determine the height of the body, and add a little extra to
- # the height so it doesn't seem cramped
- height = body.height - body.shift_amount + thickness * 5.0
- depth = body.depth + body.shift_amount
- check = AutoHeightChar(r'\__sqrt__', height, depth, state, always=True)
- height = check.height - check.shift_amount
- depth = check.depth + check.shift_amount
-
- # Put a little extra space to the left and right of the body
- padded_body = Hlist([Hbox(thickness * 2.0),
- body,
- Hbox(thickness * 2.0)])
- rightside = Vlist([Hrule(state),
- Fill(),
- padded_body])
- # Stretch the glue between the hrule and the body
- rightside.vpack(height + (state.fontsize * state.dpi) / (100.0 * 12.0),
- 'exactly', depth)
-
- # Add the root and shift it upward so it is above the tick.
- # The value of 0.6 is a hard-coded hack ;)
- if root is None:
- root = Box(check.width * 0.5, 0., 0.)
- else:
- root = Hlist([Char(x, state) for x in root])
- root.shrink()
- root.shrink()
-
- root_vlist = Vlist([Hlist([root])])
- root_vlist.shift_amount = -height * 0.6
-
- hlist = Hlist([root_vlist, # Root
- # Negative kerning to put root over tick
- Kern(-check.width * 0.5),
- check, # Check
- rightside]) # Body
- return [hlist]
-
- def overline(self, s, loc, toks):
- assert len(toks)==1
- assert len(toks[0])==1
-
- body = toks[0][0]
-
- state = self.get_state()
- thickness = state.font_output.get_underline_thickness(
- state.font, state.fontsize, state.dpi)
-
- height = body.height - body.shift_amount + thickness * 3.0
- depth = body.depth + body.shift_amount
-
- # Place overline above body
- rightside = Vlist([Hrule(state),
- Fill(),
- Hlist([body])])
-
- # Stretch the glue between the hrule and the body
- rightside.vpack(height + (state.fontsize * state.dpi) / (100.0 * 12.0),
- 'exactly', depth)
-
- hlist = Hlist([rightside])
- return [hlist]
-
- def _auto_sized_delimiter(self, front, middle, back):
- state = self.get_state()
- if len(middle):
- height = max(x.height for x in middle)
- depth = max(x.depth for x in middle)
- factor = None
- else:
- height = 0
- depth = 0
- factor = 1.0
- parts = []
- # \left. and \right. aren't supposed to produce any symbols
- if front != '.':
- parts.append(AutoHeightChar(front, height, depth, state, factor=factor))
- parts.extend(middle)
- if back != '.':
- parts.append(AutoHeightChar(back, height, depth, state, factor=factor))
- hlist = Hlist(parts)
- return hlist
-
- def auto_delim(self, s, loc, toks):
- front, middle, back = toks
-
- return self._auto_sized_delimiter(front, middle.asList(), back)
-
-###
-
-##############################################################################
-# MAIN
-
-class MathTextParser(object):
- _parser = None
-
- _backend_mapping = {
- 'bitmap': MathtextBackendBitmap,
- 'agg' : MathtextBackendAgg,
- 'ps' : MathtextBackendPs,
- 'pdf' : MathtextBackendPdf,
- 'svg' : MathtextBackendSvg,
- 'path' : MathtextBackendPath,
- 'cairo' : MathtextBackendCairo,
- 'macosx': MathtextBackendAgg,
- }
-
- _font_type_mapping = {
- 'cm' : BakomaFonts,
- 'dejavuserif' : DejaVuSerifFonts,
- 'dejavusans' : DejaVuSansFonts,
- 'stix' : StixFonts,
- 'stixsans' : StixSansFonts,
- 'custom' : UnicodeFonts
- }
-
- def __init__(self, output):
- """
- Create a MathTextParser for the given backend *output*.
- """
- self._output = output.lower()
- self._cache = maxdict(50)
-
- def parse(self, s, dpi = 72, prop = None):
- """
- Parse the given math expression *s* at the given *dpi*. If
- *prop* is provided, it is a
- :class:`~matplotlib.font_manager.FontProperties` object
- specifying the "default" font to use in the math expression,
- used for all non-math text.
-
- The results are cached, so multiple calls to :meth:`parse`
- with the same expression should be fast.
- """
- # There is a bug in Python 3.x where it leaks frame references,
- # and therefore can't handle this caching
- if prop is None:
- prop = FontProperties()
-
- cacheKey = (s, dpi, hash(prop))
- result = self._cache.get(cacheKey)
- if result is not None:
- return result
-
- if self._output == 'ps' and rcParams['ps.useafm']:
- font_output = StandardPsFonts(prop)
- else:
- backend = self._backend_mapping[self._output]()
- fontset = rcParams['mathtext.fontset']
- fontset_class = self._font_type_mapping.get(fontset.lower())
- if fontset_class is not None:
- font_output = fontset_class(prop, backend)
- else:
- raise ValueError(
- "mathtext.fontset must be either 'cm', 'dejavuserif', "
- "'dejavusans', 'stix', 'stixsans', or 'custom'")
-
- fontsize = prop.get_size_in_points()
-
- # This is a class variable so we don't rebuild the parser
- # with each request.
- if self._parser is None:
- self.__class__._parser = Parser()
-
- box = self._parser.parse(s, font_output, fontsize, dpi)
- font_output.set_canvas_size(box.width, box.height, box.depth)
- result = font_output.get_results(box)
- self._cache[cacheKey] = result
- return result
-
- def to_mask(self, texstr, dpi=120, fontsize=14):
- """
- *texstr*
- A valid mathtext string, e.g., r'IQ: $\\sigma_i=15$'
-
- *dpi*
- The dots-per-inch to render the text
-
- *fontsize*
- The font size in points
-
- Returns a tuple (*array*, *depth*)
-
- - *array* is an NxM uint8 alpha ubyte mask array of
- rasterized tex.
-
- - depth is the offset of the baseline from the bottom of the
- image in pixels.
- """
- assert self._output == "bitmap"
- prop = FontProperties(size=fontsize)
- ftimage, depth = self.parse(texstr, dpi=dpi, prop=prop)
-
- x = ftimage.as_array()
- return x, depth
-
- def to_rgba(self, texstr, color='black', dpi=120, fontsize=14):
- """
- *texstr*
- A valid mathtext string, e.g., r'IQ: $\\sigma_i=15$'
-
- *color*
- Any matplotlib color argument
-
- *dpi*
- The dots-per-inch to render the text
-
- *fontsize*
- The font size in points
-
- Returns a tuple (*array*, *depth*)
-
- - *array* is an NxM uint8 alpha ubyte mask array of
- rasterized tex.
-
- - depth is the offset of the baseline from the bottom of the
- image in pixels.
- """
- x, depth = self.to_mask(texstr, dpi=dpi, fontsize=fontsize)
-
- r, g, b, a = mcolors.to_rgba(color)
- RGBA = np.zeros((x.shape[0], x.shape[1], 4), dtype=np.uint8)
- RGBA[:, :, 0] = 255 * r
- RGBA[:, :, 1] = 255 * g
- RGBA[:, :, 2] = 255 * b
- RGBA[:, :, 3] = x
- return RGBA, depth
-
- def to_png(self, filename, texstr, color='black', dpi=120, fontsize=14):
- """
- Writes a tex expression to a PNG file.
-
- Returns the offset of the baseline from the bottom of the
- image in pixels.
-
- *filename*
- A writable filename or fileobject
-
- *texstr*
- A valid mathtext string, e.g., r'IQ: $\\sigma_i=15$'
-
- *color*
- A valid matplotlib color argument
-
- *dpi*
- The dots-per-inch to render the text
-
- *fontsize*
- The font size in points
-
- Returns the offset of the baseline from the bottom of the
- image in pixels.
- """
- rgba, depth = self.to_rgba(texstr, color=color, dpi=dpi, fontsize=fontsize)
- _png.write_png(rgba, filename)
- return depth
-
- def get_depth(self, texstr, dpi=120, fontsize=14):
- """
- Returns the offset of the baseline from the bottom of the
- image in pixels.
-
- *texstr*
- A valid mathtext string, e.g., r'IQ: $\\sigma_i=15$'
-
- *dpi*
- The dots-per-inch to render the text
-
- *fontsize*
- The font size in points
- """
- assert self._output=="bitmap"
- prop = FontProperties(size=fontsize)
- ftimage, depth = self.parse(texstr, dpi=dpi, prop=prop)
- return depth
-
-def math_to_image(s, filename_or_obj, prop=None, dpi=None, format=None):
- """
- Given a math expression, renders it in a closely-clipped bounding
- box to an image file.
-
- *s*
- A math expression. The math portion should be enclosed in
- dollar signs.
-
- *filename_or_obj*
- A filepath or writable file-like object to write the image data
- to.
-
- *prop*
- If provided, a FontProperties() object describing the size and
- style of the text.
-
- *dpi*
- Override the output dpi, otherwise use the default associated
- with the output format.
-
- *format*
- The output format, e.g., 'svg', 'pdf', 'ps' or 'png'. If not
- provided, will be deduced from the filename.
- """
- from matplotlib import figure
- # backend_agg supports all of the core output formats
- from matplotlib.backends import backend_agg
-
- if prop is None:
- prop = FontProperties()
-
- parser = MathTextParser('path')
- width, height, depth, _, _ = parser.parse(s, dpi=72, prop=prop)
-
- fig = figure.Figure(figsize=(width / 72.0, height / 72.0))
- fig.text(0, depth/height, s, fontproperties=prop)
- backend_agg.FigureCanvasAgg(fig)
- fig.savefig(filename_or_obj, dpi=dpi, format=format)
-
- return depth
diff --git a/contrib/python/matplotlib/py2/matplotlib/mlab.py b/contrib/python/matplotlib/py2/matplotlib/mlab.py
deleted file mode 100644
index bf4bc52a93..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/mlab.py
+++ /dev/null
@@ -1,4041 +0,0 @@
-"""
-
-Numerical python functions written for compatibility with MATLAB
-commands with the same names.
-
-MATLAB compatible functions
----------------------------
-
-:func:`cohere`
- Coherence (normalized cross spectral density)
-
-:func:`csd`
- Cross spectral density using Welch's average periodogram
-
-:func:`detrend`
- Remove the mean or best fit line from an array
-
-:func:`find`
- Return the indices where some condition is true;
- numpy.nonzero is similar but more general.
-
-:func:`griddata`
- Interpolate irregularly distributed data to a
- regular grid.
-
-:func:`prctile`
- Find the percentiles of a sequence
-
-:func:`prepca`
- Principal Component Analysis
-
-:func:`psd`
- Power spectral density using Welch's average periodogram
-
-:func:`rk4`
- A 4th order runge kutta integrator for 1D or ND systems
-
-:func:`specgram`
- Spectrogram (spectrum over segments of time)
-
-Miscellaneous functions
------------------------
-
-Functions that don't exist in MATLAB, but are useful anyway:
-
-:func:`cohere_pairs`
- Coherence over all pairs. This is not a MATLAB function, but we
- compute coherence a lot in my lab, and we compute it for a lot of
- pairs. This function is optimized to do this efficiently by
- caching the direct FFTs.
-
-:func:`rk4`
- A 4th order Runge-Kutta ODE integrator in case you ever find
- yourself stranded without scipy (and the far superior
- scipy.integrate tools)
-
-:func:`contiguous_regions`
- Return the indices of the regions spanned by some logical mask
-
-:func:`cross_from_below`
- Return the indices where a 1D array crosses a threshold from below
-
-:func:`cross_from_above`
- Return the indices where a 1D array crosses a threshold from above
-
-:func:`complex_spectrum`
- Return the complex-valued frequency spectrum of a signal
-
-:func:`magnitude_spectrum`
- Return the magnitude of the frequency spectrum of a signal
-
-:func:`angle_spectrum`
- Return the angle (wrapped phase) of the frequency spectrum of a signal
-
-:func:`phase_spectrum`
- Return the phase (unwrapped angle) of the frequency spectrum of a signal
-
-:func:`detrend_mean`
- Remove the mean from a line.
-
-:func:`demean`
- Remove the mean from a line. This function is the same as
- :func:`detrend_mean` except for the default *axis*.
-
-:func:`detrend_linear`
- Remove the best fit line from a line.
-
-:func:`detrend_none`
- Return the original line.
-
-:func:`stride_windows`
- Get all windows in an array in a memory-efficient manner
-
-:func:`stride_repeat`
- Repeat an array in a memory-efficient manner
-
-:func:`apply_window`
- Apply a window along a given axis
-
-
-record array helper functions
------------------------------
-
-A collection of helper methods for numpyrecord arrays
-
-.. _htmlonly:
-
- See :ref:`misc-examples-index`
-
-:func:`rec2txt`
- Pretty print a record array
-
-:func:`rec2csv`
- Store record array in CSV file
-
-:func:`csv2rec`
- Import record array from CSV file with type inspection
-
-:func:`rec_append_fields`
- Adds field(s)/array(s) to record array
-
-:func:`rec_drop_fields`
- Drop fields from record array
-
-:func:`rec_join`
- Join two record arrays on sequence of fields
-
-:func:`recs_join`
- A simple join of multiple recarrays using a single column as a key
-
-:func:`rec_groupby`
- Summarize data by groups (similar to SQL GROUP BY)
-
-:func:`rec_summarize`
- Helper code to filter rec array fields into new fields
-
-For the rec viewer functions(e rec2csv), there are a bunch of Format
-objects you can pass into the functions that will do things like color
-negative values red, set percent formatting and scaling, etc.
-
-Example usage::
-
- r = csv2rec('somefile.csv', checkrows=0)
-
- formatd = dict(
- weight = FormatFloat(2),
- change = FormatPercent(2),
- cost = FormatThousands(2),
- )
-
-
- rec2excel(r, 'test.xls', formatd=formatd)
- rec2csv(r, 'test.csv', formatd=formatd)
- scroll = rec2gtk(r, formatd=formatd)
-
- win = gtk.Window()
- win.set_size_request(600,800)
- win.add(scroll)
- win.show_all()
- gtk.main()
-
-
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import map, xrange, zip
-
-import copy
-import csv
-import operator
-import os
-import warnings
-
-import numpy as np
-
-import matplotlib.cbook as cbook
-from matplotlib import docstring
-from matplotlib.path import Path
-import math
-
-
-if six.PY3:
- long = int
-
-
-@cbook.deprecated("2.2", alternative='numpy.logspace or numpy.geomspace')
-def logspace(xmin, xmax, N):
- '''
- Return N values logarithmically spaced between xmin and xmax.
-
- '''
- return np.exp(np.linspace(np.log(xmin), np.log(xmax), N))
-
-
-def window_hanning(x):
- '''
- Return x times the hanning window of len(x).
-
- See Also
- --------
- :func:`window_none`
- :func:`window_none` is another window algorithm.
- '''
- return np.hanning(len(x))*x
-
-
-def window_none(x):
- '''
- No window function; simply return x.
-
- See Also
- --------
- :func:`window_hanning`
- :func:`window_hanning` is another window algorithm.
- '''
- return x
-
-
-def apply_window(x, window, axis=0, return_window=None):
- '''
- Apply the given window to the given 1D or 2D array along the given axis.
-
- Parameters
- ----------
- x : 1D or 2D array or sequence
- Array or sequence containing the data.
-
- window : function or array.
- Either a function to generate a window or an array with length
- *x*.shape[*axis*]
-
- axis : integer
- The axis over which to do the repetition.
- Must be 0 or 1. The default is 0
-
- return_window : bool
- If true, also return the 1D values of the window that was applied
- '''
- x = np.asarray(x)
-
- if x.ndim < 1 or x.ndim > 2:
- raise ValueError('only 1D or 2D arrays can be used')
- if axis+1 > x.ndim:
- raise ValueError('axis(=%s) out of bounds' % axis)
-
- xshape = list(x.shape)
- xshapetarg = xshape.pop(axis)
-
- if cbook.iterable(window):
- if len(window) != xshapetarg:
- raise ValueError('The len(window) must be the same as the shape '
- 'of x for the chosen axis')
- windowVals = window
- else:
- windowVals = window(np.ones(xshapetarg, dtype=x.dtype))
-
- if x.ndim == 1:
- if return_window:
- return windowVals * x, windowVals
- else:
- return windowVals * x
-
- xshapeother = xshape.pop()
-
- otheraxis = (axis+1) % 2
-
- windowValsRep = stride_repeat(windowVals, xshapeother, axis=otheraxis)
-
- if return_window:
- return windowValsRep * x, windowVals
- else:
- return windowValsRep * x
-
-
-def detrend(x, key=None, axis=None):
- '''
- Return x with its trend removed.
-
- Parameters
- ----------
- x : array or sequence
- Array or sequence containing the data.
-
- key : [ 'default' | 'constant' | 'mean' | 'linear' | 'none'] or function
- Specifies the detrend algorithm to use. 'default' is 'mean', which is
- the same as :func:`detrend_mean`. 'constant' is the same. 'linear' is
- the same as :func:`detrend_linear`. 'none' is the same as
- :func:`detrend_none`. The default is 'mean'. See the corresponding
- functions for more details regarding the algorithms. Can also be a
- function that carries out the detrend operation.
-
- axis : integer
- The axis along which to do the detrending.
-
- See Also
- --------
- :func:`detrend_mean`
- :func:`detrend_mean` implements the 'mean' algorithm.
-
- :func:`detrend_linear`
- :func:`detrend_linear` implements the 'linear' algorithm.
-
- :func:`detrend_none`
- :func:`detrend_none` implements the 'none' algorithm.
- '''
- if key is None or key in ['constant', 'mean', 'default']:
- return detrend(x, key=detrend_mean, axis=axis)
- elif key == 'linear':
- return detrend(x, key=detrend_linear, axis=axis)
- elif key == 'none':
- return detrend(x, key=detrend_none, axis=axis)
- elif isinstance(key, six.string_types):
- raise ValueError("Unknown value for key %s, must be one of: "
- "'default', 'constant', 'mean', "
- "'linear', or a function" % key)
-
- if not callable(key):
- raise ValueError("Unknown value for key %s, must be one of: "
- "'default', 'constant', 'mean', "
- "'linear', or a function" % key)
-
- x = np.asarray(x)
-
- if axis is not None and axis+1 > x.ndim:
- raise ValueError('axis(=%s) out of bounds' % axis)
-
- if (axis is None and x.ndim == 0) or (not axis and x.ndim == 1):
- return key(x)
-
- # try to use the 'axis' argument if the function supports it,
- # otherwise use apply_along_axis to do it
- try:
- return key(x, axis=axis)
- except TypeError:
- return np.apply_along_axis(key, axis=axis, arr=x)
-
-
-def demean(x, axis=0):
- '''
- Return x minus its mean along the specified axis.
-
- Parameters
- ----------
- x : array or sequence
- Array or sequence containing the data
- Can have any dimensionality
-
- axis : integer
- The axis along which to take the mean. See numpy.mean for a
- description of this argument.
-
- See Also
- --------
- :func:`delinear`
-
- :func:`denone`
- :func:`delinear` and :func:`denone` are other detrend algorithms.
-
- :func:`detrend_mean`
- This function is the same as :func:`detrend_mean` except for the
- default *axis*.
- '''
- return detrend_mean(x, axis=axis)
-
-
-def detrend_mean(x, axis=None):
- '''
- Return x minus the mean(x).
-
- Parameters
- ----------
- x : array or sequence
- Array or sequence containing the data
- Can have any dimensionality
-
- axis : integer
- The axis along which to take the mean. See numpy.mean for a
- description of this argument.
-
- See Also
- --------
- :func:`demean`
- This function is the same as :func:`demean` except for the default
- *axis*.
-
- :func:`detrend_linear`
-
- :func:`detrend_none`
- :func:`detrend_linear` and :func:`detrend_none` are other detrend
- algorithms.
-
- :func:`detrend`
- :func:`detrend` is a wrapper around all the detrend algorithms.
- '''
- x = np.asarray(x)
-
- if axis is not None and axis+1 > x.ndim:
- raise ValueError('axis(=%s) out of bounds' % axis)
-
- # short-circuit 0-D array.
- if not x.ndim:
- return np.array(0., dtype=x.dtype)
-
- # short-circuit simple operations
- if axis == 0 or axis is None or x.ndim <= 1:
- return x - x.mean(axis)
-
- ind = [slice(None)] * x.ndim
- ind[axis] = np.newaxis
- return x - x.mean(axis)[ind]
-
-
-def detrend_none(x, axis=None):
- '''
- Return x: no detrending.
-
- Parameters
- ----------
- x : any object
- An object containing the data
-
- axis : integer
- This parameter is ignored.
- It is included for compatibility with detrend_mean
-
- See Also
- --------
- :func:`denone`
- This function is the same as :func:`denone` except for the default
- *axis*, which has no effect.
-
- :func:`detrend_mean`
-
- :func:`detrend_linear`
- :func:`detrend_mean` and :func:`detrend_linear` are other detrend
- algorithms.
-
- :func:`detrend`
- :func:`detrend` is a wrapper around all the detrend algorithms.
- '''
- return x
-
-
-def detrend_linear(y):
- '''
- Return x minus best fit line; 'linear' detrending.
-
- Parameters
- ----------
- y : 0-D or 1-D array or sequence
- Array or sequence containing the data
-
- axis : integer
- The axis along which to take the mean. See numpy.mean for a
- description of this argument.
-
- See Also
- --------
- :func:`delinear`
- This function is the same as :func:`delinear` except for the default
- *axis*.
-
- :func:`detrend_mean`
-
- :func:`detrend_none`
- :func:`detrend_mean` and :func:`detrend_none` are other detrend
- algorithms.
-
- :func:`detrend`
- :func:`detrend` is a wrapper around all the detrend algorithms.
- '''
- # This is faster than an algorithm based on linalg.lstsq.
- y = np.asarray(y)
-
- if y.ndim > 1:
- raise ValueError('y cannot have ndim > 1')
-
- # short-circuit 0-D array.
- if not y.ndim:
- return np.array(0., dtype=y.dtype)
-
- x = np.arange(y.size, dtype=float)
-
- C = np.cov(x, y, bias=1)
- b = C[0, 1]/C[0, 0]
-
- a = y.mean() - b*x.mean()
- return y - (b*x + a)
-
-
-def stride_windows(x, n, noverlap=None, axis=0):
- '''
- Get all windows of x with length n as a single array,
- using strides to avoid data duplication.
-
- .. warning::
-
- It is not safe to write to the output array. Multiple
- elements may point to the same piece of memory,
- so modifying one value may change others.
-
- Parameters
- ----------
- x : 1D array or sequence
- Array or sequence containing the data.
-
- n : integer
- The number of data points in each window.
-
- noverlap : integer
- The overlap between adjacent windows.
- Default is 0 (no overlap)
-
- axis : integer
- The axis along which the windows will run.
-
- References
- ----------
- `stackoverflow: Rolling window for 1D arrays in Numpy?
- <http://stackoverflow.com/a/6811241>`_
- `stackoverflow: Using strides for an efficient moving average filter
- <http://stackoverflow.com/a/4947453>`_
- '''
- if noverlap is None:
- noverlap = 0
-
- if noverlap >= n:
- raise ValueError('noverlap must be less than n')
- if n < 1:
- raise ValueError('n cannot be less than 1')
-
- x = np.asarray(x)
-
- if x.ndim != 1:
- raise ValueError('only 1-dimensional arrays can be used')
- if n == 1 and noverlap == 0:
- if axis == 0:
- return x[np.newaxis]
- else:
- return x[np.newaxis].transpose()
- if n > x.size:
- raise ValueError('n cannot be greater than the length of x')
-
- # np.lib.stride_tricks.as_strided easily leads to memory corruption for
- # non integer shape and strides, i.e. noverlap or n. See #3845.
- noverlap = int(noverlap)
- n = int(n)
-
- step = n - noverlap
- if axis == 0:
- shape = (n, (x.shape[-1]-noverlap)//step)
- strides = (x.strides[0], step*x.strides[0])
- else:
- shape = ((x.shape[-1]-noverlap)//step, n)
- strides = (step*x.strides[0], x.strides[0])
- return np.lib.stride_tricks.as_strided(x, shape=shape, strides=strides)
-
-
-def stride_repeat(x, n, axis=0):
- '''
- Repeat the values in an array in a memory-efficient manner. Array x is
- stacked vertically n times.
-
- .. warning::
-
- It is not safe to write to the output array. Multiple
- elements may point to the same piece of memory, so
- modifying one value may change others.
-
- Parameters
- ----------
- x : 1D array or sequence
- Array or sequence containing the data.
-
- n : integer
- The number of time to repeat the array.
-
- axis : integer
- The axis along which the data will run.
-
- References
- ----------
- `stackoverflow: Repeat NumPy array without replicating data?
- <http://stackoverflow.com/a/5568169>`_
- '''
- if axis not in [0, 1]:
- raise ValueError('axis must be 0 or 1')
- x = np.asarray(x)
- if x.ndim != 1:
- raise ValueError('only 1-dimensional arrays can be used')
-
- if n == 1:
- if axis == 0:
- return np.atleast_2d(x)
- else:
- return np.atleast_2d(x).T
- if n < 1:
- raise ValueError('n cannot be less than 1')
-
- # np.lib.stride_tricks.as_strided easily leads to memory corruption for
- # non integer shape and strides, i.e. n. See #3845.
- n = int(n)
-
- if axis == 0:
- shape = (n, x.size)
- strides = (0, x.strides[0])
- else:
- shape = (x.size, n)
- strides = (x.strides[0], 0)
-
- return np.lib.stride_tricks.as_strided(x, shape=shape, strides=strides)
-
-
-def _spectral_helper(x, y=None, NFFT=None, Fs=None, detrend_func=None,
- window=None, noverlap=None, pad_to=None,
- sides=None, scale_by_freq=None, mode=None):
- '''
- This is a helper function that implements the commonality between the
- psd, csd, spectrogram and complex, magnitude, angle, and phase spectrums.
- It is *NOT* meant to be used outside of mlab and may change at any time.
- '''
- if y is None:
- # if y is None use x for y
- same_data = True
- else:
- # The checks for if y is x are so that we can use the same function to
- # implement the core of psd(), csd(), and spectrogram() without doing
- # extra calculations. We return the unaveraged Pxy, freqs, and t.
- same_data = y is x
-
- if Fs is None:
- Fs = 2
- if noverlap is None:
- noverlap = 0
- if detrend_func is None:
- detrend_func = detrend_none
- if window is None:
- window = window_hanning
-
- # if NFFT is set to None use the whole signal
- if NFFT is None:
- NFFT = 256
-
- if mode is None or mode == 'default':
- mode = 'psd'
- elif mode not in ['psd', 'complex', 'magnitude', 'angle', 'phase']:
- raise ValueError("Unknown value for mode %s, must be one of: "
- "'default', 'psd', 'complex', "
- "'magnitude', 'angle', 'phase'" % mode)
-
- if not same_data and mode != 'psd':
- raise ValueError("x and y must be equal if mode is not 'psd'")
-
- # Make sure we're dealing with a numpy array. If y and x were the same
- # object to start with, keep them that way
- x = np.asarray(x)
- if not same_data:
- y = np.asarray(y)
-
- if sides is None or sides == 'default':
- if np.iscomplexobj(x):
- sides = 'twosided'
- else:
- sides = 'onesided'
- elif sides not in ['onesided', 'twosided']:
- raise ValueError("Unknown value for sides %s, must be one of: "
- "'default', 'onesided', or 'twosided'" % sides)
-
- # zero pad x and y up to NFFT if they are shorter than NFFT
- if len(x) < NFFT:
- n = len(x)
- x = np.resize(x, (NFFT,))
- x[n:] = 0
-
- if not same_data and len(y) < NFFT:
- n = len(y)
- y = np.resize(y, (NFFT,))
- y[n:] = 0
-
- if pad_to is None:
- pad_to = NFFT
-
- if mode != 'psd':
- scale_by_freq = False
- elif scale_by_freq is None:
- scale_by_freq = True
-
- # For real x, ignore the negative frequencies unless told otherwise
- if sides == 'twosided':
- numFreqs = pad_to
- if pad_to % 2:
- freqcenter = (pad_to - 1)//2 + 1
- else:
- freqcenter = pad_to//2
- scaling_factor = 1.
- elif sides == 'onesided':
- if pad_to % 2:
- numFreqs = (pad_to + 1)//2
- else:
- numFreqs = pad_to//2 + 1
- scaling_factor = 2.
-
- result = stride_windows(x, NFFT, noverlap, axis=0)
- result = detrend(result, detrend_func, axis=0)
- result, windowVals = apply_window(result, window, axis=0,
- return_window=True)
- result = np.fft.fft(result, n=pad_to, axis=0)[:numFreqs, :]
- freqs = np.fft.fftfreq(pad_to, 1/Fs)[:numFreqs]
-
- if not same_data:
- # if same_data is False, mode must be 'psd'
- resultY = stride_windows(y, NFFT, noverlap)
- resultY = detrend(resultY, detrend_func, axis=0)
- resultY = apply_window(resultY, window, axis=0)
- resultY = np.fft.fft(resultY, n=pad_to, axis=0)[:numFreqs, :]
- result = np.conj(result) * resultY
- elif mode == 'psd':
- result = np.conj(result) * result
- elif mode == 'magnitude':
- result = np.abs(result) / np.abs(windowVals).sum()
- elif mode == 'angle' or mode == 'phase':
- # we unwrap the phase later to handle the onesided vs. twosided case
- result = np.angle(result)
- elif mode == 'complex':
- result /= np.abs(windowVals).sum()
-
- if mode == 'psd':
-
- # Also include scaling factors for one-sided densities and dividing by
- # the sampling frequency, if desired. Scale everything, except the DC
- # component and the NFFT/2 component:
-
- # if we have a even number of frequencies, don't scale NFFT/2
- if not NFFT % 2:
- slc = slice(1, -1, None)
- # if we have an odd number, just don't scale DC
- else:
- slc = slice(1, None, None)
-
- result[slc] *= scaling_factor
-
- # MATLAB divides by the sampling frequency so that density function
- # has units of dB/Hz and can be integrated by the plotted frequency
- # values. Perform the same scaling here.
- if scale_by_freq:
- result /= Fs
- # Scale the spectrum by the norm of the window to compensate for
- # windowing loss; see Bendat & Piersol Sec 11.5.2.
- result /= (np.abs(windowVals)**2).sum()
- else:
- # In this case, preserve power in the segment, not amplitude
- result /= np.abs(windowVals).sum()**2
-
- t = np.arange(NFFT/2, len(x) - NFFT/2 + 1, NFFT - noverlap)/Fs
-
- if sides == 'twosided':
- # center the frequency range at zero
- freqs = np.concatenate((freqs[freqcenter:], freqs[:freqcenter]))
- result = np.concatenate((result[freqcenter:, :],
- result[:freqcenter, :]), 0)
- elif not pad_to % 2:
- # get the last value correctly, it is negative otherwise
- freqs[-1] *= -1
-
- # we unwrap the phase here to handle the onesided vs. twosided case
- if mode == 'phase':
- result = np.unwrap(result, axis=0)
-
- return result, freqs, t
-
-
-def _single_spectrum_helper(x, mode, Fs=None, window=None, pad_to=None,
- sides=None):
- '''
- This is a helper function that implements the commonality between the
- complex, magnitude, angle, and phase spectrums.
- It is *NOT* meant to be used outside of mlab and may change at any time.
- '''
- if mode is None or mode == 'psd' or mode == 'default':
- raise ValueError('_single_spectrum_helper does not work with %s mode'
- % mode)
-
- if pad_to is None:
- pad_to = len(x)
-
- spec, freqs, _ = _spectral_helper(x=x, y=None, NFFT=len(x), Fs=Fs,
- detrend_func=detrend_none, window=window,
- noverlap=0, pad_to=pad_to,
- sides=sides,
- scale_by_freq=False,
- mode=mode)
- if mode != 'complex':
- spec = spec.real
-
- if spec.ndim == 2 and spec.shape[1] == 1:
- spec = spec[:, 0]
-
- return spec, freqs
-
-
-# Split out these keyword docs so that they can be used elsewhere
-docstring.interpd.update(Spectral=cbook.dedent("""
- Fs : scalar
- The sampling frequency (samples per time unit). It is used
- to calculate the Fourier frequencies, freqs, in cycles per time
- unit. The default value is 2.
-
- window : callable or ndarray
- A function or a vector of length *NFFT*. To create window
- vectors see :func:`window_hanning`, :func:`window_none`,
- :func:`numpy.blackman`, :func:`numpy.hamming`,
- :func:`numpy.bartlett`, :func:`scipy.signal`,
- :func:`scipy.signal.get_window`, etc. The default is
- :func:`window_hanning`. If a function is passed as the
- argument, it must take a data segment as an argument and
- return the windowed version of the segment.
-
- sides : [ 'default' | 'onesided' | 'twosided' ]
- Specifies which sides of the spectrum to return. Default gives the
- default behavior, which returns one-sided for real data and both
- for complex data. 'onesided' forces the return of a one-sided
- spectrum, while 'twosided' forces two-sided.
-"""))
-
-
-docstring.interpd.update(Single_Spectrum=cbook.dedent("""
- pad_to : integer
- The number of points to which the data segment is padded when
- performing the FFT. While not increasing the actual resolution of
- the spectrum (the minimum distance between resolvable peaks),
- this can give more points in the plot, allowing for more
- detail. This corresponds to the *n* parameter in the call to fft().
- The default is None, which sets *pad_to* equal to the length of the
- input signal (i.e. no padding).
-"""))
-
-
-docstring.interpd.update(PSD=cbook.dedent("""
- pad_to : integer
- The number of points to which the data segment is padded when
- performing the FFT. This can be different from *NFFT*, which
- specifies the number of data points used. While not increasing
- the actual resolution of the spectrum (the minimum distance between
- resolvable peaks), this can give more points in the plot,
- allowing for more detail. This corresponds to the *n* parameter
- in the call to fft(). The default is None, which sets *pad_to*
- equal to *NFFT*
-
- NFFT : integer
- The number of data points used in each block for the FFT.
- A power 2 is most efficient. The default value is 256.
- This should *NOT* be used to get zero padding, or the scaling of the
- result will be incorrect. Use *pad_to* for this instead.
-
- detrend : {'default', 'constant', 'mean', 'linear', 'none'} or callable
- The function applied to each segment before fft-ing,
- designed to remove the mean or linear trend. Unlike in
- MATLAB, where the *detrend* parameter is a vector, in
- matplotlib is it a function. The :mod:`~matplotlib.pylab`
- module defines :func:`~matplotlib.pylab.detrend_none`,
- :func:`~matplotlib.pylab.detrend_mean`, and
- :func:`~matplotlib.pylab.detrend_linear`, but you can use
- a custom function as well. You can also use a string to choose
- one of the functions. 'default', 'constant', and 'mean' call
- :func:`~matplotlib.pylab.detrend_mean`. 'linear' calls
- :func:`~matplotlib.pylab.detrend_linear`. 'none' calls
- :func:`~matplotlib.pylab.detrend_none`.
-
- scale_by_freq : boolean, optional
- Specifies whether the resulting density values should be scaled
- by the scaling frequency, which gives density in units of Hz^-1.
- This allows for integration over the returned frequency values.
- The default is True for MATLAB compatibility.
-"""))
-
-
-@docstring.dedent_interpd
-def psd(x, NFFT=None, Fs=None, detrend=None, window=None,
- noverlap=None, pad_to=None, sides=None, scale_by_freq=None):
- r"""
- Compute the power spectral density.
-
- Call signature::
-
- psd(x, NFFT=256, Fs=2, detrend=mlab.detrend_none,
- window=mlab.window_hanning, noverlap=0, pad_to=None,
- sides='default', scale_by_freq=None)
-
- The power spectral density :math:`P_{xx}` by Welch's average
- periodogram method. The vector *x* is divided into *NFFT* length
- segments. Each segment is detrended by function *detrend* and
- windowed by function *window*. *noverlap* gives the length of
- the overlap between segments. The :math:`|\mathrm{fft}(i)|^2`
- of each segment :math:`i` are averaged to compute :math:`P_{xx}`.
-
- If len(*x*) < *NFFT*, it will be zero padded to *NFFT*.
-
- Parameters
- ----------
- x : 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(PSD)s
-
- noverlap : integer
- The number of points of overlap between segments.
- The default value is 0 (no overlap).
-
- Returns
- -------
- Pxx : 1-D array
- The values for the power spectrum `P_{xx}` (real valued)
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *Pxx*
-
- References
- ----------
- Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, John
- Wiley & Sons (1986)
-
- See Also
- --------
- :func:`specgram`
- :func:`specgram` differs in the default overlap; in not returning the
- mean of the segment periodograms; and in returning the times of the
- segments.
-
- :func:`magnitude_spectrum`
- :func:`magnitude_spectrum` returns the magnitude spectrum.
-
- :func:`csd`
- :func:`csd` returns the spectral density between two signals.
- """
- Pxx, freqs = csd(x=x, y=None, NFFT=NFFT, Fs=Fs, detrend=detrend,
- window=window, noverlap=noverlap, pad_to=pad_to,
- sides=sides, scale_by_freq=scale_by_freq)
- return Pxx.real, freqs
-
-
-@docstring.dedent_interpd
-def csd(x, y, NFFT=None, Fs=None, detrend=None, window=None,
- noverlap=None, pad_to=None, sides=None, scale_by_freq=None):
- """
- Compute the cross-spectral density.
-
- Call signature::
-
- csd(x, y, NFFT=256, Fs=2, detrend=mlab.detrend_none,
- window=mlab.window_hanning, noverlap=0, pad_to=None,
- sides='default', scale_by_freq=None)
-
- The cross spectral density :math:`P_{xy}` by Welch's average
- periodogram method. The vectors *x* and *y* are divided into
- *NFFT* length segments. Each segment is detrended by function
- *detrend* and windowed by function *window*. *noverlap* gives
- the length of the overlap between segments. The product of
- the direct FFTs of *x* and *y* are averaged over each segment
- to compute :math:`P_{xy}`, with a scaling to correct for power
- loss due to windowing.
-
- If len(*x*) < *NFFT* or len(*y*) < *NFFT*, they will be zero
- padded to *NFFT*.
-
- Parameters
- ----------
- x, y : 1-D arrays or sequences
- Arrays or sequences containing the data
-
- %(Spectral)s
-
- %(PSD)s
-
- noverlap : integer
- The number of points of overlap between segments.
- The default value is 0 (no overlap).
-
- Returns
- -------
- Pxy : 1-D array
- The values for the cross spectrum `P_{xy}` before scaling (real valued)
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *Pxy*
-
- References
- ----------
- Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, John
- Wiley & Sons (1986)
-
- See Also
- --------
- :func:`psd`
- :func:`psd` is the equivalent to setting y=x.
- """
- if NFFT is None:
- NFFT = 256
- Pxy, freqs, _ = _spectral_helper(x=x, y=y, NFFT=NFFT, Fs=Fs,
- detrend_func=detrend, window=window,
- noverlap=noverlap, pad_to=pad_to,
- sides=sides, scale_by_freq=scale_by_freq,
- mode='psd')
-
- if Pxy.ndim == 2:
- if Pxy.shape[1] > 1:
- Pxy = Pxy.mean(axis=1)
- else:
- Pxy = Pxy[:, 0]
- return Pxy, freqs
-
-
-@docstring.dedent_interpd
-def complex_spectrum(x, Fs=None, window=None, pad_to=None,
- sides=None):
- """
- Compute the complex-valued frequency spectrum of *x*. Data is padded to a
- length of *pad_to* and the windowing function *window* is applied to the
- signal.
-
- Parameters
- ----------
- x : 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(Single_Spectrum)s
-
- Returns
- -------
- spectrum : 1-D array
- The values for the complex spectrum (complex valued)
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *spectrum*
-
- See Also
- --------
- :func:`magnitude_spectrum`
- :func:`magnitude_spectrum` returns the absolute value of this function.
-
- :func:`angle_spectrum`
- :func:`angle_spectrum` returns the angle of this function.
-
- :func:`phase_spectrum`
- :func:`phase_spectrum` returns the phase (unwrapped angle) of this
- function.
-
- :func:`specgram`
- :func:`specgram` can return the complex spectrum of segments within the
- signal.
- """
- return _single_spectrum_helper(x=x, Fs=Fs, window=window, pad_to=pad_to,
- sides=sides, mode='complex')
-
-
-@docstring.dedent_interpd
-def magnitude_spectrum(x, Fs=None, window=None, pad_to=None,
- sides=None):
- """
- Compute the magnitude (absolute value) of the frequency spectrum of
- *x*. Data is padded to a length of *pad_to* and the windowing function
- *window* is applied to the signal.
-
- Parameters
- ----------
- x : 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(Single_Spectrum)s
-
- Returns
- -------
- spectrum : 1-D array
- The values for the magnitude spectrum (real valued)
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *spectrum*
-
- See Also
- --------
- :func:`psd`
- :func:`psd` returns the power spectral density.
-
- :func:`complex_spectrum`
- This function returns the absolute value of :func:`complex_spectrum`.
-
- :func:`angle_spectrum`
- :func:`angle_spectrum` returns the angles of the corresponding
- frequencies.
-
- :func:`phase_spectrum`
- :func:`phase_spectrum` returns the phase (unwrapped angle) of the
- corresponding frequencies.
-
- :func:`specgram`
- :func:`specgram` can return the magnitude spectrum of segments within
- the signal.
- """
- return _single_spectrum_helper(x=x, Fs=Fs, window=window, pad_to=pad_to,
- sides=sides, mode='magnitude')
-
-
-@docstring.dedent_interpd
-def angle_spectrum(x, Fs=None, window=None, pad_to=None,
- sides=None):
- """
- Compute the angle of the frequency spectrum (wrapped phase spectrum) of
- *x*. Data is padded to a length of *pad_to* and the windowing function
- *window* is applied to the signal.
-
- Parameters
- ----------
- x : 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(Single_Spectrum)s
-
- Returns
- -------
- spectrum : 1-D array
- The values for the angle spectrum in radians (real valued)
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *spectrum*
-
- See Also
- --------
- :func:`complex_spectrum`
- This function returns the angle value of :func:`complex_spectrum`.
-
- :func:`magnitude_spectrum`
- :func:`angle_spectrum` returns the magnitudes of the corresponding
- frequencies.
-
- :func:`phase_spectrum`
- :func:`phase_spectrum` returns the unwrapped version of this function.
-
- :func:`specgram`
- :func:`specgram` can return the angle spectrum of segments within the
- signal.
- """
- return _single_spectrum_helper(x=x, Fs=Fs, window=window, pad_to=pad_to,
- sides=sides, mode='angle')
-
-
-@docstring.dedent_interpd
-def phase_spectrum(x, Fs=None, window=None, pad_to=None,
- sides=None):
- """
- Compute the phase of the frequency spectrum (unwrapped angle spectrum) of
- *x*. Data is padded to a length of *pad_to* and the windowing function
- *window* is applied to the signal.
-
- Parameters
- ----------
- x : 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(Single_Spectrum)s
-
- Returns
- -------
- spectrum : 1-D array
- The values for the phase spectrum in radians (real valued)
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *spectrum*
-
- See Also
- --------
- :func:`complex_spectrum`
- This function returns the angle value of :func:`complex_spectrum`.
-
- :func:`magnitude_spectrum`
- :func:`magnitude_spectrum` returns the magnitudes of the corresponding
- frequencies.
-
- :func:`angle_spectrum`
- :func:`angle_spectrum` returns the wrapped version of this function.
-
- :func:`specgram`
- :func:`specgram` can return the phase spectrum of segments within the
- signal.
- """
- return _single_spectrum_helper(x=x, Fs=Fs, window=window, pad_to=pad_to,
- sides=sides, mode='phase')
-
-
-@docstring.dedent_interpd
-def specgram(x, NFFT=None, Fs=None, detrend=None, window=None,
- noverlap=None, pad_to=None, sides=None, scale_by_freq=None,
- mode=None):
- """
- Compute a spectrogram.
-
- Compute and plot a spectrogram of data in x. Data are split into
- NFFT length segments and the spectrum of each section is
- computed. The windowing function window is applied to each
- segment, and the amount of overlap of each segment is
- specified with noverlap.
-
- Parameters
- ----------
- x : array_like
- 1-D array or sequence.
-
- %(Spectral)s
-
- %(PSD)s
-
- noverlap : int, optional
- The number of points of overlap between blocks. The default
- value is 128.
- mode : str, optional
- What sort of spectrum to use, default is 'psd'.
- 'psd'
- Returns the power spectral density.
-
- 'complex'
- Returns the complex-valued frequency spectrum.
-
- 'magnitude'
- Returns the magnitude spectrum.
-
- 'angle'
- Returns the phase spectrum without unwrapping.
-
- 'phase'
- Returns the phase spectrum with unwrapping.
-
- Returns
- -------
- spectrum : array_like
- 2-D array, columns are the periodograms of successive segments.
-
- freqs : array_like
- 1-D array, frequencies corresponding to the rows in *spectrum*.
-
- t : array_like
- 1-D array, the times corresponding to midpoints of segments
- (i.e the columns in *spectrum*).
-
- See Also
- --------
- psd : differs in the overlap and in the return values.
- complex_spectrum : similar, but with complex valued frequencies.
- magnitude_spectrum : similar single segment when mode is 'magnitude'.
- angle_spectrum : similar to single segment when mode is 'angle'.
- phase_spectrum : similar to single segment when mode is 'phase'.
-
- Notes
- -----
- detrend and scale_by_freq only apply when *mode* is set to 'psd'.
-
- """
- if noverlap is None:
- noverlap = 128 # default in _spectral_helper() is noverlap = 0
- if NFFT is None:
- NFFT = 256 # same default as in _spectral_helper()
- if len(x) <= NFFT:
- warnings.warn("Only one segment is calculated since parameter NFFT " +
- "(=%d) >= signal length (=%d)." % (NFFT, len(x)))
-
- spec, freqs, t = _spectral_helper(x=x, y=None, NFFT=NFFT, Fs=Fs,
- detrend_func=detrend, window=window,
- noverlap=noverlap, pad_to=pad_to,
- sides=sides,
- scale_by_freq=scale_by_freq,
- mode=mode)
-
- if mode != 'complex':
- spec = spec.real # Needed since helper implements generically
-
- return spec, freqs, t
-
-
-_coh_error = """Coherence is calculated by averaging over *NFFT*
-length segments. Your signal is too short for your choice of *NFFT*.
-"""
-
-
-@docstring.dedent_interpd
-def cohere(x, y, NFFT=256, Fs=2, detrend=detrend_none, window=window_hanning,
- noverlap=0, pad_to=None, sides='default', scale_by_freq=None):
- """
- The coherence between *x* and *y*. Coherence is the normalized
- cross spectral density:
-
- .. math::
-
- C_{xy} = \\frac{|P_{xy}|^2}{P_{xx}P_{yy}}
-
- Parameters
- ----------
- x, y
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(PSD)s
-
- noverlap : integer
- The number of points of overlap between blocks. The default value
- is 0 (no overlap).
-
- Returns
- -------
- The return value is the tuple (*Cxy*, *f*), where *f* are the
- frequencies of the coherence vector. For cohere, scaling the
- individual densities by the sampling frequency has no effect,
- since the factors cancel out.
-
- See Also
- --------
- :func:`psd`, :func:`csd` :
- For information about the methods used to compute :math:`P_{xy}`,
- :math:`P_{xx}` and :math:`P_{yy}`.
- """
-
- if len(x) < 2 * NFFT:
- raise ValueError(_coh_error)
- Pxx, f = psd(x, NFFT, Fs, detrend, window, noverlap, pad_to, sides,
- scale_by_freq)
- Pyy, f = psd(y, NFFT, Fs, detrend, window, noverlap, pad_to, sides,
- scale_by_freq)
- Pxy, f = csd(x, y, NFFT, Fs, detrend, window, noverlap, pad_to, sides,
- scale_by_freq)
- Cxy = np.abs(Pxy) ** 2 / (Pxx * Pyy)
- return Cxy, f
-
-
-@cbook.deprecated('2.2')
-def donothing_callback(*args):
- pass
-
-
-@cbook.deprecated('2.2', 'scipy.signal.coherence')
-def cohere_pairs(X, ij, NFFT=256, Fs=2, detrend=detrend_none,
- window=window_hanning, noverlap=0,
- preferSpeedOverMemory=True,
- progressCallback=donothing_callback,
- returnPxx=False):
-
- """
- Compute the coherence and phase for all pairs *ij*, in *X*.
-
- *X* is a *numSamples* * *numCols* array
-
- *ij* is a list of tuples. Each tuple is a pair of indexes into
- the columns of X for which you want to compute coherence. For
- example, if *X* has 64 columns, and you want to compute all
- nonredundant pairs, define *ij* as::
-
- ij = []
- for i in range(64):
- for j in range(i+1,64):
- ij.append( (i,j) )
-
- *preferSpeedOverMemory* is an optional bool. Defaults to true. If
- False, limits the caching by only making one, rather than two,
- complex cache arrays. This is useful if memory becomes critical.
- Even when *preferSpeedOverMemory* is False, :func:`cohere_pairs`
- will still give significant performance gains over calling
- :func:`cohere` for each pair, and will use subtantially less
- memory than if *preferSpeedOverMemory* is True. In my tests with
- a 43000,64 array over all nonredundant pairs,
- *preferSpeedOverMemory* = True delivered a 33% performance boost
- on a 1.7GHZ Athlon with 512MB RAM compared with
- *preferSpeedOverMemory* = False. But both solutions were more
- than 10x faster than naively crunching all possible pairs through
- :func:`cohere`.
-
- Returns
- -------
- Cxy : dictionary of (*i*, *j*) tuples -> coherence vector for
- that pair. i.e., ``Cxy[(i,j) = cohere(X[:,i], X[:,j])``.
- Number of dictionary keys is ``len(ij)``.
-
- Phase : dictionary of phases of the cross spectral density at
- each frequency for each pair. Keys are (*i*, *j*).
-
- freqs : vector of frequencies, equal in length to either the
- coherence or phase vectors for any (*i*, *j*) key.
-
- e.g., to make a coherence Bode plot::
-
- subplot(211)
- plot( freqs, Cxy[(12,19)])
- subplot(212)
- plot( freqs, Phase[(12,19)])
-
- For a large number of pairs, :func:`cohere_pairs` can be much more
- efficient than just calling :func:`cohere` for each pair, because
- it caches most of the intensive computations. If :math:`N` is the
- number of pairs, this function is :math:`O(N)` for most of the
- heavy lifting, whereas calling cohere for each pair is
- :math:`O(N^2)`. However, because of the caching, it is also more
- memory intensive, making 2 additional complex arrays with
- approximately the same number of elements as *X*.
-
- See :file:`test/cohere_pairs_test.py` in the src tree for an
- example script that shows that this :func:`cohere_pairs` and
- :func:`cohere` give the same results for a given pair.
-
- See Also
- --------
- :func:`psd`
- For information about the methods used to compute :math:`P_{xy}`,
- :math:`P_{xx}` and :math:`P_{yy}`.
- """
- numRows, numCols = X.shape
-
- # zero pad if X is too short
- if numRows < NFFT:
- tmp = X
- X = np.zeros((NFFT, numCols), X.dtype)
- X[:numRows, :] = tmp
- del tmp
-
- numRows, numCols = X.shape
- # get all the columns of X that we are interested in by checking
- # the ij tuples
- allColumns = set()
- for i, j in ij:
- allColumns.add(i)
- allColumns.add(j)
- Ncols = len(allColumns)
-
- # for real X, ignore the negative frequencies
- if np.iscomplexobj(X):
- numFreqs = NFFT
- else:
- numFreqs = NFFT//2+1
-
- # cache the FFT of every windowed, detrended NFFT length segment
- # of every channel. If preferSpeedOverMemory, cache the conjugate
- # as well
- if cbook.iterable(window):
- if len(window) != NFFT:
- raise ValueError("The length of the window must be equal to NFFT")
- windowVals = window
- else:
- windowVals = window(np.ones(NFFT, X.dtype))
- ind = list(xrange(0, numRows-NFFT+1, NFFT-noverlap))
- numSlices = len(ind)
- FFTSlices = {}
- FFTConjSlices = {}
- Pxx = {}
- slices = range(numSlices)
- normVal = np.linalg.norm(windowVals)**2
- for iCol in allColumns:
- progressCallback(i/Ncols, 'Cacheing FFTs')
- Slices = np.zeros((numSlices, numFreqs), dtype=np.complex_)
- for iSlice in slices:
- thisSlice = X[ind[iSlice]:ind[iSlice]+NFFT, iCol]
- thisSlice = windowVals*detrend(thisSlice)
- Slices[iSlice, :] = np.fft.fft(thisSlice)[:numFreqs]
-
- FFTSlices[iCol] = Slices
- if preferSpeedOverMemory:
- FFTConjSlices[iCol] = np.conj(Slices)
- Pxx[iCol] = np.divide(np.mean(abs(Slices)**2, axis=0), normVal)
- del Slices, ind, windowVals
-
- # compute the coherences and phases for all pairs using the
- # cached FFTs
- Cxy = {}
- Phase = {}
- count = 0
- N = len(ij)
- for i, j in ij:
- count += 1
- if count % 10 == 0:
- progressCallback(count/N, 'Computing coherences')
-
- if preferSpeedOverMemory:
- Pxy = FFTSlices[i] * FFTConjSlices[j]
- else:
- Pxy = FFTSlices[i] * np.conj(FFTSlices[j])
- if numSlices > 1:
- Pxy = np.mean(Pxy, axis=0)
-# Pxy = np.divide(Pxy, normVal)
- Pxy /= normVal
-# Cxy[(i,j)] = np.divide(np.absolute(Pxy)**2, Pxx[i]*Pxx[j])
- Cxy[i, j] = abs(Pxy)**2 / (Pxx[i]*Pxx[j])
- Phase[i, j] = np.arctan2(Pxy.imag, Pxy.real)
-
- freqs = Fs/NFFT*np.arange(numFreqs)
- if returnPxx:
- return Cxy, Phase, freqs, Pxx
- else:
- return Cxy, Phase, freqs
-
-
-@cbook.deprecated('2.2', 'scipy.stats.entropy')
-def entropy(y, bins):
- r"""
- Return the entropy of the data in *y* in units of nat.
-
- .. math::
-
- -\sum p_i \ln(p_i)
-
- where :math:`p_i` is the probability of observing *y* in the
- :math:`i^{th}` bin of *bins*. *bins* can be a number of bins or a
- range of bins; see :func:`numpy.histogram`.
-
- Compare *S* with analytic calculation for a Gaussian::
-
- x = mu + sigma * randn(200000)
- Sanalytic = 0.5 * ( 1.0 + log(2*pi*sigma**2.0) )
- """
- n, bins = np.histogram(y, bins)
- n = n.astype(float)
-
- n = np.take(n, np.nonzero(n)[0]) # get the positive
-
- p = np.divide(n, len(y))
-
- delta = bins[1] - bins[0]
- S = -1.0 * np.sum(p * np.log(p)) + np.log(delta)
- return S
-
-
-@cbook.deprecated('2.2', 'scipy.stats.norm.pdf')
-def normpdf(x, *args):
- "Return the normal pdf evaluated at *x*; args provides *mu*, *sigma*"
- mu, sigma = args
- return 1./(np.sqrt(2*np.pi)*sigma)*np.exp(-0.5 * (1./sigma*(x - mu))**2)
-
-
-@cbook.deprecated('2.2')
-def find(condition):
- "Return the indices where ravel(condition) is true"
- res, = np.nonzero(np.ravel(condition))
- return res
-
-
-@cbook.deprecated('2.2')
-def longest_contiguous_ones(x):
- """
- Return the indices of the longest stretch of contiguous ones in *x*,
- assuming *x* is a vector of zeros and ones. If there are two
- equally long stretches, pick the first.
- """
- x = np.ravel(x)
- if len(x) == 0:
- return np.array([])
-
- ind = (x == 0).nonzero()[0]
- if len(ind) == 0:
- return np.arange(len(x))
- if len(ind) == len(x):
- return np.array([])
-
- y = np.zeros((len(x)+2,), x.dtype)
- y[1:-1] = x
- dif = np.diff(y)
- up = (dif == 1).nonzero()[0]
- dn = (dif == -1).nonzero()[0]
- i = (dn-up == max(dn - up)).nonzero()[0][0]
- ind = np.arange(up[i], dn[i])
-
- return ind
-
-
-@cbook.deprecated('2.2')
-def longest_ones(x):
- '''alias for longest_contiguous_ones'''
- return longest_contiguous_ones(x)
-
-
-@cbook.deprecated('2.2')
-class PCA(object):
- def __init__(self, a, standardize=True):
- """
- compute the SVD of a and store data for PCA. Use project to
- project the data onto a reduced set of dimensions
-
- Parameters
- ----------
- a : np.ndarray
- A numobservations x numdims array
- standardize : bool
- True if input data are to be standardized. If False, only centering
- will be carried out.
-
- Attributes
- ----------
- a
- A centered unit sigma version of input ``a``.
-
- numrows, numcols
- The dimensions of ``a``.
-
- mu
- A numdims array of means of ``a``. This is the vector that points
- to the origin of PCA space.
-
- sigma
- A numdims array of standard deviation of ``a``.
-
- fracs
- The proportion of variance of each of the principal components.
-
- s
- The actual eigenvalues of the decomposition.
-
- Wt
- The weight vector for projecting a numdims point or array into
- PCA space.
-
- Y
- A projected into PCA space.
-
- Notes
- -----
- The factor loadings are in the ``Wt`` factor, i.e., the factor loadings
- for the first principal component are given by ``Wt[0]``. This row is
- also the first eigenvector.
-
- """
- n, m = a.shape
- if n < m:
- raise RuntimeError('we assume data in a is organized with '
- 'numrows>numcols')
-
- self.numrows, self.numcols = n, m
- self.mu = a.mean(axis=0)
- self.sigma = a.std(axis=0)
- self.standardize = standardize
-
- a = self.center(a)
-
- self.a = a
-
- U, s, Vh = np.linalg.svd(a, full_matrices=False)
-
- # Note: .H indicates the conjugate transposed / Hermitian.
-
- # The SVD is commonly written as a = U s V.H.
- # If U is a unitary matrix, it means that it satisfies U.H = inv(U).
-
- # The rows of Vh are the eigenvectors of a.H a.
- # The columns of U are the eigenvectors of a a.H.
- # For row i in Vh and column i in U, the corresponding eigenvalue is
- # s[i]**2.
-
- self.Wt = Vh
-
- # save the transposed coordinates
- Y = np.dot(Vh, a.T).T
- self.Y = Y
-
- # save the eigenvalues
- self.s = s**2
-
- # and now the contribution of the individual components
- vars = self.s / len(s)
- self.fracs = vars/vars.sum()
-
- def project(self, x, minfrac=0.):
- '''
- project x onto the principle axes, dropping any axes where fraction
- of variance<minfrac
- '''
- x = np.asarray(x)
- if x.shape[-1] != self.numcols:
- raise ValueError('Expected an array with dims[-1]==%d' %
- self.numcols)
- Y = np.dot(self.Wt, self.center(x).T).T
- mask = self.fracs >= minfrac
- if x.ndim == 2:
- Yreduced = Y[:, mask]
- else:
- Yreduced = Y[mask]
- return Yreduced
-
- def center(self, x):
- '''
- center and optionally standardize the data using the mean and sigma
- from training set a
- '''
- if self.standardize:
- return (x - self.mu)/self.sigma
- else:
- return (x - self.mu)
-
- @staticmethod
- def _get_colinear():
- c0 = np.array([
- 0.19294738, 0.6202667, 0.45962655, 0.07608613, 0.135818,
- 0.83580842, 0.07218851, 0.48318321, 0.84472463, 0.18348462,
- 0.81585306, 0.96923926, 0.12835919, 0.35075355, 0.15807861,
- 0.837437, 0.10824303, 0.1723387, 0.43926494, 0.83705486])
-
- c1 = np.array([
- -1.17705601, -0.513883, -0.26614584, 0.88067144, 1.00474954,
- -1.1616545, 0.0266109, 0.38227157, 1.80489433, 0.21472396,
- -1.41920399, -2.08158544, -0.10559009, 1.68999268, 0.34847107,
- -0.4685737, 1.23980423, -0.14638744, -0.35907697, 0.22442616])
-
- c2 = c0 + 2*c1
- c3 = -3*c0 + 4*c1
- a = np.array([c3, c0, c1, c2]).T
- return a
-
-
-@cbook.deprecated('2.2', 'numpy.percentile')
-def prctile(x, p=(0.0, 25.0, 50.0, 75.0, 100.0)):
- """
- Return the percentiles of *x*. *p* can either be a sequence of
- percentile values or a scalar. If *p* is a sequence, the ith
- element of the return sequence is the *p*(i)-th percentile of *x*.
- If *p* is a scalar, the largest value of *x* less than or equal to
- the *p* percentage point in the sequence is returned.
- """
-
- # This implementation derived from scipy.stats.scoreatpercentile
- def _interpolate(a, b, fraction):
- """Returns the point at the given fraction between a and b, where
- 'fraction' must be between 0 and 1.
- """
- return a + (b - a) * fraction
-
- per = np.array(p)
- values = np.sort(x, axis=None)
-
- idxs = per / 100 * (values.shape[0] - 1)
- ai = idxs.astype(int)
- bi = ai + 1
- frac = idxs % 1
-
- # handle cases where attempting to interpolate past last index
- cond = bi >= len(values)
- if per.ndim:
- ai[cond] -= 1
- bi[cond] -= 1
- frac[cond] += 1
- else:
- if cond:
- ai -= 1
- bi -= 1
- frac += 1
-
- return _interpolate(values[ai], values[bi], frac)
-
-
-@cbook.deprecated('2.2')
-def prctile_rank(x, p):
- """
- Return the rank for each element in *x*, return the rank
- 0..len(*p*). e.g., if *p* = (25, 50, 75), the return value will be a
- len(*x*) array with values in [0,1,2,3] where 0 indicates the
- value is less than the 25th percentile, 1 indicates the value is
- >= the 25th and < 50th percentile, ... and 3 indicates the value
- is above the 75th percentile cutoff.
-
- *p* is either an array of percentiles in [0..100] or a scalar which
- indicates how many quantiles of data you want ranked.
- """
-
- if not cbook.iterable(p):
- p = np.arange(100.0/p, 100.0, 100.0/p)
- else:
- p = np.asarray(p)
-
- if p.max() <= 1 or p.min() < 0 or p.max() > 100:
- raise ValueError('percentiles should be in range 0..100, not 0..1')
-
- ptiles = prctile(x, p)
- return np.searchsorted(ptiles, x)
-
-
-@cbook.deprecated('2.2')
-def center_matrix(M, dim=0):
- """
- Return the matrix *M* with each row having zero mean and unit std.
-
- If *dim* = 1 operate on columns instead of rows. (*dim* is
- opposite to the numpy axis kwarg.)
- """
- M = np.asarray(M, float)
- if dim:
- M = (M - M.mean(axis=0)) / M.std(axis=0)
- else:
- M = (M - M.mean(axis=1)[:, np.newaxis])
- M = M / M.std(axis=1)[:, np.newaxis]
- return M
-
-
-@cbook.deprecated('2.2', 'scipy.integrate.ode')
-def rk4(derivs, y0, t):
- """
- Integrate 1D or ND system of ODEs using 4-th order Runge-Kutta.
- This is a toy implementation which may be useful if you find
- yourself stranded on a system w/o scipy. Otherwise use
- :func:`scipy.integrate`.
-
- Parameters
- ----------
- y0
- initial state vector
-
- t
- sample times
-
- derivs
- returns the derivative of the system and has the
- signature ``dy = derivs(yi, ti)``
-
- Examples
- --------
-
- A 2D system::
-
- def derivs6(x,t):
- d1 = x[0] + 2*x[1]
- d2 = -3*x[0] + 4*x[1]
- return (d1, d2)
- dt = 0.0005
- t = arange(0.0, 2.0, dt)
- y0 = (1,2)
- yout = rk4(derivs6, y0, t)
-
- A 1D system::
-
- alpha = 2
- def derivs(x,t):
- return -alpha*x + exp(-t)
-
- y0 = 1
- yout = rk4(derivs, y0, t)
-
- If you have access to scipy, you should probably be using the
- scipy.integrate tools rather than this function.
- """
-
- try:
- Ny = len(y0)
- except TypeError:
- yout = np.zeros((len(t),), float)
- else:
- yout = np.zeros((len(t), Ny), float)
-
- yout[0] = y0
- i = 0
-
- for i in np.arange(len(t)-1):
-
- thist = t[i]
- dt = t[i+1] - thist
- dt2 = dt/2.0
- y0 = yout[i]
-
- k1 = np.asarray(derivs(y0, thist))
- k2 = np.asarray(derivs(y0 + dt2*k1, thist+dt2))
- k3 = np.asarray(derivs(y0 + dt2*k2, thist+dt2))
- k4 = np.asarray(derivs(y0 + dt*k3, thist+dt))
- yout[i+1] = y0 + dt/6.0*(k1 + 2*k2 + 2*k3 + k4)
- return yout
-
-
-@cbook.deprecated('2.2')
-def bivariate_normal(X, Y, sigmax=1.0, sigmay=1.0,
- mux=0.0, muy=0.0, sigmaxy=0.0):
- """
- Bivariate Gaussian distribution for equal shape *X*, *Y*.
-
- See `bivariate normal
- <http://mathworld.wolfram.com/BivariateNormalDistribution.html>`_
- at mathworld.
- """
- Xmu = X-mux
- Ymu = Y-muy
-
- rho = sigmaxy/(sigmax*sigmay)
- z = Xmu**2/sigmax**2 + Ymu**2/sigmay**2 - 2*rho*Xmu*Ymu/(sigmax*sigmay)
- denom = 2*np.pi*sigmax*sigmay*np.sqrt(1-rho**2)
- return np.exp(-z/(2*(1-rho**2))) / denom
-
-
-@cbook.deprecated('2.2')
-def get_xyz_where(Z, Cond):
- """
- *Z* and *Cond* are *M* x *N* matrices. *Z* are data and *Cond* is
- a boolean matrix where some condition is satisfied. Return value
- is (*x*, *y*, *z*) where *x* and *y* are the indices into *Z* and
- *z* are the values of *Z* at those indices. *x*, *y*, and *z* are
- 1D arrays.
- """
- X, Y = np.indices(Z.shape)
- return X[Cond], Y[Cond], Z[Cond]
-
-
-@cbook.deprecated('2.2')
-def get_sparse_matrix(M, N, frac=0.1):
- """
- Return a *M* x *N* sparse matrix with *frac* elements randomly
- filled.
- """
- data = np.zeros((M, N))*0.
- for i in range(int(M*N*frac)):
- x = np.random.randint(0, M-1)
- y = np.random.randint(0, N-1)
- data[x, y] = np.random.rand()
- return data
-
-
-@cbook.deprecated('2.2', 'numpy.hypot')
-def dist(x, y):
- """
- Return the distance between two points.
- """
- d = x-y
- return np.sqrt(np.dot(d, d))
-
-
-@cbook.deprecated('2.2')
-def dist_point_to_segment(p, s0, s1):
- """
- Get the distance of a point to a segment.
-
- *p*, *s0*, *s1* are *xy* sequences
-
- This algorithm from
- http://geomalgorithms.com/a02-_lines.html
- """
- p = np.asarray(p, float)
- s0 = np.asarray(s0, float)
- s1 = np.asarray(s1, float)
- v = s1 - s0
- w = p - s0
-
- c1 = np.dot(w, v)
- if c1 <= 0:
- return dist(p, s0)
-
- c2 = np.dot(v, v)
- if c2 <= c1:
- return dist(p, s1)
-
- b = c1 / c2
- pb = s0 + b * v
- return dist(p, pb)
-
-
-@cbook.deprecated('2.2')
-def segments_intersect(s1, s2):
- """
- Return *True* if *s1* and *s2* intersect.
- *s1* and *s2* are defined as::
-
- s1: (x1, y1), (x2, y2)
- s2: (x3, y3), (x4, y4)
- """
- (x1, y1), (x2, y2) = s1
- (x3, y3), (x4, y4) = s2
-
- den = ((y4-y3) * (x2-x1)) - ((x4-x3)*(y2-y1))
-
- n1 = ((x4-x3) * (y1-y3)) - ((y4-y3)*(x1-x3))
- n2 = ((x2-x1) * (y1-y3)) - ((y2-y1)*(x1-x3))
-
- if den == 0:
- # lines parallel
- return False
-
- u1 = n1/den
- u2 = n2/den
-
- return 0.0 <= u1 <= 1.0 and 0.0 <= u2 <= 1.0
-
-
-@cbook.deprecated('2.2')
-def fftsurr(x, detrend=detrend_none, window=window_none):
- """
- Compute an FFT phase randomized surrogate of *x*.
- """
- if cbook.iterable(window):
- x = window*detrend(x)
- else:
- x = window(detrend(x))
- z = np.fft.fft(x)
- a = 2.*np.pi*1j
- phase = a * np.random.rand(len(x))
- z = z*np.exp(phase)
- return np.fft.ifft(z).real
-
-
-@cbook.deprecated('2.2')
-def movavg(x, n):
- """
- Compute the len(*n*) moving average of *x*.
- """
- w = np.empty((n,), dtype=float)
- w[:] = 1.0/n
- return np.convolve(x, w, mode='valid')
-
-
-# the following code was written and submitted by Fernando Perez
-# from the ipython numutils package under a BSD license
-# begin fperez functions
-
-"""
-A set of convenient utilities for numerical work.
-
-Most of this module requires numpy or is meant to be used with it.
-
-Copyright (c) 2001-2004, Fernando Perez. <Fernando.Perez@colorado.edu>
-All rights reserved.
-
-This license was generated from the BSD license template as found in:
-http://www.opensource.org/licenses/bsd-license.php
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- * 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.
-
- * Neither the name of the IPython project nor the names of its
- contributors may be used to endorse or promote products derived from
- this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
-
-"""
-
-
-# *****************************************************************************
-# Globals
-# ****************************************************************************
-# function definitions
-exp_safe_MIN = math.log(2.2250738585072014e-308)
-exp_safe_MAX = 1.7976931348623157e+308
-
-
-@cbook.deprecated("2.2", 'numpy.exp')
-def exp_safe(x):
- """
- Compute exponentials which safely underflow to zero.
-
- Slow, but convenient to use. Note that numpy provides proper
- floating point exception handling with access to the underlying
- hardware.
- """
-
- if type(x) is np.ndarray:
- return np.exp(np.clip(x, exp_safe_MIN, exp_safe_MAX))
- else:
- return math.exp(x)
-
-
-@cbook.deprecated("2.2", alternative='numpy.array(list(map(...)))')
-def amap(fn, *args):
- """
- amap(function, sequence[, sequence, ...]) -> array.
-
- Works like :func:`map`, but it returns an array. This is just a
- convenient shorthand for ``numpy.array(map(...))``.
- """
- return np.array(list(map(fn, *args)))
-
-
-@cbook.deprecated("2.2")
-def rms_flat(a):
- """
- Return the root mean square of all the elements of *a*, flattened out.
- """
- return np.sqrt(np.mean(np.abs(a) ** 2))
-
-
-@cbook.deprecated("2.2", alternative='numpy.linalg.norm(a, ord=1)')
-def l1norm(a):
- """
- Return the *l1* norm of *a*, flattened out.
-
- Implemented as a separate function (not a call to :func:`norm` for speed).
- """
- return np.sum(np.abs(a))
-
-
-@cbook.deprecated("2.2", alternative='numpy.linalg.norm(a, ord=2)')
-def l2norm(a):
- """
- Return the *l2* norm of *a*, flattened out.
-
- Implemented as a separate function (not a call to :func:`norm` for speed).
- """
- return np.sqrt(np.sum(np.abs(a) ** 2))
-
-
-@cbook.deprecated("2.2", alternative='numpy.linalg.norm(a.flat, ord=p)')
-def norm_flat(a, p=2):
- """
- norm(a,p=2) -> l-p norm of a.flat
-
- Return the l-p norm of *a*, considered as a flat array. This is NOT a true
- matrix norm, since arrays of arbitrary rank are always flattened.
-
- *p* can be a number or the string 'Infinity' to get the L-infinity norm.
- """
- # This function was being masked by a more general norm later in
- # the file. We may want to simply delete it.
- if p == 'Infinity':
- return np.max(np.abs(a))
- else:
- return np.sum(np.abs(a) ** p) ** (1 / p)
-
-
-@cbook.deprecated("2.2", 'numpy.arange')
-def frange(xini, xfin=None, delta=None, **kw):
- """
- frange([start,] stop[, step, keywords]) -> array of floats
-
- Return a numpy ndarray containing a progression of floats. Similar to
- :func:`numpy.arange`, but defaults to a closed interval.
-
- ``frange(x0, x1)`` returns ``[x0, x0+1, x0+2, ..., x1]``; *start*
- defaults to 0, and the endpoint *is included*. This behavior is
- different from that of :func:`range` and
- :func:`numpy.arange`. This is deliberate, since :func:`frange`
- will probably be more useful for generating lists of points for
- function evaluation, and endpoints are often desired in this
- use. The usual behavior of :func:`range` can be obtained by
- setting the keyword *closed* = 0, in this case, :func:`frange`
- basically becomes :func:numpy.arange`.
-
- When *step* is given, it specifies the increment (or
- decrement). All arguments can be floating point numbers.
-
- ``frange(x0,x1,d)`` returns ``[x0,x0+d,x0+2d,...,xfin]`` where
- *xfin* <= *x1*.
-
- :func:`frange` can also be called with the keyword *npts*. This
- sets the number of points the list should contain (and overrides
- the value *step* might have been given). :func:`numpy.arange`
- doesn't offer this option.
-
- Examples::
-
- >>> frange(3)
- array([ 0., 1., 2., 3.])
- >>> frange(3,closed=0)
- array([ 0., 1., 2.])
- >>> frange(1,6,2)
- array([1, 3, 5]) or 1,3,5,7, depending on floating point vagueries
- >>> frange(1,6.5,npts=5)
- array([ 1. , 2.375, 3.75 , 5.125, 6.5 ])
- """
-
- # defaults
- kw.setdefault('closed', 1)
- endpoint = kw['closed'] != 0
-
- # funny logic to allow the *first* argument to be optional (like range())
- # This was modified with a simpler version from a similar frange() found
- # at http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66472
- if xfin is None:
- xfin = xini + 0.0
- xini = 0.0
-
- if delta is None:
- delta = 1.0
-
- # compute # of points, spacing and return final list
- try:
- npts = kw['npts']
- delta = (xfin-xini) / (npts-endpoint)
- except KeyError:
- npts = int(np.round((xfin-xini)/delta)) + endpoint
- # round finds the nearest, so the endpoint can be up to
- # delta/2 larger than xfin.
-
- return np.arange(npts)*delta+xini
-# end frange()
-
-
-@cbook.deprecated("2.2", 'numpy.identity')
-def identity(n, rank=2, dtype='l', typecode=None):
- """
- Returns the identity matrix of shape (*n*, *n*, ..., *n*) (rank *r*).
-
- For ranks higher than 2, this object is simply a multi-index Kronecker
- delta::
-
- / 1 if i0=i1=...=iR,
- id[i0,i1,...,iR] = -|
- \\ 0 otherwise.
-
- Optionally a *dtype* (or typecode) may be given (it defaults to 'l').
-
- Since rank defaults to 2, this function behaves in the default case (when
- only *n* is given) like ``numpy.identity(n)`` -- but surprisingly, it is
- much faster.
- """
- if typecode is not None:
- dtype = typecode
- iden = np.zeros((n,)*rank, dtype)
- for i in range(n):
- idx = (i,)*rank
- iden[idx] = 1
- return iden
-
-
-@cbook.deprecated("2.2")
-def base_repr(number, base=2, padding=0):
- """
- Return the representation of a *number* in any given *base*.
- """
- chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
- if number < base:
- return (padding - 1) * chars[0] + chars[int(number)]
- max_exponent = int(math.log(number)/math.log(base))
- max_power = long(base) ** max_exponent
- lead_digit = int(number/max_power)
- return (chars[lead_digit] +
- base_repr(number - max_power * lead_digit, base,
- max(padding - 1, max_exponent)))
-
-
-@cbook.deprecated("2.2")
-def binary_repr(number, max_length=1025):
- """
- Return the binary representation of the input *number* as a
- string.
-
- This is more efficient than using :func:`base_repr` with base 2.
-
- Increase the value of max_length for very large numbers. Note that
- on 32-bit machines, 2**1023 is the largest integer power of 2
- which can be converted to a Python float.
- """
-
-# assert number < 2L << max_length
- shifts = map(operator.rshift, max_length * [number],
- range(max_length - 1, -1, -1))
- digits = list(map(operator.mod, shifts, max_length * [2]))
- if not digits.count(1):
- return 0
- digits = digits[digits.index(1):]
- return ''.join(map(repr, digits)).replace('L', '')
-
-
-@cbook.deprecated("2.2", 'numpy.log2')
-def log2(x, ln2=math.log(2.0)):
- """
- Return the log(*x*) in base 2.
-
- This is a _slow_ function but which is guaranteed to return the correct
- integer value if the input is an integer exact power of 2.
- """
- try:
- bin_n = binary_repr(x)[1:]
- except (AssertionError, TypeError):
- return math.log(x)/ln2
- else:
- if '1' in bin_n:
- return math.log(x)/ln2
- else:
- return len(bin_n)
-
-
-@cbook.deprecated("2.2")
-def ispower2(n):
- """
- Returns the log base 2 of *n* if *n* is a power of 2, zero otherwise.
-
- Note the potential ambiguity if *n* == 1: 2**0 == 1, interpret accordingly.
- """
-
- bin_n = binary_repr(n)[1:]
- if '1' in bin_n:
- return 0
- else:
- return len(bin_n)
-
-
-@cbook.deprecated("2.2")
-def isvector(X):
- """
- Like the MATLAB function with the same name, returns *True*
- if the supplied numpy array or matrix *X* looks like a vector,
- meaning it has a one non-singleton axis (i.e., it can have
- multiple axes, but all must have length 1, except for one of
- them).
-
- If you just want to see if the array has 1 axis, use X.ndim == 1.
- """
- return np.prod(X.shape) == np.max(X.shape)
-
-# end fperez numutils code
-
-
-# helpers for loading, saving, manipulating and viewing numpy record arrays
-@cbook.deprecated("2.2", 'numpy.isnan')
-def safe_isnan(x):
- ':func:`numpy.isnan` for arbitrary types'
- if isinstance(x, six.string_types):
- return False
- try:
- b = np.isnan(x)
- except NotImplementedError:
- return False
- except TypeError:
- return False
- else:
- return b
-
-
-@cbook.deprecated("2.2", 'numpy.isinf')
-def safe_isinf(x):
- ':func:`numpy.isinf` for arbitrary types'
- if isinstance(x, six.string_types):
- return False
- try:
- b = np.isinf(x)
- except NotImplementedError:
- return False
- except TypeError:
- return False
- else:
- return b
-
-
-@cbook.deprecated("2.2")
-def rec_append_fields(rec, names, arrs, dtypes=None):
- """
- Return a new record array with field names populated with data
- from arrays in *arrs*. If appending a single field, then *names*,
- *arrs* and *dtypes* do not have to be lists. They can just be the
- values themselves.
- """
- if (not isinstance(names, six.string_types) and cbook.iterable(names)
- and len(names) and isinstance(names[0], six.string_types)):
- if len(names) != len(arrs):
- raise ValueError("number of arrays do not match number of names")
- else: # we have only 1 name and 1 array
- names = [names]
- arrs = [arrs]
- arrs = list(map(np.asarray, arrs))
- if dtypes is None:
- dtypes = [a.dtype for a in arrs]
- elif not cbook.iterable(dtypes):
- dtypes = [dtypes]
- if len(arrs) != len(dtypes):
- if len(dtypes) == 1:
- dtypes = dtypes * len(arrs)
- else:
- raise ValueError("dtypes must be None, a single dtype or a list")
- old_dtypes = rec.dtype.descr
- if six.PY2:
- old_dtypes = [(name.encode('utf-8'), dt) for name, dt in old_dtypes]
- newdtype = np.dtype(old_dtypes + list(zip(names, dtypes)))
- newrec = np.recarray(rec.shape, dtype=newdtype)
- for field in rec.dtype.fields:
- newrec[field] = rec[field]
- for name, arr in zip(names, arrs):
- newrec[name] = arr
- return newrec
-
-
-@cbook.deprecated("2.2")
-def rec_drop_fields(rec, names):
- """
- Return a new numpy record array with fields in *names* dropped.
- """
-
- names = set(names)
-
- newdtype = np.dtype([(name, rec.dtype[name]) for name in rec.dtype.names
- if name not in names])
-
- newrec = np.recarray(rec.shape, dtype=newdtype)
- for field in newdtype.names:
- newrec[field] = rec[field]
-
- return newrec
-
-
-@cbook.deprecated("2.2")
-def rec_keep_fields(rec, names):
- """
- Return a new numpy record array with only fields listed in names
- """
-
- if isinstance(names, six.string_types):
- names = names.split(',')
-
- arrays = []
- for name in names:
- arrays.append(rec[name])
-
- return np.rec.fromarrays(arrays, names=names)
-
-
-@cbook.deprecated("2.2")
-def rec_groupby(r, groupby, stats):
- """
- *r* is a numpy record array
-
- *groupby* is a sequence of record array attribute names that
- together form the grouping key. e.g., ('date', 'productcode')
-
- *stats* is a sequence of (*attr*, *func*, *outname*) tuples which
- will call ``x = func(attr)`` and assign *x* to the record array
- output with attribute *outname*. For example::
-
- stats = ( ('sales', len, 'numsales'), ('sales', np.mean, 'avgsale') )
-
- Return record array has *dtype* names for each attribute name in
- the *groupby* argument, with the associated group values, and
- for each outname name in the *stats* argument, with the associated
- stat summary output.
- """
- # build a dictionary from groupby keys-> list of indices into r with
- # those keys
- rowd = {}
- for i, row in enumerate(r):
- key = tuple([row[attr] for attr in groupby])
- rowd.setdefault(key, []).append(i)
-
- rows = []
- # sort the output by groupby keys
- for key in sorted(rowd):
- row = list(key)
- # get the indices for this groupby key
- ind = rowd[key]
- thisr = r[ind]
- # call each stat function for this groupby slice
- row.extend([func(thisr[attr]) for attr, func, outname in stats])
- rows.append(row)
-
- # build the output record array with groupby and outname attributes
- attrs, funcs, outnames = list(zip(*stats))
- names = list(groupby)
- names.extend(outnames)
- return np.rec.fromrecords(rows, names=names)
-
-
-@cbook.deprecated("2.2")
-def rec_summarize(r, summaryfuncs):
- """
- *r* is a numpy record array
-
- *summaryfuncs* is a list of (*attr*, *func*, *outname*) tuples
- which will apply *func* to the array *r*[attr] and assign the
- output to a new attribute name *outname*. The returned record
- array is identical to *r*, with extra arrays for each element in
- *summaryfuncs*.
-
- """
-
- names = list(r.dtype.names)
- arrays = [r[name] for name in names]
-
- for attr, func, outname in summaryfuncs:
- names.append(outname)
- arrays.append(np.asarray(func(r[attr])))
-
- return np.rec.fromarrays(arrays, names=names)
-
-
-@cbook.deprecated("2.2")
-def rec_join(key, r1, r2, jointype='inner', defaults=None, r1postfix='1',
- r2postfix='2'):
- """
- Join record arrays *r1* and *r2* on *key*; *key* is a tuple of
- field names -- if *key* is a string it is assumed to be a single
- attribute name. If *r1* and *r2* have equal values on all the keys
- in the *key* tuple, then their fields will be merged into a new
- record array containing the intersection of the fields of *r1* and
- *r2*.
-
- *r1* (also *r2*) must not have any duplicate keys.
-
- The *jointype* keyword can be 'inner', 'outer', 'leftouter'. To
- do a rightouter join just reverse *r1* and *r2*.
-
- The *defaults* keyword is a dictionary filled with
- ``{column_name:default_value}`` pairs.
-
- The keywords *r1postfix* and *r2postfix* are postfixed to column names
- (other than keys) that are both in *r1* and *r2*.
- """
-
- if isinstance(key, six.string_types):
- key = (key, )
-
- for name in key:
- if name not in r1.dtype.names:
- raise ValueError('r1 does not have key field %s' % name)
- if name not in r2.dtype.names:
- raise ValueError('r2 does not have key field %s' % name)
-
- def makekey(row):
- return tuple([row[name] for name in key])
-
- r1d = {makekey(row): i for i, row in enumerate(r1)}
- r2d = {makekey(row): i for i, row in enumerate(r2)}
-
- r1keys = set(r1d)
- r2keys = set(r2d)
-
- common_keys = r1keys & r2keys
-
- r1ind = np.array([r1d[k] for k in common_keys])
- r2ind = np.array([r2d[k] for k in common_keys])
-
- common_len = len(common_keys)
- left_len = right_len = 0
- if jointype == "outer" or jointype == "leftouter":
- left_keys = r1keys.difference(r2keys)
- left_ind = np.array([r1d[k] for k in left_keys])
- left_len = len(left_ind)
- if jointype == "outer":
- right_keys = r2keys.difference(r1keys)
- right_ind = np.array([r2d[k] for k in right_keys])
- right_len = len(right_ind)
-
- def key_desc(name):
- '''
- if name is a string key, use the larger size of r1 or r2 before
- merging
- '''
- dt1 = r1.dtype[name]
- if dt1.type != np.string_:
- return (name, dt1.descr[0][1])
-
- dt2 = r2.dtype[name]
- if dt1 != dt2:
- raise ValueError("The '{}' fields in arrays 'r1' and 'r2' must "
- "have the same dtype".format(name))
- if dt1.num > dt2.num:
- return (name, dt1.descr[0][1])
- else:
- return (name, dt2.descr[0][1])
-
- keydesc = [key_desc(name) for name in key]
-
- def mapped_r1field(name):
- """
- The column name in *newrec* that corresponds to the column in *r1*.
- """
- if name in key or name not in r2.dtype.names:
- return name
- else:
- return name + r1postfix
-
- def mapped_r2field(name):
- """
- The column name in *newrec* that corresponds to the column in *r2*.
- """
- if name in key or name not in r1.dtype.names:
- return name
- else:
- return name + r2postfix
-
- r1desc = [(mapped_r1field(desc[0]), desc[1]) for desc in r1.dtype.descr
- if desc[0] not in key]
- r2desc = [(mapped_r2field(desc[0]), desc[1]) for desc in r2.dtype.descr
- if desc[0] not in key]
- all_dtypes = keydesc + r1desc + r2desc
- if six.PY2:
- all_dtypes = [(name.encode('utf-8'), dt) for name, dt in all_dtypes]
- newdtype = np.dtype(all_dtypes)
- newrec = np.recarray((common_len + left_len + right_len,), dtype=newdtype)
-
- if defaults is not None:
- for thiskey in defaults:
- if thiskey not in newdtype.names:
- warnings.warn('rec_join defaults key="%s" not in new dtype '
- 'names "%s"' % (thiskey, newdtype.names))
-
- for name in newdtype.names:
- dt = newdtype[name]
- if dt.kind in ('f', 'i'):
- newrec[name] = 0
-
- if jointype != 'inner' and defaults is not None:
- # fill in the defaults enmasse
- newrec_fields = list(newrec.dtype.fields)
- for k, v in six.iteritems(defaults):
- if k in newrec_fields:
- newrec[k] = v
-
- for field in r1.dtype.names:
- newfield = mapped_r1field(field)
- if common_len:
- newrec[newfield][:common_len] = r1[field][r1ind]
- if (jointype == "outer" or jointype == "leftouter") and left_len:
- newrec[newfield][common_len:(common_len+left_len)] = (
- r1[field][left_ind]
- )
-
- for field in r2.dtype.names:
- newfield = mapped_r2field(field)
- if field not in key and common_len:
- newrec[newfield][:common_len] = r2[field][r2ind]
- if jointype == "outer" and right_len:
- newrec[newfield][-right_len:] = r2[field][right_ind]
-
- newrec.sort(order=key)
-
- return newrec
-
-
-@cbook.deprecated("2.2")
-def recs_join(key, name, recs, jointype='outer', missing=0., postfixes=None):
- """
- Join a sequence of record arrays on single column key.
-
- This function only joins a single column of the multiple record arrays
-
- *key*
- is the column name that acts as a key
-
- *name*
- is the name of the column that we want to join
-
- *recs*
- is a list of record arrays to join
-
- *jointype*
- is a string 'inner' or 'outer'
-
- *missing*
- is what any missing field is replaced by
-
- *postfixes*
- if not None, a len recs sequence of postfixes
-
- returns a record array with columns [rowkey, name0, name1, ... namen-1].
- or if postfixes [PF0, PF1, ..., PFN-1] are supplied,
- [rowkey, namePF0, namePF1, ... namePFN-1].
-
- Example::
-
- r = recs_join("date", "close", recs=[r0, r1], missing=0.)
-
- """
- results = []
- aligned_iters = cbook.align_iterators(operator.attrgetter(key),
- *[iter(r) for r in recs])
-
- def extract(r):
- if r is None:
- return missing
- else:
- return r[name]
-
- if jointype == "outer":
- for rowkey, row in aligned_iters:
- results.append([rowkey] + list(map(extract, row)))
- elif jointype == "inner":
- for rowkey, row in aligned_iters:
- if None not in row: # throw out any Nones
- results.append([rowkey] + list(map(extract, row)))
-
- if postfixes is None:
- postfixes = ['%d' % i for i in range(len(recs))]
- names = ",".join([key] + ["%s%s" % (name, postfix)
- for postfix in postfixes])
- return np.rec.fromrecords(results, names=names)
-
-
-@cbook.deprecated("2.2")
-def csv2rec(fname, comments='#', skiprows=0, checkrows=0, delimiter=',',
- converterd=None, names=None, missing='', missingd=None,
- use_mrecords=False, dayfirst=False, yearfirst=False):
- """
- Load data from comma/space/tab delimited file in *fname* into a
- numpy record array and return the record array.
-
- If *names* is *None*, a header row is required to automatically
- assign the recarray names. The headers will be lower cased,
- spaces will be converted to underscores, and illegal attribute
- name characters removed. If *names* is not *None*, it is a
- sequence of names to use for the column names. In this case, it
- is assumed there is no header row.
-
-
- - *fname*: can be a filename or a file handle. Support for gzipped
- files is automatic, if the filename ends in '.gz'
-
- - *comments*: the character used to indicate the start of a comment
- in the file, or *None* to switch off the removal of comments
-
- - *skiprows*: is the number of rows from the top to skip
-
- - *checkrows*: is the number of rows to check to validate the column
- data type. When set to zero all rows are validated.
-
- - *converterd*: if not *None*, is a dictionary mapping column number or
- munged column name to a converter function.
-
- - *names*: if not None, is a list of header names. In this case, no
- header will be read from the file
-
- - *missingd* is a dictionary mapping munged column names to field values
- which signify that the field does not contain actual data and should
- be masked, e.g., '0000-00-00' or 'unused'
-
- - *missing*: a string whose value signals a missing field regardless of
- the column it appears in
-
- - *use_mrecords*: if True, return an mrecords.fromrecords record array if
- any of the data are missing
-
- - *dayfirst*: default is False so that MM-DD-YY has precedence over
- DD-MM-YY. See
- http://labix.org/python-dateutil#head-b95ce2094d189a89f80f5ae52a05b4ab7b41af47
- for further information.
-
- - *yearfirst*: default is False so that MM-DD-YY has precedence over
- YY-MM-DD. See
- http://labix.org/python-dateutil#head-b95ce2094d189a89f80f5ae52a05b4ab7b41af47
- for further information.
-
- If no rows are found, *None* is returned
- """
-
- if converterd is None:
- converterd = dict()
-
- if missingd is None:
- missingd = {}
-
- import dateutil.parser
- import datetime
-
- fh = cbook.to_filehandle(fname)
-
- delimiter = str(delimiter)
-
- class FH:
- """
- For space-delimited files, we want different behavior than
- comma or tab. Generally, we want multiple spaces to be
- treated as a single separator, whereas with comma and tab we
- want multiple commas to return multiple (empty) fields. The
- join/strip trick below effects this.
- """
- def __init__(self, fh):
- self.fh = fh
-
- def close(self):
- self.fh.close()
-
- def seek(self, arg):
- self.fh.seek(arg)
-
- def fix(self, s):
- return ' '.join(s.split())
-
- def __next__(self):
- return self.fix(next(self.fh))
-
- def __iter__(self):
- for line in self.fh:
- yield self.fix(line)
-
- if delimiter == ' ':
- fh = FH(fh)
-
- reader = csv.reader(fh, delimiter=delimiter)
-
- def process_skiprows(reader):
- if skiprows:
- for i, row in enumerate(reader):
- if i >= (skiprows-1):
- break
-
- return fh, reader
-
- process_skiprows(reader)
-
- def ismissing(name, val):
- "Should the value val in column name be masked?"
- return val == missing or val == missingd.get(name) or val == ''
-
- def with_default_value(func, default):
- def newfunc(name, val):
- if ismissing(name, val):
- return default
- else:
- return func(val)
- return newfunc
-
- def mybool(x):
- if x == 'True':
- return True
- elif x == 'False':
- return False
- else:
- raise ValueError('invalid bool')
-
- dateparser = dateutil.parser.parse
-
- def mydateparser(x):
- # try and return a datetime object
- d = dateparser(x, dayfirst=dayfirst, yearfirst=yearfirst)
- return d
-
- mydateparser = with_default_value(mydateparser, datetime.datetime(1, 1, 1))
-
- myfloat = with_default_value(float, np.nan)
- myint = with_default_value(int, -1)
- mystr = with_default_value(str, '')
- mybool = with_default_value(mybool, None)
-
- def mydate(x):
- # try and return a date object
- d = dateparser(x, dayfirst=dayfirst, yearfirst=yearfirst)
-
- if d.hour > 0 or d.minute > 0 or d.second > 0:
- raise ValueError('not a date')
- return d.date()
- mydate = with_default_value(mydate, datetime.date(1, 1, 1))
-
- def get_func(name, item, func):
- # promote functions in this order
- funcs = [mybool, myint, myfloat, mydate, mydateparser, mystr]
- for func in funcs[funcs.index(func):]:
- try:
- func(name, item)
- except Exception:
- continue
- return func
- raise ValueError('Could not find a working conversion function')
-
- # map column names that clash with builtins -- TODO - extend this list
- itemd = {
- 'return': 'return_',
- 'file': 'file_',
- 'print': 'print_',
- }
-
- def get_converters(reader, comments):
-
- converters = None
- i = 0
- for row in reader:
- if (len(row) and comments is not None and
- row[0].startswith(comments)):
- continue
- if i == 0:
- converters = [mybool]*len(row)
- if checkrows and i > checkrows:
- break
- i += 1
-
- for j, (name, item) in enumerate(zip(names, row)):
- func = converterd.get(j)
- if func is None:
- func = converterd.get(name)
- if func is None:
- func = converters[j]
- if len(item.strip()):
- func = get_func(name, item, func)
- else:
- # how should we handle custom converters and defaults?
- func = with_default_value(func, None)
- converters[j] = func
- return converters
-
- # Get header and remove invalid characters
- needheader = names is None
-
- if needheader:
- for row in reader:
- if (len(row) and comments is not None and
- row[0].startswith(comments)):
- continue
- headers = row
- break
-
- # remove these chars
- delete = set(r"""~!@#$%^&*()-=+~\|}[]{';: /?.>,<""")
- delete.add('"')
-
- names = []
- seen = dict()
- for i, item in enumerate(headers):
- item = item.strip().lower().replace(' ', '_')
- item = ''.join([c for c in item if c not in delete])
- if not len(item):
- item = 'column%d' % i
-
- item = itemd.get(item, item)
- cnt = seen.get(item, 0)
- if cnt > 0:
- names.append(item + '_%d' % cnt)
- else:
- names.append(item)
- seen[item] = cnt+1
-
- else:
- if isinstance(names, six.string_types):
- names = [n.strip() for n in names.split(',')]
-
- # get the converter functions by inspecting checkrows
- converters = get_converters(reader, comments)
- if converters is None:
- raise ValueError('Could not find any valid data in CSV file')
-
- # reset the reader and start over
- fh.seek(0)
- reader = csv.reader(fh, delimiter=delimiter)
- process_skiprows(reader)
-
- if needheader:
- while True:
- # skip past any comments and consume one line of column header
- row = next(reader)
- if (len(row) and comments is not None and
- row[0].startswith(comments)):
- continue
- break
-
- # iterate over the remaining rows and convert the data to date
- # objects, ints, or floats as appropriate
- rows = []
- rowmasks = []
- for i, row in enumerate(reader):
- if not len(row):
- continue
- if comments is not None and row[0].startswith(comments):
- continue
- # Ensure that the row returned always has the same nr of elements
- row.extend([''] * (len(converters) - len(row)))
- rows.append([func(name, val)
- for func, name, val in zip(converters, names, row)])
- rowmasks.append([ismissing(name, val)
- for name, val in zip(names, row)])
- fh.close()
-
- if not len(rows):
- return None
-
- if use_mrecords and np.any(rowmasks):
- r = np.ma.mrecords.fromrecords(rows, names=names, mask=rowmasks)
- else:
- r = np.rec.fromrecords(rows, names=names)
- return r
-
-
-# a series of classes for describing the format intentions of various rec views
-@cbook.deprecated("2.2")
-class FormatObj(object):
- def tostr(self, x):
- return self.toval(x)
-
- def toval(self, x):
- return str(x)
-
- def fromstr(self, s):
- return s
-
- def __hash__(self):
- """
- override the hash function of any of the formatters, so that we don't
- create duplicate excel format styles
- """
- return hash(self.__class__)
-
-
-@cbook.deprecated("2.2")
-class FormatString(FormatObj):
- def tostr(self, x):
- val = repr(x)
- return val[1:-1]
-
-
-@cbook.deprecated("2.2")
-class FormatFormatStr(FormatObj):
- def __init__(self, fmt):
- self.fmt = fmt
-
- def tostr(self, x):
- if x is None:
- return 'None'
- return self.fmt % self.toval(x)
-
-
-@cbook.deprecated("2.2")
-class FormatFloat(FormatFormatStr):
- def __init__(self, precision=4, scale=1.):
- FormatFormatStr.__init__(self, '%%1.%df' % precision)
- self.precision = precision
- self.scale = scale
-
- def __hash__(self):
- return hash((self.__class__, self.precision, self.scale))
-
- def toval(self, x):
- if x is not None:
- x = x * self.scale
- return x
-
- def fromstr(self, s):
- return float(s)/self.scale
-
-
-@cbook.deprecated("2.2")
-class FormatInt(FormatObj):
-
- def tostr(self, x):
- return '%d' % int(x)
-
- def toval(self, x):
- return int(x)
-
- def fromstr(self, s):
- return int(s)
-
-
-@cbook.deprecated("2.2")
-class FormatBool(FormatObj):
- def toval(self, x):
- return str(x)
-
- def fromstr(self, s):
- return bool(s)
-
-
-@cbook.deprecated("2.2")
-class FormatPercent(FormatFloat):
- def __init__(self, precision=4):
- FormatFloat.__init__(self, precision, scale=100.)
-
-
-@cbook.deprecated("2.2")
-class FormatThousands(FormatFloat):
- def __init__(self, precision=4):
- FormatFloat.__init__(self, precision, scale=1e-3)
-
-
-@cbook.deprecated("2.2")
-class FormatMillions(FormatFloat):
- def __init__(self, precision=4):
- FormatFloat.__init__(self, precision, scale=1e-6)
-
-
-@cbook.deprecated("2.2", alternative='date.strftime')
-class FormatDate(FormatObj):
- def __init__(self, fmt):
- self.fmt = fmt
-
- def __hash__(self):
- return hash((self.__class__, self.fmt))
-
- def toval(self, x):
- if x is None:
- return 'None'
- return x.strftime(self.fmt)
-
- def fromstr(self, x):
- import dateutil.parser
- return dateutil.parser.parse(x).date()
-
-
-@cbook.deprecated("2.2", alternative='datetime.strftime')
-class FormatDatetime(FormatDate):
- def __init__(self, fmt='%Y-%m-%d %H:%M:%S'):
- FormatDate.__init__(self, fmt)
-
- def fromstr(self, x):
- import dateutil.parser
- return dateutil.parser.parse(x)
-
-
-@cbook.deprecated("2.2")
-def get_formatd(r, formatd=None):
- 'build a formatd guaranteed to have a key for every dtype name'
- defaultformatd = {
- np.bool_: FormatBool(),
- np.int16: FormatInt(),
- np.int32: FormatInt(),
- np.int64: FormatInt(),
- np.float32: FormatFloat(),
- np.float64: FormatFloat(),
- np.object_: FormatObj(),
- np.string_: FormatString()}
-
- if formatd is None:
- formatd = dict()
-
- for i, name in enumerate(r.dtype.names):
- dt = r.dtype[name]
- format = formatd.get(name)
- if format is None:
- format = defaultformatd.get(dt.type, FormatObj())
- formatd[name] = format
- return formatd
-
-
-@cbook.deprecated("2.2")
-def csvformat_factory(format):
- format = copy.deepcopy(format)
- if isinstance(format, FormatFloat):
- format.scale = 1. # override scaling for storage
- format.fmt = '%r'
- return format
-
-
-@cbook.deprecated("2.2", alternative='numpy.recarray.tofile')
-def rec2txt(r, header=None, padding=3, precision=3, fields=None):
- """
- Returns a textual representation of a record array.
-
- Parameters
- ----------
- r: numpy recarray
-
- header: list
- column headers
-
- padding:
- space between each column
-
- precision: number of decimal places to use for floats.
- Set to an integer to apply to all floats. Set to a
- list of integers to apply precision individually.
- Precision for non-floats is simply ignored.
-
- fields : list
- If not None, a list of field names to print. fields
- can be a list of strings like ['field1', 'field2'] or a single
- comma separated string like 'field1,field2'
-
- Examples
- --------
-
- For ``precision=[0,2,3]``, the output is ::
-
- ID Price Return
- ABC 12.54 0.234
- XYZ 6.32 -0.076
- """
-
- if fields is not None:
- r = rec_keep_fields(r, fields)
-
- if cbook.is_numlike(precision):
- precision = [precision]*len(r.dtype)
-
- def get_type(item, atype=int):
- tdict = {None: int, int: float, float: str}
- try:
- atype(str(item))
- except:
- return get_type(item, tdict[atype])
- return atype
-
- def get_justify(colname, column, precision):
- ntype = column.dtype
-
- if np.issubdtype(ntype, np.character):
- fixed_width = int(ntype.str[2:])
- length = max(len(colname), fixed_width)
- return 0, length+padding, "%s" # left justify
-
- if np.issubdtype(ntype, np.integer):
- length = max(len(colname),
- np.max(list(map(len, list(map(str, column))))))
- return 1, length+padding, "%d" # right justify
-
- if np.issubdtype(ntype, np.floating):
- fmt = "%." + str(precision) + "f"
- length = max(
- len(colname),
- np.max(list(map(len, list(map(lambda x: fmt % x, column)))))
- )
- return 1, length+padding, fmt # right justify
-
- return (0,
- max(len(colname),
- np.max(list(map(len, list(map(str, column))))))+padding,
- "%s")
-
- if header is None:
- header = r.dtype.names
-
- justify_pad_prec = [get_justify(header[i], r.__getitem__(colname),
- precision[i])
- for i, colname in enumerate(r.dtype.names)]
-
- justify_pad_prec_spacer = []
- for i in range(len(justify_pad_prec)):
- just, pad, prec = justify_pad_prec[i]
- if i == 0:
- justify_pad_prec_spacer.append((just, pad, prec, 0))
- else:
- pjust, ppad, pprec = justify_pad_prec[i-1]
- if pjust == 0 and just == 1:
- justify_pad_prec_spacer.append((just, pad-padding, prec, 0))
- elif pjust == 1 and just == 0:
- justify_pad_prec_spacer.append((just, pad, prec, padding))
- else:
- justify_pad_prec_spacer.append((just, pad, prec, 0))
-
- def format(item, just_pad_prec_spacer):
- just, pad, prec, spacer = just_pad_prec_spacer
- if just == 0:
- return spacer*' ' + str(item).ljust(pad)
- else:
- if get_type(item) == float:
- item = (prec % float(item))
- elif get_type(item) == int:
- item = (prec % int(item))
-
- return item.rjust(pad)
-
- textl = []
- textl.append(''.join([format(colitem, justify_pad_prec_spacer[j])
- for j, colitem in enumerate(header)]))
- for i, row in enumerate(r):
- textl.append(''.join([format(colitem, justify_pad_prec_spacer[j])
- for j, colitem in enumerate(row)]))
- if i == 0:
- textl[0] = textl[0].rstrip()
-
- text = os.linesep.join(textl)
- return text
-
-
-@cbook.deprecated("2.2", alternative='numpy.recarray.tofile')
-def rec2csv(r, fname, delimiter=',', formatd=None, missing='',
- missingd=None, withheader=True):
- """
- Save the data from numpy recarray *r* into a
- comma-/space-/tab-delimited file. The record array dtype names
- will be used for column headers.
-
- *fname*: can be a filename or a file handle. Support for gzipped
- files is automatic, if the filename ends in '.gz'
-
- *withheader*: if withheader is False, do not write the attribute
- names in the first row
-
- for formatd type FormatFloat, we override the precision to store
- full precision floats in the CSV file
-
- See Also
- --------
- :func:`csv2rec`
- For information about *missing* and *missingd*, which can be used to
- fill in masked values into your CSV file.
- """
-
- delimiter = str(delimiter)
-
- if missingd is None:
- missingd = dict()
-
- def with_mask(func):
- def newfunc(val, mask, mval):
- if mask:
- return mval
- else:
- return func(val)
- return newfunc
-
- if r.ndim != 1:
- raise ValueError('rec2csv only operates on 1 dimensional recarrays')
-
- formatd = get_formatd(r, formatd)
- funcs = []
- for i, name in enumerate(r.dtype.names):
- funcs.append(with_mask(csvformat_factory(formatd[name]).tostr))
-
- fh, opened = cbook.to_filehandle(fname, 'wb', return_opened=True)
- writer = csv.writer(fh, delimiter=delimiter)
- header = r.dtype.names
- if withheader:
- writer.writerow(header)
-
- # Our list of specials for missing values
- mvals = []
- for name in header:
- mvals.append(missingd.get(name, missing))
-
- ismasked = False
- if len(r):
- row = r[0]
- ismasked = hasattr(row, '_fieldmask')
-
- for row in r:
- if ismasked:
- row, rowmask = row.item(), row._fieldmask.item()
- else:
- rowmask = [False] * len(row)
- writer.writerow([func(val, mask, mval) for func, val, mask, mval
- in zip(funcs, row, rowmask, mvals)])
- if opened:
- fh.close()
-
-
-@cbook.deprecated('2.2', alternative='scipy.interpolate.griddata')
-def griddata(x, y, z, xi, yi, interp='nn'):
- """
- Interpolates from a nonuniformly spaced grid to some other grid.
-
- Fits a surface of the form z = f(`x`, `y`) to the data in the
- (usually) nonuniformly spaced vectors (`x`, `y`, `z`), then
- interpolates this surface at the points specified by
- (`xi`, `yi`) to produce `zi`.
-
- Parameters
- ----------
- x, y, z : 1d array_like
- Coordinates of grid points to interpolate from.
- xi, yi : 1d or 2d array_like
- Coordinates of grid points to interpolate to.
- interp : string key from {'nn', 'linear'}
- Interpolation algorithm, either 'nn' for natural neighbor, or
- 'linear' for linear interpolation.
-
- Returns
- -------
- 2d float array
- Array of values interpolated at (`xi`, `yi`) points. Array
- will be masked is any of (`xi`, `yi`) are outside the convex
- hull of (`x`, `y`).
-
- Notes
- -----
- If `interp` is 'nn' (the default), uses natural neighbor
- interpolation based on Delaunay triangulation. This option is
- only available if the mpl_toolkits.natgrid module is installed.
- This can be downloaded from https://github.com/matplotlib/natgrid.
- The (`xi`, `yi`) grid must be regular and monotonically increasing
- in this case.
-
- If `interp` is 'linear', linear interpolation is used via
- matplotlib.tri.LinearTriInterpolator.
-
- Instead of using `griddata`, more flexible functionality and other
- interpolation options are available using a
- matplotlib.tri.Triangulation and a matplotlib.tri.TriInterpolator.
- """
- # Check input arguments.
- x = np.asanyarray(x, dtype=np.float64)
- y = np.asanyarray(y, dtype=np.float64)
- z = np.asanyarray(z, dtype=np.float64)
- if x.shape != y.shape or x.shape != z.shape or x.ndim != 1:
- raise ValueError("x, y and z must be equal-length 1-D arrays")
-
- xi = np.asanyarray(xi, dtype=np.float64)
- yi = np.asanyarray(yi, dtype=np.float64)
- if xi.ndim != yi.ndim:
- raise ValueError("xi and yi must be arrays with the same number of "
- "dimensions (1 or 2)")
- if xi.ndim == 2 and xi.shape != yi.shape:
- raise ValueError("if xi and yi are 2D arrays, they must have the same "
- "shape")
- if xi.ndim == 1:
- xi, yi = np.meshgrid(xi, yi)
-
- if interp == 'nn':
- use_nn_interpolation = True
- elif interp == 'linear':
- use_nn_interpolation = False
- else:
- raise ValueError("interp keyword must be one of 'linear' (for linear "
- "interpolation) or 'nn' (for natural neighbor "
- "interpolation). Default is 'nn'.")
-
- # Remove masked points.
- mask = np.ma.getmask(z)
- if mask is not np.ma.nomask:
- x = x.compress(~mask)
- y = y.compress(~mask)
- z = z.compressed()
-
- if use_nn_interpolation:
- try:
- from mpl_toolkits.natgrid import _natgrid
- except ImportError:
- raise RuntimeError(
- "To use interp='nn' (Natural Neighbor interpolation) in "
- "griddata, natgrid must be installed. Either install it "
- "from http://github.com/matplotlib/natgrid or use "
- "interp='linear' instead.")
-
- if xi.ndim == 2:
- # natgrid expects 1D xi and yi arrays.
- xi = xi[0, :]
- yi = yi[:, 0]
-
- # Override default natgrid internal parameters.
- _natgrid.seti(b'ext', 0)
- _natgrid.setr(b'nul', np.nan)
-
- if np.min(np.diff(xi)) < 0 or np.min(np.diff(yi)) < 0:
- raise ValueError("Output grid defined by xi,yi must be monotone "
- "increasing")
-
- # Allocate array for output (buffer will be overwritten by natgridd)
- zi = np.empty((yi.shape[0], xi.shape[0]), np.float64)
-
- # Natgrid requires each array to be contiguous rather than e.g. a view
- # that is a non-contiguous slice of another array. Use numpy.require
- # to deal with this, which will copy if necessary.
- x = np.require(x, requirements=['C'])
- y = np.require(y, requirements=['C'])
- z = np.require(z, requirements=['C'])
- xi = np.require(xi, requirements=['C'])
- yi = np.require(yi, requirements=['C'])
- _natgrid.natgridd(x, y, z, xi, yi, zi)
-
- # Mask points on grid outside convex hull of input data.
- if np.any(np.isnan(zi)):
- zi = np.ma.masked_where(np.isnan(zi), zi)
- return zi
- else:
- # Linear interpolation performed using a matplotlib.tri.Triangulation
- # and a matplotlib.tri.LinearTriInterpolator.
- from .tri import Triangulation, LinearTriInterpolator
- triang = Triangulation(x, y)
- interpolator = LinearTriInterpolator(triang, z)
- return interpolator(xi, yi)
-
-
-##################################################
-# Linear interpolation algorithms
-##################################################
-@cbook.deprecated("2.2", alternative="numpy.interp")
-def less_simple_linear_interpolation(x, y, xi, extrap=False):
- """
- This function provides simple (but somewhat less so than
- :func:`cbook.simple_linear_interpolation`) linear interpolation.
- :func:`simple_linear_interpolation` will give a list of point
- between a start and an end, while this does true linear
- interpolation at an arbitrary set of points.
-
- This is very inefficient linear interpolation meant to be used
- only for a small number of points in relatively non-intensive use
- cases. For real linear interpolation, use scipy.
- """
- x = np.asarray(x)
- y = np.asarray(y)
- xi = np.atleast_1d(xi)
-
- s = list(y.shape)
- s[0] = len(xi)
- yi = np.tile(np.nan, s)
-
- for ii, xx in enumerate(xi):
- bb = x == xx
- if np.any(bb):
- jj, = np.nonzero(bb)
- yi[ii] = y[jj[0]]
- elif xx < x[0]:
- if extrap:
- yi[ii] = y[0]
- elif xx > x[-1]:
- if extrap:
- yi[ii] = y[-1]
- else:
- jj, = np.nonzero(x < xx)
- jj = max(jj)
-
- yi[ii] = y[jj] + (xx-x[jj])/(x[jj+1]-x[jj]) * (y[jj+1]-y[jj])
-
- return yi
-
-
-@cbook.deprecated("2.2")
-def slopes(x, y):
- """
- :func:`slopes` calculates the slope *y*'(*x*)
-
- The slope is estimated using the slope obtained from that of a
- parabola through any three consecutive points.
-
- This method should be superior to that described in the appendix
- of A CONSISTENTLY WELL BEHAVED METHOD OF INTERPOLATION by Russel
- W. Stineman (Creative Computing July 1980) in at least one aspect:
-
- Circles for interpolation demand a known aspect ratio between
- *x*- and *y*-values. For many functions, however, the abscissa
- are given in different dimensions, so an aspect ratio is
- completely arbitrary.
-
- The parabola method gives very similar results to the circle
- method for most regular cases but behaves much better in special
- cases.
-
- Norbert Nemec, Institute of Theoretical Physics, University or
- Regensburg, April 2006 Norbert.Nemec at physik.uni-regensburg.de
-
- (inspired by a original implementation by Halldor Bjornsson,
- Icelandic Meteorological Office, March 2006 halldor at vedur.is)
- """
- # Cast key variables as float.
- x = np.asarray(x, float)
- y = np.asarray(y, float)
-
- yp = np.zeros(y.shape, float)
-
- dx = x[1:] - x[:-1]
- dy = y[1:] - y[:-1]
- dydx = dy/dx
- yp[1:-1] = (dydx[:-1] * dx[1:] + dydx[1:] * dx[:-1])/(dx[1:] + dx[:-1])
- yp[0] = 2.0 * dy[0]/dx[0] - yp[1]
- yp[-1] = 2.0 * dy[-1]/dx[-1] - yp[-2]
- return yp
-
-
-@cbook.deprecated("2.2")
-def stineman_interp(xi, x, y, yp=None):
- """
- Given data vectors *x* and *y*, the slope vector *yp* and a new
- abscissa vector *xi*, the function :func:`stineman_interp` uses
- Stineman interpolation to calculate a vector *yi* corresponding to
- *xi*.
-
- Here's an example that generates a coarse sine curve, then
- interpolates over a finer abscissa::
-
- x = linspace(0,2*pi,20); y = sin(x); yp = cos(x)
- xi = linspace(0,2*pi,40);
- yi = stineman_interp(xi,x,y,yp);
- plot(x,y,'o',xi,yi)
-
- The interpolation method is described in the article A
- CONSISTENTLY WELL BEHAVED METHOD OF INTERPOLATION by Russell
- W. Stineman. The article appeared in the July 1980 issue of
- Creative Computing with a note from the editor stating that while
- they were:
-
- not an academic journal but once in a while something serious
- and original comes in adding that this was
- "apparently a real solution" to a well known problem.
-
- For *yp* = *None*, the routine automatically determines the slopes
- using the :func:`slopes` routine.
-
- *x* is assumed to be sorted in increasing order.
-
- For values ``xi[j] < x[0]`` or ``xi[j] > x[-1]``, the routine
- tries an extrapolation. The relevance of the data obtained from
- this, of course, is questionable...
-
- Original implementation by Halldor Bjornsson, Icelandic
- Meteorolocial Office, March 2006 halldor at vedur.is
-
- Completely reworked and optimized for Python by Norbert Nemec,
- Institute of Theoretical Physics, University or Regensburg, April
- 2006 Norbert.Nemec at physik.uni-regensburg.de
- """
-
- # Cast key variables as float.
- x = np.asarray(x, float)
- y = np.asarray(y, float)
- if x.shape != y.shape:
- raise ValueError("'x' and 'y' must be of same shape")
-
- if yp is None:
- yp = slopes(x, y)
- else:
- yp = np.asarray(yp, float)
-
- xi = np.asarray(xi, float)
- yi = np.zeros(xi.shape, float)
-
- # calculate linear slopes
- dx = x[1:] - x[:-1]
- dy = y[1:] - y[:-1]
- s = dy/dx # note length of s is N-1 so last element is #N-2
-
- # find the segment each xi is in
- # this line actually is the key to the efficiency of this implementation
- idx = np.searchsorted(x[1:-1], xi)
-
- # now we have generally: x[idx[j]] <= xi[j] <= x[idx[j]+1]
- # except at the boundaries, where it may be that xi[j] < x[0] or
- # xi[j] > x[-1]
-
- # the y-values that would come out from a linear interpolation:
- sidx = s.take(idx)
- xidx = x.take(idx)
- yidx = y.take(idx)
- xidxp1 = x.take(idx+1)
- yo = yidx + sidx * (xi - xidx)
-
- # the difference that comes when using the slopes given in yp
- # using the yp slope of the left point
- dy1 = (yp.take(idx) - sidx) * (xi - xidx)
- # using the yp slope of the right point
- dy2 = (yp.take(idx+1)-sidx) * (xi - xidxp1)
-
- dy1dy2 = dy1*dy2
- # The following is optimized for Python. The solution actually
- # does more calculations than necessary but exploiting the power
- # of numpy, this is far more efficient than coding a loop by hand
- # in Python
- yi = yo + dy1dy2 * np.choose(np.array(np.sign(dy1dy2), np.int32)+1,
- ((2*xi-xidx-xidxp1)/((dy1-dy2)*(xidxp1-xidx)),
- 0.0,
- 1/(dy1+dy2),))
- return yi
-
-
-class GaussianKDE(object):
- """
- Representation of a kernel-density estimate using Gaussian kernels.
-
- Parameters
- ----------
- dataset : array_like
- Datapoints to estimate from. In case of univariate data this is a 1-D
- array, otherwise a 2-D array with shape (# of dims, # of data).
-
- bw_method : str, scalar or callable, optional
- The method used to calculate the estimator bandwidth. This can be
- 'scott', 'silverman', a scalar constant or a callable. If a
- scalar, this will be used directly as `kde.factor`. If a
- callable, it should take a `GaussianKDE` instance as only
- parameter and return a scalar. If None (default), 'scott' is used.
-
- Attributes
- ----------
- dataset : ndarray
- The dataset with which `gaussian_kde` was initialized.
-
- dim : int
- Number of dimensions.
-
- num_dp : int
- Number of datapoints.
-
- factor : float
- The bandwidth factor, obtained from `kde.covariance_factor`, with which
- the covariance matrix is multiplied.
-
- covariance : ndarray
- The covariance matrix of `dataset`, scaled by the calculated bandwidth
- (`kde.factor`).
-
- inv_cov : ndarray
- The inverse of `covariance`.
-
- Methods
- -------
- kde.evaluate(points) : ndarray
- Evaluate the estimated pdf on a provided set of points.
-
- kde(points) : ndarray
- Same as kde.evaluate(points)
-
- """
-
- # This implementation with minor modification was too good to pass up.
- # from scipy: https://github.com/scipy/scipy/blob/master/scipy/stats/kde.py
-
- def __init__(self, dataset, bw_method=None):
- self.dataset = np.atleast_2d(dataset)
- if not np.array(self.dataset).size > 1:
- raise ValueError("`dataset` input should have multiple elements.")
-
- self.dim, self.num_dp = np.array(self.dataset).shape
- isString = isinstance(bw_method, six.string_types)
-
- if bw_method is None:
- pass
- elif (isString and bw_method == 'scott'):
- self.covariance_factor = self.scotts_factor
- elif (isString and bw_method == 'silverman'):
- self.covariance_factor = self.silverman_factor
- elif (np.isscalar(bw_method) and not isString):
- self._bw_method = 'use constant'
- self.covariance_factor = lambda: bw_method
- elif callable(bw_method):
- self._bw_method = bw_method
- self.covariance_factor = lambda: self._bw_method(self)
- else:
- raise ValueError("`bw_method` should be 'scott', 'silverman', a "
- "scalar or a callable")
-
- # Computes the covariance matrix for each Gaussian kernel using
- # covariance_factor().
-
- self.factor = self.covariance_factor()
- # Cache covariance and inverse covariance of the data
- if not hasattr(self, '_data_inv_cov'):
- self.data_covariance = np.atleast_2d(
- np.cov(
- self.dataset,
- rowvar=1,
- bias=False))
- self.data_inv_cov = np.linalg.inv(self.data_covariance)
-
- self.covariance = self.data_covariance * self.factor ** 2
- self.inv_cov = self.data_inv_cov / self.factor ** 2
- self.norm_factor = np.sqrt(
- np.linalg.det(
- 2 * np.pi * self.covariance)) * self.num_dp
-
- def scotts_factor(self):
- return np.power(self.num_dp, -1. / (self.dim + 4))
-
- def silverman_factor(self):
- return np.power(
- self.num_dp * (self.dim + 2.0) / 4.0, -1. / (self.dim + 4))
-
- # Default method to calculate bandwidth, can be overwritten by subclass
- covariance_factor = scotts_factor
-
- def evaluate(self, points):
- """Evaluate the estimated pdf on a set of points.
-
- Parameters
- ----------
- points : (# of dimensions, # of points)-array
- Alternatively, a (# of dimensions,) vector can be passed in and
- treated as a single point.
-
- Returns
- -------
- values : (# of points,)-array
- The values at each point.
-
- Raises
- ------
- ValueError : if the dimensionality of the input points is different
- than the dimensionality of the KDE.
-
- """
- points = np.atleast_2d(points)
-
- dim, num_m = np.array(points).shape
- if dim != self.dim:
- raise ValueError("points have dimension {}, dataset has dimension "
- "{}".format(dim, self.dim))
-
- result = np.zeros((num_m,), dtype=float)
-
- if num_m >= self.num_dp:
- # there are more points than data, so loop over data
- for i in range(self.num_dp):
- diff = self.dataset[:, i, np.newaxis] - points
- tdiff = np.dot(self.inv_cov, diff)
- energy = np.sum(diff * tdiff, axis=0) / 2.0
- result = result + np.exp(-energy)
- else:
- # loop over points
- for i in range(num_m):
- diff = self.dataset - points[:, i, np.newaxis]
- tdiff = np.dot(self.inv_cov, diff)
- energy = np.sum(diff * tdiff, axis=0) / 2.0
- result[i] = np.sum(np.exp(-energy), axis=0)
-
- result = result / self.norm_factor
-
- return result
-
- __call__ = evaluate
-
-
-##################################################
-# Code related to things in and around polygons
-##################################################
-@cbook.deprecated("2.2")
-def inside_poly(points, verts):
- """
- *points* is a sequence of *x*, *y* points.
- *verts* is a sequence of *x*, *y* vertices of a polygon.
-
- Return value is a sequence of indices into points for the points
- that are inside the polygon.
- """
- # Make a closed polygon path
- poly = Path(verts)
-
- # Check to see which points are contained within the Path
- return [idx for idx, p in enumerate(points) if poly.contains_point(p)]
-
-
-@cbook.deprecated("2.2")
-def poly_below(xmin, xs, ys):
- """
- Given a sequence of *xs* and *ys*, return the vertices of a
- polygon that has a horizontal base at *xmin* and an upper bound at
- the *ys*. *xmin* is a scalar.
-
- Intended for use with :meth:`matplotlib.axes.Axes.fill`, e.g.,::
-
- xv, yv = poly_below(0, x, y)
- ax.fill(xv, yv)
- """
- if any(isinstance(var, np.ma.MaskedArray) for var in [xs, ys]):
- numpy = np.ma
- else:
- numpy = np
-
- xs = numpy.asarray(xs)
- ys = numpy.asarray(ys)
- Nx = len(xs)
- Ny = len(ys)
- if Nx != Ny:
- raise ValueError("'xs' and 'ys' must have the same length")
- x = xmin*numpy.ones(2*Nx)
- y = numpy.ones(2*Nx)
- x[:Nx] = xs
- y[:Nx] = ys
- y[Nx:] = ys[::-1]
- return x, y
-
-
-@cbook.deprecated("2.2")
-def poly_between(x, ylower, yupper):
- """
- Given a sequence of *x*, *ylower* and *yupper*, return the polygon
- that fills the regions between them. *ylower* or *yupper* can be
- scalar or iterable. If they are iterable, they must be equal in
- length to *x*.
-
- Return value is *x*, *y* arrays for use with
- :meth:`matplotlib.axes.Axes.fill`.
- """
- if any(isinstance(var, np.ma.MaskedArray) for var in [ylower, yupper, x]):
- numpy = np.ma
- else:
- numpy = np
-
- Nx = len(x)
- if not cbook.iterable(ylower):
- ylower = ylower*numpy.ones(Nx)
-
- if not cbook.iterable(yupper):
- yupper = yupper*numpy.ones(Nx)
-
- x = numpy.concatenate((x, x[::-1]))
- y = numpy.concatenate((yupper, ylower[::-1]))
- return x, y
-
-
-@cbook.deprecated('2.2')
-def is_closed_polygon(X):
- """
- Tests whether first and last object in a sequence are the same. These are
- presumably coordinates on a polygonal curve, in which case this function
- tests if that curve is closed.
- """
- return np.all(X[0] == X[-1])
-
-
-@cbook.deprecated("2.2", message='Moved to matplotlib.cbook')
-def contiguous_regions(mask):
- """
- return a list of (ind0, ind1) such that mask[ind0:ind1].all() is
- True and we cover all such regions
- """
- return cbook.contiguous_regions(mask)
-
-
-@cbook.deprecated("2.2")
-def cross_from_below(x, threshold):
- """
- return the indices into *x* where *x* crosses some threshold from
- below, e.g., the i's where::
-
- x[i-1]<threshold and x[i]>=threshold
-
- Example code::
-
- import matplotlib.pyplot as plt
-
- t = np.arange(0.0, 2.0, 0.1)
- s = np.sin(2*np.pi*t)
-
- fig, ax = plt.subplots()
- ax.plot(t, s, '-o')
- ax.axhline(0.5)
- ax.axhline(-0.5)
-
- ind = cross_from_below(s, 0.5)
- ax.vlines(t[ind], -1, 1)
-
- ind = cross_from_above(s, -0.5)
- ax.vlines(t[ind], -1, 1)
-
- plt.show()
-
- See Also
- --------
- :func:`cross_from_above` and :func:`contiguous_regions`
-
- """
- x = np.asarray(x)
- ind = np.nonzero((x[:-1] < threshold) & (x[1:] >= threshold))[0]
- if len(ind):
- return ind+1
- else:
- return ind
-
-
-@cbook.deprecated("2.2")
-def cross_from_above(x, threshold):
- """
- return the indices into *x* where *x* crosses some threshold from
- below, e.g., the i's where::
-
- x[i-1]>threshold and x[i]<=threshold
-
- See Also
- --------
- :func:`cross_from_below` and :func:`contiguous_regions`
-
- """
- x = np.asarray(x)
- ind = np.nonzero((x[:-1] >= threshold) & (x[1:] < threshold))[0]
- if len(ind):
- return ind+1
- else:
- return ind
-
-
-##################################################
-# Vector and path length geometry calculations
-##################################################
-@cbook.deprecated('2.2')
-def vector_lengths(X, P=2., axis=None):
- """
- Finds the length of a set of vectors in *n* dimensions. This is
- like the :func:`numpy.norm` function for vectors, but has the ability to
- work over a particular axis of the supplied array or matrix.
-
- Computes ``(sum((x_i)^P))^(1/P)`` for each ``{x_i}`` being the
- elements of *X* along the given axis. If *axis* is *None*,
- compute over all elements of *X*.
- """
- X = np.asarray(X)
- return (np.sum(X**(P), axis=axis))**(1./P)
-
-
-@cbook.deprecated('2.2')
-def distances_along_curve(X):
- """
- Computes the distance between a set of successive points in *N* dimensions.
-
- Where *X* is an *M* x *N* array or matrix. The distances between
- successive rows is computed. Distance is the standard Euclidean
- distance.
- """
- X = np.diff(X, axis=0)
- return vector_lengths(X, axis=1)
-
-
-@cbook.deprecated('2.2')
-def path_length(X):
- """
- Computes the distance travelled along a polygonal curve in *N* dimensions.
-
- Where *X* is an *M* x *N* array or matrix. Returns an array of
- length *M* consisting of the distance along the curve at each point
- (i.e., the rows of *X*).
- """
- X = distances_along_curve(X)
- return np.concatenate((np.zeros(1), np.cumsum(X)))
-
-
-@cbook.deprecated('2.2')
-def quad2cubic(q0x, q0y, q1x, q1y, q2x, q2y):
- """
- Converts a quadratic Bezier curve to a cubic approximation.
-
- The inputs are the *x* and *y* coordinates of the three control
- points of a quadratic curve, and the output is a tuple of *x* and
- *y* coordinates of the four control points of the cubic curve.
- """
- # TODO: Candidate for deprecation -- no longer used internally
-
- # c0x, c0y = q0x, q0y
- c1x, c1y = q0x + 2./3. * (q1x - q0x), q0y + 2./3. * (q1y - q0y)
- c2x, c2y = c1x + 1./3. * (q2x - q0x), c1y + 1./3. * (q2y - q0y)
- # c3x, c3y = q2x, q2y
- return q0x, q0y, c1x, c1y, c2x, c2y, q2x, q2y
-
-
-@cbook.deprecated("2.2")
-def offset_line(y, yerr):
- """
- Offsets an array *y* by +/- an error and returns a tuple
- (y - err, y + err).
-
- The error term can be:
-
- * A scalar. In this case, the returned tuple is obvious.
- * A vector of the same length as *y*. The quantities y +/- err are computed
- component-wise.
- * A tuple of length 2. In this case, yerr[0] is the error below *y* and
- yerr[1] is error above *y*. For example::
-
- from pylab import *
- x = linspace(0, 2*pi, num=100, endpoint=True)
- y = sin(x)
- y_minus, y_plus = mlab.offset_line(y, 0.1)
- plot(x, y)
- fill_between(x, ym, y2=yp)
- show()
-
- """
- if cbook.is_numlike(yerr) or (cbook.iterable(yerr) and
- len(yerr) == len(y)):
- ymin = y - yerr
- ymax = y + yerr
- elif len(yerr) == 2:
- ymin, ymax = y - yerr[0], y + yerr[1]
- else:
- raise ValueError("yerr must be scalar, 1xN or 2xN")
- return ymin, ymax
diff --git a/contrib/python/matplotlib/py2/matplotlib/offsetbox.py b/contrib/python/matplotlib/py2/matplotlib/offsetbox.py
deleted file mode 100644
index 86c3a0d525..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/offsetbox.py
+++ /dev/null
@@ -1,1811 +0,0 @@
-"""
-The OffsetBox is a simple container artist. The child artist are meant
-to be drawn at a relative position to its parent. The [VH]Packer,
-DrawingArea and TextArea are derived from the OffsetBox.
-
-The [VH]Packer automatically adjust the relative postisions of their
-children, which should be instances of the OffsetBox. This is used to
-align similar artists together, e.g., in legend.
-
-The DrawingArea can contain any Artist as a child. The
-DrawingArea has a fixed width and height. The position of children
-relative to the parent is fixed. The TextArea is contains a single
-Text instance. The width and height of the TextArea instance is the
-width and height of the its child text.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange, zip
-
-import warnings
-import matplotlib.transforms as mtransforms
-import matplotlib.artist as martist
-import matplotlib.text as mtext
-import matplotlib.path as mpath
-import numpy as np
-from matplotlib.transforms import Bbox, BboxBase, TransformedBbox
-
-from matplotlib.font_manager import FontProperties
-from matplotlib.patches import FancyBboxPatch, FancyArrowPatch
-from matplotlib import rcParams
-
-from matplotlib import docstring
-
-from matplotlib.image import BboxImage
-
-from matplotlib.patches import bbox_artist as mbbox_artist
-from matplotlib.text import _AnnotationBase
-
-
-DEBUG = False
-
-
-# for debugging use
-def bbox_artist(*args, **kwargs):
- if DEBUG:
- mbbox_artist(*args, **kwargs)
-
-# _get_packed_offsets() and _get_aligned_offsets() are coded assuming
-# that we are packing boxes horizontally. But same function will be
-# used with vertical packing.
-
-
-def _get_packed_offsets(wd_list, total, sep, mode="fixed"):
- """
- Geiven a list of (width, xdescent) of each boxes, calculate the
- total width and the x-offset positions of each items according to
- *mode*. xdescent is analogous to the usual descent, but along the
- x-direction. xdescent values are currently ignored.
-
- *wd_list* : list of (width, xdescent) of boxes to be packed.
- *sep* : spacing between boxes
- *total* : Intended total length. None if not used.
- *mode* : packing mode. 'fixed', 'expand', or 'equal'.
- """
-
- w_list, d_list = zip(*wd_list)
- # d_list is currently not used.
-
- if mode == "fixed":
- offsets_ = np.cumsum([0] + [w + sep for w in w_list])
- offsets = offsets_[:-1]
- if total is None:
- total = offsets_[-1] - sep
- return total, offsets
-
- elif mode == "expand":
- # This is a bit of a hack to avoid a TypeError when *total*
- # is None and used in conjugation with tight layout.
- if total is None:
- total = 1
- if len(w_list) > 1:
- sep = (total - sum(w_list)) / (len(w_list) - 1)
- else:
- sep = 0
- offsets_ = np.cumsum([0] + [w + sep for w in w_list])
- offsets = offsets_[:-1]
- return total, offsets
-
- elif mode == "equal":
- maxh = max(w_list)
- if total is None:
- total = (maxh + sep) * len(w_list)
- else:
- sep = total / len(w_list) - maxh
- offsets = (maxh + sep) * np.arange(len(w_list))
- return total, offsets
-
- else:
- raise ValueError("Unknown mode : %s" % (mode,))
-
-
-def _get_aligned_offsets(hd_list, height, align="baseline"):
- """
- Given a list of (height, descent) of each boxes, align the boxes
- with *align* and calculate the y-offsets of each boxes.
- total width and the offset positions of each items according to
- *mode*. xdescent is analogous to the usual descent, but along the
- x-direction. xdescent values are currently ignored.
-
- *hd_list* : list of (width, xdescent) of boxes to be aligned.
- *sep* : spacing between boxes
- *height* : Intended total length. None if not used.
- *align* : align mode. 'baseline', 'top', 'bottom', or 'center'.
- """
-
- if height is None:
- height = max(h for h, d in hd_list)
-
- if align == "baseline":
- height_descent = max(h - d for h, d in hd_list)
- descent = max(d for h, d in hd_list)
- height = height_descent + descent
- offsets = [0. for h, d in hd_list]
- elif align in ["left", "top"]:
- descent = 0.
- offsets = [d for h, d in hd_list]
- elif align in ["right", "bottom"]:
- descent = 0.
- offsets = [height - h + d for h, d in hd_list]
- elif align == "center":
- descent = 0.
- offsets = [(height - h) * .5 + d for h, d in hd_list]
- else:
- raise ValueError("Unknown Align mode : %s" % (align,))
-
- return height, descent, offsets
-
-
-class OffsetBox(martist.Artist):
- """
- The OffsetBox is a simple container artist. The child artist are meant
- to be drawn at a relative position to its parent.
- """
- def __init__(self, *args, **kwargs):
-
- super(OffsetBox, self).__init__(*args, **kwargs)
-
- # Clipping has not been implemented in the OffesetBox family, so
- # disable the clip flag for consistency. It can always be turned back
- # on to zero effect.
- self.set_clip_on(False)
-
- self._children = []
- self._offset = (0, 0)
-
- def __getstate__(self):
- state = martist.Artist.__getstate__(self)
-
- # pickle cannot save instancemethods, so handle them here
- from .cbook import _InstanceMethodPickler
- import inspect
-
- offset = state['_offset']
- if inspect.ismethod(offset):
- state['_offset'] = _InstanceMethodPickler(offset)
- return state
-
- def __setstate__(self, state):
- self.__dict__ = state
- from .cbook import _InstanceMethodPickler
- if isinstance(self._offset, _InstanceMethodPickler):
- self._offset = self._offset.get_instancemethod()
- self.stale = True
-
- def set_figure(self, fig):
- """
- Set the figure
-
- accepts a class:`~matplotlib.figure.Figure` instance
- """
- martist.Artist.set_figure(self, fig)
- for c in self.get_children():
- c.set_figure(fig)
-
- @martist.Artist.axes.setter
- def axes(self, ax):
- # TODO deal with this better
- martist.Artist.axes.fset(self, ax)
- for c in self.get_children():
- if c is not None:
- c.axes = ax
-
- def contains(self, mouseevent):
- for c in self.get_children():
- a, b = c.contains(mouseevent)
- if a:
- return a, b
- return False, {}
-
- def set_offset(self, xy):
- """
- Set the offset
-
- accepts x, y, tuple, or a callable object.
- """
- self._offset = xy
- self.stale = True
-
- def get_offset(self, width, height, xdescent, ydescent, renderer):
- """
- Get the offset
-
- accepts extent of the box
- """
- return (self._offset(width, height, xdescent, ydescent, renderer)
- if callable(self._offset)
- else self._offset)
-
- def set_width(self, width):
- """
- Set the width
-
- accepts float
- """
- self.width = width
- self.stale = True
-
- def set_height(self, height):
- """
- Set the height
-
- accepts float
- """
- self.height = height
- self.stale = True
-
- def get_visible_children(self):
- """
- Return a list of visible artists it contains.
- """
- return [c for c in self._children if c.get_visible()]
-
- def get_children(self):
- """
- Return a list of artists it contains.
- """
- return self._children
-
- def get_extent_offsets(self, renderer):
- raise Exception("")
-
- def get_extent(self, renderer):
- """
- Return with, height, xdescent, ydescent of box
- """
- w, h, xd, yd, offsets = self.get_extent_offsets(renderer)
- return w, h, xd, yd
-
- def get_window_extent(self, renderer):
- '''
- get the bounding box in display space.
- '''
- w, h, xd, yd, offsets = self.get_extent_offsets(renderer)
- px, py = self.get_offset(w, h, xd, yd, renderer)
- return mtransforms.Bbox.from_bounds(px - xd, py - yd, w, h)
-
- def draw(self, renderer):
- """
- Update the location of children if necessary and draw them
- to the given *renderer*.
- """
-
- width, height, xdescent, ydescent, offsets = self.get_extent_offsets(
- renderer)
-
- px, py = self.get_offset(width, height, xdescent, ydescent, renderer)
-
- for c, (ox, oy) in zip(self.get_visible_children(), offsets):
- c.set_offset((px + ox, py + oy))
- c.draw(renderer)
-
- bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
- self.stale = False
-
-
-class PackerBase(OffsetBox):
- def __init__(self, pad=None, sep=None, width=None, height=None,
- align=None, mode=None,
- children=None):
- """
- Parameters
- ----------
- pad : float, optional
- Boundary pad.
-
- sep : float, optional
- Spacing between items.
-
- width : float, optional
-
- height : float, optional
- Width and height of the container box, calculated if
- `None`.
-
- align : str, optional
- Alignment of boxes. Can be one of ``top``, ``bottom``,
- ``left``, ``right``, ``center`` and ``baseline``
-
- mode : str, optional
- Packing mode.
-
- Notes
- -----
- *pad* and *sep* need to given in points and will be scale with
- the renderer dpi, while *width* and *height* need to be in
- pixels.
- """
- super(PackerBase, self).__init__()
-
- self.height = height
- self.width = width
- self.sep = sep
- self.pad = pad
- self.mode = mode
- self.align = align
-
- self._children = children
-
-
-class VPacker(PackerBase):
- """
- The VPacker has its children packed vertically. It automatically
- adjust the relative positions of children in the drawing time.
- """
- def __init__(self, pad=None, sep=None, width=None, height=None,
- align="baseline", mode="fixed",
- children=None):
- """
- Parameters
- ----------
- pad : float, optional
- Boundary pad.
-
- sep : float, optional
- Spacing between items.
-
- width : float, optional
-
- height : float, optional
-
- width and height of the container box, calculated if
- `None`.
-
- align : str, optional
- Alignment of boxes.
-
- mode : str, optional
- Packing mode.
-
- Notes
- -----
- *pad* and *sep* need to given in points and will be scale with
- the renderer dpi, while *width* and *height* need to be in
- pixels.
- """
- super(VPacker, self).__init__(pad, sep, width, height,
- align, mode,
- children)
-
- def get_extent_offsets(self, renderer):
- """
- update offset of childrens and return the extents of the box
- """
-
- dpicor = renderer.points_to_pixels(1.)
- pad = self.pad * dpicor
- sep = self.sep * dpicor
-
- if self.width is not None:
- for c in self.get_visible_children():
- if isinstance(c, PackerBase) and c.mode == "expand":
- c.set_width(self.width)
-
- whd_list = [c.get_extent(renderer)
- for c in self.get_visible_children()]
- whd_list = [(w, h, xd, (h - yd)) for w, h, xd, yd in whd_list]
-
- wd_list = [(w, xd) for w, h, xd, yd in whd_list]
- width, xdescent, xoffsets = _get_aligned_offsets(wd_list,
- self.width,
- self.align)
-
- pack_list = [(h, yd) for w, h, xd, yd in whd_list]
- height, yoffsets_ = _get_packed_offsets(pack_list, self.height,
- sep, self.mode)
-
- yoffsets = yoffsets_ + [yd for w, h, xd, yd in whd_list]
- ydescent = height - yoffsets[0]
- yoffsets = height - yoffsets
-
- yoffsets = yoffsets - ydescent
-
- return width + 2 * pad, height + 2 * pad, \
- xdescent + pad, ydescent + pad, \
- list(zip(xoffsets, yoffsets))
-
-
-class HPacker(PackerBase):
- """
- The HPacker has its children packed horizontally. It automatically
- adjusts the relative positions of children at draw time.
- """
- def __init__(self, pad=None, sep=None, width=None, height=None,
- align="baseline", mode="fixed",
- children=None):
- """
- Parameters
- ----------
- pad : float, optional
- Boundary pad.
-
- sep : float, optional
- Spacing between items.
-
- width : float, optional
-
- height : float, optional
- Width and height of the container box, calculated if
- `None`.
-
- align : str
- Alignment of boxes.
-
- mode : str
- Packing mode.
-
- Notes
- -----
- *pad* and *sep* need to given in points and will be scale with
- the renderer dpi, while *width* and *height* need to be in
- pixels.
- """
- super(HPacker, self).__init__(pad, sep, width, height,
- align, mode, children)
-
- def get_extent_offsets(self, renderer):
- """
- update offset of children and return the extents of the box
- """
- dpicor = renderer.points_to_pixels(1.)
- pad = self.pad * dpicor
- sep = self.sep * dpicor
-
- whd_list = [c.get_extent(renderer)
- for c in self.get_visible_children()]
-
- if not whd_list:
- return 2 * pad, 2 * pad, pad, pad, []
-
- if self.height is None:
- height_descent = max(h - yd for w, h, xd, yd in whd_list)
- ydescent = max(yd for w, h, xd, yd in whd_list)
- height = height_descent + ydescent
- else:
- height = self.height - 2 * pad # width w/o pad
-
- hd_list = [(h, yd) for w, h, xd, yd in whd_list]
- height, ydescent, yoffsets = _get_aligned_offsets(hd_list,
- self.height,
- self.align)
-
- pack_list = [(w, xd) for w, h, xd, yd in whd_list]
-
- width, xoffsets_ = _get_packed_offsets(pack_list, self.width,
- sep, self.mode)
-
- xoffsets = xoffsets_ + [xd for w, h, xd, yd in whd_list]
-
- xdescent = whd_list[0][2]
- xoffsets = xoffsets - xdescent
-
- return width + 2 * pad, height + 2 * pad, \
- xdescent + pad, ydescent + pad, \
- list(zip(xoffsets, yoffsets))
-
-
-class PaddedBox(OffsetBox):
- def __init__(self, child, pad=None, draw_frame=False, patch_attrs=None):
- """
- *pad* : boundary pad
-
- .. note::
- *pad* need to given in points and will be
- scale with the renderer dpi, while *width* and *height*
- need to be in pixels.
- """
-
- super(PaddedBox, self).__init__()
-
- self.pad = pad
- self._children = [child]
-
- self.patch = FancyBboxPatch(
- xy=(0.0, 0.0), width=1., height=1.,
- facecolor='w', edgecolor='k',
- mutation_scale=1, # self.prop.get_size_in_points(),
- snap=True
- )
-
- self.patch.set_boxstyle("square", pad=0)
-
- if patch_attrs is not None:
- self.patch.update(patch_attrs)
-
- self._drawFrame = draw_frame
-
- def get_extent_offsets(self, renderer):
- """
- update offset of childrens and return the extents of the box
- """
-
- dpicor = renderer.points_to_pixels(1.)
- pad = self.pad * dpicor
-
- w, h, xd, yd = self._children[0].get_extent(renderer)
-
- return w + 2 * pad, h + 2 * pad, \
- xd + pad, yd + pad, \
- [(0, 0)]
-
- def draw(self, renderer):
- """
- Update the location of children if necessary and draw them
- to the given *renderer*.
- """
-
- width, height, xdescent, ydescent, offsets = self.get_extent_offsets(
- renderer)
-
- px, py = self.get_offset(width, height, xdescent, ydescent, renderer)
-
- for c, (ox, oy) in zip(self.get_visible_children(), offsets):
- c.set_offset((px + ox, py + oy))
-
- self.draw_frame(renderer)
-
- for c in self.get_visible_children():
- c.draw(renderer)
-
- #bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
- self.stale = False
-
- def update_frame(self, bbox, fontsize=None):
- self.patch.set_bounds(bbox.x0, bbox.y0,
- bbox.width, bbox.height)
-
- if fontsize:
- self.patch.set_mutation_scale(fontsize)
- self.stale = True
-
- def draw_frame(self, renderer):
- # update the location and size of the legend
- bbox = self.get_window_extent(renderer)
- self.update_frame(bbox)
-
- if self._drawFrame:
- self.patch.draw(renderer)
-
-
-class DrawingArea(OffsetBox):
- """
- The DrawingArea can contain any Artist as a child. The DrawingArea
- has a fixed width and height. The position of children relative to
- the parent is fixed. The children can be clipped at the
- boundaries of the parent.
- """
-
- def __init__(self, width, height, xdescent=0.,
- ydescent=0., clip=False):
- """
- *width*, *height* : width and height of the container box.
- *xdescent*, *ydescent* : descent of the box in x- and y-direction.
- *clip* : Whether to clip the children
- """
-
- super(DrawingArea, self).__init__()
-
- self.width = width
- self.height = height
- self.xdescent = xdescent
- self.ydescent = ydescent
- self._clip_children = clip
-
- self.offset_transform = mtransforms.Affine2D()
- self.offset_transform.clear()
- self.offset_transform.translate(0, 0)
-
- self.dpi_transform = mtransforms.Affine2D()
-
- @property
- def clip_children(self):
- """
- If the children of this DrawingArea should be clipped
- by DrawingArea bounding box.
- """
- return self._clip_children
-
- @clip_children.setter
- def clip_children(self, val):
- self._clip_children = bool(val)
- self.stale = True
-
- def get_transform(self):
- """
- Return the :class:`~matplotlib.transforms.Transform` applied
- to the children
- """
- return self.dpi_transform + self.offset_transform
-
- def set_transform(self, t):
- """
- set_transform is ignored.
- """
- pass
-
- def set_offset(self, xy):
- """
- set offset of the container.
-
- Accept : tuple of x,y coordinate in display units.
- """
- self._offset = xy
-
- self.offset_transform.clear()
- self.offset_transform.translate(xy[0], xy[1])
- self.stale = True
-
- def get_offset(self):
- """
- return offset of the container.
- """
- return self._offset
-
- def get_window_extent(self, renderer):
- '''
- get the bounding box in display space.
- '''
- w, h, xd, yd = self.get_extent(renderer)
- ox, oy = self.get_offset() # w, h, xd, yd)
-
- return mtransforms.Bbox.from_bounds(ox - xd, oy - yd, w, h)
-
- def get_extent(self, renderer):
- """
- Return with, height, xdescent, ydescent of box
- """
-
- dpi_cor = renderer.points_to_pixels(1.)
- return self.width * dpi_cor, self.height * dpi_cor, \
- self.xdescent * dpi_cor, self.ydescent * dpi_cor
-
- def add_artist(self, a):
- 'Add any :class:`~matplotlib.artist.Artist` to the container box'
- self._children.append(a)
- if not a.is_transform_set():
- a.set_transform(self.get_transform())
- if self.axes is not None:
- a.axes = self.axes
- fig = self.figure
- if fig is not None:
- a.set_figure(fig)
-
- def draw(self, renderer):
- """
- Draw the children
- """
-
- dpi_cor = renderer.points_to_pixels(1.)
- self.dpi_transform.clear()
- self.dpi_transform.scale(dpi_cor, dpi_cor)
-
- # At this point the DrawingArea has a transform
- # to the display space so the path created is
- # good for clipping children
- tpath = mtransforms.TransformedPath(
- mpath.Path([[0, 0], [0, self.height],
- [self.width, self.height],
- [self.width, 0]]),
- self.get_transform())
- for c in self._children:
- if self._clip_children and not (c.clipbox or c._clippath):
- c.set_clip_path(tpath)
- c.draw(renderer)
-
- bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
- self.stale = False
-
-
-class TextArea(OffsetBox):
- """
- The TextArea is contains a single Text instance. The text is
- placed at (0,0) with baseline+left alignment. The width and height
- of the TextArea instance is the width and height of the its child
- text.
- """
- def __init__(self, s,
- textprops=None,
- multilinebaseline=None,
- minimumdescent=True,
- ):
- """
- Parameters
- ----------
- s : str
- a string to be displayed.
-
- textprops : `~matplotlib.font_manager.FontProperties`, optional
-
- multilinebaseline : bool, optional
- If `True`, baseline for multiline text is adjusted so that
- it is (approximatedly) center-aligned with singleline
- text.
-
- minimumdescent : bool, optional
- If `True`, the box has a minimum descent of "p".
- """
- if textprops is None:
- textprops = {}
-
- if "va" not in textprops:
- textprops["va"] = "baseline"
-
- self._text = mtext.Text(0, 0, s, **textprops)
-
- OffsetBox.__init__(self)
-
- self._children = [self._text]
-
- self.offset_transform = mtransforms.Affine2D()
- self.offset_transform.clear()
- self.offset_transform.translate(0, 0)
- self._baseline_transform = mtransforms.Affine2D()
- self._text.set_transform(self.offset_transform +
- self._baseline_transform)
-
- self._multilinebaseline = multilinebaseline
- self._minimumdescent = minimumdescent
-
- def set_text(self, s):
- "Set the text of this area as a string."
- self._text.set_text(s)
- self.stale = True
-
- def get_text(self):
- "Returns the string representation of this area's text"
- return self._text.get_text()
-
- def set_multilinebaseline(self, t):
- """
- Set multilinebaseline .
-
- If True, baseline for multiline text is
- adjusted so that it is (approximatedly) center-aligned with
- singleline text.
- """
- self._multilinebaseline = t
- self.stale = True
-
- def get_multilinebaseline(self):
- """
- get multilinebaseline .
- """
- return self._multilinebaseline
-
- def set_minimumdescent(self, t):
- """
- Set minimumdescent .
-
- If True, extent of the single line text is adjusted so that
- it has minimum descent of "p"
- """
- self._minimumdescent = t
- self.stale = True
-
- def get_minimumdescent(self):
- """
- get minimumdescent.
- """
- return self._minimumdescent
-
- def set_transform(self, t):
- """
- set_transform is ignored.
- """
- pass
-
- def set_offset(self, xy):
- """
- set offset of the container.
-
- Accept : tuple of x,y coordinates in display units.
- """
- self._offset = xy
-
- self.offset_transform.clear()
- self.offset_transform.translate(xy[0], xy[1])
- self.stale = True
-
- def get_offset(self):
- """
- return offset of the container.
- """
- return self._offset
-
- def get_window_extent(self, renderer):
- '''
- get the bounding box in display space.
- '''
- w, h, xd, yd = self.get_extent(renderer)
- ox, oy = self.get_offset() # w, h, xd, yd)
- return mtransforms.Bbox.from_bounds(ox - xd, oy - yd, w, h)
-
- def get_extent(self, renderer):
- clean_line, ismath = self._text.is_math_text(self._text._text)
- _, h_, d_ = renderer.get_text_width_height_descent(
- "lp", self._text._fontproperties, ismath=False)
-
- bbox, info, d = self._text._get_layout(renderer)
- w, h = bbox.width, bbox.height
-
- line = info[-1][0] # last line
-
- self._baseline_transform.clear()
-
- if len(info) > 1 and self._multilinebaseline:
- d_new = 0.5 * h - 0.5 * (h_ - d_)
- self._baseline_transform.translate(0, d - d_new)
- d = d_new
-
- else: # single line
-
- h_d = max(h_ - d_, h - d)
-
- if self.get_minimumdescent():
- ## to have a minimum descent, #i.e., "l" and "p" have same
- ## descents.
- d = max(d, d_)
- #else:
- # d = d
-
- h = h_d + d
-
- return w, h, 0., d
-
- def draw(self, renderer):
- """
- Draw the children
- """
-
- self._text.draw(renderer)
-
- bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
- self.stale = False
-
-
-class AuxTransformBox(OffsetBox):
- """
- Offset Box with the aux_transform . Its children will be
- transformed with the aux_transform first then will be
- offseted. The absolute coordinate of the aux_transform is meaning
- as it will be automatically adjust so that the left-lower corner
- of the bounding box of children will be set to (0,0) before the
- offset transform.
-
- It is similar to drawing area, except that the extent of the box
- is not predetermined but calculated from the window extent of its
- children. Furthermore, the extent of the children will be
- calculated in the transformed coordinate.
- """
- def __init__(self, aux_transform):
- self.aux_transform = aux_transform
- OffsetBox.__init__(self)
-
- self.offset_transform = mtransforms.Affine2D()
- self.offset_transform.clear()
- self.offset_transform.translate(0, 0)
-
- # ref_offset_transform is used to make the offset_transform is
- # always reference to the lower-left corner of the bbox of its
- # children.
- self.ref_offset_transform = mtransforms.Affine2D()
- self.ref_offset_transform.clear()
-
- def add_artist(self, a):
- 'Add any :class:`~matplotlib.artist.Artist` to the container box'
- self._children.append(a)
- a.set_transform(self.get_transform())
- self.stale = True
-
- def get_transform(self):
- """
- Return the :class:`~matplotlib.transforms.Transform` applied
- to the children
- """
- return self.aux_transform + \
- self.ref_offset_transform + \
- self.offset_transform
-
- def set_transform(self, t):
- """
- set_transform is ignored.
- """
- pass
-
- def set_offset(self, xy):
- """
- set offset of the container.
-
- Accept : tuple of x,y coordinate in display units.
- """
- self._offset = xy
-
- self.offset_transform.clear()
- self.offset_transform.translate(xy[0], xy[1])
- self.stale = True
-
- def get_offset(self):
- """
- return offset of the container.
- """
- return self._offset
-
- def get_window_extent(self, renderer):
- '''
- get the bounding box in display space.
- '''
- w, h, xd, yd = self.get_extent(renderer)
- ox, oy = self.get_offset() # w, h, xd, yd)
- return mtransforms.Bbox.from_bounds(ox - xd, oy - yd, w, h)
-
- def get_extent(self, renderer):
-
- # clear the offset transforms
- _off = self.offset_transform.to_values() # to be restored later
- self.ref_offset_transform.clear()
- self.offset_transform.clear()
-
- # calculate the extent
- bboxes = [c.get_window_extent(renderer) for c in self._children]
- ub = mtransforms.Bbox.union(bboxes)
-
- # adjust ref_offset_tansform
- self.ref_offset_transform.translate(-ub.x0, -ub.y0)
-
- # restor offset transform
- mtx = self.offset_transform.matrix_from_values(*_off)
- self.offset_transform.set_matrix(mtx)
-
- return ub.width, ub.height, 0., 0.
-
- def draw(self, renderer):
- """
- Draw the children
- """
-
- for c in self._children:
- c.draw(renderer)
-
- bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
- self.stale = False
-
-
-class AnchoredOffsetbox(OffsetBox):
- """
- An offset box placed according to the legend location
- loc. AnchoredOffsetbox has a single child. When multiple children
- is needed, use other OffsetBox class to enclose them. By default,
- the offset box is anchored against its parent axes. You may
- explicitly specify the bbox_to_anchor.
- """
- zorder = 5 # zorder of the legend
-
- # Location codes
- codes = {'upper right': 1,
- 'upper left': 2,
- 'lower left': 3,
- 'lower right': 4,
- 'right': 5,
- 'center left': 6,
- 'center right': 7,
- 'lower center': 8,
- 'upper center': 9,
- 'center': 10,
- }
-
- def __init__(self, loc,
- pad=0.4, borderpad=0.5,
- child=None, prop=None, frameon=True,
- bbox_to_anchor=None,
- bbox_transform=None,
- **kwargs):
- """
- loc is a string or an integer specifying the legend location.
- The valid location codes are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4,
- 'right' : 5, (same as 'center right', for back-compatibility)
- 'center left' : 6,
- 'center right' : 7,
- 'lower center' : 8,
- 'upper center' : 9,
- 'center' : 10,
-
- pad : pad around the child for drawing a frame. given in
- fraction of fontsize.
-
- borderpad : pad between offsetbox frame and the bbox_to_anchor,
-
- child : OffsetBox instance that will be anchored.
-
- prop : font property. This is only used as a reference for paddings.
-
- frameon : draw a frame box if True.
-
- bbox_to_anchor : bbox to anchor. Use self.axes.bbox if None.
-
- bbox_transform : with which the bbox_to_anchor will be transformed.
-
- """
- super(AnchoredOffsetbox, self).__init__(**kwargs)
-
- self.set_bbox_to_anchor(bbox_to_anchor, bbox_transform)
- self.set_child(child)
-
- if isinstance(loc, six.string_types):
- try:
- loc = self.codes[loc]
- except KeyError:
- raise ValueError('Unrecognized location "%s". Valid '
- 'locations are\n\t%s\n'
- % (loc, '\n\t'.join(self.codes)))
-
- self.loc = loc
- self.borderpad = borderpad
- self.pad = pad
-
- if prop is None:
- self.prop = FontProperties(size=rcParams["legend.fontsize"])
- elif isinstance(prop, dict):
- self.prop = FontProperties(**prop)
- if "size" not in prop:
- self.prop.set_size(rcParams["legend.fontsize"])
- else:
- self.prop = prop
-
- self.patch = FancyBboxPatch(
- xy=(0.0, 0.0), width=1., height=1.,
- facecolor='w', edgecolor='k',
- mutation_scale=self.prop.get_size_in_points(),
- snap=True
- )
- self.patch.set_boxstyle("square", pad=0)
- self._drawFrame = frameon
-
- def set_child(self, child):
- "set the child to be anchored"
- self._child = child
- if child is not None:
- child.axes = self.axes
- self.stale = True
-
- def get_child(self):
- "return the child"
- return self._child
-
- def get_children(self):
- "return the list of children"
- return [self._child]
-
- def get_extent(self, renderer):
- """
- return the extent of the artist. The extent of the child
- added with the pad is returned
- """
- w, h, xd, yd = self.get_child().get_extent(renderer)
- fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
- pad = self.pad * fontsize
-
- return w + 2 * pad, h + 2 * pad, xd + pad, yd + pad
-
- def get_bbox_to_anchor(self):
- """
- return the bbox that the legend will be anchored
- """
- if self._bbox_to_anchor is None:
- return self.axes.bbox
- else:
- transform = self._bbox_to_anchor_transform
- if transform is None:
- return self._bbox_to_anchor
- else:
- return TransformedBbox(self._bbox_to_anchor,
- transform)
-
- def set_bbox_to_anchor(self, bbox, transform=None):
- """
- set the bbox that the child will be anchored.
-
- *bbox* can be a Bbox instance, a list of [left, bottom, width,
- height], or a list of [left, bottom] where the width and
- height will be assumed to be zero. The bbox will be
- transformed to display coordinate by the given transform.
- """
- if bbox is None or isinstance(bbox, BboxBase):
- self._bbox_to_anchor = bbox
- else:
- try:
- l = len(bbox)
- except TypeError:
- raise ValueError("Invalid argument for bbox : %s" % str(bbox))
-
- if l == 2:
- bbox = [bbox[0], bbox[1], 0, 0]
-
- self._bbox_to_anchor = Bbox.from_bounds(*bbox)
-
- self._bbox_to_anchor_transform = transform
- self.stale = True
-
- def get_window_extent(self, renderer):
- '''
- get the bounding box in display space.
- '''
- self._update_offset_func(renderer)
- w, h, xd, yd = self.get_extent(renderer)
- ox, oy = self.get_offset(w, h, xd, yd, renderer)
- return Bbox.from_bounds(ox - xd, oy - yd, w, h)
-
- def _update_offset_func(self, renderer, fontsize=None):
- """
- Update the offset func which depends on the dpi of the
- renderer (because of the padding).
- """
- if fontsize is None:
- fontsize = renderer.points_to_pixels(
- self.prop.get_size_in_points())
-
- def _offset(w, h, xd, yd, renderer, fontsize=fontsize, self=self):
- bbox = Bbox.from_bounds(0, 0, w, h)
- borderpad = self.borderpad * fontsize
- bbox_to_anchor = self.get_bbox_to_anchor()
-
- x0, y0 = self._get_anchored_bbox(self.loc,
- bbox,
- bbox_to_anchor,
- borderpad)
- return x0 + xd, y0 + yd
-
- self.set_offset(_offset)
-
- def update_frame(self, bbox, fontsize=None):
- self.patch.set_bounds(bbox.x0, bbox.y0,
- bbox.width, bbox.height)
-
- if fontsize:
- self.patch.set_mutation_scale(fontsize)
-
- def draw(self, renderer):
- "draw the artist"
-
- if not self.get_visible():
- return
-
- fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
- self._update_offset_func(renderer, fontsize)
-
- if self._drawFrame:
- # update the location and size of the legend
- bbox = self.get_window_extent(renderer)
- self.update_frame(bbox, fontsize)
- self.patch.draw(renderer)
-
- width, height, xdescent, ydescent = self.get_extent(renderer)
-
- px, py = self.get_offset(width, height, xdescent, ydescent, renderer)
-
- self.get_child().set_offset((px, py))
- self.get_child().draw(renderer)
- self.stale = False
-
- def _get_anchored_bbox(self, loc, bbox, parentbbox, borderpad):
- """
- return the position of the bbox anchored at the parentbbox
- with the loc code, with the borderpad.
- """
- assert loc in range(1, 11) # called only internally
-
- BEST, UR, UL, LL, LR, R, CL, CR, LC, UC, C = xrange(11)
-
- anchor_coefs = {UR: "NE",
- UL: "NW",
- LL: "SW",
- LR: "SE",
- R: "E",
- CL: "W",
- CR: "E",
- LC: "S",
- UC: "N",
- C: "C"}
-
- c = anchor_coefs[loc]
-
- container = parentbbox.padded(-borderpad)
- anchored_box = bbox.anchored(c, container=container)
- return anchored_box.x0, anchored_box.y0
-
-
-class AnchoredText(AnchoredOffsetbox):
- """
- AnchoredOffsetbox with Text.
- """
-
- def __init__(self, s, loc, pad=0.4, borderpad=0.5, prop=None, **kwargs):
- """
- Parameters
- ----------
- s : string
- Text.
-
- loc : str
- Location code.
-
- pad : float, optional
- Pad between the text and the frame as fraction of the font
- size.
-
- borderpad : float, optional
- Pad between the frame and the axes (or *bbox_to_anchor*).
-
- prop : `matplotlib.font_manager.FontProperties`
- Font properties.
-
- Notes
- -----
- Other keyword parameters of `AnchoredOffsetbox` are also
- allowed.
- """
-
- if prop is None:
- prop = {}
- badkwargs = {'ha', 'horizontalalignment', 'va', 'verticalalignment'}
- if badkwargs & set(prop):
- warnings.warn("Mixing horizontalalignment or verticalalignment "
- "with AnchoredText is not supported.")
-
- self.txt = TextArea(s, textprops=prop, minimumdescent=False)
- fp = self.txt._text.get_fontproperties()
- super(AnchoredText, self).__init__(
- loc, pad=pad, borderpad=borderpad, child=self.txt, prop=fp,
- **kwargs)
-
-
-class OffsetImage(OffsetBox):
- def __init__(self, arr,
- zoom=1,
- cmap=None,
- norm=None,
- interpolation=None,
- origin=None,
- filternorm=1,
- filterrad=4.0,
- resample=False,
- dpi_cor=True,
- **kwargs
- ):
-
- OffsetBox.__init__(self)
- self._dpi_cor = dpi_cor
-
- self.image = BboxImage(bbox=self.get_window_extent,
- cmap=cmap,
- norm=norm,
- interpolation=interpolation,
- origin=origin,
- filternorm=filternorm,
- filterrad=filterrad,
- resample=resample,
- **kwargs
- )
-
- self._children = [self.image]
-
- self.set_zoom(zoom)
- self.set_data(arr)
-
- def set_data(self, arr):
- self._data = np.asarray(arr)
- self.image.set_data(self._data)
- self.stale = True
-
- def get_data(self):
- return self._data
-
- def set_zoom(self, zoom):
- self._zoom = zoom
- self.stale = True
-
- def get_zoom(self):
- return self._zoom
-
-# def set_axes(self, axes):
-# self.image.set_axes(axes)
-# martist.Artist.set_axes(self, axes)
-
-# def set_offset(self, xy):
-# """
-# set offset of the container.
-
-# Accept : tuple of x,y coordinate in display units.
-# """
-# self._offset = xy
-
-# self.offset_transform.clear()
-# self.offset_transform.translate(xy[0], xy[1])
-
- def get_offset(self):
- """
- return offset of the container.
- """
- return self._offset
-
- def get_children(self):
- return [self.image]
-
- def get_window_extent(self, renderer):
- '''
- get the bounding box in display space.
- '''
- w, h, xd, yd = self.get_extent(renderer)
- ox, oy = self.get_offset()
- return mtransforms.Bbox.from_bounds(ox - xd, oy - yd, w, h)
-
- def get_extent(self, renderer):
- if self._dpi_cor: # True, do correction
- dpi_cor = renderer.points_to_pixels(1.)
- else:
- dpi_cor = 1.
-
- zoom = self.get_zoom()
- data = self.get_data()
- ny, nx = data.shape[:2]
- w, h = dpi_cor * nx * zoom, dpi_cor * ny * zoom
-
- return w, h, 0, 0
-
- def draw(self, renderer):
- """
- Draw the children
- """
- self.image.draw(renderer)
- # bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
- self.stale = False
-
-
-class AnnotationBbox(martist.Artist, _AnnotationBase):
- """
- Annotation-like class, but with offsetbox instead of Text.
- """
- zorder = 3
-
- def __str__(self):
- return "AnnotationBbox(%g,%g)" % (self.xy[0], self.xy[1])
-
- @docstring.dedent_interpd
- def __init__(self, offsetbox, xy,
- xybox=None,
- xycoords='data',
- boxcoords=None,
- frameon=True, pad=0.4, # BboxPatch
- annotation_clip=None,
- box_alignment=(0.5, 0.5),
- bboxprops=None,
- arrowprops=None,
- fontsize=None,
- **kwargs):
- """
- *offsetbox* : OffsetBox instance
-
- *xycoords* : same as Annotation but can be a tuple of two
- strings which are interpreted as x and y coordinates.
-
- *boxcoords* : similar to textcoords as Annotation but can be a
- tuple of two strings which are interpreted as x and y
- coordinates.
-
- *box_alignment* : a tuple of two floats for a vertical and
- horizontal alignment of the offset box w.r.t. the *boxcoords*.
- The lower-left corner is (0.0) and upper-right corner is (1.1).
-
- other parameters are identical to that of Annotation.
- """
-
- martist.Artist.__init__(self, **kwargs)
- _AnnotationBase.__init__(self,
- xy,
- xycoords=xycoords,
- annotation_clip=annotation_clip)
-
- self.offsetbox = offsetbox
-
- self.arrowprops = arrowprops
-
- self.set_fontsize(fontsize)
-
- if xybox is None:
- self.xybox = xy
- else:
- self.xybox = xybox
-
- if boxcoords is None:
- self.boxcoords = xycoords
- else:
- self.boxcoords = boxcoords
-
- if arrowprops is not None:
- self._arrow_relpos = self.arrowprops.pop("relpos", (0.5, 0.5))
- self.arrow_patch = FancyArrowPatch((0, 0), (1, 1),
- **self.arrowprops)
- else:
- self._arrow_relpos = None
- self.arrow_patch = None
-
- #self._fw, self._fh = 0., 0. # for alignment
- self._box_alignment = box_alignment
-
- # frame
- self.patch = FancyBboxPatch(
- xy=(0.0, 0.0), width=1., height=1.,
- facecolor='w', edgecolor='k',
- mutation_scale=self.prop.get_size_in_points(),
- snap=True
- )
- self.patch.set_boxstyle("square", pad=pad)
- if bboxprops:
- self.patch.set(**bboxprops)
- self._drawFrame = frameon
-
- @property
- def xyann(self):
- return self.xybox
-
- @xyann.setter
- def xyann(self, xyann):
- self.xybox = xyann
- self.stale = True
-
- @property
- def anncoords(self):
- return self.boxcoords
-
- @anncoords.setter
- def anncoords(self, coords):
- self.boxcoords = coords
- self.stale = True
-
- def contains(self, event):
- t, tinfo = self.offsetbox.contains(event)
- #if self.arrow_patch is not None:
- # a,ainfo=self.arrow_patch.contains(event)
- # t = t or a
-
- # self.arrow_patch is currently not checked as this can be a line - JJ
-
- return t, tinfo
-
- def get_children(self):
- children = [self.offsetbox, self.patch]
- if self.arrow_patch:
- children.append(self.arrow_patch)
- return children
-
- def set_figure(self, fig):
-
- if self.arrow_patch is not None:
- self.arrow_patch.set_figure(fig)
- self.offsetbox.set_figure(fig)
- martist.Artist.set_figure(self, fig)
-
- def set_fontsize(self, s=None):
- """
- set fontsize in points
- """
- if s is None:
- s = rcParams["legend.fontsize"]
-
- self.prop = FontProperties(size=s)
- self.stale = True
-
- def get_fontsize(self, s=None):
- """
- return fontsize in points
- """
- return self.prop.get_size_in_points()
-
- def update_positions(self, renderer):
- """
- Update the pixel positions of the annotated point and the text.
- """
- xy_pixel = self._get_position_xy(renderer)
- self._update_position_xybox(renderer, xy_pixel)
-
- mutation_scale = renderer.points_to_pixels(self.get_fontsize())
- self.patch.set_mutation_scale(mutation_scale)
-
- if self.arrow_patch:
- self.arrow_patch.set_mutation_scale(mutation_scale)
-
- def _update_position_xybox(self, renderer, xy_pixel):
- """
- Update the pixel positions of the annotation text and the arrow
- patch.
- """
-
- x, y = self.xybox
- if isinstance(self.boxcoords, tuple):
- xcoord, ycoord = self.boxcoords
- x1, y1 = self._get_xy(renderer, x, y, xcoord)
- x2, y2 = self._get_xy(renderer, x, y, ycoord)
- ox0, oy0 = x1, y2
- else:
- ox0, oy0 = self._get_xy(renderer, x, y, self.boxcoords)
-
- w, h, xd, yd = self.offsetbox.get_extent(renderer)
-
- _fw, _fh = self._box_alignment
- self.offsetbox.set_offset((ox0 - _fw * w + xd, oy0 - _fh * h + yd))
-
- # update patch position
- bbox = self.offsetbox.get_window_extent(renderer)
- #self.offsetbox.set_offset((ox0-_fw*w, oy0-_fh*h))
- self.patch.set_bounds(bbox.x0, bbox.y0,
- bbox.width, bbox.height)
-
- x, y = xy_pixel
-
- ox1, oy1 = x, y
-
- if self.arrowprops:
- x0, y0 = x, y
-
- d = self.arrowprops.copy()
-
- # Use FancyArrowPatch if self.arrowprops has "arrowstyle" key.
-
- # adjust the starting point of the arrow relative to
- # the textbox.
- # TODO : Rotation needs to be accounted.
- relpos = self._arrow_relpos
-
- ox0 = bbox.x0 + bbox.width * relpos[0]
- oy0 = bbox.y0 + bbox.height * relpos[1]
-
- # The arrow will be drawn from (ox0, oy0) to (ox1,
- # oy1). It will be first clipped by patchA and patchB.
- # Then it will be shrunk by shrinkA and shrinkB
- # (in points). If patch A is not set, self.bbox_patch
- # is used.
-
- self.arrow_patch.set_positions((ox0, oy0), (ox1, oy1))
- fs = self.prop.get_size_in_points()
- mutation_scale = d.pop("mutation_scale", fs)
- mutation_scale = renderer.points_to_pixels(mutation_scale)
- self.arrow_patch.set_mutation_scale(mutation_scale)
-
- patchA = d.pop("patchA", self.patch)
- self.arrow_patch.set_patchA(patchA)
-
- def draw(self, renderer):
- """
- Draw the :class:`Annotation` object to the given *renderer*.
- """
-
- if renderer is not None:
- self._renderer = renderer
- if not self.get_visible():
- return
-
- xy_pixel = self._get_position_xy(renderer)
-
- if not self._check_xy(renderer, xy_pixel):
- return
-
- self.update_positions(renderer)
-
- if self.arrow_patch is not None:
- if self.arrow_patch.figure is None and self.figure is not None:
- self.arrow_patch.figure = self.figure
- self.arrow_patch.draw(renderer)
-
- if self._drawFrame:
- self.patch.draw(renderer)
-
- self.offsetbox.draw(renderer)
- self.stale = False
-
-
-class DraggableBase(object):
- """
- helper code for a draggable artist (legend, offsetbox)
- The derived class must override following two method.
-
- def save_offset(self):
- pass
-
- def update_offset(self, dx, dy):
- pass
-
- *save_offset* is called when the object is picked for dragging and it
- is meant to save reference position of the artist.
-
- *update_offset* is called during the dragging. dx and dy is the pixel
- offset from the point where the mouse drag started.
-
- Optionally you may override following two methods.
-
- def artist_picker(self, artist, evt):
- return self.ref_artist.contains(evt)
-
- def finalize_offset(self):
- pass
-
- *artist_picker* is a picker method that will be
- used. *finalize_offset* is called when the mouse is released. In
- current implementation of DraggableLegend and DraggableAnnotation,
- *update_offset* places the artists simply in display
- coordinates. And *finalize_offset* recalculate their position in
- the normalized axes coordinate and set a relavant attribute.
-
- """
- def __init__(self, ref_artist, use_blit=False):
- self.ref_artist = ref_artist
- self.got_artist = False
-
- self.canvas = self.ref_artist.figure.canvas
- self._use_blit = use_blit and self.canvas.supports_blit
-
- c2 = self.canvas.mpl_connect('pick_event', self.on_pick)
- c3 = self.canvas.mpl_connect('button_release_event', self.on_release)
-
- ref_artist.set_picker(self.artist_picker)
- self.cids = [c2, c3]
-
- def on_motion(self, evt):
- if self.got_artist:
- dx = evt.x - self.mouse_x
- dy = evt.y - self.mouse_y
- self.update_offset(dx, dy)
- self.canvas.draw()
-
- def on_motion_blit(self, evt):
- if self.got_artist:
- dx = evt.x - self.mouse_x
- dy = evt.y - self.mouse_y
- self.update_offset(dx, dy)
- self.canvas.restore_region(self.background)
- self.ref_artist.draw(self.ref_artist.figure._cachedRenderer)
- self.canvas.blit(self.ref_artist.figure.bbox)
-
- def on_pick(self, evt):
- if evt.artist == self.ref_artist:
-
- self.mouse_x = evt.mouseevent.x
- self.mouse_y = evt.mouseevent.y
- self.got_artist = True
-
- if self._use_blit:
- self.ref_artist.set_animated(True)
- self.canvas.draw()
- self.background = self.canvas.copy_from_bbox(
- self.ref_artist.figure.bbox)
- self.ref_artist.draw(self.ref_artist.figure._cachedRenderer)
- self.canvas.blit(self.ref_artist.figure.bbox)
- self._c1 = self.canvas.mpl_connect('motion_notify_event',
- self.on_motion_blit)
- else:
- self._c1 = self.canvas.mpl_connect('motion_notify_event',
- self.on_motion)
- self.save_offset()
-
- def on_release(self, event):
- if self.got_artist:
- self.finalize_offset()
- self.got_artist = False
- self.canvas.mpl_disconnect(self._c1)
-
- if self._use_blit:
- self.ref_artist.set_animated(False)
-
- def disconnect(self):
- """disconnect the callbacks"""
- for cid in self.cids:
- self.canvas.mpl_disconnect(cid)
- try:
- c1 = self._c1
- except AttributeError:
- pass
- else:
- self.canvas.mpl_disconnect(c1)
-
- def artist_picker(self, artist, evt):
- return self.ref_artist.contains(evt)
-
- def save_offset(self):
- pass
-
- def update_offset(self, dx, dy):
- pass
-
- def finalize_offset(self):
- pass
-
-
-class DraggableOffsetBox(DraggableBase):
- def __init__(self, ref_artist, offsetbox, use_blit=False):
- DraggableBase.__init__(self, ref_artist, use_blit=use_blit)
- self.offsetbox = offsetbox
-
- def save_offset(self):
- offsetbox = self.offsetbox
- renderer = offsetbox.figure._cachedRenderer
- w, h, xd, yd = offsetbox.get_extent(renderer)
- offset = offsetbox.get_offset(w, h, xd, yd, renderer)
- self.offsetbox_x, self.offsetbox_y = offset
- self.offsetbox.set_offset(offset)
-
- def update_offset(self, dx, dy):
- loc_in_canvas = self.offsetbox_x + dx, self.offsetbox_y + dy
- self.offsetbox.set_offset(loc_in_canvas)
-
- def get_loc_in_canvas(self):
-
- offsetbox = self.offsetbox
- renderer = offsetbox.figure._cachedRenderer
- w, h, xd, yd = offsetbox.get_extent(renderer)
- ox, oy = offsetbox._offset
- loc_in_canvas = (ox - xd, oy - yd)
-
- return loc_in_canvas
-
-
-class DraggableAnnotation(DraggableBase):
- def __init__(self, annotation, use_blit=False):
- DraggableBase.__init__(self, annotation, use_blit=use_blit)
- self.annotation = annotation
-
- def save_offset(self):
- ann = self.annotation
- self.ox, self.oy = ann.get_transform().transform(ann.xyann)
-
- def update_offset(self, dx, dy):
- ann = self.annotation
- ann.xyann = ann.get_transform().inverted().transform(
- (self.ox + dx, self.oy + dy))
-
-
-if __name__ == "__main__":
- import matplotlib.pyplot as plt
- fig = plt.figure(1)
- fig.clf()
- ax = plt.subplot(121)
-
- #txt = ax.text(0.5, 0.5, "Test", size=30, ha="center", color="w")
- kwargs = dict()
-
- a = np.arange(256).reshape(16, 16) / 256.
- myimage = OffsetImage(a,
- zoom=2,
- norm=None,
- origin=None,
- **kwargs
- )
- ax.add_artist(myimage)
-
- myimage.set_offset((100, 100))
-
- myimage2 = OffsetImage(a,
- zoom=2,
- norm=None,
- origin=None,
- **kwargs
- )
- ann = AnnotationBbox(myimage2, (0.5, 0.5),
- xybox=(30, 30),
- xycoords='data',
- boxcoords="offset points",
- frameon=True, pad=0.4, # BboxPatch
- bboxprops=dict(boxstyle="round", fc="y"),
- fontsize=None,
- arrowprops=dict(arrowstyle="->"),
- )
-
- ax.add_artist(ann)
-
- plt.draw()
- plt.show()
diff --git a/contrib/python/matplotlib/py2/matplotlib/patches.py b/contrib/python/matplotlib/py2/matplotlib/patches.py
deleted file mode 100644
index 1d66125561..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/patches.py
+++ /dev/null
@@ -1,4720 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import map, zip
-
-import math
-import warnings
-
-import numpy as np
-
-import matplotlib as mpl
-from . import artist, cbook, colors, docstring, lines as mlines, transforms
-from .bezier import (
- concatenate_paths, get_cos_sin, get_intersection, get_parallels,
- inside_circle, make_path_regular, make_wedged_bezier2,
- split_bezier_intersecting_with_closedpath, split_path_inout)
-from .path import Path
-
-_patch_alias_map = {
- 'antialiased': ['aa'],
- 'edgecolor': ['ec'],
- 'facecolor': ['fc'],
- 'linewidth': ['lw'],
- 'linestyle': ['ls']
- }
-
-
-class Patch(artist.Artist):
- """
- A patch is a 2D artist with a face color and an edge color.
-
- If any of *edgecolor*, *facecolor*, *linewidth*, or *antialiased*
- are *None*, they default to their rc params setting.
- """
- zorder = 1
- validCap = ('butt', 'round', 'projecting')
- validJoin = ('miter', 'round', 'bevel')
-
- # Whether to draw an edge by default. Set on a
- # subclass-by-subclass basis.
- _edge_default = False
-
- def __str__(self):
- return str(self.__class__).split('.')[-1]
-
- def __init__(self,
- edgecolor=None,
- facecolor=None,
- color=None,
- linewidth=None,
- linestyle=None,
- antialiased=None,
- hatch=None,
- fill=True,
- capstyle=None,
- joinstyle=None,
- **kwargs):
- """
- The following kwarg properties are supported
-
- %(Patch)s
- """
- artist.Artist.__init__(self)
-
- if linewidth is None:
- linewidth = mpl.rcParams['patch.linewidth']
- if linestyle is None:
- linestyle = "solid"
- if capstyle is None:
- capstyle = 'butt'
- if joinstyle is None:
- joinstyle = 'miter'
- if antialiased is None:
- antialiased = mpl.rcParams['patch.antialiased']
-
- self._hatch_color = colors.to_rgba(mpl.rcParams['hatch.color'])
- self._fill = True # needed for set_facecolor call
- if color is not None:
- if (edgecolor is not None or facecolor is not None):
- warnings.warn("Setting the 'color' property will override"
- "the edgecolor or facecolor properties. ")
- self.set_color(color)
- else:
- self.set_edgecolor(edgecolor)
- self.set_facecolor(facecolor)
- # unscaled dashes. Needed to scale dash patterns by lw
- self._us_dashes = None
- self._linewidth = 0
-
- self.set_fill(fill)
- self.set_linestyle(linestyle)
- self.set_linewidth(linewidth)
- self.set_antialiased(antialiased)
- self.set_hatch(hatch)
- self.set_capstyle(capstyle)
- self.set_joinstyle(joinstyle)
- self._combined_transform = transforms.IdentityTransform()
-
- if len(kwargs):
- self.update(kwargs)
-
- def get_verts(self):
- """
- Return a copy of the vertices used in this patch
-
- If the patch contains Bezier curves, the curves will be
- interpolated by line segments. To access the curves as
- curves, use :meth:`get_path`.
- """
- trans = self.get_transform()
- path = self.get_path()
- polygons = path.to_polygons(trans)
- if len(polygons):
- return polygons[0]
- return []
-
- def _process_radius(self, radius):
- if radius is not None:
- return radius
- if cbook.is_numlike(self._picker):
- _radius = self._picker
- else:
- if self.get_edgecolor()[3] == 0:
- _radius = 0
- else:
- _radius = self.get_linewidth()
- return _radius
-
- def contains(self, mouseevent, radius=None):
- """Test whether the mouse event occurred in the patch.
-
- Returns T/F, {}
- """
- if callable(self._contains):
- return self._contains(self, mouseevent)
- radius = self._process_radius(radius)
- inside = self.get_path().contains_point(
- (mouseevent.x, mouseevent.y), self.get_transform(), radius)
- return inside, {}
-
- def contains_point(self, point, radius=None):
- """
- Returns ``True`` if the given *point* is inside the path
- (transformed with its transform attribute).
-
- *radius* allows the path to be made slightly larger or smaller.
- """
- radius = self._process_radius(radius)
- return self.get_path().contains_point(point,
- self.get_transform(),
- radius)
-
- def contains_points(self, points, radius=None):
- """
- Returns a bool array which is ``True`` if the (closed) path
- contains the corresponding point.
- (transformed with its transform attribute).
-
- *points* must be Nx2 array.
- *radius* allows the path to be made slightly larger or smaller.
- """
- radius = self._process_radius(radius)
- return self.get_path().contains_points(points,
- self.get_transform(),
- radius)
-
- def update_from(self, other):
- """
- Updates this :class:`Patch` from the properties of *other*.
- """
- artist.Artist.update_from(self, other)
- # For some properties we don't need or don't want to go through the
- # getters/setters, so we just copy them directly.
- self._edgecolor = other._edgecolor
- self._facecolor = other._facecolor
- self._fill = other._fill
- self._hatch = other._hatch
- self._hatch_color = other._hatch_color
- # copy the unscaled dash pattern
- self._us_dashes = other._us_dashes
- self.set_linewidth(other._linewidth) # also sets dash properties
- self.set_transform(other.get_data_transform())
-
- def get_extents(self):
- """
- Return a :class:`~matplotlib.transforms.Bbox` object defining
- the axis-aligned extents of the :class:`Patch`.
- """
- return self.get_path().get_extents(self.get_transform())
-
- def get_transform(self):
- """
- Return the :class:`~matplotlib.transforms.Transform` applied
- to the :class:`Patch`.
- """
- return self.get_patch_transform() + artist.Artist.get_transform(self)
-
- def get_data_transform(self):
- """
- Return the :class:`~matplotlib.transforms.Transform` instance which
- maps data coordinates to physical coordinates.
- """
- return artist.Artist.get_transform(self)
-
- def get_patch_transform(self):
- """
- Return the :class:`~matplotlib.transforms.Transform` instance which
- takes patch coordinates to data coordinates.
-
- For example, one may define a patch of a circle which represents a
- radius of 5 by providing coordinates for a unit circle, and a
- transform which scales the coordinates (the patch coordinate) by 5.
- """
- return transforms.IdentityTransform()
-
- def get_antialiased(self):
- """
- Returns True if the :class:`Patch` is to be drawn with antialiasing.
- """
- return self._antialiased
- get_aa = get_antialiased
-
- def get_edgecolor(self):
- """
- Return the edge color of the :class:`Patch`.
- """
- return self._edgecolor
- get_ec = get_edgecolor
-
- def get_facecolor(self):
- """
- Return the face color of the :class:`Patch`.
- """
- return self._facecolor
- get_fc = get_facecolor
-
- def get_linewidth(self):
- """
- Return the line width in points.
- """
- return self._linewidth
- get_lw = get_linewidth
-
- def get_linestyle(self):
- """
- Return the linestyle. Will be one of ['solid' | 'dashed' |
- 'dashdot' | 'dotted']
- """
- return self._linestyle
- get_ls = get_linestyle
-
- def set_antialiased(self, aa):
- """
- Set whether to use antialiased rendering.
-
- Parameters
- ----------
- b : bool or None
- .. ACCEPTS: bool or None
- """
- if aa is None:
- aa = mpl.rcParams['patch.antialiased']
- self._antialiased = aa
- self.stale = True
-
- def set_aa(self, aa):
- """alias for set_antialiased"""
- return self.set_antialiased(aa)
-
- def _set_edgecolor(self, color):
- set_hatch_color = True
- if color is None:
- if (mpl.rcParams['patch.force_edgecolor'] or
- not self._fill or self._edge_default):
- color = mpl.rcParams['patch.edgecolor']
- else:
- color = 'none'
- set_hatch_color = False
-
- self._edgecolor = colors.to_rgba(color, self._alpha)
- if set_hatch_color:
- self._hatch_color = self._edgecolor
- self.stale = True
-
- def set_edgecolor(self, color):
- """
- Set the patch edge color
-
- ACCEPTS: mpl color spec, None, 'none', or 'auto'
- """
- self._original_edgecolor = color
- self._set_edgecolor(color)
-
- def set_ec(self, color):
- """alias for set_edgecolor"""
- return self.set_edgecolor(color)
-
- def _set_facecolor(self, color):
- if color is None:
- color = mpl.rcParams['patch.facecolor']
- alpha = self._alpha if self._fill else 0
- self._facecolor = colors.to_rgba(color, alpha)
- self.stale = True
-
- def set_facecolor(self, color):
- """
- Set the patch face color
-
- ACCEPTS: mpl color spec, or None for default, or 'none' for no color
- """
- self._original_facecolor = color
- self._set_facecolor(color)
-
- def set_fc(self, color):
- """alias for set_facecolor"""
- return self.set_facecolor(color)
-
- def set_color(self, c):
- """
- Set both the edgecolor and the facecolor.
-
- ACCEPTS: matplotlib color spec
-
- .. seealso::
-
- :meth:`set_facecolor`, :meth:`set_edgecolor`
- For setting the edge or face color individually.
- """
- self.set_facecolor(c)
- self.set_edgecolor(c)
-
- def set_alpha(self, alpha):
- """
- Set the alpha tranparency of the patch.
-
- ACCEPTS: float or None
- """
- if alpha is not None:
- try:
- float(alpha)
- except TypeError:
- raise TypeError('alpha must be a float or None')
- artist.Artist.set_alpha(self, alpha)
- self._set_facecolor(self._original_facecolor)
- self._set_edgecolor(self._original_edgecolor)
- # stale is already True
-
- def set_linewidth(self, w):
- """
- Set the patch linewidth in points
-
- ACCEPTS: float or None for default
- """
- if w is None:
- w = mpl.rcParams['patch.linewidth']
- if w is None:
- w = mpl.rcParams['axes.linewidth']
-
- self._linewidth = float(w)
- # scale the dash pattern by the linewidth
- offset, ls = self._us_dashes
- self._dashoffset, self._dashes = mlines._scale_dashes(
- offset, ls, self._linewidth)
- self.stale = True
-
- def set_lw(self, lw):
- """alias for set_linewidth"""
- return self.set_linewidth(lw)
-
- def set_linestyle(self, ls):
- """
- Set the patch linestyle
-
- =========================== =================
- linestyle description
- =========================== =================
- ``'-'`` or ``'solid'`` solid line
- ``'--'`` or ``'dashed'`` dashed line
- ``'-.'`` or ``'dashdot'`` dash-dotted line
- ``':'`` or ``'dotted'`` dotted line
- =========================== =================
-
- Alternatively a dash tuple of the following form can be provided::
-
- (offset, onoffseq),
-
- where ``onoffseq`` is an even length tuple of on and off ink
- in points.
-
- ACCEPTS: ['solid' | 'dashed', 'dashdot', 'dotted' |
- (offset, on-off-dash-seq) |
- ``'-'`` | ``'--'`` | ``'-.'`` | ``':'`` | ``'None'`` |
- ``' '`` | ``''``]
-
- Parameters
- ----------
- ls : { '-', '--', '-.', ':'} and more see description
- The line style.
- """
- if ls is None:
- ls = "solid"
- self._linestyle = ls
- # get the unscalled dash pattern
- offset, ls = self._us_dashes = mlines._get_dash_pattern(ls)
- # scale the dash pattern by the linewidth
- self._dashoffset, self._dashes = mlines._scale_dashes(
- offset, ls, self._linewidth)
- self.stale = True
-
- def set_ls(self, ls):
- """alias for set_linestyle"""
- return self.set_linestyle(ls)
-
- def set_fill(self, b):
- """
- Set whether to fill the patch.
-
- Parameters
- ----------
- b : bool
- .. ACCEPTS: bool
- """
- self._fill = bool(b)
- self._set_facecolor(self._original_facecolor)
- self._set_edgecolor(self._original_edgecolor)
- self.stale = True
-
- def get_fill(self):
- 'return whether fill is set'
- return self._fill
-
- # Make fill a property so as to preserve the long-standing
- # but somewhat inconsistent behavior in which fill was an
- # attribute.
- fill = property(get_fill, set_fill)
-
- def set_capstyle(self, s):
- """
- Set the patch capstyle
-
- ACCEPTS: ['butt' | 'round' | 'projecting']
- """
- s = s.lower()
- if s not in self.validCap:
- raise ValueError('set_capstyle passed "%s";\n' % (s,) +
- 'valid capstyles are %s' % (self.validCap,))
- self._capstyle = s
- self.stale = True
-
- def get_capstyle(self):
- "Return the current capstyle"
- return self._capstyle
-
- def set_joinstyle(self, s):
- """
- Set the patch joinstyle
-
- ACCEPTS: ['miter' | 'round' | 'bevel']
- """
- s = s.lower()
- if s not in self.validJoin:
- raise ValueError('set_joinstyle passed "%s";\n' % (s,) +
- 'valid joinstyles are %s' % (self.validJoin,))
- self._joinstyle = s
- self.stale = True
-
- def get_joinstyle(self):
- "Return the current joinstyle"
- return self._joinstyle
-
- def set_hatch(self, hatch):
- """
- Set the hatching pattern
-
- *hatch* can be one of::
-
- / - diagonal hatching
- \\ - back diagonal
- | - vertical
- - - horizontal
- + - crossed
- x - crossed diagonal
- o - small circle
- O - large circle
- . - dots
- * - stars
-
- Letters can be combined, in which case all the specified
- hatchings are done. If same letter repeats, it increases the
- density of hatching of that pattern.
-
- Hatching is supported in the PostScript, PDF, SVG and Agg
- backends only.
-
- ACCEPTS: ['/' | '\\\\' | '|' | '-' | '+' | 'x' | 'o' | 'O' | '.' | '*']
- """
- self._hatch = hatch
- self.stale = True
-
- def get_hatch(self):
- 'Return the current hatching pattern'
- return self._hatch
-
- @artist.allow_rasterization
- def draw(self, renderer):
- 'Draw the :class:`Patch` to the given *renderer*.'
- if not self.get_visible():
- return
-
- renderer.open_group('patch', self.get_gid())
- gc = renderer.new_gc()
-
- gc.set_foreground(self._edgecolor, isRGBA=True)
-
- lw = self._linewidth
- if self._edgecolor[3] == 0:
- lw = 0
- gc.set_linewidth(lw)
- gc.set_dashes(0, self._dashes)
- gc.set_capstyle(self._capstyle)
- gc.set_joinstyle(self._joinstyle)
-
- gc.set_antialiased(self._antialiased)
- self._set_gc_clip(gc)
- gc.set_url(self._url)
- gc.set_snap(self.get_snap())
-
- rgbFace = self._facecolor
- if rgbFace[3] == 0:
- rgbFace = None # (some?) renderers expect this as no-fill signal
-
- gc.set_alpha(self._alpha)
-
- if self._hatch:
- gc.set_hatch(self._hatch)
- try:
- gc.set_hatch_color(self._hatch_color)
- except AttributeError:
- # if we end up with a GC that does not have this method
- warnings.warn("Your backend does not have support for "
- "setting the hatch color.")
-
- if self.get_sketch_params() is not None:
- gc.set_sketch_params(*self.get_sketch_params())
-
- path = self.get_path()
- transform = self.get_transform()
- tpath = transform.transform_path_non_affine(path)
- affine = transform.get_affine()
-
- if self.get_path_effects():
- from matplotlib.patheffects import PathEffectRenderer
- renderer = PathEffectRenderer(self.get_path_effects(), renderer)
-
- renderer.draw_path(gc, tpath, affine, rgbFace)
-
- gc.restore()
- renderer.close_group('patch')
- self.stale = False
-
- def get_path(self):
- """
- Return the path of this patch
- """
- raise NotImplementedError('Derived must override')
-
- def get_window_extent(self, renderer=None):
- return self.get_path().get_extents(self.get_transform())
-
-
-patchdoc = artist.kwdoc(Patch)
-for k in ('Rectangle', 'Circle', 'RegularPolygon', 'Polygon', 'Wedge', 'Arrow',
- 'FancyArrow', 'YAArrow', 'CirclePolygon', 'Ellipse', 'Arc',
- 'FancyBboxPatch', 'Patch'):
- docstring.interpd.update({k: patchdoc})
-
-# define Patch.__init__ docstring after the class has been added to interpd
-docstring.dedent_interpd(Patch.__init__)
-
-
-class Shadow(Patch):
- def __str__(self):
- return "Shadow(%s)" % (str(self.patch))
-
- @docstring.dedent_interpd
- def __init__(self, patch, ox, oy, props=None, **kwargs):
- """
- Create a shadow of the given *patch* offset by *ox*, *oy*.
- *props*, if not *None*, is a patch property update dictionary.
- If *None*, the shadow will have have the same color as the face,
- but darkened.
-
- kwargs are
- %(Patch)s
- """
- Patch.__init__(self)
- self.patch = patch
- self.props = props
- self._ox, self._oy = ox, oy
- self._shadow_transform = transforms.Affine2D()
- self._update()
-
- def _update(self):
- self.update_from(self.patch)
-
- # Place the shadow patch directly behind the inherited patch.
- self.set_zorder(np.nextafter(self.patch.zorder, -np.inf))
-
- if self.props is not None:
- self.update(self.props)
- else:
- r, g, b, a = colors.to_rgba(self.patch.get_facecolor())
- rho = 0.3
- r = rho * r
- g = rho * g
- b = rho * b
-
- self.set_facecolor((r, g, b, 0.5))
- self.set_edgecolor((r, g, b, 0.5))
- self.set_alpha(0.5)
-
- def _update_transform(self, renderer):
- ox = renderer.points_to_pixels(self._ox)
- oy = renderer.points_to_pixels(self._oy)
- self._shadow_transform.clear().translate(ox, oy)
-
- def _get_ox(self):
- return self._ox
-
- def _set_ox(self, ox):
- self._ox = ox
-
- def _get_oy(self):
- return self._oy
-
- def _set_oy(self, oy):
- self._oy = oy
-
- def get_path(self):
- return self.patch.get_path()
-
- def get_patch_transform(self):
- return self.patch.get_patch_transform() + self._shadow_transform
-
- def draw(self, renderer):
- self._update_transform(renderer)
- Patch.draw(self, renderer)
-
-
-class Rectangle(Patch):
- """
- Draw a rectangle with lower left at *xy* = (*x*, *y*) with
- specified *width*, *height* and rotation *angle*.
- """
-
- def __str__(self):
- pars = self._x0, self._y0, self._width, self._height, self.angle
- fmt = "Rectangle(xy=(%g, %g), width=%g, height=%g, angle=%g)"
- return fmt % pars
-
- @docstring.dedent_interpd
- def __init__(self, xy, width, height, angle=0.0, **kwargs):
- """
- Parameters
- ----------
- xy: length-2 tuple
- The bottom and left rectangle coordinates
- width:
- Rectangle width
- height:
- Rectangle height
- angle: float, optional
- rotation in degrees anti-clockwise about *xy* (default is 0.0)
- fill: bool, optional
- Whether to fill the rectangle (default is ``True``)
-
- Notes
- -----
- Valid kwargs are:
- %(Patch)s
- """
-
- Patch.__init__(self, **kwargs)
-
- self._x0 = xy[0]
- self._y0 = xy[1]
-
- self._width = width
- self._height = height
-
- self._x1 = self._x0 + self._width
- self._y1 = self._y0 + self._height
-
- self.angle = float(angle)
- # Note: This cannot be calculated until this is added to an Axes
- self._rect_transform = transforms.IdentityTransform()
-
- def get_path(self):
- """
- Return the vertices of the rectangle
- """
- return Path.unit_rectangle()
-
- def _update_patch_transform(self):
- """NOTE: This cannot be called until after this has been added
- to an Axes, otherwise unit conversion will fail. This
- makes it very important to call the accessor method and
- not directly access the transformation member variable.
- """
- x0, y0, x1, y1 = self._convert_units()
- bbox = transforms.Bbox.from_extents(x0, y0, x1, y1)
- rot_trans = transforms.Affine2D()
- rot_trans.rotate_deg_around(x0, y0, self.angle)
- self._rect_transform = transforms.BboxTransformTo(bbox)
- self._rect_transform += rot_trans
-
- def _update_x1(self):
- self._x1 = self._x0 + self._width
-
- def _update_y1(self):
- self._y1 = self._y0 + self._height
-
- def _convert_units(self):
- '''
- Convert bounds of the rectangle
- '''
- x0 = self.convert_xunits(self._x0)
- y0 = self.convert_yunits(self._y0)
- x1 = self.convert_xunits(self._x1)
- y1 = self.convert_yunits(self._y1)
- return x0, y0, x1, y1
-
- def get_patch_transform(self):
- self._update_patch_transform()
- return self._rect_transform
-
- def get_x(self):
- "Return the left coord of the rectangle"
- return self._x0
-
- def get_y(self):
- "Return the bottom coord of the rectangle"
- return self._y0
-
- def get_xy(self):
- "Return the left and bottom coords of the rectangle"
- return self._x0, self._y0
-
- def get_width(self):
- "Return the width of the rectangle"
- return self._width
-
- def get_height(self):
- "Return the height of the rectangle"
- return self._height
-
- def set_x(self, x):
- "Set the left coord of the rectangle"
- self._x0 = x
- self._update_x1()
- self.stale = True
-
- def set_y(self, y):
- "Set the bottom coord of the rectangle"
- self._y0 = y
- self._update_y1()
- self.stale = True
-
- def set_xy(self, xy):
- """
- Set the left and bottom coords of the rectangle
-
- ACCEPTS: 2-item sequence
- """
- self._x0, self._y0 = xy
- self._update_x1()
- self._update_y1()
- self.stale = True
-
- def set_width(self, w):
- "Set the width of the rectangle"
- self._width = w
- self._update_x1()
- self.stale = True
-
- def set_height(self, h):
- "Set the height of the rectangle"
- self._height = h
- self._update_y1()
- self.stale = True
-
- def set_bounds(self, *args):
- """
- Set the bounds of the rectangle: l,b,w,h
-
- ACCEPTS: (left, bottom, width, height)
- """
- if len(args) == 0:
- l, b, w, h = args[0]
- else:
- l, b, w, h = args
- self._x0 = l
- self._y0 = b
- self._width = w
- self._height = h
- self._update_x1()
- self._update_y1()
- self.stale = True
-
- def get_bbox(self):
- x0, y0, x1, y1 = self._convert_units()
- return transforms.Bbox.from_extents(x0, y0, x1, y1)
-
- xy = property(get_xy, set_xy)
-
-
-class RegularPolygon(Patch):
- """
- A regular polygon patch.
- """
- def __str__(self):
- return "Poly%d(%g,%g)" % (self._numVertices, self._xy[0], self._xy[1])
-
- @docstring.dedent_interpd
- def __init__(self, xy, numVertices, radius=5, orientation=0,
- **kwargs):
- """
- Constructor arguments:
-
- *xy*
- A length 2 tuple (*x*, *y*) of the center.
-
- *numVertices*
- the number of vertices.
-
- *radius*
- The distance from the center to each of the vertices.
-
- *orientation*
- rotates the polygon (in radians).
-
- Valid kwargs are:
- %(Patch)s
- """
- self._xy = xy
- self._numVertices = numVertices
- self._orientation = orientation
- self._radius = radius
- self._path = Path.unit_regular_polygon(numVertices)
- self._poly_transform = transforms.Affine2D()
- self._update_transform()
-
- Patch.__init__(self, **kwargs)
-
- def _update_transform(self):
- self._poly_transform.clear() \
- .scale(self.radius) \
- .rotate(self.orientation) \
- .translate(*self.xy)
-
- def _get_xy(self):
- return self._xy
-
- def _set_xy(self, xy):
- self._xy = xy
- self._update_transform()
- xy = property(_get_xy, _set_xy)
-
- def _get_orientation(self):
- return self._orientation
-
- def _set_orientation(self, orientation):
- self._orientation = orientation
- self._update_transform()
- orientation = property(_get_orientation, _set_orientation)
-
- def _get_radius(self):
- return self._radius
-
- def _set_radius(self, radius):
- self._radius = radius
- self._update_transform()
- radius = property(_get_radius, _set_radius)
-
- def _get_numvertices(self):
- return self._numVertices
-
- def _set_numvertices(self, numVertices):
- self._numVertices = numVertices
-
- numvertices = property(_get_numvertices, _set_numvertices)
-
- def get_path(self):
- return self._path
-
- def get_patch_transform(self):
- self._update_transform()
- return self._poly_transform
-
-
-class PathPatch(Patch):
- """
- A general polycurve path patch.
- """
- _edge_default = True
-
- def __str__(self):
- return "Poly((%g, %g) ...)" % tuple(self._path.vertices[0])
-
- @docstring.dedent_interpd
- def __init__(self, path, **kwargs):
- """
- *path* is a :class:`matplotlib.path.Path` object.
-
- Valid kwargs are:
- %(Patch)s
-
- .. seealso::
-
- :class:`Patch`
- For additional kwargs
-
- """
- Patch.__init__(self, **kwargs)
- self._path = path
-
- def get_path(self):
- return self._path
-
-
-class Polygon(Patch):
- """
- A general polygon patch.
- """
- def __str__(self):
- return "Poly((%g, %g) ...)" % tuple(self._path.vertices[0])
-
- @docstring.dedent_interpd
- def __init__(self, xy, closed=True, **kwargs):
- """
- *xy* is a numpy array with shape Nx2.
-
- If *closed* is *True*, the polygon will be closed so the
- starting and ending points are the same.
-
- Valid kwargs are:
- %(Patch)s
-
- .. seealso::
-
- :class:`Patch`
- For additional kwargs
-
- """
- Patch.__init__(self, **kwargs)
- self._closed = closed
- self.set_xy(xy)
-
- def get_path(self):
- """
- Get the path of the polygon
-
- Returns
- -------
- path : Path
- The :class:`~matplotlib.path.Path` object for
- the polygon
- """
- return self._path
-
- def get_closed(self):
- """
- Returns if the polygon is closed
-
- Returns
- -------
- closed : bool
- If the path is closed
- """
- return self._closed
-
- def set_closed(self, closed):
- """
- Set if the polygon is closed
-
- Parameters
- ----------
- closed : bool
- True if the polygon is closed
- """
- if self._closed == bool(closed):
- return
- self._closed = bool(closed)
- self.set_xy(self.get_xy())
- self.stale = True
-
- def get_xy(self):
- """
- Get the vertices of the path
-
- Returns
- -------
- vertices : numpy array
- The coordinates of the vertices as a Nx2
- ndarray.
- """
- return self._path.vertices
-
- def set_xy(self, xy):
- """
- Set the vertices of the polygon
-
- Parameters
- ----------
- xy : numpy array or iterable of pairs
- The coordinates of the vertices as a Nx2
- ndarray or iterable of pairs.
- """
- xy = np.asarray(xy)
- if self._closed:
- if len(xy) and (xy[0] != xy[-1]).any():
- xy = np.concatenate([xy, [xy[0]]])
- else:
- if len(xy) > 2 and (xy[0] == xy[-1]).all():
- xy = xy[:-1]
- self._path = Path(xy, closed=self._closed)
- self.stale = True
-
- _get_xy = get_xy
- _set_xy = set_xy
- xy = property(
- get_xy, set_xy, None,
- """Set/get the vertices of the polygon. This property is
- provided for backward compatibility with matplotlib 0.91.x
- only. New code should use
- :meth:`~matplotlib.patches.Polygon.get_xy` and
- :meth:`~matplotlib.patches.Polygon.set_xy` instead.""")
-
-
-class Wedge(Patch):
- """
- Wedge shaped patch.
- """
- def __str__(self):
- pars = (self.center[0], self.center[1], self.r,
- self.theta1, self.theta2, self.width)
- fmt = "Wedge(center=(%g, %g), r=%g, theta1=%g, theta2=%g, width=%s)"
- return fmt % pars
-
- @docstring.dedent_interpd
- def __init__(self, center, r, theta1, theta2, width=None, **kwargs):
- """
- Draw a wedge centered at *x*, *y* center with radius *r* that
- sweeps *theta1* to *theta2* (in degrees). If *width* is given,
- then a partial wedge is drawn from inner radius *r* - *width*
- to outer radius *r*.
-
- Valid kwargs are:
-
- %(Patch)s
- """
- Patch.__init__(self, **kwargs)
- self.center = center
- self.r, self.width = r, width
- self.theta1, self.theta2 = theta1, theta2
- self._patch_transform = transforms.IdentityTransform()
- self._recompute_path()
-
- def _recompute_path(self):
- # Inner and outer rings are connected unless the annulus is complete
- if abs((self.theta2 - self.theta1) - 360) <= 1e-12:
- theta1, theta2 = 0, 360
- connector = Path.MOVETO
- else:
- theta1, theta2 = self.theta1, self.theta2
- connector = Path.LINETO
-
- # Form the outer ring
- arc = Path.arc(theta1, theta2)
-
- if self.width is not None:
- # Partial annulus needs to draw the outer ring
- # followed by a reversed and scaled inner ring
- v1 = arc.vertices
- v2 = arc.vertices[::-1] * (self.r - self.width) / self.r
- v = np.vstack([v1, v2, v1[0, :], (0, 0)])
- c = np.hstack([arc.codes, arc.codes, connector, Path.CLOSEPOLY])
- c[len(arc.codes)] = connector
- else:
- # Wedge doesn't need an inner ring
- v = np.vstack([arc.vertices, [(0, 0), arc.vertices[0, :], (0, 0)]])
- c = np.hstack([arc.codes, [connector, connector, Path.CLOSEPOLY]])
-
- # Shift and scale the wedge to the final location.
- v *= self.r
- v += np.asarray(self.center)
- self._path = Path(v, c)
-
- def set_center(self, center):
- self._path = None
- self.center = center
- self.stale = True
-
- def set_radius(self, radius):
- self._path = None
- self.r = radius
- self.stale = True
-
- def set_theta1(self, theta1):
- self._path = None
- self.theta1 = theta1
- self.stale = True
-
- def set_theta2(self, theta2):
- self._path = None
- self.theta2 = theta2
- self.stale = True
-
- def set_width(self, width):
- self._path = None
- self.width = width
- self.stale = True
-
- def get_path(self):
- if self._path is None:
- self._recompute_path()
- return self._path
-
-
-# COVERAGE NOTE: Not used internally or from examples
-class Arrow(Patch):
- """
- An arrow patch.
- """
- def __str__(self):
- return "Arrow()"
-
- _path = Path([[0.0, 0.1], [0.0, -0.1],
- [0.8, -0.1], [0.8, -0.3],
- [1.0, 0.0], [0.8, 0.3],
- [0.8, 0.1], [0.0, 0.1]],
- closed=True)
-
- @docstring.dedent_interpd
- def __init__(self, x, y, dx, dy, width=1.0, **kwargs):
- """
- Draws an arrow from (*x*, *y*) to (*x* + *dx*, *y* + *dy*).
- The width of the arrow is scaled by *width*.
-
- Parameters
- ----------
- x : scalar
- x coordinate of the arrow tail
- y : scalar
- y coordinate of the arrow tail
- dx : scalar
- Arrow length in the x direction
- dy : scalar
- Arrow length in the y direction
- width : scalar, optional (default: 1)
- Scale factor for the width of the arrow. With a default value of
- 1, the tail width is 0.2 and head width is 0.6.
- **kwargs :
- Keyword arguments control the :class:`~matplotlib.patches.Patch`
- properties:
-
- %(Patch)s
-
- See Also
- --------
- :class:`FancyArrow` :
- Patch that allows independent control of the head and tail
- properties
- """
- Patch.__init__(self, **kwargs)
- L = np.hypot(dx, dy)
-
- if L != 0:
- cx = dx / L
- sx = dy / L
- else:
- # Account for division by zero
- cx, sx = 0, 1
-
- trans1 = transforms.Affine2D().scale(L, width)
- trans2 = transforms.Affine2D.from_values(cx, sx, -sx, cx, 0.0, 0.0)
- trans3 = transforms.Affine2D().translate(x, y)
- trans = trans1 + trans2 + trans3
- self._patch_transform = trans.frozen()
-
- def get_path(self):
- return self._path
-
- def get_patch_transform(self):
- return self._patch_transform
-
-
-class FancyArrow(Polygon):
- """
- Like Arrow, but lets you set head width and head height independently.
- """
-
- _edge_default = True
-
- def __str__(self):
- return "FancyArrow()"
-
- @docstring.dedent_interpd
- def __init__(self, x, y, dx, dy, width=0.001, length_includes_head=False,
- head_width=None, head_length=None, shape='full', overhang=0,
- head_starts_at_zero=False, **kwargs):
- """
- Constructor arguments
- *width*: float (default: 0.001)
- width of full arrow tail
-
- *length_includes_head*: bool (default: False)
- True if head is to be counted in calculating the length.
-
- *head_width*: float or None (default: 3*width)
- total width of the full arrow head
-
- *head_length*: float or None (default: 1.5 * head_width)
- length of arrow head
-
- *shape*: ['full', 'left', 'right'] (default: 'full')
- draw the left-half, right-half, or full arrow
-
- *overhang*: float (default: 0)
- fraction that the arrow is swept back (0 overhang means
- triangular shape). Can be negative or greater than one.
-
- *head_starts_at_zero*: bool (default: False)
- if True, the head starts being drawn at coordinate 0
- instead of ending at coordinate 0.
-
- Other valid kwargs (inherited from :class:`Patch`) are:
- %(Patch)s
-
- """
- if head_width is None:
- head_width = 3 * width
- if head_length is None:
- head_length = 1.5 * head_width
-
- distance = np.hypot(dx, dy)
-
- if length_includes_head:
- length = distance
- else:
- length = distance + head_length
- if not length:
- verts = [] # display nothing if empty
- else:
- # start by drawing horizontal arrow, point at (0,0)
- hw, hl, hs, lw = head_width, head_length, overhang, width
- left_half_arrow = np.array([
- [0.0, 0.0], # tip
- [-hl, -hw / 2.0], # leftmost
- [-hl * (1 - hs), -lw / 2.0], # meets stem
- [-length, -lw / 2.0], # bottom left
- [-length, 0],
- ])
- # if we're not including the head, shift up by head length
- if not length_includes_head:
- left_half_arrow += [head_length, 0]
- # if the head starts at 0, shift up by another head length
- if head_starts_at_zero:
- left_half_arrow += [head_length / 2.0, 0]
- # figure out the shape, and complete accordingly
- if shape == 'left':
- coords = left_half_arrow
- else:
- right_half_arrow = left_half_arrow * [1, -1]
- if shape == 'right':
- coords = right_half_arrow
- elif shape == 'full':
- # The half-arrows contain the midpoint of the stem,
- # which we can omit from the full arrow. Including it
- # twice caused a problem with xpdf.
- coords = np.concatenate([left_half_arrow[:-1],
- right_half_arrow[-2::-1]])
- else:
- raise ValueError("Got unknown shape: %s" % shape)
- if distance != 0:
- cx = dx / distance
- sx = dy / distance
- else:
- # Account for division by zero
- cx, sx = 0, 1
- M = [[cx, sx], [-sx, cx]]
- verts = np.dot(coords, M) + (x + dx, y + dy)
-
- Polygon.__init__(self, list(map(tuple, verts)), closed=True, **kwargs)
-
-
-docstring.interpd.update({"FancyArrow": FancyArrow.__init__.__doc__})
-
-
-class YAArrow(Patch):
- """
- Yet another arrow class.
-
- This is an arrow that is defined in display space and has a tip at
- *x1*, *y1* and a base at *x2*, *y2*.
- """
- def __str__(self):
- return "YAArrow()"
-
- @docstring.dedent_interpd
- def __init__(self, figure, xytip, xybase,
- width=4, frac=0.1, headwidth=12, **kwargs):
- """
- Constructor arguments:
-
- *xytip*
- (*x*, *y*) location of arrow tip
-
- *xybase*
- (*x*, *y*) location the arrow base mid point
-
- *figure*
- The :class:`~matplotlib.figure.Figure` instance
- (fig.dpi)
-
- *width*
- The width of the arrow in points
-
- *frac*
- The fraction of the arrow length occupied by the head
-
- *headwidth*
- The width of the base of the arrow head in points
-
- Valid kwargs are:
- %(Patch)s
-
- """
- self.xytip = xytip
- self.xybase = xybase
- self.width = width
- self.frac = frac
- self.headwidth = headwidth
- Patch.__init__(self, **kwargs)
- # Set self.figure after Patch.__init__, since it sets self.figure to
- # None
- self.figure = figure
-
- def get_path(self):
- # Since this is dpi dependent, we need to recompute the path
- # every time.
-
- # the base vertices
- x1, y1 = self.xytip
- x2, y2 = self.xybase
- k1 = self.width * self.figure.dpi / 72. / 2.
- k2 = self.headwidth * self.figure.dpi / 72. / 2.
- xb1, yb1, xb2, yb2 = self.getpoints(x1, y1, x2, y2, k1)
-
- # a point on the segment 20% of the distance from the tip to the base
- theta = math.atan2(y2 - y1, x2 - x1)
- r = math.sqrt((y2 - y1) ** 2. + (x2 - x1) ** 2.)
- xm = x1 + self.frac * r * math.cos(theta)
- ym = y1 + self.frac * r * math.sin(theta)
- xc1, yc1, xc2, yc2 = self.getpoints(x1, y1, xm, ym, k1)
- xd1, yd1, xd2, yd2 = self.getpoints(x1, y1, xm, ym, k2)
-
- xs = self.convert_xunits([xb1, xb2, xc2, xd2, x1, xd1, xc1, xb1])
- ys = self.convert_yunits([yb1, yb2, yc2, yd2, y1, yd1, yc1, yb1])
-
- return Path(np.column_stack([xs, ys]), closed=True)
-
- def get_patch_transform(self):
- return transforms.IdentityTransform()
-
- def getpoints(self, x1, y1, x2, y2, k):
- """
- For line segment defined by (*x1*, *y1*) and (*x2*, *y2*)
- return the points on the line that is perpendicular to the
- line and intersects (*x2*, *y2*) and the distance from (*x2*,
- *y2*) of the returned points is *k*.
- """
- x1, y1, x2, y2, k = map(float, (x1, y1, x2, y2, k))
-
- if y2 - y1 == 0:
- return x2, y2 + k, x2, y2 - k
- elif x2 - x1 == 0:
- return x2 + k, y2, x2 - k, y2
-
- m = (y2 - y1) / (x2 - x1)
- pm = -1. / m
- a = 1
- b = -2 * y2
- c = y2 ** 2. - k ** 2. * pm ** 2. / (1. + pm ** 2.)
-
- y3a = (-b + math.sqrt(b ** 2 - 4 * a * c)) / (2 * a)
- x3a = (y3a - y2) / pm + x2
-
- y3b = (-b - math.sqrt(b ** 2 - 4 * a * c)) / (2 * a)
- x3b = (y3b - y2) / pm + x2
- return x3a, y3a, x3b, y3b
-
-
-class CirclePolygon(RegularPolygon):
- """
- A polygon-approximation of a circle patch.
- """
- def __str__(self):
- return "CirclePolygon(%d,%d)" % self.center
-
- @docstring.dedent_interpd
- def __init__(self, xy, radius=5,
- resolution=20, # the number of vertices
- ** kwargs):
- """
- Create a circle at *xy* = (*x*, *y*) with given *radius*.
- This circle is approximated by a regular polygon with
- *resolution* sides. For a smoother circle drawn with splines,
- see :class:`~matplotlib.patches.Circle`.
-
- Valid kwargs are:
- %(Patch)s
-
- """
- RegularPolygon.__init__(self, xy,
- resolution,
- radius,
- orientation=0,
- **kwargs)
-
-
-class Ellipse(Patch):
- """
- A scale-free ellipse.
- """
- def __str__(self):
- pars = (self.center[0], self.center[1],
- self.width, self.height, self.angle)
- fmt = "Ellipse(xy=(%s, %s), width=%s, height=%s, angle=%s)"
- return fmt % pars
-
- @docstring.dedent_interpd
- def __init__(self, xy, width, height, angle=0.0, **kwargs):
- """
- *xy*
- center of ellipse
-
- *width*
- total length (diameter) of horizontal axis
-
- *height*
- total length (diameter) of vertical axis
-
- *angle*
- rotation in degrees (anti-clockwise)
-
- Valid kwargs are:
- %(Patch)s
- """
- Patch.__init__(self, **kwargs)
-
- self.center = xy
- self.width, self.height = width, height
- self.angle = angle
- self._path = Path.unit_circle()
- # Note: This cannot be calculated until this is added to an Axes
- self._patch_transform = transforms.IdentityTransform()
-
- def _recompute_transform(self):
- """NOTE: This cannot be called until after this has been added
- to an Axes, otherwise unit conversion will fail. This
- makes it very important to call the accessor method and
- not directly access the transformation member variable.
- """
- center = (self.convert_xunits(self.center[0]),
- self.convert_yunits(self.center[1]))
- width = self.convert_xunits(self.width)
- height = self.convert_yunits(self.height)
- self._patch_transform = transforms.Affine2D() \
- .scale(width * 0.5, height * 0.5) \
- .rotate_deg(self.angle) \
- .translate(*center)
-
- def get_path(self):
- """
- Return the vertices of the rectangle
- """
- return self._path
-
- def get_patch_transform(self):
- self._recompute_transform()
- return self._patch_transform
-
-
-class Circle(Ellipse):
- """
- A circle patch.
- """
- def __str__(self):
- pars = self.center[0], self.center[1], self.radius
- fmt = "Circle(xy=(%g, %g), radius=%g)"
- return fmt % pars
-
- @docstring.dedent_interpd
- def __init__(self, xy, radius=5, **kwargs):
- """
- Create true circle at center *xy* = (*x*, *y*) with given
- *radius*. Unlike :class:`~matplotlib.patches.CirclePolygon`
- which is a polygonal approximation, this uses Bézier splines
- and is much closer to a scale-free circle.
-
- Valid kwargs are:
- %(Patch)s
-
- """
- Ellipse.__init__(self, xy, radius * 2, radius * 2, **kwargs)
- self.radius = radius
-
- def set_radius(self, radius):
- """
- Set the radius of the circle
-
- ACCEPTS: float
- """
- self.width = self.height = 2 * radius
- self.stale = True
-
- def get_radius(self):
- 'return the radius of the circle'
- return self.width / 2.
-
- radius = property(get_radius, set_radius)
-
-
-class Arc(Ellipse):
- """
- An elliptical arc. Because it performs various optimizations, it
- can not be filled.
-
- The arc must be used in an :class:`~matplotlib.axes.Axes`
- instance---it can not be added directly to a
- :class:`~matplotlib.figure.Figure`---because it is optimized to
- only render the segments that are inside the axes bounding box
- with high resolution.
- """
- def __str__(self):
- pars = (self.center[0], self.center[1], self.width,
- self.height, self.angle, self.theta1, self.theta2)
- fmt = ("Arc(xy=(%g, %g), width=%g, "
- "height=%g, angle=%g, theta1=%g, theta2=%g)")
- return fmt % pars
-
- @docstring.dedent_interpd
- def __init__(self, xy, width, height, angle=0.0,
- theta1=0.0, theta2=360.0, **kwargs):
- """
- The following args are supported:
-
- *xy*
- center of ellipse
-
- *width*
- length of horizontal axis
-
- *height*
- length of vertical axis
-
- *angle*
- rotation in degrees (anti-clockwise)
-
- *theta1*
- starting angle of the arc in degrees
-
- *theta2*
- ending angle of the arc in degrees
-
- If *theta1* and *theta2* are not provided, the arc will form a
- complete ellipse.
-
- Valid kwargs are:
-
- %(Patch)s
- """
- fill = kwargs.setdefault('fill', False)
- if fill:
- raise ValueError("Arc objects can not be filled")
-
- Ellipse.__init__(self, xy, width, height, angle, **kwargs)
-
- self.theta1 = theta1
- self.theta2 = theta2
-
- @artist.allow_rasterization
- def draw(self, renderer):
- """
- Ellipses are normally drawn using an approximation that uses
- eight cubic bezier splines. The error of this approximation
- is 1.89818e-6, according to this unverified source:
-
- Lancaster, Don. Approximating a Circle or an Ellipse Using
- Four Bezier Cubic Splines.
-
- http://www.tinaja.com/glib/ellipse4.pdf
-
- There is a use case where very large ellipses must be drawn
- with very high accuracy, and it is too expensive to render the
- entire ellipse with enough segments (either splines or line
- segments). Therefore, in the case where either radius of the
- ellipse is large enough that the error of the spline
- approximation will be visible (greater than one pixel offset
- from the ideal), a different technique is used.
-
- In that case, only the visible parts of the ellipse are drawn,
- with each visible arc using a fixed number of spline segments
- (8). The algorithm proceeds as follows:
-
- 1. The points where the ellipse intersects the axes bounding
- box are located. (This is done be performing an inverse
- transformation on the axes bbox such that it is relative
- to the unit circle -- this makes the intersection
- calculation much easier than doing rotated ellipse
- intersection directly).
-
- This uses the "line intersecting a circle" algorithm
- from:
-
- Vince, John. Geometry for Computer Graphics: Formulae,
- Examples & Proofs. London: Springer-Verlag, 2005.
-
- 2. The angles of each of the intersection points are
- calculated.
-
- 3. Proceeding counterclockwise starting in the positive
- x-direction, each of the visible arc-segments between the
- pairs of vertices are drawn using the bezier arc
- approximation technique implemented in
- :meth:`matplotlib.path.Path.arc`.
- """
- if not hasattr(self, 'axes'):
- raise RuntimeError('Arcs can only be used in Axes instances')
-
- self._recompute_transform()
-
- width = self.convert_xunits(self.width)
- height = self.convert_yunits(self.height)
-
- # If the width and height of ellipse are not equal, take into account
- # stretching when calculating angles to draw between
- def theta_stretch(theta, scale):
- theta = np.deg2rad(theta)
- x = np.cos(theta)
- y = np.sin(theta)
- return np.rad2deg(np.arctan2(scale * y, x))
- theta1 = theta_stretch(self.theta1, width / height)
- theta2 = theta_stretch(self.theta2, width / height)
-
- # Get width and height in pixels
- width, height = self.get_transform().transform_point((width, height))
- inv_error = (1.0 / 1.89818e-6) * 0.5
- if width < inv_error and height < inv_error:
- self._path = Path.arc(theta1, theta2)
- return Patch.draw(self, renderer)
-
- def iter_circle_intersect_on_line(x0, y0, x1, y1):
- dx = x1 - x0
- dy = y1 - y0
- dr2 = dx * dx + dy * dy
- D = x0 * y1 - x1 * y0
- D2 = D * D
- discrim = dr2 - D2
-
- # Single (tangential) intersection
- if discrim == 0.0:
- x = (D * dy) / dr2
- y = (-D * dx) / dr2
- yield x, y
- elif discrim > 0.0:
- # The definition of "sign" here is different from
- # np.sign: we never want to get 0.0
- if dy < 0.0:
- sign_dy = -1.0
- else:
- sign_dy = 1.0
- sqrt_discrim = np.sqrt(discrim)
- for sign in (1., -1.):
- x = (D * dy + sign * sign_dy * dx * sqrt_discrim) / dr2
- y = (-D * dx + sign * np.abs(dy) * sqrt_discrim) / dr2
- yield x, y
-
- def iter_circle_intersect_on_line_seg(x0, y0, x1, y1):
- epsilon = 1e-9
- if x1 < x0:
- x0e, x1e = x1, x0
- else:
- x0e, x1e = x0, x1
- if y1 < y0:
- y0e, y1e = y1, y0
- else:
- y0e, y1e = y0, y1
- x0e -= epsilon
- y0e -= epsilon
- x1e += epsilon
- y1e += epsilon
- for x, y in iter_circle_intersect_on_line(x0, y0, x1, y1):
- if x >= x0e and x <= x1e and y >= y0e and y <= y1e:
- yield x, y
-
- # Transforms the axes box_path so that it is relative to the unit
- # circle in the same way that it is relative to the desired
- # ellipse.
- box_path = Path.unit_rectangle()
- box_path_transform = transforms.BboxTransformTo(self.axes.bbox) + \
- self.get_transform().inverted()
- box_path = box_path.transformed(box_path_transform)
-
- thetas = set()
- # For each of the point pairs, there is a line segment
- for p0, p1 in zip(box_path.vertices[:-1], box_path.vertices[1:]):
- x0, y0 = p0
- x1, y1 = p1
- for x, y in iter_circle_intersect_on_line_seg(x0, y0, x1, y1):
- theta = np.arccos(x)
- if y < 0:
- theta = 2 * np.pi - theta
- # Convert radians to angles
- theta = np.rad2deg(theta)
- if theta1 < theta < theta2:
- thetas.add(theta)
- thetas = sorted(thetas) + [theta2]
-
- last_theta = theta1
- theta1_rad = np.deg2rad(theta1)
- inside = box_path.contains_point((np.cos(theta1_rad),
- np.sin(theta1_rad)))
-
- # save original path
- path_original = self._path
- for theta in thetas:
- if inside:
- self._path = Path.arc(last_theta, theta, 8)
- Patch.draw(self, renderer)
- inside = False
- else:
- inside = True
- last_theta = theta
-
- # restore original path
- self._path = path_original
-
-
-def bbox_artist(artist, renderer, props=None, fill=True):
- """
- This is a debug function to draw a rectangle around the bounding
- box returned by
- :meth:`~matplotlib.artist.Artist.get_window_extent` of an artist,
- to test whether the artist is returning the correct bbox.
-
- *props* is a dict of rectangle props with the additional property
- 'pad' that sets the padding around the bbox in points.
- """
- if props is None:
- props = {}
- props = props.copy() # don't want to alter the pad externally
- pad = props.pop('pad', 4)
- pad = renderer.points_to_pixels(pad)
- bbox = artist.get_window_extent(renderer)
- l, b, w, h = bbox.bounds
- l -= pad / 2.
- b -= pad / 2.
- w += pad
- h += pad
- r = Rectangle(xy=(l, b),
- width=w,
- height=h,
- fill=fill,
- )
- r.set_transform(transforms.IdentityTransform())
- r.set_clip_on(False)
- r.update(props)
- r.draw(renderer)
-
-
-def draw_bbox(bbox, renderer, color='k', trans=None):
- """
- This is a debug function to draw a rectangle around the bounding
- box returned by
- :meth:`~matplotlib.artist.Artist.get_window_extent` of an artist,
- to test whether the artist is returning the correct bbox.
- """
-
- l, b, w, h = bbox.bounds
- r = Rectangle(xy=(l, b),
- width=w,
- height=h,
- edgecolor=color,
- fill=False,
- )
- if trans is not None:
- r.set_transform(trans)
- r.set_clip_on(False)
- r.draw(renderer)
-
-
-def _pprint_table(_table, leadingspace=2):
- """
- Given the list of list of strings, return a string of REST table format.
- """
- if leadingspace:
- pad = ' ' * leadingspace
- else:
- pad = ''
-
- columns = [[] for cell in _table[0]]
-
- for row in _table:
- for column, cell in zip(columns, row):
- column.append(cell)
-
- col_len = [max(len(cell) for cell in column) for column in columns]
-
- lines = []
- table_formatstr = pad + ' '.join([('=' * cl) for cl in col_len])
-
- lines.append('')
- lines.append(table_formatstr)
- lines.append(pad + ' '.join([cell.ljust(cl)
- for cell, cl
- in zip(_table[0], col_len)]))
- lines.append(table_formatstr)
-
- lines.extend([(pad + ' '.join([cell.ljust(cl)
- for cell, cl
- in zip(row, col_len)]))
- for row in _table[1:]])
-
- lines.append(table_formatstr)
- lines.append('')
- return "\n".join(lines)
-
-
-def _pprint_styles(_styles):
- """
- A helper function for the _Style class. Given the dictionary of
- (stylename : styleclass), return a formatted string listing all the
- styles. Used to update the documentation.
- """
- import inspect
-
- _table = [["Class", "Name", "Attrs"]]
-
- for name, cls in sorted(_styles.items()):
- if six.PY2:
- args, varargs, varkw, defaults = inspect.getargspec(cls.__init__)
- else:
- (args, varargs, varkw, defaults, kwonlyargs, kwonlydefs,
- annotations) = inspect.getfullargspec(cls.__init__)
- if defaults:
- args = [(argname, argdefault)
- for argname, argdefault in zip(args[1:], defaults)]
- else:
- args = None
-
- if args is None:
- argstr = 'None'
- else:
- argstr = ",".join([("%s=%s" % (an, av))
- for an, av
- in args])
-
- # adding ``quotes`` since - and | have special meaning in reST
- _table.append([cls.__name__, "``%s``" % name, argstr])
-
- return _pprint_table(_table)
-
-
-def _simpleprint_styles(_styles):
- """
- A helper function for the _Style class. Given the dictionary of
- (stylename : styleclass), return a string rep of the list of keys.
- Used to update the documentation.
- """
- return "[{}]".format("|".join(map(" '{}' ".format, sorted(_styles))))
-
-
-class _Style(object):
- """
- A base class for the Styles. It is meant to be a container class,
- where actual styles are declared as subclass of it, and it
- provides some helper functions.
- """
- def __new__(self, stylename, **kw):
- """
- return the instance of the subclass with the given style name.
- """
-
- # the "class" should have the _style_list attribute, which is
- # a dictionary of stylname, style class paie.
-
- _list = stylename.replace(" ", "").split(",")
- _name = _list[0].lower()
- try:
- _cls = self._style_list[_name]
- except KeyError:
- raise ValueError("Unknown style : %s" % stylename)
-
- try:
- _args_pair = [cs.split("=") for cs in _list[1:]]
- _args = {k: float(v) for k, v in _args_pair}
- except ValueError:
- raise ValueError("Incorrect style argument : %s" % stylename)
- _args.update(kw)
-
- return _cls(**_args)
-
- @classmethod
- def get_styles(klass):
- """
- A class method which returns a dictionary of available styles.
- """
- return klass._style_list
-
- @classmethod
- def pprint_styles(klass):
- """
- A class method which returns a string of the available styles.
- """
- return _pprint_styles(klass._style_list)
-
- @classmethod
- def register(klass, name, style):
- """
- Register a new style.
- """
-
- if not issubclass(style, klass._Base):
- raise ValueError("%s must be a subclass of %s" % (style,
- klass._Base))
- klass._style_list[name] = style
-
-
-class BoxStyle(_Style):
- """
- :class:`BoxStyle` is a container class which defines several
- boxstyle classes, which are used for :class:`FancyBboxPatch`.
-
- A style object can be created as::
-
- BoxStyle.Round(pad=0.2)
-
- or::
-
- BoxStyle("Round", pad=0.2)
-
- or::
-
- BoxStyle("Round, pad=0.2")
-
- Following boxstyle classes are defined.
-
- %(AvailableBoxstyles)s
-
- An instance of any boxstyle class is an callable object,
- whose call signature is::
-
- __call__(self, x0, y0, width, height, mutation_size, aspect_ratio=1.)
-
- and returns a :class:`Path` instance. *x0*, *y0*, *width* and
- *height* specify the location and size of the box to be
- drawn. *mutation_scale* determines the overall size of the
- mutation (by which I mean the transformation of the rectangle to
- the fancy box). *mutation_aspect* determines the aspect-ratio of
- the mutation.
- """
-
- _style_list = {}
-
- class _Base(object):
- """
- :class:`BBoxTransmuterBase` and its derivatives are used to make a
- fancy box around a given rectangle. The :meth:`__call__` method
- returns the :class:`~matplotlib.path.Path` of the fancy box. This
- class is not an artist and actual drawing of the fancy box is done
- by the :class:`FancyBboxPatch` class.
- """
-
- # The derived classes are required to be able to be initialized
- # w/o arguments, i.e., all its argument (except self) must have
- # the default values.
-
- def __init__(self):
- """
- initializtion.
- """
- super(BoxStyle._Base, self).__init__()
-
- def transmute(self, x0, y0, width, height, mutation_size):
- """
- The transmute method is a very core of the
- :class:`BboxTransmuter` class and must be overridden in the
- subclasses. It receives the location and size of the
- rectangle, and the mutation_size, with which the amount of
- padding and etc. will be scaled. It returns a
- :class:`~matplotlib.path.Path` instance.
- """
- raise NotImplementedError('Derived must override')
-
- def __call__(self, x0, y0, width, height, mutation_size,
- aspect_ratio=1.):
- """
- Given the location and size of the box, return the path of
- the box around it.
-
- - *x0*, *y0*, *width*, *height* : location and size of the box
- - *mutation_size* : a reference scale for the mutation.
- - *aspect_ratio* : aspect-ration for the mutation.
- """
- # The __call__ method is a thin wrapper around the transmute method
- # and take care of the aspect.
-
- if aspect_ratio is not None:
- # Squeeze the given height by the aspect_ratio
- y0, height = y0 / aspect_ratio, height / aspect_ratio
- # call transmute method with squeezed height.
- path = self.transmute(x0, y0, width, height, mutation_size)
- vertices, codes = path.vertices, path.codes
- # Restore the height
- vertices[:, 1] = vertices[:, 1] * aspect_ratio
- return Path(vertices, codes)
- else:
- return self.transmute(x0, y0, width, height, mutation_size)
-
- def __reduce__(self):
- # because we have decided to nest these classes, we need to
- # add some more information to allow instance pickling.
- return (cbook._NestedClassGetter(),
- (BoxStyle, self.__class__.__name__),
- self.__dict__
- )
-
- class Square(_Base):
- """
- A simple square box.
- """
-
- def __init__(self, pad=0.3):
- """
- *pad*
- amount of padding
- """
-
- self.pad = pad
- super(BoxStyle.Square, self).__init__()
-
- def transmute(self, x0, y0, width, height, mutation_size):
- pad = mutation_size * self.pad
-
- # width and height with padding added.
- width, height = width + 2*pad, height + 2*pad
-
- # boundary of the padded box
- x0, y0 = x0 - pad, y0 - pad,
- x1, y1 = x0 + width, y0 + height
-
- vertices = [(x0, y0), (x1, y0), (x1, y1), (x0, y1), (x0, y0)]
- codes = [Path.MOVETO] + [Path.LINETO] * 3 + [Path.CLOSEPOLY]
- return Path(vertices, codes)
-
- _style_list["square"] = Square
-
- class Circle(_Base):
- """A simple circle box."""
- def __init__(self, pad=0.3):
- """
- Parameters
- ----------
- pad : float
- The amount of padding around the original box.
- """
- self.pad = pad
- super(BoxStyle.Circle, self).__init__()
-
- def transmute(self, x0, y0, width, height, mutation_size):
- pad = mutation_size * self.pad
- width, height = width + 2 * pad, height + 2 * pad
-
- # boundary of the padded box
- x0, y0 = x0 - pad, y0 - pad,
- return Path.circle((x0 + width / 2, y0 + height / 2),
- max(width, height) / 2)
-
- _style_list["circle"] = Circle
-
- class LArrow(_Base):
- """
- (left) Arrow Box
- """
- def __init__(self, pad=0.3):
- self.pad = pad
- super(BoxStyle.LArrow, self).__init__()
-
- def transmute(self, x0, y0, width, height, mutation_size):
- # padding
- pad = mutation_size * self.pad
-
- # width and height with padding added.
- width, height = width + 2. * pad, height + 2. * pad
-
- # boundary of the padded box
- x0, y0 = x0 - pad, y0 - pad,
- x1, y1 = x0 + width, y0 + height
-
- dx = (y1 - y0) / 2.
- dxx = dx * .5
- # adjust x0. 1.4 <- sqrt(2)
- x0 = x0 + pad / 1.4
-
- cp = [(x0 + dxx, y0), (x1, y0), (x1, y1), (x0 + dxx, y1),
- (x0 + dxx, y1 + dxx), (x0 - dx, y0 + dx),
- (x0 + dxx, y0 - dxx), # arrow
- (x0 + dxx, y0), (x0 + dxx, y0)]
-
- com = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO,
- Path.LINETO, Path.LINETO, Path.LINETO,
- Path.LINETO, Path.CLOSEPOLY]
-
- path = Path(cp, com)
-
- return path
- _style_list["larrow"] = LArrow
-
- class RArrow(LArrow):
- """
- (right) Arrow Box
- """
-
- def __init__(self, pad=0.3):
- super(BoxStyle.RArrow, self).__init__(pad)
-
- def transmute(self, x0, y0, width, height, mutation_size):
-
- p = BoxStyle.LArrow.transmute(self, x0, y0,
- width, height, mutation_size)
-
- p.vertices[:, 0] = 2 * x0 + width - p.vertices[:, 0]
-
- return p
-
- _style_list["rarrow"] = RArrow
-
- class DArrow(_Base):
- """
- (Double) Arrow Box
- """
- # This source is copied from LArrow,
- # modified to add a right arrow to the bbox.
-
- def __init__(self, pad=0.3):
- self.pad = pad
- super(BoxStyle.DArrow, self).__init__()
-
- def transmute(self, x0, y0, width, height, mutation_size):
-
- # padding
- pad = mutation_size * self.pad
-
- # width and height with padding added.
- # The width is padded by the arrows, so we don't need to pad it.
- height = height + 2. * pad
-
- # boundary of the padded box
- x0, y0 = x0 - pad, y0 - pad
- x1, y1 = x0 + width, y0 + height
-
- dx = (y1 - y0)/2.
- dxx = dx * .5
- # adjust x0. 1.4 <- sqrt(2)
- x0 = x0 + pad / 1.4
-
- cp = [(x0 + dxx, y0), (x1, y0), # bot-segment
- (x1, y0 - dxx), (x1 + dx + dxx, y0 + dx),
- (x1, y1 + dxx), # right-arrow
- (x1, y1), (x0 + dxx, y1), # top-segment
- (x0 + dxx, y1 + dxx), (x0 - dx, y0 + dx),
- (x0 + dxx, y0 - dxx), # left-arrow
- (x0 + dxx, y0), (x0 + dxx, y0)] # close-poly
-
- com = [Path.MOVETO, Path.LINETO,
- Path.LINETO, Path.LINETO,
- Path.LINETO,
- Path.LINETO, Path.LINETO,
- Path.LINETO, Path.LINETO,
- Path.LINETO,
- Path.LINETO, Path.CLOSEPOLY]
-
- path = Path(cp, com)
-
- return path
-
- _style_list['darrow'] = DArrow
-
- class Round(_Base):
- """
- A box with round corners.
- """
-
- def __init__(self, pad=0.3, rounding_size=None):
- """
- *pad*
- amount of padding
-
- *rounding_size*
- rounding radius of corners. *pad* if None
- """
- self.pad = pad
- self.rounding_size = rounding_size
- super(BoxStyle.Round, self).__init__()
-
- def transmute(self, x0, y0, width, height, mutation_size):
-
- # padding
- pad = mutation_size * self.pad
-
- # size of the roudning corner
- if self.rounding_size:
- dr = mutation_size * self.rounding_size
- else:
- dr = pad
-
- width, height = width + 2. * pad, height + 2. * pad
-
- x0, y0 = x0 - pad, y0 - pad,
- x1, y1 = x0 + width, y0 + height
-
- # Round corners are implemented as quadratic bezier. e.g.,
- # [(x0, y0-dr), (x0, y0), (x0+dr, y0)] for lower left corner.
- cp = [(x0 + dr, y0),
- (x1 - dr, y0),
- (x1, y0), (x1, y0 + dr),
- (x1, y1 - dr),
- (x1, y1), (x1 - dr, y1),
- (x0 + dr, y1),
- (x0, y1), (x0, y1 - dr),
- (x0, y0 + dr),
- (x0, y0), (x0 + dr, y0),
- (x0 + dr, y0)]
-
- com = [Path.MOVETO,
- Path.LINETO,
- Path.CURVE3, Path.CURVE3,
- Path.LINETO,
- Path.CURVE3, Path.CURVE3,
- Path.LINETO,
- Path.CURVE3, Path.CURVE3,
- Path.LINETO,
- Path.CURVE3, Path.CURVE3,
- Path.CLOSEPOLY]
-
- path = Path(cp, com)
-
- return path
-
- _style_list["round"] = Round
-
- class Round4(_Base):
- """
- Another box with round edges.
- """
-
- def __init__(self, pad=0.3, rounding_size=None):
- """
- *pad*
- amount of padding
-
- *rounding_size*
- rounding size of edges. *pad* if None
- """
-
- self.pad = pad
- self.rounding_size = rounding_size
- super(BoxStyle.Round4, self).__init__()
-
- def transmute(self, x0, y0, width, height, mutation_size):
-
- # padding
- pad = mutation_size * self.pad
-
- # roudning size. Use a half of the pad if not set.
- if self.rounding_size:
- dr = mutation_size * self.rounding_size
- else:
- dr = pad / 2.
-
- width, height = (width + 2. * pad - 2 * dr,
- height + 2. * pad - 2 * dr)
-
- x0, y0 = x0 - pad + dr, y0 - pad + dr,
- x1, y1 = x0 + width, y0 + height
-
- cp = [(x0, y0),
- (x0 + dr, y0 - dr), (x1 - dr, y0 - dr), (x1, y0),
- (x1 + dr, y0 + dr), (x1 + dr, y1 - dr), (x1, y1),
- (x1 - dr, y1 + dr), (x0 + dr, y1 + dr), (x0, y1),
- (x0 - dr, y1 - dr), (x0 - dr, y0 + dr), (x0, y0),
- (x0, y0)]
-
- com = [Path.MOVETO,
- Path.CURVE4, Path.CURVE4, Path.CURVE4,
- Path.CURVE4, Path.CURVE4, Path.CURVE4,
- Path.CURVE4, Path.CURVE4, Path.CURVE4,
- Path.CURVE4, Path.CURVE4, Path.CURVE4,
- Path.CLOSEPOLY]
-
- path = Path(cp, com)
-
- return path
-
- _style_list["round4"] = Round4
-
- class Sawtooth(_Base):
- """
- A sawtooth box.
- """
-
- def __init__(self, pad=0.3, tooth_size=None):
- """
- *pad*
- amount of padding
-
- *tooth_size*
- size of the sawtooth. pad* if None
- """
- self.pad = pad
- self.tooth_size = tooth_size
- super(BoxStyle.Sawtooth, self).__init__()
-
- def _get_sawtooth_vertices(self, x0, y0, width, height, mutation_size):
-
- # padding
- pad = mutation_size * self.pad
-
- # size of sawtooth
- if self.tooth_size is None:
- tooth_size = self.pad * .5 * mutation_size
- else:
- tooth_size = self.tooth_size * mutation_size
-
- tooth_size2 = tooth_size / 2.
- width, height = (width + 2. * pad - tooth_size,
- height + 2. * pad - tooth_size)
-
- # the sizes of the vertical and horizontal sawtooth are
- # separately adjusted to fit the given box size.
- dsx_n = int(np.round((width - tooth_size) / (tooth_size * 2))) * 2
- dsx = (width - tooth_size) / dsx_n
- dsy_n = int(np.round((height - tooth_size) / (tooth_size * 2))) * 2
- dsy = (height - tooth_size) / dsy_n
-
- x0, y0 = x0 - pad + tooth_size2, y0 - pad + tooth_size2
- x1, y1 = x0 + width, y0 + height
-
- bottom_saw_x = [x0] + \
- [x0 + tooth_size2 + dsx * .5 * i
- for i
- in range(dsx_n * 2)] + \
- [x1 - tooth_size2]
-
- bottom_saw_y = [y0] + \
- [y0 - tooth_size2, y0,
- y0 + tooth_size2, y0] * dsx_n + \
- [y0 - tooth_size2]
-
- right_saw_x = [x1] + \
- [x1 + tooth_size2,
- x1,
- x1 - tooth_size2,
- x1] * dsx_n + \
- [x1 + tooth_size2]
-
- right_saw_y = [y0] + \
- [y0 + tooth_size2 + dsy * .5 * i
- for i
- in range(dsy_n * 2)] + \
- [y1 - tooth_size2]
-
- top_saw_x = [x1] + \
- [x1 - tooth_size2 - dsx * .5 * i
- for i
- in range(dsx_n * 2)] + \
- [x0 + tooth_size2]
-
- top_saw_y = [y1] + \
- [y1 + tooth_size2,
- y1,
- y1 - tooth_size2,
- y1] * dsx_n + \
- [y1 + tooth_size2]
-
- left_saw_x = [x0] + \
- [x0 - tooth_size2,
- x0,
- x0 + tooth_size2,
- x0] * dsy_n + \
- [x0 - tooth_size2]
-
- left_saw_y = [y1] + \
- [y1 - tooth_size2 - dsy * .5 * i
- for i
- in range(dsy_n * 2)] + \
- [y0 + tooth_size2]
-
- saw_vertices = (list(zip(bottom_saw_x, bottom_saw_y)) +
- list(zip(right_saw_x, right_saw_y)) +
- list(zip(top_saw_x, top_saw_y)) +
- list(zip(left_saw_x, left_saw_y)) +
- [(bottom_saw_x[0], bottom_saw_y[0])])
-
- return saw_vertices
-
- def transmute(self, x0, y0, width, height, mutation_size):
-
- saw_vertices = self._get_sawtooth_vertices(x0, y0, width,
- height, mutation_size)
- path = Path(saw_vertices, closed=True)
- return path
-
- _style_list["sawtooth"] = Sawtooth
-
- class Roundtooth(Sawtooth):
- """A rounded tooth box."""
- def __init__(self, pad=0.3, tooth_size=None):
- """
- *pad*
- amount of padding
-
- *tooth_size*
- size of the sawtooth. pad* if None
- """
- super(BoxStyle.Roundtooth, self).__init__(pad, tooth_size)
-
- def transmute(self, x0, y0, width, height, mutation_size):
- saw_vertices = self._get_sawtooth_vertices(x0, y0,
- width, height,
- mutation_size)
- # Add a trailing vertex to allow us to close the polygon correctly
- saw_vertices = np.concatenate([np.array(saw_vertices),
- [saw_vertices[0]]], axis=0)
- codes = ([Path.MOVETO] +
- [Path.CURVE3, Path.CURVE3] * ((len(saw_vertices)-1)//2) +
- [Path.CLOSEPOLY])
- return Path(saw_vertices, codes)
-
- _style_list["roundtooth"] = Roundtooth
-
- if __doc__: # __doc__ could be None if -OO optimization is enabled
- __doc__ = cbook.dedent(__doc__) % \
- {"AvailableBoxstyles": _pprint_styles(_style_list)}
-
-docstring.interpd.update(
- AvailableBoxstyles=_pprint_styles(BoxStyle._style_list),
- ListBoxstyles=_simpleprint_styles(BoxStyle._style_list))
-
-
-class FancyBboxPatch(Patch):
- """
- Draw a fancy box around a rectangle with lower left at *xy*=(*x*,
- *y*) with specified width and height.
-
- :class:`FancyBboxPatch` class is similar to :class:`Rectangle`
- class, but it draws a fancy box around the rectangle. The
- transformation of the rectangle box to the fancy box is delegated
- to the :class:`BoxTransmuterBase` and its derived classes.
-
- """
-
- _edge_default = True
-
- def __str__(self):
- return self.__class__.__name__ \
- + "(%g,%g;%gx%g)" % (self._x, self._y,
- self._width, self._height)
-
- @docstring.dedent_interpd
- def __init__(self, xy, width, height,
- boxstyle="round",
- bbox_transmuter=None,
- mutation_scale=1.,
- mutation_aspect=None,
- **kwargs):
- """
- *xy* = lower left corner
-
- *width*, *height*
-
- *boxstyle* determines what kind of fancy box will be drawn. It
- can be a string of the style name with a comma separated
- attribute, or an instance of :class:`BoxStyle`. Following box
- styles are available.
-
- %(AvailableBoxstyles)s
-
- *mutation_scale* : a value with which attributes of boxstyle
- (e.g., pad) will be scaled. default=1.
-
- *mutation_aspect* : The height of the rectangle will be
- squeezed by this value before the mutation and the mutated
- box will be stretched by the inverse of it. default=None.
-
- Valid kwargs are:
- %(Patch)s
- """
-
- Patch.__init__(self, **kwargs)
-
- self._x = xy[0]
- self._y = xy[1]
- self._width = width
- self._height = height
-
- if boxstyle == "custom":
- if bbox_transmuter is None:
- raise ValueError("bbox_transmuter argument is needed with "
- "custom boxstyle")
- self._bbox_transmuter = bbox_transmuter
- else:
- self.set_boxstyle(boxstyle)
-
- self._mutation_scale = mutation_scale
- self._mutation_aspect = mutation_aspect
-
- self.stale = True
-
- @docstring.dedent_interpd
- def set_boxstyle(self, boxstyle=None, **kw):
- """
- Set the box style.
-
- *boxstyle* can be a string with boxstyle name with optional
- comma-separated attributes. Alternatively, the attrs can
- be provided as keywords::
-
- set_boxstyle("round,pad=0.2")
- set_boxstyle("round", pad=0.2)
-
- Old attrs simply are forgotten.
-
- Without argument (or with *boxstyle* = None), it returns
- available box styles.
-
- The following boxstyles are available:
- %(AvailableBoxstyles)s
-
- ACCEPTS: %(ListBoxstyles)s
-
- """
- if boxstyle is None:
- return BoxStyle.pprint_styles()
-
- if isinstance(boxstyle, BoxStyle._Base) or callable(boxstyle):
- self._bbox_transmuter = boxstyle
- else:
- self._bbox_transmuter = BoxStyle(boxstyle, **kw)
- self.stale = True
-
- def set_mutation_scale(self, scale):
- """
- Set the mutation scale.
-
- ACCEPTS: float
- """
- self._mutation_scale = scale
- self.stale = True
-
- def get_mutation_scale(self):
- """
- Return the mutation scale.
- """
- return self._mutation_scale
-
- def set_mutation_aspect(self, aspect):
- """
- Set the aspect ratio of the bbox mutation.
-
- ACCEPTS: float
- """
- self._mutation_aspect = aspect
- self.stale = True
-
- def get_mutation_aspect(self):
- """
- Return the aspect ratio of the bbox mutation.
- """
- return self._mutation_aspect
-
- def get_boxstyle(self):
- "Return the boxstyle object"
- return self._bbox_transmuter
-
- def get_path(self):
- """
- Return the mutated path of the rectangle
- """
-
- _path = self.get_boxstyle()(self._x, self._y,
- self._width, self._height,
- self.get_mutation_scale(),
- self.get_mutation_aspect())
- return _path
-
- # Following methods are borrowed from the Rectangle class.
-
- def get_x(self):
- "Return the left coord of the rectangle"
- return self._x
-
- def get_y(self):
- "Return the bottom coord of the rectangle"
- return self._y
-
- def get_width(self):
- "Return the width of the rectangle"
- return self._width
-
- def get_height(self):
- "Return the height of the rectangle"
- return self._height
-
- def set_x(self, x):
- """
- Set the left coord of the rectangle
-
- ACCEPTS: float
- """
- self._x = x
- self.stale = True
-
- def set_y(self, y):
- """
- Set the bottom coord of the rectangle
-
- ACCEPTS: float
- """
- self._y = y
- self.stale = True
-
- def set_width(self, w):
- """
- Set the width rectangle
-
- ACCEPTS: float
- """
- self._width = w
- self.stale = True
-
- def set_height(self, h):
- """
- Set the width rectangle
-
- ACCEPTS: float
- """
- self._height = h
- self.stale = True
-
- def set_bounds(self, *args):
- """
- Set the bounds of the rectangle: l,b,w,h
-
- ACCEPTS: (left, bottom, width, height)
- """
- if len(args) == 0:
- l, b, w, h = args[0]
- else:
- l, b, w, h = args
- self._x = l
- self._y = b
- self._width = w
- self._height = h
- self.stale = True
-
- def get_bbox(self):
- return transforms.Bbox.from_bounds(self._x, self._y,
- self._width, self._height)
-
-
-class ConnectionStyle(_Style):
- """
- :class:`ConnectionStyle` is a container class which defines
- several connectionstyle classes, which is used to create a path
- between two points. These are mainly used with
- :class:`FancyArrowPatch`.
-
- A connectionstyle object can be either created as::
-
- ConnectionStyle.Arc3(rad=0.2)
-
- or::
-
- ConnectionStyle("Arc3", rad=0.2)
-
- or::
-
- ConnectionStyle("Arc3, rad=0.2")
-
- The following classes are defined
-
- %(AvailableConnectorstyles)s
-
-
- An instance of any connection style class is an callable object,
- whose call signature is::
-
- __call__(self, posA, posB,
- patchA=None, patchB=None,
- shrinkA=2., shrinkB=2.)
-
- and it returns a :class:`Path` instance. *posA* and *posB* are
- tuples of x,y coordinates of the two points to be
- connected. *patchA* (or *patchB*) is given, the returned path is
- clipped so that it start (or end) from the boundary of the
- patch. The path is further shrunk by *shrinkA* (or *shrinkB*)
- which is given in points.
-
- """
-
- _style_list = {}
-
- class _Base(object):
- """
- A base class for connectionstyle classes. The subclass needs
- to implement a *connect* method whose call signature is::
-
- connect(posA, posB)
-
- where posA and posB are tuples of x, y coordinates to be
- connected. The method needs to return a path connecting two
- points. This base class defines a __call__ method, and a few
- helper methods.
- """
-
- class SimpleEvent:
- def __init__(self, xy):
- self.x, self.y = xy
-
- def _clip(self, path, patchA, patchB):
- """
- Clip the path to the boundary of the patchA and patchB.
- The starting point of the path needed to be inside of the
- patchA and the end point inside the patch B. The *contains*
- methods of each patch object is utilized to test if the point
- is inside the path.
- """
-
- if patchA:
- def insideA(xy_display):
- xy_event = ConnectionStyle._Base.SimpleEvent(xy_display)
- return patchA.contains(xy_event)[0]
-
- try:
- left, right = split_path_inout(path, insideA)
- except ValueError:
- right = path
-
- path = right
-
- if patchB:
- def insideB(xy_display):
- xy_event = ConnectionStyle._Base.SimpleEvent(xy_display)
- return patchB.contains(xy_event)[0]
-
- try:
- left, right = split_path_inout(path, insideB)
- except ValueError:
- left = path
-
- path = left
-
- return path
-
- def _shrink(self, path, shrinkA, shrinkB):
- """
- Shrink the path by fixed size (in points) with shrinkA and shrinkB
- """
- if shrinkA:
- x, y = path.vertices[0]
- insideA = inside_circle(x, y, shrinkA)
-
- try:
- left, right = split_path_inout(path, insideA)
- path = right
- except ValueError:
- pass
-
- if shrinkB:
- x, y = path.vertices[-1]
- insideB = inside_circle(x, y, shrinkB)
-
- try:
- left, right = split_path_inout(path, insideB)
- path = left
- except ValueError:
- pass
-
- return path
-
- def __call__(self, posA, posB,
- shrinkA=2., shrinkB=2., patchA=None, patchB=None):
- """
- Calls the *connect* method to create a path between *posA*
- and *posB*. The path is clipped and shrunken.
- """
-
- path = self.connect(posA, posB)
-
- clipped_path = self._clip(path, patchA, patchB)
- shrunk_path = self._shrink(clipped_path, shrinkA, shrinkB)
-
- return shrunk_path
-
- def __reduce__(self):
- # because we have decided to nest these classes, we need to
- # add some more information to allow instance pickling.
- return (cbook._NestedClassGetter(),
- (ConnectionStyle, self.__class__.__name__),
- self.__dict__
- )
-
- class Arc3(_Base):
- """
- Creates a simple quadratic bezier curve between two
- points. The curve is created so that the middle control point
- (C1) is located at the same distance from the start (C0) and
- end points(C2) and the distance of the C1 to the line
- connecting C0-C2 is *rad* times the distance of C0-C2.
- """
-
- def __init__(self, rad=0.):
- """
- *rad*
- curvature of the curve.
- """
- self.rad = rad
-
- def connect(self, posA, posB):
- x1, y1 = posA
- x2, y2 = posB
- x12, y12 = (x1 + x2) / 2., (y1 + y2) / 2.
- dx, dy = x2 - x1, y2 - y1
-
- f = self.rad
-
- cx, cy = x12 + f * dy, y12 - f * dx
-
- vertices = [(x1, y1),
- (cx, cy),
- (x2, y2)]
- codes = [Path.MOVETO,
- Path.CURVE3,
- Path.CURVE3]
-
- return Path(vertices, codes)
-
- _style_list["arc3"] = Arc3
-
- class Angle3(_Base):
- """
- Creates a simple quadratic bezier curve between two
- points. The middle control points is placed at the
- intersecting point of two lines which crosses the start (or
- end) point and has a angle of angleA (or angleB).
- """
-
- def __init__(self, angleA=90, angleB=0):
- """
- *angleA*
- starting angle of the path
-
- *angleB*
- ending angle of the path
- """
-
- self.angleA = angleA
- self.angleB = angleB
-
- def connect(self, posA, posB):
- x1, y1 = posA
- x2, y2 = posB
-
- cosA = math.cos(math.radians(self.angleA))
- sinA = math.sin(math.radians(self.angleA))
- cosB = math.cos(math.radians(self.angleB))
- sinB = math.sin(math.radians(self.angleB))
-
- cx, cy = get_intersection(x1, y1, cosA, sinA,
- x2, y2, cosB, sinB)
-
- vertices = [(x1, y1), (cx, cy), (x2, y2)]
- codes = [Path.MOVETO, Path.CURVE3, Path.CURVE3]
-
- return Path(vertices, codes)
-
- _style_list["angle3"] = Angle3
-
- class Angle(_Base):
- """
- Creates a picewise continuous quadratic bezier path between
- two points. The path has a one passing-through point placed at
- the intersecting point of two lines which crosses the start
- (or end) point and has a angle of angleA (or angleB). The
- connecting edges are rounded with *rad*.
- """
-
- def __init__(self, angleA=90, angleB=0, rad=0.):
- """
- *angleA*
- starting angle of the path
-
- *angleB*
- ending angle of the path
-
- *rad*
- rounding radius of the edge
- """
-
- self.angleA = angleA
- self.angleB = angleB
-
- self.rad = rad
-
- def connect(self, posA, posB):
- x1, y1 = posA
- x2, y2 = posB
-
- cosA = math.cos(math.radians(self.angleA))
- sinA = math.sin(math.radians(self.angleA))
- cosB = math.cos(math.radians(self.angleB))
- sinB = math.sin(math.radians(self.angleB))
-
- cx, cy = get_intersection(x1, y1, cosA, sinA,
- x2, y2, cosB, sinB)
-
- vertices = [(x1, y1)]
- codes = [Path.MOVETO]
-
- if self.rad == 0.:
- vertices.append((cx, cy))
- codes.append(Path.LINETO)
- else:
- dx1, dy1 = x1 - cx, y1 - cy
- d1 = (dx1 ** 2 + dy1 ** 2) ** .5
- f1 = self.rad / d1
- dx2, dy2 = x2 - cx, y2 - cy
- d2 = (dx2 ** 2 + dy2 ** 2) ** .5
- f2 = self.rad / d2
- vertices.extend([(cx + dx1 * f1, cy + dy1 * f1),
- (cx, cy),
- (cx + dx2 * f2, cy + dy2 * f2)])
- codes.extend([Path.LINETO, Path.CURVE3, Path.CURVE3])
-
- vertices.append((x2, y2))
- codes.append(Path.LINETO)
-
- return Path(vertices, codes)
-
- _style_list["angle"] = Angle
-
- class Arc(_Base):
- """
- Creates a picewise continuous quadratic bezier path between
- two points. The path can have two passing-through points, a
- point placed at the distance of armA and angle of angleA from
- point A, another point with respect to point B. The edges are
- rounded with *rad*.
- """
-
- def __init__(self, angleA=0, angleB=0, armA=None, armB=None, rad=0.):
- """
- *angleA* :
- starting angle of the path
-
- *angleB* :
- ending angle of the path
-
- *armA* :
- length of the starting arm
-
- *armB* :
- length of the ending arm
-
- *rad* :
- rounding radius of the edges
- """
-
- self.angleA = angleA
- self.angleB = angleB
- self.armA = armA
- self.armB = armB
-
- self.rad = rad
-
- def connect(self, posA, posB):
- x1, y1 = posA
- x2, y2 = posB
-
- vertices = [(x1, y1)]
- rounded = []
- codes = [Path.MOVETO]
-
- if self.armA:
- cosA = math.cos(math.radians(self.angleA))
- sinA = math.sin(math.radians(self.angleA))
- # x_armA, y_armB
- d = self.armA - self.rad
- rounded.append((x1 + d * cosA, y1 + d * sinA))
- d = self.armA
- rounded.append((x1 + d * cosA, y1 + d * sinA))
-
- if self.armB:
- cosB = math.cos(math.radians(self.angleB))
- sinB = math.sin(math.radians(self.angleB))
- x_armB, y_armB = x2 + self.armB * cosB, y2 + self.armB * sinB
-
- if rounded:
- xp, yp = rounded[-1]
- dx, dy = x_armB - xp, y_armB - yp
- dd = (dx * dx + dy * dy) ** .5
-
- rounded.append((xp + self.rad * dx / dd,
- yp + self.rad * dy / dd))
- vertices.extend(rounded)
- codes.extend([Path.LINETO,
- Path.CURVE3,
- Path.CURVE3])
- else:
- xp, yp = vertices[-1]
- dx, dy = x_armB - xp, y_armB - yp
- dd = (dx * dx + dy * dy) ** .5
-
- d = dd - self.rad
- rounded = [(xp + d * dx / dd, yp + d * dy / dd),
- (x_armB, y_armB)]
-
- if rounded:
- xp, yp = rounded[-1]
- dx, dy = x2 - xp, y2 - yp
- dd = (dx * dx + dy * dy) ** .5
-
- rounded.append((xp + self.rad * dx / dd,
- yp + self.rad * dy / dd))
- vertices.extend(rounded)
- codes.extend([Path.LINETO,
- Path.CURVE3,
- Path.CURVE3])
-
- vertices.append((x2, y2))
- codes.append(Path.LINETO)
-
- return Path(vertices, codes)
-
- _style_list["arc"] = Arc
-
- class Bar(_Base):
- """
- A line with *angle* between A and B with *armA* and
- *armB*. One of the arms is extended so that they are connected in
- a right angle. The length of armA is determined by (*armA*
- + *fraction* x AB distance). Same for armB.
- """
-
- def __init__(self, armA=0., armB=0., fraction=0.3, angle=None):
- """
- Parameters
- ----------
- armA : float
- minimum length of armA
-
- armB : float
- minimum length of armB
-
- fraction : float
- a fraction of the distance between two points that
- will be added to armA and armB.
-
- angle : float or None
- angle of the connecting line (if None, parallel
- to A and B)
- """
- self.armA = armA
- self.armB = armB
- self.fraction = fraction
- self.angle = angle
-
- def connect(self, posA, posB):
- x1, y1 = posA
- x20, y20 = x2, y2 = posB
-
- theta1 = math.atan2(y2 - y1, x2 - x1)
- dx, dy = x2 - x1, y2 - y1
- dd = (dx * dx + dy * dy) ** .5
- ddx, ddy = dx / dd, dy / dd
-
- armA, armB = self.armA, self.armB
-
- if self.angle is not None:
- theta0 = np.deg2rad(self.angle)
- dtheta = theta1 - theta0
- dl = dd * math.sin(dtheta)
- dL = dd * math.cos(dtheta)
- x2, y2 = x1 + dL * math.cos(theta0), y1 + dL * math.sin(theta0)
- armB = armB - dl
-
- # update
- dx, dy = x2 - x1, y2 - y1
- dd2 = (dx * dx + dy * dy) ** .5
- ddx, ddy = dx / dd2, dy / dd2
-
- else:
- dl = 0.
-
- arm = max(armA, armB)
- f = self.fraction * dd + arm
-
- cx1, cy1 = x1 + f * ddy, y1 - f * ddx
- cx2, cy2 = x2 + f * ddy, y2 - f * ddx
-
- vertices = [(x1, y1),
- (cx1, cy1),
- (cx2, cy2),
- (x20, y20)]
- codes = [Path.MOVETO,
- Path.LINETO,
- Path.LINETO,
- Path.LINETO]
-
- return Path(vertices, codes)
-
- _style_list["bar"] = Bar
-
- if __doc__:
- __doc__ = cbook.dedent(__doc__) % \
- {"AvailableConnectorstyles": _pprint_styles(_style_list)}
-
-
-def _point_along_a_line(x0, y0, x1, y1, d):
- """
- find a point along a line connecting (x0, y0) -- (x1, y1) whose
- distance from (x0, y0) is d.
- """
- dx, dy = x0 - x1, y0 - y1
- ff = d / (dx * dx + dy * dy) ** .5
- x2, y2 = x0 - ff * dx, y0 - ff * dy
-
- return x2, y2
-
-
-class ArrowStyle(_Style):
- """
- :class:`ArrowStyle` is a container class which defines several
- arrowstyle classes, which is used to create an arrow path along a
- given path. These are mainly used with :class:`FancyArrowPatch`.
-
- A arrowstyle object can be either created as::
-
- ArrowStyle.Fancy(head_length=.4, head_width=.4, tail_width=.4)
-
- or::
-
- ArrowStyle("Fancy", head_length=.4, head_width=.4, tail_width=.4)
-
- or::
-
- ArrowStyle("Fancy, head_length=.4, head_width=.4, tail_width=.4")
-
- The following classes are defined
-
- %(AvailableArrowstyles)s
-
-
- An instance of any arrow style class is a callable object,
- whose call signature is::
-
- __call__(self, path, mutation_size, linewidth, aspect_ratio=1.)
-
- and it returns a tuple of a :class:`Path` instance and a boolean
- value. *path* is a :class:`Path` instance along which the arrow
- will be drawn. *mutation_size* and *aspect_ratio* have the same
- meaning as in :class:`BoxStyle`. *linewidth* is a line width to be
- stroked. This is meant to be used to correct the location of the
- head so that it does not overshoot the destination point, but not all
- classes support it.
- """
-
- _style_list = {}
-
- class _Base(object):
- """
- Arrow Transmuter Base class
-
- ArrowTransmuterBase and its derivatives are used to make a fancy
- arrow around a given path. The __call__ method returns a path
- (which will be used to create a PathPatch instance) and a boolean
- value indicating the path is open therefore is not fillable. This
- class is not an artist and actual drawing of the fancy arrow is
- done by the FancyArrowPatch class.
-
- """
-
- # The derived classes are required to be able to be initialized
- # w/o arguments, i.e., all its argument (except self) must have
- # the default values.
-
- @staticmethod
- def ensure_quadratic_bezier(path):
- """ Some ArrowStyle class only wokrs with a simple
- quaratic bezier curve (created with Arc3Connetion or
- Angle3Connector). This static method is to check if the
- provided path is a simple quadratic bezier curve and returns
- its control points if true.
- """
- segments = list(path.iter_segments())
- if (len(segments) != 2 or segments[0][1] != Path.MOVETO or
- segments[1][1] != Path.CURVE3):
- raise ValueError(
- "'path' it's not a valid quadratic Bezier curve")
-
- return list(segments[0][0]) + list(segments[1][0])
-
- def transmute(self, path, mutation_size, linewidth):
- """
- The transmute method is the very core of the ArrowStyle
- class and must be overridden in the subclasses. It receives
- the path object along which the arrow will be drawn, and
- the mutation_size, with which the arrow head etc.
- will be scaled. The linewidth may be used to adjust
- the path so that it does not pass beyond the given
- points. It returns a tuple of a Path instance and a
- boolean. The boolean value indicate whether the path can
- be filled or not. The return value can also be a list of paths
- and list of booleans of a same length.
- """
-
- raise NotImplementedError('Derived must override')
-
- def __call__(self, path, mutation_size, linewidth,
- aspect_ratio=1.):
- """
- The __call__ method is a thin wrapper around the transmute method
- and take care of the aspect ratio.
- """
-
- path = make_path_regular(path)
-
- if aspect_ratio is not None:
- # Squeeze the given height by the aspect_ratio
-
- vertices, codes = path.vertices[:], path.codes[:]
- # Squeeze the height
- vertices[:, 1] = vertices[:, 1] / aspect_ratio
- path_shrunk = Path(vertices, codes)
- # call transmute method with squeezed height.
- path_mutated, fillable = self.transmute(path_shrunk,
- linewidth,
- mutation_size)
- if cbook.iterable(fillable):
- path_list = []
- for p in zip(path_mutated):
- v, c = p.vertices, p.codes
- # Restore the height
- v[:, 1] = v[:, 1] * aspect_ratio
- path_list.append(Path(v, c))
- return path_list, fillable
- else:
- return path_mutated, fillable
- else:
- return self.transmute(path, mutation_size, linewidth)
-
- def __reduce__(self):
- # because we have decided to nest these classes, we need to
- # add some more information to allow instance pickling.
- return (cbook._NestedClassGetter(),
- (ArrowStyle, self.__class__.__name__),
- self.__dict__
- )
-
- class _Curve(_Base):
- """
- A simple arrow which will work with any path instance. The
- returned path is simply concatenation of the original path + at
- most two paths representing the arrow head at the begin point and the
- at the end point. The arrow heads can be either open or closed.
- """
-
- def __init__(self, beginarrow=None, endarrow=None,
- fillbegin=False, fillend=False,
- head_length=.2, head_width=.1):
- """
- The arrows are drawn if *beginarrow* and/or *endarrow* are
- true. *head_length* and *head_width* determines the size
- of the arrow relative to the *mutation scale*. The
- arrowhead at the begin (or end) is closed if fillbegin (or
- fillend) is True.
- """
- self.beginarrow, self.endarrow = beginarrow, endarrow
- self.head_length, self.head_width = head_length, head_width
- self.fillbegin, self.fillend = fillbegin, fillend
- super(ArrowStyle._Curve, self).__init__()
-
- def _get_arrow_wedge(self, x0, y0, x1, y1,
- head_dist, cos_t, sin_t, linewidth
- ):
- """
- Return the paths for arrow heads. Since arrow lines are
- drawn with capstyle=projected, The arrow goes beyond the
- desired point. This method also returns the amount of the path
- to be shrunken so that it does not overshoot.
- """
-
- # arrow from x0, y0 to x1, y1
- dx, dy = x0 - x1, y0 - y1
-
- cp_distance = np.hypot(dx, dy)
-
- # pad_projected : amount of pad to account the
- # overshooting of the projection of the wedge
- pad_projected = (.5 * linewidth / sin_t)
-
- # Account for division by zero
- if cp_distance == 0:
- cp_distance = 1
-
- # apply pad for projected edge
- ddx = pad_projected * dx / cp_distance
- ddy = pad_projected * dy / cp_distance
-
- # offset for arrow wedge
- dx = dx / cp_distance * head_dist
- dy = dy / cp_distance * head_dist
-
- dx1, dy1 = cos_t * dx + sin_t * dy, -sin_t * dx + cos_t * dy
- dx2, dy2 = cos_t * dx - sin_t * dy, sin_t * dx + cos_t * dy
-
- vertices_arrow = [(x1 + ddx + dx1, y1 + ddy + dy1),
- (x1 + ddx, y1 + ddy),
- (x1 + ddx + dx2, y1 + ddy + dy2)]
- codes_arrow = [Path.MOVETO,
- Path.LINETO,
- Path.LINETO]
-
- return vertices_arrow, codes_arrow, ddx, ddy
-
- def transmute(self, path, mutation_size, linewidth):
-
- head_length = self.head_length * mutation_size
- head_width = self.head_width * mutation_size
- head_dist = math.sqrt(head_length ** 2 + head_width ** 2)
- cos_t, sin_t = head_length / head_dist, head_width / head_dist
-
- # begin arrow
- x0, y0 = path.vertices[0]
- x1, y1 = path.vertices[1]
-
- # If there is no room for an arrow and a line, then skip the arrow
- has_begin_arrow = self.beginarrow and not (x0 == x1 and y0 == y1)
- if has_begin_arrow:
- verticesA, codesA, ddxA, ddyA = \
- self._get_arrow_wedge(x1, y1, x0, y0,
- head_dist, cos_t, sin_t,
- linewidth)
- else:
- verticesA, codesA = [], []
- ddxA, ddyA = 0., 0.
-
- # end arrow
- x2, y2 = path.vertices[-2]
- x3, y3 = path.vertices[-1]
-
- # If there is no room for an arrow and a line, then skip the arrow
- has_end_arrow = (self.endarrow and not ((x2 == x3) and (y2 == y3)))
- if has_end_arrow:
- verticesB, codesB, ddxB, ddyB = \
- self._get_arrow_wedge(x2, y2, x3, y3,
- head_dist, cos_t, sin_t,
- linewidth)
- else:
- verticesB, codesB = [], []
- ddxB, ddyB = 0., 0.
-
- # this simple code will not work if ddx, ddy is greater than
- # separation bettern vertices.
- _path = [Path(np.concatenate([[(x0 + ddxA, y0 + ddyA)],
- path.vertices[1:-1],
- [(x3 + ddxB, y3 + ddyB)]]),
- path.codes)]
- _fillable = [False]
-
- if has_begin_arrow:
- if self.fillbegin:
- p = np.concatenate([verticesA, [verticesA[0],
- verticesA[0]], ])
- c = np.concatenate([codesA, [Path.LINETO, Path.CLOSEPOLY]])
- _path.append(Path(p, c))
- _fillable.append(True)
- else:
- _path.append(Path(verticesA, codesA))
- _fillable.append(False)
-
- if has_end_arrow:
- if self.fillend:
- _fillable.append(True)
- p = np.concatenate([verticesB, [verticesB[0],
- verticesB[0]], ])
- c = np.concatenate([codesB, [Path.LINETO, Path.CLOSEPOLY]])
- _path.append(Path(p, c))
- else:
- _fillable.append(False)
- _path.append(Path(verticesB, codesB))
-
- return _path, _fillable
-
- class Curve(_Curve):
- """
- A simple curve without any arrow head.
- """
-
- def __init__(self):
- super(ArrowStyle.Curve, self).__init__(
- beginarrow=False, endarrow=False)
-
- _style_list["-"] = Curve
-
- class CurveA(_Curve):
- """
- An arrow with a head at its begin point.
- """
-
- def __init__(self, head_length=.4, head_width=.2):
- """
- Parameters
- ----------
- head_length : float, optional, default : 0.4
- Length of the arrow head
-
- head_width : float, optional, default : 0.2
- Width of the arrow head
- """
-
- super(ArrowStyle.CurveA, self).__init__(
- beginarrow=True, endarrow=False,
- head_length=head_length, head_width=head_width)
-
- _style_list["<-"] = CurveA
-
- class CurveB(_Curve):
- """
- An arrow with a head at its end point.
- """
-
- def __init__(self, head_length=.4, head_width=.2):
- """
- Parameters
- ----------
- head_length : float, optional, default : 0.4
- Length of the arrow head
-
- head_width : float, optional, default : 0.2
- Width of the arrow head
- """
-
- super(ArrowStyle.CurveB, self).__init__(
- beginarrow=False, endarrow=True,
- head_length=head_length, head_width=head_width)
-
- _style_list["->"] = CurveB
-
- class CurveAB(_Curve):
- """
- An arrow with heads both at the begin and the end point.
- """
-
- def __init__(self, head_length=.4, head_width=.2):
- """
- Parameters
- ----------
- head_length : float, optional, default : 0.4
- Length of the arrow head
-
- head_width : float, optional, default : 0.2
- Width of the arrow head
- """
-
- super(ArrowStyle.CurveAB, self).__init__(
- beginarrow=True, endarrow=True,
- head_length=head_length, head_width=head_width)
-
- _style_list["<->"] = CurveAB
-
- class CurveFilledA(_Curve):
- """
- An arrow with filled triangle head at the begin.
- """
-
- def __init__(self, head_length=.4, head_width=.2):
- """
- Parameters
- ----------
- head_length : float, optional, default : 0.4
- Length of the arrow head
-
- head_width : float, optional, default : 0.2
- Width of the arrow head
- """
-
- super(ArrowStyle.CurveFilledA, self).__init__(
- beginarrow=True, endarrow=False,
- fillbegin=True, fillend=False,
- head_length=head_length, head_width=head_width)
-
- _style_list["<|-"] = CurveFilledA
-
- class CurveFilledB(_Curve):
- """
- An arrow with filled triangle head at the end.
- """
-
- def __init__(self, head_length=.4, head_width=.2):
- """
- Parameters
- ----------
- head_length : float, optional, default : 0.4
- Length of the arrow head
-
- head_width : float, optional, default : 0.2
- Width of the arrow head
- """
-
- super(ArrowStyle.CurveFilledB, self).__init__(
- beginarrow=False, endarrow=True,
- fillbegin=False, fillend=True,
- head_length=head_length, head_width=head_width)
-
- _style_list["-|>"] = CurveFilledB
-
- class CurveFilledAB(_Curve):
- """
- An arrow with filled triangle heads at both ends.
- """
-
- def __init__(self, head_length=.4, head_width=.2):
- """
- Parameters
- ----------
- head_length : float, optional, default : 0.4
- Length of the arrow head
-
- head_width : float, optional, default : 0.2
- Width of the arrow head
- """
-
- super(ArrowStyle.CurveFilledAB, self).__init__(
- beginarrow=True, endarrow=True,
- fillbegin=True, fillend=True,
- head_length=head_length, head_width=head_width)
-
- _style_list["<|-|>"] = CurveFilledAB
-
- class _Bracket(_Base):
-
- def __init__(self, bracketA=None, bracketB=None,
- widthA=1., widthB=1.,
- lengthA=0.2, lengthB=0.2,
- angleA=None, angleB=None,
- scaleA=None, scaleB=None):
- self.bracketA, self.bracketB = bracketA, bracketB
- self.widthA, self.widthB = widthA, widthB
- self.lengthA, self.lengthB = lengthA, lengthB
- self.angleA, self.angleB = angleA, angleB
- self.scaleA, self.scaleB = scaleA, scaleB
-
- def _get_bracket(self, x0, y0,
- cos_t, sin_t, width, length):
-
- # arrow from x0, y0 to x1, y1
- from matplotlib.bezier import get_normal_points
- x1, y1, x2, y2 = get_normal_points(x0, y0, cos_t, sin_t, width)
-
- dx, dy = length * cos_t, length * sin_t
-
- vertices_arrow = [(x1 + dx, y1 + dy),
- (x1, y1),
- (x2, y2),
- (x2 + dx, y2 + dy)]
- codes_arrow = [Path.MOVETO,
- Path.LINETO,
- Path.LINETO,
- Path.LINETO]
-
- return vertices_arrow, codes_arrow
-
- def transmute(self, path, mutation_size, linewidth):
-
- if self.scaleA is None:
- scaleA = mutation_size
- else:
- scaleA = self.scaleA
-
- if self.scaleB is None:
- scaleB = mutation_size
- else:
- scaleB = self.scaleB
-
- vertices_list, codes_list = [], []
-
- if self.bracketA:
- x0, y0 = path.vertices[0]
- x1, y1 = path.vertices[1]
- cos_t, sin_t = get_cos_sin(x1, y1, x0, y0)
- verticesA, codesA = self._get_bracket(x0, y0, cos_t, sin_t,
- self.widthA * scaleA,
- self.lengthA * scaleA)
- vertices_list.append(verticesA)
- codes_list.append(codesA)
-
- vertices_list.append(path.vertices)
- codes_list.append(path.codes)
-
- if self.bracketB:
- x0, y0 = path.vertices[-1]
- x1, y1 = path.vertices[-2]
- cos_t, sin_t = get_cos_sin(x1, y1, x0, y0)
- verticesB, codesB = self._get_bracket(x0, y0, cos_t, sin_t,
- self.widthB * scaleB,
- self.lengthB * scaleB)
- vertices_list.append(verticesB)
- codes_list.append(codesB)
-
- vertices = np.concatenate(vertices_list)
- codes = np.concatenate(codes_list)
-
- p = Path(vertices, codes)
-
- return p, False
-
- class BracketAB(_Bracket):
- """
- An arrow with a bracket(]) at both ends.
- """
-
- def __init__(self,
- widthA=1., lengthA=0.2, angleA=None,
- widthB=1., lengthB=0.2, angleB=None):
- """
- Parameters
- ----------
- widthA : float, optional, default : 1.0
- Width of the bracket
-
- lengthA : float, optional, default : 0.2
- Length of the bracket
-
- angleA : float, optional, default : None
- Angle between the bracket and the line
-
- widthB : float, optional, default : 1.0
- Width of the bracket
-
- lengthB : float, optional, default : 0.2
- Length of the bracket
-
- angleB : float, optional, default : None
- Angle between the bracket and the line
- """
-
- super(ArrowStyle.BracketAB, self).__init__(
- True, True, widthA=widthA, lengthA=lengthA,
- angleA=angleA, widthB=widthB, lengthB=lengthB,
- angleB=angleB)
-
- _style_list["]-["] = BracketAB
-
- class BracketA(_Bracket):
- """
- An arrow with a bracket(]) at its end.
- """
-
- def __init__(self, widthA=1., lengthA=0.2, angleA=None):
- """
- Parameters
- ----------
- widthA : float, optional, default : 1.0
- Width of the bracket
-
- lengthA : float, optional, default : 0.2
- Length of the bracket
-
- angleA : float, optional, default : None
- Angle between the bracket and the line
- """
-
- super(ArrowStyle.BracketA, self).__init__(True, None,
- widthA=widthA,
- lengthA=lengthA,
- angleA=angleA)
-
- _style_list["]-"] = BracketA
-
- class BracketB(_Bracket):
- """
- An arrow with a bracket([) at its end.
- """
-
- def __init__(self, widthB=1., lengthB=0.2, angleB=None):
- """
- Parameters
- ----------
- widthB : float, optional, default : 1.0
- Width of the bracket
-
- lengthB : float, optional, default : 0.2
- Length of the bracket
-
- angleB : float, optional, default : None
- Angle between the bracket and the line
- """
-
- super(ArrowStyle.BracketB, self).__init__(None, True,
- widthB=widthB,
- lengthB=lengthB,
- angleB=angleB)
-
- _style_list["-["] = BracketB
-
- class BarAB(_Bracket):
- """
- An arrow with a bar(|) at both ends.
- """
-
- def __init__(self,
- widthA=1., angleA=None,
- widthB=1., angleB=None):
- """
- Parameters
- ----------
- widthA : float, optional, default : 1.0
- Width of the bracket
-
- angleA : float, optional, default : None
- Angle between the bracket and the line
-
- widthB : float, optional, default : 1.0
- Width of the bracket
-
- angleB : float, optional, default : None
- Angle between the bracket and the line
- """
-
- super(ArrowStyle.BarAB, self).__init__(
- True, True, widthA=widthA, lengthA=0, angleA=angleA,
- widthB=widthB, lengthB=0, angleB=angleB)
-
- _style_list["|-|"] = BarAB
-
- class Simple(_Base):
- """
- A simple arrow. Only works with a quadratic bezier curve.
- """
-
- def __init__(self, head_length=.5, head_width=.5, tail_width=.2):
- """
- Parameters
- ----------
- head_length : float, optional, default : 0.5
- Length of the arrow head
-
- head_width : float, optional, default : 0.5
- Width of the arrow head
-
- tail_width : float, optional, default : 0.2
- Width of the arrow tail
- """
-
- self.head_length, self.head_width, self.tail_width = \
- head_length, head_width, tail_width
- super(ArrowStyle.Simple, self).__init__()
-
- def transmute(self, path, mutation_size, linewidth):
-
- x0, y0, x1, y1, x2, y2 = self.ensure_quadratic_bezier(path)
-
- # divide the path into a head and a tail
- head_length = self.head_length * mutation_size
- in_f = inside_circle(x2, y2, head_length)
- arrow_path = [(x0, y0), (x1, y1), (x2, y2)]
-
- from .bezier import NonIntersectingPathException
-
- try:
- arrow_out, arrow_in = \
- split_bezier_intersecting_with_closedpath(arrow_path,
- in_f,
- tolerence=0.01)
- except NonIntersectingPathException:
- # if this happens, make a straight line of the head_length
- # long.
- x0, y0 = _point_along_a_line(x2, y2, x1, y1, head_length)
- x1n, y1n = 0.5 * (x0 + x2), 0.5 * (y0 + y2)
- arrow_in = [(x0, y0), (x1n, y1n), (x2, y2)]
- arrow_out = None
-
- # head
- head_width = self.head_width * mutation_size
- head_left, head_right = make_wedged_bezier2(arrow_in,
- head_width / 2., wm=.5)
-
- # tail
- if arrow_out is not None:
- tail_width = self.tail_width * mutation_size
- tail_left, tail_right = get_parallels(arrow_out,
- tail_width / 2.)
-
- patch_path = [(Path.MOVETO, tail_right[0]),
- (Path.CURVE3, tail_right[1]),
- (Path.CURVE3, tail_right[2]),
- (Path.LINETO, head_right[0]),
- (Path.CURVE3, head_right[1]),
- (Path.CURVE3, head_right[2]),
- (Path.CURVE3, head_left[1]),
- (Path.CURVE3, head_left[0]),
- (Path.LINETO, tail_left[2]),
- (Path.CURVE3, tail_left[1]),
- (Path.CURVE3, tail_left[0]),
- (Path.LINETO, tail_right[0]),
- (Path.CLOSEPOLY, tail_right[0]),
- ]
- else:
- patch_path = [(Path.MOVETO, head_right[0]),
- (Path.CURVE3, head_right[1]),
- (Path.CURVE3, head_right[2]),
- (Path.CURVE3, head_left[1]),
- (Path.CURVE3, head_left[0]),
- (Path.CLOSEPOLY, head_left[0]),
- ]
-
- path = Path([p for c, p in patch_path], [c for c, p in patch_path])
-
- return path, True
-
- _style_list["simple"] = Simple
-
- class Fancy(_Base):
- """
- A fancy arrow. Only works with a quadratic bezier curve.
- """
-
- def __init__(self, head_length=.4, head_width=.4, tail_width=.4):
- """
- Parameters
- ----------
- head_length : float, optional, default : 0.4
- Length of the arrow head
-
- head_width : float, optional, default : 0.4
- Width of the arrow head
-
- tail_width : float, optional, default : 0.4
- Width of the arrow tail
- """
-
- self.head_length, self.head_width, self.tail_width = \
- head_length, head_width, tail_width
- super(ArrowStyle.Fancy, self).__init__()
-
- def transmute(self, path, mutation_size, linewidth):
-
- x0, y0, x1, y1, x2, y2 = self.ensure_quadratic_bezier(path)
-
- # divide the path into a head and a tail
- head_length = self.head_length * mutation_size
- arrow_path = [(x0, y0), (x1, y1), (x2, y2)]
-
- from .bezier import NonIntersectingPathException
-
- # path for head
- in_f = inside_circle(x2, y2, head_length)
- try:
- path_out, path_in = \
- split_bezier_intersecting_with_closedpath(
- arrow_path,
- in_f,
- tolerence=0.01)
- except NonIntersectingPathException:
- # if this happens, make a straight line of the head_length
- # long.
- x0, y0 = _point_along_a_line(x2, y2, x1, y1, head_length)
- x1n, y1n = 0.5 * (x0 + x2), 0.5 * (y0 + y2)
- arrow_path = [(x0, y0), (x1n, y1n), (x2, y2)]
- path_head = arrow_path
- else:
- path_head = path_in
-
- # path for head
- in_f = inside_circle(x2, y2, head_length * .8)
- path_out, path_in = split_bezier_intersecting_with_closedpath(
- arrow_path,
- in_f,
- tolerence=0.01
- )
- path_tail = path_out
-
- # head
- head_width = self.head_width * mutation_size
- head_l, head_r = make_wedged_bezier2(path_head,
- head_width / 2.,
- wm=.6)
-
- # tail
- tail_width = self.tail_width * mutation_size
- tail_left, tail_right = make_wedged_bezier2(path_tail,
- tail_width * .5,
- w1=1., wm=0.6, w2=0.3)
-
- # path for head
- in_f = inside_circle(x0, y0, tail_width * .3)
- path_in, path_out = split_bezier_intersecting_with_closedpath(
- arrow_path,
- in_f,
- tolerence=0.01
- )
- tail_start = path_in[-1]
-
- head_right, head_left = head_r, head_l
- patch_path = [(Path.MOVETO, tail_start),
- (Path.LINETO, tail_right[0]),
- (Path.CURVE3, tail_right[1]),
- (Path.CURVE3, tail_right[2]),
- (Path.LINETO, head_right[0]),
- (Path.CURVE3, head_right[1]),
- (Path.CURVE3, head_right[2]),
- (Path.CURVE3, head_left[1]),
- (Path.CURVE3, head_left[0]),
- (Path.LINETO, tail_left[2]),
- (Path.CURVE3, tail_left[1]),
- (Path.CURVE3, tail_left[0]),
- (Path.LINETO, tail_start),
- (Path.CLOSEPOLY, tail_start),
- ]
- path = Path([p for c, p in patch_path], [c for c, p in patch_path])
-
- return path, True
-
- _style_list["fancy"] = Fancy
-
- class Wedge(_Base):
- """
- Wedge(?) shape. Only works with a quadratic bezier curve. The
- begin point has a width of the tail_width and the end point has a
- width of 0. At the middle, the width is shrink_factor*tail_width.
- """
-
- def __init__(self, tail_width=.3, shrink_factor=0.5):
- """
- Parameters
- ----------
- tail_width : float, optional, default : 0.3
- Width of the tail
-
- shrink_factor : float, optional, default : 0.5
- Fraction of the arrow width at the middle point
- """
-
- self.tail_width = tail_width
- self.shrink_factor = shrink_factor
- super(ArrowStyle.Wedge, self).__init__()
-
- def transmute(self, path, mutation_size, linewidth):
-
- x0, y0, x1, y1, x2, y2 = self.ensure_quadratic_bezier(path)
-
- arrow_path = [(x0, y0), (x1, y1), (x2, y2)]
- b_plus, b_minus = make_wedged_bezier2(
- arrow_path,
- self.tail_width * mutation_size / 2.,
- wm=self.shrink_factor)
-
- patch_path = [(Path.MOVETO, b_plus[0]),
- (Path.CURVE3, b_plus[1]),
- (Path.CURVE3, b_plus[2]),
- (Path.LINETO, b_minus[2]),
- (Path.CURVE3, b_minus[1]),
- (Path.CURVE3, b_minus[0]),
- (Path.CLOSEPOLY, b_minus[0]),
- ]
- path = Path([p for c, p in patch_path], [c for c, p in patch_path])
-
- return path, True
-
- _style_list["wedge"] = Wedge
-
- if __doc__:
- __doc__ = cbook.dedent(__doc__) % \
- {"AvailableArrowstyles": _pprint_styles(_style_list)}
-
-
-docstring.interpd.update(
- AvailableArrowstyles=_pprint_styles(ArrowStyle._style_list),
- AvailableConnectorstyles=_pprint_styles(ConnectionStyle._style_list),
-)
-
-
-class FancyArrowPatch(Patch):
- """
- A fancy arrow patch. It draws an arrow using the :class:`ArrowStyle`.
-
- The head and tail positions are fixed at the specified start and end points
- of the arrow, but the size and shape (in display coordinates) of the arrow
- does not change when the axis is moved or zoomed.
- """
- _edge_default = True
-
- def __str__(self):
-
- if self._posA_posB is not None:
- (x1, y1), (x2, y2) = self._posA_posB
- return self.__class__.__name__ \
- + "(%g,%g->%g,%g)" % (x1, y1, x2, y2)
- else:
- return self.__class__.__name__ \
- + "(%s)" % (str(self._path_original),)
-
- @docstring.dedent_interpd
- def __init__(self, posA=None, posB=None,
- path=None,
- arrowstyle="simple",
- arrow_transmuter=None,
- connectionstyle="arc3",
- connector=None,
- patchA=None,
- patchB=None,
- shrinkA=2,
- shrinkB=2,
- mutation_scale=1,
- mutation_aspect=None,
- dpi_cor=1,
- **kwargs):
- """
- If *posA* and *posB* are given, a path connecting two points is
- created according to *connectionstyle*. The path will be
- clipped with *patchA* and *patchB* and further shrunken by
- *shrinkA* and *shrinkB*. An arrow is drawn along this
- resulting path using the *arrowstyle* parameter.
-
- Alternatively if *path* is provided, an arrow is drawn along this path
- and *patchA*, *patchB*, *shrinkA*, and *shrinkB* are ignored.
-
- Parameters
- ----------
-
- posA, posB : None, tuple, optional (default: None)
- (x,y) coordinates of arrow tail and arrow head respectively.
-
- path : None, Path (default: None)
- :class:`matplotlib.path.Path` instance. If provided, an arrow is
- drawn along this path and *patchA*, *patchB*, *shrinkA*, and
- *shrinkB* are ignored.
-
- arrowstyle : str or ArrowStyle, optional (default: 'simple')
- Describes how the fancy arrow will be
- drawn. It can be string of the available arrowstyle names,
- with optional comma-separated attributes, or an
- :class:`ArrowStyle` instance. The optional attributes are meant to
- be scaled with the *mutation_scale*. The following arrow styles are
- available:
-
- %(AvailableArrowstyles)s
-
- arrow_transmuter :
- Ignored
-
- connectionstyle : str, ConnectionStyle, or None, optional
- (default: 'arc3')
- Describes how *posA* and *posB* are connected. It can be an
- instance of the :class:`ConnectionStyle` class or a string of the
- connectionstyle name, with optional comma-separated attributes. The
- following connection styles are available:
-
- %(AvailableConnectorstyles)s
-
- connector :
- Ignored
-
- patchA, patchB : None, Patch, optional (default: None)
- Head and tail patch respectively. :class:`matplotlib.patch.Patch`
- instance.
-
- shrinkA, shrinkB : scalar, optional (default: 2)
- Shrinking factor of the tail and head of the arrow respectively
-
- mutation_scale : scalar, optional (default: 1)
- Value with which attributes of *arrowstyle* (e.g., *head_length*)
- will be scaled.
-
- mutation_aspect : None, scalar, optional (default: None)
- The height of the rectangle will be squeezed by this value before
- the mutation and the mutated box will be stretched by the inverse
- of it.
-
- dpi_cor : scalar, optional (default: 1)
- dpi_cor is currently used for linewidth-related things and shrink
- factor. Mutation scale is affected by this.
-
- Notes
- -----
- Valid kwargs are:
- %(Patch)s
- """
- Patch.__init__(self, **kwargs)
-
- if posA is not None and posB is not None and path is None:
- self._posA_posB = [posA, posB]
-
- if connectionstyle is None:
- connectionstyle = "arc3"
- self.set_connectionstyle(connectionstyle)
-
- elif posA is None and posB is None and path is not None:
- self._posA_posB = None
- self._connetors = None
- else:
- raise ValueError("either posA and posB, or path need to provided")
-
- self.patchA = patchA
- self.patchB = patchB
- self.shrinkA = shrinkA
- self.shrinkB = shrinkB
-
- self._path_original = path
-
- self.set_arrowstyle(arrowstyle)
-
- self._mutation_scale = mutation_scale
- self._mutation_aspect = mutation_aspect
-
- self.set_dpi_cor(dpi_cor)
-
- def set_dpi_cor(self, dpi_cor):
- """
- dpi_cor is currently used for linewidth-related things and
- shrink factor. Mutation scale is affected by this.
-
- Parameters
- ----------
- dpi_cor : scalar
- """
- self._dpi_cor = dpi_cor
- self.stale = True
-
- def get_dpi_cor(self):
- """
- dpi_cor is currently used for linewidth-related things and
- shrink factor. Mutation scale is affected by this.
-
- Returns
- -------
- dpi_cor : scalar
- """
- return self._dpi_cor
-
- def set_positions(self, posA, posB):
- """
- Set the begin and end positions of the connecting path.
-
- Parameters
- ----------
- posA, posB : None, tuple
- (x,y) coordinates of arrow tail and arrow head respectively. If
- `None` use current value.
- """
- if posA is not None:
- self._posA_posB[0] = posA
- if posB is not None:
- self._posA_posB[1] = posB
- self.stale = True
-
- def set_patchA(self, patchA):
- """
- Set the tail patch.
-
- Parameters
- ----------
- patchA : Patch
- :class:`matplotlib.patch.Patch` instance.
- """
- self.patchA = patchA
- self.stale = True
-
- def set_patchB(self, patchB):
- """
- Set the head patch.
-
- Parameters
- ----------
- patchB : Patch
- :class:`matplotlib.patch.Patch` instance.
- """
- self.patchB = patchB
- self.stale = True
-
- def set_connectionstyle(self, connectionstyle, **kw):
- """
- Set the connection style. Old attributes are forgotten.
-
- Parameters
- ----------
- connectionstyle : None, ConnectionStyle instance, or string
- Can be a string with connectionstyle name with
- optional comma-separated attributes, e.g.::
-
- set_connectionstyle("arc,angleA=0,armA=30,rad=10")
-
- Alternatively, the attributes can be provided as keywords, e.g.::
-
- set_connectionstyle("arc", angleA=0,armA=30,rad=10)
-
- Without any arguments (or with ``connectionstyle=None``), return
- available styles as a list of strings.
- """
-
- if connectionstyle is None:
- return ConnectionStyle.pprint_styles()
-
- if (isinstance(connectionstyle, ConnectionStyle._Base) or
- callable(connectionstyle)):
- self._connector = connectionstyle
- else:
- self._connector = ConnectionStyle(connectionstyle, **kw)
- self.stale = True
-
- def get_connectionstyle(self):
- """
- Return the :class:`ConnectionStyle` instance.
- """
- return self._connector
-
- def set_arrowstyle(self, arrowstyle=None, **kw):
- """
- Set the arrow style. Old attributes are forgotten. Without arguments
- (or with ``arrowstyle=None``) returns available box styles as a list of
- strings.
-
- Parameters
- ----------
- arrowstyle : None, ArrowStyle, str, optional (default: None)
- Can be a string with arrowstyle name with optional comma-separated
- attributes, e.g.::
-
- set_arrowstyle("Fancy,head_length=0.2")
-
- Alternatively attributes can be provided as keywords, e.g.::
-
- set_arrowstyle("fancy", head_length=0.2)
-
- """
-
- if arrowstyle is None:
- return ArrowStyle.pprint_styles()
-
- if isinstance(arrowstyle, ArrowStyle._Base):
- self._arrow_transmuter = arrowstyle
- else:
- self._arrow_transmuter = ArrowStyle(arrowstyle, **kw)
- self.stale = True
-
- def get_arrowstyle(self):
- """
- Return the arrowstyle object.
- """
- return self._arrow_transmuter
-
- def set_mutation_scale(self, scale):
- """
- Set the mutation scale.
-
- Parameters
- ----------
- scale : scalar
- """
- self._mutation_scale = scale
- self.stale = True
-
- def get_mutation_scale(self):
- """
- Return the mutation scale.
-
- Returns
- -------
- scale : scalar
- """
- return self._mutation_scale
-
- def set_mutation_aspect(self, aspect):
- """
- Set the aspect ratio of the bbox mutation.
-
- Parameters
- ----------
- aspect : scalar
- """
- self._mutation_aspect = aspect
- self.stale = True
-
- def get_mutation_aspect(self):
- """
- Return the aspect ratio of the bbox mutation.
- """
- return self._mutation_aspect
-
- def get_path(self):
- """
- Return the path of the arrow in the data coordinates. Use
- get_path_in_displaycoord() method to retrieve the arrow path
- in display coordinates.
- """
- _path, fillable = self.get_path_in_displaycoord()
-
- if cbook.iterable(fillable):
- _path = concatenate_paths(_path)
-
- return self.get_transform().inverted().transform_path(_path)
-
- def get_path_in_displaycoord(self):
- """
- Return the mutated path of the arrow in display coordinates.
- """
-
- dpi_cor = self.get_dpi_cor()
-
- if self._posA_posB is not None:
- posA = self.get_transform().transform_point(self._posA_posB[0])
- posB = self.get_transform().transform_point(self._posA_posB[1])
- _path = self.get_connectionstyle()(posA, posB,
- patchA=self.patchA,
- patchB=self.patchB,
- shrinkA=self.shrinkA * dpi_cor,
- shrinkB=self.shrinkB * dpi_cor
- )
- else:
- _path = self.get_transform().transform_path(self._path_original)
-
- _path, fillable = self.get_arrowstyle()(
- _path,
- self.get_mutation_scale() * dpi_cor,
- self.get_linewidth() * dpi_cor,
- self.get_mutation_aspect())
-
- # if not fillable:
- # self._fill = False
-
- return _path, fillable
-
- def draw(self, renderer):
- if not self.get_visible():
- return
-
- renderer.open_group('patch', self.get_gid())
- gc = renderer.new_gc()
-
- gc.set_foreground(self._edgecolor, isRGBA=True)
-
- lw = self._linewidth
- if self._edgecolor[3] == 0:
- lw = 0
- gc.set_linewidth(lw)
- gc.set_dashes(self._dashoffset, self._dashes)
-
- gc.set_antialiased(self._antialiased)
- self._set_gc_clip(gc)
- gc.set_capstyle('round')
- gc.set_snap(self.get_snap())
-
- rgbFace = self._facecolor
- if rgbFace[3] == 0:
- rgbFace = None # (some?) renderers expect this as no-fill signal
-
- gc.set_alpha(self._alpha)
-
- if self._hatch:
- gc.set_hatch(self._hatch)
- if self._hatch_color is not None:
- try:
- gc.set_hatch_color(self._hatch_color)
- except AttributeError:
- # if we end up with a GC that does not have this method
- warnings.warn("Your backend does not support setting the "
- "hatch color.")
-
- if self.get_sketch_params() is not None:
- gc.set_sketch_params(*self.get_sketch_params())
-
- # FIXME : dpi_cor is for the dpi-dependecy of the
- # linewidth. There could be room for improvement.
- #
- # dpi_cor = renderer.points_to_pixels(1.)
- self.set_dpi_cor(renderer.points_to_pixels(1.))
- path, fillable = self.get_path_in_displaycoord()
-
- if not cbook.iterable(fillable):
- path = [path]
- fillable = [fillable]
-
- affine = transforms.IdentityTransform()
-
- if self.get_path_effects():
- from matplotlib.patheffects import PathEffectRenderer
- renderer = PathEffectRenderer(self.get_path_effects(), renderer)
-
- for p, f in zip(path, fillable):
- if f:
- renderer.draw_path(gc, p, affine, rgbFace)
- else:
- renderer.draw_path(gc, p, affine, None)
-
- gc.restore()
- renderer.close_group('patch')
- self.stale = False
-
-
-class ConnectionPatch(FancyArrowPatch):
- """
- A :class:`~matplotlib.patches.ConnectionPatch` class is to make
- connecting lines between two points (possibly in different axes).
- """
- def __str__(self):
- return "ConnectionPatch((%g,%g),(%g,%g))" % \
- (self.xy1[0], self.xy1[1], self.xy2[0], self.xy2[1])
-
- @docstring.dedent_interpd
- def __init__(self, xyA, xyB, coordsA, coordsB=None,
- axesA=None, axesB=None,
- arrowstyle="-",
- arrow_transmuter=None,
- connectionstyle="arc3",
- connector=None,
- patchA=None,
- patchB=None,
- shrinkA=0.,
- shrinkB=0.,
- mutation_scale=10.,
- mutation_aspect=None,
- clip_on=False,
- dpi_cor=1.,
- **kwargs):
- """
- Connect point *xyA* in *coordsA* with point *xyB* in *coordsB*
-
-
- Valid keys are
-
-
- =============== ======================================================
- Key Description
- =============== ======================================================
- arrowstyle the arrow style
- connectionstyle the connection style
- relpos default is (0.5, 0.5)
- patchA default is bounding box of the text
- patchB default is None
- shrinkA default is 2 points
- shrinkB default is 2 points
- mutation_scale default is text size (in points)
- mutation_aspect default is 1.
- ? any key for :class:`matplotlib.patches.PathPatch`
- =============== ======================================================
-
-
- *coordsA* and *coordsB* are strings that indicate the
- coordinates of *xyA* and *xyB*.
-
- ================= ===================================================
- Property Description
- ================= ===================================================
- 'figure points' points from the lower left corner of the figure
- 'figure pixels' pixels from the lower left corner of the figure
- 'figure fraction' 0,0 is lower left of figure and 1,1 is upper, right
- 'axes points' points from lower left corner of axes
- 'axes pixels' pixels from lower left corner of axes
- 'axes fraction' 0,1 is lower left of axes and 1,1 is upper right
- 'data' use the coordinate system of the object being
- annotated (default)
- 'offset points' Specify an offset (in points) from the *xy* value
-
- 'polar' you can specify *theta*, *r* for the annotation,
- even in cartesian plots. Note that if you
- are using a polar axes, you do not need
- to specify polar for the coordinate
- system since that is the native "data" coordinate
- system.
- ================= ===================================================
-
- """
- if coordsB is None:
- coordsB = coordsA
- # we'll draw ourself after the artist we annotate by default
- self.xy1 = xyA
- self.xy2 = xyB
- self.coords1 = coordsA
- self.coords2 = coordsB
-
- self.axesA = axesA
- self.axesB = axesB
-
- FancyArrowPatch.__init__(self,
- posA=(0, 0), posB=(1, 1),
- arrowstyle=arrowstyle,
- arrow_transmuter=arrow_transmuter,
- connectionstyle=connectionstyle,
- connector=connector,
- patchA=patchA,
- patchB=patchB,
- shrinkA=shrinkA,
- shrinkB=shrinkB,
- mutation_scale=mutation_scale,
- mutation_aspect=mutation_aspect,
- clip_on=clip_on,
- dpi_cor=dpi_cor,
- **kwargs)
-
- # if True, draw annotation only if self.xy is inside the axes
- self._annotation_clip = None
-
- def _get_xy(self, x, y, s, axes=None):
- """
- calculate the pixel position of given point
- """
-
- if axes is None:
- axes = self.axes
-
- if s == 'data':
- trans = axes.transData
- x = float(self.convert_xunits(x))
- y = float(self.convert_yunits(y))
- return trans.transform_point((x, y))
- elif s == 'offset points':
- # convert the data point
- dx, dy = self.xy
-
- # prevent recursion
- if self.xycoords == 'offset points':
- return self._get_xy(dx, dy, 'data')
-
- dx, dy = self._get_xy(dx, dy, self.xycoords)
-
- # convert the offset
- dpi = self.figure.get_dpi()
- x *= dpi / 72.
- y *= dpi / 72.
-
- # add the offset to the data point
- x += dx
- y += dy
-
- return x, y
- elif s == 'polar':
- theta, r = x, y
- x = r * np.cos(theta)
- y = r * np.sin(theta)
- trans = axes.transData
- return trans.transform_point((x, y))
- elif s == 'figure points':
- # points from the lower left corner of the figure
- dpi = self.figure.dpi
- l, b, w, h = self.figure.bbox.bounds
- r = l + w
- t = b + h
-
- x *= dpi / 72.
- y *= dpi / 72.
- if x < 0:
- x = r + x
- if y < 0:
- y = t + y
- return x, y
- elif s == 'figure pixels':
- # pixels from the lower left corner of the figure
- l, b, w, h = self.figure.bbox.bounds
- r = l + w
- t = b + h
- if x < 0:
- x = r + x
- if y < 0:
- y = t + y
- return x, y
- elif s == 'figure fraction':
- # (0,0) is lower left, (1,1) is upper right of figure
- trans = self.figure.transFigure
- return trans.transform_point((x, y))
- elif s == 'axes points':
- # points from the lower left corner of the axes
- dpi = self.figure.dpi
- l, b, w, h = axes.bbox.bounds
- r = l + w
- t = b + h
- if x < 0:
- x = r + x * dpi / 72.
- else:
- x = l + x * dpi / 72.
- if y < 0:
- y = t + y * dpi / 72.
- else:
- y = b + y * dpi / 72.
- return x, y
- elif s == 'axes pixels':
- #pixels from the lower left corner of the axes
-
- l, b, w, h = axes.bbox.bounds
- r = l + w
- t = b + h
- if x < 0:
- x = r + x
- else:
- x = l + x
- if y < 0:
- y = t + y
- else:
- y = b + y
- return x, y
- elif s == 'axes fraction':
- #(0,0) is lower left, (1,1) is upper right of axes
- trans = axes.transAxes
- return trans.transform_point((x, y))
-
- def set_annotation_clip(self, b):
- """
- set *annotation_clip* attribute.
-
- * True: the annotation will only be drawn when self.xy is inside the
- axes.
- * False: the annotation will always be drawn regardless of its
- position.
- * None: the self.xy will be checked only if *xycoords* is "data"
- """
- self._annotation_clip = b
- self.stale = True
-
- def get_annotation_clip(self):
- """
- Return *annotation_clip* attribute.
- See :meth:`set_annotation_clip` for the meaning of return values.
- """
- return self._annotation_clip
-
- def get_path_in_displaycoord(self):
- """
- Return the mutated path of the arrow in the display coord
- """
-
- dpi_cor = self.get_dpi_cor()
-
- x, y = self.xy1
- posA = self._get_xy(x, y, self.coords1, self.axesA)
-
- x, y = self.xy2
- posB = self._get_xy(x, y, self.coords2, self.axesB)
-
- _path = self.get_connectionstyle()(posA, posB,
- patchA=self.patchA,
- patchB=self.patchB,
- shrinkA=self.shrinkA * dpi_cor,
- shrinkB=self.shrinkB * dpi_cor
- )
-
- _path, fillable = self.get_arrowstyle()(
- _path,
- self.get_mutation_scale() * dpi_cor,
- self.get_linewidth() * dpi_cor,
- self.get_mutation_aspect()
- )
-
- return _path, fillable
-
- def _check_xy(self, renderer):
- """
- check if the annotation need to
- be drawn.
- """
-
- b = self.get_annotation_clip()
-
- if b or (b is None and self.coords1 == "data"):
- x, y = self.xy1
- xy_pixel = self._get_xy(x, y, self.coords1, self.axesA)
- if not self.axes.contains_point(xy_pixel):
- return False
-
- if b or (b is None and self.coords2 == "data"):
- x, y = self.xy2
- xy_pixel = self._get_xy(x, y, self.coords2, self.axesB)
- if self.axesB is None:
- axes = self.axes
- else:
- axes = self.axesB
- if not axes.contains_point(xy_pixel):
- return False
-
- return True
-
- def draw(self, renderer):
- """
- Draw.
- """
-
- if renderer is not None:
- self._renderer = renderer
- if not self.get_visible():
- return
-
- if not self._check_xy(renderer):
- return
-
- FancyArrowPatch.draw(self, renderer)
diff --git a/contrib/python/matplotlib/py2/matplotlib/path.py b/contrib/python/matplotlib/py2/matplotlib/path.py
deleted file mode 100644
index 77d752ec24..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/path.py
+++ /dev/null
@@ -1,1028 +0,0 @@
-r"""
-A module for dealing with the polylines used throughout Matplotlib.
-
-The primary class for polyline handling in Matplotlib is `Path`. Almost all
-vector drawing makes use of `Path`\s somewhere in the drawing pipeline.
-
-Whilst a `Path` instance itself cannot be drawn, some `.Artist` subclasses,
-such as `.PathPatch` and `.PathCollection`, can be used for convenient `Path`
-visualisation.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from weakref import WeakValueDictionary
-
-import numpy as np
-
-from . import _path, rcParams
-from .cbook import (_to_unmasked_float_array, simple_linear_interpolation,
- maxdict)
-
-
-class Path(object):
- """
- :class:`Path` represents a series of possibly disconnected,
- possibly closed, line and curve segments.
-
- The underlying storage is made up of two parallel numpy arrays:
- - *vertices*: an Nx2 float array of vertices
- - *codes*: an N-length uint8 array of vertex types
-
- These two arrays always have the same length in the first
- dimension. For example, to represent a cubic curve, you must
- provide three vertices as well as three codes ``CURVE3``.
-
- The code types are:
-
- - ``STOP`` : 1 vertex (ignored)
- A marker for the end of the entire path (currently not
- required and ignored)
-
- - ``MOVETO`` : 1 vertex
- Pick up the pen and move to the given vertex.
-
- - ``LINETO`` : 1 vertex
- Draw a line from the current position to the given vertex.
-
- - ``CURVE3`` : 1 control point, 1 endpoint
- Draw a quadratic Bezier curve from the current position,
- with the given control point, to the given end point.
-
- - ``CURVE4`` : 2 control points, 1 endpoint
- Draw a cubic Bezier curve from the current position, with
- the given control points, to the given end point.
-
- - ``CLOSEPOLY`` : 1 vertex (ignored)
- Draw a line segment to the start point of the current
- polyline.
-
- Users of Path objects should not access the vertices and codes
- arrays directly. Instead, they should use :meth:`iter_segments`
- or :meth:`cleaned` to get the vertex/code pairs. This is important,
- since many :class:`Path` objects, as an optimization, do not store a
- *codes* at all, but have a default one provided for them by
- :meth:`iter_segments`.
-
- Some behavior of Path objects can be controlled by rcParams. See
- the rcParams whose keys contain 'path.'.
-
- .. note::
-
- The vertices and codes arrays should be treated as
- immutable -- there are a number of optimizations and assumptions
- made up front in the constructor that will not change when the
- data changes.
-
- """
-
- # Path codes
- STOP = 0 # 1 vertex
- MOVETO = 1 # 1 vertex
- LINETO = 2 # 1 vertex
- CURVE3 = 3 # 2 vertices
- CURVE4 = 4 # 3 vertices
- CLOSEPOLY = 79 # 1 vertex
-
- #: A dictionary mapping Path codes to the number of vertices that the
- #: code expects.
- NUM_VERTICES_FOR_CODE = {STOP: 1,
- MOVETO: 1,
- LINETO: 1,
- CURVE3: 2,
- CURVE4: 3,
- CLOSEPOLY: 1}
-
- code_type = np.uint8
-
- def __init__(self, vertices, codes=None, _interpolation_steps=1,
- closed=False, readonly=False):
- """
- Create a new path with the given vertices and codes.
-
- Parameters
- ----------
- vertices : array_like
- The ``(n, 2)`` float array, masked array or sequence of pairs
- representing the vertices of the path.
-
- If *vertices* contains masked values, they will be converted
- to NaNs which are then handled correctly by the Agg
- PathIterator and other consumers of path data, such as
- :meth:`iter_segments`.
- codes : {None, array_like}, optional
- n-length array integers representing the codes of the path.
- If not None, codes must be the same length as vertices.
- If None, *vertices* will be treated as a series of line segments.
- _interpolation_steps : int, optional
- Used as a hint to certain projections, such as Polar, that this
- path should be linearly interpolated immediately before drawing.
- This attribute is primarily an implementation detail and is not
- intended for public use.
- closed : bool, optional
- If *codes* is None and closed is True, vertices will be treated as
- line segments of a closed polygon.
- readonly : bool, optional
- Makes the path behave in an immutable way and sets the vertices
- and codes as read-only arrays.
- """
- vertices = _to_unmasked_float_array(vertices)
- if (vertices.ndim != 2) or (vertices.shape[1] != 2):
- raise ValueError(
- "'vertices' must be a 2D list or array with shape Nx2")
-
- if codes is not None:
- codes = np.asarray(codes, self.code_type)
- if (codes.ndim != 1) or len(codes) != len(vertices):
- raise ValueError("'codes' must be a 1D list or array with the "
- "same length of 'vertices'")
- if len(codes) and codes[0] != self.MOVETO:
- raise ValueError("The first element of 'code' must be equal "
- "to 'MOVETO' ({})".format(self.MOVETO))
- elif closed:
- codes = np.empty(len(vertices), dtype=self.code_type)
- codes[0] = self.MOVETO
- codes[1:-1] = self.LINETO
- codes[-1] = self.CLOSEPOLY
-
- self._vertices = vertices
- self._codes = codes
- self._interpolation_steps = _interpolation_steps
- self._update_values()
-
- if readonly:
- self._vertices.flags.writeable = False
- if self._codes is not None:
- self._codes.flags.writeable = False
- self._readonly = True
- else:
- self._readonly = False
-
- @classmethod
- def _fast_from_codes_and_verts(cls, verts, codes, internals=None):
- """
- Creates a Path instance without the expense of calling the constructor
-
- Parameters
- ----------
- verts : numpy array
- codes : numpy array
- internals : dict or None
- The attributes that the resulting path should have.
- Allowed keys are ``readonly``, ``should_simplify``,
- ``simplify_threshold``, ``has_nonfinite`` and
- ``interpolation_steps``.
-
- """
- internals = internals or {}
- pth = cls.__new__(cls)
- pth._vertices = _to_unmasked_float_array(verts)
- pth._codes = codes
- pth._readonly = internals.pop('readonly', False)
- pth.should_simplify = internals.pop('should_simplify', True)
- pth.simplify_threshold = (
- internals.pop('simplify_threshold',
- rcParams['path.simplify_threshold'])
- )
- pth._has_nonfinite = internals.pop('has_nonfinite', False)
- pth._interpolation_steps = internals.pop('interpolation_steps', 1)
- if internals:
- raise ValueError('Unexpected internals provided to '
- '_fast_from_codes_and_verts: '
- '{0}'.format('\n *'.join(internals)))
- return pth
-
- def _update_values(self):
- self._simplify_threshold = rcParams['path.simplify_threshold']
- self._should_simplify = (
- self._simplify_threshold > 0 and
- rcParams['path.simplify'] and
- len(self._vertices) >= 128 and
- (self._codes is None or np.all(self._codes <= Path.LINETO))
- )
- self._has_nonfinite = not np.isfinite(self._vertices).all()
-
- @property
- def vertices(self):
- """
- The list of vertices in the `Path` as an Nx2 numpy array.
- """
- return self._vertices
-
- @vertices.setter
- def vertices(self, vertices):
- if self._readonly:
- raise AttributeError("Can't set vertices on a readonly Path")
- self._vertices = vertices
- self._update_values()
-
- @property
- def codes(self):
- """
- The list of codes in the `Path` as a 1-D numpy array. Each
- code is one of `STOP`, `MOVETO`, `LINETO`, `CURVE3`, `CURVE4`
- or `CLOSEPOLY`. For codes that correspond to more than one
- vertex (`CURVE3` and `CURVE4`), that code will be repeated so
- that the length of `self.vertices` and `self.codes` is always
- the same.
- """
- return self._codes
-
- @codes.setter
- def codes(self, codes):
- if self._readonly:
- raise AttributeError("Can't set codes on a readonly Path")
- self._codes = codes
- self._update_values()
-
- @property
- def simplify_threshold(self):
- """
- The fraction of a pixel difference below which vertices will
- be simplified out.
- """
- return self._simplify_threshold
-
- @simplify_threshold.setter
- def simplify_threshold(self, threshold):
- self._simplify_threshold = threshold
-
- @property
- def has_nonfinite(self):
- """
- `True` if the vertices array has nonfinite values.
- """
- return self._has_nonfinite
-
- @property
- def should_simplify(self):
- """
- `True` if the vertices array should be simplified.
- """
- return self._should_simplify
-
- @should_simplify.setter
- def should_simplify(self, should_simplify):
- self._should_simplify = should_simplify
-
- @property
- def readonly(self):
- """
- `True` if the `Path` is read-only.
- """
- return self._readonly
-
- def __copy__(self):
- """
- Returns a shallow copy of the `Path`, which will share the
- vertices and codes with the source `Path`.
- """
- import copy
- return copy.copy(self)
-
- copy = __copy__
-
- def __deepcopy__(self, memo=None):
- """
- Returns a deepcopy of the `Path`. The `Path` will not be
- readonly, even if the source `Path` is.
- """
- try:
- codes = self.codes.copy()
- except AttributeError:
- codes = None
- return self.__class__(
- self.vertices.copy(), codes,
- _interpolation_steps=self._interpolation_steps)
-
- deepcopy = __deepcopy__
-
- @classmethod
- def make_compound_path_from_polys(cls, XY):
- """
- Make a compound path object to draw a number
- of polygons with equal numbers of sides XY is a (numpolys x
- numsides x 2) numpy array of vertices. Return object is a
- :class:`Path`
-
- .. plot:: gallery/api/histogram_path.py
-
- """
-
- # for each poly: 1 for the MOVETO, (numsides-1) for the LINETO, 1 for
- # the CLOSEPOLY; the vert for the closepoly is ignored but we still
- # need it to keep the codes aligned with the vertices
- numpolys, numsides, two = XY.shape
- if two != 2:
- raise ValueError("The third dimension of 'XY' must be 2")
- stride = numsides + 1
- nverts = numpolys * stride
- verts = np.zeros((nverts, 2))
- codes = np.ones(nverts, int) * cls.LINETO
- codes[0::stride] = cls.MOVETO
- codes[numsides::stride] = cls.CLOSEPOLY
- for i in range(numsides):
- verts[i::stride] = XY[:, i]
-
- return cls(verts, codes)
-
- @classmethod
- def make_compound_path(cls, *args):
- """Make a compound path from a list of Path objects."""
- # Handle an empty list in args (i.e. no args).
- if not args:
- return Path(np.empty([0, 2], dtype=np.float32))
-
- lengths = [len(x) for x in args]
- total_length = sum(lengths)
-
- vertices = np.vstack([x.vertices for x in args])
- vertices.reshape((total_length, 2))
-
- codes = np.empty(total_length, dtype=cls.code_type)
- i = 0
- for path in args:
- if path.codes is None:
- codes[i] = cls.MOVETO
- codes[i + 1:i + len(path.vertices)] = cls.LINETO
- else:
- codes[i:i + len(path.codes)] = path.codes
- i += len(path.vertices)
-
- return cls(vertices, codes)
-
- def __repr__(self):
- return "Path(%r, %r)" % (self.vertices, self.codes)
-
- def __len__(self):
- return len(self.vertices)
-
- def iter_segments(self, transform=None, remove_nans=True, clip=None,
- snap=False, stroke_width=1.0, simplify=None,
- curves=True, sketch=None):
- """
- Iterates over all of the curve segments in the path. Each
- iteration returns a 2-tuple (*vertices*, *code*), where
- *vertices* is a sequence of 1 - 3 coordinate pairs, and *code* is
- one of the :class:`Path` codes.
-
- Additionally, this method can provide a number of standard
- cleanups and conversions to the path.
-
- Parameters
- ----------
- transform : None or :class:`~matplotlib.transforms.Transform` instance
- If not None, the given affine transformation will
- be applied to the path.
- remove_nans : {False, True}, optional
- If True, will remove all NaNs from the path and
- insert MOVETO commands to skip over them.
- clip : None or sequence, optional
- If not None, must be a four-tuple (x1, y1, x2, y2)
- defining a rectangle in which to clip the path.
- snap : None or bool, optional
- If None, auto-snap to pixels, to reduce
- fuzziness of rectilinear lines. If True, force snapping, and
- if False, don't snap.
- stroke_width : float, optional
- The width of the stroke being drawn. Needed
- as a hint for the snapping algorithm.
- simplify : None or bool, optional
- If True, perform simplification, to remove
- vertices that do not affect the appearance of the path. If
- False, perform no simplification. If None, use the
- should_simplify member variable. See also the rcParams
- path.simplify and path.simplify_threshold.
- curves : {True, False}, optional
- If True, curve segments will be returned as curve
- segments. If False, all curves will be converted to line
- segments.
- sketch : None or sequence, optional
- If not None, must be a 3-tuple of the form
- (scale, length, randomness), representing the sketch
- parameters.
- """
- if not len(self):
- return
-
- cleaned = self.cleaned(transform=transform,
- remove_nans=remove_nans, clip=clip,
- snap=snap, stroke_width=stroke_width,
- simplify=simplify, curves=curves,
- sketch=sketch)
- vertices = cleaned.vertices
- codes = cleaned.codes
- len_vertices = vertices.shape[0]
-
- # Cache these object lookups for performance in the loop.
- NUM_VERTICES_FOR_CODE = self.NUM_VERTICES_FOR_CODE
- STOP = self.STOP
-
- i = 0
- while i < len_vertices:
- code = codes[i]
- if code == STOP:
- return
- else:
- num_vertices = NUM_VERTICES_FOR_CODE[code]
- curr_vertices = vertices[i:i+num_vertices].flatten()
- yield curr_vertices, code
- i += num_vertices
-
- def cleaned(self, transform=None, remove_nans=False, clip=None,
- quantize=False, simplify=False, curves=False,
- stroke_width=1.0, snap=False, sketch=None):
- """
- Cleans up the path according to the parameters returning a new
- Path instance.
-
- .. seealso::
-
- See :meth:`iter_segments` for details of the keyword arguments.
-
- Returns
- -------
- Path instance with cleaned up vertices and codes.
-
- """
- vertices, codes = _path.cleanup_path(self, transform,
- remove_nans, clip,
- snap, stroke_width,
- simplify, curves, sketch)
- internals = {'should_simplify': self.should_simplify and not simplify,
- 'has_nonfinite': self.has_nonfinite and not remove_nans,
- 'simplify_threshold': self.simplify_threshold,
- 'interpolation_steps': self._interpolation_steps}
- return Path._fast_from_codes_and_verts(vertices, codes, internals)
-
- def transformed(self, transform):
- """
- Return a transformed copy of the path.
-
- .. seealso::
-
- :class:`matplotlib.transforms.TransformedPath`
- A specialized path class that will cache the
- transformed result and automatically update when the
- transform changes.
- """
- return Path(transform.transform(self.vertices), self.codes,
- self._interpolation_steps)
-
- def contains_point(self, point, transform=None, radius=0.0):
- """
- Returns whether the (closed) path contains the given point.
-
- If *transform* is not ``None``, the path will be transformed before
- performing the test.
-
- *radius* allows the path to be made slightly larger or smaller.
- """
- if transform is not None:
- transform = transform.frozen()
- # `point_in_path` does not handle nonlinear transforms, so we
- # transform the path ourselves. If `transform` is affine, letting
- # `point_in_path` handle the transform avoids allocating an extra
- # buffer.
- if transform and not transform.is_affine:
- self = transform.transform_path(self)
- transform = None
- return _path.point_in_path(point[0], point[1], radius, self, transform)
-
- def contains_points(self, points, transform=None, radius=0.0):
- """
- Returns a bool array which is ``True`` if the (closed) path contains
- the corresponding point.
-
- If *transform* is not ``None``, the path will be transformed before
- performing the test.
-
- *radius* allows the path to be made slightly larger or smaller.
- """
- if transform is not None:
- transform = transform.frozen()
- result = _path.points_in_path(points, radius, self, transform)
- return result.astype('bool')
-
- def contains_path(self, path, transform=None):
- """
- Returns whether this (closed) path completely contains the given path.
-
- If *transform* is not ``None``, the path will be transformed before
- performing the test.
- """
- if transform is not None:
- transform = transform.frozen()
- return _path.path_in_path(self, None, path, transform)
-
- def get_extents(self, transform=None):
- """
- Returns the extents (*xmin*, *ymin*, *xmax*, *ymax*) of the
- path.
-
- Unlike computing the extents on the *vertices* alone, this
- algorithm will take into account the curves and deal with
- control points appropriately.
- """
- from .transforms import Bbox
- path = self
- if transform is not None:
- transform = transform.frozen()
- if not transform.is_affine:
- path = self.transformed(transform)
- transform = None
- return Bbox(_path.get_path_extents(path, transform))
-
- def intersects_path(self, other, filled=True):
- """
- Returns *True* if this path intersects another given path.
-
- *filled*, when True, treats the paths as if they were filled.
- That is, if one path completely encloses the other,
- :meth:`intersects_path` will return True.
- """
- return _path.path_intersects_path(self, other, filled)
-
- def intersects_bbox(self, bbox, filled=True):
- """
- Returns *True* if this path intersects a given
- :class:`~matplotlib.transforms.Bbox`.
-
- *filled*, when True, treats the path as if it was filled.
- That is, if the path completely encloses the bounding box,
- :meth:`intersects_bbox` will return True.
-
- The bounding box is always considered filled.
- """
- return _path.path_intersects_rectangle(self,
- bbox.x0, bbox.y0, bbox.x1, bbox.y1, filled)
-
- def interpolated(self, steps):
- """
- Returns a new path resampled to length N x steps. Does not
- currently handle interpolating curves.
- """
- if steps == 1:
- return self
-
- vertices = simple_linear_interpolation(self.vertices, steps)
- codes = self.codes
- if codes is not None:
- new_codes = Path.LINETO * np.ones(((len(codes) - 1) * steps + 1, ))
- new_codes[0::steps] = codes
- else:
- new_codes = None
- return Path(vertices, new_codes)
-
- def to_polygons(self, transform=None, width=0, height=0, closed_only=True):
- """
- Convert this path to a list of polygons or polylines. Each
- polygon/polyline is an Nx2 array of vertices. In other words,
- each polygon has no ``MOVETO`` instructions or curves. This
- is useful for displaying in backends that do not support
- compound paths or Bezier curves, such as GDK.
-
- If *width* and *height* are both non-zero then the lines will
- be simplified so that vertices outside of (0, 0), (width,
- height) will be clipped.
-
- If *closed_only* is `True` (default), only closed polygons,
- with the last point being the same as the first point, will be
- returned. Any unclosed polylines in the path will be
- explicitly closed. If *closed_only* is `False`, any unclosed
- polygons in the path will be returned as unclosed polygons,
- and the closed polygons will be returned explicitly closed by
- setting the last point to the same as the first point.
- """
- if len(self.vertices) == 0:
- return []
-
- if transform is not None:
- transform = transform.frozen()
-
- if self.codes is None and (width == 0 or height == 0):
- vertices = self.vertices
- if closed_only:
- if len(vertices) < 3:
- return []
- elif np.any(vertices[0] != vertices[-1]):
- vertices = list(vertices) + [vertices[0]]
-
- if transform is None:
- return [vertices]
- else:
- return [transform.transform(vertices)]
-
- # Deal with the case where there are curves and/or multiple
- # subpaths (using extension code)
- return _path.convert_path_to_polygons(
- self, transform, width, height, closed_only)
-
- _unit_rectangle = None
-
- @classmethod
- def unit_rectangle(cls):
- """
- Return a :class:`Path` instance of the unit rectangle
- from (0, 0) to (1, 1).
- """
- if cls._unit_rectangle is None:
- cls._unit_rectangle = \
- cls([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0],
- [0.0, 0.0]],
- [cls.MOVETO, cls.LINETO, cls.LINETO, cls.LINETO,
- cls.CLOSEPOLY],
- readonly=True)
- return cls._unit_rectangle
-
- _unit_regular_polygons = WeakValueDictionary()
-
- @classmethod
- def unit_regular_polygon(cls, numVertices):
- """
- Return a :class:`Path` instance for a unit regular
- polygon with the given *numVertices* and radius of 1.0,
- centered at (0, 0).
- """
- if numVertices <= 16:
- path = cls._unit_regular_polygons.get(numVertices)
- else:
- path = None
- if path is None:
- theta = (2*np.pi/numVertices *
- np.arange(numVertices + 1).reshape((numVertices + 1, 1)))
- # This initial rotation is to make sure the polygon always
- # "points-up"
- theta += np.pi / 2.0
- verts = np.concatenate((np.cos(theta), np.sin(theta)), 1)
- codes = np.empty((numVertices + 1,))
- codes[0] = cls.MOVETO
- codes[1:-1] = cls.LINETO
- codes[-1] = cls.CLOSEPOLY
- path = cls(verts, codes, readonly=True)
- if numVertices <= 16:
- cls._unit_regular_polygons[numVertices] = path
- return path
-
- _unit_regular_stars = WeakValueDictionary()
-
- @classmethod
- def unit_regular_star(cls, numVertices, innerCircle=0.5):
- """
- Return a :class:`Path` for a unit regular star
- with the given numVertices and radius of 1.0, centered at (0,
- 0).
- """
- if numVertices <= 16:
- path = cls._unit_regular_stars.get((numVertices, innerCircle))
- else:
- path = None
- if path is None:
- ns2 = numVertices * 2
- theta = (2*np.pi/ns2 * np.arange(ns2 + 1))
- # This initial rotation is to make sure the polygon always
- # "points-up"
- theta += np.pi / 2.0
- r = np.ones(ns2 + 1)
- r[1::2] = innerCircle
- verts = np.vstack((r*np.cos(theta), r*np.sin(theta))).transpose()
- codes = np.empty((ns2 + 1,))
- codes[0] = cls.MOVETO
- codes[1:-1] = cls.LINETO
- codes[-1] = cls.CLOSEPOLY
- path = cls(verts, codes, readonly=True)
- if numVertices <= 16:
- cls._unit_regular_stars[(numVertices, innerCircle)] = path
- return path
-
- @classmethod
- def unit_regular_asterisk(cls, numVertices):
- """
- Return a :class:`Path` for a unit regular
- asterisk with the given numVertices and radius of 1.0,
- centered at (0, 0).
- """
- return cls.unit_regular_star(numVertices, 0.0)
-
- _unit_circle = None
-
- @classmethod
- def unit_circle(cls):
- """
- Return the readonly :class:`Path` of the unit circle.
-
- For most cases, :func:`Path.circle` will be what you want.
-
- """
- if cls._unit_circle is None:
- cls._unit_circle = cls.circle(center=(0, 0), radius=1,
- readonly=True)
- return cls._unit_circle
-
- @classmethod
- def circle(cls, center=(0., 0.), radius=1., readonly=False):
- """
- Return a Path representing a circle of a given radius and center.
-
- Parameters
- ----------
- center : pair of floats
- The center of the circle. Default ``(0, 0)``.
- radius : float
- The radius of the circle. Default is 1.
- readonly : bool
- Whether the created path should have the "readonly" argument
- set when creating the Path instance.
-
- Notes
- -----
- The circle is approximated using cubic Bezier curves. This
- uses 8 splines around the circle using the approach presented
- here:
-
- Lancaster, Don. `Approximating a Circle or an Ellipse Using Four
- Bezier Cubic Splines <http://www.tinaja.com/glib/ellipse4.pdf>`_.
-
- """
- MAGIC = 0.2652031
- SQRTHALF = np.sqrt(0.5)
- MAGIC45 = SQRTHALF * MAGIC
-
- vertices = np.array([[0.0, -1.0],
-
- [MAGIC, -1.0],
- [SQRTHALF-MAGIC45, -SQRTHALF-MAGIC45],
- [SQRTHALF, -SQRTHALF],
-
- [SQRTHALF+MAGIC45, -SQRTHALF+MAGIC45],
- [1.0, -MAGIC],
- [1.0, 0.0],
-
- [1.0, MAGIC],
- [SQRTHALF+MAGIC45, SQRTHALF-MAGIC45],
- [SQRTHALF, SQRTHALF],
-
- [SQRTHALF-MAGIC45, SQRTHALF+MAGIC45],
- [MAGIC, 1.0],
- [0.0, 1.0],
-
- [-MAGIC, 1.0],
- [-SQRTHALF+MAGIC45, SQRTHALF+MAGIC45],
- [-SQRTHALF, SQRTHALF],
-
- [-SQRTHALF-MAGIC45, SQRTHALF-MAGIC45],
- [-1.0, MAGIC],
- [-1.0, 0.0],
-
- [-1.0, -MAGIC],
- [-SQRTHALF-MAGIC45, -SQRTHALF+MAGIC45],
- [-SQRTHALF, -SQRTHALF],
-
- [-SQRTHALF+MAGIC45, -SQRTHALF-MAGIC45],
- [-MAGIC, -1.0],
- [0.0, -1.0],
-
- [0.0, -1.0]],
- dtype=float)
-
- codes = [cls.CURVE4] * 26
- codes[0] = cls.MOVETO
- codes[-1] = cls.CLOSEPOLY
- return Path(vertices * radius + center, codes, readonly=readonly)
-
- _unit_circle_righthalf = None
-
- @classmethod
- def unit_circle_righthalf(cls):
- """
- Return a :class:`Path` of the right half
- of a unit circle. The circle is approximated using cubic Bezier
- curves. This uses 4 splines around the circle using the approach
- presented here:
-
- Lancaster, Don. `Approximating a Circle or an Ellipse Using Four
- Bezier Cubic Splines <http://www.tinaja.com/glib/ellipse4.pdf>`_.
- """
- if cls._unit_circle_righthalf is None:
- MAGIC = 0.2652031
- SQRTHALF = np.sqrt(0.5)
- MAGIC45 = SQRTHALF * MAGIC
-
- vertices = np.array(
- [[0.0, -1.0],
-
- [MAGIC, -1.0],
- [SQRTHALF-MAGIC45, -SQRTHALF-MAGIC45],
- [SQRTHALF, -SQRTHALF],
-
- [SQRTHALF+MAGIC45, -SQRTHALF+MAGIC45],
- [1.0, -MAGIC],
- [1.0, 0.0],
-
- [1.0, MAGIC],
- [SQRTHALF+MAGIC45, SQRTHALF-MAGIC45],
- [SQRTHALF, SQRTHALF],
-
- [SQRTHALF-MAGIC45, SQRTHALF+MAGIC45],
- [MAGIC, 1.0],
- [0.0, 1.0],
-
- [0.0, -1.0]],
-
- float)
-
- codes = cls.CURVE4 * np.ones(14)
- codes[0] = cls.MOVETO
- codes[-1] = cls.CLOSEPOLY
-
- cls._unit_circle_righthalf = cls(vertices, codes, readonly=True)
- return cls._unit_circle_righthalf
-
- @classmethod
- def arc(cls, theta1, theta2, n=None, is_wedge=False):
- """
- Return an arc on the unit circle from angle
- *theta1* to angle *theta2* (in degrees).
-
- *theta2* is unwrapped to produce the shortest arc within 360 degrees.
- That is, if *theta2* > *theta1* + 360, the arc will be from *theta1* to
- *theta2* - 360 and not a full circle plus some extra overlap.
-
- If *n* is provided, it is the number of spline segments to make.
- If *n* is not provided, the number of spline segments is
- determined based on the delta between *theta1* and *theta2*.
-
- Masionobe, L. 2003. `Drawing an elliptical arc using
- polylines, quadratic or cubic Bezier curves
- <http://www.spaceroots.org/documents/ellipse/index.html>`_.
- """
- halfpi = np.pi * 0.5
-
- eta1 = theta1
- eta2 = theta2 - 360 * np.floor((theta2 - theta1) / 360)
- # Ensure 2pi range is not flattened to 0 due to floating-point errors,
- # but don't try to expand existing 0 range.
- if theta2 != theta1 and eta2 <= eta1:
- eta2 += 360
- eta1, eta2 = np.deg2rad([eta1, eta2])
-
- # number of curve segments to make
- if n is None:
- n = int(2 ** np.ceil((eta2 - eta1) / halfpi))
- if n < 1:
- raise ValueError("n must be >= 1 or None")
-
- deta = (eta2 - eta1) / n
- t = np.tan(0.5 * deta)
- alpha = np.sin(deta) * (np.sqrt(4.0 + 3.0 * t * t) - 1) / 3.0
-
- steps = np.linspace(eta1, eta2, n + 1, True)
- cos_eta = np.cos(steps)
- sin_eta = np.sin(steps)
-
- xA = cos_eta[:-1]
- yA = sin_eta[:-1]
- xA_dot = -yA
- yA_dot = xA
-
- xB = cos_eta[1:]
- yB = sin_eta[1:]
- xB_dot = -yB
- yB_dot = xB
-
- if is_wedge:
- length = n * 3 + 4
- vertices = np.zeros((length, 2), float)
- codes = cls.CURVE4 * np.ones((length, ), cls.code_type)
- vertices[1] = [xA[0], yA[0]]
- codes[0:2] = [cls.MOVETO, cls.LINETO]
- codes[-2:] = [cls.LINETO, cls.CLOSEPOLY]
- vertex_offset = 2
- end = length - 2
- else:
- length = n * 3 + 1
- vertices = np.empty((length, 2), float)
- codes = cls.CURVE4 * np.ones((length, ), cls.code_type)
- vertices[0] = [xA[0], yA[0]]
- codes[0] = cls.MOVETO
- vertex_offset = 1
- end = length
-
- vertices[vertex_offset:end:3, 0] = xA + alpha * xA_dot
- vertices[vertex_offset:end:3, 1] = yA + alpha * yA_dot
- vertices[vertex_offset+1:end:3, 0] = xB - alpha * xB_dot
- vertices[vertex_offset+1:end:3, 1] = yB - alpha * yB_dot
- vertices[vertex_offset+2:end:3, 0] = xB
- vertices[vertex_offset+2:end:3, 1] = yB
-
- return cls(vertices, codes, readonly=True)
-
- @classmethod
- def wedge(cls, theta1, theta2, n=None):
- """
- Return a wedge of the unit circle from angle
- *theta1* to angle *theta2* (in degrees).
-
- *theta2* is unwrapped to produce the shortest wedge within 360 degrees.
- That is, if *theta2* > *theta1* + 360, the wedge will be from *theta1*
- to *theta2* - 360 and not a full circle plus some extra overlap.
-
- If *n* is provided, it is the number of spline segments to make.
- If *n* is not provided, the number of spline segments is
- determined based on the delta between *theta1* and *theta2*.
- """
- return cls.arc(theta1, theta2, n, True)
-
- _hatch_dict = maxdict(8)
-
- @classmethod
- def hatch(cls, hatchpattern, density=6):
- """
- Given a hatch specifier, *hatchpattern*, generates a Path that
- can be used in a repeated hatching pattern. *density* is the
- number of lines per unit square.
- """
- from matplotlib.hatch import get_path
-
- if hatchpattern is None:
- return None
-
- hatch_path = cls._hatch_dict.get((hatchpattern, density))
- if hatch_path is not None:
- return hatch_path
-
- hatch_path = get_path(hatchpattern, density)
- cls._hatch_dict[(hatchpattern, density)] = hatch_path
- return hatch_path
-
- def clip_to_bbox(self, bbox, inside=True):
- """
- Clip the path to the given bounding box.
-
- The path must be made up of one or more closed polygons. This
- algorithm will not behave correctly for unclosed paths.
-
- If *inside* is `True`, clip to the inside of the box, otherwise
- to the outside of the box.
- """
- # Use make_compound_path_from_polys
- verts = _path.clip_path_to_rect(self, bbox, inside)
- paths = [Path(poly) for poly in verts]
- return self.make_compound_path(*paths)
-
-
-def get_path_collection_extents(
- master_transform, paths, transforms, offsets, offset_transform):
- """
- Given a sequence of :class:`Path` objects,
- :class:`~matplotlib.transforms.Transform` objects and offsets, as
- found in a :class:`~matplotlib.collections.PathCollection`,
- returns the bounding box that encapsulates all of them.
-
- *master_transform* is a global transformation to apply to all paths
-
- *paths* is a sequence of :class:`Path` instances.
-
- *transforms* is a sequence of
- :class:`~matplotlib.transforms.Affine2D` instances.
-
- *offsets* is a sequence of (x, y) offsets (or an Nx2 array)
-
- *offset_transform* is a :class:`~matplotlib.transforms.Affine2D`
- to apply to the offsets before applying the offset to the path.
-
- The way that *paths*, *transforms* and *offsets* are combined
- follows the same method as for collections. Each is iterated over
- independently, so if you have 3 paths, 2 transforms and 1 offset,
- their combinations are as follows:
-
- (A, A, A), (B, B, A), (C, A, A)
- """
- from .transforms import Bbox
- if len(paths) == 0:
- raise ValueError("No paths provided")
- return Bbox.from_extents(*_path.get_path_collection_extents(
- master_transform, paths, np.atleast_3d(transforms),
- offsets, offset_transform))
-
-
-def get_paths_extents(paths, transforms=[]):
- """
- Given a sequence of :class:`Path` objects and optional
- :class:`~matplotlib.transforms.Transform` objects, returns the
- bounding box that encapsulates all of them.
-
- *paths* is a sequence of :class:`Path` instances.
-
- *transforms* is an optional sequence of
- :class:`~matplotlib.transforms.Affine2D` instances to apply to
- each path.
- """
- from .transforms import Bbox, Affine2D
- if len(paths) == 0:
- raise ValueError("No paths provided")
- return Bbox.from_extents(*_path.get_path_collection_extents(
- Affine2D(), paths, transforms, [], Affine2D()))
diff --git a/contrib/python/matplotlib/py2/matplotlib/patheffects.py b/contrib/python/matplotlib/py2/matplotlib/patheffects.py
deleted file mode 100644
index c0265ec719..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/patheffects.py
+++ /dev/null
@@ -1,393 +0,0 @@
-"""
-Defines classes for path effects. The path effects are supported in
-:class:`~matplotlib.text.Text`, :class:`~matplotlib.lines.Line2D`
-and :class:`~matplotlib.patches.Patch`.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from matplotlib.backend_bases import RendererBase
-from matplotlib import colors as mcolors
-from matplotlib import patches as mpatches
-from matplotlib import transforms as mtransforms
-
-
-class AbstractPathEffect(object):
- """
- A base class for path effects.
-
- Subclasses should override the ``draw_path`` method to add effect
- functionality.
-
- """
- def __init__(self, offset=(0., 0.)):
- """
- Parameters
- ----------
- offset : pair of floats
- The offset to apply to the path, measured in points.
- """
- self._offset = offset
- self._offset_trans = mtransforms.Affine2D()
-
- def _offset_transform(self, renderer, transform):
- """Apply the offset to the given transform."""
- offset_x = renderer.points_to_pixels(self._offset[0])
- offset_y = renderer.points_to_pixels(self._offset[1])
- return transform + self._offset_trans.clear().translate(offset_x,
- offset_y)
-
- def _update_gc(self, gc, new_gc_dict):
- """
- Update the given GraphicsCollection with the given
- dictionary of properties. The keys in the dictionary are used to
- identify the appropriate set_ method on the gc.
-
- """
- new_gc_dict = new_gc_dict.copy()
-
- dashes = new_gc_dict.pop("dashes", None)
- if dashes:
- gc.set_dashes(**dashes)
-
- for k, v in six.iteritems(new_gc_dict):
- set_method = getattr(gc, 'set_' + k, None)
- if not callable(set_method):
- raise AttributeError('Unknown property {0}'.format(k))
- set_method(v)
- return gc
-
- def draw_path(self, renderer, gc, tpath, affine, rgbFace=None):
- """
- Derived should override this method. The arguments are the same
- as :meth:`matplotlib.backend_bases.RendererBase.draw_path`
- except the first argument is a renderer.
-
- """
- # Get the real renderer, not a PathEffectRenderer.
- if isinstance(renderer, PathEffectRenderer):
- renderer = renderer._renderer
- return renderer.draw_path(gc, tpath, affine, rgbFace)
-
-
-class PathEffectRenderer(RendererBase):
- """
- Implements a Renderer which contains another renderer.
-
- This proxy then intercepts draw calls, calling the appropriate
- :class:`AbstractPathEffect` draw method.
-
- .. note::
- Not all methods have been overridden on this RendererBase subclass.
- It may be necessary to add further methods to extend the PathEffects
- capabilities further.
-
- """
- def __init__(self, path_effects, renderer):
- """
- Parameters
- ----------
- path_effects : iterable of :class:`AbstractPathEffect`
- The path effects which this renderer represents.
- renderer : :class:`matplotlib.backend_bases.RendererBase` instance
-
- """
- self._path_effects = path_effects
- self._renderer = renderer
-
- def new_gc(self):
- return self._renderer.new_gc()
-
- def copy_with_path_effect(self, path_effects):
- return self.__class__(path_effects, self._renderer)
-
- def draw_path(self, gc, tpath, affine, rgbFace=None):
- for path_effect in self._path_effects:
- path_effect.draw_path(self._renderer, gc, tpath, affine,
- rgbFace)
-
- def draw_markers(self, gc, marker_path, marker_trans, path, *args,
- **kwargs):
- # We do a little shimmy so that all markers are drawn for each path
- # effect in turn. Essentially, we induce recursion (depth 1) which is
- # terminated once we have just a single path effect to work with.
- if len(self._path_effects) == 1:
- # Call the base path effect function - this uses the unoptimised
- # approach of calling "draw_path" multiple times.
- return RendererBase.draw_markers(self, gc, marker_path,
- marker_trans, path, *args,
- **kwargs)
-
- for path_effect in self._path_effects:
- renderer = self.copy_with_path_effect([path_effect])
- # Recursively call this method, only next time we will only have
- # one path effect.
- renderer.draw_markers(gc, marker_path, marker_trans, path,
- *args, **kwargs)
-
- def draw_path_collection(self, gc, master_transform, paths, *args,
- **kwargs):
- # We do a little shimmy so that all paths are drawn for each path
- # effect in turn. Essentially, we induce recursion (depth 1) which is
- # terminated once we have just a single path effect to work with.
- if len(self._path_effects) == 1:
- # Call the base path effect function - this uses the unoptimised
- # approach of calling "draw_path" multiple times.
- return RendererBase.draw_path_collection(self, gc,
- master_transform, paths,
- *args, **kwargs)
-
- for path_effect in self._path_effects:
- renderer = self.copy_with_path_effect([path_effect])
- # Recursively call this method, only next time we will only have
- # one path effect.
- renderer.draw_path_collection(gc, master_transform, paths,
- *args, **kwargs)
-
- def points_to_pixels(self, points):
- return self._renderer.points_to_pixels(points)
-
- def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath):
- # Implements the naive text drawing as is found in RendererBase.
- path, transform = self._get_text_path_transform(x, y, s, prop,
- angle, ismath)
- color = gc.get_rgb()
- gc.set_linewidth(0.0)
- self.draw_path(gc, path, transform, rgbFace=color)
-
- def __getattribute__(self, name):
- if name in ['_text2path', 'flipy', 'height', 'width']:
- return getattr(self._renderer, name)
- else:
- return object.__getattribute__(self, name)
-
-
-class Normal(AbstractPathEffect):
- """
- The "identity" PathEffect.
-
- The Normal PathEffect's sole purpose is to draw the original artist with
- no special path effect.
- """
- pass
-
-
-class Stroke(AbstractPathEffect):
- """A line based PathEffect which re-draws a stroke."""
- def __init__(self, offset=(0, 0), **kwargs):
- """
- The path will be stroked with its gc updated with the given
- keyword arguments, i.e., the keyword arguments should be valid
- gc parameter values.
- """
- super(Stroke, self).__init__(offset)
- self._gc = kwargs
-
- def draw_path(self, renderer, gc, tpath, affine, rgbFace):
- """
- draw the path with updated gc.
- """
- # Do not modify the input! Use copy instead.
-
- gc0 = renderer.new_gc()
- gc0.copy_properties(gc)
-
- gc0 = self._update_gc(gc0, self._gc)
- trans = self._offset_transform(renderer, affine)
- renderer.draw_path(gc0, tpath, trans, rgbFace)
- gc0.restore()
-
-
-class withStroke(Stroke):
- """
- Adds a simple :class:`Stroke` and then draws the
- original Artist to avoid needing to call :class:`Normal`.
-
- """
- def draw_path(self, renderer, gc, tpath, affine, rgbFace):
- Stroke.draw_path(self, renderer, gc, tpath, affine, rgbFace)
- renderer.draw_path(gc, tpath, affine, rgbFace)
-
-
-class SimplePatchShadow(AbstractPathEffect):
- """A simple shadow via a filled patch."""
- def __init__(self, offset=(2, -2),
- shadow_rgbFace=None, alpha=None,
- rho=0.3, **kwargs):
- """
- Parameters
- ----------
- offset : pair of floats
- The offset of the shadow in points.
- shadow_rgbFace : color
- The shadow color.
- alpha : float
- The alpha transparency of the created shadow patch.
- Default is 0.3.
- http://matplotlib.1069221.n5.nabble.com/path-effects-question-td27630.html
- rho : float
- A scale factor to apply to the rgbFace color if `shadow_rgbFace`
- is not specified. Default is 0.3.
- **kwargs
- Extra keywords are stored and passed through to
- :meth:`AbstractPathEffect._update_gc`.
-
- """
- super(SimplePatchShadow, self).__init__(offset)
-
- if shadow_rgbFace is None:
- self._shadow_rgbFace = shadow_rgbFace
- else:
- self._shadow_rgbFace = mcolors.to_rgba(shadow_rgbFace)
-
- if alpha is None:
- alpha = 0.3
-
- self._alpha = alpha
- self._rho = rho
-
- #: The dictionary of keywords to update the graphics collection with.
- self._gc = kwargs
-
- #: The offset transform object. The offset isn't calculated yet
- #: as we don't know how big the figure will be in pixels.
- self._offset_tran = mtransforms.Affine2D()
-
- def draw_path(self, renderer, gc, tpath, affine, rgbFace):
- """
- Overrides the standard draw_path to add the shadow offset and
- necessary color changes for the shadow.
-
- """
- # IMPORTANT: Do not modify the input - we copy everything instead.
- affine0 = self._offset_transform(renderer, affine)
- gc0 = renderer.new_gc()
- gc0.copy_properties(gc)
-
- if self._shadow_rgbFace is None:
- r,g,b = (rgbFace or (1., 1., 1.))[:3]
- # Scale the colors by a factor to improve the shadow effect.
- shadow_rgbFace = (r * self._rho, g * self._rho, b * self._rho)
- else:
- shadow_rgbFace = self._shadow_rgbFace
-
- gc0.set_foreground("none")
- gc0.set_alpha(self._alpha)
- gc0.set_linewidth(0)
-
- gc0 = self._update_gc(gc0, self._gc)
- renderer.draw_path(gc0, tpath, affine0, shadow_rgbFace)
- gc0.restore()
-
-
-class withSimplePatchShadow(SimplePatchShadow):
- """
- Adds a simple :class:`SimplePatchShadow` and then draws the
- original Artist to avoid needing to call :class:`Normal`.
-
- """
- def draw_path(self, renderer, gc, tpath, affine, rgbFace):
- SimplePatchShadow.draw_path(self, renderer, gc, tpath, affine, rgbFace)
- renderer.draw_path(gc, tpath, affine, rgbFace)
-
-
-class SimpleLineShadow(AbstractPathEffect):
- """A simple shadow via a line."""
- def __init__(self, offset=(2,-2),
- shadow_color='k', alpha=0.3, rho=0.3, **kwargs):
- """
- Parameters
- ----------
- offset : pair of floats
- The offset to apply to the path, in points.
- shadow_color : color
- The shadow color. Default is black.
- A value of ``None`` takes the original artist's color
- with a scale factor of `rho`.
- alpha : float
- The alpha transparency of the created shadow patch.
- Default is 0.3.
- rho : float
- A scale factor to apply to the rgbFace color if `shadow_rgbFace`
- is ``None``. Default is 0.3.
- **kwargs
- Extra keywords are stored and passed through to
- :meth:`AbstractPathEffect._update_gc`.
-
- """
- super(SimpleLineShadow, self).__init__(offset)
- if shadow_color is None:
- self._shadow_color = shadow_color
- else:
- self._shadow_color = mcolors.to_rgba(shadow_color)
- self._alpha = alpha
- self._rho = rho
-
- #: The dictionary of keywords to update the graphics collection with.
- self._gc = kwargs
-
- #: The offset transform object. The offset isn't calculated yet
- #: as we don't know how big the figure will be in pixels.
- self._offset_tran = mtransforms.Affine2D()
-
- def draw_path(self, renderer, gc, tpath, affine, rgbFace):
- """
- Overrides the standard draw_path to add the shadow offset and
- necessary color changes for the shadow.
-
- """
- # IMPORTANT: Do not modify the input - we copy everything instead.
- affine0 = self._offset_transform(renderer, affine)
- gc0 = renderer.new_gc()
- gc0.copy_properties(gc)
-
- if self._shadow_color is None:
- r,g,b = (gc0.get_foreground() or (1., 1., 1.))[:3]
- # Scale the colors by a factor to improve the shadow effect.
- shadow_rgbFace = (r * self._rho, g * self._rho, b * self._rho)
- else:
- shadow_rgbFace = self._shadow_color
-
- fill_color = None
-
- gc0.set_foreground(shadow_rgbFace)
- gc0.set_alpha(self._alpha)
-
- gc0 = self._update_gc(gc0, self._gc)
- renderer.draw_path(gc0, tpath, affine0, fill_color)
- gc0.restore()
-
-
-class PathPatchEffect(AbstractPathEffect):
- """
- Draws a :class:`~matplotlib.patches.PathPatch` instance whose Path
- comes from the original PathEffect artist.
-
- """
- def __init__(self, offset=(0, 0), **kwargs):
- """
- Parameters
- ----------
- offset : pair of floats
- The offset to apply to the path, in points.
- **kwargs :
- All keyword arguments are passed through to the
- :class:`~matplotlib.patches.PathPatch` constructor. The
- properties which cannot be overridden are "path", "clip_box"
- "transform" and "clip_path".
- """
- super(PathPatchEffect, self).__init__(offset=offset)
- self.patch = mpatches.PathPatch([], **kwargs)
-
- def draw_path(self, renderer, gc, tpath, affine, rgbFace):
- affine = self._offset_transform(renderer, affine)
- self.patch._path = tpath
- self.patch.set_transform(affine)
- self.patch.set_clip_box(gc.get_clip_rectangle())
- clip_path = gc.get_clip_path()
- if clip_path:
- self.patch.set_clip_path(*clip_path)
- self.patch.draw(renderer)
diff --git a/contrib/python/matplotlib/py2/matplotlib/projections/__init__.py b/contrib/python/matplotlib/py2/matplotlib/projections/__init__.py
deleted file mode 100644
index 1e423420b0..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/projections/__init__.py
+++ /dev/null
@@ -1,110 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from .geo import AitoffAxes, HammerAxes, LambertAxes, MollweideAxes
-from .polar import PolarAxes
-from matplotlib import axes
-
-class ProjectionRegistry(object):
- """
- Manages the set of projections available to the system.
- """
- def __init__(self):
- self._all_projection_types = {}
-
- def register(self, *projections):
- """
- Register a new set of projection(s).
- """
- for projection in projections:
- name = projection.name
- self._all_projection_types[name] = projection
-
- def get_projection_class(self, name):
- """
- Get a projection class from its *name*.
- """
- return self._all_projection_types[name]
-
- def get_projection_names(self):
- """
- Get a list of the names of all projections currently
- registered.
- """
- return sorted(self._all_projection_types)
-projection_registry = ProjectionRegistry()
-
-projection_registry.register(
- axes.Axes,
- PolarAxes,
- AitoffAxes,
- HammerAxes,
- LambertAxes,
- MollweideAxes)
-
-
-def register_projection(cls):
- projection_registry.register(cls)
-
-
-def get_projection_class(projection=None):
- """
- Get a projection class from its name.
-
- If *projection* is None, a standard rectilinear projection is
- returned.
- """
- if projection is None:
- projection = 'rectilinear'
-
- try:
- return projection_registry.get_projection_class(projection)
- except KeyError:
- raise ValueError("Unknown projection '%s'" % projection)
-
-
-def process_projection_requirements(figure, *args, **kwargs):
- """
- Handle the args/kwargs to for add_axes/add_subplot/gca,
- returning::
-
- (axes_proj_class, proj_class_kwargs, proj_stack_key)
-
- Which can be used for new axes initialization/identification.
-
- .. note:: **kwargs** is modified in place.
-
- """
- ispolar = kwargs.pop('polar', False)
- projection = kwargs.pop('projection', None)
- if ispolar:
- if projection is not None and projection != 'polar':
- raise ValueError(
- "polar=True, yet projection=%r. "
- "Only one of these arguments should be supplied." %
- projection)
- projection = 'polar'
-
- if isinstance(projection, six.string_types) or projection is None:
- projection_class = get_projection_class(projection)
- elif hasattr(projection, '_as_mpl_axes'):
- projection_class, extra_kwargs = projection._as_mpl_axes()
- kwargs.update(**extra_kwargs)
- else:
- raise TypeError('projection must be a string, None or implement a '
- '_as_mpl_axes method. Got %r' % projection)
-
- # Make the key without projection kwargs, this is used as a unique
- # lookup for axes instances
- key = figure._make_key(*args, **kwargs)
-
- return projection_class, kwargs, key
-
-
-def get_projection_names():
- """
- Get a list of acceptable projection names.
- """
- return projection_registry.get_projection_names()
diff --git a/contrib/python/matplotlib/py2/matplotlib/projections/geo.py b/contrib/python/matplotlib/py2/matplotlib/projections/geo.py
deleted file mode 100644
index 3ed5dc7456..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/projections/geo.py
+++ /dev/null
@@ -1,547 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import numpy as np
-
-import matplotlib
-from matplotlib import rcParams
-from matplotlib.axes import Axes
-import matplotlib.axis as maxis
-from matplotlib.patches import Circle
-from matplotlib.path import Path
-import matplotlib.spines as mspines
-from matplotlib.ticker import (
- Formatter, NullLocator, FixedLocator, NullFormatter)
-from matplotlib.transforms import Affine2D, BboxTransformTo, Transform
-
-
-class GeoAxes(Axes):
- """An abstract base class for geographic projections."""
- class ThetaFormatter(Formatter):
- """
- Used to format the theta tick labels. Converts the native
- unit of radians into degrees and adds a degree symbol.
- """
- def __init__(self, round_to=1.0):
- self._round_to = round_to
-
- def __call__(self, x, pos=None):
- degrees = (x / np.pi) * 180.0
- degrees = np.round(degrees / self._round_to) * self._round_to
- if rcParams['text.usetex'] and not rcParams['text.latex.unicode']:
- return r"$%0.0f^\circ$" % degrees
- else:
- return "%0.0f\N{DEGREE SIGN}" % degrees
-
- RESOLUTION = 75
-
- def _init_axis(self):
- self.xaxis = maxis.XAxis(self)
- self.yaxis = maxis.YAxis(self)
- # Do not register xaxis or yaxis with spines -- as done in
- # Axes._init_axis() -- until GeoAxes.xaxis.cla() works.
- # self.spines['geo'].register_axis(self.yaxis)
- self._update_transScale()
-
- def cla(self):
- Axes.cla(self)
-
- self.set_longitude_grid(30)
- self.set_latitude_grid(15)
- self.set_longitude_grid_ends(75)
- self.xaxis.set_minor_locator(NullLocator())
- self.yaxis.set_minor_locator(NullLocator())
- self.xaxis.set_ticks_position('none')
- self.yaxis.set_ticks_position('none')
- self.yaxis.set_tick_params(label1On=True)
- # Why do we need to turn on yaxis tick labels, but
- # xaxis tick labels are already on?
-
- self.grid(rcParams['axes.grid'])
-
- Axes.set_xlim(self, -np.pi, np.pi)
- Axes.set_ylim(self, -np.pi / 2.0, np.pi / 2.0)
-
- def _set_lim_and_transforms(self):
- # A (possibly non-linear) projection on the (already scaled) data
- self.transProjection = self._get_core_transform(self.RESOLUTION)
-
- self.transAffine = self._get_affine_transform()
-
- self.transAxes = BboxTransformTo(self.bbox)
-
- # The complete data transformation stack -- from data all the
- # way to display coordinates
- self.transData = \
- self.transProjection + \
- self.transAffine + \
- self.transAxes
-
- # This is the transform for longitude ticks.
- self._xaxis_pretransform = \
- Affine2D() \
- .scale(1, self._longitude_cap * 2) \
- .translate(0, -self._longitude_cap)
- self._xaxis_transform = \
- self._xaxis_pretransform + \
- self.transData
- self._xaxis_text1_transform = \
- Affine2D().scale(1, 0) + \
- self.transData + \
- Affine2D().translate(0, 4)
- self._xaxis_text2_transform = \
- Affine2D().scale(1, 0) + \
- self.transData + \
- Affine2D().translate(0, -4)
-
- # This is the transform for latitude ticks.
- yaxis_stretch = Affine2D().scale(np.pi * 2, 1).translate(-np.pi, 0)
- yaxis_space = Affine2D().scale(1, 1.1)
- self._yaxis_transform = \
- yaxis_stretch + \
- self.transData
- yaxis_text_base = \
- yaxis_stretch + \
- self.transProjection + \
- (yaxis_space + \
- self.transAffine + \
- self.transAxes)
- self._yaxis_text1_transform = \
- yaxis_text_base + \
- Affine2D().translate(-8, 0)
- self._yaxis_text2_transform = \
- yaxis_text_base + \
- Affine2D().translate(8, 0)
-
- def _get_affine_transform(self):
- transform = self._get_core_transform(1)
- xscale, _ = transform.transform_point((np.pi, 0))
- _, yscale = transform.transform_point((0, np.pi / 2))
- return Affine2D() \
- .scale(0.5 / xscale, 0.5 / yscale) \
- .translate(0.5, 0.5)
-
- def get_xaxis_transform(self,which='grid'):
- if which not in ['tick1', 'tick2', 'grid']:
- raise ValueError(
- "'which' must be one of 'tick1', 'tick2', or 'grid'")
- return self._xaxis_transform
-
- def get_xaxis_text1_transform(self, pad):
- return self._xaxis_text1_transform, 'bottom', 'center'
-
- def get_xaxis_text2_transform(self, pad):
- return self._xaxis_text2_transform, 'top', 'center'
-
- def get_yaxis_transform(self,which='grid'):
- if which not in ['tick1', 'tick2', 'grid']:
- raise ValueError(
- "'which' must be one of 'tick1', 'tick2', or 'grid'")
- return self._yaxis_transform
-
- def get_yaxis_text1_transform(self, pad):
- return self._yaxis_text1_transform, 'center', 'right'
-
- def get_yaxis_text2_transform(self, pad):
- return self._yaxis_text2_transform, 'center', 'left'
-
- def _gen_axes_patch(self):
- return Circle((0.5, 0.5), 0.5)
-
- def _gen_axes_spines(self):
- return {'geo':mspines.Spine.circular_spine(self,
- (0.5, 0.5), 0.5)}
-
- def set_yscale(self, *args, **kwargs):
- if args[0] != 'linear':
- raise NotImplementedError
-
- set_xscale = set_yscale
-
- def set_xlim(self, *args, **kwargs):
- raise TypeError("It is not possible to change axes limits "
- "for geographic projections. Please consider "
- "using Basemap or Cartopy.")
-
- set_ylim = set_xlim
-
- def format_coord(self, lon, lat):
- 'return a format string formatting the coordinate'
- lon, lat = np.rad2deg([lon, lat])
- if lat >= 0.0:
- ns = 'N'
- else:
- ns = 'S'
- if lon >= 0.0:
- ew = 'E'
- else:
- ew = 'W'
- return ('%f\N{DEGREE SIGN}%s, %f\N{DEGREE SIGN}%s'
- % (abs(lat), ns, abs(lon), ew))
-
- def set_longitude_grid(self, degrees):
- """
- Set the number of degrees between each longitude grid.
- """
- # Skip -180 and 180, which are the fixed limits.
- grid = np.arange(-180 + degrees, 180, degrees)
- self.xaxis.set_major_locator(FixedLocator(np.deg2rad(grid)))
- self.xaxis.set_major_formatter(self.ThetaFormatter(degrees))
-
- def set_latitude_grid(self, degrees):
- """
- Set the number of degrees between each latitude grid.
- """
- # Skip -90 and 90, which are the fixed limits.
- grid = np.arange(-90 + degrees, 90, degrees)
- self.yaxis.set_major_locator(FixedLocator(np.deg2rad(grid)))
- self.yaxis.set_major_formatter(self.ThetaFormatter(degrees))
-
- def set_longitude_grid_ends(self, degrees):
- """
- Set the latitude(s) at which to stop drawing the longitude grids.
- """
- self._longitude_cap = np.deg2rad(degrees)
- self._xaxis_pretransform \
- .clear() \
- .scale(1.0, self._longitude_cap * 2.0) \
- .translate(0.0, -self._longitude_cap)
-
- def get_data_ratio(self):
- '''
- Return the aspect ratio of the data itself.
- '''
- return 1.0
-
- ### Interactive panning
-
- def can_zoom(self):
- """
- Return *True* if this axes supports the zoom box button functionality.
-
- This axes object does not support interactive zoom box.
- """
- return False
-
- def can_pan(self) :
- """
- Return *True* if this axes supports the pan/zoom button functionality.
-
- This axes object does not support interactive pan/zoom.
- """
- return False
-
- def start_pan(self, x, y, button):
- pass
-
- def end_pan(self):
- pass
-
- def drag_pan(self, button, key, x, y):
- pass
-
-
-class _GeoTransform(Transform):
- # Factoring out some common functionality.
- input_dims = 2
- output_dims = 2
- is_separable = False
-
- def __init__(self, resolution):
- """
- Create a new geographical transform.
-
- Resolution is the number of steps to interpolate between each input
- line segment to approximate its path in curved space.
- """
- Transform.__init__(self)
- self._resolution = resolution
-
- def __str__(self):
- return "{}({})".format(type(self).__name__, self._resolution)
-
- def transform_path_non_affine(self, path):
- vertices = path.vertices
- ipath = path.interpolated(self._resolution)
- return Path(self.transform(ipath.vertices), ipath.codes)
- transform_path_non_affine.__doc__ = \
- Transform.transform_path_non_affine.__doc__
-
-
-class AitoffAxes(GeoAxes):
- name = 'aitoff'
-
- class AitoffTransform(_GeoTransform):
- """The base Aitoff transform."""
-
- def transform_non_affine(self, ll):
- longitude = ll[:, 0]
- latitude = ll[:, 1]
-
- # Pre-compute some values
- half_long = longitude / 2.0
- cos_latitude = np.cos(latitude)
-
- alpha = np.arccos(cos_latitude * np.cos(half_long))
- # Avoid divide-by-zero errors using same method as NumPy.
- alpha[alpha == 0.0] = 1e-20
- # We want unnormalized sinc. numpy.sinc gives us normalized
- sinc_alpha = np.sin(alpha) / alpha
-
- xy = np.empty_like(ll, float)
- xy[:, 0] = (cos_latitude * np.sin(half_long)) / sinc_alpha
- xy[:, 1] = np.sin(latitude) / sinc_alpha
- return xy
- transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
-
- def inverted(self):
- return AitoffAxes.InvertedAitoffTransform(self._resolution)
- inverted.__doc__ = Transform.inverted.__doc__
-
- class InvertedAitoffTransform(_GeoTransform):
-
- def transform_non_affine(self, xy):
- # MGDTODO: Math is hard ;(
- return xy
- transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
-
- def inverted(self):
- return AitoffAxes.AitoffTransform(self._resolution)
- inverted.__doc__ = Transform.inverted.__doc__
-
- def __init__(self, *args, **kwargs):
- self._longitude_cap = np.pi / 2.0
- GeoAxes.__init__(self, *args, **kwargs)
- self.set_aspect(0.5, adjustable='box', anchor='C')
- self.cla()
-
- def _get_core_transform(self, resolution):
- return self.AitoffTransform(resolution)
-
-
-class HammerAxes(GeoAxes):
- name = 'hammer'
-
- class HammerTransform(_GeoTransform):
- """The base Hammer transform."""
-
- def transform_non_affine(self, ll):
- longitude = ll[:, 0:1]
- latitude = ll[:, 1:2]
-
- # Pre-compute some values
- half_long = longitude / 2.0
- cos_latitude = np.cos(latitude)
- sqrt2 = np.sqrt(2.0)
-
- alpha = np.sqrt(1.0 + cos_latitude * np.cos(half_long))
- x = (2.0 * sqrt2) * (cos_latitude * np.sin(half_long)) / alpha
- y = (sqrt2 * np.sin(latitude)) / alpha
- return np.concatenate((x, y), 1)
- transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
-
- def inverted(self):
- return HammerAxes.InvertedHammerTransform(self._resolution)
- inverted.__doc__ = Transform.inverted.__doc__
-
- class InvertedHammerTransform(_GeoTransform):
-
- def transform_non_affine(self, xy):
- x, y = xy.T
- z = np.sqrt(1 - (x / 4) ** 2 - (y / 2) ** 2)
- longitude = 2 * np.arctan((z * x) / (2 * (2 * z ** 2 - 1)))
- latitude = np.arcsin(y*z)
- return np.column_stack([longitude, latitude])
- transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
-
- def inverted(self):
- return HammerAxes.HammerTransform(self._resolution)
- inverted.__doc__ = Transform.inverted.__doc__
-
- def __init__(self, *args, **kwargs):
- self._longitude_cap = np.pi / 2.0
- GeoAxes.__init__(self, *args, **kwargs)
- self.set_aspect(0.5, adjustable='box', anchor='C')
- self.cla()
-
- def _get_core_transform(self, resolution):
- return self.HammerTransform(resolution)
-
-
-class MollweideAxes(GeoAxes):
- name = 'mollweide'
-
- class MollweideTransform(_GeoTransform):
- """The base Mollweide transform."""
-
- def transform_non_affine(self, ll):
- def d(theta):
- delta = (-(theta + np.sin(theta) - pi_sin_l)
- / (1 + np.cos(theta)))
- return delta, np.abs(delta) > 0.001
-
- longitude = ll[:, 0]
- latitude = ll[:, 1]
-
- clat = np.pi/2 - np.abs(latitude)
- ihigh = clat < 0.087 # within 5 degrees of the poles
- ilow = ~ihigh
- aux = np.empty(latitude.shape, dtype=float)
-
- if ilow.any(): # Newton-Raphson iteration
- pi_sin_l = np.pi * np.sin(latitude[ilow])
- theta = 2.0 * latitude[ilow]
- delta, large_delta = d(theta)
- while np.any(large_delta):
- theta[large_delta] += delta[large_delta]
- delta, large_delta = d(theta)
- aux[ilow] = theta / 2
-
- if ihigh.any(): # Taylor series-based approx. solution
- e = clat[ihigh]
- d = 0.5 * (3 * np.pi * e**2) ** (1.0/3)
- aux[ihigh] = (np.pi/2 - d) * np.sign(latitude[ihigh])
-
- xy = np.empty(ll.shape, dtype=float)
- xy[:,0] = (2.0 * np.sqrt(2.0) / np.pi) * longitude * np.cos(aux)
- xy[:,1] = np.sqrt(2.0) * np.sin(aux)
-
- return xy
- transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
-
- def inverted(self):
- return MollweideAxes.InvertedMollweideTransform(self._resolution)
- inverted.__doc__ = Transform.inverted.__doc__
-
- class InvertedMollweideTransform(_GeoTransform):
-
- def transform_non_affine(self, xy):
- x = xy[:, 0:1]
- y = xy[:, 1:2]
-
- # from Equations (7, 8) of
- # http://mathworld.wolfram.com/MollweideProjection.html
- theta = np.arcsin(y / np.sqrt(2))
- lon = (np.pi / (2 * np.sqrt(2))) * x / np.cos(theta)
- lat = np.arcsin((2 * theta + np.sin(2 * theta)) / np.pi)
-
- return np.concatenate((lon, lat), 1)
- transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
-
- def inverted(self):
- return MollweideAxes.MollweideTransform(self._resolution)
- inverted.__doc__ = Transform.inverted.__doc__
-
- def __init__(self, *args, **kwargs):
- self._longitude_cap = np.pi / 2.0
- GeoAxes.__init__(self, *args, **kwargs)
- self.set_aspect(0.5, adjustable='box', anchor='C')
- self.cla()
-
- def _get_core_transform(self, resolution):
- return self.MollweideTransform(resolution)
-
-
-class LambertAxes(GeoAxes):
- name = 'lambert'
-
- class LambertTransform(_GeoTransform):
- """The base Lambert transform."""
-
- def __init__(self, center_longitude, center_latitude, resolution):
- """
- Create a new Lambert transform. Resolution is the number of steps
- to interpolate between each input line segment to approximate its
- path in curved Lambert space.
- """
- _GeoTransform.__init__(self, resolution)
- self._center_longitude = center_longitude
- self._center_latitude = center_latitude
-
- def transform_non_affine(self, ll):
- longitude = ll[:, 0:1]
- latitude = ll[:, 1:2]
- clong = self._center_longitude
- clat = self._center_latitude
- cos_lat = np.cos(latitude)
- sin_lat = np.sin(latitude)
- diff_long = longitude - clong
- cos_diff_long = np.cos(diff_long)
-
- inner_k = (1.0 +
- np.sin(clat)*sin_lat +
- np.cos(clat)*cos_lat*cos_diff_long)
- # Prevent divide-by-zero problems
- inner_k = np.where(inner_k == 0.0, 1e-15, inner_k)
- k = np.sqrt(2.0 / inner_k)
- x = k*cos_lat*np.sin(diff_long)
- y = k*(np.cos(clat)*sin_lat -
- np.sin(clat)*cos_lat*cos_diff_long)
-
- return np.concatenate((x, y), 1)
- transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
-
- def inverted(self):
- return LambertAxes.InvertedLambertTransform(
- self._center_longitude,
- self._center_latitude,
- self._resolution)
- inverted.__doc__ = Transform.inverted.__doc__
-
- class InvertedLambertTransform(_GeoTransform):
-
- def __init__(self, center_longitude, center_latitude, resolution):
- _GeoTransform.__init__(self, resolution)
- self._center_longitude = center_longitude
- self._center_latitude = center_latitude
-
- def transform_non_affine(self, xy):
- x = xy[:, 0:1]
- y = xy[:, 1:2]
- clong = self._center_longitude
- clat = self._center_latitude
- p = np.sqrt(x*x + y*y)
- p = np.where(p == 0.0, 1e-9, p)
- c = 2.0 * np.arcsin(0.5 * p)
- sin_c = np.sin(c)
- cos_c = np.cos(c)
-
- lat = np.arcsin(cos_c*np.sin(clat) +
- ((y*sin_c*np.cos(clat)) / p))
- lon = clong + np.arctan(
- (x*sin_c) / (p*np.cos(clat)*cos_c - y*np.sin(clat)*sin_c))
-
- return np.concatenate((lon, lat), 1)
- transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
-
- def inverted(self):
- return LambertAxes.LambertTransform(
- self._center_longitude,
- self._center_latitude,
- self._resolution)
- inverted.__doc__ = Transform.inverted.__doc__
-
- def __init__(self, *args, **kwargs):
- self._longitude_cap = np.pi / 2.0
- self._center_longitude = kwargs.pop("center_longitude", 0.0)
- self._center_latitude = kwargs.pop("center_latitude", 0.0)
- GeoAxes.__init__(self, *args, **kwargs)
- self.set_aspect('equal', adjustable='box', anchor='C')
- self.cla()
-
- def cla(self):
- GeoAxes.cla(self)
- self.yaxis.set_major_formatter(NullFormatter())
-
- def _get_core_transform(self, resolution):
- return self.LambertTransform(
- self._center_longitude,
- self._center_latitude,
- resolution)
-
- def _get_affine_transform(self):
- return Affine2D() \
- .scale(0.25) \
- .translate(0.5, 0.5)
diff --git a/contrib/python/matplotlib/py2/matplotlib/projections/polar.py b/contrib/python/matplotlib/py2/matplotlib/projections/polar.py
deleted file mode 100644
index 62fc0f9ac6..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/projections/polar.py
+++ /dev/null
@@ -1,1537 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from collections import OrderedDict
-
-import numpy as np
-
-from matplotlib.axes import Axes
-import matplotlib.axis as maxis
-from matplotlib import cbook
-from matplotlib import docstring
-import matplotlib.markers as mmarkers
-import matplotlib.patches as mpatches
-import matplotlib.path as mpath
-from matplotlib import rcParams
-import matplotlib.ticker as mticker
-import matplotlib.transforms as mtransforms
-import matplotlib.spines as mspines
-
-
-class PolarTransform(mtransforms.Transform):
- """
- The base polar transform. This handles projection *theta* and
- *r* into Cartesian coordinate space *x* and *y*, but does not
- perform the ultimate affine transformation into the correct
- position.
- """
- input_dims = 2
- output_dims = 2
- is_separable = False
-
- def __init__(self, axis=None, use_rmin=True,
- _apply_theta_transforms=True):
- mtransforms.Transform.__init__(self)
- self._axis = axis
- self._use_rmin = use_rmin
- self._apply_theta_transforms = _apply_theta_transforms
-
- def __str__(self):
- return ("{}(\n"
- "{},\n"
- " use_rmin={},\n"
- " _apply_theta_transforms={})"
- .format(type(self).__name__,
- mtransforms._indent_str(self._axis),
- self._use_rmin,
- self._apply_theta_transforms))
-
- def transform_non_affine(self, tr):
- xy = np.empty(tr.shape, float)
-
- t = tr[:, 0:1]
- r = tr[:, 1:2]
- x = xy[:, 0:1]
- y = xy[:, 1:2]
-
- # PolarAxes does not use the theta transforms here, but apply them for
- # backwards-compatibility if not being used by it.
- if self._apply_theta_transforms and self._axis is not None:
- t *= self._axis.get_theta_direction()
- t += self._axis.get_theta_offset()
-
- if self._use_rmin and self._axis is not None:
- r = r - self._axis.get_rorigin()
- mask = r < 0
- x[:] = np.where(mask, np.nan, r * np.cos(t))
- y[:] = np.where(mask, np.nan, r * np.sin(t))
-
- return xy
- transform_non_affine.__doc__ = \
- mtransforms.Transform.transform_non_affine.__doc__
-
- def transform_path_non_affine(self, path):
- vertices = path.vertices
- if len(vertices) == 2 and vertices[0, 0] == vertices[1, 0]:
- return mpath.Path(self.transform(vertices), path.codes)
- ipath = path.interpolated(path._interpolation_steps)
- return mpath.Path(self.transform(ipath.vertices), ipath.codes)
- transform_path_non_affine.__doc__ = \
- mtransforms.Transform.transform_path_non_affine.__doc__
-
- def inverted(self):
- return PolarAxes.InvertedPolarTransform(self._axis, self._use_rmin,
- self._apply_theta_transforms)
- inverted.__doc__ = mtransforms.Transform.inverted.__doc__
-
-
-class PolarAffine(mtransforms.Affine2DBase):
- """
- The affine part of the polar projection. Scales the output so
- that maximum radius rests on the edge of the axes circle.
- """
- def __init__(self, scale_transform, limits):
- """
- *limits* is the view limit of the data. The only part of
- its bounds that is used is the y limits (for the radius limits).
- The theta range is handled by the non-affine transform.
- """
- mtransforms.Affine2DBase.__init__(self)
- self._scale_transform = scale_transform
- self._limits = limits
- self.set_children(scale_transform, limits)
- self._mtx = None
-
- def __str__(self):
- return ("{}(\n"
- "{},\n"
- "{})"
- .format(type(self).__name__,
- mtransforms._indent_str(self._scale_transform),
- mtransforms._indent_str(self._limits)))
-
- def get_matrix(self):
- if self._invalid:
- limits_scaled = self._limits.transformed(self._scale_transform)
- yscale = limits_scaled.ymax - limits_scaled.ymin
- affine = mtransforms.Affine2D() \
- .scale(0.5 / yscale) \
- .translate(0.5, 0.5)
- self._mtx = affine.get_matrix()
- self._inverted = None
- self._invalid = 0
- return self._mtx
- get_matrix.__doc__ = mtransforms.Affine2DBase.get_matrix.__doc__
-
-
-class InvertedPolarTransform(mtransforms.Transform):
- """
- The inverse of the polar transform, mapping Cartesian
- coordinate space *x* and *y* back to *theta* and *r*.
- """
- input_dims = 2
- output_dims = 2
- is_separable = False
-
- def __init__(self, axis=None, use_rmin=True,
- _apply_theta_transforms=True):
- mtransforms.Transform.__init__(self)
- self._axis = axis
- self._use_rmin = use_rmin
- self._apply_theta_transforms = _apply_theta_transforms
-
- def __str__(self):
- return ("{}(\n"
- "{},\n"
- " use_rmin={},\n"
- " _apply_theta_transforms={})"
- .format(type(self).__name__,
- mtransforms._indent_str(self._axis),
- self._use_rmin,
- self._apply_theta_transforms))
-
- def transform_non_affine(self, xy):
- x = xy[:, 0:1]
- y = xy[:, 1:]
- r = np.sqrt(x*x + y*y)
- with np.errstate(invalid='ignore'):
- # At x=y=r=0 this will raise an
- # invalid value warning when doing 0/0
- # Divide by zero warnings are only raised when
- # the numerator is different from 0. That
- # should not happen here.
- theta = np.arccos(x / r)
- theta = np.where(y < 0, 2 * np.pi - theta, theta)
-
- # PolarAxes does not use the theta transforms here, but apply them for
- # backwards-compatibility if not being used by it.
- if self._apply_theta_transforms and self._axis is not None:
- theta -= self._axis.get_theta_offset()
- theta *= self._axis.get_theta_direction()
- theta %= 2 * np.pi
-
- if self._use_rmin and self._axis is not None:
- r += self._axis.get_rorigin()
-
- return np.concatenate((theta, r), 1)
- transform_non_affine.__doc__ = \
- mtransforms.Transform.transform_non_affine.__doc__
-
- def inverted(self):
- return PolarAxes.PolarTransform(self._axis, self._use_rmin,
- self._apply_theta_transforms)
- inverted.__doc__ = mtransforms.Transform.inverted.__doc__
-
-
-class ThetaFormatter(mticker.Formatter):
- """
- Used to format the *theta* tick labels. Converts the native
- unit of radians into degrees and adds a degree symbol.
- """
- def __call__(self, x, pos=None):
- vmin, vmax = self.axis.get_view_interval()
- d = np.rad2deg(abs(vmax - vmin))
- digits = max(-int(np.log10(d) - 1.5), 0)
-
- if rcParams['text.usetex'] and not rcParams['text.latex.unicode']:
- format_str = r"${value:0.{digits:d}f}^\circ$"
- return format_str.format(value=np.rad2deg(x), digits=digits)
- else:
- # we use unicode, rather than mathtext with \circ, so
- # that it will work correctly with any arbitrary font
- # (assuming it has a degree sign), whereas $5\circ$
- # will only work correctly with one of the supported
- # math fonts (Computer Modern and STIX)
- format_str = "{value:0.{digits:d}f}\N{DEGREE SIGN}"
- return format_str.format(value=np.rad2deg(x), digits=digits)
-
-
-class _AxisWrapper(object):
- def __init__(self, axis):
- self._axis = axis
-
- def get_view_interval(self):
- return np.rad2deg(self._axis.get_view_interval())
-
- def set_view_interval(self, vmin, vmax):
- self._axis.set_view_interval(*np.deg2rad((vmin, vmax)))
-
- def get_minpos(self):
- return np.rad2deg(self._axis.get_minpos())
-
- def get_data_interval(self):
- return np.rad2deg(self._axis.get_data_interval())
-
- def set_data_interval(self, vmin, vmax):
- self._axis.set_data_interval(*np.deg2rad((vmin, vmax)))
-
- def get_tick_space(self):
- return self._axis.get_tick_space()
-
-
-class ThetaLocator(mticker.Locator):
- """
- Used to locate theta ticks.
-
- This will work the same as the base locator except in the case that the
- view spans the entire circle. In such cases, the previously used default
- locations of every 45 degrees are returned.
- """
- def __init__(self, base):
- self.base = base
- self.axis = self.base.axis = _AxisWrapper(self.base.axis)
-
- def set_axis(self, axis):
- self.axis = _AxisWrapper(axis)
- self.base.set_axis(self.axis)
-
- def __call__(self):
- lim = self.axis.get_view_interval()
- if _is_full_circle_deg(lim[0], lim[1]):
- return np.arange(8) * 2 * np.pi / 8
- else:
- return np.deg2rad(self.base())
-
- def autoscale(self):
- return self.base.autoscale()
-
- def pan(self, numsteps):
- return self.base.pan(numsteps)
-
- def refresh(self):
- return self.base.refresh()
-
- def view_limits(self, vmin, vmax):
- vmin, vmax = np.rad2deg((vmin, vmax))
- return np.deg2rad(self.base.view_limits(vmin, vmax))
-
- def zoom(self, direction):
- return self.base.zoom(direction)
-
-
-class ThetaTick(maxis.XTick):
- """
- A theta-axis tick.
-
- This subclass of `XTick` provides angular ticks with some small
- modification to their re-positioning such that ticks are rotated based on
- tick location. This results in ticks that are correctly perpendicular to
- the arc spine.
-
- When 'auto' rotation is enabled, labels are also rotated to be parallel to
- the spine. The label padding is also applied here since it's not possible
- to use a generic axes transform to produce tick-specific padding.
- """
- def __init__(self, axes, *args, **kwargs):
- self._text1_translate = mtransforms.ScaledTranslation(
- 0, 0,
- axes.figure.dpi_scale_trans)
- self._text2_translate = mtransforms.ScaledTranslation(
- 0, 0,
- axes.figure.dpi_scale_trans)
- super(ThetaTick, self).__init__(axes, *args, **kwargs)
-
- def _get_text1(self):
- t = super(ThetaTick, self)._get_text1()
- t.set_rotation_mode('anchor')
- t.set_transform(t.get_transform() + self._text1_translate)
- return t
-
- def _get_text2(self):
- t = super(ThetaTick, self)._get_text2()
- t.set_rotation_mode('anchor')
- t.set_transform(t.get_transform() + self._text2_translate)
- return t
-
- def _apply_params(self, **kw):
- super(ThetaTick, self)._apply_params(**kw)
-
- # Ensure transform is correct; sometimes this gets reset.
- trans = self.label1.get_transform()
- if not trans.contains_branch(self._text1_translate):
- self.label1.set_transform(trans + self._text1_translate)
- trans = self.label2.get_transform()
- if not trans.contains_branch(self._text2_translate):
- self.label2.set_transform(trans + self._text2_translate)
-
- def _update_padding(self, pad, angle):
- padx = pad * np.cos(angle) / 72
- pady = pad * np.sin(angle) / 72
- self._text1_translate._t = (padx, pady)
- self._text1_translate.invalidate()
- self._text2_translate._t = (-padx, -pady)
- self._text2_translate.invalidate()
-
- def update_position(self, loc):
- super(ThetaTick, self).update_position(loc)
- axes = self.axes
- angle = loc * axes.get_theta_direction() + axes.get_theta_offset()
- text_angle = np.rad2deg(angle) % 360 - 90
- angle -= np.pi / 2
-
- if self.tick1On:
- marker = self.tick1line.get_marker()
- if marker in (mmarkers.TICKUP, '|'):
- trans = mtransforms.Affine2D().scale(1.0, 1.0).rotate(angle)
- elif marker == mmarkers.TICKDOWN:
- trans = mtransforms.Affine2D().scale(1.0, -1.0).rotate(angle)
- else:
- # Don't modify custom tick line markers.
- trans = self.tick1line._marker._transform
- self.tick1line._marker._transform = trans
- if self.tick2On:
- marker = self.tick2line.get_marker()
- if marker in (mmarkers.TICKUP, '|'):
- trans = mtransforms.Affine2D().scale(1.0, 1.0).rotate(angle)
- elif marker == mmarkers.TICKDOWN:
- trans = mtransforms.Affine2D().scale(1.0, -1.0).rotate(angle)
- else:
- # Don't modify custom tick line markers.
- trans = self.tick2line._marker._transform
- self.tick2line._marker._transform = trans
-
- mode, user_angle = self._labelrotation
- if mode == 'default':
- text_angle = user_angle
- else:
- if text_angle > 90:
- text_angle -= 180
- elif text_angle < -90:
- text_angle += 180
- text_angle += user_angle
- if self.label1On:
- self.label1.set_rotation(text_angle)
- if self.label2On:
- self.label2.set_rotation(text_angle)
-
- # This extra padding helps preserve the look from previous releases but
- # is also needed because labels are anchored to their center.
- pad = self._pad + 7
- self._update_padding(pad,
- self._loc * axes.get_theta_direction() +
- axes.get_theta_offset())
-
-
-class ThetaAxis(maxis.XAxis):
- """
- A theta Axis.
-
- This overrides certain properties of an `XAxis` to provide special-casing
- for an angular axis.
- """
- __name__ = 'thetaaxis'
- axis_name = 'theta'
-
- def _get_tick(self, major):
- if major:
- tick_kw = self._major_tick_kw
- else:
- tick_kw = self._minor_tick_kw
- return ThetaTick(self.axes, 0, '', major=major, **tick_kw)
-
- def _wrap_locator_formatter(self):
- self.set_major_locator(ThetaLocator(self.get_major_locator()))
- self.set_major_formatter(ThetaFormatter())
- self.isDefault_majloc = True
- self.isDefault_majfmt = True
-
- def cla(self):
- super(ThetaAxis, self).cla()
- self.set_ticks_position('none')
- self._wrap_locator_formatter()
-
- def _set_scale(self, value, **kwargs):
- super(ThetaAxis, self)._set_scale(value, **kwargs)
- self._wrap_locator_formatter()
-
- def _copy_tick_props(self, src, dest):
- 'Copy the props from src tick to dest tick'
- if src is None or dest is None:
- return
- super(ThetaAxis, self)._copy_tick_props(src, dest)
-
- # Ensure that tick transforms are independent so that padding works.
- trans = dest._get_text1_transform()[0]
- dest.label1.set_transform(trans + dest._text1_translate)
- trans = dest._get_text2_transform()[0]
- dest.label2.set_transform(trans + dest._text2_translate)
-
-
-class RadialLocator(mticker.Locator):
- """
- Used to locate radius ticks.
-
- Ensures that all ticks are strictly positive. For all other
- tasks, it delegates to the base
- :class:`~matplotlib.ticker.Locator` (which may be different
- depending on the scale of the *r*-axis.
- """
- def __init__(self, base, axes=None):
- self.base = base
- self._axes = axes
-
- def __call__(self):
- show_all = True
- # Ensure previous behaviour with full circle non-annular views.
- if self._axes:
- if _is_full_circle_rad(*self._axes.viewLim.intervalx):
- rorigin = self._axes.get_rorigin()
- if self._axes.get_rmin() <= rorigin:
- show_all = False
-
- if show_all:
- return self.base()
- else:
- return [tick for tick in self.base() if tick > rorigin]
-
- def autoscale(self):
- return self.base.autoscale()
-
- def pan(self, numsteps):
- return self.base.pan(numsteps)
-
- def zoom(self, direction):
- return self.base.zoom(direction)
-
- def refresh(self):
- return self.base.refresh()
-
- def view_limits(self, vmin, vmax):
- vmin, vmax = self.base.view_limits(vmin, vmax)
- return mtransforms.nonsingular(min(0, vmin), vmax)
-
-
-class _ThetaShift(mtransforms.ScaledTranslation):
- """
- Apply a padding shift based on axes theta limits.
-
- This is used to create padding for radial ticks.
-
- Parameters
- ----------
- axes : matplotlib.axes.Axes
- The owning axes; used to determine limits.
- pad : float
- The padding to apply, in points.
- start : str, {'min', 'max', 'rlabel'}
- Whether to shift away from the start (``'min'``) or the end (``'max'``)
- of the axes, or using the rlabel position (``'rlabel'``).
- """
- def __init__(self, axes, pad, mode):
- mtransforms.ScaledTranslation.__init__(self, pad, pad,
- axes.figure.dpi_scale_trans)
- self.set_children(axes._realViewLim)
- self.axes = axes
- self.mode = mode
- self.pad = pad
-
- def __str__(self):
- return ("{}(\n"
- "{},\n"
- "{},\n"
- "{})"
- .format(type(self).__name__,
- mtransforms._indent_str(self.axes),
- mtransforms._indent_str(self.pad),
- mtransforms._indent_str(repr(self.mode))))
-
- def get_matrix(self):
- if self._invalid:
- if self.mode == 'rlabel':
- angle = (
- np.deg2rad(self.axes.get_rlabel_position()) *
- self.axes.get_theta_direction() +
- self.axes.get_theta_offset()
- )
- else:
- if self.mode == 'min':
- angle = self.axes._realViewLim.xmin
- elif self.mode == 'max':
- angle = self.axes._realViewLim.xmax
-
- if self.mode in ('rlabel', 'min'):
- padx = np.cos(angle - np.pi / 2)
- pady = np.sin(angle - np.pi / 2)
- else:
- padx = np.cos(angle + np.pi / 2)
- pady = np.sin(angle + np.pi / 2)
-
- self._t = (self.pad * padx / 72, self.pad * pady / 72)
- return mtransforms.ScaledTranslation.get_matrix(self)
-
-
-class RadialTick(maxis.YTick):
- """
- A radial-axis tick.
-
- This subclass of `YTick` provides radial ticks with some small modification
- to their re-positioning such that ticks are rotated based on axes limits.
- This results in ticks that are correctly perpendicular to the spine. Labels
- are also rotated to be perpendicular to the spine, when 'auto' rotation is
- enabled.
- """
- def _get_text1(self):
- t = super(RadialTick, self)._get_text1()
- t.set_rotation_mode('anchor')
- return t
-
- def _get_text2(self):
- t = super(RadialTick, self)._get_text2()
- t.set_rotation_mode('anchor')
- return t
-
- def _determine_anchor(self, mode, angle, start):
- # Note: angle is the (spine angle - 90) because it's used for the tick
- # & text setup, so all numbers below are -90 from (normed) spine angle.
- if mode == 'auto':
- if start:
- if -90 <= angle <= 90:
- return 'left', 'center'
- else:
- return 'right', 'center'
- else:
- if -90 <= angle <= 90:
- return 'right', 'center'
- else:
- return 'left', 'center'
- else:
- if start:
- if angle < -68.5:
- return 'center', 'top'
- elif angle < -23.5:
- return 'left', 'top'
- elif angle < 22.5:
- return 'left', 'center'
- elif angle < 67.5:
- return 'left', 'bottom'
- elif angle < 112.5:
- return 'center', 'bottom'
- elif angle < 157.5:
- return 'right', 'bottom'
- elif angle < 202.5:
- return 'right', 'center'
- elif angle < 247.5:
- return 'right', 'top'
- else:
- return 'center', 'top'
- else:
- if angle < -68.5:
- return 'center', 'bottom'
- elif angle < -23.5:
- return 'right', 'bottom'
- elif angle < 22.5:
- return 'right', 'center'
- elif angle < 67.5:
- return 'right', 'top'
- elif angle < 112.5:
- return 'center', 'top'
- elif angle < 157.5:
- return 'left', 'top'
- elif angle < 202.5:
- return 'left', 'center'
- elif angle < 247.5:
- return 'left', 'bottom'
- else:
- return 'center', 'bottom'
-
- def update_position(self, loc):
- super(RadialTick, self).update_position(loc)
- axes = self.axes
- thetamin = axes.get_thetamin()
- thetamax = axes.get_thetamax()
- direction = axes.get_theta_direction()
- offset_rad = axes.get_theta_offset()
- offset = np.rad2deg(offset_rad)
- full = _is_full_circle_deg(thetamin, thetamax)
-
- if full:
- angle = (axes.get_rlabel_position() * direction +
- offset) % 360 - 90
- tick_angle = 0
- if angle > 90:
- text_angle = angle - 180
- elif angle < -90:
- text_angle = angle + 180
- else:
- text_angle = angle
- else:
- angle = (thetamin * direction + offset) % 360 - 90
- if direction > 0:
- tick_angle = np.deg2rad(angle)
- else:
- tick_angle = np.deg2rad(angle + 180)
- if angle > 90:
- text_angle = angle - 180
- elif angle < -90:
- text_angle = angle + 180
- else:
- text_angle = angle
- mode, user_angle = self._labelrotation
- if mode == 'auto':
- text_angle += user_angle
- else:
- text_angle = user_angle
- if self.label1On:
- if full:
- ha = self.label1.get_ha()
- va = self.label1.get_va()
- else:
- ha, va = self._determine_anchor(mode, angle, direction > 0)
- self.label1.set_ha(ha)
- self.label1.set_va(va)
- self.label1.set_rotation(text_angle)
- if self.tick1On:
- marker = self.tick1line.get_marker()
- if marker == mmarkers.TICKLEFT:
- trans = (mtransforms.Affine2D()
- .scale(1.0, 1.0)
- .rotate(tick_angle))
- elif marker == '_':
- trans = (mtransforms.Affine2D()
- .scale(1.0, 1.0)
- .rotate(tick_angle + np.pi / 2))
- elif marker == mmarkers.TICKRIGHT:
- trans = (mtransforms.Affine2D()
- .scale(-1.0, 1.0)
- .rotate(tick_angle))
- else:
- # Don't modify custom tick line markers.
- trans = self.tick1line._marker._transform
- self.tick1line._marker._transform = trans
-
- if full:
- self.label2On = False
- self.tick2On = False
- else:
- angle = (thetamax * direction + offset) % 360 - 90
- if direction > 0:
- tick_angle = np.deg2rad(angle)
- else:
- tick_angle = np.deg2rad(angle + 180)
- if angle > 90:
- text_angle = angle - 180
- elif angle < -90:
- text_angle = angle + 180
- else:
- text_angle = angle
- mode, user_angle = self._labelrotation
- if mode == 'auto':
- text_angle += user_angle
- else:
- text_angle = user_angle
- if self.label2On:
- ha, va = self._determine_anchor(mode, angle, direction < 0)
- self.label2.set_ha(ha)
- self.label2.set_va(va)
- self.label2.set_rotation(text_angle)
- if self.tick2On:
- marker = self.tick2line.get_marker()
- if marker == mmarkers.TICKLEFT:
- trans = (mtransforms.Affine2D()
- .scale(1.0, 1.0)
- .rotate(tick_angle))
- elif marker == '_':
- trans = (mtransforms.Affine2D()
- .scale(1.0, 1.0)
- .rotate(tick_angle + np.pi / 2))
- elif marker == mmarkers.TICKRIGHT:
- trans = (mtransforms.Affine2D()
- .scale(-1.0, 1.0)
- .rotate(tick_angle))
- else:
- # Don't modify custom tick line markers.
- trans = self.tick2line._marker._transform
- self.tick2line._marker._transform = trans
-
-
-class RadialAxis(maxis.YAxis):
- """
- A radial Axis.
-
- This overrides certain properties of a `YAxis` to provide special-casing
- for a radial axis.
- """
- __name__ = 'radialaxis'
- axis_name = 'radius'
-
- def __init__(self, *args, **kwargs):
- super(RadialAxis, self).__init__(*args, **kwargs)
- self.sticky_edges.y.append(0)
-
- def _get_tick(self, major):
- if major:
- tick_kw = self._major_tick_kw
- else:
- tick_kw = self._minor_tick_kw
- return RadialTick(self.axes, 0, '', major=major, **tick_kw)
-
- def _wrap_locator_formatter(self):
- self.set_major_locator(RadialLocator(self.get_major_locator(),
- self.axes))
- self.isDefault_majloc = True
-
- def cla(self):
- super(RadialAxis, self).cla()
- self.set_ticks_position('none')
- self._wrap_locator_formatter()
-
- def _set_scale(self, value, **kwargs):
- super(RadialAxis, self)._set_scale(value, **kwargs)
- self._wrap_locator_formatter()
-
-
-def _is_full_circle_deg(thetamin, thetamax):
- """
- Determine if a wedge (in degrees) spans the full circle.
-
- The condition is derived from :class:`~matplotlib.patches.Wedge`.
- """
- return abs(abs(thetamax - thetamin) - 360.0) < 1e-12
-
-
-def _is_full_circle_rad(thetamin, thetamax):
- """
- Determine if a wedge (in radians) spans the full circle.
-
- The condition is derived from :class:`~matplotlib.patches.Wedge`.
- """
- return abs(abs(thetamax - thetamin) - 2 * np.pi) < 1.74e-14
-
-
-class _WedgeBbox(mtransforms.Bbox):
- """
- Transform (theta,r) wedge Bbox into axes bounding box.
-
- Parameters
- ----------
- center : tuple of float
- Center of the wedge
- viewLim : `~matplotlib.transforms.Bbox`
- Bbox determining the boundaries of the wedge
- originLim : `~matplotlib.transforms.Bbox`
- Bbox determining the origin for the wedge, if different from *viewLim*
- """
- def __init__(self, center, viewLim, originLim, **kwargs):
- mtransforms.Bbox.__init__(self,
- np.array([[0.0, 0.0], [1.0, 1.0]], np.float),
- **kwargs)
- self._center = center
- self._viewLim = viewLim
- self._originLim = originLim
- self.set_children(viewLim, originLim)
-
- def __str__(self):
- return ("{}(\n"
- "{},\n"
- "{},\n"
- "{})"
- .format(type(self).__name__,
- mtransforms._indent_str(self._center),
- mtransforms._indent_str(self._viewLim),
- mtransforms._indent_str(self._originLim)))
-
- def get_points(self):
- if self._invalid:
- points = self._viewLim.get_points().copy()
-
- # Scale angular limits to work with Wedge.
- points[:, 0] *= 180 / np.pi
- if points[0, 0] > points[1, 0]:
- points[:, 0] = points[::-1, 0]
-
- # Scale radial limits based on origin radius.
- points[:, 1] -= self._originLim.y0
-
- # Scale radial limits to match axes limits.
- rscale = 0.5 / points[1, 1]
- points[:, 1] *= rscale
- width = min(points[1, 1] - points[0, 1], 0.5)
-
- # Generate bounding box for wedge.
- wedge = mpatches.Wedge(self._center, points[1, 1],
- points[0, 0], points[1, 0],
- width=width)
- self.update_from_path(wedge.get_path())
-
- # Ensure equal aspect ratio.
- w, h = self._points[1] - self._points[0]
- if h < w:
- deltah = (w - h) / 2.0
- deltaw = 0.0
- elif w < h:
- deltah = 0.0
- deltaw = (h - w) / 2.0
- else:
- deltah = 0.0
- deltaw = 0.0
- self._points += np.array([[-deltaw, -deltah], [deltaw, deltah]])
-
- self._invalid = 0
-
- return self._points
- get_points.__doc__ = mtransforms.Bbox.get_points.__doc__
-
-
-class PolarAxes(Axes):
- """
- A polar graph projection, where the input dimensions are *theta*, *r*.
-
- Theta starts pointing east and goes anti-clockwise.
- """
- name = 'polar'
-
- def __init__(self, *args, **kwargs):
- """
- Create a new Polar Axes for a polar plot.
- """
- self._default_theta_offset = kwargs.pop('theta_offset', 0)
- self._default_theta_direction = kwargs.pop('theta_direction', 1)
- self._default_rlabel_position = np.deg2rad(
- kwargs.pop('rlabel_position', 22.5))
-
- Axes.__init__(self, *args, **kwargs)
- self.use_sticky_edges = True
- self.set_aspect('equal', adjustable='box', anchor='C')
- self.cla()
- __init__.__doc__ = Axes.__init__.__doc__
-
- def cla(self):
- Axes.cla(self)
-
- self.title.set_y(1.05)
-
- start = self.spines.get('start', None)
- if start:
- start.set_visible(False)
- end = self.spines.get('end', None)
- if end:
- end.set_visible(False)
- self.set_xlim(0.0, 2 * np.pi)
-
- self.grid(rcParams['polaraxes.grid'])
- inner = self.spines.get('inner', None)
- if inner:
- inner.set_visible(False)
-
- self.set_rorigin(None)
- self.set_theta_offset(self._default_theta_offset)
- self.set_theta_direction(self._default_theta_direction)
-
- def _init_axis(self):
- "move this out of __init__ because non-separable axes don't use it"
- self.xaxis = ThetaAxis(self)
- self.yaxis = RadialAxis(self)
- # Calling polar_axes.xaxis.cla() or polar_axes.xaxis.cla()
- # results in weird artifacts. Therefore we disable this for
- # now.
- # self.spines['polar'].register_axis(self.yaxis)
- self._update_transScale()
-
- def _set_lim_and_transforms(self):
- # A view limit where the minimum radius can be locked if the user
- # specifies an alternate origin.
- self._originViewLim = mtransforms.LockableBbox(self.viewLim)
-
- # Handle angular offset and direction.
- self._direction = mtransforms.Affine2D() \
- .scale(self._default_theta_direction, 1.0)
- self._theta_offset = mtransforms.Affine2D() \
- .translate(self._default_theta_offset, 0.0)
- self.transShift = mtransforms.composite_transform_factory(
- self._direction,
- self._theta_offset)
- # A view limit shifted to the correct location after accounting for
- # orientation and offset.
- self._realViewLim = mtransforms.TransformedBbox(self.viewLim,
- self.transShift)
-
- # Transforms the x and y axis separately by a scale factor
- # It is assumed that this part will have non-linear components
- self.transScale = mtransforms.TransformWrapper(
- mtransforms.IdentityTransform())
-
- # Scale view limit into a bbox around the selected wedge. This may be
- # smaller than the usual unit axes rectangle if not plotting the full
- # circle.
- self.axesLim = _WedgeBbox((0.5, 0.5),
- self._realViewLim, self._originViewLim)
-
- # Scale the wedge to fill the axes.
- self.transWedge = mtransforms.BboxTransformFrom(self.axesLim)
-
- # Scale the axes to fill the figure.
- self.transAxes = mtransforms.BboxTransformTo(self.bbox)
-
- # A (possibly non-linear) projection on the (already scaled)
- # data. This one is aware of rmin
- self.transProjection = self.PolarTransform(
- self,
- _apply_theta_transforms=False)
- # Add dependency on rorigin.
- self.transProjection.set_children(self._originViewLim)
-
- # An affine transformation on the data, generally to limit the
- # range of the axes
- self.transProjectionAffine = self.PolarAffine(self.transScale,
- self._originViewLim)
-
- # The complete data transformation stack -- from data all the
- # way to display coordinates
- self.transData = (
- self.transScale + self.transShift + self.transProjection +
- (self.transProjectionAffine + self.transWedge + self.transAxes))
-
- # This is the transform for theta-axis ticks. It is
- # equivalent to transData, except it always puts r == 0.0 and r == 1.0
- # at the edge of the axis circles.
- self._xaxis_transform = (
- mtransforms.blended_transform_factory(
- mtransforms.IdentityTransform(),
- mtransforms.BboxTransformTo(self.viewLim)) +
- self.transData)
- # The theta labels are flipped along the radius, so that text 1 is on
- # the outside by default. This should work the same as before.
- flipr_transform = mtransforms.Affine2D() \
- .translate(0.0, -0.5) \
- .scale(1.0, -1.0) \
- .translate(0.0, 0.5)
- self._xaxis_text_transform = flipr_transform + self._xaxis_transform
-
- # This is the transform for r-axis ticks. It scales the theta
- # axis so the gridlines from 0.0 to 1.0, now go from thetamin to
- # thetamax.
- self._yaxis_transform = (
- mtransforms.blended_transform_factory(
- mtransforms.BboxTransformTo(self.viewLim),
- mtransforms.IdentityTransform()) +
- self.transData)
- # The r-axis labels are put at an angle and padded in the r-direction
- self._r_label_position = mtransforms.Affine2D() \
- .translate(self._default_rlabel_position, 0.0)
- self._yaxis_text_transform = mtransforms.TransformWrapper(
- self._r_label_position + self.transData)
-
- def get_xaxis_transform(self, which='grid'):
- if which not in ['tick1', 'tick2', 'grid']:
- raise ValueError(
- "'which' must be one of 'tick1', 'tick2', or 'grid'")
- return self._xaxis_transform
-
- def get_xaxis_text1_transform(self, pad):
- return self._xaxis_text_transform, 'center', 'center'
-
- def get_xaxis_text2_transform(self, pad):
- return self._xaxis_text_transform, 'center', 'center'
-
- def get_yaxis_transform(self, which='grid'):
- if which in ('tick1', 'tick2'):
- return self._yaxis_text_transform
- elif which == 'grid':
- return self._yaxis_transform
- else:
- raise ValueError(
- "'which' must be one of 'tick1', 'tick2', or 'grid'")
-
- def get_yaxis_text1_transform(self, pad):
- thetamin, thetamax = self._realViewLim.intervalx
- if _is_full_circle_rad(thetamin, thetamax):
- return self._yaxis_text_transform, 'bottom', 'left'
- elif self.get_theta_direction() > 0:
- halign = 'left'
- pad_shift = _ThetaShift(self, pad, 'min')
- else:
- halign = 'right'
- pad_shift = _ThetaShift(self, pad, 'max')
- return self._yaxis_text_transform + pad_shift, 'center', halign
-
- def get_yaxis_text2_transform(self, pad):
- if self.get_theta_direction() > 0:
- halign = 'right'
- pad_shift = _ThetaShift(self, pad, 'max')
- else:
- halign = 'left'
- pad_shift = _ThetaShift(self, pad, 'min')
- return self._yaxis_text_transform + pad_shift, 'center', halign
-
- def draw(self, *args, **kwargs):
- thetamin, thetamax = np.rad2deg(self._realViewLim.intervalx)
- if thetamin > thetamax:
- thetamin, thetamax = thetamax, thetamin
- rmin, rmax = self._realViewLim.intervaly - self.get_rorigin()
-
- if isinstance(self.patch, mpatches.Wedge):
- # Backwards-compatibility: Any subclassed Axes might override the
- # patch to not be the Wedge that PolarAxes uses.
- center = self.transWedge.transform_point((0.5, 0.5))
- self.patch.set_center(center)
- self.patch.set_theta1(thetamin)
- self.patch.set_theta2(thetamax)
-
- edge, _ = self.transWedge.transform_point((1, 0))
- radius = edge - center[0]
- width = min(radius * (rmax - rmin) / rmax, radius)
- self.patch.set_radius(radius)
- self.patch.set_width(width)
-
- inner_width = radius - width
- inner = self.spines.get('inner', None)
- if inner:
- inner.set_visible(inner_width != 0.0)
-
- visible = not _is_full_circle_deg(thetamin, thetamax)
- # For backwards compatibility, any subclassed Axes might override the
- # spines to not include start/end that PolarAxes uses.
- start = self.spines.get('start', None)
- end = self.spines.get('end', None)
- if start:
- start.set_visible(visible)
- if end:
- end.set_visible(visible)
- if visible:
- yaxis_text_transform = self._yaxis_transform
- else:
- yaxis_text_transform = self._r_label_position + self.transData
- if self._yaxis_text_transform != yaxis_text_transform:
- self._yaxis_text_transform.set(yaxis_text_transform)
- self.yaxis.reset_ticks()
- self.yaxis.set_clip_path(self.patch)
-
- Axes.draw(self, *args, **kwargs)
-
- def _gen_axes_patch(self):
- return mpatches.Wedge((0.5, 0.5), 0.5, 0.0, 360.0)
-
- def _gen_axes_spines(self):
- spines = OrderedDict([
- ('polar', mspines.Spine.arc_spine(self, 'top',
- (0.5, 0.5), 0.5, 0.0, 360.0)),
- ('start', mspines.Spine.linear_spine(self, 'left')),
- ('end', mspines.Spine.linear_spine(self, 'right')),
- ('inner', mspines.Spine.arc_spine(self, 'bottom',
- (0.5, 0.5), 0.0, 0.0, 360.0))
- ])
- spines['polar'].set_transform(self.transWedge + self.transAxes)
- spines['inner'].set_transform(self.transWedge + self.transAxes)
- spines['start'].set_transform(self._yaxis_transform)
- spines['end'].set_transform(self._yaxis_transform)
- return spines
-
- def set_thetamax(self, thetamax):
- self.viewLim.x1 = np.deg2rad(thetamax)
-
- def get_thetamax(self):
- return np.rad2deg(self.viewLim.xmax)
-
- def set_thetamin(self, thetamin):
- self.viewLim.x0 = np.deg2rad(thetamin)
-
- def get_thetamin(self):
- return np.rad2deg(self.viewLim.xmin)
-
- def set_thetalim(self, *args, **kwargs):
- if 'thetamin' in kwargs:
- kwargs['xmin'] = np.deg2rad(kwargs.pop('thetamin'))
- if 'thetamax' in kwargs:
- kwargs['xmax'] = np.deg2rad(kwargs.pop('thetamax'))
- return tuple(np.rad2deg(self.set_xlim(*args, **kwargs)))
-
- def set_theta_offset(self, offset):
- """
- Set the offset for the location of 0 in radians.
- """
- mtx = self._theta_offset.get_matrix()
- mtx[0, 2] = offset
- self._theta_offset.invalidate()
-
- def get_theta_offset(self):
- """
- Get the offset for the location of 0 in radians.
- """
- return self._theta_offset.get_matrix()[0, 2]
-
- def set_theta_zero_location(self, loc, offset=0.0):
- """
- Sets the location of theta's zero. (Calls set_theta_offset
- with the correct value in radians under the hood.)
-
- loc : str
- May be one of "N", "NW", "W", "SW", "S", "SE", "E", or "NE".
-
- offset : float, optional
- An offset in degrees to apply from the specified `loc`. **Note:**
- this offset is *always* applied counter-clockwise regardless of
- the direction setting.
- """
- mapping = {
- 'N': np.pi * 0.5,
- 'NW': np.pi * 0.75,
- 'W': np.pi,
- 'SW': np.pi * 1.25,
- 'S': np.pi * 1.5,
- 'SE': np.pi * 1.75,
- 'E': 0,
- 'NE': np.pi * 0.25}
- return self.set_theta_offset(mapping[loc] + np.deg2rad(offset))
-
- def set_theta_direction(self, direction):
- """
- Set the direction in which theta increases.
-
- clockwise, -1:
- Theta increases in the clockwise direction
-
- counterclockwise, anticlockwise, 1:
- Theta increases in the counterclockwise direction
- """
- mtx = self._direction.get_matrix()
- if direction in ('clockwise',):
- mtx[0, 0] = -1
- elif direction in ('counterclockwise', 'anticlockwise'):
- mtx[0, 0] = 1
- elif direction in (1, -1):
- mtx[0, 0] = direction
- else:
- raise ValueError(
- "direction must be 1, -1, clockwise or counterclockwise")
- self._direction.invalidate()
-
- def get_theta_direction(self):
- """
- Get the direction in which theta increases.
-
- -1:
- Theta increases in the clockwise direction
-
- 1:
- Theta increases in the counterclockwise direction
- """
- return self._direction.get_matrix()[0, 0]
-
- def set_rmax(self, rmax):
- self.viewLim.y1 = rmax
-
- def get_rmax(self):
- return self.viewLim.ymax
-
- def set_rmin(self, rmin):
- self.viewLim.y0 = rmin
-
- def get_rmin(self):
- return self.viewLim.ymin
-
- def set_rorigin(self, rorigin):
- self._originViewLim.locked_y0 = rorigin
-
- def get_rorigin(self):
- return self._originViewLim.y0
-
- def set_rlim(self, *args, **kwargs):
- if 'rmin' in kwargs:
- kwargs['ymin'] = kwargs.pop('rmin')
- if 'rmax' in kwargs:
- kwargs['ymax'] = kwargs.pop('rmax')
- return self.set_ylim(*args, **kwargs)
-
- def get_rlabel_position(self):
- """
- Returns
- -------
- float
- The theta position of the radius labels in degrees.
- """
- return np.rad2deg(self._r_label_position.get_matrix()[0, 2])
-
- def set_rlabel_position(self, value):
- """Updates the theta position of the radius labels.
-
- Parameters
- ----------
- value : number
- The angular position of the radius labels in degrees.
- """
- self._r_label_position.clear().translate(np.deg2rad(value), 0.0)
-
- def set_yscale(self, *args, **kwargs):
- Axes.set_yscale(self, *args, **kwargs)
- self.yaxis.set_major_locator(
- self.RadialLocator(self.yaxis.get_major_locator(), self))
-
- def set_rscale(self, *args, **kwargs):
- return Axes.set_yscale(self, *args, **kwargs)
-
- def set_rticks(self, *args, **kwargs):
- return Axes.set_yticks(self, *args, **kwargs)
-
- @docstring.dedent_interpd
- def set_thetagrids(self, angles, labels=None, frac=None, fmt=None,
- **kwargs):
- """
- Set the angles at which to place the theta grids (these
- gridlines are equal along the theta dimension). *angles* is in
- degrees.
-
- *labels*, if not None, is a ``len(angles)`` list of strings of
- the labels to use at each angle.
-
- If *labels* is None, the labels will be ``fmt %% angle``
-
- *frac* is the fraction of the polar axes radius at which to
- place the label (1 is the edge). e.g., 1.05 is outside the axes
- and 0.95 is inside the axes.
-
- Return value is a list of tuples (*line*, *label*), where
- *line* is :class:`~matplotlib.lines.Line2D` instances and the
- *label* is :class:`~matplotlib.text.Text` instances.
-
- kwargs are optional text properties for the labels:
-
- %(Text)s
-
- ACCEPTS: sequence of floats
- """
- if frac is not None:
- cbook.warn_deprecated('2.1', name='frac', obj_type='parameter',
- alternative='tick padding via '
- 'Axes.tick_params')
-
- # Make sure we take into account unitized data
- angles = self.convert_yunits(angles)
- angles = np.deg2rad(angles)
- self.set_xticks(angles)
- if labels is not None:
- self.set_xticklabels(labels)
- elif fmt is not None:
- self.xaxis.set_major_formatter(mticker.FormatStrFormatter(fmt))
- for t in self.xaxis.get_ticklabels():
- t.update(kwargs)
- return self.xaxis.get_ticklines(), self.xaxis.get_ticklabels()
-
- @docstring.dedent_interpd
- def set_rgrids(self, radii, labels=None, angle=None, fmt=None,
- **kwargs):
- """
- Set the radial locations and labels of the *r* grids.
-
- The labels will appear at radial distances *radii* at the
- given *angle* in degrees.
-
- *labels*, if not None, is a ``len(radii)`` list of strings of the
- labels to use at each radius.
-
- If *labels* is None, the built-in formatter will be used.
-
- Return value is a list of tuples (*line*, *label*), where
- *line* is :class:`~matplotlib.lines.Line2D` instances and the
- *label* is :class:`~matplotlib.text.Text` instances.
-
- kwargs are optional text properties for the labels:
-
- %(Text)s
-
- ACCEPTS: sequence of floats
- """
- # Make sure we take into account unitized data
- radii = self.convert_xunits(radii)
- radii = np.asarray(radii)
-
- self.set_yticks(radii)
- if labels is not None:
- self.set_yticklabels(labels)
- elif fmt is not None:
- self.yaxis.set_major_formatter(mticker.FormatStrFormatter(fmt))
- if angle is None:
- angle = self.get_rlabel_position()
- self.set_rlabel_position(angle)
- for t in self.yaxis.get_ticklabels():
- t.update(kwargs)
- return self.yaxis.get_gridlines(), self.yaxis.get_ticklabels()
-
- def set_xscale(self, scale, *args, **kwargs):
- if scale != 'linear':
- raise NotImplementedError(
- "You can not set the xscale on a polar plot.")
-
- def format_coord(self, theta, r):
- """
- Return a format string formatting the coordinate using Unicode
- characters.
- """
- if theta < 0:
- theta += 2 * np.pi
- theta /= np.pi
- return ('\N{GREEK SMALL LETTER THETA}=%0.3f\N{GREEK SMALL LETTER PI} '
- '(%0.3f\N{DEGREE SIGN}), r=%0.3f') % (theta, theta * 180.0, r)
-
- def get_data_ratio(self):
- '''
- Return the aspect ratio of the data itself. For a polar plot,
- this should always be 1.0
- '''
- return 1.0
-
- # # # Interactive panning
-
- def can_zoom(self):
- """
- Return *True* if this axes supports the zoom box button functionality.
-
- Polar axes do not support zoom boxes.
- """
- return False
-
- def can_pan(self):
- """
- Return *True* if this axes supports the pan/zoom button functionality.
-
- For polar axes, this is slightly misleading. Both panning and
- zooming are performed by the same button. Panning is performed
- in azimuth while zooming is done along the radial.
- """
- return True
-
- def start_pan(self, x, y, button):
- angle = np.deg2rad(self.get_rlabel_position())
- mode = ''
- if button == 1:
- epsilon = np.pi / 45.0
- t, r = self.transData.inverted().transform_point((x, y))
- if t >= angle - epsilon and t <= angle + epsilon:
- mode = 'drag_r_labels'
- elif button == 3:
- mode = 'zoom'
-
- self._pan_start = cbook.Bunch(
- rmax=self.get_rmax(),
- trans=self.transData.frozen(),
- trans_inverse=self.transData.inverted().frozen(),
- r_label_angle=self.get_rlabel_position(),
- x=x,
- y=y,
- mode=mode)
-
- def end_pan(self):
- del self._pan_start
-
- def drag_pan(self, button, key, x, y):
- p = self._pan_start
-
- if p.mode == 'drag_r_labels':
- startt, startr = p.trans_inverse.transform_point((p.x, p.y))
- t, r = p.trans_inverse.transform_point((x, y))
-
- # Deal with theta
- dt0 = t - startt
- dt1 = startt - t
- if abs(dt1) < abs(dt0):
- dt = abs(dt1) * np.sign(dt0) * -1.0
- else:
- dt = dt0 * -1.0
- dt = (dt / np.pi) * 180.0
- self.set_rlabel_position(p.r_label_angle - dt)
-
- trans, vert1, horiz1 = self.get_yaxis_text1_transform(0.0)
- trans, vert2, horiz2 = self.get_yaxis_text2_transform(0.0)
- for t in self.yaxis.majorTicks + self.yaxis.minorTicks:
- t.label1.set_va(vert1)
- t.label1.set_ha(horiz1)
- t.label2.set_va(vert2)
- t.label2.set_ha(horiz2)
-
- elif p.mode == 'zoom':
- startt, startr = p.trans_inverse.transform_point((p.x, p.y))
- t, r = p.trans_inverse.transform_point((x, y))
-
- # Deal with r
- scale = r / startr
- self.set_rmax(p.rmax / scale)
-
-
-# to keep things all self contained, we can put aliases to the Polar classes
-# defined above. This isn't strictly necessary, but it makes some of the
-# code more readable (and provides a backwards compatible Polar API)
-PolarAxes.PolarTransform = PolarTransform
-PolarAxes.PolarAffine = PolarAffine
-PolarAxes.InvertedPolarTransform = InvertedPolarTransform
-PolarAxes.ThetaFormatter = ThetaFormatter
-PolarAxes.RadialLocator = RadialLocator
-PolarAxes.ThetaLocator = ThetaLocator
-
-
-# These are a couple of aborted attempts to project a polar plot using
-# cubic bezier curves.
-
-# def transform_path(self, path):
-# twopi = 2.0 * np.pi
-# halfpi = 0.5 * np.pi
-
-# vertices = path.vertices
-# t0 = vertices[0:-1, 0]
-# t1 = vertices[1: , 0]
-# td = np.where(t1 > t0, t1 - t0, twopi - (t0 - t1))
-# maxtd = td.max()
-# interpolate = np.ceil(maxtd / halfpi)
-# if interpolate > 1.0:
-# vertices = self.interpolate(vertices, interpolate)
-
-# vertices = self.transform(vertices)
-
-# result = np.zeros((len(vertices) * 3 - 2, 2), float)
-# codes = mpath.Path.CURVE4 * np.ones((len(vertices) * 3 - 2, ),
-# mpath.Path.code_type)
-# result[0] = vertices[0]
-# codes[0] = mpath.Path.MOVETO
-
-# kappa = 4.0 * ((np.sqrt(2.0) - 1.0) / 3.0)
-# kappa = 0.5
-
-# p0 = vertices[0:-1]
-# p1 = vertices[1: ]
-
-# x0 = p0[:, 0:1]
-# y0 = p0[:, 1: ]
-# b0 = ((y0 - x0) - y0) / ((x0 + y0) - x0)
-# a0 = y0 - b0*x0
-
-# x1 = p1[:, 0:1]
-# y1 = p1[:, 1: ]
-# b1 = ((y1 - x1) - y1) / ((x1 + y1) - x1)
-# a1 = y1 - b1*x1
-
-# x = -(a0-a1) / (b0-b1)
-# y = a0 + b0*x
-
-# xk = (x - x0) * kappa + x0
-# yk = (y - y0) * kappa + y0
-
-# result[1::3, 0:1] = xk
-# result[1::3, 1: ] = yk
-
-# xk = (x - x1) * kappa + x1
-# yk = (y - y1) * kappa + y1
-
-# result[2::3, 0:1] = xk
-# result[2::3, 1: ] = yk
-
-# result[3::3] = p1
-
-# print(vertices[-2:])
-# print(result[-2:])
-
-# return mpath.Path(result, codes)
-
-# twopi = 2.0 * np.pi
-# halfpi = 0.5 * np.pi
-
-# vertices = path.vertices
-# t0 = vertices[0:-1, 0]
-# t1 = vertices[1: , 0]
-# td = np.where(t1 > t0, t1 - t0, twopi - (t0 - t1))
-# maxtd = td.max()
-# interpolate = np.ceil(maxtd / halfpi)
-
-# print("interpolate", interpolate)
-# if interpolate > 1.0:
-# vertices = self.interpolate(vertices, interpolate)
-
-# result = np.zeros((len(vertices) * 3 - 2, 2), float)
-# codes = mpath.Path.CURVE4 * np.ones((len(vertices) * 3 - 2, ),
-# mpath.Path.code_type)
-# result[0] = vertices[0]
-# codes[0] = mpath.Path.MOVETO
-
-# kappa = 4.0 * ((np.sqrt(2.0) - 1.0) / 3.0)
-# tkappa = np.arctan(kappa)
-# hyp_kappa = np.sqrt(kappa*kappa + 1.0)
-
-# t0 = vertices[0:-1, 0]
-# t1 = vertices[1: , 0]
-# r0 = vertices[0:-1, 1]
-# r1 = vertices[1: , 1]
-
-# td = np.where(t1 > t0, t1 - t0, twopi - (t0 - t1))
-# td_scaled = td / (np.pi * 0.5)
-# rd = r1 - r0
-# r0kappa = r0 * kappa * td_scaled
-# r1kappa = r1 * kappa * td_scaled
-# ravg_kappa = ((r1 + r0) / 2.0) * kappa * td_scaled
-
-# result[1::3, 0] = t0 + (tkappa * td_scaled)
-# result[1::3, 1] = r0*hyp_kappa
-# # result[1::3, 1] = r0 / np.cos(tkappa * td_scaled)
-# # np.sqrt(r0*r0 + ravg_kappa*ravg_kappa)
-
-# result[2::3, 0] = t1 - (tkappa * td_scaled)
-# result[2::3, 1] = r1*hyp_kappa
-# # result[2::3, 1] = r1 / np.cos(tkappa * td_scaled)
-# # np.sqrt(r1*r1 + ravg_kappa*ravg_kappa)
-
-# result[3::3, 0] = t1
-# result[3::3, 1] = r1
-
-# print(vertices[:6], result[:6], t0[:6], t1[:6], td[:6],
-# td_scaled[:6], tkappa)
-# result = self.transform(result)
-# return mpath.Path(result, codes)
-# transform_path_non_affine = transform_path
diff --git a/contrib/python/matplotlib/py2/matplotlib/pylab.py b/contrib/python/matplotlib/py2/matplotlib/pylab.py
deleted file mode 100644
index 67bb7fa1f1..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/pylab.py
+++ /dev/null
@@ -1,268 +0,0 @@
-"""
-This is a procedural interface to the matplotlib object-oriented
-plotting library.
-
-The following plotting commands are provided; the majority have
-MATLAB |reg| [*]_ analogs and similar arguments.
-
-.. |reg| unicode:: 0xAE
-
-_Plotting commands
- acorr - plot the autocorrelation function
- annotate - annotate something in the figure
- arrow - add an arrow to the axes
- axes - Create a new axes
- axhline - draw a horizontal line across axes
- axvline - draw a vertical line across axes
- axhspan - draw a horizontal bar across axes
- axvspan - draw a vertical bar across axes
- axis - Set or return the current axis limits
- autoscale - turn axis autoscaling on or off, and apply it
- bar - make a bar chart
- barh - a horizontal bar chart
- broken_barh - a set of horizontal bars with gaps
- box - set the axes frame on/off state
- boxplot - make a box and whisker plot
- violinplot - make a violin plot
- cla - clear current axes
- clabel - label a contour plot
- clf - clear a figure window
- clim - adjust the color limits of the current image
- close - close a figure window
- colorbar - add a colorbar to the current figure
- cohere - make a plot of coherence
- contour - make a contour plot
- contourf - make a filled contour plot
- csd - make a plot of cross spectral density
- delaxes - delete an axes from the current figure
- draw - Force a redraw of the current figure
- errorbar - make an errorbar graph
- figlegend - make legend on the figure rather than the axes
- figimage - make a figure image
- figtext - add text in figure coords
- figure - create or change active figure
- fill - make filled polygons
- findobj - recursively find all objects matching some criteria
- gca - return the current axes
- gcf - return the current figure
- gci - get the current image, or None
- getp - get a graphics property
- grid - set whether gridding is on
- hist - make a histogram
- ioff - turn interaction mode off
- ion - turn interaction mode on
- isinteractive - return True if interaction mode is on
- imread - load image file into array
- imsave - save array as an image file
- imshow - plot image data
- legend - make an axes legend
- locator_params - adjust parameters used in locating axis ticks
- loglog - a log log plot
- matshow - display a matrix in a new figure preserving aspect
- margins - set margins used in autoscaling
- pause - pause for a specified interval
- pcolor - make a pseudocolor plot
- pcolormesh - make a pseudocolor plot using a quadrilateral mesh
- pie - make a pie chart
- plot - make a line plot
- plot_date - plot dates
- plotfile - plot column data from an ASCII tab/space/comma delimited file
- pie - pie charts
- polar - make a polar plot on a PolarAxes
- psd - make a plot of power spectral density
- quiver - make a direction field (arrows) plot
- rc - control the default params
- rgrids - customize the radial grids and labels for polar
- savefig - save the current figure
- scatter - make a scatter plot
- setp - set a graphics property
- semilogx - log x axis
- semilogy - log y axis
- show - show the figures
- specgram - a spectrogram plot
- spy - plot sparsity pattern using markers or image
- stem - make a stem plot
- subplot - make one subplot (numrows, numcols, axesnum)
- subplots - make a figure with a set of (numrows, numcols) subplots
- subplots_adjust - change the params controlling the subplot positions of current figure
- subplot_tool - launch the subplot configuration tool
- suptitle - add a figure title
- table - add a table to the plot
- text - add some text at location x,y to the current axes
- thetagrids - customize the radial theta grids and labels for polar
- tick_params - control the appearance of ticks and tick labels
- ticklabel_format - control the format of tick labels
- title - add a title to the current axes
- tricontour - make a contour plot on a triangular grid
- tricontourf - make a filled contour plot on a triangular grid
- tripcolor - make a pseudocolor plot on a triangular grid
- triplot - plot a triangular grid
- xcorr - plot the autocorrelation function of x and y
- xlim - set/get the xlimits
- ylim - set/get the ylimits
- xticks - set/get the xticks
- yticks - set/get the yticks
- xlabel - add an xlabel to the current axes
- ylabel - add a ylabel to the current axes
-
- autumn - set the default colormap to autumn
- bone - set the default colormap to bone
- cool - set the default colormap to cool
- copper - set the default colormap to copper
- flag - set the default colormap to flag
- gray - set the default colormap to gray
- hot - set the default colormap to hot
- hsv - set the default colormap to hsv
- jet - set the default colormap to jet
- pink - set the default colormap to pink
- prism - set the default colormap to prism
- spring - set the default colormap to spring
- summer - set the default colormap to summer
- winter - set the default colormap to winter
-
-_Event handling
-
- connect - register an event handler
- disconnect - remove a connected event handler
-
-_Matrix commands
-
- cumprod - the cumulative product along a dimension
- cumsum - the cumulative sum along a dimension
- detrend - remove the mean or besdt fit line from an array
- diag - the k-th diagonal of matrix
- diff - the n-th differnce of an array
- eig - the eigenvalues and eigen vectors of v
- eye - a matrix where the k-th diagonal is ones, else zero
- find - return the indices where a condition is nonzero
- fliplr - flip the rows of a matrix up/down
- flipud - flip the columns of a matrix left/right
- linspace - a linear spaced vector of N values from min to max inclusive
- logspace - a log spaced vector of N values from min to max inclusive
- meshgrid - repeat x and y to make regular matrices
- ones - an array of ones
- rand - an array from the uniform distribution [0,1]
- randn - an array from the normal distribution
- rot90 - rotate matrix k*90 degress counterclockwise
- squeeze - squeeze an array removing any dimensions of length 1
- tri - a triangular matrix
- tril - a lower triangular matrix
- triu - an upper triangular matrix
- vander - the Vandermonde matrix of vector x
- svd - singular value decomposition
- zeros - a matrix of zeros
-
-_Probability
-
- normpdf - The Gaussian probability density function
- rand - random numbers from the uniform distribution
- randn - random numbers from the normal distribution
-
-_Statistics
-
- amax - the maximum along dimension m
- amin - the minimum along dimension m
- corrcoef - correlation coefficient
- cov - covariance matrix
- mean - the mean along dimension m
- median - the median along dimension m
- norm - the norm of vector x
- prod - the product along dimension m
- ptp - the max-min along dimension m
- std - the standard deviation along dimension m
- asum - the sum along dimension m
- ksdensity - the kernel density estimate
-
-_Time series analysis
-
- bartlett - M-point Bartlett window
- blackman - M-point Blackman window
- cohere - the coherence using average periodiogram
- csd - the cross spectral density using average periodiogram
- fft - the fast Fourier transform of vector x
- hamming - M-point Hamming window
- hanning - M-point Hanning window
- hist - compute the histogram of x
- kaiser - M length Kaiser window
- psd - the power spectral density using average periodiogram
- sinc - the sinc function of array x
-
-_Dates
-
- date2num - convert python datetimes to numeric representation
- drange - create an array of numbers for date plots
- num2date - convert numeric type (float days since 0001) to datetime
-
-_Other
-
- angle - the angle of a complex array
- griddata - interpolate irregularly distributed data to a regular grid
- load - Deprecated--please use loadtxt.
- loadtxt - load ASCII data into array.
- polyfit - fit x, y to an n-th order polynomial
- polyval - evaluate an n-th order polynomial
- roots - the roots of the polynomial coefficients in p
- save - Deprecated--please use savetxt.
- savetxt - save an array to an ASCII file.
- trapz - trapezoidal integration
-
-__end
-
-.. [*] MATLAB is a registered trademark of The MathWorks, Inc.
-
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import warnings
-
-from matplotlib.cbook import (
- flatten, exception_to_str, silent_list, iterable, dedent)
-
-import matplotlib as mpl
-
-from matplotlib.dates import (
- date2num, num2date, datestr2num, strpdate2num, drange, epoch2num,
- num2epoch, mx2num, DateFormatter, IndexDateFormatter, DateLocator,
- RRuleLocator, YearLocator, MonthLocator, WeekdayLocator, DayLocator,
- HourLocator, MinuteLocator, SecondLocator, rrule, MO, TU, WE, TH, FR,
- SA, SU, YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY,
- relativedelta)
-
-# bring all the symbols in so folks can import them from
-# pylab in one fell swoop
-
-## We are still importing too many things from mlab; more cleanup is needed.
-
-from matplotlib.mlab import (
- amap, base_repr, binary_repr, bivariate_normal, center_matrix, csv2rec,
- demean, detrend, detrend_linear, detrend_mean, detrend_none, dist,
- dist_point_to_segment, distances_along_curve, entropy, exp_safe,
- fftsurr, find, frange, get_sparse_matrix, get_xyz_where, griddata,
- identity, inside_poly, is_closed_polygon, ispower2, isvector, l1norm,
- l2norm, log2, longest_contiguous_ones, longest_ones, movavg, norm_flat,
- normpdf, path_length, poly_below, poly_between, prctile, prctile_rank,
- rec2csv, rec_append_fields, rec_drop_fields, rec_join, rk4, rms_flat,
- segments_intersect, slopes, stineman_interp, vector_lengths,
- window_hanning, window_none)
-
-from matplotlib import cbook, mlab, pyplot as plt
-from matplotlib.pyplot import *
-
-from numpy import *
-from numpy.fft import *
-from numpy.random import *
-from numpy.linalg import *
-
-import numpy as np
-import numpy.ma as ma
-
-# don't let numpy's datetime hide stdlib
-import datetime
-
-# This is needed, or bytes will be numpy.random.bytes from
-# "from numpy.random import *" above
-bytes = six.moves.builtins.bytes
diff --git a/contrib/python/matplotlib/py2/matplotlib/pyplot.py b/contrib/python/matplotlib/py2/matplotlib/pyplot.py
deleted file mode 100644
index 22411701c9..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/pyplot.py
+++ /dev/null
@@ -1,4099 +0,0 @@
-# Note: The first part of this file can be modified in place, but the latter
-# part is autogenerated by the boilerplate.py script.
-
-"""
-`matplotlib.pyplot` is a state-based interface to matplotlib. It provides
-a MATLAB-like way of plotting.
-
-pyplot is mainly intended for interactive plots and simple cases of programmatic
-plot generation::
-
- import numpy as np
- import matplotlib.pyplot as plt
-
- x = np.arange(0, 5, 0.1)
- y = np.sin(x)
- plt.plot(x, y)
-
-The object-oriented API is recommended for more complex plots.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import sys
-import time
-import warnings
-
-from cycler import cycler
-import matplotlib
-import matplotlib.colorbar
-from matplotlib import style
-from matplotlib import _pylab_helpers, interactive
-from matplotlib.cbook import dedent, silent_list, is_numlike
-from matplotlib.cbook import _string_to_bool
-from matplotlib.cbook import deprecated, warn_deprecated
-from matplotlib import docstring
-from matplotlib.backend_bases import FigureCanvasBase
-from matplotlib.figure import Figure, figaspect
-from matplotlib.gridspec import GridSpec
-from matplotlib.image import imread as _imread
-from matplotlib.image import imsave as _imsave
-from matplotlib import rcParams, rcParamsDefault, get_backend
-from matplotlib import rc_context
-from matplotlib.rcsetup import interactive_bk as _interactive_bk
-from matplotlib.artist import getp, get, Artist
-from matplotlib.artist import setp as _setp
-from matplotlib.axes import Axes, Subplot
-from matplotlib.projections import PolarAxes
-from matplotlib import mlab # for csv2rec, detrend_none, window_hanning
-from matplotlib.scale import get_scale_docs, get_scale_names
-
-from matplotlib import cm
-from matplotlib.cm import get_cmap, register_cmap
-
-import numpy as np
-
-# We may not need the following imports here:
-from matplotlib.colors import Normalize
-from matplotlib.lines import Line2D
-from matplotlib.text import Text, Annotation
-from matplotlib.patches import Polygon, Rectangle, Circle, Arrow
-from matplotlib.widgets import SubplotTool, Button, Slider, Widget
-
-from .ticker import TickHelper, Formatter, FixedFormatter, NullFormatter,\
- FuncFormatter, FormatStrFormatter, ScalarFormatter,\
- LogFormatter, LogFormatterExponent, LogFormatterMathtext,\
- Locator, IndexLocator, FixedLocator, NullLocator,\
- LinearLocator, LogLocator, AutoLocator, MultipleLocator,\
- MaxNLocator
-from matplotlib.backends import pylab_setup
-
-## Backend detection ##
-def _backend_selection():
- """ If rcParams['backend_fallback'] is true, check to see if the
- current backend is compatible with the current running event
- loop, and if not switches to a compatible one.
- """
- backend = rcParams['backend']
- if not rcParams['backend_fallback'] or backend not in _interactive_bk:
- return
- is_agg_backend = rcParams['backend'].endswith('Agg')
- if 'wx' in sys.modules and not backend in ('WX', 'WXAgg'):
- import wx
- if wx.App.IsMainLoopRunning():
- rcParams['backend'] = 'wx' + 'Agg' * is_agg_backend
- elif 'PyQt4.QtCore' in sys.modules and not backend == 'Qt4Agg':
- import PyQt4.QtGui
- if not PyQt4.QtGui.qApp.startingUp():
- # The mainloop is running.
- rcParams['backend'] = 'qt4Agg'
- elif 'PyQt5.QtCore' in sys.modules and not backend == 'Qt5Agg':
- import PyQt5.QtWidgets
- if not PyQt5.QtWidgets.qApp.startingUp():
- # The mainloop is running.
- rcParams['backend'] = 'qt5Agg'
- elif ('gtk' in sys.modules and
- backend not in ('GTK', 'GTKAgg', 'GTKCairo')):
- if 'gi' in sys.modules:
- from gi.repository import GObject
- ml = GObject.MainLoop
- else:
- import gobject
- ml = gobject.MainLoop
- if ml().is_running():
- rcParams['backend'] = 'gtk' + 'Agg' * is_agg_backend
- elif 'Tkinter' in sys.modules and not backend == 'TkAgg':
- # import Tkinter
- pass # what if anything do we need to do for tkinter?
-
-_backend_selection()
-
-## Global ##
-
-_backend_mod, new_figure_manager, draw_if_interactive, _show = pylab_setup()
-
-_IP_REGISTERED = None
-_INSTALL_FIG_OBSERVER = False
-
-
-def install_repl_displayhook():
- """
- Install a repl display hook so that any stale figure are automatically
- redrawn when control is returned to the repl.
-
- This works with IPython terminals and kernels,
- as well as vanilla python shells.
- """
- global _IP_REGISTERED
- global _INSTALL_FIG_OBSERVER
-
- class _NotIPython(Exception):
- pass
-
- # see if we have IPython hooks around, if use them
-
- try:
- if 'IPython' in sys.modules:
- from IPython import get_ipython
- ip = get_ipython()
- if ip is None:
- raise _NotIPython()
-
- if _IP_REGISTERED:
- return
-
- def post_execute():
- if matplotlib.is_interactive():
- draw_all()
-
- # IPython >= 2
- try:
- ip.events.register('post_execute', post_execute)
- except AttributeError:
- # IPython 1.x
- ip.register_post_execute(post_execute)
-
- _IP_REGISTERED = post_execute
- _INSTALL_FIG_OBSERVER = False
-
- # trigger IPython's eventloop integration, if available
- from IPython.core.pylabtools import backend2gui
-
- ipython_gui_name = backend2gui.get(get_backend())
- if ipython_gui_name:
- ip.enable_gui(ipython_gui_name)
- else:
- _INSTALL_FIG_OBSERVER = True
-
- # import failed or ipython is not running
- except (ImportError, _NotIPython):
- _INSTALL_FIG_OBSERVER = True
-
-
-def uninstall_repl_displayhook():
- """
- Uninstalls the matplotlib display hook.
-
- .. warning
-
- Need IPython >= 2 for this to work. For IPython < 2 will raise a
- ``NotImplementedError``
-
- .. warning
-
- If you are using vanilla python and have installed another
- display hook this will reset ``sys.displayhook`` to what ever
- function was there when matplotlib installed it's displayhook,
- possibly discarding your changes.
- """
- global _IP_REGISTERED
- global _INSTALL_FIG_OBSERVER
- if _IP_REGISTERED:
- from IPython import get_ipython
- ip = get_ipython()
- try:
- ip.events.unregister('post_execute', _IP_REGISTERED)
- except AttributeError:
- raise NotImplementedError("Can not unregister events "
- "in IPython < 2.0")
- _IP_REGISTERED = None
-
- if _INSTALL_FIG_OBSERVER:
- _INSTALL_FIG_OBSERVER = False
-
-
-draw_all = _pylab_helpers.Gcf.draw_all
-
-
-@docstring.copy_dedent(Artist.findobj)
-def findobj(o=None, match=None, include_self=True):
- if o is None:
- o = gcf()
- return o.findobj(match, include_self=include_self)
-
-
-def switch_backend(newbackend):
- """
- Switch the default backend. This feature is **experimental**, and
- is only expected to work switching to an image backend. e.g., if
- you have a bunch of PostScript scripts that you want to run from
- an interactive ipython session, you may want to switch to the PS
- backend before running them to avoid having a bunch of GUI windows
- popup. If you try to interactively switch from one GUI backend to
- another, you will explode.
-
- Calling this command will close all open windows.
- """
- close('all')
- global _backend_mod, new_figure_manager, draw_if_interactive, _show
- matplotlib.use(newbackend, warn=False, force=True)
- from matplotlib.backends import pylab_setup
- _backend_mod, new_figure_manager, draw_if_interactive, _show = pylab_setup()
-
-
-def show(*args, **kw):
- """
- Display a figure.
- When running in ipython with its pylab mode, display all
- figures and return to the ipython prompt.
-
- In non-interactive mode, display all figures and block until
- the figures have been closed; in interactive mode it has no
- effect unless figures were created prior to a change from
- non-interactive to interactive mode (not recommended). In
- that case it displays the figures but does not block.
-
- A single experimental keyword argument, *block*, may be
- set to True or False to override the blocking behavior
- described above.
- """
- global _show
- return _show(*args, **kw)
-
-
-def isinteractive():
- """
- Return status of interactive mode.
- """
- return matplotlib.is_interactive()
-
-
-def ioff():
- """Turn interactive mode off."""
- matplotlib.interactive(False)
- uninstall_repl_displayhook()
-
-
-def ion():
- """Turn interactive mode on."""
- matplotlib.interactive(True)
- install_repl_displayhook()
-
-
-def pause(interval):
- """
- Pause for *interval* seconds.
-
- If there is an active figure, it will be updated and displayed before the
- pause, and the GUI event loop (if any) will run during the pause.
-
- This can be used for crude animation. For more complex animation, see
- :mod:`matplotlib.animation`.
-
- Notes
- -----
- This function is experimental; its behavior may be changed or extended in a
- future release.
- """
- manager = _pylab_helpers.Gcf.get_active()
- if manager is not None:
- canvas = manager.canvas
- if canvas.figure.stale:
- canvas.draw_idle()
- show(block=False)
- canvas.start_event_loop(interval)
- else:
- time.sleep(interval)
-
-
-@docstring.copy_dedent(matplotlib.rc)
-def rc(*args, **kwargs):
- matplotlib.rc(*args, **kwargs)
-
-
-@docstring.copy_dedent(matplotlib.rc_context)
-def rc_context(rc=None, fname=None):
- return matplotlib.rc_context(rc, fname)
-
-
-@docstring.copy_dedent(matplotlib.rcdefaults)
-def rcdefaults():
- matplotlib.rcdefaults()
- if matplotlib.is_interactive():
- draw_all()
-
-
-# The current "image" (ScalarMappable) is retrieved or set
-# only via the pyplot interface using the following two
-# functions:
-def gci():
- """
- Get the current colorable artist. Specifically, returns the
- current :class:`~matplotlib.cm.ScalarMappable` instance (image or
- patch collection), or *None* if no images or patch collections
- have been defined. The commands :func:`~matplotlib.pyplot.imshow`
- and :func:`~matplotlib.pyplot.figimage` create
- :class:`~matplotlib.image.Image` instances, and the commands
- :func:`~matplotlib.pyplot.pcolor` and
- :func:`~matplotlib.pyplot.scatter` create
- :class:`~matplotlib.collections.Collection` instances. The
- current image is an attribute of the current axes, or the nearest
- earlier axes in the current figure that contains an image.
- """
- return gcf()._gci()
-
-
-def sci(im):
- """
- Set the current image. This image will be the target of colormap
- commands like :func:`~matplotlib.pyplot.jet`,
- :func:`~matplotlib.pyplot.hot` or
- :func:`~matplotlib.pyplot.clim`). The current image is an
- attribute of the current axes.
- """
- gca()._sci(im)
-
-
-## Any Artist ##
-# (getp is simply imported)
-@docstring.copy(_setp)
-def setp(*args, **kwargs):
- return _setp(*args, **kwargs)
-
-
-def xkcd(scale=1, length=100, randomness=2):
- """
- Turns on `xkcd <https://xkcd.com/>`_ sketch-style drawing mode.
- This will only have effect on things drawn after this function is
- called.
-
- For best results, the "Humor Sans" font should be installed: it is
- not included with matplotlib.
-
- Parameters
- ----------
- scale : float, optional
- The amplitude of the wiggle perpendicular to the source line.
- length : float, optional
- The length of the wiggle along the line.
- randomness : float, optional
- The scale factor by which the length is shrunken or expanded.
-
- Notes
- -----
- This function works by a number of rcParams, so it will probably
- override others you have set before.
-
- If you want the effects of this function to be temporary, it can
- be used as a context manager, for example::
-
- with plt.xkcd():
- # This figure will be in XKCD-style
- fig1 = plt.figure()
- # ...
-
- # This figure will be in regular style
- fig2 = plt.figure()
- """
- if rcParams['text.usetex']:
- raise RuntimeError(
- "xkcd mode is not compatible with text.usetex = True")
-
- from matplotlib import patheffects
- return rc_context({
- 'font.family': ['xkcd', 'Humor Sans', 'Comic Sans MS'],
- 'font.size': 14.0,
- 'path.sketch': (scale, length, randomness),
- 'path.effects': [patheffects.withStroke(linewidth=4, foreground="w")],
- 'axes.linewidth': 1.5,
- 'lines.linewidth': 2.0,
- 'figure.facecolor': 'white',
- 'grid.linewidth': 0.0,
- 'axes.grid': False,
- 'axes.unicode_minus': False,
- 'axes.edgecolor': 'black',
- 'xtick.major.size': 8,
- 'xtick.major.width': 3,
- 'ytick.major.size': 8,
- 'ytick.major.width': 3,
- })
-
-
-## Figures ##
-
-def figure(num=None, # autoincrement if None, else integer from 1-N
- figsize=None, # defaults to rc figure.figsize
- dpi=None, # defaults to rc figure.dpi
- facecolor=None, # defaults to rc figure.facecolor
- edgecolor=None, # defaults to rc figure.edgecolor
- frameon=True,
- FigureClass=Figure,
- clear=False,
- **kwargs
- ):
- """
- Creates a new figure.
-
- Parameters
- ----------
-
- num : integer or string, optional, default: none
- If not provided, a new figure will be created, and the figure number
- will be incremented. The figure objects holds this number in a `number`
- attribute.
- If num is provided, and a figure with this id already exists, make
- it active, and returns a reference to it. If this figure does not
- exists, create it and returns it.
- If num is a string, the window title will be set to this figure's
- `num`.
-
- figsize : tuple of integers, optional, default: None
- width, height in inches. If not provided, defaults to rc
- figure.figsize.
-
- dpi : integer, optional, default: None
- resolution of the figure. If not provided, defaults to rc figure.dpi.
-
- facecolor :
- the background color. If not provided, defaults to rc figure.facecolor.
-
- edgecolor :
- the border color. If not provided, defaults to rc figure.edgecolor.
-
- frameon : bool, optional, default: True
- If False, suppress drawing the figure frame.
-
- FigureClass : class derived from matplotlib.figure.Figure
- Optionally use a custom Figure instance.
-
- clear : bool, optional, default: False
- If True and the figure already exists, then it is cleared.
-
- Returns
- -------
- figure : Figure
- The Figure instance returned will also be passed to new_figure_manager
- in the backends, which allows to hook custom Figure classes into the
- pylab interface. Additional kwargs will be passed to the figure init
- function.
-
- Notes
- -----
- If you are creating many figures, make sure you explicitly call "close"
- on the figures you are not using, because this will enable pylab
- to properly clean up the memory.
-
- rcParams defines the default values, which can be modified in the
- matplotlibrc file
-
- """
-
- if figsize is None:
- figsize = rcParams['figure.figsize']
- if dpi is None:
- dpi = rcParams['figure.dpi']
- if facecolor is None:
- facecolor = rcParams['figure.facecolor']
- if edgecolor is None:
- edgecolor = rcParams['figure.edgecolor']
-
- allnums = get_fignums()
- next_num = max(allnums) + 1 if allnums else 1
- figLabel = ''
- if num is None:
- num = next_num
- elif isinstance(num, six.string_types):
- figLabel = num
- allLabels = get_figlabels()
- if figLabel not in allLabels:
- if figLabel == 'all':
- warnings.warn("close('all') closes all existing figures")
- num = next_num
- else:
- inum = allLabels.index(figLabel)
- num = allnums[inum]
- else:
- num = int(num) # crude validation of num argument
-
- figManager = _pylab_helpers.Gcf.get_fig_manager(num)
- if figManager is None:
- max_open_warning = rcParams['figure.max_open_warning']
-
- if (max_open_warning >= 1 and len(allnums) >= max_open_warning):
- warnings.warn(
- "More than %d figures have been opened. Figures "
- "created through the pyplot interface "
- "(`matplotlib.pyplot.figure`) are retained until "
- "explicitly closed and may consume too much memory. "
- "(To control this warning, see the rcParam "
- "`figure.max_open_warning`)." %
- max_open_warning, RuntimeWarning)
-
- if get_backend().lower() == 'ps':
- dpi = 72
-
- figManager = new_figure_manager(num, figsize=figsize,
- dpi=dpi,
- facecolor=facecolor,
- edgecolor=edgecolor,
- frameon=frameon,
- FigureClass=FigureClass,
- **kwargs)
-
- if figLabel:
- figManager.set_window_title(figLabel)
- figManager.canvas.figure.set_label(figLabel)
-
- # make this figure current on button press event
- def make_active(event):
- _pylab_helpers.Gcf.set_active(figManager)
-
- cid = figManager.canvas.mpl_connect('button_press_event', make_active)
- figManager._cidgcf = cid
-
- _pylab_helpers.Gcf.set_active(figManager)
- fig = figManager.canvas.figure
- fig.number = num
-
- # make sure backends (inline) that we don't ship that expect this
- # to be called in plotting commands to make the figure call show
- # still work. There is probably a better way to do this in the
- # FigureManager base class.
- if matplotlib.is_interactive():
- draw_if_interactive()
-
- if _INSTALL_FIG_OBSERVER:
- fig.stale_callback = _auto_draw_if_interactive
-
- if clear:
- figManager.canvas.figure.clear()
-
- return figManager.canvas.figure
-
-
-def _auto_draw_if_interactive(fig, val):
- """
- This is an internal helper function for making sure that auto-redrawing
- works as intended in the plain python repl.
-
- Parameters
- ----------
- fig : Figure
- A figure object which is assumed to be associated with a canvas
- """
- if val and matplotlib.is_interactive() and not fig.canvas.is_saving():
- fig.canvas.draw_idle()
-
-
-def gcf():
- """Get a reference to the current figure."""
- figManager = _pylab_helpers.Gcf.get_active()
- if figManager is not None:
- return figManager.canvas.figure
- else:
- return figure()
-
-
-def fignum_exists(num):
- return _pylab_helpers.Gcf.has_fignum(num) or num in get_figlabels()
-
-
-def get_fignums():
- """Return a list of existing figure numbers."""
- return sorted(_pylab_helpers.Gcf.figs)
-
-
-def get_figlabels():
- """Return a list of existing figure labels."""
- figManagers = _pylab_helpers.Gcf.get_all_fig_managers()
- figManagers.sort(key=lambda m: m.num)
- return [m.canvas.figure.get_label() for m in figManagers]
-
-
-def get_current_fig_manager():
- figManager = _pylab_helpers.Gcf.get_active()
- if figManager is None:
- gcf() # creates an active figure as a side effect
- figManager = _pylab_helpers.Gcf.get_active()
- return figManager
-
-
-@docstring.copy_dedent(FigureCanvasBase.mpl_connect)
-def connect(s, func):
- return get_current_fig_manager().canvas.mpl_connect(s, func)
-
-
-@docstring.copy_dedent(FigureCanvasBase.mpl_disconnect)
-def disconnect(cid):
- return get_current_fig_manager().canvas.mpl_disconnect(cid)
-
-
-def close(*args):
- """
- Close a figure window.
-
- ``close()`` by itself closes the current figure
-
- ``close(fig)`` closes the `.Figure` instance *fig*
-
- ``close(num)`` closes the figure number *num*
-
- ``close(name)`` where *name* is a string, closes figure with that label
-
- ``close('all')`` closes all the figure windows
- """
-
- if len(args) == 0:
- figManager = _pylab_helpers.Gcf.get_active()
- if figManager is None:
- return
- else:
- _pylab_helpers.Gcf.destroy(figManager.num)
- elif len(args) == 1:
- arg = args[0]
- if arg == 'all':
- _pylab_helpers.Gcf.destroy_all()
- elif isinstance(arg, six.integer_types):
- _pylab_helpers.Gcf.destroy(arg)
- elif hasattr(arg, 'int'):
- # if we are dealing with a type UUID, we
- # can use its integer representation
- _pylab_helpers.Gcf.destroy(arg.int)
- elif isinstance(arg, six.string_types):
- allLabels = get_figlabels()
- if arg in allLabels:
- num = get_fignums()[allLabels.index(arg)]
- _pylab_helpers.Gcf.destroy(num)
- elif isinstance(arg, Figure):
- _pylab_helpers.Gcf.destroy_fig(arg)
- else:
- raise TypeError('Unrecognized argument type %s to close' % type(arg))
- else:
- raise TypeError('close takes 0 or 1 arguments')
-
-
-def clf():
- """
- Clear the current figure.
- """
- gcf().clf()
-
-
-def draw():
- """Redraw the current figure.
-
- This is used to update a figure that has been altered, but not
- automatically re-drawn. If interactive mode is on (:func:`.ion()`), this
- should be only rarely needed, but there may be ways to modify the state of
- a figure without marking it as `stale`. Please report these cases as
- bugs.
-
- A more object-oriented alternative, given any
- :class:`~matplotlib.figure.Figure` instance, :attr:`fig`, that
- was created using a :mod:`~matplotlib.pyplot` function, is::
-
- fig.canvas.draw_idle()
- """
- get_current_fig_manager().canvas.draw_idle()
-
-
-@docstring.copy_dedent(Figure.savefig)
-def savefig(*args, **kwargs):
- fig = gcf()
- res = fig.savefig(*args, **kwargs)
- fig.canvas.draw_idle() # need this if 'transparent=True' to reset colors
- return res
-
-
-@docstring.copy_dedent(Figure.ginput)
-def ginput(*args, **kwargs):
- """
- Blocking call to interact with the figure.
-
- This will wait for *n* clicks from the user and return a list of the
- coordinates of each click.
-
- If *timeout* is negative, does not timeout.
- """
- return gcf().ginput(*args, **kwargs)
-
-
-@docstring.copy_dedent(Figure.waitforbuttonpress)
-def waitforbuttonpress(*args, **kwargs):
- """
- Blocking call to interact with the figure.
-
- This will wait for *n* key or mouse clicks from the user and
- return a list containing True's for keyboard clicks and False's
- for mouse clicks.
-
- If *timeout* is negative, does not timeout.
- """
- return gcf().waitforbuttonpress(*args, **kwargs)
-
-
-# Putting things in figures
-
-@docstring.copy_dedent(Figure.text)
-def figtext(*args, **kwargs):
- return gcf().text(*args, **kwargs)
-
-
-@docstring.copy_dedent(Figure.suptitle)
-def suptitle(*args, **kwargs):
- return gcf().suptitle(*args, **kwargs)
-
-
-@docstring.copy_dedent(Figure.figimage)
-def figimage(*args, **kwargs):
- return gcf().figimage(*args, **kwargs)
-
-
-def figlegend(*args, **kwargs):
- """
- Place a legend in the figure.
-
- *labels*
- a sequence of strings
-
- *handles*
- a sequence of :class:`~matplotlib.lines.Line2D` or
- :class:`~matplotlib.patches.Patch` instances
-
- *loc*
- can be a string or an integer specifying the legend
- location
-
- A :class:`matplotlib.legend.Legend` instance is returned.
-
- Examples
- --------
-
- To make a legend from existing artists on every axes::
-
- figlegend()
-
- To make a legend for a list of lines and labels::
-
- figlegend( (line1, line2, line3),
- ('label1', 'label2', 'label3'),
- 'upper right' )
-
- .. seealso::
-
- :func:`~matplotlib.pyplot.legend`
-
- """
- return gcf().legend(*args, **kwargs)
-
-
-## Figure and Axes hybrid ##
-
-_hold_msg = """pyplot.hold is deprecated.
- Future behavior will be consistent with the long-time default:
- plot commands add elements without first clearing the
- Axes and/or Figure."""
-
-@deprecated("2.0", message=_hold_msg)
-def hold(b=None):
- """
- Set the hold state. If *b* is None (default), toggle the
- hold state, else set the hold state to boolean value *b*::
-
- hold() # toggle hold
- hold(True) # hold is on
- hold(False) # hold is off
-
- When *hold* is *True*, subsequent plot commands will add elements to
- the current axes. When *hold* is *False*, the current axes and
- figure will be cleared on the next plot command.
-
- """
-
- fig = gcf()
- ax = fig.gca()
-
- if b is not None:
- b = bool(b)
- fig._hold = b
- ax._hold = b
-
- # b=None toggles the hold state, so let's get get the current hold
- # state; but should pyplot hold toggle the rc setting - me thinks
- # not
- b = ax._hold
-
- # The comment above looks ancient; and probably the line below,
- # contrary to the comment, is equally ancient. It will trigger
- # a second warning, but "Oh, well...".
- rc('axes', hold=b)
-
-@deprecated("2.0", message=_hold_msg)
-def ishold():
- """
- Return the hold status of the current axes.
- """
- return gca()._hold
-
-
-@deprecated("2.0", message=_hold_msg)
-def over(func, *args, **kwargs):
- """
- Call a function with hold(True).
-
- Calls::
-
- func(*args, **kwargs)
-
- with ``hold(True)`` and then restores the hold state.
-
- """
- ax = gca()
- h = ax._hold
- ax._hold = True
- func(*args, **kwargs)
- ax._hold = h
-
-## Axes ##
-
-
-def axes(arg=None, **kwargs):
- """
- Add an axes to the current figure and make it the current axes.
-
- Parameters
- ----------
- arg : None or 4-tuple or Axes
- The exact behavior of this function depends on the type:
-
- - *None*: A new full window axes is added using
- ``subplot(111, **kwargs)``
- - 4-tuple of floats *rect* = ``[left, bottom, width, height]``.
- A new axes is added with dimensions *rect* in normalized
- (0, 1) units using `~.Figure.add_axes` on the current figure.
- - `~matplotlib.axes.Axes`: This is equivalent to `.pyplot.sca`.
- It sets the current axes to *arg*. Note: This implicitly
- changes the current figure to the parent of *arg*.
-
- .. note:: The use of an Axes as an argument is deprecated and will be
- removed in v3.0. Please use `.pyplot.sca` instead.
-
- Other Parameters
- ----------------
- **kwargs :
- For allowed keyword arguments see `.pyplot.subplot` and
- `.Figure.add_axes` respectively. Some common keyword arguments are
- listed below:
-
- ========= =========== =================================================
- kwarg Accepts Description
- ========= =========== =================================================
- facecolor color the axes background color
- frameon bool whether to display the frame
- sharex otherax share x-axis with *otherax*
- sharey otherax share y-axis with *otherax*
- polar bool whether to use polar axes
- aspect [str | num] ['equal', 'auto'] or a number. If a number, the
- ratio of y-unit/x-unit in screen-space. See also
- `~.Axes.set_aspect`.
- ========= =========== =================================================
-
- Returns
- -------
- axes : Axes
- The created or activated axes.
-
- Examples
- --------
- Creating a new full window axes::
-
- >>> plt.axes()
-
- Creating a new axes with specified dimensions and some kwargs::
-
- >>> plt.axes((left, bottom, width, height), facecolor='w')
-
- """
-
- if arg is None:
- return subplot(111, **kwargs)
-
- if isinstance(arg, Axes):
- warn_deprecated("2.2",
- message="Using pyplot.axes(ax) with ax an Axes "
- "argument is deprecated. Please use "
- "pyplot.sca(ax) instead.")
- ax = arg
- sca(ax)
- return ax
- else:
- rect = arg
- return gcf().add_axes(rect, **kwargs)
-
-
-def delaxes(ax=None):
- """
- Remove the given `Axes` *ax* from the current figure. If *ax* is *None*,
- the current axes is removed. A KeyError is raised if the axes doesn't exist.
- """
- if ax is None:
- ax = gca()
- gcf().delaxes(ax)
-
-
-def sca(ax):
- """
- Set the current Axes instance to *ax*.
-
- The current Figure is updated to the parent of *ax*.
- """
- managers = _pylab_helpers.Gcf.get_all_fig_managers()
- for m in managers:
- if ax in m.canvas.figure.axes:
- _pylab_helpers.Gcf.set_active(m)
- m.canvas.figure.sca(ax)
- return
- raise ValueError("Axes instance argument was not found in a figure.")
-
-
-def gca(**kwargs):
- """
- Get the current :class:`~matplotlib.axes.Axes` instance on the
- current figure matching the given keyword args, or create one.
-
- Examples
- --------
- To get the current polar axes on the current figure::
-
- plt.gca(projection='polar')
-
- If the current axes doesn't exist, or isn't a polar one, the appropriate
- axes will be created and then returned.
-
- See Also
- --------
- matplotlib.figure.Figure.gca : The figure's gca method.
- """
- return gcf().gca(**kwargs)
-
-# More ways of creating axes:
-
-
-def subplot(*args, **kwargs):
- """
- Return a subplot axes at the given grid position.
-
- Call signature::
-
- subplot(nrows, ncols, index, **kwargs)
-
- In the current figure, create and return an `~matplotlib.axes.Axes`,
- at position *index* of a (virtual) grid of *nrows* by *ncols* axes.
- Indexes go from 1 to ``nrows * ncols``, incrementing in row-major order.
-
- If *nrows*, *ncols* and *index* are all less than 10, they can also be
- given as a single, concatenated, three-digit number.
-
- For example, ``subplot(2, 3, 3)`` and ``subplot(233)`` both create an
- `matplotlib.axes.Axes` at the top right corner of the current figure,
- occupying half of the figure height and a third of the figure width.
-
- .. note::
-
- Creating a subplot will delete any pre-existing subplot that overlaps
- with it beyond sharing a boundary::
-
- import matplotlib.pyplot as plt
- # plot a line, implicitly creating a subplot(111)
- plt.plot([1,2,3])
- # now create a subplot which represents the top plot of a grid
- # with 2 rows and 1 column. Since this subplot will overlap the
- # first, the plot (and its axes) previously created, will be removed
- plt.subplot(211)
- plt.plot(range(12))
- plt.subplot(212, facecolor='y') # creates 2nd subplot with yellow background
-
- If you do not want this behavior, use the
- :meth:`~matplotlib.figure.Figure.add_subplot` method or the
- :func:`~matplotlib.pyplot.axes` function instead.
-
- Keyword arguments:
-
- *facecolor*:
- The background color of the subplot, which can be any valid
- color specifier. See :mod:`matplotlib.colors` for more
- information.
-
- *polar*:
- A boolean flag indicating whether the subplot plot should be
- a polar projection. Defaults to *False*.
-
- *projection*:
- A string giving the name of a custom projection to be used
- for the subplot. This projection must have been previously
- registered. See :mod:`matplotlib.projections`.
-
- .. seealso::
-
- :func:`~matplotlib.pyplot.axes`
- For additional information on :func:`axes` and
- :func:`subplot` keyword arguments.
-
- :file:`gallery/pie_and_polar_charts/polar_scatter.py`
- For an example
-
- **Example:**
-
- .. plot:: gallery/subplots_axes_and_figures/subplot.py
-
- """
- # if subplot called without arguments, create subplot(1,1,1)
- if len(args)==0:
- args=(1,1,1)
-
- # This check was added because it is very easy to type
- # subplot(1, 2, False) when subplots(1, 2, False) was intended
- # (sharex=False, that is). In most cases, no error will
- # ever occur, but mysterious behavior can result because what was
- # intended to be the sharex argument is instead treated as a
- # subplot index for subplot()
- if len(args) >= 3 and isinstance(args[2], bool) :
- warnings.warn("The subplot index argument to subplot() appears"
- " to be a boolean. Did you intend to use subplots()?")
-
- fig = gcf()
- a = fig.add_subplot(*args, **kwargs)
- bbox = a.bbox
- byebye = []
- for other in fig.axes:
- if other==a: continue
- if bbox.fully_overlaps(other.bbox):
- byebye.append(other)
- for ax in byebye: delaxes(ax)
-
- return a
-
-
-def subplots(nrows=1, ncols=1, sharex=False, sharey=False, squeeze=True,
- subplot_kw=None, gridspec_kw=None, **fig_kw):
- """
- Create a figure and a set of subplots
-
- This utility wrapper makes it convenient to create common layouts of
- subplots, including the enclosing figure object, in a single call.
-
- Parameters
- ----------
- nrows, ncols : int, optional, default: 1
- Number of rows/columns of the subplot grid.
-
- sharex, sharey : bool or {'none', 'all', 'row', 'col'}, default: False
- Controls sharing of properties among x (`sharex`) or y (`sharey`)
- axes:
-
- - True or 'all': x- or y-axis will be shared among all
- subplots.
- - False or 'none': each subplot x- or y-axis will be
- independent.
- - 'row': each subplot row will share an x- or y-axis.
- - 'col': each subplot column will share an x- or y-axis.
-
- When subplots have a shared x-axis along a column, only the x tick
- labels of the bottom subplot are created. Similarly, when subplots
- have a shared y-axis along a row, only the y tick labels of the first
- column subplot are created. To later turn other subplots' ticklabels
- on, use :meth:`~matplotlib.axes.Axes.tick_params`.
-
- squeeze : bool, optional, default: True
- - If True, extra dimensions are squeezed out from the returned
- array of Axes:
-
- - if only one subplot is constructed (nrows=ncols=1), the
- resulting single Axes object is returned as a scalar.
- - for Nx1 or 1xM subplots, the returned object is a 1D numpy
- object array of Axes objects.
- - for NxM, subplots with N>1 and M>1 are returned as a 2D array.
-
- - If False, no squeezing at all is done: the returned Axes object is
- always a 2D array containing Axes instances, even if it ends up
- being 1x1.
-
- subplot_kw : dict, optional
- Dict with keywords passed to the
- :meth:`~matplotlib.figure.Figure.add_subplot` call used to create each
- subplot.
-
- gridspec_kw : dict, optional
- Dict with keywords passed to the
- :class:`~matplotlib.gridspec.GridSpec` constructor used to create the
- grid the subplots are placed on.
-
- **fig_kw :
- All additional keyword arguments are passed to the :func:`figure` call.
-
- Returns
- -------
- fig : :class:`matplotlib.figure.Figure` object
-
- ax : Axes object or array of Axes objects.
-
- ax can be either a single :class:`matplotlib.axes.Axes` object or an
- array of Axes objects if more than one subplot was created. The
- dimensions of the resulting array can be controlled with the squeeze
- keyword, see above.
-
- Examples
- --------
- First create some toy data:
-
- >>> x = np.linspace(0, 2*np.pi, 400)
- >>> y = np.sin(x**2)
-
- Creates just a figure and only one subplot
-
- >>> fig, ax = plt.subplots()
- >>> ax.plot(x, y)
- >>> ax.set_title('Simple plot')
-
- Creates two subplots and unpacks the output array immediately
-
- >>> f, (ax1, ax2) = plt.subplots(1, 2, sharey=True)
- >>> ax1.plot(x, y)
- >>> ax1.set_title('Sharing Y axis')
- >>> ax2.scatter(x, y)
-
- Creates four polar axes, and accesses them through the returned array
-
- >>> fig, axes = plt.subplots(2, 2, subplot_kw=dict(polar=True))
- >>> axes[0, 0].plot(x, y)
- >>> axes[1, 1].scatter(x, y)
-
- Share a X axis with each column of subplots
-
- >>> plt.subplots(2, 2, sharex='col')
-
- Share a Y axis with each row of subplots
-
- >>> plt.subplots(2, 2, sharey='row')
-
- Share both X and Y axes with all subplots
-
- >>> plt.subplots(2, 2, sharex='all', sharey='all')
-
- Note that this is the same as
-
- >>> plt.subplots(2, 2, sharex=True, sharey=True)
-
- See Also
- --------
- figure
- subplot
- """
- fig = figure(**fig_kw)
- axs = fig.subplots(nrows=nrows, ncols=ncols, sharex=sharex, sharey=sharey,
- squeeze=squeeze, subplot_kw=subplot_kw,
- gridspec_kw=gridspec_kw)
- return fig, axs
-
-
-def subplot2grid(shape, loc, rowspan=1, colspan=1, fig=None, **kwargs):
- """
- Create an axis at specific location inside a regular grid.
-
- Parameters
- ----------
- shape : sequence of 2 ints
- Shape of grid in which to place axis.
- First entry is number of rows, second entry is number of columns.
-
- loc : sequence of 2 ints
- Location to place axis within grid.
- First entry is row number, second entry is column number.
-
- rowspan : int
- Number of rows for the axis to span to the right.
-
- colspan : int
- Number of columns for the axis to span downwards.
-
- fig : `Figure`, optional
- Figure to place axis in. Defaults to current figure.
-
- **kwargs
- Additional keyword arguments are handed to `add_subplot`.
-
-
- Notes
- -----
- The following call ::
-
- subplot2grid(shape, loc, rowspan=1, colspan=1)
-
- is identical to ::
-
- gridspec=GridSpec(shape[0], shape[1])
- subplotspec=gridspec.new_subplotspec(loc, rowspan, colspan)
- subplot(subplotspec)
- """
-
- if fig is None:
- fig = gcf()
-
- s1, s2 = shape
- subplotspec = GridSpec(s1, s2).new_subplotspec(loc,
- rowspan=rowspan,
- colspan=colspan)
- a = fig.add_subplot(subplotspec, **kwargs)
- bbox = a.bbox
- byebye = []
- for other in fig.axes:
- if other == a:
- continue
- if bbox.fully_overlaps(other.bbox):
- byebye.append(other)
- for ax in byebye:
- delaxes(ax)
-
- return a
-
-
-def twinx(ax=None):
- """
- Make a second axes that shares the *x*-axis. The new axes will
- overlay *ax* (or the current axes if *ax* is *None*). The ticks
- for *ax2* will be placed on the right, and the *ax2* instance is
- returned.
-
- .. seealso::
-
- :file:`examples/api_examples/two_scales.py`
- For an example
- """
- if ax is None:
- ax=gca()
- ax1 = ax.twinx()
- return ax1
-
-
-def twiny(ax=None):
- """
- Make a second axes that shares the *y*-axis. The new axis will
- overlay *ax* (or the current axes if *ax* is *None*). The ticks
- for *ax2* will be placed on the top, and the *ax2* instance is
- returned.
- """
- if ax is None:
- ax=gca()
- ax1 = ax.twiny()
- return ax1
-
-
-def subplots_adjust(*args, **kwargs):
- """
- Tune the subplot layout.
-
- call signature::
-
- subplots_adjust(left=None, bottom=None, right=None, top=None,
- wspace=None, hspace=None)
-
- The parameter meanings (and suggested defaults) are::
-
- left = 0.125 # the left side of the subplots of the figure
- right = 0.9 # the right side of the subplots of the figure
- bottom = 0.1 # the bottom of the subplots of the figure
- top = 0.9 # the top of the subplots of the figure
- wspace = 0.2 # the amount of width reserved for space between subplots,
- # expressed as a fraction of the average axis width
- hspace = 0.2 # the amount of height reserved for space between subplots,
- # expressed as a fraction of the average axis height
-
- The actual defaults are controlled by the rc file
- """
- fig = gcf()
- fig.subplots_adjust(*args, **kwargs)
-
-
-def subplot_tool(targetfig=None):
- """
- Launch a subplot tool window for a figure.
-
- A :class:`matplotlib.widgets.SubplotTool` instance is returned.
- """
- tbar = rcParams['toolbar'] # turn off the navigation toolbar for the toolfig
- rcParams['toolbar'] = 'None'
- if targetfig is None:
- manager = get_current_fig_manager()
- targetfig = manager.canvas.figure
- else:
- # find the manager for this figure
- for manager in _pylab_helpers.Gcf._activeQue:
- if manager.canvas.figure==targetfig: break
- else: raise RuntimeError('Could not find manager for targetfig')
-
- toolfig = figure(figsize=(6,3))
- toolfig.subplots_adjust(top=0.9)
- ret = SubplotTool(targetfig, toolfig)
- rcParams['toolbar'] = tbar
- _pylab_helpers.Gcf.set_active(manager) # restore the current figure
- return ret
-
-
-def tight_layout(pad=1.08, h_pad=None, w_pad=None, rect=None):
- """
- Automatically adjust subplot parameters to give specified padding.
-
- Parameters
- ----------
- pad : float
- padding between the figure edge and the edges of subplots, as a fraction of the font-size.
- h_pad, w_pad : float
- padding (height/width) between edges of adjacent subplots.
- Defaults to `pad_inches`.
- rect : if rect is given, it is interpreted as a rectangle
- (left, bottom, right, top) in the normalized figure
- coordinate that the whole subplots area (including
- labels) will fit into. Default is (0, 0, 1, 1).
-
- """
- fig = gcf()
- fig.tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
-
-
-def box(on=None):
- """
- Turn the axes box on or off on the current axes.
-
- Parameters
- ----------
- on : bool or None
- The new `~matplotlib.axes.Axes` box state. If ``None``, toggle
- the state.
-
- See Also
- --------
- :meth:`matplotlib.axes.Axes.set_frame_on`
- :meth:`matplotlib.axes.Axes.get_frame_on`
- """
- ax = gca()
- if on is None:
- on = not ax.get_frame_on()
- on = _string_to_bool(on)
- ax.set_frame_on(on)
-
-
-def title(s, *args, **kwargs):
- """
- Set a title of the current axes.
-
- Set one of the three available axes titles. The available titles are
- positioned above the axes in the center, flush with the left edge,
- and flush with the right edge.
-
- .. seealso::
- See :func:`~matplotlib.pyplot.text` for adding text
- to the current axes
-
- Parameters
- ----------
- label : str
- Text to use for the title
-
- fontdict : dict
- A dictionary controlling the appearance of the title text,
- the default `fontdict` is:
-
- {'fontsize': rcParams['axes.titlesize'],
- 'fontweight' : rcParams['axes.titleweight'],
- 'verticalalignment': 'baseline',
- 'horizontalalignment': loc}
-
- loc : {'center', 'left', 'right'}, str, optional
- Which title to set, defaults to 'center'
-
- Returns
- -------
- text : :class:`~matplotlib.text.Text`
- The matplotlib text instance representing the title
-
- Other parameters
- ----------------
- kwargs : text properties
- Other keyword arguments are text properties, see
- :class:`~matplotlib.text.Text` for a list of valid text
- properties.
-
- """
- return gca().set_title(s, *args, **kwargs)
-
-## Axis ##
-
-
-def axis(*v, **kwargs):
- """
- Convenience method to get or set axis properties.
-
- Calling with no arguments::
-
- >>> axis()
-
- returns the current axes limits ``[xmin, xmax, ymin, ymax]``.::
-
- >>> axis(v)
-
- sets the min and max of the x and y axes, with
- ``v = [xmin, xmax, ymin, ymax]``.::
-
- >>> axis('off')
-
- turns off the axis lines and labels.::
-
- >>> axis('equal')
-
- changes limits of *x* or *y* axis so that equal increments of *x*
- and *y* have the same length; a circle is circular.::
-
- >>> axis('scaled')
-
- achieves the same result by changing the dimensions of the plot box instead
- of the axis data limits.::
-
- >>> axis('tight')
-
- changes *x* and *y* axis limits such that all data is shown. If
- all data is already shown, it will move it to the center of the
- figure without modifying (*xmax* - *xmin*) or (*ymax* -
- *ymin*). Note this is slightly different than in MATLAB.::
-
- >>> axis('image')
-
- is 'scaled' with the axis limits equal to the data limits.::
-
- >>> axis('auto')
-
- and::
-
- >>> axis('normal')
-
- are deprecated. They restore default behavior; axis limits are automatically
- scaled to make the data fit comfortably within the plot box.
-
- if ``len(*v)==0``, you can pass in *xmin*, *xmax*, *ymin*, *ymax*
- as kwargs selectively to alter just those limits without changing
- the others.
-
- >>> axis('square')
-
- changes the limit ranges (*xmax*-*xmin*) and (*ymax*-*ymin*) of
- the *x* and *y* axes to be the same, and have the same scaling,
- resulting in a square plot.
-
- The xmin, xmax, ymin, ymax tuple is returned
-
- .. seealso::
-
- :func:`xlim`, :func:`ylim`
- For setting the x- and y-limits individually.
- """
- return gca().axis(*v, **kwargs)
-
-
-def xlabel(s, *args, **kwargs):
- """
- Set the x-axis label of the current axes.
-
- Call signature::
-
- xlabel(label, fontdict=None, labelpad=None, **kwargs)
-
- This is the pyplot equivalent of calling `.set_xlabel` on the current axes.
- See there for a full parameter description.
- """
- return gca().set_xlabel(s, *args, **kwargs)
-
-
-def ylabel(s, *args, **kwargs):
- """
- Set the y-axis label of the current axes.
-
- Call signature::
-
- ylabel(label, fontdict=None, labelpad=None, **kwargs)
-
- This is the pyplot equivalent of calling `.set_ylabel` on the current axes.
- See there for a full parameter description.
- """
- return gca().set_ylabel(s, *args, **kwargs)
-
-
-def xlim(*args, **kwargs):
- """
- Get or set the x limits of the current axes.
-
- Call signatures::
-
- xmin, xmax = xlim() # return the current xlim
- xlim((xmin, xmax)) # set the xlim to xmin, xmax
- xlim(xmin, xmax) # set the xlim to xmin, xmax
-
- If you do not specify args, you can pass *xmin* or *xmax* as kwargs, i.e.::
-
- xlim(xmax=3) # adjust the max leaving min unchanged
- xlim(xmin=1) # adjust the min leaving max unchanged
-
- Setting limits turns autoscaling off for the x-axis.
-
- Returns
- -------
- xmin, xmax
- A tuple of the new x-axis limits.
-
- Notes
- -----
- Calling this function with no arguments (e.g. ``xlim()``) is the pyplot
- equivalent of calling `~.Axes.get_xlim` on the current axes.
- Calling this function with arguments is the pyplot equivalent of calling
- `~.Axes.set_xlim` on the current axes. All arguments are passed though.
- """
- ax = gca()
- if not args and not kwargs:
- return ax.get_xlim()
- ret = ax.set_xlim(*args, **kwargs)
- return ret
-
-
-def ylim(*args, **kwargs):
- """
- Get or set the y-limits of the current axes.
-
- Call signatures::
-
- ymin, ymax = ylim() # return the current ylim
- ylim((ymin, ymax)) # set the ylim to ymin, ymax
- ylim(ymin, ymax) # set the ylim to ymin, ymax
-
- If you do not specify args, you can alternatively pass *ymin* or *ymax* as
- kwargs, i.e.::
-
- ylim(ymax=3) # adjust the max leaving min unchanged
- ylim(ymin=1) # adjust the min leaving max unchanged
-
- Setting limits turns autoscaling off for the y-axis.
-
- Returns
- -------
- ymin, ymax
- A tuple of the new y-axis limits.
-
- Notes
- -----
- Calling this function with no arguments (e.g. ``ylim()``) is the pyplot
- equivalent of calling `~.Axes.get_ylim` on the current axes.
- Calling this function with arguments is the pyplot equivalent of calling
- `~.Axes.set_ylim` on the current axes. All arguments are passed though.
- """
- ax = gca()
- if not args and not kwargs:
- return ax.get_ylim()
- ret = ax.set_ylim(*args, **kwargs)
- return ret
-
-
-@docstring.dedent_interpd
-def xscale(*args, **kwargs):
- """
- Set the scaling of the x-axis.
-
- Call signature::
-
- xscale(scale, **kwargs)
-
- Parameters
- ----------
- scale : [%(scale)s]
- The scaling type.
- **kwargs
- Additional parameters depend on *scale*. See Notes.
-
- Notes
- -----
- This is the pyplot equivalent of calling `~.Axes.set_xscale` on the
- current axes.
-
- Different keywords may be accepted, depending on the scale:
-
- %(scale_docs)s
- """
- gca().set_xscale(*args, **kwargs)
-
-
-@docstring.dedent_interpd
-def yscale(*args, **kwargs):
- """
- Set the scaling of the y-axis.
-
- Call signature::
-
- yscale(scale, **kwargs)
-
- Parameters
- ----------
- scale : [%(scale)s]
- The scaling type.
- **kwargs
- Additional parameters depend on *scale*. See Notes.
-
- Notes
- -----
- This is the pyplot equivalent of calling `~.Axes.set_yscale` on the
- current axes.
-
- Different keywords may be accepted, depending on the scale:
-
- %(scale_docs)s
- """
- gca().set_yscale(*args, **kwargs)
-
-
-def xticks(*args, **kwargs):
- """
- Get or set the current tick locations and labels of the x-axis.
-
- Call signatures::
-
- locs, labels = xticks() # Get locations and labels
-
- xticks(locs, [labels], **kwargs) # Set locations and labels
-
- Parameters
- ----------
- locs : array_like
- A list of positions at which ticks should be placed. You can pass an
- empty list to disable xticks.
-
- labels : array_like, optional
- A list of explicit labels to place at the given *locs*.
-
- **kwargs
- :class:`.Text` properties can be used to control the appearance of
- the labels.
-
- Returns
- -------
- locs
- An array of label locations.
- labels
- A list of `.Text` objects.
-
- Notes
- -----
- Calling this function with no arguments (e.g. ``xticks()``) is the pyplot
- equivalent of calling `~.Axes.get_xticks` and `~.Axes.get_xticklabels` on
- the current axes.
- Calling this function with arguments is the pyplot equivalent of calling
- `~.Axes.set_xticks` and `~.Axes.set_xticklabels` on the current axes.
-
- Examples
- --------
- Get the current locations and labels:
-
- >>> locs, labels = xticks()
-
- Set label locations:
-
- >>> xticks(np.arange(0, 1, step=0.2))
-
- Set text labels:
-
- >>> xticks(np.arange(5), ('Tom', 'Dick', 'Harry', 'Sally', 'Sue'))
-
- Set text labels and properties:
-
- >>> xticks(np.arange(12), calendar.month_name[1:13], rotation=20)
-
- Disable xticks:
-
- >>> xticks([])
- """
- ax = gca()
-
- if len(args)==0:
- locs = ax.get_xticks()
- labels = ax.get_xticklabels()
- elif len(args)==1:
- locs = ax.set_xticks(args[0])
- labels = ax.get_xticklabels()
- elif len(args)==2:
- locs = ax.set_xticks(args[0])
- labels = ax.set_xticklabels(args[1], **kwargs)
- else: raise TypeError('Illegal number of arguments to xticks')
- if len(kwargs):
- for l in labels:
- l.update(kwargs)
-
- return locs, silent_list('Text xticklabel', labels)
-
-
-def yticks(*args, **kwargs):
- """
- Get or set the current tick locations and labels of the y-axis.
-
- Call signatures::
-
- locs, labels = yticks() # Get locations and labels
-
- yticks(locs, [labels], **kwargs) # Set locations and labels
-
- Parameters
- ----------
- locs : array_like
- A list of positions at which ticks should be placed. You can pass an
- empty list to disable yticks.
-
- labels : array_like, optional
- A list of explicit labels to place at the given *locs*.
-
- **kwargs
- :class:`.Text` properties can be used to control the appearance of
- the labels.
-
- Returns
- -------
- locs
- An array of label locations.
- labels
- A list of `.Text` objects.
-
- Notes
- -----
- Calling this function with no arguments (e.g. ``yticks()``) is the pyplot
- equivalent of calling `~.Axes.get_yticks` and `~.Axes.get_yticklabels` on
- the current axes.
- Calling this function with arguments is the pyplot equivalent of calling
- `~.Axes.set_yticks` and `~.Axes.set_yticklabels` on the current axes.
-
- Examples
- --------
- Get the current locations and labels:
-
- >>> locs, labels = yticks()
-
- Set label locations:
-
- >>> yticks(np.arange(0, 1, step=0.2))
-
- Set text labels:
-
- >>> yticks(np.arange(5), ('Tom', 'Dick', 'Harry', 'Sally', 'Sue'))
-
- Set text labels and properties:
-
- >>> yticks(np.arange(12), calendar.month_name[1:13], rotation=45)
-
- Disable yticks:
-
- >>> yticks([])
- """
- ax = gca()
-
- if len(args)==0:
- locs = ax.get_yticks()
- labels = ax.get_yticklabels()
- elif len(args)==1:
- locs = ax.set_yticks(args[0])
- labels = ax.get_yticklabels()
- elif len(args)==2:
- locs = ax.set_yticks(args[0])
- labels = ax.set_yticklabels(args[1], **kwargs)
- else: raise TypeError('Illegal number of arguments to yticks')
- if len(kwargs):
- for l in labels:
- l.update(kwargs)
-
-
- return ( locs,
- silent_list('Text yticklabel', labels)
- )
-
-
-def minorticks_on():
- """
- Display minor ticks on the current plot.
-
- Displaying minor ticks reduces performance; turn them off using
- minorticks_off() if drawing speed is a problem.
- """
- gca().minorticks_on()
-
-
-def minorticks_off():
- """
- Remove minor ticks from the current plot.
- """
- gca().minorticks_off()
-
-
-def rgrids(*args, **kwargs):
- """
- Get or set the radial gridlines on a polar plot.
-
- call signatures::
-
- lines, labels = rgrids()
- lines, labels = rgrids(radii, labels=None, angle=22.5, **kwargs)
-
- When called with no arguments, :func:`rgrid` simply returns the
- tuple (*lines*, *labels*), where *lines* is an array of radial
- gridlines (:class:`~matplotlib.lines.Line2D` instances) and
- *labels* is an array of tick labels
- (:class:`~matplotlib.text.Text` instances). When called with
- arguments, the labels will appear at the specified radial
- distances and angles.
-
- *labels*, if not *None*, is a len(*radii*) list of strings of the
- labels to use at each angle.
-
- If *labels* is None, the rformatter will be used
-
- Examples::
-
- # set the locations of the radial gridlines and labels
- lines, labels = rgrids( (0.25, 0.5, 1.0) )
-
- # set the locations and labels of the radial gridlines and labels
- lines, labels = rgrids( (0.25, 0.5, 1.0), ('Tom', 'Dick', 'Harry' )
-
- """
- ax = gca()
- if not isinstance(ax, PolarAxes):
- raise RuntimeError('rgrids only defined for polar axes')
- if len(args)==0:
- lines = ax.yaxis.get_gridlines()
- labels = ax.yaxis.get_ticklabels()
- else:
- lines, labels = ax.set_rgrids(*args, **kwargs)
-
- return ( silent_list('Line2D rgridline', lines),
- silent_list('Text rgridlabel', labels) )
-
-
-def thetagrids(*args, **kwargs):
- """
- Get or set the theta locations of the gridlines in a polar plot.
-
- If no arguments are passed, return a tuple (*lines*, *labels*)
- where *lines* is an array of radial gridlines
- (:class:`~matplotlib.lines.Line2D` instances) and *labels* is an
- array of tick labels (:class:`~matplotlib.text.Text` instances)::
-
- lines, labels = thetagrids()
-
- Otherwise the syntax is::
-
- lines, labels = thetagrids(angles, labels=None, fmt='%d', frac = 1.1)
-
- set the angles at which to place the theta grids (these gridlines
- are equal along the theta dimension).
-
- *angles* is in degrees.
-
- *labels*, if not *None*, is a len(angles) list of strings of the
- labels to use at each angle.
-
- If *labels* is *None*, the labels will be ``fmt%angle``.
-
- *frac* is the fraction of the polar axes radius at which to place
- the label (1 is the edge). e.g., 1.05 is outside the axes and 0.95
- is inside the axes.
-
- Return value is a list of tuples (*lines*, *labels*):
-
- - *lines* are :class:`~matplotlib.lines.Line2D` instances
-
- - *labels* are :class:`~matplotlib.text.Text` instances.
-
- Note that on input, the *labels* argument is a list of strings,
- and on output it is a list of :class:`~matplotlib.text.Text`
- instances.
-
- Examples::
-
- # set the locations of the radial gridlines and labels
- lines, labels = thetagrids( range(45,360,90) )
-
- # set the locations and labels of the radial gridlines and labels
- lines, labels = thetagrids( range(45,360,90), ('NE', 'NW', 'SW','SE') )
- """
- ax = gca()
- if not isinstance(ax, PolarAxes):
- raise RuntimeError('rgrids only defined for polar axes')
- if len(args)==0:
- lines = ax.xaxis.get_ticklines()
- labels = ax.xaxis.get_ticklabels()
- else:
- lines, labels = ax.set_thetagrids(*args, **kwargs)
-
- return (silent_list('Line2D thetagridline', lines),
- silent_list('Text thetagridlabel', labels)
- )
-
-
-## Plotting Info ##
-
-def plotting():
- pass
-
-
-def get_plot_commands():
- """
- Get a sorted list of all of the plotting commands.
- """
- # This works by searching for all functions in this module and
- # removing a few hard-coded exclusions, as well as all of the
- # colormap-setting functions, and anything marked as private with
- # a preceding underscore.
-
- import inspect
-
- exclude = {'colormaps', 'colors', 'connect', 'disconnect',
- 'get_plot_commands', 'get_current_fig_manager', 'ginput',
- 'plotting', 'waitforbuttonpress'}
- exclude |= set(colormaps())
- this_module = inspect.getmodule(get_plot_commands)
-
- commands = set()
- for name, obj in list(six.iteritems(globals())):
- if name.startswith('_') or name in exclude:
- continue
- if inspect.isfunction(obj) and inspect.getmodule(obj) is this_module:
- commands.add(name)
-
- return sorted(commands)
-
-
-@deprecated('2.1')
-def colors():
- """
- This is a do-nothing function to provide you with help on how
- matplotlib handles colors.
-
- Commands which take color arguments can use several formats to
- specify the colors. For the basic built-in colors, you can use a
- single letter
-
- ===== =======
- Alias Color
- ===== =======
- 'b' blue
- 'g' green
- 'r' red
- 'c' cyan
- 'm' magenta
- 'y' yellow
- 'k' black
- 'w' white
- ===== =======
-
- For a greater range of colors, you have two options. You can
- specify the color using an html hex string, as in::
-
- color = '#eeefff'
-
- or you can pass an R,G,B tuple, where each of R,G,B are in the
- range [0,1].
-
- You can also use any legal html name for a color, for example::
-
- color = 'red'
- color = 'burlywood'
- color = 'chartreuse'
-
- The example below creates a subplot with a dark
- slate gray background::
-
- subplot(111, facecolor=(0.1843, 0.3098, 0.3098))
-
- Here is an example that creates a pale turquoise title::
-
- title('Is this the best color?', color='#afeeee')
-
- """
- pass
-
-
-def colormaps():
- """
- Matplotlib provides a number of colormaps, and others can be added using
- :func:`~matplotlib.cm.register_cmap`. This function documents the built-in
- colormaps, and will also return a list of all registered colormaps if called.
-
- You can set the colormap for an image, pcolor, scatter, etc,
- using a keyword argument::
-
- imshow(X, cmap=cm.hot)
-
- or using the :func:`set_cmap` function::
-
- imshow(X)
- pyplot.set_cmap('hot')
- pyplot.set_cmap('jet')
-
- In interactive mode, :func:`set_cmap` will update the colormap post-hoc,
- allowing you to see which one works best for your data.
-
- All built-in colormaps can be reversed by appending ``_r``: For instance,
- ``gray_r`` is the reverse of ``gray``.
-
- There are several common color schemes used in visualization:
-
- Sequential schemes
- for unipolar data that progresses from low to high
- Diverging schemes
- for bipolar data that emphasizes positive or negative deviations from a
- central value
- Cyclic schemes
- meant for plotting values that wrap around at the
- endpoints, such as phase angle, wind direction, or time of day
- Qualitative schemes
- for nominal data that has no inherent ordering, where color is used
- only to distinguish categories
-
- Matplotlib ships with 4 perceptually uniform color maps which are
- the recommended color maps for sequential data:
-
- ========= ===================================================
- Colormap Description
- ========= ===================================================
- inferno perceptually uniform shades of black-red-yellow
- magma perceptually uniform shades of black-red-white
- plasma perceptually uniform shades of blue-red-yellow
- viridis perceptually uniform shades of blue-green-yellow
- ========= ===================================================
-
- The following colormaps are based on the `ColorBrewer
- <http://colorbrewer2.org>`_ color specifications and designs developed by
- Cynthia Brewer:
-
- ColorBrewer Diverging (luminance is highest at the midpoint, and
- decreases towards differently-colored endpoints):
-
- ======== ===================================
- Colormap Description
- ======== ===================================
- BrBG brown, white, blue-green
- PiYG pink, white, yellow-green
- PRGn purple, white, green
- PuOr orange, white, purple
- RdBu red, white, blue
- RdGy red, white, gray
- RdYlBu red, yellow, blue
- RdYlGn red, yellow, green
- Spectral red, orange, yellow, green, blue
- ======== ===================================
-
- ColorBrewer Sequential (luminance decreases monotonically):
-
- ======== ====================================
- Colormap Description
- ======== ====================================
- Blues white to dark blue
- BuGn white, light blue, dark green
- BuPu white, light blue, dark purple
- GnBu white, light green, dark blue
- Greens white to dark green
- Greys white to black (not linear)
- Oranges white, orange, dark brown
- OrRd white, orange, dark red
- PuBu white, light purple, dark blue
- PuBuGn white, light purple, dark green
- PuRd white, light purple, dark red
- Purples white to dark purple
- RdPu white, pink, dark purple
- Reds white to dark red
- YlGn light yellow, dark green
- YlGnBu light yellow, light green, dark blue
- YlOrBr light yellow, orange, dark brown
- YlOrRd light yellow, orange, dark red
- ======== ====================================
-
- ColorBrewer Qualitative:
-
- (For plotting nominal data, :class:`ListedColormap` is used,
- not :class:`LinearSegmentedColormap`. Different sets of colors are
- recommended for different numbers of categories.)
-
- * Accent
- * Dark2
- * Paired
- * Pastel1
- * Pastel2
- * Set1
- * Set2
- * Set3
-
- A set of colormaps derived from those of the same name provided
- with Matlab are also included:
-
- ========= =======================================================
- Colormap Description
- ========= =======================================================
- autumn sequential linearly-increasing shades of red-orange-yellow
- bone sequential increasing black-white color map with
- a tinge of blue, to emulate X-ray film
- cool linearly-decreasing shades of cyan-magenta
- copper sequential increasing shades of black-copper
- flag repetitive red-white-blue-black pattern (not cyclic at
- endpoints)
- gray sequential linearly-increasing black-to-white
- grayscale
- hot sequential black-red-yellow-white, to emulate blackbody
- radiation from an object at increasing temperatures
- hsv cyclic red-yellow-green-cyan-blue-magenta-red, formed
- by changing the hue component in the HSV color space
- jet a spectral map with dark endpoints, blue-cyan-yellow-red;
- based on a fluid-jet simulation by NCSA [#]_
- pink sequential increasing pastel black-pink-white, meant
- for sepia tone colorization of photographs
- prism repetitive red-yellow-green-blue-purple-...-green pattern
- (not cyclic at endpoints)
- spring linearly-increasing shades of magenta-yellow
- summer sequential linearly-increasing shades of green-yellow
- winter linearly-increasing shades of blue-green
- ========= =======================================================
-
- A set of palettes from the `Yorick scientific visualisation
- package <https://dhmunro.github.io/yorick-doc/>`_, an evolution of
- the GIST package, both by David H. Munro are included:
-
- ============ =======================================================
- Colormap Description
- ============ =======================================================
- gist_earth mapmaker's colors from dark blue deep ocean to green
- lowlands to brown highlands to white mountains
- gist_heat sequential increasing black-red-orange-white, to emulate
- blackbody radiation from an iron bar as it grows hotter
- gist_ncar pseudo-spectral black-blue-green-yellow-red-purple-white
- colormap from National Center for Atmospheric
- Research [#]_
- gist_rainbow runs through the colors in spectral order from red to
- violet at full saturation (like *hsv* but not cyclic)
- gist_stern "Stern special" color table from Interactive Data
- Language software
- ============ =======================================================
-
-
- Other miscellaneous schemes:
-
- ============= =======================================================
- Colormap Description
- ============= =======================================================
- afmhot sequential black-orange-yellow-white blackbody
- spectrum, commonly used in atomic force microscopy
- brg blue-red-green
- bwr diverging blue-white-red
- coolwarm diverging blue-gray-red, meant to avoid issues with 3D
- shading, color blindness, and ordering of colors [#]_
- CMRmap "Default colormaps on color images often reproduce to
- confusing grayscale images. The proposed colormap
- maintains an aesthetically pleasing color image that
- automatically reproduces to a monotonic grayscale with
- discrete, quantifiable saturation levels." [#]_
- cubehelix Unlike most other color schemes cubehelix was designed
- by D.A. Green to be monotonically increasing in terms
- of perceived brightness. Also, when printed on a black
- and white postscript printer, the scheme results in a
- greyscale with monotonically increasing brightness.
- This color scheme is named cubehelix because the r,g,b
- values produced can be visualised as a squashed helix
- around the diagonal in the r,g,b color cube.
- gnuplot gnuplot's traditional pm3d scheme
- (black-blue-red-yellow)
- gnuplot2 sequential color printable as gray
- (black-blue-violet-yellow-white)
- ocean green-blue-white
- rainbow spectral purple-blue-green-yellow-orange-red colormap
- with diverging luminance
- seismic diverging blue-white-red
- nipy_spectral black-purple-blue-green-yellow-red-white spectrum,
- originally from the Neuroimaging in Python project
- terrain mapmaker's colors, blue-green-yellow-brown-white,
- originally from IGOR Pro
- ============= =======================================================
-
- The following colormaps are redundant and may be removed in future
- versions. It's recommended to use the names in the descriptions
- instead, which produce identical output:
-
- ========= =======================================================
- Colormap Description
- ========= =======================================================
- gist_gray identical to *gray*
- gist_yarg identical to *gray_r*
- binary identical to *gray_r*
- spectral identical to *nipy_spectral* [#]_
- ========= =======================================================
-
- .. rubric:: Footnotes
-
- .. [#] Rainbow colormaps, ``jet`` in particular, are considered a poor
- choice for scientific visualization by many researchers: `Rainbow Color
- Map (Still) Considered Harmful
- <http://ieeexplore.ieee.org/document/4118486/?arnumber=4118486>`_
-
- .. [#] Resembles "BkBlAqGrYeOrReViWh200" from NCAR Command
- Language. See `Color Table Gallery
- <https://www.ncl.ucar.edu/Document/Graphics/color_table_gallery.shtml>`_
-
- .. [#] See `Diverging Color Maps for Scientific Visualization
- <http://www.kennethmoreland.com/color-maps/>`_ by Kenneth Moreland.
-
- .. [#] See `A Color Map for Effective Black-and-White Rendering of
- Color-Scale Images
- <https://www.mathworks.com/matlabcentral/fileexchange/2662-cmrmap-m>`_
- by Carey Rappaport
-
- .. [#] Changed to distinguish from ColorBrewer's *Spectral* map.
- :func:`spectral` still works, but
- ``set_cmap('nipy_spectral')`` is recommended for clarity.
-
-
- """
- return sorted(cm.cmap_d)
-
-
-def _setup_pyplot_info_docstrings():
- """
- Generates the plotting and docstring.
-
- These must be done after the entire module is imported, so it is
- called from the end of this module, which is generated by
- boilerplate.py.
- """
- # Generate the plotting docstring
- import re
-
- def pad(s, l):
- """Pad string *s* to length *l*."""
- if l < len(s):
- return s[:l]
- return s + ' ' * (l - len(s))
-
- commands = get_plot_commands()
-
- first_sentence = re.compile(r"(?:\s*).+?\.(?:\s+|$)", flags=re.DOTALL)
-
- # Collect the first sentence of the docstring for all of the
- # plotting commands.
- rows = []
- max_name = 0
- max_summary = 0
- for name in commands:
- doc = globals()[name].__doc__
- summary = ''
- if doc is not None:
- match = first_sentence.match(doc)
- if match is not None:
- summary = match.group(0).strip().replace('\n', ' ')
- name = '`%s`' % name
- rows.append([name, summary])
- max_name = max(max_name, len(name))
- max_summary = max(max_summary, len(summary))
-
- lines = []
- sep = '=' * max_name + ' ' + '=' * max_summary
- lines.append(sep)
- lines.append(' '.join([pad("Function", max_name),
- pad("Description", max_summary)]))
- lines.append(sep)
- for name, summary in rows:
- lines.append(' '.join([pad(name, max_name),
- pad(summary, max_summary)]))
- lines.append(sep)
-
- plotting.__doc__ = '\n'.join(lines)
-
-## Plotting part 1: manually generated functions and wrappers ##
-
-def colorbar(mappable=None, cax=None, ax=None, **kw):
- if mappable is None:
- mappable = gci()
- if mappable is None:
- raise RuntimeError('No mappable was found to use for colorbar '
- 'creation. First define a mappable such as '
- 'an image (with imshow) or a contour set ('
- 'with contourf).')
- if ax is None:
- ax = gca()
-
- ret = gcf().colorbar(mappable, cax = cax, ax=ax, **kw)
- return ret
-colorbar.__doc__ = matplotlib.colorbar.colorbar_doc
-
-
-def clim(vmin=None, vmax=None):
- """
- Set the color limits of the current image.
-
- To apply clim to all axes images do::
-
- clim(0, 0.5)
-
- If either *vmin* or *vmax* is None, the image min/max respectively
- will be used for color scaling.
-
- If you want to set the clim of multiple images,
- use, for example::
-
- for im in gca().get_images():
- im.set_clim(0, 0.05)
-
- """
- im = gci()
- if im is None:
- raise RuntimeError('You must first define an image, e.g., with imshow')
-
- im.set_clim(vmin, vmax)
-
-
-def set_cmap(cmap):
- """
- Set the default colormap. Applies to the current image if any.
- See help(colormaps) for more information.
-
- *cmap* must be a :class:`~matplotlib.colors.Colormap` instance, or
- the name of a registered colormap.
-
- See :func:`matplotlib.cm.register_cmap` and
- :func:`matplotlib.cm.get_cmap`.
- """
- cmap = cm.get_cmap(cmap)
-
- rc('image', cmap=cmap.name)
- im = gci()
-
- if im is not None:
- im.set_cmap(cmap)
-
-
-
-@docstring.copy_dedent(_imread)
-def imread(*args, **kwargs):
- return _imread(*args, **kwargs)
-
-
-@docstring.copy_dedent(_imsave)
-def imsave(*args, **kwargs):
- return _imsave(*args, **kwargs)
-
-
-def matshow(A, fignum=None, **kwargs):
- """
- Display an array as a matrix in a new figure window.
-
- The origin is set at the upper left hand corner and rows (first
- dimension of the array) are displayed horizontally. The aspect
- ratio of the figure window is that of the array, unless this would
- make an excessively short or narrow figure.
-
- Tick labels for the xaxis are placed on top.
-
- Parameters
- ----------
- A : array-like(M, N)
- The matrix to be displayed.
-
- fignum : None or int or False
- If *None*, create a new figure window with automatic numbering.
-
- If *fignum* is an integer, draw into the figure with the given number
- (create it if it does not exist).
-
- If 0 or *False*, use the current axes if it exists instead of creating
- a new figure.
-
- .. note::
-
- Because of how `.Axes.matshow` tries to set the figure aspect
- ratio to be the one of the array, strange things may happen if you
- reuse an existing figure.
-
- Returns
- -------
- image : `~matplotlib.image.AxesImage`
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.axes.Axes.imshow` arguments
-
- """
- A = np.asanyarray(A)
- if fignum is False or fignum == 0:
- ax = gca()
- else:
- # Extract actual aspect ratio of array and make appropriately sized figure
- fig = figure(fignum, figsize=figaspect(A))
- ax = fig.add_axes([0.15, 0.09, 0.775, 0.775])
-
- im = ax.matshow(A, **kwargs)
- sci(im)
-
- return im
-
-
-def polar(*args, **kwargs):
- """
- Make a polar plot.
-
- call signature::
-
- polar(theta, r, **kwargs)
-
- Multiple *theta*, *r* arguments are supported, with format
- strings, as in :func:`~matplotlib.pyplot.plot`.
-
- """
- # If an axis already exists, check if it has a polar projection
- if gcf().get_axes():
- if not isinstance(gca(), PolarAxes):
- warnings.warn('Trying to create polar plot on an axis that does '
- 'not have a polar projection.')
- ax = gca(polar=True)
- ret = ax.plot(*args, **kwargs)
- return ret
-
-
-def plotfile(fname, cols=(0,), plotfuncs=None,
- comments='#', skiprows=0, checkrows=5, delimiter=',',
- names=None, subplots=True, newfig=True, **kwargs):
- """
- Plot the data in a file.
-
- *cols* is a sequence of column identifiers to plot. An identifier
- is either an int or a string. If it is an int, it indicates the
- column number. If it is a string, it indicates the column header.
- matplotlib will make column headers lower case, replace spaces with
- underscores, and remove all illegal characters; so ``'Adj Close*'``
- will have name ``'adj_close'``.
-
- - If len(*cols*) == 1, only that column will be plotted on the *y* axis.
-
- - If len(*cols*) > 1, the first element will be an identifier for
- data for the *x* axis and the remaining elements will be the
- column indexes for multiple subplots if *subplots* is *True*
- (the default), or for lines in a single subplot if *subplots*
- is *False*.
-
- *plotfuncs*, if not *None*, is a dictionary mapping identifier to
- an :class:`~matplotlib.axes.Axes` plotting function as a string.
- Default is 'plot', other choices are 'semilogy', 'fill', 'bar',
- etc. You must use the same type of identifier in the *cols*
- vector as you use in the *plotfuncs* dictionary, e.g., integer
- column numbers in both or column names in both. If *subplots*
- is *False*, then including any function such as 'semilogy'
- that changes the axis scaling will set the scaling for all
- columns.
-
- *comments*, *skiprows*, *checkrows*, *delimiter*, and *names*
- are all passed on to :func:`matplotlib.pylab.csv2rec` to
- load the data into a record array.
-
- If *newfig* is *True*, the plot always will be made in a new figure;
- if *False*, it will be made in the current figure if one exists,
- else in a new figure.
-
- kwargs are passed on to plotting functions.
-
- Example usage::
-
- # plot the 2nd and 4th column against the 1st in two subplots
- plotfile(fname, (0,1,3))
-
- # plot using column names; specify an alternate plot type for volume
- plotfile(fname, ('date', 'volume', 'adj_close'),
- plotfuncs={'volume': 'semilogy'})
-
- Note: plotfile is intended as a convenience for quickly plotting
- data from flat files; it is not intended as an alternative
- interface to general plotting with pyplot or matplotlib.
- """
-
- if newfig:
- fig = figure()
- else:
- fig = gcf()
-
- if len(cols)<1:
- raise ValueError('must have at least one column of data')
-
- if plotfuncs is None:
- plotfuncs = dict()
- from matplotlib.cbook import mplDeprecation
- with warnings.catch_warnings():
- warnings.simplefilter('ignore', mplDeprecation)
- r = mlab.csv2rec(fname, comments=comments, skiprows=skiprows,
- checkrows=checkrows, delimiter=delimiter, names=names)
-
- def getname_val(identifier):
- 'return the name and column data for identifier'
- if isinstance(identifier, six.string_types):
- return identifier, r[identifier]
- elif is_numlike(identifier):
- name = r.dtype.names[int(identifier)]
- return name, r[name]
- else:
- raise TypeError('identifier must be a string or integer')
-
- xname, x = getname_val(cols[0])
- ynamelist = []
-
- if len(cols)==1:
- ax1 = fig.add_subplot(1,1,1)
- funcname = plotfuncs.get(cols[0], 'plot')
- func = getattr(ax1, funcname)
- func(x, **kwargs)
- ax1.set_ylabel(xname)
- else:
- N = len(cols)
- for i in range(1,N):
- if subplots:
- if i==1:
- ax = ax1 = fig.add_subplot(N-1,1,i)
- else:
- ax = fig.add_subplot(N-1,1,i, sharex=ax1)
- elif i==1:
- ax = fig.add_subplot(1,1,1)
-
- yname, y = getname_val(cols[i])
- ynamelist.append(yname)
-
- funcname = plotfuncs.get(cols[i], 'plot')
- func = getattr(ax, funcname)
-
- func(x, y, **kwargs)
- if subplots:
- ax.set_ylabel(yname)
- if ax.is_last_row():
- ax.set_xlabel(xname)
- else:
- ax.set_xlabel('')
-
- if not subplots:
- ax.legend(ynamelist, loc='best')
-
- if xname=='date':
- fig.autofmt_xdate()
-
-
-def _autogen_docstring(base):
- """Autogenerated wrappers will get their docstring from a base function
- with an addendum."""
- #msg = "\n\nAdditional kwargs: hold = [True|False] overrides default hold state"
- msg = ''
- addendum = docstring.Appender(msg, '\n\n')
- return lambda func: addendum(docstring.copy_dedent(base)(func))
-
-# This function cannot be generated by boilerplate.py because it may
-# return an image or a line.
-@_autogen_docstring(Axes.spy)
-def spy(Z, precision=0, marker=None, markersize=None, aspect='equal', **kwargs):
- ax = gca()
- hold = kwargs.pop('hold', None)
- # allow callers to override the hold state by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.spy(Z, precision, marker, markersize, aspect, **kwargs)
- finally:
- ax._hold = washold
- if isinstance(ret, cm.ScalarMappable):
- sci(ret)
- return ret
-
-# just to be safe. Interactive mode can be turned on without
-# calling `plt.ion()` so register it again here.
-# This is safe because multiple calls to `install_repl_displayhook`
-# are no-ops and the registered function respect `mpl.is_interactive()`
-# to determine if they should trigger a draw.
-install_repl_displayhook()
-
-################# REMAINING CONTENT GENERATED BY boilerplate.py ##############
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.acorr)
-def acorr(x, hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.acorr(x, data=data, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.angle_spectrum)
-def angle_spectrum(x, Fs=None, Fc=None, window=None, pad_to=None, sides=None,
- hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.angle_spectrum(x, Fs=Fs, Fc=Fc, window=window, pad_to=pad_to,
- sides=sides, data=data, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.arrow)
-def arrow(x, y, dx, dy, hold=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.arrow(x, y, dx, dy, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.axhline)
-def axhline(y=0, xmin=0, xmax=1, hold=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.axhline(y=y, xmin=xmin, xmax=xmax, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.axhspan)
-def axhspan(ymin, ymax, xmin=0, xmax=1, hold=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.axhspan(ymin, ymax, xmin=xmin, xmax=xmax, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.axvline)
-def axvline(x=0, ymin=0, ymax=1, hold=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.axvline(x=x, ymin=ymin, ymax=ymax, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.axvspan)
-def axvspan(xmin, xmax, ymin=0, ymax=1, hold=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.axvspan(xmin, xmax, ymin=ymin, ymax=ymax, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.bar)
-def bar(*args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.bar(*args, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.barh)
-def barh(*args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.barh(*args, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.broken_barh)
-def broken_barh(xranges, yrange, hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.broken_barh(xranges, yrange, data=data, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.boxplot)
-def boxplot(x, notch=None, sym=None, vert=None, whis=None, positions=None,
- widths=None, patch_artist=None, bootstrap=None, usermedians=None,
- conf_intervals=None, meanline=None, showmeans=None, showcaps=None,
- showbox=None, showfliers=None, boxprops=None, labels=None,
- flierprops=None, medianprops=None, meanprops=None, capprops=None,
- whiskerprops=None, manage_xticks=True, autorange=False, zorder=None,
- hold=None, data=None):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.boxplot(x, notch=notch, sym=sym, vert=vert, whis=whis,
- positions=positions, widths=widths,
- patch_artist=patch_artist, bootstrap=bootstrap,
- usermedians=usermedians,
- conf_intervals=conf_intervals, meanline=meanline,
- showmeans=showmeans, showcaps=showcaps,
- showbox=showbox, showfliers=showfliers,
- boxprops=boxprops, labels=labels,
- flierprops=flierprops, medianprops=medianprops,
- meanprops=meanprops, capprops=capprops,
- whiskerprops=whiskerprops,
- manage_xticks=manage_xticks, autorange=autorange,
- zorder=zorder, data=data)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.cohere)
-def cohere(x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
- window=mlab.window_hanning, noverlap=0, pad_to=None, sides='default',
- scale_by_freq=None, hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.cohere(x, y, NFFT=NFFT, Fs=Fs, Fc=Fc, detrend=detrend,
- window=window, noverlap=noverlap, pad_to=pad_to,
- sides=sides, scale_by_freq=scale_by_freq, data=data,
- **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.clabel)
-def clabel(CS, *args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.clabel(CS, *args, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.contour)
-def contour(*args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.contour(*args, **kwargs)
- finally:
- ax._hold = washold
- if ret._A is not None: sci(ret)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.contourf)
-def contourf(*args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.contourf(*args, **kwargs)
- finally:
- ax._hold = washold
- if ret._A is not None: sci(ret)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.csd)
-def csd(x, y, NFFT=None, Fs=None, Fc=None, detrend=None, window=None,
- noverlap=None, pad_to=None, sides=None, scale_by_freq=None,
- return_line=None, hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.csd(x, y, NFFT=NFFT, Fs=Fs, Fc=Fc, detrend=detrend,
- window=window, noverlap=noverlap, pad_to=pad_to,
- sides=sides, scale_by_freq=scale_by_freq,
- return_line=return_line, data=data, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.errorbar)
-def errorbar(x, y, yerr=None, xerr=None, fmt='', ecolor=None, elinewidth=None,
- capsize=None, barsabove=False, lolims=False, uplims=False,
- xlolims=False, xuplims=False, errorevery=1, capthick=None,
- hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.errorbar(x, y, yerr=yerr, xerr=xerr, fmt=fmt, ecolor=ecolor,
- elinewidth=elinewidth, capsize=capsize,
- barsabove=barsabove, lolims=lolims, uplims=uplims,
- xlolims=xlolims, xuplims=xuplims,
- errorevery=errorevery, capthick=capthick, data=data,
- **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.eventplot)
-def eventplot(positions, orientation='horizontal', lineoffsets=1, linelengths=1,
- linewidths=None, colors=None, linestyles='solid', hold=None,
- data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.eventplot(positions, orientation=orientation,
- lineoffsets=lineoffsets, linelengths=linelengths,
- linewidths=linewidths, colors=colors,
- linestyles=linestyles, data=data, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.fill)
-def fill(*args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.fill(*args, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.fill_between)
-def fill_between(x, y1, y2=0, where=None, interpolate=False, step=None,
- hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.fill_between(x, y1, y2=y2, where=where,
- interpolate=interpolate, step=step, data=data,
- **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.fill_betweenx)
-def fill_betweenx(y, x1, x2=0, where=None, step=None, interpolate=False,
- hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.fill_betweenx(y, x1, x2=x2, where=where, step=step,
- interpolate=interpolate, data=data, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.hexbin)
-def hexbin(x, y, C=None, gridsize=100, bins=None, xscale='linear',
- yscale='linear', extent=None, cmap=None, norm=None, vmin=None,
- vmax=None, alpha=None, linewidths=None, edgecolors='face',
- reduce_C_function=np.mean, mincnt=None, marginals=False, hold=None,
- data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.hexbin(x, y, C=C, gridsize=gridsize, bins=bins, xscale=xscale,
- yscale=yscale, extent=extent, cmap=cmap, norm=norm,
- vmin=vmin, vmax=vmax, alpha=alpha,
- linewidths=linewidths, edgecolors=edgecolors,
- reduce_C_function=reduce_C_function, mincnt=mincnt,
- marginals=marginals, data=data, **kwargs)
- finally:
- ax._hold = washold
- sci(ret)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.hist)
-def hist(x, bins=None, range=None, density=None, weights=None, cumulative=False,
- bottom=None, histtype='bar', align='mid', orientation='vertical',
- rwidth=None, log=False, color=None, label=None, stacked=False,
- normed=None, hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.hist(x, bins=bins, range=range, density=density,
- weights=weights, cumulative=cumulative, bottom=bottom,
- histtype=histtype, align=align, orientation=orientation,
- rwidth=rwidth, log=log, color=color, label=label,
- stacked=stacked, normed=normed, data=data, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.hist2d)
-def hist2d(x, y, bins=10, range=None, normed=False, weights=None, cmin=None,
- cmax=None, hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.hist2d(x, y, bins=bins, range=range, normed=normed,
- weights=weights, cmin=cmin, cmax=cmax, data=data,
- **kwargs)
- finally:
- ax._hold = washold
- sci(ret[-1])
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.hlines)
-def hlines(y, xmin, xmax, colors='k', linestyles='solid', label='', hold=None,
- data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.hlines(y, xmin, xmax, colors=colors, linestyles=linestyles,
- label=label, data=data, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.imshow)
-def imshow(X, cmap=None, norm=None, aspect=None, interpolation=None, alpha=None,
- vmin=None, vmax=None, origin=None, extent=None, shape=None,
- filternorm=1, filterrad=4.0, imlim=None, resample=None, url=None,
- hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.imshow(X, cmap=cmap, norm=norm, aspect=aspect,
- interpolation=interpolation, alpha=alpha, vmin=vmin,
- vmax=vmax, origin=origin, extent=extent, shape=shape,
- filternorm=filternorm, filterrad=filterrad,
- imlim=imlim, resample=resample, url=url, data=data,
- **kwargs)
- finally:
- ax._hold = washold
- sci(ret)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.loglog)
-def loglog(*args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.loglog(*args, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.magnitude_spectrum)
-def magnitude_spectrum(x, Fs=None, Fc=None, window=None, pad_to=None,
- sides=None, scale=None, hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.magnitude_spectrum(x, Fs=Fs, Fc=Fc, window=window,
- pad_to=pad_to, sides=sides, scale=scale,
- data=data, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.pcolor)
-def pcolor(*args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.pcolor(*args, **kwargs)
- finally:
- ax._hold = washold
- sci(ret)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.pcolormesh)
-def pcolormesh(*args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.pcolormesh(*args, **kwargs)
- finally:
- ax._hold = washold
- sci(ret)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.phase_spectrum)
-def phase_spectrum(x, Fs=None, Fc=None, window=None, pad_to=None, sides=None,
- hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.phase_spectrum(x, Fs=Fs, Fc=Fc, window=window, pad_to=pad_to,
- sides=sides, data=data, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.pie)
-def pie(x, explode=None, labels=None, colors=None, autopct=None,
- pctdistance=0.6, shadow=False, labeldistance=1.1, startangle=None,
- radius=None, counterclock=True, wedgeprops=None, textprops=None,
- center=(0, 0), frame=False, rotatelabels=False, hold=None, data=None):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.pie(x, explode=explode, labels=labels, colors=colors,
- autopct=autopct, pctdistance=pctdistance, shadow=shadow,
- labeldistance=labeldistance, startangle=startangle,
- radius=radius, counterclock=counterclock,
- wedgeprops=wedgeprops, textprops=textprops, center=center,
- frame=frame, rotatelabels=rotatelabels, data=data)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.plot)
-def plot(*args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.plot(*args, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.plot_date)
-def plot_date(x, y, fmt='o', tz=None, xdate=True, ydate=False, hold=None,
- data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.plot_date(x, y, fmt=fmt, tz=tz, xdate=xdate, ydate=ydate,
- data=data, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.psd)
-def psd(x, NFFT=None, Fs=None, Fc=None, detrend=None, window=None,
- noverlap=None, pad_to=None, sides=None, scale_by_freq=None,
- return_line=None, hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.psd(x, NFFT=NFFT, Fs=Fs, Fc=Fc, detrend=detrend,
- window=window, noverlap=noverlap, pad_to=pad_to,
- sides=sides, scale_by_freq=scale_by_freq,
- return_line=return_line, data=data, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.quiver)
-def quiver(*args, **kw):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kw.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.quiver(*args, **kw)
- finally:
- ax._hold = washold
- sci(ret)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.quiverkey)
-def quiverkey(*args, **kw):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kw.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.quiverkey(*args, **kw)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.scatter)
-def scatter(x, y, s=None, c=None, marker=None, cmap=None, norm=None, vmin=None,
- vmax=None, alpha=None, linewidths=None, verts=None, edgecolors=None,
- hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.scatter(x, y, s=s, c=c, marker=marker, cmap=cmap, norm=norm,
- vmin=vmin, vmax=vmax, alpha=alpha,
- linewidths=linewidths, verts=verts,
- edgecolors=edgecolors, data=data, **kwargs)
- finally:
- ax._hold = washold
- sci(ret)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.semilogx)
-def semilogx(*args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.semilogx(*args, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.semilogy)
-def semilogy(*args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.semilogy(*args, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.specgram)
-def specgram(x, NFFT=None, Fs=None, Fc=None, detrend=None, window=None,
- noverlap=None, cmap=None, xextent=None, pad_to=None, sides=None,
- scale_by_freq=None, mode=None, scale=None, vmin=None, vmax=None,
- hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.specgram(x, NFFT=NFFT, Fs=Fs, Fc=Fc, detrend=detrend,
- window=window, noverlap=noverlap, cmap=cmap,
- xextent=xextent, pad_to=pad_to, sides=sides,
- scale_by_freq=scale_by_freq, mode=mode, scale=scale,
- vmin=vmin, vmax=vmax, data=data, **kwargs)
- finally:
- ax._hold = washold
- sci(ret[-1])
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.stackplot)
-def stackplot(x, *args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.stackplot(x, *args, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.stem)
-def stem(*args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.stem(*args, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.step)
-def step(x, y, *args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.step(x, y, *args, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.streamplot)
-def streamplot(x, y, u, v, density=1, linewidth=None, color=None, cmap=None,
- norm=None, arrowsize=1, arrowstyle='-|>', minlength=0.1,
- transform=None, zorder=None, start_points=None, maxlength=4.0,
- integration_direction='both', hold=None, data=None):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.streamplot(x, y, u, v, density=density, linewidth=linewidth,
- color=color, cmap=cmap, norm=norm,
- arrowsize=arrowsize, arrowstyle=arrowstyle,
- minlength=minlength, transform=transform,
- zorder=zorder, start_points=start_points,
- maxlength=maxlength,
- integration_direction=integration_direction,
- data=data)
- finally:
- ax._hold = washold
- sci(ret.lines)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.tricontour)
-def tricontour(*args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.tricontour(*args, **kwargs)
- finally:
- ax._hold = washold
- if ret._A is not None: sci(ret)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.tricontourf)
-def tricontourf(*args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.tricontourf(*args, **kwargs)
- finally:
- ax._hold = washold
- if ret._A is not None: sci(ret)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.tripcolor)
-def tripcolor(*args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.tripcolor(*args, **kwargs)
- finally:
- ax._hold = washold
- sci(ret)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.triplot)
-def triplot(*args, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kwargs.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.triplot(*args, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.violinplot)
-def violinplot(dataset, positions=None, vert=True, widths=0.5, showmeans=False,
- showextrema=True, showmedians=False, points=100, bw_method=None,
- hold=None, data=None):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.violinplot(dataset, positions=positions, vert=vert,
- widths=widths, showmeans=showmeans,
- showextrema=showextrema, showmedians=showmedians,
- points=points, bw_method=bw_method, data=data)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.vlines)
-def vlines(x, ymin, ymax, colors='k', linestyles='solid', label='', hold=None,
- data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.vlines(x, ymin, ymax, colors=colors, linestyles=linestyles,
- label=label, data=data, **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.xcorr)
-def xcorr(x, y, normed=True, detrend=mlab.detrend_none, usevlines=True,
- maxlags=10, hold=None, data=None, **kwargs):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
-
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.xcorr(x, y, normed=normed, detrend=detrend,
- usevlines=usevlines, maxlags=maxlags, data=data,
- **kwargs)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_autogen_docstring(Axes.barbs)
-def barbs(*args, **kw):
- ax = gca()
- # Deprecated: allow callers to override the hold state
- # by passing hold=True|False
- washold = ax._hold
- hold = kw.pop('hold', None)
- if hold is not None:
- ax._hold = hold
- from matplotlib.cbook import mplDeprecation
- warnings.warn("The 'hold' keyword argument is deprecated since 2.0.",
- mplDeprecation)
- try:
- ret = ax.barbs(*args, **kw)
- finally:
- ax._hold = washold
-
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@docstring.copy_dedent(Axes.cla)
-def cla():
- ret = gca().cla()
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@docstring.copy_dedent(Axes.grid)
-def grid(b=None, which='major', axis='both', **kwargs):
- ret = gca().grid(b=b, which=which, axis=axis, **kwargs)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@docstring.copy_dedent(Axes.legend)
-def legend(*args, **kwargs):
- ret = gca().legend(*args, **kwargs)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@docstring.copy_dedent(Axes.table)
-def table(**kwargs):
- ret = gca().table(**kwargs)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@docstring.copy_dedent(Axes.text)
-def text(x, y, s, fontdict=None, withdash=False, **kwargs):
- ret = gca().text(x, y, s, fontdict=fontdict, withdash=withdash, **kwargs)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@docstring.copy_dedent(Axes.annotate)
-def annotate(*args, **kwargs):
- ret = gca().annotate(*args, **kwargs)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@docstring.copy_dedent(Axes.ticklabel_format)
-def ticklabel_format(**kwargs):
- ret = gca().ticklabel_format(**kwargs)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@docstring.copy_dedent(Axes.locator_params)
-def locator_params(axis='both', tight=None, **kwargs):
- ret = gca().locator_params(axis=axis, tight=tight, **kwargs)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@docstring.copy_dedent(Axes.tick_params)
-def tick_params(axis='both', **kwargs):
- ret = gca().tick_params(axis=axis, **kwargs)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@docstring.copy_dedent(Axes.margins)
-def margins(*args, **kw):
- ret = gca().margins(*args, **kw)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@docstring.copy_dedent(Axes.autoscale)
-def autoscale(enable=True, axis='both', tight=None):
- ret = gca().autoscale(enable=enable, axis=axis, tight=tight)
- return ret
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def autumn():
- """
- Set the colormap to "autumn".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("autumn")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def bone():
- """
- Set the colormap to "bone".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("bone")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def cool():
- """
- Set the colormap to "cool".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("cool")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def copper():
- """
- Set the colormap to "copper".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("copper")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def flag():
- """
- Set the colormap to "flag".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("flag")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def gray():
- """
- Set the colormap to "gray".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("gray")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def hot():
- """
- Set the colormap to "hot".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("hot")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def hsv():
- """
- Set the colormap to "hsv".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("hsv")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def jet():
- """
- Set the colormap to "jet".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("jet")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def pink():
- """
- Set the colormap to "pink".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("pink")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def prism():
- """
- Set the colormap to "prism".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("prism")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def spring():
- """
- Set the colormap to "spring".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("spring")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def summer():
- """
- Set the colormap to "summer".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("summer")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def winter():
- """
- Set the colormap to "winter".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("winter")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def magma():
- """
- Set the colormap to "magma".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("magma")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def inferno():
- """
- Set the colormap to "inferno".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("inferno")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def plasma():
- """
- Set the colormap to "plasma".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("plasma")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def viridis():
- """
- Set the colormap to "viridis".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("viridis")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def nipy_spectral():
- """
- Set the colormap to "nipy_spectral".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("nipy_spectral")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def spectral():
- """
- Set the colormap to "spectral".
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- from matplotlib.cbook import warn_deprecated
- warn_deprecated(
- "2.0",
- name="spectral",
- obj_type="colormap"
- )
- set_cmap("spectral")
-
-_setup_pyplot_info_docstrings()
diff --git a/contrib/python/matplotlib/py2/matplotlib/quiver.py b/contrib/python/matplotlib/py2/matplotlib/quiver.py
deleted file mode 100644
index 92de37ecb8..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/quiver.py
+++ /dev/null
@@ -1,1197 +0,0 @@
-"""
-Support for plotting vector fields.
-
-Presently this contains Quiver and Barb. Quiver plots an arrow in the
-direction of the vector, with the size of the arrow related to the
-magnitude of the vector.
-
-Barbs are like quiver in that they point along a vector, but
-the magnitude of the vector is given schematically by the presence of barbs
-or flags on the barb.
-
-This will also become a home for things such as standard
-deviation ellipses, which can and will be derived very easily from
-the Quiver code.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import math
-import weakref
-
-import numpy as np
-from numpy import ma
-import matplotlib.collections as mcollections
-import matplotlib.transforms as transforms
-import matplotlib.text as mtext
-import matplotlib.artist as martist
-from matplotlib.artist import allow_rasterization
-from matplotlib import docstring
-import matplotlib.font_manager as font_manager
-from matplotlib.cbook import delete_masked_points
-from matplotlib.patches import CirclePolygon
-
-
-_quiver_doc = """
-Plot a 2-D field of arrows.
-
-Call signatures::
-
- quiver(U, V, **kw)
- quiver(U, V, C, **kw)
- quiver(X, Y, U, V, **kw)
- quiver(X, Y, U, V, C, **kw)
-
-*U* and *V* are the arrow data, *X* and *Y* set the location of the
-arrows, and *C* sets the color of the arrows. These arguments may be 1-D or
-2-D arrays or sequences.
-
-If *X* and *Y* are absent, they will be generated as a uniform grid.
-If *U* and *V* are 2-D arrays and *X* and *Y* are 1-D, and if ``len(X)`` and
-``len(Y)`` match the column and row dimensions of *U*, then *X* and *Y* will be
-expanded with :func:`numpy.meshgrid`.
-
-The default settings auto-scales the length of the arrows to a reasonable size.
-To change this behavior see the *scale* and *scale_units* kwargs.
-
-The defaults give a slightly swept-back arrow; to make the head a
-triangle, make *headaxislength* the same as *headlength*. To make the
-arrow more pointed, reduce *headwidth* or increase *headlength* and
-*headaxislength*. To make the head smaller relative to the shaft,
-scale down all the head parameters. You will probably do best to leave
-minshaft alone.
-
-*linewidths* and *edgecolors* can be used to customize the arrow
-outlines.
-
-Parameters
-----------
-X : 1D or 2D array, sequence, optional
- The x coordinates of the arrow locations
-Y : 1D or 2D array, sequence, optional
- The y coordinates of the arrow locations
-U : 1D or 2D array or masked array, sequence
- The x components of the arrow vectors
-V : 1D or 2D array or masked array, sequence
- The y components of the arrow vectors
-C : 1D or 2D array, sequence, optional
- The arrow colors
-units : [ 'width' | 'height' | 'dots' | 'inches' | 'x' | 'y' | 'xy' ]
- The arrow dimensions (except for *length*) are measured in multiples of
- this unit.
-
- 'width' or 'height': the width or height of the axis
-
- 'dots' or 'inches': pixels or inches, based on the figure dpi
-
- 'x', 'y', or 'xy': respectively *X*, *Y*, or :math:`\\sqrt{X^2 + Y^2}`
- in data units
-
- The arrows scale differently depending on the units. For
- 'x' or 'y', the arrows get larger as one zooms in; for other
- units, the arrow size is independent of the zoom state. For
- 'width or 'height', the arrow size increases with the width and
- height of the axes, respectively, when the window is resized;
- for 'dots' or 'inches', resizing does not change the arrows.
-angles : [ 'uv' | 'xy' ], array, optional
- Method for determining the angle of the arrows. Default is 'uv'.
-
- 'uv': the arrow axis aspect ratio is 1 so that
- if *U*==*V* the orientation of the arrow on the plot is 45 degrees
- counter-clockwise from the horizontal axis (positive to the right).
-
- 'xy': arrows point from (x,y) to (x+u, y+v).
- Use this for plotting a gradient field, for example.
-
- Alternatively, arbitrary angles may be specified as an array
- of values in degrees, counter-clockwise from the horizontal axis.
-
- Note: inverting a data axis will correspondingly invert the
- arrows only with ``angles='xy'``.
-scale : None, float, optional
- Number of data units per arrow length unit, e.g., m/s per plot width; a
- smaller scale parameter makes the arrow longer. Default is *None*.
-
- If *None*, a simple autoscaling algorithm is used, based on the average
- vector length and the number of vectors. The arrow length unit is given by
- the *scale_units* parameter
-scale_units : [ 'width' | 'height' | 'dots' | 'inches' | 'x' | 'y' | 'xy' ], \
-None, optional
- If the *scale* kwarg is *None*, the arrow length unit. Default is *None*.
-
- e.g. *scale_units* is 'inches', *scale* is 2.0, and
- ``(u,v) = (1,0)``, then the vector will be 0.5 inches long.
-
- If *scale_units* is 'width'/'height', then the vector will be half the
- width/height of the axes.
-
- If *scale_units* is 'x' then the vector will be 0.5 x-axis
- units. To plot vectors in the x-y plane, with u and v having
- the same units as x and y, use
- ``angles='xy', scale_units='xy', scale=1``.
-width : scalar, optional
- Shaft width in arrow units; default depends on choice of units,
- above, and number of vectors; a typical starting value is about
- 0.005 times the width of the plot.
-headwidth : scalar, optional
- Head width as multiple of shaft width, default is 3
-headlength : scalar, optional
- Head length as multiple of shaft width, default is 5
-headaxislength : scalar, optional
- Head length at shaft intersection, default is 4.5
-minshaft : scalar, optional
- Length below which arrow scales, in units of head length. Do not
- set this to less than 1, or small arrows will look terrible!
- Default is 1
-minlength : scalar, optional
- Minimum length as a multiple of shaft width; if an arrow length
- is less than this, plot a dot (hexagon) of this diameter instead.
- Default is 1.
-pivot : [ 'tail' | 'mid' | 'middle' | 'tip' ], optional
- The part of the arrow that is at the grid point; the arrow rotates
- about this point, hence the name *pivot*.
-color : [ color | color sequence ], optional
- This is a synonym for the
- :class:`~matplotlib.collections.PolyCollection` facecolor kwarg.
- If *C* has been set, *color* has no effect.
-
-Notes
------
-Additional :class:`~matplotlib.collections.PolyCollection`
-keyword arguments:
-
-%(PolyCollection)s
-
-See Also
---------
-quiverkey : Add a key to a quiver plot
-""" % docstring.interpd.params
-
-_quiverkey_doc = """
-Add a key to a quiver plot.
-
-Call signature::
-
- quiverkey(Q, X, Y, U, label, **kw)
-
-Arguments:
-
- *Q*:
- The Quiver instance returned by a call to quiver.
-
- *X*, *Y*:
- The location of the key; additional explanation follows.
-
- *U*:
- The length of the key
-
- *label*:
- A string with the length and units of the key
-
-Keyword arguments:
-
- *angle* = 0
- The angle of the key arrow. Measured in degrees anti-clockwise from the
- x-axis.
-
- *coordinates* = [ 'axes' | 'figure' | 'data' | 'inches' ]
- Coordinate system and units for *X*, *Y*: 'axes' and 'figure' are
- normalized coordinate systems with 0,0 in the lower left and 1,1
- in the upper right; 'data' are the axes data coordinates (used for
- the locations of the vectors in the quiver plot itself); 'inches'
- is position in the figure in inches, with 0,0 at the lower left
- corner.
-
- *color*:
- overrides face and edge colors from *Q*.
-
- *labelpos* = [ 'N' | 'S' | 'E' | 'W' ]
- Position the label above, below, to the right, to the left of the
- arrow, respectively.
-
- *labelsep*:
- Distance in inches between the arrow and the label. Default is
- 0.1
-
- *labelcolor*:
- defaults to default :class:`~matplotlib.text.Text` color.
-
- *fontproperties*:
- A dictionary with keyword arguments accepted by the
- :class:`~matplotlib.font_manager.FontProperties` initializer:
- *family*, *style*, *variant*, *size*, *weight*
-
-Any additional keyword arguments are used to override vector
-properties taken from *Q*.
-
-The positioning of the key depends on *X*, *Y*, *coordinates*, and
-*labelpos*. If *labelpos* is 'N' or 'S', *X*, *Y* give the position
-of the middle of the key arrow. If *labelpos* is 'E', *X*, *Y*
-positions the head, and if *labelpos* is 'W', *X*, *Y* positions the
-tail; in either of these two cases, *X*, *Y* is somewhere in the
-middle of the arrow+label key object.
-"""
-
-
-class QuiverKey(martist.Artist):
- """ Labelled arrow for use as a quiver plot scale key."""
- halign = {'N': 'center', 'S': 'center', 'E': 'left', 'W': 'right'}
- valign = {'N': 'bottom', 'S': 'top', 'E': 'center', 'W': 'center'}
- pivot = {'N': 'middle', 'S': 'middle', 'E': 'tip', 'W': 'tail'}
-
- def __init__(self, Q, X, Y, U, label, **kw):
- martist.Artist.__init__(self)
- self.Q = Q
- self.X = X
- self.Y = Y
- self.U = U
- self.angle = kw.pop('angle', 0)
- self.coord = kw.pop('coordinates', 'axes')
- self.color = kw.pop('color', None)
- self.label = label
- self._labelsep_inches = kw.pop('labelsep', 0.1)
- self.labelsep = (self._labelsep_inches * Q.ax.figure.dpi)
-
- # try to prevent closure over the real self
- weak_self = weakref.ref(self)
-
- def on_dpi_change(fig):
- self_weakref = weak_self()
- if self_weakref is not None:
- self_weakref.labelsep = (self_weakref._labelsep_inches*fig.dpi)
- self_weakref._initialized = False # simple brute force update
- # works because _init is
- # called at the start of
- # draw.
-
- self._cid = Q.ax.figure.callbacks.connect('dpi_changed',
- on_dpi_change)
-
- self.labelpos = kw.pop('labelpos', 'N')
- self.labelcolor = kw.pop('labelcolor', None)
- self.fontproperties = kw.pop('fontproperties', dict())
- self.kw = kw
- _fp = self.fontproperties
- # boxprops = dict(facecolor='red')
- self.text = mtext.Text(
- text=label, # bbox=boxprops,
- horizontalalignment=self.halign[self.labelpos],
- verticalalignment=self.valign[self.labelpos],
- fontproperties=font_manager.FontProperties(**_fp))
-
- if self.labelcolor is not None:
- self.text.set_color(self.labelcolor)
- self._initialized = False
- self.zorder = Q.zorder + 0.1
-
- def remove(self):
- """
- Overload the remove method
- """
- self.Q.ax.figure.callbacks.disconnect(self._cid)
- self._cid = None
- # pass the remove call up the stack
- martist.Artist.remove(self)
-
- __init__.__doc__ = _quiverkey_doc
-
- def _init(self):
- if True: # not self._initialized:
- if not self.Q._initialized:
- self.Q._init()
- self._set_transform()
- _pivot = self.Q.pivot
- self.Q.pivot = self.pivot[self.labelpos]
- # Hack: save and restore the Umask
- _mask = self.Q.Umask
- self.Q.Umask = ma.nomask
- self.verts = self.Q._make_verts(np.array([self.U]),
- np.zeros((1,)),
- self.angle)
- self.Q.Umask = _mask
- self.Q.pivot = _pivot
- kw = self.Q.polykw
- kw.update(self.kw)
- self.vector = mcollections.PolyCollection(
- self.verts,
- offsets=[(self.X, self.Y)],
- transOffset=self.get_transform(),
- **kw)
- if self.color is not None:
- self.vector.set_color(self.color)
- self.vector.set_transform(self.Q.get_transform())
- self.vector.set_figure(self.get_figure())
- self._initialized = True
-
- def _text_x(self, x):
- if self.labelpos == 'E':
- return x + self.labelsep
- elif self.labelpos == 'W':
- return x - self.labelsep
- else:
- return x
-
- def _text_y(self, y):
- if self.labelpos == 'N':
- return y + self.labelsep
- elif self.labelpos == 'S':
- return y - self.labelsep
- else:
- return y
-
- @allow_rasterization
- def draw(self, renderer):
- self._init()
- self.vector.draw(renderer)
- x, y = self.get_transform().transform_point((self.X, self.Y))
- self.text.set_x(self._text_x(x))
- self.text.set_y(self._text_y(y))
- self.text.draw(renderer)
- self.stale = False
-
- def _set_transform(self):
- if self.coord == 'data':
- self.set_transform(self.Q.ax.transData)
- elif self.coord == 'axes':
- self.set_transform(self.Q.ax.transAxes)
- elif self.coord == 'figure':
- self.set_transform(self.Q.ax.figure.transFigure)
- elif self.coord == 'inches':
- self.set_transform(self.Q.ax.figure.dpi_scale_trans)
- else:
- raise ValueError('unrecognized coordinates')
-
- def set_figure(self, fig):
- martist.Artist.set_figure(self, fig)
- self.text.set_figure(fig)
-
- def contains(self, mouseevent):
- # Maybe the dictionary should allow one to
- # distinguish between a text hit and a vector hit.
- if (self.text.contains(mouseevent)[0] or
- self.vector.contains(mouseevent)[0]):
- return True, {}
- return False, {}
-
- quiverkey_doc = _quiverkey_doc
-
-
-# This is a helper function that parses out the various combination of
-# arguments for doing colored vector plots. Pulling it out here
-# allows both Quiver and Barbs to use it
-def _parse_args(*args):
- X, Y, U, V, C = [None] * 5
- args = list(args)
-
- # The use of atleast_1d allows for handling scalar arguments while also
- # keeping masked arrays
- if len(args) == 3 or len(args) == 5:
- C = np.atleast_1d(args.pop(-1))
- V = np.atleast_1d(args.pop(-1))
- U = np.atleast_1d(args.pop(-1))
- if U.ndim == 1:
- nr, nc = 1, U.shape[0]
- else:
- nr, nc = U.shape
- if len(args) == 2: # remaining after removing U,V,C
- X, Y = [np.array(a).ravel() for a in args]
- if len(X) == nc and len(Y) == nr:
- X, Y = [a.ravel() for a in np.meshgrid(X, Y)]
- else:
- indexgrid = np.meshgrid(np.arange(nc), np.arange(nr))
- X, Y = [np.ravel(a) for a in indexgrid]
- return X, Y, U, V, C
-
-
-def _check_consistent_shapes(*arrays):
- all_shapes = set(a.shape for a in arrays)
- if len(all_shapes) != 1:
- raise ValueError('The shapes of the passed in arrays do not match.')
-
-
-class Quiver(mcollections.PolyCollection):
- """
- Specialized PolyCollection for arrows.
-
- The only API method is set_UVC(), which can be used
- to change the size, orientation, and color of the
- arrows; their locations are fixed when the class is
- instantiated. Possibly this method will be useful
- in animations.
-
- Much of the work in this class is done in the draw()
- method so that as much information as possible is available
- about the plot. In subsequent draw() calls, recalculation
- is limited to things that might have changed, so there
- should be no performance penalty from putting the calculations
- in the draw() method.
- """
-
- _PIVOT_VALS = ('tail', 'mid', 'middle', 'tip')
-
- @docstring.Substitution(_quiver_doc)
- def __init__(self, ax, *args, **kw):
- """
- The constructor takes one required argument, an Axes
- instance, followed by the args and kwargs described
- by the following pylab interface documentation:
- %s
- """
- self.ax = ax
- X, Y, U, V, C = _parse_args(*args)
- self.X = X
- self.Y = Y
- self.XY = np.hstack((X[:, np.newaxis], Y[:, np.newaxis]))
- self.N = len(X)
- self.scale = kw.pop('scale', None)
- self.headwidth = kw.pop('headwidth', 3)
- self.headlength = float(kw.pop('headlength', 5))
- self.headaxislength = kw.pop('headaxislength', 4.5)
- self.minshaft = kw.pop('minshaft', 1)
- self.minlength = kw.pop('minlength', 1)
- self.units = kw.pop('units', 'width')
- self.scale_units = kw.pop('scale_units', None)
- self.angles = kw.pop('angles', 'uv')
- self.width = kw.pop('width', None)
- self.color = kw.pop('color', 'k')
-
- pivot = kw.pop('pivot', 'tail').lower()
- # validate pivot
- if pivot not in self._PIVOT_VALS:
- raise ValueError(
- 'pivot must be one of {keys}, you passed {inp}'.format(
- keys=self._PIVOT_VALS, inp=pivot))
- # normalize to 'middle'
- if pivot == 'mid':
- pivot = 'middle'
- self.pivot = pivot
-
- self.transform = kw.pop('transform', ax.transData)
- kw.setdefault('facecolors', self.color)
- kw.setdefault('linewidths', (0,))
- mcollections.PolyCollection.__init__(self, [], offsets=self.XY,
- transOffset=self.transform,
- closed=False,
- **kw)
- self.polykw = kw
- self.set_UVC(U, V, C)
- self._initialized = False
-
- self.keyvec = None
- self.keytext = None
-
- # try to prevent closure over the real self
- weak_self = weakref.ref(self)
-
- def on_dpi_change(fig):
- self_weakref = weak_self()
- if self_weakref is not None:
- self_weakref._new_UV = True # vertices depend on width, span
- # which in turn depend on dpi
- self_weakref._initialized = False # simple brute force update
- # works because _init is
- # called at the start of
- # draw.
-
- self._cid = self.ax.figure.callbacks.connect('dpi_changed',
- on_dpi_change)
-
- def remove(self):
- """
- Overload the remove method
- """
- # disconnect the call back
- self.ax.figure.callbacks.disconnect(self._cid)
- self._cid = None
- # pass the remove call up the stack
- mcollections.PolyCollection.remove(self)
-
- def _init(self):
- """
- Initialization delayed until first draw;
- allow time for axes setup.
- """
- # It seems that there are not enough event notifications
- # available to have this work on an as-needed basis at present.
- if True: # not self._initialized:
- trans = self._set_transform()
- ax = self.ax
- sx, sy = trans.inverted().transform_point(
- (ax.bbox.width, ax.bbox.height))
- self.span = sx
- if self.width is None:
- sn = np.clip(math.sqrt(self.N), 8, 25)
- self.width = 0.06 * self.span / sn
-
- # _make_verts sets self.scale if not already specified
- if not self._initialized and self.scale is None:
- self._make_verts(self.U, self.V, self.angles)
-
- self._initialized = True
-
- def get_datalim(self, transData):
- trans = self.get_transform()
- transOffset = self.get_offset_transform()
- full_transform = (trans - transData) + (transOffset - transData)
- XY = full_transform.transform(self.XY)
- bbox = transforms.Bbox.null()
- bbox.update_from_data_xy(XY, ignore=True)
- return bbox
-
- @allow_rasterization
- def draw(self, renderer):
- self._init()
- verts = self._make_verts(self.U, self.V, self.angles)
- self.set_verts(verts, closed=False)
- self._new_UV = False
- mcollections.PolyCollection.draw(self, renderer)
- self.stale = False
-
- def set_UVC(self, U, V, C=None):
- # We need to ensure we have a copy, not a reference
- # to an array that might change before draw().
- U = ma.masked_invalid(U, copy=True).ravel()
- V = ma.masked_invalid(V, copy=True).ravel()
- mask = ma.mask_or(U.mask, V.mask, copy=False, shrink=True)
- if C is not None:
- C = ma.masked_invalid(C, copy=True).ravel()
- mask = ma.mask_or(mask, C.mask, copy=False, shrink=True)
- if mask is ma.nomask:
- C = C.filled()
- else:
- C = ma.array(C, mask=mask, copy=False)
- self.U = U.filled(1)
- self.V = V.filled(1)
- self.Umask = mask
- if C is not None:
- self.set_array(C)
- self._new_UV = True
- self.stale = True
-
- def _dots_per_unit(self, units):
- """
- Return a scale factor for converting from units to pixels
- """
- ax = self.ax
- if units in ('x', 'y', 'xy'):
- if units == 'x':
- dx0 = ax.viewLim.width
- dx1 = ax.bbox.width
- elif units == 'y':
- dx0 = ax.viewLim.height
- dx1 = ax.bbox.height
- else: # 'xy' is assumed
- dxx0 = ax.viewLim.width
- dxx1 = ax.bbox.width
- dyy0 = ax.viewLim.height
- dyy1 = ax.bbox.height
- dx1 = np.hypot(dxx1, dyy1)
- dx0 = np.hypot(dxx0, dyy0)
- dx = dx1 / dx0
- else:
- if units == 'width':
- dx = ax.bbox.width
- elif units == 'height':
- dx = ax.bbox.height
- elif units == 'dots':
- dx = 1.0
- elif units == 'inches':
- dx = ax.figure.dpi
- else:
- raise ValueError('unrecognized units')
- return dx
-
- def _set_transform(self):
- """
- Sets the PolygonCollection transform to go
- from arrow width units to pixels.
- """
- dx = self._dots_per_unit(self.units)
- self._trans_scale = dx # pixels per arrow width unit
- trans = transforms.Affine2D().scale(dx)
- self.set_transform(trans)
- return trans
-
- def _angles_lengths(self, U, V, eps=1):
- xy = self.ax.transData.transform(self.XY)
- uv = np.hstack((U[:, np.newaxis], V[:, np.newaxis]))
- xyp = self.ax.transData.transform(self.XY + eps * uv)
- dxy = xyp - xy
- angles = np.arctan2(dxy[:, 1], dxy[:, 0])
- lengths = np.hypot(*dxy.T) / eps
- return angles, lengths
-
- def _make_verts(self, U, V, angles):
- uv = (U + V * 1j)
- str_angles = angles if isinstance(angles, six.string_types) else ''
- if str_angles == 'xy' and self.scale_units == 'xy':
- # Here eps is 1 so that if we get U, V by diffing
- # the X, Y arrays, the vectors will connect the
- # points, regardless of the axis scaling (including log).
- angles, lengths = self._angles_lengths(U, V, eps=1)
- elif str_angles == 'xy' or self.scale_units == 'xy':
- # Calculate eps based on the extents of the plot
- # so that we don't end up with roundoff error from
- # adding a small number to a large.
- eps = np.abs(self.ax.dataLim.extents).max() * 0.001
- angles, lengths = self._angles_lengths(U, V, eps=eps)
- if str_angles and self.scale_units == 'xy':
- a = lengths
- else:
- a = np.abs(uv)
- if self.scale is None:
- sn = max(10, math.sqrt(self.N))
- if self.Umask is not ma.nomask:
- amean = a[~self.Umask].mean()
- else:
- amean = a.mean()
- # crude auto-scaling
- # scale is typical arrow length as a multiple of the arrow width
- scale = 1.8 * amean * sn / self.span
- if self.scale_units is None:
- if self.scale is None:
- self.scale = scale
- widthu_per_lenu = 1.0
- else:
- if self.scale_units == 'xy':
- dx = 1
- else:
- dx = self._dots_per_unit(self.scale_units)
- widthu_per_lenu = dx / self._trans_scale
- if self.scale is None:
- self.scale = scale * widthu_per_lenu
- length = a * (widthu_per_lenu / (self.scale * self.width))
- X, Y = self._h_arrows(length)
- if str_angles == 'xy':
- theta = angles
- elif str_angles == 'uv':
- theta = np.angle(uv)
- else:
- theta = ma.masked_invalid(np.deg2rad(angles)).filled(0)
- theta = theta.reshape((-1, 1)) # for broadcasting
- xy = (X + Y * 1j) * np.exp(1j * theta) * self.width
- xy = xy[:, :, np.newaxis]
- XY = np.concatenate((xy.real, xy.imag), axis=2)
- if self.Umask is not ma.nomask:
- XY = ma.array(XY)
- XY[self.Umask] = ma.masked
- # This might be handled more efficiently with nans, given
- # that nans will end up in the paths anyway.
-
- return XY
-
- def _h_arrows(self, length):
- """ length is in arrow width units """
- # It might be possible to streamline the code
- # and speed it up a bit by using complex (x,y)
- # instead of separate arrays; but any gain would be slight.
- minsh = self.minshaft * self.headlength
- N = len(length)
- length = length.reshape(N, 1)
- # This number is chosen based on when pixel values overflow in Agg
- # causing rendering errors
- # length = np.minimum(length, 2 ** 16)
- np.clip(length, 0, 2 ** 16, out=length)
- # x, y: normal horizontal arrow
- x = np.array([0, -self.headaxislength,
- -self.headlength, 0],
- np.float64)
- x = x + np.array([0, 1, 1, 1]) * length
- y = 0.5 * np.array([1, 1, self.headwidth, 0], np.float64)
- y = np.repeat(y[np.newaxis, :], N, axis=0)
- # x0, y0: arrow without shaft, for short vectors
- x0 = np.array([0, minsh - self.headaxislength,
- minsh - self.headlength, minsh], np.float64)
- y0 = 0.5 * np.array([1, 1, self.headwidth, 0], np.float64)
- ii = [0, 1, 2, 3, 2, 1, 0, 0]
- X = x.take(ii, 1)
- Y = y.take(ii, 1)
- Y[:, 3:-1] *= -1
- X0 = x0.take(ii)
- Y0 = y0.take(ii)
- Y0[3:-1] *= -1
- shrink = length / minsh if minsh != 0. else 0.
- X0 = shrink * X0[np.newaxis, :]
- Y0 = shrink * Y0[np.newaxis, :]
- short = np.repeat(length < minsh, 8, axis=1)
- # Now select X0, Y0 if short, otherwise X, Y
- np.copyto(X, X0, where=short)
- np.copyto(Y, Y0, where=short)
- if self.pivot == 'middle':
- X -= 0.5 * X[:, 3, np.newaxis]
- elif self.pivot == 'tip':
- X = X - X[:, 3, np.newaxis] # numpy bug? using -= does not
- # work here unless we multiply
- # by a float first, as with 'mid'.
- elif self.pivot != 'tail':
- raise ValueError(("Quiver.pivot must have value in {{'middle', "
- "'tip', 'tail'}} not {0}").format(self.pivot))
-
- tooshort = length < self.minlength
- if tooshort.any():
- # Use a heptagonal dot:
- th = np.arange(0, 8, 1, np.float64) * (np.pi / 3.0)
- x1 = np.cos(th) * self.minlength * 0.5
- y1 = np.sin(th) * self.minlength * 0.5
- X1 = np.repeat(x1[np.newaxis, :], N, axis=0)
- Y1 = np.repeat(y1[np.newaxis, :], N, axis=0)
- tooshort = np.repeat(tooshort, 8, 1)
- np.copyto(X, X1, where=tooshort)
- np.copyto(Y, Y1, where=tooshort)
- # Mask handling is deferred to the caller, _make_verts.
- return X, Y
-
- quiver_doc = _quiver_doc
-
-
-_barbs_doc = r"""
-Plot a 2-D field of barbs.
-
-Call signatures::
-
- barb(U, V, **kw)
- barb(U, V, C, **kw)
- barb(X, Y, U, V, **kw)
- barb(X, Y, U, V, C, **kw)
-
-Arguments:
-
- *X*, *Y*:
- The x and y coordinates of the barb locations
- (default is head of barb; see *pivot* kwarg)
-
- *U*, *V*:
- Give the x and y components of the barb shaft
-
- *C*:
- An optional array used to map colors to the barbs
-
-All arguments may be 1-D or 2-D arrays or sequences. If *X* and *Y*
-are absent, they will be generated as a uniform grid. If *U* and *V*
-are 2-D arrays but *X* and *Y* are 1-D, and if ``len(X)`` and ``len(Y)``
-match the column and row dimensions of *U*, then *X* and *Y* will be
-expanded with :func:`numpy.meshgrid`.
-
-*U*, *V*, *C* may be masked arrays, but masked *X*, *Y* are not
-supported at present.
-
-Keyword arguments:
-
- *length*:
- Length of the barb in points; the other parts of the barb
- are scaled against this.
- Default is 7.
-
- *pivot*: [ 'tip' | 'middle' | float ]
- The part of the arrow that is at the grid point; the arrow rotates
- about this point, hence the name *pivot*. Default is 'tip'. Can
- also be a number, which shifts the start of the barb that many
- points from the origin.
-
- *barbcolor*: [ color | color sequence ]
- Specifies the color all parts of the barb except any flags. This
- parameter is analogous to the *edgecolor* parameter for polygons,
- which can be used instead. However this parameter will override
- facecolor.
-
- *flagcolor*: [ color | color sequence ]
- Specifies the color of any flags on the barb. This parameter is
- analogous to the *facecolor* parameter for polygons, which can be
- used instead. However this parameter will override facecolor. If
- this is not set (and *C* has not either) then *flagcolor* will be
- set to match *barbcolor* so that the barb has a uniform color. If
- *C* has been set, *flagcolor* has no effect.
-
- *sizes*:
- A dictionary of coefficients specifying the ratio of a given
- feature to the length of the barb. Only those values one wishes to
- override need to be included. These features include:
-
- - 'spacing' - space between features (flags, full/half barbs)
-
- - 'height' - height (distance from shaft to top) of a flag or
- full barb
-
- - 'width' - width of a flag, twice the width of a full barb
-
- - 'emptybarb' - radius of the circle used for low magnitudes
-
- *fill_empty*:
- A flag on whether the empty barbs (circles) that are drawn should
- be filled with the flag color. If they are not filled, they will
- be drawn such that no color is applied to the center. Default is
- False
-
- *rounding*:
- A flag to indicate whether the vector magnitude should be rounded
- when allocating barb components. If True, the magnitude is
- rounded to the nearest multiple of the half-barb increment. If
- False, the magnitude is simply truncated to the next lowest
- multiple. Default is True
-
- *barb_increments*:
- A dictionary of increments specifying values to associate with
- different parts of the barb. Only those values one wishes to
- override need to be included.
-
- - 'half' - half barbs (Default is 5)
-
- - 'full' - full barbs (Default is 10)
-
- - 'flag' - flags (default is 50)
-
- *flip_barb*:
- Either a single boolean flag or an array of booleans. Single
- boolean indicates whether the lines and flags should point
- opposite to normal for all barbs. An array (which should be the
- same size as the other data arrays) indicates whether to flip for
- each individual barb. Normal behavior is for the barbs and lines
- to point right (comes from wind barbs having these features point
- towards low pressure in the Northern Hemisphere.) Default is
- False
-
-Barbs are traditionally used in meteorology as a way to plot the speed
-and direction of wind observations, but can technically be used to
-plot any two dimensional vector quantity. As opposed to arrows, which
-give vector magnitude by the length of the arrow, the barbs give more
-quantitative information about the vector magnitude by putting slanted
-lines or a triangle for various increments in magnitude, as show
-schematically below::
-
- : /\ \\
- : / \ \\
- : / \ \ \\
- : / \ \ \\
- : ------------------------------
-
-.. note the double \\ at the end of each line to make the figure
-.. render correctly
-
-The largest increment is given by a triangle (or "flag"). After those
-come full lines (barbs). The smallest increment is a half line. There
-is only, of course, ever at most 1 half line. If the magnitude is
-small and only needs a single half-line and no full lines or
-triangles, the half-line is offset from the end of the barb so that it
-can be easily distinguished from barbs with a single full line. The
-magnitude for the barb shown above would nominally be 65, using the
-standard increments of 50, 10, and 5.
-
-linewidths and edgecolors can be used to customize the barb.
-Additional :class:`~matplotlib.collections.PolyCollection` keyword
-arguments:
-
-%(PolyCollection)s
-""" % docstring.interpd.params
-
-docstring.interpd.update(barbs_doc=_barbs_doc)
-
-
-class Barbs(mcollections.PolyCollection):
- '''
- Specialized PolyCollection for barbs.
-
- The only API method is :meth:`set_UVC`, which can be used to
- change the size, orientation, and color of the arrows. Locations
- are changed using the :meth:`set_offsets` collection method.
- Possibly this method will be useful in animations.
-
- There is one internal function :meth:`_find_tails` which finds
- exactly what should be put on the barb given the vector magnitude.
- From there :meth:`_make_barbs` is used to find the vertices of the
- polygon to represent the barb based on this information.
- '''
- # This may be an abuse of polygons here to render what is essentially maybe
- # 1 triangle and a series of lines. It works fine as far as I can tell
- # however.
- @docstring.interpd
- def __init__(self, ax, *args, **kw):
- """
- The constructor takes one required argument, an Axes
- instance, followed by the args and kwargs described
- by the following pylab interface documentation:
- %(barbs_doc)s
- """
- self._pivot = kw.pop('pivot', 'tip')
- self._length = kw.pop('length', 7)
- barbcolor = kw.pop('barbcolor', None)
- flagcolor = kw.pop('flagcolor', None)
- self.sizes = kw.pop('sizes', dict())
- self.fill_empty = kw.pop('fill_empty', False)
- self.barb_increments = kw.pop('barb_increments', dict())
- self.rounding = kw.pop('rounding', True)
- self.flip = kw.pop('flip_barb', False)
- transform = kw.pop('transform', ax.transData)
-
- # Flagcolor and barbcolor provide convenience parameters for
- # setting the facecolor and edgecolor, respectively, of the barb
- # polygon. We also work here to make the flag the same color as the
- # rest of the barb by default
-
- if None in (barbcolor, flagcolor):
- kw['edgecolors'] = 'face'
- if flagcolor:
- kw['facecolors'] = flagcolor
- elif barbcolor:
- kw['facecolors'] = barbcolor
- else:
- # Set to facecolor passed in or default to black
- kw.setdefault('facecolors', 'k')
- else:
- kw['edgecolors'] = barbcolor
- kw['facecolors'] = flagcolor
-
- # Explicitly set a line width if we're not given one, otherwise
- # polygons are not outlined and we get no barbs
- if 'linewidth' not in kw and 'lw' not in kw:
- kw['linewidth'] = 1
-
- # Parse out the data arrays from the various configurations supported
- x, y, u, v, c = _parse_args(*args)
- self.x = x
- self.y = y
- xy = np.hstack((x[:, np.newaxis], y[:, np.newaxis]))
-
- # Make a collection
- barb_size = self._length ** 2 / 4 # Empirically determined
- mcollections.PolyCollection.__init__(self, [], (barb_size,),
- offsets=xy,
- transOffset=transform, **kw)
- self.set_transform(transforms.IdentityTransform())
-
- self.set_UVC(u, v, c)
-
- def _find_tails(self, mag, rounding=True, half=5, full=10, flag=50):
- '''
- Find how many of each of the tail pieces is necessary. Flag
- specifies the increment for a flag, barb for a full barb, and half for
- half a barb. Mag should be the magnitude of a vector (i.e., >= 0).
-
- This returns a tuple of:
-
- (*number of flags*, *number of barbs*, *half_flag*, *empty_flag*)
-
- *half_flag* is a boolean whether half of a barb is needed,
- since there should only ever be one half on a given
- barb. *empty_flag* flag is an array of flags to easily tell if
- a barb is empty (too low to plot any barbs/flags.
- '''
-
- # If rounding, round to the nearest multiple of half, the smallest
- # increment
- if rounding:
- mag = half * (mag / half + 0.5).astype(int)
-
- num_flags = np.floor(mag / flag).astype(int)
- mag = np.mod(mag, flag)
-
- num_barb = np.floor(mag / full).astype(int)
- mag = np.mod(mag, full)
-
- half_flag = mag >= half
- empty_flag = ~(half_flag | (num_flags > 0) | (num_barb > 0))
-
- return num_flags, num_barb, half_flag, empty_flag
-
- def _make_barbs(self, u, v, nflags, nbarbs, half_barb, empty_flag, length,
- pivot, sizes, fill_empty, flip):
- '''
- This function actually creates the wind barbs. *u* and *v*
- are components of the vector in the *x* and *y* directions,
- respectively.
-
- *nflags*, *nbarbs*, and *half_barb*, empty_flag* are,
- *respectively, the number of flags, number of barbs, flag for
- *half a barb, and flag for empty barb, ostensibly obtained
- *from :meth:`_find_tails`.
-
- *length* is the length of the barb staff in points.
-
- *pivot* specifies the point on the barb around which the
- entire barb should be rotated. Right now, valid options are
- 'tip' and 'middle'. Can also be a number, which shifts the start
- of the barb that many points from the origin.
-
- *sizes* is a dictionary of coefficients specifying the ratio
- of a given feature to the length of the barb. These features
- include:
-
- - *spacing*: space between features (flags, full/half
- barbs)
-
- - *height*: distance from shaft of top of a flag or full
- barb
-
- - *width* - width of a flag, twice the width of a full barb
-
- - *emptybarb* - radius of the circle used for low
- magnitudes
-
- *fill_empty* specifies whether the circle representing an
- empty barb should be filled or not (this changes the drawing
- of the polygon).
-
- *flip* is a flag indicating whether the features should be flipped to
- the other side of the barb (useful for winds in the southern
- hemisphere).
-
- This function returns list of arrays of vertices, defining a polygon
- for each of the wind barbs. These polygons have been rotated to
- properly align with the vector direction.
- '''
-
- # These control the spacing and size of barb elements relative to the
- # length of the shaft
- spacing = length * sizes.get('spacing', 0.125)
- full_height = length * sizes.get('height', 0.4)
- full_width = length * sizes.get('width', 0.25)
- empty_rad = length * sizes.get('emptybarb', 0.15)
-
- # Controls y point where to pivot the barb.
- pivot_points = dict(tip=0.0, middle=-length / 2.)
-
- # Check for flip
- if flip:
- full_height = -full_height
-
- endx = 0.0
- try:
- endy = float(pivot)
- except ValueError:
- endy = pivot_points[pivot.lower()]
-
- # Get the appropriate angle for the vector components. The offset is
- # due to the way the barb is initially drawn, going down the y-axis.
- # This makes sense in a meteorological mode of thinking since there 0
- # degrees corresponds to north (the y-axis traditionally)
- angles = -(ma.arctan2(v, u) + np.pi / 2)
-
- # Used for low magnitude. We just get the vertices, so if we make it
- # out here, it can be reused. The center set here should put the
- # center of the circle at the location(offset), rather than at the
- # same point as the barb pivot; this seems more sensible.
- circ = CirclePolygon((0, 0), radius=empty_rad).get_verts()
- if fill_empty:
- empty_barb = circ
- else:
- # If we don't want the empty one filled, we make a degenerate
- # polygon that wraps back over itself
- empty_barb = np.concatenate((circ, circ[::-1]))
-
- barb_list = []
- for index, angle in np.ndenumerate(angles):
- # If the vector magnitude is too weak to draw anything, plot an
- # empty circle instead
- if empty_flag[index]:
- # We can skip the transform since the circle has no preferred
- # orientation
- barb_list.append(empty_barb)
- continue
-
- poly_verts = [(endx, endy)]
- offset = length
-
- # Add vertices for each flag
- for i in range(nflags[index]):
- # The spacing that works for the barbs is a little to much for
- # the flags, but this only occurs when we have more than 1
- # flag.
- if offset != length:
- offset += spacing / 2.
- poly_verts.extend(
- [[endx, endy + offset],
- [endx + full_height, endy - full_width / 2 + offset],
- [endx, endy - full_width + offset]])
-
- offset -= full_width + spacing
-
- # Add vertices for each barb. These really are lines, but works
- # great adding 3 vertices that basically pull the polygon out and
- # back down the line
- for i in range(nbarbs[index]):
- poly_verts.extend(
- [(endx, endy + offset),
- (endx + full_height, endy + offset + full_width / 2),
- (endx, endy + offset)])
-
- offset -= spacing
-
- # Add the vertices for half a barb, if needed
- if half_barb[index]:
- # If the half barb is the first on the staff, traditionally it
- # is offset from the end to make it easy to distinguish from a
- # barb with a full one
- if offset == length:
- poly_verts.append((endx, endy + offset))
- offset -= 1.5 * spacing
- poly_verts.extend(
- [(endx, endy + offset),
- (endx + full_height / 2, endy + offset + full_width / 4),
- (endx, endy + offset)])
-
- # Rotate the barb according the angle. Making the barb first and
- # then rotating it made the math for drawing the barb really easy.
- # Also, the transform framework makes doing the rotation simple.
- poly_verts = transforms.Affine2D().rotate(-angle).transform(
- poly_verts)
- barb_list.append(poly_verts)
-
- return barb_list
-
- def set_UVC(self, U, V, C=None):
- self.u = ma.masked_invalid(U, copy=False).ravel()
- self.v = ma.masked_invalid(V, copy=False).ravel()
- if C is not None:
- c = ma.masked_invalid(C, copy=False).ravel()
- x, y, u, v, c = delete_masked_points(self.x.ravel(),
- self.y.ravel(),
- self.u, self.v, c)
- _check_consistent_shapes(x, y, u, v, c)
- else:
- x, y, u, v = delete_masked_points(self.x.ravel(), self.y.ravel(),
- self.u, self.v)
- _check_consistent_shapes(x, y, u, v)
-
- magnitude = np.hypot(u, v)
- flags, barbs, halves, empty = self._find_tails(magnitude,
- self.rounding,
- **self.barb_increments)
-
- # Get the vertices for each of the barbs
-
- plot_barbs = self._make_barbs(u, v, flags, barbs, halves, empty,
- self._length, self._pivot, self.sizes,
- self.fill_empty, self.flip)
- self.set_verts(plot_barbs)
-
- # Set the color array
- if C is not None:
- self.set_array(c)
-
- # Update the offsets in case the masked data changed
- xy = np.hstack((x[:, np.newaxis], y[:, np.newaxis]))
- self._offsets = xy
- self.stale = True
-
- def set_offsets(self, xy):
- """
- Set the offsets for the barb polygons. This saves the offsets passed
- in and actually sets version masked as appropriate for the existing
- U/V data. *offsets* should be a sequence.
-
- ACCEPTS: sequence of pairs of floats
- """
- self.x = xy[:, 0]
- self.y = xy[:, 1]
- x, y, u, v = delete_masked_points(self.x.ravel(), self.y.ravel(),
- self.u, self.v)
- _check_consistent_shapes(x, y, u, v)
- xy = np.hstack((x[:, np.newaxis], y[:, np.newaxis]))
- mcollections.PolyCollection.set_offsets(self, xy)
- self.stale = True
-
- set_offsets.__doc__ = mcollections.PolyCollection.set_offsets.__doc__
-
- barbs_doc = _barbs_doc
diff --git a/contrib/python/matplotlib/py2/matplotlib/rcsetup.py b/contrib/python/matplotlib/py2/matplotlib/rcsetup.py
deleted file mode 100644
index 902db1c43f..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/rcsetup.py
+++ /dev/null
@@ -1,1452 +0,0 @@
-"""
-The rcsetup module contains the default values and the validation code for
-customization using matplotlib's rc settings.
-
-Each rc setting is assigned a default value and a function used to validate
-any attempted changes to that setting. The default values and validation
-functions are defined in the rcsetup module, and are used to construct the
-rcParams global object which stores the settings and is referenced throughout
-matplotlib.
-
-These default values should be consistent with the default matplotlibrc file
-that actually reflects the values given here. Any additions or deletions to the
-parameter set listed here should also be visited to the
-:file:`matplotlibrc.template` in matplotlib's root source directory.
-"""
-from __future__ import absolute_import, division, print_function
-
-import six
-try:
- from collections.abc import Iterable, Mapping
-except ImportError:
- from collections import Iterable, Mapping
-from functools import reduce
-import operator
-import os
-import warnings
-import re
-
-from matplotlib import cbook, testing
-from matplotlib.cbook import mplDeprecation, deprecated, ls_mapper
-from matplotlib.fontconfig_pattern import parse_fontconfig_pattern
-from matplotlib.colors import is_color_like
-
-# Don't let the original cycler collide with our validating cycler
-from cycler import Cycler, cycler as ccycler
-
-
-# The capitalized forms are needed for ipython at present; this may
-# change for later versions.
-interactive_bk = ['GTK', 'GTKAgg', 'GTKCairo', 'MacOSX',
- 'Qt4Agg', 'Qt5Agg', 'TkAgg', 'WX', 'WXAgg',
- 'GTK3Cairo', 'GTK3Agg', 'WebAgg', 'nbAgg']
-interactive_bk = ['GTK', 'GTKAgg', 'GTKCairo', 'GTK3Agg', 'GTK3Cairo',
- 'MacOSX',
- 'nbAgg',
- 'Qt4Agg', 'Qt4Cairo', 'Qt5Agg', 'Qt5Cairo',
- 'TkAgg', 'TkCairo',
- 'WebAgg',
- 'WX', 'WXAgg', 'WXCairo']
-non_interactive_bk = ['agg', 'cairo', 'gdk',
- 'pdf', 'pgf', 'ps', 'svg', 'template']
-all_backends = interactive_bk + non_interactive_bk
-
-
-class ValidateInStrings(object):
- def __init__(self, key, valid, ignorecase=False):
- 'valid is a list of legal strings'
- self.key = key
- self.ignorecase = ignorecase
-
- def func(s):
- if ignorecase:
- return s.lower()
- else:
- return s
- self.valid = {func(k): k for k in valid}
-
- def __call__(self, s):
- if self.ignorecase:
- s = s.lower()
- if s in self.valid:
- return self.valid[s]
- raise ValueError('Unrecognized %s string "%s": valid strings are %s'
- % (self.key, s, list(six.itervalues(self.valid))))
-
-
-def _listify_validator(scalar_validator, allow_stringlist=False):
- def f(s):
- if isinstance(s, six.string_types):
- try:
- return [scalar_validator(v.strip()) for v in s.split(',')
- if v.strip()]
- except Exception:
- if allow_stringlist:
- # Sometimes, a list of colors might be a single string
- # of single-letter colornames. So give that a shot.
- return [scalar_validator(v.strip()) for v in s if v.strip()]
- else:
- raise
- # We should allow any generic sequence type, including generators,
- # Numpy ndarrays, and pandas data structures. However, unordered
- # sequences, such as sets, should be allowed but discouraged unless the
- # user desires pseudorandom behavior.
- elif isinstance(s, Iterable) and not isinstance(s, Mapping):
- # The condition on this list comprehension will preserve the
- # behavior of filtering out any empty strings (behavior was
- # from the original validate_stringlist()), while allowing
- # any non-string/text scalar values such as numbers and arrays.
- return [scalar_validator(v) for v in s
- if not isinstance(v, six.string_types) or v]
- else:
- raise ValueError("{!r} must be of type: string or non-dictionary "
- "iterable".format(s))
- try:
- f.__name__ = "{}list".format(scalar_validator.__name__)
- except AttributeError: # class instance.
- f.__name__ = "{}List".format(type(scalar_validator).__name__)
- f.__doc__ = scalar_validator.__doc__
- return f
-
-
-def validate_any(s):
- return s
-validate_anylist = _listify_validator(validate_any)
-
-
-def validate_path_exists(s):
- """If s is a path, return s, else False"""
- if s is None:
- return None
- if os.path.exists(s):
- return s
- else:
- raise RuntimeError('"%s" should be a path but it does not exist' % s)
-
-
-def validate_bool(b):
- """Convert b to a boolean or raise"""
- if isinstance(b, six.string_types):
- b = b.lower()
- if b in ('t', 'y', 'yes', 'on', 'true', '1', 1, True):
- return True
- elif b in ('f', 'n', 'no', 'off', 'false', '0', 0, False):
- return False
- else:
- raise ValueError('Could not convert "%s" to boolean' % b)
-
-
-def validate_bool_maybe_none(b):
- 'Convert b to a boolean or raise'
- if isinstance(b, six.string_types):
- b = b.lower()
- if b is None or b == 'none':
- return None
- if b in ('t', 'y', 'yes', 'on', 'true', '1', 1, True):
- return True
- elif b in ('f', 'n', 'no', 'off', 'false', '0', 0, False):
- return False
- else:
- raise ValueError('Could not convert "%s" to boolean' % b)
-
-
-def deprecate_axes_hold(value):
- if value is None:
- return None # converted to True where accessed in figure.py,
- # axes/_base.py
- warnings.warn("axes.hold is deprecated, will be removed in 3.0",
- mplDeprecation)
- return validate_bool(value)
-
-
-def validate_float(s):
- """convert s to float or raise"""
- try:
- return float(s)
- except ValueError:
- raise ValueError('Could not convert "%s" to float' % s)
-validate_floatlist = _listify_validator(validate_float)
-
-
-def validate_float_or_None(s):
- """convert s to float, None or raise"""
- # values directly from the rc file can only be strings,
- # so we need to recognize the string "None" and convert
- # it into the object. We will be case-sensitive here to
- # avoid confusion between string values of 'none', which
- # can be a valid string value for some other parameters.
- if s is None or s == 'None':
- return None
- try:
- return float(s)
- except ValueError:
- raise ValueError('Could not convert "%s" to float or None' % s)
-
-
-def validate_string_or_None(s):
- """convert s to string or raise"""
- if s is None:
- return None
- try:
- return validate_string(s)
- except ValueError:
- raise ValueError('Could not convert "%s" to string' % s)
-
-
-def validate_axisbelow(s):
- try:
- return validate_bool(s)
- except ValueError:
- if isinstance(s, six.string_types):
- s = s.lower()
- if s.startswith('line'):
- return 'line'
- raise ValueError('%s cannot be interpreted as'
- ' True, False, or "line"' % s)
-
-
-def validate_dpi(s):
- """confirm s is string 'figure' or convert s to float or raise"""
- if s == 'figure':
- return s
- try:
- return float(s)
- except ValueError:
- raise ValueError('"%s" is not string "figure" or'
- ' could not convert "%s" to float' % (s, s))
-
-
-def validate_int(s):
- """convert s to int or raise"""
- try:
- return int(s)
- except ValueError:
- raise ValueError('Could not convert "%s" to int' % s)
-
-
-def validate_int_or_None(s):
- """if not None, tries to validate as an int"""
- if s=='None':
- s = None
- if s is None:
- return None
- try:
- return int(s)
- except ValueError:
- raise ValueError('Could not convert "%s" to int' % s)
-
-
-def validate_fonttype(s):
- """
- confirm that this is a Postscript of PDF font type that we know how to
- convert to
- """
- fonttypes = {'type3': 3,
- 'truetype': 42}
- try:
- fonttype = validate_int(s)
- except ValueError:
- try:
- return fonttypes[s.lower()]
- except KeyError:
- raise ValueError(
- 'Supported Postscript/PDF font types are %s' % list(fonttypes))
- else:
- if fonttype not in six.itervalues(fonttypes):
- raise ValueError(
- 'Supported Postscript/PDF font types are %s' %
- list(six.itervalues(fonttypes)))
- return fonttype
-
-
-_validate_standard_backends = ValidateInStrings(
- 'backend', all_backends, ignorecase=True)
-
-
-def validate_backend(s):
- if s.startswith('module://'):
- return s
- else:
- return _validate_standard_backends(s)
-
-
-def validate_qt4(s):
- if s is None:
- return None
- return ValidateInStrings("backend.qt4", ['PyQt4', 'PySide', 'PyQt4v2'])(s)
-
-
-def validate_qt5(s):
- if s is None:
- return None
- return ValidateInStrings("backend.qt5", ['PyQt5', 'PySide2'])(s)
-
-
-def validate_toolbar(s):
- validator = ValidateInStrings(
- 'toolbar',
- ['None', 'toolbar2', 'toolmanager'],
- ignorecase=True)
- return validator(s)
-
-
-_seq_err_msg = ('You must supply exactly {n} values, you provided {num} '
- 'values: {s}')
-
-_str_err_msg = ('You must supply exactly {n} comma-separated values, you '
- 'provided {num} comma-separated values: {s}')
-
-
-class validate_nseq_float(object):
- def __init__(self, n=None, allow_none=False):
- self.n = n
- self.allow_none = allow_none
-
- def __call__(self, s):
- """return a seq of n floats or raise"""
- if isinstance(s, six.string_types):
- s = [x.strip() for x in s.split(',')]
- err_msg = _str_err_msg
- else:
- err_msg = _seq_err_msg
-
- if self.n is not None and len(s) != self.n:
- raise ValueError(err_msg.format(n=self.n, num=len(s), s=s))
-
- try:
- return [float(val)
- if not self.allow_none or val is not None
- else val
- for val in s]
- except ValueError:
- raise ValueError('Could not convert all entries to floats')
-
-
-class validate_nseq_int(object):
- def __init__(self, n=None):
- self.n = n
-
- def __call__(self, s):
- """return a seq of n ints or raise"""
- if isinstance(s, six.string_types):
- s = [x.strip() for x in s.split(',')]
- err_msg = _str_err_msg
- else:
- err_msg = _seq_err_msg
-
- if self.n is not None and len(s) != self.n:
- raise ValueError(err_msg.format(n=self.n, num=len(s), s=s))
-
- try:
- return [int(val) for val in s]
- except ValueError:
- raise ValueError('Could not convert all entries to ints')
-
-
-def validate_color_or_inherit(s):
- 'return a valid color arg'
- if s == 'inherit':
- return s
- return validate_color(s)
-
-
-def validate_color_or_auto(s):
- if s == 'auto':
- return s
- return validate_color(s)
-
-
-def validate_color_for_prop_cycle(s):
- # Special-case the N-th color cycle syntax, this obviously can not
- # go in the color cycle.
- if isinstance(s, bytes):
- match = re.match(b'^C[0-9]$', s)
- if match is not None:
- raise ValueError('Can not put cycle reference ({cn!r}) in '
- 'prop_cycler'.format(cn=s))
- elif isinstance(s, six.string_types):
- match = re.match('^C[0-9]$', s)
- if match is not None:
- raise ValueError('Can not put cycle reference ({cn!r}) in '
- 'prop_cycler'.format(cn=s))
- return validate_color(s)
-
-
-def validate_color(s):
- 'return a valid color arg'
- try:
- if s.lower() == 'none':
- return 'none'
- except AttributeError:
- pass
-
- if isinstance(s, six.string_types):
- if len(s) == 6 or len(s) == 8:
- stmp = '#' + s
- if is_color_like(stmp):
- return stmp
-
- if is_color_like(s):
- return s
-
- # If it is still valid, it must be a tuple.
- colorarg = s
- msg = ''
- if s.find(',') >= 0:
- # get rid of grouping symbols
- stmp = ''.join([c for c in s if c.isdigit() or c == '.' or c == ','])
- vals = stmp.split(',')
- if len(vals) not in [3, 4]:
- msg = '\nColor tuples must be of length 3 or 4'
- else:
- try:
- colorarg = [float(val) for val in vals]
- except ValueError:
- msg = '\nCould not convert all entries to floats'
-
- if not msg and is_color_like(colorarg):
- return colorarg
-
- raise ValueError('%s does not look like a color arg%s' % (s, msg))
-
-
-validate_colorlist = _listify_validator(validate_color, allow_stringlist=True)
-validate_colorlist.__doc__ = 'return a list of colorspecs'
-
-def validate_string(s):
- if isinstance(s, (str, six.text_type)):
- # Always leave str as str and unicode as unicode
- return s
- else:
- return str(s)
-
-validate_stringlist = _listify_validator(str)
-validate_stringlist.__doc__ = 'return a list'
-
-validate_orientation = ValidateInStrings(
- 'orientation', ['landscape', 'portrait'])
-
-
-def validate_aspect(s):
- if s in ('auto', 'equal'):
- return s
- try:
- return float(s)
- except ValueError:
- raise ValueError('not a valid aspect specification')
-
-
-def validate_fontsize(s):
- fontsizes = ['xx-small', 'x-small', 'small', 'medium', 'large',
- 'x-large', 'xx-large', 'smaller', 'larger']
- if isinstance(s, six.string_types):
- s = s.lower()
- if s in fontsizes:
- return s
- try:
- return float(s)
- except ValueError:
- raise ValueError("%s is not a valid font size. Valid font sizes "
- "are %s." % (s, ", ".join(fontsizes)))
-
-
-validate_fontsizelist = _listify_validator(validate_fontsize)
-
-
-def validate_font_properties(s):
- parse_fontconfig_pattern(s)
- return s
-
-
-validate_fontset = ValidateInStrings(
- 'fontset',
- ['dejavusans', 'dejavuserif', 'cm', 'stix', 'stixsans', 'custom'])
-
-validate_mathtext_default = ValidateInStrings(
- 'default',
- "rm cal it tt sf bf default bb frak circled scr regular".split())
-
-validate_verbose = ValidateInStrings(
- 'verbose',
- ['silent', 'helpful', 'debug', 'debug-annoying'])
-
-_validate_alignment = ValidateInStrings(
- 'alignment',
- ['center', 'top', 'bottom', 'baseline',
- 'center_baseline'])
-
-def validate_whiskers(s):
- if s == 'range':
- return 'range'
- else:
- try:
- v = validate_nseq_float(2)(s)
- return v
- except (TypeError, ValueError):
- try:
- v = float(s)
- return v
- except ValueError:
- raise ValueError("Not a valid whisker value ['range', float, "
- "(float, float)]")
-
-
-def update_savefig_format(value):
- # The old savefig.extension could also have a value of "auto", but
- # the new savefig.format does not. We need to fix this here.
- value = validate_string(value)
- if value == 'auto':
- value = 'png'
- return value
-
-
-validate_ps_papersize = ValidateInStrings(
- 'ps_papersize',
- ['auto', 'letter', 'legal', 'ledger',
- 'a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9', 'a10',
- 'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'b10',
- ], ignorecase=True)
-
-
-def validate_ps_distiller(s):
- if isinstance(s, six.string_types):
- s = s.lower()
- if s in ('none', None):
- return None
- elif s in ('false', False):
- return False
- elif s in ('ghostscript', 'xpdf'):
- return s
- else:
- raise ValueError('matplotlibrc ps.usedistiller must either be none, '
- 'ghostscript or xpdf')
-
-validate_joinstyle = ValidateInStrings('joinstyle',
- ['miter', 'round', 'bevel'],
- ignorecase=True)
-validate_joinstylelist = _listify_validator(validate_joinstyle)
-
-validate_capstyle = ValidateInStrings('capstyle',
- ['butt', 'round', 'projecting'],
- ignorecase=True)
-validate_capstylelist = _listify_validator(validate_capstyle)
-
-validate_fillstyle = ValidateInStrings('markers.fillstyle',
- ['full', 'left', 'right', 'bottom',
- 'top', 'none'])
-validate_fillstylelist = _listify_validator(validate_fillstyle)
-
-_validate_negative_linestyle = ValidateInStrings('negative_linestyle',
- ['solid', 'dashed'],
- ignorecase=True)
-
-
-@deprecated('2.1',
- addendum=(" See 'validate_negative_linestyle_legacy' " +
- "deprecation warning for more information."))
-def validate_negative_linestyle(s):
- return _validate_negative_linestyle(s)
-
-
-@deprecated('2.1',
- addendum=(" The 'contour.negative_linestyle' rcParam now " +
- "follows the same validation as the other rcParams " +
- "that are related to line style."))
-def validate_negative_linestyle_legacy(s):
- try:
- res = validate_negative_linestyle(s)
- return res
- except ValueError:
- dashes = validate_nseq_float(2)(s)
- return (0, dashes) # (offset, (solid, blank))
-
-
-validate_legend_loc = ValidateInStrings(
- 'legend_loc',
- ['best',
- 'upper right',
- 'upper left',
- 'lower left',
- 'lower right',
- 'right',
- 'center left',
- 'center right',
- 'lower center',
- 'upper center',
- 'center'], ignorecase=True)
-
-
-def validate_svg_fonttype(s):
- if s in ["none", "path"]:
- return s
- if s == "svgfont":
- cbook.warn_deprecated(
- "2.2", "'svgfont' support for svg.fonttype is deprecated.")
- return s
- raise ValueError("Unrecognized svg.fonttype string '{}'; "
- "valid strings are 'none', 'path'")
-
-
-def validate_hinting(s):
- if s in (True, False):
- return s
- if s.lower() in ('auto', 'native', 'either', 'none'):
- return s.lower()
- raise ValueError("hinting should be 'auto', 'native', 'either' or 'none'")
-
-validate_pgf_texsystem = ValidateInStrings('pgf.texsystem',
- ['xelatex', 'lualatex', 'pdflatex'])
-
-validate_movie_writer = ValidateInStrings('animation.writer',
- ['ffmpeg', 'ffmpeg_file',
- 'avconv', 'avconv_file',
- 'imagemagick', 'imagemagick_file',
- 'html'])
-
-validate_movie_frame_fmt = ValidateInStrings('animation.frame_format',
- ['png', 'jpeg', 'tiff', 'raw', 'rgba'])
-
-validate_axis_locator = ValidateInStrings('major', ['minor', 'both', 'major'])
-
-validate_movie_html_fmt = ValidateInStrings('animation.html',
- ['html5', 'jshtml', 'none'])
-
-def validate_bbox(s):
- if isinstance(s, six.string_types):
- s = s.lower()
- if s == 'tight':
- return s
- if s == 'standard':
- return None
- raise ValueError("bbox should be 'tight' or 'standard'")
- elif s is not None:
- # Backwards compatibility. None is equivalent to 'standard'.
- raise ValueError("bbox should be 'tight' or 'standard'")
- return s
-
-def validate_sketch(s):
- if isinstance(s, six.string_types):
- s = s.lower()
- if s == 'none' or s is None:
- return None
- if isinstance(s, six.string_types):
- result = tuple([float(v.strip()) for v in s.split(',')])
- elif isinstance(s, (list, tuple)):
- result = tuple([float(v) for v in s])
- if len(result) != 3:
- raise ValueError("path.sketch must be a tuple (scale, length, randomness)")
- return result
-
-class ValidateInterval(object):
- """
- Value must be in interval
- """
- def __init__(self, vmin, vmax, closedmin=True, closedmax=True):
- self.vmin = vmin
- self.vmax = vmax
- self.cmin = closedmin
- self.cmax = closedmax
-
- def __call__(self, s):
- try:
- s = float(s)
- except ValueError:
- raise RuntimeError('Value must be a float; found "%s"' % s)
-
- if self.cmin and s < self.vmin:
- raise RuntimeError('Value must be >= %f; found "%f"' %
- (self.vmin, s))
- elif not self.cmin and s <= self.vmin:
- raise RuntimeError('Value must be > %f; found "%f"' %
- (self.vmin, s))
-
- if self.cmax and s > self.vmax:
- raise RuntimeError('Value must be <= %f; found "%f"' %
- (self.vmax, s))
- elif not self.cmax and s >= self.vmax:
- raise RuntimeError('Value must be < %f; found "%f"' %
- (self.vmax, s))
- return s
-
-validate_grid_axis = ValidateInStrings('axes.grid.axis', ['x', 'y', 'both'])
-
-
-def validate_hatch(s):
- """
- Validate a hatch pattern.
- A hatch pattern string can have any sequence of the following
- characters: ``\\ / | - + * . x o O``.
-
- """
- if not isinstance(s, six.string_types):
- raise ValueError("Hatch pattern must be a string")
- unknown = set(s) - {'\\', '/', '|', '-', '+', '*', '.', 'x', 'o', 'O'}
- if unknown:
- raise ValueError("Unknown hatch symbol(s): %s" % list(unknown))
- return s
-validate_hatchlist = _listify_validator(validate_hatch)
-validate_dashlist = _listify_validator(validate_nseq_float(allow_none=True))
-
-_prop_validators = {
- 'color': _listify_validator(validate_color_for_prop_cycle,
- allow_stringlist=True),
- 'linewidth': validate_floatlist,
- 'linestyle': validate_stringlist,
- 'facecolor': validate_colorlist,
- 'edgecolor': validate_colorlist,
- 'joinstyle': validate_joinstylelist,
- 'capstyle': validate_capstylelist,
- 'fillstyle': validate_fillstylelist,
- 'markerfacecolor': validate_colorlist,
- 'markersize': validate_floatlist,
- 'markeredgewidth': validate_floatlist,
- 'markeredgecolor': validate_colorlist,
- 'alpha': validate_floatlist,
- 'marker': validate_stringlist,
- 'hatch': validate_hatchlist,
- 'dashes': validate_dashlist,
- }
-_prop_aliases = {
- 'c': 'color',
- 'lw': 'linewidth',
- 'ls': 'linestyle',
- 'fc': 'facecolor',
- 'ec': 'edgecolor',
- 'mfc': 'markerfacecolor',
- 'mec': 'markeredgecolor',
- 'mew': 'markeredgewidth',
- 'ms': 'markersize',
- }
-
-
-def cycler(*args, **kwargs):
- """
- Creates a `~cycler.Cycler` object much like :func:`cycler.cycler`,
- but includes input validation.
-
- Call signatures::
-
- cycler(cycler)
- cycler(label=values[, label2=values2[, ...]])
- cycler(label, values)
-
- Form 1 copies a given `~cycler.Cycler` object.
-
- Form 2 creates a `~cycler.Cycler` which cycles over one or more
- properties simultaneously. If multiple properties are given, their
- value lists must have the same length.
-
- Form 3 creates a `~cycler.Cycler` for a single property. This form
- exists for compatibility with the original cycler. Its use is
- discouraged in favor of the kwarg form, i.e. ``cycler(label=values)``.
-
- Parameters
- ----------
- cycler : Cycler
- Copy constructor for Cycler.
-
- label : str
- The property key. Must be a valid `.Artist` property.
- For example, 'color' or 'linestyle'. Aliases are allowed,
- such as 'c' for 'color' and 'lw' for 'linewidth'.
-
- values : iterable
- Finite-length iterable of the property values. These values
- are validated and will raise a ValueError if invalid.
-
- Returns
- -------
- cycler : Cycler
- A new :class:`~cycler.Cycler` for the given properties.
-
- Examples
- --------
- Creating a cycler for a single property:
-
- >>> c = cycler(color=['red', 'green', 'blue'])
-
- Creating a cycler for simultaneously cycling over multiple properties
- (e.g. red circle, green plus, blue cross):
-
- >>> c = cycler(color=['red', 'green', 'blue'],
- ... marker=['o', '+', 'x'])
-
- """
- if args and kwargs:
- raise TypeError("cycler() can only accept positional OR keyword "
- "arguments -- not both.")
- elif not args and not kwargs:
- raise TypeError("cycler() must have positional OR keyword arguments")
-
- if len(args) == 1:
- if not isinstance(args[0], Cycler):
- raise TypeError("If only one positional argument given, it must "
- " be a Cycler instance.")
- return validate_cycler(args[0])
- elif len(args) == 2:
- pairs = [(args[0], args[1])]
- elif len(args) > 2:
- raise TypeError("No more than 2 positional arguments allowed")
- else:
- pairs = six.iteritems(kwargs)
-
- validated = []
- for prop, vals in pairs:
- norm_prop = _prop_aliases.get(prop, prop)
- validator = _prop_validators.get(norm_prop, None)
- if validator is None:
- raise TypeError("Unknown artist property: %s" % prop)
- vals = validator(vals)
- # We will normalize the property names as well to reduce
- # the amount of alias handling code elsewhere.
- validated.append((norm_prop, vals))
-
- return reduce(operator.add, (ccycler(k, v) for k, v in validated))
-
-
-def validate_cycler(s):
- 'return a Cycler object from a string repr or the object itself'
- if isinstance(s, six.string_types):
- try:
- # TODO: We might want to rethink this...
- # While I think I have it quite locked down,
- # it is execution of arbitrary code without
- # sanitation.
- # Combine this with the possibility that rcparams
- # might come from the internet (future plans), this
- # could be downright dangerous.
- # I locked it down by only having the 'cycler()' function
- # available.
- # UPDATE: Partly plugging a security hole.
- # I really should have read this:
- # http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html
- # We should replace this eval with a combo of PyParsing and
- # ast.literal_eval()
- if '.__' in s.replace(' ', ''):
- raise ValueError("'%s' seems to have dunder methods. Raising"
- " an exception for your safety")
- s = eval(s, {'cycler': cycler, '__builtins__': {}})
- except BaseException as e:
- raise ValueError("'%s' is not a valid cycler construction: %s" %
- (s, e))
- # Should make sure what comes from the above eval()
- # is a Cycler object.
- if isinstance(s, Cycler):
- cycler_inst = s
- else:
- raise ValueError("object was not a string or Cycler instance: %s" % s)
-
- unknowns = cycler_inst.keys - (set(_prop_validators) | set(_prop_aliases))
- if unknowns:
- raise ValueError("Unknown artist properties: %s" % unknowns)
-
- # Not a full validation, but it'll at least normalize property names
- # A fuller validation would require v0.10 of cycler.
- checker = set()
- for prop in cycler_inst.keys:
- norm_prop = _prop_aliases.get(prop, prop)
- if norm_prop != prop and norm_prop in cycler_inst.keys:
- raise ValueError("Cannot specify both '{0}' and alias '{1}'"
- " in the same prop_cycle".format(norm_prop, prop))
- if norm_prop in checker:
- raise ValueError("Another property was already aliased to '{0}'."
- " Collision normalizing '{1}'.".format(norm_prop,
- prop))
- checker.update([norm_prop])
-
- # This is just an extra-careful check, just in case there is some
- # edge-case I haven't thought of.
- assert len(checker) == len(cycler_inst.keys)
-
- # Now, it should be safe to mutate this cycler
- for prop in cycler_inst.keys:
- norm_prop = _prop_aliases.get(prop, prop)
- cycler_inst.change_key(prop, norm_prop)
-
- for key, vals in cycler_inst.by_key().items():
- _prop_validators[key](vals)
-
- return cycler_inst
-
-
-def validate_hist_bins(s):
- if isinstance(s, six.string_types) and s == 'auto':
- return s
- try:
- return int(s)
- except (TypeError, ValueError):
- pass
-
- try:
- return validate_floatlist(s)
- except ValueError:
- pass
-
- raise ValueError("'hist.bins' must be 'auto', an int or " +
- "a sequence of floats")
-
-def validate_animation_writer_path(p):
- # Make sure it's a string and then figure out if the animations
- # are already loaded and reset the writers (which will validate
- # the path on next call)
- if not isinstance(p, six.string_types):
- raise ValueError("path must be a (unicode) string")
- from sys import modules
- # set dirty, so that the next call to the registry will re-evaluate
- # the state.
- # only set dirty if already loaded. If not loaded, the load will
- # trigger the checks.
- if "matplotlib.animation" in modules:
- modules["matplotlib.animation"].writers.set_dirty()
- return p
-
-def validate_webagg_address(s):
- if s is not None:
- import socket
- try:
- socket.inet_aton(s)
- except socket.error as e:
- raise ValueError("'webagg.address' is not a valid IP address")
- return s
- raise ValueError("'webagg.address' is not a valid IP address")
-
-# A validator dedicated to the named line styles, based on the items in
-# ls_mapper, and a list of possible strings read from Line2D.set_linestyle
-_validate_named_linestyle = ValidateInStrings('linestyle',
- list(six.iterkeys(ls_mapper)) +
- list(six.itervalues(ls_mapper)) +
- ['None', 'none', ' ', ''],
- ignorecase=True)
-
-
-def _validate_linestyle(ls):
- """
- A validator for all possible line styles, the named ones *and*
- the on-off ink sequences.
- """
- # Look first for a valid named line style, like '--' or 'solid'
- if isinstance(ls, six.string_types):
- try:
- return _validate_named_linestyle(ls)
- except (UnicodeDecodeError, KeyError):
- # On Python 2, string-like *ls*, like for example
- # 'solid'.encode('utf-16'), may raise a unicode error.
- raise ValueError("the linestyle string {!r} is not a valid "
- "string.".format(ls))
-
- if isinstance(ls, (bytes, bytearray)):
- # On Python 2, a string-like *ls* should already have lead to a
- # successful return or to raising an exception. On Python 3, we have
- # to manually raise an exception in the case of a byte-like *ls*.
- # Otherwise, if *ls* is of even-length, it will be passed to the
- # instance of validate_nseq_float, which will return an absurd on-off
- # ink sequence...
- raise ValueError("linestyle {!r} neither looks like an on-off ink "
- "sequence nor a valid string.".format(ls))
-
- # Look for an on-off ink sequence (in points) *of even length*.
- # Offset is set to None.
- try:
- if len(ls) % 2 != 0:
- raise ValueError("the linestyle sequence {!r} is not of even "
- "length.".format(ls))
-
- return (None, validate_nseq_float()(ls))
-
- except (ValueError, TypeError):
- # TypeError can be raised inside the instance of validate_nseq_float,
- # by wrong types passed to float(), like NoneType.
- raise ValueError("linestyle {!r} is not a valid on-off ink "
- "sequence.".format(ls))
-
-
-# a map from key -> value, converter
-defaultParams = {
- 'backend': ['Agg', validate_backend], # agg is certainly
- # present
- 'backend_fallback': [True, validate_bool], # agg is certainly present
- 'backend.qt4': [None, validate_qt4],
- 'backend.qt5': [None, validate_qt5],
- 'webagg.port': [8988, validate_int],
- 'webagg.address': ['127.0.0.1', validate_webagg_address],
- 'webagg.open_in_browser': [True, validate_bool],
- 'webagg.port_retries': [50, validate_int],
- 'nbagg.transparent': [True, validate_bool],
- 'toolbar': ['toolbar2', validate_toolbar],
- 'datapath': [None, validate_path_exists], # handled by
- # _get_data_path_cached
- 'interactive': [False, validate_bool],
- 'timezone': ['UTC', validate_string],
-
- # the verbosity setting
- 'verbose.level': ['silent', validate_verbose],
- 'verbose.fileo': ['sys.stdout', validate_string],
-
- # line props
- 'lines.linewidth': [1.5, validate_float], # line width in points
- 'lines.linestyle': ['-', _validate_linestyle], # solid line
- 'lines.color': ['C0', validate_color], # first color in color cycle
- 'lines.marker': ['None', validate_string], # marker name
- 'lines.markeredgewidth': [1.0, validate_float],
- 'lines.markersize': [6, validate_float], # markersize, in points
- 'lines.antialiased': [True, validate_bool], # antialiased (no jaggies)
- 'lines.dash_joinstyle': ['round', validate_joinstyle],
- 'lines.solid_joinstyle': ['round', validate_joinstyle],
- 'lines.dash_capstyle': ['butt', validate_capstyle],
- 'lines.solid_capstyle': ['projecting', validate_capstyle],
- 'lines.dashed_pattern': [[3.7, 1.6], validate_nseq_float(allow_none=True)],
- 'lines.dashdot_pattern': [[6.4, 1.6, 1, 1.6],
- validate_nseq_float(allow_none=True)],
- 'lines.dotted_pattern': [[1, 1.65], validate_nseq_float(allow_none=True)],
- 'lines.scale_dashes': [True, validate_bool],
-
- # marker props
- 'markers.fillstyle': ['full', validate_fillstyle],
-
- ## patch props
- 'patch.linewidth': [1.0, validate_float], # line width in points
- 'patch.edgecolor': ['k', validate_color],
- 'patch.force_edgecolor' : [False, validate_bool],
- 'patch.facecolor': ['C0', validate_color], # first color in cycle
- 'patch.antialiased': [True, validate_bool], # antialiased (no jaggies)
-
- ## hatch props
- 'hatch.color': ['k', validate_color],
- 'hatch.linewidth': [1.0, validate_float],
-
- ## Histogram properties
- 'hist.bins': [10, validate_hist_bins],
-
- ## Boxplot properties
- 'boxplot.notch': [False, validate_bool],
- 'boxplot.vertical': [True, validate_bool],
- 'boxplot.whiskers': [1.5, validate_whiskers],
- 'boxplot.bootstrap': [None, validate_int_or_None],
- 'boxplot.patchartist': [False, validate_bool],
- 'boxplot.showmeans': [False, validate_bool],
- 'boxplot.showcaps': [True, validate_bool],
- 'boxplot.showbox': [True, validate_bool],
- 'boxplot.showfliers': [True, validate_bool],
- 'boxplot.meanline': [False, validate_bool],
-
- 'boxplot.flierprops.color': ['k', validate_color],
- 'boxplot.flierprops.marker': ['o', validate_string],
- 'boxplot.flierprops.markerfacecolor': ['none', validate_color_or_auto],
- 'boxplot.flierprops.markeredgecolor': ['k', validate_color],
- 'boxplot.flierprops.markersize': [6, validate_float],
- 'boxplot.flierprops.linestyle': ['none', _validate_linestyle],
- 'boxplot.flierprops.linewidth': [1.0, validate_float],
-
- 'boxplot.boxprops.color': ['k', validate_color],
- 'boxplot.boxprops.linewidth': [1.0, validate_float],
- 'boxplot.boxprops.linestyle': ['-', _validate_linestyle],
-
- 'boxplot.whiskerprops.color': ['k', validate_color],
- 'boxplot.whiskerprops.linewidth': [1.0, validate_float],
- 'boxplot.whiskerprops.linestyle': ['-', _validate_linestyle],
-
- 'boxplot.capprops.color': ['k', validate_color],
- 'boxplot.capprops.linewidth': [1.0, validate_float],
- 'boxplot.capprops.linestyle': ['-', _validate_linestyle],
-
- 'boxplot.medianprops.color': ['C1', validate_color],
- 'boxplot.medianprops.linewidth': [1.0, validate_float],
- 'boxplot.medianprops.linestyle': ['-', _validate_linestyle],
-
- 'boxplot.meanprops.color': ['C2', validate_color],
- 'boxplot.meanprops.marker': ['^', validate_string],
- 'boxplot.meanprops.markerfacecolor': ['C2', validate_color],
- 'boxplot.meanprops.markeredgecolor': ['C2', validate_color],
- 'boxplot.meanprops.markersize': [6, validate_float],
- 'boxplot.meanprops.linestyle': ['--', _validate_linestyle],
- 'boxplot.meanprops.linewidth': [1.0, validate_float],
-
- ## font props
- 'font.family': [['sans-serif'], validate_stringlist], # used by text object
- 'font.style': ['normal', validate_string],
- 'font.variant': ['normal', validate_string],
- 'font.stretch': ['normal', validate_string],
- 'font.weight': ['normal', validate_string],
- 'font.size': [10, validate_float], # Base font size in points
- 'font.serif': [['DejaVu Serif', 'Bitstream Vera Serif',
- 'Computer Modern Roman',
- 'New Century Schoolbook', 'Century Schoolbook L',
- 'Utopia', 'ITC Bookman', 'Bookman',
- 'Nimbus Roman No9 L', 'Times New Roman',
- 'Times', 'Palatino', 'Charter', 'serif'],
- validate_stringlist],
- 'font.sans-serif': [['DejaVu Sans', 'Bitstream Vera Sans',
- 'Computer Modern Sans Serif',
- 'Lucida Grande', 'Verdana', 'Geneva', 'Lucid',
- 'Arial', 'Helvetica', 'Avant Garde', 'sans-serif'],
- validate_stringlist],
- 'font.cursive': [['Apple Chancery', 'Textile', 'Zapf Chancery',
- 'Sand', 'Script MT', 'Felipa', 'cursive'],
- validate_stringlist],
- 'font.fantasy': [['Comic Sans MS', 'Chicago', 'Charcoal', 'Impact'
- 'Western', 'Humor Sans', 'xkcd', 'fantasy'],
- validate_stringlist],
- 'font.monospace': [['DejaVu Sans Mono', 'Bitstream Vera Sans Mono',
- 'Computer Modern Typewriter',
- 'Andale Mono', 'Nimbus Mono L', 'Courier New',
- 'Courier', 'Fixed', 'Terminal', 'monospace'],
- validate_stringlist],
-
- # text props
- 'text.color': ['k', validate_color], # black
- 'text.usetex': [False, validate_bool],
- 'text.latex.unicode': [False, validate_bool],
- 'text.latex.preamble': [[''], validate_stringlist],
- 'text.latex.preview': [False, validate_bool],
- 'text.dvipnghack': [None, validate_bool_maybe_none],
- 'text.hinting': ['auto', validate_hinting],
- 'text.hinting_factor': [8, validate_int],
- 'text.antialiased': [True, validate_bool],
-
- 'mathtext.cal': ['cursive', validate_font_properties],
- 'mathtext.rm': ['sans', validate_font_properties],
- 'mathtext.tt': ['monospace', validate_font_properties],
- 'mathtext.it': ['sans:italic', validate_font_properties],
- 'mathtext.bf': ['sans:bold', validate_font_properties],
- 'mathtext.sf': ['sans', validate_font_properties],
- 'mathtext.fontset': ['dejavusans', validate_fontset],
- 'mathtext.default': ['it', validate_mathtext_default],
- 'mathtext.fallback_to_cm': [True, validate_bool],
-
- 'image.aspect': ['equal', validate_aspect], # equal, auto, a number
- 'image.interpolation': ['nearest', validate_string],
- 'image.cmap': ['viridis', validate_string], # one of gray, jet, etc
- 'image.lut': [256, validate_int], # lookup table
- 'image.origin': ['upper', validate_string], # lookup table
- 'image.resample': [True, validate_bool],
- # Specify whether vector graphics backends will combine all images on a
- # set of axes into a single composite image
- 'image.composite_image': [True, validate_bool],
-
- # contour props
- 'contour.negative_linestyle': ['dashed', _validate_linestyle],
- 'contour.corner_mask': [True, validate_bool],
-
- # errorbar props
- 'errorbar.capsize': [0, validate_float],
-
- # axes props
- 'axes.axisbelow': ['line', validate_axisbelow],
- 'axes.hold': [None, deprecate_axes_hold],
- 'axes.facecolor': ['w', validate_color], # background color; white
- 'axes.edgecolor': ['k', validate_color], # edge color; black
- 'axes.linewidth': [0.8, validate_float], # edge linewidth
-
- 'axes.spines.left': [True, validate_bool], # Set visibility of axes
- 'axes.spines.right': [True, validate_bool], # 'spines', the lines
- 'axes.spines.bottom': [True, validate_bool], # around the chart
- 'axes.spines.top': [True, validate_bool], # denoting data boundary
-
- 'axes.titlesize': ['large', validate_fontsize], # fontsize of the
- # axes title
- 'axes.titleweight': ['normal', validate_string], # font weight of axes title
- 'axes.titlepad': [6.0, validate_float], # pad from axes top to title in points
- 'axes.grid': [False, validate_bool], # display grid or not
- 'axes.grid.which': ['major', validate_axis_locator], # set whether the gid are by
- # default draw on 'major'
- # 'minor' or 'both' kind of
- # axis locator
- 'axes.grid.axis': ['both', validate_grid_axis], # grid type.
- # Can be 'x', 'y', 'both'
- 'axes.labelsize': ['medium', validate_fontsize], # fontsize of the
- # x any y labels
- 'axes.labelpad': [4.0, validate_float], # space between label and axis
- 'axes.labelweight': ['normal', validate_string], # fontsize of the x any y labels
- 'axes.labelcolor': ['k', validate_color], # color of axis label
- 'axes.formatter.limits': [[-7, 7], validate_nseq_int(2)],
- # use scientific notation if log10
- # of the axis range is smaller than the
- # first or larger than the second
- 'axes.formatter.use_locale': [False, validate_bool],
- # Use the current locale to format ticks
- 'axes.formatter.use_mathtext': [False, validate_bool],
- 'axes.formatter.min_exponent': [0, validate_int], # minimum exponent to format in scientific notation
- 'axes.formatter.useoffset': [True, validate_bool],
- 'axes.formatter.offset_threshold': [4, validate_int],
- 'axes.unicode_minus': [True, validate_bool],
- # This entry can be either a cycler object or a
- # string repr of a cycler-object, which gets eval()'ed
- # to create the object.
- 'axes.prop_cycle': [
- ccycler('color',
- ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728',
- '#9467bd', '#8c564b', '#e377c2', '#7f7f7f',
- '#bcbd22', '#17becf']),
- validate_cycler],
- # If 'data', axes limits are set close to the data.
- # If 'round_numbers' axes limits are set to the nearest round numbers.
- 'axes.autolimit_mode': [
- 'data',
- ValidateInStrings('autolimit_mode', ['data', 'round_numbers'])],
- 'axes.xmargin': [0.05, ValidateInterval(0, 1,
- closedmin=True,
- closedmax=True)], # margin added to xaxis
- 'axes.ymargin': [0.05, ValidateInterval(0, 1,
- closedmin=True,
- closedmax=True)],# margin added to yaxis
-
- 'polaraxes.grid': [True, validate_bool], # display polar grid or
- # not
- 'axes3d.grid': [True, validate_bool], # display 3d grid
-
- # scatter props
- 'scatter.marker': ['o', validate_string],
-
- # TODO validate that these are valid datetime format strings
- 'date.autoformatter.year': ['%Y', validate_string],
- 'date.autoformatter.month': ['%Y-%m', validate_string],
- 'date.autoformatter.day': ['%Y-%m-%d', validate_string],
- 'date.autoformatter.hour': ['%m-%d %H', validate_string],
- 'date.autoformatter.minute': ['%d %H:%M', validate_string],
- 'date.autoformatter.second': ['%H:%M:%S', validate_string],
- 'date.autoformatter.microsecond': ['%M:%S.%f', validate_string],
-
- #legend properties
- 'legend.fancybox': [True, validate_bool],
- 'legend.loc': ['best', validate_legend_loc],
- # the number of points in the legend line
- 'legend.numpoints': [1, validate_int],
- # the number of points in the legend line for scatter
- 'legend.scatterpoints': [1, validate_int],
- 'legend.fontsize': ['medium', validate_fontsize],
- # the relative size of legend markers vs. original
- 'legend.markerscale': [1.0, validate_float],
- 'legend.shadow': [False, validate_bool],
- # whether or not to draw a frame around legend
- 'legend.frameon': [True, validate_bool],
- # alpha value of the legend frame
- 'legend.framealpha': [0.8, validate_float_or_None],
-
- ## the following dimensions are in fraction of the font size
- 'legend.borderpad': [0.4, validate_float], # units are fontsize
- # the vertical space between the legend entries
- 'legend.labelspacing': [0.5, validate_float],
- # the length of the legend lines
- 'legend.handlelength': [2., validate_float],
- # the length of the legend lines
- 'legend.handleheight': [0.7, validate_float],
- # the space between the legend line and legend text
- 'legend.handletextpad': [.8, validate_float],
- # the border between the axes and legend edge
- 'legend.borderaxespad': [0.5, validate_float],
- # the border between the axes and legend edge
- 'legend.columnspacing': [2., validate_float],
- 'legend.facecolor': ['inherit', validate_color_or_inherit],
- 'legend.edgecolor': ['0.8', validate_color_or_inherit],
-
- # tick properties
- 'xtick.top': [False, validate_bool], # draw ticks on the top side
- 'xtick.bottom': [True, validate_bool], # draw ticks on the bottom side
- 'xtick.labeltop': [False, validate_bool], # draw label on the top
- 'xtick.labelbottom': [True, validate_bool], # draw label on the bottom
- 'xtick.major.size': [3.5, validate_float], # major xtick size in points
- 'xtick.minor.size': [2, validate_float], # minor xtick size in points
- 'xtick.major.width': [0.8, validate_float], # major xtick width in points
- 'xtick.minor.width': [0.6, validate_float], # minor xtick width in points
- 'xtick.major.pad': [3.5, validate_float], # distance to label in points
- 'xtick.minor.pad': [3.4, validate_float], # distance to label in points
- 'xtick.color': ['k', validate_color], # color of the xtick labels
- 'xtick.minor.visible': [False, validate_bool], # visibility of the x axis minor ticks
- 'xtick.minor.top': [True, validate_bool], # draw x axis top minor ticks
- 'xtick.minor.bottom': [True, validate_bool], # draw x axis bottom minor ticks
- 'xtick.major.top': [True, validate_bool], # draw x axis top major ticks
- 'xtick.major.bottom': [True, validate_bool], # draw x axis bottom major ticks
-
- # fontsize of the xtick labels
- 'xtick.labelsize': ['medium', validate_fontsize],
- 'xtick.direction': ['out', validate_string], # direction of xticks
- 'xtick.alignment': ["center", _validate_alignment],
-
- 'ytick.left': [True, validate_bool], # draw ticks on the left side
- 'ytick.right': [False, validate_bool], # draw ticks on the right side
- 'ytick.labelleft': [True, validate_bool], # draw tick labels on the left side
- 'ytick.labelright': [False, validate_bool], # draw tick labels on the right side
- 'ytick.major.size': [3.5, validate_float], # major ytick size in points
- 'ytick.minor.size': [2, validate_float], # minor ytick size in points
- 'ytick.major.width': [0.8, validate_float], # major ytick width in points
- 'ytick.minor.width': [0.6, validate_float], # minor ytick width in points
- 'ytick.major.pad': [3.5, validate_float], # distance to label in points
- 'ytick.minor.pad': [3.4, validate_float], # distance to label in points
- 'ytick.color': ['k', validate_color], # color of the ytick labels
- 'ytick.minor.visible': [False, validate_bool], # visibility of the y axis minor ticks
- 'ytick.minor.left': [True, validate_bool], # draw y axis left minor ticks
- 'ytick.minor.right': [True, validate_bool], # draw y axis right minor ticks
- 'ytick.major.left': [True, validate_bool], # draw y axis left major ticks
- 'ytick.major.right': [True, validate_bool], # draw y axis right major ticks
-
- # fontsize of the ytick labels
- 'ytick.labelsize': ['medium', validate_fontsize],
- 'ytick.direction': ['out', validate_string], # direction of yticks
- 'ytick.alignment': ["center_baseline", _validate_alignment],
-
-
- 'grid.color': ['#b0b0b0', validate_color], # grid color
- 'grid.linestyle': ['-', _validate_linestyle], # solid
- 'grid.linewidth': [0.8, validate_float], # in points
- 'grid.alpha': [1.0, validate_float],
-
-
- ## figure props
- # figure title
- 'figure.titlesize': ['large', validate_fontsize],
- 'figure.titleweight': ['normal', validate_string],
-
- # figure size in inches: width by height
- 'figure.figsize': [[6.4, 4.8], validate_nseq_float(2)],
- 'figure.dpi': [100, validate_float], # DPI
- 'figure.facecolor': ['w', validate_color], # facecolor; white
- 'figure.edgecolor': ['w', validate_color], # edgecolor; white
- 'figure.frameon': [True, validate_bool],
- 'figure.autolayout': [False, validate_bool],
- 'figure.max_open_warning': [20, validate_int],
-
- 'figure.subplot.left': [0.125, ValidateInterval(0, 1, closedmin=True,
- closedmax=True)],
- 'figure.subplot.right': [0.9, ValidateInterval(0, 1, closedmin=True,
- closedmax=True)],
- 'figure.subplot.bottom': [0.11, ValidateInterval(0, 1, closedmin=True,
- closedmax=True)],
- 'figure.subplot.top': [0.88, ValidateInterval(0, 1, closedmin=True,
- closedmax=True)],
- 'figure.subplot.wspace': [0.2, ValidateInterval(0, 1, closedmin=True,
- closedmax=False)],
- 'figure.subplot.hspace': [0.2, ValidateInterval(0, 1, closedmin=True,
- closedmax=False)],
-
- # do constrained_layout.
- 'figure.constrained_layout.use': [False, validate_bool],
- # wspace and hspace are fraction of adjacent subplots to use
- # for space. Much smaller than above because we don't need
- # room for the text.
- 'figure.constrained_layout.hspace': [0.02, ValidateInterval(
- 0, 1, closedmin=True, closedmax=False)],
- 'figure.constrained_layout.wspace': [0.02, ValidateInterval(
- 0, 1, closedmin=True, closedmax=False)],
- # This is a buffer around the axes in inches. This is 3pts.
- 'figure.constrained_layout.h_pad': [0.04167, validate_float],
- 'figure.constrained_layout.w_pad': [0.04167, validate_float],
-
- ## Saving figure's properties
- 'savefig.dpi': ['figure', validate_dpi], # DPI
- 'savefig.facecolor': ['w', validate_color], # facecolor; white
- 'savefig.edgecolor': ['w', validate_color], # edgecolor; white
- 'savefig.frameon': [True, validate_bool],
- 'savefig.orientation': ['portrait', validate_orientation], # edgecolor;
- #white
- 'savefig.jpeg_quality': [95, validate_int],
- # value checked by backend at runtime
- 'savefig.format': ['png', update_savefig_format],
- # options are 'tight', or 'standard'. 'standard' validates to None.
- 'savefig.bbox': ['standard', validate_bbox],
- 'savefig.pad_inches': [0.1, validate_float],
- # default directory in savefig dialog box
- 'savefig.directory': ['~', validate_string],
- 'savefig.transparent': [False, validate_bool],
-
- # Maintain shell focus for TkAgg
- 'tk.window_focus': [False, validate_bool],
-
- # Set the papersize/type
- 'ps.papersize': ['letter', validate_ps_papersize],
- 'ps.useafm': [False, validate_bool], # Set PYTHONINSPECT
- # use ghostscript or xpdf to distill ps output
- 'ps.usedistiller': [False, validate_ps_distiller],
- 'ps.distiller.res': [6000, validate_int], # dpi
- 'ps.fonttype': [3, validate_fonttype], # 3 (Type3) or 42 (Truetype)
- # compression level from 0 to 9; 0 to disable
- 'pdf.compression': [6, validate_int],
- # ignore any color-setting commands from the frontend
- 'pdf.inheritcolor': [False, validate_bool],
- # use only the 14 PDF core fonts embedded in every PDF viewing application
- 'pdf.use14corefonts': [False, validate_bool],
- 'pdf.fonttype': [3, validate_fonttype], # 3 (Type3) or 42 (Truetype)
-
- 'pgf.debug': [False, validate_bool], # output debug information
- # choose latex application for creating pdf files (xelatex/lualatex)
- 'pgf.texsystem': ['xelatex', validate_pgf_texsystem],
- # use matplotlib rc settings for font configuration
- 'pgf.rcfonts': [True, validate_bool],
- # provide a custom preamble for the latex process
- 'pgf.preamble': [[''], validate_stringlist],
-
- # write raster image data directly into the svg file
- 'svg.image_inline': [True, validate_bool],
- # True to save all characters as paths in the SVG
- 'svg.fonttype': ['path', validate_svg_fonttype],
- 'svg.hashsalt': [None, validate_string_or_None],
-
- # set this when you want to generate hardcopy docstring
- 'docstring.hardcopy': [False, validate_bool],
- # where plugin directory is locate
- 'plugins.directory': ['.matplotlib_plugins', validate_string],
-
- 'path.simplify': [True, validate_bool],
- 'path.simplify_threshold': [1.0 / 9.0, ValidateInterval(0.0, 1.0)],
- 'path.snap': [True, validate_bool],
- 'path.sketch': [None, validate_sketch],
- 'path.effects': [[], validate_any],
- 'agg.path.chunksize': [0, validate_int], # 0 to disable chunking;
-
- # key-mappings (multi-character mappings should be a list/tuple)
- 'keymap.fullscreen': [('f', 'ctrl+f'), validate_stringlist],
- 'keymap.home': [['h', 'r', 'home'], validate_stringlist],
- 'keymap.back': [['left', 'c', 'backspace'], validate_stringlist],
- 'keymap.forward': [['right', 'v'], validate_stringlist],
- 'keymap.pan': [['p'], validate_stringlist],
- 'keymap.zoom': [['o'], validate_stringlist],
- 'keymap.save': [['s', 'ctrl+s'], validate_stringlist],
- 'keymap.quit': [['ctrl+w', 'cmd+w', 'q'], validate_stringlist],
- 'keymap.quit_all': [['W', 'cmd+W', 'Q'], validate_stringlist],
- 'keymap.grid': [['g'], validate_stringlist],
- 'keymap.grid_minor': [['G'], validate_stringlist],
- 'keymap.yscale': [['l'], validate_stringlist],
- 'keymap.xscale': [['k', 'L'], validate_stringlist],
- 'keymap.all_axes': [['a'], validate_stringlist],
-
- # sample data
- 'examples.directory': ['', validate_string],
-
- # Animation settings
- 'animation.html': ['none', validate_movie_html_fmt],
- # Limit, in MB, of size of base64 encoded animation in HTML
- # (i.e. IPython notebook)
- 'animation.embed_limit': [20, validate_float],
- 'animation.writer': ['ffmpeg', validate_movie_writer],
- 'animation.codec': ['h264', validate_string],
- 'animation.bitrate': [-1, validate_int],
- # Controls image format when frames are written to disk
- 'animation.frame_format': ['png', validate_movie_frame_fmt],
- # Additional arguments for HTML writer
- 'animation.html_args': [[], validate_stringlist],
- # Path to ffmpeg binary. If just binary name, subprocess uses $PATH.
- 'animation.ffmpeg_path': ['ffmpeg', validate_animation_writer_path],
- # Additional arguments for ffmpeg movie writer (using pipes)
- 'animation.ffmpeg_args': [[], validate_stringlist],
- # Path to AVConv binary. If just binary name, subprocess uses $PATH.
- 'animation.avconv_path': ['avconv', validate_animation_writer_path],
- # Additional arguments for avconv movie writer (using pipes)
- 'animation.avconv_args': [[], validate_stringlist],
- # Path to convert binary. If just binary name, subprocess uses $PATH.
- 'animation.convert_path': ['convert', validate_animation_writer_path],
- # Additional arguments for convert movie writer (using pipes)
- 'animation.convert_args': [[], validate_stringlist],
-
- # Classic (pre 2.0) compatibility mode
- # This is used for things that are hard to make backward compatible
- # with a sane rcParam alone. This does *not* turn on classic mode
- # altogether. For that use `matplotlib.style.use('classic')`.
- '_internal.classic_mode': [False, validate_bool]
-}
-
-
-if __name__ == '__main__':
- rc = defaultParams
- rc['datapath'][0] = '/'
- for key in rc:
- if not rc[key][1](rc[key][0]) == rc[key][0]:
- print("%s: %s != %s" % (key, rc[key][1](rc[key][0]), rc[key][0]))
diff --git a/contrib/python/matplotlib/py2/matplotlib/sankey.py b/contrib/python/matplotlib/py2/matplotlib/sankey.py
deleted file mode 100644
index 88def21ce6..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sankey.py
+++ /dev/null
@@ -1,833 +0,0 @@
-"""
-Module for creating Sankey diagrams using matplotlib
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-import logging
-from six.moves import zip
-import numpy as np
-
-from matplotlib.cbook import iterable, Bunch
-from matplotlib.path import Path
-from matplotlib.patches import PathPatch
-from matplotlib.transforms import Affine2D
-from matplotlib import docstring
-from matplotlib import rcParams
-
-_log = logging.getLogger(__name__)
-
-__author__ = "Kevin L. Davies"
-__credits__ = ["Yannick Copin"]
-__license__ = "BSD"
-__version__ = "2011/09/16"
-
-# Angles [deg/90]
-RIGHT = 0
-UP = 1
-# LEFT = 2
-DOWN = 3
-
-
-class Sankey(object):
- """
- Sankey diagram in matplotlib
-
- Sankey diagrams are a specific type of flow diagram, in which
- the width of the arrows is shown proportionally to the flow
- quantity. They are typically used to visualize energy or
- material or cost transfers between processes.
- `Wikipedia (6/1/2011) <https://en.wikipedia.org/wiki/Sankey_diagram>`_
-
- """
-
- def __init__(self, ax=None, scale=1.0, unit='', format='%G', gap=0.25,
- radius=0.1, shoulder=0.03, offset=0.15, head_angle=100,
- margin=0.4, tolerance=1e-6, **kwargs):
- """
- Create a new Sankey instance.
-
- Optional keyword arguments:
-
- =============== ===================================================
- Field Description
- =============== ===================================================
- *ax* axes onto which the data should be plotted
- If *ax* isn't provided, new axes will be created.
- *scale* scaling factor for the flows
- *scale* sizes the width of the paths in order to
- maintain proper layout. The same scale is applied
- to all subdiagrams. The value should be chosen
- such that the product of the scale and the sum of
- the inputs is approximately 1.0 (and the product of
- the scale and the sum of the outputs is
- approximately -1.0).
- *unit* string representing the physical unit associated
- with the flow quantities
- If *unit* is None, then none of the quantities are
- labeled.
- *format* a Python number formatting string to be used in
- labeling the flow as a quantity (i.e., a number
- times a unit, where the unit is given)
- *gap* space between paths that break in/break away
- to/from the top or bottom
- *radius* inner radius of the vertical paths
- *shoulder* size of the shoulders of output arrowS
- *offset* text offset (from the dip or tip of the arrow)
- *head_angle* angle of the arrow heads (and negative of the angle
- of the tails) [deg]
- *margin* minimum space between Sankey outlines and the edge
- of the plot area
- *tolerance* acceptable maximum of the magnitude of the sum of
- flows
- The magnitude of the sum of connected flows cannot
- be greater than *tolerance*.
- =============== ===================================================
-
- The optional arguments listed above are applied to all subdiagrams so
- that there is consistent alignment and formatting.
-
- If :class:`Sankey` is instantiated with any keyword arguments other
- than those explicitly listed above (``**kwargs``), they will be passed
- to :meth:`add`, which will create the first subdiagram.
-
- In order to draw a complex Sankey diagram, create an instance of
- :class:`Sankey` by calling it without any kwargs::
-
- sankey = Sankey()
-
- Then add simple Sankey sub-diagrams::
-
- sankey.add() # 1
- sankey.add() # 2
- #...
- sankey.add() # n
-
- Finally, create the full diagram::
-
- sankey.finish()
-
- Or, instead, simply daisy-chain those calls::
-
- Sankey().add().add... .add().finish()
-
- .. seealso::
-
- :meth:`add`
- :meth:`finish`
-
-
- **Examples:**
-
- .. plot:: gallery/api/sankey_basics.py
- """
- # Check the arguments.
- if gap < 0:
- raise ValueError(
- "The gap is negative.\nThis isn't allowed because it "
- "would cause the paths to overlap.")
- if radius > gap:
- raise ValueError(
- "The inner radius is greater than the path spacing.\n"
- "This isn't allowed because it would cause the paths to overlap.")
- if head_angle < 0:
- raise ValueError(
- "The angle is negative.\nThis isn't allowed "
- "because it would cause inputs to look like "
- "outputs and vice versa.")
- if tolerance < 0:
- raise ValueError(
- "The tolerance is negative.\nIt must be a magnitude.")
-
- # Create axes if necessary.
- if ax is None:
- import matplotlib.pyplot as plt
- fig = plt.figure()
- ax = fig.add_subplot(1, 1, 1, xticks=[], yticks=[])
-
- self.diagrams = []
-
- # Store the inputs.
- self.ax = ax
- self.unit = unit
- self.format = format
- self.scale = scale
- self.gap = gap
- self.radius = radius
- self.shoulder = shoulder
- self.offset = offset
- self.margin = margin
- self.pitch = np.tan(np.pi * (1 - head_angle / 180.0) / 2.0)
- self.tolerance = tolerance
-
- # Initialize the vertices of tight box around the diagram(s).
- self.extent = np.array((np.inf, -np.inf, np.inf, -np.inf))
-
- # If there are any kwargs, create the first subdiagram.
- if len(kwargs):
- self.add(**kwargs)
-
- def _arc(self, quadrant=0, cw=True, radius=1, center=(0, 0)):
- """
- Return the codes and vertices for a rotated, scaled, and translated
- 90 degree arc.
-
- Optional keyword arguments:
-
- =============== ==========================================
- Keyword Description
- =============== ==========================================
- *quadrant* uses 0-based indexing (0, 1, 2, or 3)
- *cw* if True, clockwise
- *center* (x, y) tuple of the arc's center
- =============== ==========================================
- """
- # Note: It would be possible to use matplotlib's transforms to rotate,
- # scale, and translate the arc, but since the angles are discrete,
- # it's just as easy and maybe more efficient to do it here.
- ARC_CODES = [Path.LINETO,
- Path.CURVE4,
- Path.CURVE4,
- Path.CURVE4,
- Path.CURVE4,
- Path.CURVE4,
- Path.CURVE4]
- # Vertices of a cubic Bezier curve approximating a 90 deg arc
- # These can be determined by Path.arc(0,90).
- ARC_VERTICES = np.array([[1.00000000e+00, 0.00000000e+00],
- [1.00000000e+00, 2.65114773e-01],
- [8.94571235e-01, 5.19642327e-01],
- [7.07106781e-01, 7.07106781e-01],
- [5.19642327e-01, 8.94571235e-01],
- [2.65114773e-01, 1.00000000e+00],
- # Insignificant
- # [6.12303177e-17, 1.00000000e+00]])
- [0.00000000e+00, 1.00000000e+00]])
- if quadrant == 0 or quadrant == 2:
- if cw:
- vertices = ARC_VERTICES
- else:
- vertices = ARC_VERTICES[:, ::-1] # Swap x and y.
- elif quadrant == 1 or quadrant == 3:
- # Negate x.
- if cw:
- # Swap x and y.
- vertices = np.column_stack((-ARC_VERTICES[:, 1],
- ARC_VERTICES[:, 0]))
- else:
- vertices = np.column_stack((-ARC_VERTICES[:, 0],
- ARC_VERTICES[:, 1]))
- if quadrant > 1:
- radius = -radius # Rotate 180 deg.
- return list(zip(ARC_CODES, radius * vertices +
- np.tile(center, (ARC_VERTICES.shape[0], 1))))
-
- def _add_input(self, path, angle, flow, length):
- """
- Add an input to a path and return its tip and label locations.
- """
- if angle is None:
- return [0, 0], [0, 0]
- else:
- x, y = path[-1][1] # Use the last point as a reference.
- dipdepth = (flow / 2) * self.pitch
- if angle == RIGHT:
- x -= length
- dip = [x + dipdepth, y + flow / 2.0]
- path.extend([(Path.LINETO, [x, y]),
- (Path.LINETO, dip),
- (Path.LINETO, [x, y + flow]),
- (Path.LINETO, [x + self.gap, y + flow])])
- label_location = [dip[0] - self.offset, dip[1]]
- else: # Vertical
- x -= self.gap
- if angle == UP:
- sign = 1
- else:
- sign = -1
-
- dip = [x - flow / 2, y - sign * (length - dipdepth)]
- if angle == DOWN:
- quadrant = 2
- else:
- quadrant = 1
-
- # Inner arc isn't needed if inner radius is zero
- if self.radius:
- path.extend(self._arc(quadrant=quadrant,
- cw=angle == UP,
- radius=self.radius,
- center=(x + self.radius,
- y - sign * self.radius)))
- else:
- path.append((Path.LINETO, [x, y]))
- path.extend([(Path.LINETO, [x, y - sign * length]),
- (Path.LINETO, dip),
- (Path.LINETO, [x - flow, y - sign * length])])
- path.extend(self._arc(quadrant=quadrant,
- cw=angle == DOWN,
- radius=flow + self.radius,
- center=(x + self.radius,
- y - sign * self.radius)))
- path.append((Path.LINETO, [x - flow, y + sign * flow]))
- label_location = [dip[0], dip[1] - sign * self.offset]
-
- return dip, label_location
-
- def _add_output(self, path, angle, flow, length):
- """
- Append an output to a path and return its tip and label locations.
-
- .. note:: *flow* is negative for an output.
- """
- if angle is None:
- return [0, 0], [0, 0]
- else:
- x, y = path[-1][1] # Use the last point as a reference.
- tipheight = (self.shoulder - flow / 2) * self.pitch
- if angle == RIGHT:
- x += length
- tip = [x + tipheight, y + flow / 2.0]
- path.extend([(Path.LINETO, [x, y]),
- (Path.LINETO, [x, y + self.shoulder]),
- (Path.LINETO, tip),
- (Path.LINETO, [x, y - self.shoulder + flow]),
- (Path.LINETO, [x, y + flow]),
- (Path.LINETO, [x - self.gap, y + flow])])
- label_location = [tip[0] + self.offset, tip[1]]
- else: # Vertical
- x += self.gap
- if angle == UP:
- sign = 1
- else:
- sign = -1
-
- tip = [x - flow / 2.0, y + sign * (length + tipheight)]
- if angle == UP:
- quadrant = 3
- else:
- quadrant = 0
- # Inner arc isn't needed if inner radius is zero
- if self.radius:
- path.extend(self._arc(quadrant=quadrant,
- cw=angle == UP,
- radius=self.radius,
- center=(x - self.radius,
- y + sign * self.radius)))
- else:
- path.append((Path.LINETO, [x, y]))
- path.extend([(Path.LINETO, [x, y + sign * length]),
- (Path.LINETO, [x - self.shoulder,
- y + sign * length]),
- (Path.LINETO, tip),
- (Path.LINETO, [x + self.shoulder - flow,
- y + sign * length]),
- (Path.LINETO, [x - flow, y + sign * length])])
- path.extend(self._arc(quadrant=quadrant,
- cw=angle == DOWN,
- radius=self.radius - flow,
- center=(x - self.radius,
- y + sign * self.radius)))
- path.append((Path.LINETO, [x - flow, y + sign * flow]))
- label_location = [tip[0], tip[1] + sign * self.offset]
- return tip, label_location
-
- def _revert(self, path, first_action=Path.LINETO):
- """
- A path is not simply revertable by path[::-1] since the code
- specifies an action to take from the **previous** point.
- """
- reverse_path = []
- next_code = first_action
- for code, position in path[::-1]:
- reverse_path.append((next_code, position))
- next_code = code
- return reverse_path
- # This might be more efficient, but it fails because 'tuple' object
- # doesn't support item assignment:
- # path[1] = path[1][-1:0:-1]
- # path[1][0] = first_action
- # path[2] = path[2][::-1]
- # return path
-
- @docstring.dedent_interpd
- def add(self, patchlabel='', flows=None, orientations=None, labels='',
- trunklength=1.0, pathlengths=0.25, prior=None, connect=(0, 0),
- rotation=0, **kwargs):
- """
- Add a simple Sankey diagram with flows at the same hierarchical level.
-
- Return value is the instance of :class:`Sankey`.
-
- Optional keyword arguments:
-
- =============== ===================================================
- Keyword Description
- =============== ===================================================
- *patchlabel* label to be placed at the center of the diagram
- Note: *label* (not *patchlabel*) will be passed to
- the patch through ``**kwargs`` and can be used to
- create an entry in the legend.
- *flows* array of flow values
- By convention, inputs are positive and outputs are
- negative.
- *orientations* list of orientations of the paths
- Valid values are 1 (from/to the top), 0 (from/to
- the left or right), or -1 (from/to the bottom). If
- *orientations* == 0, inputs will break in from the
- left and outputs will break away to the right.
- *labels* list of specifications of the labels for the flows
- Each value may be *None* (no labels), '' (just
- label the quantities), or a labeling string. If a
- single value is provided, it will be applied to all
- flows. If an entry is a non-empty string, then the
- quantity for the corresponding flow will be shown
- below the string. However, if the *unit* of the
- main diagram is None, then quantities are never
- shown, regardless of the value of this argument.
- *trunklength* length between the bases of the input and output
- groups
- *pathlengths* list of lengths of the arrows before break-in or
- after break-away
- If a single value is given, then it will be applied
- to the first (inside) paths on the top and bottom,
- and the length of all other arrows will be
- justified accordingly. The *pathlengths* are not
- applied to the horizontal inputs and outputs.
- *prior* index of the prior diagram to which this diagram
- should be connected
- *connect* a (prior, this) tuple indexing the flow of the
- prior diagram and the flow of this diagram which
- should be connected
- If this is the first diagram or *prior* is *None*,
- *connect* will be ignored.
- *rotation* angle of rotation of the diagram [deg]
- *rotation* is ignored if this diagram is connected
- to an existing one (using *prior* and *connect*).
- The interpretation of the *orientations* argument
- will be rotated accordingly (e.g., if *rotation*
- == 90, an *orientations* entry of 1 means to/from
- the left).
- =============== ===================================================
-
- Valid kwargs are :meth:`matplotlib.patches.PathPatch` arguments:
-
- %(Patch)s
-
- As examples, ``fill=False`` and ``label='A legend entry'``.
- By default, ``facecolor='#bfd1d4'`` (light blue) and
- ``linewidth=0.5``.
-
- The indexing parameters (*prior* and *connect*) are zero-based.
-
- The flows are placed along the top of the diagram from the inside out
- in order of their index within the *flows* list or array. They are
- placed along the sides of the diagram from the top down and along the
- bottom from the outside in.
-
- If the sum of the inputs and outputs is nonzero, the discrepancy
- will appear as a cubic Bezier curve along the top and bottom edges of
- the trunk.
-
- .. seealso::
-
- :meth:`finish`
- """
- # Check and preprocess the arguments.
- if flows is None:
- flows = np.array([1.0, -1.0])
- else:
- flows = np.array(flows)
- n = flows.shape[0] # Number of flows
- if rotation is None:
- rotation = 0
- else:
- # In the code below, angles are expressed in deg/90.
- rotation /= 90.0
- if orientations is None:
- orientations = [0, 0]
- if len(orientations) != n:
- raise ValueError(
- "orientations and flows must have the same length.\n"
- "orientations has length %d, but flows has length %d."
- % (len(orientations), n))
- if labels != '' and getattr(labels, '__iter__', False):
- # iterable() isn't used because it would give True if labels is a
- # string
- if len(labels) != n:
- raise ValueError(
- "If labels is a list, then labels and flows must have the "
- "same length.\nlabels has length %d, but flows has length %d."
- % (len(labels), n))
- else:
- labels = [labels] * n
- if trunklength < 0:
- raise ValueError(
- "trunklength is negative.\nThis isn't allowed, because it would "
- "cause poor layout.")
- if np.abs(np.sum(flows)) > self.tolerance:
- _log.info("The sum of the flows is nonzero (%f).\nIs the "
- "system not at steady state?", np.sum(flows))
- scaled_flows = self.scale * flows
- gain = sum(max(flow, 0) for flow in scaled_flows)
- loss = sum(min(flow, 0) for flow in scaled_flows)
- if not (0.5 <= gain <= 2.0):
- _log.info(
- "The scaled sum of the inputs is %f.\nThis may "
- "cause poor layout.\nConsider changing the scale so"
- " that the scaled sum is approximately 1.0.", gain)
- if not (-2.0 <= loss <= -0.5):
- _log.info(
- "The scaled sum of the outputs is %f.\nThis may "
- "cause poor layout.\nConsider changing the scale so"
- " that the scaled sum is approximately 1.0.", gain)
- if prior is not None:
- if prior < 0:
- raise ValueError("The index of the prior diagram is negative.")
- if min(connect) < 0:
- raise ValueError(
- "At least one of the connection indices is negative.")
- if prior >= len(self.diagrams):
- raise ValueError(
- "The index of the prior diagram is %d, but there are "
- "only %d other diagrams.\nThe index is zero-based."
- % (prior, len(self.diagrams)))
- if connect[0] >= len(self.diagrams[prior].flows):
- raise ValueError(
- "The connection index to the source diagram is %d, but "
- "that diagram has only %d flows.\nThe index is zero-based."
- % (connect[0], len(self.diagrams[prior].flows)))
- if connect[1] >= n:
- raise ValueError(
- "The connection index to this diagram is %d, but this diagram"
- "has only %d flows.\n The index is zero-based."
- % (connect[1], n))
- if self.diagrams[prior].angles[connect[0]] is None:
- raise ValueError(
- "The connection cannot be made. Check that the magnitude "
- "of flow %d of diagram %d is greater than or equal to the "
- "specified tolerance." % (connect[0], prior))
- flow_error = (self.diagrams[prior].flows[connect[0]] +
- flows[connect[1]])
- if abs(flow_error) >= self.tolerance:
- raise ValueError(
- "The scaled sum of the connected flows is %f, which is not "
- "within the tolerance (%f)." % (flow_error, self.tolerance))
-
- # Determine if the flows are inputs.
- are_inputs = [None] * n
- for i, flow in enumerate(flows):
- if flow >= self.tolerance:
- are_inputs[i] = True
- elif flow <= -self.tolerance:
- are_inputs[i] = False
- else:
- _log.info(
- "The magnitude of flow %d (%f) is below the "
- "tolerance (%f).\nIt will not be shown, and it "
- "cannot be used in a connection."
- % (i, flow, self.tolerance))
-
- # Determine the angles of the arrows (before rotation).
- angles = [None] * n
- for i, (orient, is_input) in enumerate(zip(orientations, are_inputs)):
- if orient == 1:
- if is_input:
- angles[i] = DOWN
- elif not is_input:
- # Be specific since is_input can be None.
- angles[i] = UP
- elif orient == 0:
- if is_input is not None:
- angles[i] = RIGHT
- else:
- if orient != -1:
- raise ValueError(
- "The value of orientations[%d] is %d, "
- "but it must be [ -1 | 0 | 1 ]." % (i, orient))
- if is_input:
- angles[i] = UP
- elif not is_input:
- angles[i] = DOWN
-
- # Justify the lengths of the paths.
- if iterable(pathlengths):
- if len(pathlengths) != n:
- raise ValueError(
- "If pathlengths is a list, then pathlengths and flows must "
- "have the same length.\npathlengths has length %d, but flows "
- "has length %d." % (len(pathlengths), n))
- else: # Make pathlengths into a list.
- urlength = pathlengths
- ullength = pathlengths
- lrlength = pathlengths
- lllength = pathlengths
- d = dict(RIGHT=pathlengths)
- pathlengths = [d.get(angle, 0) for angle in angles]
- # Determine the lengths of the top-side arrows
- # from the middle outwards.
- for i, (angle, is_input, flow) in enumerate(zip(angles, are_inputs,
- scaled_flows)):
- if angle == DOWN and is_input:
- pathlengths[i] = ullength
- ullength += flow
- elif angle == UP and not is_input:
- pathlengths[i] = urlength
- urlength -= flow # Flow is negative for outputs.
- # Determine the lengths of the bottom-side arrows
- # from the middle outwards.
- for i, (angle, is_input, flow) in enumerate(reversed(list(zip(
- angles, are_inputs, scaled_flows)))):
- if angle == UP and is_input:
- pathlengths[n - i - 1] = lllength
- lllength += flow
- elif angle == DOWN and not is_input:
- pathlengths[n - i - 1] = lrlength
- lrlength -= flow
- # Determine the lengths of the left-side arrows
- # from the bottom upwards.
- has_left_input = False
- for i, (angle, is_input, spec) in enumerate(reversed(list(zip(
- angles, are_inputs, zip(scaled_flows, pathlengths))))):
- if angle == RIGHT:
- if is_input:
- if has_left_input:
- pathlengths[n - i - 1] = 0
- else:
- has_left_input = True
- # Determine the lengths of the right-side arrows
- # from the top downwards.
- has_right_output = False
- for i, (angle, is_input, spec) in enumerate(zip(
- angles, are_inputs, list(zip(scaled_flows, pathlengths)))):
- if angle == RIGHT:
- if not is_input:
- if has_right_output:
- pathlengths[i] = 0
- else:
- has_right_output = True
-
- # Begin the subpaths, and smooth the transition if the sum of the flows
- # is nonzero.
- urpath = [(Path.MOVETO, [(self.gap - trunklength / 2.0), # Upper right
- gain / 2.0]),
- (Path.LINETO, [(self.gap - trunklength / 2.0) / 2.0,
- gain / 2.0]),
- (Path.CURVE4, [(self.gap - trunklength / 2.0) / 8.0,
- gain / 2.0]),
- (Path.CURVE4, [(trunklength / 2.0 - self.gap) / 8.0,
- -loss / 2.0]),
- (Path.LINETO, [(trunklength / 2.0 - self.gap) / 2.0,
- -loss / 2.0]),
- (Path.LINETO, [(trunklength / 2.0 - self.gap),
- -loss / 2.0])]
- llpath = [(Path.LINETO, [(trunklength / 2.0 - self.gap), # Lower left
- loss / 2.0]),
- (Path.LINETO, [(trunklength / 2.0 - self.gap) / 2.0,
- loss / 2.0]),
- (Path.CURVE4, [(trunklength / 2.0 - self.gap) / 8.0,
- loss / 2.0]),
- (Path.CURVE4, [(self.gap - trunklength / 2.0) / 8.0,
- -gain / 2.0]),
- (Path.LINETO, [(self.gap - trunklength / 2.0) / 2.0,
- -gain / 2.0]),
- (Path.LINETO, [(self.gap - trunklength / 2.0),
- -gain / 2.0])]
- lrpath = [(Path.LINETO, [(trunklength / 2.0 - self.gap), # Lower right
- loss / 2.0])]
- ulpath = [(Path.LINETO, [self.gap - trunklength / 2.0, # Upper left
- gain / 2.0])]
-
- # Add the subpaths and assign the locations of the tips and labels.
- tips = np.zeros((n, 2))
- label_locations = np.zeros((n, 2))
- # Add the top-side inputs and outputs from the middle outwards.
- for i, (angle, is_input, spec) in enumerate(zip(
- angles, are_inputs, list(zip(scaled_flows, pathlengths)))):
- if angle == DOWN and is_input:
- tips[i, :], label_locations[i, :] = self._add_input(
- ulpath, angle, *spec)
- elif angle == UP and not is_input:
- tips[i, :], label_locations[i, :] = self._add_output(
- urpath, angle, *spec)
- # Add the bottom-side inputs and outputs from the middle outwards.
- for i, (angle, is_input, spec) in enumerate(reversed(list(zip(
- angles, are_inputs, list(zip(scaled_flows, pathlengths)))))):
- if angle == UP and is_input:
- tip, label_location = self._add_input(llpath, angle, *spec)
- tips[n - i - 1, :] = tip
- label_locations[n - i - 1, :] = label_location
- elif angle == DOWN and not is_input:
- tip, label_location = self._add_output(lrpath, angle, *spec)
- tips[n - i - 1, :] = tip
- label_locations[n - i - 1, :] = label_location
- # Add the left-side inputs from the bottom upwards.
- has_left_input = False
- for i, (angle, is_input, spec) in enumerate(reversed(list(zip(
- angles, are_inputs, list(zip(scaled_flows, pathlengths)))))):
- if angle == RIGHT and is_input:
- if not has_left_input:
- # Make sure the lower path extends
- # at least as far as the upper one.
- if llpath[-1][1][0] > ulpath[-1][1][0]:
- llpath.append((Path.LINETO, [ulpath[-1][1][0],
- llpath[-1][1][1]]))
- has_left_input = True
- tip, label_location = self._add_input(llpath, angle, *spec)
- tips[n - i - 1, :] = tip
- label_locations[n - i - 1, :] = label_location
- # Add the right-side outputs from the top downwards.
- has_right_output = False
- for i, (angle, is_input, spec) in enumerate(zip(
- angles, are_inputs, list(zip(scaled_flows, pathlengths)))):
- if angle == RIGHT and not is_input:
- if not has_right_output:
- # Make sure the upper path extends
- # at least as far as the lower one.
- if urpath[-1][1][0] < lrpath[-1][1][0]:
- urpath.append((Path.LINETO, [lrpath[-1][1][0],
- urpath[-1][1][1]]))
- has_right_output = True
- tips[i, :], label_locations[i, :] = self._add_output(
- urpath, angle, *spec)
- # Trim any hanging vertices.
- if not has_left_input:
- ulpath.pop()
- llpath.pop()
- if not has_right_output:
- lrpath.pop()
- urpath.pop()
-
- # Concatenate the subpaths in the correct order (clockwise from top).
- path = (urpath + self._revert(lrpath) + llpath + self._revert(ulpath) +
- [(Path.CLOSEPOLY, urpath[0][1])])
-
- # Create a patch with the Sankey outline.
- codes, vertices = zip(*path)
- vertices = np.array(vertices)
-
- def _get_angle(a, r):
- if a is None:
- return None
- else:
- return a + r
-
- if prior is None:
- if rotation != 0: # By default, none of this is needed.
- angles = [_get_angle(angle, rotation) for angle in angles]
- rotate = Affine2D().rotate_deg(rotation * 90).transform_affine
- tips = rotate(tips)
- label_locations = rotate(label_locations)
- vertices = rotate(vertices)
- text = self.ax.text(0, 0, s=patchlabel, ha='center', va='center')
- else:
- rotation = (self.diagrams[prior].angles[connect[0]] -
- angles[connect[1]])
- angles = [_get_angle(angle, rotation) for angle in angles]
- rotate = Affine2D().rotate_deg(rotation * 90).transform_affine
- tips = rotate(tips)
- offset = self.diagrams[prior].tips[connect[0]] - tips[connect[1]]
- translate = Affine2D().translate(*offset).transform_affine
- tips = translate(tips)
- label_locations = translate(rotate(label_locations))
- vertices = translate(rotate(vertices))
- kwds = dict(s=patchlabel, ha='center', va='center')
- text = self.ax.text(*offset, **kwds)
- if rcParams['_internal.classic_mode']:
- fc = kwargs.pop('fc', kwargs.pop('facecolor', '#bfd1d4'))
- lw = kwargs.pop('lw', kwargs.pop('linewidth', 0.5))
- else:
- fc = kwargs.pop('fc', kwargs.pop('facecolor', None))
- lw = kwargs.pop('lw', kwargs.pop('linewidth', None))
- if fc is None:
- fc = next(self.ax._get_patches_for_fill.prop_cycler)['color']
- patch = PathPatch(Path(vertices, codes), fc=fc, lw=lw, **kwargs)
- self.ax.add_patch(patch)
-
- # Add the path labels.
- texts = []
- for number, angle, label, location in zip(flows, angles, labels,
- label_locations):
- if label is None or angle is None:
- label = ''
- elif self.unit is not None:
- quantity = self.format % abs(number) + self.unit
- if label != '':
- label += "\n"
- label += quantity
- texts.append(self.ax.text(x=location[0], y=location[1],
- s=label,
- ha='center', va='center'))
- # Text objects are placed even they are empty (as long as the magnitude
- # of the corresponding flow is larger than the tolerance) in case the
- # user wants to provide labels later.
-
- # Expand the size of the diagram if necessary.
- self.extent = (min(np.min(vertices[:, 0]),
- np.min(label_locations[:, 0]),
- self.extent[0]),
- max(np.max(vertices[:, 0]),
- np.max(label_locations[:, 0]),
- self.extent[1]),
- min(np.min(vertices[:, 1]),
- np.min(label_locations[:, 1]),
- self.extent[2]),
- max(np.max(vertices[:, 1]),
- np.max(label_locations[:, 1]),
- self.extent[3]))
- # Include both vertices _and_ label locations in the extents; there are
- # where either could determine the margins (e.g., arrow shoulders).
-
- # Add this diagram as a subdiagram.
- self.diagrams.append(Bunch(patch=patch, flows=flows, angles=angles,
- tips=tips, text=text, texts=texts))
-
- # Allow a daisy-chained call structure (see docstring for the class).
- return self
-
- def finish(self):
- """
- Adjust the axes and return a list of information about the Sankey
- subdiagram(s).
-
- Return value is a list of subdiagrams represented with the following
- fields:
-
- =============== ===================================================
- Field Description
- =============== ===================================================
- *patch* Sankey outline (an instance of
- :class:`~maplotlib.patches.PathPatch`)
- *flows* values of the flows (positive for input, negative
- for output)
- *angles* list of angles of the arrows [deg/90]
- For example, if the diagram has not been rotated,
- an input to the top side will have an angle of 3
- (DOWN), and an output from the top side will have
- an angle of 1 (UP). If a flow has been skipped
- (because its magnitude is less than *tolerance*),
- then its angle will be *None*.
- *tips* array in which each row is an [x, y] pair
- indicating the positions of the tips (or "dips") of
- the flow paths
- If the magnitude of a flow is less the *tolerance*
- for the instance of :class:`Sankey`, the flow is
- skipped and its tip will be at the center of the
- diagram.
- *text* :class:`~matplotlib.text.Text` instance for the
- label of the diagram
- *texts* list of :class:`~matplotlib.text.Text` instances
- for the labels of flows
- =============== ===================================================
-
- .. seealso::
-
- :meth:`add`
- """
- self.ax.axis([self.extent[0] - self.margin,
- self.extent[1] + self.margin,
- self.extent[2] - self.margin,
- self.extent[3] + self.margin])
- self.ax.set_aspect('equal', adjustable='datalim')
- return self.diagrams
diff --git a/contrib/python/matplotlib/py2/matplotlib/scale.py b/contrib/python/matplotlib/py2/matplotlib/scale.py
deleted file mode 100644
index 357aff9fc2..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/scale.py
+++ /dev/null
@@ -1,607 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import numpy as np
-from numpy import ma
-
-from matplotlib import cbook, docstring, rcParams
-from matplotlib.ticker import (
- NullFormatter, ScalarFormatter, LogFormatterSciNotation, LogitFormatter,
- NullLocator, LogLocator, AutoLocator, AutoMinorLocator,
- SymmetricalLogLocator, LogitLocator)
-from matplotlib.transforms import Transform, IdentityTransform
-
-
-class ScaleBase(object):
- """
- The base class for all scales.
-
- Scales are separable transformations, working on a single dimension.
-
- Any subclasses will want to override:
-
- - :attr:`name`
- - :meth:`get_transform`
- - :meth:`set_default_locators_and_formatters`
-
- And optionally:
- - :meth:`limit_range_for_scale`
- """
- def get_transform(self):
- """
- Return the :class:`~matplotlib.transforms.Transform` object
- associated with this scale.
- """
- raise NotImplementedError()
-
- def set_default_locators_and_formatters(self, axis):
- """
- Set the :class:`~matplotlib.ticker.Locator` and
- :class:`~matplotlib.ticker.Formatter` objects on the given
- axis to match this scale.
- """
- raise NotImplementedError()
-
- def limit_range_for_scale(self, vmin, vmax, minpos):
- """
- Returns the range *vmin*, *vmax*, possibly limited to the
- domain supported by this scale.
-
- *minpos* should be the minimum positive value in the data.
- This is used by log scales to determine a minimum value.
- """
- return vmin, vmax
-
-
-class LinearScale(ScaleBase):
- """
- The default linear scale.
- """
-
- name = 'linear'
-
- def __init__(self, axis, **kwargs):
- pass
-
- def set_default_locators_and_formatters(self, axis):
- """
- Set the locators and formatters to reasonable defaults for
- linear scaling.
- """
- axis.set_major_locator(AutoLocator())
- axis.set_major_formatter(ScalarFormatter())
- axis.set_minor_formatter(NullFormatter())
- # update the minor locator for x and y axis based on rcParams
- if rcParams['xtick.minor.visible']:
- axis.set_minor_locator(AutoMinorLocator())
- else:
- axis.set_minor_locator(NullLocator())
-
- def get_transform(self):
- """
- The transform for linear scaling is just the
- :class:`~matplotlib.transforms.IdentityTransform`.
- """
- return IdentityTransform()
-
-
-class LogTransformBase(Transform):
- input_dims = 1
- output_dims = 1
- is_separable = True
- has_inverse = True
-
- def __init__(self, nonpos='clip'):
- Transform.__init__(self)
- self._clip = {"clip": True, "mask": False}[nonpos]
-
- def transform_non_affine(self, a):
- # Ignore invalid values due to nans being passed to the transform
- with np.errstate(divide="ignore", invalid="ignore"):
- out = np.log(a)
- out /= np.log(self.base)
- if self._clip:
- # SVG spec says that conforming viewers must support values up
- # to 3.4e38 (C float); however experiments suggest that
- # Inkscape (which uses cairo for rendering) runs into cairo's
- # 24-bit limit (which is apparently shared by Agg).
- # Ghostscript (used for pdf rendering appears to overflow even
- # earlier, with the max value around 2 ** 15 for the tests to
- # pass. On the other hand, in practice, we want to clip beyond
- # np.log10(np.nextafter(0, 1)) ~ -323
- # so 1000 seems safe.
- out[a <= 0] = -1000
- return out
-
- def __str__(self):
- return "{}({!r})".format(
- type(self).__name__, "clip" if self._clip else "mask")
-
-
-class InvertedLogTransformBase(Transform):
- input_dims = 1
- output_dims = 1
- is_separable = True
- has_inverse = True
-
- def transform_non_affine(self, a):
- return ma.power(self.base, a)
-
- def __str__(self):
- return "{}()".format(type(self).__name__)
-
-
-class Log10Transform(LogTransformBase):
- base = 10.0
-
- def inverted(self):
- return InvertedLog10Transform()
-
-
-class InvertedLog10Transform(InvertedLogTransformBase):
- base = 10.0
-
- def inverted(self):
- return Log10Transform()
-
-
-class Log2Transform(LogTransformBase):
- base = 2.0
-
- def inverted(self):
- return InvertedLog2Transform()
-
-
-class InvertedLog2Transform(InvertedLogTransformBase):
- base = 2.0
-
- def inverted(self):
- return Log2Transform()
-
-
-class NaturalLogTransform(LogTransformBase):
- base = np.e
-
- def inverted(self):
- return InvertedNaturalLogTransform()
-
-
-class InvertedNaturalLogTransform(InvertedLogTransformBase):
- base = np.e
-
- def inverted(self):
- return NaturalLogTransform()
-
-
-class LogTransform(LogTransformBase):
- def __init__(self, base, nonpos='clip'):
- LogTransformBase.__init__(self, nonpos)
- self.base = base
-
- def inverted(self):
- return InvertedLogTransform(self.base)
-
-
-class InvertedLogTransform(InvertedLogTransformBase):
- def __init__(self, base):
- InvertedLogTransformBase.__init__(self)
- self.base = base
-
- def inverted(self):
- return LogTransform(self.base)
-
-
-class LogScale(ScaleBase):
- """
- A standard logarithmic scale. Care is taken so non-positive
- values are not plotted.
-
- For computational efficiency (to push as much as possible to Numpy
- C code in the common cases), this scale provides different
- transforms depending on the base of the logarithm:
-
- - base 10 (:class:`Log10Transform`)
- - base 2 (:class:`Log2Transform`)
- - base e (:class:`NaturalLogTransform`)
- - arbitrary base (:class:`LogTransform`)
- """
- name = 'log'
-
- # compatibility shim
- LogTransformBase = LogTransformBase
- Log10Transform = Log10Transform
- InvertedLog10Transform = InvertedLog10Transform
- Log2Transform = Log2Transform
- InvertedLog2Transform = InvertedLog2Transform
- NaturalLogTransform = NaturalLogTransform
- InvertedNaturalLogTransform = InvertedNaturalLogTransform
- LogTransform = LogTransform
- InvertedLogTransform = InvertedLogTransform
-
- def __init__(self, axis, **kwargs):
- """
- *basex*/*basey*:
- The base of the logarithm
-
- *nonposx*/*nonposy*: ['mask' | 'clip' ]
- non-positive values in *x* or *y* can be masked as
- invalid, or clipped to a very small positive number
-
- *subsx*/*subsy*:
- Where to place the subticks between each major tick.
- Should be a sequence of integers. For example, in a log10
- scale: ``[2, 3, 4, 5, 6, 7, 8, 9]``
-
- will place 8 logarithmically spaced minor ticks between
- each major tick.
- """
- if axis.axis_name == 'x':
- base = kwargs.pop('basex', 10.0)
- subs = kwargs.pop('subsx', None)
- nonpos = kwargs.pop('nonposx', 'clip')
- else:
- base = kwargs.pop('basey', 10.0)
- subs = kwargs.pop('subsy', None)
- nonpos = kwargs.pop('nonposy', 'clip')
-
- if len(kwargs):
- raise ValueError(("provided too many kwargs, can only pass "
- "{'basex', 'subsx', nonposx'} or "
- "{'basey', 'subsy', nonposy'}. You passed ") +
- "{!r}".format(kwargs))
-
- if nonpos not in ['mask', 'clip']:
- raise ValueError("nonposx, nonposy kwarg must be 'mask' or 'clip'")
- if base <= 0 or base == 1:
- raise ValueError('The log base cannot be <= 0 or == 1')
-
- if base == 10.0:
- self._transform = self.Log10Transform(nonpos)
- elif base == 2.0:
- self._transform = self.Log2Transform(nonpos)
- elif base == np.e:
- self._transform = self.NaturalLogTransform(nonpos)
- else:
- self._transform = self.LogTransform(base, nonpos)
-
- self.base = base
- self.subs = subs
-
- def set_default_locators_and_formatters(self, axis):
- """
- Set the locators and formatters to specialized versions for
- log scaling.
- """
- axis.set_major_locator(LogLocator(self.base))
- axis.set_major_formatter(LogFormatterSciNotation(self.base))
- axis.set_minor_locator(LogLocator(self.base, self.subs))
- axis.set_minor_formatter(
- LogFormatterSciNotation(self.base,
- labelOnlyBase=(self.subs is not None)))
-
- def get_transform(self):
- """
- Return a :class:`~matplotlib.transforms.Transform` instance
- appropriate for the given logarithm base.
- """
- return self._transform
-
- def limit_range_for_scale(self, vmin, vmax, minpos):
- """
- Limit the domain to positive values.
- """
- if not np.isfinite(minpos):
- minpos = 1e-300 # This value should rarely if ever
- # end up with a visible effect.
-
- return (minpos if vmin <= 0 else vmin,
- minpos if vmax <= 0 else vmax)
-
-
-class SymmetricalLogTransform(Transform):
- input_dims = 1
- output_dims = 1
- is_separable = True
- has_inverse = True
-
- def __init__(self, base, linthresh, linscale):
- Transform.__init__(self)
- self.base = base
- self.linthresh = linthresh
- self.linscale = linscale
- self._linscale_adj = (linscale / (1.0 - self.base ** -1))
- self._log_base = np.log(base)
-
- def transform_non_affine(self, a):
- sign = np.sign(a)
- masked = ma.masked_inside(a,
- -self.linthresh,
- self.linthresh,
- copy=False)
- log = sign * self.linthresh * (
- self._linscale_adj +
- ma.log(np.abs(masked) / self.linthresh) / self._log_base)
- if masked.mask.any():
- return ma.where(masked.mask, a * self._linscale_adj, log)
- else:
- return log
-
- def inverted(self):
- return InvertedSymmetricalLogTransform(self.base, self.linthresh,
- self.linscale)
-
-
-class InvertedSymmetricalLogTransform(Transform):
- input_dims = 1
- output_dims = 1
- is_separable = True
- has_inverse = True
-
- def __init__(self, base, linthresh, linscale):
- Transform.__init__(self)
- symlog = SymmetricalLogTransform(base, linthresh, linscale)
- self.base = base
- self.linthresh = linthresh
- self.invlinthresh = symlog.transform(linthresh)
- self.linscale = linscale
- self._linscale_adj = (linscale / (1.0 - self.base ** -1))
-
- def transform_non_affine(self, a):
- sign = np.sign(a)
- masked = ma.masked_inside(a, -self.invlinthresh,
- self.invlinthresh, copy=False)
- exp = sign * self.linthresh * (
- ma.power(self.base, (sign * (masked / self.linthresh))
- - self._linscale_adj))
- if masked.mask.any():
- return ma.where(masked.mask, a / self._linscale_adj, exp)
- else:
- return exp
-
- def inverted(self):
- return SymmetricalLogTransform(self.base,
- self.linthresh, self.linscale)
-
-
-class SymmetricalLogScale(ScaleBase):
- """
- The symmetrical logarithmic scale is logarithmic in both the
- positive and negative directions from the origin.
-
- Since the values close to zero tend toward infinity, there is a
- need to have a range around zero that is linear. The parameter
- *linthresh* allows the user to specify the size of this range
- (-*linthresh*, *linthresh*).
- """
- name = 'symlog'
- # compatibility shim
- SymmetricalLogTransform = SymmetricalLogTransform
- InvertedSymmetricalLogTransform = InvertedSymmetricalLogTransform
-
- def __init__(self, axis, **kwargs):
- """
- *basex*/*basey*:
- The base of the logarithm
-
- *linthreshx*/*linthreshy*:
- A single float which defines the range (-*x*, *x*), within
- which the plot is linear. This avoids having the plot go to
- infinity around zero.
-
- *subsx*/*subsy*:
- Where to place the subticks between each major tick.
- Should be a sequence of integers. For example, in a log10
- scale: ``[2, 3, 4, 5, 6, 7, 8, 9]``
-
- will place 8 logarithmically spaced minor ticks between
- each major tick.
-
- *linscalex*/*linscaley*:
- This allows the linear range (-*linthresh* to *linthresh*)
- to be stretched relative to the logarithmic range. Its
- value is the number of decades to use for each half of the
- linear range. For example, when *linscale* == 1.0 (the
- default), the space used for the positive and negative
- halves of the linear range will be equal to one decade in
- the logarithmic range.
- """
- if axis.axis_name == 'x':
- base = kwargs.pop('basex', 10.0)
- linthresh = kwargs.pop('linthreshx', 2.0)
- subs = kwargs.pop('subsx', None)
- linscale = kwargs.pop('linscalex', 1.0)
- else:
- base = kwargs.pop('basey', 10.0)
- linthresh = kwargs.pop('linthreshy', 2.0)
- subs = kwargs.pop('subsy', None)
- linscale = kwargs.pop('linscaley', 1.0)
-
- if base <= 1.0:
- raise ValueError("'basex/basey' must be larger than 1")
- if linthresh <= 0.0:
- raise ValueError("'linthreshx/linthreshy' must be positive")
- if linscale <= 0.0:
- raise ValueError("'linscalex/linthreshy' must be positive")
-
- self._transform = self.SymmetricalLogTransform(base,
- linthresh,
- linscale)
-
- self.base = base
- self.linthresh = linthresh
- self.linscale = linscale
- self.subs = subs
-
- def set_default_locators_and_formatters(self, axis):
- """
- Set the locators and formatters to specialized versions for
- symmetrical log scaling.
- """
- axis.set_major_locator(SymmetricalLogLocator(self.get_transform()))
- axis.set_major_formatter(LogFormatterSciNotation(self.base))
- axis.set_minor_locator(SymmetricalLogLocator(self.get_transform(),
- self.subs))
- axis.set_minor_formatter(NullFormatter())
-
- def get_transform(self):
- """
- Return a :class:`SymmetricalLogTransform` instance.
- """
- return self._transform
-
-
-class LogitTransform(Transform):
- input_dims = 1
- output_dims = 1
- is_separable = True
- has_inverse = True
-
- def __init__(self, nonpos='mask'):
- Transform.__init__(self)
- self._nonpos = nonpos
- self._clip = {"clip": True, "mask": False}[nonpos]
-
- def transform_non_affine(self, a):
- """logit transform (base 10), masked or clipped"""
- with np.errstate(divide="ignore", invalid="ignore"):
- out = np.log10(a / (1 - a))
- if self._clip: # See LogTransform for choice of clip value.
- out[a <= 0] = -1000
- out[1 <= a] = 1000
- return out
-
- def inverted(self):
- return LogisticTransform(self._nonpos)
-
- def __str__(self):
- return "{}({!r})".format(type(self).__name__,
- "clip" if self._clip else "mask")
-
-
-class LogisticTransform(Transform):
- input_dims = 1
- output_dims = 1
- is_separable = True
- has_inverse = True
-
- def __init__(self, nonpos='mask'):
- Transform.__init__(self)
- self._nonpos = nonpos
-
- def transform_non_affine(self, a):
- """logistic transform (base 10)"""
- return 1.0 / (1 + 10**(-a))
-
- def inverted(self):
- return LogitTransform(self._nonpos)
-
- def __str__(self):
- return "{}({!r})".format(type(self).__name__, self._nonpos)
-
-
-class LogitScale(ScaleBase):
- """
- Logit scale for data between zero and one, both excluded.
-
- This scale is similar to a log scale close to zero and to one, and almost
- linear around 0.5. It maps the interval ]0, 1[ onto ]-infty, +infty[.
- """
- name = 'logit'
-
- def __init__(self, axis, nonpos='mask'):
- """
- *nonpos*: ['mask' | 'clip' ]
- values beyond ]0, 1[ can be masked as invalid, or clipped to a number
- very close to 0 or 1
- """
- if nonpos not in ['mask', 'clip']:
- raise ValueError("nonposx, nonposy kwarg must be 'mask' or 'clip'")
-
- self._transform = LogitTransform(nonpos)
-
- def get_transform(self):
- """
- Return a :class:`LogitTransform` instance.
- """
- return self._transform
-
- def set_default_locators_and_formatters(self, axis):
- # ..., 0.01, 0.1, 0.5, 0.9, 0.99, ...
- axis.set_major_locator(LogitLocator())
- axis.set_major_formatter(LogitFormatter())
- axis.set_minor_locator(LogitLocator(minor=True))
- axis.set_minor_formatter(LogitFormatter())
-
- def limit_range_for_scale(self, vmin, vmax, minpos):
- """
- Limit the domain to values between 0 and 1 (excluded).
- """
- if not np.isfinite(minpos):
- minpos = 1e-7 # This value should rarely if ever
- # end up with a visible effect.
- return (minpos if vmin <= 0 else vmin,
- 1 - minpos if vmax >= 1 else vmax)
-
-
-_scale_mapping = {
- 'linear': LinearScale,
- 'log': LogScale,
- 'symlog': SymmetricalLogScale,
- 'logit': LogitScale,
- }
-
-
-def get_scale_names():
- return sorted(_scale_mapping)
-
-
-def scale_factory(scale, axis, **kwargs):
- """
- Return a scale class by name.
-
- ACCEPTS: [ %(names)s ]
- """
- scale = scale.lower()
- if scale is None:
- scale = 'linear'
-
- if scale not in _scale_mapping:
- raise ValueError("Unknown scale type '%s'" % scale)
-
- return _scale_mapping[scale](axis, **kwargs)
-scale_factory.__doc__ = cbook.dedent(scale_factory.__doc__) % \
- {'names': " | ".join(get_scale_names())}
-
-
-def register_scale(scale_class):
- """
- Register a new kind of scale.
-
- *scale_class* must be a subclass of :class:`ScaleBase`.
- """
- _scale_mapping[scale_class.name] = scale_class
-
-
-def get_scale_docs():
- """
- Helper function for generating docstrings related to scales.
- """
- docs = []
- for name in get_scale_names():
- scale_class = _scale_mapping[name]
- docs.append(" '%s'" % name)
- docs.append("")
- class_docs = cbook.dedent(scale_class.__init__.__doc__)
- class_docs = "".join([" %s\n" %
- x for x in class_docs.split("\n")])
- docs.append(class_docs)
- docs.append("")
- return "\n".join(docs)
-
-
-docstring.interpd.update(
- scale=' | '.join([repr(x) for x in get_scale_names()]),
- scale_docs=get_scale_docs().rstrip(),
- )
diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/__init__.py b/contrib/python/matplotlib/py2/matplotlib/sphinxext/__init__.py
deleted file mode 100644
index 800d82e7ee..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sphinxext/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/mathmpl.py b/contrib/python/matplotlib/py2/matplotlib/sphinxext/mathmpl.py
deleted file mode 100644
index 4bfbc52a24..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sphinxext/mathmpl.py
+++ /dev/null
@@ -1,126 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-import six
-import hashlib
-import os
-import sys
-import warnings
-
-from docutils import nodes
-from docutils.parsers.rst import directives
-import sphinx
-
-from matplotlib import rcParams
-from matplotlib.mathtext import MathTextParser
-rcParams['mathtext.fontset'] = 'cm'
-mathtext_parser = MathTextParser("Bitmap")
-
-# Define LaTeX math node:
-class latex_math(nodes.General, nodes.Element):
- pass
-
-def fontset_choice(arg):
- return directives.choice(arg, ['cm', 'stix', 'stixsans'])
-
-options_spec = {'fontset': fontset_choice}
-
-def math_role(role, rawtext, text, lineno, inliner,
- options={}, content=[]):
- i = rawtext.find('`')
- latex = rawtext[i+1:-1]
- node = latex_math(rawtext)
- node['latex'] = latex
- node['fontset'] = options.get('fontset', 'cm')
- return [node], []
-math_role.options = options_spec
-
-def math_directive(name, arguments, options, content, lineno,
- content_offset, block_text, state, state_machine):
- latex = ''.join(content)
- node = latex_math(block_text)
- node['latex'] = latex
- node['fontset'] = options.get('fontset', 'cm')
- return [node]
-
-# This uses mathtext to render the expression
-def latex2png(latex, filename, fontset='cm'):
- latex = "$%s$" % latex
- orig_fontset = rcParams['mathtext.fontset']
- rcParams['mathtext.fontset'] = fontset
- if os.path.exists(filename):
- depth = mathtext_parser.get_depth(latex, dpi=100)
- else:
- try:
- depth = mathtext_parser.to_png(filename, latex, dpi=100)
- except:
- warnings.warn("Could not render math expression %s" % latex,
- Warning)
- depth = 0
- rcParams['mathtext.fontset'] = orig_fontset
- sys.stdout.write("#")
- sys.stdout.flush()
- return depth
-
-# LaTeX to HTML translation stuff:
-def latex2html(node, source):
- inline = isinstance(node.parent, nodes.TextElement)
- latex = node['latex']
- name = 'math-%s' % hashlib.md5(latex.encode()).hexdigest()[-10:]
-
- destdir = os.path.join(setup.app.builder.outdir, '_images', 'mathmpl')
- if not os.path.exists(destdir):
- os.makedirs(destdir)
- dest = os.path.join(destdir, '%s.png' % name)
- path = '/'.join((setup.app.builder.imgpath, 'mathmpl'))
-
- depth = latex2png(latex, dest, node['fontset'])
-
- if inline:
- cls = ''
- else:
- cls = 'class="center" '
- if inline and depth != 0:
- style = 'style="position: relative; bottom: -%dpx"' % (depth + 1)
- else:
- style = ''
-
- return '<img src="%s/%s.png" %s%s/>' % (path, name, cls, style)
-
-
-def setup(app):
- setup.app = app
-
- # Add visit/depart methods to HTML-Translator:
- def visit_latex_math_html(self, node):
- source = self.document.attributes['source']
- self.body.append(latex2html(node, source))
-
- def depart_latex_math_html(self, node):
- pass
-
- # Add visit/depart methods to LaTeX-Translator:
- def visit_latex_math_latex(self, node):
- inline = isinstance(node.parent, nodes.TextElement)
- if inline:
- self.body.append('$%s$' % node['latex'])
- else:
- self.body.extend(['\\begin{equation}',
- node['latex'],
- '\\end{equation}'])
-
- def depart_latex_math_latex(self, node):
- pass
-
- app.add_node(latex_math,
- html=(visit_latex_math_html, depart_latex_math_html),
- latex=(visit_latex_math_latex, depart_latex_math_latex))
- app.add_role('mathmpl', math_role)
- app.add_directive('mathmpl', math_directive,
- True, (0, 0, 0), **options_spec)
- if sphinx.version_info < (1, 8):
- app.add_role('math', math_role)
- app.add_directive('math', math_directive,
- True, (0, 0, 0), **options_spec)
-
- metadata = {'parallel_read_safe': True, 'parallel_write_safe': True}
- return metadata
diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/only_directives.py b/contrib/python/matplotlib/py2/matplotlib/sphinxext/only_directives.py
deleted file mode 100644
index 0a5ed70f80..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sphinxext/only_directives.py
+++ /dev/null
@@ -1,75 +0,0 @@
-#
-# A pair of directives for inserting content that will only appear in
-# either html or latex.
-#
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from docutils.nodes import Body, Element
-
-
-class only_base(Body, Element):
- def dont_traverse(self, *args, **kwargs):
- return []
-
-class html_only(only_base):
- pass
-
-class latex_only(only_base):
- pass
-
-def run(content, node_class, state, content_offset):
- text = '\n'.join(content)
- node = node_class(text)
- state.nested_parse(content, content_offset, node)
- return [node]
-
-def html_only_directive(name, arguments, options, content, lineno,
- content_offset, block_text, state, state_machine):
- return run(content, html_only, state, content_offset)
-
-def latex_only_directive(name, arguments, options, content, lineno,
- content_offset, block_text, state, state_machine):
- return run(content, latex_only, state, content_offset)
-
-def builder_inited(app):
- if app.builder.name == 'html':
- latex_only.traverse = only_base.dont_traverse
- else:
- html_only.traverse = only_base.dont_traverse
-
-
-def setup(app):
- app.add_directive('htmlonly', html_only_directive, True, (0, 0, 0))
- app.add_directive('latexonly', latex_only_directive, True, (0, 0, 0))
-
- # This will *really* never see the light of day As it turns out,
- # this results in "broken" image nodes since they never get
- # processed, so best not to do this.
- # app.connect('builder-inited', builder_inited)
-
- # Add visit/depart methods to HTML-Translator:
- def visit_perform(self, node):
- pass
-
- def depart_perform(self, node):
- pass
-
- def visit_ignore(self, node):
- node.children = []
-
- def depart_ignore(self, node):
- node.children = []
-
- app.add_node(html_only,
- html=(visit_perform, depart_perform),
- latex=(visit_ignore, depart_ignore))
- app.add_node(latex_only,
- latex=(visit_perform, depart_perform),
- html=(visit_ignore, depart_ignore))
-
- metadata = {'parallel_read_safe': True, 'parallel_write_safe': True}
- return metadata
diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/plot_directive.py b/contrib/python/matplotlib/py2/matplotlib/sphinxext/plot_directive.py
deleted file mode 100644
index 2e50d5aaa6..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sphinxext/plot_directive.py
+++ /dev/null
@@ -1,849 +0,0 @@
-"""
-A directive for including a matplotlib plot in a Sphinx document.
-
-By default, in HTML output, `plot` will include a .png file with a
-link to a high-res .png and .pdf. In LaTeX output, it will include a
-.pdf.
-
-The source code for the plot may be included in one of three ways:
-
- 1. **A path to a source file** as the argument to the directive::
-
- .. plot:: path/to/plot.py
-
- When a path to a source file is given, the content of the
- directive may optionally contain a caption for the plot::
-
- .. plot:: path/to/plot.py
-
- This is the caption for the plot
-
- Additionally, one may specify the name of a function to call (with
- no arguments) immediately after importing the module::
-
- .. plot:: path/to/plot.py plot_function1
-
- 2. Included as **inline content** to the directive::
-
- .. plot::
-
- import matplotlib.pyplot as plt
- import matplotlib.image as mpimg
- import numpy as np
- img = mpimg.imread('_static/stinkbug.png')
- imgplot = plt.imshow(img)
-
- 3. Using **doctest** syntax::
-
- .. plot::
- A plotting example:
- >>> import matplotlib.pyplot as plt
- >>> plt.plot([1,2,3], [4,5,6])
-
-Options
--------
-
-The ``plot`` directive supports the following options:
-
- format : {'python', 'doctest'}
- Specify the format of the input
-
- include-source : bool
- Whether to display the source code. The default can be changed
- using the `plot_include_source` variable in conf.py
-
- encoding : str
- If this source file is in a non-UTF8 or non-ASCII encoding,
- the encoding must be specified using the `:encoding:` option.
- The encoding will not be inferred using the ``-*- coding -*-``
- metacomment.
-
- context : bool or str
- If provided, the code will be run in the context of all
- previous plot directives for which the `:context:` option was
- specified. This only applies to inline code plot directives,
- not those run from files. If the ``:context: reset`` option is
- specified, the context is reset for this and future plots, and
- previous figures are closed prior to running the code.
- ``:context:close-figs`` keeps the context but closes previous figures
- before running the code.
-
- nofigs : bool
- If specified, the code block will be run, but no figures will
- be inserted. This is usually useful with the ``:context:``
- option.
-
-Additionally, this directive supports all of the options of the
-`image` directive, except for `target` (since plot will add its own
-target). These include `alt`, `height`, `width`, `scale`, `align` and
-`class`.
-
-Configuration options
----------------------
-
-The plot directive has the following configuration options:
-
- plot_include_source
- Default value for the include-source option
-
- plot_html_show_source_link
- Whether to show a link to the source in HTML.
-
- plot_pre_code
- Code that should be executed before each plot. If not specified or None
- it will default to a string containing::
-
- import numpy as np
- from matplotlib import pyplot as plt
-
- plot_basedir
- Base directory, to which ``plot::`` file names are relative
- to. (If None or empty, file names are relative to the
- directory where the file containing the directive is.)
-
- plot_formats
- File formats to generate. List of tuples or strings::
-
- [(suffix, dpi), suffix, ...]
-
- that determine the file format and the DPI. For entries whose
- DPI was omitted, sensible defaults are chosen. When passing from
- the command line through sphinx_build the list should be passed as
- suffix:dpi,suffix:dpi, ....
-
- plot_html_show_formats
- Whether to show links to the files in HTML.
-
- plot_rcparams
- A dictionary containing any non-standard rcParams that should
- be applied before each plot.
-
- plot_apply_rcparams
- By default, rcParams are applied when `context` option is not used in
- a plot directive. This configuration option overrides this behavior
- and applies rcParams before each plot.
-
- plot_working_directory
- By default, the working directory will be changed to the directory of
- the example, so the code can get at its data files, if any. Also its
- path will be added to `sys.path` so it can import any helper modules
- sitting beside it. This configuration option can be used to specify
- a central directory (also added to `sys.path`) where data files and
- helper modules for all code are located.
-
- plot_template
- Provide a customized template for preparing restructured text.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-
-import sys, os, shutil, io, re, textwrap
-from os.path import relpath
-import traceback
-import warnings
-
-if not six.PY3:
- import cStringIO
-
-from docutils.parsers.rst import directives
-from docutils.parsers.rst.directives.images import Image
-align = Image.align
-import sphinx
-
-sphinx_version = sphinx.__version__.split(".")
-# The split is necessary for sphinx beta versions where the string is
-# '6b1'
-sphinx_version = tuple([int(re.split('[^0-9]', x)[0])
- for x in sphinx_version[:2]])
-
-import jinja2 # Sphinx dependency.
-
-import matplotlib
-import matplotlib.cbook as cbook
-try:
- with warnings.catch_warnings(record=True):
- warnings.simplefilter("error", UserWarning)
- matplotlib.use('Agg')
-except UserWarning:
- import matplotlib.pyplot as plt
- plt.switch_backend("Agg")
-else:
- import matplotlib.pyplot as plt
-from matplotlib import _pylab_helpers
-
-__version__ = 2
-
-#------------------------------------------------------------------------------
-# Registration hook
-#------------------------------------------------------------------------------
-
-def plot_directive(name, arguments, options, content, lineno,
- content_offset, block_text, state, state_machine):
- """Implementation of the ``.. plot::`` directive.
-
- See the module docstring for details.
- """
- return run(arguments, content, options, state_machine, state, lineno)
-
-
-def _option_boolean(arg):
- if not arg or not arg.strip():
- # no argument given, assume used as a flag
- return True
- elif arg.strip().lower() in ('no', '0', 'false'):
- return False
- elif arg.strip().lower() in ('yes', '1', 'true'):
- return True
- else:
- raise ValueError('"%s" unknown boolean' % arg)
-
-
-def _option_context(arg):
- if arg in [None, 'reset', 'close-figs']:
- return arg
- raise ValueError("argument should be None or 'reset' or 'close-figs'")
-
-
-def _option_format(arg):
- return directives.choice(arg, ('python', 'doctest'))
-
-
-def _option_align(arg):
- return directives.choice(arg, ("top", "middle", "bottom", "left", "center",
- "right"))
-
-
-def mark_plot_labels(app, document):
- """
- To make plots referenceable, we need to move the reference from
- the "htmlonly" (or "latexonly") node to the actual figure node
- itself.
- """
- for name, explicit in six.iteritems(document.nametypes):
- if not explicit:
- continue
- labelid = document.nameids[name]
- if labelid is None:
- continue
- node = document.ids[labelid]
- if node.tagname in ('html_only', 'latex_only'):
- for n in node:
- if n.tagname == 'figure':
- sectname = name
- for c in n:
- if c.tagname == 'caption':
- sectname = c.astext()
- break
-
- node['ids'].remove(labelid)
- node['names'].remove(name)
- n['ids'].append(labelid)
- n['names'].append(name)
- document.settings.env.labels[name] = \
- document.settings.env.docname, labelid, sectname
- break
-
-
-def setup(app):
- setup.app = app
- setup.config = app.config
- setup.confdir = app.confdir
-
- options = {'alt': directives.unchanged,
- 'height': directives.length_or_unitless,
- 'width': directives.length_or_percentage_or_unitless,
- 'scale': directives.nonnegative_int,
- 'align': _option_align,
- 'class': directives.class_option,
- 'include-source': _option_boolean,
- 'format': _option_format,
- 'context': _option_context,
- 'nofigs': directives.flag,
- 'encoding': directives.encoding
- }
-
- app.add_directive('plot', plot_directive, True, (0, 2, False), **options)
- app.add_config_value('plot_pre_code', None, True)
- app.add_config_value('plot_include_source', False, True)
- app.add_config_value('plot_html_show_source_link', True, True)
- app.add_config_value('plot_formats', ['png', 'hires.png', 'pdf'], True)
- app.add_config_value('plot_basedir', None, True)
- app.add_config_value('plot_html_show_formats', True, True)
- app.add_config_value('plot_rcparams', {}, True)
- app.add_config_value('plot_apply_rcparams', False, True)
- app.add_config_value('plot_working_directory', None, True)
- app.add_config_value('plot_template', None, True)
-
- app.connect(str('doctree-read'), mark_plot_labels)
-
- metadata = {'parallel_read_safe': True, 'parallel_write_safe': True}
- return metadata
-
-#------------------------------------------------------------------------------
-# Doctest handling
-#------------------------------------------------------------------------------
-
-def contains_doctest(text):
- try:
- # check if it's valid Python as-is
- compile(text, '<string>', 'exec')
- return False
- except SyntaxError:
- pass
- r = re.compile(r'^\s*>>>', re.M)
- m = r.search(text)
- return bool(m)
-
-
-def unescape_doctest(text):
- """
- Extract code from a piece of text, which contains either Python code
- or doctests.
-
- """
- if not contains_doctest(text):
- return text
-
- code = ""
- for line in text.split("\n"):
- m = re.match(r'^\s*(>>>|\.\.\.) (.*)$', line)
- if m:
- code += m.group(2) + "\n"
- elif line.strip():
- code += "# " + line.strip() + "\n"
- else:
- code += "\n"
- return code
-
-
-def split_code_at_show(text):
- """
- Split code at plt.show()
-
- """
-
- parts = []
- is_doctest = contains_doctest(text)
-
- part = []
- for line in text.split("\n"):
- if (not is_doctest and line.strip() == 'plt.show()') or \
- (is_doctest and line.strip() == '>>> plt.show()'):
- part.append(line)
- parts.append("\n".join(part))
- part = []
- else:
- part.append(line)
- if "\n".join(part).strip():
- parts.append("\n".join(part))
- return parts
-
-
-def remove_coding(text):
- r"""
- Remove the coding comment, which six.exec\_ doesn't like.
- """
- sub_re = re.compile(r"^#\s*-\*-\s*coding:\s*.*-\*-$", flags=re.MULTILINE)
- return sub_re.sub("", text)
-
-#------------------------------------------------------------------------------
-# Template
-#------------------------------------------------------------------------------
-
-
-TEMPLATE = """
-{{ source_code }}
-
-.. only:: html
-
- {% if source_link or (html_show_formats and not multi_image) %}
- (
- {%- if source_link -%}
- `Source code <{{ source_link }}>`__
- {%- endif -%}
- {%- if html_show_formats and not multi_image -%}
- {%- for img in images -%}
- {%- for fmt in img.formats -%}
- {%- if source_link or not loop.first -%}, {% endif -%}
- `{{ fmt }} <{{ dest_dir }}/{{ img.basename }}.{{ fmt }}>`__
- {%- endfor -%}
- {%- endfor -%}
- {%- endif -%}
- )
- {% endif %}
-
- {% for img in images %}
- .. figure:: {{ build_dir }}/{{ img.basename }}.{{ default_fmt }}
- {% for option in options -%}
- {{ option }}
- {% endfor %}
-
- {% if html_show_formats and multi_image -%}
- (
- {%- for fmt in img.formats -%}
- {%- if not loop.first -%}, {% endif -%}
- `{{ fmt }} <{{ dest_dir }}/{{ img.basename }}.{{ fmt }}>`__
- {%- endfor -%}
- )
- {%- endif -%}
-
- {{ caption }}
- {% endfor %}
-
-.. only:: not html
-
- {% for img in images %}
- .. figure:: {{ build_dir }}/{{ img.basename }}.*
- {% for option in options -%}
- {{ option }}
- {% endfor %}
-
- {{ caption }}
- {% endfor %}
-
-"""
-
-exception_template = """
-.. htmlonly::
-
- [`source code <%(linkdir)s/%(basename)s.py>`__]
-
-Exception occurred rendering plot.
-
-"""
-
-# the context of the plot for all directives specified with the
-# :context: option
-plot_context = dict()
-
-class ImageFile(object):
- def __init__(self, basename, dirname):
- self.basename = basename
- self.dirname = dirname
- self.formats = []
-
- def filename(self, format):
- return os.path.join(self.dirname, "%s.%s" % (self.basename, format))
-
- def filenames(self):
- return [self.filename(fmt) for fmt in self.formats]
-
-
-def out_of_date(original, derived):
- """
- Returns True if derivative is out-of-date wrt original,
- both of which are full file paths.
- """
- return (not os.path.exists(derived) or
- (os.path.exists(original) and
- os.stat(derived).st_mtime < os.stat(original).st_mtime))
-
-
-class PlotError(RuntimeError):
- pass
-
-
-def run_code(code, code_path, ns=None, function_name=None):
- """
- Import a Python module from a path, and run the function given by
- name, if function_name is not None.
- """
-
- # Change the working directory to the directory of the example, so
- # it can get at its data files, if any. Add its path to sys.path
- # so it can import any helper modules sitting beside it.
- if six.PY2:
- pwd = os.getcwdu()
- else:
- pwd = os.getcwd()
- old_sys_path = list(sys.path)
- if setup.config.plot_working_directory is not None:
- try:
- os.chdir(setup.config.plot_working_directory)
- except OSError as err:
- raise OSError(str(err) + '\n`plot_working_directory` option in'
- 'Sphinx configuration file must be a valid '
- 'directory path')
- except TypeError as err:
- raise TypeError(str(err) + '\n`plot_working_directory` option in '
- 'Sphinx configuration file must be a string or '
- 'None')
- sys.path.insert(0, setup.config.plot_working_directory)
- elif code_path is not None:
- dirname = os.path.abspath(os.path.dirname(code_path))
- os.chdir(dirname)
- sys.path.insert(0, dirname)
-
- # Reset sys.argv
- old_sys_argv = sys.argv
- sys.argv = [code_path]
-
- # Redirect stdout
- stdout = sys.stdout
- if six.PY3:
- sys.stdout = io.StringIO()
- else:
- sys.stdout = cStringIO.StringIO()
-
- # Assign a do-nothing print function to the namespace. There
- # doesn't seem to be any other way to provide a way to (not) print
- # that works correctly across Python 2 and 3.
- def _dummy_print(*arg, **kwarg):
- pass
-
- try:
- try:
- code = unescape_doctest(code)
- if ns is None:
- ns = {}
- if not ns:
- if setup.config.plot_pre_code is None:
- six.exec_(six.text_type("import numpy as np\n" +
- "from matplotlib import pyplot as plt\n"), ns)
- else:
- six.exec_(six.text_type(setup.config.plot_pre_code), ns)
- ns['print'] = _dummy_print
- if "__main__" in code:
- six.exec_("__name__ = '__main__'", ns)
- code = remove_coding(code)
- six.exec_(code, ns)
- if function_name is not None:
- six.exec_(function_name + "()", ns)
- except (Exception, SystemExit) as err:
- raise PlotError(traceback.format_exc())
- finally:
- os.chdir(pwd)
- sys.argv = old_sys_argv
- sys.path[:] = old_sys_path
- sys.stdout = stdout
- return ns
-
-
-def clear_state(plot_rcparams, close=True):
- if close:
- plt.close('all')
- matplotlib.rc_file_defaults()
- matplotlib.rcParams.update(plot_rcparams)
-
-
-def get_plot_formats(config):
- default_dpi = {'png': 80, 'hires.png': 200, 'pdf': 200}
- formats = []
- plot_formats = config.plot_formats
- if isinstance(plot_formats, six.string_types):
- # String Sphinx < 1.3, Split on , to mimic
- # Sphinx 1.3 and later. Sphinx 1.3 always
- # returns a list.
- plot_formats = plot_formats.split(',')
- for fmt in plot_formats:
- if isinstance(fmt, six.string_types):
- if ':' in fmt:
- suffix, dpi = fmt.split(':')
- formats.append((str(suffix), int(dpi)))
- else:
- formats.append((fmt, default_dpi.get(fmt, 80)))
- elif type(fmt) in (tuple, list) and len(fmt) == 2:
- formats.append((str(fmt[0]), int(fmt[1])))
- else:
- raise PlotError('invalid image format "%r" in plot_formats' % fmt)
- return formats
-
-
-def render_figures(code, code_path, output_dir, output_base, context,
- function_name, config, context_reset=False,
- close_figs=False):
- """
- Run a pyplot script and save the images in *output_dir*.
-
- Save the images under *output_dir* with file names derived from
- *output_base*
- """
- formats = get_plot_formats(config)
-
- # -- Try to determine if all images already exist
-
- code_pieces = split_code_at_show(code)
-
- # Look for single-figure output files first
- all_exists = True
- img = ImageFile(output_base, output_dir)
- for format, dpi in formats:
- if out_of_date(code_path, img.filename(format)):
- all_exists = False
- break
- img.formats.append(format)
-
- if all_exists:
- return [(code, [img])]
-
- # Then look for multi-figure output files
- results = []
- all_exists = True
- for i, code_piece in enumerate(code_pieces):
- images = []
- for j in xrange(1000):
- if len(code_pieces) > 1:
- img = ImageFile('%s_%02d_%02d' % (output_base, i, j),
- output_dir)
- else:
- img = ImageFile('%s_%02d' % (output_base, j), output_dir)
- for format, dpi in formats:
- if out_of_date(code_path, img.filename(format)):
- all_exists = False
- break
- img.formats.append(format)
-
- # assume that if we have one, we have them all
- if not all_exists:
- all_exists = (j > 0)
- break
- images.append(img)
- if not all_exists:
- break
- results.append((code_piece, images))
-
- if all_exists:
- return results
-
- # We didn't find the files, so build them
-
- results = []
- if context:
- ns = plot_context
- else:
- ns = {}
-
- if context_reset:
- clear_state(config.plot_rcparams)
- plot_context.clear()
-
- close_figs = not context or close_figs
-
- for i, code_piece in enumerate(code_pieces):
-
- if not context or config.plot_apply_rcparams:
- clear_state(config.plot_rcparams, close_figs)
- elif close_figs:
- plt.close('all')
-
- run_code(code_piece, code_path, ns, function_name)
-
- images = []
- fig_managers = _pylab_helpers.Gcf.get_all_fig_managers()
- for j, figman in enumerate(fig_managers):
- if len(fig_managers) == 1 and len(code_pieces) == 1:
- img = ImageFile(output_base, output_dir)
- elif len(code_pieces) == 1:
- img = ImageFile("%s_%02d" % (output_base, j), output_dir)
- else:
- img = ImageFile("%s_%02d_%02d" % (output_base, i, j),
- output_dir)
- images.append(img)
- for format, dpi in formats:
- try:
- figman.canvas.figure.savefig(img.filename(format), dpi=dpi)
- except Exception as err:
- raise PlotError(traceback.format_exc())
- img.formats.append(format)
-
- results.append((code_piece, images))
-
- if not context or config.plot_apply_rcparams:
- clear_state(config.plot_rcparams, close=not context)
-
- return results
-
-
-def run(arguments, content, options, state_machine, state, lineno):
- document = state_machine.document
- config = document.settings.env.config
- nofigs = 'nofigs' in options
-
- formats = get_plot_formats(config)
- default_fmt = formats[0][0]
-
- options.setdefault('include-source', config.plot_include_source)
- keep_context = 'context' in options
- context_opt = None if not keep_context else options['context']
-
- rst_file = document.attributes['source']
- rst_dir = os.path.dirname(rst_file)
-
- if len(arguments):
- if not config.plot_basedir:
- source_file_name = os.path.join(setup.app.builder.srcdir,
- directives.uri(arguments[0]))
- else:
- source_file_name = os.path.join(setup.confdir, config.plot_basedir,
- directives.uri(arguments[0]))
-
- # If there is content, it will be passed as a caption.
- caption = '\n'.join(content)
-
- # If the optional function name is provided, use it
- if len(arguments) == 2:
- function_name = arguments[1]
- else:
- function_name = None
-
- with io.open(source_file_name, 'r', encoding='utf-8') as fd:
- code = fd.read()
- output_base = os.path.basename(source_file_name)
- else:
- source_file_name = rst_file
- code = textwrap.dedent("\n".join(map(six.text_type, content)))
- counter = document.attributes.get('_plot_counter', 0) + 1
- document.attributes['_plot_counter'] = counter
- base, ext = os.path.splitext(os.path.basename(source_file_name))
- output_base = '%s-%d.py' % (base, counter)
- function_name = None
- caption = ''
-
- base, source_ext = os.path.splitext(output_base)
- if source_ext in ('.py', '.rst', '.txt'):
- output_base = base
- else:
- source_ext = ''
-
- # ensure that LaTeX includegraphics doesn't choke in foo.bar.pdf filenames
- output_base = output_base.replace('.', '-')
-
- # is it in doctest format?
- is_doctest = contains_doctest(code)
- if 'format' in options:
- if options['format'] == 'python':
- is_doctest = False
- else:
- is_doctest = True
-
- # determine output directory name fragment
- source_rel_name = relpath(source_file_name, setup.confdir)
- source_rel_dir = os.path.dirname(source_rel_name)
- while source_rel_dir.startswith(os.path.sep):
- source_rel_dir = source_rel_dir[1:]
-
- # build_dir: where to place output files (temporarily)
- build_dir = os.path.join(os.path.dirname(setup.app.doctreedir),
- 'plot_directive',
- source_rel_dir)
- # get rid of .. in paths, also changes pathsep
- # see note in Python docs for warning about symbolic links on Windows.
- # need to compare source and dest paths at end
- build_dir = os.path.normpath(build_dir)
-
- if not os.path.exists(build_dir):
- os.makedirs(build_dir)
-
- # output_dir: final location in the builder's directory
- dest_dir = os.path.abspath(os.path.join(setup.app.builder.outdir,
- source_rel_dir))
- if not os.path.exists(dest_dir):
- os.makedirs(dest_dir) # no problem here for me, but just use built-ins
-
- # how to link to files from the RST file
- dest_dir_link = os.path.join(relpath(setup.confdir, rst_dir),
- source_rel_dir).replace(os.path.sep, '/')
- try:
- build_dir_link = relpath(build_dir, rst_dir).replace(os.path.sep, '/')
- except ValueError:
- # on Windows, relpath raises ValueError when path and start are on
- # different mounts/drives
- build_dir_link = build_dir
- source_link = dest_dir_link + '/' + output_base + source_ext
-
- # make figures
- try:
- results = render_figures(code,
- source_file_name,
- build_dir,
- output_base,
- keep_context,
- function_name,
- config,
- context_reset=context_opt == 'reset',
- close_figs=context_opt == 'close-figs')
- errors = []
- except PlotError as err:
- reporter = state.memo.reporter
- sm = reporter.system_message(
- 2, "Exception occurred in plotting {}\n from {}:\n{}".format(
- output_base, source_file_name, err),
- line=lineno)
- results = [(code, [])]
- errors = [sm]
-
- # Properly indent the caption
- caption = '\n'.join(' ' + line.strip()
- for line in caption.split('\n'))
-
- # generate output restructuredtext
- total_lines = []
- for j, (code_piece, images) in enumerate(results):
- if options['include-source']:
- if is_doctest:
- lines = ['']
- lines += [row.rstrip() for row in code_piece.split('\n')]
- else:
- lines = ['.. code-block:: python', '']
- lines += [' %s' % row.rstrip()
- for row in code_piece.split('\n')]
- source_code = "\n".join(lines)
- else:
- source_code = ""
-
- if nofigs:
- images = []
-
- opts = [
- ':%s: %s' % (key, val) for key, val in six.iteritems(options)
- if key in ('alt', 'height', 'width', 'scale', 'align', 'class')]
-
- # Not-None src_link signals the need for a source link in the generated
- # html
- if j == 0 and config.plot_html_show_source_link:
- src_link = source_link
- else:
- src_link = None
-
- result = jinja2.Template(config.plot_template or TEMPLATE).render(
- default_fmt=default_fmt,
- dest_dir=dest_dir_link,
- build_dir=build_dir_link,
- source_link=src_link,
- multi_image=len(images) > 1,
- options=opts,
- images=images,
- source_code=source_code,
- html_show_formats=config.plot_html_show_formats and len(images),
- caption=caption)
-
- total_lines.extend(result.split("\n"))
- total_lines.extend("\n")
-
- if total_lines:
- state_machine.insert_input(total_lines, source=source_file_name)
-
- # copy image files to builder's output directory, if necessary
- if not os.path.exists(dest_dir):
- cbook.mkdirs(dest_dir)
-
- for code_piece, images in results:
- for img in images:
- for fn in img.filenames():
- destimg = os.path.join(dest_dir, os.path.basename(fn))
- if fn != destimg:
- shutil.copyfile(fn, destimg)
-
- # copy script (if necessary)
- target_name = os.path.join(dest_dir, output_base + source_ext)
- with io.open(target_name, 'w', encoding="utf-8") as f:
- if source_file_name == rst_file:
- code_escaped = unescape_doctest(code)
- else:
- code_escaped = code
- f.write(code_escaped)
-
- return errors
diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/__init__.py b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/__init__.py
deleted file mode 100644
index 7a8947f7fb..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-# Make tests a package
diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/conftest.py b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/conftest.py
deleted file mode 100644
index 2971a43141..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/conftest.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from matplotlib.testing.conftest import (mpl_test_settings,
- mpl_image_comparison_parameters,
- pytest_configure, pytest_unconfigure)
diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/test_tinypages.py b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/test_tinypages.py
deleted file mode 100644
index 748a3f3819..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/test_tinypages.py
+++ /dev/null
@@ -1,64 +0,0 @@
-""" Tests for tinypages build using sphinx extensions """
-
-import filecmp
-from os.path import join as pjoin, dirname, isdir
-from subprocess import call, Popen, PIPE
-import sys
-
-import pytest
-
-from matplotlib import cbook
-
-
-needs_sphinx = pytest.mark.skipif(
- call([sys.executable, '-msphinx', '--help'], stdout=PIPE, stderr=PIPE),
- reason="'{} -msphinx' does not return 0".format(sys.executable))
-
-
-@cbook.deprecated("2.1", alternative="filecmp.cmp")
-def file_same(file1, file2):
- with open(file1, 'rb') as fobj:
- contents1 = fobj.read()
- with open(file2, 'rb') as fobj:
- contents2 = fobj.read()
- return contents1 == contents2
-
-
-def test_tinypages(tmpdir):
- html_dir = pjoin(str(tmpdir), 'html')
- doctree_dir = pjoin(str(tmpdir), 'doctrees')
- # Build the pages with warnings turned into errors
- cmd = [sys.executable, '-msphinx', '-W', '-b', 'html', '-d', doctree_dir,
- pjoin(dirname(__file__), 'tinypages'), html_dir]
- proc = Popen(cmd, stdout=PIPE, stderr=PIPE)
- out, err = proc.communicate()
- assert proc.returncode == 0, \
- "'{} -msphinx' failed with stdout:\n{}\nstderr:\n{}\n".format(
- sys.executable, out, err)
-
- assert isdir(html_dir)
-
- def plot_file(num):
- return pjoin(html_dir, 'some_plots-{0}.png'.format(num))
-
- range_10, range_6, range_4 = [plot_file(i) for i in range(1, 4)]
- # Plot 5 is range(6) plot
- assert filecmp.cmp(range_6, plot_file(5))
- # Plot 7 is range(4) plot
- assert filecmp.cmp(range_4, plot_file(7))
- # Plot 11 is range(10) plot
- assert filecmp.cmp(range_10, plot_file(11))
- # Plot 12 uses the old range(10) figure and the new range(6) figure
- assert filecmp.cmp(range_10, plot_file('12_00'))
- assert filecmp.cmp(range_6, plot_file('12_01'))
- # Plot 13 shows close-figs in action
- assert filecmp.cmp(range_4, plot_file(13))
- # Plot 14 has included source
- with open(pjoin(html_dir, 'some_plots.html'), 'rb') as fobj:
- html_contents = fobj.read()
- assert b'# Only a comment' in html_contents
- # check plot defined in external file.
- assert filecmp.cmp(range_4, pjoin(html_dir, 'range4.png'))
- assert filecmp.cmp(range_6, pjoin(html_dir, 'range6.png'))
- # check if figure caption made it into html file
- assert b'This is the caption for plot 15.' in html_contents
diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/.gitignore b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/.gitignore
deleted file mode 100644
index 69fa449dd9..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-_build/
diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/README.md b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/README.md
deleted file mode 100644
index e53d0adc5b..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Test project for matplotlib sphinx extensions
-
-A tiny sphinx project from ``sphinx-quickstart`` with all default answers.
diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/_static/.gitignore b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/_static/.gitignore
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/_static/.gitignore
+++ /dev/null
diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/_static/README.txt b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/_static/README.txt
deleted file mode 100644
index ebde2c4b4a..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/_static/README.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-##############################
-Static directory for tinypages
-##############################
-
-We need this README file to make sure the ``_static`` directory gets created
-in the installation. The tests check for warnings in builds, and, when the
-``_static`` directory is absent, this raises a warning.
diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/conf.py b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/conf.py
deleted file mode 100644
index d2d26c18ec..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/conf.py
+++ /dev/null
@@ -1,264 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# tinypages documentation build configuration file, created by
-# sphinx-quickstart on Tue Mar 18 11:58:34 2014.
-#
-# This file is execfile()d with the current directory set to its
-# containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import sys
-from os.path import join as pjoin, abspath
-import sphinx
-from distutils.version import LooseVersion
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
-sys.path.insert(0, abspath(pjoin('..', '..')))
-
-# -- General configuration ------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-#needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be
-# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
-# ones.
-extensions = ['matplotlib.sphinxext.plot_directive']
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8-sig'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = u'tinypages'
-copyright = u'2014, Matplotlib developers'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = '0.1'
-# The full version, including alpha/beta/rc tags.
-release = '0.1'
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = ['_build']
-
-# The reST default role (used for this markup: `text`) to use for all
-# documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
-
-# If true, keep warnings as "system message" paragraphs in the built documents.
-#keep_warnings = False
-
-
-# -- Options for HTML output ----------------------------------------------
-
-# The theme to use for HTML and HTML Help pages. See the documentation for
-# a list of builtin themes.
-if LooseVersion(sphinx.__version__) >= LooseVersion('1.3'):
- html_theme = 'classic'
-else:
- html_theme = 'default'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further. For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
-
-# The name for this set of Sphinx documents. If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar. Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-# Add any extra paths that contain custom files (such as robots.txt or
-# .htaccess) here, relative to this directory. These files are copied
-# directly to the root of the documentation.
-#html_extra_path = []
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_domain_indices = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it. The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'tinypagesdoc'
-
-
-# -- Options for LaTeX output ---------------------------------------------
-
-latex_elements = {
-# The paper size ('letterpaper' or 'a4paper').
-#'papersize': 'letterpaper',
-
-# The font size ('10pt', '11pt' or '12pt').
-#'pointsize': '10pt',
-
-# Additional stuff for the LaTeX preamble.
-#'preamble': '',
-}
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title,
-# author, documentclass [howto, manual, or own class]).
-latex_documents = [
- ('index', 'tinypages.tex', u'tinypages Documentation',
- u'Matplotlib developers', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# If true, show page references after internal links.
-#latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#latex_show_urls = False
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_domain_indices = True
-
-
-# -- Options for manual page output ---------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
- ('index', 'tinypages', u'tinypages Documentation',
- [u'Matplotlib developers'], 1)
-]
-
-# If true, show URL addresses after external links.
-#man_show_urls = False
-
-
-# -- Options for Texinfo output -------------------------------------------
-
-# Grouping the document tree into Texinfo files. List of tuples
-# (source start file, target name, title, author,
-# dir menu entry, description, category)
-texinfo_documents = [
- ('index', 'tinypages', u'tinypages Documentation',
- u'Matplotlib developers', 'tinypages', 'One line description of project.',
- 'Miscellaneous'),
-]
-
-# Documents to append as an appendix to all manuals.
-#texinfo_appendices = []
-
-# If false, no module index is generated.
-#texinfo_domain_indices = True
-
-# How to display URL addresses: 'footnote', 'no', or 'inline'.
-#texinfo_show_urls = 'footnote'
-
-# If true, do not generate a @detailmenu in the "Top" node's menu.
-#texinfo_no_detailmenu = False
diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/index.rst b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/index.rst
deleted file mode 100644
index 3905483a8a..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/index.rst
+++ /dev/null
@@ -1,21 +0,0 @@
-.. tinypages documentation master file, created by
- sphinx-quickstart on Tue Mar 18 11:58:34 2014.
- You can adapt this file completely to your liking, but it should at least
- contain the root `toctree` directive.
-
-Welcome to tinypages's documentation!
-=====================================
-
-Contents:
-
-.. toctree::
- :maxdepth: 2
-
- some_plots
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/range4.py b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/range4.py
deleted file mode 100644
index 0772fc84ad..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/range4.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from matplotlib import pyplot as plt
-
-plt.figure()
-plt.plot(range(4))
-plt.show()
diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/range6.py b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/range6.py
deleted file mode 100644
index 7e78816bdf..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/range6.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from matplotlib import pyplot as plt
-
-
-def range4():
- '''This is never be called if plot_directive works as expected.'''
- raise NotImplementedError
-
-
-def range6():
- '''This is the function that should be executed.'''
- plt.figure()
- plt.plot(range(6))
- plt.show()
diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/some_plots.rst b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/some_plots.rst
deleted file mode 100644
index 615908b010..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/some_plots.rst
+++ /dev/null
@@ -1,129 +0,0 @@
-##########
-Some plots
-##########
-
-Plot 1 does not use context:
-
-.. plot::
-
- plt.plot(range(10))
- a = 10
-
-Plot 2 doesn't use context either; has length 6:
-
-.. plot::
-
- plt.plot(range(6))
-
-Plot 3 has length 4:
-
-.. plot::
-
- plt.plot(range(4))
-
-Plot 4 shows that a new block with context does not see the variable defined
-in the no-context block:
-
-.. plot::
- :context:
-
- assert 'a' not in globals()
-
-Plot 5 defines ``a`` in a context block:
-
-.. plot::
- :context:
-
- plt.plot(range(6))
- a = 10
-
-Plot 6 shows that a block with context sees the new variable. It also uses
-``:nofigs:``:
-
-.. plot::
- :context:
- :nofigs:
-
- assert a == 10
- b = 4
-
-Plot 7 uses a variable previously defined in previous ``nofigs`` context. It
-also closes any previous figures to create a fresh figure:
-
-.. plot::
- :context: close-figs
-
- assert b == 4
- plt.plot(range(b))
-
-Plot 8 shows that a non-context block still doesn't have ``a``:
-
-.. plot::
- :nofigs:
-
- assert 'a' not in globals()
-
-Plot 9 has a context block, and does have ``a``:
-
-.. plot::
- :context:
- :nofigs:
-
- assert a == 10
-
-Plot 10 resets context, and ``a`` has gone again:
-
-.. plot::
- :context: reset
- :nofigs:
-
- assert 'a' not in globals()
- c = 10
-
-Plot 11 continues the context, we have the new value, but not the old:
-
-.. plot::
- :context:
-
- assert c == 10
- assert 'a' not in globals()
- plt.plot(range(c))
-
-Plot 12 opens a new figure. By default the directive will plot both the first
-and the second figure:
-
-.. plot::
- :context:
-
- plt.figure()
- plt.plot(range(6))
-
-Plot 13 shows ``close-figs`` in action. ``close-figs`` closes all figures
-previous to this plot directive, so we get always plot the figure we create in
-the directive:
-
-.. plot::
- :context: close-figs
-
- plt.figure()
- plt.plot(range(4))
-
-Plot 14 uses ``include-source``:
-
-.. plot::
- :include-source:
-
- # Only a comment
-
-Plot 15 uses an external file with the plot commands and a caption:
-
-.. plot:: range4.py
-
- This is the caption for plot 15.
-
-
-Plot 16 uses a specific function in a file with plot commands:
-
-.. plot:: range6.py range6
-
-
diff --git a/contrib/python/matplotlib/py2/matplotlib/spines.py b/contrib/python/matplotlib/py2/matplotlib/spines.py
deleted file mode 100644
index 1e75c6ed61..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/spines.py
+++ /dev/null
@@ -1,542 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import matplotlib
-
-from matplotlib.artist import allow_rasterization
-from matplotlib import docstring
-import matplotlib.transforms as mtransforms
-import matplotlib.patches as mpatches
-import matplotlib.path as mpath
-import numpy as np
-import warnings
-
-rcParams = matplotlib.rcParams
-
-
-class Spine(mpatches.Patch):
- """an axis spine -- the line noting the data area boundaries
-
- Spines are the lines connecting the axis tick marks and noting the
- boundaries of the data area. They can be placed at arbitrary
- positions. See function:`~matplotlib.spines.Spine.set_position`
- for more information.
-
- The default position is ``('outward',0)``.
-
- Spines are subclasses of class:`~matplotlib.patches.Patch`, and
- inherit much of their behavior.
-
- Spines draw a line, a circle, or an arc depending if
- function:`~matplotlib.spines.Spine.set_patch_line`,
- function:`~matplotlib.spines.Spine.set_patch_circle`, or
- function:`~matplotlib.spines.Spine.set_patch_arc` has been called.
- Line-like is the default.
-
- """
- def __str__(self):
- return "Spine"
-
- @docstring.dedent_interpd
- def __init__(self, axes, spine_type, path, **kwargs):
- """
- - *axes* : the Axes instance containing the spine
- - *spine_type* : a string specifying the spine type
- - *path* : the path instance used to draw the spine
-
- Valid kwargs are:
- %(Patch)s
- """
- super(Spine, self).__init__(**kwargs)
- self.axes = axes
- self.set_figure(self.axes.figure)
- self.spine_type = spine_type
- self.set_facecolor('none')
- self.set_edgecolor(rcParams['axes.edgecolor'])
- self.set_linewidth(rcParams['axes.linewidth'])
- self.set_capstyle('projecting')
- self.axis = None
-
- self.set_zorder(2.5)
- self.set_transform(self.axes.transData) # default transform
-
- self._bounds = None # default bounds
- self._smart_bounds = False
-
- # Defer initial position determination. (Not much support for
- # non-rectangular axes is currently implemented, and this lets
- # them pass through the spines machinery without errors.)
- self._position = None
- if not isinstance(path, matplotlib.path.Path):
- raise ValueError(
- "'path' must be an instance of 'matplotlib.path.Path'")
- self._path = path
-
- # To support drawing both linear and circular spines, this
- # class implements Patch behavior three ways. If
- # self._patch_type == 'line', behave like a mpatches.PathPatch
- # instance. If self._patch_type == 'circle', behave like a
- # mpatches.Ellipse instance. If self._patch_type == 'arc', behave like
- # a mpatches.Arc instance.
- self._patch_type = 'line'
-
- # Behavior copied from mpatches.Ellipse:
- # Note: This cannot be calculated until this is added to an Axes
- self._patch_transform = mtransforms.IdentityTransform()
-
- def set_smart_bounds(self, value):
- """set the spine and associated axis to have smart bounds"""
- self._smart_bounds = value
-
- # also set the axis if possible
- if self.spine_type in ('left', 'right'):
- self.axes.yaxis.set_smart_bounds(value)
- elif self.spine_type in ('top', 'bottom'):
- self.axes.xaxis.set_smart_bounds(value)
- self.stale = True
-
- def get_smart_bounds(self):
- """get whether the spine has smart bounds"""
- return self._smart_bounds
-
- def set_patch_arc(self, center, radius, theta1, theta2):
- """set the spine to be arc-like"""
- self._patch_type = 'arc'
- self._center = center
- self._width = radius * 2
- self._height = radius * 2
- self._theta1 = theta1
- self._theta2 = theta2
- self._path = mpath.Path.arc(theta1, theta2)
- # arc drawn on axes transform
- self.set_transform(self.axes.transAxes)
- self.stale = True
-
- def set_patch_circle(self, center, radius):
- """set the spine to be circular"""
- self._patch_type = 'circle'
- self._center = center
- self._width = radius * 2
- self._height = radius * 2
- # circle drawn on axes transform
- self.set_transform(self.axes.transAxes)
- self.stale = True
-
- def set_patch_line(self):
- """set the spine to be linear"""
- self._patch_type = 'line'
- self.stale = True
-
- # Behavior copied from mpatches.Ellipse:
- def _recompute_transform(self):
- """NOTE: This cannot be called until after this has been added
- to an Axes, otherwise unit conversion will fail. This
- makes it very important to call the accessor method and
- not directly access the transformation member variable.
- """
- assert self._patch_type in ('arc', 'circle')
- center = (self.convert_xunits(self._center[0]),
- self.convert_yunits(self._center[1]))
- width = self.convert_xunits(self._width)
- height = self.convert_yunits(self._height)
- self._patch_transform = mtransforms.Affine2D() \
- .scale(width * 0.5, height * 0.5) \
- .translate(*center)
-
- def get_patch_transform(self):
- if self._patch_type in ('arc', 'circle'):
- self._recompute_transform()
- return self._patch_transform
- else:
- return super(Spine, self).get_patch_transform()
-
- def get_path(self):
- return self._path
-
- def _ensure_position_is_set(self):
- if self._position is None:
- # default position
- self._position = ('outward', 0.0) # in points
- self.set_position(self._position)
-
- def register_axis(self, axis):
- """register an axis
-
- An axis should be registered with its corresponding spine from
- the Axes instance. This allows the spine to clear any axis
- properties when needed.
- """
- self.axis = axis
- if self.axis is not None:
- self.axis.cla()
- self.stale = True
-
- def cla(self):
- """Clear the current spine"""
- self._position = None # clear position
- if self.axis is not None:
- self.axis.cla()
-
- def is_frame_like(self):
- """return True if directly on axes frame
-
- This is useful for determining if a spine is the edge of an
- old style MPL plot. If so, this function will return True.
- """
- self._ensure_position_is_set()
- position = self._position
- if isinstance(position, six.string_types):
- if position == 'center':
- position = ('axes', 0.5)
- elif position == 'zero':
- position = ('data', 0)
- if len(position) != 2:
- raise ValueError("position should be 2-tuple")
- position_type, amount = position
- if position_type == 'outward' and amount == 0:
- return True
- else:
- return False
-
- def _adjust_location(self):
- """automatically set spine bounds to the view interval"""
-
- if self.spine_type == 'circle':
- return
-
- if self._bounds is None:
- if self.spine_type in ('left', 'right'):
- low, high = self.axes.viewLim.intervaly
- elif self.spine_type in ('top', 'bottom'):
- low, high = self.axes.viewLim.intervalx
- else:
- raise ValueError('unknown spine spine_type: %s' %
- self.spine_type)
-
- if self._smart_bounds:
- # attempt to set bounds in sophisticated way
-
- # handle inverted limits
- viewlim_low, viewlim_high = sorted([low, high])
-
- if self.spine_type in ('left', 'right'):
- datalim_low, datalim_high = self.axes.dataLim.intervaly
- ticks = self.axes.get_yticks()
- elif self.spine_type in ('top', 'bottom'):
- datalim_low, datalim_high = self.axes.dataLim.intervalx
- ticks = self.axes.get_xticks()
- # handle inverted limits
- ticks = np.sort(ticks)
- datalim_low, datalim_high = sorted([datalim_low, datalim_high])
-
- if datalim_low < viewlim_low:
- # Data extends past view. Clip line to view.
- low = viewlim_low
- else:
- # Data ends before view ends.
- cond = (ticks <= datalim_low) & (ticks >= viewlim_low)
- tickvals = ticks[cond]
- if len(tickvals):
- # A tick is less than or equal to lowest data point.
- low = tickvals[-1]
- else:
- # No tick is available
- low = datalim_low
- low = max(low, viewlim_low)
-
- if datalim_high > viewlim_high:
- # Data extends past view. Clip line to view.
- high = viewlim_high
- else:
- # Data ends before view ends.
- cond = (ticks >= datalim_high) & (ticks <= viewlim_high)
- tickvals = ticks[cond]
- if len(tickvals):
- # A tick is greater than or equal to highest data
- # point.
- high = tickvals[0]
- else:
- # No tick is available
- high = datalim_high
- high = min(high, viewlim_high)
-
- else:
- low, high = self._bounds
-
- if self._patch_type == 'arc':
- if self.spine_type in ('bottom', 'top'):
- try:
- direction = self.axes.get_theta_direction()
- except AttributeError:
- direction = 1
- try:
- offset = self.axes.get_theta_offset()
- except AttributeError:
- offset = 0
- low = low * direction + offset
- high = high * direction + offset
- if low > high:
- low, high = high, low
-
- self._path = mpath.Path.arc(np.rad2deg(low), np.rad2deg(high))
-
- if self.spine_type == 'bottom':
- rmin, rmax = self.axes.viewLim.intervaly
- try:
- rorigin = self.axes.get_rorigin()
- except AttributeError:
- rorigin = rmin
- scaled_diameter = (rmin - rorigin) / (rmax - rorigin)
- self._height = scaled_diameter
- self._width = scaled_diameter
-
- else:
- raise ValueError('unable to set bounds for spine "%s"' %
- self.spine_type)
- else:
- v1 = self._path.vertices
- assert v1.shape == (2, 2), 'unexpected vertices shape'
- if self.spine_type in ['left', 'right']:
- v1[0, 1] = low
- v1[1, 1] = high
- elif self.spine_type in ['bottom', 'top']:
- v1[0, 0] = low
- v1[1, 0] = high
- else:
- raise ValueError('unable to set bounds for spine "%s"' %
- self.spine_type)
-
- @allow_rasterization
- def draw(self, renderer):
- self._adjust_location()
- ret = super(Spine, self).draw(renderer)
- self.stale = False
- return ret
-
- def _calc_offset_transform(self):
- """calculate the offset transform performed by the spine"""
- self._ensure_position_is_set()
- position = self._position
- if isinstance(position, six.string_types):
- if position == 'center':
- position = ('axes', 0.5)
- elif position == 'zero':
- position = ('data', 0)
- assert len(position) == 2, "position should be 2-tuple"
- position_type, amount = position
- assert position_type in ('axes', 'outward', 'data')
- if position_type == 'outward':
- if amount == 0:
- # short circuit commonest case
- self._spine_transform = ('identity',
- mtransforms.IdentityTransform())
- elif self.spine_type in ['left', 'right', 'top', 'bottom']:
- offset_vec = {'left': (-1, 0),
- 'right': (1, 0),
- 'bottom': (0, -1),
- 'top': (0, 1),
- }[self.spine_type]
- # calculate x and y offset in dots
- offset_x = amount * offset_vec[0] / 72.0
- offset_y = amount * offset_vec[1] / 72.0
- self._spine_transform = ('post',
- mtransforms.ScaledTranslation(
- offset_x,
- offset_y,
- self.figure.dpi_scale_trans))
- else:
- warnings.warn('unknown spine type "%s": no spine '
- 'offset performed' % self.spine_type)
- self._spine_transform = ('identity',
- mtransforms.IdentityTransform())
- elif position_type == 'axes':
- if self.spine_type in ('left', 'right'):
- self._spine_transform = ('pre',
- mtransforms.Affine2D.from_values(
- # keep y unchanged, fix x at
- # amount
- 0, 0, 0, 1, amount, 0))
- elif self.spine_type in ('bottom', 'top'):
- self._spine_transform = ('pre',
- mtransforms.Affine2D.from_values(
- # keep x unchanged, fix y at
- # amount
- 1, 0, 0, 0, 0, amount))
- else:
- warnings.warn('unknown spine type "%s": no spine '
- 'offset performed' % self.spine_type)
- self._spine_transform = ('identity',
- mtransforms.IdentityTransform())
- elif position_type == 'data':
- if self.spine_type in ('right', 'top'):
- # The right and top spines have a default position of 1 in
- # axes coordinates. When specifying the position in data
- # coordinates, we need to calculate the position relative to 0.
- amount -= 1
- if self.spine_type in ('left', 'right'):
- self._spine_transform = ('data',
- mtransforms.Affine2D().translate(
- amount, 0))
- elif self.spine_type in ('bottom', 'top'):
- self._spine_transform = ('data',
- mtransforms.Affine2D().translate(
- 0, amount))
- else:
- warnings.warn('unknown spine type "%s": no spine '
- 'offset performed' % self.spine_type)
- self._spine_transform = ('identity',
- mtransforms.IdentityTransform())
-
- def set_position(self, position):
- """set the position of the spine
-
- Spine position is specified by a 2 tuple of (position type,
- amount). The position types are:
-
- * 'outward' : place the spine out from the data area by the
- specified number of points. (Negative values specify placing the
- spine inward.)
-
- * 'axes' : place the spine at the specified Axes coordinate (from
- 0.0-1.0).
-
- * 'data' : place the spine at the specified data coordinate.
-
- Additionally, shorthand notations define a special positions:
-
- * 'center' -> ('axes',0.5)
- * 'zero' -> ('data', 0.0)
-
- """
- if position in ('center', 'zero'):
- # special positions
- pass
- else:
- if len(position) != 2:
- raise ValueError("position should be 'center' or 2-tuple")
- if position[0] not in ['outward', 'axes', 'data']:
- raise ValueError("position[0] should be one of 'outward', "
- "'axes', or 'data' ")
- self._position = position
- self._calc_offset_transform()
-
- self.set_transform(self.get_spine_transform())
-
- if self.axis is not None:
- self.axis.reset_ticks()
- self.stale = True
-
- def get_position(self):
- """get the spine position"""
- self._ensure_position_is_set()
- return self._position
-
- def get_spine_transform(self):
- """get the spine transform"""
- self._ensure_position_is_set()
- what, how = self._spine_transform
-
- if what == 'data':
- # special case data based spine locations
- data_xform = self.axes.transScale + \
- (how + self.axes.transLimits + self.axes.transAxes)
- if self.spine_type in ['left', 'right']:
- result = mtransforms.blended_transform_factory(
- data_xform, self.axes.transData)
- elif self.spine_type in ['top', 'bottom']:
- result = mtransforms.blended_transform_factory(
- self.axes.transData, data_xform)
- else:
- raise ValueError('unknown spine spine_type: %s' %
- self.spine_type)
- return result
-
- if self.spine_type in ['left', 'right']:
- base_transform = self.axes.get_yaxis_transform(which='grid')
- elif self.spine_type in ['top', 'bottom']:
- base_transform = self.axes.get_xaxis_transform(which='grid')
- else:
- raise ValueError('unknown spine spine_type: %s' %
- self.spine_type)
-
- if what == 'identity':
- return base_transform
- elif what == 'post':
- return base_transform + how
- elif what == 'pre':
- return how + base_transform
- else:
- raise ValueError("unknown spine_transform type: %s" % what)
-
- def set_bounds(self, low, high):
- """Set the bounds of the spine."""
- if self.spine_type == 'circle':
- raise ValueError(
- 'set_bounds() method incompatible with circular spines')
- self._bounds = (low, high)
- self.stale = True
-
- def get_bounds(self):
- """Get the bounds of the spine."""
- return self._bounds
-
- @classmethod
- def linear_spine(cls, axes, spine_type, **kwargs):
- """
- (staticmethod) Returns a linear :class:`Spine`.
- """
- # all values of 13 get replaced upon call to set_bounds()
- if spine_type == 'left':
- path = mpath.Path([(0.0, 13), (0.0, 13)])
- elif spine_type == 'right':
- path = mpath.Path([(1.0, 13), (1.0, 13)])
- elif spine_type == 'bottom':
- path = mpath.Path([(13, 0.0), (13, 0.0)])
- elif spine_type == 'top':
- path = mpath.Path([(13, 1.0), (13, 1.0)])
- else:
- raise ValueError('unable to make path for spine "%s"' % spine_type)
- result = cls(axes, spine_type, path, **kwargs)
- result.set_visible(rcParams['axes.spines.{0}'.format(spine_type)])
-
- return result
-
- @classmethod
- def arc_spine(cls, axes, spine_type, center, radius, theta1, theta2,
- **kwargs):
- """
- (classmethod) Returns an arc :class:`Spine`.
- """
- path = mpath.Path.arc(theta1, theta2)
- result = cls(axes, spine_type, path, **kwargs)
- result.set_patch_arc(center, radius, theta1, theta2)
- return result
-
- @classmethod
- def circular_spine(cls, axes, center, radius, **kwargs):
- """
- (staticmethod) Returns a circular :class:`Spine`.
- """
- path = mpath.Path.unit_circle()
- spine_type = 'circle'
- result = cls(axes, spine_type, path, **kwargs)
- result.set_patch_circle(center, radius)
- return result
-
- def set_color(self, c):
- """
- Set the edgecolor.
-
- ACCEPTS: matplotlib color arg or sequence of rgba tuples
-
- .. seealso::
-
- :meth:`set_facecolor`, :meth:`set_edgecolor`
- For setting the edge or face color individually.
- """
- # The facecolor of a spine is always 'none' by default -- let
- # the user change it manually if desired.
- self.set_edgecolor(c)
- self.stale = True
diff --git a/contrib/python/matplotlib/py2/matplotlib/stackplot.py b/contrib/python/matplotlib/py2/matplotlib/stackplot.py
deleted file mode 100644
index 2b57aeb2b9..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/stackplot.py
+++ /dev/null
@@ -1,126 +0,0 @@
-"""
-Stacked area plot for 1D arrays inspired by Douglas Y'barbo's stackoverflow
-answer:
-http://stackoverflow.com/questions/2225995/how-can-i-create-stacked-line-graph-with-matplotlib
-
-(http://stackoverflow.com/users/66549/doug)
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-import numpy as np
-
-__all__ = ['stackplot']
-
-
-def stackplot(axes, x, *args, **kwargs):
- """
- Draws a stacked area plot.
-
- Parameters
- ----------
- x : 1d array of dimension N
-
- y : 2d array (dimension MxN), or sequence of 1d arrays (each dimension 1xN)
-
- The data is assumed to be unstacked. Each of the following
- calls is legal::
-
- stackplot(x, y) # where y is MxN
- stackplot(x, y1, y2, y3, y4) # where y1, y2, y3, y4, are all 1xNm
-
- baseline : ['zero' | 'sym' | 'wiggle' | 'weighted_wiggle']
- Method used to calculate the baseline:
-
- - ``'zero'``: Constant zero baseline, i.e. a simple stacked plot.
- - ``'sym'``: Symmetric around zero and is sometimes called
- 'ThemeRiver'.
- - ``'wiggle'``: Minimizes the sum of the squared slopes.
- - ``'weighted_wiggle'``: Does the same but weights to account for
- size of each layer. It is also called 'Streamgraph'-layout. More
- details can be found at http://leebyron.com/streamgraph/.
-
- labels : Length N sequence of strings
- Labels to assign to each data series.
-
- colors : Length N sequence of colors
- A list or tuple of colors. These will be cycled through and used to
- colour the stacked areas.
-
- **kwargs :
- All other keyword arguments are passed to `Axes.fill_between()`.
-
-
- Returns
- -------
- list : list of `.PolyCollection`
- A list of `.PolyCollection` instances, one for each element in the
- stacked area plot.
- """
-
- y = np.row_stack(args)
-
- labels = iter(kwargs.pop('labels', []))
-
- colors = kwargs.pop('colors', None)
- if colors is not None:
- axes.set_prop_cycle(color=colors)
-
- baseline = kwargs.pop('baseline', 'zero')
- # Assume data passed has not been 'stacked', so stack it here.
- # We'll need a float buffer for the upcoming calculations.
- stack = np.cumsum(y, axis=0, dtype=np.promote_types(y.dtype, np.float32))
-
- if baseline == 'zero':
- first_line = 0.
-
- elif baseline == 'sym':
- first_line = -np.sum(y, 0) * 0.5
- stack += first_line[None, :]
-
- elif baseline == 'wiggle':
- m = y.shape[0]
- first_line = (y * (m - 0.5 - np.arange(m)[:, None])).sum(0)
- first_line /= -m
- stack += first_line
-
- elif baseline == 'weighted_wiggle':
- m, n = y.shape
- total = np.sum(y, 0)
- # multiply by 1/total (or zero) to avoid infinities in the division:
- inv_total = np.zeros_like(total)
- mask = total > 0
- inv_total[mask] = 1.0 / total[mask]
- increase = np.hstack((y[:, 0:1], np.diff(y)))
- below_size = total - stack
- below_size += 0.5 * y
- move_up = below_size * inv_total
- move_up[:, 0] = 0.5
- center = (move_up - 0.5) * increase
- center = np.cumsum(center.sum(0))
- first_line = center - 0.5 * total
- stack += first_line
-
- else:
- errstr = "Baseline method %s not recognised. " % baseline
- errstr += "Expected 'zero', 'sym', 'wiggle' or 'weighted_wiggle'"
- raise ValueError(errstr)
-
- # Color between x = 0 and the first array.
- color = axes._get_lines.get_next_color()
- coll = axes.fill_between(x, first_line, stack[0, :],
- facecolor=color, label=next(labels, None),
- **kwargs)
- coll.sticky_edges.y[:] = [0]
- r = [coll]
-
- # Color between array i-1 and array i
- for i in xrange(len(y) - 1):
- color = axes._get_lines.get_next_color()
- r.append(axes.fill_between(x, stack[i, :], stack[i + 1, :],
- facecolor=color, label=next(labels, None),
- **kwargs))
- return r
diff --git a/contrib/python/matplotlib/py2/matplotlib/streamplot.py b/contrib/python/matplotlib/py2/matplotlib/streamplot.py
deleted file mode 100644
index 752a11eb4a..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/streamplot.py
+++ /dev/null
@@ -1,674 +0,0 @@
-"""
-Streamline plotting for 2D vector fields.
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-
-import numpy as np
-import matplotlib
-import matplotlib.cm as cm
-import matplotlib.colors as mcolors
-import matplotlib.collections as mcollections
-import matplotlib.lines as mlines
-import matplotlib.patches as patches
-
-
-__all__ = ['streamplot']
-
-
-def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None,
- cmap=None, norm=None, arrowsize=1, arrowstyle='-|>',
- minlength=0.1, transform=None, zorder=None, start_points=None,
- maxlength=4.0, integration_direction='both'):
- """Draws streamlines of a vector flow.
-
- *x*, *y* : 1d arrays
- an *evenly spaced* grid.
- *u*, *v* : 2d arrays
- x and y-velocities. Number of rows should match length of y, and
- the number of columns should match x.
- *density* : float or 2-tuple
- Controls the closeness of streamlines. When `density = 1`, the domain
- is divided into a 30x30 grid---*density* linearly scales this grid.
- Each cell in the grid can have, at most, one traversing streamline.
- For different densities in each direction, use [density_x, density_y].
- *linewidth* : numeric or 2d array
- vary linewidth when given a 2d array with the same shape as velocities.
- *color* : matplotlib color code, or 2d array
- Streamline color. When given an array with the same shape as
- velocities, *color* values are converted to colors using *cmap*.
- *cmap* : :class:`~matplotlib.colors.Colormap`
- Colormap used to plot streamlines and arrows. Only necessary when using
- an array input for *color*.
- *norm* : :class:`~matplotlib.colors.Normalize`
- Normalize object used to scale luminance data to 0, 1. If None, stretch
- (min, max) to (0, 1). Only necessary when *color* is an array.
- *arrowsize* : float
- Factor scale arrow size.
- *arrowstyle* : str
- Arrow style specification.
- See :class:`~matplotlib.patches.FancyArrowPatch`.
- *minlength* : float
- Minimum length of streamline in axes coordinates.
- *start_points*: Nx2 array
- Coordinates of starting points for the streamlines.
- In data coordinates, the same as the ``x`` and ``y`` arrays.
- *zorder* : int
- any number
- *maxlength* : float
- Maximum length of streamline in axes coordinates.
- *integration_direction* : ['forward', 'backward', 'both']
- Integrate the streamline in forward, backward or both directions.
-
- Returns:
-
- *stream_container* : StreamplotSet
- Container object with attributes
-
- - lines: `matplotlib.collections.LineCollection` of streamlines
-
- - arrows: collection of `matplotlib.patches.FancyArrowPatch`
- objects representing arrows half-way along stream
- lines.
-
- This container will probably change in the future to allow changes
- to the colormap, alpha, etc. for both lines and arrows, but these
- changes should be backward compatible.
-
- """
- grid = Grid(x, y)
- mask = StreamMask(density)
- dmap = DomainMap(grid, mask)
-
- if zorder is None:
- zorder = mlines.Line2D.zorder
-
- # default to data coordinates
- if transform is None:
- transform = axes.transData
-
- if color is None:
- color = axes._get_lines.get_next_color()
-
- if linewidth is None:
- linewidth = matplotlib.rcParams['lines.linewidth']
-
- line_kw = {}
- arrow_kw = dict(arrowstyle=arrowstyle, mutation_scale=10 * arrowsize)
-
- if integration_direction not in ['both', 'forward', 'backward']:
- errstr = ("Integration direction '%s' not recognised. "
- "Expected 'both', 'forward' or 'backward'." %
- integration_direction)
- raise ValueError(errstr)
-
- if integration_direction == 'both':
- maxlength /= 2.
-
- use_multicolor_lines = isinstance(color, np.ndarray)
- if use_multicolor_lines:
- if color.shape != grid.shape:
- raise ValueError(
- "If 'color' is given, must have the shape of 'Grid(x,y)'")
- line_colors = []
- color = np.ma.masked_invalid(color)
- else:
- line_kw['color'] = color
- arrow_kw['color'] = color
-
- if isinstance(linewidth, np.ndarray):
- if linewidth.shape != grid.shape:
- raise ValueError(
- "If 'linewidth' is given, must have the shape of 'Grid(x,y)'")
- line_kw['linewidth'] = []
- else:
- line_kw['linewidth'] = linewidth
- arrow_kw['linewidth'] = linewidth
-
- line_kw['zorder'] = zorder
- arrow_kw['zorder'] = zorder
-
- ## Sanity checks.
- if u.shape != grid.shape or v.shape != grid.shape:
- raise ValueError("'u' and 'v' must be of shape 'Grid(x,y)'")
-
- u = np.ma.masked_invalid(u)
- v = np.ma.masked_invalid(v)
-
- integrate = get_integrator(u, v, dmap, minlength, maxlength,
- integration_direction)
-
- trajectories = []
- if start_points is None:
- for xm, ym in _gen_starting_points(mask.shape):
- if mask[ym, xm] == 0:
- xg, yg = dmap.mask2grid(xm, ym)
- t = integrate(xg, yg)
- if t is not None:
- trajectories.append(t)
- else:
- sp2 = np.asanyarray(start_points, dtype=float).copy()
-
- # Check if start_points are outside the data boundaries
- for xs, ys in sp2:
- if not (grid.x_origin <= xs <= grid.x_origin + grid.width
- and grid.y_origin <= ys <= grid.y_origin + grid.height):
- raise ValueError("Starting point ({}, {}) outside of data "
- "boundaries".format(xs, ys))
-
- # Convert start_points from data to array coords
- # Shift the seed points from the bottom left of the data so that
- # data2grid works properly.
- sp2[:, 0] -= grid.x_origin
- sp2[:, 1] -= grid.y_origin
-
- for xs, ys in sp2:
- xg, yg = dmap.data2grid(xs, ys)
- t = integrate(xg, yg)
- if t is not None:
- trajectories.append(t)
-
- if use_multicolor_lines:
- if norm is None:
- norm = mcolors.Normalize(color.min(), color.max())
- if cmap is None:
- cmap = cm.get_cmap(matplotlib.rcParams['image.cmap'])
- else:
- cmap = cm.get_cmap(cmap)
-
- streamlines = []
- arrows = []
- for t in trajectories:
- tgx = np.array(t[0])
- tgy = np.array(t[1])
- # Rescale from grid-coordinates to data-coordinates.
- tx, ty = dmap.grid2data(*np.array(t))
- tx += grid.x_origin
- ty += grid.y_origin
-
- points = np.transpose([tx, ty]).reshape(-1, 1, 2)
- streamlines.extend(np.hstack([points[:-1], points[1:]]))
-
- # Add arrows half way along each trajectory.
- s = np.cumsum(np.sqrt(np.diff(tx) ** 2 + np.diff(ty) ** 2))
- n = np.searchsorted(s, s[-1] / 2.)
- arrow_tail = (tx[n], ty[n])
- arrow_head = (np.mean(tx[n:n + 2]), np.mean(ty[n:n + 2]))
-
- if isinstance(linewidth, np.ndarray):
- line_widths = interpgrid(linewidth, tgx, tgy)[:-1]
- line_kw['linewidth'].extend(line_widths)
- arrow_kw['linewidth'] = line_widths[n]
-
- if use_multicolor_lines:
- color_values = interpgrid(color, tgx, tgy)[:-1]
- line_colors.append(color_values)
- arrow_kw['color'] = cmap(norm(color_values[n]))
-
- p = patches.FancyArrowPatch(
- arrow_tail, arrow_head, transform=transform, **arrow_kw)
- axes.add_patch(p)
- arrows.append(p)
-
- lc = mcollections.LineCollection(
- streamlines, transform=transform, **line_kw)
- lc.sticky_edges.x[:] = [grid.x_origin, grid.x_origin + grid.width]
- lc.sticky_edges.y[:] = [grid.y_origin, grid.y_origin + grid.height]
- if use_multicolor_lines:
- lc.set_array(np.ma.hstack(line_colors))
- lc.set_cmap(cmap)
- lc.set_norm(norm)
- axes.add_collection(lc)
- axes.autoscale_view()
-
- ac = matplotlib.collections.PatchCollection(arrows)
- stream_container = StreamplotSet(lc, ac)
- return stream_container
-
-
-class StreamplotSet(object):
-
- def __init__(self, lines, arrows, **kwargs):
- self.lines = lines
- self.arrows = arrows
-
-
-# Coordinate definitions
-# ========================
-
-class DomainMap(object):
- """Map representing different coordinate systems.
-
- Coordinate definitions:
-
- * axes-coordinates goes from 0 to 1 in the domain.
- * data-coordinates are specified by the input x-y coordinates.
- * grid-coordinates goes from 0 to N and 0 to M for an N x M grid,
- where N and M match the shape of the input data.
- * mask-coordinates goes from 0 to N and 0 to M for an N x M mask,
- where N and M are user-specified to control the density of streamlines.
-
- This class also has methods for adding trajectories to the StreamMask.
- Before adding a trajectory, run `start_trajectory` to keep track of regions
- crossed by a given trajectory. Later, if you decide the trajectory is bad
- (e.g., if the trajectory is very short) just call `undo_trajectory`.
- """
-
- def __init__(self, grid, mask):
- self.grid = grid
- self.mask = mask
- # Constants for conversion between grid- and mask-coordinates
- self.x_grid2mask = (mask.nx - 1) / grid.nx
- self.y_grid2mask = (mask.ny - 1) / grid.ny
-
- self.x_mask2grid = 1. / self.x_grid2mask
- self.y_mask2grid = 1. / self.y_grid2mask
-
- self.x_data2grid = 1. / grid.dx
- self.y_data2grid = 1. / grid.dy
-
- def grid2mask(self, xi, yi):
- """Return nearest space in mask-coords from given grid-coords."""
- return (int((xi * self.x_grid2mask) + 0.5),
- int((yi * self.y_grid2mask) + 0.5))
-
- def mask2grid(self, xm, ym):
- return xm * self.x_mask2grid, ym * self.y_mask2grid
-
- def data2grid(self, xd, yd):
- return xd * self.x_data2grid, yd * self.y_data2grid
-
- def grid2data(self, xg, yg):
- return xg / self.x_data2grid, yg / self.y_data2grid
-
- def start_trajectory(self, xg, yg):
- xm, ym = self.grid2mask(xg, yg)
- self.mask._start_trajectory(xm, ym)
-
- def reset_start_point(self, xg, yg):
- xm, ym = self.grid2mask(xg, yg)
- self.mask._current_xy = (xm, ym)
-
- def update_trajectory(self, xg, yg):
- if not self.grid.within_grid(xg, yg):
- raise InvalidIndexError
- xm, ym = self.grid2mask(xg, yg)
- self.mask._update_trajectory(xm, ym)
-
- def undo_trajectory(self):
- self.mask._undo_trajectory()
-
-
-class Grid(object):
- """Grid of data."""
- def __init__(self, x, y):
-
- if x.ndim == 1:
- pass
- elif x.ndim == 2:
- x_row = x[0, :]
- if not np.allclose(x_row, x):
- raise ValueError("The rows of 'x' must be equal")
- x = x_row
- else:
- raise ValueError("'x' can have at maximum 2 dimensions")
-
- if y.ndim == 1:
- pass
- elif y.ndim == 2:
- y_col = y[:, 0]
- if not np.allclose(y_col, y.T):
- raise ValueError("The columns of 'y' must be equal")
- y = y_col
- else:
- raise ValueError("'y' can have at maximum 2 dimensions")
-
- self.nx = len(x)
- self.ny = len(y)
-
- self.dx = x[1] - x[0]
- self.dy = y[1] - y[0]
-
- self.x_origin = x[0]
- self.y_origin = y[0]
-
- self.width = x[-1] - x[0]
- self.height = y[-1] - y[0]
-
- @property
- def shape(self):
- return self.ny, self.nx
-
- def within_grid(self, xi, yi):
- """Return True if point is a valid index of grid."""
- # Note that xi/yi can be floats; so, for example, we can't simply check
- # `xi < self.nx` since `xi` can be `self.nx - 1 < xi < self.nx`
- return xi >= 0 and xi <= self.nx - 1 and yi >= 0 and yi <= self.ny - 1
-
-
-class StreamMask(object):
- """Mask to keep track of discrete regions crossed by streamlines.
-
- The resolution of this grid determines the approximate spacing between
- trajectories. Streamlines are only allowed to pass through zeroed cells:
- When a streamline enters a cell, that cell is set to 1, and no new
- streamlines are allowed to enter.
- """
-
- def __init__(self, density):
- if np.isscalar(density):
- if density <= 0:
- raise ValueError("If a scalar, 'density' must be positive")
- self.nx = self.ny = int(30 * density)
- else:
- if len(density) != 2:
- raise ValueError("'density' can have at maximum 2 dimensions")
- self.nx = int(30 * density[0])
- self.ny = int(30 * density[1])
- self._mask = np.zeros((self.ny, self.nx))
- self.shape = self._mask.shape
-
- self._current_xy = None
-
- def __getitem__(self, *args):
- return self._mask.__getitem__(*args)
-
- def _start_trajectory(self, xm, ym):
- """Start recording streamline trajectory"""
- self._traj = []
- self._update_trajectory(xm, ym)
-
- def _undo_trajectory(self):
- """Remove current trajectory from mask"""
- for t in self._traj:
- self._mask.__setitem__(t, 0)
-
- def _update_trajectory(self, xm, ym):
- """Update current trajectory position in mask.
-
- If the new position has already been filled, raise `InvalidIndexError`.
- """
- if self._current_xy != (xm, ym):
- if self[ym, xm] == 0:
- self._traj.append((ym, xm))
- self._mask[ym, xm] = 1
- self._current_xy = (xm, ym)
- else:
- raise InvalidIndexError
-
-
-class InvalidIndexError(Exception):
- pass
-
-
-class TerminateTrajectory(Exception):
- pass
-
-
-# Integrator definitions
-#========================
-
-def get_integrator(u, v, dmap, minlength, maxlength, integration_direction):
-
- # rescale velocity onto grid-coordinates for integrations.
- u, v = dmap.data2grid(u, v)
-
- # speed (path length) will be in axes-coordinates
- u_ax = u / dmap.grid.nx
- v_ax = v / dmap.grid.ny
- speed = np.ma.sqrt(u_ax ** 2 + v_ax ** 2)
-
- def forward_time(xi, yi):
- ds_dt = interpgrid(speed, xi, yi)
- if ds_dt == 0:
- raise TerminateTrajectory()
- dt_ds = 1. / ds_dt
- ui = interpgrid(u, xi, yi)
- vi = interpgrid(v, xi, yi)
- return ui * dt_ds, vi * dt_ds
-
- def backward_time(xi, yi):
- dxi, dyi = forward_time(xi, yi)
- return -dxi, -dyi
-
- def integrate(x0, y0):
- """Return x, y grid-coordinates of trajectory based on starting point.
-
- Integrate both forward and backward in time from starting point in
- grid coordinates.
-
- Integration is terminated when a trajectory reaches a domain boundary
- or when it crosses into an already occupied cell in the StreamMask. The
- resulting trajectory is None if it is shorter than `minlength`.
- """
-
- stotal, x_traj, y_traj = 0., [], []
-
- try:
- dmap.start_trajectory(x0, y0)
- except InvalidIndexError:
- return None
- if integration_direction in ['both', 'backward']:
- s, xt, yt = _integrate_rk12(x0, y0, dmap, backward_time, maxlength)
- stotal += s
- x_traj += xt[::-1]
- y_traj += yt[::-1]
-
- if integration_direction in ['both', 'forward']:
- dmap.reset_start_point(x0, y0)
- s, xt, yt = _integrate_rk12(x0, y0, dmap, forward_time, maxlength)
- if len(x_traj) > 0:
- xt = xt[1:]
- yt = yt[1:]
- stotal += s
- x_traj += xt
- y_traj += yt
-
- if stotal > minlength:
- return x_traj, y_traj
- else: # reject short trajectories
- dmap.undo_trajectory()
- return None
-
- return integrate
-
-
-def _integrate_rk12(x0, y0, dmap, f, maxlength):
- """2nd-order Runge-Kutta algorithm with adaptive step size.
-
- This method is also referred to as the improved Euler's method, or Heun's
- method. This method is favored over higher-order methods because:
-
- 1. To get decent looking trajectories and to sample every mask cell
- on the trajectory we need a small timestep, so a lower order
- solver doesn't hurt us unless the data is *very* high resolution.
- In fact, for cases where the user inputs
- data smaller or of similar grid size to the mask grid, the higher
- order corrections are negligible because of the very fast linear
- interpolation used in `interpgrid`.
-
- 2. For high resolution input data (i.e. beyond the mask
- resolution), we must reduce the timestep. Therefore, an adaptive
- timestep is more suited to the problem as this would be very hard
- to judge automatically otherwise.
-
- This integrator is about 1.5 - 2x as fast as both the RK4 and RK45
- solvers in most setups on my machine. I would recommend removing the
- other two to keep things simple.
- """
- # This error is below that needed to match the RK4 integrator. It
- # is set for visual reasons -- too low and corners start
- # appearing ugly and jagged. Can be tuned.
- maxerror = 0.003
-
- # This limit is important (for all integrators) to avoid the
- # trajectory skipping some mask cells. We could relax this
- # condition if we use the code which is commented out below to
- # increment the location gradually. However, due to the efficient
- # nature of the interpolation, this doesn't boost speed by much
- # for quite a bit of complexity.
- maxds = min(1. / dmap.mask.nx, 1. / dmap.mask.ny, 0.1)
-
- ds = maxds
- stotal = 0
- xi = x0
- yi = y0
- xf_traj = []
- yf_traj = []
-
- while dmap.grid.within_grid(xi, yi):
- xf_traj.append(xi)
- yf_traj.append(yi)
- try:
- k1x, k1y = f(xi, yi)
- k2x, k2y = f(xi + ds * k1x,
- yi + ds * k1y)
- except IndexError:
- # Out of the domain on one of the intermediate integration steps.
- # Take an Euler step to the boundary to improve neatness.
- ds, xf_traj, yf_traj = _euler_step(xf_traj, yf_traj, dmap, f)
- stotal += ds
- break
- except TerminateTrajectory:
- break
-
- dx1 = ds * k1x
- dy1 = ds * k1y
- dx2 = ds * 0.5 * (k1x + k2x)
- dy2 = ds * 0.5 * (k1y + k2y)
-
- nx, ny = dmap.grid.shape
- # Error is normalized to the axes coordinates
- error = np.sqrt(((dx2 - dx1) / nx) ** 2 + ((dy2 - dy1) / ny) ** 2)
-
- # Only save step if within error tolerance
- if error < maxerror:
- xi += dx2
- yi += dy2
- try:
- dmap.update_trajectory(xi, yi)
- except InvalidIndexError:
- break
- if (stotal + ds) > maxlength:
- break
- stotal += ds
-
- # recalculate stepsize based on step error
- if error == 0:
- ds = maxds
- else:
- ds = min(maxds, 0.85 * ds * (maxerror / error) ** 0.5)
-
- return stotal, xf_traj, yf_traj
-
-
-def _euler_step(xf_traj, yf_traj, dmap, f):
- """Simple Euler integration step that extends streamline to boundary."""
- ny, nx = dmap.grid.shape
- xi = xf_traj[-1]
- yi = yf_traj[-1]
- cx, cy = f(xi, yi)
- if cx == 0:
- dsx = np.inf
- elif cx < 0:
- dsx = xi / -cx
- else:
- dsx = (nx - 1 - xi) / cx
- if cy == 0:
- dsy = np.inf
- elif cy < 0:
- dsy = yi / -cy
- else:
- dsy = (ny - 1 - yi) / cy
- ds = min(dsx, dsy)
- xf_traj.append(xi + cx * ds)
- yf_traj.append(yi + cy * ds)
- return ds, xf_traj, yf_traj
-
-
-# Utility functions
-# ========================
-
-def interpgrid(a, xi, yi):
- """Fast 2D, linear interpolation on an integer grid"""
-
- Ny, Nx = np.shape(a)
- if isinstance(xi, np.ndarray):
- x = xi.astype(int)
- y = yi.astype(int)
- # Check that xn, yn don't exceed max index
- xn = np.clip(x + 1, 0, Nx - 1)
- yn = np.clip(y + 1, 0, Ny - 1)
- else:
- x = int(xi)
- y = int(yi)
- # conditional is faster than clipping for integers
- if x == (Nx - 2):
- xn = x
- else:
- xn = x + 1
- if y == (Ny - 2):
- yn = y
- else:
- yn = y + 1
-
- a00 = a[y, x]
- a01 = a[y, xn]
- a10 = a[yn, x]
- a11 = a[yn, xn]
- xt = xi - x
- yt = yi - y
- a0 = a00 * (1 - xt) + a01 * xt
- a1 = a10 * (1 - xt) + a11 * xt
- ai = a0 * (1 - yt) + a1 * yt
-
- if not isinstance(xi, np.ndarray):
- if np.ma.is_masked(ai):
- raise TerminateTrajectory
-
- return ai
-
-
-def _gen_starting_points(shape):
- """Yield starting points for streamlines.
-
- Trying points on the boundary first gives higher quality streamlines.
- This algorithm starts with a point on the mask corner and spirals inward.
- This algorithm is inefficient, but fast compared to rest of streamplot.
- """
- ny, nx = shape
- xfirst = 0
- yfirst = 1
- xlast = nx - 1
- ylast = ny - 1
- x, y = 0, 0
- i = 0
- direction = 'right'
- for i in xrange(nx * ny):
-
- yield x, y
-
- if direction == 'right':
- x += 1
- if x >= xlast:
- xlast -= 1
- direction = 'up'
- elif direction == 'up':
- y += 1
- if y >= ylast:
- ylast -= 1
- direction = 'left'
- elif direction == 'left':
- x -= 1
- if x <= xfirst:
- xfirst += 1
- direction = 'down'
- elif direction == 'down':
- y -= 1
- if y <= yfirst:
- yfirst += 1
- direction = 'right'
diff --git a/contrib/python/matplotlib/py2/matplotlib/style/__init__.py b/contrib/python/matplotlib/py2/matplotlib/style/__init__.py
deleted file mode 100644
index cb0592f41e..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/style/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from __future__ import absolute_import
-
-from .core import use, context, available, library, reload_library
diff --git a/contrib/python/matplotlib/py2/matplotlib/style/core.py b/contrib/python/matplotlib/py2/matplotlib/style/core.py
deleted file mode 100644
index 593dd9dcb1..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/style/core.py
+++ /dev/null
@@ -1,234 +0,0 @@
-from __future__ import absolute_import, division, print_function
-
-import six
-
-"""
-Core functions and attributes for the matplotlib style library:
-
-``use``
- Select style sheet to override the current matplotlib settings.
-``context``
- Context manager to use a style sheet temporarily.
-``available``
- List available style sheets.
-``library``
- A dictionary of style names and matplotlib settings.
-"""
-import os
-import re
-import contextlib
-import warnings
-
-import matplotlib as mpl
-from matplotlib import rc_params_from_file, rcParamsDefault
-
-
-__all__ = ['use', 'context', 'available', 'library', 'reload_library']
-
-
-BASE_LIBRARY_PATH = os.path.join(mpl.get_data_path(), 'stylelib')
-# Users may want multiple library paths, so store a list of paths.
-USER_LIBRARY_PATHS = [os.path.join(mpl._get_configdir(), 'stylelib')]
-STYLE_EXTENSION = 'mplstyle'
-STYLE_FILE_PATTERN = re.compile(r'([\S]+).%s$' % STYLE_EXTENSION)
-
-
-# A list of rcParams that should not be applied from styles
-STYLE_BLACKLIST = {
- 'interactive', 'backend', 'backend.qt4', 'webagg.port', 'webagg.address',
- 'webagg.port_retries', 'webagg.open_in_browser', 'backend_fallback',
- 'toolbar', 'timezone', 'datapath', 'figure.max_open_warning',
- 'savefig.directory', 'tk.window_focus', 'docstring.hardcopy'}
-
-
-def _remove_blacklisted_style_params(d, warn=True):
- o = {}
- for key, val in d.items():
- if key in STYLE_BLACKLIST:
- if warn:
- warnings.warn(
- "Style includes a parameter, '{0}', that is not related "
- "to style. Ignoring".format(key))
- else:
- o[key] = val
- return o
-
-
-def is_style_file(filename):
- """Return True if the filename looks like a style file."""
- return STYLE_FILE_PATTERN.match(filename) is not None
-
-
-def _apply_style(d, warn=True):
- mpl.rcParams.update(_remove_blacklisted_style_params(d, warn=warn))
-
-
-def use(style):
- """Use matplotlib style settings from a style specification.
-
- The style name of 'default' is reserved for reverting back to
- the default style settings.
-
- Parameters
- ----------
- style : str, dict, or list
- A style specification. Valid options are:
-
- +------+-------------------------------------------------------------+
- | str | The name of a style or a path/URL to a style file. For a |
- | | list of available style names, see `style.available`. |
- +------+-------------------------------------------------------------+
- | dict | Dictionary with valid key/value pairs for |
- | | `matplotlib.rcParams`. |
- +------+-------------------------------------------------------------+
- | list | A list of style specifiers (str or dict) applied from first |
- | | to last in the list. |
- +------+-------------------------------------------------------------+
-
-
- """
- style_alias = {'mpl20': 'default',
- 'mpl15': 'classic'}
- if isinstance(style, six.string_types) or hasattr(style, 'keys'):
- # If name is a single str or dict, make it a single element list.
- styles = [style]
- else:
- styles = style
-
- styles = (style_alias.get(s, s)
- if isinstance(s, six.string_types)
- else s
- for s in styles)
- for style in styles:
- if not isinstance(style, six.string_types):
- _apply_style(style)
- elif style == 'default':
- _apply_style(rcParamsDefault, warn=False)
- elif style in library:
- _apply_style(library[style])
- else:
- try:
- rc = rc_params_from_file(style, use_default_template=False)
- _apply_style(rc)
- except IOError:
- raise IOError(
- "{!r} not found in the style library and input is not a "
- "valid URL or path; see `style.available` for list of "
- "available styles".format(style))
-
-
-@contextlib.contextmanager
-def context(style, after_reset=False):
- """Context manager for using style settings temporarily.
-
- Parameters
- ----------
- style : str, dict, or list
- A style specification. Valid options are:
-
- +------+-------------------------------------------------------------+
- | str | The name of a style or a path/URL to a style file. For a |
- | | list of available style names, see `style.available`. |
- +------+-------------------------------------------------------------+
- | dict | Dictionary with valid key/value pairs for |
- | | `matplotlib.rcParams`. |
- +------+-------------------------------------------------------------+
- | list | A list of style specifiers (str or dict) applied from first |
- | | to last in the list. |
- +------+-------------------------------------------------------------+
-
- after_reset : bool
- If True, apply style after resetting settings to their defaults;
- otherwise, apply style on top of the current settings.
- """
- initial_settings = mpl.rcParams.copy()
- if after_reset:
- mpl.rcdefaults()
- try:
- use(style)
- except:
- # Restore original settings before raising errors during the update.
- mpl.rcParams.update(initial_settings)
- raise
- else:
- yield
- finally:
- mpl.rcParams.update(initial_settings)
-
-
-def load_base_library():
- """Load style library defined in this package."""
- library = dict()
- library.update(read_style_directory(BASE_LIBRARY_PATH))
- return library
-
-
-def iter_user_libraries():
- for stylelib_path in USER_LIBRARY_PATHS:
- stylelib_path = os.path.expanduser(stylelib_path)
- if os.path.exists(stylelib_path) and os.path.isdir(stylelib_path):
- yield stylelib_path
-
-
-def update_user_library(library):
- """Update style library with user-defined rc files"""
- for stylelib_path in iter_user_libraries():
- styles = read_style_directory(stylelib_path)
- update_nested_dict(library, styles)
- return library
-
-
-def iter_style_files(style_dir):
- """Yield file path and name of styles in the given directory."""
- for path in os.listdir(style_dir):
- filename = os.path.basename(path)
- if is_style_file(filename):
- match = STYLE_FILE_PATTERN.match(filename)
- path = os.path.abspath(os.path.join(style_dir, path))
- yield path, match.groups()[0]
-
-
-def read_style_directory(style_dir):
- """Return dictionary of styles defined in `style_dir`."""
- styles = dict()
- for path, name in iter_style_files(style_dir):
- with warnings.catch_warnings(record=True) as warns:
- styles[name] = rc_params_from_file(path,
- use_default_template=False)
-
- for w in warns:
- message = 'In %s: %s' % (path, w.message)
- warnings.warn(message)
-
- return styles
-
-
-def update_nested_dict(main_dict, new_dict):
- """Update nested dict (only level of nesting) with new values.
-
- Unlike dict.update, this assumes that the values of the parent dict are
- dicts (or dict-like), so you shouldn't replace the nested dict if it
- already exists. Instead you should update the sub-dict.
- """
- # update named styles specified by user
- for name, rc_dict in six.iteritems(new_dict):
- if name in main_dict:
- main_dict[name].update(rc_dict)
- else:
- main_dict[name] = rc_dict
- return main_dict
-
-
-# Load style library
-# ==================
-_base_library = load_base_library()
-
-library = None
-available = []
-
-
-def reload_library():
- """Reload style library."""
- global library
- available[:] = library = update_user_library(_base_library)
-reload_library()
diff --git a/contrib/python/matplotlib/py2/matplotlib/table.py b/contrib/python/matplotlib/py2/matplotlib/table.py
deleted file mode 100644
index ee7908ca9d..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/table.py
+++ /dev/null
@@ -1,702 +0,0 @@
-"""
-Place a table below the x-axis at location loc.
-
-The table consists of a grid of cells.
-
-The grid need not be rectangular and can have holes.
-
-Cells are added by specifying their row and column.
-
-For the purposes of positioning the cell at (0, 0) is
-assumed to be at the top left and the cell at (max_row, max_col)
-is assumed to be at bottom right.
-
-You can add additional cells outside this range to have convenient
-ways of positioning more interesting grids.
-
-Author : John Gill <jng@europe.renre.com>
-Copyright : 2004 John Gill and John Hunter
-License : matplotlib license
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-
-import warnings
-
-from . import artist
-from .artist import Artist, allow_rasterization
-from .patches import Rectangle
-from matplotlib import docstring
-from .text import Text
-from .transforms import Bbox
-from matplotlib.path import Path
-
-
-class Cell(Rectangle):
- """
- A cell is a Rectangle with some associated text.
-
- """
- PAD = 0.1 # padding between text and rectangle
-
- def __init__(self, xy, width, height,
- edgecolor='k', facecolor='w',
- fill=True,
- text='',
- loc=None,
- fontproperties=None
- ):
-
- # Call base
- Rectangle.__init__(self, xy, width=width, height=height,
- edgecolor=edgecolor, facecolor=facecolor)
- self.set_clip_on(False)
-
- # Create text object
- if loc is None:
- loc = 'right'
- self._loc = loc
- self._text = Text(x=xy[0], y=xy[1], text=text,
- fontproperties=fontproperties)
- self._text.set_clip_on(False)
-
- def set_transform(self, trans):
- Rectangle.set_transform(self, trans)
- # the text does not get the transform!
- self.stale = True
-
- def set_figure(self, fig):
- Rectangle.set_figure(self, fig)
- self._text.set_figure(fig)
-
- def get_text(self):
- 'Return the cell Text intance'
- return self._text
-
- def set_fontsize(self, size):
- self._text.set_fontsize(size)
- self.stale = True
-
- def get_fontsize(self):
- 'Return the cell fontsize'
- return self._text.get_fontsize()
-
- def auto_set_font_size(self, renderer):
- """ Shrink font size until text fits. """
- fontsize = self.get_fontsize()
- required = self.get_required_width(renderer)
- while fontsize > 1 and required > self.get_width():
- fontsize -= 1
- self.set_fontsize(fontsize)
- required = self.get_required_width(renderer)
-
- return fontsize
-
- @allow_rasterization
- def draw(self, renderer):
- if not self.get_visible():
- return
- # draw the rectangle
- Rectangle.draw(self, renderer)
-
- # position the text
- self._set_text_position(renderer)
- self._text.draw(renderer)
- self.stale = False
-
- def _set_text_position(self, renderer):
- """ Set text up so it draws in the right place.
-
- Currently support 'left', 'center' and 'right'
- """
- bbox = self.get_window_extent(renderer)
- l, b, w, h = bbox.bounds
-
- # draw in center vertically
- self._text.set_verticalalignment('center')
- y = b + (h / 2.0)
-
- # now position horizontally
- if self._loc == 'center':
- self._text.set_horizontalalignment('center')
- x = l + (w / 2.0)
- elif self._loc == 'left':
- self._text.set_horizontalalignment('left')
- x = l + (w * self.PAD)
- else:
- self._text.set_horizontalalignment('right')
- x = l + (w * (1.0 - self.PAD))
-
- self._text.set_position((x, y))
-
- def get_text_bounds(self, renderer):
- """ Get text bounds in axes co-ordinates. """
- bbox = self._text.get_window_extent(renderer)
- bboxa = bbox.inverse_transformed(self.get_data_transform())
- return bboxa.bounds
-
- def get_required_width(self, renderer):
- """ Get width required for this cell. """
- l, b, w, h = self.get_text_bounds(renderer)
- return w * (1.0 + (2.0 * self.PAD))
-
- def set_text_props(self, **kwargs):
- 'update the text properties with kwargs'
- self._text.update(kwargs)
- self.stale = True
-
-
-class CustomCell(Cell):
- """
- A subclass of Cell where the sides may be visibly toggled.
-
- """
-
- _edges = 'BRTL'
- _edge_aliases = {'open': '',
- 'closed': _edges, # default
- 'horizontal': 'BT',
- 'vertical': 'RL'
- }
-
- def __init__(self, *args, **kwargs):
- visible_edges = kwargs.pop('visible_edges')
- Cell.__init__(self, *args, **kwargs)
- self.visible_edges = visible_edges
-
- @property
- def visible_edges(self):
- return self._visible_edges
-
- @visible_edges.setter
- def visible_edges(self, value):
- if value is None:
- self._visible_edges = self._edges
- elif value in self._edge_aliases:
- self._visible_edges = self._edge_aliases[value]
- else:
- for edge in value:
- if edge not in self._edges:
- raise ValueError('Invalid edge param {}, must only be one '
- 'of {} or string of {}'.format(
- value,
- ", ".join(self._edge_aliases),
- ", ".join(self._edges)))
- self._visible_edges = value
- self.stale = True
-
- def get_path(self):
- 'Return a path where the edges specified by _visible_edges are drawn'
-
- codes = [Path.MOVETO]
-
- for edge in self._edges:
- if edge in self._visible_edges:
- codes.append(Path.LINETO)
- else:
- codes.append(Path.MOVETO)
-
- if Path.MOVETO not in codes[1:]: # All sides are visible
- codes[-1] = Path.CLOSEPOLY
-
- return Path(
- [[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0]],
- codes,
- readonly=True
- )
-
-
-class Table(Artist):
- """
- Create a table of cells.
-
- Table can have (optional) row and column headers.
-
- Each entry in the table can be either text or patches.
-
- Column widths and row heights for the table can be specified.
-
- Return value is a sequence of text, line and patch instances that make
- up the table
- """
- codes = {'best': 0,
- 'upper right': 1, # default
- 'upper left': 2,
- 'lower left': 3,
- 'lower right': 4,
- 'center left': 5,
- 'center right': 6,
- 'lower center': 7,
- 'upper center': 8,
- 'center': 9,
- 'top right': 10,
- 'top left': 11,
- 'bottom left': 12,
- 'bottom right': 13,
- 'right': 14,
- 'left': 15,
- 'top': 16,
- 'bottom': 17,
- }
-
- FONTSIZE = 10
- AXESPAD = 0.02 # the border between the axes and table edge
-
- def __init__(self, ax, loc=None, bbox=None, **kwargs):
-
- Artist.__init__(self)
-
- if isinstance(loc, six.string_types) and loc not in self.codes:
- warnings.warn('Unrecognized location %s. Falling back on '
- 'bottom; valid locations are\n%s\t' %
- (loc, '\n\t'.join(self.codes)))
- loc = 'bottom'
- if isinstance(loc, six.string_types):
- loc = self.codes.get(loc, 1)
- self.set_figure(ax.figure)
- self._axes = ax
- self._loc = loc
- self._bbox = bbox
-
- # use axes coords
- self.set_transform(ax.transAxes)
-
- self._texts = []
- self._cells = {}
- self._edges = None
- self._autoRows = []
- self._autoColumns = []
- self._autoFontsize = True
- self.update(kwargs)
-
- self.set_clip_on(False)
-
- def add_cell(self, row, col, *args, **kwargs):
- """
- Add a cell to the table.
-
- Parameters
- ----------
- row : int
- Row index
- col : int
- Column index
-
- Returns
- -------
- `CustomCell`: Automatically created cell
-
- """
- xy = (0, 0)
- cell = CustomCell(xy, visible_edges=self.edges, *args, **kwargs)
- self[row, col] = cell
- return cell
-
- def __setitem__(self, position, cell):
- """
- Set a customcell in a given position
- """
- if not isinstance(cell, CustomCell):
- raise TypeError('Table only accepts CustomCell')
- try:
- row, col = position[0], position[1]
- except Exception:
- raise KeyError('Only tuples length 2 are accepted as coordinates')
- cell.set_figure(self.figure)
- cell.set_transform(self.get_transform())
- cell.set_clip_on(False)
- self._cells[row, col] = cell
- self.stale = True
-
- def __getitem__(self, position):
- """
- Retreive a custom cell from a given position
- """
- try:
- row, col = position[0], position[1]
- except Exception:
- raise KeyError('Only tuples length 2 are accepted as coordinates')
- return self._cells[row, col]
-
- @property
- def edges(self):
- return self._edges
-
- @edges.setter
- def edges(self, value):
- self._edges = value
- self.stale = True
-
- def _approx_text_height(self):
- return (self.FONTSIZE / 72.0 * self.figure.dpi /
- self._axes.bbox.height * 1.2)
-
- @allow_rasterization
- def draw(self, renderer):
- # Need a renderer to do hit tests on mouseevent; assume the last one
- # will do
- if renderer is None:
- renderer = self.figure._cachedRenderer
- if renderer is None:
- raise RuntimeError('No renderer defined')
-
- if not self.get_visible():
- return
- renderer.open_group('table')
- self._update_positions(renderer)
-
- for key in sorted(self._cells):
- self._cells[key].draw(renderer)
-
- renderer.close_group('table')
- self.stale = False
-
- def _get_grid_bbox(self, renderer):
- """Get a bbox, in axes co-ordinates for the cells.
-
- Only include those in the range (0,0) to (maxRow, maxCol)"""
- boxes = [cell.get_window_extent(renderer)
- for (row, col), cell in six.iteritems(self._cells)
- if row >= 0 and col >= 0]
- bbox = Bbox.union(boxes)
- return bbox.inverse_transformed(self.get_transform())
-
- def contains(self, mouseevent):
- """Test whether the mouse event occurred in the table.
-
- Returns T/F, {}
- """
- if callable(self._contains):
- return self._contains(self, mouseevent)
-
- # TODO: Return index of the cell containing the cursor so that the user
- # doesn't have to bind to each one individually.
- renderer = self.figure._cachedRenderer
- if renderer is not None:
- boxes = [cell.get_window_extent(renderer)
- for (row, col), cell in six.iteritems(self._cells)
- if row >= 0 and col >= 0]
- bbox = Bbox.union(boxes)
- return bbox.contains(mouseevent.x, mouseevent.y), {}
- else:
- return False, {}
-
- def get_children(self):
- 'Return the Artists contained by the table'
- return list(six.itervalues(self._cells))
- get_child_artists = get_children # backward compatibility
-
- def get_window_extent(self, renderer):
- 'Return the bounding box of the table in window coords'
- boxes = [cell.get_window_extent(renderer)
- for cell in six.itervalues(self._cells)]
- return Bbox.union(boxes)
-
- def _do_cell_alignment(self):
- """ Calculate row heights and column widths.
-
- Position cells accordingly.
- """
- # Calculate row/column widths
- widths = {}
- heights = {}
- for (row, col), cell in six.iteritems(self._cells):
- height = heights.setdefault(row, 0.0)
- heights[row] = max(height, cell.get_height())
- width = widths.setdefault(col, 0.0)
- widths[col] = max(width, cell.get_width())
-
- # work out left position for each column
- xpos = 0
- lefts = {}
- for col in sorted(widths):
- lefts[col] = xpos
- xpos += widths[col]
-
- ypos = 0
- bottoms = {}
- for row in sorted(heights, reverse=True):
- bottoms[row] = ypos
- ypos += heights[row]
-
- # set cell positions
- for (row, col), cell in six.iteritems(self._cells):
- cell.set_x(lefts[col])
- cell.set_y(bottoms[row])
-
- def auto_set_column_width(self, col):
- """ Given column indexs in either List, Tuple or int. Will be able to
- automatically set the columns into optimal sizes.
-
- Here is the example of the input, which triger automatic adjustment on
- columns to optimal size by given index numbers.
- -1: the row labling
- 0: the 1st column
- 1: the 2nd column
-
- Args:
- col(List): list of indexs
- >>>table.auto_set_column_width([-1,0,1])
-
- col(Tuple): tuple of indexs
- >>>table.auto_set_column_width((-1,0,1))
-
- col(int): index integer
- >>>table.auto_set_column_width(-1)
- >>>table.auto_set_column_width(0)
- >>>table.auto_set_column_width(1)
- """
- # check for col possibility on iteration
- try:
- iter(col)
- except (TypeError, AttributeError):
- self._autoColumns.append(col)
- else:
- for cell in col:
- self._autoColumns.append(cell)
-
- self.stale = True
-
- def _auto_set_column_width(self, col, renderer):
- """ Automagically set width for column.
- """
- cells = [key for key in self._cells if key[1] == col]
-
- # find max width
- width = 0
- for cell in cells:
- c = self._cells[cell]
- width = max(c.get_required_width(renderer), width)
-
- # Now set the widths
- for cell in cells:
- self._cells[cell].set_width(width)
-
- def auto_set_font_size(self, value=True):
- """ Automatically set font size. """
- self._autoFontsize = value
- self.stale = True
-
- def _auto_set_font_size(self, renderer):
-
- if len(self._cells) == 0:
- return
- fontsize = list(six.itervalues(self._cells))[0].get_fontsize()
- cells = []
- for key, cell in six.iteritems(self._cells):
- # ignore auto-sized columns
- if key[1] in self._autoColumns:
- continue
- size = cell.auto_set_font_size(renderer)
- fontsize = min(fontsize, size)
- cells.append(cell)
-
- # now set all fontsizes equal
- for cell in six.itervalues(self._cells):
- cell.set_fontsize(fontsize)
-
- def scale(self, xscale, yscale):
- """ Scale column widths by xscale and row heights by yscale. """
- for c in six.itervalues(self._cells):
- c.set_width(c.get_width() * xscale)
- c.set_height(c.get_height() * yscale)
-
- def set_fontsize(self, size):
- """
- Set the fontsize of the cell text
-
- ACCEPTS: a float in points
- """
-
- for cell in six.itervalues(self._cells):
- cell.set_fontsize(size)
- self.stale = True
-
- def _offset(self, ox, oy):
- 'Move all the artists by ox,oy (axes coords)'
-
- for c in six.itervalues(self._cells):
- x, y = c.get_x(), c.get_y()
- c.set_x(x + ox)
- c.set_y(y + oy)
-
- def _update_positions(self, renderer):
- # called from renderer to allow more precise estimates of
- # widths and heights with get_window_extent
-
- # Do any auto width setting
- for col in self._autoColumns:
- self._auto_set_column_width(col, renderer)
-
- if self._autoFontsize:
- self._auto_set_font_size(renderer)
-
- # Align all the cells
- self._do_cell_alignment()
-
- bbox = self._get_grid_bbox(renderer)
- l, b, w, h = bbox.bounds
-
- if self._bbox is not None:
- # Position according to bbox
- rl, rb, rw, rh = self._bbox
- self.scale(rw / w, rh / h)
- ox = rl - l
- oy = rb - b
- self._do_cell_alignment()
- else:
- # Position using loc
- (BEST, UR, UL, LL, LR, CL, CR, LC, UC, C,
- TR, TL, BL, BR, R, L, T, B) = xrange(len(self.codes))
- # defaults for center
- ox = (0.5 - w / 2) - l
- oy = (0.5 - h / 2) - b
- if self._loc in (UL, LL, CL): # left
- ox = self.AXESPAD - l
- if self._loc in (BEST, UR, LR, R, CR): # right
- ox = 1 - (l + w + self.AXESPAD)
- if self._loc in (BEST, UR, UL, UC): # upper
- oy = 1 - (b + h + self.AXESPAD)
- if self._loc in (LL, LR, LC): # lower
- oy = self.AXESPAD - b
- if self._loc in (LC, UC, C): # center x
- ox = (0.5 - w / 2) - l
- if self._loc in (CL, CR, C): # center y
- oy = (0.5 - h / 2) - b
-
- if self._loc in (TL, BL, L): # out left
- ox = - (l + w)
- if self._loc in (TR, BR, R): # out right
- ox = 1.0 - l
- if self._loc in (TR, TL, T): # out top
- oy = 1.0 - b
- if self._loc in (BL, BR, B): # out bottom
- oy = - (b + h)
-
- self._offset(ox, oy)
-
- def get_celld(self):
- 'return a dict of cells in the table'
- return self._cells
-
-
-def table(ax,
- cellText=None, cellColours=None,
- cellLoc='right', colWidths=None,
- rowLabels=None, rowColours=None, rowLoc='left',
- colLabels=None, colColours=None, colLoc='center',
- loc='bottom', bbox=None, edges='closed',
- **kwargs):
- """
- TABLE(cellText=None, cellColours=None,
- cellLoc='right', colWidths=None,
- rowLabels=None, rowColours=None, rowLoc='left',
- colLabels=None, colColours=None, colLoc='center',
- loc='bottom', bbox=None, edges='closed')
-
- Factory function to generate a Table instance.
-
- Thanks to John Gill for providing the class and table.
- """
-
- if cellColours is None and cellText is None:
- raise ValueError('At least one argument from "cellColours" or '
- '"cellText" must be provided to create a table.')
-
- # Check we have some cellText
- if cellText is None:
- # assume just colours are needed
- rows = len(cellColours)
- cols = len(cellColours[0])
- cellText = [[''] * cols] * rows
-
- rows = len(cellText)
- cols = len(cellText[0])
- for row in cellText:
- if len(row) != cols:
- raise ValueError("Each row in 'cellText' must have {} columns"
- .format(cols))
-
- if cellColours is not None:
- if len(cellColours) != rows:
- raise ValueError("'cellColours' must have {} rows".format(rows))
- for row in cellColours:
- if len(row) != cols:
- raise ValueError("Each row in 'cellColours' must have {} "
- "columns".format(cols))
- else:
- cellColours = ['w' * cols] * rows
-
- # Set colwidths if not given
- if colWidths is None:
- colWidths = [1.0 / cols] * cols
-
- # Fill in missing information for column
- # and row labels
- rowLabelWidth = 0
- if rowLabels is None:
- if rowColours is not None:
- rowLabels = [''] * rows
- rowLabelWidth = colWidths[0]
- elif rowColours is None:
- rowColours = 'w' * rows
-
- if rowLabels is not None:
- if len(rowLabels) != rows:
- raise ValueError("'rowLabels' must be of length {0}".format(rows))
-
- # If we have column labels, need to shift
- # the text and colour arrays down 1 row
- offset = 1
- if colLabels is None:
- if colColours is not None:
- colLabels = [''] * cols
- else:
- offset = 0
- elif colColours is None:
- colColours = 'w' * cols
-
- # Set up cell colours if not given
- if cellColours is None:
- cellColours = ['w' * cols] * rows
-
- # Now create the table
- table = Table(ax, loc, bbox, **kwargs)
- table.edges = edges
- height = table._approx_text_height()
-
- # Add the cells
- for row in xrange(rows):
- for col in xrange(cols):
- table.add_cell(row + offset, col,
- width=colWidths[col], height=height,
- text=cellText[row][col],
- facecolor=cellColours[row][col],
- loc=cellLoc)
- # Do column labels
- if colLabels is not None:
- for col in xrange(cols):
- table.add_cell(0, col,
- width=colWidths[col], height=height,
- text=colLabels[col], facecolor=colColours[col],
- loc=colLoc)
-
- # Do row labels
- if rowLabels is not None:
- for row in xrange(rows):
- table.add_cell(row + offset, -1,
- width=rowLabelWidth or 1e-15, height=height,
- text=rowLabels[row], facecolor=rowColours[row],
- loc=rowLoc)
- if rowLabelWidth == 0:
- table.auto_set_column_width(-1)
-
- ax.add_table(table)
- return table
-
-
-docstring.interpd.update(Table=artist.kwdoc(Table))
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/__init__.py b/contrib/python/matplotlib/py2/matplotlib/testing/__init__.py
deleted file mode 100644
index 2184be03ef..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/__init__.py
+++ /dev/null
@@ -1,59 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import functools
-import warnings
-
-import matplotlib as mpl
-from matplotlib import cbook
-
-
-def is_called_from_pytest():
- """Returns whether the call was done from pytest"""
- return getattr(mpl, '_called_from_pytest', False)
-
-
-def _copy_metadata(src_func, tgt_func):
- """Replicates metadata of the function. Returns target function."""
- functools.update_wrapper(tgt_func, src_func)
- tgt_func.__wrapped__ = src_func # Python2 compatibility.
- return tgt_func
-
-
-def set_font_settings_for_testing():
- mpl.rcParams['font.family'] = 'DejaVu Sans'
- mpl.rcParams['text.hinting'] = False
- mpl.rcParams['text.hinting_factor'] = 8
-
-
-def set_reproducibility_for_testing():
- mpl.rcParams['svg.hashsalt'] = 'matplotlib'
-
-
-def setup():
- # The baseline images are created in this locale, so we should use
- # it during all of the tests.
- import locale
- from matplotlib.backends import backend_agg, backend_pdf, backend_svg
-
- try:
- locale.setlocale(locale.LC_ALL, str('en_US.UTF-8'))
- except locale.Error:
- try:
- locale.setlocale(locale.LC_ALL, str('English_United States.1252'))
- except locale.Error:
- warnings.warn(
- "Could not set locale to English/United States. "
- "Some date-related tests may fail")
-
- mpl.use('Agg', warn=False) # use Agg backend for these tests
-
- # These settings *must* be hardcoded for running the comparison
- # tests and are not necessarily the default values as specified in
- # rcsetup.py
- mpl.rcdefaults() # Start with all defaults
-
- set_font_settings_for_testing()
- set_reproducibility_for_testing()
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/_nose/__init__.py b/contrib/python/matplotlib/py2/matplotlib/testing/_nose/__init__.py
deleted file mode 100644
index d513c7b14f..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/_nose/__init__.py
+++ /dev/null
@@ -1,78 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import sys
-
-
-def get_extra_test_plugins():
- from .plugins.performgc import PerformGC
- from .plugins.knownfailure import KnownFailure
- from nose.plugins import attrib
-
- return [PerformGC, KnownFailure, attrib.Plugin]
-
-
-def get_env():
- env = {'NOSE_COVER_PACKAGE': ['matplotlib', 'mpl_toolkits'],
- 'NOSE_COVER_HTML': 1,
- 'NOSE_COVER_NO_PRINT': 1}
- return env
-
-
-def check_deps():
- try:
- import nose
- try:
- from unittest import mock
- except ImportError:
- import mock
- except ImportError:
- print("matplotlib.test requires nose and mock to run.")
- raise
-
-
-def test(verbosity=None, coverage=False, switch_backend_warn=True,
- recursionlimit=0, **kwargs):
- from ... import default_test_modules, get_backend, use
-
- old_backend = get_backend()
- old_recursionlimit = sys.getrecursionlimit()
- try:
- use('agg')
- if recursionlimit:
- sys.setrecursionlimit(recursionlimit)
- import nose
- from nose.plugins import multiprocess
-
- # Nose doesn't automatically instantiate all of the plugins in the
- # child processes, so we have to provide the multiprocess plugin with
- # a list.
- extra_plugins = get_extra_test_plugins()
- multiprocess._instantiate_plugins = extra_plugins
-
- env = get_env()
- if coverage:
- env['NOSE_WITH_COVERAGE'] = 1
-
- if verbosity is not None:
- env['NOSE_VERBOSE'] = verbosity
-
- success = nose.run(
- addplugins=[plugin() for plugin in extra_plugins],
- env=env,
- defaultTest=default_test_modules,
- **kwargs
- )
- finally:
- if old_backend.lower() != 'agg':
- use(old_backend, warn=switch_backend_warn)
- if recursionlimit:
- sys.setrecursionlimit(old_recursionlimit)
-
- return success
-
-
-def knownfail(msg):
- from .exceptions import KnownFailureTest
- # Keep the next ultra-long comment so it shows in console.
- raise KnownFailureTest(msg) # An error here when running nose means that you don't have the matplotlib.testing.nose.plugins:KnownFailure plugin in use. # noqa
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/_nose/decorators.py b/contrib/python/matplotlib/py2/matplotlib/testing/_nose/decorators.py
deleted file mode 100644
index 1f0807df20..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/_nose/decorators.py
+++ /dev/null
@@ -1,33 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from .. import _copy_metadata
-from . import knownfail
-from .exceptions import KnownFailureDidNotFailTest
-
-
-def knownfailureif(fail_condition, msg=None, known_exception_class=None):
- # based on numpy.testing.dec.knownfailureif
- if msg is None:
- msg = 'Test known to fail'
-
- def known_fail_decorator(f):
- def failer(*args, **kwargs):
- try:
- # Always run the test (to generate images).
- result = f(*args, **kwargs)
- except Exception as err:
- if fail_condition:
- if known_exception_class is not None:
- if not isinstance(err, known_exception_class):
- # This is not the expected exception
- raise
- knownfail(msg)
- else:
- raise
- if fail_condition and fail_condition != 'indeterminate':
- raise KnownFailureDidNotFailTest(msg)
- return result
- return _copy_metadata(f, failer)
- return known_fail_decorator
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/_nose/exceptions.py b/contrib/python/matplotlib/py2/matplotlib/testing/_nose/exceptions.py
deleted file mode 100644
index 51fc6f782d..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/_nose/exceptions.py
+++ /dev/null
@@ -1,10 +0,0 @@
-class KnownFailureTest(Exception):
- """
- Raise this exception to mark a test as a known failing test.
- """
-
-
-class KnownFailureDidNotFailTest(Exception):
- """
- Raise this exception to mark a test should have failed but did not.
- """
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/_nose/plugins/__init__.py b/contrib/python/matplotlib/py2/matplotlib/testing/_nose/plugins/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/_nose/plugins/__init__.py
+++ /dev/null
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/_nose/plugins/knownfailure.py b/contrib/python/matplotlib/py2/matplotlib/testing/_nose/plugins/knownfailure.py
deleted file mode 100644
index 3a5c86c350..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/_nose/plugins/knownfailure.py
+++ /dev/null
@@ -1,49 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import os
-from nose.plugins.errorclass import ErrorClass, ErrorClassPlugin
-from ..exceptions import KnownFailureTest
-
-
-class KnownFailure(ErrorClassPlugin):
- '''Plugin that installs a KNOWNFAIL error class for the
- KnownFailureClass exception. When KnownFailureTest is raised,
- the exception will be logged in the knownfail attribute of the
- result, 'K' or 'KNOWNFAIL' (verbose) will be output, and the
- exception will not be counted as an error or failure.
-
- This is based on numpy.testing.noseclasses.KnownFailure.
- '''
- enabled = True
- knownfail = ErrorClass(KnownFailureTest,
- label='KNOWNFAIL',
- isfailure=False)
-
- def options(self, parser, env=os.environ):
- env_opt = 'NOSE_WITHOUT_KNOWNFAIL'
- parser.add_option('--no-knownfail', action='store_true',
- dest='noKnownFail', default=env.get(env_opt, False),
- help='Disable special handling of KnownFailureTest '
- 'exceptions')
-
- def configure(self, options, conf):
- if not self.can_configure:
- return
- self.conf = conf
- disable = getattr(options, 'noKnownFail', False)
- if disable:
- self.enabled = False
-
- def addError(self, test, err, *zero_nine_capt_args):
- # Fixme (Really weird): if I don't leave empty method here,
- # nose gets confused and KnownFails become testing errors when
- # using the MplNosePlugin and MplTestCase.
-
- # The *zero_nine_capt_args captures an extra argument. There
- # seems to be a bug in
- # nose.testing.manager.ZeroNinePlugin.addError() in which a
- # 3rd positional argument ("capt") is passed to the plugin's
- # addError() method, even if one is not explicitly using the
- # ZeroNinePlugin.
- pass
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/_nose/plugins/performgc.py b/contrib/python/matplotlib/py2/matplotlib/testing/_nose/plugins/performgc.py
deleted file mode 100644
index 818fbd96f4..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/_nose/plugins/performgc.py
+++ /dev/null
@@ -1,26 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import gc
-import os
-from nose.plugins import Plugin
-
-
-class PerformGC(Plugin):
- """This plugin adds option to call ``gc.collect`` after each test"""
- enabled = False
-
- def options(self, parser, env=os.environ):
- env_opt = 'PERFORM_GC'
- parser.add_option('--perform-gc', action='store_true',
- dest='performGC', default=env.get(env_opt, False),
- help='Call gc.collect() after each test')
-
- def configure(self, options, conf):
- if not self.can_configure:
- return
-
- self.enabled = getattr(options, 'performGC', False)
-
- def afterTest(self, test):
- gc.collect()
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/compare.py b/contrib/python/matplotlib/py2/matplotlib/testing/compare.py
deleted file mode 100644
index dcda681d43..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/compare.py
+++ /dev/null
@@ -1,489 +0,0 @@
-"""
-Provides a collection of utilities for comparing (image) results.
-
-"""
-from __future__ import absolute_import, division, print_function
-
-import six
-
-import atexit
-import functools
-import hashlib
-import itertools
-import os
-import re
-import shutil
-import sys
-from tempfile import TemporaryFile
-
-import numpy as np
-
-import matplotlib
-from matplotlib.compat import subprocess
-from matplotlib.testing.exceptions import ImageComparisonFailure
-from matplotlib import _png
-from matplotlib import _get_cachedir
-from matplotlib import cbook
-
-__all__ = ['compare_float', 'compare_images', 'comparable_formats']
-
-
-def make_test_filename(fname, purpose):
- """
- Make a new filename by inserting `purpose` before the file's
- extension.
- """
- base, ext = os.path.splitext(fname)
- return '%s-%s%s' % (base, purpose, ext)
-
-
-def compare_float(expected, actual, relTol=None, absTol=None):
- """
- Fail if the floating point values are not close enough, with
- the given message.
-
- You can specify a relative tolerance, absolute tolerance, or both.
-
- """
- if relTol is None and absTol is None:
- raise ValueError("You haven't specified a 'relTol' relative "
- "tolerance or a 'absTol' absolute tolerance "
- "function argument. You must specify one.")
- msg = ""
-
- if absTol is not None:
- absDiff = abs(expected - actual)
- if absTol < absDiff:
- template = ['',
- 'Expected: {expected}',
- 'Actual: {actual}',
- 'Abs diff: {absDiff}',
- 'Abs tol: {absTol}']
- msg += '\n '.join([line.format(**locals()) for line in template])
-
- if relTol is not None:
- # The relative difference of the two values. If the expected value is
- # zero, then return the absolute value of the difference.
- relDiff = abs(expected - actual)
- if expected:
- relDiff = relDiff / abs(expected)
-
- if relTol < relDiff:
- # The relative difference is a ratio, so it's always unit-less.
- template = ['',
- 'Expected: {expected}',
- 'Actual: {actual}',
- 'Rel diff: {relDiff}',
- 'Rel tol: {relTol}']
- msg += '\n '.join([line.format(**locals()) for line in template])
-
- return msg or None
-
-
-def get_cache_dir():
- cachedir = _get_cachedir()
- if cachedir is None:
- raise RuntimeError('Could not find a suitable configuration directory')
- cache_dir = os.path.join(cachedir, 'test_cache')
- if not os.path.exists(cache_dir):
- try:
- cbook.mkdirs(cache_dir)
- except IOError:
- return None
- if not os.access(cache_dir, os.W_OK):
- return None
- return cache_dir
-
-
-def get_file_hash(path, block_size=2 ** 20):
- md5 = hashlib.md5()
- with open(path, 'rb') as fd:
- while True:
- data = fd.read(block_size)
- if not data:
- break
- md5.update(data)
-
- if path.endswith('.pdf'):
- from matplotlib import checkdep_ghostscript
- md5.update(checkdep_ghostscript()[1].encode('utf-8'))
- elif path.endswith('.svg'):
- from matplotlib import checkdep_inkscape
- md5.update(checkdep_inkscape().encode('utf-8'))
-
- return md5.hexdigest()
-
-
-def make_external_conversion_command(cmd):
- def convert(old, new):
- cmdline = cmd(old, new)
- pipe = subprocess.Popen(cmdline, universal_newlines=True,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- stdout, stderr = pipe.communicate()
- errcode = pipe.wait()
- if not os.path.exists(new) or errcode:
- msg = "Conversion command failed:\n%s\n" % ' '.join(cmdline)
- if stdout:
- msg += "Standard output:\n%s\n" % stdout
- if stderr:
- msg += "Standard error:\n%s\n" % stderr
- raise IOError(msg)
-
- return convert
-
-
-# Modified from https://bugs.python.org/issue25567.
-_find_unsafe_bytes = re.compile(br'[^a-zA-Z0-9_@%+=:,./-]').search
-
-
-def _shlex_quote_bytes(b):
- return (b if _find_unsafe_bytes(b) is None
- else b"'" + b.replace(b"'", b"'\"'\"'") + b"'")
-
-
-class _SVGConverter(object):
- def __init__(self):
- self._proc = None
- # We cannot rely on the GC to trigger `__del__` at exit because
- # other modules (e.g. `subprocess`) may already have their globals
- # set to `None`, which make `proc.communicate` or `proc.terminate`
- # fail. By relying on `atexit` we ensure the destructor runs before
- # `None`-setting occurs.
- atexit.register(self.__del__)
-
- def _read_to_prompt(self):
- """Did Inkscape reach the prompt without crashing?
- """
- stream = iter(functools.partial(self._proc.stdout.read, 1), b"")
- prompt = (b"\n", b">")
- n = len(prompt)
- its = itertools.tee(stream, n)
- for i, it in enumerate(its):
- next(itertools.islice(it, i, i), None) # Advance `it` by `i`.
- while True:
- window = tuple(map(next, its))
- if len(window) != n:
- # Ran out of data -- one of the `next(it)` raised
- # StopIteration, so the tuple is shorter.
- return False
- if self._proc.poll() is not None:
- # Inkscape exited.
- return False
- if window == prompt:
- # Successfully read until prompt.
- return True
-
- def __call__(self, orig, dest):
- if (not self._proc # First run.
- or self._proc.poll() is not None): # Inkscape terminated.
- env = os.environ.copy()
- # If one passes e.g. a png file to Inkscape, it will try to
- # query the user for conversion options via a GUI (even with
- # `--without-gui`). Unsetting `DISPLAY` prevents this (and causes
- # GTK to crash and Inkscape to terminate, but that'll just be
- # reported as a regular exception below).
- env.pop("DISPLAY", None) # May already be unset.
- # Do not load any user options.
- # `os.environ` needs native strings on Py2+Windows.
- env[str("INKSCAPE_PROFILE_DIR")] = os.devnull
- # Old versions of Inkscape (0.48.3.1, used on Travis as of now)
- # seem to sometimes deadlock when stderr is redirected to a pipe,
- # so we redirect it to a temporary file instead. This is not
- # necessary anymore as of Inkscape 0.92.1.
- self._stderr = TemporaryFile()
- self._proc = subprocess.Popen(
- [str("inkscape"), "--without-gui", "--shell"],
- stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- stderr=self._stderr, env=env)
- if not self._read_to_prompt():
- raise OSError("Failed to start Inkscape")
-
- try:
- fsencode = os.fsencode
- except AttributeError: # Py2.
- def fsencode(s):
- return s.encode(sys.getfilesystemencoding())
-
- # Inkscape uses glib's `g_shell_parse_argv`, which has a consistent
- # behavior across platforms, so we can just use `shlex.quote`.
- orig_b, dest_b = map(_shlex_quote_bytes, map(fsencode, [orig, dest]))
- if b"\n" in orig_b or b"\n" in dest_b:
- # Who knows whether the current folder name has a newline, or if
- # our encoding is even ASCII compatible... Just fall back on the
- # slow solution (Inkscape uses `fgets` so it will always stop at a
- # newline).
- return make_external_conversion_command(lambda old, new: [
- str('inkscape'), '-z', old, '--export-png', new])(orig, dest)
- self._proc.stdin.write(orig_b + b" --export-png=" + dest_b + b"\n")
- self._proc.stdin.flush()
- if not self._read_to_prompt():
- # Inkscape's output is not localized but gtk's is, so the
- # output stream probably has a mixed encoding. Using
- # `getfilesystemencoding` should at least get the filenames
- # right...
- self._stderr.seek(0)
- raise ImageComparisonFailure(
- self._stderr.read().decode(
- sys.getfilesystemencoding(), "replace"))
-
- def __del__(self):
- if self._proc:
- if self._proc.poll() is None: # Not exited yet.
- self._proc.communicate(b"quit\n")
- self._proc.wait()
- self._proc.stdin.close()
- self._proc.stdout.close()
- self._stderr.close()
-
-
-def _update_converter():
- gs, gs_v = matplotlib.checkdep_ghostscript()
- if gs_v is not None:
- def cmd(old, new):
- return [str(gs), '-q', '-sDEVICE=png16m', '-dNOPAUSE', '-dBATCH',
- '-sOutputFile=' + new, old]
- converter['pdf'] = make_external_conversion_command(cmd)
- converter['eps'] = make_external_conversion_command(cmd)
-
- if matplotlib.checkdep_inkscape() is not None:
- converter['svg'] = _SVGConverter()
-
-
-#: A dictionary that maps filename extensions to functions which
-#: themselves map arguments `old` and `new` (filenames) to a list of strings.
-#: The list can then be passed to Popen to convert files with that
-#: extension to png format.
-converter = {}
-_update_converter()
-
-
-def comparable_formats():
- """
- Returns the list of file formats that compare_images can compare
- on this system.
-
- """
- return ['png'] + list(converter)
-
-
-def convert(filename, cache):
- """
- Convert the named file into a png file. Returns the name of the
- created file.
-
- If *cache* is True, the result of the conversion is cached in
- `matplotlib._get_cachedir() + '/test_cache/'`. The caching is based
- on a hash of the exact contents of the input file. The is no limit
- on the size of the cache, so it may need to be manually cleared
- periodically.
-
- """
- base, extension = filename.rsplit('.', 1)
- if extension not in converter:
- reason = "Don't know how to convert %s files to png" % extension
- from . import is_called_from_pytest
- if is_called_from_pytest():
- import pytest
- pytest.skip(reason)
- else:
- from nose import SkipTest
- raise SkipTest(reason)
- newname = base + '_' + extension + '.png'
- if not os.path.exists(filename):
- raise IOError("'%s' does not exist" % filename)
-
- # Only convert the file if the destination doesn't already exist or
- # is out of date.
- if (not os.path.exists(newname) or
- os.stat(newname).st_mtime < os.stat(filename).st_mtime):
- if cache:
- cache_dir = get_cache_dir()
- else:
- cache_dir = None
-
- if cache_dir is not None:
- hash_value = get_file_hash(filename)
- new_ext = os.path.splitext(newname)[1]
- cached_file = os.path.join(cache_dir, hash_value + new_ext)
- if os.path.exists(cached_file):
- shutil.copyfile(cached_file, newname)
- return newname
-
- converter[extension](filename, newname)
-
- if cache_dir is not None:
- shutil.copyfile(newname, cached_file)
-
- return newname
-
-#: Maps file extensions to a function which takes a filename as its
-#: only argument to return a list suitable for execution with Popen.
-#: The purpose of this is so that the result file (with the given
-#: extension) can be verified with tools such as xmllint for svg.
-verifiers = {}
-
-# Turning this off, because it seems to cause multiprocessing issues
-if False and matplotlib.checkdep_xmllint():
- verifiers['svg'] = lambda filename: [
- 'xmllint', '--valid', '--nowarning', '--noout', filename]
-
-
-@cbook.deprecated("2.1")
-def verify(filename):
- """Verify the file through some sort of verification tool."""
- if not os.path.exists(filename):
- raise IOError("'%s' does not exist" % filename)
- base, extension = filename.rsplit('.', 1)
- verifier = verifiers.get(extension, None)
- if verifier is not None:
- cmd = verifier(filename)
- pipe = subprocess.Popen(cmd, universal_newlines=True,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- stdout, stderr = pipe.communicate()
- errcode = pipe.wait()
- if errcode != 0:
- msg = "File verification command failed:\n%s\n" % ' '.join(cmd)
- if stdout:
- msg += "Standard output:\n%s\n" % stdout
- if stderr:
- msg += "Standard error:\n%s\n" % stderr
- raise IOError(msg)
-
-
-def crop_to_same(actual_path, actual_image, expected_path, expected_image):
- # clip the images to the same size -- this is useful only when
- # comparing eps to pdf
- if actual_path[-7:-4] == 'eps' and expected_path[-7:-4] == 'pdf':
- aw, ah, ad = actual_image.shape
- ew, eh, ed = expected_image.shape
- actual_image = actual_image[int(aw / 2 - ew / 2):int(
- aw / 2 + ew / 2), int(ah / 2 - eh / 2):int(ah / 2 + eh / 2)]
- return actual_image, expected_image
-
-
-def calculate_rms(expectedImage, actualImage):
- "Calculate the per-pixel errors, then compute the root mean square error."
- if expectedImage.shape != actualImage.shape:
- raise ImageComparisonFailure(
- "Image sizes do not match expected size: {0} "
- "actual size {1}".format(expectedImage.shape, actualImage.shape))
- # Convert to float to avoid overflowing finite integer types.
- return np.sqrt(((expectedImage - actualImage).astype(float) ** 2).mean())
-
-
-def compare_images(expected, actual, tol, in_decorator=False):
- """
- Compare two "image" files checking differences within a tolerance.
-
- The two given filenames may point to files which are convertible to
- PNG via the `.converter` dictionary. The underlying RMS is calculated
- with the `.calculate_rms` function.
-
- Parameters
- ----------
- expected : str
- The filename of the expected image.
- actual :str
- The filename of the actual image.
- tol : float
- The tolerance (a color value difference, where 255 is the
- maximal difference). The test fails if the average pixel
- difference is greater than this value.
- in_decorator : bool
- If called from image_comparison decorator, this should be
- True. (default=False)
-
- Examples
- --------
- img1 = "./baseline/plot.png"
- img2 = "./output/plot.png"
- compare_images( img1, img2, 0.001 ):
-
- """
- if not os.path.exists(actual):
- raise Exception("Output image %s does not exist." % actual)
-
- if os.stat(actual).st_size == 0:
- raise Exception("Output image file %s is empty." % actual)
-
- # Convert the image to png
- extension = expected.split('.')[-1]
-
- if not os.path.exists(expected):
- raise IOError('Baseline image %r does not exist.' % expected)
-
- if extension != 'png':
- actual = convert(actual, False)
- expected = convert(expected, True)
-
- # open the image files and remove the alpha channel (if it exists)
- expectedImage = _png.read_png_int(expected)
- actualImage = _png.read_png_int(actual)
- expectedImage = expectedImage[:, :, :3]
- actualImage = actualImage[:, :, :3]
-
- actualImage, expectedImage = crop_to_same(
- actual, actualImage, expected, expectedImage)
-
- diff_image = make_test_filename(actual, 'failed-diff')
-
- if tol <= 0.0:
- if np.array_equal(expectedImage, actualImage):
- return None
-
- # convert to signed integers, so that the images can be subtracted without
- # overflow
- expectedImage = expectedImage.astype(np.int16)
- actualImage = actualImage.astype(np.int16)
-
- rms = calculate_rms(expectedImage, actualImage)
-
- if rms <= tol:
- return None
-
- save_diff_image(expected, actual, diff_image)
-
- results = dict(rms=rms, expected=str(expected),
- actual=str(actual), diff=str(diff_image), tol=tol)
-
- if not in_decorator:
- # Then the results should be a string suitable for stdout.
- template = ['Error: Image files did not match.',
- 'RMS Value: {rms}',
- 'Expected: \n {expected}',
- 'Actual: \n {actual}',
- 'Difference:\n {diff}',
- 'Tolerance: \n {tol}', ]
- results = '\n '.join([line.format(**results) for line in template])
- return results
-
-
-def save_diff_image(expected, actual, output):
- expectedImage = _png.read_png(expected)
- actualImage = _png.read_png(actual)
- actualImage, expectedImage = crop_to_same(
- actual, actualImage, expected, expectedImage)
- expectedImage = np.array(expectedImage).astype(float)
- actualImage = np.array(actualImage).astype(float)
- if expectedImage.shape != actualImage.shape:
- raise ImageComparisonFailure(
- "Image sizes do not match expected size: {0} "
- "actual size {1}".format(expectedImage.shape, actualImage.shape))
- absDiffImage = np.abs(expectedImage - actualImage)
-
- # expand differences in luminance domain
- absDiffImage *= 255 * 10
- save_image_np = np.clip(absDiffImage, 0, 255).astype(np.uint8)
- height, width, depth = save_image_np.shape
-
- # The PDF renderer doesn't produce an alpha channel, but the
- # matplotlib PNG writer requires one, so expand the array
- if depth == 3:
- with_alpha = np.empty((height, width, 4), dtype=np.uint8)
- with_alpha[:, :, 0:3] = save_image_np
- save_image_np = with_alpha
-
- # Hard-code the alpha channel to fully solid
- save_image_np[:, :, 3] = 255
-
- _png.write_png(save_image_np, output)
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/conftest.py b/contrib/python/matplotlib/py2/matplotlib/testing/conftest.py
deleted file mode 100644
index fb30659478..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/conftest.py
+++ /dev/null
@@ -1,100 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import pytest
-
-import matplotlib
-
-
-def pytest_configure(config):
- matplotlib.use('agg')
- matplotlib._called_from_pytest = True
- matplotlib._init_tests()
-
-
-def pytest_unconfigure(config):
- matplotlib._called_from_pytest = False
-
-
-@pytest.fixture(autouse=True)
-def mpl_test_settings(request):
- from matplotlib.testing.decorators import _do_cleanup
-
- original_units_registry = matplotlib.units.registry.copy()
- original_settings = matplotlib.rcParams.copy()
-
- backend = None
- backend_marker = request.node.get_closest_marker('backend')
- if backend_marker is not None:
- assert len(backend_marker.args) == 1, \
- "Marker 'backend' must specify 1 backend."
- backend, = backend_marker.args
- prev_backend = matplotlib.get_backend()
-
- style = '_classic_test' # Default of cleanup and image_comparison too.
- style_marker = request.node.get_closest_marker('style')
- if style_marker is not None:
- assert len(style_marker.args) == 1, \
- "Marker 'style' must specify 1 style."
- style, = style_marker.args
-
- matplotlib.testing.setup()
- if backend is not None:
- # This import must come after setup() so it doesn't load the default
- # backend prematurely.
- import matplotlib.pyplot as plt
- plt.switch_backend(backend)
- matplotlib.style.use(style)
- try:
- yield
- finally:
- if backend is not None:
- plt.switch_backend(prev_backend)
- _do_cleanup(original_units_registry,
- original_settings)
-
-
-@pytest.fixture
-def mpl_image_comparison_parameters(request, extension):
- # This fixture is applied automatically by the image_comparison decorator.
- #
- # The sole purpose of this fixture is to provide an indirect method of
- # obtaining parameters *without* modifying the decorated function
- # signature. In this way, the function signature can stay the same and
- # pytest won't get confused.
- # We annotate the decorated function with any parameters captured by this
- # fixture so that they can be used by the wrapper in image_comparison.
- baseline_images, = request.node.get_closest_marker('baseline_images').args
- if baseline_images is None:
- # Allow baseline image list to be produced on the fly based on current
- # parametrization.
- baseline_images = request.getfixturevalue('baseline_images')
-
- func = request.function
- func.__wrapped__.parameters = (baseline_images, extension)
- try:
- yield
- finally:
- delattr(func.__wrapped__, 'parameters')
-
-
-@pytest.fixture
-def pd():
- """Fixture to import and configure pandas."""
- pd = pytest.importorskip('pandas')
- try:
- from pandas.plotting import (
- register_matplotlib_converters as register)
- except ImportError:
- from pandas.tseries.converter import register
- register()
- try:
- yield pd
- finally:
- try:
- from pandas.plotting import (
- deregister_matplotlib_converters as deregister)
- except ImportError:
- pass
- else:
- deregister()
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/decorators.py b/contrib/python/matplotlib/py2/matplotlib/testing/decorators.py
deleted file mode 100644
index d008446dcb..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/decorators.py
+++ /dev/null
@@ -1,589 +0,0 @@
-from __future__ import absolute_import, division, print_function
-
-import six
-
-import functools
-import inspect
-import os
-import sys
-import shutil
-import warnings
-import unittest
-
-# Note - don't import nose up here - import it only as needed in functions.
-# This allows other functions here to be used by pytest-based testing suites
-# without requiring nose to be installed.
-
-
-import matplotlib as mpl
-import matplotlib.style
-import matplotlib.units
-import matplotlib.testing
-from matplotlib import cbook
-from matplotlib import ticker
-from matplotlib import pyplot as plt
-from matplotlib import ft2font
-from matplotlib.testing.compare import (
- comparable_formats, compare_images, make_test_filename)
-from . import _copy_metadata, is_called_from_pytest
-from .exceptions import ImageComparisonFailure
-
-
-def _knownfailureif(fail_condition, msg=None, known_exception_class=None):
- """
-
- Assume a will fail if *fail_condition* is True. *fail_condition*
- may also be False or the string 'indeterminate'.
-
- *msg* is the error message displayed for the test.
-
- If *known_exception_class* is not None, the failure is only known
- if the exception is an instance of this class. (Default = None)
-
- """
- if is_called_from_pytest():
- import pytest
- if fail_condition == 'indeterminate':
- fail_condition, strict = True, False
- else:
- fail_condition, strict = bool(fail_condition), True
- return pytest.mark.xfail(condition=fail_condition, reason=msg,
- raises=known_exception_class, strict=strict)
- else:
- from ._nose.decorators import knownfailureif
- return knownfailureif(fail_condition, msg, known_exception_class)
-
-
-@cbook.deprecated('2.1',
- alternative='pytest.xfail or import the plugin')
-def knownfailureif(fail_condition, msg=None, known_exception_class=None):
- _knownfailureif(fail_condition, msg, known_exception_class)
-
-
-def _do_cleanup(original_units_registry, original_settings):
- plt.close('all')
-
- mpl.rcParams.clear()
- mpl.rcParams.update(original_settings)
- matplotlib.units.registry.clear()
- matplotlib.units.registry.update(original_units_registry)
- warnings.resetwarnings() # reset any warning filters set in tests
-
-
-class CleanupTest(object):
- @classmethod
- def setup_class(cls):
- cls.original_units_registry = matplotlib.units.registry.copy()
- cls.original_settings = mpl.rcParams.copy()
- matplotlib.testing.setup()
-
- @classmethod
- def teardown_class(cls):
- _do_cleanup(cls.original_units_registry,
- cls.original_settings)
-
- def test(self):
- self._func()
-
-
-class CleanupTestCase(unittest.TestCase):
- '''A wrapper for unittest.TestCase that includes cleanup operations'''
- @classmethod
- def setUpClass(cls):
- import matplotlib.units
- cls.original_units_registry = matplotlib.units.registry.copy()
- cls.original_settings = mpl.rcParams.copy()
-
- @classmethod
- def tearDownClass(cls):
- _do_cleanup(cls.original_units_registry,
- cls.original_settings)
-
-
-def cleanup(style=None):
- """
- A decorator to ensure that any global state is reset before
- running a test.
-
- Parameters
- ----------
- style : str, optional
- The name of the style to apply.
- """
-
- # If cleanup is used without arguments, `style` will be a
- # callable, and we pass it directly to the wrapper generator. If
- # cleanup if called with an argument, it is a string naming a
- # style, and the function will be passed as an argument to what we
- # return. This is a confusing, but somewhat standard, pattern for
- # writing a decorator with optional arguments.
-
- def make_cleanup(func):
- if inspect.isgeneratorfunction(func):
- @functools.wraps(func)
- def wrapped_callable(*args, **kwargs):
- original_units_registry = matplotlib.units.registry.copy()
- original_settings = mpl.rcParams.copy()
- matplotlib.style.use(style)
- try:
- for yielded in func(*args, **kwargs):
- yield yielded
- finally:
- _do_cleanup(original_units_registry,
- original_settings)
- else:
- @functools.wraps(func)
- def wrapped_callable(*args, **kwargs):
- original_units_registry = matplotlib.units.registry.copy()
- original_settings = mpl.rcParams.copy()
- matplotlib.style.use(style)
- try:
- func(*args, **kwargs)
- finally:
- _do_cleanup(original_units_registry,
- original_settings)
-
- return wrapped_callable
-
- if isinstance(style, six.string_types):
- return make_cleanup
- else:
- result = make_cleanup(style)
- # Default of mpl_test_settings fixture and image_comparison too.
- style = '_classic_test'
- return result
-
-
-def check_freetype_version(ver):
- if ver is None:
- return True
-
- from distutils import version
- if isinstance(ver, six.string_types):
- ver = (ver, ver)
- ver = [version.StrictVersion(x) for x in ver]
- found = version.StrictVersion(ft2font.__freetype_version__)
-
- return found >= ver[0] and found <= ver[1]
-
-
-def _checked_on_freetype_version(required_freetype_version):
- if check_freetype_version(required_freetype_version):
- return lambda f: f
-
- reason = ("Mismatched version of freetype. "
- "Test requires '%s', you have '%s'" %
- (required_freetype_version, ft2font.__freetype_version__))
- return _knownfailureif('indeterminate', msg=reason,
- known_exception_class=ImageComparisonFailure)
-
-
-def remove_ticks_and_titles(figure):
- figure.suptitle("")
- null_formatter = ticker.NullFormatter()
- for ax in figure.get_axes():
- ax.set_title("")
- ax.xaxis.set_major_formatter(null_formatter)
- ax.xaxis.set_minor_formatter(null_formatter)
- ax.yaxis.set_major_formatter(null_formatter)
- ax.yaxis.set_minor_formatter(null_formatter)
- try:
- ax.zaxis.set_major_formatter(null_formatter)
- ax.zaxis.set_minor_formatter(null_formatter)
- except AttributeError:
- pass
-
-
-def _raise_on_image_difference(expected, actual, tol):
- __tracebackhide__ = True
-
- err = compare_images(expected, actual, tol, in_decorator=True)
-
- if not os.path.exists(expected):
- raise ImageComparisonFailure('image does not exist: %s' % expected)
-
- if err:
- for key in ["actual", "expected"]:
- err[key] = os.path.relpath(err[key])
- raise ImageComparisonFailure(
- 'images not close (RMS %(rms).3f):\n\t%(actual)s\n\t%(expected)s '
- % err)
-
-
-def _xfail_if_format_is_uncomparable(extension):
- will_fail = extension not in comparable_formats()
- if will_fail:
- fail_msg = 'Cannot compare %s files on this system' % extension
- else:
- fail_msg = 'No failure expected'
-
- return _knownfailureif(will_fail, fail_msg,
- known_exception_class=ImageComparisonFailure)
-
-
-def _mark_xfail_if_format_is_uncomparable(extension):
- if isinstance(extension, six.string_types):
- name = extension
- marks = []
- elif isinstance(extension, tuple):
- # Extension might be a pytest ParameterSet instead of a plain string.
- # Unfortunately, this type is not exposed, so since it's a namedtuple,
- # check for a tuple instead.
- name = extension.values[0]
- marks = list(extension.marks)
- else:
- # Extension might be a pytest marker instead of a plain string.
- name = extension.args[0]
- marks = [extension.mark]
-
- if name not in comparable_formats():
- fail_msg = 'Cannot compare %s files on this system' % (name, )
- import pytest
- marks += [pytest.mark.xfail(reason=fail_msg, strict=False,
- raises=ImageComparisonFailure)]
- return pytest.param(name, marks=marks)
- else:
- return extension
-
-
-class _ImageComparisonBase(object):
- """
- Image comparison base class
-
- This class provides *just* the comparison-related functionality and avoids
- any code that would be specific to any testing framework.
- """
- def __init__(self, tol, remove_text, savefig_kwargs):
- self.func = self.baseline_dir = self.result_dir = None
- self.tol = tol
- self.remove_text = remove_text
- self.savefig_kwargs = savefig_kwargs
-
- def delayed_init(self, func):
- assert self.func is None, "it looks like same decorator used twice"
- self.func = func
- self.baseline_dir, self.result_dir = _image_directories(func)
-
- def copy_baseline(self, baseline, extension):
- baseline_path = os.path.join(self.baseline_dir, baseline)
- orig_expected_fname = baseline_path + '.' + extension
- if extension == 'eps' and not os.path.exists(orig_expected_fname):
- orig_expected_fname = baseline_path + '.pdf'
- expected_fname = make_test_filename(
- os.path.join(self.result_dir,
- os.path.basename(orig_expected_fname)),
- 'expected')
- if os.path.exists(orig_expected_fname):
- shutil.copyfile(orig_expected_fname, expected_fname)
- else:
- reason = ("Do not have baseline image {0} because this "
- "file does not exist: {1}".format(expected_fname,
- orig_expected_fname))
- raise ImageComparisonFailure(reason)
- return expected_fname
-
- def compare(self, idx, baseline, extension):
- __tracebackhide__ = True
- fignum = plt.get_fignums()[idx]
- fig = plt.figure(fignum)
-
- if self.remove_text:
- remove_ticks_and_titles(fig)
-
- actual_fname = (
- os.path.join(self.result_dir, baseline) + '.' + extension)
- kwargs = self.savefig_kwargs.copy()
- if extension == 'pdf':
- kwargs.setdefault('metadata',
- {'Creator': None, 'Producer': None,
- 'CreationDate': None})
- fig.savefig(actual_fname, **kwargs)
-
- expected_fname = self.copy_baseline(baseline, extension)
- _raise_on_image_difference(expected_fname, actual_fname, self.tol)
-
-
-class ImageComparisonTest(CleanupTest, _ImageComparisonBase):
- """
- Nose-based image comparison class
-
- This class generates tests for a nose-based testing framework. Ideally,
- this class would not be public, and the only publicly visible API would
- be the :func:`image_comparison` decorator. Unfortunately, there are
- existing downstream users of this class (e.g., pytest-mpl) so it cannot yet
- be removed.
- """
- def __init__(self, baseline_images, extensions, tol,
- freetype_version, remove_text, savefig_kwargs, style):
- _ImageComparisonBase.__init__(self, tol, remove_text, savefig_kwargs)
- self.baseline_images = baseline_images
- self.extensions = extensions
- self.freetype_version = freetype_version
- self.style = style
-
- def setup(self):
- func = self.func
- plt.close('all')
- self.setup_class()
- try:
- matplotlib.style.use(self.style)
- matplotlib.testing.set_font_settings_for_testing()
- func()
- assert len(plt.get_fignums()) == len(self.baseline_images), (
- "Test generated {} images but there are {} baseline images"
- .format(len(plt.get_fignums()), len(self.baseline_images)))
- except:
- # Restore original settings before raising errors.
- self.teardown_class()
- raise
-
- def teardown(self):
- self.teardown_class()
-
- @staticmethod
- @cbook.deprecated('2.1',
- alternative='remove_ticks_and_titles')
- def remove_text(figure):
- remove_ticks_and_titles(figure)
-
- def nose_runner(self):
- func = self.compare
- func = _checked_on_freetype_version(self.freetype_version)(func)
- funcs = {extension: _xfail_if_format_is_uncomparable(extension)(func)
- for extension in self.extensions}
- for idx, baseline in enumerate(self.baseline_images):
- for extension in self.extensions:
- yield funcs[extension], idx, baseline, extension
-
- def __call__(self, func):
- self.delayed_init(func)
- import nose.tools
-
- @nose.tools.with_setup(self.setup, self.teardown)
- def runner_wrapper():
- for case in self.nose_runner():
- yield case
-
- return _copy_metadata(func, runner_wrapper)
-
-
-def _pytest_image_comparison(baseline_images, extensions, tol,
- freetype_version, remove_text, savefig_kwargs,
- style):
- """
- Decorate function with image comparison for pytest.
-
- This function creates a decorator that wraps a figure-generating function
- with image comparison code. Pytest can become confused if we change the
- signature of the function, so we indirectly pass anything we need via the
- `mpl_image_comparison_parameters` fixture and extra markers.
- """
- import pytest
-
- extensions = map(_mark_xfail_if_format_is_uncomparable, extensions)
-
- def decorator(func):
- # Parameter indirection; see docstring above and comment below.
- @pytest.mark.usefixtures('mpl_image_comparison_parameters')
- @pytest.mark.parametrize('extension', extensions)
- @pytest.mark.baseline_images(baseline_images)
- # END Parameter indirection.
- @pytest.mark.style(style)
- @_checked_on_freetype_version(freetype_version)
- @functools.wraps(func)
- def wrapper(*args, **kwargs):
- __tracebackhide__ = True
- img = _ImageComparisonBase(tol=tol, remove_text=remove_text,
- savefig_kwargs=savefig_kwargs)
- img.delayed_init(func)
- matplotlib.testing.set_font_settings_for_testing()
- func(*args, **kwargs)
-
- # Parameter indirection:
- # This is hacked on via the mpl_image_comparison_parameters fixture
- # so that we don't need to modify the function's real signature for
- # any parametrization. Modifying the signature is very very tricky
- # and likely to confuse pytest.
- baseline_images, extension = func.parameters
-
- assert len(plt.get_fignums()) == len(baseline_images), (
- "Test generated {} images but there are {} baseline images"
- .format(len(plt.get_fignums()), len(baseline_images)))
- for idx, baseline in enumerate(baseline_images):
- img.compare(idx, baseline, extension)
-
- wrapper.__wrapped__ = func # For Python 2.7.
- return _copy_metadata(func, wrapper)
-
- return decorator
-
-
-def image_comparison(baseline_images, extensions=None, tol=0,
- freetype_version=None, remove_text=False,
- savefig_kwarg=None,
- # Default of mpl_test_settings fixture and cleanup too.
- style='_classic_test'):
- """
- Compare images generated by the test with those specified in
- *baseline_images*, which must correspond else an
- ImageComparisonFailure exception will be raised.
-
- Arguments
- ---------
- baseline_images : list or None
- A list of strings specifying the names of the images generated by
- calls to :meth:`matplotlib.figure.savefig`.
-
- If *None*, the test function must use the ``baseline_images`` fixture,
- either as a parameter or with pytest.mark.usefixtures. This value is
- only allowed when using pytest.
-
- extensions : [ None | list ]
-
- If None, defaults to all supported extensions.
- Otherwise, a list of extensions to test. For example ['png','pdf'].
-
- tol : float, optional, default: 0
- The RMS threshold above which the test is considered failed.
-
- freetype_version : str or tuple
- The expected freetype version or range of versions for this test to
- pass.
-
- remove_text : bool
- Remove the title and tick text from the figure before comparison.
- This does not remove other, more deliberate, text, such as legends and
- annotations.
-
- savefig_kwarg : dict
- Optional arguments that are passed to the savefig method.
-
- style : string
- Optional name for the base style to apply to the image test. The test
- itself can also apply additional styles if desired. Defaults to the
- '_classic_test' style.
-
- """
- if extensions is None:
- # default extensions to test
- extensions = ['png', 'pdf', 'svg']
-
- if savefig_kwarg is None:
- #default no kwargs to savefig
- savefig_kwarg = dict()
-
- if is_called_from_pytest():
- return _pytest_image_comparison(
- baseline_images=baseline_images, extensions=extensions, tol=tol,
- freetype_version=freetype_version, remove_text=remove_text,
- savefig_kwargs=savefig_kwarg, style=style)
- else:
- if baseline_images is None:
- raise ValueError('baseline_images must be specified')
-
- return ImageComparisonTest(
- baseline_images=baseline_images, extensions=extensions, tol=tol,
- freetype_version=freetype_version, remove_text=remove_text,
- savefig_kwargs=savefig_kwarg, style=style)
-
-
-def _image_directories(func):
- """
- Compute the baseline and result image directories for testing *func*.
- Create the result directory if it doesn't exist.
- """
- module_name = func.__module__
- if module_name == '__main__':
- # FIXME: this won't work for nested packages in matplotlib.tests
- warnings.warn(
- 'Test module run as script. Guessing baseline image locations.')
- script_name = sys.argv[0]
- basedir = os.path.abspath(os.path.dirname(script_name))
- subdir = os.path.splitext(os.path.split(script_name)[1])[0]
- else:
- mods = module_name.split('.')
- if len(mods) >= 3:
- mods.pop(0)
- # mods[0] will be the name of the package being tested (in
- # most cases "matplotlib") However if this is a
- # namespace package pip installed and run via the nose
- # multiprocess plugin or as a specific test this may be
- # missing. See https://github.com/matplotlib/matplotlib/issues/3314
- if mods.pop(0) != 'tests':
- warnings.warn(
- "Module {!r} does not live in a parent module named 'tests'. "
- "This is probably ok, but we may not be able to guess the "
- "correct subdirectory containing the baseline images. If "
- "things go wrong please make sure that there is a parent "
- "directory named 'tests' and that it contains a __init__.py "
- "file (can be empty).".format(module_name))
- subdir = os.path.join(*mods)
-
- import imp
- def find_dotted_module(module_name, path=None):
- """A version of imp which can handle dots in the module name.
- As for imp.find_module(), the return value is a 3-element
- tuple (file, pathname, description)."""
- res = None
- for sub_mod in module_name.split('.'):
- try:
- res = file, path, _ = imp.find_module(sub_mod, path)
- path = [path]
- if file is not None:
- file.close()
- except ImportError:
- # assume namespace package
- path = list(sys.modules[sub_mod].__path__)
- res = None, path, None
- return res
-
- mod_file = find_dotted_module(func.__module__)[1]
- basedir = os.path.dirname(mod_file)
-
- baseline_dir = os.path.join(basedir, 'baseline_images', subdir)
- result_dir = os.path.abspath(os.path.join('result_images', subdir))
-
- if not os.path.exists(result_dir):
- cbook.mkdirs(result_dir)
-
- return baseline_dir, result_dir
-
-
-def switch_backend(backend):
- # Local import to avoid a hard nose dependency and only incur the
- # import time overhead at actual test-time.
- def switch_backend_decorator(func):
- @functools.wraps(func)
- def backend_switcher(*args, **kwargs):
- try:
- prev_backend = mpl.get_backend()
- matplotlib.testing.setup()
- plt.switch_backend(backend)
- result = func(*args, **kwargs)
- finally:
- plt.switch_backend(prev_backend)
- return result
-
- return _copy_metadata(func, backend_switcher)
- return switch_backend_decorator
-
-
-def skip_if_command_unavailable(cmd):
- """
- skips a test if a command is unavailable.
-
- Parameters
- ----------
- cmd : list of str
- must be a complete command which should not
- return a non zero exit code, something like
- ["latex", "-version"]
- """
- from matplotlib.compat.subprocess import check_output
- try:
- check_output(cmd)
- except:
- import pytest
- return pytest.mark.skip(reason='missing command: %s' % cmd[0])
-
- return lambda f: f
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/determinism.py b/contrib/python/matplotlib/py2/matplotlib/testing/determinism.py
deleted file mode 100644
index 614544ce28..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/determinism.py
+++ /dev/null
@@ -1,145 +0,0 @@
-"""
-Provides utilities to test output reproducibility.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import io
-import os
-import re
-import sys
-from subprocess import check_output
-
-import pytest
-
-import matplotlib
-from matplotlib import pyplot as plt
-
-
-def _determinism_save(objects='mhi', format="pdf", usetex=False):
- # save current value of SOURCE_DATE_EPOCH and set it
- # to a constant value, so that time difference is not
- # taken into account
- sde = os.environ.pop('SOURCE_DATE_EPOCH', None)
- os.environ['SOURCE_DATE_EPOCH'] = "946684800"
-
- matplotlib.rcParams['text.usetex'] = usetex
-
- fig = plt.figure()
-
- if 'm' in objects:
- # use different markers...
- ax1 = fig.add_subplot(1, 6, 1)
- x = range(10)
- ax1.plot(x, [1] * 10, marker=u'D')
- ax1.plot(x, [2] * 10, marker=u'x')
- ax1.plot(x, [3] * 10, marker=u'^')
- ax1.plot(x, [4] * 10, marker=u'H')
- ax1.plot(x, [5] * 10, marker=u'v')
-
- if 'h' in objects:
- # also use different hatch patterns
- ax2 = fig.add_subplot(1, 6, 2)
- bars = (ax2.bar(range(1, 5), range(1, 5)) +
- ax2.bar(range(1, 5), [6] * 4, bottom=range(1, 5)))
- ax2.set_xticks([1.5, 2.5, 3.5, 4.5])
-
- patterns = ('-', '+', 'x', '\\', '*', 'o', 'O', '.')
- for bar, pattern in zip(bars, patterns):
- bar.set_hatch(pattern)
-
- if 'i' in objects:
- # also use different images
- A = [[1, 2, 3], [2, 3, 1], [3, 1, 2]]
- fig.add_subplot(1, 6, 3).imshow(A, interpolation='nearest')
- A = [[1, 3, 2], [1, 2, 3], [3, 1, 2]]
- fig.add_subplot(1, 6, 4).imshow(A, interpolation='bilinear')
- A = [[2, 3, 1], [1, 2, 3], [2, 1, 3]]
- fig.add_subplot(1, 6, 5).imshow(A, interpolation='bicubic')
-
- x = range(5)
- fig.add_subplot(1, 6, 6).plot(x, x)
-
- if six.PY2 and format == 'ps':
- stdout = io.StringIO()
- else:
- stdout = getattr(sys.stdout, 'buffer', sys.stdout)
- fig.savefig(stdout, format=format)
- if six.PY2 and format == 'ps':
- sys.stdout.write(stdout.getvalue())
-
- # Restores SOURCE_DATE_EPOCH
- if sde is None:
- os.environ.pop('SOURCE_DATE_EPOCH', None)
- else:
- os.environ['SOURCE_DATE_EPOCH'] = sde
-
-
-def _determinism_check(objects='mhi', format="pdf", usetex=False):
- """
- Output three times the same graphs and checks that the outputs are exactly
- the same.
-
- Parameters
- ----------
- objects : str
- contains characters corresponding to objects to be included in the test
- document: 'm' for markers, 'h' for hatch patterns, 'i' for images. The
- default value is "mhi", so that the test includes all these objects.
- format : str
- format string. The default value is "pdf".
- """
- plots = []
- for i in range(3):
- result = check_output([sys.executable, '-R', '-c',
- 'import matplotlib; '
- 'matplotlib._called_from_pytest = True; '
- 'matplotlib.use(%r); '
- 'from matplotlib.testing.determinism '
- 'import _determinism_save;'
- '_determinism_save(%r,%r,%r)'
- % (format, objects, format, usetex)])
- plots.append(result)
- for p in plots[1:]:
- if usetex:
- if p != plots[0]:
- pytest.skip("failed, maybe due to ghostscript timestamps")
- else:
- assert p == plots[0]
-
-
-def _determinism_source_date_epoch(format, string, keyword=b"CreationDate"):
- """
- Test SOURCE_DATE_EPOCH support. Output a document with the environment
- variable SOURCE_DATE_EPOCH set to 2000-01-01 00:00 UTC and check that the
- document contains the timestamp that corresponds to this date (given as an
- argument).
-
- Parameters
- ----------
- format : str
- format string, such as "pdf".
- string : str
- timestamp string for 2000-01-01 00:00 UTC.
- keyword : bytes
- a string to look at when searching for the timestamp in the document
- (used in case the test fails).
- """
- buff = check_output([sys.executable, '-R', '-c',
- 'import matplotlib; '
- 'matplotlib._called_from_pytest = True; '
- 'matplotlib.use(%r); '
- 'from matplotlib.testing.determinism '
- 'import _determinism_save;'
- '_determinism_save(%r,%r)'
- % (format, "", format)])
- find_keyword = re.compile(b".*" + keyword + b".*")
- key = find_keyword.search(buff)
- if key:
- print(key.group())
- else:
- print("Timestamp keyword (%s) not found!" % keyword)
- assert string in buff
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/disable_internet.py b/contrib/python/matplotlib/py2/matplotlib/testing/disable_internet.py
deleted file mode 100644
index e70c656527..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/disable_internet.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# Originally from astropy project (http://astropy.org), under BSD
-# 3-clause license.
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import contextlib
-import socket
-
-from six.moves import urllib
-
-# save original socket method for restoration
-# These are global so that re-calling the turn_off_internet function doesn't
-# overwrite them again
-socket_original = socket.socket
-socket_create_connection = socket.create_connection
-socket_bind = socket.socket.bind
-socket_connect = socket.socket.connect
-
-
-INTERNET_OFF = False
-
-# urllib2 uses a global variable to cache its default "opener" for opening
-# connections for various protocols; we store it off here so we can restore to
-# the default after re-enabling internet use
-_orig_opener = None
-
-
-# ::1 is apparently another valid name for localhost?
-# it is returned by getaddrinfo when that function is given localhost
-
-def check_internet_off(original_function):
- """
- Wraps ``original_function``, which in most cases is assumed
- to be a `socket.socket` method, to raise an `IOError` for any operations
- on non-local AF_INET sockets.
- """
-
- def new_function(*args, **kwargs):
- if isinstance(args[0], socket.socket):
- if not args[0].family in (socket.AF_INET, socket.AF_INET6):
- # Should be fine in all but some very obscure cases
- # More to the point, we don't want to affect AF_UNIX
- # sockets.
- return original_function(*args, **kwargs)
- host = args[1][0]
- addr_arg = 1
- valid_hosts = ('localhost', '127.0.0.1', '::1')
- else:
- # The only other function this is used to wrap currently is
- # socket.create_connection, which should be passed a 2-tuple, but
- # we'll check just in case
- if not (isinstance(args[0], tuple) and len(args[0]) == 2):
- return original_function(*args, **kwargs)
-
- host = args[0][0]
- addr_arg = 0
- valid_hosts = ('localhost', '127.0.0.1')
-
- hostname = socket.gethostname()
- fqdn = socket.getfqdn()
-
- if host in (hostname, fqdn):
- host = 'localhost'
- new_addr = (host, args[addr_arg][1])
- args = args[:addr_arg] + (new_addr,) + args[addr_arg + 1:]
-
- if any([h in host for h in valid_hosts]):
- return original_function(*args, **kwargs)
- else:
- raise IOError("An attempt was made to connect to the internet "
- "by a test that was not marked `remote_data`.")
- return new_function
-
-
-def turn_off_internet(verbose=False):
- """
- Disable internet access via python by preventing connections from being
- created using the socket module. Presumably this could be worked around by
- using some other means of accessing the internet, but all default python
- modules (urllib, requests, etc.) use socket [citation needed].
- """
-
- global INTERNET_OFF
- global _orig_opener
-
- if INTERNET_OFF:
- return
-
- INTERNET_OFF = True
-
- __tracebackhide__ = True
- if verbose:
- print("Internet access disabled")
-
- # Update urllib2 to force it not to use any proxies
- # Must use {} here (the default of None will kick off an automatic search
- # for proxies)
- _orig_opener = urllib.request.build_opener()
- no_proxy_handler = urllib.request.ProxyHandler({})
- opener = urllib.request.build_opener(no_proxy_handler)
- urllib.request.install_opener(opener)
-
- socket.create_connection = check_internet_off(socket_create_connection)
- socket.socket.bind = check_internet_off(socket_bind)
- socket.socket.connect = check_internet_off(socket_connect)
-
- return socket
-
-
-def turn_on_internet(verbose=False):
- """
- Restore internet access. Not used, but kept in case it is needed.
- """
-
- global INTERNET_OFF
- global _orig_opener
-
- if not INTERNET_OFF:
- return
-
- INTERNET_OFF = False
-
- if verbose:
- print("Internet access enabled")
-
- urllib.request.install_opener(_orig_opener)
-
- socket.create_connection = socket_create_connection
- socket.socket.bind = socket_bind
- socket.socket.connect = socket_connect
- return socket
-
-
-@contextlib.contextmanager
-def no_internet(verbose=False):
- """Context manager to temporarily disable internet access (if not already
- disabled). If it was already disabled before entering the context manager
- (i.e. `turn_off_internet` was called previously) then this is a no-op and
- leaves internet access disabled until a manual call to `turn_on_internet`.
- """
-
- already_disabled = INTERNET_OFF
-
- turn_off_internet(verbose=verbose)
- try:
- yield
- finally:
- if not already_disabled:
- turn_on_internet(verbose=verbose)
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/exceptions.py b/contrib/python/matplotlib/py2/matplotlib/testing/exceptions.py
deleted file mode 100644
index c39a392077..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/exceptions.py
+++ /dev/null
@@ -1,4 +0,0 @@
-class ImageComparisonFailure(AssertionError):
- """
- Raise this exception to mark a test as a comparison between two images.
- """
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/Duration.py b/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/Duration.py
deleted file mode 100644
index 99b2f98729..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/Duration.py
+++ /dev/null
@@ -1,211 +0,0 @@
-#===========================================================================
-#
-# Duration
-#
-#===========================================================================
-
-
-"""Duration module."""
-
-#===========================================================================
-# Place all imports after here.
-#
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-#
-# Place all imports before here.
-#===========================================================================
-
-#===========================================================================
-class Duration(object):
- """Class Duration in development.
- """
- allowed = [ "ET", "UTC" ]
-
- #-----------------------------------------------------------------------
- def __init__( self, frame, seconds ):
- """Create a new Duration object.
-
- = ERROR CONDITIONS
- - If the input frame is not in the allowed list, an error is thrown.
-
- = INPUT VARIABLES
- - frame The frame of the duration. Must be 'ET' or 'UTC'
- - seconds The number of seconds in the Duration.
- """
- if frame not in self.allowed:
- msg = "Input frame '%s' is not one of the supported frames of %s" \
- % ( frame, str( self.allowed ) )
- raise ValueError( msg )
-
- self._frame = frame
- self._seconds = seconds
-
- #-----------------------------------------------------------------------
- def frame( self ):
- """Return the frame the duration is in."""
- return self._frame
-
- #-----------------------------------------------------------------------
- def __abs__( self ):
- """Return the absolute value of the duration."""
- return Duration( self._frame, abs( self._seconds ) )
-
- #-----------------------------------------------------------------------
- def __neg__( self ):
- """Return the negative value of this Duration."""
- return Duration( self._frame, -self._seconds )
-
- #-----------------------------------------------------------------------
- def seconds( self ):
- """Return the number of seconds in the Duration."""
- return self._seconds
-
- #-----------------------------------------------------------------------
- def __nonzero__( self ):
- """Compare two Durations.
-
- = INPUT VARIABLES
- - rhs The Duration to compare against.
-
- = RETURN VALUE
- - Returns -1 if self < rhs, 0 if self == rhs, +1 if self > rhs.
- """
- return self._seconds != 0
-
- if six.PY3:
- __bool__ = __nonzero__
-
- #-----------------------------------------------------------------------
- def __cmp__( self, rhs ):
- """Compare two Durations.
-
- = ERROR CONDITIONS
- - If the input rhs is not in the same frame, an error is thrown.
-
- = INPUT VARIABLES
- - rhs The Duration to compare against.
-
- = RETURN VALUE
- - Returns -1 if self < rhs, 0 if self == rhs, +1 if self > rhs.
- """
- self.checkSameFrame( rhs, "compare" )
- return cmp( self._seconds, rhs._seconds )
-
- #-----------------------------------------------------------------------
- def __add__( self, rhs ):
- """Add two Durations.
-
- = ERROR CONDITIONS
- - If the input rhs is not in the same frame, an error is thrown.
-
- = INPUT VARIABLES
- - rhs The Duration to add.
-
- = RETURN VALUE
- - Returns the sum of ourselves and the input Duration.
- """
- # Delay-load due to circular dependencies.
- import matplotlib.testing.jpl_units as U
-
- if isinstance( rhs, U.Epoch ):
- return rhs + self
-
- self.checkSameFrame( rhs, "add" )
- return Duration( self._frame, self._seconds + rhs._seconds )
-
- #-----------------------------------------------------------------------
- def __sub__( self, rhs ):
- """Subtract two Durations.
-
- = ERROR CONDITIONS
- - If the input rhs is not in the same frame, an error is thrown.
-
- = INPUT VARIABLES
- - rhs The Duration to subtract.
-
- = RETURN VALUE
- - Returns the difference of ourselves and the input Duration.
- """
- self.checkSameFrame( rhs, "sub" )
- return Duration( self._frame, self._seconds - rhs._seconds )
-
- #-----------------------------------------------------------------------
- def __mul__( self, rhs ):
- """Scale a UnitDbl by a value.
-
- = INPUT VARIABLES
- - rhs The scalar to multiply by.
-
- = RETURN VALUE
- - Returns the scaled Duration.
- """
- return Duration( self._frame, self._seconds * float( rhs ) )
-
- #-----------------------------------------------------------------------
- def __rmul__( self, lhs ):
- """Scale a Duration by a value.
-
- = INPUT VARIABLES
- - lhs The scalar to multiply by.
-
- = RETURN VALUE
- - Returns the scaled Duration.
- """
- return Duration( self._frame, self._seconds * float( lhs ) )
-
- #-----------------------------------------------------------------------
- def __div__( self, rhs ):
- """Divide a Duration by a value.
-
- = INPUT VARIABLES
- - rhs The scalar to divide by.
-
- = RETURN VALUE
- - Returns the scaled Duration.
- """
- return Duration( self._frame, self._seconds / rhs )
-
- #-----------------------------------------------------------------------
- def __rdiv__( self, rhs ):
- """Divide a Duration by a value.
-
- = INPUT VARIABLES
- - rhs The scalar to divide by.
-
- = RETURN VALUE
- - Returns the scaled Duration.
- """
- return Duration( self._frame, rhs / self._seconds )
-
- #-----------------------------------------------------------------------
- def __str__( self ):
- """Print the Duration."""
- return "%g %s" % ( self._seconds, self._frame )
-
- #-----------------------------------------------------------------------
- def __repr__( self ):
- """Print the Duration."""
- return "Duration( '%s', %g )" % ( self._frame, self._seconds )
-
- #-----------------------------------------------------------------------
- def checkSameFrame( self, rhs, func ):
- """Check to see if frames are the same.
-
- = ERROR CONDITIONS
- - If the frame of the rhs Duration is not the same as our frame,
- an error is thrown.
-
- = INPUT VARIABLES
- - rhs The Duration to check for the same frame
- - func The name of the function doing the check.
- """
- if self._frame != rhs._frame:
- msg = "Cannot %s Duration's with different frames.\n" \
- "LHS: %s\n" \
- "RHS: %s" % ( func, self._frame, rhs._frame )
- raise ValueError( msg )
-
-#===========================================================================
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/Epoch.py b/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/Epoch.py
deleted file mode 100644
index 91b4c127eb..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/Epoch.py
+++ /dev/null
@@ -1,238 +0,0 @@
-#===========================================================================
-#
-# Epoch
-#
-#===========================================================================
-
-
-"""Epoch module."""
-
-#===========================================================================
-# Place all imports after here.
-#
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import math
-import datetime as DT
-from matplotlib.dates import date2num
-#
-# Place all imports before here.
-#===========================================================================
-
-#===========================================================================
-class Epoch(object):
- # Frame conversion offsets in seconds
- # t(TO) = t(FROM) + allowed[ FROM ][ TO ]
- allowed = {
- "ET" : {
- "UTC" : +64.1839,
- },
- "UTC" : {
- "ET" : -64.1839,
- },
- }
-
- #-----------------------------------------------------------------------
- def __init__( self, frame, sec=None, jd=None, daynum=None, dt=None ):
- """Create a new Epoch object.
-
- Build an epoch 1 of 2 ways:
-
- Using seconds past a Julian date:
- # Epoch( 'ET', sec=1e8, jd=2451545 )
-
- or using a matplotlib day number
- # Epoch( 'ET', daynum=730119.5 )
-
-
- = ERROR CONDITIONS
- - If the input units are not in the allowed list, an error is thrown.
-
- = INPUT VARIABLES
- - frame The frame of the epoch. Must be 'ET' or 'UTC'
- - sec The number of seconds past the input JD.
- - jd The Julian date of the epoch.
- - daynum The matplotlib day number of the epoch.
- - dt A python datetime instance.
- """
- if ( ( sec is None and jd is not None ) or
- ( sec is not None and jd is None ) or
- ( daynum is not None and ( sec is not None or jd is not None ) ) or
- ( daynum is None and dt is None and ( sec is None or jd is None ) ) or
- ( daynum is not None and dt is not None ) or
- ( dt is not None and ( sec is not None or jd is not None ) ) or
- ( (dt is not None) and not isinstance(dt, DT.datetime) ) ):
- msg = "Invalid inputs. Must enter sec and jd together, " \
- "daynum by itself, or dt (must be a python datetime).\n" \
- "Sec = %s\nJD = %s\ndnum= %s\ndt = %s" \
- % ( str( sec ), str( jd ), str( daynum ), str( dt ) )
- raise ValueError( msg )
-
- if frame not in self.allowed:
- msg = "Input frame '%s' is not one of the supported frames of %s" \
- % ( frame, str( list(six.iterkeys(self.allowed) ) ) )
- raise ValueError(msg)
-
- self._frame = frame
-
- if dt is not None:
- daynum = date2num( dt )
-
- if daynum is not None:
- # 1-JAN-0001 in JD = 1721425.5
- jd = float( daynum ) + 1721425.5
- self._jd = math.floor( jd )
- self._seconds = ( jd - self._jd ) * 86400.0
-
- else:
- self._seconds = float( sec )
- self._jd = float( jd )
-
- # Resolve seconds down to [ 0, 86400 )
- deltaDays = int( math.floor( self._seconds / 86400.0 ) )
- self._jd += deltaDays
- self._seconds -= deltaDays * 86400.0
-
- #-----------------------------------------------------------------------
- def convert( self, frame ):
- if self._frame == frame:
- return self
-
- offset = self.allowed[ self._frame ][ frame ]
-
- return Epoch( frame, self._seconds + offset, self._jd )
-
- #-----------------------------------------------------------------------
- def frame( self ):
- return self._frame
-
- #-----------------------------------------------------------------------
- def julianDate( self, frame ):
- t = self
- if frame != self._frame:
- t = self.convert( frame )
-
- return t._jd + t._seconds / 86400.0
-
- #-----------------------------------------------------------------------
- def secondsPast( self, frame, jd ):
- t = self
- if frame != self._frame:
- t = self.convert( frame )
-
- delta = t._jd - jd
- return t._seconds + delta * 86400
-
- #-----------------------------------------------------------------------
- def __cmp__( self, rhs ):
- """Compare two Epoch's.
-
- = INPUT VARIABLES
- - rhs The Epoch to compare against.
-
- = RETURN VALUE
- - Returns -1 if self < rhs, 0 if self == rhs, +1 if self > rhs.
- """
- t = self
- if self._frame != rhs._frame:
- t = self.convert( rhs._frame )
-
- if t._jd != rhs._jd:
- return cmp( t._jd, rhs._jd )
-
- return cmp( t._seconds, rhs._seconds )
-
- #-----------------------------------------------------------------------
- def __add__( self, rhs ):
- """Add a duration to an Epoch.
-
- = INPUT VARIABLES
- - rhs The Epoch to subtract.
-
- = RETURN VALUE
- - Returns the difference of ourselves and the input Epoch.
- """
- t = self
- if self._frame != rhs.frame():
- t = self.convert( rhs._frame )
-
- sec = t._seconds + rhs.seconds()
-
- return Epoch( t._frame, sec, t._jd )
-
- #-----------------------------------------------------------------------
- def __sub__( self, rhs ):
- """Subtract two Epoch's or a Duration from an Epoch.
-
- Valid:
- Duration = Epoch - Epoch
- Epoch = Epoch - Duration
-
- = INPUT VARIABLES
- - rhs The Epoch to subtract.
-
- = RETURN VALUE
- - Returns either the duration between to Epoch's or the a new
- Epoch that is the result of subtracting a duration from an epoch.
- """
- # Delay-load due to circular dependencies.
- import matplotlib.testing.jpl_units as U
-
- # Handle Epoch - Duration
- if isinstance( rhs, U.Duration ):
- return self + -rhs
-
- t = self
- if self._frame != rhs._frame:
- t = self.convert( rhs._frame )
-
- days = t._jd - rhs._jd
- sec = t._seconds - rhs._seconds
-
- return U.Duration( rhs._frame, days*86400 + sec )
-
- #-----------------------------------------------------------------------
- def __str__( self ):
- """Print the Epoch."""
- return "%22.15e %s" % ( self.julianDate( self._frame ), self._frame )
-
- #-----------------------------------------------------------------------
- def __repr__( self ):
- """Print the Epoch."""
- return str( self )
-
- #-----------------------------------------------------------------------
- def range( start, stop, step ):
- """Generate a range of Epoch objects.
-
- Similar to the Python range() method. Returns the range [
- start, stop ) at the requested step. Each element will be a
- Epoch object.
-
- = INPUT VARIABLES
- - start The starting value of the range.
- - stop The stop value of the range.
- - step Step to use.
-
- = RETURN VALUE
- - Returns a list contianing the requested Epoch values.
- """
- elems = []
-
- i = 0
- while True:
- d = start + i * step
- if d >= stop:
- break
-
- elems.append( d )
- i += 1
-
- return elems
-
- range = staticmethod( range )
-
-#===========================================================================
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/EpochConverter.py b/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/EpochConverter.py
deleted file mode 100644
index eecf332113..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/EpochConverter.py
+++ /dev/null
@@ -1,165 +0,0 @@
-#===========================================================================
-#
-# EpochConverter
-#
-#===========================================================================
-
-
-"""EpochConverter module containing class EpochConverter."""
-
-#===========================================================================
-# Place all imports after here.
-#
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import matplotlib.units as units
-import matplotlib.dates as date_ticker
-from matplotlib.cbook import iterable
-#
-# Place all imports before here.
-#===========================================================================
-
-__all__ = [ 'EpochConverter' ]
-
-#===========================================================================
-class EpochConverter( units.ConversionInterface ):
- """: A matplotlib converter class. Provides matplotlib conversion
- functionality for Monte Epoch and Duration classes.
- """
-
- # julian date reference for "Jan 1, 0001" minus 1 day because
- # matplotlib really wants "Jan 0, 0001"
- jdRef = 1721425.5 - 1
-
- #------------------------------------------------------------------------
- @staticmethod
- def axisinfo( unit, axis ):
- """: Returns information on how to handle an axis that has Epoch data.
-
- = INPUT VARIABLES
- - unit The units to use for a axis with Epoch data.
-
- = RETURN VALUE
- - Returns a matplotlib AxisInfo data structure that contains
- minor/major formatters, major/minor locators, and default
- label information.
- """
-
- majloc = date_ticker.AutoDateLocator()
- majfmt = date_ticker.AutoDateFormatter( majloc )
-
- return units.AxisInfo( majloc = majloc,
- majfmt = majfmt,
- label = unit )
-
- #------------------------------------------------------------------------
- @staticmethod
- def float2epoch( value, unit ):
- """: Convert a matplotlib floating-point date into an Epoch of the
- specified units.
-
- = INPUT VARIABLES
- - value The matplotlib floating-point date.
- - unit The unit system to use for the Epoch.
-
- = RETURN VALUE
- - Returns the value converted to an Epoch in the specified time system.
- """
- # Delay-load due to circular dependencies.
- import matplotlib.testing.jpl_units as U
-
- secPastRef = value * 86400.0 * U.UnitDbl( 1.0, 'sec' )
- return U.Epoch( unit, secPastRef, EpochConverter.jdRef )
-
- #------------------------------------------------------------------------
- @staticmethod
- def epoch2float( value, unit ):
- """: Convert an Epoch value to a float suitible for plotting as a
- python datetime object.
-
- = INPUT VARIABLES
- - value An Epoch or list of Epochs that need to be converted.
- - unit The units to use for an axis with Epoch data.
-
- = RETURN VALUE
- - Returns the value parameter converted to floats.
- """
- return value.julianDate( unit ) - EpochConverter.jdRef
-
- #------------------------------------------------------------------------
- @staticmethod
- def duration2float( value ):
- """: Convert a Duration value to a float suitible for plotting as a
- python datetime object.
-
- = INPUT VARIABLES
- - value A Duration or list of Durations that need to be converted.
-
- = RETURN VALUE
- - Returns the value parameter converted to floats.
- """
- return value.seconds() / 86400.0
-
- #------------------------------------------------------------------------
- @staticmethod
- def convert( value, unit, axis ):
- """: Convert value using unit to a float. If value is a sequence, return
- the converted sequence.
-
- = INPUT VARIABLES
- - value The value or list of values that need to be converted.
- - unit The units to use for an axis with Epoch data.
-
- = RETURN VALUE
- - Returns the value parameter converted to floats.
- """
- # Delay-load due to circular dependencies.
- import matplotlib.testing.jpl_units as U
-
- isNotEpoch = True
- isDuration = False
-
- if ( iterable(value) and not isinstance(value, six.string_types) ):
- if ( len(value) == 0 ):
- return []
- else:
- return [ EpochConverter.convert( x, unit, axis ) for x in value ]
-
- if ( isinstance(value, U.Epoch) ):
- isNotEpoch = False
- elif ( isinstance(value, U.Duration) ):
- isDuration = True
-
- if ( isNotEpoch and not isDuration and
- units.ConversionInterface.is_numlike( value ) ):
- return value
-
- if ( unit == None ):
- unit = EpochConverter.default_units( value, axis )
-
- if ( isDuration ):
- return EpochConverter.duration2float( value )
- else:
- return EpochConverter.epoch2float( value, unit )
-
- #------------------------------------------------------------------------
- @staticmethod
- def default_units( value, axis ):
- """: Return the default unit for value, or None.
-
- = INPUT VARIABLES
- - value The value or list of values that need units.
-
- = RETURN VALUE
- - Returns the default units to use for value.
- """
- frame = None
- if ( iterable(value) and not isinstance(value, six.string_types) ):
- return EpochConverter.default_units( value[0], axis )
- else:
- frame = value.frame()
-
- return frame
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/StrConverter.py b/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/StrConverter.py
deleted file mode 100644
index b5b8814f7c..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/StrConverter.py
+++ /dev/null
@@ -1,164 +0,0 @@
-#===========================================================================
-#
-# StrConverter
-#
-#===========================================================================
-
-
-"""StrConverter module containing class StrConverter."""
-
-#===========================================================================
-# Place all imports after here.
-#
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-
-import matplotlib.units as units
-from matplotlib.cbook import iterable
-
-# Place all imports before here.
-#===========================================================================
-
-__all__ = [ 'StrConverter' ]
-
-#===========================================================================
-class StrConverter( units.ConversionInterface ):
- """: A matplotlib converter class. Provides matplotlib conversion
- functionality for string data values.
-
- Valid units for string are:
- - 'indexed' : Values are indexed as they are specified for plotting.
- - 'sorted' : Values are sorted alphanumerically.
- - 'inverted' : Values are inverted so that the first value is on top.
- - 'sorted-inverted' : A combination of 'sorted' and 'inverted'
- """
-
- #------------------------------------------------------------------------
- @staticmethod
- def axisinfo( unit, axis ):
- """: Returns information on how to handle an axis that has string data.
-
- = INPUT VARIABLES
- - axis The axis using this converter.
- - unit The units to use for a axis with string data.
-
- = RETURN VALUE
- - Returns a matplotlib AxisInfo data structure that contains
- minor/major formatters, major/minor locators, and default
- label information.
- """
-
- return None
-
- #------------------------------------------------------------------------
- @staticmethod
- def convert( value, unit, axis ):
- """: Convert value using unit to a float. If value is a sequence, return
- the converted sequence.
-
- = INPUT VARIABLES
- - axis The axis using this converter.
- - value The value or list of values that need to be converted.
- - unit The units to use for a axis with Epoch data.
-
- = RETURN VALUE
- - Returns the value parameter converted to floats.
- """
-
- if ( units.ConversionInterface.is_numlike( value ) ):
- return value
-
- if ( value == [] ):
- return []
-
- # we delay loading to make matplotlib happy
- ax = axis.axes
- if axis is ax.get_xaxis():
- isXAxis = True
- else:
- isXAxis = False
-
- axis.get_major_ticks()
- ticks = axis.get_ticklocs()
- labels = axis.get_ticklabels()
-
- labels = [ l.get_text() for l in labels if l.get_text() ]
-
- if ( not labels ):
- ticks = []
- labels = []
-
-
- if ( not iterable( value ) ):
- value = [ value ]
-
- newValues = []
- for v in value:
- if ( (v not in labels) and (v not in newValues) ):
- newValues.append( v )
-
- for v in newValues:
- if ( labels ):
- labels.append( v )
- else:
- labels = [ v ]
-
- #DISABLED: This is disabled because matplotlib bar plots do not
- #DISABLED: recalculate the unit conversion of the data values
- #DISABLED: this is due to design and is not really a bug.
- #DISABLED: If this gets changed, then we can activate the following
- #DISABLED: block of code. Note that this works for line plots.
- #DISABLED if ( unit ):
- #DISABLED if ( unit.find( "sorted" ) > -1 ):
- #DISABLED labels.sort()
- #DISABLED if ( unit.find( "inverted" ) > -1 ):
- #DISABLED labels = labels[ ::-1 ]
-
- # add padding (so they do not appear on the axes themselves)
- labels = [ '' ] + labels + [ '' ]
- ticks = list(xrange( len(labels) ))
- ticks[0] = 0.5
- ticks[-1] = ticks[-1] - 0.5
-
- axis.set_ticks( ticks )
- axis.set_ticklabels( labels )
- # we have to do the following lines to make ax.autoscale_view work
- loc = axis.get_major_locator()
- loc.set_bounds( ticks[0], ticks[-1] )
-
- if ( isXAxis ):
- ax.set_xlim( ticks[0], ticks[-1] )
- else:
- ax.set_ylim( ticks[0], ticks[-1] )
-
- result = []
- for v in value:
- # If v is not in labels then something went wrong with adding new
- # labels to the list of old labels.
- errmsg = "This is due to a logic error in the StrConverter class. "
- errmsg += "Please report this error and its message in bugzilla."
- assert ( v in labels ), errmsg
- result.append( ticks[ labels.index(v) ] )
-
- ax.viewLim.ignore(-1)
- return result
-
- #------------------------------------------------------------------------
- @staticmethod
- def default_units( value, axis ):
- """: Return the default unit for value, or None.
-
- = INPUT VARIABLES
- - axis The axis using this converter.
- - value The value or list of values that need units.
-
- = RETURN VALUE
- - Returns the default units to use for value.
- Return the default unit for value, or None.
- """
-
- # The default behavior for string indexing.
- return "indexed"
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/UnitDbl.py b/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/UnitDbl.py
deleted file mode 100644
index 20c89308df..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/UnitDbl.py
+++ /dev/null
@@ -1,297 +0,0 @@
-#===========================================================================
-#
-# UnitDbl
-#
-#===========================================================================
-
-
-"""UnitDbl module."""
-
-#===========================================================================
-# Place all imports after here.
-#
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-#
-# Place all imports before here.
-#===========================================================================
-
-
-#===========================================================================
-class UnitDbl(object):
- """Class UnitDbl in development.
- """
- #-----------------------------------------------------------------------
- # Unit conversion table. Small subset of the full one but enough
- # to test the required functions. First field is a scale factor to
- # convert the input units to the units of the second field. Only
- # units in this table are allowed.
- allowed = {
- "m" : ( 0.001, "km" ),
- "km" : ( 1, "km" ),
- "mile" : ( 1.609344, "km" ),
-
- "rad" : ( 1, "rad" ),
- "deg" : ( 1.745329251994330e-02, "rad" ),
-
- "sec" : ( 1, "sec" ),
- "min" : ( 60.0, "sec" ),
- "hour" : ( 3600, "sec" ),
- }
-
- _types = {
- "km" : "distance",
- "rad" : "angle",
- "sec" : "time",
- }
-
- #-----------------------------------------------------------------------
- def __init__( self, value, units ):
- """Create a new UnitDbl object.
-
- Units are internally converted to km, rad, and sec. The only
- valid inputs for units are [ m, km, mile, rad, deg, sec, min, hour ].
-
- The field UnitDbl.value will contain the converted value. Use
- the convert() method to get a specific type of units back.
-
- = ERROR CONDITIONS
- - If the input units are not in the allowed list, an error is thrown.
-
- = INPUT VARIABLES
- - value The numeric value of the UnitDbl.
- - units The string name of the units the value is in.
- """
- self.checkUnits( units )
-
- data = self.allowed[ units ]
- self._value = float( value * data[0] )
- self._units = data[1]
-
- #-----------------------------------------------------------------------
- def convert( self, units ):
- """Convert the UnitDbl to a specific set of units.
-
- = ERROR CONDITIONS
- - If the input units are not in the allowed list, an error is thrown.
-
- = INPUT VARIABLES
- - units The string name of the units to convert to.
-
- = RETURN VALUE
- - Returns the value of the UnitDbl in the requested units as a floating
- point number.
- """
- if self._units == units:
- return self._value
-
- self.checkUnits( units )
-
- data = self.allowed[ units ]
- if self._units != data[1]:
- msg = "Error trying to convert to different units.\n" \
- " Invalid conversion requested.\n" \
- " UnitDbl: %s\n" \
- " Units: %s\n" % ( str( self ), units )
- raise ValueError( msg )
-
- return self._value / data[0]
-
- #-----------------------------------------------------------------------
- def __abs__( self ):
- """Return the absolute value of this UnitDbl."""
- return UnitDbl( abs( self._value ), self._units )
-
- #-----------------------------------------------------------------------
- def __neg__( self ):
- """Return the negative value of this UnitDbl."""
- return UnitDbl( -self._value, self._units )
-
- #-----------------------------------------------------------------------
- def __nonzero__( self ):
- """Test a UnitDbl for a non-zero value.
-
- = RETURN VALUE
- - Returns true if the value is non-zero.
- """
- if six.PY3:
- return self._value.__bool__()
- else:
- return self._value.__nonzero__()
-
- if six.PY3:
- __bool__ = __nonzero__
-
- #-----------------------------------------------------------------------
- def __cmp__( self, rhs ):
- """Compare two UnitDbl's.
-
- = ERROR CONDITIONS
- - If the input rhs units are not the same as our units,
- an error is thrown.
-
- = INPUT VARIABLES
- - rhs The UnitDbl to compare against.
-
- = RETURN VALUE
- - Returns -1 if self < rhs, 0 if self == rhs, +1 if self > rhs.
- """
- self.checkSameUnits( rhs, "compare" )
- return cmp( self._value, rhs._value )
-
- #-----------------------------------------------------------------------
- def __add__( self, rhs ):
- """Add two UnitDbl's.
-
- = ERROR CONDITIONS
- - If the input rhs units are not the same as our units,
- an error is thrown.
-
- = INPUT VARIABLES
- - rhs The UnitDbl to add.
-
- = RETURN VALUE
- - Returns the sum of ourselves and the input UnitDbl.
- """
- self.checkSameUnits( rhs, "add" )
- return UnitDbl( self._value + rhs._value, self._units )
-
- #-----------------------------------------------------------------------
- def __sub__( self, rhs ):
- """Subtract two UnitDbl's.
-
- = ERROR CONDITIONS
- - If the input rhs units are not the same as our units,
- an error is thrown.
-
- = INPUT VARIABLES
- - rhs The UnitDbl to subtract.
-
- = RETURN VALUE
- - Returns the difference of ourselves and the input UnitDbl.
- """
- self.checkSameUnits( rhs, "subtract" )
- return UnitDbl( self._value - rhs._value, self._units )
-
- #-----------------------------------------------------------------------
- def __mul__( self, rhs ):
- """Scale a UnitDbl by a value.
-
- = INPUT VARIABLES
- - rhs The scalar to multiply by.
-
- = RETURN VALUE
- - Returns the scaled UnitDbl.
- """
- return UnitDbl( self._value * rhs, self._units )
-
- #-----------------------------------------------------------------------
- def __rmul__( self, lhs ):
- """Scale a UnitDbl by a value.
-
- = INPUT VARIABLES
- - lhs The scalar to multiply by.
-
- = RETURN VALUE
- - Returns the scaled UnitDbl.
- """
- return UnitDbl( self._value * lhs, self._units )
-
- #-----------------------------------------------------------------------
- def __div__( self, rhs ):
- """Divide a UnitDbl by a value.
-
- = INPUT VARIABLES
- - rhs The scalar to divide by.
-
- = RETURN VALUE
- - Returns the scaled UnitDbl.
- """
- return UnitDbl( self._value / rhs, self._units )
-
- #-----------------------------------------------------------------------
- def __str__( self ):
- """Print the UnitDbl."""
- return "%g *%s" % ( self._value, self._units )
-
- #-----------------------------------------------------------------------
- def __repr__( self ):
- """Print the UnitDbl."""
- return "UnitDbl( %g, '%s' )" % ( self._value, self._units )
-
- #-----------------------------------------------------------------------
- def type( self ):
- """Return the type of UnitDbl data."""
- return self._types[ self._units ]
-
- #-----------------------------------------------------------------------
- def range( start, stop, step=None ):
- """Generate a range of UnitDbl objects.
-
- Similar to the Python range() method. Returns the range [
- start, stop ) at the requested step. Each element will be a
- UnitDbl object.
-
- = INPUT VARIABLES
- - start The starting value of the range.
- - stop The stop value of the range.
- - step Optional step to use. If set to None, then a UnitDbl of
- value 1 w/ the units of the start is used.
-
- = RETURN VALUE
- - Returns a list contianing the requested UnitDbl values.
- """
- if step is None:
- step = UnitDbl( 1, start._units )
-
- elems = []
-
- i = 0
- while True:
- d = start + i * step
- if d >= stop:
- break
-
- elems.append( d )
- i += 1
-
- return elems
-
- range = staticmethod( range )
-
- #-----------------------------------------------------------------------
- def checkUnits( self, units ):
- """Check to see if some units are valid.
-
- = ERROR CONDITIONS
- - If the input units are not in the allowed list, an error is thrown.
-
- = INPUT VARIABLES
- - units The string name of the units to check.
- """
- if units not in self.allowed:
- msg = "Input units '%s' are not one of the supported types of %s" \
- % ( units, str( list(six.iterkeys(self.allowed)) ) )
- raise ValueError( msg )
-
- #-----------------------------------------------------------------------
- def checkSameUnits( self, rhs, func ):
- """Check to see if units are the same.
-
- = ERROR CONDITIONS
- - If the units of the rhs UnitDbl are not the same as our units,
- an error is thrown.
-
- = INPUT VARIABLES
- - rhs The UnitDbl to check for the same units
- - func The name of the function doing the check.
- """
- if self._units != rhs._units:
- msg = "Cannot %s units of different types.\n" \
- "LHS: %s\n" \
- "RHS: %s" % ( func, self._units, rhs._units )
- raise ValueError( msg )
-
-#===========================================================================
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/UnitDblConverter.py b/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/UnitDblConverter.py
deleted file mode 100644
index 41fe8e19a9..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/UnitDblConverter.py
+++ /dev/null
@@ -1,159 +0,0 @@
-#===========================================================================
-#
-# UnitDblConverter
-#
-#===========================================================================
-
-
-"""UnitDblConverter module containing class UnitDblConverter."""
-
-#===========================================================================
-# Place all imports after here.
-#
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import numpy as np
-import matplotlib.units as units
-import matplotlib.projections.polar as polar
-from matplotlib.cbook import iterable
-#
-# Place all imports before here.
-#===========================================================================
-
-__all__ = [ 'UnitDblConverter' ]
-
-#===========================================================================
-
-# A special function for use with the matplotlib FuncFormatter class
-# for formatting axes with radian units.
-# This was copied from matplotlib example code.
-def rad_fn(x, pos = None ):
- """Radian function formatter."""
- n = int((x / np.pi) * 2.0 + 0.25)
- if n == 0:
- return str(x)
- elif n == 1:
- return r'$\pi/2$'
- elif n == 2:
- return r'$\pi$'
- elif n % 2 == 0:
- return r'$%s\pi$' % (n/2,)
- else:
- return r'$%s\pi/2$' % (n,)
-
-#===========================================================================
-class UnitDblConverter( units.ConversionInterface ):
- """: A matplotlib converter class. Provides matplotlib conversion
- functionality for the Monte UnitDbl class.
- """
-
- # default for plotting
- defaults = {
- "distance" : 'km',
- "angle" : 'deg',
- "time" : 'sec',
- }
-
- #------------------------------------------------------------------------
- @staticmethod
- def axisinfo( unit, axis ):
- """: Returns information on how to handle an axis that has Epoch data.
-
- = INPUT VARIABLES
- - unit The units to use for a axis with Epoch data.
-
- = RETURN VALUE
- - Returns a matplotlib AxisInfo data structure that contains
- minor/major formatters, major/minor locators, and default
- label information.
- """
- # Delay-load due to circular dependencies.
- import matplotlib.testing.jpl_units as U
-
- # Check to see if the value used for units is a string unit value
- # or an actual instance of a UnitDbl so that we can use the unit
- # value for the default axis label value.
- if ( unit ):
- if ( isinstance( unit, six.string_types ) ):
- label = unit
- else:
- label = unit.label()
- else:
- label = None
-
- if ( label == "deg" ) and isinstance( axis.axes, polar.PolarAxes ):
- # If we want degrees for a polar plot, use the PolarPlotFormatter
- majfmt = polar.PolarAxes.ThetaFormatter()
- else:
- majfmt = U.UnitDblFormatter( useOffset = False )
-
- return units.AxisInfo( majfmt = majfmt, label = label )
-
- #------------------------------------------------------------------------
- @staticmethod
- def convert( value, unit, axis ):
- """: Convert value using unit to a float. If value is a sequence, return
- the converted sequence.
-
- = INPUT VARIABLES
- - value The value or list of values that need to be converted.
- - unit The units to use for a axis with Epoch data.
-
- = RETURN VALUE
- - Returns the value parameter converted to floats.
- """
- # Delay-load due to circular dependencies.
- import matplotlib.testing.jpl_units as U
-
- isNotUnitDbl = True
-
- if ( iterable(value) and not isinstance(value, six.string_types) ):
- if ( len(value) == 0 ):
- return []
- else:
- return [ UnitDblConverter.convert( x, unit, axis ) for x in value ]
-
- # We need to check to see if the incoming value is actually a UnitDbl and
- # set a flag. If we get an empty list, then just return an empty list.
- if ( isinstance(value, U.UnitDbl) ):
- isNotUnitDbl = False
-
- # If the incoming value behaves like a number, but is not a UnitDbl,
- # then just return it because we don't know how to convert it
- # (or it is already converted)
- if ( isNotUnitDbl and units.ConversionInterface.is_numlike( value ) ):
- return value
-
- # If no units were specified, then get the default units to use.
- if ( unit == None ):
- unit = UnitDblConverter.default_units( value, axis )
-
- # Convert the incoming UnitDbl value/values to float/floats
- if isinstance( axis.axes, polar.PolarAxes ) and value.type() == "angle":
- # Guarantee that units are radians for polar plots.
- return value.convert( "rad" )
-
- return value.convert( unit )
-
- #------------------------------------------------------------------------
- @staticmethod
- def default_units( value, axis ):
- """: Return the default unit for value, or None.
-
- = INPUT VARIABLES
- - value The value or list of values that need units.
-
- = RETURN VALUE
- - Returns the default units to use for value.
- Return the default unit for value, or None.
- """
-
- # Determine the default units based on the user preferences set for
- # default units when printing a UnitDbl.
- if ( iterable(value) and not isinstance(value, six.string_types) ):
- return UnitDblConverter.default_units( value[0], axis )
- else:
- return UnitDblConverter.defaults[ value.type() ]
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/UnitDblFormatter.py b/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/UnitDblFormatter.py
deleted file mode 100644
index 269044748c..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/UnitDblFormatter.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#===========================================================================
-#
-# UnitDblFormatter
-#
-#===========================================================================
-
-
-"""UnitDblFormatter module containing class UnitDblFormatter."""
-
-#===========================================================================
-# Place all imports after here.
-#
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import matplotlib.ticker as ticker
-#
-# Place all imports before here.
-#===========================================================================
-
-__all__ = [ 'UnitDblFormatter' ]
-
-#===========================================================================
-class UnitDblFormatter( ticker.ScalarFormatter ):
- """The formatter for UnitDbl data types. This allows for formatting
- with the unit string.
- """
- def __init__( self, *args, **kwargs ):
- 'The arguments are identical to matplotlib.ticker.ScalarFormatter.'
- ticker.ScalarFormatter.__init__( self, *args, **kwargs )
-
- def __call__( self, x, pos = None ):
- 'Return the format for tick val x at position pos'
- if len(self.locs) == 0:
- return ''
- else:
- return '{:.12}'.format(x)
-
- def format_data_short( self, value ):
- "Return the value formatted in 'short' format."
- return '{:.12}'.format(value)
-
- def format_data( self, value ):
- "Return the value formatted into a string."
- return '{:.12}'.format(value)
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/__init__.py b/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/__init__.py
deleted file mode 100644
index 074af4e835..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/jpl_units/__init__.py
+++ /dev/null
@@ -1,88 +0,0 @@
-#=======================================================================
-
-"""
-This is a sample set of units for use with testing unit conversion
-of matplotlib routines. These are used because they use very strict
-enforcement of unitized data which will test the entire spectrum of how
-unitized data might be used (it is not always meaningful to convert to
-a float without specific units given).
-
-UnitDbl is essentially a unitized floating point number. It has a
-minimal set of supported units (enough for testing purposes). All
-of the mathematical operation are provided to fully test any behaviour
-that might occur with unitized data. Remember that unitized data has
-rules as to how it can be applied to one another (a value of distance
-cannot be added to a value of time). Thus we need to guard against any
-accidental "default" conversion that will strip away the meaning of the
-data and render it neutered.
-
-Epoch is different than a UnitDbl of time. Time is something that can be
-measured where an Epoch is a specific moment in time. Epochs are typically
-referenced as an offset from some predetermined epoch.
-
-A difference of two epochs is a Duration. The distinction between a Duration
-and a UnitDbl of time is made because an Epoch can have different frames (or
-units). In the case of our test Epoch class the two allowed frames are 'UTC'
-and 'ET' (Note that these are rough estimates provided for testing purposes
-and should not be used in production code where accuracy of time frames is
-desired). As such a Duration also has a frame of reference and therefore needs
-to be called out as different that a simple measurement of time since a delta-t
-in one frame may not be the same in another.
-"""
-
-#=======================================================================
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from .Duration import Duration
-from .Epoch import Epoch
-from .UnitDbl import UnitDbl
-
-from .StrConverter import StrConverter
-from .EpochConverter import EpochConverter
-from .UnitDblConverter import UnitDblConverter
-
-from .UnitDblFormatter import UnitDblFormatter
-
-#=======================================================================
-
-__version__ = "1.0"
-
-__all__ = [
- 'register',
- 'Duration',
- 'Epoch',
- 'UnitDbl',
- 'UnitDblFormatter',
- ]
-
-#=======================================================================
-def register():
- """Register the unit conversion classes with matplotlib."""
- import matplotlib.units as mplU
-
- mplU.registry[ str ] = StrConverter()
- mplU.registry[ Epoch ] = EpochConverter()
- mplU.registry[ Duration ] = EpochConverter()
- mplU.registry[ UnitDbl ] = UnitDblConverter()
-
-#=======================================================================
-# Some default unit instances
-
-# Distances
-m = UnitDbl( 1.0, "m" )
-km = UnitDbl( 1.0, "km" )
-mile = UnitDbl( 1.0, "mile" )
-
-# Angles
-deg = UnitDbl( 1.0, "deg" )
-rad = UnitDbl( 1.0, "rad" )
-
-# Time
-sec = UnitDbl( 1.0, "sec" )
-min = UnitDbl( 1.0, "min" )
-hr = UnitDbl( 1.0, "hour" )
-day = UnitDbl( 24.0, "hour" )
-sec = UnitDbl( 1.0, "sec" )
diff --git a/contrib/python/matplotlib/py2/matplotlib/testing/noseclasses.py b/contrib/python/matplotlib/py2/matplotlib/testing/noseclasses.py
deleted file mode 100644
index 2983b93d7f..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/testing/noseclasses.py
+++ /dev/null
@@ -1,26 +0,0 @@
-"""
-The module testing.noseclasses is deprecated as of 2.1
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-try:
- from ._nose.plugins.knownfailure import KnownFailure as _KnownFailure
- has_nose = True
-except ImportError:
- has_nose = False
- _KnownFailure = object
-
-from .. import cbook
-
-cbook.warn_deprecated(
- since="2.1",
- message="The noseclass module has been deprecated in 2.1 and will "
- "be removed in matplotlib 2.3.")
-
-
-@cbook.deprecated("2.1")
-class KnownFailure(_KnownFailure):
- def __init__(self):
- if not has_nose:
- raise ImportError("Need nose for this plugin.")
diff --git a/contrib/python/matplotlib/py2/matplotlib/texmanager.py b/contrib/python/matplotlib/py2/matplotlib/texmanager.py
deleted file mode 100644
index c9001151cd..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/texmanager.py
+++ /dev/null
@@ -1,505 +0,0 @@
-r"""
-This module supports embedded TeX expressions in matplotlib via dvipng
-and dvips for the raster and postscript backends. The tex and
-dvipng/dvips information is cached in ~/.matplotlib/tex.cache for reuse between
-sessions
-
-Requirements:
-
-* latex
-* \*Agg backends: dvipng>=1.6
-* PS backend: psfrag, dvips, and Ghostscript>=8.60
-
-Backends:
-
-* \*Agg
-* PS
-* PDF
-
-For raster output, you can get RGBA numpy arrays from TeX expressions
-as follows::
-
- texmanager = TexManager()
- s = ('\TeX\ is Number '
- '$\displaystyle\sum_{n=1}^\infty\frac{-e^{i\pi}}{2^n}$!')
- Z = texmanager.get_rgba(s, fontsize=12, dpi=80, rgb=(1,0,0))
-
-To enable tex rendering of all text in your matplotlib figure, set
-text.usetex in your matplotlibrc file or include these two lines in
-your script::
-
- from matplotlib import rc
- rc('text', usetex=True)
-
-"""
-
-from __future__ import absolute_import, division, print_function
-
-import six
-
-import copy
-import glob
-import os
-import shutil
-import sys
-import warnings
-import logging
-
-from hashlib import md5
-
-import distutils.version
-import numpy as np
-import matplotlib as mpl
-from matplotlib import rcParams
-from matplotlib._png import read_png
-from matplotlib.cbook import mkdirs, Locked
-from matplotlib.compat.subprocess import subprocess, Popen, PIPE, STDOUT
-import matplotlib.dviread as dviread
-import re
-
-_log = logging.getLogger(__name__)
-
-
-@mpl.cbook.deprecated("2.1")
-def dvipng_hack_alpha():
- try:
- p = Popen([str('dvipng'), '-version'], stdin=PIPE, stdout=PIPE,
- stderr=STDOUT, close_fds=(sys.platform != 'win32'))
- stdout, stderr = p.communicate()
- except OSError:
- _log.info('No dvipng was found')
- return False
- lines = stdout.decode(sys.getdefaultencoding()).split('\n')
- for line in lines:
- if line.startswith('dvipng '):
- version = line.split()[-1]
- _log.info('Found dvipng version %s', version)
- version = distutils.version.LooseVersion(version)
- return version < distutils.version.LooseVersion('1.6')
- _log.info('Unexpected response from dvipng -version')
- return False
-
-
-class TexManager(object):
- """
- Convert strings to dvi files using TeX, caching the results to a directory.
- """
-
- cachedir = mpl.get_cachedir()
- if cachedir is not None:
- texcache = os.path.join(cachedir, 'tex.cache')
- mkdirs(texcache)
- else:
- # Should only happen in a restricted environment (such as Google App
- # Engine). Deal with this gracefully by not creating a cache directory.
- texcache = None
-
- # Caches.
- rgba_arrayd = {}
- grey_arrayd = {}
- postscriptd = property(mpl.cbook.deprecated("2.2")(lambda self: {}))
- pscnt = property(mpl.cbook.deprecated("2.2")(lambda self: 0))
-
- serif = ('cmr', '')
- sans_serif = ('cmss', '')
- monospace = ('cmtt', '')
- cursive = ('pzc', r'\usepackage{chancery}')
- font_family = 'serif'
- font_families = ('serif', 'sans-serif', 'cursive', 'monospace')
-
- font_info = {
- 'new century schoolbook': ('pnc', r'\renewcommand{\rmdefault}{pnc}'),
- 'bookman': ('pbk', r'\renewcommand{\rmdefault}{pbk}'),
- 'times': ('ptm', r'\usepackage{mathptmx}'),
- 'palatino': ('ppl', r'\usepackage{mathpazo}'),
- 'zapf chancery': ('pzc', r'\usepackage{chancery}'),
- 'cursive': ('pzc', r'\usepackage{chancery}'),
- 'charter': ('pch', r'\usepackage{charter}'),
- 'serif': ('cmr', ''),
- 'sans-serif': ('cmss', ''),
- 'helvetica': ('phv', r'\usepackage{helvet}'),
- 'avant garde': ('pag', r'\usepackage{avant}'),
- 'courier': ('pcr', r'\usepackage{courier}'),
- 'monospace': ('cmtt', ''),
- 'computer modern roman': ('cmr', ''),
- 'computer modern sans serif': ('cmss', ''),
- 'computer modern typewriter': ('cmtt', '')}
-
- _rc_cache = None
- _rc_cache_keys = (('text.latex.preamble', ) +
- tuple(['font.' + n for n in ('family', ) +
- font_families]))
-
- def __init__(self):
-
- if self.texcache is None:
- raise RuntimeError('Cannot create TexManager, as there is no '
- 'cache directory available')
-
- mkdirs(self.texcache)
- ff = rcParams['font.family']
- if len(ff) == 1 and ff[0].lower() in self.font_families:
- self.font_family = ff[0].lower()
- elif (isinstance(ff, six.string_types)
- and ff.lower() in self.font_families):
- self.font_family = ff.lower()
- else:
- _log.info('font.family must be one of (%s) when text.usetex is '
- 'True. serif will be used by default.',
- ', '.join(self.font_families))
- self.font_family = 'serif'
-
- fontconfig = [self.font_family]
- for font_family in self.font_families:
- font_family_attr = font_family.replace('-', '_')
- for font in rcParams['font.' + font_family]:
- if font.lower() in self.font_info:
- setattr(self, font_family_attr,
- self.font_info[font.lower()])
- _log.debug('family: %s, font: %s, info: %s',
- font_family, font, self.font_info[font.lower()])
- break
- else:
- _log.debug('%s font is not compatible with usetex.',
- font_family)
- else:
- _log.info('No LaTeX-compatible font found for the %s font '
- 'family in rcParams. Using default.', font_family)
- setattr(self, font_family_attr, self.font_info[font_family])
- fontconfig.append(getattr(self, font_family_attr)[0])
- # Add a hash of the latex preamble to self._fontconfig so that the
- # correct png is selected for strings rendered with same font and dpi
- # even if the latex preamble changes within the session
- preamble_bytes = self.get_custom_preamble().encode('utf-8')
- fontconfig.append(md5(preamble_bytes).hexdigest())
- self._fontconfig = ''.join(fontconfig)
-
- # The following packages and commands need to be included in the latex
- # file's preamble:
- cmd = [self.serif[1], self.sans_serif[1], self.monospace[1]]
- if self.font_family == 'cursive':
- cmd.append(self.cursive[1])
- self._font_preamble = '\n'.join(
- [r'\usepackage{type1cm}'] + cmd + [r'\usepackage{textcomp}'])
-
- def get_basefile(self, tex, fontsize, dpi=None):
- """
- Return a filename based on a hash of the string, fontsize, and dpi.
- """
- s = ''.join([tex, self.get_font_config(), '%f' % fontsize,
- self.get_custom_preamble(), str(dpi or '')])
- return os.path.join(self.texcache, md5(s.encode('utf-8')).hexdigest())
-
- def get_font_config(self):
- """Reinitializes self if relevant rcParams on have changed."""
- if self._rc_cache is None:
- self._rc_cache = dict.fromkeys(self._rc_cache_keys)
- changed = [par for par in self._rc_cache_keys
- if rcParams[par] != self._rc_cache[par]]
- if changed:
- _log.debug('following keys changed: %s', changed)
- for k in changed:
- _log.debug('%-20s: %-10s -> %-10s',
- k, self._rc_cache[k], rcParams[k])
- # deepcopy may not be necessary, but feels more future-proof
- self._rc_cache[k] = copy.deepcopy(rcParams[k])
- _log.debug('RE-INIT\nold fontconfig: %s', self._fontconfig)
- self.__init__()
- _log.debug('fontconfig: %s', self._fontconfig)
- return self._fontconfig
-
- def get_font_preamble(self):
- """
- Return a string containing font configuration for the tex preamble.
- """
- return self._font_preamble
-
- def get_custom_preamble(self):
- """Return a string containing user additions to the tex preamble."""
- return '\n'.join(rcParams['text.latex.preamble'])
-
- def make_tex(self, tex, fontsize):
- """
- Generate a tex file to render the tex string at a specific font size.
-
- Return the file name.
- """
- basefile = self.get_basefile(tex, fontsize)
- texfile = '%s.tex' % basefile
- custom_preamble = self.get_custom_preamble()
- fontcmd = {'sans-serif': r'{\sffamily %s}',
- 'monospace': r'{\ttfamily %s}'}.get(self.font_family,
- r'{\rmfamily %s}')
- tex = fontcmd % tex
-
- if rcParams['text.latex.unicode']:
- unicode_preamble = r"""
-\usepackage{ucs}
-\usepackage[utf8x]{inputenc}"""
- else:
- unicode_preamble = ''
-
- s = r"""
-\documentclass{article}
-%s
-%s
-%s
-\usepackage[papersize={72in,72in},body={70in,70in},margin={1in,1in}]{geometry}
-\pagestyle{empty}
-\begin{document}
-\fontsize{%f}{%f}%s
-\end{document}
-""" % (self._font_preamble, unicode_preamble, custom_preamble,
- fontsize, fontsize * 1.25, tex)
- with open(texfile, 'wb') as fh:
- if rcParams['text.latex.unicode']:
- fh.write(s.encode('utf8'))
- else:
- try:
- fh.write(s.encode('ascii'))
- except UnicodeEncodeError as err:
- _log.info("You are using unicode and latex, but have not "
- "enabled the 'text.latex.unicode' rcParam.")
- raise
-
- return texfile
-
- _re_vbox = re.compile(
- r"MatplotlibBox:\(([\d.]+)pt\+([\d.]+)pt\)x([\d.]+)pt")
-
- def make_tex_preview(self, tex, fontsize):
- """
- Generate a tex file to render the tex string at a specific font size.
-
- It uses the preview.sty to determine the dimension (width, height,
- descent) of the output.
-
- Return the file name.
- """
- basefile = self.get_basefile(tex, fontsize)
- texfile = '%s.tex' % basefile
- custom_preamble = self.get_custom_preamble()
- fontcmd = {'sans-serif': r'{\sffamily %s}',
- 'monospace': r'{\ttfamily %s}'}.get(self.font_family,
- r'{\rmfamily %s}')
- tex = fontcmd % tex
-
- if rcParams['text.latex.unicode']:
- unicode_preamble = r"""
-\usepackage{ucs}
-\usepackage[utf8x]{inputenc}"""
- else:
- unicode_preamble = ''
-
- # newbox, setbox, immediate, etc. are used to find the box
- # extent of the rendered text.
-
- s = r"""
-\documentclass{article}
-%s
-%s
-%s
-\usepackage[active,showbox,tightpage]{preview}
-\usepackage[papersize={72in,72in},body={70in,70in},margin={1in,1in}]{geometry}
-
-%% we override the default showbox as it is treated as an error and makes
-%% the exit status not zero
-\def\showbox#1%%
-{\immediate\write16{MatplotlibBox:(\the\ht#1+\the\dp#1)x\the\wd#1}}
-
-\begin{document}
-\begin{preview}
-{\fontsize{%f}{%f}%s}
-\end{preview}
-\end{document}
-""" % (self._font_preamble, unicode_preamble, custom_preamble,
- fontsize, fontsize * 1.25, tex)
- with open(texfile, 'wb') as fh:
- if rcParams['text.latex.unicode']:
- fh.write(s.encode('utf8'))
- else:
- try:
- fh.write(s.encode('ascii'))
- except UnicodeEncodeError as err:
- _log.info("You are using unicode and latex, but have not "
- "enabled the 'text.latex.unicode' rcParam.")
- raise
-
- return texfile
-
- def _run_checked_subprocess(self, command, tex):
- _log.debug(command)
- try:
- report = subprocess.check_output(command,
- cwd=self.texcache,
- stderr=subprocess.STDOUT)
- except subprocess.CalledProcessError as exc:
- raise RuntimeError(
- '{prog} was not able to process the following string:\n'
- '{tex!r}\n\n'
- 'Here is the full report generated by {prog}:\n'
- '{exc}\n\n'.format(
- prog=command[0],
- tex=tex.encode('unicode_escape'),
- exc=exc.output.decode('utf-8')))
- _log.debug(report)
- return report
-
- def make_dvi(self, tex, fontsize):
- """
- Generate a dvi file containing latex's layout of tex string.
-
- Return the file name.
- """
-
- if rcParams['text.latex.preview']:
- return self.make_dvi_preview(tex, fontsize)
-
- basefile = self.get_basefile(tex, fontsize)
- dvifile = '%s.dvi' % basefile
- if not os.path.exists(dvifile):
- texfile = self.make_tex(tex, fontsize)
- with Locked(self.texcache):
- self._run_checked_subprocess(
- ["latex", "-interaction=nonstopmode", "--halt-on-error",
- texfile], tex)
- for fname in glob.glob(basefile + '*'):
- if not fname.endswith(('dvi', 'tex')):
- try:
- os.remove(fname)
- except OSError:
- pass
-
- return dvifile
-
- def make_dvi_preview(self, tex, fontsize):
- """
- Generate a dvi file containing latex's layout of tex string.
-
- It calls make_tex_preview() method and store the size information
- (width, height, descent) in a separate file.
-
- Return the file name.
- """
- basefile = self.get_basefile(tex, fontsize)
- dvifile = '%s.dvi' % basefile
- baselinefile = '%s.baseline' % basefile
-
- if not os.path.exists(dvifile) or not os.path.exists(baselinefile):
- texfile = self.make_tex_preview(tex, fontsize)
- report = self._run_checked_subprocess(
- ["latex", "-interaction=nonstopmode", "--halt-on-error",
- texfile], tex)
-
- # find the box extent information in the latex output
- # file and store them in ".baseline" file
- m = TexManager._re_vbox.search(report.decode("utf-8"))
- with open(basefile + '.baseline', "w") as fh:
- fh.write(" ".join(m.groups()))
-
- for fname in glob.glob(basefile + '*'):
- if not fname.endswith(('dvi', 'tex', 'baseline')):
- try:
- os.remove(fname)
- except OSError:
- pass
-
- return dvifile
-
- def make_png(self, tex, fontsize, dpi):
- """
- Generate a png file containing latex's rendering of tex string.
-
- Return the file name.
- """
- basefile = self.get_basefile(tex, fontsize, dpi)
- pngfile = '%s.png' % basefile
- # see get_rgba for a discussion of the background
- if not os.path.exists(pngfile):
- dvifile = self.make_dvi(tex, fontsize)
- self._run_checked_subprocess(
- ["dvipng", "-bg", "Transparent", "-D", str(dpi),
- "-T", "tight", "-o", pngfile, dvifile], tex)
- return pngfile
-
- @mpl.cbook.deprecated("2.2")
- def make_ps(self, tex, fontsize):
- """
- Generate a postscript file containing latex's rendering of tex string.
-
- Return the file name.
- """
- basefile = self.get_basefile(tex, fontsize)
- psfile = '%s.epsf' % basefile
- if not os.path.exists(psfile):
- dvifile = self.make_dvi(tex, fontsize)
- self._run_checked_subprocess(
- ["dvips", "-q", "-E", "-o", psfile, dvifile], tex)
- return psfile
-
- @mpl.cbook.deprecated("2.2")
- def get_ps_bbox(self, tex, fontsize):
- """
- Return a list of PS bboxes for latex's rendering of the tex string.
- """
- psfile = self.make_ps(tex, fontsize)
- with open(psfile) as ps:
- for line in ps:
- if line.startswith('%%BoundingBox:'):
- return [int(val) for val in line.split()[1:]]
- raise RuntimeError('Could not parse %s' % psfile)
-
- def get_grey(self, tex, fontsize=None, dpi=None):
- """Return the alpha channel."""
- key = tex, self.get_font_config(), fontsize, dpi
- alpha = self.grey_arrayd.get(key)
- if alpha is None:
- pngfile = self.make_png(tex, fontsize, dpi)
- X = read_png(os.path.join(self.texcache, pngfile))
- self.grey_arrayd[key] = alpha = X[:, :, -1]
- return alpha
-
- def get_rgba(self, tex, fontsize=None, dpi=None, rgb=(0, 0, 0)):
- """Return latex's rendering of the tex string as an rgba array."""
- if not fontsize:
- fontsize = rcParams['font.size']
- if not dpi:
- dpi = rcParams['savefig.dpi']
- r, g, b = rgb
- key = tex, self.get_font_config(), fontsize, dpi, tuple(rgb)
- Z = self.rgba_arrayd.get(key)
-
- if Z is None:
- alpha = self.get_grey(tex, fontsize, dpi)
- Z = np.dstack([r, g, b, alpha])
- self.rgba_arrayd[key] = Z
-
- return Z
-
- def get_text_width_height_descent(self, tex, fontsize, renderer=None):
- """Return width, height and descent of the text."""
- if tex.strip() == '':
- return 0, 0, 0
-
- dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1
-
- if rcParams['text.latex.preview']:
- # use preview.sty
- basefile = self.get_basefile(tex, fontsize)
- baselinefile = '%s.baseline' % basefile
-
- if not os.path.exists(baselinefile):
- dvifile = self.make_dvi_preview(tex, fontsize)
-
- with open(baselinefile) as fh:
- l = fh.read().split()
- height, depth, width = [float(l1) * dpi_fraction for l1 in l]
- return width, height + depth, depth
-
- else:
- # use dviread. It sometimes returns a wrong descent.
- dvifile = self.make_dvi(tex, fontsize)
- with dviread.Dvi(dvifile, 72 * dpi_fraction) as dvi:
- page = next(iter(dvi))
- # A total height (including the descent) needs to be returned.
- return page.width, page.height + page.descent, page.descent
diff --git a/contrib/python/matplotlib/py2/matplotlib/text.py b/contrib/python/matplotlib/py2/matplotlib/text.py
deleted file mode 100644
index 6838ba5678..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/text.py
+++ /dev/null
@@ -1,2336 +0,0 @@
-"""
-Classes for including text in a figure.
-"""
-from __future__ import absolute_import, division, print_function
-
-import six
-from six.moves import zip
-
-import contextlib
-import logging
-import math
-import warnings
-import weakref
-
-import numpy as np
-
-from . import artist, cbook, docstring, rcParams
-from .artist import Artist
-from .font_manager import FontProperties
-from .lines import Line2D
-from .patches import FancyArrowPatch, FancyBboxPatch, Rectangle
-from .textpath import TextPath # Unused, but imported by others.
-from .transforms import (
- Affine2D, Bbox, BboxBase, BboxTransformTo, IdentityTransform, Transform)
-
-
-_log = logging.getLogger(__name__)
-
-
-def _process_text_args(override, fontdict=None, **kwargs):
- "Return an override dict. See :func:`~pyplot.text' docstring for info"
-
- if fontdict is not None:
- override.update(fontdict)
-
- override.update(kwargs)
- return override
-
-
-@contextlib.contextmanager
-def _wrap_text(textobj):
- """Temporarily inserts newlines to the text if the wrap option is enabled.
- """
- if textobj.get_wrap():
- old_text = textobj.get_text()
- try:
- textobj.set_text(textobj._get_wrapped_text())
- yield textobj
- finally:
- textobj.set_text(old_text)
- else:
- yield textobj
-
-
-# Extracted from Text's method to serve as a function
-def get_rotation(rotation):
- """
- Return the text angle as float. The returned
- angle is between 0 and 360 deg.
-
- *rotation* may be 'horizontal', 'vertical', or a numeric value in degrees.
- """
- try:
- angle = float(rotation)
- except (ValueError, TypeError):
- isString = isinstance(rotation, six.string_types)
- if ((isString and rotation == 'horizontal') or rotation is None):
- angle = 0.
- elif (isString and rotation == 'vertical'):
- angle = 90.
- else:
- raise ValueError("rotation is {0} expected either 'horizontal'"
- " 'vertical', numeric value or"
- "None".format(rotation))
-
- return angle % 360
-
-
-def _get_textbox(text, renderer):
- """
- Calculate the bounding box of the text. Unlike
- :meth:`matplotlib.text.Text.get_extents` method, The bbox size of
- the text before the rotation is calculated.
- """
- # TODO : This function may move into the Text class as a method. As a
- # matter of fact, The information from the _get_textbox function
- # should be available during the Text._get_layout() call, which is
- # called within the _get_textbox. So, it would better to move this
- # function as a method with some refactoring of _get_layout method.
-
- projected_xs = []
- projected_ys = []
-
- theta = np.deg2rad(text.get_rotation())
- tr = Affine2D().rotate(-theta)
-
- _, parts, d = text._get_layout(renderer)
-
- for t, wh, x, y in parts:
- w, h = wh
-
- xt1, yt1 = tr.transform_point((x, y))
- yt1 -= d
- xt2, yt2 = xt1 + w, yt1 + h
-
- projected_xs.extend([xt1, xt2])
- projected_ys.extend([yt1, yt2])
-
- xt_box, yt_box = min(projected_xs), min(projected_ys)
- w_box, h_box = max(projected_xs) - xt_box, max(projected_ys) - yt_box
-
- tr = Affine2D().rotate(theta)
-
- x_box, y_box = tr.transform_point((xt_box, yt_box))
-
- return x_box, y_box, w_box, h_box
-
-
-class Text(Artist):
- """
- Handle storing and drawing of text in window or data coordinates.
- """
- zorder = 3
- _cached = cbook.maxdict(50)
-
- def __repr__(self):
- return "Text(%g,%g,%s)" % (self._x, self._y, repr(self._text))
-
- def __init__(self,
- x=0, y=0, text='',
- color=None, # defaults to rc params
- verticalalignment='baseline',
- horizontalalignment='left',
- multialignment=None,
- fontproperties=None, # defaults to FontProperties()
- rotation=None,
- linespacing=None,
- rotation_mode=None,
- usetex=None, # defaults to rcParams['text.usetex']
- wrap=False,
- **kwargs
- ):
- """
- Create a :class:`~matplotlib.text.Text` instance at *x*, *y*
- with string *text*.
-
- Valid kwargs are
- %(Text)s
- """
-
- Artist.__init__(self)
- self._x, self._y = x, y
-
- if color is None:
- color = rcParams['text.color']
- if fontproperties is None:
- fontproperties = FontProperties()
- elif isinstance(fontproperties, six.string_types):
- fontproperties = FontProperties(fontproperties)
-
- self.set_text(text)
- self.set_color(color)
- self.set_usetex(usetex)
- self.set_wrap(wrap)
- self._verticalalignment = verticalalignment
- self._horizontalalignment = horizontalalignment
- self._multialignment = multialignment
- self._rotation = rotation
- self._fontproperties = fontproperties
- self._bbox_patch = None # a FancyBboxPatch instance
- self._renderer = None
- if linespacing is None:
- linespacing = 1.2 # Maybe use rcParam later.
- self._linespacing = linespacing
- self.set_rotation_mode(rotation_mode)
- self.update(kwargs)
-
- def update(self, kwargs):
- """
- Update properties from a dictionary.
- """
- # Update bbox last, as it depends on font properties.
- sentinel = object() # bbox can be None, so use another sentinel.
- bbox = kwargs.pop("bbox", sentinel)
- super(Text, self).update(kwargs)
- if bbox is not sentinel:
- self.set_bbox(bbox)
-
- def __getstate__(self):
- d = super(Text, self).__getstate__()
- # remove the cached _renderer (if it exists)
- d['_renderer'] = None
- return d
-
- def contains(self, mouseevent):
- """Test whether the mouse event occurred in the patch.
-
- In the case of text, a hit is true anywhere in the
- axis-aligned bounding-box containing the text.
-
- Returns True or False.
- """
- if callable(self._contains):
- return self._contains(self, mouseevent)
-
- if not self.get_visible() or self._renderer is None:
- return False, {}
-
- l, b, w, h = self.get_window_extent().bounds
- r, t = l + w, b + h
-
- x, y = mouseevent.x, mouseevent.y
- inside = (l <= x <= r and b <= y <= t)
- cattr = {}
-
- # if the text has a surrounding patch, also check containment for it,
- # and merge the results with the results for the text.
- if self._bbox_patch:
- patch_inside, patch_cattr = self._bbox_patch.contains(mouseevent)
- inside = inside or patch_inside
- cattr["bbox_patch"] = patch_cattr
-
- return inside, cattr
-
- def _get_xy_display(self):
- 'get the (possibly unit converted) transformed x, y in display coords'
- x, y = self.get_unitless_position()
- return self.get_transform().transform_point((x, y))
-
- def _get_multialignment(self):
- if self._multialignment is not None:
- return self._multialignment
- else:
- return self._horizontalalignment
-
- def get_rotation(self):
- 'return the text angle as float in degrees'
- return get_rotation(self._rotation) # string_or_number -> number
-
- def set_rotation_mode(self, m):
- """
- Set text rotation mode.
-
- .. ACCEPTS: [ None | "default" | "anchor" ]
-
- Parameters
- ----------
- m : ``None`` or ``"default"`` or ``"anchor"``
- If ``None`` or ``"default"``, the text will be first rotated, then
- aligned according to their horizontal and vertical alignments. If
- ``"anchor"``, then alignment occurs before rotation.
- """
- if m is None or m in ["anchor", "default"]:
- self._rotation_mode = m
- else:
- raise ValueError("Unknown rotation_mode : %s" % repr(m))
- self.stale = True
-
- def get_rotation_mode(self):
- "get text rotation mode"
- return self._rotation_mode
-
- def update_from(self, other):
- 'Copy properties from other to self'
- Artist.update_from(self, other)
- self._color = other._color
- self._multialignment = other._multialignment
- self._verticalalignment = other._verticalalignment
- self._horizontalalignment = other._horizontalalignment
- self._fontproperties = other._fontproperties.copy()
- self._rotation = other._rotation
- self._picker = other._picker
- self._linespacing = other._linespacing
- self.stale = True
-
- def _get_layout(self, renderer):
- """
- return the extent (bbox) of the text together with
- multiple-alignment information. Note that it returns an extent
- of a rotated text when necessary.
- """
- key = self.get_prop_tup(renderer=renderer)
- if key in self._cached:
- return self._cached[key]
-
- horizLayout = []
-
- thisx, thisy = 0.0, 0.0
- xmin, ymin = 0.0, 0.0
- width, height = 0.0, 0.0
- lines = self.get_text().split('\n')
-
- whs = np.zeros((len(lines), 2))
- horizLayout = np.zeros((len(lines), 4))
-
- # Find full vertical extent of font,
- # including ascenders and descenders:
- tmp, lp_h, lp_bl = renderer.get_text_width_height_descent('lp',
- self._fontproperties,
- ismath=False)
- offsety = (lp_h - lp_bl) * self._linespacing
-
- baseline = 0
- for i, line in enumerate(lines):
- clean_line, ismath = self.is_math_text(line, self.get_usetex())
- if clean_line:
- w, h, d = renderer.get_text_width_height_descent(clean_line,
- self._fontproperties,
- ismath=ismath)
- else:
- w, h, d = 0, 0, 0
-
- # For multiline text, increase the line spacing when the
- # text net-height(excluding baseline) is larger than that
- # of a "l" (e.g., use of superscripts), which seems
- # what TeX does.
- h = max(h, lp_h)
- d = max(d, lp_bl)
-
- whs[i] = w, h
-
- baseline = (h - d) - thisy
- thisy -= max(offsety, (h - d) * self._linespacing)
- horizLayout[i] = thisx, thisy, w, h
- thisy -= d
- width = max(width, w)
- descent = d
-
- ymin = horizLayout[-1][1]
- ymax = horizLayout[0][1] + horizLayout[0][3]
- height = ymax - ymin
- xmax = xmin + width
-
- # get the rotation matrix
- M = Affine2D().rotate_deg(self.get_rotation())
-
- offsetLayout = np.zeros((len(lines), 2))
- offsetLayout[:] = horizLayout[:, 0:2]
- # now offset the individual text lines within the box
- if len(lines) > 1: # do the multiline aligment
- malign = self._get_multialignment()
- if malign == 'center':
- offsetLayout[:, 0] += width / 2.0 - horizLayout[:, 2] / 2.0
- elif malign == 'right':
- offsetLayout[:, 0] += width - horizLayout[:, 2]
-
- # the corners of the unrotated bounding box
- cornersHoriz = np.array(
- [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)], float)
- cornersHoriz[:, 1] -= descent
-
- # now rotate the bbox
- cornersRotated = M.transform(cornersHoriz)
-
- txs = cornersRotated[:, 0]
- tys = cornersRotated[:, 1]
-
- # compute the bounds of the rotated box
- xmin, xmax = txs.min(), txs.max()
- ymin, ymax = tys.min(), tys.max()
- width = xmax - xmin
- height = ymax - ymin
-
- # Now move the box to the target position offset the display
- # bbox by alignment
- halign = self._horizontalalignment
- valign = self._verticalalignment
-
- rotation_mode = self.get_rotation_mode()
- if rotation_mode != "anchor":
- # compute the text location in display coords and the offsets
- # necessary to align the bbox with that location
- if halign == 'center':
- offsetx = (xmin + width / 2.0)
- elif halign == 'right':
- offsetx = (xmin + width)
- else:
- offsetx = xmin
-
- if valign == 'center':
- offsety = (ymin + height / 2.0)
- elif valign == 'top':
- offsety = (ymin + height)
- elif valign == 'baseline':
- offsety = (ymin + height) - baseline
- elif valign == 'center_baseline':
- offsety = ymin + height - baseline / 2.0
- else:
- offsety = ymin
- else:
- xmin1, ymin1 = cornersHoriz[0]
- xmax1, ymax1 = cornersHoriz[2]
-
- if halign == 'center':
- offsetx = (xmin1 + xmax1) / 2.0
- elif halign == 'right':
- offsetx = xmax1
- else:
- offsetx = xmin1
-
- if valign == 'center':
- offsety = (ymin1 + ymax1) / 2.0
- elif valign == 'top':
- offsety = ymax1
- elif valign == 'baseline':
- offsety = ymax1 - baseline
- elif valign == 'center_baseline':
- offsety = (ymin1 + ymax1 - baseline) / 2.0
- else:
- offsety = ymin1
-
- offsetx, offsety = M.transform_point((offsetx, offsety))
-
- xmin -= offsetx
- ymin -= offsety
-
- bbox = Bbox.from_bounds(xmin, ymin, width, height)
-
- # now rotate the positions around the first x,y position
- xys = M.transform(offsetLayout)
- xys -= (offsetx, offsety)
-
- xs, ys = xys[:, 0], xys[:, 1]
-
- ret = bbox, list(zip(lines, whs, xs, ys)), descent
- self._cached[key] = ret
- return ret
-
- def set_bbox(self, rectprops):
- """
- Draw a bounding box around self. rectprops are any settable
- properties for a FancyBboxPatch, e.g., facecolor='red', alpha=0.5.
-
- t.set_bbox(dict(facecolor='red', alpha=0.5))
-
- The default boxstyle is 'square'. The mutation
- scale of the FancyBboxPatch is set to the fontsize.
-
- ACCEPTS: FancyBboxPatch prop dict
- """
-
- if rectprops is not None:
- props = rectprops.copy()
- boxstyle = props.pop("boxstyle", None)
- pad = props.pop("pad", None)
- if boxstyle is None:
- boxstyle = "square"
- if pad is None:
- pad = 4 # points
- pad /= self.get_size() # to fraction of font size
- else:
- if pad is None:
- pad = 0.3
-
- # boxstyle could be a callable or a string
- if (isinstance(boxstyle, six.string_types)
- and "pad" not in boxstyle):
- boxstyle += ",pad=%0.2f" % pad
-
- bbox_transmuter = props.pop("bbox_transmuter", None)
-
- self._bbox_patch = FancyBboxPatch(
- (0., 0.),
- 1., 1.,
- boxstyle=boxstyle,
- bbox_transmuter=bbox_transmuter,
- transform=IdentityTransform(),
- **props)
- else:
- self._bbox_patch = None
-
- self._update_clip_properties()
-
- def get_bbox_patch(self):
- """
- Return the bbox Patch object. Returns None if the
- FancyBboxPatch is not made.
- """
- return self._bbox_patch
-
- def update_bbox_position_size(self, renderer):
- """
- Update the location and the size of the bbox. This method
- should be used when the position and size of the bbox needs to
- be updated before actually drawing the bbox.
- """
-
- if self._bbox_patch:
-
- trans = self.get_transform()
-
- # don't use self.get_unitless_position here, which refers to text
- # position in Text, and dash position in TextWithDash:
- posx = float(self.convert_xunits(self._x))
- posy = float(self.convert_yunits(self._y))
-
- posx, posy = trans.transform_point((posx, posy))
-
- x_box, y_box, w_box, h_box = _get_textbox(self, renderer)
- self._bbox_patch.set_bounds(0., 0., w_box, h_box)
- theta = np.deg2rad(self.get_rotation())
- tr = Affine2D().rotate(theta)
- tr = tr.translate(posx + x_box, posy + y_box)
- self._bbox_patch.set_transform(tr)
- fontsize_in_pixel = renderer.points_to_pixels(self.get_size())
- self._bbox_patch.set_mutation_scale(fontsize_in_pixel)
-
- def _draw_bbox(self, renderer, posx, posy):
-
- """ Update the location and the size of the bbox
- (FancyBboxPatch), and draw
- """
-
- x_box, y_box, w_box, h_box = _get_textbox(self, renderer)
- self._bbox_patch.set_bounds(0., 0., w_box, h_box)
- theta = np.deg2rad(self.get_rotation())
- tr = Affine2D().rotate(theta)
- tr = tr.translate(posx + x_box, posy + y_box)
- self._bbox_patch.set_transform(tr)
- fontsize_in_pixel = renderer.points_to_pixels(self.get_size())
- self._bbox_patch.set_mutation_scale(fontsize_in_pixel)
- self._bbox_patch.draw(renderer)
-
- def _update_clip_properties(self):
- clipprops = dict(clip_box=self.clipbox,
- clip_path=self._clippath,
- clip_on=self._clipon)
-
- if self._bbox_patch:
- bbox = self._bbox_patch.update(clipprops)
-
- def set_clip_box(self, clipbox):
- """
- Set the artist's clip :class:`~matplotlib.transforms.Bbox`.
-
- ACCEPTS: a :class:`matplotlib.transforms.Bbox` instance
- """
- super(Text, self).set_clip_box(clipbox)
- self._update_clip_properties()
-
- def set_clip_path(self, path, transform=None):
- """
- Set the artist's clip path, which may be:
-
- * a :class:`~matplotlib.patches.Patch` (or subclass) instance
-
- * a :class:`~matplotlib.path.Path` instance, in which case
- an optional :class:`~matplotlib.transforms.Transform`
- instance may be provided, which will be applied to the
- path before using it for clipping.
-
- * *None*, to remove the clipping path
-
- For efficiency, if the path happens to be an axis-aligned
- rectangle, this method will set the clipping box to the
- corresponding rectangle and set the clipping path to *None*.
-
- ACCEPTS: [ (:class:`~matplotlib.path.Path`,
- :class:`~matplotlib.transforms.Transform`) |
- :class:`~matplotlib.patches.Patch` | None ]
- """
- super(Text, self).set_clip_path(path, transform)
- self._update_clip_properties()
-
- def set_clip_on(self, b):
- """
- Set whether artist uses clipping.
-
- When False, artists will be visible outside of the axes, which can lead
- to unexpected results.
-
- Parameters
- ----------
- b : bool
- .. ACCEPTS: bool
- """
- super(Text, self).set_clip_on(b)
- self._update_clip_properties()
-
- def get_wrap(self):
- """Returns the wrapping state for the text."""
- return self._wrap
-
- def set_wrap(self, wrap):
- """Sets the wrapping state for the text.
-
- Parameters
- ----------
- wrap : bool
- .. ACCEPTS: bool
- """
- self._wrap = wrap
-
- def _get_wrap_line_width(self):
- """
- Returns the maximum line width for wrapping text based on the
- current orientation.
- """
- x0, y0 = self.get_transform().transform(self.get_position())
- figure_box = self.get_figure().get_window_extent()
-
- # Calculate available width based on text alignment
- alignment = self.get_horizontalalignment()
- self.set_rotation_mode('anchor')
- rotation = self.get_rotation()
-
- left = self._get_dist_to_box(rotation, x0, y0, figure_box)
- right = self._get_dist_to_box(
- (180 + rotation) % 360,
- x0,
- y0,
- figure_box)
-
- if alignment == 'left':
- line_width = left
- elif alignment == 'right':
- line_width = right
- else:
- line_width = 2 * min(left, right)
-
- return line_width
-
- def _get_dist_to_box(self, rotation, x0, y0, figure_box):
- """
- Returns the distance from the given points, to the boundaries
- of a rotated box in pixels.
- """
- if rotation > 270:
- quad = rotation - 270
- h1 = y0 / math.cos(math.radians(quad))
- h2 = (figure_box.x1 - x0) / math.cos(math.radians(90 - quad))
- elif rotation > 180:
- quad = rotation - 180
- h1 = x0 / math.cos(math.radians(quad))
- h2 = y0 / math.cos(math.radians(90 - quad))
- elif rotation > 90:
- quad = rotation - 90
- h1 = (figure_box.y1 - y0) / math.cos(math.radians(quad))
- h2 = x0 / math.cos(math.radians(90 - quad))
- else:
- h1 = (figure_box.x1 - x0) / math.cos(math.radians(rotation))
- h2 = (figure_box.y1 - y0) / math.cos(math.radians(90 - rotation))
-
- return min(h1, h2)
-
- def _get_rendered_text_width(self, text):
- """
- Returns the width of a given text string, in pixels.
- """
- w, h, d = self._renderer.get_text_width_height_descent(
- text,
- self.get_fontproperties(),
- False)
- return math.ceil(w)
-
- def _get_wrapped_text(self):
- """
- Return a copy of the text with new lines added, so that
- the text is wrapped relative to the parent figure.
- """
- # Not fit to handle breaking up latex syntax correctly, so
- # ignore latex for now.
- if self.get_usetex():
- return self.get_text()
-
- # Build the line incrementally, for a more accurate measure of length
- line_width = self._get_wrap_line_width()
- wrapped_str = ""
- line = ""
-
- for word in self.get_text().split(' '):
- # New lines in the user's test need to force a split, so that it's
- # not using the longest current line width in the line being built
- sub_words = word.split('\n')
- for i in range(len(sub_words)):
- current_width = self._get_rendered_text_width(
- line + ' ' + sub_words[i])
-
- # Split long lines, and each newline found in the current word
- if current_width > line_width or i > 0:
- wrapped_str += line + '\n'
- line = ""
-
- if line == "":
- line = sub_words[i]
- else:
- line += ' ' + sub_words[i]
-
- return wrapped_str + line
-
- @artist.allow_rasterization
- def draw(self, renderer):
- """
- Draws the :class:`Text` object to the given *renderer*.
- """
- if renderer is not None:
- self._renderer = renderer
- if not self.get_visible():
- return
- if self.get_text() == '':
- return
-
- renderer.open_group('text', self.get_gid())
-
- with _wrap_text(self) as textobj:
- bbox, info, descent = textobj._get_layout(renderer)
- trans = textobj.get_transform()
-
- # don't use textobj.get_position here, which refers to text
- # position in Text, and dash position in TextWithDash:
- posx = float(textobj.convert_xunits(textobj._x))
- posy = float(textobj.convert_yunits(textobj._y))
- posx, posy = trans.transform_point((posx, posy))
- if not np.isfinite(posx) or not np.isfinite(posy):
- _log.warning("posx and posy should be finite values")
- return
- canvasw, canvash = renderer.get_canvas_width_height()
-
- # draw the FancyBboxPatch
- if textobj._bbox_patch:
- textobj._draw_bbox(renderer, posx, posy)
-
- gc = renderer.new_gc()
- gc.set_foreground(textobj.get_color())
- gc.set_alpha(textobj.get_alpha())
- gc.set_url(textobj._url)
- textobj._set_gc_clip(gc)
-
- angle = textobj.get_rotation()
-
- for line, wh, x, y in info:
-
- mtext = textobj if len(info) == 1 else None
- x = x + posx
- y = y + posy
- if renderer.flipy():
- y = canvash - y
- clean_line, ismath = textobj.is_math_text(line,
- self.get_usetex())
-
- if textobj.get_path_effects():
- from matplotlib.patheffects import PathEffectRenderer
- textrenderer = PathEffectRenderer(
- textobj.get_path_effects(), renderer)
- else:
- textrenderer = renderer
-
- if textobj.get_usetex():
- textrenderer.draw_tex(gc, x, y, clean_line,
- textobj._fontproperties, angle,
- mtext=mtext)
- else:
- textrenderer.draw_text(gc, x, y, clean_line,
- textobj._fontproperties, angle,
- ismath=ismath, mtext=mtext)
-
- gc.restore()
- renderer.close_group('text')
- self.stale = False
-
- def get_color(self):
- "Return the color of the text"
- return self._color
-
- def get_fontproperties(self):
- "Return the :class:`~font_manager.FontProperties` object"
- return self._fontproperties
-
- def get_font_properties(self):
- 'alias for get_fontproperties'
- return self.get_fontproperties()
-
- def get_family(self):
- "Return the list of font families used for font lookup"
- return self._fontproperties.get_family()
-
- def get_fontfamily(self):
- 'alias for get_family'
- return self.get_family()
-
- def get_name(self):
- "Return the font name as string"
- return self._fontproperties.get_name()
-
- def get_style(self):
- "Return the font style as string"
- return self._fontproperties.get_style()
-
- def get_size(self):
- "Return the font size as integer"
- return self._fontproperties.get_size_in_points()
-
- def get_variant(self):
- "Return the font variant as a string"
- return self._fontproperties.get_variant()
-
- def get_fontvariant(self):
- 'alias for get_variant'
- return self.get_variant()
-
- def get_weight(self):
- "Get the font weight as string or number"
- return self._fontproperties.get_weight()
-
- def get_fontname(self):
- 'alias for get_name'
- return self.get_name()
-
- def get_fontstyle(self):
- 'alias for get_style'
- return self.get_style()
-
- def get_fontsize(self):
- 'alias for get_size'
- return self.get_size()
-
- def get_fontweight(self):
- 'alias for get_weight'
- return self.get_weight()
-
- def get_stretch(self):
- 'Get the font stretch as a string or number'
- return self._fontproperties.get_stretch()
-
- def get_fontstretch(self):
- 'alias for get_stretch'
- return self.get_stretch()
-
- def get_ha(self):
- 'alias for get_horizontalalignment'
- return self.get_horizontalalignment()
-
- def get_horizontalalignment(self):
- """
- Return the horizontal alignment as string. Will be one of
- 'left', 'center' or 'right'.
- """
- return self._horizontalalignment
-
- def get_unitless_position(self):
- "Return the unitless position of the text as a tuple (*x*, *y*)"
- # This will get the position with all unit information stripped away.
- # This is here for convenience since it is done in several locations.
- x = float(self.convert_xunits(self._x))
- y = float(self.convert_yunits(self._y))
- return x, y
-
- def get_position(self):
- "Return the position of the text as a tuple (*x*, *y*)"
- # This should return the same data (possible unitized) as was
- # specified with 'set_x' and 'set_y'.
- return self._x, self._y
-
- def get_prop_tup(self, renderer=None):
- """
- Return a hashable tuple of properties.
-
- Not intended to be human readable, but useful for backends who
- want to cache derived information about text (e.g., layouts) and
- need to know if the text has changed.
- """
- x, y = self.get_unitless_position()
- renderer = renderer or self._renderer
- return (x, y, self.get_text(), self._color,
- self._verticalalignment, self._horizontalalignment,
- hash(self._fontproperties),
- self._rotation, self._rotation_mode,
- self.figure.dpi, weakref.ref(renderer),
- self._linespacing
- )
-
- def get_text(self):
- "Get the text as string"
- return self._text
-
- def get_va(self):
- 'alias for :meth:`getverticalalignment`'
- return self.get_verticalalignment()
-
- def get_verticalalignment(self):
- """
- Return the vertical alignment as string. Will be one of
- 'top', 'center', 'bottom' or 'baseline'.
- """
- return self._verticalalignment
-
- def get_window_extent(self, renderer=None, dpi=None):
- '''
- Return a :class:`~matplotlib.transforms.Bbox` object bounding
- the text, in display units.
-
- In addition to being used internally, this is useful for
- specifying clickable regions in a png file on a web page.
-
- *renderer* defaults to the _renderer attribute of the text
- object. This is not assigned until the first execution of
- :meth:`draw`, so you must use this kwarg if you want
- to call :meth:`get_window_extent` prior to the first
- :meth:`draw`. For getting web page regions, it is
- simpler to call the method after saving the figure.
-
- *dpi* defaults to self.figure.dpi; the renderer dpi is
- irrelevant. For the web application, if figure.dpi is not
- the value used when saving the figure, then the value that
- was used must be specified as the *dpi* argument.
- '''
- #return _unit_box
- if not self.get_visible():
- return Bbox.unit()
- if dpi is not None:
- dpi_orig = self.figure.dpi
- self.figure.dpi = dpi
- if self.get_text() == '':
- tx, ty = self._get_xy_display()
- return Bbox.from_bounds(tx, ty, 0, 0)
-
- if renderer is not None:
- self._renderer = renderer
- if self._renderer is None:
- self._renderer = self.figure._cachedRenderer
- if self._renderer is None:
- raise RuntimeError('Cannot get window extent w/o renderer')
-
- bbox, info, descent = self._get_layout(self._renderer)
- x, y = self.get_unitless_position()
- x, y = self.get_transform().transform_point((x, y))
- bbox = bbox.translated(x, y)
- if dpi is not None:
- self.figure.dpi = dpi_orig
- return bbox
-
- def set_backgroundcolor(self, color):
- """
- Set the background color of the text by updating the bbox.
-
- .. seealso::
-
- :meth:`set_bbox`
- To change the position of the bounding box.
-
- ACCEPTS: any matplotlib color
- """
- if self._bbox_patch is None:
- self.set_bbox(dict(facecolor=color, edgecolor=color))
- else:
- self._bbox_patch.update(dict(facecolor=color))
-
- self._update_clip_properties()
- self.stale = True
-
- def set_color(self, color):
- """
- Set the foreground color of the text
-
- ACCEPTS: any matplotlib color
- """
- # Make sure it is hashable, or get_prop_tup will fail.
- try:
- hash(color)
- except TypeError:
- color = tuple(color)
- self._color = color
- self.stale = True
-
- def set_ha(self, align):
- 'alias for set_horizontalalignment'
- self.set_horizontalalignment(align)
-
- def set_horizontalalignment(self, align):
- """
- Set the horizontal alignment to one of
-
- ACCEPTS: [ 'center' | 'right' | 'left' ]
- """
- legal = ('center', 'right', 'left')
- if align not in legal:
- raise ValueError('Horizontal alignment must be one of %s' %
- str(legal))
- self._horizontalalignment = align
- self.stale = True
-
- def set_ma(self, align):
- 'alias for set_multialignment'
- self.set_multialignment(align)
-
- def set_multialignment(self, align):
- """
- Set the alignment for multiple lines layout. The layout of the
- bounding box of all the lines is determined bu the horizontalalignment
- and verticalalignment properties, but the multiline text within that
- box can be
-
- ACCEPTS: ['left' | 'right' | 'center' ]
- """
- legal = ('center', 'right', 'left')
- if align not in legal:
- raise ValueError('Horizontal alignment must be one of %s' %
- str(legal))
- self._multialignment = align
- self.stale = True
-
- def set_linespacing(self, spacing):
- """
- Set the line spacing as a multiple of the font size.
- Default is 1.2.
-
- ACCEPTS: float (multiple of font size)
- """
- self._linespacing = spacing
- self.stale = True
-
- def set_family(self, fontname):
- """
- Set the font family. May be either a single string, or a list
- of strings in decreasing priority. Each string may be either
- a real font name or a generic font class name. If the latter,
- the specific font names will be looked up in the
- :file:`matplotlibrc` file.
-
- ACCEPTS: [FONTNAME | 'serif' | 'sans-serif' | 'cursive' | 'fantasy' |
- 'monospace' ]
- """
- self._fontproperties.set_family(fontname)
- self.stale = True
-
- def set_variant(self, variant):
- """
- Set the font variant, either 'normal' or 'small-caps'.
-
- ACCEPTS: [ 'normal' | 'small-caps' ]
- """
- self._fontproperties.set_variant(variant)
- self.stale = True
-
- def set_fontvariant(self, variant):
- 'alias for set_variant'
- return self.set_variant(variant)
-
- def set_name(self, fontname):
- """alias for set_family"""
- return self.set_family(fontname)
-
- def set_fontname(self, fontname):
- """alias for set_family"""
- self.set_family(fontname)
-
- def set_style(self, fontstyle):
- """
- Set the font style.
-
- ACCEPTS: [ 'normal' | 'italic' | 'oblique']
- """
- self._fontproperties.set_style(fontstyle)
- self.stale = True
-
- def set_fontstyle(self, fontstyle):
- 'alias for set_style'
- return self.set_style(fontstyle)
-
- def set_size(self, fontsize):
- """
- Set the font size. May be either a size string, relative to
- the default font size, or an absolute font size in points.
-
- ACCEPTS: [size in points | 'xx-small' | 'x-small' | 'small' |
- 'medium' | 'large' | 'x-large' | 'xx-large' ]
- """
- self._fontproperties.set_size(fontsize)
- self.stale = True
-
- def set_fontsize(self, fontsize):
- 'alias for set_size'
- return self.set_size(fontsize)
-
- def set_weight(self, weight):
- """
- Set the font weight.
-
- ACCEPTS: [a numeric value in range 0-1000 | 'ultralight' | 'light' |
- 'normal' | 'regular' | 'book' | 'medium' | 'roman' |
- 'semibold' | 'demibold' | 'demi' | 'bold' | 'heavy' |
- 'extra bold' | 'black' ]
- """
- self._fontproperties.set_weight(weight)
- self.stale = True
-
- def set_fontweight(self, weight):
- 'alias for set_weight'
- return self.set_weight(weight)
-
- def set_stretch(self, stretch):
- """
- Set the font stretch (horizontal condensation or expansion).
-
- ACCEPTS: [a numeric value in range 0-1000 | 'ultra-condensed' |
- 'extra-condensed' | 'condensed' | 'semi-condensed' |
- 'normal' | 'semi-expanded' | 'expanded' | 'extra-expanded' |
- 'ultra-expanded' ]
- """
- self._fontproperties.set_stretch(stretch)
- self.stale = True
-
- def set_fontstretch(self, stretch):
- 'alias for set_stretch'
- return self.set_stretch(stretch)
-
- def set_position(self, xy):
- """
- Set the (*x*, *y*) position of the text
-
- ACCEPTS: (x,y)
- """
- self.set_x(xy[0])
- self.set_y(xy[1])
-
- def set_x(self, x):
- """
- Set the *x* position of the text
-
- ACCEPTS: float
- """
- self._x = x
- self.stale = True
-
- def set_y(self, y):
- """
- Set the *y* position of the text
-
- ACCEPTS: float
- """
- self._y = y
- self.stale = True
-
- def set_rotation(self, s):
- """
- Set the rotation of the text
-
- ACCEPTS: [ angle in degrees | 'vertical' | 'horizontal' ]
- """
- self._rotation = s
- self.stale = True
-
- def set_va(self, align):
- 'alias for set_verticalalignment'
- self.set_verticalalignment(align)
-
- def set_verticalalignment(self, align):
- """
- Set the vertical alignment
-
- ACCEPTS: [ 'center' | 'top' | 'bottom' | 'baseline' ]
- """
- legal = ('top', 'bottom', 'center', 'baseline')
- if align not in legal:
- raise ValueError('Vertical alignment must be one of %s' %
- str(legal))
-
- self._verticalalignment = align
- self.stale = True
-
- def set_text(self, s):
- """
- Set the text string *s*
-
- It may contain newlines (``\\n``) or math in LaTeX syntax.
-
- ACCEPTS: string or anything printable with '%s' conversion.
- """
- self._text = '%s' % (s,)
- self.stale = True
-
- @staticmethod
- def is_math_text(s, usetex=None):
- """
- Returns a cleaned string and a boolean flag.
- The flag indicates if the given string *s* contains any mathtext,
- determined by counting unescaped dollar signs. If no mathtext
- is present, the cleaned string has its dollar signs unescaped.
- If usetex is on, the flag always has the value "TeX".
- """
- # Did we find an even number of non-escaped dollar signs?
- # If so, treat is as math text.
- if usetex is None:
- usetex = rcParams['text.usetex']
- if usetex:
- if s == ' ':
- s = r'\ '
- return s, 'TeX'
-
- if cbook.is_math_text(s):
- return s, True
- else:
- return s.replace(r'\$', '$'), False
-
- def set_fontproperties(self, fp):
- """
- Set the font properties that control the text. *fp* must be a
- :class:`matplotlib.font_manager.FontProperties` object.
-
- ACCEPTS: a :class:`matplotlib.font_manager.FontProperties` instance
- """
- if isinstance(fp, six.string_types):
- fp = FontProperties(fp)
- self._fontproperties = fp.copy()
- self.stale = True
-
- def set_font_properties(self, fp):
- 'alias for set_fontproperties'
- self.set_fontproperties(fp)
-
- def set_usetex(self, usetex):
- """
- Parameters
- ----------
- usetex : bool or None
- Whether to render using TeX, ``None`` means to use
- :rc:`text.usetex`.
-
- .. ACCEPTS: bool or None
- """
- if usetex is None:
- self._usetex = rcParams['text.usetex']
- else:
- self._usetex = bool(usetex)
- self.stale = True
-
- def get_usetex(self):
- """
- Return whether this `Text` object uses TeX for rendering.
-
- If the user has not manually set this value, it defaults to
- :rc:`text.usetex`.
- """
- if self._usetex is None:
- return rcParams['text.usetex']
- else:
- return self._usetex
-
-docstring.interpd.update(Text=artist.kwdoc(Text))
-docstring.dedent_interpd(Text.__init__)
-
-
-class TextWithDash(Text):
- """
- This is basically a :class:`~matplotlib.text.Text` with a dash
- (drawn with a :class:`~matplotlib.lines.Line2D`) before/after
- it. It is intended to be a drop-in replacement for
- :class:`~matplotlib.text.Text`, and should behave identically to
- it when *dashlength* = 0.0.
-
- The dash always comes between the point specified by
- :meth:`~matplotlib.text.Text.set_position` and the text. When a
- dash exists, the text alignment arguments (*horizontalalignment*,
- *verticalalignment*) are ignored.
-
- *dashlength* is the length of the dash in canvas units.
- (default = 0.0).
-
- *dashdirection* is one of 0 or 1, where 0 draws the dash after the
- text and 1 before. (default = 0).
-
- *dashrotation* specifies the rotation of the dash, and should
- generally stay *None*. In this case
- :meth:`~matplotlib.text.TextWithDash.get_dashrotation` returns
- :meth:`~matplotlib.text.Text.get_rotation`. (i.e., the dash takes
- its rotation from the text's rotation). Because the text center is
- projected onto the dash, major deviations in the rotation cause
- what may be considered visually unappealing results.
- (default = *None*)
-
- *dashpad* is a padding length to add (or subtract) space
- between the text and the dash, in canvas units.
- (default = 3)
-
- *dashpush* "pushes" the dash and text away from the point
- specified by :meth:`~matplotlib.text.Text.set_position` by the
- amount in canvas units. (default = 0)
-
- .. note::
-
- The alignment of the two objects is based on the bounding box
- of the :class:`~matplotlib.text.Text`, as obtained by
- :meth:`~matplotlib.artist.Artist.get_window_extent`. This, in
- turn, appears to depend on the font metrics as given by the
- rendering backend. Hence the quality of the "centering" of the
- label text with respect to the dash varies depending on the
- backend used.
-
- .. note::
-
- I'm not sure that I got the
- :meth:`~matplotlib.text.TextWithDash.get_window_extent` right,
- or whether that's sufficient for providing the object bounding
- box.
-
- """
- __name__ = 'textwithdash'
-
- def __str__(self):
- return "TextWithDash(%g,%g,%s)" % (self._x, self._y, repr(self._text))
-
- def __init__(self,
- x=0, y=0, text='',
- color=None, # defaults to rc params
- verticalalignment='center',
- horizontalalignment='center',
- multialignment=None,
- fontproperties=None, # defaults to FontProperties()
- rotation=None,
- linespacing=None,
- dashlength=0.0,
- dashdirection=0,
- dashrotation=None,
- dashpad=3,
- dashpush=0,
- ):
-
- Text.__init__(self, x=x, y=y, text=text, color=color,
- verticalalignment=verticalalignment,
- horizontalalignment=horizontalalignment,
- multialignment=multialignment,
- fontproperties=fontproperties,
- rotation=rotation,
- linespacing=linespacing)
-
- # The position (x,y) values for text and dashline
- # are bogus as given in the instantiation; they will
- # be set correctly by update_coords() in draw()
-
- self.dashline = Line2D(xdata=(x, x),
- ydata=(y, y),
- color='k',
- linestyle='-')
-
- self._dashx = float(x)
- self._dashy = float(y)
- self._dashlength = dashlength
- self._dashdirection = dashdirection
- self._dashrotation = dashrotation
- self._dashpad = dashpad
- self._dashpush = dashpush
-
- #self.set_bbox(dict(pad=0))
-
- def get_unitless_position(self):
- "Return the unitless position of the text as a tuple (*x*, *y*)"
- # This will get the position with all unit information stripped away.
- # This is here for convenience since it is done in several locations.
- x = float(self.convert_xunits(self._dashx))
- y = float(self.convert_yunits(self._dashy))
- return x, y
-
- def get_position(self):
- "Return the position of the text as a tuple (*x*, *y*)"
- # This should return the same data (possibly unitized) as was
- # specified with set_x and set_y
- return self._dashx, self._dashy
-
- def get_prop_tup(self, renderer=None):
- """
- Return a hashable tuple of properties.
-
- Not intended to be human readable, but useful for backends who
- want to cache derived information about text (e.g., layouts) and
- need to know if the text has changed.
- """
- props = [p for p in Text.get_prop_tup(self, renderer=renderer)]
- props.extend([self._x, self._y, self._dashlength,
- self._dashdirection, self._dashrotation, self._dashpad,
- self._dashpush])
- return tuple(props)
-
- def draw(self, renderer):
- """
- Draw the :class:`TextWithDash` object to the given *renderer*.
- """
- self.update_coords(renderer)
- Text.draw(self, renderer)
- if self.get_dashlength() > 0.0:
- self.dashline.draw(renderer)
- self.stale = False
-
- def update_coords(self, renderer):
- """
- Computes the actual *x*, *y* coordinates for text based on the
- input *x*, *y* and the *dashlength*. Since the rotation is
- with respect to the actual canvas's coordinates we need to map
- back and forth.
- """
- dashx, dashy = self.get_unitless_position()
- dashlength = self.get_dashlength()
- # Shortcircuit this process if we don't have a dash
- if dashlength == 0.0:
- self._x, self._y = dashx, dashy
- return
-
- dashrotation = self.get_dashrotation()
- dashdirection = self.get_dashdirection()
- dashpad = self.get_dashpad()
- dashpush = self.get_dashpush()
-
- angle = get_rotation(dashrotation)
- theta = np.pi * (angle / 180.0 + dashdirection - 1)
- cos_theta, sin_theta = np.cos(theta), np.sin(theta)
-
- transform = self.get_transform()
-
- # Compute the dash end points
- # The 'c' prefix is for canvas coordinates
- cxy = transform.transform_point((dashx, dashy))
- cd = np.array([cos_theta, sin_theta])
- c1 = cxy + dashpush * cd
- c2 = cxy + (dashpush + dashlength) * cd
-
- inverse = transform.inverted()
- (x1, y1) = inverse.transform_point(tuple(c1))
- (x2, y2) = inverse.transform_point(tuple(c2))
- self.dashline.set_data((x1, x2), (y1, y2))
-
- # We now need to extend this vector out to
- # the center of the text area.
- # The basic problem here is that we're "rotating"
- # two separate objects but want it to appear as
- # if they're rotated together.
- # This is made non-trivial because of the
- # interaction between text rotation and alignment -
- # text alignment is based on the bbox after rotation.
- # We reset/force both alignments to 'center'
- # so we can do something relatively reasonable.
- # There's probably a better way to do this by
- # embedding all this in the object's transformations,
- # but I don't grok the transformation stuff
- # well enough yet.
- we = Text.get_window_extent(self, renderer=renderer)
- w, h = we.width, we.height
- # Watch for zeros
- if sin_theta == 0.0:
- dx = w
- dy = 0.0
- elif cos_theta == 0.0:
- dx = 0.0
- dy = h
- else:
- tan_theta = sin_theta / cos_theta
- dx = w
- dy = w * tan_theta
- if dy > h or dy < -h:
- dy = h
- dx = h / tan_theta
- cwd = np.array([dx, dy]) / 2
- cwd *= 1 + dashpad / np.sqrt(np.dot(cwd, cwd))
- cw = c2 + (dashdirection * 2 - 1) * cwd
-
- newx, newy = inverse.transform_point(tuple(cw))
- self._x, self._y = newx, newy
-
- # Now set the window extent
- # I'm not at all sure this is the right way to do this.
- we = Text.get_window_extent(self, renderer=renderer)
- self._twd_window_extent = we.frozen()
- self._twd_window_extent.update_from_data_xy(np.array([c1]), False)
-
- # Finally, make text align center
- Text.set_horizontalalignment(self, 'center')
- Text.set_verticalalignment(self, 'center')
-
- def get_window_extent(self, renderer=None):
- '''
- Return a :class:`~matplotlib.transforms.Bbox` object bounding
- the text, in display units.
-
- In addition to being used internally, this is useful for
- specifying clickable regions in a png file on a web page.
-
- *renderer* defaults to the _renderer attribute of the text
- object. This is not assigned until the first execution of
- :meth:`draw`, so you must use this kwarg if you want
- to call :meth:`get_window_extent` prior to the first
- :meth:`draw`. For getting web page regions, it is
- simpler to call the method after saving the figure.
- '''
- self.update_coords(renderer)
- if self.get_dashlength() == 0.0:
- return Text.get_window_extent(self, renderer=renderer)
- else:
- return self._twd_window_extent
-
- def get_dashlength(self):
- """
- Get the length of the dash.
- """
- return self._dashlength
-
- def set_dashlength(self, dl):
- """
- Set the length of the dash.
-
- ACCEPTS: float (canvas units)
- """
- self._dashlength = dl
- self.stale = True
-
- def get_dashdirection(self):
- """
- Get the direction dash. 1 is before the text and 0 is after.
- """
- return self._dashdirection
-
- def set_dashdirection(self, dd):
- """
- Set the direction of the dash following the text.
- 1 is before the text and 0 is after. The default
- is 0, which is what you'd want for the typical
- case of ticks below and on the left of the figure.
-
- ACCEPTS: int (1 is before, 0 is after)
- """
- self._dashdirection = dd
- self.stale = True
-
- def get_dashrotation(self):
- """
- Get the rotation of the dash in degrees.
- """
- if self._dashrotation is None:
- return self.get_rotation()
- else:
- return self._dashrotation
-
- def set_dashrotation(self, dr):
- """
- Set the rotation of the dash, in degrees
-
- ACCEPTS: float (degrees)
- """
- self._dashrotation = dr
- self.stale = True
-
- def get_dashpad(self):
- """
- Get the extra spacing between the dash and the text, in canvas units.
- """
- return self._dashpad
-
- def set_dashpad(self, dp):
- """
- Set the "pad" of the TextWithDash, which is the extra spacing
- between the dash and the text, in canvas units.
-
- ACCEPTS: float (canvas units)
- """
- self._dashpad = dp
- self.stale = True
-
- def get_dashpush(self):
- """
- Get the extra spacing between the dash and the specified text
- position, in canvas units.
- """
- return self._dashpush
-
- def set_dashpush(self, dp):
- """
- Set the "push" of the TextWithDash, which
- is the extra spacing between the beginning
- of the dash and the specified position.
-
- ACCEPTS: float (canvas units)
- """
- self._dashpush = dp
- self.stale = True
-
- def set_position(self, xy):
- """
- Set the (*x*, *y*) position of the :class:`TextWithDash`.
-
- ACCEPTS: (x, y)
- """
- self.set_x(xy[0])
- self.set_y(xy[1])
-
- def set_x(self, x):
- """
- Set the *x* position of the :class:`TextWithDash`.
-
- ACCEPTS: float
- """
- self._dashx = float(x)
- self.stale = True
-
- def set_y(self, y):
- """
- Set the *y* position of the :class:`TextWithDash`.
-
- ACCEPTS: float
- """
- self._dashy = float(y)
- self.stale = True
-
- def set_transform(self, t):
- """
- Set the :class:`matplotlib.transforms.Transform` instance used
- by this artist.
-
- ACCEPTS: a :class:`matplotlib.transforms.Transform` instance
- """
- Text.set_transform(self, t)
- self.dashline.set_transform(t)
- self.stale = True
-
- def get_figure(self):
- 'return the figure instance the artist belongs to'
- return self.figure
-
- def set_figure(self, fig):
- """
- Set the figure instance the artist belong to.
-
- ACCEPTS: a :class:`matplotlib.figure.Figure` instance
- """
- Text.set_figure(self, fig)
- self.dashline.set_figure(fig)
-
-docstring.interpd.update(TextWithDash=artist.kwdoc(TextWithDash))
-
-
-class OffsetFrom(object):
- 'Callable helper class for working with `Annotation`'
- def __init__(self, artist, ref_coord, unit="points"):
- '''
- Parameters
- ----------
- artist : `Artist`, `BboxBase`, or `Transform`
- The object to compute the offset from.
-
- ref_coord : length 2 sequence
- If `artist` is an `Artist` or `BboxBase`, this values is
- the location to of the offset origin in fractions of the
- `artist` bounding box.
-
- If `artist` is a transform, the offset origin is the
- transform applied to this value.
-
- unit : {'points, 'pixels'}
- The screen units to use (pixels or points) for the offset
- input.
-
- '''
- self._artist = artist
- self._ref_coord = ref_coord
- self.set_unit(unit)
-
- def set_unit(self, unit):
- '''
- The unit for input to the transform used by ``__call__``
-
- Parameters
- ----------
- unit : {'points', 'pixels'}
- '''
- if unit not in ["points", "pixels"]:
- raise ValueError("'unit' must be one of [ 'points' | 'pixels' ]")
- self._unit = unit
-
- def get_unit(self):
- 'The unit for input to the transform used by ``__call__``'
- return self._unit
-
- def _get_scale(self, renderer):
- unit = self.get_unit()
- if unit == "pixels":
- return 1.
- else:
- return renderer.points_to_pixels(1.)
-
- def __call__(self, renderer):
- '''
- Return the offset transform.
-
- Parameters
- ----------
- renderer : `RendererBase`
- The renderer to use to compute the offset
-
- Returns
- -------
- transform : `Transform`
- Maps (x, y) in pixel or point units to screen units
- relative to the given artist.
- '''
- if isinstance(self._artist, Artist):
- bbox = self._artist.get_window_extent(renderer)
- l, b, w, h = bbox.bounds
- xf, yf = self._ref_coord
- x, y = l + w * xf, b + h * yf
- elif isinstance(self._artist, BboxBase):
- l, b, w, h = self._artist.bounds
- xf, yf = self._ref_coord
- x, y = l + w * xf, b + h * yf
- elif isinstance(self._artist, Transform):
- x, y = self._artist.transform_point(self._ref_coord)
- else:
- raise RuntimeError("unknown type")
-
- sc = self._get_scale(renderer)
- tr = Affine2D().scale(sc, sc).translate(x, y)
-
- return tr
-
-
-class _AnnotationBase(object):
- def __init__(self,
- xy,
- xycoords='data',
- annotation_clip=None):
-
- self.xy = xy
- self.xycoords = xycoords
- self.set_annotation_clip(annotation_clip)
-
- self._draggable = None
-
- def _get_xy(self, renderer, x, y, s):
- if isinstance(s, tuple):
- s1, s2 = s
- else:
- s1, s2 = s, s
-
- if s1 == 'data':
- x = float(self.convert_xunits(x))
- if s2 == 'data':
- y = float(self.convert_yunits(y))
-
- tr = self._get_xy_transform(renderer, s)
- x1, y1 = tr.transform_point((x, y))
- return x1, y1
-
- def _get_xy_transform(self, renderer, s):
-
- if isinstance(s, tuple):
- s1, s2 = s
- from matplotlib.transforms import blended_transform_factory
- tr1 = self._get_xy_transform(renderer, s1)
- tr2 = self._get_xy_transform(renderer, s2)
- tr = blended_transform_factory(tr1, tr2)
- return tr
- elif callable(s):
- tr = s(renderer)
- if isinstance(tr, BboxBase):
- return BboxTransformTo(tr)
- elif isinstance(tr, Transform):
- return tr
- else:
- raise RuntimeError("unknown return type ...")
- elif isinstance(s, Artist):
- bbox = s.get_window_extent(renderer)
- return BboxTransformTo(bbox)
- elif isinstance(s, BboxBase):
- return BboxTransformTo(s)
- elif isinstance(s, Transform):
- return s
- elif not isinstance(s, six.string_types):
- raise RuntimeError("unknown coordinate type : %s" % (s,))
-
- if s == 'data':
- return self.axes.transData
- elif s == 'polar':
- from matplotlib.projections import PolarAxes
- tr = PolarAxes.PolarTransform()
- trans = tr + self.axes.transData
- return trans
-
- s_ = s.split()
- if len(s_) != 2:
- raise ValueError("%s is not a recognized coordinate" % s)
-
- bbox0, xy0 = None, None
-
- bbox_name, unit = s_
- # if unit is offset-like
- if bbox_name == "figure":
- bbox0 = self.figure.bbox
- elif bbox_name == "axes":
- bbox0 = self.axes.bbox
- # elif bbox_name == "bbox":
- # if bbox is None:
- # raise RuntimeError("bbox is specified as a coordinate but "
- # "never set")
- # bbox0 = self._get_bbox(renderer, bbox)
-
- if bbox0 is not None:
- xy0 = bbox0.bounds[:2]
- elif bbox_name == "offset":
- xy0 = self._get_ref_xy(renderer)
-
- if xy0 is not None:
- # reference x, y in display coordinate
- ref_x, ref_y = xy0
- from matplotlib.transforms import Affine2D
- if unit == "points":
- # dots per points
- dpp = self.figure.get_dpi() / 72.
- tr = Affine2D().scale(dpp, dpp)
- elif unit == "pixels":
- tr = Affine2D()
- elif unit == "fontsize":
- fontsize = self.get_size()
- dpp = fontsize * self.figure.get_dpi() / 72.
- tr = Affine2D().scale(dpp, dpp)
- elif unit == "fraction":
- w, h = bbox0.bounds[2:]
- tr = Affine2D().scale(w, h)
- else:
- raise ValueError("%s is not a recognized coordinate" % s)
-
- return tr.translate(ref_x, ref_y)
-
- else:
- raise ValueError("%s is not a recognized coordinate" % s)
-
- def _get_ref_xy(self, renderer):
- """
- return x, y (in display coordinate) that is to be used for a reference
- of any offset coordinate
- """
-
- if isinstance(self.xycoords, tuple):
- s1, s2 = self.xycoords
- if ((isinstance(s1, six.string_types)
- and s1.split()[0] == "offset")
- or (isinstance(s2, six.string_types)
- and s2.split()[0] == "offset")):
- raise ValueError("xycoords should not be an offset coordinate")
- x, y = self.xy
- x1, y1 = self._get_xy(renderer, x, y, s1)
- x2, y2 = self._get_xy(renderer, x, y, s2)
- return x1, y2
- elif (isinstance(self.xycoords, six.string_types) and
- self.xycoords.split()[0] == "offset"):
- raise ValueError("xycoords should not be an offset coordinate")
- else:
- x, y = self.xy
- return self._get_xy(renderer, x, y, self.xycoords)
- #raise RuntimeError("must be defined by the derived class")
-
- # def _get_bbox(self, renderer):
- # if hasattr(bbox, "bounds"):
- # return bbox
- # elif hasattr(bbox, "get_window_extent"):
- # bbox = bbox.get_window_extent()
- # return bbox
- # else:
- # raise ValueError("A bbox instance is expected but got %s" %
- # str(bbox))
-
- def set_annotation_clip(self, b):
- """
- set *annotation_clip* attribute.
-
- * True: the annotation will only be drawn when self.xy is inside
- the axes.
- * False: the annotation will always be drawn regardless of its
- position.
- * None: the self.xy will be checked only if *xycoords* is "data"
- """
- self._annotation_clip = b
-
- def get_annotation_clip(self):
- """
- Return *annotation_clip* attribute.
- See :meth:`set_annotation_clip` for the meaning of return values.
- """
- return self._annotation_clip
-
- def _get_position_xy(self, renderer):
- "Return the pixel position of the annotated point."
- x, y = self.xy
- return self._get_xy(renderer, x, y, self.xycoords)
-
- def _check_xy(self, renderer, xy_pixel):
- """
- given the xy pixel coordinate, check if the annotation need to
- be drawn.
- """
-
- b = self.get_annotation_clip()
-
- if b or (b is None and self.xycoords == "data"):
- # check if self.xy is inside the axes.
- if not self.axes.contains_point(xy_pixel):
- return False
-
- return True
-
- def draggable(self, state=None, use_blit=False):
- """
- Set the draggable state -- if state is
-
- * None : toggle the current state
-
- * True : turn draggable on
-
- * False : turn draggable off
-
- If draggable is on, you can drag the annotation on the canvas with
- the mouse. The DraggableAnnotation helper instance is returned if
- draggable is on.
- """
- from matplotlib.offsetbox import DraggableAnnotation
- is_draggable = self._draggable is not None
-
- # if state is None we'll toggle
- if state is None:
- state = not is_draggable
-
- if state:
- if self._draggable is None:
- self._draggable = DraggableAnnotation(self, use_blit)
- else:
- if self._draggable is not None:
- self._draggable.disconnect()
- self._draggable = None
-
- return self._draggable
-
-
-class Annotation(Text, _AnnotationBase):
- def __str__(self):
- return "Annotation(%g,%g,%s)" % (self.xy[0],
- self.xy[1],
- repr(self._text))
-
- @docstring.dedent_interpd
- def __init__(self, s, xy,
- xytext=None,
- xycoords='data',
- textcoords=None,
- arrowprops=None,
- annotation_clip=None,
- **kwargs):
- '''
- Annotate the point ``xy`` with text ``s``.
-
- Additional kwargs are passed to `~matplotlib.text.Text`.
-
- Parameters
- ----------
-
- s : str
- The text of the annotation
-
- xy : iterable
- Length 2 sequence specifying the *(x,y)* point to annotate
-
- xytext : iterable, optional
- Length 2 sequence specifying the *(x,y)* to place the text
- at. If None, defaults to ``xy``.
-
- xycoords : str, Artist, Transform, callable or tuple, optional
-
- The coordinate system that ``xy`` is given in.
-
- For a `str` the allowed values are:
-
- ================= ===============================================
- Property Description
- ================= ===============================================
- 'figure points' points from the lower left of the figure
- 'figure pixels' pixels from the lower left of the figure
- 'figure fraction' fraction of figure from lower left
- 'axes points' points from lower left corner of axes
- 'axes pixels' pixels from lower left corner of axes
- 'axes fraction' fraction of axes from lower left
- 'data' use the coordinate system of the object being
- annotated (default)
- 'polar' *(theta,r)* if not native 'data' coordinates
- ================= ===============================================
-
- If a `~matplotlib.artist.Artist` object is passed in the units are
- fraction if it's bounding box.
-
- If a `~matplotlib.transforms.Transform` object is passed
- in use that to transform ``xy`` to screen coordinates
-
- If a callable it must take a
- `~matplotlib.backend_bases.RendererBase` object as input
- and return a `~matplotlib.transforms.Transform` or
- `~matplotlib.transforms.Bbox` object
-
- If a `tuple` must be length 2 tuple of str, `Artist`,
- `Transform` or callable objects. The first transform is
- used for the *x* coordinate and the second for *y*.
-
- See :ref:`plotting-guide-annotation` for more details.
-
- Defaults to ``'data'``
-
- textcoords : str, `Artist`, `Transform`, callable or tuple, optional
- The coordinate system that ``xytext`` is given, which
- may be different than the coordinate system used for
- ``xy``.
-
- All ``xycoords`` values are valid as well as the following
- strings:
-
- ================= =========================================
- Property Description
- ================= =========================================
- 'offset points' offset (in points) from the *xy* value
- 'offset pixels' offset (in pixels) from the *xy* value
- ================= =========================================
-
- defaults to the input of ``xycoords``
-
- arrowprops : dict, optional
- If not None, properties used to draw a
- `~matplotlib.patches.FancyArrowPatch` arrow between ``xy`` and
- ``xytext``.
-
- If `arrowprops` does not contain the key ``'arrowstyle'`` the
- allowed keys are:
-
- ========== ======================================================
- Key Description
- ========== ======================================================
- width the width of the arrow in points
- headwidth the width of the base of the arrow head in points
- headlength the length of the arrow head in points
- shrink fraction of total length to 'shrink' from both ends
- ? any key to :class:`matplotlib.patches.FancyArrowPatch`
- ========== ======================================================
-
- If the `arrowprops` contains the key ``'arrowstyle'`` the
- above keys are forbidden. The allowed values of
- ``'arrowstyle'`` are:
-
- ============ =============================================
- Name Attrs
- ============ =============================================
- ``'-'`` None
- ``'->'`` head_length=0.4,head_width=0.2
- ``'-['`` widthB=1.0,lengthB=0.2,angleB=None
- ``'|-|'`` widthA=1.0,widthB=1.0
- ``'-|>'`` head_length=0.4,head_width=0.2
- ``'<-'`` head_length=0.4,head_width=0.2
- ``'<->'`` head_length=0.4,head_width=0.2
- ``'<|-'`` head_length=0.4,head_width=0.2
- ``'<|-|>'`` head_length=0.4,head_width=0.2
- ``'fancy'`` head_length=0.4,head_width=0.4,tail_width=0.4
- ``'simple'`` head_length=0.5,head_width=0.5,tail_width=0.2
- ``'wedge'`` tail_width=0.3,shrink_factor=0.5
- ============ =============================================
-
- Valid keys for `~matplotlib.patches.FancyArrowPatch` are:
-
- =============== ==================================================
- Key Description
- =============== ==================================================
- arrowstyle the arrow style
- connectionstyle the connection style
- relpos default is (0.5, 0.5)
- patchA default is bounding box of the text
- patchB default is None
- shrinkA default is 2 points
- shrinkB default is 2 points
- mutation_scale default is text size (in points)
- mutation_aspect default is 1.
- ? any key for :class:`matplotlib.patches.PathPatch`
- =============== ==================================================
-
- Defaults to None
-
- annotation_clip : bool, optional
- Controls the visibility of the annotation when it goes
- outside the axes area.
-
- If `True`, the annotation will only be drawn when the
- ``xy`` is inside the axes. If `False`, the annotation will
- always be drawn regardless of its position.
-
- The default is `None`, which behave as `True` only if
- *xycoords* is "data".
-
- Returns
- -------
- Annotation
-
- '''
-
- _AnnotationBase.__init__(self,
- xy,
- xycoords=xycoords,
- annotation_clip=annotation_clip)
- # warn about wonky input data
- if (xytext is None and
- textcoords is not None and
- textcoords != xycoords):
- warnings.warn("You have used the `textcoords` kwarg, but not "
- "the `xytext` kwarg. This can lead to surprising "
- "results.")
-
- # clean up textcoords and assign default
- if textcoords is None:
- textcoords = self.xycoords
- self._textcoords = textcoords
-
- # cleanup xytext defaults
- if xytext is None:
- xytext = self.xy
- x, y = xytext
-
- Text.__init__(self, x, y, s, **kwargs)
-
- self.arrowprops = arrowprops
-
- self.arrow = None
-
- if arrowprops is not None:
- if "arrowstyle" in arrowprops:
- arrowprops = self.arrowprops.copy()
- self._arrow_relpos = arrowprops.pop("relpos", (0.5, 0.5))
- else:
- # modified YAArrow API to be used with FancyArrowPatch
- shapekeys = ('width', 'headwidth', 'headlength',
- 'shrink', 'frac')
- arrowprops = dict()
- for key, val in self.arrowprops.items():
- if key not in shapekeys:
- arrowprops[key] = val # basic Patch properties
- self.arrow_patch = FancyArrowPatch((0, 0), (1, 1),
- **arrowprops)
- else:
- self.arrow_patch = None
-
- def contains(self, event):
- contains, tinfo = Text.contains(self, event)
- if self.arrow is not None:
- in_arrow, _ = self.arrow.contains(event)
- contains = contains or in_arrow
- if self.arrow_patch is not None:
- in_patch, _ = self.arrow_patch.contains(event)
- contains = contains or in_patch
-
- return contains, tinfo
-
- @property
- def xyann(self):
- return self.get_position()
-
- @xyann.setter
- def xyann(self, xytext):
- self.set_position(xytext)
-
- @property
- def anncoords(self):
- return self._textcoords
-
- @anncoords.setter
- def anncoords(self, coords):
- self._textcoords = coords
-
- def set_figure(self, fig):
-
- if self.arrow is not None:
- self.arrow.set_figure(fig)
- if self.arrow_patch is not None:
- self.arrow_patch.set_figure(fig)
- Artist.set_figure(self, fig)
-
- def update_positions(self, renderer):
- """"Update the pixel positions of the annotated point and the
- text.
- """
- xy_pixel = self._get_position_xy(renderer)
- self._update_position_xytext(renderer, xy_pixel)
-
- def _update_position_xytext(self, renderer, xy_pixel):
- """Update the pixel positions of the annotation text and the arrow
- patch.
- """
- # generate transformation,
- self.set_transform(self._get_xy_transform(renderer, self.anncoords))
-
- ox0, oy0 = self._get_xy_display()
- ox1, oy1 = xy_pixel
-
- if self.arrowprops is not None:
- x0, y0 = xy_pixel
- l, b, w, h = Text.get_window_extent(self, renderer).bounds
- r = l + w
- t = b + h
- xc = 0.5 * (l + r)
- yc = 0.5 * (b + t)
-
- d = self.arrowprops.copy()
- ms = d.pop("mutation_scale", self.get_size())
- self.arrow_patch.set_mutation_scale(ms)
-
- if "arrowstyle" not in d:
- # Approximately simulate the YAArrow.
- # Pop its kwargs:
- shrink = d.pop('shrink', 0.0)
- width = d.pop('width', 4)
- headwidth = d.pop('headwidth', 12)
- # Ignore frac--it is useless.
- frac = d.pop('frac', None)
- if frac is not None:
- warnings.warn(
- "'frac' option in 'arrowprops' is no longer supported;"
- " use 'headlength' to set the head length in points.")
- headlength = d.pop('headlength', 12)
-
- # NB: ms is in pts
- stylekw = dict(head_length=headlength / ms,
- head_width=headwidth / ms,
- tail_width=width / ms)
-
- self.arrow_patch.set_arrowstyle('simple', **stylekw)
-
- # using YAArrow style:
- # pick the x,y corner of the text bbox closest to point
- # annotated
- xpos = ((l, 0), (xc, 0.5), (r, 1))
- ypos = ((b, 0), (yc, 0.5), (t, 1))
-
- _, (x, relposx) = min((abs(val[0] - x0), val) for val in xpos)
- _, (y, relposy) = min((abs(val[0] - y0), val) for val in ypos)
-
- self._arrow_relpos = (relposx, relposy)
-
- r = np.hypot((y - y0), (x - x0))
- shrink_pts = shrink * r / renderer.points_to_pixels(1)
- self.arrow_patch.shrinkA = shrink_pts
- self.arrow_patch.shrinkB = shrink_pts
-
- # adjust the starting point of the arrow relative to
- # the textbox.
- # TODO : Rotation needs to be accounted.
- relpos = self._arrow_relpos
- bbox = Text.get_window_extent(self, renderer)
- ox0 = bbox.x0 + bbox.width * relpos[0]
- oy0 = bbox.y0 + bbox.height * relpos[1]
-
- # The arrow will be drawn from (ox0, oy0) to (ox1,
- # oy1). It will be first clipped by patchA and patchB.
- # Then it will be shrunk by shrinkA and shrinkB
- # (in points). If patch A is not set, self.bbox_patch
- # is used.
-
- self.arrow_patch.set_positions((ox0, oy0), (ox1, oy1))
-
- if "patchA" in d:
- self.arrow_patch.set_patchA(d.pop("patchA"))
- else:
- if self._bbox_patch:
- self.arrow_patch.set_patchA(self._bbox_patch)
- else:
- pad = renderer.points_to_pixels(4)
- if self.get_text() == "":
- self.arrow_patch.set_patchA(None)
- return
-
- bbox = Text.get_window_extent(self, renderer)
- l, b, w, h = bbox.bounds
- l -= pad / 2.
- b -= pad / 2.
- w += pad
- h += pad
- r = Rectangle(xy=(l, b),
- width=w,
- height=h,
- )
- r.set_transform(IdentityTransform())
- r.set_clip_on(False)
-
- self.arrow_patch.set_patchA(r)
-
- @artist.allow_rasterization
- def draw(self, renderer):
- """
- Draw the :class:`Annotation` object to the given *renderer*.
- """
-
- if renderer is not None:
- self._renderer = renderer
- if not self.get_visible():
- return
-
- xy_pixel = self._get_position_xy(renderer)
- if not self._check_xy(renderer, xy_pixel):
- return
-
- self._update_position_xytext(renderer, xy_pixel)
- self.update_bbox_position_size(renderer)
-
- if self.arrow_patch is not None: # FancyArrowPatch
- if self.arrow_patch.figure is None and self.figure is not None:
- self.arrow_patch.figure = self.figure
- self.arrow_patch.draw(renderer)
-
- # Draw text, including FancyBboxPatch, after FancyArrowPatch.
- # Otherwise, a wedge arrowstyle can land partly on top of the Bbox.
- Text.draw(self, renderer)
-
- def get_window_extent(self, renderer=None):
- '''
- Return a :class:`~matplotlib.transforms.Bbox` object bounding
- the text and arrow annotation, in display units.
-
- *renderer* defaults to the _renderer attribute of the text
- object. This is not assigned until the first execution of
- :meth:`draw`, so you must use this kwarg if you want
- to call :meth:`get_window_extent` prior to the first
- :meth:`draw`. For getting web page regions, it is
- simpler to call the method after saving the figure. The
- *dpi* used defaults to self.figure.dpi; the renderer dpi is
- irrelevant.
-
- '''
- if not self.get_visible():
- return Bbox.unit()
- arrow = self.arrow
- arrow_patch = self.arrow_patch
-
- text_bbox = Text.get_window_extent(self, renderer=renderer)
- bboxes = [text_bbox]
-
- if self.arrow is not None:
- bboxes.append(arrow.get_window_extent(renderer=renderer))
- elif self.arrow_patch is not None:
- bboxes.append(arrow_patch.get_window_extent(renderer=renderer))
-
- return Bbox.union(bboxes)
-
-
-docstring.interpd.update(Annotation=Annotation.__init__.__doc__)
diff --git a/contrib/python/matplotlib/py2/matplotlib/textpath.py b/contrib/python/matplotlib/py2/matplotlib/textpath.py
deleted file mode 100644
index 5ee3567742..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/textpath.py
+++ /dev/null
@@ -1,536 +0,0 @@
-# -*- coding: utf-8 -*-
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from collections import OrderedDict
-
-import six
-from six.moves import zip
-
-import warnings
-
-import numpy as np
-
-from matplotlib.path import Path
-from matplotlib import rcParams
-import matplotlib.font_manager as font_manager
-from matplotlib.ft2font import KERNING_DEFAULT, LOAD_NO_HINTING
-from matplotlib.ft2font import LOAD_TARGET_LIGHT
-from matplotlib.mathtext import MathTextParser
-import matplotlib.dviread as dviread
-from matplotlib.font_manager import FontProperties, get_font
-from matplotlib.transforms import Affine2D
-from six.moves.urllib.parse import quote as urllib_quote
-
-
-class TextToPath(object):
- """
- A class that convert a given text to a path using ttf fonts.
- """
-
- FONT_SCALE = 100.
- DPI = 72
-
- def __init__(self):
- """
- Initialization
- """
- self.mathtext_parser = MathTextParser('path')
- self.tex_font_map = None
-
- from matplotlib.cbook import maxdict
- self._ps_fontd = maxdict(50)
-
- self._texmanager = None
-
- self._adobe_standard_encoding = None
-
- def _get_adobe_standard_encoding(self):
- enc_name = dviread.find_tex_file('8a.enc')
- enc = dviread.Encoding(enc_name)
- return {c: i for i, c in enumerate(enc.encoding)}
-
- def _get_font(self, prop):
- """
- find a ttf font.
- """
- fname = font_manager.findfont(prop)
- font = get_font(fname)
- font.set_size(self.FONT_SCALE, self.DPI)
-
- return font
-
- def _get_hinting_flag(self):
- return LOAD_NO_HINTING
-
- def _get_char_id(self, font, ccode):
- """
- Return a unique id for the given font and character-code set.
- """
- sfnt = font.get_sfnt()
- try:
- ps_name = sfnt[1, 0, 0, 6].decode('mac_roman')
- except KeyError:
- ps_name = sfnt[3, 1, 0x0409, 6].decode('utf-16be')
- char_id = urllib_quote('%s-%x' % (ps_name, ccode))
- return char_id
-
- def _get_char_id_ps(self, font, ccode):
- """
- Return a unique id for the given font and character-code set (for tex).
- """
- ps_name = font.get_ps_font_info()[2]
- char_id = urllib_quote('%s-%d' % (ps_name, ccode))
- return char_id
-
- def glyph_to_path(self, font, currx=0.):
- """
- convert the ft2font glyph to vertices and codes.
- """
- verts, codes = font.get_path()
- if currx != 0.0:
- verts[:, 0] += currx
- return verts, codes
-
- def get_text_width_height_descent(self, s, prop, ismath):
- if rcParams['text.usetex']:
- texmanager = self.get_texmanager()
- fontsize = prop.get_size_in_points()
- w, h, d = texmanager.get_text_width_height_descent(s, fontsize,
- renderer=None)
- return w, h, d
-
- fontsize = prop.get_size_in_points()
- scale = fontsize / self.FONT_SCALE
-
- if ismath:
- prop = prop.copy()
- prop.set_size(self.FONT_SCALE)
-
- width, height, descent, trash, used_characters = \
- self.mathtext_parser.parse(s, 72, prop)
- return width * scale, height * scale, descent * scale
-
- font = self._get_font(prop)
- font.set_text(s, 0.0, flags=LOAD_NO_HINTING)
- w, h = font.get_width_height()
- w /= 64.0 # convert from subpixels
- h /= 64.0
- d = font.get_descent()
- d /= 64.0
- return w * scale, h * scale, d * scale
-
- def get_text_path(self, prop, s, ismath=False, usetex=False):
- """
- convert text *s* to path (a tuple of vertices and codes for
- matplotlib.path.Path).
-
- *prop*
- font property
-
- *s*
- text to be converted
-
- *usetex*
- If True, use matplotlib usetex mode.
-
- *ismath*
- If True, use mathtext parser. Effective only if usetex == False.
-
-
- """
- if not usetex:
- if not ismath:
- font = self._get_font(prop)
- glyph_info, glyph_map, rects = self.get_glyphs_with_font(
- font, s)
- else:
- glyph_info, glyph_map, rects = self.get_glyphs_mathtext(
- prop, s)
- else:
- glyph_info, glyph_map, rects = self.get_glyphs_tex(prop, s)
-
- verts, codes = [], []
-
- for glyph_id, xposition, yposition, scale in glyph_info:
- verts1, codes1 = glyph_map[glyph_id]
- if len(verts1):
- verts1 = np.array(verts1) * scale + [xposition, yposition]
- verts.extend(verts1)
- codes.extend(codes1)
-
- for verts1, codes1 in rects:
- verts.extend(verts1)
- codes.extend(codes1)
-
- return verts, codes
-
- def get_glyphs_with_font(self, font, s, glyph_map=None,
- return_new_glyphs_only=False):
- """
- convert the string *s* to vertices and codes using the
- provided ttf font.
- """
-
- # Mostly copied from backend_svg.py.
-
- lastgind = None
-
- currx = 0
- xpositions = []
- glyph_ids = []
-
- if glyph_map is None:
- glyph_map = OrderedDict()
-
- if return_new_glyphs_only:
- glyph_map_new = OrderedDict()
- else:
- glyph_map_new = glyph_map
-
- # I'm not sure if I get kernings right. Needs to be verified. -JJL
-
- for c in s:
- ccode = ord(c)
- gind = font.get_char_index(ccode)
- if gind is None:
- ccode = ord('?')
- gind = 0
-
- if lastgind is not None:
- kern = font.get_kerning(lastgind, gind, KERNING_DEFAULT)
- else:
- kern = 0
-
- glyph = font.load_char(ccode, flags=LOAD_NO_HINTING)
- horiz_advance = (glyph.linearHoriAdvance / 65536.0)
-
- char_id = self._get_char_id(font, ccode)
- if char_id not in glyph_map:
- glyph_map_new[char_id] = self.glyph_to_path(font)
-
- currx += (kern / 64.0)
-
- xpositions.append(currx)
- glyph_ids.append(char_id)
-
- currx += horiz_advance
-
- lastgind = gind
-
- ypositions = [0] * len(xpositions)
- sizes = [1.] * len(xpositions)
-
- rects = []
-
- return (list(zip(glyph_ids, xpositions, ypositions, sizes)),
- glyph_map_new, rects)
-
- def get_glyphs_mathtext(self, prop, s, glyph_map=None,
- return_new_glyphs_only=False):
- """
- convert the string *s* to vertices and codes by parsing it with
- mathtext.
- """
-
- prop = prop.copy()
- prop.set_size(self.FONT_SCALE)
-
- width, height, descent, glyphs, rects = self.mathtext_parser.parse(
- s, self.DPI, prop)
-
- if not glyph_map:
- glyph_map = OrderedDict()
-
- if return_new_glyphs_only:
- glyph_map_new = OrderedDict()
- else:
- glyph_map_new = glyph_map
-
- xpositions = []
- ypositions = []
- glyph_ids = []
- sizes = []
-
- currx, curry = 0, 0
- for font, fontsize, ccode, ox, oy in glyphs:
- char_id = self._get_char_id(font, ccode)
- if char_id not in glyph_map:
- font.clear()
- font.set_size(self.FONT_SCALE, self.DPI)
- glyph = font.load_char(ccode, flags=LOAD_NO_HINTING)
- glyph_map_new[char_id] = self.glyph_to_path(font)
-
- xpositions.append(ox)
- ypositions.append(oy)
- glyph_ids.append(char_id)
- size = fontsize / self.FONT_SCALE
- sizes.append(size)
-
- myrects = []
- for ox, oy, w, h in rects:
- vert1 = [(ox, oy), (ox, oy + h), (ox + w, oy + h),
- (ox + w, oy), (ox, oy), (0, 0)]
- code1 = [Path.MOVETO,
- Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO,
- Path.CLOSEPOLY]
- myrects.append((vert1, code1))
-
- return (list(zip(glyph_ids, xpositions, ypositions, sizes)),
- glyph_map_new, myrects)
-
- def get_texmanager(self):
- """
- return the :class:`matplotlib.texmanager.TexManager` instance
- """
- if self._texmanager is None:
- from matplotlib.texmanager import TexManager
- self._texmanager = TexManager()
- return self._texmanager
-
- def get_glyphs_tex(self, prop, s, glyph_map=None,
- return_new_glyphs_only=False):
- """
- convert the string *s* to vertices and codes using matplotlib's usetex
- mode.
- """
-
- # codes are modstly borrowed from pdf backend.
-
- texmanager = self.get_texmanager()
-
- if self.tex_font_map is None:
- self.tex_font_map = dviread.PsfontsMap(
- dviread.find_tex_file('pdftex.map'))
-
- if self._adobe_standard_encoding is None:
- self._adobe_standard_encoding = self._get_adobe_standard_encoding()
-
- fontsize = prop.get_size_in_points()
- if hasattr(texmanager, "get_dvi"):
- dvifilelike = texmanager.get_dvi(s, self.FONT_SCALE)
- dvi = dviread.DviFromFileLike(dvifilelike, self.DPI)
- else:
- dvifile = texmanager.make_dvi(s, self.FONT_SCALE)
- dvi = dviread.Dvi(dvifile, self.DPI)
- with dvi:
- page = next(iter(dvi))
-
- if glyph_map is None:
- glyph_map = OrderedDict()
-
- if return_new_glyphs_only:
- glyph_map_new = OrderedDict()
- else:
- glyph_map_new = glyph_map
-
- glyph_ids, xpositions, ypositions, sizes = [], [], [], []
-
- # Gather font information and do some setup for combining
- # characters into strings.
- # oldfont, seq = None, []
- for x1, y1, dvifont, glyph, width in page.text:
- font_and_encoding = self._ps_fontd.get(dvifont.texname)
- font_bunch = self.tex_font_map[dvifont.texname]
-
- if font_and_encoding is None:
- if font_bunch.filename is None:
- raise ValueError(
- ("No usable font file found for %s (%s). "
- "The font may lack a Type-1 version.")
- % (font_bunch.psname, dvifont.texname))
-
- font = get_font(font_bunch.filename)
-
- for charmap_name, charmap_code in [("ADOBE_CUSTOM",
- 1094992451),
- ("ADOBE_STANDARD",
- 1094995778)]:
- try:
- font.select_charmap(charmap_code)
- except (ValueError, RuntimeError):
- pass
- else:
- break
- else:
- charmap_name = ""
- warnings.warn("No supported encoding in font (%s)." %
- font_bunch.filename)
-
- if charmap_name == "ADOBE_STANDARD" and font_bunch.encoding:
- enc0 = dviread.Encoding(font_bunch.encoding)
- enc = {i: self._adobe_standard_encoding.get(c, None)
- for i, c in enumerate(enc0.encoding)}
- else:
- enc = {}
- self._ps_fontd[dvifont.texname] = font, enc
-
- else:
- font, enc = font_and_encoding
-
- ft2font_flag = LOAD_TARGET_LIGHT
-
- char_id = self._get_char_id_ps(font, glyph)
-
- if char_id not in glyph_map:
- font.clear()
- font.set_size(self.FONT_SCALE, self.DPI)
- if enc:
- charcode = enc.get(glyph, None)
- else:
- charcode = glyph
-
- if charcode is not None:
- glyph0 = font.load_char(charcode, flags=ft2font_flag)
- else:
- warnings.warn("The glyph (%d) of font (%s) cannot be "
- "converted with the encoding. Glyph may "
- "be wrong" % (glyph, font_bunch.filename))
-
- glyph0 = font.load_char(glyph, flags=ft2font_flag)
-
- glyph_map_new[char_id] = self.glyph_to_path(font)
-
- glyph_ids.append(char_id)
- xpositions.append(x1)
- ypositions.append(y1)
- sizes.append(dvifont.size / self.FONT_SCALE)
-
- myrects = []
-
- for ox, oy, h, w in page.boxes:
- vert1 = [(ox, oy), (ox + w, oy), (ox + w, oy + h),
- (ox, oy + h), (ox, oy), (0, 0)]
- code1 = [Path.MOVETO,
- Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO,
- Path.CLOSEPOLY]
- myrects.append((vert1, code1))
-
- return (list(zip(glyph_ids, xpositions, ypositions, sizes)),
- glyph_map_new, myrects)
-
-
-text_to_path = TextToPath()
-
-
-class TextPath(Path):
- """
- Create a path from the text.
- """
-
- def __init__(self, xy, s, size=None, prop=None,
- _interpolation_steps=1, usetex=False,
- *kl, **kwargs):
- """
- Create a path from the text. No support for TeX yet. Note that
- it simply is a path, not an artist. You need to use the
- PathPatch (or other artists) to draw this path onto the
- canvas.
-
- xy : position of the text.
- s : text
- size : font size
- prop : font property
- """
-
- if prop is None:
- prop = FontProperties()
-
- if size is None:
- size = prop.get_size_in_points()
-
- self._xy = xy
- self.set_size(size)
-
- self._cached_vertices = None
-
- self._vertices, self._codes = self.text_get_vertices_codes(
- prop, s,
- usetex=usetex)
-
- self._should_simplify = False
- self._simplify_threshold = rcParams['path.simplify_threshold']
- self._has_nonfinite = False
- self._interpolation_steps = _interpolation_steps
-
- def set_size(self, size):
- """
- set the size of the text
- """
- self._size = size
- self._invalid = True
-
- def get_size(self):
- """
- get the size of the text
- """
- return self._size
-
- def _get_vertices(self):
- """
- Return the cached path after updating it if necessary.
- """
- self._revalidate_path()
- return self._cached_vertices
-
- def _get_codes(self):
- """
- Return the codes
- """
- return self._codes
-
- vertices = property(_get_vertices)
- codes = property(_get_codes)
-
- def _revalidate_path(self):
- """
- update the path if necessary.
-
- The path for the text is initially create with the font size
- of FONT_SCALE, and this path is rescaled to other size when
- necessary.
-
- """
- if (self._invalid or
- (self._cached_vertices is None)):
- tr = Affine2D().scale(
- self._size / text_to_path.FONT_SCALE,
- self._size / text_to_path.FONT_SCALE).translate(*self._xy)
- self._cached_vertices = tr.transform(self._vertices)
- self._invalid = False
-
- def is_math_text(self, s):
- """
- Returns True if the given string *s* contains any mathtext.
- """
- # copied from Text.is_math_text -JJL
-
- # Did we find an even number of non-escaped dollar signs?
- # If so, treat is as math text.
- dollar_count = s.count(r'$') - s.count(r'\$')
- even_dollars = (dollar_count > 0 and dollar_count % 2 == 0)
-
- if rcParams['text.usetex']:
- return s, 'TeX'
-
- if even_dollars:
- return s, True
- else:
- return s.replace(r'\$', '$'), False
-
- def text_get_vertices_codes(self, prop, s, usetex):
- """
- convert the string *s* to vertices and codes using the
- provided font property *prop*. Mostly copied from
- backend_svg.py.
- """
-
- if usetex:
- verts, codes = text_to_path.get_text_path(prop, s, usetex=True)
- else:
- clean_line, ismath = self.is_math_text(s)
- verts, codes = text_to_path.get_text_path(prop, clean_line,
- ismath=ismath)
-
- return verts, codes
diff --git a/contrib/python/matplotlib/py2/matplotlib/ticker.py b/contrib/python/matplotlib/py2/matplotlib/ticker.py
deleted file mode 100644
index c6946c78ec..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/ticker.py
+++ /dev/null
@@ -1,2628 +0,0 @@
-"""
-Tick locating and formatting
-============================
-
-This module contains classes to support completely configurable tick
-locating and formatting. Although the locators know nothing about major
-or minor ticks, they are used by the Axis class to support major and
-minor tick locating and formatting. Generic tick locators and
-formatters are provided, as well as domain specific custom ones.
-
-Default Formatter
------------------
-
-The default formatter identifies when the x-data being plotted is a
-small range on top of a large offset. To reduce the chances that the
-ticklabels overlap, the ticks are labeled as deltas from a fixed offset.
-For example::
-
- ax.plot(np.arange(2000, 2010), range(10))
-
-will have tick of 0-9 with an offset of +2e3. If this is not desired
-turn off the use of the offset on the default formatter::
-
- ax.get_xaxis().get_major_formatter().set_useOffset(False)
-
-set the rcParam ``axes.formatter.useoffset=False`` to turn it off
-globally, or set a different formatter.
-
-Tick locating
--------------
-
-The Locator class is the base class for all tick locators. The locators
-handle autoscaling of the view limits based on the data limits, and the
-choosing of tick locations. A useful semi-automatic tick locator is
-`MultipleLocator`. It is initialized with a base, e.g., 10, and it picks
-axis limits and ticks that are multiples of that base.
-
-The Locator subclasses defined here are
-
-:class:`AutoLocator`
- `MaxNLocator` with simple defaults. This is the default tick locator for
- most plotting.
-
-:class:`MaxNLocator`
- Finds up to a max number of intervals with ticks at nice locations.
-
-:class:`LinearLocator`
- Space ticks evenly from min to max.
-
-:class:`LogLocator`
- Space ticks logarithmically from min to max.
-
-:class:`MultipleLocator`
- Ticks and range are a multiple of base; either integer or float.
-
-:class:`FixedLocator`
- Tick locations are fixed.
-
-:class:`IndexLocator`
- Locator for index plots (e.g., where ``x = range(len(y))``).
-
-:class:`NullLocator`
- No ticks.
-
-:class:`SymmetricalLogLocator`
- Locator for use with with the symlog norm; works like `LogLocator` for the
- part outside of the threshold and adds 0 if inside the limits.
-
-:class:`LogitLocator`
- Locator for logit scaling.
-
-:class:`OldAutoLocator`
- Choose a `MultipleLocator` and dynamically reassign it for intelligent
- ticking during navigation.
-
-:class:`AutoMinorLocator`
- Locator for minor ticks when the axis is linear and the
- major ticks are uniformly spaced. Subdivides the major
- tick interval into a specified number of minor intervals,
- defaulting to 4 or 5 depending on the major interval.
-
-
-There are a number of locators specialized for date locations - see
-the `dates` module.
-
-You can define your own locator by deriving from Locator. You must
-override the ``__call__`` method, which returns a sequence of locations,
-and you will probably want to override the autoscale method to set the
-view limits from the data limits.
-
-If you want to override the default locator, use one of the above or a custom
-locator and pass it to the x or y axis instance. The relevant methods are::
-
- ax.xaxis.set_major_locator(xmajor_locator)
- ax.xaxis.set_minor_locator(xminor_locator)
- ax.yaxis.set_major_locator(ymajor_locator)
- ax.yaxis.set_minor_locator(yminor_locator)
-
-The default minor locator is `NullLocator`, i.e., no minor ticks on by default.
-
-Tick formatting
----------------
-
-Tick formatting is controlled by classes derived from Formatter. The formatter
-operates on a single tick value and returns a string to the axis.
-
-:class:`NullFormatter`
- No labels on the ticks.
-
-:class:`IndexFormatter`
- Set the strings from a list of labels.
-
-:class:`FixedFormatter`
- Set the strings manually for the labels.
-
-:class:`FuncFormatter`
- User defined function sets the labels.
-
-:class:`StrMethodFormatter`
- Use string `format` method.
-
-:class:`FormatStrFormatter`
- Use an old-style sprintf format string.
-
-:class:`ScalarFormatter`
- Default formatter for scalars: autopick the format string.
-
-:class:`LogFormatter`
- Formatter for log axes.
-
-:class:`LogFormatterExponent`
- Format values for log axis using ``exponent = log_base(value)``.
-
-:class:`LogFormatterMathtext`
- Format values for log axis using ``exponent = log_base(value)``
- using Math text.
-
-:class:`LogFormatterSciNotation`
- Format values for log axis using scientific notation.
-
-:class:`LogitFormatter`
- Probability formatter.
-
-:class:`EngFormatter`
- Format labels in engineering notation
-
-:class:`PercentFormatter`
- Format labels as a percentage
-
-You can derive your own formatter from the Formatter base class by
-simply overriding the ``__call__`` method. The formatter class has
-access to the axis view and data limits.
-
-To control the major and minor tick label formats, use one of the
-following methods::
-
- ax.xaxis.set_major_formatter(xmajor_formatter)
- ax.xaxis.set_minor_formatter(xminor_formatter)
- ax.yaxis.set_major_formatter(ymajor_formatter)
- ax.yaxis.set_minor_formatter(yminor_formatter)
-
-See :doc:`/gallery/ticks_and_spines/major_minor_demo` for an
-example of setting major and minor ticks. See the :mod:`matplotlib.dates`
-module for more information and examples of using date locators and formatters.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import itertools
-import locale
-import math
-import numpy as np
-from matplotlib import rcParams
-from matplotlib import cbook
-from matplotlib import transforms as mtransforms
-from matplotlib.cbook import mplDeprecation
-
-import warnings
-
-
-__all__ = ('TickHelper', 'Formatter', 'FixedFormatter',
- 'NullFormatter', 'FuncFormatter', 'FormatStrFormatter',
- 'StrMethodFormatter', 'ScalarFormatter', 'LogFormatter',
- 'LogFormatterExponent', 'LogFormatterMathtext',
- 'IndexFormatter', 'LogFormatterSciNotation',
- 'LogitFormatter', 'EngFormatter', 'PercentFormatter',
- 'Locator', 'IndexLocator', 'FixedLocator', 'NullLocator',
- 'LinearLocator', 'LogLocator', 'AutoLocator',
- 'MultipleLocator', 'MaxNLocator', 'AutoMinorLocator',
- 'SymmetricalLogLocator', 'LogitLocator')
-
-
-if six.PY3:
- long = int
-
-
-# Work around numpy/numpy#6127.
-def _divmod(x, y):
- if isinstance(x, np.generic):
- x = x.item()
- if isinstance(y, np.generic):
- y = y.item()
- return six.moves.builtins.divmod(x, y)
-
-
-def _mathdefault(s):
- return '\\mathdefault{%s}' % s
-
-
-class _DummyAxis(object):
- def __init__(self, minpos=0):
- self.dataLim = mtransforms.Bbox.unit()
- self.viewLim = mtransforms.Bbox.unit()
- self._minpos = minpos
-
- def get_view_interval(self):
- return self.viewLim.intervalx
-
- def set_view_interval(self, vmin, vmax):
- self.viewLim.intervalx = vmin, vmax
-
- def get_minpos(self):
- return self._minpos
-
- def get_data_interval(self):
- return self.dataLim.intervalx
-
- def set_data_interval(self, vmin, vmax):
- self.dataLim.intervalx = vmin, vmax
-
- def get_tick_space(self):
- # Just use the long-standing default of nbins==9
- return 9
-
-
-class TickHelper(object):
- axis = None
-
- def set_axis(self, axis):
- self.axis = axis
-
- def create_dummy_axis(self, **kwargs):
- if self.axis is None:
- self.axis = _DummyAxis(**kwargs)
-
- def set_view_interval(self, vmin, vmax):
- self.axis.set_view_interval(vmin, vmax)
-
- def set_data_interval(self, vmin, vmax):
- self.axis.set_data_interval(vmin, vmax)
-
- def set_bounds(self, vmin, vmax):
- self.set_view_interval(vmin, vmax)
- self.set_data_interval(vmin, vmax)
-
-
-class Formatter(TickHelper):
- """
- Create a string based on a tick value and location.
- """
- # some classes want to see all the locs to help format
- # individual ones
- locs = []
-
- def __call__(self, x, pos=None):
- """
- Return the format for tick value *x* at position pos.
- ``pos=None`` indicates an unspecified location.
- """
- raise NotImplementedError('Derived must override')
-
- def format_data(self, value):
- """
- Returns the full string representation of the value with the
- position unspecified.
- """
- return self.__call__(value)
-
- def format_data_short(self, value):
- """
- Return a short string version of the tick value.
-
- Defaults to the position-independent long value.
- """
- return self.format_data(value)
-
- def get_offset(self):
- return ''
-
- def set_locs(self, locs):
- self.locs = locs
-
- def fix_minus(self, s):
- """
- Some classes may want to replace a hyphen for minus with the
- proper unicode symbol (U+2212) for typographical correctness.
- The default is to not replace it.
-
- Note, if you use this method, e.g., in :meth:`format_data` or
- call, you probably don't want to use it for
- :meth:`format_data_short` since the toolbar uses this for
- interactive coord reporting and I doubt we can expect GUIs
- across platforms will handle the unicode correctly. So for
- now the classes that override :meth:`fix_minus` should have an
- explicit :meth:`format_data_short` method
- """
- return s
-
-
-class IndexFormatter(Formatter):
- """
- Format the position x to the nearest i-th label where i=int(x+0.5)
- """
- def __init__(self, labels):
- self.labels = labels
- self.n = len(labels)
-
- def __call__(self, x, pos=None):
- """
- Return the format for tick value `x` at position pos.
-
- The position is ignored and the value is rounded to the nearest
- integer, which is used to look up the label.
- """
- i = int(x + 0.5)
- if i < 0 or i >= self.n:
- return ''
- else:
- return self.labels[i]
-
-
-class NullFormatter(Formatter):
- """
- Always return the empty string.
- """
- def __call__(self, x, pos=None):
- """
- Returns an empty string for all inputs.
- """
- return ''
-
-
-class FixedFormatter(Formatter):
- """
- Return fixed strings for tick labels based only on position, not
- value.
- """
- def __init__(self, seq):
- """
- Set the sequence of strings that will be used for labels.
- """
- self.seq = seq
- self.offset_string = ''
-
- def __call__(self, x, pos=None):
- """
- Returns the label that matches the position regardless of the
- value.
-
- For positions ``pos < len(seq)``, return `seq[i]` regardless of
- `x`. Otherwise return empty string. `seq` is the sequence of
- strings that this object was initialized with.
- """
- if pos is None or pos >= len(self.seq):
- return ''
- else:
- return self.seq[pos]
-
- def get_offset(self):
- return self.offset_string
-
- def set_offset_string(self, ofs):
- self.offset_string = ofs
-
-
-class FuncFormatter(Formatter):
- """
- Use a user-defined function for formatting.
-
- The function should take in two inputs (a tick value ``x`` and a
- position ``pos``), and return a string containing the corresponding
- tick label.
- """
- def __init__(self, func):
- self.func = func
-
- def __call__(self, x, pos=None):
- """
- Return the value of the user defined function.
-
- `x` and `pos` are passed through as-is.
- """
- return self.func(x, pos)
-
-
-class FormatStrFormatter(Formatter):
- """
- Use an old-style ('%' operator) format string to format the tick.
-
- The format string should have a single variable format (%) in it.
- It will be applied to the value (not the position) of the tick.
- """
- def __init__(self, fmt):
- self.fmt = fmt
-
- def __call__(self, x, pos=None):
- """
- Return the formatted label string.
-
- Only the value `x` is formatted. The position is ignored.
- """
- return self.fmt % x
-
-
-class StrMethodFormatter(Formatter):
- """
- Use a new-style format string (as used by `str.format()`)
- to format the tick.
-
- The field used for the value must be labeled `x` and the field used
- for the position must be labeled `pos`.
- """
- def __init__(self, fmt):
- self.fmt = fmt
-
- def __call__(self, x, pos=None):
- """
- Return the formatted label string.
-
- `x` and `pos` are passed to `str.format` as keyword arguments
- with those exact names.
- """
- return self.fmt.format(x=x, pos=pos)
-
-
-class OldScalarFormatter(Formatter):
- """
- Tick location is a plain old number.
- """
-
- def __call__(self, x, pos=None):
- """
- Return the format for tick val `x` based on the width of the
- axis.
-
- The position `pos` is ignored.
- """
- xmin, xmax = self.axis.get_view_interval()
- d = abs(xmax - xmin)
-
- return self.pprint_val(x, d)
-
- def pprint_val(self, x, d):
- """
- Formats the value `x` based on the size of the axis range `d`.
- """
- #if the number is not too big and it's an int, format it as an
- #int
- if abs(x) < 1e4 and x == int(x):
- return '%d' % x
-
- if d < 1e-2:
- fmt = '%1.3e'
- elif d < 1e-1:
- fmt = '%1.3f'
- elif d > 1e5:
- fmt = '%1.1e'
- elif d > 10:
- fmt = '%1.1f'
- elif d > 1:
- fmt = '%1.2f'
- else:
- fmt = '%1.3f'
- s = fmt % x
- tup = s.split('e')
- if len(tup) == 2:
- mantissa = tup[0].rstrip('0').rstrip('.')
- sign = tup[1][0].replace('+', '')
- exponent = tup[1][1:].lstrip('0')
- s = '%se%s%s' % (mantissa, sign, exponent)
- else:
- s = s.rstrip('0').rstrip('.')
- return s
-
-
-class ScalarFormatter(Formatter):
- """
- Format tick values as a number.
-
- Tick value is interpreted as a plain old number. If
- ``useOffset==True`` and the data range is much smaller than the data
- average, then an offset will be determined such that the tick labels
- are meaningful. Scientific notation is used for ``data < 10^-n`` or
- ``data >= 10^m``, where ``n`` and ``m`` are the power limits set
- using ``set_powerlimits((n,m))``. The defaults for these are
- controlled by the ``axes.formatter.limits`` rc parameter.
- """
- def __init__(self, useOffset=None, useMathText=None, useLocale=None):
- # useOffset allows plotting small data ranges with large offsets: for
- # example: [1+1e-9,1+2e-9,1+3e-9] useMathText will render the offset
- # and scientific notation in mathtext
-
- if useOffset is None:
- useOffset = rcParams['axes.formatter.useoffset']
- self._offset_threshold = rcParams['axes.formatter.offset_threshold']
- self.set_useOffset(useOffset)
- self._usetex = rcParams['text.usetex']
- if useMathText is None:
- useMathText = rcParams['axes.formatter.use_mathtext']
- self.set_useMathText(useMathText)
- self.orderOfMagnitude = 0
- self.format = ''
- self._scientific = True
- self._powerlimits = rcParams['axes.formatter.limits']
- if useLocale is None:
- useLocale = rcParams['axes.formatter.use_locale']
- self._useLocale = useLocale
-
- def get_useOffset(self):
- return self._useOffset
-
- def set_useOffset(self, val):
- if val in [True, False]:
- self.offset = 0
- self._useOffset = val
- else:
- self._useOffset = False
- self.offset = val
-
- useOffset = property(fget=get_useOffset, fset=set_useOffset)
-
- def get_useLocale(self):
- return self._useLocale
-
- def set_useLocale(self, val):
- if val is None:
- self._useLocale = rcParams['axes.formatter.use_locale']
- else:
- self._useLocale = val
-
- useLocale = property(fget=get_useLocale, fset=set_useLocale)
-
- def get_useMathText(self):
- return self._useMathText
-
- def set_useMathText(self, val):
- if val is None:
- self._useMathText = rcParams['axes.formatter.use_mathtext']
- else:
- self._useMathText = val
-
- useMathText = property(fget=get_useMathText, fset=set_useMathText)
-
- def fix_minus(self, s):
- """
- Replace hyphens with a unicode minus.
- """
- if rcParams['text.usetex'] or not rcParams['axes.unicode_minus']:
- return s
- else:
- return s.replace('-', '\N{MINUS SIGN}')
-
- def __call__(self, x, pos=None):
- """
- Return the format for tick value `x` at position `pos`.
- """
- if len(self.locs) == 0:
- return ''
- else:
- s = self.pprint_val(x)
- return self.fix_minus(s)
-
- def set_scientific(self, b):
- """
- Turn scientific notation on or off.
-
- .. seealso:: Method :meth:`set_powerlimits`
- """
- self._scientific = bool(b)
-
- def set_powerlimits(self, lims):
- """
- Sets size thresholds for scientific notation.
-
- Parameters
- ----------
- lims : (min_exp, max_exp)
- A tuple containing the powers of 10 that determine the switchover
- threshold. Numbers below ``10**min_exp`` and above ``10**max_exp``
- will be displayed in scientific notation.
-
- For example, ``formatter.set_powerlimits((-3, 4))`` sets the
- pre-2007 default in which scientific notation is used for
- numbers less than 1e-3 or greater than 1e4.
-
- .. seealso:: Method :meth:`set_scientific`
- """
- if len(lims) != 2:
- raise ValueError("'lims' must be a sequence of length 2")
- self._powerlimits = lims
-
- def format_data_short(self, value):
- """
- Return a short formatted string representation of a number.
- """
- if self._useLocale:
- return locale.format_string('%-12g', (value,))
- else:
- return '%-12g' % value
-
- def format_data(self, value):
- """
- Return a formatted string representation of a number.
- """
- if self._useLocale:
- s = locale.format_string('%1.10e', (value,))
- else:
- s = '%1.10e' % value
- s = self._formatSciNotation(s)
- return self.fix_minus(s)
-
- def get_offset(self):
- """
- Return scientific notation, plus offset.
- """
- if len(self.locs) == 0:
- return ''
- s = ''
- if self.orderOfMagnitude or self.offset:
- offsetStr = ''
- sciNotStr = ''
- if self.offset:
- offsetStr = self.format_data(self.offset)
- if self.offset > 0:
- offsetStr = '+' + offsetStr
- if self.orderOfMagnitude:
- if self._usetex or self._useMathText:
- sciNotStr = self.format_data(10 ** self.orderOfMagnitude)
- else:
- sciNotStr = '1e%d' % self.orderOfMagnitude
- if self._useMathText:
- if sciNotStr != '':
- sciNotStr = r'\times%s' % _mathdefault(sciNotStr)
- s = ''.join(('$', sciNotStr, _mathdefault(offsetStr), '$'))
- elif self._usetex:
- if sciNotStr != '':
- sciNotStr = r'\times%s' % sciNotStr
- s = ''.join(('$', sciNotStr, offsetStr, '$'))
- else:
- s = ''.join((sciNotStr, offsetStr))
-
- return self.fix_minus(s)
-
- def set_locs(self, locs):
- """
- Set the locations of the ticks.
- """
- self.locs = locs
- if len(self.locs) > 0:
- vmin, vmax = self.axis.get_view_interval()
- d = abs(vmax - vmin)
- if self._useOffset:
- self._compute_offset()
- self._set_orderOfMagnitude(d)
- self._set_format(vmin, vmax)
-
- def _compute_offset(self):
- locs = self.locs
- if locs is None or not len(locs):
- self.offset = 0
- return
- # Restrict to visible ticks.
- vmin, vmax = sorted(self.axis.get_view_interval())
- locs = np.asarray(locs)
- locs = locs[(vmin <= locs) & (locs <= vmax)]
- if not len(locs):
- self.offset = 0
- return
- lmin, lmax = locs.min(), locs.max()
- # Only use offset if there are at least two ticks and every tick has
- # the same sign.
- if lmin == lmax or lmin <= 0 <= lmax:
- self.offset = 0
- return
- # min, max comparing absolute values (we want division to round towards
- # zero so we work on absolute values).
- abs_min, abs_max = sorted([abs(float(lmin)), abs(float(lmax))])
- sign = math.copysign(1, lmin)
- # What is the smallest power of ten such that abs_min and abs_max are
- # equal up to that precision?
- # Note: Internally using oom instead of 10 ** oom avoids some numerical
- # accuracy issues.
- oom_max = np.ceil(math.log10(abs_max))
- oom = 1 + next(oom for oom in itertools.count(oom_max, -1)
- if abs_min // 10 ** oom != abs_max // 10 ** oom)
- if (abs_max - abs_min) / 10 ** oom <= 1e-2:
- # Handle the case of straddling a multiple of a large power of ten
- # (relative to the span).
- # What is the smallest power of ten such that abs_min and abs_max
- # are no more than 1 apart at that precision?
- oom = 1 + next(oom for oom in itertools.count(oom_max, -1)
- if abs_max // 10 ** oom - abs_min // 10 ** oom > 1)
- # Only use offset if it saves at least _offset_threshold digits.
- n = self._offset_threshold - 1
- self.offset = (sign * (abs_max // 10 ** oom) * 10 ** oom
- if abs_max // 10 ** oom >= 10**n
- else 0)
-
- def _set_orderOfMagnitude(self, range):
- # if scientific notation is to be used, find the appropriate exponent
- # if using an numerical offset, find the exponent after applying the
- # offset
- if not self._scientific:
- self.orderOfMagnitude = 0
- return
- locs = np.abs(self.locs)
- if self.offset:
- oom = math.floor(math.log10(range))
- else:
- if locs[0] > locs[-1]:
- val = locs[0]
- else:
- val = locs[-1]
- if val == 0:
- oom = 0
- else:
- oom = math.floor(math.log10(val))
- if oom <= self._powerlimits[0]:
- self.orderOfMagnitude = oom
- elif oom >= self._powerlimits[1]:
- self.orderOfMagnitude = oom
- else:
- self.orderOfMagnitude = 0
-
- def _set_format(self, vmin, vmax):
- # set the format string to format all the ticklabels
- if len(self.locs) < 2:
- # Temporarily augment the locations with the axis end points.
- _locs = list(self.locs) + [vmin, vmax]
- else:
- _locs = self.locs
- locs = (np.asarray(_locs) - self.offset) / 10. ** self.orderOfMagnitude
- loc_range = np.ptp(locs)
- # Curvilinear coordinates can yield two identical points.
- if loc_range == 0:
- loc_range = np.max(np.abs(locs))
- # Both points might be zero.
- if loc_range == 0:
- loc_range = 1
- if len(self.locs) < 2:
- # We needed the end points only for the loc_range calculation.
- locs = locs[:-2]
- loc_range_oom = int(math.floor(math.log10(loc_range)))
- # first estimate:
- sigfigs = max(0, 3 - loc_range_oom)
- # refined estimate:
- thresh = 1e-3 * 10 ** loc_range_oom
- while sigfigs >= 0:
- if np.abs(locs - np.round(locs, decimals=sigfigs)).max() < thresh:
- sigfigs -= 1
- else:
- break
- sigfigs += 1
- self.format = '%1.' + str(sigfigs) + 'f'
- if self._usetex:
- self.format = '$%s$' % self.format
- elif self._useMathText:
- self.format = '$%s$' % _mathdefault(self.format)
-
- def pprint_val(self, x):
- xp = (x - self.offset) / (10. ** self.orderOfMagnitude)
- if np.abs(xp) < 1e-8:
- xp = 0
- if self._useLocale:
- return locale.format_string(self.format, (xp,))
- else:
- return self.format % xp
-
- def _formatSciNotation(self, s):
- # transform 1e+004 into 1e4, for example
- if self._useLocale:
- decimal_point = locale.localeconv()['decimal_point']
- positive_sign = locale.localeconv()['positive_sign']
- else:
- decimal_point = '.'
- positive_sign = '+'
- tup = s.split('e')
- try:
- significand = tup[0].rstrip('0').rstrip(decimal_point)
- sign = tup[1][0].replace(positive_sign, '')
- exponent = tup[1][1:].lstrip('0')
- if self._useMathText or self._usetex:
- if significand == '1' and exponent != '':
- # reformat 1x10^y as 10^y
- significand = ''
- if exponent:
- exponent = '10^{%s%s}' % (sign, exponent)
- if significand and exponent:
- return r'%s{\times}%s' % (significand, exponent)
- else:
- return r'%s%s' % (significand, exponent)
- else:
- s = ('%se%s%s' % (significand, sign, exponent)).rstrip('e')
- return s
- except IndexError:
- return s
-
-
-class LogFormatter(Formatter):
- """
- Base class for formatting ticks on a log or symlog scale.
-
- It may be instantiated directly, or subclassed.
-
- Parameters
- ----------
- base : float, optional, default: 10.
- Base of the logarithm used in all calculations.
-
- labelOnlyBase : bool, optional, default: False
- If True, label ticks only at integer powers of base.
- This is normally True for major ticks and False for
- minor ticks.
-
- minor_thresholds : (subset, all), optional, default: (1, 0.4)
- If labelOnlyBase is False, these two numbers control
- the labeling of ticks that are not at integer powers of
- base; normally these are the minor ticks. The controlling
- parameter is the log of the axis data range. In the typical
- case where base is 10 it is the number of decades spanned
- by the axis, so we can call it 'numdec'. If ``numdec <= all``,
- all minor ticks will be labeled. If ``all < numdec <= subset``,
- then only a subset of minor ticks will be labeled, so as to
- avoid crowding. If ``numdec > subset`` then no minor ticks will
- be labeled.
-
- linthresh : None or float, optional, default: None
- If a symmetric log scale is in use, its ``linthresh``
- parameter must be supplied here.
-
- Notes
- -----
- The `set_locs` method must be called to enable the subsetting
- logic controlled by the ``minor_thresholds`` parameter.
-
- In some cases such as the colorbar, there is no distinction between
- major and minor ticks; the tick locations might be set manually,
- or by a locator that puts ticks at integer powers of base and
- at intermediate locations. For this situation, disable the
- minor_thresholds logic by using ``minor_thresholds=(np.inf, np.inf)``,
- so that all ticks will be labeled.
-
- To disable labeling of minor ticks when 'labelOnlyBase' is False,
- use ``minor_thresholds=(0, 0)``. This is the default for the
- "classic" style.
-
- Examples
- --------
- To label a subset of minor ticks when the view limits span up
- to 2 decades, and all of the ticks when zoomed in to 0.5 decades
- or less, use ``minor_thresholds=(2, 0.5)``.
-
- To label all minor ticks when the view limits span up to 1.5
- decades, use ``minor_thresholds=(1.5, 1.5)``.
-
- """
- def __init__(self, base=10.0, labelOnlyBase=False,
- minor_thresholds=None,
- linthresh=None):
-
- self._base = float(base)
- self.labelOnlyBase = labelOnlyBase
- if minor_thresholds is None:
- if rcParams['_internal.classic_mode']:
- minor_thresholds = (0, 0)
- else:
- minor_thresholds = (1, 0.4)
- self.minor_thresholds = minor_thresholds
- self._sublabels = None
- self._linthresh = linthresh
-
- def base(self, base):
- """
- Change the *base* for labeling.
-
- .. warning::
- Should always match the base used for :class:`LogLocator`
-
- """
- self._base = base
-
- def label_minor(self, labelOnlyBase):
- """
- Switch minor tick labeling on or off.
-
- Parameters
- ----------
- labelOnlyBase : bool
- If True, label ticks only at integer powers of base.
-
- """
- self.labelOnlyBase = labelOnlyBase
-
- def set_locs(self, locs=None):
- """
- Use axis view limits to control which ticks are labeled.
-
- The *locs* parameter is ignored in the present algorithm.
-
- """
- if np.isinf(self.minor_thresholds[0]):
- self._sublabels = None
- return
-
- # Handle symlog case:
- linthresh = self._linthresh
- if linthresh is None:
- try:
- linthresh = self.axis.get_transform().linthresh
- except AttributeError:
- pass
-
- vmin, vmax = self.axis.get_view_interval()
- if vmin > vmax:
- vmin, vmax = vmax, vmin
-
- if linthresh is None and vmin <= 0:
- # It's probably a colorbar with
- # a format kwarg setting a LogFormatter in the manner
- # that worked with 1.5.x, but that doesn't work now.
- self._sublabels = set((1,)) # label powers of base
- return
-
- b = self._base
- if linthresh is not None: # symlog
- # Only compute the number of decades in the logarithmic part of the
- # axis
- numdec = 0
- if vmin < -linthresh:
- rhs = min(vmax, -linthresh)
- numdec += math.log(vmin / rhs) / math.log(b)
- if vmax > linthresh:
- lhs = max(vmin, linthresh)
- numdec += math.log(vmax / lhs) / math.log(b)
- else:
- vmin = math.log(vmin) / math.log(b)
- vmax = math.log(vmax) / math.log(b)
- numdec = abs(vmax - vmin)
-
- if numdec > self.minor_thresholds[0]:
- # Label only bases
- self._sublabels = {1}
- elif numdec > self.minor_thresholds[1]:
- # Add labels between bases at log-spaced coefficients;
- # include base powers in case the locations include
- # "major" and "minor" points, as in colorbar.
- c = np.logspace(0, 1, int(b)//2 + 1, base=b)
- self._sublabels = set(np.round(c))
- # For base 10, this yields (1, 2, 3, 4, 6, 10).
- else:
- # Label all integer multiples of base**n.
- self._sublabels = set(np.arange(1, b + 1))
-
- def _num_to_string(self, x, vmin, vmax):
- if x > 10000:
- s = '%1.0e' % x
- elif x < 1:
- s = '%1.0e' % x
- else:
- s = self.pprint_val(x, vmax - vmin)
- return s
-
- def __call__(self, x, pos=None):
- """
- Return the format for tick val *x*.
- """
- if x == 0.0: # Symlog
- return '0'
-
- x = abs(x)
- b = self._base
- # only label the decades
- fx = math.log(x) / math.log(b)
- is_x_decade = is_close_to_int(fx)
- exponent = np.round(fx) if is_x_decade else np.floor(fx)
- coeff = np.round(x / b ** exponent)
-
- if self.labelOnlyBase and not is_x_decade:
- return ''
- if self._sublabels is not None and coeff not in self._sublabels:
- return ''
-
- vmin, vmax = self.axis.get_view_interval()
- vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05)
- s = self._num_to_string(x, vmin, vmax)
- return self.fix_minus(s)
-
- def format_data(self, value):
- b = self.labelOnlyBase
- self.labelOnlyBase = False
- value = cbook.strip_math(self.__call__(value))
- self.labelOnlyBase = b
- return value
-
- def format_data_short(self, value):
- """
- Return a short formatted string representation of a number.
- """
- return '%-12g' % value
-
- def pprint_val(self, x, d):
- #if the number is not too big and it's an int, format it as an
- #int
- if abs(x) < 1e4 and x == int(x):
- return '%d' % x
-
- if d < 1e-2:
- fmt = '%1.3e'
- elif d < 1e-1:
- fmt = '%1.3f'
- elif d > 1e5:
- fmt = '%1.1e'
- elif d > 10:
- fmt = '%1.1f'
- elif d > 1:
- fmt = '%1.2f'
- else:
- fmt = '%1.3f'
- s = fmt % x
-
- tup = s.split('e')
- if len(tup) == 2:
- mantissa = tup[0].rstrip('0').rstrip('.')
- exponent = int(tup[1])
- if exponent:
- s = '%se%d' % (mantissa, exponent)
- else:
- s = mantissa
- else:
- s = s.rstrip('0').rstrip('.')
- return s
-
-
-class LogFormatterExponent(LogFormatter):
- """
- Format values for log axis using ``exponent = log_base(value)``.
- """
- def _num_to_string(self, x, vmin, vmax):
- fx = math.log(x) / math.log(self._base)
- if abs(fx) > 10000:
- s = '%1.0g' % fx
- elif abs(fx) < 1:
- s = '%1.0g' % fx
- else:
- fd = math.log(vmax - vmin) / math.log(self._base)
- s = self.pprint_val(fx, fd)
- return s
-
-
-class LogFormatterMathtext(LogFormatter):
- """
- Format values for log axis using ``exponent = log_base(value)``.
- """
-
- def _non_decade_format(self, sign_string, base, fx, usetex):
- 'Return string for non-decade locations'
- if usetex:
- return (r'$%s%s^{%.2f}$') % (sign_string, base, fx)
- else:
- return ('$%s$' % _mathdefault('%s%s^{%.2f}' %
- (sign_string, base, fx)))
-
- def __call__(self, x, pos=None):
- """
- Return the format for tick value *x*.
-
- The position *pos* is ignored.
- """
- usetex = rcParams['text.usetex']
- min_exp = rcParams['axes.formatter.min_exponent']
-
- if x == 0: # Symlog
- if usetex:
- return '$0$'
- else:
- return '$%s$' % _mathdefault('0')
-
- sign_string = '-' if x < 0 else ''
- x = abs(x)
- b = self._base
-
- # only label the decades
- fx = math.log(x) / math.log(b)
- is_x_decade = is_close_to_int(fx)
- exponent = np.round(fx) if is_x_decade else np.floor(fx)
- coeff = np.round(x / b ** exponent)
- if is_x_decade:
- fx = nearest_long(fx)
-
- if self.labelOnlyBase and not is_x_decade:
- return ''
- if self._sublabels is not None and coeff not in self._sublabels:
- return ''
-
- # use string formatting of the base if it is not an integer
- if b % 1 == 0.0:
- base = '%d' % b
- else:
- base = '%s' % b
-
- if np.abs(fx) < min_exp:
- if usetex:
- return r'${0}{1:g}$'.format(sign_string, x)
- else:
- return '${0}$'.format(_mathdefault(
- '{0}{1:g}'.format(sign_string, x)))
- elif not is_x_decade:
- return self._non_decade_format(sign_string, base, fx, usetex)
- else:
- if usetex:
- return (r'$%s%s^{%d}$') % (sign_string,
- base,
- nearest_long(fx))
- else:
- return ('$%s$' % _mathdefault(
- '%s%s^{%d}' %
- (sign_string, base, nearest_long(fx))))
-
-
-class LogFormatterSciNotation(LogFormatterMathtext):
- """
- Format values following scientific notation in a logarithmic axis.
- """
-
- def _non_decade_format(self, sign_string, base, fx, usetex):
- 'Return string for non-decade locations'
- b = float(base)
- exponent = math.floor(fx)
- coeff = b ** fx / b ** exponent
- if is_close_to_int(coeff):
- coeff = nearest_long(coeff)
- if usetex:
- return (r'$%s%g\times%s^{%d}$') % \
- (sign_string, coeff, base, exponent)
- else:
- return ('$%s$' % _mathdefault(r'%s%g\times%s^{%d}' %
- (sign_string, coeff, base, exponent)))
-
-
-class LogitFormatter(Formatter):
- """
- Probability formatter (using Math text).
- """
- def __call__(self, x, pos=None):
- s = ''
- if 0.01 <= x <= 0.99:
- s = '{:.2f}'.format(x)
- elif x < 0.01:
- if is_decade(x):
- s = '$10^{{{:.0f}}}$'.format(np.log10(x))
- else:
- s = '${:.5f}$'.format(x)
- else: # x > 0.99
- if is_decade(1-x):
- s = '$1-10^{{{:.0f}}}$'.format(np.log10(1-x))
- else:
- s = '$1-{:.5f}$'.format(1-x)
- return s
-
- def format_data_short(self, value):
- 'return a short formatted string representation of a number'
- return '%-12g' % value
-
-
-class EngFormatter(Formatter):
- """
- Formats axis values using engineering prefixes to represent powers
- of 1000, plus a specified unit, e.g., 10 MHz instead of 1e7.
- """
-
- # The SI engineering prefixes
- ENG_PREFIXES = {
- -24: "y",
- -21: "z",
- -18: "a",
- -15: "f",
- -12: "p",
- -9: "n",
- -6: "\N{GREEK SMALL LETTER MU}",
- -3: "m",
- 0: "",
- 3: "k",
- 6: "M",
- 9: "G",
- 12: "T",
- 15: "P",
- 18: "E",
- 21: "Z",
- 24: "Y"
- }
-
- def __init__(self, unit="", places=None, sep=" "):
- """
- Parameters
- ----------
- unit : str (default: "")
- Unit symbol to use, suitable for use with single-letter
- representations of powers of 1000. For example, 'Hz' or 'm'.
-
- places : int (default: None)
- Precision with which to display the number, specified in
- digits after the decimal point (there will be between one
- and three digits before the decimal point). If it is None,
- the formatting falls back to the floating point format '%g',
- which displays up to 6 *significant* digits, i.e. the equivalent
- value for *places* varies between 0 and 5 (inclusive).
-
- sep : str (default: " ")
- Separator used between the value and the prefix/unit. For
- example, one get '3.14 mV' if ``sep`` is " " (default) and
- '3.14mV' if ``sep`` is "". Besides the default behavior, some
- other useful options may be:
-
- * ``sep=""`` to append directly the prefix/unit to the value;
- * ``sep="\\N{THIN SPACE}"`` (``U+2009``);
- * ``sep="\\N{NARROW NO-BREAK SPACE}"`` (``U+202F``);
- * ``sep="\\N{NO-BREAK SPACE}"`` (``U+00A0``).
- """
- self.unit = unit
- self.places = places
- self.sep = sep
-
- def __call__(self, x, pos=None):
- s = "%s%s" % (self.format_eng(x), self.unit)
- # Remove the trailing separator when there is neither prefix nor unit
- if len(self.sep) > 0 and s.endswith(self.sep):
- s = s[:-len(self.sep)]
- return self.fix_minus(s)
-
- def format_eng(self, num):
- """
- Formats a number in engineering notation, appending a letter
- representing the power of 1000 of the original number.
- Some examples:
-
- >>> format_eng(0) # for self.places = 0
- '0'
-
- >>> format_eng(1000000) # for self.places = 1
- '1.0 M'
-
- >>> format_eng("-1e-6") # for self.places = 2
- u'-1.00 \N{GREEK SMALL LETTER MU}'
-
- `num` may be a numeric value or a string that can be converted
- to a numeric value with ``float(num)``.
- """
- if isinstance(num, six.string_types):
- warnings.warn(
- "Passing a string as *num* argument is deprecated since"
- "Matplotlib 2.1, and is expected to be removed in 2.3.",
- mplDeprecation)
-
- dnum = float(num)
- sign = 1
- fmt = "g" if self.places is None else ".{:d}f".format(self.places)
-
- if dnum < 0:
- sign = -1
- dnum = -dnum
-
- if dnum != 0:
- pow10 = int(math.floor(math.log10(dnum) / 3) * 3)
- else:
- pow10 = 0
- # Force dnum to zero, to avoid inconsistencies like
- # format_eng(-0) = "0" and format_eng(0.0) = "0"
- # but format_eng(-0.0) = "-0.0"
- dnum = 0.0
-
- pow10 = np.clip(pow10, min(self.ENG_PREFIXES), max(self.ENG_PREFIXES))
-
- mant = sign * dnum / (10.0 ** pow10)
- # Taking care of the cases like 999.9..., which
- # may be rounded to 1000 instead of 1 k. Beware
- # of the corner case of values that are beyond
- # the range of SI prefixes (i.e. > 'Y').
- _fmant = float("{mant:{fmt}}".format(mant=mant, fmt=fmt))
- if _fmant >= 1000 and pow10 != max(self.ENG_PREFIXES):
- mant /= 1000
- pow10 += 3
-
- prefix = self.ENG_PREFIXES[int(pow10)]
-
- formatted = "{mant:{fmt}}{sep}{prefix}".format(
- mant=mant, sep=self.sep, prefix=prefix, fmt=fmt)
-
- return formatted
-
-
-class PercentFormatter(Formatter):
- """
- Format numbers as a percentage.
-
- Parameters
- ----------
- xmax : float
- Determines how the number is converted into a percentage.
- *xmax* is the data value that corresponds to 100%.
- Percentages are computed as ``x / xmax * 100``. So if the data is
- already scaled to be percentages, *xmax* will be 100. Another common
- situation is where `xmax` is 1.0.
-
- decimals : None or int
- The number of decimal places to place after the point.
- If *None* (the default), the number will be computed automatically.
-
- symbol : string or None
- A string that will be appended to the label. It may be
- *None* or empty to indicate that no symbol should be used. LaTeX
- special characters are escaped in *symbol* whenever latex mode is
- enabled, unless *is_latex* is *True*.
-
- is_latex : bool
- If *False*, reserved LaTeX characters in *symbol* will be escaped.
- """
- def __init__(self, xmax=100, decimals=None, symbol='%', is_latex=False):
- self.xmax = xmax + 0.0
- self.decimals = decimals
- self._symbol = symbol
- self._is_latex = is_latex
-
- def __call__(self, x, pos=None):
- """
- Formats the tick as a percentage with the appropriate scaling.
- """
- ax_min, ax_max = self.axis.get_view_interval()
- display_range = abs(ax_max - ax_min)
-
- return self.fix_minus(self.format_pct(x, display_range))
-
- def format_pct(self, x, display_range):
- """
- Formats the number as a percentage number with the correct
- number of decimals and adds the percent symbol, if any.
-
- If `self.decimals` is `None`, the number of digits after the
- decimal point is set based on the `display_range` of the axis
- as follows:
-
- +---------------+----------+------------------------+
- | display_range | decimals | sample |
- +---------------+----------+------------------------+
- | >50 | 0 | ``x = 34.5`` => 35% |
- +---------------+----------+------------------------+
- | >5 | 1 | ``x = 34.5`` => 34.5% |
- +---------------+----------+------------------------+
- | >0.5 | 2 | ``x = 34.5`` => 34.50% |
- +---------------+----------+------------------------+
- | ... | ... | ... |
- +---------------+----------+------------------------+
-
- This method will not be very good for tiny axis ranges or
- extremely large ones. It assumes that the values on the chart
- are percentages displayed on a reasonable scale.
- """
- x = self.convert_to_pct(x)
- if self.decimals is None:
- # conversion works because display_range is a difference
- scaled_range = self.convert_to_pct(display_range)
- if scaled_range <= 0:
- decimals = 0
- else:
- # Luckily Python's built-in ceil rounds to +inf, not away from
- # zero. This is very important since the equation for decimals
- # starts out as `scaled_range > 0.5 * 10**(2 - decimals)`
- # and ends up with `decimals > 2 - log10(2 * scaled_range)`.
- decimals = math.ceil(2.0 - math.log10(2.0 * scaled_range))
- if decimals > 5:
- decimals = 5
- elif decimals < 0:
- decimals = 0
- else:
- decimals = self.decimals
- s = '{x:0.{decimals}f}'.format(x=x, decimals=int(decimals))
-
- return s + self.symbol
-
- def convert_to_pct(self, x):
- return 100.0 * (x / self.xmax)
-
- @property
- def symbol(self):
- """
- The configured percent symbol as a string.
-
- If LaTeX is enabled via :rc:`text.usetex`, the special characters
- ``{'#', '$', '%', '&', '~', '_', '^', '\\', '{', '}'}`` are
- automatically escaped in the string.
- """
- symbol = self._symbol
- if not symbol:
- symbol = ''
- elif rcParams['text.usetex'] and not self._is_latex:
- # Source: http://www.personal.ceu.hu/tex/specchar.htm
- # Backslash must be first for this to work correctly since
- # it keeps getting added in
- for spec in r'\#$%&~_^{}':
- symbol = symbol.replace(spec, '\\' + spec)
- return symbol
-
- @symbol.setter
- def symbol(self, symbol):
- self._symbol = symbol
-
-
-class Locator(TickHelper):
- """
- Determine the tick locations;
-
- Note, you should not use the same locator between different
- :class:`~matplotlib.axis.Axis` because the locator stores references to
- the Axis data and view limits
- """
-
- # Some automatic tick locators can generate so many ticks they
- # kill the machine when you try and render them.
- # This parameter is set to cause locators to raise an error if too
- # many ticks are generated.
- MAXTICKS = 1000
-
- def tick_values(self, vmin, vmax):
- """
- Return the values of the located ticks given **vmin** and **vmax**.
-
- .. note::
- To get tick locations with the vmin and vmax values defined
- automatically for the associated :attr:`axis` simply call
- the Locator instance::
-
- >>> print((type(loc)))
- <type 'Locator'>
- >>> print((loc()))
- [1, 2, 3, 4]
-
- """
- raise NotImplementedError('Derived must override')
-
- def set_params(self, **kwargs):
- """
- Do nothing, and rase a warning. Any locator class not supporting the
- set_params() function will call this.
- """
- warnings.warn("'set_params()' not defined for locator of type " +
- str(type(self)))
-
- def __call__(self):
- """Return the locations of the ticks"""
- # note: some locators return data limits, other return view limits,
- # hence there is no *one* interface to call self.tick_values.
- raise NotImplementedError('Derived must override')
-
- def raise_if_exceeds(self, locs):
- """raise a RuntimeError if Locator attempts to create more than
- MAXTICKS locs"""
- if len(locs) >= self.MAXTICKS:
- raise RuntimeError("Locator attempting to generate {} ticks from "
- "{} to {}: exceeds Locator.MAXTICKS".format(
- len(locs), locs[0], locs[-1]))
- return locs
-
- def view_limits(self, vmin, vmax):
- """
- select a scale for the range from vmin to vmax
-
- Normally this method is overridden by subclasses to
- change locator behaviour.
- """
- return mtransforms.nonsingular(vmin, vmax)
-
- def autoscale(self):
- """autoscale the view limits"""
- return self.view_limits(*self.axis.get_view_interval())
-
- def pan(self, numsteps):
- """Pan numticks (can be positive or negative)"""
- ticks = self()
- numticks = len(ticks)
-
- vmin, vmax = self.axis.get_view_interval()
- vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05)
- if numticks > 2:
- step = numsteps * abs(ticks[0] - ticks[1])
- else:
- d = abs(vmax - vmin)
- step = numsteps * d / 6.
-
- vmin += step
- vmax += step
- self.axis.set_view_interval(vmin, vmax, ignore=True)
-
- def zoom(self, direction):
- "Zoom in/out on axis; if direction is >0 zoom in, else zoom out"
-
- vmin, vmax = self.axis.get_view_interval()
- vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05)
- interval = abs(vmax - vmin)
- step = 0.1 * interval * direction
- self.axis.set_view_interval(vmin + step, vmax - step, ignore=True)
-
- def refresh(self):
- """refresh internal information based on current lim"""
- pass
-
-
-class IndexLocator(Locator):
- """
- Place a tick on every multiple of some base number of points
- plotted, e.g., on every 5th point. It is assumed that you are doing
- index plotting; i.e., the axis is 0, len(data). This is mainly
- useful for x ticks.
- """
- def __init__(self, base, offset):
- 'place ticks on the i-th data points where (i-offset)%base==0'
- self._base = base
- self.offset = offset
-
- def set_params(self, base=None, offset=None):
- """Set parameters within this locator"""
- if base is not None:
- self._base = base
- if offset is not None:
- self.offset = offset
-
- def __call__(self):
- """Return the locations of the ticks"""
- dmin, dmax = self.axis.get_data_interval()
- return self.tick_values(dmin, dmax)
-
- def tick_values(self, vmin, vmax):
- return self.raise_if_exceeds(
- np.arange(vmin + self.offset, vmax + 1, self._base))
-
-
-class FixedLocator(Locator):
- """
- Tick locations are fixed. If nbins is not None,
- the array of possible positions will be subsampled to
- keep the number of ticks <= nbins +1.
- The subsampling will be done so as to include the smallest
- absolute value; for example, if zero is included in the
- array of possibilities, then it is guaranteed to be one of
- the chosen ticks.
- """
-
- def __init__(self, locs, nbins=None):
- self.locs = np.asarray(locs)
- self.nbins = nbins
- if self.nbins is not None:
- self.nbins = max(self.nbins, 2)
-
- def set_params(self, nbins=None):
- """Set parameters within this locator."""
- if nbins is not None:
- self.nbins = nbins
-
- def __call__(self):
- return self.tick_values(None, None)
-
- def tick_values(self, vmin, vmax):
- """"
- Return the locations of the ticks.
-
- .. note::
-
- Because the values are fixed, vmin and vmax are not used in this
- method.
-
- """
- if self.nbins is None:
- return self.locs
- step = max(int(np.ceil(len(self.locs) / self.nbins)), 1)
- ticks = self.locs[::step]
- for i in range(1, step):
- ticks1 = self.locs[i::step]
- if np.abs(ticks1).min() < np.abs(ticks).min():
- ticks = ticks1
- return self.raise_if_exceeds(ticks)
-
-
-class NullLocator(Locator):
- """
- No ticks
- """
-
- def __call__(self):
- return self.tick_values(None, None)
-
- def tick_values(self, vmin, vmax):
- """"
- Return the locations of the ticks.
-
- .. note::
-
- Because the values are Null, vmin and vmax are not used in this
- method.
- """
- return []
-
-
-class LinearLocator(Locator):
- """
- Determine the tick locations
-
- The first time this function is called it will try to set the
- number of ticks to make a nice tick partitioning. Thereafter the
- number of ticks will be fixed so that interactive navigation will
- be nice
-
- """
- def __init__(self, numticks=None, presets=None):
- """
- Use presets to set locs based on lom. A dict mapping vmin, vmax->locs
- """
- self.numticks = numticks
- if presets is None:
- self.presets = {}
- else:
- self.presets = presets
-
- def set_params(self, numticks=None, presets=None):
- """Set parameters within this locator."""
- if presets is not None:
- self.presets = presets
- if numticks is not None:
- self.numticks = numticks
-
- def __call__(self):
- 'Return the locations of the ticks'
- vmin, vmax = self.axis.get_view_interval()
- return self.tick_values(vmin, vmax)
-
- def tick_values(self, vmin, vmax):
- vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05)
- if vmax < vmin:
- vmin, vmax = vmax, vmin
-
- if (vmin, vmax) in self.presets:
- return self.presets[(vmin, vmax)]
-
- if self.numticks is None:
- self._set_numticks()
-
- if self.numticks == 0:
- return []
- ticklocs = np.linspace(vmin, vmax, self.numticks)
-
- return self.raise_if_exceeds(ticklocs)
-
- def _set_numticks(self):
- self.numticks = 11 # todo; be smart here; this is just for dev
-
- def view_limits(self, vmin, vmax):
- 'Try to choose the view limits intelligently'
-
- if vmax < vmin:
- vmin, vmax = vmax, vmin
-
- if vmin == vmax:
- vmin -= 1
- vmax += 1
-
- if rcParams['axes.autolimit_mode'] == 'round_numbers':
- exponent, remainder = _divmod(
- math.log10(vmax - vmin), math.log10(max(self.numticks - 1, 1)))
- exponent -= (remainder < .5)
- scale = max(self.numticks - 1, 1) ** (-exponent)
- vmin = math.floor(scale * vmin) / scale
- vmax = math.ceil(scale * vmax) / scale
-
- return mtransforms.nonsingular(vmin, vmax)
-
-
-def closeto(x, y):
- if abs(x - y) < 1e-10:
- return True
- else:
- return False
-
-
-class Base(object):
- 'this solution has some hacks to deal with floating point inaccuracies'
- def __init__(self, base):
- if base <= 0:
- raise ValueError("'base' must be positive")
- self._base = base
-
- def lt(self, x):
- 'return the largest multiple of base < x'
- d, m = _divmod(x, self._base)
- if closeto(m, 0) and not closeto(m / self._base, 1):
- return (d - 1) * self._base
- return d * self._base
-
- def le(self, x):
- 'return the largest multiple of base <= x'
- d, m = _divmod(x, self._base)
- if closeto(m / self._base, 1): # was closeto(m, self._base)
- #looks like floating point error
- return (d + 1) * self._base
- return d * self._base
-
- def gt(self, x):
- 'return the smallest multiple of base > x'
- d, m = _divmod(x, self._base)
- if closeto(m / self._base, 1):
- #looks like floating point error
- return (d + 2) * self._base
- return (d + 1) * self._base
-
- def ge(self, x):
- 'return the smallest multiple of base >= x'
- d, m = _divmod(x, self._base)
- if closeto(m, 0) and not closeto(m / self._base, 1):
- return d * self._base
- return (d + 1) * self._base
-
- def get_base(self):
- return self._base
-
-
-class MultipleLocator(Locator):
- """
- Set a tick on every integer that is multiple of base in the
- view interval
- """
-
- def __init__(self, base=1.0):
- self._base = Base(base)
-
- def set_params(self, base):
- """Set parameters within this locator."""
- if base is not None:
- self._base = base
-
- def __call__(self):
- 'Return the locations of the ticks'
- vmin, vmax = self.axis.get_view_interval()
- return self.tick_values(vmin, vmax)
-
- def tick_values(self, vmin, vmax):
- if vmax < vmin:
- vmin, vmax = vmax, vmin
- vmin = self._base.ge(vmin)
- base = self._base.get_base()
- n = (vmax - vmin + 0.001 * base) // base
- locs = vmin - base + np.arange(n + 3) * base
- return self.raise_if_exceeds(locs)
-
- def view_limits(self, dmin, dmax):
- """
- Set the view limits to the nearest multiples of base that
- contain the data
- """
- if rcParams['axes.autolimit_mode'] == 'round_numbers':
- vmin = self._base.le(dmin)
- vmax = self._base.ge(dmax)
- if vmin == vmax:
- vmin -= 1
- vmax += 1
- else:
- vmin = dmin
- vmax = dmax
-
- return mtransforms.nonsingular(vmin, vmax)
-
-
-def scale_range(vmin, vmax, n=1, threshold=100):
- dv = abs(vmax - vmin) # > 0 as nonsingular is called before.
- meanv = (vmax + vmin) / 2
- if abs(meanv) / dv < threshold:
- offset = 0
- else:
- offset = math.copysign(10 ** (math.log10(abs(meanv)) // 1), meanv)
- scale = 10 ** (math.log10(dv / n) // 1)
- return scale, offset
-
-
-class MaxNLocator(Locator):
- """
- Select no more than N intervals at nice locations.
- """
- default_params = dict(nbins=10,
- steps=None,
- integer=False,
- symmetric=False,
- prune=None,
- min_n_ticks=2)
-
- def __init__(self, *args, **kwargs):
- """
- Keyword args:
-
- *nbins*
- Maximum number of intervals; one less than max number of
- ticks. If the string `'auto'`, the number of bins will be
- automatically determined based on the length of the axis.
-
- *steps*
- Sequence of nice numbers starting with 1 and ending with 10;
- e.g., [1, 2, 4, 5, 10], where the values are acceptable
- tick multiples. i.e. for the example, 20, 40, 60 would be
- an acceptable set of ticks, as would 0.4, 0.6, 0.8, because
- they are multiples of 2. However, 30, 60, 90 would not
- be allowed because 3 does not appear in the list of steps.
-
- *integer*
- If True, ticks will take only integer values, provided
- at least `min_n_ticks` integers are found within the
- view limits.
-
- *symmetric*
- If True, autoscaling will result in a range symmetric
- about zero.
-
- *prune*
- ['lower' | 'upper' | 'both' | None]
- Remove edge ticks -- useful for stacked or ganged plots where
- the upper tick of one axes overlaps with the lower tick of the
- axes above it, primarily when :rc:`axes.autolimit_mode` is
- ``'round_numbers'``. If ``prune=='lower'``, the smallest tick will
- be removed. If ``prune == 'upper'``, the largest tick will be
- removed. If ``prune == 'both'``, the largest and smallest ticks
- will be removed. If ``prune == None``, no ticks will be removed.
-
- *min_n_ticks*
- Relax `nbins` and `integer` constraints if necessary to
- obtain this minimum number of ticks.
-
- """
- if args:
- kwargs['nbins'] = args[0]
- if len(args) > 1:
- raise ValueError(
- "Keywords are required for all arguments except 'nbins'")
- self.set_params(**self.default_params)
- self.set_params(**kwargs)
-
- @staticmethod
- def _validate_steps(steps):
- if not np.iterable(steps):
- raise ValueError('steps argument must be a sequence of numbers '
- 'from 1 to 10')
- steps = np.asarray(steps)
- if np.any(np.diff(steps) <= 0):
- raise ValueError('steps argument must be uniformly increasing')
- if steps[-1] > 10 or steps[0] < 1:
- warnings.warn('Steps argument should be a sequence of numbers\n'
- 'increasing from 1 to 10, inclusive. Behavior with\n'
- 'values outside this range is undefined, and will\n'
- 'raise a ValueError in future versions of mpl.')
- if steps[0] != 1:
- steps = np.hstack((1, steps))
- if steps[-1] != 10:
- steps = np.hstack((steps, 10))
- return steps
-
- @staticmethod
- def _staircase(steps):
- # Make an extended staircase within which the needed
- # step will be found. This is probably much larger
- # than necessary.
- flights = (0.1 * steps[:-1], steps, 10 * steps[1])
- return np.hstack(flights)
-
- def set_params(self, **kwargs):
- """Set parameters within this locator."""
- if 'nbins' in kwargs:
- self._nbins = kwargs['nbins']
- if self._nbins != 'auto':
- self._nbins = int(self._nbins)
- if 'symmetric' in kwargs:
- self._symmetric = kwargs['symmetric']
- if 'prune' in kwargs:
- prune = kwargs['prune']
- if prune is not None and prune not in ['upper', 'lower', 'both']:
- raise ValueError(
- "prune must be 'upper', 'lower', 'both', or None")
- self._prune = prune
- if 'min_n_ticks' in kwargs:
- self._min_n_ticks = max(1, kwargs['min_n_ticks'])
- if 'steps' in kwargs:
- steps = kwargs['steps']
- if steps is None:
- self._steps = np.array([1, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10])
- else:
- self._steps = self._validate_steps(steps)
- self._extended_steps = self._staircase(self._steps)
- if 'integer' in kwargs:
- self._integer = kwargs['integer']
-
- def _raw_ticks(self, vmin, vmax):
- if self._nbins == 'auto':
- if self.axis is not None:
- nbins = np.clip(self.axis.get_tick_space(),
- max(1, self._min_n_ticks - 1), 9)
- else:
- nbins = 9
- else:
- nbins = self._nbins
-
- scale, offset = scale_range(vmin, vmax, nbins)
- _vmin = vmin - offset
- _vmax = vmax - offset
- raw_step = (vmax - vmin) / nbins
- steps = self._extended_steps * scale
- if self._integer:
- # For steps > 1, keep only integer values.
- igood = (steps < 1) | (np.abs(steps - np.round(steps)) < 0.001)
- steps = steps[igood]
-
- istep = np.nonzero(steps >= raw_step)[0][0]
-
- # Classic round_numbers mode may require a larger step.
- if rcParams['axes.autolimit_mode'] == 'round_numbers':
- for istep in range(istep, len(steps)):
- step = steps[istep]
- best_vmin = (_vmin // step) * step
- best_vmax = best_vmin + step * nbins
- if (best_vmax >= _vmax):
- break
-
- # This is an upper limit; move to smaller steps if necessary.
- for i in range(istep):
- step = steps[istep - i]
- if (self._integer and
- np.floor(_vmax) - np.ceil(_vmin) >= self._min_n_ticks - 1):
- step = max(1, step)
- best_vmin = (_vmin // step) * step
-
- low = np.round(Base(step).le(_vmin - best_vmin) / step)
- high = np.round(Base(step).ge(_vmax - best_vmin) / step)
- ticks = np.arange(low, high + 1) * step + best_vmin + offset
- nticks = ((ticks <= vmax) & (ticks >= vmin)).sum()
- if nticks >= self._min_n_ticks:
- break
- return ticks
-
- def __call__(self):
- vmin, vmax = self.axis.get_view_interval()
- return self.tick_values(vmin, vmax)
-
- def tick_values(self, vmin, vmax):
- if self._symmetric:
- vmax = max(abs(vmin), abs(vmax))
- vmin = -vmax
- vmin, vmax = mtransforms.nonsingular(
- vmin, vmax, expander=1e-13, tiny=1e-14)
- locs = self._raw_ticks(vmin, vmax)
-
- prune = self._prune
- if prune == 'lower':
- locs = locs[1:]
- elif prune == 'upper':
- locs = locs[:-1]
- elif prune == 'both':
- locs = locs[1:-1]
- return self.raise_if_exceeds(locs)
-
- def view_limits(self, dmin, dmax):
- if self._symmetric:
- dmax = max(abs(dmin), abs(dmax))
- dmin = -dmax
-
- dmin, dmax = mtransforms.nonsingular(
- dmin, dmax, expander=1e-12, tiny=1e-13)
-
- if rcParams['axes.autolimit_mode'] == 'round_numbers':
- return self._raw_ticks(dmin, dmax)[[0, -1]]
- else:
- return dmin, dmax
-
-
-def decade_down(x, base=10):
- 'floor x to the nearest lower decade'
- if x == 0.0:
- return -base
- lx = np.floor(np.log(x) / np.log(base))
- return base ** lx
-
-
-def decade_up(x, base=10):
- 'ceil x to the nearest higher decade'
- if x == 0.0:
- return base
- lx = np.ceil(np.log(x) / np.log(base))
- return base ** lx
-
-
-def nearest_long(x):
- if x == 0:
- return long(0)
- elif x > 0:
- return long(x + 0.5)
- else:
- return long(x - 0.5)
-
-
-def is_decade(x, base=10):
- if not np.isfinite(x):
- return False
- if x == 0.0:
- return True
- lx = np.log(np.abs(x)) / np.log(base)
- return is_close_to_int(lx)
-
-
-def is_close_to_int(x):
- if not np.isfinite(x):
- return False
- return abs(x - nearest_long(x)) < 1e-10
-
-
-class LogLocator(Locator):
- """
- Determine the tick locations for log axes
- """
-
- def __init__(self, base=10.0, subs=(1.0,), numdecs=4, numticks=None):
- """
- Place ticks on the locations : subs[j] * base**i
-
- Parameters
- ----------
- subs : None, string, or sequence of float, optional, default (1.0,)
- Gives the multiples of integer powers of the base at which
- to place ticks. The default places ticks only at
- integer powers of the base.
- The permitted string values are ``'auto'`` and ``'all'``,
- both of which use an algorithm based on the axis view
- limits to determine whether and how to put ticks between
- integer powers of the base. With ``'auto'``, ticks are
- placed only between integer powers; with ``'all'``, the
- integer powers are included. A value of None is
- equivalent to ``'auto'``.
-
- """
- if numticks is None:
- if rcParams['_internal.classic_mode']:
- numticks = 15
- else:
- numticks = 'auto'
- self.base(base)
- self.subs(subs)
- self.numdecs = numdecs
- self.numticks = numticks
-
- def set_params(self, base=None, subs=None, numdecs=None, numticks=None):
- """Set parameters within this locator."""
- if base is not None:
- self.base(base)
- if subs is not None:
- self.subs(subs)
- if numdecs is not None:
- self.numdecs = numdecs
- if numticks is not None:
- self.numticks = numticks
-
- # FIXME: these base and subs functions are contrary to our
- # usual and desired API.
-
- def base(self, base):
- """
- set the base of the log scaling (major tick every base**i, i integer)
- """
- self._base = float(base)
-
- def subs(self, subs):
- """
- set the minor ticks for the log scaling every base**i*subs[j]
- """
- if subs is None: # consistency with previous bad API
- self._subs = 'auto'
- elif isinstance(subs, six.string_types):
- if subs not in ('all', 'auto'):
- raise ValueError("A subs string must be 'all' or 'auto'; "
- "found '%s'." % subs)
- self._subs = subs
- else:
- self._subs = np.asarray(subs, dtype=float)
-
- def __call__(self):
- 'Return the locations of the ticks'
- vmin, vmax = self.axis.get_view_interval()
- return self.tick_values(vmin, vmax)
-
- def tick_values(self, vmin, vmax):
- if self.numticks == 'auto':
- if self.axis is not None:
- numticks = np.clip(self.axis.get_tick_space(), 2, 9)
- else:
- numticks = 9
- else:
- numticks = self.numticks
-
- b = self._base
- # dummy axis has no axes attribute
- if hasattr(self.axis, 'axes') and self.axis.axes.name == 'polar':
- vmax = math.ceil(math.log(vmax) / math.log(b))
- decades = np.arange(vmax - self.numdecs, vmax)
- ticklocs = b ** decades
-
- return ticklocs
-
- if vmin <= 0.0:
- if self.axis is not None:
- vmin = self.axis.get_minpos()
-
- if vmin <= 0.0 or not np.isfinite(vmin):
- raise ValueError(
- "Data has no positive values, and therefore can not be "
- "log-scaled.")
-
- vmin = math.log(vmin) / math.log(b)
- vmax = math.log(vmax) / math.log(b)
-
- if vmax < vmin:
- vmin, vmax = vmax, vmin
-
- numdec = math.floor(vmax) - math.ceil(vmin)
-
- if isinstance(self._subs, six.string_types):
- _first = 2.0 if self._subs == 'auto' else 1.0
- if numdec > 10 or b < 3:
- if self._subs == 'auto':
- return np.array([]) # no minor or major ticks
- else:
- subs = np.array([1.0]) # major ticks
- else:
- subs = np.arange(_first, b)
- else:
- subs = self._subs
-
- stride = 1
-
- if rcParams['_internal.classic_mode']:
- # Leave the bug left over from the PY2-PY3 transition.
- while numdec / stride + 1 > numticks:
- stride += 1
- else:
- while numdec // stride + 1 > numticks:
- stride += 1
-
- # Does subs include anything other than 1?
- have_subs = len(subs) > 1 or (len(subs) == 1 and subs[0] != 1.0)
-
- decades = np.arange(math.floor(vmin) - stride,
- math.ceil(vmax) + 2 * stride, stride)
-
- if hasattr(self, '_transform'):
- ticklocs = self._transform.inverted().transform(decades)
- if have_subs:
- if stride == 1:
- ticklocs = np.ravel(np.outer(subs, ticklocs))
- else:
- ticklocs = []
- else:
- if have_subs:
- ticklocs = []
- if stride == 1:
- for decadeStart in b ** decades:
- ticklocs.extend(subs * decadeStart)
- else:
- ticklocs = b ** decades
-
- return self.raise_if_exceeds(np.asarray(ticklocs))
-
- def view_limits(self, vmin, vmax):
- 'Try to choose the view limits intelligently'
- b = self._base
-
- vmin, vmax = self.nonsingular(vmin, vmax)
-
- if self.axis.axes.name == 'polar':
- vmax = math.ceil(math.log(vmax) / math.log(b))
- vmin = b ** (vmax - self.numdecs)
-
- if rcParams['axes.autolimit_mode'] == 'round_numbers':
- if not is_decade(vmin, self._base):
- vmin = decade_down(vmin, self._base)
- if not is_decade(vmax, self._base):
- vmax = decade_up(vmax, self._base)
-
- return vmin, vmax
-
- def nonsingular(self, vmin, vmax):
- if not np.isfinite(vmin) or not np.isfinite(vmax):
- return 1, 10 # initial range, no data plotted yet
-
- if vmin > vmax:
- vmin, vmax = vmax, vmin
- if vmax <= 0:
- warnings.warn(
- "Data has no positive values, and therefore cannot be "
- "log-scaled.")
- return 1, 10
-
- minpos = self.axis.get_minpos()
- if not np.isfinite(minpos):
- minpos = 1e-300 # This should never take effect.
- if vmin <= 0:
- vmin = minpos
- if vmin == vmax:
- vmin = decade_down(vmin, self._base)
- vmax = decade_up(vmax, self._base)
- return vmin, vmax
-
-
-class SymmetricalLogLocator(Locator):
- """
- Determine the tick locations for symmetric log axes
- """
-
- def __init__(self, transform=None, subs=None, linthresh=None, base=None):
- """
- place ticks on the location= base**i*subs[j]
- """
- if transform is not None:
- self._base = transform.base
- self._linthresh = transform.linthresh
- elif linthresh is not None and base is not None:
- self._base = base
- self._linthresh = linthresh
- else:
- raise ValueError("Either transform, or both linthresh "
- "and base, must be provided.")
- if subs is None:
- self._subs = [1.0]
- else:
- self._subs = subs
- self.numticks = 15
-
- def set_params(self, subs=None, numticks=None):
- """Set parameters within this locator."""
- if numticks is not None:
- self.numticks = numticks
- if subs is not None:
- self._subs = subs
-
- def __call__(self):
- 'Return the locations of the ticks'
- # Note, these are untransformed coordinates
- vmin, vmax = self.axis.get_view_interval()
- return self.tick_values(vmin, vmax)
-
- def tick_values(self, vmin, vmax):
- b = self._base
- t = self._linthresh
-
- if vmax < vmin:
- vmin, vmax = vmax, vmin
-
- # The domain is divided into three sections, only some of
- # which may actually be present.
- #
- # <======== -t ==0== t ========>
- # aaaaaaaaa bbbbb ccccccccc
- #
- # a) and c) will have ticks at integral log positions. The
- # number of ticks needs to be reduced if there are more
- # than self.numticks of them.
- #
- # b) has a tick at 0 and only 0 (we assume t is a small
- # number, and the linear segment is just an implementation
- # detail and not interesting.)
- #
- # We could also add ticks at t, but that seems to usually be
- # uninteresting.
- #
- # "simple" mode is when the range falls entirely within (-t,
- # t) -- it should just display (vmin, 0, vmax)
-
- has_a = has_b = has_c = False
- if vmin < -t:
- has_a = True
- if vmax > -t:
- has_b = True
- if vmax > t:
- has_c = True
- elif vmin < 0:
- if vmax > 0:
- has_b = True
- if vmax > t:
- has_c = True
- else:
- return [vmin, vmax]
- elif vmin < t:
- if vmax > t:
- has_b = True
- has_c = True
- else:
- return [vmin, vmax]
- else:
- has_c = True
-
- def get_log_range(lo, hi):
- lo = np.floor(np.log(lo) / np.log(b))
- hi = np.ceil(np.log(hi) / np.log(b))
- return lo, hi
-
- # First, calculate all the ranges, so we can determine striding
- if has_a:
- if has_b:
- a_range = get_log_range(t, -vmin + 1)
- else:
- a_range = get_log_range(-vmax, -vmin + 1)
- else:
- a_range = (0, 0)
-
- if has_c:
- if has_b:
- c_range = get_log_range(t, vmax + 1)
- else:
- c_range = get_log_range(vmin, vmax + 1)
- else:
- c_range = (0, 0)
-
- total_ticks = (a_range[1] - a_range[0]) + (c_range[1] - c_range[0])
- if has_b:
- total_ticks += 1
- stride = max(total_ticks // (self.numticks - 1), 1)
-
- decades = []
- if has_a:
- decades.extend(-1 * (b ** (np.arange(a_range[0], a_range[1],
- stride)[::-1])))
-
- if has_b:
- decades.append(0.0)
-
- if has_c:
- decades.extend(b ** (np.arange(c_range[0], c_range[1], stride)))
-
- # Add the subticks if requested
- if self._subs is None:
- subs = np.arange(2.0, b)
- else:
- subs = np.asarray(self._subs)
-
- if len(subs) > 1 or subs[0] != 1.0:
- ticklocs = []
- for decade in decades:
- if decade == 0:
- ticklocs.append(decade)
- else:
- ticklocs.extend(subs * decade)
- else:
- ticklocs = decades
-
- return self.raise_if_exceeds(np.array(ticklocs))
-
- def view_limits(self, vmin, vmax):
- 'Try to choose the view limits intelligently'
- b = self._base
- if vmax < vmin:
- vmin, vmax = vmax, vmin
-
- if rcParams['axes.autolimit_mode'] == 'round_numbers':
- if not is_decade(abs(vmin), b):
- if vmin < 0:
- vmin = -decade_up(-vmin, b)
- else:
- vmin = decade_down(vmin, b)
- if not is_decade(abs(vmax), b):
- if vmax < 0:
- vmax = -decade_down(-vmax, b)
- else:
- vmax = decade_up(vmax, b)
-
- if vmin == vmax:
- if vmin < 0:
- vmin = -decade_up(-vmin, b)
- vmax = -decade_down(-vmax, b)
- else:
- vmin = decade_down(vmin, b)
- vmax = decade_up(vmax, b)
-
- result = mtransforms.nonsingular(vmin, vmax)
- return result
-
-
-class LogitLocator(Locator):
- """
- Determine the tick locations for logit axes
- """
-
- def __init__(self, minor=False):
- """
- place ticks on the logit locations
- """
- self.minor = minor
-
- def set_params(self, minor=None):
- """Set parameters within this locator."""
- if minor is not None:
- self.minor = minor
-
- def __call__(self):
- 'Return the locations of the ticks'
- vmin, vmax = self.axis.get_view_interval()
- return self.tick_values(vmin, vmax)
-
- def tick_values(self, vmin, vmax):
- # dummy axis has no axes attribute
- if hasattr(self.axis, 'axes') and self.axis.axes.name == 'polar':
- raise NotImplementedError('Polar axis cannot be logit scaled yet')
-
- vmin, vmax = self.nonsingular(vmin, vmax)
- vmin = np.log10(vmin / (1 - vmin))
- vmax = np.log10(vmax / (1 - vmax))
-
- decade_min = np.floor(vmin)
- decade_max = np.ceil(vmax)
-
- # major ticks
- if not self.minor:
- ticklocs = []
- if (decade_min <= -1):
- expo = np.arange(decade_min, min(0, decade_max + 1))
- ticklocs.extend(list(10**expo))
- if (decade_min <= 0) and (decade_max >= 0):
- ticklocs.append(0.5)
- if (decade_max >= 1):
- expo = -np.arange(max(1, decade_min), decade_max + 1)
- ticklocs.extend(list(1 - 10**expo))
-
- # minor ticks
- else:
- ticklocs = []
- if (decade_min <= -2):
- expo = np.arange(decade_min, min(-1, decade_max))
- newticks = np.outer(np.arange(2, 10), 10**expo).ravel()
- ticklocs.extend(list(newticks))
- if (decade_min <= 0) and (decade_max >= 0):
- ticklocs.extend([0.2, 0.3, 0.4, 0.6, 0.7, 0.8])
- if (decade_max >= 2):
- expo = -np.arange(max(2, decade_min), decade_max + 1)
- newticks = 1 - np.outer(np.arange(2, 10), 10**expo).ravel()
- ticklocs.extend(list(newticks))
-
- return self.raise_if_exceeds(np.array(ticklocs))
-
- def nonsingular(self, vmin, vmax):
- initial_range = (1e-7, 1 - 1e-7)
- if not np.isfinite(vmin) or not np.isfinite(vmax):
- return initial_range # no data plotted yet
-
- if vmin > vmax:
- vmin, vmax = vmax, vmin
-
- # what to do if a window beyond ]0, 1[ is chosen
- if self.axis is not None:
- minpos = self.axis.get_minpos()
- if not np.isfinite(minpos):
- return initial_range # again, no data plotted
- else:
- minpos = 1e-7 # should not occur in normal use
-
- # NOTE: for vmax, we should query a property similar to get_minpos, but
- # related to the maximal, less-than-one data point. Unfortunately,
- # Bbox._minpos is defined very deep in the BBox and updated with data,
- # so for now we use 1 - minpos as a substitute.
-
- if vmin <= 0:
- vmin = minpos
- if vmax >= 1:
- vmax = 1 - minpos
- if vmin == vmax:
- return 0.1 * vmin, 1 - 0.1 * vmin
-
- return vmin, vmax
-
-
-class AutoLocator(MaxNLocator):
- """
- Dynamically find major tick positions. This is actually a subclass
- of `~matplotlib.ticker.MaxNLocator`, with parameters *nbins = 'auto'*
- and *steps = [1, 2, 2.5, 5, 10]*.
- """
- def __init__(self):
- """
- To know the values of the non-public parameters, please have a
- look to the defaults of `~matplotlib.ticker.MaxNLocator`.
- """
- if rcParams['_internal.classic_mode']:
- nbins = 9
- steps = [1, 2, 5, 10]
- else:
- nbins = 'auto'
- steps = [1, 2, 2.5, 5, 10]
- MaxNLocator.__init__(self, nbins=nbins, steps=steps)
-
-
-class AutoMinorLocator(Locator):
- """
- Dynamically find minor tick positions based on the positions of
- major ticks. The scale must be linear with major ticks evenly spaced.
- """
- def __init__(self, n=None):
- """
- *n* is the number of subdivisions of the interval between
- major ticks; e.g., n=2 will place a single minor tick midway
- between major ticks.
-
- If *n* is omitted or None, it will be set to 5 or 4.
- """
- self.ndivs = n
-
- def __call__(self):
- 'Return the locations of the ticks'
- if self.axis.get_scale() == 'log':
- warnings.warn('AutoMinorLocator does not work with logarithmic '
- 'scale')
- return []
-
- majorlocs = self.axis.get_majorticklocs()
- try:
- majorstep = majorlocs[1] - majorlocs[0]
- except IndexError:
- # Need at least two major ticks to find minor tick locations
- # TODO: Figure out a way to still be able to display minor
- # ticks without two major ticks visible. For now, just display
- # no ticks at all.
- return []
-
- if self.ndivs is None:
- x = int(np.round(10 ** (np.log10(majorstep) % 1)))
- if x in [1, 5, 10]:
- ndivs = 5
- else:
- ndivs = 4
- else:
- ndivs = self.ndivs
-
- minorstep = majorstep / ndivs
-
- vmin, vmax = self.axis.get_view_interval()
- if vmin > vmax:
- vmin, vmax = vmax, vmin
-
- t0 = majorlocs[0]
- tmin = ((vmin - t0) // minorstep + 1) * minorstep
- tmax = ((vmax - t0) // minorstep + 1) * minorstep
- locs = np.arange(tmin, tmax, minorstep) + t0
- mod = np.abs((locs - t0) % majorstep)
- cond1 = mod > minorstep / 10.0
- cond2 = ~np.isclose(mod, majorstep, atol=0)
- locs = locs.compress(cond1 & cond2)
-
- return self.raise_if_exceeds(np.array(locs))
-
- def tick_values(self, vmin, vmax):
- raise NotImplementedError('Cannot get tick locations for a '
- '%s type.' % type(self))
-
-
-class OldAutoLocator(Locator):
- """
- On autoscale this class picks the best MultipleLocator to set the
- view limits and the tick locs.
-
- """
- def __init__(self):
- self._locator = LinearLocator()
-
- def __call__(self):
- 'Return the locations of the ticks'
- self.refresh()
- return self.raise_if_exceeds(self._locator())
-
- def tick_values(self, vmin, vmax):
- raise NotImplementedError('Cannot get tick locations for a '
- '%s type.' % type(self))
-
- def refresh(self):
- 'refresh internal information based on current lim'
- vmin, vmax = self.axis.get_view_interval()
- vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05)
- d = abs(vmax - vmin)
- self._locator = self.get_locator(d)
-
- def view_limits(self, vmin, vmax):
- 'Try to choose the view limits intelligently'
-
- d = abs(vmax - vmin)
- self._locator = self.get_locator(d)
- return self._locator.view_limits(vmin, vmax)
-
- def get_locator(self, d):
- 'pick the best locator based on a distance'
- d = abs(d)
- if d <= 0:
- locator = MultipleLocator(0.2)
- else:
-
- try:
- ld = math.log10(d)
- except OverflowError:
- raise RuntimeError('AutoLocator illegal data interval range')
-
- fld = math.floor(ld)
- base = 10 ** fld
-
- #if ld==fld: base = 10**(fld-1)
- #else: base = 10**fld
-
- if d >= 5 * base:
- ticksize = base
- elif d >= 2 * base:
- ticksize = base / 2.0
- else:
- ticksize = base / 5.0
- locator = MultipleLocator(ticksize)
-
- return locator
diff --git a/contrib/python/matplotlib/py2/matplotlib/tight_bbox.py b/contrib/python/matplotlib/py2/matplotlib/tight_bbox.py
deleted file mode 100644
index 7bffb35312..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/tight_bbox.py
+++ /dev/null
@@ -1,87 +0,0 @@
-"""
-This module is to support *bbox_inches* option in savefig command.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from matplotlib.transforms import Bbox, TransformedBbox, Affine2D
-
-
-def adjust_bbox(fig, bbox_inches, fixed_dpi=None):
- """
- Temporarily adjust the figure so that only the specified area
- (bbox_inches) is saved.
-
- It modifies fig.bbox, fig.bbox_inches,
- fig.transFigure._boxout, and fig.patch. While the figure size
- changes, the scale of the original figure is conserved. A
- function which restores the original values are returned.
- """
-
- origBbox = fig.bbox
- origBboxInches = fig.bbox_inches
- _boxout = fig.transFigure._boxout
-
- asp_list = []
- locator_list = []
- for ax in fig.axes:
- pos = ax.get_position(original=False).frozen()
- locator_list.append(ax.get_axes_locator())
- asp_list.append(ax.get_aspect())
-
- def _l(a, r, pos=pos):
- return pos
- ax.set_axes_locator(_l)
- ax.set_aspect("auto")
-
- def restore_bbox():
-
- for ax, asp, loc in zip(fig.axes, asp_list, locator_list):
- ax.set_aspect(asp)
- ax.set_axes_locator(loc)
-
- fig.bbox = origBbox
- fig.bbox_inches = origBboxInches
- fig.transFigure._boxout = _boxout
- fig.transFigure.invalidate()
- fig.patch.set_bounds(0, 0, 1, 1)
-
- if fixed_dpi is not None:
- tr = Affine2D().scale(fixed_dpi)
- dpi_scale = fixed_dpi / fig.dpi
- else:
- tr = Affine2D().scale(fig.dpi)
- dpi_scale = 1.
-
- _bbox = TransformedBbox(bbox_inches, tr)
-
- fig.bbox_inches = Bbox.from_bounds(0, 0,
- bbox_inches.width, bbox_inches.height)
- x0, y0 = _bbox.x0, _bbox.y0
- w1, h1 = fig.bbox.width * dpi_scale, fig.bbox.height * dpi_scale
- fig.transFigure._boxout = Bbox.from_bounds(-x0, -y0, w1, h1)
- fig.transFigure.invalidate()
-
- fig.bbox = TransformedBbox(fig.bbox_inches, tr)
-
- fig.patch.set_bounds(x0 / w1, y0 / h1,
- fig.bbox.width / w1, fig.bbox.height / h1)
-
- return restore_bbox
-
-
-def process_figure_for_rasterizing(fig, bbox_inches_restore, fixed_dpi=None):
- """
- This need to be called when figure dpi changes during the drawing
- (e.g., rasterizing). It recovers the bbox and re-adjust it with
- the new dpi.
- """
-
- bbox_inches, restore_bbox = bbox_inches_restore
- restore_bbox()
- r = adjust_bbox(fig, bbox_inches, fixed_dpi)
-
- return bbox_inches, r
diff --git a/contrib/python/matplotlib/py2/matplotlib/tight_layout.py b/contrib/python/matplotlib/py2/matplotlib/tight_layout.py
deleted file mode 100644
index 1c18dc63c3..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/tight_layout.py
+++ /dev/null
@@ -1,381 +0,0 @@
-"""
-This module provides routines to adjust subplot params so that subplots are
-nicely fit in the figure. In doing so, only axis labels, tick labels, axes
-titles and offsetboxes that are anchored to axes are currently considered.
-
-Internally, it assumes that the margins (left_margin, etc.) which are
-differences between ax.get_tightbbox and ax.bbox are independent of axes
-position. This may fail if Axes.adjustable is datalim. Also, This will fail
-for some cases (for example, left or right margin is affected by xlabel).
-"""
-
-import warnings
-
-import matplotlib
-from matplotlib.transforms import TransformedBbox, Bbox
-
-from matplotlib.font_manager import FontProperties
-rcParams = matplotlib.rcParams
-
-
-def _get_left(tight_bbox, axes_bbox):
- return axes_bbox.xmin - tight_bbox.xmin
-
-
-def _get_right(tight_bbox, axes_bbox):
- return tight_bbox.xmax - axes_bbox.xmax
-
-
-def _get_bottom(tight_bbox, axes_bbox):
- return axes_bbox.ymin - tight_bbox.ymin
-
-
-def _get_top(tight_bbox, axes_bbox):
- return tight_bbox.ymax - axes_bbox.ymax
-
-
-def auto_adjust_subplotpars(
- fig, renderer, nrows_ncols, num1num2_list, subplot_list,
- ax_bbox_list=None, pad=1.08, h_pad=None, w_pad=None, rect=None):
- """
- Return a dict of subplot parameters to adjust spacing between subplots.
-
- Note that this function ignores geometry information of subplot
- itself, but uses what is given by the *nrows_ncols* and *num1num2_list*
- parameters. Also, the results could be incorrect if some subplots have
- ``adjustable=datalim``.
-
- Parameters
- ----------
- nrows_ncols : Tuple[int, int]
- Number of rows and number of columns of the grid.
- num1num2_list : List[int]
- List of numbers specifying the area occupied by the subplot
- subplot_list : list of subplots
- List of subplots that will be used to calculate optimal subplot_params.
- pad : float
- Padding between the figure edge and the edges of subplots, as a
- fraction of the font size.
- h_pad, w_pad : float
- Padding (height/width) between edges of adjacent subplots, as a
- fraction of the font size. Defaults to *pad*.
- rect : Tuple[float, float, float, float]
- [left, bottom, right, top] in normalized (0, 1) figure coordinates.
- """
- rows, cols = nrows_ncols
-
- font_size_inches = (
- FontProperties(size=rcParams["font.size"]).get_size_in_points() / 72)
- pad_inches = pad * font_size_inches
- if h_pad is not None:
- vpad_inches = h_pad * font_size_inches
- else:
- vpad_inches = pad_inches
-
- if w_pad is not None:
- hpad_inches = w_pad * font_size_inches
- else:
- hpad_inches = pad_inches
-
- if len(num1num2_list) != len(subplot_list) or len(subplot_list) == 0:
- raise ValueError
-
- if rect is None:
- margin_left = margin_bottom = margin_right = margin_top = None
- else:
- margin_left, margin_bottom, _right, _top = rect
- if _right:
- margin_right = 1 - _right
- else:
- margin_right = None
- if _top:
- margin_top = 1 - _top
- else:
- margin_top = None
-
- vspaces = [[] for i in range((rows + 1) * cols)]
- hspaces = [[] for i in range(rows * (cols + 1))]
-
- union = Bbox.union
-
- if ax_bbox_list is None:
- ax_bbox_list = []
- for subplots in subplot_list:
- ax_bbox = union([ax.get_position(original=True)
- for ax in subplots])
- ax_bbox_list.append(ax_bbox)
-
- for subplots, ax_bbox, (num1, num2) in zip(subplot_list,
- ax_bbox_list,
- num1num2_list):
- if all([not ax.get_visible() for ax in subplots]):
- continue
-
- tight_bbox_raw = union([ax.get_tightbbox(renderer) for ax in subplots
- if ax.get_visible()])
- tight_bbox = TransformedBbox(tight_bbox_raw,
- fig.transFigure.inverted())
-
- row1, col1 = divmod(num1, cols)
-
- if num2 is None:
- # left
- hspaces[row1 * (cols + 1) + col1].append(
- _get_left(tight_bbox, ax_bbox))
- # right
- hspaces[row1 * (cols + 1) + (col1 + 1)].append(
- _get_right(tight_bbox, ax_bbox))
- # top
- vspaces[row1 * cols + col1].append(
- _get_top(tight_bbox, ax_bbox))
- # bottom
- vspaces[(row1 + 1) * cols + col1].append(
- _get_bottom(tight_bbox, ax_bbox))
-
- else:
- row2, col2 = divmod(num2, cols)
-
- for row_i in range(row1, row2 + 1):
- # left
- hspaces[row_i * (cols + 1) + col1].append(
- _get_left(tight_bbox, ax_bbox))
- # right
- hspaces[row_i * (cols + 1) + (col2 + 1)].append(
- _get_right(tight_bbox, ax_bbox))
- for col_i in range(col1, col2 + 1):
- # top
- vspaces[row1 * cols + col_i].append(
- _get_top(tight_bbox, ax_bbox))
- # bottom
- vspaces[(row2 + 1) * cols + col_i].append(
- _get_bottom(tight_bbox, ax_bbox))
-
- fig_width_inch, fig_height_inch = fig.get_size_inches()
-
- # margins can be negative for axes with aspect applied. And we
- # append + [0] to make minimum margins 0
-
- if not margin_left:
- margin_left = max([sum(s) for s in hspaces[::cols + 1]] + [0])
- margin_left += pad_inches / fig_width_inch
-
- if not margin_right:
- margin_right = max([sum(s) for s in hspaces[cols::cols + 1]] + [0])
- margin_right += pad_inches / fig_width_inch
-
- if not margin_top:
- margin_top = max([sum(s) for s in vspaces[:cols]] + [0])
- margin_top += pad_inches / fig_height_inch
-
- if not margin_bottom:
- margin_bottom = max([sum(s) for s in vspaces[-cols:]] + [0])
- margin_bottom += pad_inches / fig_height_inch
-
- if margin_left + margin_right >= 1:
- margin_left = 0.4999
- margin_right = 0.4999
- warnings.warn('The left and right margins cannot be made large '
- 'enough to accommodate all axes decorations. ')
- if margin_bottom + margin_top >= 1:
- margin_bottom = 0.4999
- margin_top = 0.4999
- warnings.warn('The bottom and top margins cannot be made large '
- 'enough to accommodate all axes decorations. ')
-
- kwargs = dict(left=margin_left,
- right=1 - margin_right,
- bottom=margin_bottom,
- top=1 - margin_top)
- if cols > 1:
- hspace = (
- max(sum(s)
- for i in range(rows)
- for s in hspaces[i * (cols + 1) + 1:(i + 1) * (cols + 1) - 1])
- + hpad_inches / fig_width_inch)
- # axes widths:
- h_axes = (1 - margin_right - margin_left - hspace * (cols - 1)) / cols
- if h_axes < 0:
- warnings.warn('tight_layout cannot make axes width small enough '
- 'to accommodate all axes decorations')
- kwargs["wspace"] = 0.5
- else:
- kwargs["wspace"] = hspace / h_axes
-
- if rows > 1:
- vspace = (max(sum(s) for s in vspaces[cols:-cols])
- + vpad_inches / fig_height_inch)
- v_axes = (1 - margin_top - margin_bottom - vspace * (rows - 1)) / rows
- if v_axes < 0:
- warnings.warn('tight_layout cannot make axes height small enough '
- 'to accommodate all axes decorations')
- kwargs["hspace"] = 0.5
- else:
- kwargs["hspace"] = vspace / v_axes
-
- return kwargs
-
-
-def get_renderer(fig):
- if fig._cachedRenderer:
- renderer = fig._cachedRenderer
- else:
- canvas = fig.canvas
-
- if canvas and hasattr(canvas, "get_renderer"):
- renderer = canvas.get_renderer()
- else:
- # not sure if this can happen
- warnings.warn("tight_layout : falling back to Agg renderer")
- from matplotlib.backends.backend_agg import FigureCanvasAgg
- canvas = FigureCanvasAgg(fig)
- renderer = canvas.get_renderer()
-
- return renderer
-
-
-def get_subplotspec_list(axes_list, grid_spec=None):
- """Return a list of subplotspec from the given list of axes.
-
- For an instance of axes that does not support subplotspec, None is inserted
- in the list.
-
- If grid_spec is given, None is inserted for those not from the given
- grid_spec.
- """
- subplotspec_list = []
- for ax in axes_list:
- axes_or_locator = ax.get_axes_locator()
- if axes_or_locator is None:
- axes_or_locator = ax
-
- if hasattr(axes_or_locator, "get_subplotspec"):
- subplotspec = axes_or_locator.get_subplotspec()
- subplotspec = subplotspec.get_topmost_subplotspec()
- gs = subplotspec.get_gridspec()
- if grid_spec is not None:
- if gs != grid_spec:
- subplotspec = None
- elif gs.locally_modified_subplot_params():
- subplotspec = None
- else:
- subplotspec = None
-
- subplotspec_list.append(subplotspec)
-
- return subplotspec_list
-
-
-def get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer,
- pad=1.08, h_pad=None, w_pad=None, rect=None):
- """
- Return subplot parameters for tight-layouted-figure with specified padding.
-
- Parameters
- ----------
- fig : Figure
- axes_list : list of Axes
- subplotspec_list : list of `.SubplotSpec`
- The subplotspecs of each axes.
- renderer : renderer
- pad : float
- Padding between the figure edge and the edges of subplots, as a
- fraction of the font size.
- h_pad, w_pad : float
- Padding (height/width) between edges of adjacent subplots. Defaults to
- *pad_inches*.
- rect : Tuple[float, float, float, float], optional
- (left, bottom, right, top) rectangle in normalized figure coordinates
- that the whole subplots area (including labels) will fit into.
- Defaults to using the entire figure.
- """
-
- subplot_list = []
- nrows_list = []
- ncols_list = []
- ax_bbox_list = []
-
- subplot_dict = {} # Multiple axes can share same subplot_interface (e.g.,
- # axes_grid1); thus we need to join them together.
-
- subplotspec_list2 = []
-
- for ax, subplotspec in zip(axes_list,
- subplotspec_list):
- if subplotspec is None:
- continue
-
- subplots = subplot_dict.setdefault(subplotspec, [])
-
- if not subplots:
- myrows, mycols, _, _ = subplotspec.get_geometry()
- nrows_list.append(myrows)
- ncols_list.append(mycols)
- subplotspec_list2.append(subplotspec)
- subplot_list.append(subplots)
- ax_bbox_list.append(subplotspec.get_position(fig))
-
- subplots.append(ax)
-
- if (len(nrows_list) == 0) or (len(ncols_list) == 0):
- return {}
-
- max_nrows = max(nrows_list)
- max_ncols = max(ncols_list)
-
- num1num2_list = []
- for subplotspec in subplotspec_list2:
- rows, cols, num1, num2 = subplotspec.get_geometry()
- div_row, mod_row = divmod(max_nrows, rows)
- div_col, mod_col = divmod(max_ncols, cols)
- if (mod_row != 0) or (mod_col != 0):
- raise RuntimeError("")
-
- rowNum1, colNum1 = divmod(num1, cols)
- if num2 is None:
- rowNum2, colNum2 = rowNum1, colNum1
- else:
- rowNum2, colNum2 = divmod(num2, cols)
-
- num1num2_list.append((rowNum1 * div_row * max_ncols +
- colNum1 * div_col,
- ((rowNum2 + 1) * div_row - 1) * max_ncols +
- (colNum2 + 1) * div_col - 1))
-
- kwargs = auto_adjust_subplotpars(fig, renderer,
- nrows_ncols=(max_nrows, max_ncols),
- num1num2_list=num1num2_list,
- subplot_list=subplot_list,
- ax_bbox_list=ax_bbox_list,
- pad=pad, h_pad=h_pad, w_pad=w_pad)
-
- if rect is not None:
- # if rect is given, the whole subplots area (including
- # labels) will fit into the rect instead of the
- # figure. Note that the rect argument of
- # *auto_adjust_subplotpars* specify the area that will be
- # covered by the total area of axes.bbox. Thus we call
- # auto_adjust_subplotpars twice, where the second run
- # with adjusted rect parameters.
-
- left, bottom, right, top = rect
- if left is not None:
- left += kwargs["left"]
- if bottom is not None:
- bottom += kwargs["bottom"]
- if right is not None:
- right -= (1 - kwargs["right"])
- if top is not None:
- top -= (1 - kwargs["top"])
-
- #if h_pad is None: h_pad = pad
- #if w_pad is None: w_pad = pad
-
- kwargs = auto_adjust_subplotpars(fig, renderer,
- nrows_ncols=(max_nrows, max_ncols),
- num1num2_list=num1num2_list,
- subplot_list=subplot_list,
- ax_bbox_list=ax_bbox_list,
- pad=pad, h_pad=h_pad, w_pad=w_pad,
- rect=(left, bottom, right, top))
-
- return kwargs
diff --git a/contrib/python/matplotlib/py2/matplotlib/transforms.py b/contrib/python/matplotlib/py2/matplotlib/transforms.py
deleted file mode 100644
index 65d741ed75..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/transforms.py
+++ /dev/null
@@ -1,3025 +0,0 @@
-"""
-matplotlib includes a framework for arbitrary geometric
-transformations that is used determine the final position of all
-elements drawn on the canvas.
-
-Transforms are composed into trees of :class:`TransformNode` objects
-whose actual value depends on their children. When the contents of
-children change, their parents are automatically invalidated. The
-next time an invalidated transform is accessed, it is recomputed to
-reflect those changes. This invalidation/caching approach prevents
-unnecessary recomputations of transforms, and contributes to better
-interactive performance.
-
-For example, here is a graph of the transform tree used to plot data
-to the graph:
-
-.. image:: ../_static/transforms.png
-
-The framework can be used for both affine and non-affine
-transformations. However, for speed, we want use the backend
-renderers to perform affine transformations whenever possible.
-Therefore, it is possible to perform just the affine or non-affine
-part of a transformation on a set of data. The affine is always
-assumed to occur after the non-affine. For any transform::
-
- full transform == non-affine part + affine part
-
-The backends are not expected to handle non-affine transformations
-themselves.
-"""
-
-# Note: There are a number of places in the code where we use `np.min` or
-# `np.minimum` instead of the builtin `min`, and likewise for `max`. This is
-# done so that `nan`s are propagated, instead of being silently dropped.
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import numpy as np
-from matplotlib._path import (affine_transform, count_bboxes_overlapping_bbox,
- update_path_extents)
-from numpy.linalg import inv
-
-import re
-import weakref
-import warnings
-
-from . import cbook
-from .path import Path
-
-DEBUG = False
-
-
-def _indent_str(obj): # textwrap.indent(str(obj), 4) on Py3.
- return re.sub("(^|\n)", r"\1 ", str(obj))
-
-
-class TransformNode(object):
- """
- :class:`TransformNode` is the base class for anything that
- participates in the transform tree and needs to invalidate its
- parents or be invalidated. This includes classes that are not
- really transforms, such as bounding boxes, since some transforms
- depend on bounding boxes to compute their values.
- """
- _gid = 0
-
- # Invalidation may affect only the affine part. If the
- # invalidation was "affine-only", the _invalid member is set to
- # INVALID_AFFINE_ONLY
- INVALID_NON_AFFINE = 1
- INVALID_AFFINE = 2
- INVALID = INVALID_NON_AFFINE | INVALID_AFFINE
-
- # Some metadata about the transform, used to determine whether an
- # invalidation is affine-only
- is_affine = False
- is_bbox = False
-
- pass_through = False
- """
- If pass_through is True, all ancestors will always be
- invalidated, even if 'self' is already invalid.
- """
-
- def __init__(self, shorthand_name=None):
- """
- Creates a new :class:`TransformNode`.
-
- Parameters
- ----------
- shorthand_name : str
- A string representing the "name" of the transform. The name carries
- no significance other than to improve the readability of
- ``str(transform)`` when DEBUG=True.
- """
- self._parents = {}
-
- # TransformNodes start out as invalid until their values are
- # computed for the first time.
- self._invalid = 1
- self._shorthand_name = shorthand_name or ''
-
- if DEBUG:
- def __str__(self):
- # either just return the name of this TransformNode, or it's repr
- return self._shorthand_name or repr(self)
-
- def __getstate__(self):
- d = self.__dict__.copy()
- # turn the dictionary with weak values into a normal dictionary
- d['_parents'] = dict((k, v()) for (k, v) in
- six.iteritems(self._parents))
- return d
-
- def __setstate__(self, data_dict):
- self.__dict__ = data_dict
- # turn the normal dictionary back into a dictionary with weak
- # values
- self._parents = dict((k, weakref.ref(v)) for (k, v) in
- six.iteritems(self._parents) if v is not None)
-
- def __copy__(self, *args):
- raise NotImplementedError(
- "TransformNode instances can not be copied. "
- "Consider using frozen() instead.")
- __deepcopy__ = __copy__
-
- def invalidate(self):
- """
- Invalidate this :class:`TransformNode` and triggers an
- invalidation of its ancestors. Should be called any
- time the transform changes.
- """
- value = self.INVALID
- if self.is_affine:
- value = self.INVALID_AFFINE
- return self._invalidate_internal(value, invalidating_node=self)
-
- def _invalidate_internal(self, value, invalidating_node):
- """
- Called by :meth:`invalidate` and subsequently ascends the transform
- stack calling each TransformNode's _invalidate_internal method.
- """
- # determine if this call will be an extension to the invalidation
- # status. If not, then a shortcut means that we needn't invoke an
- # invalidation up the transform stack as it will already have been
- # invalidated.
-
- # N.B This makes the invalidation sticky, once a transform has been
- # invalidated as NON_AFFINE, then it will always be invalidated as
- # NON_AFFINE even when triggered with a AFFINE_ONLY invalidation.
- # In most cases this is not a problem (i.e. for interactive panning and
- # zooming) and the only side effect will be on performance.
- status_changed = self._invalid < value
-
- if self.pass_through or status_changed:
- self._invalid = value
-
- for parent in list(six.itervalues(self._parents)):
- # Dereference the weak reference
- parent = parent()
- if parent is not None:
- parent._invalidate_internal(
- value=value, invalidating_node=self)
-
- def set_children(self, *children):
- """
- Set the children of the transform, to let the invalidation
- system know which transforms can invalidate this transform.
- Should be called from the constructor of any transforms that
- depend on other transforms.
- """
- # Parents are stored as weak references, so that if the
- # parents are destroyed, references from the children won't
- # keep them alive.
- for child in children:
- child._parents[id(self)] = weakref.ref(self)
-
- if DEBUG:
- _set_children = set_children
-
- def set_children(self, *children):
- self._set_children(*children)
- self._children = children
- set_children.__doc__ = _set_children.__doc__
-
- def frozen(self):
- """
- Returns a frozen copy of this transform node. The frozen copy
- will not update when its children change. Useful for storing
- a previously known state of a transform where
- ``copy.deepcopy()`` might normally be used.
- """
- return self
-
- if DEBUG:
- def write_graphviz(self, fobj, highlight=[]):
- """
- For debugging purposes.
-
- Writes the transform tree rooted at 'self' to a graphviz "dot"
- format file. This file can be run through the "dot" utility
- to produce a graph of the transform tree.
-
- Affine transforms are marked in blue. Bounding boxes are
- marked in yellow.
-
- *fobj*: A Python file-like object
-
- Once the "dot" file has been created, it can be turned into a
- png easily with::
-
- $> dot -Tpng -o $OUTPUT_FILE $DOT_FILE
-
- """
- seen = set()
-
- def recurse(root):
- if root in seen:
- return
- seen.add(root)
- props = {}
- label = root.__class__.__name__
- if root._invalid:
- label = '[%s]' % label
- if root in highlight:
- props['style'] = 'bold'
- props['shape'] = 'box'
- props['label'] = '"%s"' % label
- props = ' '.join(['%s=%s' % (key, val)
- for key, val
- in six.iteritems(props)])
-
- fobj.write('%s [%s];\n' %
- (hash(root), props))
-
- if hasattr(root, '_children'):
- for child in root._children:
- name = '?'
- for key, val in six.iteritems(root.__dict__):
- if val is child:
- name = key
- break
- fobj.write('"%s" -> "%s" [label="%s", fontsize=10];\n'
- % (hash(root),
- hash(child),
- name))
- recurse(child)
-
- fobj.write("digraph G {\n")
- recurse(self)
- fobj.write("}\n")
-
-
-class BboxBase(TransformNode):
- """
- This is the base class of all bounding boxes, and provides
- read-only access to its data. A mutable bounding box is provided
- by the :class:`Bbox` class.
-
- The canonical representation is as two points, with no
- restrictions on their ordering. Convenience properties are
- provided to get the left, bottom, right and top edges and width
- and height, but these are not stored explicitly.
- """
- is_bbox = True
- is_affine = True
-
- if DEBUG:
- def _check(points):
- if isinstance(points, np.ma.MaskedArray):
- warnings.warn("Bbox bounds are a masked array.")
- points = np.asarray(points)
- if (points[1, 0] - points[0, 0] == 0 or
- points[1, 1] - points[0, 1] == 0):
- warnings.warn("Singular Bbox.")
- _check = staticmethod(_check)
-
- def frozen(self):
- return Bbox(self.get_points().copy())
- frozen.__doc__ = TransformNode.__doc__
-
- def __array__(self, *args, **kwargs):
- return self.get_points()
-
- def is_unit(self):
- """
- Returns True if the :class:`Bbox` is the unit bounding box
- from (0, 0) to (1, 1).
- """
- return list(self.get_points().flatten()) == [0., 0., 1., 1.]
-
- @property
- def x0(self):
- """
- :attr:`x0` is the first of the pair of *x* coordinates that
- define the bounding box. :attr:`x0` is not guaranteed to be less than
- :attr:`x1`. If you require that, use :attr:`xmin`.
- """
- return self.get_points()[0, 0]
-
- @property
- def y0(self):
- """
- :attr:`y0` is the first of the pair of *y* coordinates that
- define the bounding box. :attr:`y0` is not guaranteed to be less than
- :attr:`y1`. If you require that, use :attr:`ymin`.
- """
- return self.get_points()[0, 1]
-
- @property
- def x1(self):
- """
- :attr:`x1` is the second of the pair of *x* coordinates that
- define the bounding box. :attr:`x1` is not guaranteed to be greater
- than :attr:`x0`. If you require that, use :attr:`xmax`.
- """
- return self.get_points()[1, 0]
-
- @property
- def y1(self):
- """
- :attr:`y1` is the second of the pair of *y* coordinates that
- define the bounding box. :attr:`y1` is not guaranteed to be greater
- than :attr:`y0`. If you require that, use :attr:`ymax`.
- """
- return self.get_points()[1, 1]
-
- @property
- def p0(self):
- """
- :attr:`p0` is the first pair of (*x*, *y*) coordinates that
- define the bounding box. It is not guaranteed to be the bottom-left
- corner. For that, use :attr:`min`.
- """
- return self.get_points()[0]
-
- @property
- def p1(self):
- """
- :attr:`p1` is the second pair of (*x*, *y*) coordinates that
- define the bounding box. It is not guaranteed to be the top-right
- corner. For that, use :attr:`max`.
- """
- return self.get_points()[1]
-
- @property
- def xmin(self):
- """
- :attr:`xmin` is the left edge of the bounding box.
- """
- return np.min(self.get_points()[:, 0])
-
- @property
- def ymin(self):
- """
- :attr:`ymin` is the bottom edge of the bounding box.
- """
- return np.min(self.get_points()[:, 1])
-
- @property
- def xmax(self):
- """
- :attr:`xmax` is the right edge of the bounding box.
- """
- return np.max(self.get_points()[:, 0])
-
- @property
- def ymax(self):
- """
- :attr:`ymax` is the top edge of the bounding box.
- """
- return np.max(self.get_points()[:, 1])
-
- @property
- def min(self):
- """
- :attr:`min` is the bottom-left corner of the bounding box.
- """
- return np.min(self.get_points(), axis=0)
-
- @property
- def max(self):
- """
- :attr:`max` is the top-right corner of the bounding box.
- """
- return np.max(self.get_points(), axis=0)
-
- @property
- def intervalx(self):
- """
- :attr:`intervalx` is the pair of *x* coordinates that define
- the bounding box. It is not guaranteed to be sorted from left to right.
- """
- return self.get_points()[:, 0]
-
- @property
- def intervaly(self):
- """
- :attr:`intervaly` is the pair of *y* coordinates that define
- the bounding box. It is not guaranteed to be sorted from bottom to
- top.
- """
- return self.get_points()[:, 1]
-
- @property
- def width(self):
- """
- The width of the bounding box. It may be negative if
- :attr:`x1` < :attr:`x0`.
- """
- points = self.get_points()
- return points[1, 0] - points[0, 0]
-
- @property
- def height(self):
- """
- The height of the bounding box. It may be negative if
- :attr:`y1` < :attr:`y0`.
- """
- points = self.get_points()
- return points[1, 1] - points[0, 1]
-
- @property
- def size(self):
- """
- The width and height of the bounding box. May be negative,
- in the same way as :attr:`width` and :attr:`height`.
- """
- points = self.get_points()
- return points[1] - points[0]
-
- @property
- def bounds(self):
- """
- Returns (:attr:`x0`, :attr:`y0`, :attr:`width`,
- :attr:`height`).
- """
- x0, y0, x1, y1 = self.get_points().flatten()
- return (x0, y0, x1 - x0, y1 - y0)
-
- @property
- def extents(self):
- """
- Returns (:attr:`x0`, :attr:`y0`, :attr:`x1`,
- :attr:`y1`).
- """
- return self.get_points().flatten().copy()
-
- def get_points(self):
- raise NotImplementedError
-
- def containsx(self, x):
- """
- Returns whether *x* is in the closed (:attr:`x0`, :attr:`x1`) interval.
- """
- x0, x1 = self.intervalx
- return x0 <= x <= x1 or x0 >= x >= x1
-
- def containsy(self, y):
- """
- Returns whether *y* is in the closed (:attr:`y0`, :attr:`y1`) interval.
- """
- y0, y1 = self.intervaly
- return y0 <= y <= y1 or y0 >= y >= y1
-
- def contains(self, x, y):
- """
- Returns whether ``(x, y)`` is in the bounding box or on its edge.
- """
- return self.containsx(x) and self.containsy(y)
-
- def overlaps(self, other):
- """
- Returns whether this bounding box overlaps with the other bounding box.
-
- Parameters
- ----------
- other : BboxBase
- """
- ax1, ay1, ax2, ay2 = self.extents
- bx1, by1, bx2, by2 = other.extents
- if ax2 < ax1:
- ax2, ax1 = ax1, ax2
- if ay2 < ay1:
- ay2, ay1 = ay1, ay2
- if bx2 < bx1:
- bx2, bx1 = bx1, bx2
- if by2 < by1:
- by2, by1 = by1, by2
- return ax1 <= bx2 and bx1 <= ax2 and ay1 <= by2 and by1 <= ay2
-
- def fully_containsx(self, x):
- """
- Returns whether *x* is in the open (:attr:`x0`, :attr:`x1`) interval.
- """
- x0, x1 = self.intervalx
- return x0 < x < x1 or x0 > x > x1
-
- def fully_containsy(self, y):
- """
- Returns whether *y* is in the open (:attr:`y0`, :attr:`y1`) interval.
- """
- y0, y1 = self.intervaly
- return y0 < y < y1 or y0 > y > y1
-
- def fully_contains(self, x, y):
- """
- Returns whether ``x, y`` is in the bounding box, but not on its edge.
- """
- return self.fully_containsx(x) and self.fully_containsy(y)
-
- def fully_overlaps(self, other):
- """
- Returns whether this bounding box overlaps with the other bounding box,
- not including the edges.
-
- Parameters
- ----------
- other : BboxBase
- """
- ax1, ay1, ax2, ay2 = self.extents
- bx1, by1, bx2, by2 = other.extents
- if ax2 < ax1:
- ax2, ax1 = ax1, ax2
- if ay2 < ay1:
- ay2, ay1 = ay1, ay2
- if bx2 < bx1:
- bx2, bx1 = bx1, bx2
- if by2 < by1:
- by2, by1 = by1, by2
- return ax1 < bx2 and bx1 < ax2 and ay1 < by2 and by1 < ay2
-
- def transformed(self, transform):
- """
- Return a new :class:`Bbox` object, statically transformed by
- the given transform.
- """
- pts = self.get_points()
- ll, ul, lr = transform.transform(np.array([pts[0],
- [pts[0, 0], pts[1, 1]], [pts[1, 0], pts[0, 1]]]))
- return Bbox([ll, [lr[0], ul[1]]])
-
- def inverse_transformed(self, transform):
- """
- Return a new :class:`Bbox` object, statically transformed by
- the inverse of the given transform.
- """
- return self.transformed(transform.inverted())
-
- coefs = {'C': (0.5, 0.5),
- 'SW': (0, 0),
- 'S': (0.5, 0),
- 'SE': (1.0, 0),
- 'E': (1.0, 0.5),
- 'NE': (1.0, 1.0),
- 'N': (0.5, 1.0),
- 'NW': (0, 1.0),
- 'W': (0, 0.5)}
-
- def anchored(self, c, container=None):
- """
- Return a copy of the :class:`Bbox`, shifted to position *c*
- within a container.
-
- Parameters
- ----------
- c :
- May be either:
-
- * A sequence (*cx*, *cy*) where *cx* and *cy* range from 0
- to 1, where 0 is left or bottom and 1 is right or top
-
- * a string:
- - 'C' for centered
- - 'S' for bottom-center
- - 'SE' for bottom-left
- - 'E' for left
- - etc.
-
- container : Bbox, optional
- The box within which the :class:`Bbox` is positioned; it defaults
- to the initial :class:`Bbox`.
- """
- if container is None:
- container = self
- l, b, w, h = container.bounds
- if isinstance(c, six.string_types):
- cx, cy = self.coefs[c]
- else:
- cx, cy = c
- L, B, W, H = self.bounds
- return Bbox(self._points +
- [(l + cx * (w - W)) - L,
- (b + cy * (h - H)) - B])
-
- def shrunk(self, mx, my):
- """
- Return a copy of the :class:`Bbox`, shrunk by the factor *mx*
- in the *x* direction and the factor *my* in the *y* direction.
- The lower left corner of the box remains unchanged. Normally
- *mx* and *my* will be less than 1, but this is not enforced.
- """
- w, h = self.size
- return Bbox([self._points[0],
- self._points[0] + [mx * w, my * h]])
-
- def shrunk_to_aspect(self, box_aspect, container=None, fig_aspect=1.0):
- """
- Return a copy of the :class:`Bbox`, shrunk so that it is as
- large as it can be while having the desired aspect ratio,
- *box_aspect*. If the box coordinates are relative---that
- is, fractions of a larger box such as a figure---then the
- physical aspect ratio of that figure is specified with
- *fig_aspect*, so that *box_aspect* can also be given as a
- ratio of the absolute dimensions, not the relative dimensions.
- """
- if box_aspect <= 0 or fig_aspect <= 0:
- raise ValueError("'box_aspect' and 'fig_aspect' must be positive")
- if container is None:
- container = self
- w, h = container.size
- H = w * box_aspect / fig_aspect
- if H <= h:
- W = w
- else:
- W = h * fig_aspect / box_aspect
- H = h
- return Bbox([self._points[0],
- self._points[0] + (W, H)])
-
- def splitx(self, *args):
- """
- e.g., ``bbox.splitx(f1, f2, ...)``
-
- Returns a list of new :class:`Bbox` objects formed by
- splitting the original one with vertical lines at fractional
- positions *f1*, *f2*, ...
- """
- xf = [0] + list(args) + [1]
- x0, y0, x1, y1 = self.extents
- w = x1 - x0
- return [Bbox([[x0 + xf0 * w, y0], [x0 + xf1 * w, y1]])
- for xf0, xf1 in zip(xf[:-1], xf[1:])]
-
- def splity(self, *args):
- """
- e.g., ``bbox.splitx(f1, f2, ...)``
-
- Returns a list of new :class:`Bbox` objects formed by
- splitting the original one with horizontal lines at fractional
- positions *f1*, *f2*, ...
- """
- yf = [0] + list(args) + [1]
- x0, y0, x1, y1 = self.extents
- h = y1 - y0
- return [Bbox([[x0, y0 + yf0 * h], [x1, y0 + yf1 * h]])
- for yf0, yf1 in zip(yf[:-1], yf[1:])]
-
- def count_contains(self, vertices):
- """
- Count the number of vertices contained in the :class:`Bbox`.
- Any vertices with a non-finite x or y value are ignored.
-
- Parameters
- ----------
- vertices : Nx2 Numpy array.
- """
- if len(vertices) == 0:
- return 0
- vertices = np.asarray(vertices)
- with np.errstate(invalid='ignore'):
- return (((self.min < vertices) &
- (vertices < self.max)).all(axis=1).sum())
-
- def count_overlaps(self, bboxes):
- """
- Count the number of bounding boxes that overlap this one.
-
- Parameters
- ----------
- bboxes : sequence of :class:`BboxBase` objects
- """
- return count_bboxes_overlapping_bbox(
- self, np.atleast_3d([np.array(x) for x in bboxes]))
-
- def expanded(self, sw, sh):
- """
- Return a new :class:`Bbox` which is this :class:`Bbox`
- expanded around its center by the given factors *sw* and
- *sh*.
- """
- width = self.width
- height = self.height
- deltaw = (sw * width - width) / 2.0
- deltah = (sh * height - height) / 2.0
- a = np.array([[-deltaw, -deltah], [deltaw, deltah]])
- return Bbox(self._points + a)
-
- def padded(self, p):
- """
- Return a new :class:`Bbox` that is padded on all four sides by
- the given value.
- """
- points = self.get_points()
- return Bbox(points + [[-p, -p], [p, p]])
-
- def translated(self, tx, ty):
- """
- Return a copy of the :class:`Bbox`, statically translated by
- *tx* and *ty*.
- """
- return Bbox(self._points + (tx, ty))
-
- def corners(self):
- """
- Return an array of points which are the four corners of this
- rectangle. For example, if this :class:`Bbox` is defined by
- the points (*a*, *b*) and (*c*, *d*), :meth:`corners` returns
- (*a*, *b*), (*a*, *d*), (*c*, *b*) and (*c*, *d*).
- """
- l, b, r, t = self.get_points().flatten()
- return np.array([[l, b], [l, t], [r, b], [r, t]])
-
- def rotated(self, radians):
- """
- Return a new bounding box that bounds a rotated version of
- this bounding box by the given radians. The new bounding box
- is still aligned with the axes, of course.
- """
- corners = self.corners()
- corners_rotated = Affine2D().rotate(radians).transform(corners)
- bbox = Bbox.unit()
- bbox.update_from_data_xy(corners_rotated, ignore=True)
- return bbox
-
- @staticmethod
- def union(bboxes):
- """
- Return a :class:`Bbox` that contains all of the given bboxes.
- """
- if not len(bboxes):
- raise ValueError("'bboxes' cannot be empty")
- x0 = np.min([bbox.xmin for bbox in bboxes])
- x1 = np.max([bbox.xmax for bbox in bboxes])
- y0 = np.min([bbox.ymin for bbox in bboxes])
- y1 = np.max([bbox.ymax for bbox in bboxes])
- return Bbox([[x0, y0], [x1, y1]])
-
- @staticmethod
- def intersection(bbox1, bbox2):
- """
- Return the intersection of the two bboxes or None
- if they do not intersect.
- """
- x0 = np.maximum(bbox1.xmin, bbox2.xmin)
- x1 = np.minimum(bbox1.xmax, bbox2.xmax)
- y0 = np.maximum(bbox1.ymin, bbox2.ymin)
- y1 = np.minimum(bbox1.ymax, bbox2.ymax)
- return Bbox([[x0, y0], [x1, y1]]) if x0 <= x1 and y0 <= y1 else None
-
-
-class Bbox(BboxBase):
- """
- A mutable bounding box.
- """
-
- def __init__(self, points, **kwargs):
- """
- Parameters
- ----------
- points : ndarray
- A 2x2 numpy array of the form ``[[x0, y0], [x1, y1]]``.
-
- Notes
- -----
- If you need to create a :class:`Bbox` object from another form
- of data, consider the static methods :meth:`unit`,
- :meth:`from_bounds` and :meth:`from_extents`.
- """
- BboxBase.__init__(self, **kwargs)
- points = np.asarray(points, float)
- if points.shape != (2, 2):
- raise ValueError('Bbox points must be of the form '
- '"[[x0, y0], [x1, y1]]".')
- self._points = points
- self._minpos = np.array([np.inf, np.inf])
- self._ignore = True
- # it is helpful in some contexts to know if the bbox is a
- # default or has been mutated; we store the orig points to
- # support the mutated methods
- self._points_orig = self._points.copy()
- if DEBUG:
- ___init__ = __init__
-
- def __init__(self, points, **kwargs):
- self._check(points)
- self.___init__(points, **kwargs)
-
- def invalidate(self):
- self._check(self._points)
- TransformNode.invalidate(self)
-
- @staticmethod
- def unit():
- """
- (staticmethod) Create a new unit :class:`Bbox` from (0, 0) to
- (1, 1).
- """
- return Bbox(np.array([[0.0, 0.0], [1.0, 1.0]], float))
-
- @staticmethod
- def null():
- """
- (staticmethod) Create a new null :class:`Bbox` from (inf, inf) to
- (-inf, -inf).
- """
- return Bbox(np.array([[np.inf, np.inf], [-np.inf, -np.inf]], float))
-
- @staticmethod
- def from_bounds(x0, y0, width, height):
- """
- (staticmethod) Create a new :class:`Bbox` from *x0*, *y0*,
- *width* and *height*.
-
- *width* and *height* may be negative.
- """
- return Bbox.from_extents(x0, y0, x0 + width, y0 + height)
-
- @staticmethod
- def from_extents(*args):
- """
- (staticmethod) Create a new Bbox from *left*, *bottom*,
- *right* and *top*.
-
- The *y*-axis increases upwards.
- """
- points = np.array(args, dtype=float).reshape(2, 2)
- return Bbox(points)
-
- def __format__(self, fmt):
- return (
- 'Bbox(x0={0.x0:{1}}, y0={0.y0:{1}}, x1={0.x1:{1}}, y1={0.y1:{1}})'.
- format(self, fmt))
-
- def __str__(self):
- return format(self, '')
-
- def __repr__(self):
- return 'Bbox([[{0.x0}, {0.y0}], [{0.x1}, {0.y1}]])'.format(self)
-
- def ignore(self, value):
- """
- Set whether the existing bounds of the box should be ignored
- by subsequent calls to :meth:`update_from_data_xy`.
-
- value : bool
- - When ``True``, subsequent calls to :meth:`update_from_data_xy`
- will ignore the existing bounds of the :class:`Bbox`.
-
- - When ``False``, subsequent calls to :meth:`update_from_data_xy`
- will include the existing bounds of the :class:`Bbox`.
- """
- self._ignore = value
-
- def update_from_path(self, path, ignore=None, updatex=True, updatey=True):
- """
- Update the bounds of the :class:`Bbox` based on the passed in
- data. After updating, the bounds will have positive *width*
- and *height*; *x0* and *y0* will be the minimal values.
-
- Parameters
- ----------
- path : :class:`~matplotlib.path.Path`
-
- ignore : bool, optional
- - when ``True``, ignore the existing bounds of the :class:`Bbox`.
- - when ``False``, include the existing bounds of the :class:`Bbox`.
- - when ``None``, use the last value passed to :meth:`ignore`.
-
- updatex, updatey : bool, optional
- When ``True``, update the x/y values.
- """
- if ignore is None:
- ignore = self._ignore
-
- if path.vertices.size == 0:
- return
-
- points, minpos, changed = update_path_extents(
- path, None, self._points, self._minpos, ignore)
-
- if changed:
- self.invalidate()
- if updatex:
- self._points[:, 0] = points[:, 0]
- self._minpos[0] = minpos[0]
- if updatey:
- self._points[:, 1] = points[:, 1]
- self._minpos[1] = minpos[1]
-
- def update_from_data_xy(self, xy, ignore=None, updatex=True, updatey=True):
- """
- Update the bounds of the :class:`Bbox` based on the passed in
- data. After updating, the bounds will have positive *width*
- and *height*; *x0* and *y0* will be the minimal values.
-
- Parameters
- ----------
- xy : ndarray
- A numpy array of 2D points.
-
- ignore : bool, optional
- - When ``True``, ignore the existing bounds of the :class:`Bbox`.
- - When ``False``, include the existing bounds of the :class:`Bbox`.
- - When ``None``, use the last value passed to :meth:`ignore`.
-
- updatex, updatey : bool, optional
- When ``True``, update the x/y values.
- """
- if len(xy) == 0:
- return
-
- path = Path(xy)
- self.update_from_path(path, ignore=ignore,
- updatex=updatex, updatey=updatey)
-
- @BboxBase.x0.setter
- def x0(self, val):
- self._points[0, 0] = val
- self.invalidate()
-
- @BboxBase.y0.setter
- def y0(self, val):
- self._points[0, 1] = val
- self.invalidate()
-
- @BboxBase.x1.setter
- def x1(self, val):
- self._points[1, 0] = val
- self.invalidate()
-
- @BboxBase.y1.setter
- def y1(self, val):
- self._points[1, 1] = val
- self.invalidate()
-
- @BboxBase.p0.setter
- def p0(self, val):
- self._points[0] = val
- self.invalidate()
-
- @BboxBase.p1.setter
- def p1(self, val):
- self._points[1] = val
- self.invalidate()
-
- @BboxBase.intervalx.setter
- def intervalx(self, interval):
- self._points[:, 0] = interval
- self.invalidate()
-
- @BboxBase.intervaly.setter
- def intervaly(self, interval):
- self._points[:, 1] = interval
- self.invalidate()
-
- @BboxBase.bounds.setter
- def bounds(self, bounds):
- l, b, w, h = bounds
- points = np.array([[l, b], [l + w, b + h]], float)
- if np.any(self._points != points):
- self._points = points
- self.invalidate()
-
- @property
- def minpos(self):
- return self._minpos
-
- @property
- def minposx(self):
- return self._minpos[0]
-
- @property
- def minposy(self):
- return self._minpos[1]
-
- def get_points(self):
- """
- Get the points of the bounding box directly as a numpy array
- of the form: ``[[x0, y0], [x1, y1]]``.
- """
- self._invalid = 0
- return self._points
-
- def set_points(self, points):
- """
- Set the points of the bounding box directly from a numpy array
- of the form: ``[[x0, y0], [x1, y1]]``. No error checking is
- performed, as this method is mainly for internal use.
- """
- if np.any(self._points != points):
- self._points = points
- self.invalidate()
-
- def set(self, other):
- """
- Set this bounding box from the "frozen" bounds of another
- :class:`Bbox`.
- """
- if np.any(self._points != other.get_points()):
- self._points = other.get_points()
- self.invalidate()
-
- def mutated(self):
- 'Return whether the bbox has changed since init.'
- return self.mutatedx() or self.mutatedy()
-
- def mutatedx(self):
- 'Return whether the x-limits have changed since init.'
- return (self._points[0, 0] != self._points_orig[0, 0] or
- self._points[1, 0] != self._points_orig[1, 0])
-
- def mutatedy(self):
- 'Return whether the y-limits have changed since init.'
- return (self._points[0, 1] != self._points_orig[0, 1] or
- self._points[1, 1] != self._points_orig[1, 1])
-
-
-class TransformedBbox(BboxBase):
- """
- A :class:`Bbox` that is automatically transformed by a given
- transform. When either the child bounding box or transform
- changes, the bounds of this bbox will update accordingly.
- """
- def __init__(self, bbox, transform, **kwargs):
- """
- Parameters
- ----------
- bbox : :class:`Bbox`
-
- transform : :class:`Transform`
- """
- if not bbox.is_bbox:
- raise ValueError("'bbox' is not a bbox")
- if not isinstance(transform, Transform):
- raise ValueError("'transform' must be an instance of "
- "'matplotlib.transform.Transform'")
- if transform.input_dims != 2 or transform.output_dims != 2:
- raise ValueError(
- "The input and output dimensions of 'transform' must be 2")
-
- BboxBase.__init__(self, **kwargs)
- self._bbox = bbox
- self._transform = transform
- self.set_children(bbox, transform)
- self._points = None
-
- def __str__(self):
- return ("{}(\n"
- "{},\n"
- "{})"
- .format(type(self).__name__,
- _indent_str(self._bbox),
- _indent_str(self._transform)))
-
- def get_points(self):
- if self._invalid:
- p = self._bbox.get_points()
- # Transform all four points, then make a new bounding box
- # from the result, taking care to make the orientation the
- # same.
- points = self._transform.transform(
- [[p[0, 0], p[0, 1]],
- [p[1, 0], p[0, 1]],
- [p[0, 0], p[1, 1]],
- [p[1, 0], p[1, 1]]])
- points = np.ma.filled(points, 0.0)
-
- xs = min(points[:, 0]), max(points[:, 0])
- if p[0, 0] > p[1, 0]:
- xs = xs[::-1]
-
- ys = min(points[:, 1]), max(points[:, 1])
- if p[0, 1] > p[1, 1]:
- ys = ys[::-1]
-
- self._points = np.array([
- [xs[0], ys[0]],
- [xs[1], ys[1]]
- ])
-
- self._invalid = 0
- return self._points
- get_points.__doc__ = Bbox.get_points.__doc__
-
- if DEBUG:
- _get_points = get_points
-
- def get_points(self):
- points = self._get_points()
- self._check(points)
- return points
-
-
-class LockableBbox(BboxBase):
- """
- A :class:`Bbox` where some elements may be locked at certain values.
-
- When the child bounding box changes, the bounds of this bbox will update
- accordingly with the exception of the locked elements.
- """
- def __init__(self, bbox, x0=None, y0=None, x1=None, y1=None, **kwargs):
- """
- Parameters
- ----------
- bbox : Bbox
- The child bounding box to wrap.
-
- x0 : float or None
- The locked value for x0, or None to leave unlocked.
-
- y0 : float or None
- The locked value for y0, or None to leave unlocked.
-
- x1 : float or None
- The locked value for x1, or None to leave unlocked.
-
- y1 : float or None
- The locked value for y1, or None to leave unlocked.
-
- """
- if not bbox.is_bbox:
- raise ValueError("'bbox' is not a bbox")
-
- BboxBase.__init__(self, **kwargs)
- self._bbox = bbox
- self.set_children(bbox)
- self._points = None
- fp = [x0, y0, x1, y1]
- mask = [val is None for val in fp]
- self._locked_points = np.ma.array(fp, float, mask=mask).reshape((2, 2))
-
- def __str__(self):
- return ("{}(\n"
- "{},\n"
- "{})"
- .format(type(self).__name__,
- _indent_str(self._bbox),
- _indent_str(self._locked_points)))
-
- def get_points(self):
- if self._invalid:
- points = self._bbox.get_points()
- self._points = np.where(self._locked_points.mask,
- points,
- self._locked_points)
- self._invalid = 0
- return self._points
- get_points.__doc__ = Bbox.get_points.__doc__
-
- if DEBUG:
- _get_points = get_points
-
- def get_points(self):
- points = self._get_points()
- self._check(points)
- return points
-
- @property
- def locked_x0(self):
- """
- float or None: The value used for the locked x0.
- """
- if self._locked_points.mask[0, 0]:
- return None
- else:
- return self._locked_points[0, 0]
-
- @locked_x0.setter
- def locked_x0(self, x0):
- self._locked_points.mask[0, 0] = x0 is None
- self._locked_points.data[0, 0] = x0
- self.invalidate()
-
- @property
- def locked_y0(self):
- """
- float or None: The value used for the locked y0.
- """
- if self._locked_points.mask[0, 1]:
- return None
- else:
- return self._locked_points[0, 1]
-
- @locked_y0.setter
- def locked_y0(self, y0):
- self._locked_points.mask[0, 1] = y0 is None
- self._locked_points.data[0, 1] = y0
- self.invalidate()
-
- @property
- def locked_x1(self):
- """
- float or None: The value used for the locked x1.
- """
- if self._locked_points.mask[1, 0]:
- return None
- else:
- return self._locked_points[1, 0]
-
- @locked_x1.setter
- def locked_x1(self, x1):
- self._locked_points.mask[1, 0] = x1 is None
- self._locked_points.data[1, 0] = x1
- self.invalidate()
-
- @property
- def locked_y1(self):
- """
- float or None: The value used for the locked y1.
- """
- if self._locked_points.mask[1, 1]:
- return None
- else:
- return self._locked_points[1, 1]
-
- @locked_y1.setter
- def locked_y1(self, y1):
- self._locked_points.mask[1, 1] = y1 is None
- self._locked_points.data[1, 1] = y1
- self.invalidate()
-
-
-class Transform(TransformNode):
- """
- The base class of all :class:`TransformNode` instances that
- actually perform a transformation.
-
- All non-affine transformations should be subclasses of this class.
- New affine transformations should be subclasses of
- :class:`Affine2D`.
-
- Subclasses of this class should override the following members (at
- minimum):
-
- - :attr:`input_dims`
- - :attr:`output_dims`
- - :meth:`transform`
- - :attr:`is_separable`
- - :attr:`has_inverse`
- - :meth:`inverted` (if :attr:`has_inverse` is True)
-
- If the transform needs to do something non-standard with
- :class:`matplotlib.path.Path` objects, such as adding curves
- where there were once line segments, it should override:
-
- - :meth:`transform_path`
- """
- input_dims = None
- """
- The number of input dimensions of this transform.
- Must be overridden (with integers) in the subclass.
- """
-
- output_dims = None
- """
- The number of output dimensions of this transform.
- Must be overridden (with integers) in the subclass.
- """
-
- has_inverse = False
- """True if this transform has a corresponding inverse transform."""
-
- is_separable = False
- """True if this transform is separable in the x- and y- dimensions."""
-
- def __add__(self, other):
- """
- Composes two transforms together such that *self* is followed
- by *other*.
- """
- if isinstance(other, Transform):
- return composite_transform_factory(self, other)
- raise TypeError(
- "Can not add Transform to object of type '%s'" % type(other))
-
- def __radd__(self, other):
- """
- Composes two transforms together such that *self* is followed
- by *other*.
- """
- if isinstance(other, Transform):
- return composite_transform_factory(other, self)
- raise TypeError(
- "Can not add Transform to object of type '%s'" % type(other))
-
- # Equality is based on object identity for `Transform`s (so we don't
- # override `__eq__`), but some subclasses, such as TransformWrapper &
- # AffineBase, override this behavior.
-
- if six.PY2:
- def __ne__(self, other):
- return not (self == other)
-
- def _iter_break_from_left_to_right(self):
- """
- Returns an iterator breaking down this transform stack from left to
- right recursively. If self == ((A, N), A) then the result will be an
- iterator which yields I : ((A, N), A), followed by A : (N, A),
- followed by (A, N) : (A), but not ((A, N), A) : I.
-
- This is equivalent to flattening the stack then yielding
- ``flat_stack[:i], flat_stack[i:]`` where i=0..(n-1).
-
- """
- yield IdentityTransform(), self
-
- @property
- def depth(self):
- """
- Returns the number of transforms which have been chained
- together to form this Transform instance.
-
- .. note::
-
- For the special case of a Composite transform, the maximum depth
- of the two is returned.
-
- """
- return 1
-
- def contains_branch(self, other):
- """
- Return whether the given transform is a sub-tree of this transform.
-
- This routine uses transform equality to identify sub-trees, therefore
- in many situations it is object id which will be used.
-
- For the case where the given transform represents the whole
- of this transform, returns True.
-
- """
- if self.depth < other.depth:
- return False
-
- # check that a subtree is equal to other (starting from self)
- for _, sub_tree in self._iter_break_from_left_to_right():
- if sub_tree == other:
- return True
- return False
-
- def contains_branch_seperately(self, other_transform):
- """
- Returns whether the given branch is a sub-tree of this transform on
- each separate dimension.
-
- A common use for this method is to identify if a transform is a blended
- transform containing an axes' data transform. e.g.::
-
- x_isdata, y_isdata = trans.contains_branch_seperately(ax.transData)
-
- """
- if self.output_dims != 2:
- raise ValueError('contains_branch_seperately only supports '
- 'transforms with 2 output dimensions')
- # for a non-blended transform each separate dimension is the same, so
- # just return the appropriate shape.
- return [self.contains_branch(other_transform)] * 2
-
- def __sub__(self, other):
- """
- Returns a transform stack which goes all the way down self's transform
- stack, and then ascends back up other's stack. If it can, this is
- optimised::
-
- # normally
- A - B == a + b.inverted()
-
- # sometimes, when A contains the tree B there is no need to
- # descend all the way down to the base of A (via B), instead we
- # can just stop at B.
-
- (A + B) - (B)^-1 == A
-
- # similarly, when B contains tree A, we can avoid decending A at
- # all, basically:
- A - (A + B) == ((B + A) - A).inverted() or B^-1
-
- For clarity, the result of ``(A + B) - B + B == (A + B)``.
-
- """
- # we only know how to do this operation if other is a Transform.
- if not isinstance(other, Transform):
- return NotImplemented
-
- for remainder, sub_tree in self._iter_break_from_left_to_right():
- if sub_tree == other:
- return remainder
-
- for remainder, sub_tree in other._iter_break_from_left_to_right():
- if sub_tree == self:
- if not remainder.has_inverse:
- raise ValueError("The shortcut cannot be computed since "
- "other's transform includes a non-invertable component.")
- return remainder.inverted()
-
- # if we have got this far, then there was no shortcut possible
- if other.has_inverse:
- return self + other.inverted()
- else:
- raise ValueError('It is not possible to compute transA - transB '
- 'since transB cannot be inverted and there is no '
- 'shortcut possible.')
-
- def __array__(self, *args, **kwargs):
- """
- Array interface to get at this Transform's affine matrix.
- """
- return self.get_affine().get_matrix()
-
- def transform(self, values):
- """
- Performs the transformation on the given array of values.
-
- Accepts a numpy array of shape (N x :attr:`input_dims`) and
- returns a numpy array of shape (N x :attr:`output_dims`).
-
- Alternatively, accepts a numpy array of length :attr:`input_dims`
- and returns a numpy array of length :attr:`output_dims`.
- """
- # Ensure that values is a 2d array (but remember whether
- # we started with a 1d or 2d array).
- values = np.asanyarray(values)
- ndim = values.ndim
- values = values.reshape((-1, self.input_dims))
-
- # Transform the values
- res = self.transform_affine(self.transform_non_affine(values))
-
- # Convert the result back to the shape of the input values.
- if ndim == 0:
- assert not np.ma.is_masked(res) # just to be on the safe side
- return res[0, 0]
- if ndim == 1:
- return res.reshape(-1)
- elif ndim == 2:
- return res
- raise ValueError(
- "Input values must have shape (N x {dims}) "
- "or ({dims}).".format(dims=self.input_dims))
-
- def transform_affine(self, values):
- """
- Performs only the affine part of this transformation on the
- given array of values.
-
- ``transform(values)`` is always equivalent to
- ``transform_affine(transform_non_affine(values))``.
-
- In non-affine transformations, this is generally a no-op. In
- affine transformations, this is equivalent to
- ``transform(values)``.
-
- Accepts a numpy array of shape (N x :attr:`input_dims`) and
- returns a numpy array of shape (N x :attr:`output_dims`).
-
- Alternatively, accepts a numpy array of length :attr:`input_dims`
- and returns a numpy array of length :attr:`output_dims`.
- """
- return self.get_affine().transform(values)
-
- def transform_non_affine(self, values):
- """
- Performs only the non-affine part of the transformation.
-
- ``transform(values)`` is always equivalent to
- ``transform_affine(transform_non_affine(values))``.
-
- In non-affine transformations, this is generally equivalent to
- ``transform(values)``. In affine transformations, this is
- always a no-op.
-
- Accepts a numpy array of shape (N x :attr:`input_dims`) and
- returns a numpy array of shape (N x :attr:`output_dims`).
-
- Alternatively, accepts a numpy array of length :attr:`input_dims`
- and returns a numpy array of length :attr:`output_dims`.
- """
- return values
-
- def transform_bbox(self, bbox):
- """
- Transform the given bounding box.
-
- Note, for smarter transforms including caching (a common
- requirement for matplotlib figures), see :class:`TransformedBbox`.
- """
- return Bbox(self.transform(bbox.get_points()))
-
- def get_affine(self):
- """
- Get the affine part of this transform.
- """
- return IdentityTransform()
-
- def get_matrix(self):
- """
- Get the Affine transformation array for the affine part
- of this transform.
-
- """
- return self.get_affine().get_matrix()
-
- def transform_point(self, point):
- """
- A convenience function that returns the transformed copy of a
- single point.
-
- The point is given as a sequence of length :attr:`input_dims`.
- The transformed point is returned as a sequence of length
- :attr:`output_dims`.
- """
- if len(point) != self.input_dims:
- raise ValueError("The length of 'point' must be 'self.input_dims'")
- return self.transform(np.asarray([point]))[0]
-
- def transform_path(self, path):
- """
- Returns a transformed path.
-
- *path*: a :class:`~matplotlib.path.Path` instance.
-
- In some cases, this transform may insert curves into the path
- that began as line segments.
- """
- return self.transform_path_affine(self.transform_path_non_affine(path))
-
- def transform_path_affine(self, path):
- """
- Returns a path, transformed only by the affine part of
- this transform.
-
- *path*: a :class:`~matplotlib.path.Path` instance.
-
- ``transform_path(path)`` is equivalent to
- ``transform_path_affine(transform_path_non_affine(values))``.
- """
- return self.get_affine().transform_path_affine(path)
-
- def transform_path_non_affine(self, path):
- """
- Returns a path, transformed only by the non-affine
- part of this transform.
-
- *path*: a :class:`~matplotlib.path.Path` instance.
-
- ``transform_path(path)`` is equivalent to
- ``transform_path_affine(transform_path_non_affine(values))``.
- """
- x = self.transform_non_affine(path.vertices)
- return Path._fast_from_codes_and_verts(x, path.codes,
- {'interpolation_steps': path._interpolation_steps,
- 'should_simplify': path.should_simplify})
-
- def transform_angles(self, angles, pts, radians=False, pushoff=1e-5):
- """
- Performs transformation on a set of angles anchored at
- specific locations.
-
- The *angles* must be a column vector (i.e., numpy array).
-
- The *pts* must be a two-column numpy array of x,y positions
- (angle transforms currently only work in 2D). This array must
- have the same number of rows as *angles*.
-
- *radians* indicates whether or not input angles are given in
- radians (True) or degrees (False; the default).
-
- *pushoff* is the distance to move away from *pts* for
- determining transformed angles (see discussion of method
- below).
-
- The transformed angles are returned in an array with the same
- size as *angles*.
-
- The generic version of this method uses a very generic
- algorithm that transforms *pts*, as well as locations very
- close to *pts*, to find the angle in the transformed system.
- """
- # Must be 2D
- if self.input_dims != 2 or self.output_dims != 2:
- raise NotImplementedError('Only defined in 2D')
-
- if pts.shape[1] != 2:
- raise ValueError("'pts' must be array with 2 columns for x,y")
-
- if angles.ndim != 1 or angles.shape[0] != pts.shape[0]:
- raise ValueError("'angles' must be a column vector and have same "
- "number of rows as 'pts'")
-
- # Convert to radians if desired
- if not radians:
- angles = angles / 180.0 * np.pi
-
- # Move a short distance away
- pts2 = pts + pushoff * np.c_[np.cos(angles), np.sin(angles)]
-
- # Transform both sets of points
- tpts = self.transform(pts)
- tpts2 = self.transform(pts2)
-
- # Calculate transformed angles
- d = tpts2 - tpts
- a = np.arctan2(d[:, 1], d[:, 0])
-
- # Convert back to degrees if desired
- if not radians:
- a = np.rad2deg(a)
-
- return a
-
- def inverted(self):
- """
- Return the corresponding inverse transformation.
-
- The return value of this method should be treated as
- temporary. An update to *self* does not cause a corresponding
- update to its inverted copy.
-
- ``x === self.inverted().transform(self.transform(x))``
- """
- raise NotImplementedError()
-
-
-class TransformWrapper(Transform):
- """
- A helper class that holds a single child transform and acts
- equivalently to it.
-
- This is useful if a node of the transform tree must be replaced at
- run time with a transform of a different type. This class allows
- that replacement to correctly trigger invalidation.
-
- Note that :class:`TransformWrapper` instances must have the same
- input and output dimensions during their entire lifetime, so the
- child transform may only be replaced with another child transform
- of the same dimensions.
- """
- pass_through = True
-
- def __init__(self, child):
- """
- *child*: A class:`Transform` instance. This child may later
- be replaced with :meth:`set`.
- """
- if not isinstance(child, Transform):
- raise ValueError("'child' must be an instance of "
- "'matplotlib.transform.Transform'")
- self._init(child)
- self.set_children(child)
-
- def _init(self, child):
- Transform.__init__(self)
- self.input_dims = child.input_dims
- self.output_dims = child.output_dims
- self._set(child)
- self._invalid = 0
-
- def __eq__(self, other):
- return self._child.__eq__(other)
-
- # NOTE: Transform.__[gs]etstate__ should be sufficient when using only
- # Python 3.4+.
- def __getstate__(self):
- # only store the child information and parents
- return {
- 'child': self._child,
- 'input_dims': self.input_dims,
- 'output_dims': self.output_dims,
- # turn the weak-values dictionary into a normal dictionary
- 'parents': dict((k, v()) for (k, v) in
- six.iteritems(self._parents))
- }
-
- def __setstate__(self, state):
- # re-initialise the TransformWrapper with the state's child
- self._init(state['child'])
- # The child may not be unpickled yet, so restore its information.
- self.input_dims = state['input_dims']
- self.output_dims = state['output_dims']
- # turn the normal dictionary back into a dictionary with weak
- # values
- self._parents = dict((k, weakref.ref(v)) for (k, v) in
- six.iteritems(state['parents']) if v is not None)
-
- def __str__(self):
- return ("{}(\n"
- "{})"
- .format(type(self).__name__,
- _indent_str(self._child)))
-
- def frozen(self):
- return self._child.frozen()
- frozen.__doc__ = Transform.frozen.__doc__
-
- def _set(self, child):
- self._child = child
-
- self.transform = child.transform
- self.transform_affine = child.transform_affine
- self.transform_non_affine = child.transform_non_affine
- self.transform_path = child.transform_path
- self.transform_path_affine = child.transform_path_affine
- self.transform_path_non_affine = child.transform_path_non_affine
- self.get_affine = child.get_affine
- self.inverted = child.inverted
- self.get_matrix = child.get_matrix
-
- # note we do not wrap other properties here since the transform's
- # child can be changed with WrappedTransform.set and so checking
- # is_affine and other such properties may be dangerous.
-
- def set(self, child):
- """
- Replace the current child of this transform with another one.
-
- The new child must have the same number of input and output
- dimensions as the current child.
- """
- if (child.input_dims != self.input_dims or
- child.output_dims != self.output_dims):
- raise ValueError(
- "The new child must have the same number of input and output "
- "dimensions as the current child")
-
- self.set_children(child)
- self._set(child)
-
- self._invalid = 0
- self.invalidate()
- self._invalid = 0
-
- def _get_is_affine(self):
- return self._child.is_affine
- is_affine = property(_get_is_affine)
-
- def _get_is_separable(self):
- return self._child.is_separable
- is_separable = property(_get_is_separable)
-
- def _get_has_inverse(self):
- return self._child.has_inverse
- has_inverse = property(_get_has_inverse)
-
-
-class AffineBase(Transform):
- """
- The base class of all affine transformations of any number of
- dimensions.
- """
- is_affine = True
-
- def __init__(self, *args, **kwargs):
- Transform.__init__(self, *args, **kwargs)
- self._inverted = None
-
- def __array__(self, *args, **kwargs):
- # optimises the access of the transform matrix vs the superclass
- return self.get_matrix()
-
- @staticmethod
- def _concat(a, b):
- """
- Concatenates two transformation matrices (represented as numpy
- arrays) together.
- """
- return np.dot(b, a)
-
- def __eq__(self, other):
- if getattr(other, "is_affine", False):
- return np.all(self.get_matrix() == other.get_matrix())
- return NotImplemented
-
- def transform(self, values):
- return self.transform_affine(values)
- transform.__doc__ = Transform.transform.__doc__
-
- def transform_affine(self, values):
- raise NotImplementedError('Affine subclasses should override this '
- 'method.')
- transform_affine.__doc__ = Transform.transform_affine.__doc__
-
- def transform_non_affine(self, points):
- return points
- transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
-
- def transform_path(self, path):
- return self.transform_path_affine(path)
- transform_path.__doc__ = Transform.transform_path.__doc__
-
- def transform_path_affine(self, path):
- return Path(self.transform_affine(path.vertices),
- path.codes, path._interpolation_steps)
- transform_path_affine.__doc__ = Transform.transform_path_affine.__doc__
-
- def transform_path_non_affine(self, path):
- return path
- transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__
-
- def get_affine(self):
- return self
- get_affine.__doc__ = Transform.get_affine.__doc__
-
-
-class Affine2DBase(AffineBase):
- """
- The base class of all 2D affine transformations.
-
- 2D affine transformations are performed using a 3x3 numpy array::
-
- a c e
- b d f
- 0 0 1
-
- This class provides the read-only interface. For a mutable 2D
- affine transformation, use :class:`Affine2D`.
-
- Subclasses of this class will generally only need to override a
- constructor and :meth:`get_matrix` that generates a custom 3x3 matrix.
- """
- has_inverse = True
-
- input_dims = 2
- output_dims = 2
-
- def frozen(self):
- return Affine2D(self.get_matrix().copy())
- frozen.__doc__ = AffineBase.frozen.__doc__
-
- def _get_is_separable(self):
- mtx = self.get_matrix()
- return mtx[0, 1] == 0.0 and mtx[1, 0] == 0.0
- is_separable = property(_get_is_separable)
-
- def to_values(self):
- """
- Return the values of the matrix as a sequence (a,b,c,d,e,f)
- """
- mtx = self.get_matrix()
- return tuple(mtx[:2].swapaxes(0, 1).flatten())
-
- @staticmethod
- def matrix_from_values(a, b, c, d, e, f):
- """
- (staticmethod) Create a new transformation matrix as a 3x3
- numpy array of the form::
-
- a c e
- b d f
- 0 0 1
- """
- return np.array([[a, c, e], [b, d, f], [0.0, 0.0, 1.0]], float)
-
- def transform_affine(self, points):
- mtx = self.get_matrix()
- if isinstance(points, np.ma.MaskedArray):
- tpoints = affine_transform(points.data, mtx)
- return np.ma.MaskedArray(tpoints, mask=np.ma.getmask(points))
- return affine_transform(points, mtx)
-
- def transform_point(self, point):
- mtx = self.get_matrix()
- return affine_transform([point], mtx)[0]
- transform_point.__doc__ = AffineBase.transform_point.__doc__
-
- if DEBUG:
- _transform_affine = transform_affine
-
- def transform_affine(self, points):
- # The major speed trap here is just converting to the
- # points to an array in the first place. If we can use
- # more arrays upstream, that should help here.
- if not isinstance(points, (np.ma.MaskedArray, np.ndarray)):
- warnings.warn(
- ('A non-numpy array of type %s was passed in for ' +
- 'transformation. Please correct this.')
- % type(points))
- return self._transform_affine(points)
- transform_affine.__doc__ = AffineBase.transform_affine.__doc__
-
- def inverted(self):
- if self._inverted is None or self._invalid:
- mtx = self.get_matrix()
- shorthand_name = None
- if self._shorthand_name:
- shorthand_name = '(%s)-1' % self._shorthand_name
- self._inverted = Affine2D(inv(mtx), shorthand_name=shorthand_name)
- self._invalid = 0
- return self._inverted
- inverted.__doc__ = AffineBase.inverted.__doc__
-
-
-class Affine2D(Affine2DBase):
- """
- A mutable 2D affine transformation.
- """
-
- def __init__(self, matrix=None, **kwargs):
- """
- Initialize an Affine transform from a 3x3 numpy float array::
-
- a c e
- b d f
- 0 0 1
-
- If *matrix* is None, initialize with the identity transform.
- """
- Affine2DBase.__init__(self, **kwargs)
- if matrix is None:
- # A bit faster than np.identity(3).
- matrix = IdentityTransform._mtx.copy()
- self._mtx = matrix
- self._invalid = 0
-
- def __str__(self):
- return ("{}(\n"
- "{})"
- .format(type(self).__name__,
- _indent_str(self._mtx)))
-
- @staticmethod
- def from_values(a, b, c, d, e, f):
- """
- (staticmethod) Create a new Affine2D instance from the given
- values::
-
- a c e
- b d f
- 0 0 1
-
- .
- """
- return Affine2D(
- np.array([a, c, e, b, d, f, 0.0, 0.0, 1.0], float).reshape((3, 3)))
-
- def get_matrix(self):
- """
- Get the underlying transformation matrix as a 3x3 numpy array::
-
- a c e
- b d f
- 0 0 1
-
- .
- """
- self._invalid = 0
- return self._mtx
-
- def set_matrix(self, mtx):
- """
- Set the underlying transformation matrix from a 3x3 numpy array::
-
- a c e
- b d f
- 0 0 1
-
- .
- """
- self._mtx = mtx
- self.invalidate()
-
- def set(self, other):
- """
- Set this transformation from the frozen copy of another
- :class:`Affine2DBase` object.
- """
- if not isinstance(other, Affine2DBase):
- raise ValueError("'other' must be an instance of "
- "'matplotlib.transform.Affine2DBase'")
- self._mtx = other.get_matrix()
- self.invalidate()
-
- @staticmethod
- def identity():
- """
- (staticmethod) Return a new :class:`Affine2D` object that is
- the identity transform.
-
- Unless this transform will be mutated later on, consider using
- the faster :class:`IdentityTransform` class instead.
- """
- return Affine2D()
-
- def clear(self):
- """
- Reset the underlying matrix to the identity transform.
- """
- # A bit faster than np.identity(3).
- self._mtx = IdentityTransform._mtx.copy()
- self.invalidate()
- return self
-
- def rotate(self, theta):
- """
- Add a rotation (in radians) to this transform in place.
-
- Returns *self*, so this method can easily be chained with more
- calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
- and :meth:`scale`.
- """
- a = np.cos(theta)
- b = np.sin(theta)
- rotate_mtx = np.array([[a, -b, 0.0], [b, a, 0.0], [0.0, 0.0, 1.0]],
- float)
- self._mtx = np.dot(rotate_mtx, self._mtx)
- self.invalidate()
- return self
-
- def rotate_deg(self, degrees):
- """
- Add a rotation (in degrees) to this transform in place.
-
- Returns *self*, so this method can easily be chained with more
- calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
- and :meth:`scale`.
- """
- return self.rotate(np.deg2rad(degrees))
-
- def rotate_around(self, x, y, theta):
- """
- Add a rotation (in radians) around the point (x, y) in place.
-
- Returns *self*, so this method can easily be chained with more
- calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
- and :meth:`scale`.
- """
- return self.translate(-x, -y).rotate(theta).translate(x, y)
-
- def rotate_deg_around(self, x, y, degrees):
- """
- Add a rotation (in degrees) around the point (x, y) in place.
-
- Returns *self*, so this method can easily be chained with more
- calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
- and :meth:`scale`.
- """
- # Cast to float to avoid wraparound issues with uint8's
- x, y = float(x), float(y)
- return self.translate(-x, -y).rotate_deg(degrees).translate(x, y)
-
- def translate(self, tx, ty):
- """
- Adds a translation in place.
-
- Returns *self*, so this method can easily be chained with more
- calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
- and :meth:`scale`.
- """
- translate_mtx = np.array(
- [[1.0, 0.0, tx], [0.0, 1.0, ty], [0.0, 0.0, 1.0]], float)
- self._mtx = np.dot(translate_mtx, self._mtx)
- self.invalidate()
- return self
-
- def scale(self, sx, sy=None):
- """
- Adds a scale in place.
-
- If *sy* is None, the same scale is applied in both the *x*- and
- *y*-directions.
-
- Returns *self*, so this method can easily be chained with more
- calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
- and :meth:`scale`.
- """
- if sy is None:
- sy = sx
- scale_mtx = np.array(
- [[sx, 0.0, 0.0], [0.0, sy, 0.0], [0.0, 0.0, 1.0]], float)
- self._mtx = np.dot(scale_mtx, self._mtx)
- self.invalidate()
- return self
-
- def skew(self, xShear, yShear):
- """
- Adds a skew in place.
-
- *xShear* and *yShear* are the shear angles along the *x*- and
- *y*-axes, respectively, in radians.
-
- Returns *self*, so this method can easily be chained with more
- calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
- and :meth:`scale`.
- """
- rotX = np.tan(xShear)
- rotY = np.tan(yShear)
- skew_mtx = np.array(
- [[1.0, rotX, 0.0], [rotY, 1.0, 0.0], [0.0, 0.0, 1.0]], float)
- self._mtx = np.dot(skew_mtx, self._mtx)
- self.invalidate()
- return self
-
- def skew_deg(self, xShear, yShear):
- """
- Adds a skew in place.
-
- *xShear* and *yShear* are the shear angles along the *x*- and
- *y*-axes, respectively, in degrees.
-
- Returns *self*, so this method can easily be chained with more
- calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
- and :meth:`scale`.
- """
- return self.skew(np.deg2rad(xShear), np.deg2rad(yShear))
-
- def _get_is_separable(self):
- mtx = self.get_matrix()
- return mtx[0, 1] == 0.0 and mtx[1, 0] == 0.0
- is_separable = property(_get_is_separable)
-
-
-class IdentityTransform(Affine2DBase):
- """
- A special class that does one thing, the identity transform, in a
- fast way.
- """
- _mtx = np.identity(3)
-
- def frozen(self):
- return self
- frozen.__doc__ = Affine2DBase.frozen.__doc__
-
- def __str__(self):
- return ("{}()"
- .format(type(self).__name__))
-
- def get_matrix(self):
- return self._mtx
- get_matrix.__doc__ = Affine2DBase.get_matrix.__doc__
-
- def transform(self, points):
- return np.asanyarray(points)
- transform.__doc__ = Affine2DBase.transform.__doc__
-
- transform_affine = transform
- transform_affine.__doc__ = Affine2DBase.transform_affine.__doc__
-
- transform_non_affine = transform
- transform_non_affine.__doc__ = Affine2DBase.transform_non_affine.__doc__
-
- def transform_path(self, path):
- return path
- transform_path.__doc__ = Affine2DBase.transform_path.__doc__
-
- transform_path_affine = transform_path
- transform_path_affine.__doc__ = Affine2DBase.transform_path_affine.__doc__
-
- transform_path_non_affine = transform_path
- transform_path_non_affine.__doc__ = Affine2DBase.transform_path_non_affine.__doc__
-
- def get_affine(self):
- return self
- get_affine.__doc__ = Affine2DBase.get_affine.__doc__
-
- inverted = get_affine
- inverted.__doc__ = Affine2DBase.inverted.__doc__
-
-
-class BlendedGenericTransform(Transform):
- """
- A "blended" transform uses one transform for the *x*-direction, and
- another transform for the *y*-direction.
-
- This "generic" version can handle any given child transform in the
- *x*- and *y*-directions.
- """
- input_dims = 2
- output_dims = 2
- is_separable = True
- pass_through = True
-
- def __init__(self, x_transform, y_transform, **kwargs):
- """
- Create a new "blended" transform using *x_transform* to
- transform the *x*-axis and *y_transform* to transform the
- *y*-axis.
-
- You will generally not call this constructor directly but use
- the :func:`blended_transform_factory` function instead, which
- can determine automatically which kind of blended transform to
- create.
- """
- # Here we ask: "Does it blend?"
-
- Transform.__init__(self, **kwargs)
- self._x = x_transform
- self._y = y_transform
- self.set_children(x_transform, y_transform)
- self._affine = None
-
- def __eq__(self, other):
- # Note, this is an exact copy of BlendedAffine2D.__eq__
- if isinstance(other, (BlendedAffine2D, BlendedGenericTransform)):
- return (self._x == other._x) and (self._y == other._y)
- elif self._x == self._y:
- return self._x == other
- else:
- return NotImplemented
-
- def contains_branch_seperately(self, transform):
- # Note, this is an exact copy of BlendedAffine2D.contains_branch_seperately
- return self._x.contains_branch(transform), self._y.contains_branch(transform)
-
- @property
- def depth(self):
- return max(self._x.depth, self._y.depth)
-
- def contains_branch(self, other):
- # a blended transform cannot possibly contain a branch from two different transforms.
- return False
-
- def _get_is_affine(self):
- return self._x.is_affine and self._y.is_affine
- is_affine = property(_get_is_affine)
-
- def _get_has_inverse(self):
- return self._x.has_inverse and self._y.has_inverse
- has_inverse = property(_get_has_inverse)
-
- def frozen(self):
- return blended_transform_factory(self._x.frozen(), self._y.frozen())
- frozen.__doc__ = Transform.frozen.__doc__
-
- def __str__(self):
- return ("{}(\n"
- "{},\n"
- "{})"
- .format(type(self).__name__,
- _indent_str(self._x),
- _indent_str(self._y)))
-
- def transform_non_affine(self, points):
- if self._x.is_affine and self._y.is_affine:
- return points
- x = self._x
- y = self._y
-
- if x == y and x.input_dims == 2:
- return x.transform_non_affine(points)
-
- if x.input_dims == 2:
- x_points = x.transform_non_affine(points)[:, 0:1]
- else:
- x_points = x.transform_non_affine(points[:, 0])
- x_points = x_points.reshape((len(x_points), 1))
-
- if y.input_dims == 2:
- y_points = y.transform_non_affine(points)[:, 1:]
- else:
- y_points = y.transform_non_affine(points[:, 1])
- y_points = y_points.reshape((len(y_points), 1))
-
- if (isinstance(x_points, np.ma.MaskedArray) or
- isinstance(y_points, np.ma.MaskedArray)):
- return np.ma.concatenate((x_points, y_points), 1)
- else:
- return np.concatenate((x_points, y_points), 1)
- transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
-
- def inverted(self):
- return BlendedGenericTransform(self._x.inverted(), self._y.inverted())
- inverted.__doc__ = Transform.inverted.__doc__
-
- def get_affine(self):
- if self._invalid or self._affine is None:
- if self._x == self._y:
- self._affine = self._x.get_affine()
- else:
- x_mtx = self._x.get_affine().get_matrix()
- y_mtx = self._y.get_affine().get_matrix()
- # This works because we already know the transforms are
- # separable, though normally one would want to set b and
- # c to zero.
- mtx = np.vstack((x_mtx[0], y_mtx[1], [0.0, 0.0, 1.0]))
- self._affine = Affine2D(mtx)
- self._invalid = 0
- return self._affine
- get_affine.__doc__ = Transform.get_affine.__doc__
-
-
-class BlendedAffine2D(Affine2DBase):
- """
- A "blended" transform uses one transform for the *x*-direction, and
- another transform for the *y*-direction.
-
- This version is an optimization for the case where both child
- transforms are of type :class:`Affine2DBase`.
- """
- is_separable = True
-
- def __init__(self, x_transform, y_transform, **kwargs):
- """
- Create a new "blended" transform using *x_transform* to
- transform the *x*-axis and *y_transform* to transform the
- *y*-axis.
-
- Both *x_transform* and *y_transform* must be 2D affine
- transforms.
-
- You will generally not call this constructor directly but use
- the :func:`blended_transform_factory` function instead, which
- can determine automatically which kind of blended transform to
- create.
- """
- is_affine = x_transform.is_affine and y_transform.is_affine
- is_separable = x_transform.is_separable and y_transform.is_separable
- is_correct = is_affine and is_separable
- if not is_correct:
- raise ValueError("Both *x_transform* and *y_transform* must be 2D "
- "affine transforms")
-
- Transform.__init__(self, **kwargs)
- self._x = x_transform
- self._y = y_transform
- self.set_children(x_transform, y_transform)
-
- Affine2DBase.__init__(self)
- self._mtx = None
-
- def __eq__(self, other):
- # Note, this is an exact copy of BlendedGenericTransform.__eq__
- if isinstance(other, (BlendedAffine2D, BlendedGenericTransform)):
- return (self._x == other._x) and (self._y == other._y)
- elif self._x == self._y:
- return self._x == other
- else:
- return NotImplemented
-
- def contains_branch_seperately(self, transform):
- # Note, this is an exact copy of BlendedTransform.contains_branch_seperately
- return self._x.contains_branch(transform), self._y.contains_branch(transform)
-
- def __str__(self):
- return ("{}(\n"
- "{},\n"
- "{})"
- .format(type(self).__name__,
- _indent_str(self._x),
- _indent_str(self._y)))
-
- def get_matrix(self):
- if self._invalid:
- if self._x == self._y:
- self._mtx = self._x.get_matrix()
- else:
- x_mtx = self._x.get_matrix()
- y_mtx = self._y.get_matrix()
- # This works because we already know the transforms are
- # separable, though normally one would want to set b and
- # c to zero.
- self._mtx = np.vstack((x_mtx[0], y_mtx[1], [0.0, 0.0, 1.0]))
- self._inverted = None
- self._invalid = 0
- return self._mtx
- get_matrix.__doc__ = Affine2DBase.get_matrix.__doc__
-
-
-def blended_transform_factory(x_transform, y_transform):
- """
- Create a new "blended" transform using *x_transform* to transform
- the *x*-axis and *y_transform* to transform the *y*-axis.
-
- A faster version of the blended transform is returned for the case
- where both child transforms are affine.
- """
- if (isinstance(x_transform, Affine2DBase)
- and isinstance(y_transform, Affine2DBase)):
- return BlendedAffine2D(x_transform, y_transform)
- return BlendedGenericTransform(x_transform, y_transform)
-
-
-class CompositeGenericTransform(Transform):
- """
- A composite transform formed by applying transform *a* then
- transform *b*.
-
- This "generic" version can handle any two arbitrary
- transformations.
- """
- pass_through = True
-
- def __init__(self, a, b, **kwargs):
- """
- Create a new composite transform that is the result of
- applying transform *a* then transform *b*.
-
- You will generally not call this constructor directly but use
- the :func:`composite_transform_factory` function instead,
- which can automatically choose the best kind of composite
- transform instance to create.
- """
- if a.output_dims != b.input_dims:
- raise ValueError("The output dimension of 'a' must be equal to "
- "the input dimensions of 'b'")
- self.input_dims = a.input_dims
- self.output_dims = b.output_dims
-
- Transform.__init__(self, **kwargs)
- self._a = a
- self._b = b
- self.set_children(a, b)
-
- is_affine = property(lambda self: self._a.is_affine and self._b.is_affine)
-
- def frozen(self):
- self._invalid = 0
- frozen = composite_transform_factory(self._a.frozen(), self._b.frozen())
- if not isinstance(frozen, CompositeGenericTransform):
- return frozen.frozen()
- return frozen
- frozen.__doc__ = Transform.frozen.__doc__
-
- def _invalidate_internal(self, value, invalidating_node):
- # In some cases for a composite transform, an invalidating call to AFFINE_ONLY needs
- # to be extended to invalidate the NON_AFFINE part too. These cases are when the right
- # hand transform is non-affine and either:
- # (a) the left hand transform is non affine
- # (b) it is the left hand node which has triggered the invalidation
- if value == Transform.INVALID_AFFINE \
- and not self._b.is_affine \
- and (not self._a.is_affine or invalidating_node is self._a):
-
- value = Transform.INVALID
-
- Transform._invalidate_internal(self, value=value,
- invalidating_node=invalidating_node)
-
- def __eq__(self, other):
- if isinstance(other, (CompositeGenericTransform, CompositeAffine2D)):
- return self is other or (self._a == other._a and self._b == other._b)
- else:
- return False
-
- def _iter_break_from_left_to_right(self):
- for lh_compliment, rh_compliment in self._a._iter_break_from_left_to_right():
- yield lh_compliment, rh_compliment + self._b
- for lh_compliment, rh_compliment in self._b._iter_break_from_left_to_right():
- yield self._a + lh_compliment, rh_compliment
-
- @property
- def depth(self):
- return self._a.depth + self._b.depth
-
- def _get_is_affine(self):
- return self._a.is_affine and self._b.is_affine
- is_affine = property(_get_is_affine)
-
- def _get_is_separable(self):
- return self._a.is_separable and self._b.is_separable
- is_separable = property(_get_is_separable)
-
- def __str__(self):
- return ("{}(\n"
- "{},\n"
- "{})"
- .format(type(self).__name__,
- _indent_str(self._a),
- _indent_str(self._b)))
-
- def transform_affine(self, points):
- return self.get_affine().transform(points)
- transform_affine.__doc__ = Transform.transform_affine.__doc__
-
- def transform_non_affine(self, points):
- if self._a.is_affine and self._b.is_affine:
- return points
- elif not self._a.is_affine and self._b.is_affine:
- return self._a.transform_non_affine(points)
- else:
- return self._b.transform_non_affine(
- self._a.transform(points))
- transform_non_affine.__doc__ = Transform.transform_non_affine.__doc__
-
- def transform_path_non_affine(self, path):
- if self._a.is_affine and self._b.is_affine:
- return path
- elif not self._a.is_affine and self._b.is_affine:
- return self._a.transform_path_non_affine(path)
- else:
- return self._b.transform_path_non_affine(
- self._a.transform_path(path))
- transform_path_non_affine.__doc__ = Transform.transform_path_non_affine.__doc__
-
- def get_affine(self):
- if not self._b.is_affine:
- return self._b.get_affine()
- else:
- return Affine2D(np.dot(self._b.get_affine().get_matrix(),
- self._a.get_affine().get_matrix()))
- get_affine.__doc__ = Transform.get_affine.__doc__
-
- def inverted(self):
- return CompositeGenericTransform(self._b.inverted(), self._a.inverted())
- inverted.__doc__ = Transform.inverted.__doc__
-
- def _get_has_inverse(self):
- return self._a.has_inverse and self._b.has_inverse
- has_inverse = property(_get_has_inverse)
-
-
-class CompositeAffine2D(Affine2DBase):
- """
- A composite transform formed by applying transform *a* then transform *b*.
-
- This version is an optimization that handles the case where both *a*
- and *b* are 2D affines.
- """
- def __init__(self, a, b, **kwargs):
- """
- Create a new composite transform that is the result of
- applying transform *a* then transform *b*.
-
- Both *a* and *b* must be instances of :class:`Affine2DBase`.
-
- You will generally not call this constructor directly but use
- the :func:`composite_transform_factory` function instead,
- which can automatically choose the best kind of composite
- transform instance to create.
- """
- if not a.is_affine or not b.is_affine:
- raise ValueError("'a' and 'b' must be affine transforms")
- if a.output_dims != b.input_dims:
- raise ValueError("The output dimension of 'a' must be equal to "
- "the input dimensions of 'b'")
- self.input_dims = a.input_dims
- self.output_dims = b.output_dims
-
- Affine2DBase.__init__(self, **kwargs)
- self._a = a
- self._b = b
- self.set_children(a, b)
- self._mtx = None
-
- @property
- def depth(self):
- return self._a.depth + self._b.depth
-
- def _iter_break_from_left_to_right(self):
- for lh_compliment, rh_compliment in self._a._iter_break_from_left_to_right():
- yield lh_compliment, rh_compliment + self._b
- for lh_compliment, rh_compliment in self._b._iter_break_from_left_to_right():
- yield self._a + lh_compliment, rh_compliment
-
- def __str__(self):
- return ("{}(\n"
- "{},\n"
- "{})"
- .format(type(self).__name__,
- _indent_str(self._a),
- _indent_str(self._b)))
-
- def get_matrix(self):
- if self._invalid:
- self._mtx = np.dot(
- self._b.get_matrix(),
- self._a.get_matrix())
- self._inverted = None
- self._invalid = 0
- return self._mtx
- get_matrix.__doc__ = Affine2DBase.get_matrix.__doc__
-
-
-def composite_transform_factory(a, b):
- """
- Create a new composite transform that is the result of applying
- transform a then transform b.
-
- Shortcut versions of the blended transform are provided for the
- case where both child transforms are affine, or one or the other
- is the identity transform.
-
- Composite transforms may also be created using the '+' operator,
- e.g.::
-
- c = a + b
- """
- # check to see if any of a or b are IdentityTransforms. We use
- # isinstance here to guarantee that the transforms will *always*
- # be IdentityTransforms. Since TransformWrappers are mutable,
- # use of equality here would be wrong.
- if isinstance(a, IdentityTransform):
- return b
- elif isinstance(b, IdentityTransform):
- return a
- elif isinstance(a, Affine2D) and isinstance(b, Affine2D):
- return CompositeAffine2D(a, b)
- return CompositeGenericTransform(a, b)
-
-
-class BboxTransform(Affine2DBase):
- """
- :class:`BboxTransform` linearly transforms points from one
- :class:`Bbox` to another :class:`Bbox`.
- """
- is_separable = True
-
- def __init__(self, boxin, boxout, **kwargs):
- """
- Create a new :class:`BboxTransform` that linearly transforms
- points from *boxin* to *boxout*.
- """
- if not boxin.is_bbox or not boxout.is_bbox:
- raise ValueError("'boxin' and 'boxout' must be bbox")
-
- Affine2DBase.__init__(self, **kwargs)
- self._boxin = boxin
- self._boxout = boxout
- self.set_children(boxin, boxout)
- self._mtx = None
- self._inverted = None
-
- def __str__(self):
- return ("{}(\n"
- "{},\n"
- "{})"
- .format(type(self).__name__,
- _indent_str(self._boxin),
- _indent_str(self._boxout)))
-
- def get_matrix(self):
- if self._invalid:
- inl, inb, inw, inh = self._boxin.bounds
- outl, outb, outw, outh = self._boxout.bounds
- x_scale = outw / inw
- y_scale = outh / inh
- if DEBUG and (x_scale == 0 or y_scale == 0):
- raise ValueError("Transforming from or to a singular bounding box.")
- self._mtx = np.array([[x_scale, 0.0 , (-inl*x_scale+outl)],
- [0.0 , y_scale, (-inb*y_scale+outb)],
- [0.0 , 0.0 , 1.0 ]],
- float)
- self._inverted = None
- self._invalid = 0
- return self._mtx
- get_matrix.__doc__ = Affine2DBase.get_matrix.__doc__
-
-
-class BboxTransformTo(Affine2DBase):
- """
- :class:`BboxTransformTo` is a transformation that linearly
- transforms points from the unit bounding box to a given
- :class:`Bbox`.
- """
- is_separable = True
-
- def __init__(self, boxout, **kwargs):
- """
- Create a new :class:`BboxTransformTo` that linearly transforms
- points from the unit bounding box to *boxout*.
- """
- if not boxout.is_bbox:
- raise ValueError("'boxout' must be bbox")
-
- Affine2DBase.__init__(self, **kwargs)
- self._boxout = boxout
- self.set_children(boxout)
- self._mtx = None
- self._inverted = None
-
- def __str__(self):
- return ("{}(\n"
- "{})"
- .format(type(self).__name__,
- _indent_str(self._boxout)))
-
- def get_matrix(self):
- if self._invalid:
- outl, outb, outw, outh = self._boxout.bounds
- if DEBUG and (outw == 0 or outh == 0):
- raise ValueError("Transforming to a singular bounding box.")
- self._mtx = np.array([[outw, 0.0, outl],
- [ 0.0, outh, outb],
- [ 0.0, 0.0, 1.0]],
- float)
- self._inverted = None
- self._invalid = 0
- return self._mtx
- get_matrix.__doc__ = Affine2DBase.get_matrix.__doc__
-
-
-class BboxTransformToMaxOnly(BboxTransformTo):
- """
- :class:`BboxTransformTo` is a transformation that linearly
- transforms points from the unit bounding box to a given
- :class:`Bbox` with a fixed upper left of (0, 0).
- """
- def get_matrix(self):
- if self._invalid:
- xmax, ymax = self._boxout.max
- if DEBUG and (xmax == 0 or ymax == 0):
- raise ValueError("Transforming to a singular bounding box.")
- self._mtx = np.array([[xmax, 0.0, 0.0],
- [ 0.0, ymax, 0.0],
- [ 0.0, 0.0, 1.0]],
- float)
- self._inverted = None
- self._invalid = 0
- return self._mtx
- get_matrix.__doc__ = Affine2DBase.get_matrix.__doc__
-
-
-class BboxTransformFrom(Affine2DBase):
- """
- :class:`BboxTransformFrom` linearly transforms points from a given
- :class:`Bbox` to the unit bounding box.
- """
- is_separable = True
-
- def __init__(self, boxin, **kwargs):
- if not boxin.is_bbox:
- raise ValueError("'boxin' must be bbox")
-
- Affine2DBase.__init__(self, **kwargs)
- self._boxin = boxin
- self.set_children(boxin)
- self._mtx = None
- self._inverted = None
-
- def __str__(self):
- return ("{}(\n"
- "{})"
- .format(type(self).__name__,
- _indent_str(self._boxin)))
-
- def get_matrix(self):
- if self._invalid:
- inl, inb, inw, inh = self._boxin.bounds
- if DEBUG and (inw == 0 or inh == 0):
- raise ValueError("Transforming from a singular bounding box.")
- x_scale = 1.0 / inw
- y_scale = 1.0 / inh
- self._mtx = np.array([[x_scale, 0.0 , (-inl*x_scale)],
- [0.0 , y_scale, (-inb*y_scale)],
- [0.0 , 0.0 , 1.0 ]],
- float)
- self._inverted = None
- self._invalid = 0
- return self._mtx
- get_matrix.__doc__ = Affine2DBase.get_matrix.__doc__
-
-
-class ScaledTranslation(Affine2DBase):
- """
- A transformation that translates by *xt* and *yt*, after *xt* and *yt*
- have been transformad by the given transform *scale_trans*.
- """
- def __init__(self, xt, yt, scale_trans, **kwargs):
- Affine2DBase.__init__(self, **kwargs)
- self._t = (xt, yt)
- self._scale_trans = scale_trans
- self.set_children(scale_trans)
- self._mtx = None
- self._inverted = None
-
- def __str__(self):
- return ("{}(\n"
- "{})"
- .format(type(self).__name__,
- _indent_str(self._t)))
-
- def get_matrix(self):
- if self._invalid:
- xt, yt = self._scale_trans.transform_point(self._t)
- self._mtx = np.array([[1.0, 0.0, xt],
- [0.0, 1.0, yt],
- [0.0, 0.0, 1.0]],
- float)
- self._invalid = 0
- self._inverted = None
- return self._mtx
- get_matrix.__doc__ = Affine2DBase.get_matrix.__doc__
-
-
-class TransformedPath(TransformNode):
- """
- A :class:`TransformedPath` caches a non-affine transformed copy of
- the :class:`~matplotlib.path.Path`. This cached copy is
- automatically updated when the non-affine part of the transform
- changes.
-
- .. note::
-
- Paths are considered immutable by this class. Any update to the
- path's vertices/codes will not trigger a transform recomputation.
-
- """
- def __init__(self, path, transform):
- """
- Create a new :class:`TransformedPath` from the given
- :class:`~matplotlib.path.Path` and :class:`Transform`.
- """
- if not isinstance(transform, Transform):
- raise ValueError("'transform' must be an instance of "
- "'matplotlib.transform.Transform'")
- TransformNode.__init__(self)
-
- self._path = path
- self._transform = transform
- self.set_children(transform)
- self._transformed_path = None
- self._transformed_points = None
-
- def _revalidate(self):
- # only recompute if the invalidation includes the non_affine part of the transform
- if ((self._invalid & self.INVALID_NON_AFFINE == self.INVALID_NON_AFFINE)
- or self._transformed_path is None):
- self._transformed_path = \
- self._transform.transform_path_non_affine(self._path)
- self._transformed_points = \
- Path._fast_from_codes_and_verts(
- self._transform.transform_non_affine(self._path.vertices),
- None,
- {'interpolation_steps': self._path._interpolation_steps,
- 'should_simplify': self._path.should_simplify})
- self._invalid = 0
-
- def get_transformed_points_and_affine(self):
- """
- Return a copy of the child path, with the non-affine part of
- the transform already applied, along with the affine part of
- the path necessary to complete the transformation. Unlike
- :meth:`get_transformed_path_and_affine`, no interpolation will
- be performed.
- """
- self._revalidate()
- return self._transformed_points, self.get_affine()
-
- def get_transformed_path_and_affine(self):
- """
- Return a copy of the child path, with the non-affine part of
- the transform already applied, along with the affine part of
- the path necessary to complete the transformation.
- """
- self._revalidate()
- return self._transformed_path, self.get_affine()
-
- def get_fully_transformed_path(self):
- """
- Return a fully-transformed copy of the child path.
- """
- self._revalidate()
- return self._transform.transform_path_affine(self._transformed_path)
-
- def get_affine(self):
- return self._transform.get_affine()
-
-
-class TransformedPatchPath(TransformedPath):
- """
- A :class:`TransformedPatchPath` caches a non-affine transformed copy of
- the :class:`~matplotlib.path.Patch`. This cached copy is automatically
- updated when the non-affine part of the transform or the patch changes.
- """
- def __init__(self, patch):
- """
- Create a new :class:`TransformedPatchPath` from the given
- :class:`~matplotlib.path.Patch`.
- """
- TransformNode.__init__(self)
-
- transform = patch.get_transform()
- self._patch = patch
- self._transform = transform
- self.set_children(transform)
- self._path = patch.get_path()
- self._transformed_path = None
- self._transformed_points = None
-
- def _revalidate(self):
- patch_path = self._patch.get_path()
- # Only recompute if the invalidation includes the non_affine part of
- # the transform, or the Patch's Path has changed.
- if (self._transformed_path is None or self._path != patch_path or
- (self._invalid & self.INVALID_NON_AFFINE ==
- self.INVALID_NON_AFFINE)):
- self._path = patch_path
- self._transformed_path = \
- self._transform.transform_path_non_affine(patch_path)
- self._transformed_points = \
- Path._fast_from_codes_and_verts(
- self._transform.transform_non_affine(patch_path.vertices),
- None,
- {'interpolation_steps': patch_path._interpolation_steps,
- 'should_simplify': patch_path.should_simplify})
- self._invalid = 0
-
-
-def nonsingular(vmin, vmax, expander=0.001, tiny=1e-15, increasing=True):
- """
- Modify the endpoints of a range as needed to avoid singularities.
-
- Parameters
- ----------
- vmin, vmax : float
- The initial endpoints.
- expander : float, optional, default: 0.001
- Fractional amount by which *vmin* and *vmax* are expanded if
- the original interval is too small, based on *tiny*.
- tiny : float, optional, default: 1e-15
- Threshold for the ratio of the interval to the maximum absolute
- value of its endpoints. If the interval is smaller than
- this, it will be expanded. This value should be around
- 1e-15 or larger; otherwise the interval will be approaching
- the double precision resolution limit.
- increasing : bool, optional, default: True
- If True, swap *vmin*, *vmax* if *vmin* > *vmax*.
-
- Returns
- -------
- vmin, vmax : float
- Endpoints, expanded and/or swapped if necessary.
- If either input is inf or NaN, or if both inputs are 0 or very
- close to zero, it returns -*expander*, *expander*.
- """
-
- if (not np.isfinite(vmin)) or (not np.isfinite(vmax)):
- return -expander, expander
-
- swapped = False
- if vmax < vmin:
- vmin, vmax = vmax, vmin
- swapped = True
-
- maxabsvalue = max(abs(vmin), abs(vmax))
- if maxabsvalue < (1e6 / tiny) * np.finfo(float).tiny:
- vmin = -expander
- vmax = expander
-
- elif vmax - vmin <= maxabsvalue * tiny:
- if vmax == 0 and vmin == 0:
- vmin = -expander
- vmax = expander
- else:
- vmin -= expander*abs(vmin)
- vmax += expander*abs(vmax)
-
- if swapped and not increasing:
- vmin, vmax = vmax, vmin
- return vmin, vmax
-
-
-def interval_contains(interval, val):
- """
- Check, inclusively, whether an interval includes a given value.
-
- Parameters
- ----------
- interval : sequence of scalar
- A 2-length sequence, endpoints that define the interval.
- val : scalar
- Value to check is within interval.
-
- Returns
- -------
- bool
- Returns true if given val is within the interval.
- """
- a, b = interval
- return a <= val <= b or a >= val >= b
-
-
-def interval_contains_open(interval, val):
- """
- Check, excluding endpoints, whether an interval includes a given value.
-
- Parameters
- ----------
- interval : sequence of scalar
- A 2-length sequence, endpoints that define the interval.
- val : scalar
- Value to check is within interval.
-
- Returns
- -------
- bool
- Returns true if given val is within the interval.
- """
- a, b = interval
- return a < val < b or a > val > b
-
-
-def offset_copy(trans, fig=None, x=0.0, y=0.0, units='inches'):
- """
- Return a new transform with an added offset.
-
- Parameters
- ----------
- trans : :class:`Transform` instance
- Any transform, to which offset will be applied.
- fig : :class:`~matplotlib.figure.Figure`, optional, default: None
- Current figure. It can be None if *units* are 'dots'.
- x, y : float, optional, default: 0.0
- Specifies the offset to apply.
- units : {'inches', 'points', 'dots'}, optional
- Units of the offset.
-
- Returns
- -------
- trans : :class:`Transform` instance
- Transform with applied offset.
- """
- if units == 'dots':
- return trans + Affine2D().translate(x, y)
- if fig is None:
- raise ValueError('For units of inches or points a fig kwarg is needed')
- if units == 'points':
- x /= 72.0
- y /= 72.0
- elif not units == 'inches':
- raise ValueError('units must be dots, points, or inches')
- return trans + ScaledTranslation(x, y, fig.dpi_scale_trans)
diff --git a/contrib/python/matplotlib/py2/matplotlib/tri/__init__.py b/contrib/python/matplotlib/py2/matplotlib/tri/__init__.py
deleted file mode 100644
index 7ea09f8b3f..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/tri/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-"""
-Unstructured triangular grid functions.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from .triangulation import *
-from .tricontour import *
-from .tritools import *
-from .trifinder import *
-from .triinterpolate import *
-from .trirefine import *
-from .tripcolor import *
-from .triplot import *
diff --git a/contrib/python/matplotlib/py2/matplotlib/tri/_tri.cpp b/contrib/python/matplotlib/py2/matplotlib/tri/_tri.cpp
deleted file mode 100644
index a27beff7f9..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/tri/_tri.cpp
+++ /dev/null
@@ -1,1999 +0,0 @@
-/* This file contains liberal use of asserts to assist code development and
- * debugging. Standard matplotlib builds disable asserts so they cause no
- * performance reduction. To enable the asserts, you need to undefine the
- * NDEBUG macro, which is achieved by adding the following
- * undef_macros=['NDEBUG']
- * to the appropriate make_extension call in setupext.py, and then rebuilding.
- */
-#define NO_IMPORT_ARRAY
-
-#include "_tri.h"
-
-#include <algorithm>
-#include <set>
-
-#define MOVETO 1
-#define LINETO 2
-
-
-
-TriEdge::TriEdge()
- : tri(-1), edge(-1)
-{}
-
-TriEdge::TriEdge(int tri_, int edge_)
- : tri(tri_), edge(edge_)
-{}
-
-bool TriEdge::operator<(const TriEdge& other) const
-{
- if (tri != other.tri)
- return tri < other.tri;
- else
- return edge < other.edge;
-}
-
-bool TriEdge::operator==(const TriEdge& other) const
-{
- return tri == other.tri && edge == other.edge;
-}
-
-bool TriEdge::operator!=(const TriEdge& other) const
-{
- return !operator==(other);
-}
-
-std::ostream& operator<<(std::ostream& os, const TriEdge& tri_edge)
-{
- return os << tri_edge.tri << ' ' << tri_edge.edge;
-}
-
-
-
-XY::XY()
-{}
-
-XY::XY(const double& x_, const double& y_)
- : x(x_), y(y_)
-{}
-
-double XY::angle() const
-{
- return atan2(y, x);
-}
-
-double XY::cross_z(const XY& other) const
-{
- return x*other.y - y*other.x;
-}
-
-bool XY::is_right_of(const XY& other) const
-{
- if (x == other.x)
- return y > other.y;
- else
- return x > other.x;
-}
-
-bool XY::operator==(const XY& other) const
-{
- return x == other.x && y == other.y;
-}
-
-bool XY::operator!=(const XY& other) const
-{
- return x != other.x || y != other.y;
-}
-
-XY XY::operator*(const double& multiplier) const
-{
- return XY(x*multiplier, y*multiplier);
-}
-
-const XY& XY::operator+=(const XY& other)
-{
- x += other.x;
- y += other.y;
- return *this;
-}
-
-const XY& XY::operator-=(const XY& other)
-{
- x -= other.x;
- y -= other.y;
- return *this;
-}
-
-XY XY::operator+(const XY& other) const
-{
- return XY(x + other.x, y + other.y);
-}
-
-XY XY::operator-(const XY& other) const
-{
- return XY(x - other.x, y - other.y);
-}
-
-std::ostream& operator<<(std::ostream& os, const XY& xy)
-{
- return os << '(' << xy.x << ' ' << xy.y << ')';
-}
-
-
-
-XYZ::XYZ(const double& x_, const double& y_, const double& z_)
- : x(x_), y(y_), z(z_)
-{}
-
-XYZ XYZ::cross(const XYZ& other) const
-{
- return XYZ(y*other.z - z*other.y,
- z*other.x - x*other.z,
- x*other.y - y*other.x);
-}
-
-double XYZ::dot(const XYZ& other) const
-{
- return x*other.x + y*other.y + z*other.z;
-}
-
-double XYZ::length_squared() const
-{
- return x*x + y*y + z*z;
-}
-
-XYZ XYZ::operator-(const XYZ& other) const
-{
- return XYZ(x - other.x, y - other.y, z - other.z);
-}
-
-std::ostream& operator<<(std::ostream& os, const XYZ& xyz)
-{
- return os << '(' << xyz.x << ' ' << xyz.y << ' ' << xyz.z << ')';
-}
-
-
-
-BoundingBox::BoundingBox()
- : empty(true)
-{}
-
-void BoundingBox::add(const XY& point)
-{
- if (empty) {
- empty = false;
- lower = upper = point;
- } else {
- if (point.x < lower.x) lower.x = point.x;
- else if (point.x > upper.x) upper.x = point.x;
-
- if (point.y < lower.y) lower.y = point.y;
- else if (point.y > upper.y) upper.y = point.y;
- }
-}
-
-void BoundingBox::expand(const XY& delta)
-{
- if (!empty) {
- lower -= delta;
- upper += delta;
- }
-}
-
-
-
-ContourLine::ContourLine()
- : std::vector<XY>()
-{}
-
-void ContourLine::insert_unique(iterator pos, const XY& point)
-{
- if (empty() || pos == end() || point != *pos)
- std::vector<XY>::insert(pos, point);
-}
-
-void ContourLine::push_back(const XY& point)
-{
- if (empty() || point != back())
- std::vector<XY>::push_back(point);
-}
-
-void ContourLine::write() const
-{
- std::cout << "ContourLine of " << size() << " points:";
- for (const_iterator it = begin(); it != end(); ++it)
- std::cout << ' ' << *it;
- std::cout << std::endl;
-}
-
-
-
-void write_contour(const Contour& contour)
-{
- std::cout << "Contour of " << contour.size() << " lines." << std::endl;
- for (Contour::const_iterator it = contour.begin(); it != contour.end(); ++it)
- it->write();
-}
-
-
-
-Triangulation::Triangulation(const CoordinateArray& x,
- const CoordinateArray& y,
- const TriangleArray& triangles,
- const MaskArray& mask,
- const EdgeArray& edges,
- const NeighborArray& neighbors,
- int correct_triangle_orientations)
- : _x(x),
- _y(y),
- _triangles(triangles),
- _mask(mask),
- _edges(edges),
- _neighbors(neighbors)
-{
- if (correct_triangle_orientations)
- correct_triangles();
-}
-
-void Triangulation::calculate_boundaries()
-{
- get_neighbors(); // Ensure _neighbors has been created.
-
- // Create set of all boundary TriEdges, which are those which do not
- // have a neighbor triangle.
- typedef std::set<TriEdge> BoundaryEdges;
- BoundaryEdges boundary_edges;
- for (int tri = 0; tri < get_ntri(); ++tri) {
- if (!is_masked(tri)) {
- for (int edge = 0; edge < 3; ++edge) {
- if (get_neighbor(tri, edge) == -1) {
- boundary_edges.insert(TriEdge(tri, edge));
- }
- }
- }
- }
-
- // Take any boundary edge and follow the boundary until return to start
- // point, removing edges from boundary_edges as they are used. At the same
- // time, initialise the _tri_edge_to_boundary_map.
- while (!boundary_edges.empty()) {
- // Start of new boundary.
- BoundaryEdges::iterator it = boundary_edges.begin();
- int tri = it->tri;
- int edge = it->edge;
- _boundaries.push_back(Boundary());
- Boundary& boundary = _boundaries.back();
-
- while (true) {
- boundary.push_back(TriEdge(tri, edge));
- boundary_edges.erase(it);
- _tri_edge_to_boundary_map[TriEdge(tri, edge)] =
- BoundaryEdge(_boundaries.size()-1, boundary.size()-1);
-
- // Move to next edge of current triangle.
- edge = (edge+1) % 3;
-
- // Find start point index of boundary edge.
- int point = get_triangle_point(tri, edge);
-
- // Find next TriEdge by traversing neighbors until find one
- // without a neighbor.
- while (get_neighbor(tri, edge) != -1) {
- tri = get_neighbor(tri, edge);
- edge = get_edge_in_triangle(tri, point);
- }
-
- if (TriEdge(tri,edge) == boundary.front())
- break; // Reached beginning of this boundary, so finished it.
- else
- it = boundary_edges.find(TriEdge(tri, edge));
- }
- }
-}
-
-void Triangulation::calculate_edges()
-{
- assert(_edges.empty() && "Expected empty edges array");
-
- // Create set of all edges, storing them with start point index less than
- // end point index.
- typedef std::set<Edge> EdgeSet;
- EdgeSet edge_set;
- for (int tri = 0; tri < get_ntri(); ++tri) {
- if (!is_masked(tri)) {
- for (int edge = 0; edge < 3; edge++) {
- int start = get_triangle_point(tri, edge);
- int end = get_triangle_point(tri, (edge+1)%3);
- edge_set.insert(start > end ? Edge(start,end) : Edge(end,start));
- }
- }
- }
-
- // Convert to python _edges array.
- npy_intp dims[2] = {static_cast<npy_intp>(edge_set.size()), 2};
- _edges = EdgeArray(dims);
-
- int i = 0;
- for (EdgeSet::const_iterator it = edge_set.begin(); it != edge_set.end(); ++it) {
- _edges(i, 0) = it->start;
- _edges(i++, 1) = it->end;
- }
-}
-
-void Triangulation::calculate_neighbors()
-{
- assert(_neighbors.empty() && "Expected empty neighbors array");
-
- // Create _neighbors array with shape (ntri,3) and initialise all to -1.
- npy_intp dims[2] = {get_ntri(), 3};
- _neighbors = NeighborArray(dims);
-
- int tri, edge;
- for (tri = 0; tri < get_ntri(); ++tri) {
- for (edge = 0; edge < 3; ++edge)
- _neighbors(tri, edge) = -1;
- }
-
- // For each triangle edge (start to end point), find corresponding neighbor
- // edge from end to start point. Do this by traversing all edges and
- // storing them in a map from edge to TriEdge. If corresponding neighbor
- // edge is already in the map, don't need to store new edge as neighbor
- // already found.
- typedef std::map<Edge, TriEdge> EdgeToTriEdgeMap;
- EdgeToTriEdgeMap edge_to_tri_edge_map;
- for (tri = 0; tri < get_ntri(); ++tri) {
- if (!is_masked(tri)) {
- for (edge = 0; edge < 3; ++edge) {
- int start = get_triangle_point(tri, edge);
- int end = get_triangle_point(tri, (edge+1)%3);
- EdgeToTriEdgeMap::iterator it =
- edge_to_tri_edge_map.find(Edge(end,start));
- if (it == edge_to_tri_edge_map.end()) {
- // No neighbor edge exists in the edge_to_tri_edge_map, so
- // add this edge to it.
- edge_to_tri_edge_map[Edge(start,end)] = TriEdge(tri,edge);
- } else {
- // Neighbor edge found, set the two elements of _neighbors
- // and remove edge from edge_to_tri_edge_map.
- _neighbors(tri, edge)= it->second.tri;
- _neighbors(it->second.tri, it->second.edge) = tri;
- edge_to_tri_edge_map.erase(it);
- }
- }
- }
- }
-
- // Note that remaining edges in the edge_to_tri_edge_map correspond to
- // boundary edges, but the boundaries are calculated separately elsewhere.
-}
-
-Triangulation::TwoCoordinateArray Triangulation::calculate_plane_coefficients(
- const CoordinateArray& z)
-{
- npy_intp dims[2] = {get_ntri(), 3};
- Triangulation::TwoCoordinateArray planes(dims);
-
- int point;
- for (int tri = 0; tri < get_ntri(); ++tri) {
- if (is_masked(tri)) {
- planes(tri, 0) = 0.0;
- planes(tri, 1) = 0.0;
- planes(tri, 2) = 0.0;
- }
- else {
- // Equation of plane for all points r on plane is r.normal = p
- // where normal is vector normal to the plane, and p is a
- // constant. Rewrite as
- // r_x*normal_x + r_y*normal_y + r_z*normal_z = p
- // and rearrange to give
- // r_z = (-normal_x/normal_z)*r_x + (-normal_y/normal_z)*r_y +
- // p/normal_z
- point = _triangles(tri, 0);
- XYZ point0(_x(point), _y(point), z(point));
- point = _triangles(tri, 1);
- XYZ side01 = XYZ(_x(point), _y(point), z(point)) - point0;
- point = _triangles(tri, 2);
- XYZ side02 = XYZ(_x(point), _y(point), z(point)) - point0;
-
- XYZ normal = side01.cross(side02);
-
- if (normal.z == 0.0) {
- // Normal is in x-y plane which means triangle consists of
- // colinear points. To avoid dividing by zero, we use the
- // Moore-Penrose pseudo-inverse.
- double sum2 = (side01.x*side01.x + side01.y*side01.y +
- side02.x*side02.x + side02.y*side02.y);
- double a = (side01.x*side01.z + side02.x*side02.z) / sum2;
- double b = (side01.y*side01.z + side02.y*side02.z) / sum2;
- planes(tri, 0) = a;
- planes(tri, 1) = b;
- planes(tri, 2) = point0.z - a*point0.x - b*point0.y;
- }
- else {
- planes(tri, 0) = -normal.x / normal.z; // x
- planes(tri, 1) = -normal.y / normal.z; // y
- planes(tri, 2) = normal.dot(point0) / normal.z; // constant
- }
- }
- }
-
- return planes;
-}
-
-void Triangulation::correct_triangles()
-{
- for (int tri = 0; tri < get_ntri(); ++tri) {
- XY point0 = get_point_coords(_triangles(tri, 0));
- XY point1 = get_point_coords(_triangles(tri, 1));
- XY point2 = get_point_coords(_triangles(tri, 2));
- if ( (point1 - point0).cross_z(point2 - point0) < 0.0) {
- // Triangle points are clockwise, so change them to anticlockwise.
- std::swap(_triangles(tri, 1), _triangles(tri, 2));
- if (!_neighbors.empty())
- std::swap(_neighbors(tri, 1), _neighbors(tri, 2));
- }
- }
-}
-
-const Triangulation::Boundaries& Triangulation::get_boundaries() const
-{
- if (_boundaries.empty())
- const_cast<Triangulation*>(this)->calculate_boundaries();
- return _boundaries;
-}
-
-void Triangulation::get_boundary_edge(const TriEdge& triEdge,
- int& boundary,
- int& edge) const
-{
- get_boundaries(); // Ensure _tri_edge_to_boundary_map has been created.
- TriEdgeToBoundaryMap::const_iterator it =
- _tri_edge_to_boundary_map.find(triEdge);
- assert(it != _tri_edge_to_boundary_map.end() &&
- "TriEdge is not on a boundary");
- boundary = it->second.boundary;
- edge = it->second.edge;
-}
-
-int Triangulation::get_edge_in_triangle(int tri, int point) const
-{
- assert(tri >= 0 && tri < get_ntri() && "Triangle index out of bounds");
- assert(point >= 0 && point < get_npoints() && "Point index out of bounds.");
- for (int edge = 0; edge < 3; ++edge) {
- if (_triangles(tri, edge) == point)
- return edge;
- }
- return -1; // point is not in triangle.
-}
-
-Triangulation::EdgeArray& Triangulation::get_edges()
-{
- if (_edges.empty())
- calculate_edges();
- return _edges;
-}
-
-int Triangulation::get_neighbor(int tri, int edge) const
-{
- assert(tri >= 0 && tri < get_ntri() && "Triangle index out of bounds");
- assert(edge >= 0 && edge < 3 && "Edge index out of bounds");
- if (_neighbors.empty())
- const_cast<Triangulation&>(*this).calculate_neighbors();
- return _neighbors(tri, edge);
-}
-
-TriEdge Triangulation::get_neighbor_edge(int tri, int edge) const
-{
- int neighbor_tri = get_neighbor(tri, edge);
- if (neighbor_tri == -1)
- return TriEdge(-1,-1);
- else
- return TriEdge(neighbor_tri,
- get_edge_in_triangle(neighbor_tri,
- get_triangle_point(tri,
- (edge+1)%3)));
-}
-
-Triangulation::NeighborArray& Triangulation::get_neighbors()
-{
- if (_neighbors.empty())
- calculate_neighbors();
- return _neighbors;
-}
-
-int Triangulation::get_npoints() const
-{
- return _x.size();
-}
-
-int Triangulation::get_ntri() const
-{
- return _triangles.size();
-}
-
-XY Triangulation::get_point_coords(int point) const
-{
- assert(point >= 0 && point < get_npoints() && "Point index out of bounds.");
- return XY(_x(point), _y(point));
-}
-
-int Triangulation::get_triangle_point(int tri, int edge) const
-{
- assert(tri >= 0 && tri < get_ntri() && "Triangle index out of bounds");
- assert(edge >= 0 && edge < 3 && "Edge index out of bounds");
- return _triangles(tri, edge);
-}
-
-int Triangulation::get_triangle_point(const TriEdge& tri_edge) const
-{
- return get_triangle_point(tri_edge.tri, tri_edge.edge);
-}
-
-bool Triangulation::is_masked(int tri) const
-{
- assert(tri >= 0 && tri < get_ntri() && "Triangle index out of bounds.");
- const npy_bool* mask_ptr = reinterpret_cast<const npy_bool*>(_mask.data());
- return !_mask.empty() && mask_ptr[tri];
-}
-
-void Triangulation::set_mask(const MaskArray& mask)
-{
- _mask = mask;
-
- // Clear derived fields so they are recalculated when needed.
- _edges = EdgeArray();
- _neighbors = NeighborArray();
- _boundaries.clear();
-}
-
-void Triangulation::write_boundaries() const
-{
- const Boundaries& bs = get_boundaries();
- std::cout << "Number of boundaries: " << bs.size() << std::endl;
- for (Boundaries::const_iterator it = bs.begin(); it != bs.end(); ++it) {
- const Boundary& b = *it;
- std::cout << " Boundary of " << b.size() << " points: ";
- for (Boundary::const_iterator itb = b.begin(); itb != b.end(); ++itb) {
- std::cout << *itb << ", ";
- }
- std::cout << std::endl;
- }
-}
-
-
-
-TriContourGenerator::TriContourGenerator(Triangulation& triangulation,
- const CoordinateArray& z)
- : _triangulation(triangulation),
- _z(z),
- _interior_visited(2*_triangulation.get_ntri()),
- _boundaries_visited(0),
- _boundaries_used(0)
-{}
-
-void TriContourGenerator::clear_visited_flags(bool include_boundaries)
-{
- // Clear _interiorVisited.
- std::fill(_interior_visited.begin(), _interior_visited.end(), false);
-
- if (include_boundaries) {
- if (_boundaries_visited.empty()) {
- const Boundaries& boundaries = get_boundaries();
-
- // Initialise _boundaries_visited.
- _boundaries_visited.reserve(boundaries.size());
- for (Boundaries::const_iterator it = boundaries.begin();
- it != boundaries.end(); ++it)
- _boundaries_visited.push_back(BoundaryVisited(it->size()));
-
- // Initialise _boundaries_used.
- _boundaries_used = BoundariesUsed(boundaries.size());
- }
-
- // Clear _boundaries_visited.
- for (BoundariesVisited::iterator it = _boundaries_visited.begin();
- it != _boundaries_visited.end(); ++it)
- std::fill(it->begin(), it->end(), false);
-
- // Clear _boundaries_used.
- std::fill(_boundaries_used.begin(), _boundaries_used.end(), false);
- }
-}
-
-PyObject* TriContourGenerator::contour_to_segs(const Contour& contour)
-{
- PyObject* segs = PyList_New(contour.size());
- for (Contour::size_type i = 0; i < contour.size(); ++i) {
- const ContourLine& line = contour[i];
- npy_intp dims[2] = {static_cast<npy_intp>(line.size()),2};
- PyArrayObject* py_line = (PyArrayObject*)PyArray_SimpleNew(
- 2, dims, NPY_DOUBLE);
- double* p = (double*)PyArray_DATA(py_line);
- for (ContourLine::const_iterator it = line.begin(); it != line.end(); ++it) {
- *p++ = it->x;
- *p++ = it->y;
- }
- if (PyList_SetItem(segs, i, (PyObject*)py_line)) {
- Py_XDECREF(segs);
- PyErr_SetString(PyExc_RuntimeError,
- "Unable to set contour segments");
- return NULL;
- }
- }
- return segs;
-}
-
-PyObject* TriContourGenerator::contour_to_segs_and_kinds(const Contour& contour)
-{
- Contour::const_iterator line;
- ContourLine::const_iterator point;
-
- // Find total number of points in all contour lines.
- int n_points = 0;
- for (line = contour.begin(); line != contour.end(); ++line)
- n_points += line->size();
-
- // Create segs array for point coordinates.
- npy_intp segs_dims[2] = {n_points, 2};
- PyArrayObject* segs = (PyArrayObject*)PyArray_SimpleNew(
- 2, segs_dims, NPY_DOUBLE);
- double* segs_ptr = (double*)PyArray_DATA(segs);
-
- // Create kinds array for code types.
- npy_intp kinds_dims[1] = {n_points};
- PyArrayObject* kinds = (PyArrayObject*)PyArray_SimpleNew(
- 1, kinds_dims, NPY_UBYTE);
- unsigned char* kinds_ptr = (unsigned char*)PyArray_DATA(kinds);
-
- for (line = contour.begin(); line != contour.end(); ++line) {
- for (point = line->begin(); point != line->end(); point++) {
- *segs_ptr++ = point->x;
- *segs_ptr++ = point->y;
- *kinds_ptr++ = (point == line->begin() ? MOVETO : LINETO);
- }
- }
-
- PyObject* result = PyTuple_New(2);
- if (PyTuple_SetItem(result, 0, (PyObject*)segs) ||
- PyTuple_SetItem(result, 1, (PyObject*)kinds)) {
- Py_XDECREF(result);
- PyErr_SetString(PyExc_RuntimeError,
- "Unable to set contour segments and kinds");
- return NULL;
- }
- return result;
-}
-
-PyObject* TriContourGenerator::create_contour(const double& level)
-{
- clear_visited_flags(false);
- Contour contour;
-
- find_boundary_lines(contour, level);
- find_interior_lines(contour, level, false, false);
-
- return contour_to_segs(contour);
-}
-
-PyObject* TriContourGenerator::create_filled_contour(const double& lower_level,
- const double& upper_level)
-{
- clear_visited_flags(true);
- Contour contour;
-
- find_boundary_lines_filled(contour, lower_level, upper_level);
- find_interior_lines(contour, lower_level, false, true);
- find_interior_lines(contour, upper_level, true, true);
-
- return contour_to_segs_and_kinds(contour);
-}
-
-XY TriContourGenerator::edge_interp(int tri, int edge, const double& level)
-{
- return interp(_triangulation.get_triangle_point(tri, edge),
- _triangulation.get_triangle_point(tri, (edge+1)%3),
- level);
-}
-
-void TriContourGenerator::find_boundary_lines(Contour& contour,
- const double& level)
-{
- // Traverse boundaries to find starting points for all contour lines that
- // intersect the boundaries. For each starting point found, follow the
- // line to its end before continuing.
- const Triangulation& triang = _triangulation;
- const Boundaries& boundaries = get_boundaries();
- for (Boundaries::const_iterator it = boundaries.begin();
- it != boundaries.end(); ++it) {
- const Boundary& boundary = *it;
- bool startAbove, endAbove = false;
- for (Boundary::const_iterator itb = boundary.begin();
- itb != boundary.end(); ++itb) {
- if (itb == boundary.begin())
- startAbove = get_z(triang.get_triangle_point(*itb)) >= level;
- else
- startAbove = endAbove;
- endAbove = get_z(triang.get_triangle_point(itb->tri,
- (itb->edge+1)%3)) >= level;
- if (startAbove && !endAbove) {
- // This boundary edge is the start point for a contour line,
- // so follow the line.
- contour.push_back(ContourLine());
- ContourLine& contour_line = contour.back();
- TriEdge tri_edge = *itb;
- follow_interior(contour_line, tri_edge, true, level, false);
- }
- }
- }
-}
-
-void TriContourGenerator::find_boundary_lines_filled(Contour& contour,
- const double& lower_level,
- const double& upper_level)
-{
- // Traverse boundaries to find starting points for all contour lines that
- // intersect the boundaries. For each starting point found, follow the
- // line to its end before continuing.
- const Triangulation& triang = _triangulation;
- const Boundaries& boundaries = get_boundaries();
- for (Boundaries::size_type i = 0; i < boundaries.size(); ++i) {
- const Boundary& boundary = boundaries[i];
- for (Boundary::size_type j = 0; j < boundary.size(); ++j) {
- if (!_boundaries_visited[i][j]) {
- // z values of start and end of this boundary edge.
- double z_start = get_z(triang.get_triangle_point(boundary[j]));
- double z_end = get_z(triang.get_triangle_point(
- boundary[j].tri, (boundary[j].edge+1)%3));
-
- // Does this boundary edge's z increase through upper level
- // and/or decrease through lower level?
- bool incr_upper = (z_start < upper_level && z_end >= upper_level);
- bool decr_lower = (z_start >= lower_level && z_end < lower_level);
-
- if (decr_lower || incr_upper) {
- // Start point for contour line, so follow it.
- contour.push_back(ContourLine());
- ContourLine& contour_line = contour.back();
- TriEdge start_tri_edge = boundary[j];
- TriEdge tri_edge = start_tri_edge;
-
- // Traverse interior and boundaries until return to start.
- bool on_upper = incr_upper;
- do {
- follow_interior(contour_line, tri_edge, true,
- on_upper ? upper_level : lower_level, on_upper);
- on_upper = follow_boundary(contour_line, tri_edge,
- lower_level, upper_level, on_upper);
- } while (tri_edge != start_tri_edge);
-
- // Filled contour lines must not have same first and last
- // points.
- if (contour_line.size() > 1 &&
- contour_line.front() == contour_line.back())
- contour_line.pop_back();
- }
- }
- }
- }
-
- // Add full boundaries that lie between the lower and upper levels. These
- // are boundaries that have not been touched by an internal contour line
- // which are stored in _boundaries_used.
- for (Boundaries::size_type i = 0; i < boundaries.size(); ++i) {
- if (!_boundaries_used[i]) {
- const Boundary& boundary = boundaries[i];
- double z = get_z(triang.get_triangle_point(boundary[0]));
- if (z >= lower_level && z < upper_level) {
- contour.push_back(ContourLine());
- ContourLine& contour_line = contour.back();
- for (Boundary::size_type j = 0; j < boundary.size(); ++j)
- contour_line.push_back(triang.get_point_coords(
- triang.get_triangle_point(boundary[j])));
- }
- }
- }
-}
-
-void TriContourGenerator::find_interior_lines(Contour& contour,
- const double& level,
- bool on_upper,
- bool filled)
-{
- const Triangulation& triang = _triangulation;
- int ntri = triang.get_ntri();
- for (int tri = 0; tri < ntri; ++tri) {
- int visited_index = (on_upper ? tri+ntri : tri);
-
- if (_interior_visited[visited_index] || triang.is_masked(tri))
- continue; // Triangle has already been visited or is masked.
-
- _interior_visited[visited_index] = true;
-
- // Determine edge via which to leave this triangle.
- int edge = get_exit_edge(tri, level, on_upper);
- assert(edge >= -1 && edge < 3 && "Invalid exit edge");
- if (edge == -1)
- continue; // Contour does not pass through this triangle.
-
- // Found start of new contour line loop.
- contour.push_back(ContourLine());
- ContourLine& contour_line = contour.back();
- TriEdge tri_edge = triang.get_neighbor_edge(tri, edge);
- follow_interior(contour_line, tri_edge, false, level, on_upper);
-
- if (!filled)
- // Non-filled contour lines must be closed.
- contour_line.push_back(contour_line.front());
- else if (contour_line.size() > 1 &&
- contour_line.front() == contour_line.back())
- // Filled contour lines must not have same first and last points.
- contour_line.pop_back();
- }
-}
-
-bool TriContourGenerator::follow_boundary(ContourLine& contour_line,
- TriEdge& tri_edge,
- const double& lower_level,
- const double& upper_level,
- bool on_upper)
-{
- const Triangulation& triang = _triangulation;
- const Boundaries& boundaries = get_boundaries();
-
- // Have TriEdge to start at, need equivalent boundary edge.
- int boundary, edge;
- triang.get_boundary_edge(tri_edge, boundary, edge);
- _boundaries_used[boundary] = true;
-
- bool stop = false;
- bool first_edge = true;
- double z_start, z_end = 0;
- while (!stop)
- {
- assert(!_boundaries_visited[boundary][edge] && "Boundary already visited");
- _boundaries_visited[boundary][edge] = true;
-
- // z values of start and end points of boundary edge.
- if (first_edge)
- z_start = get_z(triang.get_triangle_point(tri_edge));
- else
- z_start = z_end;
- z_end = get_z(triang.get_triangle_point(tri_edge.tri,
- (tri_edge.edge+1)%3));
-
- if (z_end > z_start) { // z increasing.
- if (!(!on_upper && first_edge) &&
- z_end >= lower_level && z_start < lower_level) {
- stop = true;
- on_upper = false;
- } else if (z_end >= upper_level && z_start < upper_level) {
- stop = true;
- on_upper = true;
- }
- } else { // z decreasing.
- if (!(on_upper && first_edge) &&
- z_start >= upper_level && z_end < upper_level) {
- stop = true;
- on_upper = true;
- } else if (z_start >= lower_level && z_end < lower_level) {
- stop = true;
- on_upper = false;
- }
- }
-
- first_edge = false;
-
- if (!stop) {
- // Move to next boundary edge, adding point to contour line.
- edge = (edge+1) % (int)boundaries[boundary].size();
- tri_edge = boundaries[boundary][edge];
- contour_line.push_back(triang.get_point_coords(
- triang.get_triangle_point(tri_edge)));
- }
- }
-
- return on_upper;
-}
-
-void TriContourGenerator::follow_interior(ContourLine& contour_line,
- TriEdge& tri_edge,
- bool end_on_boundary,
- const double& level,
- bool on_upper)
-{
- int& tri = tri_edge.tri;
- int& edge = tri_edge.edge;
-
- // Initial point.
- contour_line.push_back(edge_interp(tri, edge, level));
-
- while (true) {
- int visited_index = tri;
- if (on_upper)
- visited_index += _triangulation.get_ntri();
-
- // Check for end not on boundary.
- if (!end_on_boundary && _interior_visited[visited_index])
- break; // Reached start point, so return.
-
- // Determine edge by which to leave this triangle.
- edge = get_exit_edge(tri, level, on_upper);
- assert(edge >= 0 && edge < 3 && "Invalid exit edge");
-
- _interior_visited[visited_index] = true;
-
- // Append new point to point set.
- assert(edge >= 0 && edge < 3 && "Invalid triangle edge");
- contour_line.push_back(edge_interp(tri, edge, level));
-
- // Move to next triangle.
- TriEdge next_tri_edge = _triangulation.get_neighbor_edge(tri,edge);
-
- // Check if ending on a boundary.
- if (end_on_boundary && next_tri_edge.tri == -1)
- break;
-
- tri_edge = next_tri_edge;
- assert(tri_edge.tri != -1 && "Invalid triangle for internal loop");
- }
-}
-
-const TriContourGenerator::Boundaries& TriContourGenerator::get_boundaries() const
-{
- return _triangulation.get_boundaries();
-}
-
-int TriContourGenerator::get_exit_edge(int tri,
- const double& level,
- bool on_upper) const
-{
- assert(tri >= 0 && tri < _triangulation.get_ntri() &&
- "Triangle index out of bounds.");
-
- unsigned int config =
- (get_z(_triangulation.get_triangle_point(tri, 0)) >= level) |
- (get_z(_triangulation.get_triangle_point(tri, 1)) >= level) << 1 |
- (get_z(_triangulation.get_triangle_point(tri, 2)) >= level) << 2;
-
- if (on_upper) config = 7-config;
-
- switch (config) {
- case 0: return -1;
- case 1: return 2;
- case 2: return 0;
- case 3: return 2;
- case 4: return 1;
- case 5: return 1;
- case 6: return 0;
- case 7: return -1;
- default: assert(0 && "Invalid config value"); return -1;
- }
-}
-
-const double& TriContourGenerator::get_z(int point) const
-{
- assert(point >= 0 && point < _triangulation.get_npoints() &&
- "Point index out of bounds.");
- return _z(point);
-}
-
-XY TriContourGenerator::interp(int point1,
- int point2,
- const double& level) const
-{
- assert(point1 >= 0 && point1 < _triangulation.get_npoints() &&
- "Point index 1 out of bounds.");
- assert(point2 >= 0 && point2 < _triangulation.get_npoints() &&
- "Point index 2 out of bounds.");
- assert(point1 != point2 && "Identical points");
- double fraction = (get_z(point2) - level) / (get_z(point2) - get_z(point1));
- return _triangulation.get_point_coords(point1)*fraction +
- _triangulation.get_point_coords(point2)*(1.0 - fraction);
-}
-
-
-
-TrapezoidMapTriFinder::TrapezoidMapTriFinder(Triangulation& triangulation)
- : _triangulation(triangulation),
- _points(0),
- _tree(0)
-{}
-
-TrapezoidMapTriFinder::~TrapezoidMapTriFinder()
-{
- clear();
-}
-
-bool
-TrapezoidMapTriFinder::add_edge_to_tree(const Edge& edge)
-{
- std::vector<Trapezoid*> trapezoids;
- if (!find_trapezoids_intersecting_edge(edge, trapezoids))
- return false;
- assert(!trapezoids.empty() && "No trapezoids intersect edge");
-
- const Point* p = edge.left;
- const Point* q = edge.right;
- Trapezoid* left_old = 0; // old trapezoid to the left.
- Trapezoid* left_below = 0; // below trapezoid to the left.
- Trapezoid* left_above = 0; // above trapezoid to the left.
-
- // Iterate through trapezoids intersecting edge from left to right.
- // Replace each old trapezoid with 2+ new trapezoids, and replace its
- // corresponding nodes in the search tree with new nodes.
- unsigned int ntraps = trapezoids.size();
- for (unsigned int i = 0; i < ntraps; ++i) {
- Trapezoid* old = trapezoids[i]; // old trapezoid to replace.
- bool start_trap = (i == 0);
- bool end_trap = (i == ntraps-1);
- bool have_left = (start_trap && edge.left != old->left);
- bool have_right = (end_trap && edge.right != old->right);
-
- // Old trapezoid is replaced by up to 4 new trapezoids: left is to the
- // left of the start point p, below/above are below/above the edge
- // inserted, and right is to the right of the end point q.
- Trapezoid* left = 0;
- Trapezoid* below = 0;
- Trapezoid* above = 0;
- Trapezoid* right = 0;
-
- // There are 4 different cases here depending on whether the old
- // trapezoid in question is the start and/or end trapezoid of those
- // that intersect the edge inserted. There is some code duplication
- // here but it is much easier to understand this way rather than
- // interleave the 4 different cases with many more if-statements.
- if (start_trap && end_trap) {
- // Edge intersects a single trapezoid.
- if (have_left)
- left = new Trapezoid(old->left, p, old->below, old->above);
- below = new Trapezoid(p, q, old->below, edge);
- above = new Trapezoid(p, q, edge, old->above);
- if (have_right)
- right = new Trapezoid(q, old->right, old->below, old->above);
-
- // Set pairs of trapezoid neighbours.
- if (have_left) {
- left->set_lower_left(old->lower_left);
- left->set_upper_left(old->upper_left);
- left->set_lower_right(below);
- left->set_upper_right(above);
- }
- else {
- below->set_lower_left(old->lower_left);
- above->set_upper_left(old->upper_left);
- }
-
- if (have_right) {
- right->set_lower_right(old->lower_right);
- right->set_upper_right(old->upper_right);
- below->set_lower_right(right);
- above->set_upper_right(right);
- }
- else {
- below->set_lower_right(old->lower_right);
- above->set_upper_right(old->upper_right);
- }
- }
- else if (start_trap) {
- // Old trapezoid is the first of 2+ trapezoids that the edge
- // intersects.
- if (have_left)
- left = new Trapezoid(old->left, p, old->below, old->above);
- below = new Trapezoid(p, old->right, old->below, edge);
- above = new Trapezoid(p, old->right, edge, old->above);
-
- // Set pairs of trapezoid neighbours.
- if (have_left) {
- left->set_lower_left(old->lower_left);
- left->set_upper_left(old->upper_left);
- left->set_lower_right(below);
- left->set_upper_right(above);
- }
- else {
- below->set_lower_left(old->lower_left);
- above->set_upper_left(old->upper_left);
- }
-
- below->set_lower_right(old->lower_right);
- above->set_upper_right(old->upper_right);
- }
- else if (end_trap) {
- // Old trapezoid is the last of 2+ trapezoids that the edge
- // intersects.
- if (left_below->below == old->below) {
- below = left_below;
- below->right = q;
- }
- else
- below = new Trapezoid(old->left, q, old->below, edge);
-
- if (left_above->above == old->above) {
- above = left_above;
- above->right = q;
- }
- else
- above = new Trapezoid(old->left, q, edge, old->above);
-
- if (have_right)
- right = new Trapezoid(q, old->right, old->below, old->above);
-
- // Set pairs of trapezoid neighbours.
- if (have_right) {
- right->set_lower_right(old->lower_right);
- right->set_upper_right(old->upper_right);
- below->set_lower_right(right);
- above->set_upper_right(right);
- }
- else {
- below->set_lower_right(old->lower_right);
- above->set_upper_right(old->upper_right);
- }
-
- // Connect to new trapezoids replacing prevOld.
- if (below != left_below) {
- below->set_upper_left(left_below);
- if (old->lower_left == left_old)
- below->set_lower_left(left_below);
- else
- below->set_lower_left(old->lower_left);
- }
-
- if (above != left_above) {
- above->set_lower_left(left_above);
- if (old->upper_left == left_old)
- above->set_upper_left(left_above);
- else
- above->set_upper_left(old->upper_left);
- }
- }
- else { // Middle trapezoid.
- // Old trapezoid is neither the first nor last of the 3+ trapezoids
- // that the edge intersects.
- if (left_below->below == old->below) {
- below = left_below;
- below->right = old->right;
- }
- else
- below = new Trapezoid(old->left, old->right, old->below, edge);
-
- if (left_above->above == old->above) {
- above = left_above;
- above->right = old->right;
- }
- else
- above = new Trapezoid(old->left, old->right, edge, old->above);
-
- // Connect to new trapezoids replacing prevOld.
- if (below != left_below) { // below is new.
- below->set_upper_left(left_below);
- if (old->lower_left == left_old)
- below->set_lower_left(left_below);
- else
- below->set_lower_left(old->lower_left);
- }
-
- if (above != left_above) { // above is new.
- above->set_lower_left(left_above);
- if (old->upper_left == left_old)
- above->set_upper_left(left_above);
- else
- above->set_upper_left(old->upper_left);
- }
-
- below->set_lower_right(old->lower_right);
- above->set_upper_right(old->upper_right);
- }
-
- // Create new nodes to add to search tree. Below and above trapezoids
- // may already have owning trapezoid nodes, in which case reuse them.
- Node* new_top_node = new Node(
- &edge,
- below == left_below ? below->trapezoid_node : new Node(below),
- above == left_above ? above->trapezoid_node : new Node(above));
- if (have_right)
- new_top_node = new Node(q, new_top_node, new Node(right));
- if (have_left)
- new_top_node = new Node(p, new Node(left), new_top_node);
-
- // Insert new_top_node in correct position or positions in search tree.
- Node* old_node = old->trapezoid_node;
- if (old_node == _tree)
- _tree = new_top_node;
- else
- old_node->replace_with(new_top_node);
-
- // old_node has been removed from all of its parents and is no longer
- // needed.
- assert(old_node->has_no_parents() && "Node should have no parents");
- delete old_node;
-
- // Clearing up.
- if (!end_trap) {
- // Prepare for next loop.
- left_old = old;
- left_above = above;
- left_below = below;
- }
- }
-
- return true;
-}
-
-void
-TrapezoidMapTriFinder::clear()
-{
- delete [] _points;
- _points = 0;
-
- _edges.clear();
-
- delete _tree;
- _tree = 0;
-}
-
-TrapezoidMapTriFinder::TriIndexArray
-TrapezoidMapTriFinder::find_many(const CoordinateArray& x,
- const CoordinateArray& y)
-{
- // Create integer array to return.
- npy_intp n = x.dim(0);
- npy_intp dims[1] = {n};
- TriIndexArray tri_indices(dims);
-
- // Fill returned array.
- for (npy_intp i = 0; i < n; ++i)
- tri_indices(i) = find_one(XY(x(i), y(i)));
-
- return tri_indices;
-}
-
-int
-TrapezoidMapTriFinder::find_one(const XY& xy)
-{
- const Node* node = _tree->search(xy);
- assert(node != 0 && "Search tree for point returned null node");
- return node->get_tri();
-}
-
-bool
-TrapezoidMapTriFinder::find_trapezoids_intersecting_edge(
- const Edge& edge,
- std::vector<Trapezoid*>& trapezoids)
-{
- // This is the FollowSegment algorithm of de Berg et al, with some extra
- // checks to deal with simple colinear (i.e. invalid) triangles.
- trapezoids.clear();
- Trapezoid* trapezoid = _tree->search(edge);
- if (trapezoid == 0) {
- assert(trapezoid != 0 && "search(edge) returns null trapezoid");
- return false;
- }
-
- trapezoids.push_back(trapezoid);
- while (edge.right->is_right_of(*trapezoid->right)) {
- int orient = edge.get_point_orientation(*trapezoid->right);
- if (orient == 0) {
- if (edge.point_below == trapezoid->right)
- orient = +1;
- else if (edge.point_above == trapezoid->right)
- orient = -1;
- else {
- assert(0 && "Unable to deal with point on edge");
- return false;
- }
- }
-
- if (orient == -1)
- trapezoid = trapezoid->lower_right;
- else if (orient == +1)
- trapezoid = trapezoid->upper_right;
-
- if (trapezoid == 0) {
- assert(0 && "Expected trapezoid neighbor");
- return false;
- }
- trapezoids.push_back(trapezoid);
- }
-
- return true;
-}
-
-PyObject*
-TrapezoidMapTriFinder::get_tree_stats()
-{
- NodeStats stats;
- _tree->get_stats(0, stats);
-
- return Py_BuildValue("[l,l,l,l,l,l,d]",
- stats.node_count,
- stats.unique_nodes.size(),
- stats.trapezoid_count,
- stats.unique_trapezoid_nodes.size(),
- stats.max_parent_count,
- stats.max_depth,
- stats.sum_trapezoid_depth / stats.trapezoid_count);
-}
-
-void
-TrapezoidMapTriFinder::initialize()
-{
- clear();
- const Triangulation& triang = _triangulation;
-
- // Set up points array, which contains all of the points in the
- // triangulation plus the 4 corners of the enclosing rectangle.
- int npoints = triang.get_npoints();
- _points = new Point[npoints + 4];
- BoundingBox bbox;
- for (int i = 0; i < npoints; ++i) {
- XY xy = triang.get_point_coords(i);
- // Avoid problems with -0.0 values different from 0.0
- if (xy.x == -0.0)
- xy.x = 0.0;
- if (xy.y == -0.0)
- xy.y = 0.0;
- _points[i] = Point(xy);
- bbox.add(xy);
- }
-
- // Last 4 points are corner points of enclosing rectangle. Enclosing
- // rectangle made slightly larger in case corner points are already in the
- // triangulation.
- if (bbox.empty) {
- bbox.add(XY(0.0, 0.0));
- bbox.add(XY(1.0, 1.0));
- }
- else {
- const double small = 0.1; // Any value > 0.0
- bbox.expand( (bbox.upper - bbox.lower)*small );
- }
- _points[npoints ] = Point(bbox.lower); // SW point.
- _points[npoints+1] = Point(bbox.upper.x, bbox.lower.y); // SE point.
- _points[npoints+2] = Point(bbox.lower.x, bbox.upper.y); // NW point.
- _points[npoints+3] = Point(bbox.upper); // NE point.
-
- // Set up edges array.
- // First the bottom and top edges of the enclosing rectangle.
- _edges.push_back(Edge(&_points[npoints], &_points[npoints+1],-1,-1,0,0));
- _edges.push_back(Edge(&_points[npoints+2],&_points[npoints+3],-1,-1,0,0));
-
- // Add all edges in the triangulation that point to the right. Do not
- // explicitly include edges that point to the left as the neighboring
- // triangle will supply that, unless there is no such neighbor.
- int ntri = triang.get_ntri();
- for (int tri = 0; tri < ntri; ++tri) {
- if (!triang.is_masked(tri)) {
- for (int edge = 0; edge < 3; ++edge) {
- Point* start = _points + triang.get_triangle_point(tri,edge);
- Point* end = _points +
- triang.get_triangle_point(tri,(edge+1)%3);
- Point* other = _points +
- triang.get_triangle_point(tri,(edge+2)%3);
- TriEdge neighbor = triang.get_neighbor_edge(tri,edge);
- if (end->is_right_of(*start)) {
- const Point* neighbor_point_below = (neighbor.tri == -1) ?
- 0 : _points + triang.get_triangle_point(
- neighbor.tri, (neighbor.edge+2)%3);
- _edges.push_back(Edge(start, end, neighbor.tri, tri,
- neighbor_point_below, other));
- }
- else if (neighbor.tri == -1)
- _edges.push_back(Edge(end, start, tri, -1, other, 0));
-
- // Set triangle associated with start point if not already set.
- if (start->tri == -1)
- start->tri = tri;
- }
- }
- }
-
- // Initial trapezoid is enclosing rectangle.
- _tree = new Node(new Trapezoid(&_points[npoints], &_points[npoints+1],
- _edges[0], _edges[1]));
- _tree->assert_valid(false);
-
- // Randomly shuffle all edges other than first 2.
- RandomNumberGenerator rng(1234);
- std::random_shuffle(_edges.begin()+2, _edges.end(), rng);
-
- // Add edges, one at a time, to tree.
- unsigned int nedges = _edges.size();
- for (unsigned int index = 2; index < nedges; ++index) {
- if (!add_edge_to_tree(_edges[index]))
- throw std::runtime_error("Triangulation is invalid");
- _tree->assert_valid(index == nedges-1);
- }
-}
-
-void
-TrapezoidMapTriFinder::print_tree()
-{
- assert(_tree != 0 && "Null Node tree");
- _tree->print();
-}
-
-TrapezoidMapTriFinder::Edge::Edge(const Point* left_,
- const Point* right_,
- int triangle_below_,
- int triangle_above_,
- const Point* point_below_,
- const Point* point_above_)
- : left(left_),
- right(right_),
- triangle_below(triangle_below_),
- triangle_above(triangle_above_),
- point_below(point_below_),
- point_above(point_above_)
-{
- assert(left != 0 && "Null left point");
- assert(right != 0 && "Null right point");
- assert(right->is_right_of(*left) && "Incorrect point order");
- assert(triangle_below >= -1 && "Invalid triangle below index");
- assert(triangle_above >= -1 && "Invalid triangle above index");
-}
-
-int
-TrapezoidMapTriFinder::Edge::get_point_orientation(const XY& xy) const
-{
- double cross_z = (xy - *left).cross_z(*right - *left);
- return (cross_z > 0.0) ? +1 : ((cross_z < 0.0) ? -1 : 0);
-}
-
-double
-TrapezoidMapTriFinder::Edge::get_slope() const
-{
- // Divide by zero is acceptable here.
- XY diff = *right - *left;
- return diff.y / diff.x;
-}
-
-double
-TrapezoidMapTriFinder::Edge::get_y_at_x(const double& x) const
-{
- if (left->x == right->x) {
- // If edge is vertical, return lowest y from left point.
- assert(x == left->x && "x outside of edge");
- return left->y;
- }
- else {
- // Equation of line: left + lambda*(right - left) = xy.
- // i.e. left.x + lambda(right.x - left.x) = x and similar for y.
- double lambda = (x - left->x) / (right->x - left->x);
- assert(lambda >= 0 && lambda <= 1.0 && "Lambda out of bounds");
- return left->y + lambda*(right->y - left->y);
- }
-}
-
-bool
-TrapezoidMapTriFinder::Edge::has_point(const Point* point) const
-{
- assert(point != 0 && "Null point");
- return (left == point || right == point);
-}
-
-bool
-TrapezoidMapTriFinder::Edge::operator==(const Edge& other) const
-{
- return this == &other;
-}
-
-void
-TrapezoidMapTriFinder::Edge::print_debug() const
-{
- std::cout << "Edge " << *this << " tri_below=" << triangle_below
- << " tri_above=" << triangle_above << std::endl;
-}
-
-TrapezoidMapTriFinder::Node::Node(const Point* point, Node* left, Node* right)
- : _type(Type_XNode)
-{
- assert(point != 0 && "Invalid point");
- assert(left != 0 && "Invalid left node");
- assert(right != 0 && "Invalid right node");
- _union.xnode.point = point;
- _union.xnode.left = left;
- _union.xnode.right = right;
- left->add_parent(this);
- right->add_parent(this);
-}
-
-TrapezoidMapTriFinder::Node::Node(const Edge* edge, Node* below, Node* above)
- : _type(Type_YNode)
-{
- assert(edge != 0 && "Invalid edge");
- assert(below != 0 && "Invalid below node");
- assert(above != 0 && "Invalid above node");
- _union.ynode.edge = edge;
- _union.ynode.below = below;
- _union.ynode.above = above;
- below->add_parent(this);
- above->add_parent(this);
-}
-
-TrapezoidMapTriFinder::Node::Node(Trapezoid* trapezoid)
- : _type(Type_TrapezoidNode)
-{
- assert(trapezoid != 0 && "Null Trapezoid");
- _union.trapezoid = trapezoid;
- trapezoid->trapezoid_node = this;
-}
-
-TrapezoidMapTriFinder::Node::~Node()
-{
- switch (_type) {
- case Type_XNode:
- if (_union.xnode.left->remove_parent(this))
- delete _union.xnode.left;
- if (_union.xnode.right->remove_parent(this))
- delete _union.xnode.right;
- break;
- case Type_YNode:
- if (_union.ynode.below->remove_parent(this))
- delete _union.ynode.below;
- if (_union.ynode.above->remove_parent(this))
- delete _union.ynode.above;
- break;
- case Type_TrapezoidNode:
- delete _union.trapezoid;
- break;
- }
-}
-
-void
-TrapezoidMapTriFinder::Node::add_parent(Node* parent)
-{
- assert(parent != 0 && "Null parent");
- assert(parent != this && "Cannot be parent of self");
- assert(!has_parent(parent) && "Parent already in collection");
- _parents.push_back(parent);
-}
-
-void
-TrapezoidMapTriFinder::Node::assert_valid(bool tree_complete) const
-{
-#ifndef NDEBUG
- // Check parents.
- for (Parents::const_iterator it = _parents.begin();
- it != _parents.end(); ++it) {
- Node* parent = *it;
- assert(parent != this && "Cannot be parent of self");
- assert(parent->has_child(this) && "Parent missing child");
- }
-
- // Check children, and recurse.
- switch (_type) {
- case Type_XNode:
- assert(_union.xnode.left != 0 && "Null left child");
- assert(_union.xnode.left->has_parent(this) && "Incorrect parent");
- assert(_union.xnode.right != 0 && "Null right child");
- assert(_union.xnode.right->has_parent(this) && "Incorrect parent");
- _union.xnode.left->assert_valid(tree_complete);
- _union.xnode.right->assert_valid(tree_complete);
- break;
- case Type_YNode:
- assert(_union.ynode.below != 0 && "Null below child");
- assert(_union.ynode.below->has_parent(this) && "Incorrect parent");
- assert(_union.ynode.above != 0 && "Null above child");
- assert(_union.ynode.above->has_parent(this) && "Incorrect parent");
- _union.ynode.below->assert_valid(tree_complete);
- _union.ynode.above->assert_valid(tree_complete);
- break;
- case Type_TrapezoidNode:
- assert(_union.trapezoid != 0 && "Null trapezoid");
- assert(_union.trapezoid->trapezoid_node == this &&
- "Incorrect trapezoid node");
- _union.trapezoid->assert_valid(tree_complete);
- break;
- }
-#endif
-}
-
-void
-TrapezoidMapTriFinder::Node::get_stats(int depth,
- NodeStats& stats) const
-{
- stats.node_count++;
- if (depth > stats.max_depth)
- stats.max_depth = depth;
- bool new_node = stats.unique_nodes.insert(this).second;
- if (new_node)
- stats.max_parent_count = std::max(stats.max_parent_count,
- static_cast<long>(_parents.size()));
-
- switch (_type) {
- case Type_XNode:
- _union.xnode.left->get_stats(depth+1, stats);
- _union.xnode.right->get_stats(depth+1, stats);
- break;
- case Type_YNode:
- _union.ynode.below->get_stats(depth+1, stats);
- _union.ynode.above->get_stats(depth+1, stats);
- break;
- default: // Type_TrapezoidNode:
- stats.unique_trapezoid_nodes.insert(this);
- stats.trapezoid_count++;
- stats.sum_trapezoid_depth += depth;
- break;
- }
-}
-
-int
-TrapezoidMapTriFinder::Node::get_tri() const
-{
- switch (_type) {
- case Type_XNode:
- return _union.xnode.point->tri;
- case Type_YNode:
- if (_union.ynode.edge->triangle_above != -1)
- return _union.ynode.edge->triangle_above;
- else
- return _union.ynode.edge->triangle_below;
- default: // Type_TrapezoidNode:
- assert(_union.trapezoid->below.triangle_above ==
- _union.trapezoid->above.triangle_below &&
- "Inconsistent triangle indices from trapezoid edges");
- return _union.trapezoid->below.triangle_above;
- }
-}
-
-bool
-TrapezoidMapTriFinder::Node::has_child(const Node* child) const
-{
- assert(child != 0 && "Null child node");
- switch (_type) {
- case Type_XNode:
- return (_union.xnode.left == child || _union.xnode.right == child);
- case Type_YNode:
- return (_union.ynode.below == child ||
- _union.ynode.above == child);
- default: // Type_TrapezoidNode:
- return false;
- }
-}
-
-bool
-TrapezoidMapTriFinder::Node::has_no_parents() const
-{
- return _parents.empty();
-}
-
-bool
-TrapezoidMapTriFinder::Node::has_parent(const Node* parent) const
-{
- return (std::find(_parents.begin(), _parents.end(), parent) !=
- _parents.end());
-}
-
-void
-TrapezoidMapTriFinder::Node::print(int depth /* = 0 */) const
-{
- for (int i = 0; i < depth; ++i) std::cout << " ";
- switch (_type) {
- case Type_XNode:
- std::cout << "XNode " << *_union.xnode.point << std::endl;
- _union.xnode.left->print(depth + 1);
- _union.xnode.right->print(depth + 1);
- break;
- case Type_YNode:
- std::cout << "YNode " << *_union.ynode.edge << std::endl;
- _union.ynode.below->print(depth + 1);
- _union.ynode.above->print(depth + 1);
- break;
- case Type_TrapezoidNode:
- std::cout << "Trapezoid ll="
- << _union.trapezoid->get_lower_left_point() << " lr="
- << _union.trapezoid->get_lower_right_point() << " ul="
- << _union.trapezoid->get_upper_left_point() << " ur="
- << _union.trapezoid->get_upper_right_point() << std::endl;
- break;
- }
-}
-
-bool
-TrapezoidMapTriFinder::Node::remove_parent(Node* parent)
-{
- assert(parent != 0 && "Null parent");
- assert(parent != this && "Cannot be parent of self");
- Parents::iterator it = std::find(_parents.begin(), _parents.end(), parent);
- assert(it != _parents.end() && "Parent not in collection");
- _parents.erase(it);
- return _parents.empty();
-}
-
-void
-TrapezoidMapTriFinder::Node::replace_child(Node* old_child, Node* new_child)
-{
- switch (_type) {
- case Type_XNode:
- assert((_union.xnode.left == old_child ||
- _union.xnode.right == old_child) && "Not a child Node");
- assert(new_child != 0 && "Null child node");
- if (_union.xnode.left == old_child)
- _union.xnode.left = new_child;
- else
- _union.xnode.right = new_child;
- break;
- case Type_YNode:
- assert((_union.ynode.below == old_child ||
- _union.ynode.above == old_child) && "Not a child node");
- assert(new_child != 0 && "Null child node");
- if (_union.ynode.below == old_child)
- _union.ynode.below = new_child;
- else
- _union.ynode.above = new_child;
- break;
- case Type_TrapezoidNode:
- assert(0 && "Invalid type for this operation");
- break;
- }
- old_child->remove_parent(this);
- new_child->add_parent(this);
-}
-
-void
-TrapezoidMapTriFinder::Node::replace_with(Node* new_node)
-{
- assert(new_node != 0 && "Null replacement node");
- // Replace child of each parent with new_node. As each has parent has its
- // child replaced it is removed from the _parents collection.
- while (!_parents.empty())
- _parents.front()->replace_child(this, new_node);
-}
-
-const TrapezoidMapTriFinder::Node*
-TrapezoidMapTriFinder::Node::search(const XY& xy)
-{
- switch (_type) {
- case Type_XNode:
- if (xy == *_union.xnode.point)
- return this;
- else if (xy.is_right_of(*_union.xnode.point))
- return _union.xnode.right->search(xy);
- else
- return _union.xnode.left->search(xy);
- case Type_YNode: {
- int orient = _union.ynode.edge->get_point_orientation(xy);
- if (orient == 0)
- return this;
- else if (orient < 0)
- return _union.ynode.above->search(xy);
- else
- return _union.ynode.below->search(xy);
- }
- default: // Type_TrapezoidNode:
- return this;
- }
-}
-
-TrapezoidMapTriFinder::Trapezoid*
-TrapezoidMapTriFinder::Node::search(const Edge& edge)
-{
- switch (_type) {
- case Type_XNode:
- if (edge.left == _union.xnode.point)
- return _union.xnode.right->search(edge);
- else {
- if (edge.left->is_right_of(*_union.xnode.point))
- return _union.xnode.right->search(edge);
- else
- return _union.xnode.left->search(edge);
- }
- case Type_YNode:
- if (edge.left == _union.ynode.edge->left) {
- // Coinciding left edge points.
- if (edge.get_slope() == _union.ynode.edge->get_slope()) {
- if (_union.ynode.edge->triangle_above ==
- edge.triangle_below)
- return _union.ynode.above->search(edge);
- else if (_union.ynode.edge->triangle_below ==
- edge.triangle_above)
- return _union.ynode.below->search(edge);
- else {
- assert(0 &&
- "Invalid triangulation, common left points");
- return 0;
- }
- }
- if (edge.get_slope() > _union.ynode.edge->get_slope())
- return _union.ynode.above->search(edge);
- else
- return _union.ynode.below->search(edge);
- }
- else if (edge.right == _union.ynode.edge->right) {
- // Coinciding right edge points.
- if (edge.get_slope() == _union.ynode.edge->get_slope()) {
- if (_union.ynode.edge->triangle_above ==
- edge.triangle_below)
- return _union.ynode.above->search(edge);
- else if (_union.ynode.edge->triangle_below ==
- edge.triangle_above)
- return _union.ynode.below->search(edge);
- else {
- assert(0 &&
- "Invalid triangulation, common right points");
- return 0;
- }
- }
- if (edge.get_slope() > _union.ynode.edge->get_slope())
- return _union.ynode.below->search(edge);
- else
- return _union.ynode.above->search(edge);
- }
- else {
- int orient =
- _union.ynode.edge->get_point_orientation(*edge.left);
- if (orient == 0) {
- // edge.left lies on _union.ynode.edge
- if (_union.ynode.edge->point_above != 0 &&
- edge.has_point(_union.ynode.edge->point_above))
- orient = -1;
- else if (_union.ynode.edge->point_below != 0 &&
- edge.has_point(_union.ynode.edge->point_below))
- orient = +1;
- else {
- assert(0 && "Invalid triangulation, point on edge");
- return 0;
- }
- }
- if (orient < 0)
- return _union.ynode.above->search(edge);
- else
- return _union.ynode.below->search(edge);
- }
- default: // Type_TrapezoidNode:
- return _union.trapezoid;
- }
-}
-
-TrapezoidMapTriFinder::Trapezoid::Trapezoid(const Point* left_,
- const Point* right_,
- const Edge& below_,
- const Edge& above_)
- : left(left_), right(right_), below(below_), above(above_),
- lower_left(0), lower_right(0), upper_left(0), upper_right(0),
- trapezoid_node(0)
-{
- assert(left != 0 && "Null left point");
- assert(right != 0 && "Null right point");
- assert(right->is_right_of(*left) && "Incorrect point order");
-}
-
-void
-TrapezoidMapTriFinder::Trapezoid::assert_valid(bool tree_complete) const
-{
-#ifndef NDEBUG
- assert(left != 0 && "Null left point");
- assert(right != 0 && "Null right point");
-
- if (lower_left != 0) {
- assert(lower_left->below == below &&
- lower_left->lower_right == this &&
- "Incorrect lower_left trapezoid");
- assert(get_lower_left_point() == lower_left->get_lower_right_point() &&
- "Incorrect lower left point");
- }
-
- if (lower_right != 0) {
- assert(lower_right->below == below &&
- lower_right->lower_left == this &&
- "Incorrect lower_right trapezoid");
- assert(get_lower_right_point() == lower_right->get_lower_left_point() &&
- "Incorrect lower right point");
- }
-
- if (upper_left != 0) {
- assert(upper_left->above == above &&
- upper_left->upper_right == this &&
- "Incorrect upper_left trapezoid");
- assert(get_upper_left_point() == upper_left->get_upper_right_point() &&
- "Incorrect upper left point");
- }
-
- if (upper_right != 0) {
- assert(upper_right->above == above &&
- upper_right->upper_left == this &&
- "Incorrect upper_right trapezoid");
- assert(get_upper_right_point() == upper_right->get_upper_left_point() &&
- "Incorrect upper right point");
- }
-
- assert(trapezoid_node != 0 && "Null trapezoid_node");
-
- if (tree_complete) {
- assert(below.triangle_above == above.triangle_below &&
- "Inconsistent triangle indices from trapezoid edges");
- }
-#endif
-}
-
-XY
-TrapezoidMapTriFinder::Trapezoid::get_lower_left_point() const
-{
- double x = left->x;
- return XY(x, below.get_y_at_x(x));
-}
-
-XY
-TrapezoidMapTriFinder::Trapezoid::get_lower_right_point() const
-{
- double x = right->x;
- return XY(x, below.get_y_at_x(x));
-}
-
-XY
-TrapezoidMapTriFinder::Trapezoid::get_upper_left_point() const
-{
- double x = left->x;
- return XY(x, above.get_y_at_x(x));
-}
-
-XY
-TrapezoidMapTriFinder::Trapezoid::get_upper_right_point() const
-{
- double x = right->x;
- return XY(x, above.get_y_at_x(x));
-}
-
-void
-TrapezoidMapTriFinder::Trapezoid::print_debug() const
-{
- std::cout << "Trapezoid " << this
- << " left=" << *left
- << " right=" << *right
- << " below=" << below
- << " above=" << above
- << " ll=" << lower_left
- << " lr=" << lower_right
- << " ul=" << upper_left
- << " ur=" << upper_right
- << " node=" << trapezoid_node
- << " llp=" << get_lower_left_point()
- << " lrp=" << get_lower_right_point()
- << " ulp=" << get_upper_left_point()
- << " urp=" << get_upper_right_point() << std::endl;
-}
-
-void
-TrapezoidMapTriFinder::Trapezoid::set_lower_left(Trapezoid* lower_left_)
-{
- lower_left = lower_left_;
- if (lower_left != 0)
- lower_left->lower_right = this;
-}
-
-void
-TrapezoidMapTriFinder::Trapezoid::set_lower_right(Trapezoid* lower_right_)
-{
- lower_right = lower_right_;
- if (lower_right != 0)
- lower_right->lower_left = this;
-}
-
-void
-TrapezoidMapTriFinder::Trapezoid::set_upper_left(Trapezoid* upper_left_)
-{
- upper_left = upper_left_;
- if (upper_left != 0)
- upper_left->upper_right = this;
-}
-
-void
-TrapezoidMapTriFinder::Trapezoid::set_upper_right(Trapezoid* upper_right_)
-{
- upper_right = upper_right_;
- if (upper_right != 0)
- upper_right->upper_left = this;
-}
-
-
-
-RandomNumberGenerator::RandomNumberGenerator(unsigned long seed)
- : _m(21870), _a(1291), _c(4621), _seed(seed % _m)
-{}
-
-unsigned long
-RandomNumberGenerator::operator()(unsigned long max_value)
-{
- _seed = (_seed*_a + _c) % _m;
- return (_seed*max_value) / _m;
-}
diff --git a/contrib/python/matplotlib/py2/matplotlib/tri/_tri.h b/contrib/python/matplotlib/py2/matplotlib/tri/_tri.h
deleted file mode 100644
index fc24af50f0..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/tri/_tri.h
+++ /dev/null
@@ -1,815 +0,0 @@
-/*
- * Unstructured triangular grid functions, particularly contouring.
- *
- * There are two main classes: Triangulation and TriContourGenerator.
- *
- * Triangulation
- * -------------
- * Triangulation is an unstructured triangular grid with npoints and ntri
- * triangles. It consists of point x and y coordinates, and information about
- * the triangulation stored in an integer array of shape (ntri,3) called
- * triangles. Each triangle is represented by three point indices (in the
- * range 0 to npoints-1) that comprise the triangle, ordered anticlockwise.
- * There is an optional mask of length ntri which can be used to mask out
- * triangles and has the same result as removing those triangles from the
- * 'triangles' array.
- *
- * A particular edge of a triangulation is termed a TriEdge, which is a
- * triangle index and an edge index in the range 0 to 2. TriEdge(tri,edge)
- * refers to the edge that starts at point index triangles(tri,edge) and ends
- * at point index triangles(tri,(edge+1)%3).
- *
- * Various derived fields are calculated when they are first needed. The
- * triangle connectivity is stored in a neighbors array of shape (ntri,3) such
- * that neighbors(tri,edge) is the index of the triangle that adjoins the
- * TriEdge(tri,edge), or -1 if there is no such neighbor.
- *
- * A triangulation has one or more boundaries, each of which is a 1D array of
- * the TriEdges that comprise the boundary, in order following the boundary
- * with non-masked triangles on the left.
- *
- * TriContourGenerator
- * -------------------
- * A TriContourGenerator generates contours for a particular Triangulation.
- * The process followed is different for non-filled and filled contours, with
- * one and two contour levels respectively. In both cases boundary contour
- * lines are found first, then interior lines.
- *
- * Boundary lines start and end on a boundary. They are found by traversing
- * the triangulation boundary edges until a suitable start point is found, and
- * then the contour line is followed across the interior of the triangulation
- * until it ends on another boundary edge. For a non-filled contour this
- * completes a line, whereas a filled contour continues by following the
- * boundary around until either another boundary start point is found or the
- * start of the contour line is reached. Filled contour generation stores
- * boolean flags to indicate which boundary edges have already been traversed
- * so that they are not dealt with twice. Similar flags are used to indicate
- * which triangles have been used when following interior lines.
- *
- * Interior lines do not intersect any boundaries. They are found by
- * traversing all triangles that have not yet been visited until a suitable
- * starting point is found, and then the contour line is followed across the
- * interior of the triangulation until it returns to the start point. For
- * filled contours this process is repeated for both lower and upper contour
- * levels, and the direction of traversal is reversed for upper contours.
- *
- * Working out in which direction a contour line leaves a triangle uses the
- * a lookup table. A triangle has three points, each of which has a z-value
- * which is either less than the contour level or not. Hence there are 8
- * configurations to deal with, 2 of which do not have a contour line (all
- * points below or above (including the same as) the contour level) and 6 that
- * do. See the function get_exit_edge for details.
- */
-#ifndef _TRI_H
-#define _TRI_H
-
-#include "src/numpy_cpp.h"
-
-#include <iostream>
-#include <list>
-#include <map>
-#include <set>
-#include <vector>
-
-
-
-/* An edge of a triangle consisting of an triangle index in the range 0 to
- * ntri-1 and an edge index in the range 0 to 2. Edge i goes from the
- * triangle's point i to point (i+1)%3. */
-struct TriEdge
-{
- TriEdge();
- TriEdge(int tri_, int edge_);
- bool operator<(const TriEdge& other) const;
- bool operator==(const TriEdge& other) const;
- bool operator!=(const TriEdge& other) const;
- friend std::ostream& operator<<(std::ostream& os, const TriEdge& tri_edge);
-
- int tri, edge;
-};
-
-// 2D point with x,y coordinates.
-struct XY
-{
- XY();
- XY(const double& x_, const double& y_);
- double angle() const; // Angle in radians with respect to x-axis.
- double cross_z(const XY& other) const; // z-component of cross product.
- bool is_right_of(const XY& other) const; // Compares x then y.
- bool operator==(const XY& other) const;
- bool operator!=(const XY& other) const;
- XY operator*(const double& multiplier) const;
- const XY& operator+=(const XY& other);
- const XY& operator-=(const XY& other);
- XY operator+(const XY& other) const;
- XY operator-(const XY& other) const;
- friend std::ostream& operator<<(std::ostream& os, const XY& xy);
-
- double x, y;
-};
-
-// 3D point with x,y,z coordinates.
-struct XYZ
-{
- XYZ(const double& x_, const double& y_, const double& z_);
- XYZ cross(const XYZ& other) const;
- double dot(const XYZ& other) const;
- double length_squared() const;
- XYZ operator-(const XYZ& other) const;
- friend std::ostream& operator<<(std::ostream& os, const XYZ& xyz);
-
- double x, y, z;
-};
-
-// 2D bounding box, which may be empty.
-class BoundingBox
-{
-public:
- BoundingBox();
- void add(const XY& point);
- void expand(const XY& delta);
-
- // Consider these member variables read-only.
- bool empty;
- XY lower, upper;
-};
-
-/* A single line of a contour, which may be a closed line loop or an open line
- * strip. Identical adjacent points are avoided using insert_unique() and
- * push_back(), and a closed line loop should also not have identical first and
- * last points. */
-class ContourLine : public std::vector<XY>
-{
-public:
- ContourLine();
- void insert_unique(iterator pos, const XY& point);
- void push_back(const XY& point);
- void write() const;
-};
-
-// A Contour is a collection of zero or more ContourLines.
-typedef std::vector<ContourLine> Contour;
-
-// Debug contour writing function.
-void write_contour(const Contour& contour);
-
-
-
-
-/* Triangulation with npoints points and ntri triangles. Derived fields are
- * calculated when they are first needed. */
-class Triangulation
-{
-public:
- typedef numpy::array_view<const double, 1> CoordinateArray;
- typedef numpy::array_view<double, 2> TwoCoordinateArray;
- typedef numpy::array_view<int, 2> TriangleArray;
- typedef numpy::array_view<const bool, 1> MaskArray;
- typedef numpy::array_view<int, 2> EdgeArray;
- typedef numpy::array_view<int, 2> NeighborArray;
-
- /* A single boundary is a vector of the TriEdges that make up that boundary
- * following it around with unmasked triangles on the left. */
- typedef std::vector<TriEdge> Boundary;
- typedef std::vector<Boundary> Boundaries;
-
- /* Constructor with optional mask, edges and neighbors. The latter two
- * are calculated when first needed.
- * x: double array of shape (npoints) of points' x-coordinates.
- * y: double array of shape (npoints) of points' y-coordinates.
- * triangles: int array of shape (ntri,3) of triangle point indices.
- * Those ordered clockwise are changed to be anticlockwise.
- * mask: Optional bool array of shape (ntri) indicating which triangles
- * are masked.
- * edges: Optional int array of shape (?,2) of start and end point
- * indices, each edge (start,end and end,start) appearing only
- * once.
- * neighbors: Optional int array of shape (ntri,3) indicating which
- * triangles are the neighbors of which TriEdges, or -1 if
- * there is no such neighbor.
- * correct_triangle_orientations: Whether or not should correct triangle
- * orientations so that vertices are
- * ordered anticlockwise. */
- Triangulation(const CoordinateArray& x,
- const CoordinateArray& y,
- const TriangleArray& triangles,
- const MaskArray& mask,
- const EdgeArray& edges,
- const NeighborArray& neighbors,
- int correct_triangle_orientations);
-
- /* Calculate plane equation coefficients for all unmasked triangles from
- * the point (x,y) coordinates and point z-array of shape (npoints) passed
- * in via the args. Returned array has shape (npoints,3) and allows
- * z-value at (x,y) coordinates in triangle tri to be calculated using
- * z = array[tri,0]*x + array[tri,1]*y + array[tri,2]. */
- TwoCoordinateArray calculate_plane_coefficients(const CoordinateArray& z);
-
- // Return the boundaries collection, creating it if necessary.
- const Boundaries& get_boundaries() const;
-
- // Return which boundary and boundary edge the specified TriEdge is.
- void get_boundary_edge(const TriEdge& triEdge,
- int& boundary,
- int& edge) const;
-
- /* Return the edges array, creating it if necessary. */
- EdgeArray& get_edges();
-
- /* Return the triangle index of the neighbor of the specified triangle
- * edge. */
- int get_neighbor(int tri, int edge) const;
-
- /* Return the TriEdge that is the neighbor of the specified triangle edge,
- * or TriEdge(-1,-1) if there is no such neighbor. */
- TriEdge get_neighbor_edge(int tri, int edge) const;
-
- /* Return the neighbors array, creating it if necessary. */
- NeighborArray& get_neighbors();
-
- // Return the number of points in this triangulation.
- int get_npoints() const;
-
- // Return the number of triangles in this triangulation.
- int get_ntri() const;
-
- /* Return the index of the point that is at the start of the specified
- * triangle edge. */
- int get_triangle_point(int tri, int edge) const;
- int get_triangle_point(const TriEdge& tri_edge) const;
-
- // Return the coordinates of the specified point index.
- XY get_point_coords(int point) const;
-
- // Indicates if the specified triangle is masked or not.
- bool is_masked(int tri) const;
-
- /* Set or clear the mask array. Clears various derived fields so they are
- * recalculated when next needed.
- * mask: bool array of shape (ntri) indicating which triangles are
- * masked, or an empty array to clear mask. */
- void set_mask(const MaskArray& mask);
-
- // Debug function to write boundaries.
- void write_boundaries() const;
-
-private:
- // An edge of a triangulation, composed of start and end point indices.
- struct Edge
- {
- Edge() : start(-1), end(-1) {}
- Edge(int start_, int end_) : start(start_), end(end_) {}
- bool operator<(const Edge& other) const {
- return start != other.start ? start < other.start : end < other.end;
- }
- int start, end;
- };
-
- /* An edge of a boundary of a triangulation, composed of a boundary index
- * and an edge index within that boundary. Used to index into the
- * boundaries collection to obtain the corresponding TriEdge. */
- struct BoundaryEdge
- {
- BoundaryEdge() : boundary(-1), edge(-1) {}
- BoundaryEdge(int boundary_, int edge_)
- : boundary(boundary_), edge(edge_) {}
- int boundary, edge;
- };
-
- /* Calculate the boundaries collection. Should normally be accessed via
- * get_boundaries(), which will call this function if necessary. */
- void calculate_boundaries();
-
- /* Calculate the edges array. Should normally be accessed via
- * get_edges(), which will call this function if necessary. */
- void calculate_edges();
-
- /* Calculate the neighbors array. Should normally be accessed via
- * get_neighbors(), which will call this function if necessary. */
- void calculate_neighbors();
-
- /* Correct each triangle so that the vertices are ordered in an
- * anticlockwise manner. */
- void correct_triangles();
-
- /* Determine which edge index (0,1 or 2) the specified point index is in
- * the specified triangle, or -1 if the point is not in the triangle. */
- int get_edge_in_triangle(int tri, int point) const;
-
-
-
-
- // Variables shared with python, always set.
- CoordinateArray _x, _y; // double array (npoints).
- TriangleArray _triangles; // int array (ntri,3) of triangle point indices,
- // ordered anticlockwise.
-
- // Variables shared with python, may be zero.
- MaskArray _mask; // bool array (ntri).
-
- // Derived variables shared with python, may be zero. If zero, are
- // recalculated when needed.
- EdgeArray _edges; // int array (?,2) of start & end point indices.
- NeighborArray _neighbors; // int array (ntri,3), neighbor triangle indices
- // or -1 if no neighbor.
-
- // Variables internal to C++ only.
- Boundaries _boundaries;
-
- // Map used to look up BoundaryEdges from TriEdges. Normally accessed via
- // get_boundary_edge().
- typedef std::map<TriEdge, BoundaryEdge> TriEdgeToBoundaryMap;
- TriEdgeToBoundaryMap _tri_edge_to_boundary_map;
-};
-
-
-
-// Contour generator for a triangulation.
-class TriContourGenerator
-{
-public:
- typedef Triangulation::CoordinateArray CoordinateArray;
-
- /* Constructor.
- * triangulation: Triangulation to generate contours for.
- * z: Double array of shape (npoints) of z-values at triangulation
- * points. */
- TriContourGenerator(Triangulation& triangulation,
- const CoordinateArray& z);
-
- /* Create and return a non-filled contour.
- * level: Contour level.
- * Returns new python list [segs0, segs1, ...] where
- * segs0: double array of shape (?,2) of point coordinates of first
- * contour line, etc. */
- PyObject* create_contour(const double& level);
-
- /* Create and return a filled contour.
- * lower_level: Lower contour level.
- * upper_level: Upper contour level.
- * Returns new python tuple (segs, kinds) where
- * segs: double array of shape (n_points,2) of all point coordinates,
- * kinds: ubyte array of shape (n_points) of all point code types. */
- PyObject* create_filled_contour(const double& lower_level,
- const double& upper_level);
-
-private:
- typedef Triangulation::Boundary Boundary;
- typedef Triangulation::Boundaries Boundaries;
-
- /* Clear visited flags.
- * include_boundaries: Whether to clear boundary flags or not, which are
- * only used for filled contours. */
- void clear_visited_flags(bool include_boundaries);
-
- /* Convert a non-filled Contour from C++ to Python.
- * Returns new python list [segs0, segs1, ...] where
- * segs0: double array of shape (?,2) of point coordinates of first
- * contour line, etc. */
- PyObject* contour_to_segs(const Contour& contour);
-
- /* Convert a filled Contour from C++ to Python.
- * Returns new python tuple (segs, kinds) where
- * segs: double array of shape (n_points,2) of all point coordinates,
- * kinds: ubyte array of shape (n_points) of all point code types. */
- PyObject* contour_to_segs_and_kinds(const Contour& contour);
-
- /* Return the point on the specified TriEdge that intersects the specified
- * level. */
- XY edge_interp(int tri, int edge, const double& level);
-
- /* Find and follow non-filled contour lines that start and end on a
- * boundary of the Triangulation.
- * contour: Contour to add new lines to.
- * level: Contour level. */
- void find_boundary_lines(Contour& contour,
- const double& level);
-
- /* Find and follow filled contour lines at either of the specified contour
- * levels that start and end of a boundary of the Triangulation.
- * contour: Contour to add new lines to.
- * lower_level: Lower contour level.
- * upper_level: Upper contour level. */
- void find_boundary_lines_filled(Contour& contour,
- const double& lower_level,
- const double& upper_level);
-
- /* Find and follow lines at the specified contour level that are
- * completely in the interior of the Triangulation and hence do not
- * intersect any boundary.
- * contour: Contour to add new lines to.
- * level: Contour level.
- * on_upper: Whether on upper or lower contour level.
- * filled: Whether contours are filled or not. */
- void find_interior_lines(Contour& contour,
- const double& level,
- bool on_upper,
- bool filled);
-
- /* Follow contour line around boundary of the Triangulation from the
- * specified TriEdge to its end which can be on either the lower or upper
- * levels. Only used for filled contours.
- * contour_line: Contour line to append new points to.
- * tri_edge: On entry, TriEdge to start from. On exit, TriEdge that is
- * finished on.
- * lower_level: Lower contour level.
- * upper_level: Upper contour level.
- * on_upper: Whether starts on upper level or not.
- * Return true if finishes on upper level, false if lower. */
- bool follow_boundary(ContourLine& contour_line,
- TriEdge& tri_edge,
- const double& lower_level,
- const double& upper_level,
- bool on_upper);
-
- /* Follow contour line across interior of Triangulation.
- * contour_line: Contour line to append new points to.
- * tri_edge: On entry, TriEdge to start from. On exit, TriEdge that is
- * finished on.
- * end_on_boundary: Whether this line ends on a boundary, or loops back
- * upon itself.
- * level: Contour level to follow.
- * on_upper: Whether following upper or lower contour level. */
- void follow_interior(ContourLine& contour_line,
- TriEdge& tri_edge,
- bool end_on_boundary,
- const double& level,
- bool on_upper);
-
- // Return the Triangulation boundaries.
- const Boundaries& get_boundaries() const;
-
- /* Return the edge by which the a level leaves a particular triangle,
- * which is 0, 1 or 2 if the contour passes through the triangle or -1
- * otherwise.
- * tri: Triangle index.
- * level: Contour level to follow.
- * on_upper: Whether following upper or lower contour level. */
- int get_exit_edge(int tri, const double& level, bool on_upper) const;
-
- // Return the z-value at the specified point index.
- const double& get_z(int point) const;
-
- /* Return the point at which the a level intersects the line connecting the
- * two specified point indices. */
- XY interp(int point1, int point2, const double& level) const;
-
-
-
- // Variables shared with python, always set.
- Triangulation& _triangulation;
- CoordinateArray _z; // double array (npoints).
-
- // Variables internal to C++ only.
- typedef std::vector<bool> InteriorVisited; // Size 2*ntri
- typedef std::vector<bool> BoundaryVisited;
- typedef std::vector<BoundaryVisited> BoundariesVisited;
- typedef std::vector<bool> BoundariesUsed;
-
- InteriorVisited _interior_visited;
- BoundariesVisited _boundaries_visited; // Only used for filled contours.
- BoundariesUsed _boundaries_used; // Only used for filled contours.
-};
-
-
-
-/* TriFinder class implemented using the trapezoid map algorithm from the book
- * "Computational Geometry, Algorithms and Applications", second edition, by
- * M. de Berg, M. van Kreveld, M. Overmars and O. Schwarzkopf.
- *
- * The domain of interest is composed of vertical-sided trapezoids that are
- * bounded to the left and right by points of the triangulation, and below and
- * above by edges of the triangulation. Each triangle is represented by 1 or
- * more of these trapezoids. Edges are inserted one a time in a random order.
- *
- * As the trapezoid map is created, a search tree is also created which allows
- * fast lookup O(log N) of the trapezoid containing the point of interest.
- * There are 3 types of node in the search tree: all leaf nodes represent
- * trapezoids and all branch nodes have 2 child nodes and are either x-nodes or
- * y-nodes. X-nodes represent points in the triangulation, and their 2 children
- * refer to those parts of the search tree to the left and right of the point.
- * Y-nodes represent edges in the triangulation, and their 2 children refer to
- * those parts of the search tree below and above the edge.
- *
- * Nodes can be repeated throughout the search tree, and each is reference
- * counted through the multiple parent nodes it is a child of.
- *
- * The algorithm is only intended to work with valid triangulations, i.e. it
- * must not contain duplicate points, triangles formed from colinear points, or
- * overlapping triangles. It does have some tolerance to triangles formed from
- * colinear points but only in the simplest of cases. No explicit testing of
- * the validity of the triangulation is performed as this is a computationally
- * more complex task than the trifinding itself. */
-class TrapezoidMapTriFinder
-{
-public:
- typedef Triangulation::CoordinateArray CoordinateArray;
- typedef numpy::array_view<int, 1> TriIndexArray;
-
- /* Constructor. A separate call to initialize() is required to initialize
- * the object before use.
- * triangulation: Triangulation to find triangles in. */
- TrapezoidMapTriFinder(Triangulation& triangulation);
-
- ~TrapezoidMapTriFinder();
-
- /* Return an array of triangle indices. Takes 1D arrays x and y of
- * point coordinates, and returns an array of the same size containing the
- * indices of the triangles at those points. */
- TriIndexArray find_many(const CoordinateArray& x, const CoordinateArray& y);
-
- /* Return a reference to a new python list containing the following
- * statistics about the tree:
- * 0: number of nodes (tree size)
- * 1: number of unique nodes (number of unique Node objects in tree)
- * 2: number of trapezoids (tree leaf nodes)
- * 3: number of unique trapezoids
- * 4: maximum parent count (max number of times a node is repeated in
- * tree)
- * 5: maximum depth of tree (one more than the maximum number of
- * comparisons needed to search through the tree)
- * 6: mean of all trapezoid depths (one more than the average number of
- * comparisons needed to search through the tree) */
- PyObject* get_tree_stats();
-
- /* Initialize this object before use. May be called multiple times, if,
- * for example, the triangulation is changed by setting the mask. */
- void initialize();
-
- // Print the search tree as text to stdout; useful for debug purposes.
- void print_tree();
-
-private:
- /* A Point consists of x,y coordinates as well as the index of a triangle
- * associated with the point, so that a search at this point's coordinates
- * can return a valid triangle index. */
- struct Point : XY
- {
- Point() : XY(), tri(-1) {}
- Point(const double& x, const double& y) : XY(x,y), tri(-1) {}
- explicit Point(const XY& xy) : XY(xy), tri(-1) {}
-
- int tri;
- };
-
- /* An Edge connects two Points, left and right. It is always true that
- * right->is_right_of(*left). Stores indices of triangles below and above
- * the Edge which are used to map from trapezoid to triangle index. Also
- * stores pointers to the 3rd points of the below and above triangles,
- * which are only used to disambiguate triangles with colinear points. */
- struct Edge
- {
- Edge(const Point* left_,
- const Point* right_,
- int triangle_below_,
- int triangle_above_,
- const Point* point_below_,
- const Point* point_above_);
-
- // Return -1 if point to left of edge, 0 if on edge, +1 if to right.
- int get_point_orientation(const XY& xy) const;
-
- // Return slope of edge, even if vertical (divide by zero is OK here).
- double get_slope() const;
-
- /* Return y-coordinate of point on edge with specified x-coordinate.
- * x must be within the x-limits of this edge. */
- double get_y_at_x(const double& x) const;
-
- // Return true if the specified point is either of the edge end points.
- bool has_point(const Point* point) const;
-
- bool operator==(const Edge& other) const;
-
- friend std::ostream& operator<<(std::ostream& os, const Edge& edge)
- {
- return os << *edge.left << "->" << *edge.right;
- }
-
- void print_debug() const;
-
-
- const Point* left; // Not owned.
- const Point* right; // Not owned.
- int triangle_below; // Index of triangle below (to right of) Edge.
- int triangle_above; // Index of triangle above (to left of) Edge.
- const Point* point_below; // Used only for resolving ambiguous cases;
- const Point* point_above; // is 0 if corresponding triangle is -1
- };
-
- class Node; // Forward declaration.
-
- // Helper structure used by TrapezoidMapTriFinder::get_tree_stats.
- struct NodeStats
- {
- NodeStats()
- : node_count(0), trapezoid_count(0), max_parent_count(0),
- max_depth(0), sum_trapezoid_depth(0.0)
- {}
-
- long node_count, trapezoid_count, max_parent_count, max_depth;
- double sum_trapezoid_depth;
- std::set<const Node*> unique_nodes, unique_trapezoid_nodes;
- };
-
- struct Trapezoid; // Forward declaration.
-
- /* Node of the trapezoid map search tree. There are 3 possible types:
- * Type_XNode, Type_YNode and Type_TrapezoidNode. Data members are
- * represented using a union: an XNode has a Point and 2 child nodes
- * (left and right of the point), a YNode has an Edge and 2 child nodes
- * (below and above the edge), and a TrapezoidNode has a Trapezoid.
- * Each Node has multiple parents so it can appear in the search tree
- * multiple times without having to create duplicate identical Nodes.
- * The parent collection acts as a reference count to the number of times
- * a Node occurs in the search tree. When the parent count is reduced to
- * zero a Node can be safely deleted. */
- class Node
- {
- public:
- Node(const Point* point, Node* left, Node* right);// Type_XNode.
- Node(const Edge* edge, Node* below, Node* above); // Type_YNode.
- Node(Trapezoid* trapezoid); // Type_TrapezoidNode.
-
- ~Node();
-
- void add_parent(Node* parent);
-
- /* Recurse through the search tree and assert that everything is valid.
- * Reduces to a no-op if NDEBUG is defined. */
- void assert_valid(bool tree_complete) const;
-
- // Recurse through the tree to return statistics about it.
- void get_stats(int depth, NodeStats& stats) const;
-
- // Return the index of the triangle corresponding to this node.
- int get_tri() const;
-
- bool has_child(const Node* child) const;
- bool has_no_parents() const;
- bool has_parent(const Node* parent) const;
-
- /* Recurse through the tree and print a textual representation to
- * stdout. Argument depth used to indent for readability. */
- void print(int depth = 0) const;
-
- /* Remove a parent from this Node. Return true if no parents remain
- * so that this Node can be deleted. */
- bool remove_parent(Node* parent);
-
- void replace_child(Node* old_child, Node* new_child);
-
- // Replace this node with the specified new_node in all parents.
- void replace_with(Node* new_node);
-
- /* Recursive search through the tree to find the Node containing the
- * specified XY point. */
- const Node* search(const XY& xy);
-
- /* Recursive search through the tree to find the Trapezoid containing
- * the left endpoint of the specified Edge. Return 0 if fails, which
- * can only happen if the triangulation is invalid. */
- Trapezoid* search(const Edge& edge);
-
- /* Copy constructor and assignment operator defined but not implemented
- * to prevent objects being copied. */
- Node(const Node& other);
- Node& operator=(const Node& other);
-
- private:
- typedef enum {
- Type_XNode,
- Type_YNode,
- Type_TrapezoidNode
- } Type;
- Type _type;
-
- union {
- struct {
- const Point* point; // Not owned.
- Node* left; // Owned.
- Node* right; // Owned.
- } xnode;
- struct {
- const Edge* edge; // Not owned.
- Node* below; // Owned.
- Node* above; // Owned.
- } ynode;
- Trapezoid* trapezoid; // Owned.
- } _union;
-
- typedef std::list<Node*> Parents;
- Parents _parents; // Not owned.
- };
-
- /* A Trapezoid is bounded by Points to left and right, and Edges below and
- * above. Has up to 4 neighboring Trapezoids to lower/upper left/right.
- * Lower left neighbor is Trapezoid to left that shares the below Edge, or
- * is 0 if there is no such Trapezoid (and similar for other neighbors).
- * To obtain the index of the triangle corresponding to a particular
- * Trapezoid, use the Edge member variables below.triangle_above or
- * above.triangle_below. */
- struct Trapezoid
- {
- Trapezoid(const Point* left_,
- const Point* right_,
- const Edge& below_,
- const Edge& above_);
-
- /* Assert that this Trapezoid is valid. Reduces to a no-op if NDEBUG
- * is defined. */
- void assert_valid(bool tree_complete) const;
-
- /* Return one of the 4 corner points of this Trapezoid. Only used for
- * debugging purposes. */
- XY get_lower_left_point() const;
- XY get_lower_right_point() const;
- XY get_upper_left_point() const;
- XY get_upper_right_point() const;
-
- void print_debug() const;
-
- /* Set one of the 4 neighbor trapezoids and the corresponding reverse
- * Trapezoid of the new neighbor (if it is not 0), so that they are
- * consistent. */
- void set_lower_left(Trapezoid* lower_left_);
- void set_lower_right(Trapezoid* lower_right_);
- void set_upper_left(Trapezoid* upper_left_);
- void set_upper_right(Trapezoid* upper_right_);
-
- /* Copy constructor and assignment operator defined but not implemented
- * to prevent objects being copied. */
- Trapezoid(const Trapezoid& other);
- Trapezoid& operator=(const Trapezoid& other);
-
-
- const Point* left; // Not owned.
- const Point* right; // Not owned.
- const Edge& below;
- const Edge& above;
-
- // 4 neighboring trapezoids, can be 0, not owned.
- Trapezoid* lower_left; // Trapezoid to left that shares below
- Trapezoid* lower_right; // Trapezoid to right that shares below
- Trapezoid* upper_left; // Trapezoid to left that shares above
- Trapezoid* upper_right; // Trapezoid to right that shares above
-
- Node* trapezoid_node; // Node that owns this Trapezoid.
- };
-
-
- // Add the specified Edge to the search tree, returning true if successful.
- bool add_edge_to_tree(const Edge& edge);
-
- // Clear all memory allocated by this object.
- void clear();
-
- // Return the triangle index at the specified point, or -1 if no triangle.
- int find_one(const XY& xy);
-
- /* Determine the trapezoids that the specified Edge intersects, returning
- * true if successful. */
- bool find_trapezoids_intersecting_edge(const Edge& edge,
- std::vector<Trapezoid*>& trapezoids);
-
-
-
- // Variables shared with python, always set.
- Triangulation& _triangulation;
-
- // Variables internal to C++ only.
- Point* _points; // Array of all points in triangulation plus corners of
- // enclosing rectangle. Owned.
-
- typedef std::vector<Edge> Edges;
- Edges _edges; // All Edges in triangulation plus bottom and top Edges of
- // enclosing rectangle.
-
- Node* _tree; // Root node of the trapezoid map search tree. Owned.
-};
-
-
-
-/* Linear congruential random number generator. Edges in the triangulation are
- * randomly shuffled before being added to the trapezoid map. Want the
- * shuffling to be identical across different operating systems and the same
- * regardless of previous random number use. Would prefer to use a STL or
- * Boost random number generator, but support is not consistent across
- * different operating systems so implementing own here.
- *
- * This is not particularly random, but is perfectly adequate for the use here.
- * Coefficients taken from Numerical Recipes in C. */
-class RandomNumberGenerator
-{
-public:
- RandomNumberGenerator(unsigned long seed);
-
- // Return random integer in the range 0 to max_value-1.
- unsigned long operator()(unsigned long max_value);
-
-private:
- const unsigned long _m, _a, _c;
- unsigned long _seed;
-};
-
-#endif
diff --git a/contrib/python/matplotlib/py2/matplotlib/tri/_tri_wrapper.cpp b/contrib/python/matplotlib/py2/matplotlib/tri/_tri_wrapper.cpp
deleted file mode 100644
index 8ad269b353..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/tri/_tri_wrapper.cpp
+++ /dev/null
@@ -1,550 +0,0 @@
-#include "_tri.h"
-#include "src/mplutils.h"
-#include "src/py_exceptions.h"
-
-
-/* Triangulation */
-
-typedef struct
-{
- PyObject_HEAD
- Triangulation* ptr;
-} PyTriangulation;
-
-static PyTypeObject PyTriangulationType;
-
-static PyObject* PyTriangulation_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
-{
- PyTriangulation* self;
- self = (PyTriangulation*)type->tp_alloc(type, 0);
- self->ptr = NULL;
- return (PyObject*)self;
-}
-
-const char* PyTriangulation_init__doc__ =
- "Triangulation(x, y, triangles, mask, edges, neighbors)\n"
- "\n"
- "Create a new C++ Triangulation object\n"
- "This should not be called directly, instead use the python class\n"
- "matplotlib.tri.Triangulation instead.\n";
-
-static int PyTriangulation_init(PyTriangulation* self, PyObject* args, PyObject* kwds)
-{
- Triangulation::CoordinateArray x, y;
- Triangulation::TriangleArray triangles;
- Triangulation::MaskArray mask;
- Triangulation::EdgeArray edges;
- Triangulation::NeighborArray neighbors;
- int correct_triangle_orientations;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&O&O&i",
- &x.converter, &x,
- &y.converter, &y,
- &triangles.converter, &triangles,
- &mask.converter, &mask,
- &edges.converter, &edges,
- &neighbors.converter, &neighbors,
- &correct_triangle_orientations)) {
- return -1;
- }
-
- // x and y.
- if (x.empty() || y.empty() || x.dim(0) != y.dim(0)) {
- PyErr_SetString(PyExc_ValueError,
- "x and y must be 1D arrays of the same length");
- return -1;
- }
-
- // triangles.
- if (triangles.empty() || triangles.dim(1) != 3) {
- PyErr_SetString(PyExc_ValueError,
- "triangles must be a 2D array of shape (?,3)");
- return -1;
- }
-
- // Optional mask.
- if (!mask.empty() && mask.dim(0) != triangles.dim(0)) {
- PyErr_SetString(PyExc_ValueError,
- "mask must be a 1D array with the same length as the triangles array");
- return -1;
- }
-
- // Optional edges.
- if (!edges.empty() && edges.dim(1) != 2) {
- PyErr_SetString(PyExc_ValueError,
- "edges must be a 2D array with shape (?,2)");
- return -1;
- }
-
- // Optional neighbors.
- if (!neighbors.empty() && (neighbors.dim(0) != triangles.dim(0) ||
- neighbors.dim(1) != triangles.dim(1))) {
- PyErr_SetString(PyExc_ValueError,
- "neighbors must be a 2D array with the same shape as the triangles array");
- return -1;
- }
-
- CALL_CPP_INIT("Triangulation",
- (self->ptr = new Triangulation(x, y, triangles, mask,
- edges, neighbors,
- correct_triangle_orientations)));
- return 0;
-}
-
-static void PyTriangulation_dealloc(PyTriangulation* self)
-{
- delete self->ptr;
- Py_TYPE(self)->tp_free((PyObject*)self);
-}
-
-const char* PyTriangulation_calculate_plane_coefficients__doc__ =
- "calculate_plane_coefficients(z, plane_coefficients)\n"
- "\n"
- "Calculate plane equation coefficients for all unmasked triangles";
-
-static PyObject* PyTriangulation_calculate_plane_coefficients(PyTriangulation* self, PyObject* args, PyObject* kwds)
-{
- Triangulation::CoordinateArray z;
- if (!PyArg_ParseTuple(args, "O&:calculate_plane_coefficients",
- &z.converter, &z)) {
- return NULL;
- }
-
- if (z.empty() || z.dim(0) != self->ptr->get_npoints()) {
- PyErr_SetString(PyExc_ValueError,
- "z array must have same length as triangulation x and y arrays");
- return NULL;
- }
-
- Triangulation::TwoCoordinateArray result;
- CALL_CPP("calculate_plane_coefficients",
- (result = self->ptr->calculate_plane_coefficients(z)));
- return result.pyobj();
-}
-
-const char* PyTriangulation_get_edges__doc__ =
- "get_edges()\n"
- "\n"
- "Return edges array";
-
-static PyObject* PyTriangulation_get_edges(PyTriangulation* self, PyObject* args, PyObject* kwds)
-{
- Triangulation::EdgeArray* result;
- CALL_CPP("get_edges", (result = &self->ptr->get_edges()));
-
- if (result->empty()) {
- Py_RETURN_NONE;
- }
- else
- return result->pyobj();
-}
-
-const char* PyTriangulation_get_neighbors__doc__ =
- "get_neighbors()\n"
- "\n"
- "Return neighbors array";
-
-static PyObject* PyTriangulation_get_neighbors(PyTriangulation* self, PyObject* args, PyObject* kwds)
-{
- Triangulation::NeighborArray* result;
- CALL_CPP("get_neighbors", (result = &self->ptr->get_neighbors()));
-
- if (result->empty()) {
- Py_RETURN_NONE;
- }
- else
- return result->pyobj();
-}
-
-const char* PyTriangulation_set_mask__doc__ =
- "set_mask(mask)\n"
- "\n"
- "Set or clear the mask array.";
-
-static PyObject* PyTriangulation_set_mask(PyTriangulation* self, PyObject* args, PyObject* kwds)
-{
- Triangulation::MaskArray mask;
-
- if (!PyArg_ParseTuple(args, "O&:set_mask", &mask.converter, &mask)) {
- return NULL;
- }
-
- if (!mask.empty() && mask.dim(0) != self->ptr->get_ntri()) {
- PyErr_SetString(PyExc_ValueError,
- "mask must be a 1D array with the same length as the triangles array");
- return NULL;
- }
-
- CALL_CPP("set_mask", (self->ptr->set_mask(mask)));
- Py_RETURN_NONE;
-}
-
-static PyTypeObject* PyTriangulation_init_type(PyObject* m, PyTypeObject* type)
-{
- static PyMethodDef methods[] = {
- {"calculate_plane_coefficients", (PyCFunction)PyTriangulation_calculate_plane_coefficients, METH_VARARGS, PyTriangulation_calculate_plane_coefficients__doc__},
- {"get_edges", (PyCFunction)PyTriangulation_get_edges, METH_NOARGS, PyTriangulation_get_edges__doc__},
- {"get_neighbors", (PyCFunction)PyTriangulation_get_neighbors, METH_NOARGS, PyTriangulation_get_neighbors__doc__},
- {"set_mask", (PyCFunction)PyTriangulation_set_mask, METH_VARARGS, PyTriangulation_set_mask__doc__},
- {NULL}
- };
-
- memset(type, 0, sizeof(PyTypeObject));
- type->tp_name = "matplotlib._tri.Triangulation";
- type->tp_doc = PyTriangulation_init__doc__;
- type->tp_basicsize = sizeof(PyTriangulation);
- type->tp_dealloc = (destructor)PyTriangulation_dealloc;
- type->tp_flags = Py_TPFLAGS_DEFAULT;
- type->tp_methods = methods;
- type->tp_new = PyTriangulation_new;
- type->tp_init = (initproc)PyTriangulation_init;
-
- if (PyType_Ready(type) < 0) {
- return NULL;
- }
-
- if (PyModule_AddObject(m, "Triangulation", (PyObject*)type)) {
- return NULL;
- }
-
- return type;
-}
-
-
-/* TriContourGenerator */
-
-typedef struct
-{
- PyObject_HEAD
- TriContourGenerator* ptr;
- PyTriangulation* py_triangulation;
-} PyTriContourGenerator;
-
-static PyTypeObject PyTriContourGeneratorType;
-
-static PyObject* PyTriContourGenerator_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
-{
- PyTriContourGenerator* self;
- self = (PyTriContourGenerator*)type->tp_alloc(type, 0);
- self->ptr = NULL;
- self->py_triangulation = NULL;
- return (PyObject*)self;
-}
-
-const char* PyTriContourGenerator_init__doc__ =
- "TriContourGenerator(triangulation, z)\n"
- "\n"
- "Create a new C++ TriContourGenerator object\n"
- "This should not be called directly, instead use the functions\n"
- "matplotlib.axes.tricontour and tricontourf instead.\n";
-
-static int PyTriContourGenerator_init(PyTriContourGenerator* self, PyObject* args, PyObject* kwds)
-{
- PyObject* triangulation_arg;
- TriContourGenerator::CoordinateArray z;
-
- if (!PyArg_ParseTuple(args, "O!O&",
- &PyTriangulationType, &triangulation_arg,
- &z.converter, &z)) {
- return -1;
- }
-
- PyTriangulation* py_triangulation = (PyTriangulation*)triangulation_arg;
- Py_INCREF(py_triangulation);
- self->py_triangulation = py_triangulation;
- Triangulation& triangulation = *(py_triangulation->ptr);
-
- if (z.empty() || z.dim(0) != triangulation.get_npoints()) {
- PyErr_SetString(PyExc_ValueError,
- "z must be a 1D array with the same length as the x and y arrays");
- return -1;
- }
-
- CALL_CPP_INIT("TriContourGenerator",
- (self->ptr = new TriContourGenerator(triangulation, z)));
- return 0;
-}
-
-static void PyTriContourGenerator_dealloc(PyTriContourGenerator* self)
-{
- delete self->ptr;
- Py_XDECREF(self->py_triangulation);
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-const char* PyTriContourGenerator_create_contour__doc__ =
- "create_contour(level)\n"
- "\n"
- "Create and return a non-filled contour.";
-
-static PyObject* PyTriContourGenerator_create_contour(PyTriContourGenerator* self, PyObject* args, PyObject* kwds)
-{
- double level;
- if (!PyArg_ParseTuple(args, "d:create_contour", &level)) {
- return NULL;
- }
-
- PyObject* result;
- CALL_CPP("create_contour", (result = self->ptr->create_contour(level)));
- return result;
-}
-
-const char* PyTriContourGenerator_create_filled_contour__doc__ =
- "create_filled_contour(lower_level, upper_level)\n"
- "\n"
- "Create and return a filled contour";
-
-static PyObject* PyTriContourGenerator_create_filled_contour(PyTriContourGenerator* self, PyObject* args, PyObject* kwds)
-{
- double lower_level, upper_level;
- if (!PyArg_ParseTuple(args, "dd:create_filled_contour",
- &lower_level, &upper_level)) {
- return NULL;
- }
-
- if (lower_level >= upper_level)
- {
- PyErr_SetString(PyExc_ValueError,
- "filled contour levels must be increasing");
- return NULL;
- }
-
- PyObject* result;
- CALL_CPP("create_filled_contour",
- (result = self->ptr->create_filled_contour(lower_level,
- upper_level)));
- return result;
-}
-
-static PyTypeObject* PyTriContourGenerator_init_type(PyObject* m, PyTypeObject* type)
-{
- static PyMethodDef methods[] = {
- {"create_contour", (PyCFunction)PyTriContourGenerator_create_contour, METH_VARARGS, PyTriContourGenerator_create_contour__doc__},
- {"create_filled_contour", (PyCFunction)PyTriContourGenerator_create_filled_contour, METH_VARARGS, PyTriContourGenerator_create_filled_contour__doc__},
- {NULL}
- };
-
- memset(type, 0, sizeof(PyTypeObject));
- type->tp_name = "matplotlib._tri.TriContourGenerator";
- type->tp_doc = PyTriContourGenerator_init__doc__;
- type->tp_basicsize = sizeof(PyTriContourGenerator);
- type->tp_dealloc = (destructor)PyTriContourGenerator_dealloc;
- type->tp_flags = Py_TPFLAGS_DEFAULT;
- type->tp_methods = methods;
- type->tp_new = PyTriContourGenerator_new;
- type->tp_init = (initproc)PyTriContourGenerator_init;
-
- if (PyType_Ready(type) < 0) {
- return NULL;
- }
-
- if (PyModule_AddObject(m, "TriContourGenerator", (PyObject*)type)) {
- return NULL;
- }
-
- return type;
-}
-
-
-/* TrapezoidMapTriFinder */
-
-typedef struct
-{
- PyObject_HEAD
- TrapezoidMapTriFinder* ptr;
- PyTriangulation* py_triangulation;
-} PyTrapezoidMapTriFinder;
-
-static PyTypeObject PyTrapezoidMapTriFinderType;
-
-static PyObject* PyTrapezoidMapTriFinder_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
-{
- PyTrapezoidMapTriFinder* self;
- self = (PyTrapezoidMapTriFinder*)type->tp_alloc(type, 0);
- self->ptr = NULL;
- self->py_triangulation = NULL;
- return (PyObject*)self;
-}
-
-const char* PyTrapezoidMapTriFinder_init__doc__ =
- "TrapezoidMapTriFinder(triangulation)\n"
- "\n"
- "Create a new C++ TrapezoidMapTriFinder object\n"
- "This should not be called directly, instead use the python class\n"
- "matplotlib.tri.TrapezoidMapTriFinder instead.\n";
-
-static int PyTrapezoidMapTriFinder_init(PyTrapezoidMapTriFinder* self, PyObject* args, PyObject* kwds)
-{
- PyObject* triangulation_arg;
- if (!PyArg_ParseTuple(args, "O!",
- &PyTriangulationType, &triangulation_arg)) {
- return -1;
- }
-
- PyTriangulation* py_triangulation = (PyTriangulation*)triangulation_arg;
- Py_INCREF(py_triangulation);
- self->py_triangulation = py_triangulation;
- Triangulation& triangulation = *(py_triangulation->ptr);
-
- CALL_CPP_INIT("TrapezoidMapTriFinder",
- (self->ptr = new TrapezoidMapTriFinder(triangulation)));
- return 0;
-}
-
-static void PyTrapezoidMapTriFinder_dealloc(PyTrapezoidMapTriFinder* self)
-{
- delete self->ptr;
- Py_XDECREF(self->py_triangulation);
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-const char* PyTrapezoidMapTriFinder_find_many__doc__ =
- "find_many(x, y)\n"
- "\n"
- "Find indices of triangles containing the point coordinates (x, y)";
-
-static PyObject* PyTrapezoidMapTriFinder_find_many(PyTrapezoidMapTriFinder* self, PyObject* args, PyObject* kwds)
-{
- TrapezoidMapTriFinder::CoordinateArray x, y;
- if (!PyArg_ParseTuple(args, "O&O&:find_many",
- &x.converter, &x,
- &y.converter, &y)) {
- return NULL;
- }
-
- if (x.empty() || y.empty() || x.dim(0) != y.dim(0)) {
- PyErr_SetString(PyExc_ValueError,
- "x and y must be array_like with same shape");
- return NULL;
- }
-
- TrapezoidMapTriFinder::TriIndexArray result;
- CALL_CPP("find_many", (result = self->ptr->find_many(x, y)));
- return result.pyobj();
-}
-
-const char* PyTrapezoidMapTriFinder_get_tree_stats__doc__ =
- "get_tree_stats()\n"
- "\n"
- "Return statistics about the tree used by the trapezoid map";
-
-static PyObject* PyTrapezoidMapTriFinder_get_tree_stats(PyTrapezoidMapTriFinder* self, PyObject* args, PyObject* kwds)
-{
- PyObject* result;
- CALL_CPP("get_tree_stats", (result = self->ptr->get_tree_stats()));
- return result;
-}
-
-const char* PyTrapezoidMapTriFinder_initialize__doc__ =
- "initialize()\n"
- "\n"
- "Initialize this object, creating the trapezoid map from the triangulation";
-
-static PyObject* PyTrapezoidMapTriFinder_initialize(PyTrapezoidMapTriFinder* self, PyObject* args, PyObject* kwds)
-{
- CALL_CPP("initialize", (self->ptr->initialize()));
- Py_RETURN_NONE;
-}
-
-const char* PyTrapezoidMapTriFinder_print_tree__doc__ =
- "print_tree()\n"
- "\n"
- "Print the search tree as text to stdout; useful for debug purposes";
-
-static PyObject* PyTrapezoidMapTriFinder_print_tree(PyTrapezoidMapTriFinder* self, PyObject* args, PyObject* kwds)
-{
- CALL_CPP("print_tree", (self->ptr->print_tree()));
- Py_RETURN_NONE;
-}
-
-static PyTypeObject* PyTrapezoidMapTriFinder_init_type(PyObject* m, PyTypeObject* type)
-{
- static PyMethodDef methods[] = {
- {"find_many", (PyCFunction)PyTrapezoidMapTriFinder_find_many, METH_VARARGS, PyTrapezoidMapTriFinder_find_many__doc__},
- {"get_tree_stats", (PyCFunction)PyTrapezoidMapTriFinder_get_tree_stats, METH_NOARGS, PyTrapezoidMapTriFinder_get_tree_stats__doc__},
- {"initialize", (PyCFunction)PyTrapezoidMapTriFinder_initialize, METH_NOARGS, PyTrapezoidMapTriFinder_initialize__doc__},
- {"print_tree", (PyCFunction)PyTrapezoidMapTriFinder_print_tree, METH_NOARGS, PyTrapezoidMapTriFinder_print_tree__doc__},
- {NULL}
- };
-
- memset(type, 0, sizeof(PyTypeObject));
- type->tp_name = "matplotlib._tri.TrapezoidMapTriFinder";
- type->tp_doc = PyTrapezoidMapTriFinder_init__doc__;
- type->tp_basicsize = sizeof(PyTrapezoidMapTriFinder);
- type->tp_dealloc = (destructor)PyTrapezoidMapTriFinder_dealloc;
- type->tp_flags = Py_TPFLAGS_DEFAULT;
- type->tp_methods = methods;
- type->tp_new = PyTrapezoidMapTriFinder_new;
- type->tp_init = (initproc)PyTrapezoidMapTriFinder_init;
-
- if (PyType_Ready(type) < 0) {
- return NULL;
- }
-
- if (PyModule_AddObject(m, "TrapezoidMapTriFinder", (PyObject*)type)) {
- return NULL;
- }
-
- return type;
-}
-
-
-/* Module */
-
-extern "C" {
-
-#if PY3K
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_tri",
- NULL,
- 0,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit__tri(void)
-
-#else
-#define INITERROR return
-
-PyMODINIT_FUNC init_tri(void)
-#endif
-
-{
- PyObject *m;
-
-#if PY3K
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("_tri", NULL, NULL);
-#endif
-
- if (m == NULL) {
- INITERROR;
- }
-
- if (!PyTriangulation_init_type(m, &PyTriangulationType)) {
- INITERROR;
- }
- if (!PyTriContourGenerator_init_type(m, &PyTriContourGeneratorType)) {
- INITERROR;
- }
- if (!PyTrapezoidMapTriFinder_init_type(m, &PyTrapezoidMapTriFinderType)) {
- INITERROR;
- }
-
- import_array();
-
-#if PY3K
- return m;
-#endif
-}
-
-} // extern "C"
diff --git a/contrib/python/matplotlib/py2/matplotlib/tri/triangulation.py b/contrib/python/matplotlib/py2/matplotlib/tri/triangulation.py
deleted file mode 100644
index b80aaf87b9..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/tri/triangulation.py
+++ /dev/null
@@ -1,218 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import matplotlib._tri as _tri
-import matplotlib._qhull as _qhull
-import numpy as np
-
-
-class Triangulation(object):
- """
- An unstructured triangular grid consisting of npoints points and
- ntri triangles. The triangles can either be specified by the user
- or automatically generated using a Delaunay triangulation.
-
- Parameters
- ----------
- x, y : array_like of shape (npoints)
- Coordinates of grid points.
- triangles : integer array_like of shape (ntri, 3), optional
- For each triangle, the indices of the three points that make
- up the triangle, ordered in an anticlockwise manner. If not
- specified, the Delaunay triangulation is calculated.
- mask : boolean array_like of shape (ntri), optional
- Which triangles are masked out.
-
- Attributes
- ----------
- `edges`
- `neighbors`
- is_delaunay : bool
- Whether the Triangulation is a calculated Delaunay
- triangulation (where `triangles` was not specified) or not.
-
- Notes
- -----
- For a Triangulation to be valid it must not have duplicate points,
- triangles formed from colinear points, or overlapping triangles.
- """
- def __init__(self, x, y, triangles=None, mask=None):
- self.x = np.asarray(x, dtype=np.float64)
- self.y = np.asarray(y, dtype=np.float64)
- if self.x.shape != self.y.shape or self.x.ndim != 1:
- raise ValueError("x and y must be equal-length 1-D arrays")
-
- self.mask = None
- self._edges = None
- self._neighbors = None
- self.is_delaunay = False
-
- if triangles is None:
- # No triangulation specified, so use matplotlib._qhull to obtain
- # Delaunay triangulation.
- self.triangles, self._neighbors = _qhull.delaunay(x, y)
- self.is_delaunay = True
- else:
- # Triangulation specified. Copy, since we may correct triangle
- # orientation.
- self.triangles = np.array(triangles, dtype=np.int32, order='C')
- if self.triangles.ndim != 2 or self.triangles.shape[1] != 3:
- raise ValueError('triangles must be a (?,3) array')
- if self.triangles.max() >= len(self.x):
- raise ValueError('triangles max element is out of bounds')
- if self.triangles.min() < 0:
- raise ValueError('triangles min element is out of bounds')
-
- if mask is not None:
- self.mask = np.asarray(mask, dtype=bool)
- if self.mask.shape != (self.triangles.shape[0],):
- raise ValueError('mask array must have same length as '
- 'triangles array')
-
- # Underlying C++ object is not created until first needed.
- self._cpp_triangulation = None
-
- # Default TriFinder not created until needed.
- self._trifinder = None
-
- def calculate_plane_coefficients(self, z):
- """
- Calculate plane equation coefficients for all unmasked triangles from
- the point (x,y) coordinates and specified z-array of shape (npoints).
- Returned array has shape (npoints,3) and allows z-value at (x,y)
- position in triangle tri to be calculated using
- z = array[tri,0]*x + array[tri,1]*y + array[tri,2].
- """
- return self.get_cpp_triangulation().calculate_plane_coefficients(z)
-
- @property
- def edges(self):
- """
- Return integer array of shape (nedges,2) containing all edges of
- non-masked triangles.
-
- Each edge is the start point index and end point index. Each
- edge (start,end and end,start) appears only once.
- """
- if self._edges is None:
- self._edges = self.get_cpp_triangulation().get_edges()
- return self._edges
-
- def get_cpp_triangulation(self):
- # Return the underlying C++ Triangulation object, creating it
- # if necessary.
- if self._cpp_triangulation is None:
- self._cpp_triangulation = _tri.Triangulation(
- self.x, self.y, self.triangles, self.mask, self._edges,
- self._neighbors, not self.is_delaunay)
- return self._cpp_triangulation
-
- def get_masked_triangles(self):
- """
- Return an array of triangles that are not masked.
- """
- if self.mask is not None:
- return self.triangles.compress(1 - self.mask, axis=0)
- else:
- return self.triangles
-
- @staticmethod
- def get_from_args_and_kwargs(*args, **kwargs):
- """
- Return a Triangulation object from the args and kwargs, and
- the remaining args and kwargs with the consumed values removed.
-
- There are two alternatives: either the first argument is a
- Triangulation object, in which case it is returned, or the args
- and kwargs are sufficient to create a new Triangulation to
- return. In the latter case, see Triangulation.__init__ for
- the possible args and kwargs.
- """
- if isinstance(args[0], Triangulation):
- triangulation = args[0]
- args = args[1:]
- else:
- x = args[0]
- y = args[1]
- args = args[2:] # Consumed first two args.
-
- # Check triangles in kwargs then args.
- triangles = kwargs.pop('triangles', None)
- from_args = False
- if triangles is None and len(args) > 0:
- triangles = args[0]
- from_args = True
-
- if triangles is not None:
- try:
- triangles = np.asarray(triangles, dtype=np.int32)
- except ValueError:
- triangles = None
-
- if triangles is not None and (triangles.ndim != 2 or
- triangles.shape[1] != 3):
- triangles = None
-
- if triangles is not None and from_args:
- args = args[1:] # Consumed first item in args.
-
- # Check for mask in kwargs.
- mask = kwargs.pop('mask', None)
-
- triangulation = Triangulation(x, y, triangles, mask)
- return triangulation, args, kwargs
-
- def get_trifinder(self):
- """
- Return the default :class:`matplotlib.tri.TriFinder` of this
- triangulation, creating it if necessary. This allows the same
- TriFinder object to be easily shared.
- """
- if self._trifinder is None:
- # Default TriFinder class.
- from matplotlib.tri.trifinder import TrapezoidMapTriFinder
- self._trifinder = TrapezoidMapTriFinder(self)
- return self._trifinder
-
- @property
- def neighbors(self):
- """
- Return integer array of shape (ntri,3) containing neighbor
- triangles.
-
- For each triangle, the indices of the three triangles that
- share the same edges, or -1 if there is no such neighboring
- triangle. neighbors[i,j] is the triangle that is the neighbor
- to the edge from point index triangles[i,j] to point index
- triangles[i,(j+1)%3].
- """
- if self._neighbors is None:
- self._neighbors = self.get_cpp_triangulation().get_neighbors()
- return self._neighbors
-
- def set_mask(self, mask):
- """
- Set or clear the mask array. This is either None, or a boolean
- array of shape (ntri).
- """
- if mask is None:
- self.mask = None
- else:
- self.mask = np.asarray(mask, dtype=bool)
- if self.mask.shape != (self.triangles.shape[0],):
- raise ValueError('mask array must have same length as '
- 'triangles array')
-
- # Set mask in C++ Triangulation.
- if self._cpp_triangulation is not None:
- self._cpp_triangulation.set_mask(self.mask)
-
- # Clear derived fields so they are recalculated when needed.
- self._edges = None
- self._neighbors = None
-
- # Recalculate TriFinder if it exists.
- if self._trifinder is not None:
- self._trifinder._initialize()
diff --git a/contrib/python/matplotlib/py2/matplotlib/tri/tricontour.py b/contrib/python/matplotlib/py2/matplotlib/tri/tricontour.py
deleted file mode 100644
index 3087409b72..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/tri/tricontour.py
+++ /dev/null
@@ -1,283 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from matplotlib.contour import ContourSet
-from matplotlib.tri.triangulation import Triangulation
-import matplotlib._tri as _tri
-import numpy as np
-
-
-class TriContourSet(ContourSet):
- """
- Create and store a set of contour lines or filled regions for
- a triangular grid.
-
- User-callable method: clabel
-
- Useful attributes:
- ax:
- the axes object in which the contours are drawn
- collections:
- a silent_list of LineCollections or PolyCollections
- levels:
- contour levels
- layers:
- same as levels for line contours; half-way between
- levels for filled contours. See _process_colors method.
- """
- def __init__(self, ax, *args, **kwargs):
- """
- Draw triangular grid contour lines or filled regions,
- depending on whether keyword arg 'filled' is False
- (default) or True.
-
- The first argument of the initializer must be an axes
- object. The remaining arguments and keyword arguments
- are described in the docstring of `tricontour`.
- """
- ContourSet.__init__(self, ax, *args, **kwargs)
-
- def _process_args(self, *args, **kwargs):
- """
- Process args and kwargs.
- """
- if isinstance(args[0], TriContourSet):
- C = args[0].cppContourGenerator
- if self.levels is None:
- self.levels = args[0].levels
- else:
- tri, z = self._contour_args(args, kwargs)
- C = _tri.TriContourGenerator(tri.get_cpp_triangulation(), z)
- self._mins = [tri.x.min(), tri.y.min()]
- self._maxs = [tri.x.max(), tri.y.max()]
-
- self.cppContourGenerator = C
- return kwargs
-
- def _get_allsegs_and_allkinds(self):
- """
- Create and return allsegs and allkinds by calling underlying C code.
- """
- allsegs = []
- if self.filled:
- lowers, uppers = self._get_lowers_and_uppers()
- allkinds = []
- for lower, upper in zip(lowers, uppers):
- segs, kinds = self.cppContourGenerator.create_filled_contour(
- lower, upper)
- allsegs.append([segs])
- allkinds.append([kinds])
- else:
- allkinds = None
- for level in self.levels:
- segs = self.cppContourGenerator.create_contour(level)
- allsegs.append(segs)
- return allsegs, allkinds
-
- def _contour_args(self, args, kwargs):
- if self.filled:
- fn = 'contourf'
- else:
- fn = 'contour'
- tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args,
- **kwargs)
- z = np.asarray(args[0])
- if z.shape != tri.x.shape:
- raise ValueError('z array must have same length as triangulation x'
- ' and y arrays')
- self.zmax = z.max()
- self.zmin = z.min()
- if self.logscale and self.zmin <= 0:
- raise ValueError('Cannot %s log of negative values.' % fn)
- self._contour_level_args(z, args[1:])
- return (tri, z)
-
-
-def tricontour(ax, *args, **kwargs):
- """
- Draw contours on an unstructured triangular grid.
- :func:`~matplotlib.pyplot.tricontour` and
- :func:`~matplotlib.pyplot.tricontourf` draw contour lines and
- filled contours, respectively. Except as noted, function
- signatures and return values are the same for both versions.
-
- The triangulation can be specified in one of two ways; either::
-
- tricontour(triangulation, ...)
-
- where triangulation is a :class:`matplotlib.tri.Triangulation`
- object, or
-
- ::
-
- tricontour(x, y, ...)
- tricontour(x, y, triangles, ...)
- tricontour(x, y, triangles=triangles, ...)
- tricontour(x, y, mask=mask, ...)
- tricontour(x, y, triangles, mask=mask, ...)
-
- in which case a Triangulation object will be created. See
- :class:`~matplotlib.tri.Triangulation` for a explanation of
- these possibilities.
-
- The remaining arguments may be::
-
- tricontour(..., Z)
-
- where *Z* is the array of values to contour, one per point
- in the triangulation. The level values are chosen
- automatically.
-
- ::
-
- tricontour(..., Z, N)
-
- contour up to *N+1* automatically chosen contour levels
- (*N* intervals).
-
- ::
-
- tricontour(..., Z, V)
-
- draw contour lines at the values specified in sequence *V*,
- which must be in increasing order.
-
- ::
-
- tricontourf(..., Z, V)
-
- fill the (len(*V*)-1) regions between the values in *V*,
- which must be in increasing order.
-
- ::
-
- tricontour(Z, **kwargs)
-
- Use keyword args to control colors, linewidth, origin, cmap ... see
- below for more details.
-
- ``C = tricontour(...)`` returns a
- :class:`~matplotlib.contour.TriContourSet` object.
-
- Optional keyword arguments:
-
- *colors*: [ *None* | string | (mpl_colors) ]
- If *None*, the colormap specified by cmap will be used.
-
- If a string, like 'r' or 'red', all levels will be plotted in this
- color.
-
- If a tuple of matplotlib color args (string, float, rgb, etc),
- different levels will be plotted in different colors in the order
- specified.
-
- *alpha*: float
- The alpha blending value
-
- *cmap*: [ *None* | Colormap ]
- A cm :class:`~matplotlib.colors.Colormap` instance or
- *None*. If *cmap* is *None* and *colors* is *None*, a
- default Colormap is used.
-
- *norm*: [ *None* | Normalize ]
- A :class:`matplotlib.colors.Normalize` instance for
- scaling data values to colors. If *norm* is *None* and
- *colors* is *None*, the default linear scaling is used.
-
- *levels* [level0, level1, ..., leveln]
- A list of floating point numbers indicating the level
- curves to draw, in increasing order; e.g., to draw just
- the zero contour pass ``levels=[0]``
-
- *origin*: [ *None* | 'upper' | 'lower' | 'image' ]
- If *None*, the first value of *Z* will correspond to the
- lower left corner, location (0,0). If 'image', the rc
- value for ``image.origin`` will be used.
-
- This keyword is not active if *X* and *Y* are specified in
- the call to contour.
-
- *extent*: [ *None* | (x0,x1,y0,y1) ]
-
- If *origin* is not *None*, then *extent* is interpreted as
- in :func:`matplotlib.pyplot.imshow`: it gives the outer
- pixel boundaries. In this case, the position of Z[0,0]
- is the center of the pixel, not a corner. If *origin* is
- *None*, then (*x0*, *y0*) is the position of Z[0,0], and
- (*x1*, *y1*) is the position of Z[-1,-1].
-
- This keyword is not active if *X* and *Y* are specified in
- the call to contour.
-
- *locator*: [ *None* | ticker.Locator subclass ]
- If *locator* is None, the default
- :class:`~matplotlib.ticker.MaxNLocator` is used. The
- locator is used to determine the contour levels if they
- are not given explicitly via the *V* argument.
-
- *extend*: [ 'neither' | 'both' | 'min' | 'max' ]
- Unless this is 'neither', contour levels are automatically
- added to one or both ends of the range so that all data
- are included. These added ranges are then mapped to the
- special colormap values which default to the ends of the
- colormap range, but can be set via
- :meth:`matplotlib.colors.Colormap.set_under` and
- :meth:`matplotlib.colors.Colormap.set_over` methods.
-
- *xunits*, *yunits*: [ *None* | registered units ]
- Override axis units by specifying an instance of a
- :class:`matplotlib.units.ConversionInterface`.
-
-
- tricontour-only keyword arguments:
-
- *linewidths*: [ *None* | number | tuple of numbers ]
- If *linewidths* is *None*, the default width in
- ``lines.linewidth`` in ``matplotlibrc`` is used.
-
- If a number, all levels will be plotted with this linewidth.
-
- If a tuple, different levels will be plotted with different
- linewidths in the order specified
-
- *linestyles*: [ *None* | 'solid' | 'dashed' | 'dashdot' | 'dotted' ]
- If *linestyles* is *None*, the 'solid' is used.
-
- *linestyles* can also be an iterable of the above strings
- specifying a set of linestyles to be used. If this
- iterable is shorter than the number of contour levels
- it will be repeated as necessary.
-
- If contour is using a monochrome colormap and the contour
- level is less than 0, then the linestyle specified
- in ``contour.negative_linestyle`` in ``matplotlibrc``
- will be used.
-
- tricontourf-only keyword arguments:
-
- *antialiased*: bool
- enable antialiasing
-
- Note: tricontourf fills intervals that are closed at the top; that
- is, for boundaries *z1* and *z2*, the filled region is::
-
- z1 < z <= z2
-
- There is one exception: if the lowest boundary coincides with
- the minimum value of the *z* array, then that minimum value
- will be included in the lowest interval.
- """
- if not ax._hold:
- ax.cla()
- kwargs['filled'] = False
- return TriContourSet(ax, *args, **kwargs)
-
-
-def tricontourf(ax, *args, **kwargs):
- if not ax._hold:
- ax.cla()
- kwargs['filled'] = True
- return TriContourSet(ax, *args, **kwargs)
-tricontourf.__doc__ = tricontour.__doc__
diff --git a/contrib/python/matplotlib/py2/matplotlib/tri/trifinder.py b/contrib/python/matplotlib/py2/matplotlib/tri/trifinder.py
deleted file mode 100644
index 08a07f854f..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/tri/trifinder.py
+++ /dev/null
@@ -1,96 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from matplotlib.tri import Triangulation
-import matplotlib._tri as _tri
-import numpy as np
-
-
-class TriFinder(object):
- """
- Abstract base class for classes used to find the triangles of a
- Triangulation in which (x,y) points lie.
-
- Rather than instantiate an object of a class derived from TriFinder, it is
- usually better to use the function
- :func:`matplotlib.tri.Triangulation.get_trifinder`.
-
- Derived classes implement __call__(x,y) where x,y are array_like point
- coordinates of the same shape.
- """
- def __init__(self, triangulation):
- if not isinstance(triangulation, Triangulation):
- raise ValueError('Expected a Triangulation object')
- self._triangulation = triangulation
-
-
-class TrapezoidMapTriFinder(TriFinder):
- """
- :class:`~matplotlib.tri.TriFinder` class implemented using the trapezoid
- map algorithm from the book "Computational Geometry, Algorithms and
- Applications", second edition, by M. de Berg, M. van Kreveld, M. Overmars
- and O. Schwarzkopf.
-
- The triangulation must be valid, i.e. it must not have duplicate points,
- triangles formed from colinear points, or overlapping triangles. The
- algorithm has some tolerance to triangles formed from colinear points, but
- this should not be relied upon.
- """
- def __init__(self, triangulation):
- TriFinder.__init__(self, triangulation)
- self._cpp_trifinder = _tri.TrapezoidMapTriFinder(
- triangulation.get_cpp_triangulation())
- self._initialize()
-
- def __call__(self, x, y):
- """
- Return an array containing the indices of the triangles in which the
- specified x,y points lie, or -1 for points that do not lie within a
- triangle.
-
- *x*, *y* are array_like x and y coordinates of the same shape and any
- number of dimensions.
-
- Returns integer array with the same shape and *x* and *y*.
- """
- x = np.asarray(x, dtype=np.float64)
- y = np.asarray(y, dtype=np.float64)
- if x.shape != y.shape:
- raise ValueError("x and y must be array-like with the same shape")
-
- # C++ does the heavy lifting, and expects 1D arrays.
- indices = (self._cpp_trifinder.find_many(x.ravel(), y.ravel())
- .reshape(x.shape))
- return indices
-
- def _get_tree_stats(self):
- """
- Return a python list containing the statistics about the node tree:
- 0: number of nodes (tree size)
- 1: number of unique nodes
- 2: number of trapezoids (tree leaf nodes)
- 3: number of unique trapezoids
- 4: maximum parent count (max number of times a node is repeated in
- tree)
- 5: maximum depth of tree (one more than the maximum number of
- comparisons needed to search through the tree)
- 6: mean of all trapezoid depths (one more than the average number
- of comparisons needed to search through the tree)
- """
- return self._cpp_trifinder.get_tree_stats()
-
- def _initialize(self):
- """
- Initialize the underlying C++ object. Can be called multiple times if,
- for example, the triangulation is modified.
- """
- self._cpp_trifinder.initialize()
-
- def _print_tree(self):
- """
- Print a text representation of the node tree, which is useful for
- debugging purposes.
- """
- self._cpp_trifinder.print_tree()
diff --git a/contrib/python/matplotlib/py2/matplotlib/tri/triinterpolate.py b/contrib/python/matplotlib/py2/matplotlib/tri/triinterpolate.py
deleted file mode 100644
index f3c6deb0c9..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/tri/triinterpolate.py
+++ /dev/null
@@ -1,1637 +0,0 @@
-"""
-Interpolation inside triangular grids.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange
-
-from matplotlib.tri import Triangulation
-from matplotlib.tri.trifinder import TriFinder
-from matplotlib.tri.tritools import TriAnalyzer
-import numpy as np
-import warnings
-
-__all__ = ('TriInterpolator', 'LinearTriInterpolator', 'CubicTriInterpolator')
-
-
-class TriInterpolator(object):
- """
- Abstract base class for classes used to perform interpolation on
- triangular grids.
-
- Derived classes implement the following methods:
-
- - ``__call__(x, y)`` ,
- where x, y are array_like point coordinates of the same shape, and
- that returns a masked array of the same shape containing the
- interpolated z-values.
-
- - ``gradient(x, y)`` ,
- where x, y are array_like point coordinates of the same
- shape, and that returns a list of 2 masked arrays of the same shape
- containing the 2 derivatives of the interpolator (derivatives of
- interpolated z values with respect to x and y).
-
- """
- def __init__(self, triangulation, z, trifinder=None):
- if not isinstance(triangulation, Triangulation):
- raise ValueError("Expected a Triangulation object")
- self._triangulation = triangulation
-
- self._z = np.asarray(z)
- if self._z.shape != self._triangulation.x.shape:
- raise ValueError("z array must have same length as triangulation x"
- " and y arrays")
-
- if trifinder is not None and not isinstance(trifinder, TriFinder):
- raise ValueError("Expected a TriFinder object")
- self._trifinder = trifinder or self._triangulation.get_trifinder()
-
- # Default scaling factors : 1.0 (= no scaling)
- # Scaling may be used for interpolations for which the order of
- # magnitude of x, y has an impact on the interpolant definition.
- # Please refer to :meth:`_interpolate_multikeys` for details.
- self._unit_x = 1.0
- self._unit_y = 1.0
-
- # Default triangle renumbering: None (= no renumbering)
- # Renumbering may be used to avoid unnecessary computations
- # if complex calculations are done inside the Interpolator.
- # Please refer to :meth:`_interpolate_multikeys` for details.
- self._tri_renum = None
-
- # __call__ and gradient docstrings are shared by all subclasses
- # (except, if needed, relevant additions).
- # However these methods are only implemented in subclasses to avoid
- # confusion in the documentation.
- _docstring__call__ = """
- Returns a masked array containing interpolated values at the specified
- x,y points.
-
- Parameters
- ----------
- x, y : array-like
- x and y coordinates of the same shape and any number of
- dimensions.
-
- Returns
- -------
- z : np.ma.array
- Masked array of the same shape as *x* and *y* ; values
- corresponding to (*x*, *y*) points outside of the triangulation
- are masked out.
-
- """
-
- _docstringgradient = """
- Returns a list of 2 masked arrays containing interpolated derivatives
- at the specified x,y points.
-
- Parameters
- ----------
- x, y : array-like
- x and y coordinates of the same shape and any number of
- dimensions.
-
- Returns
- -------
- dzdx, dzdy : np.ma.array
- 2 masked arrays of the same shape as *x* and *y* ; values
- corresponding to (x,y) points outside of the triangulation
- are masked out.
- The first returned array contains the values of
- :math:`\\frac{\\partial z}{\\partial x}` and the second those of
- :math:`\\frac{\\partial z}{\\partial y}`.
-
- """
-
- def _interpolate_multikeys(self, x, y, tri_index=None,
- return_keys=('z',)):
- """
- Versatile (private) method defined for all TriInterpolators.
-
- :meth:`_interpolate_multikeys` is a wrapper around method
- :meth:`_interpolate_single_key` (to be defined in the child
- subclasses).
- :meth:`_interpolate_single_key actually performs the interpolation,
- but only for 1-dimensional inputs and at valid locations (inside
- unmasked triangles of the triangulation).
-
- The purpose of :meth:`_interpolate_multikeys` is to implement the
- following common tasks needed in all subclasses implementations:
-
- - calculation of containing triangles
- - dealing with more than one interpolation request at the same
- location (e.g., if the 2 derivatives are requested, it is
- unnecessary to compute the containing triangles twice)
- - scaling according to self._unit_x, self._unit_y
- - dealing with points outside of the grid (with fill value np.nan)
- - dealing with multi-dimensionnal *x*, *y* arrays: flattening for
- :meth:`_interpolate_params` call and final reshaping.
-
- (Note that np.vectorize could do most of those things very well for
- you, but it does it by function evaluations over successive tuples of
- the input arrays. Therefore, this tends to be more time consuming than
- using optimized numpy functions - e.g., np.dot - which can be used
- easily on the flattened inputs, in the child-subclass methods
- :meth:`_interpolate_single_key`.)
-
- It is guaranteed that the calls to :meth:`_interpolate_single_key`
- will be done with flattened (1-d) array_like input parameters `x`, `y`
- and with flattened, valid `tri_index` arrays (no -1 index allowed).
-
- Parameters
- ----------
- x, y : array_like
- x and y coordinates indicating where interpolated values are
- requested.
- tri_index : integer array_like, optional
- Array of the containing triangle indices, same shape as
- *x* and *y*. Defaults to None. If None, these indices
- will be computed by a TriFinder instance.
- (Note: For point outside the grid, tri_index[ipt] shall be -1).
- return_keys : tuple of keys from {'z', 'dzdx', 'dzdy'}
- Defines the interpolation arrays to return, and in which order.
-
- Returns
- -------
- ret : list of arrays
- Each array-like contains the expected interpolated values in the
- order defined by *return_keys* parameter.
- """
- # Flattening and rescaling inputs arrays x, y
- # (initial shape is stored for output)
- x = np.asarray(x, dtype=np.float64)
- y = np.asarray(y, dtype=np.float64)
- sh_ret = x.shape
- if x.shape != y.shape:
- raise ValueError("x and y shall have same shapes."
- " Given: {0} and {1}".format(x.shape, y.shape))
- x = np.ravel(x)
- y = np.ravel(y)
- x_scaled = x/self._unit_x
- y_scaled = y/self._unit_y
- size_ret = np.size(x_scaled)
-
- # Computes & ravels the element indexes, extract the valid ones.
- if tri_index is None:
- tri_index = self._trifinder(x, y)
- else:
- if (tri_index.shape != sh_ret):
- raise ValueError(
- "tri_index array is provided and shall"
- " have same shape as x and y. Given: "
- "{0} and {1}".format(tri_index.shape, sh_ret))
- tri_index = np.ravel(tri_index)
-
- mask_in = (tri_index != -1)
- if self._tri_renum is None:
- valid_tri_index = tri_index[mask_in]
- else:
- valid_tri_index = self._tri_renum[tri_index[mask_in]]
- valid_x = x_scaled[mask_in]
- valid_y = y_scaled[mask_in]
-
- ret = []
- for return_key in return_keys:
- # Find the return index associated with the key.
- try:
- return_index = {'z': 0, 'dzdx': 1, 'dzdy': 2}[return_key]
- except KeyError:
- raise ValueError("return_keys items shall take values in"
- " {'z', 'dzdx', 'dzdy'}")
-
- # Sets the scale factor for f & df components
- scale = [1., 1./self._unit_x, 1./self._unit_y][return_index]
-
- # Computes the interpolation
- ret_loc = np.empty(size_ret, dtype=np.float64)
- ret_loc[~mask_in] = np.nan
- ret_loc[mask_in] = self._interpolate_single_key(
- return_key, valid_tri_index, valid_x, valid_y) * scale
- ret += [np.ma.masked_invalid(ret_loc.reshape(sh_ret), copy=False)]
-
- return ret
-
- def _interpolate_single_key(self, return_key, tri_index, x, y):
- """
- Performs the interpolation at points belonging to the triangulation
- (inside an unmasked triangles).
-
- Parameters
- ----------
- return_index : string key from {'z', 'dzdx', 'dzdy'}
- Identifies the requested values (z or its derivatives)
- tri_index : 1d integer array
- Valid triangle index (-1 prohibited)
- x, y : 1d arrays, same shape as `tri_index`
- Valid locations where interpolation is requested.
-
- Returns
- -------
- ret : 1-d array
- Returned array of the same size as *tri_index*
- """
- raise NotImplementedError("TriInterpolator subclasses" +
- "should implement _interpolate_single_key!")
-
-
-class LinearTriInterpolator(TriInterpolator):
- """
- A LinearTriInterpolator performs linear interpolation on a triangular grid.
-
- Each triangle is represented by a plane so that an interpolated value at
- point (x,y) lies on the plane of the triangle containing (x,y).
- Interpolated values are therefore continuous across the triangulation, but
- their first derivatives are discontinuous at edges between triangles.
-
- Parameters
- ----------
- triangulation : :class:`~matplotlib.tri.Triangulation` object
- The triangulation to interpolate over.
- z : array_like of shape (npoints,)
- Array of values, defined at grid points, to interpolate between.
- trifinder : :class:`~matplotlib.tri.TriFinder` object, optional
- If this is not specified, the Triangulation's default TriFinder will
- be used by calling
- :func:`matplotlib.tri.Triangulation.get_trifinder`.
-
- Methods
- -------
- `__call__` (x, y) : Returns interpolated values at x,y points
- `gradient` (x, y) : Returns interpolated derivatives at x,y points
-
- """
- def __init__(self, triangulation, z, trifinder=None):
- TriInterpolator.__init__(self, triangulation, z, trifinder)
-
- # Store plane coefficients for fast interpolation calculations.
- self._plane_coefficients = \
- self._triangulation.calculate_plane_coefficients(self._z)
-
- def __call__(self, x, y):
- return self._interpolate_multikeys(x, y, tri_index=None,
- return_keys=('z',))[0]
- __call__.__doc__ = TriInterpolator._docstring__call__
-
- def gradient(self, x, y):
- return self._interpolate_multikeys(x, y, tri_index=None,
- return_keys=('dzdx', 'dzdy'))
- gradient.__doc__ = TriInterpolator._docstringgradient
-
- def _interpolate_single_key(self, return_key, tri_index, x, y):
- if return_key == 'z':
- return (self._plane_coefficients[tri_index, 0]*x +
- self._plane_coefficients[tri_index, 1]*y +
- self._plane_coefficients[tri_index, 2])
- elif return_key == 'dzdx':
- return self._plane_coefficients[tri_index, 0]
- elif return_key == 'dzdy':
- return self._plane_coefficients[tri_index, 1]
- else:
- raise ValueError("Invalid return_key: " + return_key)
-
-
-class CubicTriInterpolator(TriInterpolator):
- """
- A CubicTriInterpolator performs cubic interpolation on triangular grids.
-
- In one-dimension - on a segment - a cubic interpolating function is
- defined by the values of the function and its derivative at both ends.
- This is almost the same in 2-d inside a triangle, except that the values
- of the function and its 2 derivatives have to be defined at each triangle
- node.
-
- The CubicTriInterpolator takes the value of the function at each node -
- provided by the user - and internally computes the value of the
- derivatives, resulting in a smooth interpolation.
- (As a special feature, the user can also impose the value of the
- derivatives at each node, but this is not supposed to be the common
- usage.)
-
- Parameters
- ----------
- triangulation : :class:`~matplotlib.tri.Triangulation` object
- The triangulation to interpolate over.
- z : array_like of shape (npoints,)
- Array of values, defined at grid points, to interpolate between.
- kind : {'min_E', 'geom', 'user'}, optional
- Choice of the smoothing algorithm, in order to compute
- the interpolant derivatives (defaults to 'min_E'):
-
- - if 'min_E': (default) The derivatives at each node is computed
- to minimize a bending energy.
- - if 'geom': The derivatives at each node is computed as a
- weighted average of relevant triangle normals. To be used for
- speed optimization (large grids).
- - if 'user': The user provides the argument `dz`, no computation
- is hence needed.
-
- trifinder : :class:`~matplotlib.tri.TriFinder` object, optional
- If not specified, the Triangulation's default TriFinder will
- be used by calling
- :func:`matplotlib.tri.Triangulation.get_trifinder`.
- dz : tuple of array_likes (dzdx, dzdy), optional
- Used only if *kind* ='user'. In this case *dz* must be provided as
- (dzdx, dzdy) where dzdx, dzdy are arrays of the same shape as *z* and
- are the interpolant first derivatives at the *triangulation* points.
-
- Methods
- -------
- `__call__` (x, y) : Returns interpolated values at x,y points
- `gradient` (x, y) : Returns interpolated derivatives at x,y points
-
- Notes
- -----
- This note is a bit technical and details the way a
- :class:`~matplotlib.tri.CubicTriInterpolator` computes a cubic
- interpolation.
-
- The interpolation is based on a Clough-Tocher subdivision scheme of
- the *triangulation* mesh (to make it clearer, each triangle of the
- grid will be divided in 3 child-triangles, and on each child triangle
- the interpolated function is a cubic polynomial of the 2 coordinates).
- This technique originates from FEM (Finite Element Method) analysis;
- the element used is a reduced Hsieh-Clough-Tocher (HCT)
- element. Its shape functions are described in [1]_.
- The assembled function is guaranteed to be C1-smooth, i.e. it is
- continuous and its first derivatives are also continuous (this
- is easy to show inside the triangles but is also true when crossing the
- edges).
-
- In the default case (*kind* ='min_E'), the interpolant minimizes a
- curvature energy on the functional space generated by the HCT element
- shape functions - with imposed values but arbitrary derivatives at each
- node. The minimized functional is the integral of the so-called total
- curvature (implementation based on an algorithm from [2]_ - PCG sparse
- solver):
-
- .. math::
-
- E(z) = \\ \\frac{1}{2} \\int_{\\Omega} \\left(
- \\left( \\frac{\\partial^2{z}}{\\partial{x}^2} \\right)^2 +
- \\left( \\frac{\\partial^2{z}}{\\partial{y}^2} \\right)^2 +
- 2\\left( \\frac{\\partial^2{z}}{\\partial{y}\\partial{x}}
- \\right)^2 \\right) dx\\,dy
-
- If the case *kind* ='geom' is chosen by the user, a simple geometric
- approximation is used (weighted average of the triangle normal
- vectors), which could improve speed on very large grids.
-
- References
- ----------
- .. [1] Michel Bernadou, Kamal Hassan, "Basis functions for general
- Hsieh-Clough-Tocher triangles, complete or reduced.",
- International Journal for Numerical Methods in Engineering,
- 17(5):784 - 789. 2.01.
- .. [2] C.T. Kelley, "Iterative Methods for Optimization".
-
- """
- def __init__(self, triangulation, z, kind='min_E', trifinder=None,
- dz=None):
- TriInterpolator.__init__(self, triangulation, z, trifinder)
-
- # Loads the underlying c++ _triangulation.
- # (During loading, reordering of triangulation._triangles may occur so
- # that all final triangles are now anti-clockwise)
- self._triangulation.get_cpp_triangulation()
-
- # To build the stiffness matrix and avoid zero-energy spurious modes
- # we will only store internally the valid (unmasked) triangles and
- # the necessary (used) points coordinates.
- # 2 renumbering tables need to be computed and stored:
- # - a triangle renum table in order to translate the result from a
- # TriFinder instance into the internal stored triangle number.
- # - a node renum table to overwrite the self._z values into the new
- # (used) node numbering.
- tri_analyzer = TriAnalyzer(self._triangulation)
- (compressed_triangles, compressed_x, compressed_y, tri_renum,
- node_renum) = tri_analyzer._get_compressed_triangulation(True, True)
- self._triangles = compressed_triangles
- self._tri_renum = tri_renum
- # Taking into account the node renumbering in self._z:
- node_mask = (node_renum == -1)
- self._z[node_renum[~node_mask]] = self._z
- self._z = self._z[~node_mask]
-
- # Computing scale factors
- self._unit_x = np.ptp(compressed_x)
- self._unit_y = np.ptp(compressed_y)
- self._pts = np.column_stack([compressed_x / self._unit_x,
- compressed_y / self._unit_y])
- # Computing triangle points
- self._tris_pts = self._pts[self._triangles]
- # Computing eccentricities
- self._eccs = self._compute_tri_eccentricities(self._tris_pts)
- # Computing dof estimations for HCT triangle shape function
- self._dof = self._compute_dof(kind, dz=dz)
- # Loading HCT element
- self._ReferenceElement = _ReducedHCT_Element()
-
- def __call__(self, x, y):
- return self._interpolate_multikeys(x, y, tri_index=None,
- return_keys=('z',))[0]
- __call__.__doc__ = TriInterpolator._docstring__call__
-
- def gradient(self, x, y):
- return self._interpolate_multikeys(x, y, tri_index=None,
- return_keys=('dzdx', 'dzdy'))
- gradient.__doc__ = TriInterpolator._docstringgradient
-
- def _interpolate_single_key(self, return_key, tri_index, x, y):
- tris_pts = self._tris_pts[tri_index]
- alpha = self._get_alpha_vec(x, y, tris_pts)
- ecc = self._eccs[tri_index]
- dof = np.expand_dims(self._dof[tri_index], axis=1)
- if return_key == 'z':
- return self._ReferenceElement.get_function_values(
- alpha, ecc, dof)
- elif return_key in ['dzdx', 'dzdy']:
- J = self._get_jacobian(tris_pts)
- dzdx = self._ReferenceElement.get_function_derivatives(
- alpha, J, ecc, dof)
- if return_key == 'dzdx':
- return dzdx[:, 0, 0]
- else:
- return dzdx[:, 1, 0]
- else:
- raise ValueError("Invalid return_key: " + return_key)
-
- def _compute_dof(self, kind, dz=None):
- """
- Computes and returns nodal dofs according to kind
-
- Parameters
- ----------
- kind: {'min_E', 'geom', 'user'}
- Choice of the _DOF_estimator subclass to perform the gradient
- estimation.
- dz: tuple of array_likes (dzdx, dzdy), optional
- Used only if *kind=user ; in this case passed to the
- :class:`_DOF_estimator_user`.
-
- Returns
- -------
- dof : array_like, shape (npts,2)
- Estimation of the gradient at triangulation nodes (stored as
- degree of freedoms of reduced-HCT triangle elements).
- """
- if kind == 'user':
- if dz is None:
- raise ValueError("For a CubicTriInterpolator with "
- "*kind*='user', a valid *dz* "
- "argument is expected.")
- TE = _DOF_estimator_user(self, dz=dz)
- elif kind == 'geom':
- TE = _DOF_estimator_geom(self)
- elif kind == 'min_E':
- TE = _DOF_estimator_min_E(self)
- else:
- raise ValueError("CubicTriInterpolator *kind* proposed: {0} ; "
- "should be one of: "
- "'user', 'geom', 'min_E'".format(kind))
- return TE.compute_dof_from_df()
-
- @staticmethod
- def _get_alpha_vec(x, y, tris_pts):
- """
- Fast (vectorized) function to compute barycentric coordinates alpha.
-
- Parameters
- ----------
- x, y : array-like of dim 1 (shape (nx,))
- Coordinates of the points whose points barycentric
- coordinates are requested
- tris_pts : array like of dim 3 (shape: (nx,3,2))
- Coordinates of the containing triangles apexes.
-
- Returns
- -------
- alpha : array of dim 2 (shape (nx,3))
- Barycentric coordinates of the points inside the containing
- triangles.
- """
- ndim = tris_pts.ndim-2
-
- a = tris_pts[:, 1, :] - tris_pts[:, 0, :]
- b = tris_pts[:, 2, :] - tris_pts[:, 0, :]
- abT = np.concatenate([np.expand_dims(a, ndim+1),
- np.expand_dims(b, ndim+1)], ndim+1)
- ab = _transpose_vectorized(abT)
- x = np.expand_dims(x, ndim)
- y = np.expand_dims(y, ndim)
- OM = np.concatenate([x, y], ndim) - tris_pts[:, 0, :]
-
- metric = _prod_vectorized(ab, abT)
- # Here we try to deal with the colinear cases.
- # metric_inv is in this case set to the Moore-Penrose pseudo-inverse
- # meaning that we will still return a set of valid barycentric
- # coordinates.
- metric_inv = _pseudo_inv22sym_vectorized(metric)
- Covar = _prod_vectorized(ab, _transpose_vectorized(
- np.expand_dims(OM, ndim)))
- ksi = _prod_vectorized(metric_inv, Covar)
- alpha = _to_matrix_vectorized([
- [1-ksi[:, 0, 0]-ksi[:, 1, 0]], [ksi[:, 0, 0]], [ksi[:, 1, 0]]])
- return alpha
-
- @staticmethod
- def _get_jacobian(tris_pts):
- """
- Fast (vectorized) function to compute triangle jacobian matrix.
-
- Parameters
- ----------
- tris_pts : array like of dim 3 (shape: (nx,3,2))
- Coordinates of the containing triangles apexes.
-
- Returns
- -------
- J : array of dim 3 (shape (nx,2,2))
- Barycentric coordinates of the points inside the containing
- triangles.
- J[itri,:,:] is the jacobian matrix at apex 0 of the triangle
- itri, so that the following (matrix) relationship holds:
- [dz/dksi] = [J] x [dz/dx]
- with x: global coordinates
- ksi: element parametric coordinates in triangle first apex
- local basis.
- """
- a = np.array(tris_pts[:, 1, :] - tris_pts[:, 0, :])
- b = np.array(tris_pts[:, 2, :] - tris_pts[:, 0, :])
- J = _to_matrix_vectorized([[a[:, 0], a[:, 1]],
- [b[:, 0], b[:, 1]]])
- return J
-
- @staticmethod
- def _compute_tri_eccentricities(tris_pts):
- """
- Computes triangle eccentricities
-
- Parameters
- ----------
- tris_pts : array like of dim 3 (shape: (nx,3,2))
- Coordinates of the triangles apexes.
-
- Returns
- -------
- ecc : array like of dim 2 (shape: (nx,3))
- The so-called eccentricity parameters [1] needed for
- HCT triangular element.
- """
- a = np.expand_dims(tris_pts[:, 2, :] - tris_pts[:, 1, :], axis=2)
- b = np.expand_dims(tris_pts[:, 0, :] - tris_pts[:, 2, :], axis=2)
- c = np.expand_dims(tris_pts[:, 1, :] - tris_pts[:, 0, :], axis=2)
- # Do not use np.squeeze, this is dangerous if only one triangle
- # in the triangulation...
- dot_a = _prod_vectorized(_transpose_vectorized(a), a)[:, 0, 0]
- dot_b = _prod_vectorized(_transpose_vectorized(b), b)[:, 0, 0]
- dot_c = _prod_vectorized(_transpose_vectorized(c), c)[:, 0, 0]
- # Note that this line will raise a warning for dot_a, dot_b or dot_c
- # zeros, but we choose not to support triangles with duplicate points.
- return _to_matrix_vectorized([[(dot_c-dot_b) / dot_a],
- [(dot_a-dot_c) / dot_b],
- [(dot_b-dot_a) / dot_c]])
-
-
-# FEM element used for interpolation and for solving minimisation
-# problem (Reduced HCT element)
-class _ReducedHCT_Element():
- """
- Implementation of reduced HCT triangular element with explicit shape
- functions.
-
- Computes z, dz, d2z and the element stiffness matrix for bending energy:
- E(f) = integral( (d2z/dx2 + d2z/dy2)**2 dA)
-
- *** Reference for the shape functions: ***
- [1] Basis functions for general Hsieh-Clough-Tocher _triangles, complete or
- reduced.
- Michel Bernadou, Kamal Hassan
- International Journal for Numerical Methods in Engineering.
- 17(5):784 - 789. 2.01
-
- *** Element description: ***
- 9 dofs: z and dz given at 3 apex
- C1 (conform)
-
- """
- # 1) Loads matrices to generate shape functions as a function of
- # triangle eccentricities - based on [1] p.11 '''
- M = np.array([
- [ 0.00, 0.00, 0.00, 4.50, 4.50, 0.00, 0.00, 0.00, 0.00, 0.00],
- [-0.25, 0.00, 0.00, 0.50, 1.25, 0.00, 0.00, 0.00, 0.00, 0.00],
- [-0.25, 0.00, 0.00, 1.25, 0.50, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.50, 1.00, 0.00, -1.50, 0.00, 3.00, 3.00, 0.00, 0.00, 3.00],
- [ 0.00, 0.00, 0.00, -0.25, 0.25, 0.00, 1.00, 0.00, 0.00, 0.50],
- [ 0.25, 0.00, 0.00, -0.50, -0.25, 1.00, 0.00, 0.00, 0.00, 1.00],
- [ 0.50, 0.00, 1.00, 0.00, -1.50, 0.00, 0.00, 3.00, 3.00, 3.00],
- [ 0.25, 0.00, 0.00, -0.25, -0.50, 0.00, 0.00, 0.00, 1.00, 1.00],
- [ 0.00, 0.00, 0.00, 0.25, -0.25, 0.00, 0.00, 1.00, 0.00, 0.50]])
- M0 = np.array([
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [-1.00, 0.00, 0.00, 1.50, 1.50, 0.00, 0.00, 0.00, 0.00, -3.00],
- [-0.50, 0.00, 0.00, 0.75, 0.75, 0.00, 0.00, 0.00, 0.00, -1.50],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 1.00, 0.00, 0.00, -1.50, -1.50, 0.00, 0.00, 0.00, 0.00, 3.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.50, 0.00, 0.00, -0.75, -0.75, 0.00, 0.00, 0.00, 0.00, 1.50]])
- M1 = np.array([
- [-0.50, 0.00, 0.00, 1.50, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [-0.25, 0.00, 0.00, 0.75, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.50, 0.00, 0.00, -1.50, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.25, 0.00, 0.00, -0.75, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00]])
- M2 = np.array([
- [ 0.50, 0.00, 0.00, 0.00, -1.50, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.25, 0.00, 0.00, 0.00, -0.75, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [-0.50, 0.00, 0.00, 0.00, 1.50, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [-0.25, 0.00, 0.00, 0.00, 0.75, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00]])
-
- # 2) Loads matrices to rotate components of gradient & Hessian
- # vectors in the reference basis of triangle first apex (a0)
- rotate_dV = np.array([[ 1., 0.], [ 0., 1.],
- [ 0., 1.], [-1., -1.],
- [-1., -1.], [ 1., 0.]])
-
- rotate_d2V = np.array([[1., 0., 0.], [0., 1., 0.], [ 0., 0., 1.],
- [0., 1., 0.], [1., 1., 1.], [ 0., -2., -1.],
- [1., 1., 1.], [1., 0., 0.], [-2., 0., -1.]])
-
- # 3) Loads Gauss points & weights on the 3 sub-_triangles for P2
- # exact integral - 3 points on each subtriangles.
- # NOTE: as the 2nd derivative is discontinuous , we really need those 9
- # points!
- n_gauss = 9
- gauss_pts = np.array([[13./18., 4./18., 1./18.],
- [ 4./18., 13./18., 1./18.],
- [ 7./18., 7./18., 4./18.],
- [ 1./18., 13./18., 4./18.],
- [ 1./18., 4./18., 13./18.],
- [ 4./18., 7./18., 7./18.],
- [ 4./18., 1./18., 13./18.],
- [13./18., 1./18., 4./18.],
- [ 7./18., 4./18., 7./18.]], dtype=np.float64)
- gauss_w = np.ones([9], dtype=np.float64) / 9.
-
- # 4) Stiffness matrix for curvature energy
- E = np.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 2.]])
-
- # 5) Loads the matrix to compute DOF_rot from tri_J at apex 0
- J0_to_J1 = np.array([[-1., 1.], [-1., 0.]])
- J0_to_J2 = np.array([[ 0., -1.], [ 1., -1.]])
-
- def get_function_values(self, alpha, ecc, dofs):
- """
- Parameters
- ----------
- alpha : is a (N x 3 x 1) array (array of column-matrices) of
- barycentric coordinates,
- ecc : is a (N x 3 x 1) array (array of column-matrices) of triangle
- eccentricities,
- dofs : is a (N x 1 x 9) arrays (arrays of row-matrices) of computed
- degrees of freedom.
-
- Returns
- -------
- Returns the N-array of interpolated function values.
- """
- subtri = np.argmin(alpha, axis=1)[:, 0]
- ksi = _roll_vectorized(alpha, -subtri, axis=0)
- E = _roll_vectorized(ecc, -subtri, axis=0)
- x = ksi[:, 0, 0]
- y = ksi[:, 1, 0]
- z = ksi[:, 2, 0]
- x_sq = x*x
- y_sq = y*y
- z_sq = z*z
- V = _to_matrix_vectorized([
- [x_sq*x], [y_sq*y], [z_sq*z], [x_sq*z], [x_sq*y], [y_sq*x],
- [y_sq*z], [z_sq*y], [z_sq*x], [x*y*z]])
- prod = _prod_vectorized(self.M, V)
- prod += _scalar_vectorized(E[:, 0, 0],
- _prod_vectorized(self.M0, V))
- prod += _scalar_vectorized(E[:, 1, 0],
- _prod_vectorized(self.M1, V))
- prod += _scalar_vectorized(E[:, 2, 0],
- _prod_vectorized(self.M2, V))
- s = _roll_vectorized(prod, 3*subtri, axis=0)
- return _prod_vectorized(dofs, s)[:, 0, 0]
-
- def get_function_derivatives(self, alpha, J, ecc, dofs):
- """
- Parameters
- ----------
- *alpha* is a (N x 3 x 1) array (array of column-matrices of
- barycentric coordinates)
- *J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at
- triangle first apex)
- *ecc* is a (N x 3 x 1) array (array of column-matrices of triangle
- eccentricities)
- *dofs* is a (N x 1 x 9) arrays (arrays of row-matrices) of computed
- degrees of freedom.
-
- Returns
- -------
- Returns the values of interpolated function derivatives [dz/dx, dz/dy]
- in global coordinates at locations alpha, as a column-matrices of
- shape (N x 2 x 1).
- """
- subtri = np.argmin(alpha, axis=1)[:, 0]
- ksi = _roll_vectorized(alpha, -subtri, axis=0)
- E = _roll_vectorized(ecc, -subtri, axis=0)
- x = ksi[:, 0, 0]
- y = ksi[:, 1, 0]
- z = ksi[:, 2, 0]
- x_sq = x*x
- y_sq = y*y
- z_sq = z*z
- dV = _to_matrix_vectorized([
- [ -3.*x_sq, -3.*x_sq],
- [ 3.*y_sq, 0.],
- [ 0., 3.*z_sq],
- [ -2.*x*z, -2.*x*z+x_sq],
- [-2.*x*y+x_sq, -2.*x*y],
- [ 2.*x*y-y_sq, -y_sq],
- [ 2.*y*z, y_sq],
- [ z_sq, 2.*y*z],
- [ -z_sq, 2.*x*z-z_sq],
- [ x*z-y*z, x*y-y*z]])
- # Puts back dV in first apex basis
- dV = _prod_vectorized(dV, _extract_submatrices(
- self.rotate_dV, subtri, block_size=2, axis=0))
-
- prod = _prod_vectorized(self.M, dV)
- prod += _scalar_vectorized(E[:, 0, 0],
- _prod_vectorized(self.M0, dV))
- prod += _scalar_vectorized(E[:, 1, 0],
- _prod_vectorized(self.M1, dV))
- prod += _scalar_vectorized(E[:, 2, 0],
- _prod_vectorized(self.M2, dV))
- dsdksi = _roll_vectorized(prod, 3*subtri, axis=0)
- dfdksi = _prod_vectorized(dofs, dsdksi)
- # In global coordinates:
- # Here we try to deal with the simplest colinear cases, returning a
- # null matrix.
- J_inv = _safe_inv22_vectorized(J)
- dfdx = _prod_vectorized(J_inv, _transpose_vectorized(dfdksi))
- return dfdx
-
- def get_function_hessians(self, alpha, J, ecc, dofs):
- """
- Parameters
- ----------
- *alpha* is a (N x 3 x 1) array (array of column-matrices) of
- barycentric coordinates
- *J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at
- triangle first apex)
- *ecc* is a (N x 3 x 1) array (array of column-matrices) of triangle
- eccentricities
- *dofs* is a (N x 1 x 9) arrays (arrays of row-matrices) of computed
- degrees of freedom.
-
- Returns
- -------
- Returns the values of interpolated function 2nd-derivatives
- [d2z/dx2, d2z/dy2, d2z/dxdy] in global coordinates at locations alpha,
- as a column-matrices of shape (N x 3 x 1).
- """
- d2sdksi2 = self.get_d2Sidksij2(alpha, ecc)
- d2fdksi2 = _prod_vectorized(dofs, d2sdksi2)
- H_rot = self.get_Hrot_from_J(J)
- d2fdx2 = _prod_vectorized(d2fdksi2, H_rot)
- return _transpose_vectorized(d2fdx2)
-
- def get_d2Sidksij2(self, alpha, ecc):
- """
- Parameters
- ----------
- *alpha* is a (N x 3 x 1) array (array of column-matrices) of
- barycentric coordinates
- *ecc* is a (N x 3 x 1) array (array of column-matrices) of triangle
- eccentricities
-
- Returns
- -------
- Returns the arrays d2sdksi2 (N x 3 x 1) Hessian of shape functions
- expressed in covariante coordinates in first apex basis.
- """
- subtri = np.argmin(alpha, axis=1)[:, 0]
- ksi = _roll_vectorized(alpha, -subtri, axis=0)
- E = _roll_vectorized(ecc, -subtri, axis=0)
- x = ksi[:, 0, 0]
- y = ksi[:, 1, 0]
- z = ksi[:, 2, 0]
- d2V = _to_matrix_vectorized([
- [ 6.*x, 6.*x, 6.*x],
- [ 6.*y, 0., 0.],
- [ 0., 6.*z, 0.],
- [ 2.*z, 2.*z-4.*x, 2.*z-2.*x],
- [2.*y-4.*x, 2.*y, 2.*y-2.*x],
- [2.*x-4.*y, 0., -2.*y],
- [ 2.*z, 0., 2.*y],
- [ 0., 2.*y, 2.*z],
- [ 0., 2.*x-4.*z, -2.*z],
- [ -2.*z, -2.*y, x-y-z]])
- # Puts back d2V in first apex basis
- d2V = _prod_vectorized(d2V, _extract_submatrices(
- self.rotate_d2V, subtri, block_size=3, axis=0))
- prod = _prod_vectorized(self.M, d2V)
- prod += _scalar_vectorized(E[:, 0, 0],
- _prod_vectorized(self.M0, d2V))
- prod += _scalar_vectorized(E[:, 1, 0],
- _prod_vectorized(self.M1, d2V))
- prod += _scalar_vectorized(E[:, 2, 0],
- _prod_vectorized(self.M2, d2V))
- d2sdksi2 = _roll_vectorized(prod, 3*subtri, axis=0)
- return d2sdksi2
-
- def get_bending_matrices(self, J, ecc):
- """
- Parameters
- ----------
- *J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at
- triangle first apex)
- *ecc* is a (N x 3 x 1) array (array of column-matrices) of triangle
- eccentricities
-
- Returns
- -------
- Returns the element K matrices for bending energy expressed in
- GLOBAL nodal coordinates.
- K_ij = integral [ (d2zi/dx2 + d2zi/dy2) * (d2zj/dx2 + d2zj/dy2) dA]
- tri_J is needed to rotate dofs from local basis to global basis
- """
- n = np.size(ecc, 0)
-
- # 1) matrix to rotate dofs in global coordinates
- J1 = _prod_vectorized(self.J0_to_J1, J)
- J2 = _prod_vectorized(self.J0_to_J2, J)
- DOF_rot = np.zeros([n, 9, 9], dtype=np.float64)
- DOF_rot[:, 0, 0] = 1
- DOF_rot[:, 3, 3] = 1
- DOF_rot[:, 6, 6] = 1
- DOF_rot[:, 1:3, 1:3] = J
- DOF_rot[:, 4:6, 4:6] = J1
- DOF_rot[:, 7:9, 7:9] = J2
-
- # 2) matrix to rotate Hessian in global coordinates.
- H_rot, area = self.get_Hrot_from_J(J, return_area=True)
-
- # 3) Computes stiffness matrix
- # Gauss quadrature.
- K = np.zeros([n, 9, 9], dtype=np.float64)
- weights = self.gauss_w
- pts = self.gauss_pts
- for igauss in range(self.n_gauss):
- alpha = np.tile(pts[igauss, :], n).reshape(n, 3)
- alpha = np.expand_dims(alpha, 2)
- weight = weights[igauss]
- d2Skdksi2 = self.get_d2Sidksij2(alpha, ecc)
- d2Skdx2 = _prod_vectorized(d2Skdksi2, H_rot)
- K += weight * _prod_vectorized(_prod_vectorized(d2Skdx2, self.E),
- _transpose_vectorized(d2Skdx2))
-
- # 4) With nodal (not elem) dofs
- K = _prod_vectorized(_prod_vectorized(_transpose_vectorized(DOF_rot),
- K), DOF_rot)
-
- # 5) Need the area to compute total element energy
- return _scalar_vectorized(area, K)
-
- def get_Hrot_from_J(self, J, return_area=False):
- """
- Parameters
- ----------
- *J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at
- triangle first apex)
-
- Returns
- -------
- Returns H_rot used to rotate Hessian from local basis of first apex,
- to global coordinates.
- if *return_area* is True, returns also the triangle area (0.5*det(J))
- """
- # Here we try to deal with the simplest colinear cases ; a null
- # energy and area is imposed.
- J_inv = _safe_inv22_vectorized(J)
- Ji00 = J_inv[:, 0, 0]
- Ji11 = J_inv[:, 1, 1]
- Ji10 = J_inv[:, 1, 0]
- Ji01 = J_inv[:, 0, 1]
- H_rot = _to_matrix_vectorized([
- [Ji00*Ji00, Ji10*Ji10, Ji00*Ji10],
- [Ji01*Ji01, Ji11*Ji11, Ji01*Ji11],
- [2*Ji00*Ji01, 2*Ji11*Ji10, Ji00*Ji11+Ji10*Ji01]])
- if not return_area:
- return H_rot
- else:
- area = 0.5 * (J[:, 0, 0]*J[:, 1, 1] - J[:, 0, 1]*J[:, 1, 0])
- return H_rot, area
-
- def get_Kff_and_Ff(self, J, ecc, triangles, Uc):
- """
- Builds K and F for the following elliptic formulation:
- minimization of curvature energy with value of function at node
- imposed and derivatives 'free'.
- Builds the global Kff matrix in cco format.
- Builds the full Ff vec Ff = - Kfc x Uc
-
- Parameters
- ----------
- *J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at
- triangle first apex)
- *ecc* is a (N x 3 x 1) array (array of column-matrices) of triangle
- eccentricities
- *triangles* is a (N x 3) array of nodes indexes.
- *Uc* is (N x 3) array of imposed displacements at nodes
-
- Returns
- -------
- (Kff_rows, Kff_cols, Kff_vals) Kff matrix in coo format - Duplicate
- (row, col) entries must be summed.
- Ff: force vector - dim npts * 3
- """
- ntri = np.size(ecc, 0)
- vec_range = np.arange(ntri, dtype=np.int32)
- c_indices = -np.ones(ntri, dtype=np.int32) # for unused dofs, -1
- f_dof = [1, 2, 4, 5, 7, 8]
- c_dof = [0, 3, 6]
-
- # vals, rows and cols indices in global dof numbering
- f_dof_indices = _to_matrix_vectorized([[
- c_indices, triangles[:, 0]*2, triangles[:, 0]*2+1,
- c_indices, triangles[:, 1]*2, triangles[:, 1]*2+1,
- c_indices, triangles[:, 2]*2, triangles[:, 2]*2+1]])
-
- expand_indices = np.ones([ntri, 9, 1], dtype=np.int32)
- f_row_indices = _prod_vectorized(_transpose_vectorized(f_dof_indices),
- _transpose_vectorized(expand_indices))
- f_col_indices = _prod_vectorized(expand_indices, f_dof_indices)
- K_elem = self.get_bending_matrices(J, ecc)
-
- # Extracting sub-matrices
- # Explanation & notations:
- # * Subscript f denotes 'free' degrees of freedom (i.e. dz/dx, dz/dx)
- # * Subscript c denotes 'condensated' (imposed) degrees of freedom
- # (i.e. z at all nodes)
- # * F = [Ff, Fc] is the force vector
- # * U = [Uf, Uc] is the imposed dof vector
- # [ Kff Kfc ]
- # * K = [ ] is the laplacian stiffness matrix
- # [ Kcf Kff ]
- # * As F = K x U one gets straightforwardly: Ff = - Kfc x Uc
-
- # Computing Kff stiffness matrix in sparse coo format
- Kff_vals = np.ravel(K_elem[np.ix_(vec_range, f_dof, f_dof)])
- Kff_rows = np.ravel(f_row_indices[np.ix_(vec_range, f_dof, f_dof)])
- Kff_cols = np.ravel(f_col_indices[np.ix_(vec_range, f_dof, f_dof)])
-
- # Computing Ff force vector in sparse coo format
- Kfc_elem = K_elem[np.ix_(vec_range, f_dof, c_dof)]
- Uc_elem = np.expand_dims(Uc, axis=2)
- Ff_elem = - _prod_vectorized(Kfc_elem, Uc_elem)[:, :, 0]
- Ff_indices = f_dof_indices[np.ix_(vec_range, [0], f_dof)][:, 0, :]
-
- # Extracting Ff force vector in dense format
- # We have to sum duplicate indices - using bincount
- Ff = np.bincount(np.ravel(Ff_indices), weights=np.ravel(Ff_elem))
- return Kff_rows, Kff_cols, Kff_vals, Ff
-
-
-# :class:_DOF_estimator, _DOF_estimator_user, _DOF_estimator_geom,
-# _DOF_estimator_min_E
-# Private classes used to compute the degree of freedom of each triangular
-# element for the TriCubicInterpolator.
-class _DOF_estimator():
- """
- Abstract base class for classes used to perform estimation of a function
- first derivatives, and deduce the dofs for a CubicTriInterpolator using a
- reduced HCT element formulation.
- Derived classes implement compute_df(self,**kwargs), returning
- np.vstack([dfx,dfy]).T where : dfx, dfy are the estimation of the 2
- gradient coordinates.
- """
- def __init__(self, interpolator, **kwargs):
- if not isinstance(interpolator, CubicTriInterpolator):
- raise ValueError("Expected a CubicTriInterpolator object")
- self._pts = interpolator._pts
- self._tris_pts = interpolator._tris_pts
- self.z = interpolator._z
- self._triangles = interpolator._triangles
- (self._unit_x, self._unit_y) = (interpolator._unit_x,
- interpolator._unit_y)
- self.dz = self.compute_dz(**kwargs)
- self.compute_dof_from_df()
-
- def compute_dz(self, **kwargs):
- raise NotImplementedError
-
- def compute_dof_from_df(self):
- """
- Computes reduced-HCT elements degrees of freedom, knowing the
- gradient.
- """
- J = CubicTriInterpolator._get_jacobian(self._tris_pts)
- tri_z = self.z[self._triangles]
- tri_dz = self.dz[self._triangles]
- tri_dof = self.get_dof_vec(tri_z, tri_dz, J)
- return tri_dof
-
- @staticmethod
- def get_dof_vec(tri_z, tri_dz, J):
- """
- Computes the dof vector of a triangle, knowing the value of f, df and
- of the local Jacobian at each node.
-
- *tri_z*: array of shape (3,) of f nodal values
- *tri_dz*: array of shape (3,2) of df/dx, df/dy nodal values
- *J*: Jacobian matrix in local basis of apex 0
-
- Returns dof array of shape (9,) so that for each apex iapex:
- dof[iapex*3+0] = f(Ai)
- dof[iapex*3+1] = df(Ai).(AiAi+)
- dof[iapex*3+2] = df(Ai).(AiAi-)]
- """
- npt = tri_z.shape[0]
- dof = np.zeros([npt, 9], dtype=np.float64)
- J1 = _prod_vectorized(_ReducedHCT_Element.J0_to_J1, J)
- J2 = _prod_vectorized(_ReducedHCT_Element.J0_to_J2, J)
-
- col0 = _prod_vectorized(J, np.expand_dims(tri_dz[:, 0, :], axis=2))
- col1 = _prod_vectorized(J1, np.expand_dims(tri_dz[:, 1, :], axis=2))
- col2 = _prod_vectorized(J2, np.expand_dims(tri_dz[:, 2, :], axis=2))
-
- dfdksi = _to_matrix_vectorized([
- [col0[:, 0, 0], col1[:, 0, 0], col2[:, 0, 0]],
- [col0[:, 1, 0], col1[:, 1, 0], col2[:, 1, 0]]])
- dof[:, 0:7:3] = tri_z
- dof[:, 1:8:3] = dfdksi[:, 0]
- dof[:, 2:9:3] = dfdksi[:, 1]
- return dof
-
-
-class _DOF_estimator_user(_DOF_estimator):
- """ dz is imposed by user / Accounts for scaling if any """
- def compute_dz(self, dz):
- (dzdx, dzdy) = dz
- dzdx = dzdx * self._unit_x
- dzdy = dzdy * self._unit_y
- return np.vstack([dzdx, dzdy]).T
-
-
-class _DOF_estimator_geom(_DOF_estimator):
- """ Fast 'geometric' approximation, recommended for large arrays. """
- def compute_dz(self):
- """
- self.df is computed as weighted average of _triangles sharing a common
- node. On each triangle itri f is first assumed linear (= ~f), which
- allows to compute d~f[itri]
- Then the following approximation of df nodal values is then proposed:
- f[ipt] = SUM ( w[itri] x d~f[itri] , for itri sharing apex ipt)
- The weighted coeff. w[itri] are proportional to the angle of the
- triangle itri at apex ipt
- """
- el_geom_w = self.compute_geom_weights()
- el_geom_grad = self.compute_geom_grads()
-
- # Sum of weights coeffs
- w_node_sum = np.bincount(np.ravel(self._triangles),
- weights=np.ravel(el_geom_w))
-
- # Sum of weighted df = (dfx, dfy)
- dfx_el_w = np.empty_like(el_geom_w)
- dfy_el_w = np.empty_like(el_geom_w)
- for iapex in range(3):
- dfx_el_w[:, iapex] = el_geom_w[:, iapex]*el_geom_grad[:, 0]
- dfy_el_w[:, iapex] = el_geom_w[:, iapex]*el_geom_grad[:, 1]
- dfx_node_sum = np.bincount(np.ravel(self._triangles),
- weights=np.ravel(dfx_el_w))
- dfy_node_sum = np.bincount(np.ravel(self._triangles),
- weights=np.ravel(dfy_el_w))
-
- # Estimation of df
- dfx_estim = dfx_node_sum/w_node_sum
- dfy_estim = dfy_node_sum/w_node_sum
- return np.vstack([dfx_estim, dfy_estim]).T
-
- def compute_geom_weights(self):
- """
- Builds the (nelems x 3) weights coeffs of _triangles angles,
- renormalized so that np.sum(weights, axis=1) == np.ones(nelems)
- """
- weights = np.zeros([np.size(self._triangles, 0), 3])
- tris_pts = self._tris_pts
- for ipt in range(3):
- p0 = tris_pts[:, (ipt) % 3, :]
- p1 = tris_pts[:, (ipt+1) % 3, :]
- p2 = tris_pts[:, (ipt-1) % 3, :]
- alpha1 = np.arctan2(p1[:, 1]-p0[:, 1], p1[:, 0]-p0[:, 0])
- alpha2 = np.arctan2(p2[:, 1]-p0[:, 1], p2[:, 0]-p0[:, 0])
- # In the below formula we could take modulo 2. but
- # modulo 1. is safer regarding round-off errors (flat triangles).
- angle = np.abs(np.mod((alpha2-alpha1) / np.pi, 1.))
- # Weight proportional to angle up np.pi/2 ; null weight for
- # degenerated cases 0. and np.pi (Note that `angle` is normalized
- # by np.pi)
- weights[:, ipt] = 0.5 - np.abs(angle-0.5)
- return weights
-
- def compute_geom_grads(self):
- """
- Compute the (global) gradient component of f assumed linear (~f).
- returns array df of shape (nelems,2)
- df[ielem].dM[ielem] = dz[ielem] i.e. df = dz x dM = dM.T^-1 x dz
- """
- tris_pts = self._tris_pts
- tris_f = self.z[self._triangles]
-
- dM1 = tris_pts[:, 1, :] - tris_pts[:, 0, :]
- dM2 = tris_pts[:, 2, :] - tris_pts[:, 0, :]
- dM = np.dstack([dM1, dM2])
- # Here we try to deal with the simplest colinear cases: a null
- # gradient is assumed in this case.
- dM_inv = _safe_inv22_vectorized(dM)
-
- dZ1 = tris_f[:, 1] - tris_f[:, 0]
- dZ2 = tris_f[:, 2] - tris_f[:, 0]
- dZ = np.vstack([dZ1, dZ2]).T
- df = np.empty_like(dZ)
-
- # With np.einsum : could be ej,eji -> ej
- df[:, 0] = dZ[:, 0]*dM_inv[:, 0, 0] + dZ[:, 1]*dM_inv[:, 1, 0]
- df[:, 1] = dZ[:, 0]*dM_inv[:, 0, 1] + dZ[:, 1]*dM_inv[:, 1, 1]
- return df
-
-
-class _DOF_estimator_min_E(_DOF_estimator_geom):
- """
- The 'smoothest' approximation, df is computed through global minimization
- of the bending energy:
- E(f) = integral[(d2z/dx2 + d2z/dy2 + 2 d2z/dxdy)**2 dA]
- """
- def __init__(self, Interpolator):
- self._eccs = Interpolator._eccs
- _DOF_estimator_geom.__init__(self, Interpolator)
-
- def compute_dz(self):
- """
- Elliptic solver for bending energy minimization.
- Uses a dedicated 'toy' sparse Jacobi PCG solver.
- """
- # Initial guess for iterative PCG solver.
- dz_init = _DOF_estimator_geom.compute_dz(self)
- Uf0 = np.ravel(dz_init)
-
- reference_element = _ReducedHCT_Element()
- J = CubicTriInterpolator._get_jacobian(self._tris_pts)
- eccs = self._eccs
- triangles = self._triangles
- Uc = self.z[self._triangles]
-
- # Building stiffness matrix and force vector in coo format
- Kff_rows, Kff_cols, Kff_vals, Ff = reference_element.get_Kff_and_Ff(
- J, eccs, triangles, Uc)
-
- # Building sparse matrix and solving minimization problem
- # We could use scipy.sparse direct solver ; however to avoid this
- # external dependency an implementation of a simple PCG solver with
- # a simplendiagonal Jocabi preconditioner is implemented.
- tol = 1.e-10
- n_dof = Ff.shape[0]
- Kff_coo = _Sparse_Matrix_coo(Kff_vals, Kff_rows, Kff_cols,
- shape=(n_dof, n_dof))
- Kff_coo.compress_csc()
- Uf, err = _cg(A=Kff_coo, b=Ff, x0=Uf0, tol=tol)
- # If the PCG did not converge, we return the best guess between Uf0
- # and Uf.
- err0 = np.linalg.norm(Kff_coo.dot(Uf0) - Ff)
- if err0 < err:
- # Maybe a good occasion to raise a warning here ?
- warnings.warn("In TriCubicInterpolator initialization, PCG sparse"
- " solver did not converge after 1000 iterations. "
- "`geom` approximation is used instead of `min_E`")
- Uf = Uf0
-
- # Building dz from Uf
- dz = np.empty([self._pts.shape[0], 2], dtype=np.float64)
- dz[:, 0] = Uf[::2]
- dz[:, 1] = Uf[1::2]
- return dz
-
-
-# The following private :class:_Sparse_Matrix_coo and :func:_cg provide
-# a PCG sparse solver for (symmetric) elliptic problems.
-class _Sparse_Matrix_coo(object):
- def __init__(self, vals, rows, cols, shape):
- """
- Creates a sparse matrix in coo format
- *vals*: arrays of values of non-null entries of the matrix
- *rows*: int arrays of rows of non-null entries of the matrix
- *cols*: int arrays of cols of non-null entries of the matrix
- *shape*: 2-tuple (n,m) of matrix shape
-
- """
- self.n, self.m = shape
- self.vals = np.asarray(vals, dtype=np.float64)
- self.rows = np.asarray(rows, dtype=np.int32)
- self.cols = np.asarray(cols, dtype=np.int32)
-
- def dot(self, V):
- """
- Dot product of self by a vector *V* in sparse-dense to dense format
- *V* dense vector of shape (self.m,)
- """
- assert V.shape == (self.m,)
- return np.bincount(self.rows,
- weights=self.vals*V[self.cols],
- minlength=self.m)
-
- def compress_csc(self):
- """
- Compress rows, cols, vals / summing duplicates. Sort for csc format.
- """
- _, unique, indices = np.unique(
- self.rows + self.n*self.cols,
- return_index=True, return_inverse=True)
- self.rows = self.rows[unique]
- self.cols = self.cols[unique]
- self.vals = np.bincount(indices, weights=self.vals)
-
- def compress_csr(self):
- """
- Compress rows, cols, vals / summing duplicates. Sort for csr format.
- """
- _, unique, indices = np.unique(
- self.m*self.rows + self.cols,
- return_index=True, return_inverse=True)
- self.rows = self.rows[unique]
- self.cols = self.cols[unique]
- self.vals = np.bincount(indices, weights=self.vals)
-
- def to_dense(self):
- """
- Returns a dense matrix representing self.
- Mainly for debugging purposes.
- """
- ret = np.zeros([self.n, self.m], dtype=np.float64)
- nvals = self.vals.size
- for i in range(nvals):
- ret[self.rows[i], self.cols[i]] += self.vals[i]
- return ret
-
- def __str__(self):
- return self.to_dense().__str__()
-
- @property
- def diag(self):
- """
- Returns the (dense) vector of the diagonal elements.
- """
- in_diag = (self.rows == self.cols)
- diag = np.zeros(min(self.n, self.n), dtype=np.float64) # default 0.
- diag[self.rows[in_diag]] = self.vals[in_diag]
- return diag
-
-
-def _cg(A, b, x0=None, tol=1.e-10, maxiter=1000):
- """
- Use Preconditioned Conjugate Gradient iteration to solve A x = b
- A simple Jacobi (diagonal) preconditionner is used.
-
- Parameters
- ----------
- A: _Sparse_Matrix_coo
- *A* must have been compressed before by compress_csc or
- compress_csr method.
-
- b: array
- Right hand side of the linear system.
-
- Returns
- -------
- x: array.
- The converged solution.
- err: float
- The absolute error np.linalg.norm(A.dot(x) - b)
-
- Other parameters
- ----------------
- x0: array.
- Starting guess for the solution.
- tol: float.
- Tolerance to achieve. The algorithm terminates when the relative
- residual is below tol.
- maxiter: integer.
- Maximum number of iterations. Iteration will stop
- after maxiter steps even if the specified tolerance has not
- been achieved.
- """
- n = b.size
- assert A.n == n
- assert A.m == n
- b_norm = np.linalg.norm(b)
-
- # Jacobi pre-conditioner
- kvec = A.diag
- # For diag elem < 1e-6 we keep 1e-6.
- kvec = np.where(kvec > 1.e-6, kvec, 1.e-6)
-
- # Initial guess
- if x0 is None:
- x = np.zeros(n)
- else:
- x = x0
-
- r = b - A.dot(x)
- w = r/kvec
-
- p = np.zeros(n)
- beta = 0.0
- rho = np.dot(r, w)
- k = 0
-
- # Following C. T. Kelley
- while (np.sqrt(abs(rho)) > tol*b_norm) and (k < maxiter):
- p = w + beta*p
- z = A.dot(p)
- alpha = rho/np.dot(p, z)
- r = r - alpha*z
- w = r/kvec
- rhoold = rho
- rho = np.dot(r, w)
- x = x + alpha*p
- beta = rho/rhoold
- #err = np.linalg.norm(A.dot(x) - b) # absolute accuracy - not used
- k += 1
- err = np.linalg.norm(A.dot(x) - b)
- return x, err
-
-
-# The following private functions:
-# :func:`_inv22_vectorized`
-# :func:`_safe_inv22_vectorized`
-# :func:`_pseudo_inv22sym_vectorized`
-# :func:`_prod_vectorized`
-# :func:`_scalar_vectorized`
-# :func:`_transpose_vectorized`
-# :func:`_roll_vectorized`
-# :func:`_to_matrix_vectorized`
-# :func:`_extract_submatrices`
-# provide fast numpy implementation of some standard operations on arrays of
-# matrices - stored as (:, n_rows, n_cols)-shaped np.arrays.
-def _inv22_vectorized(M):
- """
- Inversion of arrays of (2,2) matrices.
- """
- assert (M.ndim == 3)
- assert (M.shape[-2:] == (2, 2))
- M_inv = np.empty_like(M)
- delta_inv = np.reciprocal(M[:, 0, 0]*M[:, 1, 1] - M[:, 0, 1]*M[:, 1, 0])
- M_inv[:, 0, 0] = M[:, 1, 1]*delta_inv
- M_inv[:, 0, 1] = -M[:, 0, 1]*delta_inv
- M_inv[:, 1, 0] = -M[:, 1, 0]*delta_inv
- M_inv[:, 1, 1] = M[:, 0, 0]*delta_inv
- return M_inv
-
-
-# Development note: Dealing with pathologic 'flat' triangles in the
-# CubicTriInterpolator code and impact on (2,2)-matrix inversion functions
-# :func:`_safe_inv22_vectorized` and :func:`_pseudo_inv22sym_vectorized`.
-#
-# Goals:
-# 1) The CubicTriInterpolator should be able to handle flat or almost flat
-# triangles without raising an error,
-# 2) These degenerated triangles should have no impact on the automatic dof
-# calculation (associated with null weight for the _DOF_estimator_geom and
-# with null energy for the _DOF_estimator_min_E),
-# 3) Linear patch test should be passed exactly on degenerated meshes,
-# 4) Interpolation (with :meth:`_interpolate_single_key` or
-# :meth:`_interpolate_multi_key`) shall be correctly handled even *inside*
-# the pathologic triangles, to interact correctly with a TriRefiner class.
-#
-# Difficulties:
-# Flat triangles have rank-deficient *J* (so-called jacobian matrix) and
-# *metric* (the metric tensor = J x J.T). Computation of the local
-# tangent plane is also problematic.
-#
-# Implementation:
-# Most of the time, when computing the inverse of a rank-deficient matrix it
-# is safe to simply return the null matrix (which is the implementation in
-# :func:`_safe_inv22_vectorized`). This is because of point 2), itself
-# enforced by:
-# - null area hence null energy in :class:`_DOF_estimator_min_E`
-# - angles close or equal to 0 or np.pi hence null weight in
-# :class:`_DOF_estimator_geom`.
-# Note that the function angle -> weight is continuous and maximum for an
-# angle np.pi/2 (refer to :meth:`compute_geom_weights`)
-# The exception is the computation of barycentric coordinates, which is done
-# by inversion of the *metric* matrix. In this case, we need to compute a set
-# of valid coordinates (1 among numerous possibilities), to ensure point 4).
-# We benefit here from the symmetry of metric = J x J.T, which makes it easier
-# to compute a pseudo-inverse in :func:`_pseudo_inv22sym_vectorized`
-def _safe_inv22_vectorized(M):
- """
- Inversion of arrays of (2,2) matrices, returns 0 for rank-deficient
- matrices.
-
- *M* : array of (2,2) matrices to inverse, shape (n,2,2)
- """
- assert M.ndim == 3
- assert M.shape[-2:] == (2, 2)
- M_inv = np.empty_like(M)
- prod1 = M[:, 0, 0]*M[:, 1, 1]
- delta = prod1 - M[:, 0, 1]*M[:, 1, 0]
-
- # We set delta_inv to 0. in case of a rank deficient matrix ; a
- # rank-deficient input matrix *M* will lead to a null matrix in output
- rank2 = (np.abs(delta) > 1e-8*np.abs(prod1))
- if np.all(rank2):
- # Normal 'optimized' flow.
- delta_inv = 1./delta
- else:
- # 'Pathologic' flow.
- delta_inv = np.zeros(M.shape[0])
- delta_inv[rank2] = 1./delta[rank2]
-
- M_inv[:, 0, 0] = M[:, 1, 1]*delta_inv
- M_inv[:, 0, 1] = -M[:, 0, 1]*delta_inv
- M_inv[:, 1, 0] = -M[:, 1, 0]*delta_inv
- M_inv[:, 1, 1] = M[:, 0, 0]*delta_inv
- return M_inv
-
-
-def _pseudo_inv22sym_vectorized(M):
- """
- Inversion of arrays of (2,2) SYMMETRIC matrices ; returns the
- (Moore-Penrose) pseudo-inverse for rank-deficient matrices.
-
- In case M is of rank 1, we have M = trace(M) x P where P is the orthogonal
- projection on Im(M), and we return trace(M)^-1 x P == M / trace(M)**2
- In case M is of rank 0, we return the null matrix.
-
- *M* : array of (2,2) matrices to inverse, shape (n,2,2)
- """
- assert M.ndim == 3
- assert M.shape[-2:] == (2, 2)
- M_inv = np.empty_like(M)
- prod1 = M[:, 0, 0]*M[:, 1, 1]
- delta = prod1 - M[:, 0, 1]*M[:, 1, 0]
- rank2 = (np.abs(delta) > 1e-8*np.abs(prod1))
-
- if np.all(rank2):
- # Normal 'optimized' flow.
- M_inv[:, 0, 0] = M[:, 1, 1] / delta
- M_inv[:, 0, 1] = -M[:, 0, 1] / delta
- M_inv[:, 1, 0] = -M[:, 1, 0] / delta
- M_inv[:, 1, 1] = M[:, 0, 0] / delta
- else:
- # 'Pathologic' flow.
- # Here we have to deal with 2 sub-cases
- # 1) First sub-case: matrices of rank 2:
- delta = delta[rank2]
- M_inv[rank2, 0, 0] = M[rank2, 1, 1] / delta
- M_inv[rank2, 0, 1] = -M[rank2, 0, 1] / delta
- M_inv[rank2, 1, 0] = -M[rank2, 1, 0] / delta
- M_inv[rank2, 1, 1] = M[rank2, 0, 0] / delta
- # 2) Second sub-case: rank-deficient matrices of rank 0 and 1:
- rank01 = ~rank2
- tr = M[rank01, 0, 0] + M[rank01, 1, 1]
- tr_zeros = (np.abs(tr) < 1.e-8)
- sq_tr_inv = (1.-tr_zeros) / (tr**2+tr_zeros)
- #sq_tr_inv = 1. / tr**2
- M_inv[rank01, 0, 0] = M[rank01, 0, 0] * sq_tr_inv
- M_inv[rank01, 0, 1] = M[rank01, 0, 1] * sq_tr_inv
- M_inv[rank01, 1, 0] = M[rank01, 1, 0] * sq_tr_inv
- M_inv[rank01, 1, 1] = M[rank01, 1, 1] * sq_tr_inv
-
- return M_inv
-
-
-def _prod_vectorized(M1, M2):
- """
- Matrix product between arrays of matrices, or a matrix and an array of
- matrices (*M1* and *M2*)
- """
- sh1 = M1.shape
- sh2 = M2.shape
- assert len(sh1) >= 2
- assert len(sh2) >= 2
- assert sh1[-1] == sh2[-2]
-
- ndim1 = len(sh1)
- t1_index = list(xrange(ndim1-2)) + [ndim1-1, ndim1-2]
- return np.sum(np.transpose(M1, t1_index)[..., np.newaxis] *
- M2[..., np.newaxis, :], -3)
-
-
-def _scalar_vectorized(scalar, M):
- """
- Scalar product between scalars and matrices.
- """
- return scalar[:, np.newaxis, np.newaxis]*M
-
-
-def _transpose_vectorized(M):
- """
- Transposition of an array of matrices *M*.
- """
- ndim = M.ndim
- assert ndim == 3
- return np.transpose(M, [0, ndim-1, ndim-2])
-
-
-def _roll_vectorized(M, roll_indices, axis):
- """
- Rolls an array of matrices along an axis according to an array of indices
- *roll_indices*
- *axis* can be either 0 (rolls rows) or 1 (rolls columns).
- """
- assert axis in [0, 1]
- ndim = M.ndim
- assert ndim == 3
- ndim_roll = roll_indices.ndim
- assert ndim_roll == 1
- sh = M.shape
- r, c = sh[-2:]
- assert sh[0] == roll_indices.shape[0]
- vec_indices = np.arange(sh[0], dtype=np.int32)
-
- # Builds the rolled matrix
- M_roll = np.empty_like(M)
- if axis == 0:
- for ir in range(r):
- for ic in range(c):
- M_roll[:, ir, ic] = M[vec_indices, (-roll_indices+ir) % r, ic]
- elif axis == 1:
- for ir in range(r):
- for ic in range(c):
- M_roll[:, ir, ic] = M[vec_indices, ir, (-roll_indices+ic) % c]
- return M_roll
-
-
-def _to_matrix_vectorized(M):
- """
- Builds an array of matrices from individuals np.arrays of identical
- shapes.
- *M*: ncols-list of nrows-lists of shape sh.
-
- Returns M_res np.array of shape (sh, nrow, ncols) so that:
- M_res[...,i,j] = M[i][j]
- """
- assert isinstance(M, (tuple, list))
- assert all([isinstance(item, (tuple, list)) for item in M])
- c_vec = np.asarray([len(item) for item in M])
- assert np.all(c_vec-c_vec[0] == 0)
- r = len(M)
- c = c_vec[0]
- M00 = np.asarray(M[0][0])
- dt = M00.dtype
- sh = [M00.shape[0], r, c]
- M_ret = np.empty(sh, dtype=dt)
- for irow in range(r):
- for icol in range(c):
- M_ret[:, irow, icol] = np.asarray(M[irow][icol])
- return M_ret
-
-
-def _extract_submatrices(M, block_indices, block_size, axis):
- """
- Extracts selected blocks of a matrices *M* depending on parameters
- *block_indices* and *block_size*.
-
- Returns the array of extracted matrices *Mres* so that:
- M_res[...,ir,:] = M[(block_indices*block_size+ir), :]
- """
- assert block_indices.ndim == 1
- assert axis in [0, 1]
-
- r, c = M.shape
- if axis == 0:
- sh = [block_indices.shape[0], block_size, c]
- elif axis == 1:
- sh = [block_indices.shape[0], r, block_size]
-
- dt = M.dtype
- M_res = np.empty(sh, dtype=dt)
- if axis == 0:
- for ir in range(block_size):
- M_res[:, ir, :] = M[(block_indices*block_size+ir), :]
- elif axis == 1:
- for ic in range(block_size):
- M_res[:, :, ic] = M[:, (block_indices*block_size+ic)]
-
- return M_res
diff --git a/contrib/python/matplotlib/py2/matplotlib/tri/tripcolor.py b/contrib/python/matplotlib/py2/matplotlib/tri/tripcolor.py
deleted file mode 100644
index 1da789a077..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/tri/tripcolor.py
+++ /dev/null
@@ -1,154 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from matplotlib.collections import PolyCollection, TriMesh
-from matplotlib.colors import Normalize
-from matplotlib.tri.triangulation import Triangulation
-import numpy as np
-
-
-def tripcolor(ax, *args, **kwargs):
- """
- Create a pseudocolor plot of an unstructured triangular grid.
-
- The triangulation can be specified in one of two ways; either::
-
- tripcolor(triangulation, ...)
-
- where triangulation is a :class:`matplotlib.tri.Triangulation`
- object, or
-
- ::
-
- tripcolor(x, y, ...)
- tripcolor(x, y, triangles, ...)
- tripcolor(x, y, triangles=triangles, ...)
- tripcolor(x, y, mask=mask, ...)
- tripcolor(x, y, triangles, mask=mask, ...)
-
- in which case a Triangulation object will be created. See
- :class:`~matplotlib.tri.Triangulation` for a explanation of these
- possibilities.
-
- The next argument must be *C*, the array of color values, either
- one per point in the triangulation if color values are defined at
- points, or one per triangle in the triangulation if color values
- are defined at triangles. If there are the same number of points
- and triangles in the triangulation it is assumed that color
- values are defined at points; to force the use of color values at
- triangles use the kwarg ``facecolors=C`` instead of just ``C``.
-
- *shading* may be 'flat' (the default) or 'gouraud'. If *shading*
- is 'flat' and C values are defined at points, the color values
- used for each triangle are from the mean C of the triangle's
- three points. If *shading* is 'gouraud' then color values must be
- defined at points.
-
- The remaining kwargs are the same as for
- :meth:`~matplotlib.axes.Axes.pcolor`.
- """
- if not ax._hold:
- ax.cla()
-
- alpha = kwargs.pop('alpha', 1.0)
- norm = kwargs.pop('norm', None)
- cmap = kwargs.pop('cmap', None)
- vmin = kwargs.pop('vmin', None)
- vmax = kwargs.pop('vmax', None)
- shading = kwargs.pop('shading', 'flat')
- facecolors = kwargs.pop('facecolors', None)
-
- if shading not in ['flat', 'gouraud']:
- raise ValueError("shading must be one of ['flat', 'gouraud'] "
- "not {0}".format(shading))
-
- tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args, **kwargs)
-
- # C is the colors array defined at either points or faces (i.e. triangles).
- # If facecolors is None, C are defined at points.
- # If facecolors is not None, C are defined at faces.
- if facecolors is not None:
- C = facecolors
- else:
- C = np.asarray(args[0])
-
- # If there are a different number of points and triangles in the
- # triangulation, can omit facecolors kwarg as it is obvious from
- # length of C whether it refers to points or faces.
- # Do not do this for gouraud shading.
- if (facecolors is None and len(C) == len(tri.triangles) and
- len(C) != len(tri.x) and shading != 'gouraud'):
- facecolors = C
-
- # Check length of C is OK.
- if ((facecolors is None and len(C) != len(tri.x)) or
- (facecolors is not None and len(C) != len(tri.triangles))):
- raise ValueError('Length of color values array must be the same '
- 'as either the number of triangulation points '
- 'or triangles')
-
- # Handling of linewidths, shading, edgecolors and antialiased as
- # in Axes.pcolor
- linewidths = (0.25,)
- if 'linewidth' in kwargs:
- kwargs['linewidths'] = kwargs.pop('linewidth')
- kwargs.setdefault('linewidths', linewidths)
-
- edgecolors = 'none'
- if 'edgecolor' in kwargs:
- kwargs['edgecolors'] = kwargs.pop('edgecolor')
- ec = kwargs.setdefault('edgecolors', edgecolors)
-
- if 'antialiased' in kwargs:
- kwargs['antialiaseds'] = kwargs.pop('antialiased')
- if 'antialiaseds' not in kwargs and ec.lower() == "none":
- kwargs['antialiaseds'] = False
-
- if shading == 'gouraud':
- if facecolors is not None:
- raise ValueError('Gouraud shading does not support the use '
- 'of facecolors kwarg')
- if len(C) != len(tri.x):
- raise ValueError('For gouraud shading, the length of color '
- 'values array must be the same as the '
- 'number of triangulation points')
- collection = TriMesh(tri, **kwargs)
- else:
- # Vertices of triangles.
- maskedTris = tri.get_masked_triangles()
- verts = np.concatenate((tri.x[maskedTris][..., np.newaxis],
- tri.y[maskedTris][..., np.newaxis]), axis=2)
-
- # Color values.
- if facecolors is None:
- # One color per triangle, the mean of the 3 vertex color values.
- C = C[maskedTris].mean(axis=1)
- elif tri.mask is not None:
- # Remove color values of masked triangles.
- C = C.compress(1-tri.mask)
-
- collection = PolyCollection(verts, **kwargs)
-
- collection.set_alpha(alpha)
- collection.set_array(C)
- if norm is not None and not isinstance(norm, Normalize):
- raise ValueError("'norm' must be an instance of 'Normalize'")
- collection.set_cmap(cmap)
- collection.set_norm(norm)
- if vmin is not None or vmax is not None:
- collection.set_clim(vmin, vmax)
- else:
- collection.autoscale_None()
- ax.grid(False)
-
- minx = tri.x.min()
- maxx = tri.x.max()
- miny = tri.y.min()
- maxy = tri.y.max()
- corners = (minx, miny), (maxx, maxy)
- ax.update_datalim(corners)
- ax.autoscale_view()
- ax.add_collection(collection)
- return collection
diff --git a/contrib/python/matplotlib/py2/matplotlib/tri/triplot.py b/contrib/python/matplotlib/py2/matplotlib/tri/triplot.py
deleted file mode 100644
index b22d77b71e..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/tri/triplot.py
+++ /dev/null
@@ -1,88 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import numpy as np
-from matplotlib.tri.triangulation import Triangulation
-
-
-def triplot(ax, *args, **kwargs):
- """
- Draw a unstructured triangular grid as lines and/or markers.
-
- The triangulation to plot can be specified in one of two ways;
- either::
-
- triplot(triangulation, ...)
-
- where triangulation is a :class:`matplotlib.tri.Triangulation`
- object, or
-
- ::
-
- triplot(x, y, ...)
- triplot(x, y, triangles, ...)
- triplot(x, y, triangles=triangles, ...)
- triplot(x, y, mask=mask, ...)
- triplot(x, y, triangles, mask=mask, ...)
-
- in which case a Triangulation object will be created. See
- :class:`~matplotlib.tri.Triangulation` for a explanation of these
- possibilities.
-
- The remaining args and kwargs are the same as for
- :meth:`~matplotlib.axes.Axes.plot`.
-
- Return a list of 2 :class:`~matplotlib.lines.Line2D` containing
- respectively:
-
- - the lines plotted for triangles edges
- - the markers plotted for triangles nodes
- """
- import matplotlib.axes
-
- tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args, **kwargs)
- x, y, edges = (tri.x, tri.y, tri.edges)
-
- # Decode plot format string, e.g., 'ro-'
- fmt = ""
- if len(args) > 0:
- fmt = args[0]
- linestyle, marker, color = matplotlib.axes._base._process_plot_format(fmt)
-
- # Insert plot format string into a copy of kwargs (kwargs values prevail).
- kw = kwargs.copy()
- for key, val in zip(('linestyle', 'marker', 'color'),
- (linestyle, marker, color)):
- if val is not None:
- kw[key] = kwargs.get(key, val)
-
- # Draw lines without markers.
- # Note 1: If we drew markers here, most markers would be drawn more than
- # once as they belong to several edges.
- # Note 2: We insert nan values in the flattened edges arrays rather than
- # plotting directly (triang.x[edges].T, triang.y[edges].T)
- # as it considerably speeds-up code execution.
- linestyle = kw['linestyle']
- kw_lines = kw.copy()
- kw_lines['marker'] = 'None' # No marker to draw.
- kw_lines['zorder'] = kw.get('zorder', 1) # Path default zorder is used.
- if (linestyle is not None) and (linestyle not in ['None', '', ' ']):
- tri_lines_x = np.insert(x[edges], 2, np.nan, axis=1)
- tri_lines_y = np.insert(y[edges], 2, np.nan, axis=1)
- tri_lines = ax.plot(tri_lines_x.ravel(), tri_lines_y.ravel(),
- **kw_lines)
- else:
- tri_lines = ax.plot([], [], **kw_lines)
-
- # Draw markers separately.
- marker = kw['marker']
- kw_markers = kw.copy()
- kw_markers['linestyle'] = 'None' # No line to draw.
- if (marker is not None) and (marker not in ['None', '', ' ']):
- tri_markers = ax.plot(x, y, **kw_markers)
- else:
- tri_markers = ax.plot([], [], **kw_markers)
-
- return tri_lines + tri_markers
diff --git a/contrib/python/matplotlib/py2/matplotlib/tri/trirefine.py b/contrib/python/matplotlib/py2/matplotlib/tri/trirefine.py
deleted file mode 100644
index bbf3398809..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/tri/trirefine.py
+++ /dev/null
@@ -1,323 +0,0 @@
-"""
-Mesh refinement for triangular grids.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import numpy as np
-from matplotlib.tri.triangulation import Triangulation
-import matplotlib.tri.triinterpolate
-
-
-class TriRefiner(object):
- """
- Abstract base class for classes implementing mesh refinement.
-
- A TriRefiner encapsulates a Triangulation object and provides tools for
- mesh refinement and interpolation.
-
- Derived classes must implements:
-
- - ``refine_triangulation(return_tri_index=False, **kwargs)`` , where
- the optional keyword arguments *kwargs* are defined in each
- TriRefiner concrete implementation, and which returns :
-
- - a refined triangulation
- - optionally (depending on *return_tri_index*), for each
- point of the refined triangulation: the index of
- the initial triangulation triangle to which it belongs.
-
- - ``refine_field(z, triinterpolator=None, **kwargs)`` , where:
-
- - *z* array of field values (to refine) defined at the base
- triangulation nodes
- - *triinterpolator* is a
- :class:`~matplotlib.tri.TriInterpolator` (optional)
- - the other optional keyword arguments *kwargs* are defined in
- each TriRefiner concrete implementation
-
- and which returns (as a tuple) a refined triangular mesh and the
- interpolated values of the field at the refined triangulation nodes.
-
- """
- def __init__(self, triangulation):
- if not isinstance(triangulation, Triangulation):
- raise ValueError("Expected a Triangulation object")
- self._triangulation = triangulation
-
-
-class UniformTriRefiner(TriRefiner):
- """
- Uniform mesh refinement by recursive subdivisions.
-
- Parameters
- ----------
- triangulation : :class:`~matplotlib.tri.Triangulation`
- The encapsulated triangulation (to be refined)
- """
-# See Also
-# --------
-# :class:`~matplotlib.tri.CubicTriInterpolator` and
-# :class:`~matplotlib.tri.TriAnalyzer`.
-# """
- def __init__(self, triangulation):
- TriRefiner.__init__(self, triangulation)
-
- def refine_triangulation(self, return_tri_index=False, subdiv=3):
- """
- Computes an uniformly refined triangulation *refi_triangulation* of
- the encapsulated :attr:`triangulation`.
-
- This function refines the encapsulated triangulation by splitting each
- father triangle into 4 child sub-triangles built on the edges midside
- nodes, recursively (level of recursion *subdiv*).
- In the end, each triangle is hence divided into ``4**subdiv``
- child triangles.
- The default value for *subdiv* is 3 resulting in 64 refined
- subtriangles for each triangle of the initial triangulation.
-
- Parameters
- ----------
- return_tri_index : boolean, optional
- Boolean indicating whether an index table indicating the father
- triangle index of each point will be returned. Default value
- False.
- subdiv : integer, optional
- Recursion level for the subdivision. Defaults value 3.
- Each triangle will be divided into ``4**subdiv`` child triangles.
-
- Returns
- -------
- refi_triangulation : :class:`~matplotlib.tri.Triangulation`
- The returned refined triangulation
- found_index : array-like of integers
- Index of the initial triangulation containing triangle, for each
- point of *refi_triangulation*.
- Returned only if *return_tri_index* is set to True.
-
- """
- refi_triangulation = self._triangulation
- ntri = refi_triangulation.triangles.shape[0]
-
- # Computes the triangulation ancestors numbers in the reference
- # triangulation.
- ancestors = np.arange(ntri, dtype=np.int32)
- for _ in range(subdiv):
- refi_triangulation, ancestors = self._refine_triangulation_once(
- refi_triangulation, ancestors)
- refi_npts = refi_triangulation.x.shape[0]
- refi_triangles = refi_triangulation.triangles
-
- # Now we compute found_index table if needed
- if return_tri_index:
- # We have to initialize found_index with -1 because some nodes
- # may very well belong to no triangle at all, e.g., in case of
- # Delaunay Triangulation with DuplicatePointWarning.
- found_index = - np.ones(refi_npts, dtype=np.int32)
- tri_mask = self._triangulation.mask
- if tri_mask is None:
- found_index[refi_triangles] = np.repeat(ancestors,
- 3).reshape(-1, 3)
- else:
- # There is a subtlety here: we want to avoid whenever possible
- # that refined points container is a masked triangle (which
- # would result in artifacts in plots).
- # So we impose the numbering from masked ancestors first,
- # then overwrite it with unmasked ancestor numbers.
- ancestor_mask = tri_mask[ancestors]
- found_index[refi_triangles[ancestor_mask, :]
- ] = np.repeat(ancestors[ancestor_mask],
- 3).reshape(-1, 3)
- found_index[refi_triangles[~ancestor_mask, :]
- ] = np.repeat(ancestors[~ancestor_mask],
- 3).reshape(-1, 3)
- return refi_triangulation, found_index
- else:
- return refi_triangulation
-
- def refine_field(self, z, triinterpolator=None, subdiv=3):
- """
- Refines a field defined on the encapsulated triangulation.
-
- Returns *refi_tri* (refined triangulation), *refi_z* (interpolated
- values of the field at the node of the refined triangulation).
-
- Parameters
- ----------
- z : 1d-array-like of length ``n_points``
- Values of the field to refine, defined at the nodes of the
- encapsulated triangulation. (``n_points`` is the number of points
- in the initial triangulation)
- triinterpolator : :class:`~matplotlib.tri.TriInterpolator`, optional
- Interpolator used for field interpolation. If not specified,
- a :class:`~matplotlib.tri.CubicTriInterpolator` will
- be used.
- subdiv : integer, optional
- Recursion level for the subdivision. Defaults to 3.
- Each triangle will be divided into ``4**subdiv`` child triangles.
-
- Returns
- -------
- refi_tri : :class:`~matplotlib.tri.Triangulation` object
- The returned refined triangulation
- refi_z : 1d array of length: *refi_tri* node count.
- The returned interpolated field (at *refi_tri* nodes)
- """
- if triinterpolator is None:
- interp = matplotlib.tri.CubicTriInterpolator(
- self._triangulation, z)
- else:
- if not isinstance(triinterpolator,
- matplotlib.tri.TriInterpolator):
- raise ValueError("Expected a TriInterpolator object")
- interp = triinterpolator
-
- refi_tri, found_index = self.refine_triangulation(
- subdiv=subdiv, return_tri_index=True)
- refi_z = interp._interpolate_multikeys(
- refi_tri.x, refi_tri.y, tri_index=found_index)[0]
- return refi_tri, refi_z
-
- @staticmethod
- def _refine_triangulation_once(triangulation, ancestors=None):
- """
- This function refines a matplotlib.tri *triangulation* by splitting
- each triangle into 4 child-masked_triangles built on the edges midside
- nodes.
- The masked triangles, if present, are also split but their children
- returned masked.
-
- If *ancestors* is not provided, returns only a new triangulation:
- child_triangulation.
-
- If the array-like key table *ancestor* is given, it shall be of shape
- (ntri,) where ntri is the number of *triangulation* masked_triangles.
- In this case, the function returns
- (child_triangulation, child_ancestors)
- child_ancestors is defined so that the 4 child masked_triangles share
- the same index as their father: child_ancestors.shape = (4 * ntri,).
-
- """
- x = triangulation.x
- y = triangulation.y
-
- # According to tri.triangulation doc:
- # neighbors[i,j] is the triangle that is the neighbor
- # to the edge from point index masked_triangles[i,j] to point
- # index masked_triangles[i,(j+1)%3].
- neighbors = triangulation.neighbors
- triangles = triangulation.triangles
- npts = np.shape(x)[0]
- ntri = np.shape(triangles)[0]
- if ancestors is not None:
- ancestors = np.asarray(ancestors)
- if np.shape(ancestors) != (ntri,):
- raise ValueError(
- "Incompatible shapes provide for triangulation"
- ".masked_triangles and ancestors: {0} and {1}".format(
- np.shape(triangles), np.shape(ancestors)))
-
- # Initiating tables refi_x and refi_y of the refined triangulation
- # points
- # hint: each apex is shared by 2 masked_triangles except the borders.
- borders = np.sum(neighbors == -1)
- added_pts = (3*ntri + borders) // 2
- refi_npts = npts + added_pts
- refi_x = np.zeros(refi_npts)
- refi_y = np.zeros(refi_npts)
-
- # First part of refi_x, refi_y is just the initial points
- refi_x[:npts] = x
- refi_y[:npts] = y
-
- # Second part contains the edge midside nodes.
- # Each edge belongs to 1 triangle (if border edge) or is shared by 2
- # masked_triangles (interior edge).
- # We first build 2 * ntri arrays of edge starting nodes (edge_elems,
- # edge_apexes) ; we then extract only the masters to avoid overlaps.
- # The so-called 'master' is the triangle with biggest index
- # The 'slave' is the triangle with lower index
- # (can be -1 if border edge)
- # For slave and master we will identify the apex pointing to the edge
- # start
- edge_elems = np.ravel(np.vstack([np.arange(ntri, dtype=np.int32),
- np.arange(ntri, dtype=np.int32),
- np.arange(ntri, dtype=np.int32)]))
- edge_apexes = np.ravel(np.vstack([np.zeros(ntri, dtype=np.int32),
- np.ones(ntri, dtype=np.int32),
- np.ones(ntri, dtype=np.int32)*2]))
- edge_neighbors = neighbors[edge_elems, edge_apexes]
- mask_masters = (edge_elems > edge_neighbors)
-
- # Identifying the "masters" and adding to refi_x, refi_y vec
- masters = edge_elems[mask_masters]
- apex_masters = edge_apexes[mask_masters]
- x_add = (x[triangles[masters, apex_masters]] +
- x[triangles[masters, (apex_masters+1) % 3]]) * 0.5
- y_add = (y[triangles[masters, apex_masters]] +
- y[triangles[masters, (apex_masters+1) % 3]]) * 0.5
- refi_x[npts:] = x_add
- refi_y[npts:] = y_add
-
- # Building the new masked_triangles ; each old masked_triangles hosts
- # 4 new masked_triangles
- # there are 6 pts to identify per 'old' triangle, 3 new_pt_corner and
- # 3 new_pt_midside
- new_pt_corner = triangles
-
- # What is the index in refi_x, refi_y of point at middle of apex iapex
- # of elem ielem ?
- # If ielem is the apex master: simple count, given the way refi_x was
- # built.
- # If ielem is the apex slave: yet we do not know ; but we will soon
- # using the neighbors table.
- new_pt_midside = np.empty([ntri, 3], dtype=np.int32)
- cum_sum = npts
- for imid in range(3):
- mask_st_loc = (imid == apex_masters)
- n_masters_loc = np.sum(mask_st_loc)
- elem_masters_loc = masters[mask_st_loc]
- new_pt_midside[:, imid][elem_masters_loc] = np.arange(
- n_masters_loc, dtype=np.int32) + cum_sum
- cum_sum += n_masters_loc
-
- # Now dealing with slave elems.
- # for each slave element we identify the master and then the inode
- # once slave_masters is identified, slave_masters_apex is such that:
- # neighbors[slaves_masters, slave_masters_apex] == slaves
- mask_slaves = np.logical_not(mask_masters)
- slaves = edge_elems[mask_slaves]
- slaves_masters = edge_neighbors[mask_slaves]
- diff_table = np.abs(neighbors[slaves_masters, :] -
- np.outer(slaves, np.ones(3, dtype=np.int32)))
- slave_masters_apex = np.argmin(diff_table, axis=1)
- slaves_apex = edge_apexes[mask_slaves]
- new_pt_midside[slaves, slaves_apex] = new_pt_midside[
- slaves_masters, slave_masters_apex]
-
- # Builds the 4 child masked_triangles
- child_triangles = np.empty([ntri*4, 3], dtype=np.int32)
- child_triangles[0::4, :] = np.vstack([
- new_pt_corner[:, 0], new_pt_midside[:, 0],
- new_pt_midside[:, 2]]).T
- child_triangles[1::4, :] = np.vstack([
- new_pt_corner[:, 1], new_pt_midside[:, 1],
- new_pt_midside[:, 0]]).T
- child_triangles[2::4, :] = np.vstack([
- new_pt_corner[:, 2], new_pt_midside[:, 2],
- new_pt_midside[:, 1]]).T
- child_triangles[3::4, :] = np.vstack([
- new_pt_midside[:, 0], new_pt_midside[:, 1],
- new_pt_midside[:, 2]]).T
- child_triangulation = Triangulation(refi_x, refi_y, child_triangles)
-
- # Builds the child mask
- if triangulation.mask is not None:
- child_triangulation.set_mask(np.repeat(triangulation.mask, 4))
-
- if ancestors is None:
- return child_triangulation
- else:
- return child_triangulation, np.repeat(ancestors, 4)
diff --git a/contrib/python/matplotlib/py2/matplotlib/tri/tritools.py b/contrib/python/matplotlib/py2/matplotlib/tri/tritools.py
deleted file mode 100644
index c7491f9ea5..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/tri/tritools.py
+++ /dev/null
@@ -1,304 +0,0 @@
-"""
-Tools for triangular grids.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from matplotlib.tri import Triangulation
-import numpy as np
-
-
-class TriAnalyzer(object):
- """
- Define basic tools for triangular mesh analysis and improvement.
-
- A TriAnalizer encapsulates a :class:`~matplotlib.tri.Triangulation`
- object and provides basic tools for mesh analysis and mesh improvement.
-
- Parameters
- ----------
- triangulation : :class:`~matplotlib.tri.Triangulation` object
- The encapsulated triangulation to analyze.
-
- Attributes
- ----------
- `scale_factors`
-
- """
- def __init__(self, triangulation):
- if not isinstance(triangulation, Triangulation):
- raise ValueError("Expected a Triangulation object")
- self._triangulation = triangulation
-
- @property
- def scale_factors(self):
- """
- Factors to rescale the triangulation into a unit square.
-
- Returns *k*, tuple of 2 scale factors.
-
- Returns
- -------
- k : tuple of 2 floats (kx, ky)
- Tuple of floats that would rescale the triangulation :
- ``[triangulation.x * kx, triangulation.y * ky]``
- fits exactly inside a unit square.
-
- """
- compressed_triangles = self._triangulation.get_masked_triangles()
- node_used = (np.bincount(np.ravel(compressed_triangles),
- minlength=self._triangulation.x.size) != 0)
- return (1 / np.ptp(self._triangulation.x[node_used]),
- 1 / np.ptp(self._triangulation.y[node_used]))
-
- def circle_ratios(self, rescale=True):
- """
- Returns a measure of the triangulation triangles flatness.
-
- The ratio of the incircle radius over the circumcircle radius is a
- widely used indicator of a triangle flatness.
- It is always ``<= 0.5`` and ``== 0.5`` only for equilateral
- triangles. Circle ratios below 0.01 denote very flat triangles.
-
- To avoid unduly low values due to a difference of scale between the 2
- axis, the triangular mesh can first be rescaled to fit inside a unit
- square with :attr:`scale_factors` (Only if *rescale* is True, which is
- its default value).
-
- Parameters
- ----------
- rescale : boolean, optional
- If True, a rescaling will be internally performed (based on
- :attr:`scale_factors`, so that the (unmasked) triangles fit
- exactly inside a unit square mesh. Default is True.
-
- Returns
- -------
- circle_ratios : masked array
- Ratio of the incircle radius over the
- circumcircle radius, for each 'rescaled' triangle of the
- encapsulated triangulation.
- Values corresponding to masked triangles are masked out.
-
- """
- # Coords rescaling
- if rescale:
- (kx, ky) = self.scale_factors
- else:
- (kx, ky) = (1.0, 1.0)
- pts = np.vstack([self._triangulation.x*kx,
- self._triangulation.y*ky]).T
- tri_pts = pts[self._triangulation.triangles]
- # Computes the 3 side lengths
- a = tri_pts[:, 1, :] - tri_pts[:, 0, :]
- b = tri_pts[:, 2, :] - tri_pts[:, 1, :]
- c = tri_pts[:, 0, :] - tri_pts[:, 2, :]
- a = np.sqrt(a[:, 0]**2 + a[:, 1]**2)
- b = np.sqrt(b[:, 0]**2 + b[:, 1]**2)
- c = np.sqrt(c[:, 0]**2 + c[:, 1]**2)
- # circumcircle and incircle radii
- s = (a+b+c)*0.5
- prod = s*(a+b-s)*(a+c-s)*(b+c-s)
- # We have to deal with flat triangles with infinite circum_radius
- bool_flat = (prod == 0.)
- if np.any(bool_flat):
- # Pathologic flow
- ntri = tri_pts.shape[0]
- circum_radius = np.empty(ntri, dtype=np.float64)
- circum_radius[bool_flat] = np.inf
- abc = a*b*c
- circum_radius[~bool_flat] = abc[~bool_flat] / (
- 4.0*np.sqrt(prod[~bool_flat]))
- else:
- # Normal optimized flow
- circum_radius = (a*b*c) / (4.0*np.sqrt(prod))
- in_radius = (a*b*c) / (4.0*circum_radius*s)
- circle_ratio = in_radius/circum_radius
- mask = self._triangulation.mask
- if mask is None:
- return circle_ratio
- else:
- return np.ma.array(circle_ratio, mask=mask)
-
- def get_flat_tri_mask(self, min_circle_ratio=0.01, rescale=True):
- """
- Eliminates excessively flat border triangles from the triangulation.
-
- Returns a mask *new_mask* which allows to clean the encapsulated
- triangulation from its border-located flat triangles
- (according to their :meth:`circle_ratios`).
- This mask is meant to be subsequently applied to the triangulation
- using :func:`matplotlib.tri.Triangulation.set_mask` .
- *new_mask* is an extension of the initial triangulation mask
- in the sense that an initially masked triangle will remain masked.
-
- The *new_mask* array is computed recursively ; at each step flat
- triangles are removed only if they share a side with the current
- mesh border. Thus no new holes in the triangulated domain will be
- created.
-
- Parameters
- ----------
- min_circle_ratio : float, optional
- Border triangles with incircle/circumcircle radii ratio r/R will
- be removed if r/R < *min_circle_ratio*. Default value: 0.01
- rescale : boolean, optional
- If True, a rescaling will first be internally performed (based on
- :attr:`scale_factors` ), so that the (unmasked) triangles fit
- exactly inside a unit square mesh. This rescaling accounts for the
- difference of scale which might exist between the 2 axis. Default
- (and recommended) value is True.
-
- Returns
- -------
- new_mask : array-like of booleans
- Mask to apply to encapsulated triangulation.
- All the initially masked triangles remain masked in the
- *new_mask*.
-
- Notes
- -----
- The rationale behind this function is that a Delaunay
- triangulation - of an unstructured set of points - sometimes contains
- almost flat triangles at its border, leading to artifacts in plots
- (especially for high-resolution contouring).
- Masked with computed *new_mask*, the encapsulated
- triangulation would contain no more unmasked border triangles
- with a circle ratio below *min_circle_ratio*, thus improving the
- mesh quality for subsequent plots or interpolation.
- """
- # Recursively computes the mask_current_borders, true if a triangle is
- # at the border of the mesh OR touching the border through a chain of
- # invalid aspect ratio masked_triangles.
- ntri = self._triangulation.triangles.shape[0]
- mask_bad_ratio = self.circle_ratios(rescale) < min_circle_ratio
-
- current_mask = self._triangulation.mask
- if current_mask is None:
- current_mask = np.zeros(ntri, dtype=bool)
- valid_neighbors = np.copy(self._triangulation.neighbors)
- renum_neighbors = np.arange(ntri, dtype=np.int32)
- nadd = -1
- while nadd != 0:
- # The active wavefront is the triangles from the border (unmasked
- # but with a least 1 neighbor equal to -1
- wavefront = ((np.min(valid_neighbors, axis=1) == -1)
- & ~current_mask)
- # The element from the active wavefront will be masked if their
- # circle ratio is bad.
- added_mask = np.logical_and(wavefront, mask_bad_ratio)
- current_mask = (added_mask | current_mask)
- nadd = np.sum(added_mask)
-
- # now we have to update the tables valid_neighbors
- valid_neighbors[added_mask, :] = -1
- renum_neighbors[added_mask] = -1
- valid_neighbors = np.where(valid_neighbors == -1, -1,
- renum_neighbors[valid_neighbors])
-
- return np.ma.filled(current_mask, True)
-
- def _get_compressed_triangulation(self, return_tri_renum=False,
- return_node_renum=False):
- """
- Compress (if masked) the encapsulated triangulation.
-
- Returns minimal-length triangles array (*compressed_triangles*) and
- coordinates arrays (*compressed_x*, *compressed_y*) that can still
- describe the unmasked triangles of the encapsulated triangulation.
-
- Parameters
- ----------
- return_tri_renum : boolean, optional
- Indicates whether a renumbering table to translate the triangle
- numbers from the encapsulated triangulation numbering into the
- new (compressed) renumbering will be returned.
- return_node_renum : boolean, optional
- Indicates whether a renumbering table to translate the nodes
- numbers from the encapsulated triangulation numbering into the
- new (compressed) renumbering will be returned.
-
- Returns
- -------
- compressed_triangles : array-like
- the returned compressed triangulation triangles
- compressed_x : array-like
- the returned compressed triangulation 1st coordinate
- compressed_y : array-like
- the returned compressed triangulation 2nd coordinate
- tri_renum : array-like of integers
- renumbering table to translate the triangle numbers from the
- encapsulated triangulation into the new (compressed) renumbering.
- -1 for masked triangles (deleted from *compressed_triangles*).
- Returned only if *return_tri_renum* is True.
- node_renum : array-like of integers
- renumbering table to translate the point numbers from the
- encapsulated triangulation into the new (compressed) renumbering.
- -1 for unused points (i.e. those deleted from *compressed_x* and
- *compressed_y*). Returned only if *return_node_renum* is True.
-
- """
- # Valid triangles and renumbering
- tri_mask = self._triangulation.mask
- compressed_triangles = self._triangulation.get_masked_triangles()
- ntri = self._triangulation.triangles.shape[0]
- tri_renum = self._total_to_compress_renum(tri_mask, ntri)
-
- # Valid nodes and renumbering
- node_mask = (np.bincount(np.ravel(compressed_triangles),
- minlength=self._triangulation.x.size) == 0)
- compressed_x = self._triangulation.x[~node_mask]
- compressed_y = self._triangulation.y[~node_mask]
- node_renum = self._total_to_compress_renum(node_mask)
-
- # Now renumbering the valid triangles nodes
- compressed_triangles = node_renum[compressed_triangles]
-
- # 4 cases possible for return
- if not return_tri_renum:
- if not return_node_renum:
- return compressed_triangles, compressed_x, compressed_y
- else:
- return (compressed_triangles, compressed_x, compressed_y,
- node_renum)
- else:
- if not return_node_renum:
- return (compressed_triangles, compressed_x, compressed_y,
- tri_renum)
- else:
- return (compressed_triangles, compressed_x, compressed_y,
- tri_renum, node_renum)
-
- @staticmethod
- def _total_to_compress_renum(mask, n=None):
- """
- Parameters
- ----------
- mask : 1d boolean array or None
- mask
- n : integer
- length of the mask. Useful only id mask can be None
-
- Returns
- -------
- renum : integer array
- array so that (`valid_array` being a compressed array
- based on a `masked_array` with mask *mask*) :
-
- - For all i such as mask[i] = False:
- valid_array[renum[i]] = masked_array[i]
- - For all i such as mask[i] = True:
- renum[i] = -1 (invalid value)
-
- """
- if n is None:
- n = np.size(mask)
- if mask is not None:
- renum = -np.ones(n, dtype=np.int32) # Default num is -1
- valid = np.arange(n, dtype=np.int32).compress(~mask, axis=0)
- renum[valid] = np.arange(np.size(valid, 0), dtype=np.int32)
- return renum
- else:
- return np.arange(n, dtype=np.int32)
diff --git a/contrib/python/matplotlib/py2/matplotlib/tri/ya.make b/contrib/python/matplotlib/py2/matplotlib/tri/ya.make
deleted file mode 100644
index fb0545dd9f..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/tri/ya.make
+++ /dev/null
@@ -1,43 +0,0 @@
-PY2_LIBRARY()
-
-VERSION(2.2.5)
-
-LICENSE(PSF-2.0)
-
-NO_COMPILER_WARNINGS()
-NO_LINT()
-
-PEERDIR(
- ADDINCL contrib/python/numpy
-)
-
-ADDINCL(
- contrib/python/matplotlib/py2
-)
-
-CFLAGS(
- -DPY_ARRAY_UNIQUE_SYMBOL=MPL_matplotlib__tri_ARRAY_API
- -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION
-)
-
-PY_SRCS(
- NAMESPACE matplotlib.tri
- __init__.py
- triangulation.py
- tricontour.py
- trifinder.py
- triinterpolate.py
- tripcolor.py
- triplot.py
- trirefine.py
- tritools.py
-)
-
-PY_REGISTER(matplotlib._tri)
-
-SRCS(
- _tri.cpp
- _tri_wrapper.cpp
-)
-
-END()
diff --git a/contrib/python/matplotlib/py2/matplotlib/type1font.py b/contrib/python/matplotlib/py2/matplotlib/type1font.py
deleted file mode 100644
index 0eed97ec68..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/type1font.py
+++ /dev/null
@@ -1,334 +0,0 @@
-"""
-This module contains a class representing a Type 1 font.
-
-This version reads pfa and pfb files and splits them for embedding in
-pdf files. It also supports SlantFont and ExtendFont transformations,
-similarly to pdfTeX and friends. There is no support yet for
-subsetting.
-
-Usage::
-
- >>> font = Type1Font(filename)
- >>> clear_part, encrypted_part, finale = font.parts
- >>> slanted_font = font.transform({'slant': 0.167})
- >>> extended_font = font.transform({'extend': 1.2})
-
-Sources:
-
-* Adobe Technical Note #5040, Supporting Downloadable PostScript
- Language Fonts.
-
-* Adobe Type 1 Font Format, Adobe Systems Incorporated, third printing,
- v1.1, 1993. ISBN 0-201-57044-0.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import binascii
-import io
-import itertools
-import re
-import struct
-
-import numpy as np
-
-if six.PY3:
- def ord(x):
- return x
-
-
-class Type1Font(object):
- """
- A class representing a Type-1 font, for use by backends.
-
- Attributes
- ----------
- parts : tuple
- A 3-tuple of the cleartext part, the encrypted part, and the finale of
- zeros.
-
- prop : Dict[str, Any]
- A dictionary of font properties.
-
- """
- __slots__ = ('parts', 'prop')
-
- def __init__(self, input):
- """
- Initialize a Type-1 font. *input* can be either the file name of
- a pfb file or a 3-tuple of already-decoded Type-1 font parts.
- """
- if isinstance(input, tuple) and len(input) == 3:
- self.parts = input
- else:
- with open(input, 'rb') as file:
- data = self._read(file)
- self.parts = self._split(data)
-
- self._parse()
-
- def _read(self, file):
- """
- Read the font from a file, decoding into usable parts.
- """
- rawdata = file.read()
- if not rawdata.startswith(b'\x80'):
- return rawdata
-
- data = b''
- while len(rawdata) > 0:
- if not rawdata.startswith(b'\x80'):
- raise RuntimeError('Broken pfb file (expected byte 128, '
- 'got %d)' % ord(rawdata[0]))
- type = ord(rawdata[1])
- if type in (1, 2):
- length, = struct.unpack(str('<i'), rawdata[2:6])
- segment = rawdata[6:6 + length]
- rawdata = rawdata[6 + length:]
-
- if type == 1: # ASCII text: include verbatim
- data += segment
- elif type == 2: # binary data: encode in hexadecimal
- data += binascii.hexlify(segment)
- elif type == 3: # end of file
- break
- else:
- raise RuntimeError('Unknown segment type %d in pfb file' %
- type)
-
- return data
-
- def _split(self, data):
- """
- Split the Type 1 font into its three main parts.
-
- The three parts are: (1) the cleartext part, which ends in a
- eexec operator; (2) the encrypted part; (3) the fixed part,
- which contains 512 ASCII zeros possibly divided on various
- lines, a cleartomark operator, and possibly something else.
- """
-
- # Cleartext part: just find the eexec and skip whitespace
- idx = data.index(b'eexec')
- idx += len(b'eexec')
- while data[idx] in b' \t\r\n':
- idx += 1
- len1 = idx
-
- # Encrypted part: find the cleartomark operator and count
- # zeros backward
- idx = data.rindex(b'cleartomark') - 1
- zeros = 512
- while zeros and data[idx] in b'0' or data[idx] in b'\r\n':
- if data[idx] in b'0':
- zeros -= 1
- idx -= 1
- if zeros:
- raise RuntimeError('Insufficiently many zeros in Type 1 font')
-
- # Convert encrypted part to binary (if we read a pfb file, we
- # may end up converting binary to hexadecimal to binary again;
- # but if we read a pfa file, this part is already in hex, and
- # I am not quite sure if even the pfb format guarantees that
- # it will be in binary).
- binary = binascii.unhexlify(data[len1:idx+1])
-
- return data[:len1], binary, data[idx+1:]
-
- _whitespace_re = re.compile(br'[\0\t\r\014\n ]+')
- _token_re = re.compile(br'/{0,2}[^]\0\t\r\v\n ()<>{}/%[]+')
- _comment_re = re.compile(br'%[^\r\n\v]*')
- _instring_re = re.compile(br'[()\\]')
-
- # token types, compared via object identity (poor man's enum)
- _whitespace = object()
- _name = object()
- _string = object()
- _delimiter = object()
- _number = object()
-
- @classmethod
- def _tokens(cls, text):
- """
- A PostScript tokenizer. Yield (token, value) pairs such as
- (cls._whitespace, ' ') or (cls._name, '/Foobar').
- """
- pos = 0
- while pos < len(text):
- match = (cls._comment_re.match(text[pos:]) or
- cls._whitespace_re.match(text[pos:]))
- if match:
- yield (cls._whitespace, match.group())
- pos += match.end()
- elif text[pos] == b'(':
- start = pos
- pos += 1
- depth = 1
- while depth:
- match = cls._instring_re.search(text[pos:])
- if match is None:
- return
- pos += match.end()
- if match.group() == b'(':
- depth += 1
- elif match.group() == b')':
- depth -= 1
- else: # a backslash - skip the next character
- pos += 1
- yield (cls._string, text[start:pos])
- elif text[pos:pos + 2] in (b'<<', b'>>'):
- yield (cls._delimiter, text[pos:pos + 2])
- pos += 2
- elif text[pos] == b'<':
- start = pos
- pos += text[pos:].index(b'>')
- yield (cls._string, text[start:pos])
- else:
- match = cls._token_re.match(text[pos:])
- if match:
- try:
- float(match.group())
- yield (cls._number, match.group())
- except ValueError:
- yield (cls._name, match.group())
- pos += match.end()
- else:
- yield (cls._delimiter, text[pos:pos + 1])
- pos += 1
-
- def _parse(self):
- """
- Find the values of various font properties. This limited kind
- of parsing is described in Chapter 10 "Adobe Type Manager
- Compatibility" of the Type-1 spec.
- """
- # Start with reasonable defaults
- prop = {'weight': 'Regular', 'ItalicAngle': 0.0, 'isFixedPitch': False,
- 'UnderlinePosition': -100, 'UnderlineThickness': 50}
- filtered = ((token, value)
- for token, value in self._tokens(self.parts[0])
- if token is not self._whitespace)
- # The spec calls this an ASCII format; in Python 2.x we could
- # just treat the strings and names as opaque bytes but let's
- # turn them into proper Unicode, and be lenient in case of high bytes.
- convert = lambda x: x.decode('ascii', 'replace')
- for token, value in filtered:
- if token is self._name and value.startswith(b'/'):
- key = convert(value[1:])
- token, value = next(filtered)
- if token is self._name:
- if value in (b'true', b'false'):
- value = value == b'true'
- else:
- value = convert(value.lstrip(b'/'))
- elif token is self._string:
- value = convert(value.lstrip(b'(').rstrip(b')'))
- elif token is self._number:
- if b'.' in value:
- value = float(value)
- else:
- value = int(value)
- else: # more complicated value such as an array
- value = None
- if key != 'FontInfo' and value is not None:
- prop[key] = value
-
- # Fill in the various *Name properties
- if 'FontName' not in prop:
- prop['FontName'] = (prop.get('FullName') or
- prop.get('FamilyName') or
- 'Unknown')
- if 'FullName' not in prop:
- prop['FullName'] = prop['FontName']
- if 'FamilyName' not in prop:
- extras = ('(?i)([ -](regular|plain|italic|oblique|(semi)?bold|'
- '(ultra)?light|extra|condensed))+$')
- prop['FamilyName'] = re.sub(extras, '', prop['FullName'])
-
- self.prop = prop
-
- @classmethod
- def _transformer(cls, tokens, slant, extend):
- def fontname(name):
- result = name
- if slant:
- result += b'_Slant_' + str(int(1000 * slant)).encode('ascii')
- if extend != 1.0:
- result += b'_Extend_' + str(int(1000 * extend)).encode('ascii')
- return result
-
- def italicangle(angle):
- return (str(float(angle) - np.arctan(slant) / np.pi * 180)
- .encode('ascii'))
-
- def fontmatrix(array):
- array = array.lstrip(b'[').rstrip(b']').split()
- array = [float(x) for x in array]
- oldmatrix = np.eye(3, 3)
- oldmatrix[0:3, 0] = array[::2]
- oldmatrix[0:3, 1] = array[1::2]
- modifier = np.array([[extend, 0, 0],
- [slant, 1, 0],
- [0, 0, 1]])
- newmatrix = np.dot(modifier, oldmatrix)
- array[::2] = newmatrix[0:3, 0]
- array[1::2] = newmatrix[0:3, 1]
- as_string = u'[' + u' '.join(str(x) for x in array) + u']'
- return as_string.encode('latin-1')
-
- def replace(fun):
- def replacer(tokens):
- token, value = next(tokens) # name, e.g., /FontMatrix
- yield bytes(value)
- token, value = next(tokens) # possible whitespace
- while token is cls._whitespace:
- yield bytes(value)
- token, value = next(tokens)
- if value != b'[': # name/number/etc.
- yield bytes(fun(value))
- else: # array, e.g., [1 2 3]
- result = b''
- while value != b']':
- result += value
- token, value = next(tokens)
- result += value
- yield fun(result)
- return replacer
-
- def suppress(tokens):
- for x in itertools.takewhile(lambda x: x[1] != b'def', tokens):
- pass
- yield b''
-
- table = {b'/FontName': replace(fontname),
- b'/ItalicAngle': replace(italicangle),
- b'/FontMatrix': replace(fontmatrix),
- b'/UniqueID': suppress}
-
- for token, value in tokens:
- if token is cls._name and value in table:
- for value in table[value](itertools.chain([(token, value)],
- tokens)):
- yield value
- else:
- yield value
-
- def transform(self, effects):
- """
- Transform the font by slanting or extending. *effects* should
- be a dict where ``effects['slant']`` is the tangent of the
- angle that the font is to be slanted to the right (so negative
- values slant to the left) and ``effects['extend']`` is the
- multiplier by which the font is to be extended (so values less
- than 1.0 condense). Returns a new :class:`Type1Font` object.
- """
- with io.BytesIO() as buffer:
- tokenizer = self._tokens(self.parts[0])
- transformed = self._transformer(tokenizer,
- slant=effects.get('slant', 0.0),
- extend=effects.get('extend', 1.0))
- list(map(buffer.write, transformed))
- return Type1Font((buffer.getvalue(), self.parts[1], self.parts[2]))
diff --git a/contrib/python/matplotlib/py2/matplotlib/units.py b/contrib/python/matplotlib/py2/matplotlib/units.py
deleted file mode 100644
index 6e0a0b78d2..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/units.py
+++ /dev/null
@@ -1,200 +0,0 @@
-"""
-The classes here provide support for using custom classes with
-Matplotlib, e.g., those that do not expose the array interface but know
-how to convert themselves to arrays. It also supports classes with
-units and units conversion. Use cases include converters for custom
-objects, e.g., a list of datetime objects, as well as for objects that
-are unit aware. We don't assume any particular units implementation;
-rather a units implementation must provide the register with the Registry
-converter dictionary and a `ConversionInterface`. For example,
-here is a complete implementation which supports plotting with native
-datetime objects::
-
- import matplotlib.units as units
- import matplotlib.dates as dates
- import matplotlib.ticker as ticker
- import datetime
-
- class DateConverter(units.ConversionInterface):
-
- @staticmethod
- def convert(value, unit, axis):
- 'Convert a datetime value to a scalar or array'
- return dates.date2num(value)
-
- @staticmethod
- def axisinfo(unit, axis):
- 'Return major and minor tick locators and formatters'
- if unit!='date': return None
- majloc = dates.AutoDateLocator()
- majfmt = dates.AutoDateFormatter(majloc)
- return AxisInfo(majloc=majloc,
- majfmt=majfmt,
- label='date')
-
- @staticmethod
- def default_units(x, axis):
- 'Return the default unit for x or None'
- return 'date'
-
- # Finally we register our object type with the Matplotlib units registry.
- units.registry[datetime.date] = DateConverter()
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-
-import six
-from matplotlib.cbook import iterable, is_numlike, safe_first_element
-import numpy as np
-
-
-class AxisInfo(object):
- """
- Information to support default axis labeling, tick labeling, and
- default limits. An instance of this class must be returned by
- :meth:`ConversionInterface.axisinfo`.
- """
- def __init__(self, majloc=None, minloc=None,
- majfmt=None, minfmt=None, label=None,
- default_limits=None):
- """
- Parameters
- ----------
- majloc, minloc : Locator, optional
- Tick locators for the major and minor ticks.
- majfmt, minfmt : Formatter, optional
- Tick formatters for the major and minor ticks.
- label : str, optional
- The default axis label.
- default_limits : optional
- The default min and max limits of the axis if no data has
- been plotted.
-
- Notes
- -----
- If any of the above are ``None``, the axis will simply use the
- default value.
- """
- self.majloc = majloc
- self.minloc = minloc
- self.majfmt = majfmt
- self.minfmt = minfmt
- self.label = label
- self.default_limits = default_limits
-
-
-class ConversionInterface(object):
- """
- The minimal interface for a converter to take custom data types (or
- sequences) and convert them to values Matplotlib can use.
- """
- @staticmethod
- def axisinfo(unit, axis):
- """
- Return an `~units.AxisInfo` instance for the axis with the
- specified units.
- """
- return None
-
- @staticmethod
- def default_units(x, axis):
- """
- Return the default unit for *x* or ``None`` for the given axis.
- """
- return None
-
- @staticmethod
- def convert(obj, unit, axis):
- """
- Convert *obj* using *unit* for the specified *axis*.
- If *obj* is a sequence, return the converted sequence.
- The output must be a sequence of scalars that can be used by the numpy
- array layer.
- """
- return obj
-
- @staticmethod
- def is_numlike(x):
- """
- The Matplotlib datalim, autoscaling, locators etc work with
- scalars which are the units converted to floats given the
- current unit. The converter may be passed these floats, or
- arrays of them, even when units are set.
- """
- if iterable(x):
- for thisx in x:
- return is_numlike(thisx)
- else:
- return is_numlike(x)
-
-
-class Registry(dict):
- """
- A register that maps types to conversion interfaces.
- """
- def __init__(self):
- dict.__init__(self)
- self._cached = {}
-
- def get_converter(self, x):
- """
- Get the converter for data that has the same type as *x*. If no
- converters are registered for *x*, returns ``None``.
- """
-
- if not len(self):
- return None # nothing registered
- # DISABLED idx = id(x)
- # DISABLED cached = self._cached.get(idx)
- # DISABLED if cached is not None: return cached
-
- converter = None
- classx = getattr(x, '__class__', None)
-
- if classx is not None:
- converter = self.get(classx)
-
- if converter is None and hasattr(x, "values"):
- # this unpacks pandas series or dataframes...
- x = x.values
-
- # If x is an array, look inside the array for data with units
- if isinstance(x, np.ndarray) and x.size:
- xravel = x.ravel()
- try:
- # pass the first value of x that is not masked back to
- # get_converter
- if not np.all(xravel.mask):
- # some elements are not masked
- converter = self.get_converter(
- xravel[np.argmin(xravel.mask)])
- return converter
- except AttributeError:
- # not a masked_array
- # Make sure we don't recurse forever -- it's possible for
- # ndarray subclasses to continue to return subclasses and
- # not ever return a non-subclass for a single element.
- next_item = xravel[0]
- if (not isinstance(next_item, np.ndarray) or
- next_item.shape != x.shape):
- converter = self.get_converter(next_item)
- return converter
-
- # If we haven't found a converter yet, try to get the first element
- if converter is None:
- try:
- thisx = safe_first_element(x)
- except (TypeError, StopIteration):
- pass
- else:
- if classx and classx != getattr(thisx, '__class__', None):
- converter = self.get_converter(thisx)
- return converter
-
- # DISABLED self._cached[idx] = converter
- return converter
-
-
-registry = Registry()
diff --git a/contrib/python/matplotlib/py2/matplotlib/widgets.py b/contrib/python/matplotlib/py2/matplotlib/widgets.py
deleted file mode 100644
index 0563964da6..0000000000
--- a/contrib/python/matplotlib/py2/matplotlib/widgets.py
+++ /dev/null
@@ -1,2818 +0,0 @@
-"""
-GUI neutral widgets
-===================
-
-Widgets that are designed to work for any of the GUI backends.
-All of these widgets require you to predefine a :class:`matplotlib.axes.Axes`
-instance and pass that as the first arg. matplotlib doesn't try to
-be too smart with respect to layout -- you will have to figure out how
-wide and tall you want your Axes to be to accommodate your widget.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import copy
-import six
-from six.moves import zip
-
-import numpy as np
-from matplotlib import rcParams
-
-from .patches import Circle, Rectangle, Ellipse
-from .lines import Line2D
-from .transforms import blended_transform_factory
-
-
-class LockDraw(object):
- """
- Some widgets, like the cursor, draw onto the canvas, and this is not
- desirable under all circumstances, like when the toolbar is in
- zoom-to-rect mode and drawing a rectangle. The module level "lock"
- allows someone to grab the lock and prevent other widgets from
- drawing. Use ``matplotlib.widgets.lock(someobj)`` to prevent
- other widgets from drawing while you're interacting with the canvas.
- """
-
- def __init__(self):
- self._owner = None
-
- def __call__(self, o):
- """reserve the lock for *o*"""
- if not self.available(o):
- raise ValueError('already locked')
- self._owner = o
-
- def release(self, o):
- """release the lock"""
- if not self.available(o):
- raise ValueError('you do not own this lock')
- self._owner = None
-
- def available(self, o):
- """drawing is available to *o*"""
- return not self.locked() or self.isowner(o)
-
- def isowner(self, o):
- """Return True if *o* owns this lock"""
- return self._owner is o
-
- def locked(self):
- """Return True if the lock is currently held by an owner"""
- return self._owner is not None
-
-
-class Widget(object):
- """
- Abstract base class for GUI neutral widgets
- """
- drawon = True
- eventson = True
- _active = True
-
- def set_active(self, active):
- """Set whether the widget is active.
- """
- self._active = active
-
- def get_active(self):
- """Get whether the widget is active.
- """
- return self._active
-
- # set_active is overridden by SelectorWidgets.
- active = property(get_active, lambda self, active: self.set_active(active),
- doc="Is the widget active?")
-
- def ignore(self, event):
- """Return True if event should be ignored.
-
- This method (or a version of it) should be called at the beginning
- of any event callback.
- """
- return not self.active
-
-
-class AxesWidget(Widget):
- """Widget that is connected to a single
- :class:`~matplotlib.axes.Axes`.
-
- To guarantee that the widget remains responsive and not garbage-collected,
- a reference to the object should be maintained by the user.
-
- This is necessary because the callback registry
- maintains only weak-refs to the functions, which are member
- functions of the widget. If there are no references to the widget
- object it may be garbage collected which will disconnect the
- callbacks.
-
- Attributes:
-
- *ax* : :class:`~matplotlib.axes.Axes`
- The parent axes for the widget
- *canvas* : :class:`~matplotlib.backend_bases.FigureCanvasBase` subclass
- The parent figure canvas for the widget.
- *active* : bool
- If False, the widget does not respond to events.
- """
- def __init__(self, ax):
- self.ax = ax
- self.canvas = ax.figure.canvas
- self.cids = []
-
- def connect_event(self, event, callback):
- """Connect callback with an event.
-
- This should be used in lieu of `figure.canvas.mpl_connect` since this
- function stores callback ids for later clean up.
- """
- cid = self.canvas.mpl_connect(event, callback)
- self.cids.append(cid)
-
- def disconnect_events(self):
- """Disconnect all events created by this widget."""
- for c in self.cids:
- self.canvas.mpl_disconnect(c)
-
-
-class Button(AxesWidget):
- """
- A GUI neutral button.
-
- For the button to remain responsive you must keep a reference to it.
- Call :meth:`on_clicked` to connect to the button.
-
- Attributes
- ----------
- ax :
- The :class:`matplotlib.axes.Axes` the button renders into.
- label :
- A :class:`matplotlib.text.Text` instance.
- color :
- The color of the button when not hovering.
- hovercolor :
- The color of the button when hovering.
- """
-
- def __init__(self, ax, label, image=None,
- color='0.85', hovercolor='0.95'):
- """
- Parameters
- ----------
- ax : matplotlib.axes.Axes
- The :class:`matplotlib.axes.Axes` instance the button
- will be placed into.
-
- label : str
- The button text. Accepts string.
-
- image : array, mpl image, Pillow Image
- The image to place in the button, if not *None*.
- Can be any legal arg to imshow (numpy array,
- matplotlib Image instance, or Pillow Image).
-
- color : color
- The color of the button when not activated
-
- hovercolor : color
- The color of the button when the mouse is over it
- """
- AxesWidget.__init__(self, ax)
-
- if image is not None:
- ax.imshow(image)
- self.label = ax.text(0.5, 0.5, label,
- verticalalignment='center',
- horizontalalignment='center',
- transform=ax.transAxes)
-
- self.cnt = 0
- self.observers = {}
-
- self.connect_event('button_press_event', self._click)
- self.connect_event('button_release_event', self._release)
- self.connect_event('motion_notify_event', self._motion)
- ax.set_navigate(False)
- ax.set_facecolor(color)
- ax.set_xticks([])
- ax.set_yticks([])
- self.color = color
- self.hovercolor = hovercolor
-
- self._lastcolor = color
-
- def _click(self, event):
- if self.ignore(event):
- return
- if event.inaxes != self.ax:
- return
- if not self.eventson:
- return
- if event.canvas.mouse_grabber != self.ax:
- event.canvas.grab_mouse(self.ax)
-
- def _release(self, event):
- if self.ignore(event):
- return
- if event.canvas.mouse_grabber != self.ax:
- return
- event.canvas.release_mouse(self.ax)
- if not self.eventson:
- return
- if event.inaxes != self.ax:
- return
- for cid, func in six.iteritems(self.observers):
- func(event)
-
- def _motion(self, event):
- if self.ignore(event):
- return
- if event.inaxes == self.ax:
- c = self.hovercolor
- else:
- c = self.color
- if c != self._lastcolor:
- self.ax.set_facecolor(c)
- self._lastcolor = c
- if self.drawon:
- self.ax.figure.canvas.draw()
-
- def on_clicked(self, func):
- """
- When the button is clicked, call this *func* with event.
-
- A connection id is returned. It can be used to disconnect
- the button from its callback.
- """
- cid = self.cnt
- self.observers[cid] = func
- self.cnt += 1
- return cid
-
- def disconnect(self, cid):
- """remove the observer with connection id *cid*"""
- try:
- del self.observers[cid]
- except KeyError:
- pass
-
-
-class Slider(AxesWidget):
- """
- A slider representing a floating point range.
-
- Create a slider from *valmin* to *valmax* in axes *ax*. For the slider to
- remain responsive you must maintain a reference to it. Call
- :meth:`on_changed` to connect to the slider event.
-
- Attributes
- ----------
- val : float
- Slider value.
- """
- def __init__(self, ax, label, valmin, valmax, valinit=0.5, valfmt='%1.2f',
- closedmin=True, closedmax=True, slidermin=None,
- slidermax=None, dragging=True, valstep=None, **kwargs):
- """
- Parameters
- ----------
- ax : Axes
- The Axes to put the slider in.
-
- label : str
- Slider label.
-
- valmin : float
- The minimum value of the slider.
-
- valmax : float
- The maximum value of the slider.
-
- valinit : float, optional, default: 0.5
- The slider initial position.
-
- valfmt : str, optional, default: "%1.2f"
- Used to format the slider value, fprint format string.
-
- closedmin : bool, optional, default: True
- Indicate whether the slider interval is closed on the bottom.
-
- closedmax : bool, optional, default: True
- Indicate whether the slider interval is closed on the top.
-
- slidermin : Slider, optional, default: None
- Do not allow the current slider to have a value less than
- the value of the Slider `slidermin`.
-
- slidermax : Slider, optional, default: None
- Do not allow the current slider to have a value greater than
- the value of the Slider `slidermax`.
-
- dragging : bool, optional, default: True
- If True the slider can be dragged by the mouse.
-
- valstep : float, optional, default: None
- If given, the slider will snap to multiples of `valstep`.
-
- Notes
- -----
- Additional kwargs are passed on to ``self.poly`` which is the
- :class:`~matplotlib.patches.Rectangle` that draws the slider
- knob. See the :class:`~matplotlib.patches.Rectangle` documentation for
- valid property names (e.g., `facecolor`, `edgecolor`, `alpha`).
- """
- AxesWidget.__init__(self, ax)
-
- if slidermin is not None and not hasattr(slidermin, 'val'):
- raise ValueError("Argument slidermin ({}) has no 'val'"
- .format(type(slidermin)))
- if slidermax is not None and not hasattr(slidermax, 'val'):
- raise ValueError("Argument slidermax ({}) has no 'val'"
- .format(type(slidermax)))
- self.closedmin = closedmin
- self.closedmax = closedmax
- self.slidermin = slidermin
- self.slidermax = slidermax
- self.drag_active = False
- self.valmin = valmin
- self.valmax = valmax
- self.valstep = valstep
- valinit = self._value_in_bounds(valinit)
- if valinit is None:
- valinit = valmin
- self.val = valinit
- self.valinit = valinit
- self.poly = ax.axvspan(valmin, valinit, 0, 1, **kwargs)
- self.vline = ax.axvline(valinit, 0, 1, color='r', lw=1)
-
- self.valfmt = valfmt
- ax.set_yticks([])
- ax.set_xlim((valmin, valmax))
- ax.set_xticks([])
- ax.set_navigate(False)
-
- self.connect_event('button_press_event', self._update)
- self.connect_event('button_release_event', self._update)
- if dragging:
- self.connect_event('motion_notify_event', self._update)
- self.label = ax.text(-0.02, 0.5, label, transform=ax.transAxes,
- verticalalignment='center',
- horizontalalignment='right')
-
- self.valtext = ax.text(1.02, 0.5, valfmt % valinit,
- transform=ax.transAxes,
- verticalalignment='center',
- horizontalalignment='left')
-
- self.cnt = 0
- self.observers = {}
-
- self.set_val(valinit)
-
- def _value_in_bounds(self, val):
- """ Makes sure self.val is with given bounds."""
- if self.valstep:
- val = np.round((val - self.valmin)/self.valstep)*self.valstep
- val += self.valmin
-
- if val <= self.valmin:
- if not self.closedmin:
- return
- val = self.valmin
- elif val >= self.valmax:
- if not self.closedmax:
- return
- val = self.valmax
-
- if self.slidermin is not None and val <= self.slidermin.val:
- if not self.closedmin:
- return
- val = self.slidermin.val
-
- if self.slidermax is not None and val >= self.slidermax.val:
- if not self.closedmax:
- return
- val = self.slidermax.val
- return val
-
- def _update(self, event):
- """update the slider position"""
- if self.ignore(event):
- return
-
- if event.button != 1:
- return
-
- if event.name == 'button_press_event' and event.inaxes == self.ax:
- self.drag_active = True
- event.canvas.grab_mouse(self.ax)
-
- if not self.drag_active:
- return
-
- elif ((event.name == 'button_release_event') or
- (event.name == 'button_press_event' and
- event.inaxes != self.ax)):
- self.drag_active = False
- event.canvas.release_mouse(self.ax)
- return
- val = self._value_in_bounds(event.xdata)
- if (val is not None) and (val != self.val):
- self.set_val(val)
-
- def set_val(self, val):
- """
- Set slider value to *val*
-
- Parameters
- ----------
- val : float
- """
- xy = self.poly.xy
- xy[2] = val, 1
- xy[3] = val, 0
- self.poly.xy = xy
- self.valtext.set_text(self.valfmt % val)
- if self.drawon:
- self.ax.figure.canvas.draw_idle()
- self.val = val
- if not self.eventson:
- return
- for cid, func in six.iteritems(self.observers):
- func(val)
-
- def on_changed(self, func):
- """
- When the slider value is changed call *func* with the new
- slider value
-
- Parameters
- ----------
- func : callable
- Function to call when slider is changed.
- The function must accept a single float as its arguments.
-
- Returns
- -------
- cid : int
- Connection id (which can be used to disconnect *func*)
- """
- cid = self.cnt
- self.observers[cid] = func
- self.cnt += 1
- return cid
-
- def disconnect(self, cid):
- """
- Remove the observer with connection id *cid*
-
- Parameters
- ----------
- cid : int
- Connection id of the observer to be removed
- """
- try:
- del self.observers[cid]
- except KeyError:
- pass
-
- def reset(self):
- """Reset the slider to the initial value"""
- if (self.val != self.valinit):
- self.set_val(self.valinit)
-
-
-class CheckButtons(AxesWidget):
- """
- A GUI neutral set of check buttons.
-
- For the check buttons to remain responsive you must keep a
- reference to this object.
-
- The following attributes are exposed
-
- *ax*
- The :class:`matplotlib.axes.Axes` instance the buttons are
- located in
-
- *labels*
- List of :class:`matplotlib.text.Text` instances
-
- *lines*
- List of (line1, line2) tuples for the x's in the check boxes.
- These lines exist for each box, but have ``set_visible(False)``
- when its box is not checked.
-
- *rectangles*
- List of :class:`matplotlib.patches.Rectangle` instances
-
- Connect to the CheckButtons with the :meth:`on_clicked` method
- """
- def __init__(self, ax, labels, actives):
- """
- Add check buttons to :class:`matplotlib.axes.Axes` instance *ax*
-
- *labels*
- A len(buttons) list of labels as strings
-
- *actives*
- A len(buttons) list of booleans indicating whether
- the button is active
- """
- AxesWidget.__init__(self, ax)
-
- ax.set_xticks([])
- ax.set_yticks([])
- ax.set_navigate(False)
-
- if len(labels) > 1:
- dy = 1. / (len(labels) + 1)
- ys = np.linspace(1 - dy, dy, len(labels))
- else:
- dy = 0.25
- ys = [0.5]
-
- cnt = 0
- axcolor = ax.get_facecolor()
-
- self.labels = []
- self.lines = []
- self.rectangles = []
-
- lineparams = {'color': 'k', 'linewidth': 1.25,
- 'transform': ax.transAxes, 'solid_capstyle': 'butt'}
- for y, label in zip(ys, labels):
- t = ax.text(0.25, y, label, transform=ax.transAxes,
- horizontalalignment='left',
- verticalalignment='center')
-
- w, h = dy / 2., dy / 2.
- x, y = 0.05, y - h / 2.
-
- p = Rectangle(xy=(x, y), width=w, height=h, edgecolor='black',
- facecolor=axcolor, transform=ax.transAxes)
-
- l1 = Line2D([x, x + w], [y + h, y], **lineparams)
- l2 = Line2D([x, x + w], [y, y + h], **lineparams)
-
- l1.set_visible(actives[cnt])
- l2.set_visible(actives[cnt])
- self.labels.append(t)
- self.rectangles.append(p)
- self.lines.append((l1, l2))
- ax.add_patch(p)
- ax.add_line(l1)
- ax.add_line(l2)
- cnt += 1
-
- self.connect_event('button_press_event', self._clicked)
-
- self.cnt = 0
- self.observers = {}
-
- def _clicked(self, event):
- if self.ignore(event):
- return
- if event.button != 1:
- return
- if event.inaxes != self.ax:
- return
-
- for i, (p, t) in enumerate(zip(self.rectangles, self.labels)):
- if (t.get_window_extent().contains(event.x, event.y) or
- p.get_window_extent().contains(event.x, event.y)):
- self.set_active(i)
- break
- else:
- return
-
- def set_active(self, index):
- """
- Directly (de)activate a check button by index.
-
- *index* is an index into the original label list
- that this object was constructed with.
- Raises ValueError if *index* is invalid.
-
- Callbacks will be triggered if :attr:`eventson` is True.
-
- """
- if 0 > index >= len(self.labels):
- raise ValueError("Invalid CheckButton index: %d" % index)
-
- l1, l2 = self.lines[index]
- l1.set_visible(not l1.get_visible())
- l2.set_visible(not l2.get_visible())
-
- if self.drawon:
- self.ax.figure.canvas.draw()
-
- if not self.eventson:
- return
- for cid, func in six.iteritems(self.observers):
- func(self.labels[index].get_text())
-
- def get_status(self):
- """
- returns a tuple of the status (True/False) of all of the check buttons
- """
- return [l1.get_visible() for (l1, l2) in self.lines]
-
- def on_clicked(self, func):
- """
- When the button is clicked, call *func* with button label
-
- A connection id is returned which can be used to disconnect
- """
- cid = self.cnt
- self.observers[cid] = func
- self.cnt += 1
- return cid
-
- def disconnect(self, cid):
- """remove the observer with connection id *cid*"""
- try:
- del self.observers[cid]
- except KeyError:
- pass
-
-
-class TextBox(AxesWidget):
- """
- A GUI neutral text input box.
-
- For the text box to remain responsive you must keep a reference to it.
-
- The following attributes are accessible:
-
- *ax*
- The :class:`matplotlib.axes.Axes` the button renders into.
-
- *label*
- A :class:`matplotlib.text.Text` instance.
-
- *color*
- The color of the text box when not hovering.
-
- *hovercolor*
- The color of the text box when hovering.
-
- Call :meth:`on_text_change` to be updated whenever the text changes.
-
- Call :meth:`on_submit` to be updated whenever the user hits enter or
- leaves the text entry field.
- """
-
- def __init__(self, ax, label, initial='',
- color='.95', hovercolor='1', label_pad=.01):
- """
- Parameters
- ----------
- ax : matplotlib.axes.Axes
- The :class:`matplotlib.axes.Axes` instance the button
- will be placed into.
-
- label : str
- Label for this text box. Accepts string.
-
- initial : str
- Initial value in the text box
-
- color : color
- The color of the box
-
- hovercolor : color
- The color of the box when the mouse is over it
-
- label_pad : float
- the distance between the label and the right side of the textbox
- """
- AxesWidget.__init__(self, ax)
-
- self.DIST_FROM_LEFT = .05
-
- self.params_to_disable = [key for key in rcParams if u'keymap' in key]
-
- self.text = initial
- self.label = ax.text(-label_pad, 0.5, label,
- verticalalignment='center',
- horizontalalignment='right',
- transform=ax.transAxes)
- self.text_disp = self._make_text_disp(self.text)
-
- self.cnt = 0
- self.change_observers = {}
- self.submit_observers = {}
-
- # If these lines are removed, the cursor won't appear the first
- # time the box is clicked:
- self.ax.set_xlim(0, 1)
- self.ax.set_ylim(0, 1)
-
- self.cursor_index = 0
-
- # Because this is initialized, _render_cursor
- # can assume that cursor exists.
- self.cursor = self.ax.vlines(0, 0, 0)
- self.cursor.set_visible(False)
-
- self.connect_event('button_press_event', self._click)
- self.connect_event('button_release_event', self._release)
- self.connect_event('motion_notify_event', self._motion)
- self.connect_event('key_press_event', self._keypress)
- self.connect_event('resize_event', self._resize)
- ax.set_navigate(False)
- ax.set_facecolor(color)
- ax.set_xticks([])
- ax.set_yticks([])
- self.color = color
- self.hovercolor = hovercolor
-
- self._lastcolor = color
-
- self.capturekeystrokes = False
-
- def _make_text_disp(self, string):
- return self.ax.text(self.DIST_FROM_LEFT, 0.5, string,
- verticalalignment='center',
- horizontalalignment='left',
- transform=self.ax.transAxes)
-
- def _rendercursor(self):
- # this is a hack to figure out where the cursor should go.
- # we draw the text up to where the cursor should go, measure
- # and save its dimensions, draw the real text, then put the cursor
- # at the saved dimensions
-
- widthtext = self.text[:self.cursor_index]
- no_text = False
- if(widthtext == "" or widthtext == " " or widthtext == " "):
- no_text = widthtext == ""
- widthtext = ","
-
- wt_disp = self._make_text_disp(widthtext)
-
- self.ax.figure.canvas.draw()
- bb = wt_disp.get_window_extent()
- inv = self.ax.transData.inverted()
- bb = inv.transform(bb)
- wt_disp.set_visible(False)
- if no_text:
- bb[1, 0] = bb[0, 0]
- # hack done
- self.cursor.set_visible(False)
-
- self.cursor = self.ax.vlines(bb[1, 0], bb[0, 1], bb[1, 1])
- self.ax.figure.canvas.draw()
-
- def _notify_submit_observers(self):
- for cid, func in six.iteritems(self.submit_observers):
- func(self.text)
-
- def _release(self, event):
- if self.ignore(event):
- return
- if event.canvas.mouse_grabber != self.ax:
- return
- event.canvas.release_mouse(self.ax)
-
- def _keypress(self, event):
- if self.ignore(event):
- return
- if self.capturekeystrokes:
- key = event.key
-
- if(len(key) == 1):
- self.text = (self.text[:self.cursor_index] + key +
- self.text[self.cursor_index:])
- self.cursor_index += 1
- elif key == "right":
- if self.cursor_index != len(self.text):
- self.cursor_index += 1
- elif key == "left":
- if self.cursor_index != 0:
- self.cursor_index -= 1
- elif key == "home":
- self.cursor_index = 0
- elif key == "end":
- self.cursor_index = len(self.text)
- elif(key == "backspace"):
- if self.cursor_index != 0:
- self.text = (self.text[:self.cursor_index - 1] +
- self.text[self.cursor_index:])
- self.cursor_index -= 1
- elif(key == "delete"):
- if self.cursor_index != len(self.text):
- self.text = (self.text[:self.cursor_index] +
- self.text[self.cursor_index + 1:])
-
- self.text_disp.remove()
- self.text_disp = self._make_text_disp(self.text)
- self._rendercursor()
- self._notify_change_observers()
- if key == "enter":
- self._notify_submit_observers()
-
- def set_val(self, val):
- newval = str(val)
- if self.text == newval:
- return
- self.text = newval
- self.text_disp.remove()
- self.text_disp = self._make_text_disp(self.text)
- self._rendercursor()
- self._notify_change_observers()
- self._notify_submit_observers()
-
- def _notify_change_observers(self):
- for cid, func in six.iteritems(self.change_observers):
- func(self.text)
-
- def begin_typing(self, x):
- self.capturekeystrokes = True
- # disable command keys so that the user can type without
- # command keys causing figure to be saved, etc
- self.reset_params = {}
- for key in self.params_to_disable:
- self.reset_params[key] = rcParams[key]
- rcParams[key] = []
-
- def stop_typing(self):
- notifysubmit = False
- # because _notify_submit_users might throw an error in the
- # user's code, we only want to call it once we've already done
- # our cleanup.
- if self.capturekeystrokes:
- # since the user is no longer typing,
- # reactivate the standard command keys
- for key in self.params_to_disable:
- rcParams[key] = self.reset_params[key]
- notifysubmit = True
- self.capturekeystrokes = False
- self.cursor.set_visible(False)
- self.ax.figure.canvas.draw()
- if notifysubmit:
- self._notify_submit_observers()
-
- def position_cursor(self, x):
- # now, we have to figure out where the cursor goes.
- # approximate it based on assuming all characters the same length
- if len(self.text) == 0:
- self.cursor_index = 0
- else:
- bb = self.text_disp.get_window_extent()
-
- trans = self.ax.transData
- inv = self.ax.transData.inverted()
- bb = trans.transform(inv.transform(bb))
-
- text_start = bb[0, 0]
- text_end = bb[1, 0]
-
- ratio = (x - text_start) / (text_end - text_start)
-
- if ratio < 0:
- ratio = 0
- if ratio > 1:
- ratio = 1
-
- self.cursor_index = int(len(self.text) * ratio)
-
- self._rendercursor()
-
- def _click(self, event):
- if self.ignore(event):
- return
- if event.inaxes != self.ax:
- self.stop_typing()
- return
- if not self.eventson:
- return
- if event.canvas.mouse_grabber != self.ax:
- event.canvas.grab_mouse(self.ax)
- if not self.capturekeystrokes:
- self.begin_typing(event.x)
- self.position_cursor(event.x)
-
- def _resize(self, event):
- self.stop_typing()
-
- def _motion(self, event):
- if self.ignore(event):
- return
- if event.inaxes == self.ax:
- c = self.hovercolor
- else:
- c = self.color
- if c != self._lastcolor:
- self.ax.set_facecolor(c)
- self._lastcolor = c
- if self.drawon:
- self.ax.figure.canvas.draw()
-
- def on_text_change(self, func):
- """
- When the text changes, call this *func* with event.
-
- A connection id is returned which can be used to disconnect.
- """
- cid = self.cnt
- self.change_observers[cid] = func
- self.cnt += 1
- return cid
-
- def on_submit(self, func):
- """
- When the user hits enter or leaves the submision box, call this
- *func* with event.
-
- A connection id is returned which can be used to disconnect.
- """
- cid = self.cnt
- self.submit_observers[cid] = func
- self.cnt += 1
- return cid
-
- def disconnect(self, cid):
- """remove the observer with connection id *cid*"""
- for reg in (self.change_observers, self.submit_observers):
- try:
- del reg[cid]
- except KeyError:
- pass
-
-
-class RadioButtons(AxesWidget):
- """
- A GUI neutral radio button.
-
- For the buttons to remain responsive
- you must keep a reference to this object.
-
- The following attributes are exposed:
-
- *ax*
- The :class:`matplotlib.axes.Axes` instance the buttons are in
-
- *activecolor*
- The color of the button when clicked
-
- *labels*
- A list of :class:`matplotlib.text.Text` instances
-
- *circles*
- A list of :class:`matplotlib.patches.Circle` instances
-
- *value_selected*
- A string listing the current value selected
-
- Connect to the RadioButtons with the :meth:`on_clicked` method
- """
- def __init__(self, ax, labels, active=0, activecolor='blue'):
- """
- Add radio buttons to :class:`matplotlib.axes.Axes` instance *ax*
-
- *labels*
- A len(buttons) list of labels as strings
-
- *active*
- The index into labels for the button that is active
-
- *activecolor*
- The color of the button when clicked
- """
- AxesWidget.__init__(self, ax)
- self.activecolor = activecolor
- self.value_selected = None
-
- ax.set_xticks([])
- ax.set_yticks([])
- ax.set_navigate(False)
- dy = 1. / (len(labels) + 1)
- ys = np.linspace(1 - dy, dy, len(labels))
- cnt = 0
- axcolor = ax.get_facecolor()
-
- self.labels = []
- self.circles = []
- for y, label in zip(ys, labels):
- t = ax.text(0.25, y, label, transform=ax.transAxes,
- horizontalalignment='left',
- verticalalignment='center')
-
- if cnt == active:
- self.value_selected = label
- facecolor = activecolor
- else:
- facecolor = axcolor
-
- p = Circle(xy=(0.15, y), radius=0.05, edgecolor='black',
- facecolor=facecolor, transform=ax.transAxes)
-
- self.labels.append(t)
- self.circles.append(p)
- ax.add_patch(p)
- cnt += 1
-
- self.connect_event('button_press_event', self._clicked)
-
- self.cnt = 0
- self.observers = {}
-
- def _clicked(self, event):
- if self.ignore(event):
- return
- if event.button != 1:
- return
- if event.inaxes != self.ax:
- return
- xy = self.ax.transAxes.inverted().transform_point((event.x, event.y))
- pclicked = np.array([xy[0], xy[1]])
-
- def inside(p):
- pcirc = np.array([p.center[0], p.center[1]])
- d = pclicked - pcirc
- return np.sqrt(np.dot(d, d)) < p.radius
-
- for i, (p, t) in enumerate(zip(self.circles, self.labels)):
- if t.get_window_extent().contains(event.x, event.y) or inside(p):
- self.set_active(i)
- break
- else:
- return
-
- def set_active(self, index):
- """
- Trigger which radio button to make active.
-
- *index* is an index into the original label list
- that this object was constructed with.
- Raise ValueError if the index is invalid.
-
- Callbacks will be triggered if :attr:`eventson` is True.
-
- """
- if 0 > index >= len(self.labels):
- raise ValueError("Invalid RadioButton index: %d" % index)
-
- self.value_selected = self.labels[index].get_text()
-
- for i, p in enumerate(self.circles):
- if i == index:
- color = self.activecolor
- else:
- color = self.ax.get_facecolor()
- p.set_facecolor(color)
-
- if self.drawon:
- self.ax.figure.canvas.draw()
-
- if not self.eventson:
- return
- for cid, func in six.iteritems(self.observers):
- func(self.labels[index].get_text())
-
- def on_clicked(self, func):
- """
- When the button is clicked, call *func* with button label
-
- A connection id is returned which can be used to disconnect
- """
- cid = self.cnt
- self.observers[cid] = func
- self.cnt += 1
- return cid
-
- def disconnect(self, cid):
- """remove the observer with connection id *cid*"""
- try:
- del self.observers[cid]
- except KeyError:
- pass
-
-
-class SubplotTool(Widget):
- """
- A tool to adjust the subplot params of a :class:`matplotlib.figure.Figure`.
- """
- def __init__(self, targetfig, toolfig):
- """
- *targetfig*
- The figure instance to adjust.
-
- *toolfig*
- The figure instance to embed the subplot tool into. If
- *None*, a default figure will be created. If you are using
- this from the GUI
- """
- # FIXME: The docstring seems to just abruptly end without...
-
- self.targetfig = targetfig
- toolfig.subplots_adjust(left=0.2, right=0.9)
-
- class toolbarfmt:
- def __init__(self, slider):
- self.slider = slider
-
- def __call__(self, x, y):
- fmt = '%s=%s' % (self.slider.label.get_text(),
- self.slider.valfmt)
- return fmt % x
-
- self.axleft = toolfig.add_subplot(711)
- self.axleft.set_title('Click on slider to adjust subplot param')
- self.axleft.set_navigate(False)
-
- self.sliderleft = Slider(self.axleft, 'left',
- 0, 1, targetfig.subplotpars.left,
- closedmax=False)
- self.sliderleft.on_changed(self.funcleft)
-
- self.axbottom = toolfig.add_subplot(712)
- self.axbottom.set_navigate(False)
- self.sliderbottom = Slider(self.axbottom,
- 'bottom', 0, 1,
- targetfig.subplotpars.bottom,
- closedmax=False)
- self.sliderbottom.on_changed(self.funcbottom)
-
- self.axright = toolfig.add_subplot(713)
- self.axright.set_navigate(False)
- self.sliderright = Slider(self.axright, 'right', 0, 1,
- targetfig.subplotpars.right,
- closedmin=False)
- self.sliderright.on_changed(self.funcright)
-
- self.axtop = toolfig.add_subplot(714)
- self.axtop.set_navigate(False)
- self.slidertop = Slider(self.axtop, 'top', 0, 1,
- targetfig.subplotpars.top,
- closedmin=False)
- self.slidertop.on_changed(self.functop)
-
- self.axwspace = toolfig.add_subplot(715)
- self.axwspace.set_navigate(False)
- self.sliderwspace = Slider(self.axwspace, 'wspace',
- 0, 1, targetfig.subplotpars.wspace,
- closedmax=False)
- self.sliderwspace.on_changed(self.funcwspace)
-
- self.axhspace = toolfig.add_subplot(716)
- self.axhspace.set_navigate(False)
- self.sliderhspace = Slider(self.axhspace, 'hspace',
- 0, 1, targetfig.subplotpars.hspace,
- closedmax=False)
- self.sliderhspace.on_changed(self.funchspace)
-
- # constraints
- self.sliderleft.slidermax = self.sliderright
- self.sliderright.slidermin = self.sliderleft
- self.sliderbottom.slidermax = self.slidertop
- self.slidertop.slidermin = self.sliderbottom
-
- bax = toolfig.add_axes([0.8, 0.05, 0.15, 0.075])
- self.buttonreset = Button(bax, 'Reset')
-
- sliders = (self.sliderleft, self.sliderbottom, self.sliderright,
- self.slidertop, self.sliderwspace, self.sliderhspace,)
-
- def func(event):
- thisdrawon = self.drawon
-
- self.drawon = False
-
- # store the drawon state of each slider
- bs = []
- for slider in sliders:
- bs.append(slider.drawon)
- slider.drawon = False
-
- # reset the slider to the initial position
- for slider in sliders:
- slider.reset()
-
- # reset drawon
- for slider, b in zip(sliders, bs):
- slider.drawon = b
-
- # draw the canvas
- self.drawon = thisdrawon
- if self.drawon:
- toolfig.canvas.draw()
- self.targetfig.canvas.draw()
-
- # during reset there can be a temporary invalid state
- # depending on the order of the reset so we turn off
- # validation for the resetting
- validate = toolfig.subplotpars.validate
- toolfig.subplotpars.validate = False
- self.buttonreset.on_clicked(func)
- toolfig.subplotpars.validate = validate
-
- def funcleft(self, val):
- self.targetfig.subplots_adjust(left=val)
- if self.drawon:
- self.targetfig.canvas.draw()
-
- def funcright(self, val):
- self.targetfig.subplots_adjust(right=val)
- if self.drawon:
- self.targetfig.canvas.draw()
-
- def funcbottom(self, val):
- self.targetfig.subplots_adjust(bottom=val)
- if self.drawon:
- self.targetfig.canvas.draw()
-
- def functop(self, val):
- self.targetfig.subplots_adjust(top=val)
- if self.drawon:
- self.targetfig.canvas.draw()
-
- def funcwspace(self, val):
- self.targetfig.subplots_adjust(wspace=val)
- if self.drawon:
- self.targetfig.canvas.draw()
-
- def funchspace(self, val):
- self.targetfig.subplots_adjust(hspace=val)
- if self.drawon:
- self.targetfig.canvas.draw()
-
-
-class Cursor(AxesWidget):
- """
- A horizontal and vertical line that spans the axes and moves with
- the pointer. You can turn off the hline or vline respectively with
- the following attributes:
-
- *horizOn*
- Controls the visibility of the horizontal line
-
- *vertOn*
- Controls the visibility of the horizontal line
-
- and the visibility of the cursor itself with the *visible* attribute.
-
- For the cursor to remain responsive you must keep a reference to
- it.
- """
- def __init__(self, ax, horizOn=True, vertOn=True, useblit=False,
- **lineprops):
- """
- Add a cursor to *ax*. If ``useblit=True``, use the backend-dependent
- blitting features for faster updates. *lineprops* is a dictionary of
- line properties.
- """
- AxesWidget.__init__(self, ax)
-
- self.connect_event('motion_notify_event', self.onmove)
- self.connect_event('draw_event', self.clear)
-
- self.visible = True
- self.horizOn = horizOn
- self.vertOn = vertOn
- self.useblit = useblit and self.canvas.supports_blit
-
- if self.useblit:
- lineprops['animated'] = True
- self.lineh = ax.axhline(ax.get_ybound()[0], visible=False, **lineprops)
- self.linev = ax.axvline(ax.get_xbound()[0], visible=False, **lineprops)
-
- self.background = None
- self.needclear = False
-
- def clear(self, event):
- """clear the cursor"""
- if self.ignore(event):
- return
- if self.useblit:
- self.background = self.canvas.copy_from_bbox(self.ax.bbox)
- self.linev.set_visible(False)
- self.lineh.set_visible(False)
-
- def onmove(self, event):
- """on mouse motion draw the cursor if visible"""
- if self.ignore(event):
- return
- if not self.canvas.widgetlock.available(self):
- return
- if event.inaxes != self.ax:
- self.linev.set_visible(False)
- self.lineh.set_visible(False)
-
- if self.needclear:
- self.canvas.draw()
- self.needclear = False
- return
- self.needclear = True
- if not self.visible:
- return
- self.linev.set_xdata((event.xdata, event.xdata))
-
- self.lineh.set_ydata((event.ydata, event.ydata))
- self.linev.set_visible(self.visible and self.vertOn)
- self.lineh.set_visible(self.visible and self.horizOn)
-
- self._update()
-
- def _update(self):
-
- if self.useblit:
- if self.background is not None:
- self.canvas.restore_region(self.background)
- self.ax.draw_artist(self.linev)
- self.ax.draw_artist(self.lineh)
- self.canvas.blit(self.ax.bbox)
- else:
-
- self.canvas.draw_idle()
-
- return False
-
-
-class MultiCursor(Widget):
- """
- Provide a vertical (default) and/or horizontal line cursor shared between
- multiple axes.
-
- For the cursor to remain responsive you must keep a reference to
- it.
-
- Example usage::
-
- from matplotlib.widgets import MultiCursor
- from pylab import figure, show, np
-
- t = np.arange(0.0, 2.0, 0.01)
- s1 = np.sin(2*np.pi*t)
- s2 = np.sin(4*np.pi*t)
- fig = figure()
- ax1 = fig.add_subplot(211)
- ax1.plot(t, s1)
-
-
- ax2 = fig.add_subplot(212, sharex=ax1)
- ax2.plot(t, s2)
-
- multi = MultiCursor(fig.canvas, (ax1, ax2), color='r', lw=1,
- horizOn=False, vertOn=True)
- show()
-
- """
- def __init__(self, canvas, axes, useblit=True, horizOn=False, vertOn=True,
- **lineprops):
-
- self.canvas = canvas
- self.axes = axes
- self.horizOn = horizOn
- self.vertOn = vertOn
-
- xmin, xmax = axes[-1].get_xlim()
- ymin, ymax = axes[-1].get_ylim()
- xmid = 0.5 * (xmin + xmax)
- ymid = 0.5 * (ymin + ymax)
-
- self.visible = True
- self.useblit = useblit and self.canvas.supports_blit
- self.background = None
- self.needclear = False
-
- if self.useblit:
- lineprops['animated'] = True
-
- if vertOn:
- self.vlines = [ax.axvline(xmid, visible=False, **lineprops)
- for ax in axes]
- else:
- self.vlines = []
-
- if horizOn:
- self.hlines = [ax.axhline(ymid, visible=False, **lineprops)
- for ax in axes]
- else:
- self.hlines = []
-
- self.connect()
-
- def connect(self):
- """connect events"""
- self._cidmotion = self.canvas.mpl_connect('motion_notify_event',
- self.onmove)
- self._ciddraw = self.canvas.mpl_connect('draw_event', self.clear)
-
- def disconnect(self):
- """disconnect events"""
- self.canvas.mpl_disconnect(self._cidmotion)
- self.canvas.mpl_disconnect(self._ciddraw)
-
- def clear(self, event):
- """clear the cursor"""
- if self.ignore(event):
- return
- if self.useblit:
- self.background = (
- self.canvas.copy_from_bbox(self.canvas.figure.bbox))
- for line in self.vlines + self.hlines:
- line.set_visible(False)
-
- def onmove(self, event):
- if self.ignore(event):
- return
- if event.inaxes is None:
- return
- if not self.canvas.widgetlock.available(self):
- return
- self.needclear = True
- if not self.visible:
- return
- if self.vertOn:
- for line in self.vlines:
- line.set_xdata((event.xdata, event.xdata))
- line.set_visible(self.visible)
- if self.horizOn:
- for line in self.hlines:
- line.set_ydata((event.ydata, event.ydata))
- line.set_visible(self.visible)
- self._update()
-
- def _update(self):
- if self.useblit:
- if self.background is not None:
- self.canvas.restore_region(self.background)
- if self.vertOn:
- for ax, line in zip(self.axes, self.vlines):
- ax.draw_artist(line)
- if self.horizOn:
- for ax, line in zip(self.axes, self.hlines):
- ax.draw_artist(line)
- self.canvas.blit(self.canvas.figure.bbox)
- else:
- self.canvas.draw_idle()
-
-
-class _SelectorWidget(AxesWidget):
-
- def __init__(self, ax, onselect, useblit=False, button=None,
- state_modifier_keys=None):
- AxesWidget.__init__(self, ax)
-
- self.visible = True
- self.onselect = onselect
- self.useblit = useblit and self.canvas.supports_blit
- self.connect_default_events()
-
- self.state_modifier_keys = dict(move=' ', clear='escape',
- square='shift', center='control')
- self.state_modifier_keys.update(state_modifier_keys or {})
-
- self.background = None
- self.artists = []
-
- if isinstance(button, int):
- self.validButtons = [button]
- else:
- self.validButtons = button
-
- # will save the data (position at mouseclick)
- self.eventpress = None
- # will save the data (pos. at mouserelease)
- self.eventrelease = None
- self._prev_event = None
- self.state = set()
-
- def set_active(self, active):
- AxesWidget.set_active(self, active)
- if active:
- self.update_background(None)
-
- def update_background(self, event):
- """force an update of the background"""
- # If you add a call to `ignore` here, you'll want to check edge case:
- # `release` can call a draw event even when `ignore` is True.
- if self.useblit:
- self.background = self.canvas.copy_from_bbox(self.ax.bbox)
-
- def connect_default_events(self):
- """Connect the major canvas events to methods."""
- self.connect_event('motion_notify_event', self.onmove)
- self.connect_event('button_press_event', self.press)
- self.connect_event('button_release_event', self.release)
- self.connect_event('draw_event', self.update_background)
- self.connect_event('key_press_event', self.on_key_press)
- self.connect_event('key_release_event', self.on_key_release)
- self.connect_event('scroll_event', self.on_scroll)
-
- def ignore(self, event):
- """return *True* if *event* should be ignored"""
- if not self.active or not self.ax.get_visible():
- return True
-
- # If canvas was locked
- if not self.canvas.widgetlock.available(self):
- return True
-
- if not hasattr(event, 'button'):
- event.button = None
-
- # Only do rectangle selection if event was triggered
- # with a desired button
- if self.validButtons is not None:
- if event.button not in self.validButtons:
- return True
-
- # If no button was pressed yet ignore the event if it was out
- # of the axes
- if self.eventpress is None:
- return event.inaxes != self.ax
-
- # If a button was pressed, check if the release-button is the
- # same.
- if event.button == self.eventpress.button:
- return False
-
- # If a button was pressed, check if the release-button is the
- # same.
- return (event.inaxes != self.ax or
- event.button != self.eventpress.button)
-
- def update(self):
- """draw using newfangled blit or oldfangled draw depending on
- useblit
-
- """
- if not self.ax.get_visible():
- return False
-
- if self.useblit:
- if self.background is not None:
- self.canvas.restore_region(self.background)
- for artist in self.artists:
- self.ax.draw_artist(artist)
-
- self.canvas.blit(self.ax.bbox)
-
- else:
- self.canvas.draw_idle()
- return False
-
- def _get_data(self, event):
- """Get the xdata and ydata for event, with limits"""
- if event.xdata is None:
- return None, None
- x0, x1 = self.ax.get_xbound()
- y0, y1 = self.ax.get_ybound()
- xdata = max(x0, event.xdata)
- xdata = min(x1, xdata)
- ydata = max(y0, event.ydata)
- ydata = min(y1, ydata)
- return xdata, ydata
-
- def _clean_event(self, event):
- """Clean up an event
-
- Use prev event if there is no xdata
- Limit the xdata and ydata to the axes limits
- Set the prev event
- """
- if event.xdata is None:
- event = self._prev_event
- else:
- event = copy.copy(event)
- event.xdata, event.ydata = self._get_data(event)
-
- self._prev_event = event
- return event
-
- def press(self, event):
- """Button press handler and validator"""
- if not self.ignore(event):
- event = self._clean_event(event)
- self.eventpress = event
- self._prev_event = event
- key = event.key or ''
- key = key.replace('ctrl', 'control')
- # move state is locked in on a button press
- if key == self.state_modifier_keys['move']:
- self.state.add('move')
- self._press(event)
- return True
- return False
-
- def _press(self, event):
- """Button press handler"""
- pass
-
- def release(self, event):
- """Button release event handler and validator"""
- if not self.ignore(event) and self.eventpress:
- event = self._clean_event(event)
- self.eventrelease = event
- self._release(event)
- self.eventpress = None
- self.eventrelease = None
- self.state.discard('move')
- return True
- return False
-
- def _release(self, event):
- """Button release event handler"""
- pass
-
- def onmove(self, event):
- """Cursor move event handler and validator"""
- if not self.ignore(event) and self.eventpress:
- event = self._clean_event(event)
- self._onmove(event)
- return True
- return False
-
- def _onmove(self, event):
- """Cursor move event handler"""
- pass
-
- def on_scroll(self, event):
- """Mouse scroll event handler and validator"""
- if not self.ignore(event):
- self._on_scroll(event)
-
- def _on_scroll(self, event):
- """Mouse scroll event handler"""
- pass
-
- def on_key_press(self, event):
- """Key press event handler and validator for all selection widgets"""
- if self.active:
- key = event.key or ''
- key = key.replace('ctrl', 'control')
- if key == self.state_modifier_keys['clear']:
- for artist in self.artists:
- artist.set_visible(False)
- self.update()
- return
- for (state, modifier) in self.state_modifier_keys.items():
- if modifier in key:
- self.state.add(state)
- self._on_key_press(event)
-
- def _on_key_press(self, event):
- """Key press event handler - use for widget-specific key press actions.
- """
- pass
-
- def on_key_release(self, event):
- """Key release event handler and validator"""
- if self.active:
- key = event.key or ''
- for (state, modifier) in self.state_modifier_keys.items():
- if modifier in key:
- self.state.discard(state)
- self._on_key_release(event)
-
- def _on_key_release(self, event):
- """Key release event handler"""
- pass
-
- def set_visible(self, visible):
- """ Set the visibility of our artists """
- self.visible = visible
- for artist in self.artists:
- artist.set_visible(visible)
-
-
-class SpanSelector(_SelectorWidget):
- """
- Visually select a min/max range on a single axis and call a function with
- those values.
-
- To guarantee that the selector remains responsive, keep a reference to it.
-
- In order to turn off the SpanSelector, set `span_selector.active=False`. To
- turn it back on, set `span_selector.active=True`.
-
- Parameters
- ----------
- ax : :class:`matplotlib.axes.Axes` object
-
- onselect : func(min, max), min/max are floats
-
- direction : "horizontal" or "vertical"
- The axis along which to draw the span selector
-
- minspan : float, default is None
- If selection is less than *minspan*, do not call *onselect*
-
- useblit : bool, default is False
- If True, use the backend-dependent blitting features for faster
- canvas updates.
-
- rectprops : dict, default is None
- Dictionary of :class:`matplotlib.patches.Patch` properties
-
- onmove_callback : func(min, max), min/max are floats, default is None
- Called on mouse move while the span is being selected
-
- span_stays : bool, default is False
- If True, the span stays visible after the mouse is released
-
- button : int or list of ints
- Determines which mouse buttons activate the span selector
- 1 = left mouse button\n
- 2 = center mouse button (scroll wheel)\n
- 3 = right mouse button\n
-
- Examples
- --------
- >>> import matplotlib.pyplot as plt
- >>> import matplotlib.widgets as mwidgets
- >>> fig, ax = plt.subplots()
- >>> ax.plot([1, 2, 3], [10, 50, 100])
- >>> def onselect(vmin, vmax):
- print(vmin, vmax)
- >>> rectprops = dict(facecolor='blue', alpha=0.5)
- >>> span = mwidgets.SpanSelector(ax, onselect, 'horizontal',
- rectprops=rectprops)
- >>> fig.show()
-
- See also: :doc:`/gallery/widgets/span_selector`
-
- """
-
- def __init__(self, ax, onselect, direction, minspan=None, useblit=False,
- rectprops=None, onmove_callback=None, span_stays=False,
- button=None):
-
- _SelectorWidget.__init__(self, ax, onselect, useblit=useblit,
- button=button)
-
- if rectprops is None:
- rectprops = dict(facecolor='red', alpha=0.5)
-
- rectprops['animated'] = self.useblit
-
- if direction not in ['horizontal', 'vertical']:
- raise ValueError("direction must be 'horizontal' or 'vertical'")
- self.direction = direction
-
- self.rect = None
- self.pressv = None
-
- self.rectprops = rectprops
- self.onmove_callback = onmove_callback
- self.minspan = minspan
- self.span_stays = span_stays
-
- # Needed when dragging out of axes
- self.prev = (0, 0)
-
- # Reset canvas so that `new_axes` connects events.
- self.canvas = None
- self.new_axes(ax)
-
- def new_axes(self, ax):
- """Set SpanSelector to operate on a new Axes"""
- self.ax = ax
- if self.canvas is not ax.figure.canvas:
- if self.canvas is not None:
- self.disconnect_events()
-
- self.canvas = ax.figure.canvas
- self.connect_default_events()
-
- if self.direction == 'horizontal':
- trans = blended_transform_factory(self.ax.transData,
- self.ax.transAxes)
- w, h = 0, 1
- else:
- trans = blended_transform_factory(self.ax.transAxes,
- self.ax.transData)
- w, h = 1, 0
- self.rect = Rectangle((0, 0), w, h,
- transform=trans,
- visible=False,
- **self.rectprops)
- if self.span_stays:
- self.stay_rect = Rectangle((0, 0), w, h,
- transform=trans,
- visible=False,
- **self.rectprops)
- self.stay_rect.set_animated(False)
- self.ax.add_patch(self.stay_rect)
-
- self.ax.add_patch(self.rect)
- self.artists = [self.rect]
-
- def ignore(self, event):
- """return *True* if *event* should be ignored"""
- return _SelectorWidget.ignore(self, event) or not self.visible
-
- def _press(self, event):
- """on button press event"""
- self.rect.set_visible(self.visible)
- if self.span_stays:
- self.stay_rect.set_visible(False)
- # really force a draw so that the stay rect is not in
- # the blit background
- if self.useblit:
- self.canvas.draw()
- xdata, ydata = self._get_data(event)
- if self.direction == 'horizontal':
- self.pressv = xdata
- else:
- self.pressv = ydata
- return False
-
- def _release(self, event):
- """on button release event"""
- if self.pressv is None:
- return
- self.buttonDown = False
-
- self.rect.set_visible(False)
-
- if self.span_stays:
- self.stay_rect.set_x(self.rect.get_x())
- self.stay_rect.set_y(self.rect.get_y())
- self.stay_rect.set_width(self.rect.get_width())
- self.stay_rect.set_height(self.rect.get_height())
- self.stay_rect.set_visible(True)
-
- self.canvas.draw_idle()
- vmin = self.pressv
- xdata, ydata = self._get_data(event)
- if self.direction == 'horizontal':
- vmax = xdata or self.prev[0]
- else:
- vmax = ydata or self.prev[1]
-
- if vmin > vmax:
- vmin, vmax = vmax, vmin
- span = vmax - vmin
- if self.minspan is not None and span < self.minspan:
- return
- self.onselect(vmin, vmax)
- self.pressv = None
- return False
-
- def _onmove(self, event):
- """on motion notify event"""
- if self.pressv is None:
- return
- x, y = self._get_data(event)
- if x is None:
- return
-
- self.prev = x, y
- if self.direction == 'horizontal':
- v = x
- else:
- v = y
-
- minv, maxv = v, self.pressv
- if minv > maxv:
- minv, maxv = maxv, minv
- if self.direction == 'horizontal':
- self.rect.set_x(minv)
- self.rect.set_width(maxv - minv)
- else:
- self.rect.set_y(minv)
- self.rect.set_height(maxv - minv)
-
- if self.onmove_callback is not None:
- vmin = self.pressv
- xdata, ydata = self._get_data(event)
- if self.direction == 'horizontal':
- vmax = xdata or self.prev[0]
- else:
- vmax = ydata or self.prev[1]
-
- if vmin > vmax:
- vmin, vmax = vmax, vmin
- self.onmove_callback(vmin, vmax)
-
- self.update()
- return False
-
-
-class ToolHandles(object):
- """Control handles for canvas tools.
-
- Parameters
- ----------
- ax : :class:`matplotlib.axes.Axes`
- Matplotlib axes where tool handles are displayed.
- x, y : 1D arrays
- Coordinates of control handles.
- marker : str
- Shape of marker used to display handle. See `matplotlib.pyplot.plot`.
- marker_props : dict
- Additional marker properties. See :class:`matplotlib.lines.Line2D`.
- """
-
- def __init__(self, ax, x, y, marker='o', marker_props=None, useblit=True):
- self.ax = ax
-
- props = dict(marker=marker, markersize=7, mfc='w', ls='none',
- alpha=0.5, visible=False, label='_nolegend_')
- props.update(marker_props if marker_props is not None else {})
- self._markers = Line2D(x, y, animated=useblit, **props)
- self.ax.add_line(self._markers)
- self.artist = self._markers
-
- @property
- def x(self):
- return self._markers.get_xdata()
-
- @property
- def y(self):
- return self._markers.get_ydata()
-
- def set_data(self, pts, y=None):
- """Set x and y positions of handles"""
- if y is not None:
- x = pts
- pts = np.array([x, y])
- self._markers.set_data(pts)
-
- def set_visible(self, val):
- self._markers.set_visible(val)
-
- def set_animated(self, val):
- self._markers.set_animated(val)
-
- def closest(self, x, y):
- """Return index and pixel distance to closest index."""
- pts = np.transpose((self.x, self.y))
- # Transform data coordinates to pixel coordinates.
- pts = self.ax.transData.transform(pts)
- diff = pts - ((x, y))
- if diff.ndim == 2:
- dist = np.sqrt(np.sum(diff ** 2, axis=1))
- return np.argmin(dist), np.min(dist)
- else:
- return 0, np.sqrt(np.sum(diff ** 2))
-
-
-class RectangleSelector(_SelectorWidget):
- """
- Select a rectangular region of an axes.
-
- For the cursor to remain responsive you must keep a reference to
- it.
-
- Example usage::
-
- from matplotlib.widgets import RectangleSelector
- from pylab import *
-
- def onselect(eclick, erelease):
- 'eclick and erelease are matplotlib events at press and release'
- print(' startposition : (%f, %f)' % (eclick.xdata, eclick.ydata))
- print(' endposition : (%f, %f)' % (erelease.xdata, erelease.ydata))
- print(' used button : ', eclick.button)
-
- def toggle_selector(event):
- print(' Key pressed.')
- if event.key in ['Q', 'q'] and toggle_selector.RS.active:
- print(' RectangleSelector deactivated.')
- toggle_selector.RS.set_active(False)
- if event.key in ['A', 'a'] and not toggle_selector.RS.active:
- print(' RectangleSelector activated.')
- toggle_selector.RS.set_active(True)
-
- x = arange(100)/(99.0)
- y = sin(x)
- fig = figure
- ax = subplot(111)
- ax.plot(x,y)
-
- toggle_selector.RS = RectangleSelector(ax, onselect, drawtype='line')
- connect('key_press_event', toggle_selector)
- show()
- """
-
- _shape_klass = Rectangle
-
- def __init__(self, ax, onselect, drawtype='box',
- minspanx=None, minspany=None, useblit=False,
- lineprops=None, rectprops=None, spancoords='data',
- button=None, maxdist=10, marker_props=None,
- interactive=False, state_modifier_keys=None):
-
- """
- Create a selector in *ax*. When a selection is made, clear
- the span and call onselect with::
-
- onselect(pos_1, pos_2)
-
- and clear the drawn box/line. The ``pos_1`` and ``pos_2`` are
- arrays of length 2 containing the x- and y-coordinate.
-
- If *minspanx* is not *None* then events smaller than *minspanx*
- in x direction are ignored (it's the same for y).
-
- The rectangle is drawn with *rectprops*; default::
-
- rectprops = dict(facecolor='red', edgecolor = 'black',
- alpha=0.2, fill=True)
-
- The line is drawn with *lineprops*; default::
-
- lineprops = dict(color='black', linestyle='-',
- linewidth = 2, alpha=0.5)
-
- Use *drawtype* if you want the mouse to draw a line,
- a box or nothing between click and actual position by setting
-
- ``drawtype = 'line'``, ``drawtype='box'`` or ``drawtype = 'none'``.
- Drawing a line would result in a line from vertex A to vertex C in
- a rectangle ABCD.
-
- *spancoords* is one of 'data' or 'pixels'. If 'data', *minspanx*
- and *minspanx* will be interpreted in the same coordinates as
- the x and y axis. If 'pixels', they are in pixels.
-
- *button* is a list of integers indicating which mouse buttons should
- be used for rectangle selection. You can also specify a single
- integer if only a single button is desired. Default is *None*,
- which does not limit which button can be used.
-
- Note, typically:
- 1 = left mouse button
- 2 = center mouse button (scroll wheel)
- 3 = right mouse button
-
- *interactive* will draw a set of handles and allow you interact
- with the widget after it is drawn.
-
- *state_modifier_keys* are keyboard modifiers that affect the behavior
- of the widget.
-
- The defaults are:
- dict(move=' ', clear='escape', square='shift', center='ctrl')
-
- Keyboard modifiers, which:
- 'move': Move the existing shape.
- 'clear': Clear the current shape.
- 'square': Makes the shape square.
- 'center': Make the initial point the center of the shape.
- 'square' and 'center' can be combined.
- """
- _SelectorWidget.__init__(self, ax, onselect, useblit=useblit,
- button=button,
- state_modifier_keys=state_modifier_keys)
-
- self.to_draw = None
- self.visible = True
- self.interactive = interactive
-
- if drawtype == 'none':
- drawtype = 'line' # draw a line but make it
- self.visible = False # invisible
-
- if drawtype == 'box':
- if rectprops is None:
- rectprops = dict(facecolor='red', edgecolor='black',
- alpha=0.2, fill=True)
- rectprops['animated'] = self.useblit
- self.rectprops = rectprops
- self.to_draw = self._shape_klass((0, 0), 0, 1, visible=False,
- **self.rectprops)
- self.ax.add_patch(self.to_draw)
- if drawtype == 'line':
- if lineprops is None:
- lineprops = dict(color='black', linestyle='-',
- linewidth=2, alpha=0.5)
- lineprops['animated'] = self.useblit
- self.lineprops = lineprops
- self.to_draw = Line2D([0, 0], [0, 0], visible=False,
- **self.lineprops)
- self.ax.add_line(self.to_draw)
-
- self.minspanx = minspanx
- self.minspany = minspany
-
- if spancoords not in ('data', 'pixels'):
- raise ValueError("'spancoords' must be 'data' or 'pixels'")
-
- self.spancoords = spancoords
- self.drawtype = drawtype
-
- self.maxdist = maxdist
-
- if rectprops is None:
- props = dict(mec='r')
- else:
- props = dict(mec=rectprops.get('edgecolor', 'r'))
- self._corner_order = ['NW', 'NE', 'SE', 'SW']
- xc, yc = self.corners
- self._corner_handles = ToolHandles(self.ax, xc, yc, marker_props=props,
- useblit=self.useblit)
-
- self._edge_order = ['W', 'N', 'E', 'S']
- xe, ye = self.edge_centers
- self._edge_handles = ToolHandles(self.ax, xe, ye, marker='s',
- marker_props=props,
- useblit=self.useblit)
-
- xc, yc = self.center
- self._center_handle = ToolHandles(self.ax, [xc], [yc], marker='s',
- marker_props=props,
- useblit=self.useblit)
-
- self.active_handle = None
-
- self.artists = [self.to_draw, self._center_handle.artist,
- self._corner_handles.artist,
- self._edge_handles.artist]
-
- if not self.interactive:
- self.artists = [self.to_draw]
-
- self._extents_on_press = None
-
- def _press(self, event):
- """on button press event"""
- # make the drawed box/line visible get the click-coordinates,
- # button, ...
- if self.interactive and self.to_draw.get_visible():
- self._set_active_handle(event)
- else:
- self.active_handle = None
-
- if self.active_handle is None or not self.interactive:
- # Clear previous rectangle before drawing new rectangle.
- self.update()
-
- self.set_visible(self.visible)
-
- def _release(self, event):
- """on button release event"""
- if not self.interactive:
- self.to_draw.set_visible(False)
-
- # update the eventpress and eventrelease with the resulting extents
- x1, x2, y1, y2 = self.extents
- self.eventpress.xdata = x1
- self.eventpress.ydata = y1
- xy1 = self.ax.transData.transform_point([x1, y1])
- self.eventpress.x, self.eventpress.y = xy1
-
- self.eventrelease.xdata = x2
- self.eventrelease.ydata = y2
- xy2 = self.ax.transData.transform_point([x2, y2])
- self.eventrelease.x, self.eventrelease.y = xy2
-
- if self.spancoords == 'data':
- xmin, ymin = self.eventpress.xdata, self.eventpress.ydata
- xmax, ymax = self.eventrelease.xdata, self.eventrelease.ydata
- # calculate dimensions of box or line get values in the right
- # order
- elif self.spancoords == 'pixels':
- xmin, ymin = self.eventpress.x, self.eventpress.y
- xmax, ymax = self.eventrelease.x, self.eventrelease.y
- else:
- raise ValueError('spancoords must be "data" or "pixels"')
-
- if xmin > xmax:
- xmin, xmax = xmax, xmin
- if ymin > ymax:
- ymin, ymax = ymax, ymin
-
- spanx = xmax - xmin
- spany = ymax - ymin
- xproblems = self.minspanx is not None and spanx < self.minspanx
- yproblems = self.minspany is not None and spany < self.minspany
-
- # check if drawn distance (if it exists) is not too small in
- # either x or y-direction
- if self.drawtype != 'none' and (xproblems or yproblems):
- for artist in self.artists:
- artist.set_visible(False)
- self.update()
- return
-
- # call desired function
- self.onselect(self.eventpress, self.eventrelease)
- self.update()
-
- return False
-
- def _onmove(self, event):
- """on motion notify event if box/line is wanted"""
- # resize an existing shape
- if self.active_handle and not self.active_handle == 'C':
- x1, x2, y1, y2 = self._extents_on_press
- if self.active_handle in ['E', 'W'] + self._corner_order:
- x2 = event.xdata
- if self.active_handle in ['N', 'S'] + self._corner_order:
- y2 = event.ydata
-
- # move existing shape
- elif (('move' in self.state or self.active_handle == 'C')
- and self._extents_on_press is not None):
- x1, x2, y1, y2 = self._extents_on_press
- dx = event.xdata - self.eventpress.xdata
- dy = event.ydata - self.eventpress.ydata
- x1 += dx
- x2 += dx
- y1 += dy
- y2 += dy
-
- # new shape
- else:
- center = [self.eventpress.xdata, self.eventpress.ydata]
- center_pix = [self.eventpress.x, self.eventpress.y]
- dx = (event.xdata - center[0]) / 2.
- dy = (event.ydata - center[1]) / 2.
-
- # square shape
- if 'square' in self.state:
- dx_pix = abs(event.x - center_pix[0])
- dy_pix = abs(event.y - center_pix[1])
- if not dx_pix:
- return
- maxd = max(abs(dx_pix), abs(dy_pix))
- if abs(dx_pix) < maxd:
- dx *= maxd / (abs(dx_pix) + 1e-6)
- if abs(dy_pix) < maxd:
- dy *= maxd / (abs(dy_pix) + 1e-6)
-
- # from center
- if 'center' in self.state:
- dx *= 2
- dy *= 2
-
- # from corner
- else:
- center[0] += dx
- center[1] += dy
-
- x1, x2, y1, y2 = (center[0] - dx, center[0] + dx,
- center[1] - dy, center[1] + dy)
-
- self.extents = x1, x2, y1, y2
-
- @property
- def _rect_bbox(self):
- if self.drawtype == 'box':
- x0 = self.to_draw.get_x()
- y0 = self.to_draw.get_y()
- width = self.to_draw.get_width()
- height = self.to_draw.get_height()
- return x0, y0, width, height
- else:
- x, y = self.to_draw.get_data()
- x0, x1 = min(x), max(x)
- y0, y1 = min(y), max(y)
- return x0, y0, x1 - x0, y1 - y0
-
- @property
- def corners(self):
- """Corners of rectangle from lower left, moving clockwise."""
- x0, y0, width, height = self._rect_bbox
- xc = x0, x0 + width, x0 + width, x0
- yc = y0, y0, y0 + height, y0 + height
- return xc, yc
-
- @property
- def edge_centers(self):
- """Midpoint of rectangle edges from left, moving clockwise."""
- x0, y0, width, height = self._rect_bbox
- w = width / 2.
- h = height / 2.
- xe = x0, x0 + w, x0 + width, x0 + w
- ye = y0 + h, y0, y0 + h, y0 + height
- return xe, ye
-
- @property
- def center(self):
- """Center of rectangle"""
- x0, y0, width, height = self._rect_bbox
- return x0 + width / 2., y0 + height / 2.
-
- @property
- def extents(self):
- """Return (xmin, xmax, ymin, ymax)."""
- x0, y0, width, height = self._rect_bbox
- xmin, xmax = sorted([x0, x0 + width])
- ymin, ymax = sorted([y0, y0 + height])
- return xmin, xmax, ymin, ymax
-
- @extents.setter
- def extents(self, extents):
- # Update displayed shape
- self.draw_shape(extents)
- # Update displayed handles
- self._corner_handles.set_data(*self.corners)
- self._edge_handles.set_data(*self.edge_centers)
- self._center_handle.set_data(*self.center)
- self.set_visible(self.visible)
- self.update()
-
- def draw_shape(self, extents):
- x0, x1, y0, y1 = extents
- xmin, xmax = sorted([x0, x1])
- ymin, ymax = sorted([y0, y1])
- xlim = sorted(self.ax.get_xlim())
- ylim = sorted(self.ax.get_ylim())
-
- xmin = max(xlim[0], xmin)
- ymin = max(ylim[0], ymin)
- xmax = min(xmax, xlim[1])
- ymax = min(ymax, ylim[1])
-
- if self.drawtype == 'box':
- self.to_draw.set_x(xmin)
- self.to_draw.set_y(ymin)
- self.to_draw.set_width(xmax - xmin)
- self.to_draw.set_height(ymax - ymin)
-
- elif self.drawtype == 'line':
- self.to_draw.set_data([xmin, xmax], [ymin, ymax])
-
- def _set_active_handle(self, event):
- """Set active handle based on the location of the mouse event"""
- # Note: event.xdata/ydata in data coordinates, event.x/y in pixels
- c_idx, c_dist = self._corner_handles.closest(event.x, event.y)
- e_idx, e_dist = self._edge_handles.closest(event.x, event.y)
- m_idx, m_dist = self._center_handle.closest(event.x, event.y)
-
- if 'move' in self.state:
- self.active_handle = 'C'
- self._extents_on_press = self.extents
-
- # Set active handle as closest handle, if mouse click is close enough.
- elif m_dist < self.maxdist * 2:
- self.active_handle = 'C'
- elif c_dist > self.maxdist and e_dist > self.maxdist:
- self.active_handle = None
- return
- elif c_dist < e_dist:
- self.active_handle = self._corner_order[c_idx]
- else:
- self.active_handle = self._edge_order[e_idx]
-
- # Save coordinates of rectangle at the start of handle movement.
- x1, x2, y1, y2 = self.extents
- # Switch variables so that only x2 and/or y2 are updated on move.
- if self.active_handle in ['W', 'SW', 'NW']:
- x1, x2 = x2, event.xdata
- if self.active_handle in ['N', 'NW', 'NE']:
- y1, y2 = y2, event.ydata
- self._extents_on_press = x1, x2, y1, y2
-
- @property
- def geometry(self):
- """
- Returns numpy.ndarray of shape (2,5) containing
- x (``RectangleSelector.geometry[1,:]``) and
- y (``RectangleSelector.geometry[0,:]``)
- coordinates of the four corners of the rectangle starting
- and ending in the top left corner.
- """
- if hasattr(self.to_draw, 'get_verts'):
- xfm = self.ax.transData.inverted()
- y, x = xfm.transform(self.to_draw.get_verts()).T
- return np.array([x, y])
- else:
- return np.array(self.to_draw.get_data())
-
-
-class EllipseSelector(RectangleSelector):
- """
- Select an elliptical region of an axes.
-
- For the cursor to remain responsive you must keep a reference to
- it.
-
- Example usage::
-
- from matplotlib.widgets import EllipseSelector
- from pylab import *
-
- def onselect(eclick, erelease):
- 'eclick and erelease are matplotlib events at press and release'
- print(' startposition : (%f, %f)' % (eclick.xdata, eclick.ydata))
- print(' endposition : (%f, %f)' % (erelease.xdata, erelease.ydata))
- print(' used button : ', eclick.button)
-
- def toggle_selector(event):
- print(' Key pressed.')
- if event.key in ['Q', 'q'] and toggle_selector.ES.active:
- print(' EllipseSelector deactivated.')
- toggle_selector.RS.set_active(False)
- if event.key in ['A', 'a'] and not toggle_selector.ES.active:
- print(' EllipseSelector activated.')
- toggle_selector.ES.set_active(True)
-
- x = arange(100)/(99.0)
- y = sin(x)
- fig = figure
- ax = subplot(111)
- ax.plot(x,y)
-
- toggle_selector.ES = EllipseSelector(ax, onselect, drawtype='line')
- connect('key_press_event', toggle_selector)
- show()
- """
- _shape_klass = Ellipse
-
- def draw_shape(self, extents):
- x1, x2, y1, y2 = extents
- xmin, xmax = sorted([x1, x2])
- ymin, ymax = sorted([y1, y2])
- center = [x1 + (x2 - x1) / 2., y1 + (y2 - y1) / 2.]
- a = (xmax - xmin) / 2.
- b = (ymax - ymin) / 2.
-
- if self.drawtype == 'box':
- self.to_draw.center = center
- self.to_draw.width = 2 * a
- self.to_draw.height = 2 * b
- else:
- rad = np.deg2rad(np.arange(31) * 12)
- x = a * np.cos(rad) + center[0]
- y = b * np.sin(rad) + center[1]
- self.to_draw.set_data(x, y)
-
- @property
- def _rect_bbox(self):
- if self.drawtype == 'box':
- x, y = self.to_draw.center
- width = self.to_draw.width
- height = self.to_draw.height
- return x - width / 2., y - height / 2., width, height
- else:
- x, y = self.to_draw.get_data()
- x0, x1 = min(x), max(x)
- y0, y1 = min(y), max(y)
- return x0, y0, x1 - x0, y1 - y0
-
-
-class LassoSelector(_SelectorWidget):
- """
- Selection curve of an arbitrary shape.
-
- For the selector to remain responsive you must keep a reference to it.
-
- The selected path can be used in conjunction with `~.Path.contains_point`
- to select data points from an image.
-
- In contrast to `Lasso`, `LassoSelector` is written with an interface
- similar to `RectangleSelector` and `SpanSelector`, and will continue to
- interact with the axes until disconnected.
-
- Example usage::
-
- ax = subplot(111)
- ax.plot(x,y)
-
- def onselect(verts):
- print(verts)
- lasso = LassoSelector(ax, onselect)
-
- Parameters
- ----------
- ax : :class:`~matplotlib.axes.Axes`
- The parent axes for the widget.
- onselect : function
- Whenever the lasso is released, the *onselect* function is called and
- passed the vertices of the selected path.
- button : List[Int], optional
- A list of integers indicating which mouse buttons should be used for
- rectangle selection. You can also specify a single integer if only a
- single button is desired. Default is ``None``, which does not limit
- which button can be used.
-
- Note, typically:
-
- - 1 = left mouse button
- - 2 = center mouse button (scroll wheel)
- - 3 = right mouse button
-
- """
-
- def __init__(self, ax, onselect=None, useblit=True, lineprops=None,
- button=None):
- _SelectorWidget.__init__(self, ax, onselect, useblit=useblit,
- button=button)
-
- self.verts = None
-
- if lineprops is None:
- lineprops = dict()
- if useblit:
- lineprops['animated'] = True
- self.line = Line2D([], [], **lineprops)
- self.line.set_visible(False)
- self.ax.add_line(self.line)
- self.artists = [self.line]
-
- def onpress(self, event):
- self.press(event)
-
- def _press(self, event):
- self.verts = [self._get_data(event)]
- self.line.set_visible(True)
-
- def onrelease(self, event):
- self.release(event)
-
- def _release(self, event):
- if self.verts is not None:
- self.verts.append(self._get_data(event))
- self.onselect(self.verts)
- self.line.set_data([[], []])
- self.line.set_visible(False)
- self.verts = None
-
- def _onmove(self, event):
- if self.verts is None:
- return
- self.verts.append(self._get_data(event))
-
- self.line.set_data(list(zip(*self.verts)))
-
- self.update()
-
-
-class PolygonSelector(_SelectorWidget):
- """Select a polygon region of an axes.
-
- Place vertices with each mouse click, and make the selection by completing
- the polygon (clicking on the first vertex). Hold the *ctrl* key and click
- and drag a vertex to reposition it (the *ctrl* key is not necessary if the
- polygon has already been completed). Hold the *shift* key and click and
- drag anywhere in the axes to move all vertices. Press the *esc* key to
- start a new polygon.
-
- For the selector to remain responsive you must keep a reference to
- it.
-
- Parameters
- ----------
- ax : :class:`~matplotlib.axes.Axes`
- The parent axes for the widget.
- onselect : function
- When a polygon is completed or modified after completion,
- the `onselect` function is called and passed a list of the vertices as
- ``(xdata, ydata)`` tuples.
- useblit : bool, optional
- lineprops : dict, optional
- The line for the sides of the polygon is drawn with the properties
- given by `lineprops`. The default is ``dict(color='k', linestyle='-',
- linewidth=2, alpha=0.5)``.
- markerprops : dict, optional
- The markers for the vertices of the polygon are drawn with the
- properties given by `markerprops`. The default is ``dict(marker='o',
- markersize=7, mec='k', mfc='k', alpha=0.5)``.
- vertex_select_radius : float, optional
- A vertex is selected (to complete the polygon or to move a vertex)
- if the mouse click is within `vertex_select_radius` pixels of the
- vertex. The default radius is 15 pixels.
-
- Examples
- --------
- :doc:`/gallery/widgets/polygon_selector_demo`
- """
-
- def __init__(self, ax, onselect, useblit=False,
- lineprops=None, markerprops=None, vertex_select_radius=15):
- # The state modifiers 'move', 'square', and 'center' are expected by
- # _SelectorWidget but are not supported by PolygonSelector
- # Note: could not use the existing 'move' state modifier in-place of
- # 'move_all' because _SelectorWidget automatically discards 'move'
- # from the state on button release.
- state_modifier_keys = dict(clear='escape', move_vertex='control',
- move_all='shift', move='not-applicable',
- square='not-applicable',
- center='not-applicable')
- _SelectorWidget.__init__(self, ax, onselect, useblit=useblit,
- state_modifier_keys=state_modifier_keys)
-
- self._xs, self._ys = [0], [0]
- self._polygon_completed = False
-
- if lineprops is None:
- lineprops = dict(color='k', linestyle='-', linewidth=2, alpha=0.5)
- lineprops['animated'] = self.useblit
- self.line = Line2D(self._xs, self._ys, **lineprops)
- self.ax.add_line(self.line)
-
- if markerprops is None:
- markerprops = dict(mec='k', mfc=lineprops.get('color', 'k'))
- self._polygon_handles = ToolHandles(self.ax, self._xs, self._ys,
- useblit=self.useblit,
- marker_props=markerprops)
-
- self._active_handle_idx = -1
- self.vertex_select_radius = vertex_select_radius
-
- self.artists = [self.line, self._polygon_handles.artist]
- self.set_visible(True)
-
- def _press(self, event):
- """Button press event handler"""
- # Check for selection of a tool handle.
- if ((self._polygon_completed or 'move_vertex' in self.state)
- and len(self._xs) > 0):
- h_idx, h_dist = self._polygon_handles.closest(event.x, event.y)
- if h_dist < self.vertex_select_radius:
- self._active_handle_idx = h_idx
- # Save the vertex positions at the time of the press event (needed to
- # support the 'move_all' state modifier).
- self._xs_at_press, self._ys_at_press = self._xs[:], self._ys[:]
-
- def _release(self, event):
- """Button release event handler"""
- # Release active tool handle.
- if self._active_handle_idx >= 0:
- self._active_handle_idx = -1
-
- # Complete the polygon.
- elif (len(self._xs) > 3
- and self._xs[-1] == self._xs[0]
- and self._ys[-1] == self._ys[0]):
- self._polygon_completed = True
-
- # Place new vertex.
- elif (not self._polygon_completed
- and 'move_all' not in self.state
- and 'move_vertex' not in self.state):
- self._xs.insert(-1, event.xdata)
- self._ys.insert(-1, event.ydata)
-
- if self._polygon_completed:
- self.onselect(self.verts)
-
- def onmove(self, event):
- """Cursor move event handler and validator"""
- # Method overrides _SelectorWidget.onmove because the polygon selector
- # needs to process the move callback even if there is no button press.
- # _SelectorWidget.onmove include logic to ignore move event if
- # eventpress is None.
- if not self.ignore(event):
- event = self._clean_event(event)
- self._onmove(event)
- return True
- return False
-
- def _onmove(self, event):
- """Cursor move event handler"""
- # Move the active vertex (ToolHandle).
- if self._active_handle_idx >= 0:
- idx = self._active_handle_idx
- self._xs[idx], self._ys[idx] = event.xdata, event.ydata
- # Also update the end of the polygon line if the first vertex is
- # the active handle and the polygon is completed.
- if idx == 0 and self._polygon_completed:
- self._xs[-1], self._ys[-1] = event.xdata, event.ydata
-
- # Move all vertices.
- elif 'move_all' in self.state and self.eventpress:
- dx = event.xdata - self.eventpress.xdata
- dy = event.ydata - self.eventpress.ydata
- for k in range(len(self._xs)):
- self._xs[k] = self._xs_at_press[k] + dx
- self._ys[k] = self._ys_at_press[k] + dy
-
- # Do nothing if completed or waiting for a move.
- elif (self._polygon_completed
- or 'move_vertex' in self.state or 'move_all' in self.state):
- return
-
- # Position pending vertex.
- else:
- # Calculate distance to the start vertex.
- x0, y0 = self.line.get_transform().transform((self._xs[0],
- self._ys[0]))
- v0_dist = np.sqrt((x0 - event.x) ** 2 + (y0 - event.y) ** 2)
- # Lock on to the start vertex if near it and ready to complete.
- if len(self._xs) > 3 and v0_dist < self.vertex_select_radius:
- self._xs[-1], self._ys[-1] = self._xs[0], self._ys[0]
- else:
- self._xs[-1], self._ys[-1] = event.xdata, event.ydata
-
- self._draw_polygon()
-
- def _on_key_press(self, event):
- """Key press event handler"""
- # Remove the pending vertex if entering the 'move_vertex' or
- # 'move_all' mode
- if (not self._polygon_completed
- and ('move_vertex' in self.state or 'move_all' in self.state)):
- self._xs, self._ys = self._xs[:-1], self._ys[:-1]
- self._draw_polygon()
-
- def _on_key_release(self, event):
- """Key release event handler"""
- # Add back the pending vertex if leaving the 'move_vertex' or
- # 'move_all' mode (by checking the released key)
- if (not self._polygon_completed
- and
- (event.key == self.state_modifier_keys.get('move_vertex')
- or event.key == self.state_modifier_keys.get('move_all'))):
- self._xs.append(event.xdata)
- self._ys.append(event.ydata)
- self._draw_polygon()
- # Reset the polygon if the released key is the 'clear' key.
- elif event.key == self.state_modifier_keys.get('clear'):
- event = self._clean_event(event)
- self._xs, self._ys = [event.xdata], [event.ydata]
- self._polygon_completed = False
- self.set_visible(True)
-
- def _draw_polygon(self):
- """Redraw the polygon based on the new vertex positions."""
- self.line.set_data(self._xs, self._ys)
- # Only show one tool handle at the start and end vertex of the polygon
- # if the polygon is completed or the user is locked on to the start
- # vertex.
- if (self._polygon_completed
- or (len(self._xs) > 3
- and self._xs[-1] == self._xs[0]
- and self._ys[-1] == self._ys[0])):
- self._polygon_handles.set_data(self._xs[:-1], self._ys[:-1])
- else:
- self._polygon_handles.set_data(self._xs, self._ys)
- self.update()
-
- @property
- def verts(self):
- """Get the polygon vertices.
-
- Returns
- -------
- list
- A list of the vertices of the polygon as ``(xdata, ydata)`` tuples.
- """
- return list(zip(self._xs[:-1], self._ys[:-1]))
-
-
-class Lasso(AxesWidget):
- """Selection curve of an arbitrary shape.
-
- The selected path can be used in conjunction with
- :func:`~matplotlib.path.Path.contains_point` to select data points
- from an image.
-
- Unlike :class:`LassoSelector`, this must be initialized with a starting
- point `xy`, and the `Lasso` events are destroyed upon release.
-
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The parent axes for the widget.
- xy : array
- Coordinates of the start of the lasso.
- callback : callable
- Whenever the lasso is released, the `callback` function is called and
- passed the vertices of the selected path.
- """
-
- def __init__(self, ax, xy, callback=None, useblit=True):
- AxesWidget.__init__(self, ax)
-
- self.useblit = useblit and self.canvas.supports_blit
- if self.useblit:
- self.background = self.canvas.copy_from_bbox(self.ax.bbox)
-
- x, y = xy
- self.verts = [(x, y)]
- self.line = Line2D([x], [y], linestyle='-', color='black', lw=2)
- self.ax.add_line(self.line)
- self.callback = callback
- self.connect_event('button_release_event', self.onrelease)
- self.connect_event('motion_notify_event', self.onmove)
-
- def onrelease(self, event):
- if self.ignore(event):
- return
- if self.verts is not None:
- self.verts.append((event.xdata, event.ydata))
- if len(self.verts) > 2:
- self.callback(self.verts)
- self.ax.lines.remove(self.line)
- self.verts = None
- self.disconnect_events()
-
- def onmove(self, event):
- if self.ignore(event):
- return
- if self.verts is None:
- return
- if event.inaxes != self.ax:
- return
- if event.button != 1:
- return
- self.verts.append((event.xdata, event.ydata))
-
- self.line.set_data(list(zip(*self.verts)))
-
- if self.useblit:
- self.canvas.restore_region(self.background)
- self.ax.draw_artist(self.line)
- self.canvas.blit(self.ax.bbox)
- else:
- self.canvas.draw_idle()
diff --git a/contrib/python/matplotlib/py2/matplotlibrc.template b/contrib/python/matplotlib/py2/matplotlibrc.template
deleted file mode 100644
index 3c9d6f4cbc..0000000000
--- a/contrib/python/matplotlib/py2/matplotlibrc.template
+++ /dev/null
@@ -1,618 +0,0 @@
-#### MATPLOTLIBRC FORMAT
-
-## This is a sample matplotlib configuration file - you can find a copy
-## of it on your system in
-## site-packages/matplotlib/mpl-data/matplotlibrc. If you edit it
-## there, please note that it will be overwritten in your next install.
-## If you want to keep a permanent local copy that will not be
-## overwritten, place it in the following location:
-## unix/linux:
-## $HOME/.config/matplotlib/matplotlibrc or
-## $XDG_CONFIG_HOME/matplotlib/matplotlibrc (if $XDG_CONFIG_HOME is set)
-## other platforms:
-## $HOME/.matplotlib/matplotlibrc
-##
-## See http://matplotlib.org/users/customizing.html#the-matplotlibrc-file for
-## more details on the paths which are checked for the configuration file.
-##
-## This file is best viewed in a editor which supports python mode
-## syntax highlighting. Blank lines, or lines starting with a comment
-## symbol, are ignored, as are trailing comments. Other lines must
-## have the format
-## key : val ## optional comment
-##
-## Colors: for the color values below, you can either use - a
-## matplotlib color string, such as r, k, or b - an rgb tuple, such as
-## (1.0, 0.5, 0.0) - a hex string, such as ff00ff - a scalar
-## grayscale intensity such as 0.75 - a legal html color name, e.g., red,
-## blue, darkslategray
-
-##### CONFIGURATION BEGINS HERE
-
-## The default backend; one of GTK GTKAgg GTKCairo GTK3Agg GTK3Cairo
-## MacOSX Qt4Agg Qt5Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG
-## Template.
-## You can also deploy your own backend outside of matplotlib by
-## referring to the module name (which must be in the PYTHONPATH) as
-## 'module://my_backend'.
-##
-## If you omit this parameter, it will always default to "Agg", which is a
-## non-interactive backend.
-backend : $TEMPLATE_BACKEND
-
-## Note that this can be overridden by the environment variable
-## QT_API used by Enthought Tool Suite (ETS); valid values are
-## "pyqt" and "pyside". The "pyqt" setting has the side effect of
-## forcing the use of Version 2 API for QString and QVariant.
-
-## The port to use for the web server in the WebAgg backend.
-#webagg.port : 8988
-
-## The address on which the WebAgg web server should be reachable
-#webagg.address : 127.0.0.1
-
-## If webagg.port is unavailable, a number of other random ports will
-## be tried until one that is available is found.
-#webagg.port_retries : 50
-
-## When True, open the webbrowser to the plot that is shown
-#webagg.open_in_browser : True
-
-## if you are running pyplot inside a GUI and your backend choice
-## conflicts, we will automatically try to find a compatible one for
-## you if backend_fallback is True
-#backend_fallback: True
-
-#interactive : False
-#toolbar : toolbar2 ## None | toolbar2 ("classic" is deprecated)
-#timezone : UTC ## a pytz timezone string, e.g., US/Central or Europe/Paris
-
-## Where your matplotlib data lives if you installed to a non-default
-## location. This is where the matplotlib fonts, bitmaps, etc reside
-#datapath : /home/jdhunter/mpldata
-
-
-#### LINES
-## See http://matplotlib.org/api/artist_api.html#module-matplotlib.lines for more
-## information on line properties.
-#lines.linewidth : 1.5 ## line width in points
-#lines.linestyle : - ## solid line
-#lines.color : C0 ## has no affect on plot(); see axes.prop_cycle
-#lines.marker : None ## the default marker
-#lines.markeredgewidth : 1.0 ## the line width around the marker symbol
-#lines.markersize : 6 ## markersize, in points
-#lines.dash_joinstyle : round ## miter|round|bevel
-#lines.dash_capstyle : butt ## butt|round|projecting
-#lines.solid_joinstyle : round ## miter|round|bevel
-#lines.solid_capstyle : projecting ## butt|round|projecting
-#lines.antialiased : True ## render lines in antialiased (no jaggies)
-
-## The three standard dash patterns. These are scaled by the linewidth.
-#lines.dashed_pattern : 3.7, 1.6
-#lines.dashdot_pattern : 6.4, 1.6, 1, 1.6
-#lines.dotted_pattern : 1, 1.65
-#lines.scale_dashes : True
-
-#markers.fillstyle: full ## full|left|right|bottom|top|none
-
-#### PATCHES
-## Patches are graphical objects that fill 2D space, like polygons or
-## circles. See
-## http://matplotlib.org/api/artist_api.html#module-matplotlib.patches
-## information on patch properties
-#patch.linewidth : 1 ## edge width in points.
-#patch.facecolor : C0
-#patch.edgecolor : k ## if forced, or patch is not filled
-#patch.force_edgecolor : False ## True to always use edgecolor
-#patch.antialiased : True ## render patches in antialiased (no jaggies)
-
-#### HATCHES
-#hatch.color : k
-#hatch.linewidth : 1.0
-
-#### Boxplot
-#boxplot.notch : False
-#boxplot.vertical : True
-#boxplot.whiskers : 1.5
-#boxplot.bootstrap : None
-#boxplot.patchartist : False
-#boxplot.showmeans : False
-#boxplot.showcaps : True
-#boxplot.showbox : True
-#boxplot.showfliers : True
-#boxplot.meanline : False
-
-#boxplot.flierprops.color : k
-#boxplot.flierprops.marker : o
-#boxplot.flierprops.markerfacecolor : none
-#boxplot.flierprops.markeredgecolor : k
-#boxplot.flierprops.markersize : 6
-#boxplot.flierprops.linestyle : none
-#boxplot.flierprops.linewidth : 1.0
-
-#boxplot.boxprops.color : k
-#boxplot.boxprops.linewidth : 1.0
-#boxplot.boxprops.linestyle : -
-
-#boxplot.whiskerprops.color : k
-#boxplot.whiskerprops.linewidth : 1.0
-#boxplot.whiskerprops.linestyle : -
-
-#boxplot.capprops.color : k
-#boxplot.capprops.linewidth : 1.0
-#boxplot.capprops.linestyle : -
-
-#boxplot.medianprops.color : C1
-#boxplot.medianprops.linewidth : 1.0
-#boxplot.medianprops.linestyle : -
-
-#boxplot.meanprops.color : C2
-#boxplot.meanprops.marker : ^
-#boxplot.meanprops.markerfacecolor : C2
-#boxplot.meanprops.markeredgecolor : C2
-#boxplot.meanprops.markersize : 6
-#boxplot.meanprops.linestyle : --
-#boxplot.meanprops.linewidth : 1.0
-
-
-#### FONT
-
-## font properties used by text.Text. See
-## http://matplotlib.org/api/font_manager_api.html for more
-## information on font properties. The 6 font properties used for font
-## matching are given below with their default values.
-##
-## The font.family property has five values: 'serif' (e.g., Times),
-## 'sans-serif' (e.g., Helvetica), 'cursive' (e.g., Zapf-Chancery),
-## 'fantasy' (e.g., Western), and 'monospace' (e.g., Courier). Each of
-## these font families has a default list of font names in decreasing
-## order of priority associated with them. When text.usetex is False,
-## font.family may also be one or more concrete font names.
-##
-## The font.style property has three values: normal (or roman), italic
-## or oblique. The oblique style will be used for italic, if it is not
-## present.
-##
-## The font.variant property has two values: normal or small-caps. For
-## TrueType fonts, which are scalable fonts, small-caps is equivalent
-## to using a font size of 'smaller', or about 83%% of the current font
-## size.
-##
-## The font.weight property has effectively 13 values: normal, bold,
-## bolder, lighter, 100, 200, 300, ..., 900. Normal is the same as
-## 400, and bold is 700. bolder and lighter are relative values with
-## respect to the current weight.
-##
-## The font.stretch property has 11 values: ultra-condensed,
-## extra-condensed, condensed, semi-condensed, normal, semi-expanded,
-## expanded, extra-expanded, ultra-expanded, wider, and narrower. This
-## property is not currently implemented.
-##
-## The font.size property is the default font size for text, given in pts.
-## 10 pt is the standard value.
-
-#font.family : sans-serif
-#font.style : normal
-#font.variant : normal
-#font.weight : normal
-#font.stretch : normal
-## note that font.size controls default text sizes. To configure
-## special text sizes tick labels, axes, labels, title, etc, see the rc
-## settings for axes and ticks. Special text sizes can be defined
-## relative to font.size, using the following values: xx-small, x-small,
-## small, medium, large, x-large, xx-large, larger, or smaller
-#font.size : 10.0
-#font.serif : DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif
-#font.sans-serif : DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
-#font.cursive : Apple Chancery, Textile, Zapf Chancery, Sand, Script MT, Felipa, cursive
-#font.fantasy : Comic Sans MS, Chicago, Charcoal, ImpactWestern, Humor Sans, xkcd, fantasy
-#font.monospace : DejaVu Sans Mono, Bitstream Vera Sans Mono, Computer Modern Typewriter, Andale Mono, Nimbus Mono L, Courier New, Courier, Fixed, Terminal, monospace
-
-#### TEXT
-## text properties used by text.Text. See
-## http://matplotlib.org/api/artist_api.html#module-matplotlib.text for more
-## information on text properties
-#text.color : k
-
-#### LaTeX customizations. See http://wiki.scipy.org/Cookbook/Matplotlib/UsingTex
-#text.usetex : False ## use latex for all text handling. The following fonts
- ## are supported through the usual rc parameter settings:
- ## new century schoolbook, bookman, times, palatino,
- ## zapf chancery, charter, serif, sans-serif, helvetica,
- ## avant garde, courier, monospace, computer modern roman,
- ## computer modern sans serif, computer modern typewriter
- ## If another font is desired which can loaded using the
- ## LaTeX \usepackage command, please inquire at the
- ## matplotlib mailing list
-#text.latex.unicode : False ## use "ucs" and "inputenc" LaTeX packages for handling
- ## unicode strings.
-#text.latex.preamble : ## IMPROPER USE OF THIS FEATURE WILL LEAD TO LATEX FAILURES
- ## AND IS THEREFORE UNSUPPORTED. PLEASE DO NOT ASK FOR HELP
- ## IF THIS FEATURE DOES NOT DO WHAT YOU EXPECT IT TO.
- ## preamble is a comma separated list of LaTeX statements
- ## that are included in the LaTeX document preamble.
- ## An example:
- ## text.latex.preamble : \usepackage{bm},\usepackage{euler}
- ## The following packages are always loaded with usetex, so
- ## beware of package collisions: color, geometry, graphicx,
- ## type1cm, textcomp. Adobe Postscript (PSSNFS) font packages
- ## may also be loaded, depending on your font settings
-#text.latex.preview : False
-
-#text.hinting : auto ## May be one of the following:
- ## none: Perform no hinting
- ## auto: Use FreeType's autohinter
- ## native: Use the hinting information in the
- # font file, if available, and if your
- # FreeType library supports it
- ## either: Use the native hinting information,
- # or the autohinter if none is available.
- ## For backward compatibility, this value may also be
- ## True === 'auto' or False === 'none'.
-#text.hinting_factor : 8 ## Specifies the amount of softness for hinting in the
- ## horizontal direction. A value of 1 will hint to full
- ## pixels. A value of 2 will hint to half pixels etc.
-#text.antialiased : True ## If True (default), the text will be antialiased.
- ## This only affects the Agg backend.
-
-## The following settings allow you to select the fonts in math mode.
-## They map from a TeX font name to a fontconfig font pattern.
-## These settings are only used if mathtext.fontset is 'custom'.
-## Note that this "custom" mode is unsupported and may go away in the
-## future.
-#mathtext.cal : cursive
-#mathtext.rm : sans
-#mathtext.tt : monospace
-#mathtext.it : sans:italic
-#mathtext.bf : sans:bold
-#mathtext.sf : sans
-#mathtext.fontset : dejavusans ## Should be 'dejavusans' (default),
- ## 'dejavuserif', 'cm' (Computer Modern), 'stix',
- ## 'stixsans' or 'custom'
-#mathtext.fallback_to_cm : True ## When True, use symbols from the Computer Modern
- ## fonts when a symbol can not be found in one of
- ## the custom math fonts.
-#mathtext.default : it ## The default font to use for math.
- ## Can be any of the LaTeX font names, including
- ## the special name "regular" for the same font
- ## used in regular text.
-
-#### AXES
-## default face and edge color, default tick sizes,
-## default fontsizes for ticklabels, and so on. See
-## http://matplotlib.org/api/axes_api.html#module-matplotlib.axes
-#axes.facecolor : w ## axes background color
-#axes.edgecolor : k ## axes edge color
-#axes.linewidth : 0.8 ## edge linewidth
-#axes.grid : False ## display grid or not
-#axes.grid.axis : both ## which axis the grid should apply to
-#axes.grid.which : major ## gridlines at major, minor or both ticks
-#axes.titlesize : large ## fontsize of the axes title
-#axes.titleweight : normal ## font weight of title
-#axes.titlepad : 6.0 ## pad between axes and title in points
-#axes.labelsize : medium ## fontsize of the x any y labels
-#axes.labelpad : 4.0 ## space between label and axis
-#axes.labelweight : normal ## weight of the x and y labels
-#axes.labelcolor : k
-#axes.axisbelow : line ## draw axis gridlines and ticks below
- ## patches (True); above patches but below
- ## lines ('line'); or above all (False)
-#axes.formatter.limits : -7, 7 ## use scientific notation if log10
- ## of the axis range is smaller than the
- ## first or larger than the second
-#axes.formatter.use_locale : False ## When True, format tick labels
- ## according to the user's locale.
- ## For example, use ',' as a decimal
- ## separator in the fr_FR locale.
-#axes.formatter.use_mathtext : False ## When True, use mathtext for scientific
- ## notation.
-#axes.formatter.min_exponent: 0 ## minimum exponent to format in scientific notation
-#axes.formatter.useoffset : True ## If True, the tick label formatter
- ## will default to labeling ticks relative
- ## to an offset when the data range is
- ## small compared to the minimum absolute
- ## value of the data.
-#axes.formatter.offset_threshold : 4 ## When useoffset is True, the offset
- ## will be used when it can remove
- ## at least this number of significant
- ## digits from tick labels.
-#axes.spines.left : True ## display axis spines
-#axes.spines.bottom : True
-#axes.spines.top : True
-#axes.spines.right : True
-#axes.unicode_minus : True ## use unicode for the minus symbol
- ## rather than hyphen. See
- ## http://en.wikipedia.org/wiki/Plus_and_minus_signs#Character_codes
-#axes.prop_cycle : cycler('color', ['1f77b4', 'ff7f0e', '2ca02c', 'd62728', '9467bd', '8c564b', 'e377c2', '7f7f7f', 'bcbd22', '17becf'])
- ## color cycle for plot lines as list of string
- ## colorspecs: single letter, long name, or web-style hex
- ## Note the use of string escapes here ('1f77b4', instead of 1f77b4)
- ## as opposed to the rest of this file.
-#axes.autolimit_mode : data ## How to scale axes limits to the data.
- ## Use "data" to use data limits, plus some margin
- ## Use "round_number" move to the nearest "round" number
-#axes.xmargin : .05 ## x margin. See `axes.Axes.margins`
-#axes.ymargin : .05 ## y margin See `axes.Axes.margins`
-#polaraxes.grid : True ## display grid on polar axes
-#axes3d.grid : True ## display grid on 3d axes
-
-#### DATES
-## These control the default format strings used in AutoDateFormatter.
-## Any valid format datetime format string can be used (see the python
-## `datetime` for details). For example using '%%x' will use the locale date representation
-## '%%X' will use the locale time representation and '%%c' will use the full locale datetime
-## representation.
-## These values map to the scales:
-## {'year': 365, 'month': 30, 'day': 1, 'hour': 1/24, 'minute': 1 / (24 * 60)}
-
-#date.autoformatter.year : %Y
-#date.autoformatter.month : %Y-%m
-#date.autoformatter.day : %Y-%m-%d
-#date.autoformatter.hour : %m-%d %H
-#date.autoformatter.minute : %d %H:%M
-#date.autoformatter.second : %H:%M:%S
-#date.autoformatter.microsecond : %M:%S.%f
-
-#### TICKS
-## see http://matplotlib.org/api/axis_api.html#matplotlib.axis.Tick
-#xtick.top : False ## draw ticks on the top side
-#xtick.bottom : True ## draw ticks on the bottom side
-#xtick.labeltop : False ## draw label on the top
-#xtick.labelbottom : True ## draw label on the bottom
-#xtick.major.size : 3.5 ## major tick size in points
-#xtick.minor.size : 2 ## minor tick size in points
-#xtick.major.width : 0.8 ## major tick width in points
-#xtick.minor.width : 0.6 ## minor tick width in points
-#xtick.major.pad : 3.5 ## distance to major tick label in points
-#xtick.minor.pad : 3.4 ## distance to the minor tick label in points
-#xtick.color : k ## color of the tick labels
-#xtick.labelsize : medium ## fontsize of the tick labels
-#xtick.direction : out ## direction: in, out, or inout
-#xtick.minor.visible : False ## visibility of minor ticks on x-axis
-#xtick.major.top : True ## draw x axis top major ticks
-#xtick.major.bottom : True ## draw x axis bottom major ticks
-#xtick.minor.top : True ## draw x axis top minor ticks
-#xtick.minor.bottom : True ## draw x axis bottom minor ticks
-#xtick.alignment : center ## alignment of xticks
-
-#ytick.left : True ## draw ticks on the left side
-#ytick.right : False ## draw ticks on the right side
-#ytick.labelleft : True ## draw tick labels on the left side
-#ytick.labelright : False ## draw tick labels on the right side
-#ytick.major.size : 3.5 ## major tick size in points
-#ytick.minor.size : 2 ## minor tick size in points
-#ytick.major.width : 0.8 ## major tick width in points
-#ytick.minor.width : 0.6 ## minor tick width in points
-#ytick.major.pad : 3.5 ## distance to major tick label in points
-#ytick.minor.pad : 3.4 ## distance to the minor tick label in points
-#ytick.color : k ## color of the tick labels
-#ytick.labelsize : medium ## fontsize of the tick labels
-#ytick.direction : out ## direction: in, out, or inout
-#ytick.minor.visible : False ## visibility of minor ticks on y-axis
-#ytick.major.left : True ## draw y axis left major ticks
-#ytick.major.right : True ## draw y axis right major ticks
-#ytick.minor.left : True ## draw y axis left minor ticks
-#ytick.minor.right : True ## draw y axis right minor ticks
-#ytick.alignment : center_baseline ## alignment of yticks
-
-#### GRIDS
-#grid.color : b0b0b0 ## grid color
-#grid.linestyle : - ## solid
-#grid.linewidth : 0.8 ## in points
-#grid.alpha : 1.0 ## transparency, between 0.0 and 1.0
-
-#### Legend
-#legend.loc : best
-#legend.frameon : True ## if True, draw the legend on a background patch
-#legend.framealpha : 0.8 ## legend patch transparency
-#legend.facecolor : inherit ## inherit from axes.facecolor; or color spec
-#legend.edgecolor : 0.8 ## background patch boundary color
-#legend.fancybox : True ## if True, use a rounded box for the
- ## legend background, else a rectangle
-#legend.shadow : False ## if True, give background a shadow effect
-#legend.numpoints : 1 ## the number of marker points in the legend line
-#legend.scatterpoints : 1 ## number of scatter points
-#legend.markerscale : 1.0 ## the relative size of legend markers vs. original
-#legend.fontsize : medium
-## Dimensions as fraction of fontsize:
-#legend.borderpad : 0.4 ## border whitespace
-#legend.labelspacing : 0.5 ## the vertical space between the legend entries
-#legend.handlelength : 2.0 ## the length of the legend lines
-#legend.handleheight : 0.7 ## the height of the legend handle
-#legend.handletextpad : 0.8 ## the space between the legend line and legend text
-#legend.borderaxespad : 0.5 ## the border between the axes and legend edge
-#legend.columnspacing : 2.0 ## column separation
-
-#### FIGURE
-## See http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure
-#figure.titlesize : large ## size of the figure title (Figure.suptitle())
-#figure.titleweight : normal ## weight of the figure title
-#figure.figsize : 6.4, 4.8 ## figure size in inches
-#figure.dpi : 100 ## figure dots per inch
-#figure.facecolor : w ## figure facecolor; 0.75 is scalar gray
-#figure.edgecolor : w ## figure edgecolor
-#figure.frameon : True ## enable figure frame
-#figure.max_open_warning : 20 ## The maximum number of figures to open through
- ## the pyplot interface before emitting a warning.
- ## If less than one this feature is disabled.
-## The figure subplot parameters. All dimensions are a fraction of the
-#figure.subplot.left : 0.125 ## the left side of the subplots of the figure
-#figure.subplot.right : 0.9 ## the right side of the subplots of the figure
-#figure.subplot.bottom : 0.11 ## the bottom of the subplots of the figure
-#figure.subplot.top : 0.88 ## the top of the subplots of the figure
-#figure.subplot.wspace : 0.2 ## the amount of width reserved for space between subplots,
- ## expressed as a fraction of the average axis width
-#figure.subplot.hspace : 0.2 ## the amount of height reserved for space between subplots,
- ## expressed as a fraction of the average axis height
-
-## Figure layout
-#figure.autolayout : False ## When True, automatically adjust subplot
- ## parameters to make the plot fit the figure
- ## using `tight_layout`
-#figure.constrained_layout.use: False ## When True, automatically make plot
- ## elements fit on the figure. (Not compatible
- ## with `autolayout`, above).
-#figure.constrained_layout.h_pad : 0.04167 ## Padding around axes objects. Float representing
-#figure.constrained_layout.w_pad : 0.04167 ## inches. Default is 3./72. inches (3 pts)
-#figure.constrained_layout.hspace : 0.02 ## Space between subplot groups. Float representing
-#figure.constrained_layout.wspace : 0.02 ## a fraction of the subplot widths being separated.
-
-#### IMAGES
-#image.aspect : equal ## equal | auto | a number
-#image.interpolation : nearest ## see help(imshow) for options
-#image.cmap : viridis ## A colormap name, gray etc...
-#image.lut : 256 ## the size of the colormap lookup table
-#image.origin : upper ## lower | upper
-#image.resample : True
-#image.composite_image : True ## When True, all the images on a set of axes are
- ## combined into a single composite image before
- ## saving a figure as a vector graphics file,
- ## such as a PDF.
-
-#### CONTOUR PLOTS
-#contour.negative_linestyle : dashed ## string or on-off ink sequence
-#contour.corner_mask : True ## True | False | legacy
-
-#### ERRORBAR PLOTS
-#errorbar.capsize : 0 ## length of end cap on error bars in pixels
-
-#### HISTOGRAM PLOTS
-#hist.bins : 10 ## The default number of histogram bins.
- ## If Numpy 1.11 or later is
- ## installed, may also be `auto`
-
-#### SCATTER PLOTS
-#scatter.marker : o ## The default marker type for scatter plots.
-
-#### Agg rendering
-#### Warning: experimental, 2008/10/10
-#agg.path.chunksize : 0 ## 0 to disable; values in the range
- ## 10000 to 100000 can improve speed slightly
- ## and prevent an Agg rendering failure
- ## when plotting very large data sets,
- ## especially if they are very gappy.
- ## It may cause minor artifacts, though.
- ## A value of 20000 is probably a good
- ## starting point.
-#### PATHS
-#path.simplify : True ## When True, simplify paths by removing "invisible"
- ## points to reduce file size and increase rendering
- ## speed
-#path.simplify_threshold : 0.111111111111 ## The threshold of similarity below which
- ## vertices will be removed in the
- ## simplification process
-#path.snap : True ## When True, rectilinear axis-aligned paths will be snapped to
- ## the nearest pixel when certain criteria are met. When False,
- ## paths will never be snapped.
-#path.sketch : None ## May be none, or a 3-tuple of the form (scale, length,
- ## randomness).
- ## *scale* is the amplitude of the wiggle
- ## perpendicular to the line (in pixels). *length*
- ## is the length of the wiggle along the line (in
- ## pixels). *randomness* is the factor by which
- ## the length is randomly scaled.
-#path.effects : [] ##
-
-#### SAVING FIGURES
-## the default savefig params can be different from the display params
-## e.g., you may want a higher resolution, or to make the figure
-## background white
-#savefig.dpi : figure ## figure dots per inch or 'figure'
-#savefig.facecolor : w ## figure facecolor when saving
-#savefig.edgecolor : w ## figure edgecolor when saving
-#savefig.format : png ## png, ps, pdf, svg
-#savefig.bbox : standard ## 'tight' or 'standard'.
- ## 'tight' is incompatible with pipe-based animation
- ## backends but will workd with temporary file based ones:
- ## e.g. setting animation.writer to ffmpeg will not work,
- ## use ffmpeg_file instead
-#savefig.pad_inches : 0.1 ## Padding to be used when bbox is set to 'tight'
-#savefig.jpeg_quality: 95 ## when a jpeg is saved, the default quality parameter.
-#savefig.directory : ~ ## default directory in savefig dialog box,
- ## leave empty to always use current working directory
-#savefig.transparent : False ## setting that controls whether figures are saved with a
- ## transparent background by default
-#savefig.frameon : True ## enable frame of figure when saving
-#savefig.orientation : portrait ## Orientation of saved figure
-
-### tk backend params
-#tk.window_focus : False ## Maintain shell focus for TkAgg
-
-### ps backend params
-#ps.papersize : letter ## auto, letter, legal, ledger, A0-A10, B0-B10
-#ps.useafm : False ## use of afm fonts, results in small files
-#ps.usedistiller : False ## can be: None, ghostscript or xpdf
- ## Experimental: may produce smaller files.
- ## xpdf intended for production of publication quality files,
- ## but requires ghostscript, xpdf and ps2eps
-#ps.distiller.res : 6000 ## dpi
-#ps.fonttype : 3 ## Output Type 3 (Type3) or Type 42 (TrueType)
-
-### pdf backend params
-#pdf.compression : 6 ## integer from 0 to 9
- ## 0 disables compression (good for debugging)
-#pdf.fonttype : 3 ## Output Type 3 (Type3) or Type 42 (TrueType)
-#pdf.use14corefonts : False
-#pdf.inheritcolor : False
-
-### svg backend params
-#svg.image_inline : True ## write raster image data directly into the svg file
-#svg.fonttype : path ## How to handle SVG fonts:
- ## none: Assume fonts are installed on the machine where the SVG will be viewed.
- ## path: Embed characters as paths -- supported by most SVG renderers
- ## svgfont: Embed characters as SVG fonts -- supported only by Chrome,
- ## Opera and Safari
-#svg.hashsalt : None ## if not None, use this string as hash salt
- ## instead of uuid4
-### pgf parameter
-#pgf.rcfonts : True
-#pgf.preamble :
-#pgf.texsystem : xelatex
-#pgf.debug : False
-
-### docstring params
-##docstring.hardcopy = False ## set this when you want to generate hardcopy docstring
-
-## Event keys to interact with figures/plots via keyboard.
-## Customize these settings according to your needs.
-## Leave the field(s) empty if you don't need a key-map. (i.e., fullscreen : '')
-#keymap.fullscreen : f, ctrl+f ## toggling
-#keymap.home : h, r, home ## home or reset mnemonic
-#keymap.back : left, c, backspace ## forward / backward keys to enable
-#keymap.forward : right, v ## left handed quick navigation
-#keymap.pan : p ## pan mnemonic
-#keymap.zoom : o ## zoom mnemonic
-#keymap.save : s, ctrl+s ## saving current figure
-#keymap.quit : ctrl+w, cmd+w, q ## close the current figure
-#keymap.quit_all : W, cmd+W, Q ## close all figures
-#keymap.grid : g ## switching on/off major grids in current axes
-#keymap.grid_minor : G ## switching on/off minor grids in current axes
-#keymap.yscale : l ## toggle scaling of y-axes ('log'/'linear')
-#keymap.xscale : k, L ## toggle scaling of x-axes ('log'/'linear')
-#keymap.all_axes : a ## enable all axes
-
-## Control location of examples data files
-#examples.directory : ## directory to look in for custom installation
-
-###ANIMATION settings
-#animation.html : none ## How to display the animation as HTML in
- ## the IPython notebook. 'html5' uses
- ## HTML5 video tag; 'jshtml' creates a
- ## Javascript animation
-#animation.writer : ffmpeg ## MovieWriter 'backend' to use
-#animation.codec : h264 ## Codec to use for writing movie
-#animation.bitrate: -1 ## Controls size/quality tradeoff for movie.
- ## -1 implies let utility auto-determine
-#animation.frame_format: png ## Controls frame format used by temp files
-#animation.html_args: ## Additional arguments to pass to html writer
-#animation.ffmpeg_path: ffmpeg ## Path to ffmpeg binary. Without full path
- ## $PATH is searched
-#animation.ffmpeg_args: ## Additional arguments to pass to ffmpeg
-#animation.avconv_path: avconv ## Path to avconv binary. Without full path
- ## $PATH is searched
-#animation.avconv_args: ## Additional arguments to pass to avconv
-#animation.convert_path: convert ## Path to ImageMagick's convert binary.
- ## On Windows use the full path since convert
- ## is also the name of a system tool.
-#animation.convert_args: ## Additional arguments to pass to convert
-#animation.embed_limit : 20.0
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/__init__.py b/contrib/python/matplotlib/py2/mpl_toolkits/__init__.py
deleted file mode 100644
index 8d9942e652..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-try:
- __import__('pkg_resources').declare_namespace(__name__)
-except ImportError:
- pass # must not have setuptools
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/ChangeLog b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/ChangeLog
deleted file mode 100644
index 79cc01cfdf..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/ChangeLog
+++ /dev/null
@@ -1,13 +0,0 @@
-2009-06-01 Jae-Joon Lee <lee.j.joon@gmail.com>
-
- * axislines.py (Axes.toggle_axisline): fix broken spine support.
- (AxisArtistHelper): Initial support for curvelinear grid and ticks.
-
-2009-05-04 Jae-Joon Lee <lee.j.joon@gmail.com>
-
- * inset_locator.py (inset_axes, zoomed_inset_axes): axes_class support
-
- * axislines.py : Better support for tick (tick label) color
- handling
- (Axes.get_children): fix typo
-
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/__init__.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/__init__.py
deleted file mode 100644
index c10e89bd62..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from . import axes_size as Size
-from .axes_divider import Divider, SubplotDivider, LocatableAxes, \
- make_axes_locatable
-from .axes_grid import Grid, ImageGrid, AxesGrid
-#from axes_divider import make_axes_locatable
-from matplotlib.cbook import warn_deprecated
-warn_deprecated(since='2.1',
- name='mpl_toolkits.axes_grid',
- alternative='mpl_toolkits.axes_grid1 and'
- ' mpl_toolkits.axisartist provies the same'
- ' functionality',
- obj_type='module')
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/anchored_artists.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/anchored_artists.py
deleted file mode 100644
index 14b661497d..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/anchored_artists.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from matplotlib.offsetbox import AnchoredOffsetbox, AuxTransformBox, VPacker,\
- TextArea, AnchoredText, DrawingArea, AnnotationBbox
-
-from mpl_toolkits.axes_grid1.anchored_artists import \
- AnchoredDrawingArea, AnchoredAuxTransformBox, \
- AnchoredEllipse, AnchoredSizeBar
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/angle_helper.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/angle_helper.py
deleted file mode 100644
index f0f877d913..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/angle_helper.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axisartist.angle_helper import *
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axes_divider.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axes_divider.py
deleted file mode 100644
index 25694ecf5e..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axes_divider.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axes_grid1.axes_divider import Divider, AxesLocator, SubplotDivider, \
- AxesDivider, locatable_axes_factory, make_axes_locatable
-
-from mpl_toolkits.axes_grid.axislines import Axes
-LocatableAxes = locatable_axes_factory(Axes)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axes_grid.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axes_grid.py
deleted file mode 100644
index 58212ac89c..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axes_grid.py
+++ /dev/null
@@ -1,30 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import mpl_toolkits.axes_grid1.axes_grid as axes_grid_orig
-from .axes_divider import LocatableAxes
-
-class CbarAxes(axes_grid_orig.CbarAxesBase, LocatableAxes):
- def __init__(self, *kl, **kwargs):
- orientation=kwargs.pop("orientation", None)
- if orientation is None:
- raise ValueError("orientation must be specified")
- self.orientation = orientation
- self._default_label_on = False
- self.locator = None
-
- super(LocatableAxes, self).__init__(*kl, **kwargs)
-
- def cla(self):
- super(LocatableAxes, self).cla()
- self._config_axes()
-
-
-class Grid(axes_grid_orig.Grid):
- _defaultLocatableAxesClass = LocatableAxes
-
-class ImageGrid(axes_grid_orig.ImageGrid):
- _defaultLocatableAxesClass = LocatableAxes
- _defaultCbarAxesClass = CbarAxes
-
-AxesGrid = ImageGrid
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axes_rgb.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axes_rgb.py
deleted file mode 100644
index bfd4bb98ad..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axes_rgb.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-#from mpl_toolkits.axes_grid1.axes_rgb import *
-from mpl_toolkits.axes_grid1.axes_rgb import make_rgb_axes, imshow_rgb, RGBAxesBase
-
-#import mpl_toolkits.axes_grid1.axes_rgb as axes_rgb_orig
-from .axislines import Axes
-
-class RGBAxes(RGBAxesBase):
- _defaultAxesClass = Axes
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axes_size.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axes_size.py
deleted file mode 100644
index 998b5e3c87..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axes_size.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axes_grid1.axes_size import *
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axis_artist.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axis_artist.py
deleted file mode 100644
index 92f0538ceb..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axis_artist.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axisartist.axis_artist import *
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axisline_style.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axisline_style.py
deleted file mode 100644
index 2eef3b8b34..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axisline_style.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axisartist.axisline_style import *
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axislines.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axislines.py
deleted file mode 100644
index 9653aa1702..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/axislines.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axisartist.axislines import *
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/clip_path.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/clip_path.py
deleted file mode 100644
index bafe568fb1..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/clip_path.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axisartist.clip_path import *
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/colorbar.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/colorbar.py
deleted file mode 100644
index cc5c252da8..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/colorbar.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from mpl_toolkits.axes_grid1.colorbar import (
- make_axes_kw_doc, colormap_kw_doc, colorbar_doc,
- CbarAxesLocator, ColorbarBase, Colorbar,
- make_axes, colorbar
-)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/floating_axes.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/floating_axes.py
deleted file mode 100644
index 3f30d57c3a..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/floating_axes.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axisartist.floating_axes import *
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/grid_finder.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/grid_finder.py
deleted file mode 100644
index ffa3db76cf..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/grid_finder.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axisartist.grid_finder import *
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/grid_helper_curvelinear.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/grid_helper_curvelinear.py
deleted file mode 100644
index 325ddd6af2..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/grid_helper_curvelinear.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axisartist.grid_helper_curvelinear import *
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/inset_locator.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/inset_locator.py
deleted file mode 100644
index a9ed77beda..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/inset_locator.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axes_grid1.inset_locator import InsetPosition, \
- AnchoredSizeLocator, \
- AnchoredZoomLocator, BboxPatch, BboxConnector, BboxConnectorPatch, \
- inset_axes, zoomed_inset_axes, mark_inset
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/parasite_axes.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/parasite_axes.py
deleted file mode 100644
index cad56e43a2..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid/parasite_axes.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axes_grid1.parasite_axes import (
- host_axes_class_factory, parasite_axes_class_factory,
- parasite_axes_auxtrans_class_factory, subplot_class_factory)
-
-from .axislines import Axes
-
-
-ParasiteAxes = parasite_axes_class_factory(Axes)
-
-ParasiteAxesAuxTrans = \
- parasite_axes_auxtrans_class_factory(axes_class=ParasiteAxes)
-
-HostAxes = host_axes_class_factory(axes_class=Axes)
-
-SubplotHost = subplot_class_factory(HostAxes)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/__init__.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/__init__.py
deleted file mode 100644
index 3e225ba9f0..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/__init__.py
+++ /dev/null
@@ -1,12 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from . import axes_size as Size
-from .axes_divider import Divider, SubplotDivider, LocatableAxes, \
- make_axes_locatable
-from .axes_grid import Grid, ImageGrid, AxesGrid
-#from axes_divider import make_axes_locatable
-
-from .parasite_axes import host_subplot, host_axes
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/anchored_artists.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/anchored_artists.py
deleted file mode 100644
index 5b492858e8..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/anchored_artists.py
+++ /dev/null
@@ -1,376 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-import six
-
-from matplotlib import docstring
-from matplotlib.offsetbox import (AnchoredOffsetbox, AuxTransformBox,
- DrawingArea, TextArea, VPacker)
-from matplotlib.patches import Rectangle, Ellipse
-
-
-__all__ = ['AnchoredDrawingArea', 'AnchoredAuxTransformBox',
- 'AnchoredEllipse', 'AnchoredSizeBar']
-
-
-class AnchoredDrawingArea(AnchoredOffsetbox):
- @docstring.dedent
- def __init__(self, width, height, xdescent, ydescent,
- loc, pad=0.4, borderpad=0.5, prop=None, frameon=True,
- **kwargs):
- """
- An anchored container with a fixed size and fillable DrawingArea.
-
- Artists added to the *drawing_area* will have their coordinates
- interpreted as pixels. Any transformations set on the artists will be
- overridden.
-
- Parameters
- ----------
- width, height : int or float
- width and height of the container, in pixels.
-
- xdescent, ydescent : int or float
- descent of the container in the x- and y- direction, in pixels.
-
- loc : int
- Location of this artist. Valid location codes are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4,
- 'right' : 5,
- 'center left' : 6,
- 'center right' : 7,
- 'lower center' : 8,
- 'upper center' : 9,
- 'center' : 10
-
- pad : int or float, optional
- Padding around the child objects, in fraction of the font
- size. Defaults to 0.4.
-
- borderpad : int or float, optional
- Border padding, in fraction of the font size.
- Defaults to 0.5.
-
- prop : `matplotlib.font_manager.FontProperties`, optional
- Font property used as a reference for paddings.
-
- frameon : bool, optional
- If True, draw a box around this artists. Defaults to True.
-
- **kwargs :
- Keyworded arguments to pass to
- :class:`matplotlib.offsetbox.AnchoredOffsetbox`.
-
- Attributes
- ----------
- drawing_area : `matplotlib.offsetbox.DrawingArea`
- A container for artists to display.
-
- Examples
- --------
- To display blue and red circles of different sizes in the upper right
- of an axes *ax*:
-
- >>> ada = AnchoredDrawingArea(20, 20, 0, 0, loc=1, frameon=False)
- >>> ada.drawing_area.add_artist(Circle((10, 10), 10, fc="b"))
- >>> ada.drawing_area.add_artist(Circle((30, 10), 5, fc="r"))
- >>> ax.add_artist(ada)
- """
- self.da = DrawingArea(width, height, xdescent, ydescent)
- self.drawing_area = self.da
-
- super(AnchoredDrawingArea, self).__init__(
- loc, pad=pad, borderpad=borderpad, child=self.da, prop=None,
- frameon=frameon, **kwargs
- )
-
-
-class AnchoredAuxTransformBox(AnchoredOffsetbox):
- @docstring.dedent
- def __init__(self, transform, loc,
- pad=0.4, borderpad=0.5, prop=None, frameon=True, **kwargs):
- """
- An anchored container with transformed coordinates.
-
- Artists added to the *drawing_area* are scaled according to the
- coordinates of the transformation used. The dimensions of this artist
- will scale to contain the artists added.
-
- Parameters
- ----------
- transform : `matplotlib.transforms.Transform`
- The transformation object for the coordinate system in use, i.e.,
- :attr:`matplotlib.axes.Axes.transData`.
-
- loc : int
- Location of this artist. Valid location codes are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4,
- 'right' : 5,
- 'center left' : 6,
- 'center right' : 7,
- 'lower center' : 8,
- 'upper center' : 9,
- 'center' : 10
-
- pad : int or float, optional
- Padding around the child objects, in fraction of the font
- size. Defaults to 0.4.
-
- borderpad : int or float, optional
- Border padding, in fraction of the font size.
- Defaults to 0.5.
-
- prop : `matplotlib.font_manager.FontProperties`, optional
- Font property used as a reference for paddings.
-
- frameon : bool, optional
- If True, draw a box around this artists. Defaults to True.
-
- **kwargs :
- Keyworded arguments to pass to
- :class:`matplotlib.offsetbox.AnchoredOffsetbox`.
-
- Attributes
- ----------
- drawing_area : `matplotlib.offsetbox.AuxTransformBox`
- A container for artists to display.
-
- Examples
- --------
- To display an ellipse in the upper left, with a width of 0.1 and
- height of 0.4 in data coordinates:
-
- >>> box = AnchoredAuxTransformBox(ax.transData, loc=2)
- >>> el = Ellipse((0,0), width=0.1, height=0.4, angle=30)
- >>> box.drawing_area.add_artist(el)
- >>> ax.add_artist(box)
- """
- self.drawing_area = AuxTransformBox(transform)
-
- AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad,
- child=self.drawing_area,
- prop=prop,
- frameon=frameon,
- **kwargs)
-
-
-class AnchoredEllipse(AnchoredOffsetbox):
- @docstring.dedent
- def __init__(self, transform, width, height, angle, loc,
- pad=0.1, borderpad=0.1, prop=None, frameon=True, **kwargs):
- """
- Draw an anchored ellipse of a given size.
-
- Parameters
- ----------
- transform : `matplotlib.transforms.Transform`
- The transformation object for the coordinate system in use, i.e.,
- :attr:`matplotlib.axes.Axes.transData`.
-
- width, height : int or float
- Width and height of the ellipse, given in coordinates of
- *transform*.
-
- angle : int or float
- Rotation of the ellipse, in degrees, anti-clockwise.
-
- loc : int
- Location of this size bar. Valid location codes are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4,
- 'right' : 5,
- 'center left' : 6,
- 'center right' : 7,
- 'lower center' : 8,
- 'upper center' : 9,
- 'center' : 10
-
- pad : int or float, optional
- Padding around the ellipse, in fraction of the font size. Defaults
- to 0.1.
-
- borderpad : int or float, optional
- Border padding, in fraction of the font size. Defaults to 0.1.
-
- frameon : bool, optional
- If True, draw a box around the ellipse. Defaults to True.
-
- prop : `matplotlib.font_manager.FontProperties`, optional
- Font property used as a reference for paddings.
-
- **kwargs :
- Keyworded arguments to pass to
- :class:`matplotlib.offsetbox.AnchoredOffsetbox`.
-
- Attributes
- ----------
- ellipse : `matplotlib.patches.Ellipse`
- Ellipse patch drawn.
- """
- self._box = AuxTransformBox(transform)
- self.ellipse = Ellipse((0, 0), width, height, angle)
- self._box.add_artist(self.ellipse)
-
- AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad,
- child=self._box,
- prop=prop,
- frameon=frameon, **kwargs)
-
-
-class AnchoredSizeBar(AnchoredOffsetbox):
- @docstring.dedent
- def __init__(self, transform, size, label, loc,
- pad=0.1, borderpad=0.1, sep=2,
- frameon=True, size_vertical=0, color='black',
- label_top=False, fontproperties=None, fill_bar=None,
- **kwargs):
- """
- Draw a horizontal scale bar with a center-aligned label underneath.
-
- Parameters
- ----------
- transform : `matplotlib.transforms.Transform`
- The transformation object for the coordinate system in use, i.e.,
- :attr:`matplotlib.axes.Axes.transData`.
-
- size : int or float
- Horizontal length of the size bar, given in coordinates of
- *transform*.
-
- label : str
- Label to display.
-
- loc : int
- Location of this size bar. Valid location codes are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4,
- 'right' : 5,
- 'center left' : 6,
- 'center right' : 7,
- 'lower center' : 8,
- 'upper center' : 9,
- 'center' : 10
-
- pad : int or float, optional
- Padding around the label and size bar, in fraction of the font
- size. Defaults to 0.1.
-
- borderpad : int or float, optional
- Border padding, in fraction of the font size.
- Defaults to 0.1.
-
- sep : int or float, optional
- Separation between the label and the size bar, in points.
- Defaults to 2.
-
- frameon : bool, optional
- If True, draw a box around the horizontal bar and label.
- Defaults to True.
-
- size_vertical : int or float, optional
- Vertical length of the size bar, given in coordinates of
- *transform*. Defaults to 0.
-
- color : str, optional
- Color for the size bar and label.
- Defaults to black.
-
- label_top : bool, optional
- If True, the label will be over the size bar.
- Defaults to False.
-
- fontproperties : `matplotlib.font_manager.FontProperties`, optional
- Font properties for the label text.
-
- fill_bar : bool, optional
- If True and if size_vertical is nonzero, the size bar will
- be filled in with the color specified by the size bar.
- Defaults to True if `size_vertical` is greater than
- zero and False otherwise.
-
- **kwargs :
- Keyworded arguments to pass to
- :class:`matplotlib.offsetbox.AnchoredOffsetbox`.
-
- Attributes
- ----------
- size_bar : `matplotlib.offsetbox.AuxTransformBox`
- Container for the size bar.
-
- txt_label : `matplotlib.offsetbox.TextArea`
- Container for the label of the size bar.
-
- Notes
- -----
- If *prop* is passed as a keyworded argument, but *fontproperties* is
- not, then *prop* is be assumed to be the intended *fontproperties*.
- Using both *prop* and *fontproperties* is not supported.
-
- Examples
- --------
- >>> import matplotlib.pyplot as plt
- >>> import numpy as np
- >>> from mpl_toolkits.axes_grid1.anchored_artists import \
-AnchoredSizeBar
- >>> fig, ax = plt.subplots()
- >>> ax.imshow(np.random.random((10,10)))
- >>> bar = AnchoredSizeBar(ax.transData, 3, '3 data units', 4)
- >>> ax.add_artist(bar)
- >>> fig.show()
-
- Using all the optional parameters
-
- >>> import matplotlib.font_manager as fm
- >>> fontprops = fm.FontProperties(size=14, family='monospace')
- >>> bar = AnchoredSizeBar(ax.transData, 3, '3 units', 4, pad=0.5, \
-sep=5, borderpad=0.5, frameon=False, \
-size_vertical=0.5, color='white', \
-fontproperties=fontprops)
- """
- if fill_bar is None:
- fill_bar = size_vertical > 0
-
- self.size_bar = AuxTransformBox(transform)
- self.size_bar.add_artist(Rectangle((0, 0), size, size_vertical,
- fill=fill_bar, facecolor=color,
- edgecolor=color))
-
- if fontproperties is None and 'prop' in kwargs:
- fontproperties = kwargs.pop('prop')
-
- if fontproperties is None:
- textprops = {'color': color}
- else:
- textprops = {'color': color, 'fontproperties': fontproperties}
-
- self.txt_label = TextArea(
- label,
- minimumdescent=False,
- textprops=textprops)
-
- if label_top:
- _box_children = [self.txt_label, self.size_bar]
- else:
- _box_children = [self.size_bar, self.txt_label]
-
- self._box = VPacker(children=_box_children,
- align="center",
- pad=0, sep=sep)
-
- AnchoredOffsetbox.__init__(self, loc, pad=pad, borderpad=borderpad,
- child=self._box,
- prop=fontproperties,
- frameon=frameon, **kwargs)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/axes_divider.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/axes_divider.py
deleted file mode 100644
index b238e73cc5..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/axes_divider.py
+++ /dev/null
@@ -1,975 +0,0 @@
-"""
-The axes_divider module provides helper classes to adjust the positions of
-multiple axes at drawing time.
-
- Divider: this is the class that is used to calculate the axes
- position. It divides the given rectangular area into several sub
- rectangles. You initialize the divider by setting the horizontal
- and vertical lists of sizes that the division will be based on. You
- then use the new_locator method, whose return value is a callable
- object that can be used to set the axes_locator of the axes.
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import map
-
-import matplotlib.transforms as mtransforms
-
-from matplotlib.axes import SubplotBase
-
-from . import axes_size as Size
-
-
-class Divider(object):
- """
- This class calculates the axes position. It
- divides the given rectangular area into several
- sub-rectangles. You initialize the divider by setting the
- horizontal and vertical lists of sizes
- (:mod:`mpl_toolkits.axes_grid.axes_size`) that the division will
- be based on. You then use the new_locator method to create a
- callable object that can be used as the axes_locator of the
- axes.
- """
-
- def __init__(self, fig, pos, horizontal, vertical,
- aspect=None, anchor="C"):
- """
- Parameters
- ----------
- fig : Figure
- pos : tuple of 4 floats
- position of the rectangle that will be divided
- horizontal : list of :mod:`~mpl_toolkits.axes_grid.axes_size`
- sizes for horizontal division
- vertical : list of :mod:`~mpl_toolkits.axes_grid.axes_size`
- sizes for vertical division
- aspect : bool
- if True, the overall rectangular area is reduced
- so that the relative part of the horizontal and
- vertical scales have the same scale.
- anchor : {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', 'NW', 'W'}
- placement of the reduced rectangle when *aspect* is True
- """
-
- self._fig = fig
- self._pos = pos
- self._horizontal = horizontal
- self._vertical = vertical
- self._anchor = anchor
- self._aspect = aspect
- self._xrefindex = 0
- self._yrefindex = 0
- self._locator = None
-
- def get_horizontal_sizes(self, renderer):
- return [s.get_size(renderer) for s in self.get_horizontal()]
-
- def get_vertical_sizes(self, renderer):
- return [s.get_size(renderer) for s in self.get_vertical()]
-
- def get_vsize_hsize(self):
-
- from .axes_size import AddList
-
- vsize = AddList(self.get_vertical())
- hsize = AddList(self.get_horizontal())
-
- return vsize, hsize
-
- @staticmethod
- def _calc_k(l, total_size):
-
- rs_sum, as_sum = 0., 0.
-
- for _rs, _as in l:
- rs_sum += _rs
- as_sum += _as
-
- if rs_sum != 0.:
- k = (total_size - as_sum) / rs_sum
- return k
- else:
- return 0.
-
- @staticmethod
- def _calc_offsets(l, k):
-
- offsets = [0.]
-
- #for s in l:
- for _rs, _as in l:
- #_rs, _as = s.get_size(renderer)
- offsets.append(offsets[-1] + _rs*k + _as)
-
- return offsets
-
- def set_position(self, pos):
- """
- set the position of the rectangle.
-
- Parameters
- ----------
- pos : tuple of 4 floats
- position of the rectangle that will be divided
- """
- self._pos = pos
-
- def get_position(self):
- "return the position of the rectangle."
- return self._pos
-
- def set_anchor(self, anchor):
- """
- Parameters
- ----------
- anchor : {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', 'NW', 'W'}
- anchor position
-
- ===== ============
- value description
- ===== ============
- 'C' Center
- 'SW' bottom left
- 'S' bottom
- 'SE' bottom right
- 'E' right
- 'NE' top right
- 'N' top
- 'NW' top left
- 'W' left
- ===== ============
-
- """
- if anchor in mtransforms.Bbox.coefs or len(anchor) == 2:
- self._anchor = anchor
- else:
- raise ValueError('argument must be among %s' %
- ', '.join(mtransforms.BBox.coefs))
-
- def get_anchor(self):
- "return the anchor"
- return self._anchor
-
- def set_horizontal(self, h):
- """
- Parameters
- ----------
- h : list of :mod:`~mpl_toolkits.axes_grid.axes_size`
- sizes for horizontal division
- """
- self._horizontal = h
-
- def get_horizontal(self):
- "return horizontal sizes"
- return self._horizontal
-
- def set_vertical(self, v):
- """
- Parameters
- ----------
- v : list of :mod:`~mpl_toolkits.axes_grid.axes_size`
- sizes for vertical division
- """
- self._vertical = v
-
- def get_vertical(self):
- "return vertical sizes"
- return self._vertical
-
- def set_aspect(self, aspect=False):
- """
- Parameters
- ----------
- aspect : bool
- """
- self._aspect = aspect
-
- def get_aspect(self):
- "return aspect"
- return self._aspect
-
- def set_locator(self, _locator):
- self._locator = _locator
-
- def get_locator(self):
- return self._locator
-
- def get_position_runtime(self, ax, renderer):
- if self._locator is None:
- return self.get_position()
- else:
- return self._locator(ax, renderer).bounds
-
- def locate(self, nx, ny, nx1=None, ny1=None, axes=None, renderer=None):
- """
- Parameters
- ----------
- nx, nx1 : int
- Integers specifying the column-position of the
- cell. When *nx1* is None, a single *nx*-th column is
- specified. Otherwise location of columns spanning between *nx*
- to *nx1* (but excluding *nx1*-th column) is specified.
- ny, ny1 : int
- Same as *nx* and *nx1*, but for row positions.
- axes
- renderer
- """
-
- figW, figH = self._fig.get_size_inches()
- x, y, w, h = self.get_position_runtime(axes, renderer)
-
- hsizes = self.get_horizontal_sizes(renderer)
- vsizes = self.get_vertical_sizes(renderer)
- k_h = self._calc_k(hsizes, figW*w)
- k_v = self._calc_k(vsizes, figH*h)
-
- if self.get_aspect():
- k = min(k_h, k_v)
- ox = self._calc_offsets(hsizes, k)
- oy = self._calc_offsets(vsizes, k)
-
- ww = (ox[-1] - ox[0])/figW
- hh = (oy[-1] - oy[0])/figH
- pb = mtransforms.Bbox.from_bounds(x, y, w, h)
- pb1 = mtransforms.Bbox.from_bounds(x, y, ww, hh)
- pb1_anchored = pb1.anchored(self.get_anchor(), pb)
- x0, y0 = pb1_anchored.x0, pb1_anchored.y0
-
- else:
- ox = self._calc_offsets(hsizes, k_h)
- oy = self._calc_offsets(vsizes, k_v)
- x0, y0 = x, y
-
- if nx1 is None:
- nx1 = nx+1
- if ny1 is None:
- ny1 = ny+1
-
- x1, w1 = x0 + ox[nx]/figW, (ox[nx1] - ox[nx])/figW
- y1, h1 = y0 + oy[ny]/figH, (oy[ny1] - oy[ny])/figH
-
- return mtransforms.Bbox.from_bounds(x1, y1, w1, h1)
-
- def new_locator(self, nx, ny, nx1=None, ny1=None):
- """
- Returns a new locator
- (:class:`mpl_toolkits.axes_grid.axes_divider.AxesLocator`) for
- specified cell.
-
- Parameters
- ----------
- nx, nx1 : int
- Integers specifying the column-position of the
- cell. When *nx1* is None, a single *nx*-th column is
- specified. Otherwise location of columns spanning between *nx*
- to *nx1* (but excluding *nx1*-th column) is specified.
- ny, ny1 : int
- Same as *nx* and *nx1*, but for row positions.
- """
- return AxesLocator(self, nx, ny, nx1, ny1)
-
- def append_size(self, position, size):
-
- if position == "left":
- self._horizontal.insert(0, size)
- self._xrefindex += 1
- elif position == "right":
- self._horizontal.append(size)
- elif position == "bottom":
- self._vertical.insert(0, size)
- self._yrefindex += 1
- elif position == "top":
- self._vertical.append(size)
- else:
- raise ValueError("the position must be one of left," +
- " right, bottom, or top")
-
- def add_auto_adjustable_area(self,
- use_axes, pad=0.1,
- adjust_dirs=None,
- ):
- if adjust_dirs is None:
- adjust_dirs = ["left", "right", "bottom", "top"]
- from .axes_size import Padded, SizeFromFunc, GetExtentHelper
- for d in adjust_dirs:
- helper = GetExtentHelper(use_axes, d)
- size = SizeFromFunc(helper)
- padded_size = Padded(size, pad) # pad in inch
- self.append_size(d, padded_size)
-
-
-class AxesLocator(object):
- """
- A simple callable object, initialized with AxesDivider class,
- returns the position and size of the given cell.
- """
- def __init__(self, axes_divider, nx, ny, nx1=None, ny1=None):
- """
- Parameters
- ----------
- axes_divider : AxesDivider
- nx, nx1 : int
- Integers specifying the column-position of the
- cell. When *nx1* is None, a single *nx*-th column is
- specified. Otherwise location of columns spanning between *nx*
- to *nx1* (but excluding *nx1*-th column) is specified.
- ny, ny1 : int
- Same as *nx* and *nx1*, but for row positions.
- """
- self._axes_divider = axes_divider
-
- _xrefindex = axes_divider._xrefindex
- _yrefindex = axes_divider._yrefindex
-
- self._nx, self._ny = nx - _xrefindex, ny - _yrefindex
-
- if nx1 is None:
- nx1 = nx+1
- if ny1 is None:
- ny1 = ny+1
-
- self._nx1 = nx1 - _xrefindex
- self._ny1 = ny1 - _yrefindex
-
- def __call__(self, axes, renderer):
-
- _xrefindex = self._axes_divider._xrefindex
- _yrefindex = self._axes_divider._yrefindex
-
- return self._axes_divider.locate(self._nx + _xrefindex,
- self._ny + _yrefindex,
- self._nx1 + _xrefindex,
- self._ny1 + _yrefindex,
- axes,
- renderer)
-
- def get_subplotspec(self):
- if hasattr(self._axes_divider, "get_subplotspec"):
- return self._axes_divider.get_subplotspec()
- else:
- return None
-
-
-from matplotlib.gridspec import SubplotSpec, GridSpec
-
-
-class SubplotDivider(Divider):
- """
- The Divider class whose rectangle area is specified as a subplot geometry.
- """
-
- def __init__(self, fig, *args, **kwargs):
- """
- Parameters
- ----------
- fig : :class:`matplotlib.figure.Figure`
- args : tuple (*numRows*, *numCols*, *plotNum*)
- The array of subplots in the figure has dimensions *numRows*,
- *numCols*, and *plotNum* is the number of the subplot
- being created. *plotNum* starts at 1 in the upper left
- corner and increases to the right.
-
- If *numRows* <= *numCols* <= *plotNum* < 10, *args* can be the
- decimal integer *numRows* * 100 + *numCols* * 10 + *plotNum*.
- """
-
- self.figure = fig
-
- if len(args) == 1:
- if isinstance(args[0], SubplotSpec):
- self._subplotspec = args[0]
- else:
- try:
- s = str(int(args[0]))
- rows, cols, num = map(int, s)
- except ValueError:
- raise ValueError(
- 'Single argument to subplot must be a 3-digit integer')
- self._subplotspec = GridSpec(rows, cols)[num-1]
- # num - 1 for converting from MATLAB to python indexing
- elif len(args) == 3:
- rows, cols, num = args
- rows = int(rows)
- cols = int(cols)
- if isinstance(num, tuple) and len(num) == 2:
- num = [int(n) for n in num]
- self._subplotspec = GridSpec(rows, cols)[num[0]-1:num[1]]
- else:
- self._subplotspec = GridSpec(rows, cols)[int(num)-1]
- # num - 1 for converting from MATLAB to python indexing
- else:
- raise ValueError('Illegal argument(s) to subplot: %s' % (args,))
-
- # total = rows*cols
- # num -= 1 # convert from matlab to python indexing
- # # i.e., num in range(0,total)
- # if num >= total:
- # raise ValueError( 'Subplot number exceeds total subplots')
- # self._rows = rows
- # self._cols = cols
- # self._num = num
-
- # self.update_params()
-
- # sets self.fixbox
- self.update_params()
-
- pos = self.figbox.bounds
-
- horizontal = kwargs.pop("horizontal", [])
- vertical = kwargs.pop("vertical", [])
- aspect = kwargs.pop("aspect", None)
- anchor = kwargs.pop("anchor", "C")
-
- if kwargs:
- raise Exception("")
-
- Divider.__init__(self, fig, pos, horizontal, vertical,
- aspect=aspect, anchor=anchor)
-
- def get_position(self):
- "return the bounds of the subplot box"
-
- self.update_params() # update self.figbox
- return self.figbox.bounds
-
- # def update_params(self):
- # 'update the subplot position from fig.subplotpars'
-
- # rows = self._rows
- # cols = self._cols
- # num = self._num
-
- # pars = self.figure.subplotpars
- # left = pars.left
- # right = pars.right
- # bottom = pars.bottom
- # top = pars.top
- # wspace = pars.wspace
- # hspace = pars.hspace
- # totWidth = right-left
- # totHeight = top-bottom
-
- # figH = totHeight/(rows + hspace*(rows-1))
- # sepH = hspace*figH
-
- # figW = totWidth/(cols + wspace*(cols-1))
- # sepW = wspace*figW
-
- # rowNum, colNum = divmod(num, cols)
-
- # figBottom = top - (rowNum+1)*figH - rowNum*sepH
- # figLeft = left + colNum*(figW + sepW)
-
- # self.figbox = mtransforms.Bbox.from_bounds(figLeft, figBottom,
- # figW, figH)
-
- def update_params(self):
- 'update the subplot position from fig.subplotpars'
-
- self.figbox = self.get_subplotspec().get_position(self.figure)
-
- def get_geometry(self):
- 'get the subplot geometry, e.g., 2,2,3'
- rows, cols, num1, num2 = self.get_subplotspec().get_geometry()
- return rows, cols, num1+1 # for compatibility
-
- # COVERAGE NOTE: Never used internally or from examples
- def change_geometry(self, numrows, numcols, num):
- 'change subplot geometry, e.g., from 1,1,1 to 2,2,3'
- self._subplotspec = GridSpec(numrows, numcols)[num-1]
- self.update_params()
- self.set_position(self.figbox)
-
- def get_subplotspec(self):
- 'get the SubplotSpec instance'
- return self._subplotspec
-
- def set_subplotspec(self, subplotspec):
- 'set the SubplotSpec instance'
- self._subplotspec = subplotspec
-
-
-class AxesDivider(Divider):
- """
- Divider based on the pre-existing axes.
- """
-
- def __init__(self, axes, xref=None, yref=None):
- """
- Parameters
- ----------
- axes : :class:`~matplotlib.axes.Axes`
- xref
- yref
- """
- self._axes = axes
- if xref is None:
- self._xref = Size.AxesX(axes)
- else:
- self._xref = xref
- if yref is None:
- self._yref = Size.AxesY(axes)
- else:
- self._yref = yref
-
- Divider.__init__(self, fig=axes.get_figure(), pos=None,
- horizontal=[self._xref], vertical=[self._yref],
- aspect=None, anchor="C")
-
- def _get_new_axes(self, **kwargs):
- axes = self._axes
-
- axes_class = kwargs.pop("axes_class", None)
-
- if axes_class is None:
- if isinstance(axes, SubplotBase):
- axes_class = axes._axes_class
- else:
- axes_class = type(axes)
-
- ax = axes_class(axes.get_figure(),
- axes.get_position(original=True), **kwargs)
-
- return ax
-
- def new_horizontal(self, size, pad=None, pack_start=False, **kwargs):
- """
- Add a new axes on the right (or left) side of the main axes.
-
- Parameters
- ----------
- size : :mod:`~mpl_toolkits.axes_grid.axes_size` or float or string
- A width of the axes. If float or string is given, *from_any*
- function is used to create the size, with *ref_size* set to AxesX
- instance of the current axes.
- pad : :mod:`~mpl_toolkits.axes_grid.axes_size` or float or string
- Pad between the axes. It takes same argument as *size*.
- pack_start : bool
- If False, the new axes is appended at the end
- of the list, i.e., it became the right-most axes. If True, it is
- inserted at the start of the list, and becomes the left-most axes.
- kwargs
- All extra keywords arguments are passed to the created axes.
- If *axes_class* is given, the new axes will be created as an
- instance of the given class. Otherwise, the same class of the
- main axes will be used.
- """
-
- if pad:
- if not isinstance(pad, Size._Base):
- pad = Size.from_any(pad,
- fraction_ref=self._xref)
- if pack_start:
- self._horizontal.insert(0, pad)
- self._xrefindex += 1
- else:
- self._horizontal.append(pad)
-
- if not isinstance(size, Size._Base):
- size = Size.from_any(size,
- fraction_ref=self._xref)
-
- if pack_start:
- self._horizontal.insert(0, size)
- self._xrefindex += 1
- locator = self.new_locator(nx=0, ny=self._yrefindex)
- else:
- self._horizontal.append(size)
- locator = self.new_locator(nx=len(self._horizontal)-1, ny=self._yrefindex)
-
- ax = self._get_new_axes(**kwargs)
- ax.set_axes_locator(locator)
-
- return ax
-
- def new_vertical(self, size, pad=None, pack_start=False, **kwargs):
- """
- Add a new axes on the top (or bottom) side of the main axes.
-
- Parameters
- ----------
- size : :mod:`~mpl_toolkits.axes_grid.axes_size` or float or string
- A height of the axes. If float or string is given, *from_any*
- function is used to create the size, with *ref_size* set to AxesX
- instance of the current axes.
- pad : :mod:`~mpl_toolkits.axes_grid.axes_size` or float or string
- Pad between the axes. It takes same argument as *size*.
- pack_start : bool
- If False, the new axes is appended at the end
- of the list, i.e., it became the right-most axes. If True, it is
- inserted at the start of the list, and becomes the left-most axes.
- kwargs
- All extra keywords arguments are passed to the created axes.
- If *axes_class* is given, the new axes will be created as an
- instance of the given class. Otherwise, the same class of the
- main axes will be used.
- """
-
- if pad:
- if not isinstance(pad, Size._Base):
- pad = Size.from_any(pad,
- fraction_ref=self._yref)
- if pack_start:
- self._vertical.insert(0, pad)
- self._yrefindex += 1
- else:
- self._vertical.append(pad)
-
- if not isinstance(size, Size._Base):
- size = Size.from_any(size,
- fraction_ref=self._yref)
-
- if pack_start:
- self._vertical.insert(0, size)
- self._yrefindex += 1
- locator = self.new_locator(nx=self._xrefindex, ny=0)
- else:
- self._vertical.append(size)
- locator = self.new_locator(nx=self._xrefindex, ny=len(self._vertical)-1)
-
- ax = self._get_new_axes(**kwargs)
- ax.set_axes_locator(locator)
-
- return ax
-
- def append_axes(self, position, size, pad=None, add_to_figure=True,
- **kwargs):
- """
- create an axes at the given *position* with the same height
- (or width) of the main axes.
-
- *position*
- ["left"|"right"|"bottom"|"top"]
-
- *size* and *pad* should be axes_grid.axes_size compatible.
- """
-
- if position == "left":
- ax = self.new_horizontal(size, pad, pack_start=True, **kwargs)
- elif position == "right":
- ax = self.new_horizontal(size, pad, pack_start=False, **kwargs)
- elif position == "bottom":
- ax = self.new_vertical(size, pad, pack_start=True, **kwargs)
- elif position == "top":
- ax = self.new_vertical(size, pad, pack_start=False, **kwargs)
- else:
- raise ValueError("the position must be one of left," +
- " right, bottom, or top")
-
- if add_to_figure:
- self._fig.add_axes(ax)
- return ax
-
- def get_aspect(self):
- if self._aspect is None:
- aspect = self._axes.get_aspect()
- if aspect == "auto":
- return False
- else:
- return True
- else:
- return self._aspect
-
- def get_position(self):
- if self._pos is None:
- bbox = self._axes.get_position(original=True)
- return bbox.bounds
- else:
- return self._pos
-
- def get_anchor(self):
- if self._anchor is None:
- return self._axes.get_anchor()
- else:
- return self._anchor
-
- def get_subplotspec(self):
- if hasattr(self._axes, "get_subplotspec"):
- return self._axes.get_subplotspec()
- else:
- return None
-
-
-class HBoxDivider(SubplotDivider):
-
- def __init__(self, fig, *args, **kwargs):
- SubplotDivider.__init__(self, fig, *args, **kwargs)
-
- @staticmethod
- def _determine_karray(equivalent_sizes, appended_sizes,
- max_equivalent_size,
- total_appended_size):
-
- n = len(equivalent_sizes)
- import numpy as np
- A = np.mat(np.zeros((n+1, n+1), dtype="d"))
- B = np.zeros((n+1), dtype="d")
- # AxK = B
-
- # populated A
- for i, (r, a) in enumerate(equivalent_sizes):
- A[i, i] = r
- A[i, -1] = -1
- B[i] = -a
- A[-1, :-1] = [r for r, a in appended_sizes]
- B[-1] = total_appended_size - sum([a for rs, a in appended_sizes])
-
- karray_H = (A.I*np.mat(B).T).A1
- karray = karray_H[:-1]
- H = karray_H[-1]
-
- if H > max_equivalent_size:
- karray = ((max_equivalent_size -
- np.array([a for r, a in equivalent_sizes]))
- / np.array([r for r, a in equivalent_sizes]))
- return karray
-
- @staticmethod
- def _calc_offsets(appended_sizes, karray):
- offsets = [0.]
-
- #for s in l:
- for (r, a), k in zip(appended_sizes, karray):
- offsets.append(offsets[-1] + r*k + a)
-
- return offsets
-
- def new_locator(self, nx, nx1=None):
- """
- returns a new locator
- (:class:`mpl_toolkits.axes_grid.axes_divider.AxesLocator`) for
- specified cell.
-
- Parameters
- ----------
- nx, nx1 : int
- Integers specifying the column-position of the
- cell. When *nx1* is None, a single *nx*-th column is
- specified. Otherwise location of columns spanning between *nx*
- to *nx1* (but excluding *nx1*-th column) is specified.
- ny, ny1 : int
- Same as *nx* and *nx1*, but for row positions.
- """
- return AxesLocator(self, nx, 0, nx1, None)
-
- def _locate(self, x, y, w, h,
- y_equivalent_sizes, x_appended_sizes,
- figW, figH):
- """
- Parameters
- ----------
- x
- y
- w
- h
- y_equivalent_sizes
- x_appended_sizes
- figW
- figH
- """
-
- equivalent_sizes = y_equivalent_sizes
- appended_sizes = x_appended_sizes
-
- max_equivalent_size = figH*h
- total_appended_size = figW*w
- karray = self._determine_karray(equivalent_sizes, appended_sizes,
- max_equivalent_size,
- total_appended_size)
-
- ox = self._calc_offsets(appended_sizes, karray)
-
- ww = (ox[-1] - ox[0])/figW
- ref_h = equivalent_sizes[0]
- hh = (karray[0]*ref_h[0] + ref_h[1])/figH
- pb = mtransforms.Bbox.from_bounds(x, y, w, h)
- pb1 = mtransforms.Bbox.from_bounds(x, y, ww, hh)
- pb1_anchored = pb1.anchored(self.get_anchor(), pb)
- x0, y0 = pb1_anchored.x0, pb1_anchored.y0
-
- return x0, y0, ox, hh
-
- def locate(self, nx, ny, nx1=None, ny1=None, axes=None, renderer=None):
- """
- Parameters
- ----------
- axes_divider : AxesDivider
- nx, nx1 : int
- Integers specifying the column-position of the
- cell. When *nx1* is None, a single *nx*-th column is
- specified. Otherwise location of columns spanning between *nx*
- to *nx1* (but excluding *nx1*-th column) is specified.
- ny, ny1 : int
- Same as *nx* and *nx1*, but for row positions.
- axes
- renderer
- """
-
- figW, figH = self._fig.get_size_inches()
- x, y, w, h = self.get_position_runtime(axes, renderer)
-
- y_equivalent_sizes = self.get_vertical_sizes(renderer)
- x_appended_sizes = self.get_horizontal_sizes(renderer)
- x0, y0, ox, hh = self._locate(x, y, w, h,
- y_equivalent_sizes, x_appended_sizes,
- figW, figH)
- if nx1 is None:
- nx1 = nx+1
-
- x1, w1 = x0 + ox[nx]/figW, (ox[nx1] - ox[nx])/figW
- y1, h1 = y0, hh
-
- return mtransforms.Bbox.from_bounds(x1, y1, w1, h1)
-
-
-class VBoxDivider(HBoxDivider):
- """
- The Divider class whose rectangle area is specified as a subplot geometry.
- """
-
- def new_locator(self, ny, ny1=None):
- """
- returns a new locator
- (:class:`mpl_toolkits.axes_grid.axes_divider.AxesLocator`) for
- specified cell.
-
- Parameters
- ----------
- ny, ny1 : int
- Integers specifying the row-position of the
- cell. When *ny1* is None, a single *ny*-th row is
- specified. Otherwise location of rows spanning between *ny*
- to *ny1* (but excluding *ny1*-th row) is specified.
- """
- return AxesLocator(self, 0, ny, None, ny1)
-
- def locate(self, nx, ny, nx1=None, ny1=None, axes=None, renderer=None):
- """
- Parameters
- ----------
- axes_divider : AxesDivider
- nx, nx1 : int
- Integers specifying the column-position of the
- cell. When *nx1* is None, a single *nx*-th column is
- specified. Otherwise location of columns spanning between *nx*
- to *nx1* (but excluding *nx1*-th column) is specified.
- ny, ny1 : int
- Same as *nx* and *nx1*, but for row positions.
- axes
- renderer
- """
-
- figW, figH = self._fig.get_size_inches()
- x, y, w, h = self.get_position_runtime(axes, renderer)
-
- x_equivalent_sizes = self.get_horizontal_sizes(renderer)
- y_appended_sizes = self.get_vertical_sizes(renderer)
-
- y0, x0, oy, ww = self._locate(y, x, h, w,
- x_equivalent_sizes, y_appended_sizes,
- figH, figW)
- if ny1 is None:
- ny1 = ny+1
-
- x1, w1 = x0, ww
- y1, h1 = y0 + oy[ny]/figH, (oy[ny1] - oy[ny])/figH
-
- return mtransforms.Bbox.from_bounds(x1, y1, w1, h1)
-
-
-class LocatableAxesBase(object):
- def __init__(self, *kl, **kw):
-
- self._axes_class.__init__(self, *kl, **kw)
-
- self._locator = None
- self._locator_renderer = None
-
- def set_axes_locator(self, locator):
- self._locator = locator
-
- def get_axes_locator(self):
- return self._locator
-
- def apply_aspect(self, position=None):
-
- if self.get_axes_locator() is None:
- self._axes_class.apply_aspect(self, position)
- else:
- pos = self.get_axes_locator()(self, self._locator_renderer)
- self._axes_class.apply_aspect(self, position=pos)
-
- def draw(self, renderer=None, inframe=False):
-
- self._locator_renderer = renderer
-
- self._axes_class.draw(self, renderer, inframe)
-
- def _make_twin_axes(self, *kl, **kwargs):
- """
- Need to overload so that twinx/twiny will work with
- these axes.
- """
- if 'sharex' in kwargs and 'sharey' in kwargs:
- raise ValueError("Twinned Axes may share only one axis.")
- ax2 = type(self)(self.figure, self.get_position(True), *kl, **kwargs)
- ax2.set_axes_locator(self.get_axes_locator())
- self.figure.add_axes(ax2)
- self.set_adjustable('datalim')
- ax2.set_adjustable('datalim')
- self._twinned_axes.join(self, ax2)
- return ax2
-
-_locatableaxes_classes = {}
-
-
-def locatable_axes_factory(axes_class):
-
- new_class = _locatableaxes_classes.get(axes_class)
- if new_class is None:
- new_class = type(str("Locatable%s" % (axes_class.__name__)),
- (LocatableAxesBase, axes_class),
- {'_axes_class': axes_class})
-
- _locatableaxes_classes[axes_class] = new_class
-
- return new_class
-
-#if hasattr(maxes.Axes, "get_axes_locator"):
-# LocatableAxes = maxes.Axes
-#else:
-
-
-def make_axes_locatable(axes):
- if not hasattr(axes, "set_axes_locator"):
- new_class = locatable_axes_factory(type(axes))
- axes.__class__ = new_class
-
- divider = AxesDivider(axes)
- locator = divider.new_locator(nx=0, ny=0)
- axes.set_axes_locator(locator)
-
- return divider
-
-
-def make_axes_area_auto_adjustable(ax,
- use_axes=None, pad=0.1,
- adjust_dirs=None):
- if adjust_dirs is None:
- adjust_dirs = ["left", "right", "bottom", "top"]
- divider = make_axes_locatable(ax)
-
- if use_axes is None:
- use_axes = ax
-
- divider.add_auto_adjustable_area(use_axes=use_axes, pad=pad,
- adjust_dirs=adjust_dirs)
-
-#from matplotlib.axes import Axes
-from .mpl_axes import Axes
-LocatableAxes = locatable_axes_factory(Axes)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/axes_grid.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/axes_grid.py
deleted file mode 100644
index d7e4fa8768..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/axes_grid.py
+++ /dev/null
@@ -1,771 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import matplotlib.axes as maxes
-import matplotlib.cbook as cbook
-import matplotlib.ticker as ticker
-from matplotlib.gridspec import SubplotSpec
-
-from .axes_divider import Size, SubplotDivider, LocatableAxes, Divider
-from .colorbar import Colorbar
-
-
-def _extend_axes_pad(value):
- # Check whether a list/tuple/array or scalar has been passed
- ret = value
- if not hasattr(ret, "__getitem__"):
- ret = (value, value)
- return ret
-
-
-def _tick_only(ax, bottom_on, left_on):
- bottom_off = not bottom_on
- left_off = not left_on
- # [l.set_visible(bottom_off) for l in ax.get_xticklabels()]
- # [l.set_visible(left_off) for l in ax.get_yticklabels()]
- # ax.xaxis.label.set_visible(bottom_off)
- # ax.yaxis.label.set_visible(left_off)
- ax.axis["bottom"].toggle(ticklabels=bottom_off, label=bottom_off)
- ax.axis["left"].toggle(ticklabels=left_off, label=left_off)
-
-
-class CbarAxesBase(object):
-
- def colorbar(self, mappable, **kwargs):
- locator = kwargs.pop("locator", None)
-
- if locator is None:
- if "ticks" not in kwargs:
- kwargs["ticks"] = ticker.MaxNLocator(5)
- if locator is not None:
- if "ticks" in kwargs:
- raise ValueError("Either *locator* or *ticks* need" +
- " to be given, not both")
- else:
- kwargs["ticks"] = locator
-
- self._hold = True
- if self.orientation in ["top", "bottom"]:
- orientation = "horizontal"
- else:
- orientation = "vertical"
-
- cb = Colorbar(self, mappable, orientation=orientation, **kwargs)
- self._config_axes()
-
- def on_changed(m):
- cb.set_cmap(m.get_cmap())
- cb.set_clim(m.get_clim())
- cb.update_bruteforce(m)
-
- self.cbid = mappable.callbacksSM.connect('changed', on_changed)
- mappable.colorbar = cb
-
- self.locator = cb.cbar_axis.get_major_locator()
-
- return cb
-
- def _config_axes(self):
- '''
- Make an axes patch and outline.
- '''
- ax = self
- ax.set_navigate(False)
-
- ax.axis[:].toggle(all=False)
- b = self._default_label_on
- ax.axis[self.orientation].toggle(all=b)
-
- # for axis in ax.axis.values():
- # axis.major_ticks.set_visible(False)
- # axis.minor_ticks.set_visible(False)
- # axis.major_ticklabels.set_visible(False)
- # axis.minor_ticklabels.set_visible(False)
- # axis.label.set_visible(False)
-
- # axis = ax.axis[self.orientation]
- # axis.major_ticks.set_visible(True)
- # axis.minor_ticks.set_visible(True)
-
- #axis.major_ticklabels.set_size(
- # int(axis.major_ticklabels.get_size()*.9))
- #axis.major_tick_pad = 3
-
- # axis.major_ticklabels.set_visible(b)
- # axis.minor_ticklabels.set_visible(b)
- # axis.label.set_visible(b)
-
- def toggle_label(self, b):
- self._default_label_on = b
- axis = self.axis[self.orientation]
- axis.toggle(ticklabels=b, label=b)
- #axis.major_ticklabels.set_visible(b)
- #axis.minor_ticklabels.set_visible(b)
- #axis.label.set_visible(b)
-
-
-class CbarAxes(CbarAxesBase, LocatableAxes):
- def __init__(self, *kl, **kwargs):
- orientation = kwargs.pop("orientation", None)
- if orientation is None:
- raise ValueError("orientation must be specified")
- self.orientation = orientation
- self._default_label_on = True
- self.locator = None
-
- super(LocatableAxes, self).__init__(*kl, **kwargs)
-
- def cla(self):
- super(LocatableAxes, self).cla()
- self._config_axes()
-
-
-class Grid(object):
- """
- A class that creates a grid of Axes. In matplotlib, the axes
- location (and size) is specified in the normalized figure
- coordinates. This may not be ideal for images that needs to be
- displayed with a given aspect ratio. For example, displaying
- images of a same size with some fixed padding between them cannot
- be easily done in matplotlib. AxesGrid is used in such case.
- """
-
- _defaultLocatableAxesClass = LocatableAxes
-
- def __init__(self, fig,
- rect,
- nrows_ncols,
- ngrids=None,
- direction="row",
- axes_pad=0.02,
- add_all=True,
- share_all=False,
- share_x=True,
- share_y=True,
- #aspect=True,
- label_mode="L",
- axes_class=None,
- ):
- """
- Build an :class:`Grid` instance with a grid nrows*ncols
- :class:`~matplotlib.axes.Axes` in
- :class:`~matplotlib.figure.Figure` *fig* with
- *rect=[left, bottom, width, height]* (in
- :class:`~matplotlib.figure.Figure` coordinates) or
- the subplot position code (e.g., "121").
-
- Optional keyword arguments:
-
- ================ ======== =========================================
- Keyword Default Description
- ================ ======== =========================================
- direction "row" [ "row" | "column" ]
- axes_pad 0.02 float| pad between axes given in inches
- or tuple-like of floats,
- (horizontal padding, vertical padding)
- add_all True bool
- share_all False bool
- share_x True bool
- share_y True bool
- label_mode "L" [ "L" | "1" | "all" ]
- axes_class None a type object which must be a subclass
- of :class:`~matplotlib.axes.Axes`
- ================ ======== =========================================
- """
- self._nrows, self._ncols = nrows_ncols
-
- if ngrids is None:
- ngrids = self._nrows * self._ncols
- else:
- if (ngrids > self._nrows * self._ncols) or (ngrids <= 0):
- raise Exception("")
-
- self.ngrids = ngrids
-
- self._init_axes_pad(axes_pad)
-
- if direction not in ["column", "row"]:
- raise Exception("")
-
- self._direction = direction
-
- if axes_class is None:
- axes_class = self._defaultLocatableAxesClass
- axes_class_args = {}
- else:
- if (type(axes_class)) == type and \
- issubclass(axes_class,
- self._defaultLocatableAxesClass.Axes):
- axes_class_args = {}
- else:
- axes_class, axes_class_args = axes_class
-
- self.axes_all = []
- self.axes_column = [[] for _ in range(self._ncols)]
- self.axes_row = [[] for _ in range(self._nrows)]
-
- h = []
- v = []
- if isinstance(rect, six.string_types) or cbook.is_numlike(rect):
- self._divider = SubplotDivider(fig, rect, horizontal=h, vertical=v,
- aspect=False)
- elif isinstance(rect, SubplotSpec):
- self._divider = SubplotDivider(fig, rect, horizontal=h, vertical=v,
- aspect=False)
- elif len(rect) == 3:
- kw = dict(horizontal=h, vertical=v, aspect=False)
- self._divider = SubplotDivider(fig, *rect, **kw)
- elif len(rect) == 4:
- self._divider = Divider(fig, rect, horizontal=h, vertical=v,
- aspect=False)
- else:
- raise Exception("")
-
- rect = self._divider.get_position()
-
- # reference axes
- self._column_refax = [None for _ in range(self._ncols)]
- self._row_refax = [None for _ in range(self._nrows)]
- self._refax = None
-
- for i in range(self.ngrids):
-
- col, row = self._get_col_row(i)
-
- if share_all:
- sharex = self._refax
- sharey = self._refax
- else:
- if share_x:
- sharex = self._column_refax[col]
- else:
- sharex = None
-
- if share_y:
- sharey = self._row_refax[row]
- else:
- sharey = None
-
- ax = axes_class(fig, rect, sharex=sharex, sharey=sharey,
- **axes_class_args)
-
- if share_all:
- if self._refax is None:
- self._refax = ax
- else:
- if sharex is None:
- self._column_refax[col] = ax
- if sharey is None:
- self._row_refax[row] = ax
-
- self.axes_all.append(ax)
- self.axes_column[col].append(ax)
- self.axes_row[row].append(ax)
-
- self.axes_llc = self.axes_column[0][-1]
-
- self._update_locators()
-
- if add_all:
- for ax in self.axes_all:
- fig.add_axes(ax)
-
- self.set_label_mode(label_mode)
-
- def _init_axes_pad(self, axes_pad):
- axes_pad = _extend_axes_pad(axes_pad)
- self._axes_pad = axes_pad
-
- self._horiz_pad_size = Size.Fixed(axes_pad[0])
- self._vert_pad_size = Size.Fixed(axes_pad[1])
-
- def _update_locators(self):
-
- h = []
-
- h_ax_pos = []
-
- for _ in self._column_refax:
- #if h: h.append(Size.Fixed(self._axes_pad))
- if h:
- h.append(self._horiz_pad_size)
-
- h_ax_pos.append(len(h))
-
- sz = Size.Scaled(1)
- h.append(sz)
-
- v = []
-
- v_ax_pos = []
- for _ in self._row_refax[::-1]:
- #if v: v.append(Size.Fixed(self._axes_pad))
- if v:
- v.append(self._vert_pad_size)
-
- v_ax_pos.append(len(v))
- sz = Size.Scaled(1)
- v.append(sz)
-
- for i in range(self.ngrids):
- col, row = self._get_col_row(i)
- locator = self._divider.new_locator(nx=h_ax_pos[col],
- ny=v_ax_pos[self._nrows - 1 - row])
- self.axes_all[i].set_axes_locator(locator)
-
- self._divider.set_horizontal(h)
- self._divider.set_vertical(v)
-
- def _get_col_row(self, n):
- if self._direction == "column":
- col, row = divmod(n, self._nrows)
- else:
- row, col = divmod(n, self._ncols)
-
- return col, row
-
- # Good to propagate __len__ if we have __getitem__
- def __len__(self):
- return len(self.axes_all)
-
- def __getitem__(self, i):
- return self.axes_all[i]
-
- def get_geometry(self):
- """
- get geometry of the grid. Returns a tuple of two integer,
- representing number of rows and number of columns.
- """
- return self._nrows, self._ncols
-
- def set_axes_pad(self, axes_pad):
- "set axes_pad"
- self._axes_pad = axes_pad
-
- # These two lines actually differ from ones in _init_axes_pad
- self._horiz_pad_size.fixed_size = axes_pad[0]
- self._vert_pad_size.fixed_size = axes_pad[1]
-
- def get_axes_pad(self):
- """
- get axes_pad
-
- Returns
- -------
- tuple
- Padding in inches, (horizontal pad, vertical pad)
- """
- return self._axes_pad
-
- def set_aspect(self, aspect):
- "set aspect"
- self._divider.set_aspect(aspect)
-
- def get_aspect(self):
- "get aspect"
- return self._divider.get_aspect()
-
- def set_label_mode(self, mode):
- "set label_mode"
- if mode == "all":
- for ax in self.axes_all:
- _tick_only(ax, False, False)
- elif mode == "L":
- # left-most axes
- for ax in self.axes_column[0][:-1]:
- _tick_only(ax, bottom_on=True, left_on=False)
- # lower-left axes
- ax = self.axes_column[0][-1]
- _tick_only(ax, bottom_on=False, left_on=False)
-
- for col in self.axes_column[1:]:
- # axes with no labels
- for ax in col[:-1]:
- _tick_only(ax, bottom_on=True, left_on=True)
-
- # bottom
- ax = col[-1]
- _tick_only(ax, bottom_on=False, left_on=True)
-
- elif mode == "1":
- for ax in self.axes_all:
- _tick_only(ax, bottom_on=True, left_on=True)
-
- ax = self.axes_llc
- _tick_only(ax, bottom_on=False, left_on=False)
-
- def get_divider(self):
- return self._divider
-
- def set_axes_locator(self, locator):
- self._divider.set_locator(locator)
-
- def get_axes_locator(self):
- return self._divider.get_locator()
-
- def get_vsize_hsize(self):
-
- return self._divider.get_vsize_hsize()
-# from axes_size import AddList
-
-# vsize = AddList(self._divider.get_vertical())
-# hsize = AddList(self._divider.get_horizontal())
-
-# return vsize, hsize
-
-
-class ImageGrid(Grid):
- """
- A class that creates a grid of Axes. In matplotlib, the axes
- location (and size) is specified in the normalized figure
- coordinates. This may not be ideal for images that needs to be
- displayed with a given aspect ratio. For example, displaying
- images of a same size with some fixed padding between them cannot
- be easily done in matplotlib. ImageGrid is used in such case.
- """
-
- _defaultCbarAxesClass = CbarAxes
-
- def __init__(self, fig,
- rect,
- nrows_ncols,
- ngrids=None,
- direction="row",
- axes_pad=0.02,
- add_all=True,
- share_all=False,
- aspect=True,
- label_mode="L",
- cbar_mode=None,
- cbar_location="right",
- cbar_pad=None,
- cbar_size="5%",
- cbar_set_cax=True,
- axes_class=None,
- ):
- """
- Build an :class:`ImageGrid` instance with a grid nrows*ncols
- :class:`~matplotlib.axes.Axes` in
- :class:`~matplotlib.figure.Figure` *fig* with
- *rect=[left, bottom, width, height]* (in
- :class:`~matplotlib.figure.Figure` coordinates) or
- the subplot position code (e.g., "121").
-
- Optional keyword arguments:
-
- ================ ======== =========================================
- Keyword Default Description
- ================ ======== =========================================
- direction "row" [ "row" | "column" ]
- axes_pad 0.02 float| pad between axes given in inches
- or tuple-like of floats,
- (horizontal padding, vertical padding)
- add_all True bool
- share_all False bool
- aspect True bool
- label_mode "L" [ "L" | "1" | "all" ]
- cbar_mode None [ "each" | "single" | "edge" ]
- cbar_location "right" [ "left" | "right" | "bottom" | "top" ]
- cbar_pad None
- cbar_size "5%"
- cbar_set_cax True bool
- axes_class None a type object which must be a subclass
- of axes_grid's subclass of
- :class:`~matplotlib.axes.Axes`
- ================ ======== =========================================
-
- *cbar_set_cax* : if True, each axes in the grid has a cax
- attribute that is bind to associated cbar_axes.
- """
- self._nrows, self._ncols = nrows_ncols
-
- if ngrids is None:
- ngrids = self._nrows * self._ncols
- else:
- if not 0 < ngrids <= self._nrows * self._ncols:
- raise Exception
-
- self.ngrids = ngrids
-
- axes_pad = _extend_axes_pad(axes_pad)
- self._axes_pad = axes_pad
-
- self._colorbar_mode = cbar_mode
- self._colorbar_location = cbar_location
- if cbar_pad is None:
- # horizontal or vertical arrangement?
- if cbar_location in ("left", "right"):
- self._colorbar_pad = axes_pad[0]
- else:
- self._colorbar_pad = axes_pad[1]
- else:
- self._colorbar_pad = cbar_pad
-
- self._colorbar_size = cbar_size
-
- self._init_axes_pad(axes_pad)
-
- if direction not in ["column", "row"]:
- raise Exception("")
-
- self._direction = direction
-
- if axes_class is None:
- axes_class = self._defaultLocatableAxesClass
- axes_class_args = {}
- else:
- if isinstance(axes_class, maxes.Axes):
- axes_class_args = {}
- else:
- axes_class, axes_class_args = axes_class
-
- self.axes_all = []
- self.axes_column = [[] for _ in range(self._ncols)]
- self.axes_row = [[] for _ in range(self._nrows)]
-
- self.cbar_axes = []
-
- h = []
- v = []
- if isinstance(rect, six.string_types) or cbook.is_numlike(rect):
- self._divider = SubplotDivider(fig, rect, horizontal=h, vertical=v,
- aspect=aspect)
- elif isinstance(rect, SubplotSpec):
- self._divider = SubplotDivider(fig, rect, horizontal=h, vertical=v,
- aspect=aspect)
- elif len(rect) == 3:
- kw = dict(horizontal=h, vertical=v, aspect=aspect)
- self._divider = SubplotDivider(fig, *rect, **kw)
- elif len(rect) == 4:
- self._divider = Divider(fig, rect, horizontal=h, vertical=v,
- aspect=aspect)
- else:
- raise Exception("")
-
- rect = self._divider.get_position()
-
- # reference axes
- self._column_refax = [None for _ in range(self._ncols)]
- self._row_refax = [None for _ in range(self._nrows)]
- self._refax = None
-
- for i in range(self.ngrids):
-
- col, row = self._get_col_row(i)
-
- if share_all:
- if self.axes_all:
- sharex = self.axes_all[0]
- sharey = self.axes_all[0]
- else:
- sharex = None
- sharey = None
- else:
- sharex = self._column_refax[col]
- sharey = self._row_refax[row]
-
- ax = axes_class(fig, rect, sharex=sharex, sharey=sharey,
- **axes_class_args)
-
- self.axes_all.append(ax)
- self.axes_column[col].append(ax)
- self.axes_row[row].append(ax)
-
- if share_all:
- if self._refax is None:
- self._refax = ax
- if sharex is None:
- self._column_refax[col] = ax
- if sharey is None:
- self._row_refax[row] = ax
-
- cax = self._defaultCbarAxesClass(fig, rect,
- orientation=self._colorbar_location)
- self.cbar_axes.append(cax)
-
- self.axes_llc = self.axes_column[0][-1]
-
- self._update_locators()
-
- if add_all:
- for ax in self.axes_all+self.cbar_axes:
- fig.add_axes(ax)
-
- if cbar_set_cax:
- if self._colorbar_mode == "single":
- for ax in self.axes_all:
- ax.cax = self.cbar_axes[0]
- elif self._colorbar_mode == "edge":
- for index, ax in enumerate(self.axes_all):
- col, row = self._get_col_row(index)
- if self._colorbar_location in ("left", "right"):
- ax.cax = self.cbar_axes[row]
- else:
- ax.cax = self.cbar_axes[col]
- else:
- for ax, cax in zip(self.axes_all, self.cbar_axes):
- ax.cax = cax
-
- self.set_label_mode(label_mode)
-
- def _update_locators(self):
-
- h = []
- v = []
-
- h_ax_pos = []
- h_cb_pos = []
- if (self._colorbar_mode == "single" and
- self._colorbar_location in ('left', 'bottom')):
- if self._colorbar_location == "left":
- #sz = Size.Fraction(Size.AxesX(self.axes_llc), self._nrows)
- sz = Size.Fraction(self._nrows, Size.AxesX(self.axes_llc))
- h.append(Size.from_any(self._colorbar_size, sz))
- h.append(Size.from_any(self._colorbar_pad, sz))
- locator = self._divider.new_locator(nx=0, ny=0, ny1=-1)
- elif self._colorbar_location == "bottom":
- #sz = Size.Fraction(Size.AxesY(self.axes_llc), self._ncols)
- sz = Size.Fraction(self._ncols, Size.AxesY(self.axes_llc))
- v.append(Size.from_any(self._colorbar_size, sz))
- v.append(Size.from_any(self._colorbar_pad, sz))
- locator = self._divider.new_locator(nx=0, nx1=-1, ny=0)
- for i in range(self.ngrids):
- self.cbar_axes[i].set_visible(False)
- self.cbar_axes[0].set_axes_locator(locator)
- self.cbar_axes[0].set_visible(True)
-
- for col, ax in enumerate(self.axes_row[0]):
- if h:
- h.append(self._horiz_pad_size) # Size.Fixed(self._axes_pad))
-
- if ax:
- sz = Size.AxesX(ax, aspect="axes", ref_ax=self.axes_all[0])
- else:
- sz = Size.AxesX(self.axes_all[0],
- aspect="axes", ref_ax=self.axes_all[0])
-
- if (self._colorbar_mode == "each" or
- (self._colorbar_mode == 'edge' and
- col == 0)) and self._colorbar_location == "left":
- h_cb_pos.append(len(h))
- h.append(Size.from_any(self._colorbar_size, sz))
- h.append(Size.from_any(self._colorbar_pad, sz))
-
- h_ax_pos.append(len(h))
-
- h.append(sz)
-
- if ((self._colorbar_mode == "each" or
- (self._colorbar_mode == 'edge' and
- col == self._ncols - 1)) and
- self._colorbar_location == "right"):
- h.append(Size.from_any(self._colorbar_pad, sz))
- h_cb_pos.append(len(h))
- h.append(Size.from_any(self._colorbar_size, sz))
-
- v_ax_pos = []
- v_cb_pos = []
- for row, ax in enumerate(self.axes_column[0][::-1]):
- if v:
- v.append(self._vert_pad_size) # Size.Fixed(self._axes_pad))
-
- if ax:
- sz = Size.AxesY(ax, aspect="axes", ref_ax=self.axes_all[0])
- else:
- sz = Size.AxesY(self.axes_all[0],
- aspect="axes", ref_ax=self.axes_all[0])
-
- if (self._colorbar_mode == "each" or
- (self._colorbar_mode == 'edge' and
- row == 0)) and self._colorbar_location == "bottom":
- v_cb_pos.append(len(v))
- v.append(Size.from_any(self._colorbar_size, sz))
- v.append(Size.from_any(self._colorbar_pad, sz))
-
- v_ax_pos.append(len(v))
- v.append(sz)
-
- if ((self._colorbar_mode == "each" or
- (self._colorbar_mode == 'edge' and
- row == self._nrows - 1)) and
- self._colorbar_location == "top"):
- v.append(Size.from_any(self._colorbar_pad, sz))
- v_cb_pos.append(len(v))
- v.append(Size.from_any(self._colorbar_size, sz))
-
- for i in range(self.ngrids):
- col, row = self._get_col_row(i)
- #locator = self._divider.new_locator(nx=4*col,
- # ny=2*(self._nrows - row - 1))
- locator = self._divider.new_locator(nx=h_ax_pos[col],
- ny=v_ax_pos[self._nrows-1-row])
- self.axes_all[i].set_axes_locator(locator)
-
- if self._colorbar_mode == "each":
- if self._colorbar_location in ("right", "left"):
- locator = self._divider.new_locator(
- nx=h_cb_pos[col], ny=v_ax_pos[self._nrows - 1 - row])
-
- elif self._colorbar_location in ("top", "bottom"):
- locator = self._divider.new_locator(
- nx=h_ax_pos[col], ny=v_cb_pos[self._nrows - 1 - row])
-
- self.cbar_axes[i].set_axes_locator(locator)
- elif self._colorbar_mode == 'edge':
- if ((self._colorbar_location == 'left' and col == 0) or
- (self._colorbar_location == 'right'
- and col == self._ncols-1)):
- locator = self._divider.new_locator(
- nx=h_cb_pos[0], ny=v_ax_pos[self._nrows -1 - row])
- self.cbar_axes[row].set_axes_locator(locator)
- elif ((self._colorbar_location == 'bottom' and
- row == self._nrows - 1) or
- (self._colorbar_location == 'top' and row == 0)):
- locator = self._divider.new_locator(nx=h_ax_pos[col],
- ny=v_cb_pos[0])
- self.cbar_axes[col].set_axes_locator(locator)
-
- if self._colorbar_mode == "single":
- if self._colorbar_location == "right":
- #sz = Size.Fraction(Size.AxesX(self.axes_llc), self._nrows)
- sz = Size.Fraction(self._nrows, Size.AxesX(self.axes_llc))
- h.append(Size.from_any(self._colorbar_pad, sz))
- h.append(Size.from_any(self._colorbar_size, sz))
- locator = self._divider.new_locator(nx=-2, ny=0, ny1=-1)
- elif self._colorbar_location == "top":
- #sz = Size.Fraction(Size.AxesY(self.axes_llc), self._ncols)
- sz = Size.Fraction(self._ncols, Size.AxesY(self.axes_llc))
- v.append(Size.from_any(self._colorbar_pad, sz))
- v.append(Size.from_any(self._colorbar_size, sz))
- locator = self._divider.new_locator(nx=0, nx1=-1, ny=-2)
- if self._colorbar_location in ("right", "top"):
- for i in range(self.ngrids):
- self.cbar_axes[i].set_visible(False)
- self.cbar_axes[0].set_axes_locator(locator)
- self.cbar_axes[0].set_visible(True)
- elif self._colorbar_mode == "each":
- for i in range(self.ngrids):
- self.cbar_axes[i].set_visible(True)
- elif self._colorbar_mode == "edge":
- if self._colorbar_location in ('right', 'left'):
- count = self._nrows
- else:
- count = self._ncols
- for i in range(count):
- self.cbar_axes[i].set_visible(True)
- for j in range(i + 1, self.ngrids):
- self.cbar_axes[j].set_visible(False)
- else:
- for i in range(self.ngrids):
- self.cbar_axes[i].set_visible(False)
- self.cbar_axes[i].set_position([1., 1., 0.001, 0.001],
- which="active")
-
- self._divider.set_horizontal(h)
- self._divider.set_vertical(v)
-
-
-AxesGrid = ImageGrid
-
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/axes_rgb.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/axes_rgb.py
deleted file mode 100644
index e62d4f0615..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/axes_rgb.py
+++ /dev/null
@@ -1,228 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import numpy as np
-from .axes_divider import make_axes_locatable, Size, locatable_axes_factory
-import sys
-from .mpl_axes import Axes
-
-
-def make_rgb_axes(ax, pad=0.01, axes_class=None, add_all=True):
- """
- pad : fraction of the axes height.
- """
-
- divider = make_axes_locatable(ax)
-
- pad_size = Size.Fraction(pad, Size.AxesY(ax))
-
- xsize = Size.Fraction((1.-2.*pad)/3., Size.AxesX(ax))
- ysize = Size.Fraction((1.-2.*pad)/3., Size.AxesY(ax))
-
- divider.set_horizontal([Size.AxesX(ax), pad_size, xsize])
- divider.set_vertical([ysize, pad_size, ysize, pad_size, ysize])
-
- ax.set_axes_locator(divider.new_locator(0, 0, ny1=-1))
-
- ax_rgb = []
- if axes_class is None:
- try:
- axes_class = locatable_axes_factory(ax._axes_class)
- except AttributeError:
- axes_class = locatable_axes_factory(type(ax))
-
- for ny in [4, 2, 0]:
- ax1 = axes_class(ax.get_figure(),
- ax.get_position(original=True),
- sharex=ax, sharey=ax)
- locator = divider.new_locator(nx=2, ny=ny)
- ax1.set_axes_locator(locator)
- for t in ax1.yaxis.get_ticklabels() + ax1.xaxis.get_ticklabels():
- t.set_visible(False)
- try:
- for axis in ax1.axis.values():
- axis.major_ticklabels.set_visible(False)
- except AttributeError:
- pass
-
- ax_rgb.append(ax1)
-
- if add_all:
- fig = ax.get_figure()
- for ax1 in ax_rgb:
- fig.add_axes(ax1)
-
- return ax_rgb
-
-
-def imshow_rgb(ax, r, g, b, **kwargs):
- ny, nx = r.shape
- R = np.zeros([ny, nx, 3], dtype="d")
- R[:,:,0] = r
- G = np.zeros_like(R)
- G[:,:,1] = g
- B = np.zeros_like(R)
- B[:,:,2] = b
-
- RGB = R + G + B
-
- im_rgb = ax.imshow(RGB, **kwargs)
-
- return im_rgb
-
-
-class RGBAxesBase(object):
- """base class for a 4-panel imshow (RGB, R, G, B)
-
- Layout:
- +---------------+-----+
- | | R |
- + +-----+
- | RGB | G |
- + +-----+
- | | B |
- +---------------+-----+
-
- Attributes
- ----------
- _defaultAxesClass : matplotlib.axes.Axes
- defaults to 'Axes' in RGBAxes child class.
- No default in abstract base class
- RGB : _defaultAxesClass
- The axes object for the three-channel imshow
- R : _defaultAxesClass
- The axes object for the red channel imshow
- G : _defaultAxesClass
- The axes object for the green channel imshow
- B : _defaultAxesClass
- The axes object for the blue channel imshow
- """
- def __init__(self, *kl, **kwargs):
- """
- Parameters
- ----------
- pad : float
- fraction of the axes height to put as padding.
- defaults to 0.0
- add_all : bool
- True: Add the {rgb, r, g, b} axes to the figure
- defaults to True.
- axes_class : matplotlib.axes.Axes
-
- kl :
- Unpacked into axes_class() init for RGB
- kwargs :
- Unpacked into axes_class() init for RGB, R, G, B axes
- """
- pad = kwargs.pop("pad", 0.0)
- add_all = kwargs.pop("add_all", True)
- try:
- axes_class = kwargs.pop("axes_class", self._defaultAxesClass)
- except AttributeError:
- new_msg = ("A subclass of RGBAxesBase must have a "
- "_defaultAxesClass attribute. If you are not sure which "
- "axes class to use, consider using "
- "mpl_toolkits.axes_grid1.mpl_axes.Axes.")
- six.reraise(AttributeError, AttributeError(new_msg),
- sys.exc_info()[2])
-
- ax = axes_class(*kl, **kwargs)
-
- divider = make_axes_locatable(ax)
-
- pad_size = Size.Fraction(pad, Size.AxesY(ax))
-
- xsize = Size.Fraction((1.-2.*pad)/3., Size.AxesX(ax))
- ysize = Size.Fraction((1.-2.*pad)/3., Size.AxesY(ax))
-
- divider.set_horizontal([Size.AxesX(ax), pad_size, xsize])
- divider.set_vertical([ysize, pad_size, ysize, pad_size, ysize])
-
- ax.set_axes_locator(divider.new_locator(0, 0, ny1=-1))
-
- ax_rgb = []
- for ny in [4, 2, 0]:
- ax1 = axes_class(ax.get_figure(),
- ax.get_position(original=True),
- sharex=ax, sharey=ax, **kwargs)
- locator = divider.new_locator(nx=2, ny=ny)
- ax1.set_axes_locator(locator)
- ax1.axis[:].toggle(ticklabels=False)
- ax_rgb.append(ax1)
-
- self.RGB = ax
- self.R, self.G, self.B = ax_rgb
-
- if add_all:
- fig = ax.get_figure()
- fig.add_axes(ax)
- self.add_RGB_to_figure()
-
- self._config_axes()
-
- def _config_axes(self, line_color='w', marker_edge_color='w'):
- """Set the line color and ticks for the axes
-
- Parameters
- ----------
- line_color : any matplotlib color
- marker_edge_color : any matplotlib color
- """
- for ax1 in [self.RGB, self.R, self.G, self.B]:
- ax1.axis[:].line.set_color(line_color)
- ax1.axis[:].major_ticks.set_markeredgecolor(marker_edge_color)
-
- def add_RGB_to_figure(self):
- """Add the red, green and blue axes to the RGB composite's axes figure
- """
- self.RGB.get_figure().add_axes(self.R)
- self.RGB.get_figure().add_axes(self.G)
- self.RGB.get_figure().add_axes(self.B)
-
- def imshow_rgb(self, r, g, b, **kwargs):
- """Create the four images {rgb, r, g, b}
-
- Parameters
- ----------
- r : array-like
- The red array
- g : array-like
- The green array
- b : array-like
- The blue array
- kwargs : imshow kwargs
- kwargs get unpacked into the imshow calls for the four images
-
- Returns
- -------
- rgb : matplotlib.image.AxesImage
- r : matplotlib.image.AxesImage
- g : matplotlib.image.AxesImage
- b : matplotlib.image.AxesImage
- """
- if not (r.shape == g.shape == b.shape):
- raise ValueError('Input shapes do not match.'
- '\nr.shape = {}'
- '\ng.shape = {}'
- '\nb.shape = {}'
- .format(r.shape, g.shape, b.shape))
- RGB = np.dstack([r, g, b])
- R = np.zeros_like(RGB)
- R[:,:,0] = r
- G = np.zeros_like(RGB)
- G[:,:,1] = g
- B = np.zeros_like(RGB)
- B[:,:,2] = b
-
- im_rgb = self.RGB.imshow(RGB, **kwargs)
- im_r = self.R.imshow(R, **kwargs)
- im_g = self.G.imshow(G, **kwargs)
- im_b = self.B.imshow(B, **kwargs)
-
- return im_rgb, im_r, im_g, im_b
-
-
-class RGBAxes(RGBAxesBase):
- _defaultAxesClass = Axes
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/axes_size.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/axes_size.py
deleted file mode 100644
index 163a6245fe..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/axes_size.py
+++ /dev/null
@@ -1,323 +0,0 @@
-
-"""
-provides a classes of simple units that will be used with AxesDivider
-class (or others) to determine the size of each axes. The unit
-classes define `get_size` method that returns a tuple of two floats,
-meaning relative and absolute sizes, respectively.
-
-Note that this class is nothing more than a simple tuple of two
-floats. Take a look at the Divider class to see how these two
-values are used.
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import matplotlib.cbook as cbook
-from matplotlib.axes import Axes
-
-class _Base(object):
- "Base class"
-
- def __rmul__(self, other):
- float(other) # just to check if number if given
- return Fraction(other, self)
-
- def __add__(self, other):
- if isinstance(other, _Base):
- return Add(self, other)
- else:
- float(other)
- other = Fixed(other)
- return Add(self, other)
-
-
-class Add(_Base):
- def __init__(self, a, b):
- self._a = a
- self._b = b
-
- def get_size(self, renderer):
- a_rel_size, a_abs_size = self._a.get_size(renderer)
- b_rel_size, b_abs_size = self._b.get_size(renderer)
- return a_rel_size + b_rel_size, a_abs_size + b_abs_size
-
-class AddList(_Base):
- def __init__(self, add_list):
- self._list = add_list
-
- def get_size(self, renderer):
- sum_rel_size = sum([a.get_size(renderer)[0] for a in self._list])
- sum_abs_size = sum([a.get_size(renderer)[1] for a in self._list])
- return sum_rel_size, sum_abs_size
-
-
-class Fixed(_Base):
- "Simple fixed size with absolute part = *fixed_size* and relative part = 0"
- def __init__(self, fixed_size):
- self.fixed_size = fixed_size
-
- def get_size(self, renderer):
- rel_size = 0.
- abs_size = self.fixed_size
- return rel_size, abs_size
-
-
-class Scaled(_Base):
- "Simple scaled(?) size with absolute part = 0 and relative part = *scalable_size*"
- def __init__(self, scalable_size):
- self._scalable_size = scalable_size
-
- def get_size(self, renderer):
- rel_size = self._scalable_size
- abs_size = 0.
- return rel_size, abs_size
-
-Scalable=Scaled
-
-def _get_axes_aspect(ax):
- aspect = ax.get_aspect()
- # when aspec is "auto", consider it as 1.
- if aspect in ('normal', 'auto'):
- aspect = 1.
- elif aspect == "equal":
- aspect = 1
- else:
- aspect = float(aspect)
-
- return aspect
-
-class AxesX(_Base):
- """
- Scaled size whose relative part corresponds to the data width
- of the *axes* multiplied by the *aspect*.
- """
- def __init__(self, axes, aspect=1., ref_ax=None):
- self._axes = axes
- self._aspect = aspect
- if aspect == "axes" and ref_ax is None:
- raise ValueError("ref_ax must be set when aspect='axes'")
- self._ref_ax = ref_ax
-
- def get_size(self, renderer):
- l1, l2 = self._axes.get_xlim()
- if self._aspect == "axes":
- ref_aspect = _get_axes_aspect(self._ref_ax)
- aspect = ref_aspect/_get_axes_aspect(self._axes)
- else:
- aspect = self._aspect
-
- rel_size = abs(l2-l1)*aspect
- abs_size = 0.
- return rel_size, abs_size
-
-class AxesY(_Base):
- """
- Scaled size whose relative part corresponds to the data height
- of the *axes* multiplied by the *aspect*.
- """
- def __init__(self, axes, aspect=1., ref_ax=None):
- self._axes = axes
- self._aspect = aspect
- if aspect == "axes" and ref_ax is None:
- raise ValueError("ref_ax must be set when aspect='axes'")
- self._ref_ax = ref_ax
-
- def get_size(self, renderer):
- l1, l2 = self._axes.get_ylim()
-
- if self._aspect == "axes":
- ref_aspect = _get_axes_aspect(self._ref_ax)
- aspect = _get_axes_aspect(self._axes)
- else:
- aspect = self._aspect
-
- rel_size = abs(l2-l1)*aspect
- abs_size = 0.
- return rel_size, abs_size
-
-
-class MaxExtent(_Base):
- """
- Size whose absolute part is the largest width (or height) of
- the given *artist_list*.
- """
- def __init__(self, artist_list, w_or_h):
- self._artist_list = artist_list
-
- if w_or_h not in ["width", "height"]:
- raise ValueError()
-
- self._w_or_h = w_or_h
-
- def add_artist(self, a):
- self._artist_list.append(a)
-
- def get_size(self, renderer):
- rel_size = 0.
- w_list, h_list = [], []
- for a in self._artist_list:
- bb = a.get_window_extent(renderer)
- w_list.append(bb.width)
- h_list.append(bb.height)
- dpi = a.get_figure().get_dpi()
- if self._w_or_h == "width":
- abs_size = max(w_list)/dpi
- elif self._w_or_h == "height":
- abs_size = max(h_list)/dpi
-
- return rel_size, abs_size
-
-
-class MaxWidth(_Base):
- """
- Size whose absolute part is the largest width of
- the given *artist_list*.
- """
- def __init__(self, artist_list):
- self._artist_list = artist_list
-
- def add_artist(self, a):
- self._artist_list.append(a)
-
- def get_size(self, renderer):
- rel_size = 0.
- w_list = []
- for a in self._artist_list:
- bb = a.get_window_extent(renderer)
- w_list.append(bb.width)
- dpi = a.get_figure().get_dpi()
- abs_size = max(w_list)/dpi
-
- return rel_size, abs_size
-
-
-
-class MaxHeight(_Base):
- """
- Size whose absolute part is the largest height of
- the given *artist_list*.
- """
- def __init__(self, artist_list):
- self._artist_list = artist_list
-
- def add_artist(self, a):
- self._artist_list.append(a)
-
- def get_size(self, renderer):
- rel_size = 0.
- h_list = []
- for a in self._artist_list:
- bb = a.get_window_extent(renderer)
- h_list.append(bb.height)
- dpi = a.get_figure().get_dpi()
- abs_size = max(h_list)/dpi
-
- return rel_size, abs_size
-
-
-class Fraction(_Base):
- """
- An instance whose size is a *fraction* of the *ref_size*.
- ::
-
- >>> s = Fraction(0.3, AxesX(ax))
-
- """
- def __init__(self, fraction, ref_size):
- self._fraction_ref = ref_size
- self._fraction = fraction
-
- def get_size(self, renderer):
- if self._fraction_ref is None:
- return self._fraction, 0.
- else:
- r, a = self._fraction_ref.get_size(renderer)
- rel_size = r*self._fraction
- abs_size = a*self._fraction
- return rel_size, abs_size
-
-class Padded(_Base):
- """
- Return a instance where the absolute part of *size* is
- increase by the amount of *pad*.
- """
- def __init__(self, size, pad):
- self._size = size
- self._pad = pad
-
- def get_size(self, renderer):
- r, a = self._size.get_size(renderer)
- rel_size = r
- abs_size = a + self._pad
- return rel_size, abs_size
-
-def from_any(size, fraction_ref=None):
- """
- Creates Fixed unit when the first argument is a float, or a
- Fraction unit if that is a string that ends with %. The second
- argument is only meaningful when Fraction unit is created.::
-
- >>> a = Size.from_any(1.2) # => Size.Fixed(1.2)
- >>> Size.from_any("50%", a) # => Size.Fraction(0.5, a)
-
- """
- if cbook.is_numlike(size):
- return Fixed(size)
- elif isinstance(size, six.string_types):
- if size[-1] == "%":
- return Fraction(float(size[:-1]) / 100, fraction_ref)
-
- raise ValueError("Unknown format")
-
-
-class SizeFromFunc(_Base):
- def __init__(self, func):
- self._func = func
-
- def get_size(self, renderer):
- rel_size = 0.
-
- bb = self._func(renderer)
- dpi = renderer.points_to_pixels(72.)
- abs_size = bb/dpi
-
- return rel_size, abs_size
-
-class GetExtentHelper(object):
- def _get_left(tight_bbox, axes_bbox):
- return axes_bbox.xmin - tight_bbox.xmin
-
- def _get_right(tight_bbox, axes_bbox):
- return tight_bbox.xmax - axes_bbox.xmax
-
- def _get_bottom(tight_bbox, axes_bbox):
- return axes_bbox.ymin - tight_bbox.ymin
-
- def _get_top(tight_bbox, axes_bbox):
- return tight_bbox.ymax - axes_bbox.ymax
-
- _get_func_map = dict(left=_get_left,
- right=_get_right,
- bottom=_get_bottom,
- top=_get_top)
-
- del _get_left, _get_right, _get_bottom, _get_top
-
- def __init__(self, ax, direction):
- if isinstance(ax, Axes):
- self._ax_list = [ax]
- else:
- self._ax_list = ax
-
- try:
- self._get_func = self._get_func_map[direction]
- except KeyError:
- raise KeyError("direction must be one of left, right, bottom, top")
-
- def __call__(self, renderer):
- vl = [self._get_func(ax.get_tightbbox(renderer, False),
- ax.bbox) for ax in self._ax_list]
- return max(vl)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/colorbar.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/colorbar.py
deleted file mode 100644
index 34bdf3618a..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/colorbar.py
+++ /dev/null
@@ -1,836 +0,0 @@
-"""
-Colorbar toolkit with two classes and a function:
-
- :class:`ColorbarBase`
- the base class with full colorbar drawing functionality.
- It can be used as-is to make a colorbar for a given colormap;
- a mappable object (e.g., image) is not needed.
-
- :class:`Colorbar`
- the derived class for use with images or contour plots.
-
- :func:`make_axes`
- a function for resizing an axes and adding a second axes
- suitable for a colorbar
-
-The :meth:`~matplotlib.figure.Figure.colorbar` method uses :func:`make_axes`
-and :class:`Colorbar`; the :func:`~matplotlib.pyplot.colorbar` function
-is a thin wrapper over :meth:`~matplotlib.figure.Figure.colorbar`.
-"""
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import xrange, zip
-
-import numpy as np
-import matplotlib as mpl
-import matplotlib.colors as colors
-import matplotlib.cm as cm
-from matplotlib import docstring
-import matplotlib.ticker as ticker
-import matplotlib.cbook as cbook
-import matplotlib.collections as collections
-import matplotlib.contour as contour
-from matplotlib.path import Path
-from matplotlib.patches import PathPatch
-from matplotlib.transforms import Bbox
-
-
-make_axes_kw_doc = '''
-
- ============= ====================================================
- Property Description
- ============= ====================================================
- *orientation* vertical or horizontal
- *fraction* 0.15; fraction of original axes to use for colorbar
- *pad* 0.05 if vertical, 0.15 if horizontal; fraction
- of original axes between colorbar and new image axes
- *shrink* 1.0; fraction by which to shrink the colorbar
- *aspect* 20; ratio of long to short dimensions
- ============= ====================================================
-
-'''
-
-colormap_kw_doc = '''
-
- =========== ====================================================
- Property Description
- =========== ====================================================
- *extend* [ 'neither' | 'both' | 'min' | 'max' ]
- If not 'neither', make pointed end(s) for out-of-
- range values. These are set for a given colormap
- using the colormap set_under and set_over methods.
- *spacing* [ 'uniform' | 'proportional' ]
- Uniform spacing gives each discrete color the same
- space; proportional makes the space proportional to
- the data interval.
- *ticks* [ None | list of ticks | Locator object ]
- If None, ticks are determined automatically from the
- input.
- *format* [ None | format string | Formatter object ]
- If None, the
- :class:`~matplotlib.ticker.ScalarFormatter` is used.
- If a format string is given, e.g., '%.3f', that is
- used. An alternative
- :class:`~matplotlib.ticker.Formatter` object may be
- given instead.
- *drawedges* bool
- Whether to draw lines at color boundaries.
- =========== ====================================================
-
- The following will probably be useful only in the context of
- indexed colors (that is, when the mappable has norm=NoNorm()),
- or other unusual circumstances.
-
- ============ ===================================================
- Property Description
- ============ ===================================================
- *boundaries* None or a sequence
- *values* None or a sequence which must be of length 1 less
- than the sequence of *boundaries*. For each region
- delimited by adjacent entries in *boundaries*, the
- color mapped to the corresponding value in values
- will be used.
- ============ ===================================================
-
-'''
-
-colorbar_doc = '''
-
-Add a colorbar to a plot.
-
-Function signatures for the :mod:`~matplotlib.pyplot` interface; all
-but the first are also method signatures for the
-:meth:`~matplotlib.figure.Figure.colorbar` method::
-
- colorbar(**kwargs)
- colorbar(mappable, **kwargs)
- colorbar(mappable, cax=cax, **kwargs)
- colorbar(mappable, ax=ax, **kwargs)
-
-arguments:
-
- *mappable*
- the :class:`~matplotlib.image.Image`,
- :class:`~matplotlib.contour.ContourSet`, etc. to
- which the colorbar applies; this argument is mandatory for the
- :meth:`~matplotlib.figure.Figure.colorbar` method but optional for the
- :func:`~matplotlib.pyplot.colorbar` function, which sets the
- default to the current image.
-
-keyword arguments:
-
- *cax*
- None | axes object into which the colorbar will be drawn
- *ax*
- None | parent axes object from which space for a new
- colorbar axes will be stolen
-
-
-Additional keyword arguments are of two kinds:
-
- axes properties:
- %s
- colorbar properties:
- %s
-
-If *mappable* is a :class:`~matplotlib.contours.ContourSet`, its *extend*
-kwarg is included automatically.
-
-Note that the *shrink* kwarg provides a simple way to keep a vertical
-colorbar, for example, from being taller than the axes of the mappable
-to which the colorbar is attached; but it is a manual method requiring
-some trial and error. If the colorbar is too tall (or a horizontal
-colorbar is too wide) use a smaller value of *shrink*.
-
-For more precise control, you can manually specify the positions of
-the axes objects in which the mappable and the colorbar are drawn. In
-this case, do not use any of the axes properties kwargs.
-
-It is known that some vector graphics viewer (svg and pdf) renders white gaps
-between segments of the colorbar. This is due to bugs in the viewers not
-matplotlib. As a workaround the colorbar can be rendered with overlapping
-segments::
-
- cbar = colorbar()
- cbar.solids.set_edgecolor("face")
- draw()
-
-However this has negative consequences in other circumstances. Particularly with
-semi transparent images (alpha < 1) and colorbar extensions and is not enabled
-by default see (issue #1188).
-
-returns:
- :class:`~matplotlib.colorbar.Colorbar` instance; see also its base class,
- :class:`~matplotlib.colorbar.ColorbarBase`. Call the
- :meth:`~matplotlib.colorbar.ColorbarBase.set_label` method
- to label the colorbar.
-
-
-The transData of the *cax* is adjusted so that the limits in the
-longest axis actually corresponds to the limits in colorbar range. On
-the other hand, the shortest axis has a data limits of [1,2], whose
-unconventional value is to prevent underflow when log scale is used.
-''' % (make_axes_kw_doc, colormap_kw_doc)
-
-#docstring.interpd.update(colorbar_doc=colorbar_doc)
-
-
-class CbarAxesLocator(object):
- """
- CbarAxesLocator is a axes_locator for colorbar axes. It adjust the
- position of the axes to make a room for extended ends, i.e., the
- extended ends are located outside the axes area.
- """
-
- def __init__(self, locator=None, extend="neither", orientation="vertical"):
- """
- *locator* : the bbox returned from the locator is used as a
- initial axes location. If None, axes.bbox is used.
-
- *extend* : same as in ColorbarBase
- *orientation* : same as in ColorbarBase
-
- """
- self._locator = locator
- self.extesion_fraction = 0.05
- self.extend = extend
- self.orientation = orientation
-
- def get_original_position(self, axes, renderer):
- """
- get the original position of the axes.
- """
- if self._locator is None:
- bbox = axes.get_position(original=True)
- else:
- bbox = self._locator(axes, renderer)
- return bbox
-
- def get_end_vertices(self):
- """
- return a tuple of two vertices for the colorbar extended ends.
- The first vertices is for the minimum end, and the second is for
- the maximum end.
- """
- # Note that concatenating two vertices needs to make a
- # vertices for the frame.
- extesion_fraction = self.extesion_fraction
-
- corx = extesion_fraction*2.
- cory = 1./(1. - corx)
- x1, y1, w, h = 0, 0, 1, 1
- x2, y2 = x1 + w, y1 + h
- dw, dh = w*extesion_fraction, h*extesion_fraction*cory
-
- if self.extend in ["min", "both"]:
- bottom = [(x1, y1),
- (x1+w/2., y1-dh),
- (x2, y1)]
- else:
- bottom = [(x1, y1),
- (x2, y1)]
-
- if self.extend in ["max", "both"]:
- top = [(x2, y2),
- (x1+w/2., y2+dh),
- (x1, y2)]
- else:
- top = [(x2, y2),
- (x1, y2)]
-
- if self.orientation == "horizontal":
- bottom = [(y,x) for (x,y) in bottom]
- top = [(y,x) for (x,y) in top]
-
- return bottom, top
-
-
- def get_path_patch(self):
- """
- get the path for axes patch
- """
- end1, end2 = self.get_end_vertices()
-
- verts = [] + end1 + end2 + end1[:1]
-
- return Path(verts)
-
-
- def get_path_ends(self):
- """
- get the paths for extended ends
- """
-
- end1, end2 = self.get_end_vertices()
-
- return Path(end1), Path(end2)
-
-
- def __call__(self, axes, renderer):
- """
- Return the adjusted position of the axes
- """
- bbox0 = self.get_original_position(axes, renderer)
- bbox = bbox0
-
- x1, y1, w, h = bbox.bounds
- extesion_fraction = self.extesion_fraction
- dw, dh = w*extesion_fraction, h*extesion_fraction
-
- if self.extend in ["min", "both"]:
- if self.orientation == "horizontal":
- x1 = x1 + dw
- else:
- y1 = y1+dh
-
- if self.extend in ["max", "both"]:
- if self.orientation == "horizontal":
- w = w-2*dw
- else:
- h = h-2*dh
-
- return Bbox.from_bounds(x1, y1, w, h)
-
-
-
-class ColorbarBase(cm.ScalarMappable):
- '''
- Draw a colorbar in an existing axes.
-
- This is a base class for the :class:`Colorbar` class, which is the
- basis for the :func:`~matplotlib.pyplot.colorbar` method and pylab
- function.
-
- It is also useful by itself for showing a colormap. If the *cmap*
- kwarg is given but *boundaries* and *values* are left as None,
- then the colormap will be displayed on a 0-1 scale. To show the
- under- and over-value colors, specify the *norm* as::
-
- colors.Normalize(clip=False)
-
- To show the colors versus index instead of on the 0-1 scale,
- use::
-
- norm=colors.NoNorm.
-
- Useful attributes:
-
- :attr:`ax`
- the Axes instance in which the colorbar is drawn
-
- :attr:`lines`
- a LineCollection if lines were drawn, otherwise None
-
- :attr:`dividers`
- a LineCollection if *drawedges* is True, otherwise None
-
- Useful public methods are :meth:`set_label` and :meth:`add_lines`.
-
- '''
-
- def __init__(self, ax, cmap=None,
- norm=None,
- alpha=1.0,
- values=None,
- boundaries=None,
- orientation='vertical',
- extend='neither',
- spacing='uniform', # uniform or proportional
- ticks=None,
- format=None,
- drawedges=False,
- filled=True,
- ):
- self.ax = ax
-
- if cmap is None: cmap = cm.get_cmap()
- if norm is None: norm = colors.Normalize()
- self.alpha = alpha
- cm.ScalarMappable.__init__(self, cmap=cmap, norm=norm)
- self.values = values
- self.boundaries = boundaries
- self.extend = extend
- self.spacing = spacing
- self.orientation = orientation
- self.drawedges = drawedges
- self.filled = filled
-
- # artists
- self.solids = None
- self.lines = None
- self.dividers = None
- self.extension_patch1 = None
- self.extension_patch2 = None
-
- if orientation == "vertical":
- self.cbar_axis = self.ax.yaxis
- else:
- self.cbar_axis = self.ax.xaxis
-
-
- if format is None:
- if isinstance(self.norm, colors.LogNorm):
- # change both axis for proper aspect
- self.ax.set_xscale("log")
- self.ax.set_yscale("log")
- self.cbar_axis.set_minor_locator(ticker.NullLocator())
- formatter = ticker.LogFormatter()
- else:
- formatter = None
- elif isinstance(format, six.string_types):
- formatter = ticker.FormatStrFormatter(format)
- else:
- formatter = format # Assume it is a Formatter
-
- if formatter is None:
- formatter = self.cbar_axis.get_major_formatter()
- else:
- self.cbar_axis.set_major_formatter(formatter)
-
- if cbook.iterable(ticks):
- self.cbar_axis.set_ticks(ticks)
- elif ticks is not None:
- self.cbar_axis.set_major_locator(ticks)
- else:
- self._select_locator(formatter)
-
-
- self._config_axes()
-
- self.update_artists()
-
- self.set_label_text('')
-
-
- def _get_colorbar_limits(self):
- """
- initial limits for colorbar range. The returned min, max values
- will be used to create colorbar solid(?) and etc.
- """
- if self.boundaries is not None:
- C = self.boundaries
- if self.extend in ["min", "both"]:
- C = C[1:]
-
- if self.extend in ["max", "both"]:
- C = C[:-1]
- return min(C), max(C)
- else:
- return self.get_clim()
-
-
- def _config_axes(self):
- '''
- Adjust the properties of the axes to be adequate for colorbar display.
- '''
- ax = self.ax
-
- axes_locator = CbarAxesLocator(ax.get_axes_locator(),
- extend=self.extend,
- orientation=self.orientation)
- ax.set_axes_locator(axes_locator)
-
- # override the get_data_ratio for the aspect works.
- def _f():
- return 1.
- ax.get_data_ratio = _f
- ax.get_data_ratio_log = _f
-
- ax.set_frame_on(True)
- ax.set_navigate(False)
-
- self.ax.set_autoscalex_on(False)
- self.ax.set_autoscaley_on(False)
-
- if self.orientation == 'horizontal':
- ax.xaxis.set_label_position('bottom')
- ax.set_yticks([])
- else:
- ax.set_xticks([])
- ax.yaxis.set_label_position('right')
- ax.yaxis.set_ticks_position('right')
-
-
-
- def update_artists(self):
- """
- Update the colorbar associated artists, *filled* and
- *ends*. Note that *lines* are not updated. This needs to be
- called whenever clim of associated image changes.
- """
- self._process_values()
- self._add_ends()
-
- X, Y = self._mesh()
- if self.filled:
- C = self._values[:,np.newaxis]
- self._add_solids(X, Y, C)
-
- ax = self.ax
- vmin, vmax = self._get_colorbar_limits()
- if self.orientation == 'horizontal':
- ax.set_ylim(1, 2)
- ax.set_xlim(vmin, vmax)
- else:
- ax.set_xlim(1, 2)
- ax.set_ylim(vmin, vmax)
-
-
- def _add_ends(self):
- """
- Create patches from extended ends and add them to the axes.
- """
-
- del self.extension_patch1
- del self.extension_patch2
-
- path1, path2 = self.ax.get_axes_locator().get_path_ends()
- fc=mpl.rcParams['axes.facecolor']
- ec=mpl.rcParams['axes.edgecolor']
- linewidths=0.5*mpl.rcParams['axes.linewidth']
- self.extension_patch1 = PathPatch(path1,
- fc=fc, ec=ec, lw=linewidths,
- zorder=2.,
- transform=self.ax.transAxes,
- clip_on=False)
- self.extension_patch2 = PathPatch(path2,
- fc=fc, ec=ec, lw=linewidths,
- zorder=2.,
- transform=self.ax.transAxes,
- clip_on=False)
- self.ax.add_artist(self.extension_patch1)
- self.ax.add_artist(self.extension_patch2)
-
-
-
- def _set_label_text(self):
- """
- set label.
- """
- self.cbar_axis.set_label_text(self._label, **self._labelkw)
-
- def set_label_text(self, label, **kw):
- '''
- Label the long axis of the colorbar
- '''
- self._label = label
- self._labelkw = kw
- self._set_label_text()
-
-
- def _edges(self, X, Y):
- '''
- Return the separator line segments; helper for _add_solids.
- '''
- N = X.shape[0]
- # Using the non-array form of these line segments is much
- # simpler than making them into arrays.
- if self.orientation == 'vertical':
- return [list(zip(X[i], Y[i])) for i in xrange(1, N-1)]
- else:
- return [list(zip(Y[i], X[i])) for i in xrange(1, N-1)]
-
- def _add_solids(self, X, Y, C):
- '''
- Draw the colors using :meth:`~matplotlib.axes.Axes.pcolormesh`;
- optionally add separators.
- '''
- ## Change to pcolorfast after fixing bugs in some backends...
-
- if self.extend in ["min", "both"]:
- cc = self.to_rgba([C[0][0]])
- self.extension_patch1.set_fc(cc[0])
- X, Y, C = X[1:], Y[1:], C[1:]
-
- if self.extend in ["max", "both"]:
- cc = self.to_rgba([C[-1][0]])
- self.extension_patch2.set_fc(cc[0])
- X, Y, C = X[:-1], Y[:-1], C[:-1]
-
- if self.orientation == 'vertical':
- args = (X, Y, C)
- else:
- args = (np.transpose(Y), np.transpose(X), np.transpose(C))
- kw = {'cmap':self.cmap, 'norm':self.norm,
- 'shading':'flat', 'alpha':self.alpha,
- }
-
- del self.solids
- del self.dividers
-
- col = self.ax.pcolormesh(*args, **kw)
-
- self.solids = col
- if self.drawedges:
- self.dividers = collections.LineCollection(self._edges(X,Y),
- colors=(mpl.rcParams['axes.edgecolor'],),
- linewidths=(0.5*mpl.rcParams['axes.linewidth'],),
- )
- self.ax.add_collection(self.dividers)
- else:
- self.dividers = None
-
- def add_lines(self, levels, colors, linewidths):
- '''
- Draw lines on the colorbar. It deletes preexisting lines.
- '''
- del self.lines
-
- N = len(levels)
- x = np.array([1.0, 2.0])
- X, Y = np.meshgrid(x,levels)
- if self.orientation == 'vertical':
- xy = [list(zip(X[i], Y[i])) for i in xrange(N)]
- else:
- xy = [list(zip(Y[i], X[i])) for i in xrange(N)]
- col = collections.LineCollection(xy, linewidths=linewidths,
- )
- self.lines = col
- col.set_color(colors)
- self.ax.add_collection(col)
-
-
- def _select_locator(self, formatter):
- '''
- select a suitable locator
- '''
- if self.boundaries is None:
- if isinstance(self.norm, colors.NoNorm):
- nv = len(self._values)
- base = 1 + int(nv/10)
- locator = ticker.IndexLocator(base=base, offset=0)
- elif isinstance(self.norm, colors.BoundaryNorm):
- b = self.norm.boundaries
- locator = ticker.FixedLocator(b, nbins=10)
- elif isinstance(self.norm, colors.LogNorm):
- locator = ticker.LogLocator()
- else:
- locator = ticker.MaxNLocator(nbins=5)
- else:
- b = self._boundaries[self._inside]
- locator = ticker.FixedLocator(b) #, nbins=10)
-
- self.cbar_axis.set_major_locator(locator)
-
-
- def _process_values(self, b=None):
- '''
- Set the :attr:`_boundaries` and :attr:`_values` attributes
- based on the input boundaries and values. Input boundaries
- can be *self.boundaries* or the argument *b*.
- '''
- if b is None:
- b = self.boundaries
- if b is not None:
- self._boundaries = np.asarray(b, dtype=float)
- if self.values is None:
- self._values = 0.5*(self._boundaries[:-1]
- + self._boundaries[1:])
- if isinstance(self.norm, colors.NoNorm):
- self._values = (self._values + 0.00001).astype(np.int16)
- return
- self._values = np.array(self.values)
- return
- if self.values is not None:
- self._values = np.array(self.values)
- if self.boundaries is None:
- b = np.zeros(len(self.values)+1, 'd')
- b[1:-1] = 0.5*(self._values[:-1] - self._values[1:])
- b[0] = 2.0*b[1] - b[2]
- b[-1] = 2.0*b[-2] - b[-3]
- self._boundaries = b
- return
- self._boundaries = np.array(self.boundaries)
- return
- # Neither boundaries nor values are specified;
- # make reasonable ones based on cmap and norm.
- if isinstance(self.norm, colors.NoNorm):
- b = self._uniform_y(self.cmap.N+1) * self.cmap.N - 0.5
- v = np.zeros((len(b)-1,), dtype=np.int16)
- v = np.arange(self.cmap.N, dtype=np.int16)
- self._boundaries = b
- self._values = v
- return
- elif isinstance(self.norm, colors.BoundaryNorm):
- b = np.array(self.norm.boundaries)
- v = np.zeros((len(b)-1,), dtype=float)
- bi = self.norm.boundaries
- v = 0.5*(bi[:-1] + bi[1:])
- self._boundaries = b
- self._values = v
- return
- else:
- b = self._uniform_y(self.cmap.N+1)
-
- self._process_values(b)
-
-
- def _uniform_y(self, N):
- '''
- Return colorbar data coordinates for *N* uniformly
- spaced boundaries.
- '''
- vmin, vmax = self._get_colorbar_limits()
- if isinstance(self.norm, colors.LogNorm):
- y = np.logspace(np.log10(vmin), np.log10(vmax), N)
- else:
- y = np.linspace(vmin, vmax, N)
- return y
-
- def _mesh(self):
- '''
- Return X,Y, the coordinate arrays for the colorbar pcolormesh.
- These are suitable for a vertical colorbar; swapping and
- transposition for a horizontal colorbar are done outside
- this function.
- '''
- x = np.array([1.0, 2.0])
- if self.spacing == 'uniform':
- y = self._uniform_y(len(self._boundaries))
- else:
- y = self._boundaries
- self._y = y
-
- X, Y = np.meshgrid(x,y)
- return X, Y
-
-
- def set_alpha(self, alpha):
- """
- set alpha value.
- """
- self.alpha = alpha
-
-
-class Colorbar(ColorbarBase):
- def __init__(self, ax, mappable, **kw):
- mappable.autoscale_None() # Ensure mappable.norm.vmin, vmax
- # are set when colorbar is called,
- # even if mappable.draw has not yet
- # been called. This will not change
- # vmin, vmax if they are already set.
- self.mappable = mappable
- kw['cmap'] = mappable.cmap
- kw['norm'] = mappable.norm
- kw['alpha'] = mappable.get_alpha()
- if isinstance(mappable, contour.ContourSet):
- CS = mappable
- kw['boundaries'] = CS._levels
- kw['values'] = CS.cvalues
- kw['extend'] = CS.extend
- #kw['ticks'] = CS._levels
- kw.setdefault('ticks', ticker.FixedLocator(CS.levels, nbins=10))
- kw['filled'] = CS.filled
- ColorbarBase.__init__(self, ax, **kw)
- if not CS.filled:
- self.add_lines(CS)
- else:
- ColorbarBase.__init__(self, ax, **kw)
-
-
- def add_lines(self, CS):
- '''
- Add the lines from a non-filled
- :class:`~matplotlib.contour.ContourSet` to the colorbar.
- '''
- if not isinstance(CS, contour.ContourSet) or CS.filled:
- raise ValueError('add_lines is only for a ContourSet of lines')
- tcolors = [c[0] for c in CS.tcolors]
- tlinewidths = [t[0] for t in CS.tlinewidths]
- # The following was an attempt to get the colorbar lines
- # to follow subsequent changes in the contour lines,
- # but more work is needed: specifically, a careful
- # look at event sequences, and at how
- # to make one object track another automatically.
- #tcolors = [col.get_colors()[0] for col in CS.collections]
- #tlinewidths = [col.get_linewidth()[0] for lw in CS.collections]
- ColorbarBase.add_lines(self, CS.levels, tcolors, tlinewidths)
-
- def update_bruteforce(self, mappable):
- """
- Update the colorbar artists to reflect the change of the
- associated mappable.
- """
- self.update_artists()
-
- if isinstance(mappable, contour.ContourSet):
- if not mappable.filled:
- self.add_lines(mappable)
-
-@docstring.Substitution(make_axes_kw_doc)
-def make_axes(parent, **kw):
- '''
- Resize and reposition a parent axes, and return a child
- axes suitable for a colorbar
-
- ::
-
- cax, kw = make_axes(parent, **kw)
-
- Keyword arguments may include the following (with defaults):
-
- *orientation*
- 'vertical' or 'horizontal'
-
- %s
-
- All but the first of these are stripped from the input kw set.
-
- Returns (cax, kw), the child axes and the reduced kw dictionary.
- '''
- orientation = kw.setdefault('orientation', 'vertical')
- fraction = kw.pop('fraction', 0.15)
- shrink = kw.pop('shrink', 1.0)
- aspect = kw.pop('aspect', 20)
- #pb = transforms.PBox(parent.get_position())
- pb = parent.get_position(original=True).frozen()
- if orientation == 'vertical':
- pad = kw.pop('pad', 0.05)
- x1 = 1.0-fraction
- pb1, pbx, pbcb = pb.splitx(x1-pad, x1)
- pbcb = pbcb.shrunk(1.0, shrink).anchored('C', pbcb)
- anchor = (0.0, 0.5)
- panchor = (1.0, 0.5)
- else:
- pad = kw.pop('pad', 0.15)
- pbcb, pbx, pb1 = pb.splity(fraction, fraction+pad)
- pbcb = pbcb.shrunk(shrink, 1.0).anchored('C', pbcb)
- aspect = 1.0/aspect
- anchor = (0.5, 1.0)
- panchor = (0.5, 0.0)
- parent.set_position(pb1)
- parent.set_anchor(panchor)
- fig = parent.get_figure()
- cax = fig.add_axes(pbcb)
- cax.set_aspect(aspect, anchor=anchor, adjustable='box')
- return cax, kw
-
-@docstring.Substitution(colorbar_doc)
-def colorbar(mappable, cax=None, ax=None, **kw):
- """
- Create a colorbar for a ScalarMappable instance.
-
- Documentation for the pylab thin wrapper:
-
- %s
- """
- import matplotlib.pyplot as plt
- if ax is None:
- ax = plt.gca()
- if cax is None:
- cax, kw = make_axes(ax, **kw)
- cax._hold = True
- cb = Colorbar(cax, mappable, **kw)
-
- def on_changed(m):
- cb.set_cmap(m.get_cmap())
- cb.set_clim(m.get_clim())
- cb.update_bruteforce(m)
-
- cbid = mappable.callbacksSM.connect('changed', on_changed)
- mappable.colorbar = cb
- ax.figure.sca(ax)
- return cb
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/inset_locator.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/inset_locator.py
deleted file mode 100644
index 9aeedcb088..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/inset_locator.py
+++ /dev/null
@@ -1,659 +0,0 @@
-"""
-A collection of functions and objects for creating or placing inset axes.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import warnings
-from matplotlib import docstring
-import six
-from matplotlib.offsetbox import AnchoredOffsetbox
-from matplotlib.patches import Patch, Rectangle
-from matplotlib.path import Path
-from matplotlib.transforms import Bbox, BboxTransformTo
-from matplotlib.transforms import IdentityTransform, TransformedBbox
-
-from . import axes_size as Size
-from .parasite_axes import HostAxes
-
-
-class InsetPosition(object):
- @docstring.dedent_interpd
- def __init__(self, parent, lbwh):
- """
- An object for positioning an inset axes.
-
- This is created by specifying the normalized coordinates in the axes,
- instead of the figure.
-
- Parameters
- ----------
- parent : `matplotlib.axes.Axes`
- Axes to use for normalizing coordinates.
-
- lbwh : iterable of four floats
- The left edge, bottom edge, width, and height of the inset axes, in
- units of the normalized coordinate of the *parent* axes.
-
- See Also
- --------
- :meth:`matplotlib.axes.Axes.set_axes_locator`
-
- Examples
- --------
- The following bounds the inset axes to a box with 20%% of the parent
- axes's height and 40%% of the width. The size of the axes specified
- ([0, 0, 1, 1]) ensures that the axes completely fills the bounding box:
-
- >>> parent_axes = plt.gca()
- >>> ax_ins = plt.axes([0, 0, 1, 1])
- >>> ip = InsetPosition(ax, [0.5, 0.1, 0.4, 0.2])
- >>> ax_ins.set_axes_locator(ip)
- """
- self.parent = parent
- self.lbwh = lbwh
-
- def __call__(self, ax, renderer):
- bbox_parent = self.parent.get_position(original=False)
- trans = BboxTransformTo(bbox_parent)
- bbox_inset = Bbox.from_bounds(*self.lbwh)
- bb = TransformedBbox(bbox_inset, trans)
- return bb
-
-
-class AnchoredLocatorBase(AnchoredOffsetbox):
- def __init__(self, bbox_to_anchor, offsetbox, loc,
- borderpad=0.5, bbox_transform=None):
- super(AnchoredLocatorBase, self).__init__(
- loc, pad=0., child=None, borderpad=borderpad,
- bbox_to_anchor=bbox_to_anchor, bbox_transform=bbox_transform
- )
-
- def draw(self, renderer):
- raise RuntimeError("No draw method should be called")
-
- def __call__(self, ax, renderer):
- self.axes = ax
-
- fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
- self._update_offset_func(renderer, fontsize)
-
- width, height, xdescent, ydescent = self.get_extent(renderer)
-
- px, py = self.get_offset(width, height, 0, 0, renderer)
- bbox_canvas = Bbox.from_bounds(px, py, width, height)
- tr = ax.figure.transFigure.inverted()
- bb = TransformedBbox(bbox_canvas, tr)
-
- return bb
-
-
-class AnchoredSizeLocator(AnchoredLocatorBase):
- def __init__(self, bbox_to_anchor, x_size, y_size, loc,
- borderpad=0.5, bbox_transform=None):
-
- super(AnchoredSizeLocator, self).__init__(
- bbox_to_anchor, None, loc,
- borderpad=borderpad, bbox_transform=bbox_transform
- )
-
- self.x_size = Size.from_any(x_size)
- self.y_size = Size.from_any(y_size)
-
- def get_extent(self, renderer):
- x, y, w, h = self.get_bbox_to_anchor().bounds
-
- dpi = renderer.points_to_pixels(72.)
-
- r, a = self.x_size.get_size(renderer)
- width = w * r + a * dpi
-
- r, a = self.y_size.get_size(renderer)
- height = h * r + a * dpi
- xd, yd = 0, 0
-
- fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
- pad = self.pad * fontsize
-
- return width + 2 * pad, height + 2 * pad, xd + pad, yd + pad
-
-
-class AnchoredZoomLocator(AnchoredLocatorBase):
- def __init__(self, parent_axes, zoom, loc,
- borderpad=0.5,
- bbox_to_anchor=None,
- bbox_transform=None):
- self.parent_axes = parent_axes
- self.zoom = zoom
-
- if bbox_to_anchor is None:
- bbox_to_anchor = parent_axes.bbox
-
- super(AnchoredZoomLocator, self).__init__(
- bbox_to_anchor, None, loc, borderpad=borderpad,
- bbox_transform=bbox_transform)
-
- def get_extent(self, renderer):
- bb = TransformedBbox(self.axes.viewLim,
- self.parent_axes.transData)
-
- x, y, w, h = bb.bounds
- fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
- pad = self.pad * fontsize
-
- return abs(w * self.zoom) + 2 * pad, abs(h * self.zoom) + 2 * pad, pad, pad
-
-
-class BboxPatch(Patch):
- @docstring.dedent_interpd
- def __init__(self, bbox, **kwargs):
- """
- Patch showing the shape bounded by a Bbox.
-
- Parameters
- ----------
- bbox : `matplotlib.transforms.Bbox`
- Bbox to use for the extents of this patch.
-
- **kwargs
- Patch properties. Valid arguments include:
- %(Patch)s
- """
- if "transform" in kwargs:
- raise ValueError("transform should not be set")
-
- kwargs["transform"] = IdentityTransform()
- Patch.__init__(self, **kwargs)
- self.bbox = bbox
-
- def get_path(self):
- x0, y0, x1, y1 = self.bbox.extents
-
- verts = [(x0, y0),
- (x1, y0),
- (x1, y1),
- (x0, y1),
- (x0, y0),
- (0, 0)]
-
- codes = [Path.MOVETO,
- Path.LINETO,
- Path.LINETO,
- Path.LINETO,
- Path.LINETO,
- Path.CLOSEPOLY]
-
- return Path(verts, codes)
-
- get_path.__doc__ = Patch.get_path.__doc__
-
-
-class BboxConnector(Patch):
- @staticmethod
- def get_bbox_edge_pos(bbox, loc):
- """
- Helper function to obtain the location of a corner of a bbox
-
- Parameters
- ----------
- bbox : `matplotlib.transforms.Bbox`
-
- loc : {1, 2, 3, 4}
- Corner of *bbox*. Valid values are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4
-
- Returns
- -------
- x, y : float
- Coordinates of the corner specified by *loc*.
- """
- x0, y0, x1, y1 = bbox.extents
- if loc == 1:
- return x1, y1
- elif loc == 2:
- return x0, y1
- elif loc == 3:
- return x0, y0
- elif loc == 4:
- return x1, y0
-
- @staticmethod
- def connect_bbox(bbox1, bbox2, loc1, loc2=None):
- """
- Helper function to obtain a Path from one bbox to another.
-
- Parameters
- ----------
- bbox1, bbox2 : `matplotlib.transforms.Bbox`
- Bounding boxes to connect.
-
- loc1 : {1, 2, 3, 4}
- Corner of *bbox1* to use. Valid values are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4
-
- loc2 : {1, 2, 3, 4}, optional
- Corner of *bbox2* to use. If None, defaults to *loc1*.
- Valid values are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4
-
- Returns
- -------
- path : `matplotlib.path.Path`
- A line segment from the *loc1* corner of *bbox1* to the *loc2*
- corner of *bbox2*.
- """
- if isinstance(bbox1, Rectangle):
- transform = bbox1.get_transfrom()
- bbox1 = Bbox.from_bounds(0, 0, 1, 1)
- bbox1 = TransformedBbox(bbox1, transform)
-
- if isinstance(bbox2, Rectangle):
- transform = bbox2.get_transform()
- bbox2 = Bbox.from_bounds(0, 0, 1, 1)
- bbox2 = TransformedBbox(bbox2, transform)
-
- if loc2 is None:
- loc2 = loc1
-
- x1, y1 = BboxConnector.get_bbox_edge_pos(bbox1, loc1)
- x2, y2 = BboxConnector.get_bbox_edge_pos(bbox2, loc2)
-
- verts = [[x1, y1], [x2, y2]]
- codes = [Path.MOVETO, Path.LINETO]
-
- return Path(verts, codes)
-
- @docstring.dedent_interpd
- def __init__(self, bbox1, bbox2, loc1, loc2=None, **kwargs):
- """
- Connect two bboxes with a straight line.
-
- Parameters
- ----------
- bbox1, bbox2 : `matplotlib.transforms.Bbox`
- Bounding boxes to connect.
-
- loc1 : {1, 2, 3, 4}
- Corner of *bbox1* to draw the line. Valid values are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4
-
- loc2 : {1, 2, 3, 4}, optional
- Corner of *bbox2* to draw the line. If None, defaults to *loc1*.
- Valid values are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4
-
- **kwargs
- Patch properties for the line drawn. Valid arguments include:
- %(Patch)s
- """
- if "transform" in kwargs:
- raise ValueError("transform should not be set")
-
- kwargs["transform"] = IdentityTransform()
- Patch.__init__(self, fill=False, **kwargs)
- self.bbox1 = bbox1
- self.bbox2 = bbox2
- self.loc1 = loc1
- self.loc2 = loc2
-
- def get_path(self):
- return self.connect_bbox(self.bbox1, self.bbox2,
- self.loc1, self.loc2)
-
- get_path.__doc__ = Patch.get_path.__doc__
-
-
-class BboxConnectorPatch(BboxConnector):
- @docstring.dedent_interpd
- def __init__(self, bbox1, bbox2, loc1a, loc2a, loc1b, loc2b, **kwargs):
- """
- Connect two bboxes with a quadrilateral.
-
- The quadrilateral is specified by two lines that start and end at corners
- of the bboxes. The four sides of the quadrilateral are defined by the two
- lines given, the line between the two corners specified in *bbox1* and the
- line between the two corners specified in *bbox2*.
-
- Parameters
- ----------
- bbox1, bbox2 : `matplotlib.transforms.Bbox`
- Bounding boxes to connect.
-
- loc1a, loc2a : {1, 2, 3, 4}
- Corners of *bbox1* and *bbox2* to draw the first line.
- Valid values are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4
-
- loc1b, loc2b : {1, 2, 3, 4}
- Corners of *bbox1* and *bbox2* to draw the second line.
- Valid values are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4
-
- **kwargs
- Patch properties for the line drawn:
- %(Patch)s
- """
- if "transform" in kwargs:
- raise ValueError("transform should not be set")
- BboxConnector.__init__(self, bbox1, bbox2, loc1a, loc2a, **kwargs)
- self.loc1b = loc1b
- self.loc2b = loc2b
-
- def get_path(self):
- path1 = self.connect_bbox(self.bbox1, self.bbox2, self.loc1, self.loc2)
- path2 = self.connect_bbox(self.bbox2, self.bbox1,
- self.loc2b, self.loc1b)
- path_merged = (list(path1.vertices) +
- list(path2.vertices) +
- [path1.vertices[0]])
- return Path(path_merged)
-
- get_path.__doc__ = BboxConnector.get_path.__doc__
-
-
-def _add_inset_axes(parent_axes, inset_axes):
- """Helper function to add an inset axes and disable navigation in it"""
- parent_axes.figure.add_axes(inset_axes)
- inset_axes.set_navigate(False)
-
-
-@docstring.dedent_interpd
-def inset_axes(parent_axes, width, height, loc=1,
- bbox_to_anchor=None, bbox_transform=None,
- axes_class=None,
- axes_kwargs=None,
- borderpad=0.5):
- """
- Create an inset axes with a given width and height.
-
- Both sizes used can be specified either in inches or percentage.
- For example,::
-
- inset_axes(parent_axes, width='40%%', height='30%%', loc=3)
-
- creates in inset axes in the lower left corner of *parent_axes* which spans
- over 30%% in height and 40%% in width of the *parent_axes*. Since the usage
- of `.inset_axes` may become slightly tricky when exceeding such standard
- cases, it is recommended to read
- :ref:`the examples <sphx_glr_gallery_axes_grid1_inset_locator_demo.py>`.
-
- Parameters
- ----------
- parent_axes : `matplotlib.axes.Axes`
- Axes to place the inset axes.
-
- width, height : float or str
- Size of the inset axes to create. If a float is provided, it is
- the size in inches, e.g. *width=1.3*. If a string is provided, it is
- the size in relative units, e.g. *width='40%%'*. By default, i.e. if
- neither *bbox_to_anchor* nor *bbox_transform* are specified, those
- are relative to the parent_axes. Otherwise they are to be understood
- relative to the bounding box provided via *bbox_to_anchor*.
-
- loc : int or string, optional, default to 1
- Location to place the inset axes. The valid locations are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4,
- 'right' : 5,
- 'center left' : 6,
- 'center right' : 7,
- 'lower center' : 8,
- 'upper center' : 9,
- 'center' : 10
-
- bbox_to_anchor : tuple or `matplotlib.transforms.BboxBase`, optional
- Bbox that the inset axes will be anchored to. If None,
- *parent_axes.bbox* is used. If a tuple, can be either
- [left, bottom, width, height], or [left, bottom].
- If the kwargs *width* and/or *height* are specified in relative units,
- the 2-tuple [left, bottom] cannot be used. Note that
- the units of the bounding box are determined through the transform
- in use. When using *bbox_to_anchor* it almost always makes sense to
- also specify a *bbox_transform*. This might often be the axes transform
- *parent_axes.transAxes*.
-
- bbox_transform : `matplotlib.transforms.Transform`, optional
- Transformation for the bbox that contains the inset axes.
- If None, a `.transforms.IdentityTransform` is used (i.e. pixel
- coordinates). This is useful when not providing any argument to
- *bbox_to_anchor*. When using *bbox_to_anchor* it almost always makes
- sense to also specify a *bbox_transform*. This might often be the
- axes transform *parent_axes.transAxes*. Inversely, when specifying
- the axes- or figure-transform here, be aware that not specifying
- *bbox_to_anchor* will use *parent_axes.bbox*, the units of which are
- in display (pixel) coordinates.
-
- axes_class : `matplotlib.axes.Axes` type, optional
- If specified, the inset axes created will be created with this class's
- constructor.
-
- axes_kwargs : dict, optional
- Keyworded arguments to pass to the constructor of the inset axes.
- Valid arguments include:
- %(Axes)s
-
- borderpad : float, optional
- Padding between inset axes and the bbox_to_anchor. Defaults to 0.5.
- The units are axes font size, i.e. for a default font size of 10 points
- *borderpad = 0.5* is equivalent to a padding of 5 points.
-
- Returns
- -------
- inset_axes : `axes_class`
- Inset axes object created.
- """
-
- if axes_class is None:
- axes_class = HostAxes
-
- if axes_kwargs is None:
- inset_axes = axes_class(parent_axes.figure, parent_axes.get_position())
- else:
- inset_axes = axes_class(parent_axes.figure, parent_axes.get_position(),
- **axes_kwargs)
-
- if bbox_transform in [parent_axes.transAxes,
- parent_axes.figure.transFigure]:
- if bbox_to_anchor is None:
- warnings.warn("Using the axes or figure transform requires a "
- "bounding box in the respective coordinates. "
- "Using bbox_to_anchor=(0,0,1,1) now.")
- bbox_to_anchor = (0, 0, 1, 1)
-
- if bbox_to_anchor is None:
- bbox_to_anchor = parent_axes.bbox
-
- if isinstance(bbox_to_anchor, tuple) and \
- (isinstance(width, str) or isinstance(height, str)):
- if len(bbox_to_anchor) != 4:
- raise ValueError("Using relative units for width or height "
- "requires to provide a 4-tuple or a "
- "`BBox` instance to `bbox_to_anchor.")
-
- axes_locator = AnchoredSizeLocator(bbox_to_anchor,
- width, height,
- loc=loc,
- bbox_transform=bbox_transform,
- borderpad=borderpad)
-
- inset_axes.set_axes_locator(axes_locator)
-
- _add_inset_axes(parent_axes, inset_axes)
-
- return inset_axes
-
-
-@docstring.dedent_interpd
-def zoomed_inset_axes(parent_axes, zoom, loc=1,
- bbox_to_anchor=None, bbox_transform=None,
- axes_class=None,
- axes_kwargs=None,
- borderpad=0.5):
- """
- Create an anchored inset axes by scaling a parent axes. For usage, also see
- :ref:`the examples <sphx_glr_gallery_axes_grid1_inset_locator_demo2.py>`.
-
- Parameters
- ----------
- parent_axes : `matplotlib.axes.Axes`
- Axes to place the inset axes.
-
- zoom : float
- Scaling factor of the data axes. *zoom* > 1 will enlargen the
- coordinates (i.e., "zoomed in"), while *zoom* < 1 will shrink the
- coordinates (i.e., "zoomed out").
-
- loc : int or string, optional, default to 1
- Location to place the inset axes. The valid locations are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4,
- 'right' : 5,
- 'center left' : 6,
- 'center right' : 7,
- 'lower center' : 8,
- 'upper center' : 9,
- 'center' : 10
-
- bbox_to_anchor : tuple or `matplotlib.transforms.BboxBase`, optional
- Bbox that the inset axes will be anchored to. If None,
- *parent_axes.bbox* is used. If a tuple, can be either
- [left, bottom, width, height], or [left, bottom].
- If the kwargs *width* and/or *height* are specified in relative units,
- the 2-tuple [left, bottom] cannot be used. Note that
- the units of the bounding box are determined through the transform
- in use. When using *bbox_to_anchor* it almost always makes sense to
- also specify a *bbox_transform*. This might often be the axes transform
- *parent_axes.transAxes*.
-
- bbox_transform : `matplotlib.transforms.Transform`, optional
- Transformation for the bbox that contains the inset axes.
- If None, a `.transforms.IdentityTransform` is used (i.e. pixel
- coordinates). This is useful when not providing any argument to
- *bbox_to_anchor*. When using *bbox_to_anchor* it almost always makes
- sense to also specify a *bbox_transform*. This might often be the
- axes transform *parent_axes.transAxes*. Inversely, when specifying
- the axes- or figure-transform here, be aware that not specifying
- *bbox_to_anchor* will use *parent_axes.bbox*, the units of which are
- in display (pixel) coordinates.
-
- axes_class : `matplotlib.axes.Axes` type, optional
- If specified, the inset axes created will be created with this class's
- constructor.
-
- axes_kwargs : dict, optional
- Keyworded arguments to pass to the constructor of the inset axes.
- Valid arguments include:
- %(Axes)s
-
- borderpad : float, optional
- Padding between inset axes and the bbox_to_anchor. Defaults to 0.5.
- The units are axes font size, i.e. for a default font size of 10 points
- *borderpad = 0.5* is equivalent to a padding of 5 points.
-
- Returns
- -------
- inset_axes : `axes_class`
- Inset axes object created.
- """
-
- if axes_class is None:
- axes_class = HostAxes
-
- if axes_kwargs is None:
- inset_axes = axes_class(parent_axes.figure, parent_axes.get_position())
- else:
- inset_axes = axes_class(parent_axes.figure, parent_axes.get_position(),
- **axes_kwargs)
-
- axes_locator = AnchoredZoomLocator(parent_axes, zoom=zoom, loc=loc,
- bbox_to_anchor=bbox_to_anchor,
- bbox_transform=bbox_transform,
- borderpad=borderpad)
- inset_axes.set_axes_locator(axes_locator)
-
- _add_inset_axes(parent_axes, inset_axes)
-
- return inset_axes
-
-
-@docstring.dedent_interpd
-def mark_inset(parent_axes, inset_axes, loc1, loc2, **kwargs):
- """
- Draw a box to mark the location of an area represented by an inset axes.
-
- This function draws a box in *parent_axes* at the bounding box of
- *inset_axes*, and shows a connection with the inset axes by drawing lines
- at the corners, giving a "zoomed in" effect.
-
- Parameters
- ----------
- parent_axes : `matplotlib.axes.Axes`
- Axes which contains the area of the inset axes.
-
- inset_axes : `matplotlib.axes.Axes`
- The inset axes.
-
- loc1, loc2 : {1, 2, 3, 4}
- Corners to use for connecting the inset axes and the area in the
- parent axes.
-
- **kwargs
- Patch properties for the lines and box drawn:
- %(Patch)s
-
- Returns
- -------
- pp : `matplotlib.patches.Patch`
- The patch drawn to represent the area of the inset axes.
-
- p1, p2 : `matplotlib.patches.Patch`
- The patches connecting two corners of the inset axes and its area.
- """
- rect = TransformedBbox(inset_axes.viewLim, parent_axes.transData)
-
- fill = kwargs.pop("fill", False)
- pp = BboxPatch(rect, fill=fill, **kwargs)
- parent_axes.add_patch(pp)
-
- p1 = BboxConnector(inset_axes.bbox, rect, loc1=loc1, **kwargs)
- inset_axes.add_patch(p1)
- p1.set_clip_on(False)
- p2 = BboxConnector(inset_axes.bbox, rect, loc1=loc2, **kwargs)
- inset_axes.add_patch(p2)
- p2.set_clip_on(False)
-
- return pp, p1, p2
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/mpl_axes.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/mpl_axes.py
deleted file mode 100644
index aaff7b7692..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/mpl_axes.py
+++ /dev/null
@@ -1,154 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import matplotlib.axes as maxes
-from matplotlib.artist import Artist
-from matplotlib.axis import XAxis, YAxis
-
-class SimpleChainedObjects(object):
- def __init__(self, objects):
- self._objects = objects
-
- def __getattr__(self, k):
- _a = SimpleChainedObjects([getattr(a, k) for a in self._objects])
- return _a
-
- def __call__(self, *kl, **kwargs):
- for m in self._objects:
- m(*kl, **kwargs)
-
-
-class Axes(maxes.Axes):
-
- class AxisDict(dict):
- def __init__(self, axes):
- self.axes = axes
- super(Axes.AxisDict, self).__init__()
-
- def __getitem__(self, k):
- if isinstance(k, tuple):
- r = SimpleChainedObjects(
- [super(Axes.AxisDict, self).__getitem__(k1) for k1 in k])
- return r
- elif isinstance(k, slice):
- if k.start is None and k.stop is None and k.step is None:
- r = SimpleChainedObjects(list(six.itervalues(self)))
- return r
- else:
- raise ValueError("Unsupported slice")
- else:
- return dict.__getitem__(self, k)
-
- def __call__(self, *v, **kwargs):
- return maxes.Axes.axis(self.axes, *v, **kwargs)
-
- def __init__(self, *kl, **kw):
- super(Axes, self).__init__(*kl, **kw)
-
- def _init_axis_artists(self, axes=None):
- if axes is None:
- axes = self
-
- self._axislines = self.AxisDict(self)
-
- self._axislines["bottom"] = SimpleAxisArtist(self.xaxis, 1, self.spines["bottom"])
- self._axislines["top"] = SimpleAxisArtist(self.xaxis, 2, self.spines["top"])
- self._axislines["left"] = SimpleAxisArtist(self.yaxis, 1, self.spines["left"])
- self._axislines["right"] = SimpleAxisArtist(self.yaxis, 2, self.spines["right"])
-
-
- def _get_axislines(self):
- return self._axislines
-
- axis = property(_get_axislines)
-
- def cla(self):
-
- super(Axes, self).cla()
- self._init_axis_artists()
-
-
-class SimpleAxisArtist(Artist):
- def __init__(self, axis, axisnum, spine):
- self._axis = axis
- self._axisnum = axisnum
- self.line = spine
-
- if isinstance(axis, XAxis):
- self._axis_direction = ["bottom", "top"][axisnum-1]
- elif isinstance(axis, YAxis):
- self._axis_direction = ["left", "right"][axisnum-1]
- else:
- raise ValueError("axis must be instance of XAxis or YAxis : %s is provided" % (axis,))
- Artist.__init__(self)
-
-
- def _get_major_ticks(self):
- tickline = "tick%dline" % self._axisnum
- return SimpleChainedObjects([getattr(tick, tickline)
- for tick in self._axis.get_major_ticks()])
-
- def _get_major_ticklabels(self):
- label = "label%d" % self._axisnum
- return SimpleChainedObjects([getattr(tick, label)
- for tick in self._axis.get_major_ticks()])
-
- def _get_label(self):
- return self._axis.label
-
- major_ticks = property(_get_major_ticks)
- major_ticklabels = property(_get_major_ticklabels)
- label = property(_get_label)
-
- def set_visible(self, b):
- self.toggle(all=b)
- self.line.set_visible(b)
- self._axis.set_visible(True)
- Artist.set_visible(self, b)
-
- def set_label(self, txt):
- self._axis.set_label_text(txt)
-
- def toggle(self, all=None, ticks=None, ticklabels=None, label=None):
-
- if all:
- _ticks, _ticklabels, _label = True, True, True
- elif all is not None:
- _ticks, _ticklabels, _label = False, False, False
- else:
- _ticks, _ticklabels, _label = None, None, None
-
- if ticks is not None:
- _ticks = ticks
- if ticklabels is not None:
- _ticklabels = ticklabels
- if label is not None:
- _label = label
-
- tickOn = "tick%dOn" % self._axisnum
- labelOn = "label%dOn" % self._axisnum
-
- if _ticks is not None:
- tickparam = {tickOn: _ticks}
- self._axis.set_tick_params(**tickparam)
- if _ticklabels is not None:
- tickparam = {labelOn: _ticklabels}
- self._axis.set_tick_params(**tickparam)
-
- if _label is not None:
- pos = self._axis.get_label_position()
- if (pos == self._axis_direction) and not _label:
- self._axis.label.set_visible(False)
- elif _label:
- self._axis.label.set_visible(True)
- self._axis.set_label_position(self._axis_direction)
-
-
-if __name__ == '__main__':
- import matplotlib.pyplot as plt
- fig = plt.figure()
- ax = Axes(fig, [0.1, 0.1, 0.8, 0.8])
- fig.add_axes(ax)
- ax.cla()
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/parasite_axes.py b/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/parasite_axes.py
deleted file mode 100644
index 16a67b4d1f..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axes_grid1/parasite_axes.py
+++ /dev/null
@@ -1,486 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from matplotlib import (
- artist as martist, collections as mcoll, transforms as mtransforms,
- rcParams)
-from matplotlib.axes import subplot_class_factory
-from matplotlib.transforms import Bbox
-from .mpl_axes import Axes
-
-import numpy as np
-
-
-class ParasiteAxesBase(object):
-
- def get_images_artists(self):
- artists = {a for a in self.get_children() if a.get_visible()}
- images = {a for a in self.images if a.get_visible()}
-
- return list(images), list(artists - images)
-
- def __init__(self, parent_axes, **kargs):
-
- self._parent_axes = parent_axes
- kargs.update(dict(frameon=False))
- self._get_base_axes_attr("__init__")(self, parent_axes.figure,
- parent_axes._position, **kargs)
-
- def cla(self):
- self._get_base_axes_attr("cla")(self)
-
- martist.setp(self.get_children(), visible=False)
- self._get_lines = self._parent_axes._get_lines
-
- # In mpl's Axes, zorders of x- and y-axis are originally set
- # within Axes.draw().
- if self._axisbelow:
- self.xaxis.set_zorder(0.5)
- self.yaxis.set_zorder(0.5)
- else:
- self.xaxis.set_zorder(2.5)
- self.yaxis.set_zorder(2.5)
-
-
-_parasite_axes_classes = {}
-def parasite_axes_class_factory(axes_class=None):
- if axes_class is None:
- axes_class = Axes
-
- new_class = _parasite_axes_classes.get(axes_class)
- if new_class is None:
- def _get_base_axes_attr(self, attrname):
- return getattr(axes_class, attrname)
-
- new_class = type(str("%sParasite" % (axes_class.__name__)),
- (ParasiteAxesBase, axes_class),
- {'_get_base_axes_attr': _get_base_axes_attr})
- _parasite_axes_classes[axes_class] = new_class
-
- return new_class
-
-ParasiteAxes = parasite_axes_class_factory()
-
-# #class ParasiteAxes(ParasiteAxesBase, Axes):
-
-# @classmethod
-# def _get_base_axes_attr(cls, attrname):
-# return getattr(Axes, attrname)
-
-
-
-class ParasiteAxesAuxTransBase(object):
- def __init__(self, parent_axes, aux_transform, viewlim_mode=None,
- **kwargs):
-
- self.transAux = aux_transform
- self.set_viewlim_mode(viewlim_mode)
-
- self._parasite_axes_class.__init__(self, parent_axes, **kwargs)
-
- def _set_lim_and_transforms(self):
-
- self.transAxes = self._parent_axes.transAxes
-
- self.transData = \
- self.transAux + \
- self._parent_axes.transData
-
- self._xaxis_transform = mtransforms.blended_transform_factory(
- self.transData, self.transAxes)
- self._yaxis_transform = mtransforms.blended_transform_factory(
- self.transAxes, self.transData)
-
- def set_viewlim_mode(self, mode):
- if mode not in [None, "equal", "transform"]:
- raise ValueError("Unknown mode : %s" % (mode,))
- else:
- self._viewlim_mode = mode
-
- def get_viewlim_mode(self):
- return self._viewlim_mode
-
-
- def update_viewlim(self):
- viewlim = self._parent_axes.viewLim.frozen()
- mode = self.get_viewlim_mode()
- if mode is None:
- pass
- elif mode == "equal":
- self.axes.viewLim.set(viewlim)
- elif mode == "transform":
- self.axes.viewLim.set(viewlim.transformed(self.transAux.inverted()))
- else:
- raise ValueError("Unknown mode : %s" % (self._viewlim_mode,))
-
-
- def _pcolor(self, method_name, *XYC, **kwargs):
- if len(XYC) == 1:
- C = XYC[0]
- ny, nx = C.shape
-
- gx = np.arange(-0.5, nx, 1.)
- gy = np.arange(-0.5, ny, 1.)
-
- X, Y = np.meshgrid(gx, gy)
- else:
- X, Y, C = XYC
-
- pcolor_routine = self._get_base_axes_attr(method_name)
-
- if "transform" in kwargs:
- mesh = pcolor_routine(self, X, Y, C, **kwargs)
- else:
- orig_shape = X.shape
- xy = np.vstack([X.flat, Y.flat])
- xyt=xy.transpose()
- wxy = self.transAux.transform(xyt)
- gx, gy = wxy[:,0].reshape(orig_shape), wxy[:,1].reshape(orig_shape)
- mesh = pcolor_routine(self, gx, gy, C, **kwargs)
- mesh.set_transform(self._parent_axes.transData)
-
- return mesh
-
- def pcolormesh(self, *XYC, **kwargs):
- return self._pcolor("pcolormesh", *XYC, **kwargs)
-
- def pcolor(self, *XYC, **kwargs):
- return self._pcolor("pcolor", *XYC, **kwargs)
-
-
- def _contour(self, method_name, *XYCL, **kwargs):
-
- if len(XYCL) <= 2:
- C = XYCL[0]
- ny, nx = C.shape
-
- gx = np.arange(0., nx, 1.)
- gy = np.arange(0., ny, 1.)
-
- X,Y = np.meshgrid(gx, gy)
- CL = XYCL
- else:
- X, Y = XYCL[:2]
- CL = XYCL[2:]
-
- contour_routine = self._get_base_axes_attr(method_name)
-
- if "transform" in kwargs:
- cont = contour_routine(self, X, Y, *CL, **kwargs)
- else:
- orig_shape = X.shape
- xy = np.vstack([X.flat, Y.flat])
- xyt=xy.transpose()
- wxy = self.transAux.transform(xyt)
- gx, gy = wxy[:,0].reshape(orig_shape), wxy[:,1].reshape(orig_shape)
- cont = contour_routine(self, gx, gy, *CL, **kwargs)
- for c in cont.collections:
- c.set_transform(self._parent_axes.transData)
-
- return cont
-
- def contour(self, *XYCL, **kwargs):
- return self._contour("contour", *XYCL, **kwargs)
-
- def contourf(self, *XYCL, **kwargs):
- return self._contour("contourf", *XYCL, **kwargs)
-
- def apply_aspect(self, position=None):
- self.update_viewlim()
- self._get_base_axes_attr("apply_aspect")(self)
- #ParasiteAxes.apply_aspect()
-
-
-
-_parasite_axes_auxtrans_classes = {}
-def parasite_axes_auxtrans_class_factory(axes_class=None):
- if axes_class is None:
- parasite_axes_class = ParasiteAxes
- elif not issubclass(axes_class, ParasiteAxesBase):
- parasite_axes_class = parasite_axes_class_factory(axes_class)
- else:
- parasite_axes_class = axes_class
-
- new_class = _parasite_axes_auxtrans_classes.get(parasite_axes_class)
- if new_class is None:
- new_class = type(str("%sParasiteAuxTrans" % (parasite_axes_class.__name__)),
- (ParasiteAxesAuxTransBase, parasite_axes_class),
- {'_parasite_axes_class': parasite_axes_class,
- 'name': 'parasite_axes'})
- _parasite_axes_auxtrans_classes[parasite_axes_class] = new_class
-
- return new_class
-
-
-ParasiteAxesAuxTrans = parasite_axes_auxtrans_class_factory(axes_class=ParasiteAxes)
-
-
-
-
-def _get_handles(ax):
- handles = ax.lines[:]
- handles.extend(ax.patches)
- handles.extend([c for c in ax.collections
- if isinstance(c, mcoll.LineCollection)])
- handles.extend([c for c in ax.collections
- if isinstance(c, mcoll.RegularPolyCollection)])
- handles.extend([c for c in ax.collections
- if isinstance(c, mcoll.CircleCollection)])
-
- return handles
-
-
-class HostAxesBase(object):
- def __init__(self, *args, **kwargs):
-
- self.parasites = []
- self._get_base_axes_attr("__init__")(self, *args, **kwargs)
-
-
- def get_aux_axes(self, tr, viewlim_mode="equal", axes_class=None):
- parasite_axes_class = parasite_axes_auxtrans_class_factory(axes_class)
- ax2 = parasite_axes_class(self, tr, viewlim_mode)
- # note that ax2.transData == tr + ax1.transData
- # Anthing you draw in ax2 will match the ticks and grids of ax1.
- self.parasites.append(ax2)
- ax2._remove_method = lambda h: self.parasites.remove(h)
- return ax2
-
- def _get_legend_handles(self, legend_handler_map=None):
- # don't use this!
- Axes_get_legend_handles = self._get_base_axes_attr("_get_legend_handles")
- all_handles = list(Axes_get_legend_handles(self, legend_handler_map))
-
- for ax in self.parasites:
- all_handles.extend(ax._get_legend_handles(legend_handler_map))
-
- return all_handles
-
-
- def draw(self, renderer):
-
- orig_artists = list(self.artists)
- orig_images = list(self.images)
-
- if hasattr(self, "get_axes_locator"):
- locator = self.get_axes_locator()
- if locator:
- pos = locator(self, renderer)
- self.set_position(pos, which="active")
- self.apply_aspect(pos)
- else:
- self.apply_aspect()
- else:
- self.apply_aspect()
-
- rect = self.get_position()
-
- for ax in self.parasites:
- ax.apply_aspect(rect)
- images, artists = ax.get_images_artists()
- self.images.extend(images)
- self.artists.extend(artists)
-
- self._get_base_axes_attr("draw")(self, renderer)
- self.artists = orig_artists
- self.images = orig_images
-
-
- def cla(self):
-
- for ax in self.parasites:
- ax.cla()
-
- self._get_base_axes_attr("cla")(self)
- #super(HostAxes, self).cla()
-
-
- def twinx(self, axes_class=None):
- """
- create a twin of Axes for generating a plot with a sharex
- x-axis but independent y axis. The y-axis of self will have
- ticks on left and the returned axes will have ticks on the
- right
- """
-
- if axes_class is None:
- axes_class = self._get_base_axes()
-
- parasite_axes_class = parasite_axes_class_factory(axes_class)
-
- ax2 = parasite_axes_class(self, sharex=self, frameon=False)
- self.parasites.append(ax2)
-
- self.axis["right"].set_visible(False)
-
- ax2.axis["right"].set_visible(True)
- ax2.axis["left", "top", "bottom"].set_visible(False)
-
- def _remove_method(h):
- self.parasites.remove(h)
- self.axis["right"].set_visible(True)
- self.axis["right"].toggle(ticklabels=False, label=False)
- ax2._remove_method = _remove_method
-
- return ax2
-
- def twiny(self, axes_class=None):
- """
- create a twin of Axes for generating a plot with a shared
- y-axis but independent x axis. The x-axis of self will have
- ticks on bottom and the returned axes will have ticks on the
- top
- """
-
- if axes_class is None:
- axes_class = self._get_base_axes()
-
- parasite_axes_class = parasite_axes_class_factory(axes_class)
-
- ax2 = parasite_axes_class(self, sharey=self, frameon=False)
- self.parasites.append(ax2)
-
- self.axis["top"].set_visible(False)
-
- ax2.axis["top"].set_visible(True)
- ax2.axis["left", "right", "bottom"].set_visible(False)
-
- def _remove_method(h):
- self.parasites.remove(h)
- self.axis["top"].set_visible(True)
- self.axis["top"].toggle(ticklabels=False, label=False)
- ax2._remove_method = _remove_method
-
- return ax2
-
-
- def twin(self, aux_trans=None, axes_class=None):
- """
- create a twin of Axes for generating a plot with a sharex
- x-axis but independent y axis. The y-axis of self will have
- ticks on left and the returned axes will have ticks on the
- right
- """
-
- if axes_class is None:
- axes_class = self._get_base_axes()
-
- parasite_axes_auxtrans_class = parasite_axes_auxtrans_class_factory(axes_class)
-
- if aux_trans is None:
- ax2 = parasite_axes_auxtrans_class(self, mtransforms.IdentityTransform(),
- viewlim_mode="equal",
- )
- else:
- ax2 = parasite_axes_auxtrans_class(self, aux_trans,
- viewlim_mode="transform",
- )
- self.parasites.append(ax2)
- ax2._remove_method = lambda h: self.parasites.remove(h)
-
- self.axis["top", "right"].set_visible(False)
-
- ax2.axis["top", "right"].set_visible(True)
- ax2.axis["left", "bottom"].set_visible(False)
-
- def _remove_method(h):
- self.parasites.remove(h)
- self.axis["top", "right"].set_visible(True)
- self.axis["top", "right"].toggle(ticklabels=False, label=False)
- ax2._remove_method = _remove_method
-
- return ax2
-
- def get_tightbbox(self, renderer, call_axes_locator=True):
-
- bbs = [ax.get_tightbbox(renderer, call_axes_locator)
- for ax in self.parasites]
- get_tightbbox = self._get_base_axes_attr("get_tightbbox")
- bbs.append(get_tightbbox(self, renderer, call_axes_locator))
-
- _bbox = Bbox.union([b for b in bbs if b.width!=0 or b.height!=0])
-
- return _bbox
-
-
-
-_host_axes_classes = {}
-def host_axes_class_factory(axes_class=None):
- if axes_class is None:
- axes_class = Axes
-
- new_class = _host_axes_classes.get(axes_class)
- if new_class is None:
- def _get_base_axes(self):
- return axes_class
-
- def _get_base_axes_attr(self, attrname):
- return getattr(axes_class, attrname)
-
- new_class = type(str("%sHostAxes" % (axes_class.__name__)),
- (HostAxesBase, axes_class),
- {'_get_base_axes_attr': _get_base_axes_attr,
- '_get_base_axes': _get_base_axes})
-
- _host_axes_classes[axes_class] = new_class
-
- return new_class
-
-def host_subplot_class_factory(axes_class):
- host_axes_class = host_axes_class_factory(axes_class=axes_class)
- subplot_host_class = subplot_class_factory(host_axes_class)
- return subplot_host_class
-
-HostAxes = host_axes_class_factory(axes_class=Axes)
-SubplotHost = subplot_class_factory(HostAxes)
-
-
-def host_axes(*args, **kwargs):
- """
- Create axes that can act as a hosts to parasitic axes.
-
- Parameters
- ----------
- figure : `matplotlib.figure.Figure`
- Figure to which the axes will be added. Defaults to the current figure
- `pyplot.gcf()`.
-
- *args, **kwargs :
- Will be passed on to the underlying ``Axes`` object creation.
- """
- import matplotlib.pyplot as plt
- axes_class = kwargs.pop("axes_class", None)
- host_axes_class = host_axes_class_factory(axes_class)
- fig = kwargs.get("figure", None)
- if fig is None:
- fig = plt.gcf()
- ax = host_axes_class(fig, *args, **kwargs)
- fig.add_axes(ax)
- plt.draw_if_interactive()
- return ax
-
-def host_subplot(*args, **kwargs):
- """
- Create a subplot that can act as a host to parasitic axes.
-
- Parameters
- ----------
- figure : `matplotlib.figure.Figure`
- Figure to which the subplot will be added. Defaults to the current
- figure `pyplot.gcf()`.
-
- *args, **kwargs :
- Will be passed on to the underlying ``Axes`` object creation.
- """
- import matplotlib.pyplot as plt
- axes_class = kwargs.pop("axes_class", None)
- host_subplot_class = host_subplot_class_factory(axes_class)
- fig = kwargs.get("figure", None)
- if fig is None:
- fig = plt.gcf()
- ax = host_subplot_class(fig, *args, **kwargs)
- fig.add_subplot(ax)
- plt.draw_if_interactive()
- return ax
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/__init__.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/__init__.py
deleted file mode 100644
index 8431c0cd3e..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from .axislines import (
- Axes, AxesZero, AxisArtistHelper, AxisArtistHelperRectlinear,
- GridHelperBase, GridHelperRectlinear, Subplot, SubplotZero)
-from .axis_artist import AxisArtist, GridlinesCollection
-
-from .grid_helper_curvelinear import GridHelperCurveLinear
-
-from .floating_axes import FloatingAxes, FloatingSubplot
-
-from mpl_toolkits.axes_grid1.parasite_axes import (
- host_axes_class_factory, parasite_axes_class_factory,
- parasite_axes_auxtrans_class_factory, subplot_class_factory)
-
-ParasiteAxes = parasite_axes_class_factory(Axes)
-
-ParasiteAxesAuxTrans = \
- parasite_axes_auxtrans_class_factory(axes_class=ParasiteAxes)
-
-HostAxes = host_axes_class_factory(axes_class=Axes)
-
-SubplotHost = subplot_class_factory(HostAxes)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/angle_helper.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/angle_helper.py
deleted file mode 100644
index 15732a58ec..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/angle_helper.py
+++ /dev/null
@@ -1,416 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import numpy as np
-import math
-
-from mpl_toolkits.axisartist.grid_finder import ExtremeFinderSimple
-
-def select_step_degree(dv):
-
- degree_limits_ = [1.5, 3, 7, 13, 20, 40, 70, 120, 270, 520]
- degree_steps_ = [ 1, 2, 5, 10, 15, 30, 45, 90, 180, 360]
- degree_factors = [1.] * len(degree_steps_)
-
- minsec_limits_ = [1.5, 2.5, 3.5, 8, 11, 18, 25, 45]
- minsec_steps_ = [1, 2, 3, 5, 10, 15, 20, 30]
-
- minute_limits_ = np.array(minsec_limits_) / 60
- minute_factors = [60.] * len(minute_limits_)
-
- second_limits_ = np.array(minsec_limits_) / 3600
- second_factors = [3600.] * len(second_limits_)
-
- degree_limits = np.concatenate([second_limits_,
- minute_limits_,
- degree_limits_])
-
- degree_steps = np.concatenate([minsec_steps_,
- minsec_steps_,
- degree_steps_])
-
- degree_factors = np.concatenate([second_factors,
- minute_factors,
- degree_factors])
-
- n = degree_limits.searchsorted(dv)
- step = degree_steps[n]
- factor = degree_factors[n]
-
- return step, factor
-
-
-
-def select_step_hour(dv):
-
- hour_limits_ = [1.5, 2.5, 3.5, 5, 7, 10, 15, 21, 36]
- hour_steps_ = [1, 2 , 3, 4, 6, 8, 12, 18, 24]
- hour_factors = [1.] * len(hour_steps_)
-
- minsec_limits_ = [1.5, 2.5, 3.5, 4.5, 5.5, 8, 11, 14, 18, 25, 45]
- minsec_steps_ = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30]
-
- minute_limits_ = np.array(minsec_limits_) / 60
- minute_factors = [60.] * len(minute_limits_)
-
- second_limits_ = np.array(minsec_limits_) / 3600
- second_factors = [3600.] * len(second_limits_)
-
- hour_limits = np.concatenate([second_limits_,
- minute_limits_,
- hour_limits_])
-
- hour_steps = np.concatenate([minsec_steps_,
- minsec_steps_,
- hour_steps_])
-
- hour_factors = np.concatenate([second_factors,
- minute_factors,
- hour_factors])
-
- n = hour_limits.searchsorted(dv)
- step = hour_steps[n]
- factor = hour_factors[n]
-
- return step, factor
-
-
-def select_step_sub(dv):
-
- # subarcsec or degree
- tmp = 10.**(int(math.log10(dv))-1.)
-
- factor = 1./tmp
-
- if 1.5*tmp >= dv:
- step = 1
- elif 3.*tmp >= dv:
- step = 2
- elif 7.*tmp >= dv:
- step = 5
- else:
- step = 1
- factor = 0.1*factor
-
- return step, factor
-
-
-def select_step(v1, v2, nv, hour=False, include_last=True,
- threshold_factor=3600.):
-
- if v1 > v2:
- v1, v2 = v2, v1
-
- dv = (v2 - v1) / nv
-
- if hour:
- _select_step = select_step_hour
- cycle = 24.
- else:
- _select_step = select_step_degree
- cycle = 360.
-
- # for degree
- if dv > 1./threshold_factor:
- step, factor = _select_step(dv)
- else:
- step, factor = select_step_sub(dv*threshold_factor)
-
- factor = factor * threshold_factor
-
-
- f1, f2, fstep = v1*factor, v2*factor, step/factor
- levs = np.arange(np.floor(f1/step), np.ceil(f2/step)+0.5, dtype=int) * step
-
- # n : number of valid levels. If there is a cycle, e.g., [0, 90, 180,
- # 270, 360], the grid line needs to be extended from 0 to 360, so
- # we need to return the whole array. However, the last level (360)
- # needs to be ignored often. In this case, so we return n=4.
-
- n = len(levs)
-
-
- # we need to check the range of values
- # for example, -90 to 90, 0 to 360,
-
- if factor == 1. and (levs[-1] >= levs[0]+cycle): # check for cycle
- nv = int(cycle / step)
- if include_last:
- levs = levs[0] + np.arange(0, nv+1, 1) * step
- else:
- levs = levs[0] + np.arange(0, nv, 1) * step
-
- n = len(levs)
-
- return np.array(levs), n, factor
-
-
-def select_step24(v1, v2, nv, include_last=True, threshold_factor=3600):
- v1, v2 = v1/15., v2/15.
- levs, n, factor = select_step(v1, v2, nv, hour=True,
- include_last=include_last,
- threshold_factor=threshold_factor)
- return levs*15., n, factor
-
-def select_step360(v1, v2, nv, include_last=True, threshold_factor=3600):
- return select_step(v1, v2, nv, hour=False,
- include_last=include_last,
- threshold_factor=threshold_factor)
-
-
-class LocatorBase(object):
- def __init__(self, den, include_last=True):
- self.den = den
- self._include_last = include_last
-
- @property
- def nbins(self):
- return self.den
-
- @nbins.setter
- def nbins(self, v):
- self.den = v
-
- def set_params(self, nbins=None):
- if nbins is not None:
- self.den = int(nbins)
-
-
-class LocatorHMS(LocatorBase):
- def __call__(self, v1, v2):
- return select_step24(v1, v2, self.den, self._include_last)
-
-class LocatorHM(LocatorBase):
- def __call__(self, v1, v2):
- return select_step24(v1, v2, self.den, self._include_last,
- threshold_factor=60)
-
-class LocatorH(LocatorBase):
- def __call__(self, v1, v2):
- return select_step24(v1, v2, self.den, self._include_last,
- threshold_factor=1)
-
-
-class LocatorDMS(LocatorBase):
- def __call__(self, v1, v2):
- return select_step360(v1, v2, self.den, self._include_last)
-
-class LocatorDM(LocatorBase):
- def __call__(self, v1, v2):
- return select_step360(v1, v2, self.den, self._include_last,
- threshold_factor=60)
-
-class LocatorD(LocatorBase):
- def __call__(self, v1, v2):
- return select_step360(v1, v2, self.den, self._include_last,
- threshold_factor=1)
-
-
-class FormatterDMS(object):
- deg_mark = r"^{\circ}"
- min_mark = r"^{\prime}"
- sec_mark = r"^{\prime\prime}"
-
- fmt_d = "$%d" + deg_mark + "$"
- fmt_ds = r"$%d.%s" + deg_mark + "$"
-
- # %s for sign
- fmt_d_m = r"$%s%d" + deg_mark + r"\,%02d" + min_mark + "$"
- fmt_d_ms = r"$%s%d" + deg_mark + r"\,%02d.%s" + min_mark + "$"
-
- fmt_d_m_partial = "$%s%d" + deg_mark + r"\,%02d" + min_mark + r"\,"
- fmt_s_partial = "%02d" + sec_mark + "$"
- fmt_ss_partial = "%02d.%s" + sec_mark + "$"
-
- def _get_number_fraction(self, factor):
- ## check for fractional numbers
- number_fraction = None
- # check for 60
-
- for threshold in [1, 60, 3600]:
- if factor <= threshold:
- break
-
- d = factor // threshold
- int_log_d = int(np.floor(np.log10(d)))
- if 10**int_log_d == d and d != 1:
- number_fraction = int_log_d
- factor = factor // 10**int_log_d
- return factor, number_fraction
-
- return factor, number_fraction
-
-
- def __call__(self, direction, factor, values):
- if len(values) == 0:
- return []
- #ss = [[-1, 1][v>0] for v in values] #not py24 compliant
- values = np.asarray(values)
- ss = np.where(values>0, 1, -1)
-
- sign_map = {(-1, True):"-"}
- signs = [sign_map.get((s, v!=0), "") for s, v in zip(ss, values)]
-
- factor, number_fraction = self._get_number_fraction(factor)
-
- values = np.abs(values)
-
- if number_fraction is not None:
- values, frac_part = divmod(values, 10**number_fraction)
- frac_fmt = "%%0%dd" % (number_fraction,)
- frac_str = [frac_fmt % (f1,) for f1 in frac_part]
-
- if factor == 1:
- if number_fraction is None:
- return [self.fmt_d % (s*int(v),) for (s, v) in zip(ss, values)]
- else:
- return [self.fmt_ds % (s*int(v), f1)
- for (s, v, f1) in zip(ss, values, frac_str)]
- elif factor == 60:
- deg_part, min_part = divmod(values, 60)
- if number_fraction is None:
- return [self.fmt_d_m % (s1, d1, m1)
- for s1, d1, m1 in zip(signs, deg_part, min_part)]
- else:
- return [self.fmt_d_ms % (s, d1, m1, f1)
- for s, d1, m1, f1 in zip(signs, deg_part, min_part, frac_str)]
-
- elif factor == 3600:
- if ss[-1] == -1:
- inverse_order = True
- values = values[::-1]
- signs = signs[::-1]
- else:
- inverse_order = False
-
- l_hm_old = ""
- r = []
-
- deg_part, min_part_ = divmod(values, 3600)
- min_part, sec_part = divmod(min_part_, 60)
-
- if number_fraction is None:
- sec_str = [self.fmt_s_partial % (s1,) for s1 in sec_part]
- else:
- sec_str = [self.fmt_ss_partial % (s1, f1) for s1, f1 in zip(sec_part, frac_str)]
-
- for s, d1, m1, s1 in zip(signs, deg_part, min_part, sec_str):
- l_hm = self.fmt_d_m_partial % (s, d1, m1)
- if l_hm != l_hm_old:
- l_hm_old = l_hm
- l = l_hm + s1 #l_s
- else:
- l = "$" + s + s1
- r.append(l)
-
- if inverse_order:
- return r[::-1]
- else:
- return r
-
- else: # factor > 3600.
- return [r"$%s^{\circ}$" % (str(v),) for v in ss*values]
-
-
-class FormatterHMS(FormatterDMS):
- deg_mark = r"^\mathrm{h}"
- min_mark = r"^\mathrm{m}"
- sec_mark = r"^\mathrm{s}"
-
- fmt_d = "$%d" + deg_mark + "$"
- fmt_ds = r"$%d.%s" + deg_mark + "$"
-
- # %s for sign
- fmt_d_m = r"$%s%d" + deg_mark + r"\,%02d" + min_mark+"$"
- fmt_d_ms = r"$%s%d" + deg_mark + r"\,%02d.%s" + min_mark+"$"
-
- fmt_d_m_partial = "$%s%d" + deg_mark + r"\,%02d" + min_mark + r"\,"
- fmt_s_partial = "%02d" + sec_mark + "$"
- fmt_ss_partial = "%02d.%s" + sec_mark + "$"
-
- def __call__(self, direction, factor, values): # hour
- return FormatterDMS.__call__(self, direction, factor, np.asarray(values)/15.)
-
-
-
-
-
-class ExtremeFinderCycle(ExtremeFinderSimple):
- """
- When there is a cycle, e.g., longitude goes from 0-360.
- """
- def __init__(self,
- nx, ny,
- lon_cycle = 360.,
- lat_cycle = None,
- lon_minmax = None,
- lat_minmax = (-90, 90)
- ):
- #self.transfrom_xy = transform_xy
- #self.inv_transfrom_xy = inv_transform_xy
- self.nx, self.ny = nx, ny
- self.lon_cycle, self.lat_cycle = lon_cycle, lat_cycle
- self.lon_minmax = lon_minmax
- self.lat_minmax = lat_minmax
-
-
- def __call__(self, transform_xy, x1, y1, x2, y2):
- """
- get extreme values.
-
- x1, y1, x2, y2 in image coordinates (0-based)
- nx, ny : number of divisions in each axis
- """
- x_, y_ = np.linspace(x1, x2, self.nx), np.linspace(y1, y2, self.ny)
- x, y = np.meshgrid(x_, y_)
- lon, lat = transform_xy(np.ravel(x), np.ravel(y))
-
- # iron out jumps, but algorithm should be improved.
- # This is just naive way of doing and my fail for some cases.
- # Consider replacing this with numpy.unwrap
- # We are ignoring invalid warnings. They are triggered when
- # comparing arrays with NaNs using > We are already handling
- # that correctly using np.nanmin and np.nanmax
- with np.errstate(invalid='ignore'):
- if self.lon_cycle is not None:
- lon0 = np.nanmin(lon)
- lon -= 360. * ((lon - lon0) > 180.)
- if self.lat_cycle is not None:
- lat0 = np.nanmin(lat)
- lat -= 360. * ((lat - lat0) > 180.)
-
- lon_min, lon_max = np.nanmin(lon), np.nanmax(lon)
- lat_min, lat_max = np.nanmin(lat), np.nanmax(lat)
-
- lon_min, lon_max, lat_min, lat_max = \
- self._adjust_extremes(lon_min, lon_max, lat_min, lat_max)
-
- return lon_min, lon_max, lat_min, lat_max
-
-
- def _adjust_extremes(self, lon_min, lon_max, lat_min, lat_max):
-
- lon_min, lon_max, lat_min, lat_max = \
- self._add_pad(lon_min, lon_max, lat_min, lat_max)
-
- # check cycle
- if self.lon_cycle:
- lon_max = min(lon_max, lon_min + self.lon_cycle)
- if self.lat_cycle:
- lat_max = min(lat_max, lat_min + self.lat_cycle)
-
- if self.lon_minmax is not None:
- min0 = self.lon_minmax[0]
- lon_min = max(min0, lon_min)
- max0 = self.lon_minmax[1]
- lon_max = min(max0, lon_max)
-
- if self.lat_minmax is not None:
- min0 = self.lat_minmax[0]
- lat_min = max(min0, lat_min)
- max0 = self.lat_minmax[1]
- lat_max = min(max0, lat_max)
-
- return lon_min, lon_max, lat_min, lat_max
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_divider.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_divider.py
deleted file mode 100644
index 5294940530..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_divider.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axes_grid1.axes_divider import (
- Divider, AxesLocator, SubplotDivider, AxesDivider, locatable_axes_factory,
- make_axes_locatable)
-
-from mpl_toolkits.axes_grid.axislines import Axes
-LocatableAxes = locatable_axes_factory(Axes)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_grid.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_grid.py
deleted file mode 100644
index 58212ac89c..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_grid.py
+++ /dev/null
@@ -1,30 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import mpl_toolkits.axes_grid1.axes_grid as axes_grid_orig
-from .axes_divider import LocatableAxes
-
-class CbarAxes(axes_grid_orig.CbarAxesBase, LocatableAxes):
- def __init__(self, *kl, **kwargs):
- orientation=kwargs.pop("orientation", None)
- if orientation is None:
- raise ValueError("orientation must be specified")
- self.orientation = orientation
- self._default_label_on = False
- self.locator = None
-
- super(LocatableAxes, self).__init__(*kl, **kwargs)
-
- def cla(self):
- super(LocatableAxes, self).cla()
- self._config_axes()
-
-
-class Grid(axes_grid_orig.Grid):
- _defaultLocatableAxesClass = LocatableAxes
-
-class ImageGrid(axes_grid_orig.ImageGrid):
- _defaultLocatableAxesClass = LocatableAxes
- _defaultCbarAxesClass = CbarAxes
-
-AxesGrid = ImageGrid
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_rgb.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_rgb.py
deleted file mode 100644
index 695a362b57..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axes_rgb.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axes_grid1.axes_rgb import (
- make_rgb_axes, imshow_rgb, RGBAxesBase)
-
-from .axislines import Axes
-
-
-class RGBAxes(RGBAxesBase):
- _defaultAxesClass = Axes
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axis_artist.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axis_artist.py
deleted file mode 100644
index 620232112c..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axis_artist.py
+++ /dev/null
@@ -1,1527 +0,0 @@
-"""
-axis_artist.py module provides axis-related artists. They are
-
- * axis line
- * tick lines
- * tick labels
- * axis label
- * grid lines
-
-The main artist class is a AxisArtist and a GridlinesCollection. The
-GridlinesCollection is responsible for drawing grid lines and the
-AxisArtist is responsible for all other artists. The AxisArtist class
-has attributes that are associated with each type of artists.
-
- * line : axis line
- * major_ticks : major tick lines
- * major_ticklabels : major tick labels
- * minor_ticks : minor tick lines
- * minor_ticklabels : minor tick labels
- * label : axis label
-
-Typically, the AxisArtist associated with a axes will be accessed with
-the *axis* dictionary of the axes, i.e., the AxisArtist for the bottom
-axis is
-
- ax.axis["bottom"]
-
-where *ax* is an instance of axes (mpl_toolkits.axislines.Axes). Thus,
-ax.axis["bottom"].line is an artist associated with the axis line, and
-ax.axis["bottom"].major_ticks is an artist associated with the major tick
-lines.
-
-You can change the colors, fonts, line widths, etc. of these artists
-by calling suitable set method. For example, to change the color of the major
-ticks of the bottom axis to red,
-
- ax.axis["bottom"].major_ticks.set_color("r")
-
-However, things like the locations of ticks, and their ticklabels need
-to be changed from the side of the grid_helper.
-
-axis_direction
---------------
-
-AxisArtist, AxisLabel, TickLabels have *axis_direction* attribute,
-which adjusts the location, angle, etc.,. The *axis_direction* must be
-one of [left, right, bottom, top] and they follow the matplotlib
-convention for the rectangle axis.
-
-For example, for the *bottom* axis (the left and right is relative to
-the direction of the increasing coordinate),
-
- * ticklabels and axislabel are on the right
- * ticklabels and axislabel have text angle of 0
- * ticklabels are baseline, center-aligned
- * axislabel is top, center-aligned
-
-
-The text angles are actually relative to (90 + angle of the direction
-to the ticklabel), which gives 0 for bottom axis.
-
- Parameter left bottom right top
- ticklabels location left right right left
- axislabel location left right right left
- ticklabels angle 90 0 -90 180
- axislabel angle 180 0 0 180
- ticklabel va center baseline center baseline
- axislabel va center top center bottom
- ticklabel ha right center right center
- axislabel ha right center right center
-
-
-Ticks are by default direct opposite side of the ticklabels. To make
-ticks to the same side of the ticklabels,
-
- ax.axis["bottom"].major_ticks.set_ticks_out(True)
-
-
-Following attributes can be customized (use set_xxx method)
-
- * Ticks : ticksize, tick_out
- * TickLabels : pad
- * AxisLabel : pad
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-# FIXME :
-# angles are given in data coordinate - need to convert it to canvas coordinate
-
-
-import matplotlib.artist as martist
-import matplotlib.text as mtext
-import matplotlib.font_manager as font_manager
-
-from matplotlib.path import Path
-from matplotlib.transforms import (
- Affine2D, Bbox, IdentityTransform, ScaledTranslation, TransformedPath)
-from matplotlib.collections import LineCollection
-
-from matplotlib import rcParams
-
-from matplotlib.artist import allow_rasterization
-
-import warnings
-
-import numpy as np
-
-
-import matplotlib.lines as mlines
-from .axisline_style import AxislineStyle
-
-
-class BezierPath(mlines.Line2D):
-
- def __init__(self, path, *kl, **kw):
- mlines.Line2D.__init__(self, [], [], *kl, **kw)
- self._path = path
- self._invalid = False
-
- def recache(self):
-
- self._transformed_path = TransformedPath(self._path, self.get_transform())
-
- self._invalid = False
-
- def set_path(self, path):
- self._path = path
- self._invalid = True
-
-
- def draw(self, renderer):
- if self._invalid:
- self.recache()
-
- if not self._visible: return
- renderer.open_group('line2d')
-
- gc = renderer.new_gc()
- self._set_gc_clip(gc)
-
- gc.set_foreground(self._color)
- gc.set_antialiased(self._antialiased)
- gc.set_linewidth(self._linewidth)
- gc.set_alpha(self._alpha)
- if self.is_dashed():
- cap = self._dashcapstyle
- join = self._dashjoinstyle
- else:
- cap = self._solidcapstyle
- join = self._solidjoinstyle
- gc.set_joinstyle(join)
- gc.set_capstyle(cap)
- gc.set_dashes(self._dashOffset, self._dashSeq)
-
- if self._lineStyles[self._linestyle] != '_draw_nothing':
- tpath, affine = (
- self._transformed_path.get_transformed_path_and_affine())
- renderer.draw_path(gc, tpath, affine.frozen())
-
- gc.restore()
- renderer.close_group('line2d')
-
-
-
-class UnimplementedException(Exception):
- pass
-
-from matplotlib.artist import Artist
-
-class AttributeCopier(object):
- def __init__(self, ref_artist, klass=Artist):
- self._klass = klass
- self._ref_artist = ref_artist
- super(AttributeCopier, self).__init__()
-
- def set_ref_artist(self, artist):
- self._ref_artist = artist
-
- def get_ref_artist(self):
- raise RuntimeError("get_ref_artist must overridden")
- #return self._ref_artist
-
- def get_attribute_from_ref_artist(self, attr_name, default_value):
- get_attr_method_name = "get_"+attr_name
- c = getattr(self._klass, get_attr_method_name)(self)
- if c == 'auto':
- ref_artist = self.get_ref_artist()
- if ref_artist:
- attr = getattr(ref_artist,
- get_attr_method_name)()
- return attr
- else:
- return default_value
-
- return c
-
-
-from matplotlib.lines import Line2D
-
-class Ticks(Line2D, AttributeCopier):
- """
- Ticks are derived from Line2D, and note that ticks themselves
- are markers. Thus, you should use set_mec, set_mew, etc.
-
- To change the tick size (length), you need to use
- set_ticksize. To change the direction of the ticks (ticks are
- in opposite direction of ticklabels by default), use
- set_tick_out(False).
- """
-
- def __init__(self, ticksize, tick_out=False, **kwargs):
- self._ticksize = ticksize
- self.locs_angles_labels = []
-
- self.set_tick_out(tick_out)
-
- self._axis = kwargs.pop("axis", None)
- if self._axis is not None:
- if "color" not in kwargs:
- kwargs["color"] = "auto"
- if ("mew" not in kwargs) and ("markeredgewidth" not in kwargs):
- kwargs["markeredgewidth"] = "auto"
-
- Line2D.__init__(self, [0.], [0.], **kwargs)
- AttributeCopier.__init__(self, self._axis, klass=Line2D)
- self.set_snap(True)
-
- def get_ref_artist(self):
- #return self._ref_artist.get_ticklines()[0]
- return self._ref_artist.majorTicks[0].tick1line
-
- def get_color(self):
- return self.get_attribute_from_ref_artist("color", "k")
-
- def get_markeredgecolor(self):
- if self._markeredgecolor == 'auto':
- return self.get_color()
- else:
- return self._markeredgecolor
-
- def get_markeredgewidth(self):
- return self.get_attribute_from_ref_artist("markeredgewidth", .5)
-
-
- def set_tick_out(self, b):
- """
- set True if tick need to be rotated by 180 degree.
- """
- self._tick_out = b
-
- def get_tick_out(self):
- """
- Return True if the tick will be rotated by 180 degree.
- """
- return self._tick_out
-
-
- def set_ticksize(self, ticksize):
- """
- set length of the ticks in points.
- """
- self._ticksize = ticksize
-
-
- def get_ticksize(self):
- """
- Return length of the ticks in points.
- """
- return self._ticksize
-
- def set_locs_angles(self, locs_angles):
- self.locs_angles = locs_angles
-
-
- def _update(self, renderer):
- pass
-
- _tickvert_path = Path([[0., 0.], [1., 0.]])
-
- def draw(self, renderer):
- if not self.get_visible():
- return
-
- self._update(renderer) # update the tick
-
- size = self._ticksize
- path_trans = self.get_transform()
-
- # set gc : copied from lines.py
-# gc = renderer.new_gc()
-# self._set_gc_clip(gc)
-
-# gc.set_foreground(self.get_color())
-# gc.set_antialiased(self._antialiased)
-# gc.set_linewidth(self._linewidth)
-# gc.set_alpha(self._alpha)
-# if self.is_dashed():
-# cap = self._dashcapstyle
-# join = self._dashjoinstyle
-# else:
-# cap = self._solidcapstyle
-# join = self._solidjoinstyle
-# gc.set_joinstyle(join)
-# gc.set_capstyle(cap)
-# gc.set_snap(self.get_snap())
-
-
- gc = renderer.new_gc()
- gc.set_foreground(self.get_markeredgecolor())
- gc.set_linewidth(self.get_markeredgewidth())
- gc.set_alpha(self._alpha)
-
- offset = renderer.points_to_pixels(size)
- marker_scale = Affine2D().scale(offset, offset)
-
- if self.get_tick_out():
- add_angle = 180
- else:
- add_angle = 0
-
- marker_rotation = Affine2D()
- marker_transform = marker_scale + marker_rotation
-
- for loc, angle in self.locs_angles:
- marker_rotation.clear().rotate_deg(angle+add_angle)
- locs = path_trans.transform_non_affine(np.array([loc]))
- if self.axes and not self.axes.viewLim.contains(*locs[0]):
- continue
- renderer.draw_markers(gc, self._tickvert_path, marker_transform,
- Path(locs), path_trans.get_affine())
-
- gc.restore()
-
-
-class LabelBase(mtext.Text):
- """
- A base class for AxisLabel and TickLabels. The position and angle
- of the text are calculated by to offset_ref_angle,
- text_ref_angle, and offset_radius attributes.
- """
-
- def __init__(self, *kl, **kwargs):
- self.locs_angles_labels = []
- self._ref_angle = 0
- self._offset_radius = 0.
-
- super(LabelBase, self).__init__(*kl,
- **kwargs)
-
- self.set_rotation_mode("anchor")
- self._text_follow_ref_angle = True
- #self._offset_ref_angle = 0
-
- def _set_ref_angle(self, a):
- self._ref_angle = a
-
- def _get_ref_angle(self):
- return self._ref_angle
-
- def _get_text_ref_angle(self):
- if self._text_follow_ref_angle:
- return self._get_ref_angle()+90
- else:
- return 0 #self.get_ref_angle()
-
- def _get_offset_ref_angle(self):
- return self._get_ref_angle()
-
- def _set_offset_radius(self, offset_radius):
- self._offset_radius = offset_radius
-
- def _get_offset_radius(self):
- return self._offset_radius
-
-
- _get_opposite_direction = {"left":"right",
- "right":"left",
- "top":"bottom",
- "bottom":"top"}.__getitem__
-
-
- def _update(self, renderer):
- pass
-
- def draw(self, renderer):
- if not self.get_visible(): return
-
- self._update(renderer)
-
- # save original and adjust some properties
- tr = self.get_transform()
- angle_orig = self.get_rotation()
-
- offset_tr = Affine2D()
- self.set_transform(tr+offset_tr)
-
- text_ref_angle = self._get_text_ref_angle()
- offset_ref_angle = self._get_offset_ref_angle()
-
- theta = (offset_ref_angle)/180.*np.pi
- dd = self._get_offset_radius()
- dx, dy = dd * np.cos(theta), dd * np.sin(theta)
- offset_tr.translate(dx, dy)
- self.set_rotation(text_ref_angle+angle_orig)
- super(LabelBase, self).draw(renderer)
- offset_tr.clear()
-
-
- # restore original properties
- self.set_transform(tr)
- self.set_rotation(angle_orig)
-
-
- def get_window_extent(self, renderer):
-
- self._update(renderer)
-
- # save original and adjust some properties
- tr = self.get_transform()
- angle_orig = self.get_rotation()
-
- offset_tr = Affine2D()
- self.set_transform(tr+offset_tr)
-
- text_ref_angle = self._get_text_ref_angle()
- offset_ref_angle = self._get_offset_ref_angle()
-
- theta = (offset_ref_angle)/180.*np.pi
- dd = self._get_offset_radius()
- dx, dy = dd * np.cos(theta), dd * np.sin(theta)
- offset_tr.translate(dx, dy)
- self.set_rotation(text_ref_angle+angle_orig)
-
- bbox = super(LabelBase, self).get_window_extent(renderer).frozen()
-
- offset_tr.clear()
-
-
- # restore original properties
- self.set_transform(tr)
- self.set_rotation(angle_orig)
-
- return bbox
-
-
-class AxisLabel(LabelBase, AttributeCopier):
- """
- Axis Label. Derived from Text. The position of the text is updated
- in the fly, so changing text position has no effect. Otherwise, the
- properties can be changed as a normal Text.
-
- To change the pad between ticklabels and axis label, use set_pad.
- """
-
- def __init__(self, *kl, **kwargs):
-
- axis_direction = kwargs.pop("axis_direction", "bottom")
- self._axis = kwargs.pop("axis", None)
- #super(AxisLabel, self).__init__(*kl, **kwargs)
- LabelBase.__init__(self, *kl, **kwargs)
- AttributeCopier.__init__(self, self._axis, klass=LabelBase)
-
- self.set_axis_direction(axis_direction)
- self._pad = 5
- self._extra_pad = 0
-
- def set_pad(self, pad):
- """
- Set the pad in points. Note that the actual pad will be the
- sum of the internal pad and the external pad (that are set
- automatically by the AxisArtist), and it only set the internal
- pad
- """
- self._pad = pad
-
- def get_pad(self):
- """
- return pad in points. See set_pad for more details.
- """
- return self._pad
-
-
- def _set_external_pad(self, p):
- """
- Set external pad IN PIXELS. This is intended to be set by the
- AxisArtist, bot by user..
- """
- self._extra_pad = p
-
- def _get_external_pad(self):
- """
- Get external pad.
- """
- return self._extra_pad
-
-
- def get_ref_artist(self):
- return self._axis.get_label()
-
-
- def get_text(self):
- t = super(AxisLabel, self).get_text()
- if t == "__from_axes__":
- return self._axis.get_label().get_text()
- return self._text
-
- _default_alignments = dict(left=("bottom", "center"),
- right=("top", "center"),
- bottom=("top", "center"),
- top=("bottom", "center"))
-
-
-
- def set_default_alignment(self, d):
- if d not in ["left", "right", "top", "bottom"]:
- raise ValueError('direction must be on of "left", "right", "top", "bottom"')
-
- va, ha = self._default_alignments[d]
- self.set_va(va)
- self.set_ha(ha)
-
-
- _default_angles = dict(left=180,
- right=0,
- bottom=0,
- top=180)
-
-
- def set_default_angle(self, d):
- if d not in ["left", "right", "top", "bottom"]:
- raise ValueError('direction must be on of "left", "right", "top", "bottom"')
-
- self.set_rotation(self._default_angles[d])
-
-
- def set_axis_direction(self, d):
- """
- Adjust the text angle and text alignment of axis label
- according to the matplotlib convention.
-
-
- ===================== ========== ========= ========== ==========
- property left bottom right top
- ===================== ========== ========= ========== ==========
- axislabel angle 180 0 0 180
- axislabel va center top center bottom
- axislabel ha right center right center
- ===================== ========== ========= ========== ==========
-
- Note that the text angles are actually relative to (90 + angle
- of the direction to the ticklabel), which gives 0 for bottom
- axis.
-
- """
- if d not in ["left", "right", "top", "bottom"]:
- raise ValueError('direction must be on of "left", "right", "top", "bottom"')
-
- self.set_default_alignment(d)
- self.set_default_angle(d)
-
- def get_color(self):
- return self.get_attribute_from_ref_artist("color", "k")
-
- def draw(self, renderer):
- if not self.get_visible():
- return
-
- pad = renderer.points_to_pixels(self.get_pad())
- r = self._get_external_pad() + pad
- self._set_offset_radius(r)
-
- super(AxisLabel, self).draw(renderer)
-
-
- def get_window_extent(self, renderer):
-
- if not self.get_visible():
- return
-
- pad = renderer.points_to_pixels(self.get_pad())
- r = self._get_external_pad() + pad
- self._set_offset_radius(r)
-
- bb = super(AxisLabel, self).get_window_extent(renderer)
-
- return bb
-
-
-class TickLabels(AxisLabel, AttributeCopier): # mtext.Text
- """
- Tick Labels. While derived from Text, this single artist draws all
- ticklabels. As in AxisLabel, the position of the text is updated
- in the fly, so changing text position has no effect. Otherwise,
- the properties can be changed as a normal Text. Unlike the
- ticklabels of the mainline matplotlib, properties of single
- ticklabel alone cannot modified.
-
- To change the pad between ticks and ticklabels, use set_pad.
- """
-
- def __init__(self, **kwargs):
-
- axis_direction = kwargs.pop("axis_direction", "bottom")
- AxisLabel.__init__(self, **kwargs)
- self.set_axis_direction(axis_direction)
- #self._axis_direction = axis_direction
- self._axislabel_pad = 0
- #self._extra_pad = 0
-
-
- # attribute copier
- def get_ref_artist(self):
- return self._axis.get_ticklabels()[0]
-
- def set_axis_direction(self, label_direction):
- """
- Adjust the text angle and text alignment of ticklabels
- according to the matplotlib convention.
-
- The *label_direction* must be one of [left, right, bottom,
- top].
-
- ===================== ========== ========= ========== ==========
- property left bottom right top
- ===================== ========== ========= ========== ==========
- ticklabels angle 90 0 -90 180
- ticklabel va center baseline center baseline
- ticklabel ha right center right center
- ===================== ========== ========= ========== ==========
-
-
- Note that the text angles are actually relative to (90 + angle
- of the direction to the ticklabel), which gives 0 for bottom
- axis.
-
- """
-
- if label_direction not in ["left", "right", "top", "bottom"]:
- raise ValueError('direction must be one of "left", "right", "top", "bottom"')
-
- self._axis_direction = label_direction
- self.set_default_alignment(label_direction)
- self.set_default_angle(label_direction)
-
-
- def invert_axis_direction(self):
- label_direction = self._get_opposite_direction(self._axis_direction)
- self.set_axis_direction(label_direction)
-
- def _get_ticklabels_offsets(self, renderer, label_direction):
- """
- Calculates the offsets of the ticklabels from the tick and
- their total heights. The offset only takes account the offset
- due to the vertical alignment of the ticklabels, i.e.,if axis
- direction is bottom and va is ;top', it will return 0. if va
- is 'baseline', it will return (height-descent).
- """
- whd_list = self.get_texts_widths_heights_descents(renderer)
-
- if not whd_list:
- return 0, 0
-
- r = 0
- va, ha = self.get_va(), self.get_ha()
-
- if label_direction == "left":
- pad = max(w for w, h, d in whd_list)
- if ha == "left":
- r = pad
- elif ha == "center":
- r = .5 * pad
- elif label_direction == "right":
- pad = max(w for w, h, d in whd_list)
- if ha == "right":
- r = pad
- elif ha == "center":
- r = .5 * pad
- elif label_direction == "bottom":
- pad = max(h for w, h, d in whd_list)
- if va == "bottom":
- r = pad
- elif va == "center":
- r =.5 * pad
- elif va == "baseline":
- max_ascent = max(h - d for w, h, d in whd_list)
- max_descent = max(d for w, h, d in whd_list)
- r = max_ascent
- pad = max_ascent + max_descent
- elif label_direction == "top":
- pad = max(h for w, h, d in whd_list)
- if va == "top":
- r = pad
- elif va == "center":
- r =.5 * pad
- elif va == "baseline":
- max_ascent = max(h - d for w, h, d in whd_list)
- max_descent = max(d for w, h, d in whd_list)
- r = max_descent
- pad = max_ascent + max_descent
-
- #tick_pad = renderer.points_to_pixels(self.get_pad())
-
- # r : offset
-
- # pad : total height of the ticklabels. This will be used to
- # calculate the pad for the axislabel.
- return r, pad
-
-
-
- _default_alignments = dict(left=("center", "right"),
- right=("center", "left"),
- bottom=("baseline", "center"),
- top=("baseline", "center"))
-
-
-
- # set_default_alignments(self, d)
-
- _default_angles = dict(left=90,
- right=-90,
- bottom=0,
- top=180)
-
-
- def draw(self, renderer):
- if not self.get_visible():
- self._axislabel_pad = self._get_external_pad()
- return
-
- r, total_width = self._get_ticklabels_offsets(renderer,
- self._axis_direction)
-
- #self._set_external_pad(r+self._get_external_pad())
- pad = self._get_external_pad() + \
- renderer.points_to_pixels(self.get_pad())
- self._set_offset_radius(r+pad)
-
- #self._set_offset_radius(r)
-
- for (x, y), a, l in self._locs_angles_labels:
- if not l.strip(): continue
- self._set_ref_angle(a) #+ add_angle
- self.set_x(x)
- self.set_y(y)
- self.set_text(l)
- LabelBase.draw(self, renderer)
-
- self._axislabel_pad = total_width \
- + pad # the value saved will be used to draw axislabel.
-
-
- def set_locs_angles_labels(self, locs_angles_labels):
- self._locs_angles_labels = locs_angles_labels
-
- def get_window_extents(self, renderer):
-
- if not self.get_visible():
- self._axislabel_pad = self._get_external_pad()
- return []
-
- bboxes = []
-
- r, total_width = self._get_ticklabels_offsets(renderer,
- self._axis_direction)
-
- pad = self._get_external_pad() + \
- renderer.points_to_pixels(self.get_pad())
- self._set_offset_radius(r+pad)
-
-
- for (x, y), a, l in self._locs_angles_labels:
- self._set_ref_angle(a) #+ add_angle
- self.set_x(x)
- self.set_y(y)
- self.set_text(l)
- bb = LabelBase.get_window_extent(self, renderer)
- bboxes.append(bb)
-
- self._axislabel_pad = total_width \
- + pad # the value saved will be used to draw axislabel.
-
- return bboxes
-
-
- def get_texts_widths_heights_descents(self, renderer):
- """
- return a list of width, height, descent for ticklabels.
- """
- whd_list = []
- for (x, y), a, l in self._locs_angles_labels:
- if not l.strip(): continue
- clean_line, ismath = self.is_math_text(l)
- whd = renderer.get_text_width_height_descent(
- clean_line, self._fontproperties, ismath=ismath)
- whd_list.append(whd)
-
- return whd_list
-
-
-class GridlinesCollection(LineCollection):
- def __init__(self, *kl, **kwargs):
- """
- *which* : "major" or "minor"
- *axis* : "both", "x" or "y"
- """
- self._which = kwargs.pop("which", "major")
- self._axis = kwargs.pop("axis", "both")
- super(GridlinesCollection, self).__init__(*kl, **kwargs)
- self.set_grid_helper(None)
-
- def set_which(self, which):
- self._which = which
-
- def set_axis(self, axis):
- self._axis = axis
-
- def set_grid_helper(self, grid_helper):
- self._grid_helper = grid_helper
-
- def draw(self, renderer):
- if self._grid_helper is not None:
- self._grid_helper.update_lim(self.axes)
- gl = self._grid_helper.get_gridlines(self._which, self._axis)
- if gl:
- self.set_segments([np.transpose(l) for l in gl])
- else:
- self.set_segments([])
- super(GridlinesCollection, self).draw(renderer)
-
-
-
-
-class AxisArtist(martist.Artist):
- """
- An artist which draws axis (a line along which the n-th axes coord
- is constant) line, ticks, ticklabels, and axis label.
- """
-
- ZORDER=2.5
-
- @property
- def LABELPAD(self):
- return self.label.get_pad()
-
- @LABELPAD.setter
- def LABELPAD(self, v):
- return self.label.set_pad(v)
-
- def __init__(self, axes,
- helper,
- offset=None,
- axis_direction="bottom",
- **kw):
- """
- *axes* : axes
- *helper* : an AxisArtistHelper instance.
- """
- #axes is also used to follow the axis attribute (tick color, etc).
-
- super(AxisArtist, self).__init__(**kw)
-
- self.axes = axes
-
- self._axis_artist_helper = helper
-
- if offset is None:
- offset = (0, 0)
- self.dpi_transform = Affine2D()
- self.offset_transform = ScaledTranslation(offset[0], offset[1],
- self.dpi_transform)
-
- self._label_visible = True
- self._majortick_visible = True
- self._majorticklabel_visible = True
- self._minortick_visible = True
- self._minorticklabel_visible = True
-
-
- #if self._axis_artist_helper._loc in ["left", "right"]:
- if axis_direction in ["left", "right"]:
- axis_name = "ytick"
- self.axis = axes.yaxis
- else:
- axis_name = "xtick"
- self.axis = axes.xaxis
-
-
- self._axisline_style = None
-
-
- self._axis_direction = axis_direction
-
-
- self._init_line()
- self._init_ticks(axis_name, **kw)
- self._init_offsetText(axis_direction)
- self._init_label()
-
- self.set_zorder(self.ZORDER)
-
- self._rotate_label_along_line = False
-
- # axis direction
- self._tick_add_angle = 180.
- self._ticklabel_add_angle = 0.
- self._axislabel_add_angle = 0.
- self.set_axis_direction(axis_direction)
-
-
- # axis direction
-
- def set_axis_direction(self, axis_direction):
- """
- Adjust the direction, text angle, text alignment of
- ticklabels, labels following the matplotlib convention for
- the rectangle axes.
-
- The *axis_direction* must be one of [left, right, bottom,
- top].
-
- ===================== ========== ========= ========== ==========
- property left bottom right top
- ===================== ========== ========= ========== ==========
- ticklabels location "-" "+" "+" "-"
- axislabel location "-" "+" "+" "-"
- ticklabels angle 90 0 -90 180
- ticklabel va center baseline center baseline
- ticklabel ha right center right center
- axislabel angle 180 0 0 180
- axislabel va center top center bottom
- axislabel ha right center right center
- ===================== ========== ========= ========== ==========
-
-
- Note that the direction "+" and "-" are relative to the direction of
- the increasing coordinate. Also, the text angles are actually
- relative to (90 + angle of the direction to the ticklabel),
- which gives 0 for bottom axis.
-
- """
-
- if axis_direction not in ["left", "right", "top", "bottom"]:
- raise ValueError('direction must be on of "left", "right", "top", "bottom"')
- self._axis_direction = axis_direction
- if axis_direction in ["left", "top"]:
- #self._set_tick_direction("+")
- self.set_ticklabel_direction("-")
- self.set_axislabel_direction("-")
- else:
- #self._set_tick_direction("-")
- self.set_ticklabel_direction("+")
- self.set_axislabel_direction("+")
-
- self.major_ticklabels.set_axis_direction(axis_direction)
- self.label.set_axis_direction(axis_direction)
-
- # def _set_tick_direction(self, d):
- # if d not in ["+", "-"]:
- # raise ValueError('direction must be on of "in", "out"')
-
- # if d == "+":
- # self._tick_add_angle = 0 #get_helper()._extremes=0, 10
- # else:
- # self._tick_add_angle = 180 #get_helper()._extremes=0, 10
-
- def set_ticklabel_direction(self, tick_direction):
- """
- Adjust the direction of the ticklabel.
-
- ACCEPTS: [ "+" | "-" ]
-
- Note that the label_direction '+' and '-' are relative to the
- direction of the increasing coordinate.
- """
-
- if tick_direction not in ["+", "-"]:
- raise ValueError('direction must be one of "+", "-"')
-
- if tick_direction == "-":
- self._ticklabel_add_angle = 180
- else:
- self._ticklabel_add_angle = 0
-
- def invert_ticklabel_direction(self):
- self._ticklabel_add_angle = (self._ticklabel_add_angle + 180) % 360
- self.major_ticklabels.invert_axis_direction()
- self.minor_ticklabels.invert_axis_direction()
-
- # def invert_ticks_direction(self):
- # self.major_ticks.set_tick_out(not self.major_ticks.get_tick_out())
- # self.minor_ticks.set_tick_out(not self.minor_ticks.get_tick_out())
-
- def set_axislabel_direction(self, label_direction):
- """
- Adjust the direction of the axislabel.
-
- ACCEPTS: [ "+" | "-" ]
-
- Note that the label_direction '+' and '-' are relative to the
- direction of the increasing coordinate.
- """
- if label_direction not in ["+", "-"]:
- raise ValueError('direction must be one of "+", "-"')
-
- if label_direction == "-":
- self._axislabel_add_angle = 180
- else:
- self._axislabel_add_angle = 0
-
-
-
- def get_transform(self):
- return self.axes.transAxes + self.offset_transform
-
- def get_helper(self):
- """
- Return axis artist helper instance.
- """
- return self._axis_artist_helper
-
-
- def set_axisline_style(self, axisline_style=None, **kw):
- """
- Set the axisline style.
-
- *axisline_style* can be a string with axisline style name with optional
- comma-separated attributes. Alternatively, the attrs can
- be provided as keywords.
-
- set_arrowstyle("->,size=1.5")
- set_arrowstyle("->", size=1.5)
-
- Old attrs simply are forgotten.
-
- Without argument (or with arrowstyle=None), return
- available styles as a list of strings.
- """
-
- if axisline_style==None:
- return AxislineStyle.pprint_styles()
-
- if isinstance(axisline_style, AxislineStyle._Base):
- self._axisline_style = axisline_style
- else:
- self._axisline_style = AxislineStyle(axisline_style, **kw)
-
-
- self._init_line()
-
-
- def get_axisline_style(self):
- """
- return the current axisline style.
- """
- return self._axisline_style
-
- def _init_line(self):
- """
- Initialize the *line* artist that is responsible to draw the axis line.
- """
- tran = self._axis_artist_helper.get_line_transform(self.axes) \
- + self.offset_transform
-
- axisline_style = self.get_axisline_style()
- if axisline_style is None:
- self.line = BezierPath(self._axis_artist_helper.get_line(self.axes),
- color=rcParams['axes.edgecolor'],
- linewidth=rcParams['axes.linewidth'],
- transform=tran)
- else:
- self.line = axisline_style(self, transform=tran)
-
- def _draw_line(self, renderer):
- self.line.set_path(self._axis_artist_helper.get_line(self.axes))
- if self.get_axisline_style() is not None:
- self.line.set_line_mutation_scale(self.major_ticklabels.get_size())
- self.line.draw(renderer)
-
-
- def _init_ticks(self, axis_name, **kw):
-
- trans=self._axis_artist_helper.get_tick_transform(self.axes) \
- + self.offset_transform
-
-
- major_tick_size = kw.get("major_tick_size",
- rcParams['%s.major.size'%axis_name])
- major_tick_pad = kw.get("major_tick_pad",
- rcParams['%s.major.pad'%axis_name])
- minor_tick_size = kw.get("minor_tick_size",
- rcParams['%s.minor.size'%axis_name])
- minor_tick_pad = kw.get("minor_tick_pad",
- rcParams['%s.minor.pad'%axis_name])
-
- self.major_ticks = Ticks(major_tick_size,
- axis=self.axis,
- transform=trans)
- self.minor_ticks = Ticks(minor_tick_size,
- axis=self.axis,
- transform=trans)
-
- if axis_name == "xaxis":
- size = rcParams['xtick.labelsize']
- else:
- size = rcParams['ytick.labelsize']
-
-
- fontprops = font_manager.FontProperties(size=size)
-
- self.major_ticklabels = TickLabels(size=size, axis=self.axis,
- axis_direction=self._axis_direction)
- self.minor_ticklabels = TickLabels(size=size, axis=self.axis,
- axis_direction=self._axis_direction)
-
-
- self.major_ticklabels.set(figure = self.axes.figure,
- transform=trans,
- fontproperties=fontprops)
- self.major_ticklabels.set_pad(major_tick_pad)
-
- self.minor_ticklabels.set(figure = self.axes.figure,
- transform=trans,
- fontproperties=fontprops)
- self.minor_ticklabels.set_pad(minor_tick_pad)
-
-
-
- def _get_tick_info(self, tick_iter):
- """
- return ticks_loc_angle, ticklabels_loc_angle_label
-
- ticks_loc_angle : list of locs and angles for ticks
- ticklabels_loc_angle_label : list of locs, angles and labels for tickslabels
- """
- ticks_loc_angle = []
- ticklabels_loc_angle_label = []
-
- tick_add_angle = self._tick_add_angle
- ticklabel_add_angle = self._ticklabel_add_angle
-
- for loc, angle_normal, angle_tangent, label in tick_iter:
- angle_label = angle_tangent - 90
- angle_label += ticklabel_add_angle
-
- if np.cos((angle_label - angle_normal)/180.*np.pi) < 0.:
- angle_tick = angle_normal
- else:
- angle_tick = angle_normal + 180
-
- ticks_loc_angle.append([loc, angle_tick])
- ticklabels_loc_angle_label.append([loc, angle_label, label])
-
- return ticks_loc_angle, ticklabels_loc_angle_label
-
-
- def _update_ticks(self, renderer):
-
-
- # set extra pad for major and minor ticklabels:
- # use ticksize of majorticks even for minor ticks. not clear what is best.
-
- dpi_cor = renderer.points_to_pixels(1.)
- if self.major_ticks.get_visible() and self.major_ticks.get_tick_out():
- self.major_ticklabels._set_external_pad(self.major_ticks._ticksize*dpi_cor)
- self.minor_ticklabels._set_external_pad(self.major_ticks._ticksize*dpi_cor)
- else:
- self.major_ticklabels._set_external_pad(0)
- self.minor_ticklabels._set_external_pad(0)
-
-
- majortick_iter, minortick_iter = \
- self._axis_artist_helper.get_tick_iterators(self.axes)
-
- tick_loc_angle, ticklabel_loc_angle_label \
- = self._get_tick_info(majortick_iter)
-
- self.major_ticks.set_locs_angles(tick_loc_angle)
- self.major_ticklabels.set_locs_angles_labels(ticklabel_loc_angle_label)
-
- #self.major_ticks.draw(renderer)
- #self.major_ticklabels.draw(renderer)
-
-
- # minor ticks
- tick_loc_angle, ticklabel_loc_angle_label \
- = self._get_tick_info(minortick_iter)
-
- self.minor_ticks.set_locs_angles(tick_loc_angle)
- self.minor_ticklabels.set_locs_angles_labels(ticklabel_loc_angle_label)
-
- #self.minor_ticks.draw(renderer)
- #self.minor_ticklabels.draw(renderer)
-
-
- #if (self.major_ticklabels.get_visible() or self.minor_ticklabels.get_visible()):
- # self._draw_offsetText(renderer)
-
- return self.major_ticklabels.get_window_extents(renderer)
-
-
- def _draw_ticks(self, renderer):
-
- extents = self._update_ticks(renderer)
-
- self.major_ticks.draw(renderer)
- self.major_ticklabels.draw(renderer)
-
- self.minor_ticks.draw(renderer)
- self.minor_ticklabels.draw(renderer)
-
-
- if (self.major_ticklabels.get_visible() or self.minor_ticklabels.get_visible()):
- self._draw_offsetText(renderer)
-
- return extents
-
- def _draw_ticks2(self, renderer):
-
-
- # set extra pad for major and minor ticklabels:
- # use ticksize of majorticks even for minor ticks. not clear what is best.
-
- dpi_cor = renderer.points_to_pixels(1.)
- if self.major_ticks.get_visible() and self.major_ticks.get_tick_out():
- self.major_ticklabels._set_external_pad(self.major_ticks._ticksize*dpi_cor)
- self.minor_ticklabels._set_external_pad(self.major_ticks._ticksize*dpi_cor)
- else:
- self.major_ticklabels._set_external_pad(0)
- self.minor_ticklabels._set_external_pad(0)
-
-
- majortick_iter, minortick_iter = \
- self._axis_artist_helper.get_tick_iterators(self.axes)
-
- tick_loc_angle, ticklabel_loc_angle_label \
- = self._get_tick_info(majortick_iter)
-
- self.major_ticks.set_locs_angles(tick_loc_angle)
- self.major_ticklabels.set_locs_angles_labels(ticklabel_loc_angle_label)
-
- self.major_ticks.draw(renderer)
- self.major_ticklabels.draw(renderer)
-
-
- # minor ticks
- tick_loc_angle, ticklabel_loc_angle_label \
- = self._get_tick_info(minortick_iter)
-
- self.minor_ticks.set_locs_angles(tick_loc_angle)
- self.minor_ticklabels.set_locs_angles_labels(ticklabel_loc_angle_label)
-
- self.minor_ticks.draw(renderer)
- self.minor_ticklabels.draw(renderer)
-
-
- if (self.major_ticklabels.get_visible() or self.minor_ticklabels.get_visible()):
- self._draw_offsetText(renderer)
-
- return self.major_ticklabels.get_window_extents(renderer)
-
-
-
-
- _offsetText_pos = dict(left=(0, 1, "bottom", "right"),
- right=(1, 1, "bottom", "left"),
- bottom=(1, 0, "top", "right"),
- top=(1, 1, "bottom", "right"))
-
- def _init_offsetText(self, direction):
-
- x,y,va,ha = self._offsetText_pos[direction]
-
- self.offsetText = mtext.Annotation("",
- xy=(x,y), xycoords="axes fraction",
- xytext=(0,0), textcoords="offset points",
- #fontproperties = fp,
- color = rcParams['xtick.color'],
- verticalalignment=va,
- horizontalalignment=ha,
- )
- self.offsetText.set_transform(IdentityTransform())
- self.axes._set_artist_props(self.offsetText)
-
-
- def _update_offsetText(self):
- self.offsetText.set_text( self.axis.major.formatter.get_offset() )
- self.offsetText.set_size(self.major_ticklabels.get_size())
- offset = self.major_ticklabels.get_pad() + self.major_ticklabels.get_size() + 2.
- self.offsetText.xyann= (0, offset)
-
-
- def _draw_offsetText(self, renderer):
- self._update_offsetText()
- self.offsetText.draw(renderer)
-
-
-
- def _init_label(self, **kw):
- # x in axes coords, y in display coords (to be updated at draw
- # time by _update_label_positions)
-
- labelsize = kw.get("labelsize",
- rcParams['axes.labelsize'])
- #labelcolor = kw.get("labelcolor",
- # rcParams['axes.labelcolor'])
- fontprops = font_manager.FontProperties(
- size=labelsize,
- weight=rcParams['axes.labelweight'])
- textprops = dict(fontproperties = fontprops)
- #color = labelcolor)
-
- tr = self._axis_artist_helper.get_axislabel_transform(self.axes) \
- + self.offset_transform
-
- self.label = AxisLabel(0, 0, "__from_axes__",
- color = "auto", #rcParams['axes.labelcolor'],
- fontproperties=fontprops,
- axis=self.axis,
- transform=tr,
- axis_direction=self._axis_direction,
- )
-
- self.label.set_figure(self.axes.figure)
-
- labelpad = kw.get("labelpad", 5)
- self.label.set_pad(labelpad)
-
-
- def _update_label(self, renderer):
-
- if not self.label.get_visible():
- return
-
- fontprops = font_manager.FontProperties(
- size=rcParams['axes.labelsize'],
- weight=rcParams['axes.labelweight'])
-
- #pad_points = self.major_tick_pad
-
- #if abs(self._ticklabel_add_angle - self._axislabel_add_angle)%360 > 90:
- if self._ticklabel_add_angle != self._axislabel_add_angle:
- if (self.major_ticks.get_visible() and not self.major_ticks.get_tick_out()) \
- or \
- (self.minor_ticks.get_visible() and not self.major_ticks.get_tick_out()):
- axislabel_pad = self.major_ticks._ticksize
- else:
- axislabel_pad = 0
- else:
- axislabel_pad = max(self.major_ticklabels._axislabel_pad,
- self.minor_ticklabels._axislabel_pad)
-
-
- #label_offset = axislabel_pad + self.LABELPAD
-
- #self.label._set_offset_radius(label_offset)
- self.label._set_external_pad(axislabel_pad)
-
- xy, angle_tangent = self._axis_artist_helper.get_axislabel_pos_angle(self.axes)
- if xy is None: return
-
- angle_label = angle_tangent - 90
-
-
- x, y = xy
- self.label._set_ref_angle(angle_label+self._axislabel_add_angle)
- self.label.set(x=x, y=y)
-
-
- def _draw_label(self, renderer):
- self._update_label(renderer)
- self.label.draw(renderer)
-
- def _draw_label2(self, renderer):
-
- if not self.label.get_visible():
- return
-
- fontprops = font_manager.FontProperties(
- size=rcParams['axes.labelsize'],
- weight=rcParams['axes.labelweight'])
-
- #pad_points = self.major_tick_pad
-
- #if abs(self._ticklabel_add_angle - self._axislabel_add_angle)%360 > 90:
- if self._ticklabel_add_angle != self._axislabel_add_angle:
- if (self.major_ticks.get_visible() and not self.major_ticks.get_tick_out()) \
- or \
- (self.minor_ticks.get_visible() and not self.major_ticks.get_tick_out()):
- axislabel_pad = self.major_ticks._ticksize
- else:
- axislabel_pad = 0
- else:
- axislabel_pad = max(self.major_ticklabels._axislabel_pad,
- self.minor_ticklabels._axislabel_pad)
-
- #label_offset = axislabel_pad + self.LABELPAD
-
- #self.label._set_offset_radius(label_offset)
- self.label._set_external_pad(axislabel_pad)
-
- xy, angle_tangent = self._axis_artist_helper.get_axislabel_pos_angle(self.axes)
- if xy is None: return
-
- angle_label = angle_tangent - 90
-
- x, y = xy
- self.label._set_ref_angle(angle_label+self._axislabel_add_angle)
- self.label.set(x=x, y=y)
- self.label.draw(renderer)
-
-
-
- def set_label(self, s):
- self.label.set_text(s)
-
-
-
- def get_tightbbox(self, renderer):
- if not self.get_visible(): return
-
- self._axis_artist_helper.update_lim(self.axes)
-
- dpi_cor = renderer.points_to_pixels(1.)
- self.dpi_transform.clear().scale(dpi_cor, dpi_cor)
-
-
- bb = []
-
- self._update_ticks(renderer)
-
- #if self.major_ticklabels.get_visible():
- bb.extend(self.major_ticklabels.get_window_extents(renderer))
- #if self.minor_ticklabels.get_visible():
- bb.extend(self.minor_ticklabels.get_window_extents(renderer))
-
-
- self._update_label(renderer)
-
- #if self.label.get_visible():
- bb.append(self.label.get_window_extent(renderer))
- bb.append(self.offsetText.get_window_extent(renderer))
-
- bb = [b for b in bb if b and (b.width!=0 or b.height!=0)]
- if bb:
- _bbox = Bbox.union(bb)
- return _bbox
- else:
- return None
-
- #self._draw_line(renderer)
-
- #self._draw_ticks(renderer)
-
- #self._draw_offsetText(renderer)
- #self._draw_label(renderer)
-
-
-
- @allow_rasterization
- def draw(self, renderer):
- 'Draw the axis lines, tick lines and labels'
-
- if not self.get_visible(): return
-
- renderer.open_group(__name__)
-
- self._axis_artist_helper.update_lim(self.axes)
-
- dpi_cor = renderer.points_to_pixels(1.)
- self.dpi_transform.clear().scale(dpi_cor, dpi_cor)
-
-
- self._draw_ticks(renderer)
-
- self._draw_line(renderer)
-
- #self._draw_offsetText(renderer)
- self._draw_label(renderer)
-
- renderer.close_group(__name__)
-
- #def get_ticklabel_extents(self, renderer):
- # pass
-
- def toggle(self, all=None, ticks=None, ticklabels=None, label=None):
- """
- Toggle visibility of ticks, ticklabels, and (axis) label.
- To turn all off, ::
-
- axis.toggle(all=False)
-
- To turn all off but ticks on ::
-
- axis.toggle(all=False, ticks=True)
-
- To turn all on but (axis) label off ::
-
- axis.toggle(all=True, label=False))
-
- """
- if all:
- _ticks, _ticklabels, _label = True, True, True
- elif all is not None:
- _ticks, _ticklabels, _label = False, False, False
- else:
- _ticks, _ticklabels, _label = None, None, None
-
- if ticks is not None:
- _ticks = ticks
- if ticklabels is not None:
- _ticklabels = ticklabels
- if label is not None:
- _label = label
-
- if _ticks is not None:
- self.major_ticks.set_visible(_ticks)
- self.minor_ticks.set_visible(_ticks)
- if _ticklabels is not None:
- self.major_ticklabels.set_visible(_ticklabels)
- self.minor_ticklabels.set_visible(_ticklabels)
- if _label is not None:
- self.label.set_visible(_label)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axisline_style.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axisline_style.py
deleted file mode 100644
index 876f5fe189..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axisline_style.py
+++ /dev/null
@@ -1,168 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from matplotlib.patches import _Style, FancyArrowPatch
-from matplotlib.transforms import IdentityTransform
-from matplotlib.path import Path
-import numpy as np
-
-class _FancyAxislineStyle(object):
- class SimpleArrow(FancyArrowPatch):
- """
- The artist class that will be returned for SimpleArrow style.
- """
- _ARROW_STYLE = "->"
-
- def __init__(self, axis_artist, line_path, transform,
- line_mutation_scale):
- self._axis_artist = axis_artist
- self._line_transform = transform
- self._line_path = line_path
- self._line_mutation_scale = line_mutation_scale
-
- FancyArrowPatch.__init__(self,
- path=self._line_path,
- arrowstyle=self._ARROW_STYLE,
- arrow_transmuter=None,
- patchA=None,
- patchB=None,
- shrinkA=0.,
- shrinkB=0.,
- mutation_scale=line_mutation_scale,
- mutation_aspect=None,
- transform=IdentityTransform(),
- )
-
- def set_line_mutation_scale(self, scale):
- self.set_mutation_scale(scale*self._line_mutation_scale)
-
- def _extend_path(self, path, mutation_size=10):
- """
- Extend the path to make a room for drawing arrow.
- """
- from matplotlib.bezier import get_cos_sin
-
- x0, y0 = path.vertices[-2]
- x1, y1 = path.vertices[-1]
- cost, sint = get_cos_sin(x0, y0, x1, y1)
-
- d = mutation_size * 1.
- x2, y2 = x1 + cost*d, y1+sint*d
-
- if path.codes is None:
- _path = Path(np.concatenate([path.vertices, [[x2, y2]]]))
- else:
- _path = Path(np.concatenate([path.vertices, [[x2, y2]]]),
- np.concatenate([path.codes, [Path.LINETO]]))
-
- return _path
-
- def set_path(self, path):
- self._line_path = path
-
- def draw(self, renderer):
- """
- Draw the axis line.
- 1) transform the path to the display coordinate.
- 2) extend the path to make a room for arrow
- 3) update the path of the FancyArrowPatch.
- 4) draw
- """
- path_in_disp = self._line_transform.transform_path(self._line_path)
- mutation_size = self.get_mutation_scale() #line_mutation_scale()
- extented_path = self._extend_path(path_in_disp,
- mutation_size=mutation_size)
-
- self._path_original = extented_path
- FancyArrowPatch.draw(self, renderer)
-
- class FilledArrow(SimpleArrow):
- """
- The artist class that will be returned for SimpleArrow style.
- """
- _ARROW_STYLE = "-|>"
-
-
-class AxislineStyle(_Style):
- """
- :class:`AxislineStyle` is a container class which defines style classes
- for AxisArtists.
-
- An instance of any axisline style class is an callable object,
- whose call signature is ::
-
- __call__(self, axis_artist, path, transform)
-
- When called, this should return a mpl artist with following
- methods implemented. ::
-
- def set_path(self, path):
- # set the path for axisline.
-
- def set_line_mutation_scale(self, scale):
- # set the scale
-
- def draw(self, renderer):
- # draw
-
-
- """
-
- _style_list = {}
-
-
- class _Base(object):
- # The derived classes are required to be able to be initialized
- # w/o arguments, i.e., all its argument (except self) must have
- # the default values.
-
- def __init__(self):
- """
- initialization.
- """
- super(AxislineStyle._Base, self).__init__()
-
-
-
-
- def __call__(self, axis_artist, transform):
- """
- Given the AxisArtist instance, and transform for the path
- (set_path method), return the mpl artist for drawing the axis line.
- """
-
- return self.new_line(axis_artist, transform)
-
-
- class SimpleArrow(_Base):
- """
- A simple arrow.
- """
-
- ArrowAxisClass = _FancyAxislineStyle.SimpleArrow
-
- def __init__(self, size=1):
- """
- *size*
- size of the arrow as a fraction of the ticklabel size.
- """
-
- self.size = size
- super(AxislineStyle.SimpleArrow, self).__init__()
-
- def new_line(self, axis_artist, transform):
-
- linepath = Path([(0,0), (0, 1)])
- axisline = self.ArrowAxisClass(axis_artist, linepath, transform,
- line_mutation_scale=self.size)
- return axisline
-
-
- _style_list["->"] = SimpleArrow
-
- class FilledArrow(SimpleArrow):
- ArrowAxisClass = _FancyAxislineStyle.FilledArrow
-
- _style_list["-|>"] = FilledArrow
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axislines.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axislines.py
deleted file mode 100644
index 6182608cc5..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/axislines.py
+++ /dev/null
@@ -1,828 +0,0 @@
-"""
-Axislines includes modified implementation of the Axes class. The
-biggest difference is that the artists responsible for drawing the axis spine,
-ticks, ticklabels and axis labels are separated out from mpl's Axis
-class. Originally, this change was motivated to support curvilinear
-grid. Here are a few reasons that I came up with a new axes class:
-
-
- * "top" and "bottom" x-axis (or "left" and "right" y-axis) can have
- different ticks (tick locations and labels). This is not possible
- with the current mpl, although some twin axes trick can help.
-
- * Curvilinear grid.
-
- * angled ticks.
-
-In the new axes class, xaxis and yaxis is set to not visible by
-default, and new set of artist (AxisArtist) are defined to draw axis
-line, ticks, ticklabels and axis label. Axes.axis attribute serves as
-a dictionary of these artists, i.e., ax.axis["left"] is a AxisArtist
-instance responsible to draw left y-axis. The default Axes.axis contains
-"bottom", "left", "top" and "right".
-
-AxisArtist can be considered as a container artist and
-has following children artists which will draw ticks, labels, etc.
-
- * line
- * major_ticks, major_ticklabels
- * minor_ticks, minor_ticklabels
- * offsetText
- * label
-
-Note that these are separate artists from Axis class of the
-original mpl, thus most of tick-related command in the original mpl
-won't work, although some effort has made to work with. For example,
-color and markerwidth of the ax.axis["bottom"].major_ticks will follow
-those of Axes.xaxis unless explicitly specified.
-
-In addition to AxisArtist, the Axes will have *gridlines* attribute,
-which obviously draws grid lines. The gridlines needs to be separated
-from the axis as some gridlines can never pass any axis.
-
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import warnings
-
-import numpy as np
-
-from matplotlib import rcParams
-import matplotlib.artist as martist
-import matplotlib.axes as maxes
-from matplotlib.path import Path
-from matplotlib.transforms import Bbox
-from .axisline_style import AxislineStyle
-from .axis_artist import AxisArtist, GridlinesCollection
-
-
-class AxisArtistHelper(object):
- """
- AxisArtistHelper should define
- following method with given APIs. Note that the first axes argument
- will be axes attribute of the caller artist.::
-
-
- # LINE (spinal line?)
-
- def get_line(self, axes):
- # path : Path
- return path
-
- def get_line_transform(self, axes):
- # ...
- # trans : transform
- return trans
-
- # LABEL
-
- def get_label_pos(self, axes):
- # x, y : position
- return (x, y), trans
-
-
- def get_label_offset_transform(self, \
- axes,
- pad_points, fontprops, renderer,
- bboxes,
- ):
- # va : vertical alignment
- # ha : horizontal alignment
- # a : angle
- return trans, va, ha, a
-
- # TICK
-
- def get_tick_transform(self, axes):
- return trans
-
- def get_tick_iterators(self, axes):
- # iter : iterable object that yields (c, angle, l) where
- # c, angle, l is position, tick angle, and label
-
- return iter_major, iter_minor
-
-
- """
-
- class _Base(object):
- """
- Base class for axis helper.
- """
- def __init__(self):
- """
- """
- self.delta1, self.delta2 = 0.00001, 0.00001
-
- def update_lim(self, axes):
- pass
-
-
- class Fixed(_Base):
- """
- Helper class for a fixed (in the axes coordinate) axis.
- """
-
- _default_passthru_pt = dict(left=(0, 0),
- right=(1, 0),
- bottom=(0, 0),
- top=(0, 1))
-
- def __init__(self,
- loc, nth_coord=None,
- ):
- """
- nth_coord = along which coordinate value varies
- in 2d, nth_coord = 0 -> x axis, nth_coord = 1 -> y axis
- """
-
- self._loc = loc
-
- if loc not in ["left", "right", "bottom", "top"]:
- raise ValueError("%s" % loc)
-
- if nth_coord is None:
- if loc in ["left", "right"]:
- nth_coord = 1
- elif loc in ["bottom", "top"]:
- nth_coord = 0
-
- self.nth_coord = nth_coord
-
- super(AxisArtistHelper.Fixed, self).__init__()
-
- self.passthru_pt = self._default_passthru_pt[loc]
-
-
-
- _verts = np.array([[0., 0.],
- [1., 1.]])
- fixed_coord = 1-nth_coord
- _verts[:,fixed_coord] = self.passthru_pt[fixed_coord]
-
- # axis line in transAxes
- self._path = Path(_verts)
-
-
- def get_nth_coord(self):
- return self.nth_coord
-
- # LINE
-
- def get_line(self, axes):
- return self._path
-
- def get_line_transform(self, axes):
- return axes.transAxes
-
- # LABEL
-
- def get_axislabel_transform(self, axes):
- return axes.transAxes
-
- def get_axislabel_pos_angle(self, axes):
- """
- label reference position in transAxes.
-
- get_label_transform() returns a transform of (transAxes+offset)
- """
- loc = self._loc
- pos, angle_tangent = dict(left=((0., 0.5), 90),
- right=((1., 0.5), 90),
- bottom=((0.5, 0.), 0),
- top=((0.5, 1.), 0))[loc]
-
- return pos, angle_tangent
-
-
-
- # TICK
-
- def get_tick_transform(self, axes):
- trans_tick = [axes.get_xaxis_transform(),
- axes.get_yaxis_transform()][self.nth_coord]
-
- return trans_tick
-
-
- class Floating(_Base):
- def __init__(self, nth_coord,
- value):
-
- self.nth_coord = nth_coord
-
- self._value = value
-
- super(AxisArtistHelper.Floating,
- self).__init__()
-
-
- def get_nth_coord(self):
- return self.nth_coord
-
- def get_line(self, axes):
- raise RuntimeError("get_line method should be defined by the derived class")
-
-
-
-
-class AxisArtistHelperRectlinear(object):
-
- class Fixed(AxisArtistHelper.Fixed):
-
- def __init__(self, axes, loc, nth_coord=None):
- """
- nth_coord = along which coordinate value varies
- in 2d, nth_coord = 0 -> x axis, nth_coord = 1 -> y axis
- """
- super(AxisArtistHelperRectlinear.Fixed, self).__init__(
- loc, nth_coord)
- self.axis = [axes.xaxis, axes.yaxis][self.nth_coord]
-
- # TICK
-
- def get_tick_iterators(self, axes):
- """tick_loc, tick_angle, tick_label"""
-
- loc = self._loc
-
- if loc in ["bottom", "top"]:
- angle_normal, angle_tangent = 90, 0
- else:
- angle_normal, angle_tangent = 0, 90
-
- major = self.axis.major
- majorLocs = major.locator()
- major.formatter.set_locs(majorLocs)
- majorLabels = [major.formatter(val, i) for i, val in enumerate(majorLocs)]
-
- minor = self.axis.minor
- minorLocs = minor.locator()
- minor.formatter.set_locs(minorLocs)
- minorLabels = [minor.formatter(val, i) for i, val in enumerate(minorLocs)]
-
- trans_tick = self.get_tick_transform(axes)
-
- tr2ax = trans_tick + axes.transAxes.inverted()
-
- def _f(locs, labels):
- for x, l in zip(locs, labels):
-
- c = list(self.passthru_pt) # copy
- c[self.nth_coord] = x
-
- # check if the tick point is inside axes
- c2 = tr2ax.transform_point(c)
- #delta=0.00001
- if 0. -self.delta1<= c2[self.nth_coord] <= 1.+self.delta2:
- yield c, angle_normal, angle_tangent, l
-
- return _f(majorLocs, majorLabels), _f(minorLocs, minorLabels)
-
-
-
- class Floating(AxisArtistHelper.Floating):
- def __init__(self, axes, nth_coord,
- passingthrough_point, axis_direction="bottom"):
- super(AxisArtistHelperRectlinear.Floating, self).__init__(
- nth_coord, passingthrough_point)
- self._axis_direction = axis_direction
- self.axis = [axes.xaxis, axes.yaxis][self.nth_coord]
-
- def get_line(self, axes):
- _verts = np.array([[0., 0.],
- [1., 1.]])
-
- fixed_coord = 1-self.nth_coord
- trans_passingthrough_point = axes.transData + axes.transAxes.inverted()
- p = trans_passingthrough_point.transform_point([self._value,
- self._value])
- _verts[:,fixed_coord] = p[fixed_coord]
-
- return Path(_verts)
-
- def get_line_transform(self, axes):
- return axes.transAxes
-
- def get_axislabel_transform(self, axes):
- return axes.transAxes
-
- def get_axislabel_pos_angle(self, axes):
- """
- label reference position in transAxes.
-
- get_label_transform() returns a transform of (transAxes+offset)
- """
- loc = self._axis_direction
- #angle = dict(left=0,
- # right=0,
- # bottom=.5*np.pi,
- # top=.5*np.pi)[loc]
-
- if self.nth_coord == 0:
- angle = 0
- else:
- angle = 90
-
- _verts = [0.5, 0.5]
-
- fixed_coord = 1-self.nth_coord
- trans_passingthrough_point = axes.transData + axes.transAxes.inverted()
- p = trans_passingthrough_point.transform_point([self._value,
- self._value])
- _verts[fixed_coord] = p[fixed_coord]
- if not (0. <= _verts[fixed_coord] <= 1.):
- return None, None
- else:
- return _verts, angle
-
-
-
- def get_tick_transform(self, axes):
- return axes.transData
-
-
- def get_tick_iterators(self, axes):
- """tick_loc, tick_angle, tick_label"""
-
- loc = self._axis_direction
-
- if loc in ["bottom", "top"]:
- angle_normal, angle_tangent = 90, 0
- else:
- angle_normal, angle_tangent = 0, 90
-
- if self.nth_coord == 0:
- angle_normal, angle_tangent = 90, 0
- else:
- angle_normal, angle_tangent = 0, 90
-
- #angle = 90 - 90 * self.nth_coord
-
- major = self.axis.major
- majorLocs = major.locator()
- major.formatter.set_locs(majorLocs)
- majorLabels = [major.formatter(val, i) for i, val in enumerate(majorLocs)]
-
- minor = self.axis.minor
- minorLocs = minor.locator()
- minor.formatter.set_locs(minorLocs)
- minorLabels = [minor.formatter(val, i) for i, val in enumerate(minorLocs)]
-
- tr2ax = axes.transData + axes.transAxes.inverted()
-
- def _f(locs, labels):
- for x, l in zip(locs, labels):
-
- c = [self._value, self._value]
- c[self.nth_coord] = x
- c1, c2 = tr2ax.transform_point(c)
- if 0. <= c1 <= 1. and 0. <= c2 <= 1.:
- if 0. - self.delta1 <= [c1, c2][self.nth_coord] <= 1. + self.delta2:
- yield c, angle_normal, angle_tangent, l
-
- return _f(majorLocs, majorLabels), _f(minorLocs, minorLabels)
-
-
-
-
-
-class GridHelperBase(object):
-
- def __init__(self):
- self._force_update = True
- self._old_limits = None
- super(GridHelperBase, self).__init__()
-
-
- def update_lim(self, axes):
- x1, x2 = axes.get_xlim()
- y1, y2 = axes.get_ylim()
-
- if self._force_update or self._old_limits != (x1, x2, y1, y2):
- self._update(x1, x2, y1, y2)
- self._force_update = False
- self._old_limits = (x1, x2, y1, y2)
-
-
- def _update(self, x1, x2, y1, y2):
- pass
-
-
- def invalidate(self):
- self._force_update = True
-
- def valid(self):
- return not self._force_update
-
-
- def get_gridlines(self, which, axis):
- """
- Return list of grid lines as a list of paths (list of points).
-
- *which* : "major" or "minor"
- *axis* : "both", "x" or "y"
- """
- return []
-
- def new_gridlines(self, ax):
- """
- Create and return a new GridlineCollection instance.
-
- *which* : "major" or "minor"
- *axis* : "both", "x" or "y"
-
- """
- gridlines = GridlinesCollection(None, transform=ax.transData,
- colors=rcParams['grid.color'],
- linestyles=rcParams['grid.linestyle'],
- linewidths=rcParams['grid.linewidth'])
- ax._set_artist_props(gridlines)
- gridlines.set_grid_helper(self)
-
- ax.axes._set_artist_props(gridlines)
- # gridlines.set_clip_path(self.axes.patch)
- # set_clip_path need to be deferred after Axes.cla is completed.
- # It is done inside the cla.
-
- return gridlines
-
-
-class GridHelperRectlinear(GridHelperBase):
-
-
- def __init__(self, axes):
-
- super(GridHelperRectlinear, self).__init__()
- self.axes = axes
-
-
-
- def new_fixed_axis(self, loc,
- nth_coord=None,
- axis_direction=None,
- offset=None,
- axes=None,
- ):
-
- if axes is None:
- warnings.warn("'new_fixed_axis' explicitly requires the axes keyword.")
- axes = self.axes
-
- _helper = AxisArtistHelperRectlinear.Fixed(axes, loc, nth_coord)
-
- if axis_direction is None:
- axis_direction = loc
- axisline = AxisArtist(axes, _helper, offset=offset,
- axis_direction=axis_direction,
- )
-
- return axisline
-
-
- def new_floating_axis(self, nth_coord, value,
- axis_direction="bottom",
- axes=None,
- ):
-
- if axes is None:
- warnings.warn(
- "'new_floating_axis' explicitly requires the axes keyword.")
- axes = self.axes
-
- passthrough_point = (value, value)
- transform = axes.transData
-
- _helper = AxisArtistHelperRectlinear.Floating(
- axes, nth_coord, value, axis_direction)
-
- axisline = AxisArtist(axes, _helper)
-
- axisline.line.set_clip_on(True)
- axisline.line.set_clip_box(axisline.axes.bbox)
- return axisline
-
-
- def get_gridlines(self, which="major", axis="both"):
- """
- return list of gridline coordinates in data coordinates.
-
- *which* : "major" or "minor"
- *axis* : "both", "x" or "y"
- """
-
- gridlines = []
-
-
- if axis in ["both", "x"]:
- locs = []
- y1, y2 = self.axes.get_ylim()
- #if self.axes.xaxis._gridOnMajor:
- if which in ["both", "major"]:
- locs.extend(self.axes.xaxis.major.locator())
- #if self.axes.xaxis._gridOnMinor:
- if which in ["both", "minor"]:
- locs.extend(self.axes.xaxis.minor.locator())
-
- for x in locs:
- gridlines.append([[x, x], [y1, y2]])
-
-
- if axis in ["both", "y"]:
- x1, x2 = self.axes.get_xlim()
- locs = []
- if self.axes.yaxis._gridOnMajor:
- #if which in ["both", "major"]:
- locs.extend(self.axes.yaxis.major.locator())
- if self.axes.yaxis._gridOnMinor:
- #if which in ["both", "minor"]:
- locs.extend(self.axes.yaxis.minor.locator())
-
- for y in locs:
- gridlines.append([[x1, x2], [y, y]])
-
- return gridlines
-
-
-
-
-
-
-class SimpleChainedObjects(object):
- def __init__(self, objects):
- self._objects = objects
-
- def __getattr__(self, k):
- _a = SimpleChainedObjects([getattr(a, k) for a in self._objects])
- return _a
-
- def __call__(self, *kl, **kwargs):
- for m in self._objects:
- m(*kl, **kwargs)
-
-
-class Axes(maxes.Axes):
-
- class AxisDict(dict):
- def __init__(self, axes):
- self.axes = axes
- super(Axes.AxisDict, self).__init__()
-
- def __getitem__(self, k):
- if isinstance(k, tuple):
- r = SimpleChainedObjects([dict.__getitem__(self, k1) for k1 in k])
- return r
- elif isinstance(k, slice):
- if k.start == None and k.stop == None and k.step == None:
- r = SimpleChainedObjects(list(six.itervalues(self)))
- return r
- else:
- raise ValueError("Unsupported slice")
- else:
- return dict.__getitem__(self, k)
-
- def __call__(self, *v, **kwargs):
- return maxes.Axes.axis(self.axes, *v, **kwargs)
-
-
- def __init__(self, *kl, **kw):
-
-
- helper = kw.pop("grid_helper", None)
-
- self._axisline_on = True
-
- if helper:
- self._grid_helper = helper
- else:
- self._grid_helper = GridHelperRectlinear(self)
-
- super(Axes, self).__init__(*kl, **kw)
-
- self.toggle_axisline(True)
-
-
- def toggle_axisline(self, b=None):
- if b is None:
- b = not self._axisline_on
- if b:
- self._axisline_on = True
- for s in self.spines.values():
- s.set_visible(False)
- self.xaxis.set_visible(False)
- self.yaxis.set_visible(False)
- else:
- self._axisline_on = False
- for s in self.spines.values():
- s.set_visible(True)
- self.xaxis.set_visible(True)
- self.yaxis.set_visible(True)
-
-
- def _init_axis(self):
- super(Axes, self)._init_axis()
-
-
- def _init_axis_artists(self, axes=None):
- if axes is None:
- axes = self
-
- self._axislines = self.AxisDict(self)
- new_fixed_axis = self.get_grid_helper().new_fixed_axis
- for loc in ["bottom", "top", "left", "right"]:
- self._axislines[loc] = new_fixed_axis(loc=loc, axes=axes,
- axis_direction=loc)
-
- for axisline in [self._axislines["top"], self._axislines["right"]]:
- axisline.label.set_visible(False)
- axisline.major_ticklabels.set_visible(False)
- axisline.minor_ticklabels.set_visible(False)
-
- @property
- def axis(self):
- return self._axislines
-
- def new_gridlines(self, grid_helper=None):
- """
- Create and return a new GridlineCollection instance.
-
- *which* : "major" or "minor"
- *axis* : "both", "x" or "y"
-
- """
- if grid_helper is None:
- grid_helper = self.get_grid_helper()
-
- gridlines = grid_helper.new_gridlines(self)
-
- return gridlines
-
-
- def _init_gridlines(self, grid_helper=None):
- # It is done inside the cla.
- gridlines = self.new_gridlines(grid_helper)
-
- self.gridlines = gridlines
-
- def cla(self):
- # gridlines need to b created before cla() since cla calls grid()
-
- self._init_gridlines()
- super(Axes, self).cla()
-
- # the clip_path should be set after Axes.cla() since that's
- # when a patch is created.
- self.gridlines.set_clip_path(self.axes.patch)
-
- self._init_axis_artists()
-
- def get_grid_helper(self):
- return self._grid_helper
-
-
- def grid(self, b=None, which='major', axis="both", **kwargs):
- """
- Toggle the gridlines, and optionally set the properties of the lines.
- """
- # their are some discrepancy between the behavior of grid in
- # axes_grid and the original mpl's grid, because axes_grid
- # explicitly set the visibility of the gridlines.
-
- super(Axes, self).grid(b, which=which, axis=axis, **kwargs)
- if not self._axisline_on:
- return
-
- if b is None:
-
- if self.axes.xaxis._gridOnMinor or self.axes.xaxis._gridOnMajor or \
- self.axes.yaxis._gridOnMinor or self.axes.yaxis._gridOnMajor:
- b=True
- else:
- b=False
-
- self.gridlines.set_which(which)
- self.gridlines.set_axis(axis)
- self.gridlines.set_visible(b)
-
- if len(kwargs):
- martist.setp(self.gridlines, **kwargs)
-
- def get_children(self):
- if self._axisline_on:
- children = list(six.itervalues(self._axislines)) + [self.gridlines]
- else:
- children = []
- children.extend(super(Axes, self).get_children())
- return children
-
- def invalidate_grid_helper(self):
- self._grid_helper.invalidate()
-
-
- def new_fixed_axis(self, loc, offset=None):
- gh = self.get_grid_helper()
- axis = gh.new_fixed_axis(loc,
- nth_coord=None,
- axis_direction=None,
- offset=offset,
- axes=self,
- )
- return axis
-
-
- def new_floating_axis(self, nth_coord, value,
- axis_direction="bottom",
- ):
- gh = self.get_grid_helper()
- axis = gh.new_floating_axis(nth_coord, value,
- axis_direction=axis_direction,
- axes=self)
- return axis
-
-
-
- def draw(self, renderer, inframe=False):
-
- if not self._axisline_on:
- super(Axes, self).draw(renderer, inframe)
- return
-
- orig_artists = self.artists
- self.artists = self.artists + list(self._axislines.values()) + [self.gridlines]
-
- super(Axes, self).draw(renderer, inframe)
-
- self.artists = orig_artists
-
-
- def get_tightbbox(self, renderer, call_axes_locator=True):
-
- bb0 = super(Axes, self).get_tightbbox(renderer, call_axes_locator)
-
- if not self._axisline_on:
- return bb0
-
- bb = [bb0]
-
- for axisline in list(six.itervalues(self._axislines)):
- if not axisline.get_visible():
- continue
-
- bb.append(axisline.get_tightbbox(renderer))
- # if axisline.label.get_visible():
- # bb.append(axisline.label.get_window_extent(renderer))
-
-
- # if axisline.major_ticklabels.get_visible():
- # bb.extend(axisline.major_ticklabels.get_window_extents(renderer))
- # if axisline.minor_ticklabels.get_visible():
- # bb.extend(axisline.minor_ticklabels.get_window_extents(renderer))
- # if axisline.major_ticklabels.get_visible() or \
- # axisline.minor_ticklabels.get_visible():
- # bb.append(axisline.offsetText.get_window_extent(renderer))
-
- #bb.extend([c.get_window_extent(renderer) for c in artists \
- # if c.get_visible()])
-
- _bbox = Bbox.union([b for b in bb if b and (b.width!=0 or b.height!=0)])
-
- return _bbox
-
-
-
-
-Subplot = maxes.subplot_class_factory(Axes)
-
-class AxesZero(Axes):
- def __init__(self, *kl, **kw):
-
- super(AxesZero, self).__init__(*kl, **kw)
-
-
- def _init_axis_artists(self):
- super(AxesZero, self)._init_axis_artists()
-
- new_floating_axis = self._grid_helper.new_floating_axis
- xaxis_zero = new_floating_axis(nth_coord=0,
- value=0.,
- axis_direction="bottom",
- axes=self)
-
- xaxis_zero.line.set_clip_path(self.patch)
- xaxis_zero.set_visible(False)
- self._axislines["xzero"] = xaxis_zero
-
- yaxis_zero = new_floating_axis(nth_coord=1,
- value=0.,
- axis_direction="left",
- axes=self)
-
-
- yaxis_zero.line.set_clip_path(self.patch)
- yaxis_zero.set_visible(False)
- self._axislines["yzero"] = yaxis_zero
-
-SubplotZero = maxes.subplot_class_factory(AxesZero)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/clip_path.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/clip_path.py
deleted file mode 100644
index 8507b09b07..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/clip_path.py
+++ /dev/null
@@ -1,135 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import zip
-
-import numpy as np
-from math import degrees
-import math
-import warnings
-
-def atan2(dy, dx):
- if dx == 0 and dy == 0:
- warnings.warn("dx and dy is 0")
- return 0
- else:
- return math.atan2(dy, dx)
-
-# FIXME : The current algorithm seems to return incorrect angle when the line
-# ends at the boundary.
-
-def clip(xlines, ylines, x0, clip="right", xdir=True, ydir=True):
-
- clipped_xlines = []
- clipped_ylines = []
-
- _pos_angles = []
-
- if xdir:
- xsign = 1
- else:
- xsign = -1
-
- if ydir:
- ysign = 1
- else:
- ysign = -1
-
-
- for x, y in zip(xlines, ylines):
-
- if clip in ["up", "right"]:
- b = (x < x0).astype("i")
- db = b[1:] - b[:-1]
- else:
- b = (x > x0).astype("i")
- db = b[1:] - b[:-1]
-
-
- if b[0]:
- ns = 0
- else:
- ns = -1
- segx, segy = [], []
- for (i,) in np.argwhere(db!=0):
- c = db[i]
- if c == -1:
- dx = (x0 - x[i])
- dy = (y[i+1] - y[i]) * (dx/ (x[i+1] - x[i]))
- y0 = y[i] + dy
- clipped_xlines.append(np.concatenate([segx, x[ns:i+1], [x0]]))
- clipped_ylines.append(np.concatenate([segy, y[ns:i+1], [y0]]))
- ns = -1
- segx, segy = [], []
-
- if dx == 0. and dy == 0:
- dx = x[i+1] - x[i]
- dy = y[i+1] - y[i]
-
- a = degrees(atan2(ysign*dy, xsign*dx))
- _pos_angles.append((x0, y0, a))
-
- elif c == 1:
- dx = (x0 - x[i])
- dy = (y[i+1] - y[i]) * (dx / (x[i+1] - x[i]))
- y0 = y[i] + dy
- segx, segy = [x0], [y0]
- ns = i+1
-
- if dx == 0. and dy == 0:
- dx = x[i+1] - x[i]
- dy = y[i+1] - y[i]
-
- a = degrees(atan2(ysign*dy, xsign*dx))
- _pos_angles.append((x0, y0, a))
-
- if ns != -1:
- clipped_xlines.append(np.concatenate([segx, x[ns:]]))
- clipped_ylines.append(np.concatenate([segy, y[ns:]]))
-
- #clipped_pos_angles.append(_pos_angles)
-
-
- return clipped_xlines, clipped_ylines, _pos_angles
-
-
-def clip_line_to_rect(xline, yline, bbox):
-
- x0, y0, x1, y1 = bbox.extents
-
- xdir = x1 > x0
- ydir = y1 > y0
-
- if x1 > x0:
- lx1, ly1, c_right_ = clip([xline], [yline], x1, clip="right", xdir=xdir, ydir=ydir)
- lx2, ly2, c_left_ = clip(lx1, ly1, x0, clip="left", xdir=xdir, ydir=ydir)
- else:
- lx1, ly1, c_right_ = clip([xline], [yline], x0, clip="right", xdir=xdir, ydir=ydir)
- lx2, ly2, c_left_ = clip(lx1, ly1, x1, clip="left", xdir=xdir, ydir=ydir)
-
- if y1 > y0:
- ly3, lx3, c_top_ = clip(ly2, lx2, y1, clip="right", xdir=ydir, ydir=xdir)
- ly4, lx4, c_bottom_ = clip(ly3, lx3, y0, clip="left", xdir=ydir, ydir=xdir)
- else:
- ly3, lx3, c_top_ = clip(ly2, lx2, y0, clip="right", xdir=ydir, ydir=xdir)
- ly4, lx4, c_bottom_ = clip(ly3, lx3, y1, clip="left", xdir=ydir, ydir=xdir)
-
-
- # lx1, ly1, c_right_ = clip([xline], [yline], x1, clip="right")
- # lx2, ly2, c_left_ = clip(lx1, ly1, x0, clip="left")
- # ly3, lx3, c_top_ = clip(ly2, lx2, y1, clip="right")
- # ly4, lx4, c_bottom_ = clip(ly3, lx3, y0, clip="left")
-
- #c_left = [((x, y), (a+90)%180-180) for (x, y, a) in c_left_ \
- # if bbox.containsy(y)]
- c_left = [((x, y), (a+90)%180-90) for (x, y, a) in c_left_
- if bbox.containsy(y)]
- c_bottom = [((x, y), (90 - a)%180) for (y, x, a) in c_bottom_
- if bbox.containsx(x)]
- c_right = [((x, y), (a+90)%180+90) for (x, y, a) in c_right_
- if bbox.containsy(y)]
- c_top = [((x, y), (90 - a)%180+180) for (y, x, a) in c_top_
- if bbox.containsx(x)]
-
- return list(zip(lx4, ly4)), [c_left, c_bottom, c_right, c_top]
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/floating_axes.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/floating_axes.py
deleted file mode 100644
index 468413dbac..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/floating_axes.py
+++ /dev/null
@@ -1,544 +0,0 @@
-"""
-An experimental support for curvilinear grid.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import zip
-
-# TODO :
-# see if tick_iterator method can be simplified by reusing the parent method.
-
-import numpy as np
-
-from matplotlib.transforms import Affine2D, IdentityTransform
-from . import grid_helper_curvelinear
-from .axislines import AxisArtistHelper, GridHelperBase
-from .axis_artist import AxisArtist
-from .grid_finder import GridFinder
-
-
-class FloatingAxisArtistHelper(grid_helper_curvelinear.FloatingAxisArtistHelper):
- pass
-
-
-class FixedAxisArtistHelper(grid_helper_curvelinear.FloatingAxisArtistHelper):
-
- def __init__(self, grid_helper, side, nth_coord_ticks=None):
- """
- nth_coord = along which coordinate value varies.
- nth_coord = 0 -> x axis, nth_coord = 1 -> y axis
- """
-
- value, nth_coord = grid_helper.get_data_boundary(side) # return v= 0 , nth=1, extremes of the other coordinate.
- super(FixedAxisArtistHelper, self).__init__(grid_helper,
- nth_coord,
- value,
- axis_direction=side,
- )
- #self.grid_helper = grid_helper
- if nth_coord_ticks is None:
- nth_coord_ticks = nth_coord
- self.nth_coord_ticks = nth_coord_ticks
-
- self.value = value
- self.grid_helper = grid_helper
- self._side = side
-
-
- def update_lim(self, axes):
- self.grid_helper.update_lim(axes)
-
- self.grid_info = self.grid_helper.grid_info
-
-
-
- def get_axislabel_pos_angle(self, axes):
-
- extremes = self.grid_info["extremes"]
-
- if self.nth_coord == 0:
- xx0 = self.value
- yy0 = (extremes[2]+extremes[3])/2.
- dxx, dyy = 0., abs(extremes[2]-extremes[3])/1000.
- elif self.nth_coord == 1:
- xx0 = (extremes[0]+extremes[1])/2.
- yy0 = self.value
- dxx, dyy = abs(extremes[0]-extremes[1])/1000., 0.
-
- grid_finder = self.grid_helper.grid_finder
- xx1, yy1 = grid_finder.transform_xy([xx0], [yy0])
-
- trans_passingthrough_point = axes.transData + axes.transAxes.inverted()
- p = trans_passingthrough_point.transform_point([xx1[0], yy1[0]])
-
-
- if (0. <= p[0] <= 1.) and (0. <= p[1] <= 1.):
- xx1c, yy1c = axes.transData.transform_point([xx1[0], yy1[0]])
- xx2, yy2 = grid_finder.transform_xy([xx0+dxx], [yy0+dyy])
- xx2c, yy2c = axes.transData.transform_point([xx2[0], yy2[0]])
-
- return (xx1c, yy1c), np.arctan2(yy2c-yy1c, xx2c-xx1c)/np.pi*180.
- else:
- return None, None
-
-
-
- def get_tick_transform(self, axes):
- return IdentityTransform() #axes.transData
-
- def get_tick_iterators(self, axes):
- """tick_loc, tick_angle, tick_label, (optionally) tick_label"""
-
-
- grid_finder = self.grid_helper.grid_finder
-
- lat_levs, lat_n, lat_factor = self.grid_info["lat_info"]
- lon_levs, lon_n, lon_factor = self.grid_info["lon_info"]
-
- lon_levs, lat_levs = np.asarray(lon_levs), np.asarray(lat_levs)
- if lat_factor is not None:
- yy0 = lat_levs / lat_factor
- dy = 0.001 / lat_factor
- else:
- yy0 = lat_levs
- dy = 0.001
-
- if lon_factor is not None:
- xx0 = lon_levs / lon_factor
- dx = 0.001 / lon_factor
- else:
- xx0 = lon_levs
- dx = 0.001
-
- _extremes = self.grid_helper._extremes
- xmin, xmax = sorted(_extremes[:2])
- ymin, ymax = sorted(_extremes[2:])
- if self.nth_coord == 0:
- mask = (ymin <= yy0) & (yy0 <= ymax)
- yy0 = yy0[mask]
- elif self.nth_coord == 1:
- mask = (xmin <= xx0) & (xx0 <= xmax)
- xx0 = xx0[mask]
-
- def transform_xy(x, y):
- x1, y1 = grid_finder.transform_xy(x, y)
- x2y2 = axes.transData.transform(np.array([x1, y1]).transpose())
- x2, y2 = x2y2.transpose()
- return x2, y2
-
- # find angles
- if self.nth_coord == 0:
- xx0 = np.empty_like(yy0)
- xx0.fill(self.value)
-
- #yy0_ = yy0.copy()
-
- xx1, yy1 = transform_xy(xx0, yy0)
-
- xx00 = xx0.astype(float, copy=True)
- xx00[xx0+dx>xmax] -= dx
- xx1a, yy1a = transform_xy(xx00, yy0)
- xx1b, yy1b = transform_xy(xx00+dx, yy0)
-
- yy00 = yy0.astype(float, copy=True)
- yy00[yy0+dy>ymax] -= dy
- xx2a, yy2a = transform_xy(xx0, yy00)
- xx2b, yy2b = transform_xy(xx0, yy00+dy)
-
- labels = self.grid_info["lat_labels"]
- labels = [l for l, m in zip(labels, mask) if m]
-
- elif self.nth_coord == 1:
- yy0 = np.empty_like(xx0)
- yy0.fill(self.value)
-
- #xx0_ = xx0.copy()
- xx1, yy1 = transform_xy(xx0, yy0)
-
-
- yy00 = yy0.astype(float, copy=True)
- yy00[yy0+dy>ymax] -= dy
- xx1a, yy1a = transform_xy(xx0, yy00)
- xx1b, yy1b = transform_xy(xx0, yy00+dy)
-
- xx00 = xx0.astype(float, copy=True)
- xx00[xx0+dx>xmax] -= dx
- xx2a, yy2a = transform_xy(xx00, yy0)
- xx2b, yy2b = transform_xy(xx00+dx, yy0)
-
- labels = self.grid_info["lon_labels"]
- labels = [l for l, m in zip(labels, mask) if m]
-
-
- def f1():
- dd = np.arctan2(yy1b-yy1a, xx1b-xx1a) # angle normal
- dd2 = np.arctan2(yy2b-yy2a, xx2b-xx2a) # angle tangent
- mm = ((yy1b-yy1a)==0.) & ((xx1b-xx1a)==0.) # mask where dd1 is not defined
- dd[mm] = dd2[mm] + np.pi / 2
-
- #dd += np.pi
- #dd = np.arctan2(xx2-xx1, angle_tangent-yy1)
- trans_tick = self.get_tick_transform(axes)
- tr2ax = trans_tick + axes.transAxes.inverted()
- for x, y, d, d2, lab in zip(xx1, yy1, dd, dd2, labels):
- c2 = tr2ax.transform_point((x, y))
- delta=0.00001
- if (0. -delta<= c2[0] <= 1.+delta) and \
- (0. -delta<= c2[1] <= 1.+delta):
- d1 = d/3.14159*180.
- d2 = d2/3.14159*180.
- #_mod = (d2-d1+180)%360
- #if _mod < 180:
- # d1 += 180
- ##_div, _mod = divmod(d2-d1, 360)
- yield [x, y], d1, d2, lab
- #, d2/3.14159*180.+da)
-
- return f1(), iter([])
-
- def get_line_transform(self, axes):
- return axes.transData
-
- def get_line(self, axes):
-
- self.update_lim(axes)
- from matplotlib.path import Path
- k, v = dict(left=("lon_lines0", 0),
- right=("lon_lines0", 1),
- bottom=("lat_lines0", 0),
- top=("lat_lines0", 1))[self._side]
-
- xx, yy = self.grid_info[k][v]
- return Path(np.column_stack([xx, yy]))
-
-
-
-from .grid_finder import ExtremeFinderSimple
-
-class ExtremeFinderFixed(ExtremeFinderSimple):
- def __init__(self, extremes):
- self._extremes = extremes
-
- def __call__(self, transform_xy, x1, y1, x2, y2):
- """
- get extreme values.
-
- x1, y1, x2, y2 in image coordinates (0-based)
- nx, ny : number of division in each axis
- """
- #lon_min, lon_max, lat_min, lat_max = self._extremes
- return self._extremes
-
-
-
-class GridHelperCurveLinear(grid_helper_curvelinear.GridHelperCurveLinear):
-
- def __init__(self, aux_trans, extremes,
- grid_locator1=None,
- grid_locator2=None,
- tick_formatter1=None,
- tick_formatter2=None):
- """
- aux_trans : a transform from the source (curved) coordinate to
- target (rectilinear) coordinate. An instance of MPL's Transform
- (inverse transform should be defined) or a tuple of two callable
- objects which defines the transform and its inverse. The callables
- need take two arguments of array of source coordinates and
- should return two target coordinates:
- e.g., *x2, y2 = trans(x1, y1)*
- """
-
- self._old_values = None
-
- self._extremes = extremes
- extreme_finder = ExtremeFinderFixed(extremes)
-
- super(GridHelperCurveLinear, self).__init__(aux_trans,
- extreme_finder,
- grid_locator1=grid_locator1,
- grid_locator2=grid_locator2,
- tick_formatter1=tick_formatter1,
- tick_formatter2=tick_formatter2)
-
-
- # def update_grid_finder(self, aux_trans=None, **kw):
-
- # if aux_trans is not None:
- # self.grid_finder.update_transform(aux_trans)
-
- # self.grid_finder.update(**kw)
- # self.invalidate()
-
-
- # def _update(self, x1, x2, y1, y2):
- # "bbox in 0-based image coordinates"
- # # update wcsgrid
-
- # if self.valid() and self._old_values == (x1, x2, y1, y2):
- # return
-
- # self._update_grid(x1, y1, x2, y2)
-
- # self._old_values = (x1, x2, y1, y2)
-
- # self._force_update = False
-
-
- def get_data_boundary(self, side):
- """
- return v= 0 , nth=1
- """
- lon1, lon2, lat1, lat2 = self._extremes
- return dict(left=(lon1, 0),
- right=(lon2, 0),
- bottom=(lat1, 1),
- top=(lat2, 1))[side]
-
-
- def new_fixed_axis(self, loc,
- nth_coord=None,
- axis_direction=None,
- offset=None,
- axes=None):
-
- if axes is None:
- axes = self.axes
-
- if axis_direction is None:
- axis_direction = loc
-
- _helper = FixedAxisArtistHelper(self, loc,
- nth_coord_ticks=nth_coord)
-
-
- axisline = AxisArtist(axes, _helper, axis_direction=axis_direction)
- axisline.line.set_clip_on(True)
- axisline.line.set_clip_box(axisline.axes.bbox)
-
-
- return axisline
-
-
- # new_floating_axis will inherit the grid_helper's extremes.
-
- # def new_floating_axis(self, nth_coord,
- # value,
- # axes=None,
- # axis_direction="bottom"
- # ):
-
- # axis = super(GridHelperCurveLinear,
- # self).new_floating_axis(nth_coord,
- # value, axes=axes,
- # axis_direction=axis_direction)
-
- # # set extreme values of the axis helper
- # if nth_coord == 1:
- # axis.get_helper().set_extremes(*self._extremes[:2])
- # elif nth_coord == 0:
- # axis.get_helper().set_extremes(*self._extremes[2:])
-
- # return axis
-
-
- def _update_grid(self, x1, y1, x2, y2):
-
- #self.grid_info = self.grid_finder.get_grid_info(x1, y1, x2, y2)
-
- if self.grid_info is None:
- self.grid_info = dict()
-
- grid_info = self.grid_info
-
- grid_finder = self.grid_finder
- extremes = grid_finder.extreme_finder(grid_finder.inv_transform_xy,
- x1, y1, x2, y2)
-
- lon_min, lon_max = sorted(extremes[:2])
- lat_min, lat_max = sorted(extremes[2:])
- lon_levs, lon_n, lon_factor = \
- grid_finder.grid_locator1(lon_min, lon_max)
- lat_levs, lat_n, lat_factor = \
- grid_finder.grid_locator2(lat_min, lat_max)
- grid_info["extremes"] = lon_min, lon_max, lat_min, lat_max #extremes
-
- grid_info["lon_info"] = lon_levs, lon_n, lon_factor
- grid_info["lat_info"] = lat_levs, lat_n, lat_factor
-
- grid_info["lon_labels"] = grid_finder.tick_formatter1("bottom",
- lon_factor,
- lon_levs)
-
- grid_info["lat_labels"] = grid_finder.tick_formatter2("bottom",
- lat_factor,
- lat_levs)
-
- if lon_factor is None:
- lon_values = np.asarray(lon_levs[:lon_n])
- else:
- lon_values = np.asarray(lon_levs[:lon_n]/lon_factor)
- if lat_factor is None:
- lat_values = np.asarray(lat_levs[:lat_n])
- else:
- lat_values = np.asarray(lat_levs[:lat_n]/lat_factor)
-
- lon_values0 = lon_values[(lon_min<lon_values) & (lon_values<lon_max)]
- lat_values0 = lat_values[(lat_min<lat_values) & (lat_values<lat_max)]
- lon_lines, lat_lines = grid_finder._get_raw_grid_lines(lon_values0,
- lat_values0,
- lon_min, lon_max,
- lat_min, lat_max)
-
-
- grid_info["lon_lines"] = lon_lines
- grid_info["lat_lines"] = lat_lines
-
-
- lon_lines, lat_lines = grid_finder._get_raw_grid_lines(extremes[:2],
- extremes[2:],
- *extremes)
- #lon_min, lon_max,
- # lat_min, lat_max)
-
-
- grid_info["lon_lines0"] = lon_lines
- grid_info["lat_lines0"] = lat_lines
-
-
-
- def get_gridlines(self, which="major", axis="both"):
- grid_lines = []
- if axis in ["both", "x"]:
- for gl in self.grid_info["lon_lines"]:
- grid_lines.extend([gl])
- if axis in ["both", "y"]:
- for gl in self.grid_info["lat_lines"]:
- grid_lines.extend([gl])
-
- return grid_lines
-
-
- def get_boundary(self):
- """
- return Nx2 array of x,y coordinate of the boundary
- """
- x0, x1, y0, y1 = self._extremes
- tr = self._aux_trans
- xx = np.linspace(x0, x1, 100)
- yy0, yy1 = np.empty_like(xx), np.empty_like(xx)
- yy0.fill(y0)
- yy1.fill(y1)
-
- yy = np.linspace(y0, y1, 100)
- xx0, xx1 = np.empty_like(yy), np.empty_like(yy)
- xx0.fill(x0)
- xx1.fill(x1)
-
- xxx = np.concatenate([xx[:-1], xx1[:-1], xx[-1:0:-1], xx0])
- yyy = np.concatenate([yy0[:-1], yy[:-1], yy1[:-1], yy[::-1]])
- t = tr.transform(np.array([xxx, yyy]).transpose())
-
- return t
-
-
-
-
-
-
-
-
-
-
-
-
-class FloatingAxesBase(object):
-
-
- def __init__(self, *kl, **kwargs):
- grid_helper = kwargs.get("grid_helper", None)
- if grid_helper is None:
- raise ValueError("FloatingAxes requires grid_helper argument")
- if not hasattr(grid_helper, "get_boundary"):
- raise ValueError("grid_helper must implement get_boundary method")
-
- self._axes_class_floating.__init__(self, *kl, **kwargs)
-
- self.set_aspect(1.)
- self.adjust_axes_lim()
-
-
- def _gen_axes_patch(self):
- """
- Returns the patch used to draw the background of the axes. It
- is also used as the clipping path for any data elements on the
- axes.
-
- In the standard axes, this is a rectangle, but in other
- projections it may not be.
-
- .. note::
- Intended to be overridden by new projection types.
- """
- import matplotlib.patches as mpatches
- grid_helper = self.get_grid_helper()
- t = grid_helper.get_boundary()
- return mpatches.Polygon(t)
-
- def cla(self):
- self._axes_class_floating.cla(self)
- #HostAxes.cla(self)
- self.patch.set_transform(self.transData)
-
-
- patch = self._axes_class_floating._gen_axes_patch(self)
- patch.set_figure(self.figure)
- patch.set_visible(False)
- patch.set_transform(self.transAxes)
-
- self.patch.set_clip_path(patch)
- self.gridlines.set_clip_path(patch)
-
- self._original_patch = patch
-
-
- def adjust_axes_lim(self):
-
- #t = self.get_boundary()
- grid_helper = self.get_grid_helper()
- t = grid_helper.get_boundary()
- x, y = t[:,0], t[:,1]
-
- xmin, xmax = min(x), max(x)
- ymin, ymax = min(y), max(y)
-
- dx = (xmax-xmin)/100.
- dy = (ymax-ymin)/100.
-
- self.set_xlim(xmin-dx, xmax+dx)
- self.set_ylim(ymin-dy, ymax+dy)
-
-
-
-_floatingaxes_classes = {}
-
-def floatingaxes_class_factory(axes_class):
-
- new_class = _floatingaxes_classes.get(axes_class)
- if new_class is None:
- new_class = type(str("Floating %s" % (axes_class.__name__)),
- (FloatingAxesBase, axes_class),
- {'_axes_class_floating': axes_class})
- _floatingaxes_classes[axes_class] = new_class
-
- return new_class
-
-from .axislines import Axes
-from mpl_toolkits.axes_grid1.parasite_axes import host_axes_class_factory
-
-FloatingAxes = floatingaxes_class_factory(host_axes_class_factory(Axes))
-
-
-import matplotlib.axes as maxes
-FloatingSubplot = maxes.subplot_class_factory(FloatingAxes)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/grid_finder.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/grid_finder.py
deleted file mode 100644
index 62a94b1478..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/grid_finder.py
+++ /dev/null
@@ -1,340 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import numpy as np
-from matplotlib.transforms import Bbox
-from . import clip_path
-clip_line_to_rect = clip_path.clip_line_to_rect
-
-import matplotlib.ticker as mticker
-from matplotlib.transforms import Transform
-
-# extremes finder
-
-class ExtremeFinderSimple(object):
- def __init__(self, nx, ny):
- self.nx, self.ny = nx, ny
-
- def __call__(self, transform_xy, x1, y1, x2, y2):
- """
- get extreme values.
-
- x1, y1, x2, y2 in image coordinates (0-based)
- nx, ny : number of division in each axis
- """
- x_, y_ = np.linspace(x1, x2, self.nx), np.linspace(y1, y2, self.ny)
- x, y = np.meshgrid(x_, y_)
- lon, lat = transform_xy(np.ravel(x), np.ravel(y))
-
- lon_min, lon_max = lon.min(), lon.max()
- lat_min, lat_max = lat.min(), lat.max()
-
- return self._add_pad(lon_min, lon_max, lat_min, lat_max)
-
- def _add_pad(self, lon_min, lon_max, lat_min, lat_max):
- """ a small amount of padding is added because the current
- clipping algorithms seems to fail when the gridline ends at
- the bbox boundary.
- """
- dlon = (lon_max - lon_min) / self.nx
- dlat = (lat_max - lat_min) / self.ny
-
- lon_min, lon_max = lon_min - dlon, lon_max + dlon
- lat_min, lat_max = lat_min - dlat, lat_max + dlat
-
- return lon_min, lon_max, lat_min, lat_max
-
-
-
-class GridFinderBase(object):
- def __init__(self,
- extreme_finder,
- grid_locator1,
- grid_locator2,
- tick_formatter1=None,
- tick_formatter2=None):
- """
- the transData of the axes to the world coordinate.
- locator1, locator2 : grid locator for 1st and 2nd axis.
-
- Derived must define "transform_xy, inv_transform_xy"
- (may use update_transform)
- """
- super(GridFinderBase, self).__init__()
-
- self.extreme_finder = extreme_finder
- self.grid_locator1 = grid_locator1
- self.grid_locator2 = grid_locator2
- self.tick_formatter1 = tick_formatter1
- self.tick_formatter2 = tick_formatter2
-
- def get_grid_info(self,
- x1, y1, x2, y2):
- """
- lon_values, lat_values : list of grid values. if integer is given,
- rough number of grids in each direction.
- """
-
- extremes = self.extreme_finder(self.inv_transform_xy, x1, y1, x2, y2)
-
- # min & max rage of lat (or lon) for each grid line will be drawn.
- # i.e., gridline of lon=0 will be drawn from lat_min to lat_max.
-
- lon_min, lon_max, lat_min, lat_max = extremes
- lon_levs, lon_n, lon_factor = \
- self.grid_locator1(lon_min, lon_max)
- lat_levs, lat_n, lat_factor = \
- self.grid_locator2(lat_min, lat_max)
-
- if lon_factor is None:
- lon_values = np.asarray(lon_levs[:lon_n])
- else:
- lon_values = np.asarray(lon_levs[:lon_n]/lon_factor)
- if lat_factor is None:
- lat_values = np.asarray(lat_levs[:lat_n])
- else:
- lat_values = np.asarray(lat_levs[:lat_n]/lat_factor)
-
-
- lon_lines, lat_lines = self._get_raw_grid_lines(lon_values,
- lat_values,
- lon_min, lon_max,
- lat_min, lat_max)
-
- ddx = (x2-x1)*1.e-10
- ddy = (y2-y1)*1.e-10
- bb = Bbox.from_extents(x1-ddx, y1-ddy, x2+ddx, y2+ddy)
-
- grid_info = {}
- grid_info["extremes"] = extremes
- grid_info["lon_lines"] = lon_lines
- grid_info["lat_lines"] = lat_lines
-
- grid_info["lon"] = self._clip_grid_lines_and_find_ticks(lon_lines,
- lon_values,
- lon_levs,
- bb)
-
- grid_info["lat"] = self._clip_grid_lines_and_find_ticks(lat_lines,
- lat_values,
- lat_levs,
- bb)
-
- tck_labels = grid_info["lon"]["tick_labels"] = dict()
- for direction in ["left", "bottom", "right", "top"]:
- levs = grid_info["lon"]["tick_levels"][direction]
- tck_labels[direction] = self.tick_formatter1(direction,
- lon_factor, levs)
-
- tck_labels = grid_info["lat"]["tick_labels"] = dict()
- for direction in ["left", "bottom", "right", "top"]:
- levs = grid_info["lat"]["tick_levels"][direction]
- tck_labels[direction] = self.tick_formatter2(direction,
- lat_factor, levs)
-
- return grid_info
-
-
- def _get_raw_grid_lines(self,
- lon_values, lat_values,
- lon_min, lon_max, lat_min, lat_max):
-
- lons_i = np.linspace(lon_min, lon_max, 100) # for interpolation
- lats_i = np.linspace(lat_min, lat_max, 100)
-
- lon_lines = [self.transform_xy(np.zeros_like(lats_i) + lon, lats_i)
- for lon in lon_values]
- lat_lines = [self.transform_xy(lons_i, np.zeros_like(lons_i) + lat)
- for lat in lat_values]
-
- return lon_lines, lat_lines
-
-
- def _clip_grid_lines_and_find_ticks(self, lines, values, levs, bb):
- gi = dict()
- gi["values"] = []
- gi["levels"] = []
- gi["tick_levels"] = dict(left=[], bottom=[], right=[], top=[])
- gi["tick_locs"] = dict(left=[], bottom=[], right=[], top=[])
- gi["lines"] = []
-
- tck_levels = gi["tick_levels"]
- tck_locs = gi["tick_locs"]
- for (lx, ly), v, lev in zip(lines, values, levs):
- xy, tcks = clip_line_to_rect(lx, ly, bb)
- if not xy:
- continue
- gi["levels"].append(v)
- gi["lines"].append(xy)
-
- for tck, direction in zip(tcks,
- ["left", "bottom", "right", "top"]):
- for t in tck:
- tck_levels[direction].append(lev)
- tck_locs[direction].append(t)
-
- return gi
-
-
- def update_transform(self, aux_trans):
- if isinstance(aux_trans, Transform):
- def transform_xy(x, y):
- x, y = np.asarray(x), np.asarray(y)
- ll1 = np.concatenate((x[:,np.newaxis], y[:,np.newaxis]), 1)
- ll2 = aux_trans.transform(ll1)
- lon, lat = ll2[:,0], ll2[:,1]
- return lon, lat
-
- def inv_transform_xy(x, y):
- x, y = np.asarray(x), np.asarray(y)
- ll1 = np.concatenate((x[:,np.newaxis], y[:,np.newaxis]), 1)
- ll2 = aux_trans.inverted().transform(ll1)
- lon, lat = ll2[:,0], ll2[:,1]
- return lon, lat
-
- else:
- transform_xy, inv_transform_xy = aux_trans
-
- self.transform_xy = transform_xy
- self.inv_transform_xy = inv_transform_xy
-
-
- def update(self, **kw):
- for k in kw:
- if k in ["extreme_finder",
- "grid_locator1",
- "grid_locator2",
- "tick_formatter1",
- "tick_formatter2"]:
- setattr(self, k, kw[k])
- else:
- raise ValueError("unknown update property '%s'" % k)
-
-
-class GridFinder(GridFinderBase):
-
- def __init__(self,
- transform,
- extreme_finder=None,
- grid_locator1=None,
- grid_locator2=None,
- tick_formatter1=None,
- tick_formatter2=None):
- """
- transform : transform from the image coordinate (which will be
- the transData of the axes to the world coordinate.
-
- or transform = (transform_xy, inv_transform_xy)
-
- locator1, locator2 : grid locator for 1st and 2nd axis.
- """
- if extreme_finder is None:
- extreme_finder = ExtremeFinderSimple(20, 20)
- if grid_locator1 is None:
- grid_locator1 = MaxNLocator()
- if grid_locator2 is None:
- grid_locator2 = MaxNLocator()
- if tick_formatter1 is None:
- tick_formatter1 = FormatterPrettyPrint()
- if tick_formatter2 is None:
- tick_formatter2 = FormatterPrettyPrint()
- super(GridFinder, self).__init__(
- extreme_finder,
- grid_locator1,
- grid_locator2,
- tick_formatter1,
- tick_formatter2)
- self.update_transform(transform)
-
-
-class MaxNLocator(mticker.MaxNLocator):
- def __init__(self, nbins=10, steps=None,
- trim=True,
- integer=False,
- symmetric=False,
- prune=None):
- # trim argument has no effect. It has been left for API compatibility
- mticker.MaxNLocator.__init__(self, nbins, steps=steps,
- integer=integer,
- symmetric=symmetric, prune=prune)
- self.create_dummy_axis()
- self._factor = None
-
- def __call__(self, v1, v2):
- if self._factor is not None:
- self.set_bounds(v1*self._factor, v2*self._factor)
- locs = mticker.MaxNLocator.__call__(self)
- return np.array(locs), len(locs), self._factor
- else:
- self.set_bounds(v1, v2)
- locs = mticker.MaxNLocator.__call__(self)
- return np.array(locs), len(locs), None
-
- def set_factor(self, f):
- self._factor = f
-
-
-class FixedLocator(object):
- def __init__(self, locs):
- self._locs = locs
- self._factor = None
-
-
- def __call__(self, v1, v2):
- if self._factor is None:
- v1, v2 = sorted([v1, v2])
- else:
- v1, v2 = sorted([v1*self._factor, v2*self._factor])
- locs = np.array([l for l in self._locs if ((v1 <= l) and (l <= v2))])
- return locs, len(locs), self._factor
-
- def set_factor(self, f):
- self._factor = f
-
-
-
-# Tick Formatter
-
-class FormatterPrettyPrint(object):
- def __init__(self, useMathText=True):
- self._fmt = mticker.ScalarFormatter(
- useMathText=useMathText, useOffset=False)
- self._fmt.create_dummy_axis()
- self._ignore_factor = True
-
- def __call__(self, direction, factor, values):
- if not self._ignore_factor:
- if factor is None:
- factor = 1.
- values = [v/factor for v in values]
- #values = [v for v in values]
- self._fmt.set_locs(values)
- return [self._fmt(v) for v in values]
-
-
-class DictFormatter(object):
- def __init__(self, format_dict, formatter=None):
- """
- format_dict : dictionary for format strings to be used.
- formatter : fall-back formatter
- """
- super(DictFormatter, self).__init__()
- self._format_dict = format_dict
- self._fallback_formatter = formatter
-
- def __call__(self, direction, factor, values):
- """
- factor is ignored if value is found in the dictionary
- """
-
- if self._fallback_formatter:
- fallback_strings = self._fallback_formatter(
- direction, factor, values)
- else:
- fallback_strings = [""]*len(values)
-
- r = [self._format_dict.get(k, v) for k, v in zip(values,
- fallback_strings)]
- return r
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/grid_helper_curvelinear.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/grid_helper_curvelinear.py
deleted file mode 100644
index 578645148e..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/grid_helper_curvelinear.py
+++ /dev/null
@@ -1,475 +0,0 @@
-"""
-An experimental support for curvilinear grid.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import zip
-
-from itertools import chain
-from .grid_finder import GridFinder
-
-from .axislines import AxisArtistHelper, GridHelperBase
-from .axis_artist import AxisArtist
-from matplotlib.transforms import Affine2D, IdentityTransform
-import numpy as np
-
-from matplotlib.path import Path
-
-class FixedAxisArtistHelper(AxisArtistHelper.Fixed):
- """
- Helper class for a fixed axis.
- """
-
- def __init__(self, grid_helper, side, nth_coord_ticks=None):
- """
- nth_coord = along which coordinate value varies.
- nth_coord = 0 -> x axis, nth_coord = 1 -> y axis
- """
-
- super(FixedAxisArtistHelper, self).__init__(loc=side)
-
- self.grid_helper = grid_helper
- if nth_coord_ticks is None:
- nth_coord_ticks = self.nth_coord
- self.nth_coord_ticks = nth_coord_ticks
-
- self.side = side
- self._limits_inverted = False
-
- def update_lim(self, axes):
- self.grid_helper.update_lim(axes)
-
- if self.nth_coord == 0:
- xy1, xy2 = axes.get_ylim()
- else:
- xy1, xy2 = axes.get_xlim()
-
- if xy1 > xy2:
- self._limits_inverted = True
- else:
- self._limits_inverted = False
-
-
- def change_tick_coord(self, coord_number=None):
- if coord_number is None:
- self.nth_coord_ticks = 1 - self.nth_coord_ticks
- elif coord_number in [0, 1]:
- self.nth_coord_ticks = coord_number
- else:
- raise Exception("wrong coord number")
-
-
- def get_tick_transform(self, axes):
- return axes.transData
-
- def get_tick_iterators(self, axes):
- """tick_loc, tick_angle, tick_label"""
-
- g = self.grid_helper
-
- if self._limits_inverted:
- side = {"left":"right","right":"left",
- "top":"bottom", "bottom":"top"}[self.side]
- else:
- side = self.side
-
- ti1 = g.get_tick_iterator(self.nth_coord_ticks, side)
- ti2 = g.get_tick_iterator(1-self.nth_coord_ticks, side, minor=True)
-
- #ti2 = g.get_tick_iterator(1-self.nth_coord_ticks, self.side, minor=True)
-
- return chain(ti1, ti2), iter([])
-
-
-
-class FloatingAxisArtistHelper(AxisArtistHelper.Floating):
-
- def __init__(self, grid_helper, nth_coord, value, axis_direction=None):
- """
- nth_coord = along which coordinate value varies.
- nth_coord = 0 -> x axis, nth_coord = 1 -> y axis
- """
-
- super(FloatingAxisArtistHelper, self).__init__(nth_coord,
- value,
- )
- self.value = value
- self.grid_helper = grid_helper
- self._extremes = None, None
-
- self._get_line_path = None # a method that returns a Path.
- self._line_num_points = 100 # number of points to create a line
-
- def set_extremes(self, e1, e2):
- self._extremes = e1, e2
-
- def update_lim(self, axes):
- self.grid_helper.update_lim(axes)
-
- x1, x2 = axes.get_xlim()
- y1, y2 = axes.get_ylim()
- grid_finder = self.grid_helper.grid_finder
- extremes = grid_finder.extreme_finder(grid_finder.inv_transform_xy,
- x1, y1, x2, y2)
-
- extremes = list(extremes)
- e1, e2 = self._extremes # ranges of other coordinates
- if self.nth_coord == 0:
- if e1 is not None:
- extremes[2] = max(e1, extremes[2])
- if e2 is not None:
- extremes[3] = min(e2, extremes[3])
- elif self.nth_coord == 1:
- if e1 is not None:
- extremes[0] = max(e1, extremes[0])
- if e2 is not None:
- extremes[1] = min(e2, extremes[1])
-
- grid_info = dict()
- lon_min, lon_max, lat_min, lat_max = extremes
- lon_levs, lon_n, lon_factor = \
- grid_finder.grid_locator1(lon_min, lon_max)
- lat_levs, lat_n, lat_factor = \
- grid_finder.grid_locator2(lat_min, lat_max)
- grid_info["extremes"] = extremes
-
- grid_info["lon_info"] = lon_levs, lon_n, lon_factor
- grid_info["lat_info"] = lat_levs, lat_n, lat_factor
-
- grid_info["lon_labels"] = grid_finder.tick_formatter1("bottom",
- lon_factor,
- lon_levs)
-
- grid_info["lat_labels"] = grid_finder.tick_formatter2("bottom",
- lat_factor,
- lat_levs)
-
- grid_finder = self.grid_helper.grid_finder
-
- #e1, e2 = self._extremes # ranges of other coordinates
- if self.nth_coord == 0:
- xx0 = np.linspace(self.value, self.value, self._line_num_points)
- yy0 = np.linspace(extremes[2], extremes[3], self._line_num_points)
- xx, yy = grid_finder.transform_xy(xx0, yy0)
- elif self.nth_coord == 1:
- xx0 = np.linspace(extremes[0], extremes[1], self._line_num_points)
- yy0 = np.linspace(self.value, self.value, self._line_num_points)
- xx, yy = grid_finder.transform_xy(xx0, yy0)
-
- grid_info["line_xy"] = xx, yy
- self.grid_info = grid_info
-
- def get_axislabel_transform(self, axes):
- return Affine2D() #axes.transData
-
- def get_axislabel_pos_angle(self, axes):
-
- extremes = self.grid_info["extremes"]
-
- if self.nth_coord == 0:
- xx0 = self.value
- yy0 = (extremes[2]+extremes[3])/2.
- dxx, dyy = 0., abs(extremes[2]-extremes[3])/1000.
- elif self.nth_coord == 1:
- xx0 = (extremes[0]+extremes[1])/2.
- yy0 = self.value
- dxx, dyy = abs(extremes[0]-extremes[1])/1000., 0.
-
- grid_finder = self.grid_helper.grid_finder
- xx1, yy1 = grid_finder.transform_xy([xx0], [yy0])
-
- trans_passingthrough_point = axes.transData + axes.transAxes.inverted()
- p = trans_passingthrough_point.transform_point([xx1[0], yy1[0]])
-
-
- if (0. <= p[0] <= 1.) and (0. <= p[1] <= 1.):
- xx1c, yy1c = axes.transData.transform_point([xx1[0], yy1[0]])
- xx2, yy2 = grid_finder.transform_xy([xx0+dxx], [yy0+dyy])
- xx2c, yy2c = axes.transData.transform_point([xx2[0], yy2[0]])
-
- return (xx1c, yy1c), np.arctan2(yy2c-yy1c, xx2c-xx1c)/np.pi*180.
- else:
- return None, None
-
-
-
-
- def get_tick_transform(self, axes):
- return IdentityTransform() #axes.transData
-
- def get_tick_iterators(self, axes):
- """tick_loc, tick_angle, tick_label, (optionally) tick_label"""
-
- grid_finder = self.grid_helper.grid_finder
-
- lat_levs, lat_n, lat_factor = self.grid_info["lat_info"]
- lat_levs = np.asarray(lat_levs)
- if lat_factor is not None:
- yy0 = lat_levs / lat_factor
- dy = 0.01 / lat_factor
- else:
- yy0 = lat_levs
- dy = 0.01
-
- lon_levs, lon_n, lon_factor = self.grid_info["lon_info"]
- lon_levs = np.asarray(lon_levs)
- if lon_factor is not None:
- xx0 = lon_levs / lon_factor
- dx = 0.01 / lon_factor
- else:
- xx0 = lon_levs
- dx = 0.01
-
- if None in self._extremes:
- e0, e1 = self._extremes
- else:
- e0, e1 = sorted(self._extremes)
- if e0 is None:
- e0 = -np.inf
- if e1 is None:
- e1 = np.inf
-
- if self.nth_coord == 0:
- mask = (e0 <= yy0) & (yy0 <= e1)
- #xx0, yy0 = xx0[mask], yy0[mask]
- yy0 = yy0[mask]
- elif self.nth_coord == 1:
- mask = (e0 <= xx0) & (xx0 <= e1)
- #xx0, yy0 = xx0[mask], yy0[mask]
- xx0 = xx0[mask]
-
- def transform_xy(x, y):
- x1, y1 = grid_finder.transform_xy(x, y)
- x2y2 = axes.transData.transform(np.array([x1, y1]).transpose())
- x2, y2 = x2y2.transpose()
- return x2, y2
-
- # find angles
- if self.nth_coord == 0:
- xx0 = np.empty_like(yy0)
- xx0.fill(self.value)
-
- xx1, yy1 = transform_xy(xx0, yy0)
-
- xx00 = xx0.copy()
- xx00[xx0+dx>e1] -= dx
- xx1a, yy1a = transform_xy(xx00, yy0)
- xx1b, yy1b = transform_xy(xx00+dx, yy0)
-
- xx2a, yy2a = transform_xy(xx0, yy0)
- xx2b, yy2b = transform_xy(xx0, yy0+dy)
-
- labels = self.grid_info["lat_labels"]
- labels = [l for l, m in zip(labels, mask) if m]
-
- elif self.nth_coord == 1:
- yy0 = np.empty_like(xx0)
- yy0.fill(self.value)
-
- xx1, yy1 = transform_xy(xx0, yy0)
-
- xx1a, yy1a = transform_xy(xx0, yy0)
- xx1b, yy1b = transform_xy(xx0, yy0+dy)
-
- xx00 = xx0.copy()
- xx00[xx0+dx>e1] -= dx
- xx2a, yy2a = transform_xy(xx00, yy0)
- xx2b, yy2b = transform_xy(xx00+dx, yy0)
-
- labels = self.grid_info["lon_labels"]
- labels = [l for l, m in zip(labels, mask) if m]
-
-
- def f1():
- dd = np.arctan2(yy1b-yy1a, xx1b-xx1a) # angle normal
- dd2 = np.arctan2(yy2b-yy2a, xx2b-xx2a) # angle tangent
- mm = ((yy1b-yy1a)==0.) & ((xx1b-xx1a)==0.) # mask where dd1 is not defined
- dd[mm] = dd2[mm] + np.pi / 2
- #dd = np.arctan2(yy2-yy1, xx2-xx1) # angle normal
- #dd2 = np.arctan2(yy3-yy1, xx3-xx1) # angle tangent
- #mm = ((yy2-yy1)==0.) & ((xx2-xx1)==0.) # mask where dd1 is not defined
- #dd[mm] = dd2[mm] + np.pi / 2
-
- #dd += np.pi
-
- #dd = np.arctan2(xx2-xx1, angle_tangent-yy1)
- trans_tick = self.get_tick_transform(axes)
- tr2ax = trans_tick + axes.transAxes.inverted()
- for x, y, d, d2, lab in zip(xx1, yy1, dd, dd2, labels):
- c2 = tr2ax.transform_point((x, y))
- delta=0.00001
- if (0. -delta<= c2[0] <= 1.+delta) and \
- (0. -delta<= c2[1] <= 1.+delta):
- d1 = d/3.14159*180.
- d2 = d2/3.14159*180.
- yield [x, y], d1, d2, lab
-
- return f1(), iter([])
-
- def get_line_transform(self, axes):
- return axes.transData
-
- def get_line(self, axes):
- self.update_lim(axes)
- x, y = self.grid_info["line_xy"]
-
- if self._get_line_path is None:
- return Path(np.column_stack([x, y]))
- else:
- return self._get_line_path(axes, x, y)
-
-
-
-
-class GridHelperCurveLinear(GridHelperBase):
-
- def __init__(self, aux_trans,
- extreme_finder=None,
- grid_locator1=None,
- grid_locator2=None,
- tick_formatter1=None,
- tick_formatter2=None):
- """
- aux_trans : a transform from the source (curved) coordinate to
- target (rectilinear) coordinate. An instance of MPL's Transform
- (inverse transform should be defined) or a tuple of two callable
- objects which defines the transform and its inverse. The callables
- need take two arguments of array of source coordinates and
- should return two target coordinates.
-
- e.g., ``x2, y2 = trans(x1, y1)``
- """
- super(GridHelperCurveLinear, self).__init__()
-
- self.grid_info = None
- self._old_values = None
- #self._grid_params = dict()
- self._aux_trans = aux_trans
-
- self.grid_finder = GridFinder(aux_trans,
- extreme_finder,
- grid_locator1,
- grid_locator2,
- tick_formatter1,
- tick_formatter2)
-
-
- def update_grid_finder(self, aux_trans=None, **kw):
-
- if aux_trans is not None:
- self.grid_finder.update_transform(aux_trans)
-
- self.grid_finder.update(**kw)
- self.invalidate()
-
-
- def _update(self, x1, x2, y1, y2):
- "bbox in 0-based image coordinates"
- # update wcsgrid
-
- if self.valid() and self._old_values == (x1, x2, y1, y2):
- return
-
- self._update_grid(x1, y1, x2, y2)
-
- self._old_values = (x1, x2, y1, y2)
-
- self._force_update = False
-
-
- def new_fixed_axis(self, loc,
- nth_coord=None,
- axis_direction=None,
- offset=None,
- axes=None):
-
-
- if axes is None:
- axes = self.axes
-
- if axis_direction is None:
- axis_direction = loc
- _helper = FixedAxisArtistHelper(self, loc,
- #nth_coord,
- nth_coord_ticks=nth_coord,
- )
-
- axisline = AxisArtist(axes, _helper, axis_direction=axis_direction)
-
- return axisline
-
-
- def new_floating_axis(self, nth_coord,
- value,
- axes=None,
- axis_direction="bottom"
- ):
-
- if axes is None:
- axes = self.axes
-
- _helper = FloatingAxisArtistHelper(
- self, nth_coord, value, axis_direction)
-
- axisline = AxisArtist(axes, _helper)
-
- #_helper = FloatingAxisArtistHelper(self, nth_coord,
- # value,
- # label_direction=label_direction,
- # )
-
- #axisline = AxisArtistFloating(axes, _helper,
- # axis_direction=axis_direction)
- axisline.line.set_clip_on(True)
- axisline.line.set_clip_box(axisline.axes.bbox)
- #axisline.major_ticklabels.set_visible(True)
- #axisline.minor_ticklabels.set_visible(False)
-
- #axisline.major_ticklabels.set_rotate_along_line(True)
- #axisline.set_rotate_label_along_line(True)
-
- return axisline
-
-
- def _update_grid(self, x1, y1, x2, y2):
-
- self.grid_info = self.grid_finder.get_grid_info(x1, y1, x2, y2)
-
-
- def get_gridlines(self, which="major", axis="both"):
- grid_lines = []
-
- if axis in ["both", "x"]:
- for gl in self.grid_info["lon"]["lines"]:
- grid_lines.extend(gl)
- if axis in ["both", "y"]:
- for gl in self.grid_info["lat"]["lines"]:
- grid_lines.extend(gl)
-
- return grid_lines
-
-
- def get_tick_iterator(self, nth_coord, axis_side, minor=False):
-
- #axisnr = dict(left=0, bottom=1, right=2, top=3)[axis_side]
- angle_tangent = dict(left=90, right=90, bottom=0, top=0)[axis_side]
- #angle = [0, 90, 180, 270][axisnr]
- lon_or_lat = ["lon", "lat"][nth_coord]
- if not minor: # major ticks
- def f():
- for (xy, a), l in zip(self.grid_info[lon_or_lat]["tick_locs"][axis_side],
- self.grid_info[lon_or_lat]["tick_labels"][axis_side]):
- angle_normal = a
- yield xy, angle_normal, angle_tangent, l
- else:
- def f():
- for (xy, a), l in zip(self.grid_info[lon_or_lat]["tick_locs"][axis_side],
- self.grid_info[lon_or_lat]["tick_labels"][axis_side]):
- angle_normal = a
- yield xy, angle_normal, angle_tangent, ""
- #for xy, a, l in self.grid_info[lon_or_lat]["ticks"][axis_side]:
- # yield xy, a, ""
-
- return f()
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/parasite_axes.py b/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/parasite_axes.py
deleted file mode 100644
index cad56e43a2..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/axisartist/parasite_axes.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-from mpl_toolkits.axes_grid1.parasite_axes import (
- host_axes_class_factory, parasite_axes_class_factory,
- parasite_axes_auxtrans_class_factory, subplot_class_factory)
-
-from .axislines import Axes
-
-
-ParasiteAxes = parasite_axes_class_factory(Axes)
-
-ParasiteAxesAuxTrans = \
- parasite_axes_auxtrans_class_factory(axes_class=ParasiteAxes)
-
-HostAxes = host_axes_class_factory(axes_class=Axes)
-
-SubplotHost = subplot_class_factory(HostAxes)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/__init__.py b/contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/__init__.py
deleted file mode 100644
index cd9c2139d2..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-from .axes3d import Axes3D
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/art3d.py b/contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/art3d.py
deleted file mode 100644
index ef55dd693e..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/art3d.py
+++ /dev/null
@@ -1,774 +0,0 @@
-# art3d.py, original mplot3d version by John Porter
-# Parts rewritten by Reinier Heeres <reinier@heeres.eu>
-# Minor additions by Ben Axelrod <baxelrod@coroware.com>
-
-'''
-Module containing 3D artist code and functions to convert 2D
-artists into 3D versions which can be added to an Axes3D.
-'''
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import zip
-
-import math
-
-import numpy as np
-
-from matplotlib import (
- artist, cbook, colors as mcolors, lines, text as mtext, path as mpath)
-from matplotlib.cbook import _backports
-from matplotlib.collections import (
- Collection, LineCollection, PolyCollection, PatchCollection,
- PathCollection)
-from matplotlib.colors import Normalize
-from matplotlib.patches import Patch
-from . import proj3d
-
-
-def norm_angle(a):
- """Return angle between -180 and +180"""
- a = (a + 360) % 360
- if a > 180:
- a = a - 360
- return a
-
-
-def norm_text_angle(a):
- """Return angle between -90 and +90"""
- a = (a + 180) % 180
- if a > 90:
- a = a - 180
- return a
-
-
-def get_dir_vector(zdir):
- if zdir == 'x':
- return np.array((1, 0, 0))
- elif zdir == 'y':
- return np.array((0, 1, 0))
- elif zdir == 'z':
- return np.array((0, 0, 1))
- elif zdir is None:
- return np.array((0, 0, 0))
- elif cbook.iterable(zdir) and len(zdir) == 3:
- return zdir
- else:
- raise ValueError("'x', 'y', 'z', None or vector of length 3 expected")
-
-
-class Text3D(mtext.Text):
- '''
- Text object with 3D position and (in the future) direction.
- '''
-
- def __init__(self, x=0, y=0, z=0, text='', zdir='z', **kwargs):
- '''
- *x*, *y*, *z* Position of text
- *text* Text string to display
- *zdir* Direction of text
-
- Keyword arguments are passed onto :func:`~matplotlib.text.Text`.
- '''
- mtext.Text.__init__(self, x, y, text, **kwargs)
- self.set_3d_properties(z, zdir)
-
- def set_3d_properties(self, z=0, zdir='z'):
- x, y = self.get_position()
- self._position3d = np.array((x, y, z))
- self._dir_vec = get_dir_vector(zdir)
- self.stale = True
-
- def draw(self, renderer):
- proj = proj3d.proj_trans_points(
- [self._position3d, self._position3d + self._dir_vec], renderer.M)
- dx = proj[0][1] - proj[0][0]
- dy = proj[1][1] - proj[1][0]
- if dx==0. and dy==0.:
- # atan2 raises ValueError: math domain error on 0,0
- angle = 0.
- else:
- angle = math.degrees(math.atan2(dy, dx))
- self.set_position((proj[0][0], proj[1][0]))
- self.set_rotation(norm_text_angle(angle))
- mtext.Text.draw(self, renderer)
- self.stale = False
-
-
-def text_2d_to_3d(obj, z=0, zdir='z'):
- """Convert a Text to a Text3D object."""
- obj.__class__ = Text3D
- obj.set_3d_properties(z, zdir)
-
-
-class Line3D(lines.Line2D):
- '''
- 3D line object.
- '''
-
- def __init__(self, xs, ys, zs, *args, **kwargs):
- '''
- Keyword arguments are passed onto :func:`~matplotlib.lines.Line2D`.
- '''
- lines.Line2D.__init__(self, [], [], *args, **kwargs)
- self._verts3d = xs, ys, zs
-
- def set_3d_properties(self, zs=0, zdir='z'):
- xs = self.get_xdata()
- ys = self.get_ydata()
-
- try:
- # If *zs* is a list or array, then this will fail and
- # just proceed to juggle_axes().
- zs = float(zs)
- zs = [zs for x in xs]
- except TypeError:
- pass
- self._verts3d = juggle_axes(xs, ys, zs, zdir)
- self.stale = True
-
- def draw(self, renderer):
- xs3d, ys3d, zs3d = self._verts3d
- xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M)
- self.set_data(xs, ys)
- lines.Line2D.draw(self, renderer)
- self.stale = False
-
-
-def line_2d_to_3d(line, zs=0, zdir='z'):
- '''
- Convert a 2D line to 3D.
- '''
- line.__class__ = Line3D
- line.set_3d_properties(zs, zdir)
-
-
-def path_to_3d_segment(path, zs=0, zdir='z'):
- '''Convert a path to a 3D segment.'''
-
- zs = _backports.broadcast_to(zs, len(path))
- pathsegs = path.iter_segments(simplify=False, curves=False)
- seg = [(x, y, z) for (((x, y), code), z) in zip(pathsegs, zs)]
- seg3d = [juggle_axes(x, y, z, zdir) for (x, y, z) in seg]
- return seg3d
-
-
-def paths_to_3d_segments(paths, zs=0, zdir='z'):
- '''
- Convert paths from a collection object to 3D segments.
- '''
-
- zs = _backports.broadcast_to(zs, len(paths))
- segs = [path_to_3d_segment(path, pathz, zdir)
- for path, pathz in zip(paths, zs)]
- return segs
-
-
-def path_to_3d_segment_with_codes(path, zs=0, zdir='z'):
- '''Convert a path to a 3D segment with path codes.'''
-
- zs = _backports.broadcast_to(zs, len(path))
- seg = []
- codes = []
- pathsegs = path.iter_segments(simplify=False, curves=False)
- for (((x, y), code), z) in zip(pathsegs, zs):
- seg.append((x, y, z))
- codes.append(code)
- seg3d = [juggle_axes(x, y, z, zdir) for (x, y, z) in seg]
- return seg3d, codes
-
-
-def paths_to_3d_segments_with_codes(paths, zs=0, zdir='z'):
- '''
- Convert paths from a collection object to 3D segments with path codes.
- '''
-
- zs = _backports.broadcast_to(zs, len(paths))
- segments = []
- codes_list = []
- for path, pathz in zip(paths, zs):
- segs, codes = path_to_3d_segment_with_codes(path, pathz, zdir)
- segments.append(segs)
- codes_list.append(codes)
- return segments, codes_list
-
-
-class Line3DCollection(LineCollection):
- '''
- A collection of 3D lines.
- '''
-
- def __init__(self, segments, *args, **kwargs):
- '''
- Keyword arguments are passed onto :func:`~matplotlib.collections.LineCollection`.
- '''
- LineCollection.__init__(self, segments, *args, **kwargs)
-
- def set_sort_zpos(self, val):
- '''Set the position to use for z-sorting.'''
- self._sort_zpos = val
- self.stale = True
-
- def set_segments(self, segments):
- '''
- Set 3D segments
- '''
- self._segments3d = np.asanyarray(segments)
- LineCollection.set_segments(self, [])
-
- def do_3d_projection(self, renderer):
- '''
- Project the points according to renderer matrix.
- '''
- xyslist = [
- proj3d.proj_trans_points(points, renderer.M) for points in
- self._segments3d]
- segments_2d = [np.column_stack([xs, ys]) for xs, ys, zs in xyslist]
- LineCollection.set_segments(self, segments_2d)
-
- # FIXME
- minz = 1e9
- for xs, ys, zs in xyslist:
- minz = min(minz, min(zs))
- return minz
-
- def draw(self, renderer, project=False):
- if project:
- self.do_3d_projection(renderer)
- LineCollection.draw(self, renderer)
-
-
-def line_collection_2d_to_3d(col, zs=0, zdir='z'):
- """Convert a LineCollection to a Line3DCollection object."""
- segments3d = paths_to_3d_segments(col.get_paths(), zs, zdir)
- col.__class__ = Line3DCollection
- col.set_segments(segments3d)
-
-
-class Patch3D(Patch):
- '''
- 3D patch object.
- '''
-
- def __init__(self, *args, **kwargs):
- zs = kwargs.pop('zs', [])
- zdir = kwargs.pop('zdir', 'z')
- Patch.__init__(self, *args, **kwargs)
- self.set_3d_properties(zs, zdir)
-
- def set_3d_properties(self, verts, zs=0, zdir='z'):
- zs = _backports.broadcast_to(zs, len(verts))
- self._segment3d = [juggle_axes(x, y, z, zdir)
- for ((x, y), z) in zip(verts, zs)]
- self._facecolor3d = Patch.get_facecolor(self)
-
- def get_path(self):
- return self._path2d
-
- def get_facecolor(self):
- return self._facecolor2d
-
- def do_3d_projection(self, renderer):
- s = self._segment3d
- xs, ys, zs = zip(*s)
- vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs, renderer.M)
- self._path2d = mpath.Path(np.column_stack([vxs, vys]))
- # FIXME: coloring
- self._facecolor2d = self._facecolor3d
- return min(vzs)
-
- def draw(self, renderer):
- Patch.draw(self, renderer)
-
-
-class PathPatch3D(Patch3D):
- '''
- 3D PathPatch object.
- '''
-
- def __init__(self, path, **kwargs):
- zs = kwargs.pop('zs', [])
- zdir = kwargs.pop('zdir', 'z')
- Patch.__init__(self, **kwargs)
- self.set_3d_properties(path, zs, zdir)
-
- def set_3d_properties(self, path, zs=0, zdir='z'):
- Patch3D.set_3d_properties(self, path.vertices, zs=zs, zdir=zdir)
- self._code3d = path.codes
-
- def do_3d_projection(self, renderer):
- s = self._segment3d
- xs, ys, zs = zip(*s)
- vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs, renderer.M)
- self._path2d = mpath.Path(np.column_stack([vxs, vys]), self._code3d)
- # FIXME: coloring
- self._facecolor2d = self._facecolor3d
- return min(vzs)
-
-
-def get_patch_verts(patch):
- """Return a list of vertices for the path of a patch."""
- trans = patch.get_patch_transform()
- path = patch.get_path()
- polygons = path.to_polygons(trans)
- if len(polygons):
- return polygons[0]
- else:
- return []
-
-
-def patch_2d_to_3d(patch, z=0, zdir='z'):
- """Convert a Patch to a Patch3D object."""
- verts = get_patch_verts(patch)
- patch.__class__ = Patch3D
- patch.set_3d_properties(verts, z, zdir)
-
-
-def pathpatch_2d_to_3d(pathpatch, z=0, zdir='z'):
- """Convert a PathPatch to a PathPatch3D object."""
- path = pathpatch.get_path()
- trans = pathpatch.get_patch_transform()
-
- mpath = trans.transform_path(path)
- pathpatch.__class__ = PathPatch3D
- pathpatch.set_3d_properties(mpath, z, zdir)
-
-
-class Patch3DCollection(PatchCollection):
- '''
- A collection of 3D patches.
- '''
-
- def __init__(self, *args, **kwargs):
- """
- Create a collection of flat 3D patches with its normal vector
- pointed in *zdir* direction, and located at *zs* on the *zdir*
- axis. 'zs' can be a scalar or an array-like of the same length as
- the number of patches in the collection.
-
- Constructor arguments are the same as for
- :class:`~matplotlib.collections.PatchCollection`. In addition,
- keywords *zs=0* and *zdir='z'* are available.
-
- Also, the keyword argument "depthshade" is available to
- indicate whether or not to shade the patches in order to
- give the appearance of depth (default is *True*).
- This is typically desired in scatter plots.
- """
- zs = kwargs.pop('zs', 0)
- zdir = kwargs.pop('zdir', 'z')
- self._depthshade = kwargs.pop('depthshade', True)
- PatchCollection.__init__(self, *args, **kwargs)
- self.set_3d_properties(zs, zdir)
-
- def set_sort_zpos(self, val):
- '''Set the position to use for z-sorting.'''
- self._sort_zpos = val
- self.stale = True
-
- def set_3d_properties(self, zs, zdir):
- # Force the collection to initialize the face and edgecolors
- # just in case it is a scalarmappable with a colormap.
- self.update_scalarmappable()
- offsets = self.get_offsets()
- if len(offsets) > 0:
- xs, ys = zip(*offsets)
- else:
- xs = []
- ys = []
- self._offsets3d = juggle_axes(xs, ys, np.atleast_1d(zs), zdir)
- self._facecolor3d = self.get_facecolor()
- self._edgecolor3d = self.get_edgecolor()
- self.stale = True
-
- def do_3d_projection(self, renderer):
- xs, ys, zs = self._offsets3d
- vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs, renderer.M)
-
- fcs = (zalpha(self._facecolor3d, vzs) if self._depthshade else
- self._facecolor3d)
- fcs = mcolors.to_rgba_array(fcs, self._alpha)
- self.set_facecolors(fcs)
-
- ecs = (zalpha(self._edgecolor3d, vzs) if self._depthshade else
- self._edgecolor3d)
- ecs = mcolors.to_rgba_array(ecs, self._alpha)
- self.set_edgecolors(ecs)
- PatchCollection.set_offsets(self, np.column_stack([vxs, vys]))
-
- if vzs.size > 0:
- return min(vzs)
- else:
- return np.nan
-
-
-class Path3DCollection(PathCollection):
- '''
- A collection of 3D paths.
- '''
-
- def __init__(self, *args, **kwargs):
- """
- Create a collection of flat 3D paths with its normal vector
- pointed in *zdir* direction, and located at *zs* on the *zdir*
- axis. 'zs' can be a scalar or an array-like of the same length as
- the number of paths in the collection.
-
- Constructor arguments are the same as for
- :class:`~matplotlib.collections.PathCollection`. In addition,
- keywords *zs=0* and *zdir='z'* are available.
-
- Also, the keyword argument "depthshade" is available to
- indicate whether or not to shade the patches in order to
- give the appearance of depth (default is *True*).
- This is typically desired in scatter plots.
- """
- zs = kwargs.pop('zs', 0)
- zdir = kwargs.pop('zdir', 'z')
- self._depthshade = kwargs.pop('depthshade', True)
- PathCollection.__init__(self, *args, **kwargs)
- self.set_3d_properties(zs, zdir)
-
- def set_sort_zpos(self, val):
- '''Set the position to use for z-sorting.'''
- self._sort_zpos = val
- self.stale = True
-
- def set_3d_properties(self, zs, zdir):
- # Force the collection to initialize the face and edgecolors
- # just in case it is a scalarmappable with a colormap.
- self.update_scalarmappable()
- offsets = self.get_offsets()
- if len(offsets) > 0:
- xs, ys = zip(*offsets)
- else:
- xs = []
- ys = []
- self._offsets3d = juggle_axes(xs, ys, np.atleast_1d(zs), zdir)
- self._facecolor3d = self.get_facecolor()
- self._edgecolor3d = self.get_edgecolor()
- self.stale = True
-
- def do_3d_projection(self, renderer):
- xs, ys, zs = self._offsets3d
- vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs, renderer.M)
-
- fcs = (zalpha(self._facecolor3d, vzs) if self._depthshade else
- self._facecolor3d)
- fcs = mcolors.to_rgba_array(fcs, self._alpha)
- self.set_facecolors(fcs)
-
- ecs = (zalpha(self._edgecolor3d, vzs) if self._depthshade else
- self._edgecolor3d)
- ecs = mcolors.to_rgba_array(ecs, self._alpha)
- self.set_edgecolors(ecs)
- PathCollection.set_offsets(self, np.column_stack([vxs, vys]))
-
- if vzs.size > 0 :
- return min(vzs)
- else :
- return np.nan
-
-
-def patch_collection_2d_to_3d(col, zs=0, zdir='z', depthshade=True):
- """
- Convert a :class:`~matplotlib.collections.PatchCollection` into a
- :class:`Patch3DCollection` object
- (or a :class:`~matplotlib.collections.PathCollection` into a
- :class:`Path3DCollection` object).
-
- Keywords:
-
- *za* The location or locations to place the patches in the
- collection along the *zdir* axis. Defaults to 0.
-
- *zdir* The axis in which to place the patches. Default is "z".
-
- *depthshade* Whether to shade the patches to give a sense of depth.
- Defaults to *True*.
-
- """
- if isinstance(col, PathCollection):
- col.__class__ = Path3DCollection
- elif isinstance(col, PatchCollection):
- col.__class__ = Patch3DCollection
- col._depthshade = depthshade
- col.set_3d_properties(zs, zdir)
-
-
-class Poly3DCollection(PolyCollection):
- '''
- A collection of 3D polygons.
- '''
-
- def __init__(self, verts, *args, **kwargs):
- '''
- Create a Poly3DCollection.
-
- *verts* should contain 3D coordinates.
-
- Keyword arguments:
- zsort, see set_zsort for options.
-
- Note that this class does a bit of magic with the _facecolors
- and _edgecolors properties.
- '''
- zsort = kwargs.pop('zsort', True)
- PolyCollection.__init__(self, verts, *args, **kwargs)
- self.set_zsort(zsort)
- self._codes3d = None
-
- _zsort_functions = {
- 'average': np.average,
- 'min': np.min,
- 'max': np.max,
- }
-
- def set_zsort(self, zsort):
- '''
- Set z-sorting behaviour:
- boolean: if True use default 'average'
- string: 'average', 'min' or 'max'
- '''
-
- if zsort is True:
- zsort = 'average'
-
- if zsort is not False:
- if zsort in self._zsort_functions:
- zsortfunc = self._zsort_functions[zsort]
- else:
- return False
- else:
- zsortfunc = None
-
- self._zsort = zsort
- self._sort_zpos = None
- self._zsortfunc = zsortfunc
- self.stale = True
-
- def get_vector(self, segments3d):
- """Optimize points for projection"""
- si = 0
- ei = 0
- segis = []
- points = []
- for p in segments3d:
- points.extend(p)
- ei = si + len(p)
- segis.append((si, ei))
- si = ei
-
- if len(segments3d):
- xs, ys, zs = zip(*points)
- else :
- # We need this so that we can skip the bad unpacking from zip()
- xs, ys, zs = [], [], []
-
- ones = np.ones(len(xs))
- self._vec = np.array([xs, ys, zs, ones])
- self._segis = segis
-
- def set_verts(self, verts, closed=True):
- '''Set 3D vertices.'''
- self.get_vector(verts)
- # 2D verts will be updated at draw time
- PolyCollection.set_verts(self, [], False)
- self._closed = closed
-
- def set_verts_and_codes(self, verts, codes):
- '''Sets 3D vertices with path codes'''
- # set vertices with closed=False to prevent PolyCollection from
- # setting path codes
- self.set_verts(verts, closed=False)
- # and set our own codes instead.
- self._codes3d = codes
-
- def set_3d_properties(self):
- # Force the collection to initialize the face and edgecolors
- # just in case it is a scalarmappable with a colormap.
- self.update_scalarmappable()
- self._sort_zpos = None
- self.set_zsort(True)
- self._facecolors3d = PolyCollection.get_facecolors(self)
- self._edgecolors3d = PolyCollection.get_edgecolors(self)
- self._alpha3d = PolyCollection.get_alpha(self)
- self.stale = True
-
- def set_sort_zpos(self,val):
- '''Set the position to use for z-sorting.'''
- self._sort_zpos = val
- self.stale = True
-
- def do_3d_projection(self, renderer):
- '''
- Perform the 3D projection for this object.
- '''
- # FIXME: This may no longer be needed?
- if self._A is not None:
- self.update_scalarmappable()
- self._facecolors3d = self._facecolors
-
- txs, tys, tzs = proj3d.proj_transform_vec(self._vec, renderer.M)
- xyzlist = [(txs[si:ei], tys[si:ei], tzs[si:ei])
- for si, ei in self._segis]
-
- # This extra fuss is to re-order face / edge colors
- cface = self._facecolors3d
- cedge = self._edgecolors3d
- if len(cface) != len(xyzlist):
- cface = cface.repeat(len(xyzlist), axis=0)
- if len(cedge) != len(xyzlist):
- if len(cedge) == 0:
- cedge = cface
- else:
- cedge = cedge.repeat(len(xyzlist), axis=0)
-
- # if required sort by depth (furthest drawn first)
- if self._zsort:
- z_segments_2d = sorted(
- ((self._zsortfunc(zs), np.column_stack([xs, ys]), fc, ec, idx)
- for idx, ((xs, ys, zs), fc, ec)
- in enumerate(zip(xyzlist, cface, cedge))),
- key=lambda x: x[0], reverse=True)
- else:
- raise ValueError("whoops")
-
- segments_2d = [s for z, s, fc, ec, idx in z_segments_2d]
- if self._codes3d is not None:
- codes = [self._codes3d[idx] for z, s, fc, ec, idx in z_segments_2d]
- PolyCollection.set_verts_and_codes(self, segments_2d, codes)
- else:
- PolyCollection.set_verts(self, segments_2d, self._closed)
-
- self._facecolors2d = [fc for z, s, fc, ec, idx in z_segments_2d]
- if len(self._edgecolors3d) == len(cface):
- self._edgecolors2d = [ec for z, s, fc, ec, idx in z_segments_2d]
- else:
- self._edgecolors2d = self._edgecolors3d
-
- # Return zorder value
- if self._sort_zpos is not None:
- zvec = np.array([[0], [0], [self._sort_zpos], [1]])
- ztrans = proj3d.proj_transform_vec(zvec, renderer.M)
- return ztrans[2][0]
- elif tzs.size > 0 :
- # FIXME: Some results still don't look quite right.
- # In particular, examine contourf3d_demo2.py
- # with az = -54 and elev = -45.
- return np.min(tzs)
- else :
- return np.nan
-
- def set_facecolor(self, colors):
- PolyCollection.set_facecolor(self, colors)
- self._facecolors3d = PolyCollection.get_facecolor(self)
- set_facecolors = set_facecolor
-
- def set_edgecolor(self, colors):
- PolyCollection.set_edgecolor(self, colors)
- self._edgecolors3d = PolyCollection.get_edgecolor(self)
- set_edgecolors = set_edgecolor
-
- def set_alpha(self, alpha):
- """
- Set the alpha tranparencies of the collection. *alpha* must be
- a float or *None*.
-
- ACCEPTS: float or None
- """
- if alpha is not None:
- try:
- float(alpha)
- except TypeError:
- raise TypeError('alpha must be a float or None')
- artist.Artist.set_alpha(self, alpha)
- try:
- self._facecolors = mcolors.to_rgba_array(
- self._facecolors3d, self._alpha)
- except (AttributeError, TypeError, IndexError):
- pass
- try:
- self._edgecolors = mcolors.to_rgba_array(
- self._edgecolors3d, self._alpha)
- except (AttributeError, TypeError, IndexError):
- pass
- self.stale = True
-
- def get_facecolors(self):
- return self._facecolors2d
- get_facecolor = get_facecolors
-
- def get_edgecolors(self):
- return self._edgecolors2d
- get_edgecolor = get_edgecolors
-
- def draw(self, renderer):
- return Collection.draw(self, renderer)
-
-
-def poly_collection_2d_to_3d(col, zs=0, zdir='z'):
- """Convert a PolyCollection to a Poly3DCollection object."""
- segments_3d, codes = paths_to_3d_segments_with_codes(col.get_paths(),
- zs, zdir)
- col.__class__ = Poly3DCollection
- col.set_verts_and_codes(segments_3d, codes)
- col.set_3d_properties()
-
-
-def juggle_axes(xs, ys, zs, zdir):
- """
- Reorder coordinates so that 2D xs, ys can be plotted in the plane
- orthogonal to zdir. zdir is normally x, y or z. However, if zdir
- starts with a '-' it is interpreted as a compensation for rotate_axes.
- """
- if zdir == 'x':
- return zs, xs, ys
- elif zdir == 'y':
- return xs, zs, ys
- elif zdir[0] == '-':
- return rotate_axes(xs, ys, zs, zdir)
- else:
- return xs, ys, zs
-
-
-def rotate_axes(xs, ys, zs, zdir):
- """
- Reorder coordinates so that the axes are rotated with zdir along
- the original z axis. Prepending the axis with a '-' does the
- inverse transform, so zdir can be x, -x, y, -y, z or -z
- """
- if zdir == 'x':
- return ys, zs, xs
- elif zdir == '-x':
- return zs, xs, ys
-
- elif zdir == 'y':
- return zs, xs, ys
- elif zdir == '-y':
- return ys, zs, xs
-
- else:
- return xs, ys, zs
-
-
-def get_colors(c, num):
- """Stretch the color argument to provide the required number num"""
- return _backports.broadcast_to(
- mcolors.to_rgba_array(c) if len(c) else [0, 0, 0, 0],
- (num, 4))
-
-
-def zalpha(colors, zs):
- """Modify the alphas of the color list according to depth"""
- # FIXME: This only works well if the points for *zs* are well-spaced
- # in all three dimensions. Otherwise, at certain orientations,
- # the min and max zs are very close together.
- # Should really normalize against the viewing depth.
- colors = get_colors(colors, len(zs))
- if len(zs):
- norm = Normalize(min(zs), max(zs))
- sats = 1 - norm(zs) * 0.7
- colors = [(c[0], c[1], c[2], c[3] * s) for c, s in zip(colors, sats)]
- return colors
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/axes3d.py b/contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/axes3d.py
deleted file mode 100644
index b99a090c62..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/axes3d.py
+++ /dev/null
@@ -1,2958 +0,0 @@
-"""
-axes3d.py, original mplot3d version by John Porter
-Created: 23 Sep 2005
-
-Parts fixed by Reinier Heeres <reinier@heeres.eu>
-Minor additions by Ben Axelrod <baxelrod@coroware.com>
-Significant updates and revisions by Ben Root <ben.v.root@gmail.com>
-
-Module containing Axes3D, an object which can plot 3D objects on a
-2D matplotlib figure.
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import map, xrange, zip, reduce
-
-import math
-import warnings
-from collections import defaultdict
-
-import numpy as np
-
-import matplotlib.axes as maxes
-import matplotlib.cbook as cbook
-import matplotlib.collections as mcoll
-import matplotlib.colors as mcolors
-import matplotlib.docstring as docstring
-import matplotlib.scale as mscale
-import matplotlib.transforms as mtransforms
-from matplotlib.axes import Axes, rcParams
-from matplotlib.cbook import _backports
-from matplotlib.colors import Normalize, LightSource
-from matplotlib.transforms import Bbox
-from matplotlib.tri.triangulation import Triangulation
-
-from . import art3d
-from . import proj3d
-from . import axis3d
-
-
-def unit_bbox():
- box = Bbox(np.array([[0, 0], [1, 1]]))
- return box
-
-
-class Axes3D(Axes):
- """
- 3D axes object.
- """
- name = '3d'
- _shared_z_axes = cbook.Grouper()
-
- def __init__(self, fig, rect=None, *args, **kwargs):
- '''
- Build an :class:`Axes3D` instance in
- :class:`~matplotlib.figure.Figure` *fig* with
- *rect=[left, bottom, width, height]* in
- :class:`~matplotlib.figure.Figure` coordinates
-
- Optional keyword arguments:
-
- ================ =========================================
- Keyword Description
- ================ =========================================
- *azim* Azimuthal viewing angle (default -60)
- *elev* Elevation viewing angle (default 30)
- *zscale* [%(scale)s]
- *sharez* Other axes to share z-limits with
- *proj_type* 'persp' or 'ortho' (default 'persp')
- ================ =========================================
-
- .. versionadded :: 1.2.1
- *sharez*
-
- ''' % {'scale': ' | '.join([repr(x) for x in mscale.get_scale_names()])}
-
- if rect is None:
- rect = [0.0, 0.0, 1.0, 1.0]
- self._cids = []
-
- self.initial_azim = kwargs.pop('azim', -60)
- self.initial_elev = kwargs.pop('elev', 30)
- zscale = kwargs.pop('zscale', None)
- sharez = kwargs.pop('sharez', None)
- self.set_proj_type(kwargs.pop('proj_type', 'persp'))
-
- self.xy_viewLim = unit_bbox()
- self.zz_viewLim = unit_bbox()
- self.xy_dataLim = unit_bbox()
- self.zz_dataLim = unit_bbox()
- # inihibit autoscale_view until the axes are defined
- # they can't be defined until Axes.__init__ has been called
- self.view_init(self.initial_elev, self.initial_azim)
- self._ready = 0
-
- self._sharez = sharez
- if sharez is not None:
- self._shared_z_axes.join(self, sharez)
- self._adjustable = 'datalim'
-
- super(Axes3D, self).__init__(fig, rect,
- frameon=True,
- *args, **kwargs)
- # Disable drawing of axes by base class
- super(Axes3D, self).set_axis_off()
- # Enable drawing of axes by Axes3D class
- self.set_axis_on()
- self.M = None
-
- # func used to format z -- fall back on major formatters
- self.fmt_zdata = None
-
- if zscale is not None:
- self.set_zscale(zscale)
-
- if self.zaxis is not None:
- self._zcid = self.zaxis.callbacks.connect(
- 'units finalize', lambda: self._on_units_changed(scalez=True))
- else:
- self._zcid = None
-
- self._ready = 1
- self.mouse_init()
- self.set_top_view()
-
- self.patch.set_linewidth(0)
- # Calculate the pseudo-data width and height
- pseudo_bbox = self.transLimits.inverted().transform([(0, 0), (1, 1)])
- self._pseudo_w, self._pseudo_h = pseudo_bbox[1] - pseudo_bbox[0]
-
- self.figure.add_axes(self)
-
- def set_axis_off(self):
- self._axis3don = False
- self.stale = True
-
- def set_axis_on(self):
- self._axis3don = True
- self.stale = True
-
- def have_units(self):
- """
- Return *True* if units are set on the *x*, *y*, or *z* axes
-
- """
- return (self.xaxis.have_units() or self.yaxis.have_units() or
- self.zaxis.have_units())
-
- def convert_zunits(self, z):
- """
- For artists in an axes, if the zaxis has units support,
- convert *z* using zaxis unit type
-
- .. versionadded :: 1.2.1
-
- """
- return self.zaxis.convert_units(z)
-
- def _process_unit_info(self, xdata=None, ydata=None, zdata=None,
- kwargs=None):
- """
- Look for unit *kwargs* and update the axis instances as necessary
-
- """
- super(Axes3D, self)._process_unit_info(xdata=xdata, ydata=ydata,
- kwargs=kwargs)
-
- if self.xaxis is None or self.yaxis is None or self.zaxis is None:
- return
-
- if zdata is not None:
- # we only need to update if there is nothing set yet.
- if not self.zaxis.have_units():
- self.zaxis.update_units(xdata)
-
- # process kwargs 2nd since these will override default units
- if kwargs is not None:
- zunits = kwargs.pop('zunits', self.zaxis.units)
- if zunits != self.zaxis.units:
- self.zaxis.set_units(zunits)
- # If the units being set imply a different converter,
- # we need to update.
- if zdata is not None:
- self.zaxis.update_units(zdata)
-
- def set_top_view(self):
- # this happens to be the right view for the viewing coordinates
- # moved up and to the left slightly to fit labels and axes
- xdwl = (0.95/self.dist)
- xdw = (0.9/self.dist)
- ydwl = (0.95/self.dist)
- ydw = (0.9/self.dist)
-
- # This is purposely using the 2D Axes's set_xlim and set_ylim,
- # because we are trying to place our viewing pane.
- super(Axes3D, self).set_xlim(-xdwl, xdw, auto=None)
- super(Axes3D, self).set_ylim(-ydwl, ydw, auto=None)
-
- def _init_axis(self):
- '''Init 3D axes; overrides creation of regular X/Y axes'''
- self.w_xaxis = axis3d.XAxis('x', self.xy_viewLim.intervalx,
- self.xy_dataLim.intervalx, self)
- self.xaxis = self.w_xaxis
- self.w_yaxis = axis3d.YAxis('y', self.xy_viewLim.intervaly,
- self.xy_dataLim.intervaly, self)
- self.yaxis = self.w_yaxis
- self.w_zaxis = axis3d.ZAxis('z', self.zz_viewLim.intervalx,
- self.zz_dataLim.intervalx, self)
- self.zaxis = self.w_zaxis
-
- for ax in self.xaxis, self.yaxis, self.zaxis:
- ax.init3d()
-
- def get_children(self):
- return [self.zaxis, ] + super(Axes3D, self).get_children()
-
- def _get_axis_list(self):
- return super(Axes3D, self)._get_axis_list() + (self.zaxis, )
-
- def unit_cube(self, vals=None):
- minx, maxx, miny, maxy, minz, maxz = vals or self.get_w_lims()
- xs, ys, zs = ([minx, maxx, maxx, minx, minx, maxx, maxx, minx],
- [miny, miny, maxy, maxy, miny, miny, maxy, maxy],
- [minz, minz, minz, minz, maxz, maxz, maxz, maxz])
- return list(zip(xs, ys, zs))
-
- def tunit_cube(self, vals=None, M=None):
- if M is None:
- M = self.M
- xyzs = self.unit_cube(vals)
- tcube = proj3d.proj_points(xyzs, M)
- return tcube
-
- def tunit_edges(self, vals=None, M=None):
- tc = self.tunit_cube(vals, M)
- edges = [(tc[0], tc[1]),
- (tc[1], tc[2]),
- (tc[2], tc[3]),
- (tc[3], tc[0]),
-
- (tc[0], tc[4]),
- (tc[1], tc[5]),
- (tc[2], tc[6]),
- (tc[3], tc[7]),
-
- (tc[4], tc[5]),
- (tc[5], tc[6]),
- (tc[6], tc[7]),
- (tc[7], tc[4])]
- return edges
-
- def draw(self, renderer):
- # draw the background patch
- self.patch.draw(renderer)
- self._frameon = False
-
- # first, set the aspect
- # this is duplicated from `axes._base._AxesBase.draw`
- # but must be called before any of the artist are drawn as
- # it adjusts the view limits and the size of the bounding box
- # of the axes
- locator = self.get_axes_locator()
- if locator:
- pos = locator(self, renderer)
- self.apply_aspect(pos)
- else:
- self.apply_aspect()
-
- # add the projection matrix to the renderer
- self.M = self.get_proj()
- renderer.M = self.M
- renderer.vvec = self.vvec
- renderer.eye = self.eye
- renderer.get_axis_position = self.get_axis_position
-
- # Calculate projection of collections and zorder them
- for i, col in enumerate(
- sorted(self.collections,
- key=lambda col: col.do_3d_projection(renderer),
- reverse=True)):
- col.zorder = i
-
- # Calculate projection of patches and zorder them
- for i, patch in enumerate(
- sorted(self.patches,
- key=lambda patch: patch.do_3d_projection(renderer),
- reverse=True)):
- patch.zorder = i
-
- if self._axis3don:
- axes = (self.xaxis, self.yaxis, self.zaxis)
- # Draw panes first
- for ax in axes:
- ax.draw_pane(renderer)
- # Then axes
- for ax in axes:
- ax.draw(renderer)
-
- # Then rest
- super(Axes3D, self).draw(renderer)
-
- def get_axis_position(self):
- vals = self.get_w_lims()
- tc = self.tunit_cube(vals, self.M)
- xhigh = tc[1][2] > tc[2][2]
- yhigh = tc[3][2] > tc[2][2]
- zhigh = tc[0][2] > tc[2][2]
- return xhigh, yhigh, zhigh
-
- def _on_units_changed(self, scalex=False, scaley=False, scalez=False):
- """
- Callback for processing changes to axis units.
-
- Currently forces updates of data limits and view limits.
- """
- self.relim()
- self.autoscale_view(scalex=scalex, scaley=scaley, scalez=scalez)
-
- def update_datalim(self, xys, **kwargs):
- pass
-
- def get_autoscale_on(self):
- """
- Get whether autoscaling is applied for all axes on plot commands
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """
- return super(Axes3D, self).get_autoscale_on() and self.get_autoscalez_on()
-
- def get_autoscalez_on(self):
- """
- Get whether autoscaling for the z-axis is applied on plot commands
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """
- return self._autoscaleZon
-
- def set_autoscale_on(self, b):
- """
- Set whether autoscaling is applied on plot commands
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
-
- Parameters
- ----------
- b : bool
- .. ACCEPTS: bool
- """
- super(Axes3D, self).set_autoscale_on(b)
- self.set_autoscalez_on(b)
-
- def set_autoscalez_on(self, b):
- """
- Set whether autoscaling for the z-axis is applied on plot commands
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
-
- Parameters
- ----------
- b : bool
- .. ACCEPTS: bool
- """
- self._autoscaleZon = b
-
- def set_zmargin(self, m):
- """
- Set padding of Z data limits prior to autoscaling.
-
- *m* times the data interval will be added to each
- end of that interval before it is used in autoscaling.
-
- accepts: float in range 0 to 1
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """
- if m < 0 or m > 1 :
- raise ValueError("margin must be in range 0 to 1")
- self._zmargin = m
- self.stale = True
-
- def margins(self, *args, **kw):
- """
- Convenience method to set or retrieve autoscaling margins.
-
- signatures::
- margins()
-
- returns xmargin, ymargin, zmargin
-
- ::
-
- margins(margin)
-
- margins(xmargin, ymargin, zmargin)
-
- margins(x=xmargin, y=ymargin, z=zmargin)
-
- margins(..., tight=False)
-
- All forms above set the xmargin, ymargin and zmargin
- parameters. All keyword parameters are optional. A single argument
- specifies xmargin, ymargin and zmargin. The *tight* parameter
- is passed to :meth:`autoscale_view`, which is executed after
- a margin is changed; the default here is *True*, on the
- assumption that when margins are specified, no additional
- padding to match tick marks is usually desired. Setting
- *tight* to *None* will preserve the previous setting.
-
- Specifying any margin changes only the autoscaling; for example,
- if *xmargin* is not None, then *xmargin* times the X data
- interval will be added to each end of that interval before
- it is used in autoscaling.
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """
- if not args and not kw:
- return self._xmargin, self._ymargin, self._zmargin
-
- tight = kw.pop('tight', True)
- mx = kw.pop('x', None)
- my = kw.pop('y', None)
- mz = kw.pop('z', None)
- if not args:
- pass
- elif len(args) == 1:
- mx = my = mz = args[0]
- elif len(args) == 2:
- warnings.warn(
- "Passing exactly two positional arguments to Axes3D.margins "
- "is deprecated. If needed, pass them as keyword arguments "
- "instead", cbook.mplDeprecation)
- mx, my = args
- elif len(args) == 3:
- mx, my, mz = args
- else:
- raise ValueError(
- "Axes3D.margins takes at most three positional arguments")
- if mx is not None:
- self.set_xmargin(mx)
- if my is not None:
- self.set_ymargin(my)
- if mz is not None:
- self.set_zmargin(mz)
-
- scalex = mx is not None
- scaley = my is not None
- scalez = mz is not None
-
- self.autoscale_view(tight=tight, scalex=scalex, scaley=scaley,
- scalez=scalez)
-
- def autoscale(self, enable=True, axis='both', tight=None):
- """
- Convenience method for simple axis view autoscaling.
- See :meth:`matplotlib.axes.Axes.autoscale` for full explanation.
- Note that this function behaves the same, but for all
- three axes. Therefore, 'z' can be passed for *axis*,
- and 'both' applies to all three axes.
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """
- if enable is None:
- scalex = True
- scaley = True
- scalez = True
- else:
- if axis in ['x', 'both']:
- self._autoscaleXon = scalex = bool(enable)
- else:
- scalex = False
- if axis in ['y', 'both']:
- self._autoscaleYon = scaley = bool(enable)
- else:
- scaley = False
- if axis in ['z', 'both']:
- self._autoscaleZon = scalez = bool(enable)
- else:
- scalez = False
- self.autoscale_view(tight=tight, scalex=scalex, scaley=scaley,
- scalez=scalez)
-
- def auto_scale_xyz(self, X, Y, Z=None, had_data=None):
- x, y, z = map(np.asarray, (X, Y, Z))
- try:
- x, y = x.flatten(), y.flatten()
- if Z is not None:
- z = z.flatten()
- except AttributeError:
- raise
-
- # This updates the bounding boxes as to keep a record as
- # to what the minimum sized rectangular volume holds the
- # data.
- self.xy_dataLim.update_from_data_xy(np.array([x, y]).T, not had_data)
- if z is not None:
- self.zz_dataLim.update_from_data_xy(np.array([z, z]).T, not had_data)
-
- # Let autoscale_view figure out how to use this data.
- self.autoscale_view()
-
- def autoscale_view(self, tight=None, scalex=True, scaley=True,
- scalez=True):
- """
- Autoscale the view limits using the data limits.
- See :meth:`matplotlib.axes.Axes.autoscale_view` for documentation.
- Note that this function applies to the 3D axes, and as such
- adds the *scalez* to the function arguments.
-
- .. versionchanged :: 1.1.0
- Function signature was changed to better match the 2D version.
- *tight* is now explicitly a kwarg and placed first.
-
- .. versionchanged :: 1.2.1
- This is now fully functional.
-
- """
- if not self._ready:
- return
-
- # This method looks at the rectangular volume (see above)
- # of data and decides how to scale the view portal to fit it.
- if tight is None:
- # if image data only just use the datalim
- _tight = self._tight or (len(self.images)>0 and
- len(self.lines)==0 and
- len(self.patches)==0)
- else:
- _tight = self._tight = bool(tight)
-
- if scalex and self._autoscaleXon:
- xshared = self._shared_x_axes.get_siblings(self)
- dl = [ax.dataLim for ax in xshared]
- bb = mtransforms.BboxBase.union(dl)
- x0, x1 = self.xy_dataLim.intervalx
- xlocator = self.xaxis.get_major_locator()
- try:
- x0, x1 = xlocator.nonsingular(x0, x1)
- except AttributeError:
- x0, x1 = mtransforms.nonsingular(x0, x1, increasing=False,
- expander=0.05)
- if self._xmargin > 0:
- delta = (x1 - x0) * self._xmargin
- x0 -= delta
- x1 += delta
- if not _tight:
- x0, x1 = xlocator.view_limits(x0, x1)
- self.set_xbound(x0, x1)
-
- if scaley and self._autoscaleYon:
- yshared = self._shared_y_axes.get_siblings(self)
- dl = [ax.dataLim for ax in yshared]
- bb = mtransforms.BboxBase.union(dl)
- y0, y1 = self.xy_dataLim.intervaly
- ylocator = self.yaxis.get_major_locator()
- try:
- y0, y1 = ylocator.nonsingular(y0, y1)
- except AttributeError:
- y0, y1 = mtransforms.nonsingular(y0, y1, increasing=False,
- expander=0.05)
- if self._ymargin > 0:
- delta = (y1 - y0) * self._ymargin
- y0 -= delta
- y1 += delta
- if not _tight:
- y0, y1 = ylocator.view_limits(y0, y1)
- self.set_ybound(y0, y1)
-
- if scalez and self._autoscaleZon:
- zshared = self._shared_z_axes.get_siblings(self)
- dl = [ax.dataLim for ax in zshared]
- bb = mtransforms.BboxBase.union(dl)
- z0, z1 = self.zz_dataLim.intervalx
- zlocator = self.zaxis.get_major_locator()
- try:
- z0, z1 = zlocator.nonsingular(z0, z1)
- except AttributeError:
- z0, z1 = mtransforms.nonsingular(z0, z1, increasing=False,
- expander=0.05)
- if self._zmargin > 0:
- delta = (z1 - z0) * self._zmargin
- z0 -= delta
- z1 += delta
- if not _tight:
- z0, z1 = zlocator.view_limits(z0, z1)
- self.set_zbound(z0, z1)
-
- def get_w_lims(self):
- '''Get 3D world limits.'''
- minx, maxx = self.get_xlim3d()
- miny, maxy = self.get_ylim3d()
- minz, maxz = self.get_zlim3d()
- return minx, maxx, miny, maxy, minz, maxz
-
- def _determine_lims(self, xmin=None, xmax=None, *args, **kwargs):
- if xmax is None and cbook.iterable(xmin):
- xmin, xmax = xmin
- if xmin == xmax:
- xmin -= 0.05
- xmax += 0.05
- return (xmin, xmax)
-
- def set_xlim3d(self, left=None, right=None, emit=True, auto=False, **kw):
- """
- Set 3D x limits.
-
- See :meth:`matplotlib.axes.Axes.set_xlim` for full documentation.
-
- """
- if 'xmin' in kw:
- left = kw.pop('xmin')
- if 'xmax' in kw:
- right = kw.pop('xmax')
- if kw:
- raise ValueError("unrecognized kwargs: %s" % list(kw))
-
- if right is None and cbook.iterable(left):
- left, right = left
-
- self._process_unit_info(xdata=(left, right))
- left = self._validate_converted_limits(left, self.convert_xunits)
- right = self._validate_converted_limits(right, self.convert_xunits)
-
- old_left, old_right = self.get_xlim()
- if left is None:
- left = old_left
- if right is None:
- right = old_right
-
- if left == right:
- warnings.warn(('Attempting to set identical left==right results\n'
- 'in singular transformations; automatically expanding.\n'
- 'left=%s, right=%s') % (left, right))
- left, right = mtransforms.nonsingular(left, right, increasing=False)
- left, right = self.xaxis.limit_range_for_scale(left, right)
- self.xy_viewLim.intervalx = (left, right)
-
- if auto is not None:
- self._autoscaleXon = bool(auto)
-
- if emit:
- self.callbacks.process('xlim_changed', self)
- # Call all of the other x-axes that are shared with this one
- for other in self._shared_x_axes.get_siblings(self):
- if other is not self:
- other.set_xlim(self.xy_viewLim.intervalx,
- emit=False, auto=auto)
- if (other.figure != self.figure and
- other.figure.canvas is not None):
- other.figure.canvas.draw_idle()
- self.stale = True
- return left, right
- set_xlim = set_xlim3d
-
- def set_ylim3d(self, bottom=None, top=None, emit=True, auto=False, **kw):
- """
- Set 3D y limits.
-
- See :meth:`matplotlib.axes.Axes.set_ylim` for full documentation.
-
- """
- if 'ymin' in kw:
- bottom = kw.pop('ymin')
- if 'ymax' in kw:
- top = kw.pop('ymax')
- if kw:
- raise ValueError("unrecognized kwargs: %s" % list(kw))
-
- if top is None and cbook.iterable(bottom):
- bottom, top = bottom
-
- self._process_unit_info(ydata=(bottom, top))
- bottom = self._validate_converted_limits(bottom, self.convert_yunits)
- top = self._validate_converted_limits(top, self.convert_yunits)
-
- old_bottom, old_top = self.get_ylim()
- if bottom is None:
- bottom = old_bottom
- if top is None:
- top = old_top
-
- if top == bottom:
- warnings.warn(('Attempting to set identical bottom==top results\n'
- 'in singular transformations; automatically expanding.\n'
- 'bottom=%s, top=%s') % (bottom, top))
- bottom, top = mtransforms.nonsingular(bottom, top, increasing=False)
- bottom, top = self.yaxis.limit_range_for_scale(bottom, top)
- self.xy_viewLim.intervaly = (bottom, top)
-
- if auto is not None:
- self._autoscaleYon = bool(auto)
-
- if emit:
- self.callbacks.process('ylim_changed', self)
- # Call all of the other y-axes that are shared with this one
- for other in self._shared_y_axes.get_siblings(self):
- if other is not self:
- other.set_ylim(self.xy_viewLim.intervaly,
- emit=False, auto=auto)
- if (other.figure != self.figure and
- other.figure.canvas is not None):
- other.figure.canvas.draw_idle()
- self.stale = True
- return bottom, top
- set_ylim = set_ylim3d
-
- def set_zlim3d(self, bottom=None, top=None, emit=True, auto=False, **kw):
- """
- Set 3D z limits.
-
- See :meth:`matplotlib.axes.Axes.set_ylim` for full documentation
-
- """
- if 'zmin' in kw:
- bottom = kw.pop('zmin')
- if 'zmax' in kw:
- top = kw.pop('zmax')
- if kw:
- raise ValueError("unrecognized kwargs: %s" % list(kw))
-
- if top is None and cbook.iterable(bottom):
- bottom, top = bottom
-
- self._process_unit_info(zdata=(bottom, top))
- bottom = self._validate_converted_limits(bottom, self.convert_zunits)
- top = self._validate_converted_limits(top, self.convert_zunits)
-
- old_bottom, old_top = self.get_zlim()
- if bottom is None:
- bottom = old_bottom
- if top is None:
- top = old_top
-
- if top == bottom:
- warnings.warn(('Attempting to set identical bottom==top results\n'
- 'in singular transformations; automatically expanding.\n'
- 'bottom=%s, top=%s') % (bottom, top))
- bottom, top = mtransforms.nonsingular(bottom, top, increasing=False)
- bottom, top = self.zaxis.limit_range_for_scale(bottom, top)
- self.zz_viewLim.intervalx = (bottom, top)
-
- if auto is not None:
- self._autoscaleZon = bool(auto)
-
- if emit:
- self.callbacks.process('zlim_changed', self)
- # Call all of the other y-axes that are shared with this one
- for other in self._shared_z_axes.get_siblings(self):
- if other is not self:
- other.set_zlim(self.zz_viewLim.intervalx,
- emit=False, auto=auto)
- if (other.figure != self.figure and
- other.figure.canvas is not None):
- other.figure.canvas.draw_idle()
- self.stale = True
- return bottom, top
- set_zlim = set_zlim3d
-
- def get_xlim3d(self):
- return tuple(self.xy_viewLim.intervalx)
- get_xlim3d.__doc__ = maxes.Axes.get_xlim.__doc__
- get_xlim = get_xlim3d
- if get_xlim.__doc__ is not None:
- get_xlim.__doc__ += """
- .. versionchanged :: 1.1.0
- This function now correctly refers to the 3D x-limits
- """
-
- def get_ylim3d(self):
- return tuple(self.xy_viewLim.intervaly)
- get_ylim3d.__doc__ = maxes.Axes.get_ylim.__doc__
- get_ylim = get_ylim3d
- if get_ylim.__doc__ is not None:
- get_ylim.__doc__ += """
- .. versionchanged :: 1.1.0
- This function now correctly refers to the 3D y-limits.
- """
-
- def get_zlim3d(self):
- '''Get 3D z limits.'''
- return tuple(self.zz_viewLim.intervalx)
- get_zlim = get_zlim3d
-
- def get_zscale(self):
- """
- Return the zaxis scale string %s
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """ % (", ".join(mscale.get_scale_names()))
- return self.zaxis.get_scale()
-
- # We need to slightly redefine these to pass scalez=False
- # to their calls of autoscale_view.
- def set_xscale(self, value, **kwargs):
- self.xaxis._set_scale(value, **kwargs)
- self.autoscale_view(scaley=False, scalez=False)
- self._update_transScale()
- if maxes.Axes.set_xscale.__doc__ is not None:
- set_xscale.__doc__ = maxes.Axes.set_xscale.__doc__ + """
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """
-
- def set_yscale(self, value, **kwargs):
- self.yaxis._set_scale(value, **kwargs)
- self.autoscale_view(scalex=False, scalez=False)
- self._update_transScale()
- self.stale = True
- if maxes.Axes.set_yscale.__doc__ is not None:
- set_yscale.__doc__ = maxes.Axes.set_yscale.__doc__ + """
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """
-
- @docstring.dedent_interpd
- def set_zscale(self, value, **kwargs):
- """
- Set the scaling of the z-axis: %(scale)s
-
- ACCEPTS: [%(scale)s]
-
- Different kwargs are accepted, depending on the scale:
- %(scale_docs)s
-
- .. note ::
- Currently, Axes3D objects only supports linear scales.
- Other scales may or may not work, and support for these
- is improving with each release.
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """
- self.zaxis._set_scale(value, **kwargs)
- self.autoscale_view(scalex=False, scaley=False)
- self._update_transScale()
- self.stale = True
-
- def set_zticks(self, *args, **kwargs):
- """
- Set z-axis tick locations.
- See :meth:`matplotlib.axes.Axes.set_yticks` for more details.
-
- .. note::
- Minor ticks are not supported.
-
- .. versionadded:: 1.1.0
- """
- return self.zaxis.set_ticks(*args, **kwargs)
-
- def get_zticks(self, minor=False):
- """
- Return the z ticks as a list of locations
- See :meth:`matplotlib.axes.Axes.get_yticks` for more details.
-
- .. note::
- Minor ticks are not supported.
-
- .. versionadded:: 1.1.0
- """
- return self.zaxis.get_ticklocs(minor=minor)
-
- def get_zmajorticklabels(self):
- """
- Get the ztick labels as a list of Text instances
-
- .. versionadded :: 1.1.0
- """
- return cbook.silent_list('Text zticklabel',
- self.zaxis.get_majorticklabels())
-
- def get_zminorticklabels(self):
- """
- Get the ztick labels as a list of Text instances
-
- .. note::
- Minor ticks are not supported. This function was added
- only for completeness.
-
- .. versionadded :: 1.1.0
- """
- return cbook.silent_list('Text zticklabel',
- self.zaxis.get_minorticklabels())
-
- def set_zticklabels(self, *args, **kwargs):
- """
- Set z-axis tick labels.
- See :meth:`matplotlib.axes.Axes.set_yticklabels` for more details.
-
- .. note::
- Minor ticks are not supported by Axes3D objects.
-
- .. versionadded:: 1.1.0
- """
- return self.zaxis.set_ticklabels(*args, **kwargs)
-
- def get_zticklabels(self, minor=False):
- """
- Get ztick labels as a list of Text instances.
- See :meth:`matplotlib.axes.Axes.get_yticklabels` for more details.
-
- .. note::
- Minor ticks are not supported.
-
- .. versionadded:: 1.1.0
- """
- return cbook.silent_list('Text zticklabel',
- self.zaxis.get_ticklabels(minor=minor))
-
- def zaxis_date(self, tz=None):
- """
- Sets up z-axis ticks and labels that treat the z data as dates.
-
- *tz* is a timezone string or :class:`tzinfo` instance.
- Defaults to rc value.
-
- .. note::
- This function is merely provided for completeness.
- Axes3D objects do not officially support dates for ticks,
- and so this may or may not work as expected.
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """
- self.zaxis.axis_date(tz)
-
- def get_zticklines(self):
- """
- Get ztick lines as a list of Line2D instances.
- Note that this function is provided merely for completeness.
- These lines are re-calculated as the display changes.
-
- .. versionadded:: 1.1.0
- """
- return self.zaxis.get_ticklines()
-
- def clabel(self, *args, **kwargs):
- """
- This function is currently not implemented for 3D axes.
- Returns *None*.
- """
- return None
-
- def view_init(self, elev=None, azim=None):
- """
- Set the elevation and azimuth of the axes.
-
- This can be used to rotate the axes programmatically.
-
- 'elev' stores the elevation angle in the z plane.
- 'azim' stores the azimuth angle in the x,y plane.
-
- if elev or azim are None (default), then the initial value
- is used which was specified in the :class:`Axes3D` constructor.
- """
-
- self.dist = 10
-
- if elev is None:
- self.elev = self.initial_elev
- else:
- self.elev = elev
-
- if azim is None:
- self.azim = self.initial_azim
- else:
- self.azim = azim
-
- def set_proj_type(self, proj_type):
- """
- Set the projection type.
-
- Parameters
- ----------
- proj_type : str
- Type of projection, accepts 'persp' and 'ortho'.
-
- """
- if proj_type == 'persp':
- self._projection = proj3d.persp_transformation
- elif proj_type == 'ortho':
- self._projection = proj3d.ortho_transformation
- else:
- raise ValueError("unrecognized projection: %s" % proj_type)
-
- def get_proj(self):
- """
- Create the projection matrix from the current viewing position.
-
- elev stores the elevation angle in the z plane
- azim stores the azimuth angle in the x,y plane
-
- dist is the distance of the eye viewing point from the object
- point.
-
- """
- relev, razim = np.pi * self.elev/180, np.pi * self.azim/180
-
- xmin, xmax = self.get_xlim3d()
- ymin, ymax = self.get_ylim3d()
- zmin, zmax = self.get_zlim3d()
-
- # transform to uniform world coordinates 0-1.0,0-1.0,0-1.0
- worldM = proj3d.world_transformation(xmin, xmax,
- ymin, ymax,
- zmin, zmax)
-
- # look into the middle of the new coordinates
- R = np.array([0.5, 0.5, 0.5])
-
- xp = R[0] + np.cos(razim) * np.cos(relev) * self.dist
- yp = R[1] + np.sin(razim) * np.cos(relev) * self.dist
- zp = R[2] + np.sin(relev) * self.dist
- E = np.array((xp, yp, zp))
-
- self.eye = E
- self.vvec = R - E
- self.vvec = self.vvec / proj3d.mod(self.vvec)
-
- if abs(relev) > np.pi/2:
- # upside down
- V = np.array((0, 0, -1))
- else:
- V = np.array((0, 0, 1))
- zfront, zback = -self.dist, self.dist
-
- viewM = proj3d.view_transformation(E, R, V)
- projM = self._projection(zfront, zback)
- M0 = np.dot(viewM, worldM)
- M = np.dot(projM, M0)
- return M
-
- def mouse_init(self, rotate_btn=1, zoom_btn=3):
- """Initializes mouse button callbacks to enable 3D rotation of
- the axes. Also optionally sets the mouse buttons for 3D rotation
- and zooming.
-
- ============ =======================================================
- Argument Description
- ============ =======================================================
- *rotate_btn* The integer or list of integers specifying which mouse
- button or buttons to use for 3D rotation of the axes.
- Default = 1.
-
- *zoom_btn* The integer or list of integers specifying which mouse
- button or buttons to use to zoom the 3D axes.
- Default = 3.
- ============ =======================================================
-
- """
- self.button_pressed = None
- canv = self.figure.canvas
- if canv is not None:
- c1 = canv.mpl_connect('motion_notify_event', self._on_move)
- c2 = canv.mpl_connect('button_press_event', self._button_press)
- c3 = canv.mpl_connect('button_release_event', self._button_release)
- self._cids = [c1, c2, c3]
- else:
- warnings.warn(
- "Axes3D.figure.canvas is 'None', mouse rotation disabled. "
- "Set canvas then call Axes3D.mouse_init().")
-
- # coerce scalars into array-like, then convert into
- # a regular list to avoid comparisons against None
- # which breaks in recent versions of numpy.
- self._rotate_btn = np.atleast_1d(rotate_btn).tolist()
- self._zoom_btn = np.atleast_1d(zoom_btn).tolist()
-
- def can_zoom(self):
- """
- Return *True* if this axes supports the zoom box button functionality.
-
- 3D axes objects do not use the zoom box button.
- """
- return False
-
- def can_pan(self):
- """
- Return *True* if this axes supports the pan/zoom button functionality.
-
- 3D axes objects do not use the pan/zoom button.
- """
- return False
-
- def cla(self):
- """
- Clear axes
- """
- # Disabling mouse interaction might have been needed a long
- # time ago, but I can't find a reason for it now - BVR (2012-03)
- #self.disable_mouse_rotation()
- super(Axes3D, self).cla()
- self.zaxis.cla()
-
- if self._sharez is not None:
- self.zaxis.major = self._sharez.zaxis.major
- self.zaxis.minor = self._sharez.zaxis.minor
- z0, z1 = self._sharez.get_zlim()
- self.set_zlim(z0, z1, emit=False, auto=None)
- self.zaxis._set_scale(self._sharez.zaxis.get_scale())
- else:
- self.zaxis._set_scale('linear')
- try:
- self.set_zlim(0, 1)
- except TypeError:
- pass
-
- self._autoscaleZon = True
- self._zmargin = 0
-
- self.grid(rcParams['axes3d.grid'])
-
- def disable_mouse_rotation(self):
- """Disable mouse button callbacks.
- """
- # Disconnect the various events we set.
- for cid in self._cids:
- self.figure.canvas.mpl_disconnect(cid)
-
- self._cids = []
-
- def _button_press(self, event):
- if event.inaxes == self:
- self.button_pressed = event.button
- self.sx, self.sy = event.xdata, event.ydata
-
- def _button_release(self, event):
- self.button_pressed = None
-
- def format_zdata(self, z):
- """
- Return *z* string formatted. This function will use the
- :attr:`fmt_zdata` attribute if it is callable, else will fall
- back on the zaxis major formatter
- """
- try: return self.fmt_zdata(z)
- except (AttributeError, TypeError):
- func = self.zaxis.get_major_formatter().format_data_short
- val = func(z)
- return val
-
- def format_coord(self, xd, yd):
- """
- Given the 2D view coordinates attempt to guess a 3D coordinate.
- Looks for the nearest edge to the point and then assumes that
- the point is at the same z location as the nearest point on the edge.
- """
-
- if self.M is None:
- return ''
-
- if self.button_pressed in self._rotate_btn:
- return 'azimuth=%d deg, elevation=%d deg ' % (self.azim, self.elev)
- # ignore xd and yd and display angles instead
-
- # nearest edge
- p0, p1 = min(self.tunit_edges(),
- key=lambda edge: proj3d.line2d_seg_dist(
- edge[0], edge[1], (xd, yd)))
-
- # scale the z value to match
- x0, y0, z0 = p0
- x1, y1, z1 = p1
- d0 = np.hypot(x0-xd, y0-yd)
- d1 = np.hypot(x1-xd, y1-yd)
- dt = d0+d1
- z = d1/dt * z0 + d0/dt * z1
-
- x, y, z = proj3d.inv_transform(xd, yd, z, self.M)
-
- xs = self.format_xdata(x)
- ys = self.format_ydata(y)
- zs = self.format_zdata(z)
- return 'x=%s, y=%s, z=%s' % (xs, ys, zs)
-
- def _on_move(self, event):
- """Mouse moving
-
- button-1 rotates by default. Can be set explicitly in mouse_init().
- button-3 zooms by default. Can be set explicitly in mouse_init().
- """
-
- if not self.button_pressed:
- return
-
- if self.M is None:
- return
-
- x, y = event.xdata, event.ydata
- # In case the mouse is out of bounds.
- if x is None:
- return
-
- dx, dy = x - self.sx, y - self.sy
- w = self._pseudo_w
- h = self._pseudo_h
- self.sx, self.sy = x, y
-
- # Rotation
- if self.button_pressed in self._rotate_btn:
- # rotate viewing point
- # get the x and y pixel coords
- if dx == 0 and dy == 0:
- return
- self.elev = art3d.norm_angle(self.elev - (dy/h)*180)
- self.azim = art3d.norm_angle(self.azim - (dx/w)*180)
- self.get_proj()
- self.stale = True
- self.figure.canvas.draw_idle()
-
-# elif self.button_pressed == 2:
- # pan view
- # project xv,yv,zv -> xw,yw,zw
- # pan
-# pass
-
- # Zoom
- elif self.button_pressed in self._zoom_btn:
- # zoom view
- # hmmm..this needs some help from clipping....
- minx, maxx, miny, maxy, minz, maxz = self.get_w_lims()
- df = 1-((h - dy)/h)
- dx = (maxx-minx)*df
- dy = (maxy-miny)*df
- dz = (maxz-minz)*df
- self.set_xlim3d(minx - dx, maxx + dx)
- self.set_ylim3d(miny - dy, maxy + dy)
- self.set_zlim3d(minz - dz, maxz + dz)
- self.get_proj()
- self.figure.canvas.draw_idle()
-
- def set_zlabel(self, zlabel, fontdict=None, labelpad=None, **kwargs):
- '''
- Set zlabel. See doc for :meth:`set_ylabel` for description.
-
- '''
- if labelpad is not None : self.zaxis.labelpad = labelpad
- return self.zaxis.set_label_text(zlabel, fontdict, **kwargs)
-
- def get_zlabel(self):
- """
- Get the z-label text string.
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """
- label = self.zaxis.get_label()
- return label.get_text()
-
- #### Axes rectangle characteristics
-
- def get_frame_on(self):
- """
- Get whether the 3D axes panels are drawn.
-
- .. versionadded :: 1.1.0
- """
- return self._frameon
-
- def set_frame_on(self, b):
- """
- Set whether the 3D axes panels are drawn.
-
- .. versionadded :: 1.1.0
-
- Parameters
- ----------
- b : bool
- .. ACCEPTS: bool
- """
- self._frameon = bool(b)
- self.stale = True
-
- def get_axisbelow(self):
- """
- Get whether axis below is true or not.
-
- For axes3d objects, this will always be *True*
-
- .. versionadded :: 1.1.0
- This function was added for completeness.
- """
- return True
-
- def set_axisbelow(self, b):
- """
- Set whether axis ticks and gridlines are above or below most artists.
-
- For axes3d objects, this will ignore any settings and just use *True*
-
- .. versionadded :: 1.1.0
- This function was added for completeness.
-
- Parameters
- ----------
- b : bool
- .. ACCEPTS: bool
- """
- self._axisbelow = True
- self.stale = True
-
- def grid(self, b=True, **kwargs):
- '''
- Set / unset 3D grid.
-
- .. note::
-
- Currently, this function does not behave the same as
- :meth:`matplotlib.axes.Axes.grid`, but it is intended to
- eventually support that behavior.
-
- .. versionchanged :: 1.1.0
- This function was changed, but not tested. Please report any bugs.
- '''
- # TODO: Operate on each axes separately
- if len(kwargs):
- b = True
- self._draw_grid = cbook._string_to_bool(b)
- self.stale = True
-
- def ticklabel_format(self, **kwargs):
- """
- Convenience method for manipulating the ScalarFormatter
- used by default for linear axes in Axed3D objects.
-
- See :meth:`matplotlib.axes.Axes.ticklabel_format` for full
- documentation. Note that this version applies to all three
- axes of the Axes3D object. Therefore, the *axis* argument
- will also accept a value of 'z' and the value of 'both' will
- apply to all three axes.
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """
- style = kwargs.pop('style', '').lower()
- scilimits = kwargs.pop('scilimits', None)
- useOffset = kwargs.pop('useOffset', None)
- axis = kwargs.pop('axis', 'both').lower()
- if scilimits is not None:
- try:
- m, n = scilimits
- m+n+1 # check that both are numbers
- except (ValueError, TypeError):
- raise ValueError("scilimits must be a sequence of 2 integers")
- if style[:3] == 'sci':
- sb = True
- elif style in ['plain', 'comma']:
- sb = False
- if style == 'plain':
- cb = False
- else:
- cb = True
- raise NotImplementedError("comma style remains to be added")
- elif style == '':
- sb = None
- else:
- raise ValueError("%s is not a valid style value")
- try:
- if sb is not None:
- if axis in ['both', 'z']:
- self.xaxis.major.formatter.set_scientific(sb)
- if axis in ['both', 'y']:
- self.yaxis.major.formatter.set_scientific(sb)
- if axis in ['both', 'z'] :
- self.zaxis.major.formatter.set_scientific(sb)
- if scilimits is not None:
- if axis in ['both', 'x']:
- self.xaxis.major.formatter.set_powerlimits(scilimits)
- if axis in ['both', 'y']:
- self.yaxis.major.formatter.set_powerlimits(scilimits)
- if axis in ['both', 'z']:
- self.zaxis.major.formatter.set_powerlimits(scilimits)
- if useOffset is not None:
- if axis in ['both', 'x']:
- self.xaxis.major.formatter.set_useOffset(useOffset)
- if axis in ['both', 'y']:
- self.yaxis.major.formatter.set_useOffset(useOffset)
- if axis in ['both', 'z']:
- self.zaxis.major.formatter.set_useOffset(useOffset)
- except AttributeError:
- raise AttributeError(
- "This method only works with the ScalarFormatter.")
-
- def locator_params(self, axis='both', tight=None, **kwargs):
- """
- Convenience method for controlling tick locators.
-
- See :meth:`matplotlib.axes.Axes.locator_params` for full
- documentation Note that this is for Axes3D objects,
- therefore, setting *axis* to 'both' will result in the
- parameters being set for all three axes. Also, *axis*
- can also take a value of 'z' to apply parameters to the
- z axis.
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """
- _x = axis in ['x', 'both']
- _y = axis in ['y', 'both']
- _z = axis in ['z', 'both']
- if _x:
- self.xaxis.get_major_locator().set_params(**kwargs)
- if _y:
- self.yaxis.get_major_locator().set_params(**kwargs)
- if _z:
- self.zaxis.get_major_locator().set_params(**kwargs)
- self.autoscale_view(tight=tight, scalex=_x, scaley=_y, scalez=_z)
-
- def tick_params(self, axis='both', **kwargs):
- """
- Convenience method for changing the appearance of ticks and
- tick labels.
-
- See :meth:`matplotlib.axes.Axes.tick_params` for more complete
- documentation.
-
- The only difference is that setting *axis* to 'both' will
- mean that the settings are applied to all three axes. Also,
- the *axis* parameter also accepts a value of 'z', which
- would mean to apply to only the z-axis.
-
- Also, because of how Axes3D objects are drawn very differently
- from regular 2D axes, some of these settings may have
- ambiguous meaning. For simplicity, the 'z' axis will
- accept settings as if it was like the 'y' axis.
-
- .. note::
- While this function is currently implemented, the core part
- of the Axes3D object may ignore some of these settings.
- Future releases will fix this. Priority will be given to
- those who file bugs.
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """
- super(Axes3D, self).tick_params(axis, **kwargs)
- if axis in ['z', 'both'] :
- zkw = dict(kwargs)
- zkw.pop('top', None)
- zkw.pop('bottom', None)
- zkw.pop('labeltop', None)
- zkw.pop('labelbottom', None)
- self.zaxis.set_tick_params(**zkw)
-
- ### data limits, ticks, tick labels, and formatting
-
- def invert_zaxis(self):
- """
- Invert the z-axis.
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """
- bottom, top = self.get_zlim()
- self.set_zlim(top, bottom, auto=None)
-
- def zaxis_inverted(self):
- '''
- Returns True if the z-axis is inverted.
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- '''
- bottom, top = self.get_zlim()
- return top < bottom
-
- def get_zbound(self):
- """
- Returns the z-axis numerical bounds where::
-
- lowerBound < upperBound
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """
- bottom, top = self.get_zlim()
- if bottom < top:
- return bottom, top
- else:
- return top, bottom
-
- def set_zbound(self, lower=None, upper=None):
- """
- Set the lower and upper numerical bounds of the z-axis.
- This method will honor axes inversion regardless of parameter order.
- It will not change the :attr:`_autoscaleZon` attribute.
-
- .. versionadded :: 1.1.0
- This function was added, but not tested. Please report any bugs.
- """
- if upper is None and cbook.iterable(lower):
- lower,upper = lower
-
- old_lower,old_upper = self.get_zbound()
-
- if lower is None: lower = old_lower
- if upper is None: upper = old_upper
-
- if self.zaxis_inverted():
- if lower < upper:
- self.set_zlim(upper, lower, auto=None)
- else:
- self.set_zlim(lower, upper, auto=None)
- else :
- if lower < upper:
- self.set_zlim(lower, upper, auto=None)
- else :
- self.set_zlim(upper, lower, auto=None)
-
- def text(self, x, y, z, s, zdir=None, **kwargs):
- '''
- Add text to the plot. kwargs will be passed on to Axes.text,
- except for the `zdir` keyword, which sets the direction to be
- used as the z direction.
- '''
- text = super(Axes3D, self).text(x, y, s, **kwargs)
- art3d.text_2d_to_3d(text, z, zdir)
- return text
-
- text3D = text
- text2D = Axes.text
-
- def plot(self, xs, ys, *args, **kwargs):
- '''
- Plot 2D or 3D data.
-
- ========== ================================================
- Argument Description
- ========== ================================================
- *xs*, *ys* x, y coordinates of vertices
-
- *zs* z value(s), either one for all points or one for
- each point.
- *zdir* Which direction to use as z ('x', 'y' or 'z')
- when plotting a 2D set.
- ========== ================================================
-
- Other arguments are passed on to
- :func:`~matplotlib.axes.Axes.plot`
- '''
- had_data = self.has_data()
-
- # `zs` can be passed positionally or as keyword; checking whether
- # args[0] is a string matches the behavior of 2D `plot` (via
- # `_process_plot_var_args`).
- if args and not isinstance(args[0], six.string_types):
- zs = args[0]
- args = args[1:]
- if 'zs' in kwargs:
- raise TypeError("plot() for multiple values for argument 'z'")
- else:
- zs = kwargs.pop('zs', 0)
- zdir = kwargs.pop('zdir', 'z')
-
- # Match length
- zs = _backports.broadcast_to(zs, len(xs))
-
- lines = super(Axes3D, self).plot(xs, ys, *args, **kwargs)
- for line in lines:
- art3d.line_2d_to_3d(line, zs=zs, zdir=zdir)
-
- xs, ys, zs = art3d.juggle_axes(xs, ys, zs, zdir)
- self.auto_scale_xyz(xs, ys, zs, had_data)
- return lines
-
- plot3D = plot
-
- def plot_surface(self, X, Y, Z, *args, **kwargs):
- """
- Create a surface plot.
-
- By default it will be colored in shades of a solid color, but it also
- supports color mapping by supplying the *cmap* argument.
-
- .. note::
-
- The *rcount* and *ccount* kwargs, which both default to 50,
- determine the maximum number of samples used in each direction. If
- the input data is larger, it will be downsampled (by slicing) to
- these numbers of points.
-
- Parameters
- ----------
- X, Y, Z : 2d arrays
- Data values.
-
- rcount, ccount : int
- Maximum number of samples used in each direction. If the input
- data is larger, it will be downsampled (by slicing) to these
- numbers of points. Defaults to 50.
-
- .. versionadded:: 2.0
-
- rstride, cstride : int
- Downsampling stride in each direction. These arguments are
- mutually exclusive with *rcount* and *ccount*. If only one of
- *rstride* or *cstride* is set, the other defaults to 10.
-
- 'classic' mode uses a default of ``rstride = cstride = 10`` instead
- of the new default of ``rcount = ccount = 50``.
-
- color : color-like
- Color of the surface patches.
-
- cmap : Colormap
- Colormap of the surface patches.
-
- facecolors : array-like of colors.
- Colors of each individual patch.
-
- norm : Normalize
- Normalization for the colormap.
-
- vmin, vmax : float
- Bounds for the normalization.
-
- shade : bool
- Whether to shade the face colors.
-
- **kwargs :
- Other arguments are forwarded to `.Poly3DCollection`.
- """
-
- had_data = self.has_data()
-
- if Z.ndim != 2:
- raise ValueError("Argument Z must be 2-dimensional.")
- # TODO: Support masked arrays
- X, Y, Z = np.broadcast_arrays(X, Y, Z)
- rows, cols = Z.shape
-
- has_stride = 'rstride' in kwargs or 'cstride' in kwargs
- has_count = 'rcount' in kwargs or 'ccount' in kwargs
-
- if has_stride and has_count:
- raise ValueError("Cannot specify both stride and count arguments")
-
- rstride = kwargs.pop('rstride', 10)
- cstride = kwargs.pop('cstride', 10)
- rcount = kwargs.pop('rcount', 50)
- ccount = kwargs.pop('ccount', 50)
-
- if rcParams['_internal.classic_mode']:
- # Strides have priority over counts in classic mode.
- # So, only compute strides from counts
- # if counts were explicitly given
- if has_count:
- rstride = int(max(np.ceil(rows / rcount), 1))
- cstride = int(max(np.ceil(cols / ccount), 1))
- else:
- # If the strides are provided then it has priority.
- # Otherwise, compute the strides from the counts.
- if not has_stride:
- rstride = int(max(np.ceil(rows / rcount), 1))
- cstride = int(max(np.ceil(cols / ccount), 1))
-
- if 'facecolors' in kwargs:
- fcolors = kwargs.pop('facecolors')
- else:
- color = kwargs.pop('color', None)
- if color is None:
- color = self._get_lines.get_next_color()
- color = np.array(mcolors.to_rgba(color))
- fcolors = None
-
- cmap = kwargs.get('cmap', None)
- norm = kwargs.pop('norm', None)
- vmin = kwargs.pop('vmin', None)
- vmax = kwargs.pop('vmax', None)
- linewidth = kwargs.get('linewidth', None)
- shade = kwargs.pop('shade', cmap is None)
- lightsource = kwargs.pop('lightsource', None)
-
- # Shade the data
- if shade and cmap is not None and fcolors is not None:
- fcolors = self._shade_colors_lightsource(Z, cmap, lightsource)
-
- polys = []
- # Only need these vectors to shade if there is no cmap
- if cmap is None and shade :
- totpts = int(np.ceil((rows - 1) / rstride) *
- np.ceil((cols - 1) / cstride))
- v1 = np.empty((totpts, 3))
- v2 = np.empty((totpts, 3))
- # This indexes the vertex points
- which_pt = 0
-
-
- #colset contains the data for coloring: either average z or the facecolor
- colset = []
- for rs in xrange(0, rows-1, rstride):
- for cs in xrange(0, cols-1, cstride):
- ps = []
- for a in (X, Y, Z):
- ztop = a[rs,cs:min(cols, cs+cstride+1)]
- zleft = a[rs+1:min(rows, rs+rstride+1),
- min(cols-1, cs+cstride)]
- zbase = a[min(rows-1, rs+rstride), cs:min(cols, cs+cstride+1):][::-1]
- zright = a[rs:min(rows-1, rs+rstride):, cs][::-1]
- z = np.concatenate((ztop, zleft, zbase, zright))
- ps.append(z)
-
- # The construction leaves the array with duplicate points, which
- # are removed here.
- ps = list(zip(*ps))
- lastp = np.array([])
- ps2 = [ps[0]] + [ps[i] for i in xrange(1, len(ps)) if ps[i] != ps[i-1]]
- avgzsum = sum(p[2] for p in ps2)
- polys.append(ps2)
-
- if fcolors is not None:
- colset.append(fcolors[rs][cs])
- else:
- colset.append(avgzsum / len(ps2))
-
- # Only need vectors to shade if no cmap
- if cmap is None and shade:
- i1, i2, i3 = 0, int(len(ps2)/3), int(2*len(ps2)/3)
- v1[which_pt] = np.array(ps2[i1]) - np.array(ps2[i2])
- v2[which_pt] = np.array(ps2[i2]) - np.array(ps2[i3])
- which_pt += 1
- if cmap is None and shade:
- normals = np.cross(v1, v2)
- else :
- normals = []
-
- polyc = art3d.Poly3DCollection(polys, *args, **kwargs)
-
- if fcolors is not None:
- if shade:
- colset = self._shade_colors(colset, normals)
- polyc.set_facecolors(colset)
- polyc.set_edgecolors(colset)
- elif cmap:
- colset = np.array(colset)
- polyc.set_array(colset)
- if vmin is not None or vmax is not None:
- polyc.set_clim(vmin, vmax)
- if norm is not None:
- polyc.set_norm(norm)
- else:
- if shade:
- colset = self._shade_colors(color, normals)
- else:
- colset = color
- polyc.set_facecolors(colset)
-
- self.add_collection(polyc)
- self.auto_scale_xyz(X, Y, Z, had_data)
-
- return polyc
-
- def _generate_normals(self, polygons):
- '''
- Generate normals for polygons by using the first three points.
- This normal of course might not make sense for polygons with
- more than three points not lying in a plane.
- '''
-
- normals = []
- for verts in polygons:
- v1 = np.array(verts[0]) - np.array(verts[1])
- v2 = np.array(verts[2]) - np.array(verts[0])
- normals.append(np.cross(v1, v2))
- return normals
-
- def _shade_colors(self, color, normals):
- '''
- Shade *color* using normal vectors given by *normals*.
- *color* can also be an array of the same length as *normals*.
- '''
-
- shade = np.array([np.dot(n / proj3d.mod(n), [-1, -1, 0.5])
- if proj3d.mod(n) else np.nan
- for n in normals])
- mask = ~np.isnan(shade)
-
- if len(shade[mask]) > 0:
- norm = Normalize(min(shade[mask]), max(shade[mask]))
- shade[~mask] = min(shade[mask])
- color = mcolors.to_rgba_array(color)
- # shape of color should be (M, 4) (where M is number of faces)
- # shape of shade should be (M,)
- # colors should have final shape of (M, 4)
- alpha = color[:, 3]
- colors = (0.5 + norm(shade)[:, np.newaxis] * 0.5) * color
- colors[:, 3] = alpha
- else:
- colors = np.asanyarray(color).copy()
-
- return colors
-
- def _shade_colors_lightsource(self, data, cmap, lightsource):
- if lightsource is None:
- lightsource = LightSource(azdeg=135, altdeg=55)
- return lightsource.shade(data, cmap)
-
- def plot_wireframe(self, X, Y, Z, *args, **kwargs):
- """
- Plot a 3D wireframe.
-
- .. note::
-
- The *rcount* and *ccount* kwargs, which both default to 50,
- determine the maximum number of samples used in each direction. If
- the input data is larger, it will be downsampled (by slicing) to
- these numbers of points.
-
- Parameters
- ----------
- X, Y, Z : 2d arrays
- Data values.
-
- rcount, ccount : int
- Maximum number of samples used in each direction. If the input
- data is larger, it will be downsampled (by slicing) to these
- numbers of points. Setting a count to zero causes the data to be
- not sampled in the corresponding direction, producing a 3D line
- plot rather than a wireframe plot. Defaults to 50.
-
- .. versionadded:: 2.0
-
- rstride, cstride : int
- Downsampling stride in each direction. These arguments are
- mutually exclusive with *rcount* and *ccount*. If only one of
- *rstride* or *cstride* is set, the other defaults to 1. Setting a
- stride to zero causes the data to be not sampled in the
- corresponding direction, producing a 3D line plot rather than a
- wireframe plot.
-
- 'classic' mode uses a default of ``rstride = cstride = 1`` instead
- of the new default of ``rcount = ccount = 50``.
-
- **kwargs :
- Other arguments are forwarded to `.Line3DCollection`.
- """
-
- had_data = self.has_data()
- if Z.ndim != 2:
- raise ValueError("Argument Z must be 2-dimensional.")
- # FIXME: Support masked arrays
- X, Y, Z = np.broadcast_arrays(X, Y, Z)
- rows, cols = Z.shape
-
- has_stride = 'rstride' in kwargs or 'cstride' in kwargs
- has_count = 'rcount' in kwargs or 'ccount' in kwargs
-
- if has_stride and has_count:
- raise ValueError("Cannot specify both stride and count arguments")
-
- rstride = kwargs.pop('rstride', 1)
- cstride = kwargs.pop('cstride', 1)
- rcount = kwargs.pop('rcount', 50)
- ccount = kwargs.pop('ccount', 50)
-
- if rcParams['_internal.classic_mode']:
- # Strides have priority over counts in classic mode.
- # So, only compute strides from counts
- # if counts were explicitly given
- if has_count:
- rstride = int(max(np.ceil(rows / rcount), 1)) if rcount else 0
- cstride = int(max(np.ceil(cols / ccount), 1)) if ccount else 0
- else:
- # If the strides are provided then it has priority.
- # Otherwise, compute the strides from the counts.
- if not has_stride:
- rstride = int(max(np.ceil(rows / rcount), 1)) if rcount else 0
- cstride = int(max(np.ceil(cols / ccount), 1)) if ccount else 0
-
- # We want two sets of lines, one running along the "rows" of
- # Z and another set of lines running along the "columns" of Z.
- # This transpose will make it easy to obtain the columns.
- tX, tY, tZ = np.transpose(X), np.transpose(Y), np.transpose(Z)
-
- if rstride:
- rii = list(xrange(0, rows, rstride))
- # Add the last index only if needed
- if rows > 0 and rii[-1] != (rows - 1):
- rii += [rows-1]
- else:
- rii = []
- if cstride:
- cii = list(xrange(0, cols, cstride))
- # Add the last index only if needed
- if cols > 0 and cii[-1] != (cols - 1):
- cii += [cols-1]
- else:
- cii = []
-
- if rstride == 0 and cstride == 0:
- raise ValueError("Either rstride or cstride must be non zero")
-
- # If the inputs were empty, then just
- # reset everything.
- if Z.size == 0:
- rii = []
- cii = []
-
- xlines = [X[i] for i in rii]
- ylines = [Y[i] for i in rii]
- zlines = [Z[i] for i in rii]
-
- txlines = [tX[i] for i in cii]
- tylines = [tY[i] for i in cii]
- tzlines = [tZ[i] for i in cii]
-
- lines = ([list(zip(xl, yl, zl))
- for xl, yl, zl in zip(xlines, ylines, zlines)]
- + [list(zip(xl, yl, zl))
- for xl, yl, zl in zip(txlines, tylines, tzlines)])
-
- linec = art3d.Line3DCollection(lines, *args, **kwargs)
- self.add_collection(linec)
- self.auto_scale_xyz(X, Y, Z, had_data)
-
- return linec
-
- def plot_trisurf(self, *args, **kwargs):
- """
- ============= ================================================
- Argument Description
- ============= ================================================
- *X*, *Y*, *Z* Data values as 1D arrays
- *color* Color of the surface patches
- *cmap* A colormap for the surface patches.
- *norm* An instance of Normalize to map values to colors
- *vmin* Minimum value to map
- *vmax* Maximum value to map
- *shade* Whether to shade the facecolors
- ============= ================================================
-
- The (optional) triangulation can be specified in one of two ways;
- either::
-
- plot_trisurf(triangulation, ...)
-
- where triangulation is a :class:`~matplotlib.tri.Triangulation`
- object, or::
-
- plot_trisurf(X, Y, ...)
- plot_trisurf(X, Y, triangles, ...)
- plot_trisurf(X, Y, triangles=triangles, ...)
-
- in which case a Triangulation object will be created. See
- :class:`~matplotlib.tri.Triangulation` for a explanation of
- these possibilities.
-
- The remaining arguments are::
-
- plot_trisurf(..., Z)
-
- where *Z* is the array of values to contour, one per point
- in the triangulation.
-
- Other arguments are passed on to
- :class:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection`
-
- **Examples:**
-
- .. plot:: gallery/mplot3d/trisurf3d.py
- .. plot:: gallery/mplot3d/trisurf3d_2.py
-
- .. versionadded:: 1.2.0
- This plotting function was added for the v1.2.0 release.
- """
-
- had_data = self.has_data()
-
- # TODO: Support custom face colours
- color = kwargs.pop('color', None)
- if color is None:
- color = self._get_lines.get_next_color()
- color = np.array(mcolors.to_rgba(color))
-
- cmap = kwargs.get('cmap', None)
- norm = kwargs.pop('norm', None)
- vmin = kwargs.pop('vmin', None)
- vmax = kwargs.pop('vmax', None)
- linewidth = kwargs.get('linewidth', None)
- shade = kwargs.pop('shade', cmap is None)
- lightsource = kwargs.pop('lightsource', None)
-
- tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args, **kwargs)
- if 'Z' in kwargs:
- z = np.asarray(kwargs.pop('Z'))
- else:
- z = np.asarray(args[0])
- # We do this so Z doesn't get passed as an arg to PolyCollection
- args = args[1:]
-
- triangles = tri.get_masked_triangles()
- xt = tri.x[triangles]
- yt = tri.y[triangles]
- zt = z[triangles]
-
- # verts = np.stack((xt, yt, zt), axis=-1)
- verts = np.concatenate((
- xt[..., np.newaxis], yt[..., np.newaxis], zt[..., np.newaxis]
- ), axis=-1)
-
- polyc = art3d.Poly3DCollection(verts, *args, **kwargs)
-
- if cmap:
- # average over the three points of each triangle
- avg_z = verts[:, :, 2].mean(axis=1)
- polyc.set_array(avg_z)
- if vmin is not None or vmax is not None:
- polyc.set_clim(vmin, vmax)
- if norm is not None:
- polyc.set_norm(norm)
- else:
- if shade:
- v1 = verts[:, 0, :] - verts[:, 1, :]
- v2 = verts[:, 1, :] - verts[:, 2, :]
- normals = np.cross(v1, v2)
- colset = self._shade_colors(color, normals)
- else:
- colset = color
- polyc.set_facecolors(colset)
-
- self.add_collection(polyc)
- self.auto_scale_xyz(tri.x, tri.y, z, had_data)
-
- return polyc
-
- def _3d_extend_contour(self, cset, stride=5):
- '''
- Extend a contour in 3D by creating
- '''
-
- levels = cset.levels
- colls = cset.collections
- dz = (levels[1] - levels[0]) / 2
-
- for z, linec in zip(levels, colls):
- topverts = art3d.paths_to_3d_segments(linec.get_paths(), z - dz)
- botverts = art3d.paths_to_3d_segments(linec.get_paths(), z + dz)
-
- color = linec.get_color()[0]
-
- polyverts = []
- normals = []
- nsteps = np.round(len(topverts[0]) / stride)
- if nsteps <= 1:
- if len(topverts[0]) > 1:
- nsteps = 2
- else:
- continue
-
- stepsize = (len(topverts[0]) - 1) / (nsteps - 1)
- for i in range(int(np.round(nsteps)) - 1):
- i1 = int(np.round(i * stepsize))
- i2 = int(np.round((i + 1) * stepsize))
- polyverts.append([topverts[0][i1],
- topverts[0][i2],
- botverts[0][i2],
- botverts[0][i1]])
-
- v1 = np.array(topverts[0][i1]) - np.array(topverts[0][i2])
- v2 = np.array(topverts[0][i1]) - np.array(botverts[0][i1])
- normals.append(np.cross(v1, v2))
-
- colors = self._shade_colors(color, normals)
- colors2 = self._shade_colors(color, normals)
- polycol = art3d.Poly3DCollection(polyverts,
- facecolors=colors,
- edgecolors=colors2)
- polycol.set_sort_zpos(z)
- self.add_collection3d(polycol)
-
- for col in colls:
- self.collections.remove(col)
-
- def add_contour_set(self, cset, extend3d=False, stride=5, zdir='z', offset=None):
- zdir = '-' + zdir
- if extend3d:
- self._3d_extend_contour(cset, stride)
- else:
- for z, linec in zip(cset.levels, cset.collections):
- if offset is not None:
- z = offset
- art3d.line_collection_2d_to_3d(linec, z, zdir=zdir)
-
- def add_contourf_set(self, cset, zdir='z', offset=None):
- zdir = '-' + zdir
- for z, linec in zip(cset.levels, cset.collections):
- if offset is not None :
- z = offset
- art3d.poly_collection_2d_to_3d(linec, z, zdir=zdir)
- linec.set_sort_zpos(z)
-
- def contour(self, X, Y, Z, *args, **kwargs):
- '''
- Create a 3D contour plot.
-
- ========== ================================================
- Argument Description
- ========== ================================================
- *X*, *Y*, Data values as numpy.arrays
- *Z*
- *extend3d* Whether to extend contour in 3D (default: False)
- *stride* Stride (step size) for extending contour
- *zdir* The direction to use: x, y or z (default)
- *offset* If specified plot a projection of the contour
- lines on this position in plane normal to zdir
- ========== ================================================
-
- The positional and other keyword arguments are passed on to
- :func:`~matplotlib.axes.Axes.contour`
-
- Returns a :class:`~matplotlib.axes.Axes.contour`
- '''
-
- extend3d = kwargs.pop('extend3d', False)
- stride = kwargs.pop('stride', 5)
- zdir = kwargs.pop('zdir', 'z')
- offset = kwargs.pop('offset', None)
-
- had_data = self.has_data()
-
- jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir)
- cset = super(Axes3D, self).contour(jX, jY, jZ, *args, **kwargs)
- self.add_contour_set(cset, extend3d, stride, zdir, offset)
-
- self.auto_scale_xyz(X, Y, Z, had_data)
- return cset
-
- contour3D = contour
-
- def tricontour(self, *args, **kwargs):
- """
- Create a 3D contour plot.
-
- ========== ================================================
- Argument Description
- ========== ================================================
- *X*, *Y*, Data values as numpy.arrays
- *Z*
- *extend3d* Whether to extend contour in 3D (default: False)
- *stride* Stride (step size) for extending contour
- *zdir* The direction to use: x, y or z (default)
- *offset* If specified plot a projection of the contour
- lines on this position in plane normal to zdir
- ========== ================================================
-
- Other keyword arguments are passed on to
- :func:`~matplotlib.axes.Axes.tricontour`
-
- Returns a :class:`~matplotlib.axes.Axes.contour`
-
- .. versionchanged:: 1.3.0
- Added support for custom triangulations
-
- EXPERIMENTAL: This method currently produces incorrect output due to a
- longstanding bug in 3D PolyCollection rendering.
- """
-
- extend3d = kwargs.pop('extend3d', False)
- stride = kwargs.pop('stride', 5)
- zdir = kwargs.pop('zdir', 'z')
- offset = kwargs.pop('offset', None)
-
- had_data = self.has_data()
-
- tri, args, kwargs = Triangulation.get_from_args_and_kwargs(
- *args, **kwargs)
- X = tri.x
- Y = tri.y
- if 'Z' in kwargs:
- Z = kwargs.pop('Z')
- else:
- Z = args[0]
- # We do this so Z doesn't get passed as an arg to Axes.tricontour
- args = args[1:]
-
- jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir)
- tri = Triangulation(jX, jY, tri.triangles, tri.mask)
-
- cset = super(Axes3D, self).tricontour(tri, jZ, *args, **kwargs)
- self.add_contour_set(cset, extend3d, stride, zdir, offset)
-
- self.auto_scale_xyz(X, Y, Z, had_data)
- return cset
-
- def contourf(self, X, Y, Z, *args, **kwargs):
- '''
- Create a 3D contourf plot.
-
- ========== ================================================
- Argument Description
- ========== ================================================
- *X*, *Y*, Data values as numpy.arrays
- *Z*
- *zdir* The direction to use: x, y or z (default)
- *offset* If specified plot a projection of the filled contour
- on this position in plane normal to zdir
- ========== ================================================
-
- The positional and keyword arguments are passed on to
- :func:`~matplotlib.axes.Axes.contourf`
-
- Returns a :class:`~matplotlib.axes.Axes.contourf`
-
- .. versionchanged :: 1.1.0
- The *zdir* and *offset* kwargs were added.
- '''
-
- zdir = kwargs.pop('zdir', 'z')
- offset = kwargs.pop('offset', None)
-
- had_data = self.has_data()
-
- jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir)
- cset = super(Axes3D, self).contourf(jX, jY, jZ, *args, **kwargs)
- self.add_contourf_set(cset, zdir, offset)
-
- self.auto_scale_xyz(X, Y, Z, had_data)
- return cset
-
- contourf3D = contourf
-
- def tricontourf(self, *args, **kwargs):
- """
- Create a 3D contourf plot.
-
- ========== ================================================
- Argument Description
- ========== ================================================
- *X*, *Y*, Data values as numpy.arrays
- *Z*
- *zdir* The direction to use: x, y or z (default)
- *offset* If specified plot a projection of the contour
- lines on this position in plane normal to zdir
- ========== ================================================
-
- Other keyword arguments are passed on to
- :func:`~matplotlib.axes.Axes.tricontour`
-
- Returns a :class:`~matplotlib.axes.Axes.contour`
-
- .. versionchanged :: 1.3.0
- Added support for custom triangulations
-
- EXPERIMENTAL: This method currently produces incorrect output due to a
- longstanding bug in 3D PolyCollection rendering.
- """
- zdir = kwargs.pop('zdir', 'z')
- offset = kwargs.pop('offset', None)
-
- had_data = self.has_data()
-
- tri, args, kwargs = Triangulation.get_from_args_and_kwargs(
- *args, **kwargs)
- X = tri.x
- Y = tri.y
- if 'Z' in kwargs:
- Z = kwargs.pop('Z')
- else:
- Z = args[0]
- # We do this so Z doesn't get passed as an arg to Axes.tricontourf
- args = args[1:]
-
- jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir)
- tri = Triangulation(jX, jY, tri.triangles, tri.mask)
-
- cset = super(Axes3D, self).tricontourf(tri, jZ, *args, **kwargs)
- self.add_contourf_set(cset, zdir, offset)
-
- self.auto_scale_xyz(X, Y, Z, had_data)
- return cset
-
- def add_collection3d(self, col, zs=0, zdir='z'):
- '''
- Add a 3D collection object to the plot.
-
- 2D collection types are converted to a 3D version by
- modifying the object and adding z coordinate information.
-
- Supported are:
- - PolyCollection
- - LineCollection
- - PatchCollection
- '''
- zvals = np.atleast_1d(zs)
- if len(zvals) > 0 :
- zsortval = min(zvals)
- else :
- zsortval = 0 # FIXME: Fairly arbitrary. Is there a better value?
-
- # FIXME: use issubclass() (although, then a 3D collection
- # object would also pass.) Maybe have a collection3d
- # abstract class to test for and exclude?
- if type(col) is mcoll.PolyCollection:
- art3d.poly_collection_2d_to_3d(col, zs=zs, zdir=zdir)
- col.set_sort_zpos(zsortval)
- elif type(col) is mcoll.LineCollection:
- art3d.line_collection_2d_to_3d(col, zs=zs, zdir=zdir)
- col.set_sort_zpos(zsortval)
- elif type(col) is mcoll.PatchCollection:
- art3d.patch_collection_2d_to_3d(col, zs=zs, zdir=zdir)
- col.set_sort_zpos(zsortval)
-
- super(Axes3D, self).add_collection(col)
-
- def scatter(self, xs, ys, zs=0, zdir='z', s=20, c=None, depthshade=True,
- *args, **kwargs):
- '''
- Create a scatter plot.
-
- ============ ========================================================
- Argument Description
- ============ ========================================================
- *xs*, *ys* Positions of data points.
- *zs* Either an array of the same length as *xs* and
- *ys* or a single value to place all points in
- the same plane. Default is 0.
- *zdir* Which direction to use as z ('x', 'y' or 'z')
- when plotting a 2D set.
- *s* Size in points^2. It is a scalar or an array of the
- same length as *x* and *y*.
-
- *c* A color. *c* can be a single color format string, or a
- sequence of color specifications of length *N*, or a
- sequence of *N* numbers to be mapped to colors using the
- *cmap* and *norm* specified via kwargs (see below). Note
- that *c* should not be a single numeric RGB or RGBA
- sequence because that is indistinguishable from an array
- of values to be colormapped. *c* can be a 2-D array in
- which the rows are RGB or RGBA, however, including the
- case of a single row to specify the same color for
- all points.
-
- *depthshade*
- Whether or not to shade the scatter markers to give
- the appearance of depth. Default is *True*.
- ============ ========================================================
-
- Keyword arguments are passed on to
- :func:`~matplotlib.axes.Axes.scatter`.
-
- Returns a :class:`~mpl_toolkits.mplot3d.art3d.Patch3DCollection`
- '''
-
- had_data = self.has_data()
-
- xs, ys, zs = np.broadcast_arrays(
- *[np.ravel(np.ma.filled(t, np.nan)) for t in [xs, ys, zs]])
- s = np.ma.ravel(s) # This doesn't have to match x, y in size.
-
- xs, ys, zs, s, c = cbook.delete_masked_points(xs, ys, zs, s, c)
-
- patches = super(Axes3D, self).scatter(
- xs, ys, s=s, c=c, *args, **kwargs)
- is_2d = not cbook.iterable(zs)
- zs = _backports.broadcast_to(zs, len(xs))
- art3d.patch_collection_2d_to_3d(patches, zs=zs, zdir=zdir,
- depthshade=depthshade)
-
- if self._zmargin < 0.05 and xs.size > 0:
- self.set_zmargin(0.05)
-
- #FIXME: why is this necessary?
- if not is_2d:
- self.auto_scale_xyz(xs, ys, zs, had_data)
-
- return patches
-
- scatter3D = scatter
-
- def bar(self, left, height, zs=0, zdir='z', *args, **kwargs):
- '''
- Add 2D bar(s).
-
- ========== ================================================
- Argument Description
- ========== ================================================
- *left* The x coordinates of the left sides of the bars.
- *height* The height of the bars.
- *zs* Z coordinate of bars, if one value is specified
- they will all be placed at the same z.
- *zdir* Which direction to use as z ('x', 'y' or 'z')
- when plotting a 2D set.
- ========== ================================================
-
- Keyword arguments are passed onto :func:`~matplotlib.axes.Axes.bar`.
-
- Returns a :class:`~mpl_toolkits.mplot3d.art3d.Patch3DCollection`
- '''
-
- had_data = self.has_data()
-
- patches = super(Axes3D, self).bar(left, height, *args, **kwargs)
-
- zs = _backports.broadcast_to(zs, len(left))
-
- verts = []
- verts_zs = []
- for p, z in zip(patches, zs):
- vs = art3d.get_patch_verts(p)
- verts += vs.tolist()
- verts_zs += [z] * len(vs)
- art3d.patch_2d_to_3d(p, z, zdir)
- if 'alpha' in kwargs:
- p.set_alpha(kwargs['alpha'])
-
- if len(verts) > 0 :
- # the following has to be skipped if verts is empty
- # NOTE: Bugs could still occur if len(verts) > 0,
- # but the "2nd dimension" is empty.
- xs, ys = list(zip(*verts))
- else :
- xs, ys = [], []
-
- xs, ys, verts_zs = art3d.juggle_axes(xs, ys, verts_zs, zdir)
- self.auto_scale_xyz(xs, ys, verts_zs, had_data)
-
- return patches
-
- def bar3d(self, x, y, z, dx, dy, dz, color=None,
- zsort='average', shade=True, *args, **kwargs):
- """Generate a 3D barplot.
-
- This method creates three dimensional barplot where the width,
- depth, height, and color of the bars can all be uniquely set.
-
- Parameters
- ----------
- x, y, z : array-like
- The coordinates of the anchor point of the bars.
-
- dx, dy, dz : scalar or array-like
- The width, depth, and height of the bars, respectively.
-
- color : sequence of valid color specifications, optional
- The color of the bars can be specified globally or
- individually. This parameter can be:
-
- - A single color value, to color all bars the same color.
- - An array of colors of length N bars, to color each bar
- independently.
- - An array of colors of length 6, to color the faces of the
- bars similarly.
- - An array of colors of length 6 * N bars, to color each face
- independently.
-
- When coloring the faces of the boxes specifically, this is
- the order of the coloring:
-
- 1. -Z (bottom of box)
- 2. +Z (top of box)
- 3. -Y
- 4. +Y
- 5. -X
- 6. +X
-
- zsort : str, optional
- The z-axis sorting scheme passed onto
- :func:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection`
-
- shade : bool, optional (default = True)
- When true, this shades the dark sides of the bars (relative
- to the plot's source of light).
-
- Any additional keyword arguments are passed onto
- :func:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection`
-
- Returns
- -------
- collection : Poly3DCollection
- A collection of three dimensional polygons representing
- the bars.
- """
-
- had_data = self.has_data()
-
- x, y, z, dx, dy, dz = np.broadcast_arrays(
- np.atleast_1d(x), y, z, dx, dy, dz)
- minx = np.min(x)
- maxx = np.max(x + dx)
- miny = np.min(y)
- maxy = np.max(y + dy)
- minz = np.min(z)
- maxz = np.max(z + dz)
-
- polys = []
- for xi, yi, zi, dxi, dyi, dzi in zip(x, y, z, dx, dy, dz):
- polys.extend([
- ((xi, yi, zi), (xi + dxi, yi, zi),
- (xi + dxi, yi + dyi, zi), (xi, yi + dyi, zi)),
- ((xi, yi, zi + dzi), (xi + dxi, yi, zi + dzi),
- (xi + dxi, yi + dyi, zi + dzi), (xi, yi + dyi, zi + dzi)),
-
- ((xi, yi, zi), (xi + dxi, yi, zi),
- (xi + dxi, yi, zi + dzi), (xi, yi, zi + dzi)),
- ((xi, yi + dyi, zi), (xi + dxi, yi + dyi, zi),
- (xi + dxi, yi + dyi, zi + dzi), (xi, yi + dyi, zi + dzi)),
-
- ((xi, yi, zi), (xi, yi + dyi, zi),
- (xi, yi + dyi, zi + dzi), (xi, yi, zi + dzi)),
- ((xi + dxi, yi, zi), (xi + dxi, yi + dyi, zi),
- (xi + dxi, yi + dyi, zi + dzi), (xi + dxi, yi, zi + dzi)),
- ])
-
- facecolors = []
- if color is None:
- color = [self._get_patches_for_fill.get_next_color()]
-
- if len(color) == len(x):
- # bar colors specified, need to expand to number of faces
- for c in color:
- facecolors.extend([c] * 6)
- else:
- # a single color specified, or face colors specified explicitly
- facecolors = list(mcolors.to_rgba_array(color))
- if len(facecolors) < len(x):
- facecolors *= (6 * len(x))
-
- if shade:
- normals = self._generate_normals(polys)
- sfacecolors = self._shade_colors(facecolors, normals)
- else:
- sfacecolors = facecolors
-
- col = art3d.Poly3DCollection(polys,
- zsort=zsort,
- facecolor=sfacecolors,
- *args, **kwargs)
- self.add_collection(col)
-
- self.auto_scale_xyz((minx, maxx), (miny, maxy), (minz, maxz), had_data)
-
- return col
-
- def set_title(self, label, fontdict=None, loc='center', **kwargs):
- ret = super(Axes3D, self).set_title(label, fontdict=fontdict, loc=loc,
- **kwargs)
- (x, y) = self.title.get_position()
- self.title.set_y(0.92 * y)
- return ret
- set_title.__doc__ = maxes.Axes.set_title.__doc__
-
- def quiver(self, *args, **kwargs):
- """
- Plot a 3D field of arrows.
-
- call signatures::
-
- quiver(X, Y, Z, U, V, W, **kwargs)
-
- Arguments:
-
- *X*, *Y*, *Z*:
- The x, y and z coordinates of the arrow locations (default is
- tail of arrow; see *pivot* kwarg)
-
- *U*, *V*, *W*:
- The x, y and z components of the arrow vectors
-
- The arguments could be array-like or scalars, so long as they
- they can be broadcast together. The arguments can also be
- masked arrays. If an element in any of argument is masked, then
- that corresponding quiver element will not be plotted.
-
- Keyword arguments:
-
- *length*: [1.0 | float]
- The length of each quiver, default to 1.0, the unit is
- the same with the axes
-
- *arrow_length_ratio*: [0.3 | float]
- The ratio of the arrow head with respect to the quiver,
- default to 0.3
-
- *pivot*: [ 'tail' | 'middle' | 'tip' ]
- The part of the arrow that is at the grid point; the arrow
- rotates about this point, hence the name *pivot*.
- Default is 'tail'
-
- *normalize*: bool
- When True, all of the arrows will be the same length. This
- defaults to False, where the arrows will be different lengths
- depending on the values of u,v,w.
-
- Any additional keyword arguments are delegated to
- :class:`~matplotlib.collections.LineCollection`
-
- """
- def calc_arrow(uvw, angle=15):
- """
- To calculate the arrow head. uvw should be a unit vector.
- We normalize it here:
- """
- # get unit direction vector perpendicular to (u,v,w)
- norm = np.linalg.norm(uvw[:2])
- if norm > 0:
- x = uvw[1] / norm
- y = -uvw[0] / norm
- else:
- x, y = 0, 1
-
- # compute the two arrowhead direction unit vectors
- ra = math.radians(angle)
- c = math.cos(ra)
- s = math.sin(ra)
-
- # construct the rotation matrices
- Rpos = np.array([[c+(x**2)*(1-c), x*y*(1-c), y*s],
- [y*x*(1-c), c+(y**2)*(1-c), -x*s],
- [-y*s, x*s, c]])
- # opposite rotation negates all the sin terms
- Rneg = Rpos.copy()
- Rneg[[0,1,2,2],[2,2,0,1]] = -Rneg[[0,1,2,2],[2,2,0,1]]
-
- # multiply them to get the rotated vector
- return Rpos.dot(uvw), Rneg.dot(uvw)
-
- had_data = self.has_data()
-
- # handle kwargs
- # shaft length
- length = kwargs.pop('length', 1)
- # arrow length ratio to the shaft length
- arrow_length_ratio = kwargs.pop('arrow_length_ratio', 0.3)
- # pivot point
- pivot = kwargs.pop('pivot', 'tail')
- # normalize
- normalize = kwargs.pop('normalize', False)
-
- # handle args
- argi = 6
- if len(args) < argi:
- raise ValueError('Wrong number of arguments. Expected %d got %d' %
- (argi, len(args)))
-
- # first 6 arguments are X, Y, Z, U, V, W
- input_args = args[:argi]
- # if any of the args are scalar, convert into list
- input_args = [[k] if isinstance(k, (int, float)) else k
- for k in input_args]
-
- # extract the masks, if any
- masks = [k.mask for k in input_args if isinstance(k, np.ma.MaskedArray)]
- # broadcast to match the shape
- bcast = np.broadcast_arrays(*(input_args + masks))
- input_args = bcast[:argi]
- masks = bcast[argi:]
- if masks:
- # combine the masks into one
- mask = reduce(np.logical_or, masks)
- # put mask on and compress
- input_args = [np.ma.array(k, mask=mask).compressed()
- for k in input_args]
- else:
- input_args = [k.flatten() for k in input_args]
-
- if any(len(v) == 0 for v in input_args):
- # No quivers, so just make an empty collection and return early
- linec = art3d.Line3DCollection([], *args[argi:], **kwargs)
- self.add_collection(linec)
- return linec
-
- # Following assertions must be true before proceeding
- # must all be ndarray
- assert all(isinstance(k, np.ndarray) for k in input_args)
- # must all in same shape
- assert len({k.shape for k in input_args}) == 1
-
- shaft_dt = np.linspace(0, length, num=2)
- arrow_dt = shaft_dt * arrow_length_ratio
-
- if pivot == 'tail':
- shaft_dt -= length
- elif pivot == 'middle':
- shaft_dt -= length/2.
- elif pivot != 'tip':
- raise ValueError('Invalid pivot argument: ' + str(pivot))
-
- XYZ = np.column_stack(input_args[:3])
- UVW = np.column_stack(input_args[3:argi]).astype(float)
-
- # Normalize rows of UVW
- # Note: with numpy 1.9+, could use np.linalg.norm(UVW, axis=1)
- norm = np.sqrt(np.sum(UVW**2, axis=1))
-
- # If any row of UVW is all zeros, don't make a quiver for it
- mask = norm > 0
- XYZ = XYZ[mask]
- if normalize:
- UVW = UVW[mask] / norm[mask].reshape((-1, 1))
- else:
- UVW = UVW[mask]
-
- if len(XYZ) > 0:
- # compute the shaft lines all at once with an outer product
- shafts = (XYZ - np.multiply.outer(shaft_dt, UVW)).swapaxes(0, 1)
- # compute head direction vectors, n heads by 2 sides by 3 dimensions
- head_dirs = np.array([calc_arrow(d) for d in UVW])
- # compute all head lines at once, starting from where the shaft ends
- heads = shafts[:, :1] - np.multiply.outer(arrow_dt, head_dirs)
- # stack left and right head lines together
- heads.shape = (len(arrow_dt), -1, 3)
- # transpose to get a list of lines
- heads = heads.swapaxes(0, 1)
-
- lines = list(shafts) + list(heads)
- else:
- lines = []
-
- linec = art3d.Line3DCollection(lines, *args[argi:], **kwargs)
- self.add_collection(linec)
-
- self.auto_scale_xyz(XYZ[:, 0], XYZ[:, 1], XYZ[:, 2], had_data)
-
- return linec
-
- quiver3D = quiver
-
- def voxels(self, *args, **kwargs):
- """
- ax.voxels([x, y, z,] /, filled, **kwargs)
-
- Plot a set of filled voxels
-
- All voxels are plotted as 1x1x1 cubes on the axis, with filled[0,0,0]
- placed with its lower corner at the origin. Occluded faces are not
- plotted.
-
- Call signatures::
-
- voxels(filled, facecolors=fc, edgecolors=ec, **kwargs)
- voxels(x, y, z, filled, facecolors=fc, edgecolors=ec, **kwargs)
-
- .. versionadded:: 2.1
-
- Parameters
- ----------
- filled : 3D np.array of bool
- A 3d array of values, with truthy values indicating which voxels
- to fill
-
- x, y, z : 3D np.array, optional
- The coordinates of the corners of the voxels. This should broadcast
- to a shape one larger in every dimension than the shape of `filled`.
- These can be used to plot non-cubic voxels.
-
- If not specified, defaults to increasing integers along each axis,
- like those returned by :func:`~numpy.indices`.
- As indicated by the ``/`` in the function signature, these arguments
- can only be passed positionally.
-
- facecolors, edgecolors : array_like, optional
- The color to draw the faces and edges of the voxels. Can only be
- passed as keyword arguments.
- This parameter can be:
-
- - A single color value, to color all voxels the same color. This
- can be either a string, or a 1D rgb/rgba array
- - ``None``, the default, to use a single color for the faces, and
- the style default for the edges.
- - A 3D ndarray of color names, with each item the color for the
- corresponding voxel. The size must match the voxels.
- - A 4D ndarray of rgb/rgba data, with the components along the
- last axis.
-
- **kwargs
- Additional keyword arguments to pass onto
- :func:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection`
-
- Returns
- -------
- faces : dict
- A dictionary indexed by coordinate, where ``faces[i,j,k]`` is a
- `Poly3DCollection` of the faces drawn for the voxel
- ``filled[i,j,k]``. If no faces were drawn for a given voxel, either
- because it was not asked to be drawn, or it is fully occluded, then
- ``(i,j,k) not in faces``.
-
- Examples
- --------
- .. plot:: gallery/mplot3d/voxels.py
- .. plot:: gallery/mplot3d/voxels_rgb.py
- .. plot:: gallery/mplot3d/voxels_torus.py
- .. plot:: gallery/mplot3d/voxels_numpy_logo.py
- """
-
- # work out which signature we should be using, and use it to parse
- # the arguments. Name must be voxels for the correct error message
- if len(args) >= 3:
- # underscores indicate position only
- def voxels(__x, __y, __z, filled, **kwargs):
- return (__x, __y, __z), filled, kwargs
- else:
- def voxels(filled, **kwargs):
- return None, filled, kwargs
-
- xyz, filled, kwargs = voxels(*args, **kwargs)
-
- # check dimensions
- if filled.ndim != 3:
- raise ValueError("Argument filled must be 3-dimensional")
- size = np.array(filled.shape, dtype=np.intp)
-
- # check xyz coordinates, which are one larger than the filled shape
- coord_shape = tuple(size + 1)
- if xyz is None:
- x, y, z = np.indices(coord_shape)
- else:
- x, y, z = (_backports.broadcast_to(c, coord_shape) for c in xyz)
-
- def _broadcast_color_arg(color, name):
- if np.ndim(color) in (0, 1):
- # single color, like "red" or [1, 0, 0]
- return _backports.broadcast_to(
- color, filled.shape + np.shape(color))
- elif np.ndim(color) in (3, 4):
- # 3D array of strings, or 4D array with last axis rgb
- if np.shape(color)[:3] != filled.shape:
- raise ValueError(
- "When multidimensional, {} must match the shape of "
- "filled".format(name))
- return color
- else:
- raise ValueError("Invalid {} argument".format(name))
-
- # intercept the facecolors, handling defaults and broacasting
- facecolors = kwargs.pop('facecolors', None)
- if facecolors is None:
- facecolors = self._get_patches_for_fill.get_next_color()
- facecolors = _broadcast_color_arg(facecolors, 'facecolors')
-
- # broadcast but no default on edgecolors
- edgecolors = kwargs.pop('edgecolors', None)
- edgecolors = _broadcast_color_arg(edgecolors, 'edgecolors')
-
- # always scale to the full array, even if the data is only in the center
- self.auto_scale_xyz(x, y, z)
-
- # points lying on corners of a square
- square = np.array([
- [0, 0, 0],
- [0, 1, 0],
- [1, 1, 0],
- [1, 0, 0]
- ], dtype=np.intp)
-
- voxel_faces = defaultdict(list)
-
- def permutation_matrices(n):
- """ Generator of cyclic permutation matices """
- mat = np.eye(n, dtype=np.intp)
- for i in range(n):
- yield mat
- mat = np.roll(mat, 1, axis=0)
-
- # iterate over each of the YZ, ZX, and XY orientations, finding faces to
- # render
- for permute in permutation_matrices(3):
- # find the set of ranges to iterate over
- pc, qc, rc = permute.T.dot(size)
- pinds = np.arange(pc)
- qinds = np.arange(qc)
- rinds = np.arange(rc)
-
- square_rot = square.dot(permute.T)
-
- # iterate within the current plane
- for p in pinds:
- for q in qinds:
- # iterate perpendicularly to the current plane, handling
- # boundaries. We only draw faces between a voxel and an
- # empty space, to avoid drawing internal faces.
-
- # draw lower faces
- p0 = permute.dot([p, q, 0])
- i0 = tuple(p0)
- if filled[i0]:
- voxel_faces[i0].append(p0 + square_rot)
-
- # draw middle faces
- for r1, r2 in zip(rinds[:-1], rinds[1:]):
- p1 = permute.dot([p, q, r1])
- p2 = permute.dot([p, q, r2])
-
- i1 = tuple(p1)
- i2 = tuple(p2)
-
- if filled[i1] and not filled[i2]:
- voxel_faces[i1].append(p2 + square_rot)
- elif not filled[i1] and filled[i2]:
- voxel_faces[i2].append(p2 + square_rot)
-
- # draw upper faces
- pk = permute.dot([p, q, rc-1])
- pk2 = permute.dot([p, q, rc])
- ik = tuple(pk)
- if filled[ik]:
- voxel_faces[ik].append(pk2 + square_rot)
-
- # iterate over the faces, and generate a Poly3DCollection for each voxel
- polygons = {}
- for coord, faces_inds in voxel_faces.items():
- # convert indices into 3D positions
- if xyz is None:
- faces = faces_inds
- else:
- faces = []
- for face_inds in faces_inds:
- ind = face_inds[:, 0], face_inds[:, 1], face_inds[:, 2]
- face = np.empty(face_inds.shape)
- face[:, 0] = x[ind]
- face[:, 1] = y[ind]
- face[:, 2] = z[ind]
- faces.append(face)
-
- poly = art3d.Poly3DCollection(faces,
- facecolors=facecolors[coord],
- edgecolors=edgecolors[coord],
- **kwargs
- )
- self.add_collection3d(poly)
- polygons[coord] = poly
-
- return polygons
-
-
-def get_test_data(delta=0.05):
- '''
- Return a tuple X, Y, Z with a test data set.
- '''
- x = y = np.arange(-3.0, 3.0, delta)
- X, Y = np.meshgrid(x, y)
-
- Z1 = np.exp(-(X**2 + Y**2) / 2) / (2 * np.pi)
- Z2 = (np.exp(-(((X - 1) / 1.5)**2 + ((Y - 1) / 0.5)**2) / 2) /
- (2 * np.pi * 0.5 * 1.5))
- Z = Z2 - Z1
-
- X = X * 10
- Y = Y * 10
- Z = Z * 500
- return X, Y, Z
-
-
-########################################################
-# Register Axes3D as a 'projection' object available
-# for use just like any other axes
-########################################################
-import matplotlib.projections as proj
-proj.projection_registry.register(Axes3D)
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/axis3d.py b/contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/axis3d.py
deleted file mode 100644
index 50b81df912..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/axis3d.py
+++ /dev/null
@@ -1,484 +0,0 @@
-# axis3d.py, original mplot3d version by John Porter
-# Created: 23 Sep 2005
-# Parts rewritten by Reinier Heeres <reinier@heeres.eu>
-
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-
-import math
-import copy
-
-from matplotlib import lines as mlines, axis as maxis, patches as mpatches
-from matplotlib import rcParams
-from . import art3d
-from . import proj3d
-
-import numpy as np
-
-def get_flip_min_max(coord, index, mins, maxs):
- if coord[index] == mins[index]:
- return maxs[index]
- else:
- return mins[index]
-
-def move_from_center(coord, centers, deltas, axmask=(True, True, True)):
- '''Return a coordinate that is moved by "deltas" away from the center.'''
- coord = copy.copy(coord)
- for i in range(3):
- if not axmask[i]:
- continue
- if coord[i] < centers[i]:
- coord[i] -= deltas[i]
- else:
- coord[i] += deltas[i]
- return coord
-
-def tick_update_position(tick, tickxs, tickys, labelpos):
- '''Update tick line and label position and style.'''
-
- for (label, on) in [(tick.label1, tick.label1On),
- (tick.label2, tick.label2On)]:
- if on:
- label.set_position(labelpos)
-
- tick.tick1On, tick.tick2On = True, False
- tick.tick1line.set_linestyle('-')
- tick.tick1line.set_marker('')
- tick.tick1line.set_data(tickxs, tickys)
- tick.gridline.set_data(0, 0)
-
-class Axis(maxis.XAxis):
-
- # These points from the unit cube make up the x, y and z-planes
- _PLANES = (
- (0, 3, 7, 4), (1, 2, 6, 5), # yz planes
- (0, 1, 5, 4), (3, 2, 6, 7), # xz planes
- (0, 1, 2, 3), (4, 5, 6, 7), # xy planes
- )
-
- # Some properties for the axes
- _AXINFO = {
- 'x': {'i': 0, 'tickdir': 1, 'juggled': (1, 0, 2),
- 'color': (0.95, 0.95, 0.95, 0.5)},
- 'y': {'i': 1, 'tickdir': 0, 'juggled': (0, 1, 2),
- 'color': (0.90, 0.90, 0.90, 0.5)},
- 'z': {'i': 2, 'tickdir': 0, 'juggled': (0, 2, 1),
- 'color': (0.925, 0.925, 0.925, 0.5)},
- }
-
- def __init__(self, adir, v_intervalx, d_intervalx, axes, *args, **kwargs):
- # adir identifies which axes this is
- self.adir = adir
- # data and viewing intervals for this direction
- self.d_interval = d_intervalx
- self.v_interval = v_intervalx
-
- # This is a temporary member variable.
- # Do not depend on this existing in future releases!
- self._axinfo = self._AXINFO[adir].copy()
- if rcParams['_internal.classic_mode']:
- self._axinfo.update(
- {'label': {'va': 'center',
- 'ha': 'center'},
- 'tick': {'inward_factor': 0.2,
- 'outward_factor': 0.1,
- 'linewidth': rcParams['lines.linewidth'],
- 'color': 'k'},
- 'axisline': {'linewidth': 0.75,
- 'color': (0, 0, 0, 1)},
- 'grid': {'color': (0.9, 0.9, 0.9, 1),
- 'linewidth': 1.0,
- 'linestyle': '-'},
- })
- else:
- self._axinfo.update(
- {'label': {'va': 'center',
- 'ha': 'center'},
- 'tick': {'inward_factor': 0.2,
- 'outward_factor': 0.1,
- 'linewidth': rcParams.get(
- adir + 'tick.major.width',
- rcParams['xtick.major.width']),
- 'color': rcParams.get(
- adir + 'tick.color',
- rcParams['xtick.color'])},
- 'axisline': {'linewidth': rcParams['axes.linewidth'],
- 'color': rcParams['axes.edgecolor']},
- 'grid': {'color': rcParams['grid.color'],
- 'linewidth': rcParams['grid.linewidth'],
- 'linestyle': rcParams['grid.linestyle']},
- })
-
- maxis.XAxis.__init__(self, axes, *args, **kwargs)
- self.set_rotate_label(kwargs.get('rotate_label', None))
-
- def init3d(self):
- self.line = mlines.Line2D(
- xdata=(0, 0), ydata=(0, 0),
- linewidth=self._axinfo['axisline']['linewidth'],
- color=self._axinfo['axisline']['color'],
- antialiased=True)
-
- # Store dummy data in Polygon object
- self.pane = mpatches.Polygon(
- np.array([[0, 0], [0, 1], [1, 0], [0, 0]]),
- closed=False, alpha=0.8, facecolor='k', edgecolor='k')
- self.set_pane_color(self._axinfo['color'])
-
- self.axes._set_artist_props(self.line)
- self.axes._set_artist_props(self.pane)
- self.gridlines = art3d.Line3DCollection([])
- self.axes._set_artist_props(self.gridlines)
- self.axes._set_artist_props(self.label)
- self.axes._set_artist_props(self.offsetText)
- # Need to be able to place the label at the correct location
- self.label._transform = self.axes.transData
- self.offsetText._transform = self.axes.transData
-
- def get_tick_positions(self):
- majorLocs = self.major.locator()
- self.major.formatter.set_locs(majorLocs)
- majorLabels = [self.major.formatter(val, i)
- for i, val in enumerate(majorLocs)]
- return majorLabels, majorLocs
-
- def get_major_ticks(self, numticks=None):
- ticks = maxis.XAxis.get_major_ticks(self, numticks)
- for t in ticks:
- t.tick1line.set_transform(self.axes.transData)
- t.tick2line.set_transform(self.axes.transData)
- t.gridline.set_transform(self.axes.transData)
- t.label1.set_transform(self.axes.transData)
- t.label2.set_transform(self.axes.transData)
- return ticks
-
- def set_pane_pos(self, xys):
- xys = np.asarray(xys)
- xys = xys[:,:2]
- self.pane.xy = xys
- self.stale = True
-
- def set_pane_color(self, color):
- '''Set pane color to a RGBA tuple.'''
- self._axinfo['color'] = color
- self.pane.set_edgecolor(color)
- self.pane.set_facecolor(color)
- self.pane.set_alpha(color[-1])
- self.stale = True
-
- def set_rotate_label(self, val):
- '''
- Whether to rotate the axis label: True, False or None.
- If set to None the label will be rotated if longer than 4 chars.
- '''
- self._rotate_label = val
- self.stale = True
-
- def get_rotate_label(self, text):
- if self._rotate_label is not None:
- return self._rotate_label
- else:
- return len(text) > 4
-
- def _get_coord_info(self, renderer):
- minx, maxx, miny, maxy, minz, maxz = self.axes.get_w_lims()
- if minx > maxx:
- minx, maxx = maxx, minx
- if miny > maxy:
- miny, maxy = maxy, miny
- if minz > maxz:
- minz, maxz = maxz, minz
- mins = np.array((minx, miny, minz))
- maxs = np.array((maxx, maxy, maxz))
- centers = (maxs + mins) / 2.
- deltas = (maxs - mins) / 12.
- mins = mins - deltas / 4.
- maxs = maxs + deltas / 4.
-
- vals = mins[0], maxs[0], mins[1], maxs[1], mins[2], maxs[2]
- tc = self.axes.tunit_cube(vals, renderer.M)
- avgz = [tc[p1][2] + tc[p2][2] + tc[p3][2] + tc[p4][2]
- for p1, p2, p3, p4 in self._PLANES]
- highs = np.array([avgz[2*i] < avgz[2*i+1] for i in range(3)])
-
- return mins, maxs, centers, deltas, tc, highs
-
- def draw_pane(self, renderer):
- renderer.open_group('pane3d')
-
- mins, maxs, centers, deltas, tc, highs = self._get_coord_info(renderer)
-
- info = self._axinfo
- index = info['i']
- if not highs[index]:
- plane = self._PLANES[2 * index]
- else:
- plane = self._PLANES[2 * index + 1]
- xys = [tc[p] for p in plane]
- self.set_pane_pos(xys)
- self.pane.draw(renderer)
-
- renderer.close_group('pane3d')
-
- def draw(self, renderer):
- self.label._transform = self.axes.transData
- renderer.open_group('axis3d')
-
- # code from XAxis
- majorTicks = self.get_major_ticks()
- majorLocs = self.major.locator()
-
- info = self._axinfo
- index = info['i']
-
- # filter locations here so that no extra grid lines are drawn
- locmin, locmax = self.get_view_interval()
- if locmin > locmax:
- locmin, locmax = locmax, locmin
-
- # Rudimentary clipping
- majorLocs = [loc for loc in majorLocs if
- locmin <= loc <= locmax]
- self.major.formatter.set_locs(majorLocs)
- majorLabels = [self.major.formatter(val, i)
- for i, val in enumerate(majorLocs)]
-
- mins, maxs, centers, deltas, tc, highs = self._get_coord_info(renderer)
-
- # Determine grid lines
- minmax = np.where(highs, maxs, mins)
-
- # Draw main axis line
- juggled = info['juggled']
- edgep1 = minmax.copy()
- edgep1[juggled[0]] = get_flip_min_max(edgep1, juggled[0], mins, maxs)
-
- edgep2 = edgep1.copy()
- edgep2[juggled[1]] = get_flip_min_max(edgep2, juggled[1], mins, maxs)
- pep = proj3d.proj_trans_points([edgep1, edgep2], renderer.M)
- centpt = proj3d.proj_transform(
- centers[0], centers[1], centers[2], renderer.M)
- self.line.set_data((pep[0][0], pep[0][1]), (pep[1][0], pep[1][1]))
- self.line.draw(renderer)
-
- # Grid points where the planes meet
- xyz0 = []
- for val in majorLocs:
- coord = minmax.copy()
- coord[index] = val
- xyz0.append(coord)
-
- # Draw labels
- peparray = np.asanyarray(pep)
- # The transAxes transform is used because the Text object
- # rotates the text relative to the display coordinate system.
- # Therefore, if we want the labels to remain parallel to the
- # axis regardless of the aspect ratio, we need to convert the
- # edge points of the plane to display coordinates and calculate
- # an angle from that.
- # TODO: Maybe Text objects should handle this themselves?
- dx, dy = (self.axes.transAxes.transform([peparray[0:2, 1]]) -
- self.axes.transAxes.transform([peparray[0:2, 0]]))[0]
-
- lxyz = 0.5*(edgep1 + edgep2)
-
- # A rough estimate; points are ambiguous since 3D plots rotate
- ax_scale = self.axes.bbox.size / self.figure.bbox.size
- ax_inches = np.multiply(ax_scale, self.figure.get_size_inches())
- ax_points_estimate = sum(72. * ax_inches)
- deltas_per_point = 48. / ax_points_estimate
- default_offset = 21.
- labeldeltas = (
- (self.labelpad + default_offset) * deltas_per_point * deltas)
- axmask = [True, True, True]
- axmask[index] = False
- lxyz = move_from_center(lxyz, centers, labeldeltas, axmask)
- tlx, tly, tlz = proj3d.proj_transform(lxyz[0], lxyz[1], lxyz[2],
- renderer.M)
- self.label.set_position((tlx, tly))
- if self.get_rotate_label(self.label.get_text()):
- angle = art3d.norm_text_angle(math.degrees(math.atan2(dy, dx)))
- self.label.set_rotation(angle)
- self.label.set_va(info['label']['va'])
- self.label.set_ha(info['label']['ha'])
- self.label.draw(renderer)
-
-
- # Draw Offset text
-
- # Which of the two edge points do we want to
- # use for locating the offset text?
- if juggled[2] == 2 :
- outeredgep = edgep1
- outerindex = 0
- else :
- outeredgep = edgep2
- outerindex = 1
-
- pos = copy.copy(outeredgep)
- pos = move_from_center(pos, centers, labeldeltas, axmask)
- olx, oly, olz = proj3d.proj_transform(
- pos[0], pos[1], pos[2], renderer.M)
- self.offsetText.set_text( self.major.formatter.get_offset() )
- self.offsetText.set_position( (olx, oly) )
- angle = art3d.norm_text_angle(math.degrees(math.atan2(dy, dx)))
- self.offsetText.set_rotation(angle)
- # Must set rotation mode to "anchor" so that
- # the alignment point is used as the "fulcrum" for rotation.
- self.offsetText.set_rotation_mode('anchor')
-
- #----------------------------------------------------------------------
- # Note: the following statement for determining the proper alignment of
- # the offset text. This was determined entirely by trial-and-error
- # and should not be in any way considered as "the way". There are
- # still some edge cases where alignment is not quite right, but this
- # seems to be more of a geometry issue (in other words, I might be
- # using the wrong reference points).
- #
- # (TT, FF, TF, FT) are the shorthand for the tuple of
- # (centpt[info['tickdir']] <= peparray[info['tickdir'], outerindex],
- # centpt[index] <= peparray[index, outerindex])
- #
- # Three-letters (e.g., TFT, FTT) are short-hand for the array of bools
- # from the variable 'highs'.
- # ---------------------------------------------------------------------
- if centpt[info['tickdir']] > peparray[info['tickdir'], outerindex] :
- # if FT and if highs has an even number of Trues
- if (centpt[index] <= peparray[index, outerindex]
- and ((len(highs.nonzero()[0]) % 2) == 0)) :
- # Usually, this means align right, except for the FTT case,
- # in which offset for axis 1 and 2 are aligned left.
- if highs.tolist() == [False, True, True] and index in (1, 2) :
- align = 'left'
- else :
- align = 'right'
- else :
- # The FF case
- align = 'left'
- else :
- # if TF and if highs has an even number of Trues
- if (centpt[index] > peparray[index, outerindex]
- and ((len(highs.nonzero()[0]) % 2) == 0)) :
- # Usually mean align left, except if it is axis 2
- if index == 2 :
- align = 'right'
- else :
- align = 'left'
- else :
- # The TT case
- align = 'right'
-
- self.offsetText.set_va('center')
- self.offsetText.set_ha(align)
- self.offsetText.draw(renderer)
-
- # Draw grid lines
- if len(xyz0) > 0:
- # Grid points at end of one plane
- xyz1 = copy.deepcopy(xyz0)
- newindex = (index + 1) % 3
- newval = get_flip_min_max(xyz1[0], newindex, mins, maxs)
- for i in range(len(majorLocs)):
- xyz1[i][newindex] = newval
-
- # Grid points at end of the other plane
- xyz2 = copy.deepcopy(xyz0)
- newindex = (index + 2) % 3
- newval = get_flip_min_max(xyz2[0], newindex, mins, maxs)
- for i in range(len(majorLocs)):
- xyz2[i][newindex] = newval
-
- lines = list(zip(xyz1, xyz0, xyz2))
- if self.axes._draw_grid:
- self.gridlines.set_segments(lines)
- self.gridlines.set_color([info['grid']['color']] * len(lines))
- self.gridlines.set_linewidth(
- [info['grid']['linewidth']] * len(lines))
- self.gridlines.set_linestyle(
- [info['grid']['linestyle']] * len(lines))
- self.gridlines.draw(renderer, project=True)
-
- # Draw ticks
- tickdir = info['tickdir']
- tickdelta = deltas[tickdir]
- if highs[tickdir]:
- ticksign = 1
- else:
- ticksign = -1
-
- for tick, loc, label in zip(majorTicks, majorLocs, majorLabels):
- if tick is None:
- continue
-
- # Get tick line positions
- pos = copy.copy(edgep1)
- pos[index] = loc
- pos[tickdir] = (
- edgep1[tickdir]
- + info['tick']['outward_factor'] * ticksign * tickdelta)
- x1, y1, z1 = proj3d.proj_transform(pos[0], pos[1], pos[2],
- renderer.M)
- pos[tickdir] = (
- edgep1[tickdir]
- - info['tick']['inward_factor'] * ticksign * tickdelta)
- x2, y2, z2 = proj3d.proj_transform(pos[0], pos[1], pos[2],
- renderer.M)
-
- # Get position of label
- default_offset = 8. # A rough estimate
- labeldeltas = (
- (tick.get_pad() + default_offset) * deltas_per_point * deltas)
-
- axmask = [True, True, True]
- axmask[index] = False
- pos[tickdir] = edgep1[tickdir]
- pos = move_from_center(pos, centers, labeldeltas, axmask)
- lx, ly, lz = proj3d.proj_transform(pos[0], pos[1], pos[2],
- renderer.M)
-
- tick_update_position(tick, (x1, x2), (y1, y2), (lx, ly))
- tick.tick1line.set_linewidth(info['tick']['linewidth'])
- tick.tick1line.set_color(info['tick']['color'])
- tick.set_label1(label)
- tick.set_label2(label)
- tick.draw(renderer)
-
- renderer.close_group('axis3d')
- self.stale = False
-
- def get_view_interval(self):
- """return the Interval instance for this 3d axis view limits"""
- return self.v_interval
-
- def set_view_interval(self, vmin, vmax, ignore=False):
- if ignore:
- self.v_interval = vmin, vmax
- else:
- Vmin, Vmax = self.get_view_interval()
- self.v_interval = min(vmin, Vmin), max(vmax, Vmax)
-
- # TODO: Get this to work properly when mplot3d supports
- # the transforms framework.
- def get_tightbbox(self, renderer) :
- # Currently returns None so that Axis.get_tightbbox
- # doesn't return junk info.
- return None
-
-# Use classes to look at different data limits
-
-class XAxis(Axis):
- def get_data_interval(self):
- 'return the Interval instance for this axis data limits'
- return self.axes.xy_dataLim.intervalx
-
-class YAxis(Axis):
- def get_data_interval(self):
- 'return the Interval instance for this axis data limits'
- return self.axes.xy_dataLim.intervaly
-
-class ZAxis(Axis):
- def get_data_interval(self):
- 'return the Interval instance for this axis data limits'
- return self.axes.zz_dataLim.intervalx
diff --git a/contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/proj3d.py b/contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/proj3d.py
deleted file mode 100644
index a084e7f36a..0000000000
--- a/contrib/python/matplotlib/py2/mpl_toolkits/mplot3d/proj3d.py
+++ /dev/null
@@ -1,203 +0,0 @@
-# 3dproj.py
-#
-"""
-Various transforms used for by the 3D code
-"""
-from __future__ import (absolute_import, division, print_function,
- unicode_literals)
-
-import six
-from six.moves import zip
-
-import numpy as np
-import numpy.linalg as linalg
-
-
-
-def line2d(p0, p1):
- """
- Return 2D equation of line in the form ax+by+c = 0
- """
- # x + x1 = 0
- x0, y0 = p0[:2]
- x1, y1 = p1[:2]
- #
- if x0 == x1:
- a = -1
- b = 0
- c = x1
- elif y0 == y1:
- a = 0
- b = 1
- c = -y1
- else:
- a = (y0-y1)
- b = (x0-x1)
- c = (x0*y1 - x1*y0)
- return a, b, c
-
-def line2d_dist(l, p):
- """
- Distance from line to point
- line is a tuple of coefficients a,b,c
- """
- a, b, c = l
- x0, y0 = p
- return abs((a*x0 + b*y0 + c)/np.sqrt(a**2+b**2))
-
-
-def line2d_seg_dist(p1, p2, p0):
- """distance(s) from line defined by p1 - p2 to point(s) p0
-
- p0[0] = x(s)
- p0[1] = y(s)
-
- intersection point p = p1 + u*(p2-p1)
- and intersection point lies within segment if u is between 0 and 1
- """
-
- x21 = p2[0] - p1[0]
- y21 = p2[1] - p1[1]
- x01 = np.asarray(p0[0]) - p1[0]
- y01 = np.asarray(p0[1]) - p1[1]
-
- u = (x01*x21 + y01*y21) / (x21**2 + y21**2)
- u = np.clip(u, 0, 1)
- d = np.sqrt((x01 - u*x21)**2 + (y01 - u*y21)**2)
-
- return d
-
-
-def mod(v):
- """3d vector length"""
- return np.sqrt(v[0]**2+v[1]**2+v[2]**2)
-
-def world_transformation(xmin, xmax,
- ymin, ymax,
- zmin, zmax):
- dx, dy, dz = (xmax-xmin), (ymax-ymin), (zmax-zmin)
- return np.array([
- [1.0/dx,0,0,-xmin/dx],
- [0,1.0/dy,0,-ymin/dy],
- [0,0,1.0/dz,-zmin/dz],
- [0,0,0,1.0]])
-
-
-def view_transformation(E, R, V):
- n = (E - R)
- ## new
-# n /= mod(n)
-# u = np.cross(V,n)
-# u /= mod(u)
-# v = np.cross(n,u)
-# Mr = np.diag([1.]*4)
-# Mt = np.diag([1.]*4)
-# Mr[:3,:3] = u,v,n
-# Mt[:3,-1] = -E
- ## end new
-
- ## old
- n = n / mod(n)
- u = np.cross(V, n)
- u = u / mod(u)
- v = np.cross(n, u)
- Mr = [[u[0],u[1],u[2],0],
- [v[0],v[1],v[2],0],
- [n[0],n[1],n[2],0],
- [0, 0, 0, 1],
- ]
- #
- Mt = [[1, 0, 0, -E[0]],
- [0, 1, 0, -E[1]],
- [0, 0, 1, -E[2]],
- [0, 0, 0, 1]]
- ## end old
-
- return np.dot(Mr, Mt)
-
-def persp_transformation(zfront, zback):
- a = (zfront+zback)/(zfront-zback)
- b = -2*(zfront*zback)/(zfront-zback)
- return np.array([[1,0,0,0],
- [0,1,0,0],
- [0,0,a,b],
- [0,0,-1,0]
- ])
-
-def ortho_transformation(zfront, zback):
- # note: w component in the resulting vector will be (zback-zfront), not 1
- a = -(zfront + zback)
- b = -(zfront - zback)
- return np.array([[2,0,0,0],
- [0,2,0,0],
- [0,0,-2,0],
- [0,0,a,b]
- ])
-
-def proj_transform_vec(vec, M):
- vecw = np.dot(M, vec)
- w = vecw[3]
- # clip here..
- txs, tys, tzs = vecw[0]/w, vecw[1]/w, vecw[2]/w
- return txs, tys, tzs
-
-def proj_transform_vec_clip(vec, M):
- vecw = np.dot(M, vec)
- w = vecw[3]
- # clip here.
- txs, tys, tzs = vecw[0] / w, vecw[1] / w, vecw[2] / w
- tis = (0 <= vecw[0]) & (vecw[0] <= 1) & (0 <= vecw[1]) & (vecw[1] <= 1)
- if np.any(tis):
- tis = vecw[1] < 1
- return txs, tys, tzs, tis
-
-def inv_transform(xs, ys, zs, M):
- iM = linalg.inv(M)
- vec = vec_pad_ones(xs, ys, zs)
- vecr = np.dot(iM, vec)
- try:
- vecr = vecr/vecr[3]
- except OverflowError:
- pass
- return vecr[0], vecr[1], vecr[2]
-
-def vec_pad_ones(xs, ys, zs):
- return np.array([xs, ys, zs, np.ones_like(xs)])
-
-def proj_transform(xs, ys, zs, M):
- """
- Transform the points by the projection matrix
- """
- vec = vec_pad_ones(xs, ys, zs)
- return proj_transform_vec(vec, M)
-
-def proj_transform_clip(xs, ys, zs, M):
- """
- Transform the points by the projection matrix
- and return the clipping result
- returns txs,tys,tzs,tis
- """
- vec = vec_pad_ones(xs, ys, zs)
- return proj_transform_vec_clip(vec, M)
-transform = proj_transform
-
-def proj_points(points, M):
- return np.column_stack(proj_trans_points(points, M))
-
-def proj_trans_points(points, M):
- xs, ys, zs = zip(*points)
- return proj_transform(xs, ys, zs, M)
-
-def proj_trans_clip_points(points, M):
- xs, ys, zs = zip(*points)
- return proj_transform_clip(xs, ys, zs, M)
-
-
-def rot_x(V, alpha):
- cosa, sina = np.cos(alpha), np.sin(alpha)
- M1 = np.array([[1,0,0,0],
- [0,cosa,-sina,0],
- [0,sina,cosa,0],
- [0,0,0,1]])
-
- return np.dot(M1, V)
diff --git a/contrib/python/matplotlib/py2/pylab.py b/contrib/python/matplotlib/py2/pylab.py
deleted file mode 100644
index f9d135d36e..0000000000
--- a/contrib/python/matplotlib/py2/pylab.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from matplotlib.pylab import *
-import matplotlib.pylab
-__doc__ = matplotlib.pylab.__doc__
diff --git a/contrib/python/matplotlib/py2/src/_backend_agg.cpp b/contrib/python/matplotlib/py2/src/_backend_agg.cpp
deleted file mode 100644
index 3dc35f6782..0000000000
--- a/contrib/python/matplotlib/py2/src/_backend_agg.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#define NO_IMPORT_ARRAY
-
-#include "_backend_agg.h"
-#include "mplutils.h"
-
-void BufferRegion::to_string_argb(uint8_t *buf)
-{
- unsigned char *pix;
- unsigned char tmp;
- size_t i, j;
-
- memcpy(buf, data, height * stride);
-
- for (i = 0; i < (size_t)height; ++i) {
- pix = buf + i * stride;
- for (j = 0; j < (size_t)width; ++j) {
- // Convert rgba to argb
- tmp = pix[2];
- pix[2] = pix[0];
- pix[0] = tmp;
- pix += 4;
- }
- }
-}
-
-RendererAgg::RendererAgg(unsigned int width, unsigned int height, double dpi)
- : width(width),
- height(height),
- dpi(dpi),
- NUMBYTES(width * height * 4),
- pixBuffer(NULL),
- renderingBuffer(),
- alphaBuffer(NULL),
- alphaMaskRenderingBuffer(),
- alphaMask(alphaMaskRenderingBuffer),
- pixfmtAlphaMask(alphaMaskRenderingBuffer),
- rendererBaseAlphaMask(),
- rendererAlphaMask(),
- scanlineAlphaMask(),
- slineP8(),
- slineBin(),
- pixFmt(),
- rendererBase(),
- rendererAA(),
- rendererBin(),
- theRasterizer(8192),
- lastclippath(NULL),
- _fill_color(agg::rgba(1, 1, 1, 0))
-{
- unsigned stride(width * 4);
-
- pixBuffer = new agg::int8u[NUMBYTES];
- renderingBuffer.attach(pixBuffer, width, height, stride);
- pixFmt.attach(renderingBuffer);
- rendererBase.attach(pixFmt);
- rendererBase.clear(_fill_color);
- rendererAA.attach(rendererBase);
- rendererBin.attach(rendererBase);
- hatch_size = int(dpi);
- hatchBuffer = new agg::int8u[hatch_size * hatch_size * 4];
- hatchRenderingBuffer.attach(hatchBuffer, hatch_size, hatch_size, hatch_size * 4);
-}
-
-RendererAgg::~RendererAgg()
-{
- delete[] hatchBuffer;
- delete[] alphaBuffer;
- delete[] pixBuffer;
-}
-
-void RendererAgg::create_alpha_buffers()
-{
- if (!alphaBuffer) {
- alphaBuffer = new agg::int8u[width * height];
- alphaMaskRenderingBuffer.attach(alphaBuffer, width, height, width);
- rendererBaseAlphaMask.attach(pixfmtAlphaMask);
- rendererAlphaMask.attach(rendererBaseAlphaMask);
- }
-}
-
-BufferRegion *RendererAgg::copy_from_bbox(agg::rect_d in_rect)
-{
- agg::rect_i rect(
- (int)in_rect.x1, height - (int)in_rect.y2, (int)in_rect.x2, height - (int)in_rect.y1);
-
- BufferRegion *reg = NULL;
- reg = new BufferRegion(rect);
-
- agg::rendering_buffer rbuf;
- rbuf.attach(reg->get_data(), reg->get_width(), reg->get_height(), reg->get_stride());
-
- pixfmt pf(rbuf);
- renderer_base rb(pf);
- rb.copy_from(renderingBuffer, &rect, -rect.x1, -rect.y1);
-
- return reg;
-}
-
-void RendererAgg::restore_region(BufferRegion &region)
-{
- if (region.get_data() == NULL) {
- throw std::runtime_error("Cannot restore_region from NULL data");
- }
-
- agg::rendering_buffer rbuf;
- rbuf.attach(region.get_data(), region.get_width(), region.get_height(), region.get_stride());
-
- rendererBase.copy_from(rbuf, 0, region.get_rect().x1, region.get_rect().y1);
-}
-
-// Restore the part of the saved region with offsets
-void
-RendererAgg::restore_region(BufferRegion &region, int xx1, int yy1, int xx2, int yy2, int x, int y )
-{
- if (region.get_data() == NULL) {
- throw std::runtime_error("Cannot restore_region from NULL data");
- }
-
- agg::rect_i &rrect = region.get_rect();
-
- agg::rect_i rect(xx1 - rrect.x1, (yy1 - rrect.y1), xx2 - rrect.x1, (yy2 - rrect.y1));
-
- agg::rendering_buffer rbuf;
- rbuf.attach(region.get_data(), region.get_width(), region.get_height(), region.get_stride());
-
- rendererBase.copy_from(rbuf, &rect, x, y);
-}
-
-bool RendererAgg::render_clippath(py::PathIterator &clippath,
- const agg::trans_affine &clippath_trans)
-{
- typedef agg::conv_transform<py::PathIterator> transformed_path_t;
- typedef agg::conv_curve<transformed_path_t> curve_t;
-
- bool has_clippath = (clippath.total_vertices() != 0);
-
- if (has_clippath &&
- (clippath.get_id() != lastclippath || clippath_trans != lastclippath_transform)) {
- create_alpha_buffers();
- agg::trans_affine trans(clippath_trans);
- trans *= agg::trans_affine_scaling(1.0, -1.0);
- trans *= agg::trans_affine_translation(0.0, (double)height);
-
- rendererBaseAlphaMask.clear(agg::gray8(0, 0));
- transformed_path_t transformed_clippath(clippath, trans);
- curve_t curved_clippath(transformed_clippath);
- theRasterizer.add_path(curved_clippath);
- rendererAlphaMask.color(agg::gray8(255, 255));
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, rendererAlphaMask);
- lastclippath = clippath.get_id();
- lastclippath_transform = clippath_trans;
- }
-
- return has_clippath;
-}
-
-void RendererAgg::tostring_rgb(uint8_t *buf)
-{
- // "Return the rendered buffer as an RGB string"
-
- int row_len = width * 3;
-
- agg::rendering_buffer renderingBufferTmp;
- renderingBufferTmp.attach(buf, width, height, row_len);
-
- agg::color_conv(&renderingBufferTmp, &renderingBuffer, agg::color_conv_rgba32_to_rgb24());
-}
-
-void RendererAgg::tostring_argb(uint8_t *buf)
-{
- //"Return the rendered buffer as an RGB string";
-
- int row_len = width * 4;
-
- agg::rendering_buffer renderingBufferTmp;
- renderingBufferTmp.attach(buf, width, height, row_len);
- agg::color_conv(&renderingBufferTmp, &renderingBuffer, agg::color_conv_rgba32_to_argb32());
-}
-
-void RendererAgg::tostring_bgra(uint8_t *buf)
-{
- //"Return the rendered buffer as an RGB string";
-
- int row_len = width * 4;
-
- agg::rendering_buffer renderingBufferTmp;
- renderingBufferTmp.attach(buf, width, height, row_len);
-
- agg::color_conv(&renderingBufferTmp, &renderingBuffer, agg::color_conv_rgba32_to_bgra32());
-}
-
-agg::rect_i RendererAgg::get_content_extents()
-{
- agg::rect_i r(width, height, 0, 0);
-
- // Looks at the alpha channel to find the minimum extents of the image
- unsigned char *pixel = pixBuffer + 3;
- for (int y = 0; y < (int)height; ++y) {
- for (int x = 0; x < (int)width; ++x) {
- if (*pixel) {
- if (x < r.x1)
- r.x1 = x;
- if (y < r.y1)
- r.y1 = y;
- if (x > r.x2)
- r.x2 = x;
- if (y > r.y2)
- r.y2 = y;
- }
- pixel += 4;
- }
- }
-
- if (r.x1 == width && r.x2 == 0) {
- // The buffer is completely empty.
- r.x1 = r.y1 = r.x2 = r.y2 = 0;
- } else {
- r.x1 = std::max(0, r.x1);
- r.y1 = std::max(0, r.y1);
- r.x2 = std::min(r.x2 + 1, (int)width);
- r.y2 = std::min(r.y2 + 1, (int)height);
- }
-
- return r;
-}
-
-void RendererAgg::clear()
-{
- //"clear the rendered buffer";
-
- rendererBase.clear(_fill_color);
-}
diff --git a/contrib/python/matplotlib/py2/src/_backend_agg.h b/contrib/python/matplotlib/py2/src/_backend_agg.h
deleted file mode 100644
index 53b73f179b..0000000000
--- a/contrib/python/matplotlib/py2/src/_backend_agg.h
+++ /dev/null
@@ -1,1294 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/* _backend_agg.h
-*/
-
-#ifndef __BACKEND_AGG_H__
-#define __BACKEND_AGG_H__
-
-#include <cmath>
-#include <vector>
-#include <algorithm>
-
-#include "agg_alpha_mask_u8.h"
-#include "agg_conv_curve.h"
-#include "agg_conv_dash.h"
-#include "agg_conv_stroke.h"
-#include "agg_image_accessors.h"
-#include "agg_pixfmt_amask_adaptor.h"
-#include "agg_pixfmt_gray.h"
-#include "agg_pixfmt_rgba.h"
-#include "agg_rasterizer_scanline_aa.h"
-#include "agg_renderer_base.h"
-#include "agg_renderer_scanline.h"
-#include "agg_rendering_buffer.h"
-#include "agg_scanline_bin.h"
-#include "agg_scanline_p.h"
-#include "agg_scanline_storage_aa.h"
-#include "agg_scanline_storage_bin.h"
-#include "agg_scanline_u.h"
-#include "agg_span_allocator.h"
-#include "agg_span_converter.h"
-#include "agg_span_gouraud_rgba.h"
-#include "agg_span_image_filter_gray.h"
-#include "agg_span_image_filter_rgba.h"
-#include "agg_span_interpolator_linear.h"
-#include "agg_span_pattern_rgba.h"
-#include "util/agg_color_conv_rgb8.h"
-
-#include "_backend_agg_basic_types.h"
-#include "path_converters.h"
-#include "array.h"
-#include "agg_workaround.h"
-
-/**********************************************************************/
-
-// a helper class to pass agg::buffer objects around. agg::buffer is
-// a class in the swig wrapper
-class BufferRegion
-{
- public:
- BufferRegion(const agg::rect_i &r) : rect(r)
- {
- width = r.x2 - r.x1;
- height = r.y2 - r.y1;
- stride = width * 4;
- data = new agg::int8u[stride * height];
- }
-
- virtual ~BufferRegion()
- {
- delete[] data;
- };
-
- agg::int8u *get_data()
- {
- return data;
- }
-
- agg::rect_i &get_rect()
- {
- return rect;
- }
-
- int get_width()
- {
- return width;
- }
-
- int get_height()
- {
- return height;
- }
-
- int get_stride()
- {
- return stride;
- }
-
- void to_string_argb(uint8_t *buf);
-
- private:
- agg::int8u *data;
- agg::rect_i rect;
- int width;
- int height;
- int stride;
-
- private:
- // prevent copying
- BufferRegion(const BufferRegion &);
- BufferRegion &operator=(const BufferRegion &);
-};
-
-#define MARKER_CACHE_SIZE 512
-
-// the renderer
-class RendererAgg
-{
- public:
-
- typedef fixed_blender_rgba_plain<agg::rgba8, agg::order_rgba> fixed_blender_rgba32_plain;
- typedef agg::pixfmt_alpha_blend_rgba<fixed_blender_rgba32_plain, agg::rendering_buffer> pixfmt;
- typedef agg::renderer_base<pixfmt> renderer_base;
- typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_aa;
- typedef agg::renderer_scanline_bin_solid<renderer_base> renderer_bin;
- typedef agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> rasterizer;
-
- typedef agg::scanline_p8 scanline_p8;
- typedef agg::scanline_bin scanline_bin;
- typedef agg::amask_no_clip_gray8 alpha_mask_type;
- typedef agg::scanline_u8_am<alpha_mask_type> scanline_am;
-
- typedef agg::renderer_base<agg::pixfmt_gray8> renderer_base_alpha_mask_type;
- typedef agg::renderer_scanline_aa_solid<renderer_base_alpha_mask_type> renderer_alpha_mask_type;
-
- /* TODO: Remove facepair_t */
- typedef std::pair<bool, agg::rgba> facepair_t;
-
- RendererAgg(unsigned int width, unsigned int height, double dpi);
-
- virtual ~RendererAgg();
-
- unsigned int get_width()
- {
- return width;
- }
-
- unsigned int get_height()
- {
- return height;
- }
-
- template <class PathIterator>
- void draw_path(GCAgg &gc, PathIterator &path, agg::trans_affine &trans, agg::rgba &color);
-
- template <class PathIterator>
- void draw_markers(GCAgg &gc,
- PathIterator &marker_path,
- agg::trans_affine &marker_path_trans,
- PathIterator &path,
- agg::trans_affine &trans,
- agg::rgba face);
-
- template <class ImageArray>
- void draw_text_image(GCAgg &gc, ImageArray &image, int x, int y, double angle);
-
- template <class ImageArray>
- void draw_image(GCAgg &gc,
- double x,
- double y,
- ImageArray &image);
-
- template <class PathGenerator,
- class TransformArray,
- class OffsetArray,
- class ColorArray,
- class LineWidthArray,
- class AntialiasedArray>
- void draw_path_collection(GCAgg &gc,
- agg::trans_affine &master_transform,
- PathGenerator &path,
- TransformArray &transforms,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- ColorArray &edgecolors,
- LineWidthArray &linewidths,
- DashesVector &linestyles,
- AntialiasedArray &antialiaseds,
- e_offset_position offset_position);
-
- template <class CoordinateArray, class OffsetArray, class ColorArray>
- void draw_quad_mesh(GCAgg &gc,
- agg::trans_affine &master_transform,
- unsigned int mesh_width,
- unsigned int mesh_height,
- CoordinateArray &coordinates,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- bool antialiased,
- ColorArray &edgecolors);
-
- template <class PointArray, class ColorArray>
- void draw_gouraud_triangle(GCAgg &gc,
- PointArray &points,
- ColorArray &colors,
- agg::trans_affine &trans);
-
- template <class PointArray, class ColorArray>
- void draw_gouraud_triangles(GCAgg &gc,
- PointArray &points,
- ColorArray &colors,
- agg::trans_affine &trans);
-
- void tostring_rgb(uint8_t *buf);
- void tostring_argb(uint8_t *buf);
- void tostring_bgra(uint8_t *buf);
- agg::rect_i get_content_extents();
- void clear();
-
- BufferRegion *copy_from_bbox(agg::rect_d in_rect);
- void restore_region(BufferRegion &reg);
- void restore_region(BufferRegion &region, int xx1, int yy1, int xx2, int yy2, int x, int y);
-
- unsigned int width, height;
- double dpi;
- size_t NUMBYTES; // the number of bytes in buffer
-
- agg::int8u *pixBuffer;
- agg::rendering_buffer renderingBuffer;
-
- agg::int8u *alphaBuffer;
- agg::rendering_buffer alphaMaskRenderingBuffer;
- alpha_mask_type alphaMask;
- agg::pixfmt_gray8 pixfmtAlphaMask;
- renderer_base_alpha_mask_type rendererBaseAlphaMask;
- renderer_alpha_mask_type rendererAlphaMask;
- scanline_am scanlineAlphaMask;
-
- scanline_p8 slineP8;
- scanline_bin slineBin;
- pixfmt pixFmt;
- renderer_base rendererBase;
- renderer_aa rendererAA;
- renderer_bin rendererBin;
- rasterizer theRasterizer;
-
- void *lastclippath;
- agg::trans_affine lastclippath_transform;
-
- size_t hatch_size;
- agg::int8u *hatchBuffer;
- agg::rendering_buffer hatchRenderingBuffer;
-
- agg::rgba _fill_color;
-
- protected:
- inline double points_to_pixels(double points)
- {
- return points * dpi / 72.0;
- }
-
- template <class R>
- void set_clipbox(const agg::rect_d &cliprect, R &rasterizer);
-
- bool render_clippath(py::PathIterator &clippath, const agg::trans_affine &clippath_trans);
-
- template <class PathIteratorType>
- void _draw_path(PathIteratorType &path, bool has_clippath, const facepair_t &face, GCAgg &gc);
-
- template <class PathIterator,
- class PathGenerator,
- class TransformArray,
- class OffsetArray,
- class ColorArray,
- class LineWidthArray,
- class AntialiasedArray>
- void _draw_path_collection_generic(GCAgg &gc,
- agg::trans_affine master_transform,
- const agg::rect_d &cliprect,
- PathIterator &clippath,
- const agg::trans_affine &clippath_trans,
- PathGenerator &path_generator,
- TransformArray &transforms,
- OffsetArray &offsets,
- const agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- ColorArray &edgecolors,
- LineWidthArray &linewidths,
- DashesVector &linestyles,
- AntialiasedArray &antialiaseds,
- e_offset_position offset_position,
- int check_snap,
- int has_curves);
-
- template <class PointArray, class ColorArray>
- void _draw_gouraud_triangle(PointArray &points,
- ColorArray &colors,
- agg::trans_affine trans,
- bool has_clippath);
-
- private:
- void create_alpha_buffers();
-
- // prevent copying
- RendererAgg(const RendererAgg &);
- RendererAgg &operator=(const RendererAgg &);
-};
-
-/***************************************************************************
- * Implementation
- */
-
-template <class path_t>
-inline void
-RendererAgg::_draw_path(path_t &path, bool has_clippath, const facepair_t &face, GCAgg &gc)
-{
- typedef agg::conv_stroke<path_t> stroke_t;
- typedef agg::conv_dash<path_t> dash_t;
- typedef agg::conv_stroke<dash_t> stroke_dash_t;
- typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
- typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
- typedef agg::renderer_scanline_aa_solid<amask_ren_type> amask_aa_renderer_type;
- typedef agg::renderer_scanline_bin_solid<amask_ren_type> amask_bin_renderer_type;
-
- // Render face
- if (face.first) {
- theRasterizer.add_path(path);
-
- if (gc.isaa) {
- if (has_clippath) {
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_aa_renderer_type ren(r);
- ren.color(face.second);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ren);
- } else {
- rendererAA.color(face.second);
- agg::render_scanlines(theRasterizer, slineP8, rendererAA);
- }
- } else {
- if (has_clippath) {
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_bin_renderer_type ren(r);
- ren.color(face.second);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ren);
- } else {
- rendererBin.color(face.second);
- agg::render_scanlines(theRasterizer, slineP8, rendererBin);
- }
- }
- }
-
- // Render hatch
- if (gc.has_hatchpath()) {
- // Reset any clipping that may be in effect, since we'll be
- // drawing the hatch in a scratch buffer at origin (0, 0)
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
-
- // Create and transform the path
- typedef agg::conv_transform<py::PathIterator> hatch_path_trans_t;
- typedef agg::conv_curve<hatch_path_trans_t> hatch_path_curve_t;
- typedef agg::conv_stroke<hatch_path_curve_t> hatch_path_stroke_t;
-
- py::PathIterator hatch_path(gc.hatchpath);
- agg::trans_affine hatch_trans;
- hatch_trans *= agg::trans_affine_scaling(1.0, -1.0);
- hatch_trans *= agg::trans_affine_translation(0.0, 1.0);
- hatch_trans *= agg::trans_affine_scaling(hatch_size, hatch_size);
- hatch_path_trans_t hatch_path_trans(hatch_path, hatch_trans);
- hatch_path_curve_t hatch_path_curve(hatch_path_trans);
- hatch_path_stroke_t hatch_path_stroke(hatch_path_curve);
- hatch_path_stroke.width(points_to_pixels(gc.hatch_linewidth));
- hatch_path_stroke.line_cap(agg::square_cap);
-
- // Render the path into the hatch buffer
- pixfmt hatch_img_pixf(hatchRenderingBuffer);
- renderer_base rb(hatch_img_pixf);
- renderer_aa rs(rb);
- rb.clear(_fill_color);
- rs.color(gc.hatch_color);
-
- theRasterizer.add_path(hatch_path_curve);
- agg::render_scanlines(theRasterizer, slineP8, rs);
- theRasterizer.add_path(hatch_path_stroke);
- agg::render_scanlines(theRasterizer, slineP8, rs);
-
- // Put clipping back on, if originally set on entry to this
- // function
- set_clipbox(gc.cliprect, theRasterizer);
- if (has_clippath) {
- render_clippath(gc.clippath.path, gc.clippath.trans);
- }
-
- // Transfer the hatch to the main image buffer
- typedef agg::image_accessor_wrap<pixfmt,
- agg::wrap_mode_repeat_auto_pow2,
- agg::wrap_mode_repeat_auto_pow2> img_source_type;
- typedef agg::span_pattern_rgba<img_source_type> span_gen_type;
- agg::span_allocator<agg::rgba8> sa;
- img_source_type img_src(hatch_img_pixf);
- span_gen_type sg(img_src, 0, 0);
- theRasterizer.add_path(path);
-
- if (has_clippath) {
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type ren(pfa);
- agg::render_scanlines_aa(theRasterizer, slineP8, ren, sa, sg);
- } else {
- agg::render_scanlines_aa(theRasterizer, slineP8, rendererBase, sa, sg);
- }
- }
-
- // Render stroke
- if (gc.linewidth != 0.0) {
- double linewidth = points_to_pixels(gc.linewidth);
- if (!gc.isaa) {
- linewidth = (linewidth < 0.5) ? 0.5 : mpl_round(linewidth);
- }
- if (gc.dashes.size() == 0) {
- stroke_t stroke(path);
- stroke.width(points_to_pixels(gc.linewidth));
- stroke.line_cap(gc.cap);
- stroke.line_join(gc.join);
- stroke.miter_limit(points_to_pixels(gc.linewidth));
- theRasterizer.add_path(stroke);
- } else {
- dash_t dash(path);
- gc.dashes.dash_to_stroke(dash, dpi, gc.isaa);
- stroke_dash_t stroke(dash);
- stroke.line_cap(gc.cap);
- stroke.line_join(gc.join);
- stroke.width(linewidth);
- stroke.miter_limit(points_to_pixels(gc.linewidth));
- theRasterizer.add_path(stroke);
- }
-
- if (gc.isaa) {
- if (has_clippath) {
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_aa_renderer_type ren(r);
- ren.color(gc.color);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ren);
- } else {
- rendererAA.color(gc.color);
- agg::render_scanlines(theRasterizer, slineP8, rendererAA);
- }
- } else {
- if (has_clippath) {
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_bin_renderer_type ren(r);
- ren.color(gc.color);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ren);
- } else {
- rendererBin.color(gc.color);
- agg::render_scanlines(theRasterizer, slineBin, rendererBin);
- }
- }
- }
-}
-
-template <class PathIterator>
-inline void
-RendererAgg::draw_path(GCAgg &gc, PathIterator &path, agg::trans_affine &trans, agg::rgba &color)
-{
- typedef agg::conv_transform<py::PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removed_t;
- typedef PathClipper<nan_removed_t> clipped_t;
- typedef PathSnapper<clipped_t> snapped_t;
- typedef PathSimplifier<snapped_t> simplify_t;
- typedef agg::conv_curve<simplify_t> curve_t;
- typedef Sketch<curve_t> sketch_t;
-
- facepair_t face(color.a != 0.0, color);
-
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(gc.cliprect, theRasterizer);
- bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans);
-
- trans *= agg::trans_affine_scaling(1.0, -1.0);
- trans *= agg::trans_affine_translation(0.0, (double)height);
- bool clip = !face.first && !gc.has_hatchpath() && !path.has_curves();
- bool simplify = path.should_simplify() && clip;
- double snapping_linewidth = points_to_pixels(gc.linewidth);
- if (gc.color.a == 0.0) {
- snapping_linewidth = 0.0;
- }
-
- transformed_path_t tpath(path, trans);
- nan_removed_t nan_removed(tpath, true, path.has_curves());
- clipped_t clipped(nan_removed, clip && !path.has_curves(), width, height);
- snapped_t snapped(clipped, gc.snap_mode, path.total_vertices(), snapping_linewidth);
- simplify_t simplified(snapped, simplify, path.simplify_threshold());
- curve_t curve(simplified);
- sketch_t sketch(curve, gc.sketch.scale, gc.sketch.length, gc.sketch.randomness);
-
- _draw_path(sketch, has_clippath, face, gc);
-}
-
-template <class PathIterator>
-inline void RendererAgg::draw_markers(GCAgg &gc,
- PathIterator &marker_path,
- agg::trans_affine &marker_trans,
- PathIterator &path,
- agg::trans_affine &trans,
- agg::rgba color)
-{
- typedef agg::conv_transform<py::PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removed_t;
- typedef PathSnapper<nan_removed_t> snap_t;
- typedef agg::conv_curve<snap_t> curve_t;
- typedef agg::conv_stroke<curve_t> stroke_t;
- typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
- typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
- typedef agg::renderer_scanline_aa_solid<amask_ren_type> amask_aa_renderer_type;
-
- // Deal with the difference in y-axis direction
- marker_trans *= agg::trans_affine_scaling(1.0, -1.0);
-
- trans *= agg::trans_affine_scaling(1.0, -1.0);
- trans *= agg::trans_affine_translation(0.5, (double)height + 0.5);
-
- transformed_path_t marker_path_transformed(marker_path, marker_trans);
- nan_removed_t marker_path_nan_removed(marker_path_transformed, true, marker_path.has_curves());
- snap_t marker_path_snapped(marker_path_nan_removed,
- gc.snap_mode,
- marker_path.total_vertices(),
- points_to_pixels(gc.linewidth));
- curve_t marker_path_curve(marker_path_snapped);
-
- if (!marker_path_snapped.is_snapping()) {
- // If the path snapper isn't in effect, at least make sure the marker
- // at (0, 0) is in the center of a pixel. This, importantly, makes
- // the circle markers look centered around the point they refer to.
- marker_trans *= agg::trans_affine_translation(0.5, 0.5);
- }
-
- transformed_path_t path_transformed(path, trans);
- nan_removed_t path_nan_removed(path_transformed, false, false);
- snap_t path_snapped(path_nan_removed, SNAP_FALSE, path.total_vertices(), 0.0);
- curve_t path_curve(path_snapped);
- path_curve.rewind(0);
-
- facepair_t face(color.a != 0.0, color);
-
- // maxim's suggestions for cached scanlines
- agg::scanline_storage_aa8 scanlines;
- theRasterizer.reset();
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- agg::rect_i marker_size(0x7FFFFFFF, 0x7FFFFFFF, -0x7FFFFFFF, -0x7FFFFFFF);
-
- agg::int8u staticFillCache[MARKER_CACHE_SIZE];
- agg::int8u staticStrokeCache[MARKER_CACHE_SIZE];
- agg::int8u *fillCache = staticFillCache;
- agg::int8u *strokeCache = staticStrokeCache;
-
- try
- {
- unsigned fillSize = 0;
- if (face.first) {
- theRasterizer.add_path(marker_path_curve);
- agg::render_scanlines(theRasterizer, slineP8, scanlines);
- fillSize = scanlines.byte_size();
- if (fillSize >= MARKER_CACHE_SIZE) {
- fillCache = new agg::int8u[fillSize];
- }
- scanlines.serialize(fillCache);
- marker_size = agg::rect_i(scanlines.min_x(),
- scanlines.min_y(),
- scanlines.max_x(),
- scanlines.max_y());
- }
-
- stroke_t stroke(marker_path_curve);
- stroke.width(points_to_pixels(gc.linewidth));
- stroke.line_cap(gc.cap);
- stroke.line_join(gc.join);
- stroke.miter_limit(points_to_pixels(gc.linewidth));
- theRasterizer.reset();
- theRasterizer.add_path(stroke);
- agg::render_scanlines(theRasterizer, slineP8, scanlines);
- unsigned strokeSize = scanlines.byte_size();
- if (strokeSize >= MARKER_CACHE_SIZE) {
- strokeCache = new agg::int8u[strokeSize];
- }
- scanlines.serialize(strokeCache);
- marker_size = agg::rect_i(std::min(marker_size.x1, scanlines.min_x()),
- std::min(marker_size.y1, scanlines.min_y()),
- std::max(marker_size.x2, scanlines.max_x()),
- std::max(marker_size.y2, scanlines.max_y()));
-
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(gc.cliprect, rendererBase);
- bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans);
-
- double x, y;
-
- agg::serialized_scanlines_adaptor_aa8 sa;
- agg::serialized_scanlines_adaptor_aa8::embedded_scanline sl;
-
- agg::rect_d clipping_rect(-1.0 - marker_size.x2,
- -1.0 - marker_size.y2,
- 1.0 + width - marker_size.x1,
- 1.0 + height - marker_size.y1);
-
- if (has_clippath) {
- while (path_curve.vertex(&x, &y) != agg::path_cmd_stop) {
- if (!(std::isfinite(x) && std::isfinite(y))) {
- continue;
- }
-
- /* These values are correctly snapped above -- so we don't want
- to round here, we really only want to truncate */
- x = floor(x);
- y = floor(y);
-
- // Cull points outside the boundary of the image.
- // Values that are too large may overflow and create
- // segfaults.
- // http://sourceforge.net/tracker/?func=detail&aid=2865490&group_id=80706&atid=560720
- if (!clipping_rect.hit_test(x, y)) {
- continue;
- }
-
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_aa_renderer_type ren(r);
-
- if (face.first) {
- ren.color(face.second);
- sa.init(fillCache, fillSize, x, y);
- agg::render_scanlines(sa, sl, ren);
- }
- ren.color(gc.color);
- sa.init(strokeCache, strokeSize, x, y);
- agg::render_scanlines(sa, sl, ren);
- }
- } else {
- while (path_curve.vertex(&x, &y) != agg::path_cmd_stop) {
- if (!(std::isfinite(x) && std::isfinite(y))) {
- continue;
- }
-
- /* These values are correctly snapped above -- so we don't want
- to round here, we really only want to truncate */
- x = floor(x);
- y = floor(y);
-
- // Cull points outside the boundary of the image.
- // Values that are too large may overflow and create
- // segfaults.
- // http://sourceforge.net/tracker/?func=detail&aid=2865490&group_id=80706&atid=560720
- if (!clipping_rect.hit_test(x, y)) {
- continue;
- }
-
- if (face.first) {
- rendererAA.color(face.second);
- sa.init(fillCache, fillSize, x, y);
- agg::render_scanlines(sa, sl, rendererAA);
- }
-
- rendererAA.color(gc.color);
- sa.init(strokeCache, strokeSize, x, y);
- agg::render_scanlines(sa, sl, rendererAA);
- }
- }
- }
- catch (...)
- {
- if (fillCache != staticFillCache)
- delete[] fillCache;
- if (strokeCache != staticStrokeCache)
- delete[] strokeCache;
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- throw;
- }
-
- if (fillCache != staticFillCache)
- delete[] fillCache;
- if (strokeCache != staticStrokeCache)
- delete[] strokeCache;
-
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
-}
-
-/**
- * This is a custom span generator that converts spans in the
- * 8-bit inverted greyscale font buffer to rgba that agg can use.
- */
-template <class ChildGenerator>
-class font_to_rgba
-{
- public:
- typedef ChildGenerator child_type;
- typedef agg::rgba8 color_type;
- typedef typename child_type::color_type child_color_type;
- typedef agg::span_allocator<child_color_type> span_alloc_type;
-
- private:
- child_type *_gen;
- color_type _color;
- span_alloc_type _allocator;
-
- public:
- font_to_rgba(child_type *gen, color_type color) : _gen(gen), _color(color)
- {
- }
-
- inline void generate(color_type *output_span, int x, int y, unsigned len)
- {
- _allocator.allocate(len);
- child_color_type *input_span = _allocator.span();
- _gen->generate(input_span, x, y, len);
-
- do {
- *output_span = _color;
- output_span->a = ((unsigned int)_color.a * (unsigned int)input_span->v) >> 8;
- ++output_span;
- ++input_span;
- } while (--len);
- }
-
- void prepare()
- {
- _gen->prepare();
- }
-};
-
-template <class ImageArray>
-inline void RendererAgg::draw_text_image(GCAgg &gc, ImageArray &image, int x, int y, double angle)
-{
- typedef agg::span_allocator<agg::rgba8> color_span_alloc_type;
- typedef agg::span_interpolator_linear<> interpolator_type;
- typedef agg::image_accessor_clip<agg::pixfmt_gray8> image_accessor_type;
- typedef agg::span_image_filter_gray<image_accessor_type, interpolator_type> image_span_gen_type;
- typedef font_to_rgba<image_span_gen_type> span_gen_type;
- typedef agg::renderer_scanline_aa<renderer_base, color_span_alloc_type, span_gen_type>
- renderer_type;
-
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- if (angle != 0.0) {
- agg::rendering_buffer srcbuf(
- image.data(), (unsigned)image.dim(1),
- (unsigned)image.dim(0), (unsigned)image.dim(1));
- agg::pixfmt_gray8 pixf_img(srcbuf);
-
- set_clipbox(gc.cliprect, theRasterizer);
-
- agg::trans_affine mtx;
- mtx *= agg::trans_affine_translation(0, -image.dim(0));
- mtx *= agg::trans_affine_rotation(-angle * agg::pi / 180.0);
- mtx *= agg::trans_affine_translation(x, y);
-
- agg::path_storage rect;
- rect.move_to(0, 0);
- rect.line_to(image.dim(1), 0);
- rect.line_to(image.dim(1), image.dim(0));
- rect.line_to(0, image.dim(0));
- rect.line_to(0, 0);
- agg::conv_transform<agg::path_storage> rect2(rect, mtx);
-
- agg::trans_affine inv_mtx(mtx);
- inv_mtx.invert();
-
- agg::image_filter_lut filter;
- filter.calculate(agg::image_filter_spline36());
- interpolator_type interpolator(inv_mtx);
- color_span_alloc_type sa;
- image_accessor_type ia(pixf_img, agg::gray8(0));
- image_span_gen_type image_span_generator(ia, interpolator, filter);
- span_gen_type output_span_generator(&image_span_generator, gc.color);
- renderer_type ri(rendererBase, sa, output_span_generator);
-
- theRasterizer.add_path(rect2);
- agg::render_scanlines(theRasterizer, slineP8, ri);
- } else {
- agg::rect_i fig, text;
-
- fig.init(0, 0, width, height);
- text.init(x, y - image.dim(0), x + image.dim(1), y);
- text.clip(fig);
-
- if (gc.cliprect.x1 != 0.0 || gc.cliprect.y1 != 0.0 || gc.cliprect.x2 != 0.0 || gc.cliprect.y2 != 0.0) {
- agg::rect_i clip;
-
- clip.init(int(mpl_round(gc.cliprect.x1)),
- int(mpl_round(height - gc.cliprect.y2)),
- int(mpl_round(gc.cliprect.x2)),
- int(mpl_round(height - gc.cliprect.y1)));
- text.clip(clip);
- }
-
- if (text.x2 > text.x1) {
- for (int yi = text.y1; yi < text.y2; ++yi) {
- pixFmt.blend_solid_hspan(text.x1, yi, (text.x2 - text.x1), gc.color,
- &image(yi - (y - image.dim(0)), text.x1 - x));
- }
- }
- }
-}
-
-class span_conv_alpha
-{
- public:
- typedef agg::rgba8 color_type;
-
- double m_alpha;
-
- span_conv_alpha(double alpha) : m_alpha(alpha)
- {
- }
-
- void prepare()
- {
- }
- void generate(color_type *span, int x, int y, unsigned len) const
- {
- do {
- span->a = (agg::int8u)((double)span->a * m_alpha);
- ++span;
- } while (--len);
- }
-};
-
-template <class ImageArray>
-inline void RendererAgg::draw_image(GCAgg &gc,
- double x,
- double y,
- ImageArray &image)
-{
- double alpha = gc.alpha;
-
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(gc.cliprect, theRasterizer);
- bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans);
-
- agg::rendering_buffer buffer;
- buffer.attach(
- image.data(), (unsigned)image.dim(1), (unsigned)image.dim(0), -(int)image.dim(1) * 4);
- pixfmt pixf(buffer);
-
- if (has_clippath) {
- agg::trans_affine mtx;
- agg::path_storage rect;
-
- mtx *= agg::trans_affine_translation((int)x, (int)(height - (y + image.dim(0))));
-
- rect.move_to(0, 0);
- rect.line_to(image.dim(1), 0);
- rect.line_to(image.dim(1), image.dim(0));
- rect.line_to(0, image.dim(0));
- rect.line_to(0, 0);
-
- agg::conv_transform<agg::path_storage> rect2(rect, mtx);
-
- agg::trans_affine inv_mtx(mtx);
- inv_mtx.invert();
-
- typedef agg::span_allocator<agg::rgba8> color_span_alloc_type;
- typedef agg::image_accessor_clip<pixfmt> image_accessor_type;
- typedef agg::span_interpolator_linear<> interpolator_type;
- typedef agg::span_image_filter_rgba_nn<image_accessor_type, interpolator_type>
- image_span_gen_type;
- typedef agg::span_converter<image_span_gen_type, span_conv_alpha> span_conv;
-
- color_span_alloc_type sa;
- image_accessor_type ia(pixf, agg::rgba8(0, 0, 0, 0));
- interpolator_type interpolator(inv_mtx);
- image_span_gen_type image_span_generator(ia, interpolator);
- span_conv_alpha conv_alpha(alpha);
- span_conv spans(image_span_generator, conv_alpha);
-
- typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
- typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
- typedef agg::renderer_scanline_aa<amask_ren_type, color_span_alloc_type, span_conv>
- renderer_type_alpha;
-
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- renderer_type_alpha ri(r, sa, spans);
-
- theRasterizer.add_path(rect2);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ri);
- } else {
- set_clipbox(gc.cliprect, rendererBase);
- rendererBase.blend_from(
- pixf, 0, (int)x, (int)(height - (y + image.dim(0))), (agg::int8u)(alpha * 255));
- }
-
- rendererBase.reset_clipping(true);
-}
-
-template <class PathIterator,
- class PathGenerator,
- class TransformArray,
- class OffsetArray,
- class ColorArray,
- class LineWidthArray,
- class AntialiasedArray>
-inline void RendererAgg::_draw_path_collection_generic(GCAgg &gc,
- agg::trans_affine master_transform,
- const agg::rect_d &cliprect,
- PathIterator &clippath,
- const agg::trans_affine &clippath_trans,
- PathGenerator &path_generator,
- TransformArray &transforms,
- OffsetArray &offsets,
- const agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- ColorArray &edgecolors,
- LineWidthArray &linewidths,
- DashesVector &linestyles,
- AntialiasedArray &antialiaseds,
- e_offset_position offset_position,
- int check_snap,
- int has_curves)
-{
- typedef agg::conv_transform<typename PathGenerator::path_iterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removed_t;
- typedef PathClipper<nan_removed_t> clipped_t;
- typedef PathSnapper<clipped_t> snapped_t;
- typedef agg::conv_curve<snapped_t> snapped_curve_t;
- typedef agg::conv_curve<clipped_t> curve_t;
-
- size_t Npaths = path_generator.num_paths();
- size_t Noffsets = offsets.size();
- size_t N = std::max(Npaths, Noffsets);
-
- size_t Ntransforms = transforms.size();
- size_t Nfacecolors = facecolors.size();
- size_t Nedgecolors = edgecolors.size();
- size_t Nlinewidths = linewidths.size();
- size_t Nlinestyles = std::min(linestyles.size(), N);
- size_t Naa = antialiaseds.size();
-
- if ((Nfacecolors == 0 && Nedgecolors == 0) || Npaths == 0) {
- return;
- }
-
- // Handle any clipping globally
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(cliprect, theRasterizer);
- bool has_clippath = render_clippath(clippath, clippath_trans);
-
- // Set some defaults, assuming no face or edge
- gc.linewidth = 0.0;
- facepair_t face;
- face.first = Nfacecolors != 0;
- agg::trans_affine trans;
-
- for (int i = 0; i < (int)N; ++i) {
- typename PathGenerator::path_iterator path = path_generator(i);
-
- if (Ntransforms) {
- int it = i % Ntransforms;
- trans = agg::trans_affine(transforms(it, 0, 0),
- transforms(it, 1, 0),
- transforms(it, 0, 1),
- transforms(it, 1, 1),
- transforms(it, 0, 2),
- transforms(it, 1, 2));
- trans *= master_transform;
- } else {
- trans = master_transform;
- }
-
- if (Noffsets) {
- double xo = offsets(i % Noffsets, 0);
- double yo = offsets(i % Noffsets, 1);
- offset_trans.transform(&xo, &yo);
- if (offset_position == OFFSET_POSITION_DATA) {
- trans = agg::trans_affine_translation(xo, yo) * trans;
- } else {
- trans *= agg::trans_affine_translation(xo, yo);
- }
- }
-
- // These transformations must be done post-offsets
- trans *= agg::trans_affine_scaling(1.0, -1.0);
- trans *= agg::trans_affine_translation(0.0, (double)height);
-
- if (Nfacecolors) {
- int ic = i % Nfacecolors;
- face.second = agg::rgba(facecolors(ic, 0), facecolors(ic, 1), facecolors(ic, 2), facecolors(ic, 3));
- }
-
- if (Nedgecolors) {
- int ic = i % Nedgecolors;
- gc.color = agg::rgba(edgecolors(ic, 0), edgecolors(ic, 1), edgecolors(ic, 2), edgecolors(ic, 3));
-
- if (Nlinewidths) {
- gc.linewidth = linewidths(i % Nlinewidths);
- } else {
- gc.linewidth = 1.0;
- }
- if (Nlinestyles) {
- gc.dashes = linestyles[i % Nlinestyles];
- }
- }
-
- bool do_clip = !face.first && !gc.has_hatchpath() && !has_curves;
-
- if (check_snap) {
- gc.isaa = antialiaseds(i % Naa);
-
- transformed_path_t tpath(path, trans);
- nan_removed_t nan_removed(tpath, true, has_curves);
- clipped_t clipped(nan_removed, do_clip && !has_curves, width, height);
- snapped_t snapped(
- clipped, gc.snap_mode, path.total_vertices(), points_to_pixels(gc.linewidth));
- if (has_curves) {
- snapped_curve_t curve(snapped);
- _draw_path(curve, has_clippath, face, gc);
- } else {
- _draw_path(snapped, has_clippath, face, gc);
- }
- } else {
- gc.isaa = antialiaseds(i % Naa);
-
- transformed_path_t tpath(path, trans);
- nan_removed_t nan_removed(tpath, true, has_curves);
- clipped_t clipped(nan_removed, do_clip, width, height);
- if (has_curves) {
- curve_t curve(clipped);
- _draw_path(curve, has_clippath, face, gc);
- } else {
- _draw_path(clipped, has_clippath, face, gc);
- }
- }
- }
-}
-
-template <class PathGenerator,
- class TransformArray,
- class OffsetArray,
- class ColorArray,
- class LineWidthArray,
- class AntialiasedArray>
-inline void RendererAgg::draw_path_collection(GCAgg &gc,
- agg::trans_affine &master_transform,
- PathGenerator &path,
- TransformArray &transforms,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- ColorArray &edgecolors,
- LineWidthArray &linewidths,
- DashesVector &linestyles,
- AntialiasedArray &antialiaseds,
- e_offset_position offset_position)
-{
- _draw_path_collection_generic(gc,
- master_transform,
- gc.cliprect,
- gc.clippath.path,
- gc.clippath.trans,
- path,
- transforms,
- offsets,
- offset_trans,
- facecolors,
- edgecolors,
- linewidths,
- linestyles,
- antialiaseds,
- offset_position,
- 1,
- 1);
-}
-
-template <class CoordinateArray>
-class QuadMeshGenerator
-{
- unsigned m_meshWidth;
- unsigned m_meshHeight;
- CoordinateArray m_coordinates;
-
- class QuadMeshPathIterator
- {
- unsigned m_iterator;
- unsigned m_m, m_n;
- const CoordinateArray *m_coordinates;
-
- public:
- QuadMeshPathIterator(unsigned m, unsigned n, const CoordinateArray *coordinates)
- : m_iterator(0), m_m(m), m_n(n), m_coordinates(coordinates)
- {
- }
-
- private:
- inline unsigned vertex(unsigned idx, double *x, double *y)
- {
- size_t m = m_m + ((idx & 0x2) >> 1);
- size_t n = m_n + (((idx + 1) & 0x2) >> 1);
- *x = (*m_coordinates)(n, m, 0);
- *y = (*m_coordinates)(n, m, 1);
- return (idx) ? agg::path_cmd_line_to : agg::path_cmd_move_to;
- }
-
- public:
- inline unsigned vertex(double *x, double *y)
- {
- if (m_iterator >= total_vertices()) {
- return agg::path_cmd_stop;
- }
- return vertex(m_iterator++, x, y);
- }
-
- inline void rewind(unsigned path_id)
- {
- m_iterator = path_id;
- }
-
- inline unsigned total_vertices()
- {
- return 5;
- }
-
- inline bool should_simplify()
- {
- return false;
- }
- };
-
- public:
- typedef QuadMeshPathIterator path_iterator;
-
- inline QuadMeshGenerator(unsigned meshWidth, unsigned meshHeight, CoordinateArray &coordinates)
- : m_meshWidth(meshWidth), m_meshHeight(meshHeight), m_coordinates(coordinates)
- {
- }
-
- inline size_t num_paths() const
- {
- return m_meshWidth * m_meshHeight;
- }
-
- inline path_iterator operator()(size_t i) const
- {
- return QuadMeshPathIterator(i % m_meshWidth, i / m_meshWidth, &m_coordinates);
- }
-};
-
-template <class CoordinateArray, class OffsetArray, class ColorArray>
-inline void RendererAgg::draw_quad_mesh(GCAgg &gc,
- agg::trans_affine &master_transform,
- unsigned int mesh_width,
- unsigned int mesh_height,
- CoordinateArray &coordinates,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- bool antialiased,
- ColorArray &edgecolors)
-{
- QuadMeshGenerator<CoordinateArray> path_generator(mesh_width, mesh_height, coordinates);
-
- array::empty<double> transforms;
- array::scalar<double, 1> linewidths(gc.linewidth);
- array::scalar<uint8_t, 1> antialiaseds(antialiased);
- DashesVector linestyles;
- ColorArray *edgecolors_ptr = &edgecolors;
-
- if (edgecolors.size() == 0) {
- if (antialiased) {
- edgecolors_ptr = &facecolors;
- }
- }
-
- _draw_path_collection_generic(gc,
- master_transform,
- gc.cliprect,
- gc.clippath.path,
- gc.clippath.trans,
- path_generator,
- transforms,
- offsets,
- offset_trans,
- facecolors,
- *edgecolors_ptr,
- linewidths,
- linestyles,
- antialiaseds,
- OFFSET_POSITION_FIGURE,
- 0,
- 0);
-}
-
-template <class PointArray, class ColorArray>
-inline void RendererAgg::_draw_gouraud_triangle(PointArray &points,
- ColorArray &colors,
- agg::trans_affine trans,
- bool has_clippath)
-{
- typedef agg::rgba8 color_t;
- typedef agg::span_gouraud_rgba<color_t> span_gen_t;
- typedef agg::span_allocator<color_t> span_alloc_t;
-
- trans *= agg::trans_affine_scaling(1.0, -1.0);
- trans *= agg::trans_affine_translation(0.0, (double)height);
-
- double tpoints[3][2];
-
- for (int i = 0; i < 3; ++i) {
- for (int j = 0; j < 2; ++j) {
- tpoints[i][j] = points(i, j);
- }
- trans.transform(&tpoints[i][0], &tpoints[i][1]);
- }
-
- span_alloc_t span_alloc;
- span_gen_t span_gen;
-
- span_gen.colors(agg::rgba(colors(0, 0), colors(0, 1), colors(0, 2), colors(0, 3)),
- agg::rgba(colors(1, 0), colors(1, 1), colors(1, 2), colors(1, 3)),
- agg::rgba(colors(2, 0), colors(2, 1), colors(2, 2), colors(2, 3)));
- span_gen.triangle(tpoints[0][0],
- tpoints[0][1],
- tpoints[1][0],
- tpoints[1][1],
- tpoints[2][0],
- tpoints[2][1],
- 0.5);
-
- theRasterizer.add_path(span_gen);
-
- if (has_clippath) {
- typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
- typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
- typedef agg::renderer_scanline_aa<amask_ren_type, span_alloc_t, span_gen_t>
- amask_aa_renderer_type;
-
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_aa_renderer_type ren(r, span_alloc, span_gen);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ren);
- } else {
- agg::render_scanlines_aa(theRasterizer, slineP8, rendererBase, span_alloc, span_gen);
- }
-}
-
-template <class PointArray, class ColorArray>
-inline void RendererAgg::draw_gouraud_triangle(GCAgg &gc,
- PointArray &points,
- ColorArray &colors,
- agg::trans_affine &trans)
-{
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(gc.cliprect, theRasterizer);
- bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans);
-
- _draw_gouraud_triangle(points, colors, trans, has_clippath);
-}
-
-template <class PointArray, class ColorArray>
-inline void RendererAgg::draw_gouraud_triangles(GCAgg &gc,
- PointArray &points,
- ColorArray &colors,
- agg::trans_affine &trans)
-{
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(gc.cliprect, theRasterizer);
- bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans);
-
- for (int i = 0; i < points.dim(0); ++i) {
- typename PointArray::sub_t point = points.subarray(i);
- typename ColorArray::sub_t color = colors.subarray(i);
-
- _draw_gouraud_triangle(point, color, trans, has_clippath);
- }
-}
-
-template <class R>
-void RendererAgg::set_clipbox(const agg::rect_d &cliprect, R &rasterizer)
-{
- // set the clip rectangle from the gc
-
- if (cliprect.x1 != 0.0 || cliprect.y1 != 0.0 || cliprect.x2 != 0.0 || cliprect.y2 != 0.0) {
- rasterizer.clip_box(std::max(int(floor(cliprect.x1 + 0.5)), 0),
- std::max(int(floor(height - cliprect.y1 + 0.5)), 0),
- std::min(int(floor(cliprect.x2 + 0.5)), int(width)),
- std::min(int(floor(height - cliprect.y2 + 0.5)), int(height)));
- } else {
- rasterizer.clip_box(0, 0, width, height);
- }
-}
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/_backend_agg_basic_types.h b/contrib/python/matplotlib/py2/src/_backend_agg_basic_types.h
deleted file mode 100644
index 74a318e7d2..0000000000
--- a/contrib/python/matplotlib/py2/src/_backend_agg_basic_types.h
+++ /dev/null
@@ -1,127 +0,0 @@
-#ifndef __BACKEND_AGG_BASIC_TYPES_H__
-#define __BACKEND_AGG_BASIC_TYPES_H__
-
-/* Contains some simple types from the Agg backend that are also used
- by other modules */
-
-#include <vector>
-
-#include "agg_color_rgba.h"
-#include "agg_math_stroke.h"
-#include "path_converters.h"
-
-#include "py_adaptors.h"
-
-struct ClipPath
-{
- py::PathIterator path;
- agg::trans_affine trans;
-};
-
-struct SketchParams
-{
- double scale;
- double length;
- double randomness;
-};
-
-class Dashes
-{
- typedef std::vector<std::pair<double, double> > dash_t;
- double dash_offset;
- dash_t dashes;
-
- public:
- double get_dash_offset() const
- {
- return dash_offset;
- }
- void set_dash_offset(double x)
- {
- dash_offset = x;
- }
- void add_dash_pair(double length, double skip)
- {
- dashes.push_back(std::make_pair(length, skip));
- }
- size_t size() const
- {
- return dashes.size();
- }
-
- template <class T>
- void dash_to_stroke(T &stroke, double dpi, bool isaa)
- {
- for (dash_t::const_iterator i = dashes.begin(); i != dashes.end(); ++i) {
- double val0 = i->first;
- double val1 = i->second;
- val0 = val0 * dpi / 72.0;
- val1 = val1 * dpi / 72.0;
- if (!isaa) {
- val0 = (int)val0 + 0.5;
- val1 = (int)val1 + 0.5;
- }
- stroke.add_dash(val0, val1);
- }
- stroke.dash_start(get_dash_offset() * dpi / 72.0);
- }
-};
-
-typedef std::vector<Dashes> DashesVector;
-
-enum e_offset_position {
- OFFSET_POSITION_FIGURE,
- OFFSET_POSITION_DATA
-};
-
-class GCAgg
-{
- public:
- GCAgg()
- : linewidth(1.0),
- alpha(1.0),
- cap(agg::butt_cap),
- join(agg::round_join),
- snap_mode(SNAP_FALSE)
- {
- }
-
- ~GCAgg()
- {
- }
-
- double linewidth;
- double alpha;
- bool forced_alpha;
- agg::rgba color;
- bool isaa;
-
- agg::line_cap_e cap;
- agg::line_join_e join;
-
- agg::rect_d cliprect;
-
- ClipPath clippath;
-
- Dashes dashes;
-
- e_snap_mode snap_mode;
-
- py::PathIterator hatchpath;
- agg::rgba hatch_color;
- double hatch_linewidth;
-
- SketchParams sketch;
-
- bool has_hatchpath()
- {
- return hatchpath.total_vertices();
- }
-
- private:
- // prevent copying
- GCAgg(const GCAgg &);
- GCAgg &operator=(const GCAgg &);
-};
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/_backend_agg_wrapper.cpp b/contrib/python/matplotlib/py2/src/_backend_agg_wrapper.cpp
deleted file mode 100644
index ea6c7b1267..0000000000
--- a/contrib/python/matplotlib/py2/src/_backend_agg_wrapper.cpp
+++ /dev/null
@@ -1,777 +0,0 @@
-#include "mplutils.h"
-#include "py_converters.h"
-#include "_backend_agg.h"
-
-typedef struct
-{
- PyObject_HEAD
- RendererAgg *x;
- Py_ssize_t shape[3];
- Py_ssize_t strides[3];
- Py_ssize_t suboffsets[3];
-} PyRendererAgg;
-
-typedef struct
-{
- PyObject_HEAD
- BufferRegion *x;
- Py_ssize_t shape[3];
- Py_ssize_t strides[3];
- Py_ssize_t suboffsets[3];
-} PyBufferRegion;
-
-
-/**********************************************************************
- * BufferRegion
- * */
-
-static PyObject *PyBufferRegion_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyBufferRegion *self;
- self = (PyBufferRegion *)type->tp_alloc(type, 0);
- self->x = NULL;
- return (PyObject *)self;
-}
-
-static void PyBufferRegion_dealloc(PyBufferRegion *self)
-{
- delete self->x;
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-static PyObject *PyBufferRegion_to_string(PyBufferRegion *self, PyObject *args, PyObject *kwds)
-{
- return PyBytes_FromStringAndSize((const char *)self->x->get_data(),
- self->x->get_height() * self->x->get_stride());
-}
-
-/* TODO: This doesn't seem to be used internally. Remove? */
-
-static PyObject *PyBufferRegion_set_x(PyBufferRegion *self, PyObject *args, PyObject *kwds)
-{
- int x;
- if (!PyArg_ParseTuple(args, "i:set_x", &x)) {
- return NULL;
- }
- self->x->get_rect().x1 = x;
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyBufferRegion_set_y(PyBufferRegion *self, PyObject *args, PyObject *kwds)
-{
- int y;
- if (!PyArg_ParseTuple(args, "i:set_y", &y)) {
- return NULL;
- }
- self->x->get_rect().y1 = y;
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyBufferRegion_get_extents(PyBufferRegion *self, PyObject *args, PyObject *kwds)
-{
- agg::rect_i rect = self->x->get_rect();
-
- return Py_BuildValue("IIII", rect.x1, rect.y1, rect.x2, rect.y2);
-}
-
-static PyObject *PyBufferRegion_to_string_argb(PyBufferRegion *self, PyObject *args, PyObject *kwds)
-{
- PyObject *bufobj;
- uint8_t *buf;
-
- bufobj = PyBytes_FromStringAndSize(NULL, self->x->get_height() * self->x->get_stride());
- buf = (uint8_t *)PyBytes_AS_STRING(bufobj);
-
- CALL_CPP_CLEANUP("to_string_argb", (self->x->to_string_argb(buf)), Py_DECREF(bufobj));
-
- return bufobj;
-}
-
-int PyBufferRegion_get_buffer(PyBufferRegion *self, Py_buffer *buf, int flags)
-{
- Py_INCREF(self);
- buf->obj = (PyObject *)self;
- buf->buf = self->x->get_data();
- buf->len = self->x->get_width() * self->x->get_height() * 4;
- buf->readonly = 0;
- buf->format = (char *)"B";
- buf->ndim = 3;
- self->shape[0] = self->x->get_height();
- self->shape[1] = self->x->get_width();
- self->shape[2] = 4;
- buf->shape = self->shape;
- self->strides[0] = self->x->get_width() * 4;
- self->strides[1] = 4;
- self->strides[2] = 1;
- buf->strides = self->strides;
- buf->suboffsets = NULL;
- buf->itemsize = 1;
- buf->internal = NULL;
-
- return 1;
-}
-
-static PyTypeObject PyBufferRegionType;
-
-static PyTypeObject *PyBufferRegion_init_type(PyObject *m, PyTypeObject *type)
-{
- static PyMethodDef methods[] = {
- { "to_string", (PyCFunction)PyBufferRegion_to_string, METH_NOARGS, NULL },
- { "to_string_argb", (PyCFunction)PyBufferRegion_to_string_argb, METH_NOARGS, NULL },
- { "set_x", (PyCFunction)PyBufferRegion_set_x, METH_VARARGS, NULL },
- { "set_y", (PyCFunction)PyBufferRegion_set_y, METH_VARARGS, NULL },
- { "get_extents", (PyCFunction)PyBufferRegion_get_extents, METH_NOARGS, NULL },
- { NULL }
- };
-
- static PyBufferProcs buffer_procs;
- memset(&buffer_procs, 0, sizeof(PyBufferProcs));
- buffer_procs.bf_getbuffer = (getbufferproc)PyBufferRegion_get_buffer;
-
- memset(type, 0, sizeof(PyTypeObject));
- type->tp_name = "matplotlib.backends._backend_agg.BufferRegion";
- type->tp_basicsize = sizeof(PyBufferRegion);
- type->tp_dealloc = (destructor)PyBufferRegion_dealloc;
- type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_NEWBUFFER;
- type->tp_methods = methods;
- type->tp_new = PyBufferRegion_new;
- type->tp_as_buffer = &buffer_procs;
-
- if (PyType_Ready(type) < 0) {
- return NULL;
- }
-
- /* Don't need to add to module, since you can't create buffer
- regions directly from Python */
-
- return type;
-}
-
-/**********************************************************************
- * RendererAgg
- * */
-
-static PyObject *PyRendererAgg_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyRendererAgg *self;
- self = (PyRendererAgg *)type->tp_alloc(type, 0);
- self->x = NULL;
- return (PyObject *)self;
-}
-
-static int PyRendererAgg_init(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- unsigned int width;
- unsigned int height;
- double dpi;
- int debug = 0;
-
- if (!PyArg_ParseTuple(args, "IId|i:RendererAgg", &width, &height, &dpi, &debug)) {
- return -1;
- }
-
- if (dpi <= 0.0) {
- PyErr_SetString(PyExc_ValueError, "dpi must be positive");
- return -1;
- }
-
- if (width >= 1 << 16 || height >= 1 << 16) {
- PyErr_Format(
- PyExc_ValueError,
- "Image size of %dx%d pixels is too large. "
- "It must be less than 2^16 in each direction.",
- width, height);
- return -1;
- }
-
- CALL_CPP_INIT("RendererAgg", self->x = new RendererAgg(width, height, dpi))
-
- return 0;
-}
-
-static void PyRendererAgg_dealloc(PyRendererAgg *self)
-{
- delete self->x;
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-static PyObject *PyRendererAgg_draw_path(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- GCAgg gc;
- py::PathIterator path;
- agg::trans_affine trans;
- PyObject *faceobj = NULL;
- agg::rgba face;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&|O:draw_path",
- &convert_gcagg,
- &gc,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &faceobj)) {
- return NULL;
- }
-
- if (!convert_face(faceobj, gc, &face)) {
- return NULL;
- }
-
- CALL_CPP("draw_path", (self->x->draw_path(gc, path, trans, face)));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyRendererAgg_draw_text_image(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- numpy::array_view<agg::int8u, 2> image;
- double x;
- double y;
- double angle;
- GCAgg gc;
-
- if (!PyArg_ParseTuple(args,
- "O&dddO&:draw_text_image",
- &image.converter_contiguous,
- &image,
- &x,
- &y,
- &angle,
- &convert_gcagg,
- &gc)) {
- return NULL;
- }
-
- CALL_CPP("draw_text_image", (self->x->draw_text_image(gc, image, x, y, angle)));
-
- Py_RETURN_NONE;
-}
-
-PyObject *PyRendererAgg_draw_markers(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- GCAgg gc;
- py::PathIterator marker_path;
- agg::trans_affine marker_path_trans;
- py::PathIterator path;
- agg::trans_affine trans;
- PyObject *faceobj = NULL;
- agg::rgba face;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&O&|O:draw_markers",
- &convert_gcagg,
- &gc,
- &convert_path,
- &marker_path,
- &convert_trans_affine,
- &marker_path_trans,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &faceobj)) {
- return NULL;
- }
-
- if (!convert_face(faceobj, gc, &face)) {
- return NULL;
- }
-
- CALL_CPP("draw_markers",
- (self->x->draw_markers(gc, marker_path, marker_path_trans, path, trans, face)));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyRendererAgg_draw_image(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- GCAgg gc;
- double x;
- double y;
- numpy::array_view<agg::int8u, 3> image;
-
- if (!PyArg_ParseTuple(args,
- "O&ddO&:draw_image",
- &convert_gcagg,
- &gc,
- &x,
- &y,
- &image.converter_contiguous,
- &image)) {
- return NULL;
- }
-
- x = mpl_round(x);
- y = mpl_round(y);
-
- gc.alpha = 1.0;
- CALL_CPP("draw_image", (self->x->draw_image(gc, x, y, image)));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *
-PyRendererAgg_draw_path_collection(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- GCAgg gc;
- agg::trans_affine master_transform;
- PyObject *pathobj;
- numpy::array_view<const double, 3> transforms;
- numpy::array_view<const double, 2> offsets;
- agg::trans_affine offset_trans;
- numpy::array_view<const double, 2> facecolors;
- numpy::array_view<const double, 2> edgecolors;
- numpy::array_view<const double, 1> linewidths;
- DashesVector dashes;
- numpy::array_view<const uint8_t, 1> antialiaseds;
- PyObject *ignored;
- e_offset_position offset_position;
-
- if (!PyArg_ParseTuple(args,
- "O&O&OO&O&O&O&O&O&O&O&OO&:draw_path_collection",
- &convert_gcagg,
- &gc,
- &convert_trans_affine,
- &master_transform,
- &pathobj,
- &convert_transforms,
- &transforms,
- &convert_points,
- &offsets,
- &convert_trans_affine,
- &offset_trans,
- &convert_colors,
- &facecolors,
- &convert_colors,
- &edgecolors,
- &linewidths.converter,
- &linewidths,
- &convert_dashes_vector,
- &dashes,
- &antialiaseds.converter,
- &antialiaseds,
- &ignored,
- &convert_offset_position,
- &offset_position)) {
- return NULL;
- }
-
- try
- {
- py::PathGenerator path(pathobj);
-
- CALL_CPP("draw_path_collection",
- (self->x->draw_path_collection(gc,
- master_transform,
- path,
- transforms,
- offsets,
- offset_trans,
- facecolors,
- edgecolors,
- linewidths,
- dashes,
- antialiaseds,
- offset_position)));
- }
- catch (const py::exception &)
- {
- return NULL;
- }
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyRendererAgg_draw_quad_mesh(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- GCAgg gc;
- agg::trans_affine master_transform;
- unsigned int mesh_width;
- unsigned int mesh_height;
- numpy::array_view<const double, 3> coordinates;
- numpy::array_view<const double, 2> offsets;
- agg::trans_affine offset_trans;
- numpy::array_view<const double, 2> facecolors;
- int antialiased;
- numpy::array_view<const double, 2> edgecolors;
-
- if (!PyArg_ParseTuple(args,
- "O&O&IIO&O&O&O&iO&:draw_quad_mesh",
- &convert_gcagg,
- &gc,
- &convert_trans_affine,
- &master_transform,
- &mesh_width,
- &mesh_height,
- &coordinates.converter,
- &coordinates,
- &convert_points,
- &offsets,
- &convert_trans_affine,
- &offset_trans,
- &convert_colors,
- &facecolors,
- &antialiased,
- &convert_colors,
- &edgecolors)) {
- return NULL;
- }
-
- CALL_CPP("draw_quad_mesh",
- (self->x->draw_quad_mesh(gc,
- master_transform,
- mesh_width,
- mesh_height,
- coordinates,
- offsets,
- offset_trans,
- facecolors,
- antialiased,
- edgecolors)));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *
-PyRendererAgg_draw_gouraud_triangle(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- GCAgg gc;
- numpy::array_view<const double, 2> points;
- numpy::array_view<const double, 2> colors;
- agg::trans_affine trans;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&|O:draw_gouraud_triangle",
- &convert_gcagg,
- &gc,
- &points.converter,
- &points,
- &colors.converter,
- &colors,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- if (points.dim(0) != 3 || points.dim(1) != 2) {
- PyErr_Format(PyExc_ValueError,
- "points must be a 3x2 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT,
- points.dim(0), points.dim(1));
- return NULL;
- }
-
- if (colors.dim(0) != 3 || colors.dim(1) != 4) {
- PyErr_Format(PyExc_ValueError,
- "colors must be a 3x4 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT,
- colors.dim(0), colors.dim(1));
- return NULL;
- }
-
-
- CALL_CPP("draw_gouraud_triangle", (self->x->draw_gouraud_triangle(gc, points, colors, trans)));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *
-PyRendererAgg_draw_gouraud_triangles(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- GCAgg gc;
- numpy::array_view<const double, 3> points;
- numpy::array_view<const double, 3> colors;
- agg::trans_affine trans;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&|O:draw_gouraud_triangles",
- &convert_gcagg,
- &gc,
- &points.converter,
- &points,
- &colors.converter,
- &colors,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- if (points.size() != 0 && (points.dim(1) != 3 || points.dim(2) != 2)) {
- PyErr_Format(PyExc_ValueError,
- "points must be a Nx3x2 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT "x%" NPY_INTP_FMT,
- points.dim(0), points.dim(1), points.dim(2));
- return NULL;
- }
-
- if (colors.size() != 0 && (colors.dim(1) != 3 || colors.dim(2) != 4)) {
- PyErr_Format(PyExc_ValueError,
- "colors must be a Nx3x4 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT "x%" NPY_INTP_FMT,
- colors.dim(0), colors.dim(1), colors.dim(2));
- return NULL;
- }
-
- if (points.size() != colors.size()) {
- PyErr_Format(PyExc_ValueError,
- "points and colors arrays must be the same length, got %" NPY_INTP_FMT " and %" NPY_INTP_FMT,
- points.dim(0), colors.dim(0));
- return NULL;
- }
-
- CALL_CPP("draw_gouraud_triangles", self->x->draw_gouraud_triangles(gc, points, colors, trans));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyRendererAgg_tostring_rgb(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- PyObject *buffobj = NULL;
-
- buffobj = PyBytes_FromStringAndSize(NULL, self->x->get_width() * self->x->get_height() * 3);
- if (buffobj == NULL) {
- return NULL;
- }
-
- CALL_CPP_CLEANUP("tostring_rgb",
- (self->x->tostring_rgb((uint8_t *)PyBytes_AS_STRING(buffobj))),
- Py_DECREF(buffobj));
-
- return buffobj;
-}
-
-static PyObject *PyRendererAgg_tostring_argb(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- PyObject *buffobj = NULL;
-
- buffobj = PyBytes_FromStringAndSize(NULL, self->x->get_width() * self->x->get_height() * 4);
- if (buffobj == NULL) {
- return NULL;
- }
-
- CALL_CPP_CLEANUP("tostring_argb",
- (self->x->tostring_argb((uint8_t *)PyBytes_AS_STRING(buffobj))),
- Py_DECREF(buffobj));
-
- return buffobj;
-}
-
-static PyObject *PyRendererAgg_tostring_bgra(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- PyObject *buffobj = NULL;
-
- buffobj = PyBytes_FromStringAndSize(NULL, self->x->get_width() * self->x->get_height() * 4);
- if (buffobj == NULL) {
- return NULL;
- }
-
- CALL_CPP_CLEANUP("to_string_bgra",
- (self->x->tostring_bgra((uint8_t *)PyBytes_AS_STRING(buffobj))),
- Py_DECREF(buffobj));
-
- return buffobj;
-}
-
-static PyObject *
-PyRendererAgg_get_content_extents(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- agg::rect_i extents;
-
- CALL_CPP("get_content_extents", (extents = self->x->get_content_extents()));
-
- return Py_BuildValue(
- "iiii", extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1);
-}
-
-static PyObject *PyRendererAgg_buffer_rgba(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
-#if PY3K
- return PyBytes_FromStringAndSize((const char *)self->x->pixBuffer,
- self->x->get_width() * self->x->get_height() * 4);
-#else
- return PyBuffer_FromReadWriteMemory(self->x->pixBuffer,
- self->x->get_width() * self->x->get_height() * 4);
-#endif
-}
-
-int PyRendererAgg_get_buffer(PyRendererAgg *self, Py_buffer *buf, int flags)
-{
- Py_INCREF(self);
- buf->obj = (PyObject *)self;
- buf->buf = self->x->pixBuffer;
- buf->len = self->x->get_width() * self->x->get_height() * 4;
- buf->readonly = 0;
- buf->format = (char *)"B";
- buf->ndim = 3;
- self->shape[0] = self->x->get_height();
- self->shape[1] = self->x->get_width();
- self->shape[2] = 4;
- buf->shape = self->shape;
- self->strides[0] = self->x->get_width() * 4;
- self->strides[1] = 4;
- self->strides[2] = 1;
- buf->strides = self->strides;
- buf->suboffsets = NULL;
- buf->itemsize = 1;
- buf->internal = NULL;
-
- return 1;
-}
-
-static PyObject *PyRendererAgg_clear(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- CALL_CPP("clear", self->x->clear());
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyRendererAgg_copy_from_bbox(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- agg::rect_d bbox;
- BufferRegion *reg;
- PyObject *regobj;
-
- if (!PyArg_ParseTuple(args, "O&:copy_from_bbox", &convert_rect, &bbox)) {
- return 0;
- }
-
- CALL_CPP("copy_from_bbox", (reg = self->x->copy_from_bbox(bbox)));
-
- regobj = PyBufferRegion_new(&PyBufferRegionType, NULL, NULL);
- ((PyBufferRegion *)regobj)->x = reg;
-
- return regobj;
-}
-
-static PyObject *PyRendererAgg_restore_region(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- PyBufferRegion *regobj;
- int xx1 = 0, yy1 = 0, xx2 = 0, yy2 = 0, x = 0, y = 0;
-
- if (!PyArg_ParseTuple(args,
- "O!|iiiiii:restore_region",
- &PyBufferRegionType,
- &regobj,
- &xx1,
- &yy1,
- &xx2,
- &yy2,
- &x,
- &y)) {
- return 0;
- }
-
- if (PySequence_Size(args) == 1) {
- CALL_CPP("restore_region", (self->x->restore_region(*(regobj->x))));
- } else {
- CALL_CPP("restore_region", self->x->restore_region(*(regobj->x), xx1, yy1, xx2, yy2, x, y));
- }
-
- Py_RETURN_NONE;
-}
-
-PyTypeObject PyRendererAggType;
-
-static PyTypeObject *PyRendererAgg_init_type(PyObject *m, PyTypeObject *type)
-{
- static PyMethodDef methods[] = {
- {"draw_path", (PyCFunction)PyRendererAgg_draw_path, METH_VARARGS, NULL},
- {"draw_markers", (PyCFunction)PyRendererAgg_draw_markers, METH_VARARGS, NULL},
- {"draw_text_image", (PyCFunction)PyRendererAgg_draw_text_image, METH_VARARGS, NULL},
- {"draw_image", (PyCFunction)PyRendererAgg_draw_image, METH_VARARGS, NULL},
- {"draw_path_collection", (PyCFunction)PyRendererAgg_draw_path_collection, METH_VARARGS, NULL},
- {"draw_quad_mesh", (PyCFunction)PyRendererAgg_draw_quad_mesh, METH_VARARGS, NULL},
- {"draw_gouraud_triangle", (PyCFunction)PyRendererAgg_draw_gouraud_triangle, METH_VARARGS, NULL},
- {"draw_gouraud_triangles", (PyCFunction)PyRendererAgg_draw_gouraud_triangles, METH_VARARGS, NULL},
-
- {"tostring_rgb", (PyCFunction)PyRendererAgg_tostring_rgb, METH_NOARGS, NULL},
- {"tostring_argb", (PyCFunction)PyRendererAgg_tostring_argb, METH_NOARGS, NULL},
- {"tostring_bgra", (PyCFunction)PyRendererAgg_tostring_bgra, METH_NOARGS, NULL},
- {"get_content_extents", (PyCFunction)PyRendererAgg_get_content_extents, METH_NOARGS, NULL},
- {"buffer_rgba", (PyCFunction)PyRendererAgg_buffer_rgba, METH_NOARGS, NULL},
- {"clear", (PyCFunction)PyRendererAgg_clear, METH_NOARGS, NULL},
-
- {"copy_from_bbox", (PyCFunction)PyRendererAgg_copy_from_bbox, METH_VARARGS, NULL},
- {"restore_region", (PyCFunction)PyRendererAgg_restore_region, METH_VARARGS, NULL},
- {NULL}
- };
-
- static PyBufferProcs buffer_procs;
- memset(&buffer_procs, 0, sizeof(PyBufferProcs));
- buffer_procs.bf_getbuffer = (getbufferproc)PyRendererAgg_get_buffer;
-
- memset(type, 0, sizeof(PyTypeObject));
- type->tp_name = "matplotlib.backends._backend_agg.RendererAgg";
- type->tp_basicsize = sizeof(PyRendererAgg);
- type->tp_dealloc = (destructor)PyRendererAgg_dealloc;
- type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_NEWBUFFER;
- type->tp_methods = methods;
- type->tp_init = (initproc)PyRendererAgg_init;
- type->tp_new = PyRendererAgg_new;
- type->tp_as_buffer = &buffer_procs;
-
- if (PyType_Ready(type) < 0) {
- return NULL;
- }
-
- if (PyModule_AddObject(m, "RendererAgg", (PyObject *)type)) {
- return NULL;
- }
-
- return type;
-}
-
-extern "C" {
-
-#if PY3K
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_backend_agg",
- NULL,
- 0,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit__backend_agg(void)
-
-#else
-#define INITERROR return
-
-PyMODINIT_FUNC init_backend_agg(void)
-#endif
-
-{
- PyObject *m;
-
-#if PY3K
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("_backend_agg", NULL, NULL);
-#endif
-
- if (m == NULL) {
- INITERROR;
- }
-
- import_array();
-
- if (!PyRendererAgg_init_type(m, &PyRendererAggType)) {
- INITERROR;
- }
-
- if (!PyBufferRegion_init_type(m, &PyBufferRegionType)) {
- INITERROR;
- }
-
-#if PY3K
- return m;
-#endif
-}
-
-} // extern "C"
diff --git a/contrib/python/matplotlib/py2/src/_backend_gdk.c b/contrib/python/matplotlib/py2/src/_backend_gdk.c
deleted file mode 100644
index 8314219cca..0000000000
--- a/contrib/python/matplotlib/py2/src/_backend_gdk.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- mode: C; c-basic-offset: 4 -*-
- * C extensions for backend_gdk
- */
-
-#include "Python.h"
-#include "numpy/arrayobject.h"
-
-#include <pygtk/pygtk.h>
-
-static PyTypeObject *_PyGdkPixbuf_Type;
-#define PyGdkPixbuf_Type (*_PyGdkPixbuf_Type)
-
-static PyObject *pixbuf_get_pixels_array(PyObject *self, PyObject *args)
-{
- /* 1) read in Python pixbuf, get the underlying gdk_pixbuf */
- PyGObject *py_pixbuf;
- GdkPixbuf *gdk_pixbuf;
- PyArrayObject *array;
- npy_intp dims[3] = { 0, 0, 3 };
- npy_intp strides[3];
-
- if (!PyArg_ParseTuple(args, "O!:pixbuf_get_pixels_array", &PyGdkPixbuf_Type, &py_pixbuf))
- return NULL;
-
- gdk_pixbuf = GDK_PIXBUF(py_pixbuf->obj);
-
- /* 2) same as pygtk/gtk/gdk.c _wrap_gdk_pixbuf_get_pixels_array()
- * with 'self' changed to py_pixbuf
- */
-
- dims[0] = gdk_pixbuf_get_height(gdk_pixbuf);
- dims[1] = gdk_pixbuf_get_width(gdk_pixbuf);
- if (gdk_pixbuf_get_has_alpha(gdk_pixbuf))
- dims[2] = 4;
-
- strides[0] = gdk_pixbuf_get_rowstride(gdk_pixbuf);
- strides[1] = dims[2];
- strides[2] = 1;
-
- array = (PyArrayObject*)
- PyArray_New(&PyArray_Type, 3, dims, NPY_UBYTE, strides,
- (void*)gdk_pixbuf_get_pixels(gdk_pixbuf), 1,
- NPY_ARRAY_WRITEABLE, NULL);
-
- if (array == NULL)
- return NULL;
-
- /* the array holds a ref to the pixbuf pixels through this wrapper*/
- Py_INCREF(py_pixbuf);
- if (PyArray_SetBaseObject(array, (PyObject *)py_pixbuf) == -1) {
- Py_DECREF(py_pixbuf);
- Py_DECREF(array);
- return NULL;
- }
- return PyArray_Return(array);
-}
-
-static PyMethodDef _backend_gdk_functions[] = {
- { "pixbuf_get_pixels_array", (PyCFunction)pixbuf_get_pixels_array, METH_VARARGS },
- { NULL, NULL, 0 }
-};
-
-PyMODINIT_FUNC init_backend_gdk(void)
-{
- PyObject *mod;
- mod = Py_InitModule("matplotlib.backends._backend_gdk", _backend_gdk_functions);
- import_array();
- init_pygtk();
-
- mod = PyImport_ImportModule("gtk.gdk");
- _PyGdkPixbuf_Type = (PyTypeObject *)PyObject_GetAttrString(mod, "Pixbuf");
-}
diff --git a/contrib/python/matplotlib/py2/src/_contour.cpp b/contrib/python/matplotlib/py2/src/_contour.cpp
deleted file mode 100644
index aecb442c7e..0000000000
--- a/contrib/python/matplotlib/py2/src/_contour.cpp
+++ /dev/null
@@ -1,1790 +0,0 @@
-// This file contains liberal use of asserts to assist code development and
-// debugging. Standard matplotlib builds disable asserts so they cause no
-// performance reduction. To enable the asserts, you need to undefine the
-// NDEBUG macro, which is achieved by adding the following
-// undef_macros=['NDEBUG']
-// to the appropriate make_extension call in setupext.py, and then rebuilding.
-#define NO_IMPORT_ARRAY
-
-#include "src/mplutils.h"
-#include "src/_contour.h"
-#include <algorithm>
-
-
-// 'kind' codes.
-#define MOVETO 1
-#define LINETO 2
-#define CLOSEPOLY 79
-
-// Point indices from current quad index.
-#define POINT_SW (quad)
-#define POINT_SE (quad+1)
-#define POINT_NW (quad+_nx)
-#define POINT_NE (quad+_nx+1)
-
-// CacheItem masks, only accessed directly to set. To read, use accessors
-// detailed below. 1 and 2 refer to level indices (lower and upper).
-#define MASK_Z_LEVEL 0x0003 // Combines the following two.
-#define MASK_Z_LEVEL_1 0x0001 // z > lower_level.
-#define MASK_Z_LEVEL_2 0x0002 // z > upper_level.
-#define MASK_VISITED_1 0x0004 // Algorithm has visited this quad.
-#define MASK_VISITED_2 0x0008
-#define MASK_SADDLE_1 0x0010 // quad is a saddle quad.
-#define MASK_SADDLE_2 0x0020
-#define MASK_SADDLE_LEFT_1 0x0040 // Contours turn left at saddle quad.
-#define MASK_SADDLE_LEFT_2 0x0080
-#define MASK_SADDLE_START_SW_1 0x0100 // Next visit starts on S or W edge.
-#define MASK_SADDLE_START_SW_2 0x0200
-#define MASK_BOUNDARY_S 0x0400 // S edge of quad is a boundary.
-#define MASK_BOUNDARY_W 0x0800 // W edge of quad is a boundary.
-// EXISTS_QUAD bit is always used, but the 4 EXISTS_CORNER are only used if
-// _corner_mask is true. Only one of EXISTS_QUAD or EXISTS_??_CORNER is ever
-// set per quad, hence not using unique bits for each; care is needed when
-// testing for these flags as they overlap.
-#define MASK_EXISTS_QUAD 0x1000 // All of quad exists (is not masked).
-#define MASK_EXISTS_SW_CORNER 0x2000 // SW corner exists, NE corner is masked.
-#define MASK_EXISTS_SE_CORNER 0x3000
-#define MASK_EXISTS_NW_CORNER 0x4000
-#define MASK_EXISTS_NE_CORNER 0x5000
-#define MASK_EXISTS 0x7000 // Combines all 5 EXISTS masks.
-
-// The following are only needed for filled contours.
-#define MASK_VISITED_S 0x10000 // Algorithm has visited S boundary.
-#define MASK_VISITED_W 0x20000 // Algorithm has visited W boundary.
-#define MASK_VISITED_CORNER 0x40000 // Algorithm has visited corner edge.
-
-
-// Accessors for various CacheItem masks. li is shorthand for level_index.
-#define Z_LEVEL(quad) (_cache[quad] & MASK_Z_LEVEL)
-#define Z_NE Z_LEVEL(POINT_NE)
-#define Z_NW Z_LEVEL(POINT_NW)
-#define Z_SE Z_LEVEL(POINT_SE)
-#define Z_SW Z_LEVEL(POINT_SW)
-#define VISITED(quad,li) (_cache[quad] & (li==1 ? MASK_VISITED_1 : MASK_VISITED_2))
-#define VISITED_S(quad) (_cache[quad] & MASK_VISITED_S)
-#define VISITED_W(quad) (_cache[quad] & MASK_VISITED_W)
-#define VISITED_CORNER(quad) (_cache[quad] & MASK_VISITED_CORNER)
-#define SADDLE(quad,li) (_cache[quad] & (li==1 ? MASK_SADDLE_1 : MASK_SADDLE_2))
-#define SADDLE_LEFT(quad,li) (_cache[quad] & (li==1 ? MASK_SADDLE_LEFT_1 : MASK_SADDLE_LEFT_2))
-#define SADDLE_START_SW(quad,li) (_cache[quad] & (li==1 ? MASK_SADDLE_START_SW_1 : MASK_SADDLE_START_SW_2))
-#define BOUNDARY_S(quad) (_cache[quad] & MASK_BOUNDARY_S)
-#define BOUNDARY_W(quad) (_cache[quad] & MASK_BOUNDARY_W)
-#define BOUNDARY_N(quad) BOUNDARY_S(quad+_nx)
-#define BOUNDARY_E(quad) BOUNDARY_W(quad+1)
-#define EXISTS_QUAD(quad) ((_cache[quad] & MASK_EXISTS) == MASK_EXISTS_QUAD)
-#define EXISTS_NONE(quad) ((_cache[quad] & MASK_EXISTS) == 0)
-// The following are only used if _corner_mask is true.
-#define EXISTS_SW_CORNER(quad) ((_cache[quad] & MASK_EXISTS) == MASK_EXISTS_SW_CORNER)
-#define EXISTS_SE_CORNER(quad) ((_cache[quad] & MASK_EXISTS) == MASK_EXISTS_SE_CORNER)
-#define EXISTS_NW_CORNER(quad) ((_cache[quad] & MASK_EXISTS) == MASK_EXISTS_NW_CORNER)
-#define EXISTS_NE_CORNER(quad) ((_cache[quad] & MASK_EXISTS) == MASK_EXISTS_NE_CORNER)
-#define EXISTS_ANY_CORNER(quad) (!EXISTS_NONE(quad) && !EXISTS_QUAD(quad))
-#define EXISTS_W_EDGE(quad) (EXISTS_QUAD(quad) || EXISTS_SW_CORNER(quad) || EXISTS_NW_CORNER(quad))
-#define EXISTS_E_EDGE(quad) (EXISTS_QUAD(quad) || EXISTS_SE_CORNER(quad) || EXISTS_NE_CORNER(quad))
-#define EXISTS_S_EDGE(quad) (EXISTS_QUAD(quad) || EXISTS_SW_CORNER(quad) || EXISTS_SE_CORNER(quad))
-#define EXISTS_N_EDGE(quad) (EXISTS_QUAD(quad) || EXISTS_NW_CORNER(quad) || EXISTS_NE_CORNER(quad))
-// Note that EXISTS_NE_CORNER(quad) is equivalent to BOUNDARY_SW(quad), etc.
-
-
-
-QuadEdge::QuadEdge()
- : quad(-1), edge(Edge_None)
-{}
-
-QuadEdge::QuadEdge(long quad_, Edge edge_)
- : quad(quad_), edge(edge_)
-{}
-
-bool QuadEdge::operator<(const QuadEdge& other) const
-{
- if (quad != other.quad)
- return quad < other.quad;
- else
- return edge < other.edge;
-}
-
-bool QuadEdge::operator==(const QuadEdge& other) const
-{
- return quad == other.quad && edge == other.edge;
-}
-
-bool QuadEdge::operator!=(const QuadEdge& other) const
-{
- return !operator==(other);
-}
-
-std::ostream& operator<<(std::ostream& os, const QuadEdge& quad_edge)
-{
- return os << quad_edge.quad << ' ' << quad_edge.edge;
-}
-
-
-// conflict with code from matplotlib/tri/_tri.cpp
-#if 0
-XY::XY()
-{}
-
-XY::XY(const double& x_, const double& y_)
- : x(x_), y(y_)
-{}
-
-bool XY::operator==(const XY& other) const
-{
- return x == other.x && y == other.y;
-}
-
-bool XY::operator!=(const XY& other) const
-{
- return x != other.x || y != other.y;
-}
-
-XY XY::operator*(const double& multiplier) const
-{
- return XY(x*multiplier, y*multiplier);
-}
-
-const XY& XY::operator+=(const XY& other)
-{
- x += other.x;
- y += other.y;
- return *this;
-}
-
-const XY& XY::operator-=(const XY& other)
-{
- x -= other.x;
- y -= other.y;
- return *this;
-}
-
-XY XY::operator+(const XY& other) const
-{
- return XY(x + other.x, y + other.y);
-}
-
-XY XY::operator-(const XY& other) const
-{
- return XY(x - other.x, y - other.y);
-}
-
-std::ostream& operator<<(std::ostream& os, const XY& xy)
-{
- return os << '(' << xy.x << ' ' << xy.y << ')';
-}
-#endif
-
-
-ContourLine::ContourLine(bool is_hole)
- : std::vector<XY>(),
- _is_hole(is_hole),
- _parent(0)
-{}
-
-void ContourLine::add_child(ContourLine* child)
-{
- assert(!_is_hole && "Cannot add_child to a hole");
- assert(child != 0 && "Null child ContourLine");
- _children.push_back(child);
-}
-
-void ContourLine::clear_parent()
-{
- assert(is_hole() && "Cannot clear parent of non-hole");
- assert(_parent != 0 && "Null parent ContourLine");
- _parent = 0;
-}
-
-const ContourLine::Children& ContourLine::get_children() const
-{
- assert(!_is_hole && "Cannot get_children of a hole");
- return _children;
-}
-
-const ContourLine* ContourLine::get_parent() const
-{
- assert(_is_hole && "Cannot get_parent of a non-hole");
- return _parent;
-}
-
-ContourLine* ContourLine::get_parent()
-{
- assert(_is_hole && "Cannot get_parent of a non-hole");
- return _parent;
-}
-
-bool ContourLine::is_hole() const
-{
- return _is_hole;
-}
-
-// conflict with code from matplotlib/tri/_tri.cpp
-#if 0
-void ContourLine::push_back(const XY& point)
-{
- if (empty() || point != back())
- std::vector<XY>::push_back(point);
-}
-#endif
-
-void ContourLine::set_parent(ContourLine* parent)
-{
- assert(_is_hole && "Cannot set parent of a non-hole");
- assert(parent != 0 && "Null parent ContourLine");
- _parent = parent;
-}
-
-// conflict with code from matplotlib/tri/_tri.cpp
-#if 0
-void ContourLine::write() const
-{
- std::cout << "ContourLine " << this << " of " << size() << " points:";
- for (const_iterator it = begin(); it != end(); ++it)
- std::cout << ' ' << *it;
- if (is_hole())
- std::cout << " hole, parent=" << get_parent();
- else {
- std::cout << " not hole";
- if (!_children.empty()) {
- std::cout << ", children=";
- for (Children::const_iterator it = _children.begin();
- it != _children.end(); ++it)
- std::cout << *it << ' ';
- }
- }
- std::cout << std::endl;
-}
-#endif
-
-
-Contour::Contour()
-{}
-
-Contour::~Contour()
-{
- delete_contour_lines();
-}
-
-void Contour::delete_contour_lines()
-{
- for (iterator line_it = begin(); line_it != end(); ++line_it) {
- delete *line_it;
- *line_it = 0;
- }
- std::vector<ContourLine*>::clear();
-}
-
-void Contour::write() const
-{
- std::cout << "Contour of " << size() << " lines." << std::endl;
- for (const_iterator it = begin(); it != end(); ++it)
- (*it)->write();
-}
-
-
-
-ParentCache::ParentCache(long nx, long x_chunk_points, long y_chunk_points)
- : _nx(nx),
- _x_chunk_points(x_chunk_points),
- _y_chunk_points(y_chunk_points),
- _lines(0), // Initialised when first needed.
- _istart(0),
- _jstart(0)
-{
- assert(_x_chunk_points > 0 && _y_chunk_points > 0 &&
- "Chunk sizes must be positive");
-}
-
-ContourLine* ParentCache::get_parent(long quad)
-{
- long index = quad_to_index(quad);
- ContourLine* parent = _lines[index];
- while (parent == 0) {
- index -= _x_chunk_points;
- assert(index >= 0 && "Failed to find parent in chunk ParentCache");
- parent = _lines[index];
- }
- assert(parent != 0 && "Failed to find parent in chunk ParentCache");
- return parent;
-}
-
-long ParentCache::quad_to_index(long quad) const
-{
- long i = quad % _nx;
- long j = quad / _nx;
- long index = (i-_istart) + (j-_jstart)*_x_chunk_points;
-
- assert(i >= _istart && i < _istart + _x_chunk_points &&
- "i-index outside chunk");
- assert(j >= _jstart && j < _jstart + _y_chunk_points &&
- "j-index outside chunk");
- assert(index >= 0 && index < static_cast<long>(_lines.size()) &&
- "ParentCache index outside chunk");
-
- return index;
-}
-
-void ParentCache::set_chunk_starts(long istart, long jstart)
-{
- assert(istart >= 0 && jstart >= 0 &&
- "Chunk start indices cannot be negative");
- _istart = istart;
- _jstart = jstart;
- if (_lines.empty())
- _lines.resize(_x_chunk_points*_y_chunk_points, 0);
- else
- std::fill(_lines.begin(), _lines.end(), (ContourLine*)0);
-}
-
-void ParentCache::set_parent(long quad, ContourLine& contour_line)
-{
- assert(!_lines.empty() &&
- "Accessing ParentCache before it has been initialised");
- long index = quad_to_index(quad);
- if (_lines[index] == 0)
- _lines[index] = (contour_line.is_hole() ? contour_line.get_parent()
- : &contour_line);
-}
-
-
-
-QuadContourGenerator::QuadContourGenerator(const CoordinateArray& x,
- const CoordinateArray& y,
- const CoordinateArray& z,
- const MaskArray& mask,
- bool corner_mask,
- long chunk_size)
- : _x(x),
- _y(y),
- _z(z),
- _nx(static_cast<long>(_x.dim(1))),
- _ny(static_cast<long>(_x.dim(0))),
- _n(_nx*_ny),
- _corner_mask(corner_mask),
- _chunk_size(chunk_size > 0 ? std::min(chunk_size, std::max(_nx, _ny)-1)
- : std::max(_nx, _ny)-1),
- _nxchunk(calc_chunk_count(_nx)),
- _nychunk(calc_chunk_count(_ny)),
- _chunk_count(_nxchunk*_nychunk),
- _cache(new CacheItem[_n]),
- _parent_cache(_nx,
- chunk_size > 0 ? chunk_size+1 : _nx,
- chunk_size > 0 ? chunk_size+1 : _ny)
-{
- assert(!_x.empty() && !_y.empty() && !_z.empty() && "Empty array");
- assert(_y.dim(0) == _x.dim(0) && _y.dim(1) == _x.dim(1) &&
- "Different-sized y and x arrays");
- assert(_z.dim(0) == _x.dim(0) && _z.dim(1) == _x.dim(1) &&
- "Different-sized z and x arrays");
- assert((mask.empty() ||
- (mask.dim(0) == _x.dim(0) && mask.dim(1) == _x.dim(1))) &&
- "Different-sized mask and x arrays");
-
- init_cache_grid(mask);
-}
-
-QuadContourGenerator::~QuadContourGenerator()
-{
- delete [] _cache;
-}
-
-void QuadContourGenerator::append_contour_line_to_vertices(
- ContourLine& contour_line,
- PyObject* vertices_list) const
-{
- assert(vertices_list != 0 && "Null python vertices_list");
-
- // Convert ContourLine to python equivalent, and clear it.
- npy_intp dims[2] = {static_cast<npy_intp>(contour_line.size()), 2};
- numpy::array_view<double, 2> line(dims);
- npy_intp i = 0;
- for (ContourLine::const_iterator point = contour_line.begin();
- point != contour_line.end(); ++point, ++i) {
- line(i, 0) = point->x;
- line(i, 1) = point->y;
- }
- if (PyList_Append(vertices_list, line.pyobj_steal())) {
- Py_XDECREF(vertices_list);
- throw std::runtime_error("Unable to add contour line to vertices_list");
- }
-
- contour_line.clear();
-}
-
-void QuadContourGenerator::append_contour_to_vertices_and_codes(
- Contour& contour,
- PyObject* vertices_list,
- PyObject* codes_list) const
-{
- assert(vertices_list != 0 && "Null python vertices_list");
- assert(codes_list != 0 && "Null python codes_list");
-
- // Convert Contour to python equivalent, and clear it.
- for (Contour::iterator line_it = contour.begin(); line_it != contour.end();
- ++line_it) {
- ContourLine& line = **line_it;
- if (line.is_hole()) {
- // If hole has already been converted to python its parent will be
- // set to 0 and it can be deleted.
- if (line.get_parent() != 0) {
- delete *line_it;
- *line_it = 0;
- }
- }
- else {
- // Non-holes are converted to python together with their child
- // holes so that they are rendered correctly.
- ContourLine::const_iterator point;
- ContourLine::Children::const_iterator children_it;
-
- const ContourLine::Children& children = line.get_children();
- npy_intp npoints = static_cast<npy_intp>(line.size() + 1);
- for (children_it = children.begin(); children_it != children.end();
- ++children_it)
- npoints += static_cast<npy_intp>((*children_it)->size() + 1);
-
- npy_intp vertices_dims[2] = {npoints, 2};
- numpy::array_view<double, 2> vertices(vertices_dims);
- double* vertices_ptr = vertices.data();
-
- npy_intp codes_dims[1] = {npoints};
- numpy::array_view<unsigned char, 1> codes(codes_dims);
- unsigned char* codes_ptr = codes.data();
-
- for (point = line.begin(); point != line.end(); ++point) {
- *vertices_ptr++ = point->x;
- *vertices_ptr++ = point->y;
- *codes_ptr++ = (point == line.begin() ? MOVETO : LINETO);
- }
- point = line.begin();
- *vertices_ptr++ = point->x;
- *vertices_ptr++ = point->y;
- *codes_ptr++ = CLOSEPOLY;
-
- for (children_it = children.begin(); children_it != children.end();
- ++children_it) {
- ContourLine& child = **children_it;
- for (point = child.begin(); point != child.end(); ++point) {
- *vertices_ptr++ = point->x;
- *vertices_ptr++ = point->y;
- *codes_ptr++ = (point == child.begin() ? MOVETO : LINETO);
- }
- point = child.begin();
- *vertices_ptr++ = point->x;
- *vertices_ptr++ = point->y;
- *codes_ptr++ = CLOSEPOLY;
-
- child.clear_parent(); // To indicate it can be deleted.
- }
-
- if (PyList_Append(vertices_list, vertices.pyobj_steal()) ||
- PyList_Append(codes_list, codes.pyobj_steal())) {
- Py_XDECREF(vertices_list);
- Py_XDECREF(codes_list);
- contour.delete_contour_lines();
- throw std::runtime_error("Unable to add contour line to vertices and codes lists");
- }
-
- delete *line_it;
- *line_it = 0;
- }
- }
-
- // Delete remaining contour lines.
- contour.delete_contour_lines();
-}
-
-long QuadContourGenerator::calc_chunk_count(long point_count) const
-{
- assert(point_count > 0 && "point count must be positive");
- assert(_chunk_size > 0 && "Chunk size must be positive");
-
- if (_chunk_size > 0) {
- long count = (point_count-1) / _chunk_size;
- if (count*_chunk_size < point_count-1)
- ++count;
-
- assert(count >= 1 && "Invalid chunk count");
- return count;
- }
- else
- return 1;
-}
-
-PyObject* QuadContourGenerator::create_contour(const double& level)
-{
- init_cache_levels(level, level);
-
- PyObject* vertices_list = PyList_New(0);
- if (vertices_list == 0)
- throw std::runtime_error("Failed to create Python list");
-
- // Lines that start and end on boundaries.
- long ichunk, jchunk, istart, iend, jstart, jend;
- for (long ijchunk = 0; ijchunk < _chunk_count; ++ijchunk) {
- get_chunk_limits(ijchunk, ichunk, jchunk, istart, iend, jstart, jend);
-
- for (long j = jstart; j < jend; ++j) {
- long quad_end = iend + j*_nx;
- for (long quad = istart + j*_nx; quad < quad_end; ++quad) {
- if (EXISTS_NONE(quad) || VISITED(quad,1)) continue;
-
- if (BOUNDARY_S(quad) && Z_SW >= 1 && Z_SE < 1 &&
- start_line(vertices_list, quad, Edge_S, level)) continue;
-
- if (BOUNDARY_W(quad) && Z_NW >= 1 && Z_SW < 1 &&
- start_line(vertices_list, quad, Edge_W, level)) continue;
-
- if (BOUNDARY_N(quad) && Z_NE >= 1 && Z_NW < 1 &&
- start_line(vertices_list, quad, Edge_N, level)) continue;
-
- if (BOUNDARY_E(quad) && Z_SE >= 1 && Z_NE < 1 &&
- start_line(vertices_list, quad, Edge_E, level)) continue;
-
- if (_corner_mask) {
- // Equates to NE boundary.
- if (EXISTS_SW_CORNER(quad) && Z_SE >= 1 && Z_NW < 1 &&
- start_line(vertices_list, quad, Edge_NE, level)) continue;
-
- // Equates to NW boundary.
- if (EXISTS_SE_CORNER(quad) && Z_NE >= 1 && Z_SW < 1 &&
- start_line(vertices_list, quad, Edge_NW, level)) continue;
-
- // Equates to SE boundary.
- if (EXISTS_NW_CORNER(quad) && Z_SW >= 1 && Z_NE < 1 &&
- start_line(vertices_list, quad, Edge_SE, level)) continue;
-
- // Equates to SW boundary.
- if (EXISTS_NE_CORNER(quad) && Z_NW >= 1 && Z_SE < 1 &&
- start_line(vertices_list, quad, Edge_SW, level)) continue;
- }
- }
- }
- }
-
- // Internal loops.
- ContourLine contour_line(false); // Reused for each contour line.
- for (long ijchunk = 0; ijchunk < _chunk_count; ++ijchunk) {
- get_chunk_limits(ijchunk, ichunk, jchunk, istart, iend, jstart, jend);
-
- for (long j = jstart; j < jend; ++j) {
- long quad_end = iend + j*_nx;
- for (long quad = istart + j*_nx; quad < quad_end; ++quad) {
- if (EXISTS_NONE(quad) || VISITED(quad,1))
- continue;
-
- Edge start_edge = get_start_edge(quad, 1);
- if (start_edge == Edge_None)
- continue;
-
- QuadEdge quad_edge(quad, start_edge);
- QuadEdge start_quad_edge(quad_edge);
-
- // To obtain output identical to that produced by legacy code,
- // sometimes need to ignore the first point and add it on the
- // end instead.
- bool ignore_first = (start_edge == Edge_N);
- follow_interior(contour_line, quad_edge, 1, level,
- !ignore_first, &start_quad_edge, 1, false);
- if (ignore_first && !contour_line.empty())
- contour_line.push_back(contour_line.front());
- append_contour_line_to_vertices(contour_line, vertices_list);
-
- // Repeat if saddle point but not visited.
- if (SADDLE(quad,1) && !VISITED(quad,1))
- --quad;
- }
- }
- }
-
- return vertices_list;
-}
-
-PyObject* QuadContourGenerator::create_filled_contour(const double& lower_level,
- const double& upper_level)
-{
- init_cache_levels(lower_level, upper_level);
-
- Contour contour;
-
- PyObject* vertices = PyList_New(0);
- if (vertices == 0)
- throw std::runtime_error("Failed to create Python list");
-
- PyObject* codes = PyList_New(0);
- if (codes == 0) {
- Py_XDECREF(vertices);
- throw std::runtime_error("Failed to create Python list");
- }
-
- long ichunk, jchunk, istart, iend, jstart, jend;
- for (long ijchunk = 0; ijchunk < _chunk_count; ++ijchunk) {
- get_chunk_limits(ijchunk, ichunk, jchunk, istart, iend, jstart, jend);
- _parent_cache.set_chunk_starts(istart, jstart);
-
- for (long j = jstart; j < jend; ++j) {
- long quad_end = iend + j*_nx;
- for (long quad = istart + j*_nx; quad < quad_end; ++quad) {
- if (!EXISTS_NONE(quad))
- single_quad_filled(contour, quad, lower_level, upper_level);
- }
- }
-
- // Clear VISITED_W and VISITED_S flags that are reused by later chunks.
- if (jchunk < _nychunk-1) {
- long quad_end = iend + jend*_nx;
- for (long quad = istart + jend*_nx; quad < quad_end; ++quad)
- _cache[quad] &= ~MASK_VISITED_S;
- }
-
- if (ichunk < _nxchunk-1) {
- long quad_end = iend + jend*_nx;
- for (long quad = iend + jstart*_nx; quad < quad_end; quad += _nx)
- _cache[quad] &= ~MASK_VISITED_W;
- }
-
- // Create python objects to return for this chunk.
- append_contour_to_vertices_and_codes(contour, vertices, codes);
- }
-
- PyObject* tuple = PyTuple_New(2);
- if (tuple == 0) {
- Py_XDECREF(vertices);
- Py_XDECREF(codes);
- throw std::runtime_error("Failed to create Python tuple");
- }
-
- // No error checking here as filling in a brand new pre-allocated tuple.
- PyTuple_SET_ITEM(tuple, 0, vertices);
- PyTuple_SET_ITEM(tuple, 1, codes);
-
- return tuple;
-}
-
-XY QuadContourGenerator::edge_interp(const QuadEdge& quad_edge,
- const double& level)
-{
- assert(quad_edge.quad >= 0 && quad_edge.quad < _n &&
- "Quad index out of bounds");
- assert(quad_edge.edge != Edge_None && "Invalid edge");
- return interp(get_edge_point_index(quad_edge, true),
- get_edge_point_index(quad_edge, false),
- level);
-}
-
-unsigned int QuadContourGenerator::follow_boundary(
- ContourLine& contour_line,
- QuadEdge& quad_edge,
- const double& lower_level,
- const double& upper_level,
- unsigned int level_index,
- const QuadEdge& start_quad_edge)
-{
- assert(quad_edge.quad >= 0 && quad_edge.quad < _n &&
- "Quad index out of bounds");
- assert(quad_edge.edge != Edge_None && "Invalid edge");
- assert(is_edge_a_boundary(quad_edge) && "Not a boundary edge");
- assert((level_index == 1 || level_index == 2) &&
- "level index must be 1 or 2");
- assert(start_quad_edge.quad >= 0 && start_quad_edge.quad < _n &&
- "Start quad index out of bounds");
- assert(start_quad_edge.edge != Edge_None && "Invalid start edge");
-
- // Only called for filled contours, so always updates _parent_cache.
- unsigned int end_level = 0;
- bool first_edge = true;
- bool stop = false;
- long& quad = quad_edge.quad;
-
- while (true) {
- // Levels of start and end points of quad_edge.
- unsigned int start_level =
- (first_edge ? Z_LEVEL(get_edge_point_index(quad_edge, true))
- : end_level);
- long end_point = get_edge_point_index(quad_edge, false);
- end_level = Z_LEVEL(end_point);
-
- if (level_index == 1) {
- if (start_level <= level_index && end_level == 2) {
- // Increasing z, switching levels from 1 to 2.
- level_index = 2;
- stop = true;
- }
- else if (start_level >= 1 && end_level == 0) {
- // Decreasing z, keeping same level.
- stop = true;
- }
- }
- else { // level_index == 2
- if (start_level <= level_index && end_level == 2) {
- // Increasing z, keeping same level.
- stop = true;
- }
- else if (start_level >= 1 && end_level == 0) {
- // Decreasing z, switching levels from 2 to 1.
- level_index = 1;
- stop = true;
- }
- }
-
- if (!first_edge && !stop && quad_edge == start_quad_edge)
- // Return if reached start point of contour line. Do this before
- // checking/setting VISITED flags as will already have been
- // visited.
- break;
-
- switch (quad_edge.edge) {
- case Edge_E:
- assert(!VISITED_W(quad+1) && "Already visited");
- _cache[quad+1] |= MASK_VISITED_W;
- break;
- case Edge_N:
- assert(!VISITED_S(quad+_nx) && "Already visited");
- _cache[quad+_nx] |= MASK_VISITED_S;
- break;
- case Edge_W:
- assert(!VISITED_W(quad) && "Already visited");
- _cache[quad] |= MASK_VISITED_W;
- break;
- case Edge_S:
- assert(!VISITED_S(quad) && "Already visited");
- _cache[quad] |= MASK_VISITED_S;
- break;
- case Edge_NE:
- case Edge_NW:
- case Edge_SW:
- case Edge_SE:
- assert(!VISITED_CORNER(quad) && "Already visited");
- _cache[quad] |= MASK_VISITED_CORNER;
- break;
- default:
- assert(0 && "Invalid Edge");
- break;
- }
-
- if (stop) {
- // Exiting boundary to enter interior.
- contour_line.push_back(edge_interp(quad_edge,
- level_index == 1 ? lower_level
- : upper_level));
- break;
- }
-
- move_to_next_boundary_edge(quad_edge);
-
- // Just moved to new quad edge, so label parent of start of quad edge.
- switch (quad_edge.edge) {
- case Edge_W:
- case Edge_SW:
- case Edge_S:
- case Edge_SE:
- if (!EXISTS_SE_CORNER(quad))
- _parent_cache.set_parent(quad, contour_line);
- break;
- case Edge_E:
- case Edge_NE:
- case Edge_N:
- case Edge_NW:
- if (!EXISTS_SW_CORNER(quad))
- _parent_cache.set_parent(quad + 1, contour_line);
- break;
- default:
- assert(0 && "Invalid edge");
- break;
- }
-
- // Add point to contour.
- contour_line.push_back(get_point_xy(end_point));
-
- if (first_edge)
- first_edge = false;
- }
-
- return level_index;
-}
-
-void QuadContourGenerator::follow_interior(ContourLine& contour_line,
- QuadEdge& quad_edge,
- unsigned int level_index,
- const double& level,
- bool want_initial_point,
- const QuadEdge* start_quad_edge,
- unsigned int start_level_index,
- bool set_parents)
-{
- assert(quad_edge.quad >= 0 && quad_edge.quad < _n &&
- "Quad index out of bounds.");
- assert(quad_edge.edge != Edge_None && "Invalid edge");
- assert((level_index == 1 || level_index == 2) &&
- "level index must be 1 or 2");
- assert((start_quad_edge == 0 ||
- (start_quad_edge->quad >= 0 && start_quad_edge->quad < _n)) &&
- "Start quad index out of bounds.");
- assert((start_quad_edge == 0 || start_quad_edge->edge != Edge_None) &&
- "Invalid start edge");
- assert((start_level_index == 1 || start_level_index == 2) &&
- "start level index must be 1 or 2");
-
- long& quad = quad_edge.quad;
- Edge& edge = quad_edge.edge;
-
- if (want_initial_point)
- contour_line.push_back(edge_interp(quad_edge, level));
-
- CacheItem visited_mask = (level_index == 1 ? MASK_VISITED_1 : MASK_VISITED_2);
- CacheItem saddle_mask = (level_index == 1 ? MASK_SADDLE_1 : MASK_SADDLE_2);
- Dir dir = Dir_Straight;
-
- while (true) {
- assert(!EXISTS_NONE(quad) && "Quad does not exist");
- assert(!(_cache[quad] & visited_mask) && "Quad already visited");
-
- // Determine direction to move to next quad. If the quad is already
- // labelled as a saddle quad then the direction is easily read from
- // the cache. Otherwise the direction is determined differently
- // depending on whether the quad is a corner quad or not.
-
- if (_cache[quad] & saddle_mask) {
- // Already identified as a saddle quad, so direction is easy.
- dir = (SADDLE_LEFT(quad,level_index) ? Dir_Left : Dir_Right);
- _cache[quad] |= visited_mask;
- }
- else if (EXISTS_ANY_CORNER(quad)) {
- // Need z-level of point opposite the entry edge, as that
- // determines whether contour turns left or right.
- long point_opposite = -1;
- switch (edge) {
- case Edge_E:
- point_opposite = (EXISTS_SE_CORNER(quad) ? POINT_SW
- : POINT_NW);
- break;
- case Edge_N:
- point_opposite = (EXISTS_NW_CORNER(quad) ? POINT_SW
- : POINT_SE);
- break;
- case Edge_W:
- point_opposite = (EXISTS_SW_CORNER(quad) ? POINT_SE
- : POINT_NE);
- break;
- case Edge_S:
- point_opposite = (EXISTS_SW_CORNER(quad) ? POINT_NW
- : POINT_NE);
- break;
- case Edge_NE: point_opposite = POINT_SW; break;
- case Edge_NW: point_opposite = POINT_SE; break;
- case Edge_SW: point_opposite = POINT_NE; break;
- case Edge_SE: point_opposite = POINT_NW; break;
- default: assert(0 && "Invalid edge"); break;
- }
- assert(point_opposite != -1 && "Failed to find opposite point");
-
- // Lower-level polygons (level_index == 1) always have higher
- // values to the left of the contour. Upper-level contours
- // (level_index == 2) are reversed, which is what the fancy XOR
- // does below.
- if ((Z_LEVEL(point_opposite) >= level_index) ^ (level_index == 2))
- dir = Dir_Right;
- else
- dir = Dir_Left;
- _cache[quad] |= visited_mask;
- }
- else {
- // Calculate configuration of this quad.
- long point_left = -1, point_right = -1;
- switch (edge) {
- case Edge_E: point_left = POINT_SW; point_right = POINT_NW; break;
- case Edge_N: point_left = POINT_SE; point_right = POINT_SW; break;
- case Edge_W: point_left = POINT_NE; point_right = POINT_SE; break;
- case Edge_S: point_left = POINT_NW; point_right = POINT_NE; break;
- default: assert(0 && "Invalid edge"); break;
- }
-
- unsigned int config = (Z_LEVEL(point_left) >= level_index) << 1 |
- (Z_LEVEL(point_right) >= level_index);
-
- // Upper level (level_index == 2) polygons are reversed compared to
- // lower level ones, i.e. higher values on the right rather than
- // the left.
- if (level_index == 2)
- config = 3 - config;
-
- // Calculate turn direction to move to next quad along contour line.
- if (config == 1) {
- // New saddle quad, set up cache bits for it.
- double zmid = 0.25*(get_point_z(POINT_SW) +
- get_point_z(POINT_SE) +
- get_point_z(POINT_NW) +
- get_point_z(POINT_NE));
- _cache[quad] |= (level_index == 1 ? MASK_SADDLE_1 : MASK_SADDLE_2);
- if ((zmid > level) ^ (level_index == 2)) {
- dir = Dir_Right;
- }
- else {
- dir = Dir_Left;
- _cache[quad] |= (level_index == 1 ? MASK_SADDLE_LEFT_1
- : MASK_SADDLE_LEFT_2);
- }
- if (edge == Edge_N || edge == Edge_E) {
- // Next visit to this quad must start on S or W.
- _cache[quad] |= (level_index == 1 ? MASK_SADDLE_START_SW_1
- : MASK_SADDLE_START_SW_2);
- }
- }
- else {
- // Normal (non-saddle) quad.
- dir = (config == 0 ? Dir_Left
- : (config == 3 ? Dir_Right : Dir_Straight));
- _cache[quad] |= visited_mask;
- }
- }
-
- // Use dir to determine exit edge.
- edge = get_exit_edge(quad_edge, dir);
-
- if (set_parents) {
- if (edge == Edge_E)
- _parent_cache.set_parent(quad+1, contour_line);
- else if (edge == Edge_W)
- _parent_cache.set_parent(quad, contour_line);
- }
-
- // Add new point to contour line.
- contour_line.push_back(edge_interp(quad_edge, level));
-
- // Stop if reached boundary.
- if (is_edge_a_boundary(quad_edge))
- break;
-
- move_to_next_quad(quad_edge);
- assert(quad_edge.quad >= 0 && quad_edge.quad < _n &&
- "Quad index out of bounds");
-
- // Return if reached start point of contour line.
- if (start_quad_edge != 0 &&
- quad_edge == *start_quad_edge &&
- level_index == start_level_index)
- break;
- }
-}
-
-void QuadContourGenerator::get_chunk_limits(long ijchunk,
- long& ichunk,
- long& jchunk,
- long& istart,
- long& iend,
- long& jstart,
- long& jend)
-{
- assert(ijchunk >= 0 && ijchunk < _chunk_count && "ijchunk out of bounds");
- ichunk = ijchunk % _nxchunk;
- jchunk = ijchunk / _nxchunk;
- istart = ichunk*_chunk_size;
- iend = (ichunk == _nxchunk-1 ? _nx : (ichunk+1)*_chunk_size);
- jstart = jchunk*_chunk_size;
- jend = (jchunk == _nychunk-1 ? _ny : (jchunk+1)*_chunk_size);
-}
-
-Edge QuadContourGenerator::get_corner_start_edge(long quad,
- unsigned int level_index) const
-{
- assert(quad >= 0 && quad < _n && "Quad index out of bounds");
- assert((level_index == 1 || level_index == 2) &&
- "level index must be 1 or 2");
- assert(EXISTS_ANY_CORNER(quad) && "Quad is not a corner");
-
- // Diagram for NE corner. Rotate for other corners.
- //
- // edge12
- // point1 +---------+ point2
- // \ |
- // \ | edge23
- // edge31 \ |
- // \ |
- // + point3
- //
- long point1, point2, point3;
- Edge edge12, edge23, edge31;
- switch (_cache[quad] & MASK_EXISTS) {
- case MASK_EXISTS_SW_CORNER:
- point1 = POINT_SE; point2 = POINT_SW; point3 = POINT_NW;
- edge12 = Edge_S; edge23 = Edge_W; edge31 = Edge_NE;
- break;
- case MASK_EXISTS_SE_CORNER:
- point1 = POINT_NE; point2 = POINT_SE; point3 = POINT_SW;
- edge12 = Edge_E; edge23 = Edge_S; edge31 = Edge_NW;
- break;
- case MASK_EXISTS_NW_CORNER:
- point1 = POINT_SW; point2 = POINT_NW; point3 = POINT_NE;
- edge12 = Edge_W; edge23 = Edge_N; edge31 = Edge_SE;
- break;
- case MASK_EXISTS_NE_CORNER:
- point1 = POINT_NW; point2 = POINT_NE; point3 = POINT_SE;
- edge12 = Edge_N; edge23 = Edge_E; edge31 = Edge_SW;
- break;
- default:
- assert(0 && "Invalid EXISTS for quad");
- return Edge_None;
- }
-
- unsigned int config = (Z_LEVEL(point1) >= level_index) << 2 |
- (Z_LEVEL(point2) >= level_index) << 1 |
- (Z_LEVEL(point3) >= level_index);
-
- // Upper level (level_index == 2) polygons are reversed compared to lower
- // level ones, i.e. higher values on the right rather than the left.
- if (level_index == 2)
- config = 7 - config;
-
- switch (config) {
- case 0: return Edge_None;
- case 1: return edge23;
- case 2: return edge12;
- case 3: return edge12;
- case 4: return edge31;
- case 5: return edge23;
- case 6: return edge31;
- case 7: return Edge_None;
- default: assert(0 && "Invalid config"); return Edge_None;
- }
-}
-
-long QuadContourGenerator::get_edge_point_index(const QuadEdge& quad_edge,
- bool start) const
-{
- assert(quad_edge.quad >= 0 && quad_edge.quad < _n &&
- "Quad index out of bounds");
- assert(quad_edge.edge != Edge_None && "Invalid edge");
-
- // Edges are ordered anticlockwise around their quad, as indicated by
- // directions of arrows in diagrams below.
- // Full quad NW corner (others similar)
- //
- // POINT_NW Edge_N POINT_NE POINT_NW Edge_N POINT_NE
- // +----<-----+ +----<-----+
- // | | | /
- // | | | quad /
- // Edge_W V quad ^ Edge_E Edge_W V ^
- // | | | / Edge_SE
- // | | | /
- // +---->-----+ +
- // POINT_SW Edge_S POINT_SE POINT_SW
- //
- const long& quad = quad_edge.quad;
- switch (quad_edge.edge) {
- case Edge_E: return (start ? POINT_SE : POINT_NE);
- case Edge_N: return (start ? POINT_NE : POINT_NW);
- case Edge_W: return (start ? POINT_NW : POINT_SW);
- case Edge_S: return (start ? POINT_SW : POINT_SE);
- case Edge_NE: return (start ? POINT_SE : POINT_NW);
- case Edge_NW: return (start ? POINT_NE : POINT_SW);
- case Edge_SW: return (start ? POINT_NW : POINT_SE);
- case Edge_SE: return (start ? POINT_SW : POINT_NE);
- default: assert(0 && "Invalid edge"); return 0;
- }
-}
-
-Edge QuadContourGenerator::get_exit_edge(const QuadEdge& quad_edge,
- Dir dir) const
-{
- assert(quad_edge.quad >= 0 && quad_edge.quad < _n &&
- "Quad index out of bounds");
- assert(quad_edge.edge != Edge_None && "Invalid edge");
-
- const long& quad = quad_edge.quad;
- const Edge& edge = quad_edge.edge;
- if (EXISTS_ANY_CORNER(quad)) {
- // Corner directions are always left or right. A corner is a triangle,
- // entered via one edge so the other two edges are the left and right
- // ones.
- switch (edge) {
- case Edge_E:
- return (EXISTS_SE_CORNER(quad)
- ? (dir == Dir_Left ? Edge_S : Edge_NW)
- : (dir == Dir_Right ? Edge_N : Edge_SW));
- case Edge_N:
- return (EXISTS_NW_CORNER(quad)
- ? (dir == Dir_Right ? Edge_W : Edge_SE)
- : (dir == Dir_Left ? Edge_E : Edge_SW));
- case Edge_W:
- return (EXISTS_SW_CORNER(quad)
- ? (dir == Dir_Right ? Edge_S : Edge_NE)
- : (dir == Dir_Left ? Edge_N : Edge_SE));
- case Edge_S:
- return (EXISTS_SW_CORNER(quad)
- ? (dir == Dir_Left ? Edge_W : Edge_NE)
- : (dir == Dir_Right ? Edge_E : Edge_NW));
- case Edge_NE: return (dir == Dir_Left ? Edge_S : Edge_W);
- case Edge_NW: return (dir == Dir_Left ? Edge_E : Edge_S);
- case Edge_SW: return (dir == Dir_Left ? Edge_N : Edge_E);
- case Edge_SE: return (dir == Dir_Left ? Edge_W : Edge_N);
- default: assert(0 && "Invalid edge"); return Edge_None;
- }
- }
- else {
- // A full quad has four edges, entered via one edge so that other three
- // edges correspond to left, straight and right directions.
- switch (edge) {
- case Edge_E:
- return (dir == Dir_Left ? Edge_S :
- (dir == Dir_Right ? Edge_N : Edge_W));
- case Edge_N:
- return (dir == Dir_Left ? Edge_E :
- (dir == Dir_Right ? Edge_W : Edge_S));
- case Edge_W:
- return (dir == Dir_Left ? Edge_N :
- (dir == Dir_Right ? Edge_S : Edge_E));
- case Edge_S:
- return (dir == Dir_Left ? Edge_W :
- (dir == Dir_Right ? Edge_E : Edge_N));
- default: assert(0 && "Invalid edge"); return Edge_None;
- }
- }
-}
-
-XY QuadContourGenerator::get_point_xy(long point) const
-{
- assert(point >= 0 && point < _n && "Point index out of bounds.");
- return XY(_x.data()[static_cast<npy_intp>(point)],
- _y.data()[static_cast<npy_intp>(point)]);
-}
-
-const double& QuadContourGenerator::get_point_z(long point) const
-{
- assert(point >= 0 && point < _n && "Point index out of bounds.");
- return _z.data()[static_cast<npy_intp>(point)];
-}
-
-Edge QuadContourGenerator::get_quad_start_edge(long quad,
- unsigned int level_index) const
-{
- assert(quad >= 0 && quad < _n && "Quad index out of bounds");
- assert((level_index == 1 || level_index == 2) &&
- "level index must be 1 or 2");
- assert(EXISTS_QUAD(quad) && "Quad does not exist");
-
- unsigned int config = (Z_NW >= level_index) << 3 |
- (Z_NE >= level_index) << 2 |
- (Z_SW >= level_index) << 1 |
- (Z_SE >= level_index);
-
- // Upper level (level_index == 2) polygons are reversed compared to lower
- // level ones, i.e. higher values on the right rather than the left.
- if (level_index == 2)
- config = 15 - config;
-
- switch (config) {
- case 0: return Edge_None;
- case 1: return Edge_E;
- case 2: return Edge_S;
- case 3: return Edge_E;
- case 4: return Edge_N;
- case 5: return Edge_N;
- case 6:
- // If already identified as a saddle quad then the start edge is
- // read from the cache. Otherwise return either valid start edge
- // and the subsequent call to follow_interior() will correctly set
- // up saddle bits in cache.
- if (!SADDLE(quad,level_index) || SADDLE_START_SW(quad,level_index))
- return Edge_S;
- else
- return Edge_N;
- case 7: return Edge_N;
- case 8: return Edge_W;
- case 9:
- // See comment for 6 above.
- if (!SADDLE(quad,level_index) || SADDLE_START_SW(quad,level_index))
- return Edge_W;
- else
- return Edge_E;
- case 10: return Edge_S;
- case 11: return Edge_E;
- case 12: return Edge_W;
- case 13: return Edge_W;
- case 14: return Edge_S;
- case 15: return Edge_None;
- default: assert(0 && "Invalid config"); return Edge_None;
- }
-}
-
-Edge QuadContourGenerator::get_start_edge(long quad,
- unsigned int level_index) const
-{
- if (EXISTS_ANY_CORNER(quad))
- return get_corner_start_edge(quad, level_index);
- else
- return get_quad_start_edge(quad, level_index);
-}
-
-void QuadContourGenerator::init_cache_grid(const MaskArray& mask)
-{
- long i, j, quad;
-
- if (mask.empty()) {
- // No mask, easy to calculate quad existence and boundaries together.
- quad = 0;
- for (j = 0; j < _ny; ++j) {
- for (i = 0; i < _nx; ++i, ++quad) {
- _cache[quad] = 0;
-
- if (i < _nx-1 && j < _ny-1)
- _cache[quad] |= MASK_EXISTS_QUAD;
-
- if ((i % _chunk_size == 0 || i == _nx-1) && j < _ny-1)
- _cache[quad] |= MASK_BOUNDARY_W;
-
- if ((j % _chunk_size == 0 || j == _ny-1) && i < _nx-1)
- _cache[quad] |= MASK_BOUNDARY_S;
- }
- }
- }
- else {
- // Casting avoids problem when sizeof(bool) != sizeof(npy_bool).
- const npy_bool* mask_ptr =
- reinterpret_cast<const npy_bool*>(mask.data());
-
- // Have mask so use two stages.
- // Stage 1, determine if quads/corners exist.
- quad = 0;
- for (j = 0; j < _ny; ++j) {
- for (i = 0; i < _nx; ++i, ++quad) {
- _cache[quad] = 0;
-
- if (i < _nx-1 && j < _ny-1) {
- unsigned int config = mask_ptr[POINT_NW] << 3 |
- mask_ptr[POINT_NE] << 2 |
- mask_ptr[POINT_SW] << 1 |
- mask_ptr[POINT_SE];
-
- if (_corner_mask) {
- switch (config) {
- case 0: _cache[quad] = MASK_EXISTS_QUAD; break;
- case 1: _cache[quad] = MASK_EXISTS_NW_CORNER; break;
- case 2: _cache[quad] = MASK_EXISTS_NE_CORNER; break;
- case 4: _cache[quad] = MASK_EXISTS_SW_CORNER; break;
- case 8: _cache[quad] = MASK_EXISTS_SE_CORNER; break;
- default:
- // Do nothing, quad is masked out.
- break;
- }
- }
- else if (config == 0)
- _cache[quad] = MASK_EXISTS_QUAD;
- }
- }
- }
-
- // Stage 2, calculate W and S boundaries. For each quad use boundary
- // data already calculated for quads to W and S, so must iterate
- // through quads in correct order (increasing i and j indices).
- // Cannot use boundary data for quads to E and N as have not yet
- // calculated it.
- quad = 0;
- for (j = 0; j < _ny; ++j) {
- for (i = 0; i < _nx; ++i, ++quad) {
- if (_corner_mask) {
- bool W_exists_none = (i == 0 || EXISTS_NONE(quad-1));
- bool S_exists_none = (j == 0 || EXISTS_NONE(quad-_nx));
- bool W_exists_E_edge = (i > 0 && EXISTS_E_EDGE(quad-1));
- bool S_exists_N_edge = (j > 0 && EXISTS_N_EDGE(quad-_nx));
-
- if ((EXISTS_W_EDGE(quad) && W_exists_none) ||
- (EXISTS_NONE(quad) && W_exists_E_edge) ||
- (i % _chunk_size == 0 && EXISTS_W_EDGE(quad) &&
- W_exists_E_edge))
- _cache[quad] |= MASK_BOUNDARY_W;
-
- if ((EXISTS_S_EDGE(quad) && S_exists_none) ||
- (EXISTS_NONE(quad) && S_exists_N_edge) ||
- (j % _chunk_size == 0 && EXISTS_S_EDGE(quad) &&
- S_exists_N_edge))
- _cache[quad] |= MASK_BOUNDARY_S;
- }
- else {
- bool W_exists_quad = (i > 0 && EXISTS_QUAD(quad-1));
- bool S_exists_quad = (j > 0 && EXISTS_QUAD(quad-_nx));
-
- if ((EXISTS_QUAD(quad) != W_exists_quad) ||
- (i % _chunk_size == 0 && EXISTS_QUAD(quad) &&
- W_exists_quad))
- _cache[quad] |= MASK_BOUNDARY_W;
-
- if ((EXISTS_QUAD(quad) != S_exists_quad) ||
- (j % _chunk_size == 0 && EXISTS_QUAD(quad) &&
- S_exists_quad))
- _cache[quad] |= MASK_BOUNDARY_S;
- }
- }
- }
- }
-}
-
-void QuadContourGenerator::init_cache_levels(const double& lower_level,
- const double& upper_level)
-{
- assert(upper_level >= lower_level &&
- "upper and lower levels are wrong way round");
-
- bool two_levels = (lower_level != upper_level);
- CacheItem keep_mask =
- (_corner_mask ? MASK_EXISTS | MASK_BOUNDARY_S | MASK_BOUNDARY_W
- : MASK_EXISTS_QUAD | MASK_BOUNDARY_S | MASK_BOUNDARY_W);
-
- if (two_levels) {
- const double* z_ptr = _z.data();
- for (long quad = 0; quad < _n; ++quad, ++z_ptr) {
- _cache[quad] &= keep_mask;
- if (*z_ptr > upper_level)
- _cache[quad] |= MASK_Z_LEVEL_2;
- else if (*z_ptr > lower_level)
- _cache[quad] |= MASK_Z_LEVEL_1;
- }
- }
- else {
- const double* z_ptr = _z.data();
- for (long quad = 0; quad < _n; ++quad, ++z_ptr) {
- _cache[quad] &= keep_mask;
- if (*z_ptr > lower_level)
- _cache[quad] |= MASK_Z_LEVEL_1;
- }
- }
-}
-
-XY QuadContourGenerator::interp(
- long point1, long point2, const double& level) const
-{
- assert(point1 >= 0 && point1 < _n && "Point index 1 out of bounds.");
- assert(point2 >= 0 && point2 < _n && "Point index 2 out of bounds.");
- assert(point1 != point2 && "Identical points");
- double fraction = (get_point_z(point2) - level) /
- (get_point_z(point2) - get_point_z(point1));
- return get_point_xy(point1)*fraction + get_point_xy(point2)*(1.0 - fraction);
-}
-
-bool QuadContourGenerator::is_edge_a_boundary(const QuadEdge& quad_edge) const
-{
- assert(quad_edge.quad >= 0 && quad_edge.quad < _n &&
- "Quad index out of bounds");
- assert(quad_edge.edge != Edge_None && "Invalid edge");
-
- switch (quad_edge.edge) {
- case Edge_E: return BOUNDARY_E(quad_edge.quad);
- case Edge_N: return BOUNDARY_N(quad_edge.quad);
- case Edge_W: return BOUNDARY_W(quad_edge.quad);
- case Edge_S: return BOUNDARY_S(quad_edge.quad);
- case Edge_NE: return EXISTS_SW_CORNER(quad_edge.quad);
- case Edge_NW: return EXISTS_SE_CORNER(quad_edge.quad);
- case Edge_SW: return EXISTS_NE_CORNER(quad_edge.quad);
- case Edge_SE: return EXISTS_NW_CORNER(quad_edge.quad);
- default: assert(0 && "Invalid edge"); return true;
- }
-}
-
-void QuadContourGenerator::move_to_next_boundary_edge(QuadEdge& quad_edge) const
-{
- assert(is_edge_a_boundary(quad_edge) && "QuadEdge is not a boundary");
-
- long& quad = quad_edge.quad;
- Edge& edge = quad_edge.edge;
-
- quad = get_edge_point_index(quad_edge, false);
-
- // quad is now such that POINT_SW is the end point of the quad_edge passed
- // to this function.
-
- // To find the next boundary edge, first attempt to turn left 135 degrees
- // and if that edge is a boundary then move to it. If not, attempt to turn
- // left 90 degrees, then left 45 degrees, then straight on, etc, until can
- // move.
- // First determine which edge to attempt first.
- int index = 0;
- switch (edge) {
- case Edge_E: index = 0; break;
- case Edge_SE: index = 1; break;
- case Edge_S: index = 2; break;
- case Edge_SW: index = 3; break;
- case Edge_W: index = 4; break;
- case Edge_NW: index = 5; break;
- case Edge_N: index = 6; break;
- case Edge_NE: index = 7; break;
- default: assert(0 && "Invalid edge"); break;
- }
-
- // If _corner_mask not set, only need to consider odd index in loop below.
- if (!_corner_mask)
- ++index;
-
- // Try each edge in turn until a boundary is found.
- int start_index = index;
- do
- {
- switch (index) {
- case 0:
- if (EXISTS_SE_CORNER(quad-_nx-1)) { // Equivalent to BOUNDARY_NW
- quad -= _nx+1;
- edge = Edge_NW;
- return;
- }
- break;
- case 1:
- if (BOUNDARY_N(quad-_nx-1)) {
- quad -= _nx+1;
- edge = Edge_N;
- return;
- }
- break;
- case 2:
- if (EXISTS_SW_CORNER(quad-1)) { // Equivalent to BOUNDARY_NE
- quad -= 1;
- edge = Edge_NE;
- return;
- }
- break;
- case 3:
- if (BOUNDARY_E(quad-1)) {
- quad -= 1;
- edge = Edge_E;
- return;
- }
- break;
- case 4:
- if (EXISTS_NW_CORNER(quad)) { // Equivalent to BOUNDARY_SE
- edge = Edge_SE;
- return;
- }
- break;
- case 5:
- if (BOUNDARY_S(quad)) {
- edge = Edge_S;
- return;
- }
- break;
- case 6:
- if (EXISTS_NE_CORNER(quad-_nx)) { // Equivalent to BOUNDARY_SW
- quad -= _nx;
- edge = Edge_SW;
- return;
- }
- break;
- case 7:
- if (BOUNDARY_W(quad-_nx)) {
- quad -= _nx;
- edge = Edge_W;
- return;
- }
- break;
- default: assert(0 && "Invalid index"); break;
- }
-
- if (_corner_mask)
- index = (index + 1) % 8;
- else
- index = (index + 2) % 8;
- } while (index != start_index);
-
- assert(0 && "Failed to find next boundary edge");
-}
-
-void QuadContourGenerator::move_to_next_quad(QuadEdge& quad_edge) const
-{
- assert(quad_edge.quad >= 0 && quad_edge.quad < _n &&
- "Quad index out of bounds");
- assert(quad_edge.edge != Edge_None && "Invalid edge");
-
- // Move from quad_edge.quad to the neighbouring quad in the direction
- // specified by quad_edge.edge.
- switch (quad_edge.edge) {
- case Edge_E: quad_edge.quad += 1; quad_edge.edge = Edge_W; break;
- case Edge_N: quad_edge.quad += _nx; quad_edge.edge = Edge_S; break;
- case Edge_W: quad_edge.quad -= 1; quad_edge.edge = Edge_E; break;
- case Edge_S: quad_edge.quad -= _nx; quad_edge.edge = Edge_N; break;
- default: assert(0 && "Invalid edge"); break;
- }
-}
-
-void QuadContourGenerator::single_quad_filled(Contour& contour,
- long quad,
- const double& lower_level,
- const double& upper_level)
-{
- assert(quad >= 0 && quad < _n && "Quad index out of bounds");
-
- // Order of checking is important here as can have different ContourLines
- // from both lower and upper levels in the same quad. First check the S
- // edge, then move up the quad to the N edge checking as required.
-
- // Possible starts from S boundary.
- if (BOUNDARY_S(quad) && EXISTS_S_EDGE(quad)) {
-
- // Lower-level start from S boundary into interior.
- if (!VISITED_S(quad) && Z_SW >= 1 && Z_SE == 0)
- contour.push_back(start_filled(quad, Edge_S, 1, NotHole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from S boundary into interior.
- if (!VISITED_S(quad) && Z_SW < 2 && Z_SE == 2)
- contour.push_back(start_filled(quad, Edge_S, 2, NotHole, Interior,
- lower_level, upper_level));
-
- // Lower-level start following S boundary from W to E.
- if (!VISITED_S(quad) && Z_SW <= 1 && Z_SE == 1)
- contour.push_back(start_filled(quad, Edge_S, 1, NotHole, Boundary,
- lower_level, upper_level));
-
- // Upper-level start following S boundary from W to E.
- if (!VISITED_S(quad) && Z_SW == 2 && Z_SE == 1)
- contour.push_back(start_filled(quad, Edge_S, 2, NotHole, Boundary,
- lower_level, upper_level));
- }
-
- // Possible starts from W boundary.
- if (BOUNDARY_W(quad) && EXISTS_W_EDGE(quad)) {
-
- // Lower-level start from W boundary into interior.
- if (!VISITED_W(quad) && Z_NW >= 1 && Z_SW == 0)
- contour.push_back(start_filled(quad, Edge_W, 1, NotHole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from W boundary into interior.
- if (!VISITED_W(quad) && Z_NW < 2 && Z_SW == 2)
- contour.push_back(start_filled(quad, Edge_W, 2, NotHole, Interior,
- lower_level, upper_level));
-
- // Lower-level start following W boundary from N to S.
- if (!VISITED_W(quad) && Z_NW <= 1 && Z_SW == 1)
- contour.push_back(start_filled(quad, Edge_W, 1, NotHole, Boundary,
- lower_level, upper_level));
-
- // Upper-level start following W boundary from N to S.
- if (!VISITED_W(quad) && Z_NW == 2 && Z_SW == 1)
- contour.push_back(start_filled(quad, Edge_W, 2, NotHole, Boundary,
- lower_level, upper_level));
- }
-
- // Possible starts from NE boundary.
- if (EXISTS_SW_CORNER(quad)) { // i.e. BOUNDARY_NE
-
- // Lower-level start following NE boundary from SE to NW, hole.
- if (!VISITED_CORNER(quad) && Z_NW == 1 && Z_SE == 1)
- contour.push_back(start_filled(quad, Edge_NE, 1, Hole, Boundary,
- lower_level, upper_level));
- }
- // Possible starts from SE boundary.
- else if (EXISTS_NW_CORNER(quad)) { // i.e. BOUNDARY_SE
-
- // Lower-level start from N to SE.
- if (!VISITED(quad,1) && Z_NW == 0 && Z_SW == 0 && Z_NE >= 1)
- contour.push_back(start_filled(quad, Edge_N, 1, NotHole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from SE to N, hole.
- if (!VISITED(quad,2) && Z_NW < 2 && Z_SW < 2 && Z_NE == 2)
- contour.push_back(start_filled(quad, Edge_SE, 2, Hole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from N to SE.
- if (!VISITED(quad,2) && Z_NW == 2 && Z_SW == 2 && Z_NE < 2)
- contour.push_back(start_filled(quad, Edge_N, 2, NotHole, Interior,
- lower_level, upper_level));
-
- // Lower-level start from SE to N, hole.
- if (!VISITED(quad,1) && Z_NW >= 1 && Z_SW >= 1 && Z_NE == 0)
- contour.push_back(start_filled(quad, Edge_SE, 1, Hole, Interior,
- lower_level, upper_level));
- }
- // Possible starts from NW boundary.
- else if (EXISTS_SE_CORNER(quad)) { // i.e. BOUNDARY_NW
-
- // Lower-level start from NW to E.
- if (!VISITED(quad,1) && Z_SW == 0 && Z_SE == 0 && Z_NE >= 1)
- contour.push_back(start_filled(quad, Edge_NW, 1, NotHole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from E to NW, hole.
- if (!VISITED(quad,2) && Z_SW < 2 && Z_SE < 2 && Z_NE == 2)
- contour.push_back(start_filled(quad, Edge_E, 2, Hole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from NW to E.
- if (!VISITED(quad,2) && Z_SW == 2 && Z_SE == 2 && Z_NE < 2)
- contour.push_back(start_filled(quad, Edge_NW, 2, NotHole, Interior,
- lower_level, upper_level));
-
- // Lower-level start from E to NW, hole.
- if (!VISITED(quad,1) && Z_SW >= 1 && Z_SE >= 1 && Z_NE == 0)
- contour.push_back(start_filled(quad, Edge_E, 1, Hole, Interior,
- lower_level, upper_level));
- }
- // Possible starts from SW boundary.
- else if (EXISTS_NE_CORNER(quad)) { // i.e. BOUNDARY_SW
-
- // Lower-level start from SW boundary into interior.
- if (!VISITED_CORNER(quad) && Z_NW >= 1 && Z_SE == 0)
- contour.push_back(start_filled(quad, Edge_SW, 1, NotHole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from SW boundary into interior.
- if (!VISITED_CORNER(quad) && Z_NW < 2 && Z_SE == 2)
- contour.push_back(start_filled(quad, Edge_SW, 2, NotHole, Interior,
- lower_level, upper_level));
-
- // Lower-level start following SW boundary from NW to SE.
- if (!VISITED_CORNER(quad) && Z_NW <= 1 && Z_SE == 1)
- contour.push_back(start_filled(quad, Edge_SW, 1, NotHole, Boundary,
- lower_level, upper_level));
-
- // Upper-level start following SW boundary from NW to SE.
- if (!VISITED_CORNER(quad) && Z_NW == 2 && Z_SE == 1)
- contour.push_back(start_filled(quad, Edge_SW, 2, NotHole, Boundary,
- lower_level, upper_level));
- }
-
- // A full (unmasked) quad can only have a start on the NE corner, i.e. from
- // N to E (lower level) or E to N (upper level). Any other start will have
- // already been created in a call to this function for a prior quad so we
- // don't need to test for it again here.
- //
- // The situation is complicated by the possibility that the quad is a
- // saddle quad, in which case a contour line starting on the N could leave
- // by either the W or the E. We only need to consider those leaving E.
- //
- // A NE corner can also have a N to E or E to N start.
- if (EXISTS_QUAD(quad) || EXISTS_NE_CORNER(quad)) {
-
- // Lower-level start from N to E.
- if (!VISITED(quad,1) && Z_NW == 0 && Z_SE == 0 && Z_NE >= 1 &&
- (!SADDLE(quad,1) || SADDLE_LEFT(quad,1)))
- contour.push_back(start_filled(quad, Edge_N, 1, NotHole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from E to N, hole.
- if (!VISITED(quad,2) && Z_NW < 2 && Z_SE < 2 && Z_NE == 2 &&
- (!SADDLE(quad,2) || !SADDLE_LEFT(quad,2)))
- contour.push_back(start_filled(quad, Edge_E, 2, Hole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from N to E.
- if (!VISITED(quad,2) && Z_NW == 2 && Z_SE == 2 && Z_NE < 2 &&
- (!SADDLE(quad,2) || SADDLE_LEFT(quad,2)))
- contour.push_back(start_filled(quad, Edge_N, 2, NotHole, Interior,
- lower_level, upper_level));
-
- // Lower-level start from E to N, hole.
- if (!VISITED(quad,1) && Z_NW >= 1 && Z_SE >= 1 && Z_NE == 0 &&
- (!SADDLE(quad,1) || !SADDLE_LEFT(quad,1)))
- contour.push_back(start_filled(quad, Edge_E, 1, Hole, Interior,
- lower_level, upper_level));
-
- // All possible contours passing through the interior of this quad
- // should have already been created, so assert this.
- assert((VISITED(quad,1) || get_start_edge(quad, 1) == Edge_None) &&
- "Found start of contour that should have already been created");
- assert((VISITED(quad,2) || get_start_edge(quad, 2) == Edge_None) &&
- "Found start of contour that should have already been created");
- }
-
- // Lower-level start following N boundary from E to W, hole.
- // This is required for an internal masked region which is a hole in a
- // surrounding contour line.
- if (BOUNDARY_N(quad) && EXISTS_N_EDGE(quad) &&
- !VISITED_S(quad+_nx) && Z_NW == 1 && Z_NE == 1)
- contour.push_back(start_filled(quad, Edge_N, 1, Hole, Boundary,
- lower_level, upper_level));
-}
-
-ContourLine* QuadContourGenerator::start_filled(
- long quad,
- Edge edge,
- unsigned int start_level_index,
- HoleOrNot hole_or_not,
- BoundaryOrInterior boundary_or_interior,
- const double& lower_level,
- const double& upper_level)
-{
- assert(quad >= 0 && quad < _n && "Quad index out of bounds");
- assert(edge != Edge_None && "Invalid edge");
- assert((start_level_index == 1 || start_level_index == 2) &&
- "start level index must be 1 or 2");
-
- ContourLine* contour_line = new ContourLine(hole_or_not == Hole);
- if (hole_or_not == Hole) {
- // Find and set parent ContourLine.
- ContourLine* parent = _parent_cache.get_parent(quad + 1);
- assert(parent != 0 && "Failed to find parent ContourLine");
- contour_line->set_parent(parent);
- parent->add_child(contour_line);
- }
-
- QuadEdge quad_edge(quad, edge);
- const QuadEdge start_quad_edge(quad_edge);
- unsigned int level_index = start_level_index;
-
- // If starts on interior, can only finish on interior.
- // If starts on boundary, can only finish on boundary.
-
- while (true) {
- if (boundary_or_interior == Interior) {
- double level = (level_index == 1 ? lower_level : upper_level);
- follow_interior(*contour_line, quad_edge, level_index, level,
- false, &start_quad_edge, start_level_index, true);
- }
- else {
- level_index = follow_boundary(
- *contour_line, quad_edge, lower_level,
- upper_level, level_index, start_quad_edge);
- }
-
- if (quad_edge == start_quad_edge && (boundary_or_interior == Boundary ||
- level_index == start_level_index))
- break;
-
- if (boundary_or_interior == Boundary)
- boundary_or_interior = Interior;
- else
- boundary_or_interior = Boundary;
- }
-
- return contour_line;
-}
-
-bool QuadContourGenerator::start_line(
- PyObject* vertices_list, long quad, Edge edge, const double& level)
-{
- assert(vertices_list != 0 && "Null python vertices list");
- assert(is_edge_a_boundary(QuadEdge(quad, edge)) &&
- "QuadEdge is not a boundary");
-
- QuadEdge quad_edge(quad, edge);
- ContourLine contour_line(false);
- follow_interior(contour_line, quad_edge, 1, level, true, 0, 1, false);
- append_contour_line_to_vertices(contour_line, vertices_list);
- return VISITED(quad,1);
-}
-
-void QuadContourGenerator::write_cache(bool grid_only) const
-{
- std::cout << "-----------------------------------------------" << std::endl;
- for (long quad = 0; quad < _n; ++quad)
- write_cache_quad(quad, grid_only);
- std::cout << "-----------------------------------------------" << std::endl;
-}
-
-void QuadContourGenerator::write_cache_quad(long quad, bool grid_only) const
-{
- long j = quad / _nx;
- long i = quad - j*_nx;
- std::cout << quad << ": i=" << i << " j=" << j
- << " EXISTS=" << EXISTS_QUAD(quad);
- if (_corner_mask)
- std::cout << " CORNER=" << EXISTS_SW_CORNER(quad) << EXISTS_SE_CORNER(quad)
- << EXISTS_NW_CORNER(quad) << EXISTS_NE_CORNER(quad);
- std::cout << " BNDY=" << (BOUNDARY_S(quad)>0) << (BOUNDARY_W(quad)>0);
- if (!grid_only) {
- std::cout << " Z=" << Z_LEVEL(quad)
- << " SAD=" << (SADDLE(quad,1)>0) << (SADDLE(quad,2)>0)
- << " LEFT=" << (SADDLE_LEFT(quad,1)>0) << (SADDLE_LEFT(quad,2)>0)
- << " NW=" << (SADDLE_START_SW(quad,1)>0) << (SADDLE_START_SW(quad,2)>0)
- << " VIS=" << (VISITED(quad,1)>0) << (VISITED(quad,2)>0)
- << (VISITED_S(quad)>0) << (VISITED_W(quad)>0)
- << (VISITED_CORNER(quad)>0);
- }
- std::cout << std::endl;
-}
diff --git a/contrib/python/matplotlib/py2/src/_contour.h b/contrib/python/matplotlib/py2/src/_contour.h
deleted file mode 100644
index e01c3bc732..0000000000
--- a/contrib/python/matplotlib/py2/src/_contour.h
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * QuadContourGenerator
- * --------------------
- * A QuadContourGenerator generates contours for scalar fields defined on
- * quadrilateral grids. A single QuadContourGenerator object can create both
- * line contours (at single levels) and filled contours (between pairs of
- * levels) for the same field.
- *
- * A field to be contoured has nx, ny points in the x- and y-directions
- * respectively. The quad grid is defined by x and y arrays of shape(ny, nx),
- * and the field itself is the z array also of shape(ny, nx). There is an
- * optional boolean mask; if it exists then it also has shape(ny, nx). The
- * mask applies to grid points rather than quads.
- *
- * How quads are masked based on the point mask is determined by the boolean
- * 'corner_mask' flag. If false then any quad that has one or more of its four
- * corner points masked is itself masked. If true the behaviour is the same
- * except that any quad which has exactly one of its four corner points masked
- * has only the triangular corner (half of the quad) adjacent to that point
- * masked; the opposite triangular corner has three unmasked points and is not
- * masked.
- *
- * By default the entire domain of nx*ny points is contoured together which can
- * result in some very long polygons. The alternative is to break up the
- * domain into subdomains or 'chunks' of smaller size, each of which is
- * independently contoured. The size of these chunks is controlled by the
- * 'nchunk' (or 'chunk_size') parameter. Chunking not only results in shorter
- * polygons but also requires slightly less RAM. It can result in rendering
- * artifacts though, depending on backend, antialiased flag and alpha value.
- *
- * Notation
- * --------
- * i and j are array indices in the x- and y-directions respectively. Although
- * a single element of an array z can be accessed using z[j][i] or z(j,i), it
- * is often convenient to use the single quad index z[quad], where
- * quad = i + j*nx
- * and hence
- * i = quad % nx
- * j = quad / nx
- *
- * Rather than referring to x- and y-directions, compass directions are used
- * instead such that W, E, S, N refer to the -x, +x, -y, +y directions
- * respectively. To move one quad to the E you would therefore add 1 to the
- * quad index, to move one quad to the N you would add nx to the quad index.
- *
- * Cache
- * -----
- * Lots of information that is reused during contouring is stored as single
- * bits in a mesh-sized cache, indexed by quad. Each quad's cache entry stores
- * information about the quad itself such as if it is masked, and about the
- * point at the SW corner of the quad, and about the W and S edges. Hence
- * information about each point and each edge is only stored once in the cache.
- *
- * Cache information is divided into two types: that which is constant over the
- * lifetime of the QuadContourGenerator, and that which changes for each
- * contouring operation. The former is all grid-specific information such
- * as quad and corner masks, and which edges are boundaries, either between
- * masked and non-masked regions or between adjacent chunks. The latter
- * includes whether points lie above or below the current contour levels, plus
- * some flags to indicate how the contouring is progressing.
- *
- * Line Contours
- * -------------
- * A line contour connects points with the same z-value. Each point of such a
- * contour occurs on an edge of the grid, at a point linearly interpolated to
- * the contour z-level from the z-values at the end points of the edge. The
- * direction of a line contour is such that higher values are to the left of
- * the contour, so any edge that the contour passes through will have a left-
- * hand end point with z > contour level and a right-hand end point with
- * z <= contour level.
- *
- * Line contours are of two types. Firstly there are open line strips that
- * start on a boundary, traverse the interior of the domain and end on a
- * boundary. Secondly there are closed line loops that occur completely within
- * the interior of the domain and do not touch a boundary.
- *
- * The QuadContourGenerator makes two sweeps through the grid to generate line
- * contours for a particular level. In the first sweep it looks only for start
- * points that occur on boundaries, and when it finds one it follows the
- * contour through the interior until it finishes on another boundary edge.
- * Each quad that is visited by the algorithm has a 'visited' flag set in the
- * cache to indicate that the quad does not need to be visited again. In the
- * second sweep all non-visited quads are checked to see if they contain part
- * of an interior closed loop, and again each time one is found it is followed
- * through the domain interior until it returns back to its start quad and is
- * therefore completed.
- *
- * The situation is complicated by saddle quads that have two opposite corners
- * with z >= contour level and the other two corners with z < contour level.
- * These therefore contain two segments of a line contour, and the visited
- * flags take account of this by only being set on the second visit. On the
- * first visit a number of saddle flags are set in the cache to indicate which
- * one of the two segments has been completed so far.
- *
- * Filled Contours
- * ---------------
- * Filled contours are produced between two contour levels and are always
- * closed polygons. They can occur completely within the interior of the
- * domain without touching a boundary, following either the lower or upper
- * contour levels. Those on the lower level are exactly like interior line
- * contours with higher values on the left. Those on the upper level are
- * reversed such that higher values are on the right.
- *
- * Filled contours can also involve a boundary in which case they consist of
- * one or more sections along a boundary and one or more sections through the
- * interior. Interior sections can be on either level, and again those on the
- * upper level have higher values on the right. Boundary sections can remain
- * on either contour level or switch between the two.
- *
- * Once the start of a filled contour is found, the algorithm is similar to
- * that for line contours in that it follows the contour to its end, which
- * because filled contours are always closed polygons will be by returning
- * back to the start. However, because two levels must be considered, each
- * level has its own set of saddle and visited flags and indeed some extra
- * visited flags for boundary edges.
- *
- * The major complication for filled contours is that some polygons can be
- * holes (with points ordered clockwise) within other polygons (with points
- * ordered anticlockwise). When it comes to rendering filled contours each
- * non-hole polygon must be rendered along with its zero or more contained
- * holes or the rendering will not be correct. The filled contour finding
- * algorithm could progress pretty much as the line contour algorithm does,
- * taking each polygon as it is found, but then at the end there would have to
- * be an extra step to identify the parent non-hole polygon for each hole.
- * This is not a particularly onerous task but it does not scale well and can
- * easily dominate the execution time of the contour finding for even modest
- * problems. It is much better to identity each hole's parent non-hole during
- * the sweep algorithm.
- *
- * This requirement dictates the order that filled contours are identified. As
- * the algorithm sweeps up through the grid, every time a polygon passes
- * through a quad a ParentCache object is updated with the new possible parent.
- * When a new hole polygon is started, the ParentCache is used to find the
- * first possible parent in the same quad or to the S of it. Great care is
- * needed each time a new quad is checked to see if a new polygon should be
- * started, as a single quad can have multiple polygon starts, e.g. a quad
- * could be a saddle quad for both lower and upper contour levels, meaning it
- * has four contour line segments passing through it which could all be from
- * different polygons. The S-most polygon must be started first, then the next
- * S-most and so on until the N-most polygon is started in that quad.
- */
-#ifndef _CONTOUR_H
-#define _CONTOUR_H
-
-#include "src/numpy_cpp.h"
-#include <stdint.h>
-#include <list>
-#include <iostream>
-#include <vector>
-
-
-// Edge of a quad including diagonal edges of masked quads if _corner_mask true.
-typedef enum
-{
- // Listing values here so easier to check for debug purposes.
- Edge_None = -1,
- Edge_E = 0,
- Edge_N = 1,
- Edge_W = 2,
- Edge_S = 3,
- // The following are only used if _corner_mask is true.
- Edge_NE = 4,
- Edge_NW = 5,
- Edge_SW = 6,
- Edge_SE = 7
-} Edge;
-
-// Combination of a quad and an edge of that quad.
-// An invalid quad edge has quad of -1.
-struct QuadEdge
-{
- QuadEdge();
- QuadEdge(long quad_, Edge edge_);
- bool operator<(const QuadEdge& other) const;
- bool operator==(const QuadEdge& other) const;
- bool operator!=(const QuadEdge& other) const;
- friend std::ostream& operator<<(std::ostream& os,
- const QuadEdge& quad_edge);
-
- long quad;
- Edge edge;
-};
-
-// 2D point with x,y coordinates.
-struct XY
-{
- XY();
- XY(const double& x_, const double& y_);
- bool operator==(const XY& other) const;
- bool operator!=(const XY& other) const;
- XY operator*(const double& multiplier) const;
- const XY& operator+=(const XY& other);
- const XY& operator-=(const XY& other);
- XY operator+(const XY& other) const;
- XY operator-(const XY& other) const;
- friend std::ostream& operator<<(std::ostream& os, const XY& xy);
-
- double x, y;
-};
-
-// A single line of a contour, which may be a closed line loop or an open line
-// strip. Identical adjacent points are avoided using push_back().
-// A ContourLine is either a hole (points ordered clockwise) or it is not
-// (points ordered anticlockwise). Each hole has a parent ContourLine that is
-// not a hole; each non-hole contains zero or more child holes. A non-hole and
-// its child holes must be rendered together to obtain the correct results.
-class ContourLine : public std::vector<XY>
-{
-public:
- typedef std::list<ContourLine*> Children;
-
- ContourLine(bool is_hole);
- void add_child(ContourLine* child);
- void clear_parent();
- const Children& get_children() const;
- const ContourLine* get_parent() const;
- ContourLine* get_parent();
- bool is_hole() const;
- void push_back(const XY& point);
- void set_parent(ContourLine* parent);
- void write() const;
-
-private:
- bool _is_hole;
- ContourLine* _parent; // Only set if is_hole, not owned.
- Children _children; // Only set if !is_hole, not owned.
-};
-
-
-// A Contour is a collection of zero or more ContourLines.
-class Contour : public std::vector<ContourLine*>
-{
-public:
- Contour();
- virtual ~Contour();
- void delete_contour_lines();
- void write() const;
-};
-
-
-// Single chunk of ContourLine parents, indexed by quad. As a chunk's filled
-// contours are created, the ParentCache is updated each time a ContourLine
-// passes through each quad. When a new ContourLine is created, if it is a
-// hole its parent ContourLine is read from the ParentCache by looking at the
-// start quad, then each quad to the S in turn until a non-zero ContourLine is
-// found.
-class ParentCache
-{
-public:
- ParentCache(long nx, long x_chunk_points, long y_chunk_points);
- ContourLine* get_parent(long quad);
- void set_chunk_starts(long istart, long jstart);
- void set_parent(long quad, ContourLine& contour_line);
-
-private:
- long quad_to_index(long quad) const;
-
- long _nx;
- long _x_chunk_points, _y_chunk_points; // Number of points not quads.
- std::vector<ContourLine*> _lines; // Not owned.
- long _istart, _jstart;
-};
-
-
-// See overview of algorithm at top of file.
-class QuadContourGenerator
-{
-public:
- typedef numpy::array_view<const double, 2> CoordinateArray;
- typedef numpy::array_view<const bool, 2> MaskArray;
-
- // Constructor with optional mask.
- // x, y, z: double arrays of shape (ny,nx).
- // mask: boolean array, ether empty (if no mask), or of shape (ny,nx).
- // corner_mask: flag for different masking behaviour.
- // chunk_size: 0 for no chunking, or +ve integer for size of chunks that
- // the domain is subdivided into.
- QuadContourGenerator(const CoordinateArray& x,
- const CoordinateArray& y,
- const CoordinateArray& z,
- const MaskArray& mask,
- bool corner_mask,
- long chunk_size);
-
- // Destructor.
- ~QuadContourGenerator();
-
- // Create and return polygons for a line (i.e. non-filled) contour at the
- // specified level.
- PyObject* create_contour(const double& level);
-
- // Create and return polygons for a filled contour between the two
- // specified levels.
- PyObject* create_filled_contour(const double& lower_level,
- const double& upper_level);
-
-private:
- // Typedef for following either a boundary of the domain or the interior;
- // clearer than using a boolean.
- typedef enum
- {
- Boundary,
- Interior
- } BoundaryOrInterior;
-
- // Typedef for direction of movement from one quad to the next.
- typedef enum
- {
- Dir_Right = -1,
- Dir_Straight = 0,
- Dir_Left = +1
- } Dir;
-
- // Typedef for a polygon being a hole or not; clearer than using a boolean.
- typedef enum
- {
- NotHole,
- Hole
- } HoleOrNot;
-
- // Append a C++ ContourLine to the end of a python list. Used for line
- // contours where each ContourLine is converted to a separate numpy array
- // of (x,y) points.
- // Clears the ContourLine too.
- void append_contour_line_to_vertices(ContourLine& contour_line,
- PyObject* vertices_list) const;
-
- // Append a C++ Contour to the end of two python lists. Used for filled
- // contours where each non-hole ContourLine and its child holes are
- // represented by a numpy array of (x,y) points and a second numpy array of
- // 'kinds' or 'codes' that indicates where the points array is split into
- // individual polygons.
- // Clears the Contour too, freeing each ContourLine as soon as possible
- // for minimum RAM usage.
- void append_contour_to_vertices_and_codes(Contour& contour,
- PyObject* vertices_list,
- PyObject* codes_list) const;
-
- // Return number of chunks that fit in the specified point_count.
- long calc_chunk_count(long point_count) const;
-
- // Return the point on the specified QuadEdge that intersects the specified
- // level.
- XY edge_interp(const QuadEdge& quad_edge, const double& level);
-
- // Follow a contour along a boundary, appending points to the ContourLine
- // as it progresses. Only called for filled contours. Stops when the
- // contour leaves the boundary to move into the interior of the domain, or
- // when the start_quad_edge is reached in which case the ContourLine is a
- // completed closed loop. Always adds the end point of each boundary edge
- // to the ContourLine, regardless of whether moving to another boundary
- // edge or leaving the boundary into the interior. Never adds the start
- // point of the first boundary edge to the ContourLine.
- // contour_line: ContourLine to append points to.
- // quad_edge: on entry the QuadEdge to start from, on exit the QuadEdge
- // that is stopped on.
- // lower_level: lower contour z-value.
- // upper_level: upper contour z-value.
- // level_index: level index started on (1 = lower, 2 = upper level).
- // start_quad_edge: QuadEdge that the ContourLine started from, which is
- // used to check if the ContourLine is finished.
- // Returns the end level_index.
- unsigned int follow_boundary(ContourLine& contour_line,
- QuadEdge& quad_edge,
- const double& lower_level,
- const double& upper_level,
- unsigned int level_index,
- const QuadEdge& start_quad_edge);
-
- // Follow a contour across the interior of the domain, appending points to
- // the ContourLine as it progresses. Called for both line and filled
- // contours. Stops when the contour reaches a boundary or, if the
- // start_quad_edge is specified, when quad_edge == start_quad_edge and
- // level_index == start_level_index. Always adds the end point of each
- // quad traversed to the ContourLine; only adds the start point of the
- // first quad if want_initial_point flag is true.
- // contour_line: ContourLine to append points to.
- // quad_edge: on entry the QuadEdge to start from, on exit the QuadEdge
- // that is stopped on.
- // level_index: level index started on (1 = lower, 2 = upper level).
- // level: contour z-value.
- // want_initial_point: whether want to append the initial point to the
- // ContourLine or not.
- // start_quad_edge: the QuadEdge that the ContourLine started from to
- // check if the ContourLine is finished, or 0 if no check should occur.
- // start_level_index: the level_index that the ContourLine started from.
- // set_parents: whether should set ParentCache as it progresses or not.
- // This is true for filled contours, false for line contours.
- void follow_interior(ContourLine& contour_line,
- QuadEdge& quad_edge,
- unsigned int level_index,
- const double& level,
- bool want_initial_point,
- const QuadEdge* start_quad_edge,
- unsigned int start_level_index,
- bool set_parents);
-
- // Return the index limits of a particular chunk.
- void get_chunk_limits(long ijchunk,
- long& ichunk,
- long& jchunk,
- long& istart,
- long& iend,
- long& jstart,
- long& jend);
-
- // Check if a contour starts within the specified corner quad on the
- // specified level_index, and if so return the start edge. Otherwise
- // return Edge_None.
- Edge get_corner_start_edge(long quad, unsigned int level_index) const;
-
- // Return index of point at start or end of specified QuadEdge, assuming
- // anticlockwise ordering around non-masked quads.
- long get_edge_point_index(const QuadEdge& quad_edge, bool start) const;
-
- // Return the edge to exit a quad from, given the specified entry quad_edge
- // and direction to move in.
- Edge get_exit_edge(const QuadEdge& quad_edge, Dir dir) const;
-
- // Return the (x,y) coordinates of the specified point index.
- XY get_point_xy(long point) const;
-
- // Return the z-value of the specified point index.
- const double& get_point_z(long point) const;
-
- // Check if a contour starts within the specified non-corner quad on the
- // specified level_index, and if so return the start edge. Otherwise
- // return Edge_None.
- Edge get_quad_start_edge(long quad, unsigned int level_index) const;
-
- // Check if a contour starts within the specified quad, whether it is a
- // corner or a full quad, and if so return the start edge. Otherwise
- // return Edge_None.
- Edge get_start_edge(long quad, unsigned int level_index) const;
-
- // Initialise the cache to contain grid information that is constant
- // across the lifetime of this object, i.e. does not vary between calls to
- // create_contour() and create_filled_contour().
- void init_cache_grid(const MaskArray& mask);
-
- // Initialise the cache with information that is specific to contouring the
- // specified two levels. The levels are the same for contour lines,
- // different for filled contours.
- void init_cache_levels(const double& lower_level,
- const double& upper_level);
-
- // Return the (x,y) point at which the level intersects the line connecting
- // the two specified point indices.
- XY interp(long point1, long point2, const double& level) const;
-
- // Return true if the specified QuadEdge is a boundary, i.e. is either an
- // edge between a masked and non-masked quad/corner or is a chunk boundary.
- bool is_edge_a_boundary(const QuadEdge& quad_edge) const;
-
- // Follow a boundary from one QuadEdge to the next in an anticlockwise
- // manner around the non-masked region.
- void move_to_next_boundary_edge(QuadEdge& quad_edge) const;
-
- // Move from the quad specified by quad_edge.quad to the neighbouring quad
- // by crossing the edge specified by quad_edge.edge.
- void move_to_next_quad(QuadEdge& quad_edge) const;
-
- // Check for filled contours starting within the specified quad and
- // complete any that are found, appending them to the specified Contour.
- void single_quad_filled(Contour& contour,
- long quad,
- const double& lower_level,
- const double& upper_level);
-
- // Start and complete a filled contour line.
- // quad: index of quad to start ContourLine in.
- // edge: edge of quad to start ContourLine from.
- // start_level_index: the level_index that the ContourLine starts from.
- // hole_or_not: whether the ContourLine is a hole or not.
- // boundary_or_interior: whether the ContourLine starts on a boundary or
- // the interior.
- // lower_level: lower contour z-value.
- // upper_level: upper contour z-value.
- // Returns newly created ContourLine.
- ContourLine* start_filled(long quad,
- Edge edge,
- unsigned int start_level_index,
- HoleOrNot hole_or_not,
- BoundaryOrInterior boundary_or_interior,
- const double& lower_level,
- const double& upper_level);
-
- // Start and complete a line contour that both starts and end on a
- // boundary, traversing the interior of the domain.
- // vertices_list: Python list that the ContourLine should be appended to.
- // quad: index of quad to start ContourLine in.
- // edge: boundary edge to start ContourLine from.
- // level: contour z-value.
- // Returns true if the start quad does not need to be visited again, i.e.
- // VISITED(quad,1).
- bool start_line(PyObject* vertices_list,
- long quad,
- Edge edge,
- const double& level);
-
- // Debug function that writes the cache status to stdout.
- void write_cache(bool grid_only = false) const;
-
- // Debug function that writes that cache status for a single quad to
- // stdout.
- void write_cache_quad(long quad, bool grid_only) const;
-
-
-
- // Note that mask is not stored as once it has been used to initialise the
- // cache it is no longer needed.
- CoordinateArray _x, _y, _z;
- long _nx, _ny; // Number of points in each direction.
- long _n; // Total number of points (and hence quads).
-
- bool _corner_mask;
- long _chunk_size; // Number of quads per chunk (not points).
- // Always > 0, unlike python nchunk which is 0
- // for no chunking.
-
- long _nxchunk, _nychunk; // Number of chunks in each direction.
- long _chunk_count; // Total number of chunks.
-
- typedef uint32_t CacheItem;
- CacheItem* _cache;
-
- ParentCache _parent_cache; // On W quad sides.
-};
-
-#endif // _CONTOUR_H
diff --git a/contrib/python/matplotlib/py2/src/_contour_wrapper.cpp b/contrib/python/matplotlib/py2/src/_contour_wrapper.cpp
deleted file mode 100644
index eedc8a1aec..0000000000
--- a/contrib/python/matplotlib/py2/src/_contour_wrapper.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-#include "src/_contour.h"
-#include "src/mplutils.h"
-#include "src/py_exceptions.h"
-
-/* QuadContourGenerator */
-
-typedef struct
-{
- PyObject_HEAD
- QuadContourGenerator* ptr;
-} PyQuadContourGenerator;
-
-static PyTypeObject PyQuadContourGeneratorType;
-
-static PyObject* PyQuadContourGenerator_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
-{
- PyQuadContourGenerator* self;
- self = (PyQuadContourGenerator*)type->tp_alloc(type, 0);
- self->ptr = NULL;
- return (PyObject*)self;
-}
-
-const char* PyQuadContourGenerator_init__doc__ =
- "QuadContourGenerator(x, y, z, mask, corner_mask, chunk_size)\n"
- "\n"
- "Create a new C++ QuadContourGenerator object\n";
-
-static int PyQuadContourGenerator_init(PyQuadContourGenerator* self, PyObject* args, PyObject* kwds)
-{
- QuadContourGenerator::CoordinateArray x, y, z;
- QuadContourGenerator::MaskArray mask;
- int corner_mask;
- long chunk_size;
-
- if (!PyArg_ParseTuple(args, "O&O&O&O&il",
- &x.converter_contiguous, &x,
- &y.converter_contiguous, &y,
- &z.converter_contiguous, &z,
- &mask.converter_contiguous, &mask,
- &corner_mask,
- &chunk_size)) {
- return -1;
- }
-
- if (x.empty() || y.empty() || z.empty() ||
- y.dim(0) != x.dim(0) || z.dim(0) != x.dim(0) ||
- y.dim(1) != x.dim(1) || z.dim(1) != x.dim(1)) {
- PyErr_SetString(PyExc_ValueError,
- "x, y and z must all be 2D arrays with the same dimensions");
- return -1;
- }
-
- if (z.dim(0) < 2 || z.dim(1) < 2) {
- PyErr_SetString(PyExc_ValueError,
- "x, y and z must all be at least 2x2 arrays");
- return -1;
- }
-
- // Mask array is optional, if set must be same size as other arrays.
- if (!mask.empty() && (mask.dim(0) != x.dim(0) || mask.dim(1) != x.dim(1))) {
- PyErr_SetString(PyExc_ValueError,
- "If mask is set it must be a 2D array with the same dimensions as x.");
- return -1;
- }
-
- CALL_CPP_INIT("QuadContourGenerator",
- (self->ptr = new QuadContourGenerator(
- x, y, z, mask, corner_mask, chunk_size)));
- return 0;
-}
-
-static void PyQuadContourGenerator_dealloc(PyQuadContourGenerator* self)
-{
- delete self->ptr;
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-const char* PyQuadContourGenerator_create_contour__doc__ =
- "create_contour(level)\n"
- "\n"
- "Create and return a non-filled contour.";
-
-static PyObject* PyQuadContourGenerator_create_contour(PyQuadContourGenerator* self, PyObject* args, PyObject* kwds)
-{
- double level;
- if (!PyArg_ParseTuple(args, "d:create_contour", &level)) {
- return NULL;
- }
-
- PyObject* result;
- CALL_CPP("create_contour", (result = self->ptr->create_contour(level)));
- return result;
-}
-
-const char* PyQuadContourGenerator_create_filled_contour__doc__ =
- "create_filled_contour(lower_level, upper_level)\n"
- "\n"
- "Create and return a filled contour";
-
-static PyObject* PyQuadContourGenerator_create_filled_contour(PyQuadContourGenerator* self, PyObject* args, PyObject* kwds)
-{
- double lower_level, upper_level;
- if (!PyArg_ParseTuple(args, "dd:create_filled_contour",
- &lower_level, &upper_level)) {
- return NULL;
- }
-
- if (lower_level >= upper_level)
- {
- PyErr_SetString(PyExc_ValueError,
- "filled contour levels must be increasing");
- return NULL;
- }
-
- PyObject* result;
- CALL_CPP("create_filled_contour",
- (result = self->ptr->create_filled_contour(lower_level,
- upper_level)));
- return result;
-}
-
-static PyTypeObject* PyQuadContourGenerator_init_type(PyObject* m, PyTypeObject* type)
-{
- static PyMethodDef methods[] = {
- {"create_contour", (PyCFunction)PyQuadContourGenerator_create_contour, METH_VARARGS, PyQuadContourGenerator_create_contour__doc__},
- {"create_filled_contour", (PyCFunction)PyQuadContourGenerator_create_filled_contour, METH_VARARGS, PyQuadContourGenerator_create_filled_contour__doc__},
- {NULL}
- };
-
- memset(type, 0, sizeof(PyTypeObject));
- type->tp_name = "matplotlib.QuadContourGenerator";
- type->tp_doc = PyQuadContourGenerator_init__doc__;
- type->tp_basicsize = sizeof(PyQuadContourGenerator);
- type->tp_dealloc = (destructor)PyQuadContourGenerator_dealloc;
- type->tp_flags = Py_TPFLAGS_DEFAULT;
- type->tp_methods = methods;
- type->tp_new = PyQuadContourGenerator_new;
- type->tp_init = (initproc)PyQuadContourGenerator_init;
-
- if (PyType_Ready(type) < 0) {
- return NULL;
- }
-
- if (PyModule_AddObject(m, "QuadContourGenerator", (PyObject*)type)) {
- return NULL;
- }
-
- return type;
-}
-
-
-/* Module */
-
-extern "C" {
-
-#if PY3K
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_contour",
- NULL,
- 0,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit__contour(void)
-
-#else
-#define INITERROR return
-
-PyMODINIT_FUNC init_contour(void)
-#endif
-
-{
- PyObject *m;
-
-#if PY3K
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("_contour", NULL, NULL);
-#endif
-
- if (m == NULL) {
- INITERROR;
- }
-
- if (!PyQuadContourGenerator_init_type(m, &PyQuadContourGeneratorType)) {
- INITERROR;
- }
-
- import_array();
-
-#if PY3K
- return m;
-#endif
-}
-
-} // extern "C"
diff --git a/contrib/python/matplotlib/py2/src/_gtkagg.cpp b/contrib/python/matplotlib/py2/src/_gtkagg.cpp
deleted file mode 100644
index 2d6a1cec13..0000000000
--- a/contrib/python/matplotlib/py2/src/_gtkagg.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#include <pygobject.h>
-#include <pygtk/pygtk.h>
-
-#include <vector>
-
-#include "agg_basics.h"
-#include "agg_pixfmt_rgba.h"
-#include "agg_renderer_base.h"
-#include "agg_rendering_buffer.h"
-
-#include "numpy_cpp.h"
-#include "py_converters.h"
-
-static PyObject *Py_agg_to_gtk_drawable(PyObject *self, PyObject *args, PyObject *kwds)
-{
- typedef agg::pixfmt_rgba32_plain pixfmt;
- typedef agg::renderer_base<pixfmt> renderer_base;
-
- PyGObject *py_drawable;
- numpy::array_view<agg::int8u, 3> buffer;
- agg::rect_d rect;
-
- // args are gc, renderer, bbox where bbox is a transforms BBox
- // (possibly None). If bbox is None, blit the entire agg buffer
- // to gtk. If bbox is not None, blit only the region defined by
- // the bbox
-
- if (!PyArg_ParseTuple(args,
- "OO&O&:agg_to_gtk_drawable",
- &py_drawable,
- &buffer.converter,
- &buffer,
- &convert_rect,
- &rect)) {
- return NULL;
- }
-
- if (buffer.dim(2) != 4) {
- PyErr_SetString(PyExc_ValueError, "Invalid image buffer. Must be NxMx4.");
- return NULL;
- }
-
- GdkDrawable *drawable = GDK_DRAWABLE(py_drawable->obj);
- GdkGC *gc = gdk_gc_new(drawable);
-
- int srcstride = buffer.dim(1) * 4;
- int srcwidth = buffer.dim(1);
- int srcheight = buffer.dim(0);
-
- // these three will be overridden below
- int destx = 0;
- int desty = 0;
- int destwidth = 1;
- int destheight = 1;
- int deststride = 1;
-
- std::vector<agg::int8u> destbuffer;
- agg::int8u *destbufferptr;
-
- if (rect.x1 == 0.0 && rect.x2 == 0.0 && rect.y1 == 0.0 && rect.y2 == 0.0) {
- // bbox is None; copy the entire image
- destbufferptr = (agg::int8u *)buffer.data();
- destwidth = srcwidth;
- destheight = srcheight;
- deststride = srcstride;
- } else {
- destx = (int)rect.x1;
- desty = srcheight - (int)rect.y2;
- destwidth = (int)(rect.x2 - rect.x1);
- destheight = (int)(rect.y2 - rect.y1);
- deststride = destwidth * 4;
- destbuffer.resize(destheight * deststride, 0);
- destbufferptr = &destbuffer.front();
-
- agg::rendering_buffer destrbuf;
- destrbuf.attach(destbufferptr, destwidth, destheight, deststride);
- pixfmt destpf(destrbuf);
- renderer_base destrb(destpf);
-
- agg::rendering_buffer srcrbuf;
- srcrbuf.attach((agg::int8u *)buffer.data(), buffer.dim(1), buffer.dim(0), buffer.dim(1) * 4);
-
- agg::rect_base<int> region(destx, desty, (int)rect.x2, srcheight - (int)rect.y1);
- destrb.copy_from(srcrbuf, &region, -destx, -desty);
- }
-
- gdk_draw_rgb_32_image(drawable,
- gc,
- destx,
- desty,
- destwidth,
- destheight,
- GDK_RGB_DITHER_NORMAL,
- destbufferptr,
- deststride);
-
- gdk_gc_destroy(gc);
-
- Py_RETURN_NONE;
-}
-
-static PyMethodDef module_methods[] = {
- {"agg_to_gtk_drawable", (PyCFunction)Py_agg_to_gtk_drawable, METH_VARARGS, NULL},
- NULL
-};
-
-extern "C" {
-
-#if PY3K
- static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_gtkagg",
- NULL,
- 0,
- module_methods,
- NULL,
- NULL,
- NULL,
- NULL
- };
-
-#define INITERROR return NULL
-
- PyMODINIT_FUNC PyInit__gtkagg(void)
-
-#else
-#define INITERROR return
-
- PyMODINIT_FUNC init_gtkagg(void)
-#endif
-
- {
- PyObject *m;
-
-#if PY3K
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("_gtkagg", module_methods, NULL);
-#endif
-
- if (m == NULL) {
- INITERROR;
- }
-
- init_pygobject();
- init_pygtk();
- import_array();
-
-#if PY3K
- return m;
-#endif
- }
-}
diff --git a/contrib/python/matplotlib/py2/src/_image.cpp b/contrib/python/matplotlib/py2/src/_image.cpp
deleted file mode 100644
index 8fc386fccb..0000000000
--- a/contrib/python/matplotlib/py2/src/_image.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#define NO_IMPORT_ARRAY
-
-#include <math.h>
-
-// utilities for irregular grids
-void _bin_indices_middle(
- unsigned int *irows, int nrows, const float *ys1, unsigned long ny, float dy, float y_min)
-{
- int i, j, j_last;
- unsigned int *rowstart = irows;
- const float *ys2 = ys1 + 1;
- const float *yl = ys1 + ny;
- float yo = y_min + dy / 2.0;
- float ym = 0.5f * (*ys1 + *ys2);
- // y/rows
- j = 0;
- j_last = j;
- for (i = 0; i < nrows; i++, yo += dy, rowstart++) {
- while (ys2 != yl && yo > ym) {
- ys1 = ys2;
- ys2 = ys1 + 1;
- ym = 0.5f * (*ys1 + *ys2);
- j++;
- }
- *rowstart = j - j_last;
- j_last = j;
- }
-}
-
-void _bin_indices_middle_linear(float *arows,
- unsigned int *irows,
- int nrows,
- const float *y,
- unsigned long ny,
- float dy,
- float y_min)
-{
- int i;
- int ii = 0;
- int iilast = (int)ny - 1;
- float sc = 1 / dy;
- int iy0 = (int)floor(sc * (y[ii] - y_min));
- int iy1 = (int)floor(sc * (y[ii + 1] - y_min));
- float invgap = 1.0f / (iy1 - iy0);
- for (i = 0; i < nrows && i <= iy0; i++) {
- irows[i] = 0;
- arows[i] = 1.0;
- }
- for (; i < nrows; i++) {
- while (i > iy1 && ii < iilast) {
- ii++;
- iy0 = iy1;
- iy1 = (int)floor(sc * (y[ii + 1] - y_min));
- invgap = 1.0f / (iy1 - iy0);
- }
- if (i >= iy0 && i <= iy1) {
- irows[i] = ii;
- arows[i] = (iy1 - i) * invgap;
- } else
- break;
- }
- for (; i < nrows; i++) {
- irows[i] = iilast - 1;
- arows[i] = 0.0;
- }
-}
-
-void _bin_indices(int *irows, int nrows, const double *y, unsigned long ny, double sc, double offs)
-{
- int i;
- if (sc * (y[ny - 1] - y[0]) > 0) {
- int ii = 0;
- int iilast = (int)ny - 1;
- int iy0 = (int)floor(sc * (y[ii] - offs));
- int iy1 = (int)floor(sc * (y[ii + 1] - offs));
- for (i = 0; i < nrows && i < iy0; i++) {
- irows[i] = -1;
- }
- for (; i < nrows; i++) {
- while (i > iy1 && ii < iilast) {
- ii++;
- iy0 = iy1;
- iy1 = (int)floor(sc * (y[ii + 1] - offs));
- }
- if (i >= iy0 && i <= iy1)
- irows[i] = ii;
- else
- break;
- }
- for (; i < nrows; i++) {
- irows[i] = -1;
- }
- } else {
- int iilast = (int)ny - 1;
- int ii = iilast;
- int iy0 = (int)floor(sc * (y[ii] - offs));
- int iy1 = (int)floor(sc * (y[ii - 1] - offs));
- for (i = 0; i < nrows && i < iy0; i++) {
- irows[i] = -1;
- }
- for (; i < nrows; i++) {
- while (i > iy1 && ii > 1) {
- ii--;
- iy0 = iy1;
- iy1 = (int)floor(sc * (y[ii - 1] - offs));
- }
- if (i >= iy0 && i <= iy1)
- irows[i] = ii - 1;
- else
- break;
- }
- for (; i < nrows; i++) {
- irows[i] = -1;
- }
- }
-}
-
-void _bin_indices_linear(
- float *arows, int *irows, int nrows, double *y, unsigned long ny, double sc, double offs)
-{
- int i;
- if (sc * (y[ny - 1] - y[0]) > 0) {
- int ii = 0;
- int iilast = (int)ny - 1;
- int iy0 = (int)floor(sc * (y[ii] - offs));
- int iy1 = (int)floor(sc * (y[ii + 1] - offs));
- float invgap = 1.0 / (iy1 - iy0);
- for (i = 0; i < nrows && i < iy0; i++) {
- irows[i] = -1;
- }
- for (; i < nrows; i++) {
- while (i > iy1 && ii < iilast) {
- ii++;
- iy0 = iy1;
- iy1 = (int)floor(sc * (y[ii + 1] - offs));
- invgap = 1.0 / (iy1 - iy0);
- }
- if (i >= iy0 && i <= iy1) {
- irows[i] = ii;
- arows[i] = (iy1 - i) * invgap;
- } else
- break;
- }
- for (; i < nrows; i++) {
- irows[i] = -1;
- }
- } else {
- int iilast = (int)ny - 1;
- int ii = iilast;
- int iy0 = (int)floor(sc * (y[ii] - offs));
- int iy1 = (int)floor(sc * (y[ii - 1] - offs));
- float invgap = 1.0 / (iy1 - iy0);
- for (i = 0; i < nrows && i < iy0; i++) {
- irows[i] = -1;
- }
- for (; i < nrows; i++) {
- while (i > iy1 && ii > 1) {
- ii--;
- iy0 = iy1;
- iy1 = (int)floor(sc * (y[ii - 1] - offs));
- invgap = 1.0 / (iy1 - iy0);
- }
- if (i >= iy0 && i <= iy1) {
- irows[i] = ii - 1;
- arows[i] = (i - iy0) * invgap;
- } else
- break;
- }
- for (; i < nrows; i++) {
- irows[i] = -1;
- }
- }
-}
diff --git a/contrib/python/matplotlib/py2/src/_image.h b/contrib/python/matplotlib/py2/src/_image.h
deleted file mode 100644
index 629714d2ec..0000000000
--- a/contrib/python/matplotlib/py2/src/_image.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/* image.h
- *
- */
-
-#ifndef _IMAGE_H
-#define _IMAGE_H
-
-#include <vector>
-
-
-// utilities for irregular grids
-void _bin_indices_middle(
- unsigned int *irows, int nrows, const float *ys1, unsigned long ny, float dy, float y_min);
-void _bin_indices_middle_linear(float *arows,
- unsigned int *irows,
- int nrows,
- const float *y,
- unsigned long ny,
- float dy,
- float y_min);
-void _bin_indices(int *irows, int nrows, const double *y, unsigned long ny, double sc, double offs);
-void _bin_indices_linear(
- float *arows, int *irows, int nrows, double *y, unsigned long ny, double sc, double offs);
-
-template <class CoordinateArray, class ColorArray, class OutputArray>
-void pcolor(CoordinateArray &x,
- CoordinateArray &y,
- ColorArray &d,
- unsigned int rows,
- unsigned int cols,
- float bounds[4],
- int interpolation,
- OutputArray &out)
-{
- if (rows >= 32768 || cols >= 32768) {
- throw std::runtime_error("rows and cols must both be less than 32768");
- }
-
- float x_min = bounds[0];
- float x_max = bounds[1];
- float y_min = bounds[2];
- float y_max = bounds[3];
- float width = x_max - x_min;
- float height = y_max - y_min;
- float dx = width / ((float)cols);
- float dy = height / ((float)rows);
-
- // Check we have something to output to
- if (rows == 0 || cols == 0) {
- throw std::runtime_error("Cannot scale to zero size");
- }
-
- if (d.dim(2) != 4) {
- throw std::runtime_error("data must be in RGBA format");
- }
-
- // Check dimensions match
- unsigned long nx = x.dim(0);
- unsigned long ny = y.dim(0);
- if (nx != (unsigned long)d.dim(1) || ny != (unsigned long)d.dim(0)) {
- throw std::runtime_error("data and axis dimensions do not match");
- }
-
- // Allocate memory for pointer arrays
- std::vector<unsigned int> rowstarts(rows);
- std::vector<unsigned int> colstarts(cols);
-
- // Calculate the pointer arrays to map input x to output x
- unsigned int i, j;
- unsigned int *colstart = &colstarts[0];
- unsigned int *rowstart = &rowstarts[0];
- const float *xs1 = x.data();
- const float *ys1 = y.data();
-
- // Copy data to output buffer
- const unsigned char *start;
- const unsigned char *inposition;
- size_t inrowsize = nx * 4;
- size_t rowsize = cols * 4;
- unsigned char *position = (unsigned char *)out.data();
- unsigned char *oldposition = NULL;
- start = d.data();
-
- if (interpolation == NEAREST) {
- _bin_indices_middle(colstart, cols, xs1, nx, dx, x_min);
- _bin_indices_middle(rowstart, rows, ys1, ny, dy, y_min);
- for (i = 0; i < rows; i++, rowstart++) {
- if (i > 0 && *rowstart == 0) {
- memcpy(position, oldposition, rowsize * sizeof(unsigned char));
- oldposition = position;
- position += rowsize;
- } else {
- oldposition = position;
- start += *rowstart * inrowsize;
- inposition = start;
- for (j = 0, colstart = &colstarts[0]; j < cols; j++, position += 4, colstart++) {
- inposition += *colstart * 4;
- memcpy(position, inposition, 4 * sizeof(unsigned char));
- }
- }
- }
- } else if (interpolation == BILINEAR) {
- std::vector<float> acols(cols);
- std::vector<float> arows(rows);
-
- _bin_indices_middle_linear(&acols[0], colstart, cols, xs1, nx, dx, x_min);
- _bin_indices_middle_linear(&arows[0], rowstart, rows, ys1, ny, dy, y_min);
- double a00, a01, a10, a11, alpha, beta;
-
- // Copy data to output buffer
- for (i = 0; i < rows; i++) {
- for (j = 0; j < cols; j++) {
- alpha = arows[i];
- beta = acols[j];
-
- a00 = alpha * beta;
- a01 = alpha * (1.0 - beta);
- a10 = (1.0 - alpha) * beta;
- a11 = 1.0 - a00 - a01 - a10;
-
- for (size_t k = 0; k < 4; ++k) {
- position[k] =
- d(rowstart[i], colstart[j], k) * a00 +
- d(rowstart[i], colstart[j] + 1, k) * a01 +
- d(rowstart[i] + 1, colstart[j], k) * a10 +
- d(rowstart[i] + 1, colstart[j] + 1, k) * a11;
- }
- position += 4;
- }
- }
- }
-}
-
-template <class CoordinateArray, class ColorArray, class Color, class OutputArray>
-void pcolor2(CoordinateArray &x,
- CoordinateArray &y,
- ColorArray &d,
- unsigned int rows,
- unsigned int cols,
- float bounds[4],
- Color &bg,
- OutputArray &out)
-{
- double x_left = bounds[0];
- double x_right = bounds[1];
- double y_bot = bounds[2];
- double y_top = bounds[3];
-
- // Check we have something to output to
- if (rows == 0 || cols == 0) {
- throw std::runtime_error("rows or cols is zero; there are no pixels");
- }
-
- if (d.dim(2) != 4) {
- throw std::runtime_error("data must be in RGBA format");
- }
-
- // Check dimensions match
- unsigned long nx = x.dim(0);
- unsigned long ny = y.dim(0);
- if (nx != (unsigned long)d.dim(1) + 1 || ny != (unsigned long)d.dim(0) + 1) {
- throw std::runtime_error("data and axis bin boundary dimensions are incompatible");
- }
-
- if (bg.dim(0) != 4) {
- throw std::runtime_error("bg must be in RGBA format");
- }
-
- std::vector<int> irows(rows);
- std::vector<int> jcols(cols);
-
- // Calculate the pointer arrays to map input x to output x
- size_t i, j;
- const double *x0 = x.data();
- const double *y0 = y.data();
- double sx = cols / (x_right - x_left);
- double sy = rows / (y_top - y_bot);
- _bin_indices(&jcols[0], cols, x0, nx, sx, x_left);
- _bin_indices(&irows[0], rows, y0, ny, sy, y_bot);
-
- // Copy data to output buffer
- unsigned char *position = (unsigned char *)out.data();
-
- for (i = 0; i < rows; i++) {
- for (j = 0; j < cols; j++) {
- if (irows[i] == -1 || jcols[j] == -1) {
- memcpy(position, (const unsigned char *)bg.data(), 4 * sizeof(unsigned char));
- } else {
- for (size_t k = 0; k < 4; ++k) {
- position[k] = d(irows[i], jcols[j], k);
- }
- }
- position += 4;
- }
- }
-}
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/_image_resample.h b/contrib/python/matplotlib/py2/src/_image_resample.h
deleted file mode 100644
index 86cbef0324..0000000000
--- a/contrib/python/matplotlib/py2/src/_image_resample.h
+++ /dev/null
@@ -1,1013 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef RESAMPLE_H
-#define RESAMPLE_H
-
-#include "agg_image_accessors.h"
-#include "agg_path_storage.h"
-#include "agg_pixfmt_gray.h"
-#include "agg_pixfmt_rgb.h"
-#include "agg_pixfmt_rgba.h"
-#include "agg_renderer_base.h"
-#include "agg_renderer_scanline.h"
-#include "agg_rasterizer_scanline_aa.h"
-#include "agg_scanline_u.h"
-#include "agg_span_allocator.h"
-#include "agg_span_converter.h"
-#include "agg_span_image_filter_gray.h"
-#include "agg_span_image_filter_rgba.h"
-#include "agg_span_interpolator_adaptor.h"
-#include "agg_span_interpolator_linear.h"
-
-#include "agg_workaround.h"
-
-// Based on:
-
-//----------------------------------------------------------------------------
-// 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.
-//
-
-//===================================================================gray64
-namespace agg
-{
- struct gray64
- {
- typedef double value_type;
- typedef double calc_type;
- typedef double long_type;
- typedef gray64 self_type;
-
- value_type v;
- value_type a;
-
- //--------------------------------------------------------------------
- gray64() {}
-
- //--------------------------------------------------------------------
- explicit gray64(value_type v_, value_type a_ = 1) :
- v(v_), a(a_) {}
-
- //--------------------------------------------------------------------
- gray64(const self_type& c, value_type a_) :
- v(c.v), a(a_) {}
-
- //--------------------------------------------------------------------
- gray64(const gray64& c) :
- v(c.v),
- a(c.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); }
- };
-
-
- //====================================================================rgba32
- struct rgba64
- {
- typedef double value_type;
- typedef double calc_type;
- typedef double long_type;
- typedef rgba64 self_type;
-
- value_type r;
- value_type g;
- value_type b;
- value_type a;
-
- //--------------------------------------------------------------------
- rgba64() {}
-
- //--------------------------------------------------------------------
- rgba64(value_type r_, value_type g_, value_type b_, value_type a_= 1) :
- r(r_), g(g_), b(b_), a(a_) {}
-
- //--------------------------------------------------------------------
- rgba64(const self_type& c, float a_) :
- r(c.r), g(c.g), b(c.b), a(a_) {}
-
- //--------------------------------------------------------------------
- rgba64(const rgba& c) :
- r(value_type(c.r)), g(value_type(c.g)), b(value_type(c.b)), a(value_type(c.a)) {}
-
- //--------------------------------------------------------------------
- operator rgba() const
- {
- return rgba(r, g, b, 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()
- {
- 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;
- }
-
- //--------------------------------------------------------------------
- static self_type no_color() { return self_type(0,0,0,0); }
- };
-}
-
-
-typedef enum {
- NEAREST,
- BILINEAR,
- BICUBIC,
- SPLINE16,
- SPLINE36,
- HANNING,
- HAMMING,
- HERMITE,
- KAISER,
- QUADRIC,
- CATROM,
- GAUSSIAN,
- BESSEL,
- MITCHELL,
- SINC,
- LANCZOS,
- BLACKMAN,
- _n_interpolation
-} interpolation_e;
-
-
-template <typename T>
-class type_mapping;
-
-
-template <> class type_mapping<agg::rgba8>
-{
- public:
- typedef agg::rgba8 color_type;
- typedef fixed_blender_rgba_plain<color_type, agg::order_rgba> blender_type;
- typedef fixed_blender_rgba_pre<color_type, agg::order_rgba> pre_blender_type;
- typedef agg::pixfmt_alpha_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_type;
- typedef agg::pixfmt_alpha_blend_rgba<pre_blender_type, agg::rendering_buffer> pixfmt_pre_type;
-
- template <typename A>
- struct span_gen_affine_type
- {
- typedef agg::span_image_resample_rgba_affine<A> type;
- };
-
- template <typename A, typename B>
- struct span_gen_filter_type
- {
- typedef agg::span_image_filter_rgba<A, B> type;
- };
-
- template <typename A, typename B>
- struct span_gen_nn_type
- {
- typedef agg::span_image_filter_rgba_nn<A, B> type;
- };
-};
-
-
-template <> class type_mapping<agg::rgba16>
-{
- public:
- typedef agg::rgba16 color_type;
- typedef fixed_blender_rgba_plain<color_type, agg::order_rgba> blender_type;
- typedef fixed_blender_rgba_pre<color_type, agg::order_rgba> pre_blender_type;
- typedef agg::pixfmt_alpha_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_type;
- typedef agg::pixfmt_alpha_blend_rgba<pre_blender_type, agg::rendering_buffer> pixfmt_pre_type;
-
- template <typename A>
- struct span_gen_affine_type
- {
- typedef agg::span_image_resample_rgba_affine<A> type;
- };
-
- template <typename A, typename B>
- struct span_gen_filter_type
- {
- typedef agg::span_image_filter_rgba<A, B> type;
- };
-
- template <typename A, typename B>
- struct span_gen_nn_type
- {
- typedef agg::span_image_filter_rgba_nn<A, B> type;
- };
-};
-
-
-template <> class type_mapping<agg::rgba32>
-{
- public:
- typedef agg::rgba32 color_type;
- typedef agg::blender_rgba_plain<color_type, agg::order_rgba> blender_type;
- typedef agg::blender_rgba_pre<color_type, agg::order_rgba> pre_blender_type;
- typedef agg::pixfmt_alpha_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_type;
- typedef agg::pixfmt_alpha_blend_rgba<pre_blender_type, agg::rendering_buffer> pixfmt_pre_type;
-
- template <typename A>
- struct span_gen_affine_type
- {
- typedef agg::span_image_resample_rgba_affine<A> type;
- };
-
- template <typename A, typename B>
- struct span_gen_filter_type
- {
- typedef agg::span_image_filter_rgba<A, B> type;
- };
-
- template <typename A, typename B>
- struct span_gen_nn_type
- {
- typedef agg::span_image_filter_rgba_nn<A, B> type;
- };
-};
-
-
-template <> class type_mapping<agg::rgba64>
-{
- public:
- typedef agg::rgba64 color_type;
- typedef agg::blender_rgba_plain<color_type, agg::order_rgba> blender_type;
- typedef agg::blender_rgba_pre<color_type, agg::order_rgba> pre_blender_type;
- typedef agg::pixfmt_alpha_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_type;
- typedef agg::pixfmt_alpha_blend_rgba<pre_blender_type, agg::rendering_buffer> pixfmt_pre_type;
-
- template <typename A>
- struct span_gen_affine_type
- {
- typedef agg::span_image_resample_rgba_affine<A> type;
- };
-
- template <typename A, typename B>
- struct span_gen_filter_type
- {
- typedef agg::span_image_filter_rgba<A, B> type;
- };
-
- template <typename A, typename B>
- struct span_gen_nn_type
- {
- typedef agg::span_image_filter_rgba_nn<A, B> type;
- };
-};
-
-
-template <> class type_mapping<double>
-{
- public:
- typedef agg::gray64 color_type;
- typedef agg::blender_gray<color_type> blender_type;
- typedef agg::pixfmt_alpha_blend_gray<blender_type, agg::rendering_buffer> pixfmt_type;
- typedef pixfmt_type pixfmt_pre_type;
-
- template <typename A>
- struct span_gen_affine_type
- {
- typedef agg::span_image_resample_gray_affine<A> type;
- };
-
- template <typename A, typename B>
- struct span_gen_filter_type
- {
- typedef agg::span_image_filter_gray<A, B> type;
- };
-
- template <typename A, typename B>
- struct span_gen_nn_type
- {
- typedef agg::span_image_filter_gray_nn<A, B> type;
- };
-};
-
-
-template <> class type_mapping<float>
-{
- public:
- typedef agg::gray32 color_type;
- typedef agg::blender_gray<color_type> blender_type;
- typedef agg::pixfmt_alpha_blend_gray<blender_type, agg::rendering_buffer> pixfmt_type;
- typedef pixfmt_type pixfmt_pre_type;
-
- template <typename A>
- struct span_gen_affine_type
- {
- typedef agg::span_image_resample_gray_affine<A> type;
- };
-
- template <typename A, typename B>
- struct span_gen_filter_type
- {
- typedef agg::span_image_filter_gray<A, B> type;
- };
-
- template <typename A, typename B>
- struct span_gen_nn_type
- {
- typedef agg::span_image_filter_gray_nn<A, B> type;
- };
-};
-
-
-template <> class type_mapping<unsigned short>
-{
- public:
- typedef agg::gray16 color_type;
- typedef agg::blender_gray<color_type> blender_type;
- typedef agg::pixfmt_alpha_blend_gray<blender_type, agg::rendering_buffer> pixfmt_type;
- typedef pixfmt_type pixfmt_pre_type;
-
- template <typename A>
- struct span_gen_affine_type
- {
- typedef agg::span_image_resample_gray_affine<A> type;
- };
-
- template <typename A, typename B>
- struct span_gen_filter_type
- {
- typedef agg::span_image_filter_gray<A, B> type;
- };
-
- template <typename A, typename B>
- struct span_gen_nn_type
- {
- typedef agg::span_image_filter_gray_nn<A, B> type;
- };
-};
-
-
-template <> class type_mapping<unsigned char>
-{
- public:
- typedef agg::gray8 color_type;
- typedef agg::blender_gray<color_type> blender_type;
- typedef agg::pixfmt_alpha_blend_gray<blender_type, agg::rendering_buffer> pixfmt_type;
- typedef pixfmt_type pixfmt_pre_type;
-
- template <typename A>
- struct span_gen_affine_type
- {
- typedef agg::span_image_resample_gray_affine<A> type;
- };
-
- template <typename A, typename B>
- struct span_gen_filter_type
- {
- typedef agg::span_image_filter_gray<A, B> type;
- };
-
- template <typename A, typename B>
- struct span_gen_nn_type
- {
- typedef agg::span_image_filter_gray_nn<A, B> type;
- };
-};
-
-
-
-template<class color_type>
-class span_conv_alpha
-{
-public:
- span_conv_alpha(const double alpha) :
- m_alpha(alpha)
- {
- }
-
- void prepare() {}
-
- void generate(color_type* span, int x, int y, unsigned len) const
- {
- if (m_alpha != 1.0) {
- do {
- span->a *= m_alpha;
- ++span;
- } while (--len);
- }
- }
-private:
-
- const double m_alpha;
-};
-
-
-/* A class to use a lookup table for a transformation */
-class lookup_distortion
-{
-public:
- lookup_distortion(const double *mesh, int in_width, int in_height,
- int out_width, int out_height) :
- m_mesh(mesh),
- m_in_width(in_width),
- m_in_height(in_height),
- m_out_width(out_width),
- m_out_height(out_height)
- {}
-
- void calculate(int* x, int* y) {
- if (m_mesh) {
- double dx = double(*x) / agg::image_subpixel_scale;
- double dy = double(*y) / agg::image_subpixel_scale;
- if (dx >= 0 && dx < m_out_width &&
- dy >= 0 && dy < m_out_height) {
- const double *coord = m_mesh + (int(dy) * m_out_width + int(dx)) * 2;
- *x = int(coord[0] * agg::image_subpixel_scale);
- *y = int(coord[1] * agg::image_subpixel_scale);
- }
- }
- }
-
-protected:
- const double *m_mesh;
- int m_in_width;
- int m_in_height;
- int m_out_width;
- int m_out_height;
-};
-
-
-struct resample_params_t {
- interpolation_e interpolation;
- bool is_affine;
- agg::trans_affine affine;
- const double *transform_mesh;
- bool resample;
- double norm;
- double radius;
- double alpha;
-};
-
-
-static void get_filter(const resample_params_t &params,
- agg::image_filter_lut &filter)
-{
- switch (params.interpolation) {
- case NEAREST:
- case _n_interpolation:
- // Never should get here. Here to silence compiler warnings.
- break;
-
- case HANNING:
- filter.calculate(agg::image_filter_hanning(), params.norm);
- break;
-
- case HAMMING:
- filter.calculate(agg::image_filter_hamming(), params.norm);
- break;
-
- case HERMITE:
- filter.calculate(agg::image_filter_hermite(), params.norm);
- break;
-
- case BILINEAR:
- filter.calculate(agg::image_filter_bilinear(), params.norm);
- break;
-
- case BICUBIC:
- filter.calculate(agg::image_filter_bicubic(), params.norm);
- break;
-
- case SPLINE16:
- filter.calculate(agg::image_filter_spline16(), params.norm);
- break;
-
- case SPLINE36:
- filter.calculate(agg::image_filter_spline36(), params.norm);
- break;
-
- case KAISER:
- filter.calculate(agg::image_filter_kaiser(), params.norm);
- break;
-
- case QUADRIC:
- filter.calculate(agg::image_filter_quadric(), params.norm);
- break;
-
- case CATROM:
- filter.calculate(agg::image_filter_catrom(), params.norm);
- break;
-
- case GAUSSIAN:
- filter.calculate(agg::image_filter_gaussian(), params.norm);
- break;
-
- case BESSEL:
- filter.calculate(agg::image_filter_bessel(), params.norm);
- break;
-
- case MITCHELL:
- filter.calculate(agg::image_filter_mitchell(), params.norm);
- break;
-
- case SINC:
- filter.calculate(agg::image_filter_sinc(params.radius), params.norm);
- break;
-
- case LANCZOS:
- filter.calculate(agg::image_filter_lanczos(params.radius), params.norm);
- break;
-
- case BLACKMAN:
- filter.calculate(agg::image_filter_blackman(params.radius), params.norm);
- break;
- }
-}
-
-
-template<class T>
-void resample(
- const T *input, int in_width, int in_height,
- T *output, int out_width, int out_height,
- resample_params_t &params)
-{
- typedef type_mapping<T> type_mapping_t;
-
- typedef typename type_mapping_t::pixfmt_type input_pixfmt_t;
- typedef typename type_mapping_t::pixfmt_type output_pixfmt_t;
-
- typedef agg::renderer_base<output_pixfmt_t> renderer_t;
- typedef agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> rasterizer_t;
-
- typedef agg::wrap_mode_reflect reflect_t;
- typedef agg::image_accessor_wrap<input_pixfmt_t, reflect_t, reflect_t> image_accessor_t;
-
- typedef agg::span_allocator<typename type_mapping_t::color_type> span_alloc_t;
- typedef span_conv_alpha<typename type_mapping_t::color_type> span_conv_alpha_t;
-
- typedef agg::span_interpolator_linear<> affine_interpolator_t;
- typedef agg::span_interpolator_adaptor<agg::span_interpolator_linear<>, lookup_distortion>
- arbitrary_interpolator_t;
-
- if (params.interpolation != NEAREST &&
- params.is_affine &&
- fabs(params.affine.sx) == 1.0 &&
- fabs(params.affine.sy) == 1.0 &&
- params.affine.shx == 0.0 &&
- params.affine.shy == 0.0) {
- params.interpolation = NEAREST;
- }
-
- span_alloc_t span_alloc;
- rasterizer_t rasterizer;
- agg::scanline_u8 scanline;
-
- span_conv_alpha_t conv_alpha(params.alpha);
-
- agg::rendering_buffer input_buffer;
- input_buffer.attach((unsigned char *)input, in_width, in_height,
- in_width * sizeof(T));
- input_pixfmt_t input_pixfmt(input_buffer);
- image_accessor_t input_accessor(input_pixfmt);
-
- agg::rendering_buffer output_buffer;
- output_buffer.attach((unsigned char *)output, out_width, out_height,
- out_width * sizeof(T));
- output_pixfmt_t output_pixfmt(output_buffer);
- renderer_t renderer(output_pixfmt);
-
- agg::trans_affine inverted = params.affine;
- inverted.invert();
-
- rasterizer.clip_box(0, 0, out_width, out_height);
-
- agg::path_storage path;
- if (params.is_affine) {
- path.move_to(0, 0);
- path.line_to(in_width, 0);
- path.line_to(in_width, in_height);
- path.line_to(0, in_height);
- path.close_polygon();
- agg::conv_transform<agg::path_storage> rectangle(path, params.affine);
- rasterizer.add_path(rectangle);
- } else {
- path.move_to(0, 0);
- path.line_to(out_width, 0);
- path.line_to(out_width, out_height);
- path.line_to(0, out_height);
- path.close_polygon();
- rasterizer.add_path(path);
- }
-
- if (params.interpolation == NEAREST) {
- if (params.is_affine) {
- typedef typename type_mapping_t::template span_gen_nn_type<image_accessor_t, affine_interpolator_t>::type span_gen_t;
- typedef agg::span_converter<span_gen_t, span_conv_alpha_t> span_conv_t;
- typedef agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t> nn_renderer_t;
-
- affine_interpolator_t interpolator(inverted);
- span_gen_t span_gen(input_accessor, interpolator);
- span_conv_t span_conv(span_gen, conv_alpha);
- nn_renderer_t nn_renderer(renderer, span_alloc, span_conv);
- agg::render_scanlines(rasterizer, scanline, nn_renderer);
- } else {
- typedef typename type_mapping_t::template span_gen_nn_type<image_accessor_t, arbitrary_interpolator_t>::type span_gen_t;
- typedef agg::span_converter<span_gen_t, span_conv_alpha_t> span_conv_t;
- typedef agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t> nn_renderer_t;
-
- lookup_distortion dist(
- params.transform_mesh, in_width, in_height, out_width, out_height);
- arbitrary_interpolator_t interpolator(inverted, dist);
- span_gen_t span_gen(input_accessor, interpolator);
- span_conv_t span_conv(span_gen, conv_alpha);
- nn_renderer_t nn_renderer(renderer, span_alloc, span_conv);
- agg::render_scanlines(rasterizer, scanline, nn_renderer);
- }
- } else {
- agg::image_filter_lut filter;
- get_filter(params, filter);
-
- if (params.is_affine && params.resample) {
- typedef typename type_mapping_t::template span_gen_affine_type<image_accessor_t>::type span_gen_t;
- typedef agg::span_converter<span_gen_t, span_conv_alpha_t> span_conv_t;
- typedef agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t> int_renderer_t;
-
- affine_interpolator_t interpolator(inverted);
- span_gen_t span_gen(input_accessor, interpolator, filter);
- span_conv_t span_conv(span_gen, conv_alpha);
- int_renderer_t int_renderer(renderer, span_alloc, span_conv);
- agg::render_scanlines(rasterizer, scanline, int_renderer);
- } else {
- typedef typename type_mapping_t::template span_gen_filter_type<image_accessor_t, arbitrary_interpolator_t>::type span_gen_t;
- typedef agg::span_converter<span_gen_t, span_conv_alpha_t> span_conv_t;
- typedef agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t> int_renderer_t;
-
- lookup_distortion dist(
- params.transform_mesh, in_width, in_height, out_width, out_height);
- arbitrary_interpolator_t interpolator(inverted, dist);
- span_gen_t span_gen(input_accessor, interpolator, filter);
- span_conv_t span_conv(span_gen, conv_alpha);
- int_renderer_t int_renderer(renderer, span_alloc, span_conv);
- agg::render_scanlines(rasterizer, scanline, int_renderer);
- }
- }
-}
-
-#endif /* RESAMPLE_H */
diff --git a/contrib/python/matplotlib/py2/src/_image_wrapper.cpp b/contrib/python/matplotlib/py2/src/_image_wrapper.cpp
deleted file mode 100644
index ee0bfe84c7..0000000000
--- a/contrib/python/matplotlib/py2/src/_image_wrapper.cpp
+++ /dev/null
@@ -1,510 +0,0 @@
-#include "mplutils.h"
-#include "_image_resample.h"
-#include "_image.h"
-#include "py_converters.h"
-
-
-#ifndef NPY_1_7_API_VERSION
-#define NPY_ARRAY_C_CONTIGUOUS NPY_C_CONTIGUOUS
-#endif
-
-
-/**********************************************************************
- * Free functions
- * */
-
-const char* image_resample__doc__ =
-"resample(input_array, output_array, matrix, interpolation=NEAREST, alpha=1.0, norm=0, radius=1)\n\n"
-
-"Resample input_array, blending it in-place into output_array, using an\n"
-"affine transformation.\n\n"
-
-"Parameters\n"
-"----------\n"
-"input_array : 2-d or 3-d Numpy array of float, double or uint8\n"
-" If 2-d, the image is grayscale. If 3-d, the image must be of size\n"
-" 4 in the last dimension and represents RGBA data.\n\n"
-
-"output_array : 2-d or 3-d Numpy array of float, double or uint8\n"
-" The dtype and number of dimensions must match `input_array`.\n\n"
-
-"transform : matplotlib.transforms.Transform instance\n"
-" The transformation from the input array to the output\n"
-" array.\n\n"
-
-"interpolation : int, optional\n"
-" The interpolation method. Must be one of the following constants\n"
-" defined in this module:\n\n"
-
-" NEAREST (default), BILINEAR, BICUBIC, SPLINE16, SPLINE36,\n"
-" HANNING, HAMMING, HERMITE, KAISER, QUADRIC, CATROM, GAUSSIAN,\n"
-" BESSEL, MITCHELL, SINC, LANCZOS, BLACKMAN\n\n"
-
-"resample : bool, optional\n"
-" When `True`, use a full resampling method. When `False`, only\n"
-" resample when the output image is larger than the input image.\n\n"
-
-"alpha : float, optional\n"
-" The level of transparency to apply. 1.0 is completely opaque.\n"
-" 0.0 is completely transparent.\n\n"
-
-"norm : float, optional\n"
-" The norm for the interpolation function. Default is 0.\n\n"
-
-"radius: float, optional\n"
-" The radius of the kernel, if method is SINC, LANCZOS or BLACKMAN.\n"
-" Default is 1.\n";
-
-
-static PyArrayObject *
-_get_transform_mesh(PyObject *py_affine, npy_intp *dims)
-{
- /* TODO: Could we get away with float, rather than double, arrays here? */
-
- /* Given a non-affine transform object, create a mesh that maps
- every pixel in the output image to the input image. This is used
- as a lookup table during the actual resampling. */
-
- PyObject *py_inverse = NULL;
- npy_intp out_dims[3];
-
- out_dims[0] = dims[0] * dims[1];
- out_dims[1] = 2;
-
- py_inverse = PyObject_CallMethod(
- py_affine, (char *)"inverted", (char *)"", NULL);
- if (py_inverse == NULL) {
- return NULL;
- }
-
- numpy::array_view<double, 2> input_mesh(out_dims);
- double *p = (double *)input_mesh.data();
-
- for (npy_intp y = 0; y < dims[0]; ++y) {
- for (npy_intp x = 0; x < dims[1]; ++x) {
- *p++ = (double)x;
- *p++ = (double)y;
- }
- }
-
- PyObject *output_mesh =
- PyObject_CallMethod(
- py_inverse, (char *)"transform", (char *)"O",
- (char *)input_mesh.pyobj(), NULL);
-
- Py_DECREF(py_inverse);
-
- if (output_mesh == NULL) {
- return NULL;
- }
-
- PyArrayObject *output_mesh_array =
- (PyArrayObject *)PyArray_ContiguousFromAny(
- output_mesh, NPY_DOUBLE, 2, 2);
-
- Py_DECREF(output_mesh);
-
- if (output_mesh_array == NULL) {
- return NULL;
- }
-
- return output_mesh_array;
-}
-
-
-static PyObject *
-image_resample(PyObject *self, PyObject* args, PyObject *kwargs)
-{
- PyObject *py_input_array = NULL;
- PyObject *py_output_array = NULL;
- PyObject *py_transform = NULL;
- resample_params_t params;
- int resample_;
-
- PyArrayObject *input_array = NULL;
- PyArrayObject *output_array = NULL;
- PyArrayObject *transform_mesh_array = NULL;
-
- params.transform_mesh = NULL;
-
- const char *kwlist[] = {
- "input_array", "output_array", "transform", "interpolation",
- "resample", "alpha", "norm", "radius", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kwargs, "OOO|iiddd:resample", (char **)kwlist,
- &py_input_array, &py_output_array, &py_transform,
- &params.interpolation, &resample_, &params.alpha, &params.norm,
- &params.radius)) {
- return NULL;
- }
-
- if (params.interpolation < 0 || params.interpolation >= _n_interpolation) {
- PyErr_Format(PyExc_ValueError, "invalid interpolation value %d",
- params.interpolation);
- goto error;
- }
-
- params.resample = (resample_ != 0);
-
- input_array = (PyArrayObject *)PyArray_FromAny(
- py_input_array, NULL, 2, 3, NPY_ARRAY_C_CONTIGUOUS, NULL);
- if (input_array == NULL) {
- goto error;
- }
-
- output_array = (PyArrayObject *)PyArray_FromAny(
- py_output_array, NULL, 2, 3, NPY_ARRAY_C_CONTIGUOUS, NULL);
- if (output_array == NULL) {
- goto error;
- }
-
- if (py_transform == NULL || py_transform == Py_None) {
- params.is_affine = true;
- } else {
- PyObject *py_is_affine;
- int py_is_affine2;
- py_is_affine = PyObject_GetAttrString(py_transform, "is_affine");
- if (py_is_affine == NULL) {
- goto error;
- }
-
- py_is_affine2 = PyObject_IsTrue(py_is_affine);
- Py_DECREF(py_is_affine);
-
- if (py_is_affine2 == -1) {
- goto error;
- } else if (py_is_affine2) {
- if (!convert_trans_affine(py_transform, &params.affine)) {
- goto error;
- }
- params.is_affine = true;
- } else {
- transform_mesh_array = _get_transform_mesh(
- py_transform, PyArray_DIMS(output_array));
- if (transform_mesh_array == NULL) {
- goto error;
- }
- params.transform_mesh = (double *)PyArray_DATA(transform_mesh_array);
- params.is_affine = false;
- }
- }
-
- if (PyArray_NDIM(input_array) != PyArray_NDIM(output_array)) {
- PyErr_Format(
- PyExc_ValueError,
- "Mismatched number of dimensions. Got %d and %d.",
- PyArray_NDIM(input_array), PyArray_NDIM(output_array));
- goto error;
- }
-
- if (PyArray_TYPE(input_array) != PyArray_TYPE(output_array)) {
- PyErr_SetString(PyExc_ValueError, "Mismatched types");
- goto error;
- }
-
- if (PyArray_NDIM(input_array) == 3) {
- if (PyArray_DIM(output_array, 2) != 4) {
- PyErr_SetString(
- PyExc_ValueError,
- "Output array must be RGBA");
- goto error;
- }
-
- if (PyArray_DIM(input_array, 2) == 4) {
- switch(PyArray_TYPE(input_array)) {
- case NPY_BYTE:
- case NPY_UINT8:
- Py_BEGIN_ALLOW_THREADS
- resample(
- (agg::rgba8 *)PyArray_DATA(input_array),
- PyArray_DIM(input_array, 1),
- PyArray_DIM(input_array, 0),
- (agg::rgba8 *)PyArray_DATA(output_array),
- PyArray_DIM(output_array, 1),
- PyArray_DIM(output_array, 0),
- params);
- Py_END_ALLOW_THREADS
- break;
- case NPY_UINT16:
- case NPY_INT16:
- Py_BEGIN_ALLOW_THREADS
- resample(
- (agg::rgba16 *)PyArray_DATA(input_array),
- PyArray_DIM(input_array, 1),
- PyArray_DIM(input_array, 0),
- (agg::rgba16 *)PyArray_DATA(output_array),
- PyArray_DIM(output_array, 1),
- PyArray_DIM(output_array, 0),
- params);
- Py_END_ALLOW_THREADS
- break;
- case NPY_FLOAT32:
- Py_BEGIN_ALLOW_THREADS
- resample(
- (agg::rgba32 *)PyArray_DATA(input_array),
- PyArray_DIM(input_array, 1),
- PyArray_DIM(input_array, 0),
- (agg::rgba32 *)PyArray_DATA(output_array),
- PyArray_DIM(output_array, 1),
- PyArray_DIM(output_array, 0),
- params);
- Py_END_ALLOW_THREADS
- break;
- case NPY_FLOAT64:
- Py_BEGIN_ALLOW_THREADS
- resample(
- (agg::rgba64 *)PyArray_DATA(input_array),
- PyArray_DIM(input_array, 1),
- PyArray_DIM(input_array, 0),
- (agg::rgba64 *)PyArray_DATA(output_array),
- PyArray_DIM(output_array, 1),
- PyArray_DIM(output_array, 0),
- params);
- Py_END_ALLOW_THREADS
- break;
- default:
- PyErr_SetString(
- PyExc_ValueError,
- "3-dimensional arrays must be of dtype unsigned byte, "
- "unsigned short, float32 or float64");
- goto error;
- }
- } else {
- PyErr_Format(
- PyExc_ValueError,
- "If 3-dimensional, array must be RGBA. Got %" NPY_INTP_FMT " planes.",
- PyArray_DIM(input_array, 2));
- goto error;
- }
- } else { // NDIM == 2
- switch (PyArray_TYPE(input_array)) {
- case NPY_DOUBLE:
- Py_BEGIN_ALLOW_THREADS
- resample(
- (double *)PyArray_DATA(input_array),
- PyArray_DIM(input_array, 1),
- PyArray_DIM(input_array, 0),
- (double *)PyArray_DATA(output_array),
- PyArray_DIM(output_array, 1),
- PyArray_DIM(output_array, 0),
- params);
- Py_END_ALLOW_THREADS
- break;
- case NPY_FLOAT:
- Py_BEGIN_ALLOW_THREADS
- resample(
- (float *)PyArray_DATA(input_array),
- PyArray_DIM(input_array, 1),
- PyArray_DIM(input_array, 0),
- (float *)PyArray_DATA(output_array),
- PyArray_DIM(output_array, 1),
- PyArray_DIM(output_array, 0),
- params);
- Py_END_ALLOW_THREADS
- break;
- case NPY_UINT8:
- case NPY_BYTE:
- Py_BEGIN_ALLOW_THREADS
- resample(
- (unsigned char *)PyArray_DATA(input_array),
- PyArray_DIM(input_array, 1),
- PyArray_DIM(input_array, 0),
- (unsigned char *)PyArray_DATA(output_array),
- PyArray_DIM(output_array, 1),
- PyArray_DIM(output_array, 0),
- params);
- Py_END_ALLOW_THREADS
- break;
- case NPY_UINT16:
- case NPY_INT16:
- Py_BEGIN_ALLOW_THREADS
- resample(
- (unsigned short *)PyArray_DATA(input_array),
- PyArray_DIM(input_array, 1),
- PyArray_DIM(input_array, 0),
- (unsigned short *)PyArray_DATA(output_array),
- PyArray_DIM(output_array, 1),
- PyArray_DIM(output_array, 0),
- params);
- Py_END_ALLOW_THREADS
- break;
- default:
- PyErr_SetString(PyExc_ValueError, "Unsupported dtype");
- goto error;
- }
- }
-
- Py_DECREF(input_array);
- Py_XDECREF(transform_mesh_array);
- return (PyObject *)output_array;
-
- error:
- Py_XDECREF(input_array);
- Py_XDECREF(output_array);
- Py_XDECREF(transform_mesh_array);
- return NULL;
-}
-
-
-const char *image_pcolor__doc__ =
- "pcolor(x, y, data, rows, cols, bounds)\n"
- "\n"
- "Generate a pseudo-color image from data on a non-uniform grid using\n"
- "nearest neighbour or linear interpolation.\n"
- "bounds = (x_min, x_max, y_min, y_max)\n"
- "interpolation = NEAREST or BILINEAR \n";
-
-static PyObject *image_pcolor(PyObject *self, PyObject *args, PyObject *kwds)
-{
- numpy::array_view<const float, 1> x;
- numpy::array_view<const float, 1> y;
- numpy::array_view<const agg::int8u, 3> d;
- npy_intp rows, cols;
- float bounds[4];
- int interpolation;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&nn(ffff)i:pcolor",
- &x.converter,
- &x,
- &y.converter,
- &y,
- &d.converter_contiguous,
- &d,
- &rows,
- &cols,
- &bounds[0],
- &bounds[1],
- &bounds[2],
- &bounds[3],
- &interpolation)) {
- return NULL;
- }
-
- npy_intp dim[3] = {rows, cols, 4};
- numpy::array_view<const agg::int8u, 3> output(dim);
-
- CALL_CPP("pcolor", (pcolor(x, y, d, rows, cols, bounds, interpolation, output)));
-
- return output.pyobj();
-}
-
-const char *image_pcolor2__doc__ =
- "pcolor2(x, y, data, rows, cols, bounds, bg)\n"
- "\n"
- "Generate a pseudo-color image from data on a non-uniform grid\n"
- "specified by its cell boundaries.\n"
- "bounds = (x_left, x_right, y_bot, y_top)\n"
- "bg = ndarray of 4 uint8 representing background rgba\n";
-
-static PyObject *image_pcolor2(PyObject *self, PyObject *args, PyObject *kwds)
-{
- numpy::array_view<const double, 1> x;
- numpy::array_view<const double, 1> y;
- numpy::array_view<const agg::int8u, 3> d;
- npy_intp rows, cols;
- float bounds[4];
- numpy::array_view<const agg::int8u, 1> bg;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&nn(ffff)O&:pcolor2",
- &x.converter_contiguous,
- &x,
- &y.converter_contiguous,
- &y,
- &d.converter_contiguous,
- &d,
- &rows,
- &cols,
- &bounds[0],
- &bounds[1],
- &bounds[2],
- &bounds[3],
- &bg.converter,
- &bg)) {
- return NULL;
- }
-
- npy_intp dim[3] = {rows, cols, 4};
- numpy::array_view<const agg::int8u, 3> output(dim);
-
- CALL_CPP("pcolor2", (pcolor2(x, y, d, rows, cols, bounds, bg, output)));
-
- return output.pyobj();
-}
-
-static PyMethodDef module_functions[] = {
- {"resample", (PyCFunction)image_resample, METH_VARARGS|METH_KEYWORDS, image_resample__doc__},
- {"pcolor", (PyCFunction)image_pcolor, METH_VARARGS, image_pcolor__doc__},
- {"pcolor2", (PyCFunction)image_pcolor2, METH_VARARGS, image_pcolor2__doc__},
- {NULL}
-};
-
-extern "C" {
-
-#if PY3K
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_image",
- NULL,
- 0,
- module_functions,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit__image(void)
-
-#else
-#define INITERROR return
-
-PyMODINIT_FUNC init_image(void)
-#endif
-
-{
- PyObject *m;
-
-#if PY3K
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("_image", module_functions, NULL);
-#endif
-
- if (m == NULL) {
- INITERROR;
- }
-
- if (PyModule_AddIntConstant(m, "NEAREST", NEAREST) ||
- PyModule_AddIntConstant(m, "BILINEAR", BILINEAR) ||
- PyModule_AddIntConstant(m, "BICUBIC", BICUBIC) ||
- PyModule_AddIntConstant(m, "SPLINE16", SPLINE16) ||
- PyModule_AddIntConstant(m, "SPLINE36", SPLINE36) ||
- PyModule_AddIntConstant(m, "HANNING", HANNING) ||
- PyModule_AddIntConstant(m, "HAMMING", HAMMING) ||
- PyModule_AddIntConstant(m, "HERMITE", HERMITE) ||
- PyModule_AddIntConstant(m, "KAISER", KAISER) ||
- PyModule_AddIntConstant(m, "QUADRIC", QUADRIC) ||
- PyModule_AddIntConstant(m, "CATROM", CATROM) ||
- PyModule_AddIntConstant(m, "GAUSSIAN", GAUSSIAN) ||
- PyModule_AddIntConstant(m, "BESSEL", BESSEL) ||
- PyModule_AddIntConstant(m, "MITCHELL", MITCHELL) ||
- PyModule_AddIntConstant(m, "SINC", SINC) ||
- PyModule_AddIntConstant(m, "LANCZOS", LANCZOS) ||
- PyModule_AddIntConstant(m, "BLACKMAN", BLACKMAN) ||
- PyModule_AddIntConstant(m, "_n_interpolation", _n_interpolation)) {
- INITERROR;
- }
-
- import_array();
-
-#if PY3K
- return m;
-#endif
-}
-
-} // extern "C"
diff --git a/contrib/python/matplotlib/py2/src/_macosx.m b/contrib/python/matplotlib/py2/src/_macosx.m
deleted file mode 100644
index 8f44f1eb0c..0000000000
--- a/contrib/python/matplotlib/py2/src/_macosx.m
+++ /dev/null
@@ -1,3174 +0,0 @@
-#include <Cocoa/Cocoa.h>
-#include <ApplicationServices/ApplicationServices.h>
-#include <sys/socket.h>
-#include <Python.h>
-
-#define PYOSINPUTHOOK_REPETITIVE 1 /* Remove this once Python is fixed */
-
-#if PY_MAJOR_VERSION >= 3
-#define PY3K 1
-#else
-#define PY3K 0
-#endif
-
-/* Proper way to check for the OS X version we are compiling for, from
- http://developer.apple.com/documentation/DeveloperTools/Conceptual/cross_development */
-#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
-#define COMPILING_FOR_10_6
-#endif
-#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
-#define COMPILING_FOR_10_7
-#endif
-#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 10100
-#define COMPILING_FOR_10_10
-#endif
-
-
-/* CGFloat was defined in Mac OS X 10.5 */
-#ifndef CGFLOAT_DEFINED
-#define CGFloat float
-#endif
-
-
-/* Various NSApplicationDefined event subtypes */
-#define STOP_EVENT_LOOP 2
-#define WINDOW_CLOSING 3
-
-
-/* Keep track of number of windows present
- Needed to know when to stop the NSApp */
-static long FigureWindowCount = 0;
-
-/* -------------------------- Helper function ---------------------------- */
-
-static void
-_stdin_callback(CFReadStreamRef stream, CFStreamEventType eventType, void* info)
-{
- CFRunLoopRef runloop = info;
- CFRunLoopStop(runloop);
-}
-
-static int sigint_fd = -1;
-
-static void _sigint_handler(int sig)
-{
- const char c = 'i';
- write(sigint_fd, &c, 1);
-}
-
-static void _sigint_callback(CFSocketRef s,
- CFSocketCallBackType type,
- CFDataRef address,
- const void * data,
- void *info)
-{
- char c;
- int* interrupted = info;
- CFSocketNativeHandle handle = CFSocketGetNative(s);
- CFRunLoopRef runloop = CFRunLoopGetCurrent();
- read(handle, &c, 1);
- *interrupted = 1;
- CFRunLoopStop(runloop);
-}
-
-static CGEventRef _eventtap_callback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon)
-{
- CFRunLoopRef runloop = refcon;
- CFRunLoopStop(runloop);
- return event;
-}
-
-static int wait_for_stdin(void)
-{
- int interrupted = 0;
- const UInt8 buffer[] = "/dev/fd/0";
- const CFIndex n = (CFIndex)strlen((char*)buffer);
- CFRunLoopRef runloop = CFRunLoopGetCurrent();
- CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
- buffer,
- n,
- false);
- CFReadStreamRef stream = CFReadStreamCreateWithFile(kCFAllocatorDefault,
- url);
- CFRelease(url);
-
- CFReadStreamOpen(stream);
-#ifdef PYOSINPUTHOOK_REPETITIVE
- if (!CFReadStreamHasBytesAvailable(stream))
- /* This is possible because of how PyOS_InputHook is called from Python */
- {
-#endif
- int error;
- int channel[2];
- CFSocketRef sigint_socket = NULL;
- PyOS_sighandler_t py_sigint_handler = NULL;
- CFStreamClientContext clientContext = {0, NULL, NULL, NULL, NULL};
- clientContext.info = runloop;
- CFReadStreamSetClient(stream,
- kCFStreamEventHasBytesAvailable,
- _stdin_callback,
- &clientContext);
- CFReadStreamScheduleWithRunLoop(stream, runloop, kCFRunLoopDefaultMode);
- error = socketpair(AF_UNIX, SOCK_STREAM, 0, channel);
- if (error==0)
- {
- CFSocketContext context;
- context.version = 0;
- context.info = &interrupted;
- context.retain = NULL;
- context.release = NULL;
- context.copyDescription = NULL;
- fcntl(channel[0], F_SETFL, O_WRONLY | O_NONBLOCK);
- sigint_socket = CFSocketCreateWithNative(
- kCFAllocatorDefault,
- channel[1],
- kCFSocketReadCallBack,
- _sigint_callback,
- &context);
- if (sigint_socket)
- {
- CFRunLoopSourceRef source;
- source = CFSocketCreateRunLoopSource(kCFAllocatorDefault,
- sigint_socket,
- 0);
- CFRelease(sigint_socket);
- if (source)
- {
- CFRunLoopAddSource(runloop, source, kCFRunLoopDefaultMode);
- CFRelease(source);
- sigint_fd = channel[0];
- py_sigint_handler = PyOS_setsig(SIGINT, _sigint_handler);
- }
- }
- }
-
- NSEvent* event;
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- while (true) {
- while (true) {
- event = [NSApp nextEventMatchingMask: NSAnyEventMask
- untilDate: [NSDate distantPast]
- inMode: NSDefaultRunLoopMode
- dequeue: YES];
- if (!event) break;
- [NSApp sendEvent: event];
- }
- CFRunLoopRun();
- if (interrupted || CFReadStreamHasBytesAvailable(stream)) break;
- }
- [pool release];
-
- if (py_sigint_handler) PyOS_setsig(SIGINT, py_sigint_handler);
- CFReadStreamUnscheduleFromRunLoop(stream,
- runloop,
- kCFRunLoopCommonModes);
- if (sigint_socket) CFSocketInvalidate(sigint_socket);
- if (error==0) {
- close(channel[0]);
- close(channel[1]);
- }
-#ifdef PYOSINPUTHOOK_REPETITIVE
- }
-#endif
- CFReadStreamClose(stream);
- CFRelease(stream);
- if (interrupted) {
- errno = EINTR;
- raise(SIGINT);
- return -1;
- }
- return 1;
-}
-
-/* ---------------------------- Cocoa classes ---------------------------- */
-
-@interface WindowServerConnectionManager : NSObject
-{
-}
-+ (WindowServerConnectionManager*)sharedManager;
-- (void)launch:(NSNotification*)notification;
-@end
-
-@interface Window : NSWindow
-{ PyObject* manager;
-}
-- (Window*)initWithContentRect:(NSRect)rect styleMask:(unsigned int)mask backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation withManager: (PyObject*)theManager;
-- (NSRect)constrainFrameRect:(NSRect)rect toScreen:(NSScreen*)screen;
-- (BOOL)closeButtonPressed;
-- (void)dealloc;
-@end
-
-@interface ToolWindow : NSWindow
-{
-}
-- (ToolWindow*)initWithContentRect:(NSRect)rect master:(NSWindow*)window;
-- (void)masterCloses:(NSNotification*)notification;
-- (void)close;
-@end
-
-#ifdef COMPILING_FOR_10_6
-@interface View : NSView <NSWindowDelegate>
-#else
-@interface View : NSView
-#endif
-{ PyObject* canvas;
- NSRect rubberband;
- BOOL inside;
- NSTrackingRectTag tracking;
- @public double device_scale;
-}
-- (void)dealloc;
-- (void)drawRect:(NSRect)rect;
-- (void)windowDidResize:(NSNotification*)notification;
-- (View*)initWithFrame:(NSRect)rect;
-- (void)setCanvas: (PyObject*)newCanvas;
-- (void)windowWillClose:(NSNotification*)notification;
-- (BOOL)windowShouldClose:(NSNotification*)notification;
-- (BOOL)isFlipped;
-- (void)mouseEntered:(NSEvent*)event;
-- (void)mouseExited:(NSEvent*)event;
-- (void)mouseDown:(NSEvent*)event;
-- (void)mouseUp:(NSEvent*)event;
-- (void)mouseDragged:(NSEvent*)event;
-- (void)mouseMoved:(NSEvent*)event;
-- (void)rightMouseDown:(NSEvent*)event;
-- (void)rightMouseUp:(NSEvent*)event;
-- (void)rightMouseDragged:(NSEvent*)event;
-- (void)otherMouseDown:(NSEvent*)event;
-- (void)otherMouseUp:(NSEvent*)event;
-- (void)otherMouseDragged:(NSEvent*)event;
-- (void)setRubberband:(NSRect)rect;
-- (void)removeRubberband;
-- (const char*)convertKeyEvent:(NSEvent*)event;
-- (void)keyDown:(NSEvent*)event;
-- (void)keyUp:(NSEvent*)event;
-- (void)scrollWheel:(NSEvent *)event;
-- (BOOL)acceptsFirstResponder;
-//- (void)flagsChanged:(NSEvent*)event;
-@end
-
-@interface ScrollableButton : NSButton
-{
- SEL scrollWheelUpAction;
- SEL scrollWheelDownAction;
-}
-- (void)setScrollWheelUpAction:(SEL)action;
-- (void)setScrollWheelDownAction:(SEL)action;
-- (void)scrollWheel:(NSEvent *)event;
-@end
-
-@interface MenuItem: NSMenuItem
-{ int index;
-}
-+ (MenuItem*)menuItemWithTitle:(NSString*)title;
-+ (MenuItem*)menuItemSelectAll;
-+ (MenuItem*)menuItemInvertAll;
-+ (MenuItem*)menuItemForAxis:(int)i;
-- (void)toggle:(id)sender;
-- (void)selectAll:(id)sender;
-- (void)invertAll:(id)sender;
-- (int)index;
-@end
-
-/* ---------------------------- Python classes ---------------------------- */
-
-static CGFloat _get_device_scale(CGContextRef cr)
-{
- CGSize pixelSize = CGContextConvertSizeToDeviceSpace(cr, CGSizeMake(1, 1));
- return pixelSize.width;
-}
-
-typedef struct {
- PyObject_HEAD
- View* view;
-} FigureCanvas;
-
-static PyObject*
-FigureCanvas_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- FigureCanvas *self = (FigureCanvas*)type->tp_alloc(type, 0);
- if (!self) return NULL;
- self->view = [View alloc];
- return (PyObject*)self;
-}
-
-static int
-FigureCanvas_init(FigureCanvas *self, PyObject *args, PyObject *kwds)
-{
- int width;
- int height;
- if(!self->view)
- {
- PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL");
- return -1;
- }
-
- if(!PyArg_ParseTuple(args, "ii", &width, &height)) return -1;
-
- NSRect rect = NSMakeRect(0.0, 0.0, width, height);
- self->view = [self->view initWithFrame: rect];
- [self->view setCanvas: (PyObject*)self];
- return 0;
-}
-
-static void
-FigureCanvas_dealloc(FigureCanvas* self)
-{
- if (self->view)
- {
- [self->view setCanvas: NULL];
- [self->view release];
- }
- Py_TYPE(self)->tp_free((PyObject*)self);
-}
-
-static PyObject*
-FigureCanvas_repr(FigureCanvas* self)
-{
-#if PY3K
- return PyUnicode_FromFormat("FigureCanvas object %p wrapping NSView %p",
- (void*)self, (void*)(self->view));
-#else
- return PyString_FromFormat("FigureCanvas object %p wrapping NSView %p",
- (void*)self, (void*)(self->view));
-#endif
-}
-
-static PyObject*
-FigureCanvas_draw(FigureCanvas* self)
-{
- View* view = self->view;
-
- if(view) /* The figure may have been closed already */
- {
- /* Whereas drawRect creates its own autorelease pool, apparently
- * [view display] also needs one. Create and release it here. */
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [view display];
- [pool release];
- }
-
- Py_RETURN_NONE;
-}
-
-static PyObject*
-FigureCanvas_invalidate(FigureCanvas* self)
-{
- View* view = self->view;
- if(!view)
- {
- PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL");
- return NULL;
- }
- [view setNeedsDisplay: YES];
- Py_RETURN_NONE;
-}
-
-static PyObject*
-FigureCanvas_flush_events(FigureCanvas* self)
-{
- View* view = self->view;
- if(!view)
- {
- PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL");
- return NULL;
- }
- [view displayIfNeeded];
- Py_RETURN_NONE;
-}
-
-static PyObject*
-FigureCanvas_set_rubberband(FigureCanvas* self, PyObject *args)
-{
- View* view = self->view;
- int x0, y0, x1, y1;
- NSRect rubberband;
- if(!view)
- {
- PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL");
- return NULL;
- }
- if(!PyArg_ParseTuple(args, "iiii", &x0, &y0, &x1, &y1)) return NULL;
-
- x0 /= view->device_scale;
- x1 /= view->device_scale;
- y0 /= view->device_scale;
- y1 /= view->device_scale;
-
- if (x1 > x0)
- {
- rubberband.origin.x = x0;
- rubberband.size.width = x1 - x0;
- }
- else
- {
- rubberband.origin.x = x1;
- rubberband.size.width = x0 - x1;
- }
- if (y1 > y0)
- {
- rubberband.origin.y = y0;
- rubberband.size.height = y1 - y0;
- }
- else
- {
- rubberband.origin.y = y1;
- rubberband.size.height = y0 - y1;
- }
-
- [view setRubberband: rubberband];
- Py_RETURN_NONE;
-}
-
-static PyObject*
-FigureCanvas_remove_rubberband(FigureCanvas* self)
-{
- View* view = self->view;
- if(!view)
- {
- PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL");
- return NULL;
- }
- [view removeRubberband];
- Py_RETURN_NONE;
-}
-
-static NSImage* _read_ppm_image(PyObject* obj)
-{
- int width;
- int height;
- const char* data;
- int n;
- int i;
- NSBitmapImageRep* bitmap;
- unsigned char* bitmapdata;
-
- if (!obj) return NULL;
- if (!PyTuple_Check(obj)) return NULL;
- if (!PyArg_ParseTuple(obj, "iit#", &width, &height, &data, &n)) return NULL;
- if (width*height*3 != n) return NULL; /* RGB image uses 3 colors / pixel */
-
- bitmap = [[NSBitmapImageRep alloc]
- initWithBitmapDataPlanes: NULL
- pixelsWide: width
- pixelsHigh: height
- bitsPerSample: 8
- samplesPerPixel: 3
- hasAlpha: NO
- isPlanar: NO
- colorSpaceName: NSDeviceRGBColorSpace
- bitmapFormat: 0
- bytesPerRow: width*3
- bitsPerPixel: 24];
- if (!bitmap) return NULL;
- bitmapdata = [bitmap bitmapData];
- for (i = 0; i < n; i++) bitmapdata[i] = data[i];
-
- NSSize size = NSMakeSize(width, height);
- NSImage* image = [[NSImage alloc] initWithSize: size];
- if (image) [image addRepresentation: bitmap];
-
- [bitmap release];
-
- return image;
-}
-
-static PyObject*
-FigureCanvas_start_event_loop(FigureCanvas* self, PyObject* args, PyObject* keywords)
-{
- float timeout = 0.0;
-
- static char* kwlist[] = {"timeout", NULL};
- if(!PyArg_ParseTupleAndKeywords(args, keywords, "f", kwlist, &timeout))
- return NULL;
-
- int error;
- int interrupted = 0;
- int channel[2];
- CFSocketRef sigint_socket = NULL;
- PyOS_sighandler_t py_sigint_handler = NULL;
-
- CFRunLoopRef runloop = CFRunLoopGetCurrent();
-
- error = pipe(channel);
- if (error==0)
- {
- CFSocketContext context = {0, NULL, NULL, NULL, NULL};
- fcntl(channel[1], F_SETFL, O_WRONLY | O_NONBLOCK);
-
- context.info = &interrupted;
- sigint_socket = CFSocketCreateWithNative(kCFAllocatorDefault,
- channel[0],
- kCFSocketReadCallBack,
- _sigint_callback,
- &context);
- if (sigint_socket)
- {
- CFRunLoopSourceRef source;
- source = CFSocketCreateRunLoopSource(kCFAllocatorDefault,
- sigint_socket,
- 0);
- CFRelease(sigint_socket);
- if (source)
- {
- CFRunLoopAddSource(runloop, source, kCFRunLoopDefaultMode);
- CFRelease(source);
- sigint_fd = channel[1];
- py_sigint_handler = PyOS_setsig(SIGINT, _sigint_handler);
- }
- }
- else
- close(channel[0]);
- }
-
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSDate* date =
- (timeout > 0.0) ? [NSDate dateWithTimeIntervalSinceNow: timeout]
- : [NSDate distantFuture];
- while (true)
- { NSEvent* event = [NSApp nextEventMatchingMask: NSAnyEventMask
- untilDate: date
- inMode: NSDefaultRunLoopMode
- dequeue: YES];
- if (!event || [event type]==NSApplicationDefined) break;
- [NSApp sendEvent: event];
- }
- [pool release];
-
- if (py_sigint_handler) PyOS_setsig(SIGINT, py_sigint_handler);
-
- if (sigint_socket) CFSocketInvalidate(sigint_socket);
- if (error==0) close(channel[1]);
- if (interrupted) raise(SIGINT);
-
- Py_RETURN_NONE;
-}
-
-static PyObject*
-FigureCanvas_stop_event_loop(FigureCanvas* self)
-{
- NSEvent* event = [NSEvent otherEventWithType: NSApplicationDefined
- location: NSZeroPoint
- modifierFlags: 0
- timestamp: 0.0
- windowNumber: 0
- context: nil
- subtype: STOP_EVENT_LOOP
- data1: 0
- data2: 0];
- [NSApp postEvent: event atStart: true];
- Py_RETURN_NONE;
-}
-
-static PyMethodDef FigureCanvas_methods[] = {
- {"draw",
- (PyCFunction)FigureCanvas_draw,
- METH_NOARGS,
- "Draws the canvas."
- },
- {"invalidate",
- (PyCFunction)FigureCanvas_invalidate,
- METH_NOARGS,
- "Invalidates the canvas."
- },
- {"flush_events",
- (PyCFunction)FigureCanvas_flush_events,
- METH_NOARGS,
- "Flush the GUI events for the figure."
- },
- {"set_rubberband",
- (PyCFunction)FigureCanvas_set_rubberband,
- METH_VARARGS,
- "Specifies a new rubberband rectangle and invalidates it."
- },
- {"remove_rubberband",
- (PyCFunction)FigureCanvas_remove_rubberband,
- METH_NOARGS,
- "Removes the current rubberband rectangle."
- },
- {"start_event_loop",
- (PyCFunction)FigureCanvas_start_event_loop,
- METH_KEYWORDS | METH_VARARGS,
- "Runs the event loop until the timeout or until stop_event_loop is called.\n",
- },
- {"stop_event_loop",
- (PyCFunction)FigureCanvas_stop_event_loop,
- METH_NOARGS,
- "Stops the event loop that was started by start_event_loop.\n",
- },
- {NULL} /* Sentinel */
-};
-
-static char FigureCanvas_doc[] =
-"A FigureCanvas object wraps a Cocoa NSView object.\n";
-
-static PyTypeObject FigureCanvasType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_macosx.FigureCanvas", /*tp_name*/
- sizeof(FigureCanvas), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)FigureCanvas_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- (reprfunc)FigureCanvas_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
- FigureCanvas_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- FigureCanvas_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)FigureCanvas_init, /* tp_init */
- 0, /* tp_alloc */
- FigureCanvas_new, /* tp_new */
-};
-
-typedef struct {
- PyObject_HEAD
- Window* window;
-} FigureManager;
-
-static PyObject*
-FigureManager_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- Window* window = [Window alloc];
- if (!window) return NULL;
- FigureManager *self = (FigureManager*)type->tp_alloc(type, 0);
- if (!self)
- {
- [window release];
- return NULL;
- }
- self->window = window;
- ++FigureWindowCount;
- return (PyObject*)self;
-}
-
-static int
-FigureManager_init(FigureManager *self, PyObject *args, PyObject *kwds)
-{
- NSRect rect;
- Window* window;
- View* view;
- const char* title;
- PyObject* size;
- int width, height;
- PyObject* obj;
- FigureCanvas* canvas;
-
- if(!self->window)
- {
- PyErr_SetString(PyExc_RuntimeError, "NSWindow* is NULL");
- return -1;
- }
-
- if(!PyArg_ParseTuple(args, "Os", &obj, &title)) return -1;
-
- canvas = (FigureCanvas*)obj;
- view = canvas->view;
- if (!view) /* Something really weird going on */
- {
- PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL");
- return -1;
- }
-
- size = PyObject_CallMethod(obj, "get_width_height", "");
- if(!size) return -1;
- if(!PyArg_ParseTuple(size, "ii", &width, &height))
- { Py_DECREF(size);
- return -1;
- }
- Py_DECREF(size);
-
- rect.origin.x = 100;
- rect.origin.y = 350;
- rect.size.height = height;
- rect.size.width = width;
-
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- self->window = [self->window initWithContentRect: rect
- styleMask: NSTitledWindowMask
- | NSClosableWindowMask
- | NSResizableWindowMask
- | NSMiniaturizableWindowMask
- backing: NSBackingStoreBuffered
- defer: YES
- withManager: (PyObject*)self];
- window = self->window;
- [window setTitle: [NSString stringWithCString: title
- encoding: NSASCIIStringEncoding]];
-
- [window setAcceptsMouseMovedEvents: YES];
- [window setDelegate: view];
- [window makeFirstResponder: view];
- [[window contentView] addSubview: view];
-
- [pool release];
- return 0;
-}
-
-static PyObject*
-FigureManager_repr(FigureManager* self)
-{
-#if PY3K
- return PyUnicode_FromFormat("FigureManager object %p wrapping NSWindow %p",
- (void*) self, (void*)(self->window));
-#else
- return PyString_FromFormat("FigureManager object %p wrapping NSWindow %p",
- (void*) self, (void*)(self->window));
-#endif
-}
-
-static void
-FigureManager_dealloc(FigureManager* self)
-{
- Window* window = self->window;
- if(window)
- {
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [window close];
- [pool release];
- }
- Py_TYPE(self)->tp_free((PyObject*)self);
-}
-
-static PyObject*
-FigureManager_show(FigureManager* self)
-{
- Window* window = self->window;
- if(window)
- {
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [window makeKeyAndOrderFront: nil];
- [window orderFrontRegardless];
- [pool release];
- }
- Py_RETURN_NONE;
-}
-
-static PyObject*
-FigureManager_destroy(FigureManager* self)
-{
- Window* window = self->window;
- if(window)
- {
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [window close];
- [pool release];
- self->window = NULL;
- }
- Py_RETURN_NONE;
-}
-
-static PyObject*
-FigureManager_set_window_title(FigureManager* self,
- PyObject *args, PyObject *kwds)
-{
- char* title;
- if(!PyArg_ParseTuple(args, "es", "UTF-8", &title))
- return NULL;
-
- Window* window = self->window;
- if(window)
- {
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSString* ns_title = [[[NSString alloc]
- initWithCString: title
- encoding: NSUTF8StringEncoding] autorelease];
- [window setTitle: ns_title];
- [pool release];
- }
- PyMem_Free(title);
- Py_RETURN_NONE;
-}
-
-static PyObject*
-FigureManager_get_window_title(FigureManager* self)
-{
- Window* window = self->window;
- PyObject* result = NULL;
- if(window)
- {
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSString* title = [window title];
- if (title) {
- const char* cTitle = [title UTF8String];
- result = PyUnicode_FromString(cTitle);
- }
- [pool release];
- }
- if (result) {
- return result;
- } else {
- Py_RETURN_NONE;
- }
-}
-
-static PyMethodDef FigureManager_methods[] = {
- {"show",
- (PyCFunction)FigureManager_show,
- METH_NOARGS,
- "Shows the window associated with the figure manager."
- },
- {"destroy",
- (PyCFunction)FigureManager_destroy,
- METH_NOARGS,
- "Closes the window associated with the figure manager."
- },
- {"set_window_title",
- (PyCFunction)FigureManager_set_window_title,
- METH_VARARGS,
- "Sets the title of the window associated with the figure manager."
- },
- {"get_window_title",
- (PyCFunction)FigureManager_get_window_title,
- METH_NOARGS,
- "Returns the title of the window associated with the figure manager."
- },
- {NULL} /* Sentinel */
-};
-
-static char FigureManager_doc[] =
-"A FigureManager object wraps a Cocoa NSWindow object.\n";
-
-static PyTypeObject FigureManagerType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_macosx.FigureManager", /*tp_name*/
- sizeof(FigureManager), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)FigureManager_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- (reprfunc)FigureManager_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
- FigureManager_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- FigureManager_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)FigureManager_init, /* tp_init */
- 0, /* tp_alloc */
- FigureManager_new, /* tp_new */
-};
-
-@interface NavigationToolbarHandler : NSObject
-{ PyObject* toolbar;
-}
-- (NavigationToolbarHandler*)initWithToolbar:(PyObject*)toolbar;
--(void)left:(id)sender;
--(void)right:(id)sender;
--(void)up:(id)sender;
--(void)down:(id)sender;
--(void)zoominx:(id)sender;
--(void)zoominy:(id)sender;
--(void)zoomoutx:(id)sender;
--(void)zoomouty:(id)sender;
-@end
-
-typedef struct {
- PyObject_HEAD
- NSPopUpButton* menu;
- NavigationToolbarHandler* handler;
-} NavigationToolbar;
-
-@implementation NavigationToolbarHandler
-- (NavigationToolbarHandler*)initWithToolbar:(PyObject*)theToolbar
-{ [self init];
- toolbar = theToolbar;
- return self;
-}
-
--(void)left:(id)sender
-{ PyObject* result;
- PyGILState_STATE gstate;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(toolbar, "panx", "i", -1);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-}
-
--(void)right:(id)sender
-{ PyObject* result;
- PyGILState_STATE gstate;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(toolbar, "panx", "i", 1);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-}
-
--(void)up:(id)sender
-{ PyObject* result;
- PyGILState_STATE gstate;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(toolbar, "pany", "i", 1);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-}
-
--(void)down:(id)sender
-{ PyObject* result;
- PyGILState_STATE gstate;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(toolbar, "pany", "i", -1);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-}
-
--(void)zoominx:(id)sender
-{ PyObject* result;
- PyGILState_STATE gstate;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(toolbar, "zoomx", "i", 1);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-}
-
--(void)zoomoutx:(id)sender
-{ PyObject* result;
- PyGILState_STATE gstate;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(toolbar, "zoomx", "i", -1);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-}
-
--(void)zoominy:(id)sender
-{ PyObject* result;
- PyGILState_STATE gstate;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(toolbar, "zoomy", "i", 1);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-}
-
--(void)zoomouty:(id)sender
-{ PyObject* result;
- PyGILState_STATE gstate;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(toolbar, "zoomy", "i", -1);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-}
-
--(void)save_figure:(id)sender
-{ PyObject* result;
- PyGILState_STATE gstate;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(toolbar, "save_figure", "");
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-}
-@end
-
-static PyObject*
-NavigationToolbar_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- NavigationToolbarHandler* handler = [NavigationToolbarHandler alloc];
- if (!handler) return NULL;
- NavigationToolbar *self = (NavigationToolbar*)type->tp_alloc(type, 0);
- if (!self)
- { [handler release];
- return NULL;
- }
- self->handler = handler;
- return (PyObject*)self;
-}
-
-static int
-NavigationToolbar_init(NavigationToolbar *self, PyObject *args, PyObject *kwds)
-{
- int i;
- NSRect rect;
-
- const float smallgap = 2;
- const float biggap = 10;
- const int height = 32;
-
- PyObject* images;
- PyObject* obj;
-
- FigureCanvas* canvas;
- View* view;
-
- obj = PyObject_GetAttrString((PyObject*)self, "canvas");
- if (obj==NULL)
- {
- PyErr_SetString(PyExc_AttributeError, "Attempt to install toolbar for NULL canvas");
- return -1;
- }
- Py_DECREF(obj); /* Don't increase the reference count */
- if (!PyObject_IsInstance(obj, (PyObject*) &FigureCanvasType))
- {
- PyErr_SetString(PyExc_TypeError, "Attempt to install toolbar for object that is not a FigureCanvas");
- return -1;
- }
- canvas = (FigureCanvas*)obj;
- view = canvas->view;
- if(!view)
- {
- PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL");
- return -1;
- }
-
- if(!PyArg_ParseTuple(args, "O", &images)) return -1;
- if(!PyDict_Check(images)) return -1;
-
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSRect bounds = [view bounds];
- NSWindow* window = [view window];
-
- bounds.origin.y += height;
- [view setFrame: bounds];
-
- bounds.size.height += height;
- [window setContentSize: bounds.size];
-
- char* imagenames[9] = {"stock_left",
- "stock_right",
- "stock_zoom-in",
- "stock_zoom-out",
- "stock_up",
- "stock_down",
- "stock_zoom-in",
- "stock_zoom-out",
- "stock_save_as"};
-
- NSString* tooltips[9] = {
- @"Pan left with click or wheel mouse (bidirectional)",
- @"Pan right with click or wheel mouse (bidirectional)",
- @"Zoom In X (shrink the x axis limits) with click or wheel mouse (bidirectional)",
- @"Zoom Out X (expand the x axis limits) with click or wheel mouse (bidirectional)",
- @"Pan up with click or wheel mouse (bidirectional)",
- @"Pan down with click or wheel mouse (bidirectional)",
- @"Zoom in Y (shrink the y axis limits) with click or wheel mouse (bidirectional)",
- @"Zoom Out Y (expand the y axis limits) with click or wheel mouse (bidirectional)",
- @"Save the figure"};
-
- SEL actions[9] = {@selector(left:),
- @selector(right:),
- @selector(zoominx:),
- @selector(zoomoutx:),
- @selector(up:),
- @selector(down:),
- @selector(zoominy:),
- @selector(zoomouty:),
- @selector(save_figure:)};
-
- SEL scroll_actions[9][2] = {{@selector(left:), @selector(right:)},
- {@selector(left:), @selector(right:)},
- {@selector(zoominx:), @selector(zoomoutx:)},
- {@selector(zoominx:), @selector(zoomoutx:)},
- {@selector(up:), @selector(down:)},
- {@selector(up:), @selector(down:)},
- {@selector(zoominy:), @selector(zoomouty:)},
- {@selector(zoominy:), @selector(zoomouty:)},
- {nil,nil},
- };
-
-
- rect.size.width = 120;
- rect.size.height = 24;
- rect.origin.x = biggap;
- rect.origin.y = 0.5*(height - rect.size.height);
- self->menu = [[NSPopUpButton alloc] initWithFrame: rect
- pullsDown: YES];
- [self->menu setAutoenablesItems: NO];
- [[window contentView] addSubview: self->menu];
- [self->menu release];
- rect.origin.x += rect.size.width + biggap;
- rect.size.width = 24;
-
- self->handler = [self->handler initWithToolbar: (PyObject*)self];
- for (i = 0; i < 9; i++)
- {
- NSButton* button;
- SEL scrollWheelUpAction = scroll_actions[i][0];
- SEL scrollWheelDownAction = scroll_actions[i][1];
- if (scrollWheelUpAction && scrollWheelDownAction)
- {
- ScrollableButton* scrollable_button = [ScrollableButton alloc];
- [scrollable_button initWithFrame: rect];
- [scrollable_button setScrollWheelUpAction: scrollWheelUpAction];
- [scrollable_button setScrollWheelDownAction: scrollWheelDownAction];
- button = (NSButton*)scrollable_button;
- }
- else
- {
- button = [NSButton alloc];
- [button initWithFrame: rect];
- }
- PyObject* imagedata = PyDict_GetItemString(images, imagenames[i]);
- NSImage* image = _read_ppm_image(imagedata);
- [button setBezelStyle: NSShadowlessSquareBezelStyle];
- [button setButtonType: NSMomentaryLightButton];
- if(image)
- {
- [button setImage: image];
- [image release];
- }
- [button setToolTip: tooltips[i]];
- [button setTarget: self->handler];
- [button setAction: actions[i]];
- [[window contentView] addSubview: button];
- [button release];
- rect.origin.x += rect.size.width + smallgap;
- }
- [[window contentView] display];
- [pool release];
-
- return 0;
-}
-
-static void
-NavigationToolbar_dealloc(NavigationToolbar *self)
-{
- [self->handler release];
- Py_TYPE(self)->tp_free((PyObject*)self);
-}
-
-static PyObject*
-NavigationToolbar_repr(NavigationToolbar* self)
-{
-#if PY3K
- return PyUnicode_FromFormat("NavigationToolbar object %p", (void*)self);
-#else
- return PyString_FromFormat("NavigationToolbar object %p", (void*)self);
-#endif
-}
-
-static char NavigationToolbar_doc[] =
-"NavigationToolbar\n";
-
-static PyObject*
-NavigationToolbar_update (NavigationToolbar* self)
-{
- int n;
- NSPopUpButton* button = self->menu;
- if (!button)
- {
- PyErr_SetString(PyExc_RuntimeError, "Menu button is NULL");
- return NULL;
- }
-
- PyObject* canvas = PyObject_GetAttrString((PyObject*)self, "canvas");
- if (canvas==NULL)
- {
- PyErr_SetString(PyExc_AttributeError, "Failed to find canvas");
- return NULL;
- }
- Py_DECREF(canvas); /* Don't keep a reference here */
- PyObject* figure = PyObject_GetAttrString(canvas, "figure");
- if (figure==NULL)
- {
- PyErr_SetString(PyExc_AttributeError, "Failed to find figure");
- return NULL;
- }
- Py_DECREF(figure); /* Don't keep a reference here */
- PyObject* axes = PyObject_GetAttrString(figure, "axes");
- if (axes==NULL)
- {
- PyErr_SetString(PyExc_AttributeError, "Failed to find figure axes");
- return NULL;
- }
- Py_DECREF(axes); /* Don't keep a reference here */
- if (!PyList_Check(axes))
- {
- PyErr_SetString(PyExc_TypeError, "Figure axes is not a list");
- return NULL;
- }
- n = PyList_GET_SIZE(axes);
-
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- [button removeAllItems];
-
- NSMenu* menu = [button menu];
- [menu addItem: [MenuItem menuItemWithTitle: @"Axes"]];
-
- if (n==0)
- {
- [button setEnabled: NO];
- }
- else
- {
- int i;
- [menu addItem: [MenuItem menuItemSelectAll]];
- [menu addItem: [MenuItem menuItemInvertAll]];
- [menu addItem: [NSMenuItem separatorItem]];
- for (i = 0; i < n; i++)
- {
- [menu addItem: [MenuItem menuItemForAxis: i]];
- }
- [button setEnabled: YES];
- }
- [pool release];
- Py_RETURN_NONE;
-}
-
-static PyObject*
-NavigationToolbar_get_active (NavigationToolbar* self)
-{
- NSPopUpButton* button = self->menu;
- if (!button)
- {
- PyErr_SetString(PyExc_RuntimeError, "Menu button is NULL");
- return NULL;
- }
- NSMenu* menu = [button menu];
- NSArray* items = [menu itemArray];
- size_t n = [items count];
- int* states = calloc(n, sizeof(int));
- if (!states)
- {
- PyErr_SetString(PyExc_RuntimeError, "calloc failed");
- return NULL;
- }
- int i;
- unsigned int m = 0;
- NSEnumerator* enumerator = [items objectEnumerator];
- MenuItem* item;
- while ((item = [enumerator nextObject]))
- {
- if ([item isSeparatorItem]) continue;
- i = [item index];
- if (i < 0) continue;
- if ([item state]==NSOnState)
- {
- states[i] = 1;
- m++;
- }
- }
- Py_ssize_t list_index = 0;
- PyObject* list = PyList_New(m);
-
- size_t state_index;
- for (state_index = 0; state_index < n; state_index++)
- {
- if(states[state_index]==1)
- {
- PyList_SET_ITEM(list, list_index++, PyLong_FromSize_t(state_index));
- }
- }
- free(states);
- return list;
-}
-
-static PyMethodDef NavigationToolbar_methods[] = {
- {"update",
- (PyCFunction)NavigationToolbar_update,
- METH_NOARGS,
- "Updates the toolbar menu."
- },
- {"get_active",
- (PyCFunction)NavigationToolbar_get_active,
- METH_NOARGS,
- "Returns a list of integers identifying which items in the menu are selected."
- },
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject NavigationToolbarType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_macosx.NavigationToolbar", /*tp_name*/
- sizeof(NavigationToolbar), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)NavigationToolbar_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- (reprfunc)NavigationToolbar_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
- NavigationToolbar_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- NavigationToolbar_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)NavigationToolbar_init, /* tp_init */
- 0, /* tp_alloc */
- NavigationToolbar_new, /* tp_new */
-};
-
-@interface NavigationToolbar2Handler : NSObject
-{ PyObject* toolbar;
- NSButton* panbutton;
- NSButton* zoombutton;
-}
-- (NavigationToolbar2Handler*)initWithToolbar:(PyObject*)toolbar;
-- (void)installCallbacks:(SEL[7])actions forButtons: (NSButton*[7])buttons;
-- (void)home:(id)sender;
-- (void)back:(id)sender;
-- (void)forward:(id)sender;
-- (void)pan:(id)sender;
-- (void)zoom:(id)sender;
-- (void)configure_subplots:(id)sender;
-- (void)save_figure:(id)sender;
-@end
-
-typedef struct {
- PyObject_HEAD
- NSPopUpButton* menu;
- NSText* messagebox;
- NavigationToolbar2Handler* handler;
-} NavigationToolbar2;
-
-@implementation NavigationToolbar2Handler
-- (NavigationToolbar2Handler*)initWithToolbar:(PyObject*)theToolbar
-{ [self init];
- toolbar = theToolbar;
- return self;
-}
-
-- (void)installCallbacks:(SEL[7])actions forButtons: (NSButton*[7])buttons
-{
- int i;
- for (i = 0; i < 7; i++)
- {
- SEL action = actions[i];
- NSButton* button = buttons[i];
- [button setTarget: self];
- [button setAction: action];
- if (action==@selector(pan:)) panbutton = button;
- if (action==@selector(zoom:)) zoombutton = button;
- }
-}
-
--(void)home:(id)sender
-{ PyObject* result;
- PyGILState_STATE gstate;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(toolbar, "home", "");
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-}
-
--(void)back:(id)sender
-{ PyObject* result;
- PyGILState_STATE gstate;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(toolbar, "back", "");
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-}
-
--(void)forward:(id)sender
-{ PyObject* result;
- PyGILState_STATE gstate;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(toolbar, "forward", "");
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-}
-
--(void)pan:(id)sender
-{ PyObject* result;
- PyGILState_STATE gstate;
- if ([sender state])
- {
- if (zoombutton) [zoombutton setState: NO];
- }
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(toolbar, "pan", "");
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-}
-
--(void)zoom:(id)sender
-{ PyObject* result;
- PyGILState_STATE gstate;
- if ([sender state])
- {
- if (panbutton) [panbutton setState: NO];
- }
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(toolbar, "zoom", "");
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-}
-
--(void)configure_subplots:(id)sender
-{ PyObject* canvas;
- View* view;
- PyObject* size;
- NSRect rect;
- int width, height;
-
- rect.origin.x = 100;
- rect.origin.y = 350;
- PyGILState_STATE gstate = PyGILState_Ensure();
- PyObject* master = PyObject_GetAttrString(toolbar, "canvas");
- if (master==nil)
- {
- PyErr_Print();
- PyGILState_Release(gstate);
- return;
- }
- canvas = PyObject_CallMethod(toolbar, "prepare_configure_subplots", "");
- if(!canvas)
- {
- PyErr_Print();
- Py_DECREF(master);
- PyGILState_Release(gstate);
- return;
- }
-
- view = ((FigureCanvas*)canvas)->view;
- if (!view) /* Something really weird going on */
- {
- PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL");
- PyErr_Print();
- Py_DECREF(canvas);
- Py_DECREF(master);
- PyGILState_Release(gstate);
- return;
- }
-
- size = PyObject_CallMethod(canvas, "get_width_height", "");
- Py_DECREF(canvas);
- if(!size)
- {
- PyErr_Print();
- Py_DECREF(master);
- PyGILState_Release(gstate);
- return;
- }
-
- int ok = PyArg_ParseTuple(size, "ii", &width, &height);
- Py_DECREF(size);
- if (!ok)
- {
- PyErr_Print();
- Py_DECREF(master);
- PyGILState_Release(gstate);
- return;
- }
-
- NSWindow* mw = [((FigureCanvas*)master)->view window];
- Py_DECREF(master);
- PyGILState_Release(gstate);
-
- rect.size.width = width;
- rect.size.height = height;
-
- ToolWindow* window = [ [ToolWindow alloc] initWithContentRect: rect
- master: mw];
- [window setContentView: view];
- [view release];
- [window makeKeyAndOrderFront: nil];
-}
-
--(void)save_figure:(id)sender
-{ PyObject* result;
- PyGILState_STATE gstate;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(toolbar, "save_figure", "");
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-}
-@end
-
-static PyObject*
-NavigationToolbar2_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- NavigationToolbar2Handler* handler = [NavigationToolbar2Handler alloc];
- if (!handler) return NULL;
- NavigationToolbar2 *self = (NavigationToolbar2*)type->tp_alloc(type, 0);
- if (!self)
- {
- [handler release];
- return NULL;
- }
- self->handler = handler;
- return (PyObject*)self;
-}
-
-static int
-NavigationToolbar2_init(NavigationToolbar2 *self, PyObject *args, PyObject *kwds)
-{
- PyObject* obj;
- FigureCanvas* canvas;
- View* view;
-
- int i;
- NSRect rect;
- NSSize size;
- NSSize scale;
-
- const float gap = 2;
- const int height = 36;
- const int imagesize = 24;
-
- const char* basedir;
-
- obj = PyObject_GetAttrString((PyObject*)self, "canvas");
- if (obj==NULL)
- {
- PyErr_SetString(PyExc_AttributeError, "Attempt to install toolbar for NULL canvas");
- return -1;
- }
- Py_DECREF(obj); /* Don't increase the reference count */
- if (!PyObject_IsInstance(obj, (PyObject*) &FigureCanvasType))
- {
- PyErr_SetString(PyExc_TypeError, "Attempt to install toolbar for object that is not a FigureCanvas");
- return -1;
- }
- canvas = (FigureCanvas*)obj;
- view = canvas->view;
- if(!view)
- {
- PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL");
- return -1;
- }
-
- if(!PyArg_ParseTuple(args, "s", &basedir)) return -1;
-
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSRect bounds = [view bounds];
- NSWindow* window = [view window];
-
- bounds.origin.y += height;
- [view setFrame: bounds];
-
- bounds.size.height += height;
- [window setContentSize: bounds.size];
-
- NSString* dir = [NSString stringWithCString: basedir
- encoding: NSASCIIStringEncoding];
-
- NSButton* buttons[7];
-
- NSString* images[7] = {@"home.pdf",
- @"back.pdf",
- @"forward.pdf",
- @"move.pdf",
- @"zoom_to_rect.pdf",
- @"subplots.pdf",
- @"filesave.pdf"};
-
- NSString* tooltips[7] = {@"Reset original view",
- @"Back to previous view",
- @"Forward to next view",
- @"Pan axes with left mouse, zoom with right",
- @"Zoom to rectangle",
- @"Configure subplots",
- @"Save the figure"};
-
- SEL actions[7] = {@selector(home:),
- @selector(back:),
- @selector(forward:),
- @selector(pan:),
- @selector(zoom:),
- @selector(configure_subplots:),
- @selector(save_figure:)};
-
- NSButtonType buttontypes[7] = {NSMomentaryLightButton,
- NSMomentaryLightButton,
- NSMomentaryLightButton,
- NSPushOnPushOffButton,
- NSPushOnPushOffButton,
- NSMomentaryLightButton,
- NSMomentaryLightButton};
-
- rect.origin.x = 0;
- rect.origin.y = 0;
- rect.size.width = imagesize;
- rect.size.height = imagesize;
-#ifdef COMPILING_FOR_10_7
- rect = [window convertRectToBacking: rect];
-#endif
- size = rect.size;
- scale.width = imagesize / size.width;
- scale.height = imagesize / size.height;
-
- rect.size.width = 32;
- rect.size.height = 32;
- rect.origin.x = gap;
- rect.origin.y = 0.5*(height - rect.size.height);
-
- for (i = 0; i < 7; i++)
- {
- NSString* filename = [dir stringByAppendingPathComponent: images[i]];
- NSImage* image = [[NSImage alloc] initWithContentsOfFile: filename];
- buttons[i] = [[NSButton alloc] initWithFrame: rect];
- [image setSize: size];
- [buttons[i] setBezelStyle: NSShadowlessSquareBezelStyle];
- [buttons[i] setButtonType: buttontypes[i]];
- [buttons[i] setImage: image];
- [buttons[i] scaleUnitSquareToSize: scale];
- [buttons[i] setImagePosition: NSImageOnly];
- [buttons[i] setToolTip: tooltips[i]];
- [[window contentView] addSubview: buttons[i]];
- [buttons[i] release];
- [image release];
- rect.origin.x += rect.size.width + gap;
- }
-
- self->handler = [self->handler initWithToolbar: (PyObject*)self];
- [self->handler installCallbacks: actions forButtons: buttons];
-
- NSFont* font = [NSFont systemFontOfSize: 0.0];
- rect.size.width = 300;
- rect.size.height = 0;
- rect.origin.x += height;
- NSText* messagebox = [[NSText alloc] initWithFrame: rect];
- [messagebox setFont: font];
- [messagebox setDrawsBackground: NO];
- [messagebox setSelectable: NO];
- /* if selectable, the messagebox can become first responder,
- * which is not supposed to happen */
- rect = [messagebox frame];
- rect.origin.y = 0.5 * (height - rect.size.height);
- [messagebox setFrameOrigin: rect.origin];
- [[window contentView] addSubview: messagebox];
- [messagebox release];
- [[window contentView] display];
-
- [pool release];
-
- self->messagebox = messagebox;
- return 0;
-}
-
-static void
-NavigationToolbar2_dealloc(NavigationToolbar2 *self)
-{
- [self->handler release];
- Py_TYPE(self)->tp_free((PyObject*)self);
-}
-
-static PyObject*
-NavigationToolbar2_repr(NavigationToolbar2* self)
-{
-#if PY3K
- return PyUnicode_FromFormat("NavigationToolbar2 object %p", (void*)self);
-#else
- return PyString_FromFormat("NavigationToolbar2 object %p", (void*)self);
-#endif
-}
-
-static char NavigationToolbar2_doc[] =
-"NavigationToolbar2\n";
-
-static PyObject*
-NavigationToolbar2_set_message(NavigationToolbar2 *self, PyObject* args)
-{
- const char* message;
-
-#if PY3K
- if(!PyArg_ParseTuple(args, "y", &message)) return NULL;
-#else
- if(!PyArg_ParseTuple(args, "s", &message)) return NULL;
-#endif
-
- NSText* messagebox = self->messagebox;
-
- if (messagebox)
- { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSString* text = [NSString stringWithUTF8String: message];
- [messagebox setString: text];
- [pool release];
- }
-
- Py_RETURN_NONE;
-}
-
-static PyMethodDef NavigationToolbar2_methods[] = {
- {"set_message",
- (PyCFunction)NavigationToolbar2_set_message,
- METH_VARARGS,
- "Set the message to be displayed on the toolbar."
- },
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject NavigationToolbar2Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_macosx.NavigationToolbar2", /*tp_name*/
- sizeof(NavigationToolbar2), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)NavigationToolbar2_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- (reprfunc)NavigationToolbar2_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
- NavigationToolbar2_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- NavigationToolbar2_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- (initproc)NavigationToolbar2_init, /* tp_init */
- 0, /* tp_alloc */
- NavigationToolbar2_new, /* tp_new */
-};
-
-static PyObject*
-choose_save_file(PyObject* unused, PyObject* args)
-{
- int result;
- const char* title;
- char* default_filename;
- if(!PyArg_ParseTuple(args, "ses", &title, "UTF-8", &default_filename))
- return NULL;
-
- NSSavePanel* panel = [NSSavePanel savePanel];
- [panel setTitle: [NSString stringWithCString: title
- encoding: NSASCIIStringEncoding]];
- NSString* ns_default_filename =
- [[NSString alloc]
- initWithCString: default_filename
- encoding: NSUTF8StringEncoding];
- PyMem_Free(default_filename);
-#ifdef COMPILING_FOR_10_6
- [panel setNameFieldStringValue: ns_default_filename];
- result = [panel runModal];
-#else
- result = [panel runModalForDirectory: nil file: ns_default_filename];
-#endif
- [ns_default_filename release];
-#ifdef COMPILING_FOR_10_10
- if (result == NSModalResponseOK)
-#else
- if (result == NSOKButton)
-#endif
- {
-#ifdef COMPILING_FOR_10_6
- NSURL* url = [panel URL];
- NSString* filename = [url path];
- if (!filename) {
- PyErr_SetString(PyExc_RuntimeError, "Failed to obtain filename");
- return 0;
- }
-#else
- NSString* filename = [panel filename];
-#endif
- unsigned int n = [filename length];
- unichar* buffer = malloc(n*sizeof(unichar));
- [filename getCharacters: buffer];
-#if PY3K
- PyObject* string = PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND, buffer, n);
-#else
- PyObject* string = PyUnicode_FromUnicode(buffer, n);
-#endif
- free(buffer);
- return string;
- }
- Py_RETURN_NONE;
-}
-
-static PyObject*
-set_cursor(PyObject* unused, PyObject* args)
-{
- int i;
- if(!PyArg_ParseTuple(args, "i", &i)) return NULL;
- switch (i)
- { case 0: [[NSCursor pointingHandCursor] set]; break;
- case 1: [[NSCursor arrowCursor] set]; break;
- case 2: [[NSCursor crosshairCursor] set]; break;
- case 3: [[NSCursor openHandCursor] set]; break;
- /* OSX handles busy state itself so no need to set a cursor here */
- case 4: break;
- default: return NULL;
- }
- Py_RETURN_NONE;
-}
-
-@implementation WindowServerConnectionManager
-static WindowServerConnectionManager *sharedWindowServerConnectionManager = nil;
-
-+ (WindowServerConnectionManager *)sharedManager
-{
- if (sharedWindowServerConnectionManager == nil)
- {
- sharedWindowServerConnectionManager = [[super allocWithZone:NULL] init];
- }
- return sharedWindowServerConnectionManager;
-}
-
-+ (id)allocWithZone:(NSZone *)zone
-{
- return [[self sharedManager] retain];
-}
-
-+ (id)copyWithZone:(NSZone *)zone
-{
- return self;
-}
-
-+ (id)retain
-{
- return self;
-}
-
-- (NSUInteger)retainCount
-{
- return NSUIntegerMax; //denotes an object that cannot be released
-}
-
-- (oneway void)release
-{
- // Don't release a singleton object
-}
-
-- (id)autorelease
-{
- return self;
-}
-
-- (void)launch:(NSNotification*)notification
-{
- CFRunLoopRef runloop;
- CFMachPortRef port;
- CFRunLoopSourceRef source;
- NSDictionary* dictionary = [notification userInfo];
- if (! [[dictionary valueForKey:@"NSApplicationName"]
- isEqualToString:@"Python"])
- return;
- NSNumber* psnLow = [dictionary valueForKey: @"NSApplicationProcessSerialNumberLow"];
- NSNumber* psnHigh = [dictionary valueForKey: @"NSApplicationProcessSerialNumberHigh"];
- ProcessSerialNumber psn;
- psn.highLongOfPSN = [psnHigh intValue];
- psn.lowLongOfPSN = [psnLow intValue];
- runloop = CFRunLoopGetCurrent();
- port = CGEventTapCreateForPSN(&psn,
- kCGHeadInsertEventTap,
- kCGEventTapOptionListenOnly,
- kCGEventMaskForAllEvents,
- &_eventtap_callback,
- runloop);
- source = CFMachPortCreateRunLoopSource(kCFAllocatorDefault,
- port,
- 0);
- CFRunLoopAddSource(runloop, source, kCFRunLoopDefaultMode);
- CFRelease(port);
-}
-@end
-
-@implementation Window
-- (Window*)initWithContentRect:(NSRect)rect styleMask:(unsigned int)mask backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation withManager: (PyObject*)theManager
-{
- self = [super initWithContentRect: rect
- styleMask: mask
- backing: bufferingType
- defer: deferCreation];
- manager = theManager;
- Py_INCREF(manager);
- return self;
-}
-
-- (NSRect)constrainFrameRect:(NSRect)rect toScreen:(NSScreen*)screen
-{
- /* Allow window sizes larger than the screen */
- NSRect suggested = [super constrainFrameRect: rect toScreen: screen];
- const CGFloat difference = rect.size.height - suggested.size.height;
- suggested.origin.y -= difference;
- suggested.size.height += difference;
- return suggested;
-}
-
-- (BOOL)closeButtonPressed
-{
- PyObject* result;
- PyGILState_STATE gstate;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(manager, "close", "");
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
- return YES;
-}
-
-- (void)close
-{
- [super close];
- --FigureWindowCount;
- if (!FigureWindowCount) [NSApp stop: self];
- /* This is needed for show(), which should exit from [NSApp run]
- * after all windows are closed.
- */
-}
-
-- (void)dealloc
-{
- PyGILState_STATE gstate;
- gstate = PyGILState_Ensure();
- Py_DECREF(manager);
- PyGILState_Release(gstate);
- /* The reference count of the view that was added as a subview to the
- * content view of this window was increased during the call to addSubview,
- * and is decreased during the call to [super dealloc].
- */
- [super dealloc];
-}
-@end
-
-@implementation ToolWindow
-- (ToolWindow*)initWithContentRect:(NSRect)rect master:(NSWindow*)window
-{
- [self initWithContentRect: rect
- styleMask: NSTitledWindowMask
- | NSClosableWindowMask
- | NSResizableWindowMask
- | NSMiniaturizableWindowMask
- backing: NSBackingStoreBuffered
- defer: YES];
- [self setTitle: @"Subplot Configuration Tool"];
- [[NSNotificationCenter defaultCenter] addObserver: self
- selector: @selector(masterCloses:)
- name: NSWindowWillCloseNotification
- object: window];
- return self;
-}
-
-- (void)masterCloses:(NSNotification*)notification
-{
- [self close];
-}
-
-- (void)close
-{
- [[NSNotificationCenter defaultCenter] removeObserver: self];
- [super close];
-}
-@end
-
-@implementation View
-- (BOOL)isFlipped
-{
- return NO;
-}
-
-- (View*)initWithFrame:(NSRect)rect
-{
- self = [super initWithFrame: rect];
- rubberband = NSZeroRect;
- inside = false;
- tracking = 0;
- device_scale = 1;
- return self;
-}
-
-- (void)dealloc
-{
- FigureCanvas* fc = (FigureCanvas*)canvas;
- if (fc) fc->view = NULL;
- [self removeTrackingRect: tracking];
- [super dealloc];
-}
-
-- (void)setCanvas: (PyObject*)newCanvas
-{
- canvas = newCanvas;
-}
-
-static void _buffer_release(void* info, const void* data, size_t size) {
- PyBuffer_Release((Py_buffer *)info);
-}
-
-static int _copy_agg_buffer(CGContextRef cr, PyObject *renderer)
-{
- Py_buffer buffer;
-
- if (PyObject_GetBuffer(renderer, &buffer, PyBUF_CONTIG_RO) == -1) {
- PyErr_Print();
- return 1;
- }
-
- if (buffer.ndim != 3 || buffer.shape[2] != 4) {
- PyBuffer_Release(&buffer);
- return 1;
- }
-
- const Py_ssize_t nrows = buffer.shape[0];
- const Py_ssize_t ncols = buffer.shape[1];
- const size_t bytesPerComponent = 1;
- const size_t bitsPerComponent = 8 * bytesPerComponent;
- const size_t nComponents = 4; /* red, green, blue, alpha */
- const size_t bitsPerPixel = bitsPerComponent * nComponents;
- const size_t bytesPerRow = nComponents * bytesPerComponent * ncols;
-
- CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
- if (!colorspace) {
- PyBuffer_Release(&buffer);
- return 1;
- }
-
- CGDataProviderRef provider = CGDataProviderCreateWithData(&buffer,
- buffer.buf,
- buffer.len,
- _buffer_release);
- if (!provider) {
- PyBuffer_Release(&buffer);
- CGColorSpaceRelease(colorspace);
- return 1;
- }
-
- CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaLast;
- CGImageRef bitmap = CGImageCreate(ncols,
- nrows,
- bitsPerComponent,
- bitsPerPixel,
- bytesPerRow,
- colorspace,
- bitmapInfo,
- provider,
- NULL,
- false,
- kCGRenderingIntentDefault);
- CGColorSpaceRelease(colorspace);
- CGDataProviderRelease(provider);
-
- if (!bitmap) {
- PyBuffer_Release(&buffer);
- return 1;
- }
-
- CGFloat deviceScale = _get_device_scale(cr);
- CGContextSaveGState(cr);
- CGContextDrawImage(cr, CGRectMake(0, 0, ncols/deviceScale, nrows/deviceScale), bitmap);
- CGImageRelease(bitmap);
- CGContextRestoreGState(cr);
-
- return 0;
-}
-
--(void)drawRect:(NSRect)rect
-{
- PyObject* renderer = NULL;
- PyObject* renderer_buffer = NULL;
-
- PyGILState_STATE gstate = PyGILState_Ensure();
-
- CGContextRef cr = [[NSGraphicsContext currentContext] graphicsPort];
-
- double new_device_scale = _get_device_scale(cr);
-
- if (device_scale != new_device_scale) {
- device_scale = new_device_scale;
- if (!PyObject_CallMethod(canvas, "_set_device_scale", "d", device_scale, NULL)) {
- PyErr_Print();
- goto exit;
- }
- }
-
- renderer = PyObject_CallMethod(canvas, "_draw", "", NULL);
- if (!renderer)
- {
- PyErr_Print();
- goto exit;
- }
-
- renderer_buffer = PyObject_GetAttrString(renderer, "_renderer");
- if (!renderer_buffer) {
- PyErr_Print();
- goto exit;
- }
-
- if (_copy_agg_buffer(cr, renderer_buffer)) {
- printf("copy_agg_buffer failed\n");
- goto exit;
- }
-
-
- if (!NSIsEmptyRect(rubberband)) {
- NSFrameRect(rubberband);
- }
-
- exit:
- Py_XDECREF(renderer_buffer);
- Py_XDECREF(renderer);
-
- PyGILState_Release(gstate);
-}
-
-- (void)windowDidResize: (NSNotification*)notification
-{
- int width, height;
- Window* window = [notification object];
- NSSize size = [[window contentView] frame].size;
- NSRect rect = [self frame];
-
- size.height -= rect.origin.y;
- width = size.width;
- height = size.height;
-
- [self setFrameSize: size];
-
- PyGILState_STATE gstate = PyGILState_Ensure();
- PyObject* result = PyObject_CallMethod(
- canvas, "resize", "ii", width, height);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
- if (tracking) [self removeTrackingRect: tracking];
- tracking = [self addTrackingRect: [self bounds]
- owner: self
- userData: nil
- assumeInside: NO];
- [self setNeedsDisplay: YES];
-}
-
-- (void)windowWillClose:(NSNotification*)notification
-{
- PyGILState_STATE gstate;
- PyObject* result;
-
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(canvas, "close_event", "");
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-}
-
-- (BOOL)windowShouldClose:(NSNotification*)notification
-{
- NSWindow* window = [self window];
- NSEvent* event = [NSEvent otherEventWithType: NSApplicationDefined
- location: NSZeroPoint
- modifierFlags: 0
- timestamp: 0.0
- windowNumber: 0
- context: nil
- subtype: WINDOW_CLOSING
- data1: 0
- data2: 0];
- [NSApp postEvent: event atStart: true];
- if ([window respondsToSelector: @selector(closeButtonPressed)])
- { BOOL closed = [((Window*) window) closeButtonPressed];
- /* If closed, the window has already been closed via the manager. */
- if (closed) return NO;
- }
- return YES;
-}
-
-- (void)mouseEntered:(NSEvent *)event
-{
- PyGILState_STATE gstate;
- PyObject* result;
- NSWindow* window = [self window];
- if ([window isKeyWindow]==false) return;
-
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(canvas, "enter_notify_event", "");
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-
- [window setAcceptsMouseMovedEvents: YES];
- inside = true;
-}
-
-- (void)mouseExited:(NSEvent *)event
-{
- PyGILState_STATE gstate;
- PyObject* result;
- NSWindow* window = [self window];
- if ([window isKeyWindow]==false) return;
-
- if (inside==false) return;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(canvas, "leave_notify_event", "");
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
- PyGILState_Release(gstate);
-
- [[self window] setAcceptsMouseMovedEvents: NO];
- inside = false;
-}
-
-- (void)mouseDown:(NSEvent *)event
-{
- int x, y;
- int num;
- int dblclick = 0;
- PyObject* result;
- PyGILState_STATE gstate;
- NSPoint location = [event locationInWindow];
- location = [self convertPoint: location fromView: nil];
- x = location.x * device_scale;
- y = location.y * device_scale;
- switch ([event type])
- { case NSLeftMouseDown:
- { unsigned int modifier = [event modifierFlags];
- if (modifier & NSControlKeyMask)
- /* emulate a right-button click */
- num = 3;
- else if (modifier & NSAlternateKeyMask)
- /* emulate a middle-button click */
- num = 2;
- else
- {
- num = 1;
- if ([NSCursor currentCursor]==[NSCursor openHandCursor])
- [[NSCursor closedHandCursor] set];
- }
- break;
- }
- case NSOtherMouseDown: num = 2; break;
- case NSRightMouseDown: num = 3; break;
- default: return; /* Unknown mouse event */
- }
- if ([event clickCount] == 2) {
- dblclick = 1;
- }
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(canvas, "button_press_event", "iiii", x, y, num, dblclick);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
-
- PyGILState_Release(gstate);
-}
-
-- (void)mouseUp:(NSEvent *)event
-{
- int num;
- int x, y;
- PyObject* result;
- PyGILState_STATE gstate;
- NSPoint location = [event locationInWindow];
- location = [self convertPoint: location fromView: nil];
- x = location.x * device_scale;
- y = location.y * device_scale;
- switch ([event type])
- { case NSLeftMouseUp:
- num = 1;
- if ([NSCursor currentCursor]==[NSCursor closedHandCursor])
- [[NSCursor openHandCursor] set];
- break;
- case NSOtherMouseUp: num = 2; break;
- case NSRightMouseUp: num = 3; break;
- default: return; /* Unknown mouse event */
- }
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(canvas, "button_release_event", "iii", x, y, num);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
-
- PyGILState_Release(gstate);
-}
-
-- (void)mouseMoved:(NSEvent *)event
-{
- int x, y;
- NSPoint location = [event locationInWindow];
- location = [self convertPoint: location fromView: nil];
- x = location.x * device_scale;
- y = location.y * device_scale;
- PyGILState_STATE gstate = PyGILState_Ensure();
- PyObject* result = PyObject_CallMethod(canvas, "motion_notify_event", "ii", x, y);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
-
- PyGILState_Release(gstate);
-}
-
-- (void)mouseDragged:(NSEvent *)event
-{
- int x, y;
- NSPoint location = [event locationInWindow];
- location = [self convertPoint: location fromView: nil];
- x = location.x * device_scale;
- y = location.y * device_scale;
- PyGILState_STATE gstate = PyGILState_Ensure();
- PyObject* result = PyObject_CallMethod(canvas, "motion_notify_event", "ii", x, y);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
-
- PyGILState_Release(gstate);
-}
-
-- (void)rightMouseDown:(NSEvent *)event
-{
- int x, y;
- int num = 3;
- int dblclick = 0;
- PyObject* result;
- PyGILState_STATE gstate;
- NSPoint location = [event locationInWindow];
- location = [self convertPoint: location fromView: nil];
- x = location.x * device_scale;
- y = location.y * device_scale;
- gstate = PyGILState_Ensure();
- if ([event clickCount] == 2) {
- dblclick = 1;
- }
- result = PyObject_CallMethod(canvas, "button_press_event", "iiii", x, y, num, dblclick);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
-
- PyGILState_Release(gstate);
-}
-
-- (void)rightMouseUp:(NSEvent *)event
-{
- int x, y;
- int num = 3;
- PyObject* result;
- PyGILState_STATE gstate;
- NSPoint location = [event locationInWindow];
- location = [self convertPoint: location fromView: nil];
- x = location.x * device_scale;
- y = location.y * device_scale;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(canvas, "button_release_event", "iii", x, y, num);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
-
- PyGILState_Release(gstate);
-}
-
-- (void)rightMouseDragged:(NSEvent *)event
-{
- int x, y;
- NSPoint location = [event locationInWindow];
- location = [self convertPoint: location fromView: nil];
- x = location.x * device_scale;
- y = location.y * device_scale;
- PyGILState_STATE gstate = PyGILState_Ensure();
- PyObject* result = PyObject_CallMethod(canvas, "motion_notify_event", "ii", x, y);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
-
- PyGILState_Release(gstate);
-}
-
-- (void)otherMouseDown:(NSEvent *)event
-{
- int x, y;
- int num = 2;
- int dblclick = 0;
- PyObject* result;
- PyGILState_STATE gstate;
- NSPoint location = [event locationInWindow];
- location = [self convertPoint: location fromView: nil];
- x = location.x * device_scale;
- y = location.y * device_scale;
- gstate = PyGILState_Ensure();
- if ([event clickCount] == 2) {
- dblclick = 1;
- }
- result = PyObject_CallMethod(canvas, "button_press_event", "iiii", x, y, num, dblclick);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
-
- PyGILState_Release(gstate);
-}
-
-- (void)otherMouseUp:(NSEvent *)event
-{
- int x, y;
- int num = 2;
- PyObject* result;
- PyGILState_STATE gstate;
- NSPoint location = [event locationInWindow];
- location = [self convertPoint: location fromView: nil];
- x = location.x * device_scale;
- y = location.y * device_scale;
- gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(canvas, "button_release_event", "iii", x, y, num);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
-
- PyGILState_Release(gstate);
-}
-
-- (void)otherMouseDragged:(NSEvent *)event
-{
- int x, y;
- NSPoint location = [event locationInWindow];
- location = [self convertPoint: location fromView: nil];
- x = location.x * device_scale;
- y = location.y * device_scale;
- PyGILState_STATE gstate = PyGILState_Ensure();
- PyObject* result = PyObject_CallMethod(canvas, "motion_notify_event", "ii", x, y);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
-
- PyGILState_Release(gstate);
-}
-
-- (void)setRubberband:(NSRect)rect
-{
- if (!NSIsEmptyRect(rubberband)) [self setNeedsDisplayInRect: rubberband];
- rubberband = rect;
- [self setNeedsDisplayInRect: rubberband];
-}
-
-- (void)removeRubberband
-{
- if (NSIsEmptyRect(rubberband)) return;
- [self setNeedsDisplayInRect: rubberband];
- rubberband = NSZeroRect;
-}
-
-
-
-- (const char*)convertKeyEvent:(NSEvent*)event
-{
- NSDictionary* specialkeymappings = [NSDictionary dictionaryWithObjectsAndKeys:
- @"left", [NSNumber numberWithUnsignedLong:NSLeftArrowFunctionKey],
- @"right", [NSNumber numberWithUnsignedLong:NSRightArrowFunctionKey],
- @"up", [NSNumber numberWithUnsignedLong:NSUpArrowFunctionKey],
- @"down", [NSNumber numberWithUnsignedLong:NSDownArrowFunctionKey],
- @"f1", [NSNumber numberWithUnsignedLong:NSF1FunctionKey],
- @"f2", [NSNumber numberWithUnsignedLong:NSF2FunctionKey],
- @"f3", [NSNumber numberWithUnsignedLong:NSF3FunctionKey],
- @"f4", [NSNumber numberWithUnsignedLong:NSF4FunctionKey],
- @"f5", [NSNumber numberWithUnsignedLong:NSF5FunctionKey],
- @"f6", [NSNumber numberWithUnsignedLong:NSF6FunctionKey],
- @"f7", [NSNumber numberWithUnsignedLong:NSF7FunctionKey],
- @"f8", [NSNumber numberWithUnsignedLong:NSF8FunctionKey],
- @"f9", [NSNumber numberWithUnsignedLong:NSF9FunctionKey],
- @"f10", [NSNumber numberWithUnsignedLong:NSF10FunctionKey],
- @"f11", [NSNumber numberWithUnsignedLong:NSF11FunctionKey],
- @"f12", [NSNumber numberWithUnsignedLong:NSF12FunctionKey],
- @"f13", [NSNumber numberWithUnsignedLong:NSF13FunctionKey],
- @"f14", [NSNumber numberWithUnsignedLong:NSF14FunctionKey],
- @"f15", [NSNumber numberWithUnsignedLong:NSF15FunctionKey],
- @"f16", [NSNumber numberWithUnsignedLong:NSF16FunctionKey],
- @"f17", [NSNumber numberWithUnsignedLong:NSF17FunctionKey],
- @"f18", [NSNumber numberWithUnsignedLong:NSF18FunctionKey],
- @"f19", [NSNumber numberWithUnsignedLong:NSF19FunctionKey],
- @"scroll_lock", [NSNumber numberWithUnsignedLong:NSScrollLockFunctionKey],
- @"break", [NSNumber numberWithUnsignedLong:NSBreakFunctionKey],
- @"insert", [NSNumber numberWithUnsignedLong:NSInsertFunctionKey],
- @"delete", [NSNumber numberWithUnsignedLong:NSDeleteFunctionKey],
- @"home", [NSNumber numberWithUnsignedLong:NSHomeFunctionKey],
- @"end", [NSNumber numberWithUnsignedLong:NSEndFunctionKey],
- @"pagedown", [NSNumber numberWithUnsignedLong:NSPageDownFunctionKey],
- @"pageup", [NSNumber numberWithUnsignedLong:NSPageUpFunctionKey],
- @"backspace", [NSNumber numberWithUnsignedLong:NSDeleteCharacter],
- @"enter", [NSNumber numberWithUnsignedLong:NSEnterCharacter],
- @"tab", [NSNumber numberWithUnsignedLong:NSTabCharacter],
- @"enter", [NSNumber numberWithUnsignedLong:NSCarriageReturnCharacter],
- @"backtab", [NSNumber numberWithUnsignedLong:NSBackTabCharacter],
- @"escape", [NSNumber numberWithUnsignedLong:27],
- nil
- ];
-
- NSMutableString* returnkey = [NSMutableString string];
- if ([event modifierFlags] & NSControlKeyMask)
- [returnkey appendString:@"ctrl+" ];
- if ([event modifierFlags] & NSAlternateKeyMask)
- [returnkey appendString:@"alt+" ];
- if ([event modifierFlags] & NSCommandKeyMask)
- [returnkey appendString:@"cmd+" ];
-
- unichar uc = [[event charactersIgnoringModifiers] characterAtIndex:0];
- NSString* specialchar = [specialkeymappings objectForKey:[NSNumber numberWithUnsignedLong:uc]];
- if (specialchar){
- if ([event modifierFlags] & NSShiftKeyMask)
- [returnkey appendString:@"shift+" ];
- [returnkey appendString:specialchar];
- }
- else
- [returnkey appendString:[event charactersIgnoringModifiers]];
-
- return [returnkey UTF8String];
-}
-
-- (void)keyDown:(NSEvent*)event
-{
- PyObject* result;
- const char* s = [self convertKeyEvent: event];
- PyGILState_STATE gstate = PyGILState_Ensure();
- if (s==NULL)
- {
- result = PyObject_CallMethod(canvas, "key_press_event", "O", Py_None);
- }
- else
- {
- result = PyObject_CallMethod(canvas, "key_press_event", "s", s);
- }
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
-
- PyGILState_Release(gstate);
-}
-
-- (void)keyUp:(NSEvent*)event
-{
- PyObject* result;
- const char* s = [self convertKeyEvent: event];
- PyGILState_STATE gstate = PyGILState_Ensure();
- if (s==NULL)
- {
- result = PyObject_CallMethod(canvas, "key_release_event", "O", Py_None);
- }
- else
- {
- result = PyObject_CallMethod(canvas, "key_release_event", "s", s);
- }
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
-
- PyGILState_Release(gstate);
-}
-
-- (void)scrollWheel:(NSEvent*)event
-{
- int step;
- float d = [event deltaY];
- if (d > 0) step = 1;
- else if (d < 0) step = -1;
- else return;
- NSPoint location = [event locationInWindow];
- NSPoint point = [self convertPoint: location fromView: nil];
- int x = (int)round(point.x * device_scale);
- int y = (int)round(point.y * device_scale - 1);
-
- PyObject* result;
- PyGILState_STATE gstate = PyGILState_Ensure();
- result = PyObject_CallMethod(canvas, "scroll_event", "iii", x, y, step);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
-
- PyGILState_Release(gstate);
-}
-
-- (BOOL)acceptsFirstResponder
-{
- return YES;
-}
-
-/* This is all wrong. Address of pointer is being passed instead of pointer, keynames don't
- match up with what the front-end and does the front-end even handle modifier keys by themselves?
-
-- (void)flagsChanged:(NSEvent*)event
-{
- const char *s = NULL;
- if (([event modifierFlags] & NSControlKeyMask) == NSControlKeyMask)
- s = "control";
- else if (([event modifierFlags] & NSShiftKeyMask) == NSShiftKeyMask)
- s = "shift";
- else if (([event modifierFlags] & NSAlternateKeyMask) == NSAlternateKeyMask)
- s = "alt";
- else return;
- PyGILState_STATE gstate = PyGILState_Ensure();
- PyObject* result = PyObject_CallMethod(canvas, "key_press_event", "s", &s);
- if(result)
- Py_DECREF(result);
- else
- PyErr_Print();
-
- PyGILState_Release(gstate);
-}
- */
-@end
-
-@implementation ScrollableButton
-- (void)setScrollWheelUpAction:(SEL)action
-{
- scrollWheelUpAction = action;
-}
-
-- (void)setScrollWheelDownAction:(SEL)action
-{
- scrollWheelDownAction = action;
-}
-
-- (void)scrollWheel:(NSEvent*)event
-{
- float d = [event deltaY];
- Window* target = [self target];
- if (d > 0)
- [NSApp sendAction: scrollWheelUpAction to: target from: self];
- else if (d < 0)
- [NSApp sendAction: scrollWheelDownAction to: target from: self];
-}
-@end
-
-@implementation MenuItem
-+ (MenuItem*)menuItemWithTitle: (NSString*)title
-{
- MenuItem* item = [[MenuItem alloc] initWithTitle: title
- action: nil
- keyEquivalent: @""];
- item->index = -1;
- return [item autorelease];
-}
-
-+ (MenuItem*)menuItemForAxis: (int)i
-{
- NSString* title = [NSString stringWithFormat: @"Axis %d", i+1];
- MenuItem* item = [[MenuItem alloc] initWithTitle: title
- action: @selector(toggle:)
- keyEquivalent: @""];
- [item setTarget: item];
- [item setState: NSOnState];
- item->index = i;
- return [item autorelease];
-}
-
-+ (MenuItem*)menuItemSelectAll
-{
- MenuItem* item = [[MenuItem alloc] initWithTitle: @"Select All"
- action: @selector(selectAll:)
- keyEquivalent: @""];
- [item setTarget: item];
- item->index = -1;
- return [item autorelease];
-}
-
-+ (MenuItem*)menuItemInvertAll
-{
- MenuItem* item = [[MenuItem alloc] initWithTitle: @"Invert All"
- action: @selector(invertAll:)
- keyEquivalent: @""];
- [item setTarget: item];
- item->index = -1;
- return [item autorelease];
-}
-
-- (void)toggle:(id)sender
-{
- if ([self state]) [self setState: NSOffState];
- else [self setState: NSOnState];
-}
-
-- (void)selectAll:(id)sender
-{
- NSMenu* menu = [sender menu];
- if(!menu) return; /* Weird */
- NSArray* items = [menu itemArray];
- NSEnumerator* enumerator = [items objectEnumerator];
- MenuItem* item;
- while ((item = [enumerator nextObject]))
- {
- if (item->index >= 0) [item setState: NSOnState];
- }
-}
-
-- (void)invertAll:(id)sender
-{
- NSMenu* menu = [sender menu];
- if(!menu) return; /* Weird */
- NSArray* items = [menu itemArray];
- NSEnumerator* enumerator = [items objectEnumerator];
- MenuItem* item;
- while ((item = [enumerator nextObject]))
- {
- if (item->index < 0) continue;
- if ([item state]==NSOffState) [item setState: NSOnState];
- else [item setState: NSOffState];
- }
-}
-
-- (int)index
-{
- return self->index;
-}
-@end
-
-static PyObject*
-show(PyObject* self)
-{
- [NSApp activateIgnoringOtherApps: YES];
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSArray *windowsArray = [NSApp windows];
- NSEnumerator *enumerator = [windowsArray objectEnumerator];
- NSWindow *window;
- while ((window = [enumerator nextObject])) {
- [window orderFront:nil];
- }
- [pool release];
- Py_BEGIN_ALLOW_THREADS
- [NSApp run];
- Py_END_ALLOW_THREADS
- Py_RETURN_NONE;
-}
-
-typedef struct {
- PyObject_HEAD
- CFRunLoopTimerRef timer;
-} Timer;
-
-static PyObject*
-Timer_new(PyTypeObject* type, PyObject *args, PyObject *kwds)
-{
- Timer* self = (Timer*)type->tp_alloc(type, 0);
- if (!self) return NULL;
- self->timer = NULL;
- return (PyObject*) self;
-}
-
-static PyObject*
-Timer_repr(Timer* self)
-{
-#if PY3K
- return PyUnicode_FromFormat("Timer object %p wrapping CFRunLoopTimerRef %p",
- (void*) self, (void*)(self->timer));
-#else
- return PyString_FromFormat("Timer object %p wrapping CFRunLoopTimerRef %p",
- (void*) self, (void*)(self->timer));
-#endif
-}
-
-static char Timer_doc[] =
-"A Timer object wraps a CFRunLoopTimerRef and can add it to the event loop.\n";
-
-static void timer_callback(CFRunLoopTimerRef timer, void* info)
-{
- PyObject* method = info;
- PyGILState_STATE gstate = PyGILState_Ensure();
- PyObject* result = PyObject_CallFunction(method, NULL);
- if (result) {
- Py_DECREF(result);
- } else {
- PyErr_Print();
- }
- PyGILState_Release(gstate);
-}
-
-static void context_cleanup(const void* info)
-{
- Py_DECREF((PyObject*)info);
-}
-
-static PyObject*
-Timer__timer_start(Timer* self, PyObject* args)
-{
- CFRunLoopRef runloop;
- CFRunLoopTimerRef timer;
- CFRunLoopTimerContext context;
- double milliseconds;
- CFTimeInterval interval;
- PyObject* attribute;
- PyObject* failure;
- runloop = CFRunLoopGetCurrent();
- if (!runloop) {
- PyErr_SetString(PyExc_RuntimeError, "Failed to obtain run loop");
- return NULL;
- }
- attribute = PyObject_GetAttrString((PyObject*)self, "_interval");
- if (attribute==NULL)
- {
- PyErr_SetString(PyExc_AttributeError, "Timer has no attribute '_interval'");
- return NULL;
- }
- milliseconds = PyFloat_AsDouble(attribute);
- failure = PyErr_Occurred();
- Py_DECREF(attribute);
- if (failure) return NULL;
- attribute = PyObject_GetAttrString((PyObject*)self, "_single");
- if (attribute==NULL)
- {
- PyErr_SetString(PyExc_AttributeError, "Timer has no attribute '_single'");
- return NULL;
- }
- switch (PyObject_IsTrue(attribute)) {
- case 1:
- interval = 0;
- break;
- case 0:
- interval = milliseconds / 1000.0;
- break;
- case -1:
- default:
- PyErr_SetString(PyExc_ValueError, "Cannot interpret _single attribute as True of False");
- return NULL;
- }
- Py_DECREF(attribute);
- attribute = PyObject_GetAttrString((PyObject*)self, "_on_timer");
- if (attribute==NULL)
- {
- PyErr_SetString(PyExc_AttributeError, "Timer has no attribute '_on_timer'");
- return NULL;
- }
- if (!PyMethod_Check(attribute)) {
- PyErr_SetString(PyExc_RuntimeError, "_on_timer should be a Python method");
- return NULL;
- }
- context.version = 0;
- context.retain = NULL;
- context.release = context_cleanup;
- context.copyDescription = NULL;
- context.info = attribute;
- timer = CFRunLoopTimerCreate(kCFAllocatorDefault,
- 0,
- interval,
- 0,
- 0,
- timer_callback,
- &context);
- if (!timer) {
- Py_DECREF(attribute);
- PyErr_SetString(PyExc_RuntimeError, "Failed to create timer");
- return NULL;
- }
- if (self->timer) {
- CFRunLoopTimerInvalidate(self->timer);
- CFRelease(self->timer);
- }
- CFRunLoopAddTimer(runloop, timer, kCFRunLoopCommonModes);
- /* Don't release the timer here, since the run loop may be destroyed and
- * the timer lost before we have a chance to decrease the reference count
- * of the attribute */
- self->timer = timer;
- Py_RETURN_NONE;
-}
-
-static PyObject*
-Timer__timer_stop(Timer* self)
-{
- if (self->timer) {
- CFRunLoopTimerInvalidate(self->timer);
- CFRelease(self->timer);
- self->timer = NULL;
- }
- Py_RETURN_NONE;
-}
-
-static void
-Timer_dealloc(Timer* self)
-{
- Timer__timer_stop(self);
- Py_TYPE(self)->tp_free((PyObject*)self);
-}
-
-static PyMethodDef Timer_methods[] = {
- {"_timer_start",
- (PyCFunction)Timer__timer_start,
- METH_VARARGS,
- "Initialize and start the timer."
- },
- {"_timer_stop",
- (PyCFunction)Timer__timer_stop,
- METH_NOARGS,
- "Stop the timer."
- },
- {NULL} /* Sentinel */
-};
-
-static PyTypeObject TimerType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "_macosx.Timer", /*tp_name*/
- sizeof(Timer), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- (destructor)Timer_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- (reprfunc)Timer_repr, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
- Timer_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- Timer_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- Timer_new, /* tp_new */
-};
-
-static bool verify_framework(void)
-{
-#ifdef COMPILING_FOR_10_6
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- NSRunningApplication* app = [NSRunningApplication currentApplication];
- NSApplicationActivationPolicy activationPolicy = [app activationPolicy];
- [pool release];
- switch (activationPolicy) {
- case NSApplicationActivationPolicyRegular:
- case NSApplicationActivationPolicyAccessory:
- return true;
- case NSApplicationActivationPolicyProhibited:
- break;
- }
-#else
- ProcessSerialNumber psn;
- if (CGMainDisplayID()!=0
- && GetCurrentProcess(&psn)==noErr
- && SetFrontProcess(&psn)==noErr) return true;
-#endif
- PyErr_SetString(PyExc_RuntimeError,
- "Python is not installed as a framework. The Mac OS X backend will "
- "not be able to function correctly if Python is not installed as a "
- "framework. See the Python documentation for more information on "
- "installing Python as a framework on Mac OS X. Please either reinstall "
- "Python as a framework, or try one of the other backends. If you are "
- "using (Ana)Conda please install python.app and replace the use of 'python' "
- "with 'pythonw'. See 'Working with Matplotlib on OSX' "
- "in the Matplotlib FAQ for more information.");
- return false;
-}
-
-static struct PyMethodDef methods[] = {
- {"show",
- (PyCFunction)show,
- METH_NOARGS,
- "Show all the figures and enter the main loop.\nThis function does not return until all Matplotlib windows are closed,\nand is normally not needed in interactive sessions."
- },
- {"choose_save_file",
- (PyCFunction)choose_save_file,
- METH_VARARGS,
- "Closes the window."
- },
- {"set_cursor",
- (PyCFunction)set_cursor,
- METH_VARARGS,
- "Sets the active cursor."
- },
- {NULL, NULL, 0, NULL}/* sentinel */
-};
-
-#if PY3K
-
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_macosx",
- "Mac OS X native backend",
- -1,
- methods,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-PyObject* PyInit__macosx(void)
-
-#else
-
-void init_macosx(void)
-#endif
-{
- PyObject *module;
-
- if (PyType_Ready(&FigureCanvasType) < 0
- || PyType_Ready(&FigureManagerType) < 0
- || PyType_Ready(&NavigationToolbarType) < 0
- || PyType_Ready(&NavigationToolbar2Type) < 0
- || PyType_Ready(&TimerType) < 0)
-#if PY3K
- return NULL;
-#else
- return;
-#endif
-
- NSApp = [NSApplication sharedApplication];
-
- if (!verify_framework())
-#if PY3K
- return NULL;
-#else
- return;
-#endif
-
-#if PY3K
- module = PyModule_Create(&moduledef);
- if (module==NULL) return NULL;
-#else
- module = Py_InitModule4("_macosx",
- methods,
- "Mac OS X native backend",
- NULL,
- PYTHON_API_VERSION);
-#endif
-
- Py_INCREF(&FigureCanvasType);
- Py_INCREF(&FigureManagerType);
- Py_INCREF(&NavigationToolbarType);
- Py_INCREF(&NavigationToolbar2Type);
- Py_INCREF(&TimerType);
- PyModule_AddObject(module, "FigureCanvas", (PyObject*) &FigureCanvasType);
- PyModule_AddObject(module, "FigureManager", (PyObject*) &FigureManagerType);
- PyModule_AddObject(module, "NavigationToolbar", (PyObject*) &NavigationToolbarType);
- PyModule_AddObject(module, "NavigationToolbar2", (PyObject*) &NavigationToolbar2Type);
- PyModule_AddObject(module, "Timer", (PyObject*) &TimerType);
-
- PyOS_InputHook = wait_for_stdin;
-
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- WindowServerConnectionManager* connectionManager = [WindowServerConnectionManager sharedManager];
- NSWorkspace* workspace = [NSWorkspace sharedWorkspace];
- NSNotificationCenter* notificationCenter = [workspace notificationCenter];
- [notificationCenter addObserver: connectionManager
- selector: @selector(launch:)
- name: NSWorkspaceDidLaunchApplicationNotification
- object: nil];
- [pool release];
-#if PY3K
- return module;
-#endif
-}
diff --git a/contrib/python/matplotlib/py2/src/_path.h b/contrib/python/matplotlib/py2/src/_path.h
deleted file mode 100644
index 76f1894c4a..0000000000
--- a/contrib/python/matplotlib/py2/src/_path.h
+++ /dev/null
@@ -1,1316 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef __PATH_H__
-#define __PATH_H__
-
-#include <limits>
-#include <math.h>
-#include <vector>
-#include <cmath>
-#include <algorithm>
-
-#include "agg_conv_contour.h"
-#include "agg_conv_curve.h"
-#include "agg_conv_stroke.h"
-#include "agg_conv_transform.h"
-#include "agg_path_storage.h"
-#include "agg_trans_affine.h"
-
-#include "path_converters.h"
-#include "_backend_agg_basic_types.h"
-#include "numpy_cpp.h"
-
-struct XY
-{
- double x;
- double y;
-
- XY(double x_, double y_) : x(x_), y(y_)
- {
- }
-
- bool operator==(const XY& o)
- {
- return (x == o.x && y == o.y);
- }
-
- bool operator!=(const XY& o)
- {
- return (x != o.x || y != o.y);
- }
-};
-
-typedef std::vector<XY> Polygon;
-
-void _finalize_polygon(std::vector<Polygon> &result, int closed_only)
-{
- if (result.size() == 0) {
- return;
- }
-
- Polygon &polygon = result.back();
-
- /* Clean up the last polygon in the result. */
- if (polygon.size() == 0) {
- result.pop_back();
- } else if (closed_only) {
- if (polygon.size() < 3) {
- result.pop_back();
- } else if (polygon.front() != polygon.back()) {
- polygon.push_back(polygon.front());
- }
- }
-}
-
-//
-// The following function was found in the Agg 2.3 examples (interactive_polygon.cpp).
-// It has been generalized to work on (possibly curved) polylines, rather than
-// just polygons. The original comments have been kept intact.
-// -- Michael Droettboom 2007-10-02
-//
-//======= 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.
-template <class PathIterator, class PointArray, class ResultArray>
-void point_in_path_impl(PointArray &points, PathIterator &path, ResultArray &inside_flag)
-{
- uint8_t yflag1;
- double vtx0, vty0, vtx1, vty1;
- double tx, ty;
- double sx, sy;
- double x, y;
- size_t i;
- bool all_done;
-
- size_t n = points.size();
-
- std::vector<uint8_t> yflag0(n);
- std::vector<uint8_t> subpath_flag(n);
-
- path.rewind(0);
-
- for (i = 0; i < n; ++i) {
- inside_flag[i] = 0;
- }
-
- unsigned code = 0;
- do {
- if (code != agg::path_cmd_move_to) {
- code = path.vertex(&x, &y);
- if (code == agg::path_cmd_stop ||
- (code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) {
- continue;
- }
- }
-
- sx = vtx0 = vtx1 = x;
- sy = vty0 = vty1 = y;
-
- for (i = 0; i < n; ++i) {
- ty = points(i, 1);
-
- if (std::isfinite(ty)) {
- // get test bit for above/below X axis
- yflag0[i] = (vty0 >= ty);
-
- subpath_flag[i] = 0;
- }
- }
-
- do {
- code = path.vertex(&x, &y);
-
- // The following cases denote the beginning on a new subpath
- if (code == agg::path_cmd_stop ||
- (code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) {
- x = sx;
- y = sy;
- } else if (code == agg::path_cmd_move_to) {
- break;
- }
-
- for (i = 0; i < n; ++i) {
- tx = points(i, 0);
- ty = points(i, 1);
-
- if (!(std::isfinite(tx) && std::isfinite(ty))) {
- continue;
- }
-
- 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[i] != 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) {
- subpath_flag[i] ^= 1;
- }
- }
-
- // Move to the next pair of vertices, retaining info as
- // possible.
- yflag0[i] = yflag1;
- }
-
- vtx0 = vtx1;
- vty0 = vty1;
-
- vtx1 = x;
- vty1 = y;
- } while (code != agg::path_cmd_stop &&
- (code & agg::path_cmd_end_poly) != agg::path_cmd_end_poly);
-
- all_done = true;
- for (i = 0; i < n; ++i) {
- tx = points(i, 0);
- ty = points(i, 1);
-
- if (!(std::isfinite(tx) && std::isfinite(ty))) {
- continue;
- }
-
- yflag1 = (vty1 >= ty);
- if (yflag0[i] != yflag1) {
- if (((vty1 - ty) * (vtx0 - vtx1) >= (vtx1 - tx) * (vty0 - vty1)) == yflag1) {
- subpath_flag[i] = subpath_flag[i] ^ true;
- }
- }
- inside_flag[i] |= subpath_flag[i];
- if (inside_flag[i] == 0) {
- all_done = false;
- }
- }
-
- if (all_done) {
- break;
- }
- } while (code != agg::path_cmd_stop);
-}
-
-template <class PathIterator, class PointArray, class ResultArray>
-inline void points_in_path(PointArray &points,
- const double r,
- PathIterator &path,
- agg::trans_affine &trans,
- ResultArray &result)
-{
- typedef agg::conv_transform<PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> no_nans_t;
- typedef agg::conv_curve<no_nans_t> curve_t;
- typedef agg::conv_contour<curve_t> contour_t;
-
- size_t i;
- for (i = 0; i < points.size(); ++i) {
- result[i] = false;
- }
-
- if (path.total_vertices() < 3) {
- return;
- }
-
- transformed_path_t trans_path(path, trans);
- no_nans_t no_nans_path(trans_path, true, path.has_curves());
- curve_t curved_path(no_nans_path);
- if (r != 0.0) {
- contour_t contoured_path(curved_path);
- contoured_path.width(r);
- point_in_path_impl(points, contoured_path, result);
- } else {
- point_in_path_impl(points, curved_path, result);
- }
-}
-
-template <class PathIterator>
-inline bool point_in_path(
- double x, double y, const double r, PathIterator &path, agg::trans_affine &trans)
-{
- npy_intp shape[] = {1, 2};
- numpy::array_view<double, 2> points(shape);
- points(0, 0) = x;
- points(0, 1) = y;
-
- int result[1];
- result[0] = 0;
-
- points_in_path(points, r, path, trans, result);
-
- return (bool)result[0];
-}
-
-template <class PathIterator, class PointArray, class ResultArray>
-void points_on_path(PointArray &points,
- const double r,
- PathIterator &path,
- agg::trans_affine &trans,
- ResultArray result)
-{
- typedef agg::conv_transform<PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> no_nans_t;
- typedef agg::conv_curve<no_nans_t> curve_t;
- typedef agg::conv_stroke<curve_t> stroke_t;
-
- size_t i;
- for (i = 0; i < points.size(); ++i) {
- result[i] = false;
- }
-
- transformed_path_t trans_path(path, trans);
- no_nans_t nan_removed_path(trans_path, true, path.has_curves());
- curve_t curved_path(nan_removed_path);
- stroke_t stroked_path(curved_path);
- stroked_path.width(r * 2.0);
- point_in_path_impl(points, stroked_path, result);
-}
-
-template <class PathIterator>
-inline bool point_on_path(
- double x, double y, const double r, PathIterator &path, agg::trans_affine &trans)
-{
- npy_intp shape[] = {1, 2};
- numpy::array_view<double, 2> points(shape);
- points(0, 0) = x;
- points(0, 1) = y;
-
- int result[1];
- result[0] = 0;
-
- points_on_path(points, r, path, trans, result);
-
- return (bool)result[0];
-}
-
-struct extent_limits
-{
- double x0;
- double y0;
- double x1;
- double y1;
- double xm;
- double ym;
-};
-
-void reset_limits(extent_limits &e)
-{
- e.x0 = std::numeric_limits<double>::infinity();
- e.y0 = std::numeric_limits<double>::infinity();
- e.x1 = -std::numeric_limits<double>::infinity();
- e.y1 = -std::numeric_limits<double>::infinity();
- /* xm and ym are the minimum positive values in the data, used
- by log scaling */
- e.xm = std::numeric_limits<double>::infinity();
- e.ym = std::numeric_limits<double>::infinity();
-}
-
-inline void update_limits(double x, double y, extent_limits &e)
-{
- if (x < e.x0)
- e.x0 = x;
- if (y < e.y0)
- e.y0 = y;
- if (x > e.x1)
- e.x1 = x;
- if (y > e.y1)
- e.y1 = y;
- /* xm and ym are the minimum positive values in the data, used
- by log scaling */
- if (x > 0.0 && x < e.xm)
- e.xm = x;
- if (y > 0.0 && y < e.ym)
- e.ym = y;
-}
-
-template <class PathIterator>
-void update_path_extents(PathIterator &path, agg::trans_affine &trans, extent_limits &extents)
-{
- typedef agg::conv_transform<PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removed_t;
- double x, y;
- unsigned code;
-
- transformed_path_t tpath(path, trans);
- nan_removed_t nan_removed(tpath, true, path.has_curves());
-
- nan_removed.rewind(0);
-
- while ((code = nan_removed.vertex(&x, &y)) != agg::path_cmd_stop) {
- if ((code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) {
- continue;
- }
- update_limits(x, y, extents);
- }
-}
-
-template <class PathGenerator, class TransformArray, class OffsetArray>
-void get_path_collection_extents(agg::trans_affine &master_transform,
- PathGenerator &paths,
- TransformArray &transforms,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- extent_limits &extent)
-{
- if (offsets.size() != 0 && offsets.dim(1) != 2) {
- throw std::runtime_error("Offsets array must be Nx2");
- }
-
- size_t Npaths = paths.size();
- size_t Noffsets = offsets.size();
- size_t N = std::max(Npaths, Noffsets);
- size_t Ntransforms = std::min(transforms.size(), N);
- size_t i;
-
- agg::trans_affine trans;
-
- reset_limits(extent);
-
- for (i = 0; i < N; ++i) {
- typename PathGenerator::path_iterator path(paths(i % Npaths));
- if (Ntransforms) {
- size_t ti = i % Ntransforms;
- trans = agg::trans_affine(transforms(ti, 0, 0),
- transforms(ti, 1, 0),
- transforms(ti, 0, 1),
- transforms(ti, 1, 1),
- transforms(ti, 0, 2),
- transforms(ti, 1, 2));
- } else {
- trans = master_transform;
- }
-
- if (Noffsets) {
- double xo = offsets(i % Noffsets, 0);
- double yo = offsets(i % Noffsets, 1);
- offset_trans.transform(&xo, &yo);
- trans *= agg::trans_affine_translation(xo, yo);
- }
-
- update_path_extents(path, trans, extent);
- }
-}
-
-template <class PathGenerator, class TransformArray, class OffsetArray>
-void point_in_path_collection(double x,
- double y,
- double radius,
- agg::trans_affine &master_transform,
- PathGenerator &paths,
- TransformArray &transforms,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- bool filled,
- e_offset_position offset_position,
- std::vector<int> &result)
-{
- size_t Npaths = paths.size();
-
- if (Npaths == 0) {
- return;
- }
-
- size_t Noffsets = offsets.size();
- size_t N = std::max(Npaths, Noffsets);
- size_t Ntransforms = std::min(transforms.size(), N);
- size_t i;
-
- agg::trans_affine trans;
-
- for (i = 0; i < N; ++i) {
- typename PathGenerator::path_iterator path = paths(i % Npaths);
-
- if (Ntransforms) {
- size_t ti = i % Ntransforms;
- trans = agg::trans_affine(transforms(ti, 0, 0),
- transforms(ti, 1, 0),
- transforms(ti, 0, 1),
- transforms(ti, 1, 1),
- transforms(ti, 0, 2),
- transforms(ti, 1, 2));
- trans *= master_transform;
- } else {
- trans = master_transform;
- }
-
- if (Noffsets) {
- double xo = offsets(i % Noffsets, 0);
- double yo = offsets(i % Noffsets, 1);
- offset_trans.transform(&xo, &yo);
- if (offset_position == OFFSET_POSITION_DATA) {
- trans = agg::trans_affine_translation(xo, yo) * trans;
- } else {
- trans *= agg::trans_affine_translation(xo, yo);
- }
- }
-
- if (filled) {
- if (point_in_path(x, y, radius, path, trans)) {
- result.push_back(i);
- }
- } else {
- if (point_on_path(x, y, radius, path, trans)) {
- result.push_back(i);
- }
- }
- }
-}
-
-template <class PathIterator1, class PathIterator2>
-bool path_in_path(PathIterator1 &a,
- agg::trans_affine &atrans,
- PathIterator2 &b,
- agg::trans_affine &btrans)
-{
- typedef agg::conv_transform<PathIterator2> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> no_nans_t;
- typedef agg::conv_curve<no_nans_t> curve_t;
-
- if (a.total_vertices() < 3) {
- return false;
- }
-
- transformed_path_t b_path_trans(b, btrans);
- no_nans_t b_no_nans(b_path_trans, true, b.has_curves());
- curve_t b_curved(b_no_nans);
-
- double x, y;
- b_curved.rewind(0);
- while (b_curved.vertex(&x, &y) != agg::path_cmd_stop) {
- if (!point_in_path(x, y, 0.0, a, atrans)) {
- return false;
- }
- }
-
- return true;
-}
-
-/** The clip_path_to_rect code here is a clean-room implementation of
- the Sutherland-Hodgman clipping algorithm described here:
-
- http://en.wikipedia.org/wiki/Sutherland-Hodgman_clipping_algorithm
-*/
-
-namespace clip_to_rect_filters
-{
-/* There are four different passes needed to create/remove
- vertices (one for each side of the rectangle). The differences
- between those passes are encapsulated in these functor classes.
-*/
-struct bisectx
-{
- double m_x;
-
- bisectx(double x) : m_x(x)
- {
- }
-
- inline void bisect(double sx, double sy, double px, double py, double *bx, double *by) const
- {
- *bx = m_x;
- double dx = px - sx;
- double dy = py - sy;
- *by = sy + dy * ((m_x - sx) / dx);
- }
-};
-
-struct xlt : public bisectx
-{
- xlt(double x) : bisectx(x)
- {
- }
-
- inline bool is_inside(double x, double y) const
- {
- return x <= m_x;
- }
-};
-
-struct xgt : public bisectx
-{
- xgt(double x) : bisectx(x)
- {
- }
-
- inline bool is_inside(double x, double y) const
- {
- return x >= m_x;
- }
-};
-
-struct bisecty
-{
- double m_y;
-
- bisecty(double y) : m_y(y)
- {
- }
-
- inline void bisect(double sx, double sy, double px, double py, double *bx, double *by) const
- {
- *by = m_y;
- double dx = px - sx;
- double dy = py - sy;
- *bx = sx + dx * ((m_y - sy) / dy);
- }
-};
-
-struct ylt : public bisecty
-{
- ylt(double y) : bisecty(y)
- {
- }
-
- inline bool is_inside(double x, double y) const
- {
- return y <= m_y;
- }
-};
-
-struct ygt : public bisecty
-{
- ygt(double y) : bisecty(y)
- {
- }
-
- inline bool is_inside(double x, double y) const
- {
- return y >= m_y;
- }
-};
-}
-
-template <class Filter>
-inline void clip_to_rect_one_step(const Polygon &polygon, Polygon &result, const Filter &filter)
-{
- double sx, sy, px, py, bx, by;
- bool sinside, pinside;
- result.clear();
-
- if (polygon.size() == 0) {
- return;
- }
-
- sx = polygon.back().x;
- sy = polygon.back().y;
- for (Polygon::const_iterator i = polygon.begin(); i != polygon.end(); ++i) {
- px = i->x;
- py = i->y;
-
- sinside = filter.is_inside(sx, sy);
- pinside = filter.is_inside(px, py);
-
- if (sinside ^ pinside) {
- filter.bisect(sx, sy, px, py, &bx, &by);
- result.push_back(XY(bx, by));
- }
-
- if (pinside) {
- result.push_back(XY(px, py));
- }
-
- sx = px;
- sy = py;
- }
-}
-
-template <class PathIterator>
-void
-clip_path_to_rect(PathIterator &path, agg::rect_d &rect, bool inside, std::vector<Polygon> &results)
-{
- double xmin, ymin, xmax, ymax;
- if (rect.x1 < rect.x2) {
- xmin = rect.x1;
- xmax = rect.x2;
- } else {
- xmin = rect.x2;
- xmax = rect.x1;
- }
-
- if (rect.y1 < rect.y2) {
- ymin = rect.y1;
- ymax = rect.y2;
- } else {
- ymin = rect.y2;
- ymax = rect.y1;
- }
-
- if (!inside) {
- std::swap(xmin, xmax);
- std::swap(ymin, ymax);
- }
-
- typedef agg::conv_curve<PathIterator> curve_t;
- curve_t curve(path);
-
- Polygon polygon1, polygon2;
- double x = 0, y = 0;
- unsigned code = 0;
- curve.rewind(0);
-
- do {
- // Grab the next subpath and store it in polygon1
- polygon1.clear();
- do {
- if (code == agg::path_cmd_move_to) {
- polygon1.push_back(XY(x, y));
- }
-
- code = curve.vertex(&x, &y);
-
- if (code == agg::path_cmd_stop) {
- break;
- }
-
- if (code != agg::path_cmd_move_to) {
- polygon1.push_back(XY(x, y));
- }
- } while ((code & agg::path_cmd_end_poly) != agg::path_cmd_end_poly);
-
- // The result of each step is fed into the next (note the
- // swapping of polygon1 and polygon2 at each step).
- clip_to_rect_one_step(polygon1, polygon2, clip_to_rect_filters::xlt(xmax));
- clip_to_rect_one_step(polygon2, polygon1, clip_to_rect_filters::xgt(xmin));
- clip_to_rect_one_step(polygon1, polygon2, clip_to_rect_filters::ylt(ymax));
- clip_to_rect_one_step(polygon2, polygon1, clip_to_rect_filters::ygt(ymin));
-
- // Empty polygons aren't very useful, so skip them
- if (polygon1.size()) {
- _finalize_polygon(results, 1);
- results.push_back(polygon1);
- }
- } while (code != agg::path_cmd_stop);
-
- _finalize_polygon(results, 1);
-}
-
-template <class VerticesArray, class ResultArray>
-void affine_transform_2d(VerticesArray &vertices, agg::trans_affine &trans, ResultArray &result)
-{
- if (vertices.size() != 0 && vertices.dim(1) != 2) {
- throw std::runtime_error("Invalid vertices array.");
- }
-
- size_t n = vertices.size();
- double x;
- double y;
- double t0;
- double t1;
- double t;
-
- for (size_t i = 0; i < n; ++i) {
- x = vertices(i, 0);
- y = vertices(i, 1);
-
- t0 = trans.sx * x;
- t1 = trans.shx * y;
- t = t0 + t1 + trans.tx;
- result(i, 0) = t;
-
- t0 = trans.shy * x;
- t1 = trans.sy * y;
- t = t0 + t1 + trans.ty;
- result(i, 1) = t;
- }
-}
-
-template <class VerticesArray, class ResultArray>
-void affine_transform_1d(VerticesArray &vertices, agg::trans_affine &trans, ResultArray &result)
-{
- if (vertices.dim(0) != 2) {
- throw std::runtime_error("Invalid vertices array.");
- }
-
- double x;
- double y;
- double t0;
- double t1;
- double t;
-
- x = vertices(0);
- y = vertices(1);
-
- t0 = trans.sx * x;
- t1 = trans.shx * y;
- t = t0 + t1 + trans.tx;
- result(0) = t;
-
- t0 = trans.shy * x;
- t1 = trans.sy * y;
- t = t0 + t1 + trans.ty;
- result(1) = t;
-}
-
-template <class BBoxArray>
-int count_bboxes_overlapping_bbox(agg::rect_d &a, BBoxArray &bboxes)
-{
- agg::rect_d b;
- int count = 0;
-
- if (a.x2 < a.x1) {
- std::swap(a.x1, a.x2);
- }
- if (a.y2 < a.y1) {
- std::swap(a.y1, a.y2);
- }
-
- size_t num_bboxes = bboxes.size();
- for (size_t i = 0; i < num_bboxes; ++i) {
- b = agg::rect_d(bboxes(i, 0, 0), bboxes(i, 0, 1), bboxes(i, 1, 0), bboxes(i, 1, 1));
-
- if (b.x2 < b.x1) {
- std::swap(b.x1, b.x2);
- }
- if (b.y2 < b.y1) {
- std::swap(b.y1, b.y2);
- }
- if (!((b.x2 <= a.x1) || (b.y2 <= a.y1) || (b.x1 >= a.x2) || (b.y1 >= a.y2))) {
- ++count;
- }
- }
-
- return count;
-}
-
-inline bool segments_intersect(const double &x1,
- const double &y1,
- const double &x2,
- const double &y2,
- const double &x3,
- const double &y3,
- const double &x4,
- const double &y4)
-{
- double den = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1));
- if (den == 0.0) {
- return false;
- }
-
- double n1 = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));
- double n2 = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3));
-
- double u1 = n1 / den;
- double u2 = n2 / den;
-
- return (u1 >= 0.0 && u1 <= 1.0 && u2 >= 0.0 && u2 <= 1.0);
-}
-
-template <class PathIterator1, class PathIterator2>
-bool path_intersects_path(PathIterator1 &p1, PathIterator2 &p2)
-{
- typedef PathNanRemover<py::PathIterator> no_nans_t;
- typedef agg::conv_curve<no_nans_t> curve_t;
-
- if (p1.total_vertices() < 2 || p2.total_vertices() < 2) {
- return false;
- }
-
- no_nans_t n1(p1, true, p1.has_curves());
- no_nans_t n2(p2, true, p2.has_curves());
-
- curve_t c1(n1);
- curve_t c2(n2);
-
- double x11, y11, x12, y12;
- double x21, y21, x22, y22;
-
- c1.vertex(&x11, &y11);
- while (c1.vertex(&x12, &y12) != agg::path_cmd_stop) {
- c2.rewind(0);
- c2.vertex(&x21, &y21);
- while (c2.vertex(&x22, &y22) != agg::path_cmd_stop) {
- if (segments_intersect(x11, y11, x12, y12, x21, y21, x22, y22)) {
- return true;
- }
- x21 = x22;
- y21 = y22;
- }
- x11 = x12;
- y11 = y12;
- }
-
- return false;
-}
-
-// returns whether the segment from (x1,y1) to (x2,y2)
-// intersects the rectangle centered at (cx,cy) with size (w,h)
-// see doc/segment_intersects_rectangle.svg for a more detailed explanation
-inline bool segment_intersects_rectangle(double x1, double y1,
- double x2, double y2,
- double cx, double cy,
- double w, double h)
-{
- return fabs(x1 + x2 - 2.0 * cx) < fabs(x1 - x2) + w &&
- fabs(y1 + y2 - 2.0 * cy) < fabs(y1 - y2) + h &&
- 2.0 * fabs((x1 - cx) * (y1 - y2) - (y1 - cy) * (x1 - x2)) <
- w * fabs(y1 - y2) + h * fabs(x1 - x2);
-}
-
-template <class PathIterator>
-bool path_intersects_rectangle(PathIterator &path,
- double rect_x1, double rect_y1,
- double rect_x2, double rect_y2,
- bool filled)
-{
- typedef PathNanRemover<py::PathIterator> no_nans_t;
- typedef agg::conv_curve<no_nans_t> curve_t;
-
- if (path.total_vertices() == 0) {
- return false;
- }
-
- no_nans_t no_nans(path, true, path.has_curves());
- curve_t curve(no_nans);
-
- double cx = (rect_x1 + rect_x2) * 0.5, cy = (rect_y1 + rect_y2) * 0.5;
- double w = fabs(rect_x1 - rect_x2), h = fabs(rect_y1 - rect_y2);
-
- double x1, y1, x2, y2;
-
- curve.vertex(&x1, &y1);
- if (2.0 * fabs(x1 - cx) <= w && 2.0 * fabs(y1 - cy) <= h) {
- return true;
- }
-
- while (curve.vertex(&x2, &y2) != agg::path_cmd_stop) {
- if (segment_intersects_rectangle(x1, y1, x2, y2, cx, cy, w, h)) {
- return true;
- }
- x1 = x2;
- y1 = y2;
- }
-
- if (filled) {
- agg::trans_affine trans;
- if (point_in_path(cx, cy, 0.0, path, trans)) {
- return true;
- }
- }
-
- return false;
-}
-
-template <class PathIterator>
-void convert_path_to_polygons(PathIterator &path,
- agg::trans_affine &trans,
- double width,
- double height,
- int closed_only,
- std::vector<Polygon> &result)
-{
- typedef agg::conv_transform<py::PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removal_t;
- typedef PathClipper<nan_removal_t> clipped_t;
- typedef PathSimplifier<clipped_t> simplify_t;
- typedef agg::conv_curve<simplify_t> curve_t;
-
- bool do_clip = width != 0.0 && height != 0.0;
- bool simplify = path.should_simplify();
-
- transformed_path_t tpath(path, trans);
- nan_removal_t nan_removed(tpath, true, path.has_curves());
- clipped_t clipped(nan_removed, do_clip && !path.has_curves(), width, height);
- simplify_t simplified(clipped, simplify, path.simplify_threshold());
- curve_t curve(simplified);
-
- result.push_back(Polygon());
- Polygon *polygon = &result.back();
- double x, y;
- unsigned code;
-
- while ((code = curve.vertex(&x, &y)) != agg::path_cmd_stop) {
- if ((code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) {
- _finalize_polygon(result, 1);
- result.push_back(Polygon());
- polygon = &result.back();
- } else {
- if (code == agg::path_cmd_move_to) {
- _finalize_polygon(result, closed_only);
- result.push_back(Polygon());
- polygon = &result.back();
- }
- polygon->push_back(XY(x, y));
- }
- }
-
- _finalize_polygon(result, closed_only);
-}
-
-template <class VertexSource>
-void
-__cleanup_path(VertexSource &source, std::vector<double> &vertices, std::vector<npy_uint8> &codes)
-{
- unsigned code;
- double x, y;
- do {
- code = source.vertex(&x, &y);
- vertices.push_back(x);
- vertices.push_back(y);
- codes.push_back((npy_uint8)code);
- } while (code != agg::path_cmd_stop);
-}
-
-template <class PathIterator>
-void cleanup_path(PathIterator &path,
- agg::trans_affine &trans,
- bool remove_nans,
- bool do_clip,
- const agg::rect_base<double> &rect,
- e_snap_mode snap_mode,
- double stroke_width,
- bool do_simplify,
- bool return_curves,
- SketchParams sketch_params,
- std::vector<double> &vertices,
- std::vector<unsigned char> &codes)
-{
- typedef agg::conv_transform<py::PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removal_t;
- typedef PathClipper<nan_removal_t> clipped_t;
- typedef PathSnapper<clipped_t> snapped_t;
- typedef PathSimplifier<snapped_t> simplify_t;
- typedef agg::conv_curve<simplify_t> curve_t;
- typedef Sketch<curve_t> sketch_t;
-
- transformed_path_t tpath(path, trans);
- nan_removal_t nan_removed(tpath, remove_nans, path.has_curves());
- clipped_t clipped(nan_removed, do_clip && !path.has_curves(), rect);
- snapped_t snapped(clipped, snap_mode, path.total_vertices(), stroke_width);
- simplify_t simplified(snapped, do_simplify, path.simplify_threshold());
-
- vertices.reserve(path.total_vertices() * 2);
- codes.reserve(path.total_vertices());
-
- if (return_curves && sketch_params.scale == 0.0) {
- __cleanup_path(simplified, vertices, codes);
- } else {
- curve_t curve(simplified);
- sketch_t sketch(curve, sketch_params.scale, sketch_params.length, sketch_params.randomness);
- __cleanup_path(sketch, vertices, codes);
- }
-}
-
-void quad2cubic(double x0, double y0,
- double x1, double y1,
- double x2, double y2,
- double *outx, double *outy)
-{
-
- outx[0] = x0 + 2./3. * (x1 - x0);
- outy[0] = y0 + 2./3. * (y1 - y0);
- outx[1] = outx[0] + 1./3. * (x2 - x0);
- outy[1] = outy[0] + 1./3. * (y2 - y0);
- outx[2] = x2;
- outy[2] = y2;
-}
-
-char *__append_to_string(char *p, char **buffer, size_t *buffersize,
- const char *content)
-{
- for (const char *i = content; *i; ++i) {
- if (p < *buffer) {
- /* This is just an internal error */
- return NULL;
- }
- if ((size_t)(p - *buffer) >= *buffersize) {
- ptrdiff_t diff = p - *buffer;
- *buffersize *= 2;
- *buffer = (char *)realloc(*buffer, *buffersize);
- if (*buffer == NULL) {
- return NULL;
- }
- p = *buffer + diff;
- }
-
- *p++ = *i;
- }
-
- return p;
-}
-
-
-char *__add_number(double val, const char *format, int precision,
- char **buffer, char *p, size_t *buffersize)
-{
- char *result;
-
-#if PY_VERSION_HEX >= 0x02070000
- char *str;
- str = PyOS_double_to_string(val, format[0], precision, 0, NULL);
-#else
- char str[64];
- PyOS_ascii_formatd(str, 64, format, val);
-#endif
-
- // Delete trailing zeros and decimal point
- char *q = str;
- for (; *q != 0; ++q) {
- // Find the end of the string
- }
-
- --q;
- for (; q >= str && *q == '0'; --q) {
- // Rewind through all the zeros
- }
-
- // If the end is a decimal qoint, delete that too
- if (q >= str && *q == '.') {
- --q;
- }
-
- // Truncate the string
- ++q;
- *q = 0;
-
-#if PY_VERSION_HEX >= 0x02070000
- if ((result = __append_to_string(p, buffer, buffersize, str)) == NULL) {
- PyMem_Free(str);
- return NULL;
- }
- PyMem_Free(str);
-#else
- if ((result = __append_to_string(p, buffer, buffersize, str)) == NULL) {
- return NULL;
- }
-#endif
-
- return result;
-}
-
-
-template <class PathIterator>
-int __convert_to_string(PathIterator &path,
- int precision,
- char **codes,
- bool postfix,
- char **buffer,
- size_t *buffersize)
-{
-#if PY_VERSION_HEX >= 0x02070000
- const char *format = "f";
-#else
- char format[64];
- snprintf(format, 64, "%s.%df", "%", precision);
-#endif
-
- char *p = *buffer;
- double x[3];
- double y[3];
- double last_x = 0.0;
- double last_y = 0.0;
-
- const int sizes[] = { 1, 1, 2, 3 };
- int size = 0;
- unsigned code;
-
- while ((code = path.vertex(&x[0], &y[0])) != agg::path_cmd_stop) {
- if (code == 0x4f) {
- if ((p = __append_to_string(p, buffer, buffersize, codes[4])) == NULL) return 1;
- } else if (code < 5) {
- size = sizes[code - 1];
-
- for (int i = 1; i < size; ++i) {
- unsigned subcode = path.vertex(&x[i], &y[i]);
- if (subcode != code) {
- return 2;
- }
- }
-
- /* For formats that don't support quad curves, convert to
- cubic curves */
- if (code == CURVE3 && codes[code - 1][0] == '\0') {
- quad2cubic(last_x, last_y, x[0], y[0], x[1], y[1], x, y);
- code++;
- size = 3;
- }
-
- if (!postfix) {
- if ((p = __append_to_string(p, buffer, buffersize, codes[code - 1])) == NULL) return 1;
- if ((p = __append_to_string(p, buffer, buffersize, " ")) == NULL) return 1;
- }
-
- for (int i = 0; i < size; ++i) {
- if ((p = __add_number(x[i], format, precision, buffer, p, buffersize)) == NULL) return 1;
- if ((p = __append_to_string(p, buffer, buffersize, " ")) == NULL) return 1;
- if ((p = __add_number(y[i], format, precision, buffer, p, buffersize)) == NULL) return 1;
- if ((p = __append_to_string(p, buffer, buffersize, " ")) == NULL) return 1;
- }
-
- if (postfix) {
- if ((p = __append_to_string(p, buffer, buffersize, codes[code - 1])) == NULL) return 1;
- }
-
- last_x = x[size - 1];
- last_y = y[size - 1];
- } else {
- // Unknown code value
- return 2;
- }
-
- if ((p = __append_to_string(p, buffer, buffersize, "\n")) == NULL) return 1;
- }
-
- *buffersize = p - *buffer;
-
- return 0;
-}
-
-template <class PathIterator>
-int convert_to_string(PathIterator &path,
- agg::trans_affine &trans,
- agg::rect_d &clip_rect,
- bool simplify,
- SketchParams sketch_params,
- int precision,
- char **codes,
- bool postfix,
- char **buffer,
- size_t *buffersize)
-{
- typedef agg::conv_transform<py::PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removal_t;
- typedef PathClipper<nan_removal_t> clipped_t;
- typedef PathSimplifier<clipped_t> simplify_t;
- typedef agg::conv_curve<simplify_t> curve_t;
- typedef Sketch<curve_t> sketch_t;
-
- bool do_clip = (clip_rect.x1 < clip_rect.x2 && clip_rect.y1 < clip_rect.y2);
-
- transformed_path_t tpath(path, trans);
- nan_removal_t nan_removed(tpath, true, path.has_curves());
- clipped_t clipped(nan_removed, do_clip && !path.has_curves(), clip_rect);
- simplify_t simplified(clipped, simplify, path.simplify_threshold());
-
- *buffersize = path.total_vertices() * (precision + 5) * 4;
- if (*buffersize == 0) {
- return 0;
- }
-
- if (sketch_params.scale != 0.0) {
- *buffersize *= 10.0;
- }
-
- *buffer = (char *)malloc(*buffersize);
- if (*buffer == NULL) {
- return 1;
- }
-
- if (sketch_params.scale == 0.0) {
- return __convert_to_string(simplified, precision, codes, postfix, buffer, buffersize);
- } else {
- curve_t curve(simplified);
- sketch_t sketch(curve, sketch_params.scale, sketch_params.length, sketch_params.randomness);
- return __convert_to_string(sketch, precision, codes, postfix, buffer, buffersize);
- }
-
-}
-
-template<class T>
-struct _is_sorted
-{
- bool operator()(PyArrayObject *array)
- {
- npy_intp size;
- npy_intp i;
- T last_value;
- T current_value;
-
- size = PyArray_DIM(array, 0);
-
- // std::isnan is only in C++11, which we don't yet require,
- // so we use the "self == self" trick
- for (i = 0; i < size; ++i) {
- last_value = *((T *)PyArray_GETPTR1(array, i));
- if (last_value == last_value) {
- break;
- }
- }
-
- if (i == size) {
- // The whole array is non-finite
- return false;
- }
-
- for (; i < size; ++i) {
- current_value = *((T *)PyArray_GETPTR1(array, i));
- if (current_value == current_value) {
- if (current_value < last_value) {
- return false;
- }
- last_value = current_value;
- }
- }
-
- return true;
- }
-};
-
-
-template<class T>
-struct _is_sorted_int
-{
- bool operator()(PyArrayObject *array)
- {
- npy_intp size;
- npy_intp i;
- T last_value;
- T current_value;
-
- size = PyArray_DIM(array, 0);
-
- last_value = *((T *)PyArray_GETPTR1(array, 0));
-
- for (i = 1; i < size; ++i) {
- current_value = *((T *)PyArray_GETPTR1(array, i));
- if (current_value < last_value) {
- return false;
- }
- last_value = current_value;
- }
-
- return true;
- }
-};
-
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/_path_wrapper.cpp b/contrib/python/matplotlib/py2/src/_path_wrapper.cpp
deleted file mode 100644
index 08a595e7c4..0000000000
--- a/contrib/python/matplotlib/py2/src/_path_wrapper.cpp
+++ /dev/null
@@ -1,900 +0,0 @@
-#include "numpy_cpp.h"
-
-#include "_path.h"
-
-#include "py_converters.h"
-#include "py_adaptors.h"
-
-PyObject *convert_polygon_vector(std::vector<Polygon> &polygons)
-{
- PyObject *pyresult = PyList_New(polygons.size());
-
- for (size_t i = 0; i < polygons.size(); ++i) {
- Polygon poly = polygons[i];
- npy_intp dims[2];
- dims[1] = 2;
-
- dims[0] = (npy_intp)poly.size();
-
- numpy::array_view<double, 2> subresult(dims);
- memcpy(subresult.data(), &poly[0], sizeof(double) * poly.size() * 2);
-
- if (PyList_SetItem(pyresult, i, subresult.pyobj())) {
- Py_DECREF(pyresult);
- return NULL;
- }
- }
-
- return pyresult;
-}
-
-const char *Py_point_in_path__doc__ = "point_in_path(x, y, radius, path, trans)";
-
-static PyObject *Py_point_in_path(PyObject *self, PyObject *args, PyObject *kwds)
-{
- double x, y, r;
- py::PathIterator path;
- agg::trans_affine trans;
- bool result;
-
- if (!PyArg_ParseTuple(args,
- "dddO&O&:point_in_path",
- &x,
- &y,
- &r,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- CALL_CPP("point_in_path", (result = point_in_path(x, y, r, path, trans)));
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-const char *Py_points_in_path__doc__ = "points_in_path(points, radius, path, trans)";
-
-static PyObject *Py_points_in_path(PyObject *self, PyObject *args, PyObject *kwds)
-{
- numpy::array_view<const double, 2> points;
- double r;
- py::PathIterator path;
- agg::trans_affine trans;
-
- if (!PyArg_ParseTuple(args,
- "O&dO&O&:points_in_path",
- &convert_points,
- &points,
- &r,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- npy_intp dims[] = { (npy_intp)points.size() };
- numpy::array_view<uint8_t, 1> results(dims);
-
- CALL_CPP("points_in_path", (points_in_path(points, r, path, trans, results)));
-
- return results.pyobj();
-}
-
-const char *Py_point_on_path__doc__ = "point_on_path(x, y, radius, path, trans)";
-
-static PyObject *Py_point_on_path(PyObject *self, PyObject *args, PyObject *kwds)
-{
- double x, y, r;
- py::PathIterator path;
- agg::trans_affine trans;
- bool result;
-
- if (!PyArg_ParseTuple(args,
- "dddO&O&:point_on_path",
- &x,
- &y,
- &r,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- CALL_CPP("point_on_path", (result = point_on_path(x, y, r, path, trans)));
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-const char *Py_points_on_path__doc__ = "points_on_path(points, radius, path, trans)";
-
-static PyObject *Py_points_on_path(PyObject *self, PyObject *args, PyObject *kwds)
-{
- numpy::array_view<const double, 2> points;
- double r;
- py::PathIterator path;
- agg::trans_affine trans;
-
- if (!PyArg_ParseTuple(args,
- "O&dO&O&:points_on_path",
- &convert_points,
- &points,
- &r,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- npy_intp dims[] = { (npy_intp)points.size() };
- numpy::array_view<uint8_t, 1> results(dims);
-
- CALL_CPP("points_on_path", (points_on_path(points, r, path, trans, results)));
-
- return results.pyobj();
-}
-
-const char *Py_get_path_extents__doc__ = "get_path_extents(path, trans)";
-
-static PyObject *Py_get_path_extents(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator path;
- agg::trans_affine trans;
-
- if (!PyArg_ParseTuple(
- args, "O&O&:get_path_extents", &convert_path, &path, &convert_trans_affine, &trans)) {
- return NULL;
- }
-
- extent_limits e;
-
- CALL_CPP("get_path_extents", (reset_limits(e)));
- CALL_CPP("get_path_extents", (update_path_extents(path, trans, e)));
-
- npy_intp dims[] = { 2, 2 };
- numpy::array_view<double, 2> extents(dims);
- extents(0, 0) = e.x0;
- extents(0, 1) = e.y0;
- extents(1, 0) = e.x1;
- extents(1, 1) = e.y1;
-
- return extents.pyobj();
-}
-
-const char *Py_update_path_extents__doc__ =
- "update_path_extents(path, trans, rect, minpos, ignore)";
-
-static PyObject *Py_update_path_extents(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator path;
- agg::trans_affine trans;
- agg::rect_d rect;
- numpy::array_view<double, 1> minpos;
- int ignore;
- int changed;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&i:update_path_extents",
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &convert_rect,
- &rect,
- &minpos.converter,
- &minpos,
- &ignore)) {
- return NULL;
- }
-
- if (minpos.dim(0) != 2) {
- PyErr_Format(PyExc_ValueError,
- "minpos must be of length 2, got %" NPY_INTP_FMT,
- minpos.dim(0));
- return NULL;
- }
-
- extent_limits e;
-
- if (ignore) {
- CALL_CPP("update_path_extents", reset_limits(e));
- } else {
- if (rect.x1 > rect.x2) {
- e.x0 = std::numeric_limits<double>::infinity();
- e.x1 = -std::numeric_limits<double>::infinity();
- } else {
- e.x0 = rect.x1;
- e.x1 = rect.x2;
- }
- if (rect.y1 > rect.y2) {
- e.y0 = std::numeric_limits<double>::infinity();
- e.y1 = -std::numeric_limits<double>::infinity();
- } else {
- e.y0 = rect.y1;
- e.y1 = rect.y2;
- }
- e.xm = minpos(0);
- e.ym = minpos(1);
- }
-
- CALL_CPP("update_path_extents", (update_path_extents(path, trans, e)));
-
- changed = (e.x0 != rect.x1 || e.y0 != rect.y1 || e.x1 != rect.x2 || e.y1 != rect.y2 ||
- e.xm != minpos(0) || e.ym != minpos(1));
-
- npy_intp extentsdims[] = { 2, 2 };
- numpy::array_view<double, 2> outextents(extentsdims);
- outextents(0, 0) = e.x0;
- outextents(0, 1) = e.y0;
- outextents(1, 0) = e.x1;
- outextents(1, 1) = e.y1;
-
- npy_intp minposdims[] = { 2 };
- numpy::array_view<double, 1> outminpos(minposdims);
- outminpos(0) = e.xm;
- outminpos(1) = e.ym;
-
- return Py_BuildValue(
- "NNi", outextents.pyobj(), outminpos.pyobj(), changed);
-}
-
-const char *Py_get_path_collection_extents__doc__ = "get_path_collection_extents(";
-
-static PyObject *Py_get_path_collection_extents(PyObject *self, PyObject *args, PyObject *kwds)
-{
- agg::trans_affine master_transform;
- PyObject *pathsobj;
- numpy::array_view<const double, 3> transforms;
- numpy::array_view<const double, 2> offsets;
- agg::trans_affine offset_trans;
- extent_limits e;
-
- if (!PyArg_ParseTuple(args,
- "O&OO&O&O&:get_path_collection_extents",
- &convert_trans_affine,
- &master_transform,
- &pathsobj,
- &convert_transforms,
- &transforms,
- &convert_points,
- &offsets,
- &convert_trans_affine,
- &offset_trans)) {
- return NULL;
- }
-
- try
- {
- py::PathGenerator paths(pathsobj);
-
- CALL_CPP("get_path_collection_extents",
- (get_path_collection_extents(
- master_transform, paths, transforms, offsets, offset_trans, e)));
- }
- catch (const py::exception &)
- {
- return NULL;
- }
-
- npy_intp dims[] = { 2, 2 };
- numpy::array_view<double, 2> extents(dims);
- extents(0, 0) = e.x0;
- extents(0, 1) = e.y0;
- extents(1, 0) = e.x1;
- extents(1, 1) = e.y1;
-
- return extents.pyobj();
-}
-
-const char *Py_point_in_path_collection__doc__ =
- "point_in_path_collection(x, y, radius, master_transform, paths, transforms, offsets, "
- "offset_trans, filled, offset_position)";
-
-static PyObject *Py_point_in_path_collection(PyObject *self, PyObject *args, PyObject *kwds)
-{
- double x, y, radius;
- agg::trans_affine master_transform;
- PyObject *pathsobj;
- numpy::array_view<const double, 3> transforms;
- numpy::array_view<const double, 2> offsets;
- agg::trans_affine offset_trans;
- int filled;
- e_offset_position offset_position;
- std::vector<int> result;
-
- if (!PyArg_ParseTuple(args,
- "dddO&OO&O&O&iO&:point_in_path_collection",
- &x,
- &y,
- &radius,
- &convert_trans_affine,
- &master_transform,
- &pathsobj,
- &convert_transforms,
- &transforms,
- &convert_points,
- &offsets,
- &convert_trans_affine,
- &offset_trans,
- &filled,
- &convert_offset_position,
- &offset_position)) {
- return NULL;
- }
-
- try
- {
- py::PathGenerator paths(pathsobj);
-
- CALL_CPP("point_in_path_collection",
- (point_in_path_collection(x,
- y,
- radius,
- master_transform,
- paths,
- transforms,
- offsets,
- offset_trans,
- filled,
- offset_position,
- result)));
- }
- catch (const py::exception &)
- {
- return NULL;
- }
-
- npy_intp dims[] = {(npy_intp)result.size() };
- numpy::array_view<int, 1> pyresult(dims);
- if (result.size() > 0) {
- memcpy(pyresult.data(), &result[0], result.size() * sizeof(int));
- }
- return pyresult.pyobj();
-}
-
-const char *Py_path_in_path__doc__ = "path_in_path(path_a, trans_a, path_b, trans_b)";
-
-static PyObject *Py_path_in_path(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator a;
- agg::trans_affine atrans;
- py::PathIterator b;
- agg::trans_affine btrans;
- bool result;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&:path_in_path",
- &convert_path,
- &a,
- &convert_trans_affine,
- &atrans,
- &convert_path,
- &b,
- &convert_trans_affine,
- &btrans)) {
- return NULL;
- }
-
- CALL_CPP("path_in_path", (result = path_in_path(a, atrans, b, btrans)));
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-const char *Py_clip_path_to_rect__doc__ = "clip_path_to_rect(path, rect, inside)";
-
-static PyObject *Py_clip_path_to_rect(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator path;
- agg::rect_d rect;
- int inside;
- std::vector<Polygon> result;
-
- if (!PyArg_ParseTuple(args,
- "O&O&i:clip_path_to_rect",
- &convert_path,
- &path,
- &convert_rect,
- &rect,
- &inside)) {
- return NULL;
- }
-
- CALL_CPP("clip_path_to_rect", (clip_path_to_rect(path, rect, inside, result)));
-
- return convert_polygon_vector(result);
-}
-
-const char *Py_affine_transform__doc__ = "affine_transform(points, trans)";
-
-static PyObject *Py_affine_transform(PyObject *self, PyObject *args, PyObject *kwds)
-{
- PyObject *vertices_obj;
- agg::trans_affine trans;
-
- if (!PyArg_ParseTuple(args,
- "OO&:affine_transform",
- &vertices_obj,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- try {
- numpy::array_view<double, 2> vertices(vertices_obj);
- npy_intp dims[] = { (npy_intp)vertices.size(), 2 };
- numpy::array_view<double, 2> result(dims);
- CALL_CPP("affine_transform", (affine_transform_2d(vertices, trans, result)));
- return result.pyobj();
- } catch (py::exception &) {
- PyErr_Clear();
- try {
- numpy::array_view<double, 1> vertices(vertices_obj);
- npy_intp dims[] = { (npy_intp)vertices.size() };
- numpy::array_view<double, 1> result(dims);
- CALL_CPP("affine_transform", (affine_transform_1d(vertices, trans, result)));
- return result.pyobj();
- } catch (py::exception &) {
- return NULL;
- }
- }
-}
-
-const char *Py_count_bboxes_overlapping_bbox__doc__ = "count_bboxes_overlapping_bbox(bbox, bboxes)";
-
-static PyObject *Py_count_bboxes_overlapping_bbox(PyObject *self, PyObject *args, PyObject *kwds)
-{
- agg::rect_d bbox;
- numpy::array_view<const double, 3> bboxes;
- int result;
-
- if (!PyArg_ParseTuple(args,
- "O&O&:count_bboxes_overlapping_bbox",
- &convert_rect,
- &bbox,
- &convert_bboxes,
- &bboxes)) {
- return NULL;
- }
-
- CALL_CPP("count_bboxes_overlapping_bbox",
- (result = count_bboxes_overlapping_bbox(bbox, bboxes)));
-
- return PyLong_FromLong(result);
-}
-
-const char *Py_path_intersects_path__doc__ = "path_intersects_path(path1, path2, filled=False)";
-
-static PyObject *Py_path_intersects_path(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator p1;
- py::PathIterator p2;
- agg::trans_affine t1;
- agg::trans_affine t2;
- int filled = 0;
- const char *names[] = { "p1", "p2", "filled", NULL };
- bool result;
-
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O&O&i:path_intersects_path",
- (char **)names,
- &convert_path,
- &p1,
- &convert_path,
- &p2,
- &filled)) {
- return NULL;
- }
-
- CALL_CPP("path_intersects_path", (result = path_intersects_path(p1, p2)));
- if (filled) {
- if (!result) {
- CALL_CPP("path_intersects_path",
- (result = path_in_path(p1, t1, p2, t2)));
- }
- if (!result) {
- CALL_CPP("path_intersects_path",
- (result = path_in_path(p2, t1, p1, t2)));
- }
- }
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-const char *Py_path_intersects_rectangle__doc__ = "path_intersects_rectangle(path, rect_x1, rect_y1, rect_x2, rect_y2, filled=False)";
-
-static PyObject *Py_path_intersects_rectangle(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator path;
- double rect_x1, rect_y1, rect_x2, rect_y2;
- int filled = 0;
- const char *names[] = { "path", "rect_x1", "rect_y1", "rect_x2", "rect_y2", "filled", NULL };
- bool result;
-
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O&dddd|i:path_intersects_rectangle",
- (char **)names,
- &convert_path,
- &path,
- &rect_x1,
- &rect_y1,
- &rect_x2,
- &rect_y2,
- &filled)) {
- return NULL;
- }
-
- CALL_CPP("path_intersects_rectangle", (result = path_intersects_rectangle(path, rect_x1, rect_y1, rect_x2, rect_y2, filled)));
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-const char *Py_convert_path_to_polygons__doc__ =
- "convert_path_to_polygons(path, trans, width=0, height=0)";
-
-static PyObject *Py_convert_path_to_polygons(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator path;
- agg::trans_affine trans;
- double width = 0.0, height = 0.0;
- int closed_only = 1;
- std::vector<Polygon> result;
- const char *names[] = { "path", "transform", "width", "height", "closed_only", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O&O&|ddi:convert_path_to_polygons",
- (char **)names,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &width,
- &height,
- &closed_only)) {
- return NULL;
- }
-
- CALL_CPP("convert_path_to_polygons",
- (convert_path_to_polygons(path, trans, width, height, closed_only, result)));
-
- return convert_polygon_vector(result);
-}
-
-const char *Py_cleanup_path__doc__ =
- "cleanup_path(path, trans, remove_nans, clip_rect, snap_mode, stroke_width, simplify, "
- "return_curves, sketch)";
-
-static PyObject *Py_cleanup_path(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator path;
- agg::trans_affine trans;
- int remove_nans;
- agg::rect_d clip_rect;
- e_snap_mode snap_mode;
- double stroke_width;
- PyObject *simplifyobj;
- bool simplify = false;
- int return_curves;
- SketchParams sketch;
-
- if (!PyArg_ParseTuple(args,
- "O&O&iO&O&dOiO&:cleanup_path",
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &remove_nans,
- &convert_rect,
- &clip_rect,
- &convert_snap,
- &snap_mode,
- &stroke_width,
- &simplifyobj,
- &return_curves,
- &convert_sketch_params,
- &sketch)) {
- return NULL;
- }
-
- if (simplifyobj == Py_None) {
- simplify = path.should_simplify();
- } else if (PyObject_IsTrue(simplifyobj)) {
- simplify = true;
- }
-
- bool do_clip = (clip_rect.x1 < clip_rect.x2 && clip_rect.y1 < clip_rect.y2);
-
- std::vector<double> vertices;
- std::vector<npy_uint8> codes;
-
- CALL_CPP("cleanup_path",
- (cleanup_path(path,
- trans,
- remove_nans,
- do_clip,
- clip_rect,
- snap_mode,
- stroke_width,
- simplify,
- return_curves,
- sketch,
- vertices,
- codes)));
-
- size_t length = codes.size();
-
- npy_intp vertices_dims[] = {(npy_intp)length, 2 };
- numpy::array_view<double, 2> pyvertices(vertices_dims);
-
- npy_intp codes_dims[] = {(npy_intp)length };
- numpy::array_view<unsigned char, 1> pycodes(codes_dims);
-
- memcpy(pyvertices.data(), &vertices[0], sizeof(double) * 2 * length);
- memcpy(pycodes.data(), &codes[0], sizeof(unsigned char) * length);
-
- return Py_BuildValue("NN", pyvertices.pyobj(), pycodes.pyobj());
-}
-
-const char *Py_convert_to_string__doc__ = "convert_to_string(path, trans, "
- "clip_rect, simplify, sketch, precision, codes, postfix)";
-
-static PyObject *Py_convert_to_string(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator path;
- agg::trans_affine trans;
- agg::rect_d cliprect;
- PyObject *simplifyobj;
- bool simplify = false;
- SketchParams sketch;
- int precision;
- PyObject *codesobj;
- char *codes[5];
- int postfix;
- char *buffer = NULL;
- size_t buffersize;
- PyObject *result;
- int status;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&OO&iOi:convert_to_string",
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &convert_rect,
- &cliprect,
- &simplifyobj,
- &convert_sketch_params,
- &sketch,
- &precision,
- &codesobj,
- &postfix)) {
- return NULL;
- }
-
- if (simplifyobj == Py_None) {
- simplify = path.should_simplify();
- } else if (PyObject_IsTrue(simplifyobj)) {
- simplify = true;
- }
-
- if (!PySequence_Check(codesobj)) {
- return NULL;
- }
- if (PySequence_Size(codesobj) != 5) {
- PyErr_SetString(
- PyExc_ValueError,
- "codes must be a 5-length sequence of byte strings");
- return NULL;
- }
- for (int i = 0; i < 5; ++i) {
- PyObject *item = PySequence_GetItem(codesobj, i);
- if (item == NULL) {
- return NULL;
- }
- codes[i] = PyBytes_AsString(item);
- if (codes[i] == NULL) {
- return NULL;
- }
- }
-
- CALL_CPP("convert_to_string",
- (status = convert_to_string(
- path, trans, cliprect, simplify, sketch,
- precision, codes, (bool)postfix, &buffer,
- &buffersize)));
-
- if (status) {
- free(buffer);
- if (status == 1) {
- PyErr_SetString(PyExc_MemoryError, "Memory error");
- } else if (status == 2) {
- PyErr_SetString(PyExc_ValueError, "Malformed path codes");
- }
- return NULL;
- }
-
- if (buffersize == 0) {
- result = PyBytes_FromString("");
- } else {
- result = PyBytes_FromStringAndSize(buffer, buffersize);
- }
-
- free(buffer);
-
- return result;
-}
-
-
-const char *Py_is_sorted__doc__ = "is_sorted(array)\n\n"
- "Returns True if 1-D array is monotonically increasing, ignoring NaNs\n";
-
-static PyObject *Py_is_sorted(PyObject *self, PyObject *obj)
-{
- npy_intp size;
- bool result;
-
- PyArrayObject *array = (PyArrayObject *)PyArray_FromAny(
- obj, NULL, 1, 1, 0, NULL);
-
- if (array == NULL) {
- return NULL;
- }
-
- size = PyArray_DIM(array, 0);
-
- if (size < 2) {
- Py_DECREF(array);
- Py_RETURN_TRUE;
- }
-
- /* Handle just the most common types here, otherwise coerce to
- double */
- switch(PyArray_TYPE(array)) {
- case NPY_INT:
- {
- _is_sorted_int<npy_int> is_sorted;
- result = is_sorted(array);
- }
- break;
-
- case NPY_LONG:
- {
- _is_sorted_int<npy_long> is_sorted;
- result = is_sorted(array);
- }
- break;
-
- case NPY_LONGLONG:
- {
- _is_sorted_int<npy_longlong> is_sorted;
- result = is_sorted(array);
- }
- break;
-
- case NPY_FLOAT:
- {
- _is_sorted<npy_float> is_sorted;
- result = is_sorted(array);
- }
- break;
-
- case NPY_DOUBLE:
- {
- _is_sorted<npy_double> is_sorted;
- result = is_sorted(array);
- }
- break;
-
- default:
- {
- Py_DECREF(array);
- array = (PyArrayObject *)PyArray_FromObject(obj, NPY_DOUBLE, 1, 1);
-
- if (array == NULL) {
- return NULL;
- }
-
- _is_sorted<npy_double> is_sorted;
- result = is_sorted(array);
- }
- }
-
- Py_DECREF(array);
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-
-extern "C" {
-
- static PyMethodDef module_functions[] = {
- {"point_in_path", (PyCFunction)Py_point_in_path, METH_VARARGS, Py_point_in_path__doc__},
- {"points_in_path", (PyCFunction)Py_points_in_path, METH_VARARGS, Py_points_in_path__doc__},
- {"point_on_path", (PyCFunction)Py_point_on_path, METH_VARARGS, Py_point_on_path__doc__},
- {"points_on_path", (PyCFunction)Py_points_on_path, METH_VARARGS, Py_points_on_path__doc__},
- {"get_path_extents", (PyCFunction)Py_get_path_extents, METH_VARARGS, Py_get_path_extents__doc__},
- {"update_path_extents", (PyCFunction)Py_update_path_extents, METH_VARARGS, Py_update_path_extents__doc__},
- {"get_path_collection_extents", (PyCFunction)Py_get_path_collection_extents, METH_VARARGS, Py_get_path_collection_extents__doc__},
- {"point_in_path_collection", (PyCFunction)Py_point_in_path_collection, METH_VARARGS, Py_point_in_path_collection__doc__},
- {"path_in_path", (PyCFunction)Py_path_in_path, METH_VARARGS, Py_path_in_path__doc__},
- {"clip_path_to_rect", (PyCFunction)Py_clip_path_to_rect, METH_VARARGS, Py_clip_path_to_rect__doc__},
- {"affine_transform", (PyCFunction)Py_affine_transform, METH_VARARGS, Py_affine_transform__doc__},
- {"count_bboxes_overlapping_bbox", (PyCFunction)Py_count_bboxes_overlapping_bbox, METH_VARARGS, Py_count_bboxes_overlapping_bbox__doc__},
- {"path_intersects_path", (PyCFunction)Py_path_intersects_path, METH_VARARGS|METH_KEYWORDS, Py_path_intersects_path__doc__},
- {"path_intersects_rectangle", (PyCFunction)Py_path_intersects_rectangle, METH_VARARGS|METH_KEYWORDS, Py_path_intersects_rectangle__doc__},
- {"convert_path_to_polygons", (PyCFunction)Py_convert_path_to_polygons, METH_VARARGS|METH_KEYWORDS, Py_convert_path_to_polygons__doc__},
- {"cleanup_path", (PyCFunction)Py_cleanup_path, METH_VARARGS, Py_cleanup_path__doc__},
- {"convert_to_string", (PyCFunction)Py_convert_to_string, METH_VARARGS, Py_convert_to_string__doc__},
- {"is_sorted", (PyCFunction)Py_is_sorted, METH_O, Py_is_sorted__doc__},
- {NULL}
- };
-
-#if PY3K
- static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_path",
- NULL,
- 0,
- module_functions,
- NULL,
- NULL,
- NULL,
- NULL
- };
-
-#define INITERROR return NULL
- PyMODINIT_FUNC PyInit__path(void)
-#else
-#define INITERROR return
- PyMODINIT_FUNC init_path(void)
-#endif
- {
- PyObject *m;
-#if PY3K
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("_path", module_functions, NULL);
-#endif
-
- if (m == NULL) {
- INITERROR;
- }
-
- import_array();
-
-#if PY3K
- return m;
-#endif
- }
-}
diff --git a/contrib/python/matplotlib/py2/src/_png.cpp b/contrib/python/matplotlib/py2/src/_png.cpp
deleted file mode 100644
index ea7bf32efe..0000000000
--- a/contrib/python/matplotlib/py2/src/_png.cpp
+++ /dev/null
@@ -1,793 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/* For linux, png.h must be imported before Python.h because
- png.h needs to be the one to define setjmp.
- Undefining _POSIX_C_SOURCE and _XOPEN_SOURCE stops a couple
- of harmless warnings.
-*/
-#define PY_SSIZE_T_CLEAN
-
-extern "C" {
-# include <png.h>
-# ifdef _POSIX_C_SOURCE
-# undef _POSIX_C_SOURCE
-# endif
-# ifndef _AIX
-# ifdef _XOPEN_SOURCE
-# undef _XOPEN_SOURCE
-# endif
-# endif
-}
-
-#include "numpy_cpp.h"
-#include "mplutils.h"
-#include "file_compat.h"
-
-# include <vector>
-# include "Python.h"
-
-
-// As reported in [3082058] build _png.so on aix
-#ifdef _AIX
-#undef jmpbuf
-#endif
-
-struct buffer_t {
- PyObject *str;
- size_t cursor;
- size_t size;
-};
-
-
-static void write_png_data_buffer(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- buffer_t *buff = (buffer_t *)png_get_io_ptr(png_ptr);
- if (buff->cursor + length < buff->size) {
- memcpy(PyBytes_AS_STRING(buff->str) + buff->cursor, data, length);
- buff->cursor += length;
- }
-}
-
-static void flush_png_data_buffer(png_structp png_ptr)
-{
-
-}
-
-static void write_png_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- PyObject *py_file_obj = (PyObject *)png_get_io_ptr(png_ptr);
- PyObject *write_method = PyObject_GetAttrString(py_file_obj, "write");
- PyObject *result = NULL;
- if (write_method) {
-#if PY3K
- result = PyObject_CallFunction(write_method, (char *)"y#", data, length);
-#else
- result = PyObject_CallFunction(write_method, (char *)"s#", data, length);
-#endif
- }
- Py_XDECREF(write_method);
- Py_XDECREF(result);
-}
-
-static void flush_png_data(png_structp png_ptr)
-{
- PyObject *py_file_obj = (PyObject *)png_get_io_ptr(png_ptr);
- PyObject *flush_method = PyObject_GetAttrString(py_file_obj, "flush");
- PyObject *result = NULL;
- if (flush_method) {
- result = PyObject_CallFunction(flush_method, (char *)"");
- }
- Py_XDECREF(flush_method);
- Py_XDECREF(result);
-}
-
-const char *Py_write_png__doc__ =
- "write_png(buffer, file, dpi=0, compression=6, filter=auto, metadata=None)\n"
- "\n"
- "Parameters\n"
- "----------\n"
- "buffer : numpy array of image data\n"
- " Must be an MxNxD array of dtype uint8.\n"
- " - if D is 1, the image is greyscale\n"
- " - if D is 3, the image is RGB\n"
- " - if D is 4, the image is RGBA\n"
- "\n"
- "file : str path, file-like object or None\n"
- " - If a str, must be a file path\n"
- " - If a file-like object, must write bytes\n"
- " - If None, a byte string containing the PNG data will be returned\n"
- "\n"
- "dpi : float\n"
- " The dpi to store in the file metadata.\n"
- "\n"
- "compression : int\n"
- " The level of lossless zlib compression to apply. 0 indicates no\n"
- " compression. Values 1-9 indicate low/fast through high/slow\n"
- " compression. Default is 6.\n"
- "\n"
- "filter : int\n"
- " Filter to apply. Must be one of the constants: PNG_FILTER_NONE,\n"
- " PNG_FILTER_SUB, PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH.\n"
- " See the PNG standard for more information.\n"
- " If not provided, libpng will try to automatically determine the\n"
- " best filter on a line-by-line basis.\n"
- "\n"
- "metadata : dictionary\n"
- " The keyword-text pairs that are stored as comments in the image.\n"
- " Keys must be shorter than 79 chars. The only supported encoding\n"
- " for both keywords and values is Latin-1 (ISO 8859-1).\n"
- " Examples given in the PNG Specification are:\n"
- " - Title: Short (one line) title or caption for image\n"
- " - Author: Name of image's creator\n"
- " - Description: Description of image (possibly long)\n"
- " - Copyright: Copyright notice\n"
- " - Creation Time: Time of original image creation\n"
- " (usually RFC 1123 format, see below)\n"
- " - Software: Software used to create the image\n"
- " - Disclaimer: Legal disclaimer\n"
- " - Warning: Warning of nature of content\n"
- " - Source: Device used to create the image\n"
- " - Comment: Miscellaneous comment; conversion\n"
- " from other image format\n"
- "\n"
- "Returns\n"
- "-------\n"
- "buffer : bytes or None\n"
- " Byte string containing the PNG content if None was passed in for\n"
- " file, otherwise None is returned.\n";
-
-// this code is heavily adapted from
-// https://www.object-craft.com.au/projects/paint/ which licensed under the
-// (BSD compatible) LICENSE_PAINT which is included in this distribution.
-static PyObject *Py_write_png(PyObject *self, PyObject *args, PyObject *kwds)
-{
- numpy::array_view<unsigned char, 3> buffer;
- PyObject *filein;
- PyObject *metadata = NULL;
- PyObject *meta_key, *meta_val;
- png_text *text;
- Py_ssize_t pos = 0;
- int meta_pos = 0;
- Py_ssize_t meta_size;
- double dpi = 0;
- int compression = 6;
- int filter = -1;
- const char *names[] = { "buffer", "file", "dpi", "compression", "filter", "metadata", NULL };
-
- // We don't need strict contiguity, just for each row to be
- // contiguous, and libpng has special handling for getting RGB out
- // of RGBA, ARGB or BGR. But the simplest thing to do is to
- // enforce contiguity using array_view::converter_contiguous.
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O&O|diiO:write_png",
- (char **)names,
- &buffer.converter_contiguous,
- &buffer,
- &filein,
- &dpi,
- &compression,
- &filter,
- &metadata)) {
- return NULL;
- }
-
- png_uint_32 width = (png_uint_32)buffer.dim(1);
- png_uint_32 height = (png_uint_32)buffer.dim(0);
- int channels = buffer.dim(2);
- std::vector<png_bytep> row_pointers(height);
- for (png_uint_32 row = 0; row < (png_uint_32)height; ++row) {
- row_pointers[row] = (png_bytep)&buffer(row, 0, 0);
- }
-
- FILE *fp = NULL;
- mpl_off_t offset = 0;
- bool close_file = false;
- bool close_dup_file = false;
- PyObject *py_file = NULL;
-
- png_structp png_ptr = NULL;
- png_infop info_ptr = NULL;
- struct png_color_8_struct sig_bit;
- int png_color_type;
- buffer_t buff;
- buff.str = NULL;
-
- switch (channels) {
- case 1:
- png_color_type = PNG_COLOR_TYPE_GRAY;
- break;
- case 3:
- png_color_type = PNG_COLOR_TYPE_RGB;
- break;
- case 4:
- png_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
- break;
- default:
- PyErr_SetString(PyExc_ValueError,
- "Buffer must be an NxMxD array with D in 1, 3, 4 "
- "(grayscale, RGB, RGBA)");
- goto exit;
- }
-
- if (compression < 0 || compression > 9) {
- PyErr_Format(PyExc_ValueError,
- "compression must be in range 0-9, got %d", compression);
- goto exit;
- }
-
- if (PyBytes_Check(filein) || PyUnicode_Check(filein)) {
- if ((py_file = mpl_PyFile_OpenFile(filein, (char *)"wb")) == NULL) {
- goto exit;
- }
- close_file = true;
- } else {
- py_file = filein;
- }
-
- if (filein == Py_None) {
- buff.size = width * height * 4 + 1024;
- buff.str = PyBytes_FromStringAndSize(NULL, buff.size);
- if (buff.str == NULL) {
- goto exit;
- }
- buff.cursor = 0;
- } else {
- #if PY3K
- if (close_file) {
- #else
- if (close_file || PyFile_Check(py_file)) {
- #endif
- fp = mpl_PyFile_Dup(py_file, (char *)"wb", &offset);
- }
-
- if (fp) {
- close_dup_file = true;
- } else {
- PyErr_Clear();
- PyObject *write_method = PyObject_GetAttrString(py_file, "write");
- if (!(write_method && PyCallable_Check(write_method))) {
- Py_XDECREF(write_method);
- PyErr_SetString(PyExc_TypeError,
- "Object does not appear to be a 8-bit string path or "
- "a Python file-like object");
- goto exit;
- }
- Py_XDECREF(write_method);
- }
- }
-
- png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (png_ptr == NULL) {
- PyErr_SetString(PyExc_RuntimeError, "Could not create write struct");
- goto exit;
- }
-
- png_set_compression_level(png_ptr, compression);
- if (filter >= 0) {
- png_set_filter(png_ptr, 0, filter);
- }
-
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL) {
- PyErr_SetString(PyExc_RuntimeError, "Could not create info struct");
- goto exit;
- }
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- PyErr_SetString(PyExc_RuntimeError, "libpng signaled error");
- goto exit;
- }
-
- if (buff.str) {
- png_set_write_fn(png_ptr, (void *)&buff, &write_png_data_buffer, &flush_png_data_buffer);
- } else if (fp) {
- png_init_io(png_ptr, fp);
- } else {
- png_set_write_fn(png_ptr, (void *)py_file, &write_png_data, &flush_png_data);
- }
- png_set_IHDR(png_ptr,
- info_ptr,
- width,
- height,
- 8,
- png_color_type,
- PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_BASE,
- PNG_FILTER_TYPE_BASE);
-
- // Save the dpi of the image in the file
- if (dpi > 0.0) {
- png_uint_32 dots_per_meter = (png_uint_32)(dpi / (2.54 / 100.0));
- png_set_pHYs(png_ptr, info_ptr, dots_per_meter, dots_per_meter, PNG_RESOLUTION_METER);
- }
-
-#ifdef PNG_TEXT_SUPPORTED
- // Save the metadata
- if (metadata != NULL) {
- meta_size = PyDict_Size(metadata);
- text = new png_text[meta_size];
-
- while (PyDict_Next(metadata, &pos, &meta_key, &meta_val)) {
- text[meta_pos].compression = PNG_TEXT_COMPRESSION_NONE;
-#if PY3K
- if (PyUnicode_Check(meta_key)) {
- PyObject *temp_key = PyUnicode_AsEncodedString(meta_key, "latin_1", "strict");
- if (temp_key != NULL) {
- text[meta_pos].key = PyBytes_AsString(temp_key);
- }
- } else if (PyBytes_Check(meta_key)) {
- text[meta_pos].key = PyBytes_AsString(meta_key);
- } else {
- char invalid_key[79];
- sprintf(invalid_key,"INVALID KEY %d", meta_pos);
- text[meta_pos].key = invalid_key;
- }
- if (PyUnicode_Check(meta_val)) {
- PyObject *temp_val = PyUnicode_AsEncodedString(meta_val, "latin_1", "strict");
- if (temp_val != NULL) {
- text[meta_pos].text = PyBytes_AsString(temp_val);
- }
- } else if (PyBytes_Check(meta_val)) {
- text[meta_pos].text = PyBytes_AsString(meta_val);
- } else {
- text[meta_pos].text = (char *)"Invalid value in metadata";
- }
-#else
- text[meta_pos].key = PyString_AsString(meta_key);
- text[meta_pos].text = PyString_AsString(meta_val);
-#endif
-#ifdef PNG_iTXt_SUPPORTED
- text[meta_pos].lang = NULL;
-#endif
- meta_pos++;
- }
- png_set_text(png_ptr, info_ptr, text, meta_size);
- delete[] text;
- }
-#endif
-
- sig_bit.alpha = 0;
- switch (png_color_type) {
- case PNG_COLOR_TYPE_GRAY:
- sig_bit.gray = 8;
- sig_bit.red = 0;
- sig_bit.green = 0;
- sig_bit.blue = 0;
- break;
- case PNG_COLOR_TYPE_RGB_ALPHA:
- sig_bit.alpha = 8;
- // fall through
- case PNG_COLOR_TYPE_RGB:
- sig_bit.gray = 0;
- sig_bit.red = 8;
- sig_bit.green = 8;
- sig_bit.blue = 8;
- break;
- default:
- PyErr_SetString(PyExc_RuntimeError, "internal error, bad png_color_type");
- goto exit;
- }
- png_set_sBIT(png_ptr, info_ptr, &sig_bit);
-
- png_write_info(png_ptr, info_ptr);
- png_write_image(png_ptr, &row_pointers[0]);
- png_write_end(png_ptr, info_ptr);
-
-exit:
-
- if (png_ptr && info_ptr) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- }
-
- if (close_dup_file) {
- mpl_PyFile_DupClose(py_file, fp, offset);
- }
-
- if (close_file) {
- mpl_PyFile_CloseFile(py_file);
- Py_DECREF(py_file);
- }
-
- if (PyErr_Occurred()) {
- Py_XDECREF(buff.str);
- return NULL;
- } else {
- if (buff.str) {
- _PyBytes_Resize(&buff.str, buff.cursor);
- return buff.str;
- }
- Py_RETURN_NONE;
- }
-}
-
-static void _read_png_data(PyObject *py_file_obj, png_bytep data, png_size_t length)
-{
- PyObject *read_method = PyObject_GetAttrString(py_file_obj, "read");
- PyObject *result = NULL;
- char *buffer;
- Py_ssize_t bufflen;
- if (read_method) {
- result = PyObject_CallFunction(read_method, (char *)"i", length);
- if (result) {
- if (PyBytes_AsStringAndSize(result, &buffer, &bufflen) == 0) {
- if (bufflen == (Py_ssize_t)length) {
- memcpy(data, buffer, length);
- } else {
- PyErr_SetString(PyExc_IOError, "read past end of file");
- }
- } else {
- PyErr_SetString(PyExc_IOError, "failed to copy buffer");
- }
- } else {
- PyErr_SetString(PyExc_IOError, "failed to read file");
- }
-
-
- }
- Py_XDECREF(read_method);
- Py_XDECREF(result);
-}
-
-static void read_png_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- PyObject *py_file_obj = (PyObject *)png_get_io_ptr(png_ptr);
- _read_png_data(py_file_obj, data, length);
- if (PyErr_Occurred()) {
- png_error(png_ptr, "failed to read file");
- }
-
-}
-
-static PyObject *_read_png(PyObject *filein, bool float_result)
-{
- png_byte header[8]; // 8 is the maximum size that can be checked
- FILE *fp = NULL;
- mpl_off_t offset = 0;
- bool close_file = false;
- bool close_dup_file = false;
- PyObject *py_file = NULL;
- png_structp png_ptr = NULL;
- png_infop info_ptr = NULL;
- int num_dims;
- std::vector<png_bytep> row_pointers;
- png_uint_32 width = 0;
- png_uint_32 height = 0;
- int bit_depth;
- PyObject *result = NULL;
-
- // TODO: Remove direct calls to Numpy API here
-
- if (PyBytes_Check(filein) || PyUnicode_Check(filein)) {
- if ((py_file = mpl_PyFile_OpenFile(filein, (char *)"rb")) == NULL) {
- goto exit;
- }
- close_file = true;
- } else {
- py_file = filein;
- }
-
- #if PY3K
- if (close_file) {
- #else
- if (close_file || PyFile_Check(py_file)) {
- #endif
- fp = mpl_PyFile_Dup(py_file, (char *)"rb", &offset);
- }
-
- if (fp) {
- close_dup_file = true;
- if (fread(header, 1, 8, fp) != 8) {
- PyErr_SetString(PyExc_IOError, "error reading PNG header");
- goto exit;
- }
- } else {
- PyErr_Clear();
-
- PyObject *read_method = PyObject_GetAttrString(py_file, "read");
- if (!(read_method && PyCallable_Check(read_method))) {
- Py_XDECREF(read_method);
- PyErr_SetString(PyExc_TypeError,
- "Object does not appear to be a 8-bit string path or "
- "a Python file-like object");
- goto exit;
- }
- Py_XDECREF(read_method);
- _read_png_data(py_file, header, 8);
- if (PyErr_Occurred()) {
- goto exit;
- }
- }
-
- if (png_sig_cmp(header, 0, 8)) {
- PyErr_SetString(PyExc_ValueError, "invalid PNG header");
- goto exit;
- }
-
- /* initialize stuff */
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-
- if (!png_ptr) {
- PyErr_SetString(PyExc_RuntimeError, "png_create_read_struct failed");
- goto exit;
- }
-
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr) {
- PyErr_SetString(PyExc_RuntimeError, "png_create_info_struct failed");
- goto exit;
- }
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- if (!PyErr_Occurred()) {
- PyErr_SetString(PyExc_RuntimeError, "error setting jump");
- }
- goto exit;
- }
-
- if (fp) {
- png_init_io(png_ptr, fp);
- } else {
- png_set_read_fn(png_ptr, (void *)py_file, &read_png_data);
- }
- png_set_sig_bytes(png_ptr, 8);
- png_read_info(png_ptr, info_ptr);
-
- width = png_get_image_width(png_ptr, info_ptr);
- height = png_get_image_height(png_ptr, info_ptr);
-
- bit_depth = png_get_bit_depth(png_ptr, info_ptr);
-
- // Unpack 1, 2, and 4-bit images
- if (bit_depth < 8) {
- png_set_packing(png_ptr);
- }
-
- // If sig bits are set, shift data
- png_color_8p sig_bit;
- if ((png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_PALETTE) &&
- png_get_sBIT(png_ptr, info_ptr, &sig_bit)) {
- png_set_shift(png_ptr, sig_bit);
- }
-
-#if NPY_BYTE_ORDER == NPY_LITTLE_ENDIAN
- // Convert big endian to little
- if (bit_depth == 16) {
- png_set_swap(png_ptr);
- }
-#endif
-
- // Convert palletes to full RGB
- if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) {
- png_set_palette_to_rgb(png_ptr);
- bit_depth = 8;
- }
-
- // If there's an alpha channel convert gray to RGB
- if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY_ALPHA) {
- png_set_gray_to_rgb(png_ptr);
- }
-
- png_set_interlace_handling(png_ptr);
- png_read_update_info(png_ptr, info_ptr);
-
- row_pointers.resize(height);
- for (png_uint_32 row = 0; row < height; row++) {
- row_pointers[row] = new png_byte[png_get_rowbytes(png_ptr, info_ptr)];
- }
-
- png_read_image(png_ptr, &row_pointers[0]);
-
- npy_intp dimensions[3];
- dimensions[0] = height; // numrows
- dimensions[1] = width; // numcols
- if (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_ALPHA) {
- dimensions[2] = 4; // RGBA images
- } else if (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_COLOR) {
- dimensions[2] = 3; // RGB images
- } else {
- dimensions[2] = 1; // Greyscale images
- }
-
- if (float_result) {
- double max_value = (1 << bit_depth) - 1;
-
- numpy::array_view<float, 3> A(dimensions);
-
- for (png_uint_32 y = 0; y < height; y++) {
- png_byte *row = row_pointers[y];
- for (png_uint_32 x = 0; x < width; x++) {
- if (bit_depth == 16) {
- png_uint_16 *ptr = &reinterpret_cast<png_uint_16 *>(row)[x * dimensions[2]];
- for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) {
- A(y, x, p) = (float)(ptr[p]) / max_value;
- }
- } else {
- png_byte *ptr = &(row[x * dimensions[2]]);
- for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) {
- A(y, x, p) = (float)(ptr[p]) / max_value;
- }
- }
- }
- }
-
- result = A.pyobj();
- } else if (bit_depth == 16) {
- numpy::array_view<png_uint_16, 3> A(dimensions);
-
- for (png_uint_32 y = 0; y < height; y++) {
- png_byte *row = row_pointers[y];
- for (png_uint_32 x = 0; x < width; x++) {
- png_uint_16 *ptr = &reinterpret_cast<png_uint_16 *>(row)[x * dimensions[2]];
- for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) {
- A(y, x, p) = ptr[p];
- }
- }
- }
-
- result = A.pyobj();
- } else if (bit_depth == 8) {
- numpy::array_view<png_byte, 3> A(dimensions);
-
- for (png_uint_32 y = 0; y < height; y++) {
- png_byte *row = row_pointers[y];
- for (png_uint_32 x = 0; x < width; x++) {
- png_byte *ptr = &(row[x * dimensions[2]]);
- for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) {
- A(y, x, p) = ptr[p];
- }
- }
- }
-
- result = A.pyobj();
- } else {
- PyErr_SetString(PyExc_RuntimeError, "image has unknown bit depth");
- goto exit;
- }
-
- // free the png memory
- png_read_end(png_ptr, info_ptr);
-
- // For gray, return an x by y array, not an x by y by 1
- num_dims = (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_COLOR) ? 3 : 2;
-
- if (num_dims == 2) {
- PyArray_Dims dims = {dimensions, 2};
- PyObject *reshaped = PyArray_Newshape((PyArrayObject *)result, &dims, NPY_CORDER);
- Py_DECREF(result);
- result = reshaped;
- }
-
-exit:
- if (png_ptr && info_ptr) {
-#ifndef png_infopp_NULL
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
-#else
- png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
-#endif
- }
-
- if (close_dup_file) {
- mpl_PyFile_DupClose(py_file, fp, offset);
- }
-
- if (close_file) {
- mpl_PyFile_CloseFile(py_file);
- Py_DECREF(py_file);
- }
-
- for (png_uint_32 row = 0; row < height; row++) {
- delete[] row_pointers[row];
- }
-
- if (PyErr_Occurred()) {
- Py_XDECREF(result);
- return NULL;
- } else {
- return result;
- }
-}
-
-const char *Py_read_png_float__doc__ =
- "read_png_float(file)\n"
- "\n"
- "Read in a PNG file, converting values to floating-point doubles\n"
- "in the range (0, 1)\n"
- "\n"
- "Parameters\n"
- "----------\n"
- "file : str path or file-like object\n";
-
-static PyObject *Py_read_png_float(PyObject *self, PyObject *args, PyObject *kwds)
-{
- return _read_png(args, true);
-}
-
-const char *Py_read_png_int__doc__ =
- "read_png_int(file)\n"
- "\n"
- "Read in a PNG file with original integer values.\n"
- "\n"
- "Parameters\n"
- "----------\n"
- "file : str path or file-like object\n";
-
-static PyObject *Py_read_png_int(PyObject *self, PyObject *args, PyObject *kwds)
-{
- return _read_png(args, false);
-}
-
-const char *Py_read_png__doc__ =
- "read_png(file)\n"
- "\n"
- "Read in a PNG file, converting values to floating-point doubles\n"
- "in the range (0, 1)\n"
- "\n"
- "Alias for read_png_float()\n"
- "\n"
- "Parameters\n"
- "----------\n"
- "file : str path or file-like object\n";
-
-static PyMethodDef module_methods[] = {
- {"write_png", (PyCFunction)Py_write_png, METH_VARARGS|METH_KEYWORDS, Py_write_png__doc__},
- {"read_png", (PyCFunction)Py_read_png_float, METH_O, Py_read_png__doc__},
- {"read_png_float", (PyCFunction)Py_read_png_float, METH_O, Py_read_png_float__doc__},
- {"read_png_int", (PyCFunction)Py_read_png_int, METH_O, Py_read_png_int__doc__},
- {NULL}
-};
-
-extern "C" {
-
-#if PY3K
- static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_png",
- NULL,
- 0,
- module_methods,
- NULL,
- NULL,
- NULL,
- NULL
- };
-
-#define INITERROR return NULL
-
- PyMODINIT_FUNC PyInit__png(void)
-
-#else
-#define INITERROR return
-
- PyMODINIT_FUNC init_png(void)
-#endif
-
- {
- PyObject *m;
-
-#if PY3K
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("_png", module_methods, NULL);
-#endif
-
- if (m == NULL) {
- INITERROR;
- }
-
- import_array();
-
- if (PyModule_AddIntConstant(m, "PNG_FILTER_NONE", PNG_FILTER_NONE) ||
- PyModule_AddIntConstant(m, "PNG_FILTER_SUB", PNG_FILTER_SUB) ||
- PyModule_AddIntConstant(m, "PNG_FILTER_UP", PNG_FILTER_UP) ||
- PyModule_AddIntConstant(m, "PNG_FILTER_AVG", PNG_FILTER_AVG) ||
- PyModule_AddIntConstant(m, "PNG_FILTER_PAETH", PNG_FILTER_PAETH)) {
- INITERROR;
- }
-
-
-#if PY3K
- return m;
-#endif
- }
-}
diff --git a/contrib/python/matplotlib/py2/src/_tkagg.cpp b/contrib/python/matplotlib/py2/src/_tkagg.cpp
deleted file mode 100644
index 106f1398b3..0000000000
--- a/contrib/python/matplotlib/py2/src/_tkagg.cpp
+++ /dev/null
@@ -1,475 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/*
- * This code is derived from The Python Imaging Library and is covered
- * by the PIL license.
- *
- * See LICENSE/LICENSE.PIL for details.
- *
- */
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-#include <cstdlib>
-#include <cstdio>
-#include <sstream>
-
-#include <agg_basics.h> // agg:int8u
-
-// Include our own excerpts from the Tcl / Tk headers
-#include "_tkmini.h"
-
-#if defined(_MSC_VER)
-# define IMG_FORMAT "%d %d %Iu"
-#else
-# define IMG_FORMAT "%d %d %zu"
-#endif
-#define BBOX_FORMAT "%f %f %f %f"
-
-typedef struct
-{
- PyObject_HEAD
- Tcl_Interp *interp;
-} TkappObject;
-
-// Global vars for Tcl / Tk functions. We load these symbols from the tkinter
-// extension module or loaded Tcl / Tk libraries at run-time.
-static Tcl_CreateCommand_t TCL_CREATE_COMMAND;
-static Tcl_AppendResult_t TCL_APPEND_RESULT;
-static Tk_MainWindow_t TK_MAIN_WINDOW;
-static Tk_FindPhoto_t TK_FIND_PHOTO;
-static Tk_PhotoPutBlock_NoComposite_t TK_PHOTO_PUT_BLOCK_NO_COMPOSITE;
-static Tk_PhotoBlank_t TK_PHOTO_BLANK;
-
-static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
- argc, char **argv)
-{
- Tk_PhotoHandle photo;
- Tk_PhotoImageBlock block;
-
- // vars for blitting
-
- size_t pdata;
- int wdata, hdata, bbox_parse;
- float x1, x2, y1, y2;
- bool has_bbox;
- agg::int8u *destbuffer, *buffer;
- int destx, desty, destwidth, destheight, deststride;
-
- long mode;
- long nval;
- if (TK_MAIN_WINDOW(interp) == NULL) {
- // Will throw a _tkinter.TclError with "this isn't a Tk application"
- return TCL_ERROR;
- }
-
- if (argc != 5) {
- TCL_APPEND_RESULT(interp, "usage: ", argv[0], " destPhoto srcImage", (char *)NULL);
- return TCL_ERROR;
- }
-
- /* get Tcl PhotoImage handle */
- photo = TK_FIND_PHOTO(interp, argv[1]);
- if (photo == NULL) {
- TCL_APPEND_RESULT(interp, "destination photo must exist", (char *)NULL);
- return TCL_ERROR;
- }
- /* get buffer from str which is "height width ptr" */
- if (sscanf(argv[2], IMG_FORMAT, &hdata, &wdata, &pdata) != 3) {
- TCL_APPEND_RESULT(interp,
- "error reading data, expected height width ptr",
- (char *)NULL);
- return TCL_ERROR;
- }
- buffer = (agg::int8u*)pdata;
-
- /* get array mode (0=mono, 1=rgb, 2=rgba) */
- mode = atol(argv[3]);
- if ((mode != 0) && (mode != 1) && (mode != 2)) {
- TCL_APPEND_RESULT(interp, "illegal image mode", (char *)NULL);
- return TCL_ERROR;
- }
-
- /* check for bbox/blitting */
- bbox_parse = sscanf(argv[4], BBOX_FORMAT, &x1, &x2, &y1, &y2);
- if (bbox_parse == 4) {
- has_bbox = true;
- }
- else if ((bbox_parse == 1) && (x1 == 0)){
- has_bbox = false;
- } else {
- TCL_APPEND_RESULT(interp, "illegal bbox", (char *)NULL);
- return TCL_ERROR;
- }
-
- if (has_bbox) {
- int srcstride = wdata * 4;
- destx = (int)x1;
- desty = (int)(hdata - y2);
- destwidth = (int)(x2 - x1);
- destheight = (int)(y2 - y1);
- deststride = 4 * destwidth;
-
- destbuffer = new agg::int8u[deststride * destheight];
- if (destbuffer == NULL) {
- TCL_APPEND_RESULT(interp, "could not allocate memory", (char *)NULL);
- return TCL_ERROR;
- }
-
- for (int i = 0; i < destheight; ++i) {
- memcpy(destbuffer + (deststride * i),
- &buffer[(i + desty) * srcstride + (destx * 4)],
- deststride);
- }
- } else {
- destbuffer = NULL;
- destx = desty = destwidth = destheight = deststride = 0;
- }
-
- /* setup tkblock */
- block.pixelSize = 1;
- if (mode == 0) {
- block.offset[0] = block.offset[1] = block.offset[2] = 0;
- nval = 1;
- } else {
- block.offset[0] = 0;
- block.offset[1] = 1;
- block.offset[2] = 2;
- if (mode == 1) {
- block.offset[3] = 0;
- block.pixelSize = 3;
- nval = 3;
- } else {
- block.offset[3] = 3;
- block.pixelSize = 4;
- nval = 4;
- }
- }
-
- if (has_bbox) {
- block.width = destwidth;
- block.height = destheight;
- block.pitch = deststride;
- block.pixelPtr = destbuffer;
-
- TK_PHOTO_PUT_BLOCK_NO_COMPOSITE(photo, &block, destx, desty,
- destwidth, destheight);
- delete[] destbuffer;
-
- } else {
- block.width = wdata;
- block.height = hdata;
- block.pitch = (int)block.width * nval;
- block.pixelPtr = buffer;
-
- /* Clear current contents */
- TK_PHOTO_BLANK(photo);
- /* Copy opaque block to photo image, and leave the rest to TK */
- TK_PHOTO_PUT_BLOCK_NO_COMPOSITE(photo, &block, 0, 0, block.width,
- block.height);
- }
-
- return TCL_OK;
-}
-
-static PyObject *_tkinit(PyObject *self, PyObject *args)
-{
- Tcl_Interp *interp;
- TkappObject *app;
-
- PyObject *arg;
- int is_interp;
- if (!PyArg_ParseTuple(args, "Oi", &arg, &is_interp)) {
- return NULL;
- }
-
- if (is_interp) {
- interp = (Tcl_Interp *)PyLong_AsVoidPtr(arg);
- } else {
- /* Do it the hard way. This will break if the TkappObject
- layout changes */
- app = (TkappObject *)arg;
- interp = app->interp;
- }
-
- /* This will bomb if interp is invalid... */
-
- TCL_CREATE_COMMAND(interp,
- "PyAggImagePhoto",
- (Tcl_CmdProc *)PyAggImagePhoto,
- (ClientData)0,
- (Tcl_CmdDeleteProc *)NULL);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyMethodDef functions[] = {
- /* Tkinter interface stuff */
- { "tkinit", (PyCFunction)_tkinit, 1 },
- { NULL, NULL } /* sentinel */
-};
-
-// Functions to fill global TCL / Tk function pointers by dynamic loading
-#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
-
-/*
- * On Windows, we can't load the tkinter module to get the TCL or Tk symbols,
- * because Windows does not load symbols into the library name-space of
- * importing modules. So, knowing that tkinter has already been imported by
- * Python, we scan all modules in the running process for the TCL and Tk
- * function names.
- */
-#include <windows.h>
-#define PSAPI_VERSION 1
-#include <psapi.h>
-// Must be linked with 'psapi' library
-
-FARPROC _dfunc(HMODULE lib_handle, const char *func_name)
-{
- // Load function `func_name` from `lib_handle`.
- // Set Python exception if we can't find `func_name` in `lib_handle`.
- // Returns function pointer or NULL if not present.
-
- char message[100];
-
- FARPROC func = GetProcAddress(lib_handle, func_name);
- if (func == NULL) {
- sprintf(message, "Cannot load function %s", func_name);
- PyErr_SetString(PyExc_RuntimeError, message);
- }
- return func;
-}
-
-int get_tcl(HMODULE hMod)
-{
- // Try to fill TCL global vars with function pointers. Return 0 for no
- // functions found, 1 for all functions found, -1 for some but not all
- // functions found.
- TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)
- GetProcAddress(hMod, "Tcl_CreateCommand");
- if (TCL_CREATE_COMMAND == NULL) { // Maybe not TCL module
- return 0;
- }
- TCL_APPEND_RESULT = (Tcl_AppendResult_t) _dfunc(hMod,
- "Tcl_AppendResult");
- return (TCL_APPEND_RESULT == NULL) ? -1 : 1;
-}
-
-int get_tk(HMODULE hMod)
-{
- // Try to fill Tk global vars with function pointers. Return 0 for no
- // functions found, 1 for all functions found, -1 for some but not all
- // functions found.
- TK_MAIN_WINDOW = (Tk_MainWindow_t)
- GetProcAddress(hMod, "Tk_MainWindow");
- if (TK_MAIN_WINDOW == NULL) { // Maybe not Tk module
- return 0;
- }
- return ( // -1 if any remaining symbols are NULL
- ((TK_FIND_PHOTO = (Tk_FindPhoto_t)
- _dfunc(hMod, "Tk_FindPhoto")) == NULL) ||
- ((TK_PHOTO_PUT_BLOCK_NO_COMPOSITE = (Tk_PhotoPutBlock_NoComposite_t)
- _dfunc(hMod, "Tk_PhotoPutBlock_NoComposite")) == NULL) ||
- ((TK_PHOTO_BLANK = (Tk_PhotoBlank_t)
- _dfunc(hMod, "Tk_PhotoBlank")) == NULL))
- ? -1 : 1;
-}
-
-int load_tkinter_funcs(void)
-{
- // Load TCL and Tk functions by searching all modules in current process.
- // Return 0 for success, non-zero for failure.
-
- HMODULE hMods[1024];
- HANDLE hProcess;
- DWORD cbNeeded;
- unsigned int i;
- int found_tcl = 0;
- int found_tk = 0;
-
- // Returns pseudo-handle that does not need to be closed
- hProcess = GetCurrentProcess();
-
- // Iterate through modules in this process looking for TCL / Tk names
- if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) {
- for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
- if (!found_tcl) {
- found_tcl = get_tcl(hMods[i]);
- if (found_tcl == -1) {
- return 1;
- }
- }
- if (!found_tk) {
- found_tk = get_tk(hMods[i]);
- if (found_tk == -1) {
- return 1;
- }
- }
- if (found_tcl && found_tk) {
- return 0;
- }
- }
- }
-
- if (found_tcl == 0) {
- PyErr_SetString(PyExc_RuntimeError, "Could not find TCL routines");
- } else {
- PyErr_SetString(PyExc_RuntimeError, "Could not find Tk routines");
- }
- return 1;
-}
-
-#else // not Windows
-
-/*
- * On Unix, we can get the TCL and Tk synbols from the tkinter module, because
- * tkinter uses these symbols, and the symbols are therefore visible in the
- * tkinter dynamic library (module).
- */
-#if PY_MAJOR_VERSION >= 3
-#define TKINTER_PKG "tkinter"
-#define TKINTER_MOD "_tkinter"
-// From module __file__ attribute to char *string for dlopen.
-char *fname2char(PyObject *fname)
-{
- PyObject* bytes;
- bytes = PyUnicode_EncodeFSDefault(fname);
- if (bytes == NULL) {
- return NULL;
- }
- return PyBytes_AsString(bytes);
-}
-#else
-#define TKINTER_PKG "Tkinter"
-#define TKINTER_MOD "tkinter"
-// From module __file__ attribute to char *string for dlopen
-#define fname2char(s) (PyString_AsString(s))
-#endif
-
-#include <dlfcn.h>
-
-void *_dfunc(void *lib_handle, const char *func_name)
-{
- // Load function `func_name` from `lib_handle`.
- // Set Python exception if we can't find `func_name` in `lib_handle`.
- // Returns function pointer or NULL if not present.
-
- void* func;
- // Reset errors.
- dlerror();
- func = dlsym(lib_handle, func_name);
- if (func == NULL) {
- const char *error = dlerror();
- PyErr_SetString(PyExc_RuntimeError, error);
- }
- return func;
-}
-
-int _func_loader(void *lib)
-{
- // Fill global function pointers from dynamic lib.
- // Return 1 if any pointer is NULL, 0 otherwise.
- return (
- ((TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)
- _dfunc(lib, "Tcl_CreateCommand")) == NULL) ||
- ((TCL_APPEND_RESULT = (Tcl_AppendResult_t)
- _dfunc(lib, "Tcl_AppendResult")) == NULL) ||
- ((TK_MAIN_WINDOW = (Tk_MainWindow_t)
- _dfunc(lib, "Tk_MainWindow")) == NULL) ||
- ((TK_FIND_PHOTO = (Tk_FindPhoto_t)
- _dfunc(lib, "Tk_FindPhoto")) == NULL) ||
- ((TK_PHOTO_PUT_BLOCK_NO_COMPOSITE = (Tk_PhotoPutBlock_NoComposite_t)
- _dfunc(lib, "Tk_PhotoPutBlock_NoComposite")) == NULL) ||
- ((TK_PHOTO_BLANK = (Tk_PhotoBlank_t)
- _dfunc(lib, "Tk_PhotoBlank")) == NULL));
-}
-
-int load_tkinter_funcs(void)
-{
- // Load tkinter global funcs from tkinter compiled module.
- // Return 0 for success, non-zero for failure.
- int ret = -1;
- void *main_program, *tkinter_lib;
- char *tkinter_libname;
- PyObject *pModule = NULL, *pSubmodule = NULL, *pString = NULL;
-
- // Try loading from the main program namespace first
- main_program = dlopen(NULL, RTLD_LAZY);
- if (_func_loader(main_program) == 0) {
- return 0;
- }
- // Clear exception triggered when we didn't find symbols above.
- PyErr_Clear();
-
- // Now try finding the tkinter compiled module
- pModule = PyImport_ImportModule(TKINTER_PKG);
- if (pModule == NULL) {
- goto exit;
- }
- pSubmodule = PyObject_GetAttrString(pModule, TKINTER_MOD);
- if (pSubmodule == NULL) {
- goto exit;
- }
- pString = PyObject_GetAttrString(pSubmodule, "__file__");
- if (pString == NULL) {
- goto exit;
- }
- tkinter_libname = fname2char(pString);
- if (tkinter_libname == NULL) {
- goto exit;
- }
- tkinter_lib = dlopen(tkinter_libname, RTLD_LAZY);
- if (tkinter_lib == NULL) {
- /* Perhaps it is a cffi module, like in PyPy? */
- pString = PyObject_GetAttrString(pSubmodule, "tklib_cffi");
- if (pString == NULL) {
- goto fail;
- }
- pString = PyObject_GetAttrString(pString, "__file__");
- if (pString == NULL) {
- goto fail;
- }
- tkinter_libname = fname2char(pString);
- if (tkinter_libname == NULL) {
- goto fail;
- }
- tkinter_lib = dlopen(tkinter_libname, RTLD_LAZY);
- }
- if (tkinter_lib == NULL) {
- goto fail;
- }
- ret = _func_loader(tkinter_lib);
- // dlclose probably safe because tkinter has been imported.
- dlclose(tkinter_lib);
- goto exit;
-fail:
- PyErr_SetString(PyExc_RuntimeError,
- "Cannot dlopen tkinter module file");
-exit:
- Py_XDECREF(pModule);
- Py_XDECREF(pSubmodule);
- Py_XDECREF(pString);
- return ret;
-}
-#endif // end not Windows
-
-#if PY_MAJOR_VERSION >= 3
-static PyModuleDef _tkagg_module = { PyModuleDef_HEAD_INIT, "_tkagg", "", -1, functions,
- NULL, NULL, NULL, NULL };
-
-PyMODINIT_FUNC PyInit__tkagg(void)
-{
- PyObject *m;
-
- m = PyModule_Create(&_tkagg_module);
-
- return (load_tkinter_funcs() == 0) ? m : NULL;
-}
-#else
-PyMODINIT_FUNC init_tkagg(void)
-{
- Py_InitModule("_tkagg", functions);
-
- load_tkinter_funcs();
-}
-#endif
diff --git a/contrib/python/matplotlib/py2/src/_tkmini.h b/contrib/python/matplotlib/py2/src/_tkmini.h
deleted file mode 100644
index 9b730b6c8c..0000000000
--- a/contrib/python/matplotlib/py2/src/_tkmini.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Small excerpts from the Tcl / Tk 8.6 headers
- *
- * License terms copied from:
- * http://www.tcl.tk/software/tcltk/license.html
- * as of 20 May 2016.
- *
- * Copyright (c) 1987-1994 The Regents of the University of California.
- * Copyright (c) 1993-1996 Lucent Technologies.
- * Copyright (c) 1994-1998 Sun Microsystems, Inc.
- * Copyright (c) 1998-2000 by Scriptics Corporation.
- * Copyright (c) 2002 by Kevin B. Kenny. All rights reserved.
- *
- * This software is copyrighted by the Regents of the University
- * of California, Sun Microsystems, Inc., Scriptics Corporation,
- * and other parties. The following terms apply to all files
- * associated with the software unless explicitly disclaimed in
- * individual files.
- *
- * The authors hereby grant permission to use, copy, modify,
- * distribute, and license this software and its documentation
- * for any purpose, provided that existing copyright notices are
- * retained in all copies and that this notice is included
- * verbatim in any distributions. No written agreement, license,
- * or royalty fee is required for any of the authorized uses.
- * Modifications to this software may be copyrighted by their
- * authors and need not follow the licensing terms described
- * here, provided that the new terms are clearly indicated on
- * the first page of each file where they apply.
- *
- * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO
- * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
- * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
- * SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN
- * IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON
- * AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO
- * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
- * ENHANCEMENTS, OR MODIFICATIONS.
- *
- * GOVERNMENT USE: If you are acquiring this software on behalf
- * of the U.S. government, the Government shall have only
- * "Restricted Rights" in the software and related documentation
- * as defined in the Federal Acquisition Regulations (FARs) in
- * Clause 52.227.19 (c) (2). If you are acquiring the software
- * on behalf of the Department of Defense, the software shall be
- * classified as "Commercial Computer Software" and the
- * Government shall have only "Restricted Rights" as defined in
- * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the
- * foregoing, the authors grant the U.S. Government and others
- * acting in its behalf permission to use and distribute the
- * software in accordance with the terms specified in this
- * license
- */
-
-/*
- * Unless otherwise noted, these definitions are stable from Tcl / Tk 8.5
- * through Tck / Tk master as of 21 May 2016
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Tcl header excerpts */
-#define TCL_OK 0
-#define TCL_ERROR 1
-
-/*
- * Users of versions of Tcl >= 8.6 encouraged to tread Tcl_Interp as an opaque
- * pointer. The following definition results when TCL_NO_DEPRECATED defined.
- */
-typedef struct Tcl_Interp Tcl_Interp;
-
-typedef struct Tcl_Command_ *Tcl_Command;
-typedef void *ClientData;
-
-typedef int (Tcl_CmdProc) (ClientData clientData, Tcl_Interp
- *interp, int argc, const char *argv[]);
-typedef void (Tcl_CmdDeleteProc) (ClientData clientData);
-
-/* Typedefs derived from function signatures in Tcl header */
-/* Tcl_CreateCommand */
-typedef Tcl_Command (*Tcl_CreateCommand_t)(Tcl_Interp *interp,
- const char *cmdName, Tcl_CmdProc *proc,
- ClientData clientData,
- Tcl_CmdDeleteProc *deleteProc);
-/* Tcl_AppendResult */
-typedef void (*Tcl_AppendResult_t) (Tcl_Interp *interp, ...);
-
-/* Tk header excerpts */
-typedef struct Tk_Window_ *Tk_Window;
-
-typedef void *Tk_PhotoHandle;
-
-typedef struct Tk_PhotoImageBlock
-{
- unsigned char *pixelPtr;
- int width;
- int height;
- int pitch;
- int pixelSize;
- int offset[4];
-} Tk_PhotoImageBlock;
-
-/* Typedefs derived from function signatures in Tk header */
-/* Tk_MainWindow */
-typedef Tk_Window (*Tk_MainWindow_t) (Tcl_Interp *interp);
-typedef Tk_PhotoHandle (*Tk_FindPhoto_t) (Tcl_Interp *interp, const char
- *imageName);
-/* Tk_PhotoPutBLock_NoComposite typedef */
-typedef void (*Tk_PhotoPutBlock_NoComposite_t) (Tk_PhotoHandle handle,
- Tk_PhotoImageBlock *blockPtr, int x, int y,
- int width, int height);
-/* Tk_PhotoBlank */
-typedef void (*Tk_PhotoBlank_t) (Tk_PhotoHandle handle);
-
-/*
- * end block for C++
- */
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/contrib/python/matplotlib/py2/src/_ttconv.cpp b/contrib/python/matplotlib/py2/src/_ttconv.cpp
deleted file mode 100644
index e18c8a53ca..0000000000
--- a/contrib/python/matplotlib/py2/src/_ttconv.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/*
- _ttconv.c
-
- Python wrapper for TrueType conversion library in ../ttconv.
- */
-#define PY_SSIZE_T_CLEAN
-#include "mplutils.h"
-
-#include <Python.h>
-#include "ttconv/pprdrv.h"
-#include "py_exceptions.h"
-#include <vector>
-#include <cassert>
-
-/**
- * An implementation of TTStreamWriter that writes to a Python
- * file-like object.
- */
-class PythonFileWriter : public TTStreamWriter
-{
- PyObject *_write_method;
-
- public:
- PythonFileWriter()
- {
- _write_method = NULL;
- }
-
- ~PythonFileWriter()
- {
- Py_XDECREF(_write_method);
- }
-
- void set(PyObject *write_method)
- {
- Py_XDECREF(_write_method);
- _write_method = write_method;
- Py_XINCREF(_write_method);
- }
-
- virtual void write(const char *a)
- {
- PyObject *result = NULL;
- if (_write_method) {
- PyObject *decoded = NULL;
- decoded = PyUnicode_DecodeLatin1(a, strlen(a), "");
- if (decoded == NULL) {
- throw py::exception();
- }
- result = PyObject_CallFunction(_write_method, (char *)"O", decoded);
- Py_DECREF(decoded);
- if (!result) {
- throw py::exception();
- }
- Py_DECREF(result);
- }
- }
-};
-
-int fileobject_to_PythonFileWriter(PyObject *object, void *address)
-{
- PythonFileWriter *file_writer = (PythonFileWriter *)address;
-
- PyObject *write_method = PyObject_GetAttrString(object, "write");
- if (write_method == NULL || !PyCallable_Check(write_method)) {
- PyErr_SetString(PyExc_TypeError, "Expected a file-like object with a write method.");
- return 0;
- }
-
- file_writer->set(write_method);
- Py_DECREF(write_method);
-
- return 1;
-}
-
-int pyiterable_to_vector_int(PyObject *object, void *address)
-{
- std::vector<int> *result = (std::vector<int> *)address;
-
- PyObject *iterator = PyObject_GetIter(object);
- if (!iterator) {
- return 0;
- }
-
- PyObject *item;
- while ((item = PyIter_Next(iterator))) {
-#if PY3K
- long value = PyLong_AsLong(item);
-#else
- long value = PyInt_AsLong(item);
-#endif
- Py_DECREF(item);
- if (value == -1 && PyErr_Occurred()) {
- return 0;
- }
- result->push_back((int)value);
- }
-
- Py_DECREF(iterator);
-
- return 1;
-}
-
-static PyObject *convert_ttf_to_ps(PyObject *self, PyObject *args, PyObject *kwds)
-{
- const char *filename;
- PythonFileWriter output;
- int fonttype;
- std::vector<int> glyph_ids;
-
- static const char *kwlist[] = { "filename", "output", "fonttype", "glyph_ids", NULL };
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
-#if PY_MAJOR_VERSION == 3
- "yO&i|O&:convert_ttf_to_ps",
-#else
- "sO&i|O&:convert_ttf_to_ps",
-#endif
- (char **)kwlist,
- &filename,
- fileobject_to_PythonFileWriter,
- &output,
- &fonttype,
- pyiterable_to_vector_int,
- &glyph_ids)) {
- return NULL;
- }
-
- if (fonttype != 3 && fonttype != 42) {
- PyErr_SetString(PyExc_ValueError,
- "fonttype must be either 3 (raw Postscript) or 42 "
- "(embedded Truetype)");
- return NULL;
- }
-
- try
- {
- insert_ttfont(filename, output, (font_type_enum)fonttype, glyph_ids);
- }
- catch (TTException &e)
- {
- PyErr_SetString(PyExc_RuntimeError, e.getMessage());
- return NULL;
- }
- catch (const py::exception &)
- {
- return NULL;
- }
- catch (...)
- {
- PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception");
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-class PythonDictionaryCallback : public TTDictionaryCallback
-{
- PyObject *_dict;
-
- public:
- PythonDictionaryCallback(PyObject *dict)
- {
- _dict = dict;
- }
-
- virtual void add_pair(const char *a, const char *b)
- {
- assert(a != NULL);
- assert(b != NULL);
- PyObject *value = PyBytes_FromString(b);
- if (!value) {
- throw py::exception();
- }
- if (PyDict_SetItemString(_dict, a, value)) {
- Py_DECREF(value);
- throw py::exception();
- }
- Py_DECREF(value);
- }
-};
-
-static PyObject *py_get_pdf_charprocs(PyObject *self, PyObject *args, PyObject *kwds)
-{
- const char *filename;
- std::vector<int> glyph_ids;
- PyObject *result;
-
- static const char *kwlist[] = { "filename", "glyph_ids", NULL };
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
-#if PY_MAJOR_VERSION == 3
- "y|O&:get_pdf_charprocs",
-#else
- "s|O&:get_pdf_charprocs",
-#endif
- (char **)kwlist,
- &filename,
- pyiterable_to_vector_int,
- &glyph_ids)) {
- return NULL;
- }
-
- result = PyDict_New();
- if (!result) {
- return NULL;
- }
-
- PythonDictionaryCallback dict(result);
-
- try
- {
- ::get_pdf_charprocs(filename, glyph_ids, dict);
- }
- catch (TTException &e)
- {
- Py_DECREF(result);
- PyErr_SetString(PyExc_RuntimeError, e.getMessage());
- return NULL;
- }
- catch (const py::exception &)
- {
- Py_DECREF(result);
- return NULL;
- }
- catch (...)
- {
- Py_DECREF(result);
- PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception");
- return NULL;
- }
-
- return result;
-}
-
-static PyMethodDef ttconv_methods[] =
-{
- {
- "convert_ttf_to_ps", (PyCFunction)convert_ttf_to_ps, METH_VARARGS | METH_KEYWORDS,
- "convert_ttf_to_ps(filename, output, fonttype, glyph_ids)\n"
- "\n"
- "Converts the Truetype font into a Type 3 or Type 42 Postscript font, "
- "optionally subsetting the font to only the desired set of characters.\n"
- "\n"
- "filename is the path to a TTF font file.\n"
- "output is a Python file-like object with a write method that the Postscript "
- "font data will be written to.\n"
- "fonttype may be either 3 or 42. Type 3 is a \"raw Postscript\" font. "
- "Type 42 is an embedded Truetype font. Glyph subsetting is not supported "
- "for Type 42 fonts.\n"
- "glyph_ids (optional) is a list of glyph ids (integers) to keep when "
- "subsetting to a Type 3 font. If glyph_ids is not provided or is None, "
- "then all glyphs will be included. If any of the glyphs specified are "
- "composite glyphs, then the component glyphs will also be included."
- },
- {
- "get_pdf_charprocs", (PyCFunction)py_get_pdf_charprocs, METH_VARARGS | METH_KEYWORDS,
- "get_pdf_charprocs(filename, glyph_ids)\n"
- "\n"
- "Given a Truetype font file, returns a dictionary containing the PDF Type 3\n"
- "representation of its paths. Useful for subsetting a Truetype font inside\n"
- "of a PDF file.\n"
- "\n"
- "filename is the path to a TTF font file.\n"
- "glyph_ids is a list of the numeric glyph ids to include.\n"
- "The return value is a dictionary where the keys are glyph names and\n"
- "the values are the stream content needed to render that glyph. This\n"
- "is useful to generate the CharProcs dictionary in a PDF Type 3 font.\n"
- },
- {0, 0, 0, 0} /* Sentinel */
-};
-
-static const char *module_docstring =
- "Module to handle converting and subsetting TrueType "
- "fonts to Postscript Type 3, Postscript Type 42 and "
- "Pdf Type 3 fonts.";
-
-#if PY3K
-static PyModuleDef ttconv_module = {
- PyModuleDef_HEAD_INIT,
- "ttconv",
- module_docstring,
- -1,
- ttconv_methods,
- NULL, NULL, NULL, NULL
-};
-
-PyMODINIT_FUNC
-PyInit_ttconv(void)
-{
- PyObject* m;
-
- m = PyModule_Create(&ttconv_module);
-
- return m;
-}
-#else
-PyMODINIT_FUNC
-initttconv(void)
-{
- Py_InitModule3("ttconv", ttconv_methods, module_docstring);
-}
-#endif
diff --git a/contrib/python/matplotlib/py2/src/_windowing.cpp b/contrib/python/matplotlib/py2/src/_windowing.cpp
deleted file mode 100644
index 7a20baa0a3..0000000000
--- a/contrib/python/matplotlib/py2/src/_windowing.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-#include "Python.h"
-#include <windows.h>
-
-static PyObject *
-_GetForegroundWindow(PyObject *module, PyObject *args)
-{
- HWND handle = GetForegroundWindow();
- if (!PyArg_ParseTuple(args, ":GetForegroundWindow"))
- {
- return NULL;
- }
- return PyLong_FromSize_t((size_t)handle);
-}
-
-static PyObject *
-_SetForegroundWindow(PyObject *module, PyObject *args)
-{
- HWND handle;
- if (!PyArg_ParseTuple(args, "n:SetForegroundWindow", &handle))
- {
- return NULL;
- }
- if (!SetForegroundWindow(handle))
- {
- return PyErr_Format(PyExc_RuntimeError,
- "Error setting window");
- }
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyMethodDef _windowing_methods[] =
-{
- {"GetForegroundWindow", _GetForegroundWindow, METH_VARARGS},
- {"SetForegroundWindow", _SetForegroundWindow, METH_VARARGS},
- {NULL, NULL}
-};
-
-#if PY_MAJOR_VERSION >= 3
-
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_windowing",
- "",
- -1,
- _windowing_methods,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-PyMODINIT_FUNC PyInit__windowing(void)
-{
- PyObject *module = PyModule_Create(&moduledef);
- return module;
-}
-
-#else
-PyMODINIT_FUNC init_windowing()
-{
- Py_InitModule("_windowing", _windowing_methods);
-}
-#endif
diff --git a/contrib/python/matplotlib/py2/src/agg_workaround.h b/contrib/python/matplotlib/py2/src/agg_workaround.h
deleted file mode 100644
index bfadf39284..0000000000
--- a/contrib/python/matplotlib/py2/src/agg_workaround.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef __AGG_WORKAROUND_H__
-#define __AGG_WORKAROUND_H__
-
-#include "agg_pixfmt_rgba.h"
-
-/**********************************************************************
- WORKAROUND: This class is to workaround a bug in Agg SVN where the
- blending of RGBA32 pixels does not preserve enough precision
-*/
-
-template<class ColorT, class Order>
-struct fixed_blender_rgba_pre : agg::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;
- 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,
- value_type cr, value_type cg, value_type cb,
- value_type alpha, agg::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)
- {
- alpha = base_mask - alpha;
- p[Order::R] = (value_type)(((p[Order::R] * alpha) >> base_shift) + cr);
- p[Order::G] = (value_type)(((p[Order::G] * alpha) >> base_shift) + cg);
- p[Order::B] = (value_type)(((p[Order::B] * alpha) >> base_shift) + cb);
- p[Order::A] = (value_type)(base_mask - ((alpha * (base_mask - p[Order::A])) >> base_shift));
- }
-};
-
-
-template<class ColorT, class Order>
-struct fixed_blender_rgba_plain : agg::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;
- enum base_scale_e { base_shift = color_type::base_shift };
-
- //--------------------------------------------------------------------
- static AGG_INLINE void blend_pix(value_type* p,
- value_type cr, value_type cg, value_type cb, value_type alpha, agg::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 == 0) return;
- calc_type a = p[Order::A];
- calc_type r = p[Order::R] * a;
- calc_type g = p[Order::G] * a;
- calc_type b = p[Order::B] * a;
- a = ((alpha + a) << base_shift) - alpha * a;
- p[Order::A] = (value_type)(a >> base_shift);
- p[Order::R] = (value_type)((((cr << base_shift) - r) * alpha + (r << base_shift)) / a);
- p[Order::G] = (value_type)((((cg << base_shift) - g) * alpha + (g << base_shift)) / a);
- p[Order::B] = (value_type)((((cb << base_shift) - b) * alpha + (b << base_shift)) / a);
- }
-};
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/array.h b/contrib/python/matplotlib/py2/src/array.h
deleted file mode 100644
index 8056366a1c..0000000000
--- a/contrib/python/matplotlib/py2/src/array.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/* Utilities to create scalars and empty arrays that behave like the
- Numpy array wrappers in numpy_cpp.h */
-
-#ifndef _SCALAR_H_
-#define _SCALAR_H_
-
-namespace array
-{
-
-template <typename T, int ND>
-class scalar
-{
- public:
- T m_value;
-
- scalar(const T value) : m_value(value)
- {
- }
-
- T &operator()(int i, int j = 0, int k = 0)
- {
- return m_value;
- }
-
- const T &operator()(int i, int j = 0, int k = 0) const
- {
- return m_value;
- }
-
- int dim(size_t i)
- {
- return 1;
- }
-
- size_t size()
- {
- return 1;
- }
-};
-
-template <typename T>
-class empty
-{
- public:
- typedef empty<T> sub_t;
-
- empty()
- {
- }
-
- T &operator()(int i, int j = 0, int k = 0)
- {
- throw std::runtime_error("Accessed empty array");
- }
-
- const T &operator()(int i, int j = 0, int k = 0) const
- {
- throw std::runtime_error("Accessed empty array");
- }
-
- sub_t operator[](int i) const
- {
- return empty<T>();
- }
-
- int dim(size_t i) const
- {
- return 0;
- }
-
- size_t size() const
- {
- return 0;
- }
-};
-}
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/file_compat.h b/contrib/python/matplotlib/py2/src/file_compat.h
deleted file mode 100644
index 114279fb1a..0000000000
--- a/contrib/python/matplotlib/py2/src/file_compat.h
+++ /dev/null
@@ -1,240 +0,0 @@
-#ifndef __FILE_COMPAT_H__
-#define __FILE_COMPAT_H__
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-#include <stdio.h>
-#include "numpy/npy_common.h"
-#include "numpy/ndarrayobject.h"
-#include "mplutils.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#if defined(_MSC_VER) && defined(_WIN64) && (_MSC_VER > 1400)
- #include <io.h>
- #define mpl_fseek _fseeki64
- #define mpl_ftell _ftelli64
- #define mpl_lseek _lseeki64
- #define mpl_off_t npy_int64
-
- #if NPY_SIZEOF_INT == 8
- #define MPL_OFF_T_PYFMT "i"
- #elif NPY_SIZEOF_LONG == 8
- #define MPL_OFF_T_PYFMT "l"
- #elif NPY_SIZEOF_LONGLONG == 8
- #define MPL_OFF_T_PYFMT "L"
- #else
- #error Unsupported size for type off_t
- #endif
-#else
- #define mpl_fseek fseek
- #define mpl_ftell ftell
- #define mpl_lseek lseek
- #define mpl_off_t off_t
-
- #if NPY_SIZEOF_INT == NPY_SIZEOF_SHORT
- #define MPL_OFF_T_PYFMT "h"
- #elif NPY_SIZEOF_INT == NPY_SIZEOF_INT
- #define MPL_OFF_T_PYFMT "i"
- #elif NPY_SIZEOF_INT == NPY_SIZEOF_LONG
- #define MPL_OFF_T_PYFMT "l"
- #elif NPY_SIZEOF_INT == NPY_SIZEOF_LONGLONG
- #define MPL_OFF_T_PYFMT "L"
- #else
- #error Unsupported size for type off_t
- #endif
-#endif
-
-/*
- * PyFile_* compatibility
- */
-#if PY3K | defined(PYPY_VERSION)
-
-/*
- * Get a FILE* handle to the file represented by the Python object
- */
-static NPY_INLINE FILE *mpl_PyFile_Dup(PyObject *file, char *mode, mpl_off_t *orig_pos)
-{
- int fd, fd2;
- PyObject *ret, *os;
- mpl_off_t pos;
- FILE *handle;
-
- if (mode[0] != 'r') {
- /* Flush first to ensure things end up in the file in the correct order */
- ret = PyObject_CallMethod(file, (char *)"flush", (char *)"");
- if (ret == NULL) {
- return NULL;
- }
- Py_DECREF(ret);
- }
-
- fd = PyObject_AsFileDescriptor(file);
- if (fd == -1) {
- return NULL;
- }
-
- /* The handle needs to be dup'd because we have to call fclose
- at the end */
- os = PyImport_ImportModule("os");
- if (os == NULL) {
- return NULL;
- }
- ret = PyObject_CallMethod(os, (char *)"dup", (char *)"i", fd);
- Py_DECREF(os);
- if (ret == NULL) {
- return NULL;
- }
- fd2 = PyNumber_AsSsize_t(ret, NULL);
- Py_DECREF(ret);
-
-/* Convert to FILE* handle */
-#ifdef _WIN32
- handle = _fdopen(fd2, mode);
-#else
- handle = fdopen(fd2, mode);
-#endif
- if (handle == NULL) {
- PyErr_SetString(PyExc_IOError, "Getting a FILE* from a Python file object failed");
- }
-
- /* Record the original raw file handle position */
- *orig_pos = mpl_ftell(handle);
- if (*orig_pos == -1) {
- // handle is a stream, so we don't have to worry about this
- return handle;
- }
-
- /* Seek raw handle to the Python-side position */
- ret = PyObject_CallMethod(file, (char *)"tell", (char *)"");
- if (ret == NULL) {
- fclose(handle);
- return NULL;
- }
- pos = PyNumber_AsSsize_t(ret, PyExc_OverflowError);
- Py_DECREF(ret);
- if (PyErr_Occurred()) {
- fclose(handle);
- return NULL;
- }
- if (mpl_fseek(handle, pos, SEEK_SET) == -1) {
- PyErr_SetString(PyExc_IOError, "seeking file failed");
- return NULL;
- }
- return handle;
-}
-
-/*
- * Close the dup-ed file handle, and seek the Python one to the current position
- */
-static NPY_INLINE int mpl_PyFile_DupClose(PyObject *file, FILE *handle, mpl_off_t orig_pos)
-{
- PyObject *exc_type = NULL, *exc_value = NULL, *exc_tb = NULL;
- PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
-
- int fd;
- PyObject *ret;
- mpl_off_t position;
-
- position = mpl_ftell(handle);
-
- /* Close the FILE* handle */
- fclose(handle);
-
- /* Restore original file handle position, in order to not confuse
- Python-side data structures. Note that this would fail if an exception
- is currently set, which can happen as this function is called in cleanup
- code, so we need to carefully fetch and restore the exception state. */
- fd = PyObject_AsFileDescriptor(file);
- if (fd == -1) {
- goto fail;
- }
- if (mpl_lseek(fd, orig_pos, SEEK_SET) != -1) {
- if (position == -1) {
- PyErr_SetString(PyExc_IOError, "obtaining file position failed");
- goto fail;
- }
-
- /* Seek Python-side handle to the FILE* handle position */
- ret = PyObject_CallMethod(file, (char *)"seek", (char *)(MPL_OFF_T_PYFMT "i"), position, 0);
- if (ret == NULL) {
- goto fail;
- }
- Py_DECREF(ret);
- }
- PyErr_Restore(exc_type, exc_value, exc_tb);
- return 0;
-fail:
- Py_XDECREF(exc_type);
- Py_XDECREF(exc_value);
- Py_XDECREF(exc_tb);
- return -1;
-}
-
-static NPY_INLINE int mpl_PyFile_Check(PyObject *file)
-{
- int fd;
- fd = PyObject_AsFileDescriptor(file);
- if (fd == -1) {
- PyErr_Clear();
- return 0;
- }
- return 1;
-}
-
-#else
-
-static NPY_INLINE FILE *mpl_PyFile_Dup(PyObject *file, const char *mode, mpl_off_t *orig_pos)
-{
- return PyFile_AsFile(file);
-}
-
-static NPY_INLINE int mpl_PyFile_DupClose(PyObject *file, FILE *handle, mpl_off_t orig_pos)
-{
- // deliberately nothing
- return 0;
-}
-
-static NPY_INLINE int mpl_PyFile_Check(PyObject *file)
-{
- return PyFile_Check(file);
-}
-
-#endif
-
-static NPY_INLINE PyObject *mpl_PyFile_OpenFile(PyObject *filename, const char *mode)
-{
- PyObject *open;
- open = PyDict_GetItemString(PyEval_GetBuiltins(), "open");
- if (open == NULL) {
- return NULL;
- }
- return PyObject_CallFunction(open, (char *)"Os", filename, mode);
-}
-
-static NPY_INLINE int mpl_PyFile_CloseFile(PyObject *file)
-{
- PyObject *type, *value, *tb;
- PyErr_Fetch(&type, &value, &tb);
-
- PyObject *ret;
-
- ret = PyObject_CallMethod(file, (char *)"close", NULL);
- if (ret == NULL) {
- goto fail;
- }
- Py_DECREF(ret);
- PyErr_Restore(type, value, tb);
- return 0;
-fail:
- Py_XDECREF(type);
- Py_XDECREF(value);
- Py_XDECREF(tb);
- return -1;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ifndef __FILE_COMPAT_H__ */
diff --git a/contrib/python/matplotlib/py2/src/ft2font.cpp b/contrib/python/matplotlib/py2/src/ft2font.cpp
deleted file mode 100644
index 7245ca332a..0000000000
--- a/contrib/python/matplotlib/py2/src/ft2font.cpp
+++ /dev/null
@@ -1,808 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#define NO_IMPORT_ARRAY
-
-#include <algorithm>
-#include <stdexcept>
-#include <string>
-
-#include "ft2font.h"
-#include "mplutils.h"
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846264338328
-#endif
-
-/**
- To improve the hinting of the fonts, this code uses a hack
- presented here:
-
- http://antigrain.com/research/font_rasterization/index.html
-
- The idea is to limit the effect of hinting in the x-direction, while
- preserving hinting in the y-direction. Since freetype does not
- support this directly, the dpi in the x-direction is set higher than
- in the y-direction, which affects the hinting grid. Then, a global
- transform is placed on the font to shrink it back to the desired
- size. While it is a bit surprising that the dpi setting affects
- hinting, whereas the global transform does not, this is documented
- behavior of FreeType, and therefore hopefully unlikely to change.
- The FreeType 2 tutorial says:
-
- NOTE: The transformation is applied to every glyph that is
- loaded through FT_Load_Glyph and is completely independent of
- any hinting process. This means that you won't get the same
- results if you load a glyph at the size of 24 pixels, or a glyph
- at the size at 12 pixels scaled by 2 through a transform,
- because the hints will have been computed differently (except
- you have disabled hints).
- */
-
-FT_Library _ft2Library;
-
-FT2Image::FT2Image() : m_dirty(true), m_buffer(NULL), m_width(0), m_height(0)
-{
-}
-
-FT2Image::FT2Image(unsigned long width, unsigned long height)
- : m_dirty(true), m_buffer(NULL), m_width(0), m_height(0)
-{
- resize(width, height);
-}
-
-FT2Image::~FT2Image()
-{
- delete[] m_buffer;
-}
-
-void FT2Image::resize(long width, long height)
-{
- if (width <= 0) {
- width = 1;
- }
- if (height <= 0) {
- height = 1;
- }
- size_t numBytes = width * height;
-
- if ((unsigned long)width != m_width || (unsigned long)height != m_height) {
- if (numBytes > m_width * m_height) {
- delete[] m_buffer;
- m_buffer = NULL;
- m_buffer = new unsigned char[numBytes];
- }
-
- m_width = (unsigned long)width;
- m_height = (unsigned long)height;
- }
-
- if (numBytes && m_buffer) {
- memset(m_buffer, 0, numBytes);
- }
-
- m_dirty = true;
-}
-
-void FT2Image::draw_bitmap(FT_Bitmap *bitmap, FT_Int x, FT_Int y)
-{
- FT_Int image_width = (FT_Int)m_width;
- FT_Int image_height = (FT_Int)m_height;
- FT_Int char_width = bitmap->width;
- FT_Int char_height = bitmap->rows;
-
- FT_Int x1 = CLAMP(x, 0, image_width);
- FT_Int y1 = CLAMP(y, 0, image_height);
- FT_Int x2 = CLAMP(x + char_width, 0, image_width);
- FT_Int y2 = CLAMP(y + char_height, 0, image_height);
-
- FT_Int x_start = MAX(0, -x);
- FT_Int y_offset = y1 - MAX(0, -y);
-
- if (bitmap->pixel_mode == FT_PIXEL_MODE_GRAY) {
- for (FT_Int i = y1; i < y2; ++i) {
- unsigned char *dst = m_buffer + (i * image_width + x1);
- unsigned char *src = bitmap->buffer + (((i - y_offset) * bitmap->pitch) + x_start);
- for (FT_Int j = x1; j < x2; ++j, ++dst, ++src)
- *dst |= *src;
- }
- } else if (bitmap->pixel_mode == FT_PIXEL_MODE_MONO) {
- for (FT_Int i = y1; i < y2; ++i) {
- unsigned char *dst = m_buffer + (i * image_width + x1);
- unsigned char *src = bitmap->buffer + ((i - y_offset) * bitmap->pitch);
- for (FT_Int j = x1; j < x2; ++j, ++dst) {
- int x = (j - x1 + x_start);
- int val = *(src + (x >> 3)) & (1 << (7 - (x & 0x7)));
- *dst = val ? 255 : *dst;
- }
- }
- } else {
- throw std::runtime_error("Unknown pixel mode");
- }
-
- m_dirty = true;
-}
-
-void FT2Image::draw_rect(unsigned long x0, unsigned long y0, unsigned long x1, unsigned long y1)
-{
- if (x0 > m_width || x1 > m_width || y0 > m_height || y1 > m_height) {
- throw std::runtime_error("Rect coords outside image bounds");
- }
-
- size_t top = y0 * m_width;
- size_t bottom = y1 * m_width;
- for (size_t i = x0; i < x1 + 1; ++i) {
- m_buffer[i + top] = 255;
- m_buffer[i + bottom] = 255;
- }
-
- for (size_t j = y0 + 1; j < y1; ++j) {
- m_buffer[x0 + j * m_width] = 255;
- m_buffer[x1 + j * m_width] = 255;
- }
-
- m_dirty = true;
-}
-
-void
-FT2Image::draw_rect_filled(unsigned long x0, unsigned long y0, unsigned long x1, unsigned long y1)
-{
- x0 = std::min(x0, m_width);
- y0 = std::min(y0, m_height);
- x1 = std::min(x1 + 1, m_width);
- y1 = std::min(y1 + 1, m_height);
-
- for (size_t j = y0; j < y1; j++) {
- for (size_t i = x0; i < x1; i++) {
- m_buffer[i + j * m_width] = 255;
- }
- }
-
- m_dirty = true;
-}
-
-inline double conv(long v)
-{
- return double(v) / 64.0;
-}
-
-int FT2Font::get_path_count()
-{
- // get the glyph as a path, a list of (COMMAND, *args) as described in matplotlib.path
- // this code is from agg's decompose_ft_outline with minor modifications
-
- if (!face->glyph) {
- throw std::runtime_error("No glyph loaded");
- }
-
- FT_Outline &outline = face->glyph->outline;
-
- FT_Vector v_last;
- FT_Vector v_control;
- FT_Vector v_start;
-
- FT_Vector *point;
- FT_Vector *limit;
- unsigned char *tags;
-
- int n; // index of contour in outline
- int first; // index of first point in contour
- char tag; // current point's state
- int count;
-
- count = 0;
- first = 0;
- for (n = 0; n < outline.n_contours; n++) {
- int last; // index of last point in contour
- bool starts_with_last;
-
- 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) {
- throw std::runtime_error("A contour cannot start with a cubic control point");
- } else if (tag == FT_CURVE_TAG_CONIC) {
- starts_with_last = true;
- } else {
- starts_with_last = false;
- }
-
- count++;
-
- while (point < limit) {
- if (!starts_with_last) {
- point++;
- tags++;
- }
- starts_with_last = false;
-
- tag = FT_CURVE_TAG(tags[0]);
- switch (tag) {
- case FT_CURVE_TAG_ON: // emit a single line_to
- {
- count++;
- continue;
- }
-
- case FT_CURVE_TAG_CONIC: // consume conic arcs
- {
- Count_Do_Conic:
- if (point < limit) {
- point++;
- tags++;
- tag = FT_CURVE_TAG(tags[0]);
-
- if (tag == FT_CURVE_TAG_ON) {
- count += 2;
- continue;
- }
-
- if (tag != FT_CURVE_TAG_CONIC) {
- throw std::runtime_error("Invalid font");
- }
-
- count += 2;
-
- goto Count_Do_Conic;
- }
-
- count += 2;
-
- goto Count_Close;
- }
-
- default: // FT_CURVE_TAG_CUBIC
- {
- if (point + 1 > limit || FT_CURVE_TAG(tags[1]) != FT_CURVE_TAG_CUBIC) {
- throw std::runtime_error("Invalid font");
- }
-
- point += 2;
- tags += 2;
-
- if (point <= limit) {
- count += 3;
- continue;
- }
-
- count += 3;
-
- goto Count_Close;
- }
- }
- }
-
- Count_Close:
- count++;
- first = last + 1;
- }
-
- return count;
-}
-
-void FT2Font::get_path(double *outpoints, unsigned char *outcodes)
-{
- FT_Outline &outline = face->glyph->outline;
- bool flip_y = false; // todo, pass me as kwarg
-
- FT_Vector v_last;
- FT_Vector v_control;
- FT_Vector v_start;
-
- FT_Vector *point;
- FT_Vector *limit;
- unsigned 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
- bool starts_with_last;
-
- 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]);
-
- double x, y;
- if (tag != FT_CURVE_TAG_ON) {
- x = conv(v_last.x);
- y = flip_y ? -conv(v_last.y) : conv(v_last.y);
- starts_with_last = true;
- } else {
- x = conv(v_start.x);
- y = flip_y ? -conv(v_start.y) : conv(v_start.y);
- starts_with_last = false;
- }
-
- *(outpoints++) = x;
- *(outpoints++) = y;
- *(outcodes++) = MOVETO;
-
- while (point < limit) {
- if (!starts_with_last) {
- point++;
- tags++;
- }
- starts_with_last = false;
-
- tag = FT_CURVE_TAG(tags[0]);
- switch (tag) {
- case FT_CURVE_TAG_ON: // emit a single line_to
- {
- double x = conv(point->x);
- double y = flip_y ? -conv(point->y) : conv(point->y);
- *(outpoints++) = x;
- *(outpoints++) = y;
- *(outcodes++) = LINETO;
- 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) {
- double xctl = conv(v_control.x);
- double yctl = flip_y ? -conv(v_control.y) : conv(v_control.y);
- double xto = conv(vec.x);
- double yto = flip_y ? -conv(vec.y) : conv(vec.y);
- *(outpoints++) = xctl;
- *(outpoints++) = yctl;
- *(outpoints++) = xto;
- *(outpoints++) = yto;
- *(outcodes++) = CURVE3;
- *(outcodes++) = CURVE3;
- continue;
- }
-
- v_middle.x = (v_control.x + vec.x) / 2;
- v_middle.y = (v_control.y + vec.y) / 2;
-
- double xctl = conv(v_control.x);
- double yctl = flip_y ? -conv(v_control.y) : conv(v_control.y);
- double xto = conv(v_middle.x);
- double yto = flip_y ? -conv(v_middle.y) : conv(v_middle.y);
- *(outpoints++) = xctl;
- *(outpoints++) = yctl;
- *(outpoints++) = xto;
- *(outpoints++) = yto;
- *(outcodes++) = CURVE3;
- *(outcodes++) = CURVE3;
-
- v_control = vec;
- goto Do_Conic;
- }
- double xctl = conv(v_control.x);
- double yctl = flip_y ? -conv(v_control.y) : conv(v_control.y);
- double xto = conv(v_start.x);
- double yto = flip_y ? -conv(v_start.y) : conv(v_start.y);
-
- *(outpoints++) = xctl;
- *(outpoints++) = yctl;
- *(outpoints++) = xto;
- *(outpoints++) = yto;
- *(outcodes++) = CURVE3;
- *(outcodes++) = CURVE3;
-
- goto Close;
- }
-
- default: // FT_CURVE_TAG_CUBIC
- {
- FT_Vector vec1, vec2;
-
- 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;
-
- double xctl1 = conv(vec1.x);
- double yctl1 = flip_y ? -conv(vec1.y) : conv(vec1.y);
- double xctl2 = conv(vec2.x);
- double yctl2 = flip_y ? -conv(vec2.y) : conv(vec2.y);
- double xto = conv(vec.x);
- double yto = flip_y ? -conv(vec.y) : conv(vec.y);
-
- (*outpoints++) = xctl1;
- (*outpoints++) = yctl1;
- (*outpoints++) = xctl2;
- (*outpoints++) = yctl2;
- (*outpoints++) = xto;
- (*outpoints++) = yto;
- (*outcodes++) = CURVE4;
- (*outcodes++) = CURVE4;
- (*outcodes++) = CURVE4;
- continue;
- }
-
- double xctl1 = conv(vec1.x);
- double yctl1 = flip_y ? -conv(vec1.y) : conv(vec1.y);
- double xctl2 = conv(vec2.x);
- double yctl2 = flip_y ? -conv(vec2.y) : conv(vec2.y);
- double xto = conv(v_start.x);
- double yto = flip_y ? -conv(v_start.y) : conv(v_start.y);
- (*outpoints++) = xctl1;
- (*outpoints++) = yctl1;
- (*outpoints++) = xctl2;
- (*outpoints++) = yctl2;
- (*outpoints++) = xto;
- (*outpoints++) = yto;
- (*outcodes++) = CURVE4;
- (*outcodes++) = CURVE4;
- (*outcodes++) = CURVE4;
-
- goto Close;
- }
- }
- }
-
- Close:
- (*outpoints++) = 0.0;
- (*outpoints++) = 0.0;
- (*outcodes++) = ENDPOLY;
- first = last + 1;
- }
-}
-
-FT2Font::FT2Font(FT_Open_Args &open_args, long hinting_factor_) : image(), face(NULL)
-{
- clear();
-
- int error = FT_Open_Face(_ft2Library, &open_args, 0, &face);
-
- if (error == FT_Err_Unknown_File_Format) {
- throw std::runtime_error("Can not load face. Unknown file format.");
- } else if (error == FT_Err_Cannot_Open_Resource) {
- throw std::runtime_error("Can not load face. Can not open resource.");
- } else if (error == FT_Err_Invalid_File_Format) {
- throw std::runtime_error("Can not load face. Invalid file format.");
- } else if (error) {
- throw std::runtime_error("Can not load face.");
- }
-
- // set a default fontsize 12 pt at 72dpi
- hinting_factor = hinting_factor_;
-
- error = FT_Set_Char_Size(face, 12 * 64, 0, 72 * (unsigned int)hinting_factor, 72);
- if (error) {
- FT_Done_Face(face);
- throw std::runtime_error("Could not set the fontsize");
- }
-
- if (open_args.stream != NULL) {
- face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
- }
-
- FT_Matrix transform = { 65536 / hinting_factor, 0, 0, 65536 };
- FT_Set_Transform(face, &transform, 0);
-}
-
-FT2Font::~FT2Font()
-{
- for (size_t i = 0; i < glyphs.size(); i++) {
- FT_Done_Glyph(glyphs[i]);
- }
-
- if (face) {
- FT_Done_Face(face);
- }
-}
-
-void FT2Font::clear()
-{
- angle = 0.0;
-
- pen.x = 0;
- pen.y = 0;
-
- for (size_t i = 0; i < glyphs.size(); i++) {
- FT_Done_Glyph(glyphs[i]);
- }
-
- glyphs.clear();
-}
-
-void FT2Font::set_size(double ptsize, double dpi)
-{
- int error = FT_Set_Char_Size(
- face, (long)(ptsize * 64), 0, (unsigned int)(dpi * hinting_factor), (unsigned int)dpi);
- FT_Matrix transform = { 65536 / hinting_factor, 0, 0, 65536 };
- FT_Set_Transform(face, &transform, 0);
-
- if (error) {
- throw std::runtime_error("Could not set the fontsize");
- }
-}
-
-void FT2Font::set_charmap(int i)
-{
- if (i >= face->num_charmaps) {
- throw std::runtime_error("i exceeds the available number of char maps");
- }
- FT_CharMap charmap = face->charmaps[i];
- if (FT_Set_Charmap(face, charmap)) {
- throw std::runtime_error("Could not set the charmap");
- }
-}
-
-void FT2Font::select_charmap(unsigned long i)
-{
- if (FT_Select_Charmap(face, (FT_Encoding)i)) {
- throw std::runtime_error("Could not set the charmap");
- }
-}
-
-int FT2Font::get_kerning(FT_UInt left, FT_UInt right, FT_UInt mode)
-{
- if (!FT_HAS_KERNING(face)) {
- return 0;
- }
- FT_Vector delta;
-
- if (!FT_Get_Kerning(face, left, right, mode, &delta)) {
- return (int)(delta.x) / (hinting_factor << 6);
- } else {
- return 0;
- }
-}
-
-void FT2Font::set_text(
- size_t N, uint32_t *codepoints, double angle, FT_Int32 flags, std::vector<double> &xys)
-{
- angle = angle / 360.0 * 2 * M_PI;
-
- // this computes width and height in subpixels so we have to divide by 64
- matrix.xx = (FT_Fixed)(cos(angle) * 0x10000L);
- matrix.xy = (FT_Fixed)(-sin(angle) * 0x10000L);
- matrix.yx = (FT_Fixed)(sin(angle) * 0x10000L);
- matrix.yy = (FT_Fixed)(cos(angle) * 0x10000L);
-
- FT_Bool use_kerning = FT_HAS_KERNING(face);
- FT_UInt previous = 0;
-
- clear();
-
- bbox.xMin = bbox.yMin = 32000;
- bbox.xMax = bbox.yMax = -32000;
-
- for (unsigned int n = 0; n < N; n++) {
- std::string thischar("?");
- FT_UInt glyph_index;
- FT_BBox glyph_bbox;
- FT_Pos last_advance;
-
- glyph_index = FT_Get_Char_Index(face, codepoints[n]);
-
- // retrieve kerning distance and move pen position
- if (use_kerning && previous && glyph_index) {
- FT_Vector delta;
- FT_Get_Kerning(face, previous, glyph_index, FT_KERNING_DEFAULT, &delta);
- pen.x += (delta.x << 10) / (hinting_factor << 16);
- }
- error = FT_Load_Glyph(face, glyph_index, flags);
- if (error) {
- throw std::runtime_error("could not load glyph");
- }
- // ignore errors, jump to next glyph
-
- // extract glyph image and store it in our table
-
- FT_Glyph thisGlyph;
- error = FT_Get_Glyph(face->glyph, &thisGlyph);
-
- if (error) {
- throw std::runtime_error("could not get glyph");
- }
- // ignore errors, jump to next glyph
-
- last_advance = face->glyph->advance.x;
- FT_Glyph_Transform(thisGlyph, 0, &pen);
- FT_Glyph_Transform(thisGlyph, &matrix, 0);
- xys.push_back(pen.x);
- xys.push_back(pen.y);
-
- FT_Glyph_Get_CBox(thisGlyph, ft_glyph_bbox_subpixels, &glyph_bbox);
-
- bbox.xMin = std::min(bbox.xMin, glyph_bbox.xMin);
- bbox.xMax = std::max(bbox.xMax, glyph_bbox.xMax);
- bbox.yMin = std::min(bbox.yMin, glyph_bbox.yMin);
- bbox.yMax = std::max(bbox.yMax, glyph_bbox.yMax);
-
- pen.x += last_advance;
-
- previous = glyph_index;
- glyphs.push_back(thisGlyph);
- }
-
- FT_Vector_Transform(&pen, &matrix);
- advance = pen.x;
-
- if (bbox.xMin > bbox.xMax) {
- bbox.xMin = bbox.yMin = bbox.xMax = bbox.yMax = 0;
- }
-}
-
-void FT2Font::load_char(long charcode, FT_Int32 flags)
-{
- int error = FT_Load_Char(face, (unsigned long)charcode, flags);
-
- if (error) {
- throw std::runtime_error("Could not load charcode");
- }
-
- FT_Glyph thisGlyph;
- error = FT_Get_Glyph(face->glyph, &thisGlyph);
-
- if (error) {
- throw std::runtime_error("Could not get glyph");
- }
-
- glyphs.push_back(thisGlyph);
-}
-
-void FT2Font::load_glyph(FT_UInt glyph_index, FT_Int32 flags)
-{
- int error = FT_Load_Glyph(face, glyph_index, flags);
-
- if (error) {
- throw std::runtime_error("Could not load glyph");
- }
-
- FT_Glyph thisGlyph;
- error = FT_Get_Glyph(face->glyph, &thisGlyph);
-
- if (error) {
- throw std::runtime_error("Could not load glyph");
- }
-
- glyphs.push_back(thisGlyph);
-}
-
-void FT2Font::get_width_height(long *width, long *height)
-{
- *width = advance;
- *height = bbox.yMax - bbox.yMin;
-}
-
-long FT2Font::get_descent()
-{
- return -bbox.yMin;
-}
-
-void FT2Font::get_bitmap_offset(long *x, long *y)
-{
- *x = bbox.xMin;
- *y = 0;
-}
-
-void FT2Font::draw_glyphs_to_bitmap(bool antialiased)
-{
- size_t width = (bbox.xMax - bbox.xMin) / 64 + 2;
- size_t height = (bbox.yMax - bbox.yMin) / 64 + 2;
-
- image.resize(width, height);
-
- for (size_t n = 0; n < glyphs.size(); n++) {
- error = FT_Glyph_To_Bitmap(
- &glyphs[n], antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, 0, 1);
- if (error) {
- throw std::runtime_error("Could not convert glyph to bitmap");
- }
-
- FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyphs[n];
- // now, draw to our target surface (convert position)
-
- // bitmap left and top in pixel, string bbox in subpixel
- FT_Int x = (FT_Int)(bitmap->left - (bbox.xMin / 64.));
- FT_Int y = (FT_Int)((bbox.yMax / 64.) - bitmap->top + 1);
-
- image.draw_bitmap(&bitmap->bitmap, x, y);
- }
-}
-
-void FT2Font::get_xys(bool antialiased, std::vector<double> &xys)
-{
- for (size_t n = 0; n < glyphs.size(); n++) {
-
- error = FT_Glyph_To_Bitmap(
- &glyphs[n], antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, 0, 1);
- if (error) {
- throw std::runtime_error("Could not convert glyph to bitmap");
- }
-
- FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyphs[n];
-
- // bitmap left and top in pixel, string bbox in subpixel
- FT_Int x = (FT_Int)(bitmap->left - bbox.xMin / 64.);
- FT_Int y = (FT_Int)(bbox.yMax / 64. - bitmap->top + 1);
- // make sure the index is non-neg
- x = x < 0 ? 0 : x;
- y = y < 0 ? 0 : y;
- xys.push_back(x);
- xys.push_back(y);
- }
-}
-
-void FT2Font::draw_glyph_to_bitmap(FT2Image &im, int x, int y, size_t glyphInd, bool antialiased)
-{
- FT_Vector sub_offset;
- sub_offset.x = 0; // int((xd - (double)x) * 64.0);
- sub_offset.y = 0; // int((yd - (double)y) * 64.0);
-
- if (glyphInd >= glyphs.size()) {
- throw std::runtime_error("glyph num is out of range");
- }
-
- error = FT_Glyph_To_Bitmap(&glyphs[glyphInd],
- antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO,
- &sub_offset, // additional translation
- 1 // destroy image
- );
- if (error) {
- throw std::runtime_error("Could not convert glyph to bitmap");
- }
-
- FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyphs[glyphInd];
-
- im.draw_bitmap(&bitmap->bitmap, x + bitmap->left, y);
-}
-
-void FT2Font::get_glyph_name(unsigned int glyph_number, char *buffer)
-{
- if (!FT_HAS_GLYPH_NAMES(face)) {
- /* Note that this generated name must match the name that
- is generated by ttconv in ttfont_CharStrings_getname. */
- PyOS_snprintf(buffer, 128, "uni%08x", glyph_number);
- } else {
- if (FT_Get_Glyph_Name(face, glyph_number, buffer, 128)) {
- throw std::runtime_error("Could not get glyph names.");
- }
- }
-}
-
-long FT2Font::get_name_index(char *name)
-{
- return FT_Get_Name_Index(face, (FT_String *)name);
-}
diff --git a/contrib/python/matplotlib/py2/src/ft2font.h b/contrib/python/matplotlib/py2/src/ft2font.h
deleted file mode 100644
index 072428ceed..0000000000
--- a/contrib/python/matplotlib/py2/src/ft2font.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/* A python interface to FreeType */
-#ifndef _FT2FONT_H
-#define _FT2FONT_H
-#include <vector>
-#include <stdint.h>
-
-extern "C" {
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_GLYPH_H
-#include FT_SFNT_NAMES_H
-#include FT_TYPE1_TABLES_H
-#include FT_TRUETYPE_TABLES_H
-}
-
-/*
- By definition, FT_FIXED as 2 16bit values stored in a single long.
- */
-#define FIXED_MAJOR(val) (signed short)((val & 0xffff0000) >> 16)
-#define FIXED_MINOR(val) (unsigned short)(val & 0xffff)
-
-// the FreeType string rendered into a width, height buffer
-class FT2Image
-{
- public:
- FT2Image();
- FT2Image(unsigned long width, unsigned long height);
- virtual ~FT2Image();
-
- void resize(long width, long height);
- void draw_bitmap(FT_Bitmap *bitmap, FT_Int x, FT_Int y);
- void write_bitmap(FILE *fp) const;
- void draw_rect(unsigned long x0, unsigned long y0, unsigned long x1, unsigned long y1);
- void draw_rect_filled(unsigned long x0, unsigned long y0, unsigned long x1, unsigned long y1);
-
- unsigned char *get_buffer()
- {
- return m_buffer;
- }
- unsigned long get_width()
- {
- return m_width;
- }
- unsigned long get_height()
- {
- return m_height;
- }
-
- private:
- bool m_dirty;
- unsigned char *m_buffer;
- unsigned long m_width;
- unsigned long m_height;
-
- // prevent copying
- FT2Image(const FT2Image &);
- FT2Image &operator=(const FT2Image &);
-};
-
-extern FT_Library _ft2Library;
-
-class FT2Font
-{
-
- public:
- FT2Font(FT_Open_Args &open_args, long hinting_factor);
- virtual ~FT2Font();
- void clear();
- void set_size(double ptsize, double dpi);
- void set_charmap(int i);
- void select_charmap(unsigned long i);
- void set_text(
- size_t N, uint32_t *codepoints, double angle, FT_Int32 flags, std::vector<double> &xys);
- int get_kerning(FT_UInt left, FT_UInt right, FT_UInt mode);
- void load_char(long charcode, FT_Int32 flags);
- void load_glyph(FT_UInt glyph_index, FT_Int32 flags);
- void get_width_height(long *width, long *height);
- void get_bitmap_offset(long *x, long *y);
- long get_descent();
- // TODO: Since we know the size of the array upfront, we probably don't
- // need to dynamically allocate like this
- void get_xys(bool antialiased, std::vector<double> &xys);
- void draw_glyphs_to_bitmap(bool antialiased);
- void draw_glyph_to_bitmap(FT2Image &im, int x, int y, size_t glyphInd, bool antialiased);
- void get_glyph_name(unsigned int glyph_number, char *buffer);
- long get_name_index(char *name);
- int get_path_count();
- void get_path(double *outpoints, unsigned char *outcodes);
-
- FT_Face &get_face()
- {
- return face;
- }
- FT2Image &get_image()
- {
- return image;
- }
- FT_Glyph &get_last_glyph()
- {
- return glyphs.back();
- }
- size_t get_last_glyph_index()
- {
- return glyphs.size() - 1;
- }
- size_t get_num_glyphs()
- {
- return glyphs.size();
- }
- long get_hinting_factor()
- {
- return hinting_factor;
- }
-
- private:
- FT2Image image;
- FT_Face face;
- FT_Matrix matrix; /* transformation matrix */
- FT_Vector pen; /* untransformed origin */
- FT_Error error;
- std::vector<FT_Glyph> glyphs;
- std::vector<FT_Vector> pos;
- FT_BBox bbox;
- FT_Pos advance;
- double angle;
- double ptsize;
- double dpi;
- long hinting_factor;
-
- void set_scalable_attributes();
-
- // prevent copying
- FT2Font(const FT2Font &);
- FT2Font &operator=(const FT2Font &);
-};
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/ft2font_wrapper.cpp b/contrib/python/matplotlib/py2/src/ft2font_wrapper.cpp
deleted file mode 100644
index d0e516ad02..0000000000
--- a/contrib/python/matplotlib/py2/src/ft2font_wrapper.cpp
+++ /dev/null
@@ -1,1808 +0,0 @@
-#include "mplutils.h"
-#include "ft2font.h"
-#include "file_compat.h"
-#include "py_exceptions.h"
-#include "numpy_cpp.h"
-
-// From Python
-#include <structmember.h>
-
-#define STRINGIFY(s) XSTRINGIFY(s)
-#define XSTRINGIFY(s) #s
-
-static PyObject *convert_xys_to_array(std::vector<double> &xys)
-{
- npy_intp dims[] = {(npy_intp)xys.size() / 2, 2 };
- if (dims[0] > 0) {
- return PyArray_SimpleNewFromData(2, dims, NPY_DOUBLE, &xys[0]);
- } else {
- return PyArray_SimpleNew(2, dims, NPY_DOUBLE);
- }
-}
-
-/**********************************************************************
- * FT2Image
- * */
-
-typedef struct
-{
- PyObject_HEAD
- FT2Image *x;
- Py_ssize_t shape[2];
- Py_ssize_t strides[2];
- Py_ssize_t suboffsets[2];
-} PyFT2Image;
-
-static PyObject *PyFT2Image_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyFT2Image *self;
- self = (PyFT2Image *)type->tp_alloc(type, 0);
- self->x = NULL;
- return (PyObject *)self;
-}
-
-static int PyFT2Image_init(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- double width;
- double height;
-
- if (!PyArg_ParseTuple(args, "dd:FT2Image", &width, &height)) {
- return -1;
- }
-
- CALL_CPP_INIT("FT2Image", (self->x = new FT2Image(width, height)));
-
- return 0;
-}
-
-static void PyFT2Image_dealloc(PyFT2Image *self)
-{
- delete self->x;
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-const char *PyFT2Image_draw_rect__doc__ =
- "draw_rect(x0, y0, x1, y1)\n"
- "\n"
- "Draw a rect to the image.\n"
- "\n";
-
-static PyObject *PyFT2Image_draw_rect(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- double x0, y0, x1, y1;
-
- if (!PyArg_ParseTuple(args, "dddd:draw_rect", &x0, &y0, &x1, &y1)) {
- return NULL;
- }
-
- CALL_CPP("draw_rect", (self->x->draw_rect(x0, y0, x1, y1)));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Image_draw_rect_filled__doc__ =
- "draw_rect_filled(x0, y0, x1, y1)\n"
- "\n"
- "Draw a filled rect to the image.\n"
- "\n";
-
-static PyObject *PyFT2Image_draw_rect_filled(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- double x0, y0, x1, y1;
-
- if (!PyArg_ParseTuple(args, "dddd:draw_rect_filled", &x0, &y0, &x1, &y1)) {
- return NULL;
- }
-
- CALL_CPP("draw_rect_filled", (self->x->draw_rect_filled(x0, y0, x1, y1)));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Image_as_str__doc__ =
- "s = image.as_str()\n"
- "\n"
- "Return the image buffer as a string\n"
- "\n";
-
-static PyObject *PyFT2Image_as_str(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- // TODO: Use a buffer to avoid the copy
- return PyBytes_FromStringAndSize((const char *)self->x->get_buffer(),
- self->x->get_width() * self->x->get_height());
-}
-
-const char *PyFT2Image_as_rgba_str__doc__ =
- "s = image.as_rgba_str()\n"
- "\n"
- "Return the image buffer as a RGBA string\n"
- "\n";
-
-static PyObject *PyFT2Image_as_rgba_str(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- npy_intp dims[] = {(npy_intp)self->x->get_height(), (npy_intp)self->x->get_width(), 4 };
- numpy::array_view<unsigned char, 3> result(dims);
-
- unsigned char *src = self->x->get_buffer();
- unsigned char *end = src + (self->x->get_width() * self->x->get_height());
- unsigned char *dst = result.data();
-
- while (src != end) {
- *dst++ = 0;
- *dst++ = 0;
- *dst++ = 0;
- *dst++ = *src++;
- }
-
- return result.pyobj();
-}
-
-const char *PyFT2Image_as_array__doc__ =
- "x = image.as_array()\n"
- "\n"
- "Return the image buffer as a width x height numpy array of ubyte \n"
- "\n";
-
-static PyObject *PyFT2Image_as_array(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- npy_intp dims[] = {(npy_intp)self->x->get_height(), (npy_intp)self->x->get_width() };
- return PyArray_SimpleNewFromData(2, dims, NPY_UBYTE, self->x->get_buffer());
-}
-
-static PyObject *PyFT2Image_get_width(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- return PyLong_FromLong(self->x->get_width());
-}
-
-static PyObject *PyFT2Image_get_height(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- return PyLong_FromLong(self->x->get_height());
-}
-
-static int PyFT2Image_get_buffer(PyFT2Image *self, Py_buffer *buf, int flags)
-{
- FT2Image *im = self->x;
-
- Py_INCREF(self);
- buf->obj = (PyObject *)self;
- buf->buf = im->get_buffer();
- buf->len = im->get_width() * im->get_height();
- buf->readonly = 0;
- buf->format = (char *)"B";
- buf->ndim = 2;
- self->shape[0] = im->get_height();
- self->shape[1] = im->get_width();
- buf->shape = self->shape;
- self->strides[0] = im->get_width();
- self->strides[1] = 1;
- buf->strides = self->strides;
- buf->suboffsets = NULL;
- buf->itemsize = 1;
- buf->internal = NULL;
-
- return 1;
-}
-
-static PyTypeObject PyFT2ImageType;
-
-static PyTypeObject *PyFT2Image_init_type(PyObject *m, PyTypeObject *type)
-{
- static PyMethodDef methods[] = {
- {"draw_rect", (PyCFunction)PyFT2Image_draw_rect, METH_VARARGS, PyFT2Image_draw_rect__doc__},
- {"draw_rect_filled", (PyCFunction)PyFT2Image_draw_rect_filled, METH_VARARGS, PyFT2Image_draw_rect_filled__doc__},
- {"as_str", (PyCFunction)PyFT2Image_as_str, METH_NOARGS, PyFT2Image_as_str__doc__},
- {"as_rgba_str", (PyCFunction)PyFT2Image_as_rgba_str, METH_NOARGS, PyFT2Image_as_rgba_str__doc__},
- {"as_array", (PyCFunction)PyFT2Image_as_array, METH_NOARGS, PyFT2Image_as_array__doc__},
- {"get_width", (PyCFunction)PyFT2Image_get_width, METH_NOARGS, NULL},
- {"get_height", (PyCFunction)PyFT2Image_get_height, METH_NOARGS, NULL},
- {NULL}
- };
-
- static PyBufferProcs buffer_procs;
- memset(&buffer_procs, 0, sizeof(PyBufferProcs));
- buffer_procs.bf_getbuffer = (getbufferproc)PyFT2Image_get_buffer;
-
- memset(type, 0, sizeof(PyTypeObject));
- type->tp_name = "matplotlib.ft2font.FT2Image";
- type->tp_basicsize = sizeof(PyFT2Image);
- type->tp_dealloc = (destructor)PyFT2Image_dealloc;
- type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_NEWBUFFER;
- type->tp_methods = methods;
- type->tp_new = PyFT2Image_new;
- type->tp_init = (initproc)PyFT2Image_init;
- type->tp_as_buffer = &buffer_procs;
-
- if (PyType_Ready(type) < 0) {
- return NULL;
- }
-
- if (PyModule_AddObject(m, "FT2Image", (PyObject *)type)) {
- return NULL;
- }
-
- return type;
-}
-
-/**********************************************************************
- * Glyph
- * */
-
-typedef struct
-{
- PyObject_HEAD
- size_t glyphInd;
- long width;
- long height;
- long horiBearingX;
- long horiBearingY;
- long horiAdvance;
- long linearHoriAdvance;
- long vertBearingX;
- long vertBearingY;
- long vertAdvance;
- FT_BBox bbox;
-} PyGlyph;
-
-static PyTypeObject PyGlyphType;
-
-static PyObject *
-PyGlyph_new(const FT_Face &face, const FT_Glyph &glyph, size_t ind, long hinting_factor)
-{
- PyGlyph *self;
- self = (PyGlyph *)PyGlyphType.tp_alloc(&PyGlyphType, 0);
-
- self->glyphInd = ind;
-
- FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_subpixels, &self->bbox);
-
- self->width = face->glyph->metrics.width / hinting_factor;
- self->height = face->glyph->metrics.height;
- self->horiBearingX = face->glyph->metrics.horiBearingX / hinting_factor;
- self->horiBearingY = face->glyph->metrics.horiBearingY;
- self->horiAdvance = face->glyph->metrics.horiAdvance;
- self->linearHoriAdvance = face->glyph->linearHoriAdvance / hinting_factor;
- self->vertBearingX = face->glyph->metrics.vertBearingX;
- self->vertBearingY = face->glyph->metrics.vertBearingY;
- self->vertAdvance = face->glyph->metrics.vertAdvance;
-
- return (PyObject *)self;
-}
-
-static void PyGlyph_dealloc(PyGlyph *self)
-{
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-static PyObject *PyGlyph_get_bbox(PyGlyph *self, void *closure)
-{
- return Py_BuildValue(
- "llll", self->bbox.xMin, self->bbox.yMin, self->bbox.xMax, self->bbox.yMax);
-}
-
-static PyTypeObject *PyGlyph_init_type(PyObject *m, PyTypeObject *type)
-{
- static PyMemberDef members[] = {
- {(char *)"width", T_LONG, offsetof(PyGlyph, width), READONLY, (char *)""},
- {(char *)"height", T_LONG, offsetof(PyGlyph, height), READONLY, (char *)""},
- {(char *)"horiBearingX", T_LONG, offsetof(PyGlyph, horiBearingX), READONLY, (char *)""},
- {(char *)"horiBearingY", T_LONG, offsetof(PyGlyph, horiBearingY), READONLY, (char *)""},
- {(char *)"horiAdvance", T_LONG, offsetof(PyGlyph, horiAdvance), READONLY, (char *)""},
- {(char *)"linearHoriAdvance", T_LONG, offsetof(PyGlyph, linearHoriAdvance), READONLY, (char *)""},
- {(char *)"vertBearingX", T_LONG, offsetof(PyGlyph, vertBearingX), READONLY, (char *)""},
- {(char *)"vertBearingY", T_LONG, offsetof(PyGlyph, vertBearingY), READONLY, (char *)""},
- {(char *)"vertAdvance", T_LONG, offsetof(PyGlyph, vertAdvance), READONLY, (char *)""},
- {NULL}
- };
-
- static PyGetSetDef getset[] = {
- {(char *)"bbox", (getter)PyGlyph_get_bbox, NULL, NULL, NULL},
- {NULL}
- };
-
- memset(type, 0, sizeof(PyTypeObject));
- type->tp_name = "matplotlib.ft2font.Glyph";
- type->tp_basicsize = sizeof(PyGlyph);
- type->tp_dealloc = (destructor)PyGlyph_dealloc;
- type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
- type->tp_members = members;
- type->tp_getset = getset;
-
- if (PyType_Ready(type) < 0) {
- return NULL;
- }
-
- /* Don't need to add to module, since you can't create glyphs
- directly from Python */
-
- return type;
-}
-
-/**********************************************************************
- * FT2Font
- * */
-
-typedef struct
-{
- PyObject_HEAD
- FT2Font *x;
- PyObject *fname;
- PyObject *py_file;
- FILE *fp;
- int close_file;
- mpl_off_t offset;
- FT_StreamRec stream;
- FT_Byte *mem;
- size_t mem_size;
- Py_ssize_t shape[2];
- Py_ssize_t strides[2];
- Py_ssize_t suboffsets[2];
-} PyFT2Font;
-
-static unsigned long read_from_file_callback(FT_Stream stream,
- unsigned long offset,
- unsigned char *buffer,
- unsigned long count)
-{
-
- PyFT2Font *def = (PyFT2Font *)stream->descriptor.pointer;
-
- if (fseek(def->fp, offset, SEEK_SET) == -1) {
- return 0;
- }
-
- if (count > 0) {
- return fread(buffer, 1, count, def->fp);
- }
-
- return 0;
-}
-
-static void close_file_callback(FT_Stream stream)
-{
- PyFT2Font *def = (PyFT2Font *)stream->descriptor.pointer;
-
- if (mpl_PyFile_DupClose(def->py_file, def->fp, def->offset)) {
- throw std::runtime_error("Couldn't close file");
- }
-
- if (def->close_file) {
- mpl_PyFile_CloseFile(def->py_file);
- }
-
- Py_DECREF(def->py_file);
- def->py_file = NULL;
-}
-
-static int convert_open_args(PyFT2Font *self, PyObject *py_file_arg, FT_Open_Args *open_args)
-{
- PyObject *py_file = NULL;
- int close_file = 0;
- FILE *fp;
- PyObject *data = NULL;
- char *data_ptr;
- Py_ssize_t data_len;
- long file_size;
- FT_Byte *new_memory;
- mpl_off_t offset = 0;
-
- int result = 0;
-
- memset((void *)open_args, 0, sizeof(FT_Open_Args));
-
- if (PyBytes_Check(py_file_arg) || PyUnicode_Check(py_file_arg)) {
- if ((py_file = mpl_PyFile_OpenFile(py_file_arg, (char *)"rb")) == NULL) {
- goto exit;
- }
- close_file = 1;
- } else {
- Py_INCREF(py_file_arg);
- py_file = py_file_arg;
- }
-
- if ((fp = mpl_PyFile_Dup(py_file, (char *)"rb", &offset))) {
- Py_INCREF(py_file);
- self->py_file = py_file;
- self->close_file = close_file;
- self->fp = fp;
- self->offset = offset;
- fseek(fp, 0, SEEK_END);
- file_size = ftell(fp);
- fseek(fp, 0, SEEK_SET);
-
- self->stream.base = NULL;
- self->stream.size = (unsigned long)file_size;
- self->stream.pos = 0;
- self->stream.descriptor.pointer = self;
- self->stream.read = &read_from_file_callback;
- self->stream.close = &close_file_callback;
-
- open_args->flags = FT_OPEN_STREAM;
- open_args->stream = &self->stream;
- } else {
- if (PyObject_HasAttrString(py_file_arg, "read") &&
- (data = PyObject_CallMethod(py_file_arg, (char *)"read", (char *)""))) {
- if (PyBytes_AsStringAndSize(data, &data_ptr, &data_len)) {
- goto exit;
- }
-
- if (self->mem) {
- free(self->mem);
- }
- self->mem = (FT_Byte *)malloc((self->mem_size + data_len) * sizeof(FT_Byte));
- if (self->mem == NULL) {
- goto exit;
- }
- new_memory = self->mem + self->mem_size;
- self->mem_size += data_len;
-
- memcpy(new_memory, data_ptr, data_len);
- open_args->flags = FT_OPEN_MEMORY;
- open_args->memory_base = new_memory;
- open_args->memory_size = data_len;
- open_args->stream = NULL;
- } else {
- PyErr_SetString(PyExc_TypeError,
- "First argument must be a path or file object reading bytes");
- goto exit;
- }
- }
-
- result = 1;
-
-exit:
-
- Py_XDECREF(py_file);
- Py_XDECREF(data);
-
- return result;
-}
-
-static PyTypeObject PyFT2FontType;
-
-static PyObject *PyFT2Font_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyFT2Font *self;
- self = (PyFT2Font *)type->tp_alloc(type, 0);
- self->x = NULL;
- self->fname = NULL;
- self->py_file = NULL;
- self->fp = NULL;
- self->close_file = 0;
- self->offset = 0;
- memset(&self->stream, 0, sizeof(FT_StreamRec));
- self->mem = 0;
- self->mem_size = 0;
- return (PyObject *)self;
-}
-
-const char *PyFT2Font_init__doc__ =
- "FT2Font(ttffile)\n"
- "\n"
- "Create a new FT2Font object\n"
- "The following global font attributes are defined:\n"
- " num_faces number of faces in file\n"
- " face_flags face flags (int type); see the ft2font constants\n"
- " style_flags style flags (int type); see the ft2font constants\n"
- " num_glyphs number of glyphs in the face\n"
- " family_name face family name\n"
- " style_name face style name\n"
- " num_fixed_sizes number of bitmap in the face\n"
- " scalable face is scalable\n"
- "\n"
- "The following are available, if scalable is true:\n"
- " bbox face global bounding box (xmin, ymin, xmax, ymax)\n"
- " units_per_EM number of font units covered by the EM\n"
- " ascender ascender in 26.6 units\n"
- " descender descender in 26.6 units\n"
- " height height in 26.6 units; used to compute a default\n"
- " line spacing (baseline-to-baseline distance)\n"
- " max_advance_width maximum horizontal cursor advance for all glyphs\n"
- " max_advance_height same for vertical layout\n"
- " underline_position vertical position of the underline bar\n"
- " underline_thickness vertical thickness of the underline\n"
- " postscript_name PostScript name of the font\n";
-
-static void PyFT2Font_fail(PyFT2Font *self)
-{
- free(self->mem);
- self->mem = NULL;
- Py_XDECREF(self->py_file);
- self->py_file = NULL;
-}
-
-static int PyFT2Font_init(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- PyObject *fname;
- FT_Open_Args open_args;
- long hinting_factor = 8;
- const char *names[] = { "filename", "hinting_factor", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kwds, "O|l:FT2Font", (char **)names, &fname, &hinting_factor)) {
- return -1;
- }
-
- if (!convert_open_args(self, fname, &open_args)) {
- return -1;
- }
-
- CALL_CPP_FULL(
- "FT2Font", (self->x = new FT2Font(open_args, hinting_factor)), PyFT2Font_fail(self), -1);
-
- Py_INCREF(fname);
- self->fname = fname;
-
- return 0;
-}
-
-static void PyFT2Font_dealloc(PyFT2Font *self)
-{
- delete self->x;
- free(self->mem);
- Py_XDECREF(self->py_file);
- Py_XDECREF(self->fname);
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-const char *PyFT2Font_clear__doc__ =
- "clear()\n"
- "\n"
- "Clear all the glyphs, reset for a new set_text";
-
-static PyObject *PyFT2Font_clear(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- CALL_CPP("clear", (self->x->clear()));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_set_size__doc__ =
- "set_size(ptsize, dpi)\n"
- "\n"
- "Set the point size and dpi of the text.\n";
-
-static PyObject *PyFT2Font_set_size(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- double ptsize;
- double dpi;
-
- if (!PyArg_ParseTuple(args, "dd:set_size", &ptsize, &dpi)) {
- return NULL;
- }
-
- CALL_CPP("set_size", (self->x->set_size(ptsize, dpi)));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_set_charmap__doc__ =
- "set_charmap(i)\n"
- "\n"
- "Make the i-th charmap current\n";
-
-static PyObject *PyFT2Font_set_charmap(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- int i;
-
- if (!PyArg_ParseTuple(args, "i:set_charmap", &i)) {
- return NULL;
- }
-
- CALL_CPP("set_charmap", (self->x->set_charmap(i)));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_select_charmap__doc__ =
- "select_charmap(i)\n"
- "\n"
- "select charmap i where i is one of the FT_Encoding number\n";
-
-static PyObject *PyFT2Font_select_charmap(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- unsigned long i;
-
- if (!PyArg_ParseTuple(args, "k:select_charmap", &i)) {
- return NULL;
- }
-
- CALL_CPP("select_charmap", self->x->select_charmap(i));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_get_kerning__doc__ =
- "dx = get_kerning(left, right, mode)\n"
- "\n"
- "Get the kerning between left char and right glyph indices\n"
- "mode is a kerning mode constant\n"
- " KERNING_DEFAULT - Return scaled and grid-fitted kerning distances\n"
- " KERNING_UNFITTED - Return scaled but un-grid-fitted kerning distances\n"
- " KERNING_UNSCALED - Return the kerning vector in original font units\n";
-
-static PyObject *PyFT2Font_get_kerning(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- FT_UInt left, right, mode;
- int result;
-
- if (!PyArg_ParseTuple(args, "III:get_kerning", &left, &right, &mode)) {
- return NULL;
- }
-
- CALL_CPP("get_kerning", (result = self->x->get_kerning(left, right, mode)));
-
- return PyLong_FromLong(result);
-}
-
-const char *PyFT2Font_set_text__doc__ =
- "set_text(s, angle)\n"
- "\n"
- "Set the text string and angle.\n"
- "You must call this before draw_glyphs_to_bitmap\n"
- "A sequence of x,y positions is returned";
-
-static PyObject *PyFT2Font_set_text(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- PyObject *textobj;
- double angle = 0.0;
- FT_Int32 flags = FT_LOAD_FORCE_AUTOHINT;
- std::vector<double> xys;
- const char *names[] = { "string", "angle", "flags", NULL };
-
- /* This makes a technically incorrect assumption that FT_Int32 is
- int. In theory it can also be long, if the size of int is less
- than 32 bits. This is very unlikely on modern platforms. */
- if (!PyArg_ParseTupleAndKeywords(
- args, kwds, "O|di:set_text", (char **)names, &textobj, &angle, &flags)) {
- return NULL;
- }
-
- std::vector<uint32_t> codepoints;
- size_t size;
-
- if (PyUnicode_Check(textobj)) {
- size = PyUnicode_GET_SIZE(textobj);
- codepoints.resize(size);
- Py_UNICODE *unistr = PyUnicode_AsUnicode(textobj);
- for (size_t i = 0; i < size; ++i) {
- codepoints[i] = unistr[i];
- }
- } else if (PyBytes_Check(textobj)) {
- size = PyBytes_Size(textobj);
- codepoints.resize(size);
- char *bytestr = PyBytes_AsString(textobj);
- for (size_t i = 0; i < size; ++i) {
- codepoints[i] = bytestr[i];
- }
- } else {
- PyErr_SetString(PyExc_TypeError, "String must be unicode or bytes");
- return NULL;
- }
-
- uint32_t* codepoints_array = NULL;
- if (size > 0) {
- codepoints_array = &codepoints[0];
- }
- CALL_CPP("set_text", self->x->set_text(size, codepoints_array, angle, flags, xys));
-
- return convert_xys_to_array(xys);
-}
-
-const char *PyFT2Font_get_num_glyphs__doc__ =
- "get_num_glyphs()\n"
- "\n"
- "Return the number of loaded glyphs\n";
-
-static PyObject *PyFT2Font_get_num_glyphs(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- return PyLong_FromLong(self->x->get_num_glyphs());
-}
-
-const char *PyFT2Font_load_char__doc__ =
- "load_char(charcode, flags=LOAD_FORCE_AUTOHINT)\n"
- "\n"
- "Load character with charcode in current fontfile and set glyph.\n"
- "The flags argument can be a bitwise-or of the LOAD_XXX constants.\n"
- "Return value is a Glyph object, with attributes\n"
- " width # glyph width\n"
- " height # glyph height\n"
- " bbox # the glyph bbox (xmin, ymin, xmax, ymax)\n"
- " horiBearingX # left side bearing in horizontal layouts\n"
- " horiBearingY # top side bearing in horizontal layouts\n"
- " horiAdvance # advance width for horizontal layout\n"
- " vertBearingX # left side bearing in vertical layouts\n"
- " vertBearingY # top side bearing in vertical layouts\n"
- " vertAdvance # advance height for vertical layout\n";
-
-static PyObject *PyFT2Font_load_char(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- long charcode;
- FT_Int32 flags = FT_LOAD_FORCE_AUTOHINT;
- const char *names[] = { "charcode", "flags", NULL };
-
- /* This makes a technically incorrect assumption that FT_Int32 is
- int. In theory it can also be long, if the size of int is less
- than 32 bits. This is very unlikely on modern platforms. */
- if (!PyArg_ParseTupleAndKeywords(
- args, kwds, "l|i:load_char", (char **)names, &charcode, &flags)) {
- return NULL;
- }
-
- CALL_CPP("load_char", (self->x->load_char(charcode, flags)));
-
- return PyGlyph_new(self->x->get_face(),
- self->x->get_last_glyph(),
- self->x->get_last_glyph_index(),
- self->x->get_hinting_factor());
-}
-
-const char *PyFT2Font_load_glyph__doc__ =
- "load_glyph(glyphindex, flags=LOAD_FORCE_AUTOHINT)\n"
- "\n"
- "Load character with glyphindex in current fontfile and set glyph.\n"
- "The flags argument can be a bitwise-or of the LOAD_XXX constants.\n"
- "Return value is a Glyph object, with attributes\n"
- " width # glyph width\n"
- " height # glyph height\n"
- " bbox # the glyph bbox (xmin, ymin, xmax, ymax)\n"
- " horiBearingX # left side bearing in horizontal layouts\n"
- " horiBearingY # top side bearing in horizontal layouts\n"
- " horiAdvance # advance width for horizontal layout\n"
- " vertBearingX # left side bearing in vertical layouts\n"
- " vertBearingY # top side bearing in vertical layouts\n"
- " vertAdvance # advance height for vertical layout\n";
-
-static PyObject *PyFT2Font_load_glyph(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- FT_UInt glyph_index;
- FT_Int32 flags = FT_LOAD_FORCE_AUTOHINT;
- const char *names[] = { "glyph_index", "flags", NULL };
-
- /* This makes a technically incorrect assumption that FT_Int32 is
- int. In theory it can also be long, if the size of int is less
- than 32 bits. This is very unlikely on modern platforms. */
- if (!PyArg_ParseTupleAndKeywords(
- args, kwds, "I|i:load_glyph", (char **)names, &glyph_index, &flags)) {
- return NULL;
- }
-
- CALL_CPP("load_glyph", (self->x->load_glyph(glyph_index, flags)));
-
- return PyGlyph_new(self->x->get_face(),
- self->x->get_last_glyph(),
- self->x->get_last_glyph_index(),
- self->x->get_hinting_factor());
-}
-
-const char *PyFT2Font_get_width_height__doc__ =
- "w, h = get_width_height()\n"
- "\n"
- "Get the width and height in 26.6 subpixels of the current string set by set_text\n"
- "The rotation of the string is accounted for. To get width and height\n"
- "in pixels, divide these values by 64\n";
-
-static PyObject *PyFT2Font_get_width_height(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- long width, height;
-
- CALL_CPP("get_width_height", (self->x->get_width_height(&width, &height)));
-
- return Py_BuildValue("ll", width, height);
-}
-
-const char *PyFT2Font_get_bitmap_offset__doc__ =
- "x, y = get_bitmap_offset()\n"
- "\n"
- "Get the offset in 26.6 subpixels for the bitmap if ink hangs left or below (0, 0).\n"
- "Since matplotlib only supports left-to-right text, y is always 0.\n";
-
-static PyObject *PyFT2Font_get_bitmap_offset(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- long x, y;
-
- CALL_CPP("get_bitmap_offset", (self->x->get_bitmap_offset(&x, &y)));
-
- return Py_BuildValue("ll", x, y);
-}
-
-const char *PyFT2Font_get_descent__doc__ =
- "d = get_descent()\n"
- "\n"
- "Get the descent of the current string set by set_text in 26.6 subpixels.\n"
- "The rotation of the string is accounted for. To get the descent\n"
- "in pixels, divide this value by 64.\n";
-
-static PyObject *PyFT2Font_get_descent(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- long descent;
-
- CALL_CPP("get_descent", (descent = self->x->get_descent()));
-
- return PyLong_FromLong(descent);
-}
-
-const char *PyFT2Font_draw_glyphs_to_bitmap__doc__ =
- "draw_glyphs_to_bitmap()\n"
- "\n"
- "Draw the glyphs that were loaded by set_text to the bitmap\n"
- "The bitmap size will be automatically set to include the glyphs\n";
-
-static PyObject *PyFT2Font_draw_glyphs_to_bitmap(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- int antialiased = 1;
- const char *names[] = { "antialiased", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kwds, "|i:draw_glyphs_to_bitmap", (char **)names, &antialiased)) {
- return NULL;
- }
-
- CALL_CPP("draw_glyphs_to_bitmap", (self->x->draw_glyphs_to_bitmap(antialiased)));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_get_xys__doc__ =
- "get_xys()\n"
- "\n"
- "Get the xy locations of the current glyphs\n";
-
-static PyObject *PyFT2Font_get_xys(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- int antialiased = 1;
- std::vector<double> xys;
- const char *names[] = { "antialiased", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:get_xys", (char **)names, &antialiased)) {
- return NULL;
- }
-
- CALL_CPP("get_xys", (self->x->get_xys(antialiased, xys)));
-
- return convert_xys_to_array(xys);
-}
-
-const char *PyFT2Font_draw_glyph_to_bitmap__doc__ =
- "draw_glyph_to_bitmap(bitmap, x, y, glyph)\n"
- "\n"
- "Draw a single glyph to the bitmap at pixel locations x,y\n"
- "Note it is your responsibility to set up the bitmap manually\n"
- "with set_bitmap_size(w,h) before this call is made.\n"
- "\n"
- "If you want automatic layout, use set_text in combinations with\n"
- "draw_glyphs_to_bitmap. This function is intended for people who\n"
- "want to render individual glyphs at precise locations, eg, a\n"
- "a glyph returned by load_char\n";
-
-static PyObject *PyFT2Font_draw_glyph_to_bitmap(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- PyFT2Image *image;
- double xd, yd;
- PyGlyph *glyph;
- int antialiased = 1;
- const char *names[] = { "image", "x", "y", "glyph", "antialiased", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O!ddO!|i:draw_glyph_to_bitmap",
- (char **)names,
- &PyFT2ImageType,
- &image,
- &xd,
- &yd,
- &PyGlyphType,
- &glyph,
- &antialiased)) {
- return NULL;
- }
-
- CALL_CPP("draw_glyph_to_bitmap",
- self->x->draw_glyph_to_bitmap(*(image->x), xd, yd, glyph->glyphInd, antialiased));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_get_glyph_name__doc__ =
- "get_glyph_name(index)\n"
- "\n"
- "Retrieves the ASCII name of a given glyph in a face.\n";
-
-static PyObject *PyFT2Font_get_glyph_name(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- unsigned int glyph_number;
- char buffer[128];
-
- if (!PyArg_ParseTuple(args, "I:get_glyph_name", &glyph_number)) {
- return NULL;
- }
-
- CALL_CPP("get_glyph_name", (self->x->get_glyph_name(glyph_number, buffer)));
-
- return PyUnicode_FromString(buffer);
-}
-
-const char *PyFT2Font_get_charmap__doc__ =
- "get_charmap()\n"
- "\n"
- "Returns a dictionary that maps the character codes of the selected charmap\n"
- "(Unicode by default) to their corresponding glyph indices.\n";
-
-static PyObject *PyFT2Font_get_charmap(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- PyObject *charmap;
-
- charmap = PyDict_New();
- if (charmap == NULL) {
- return NULL;
- }
-
- FT_UInt index;
- FT_ULong code = FT_Get_First_Char(self->x->get_face(), &index);
- while (index != 0) {
- PyObject *key;
- PyObject *val;
-
- key = PyLong_FromLong(code);
- if (key == NULL) {
- Py_DECREF(charmap);
- return NULL;
- }
-
- val = PyLong_FromLong(index);
- if (val == NULL) {
- Py_DECREF(key);
- Py_DECREF(charmap);
- return NULL;
- }
-
- if (PyDict_SetItem(charmap, key, val)) {
- Py_DECREF(key);
- Py_DECREF(val);
- Py_DECREF(charmap);
- return NULL;
- }
-
- Py_DECREF(key);
- Py_DECREF(val);
-
- code = FT_Get_Next_Char(self->x->get_face(), code, &index);
- }
-
- return charmap;
-}
-
-
-const char *PyFT2Font_get_char_index__doc__ =
- "get_char_index()\n"
- "\n"
- "Given a character code, returns a glyph index.\n";
-
-static PyObject *PyFT2Font_get_char_index(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- FT_UInt index;
- FT_ULong ccode;
-
- if (!PyArg_ParseTuple(args, "k:get_char_index", &ccode)) {
- return NULL;
- }
-
- index = FT_Get_Char_Index(self->x->get_face(), ccode);
-
- return PyLong_FromLong(index);
-}
-
-
-const char *PyFT2Font_get_sfnt__doc__ =
- "get_sfnt(name)\n"
- "\n"
- "Get all values from the SFNT names table. Result is a dictionary whose"
- "key is the platform-ID, ISO-encoding-scheme, language-code, and"
- "description.\n";
-
-static PyObject *PyFT2Font_get_sfnt(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- PyObject *names;
-
- if (!(self->x->get_face()->face_flags & FT_FACE_FLAG_SFNT)) {
- PyErr_SetString(PyExc_ValueError, "No SFNT name table");
- return NULL;
- }
-
- size_t count = FT_Get_Sfnt_Name_Count(self->x->get_face());
-
- names = PyDict_New();
- if (names == NULL) {
- return NULL;
- }
-
- for (FT_UInt j = 0; j < count; ++j) {
- FT_SfntName sfnt;
- FT_Error error = FT_Get_Sfnt_Name(self->x->get_face(), j, &sfnt);
-
- if (error) {
- Py_DECREF(names);
- PyErr_SetString(PyExc_ValueError, "Could not get SFNT name");
- return NULL;
- }
-
- PyObject *key = Py_BuildValue(
- "HHHH", sfnt.platform_id, sfnt.encoding_id, sfnt.language_id, sfnt.name_id);
- if (key == NULL) {
- Py_DECREF(names);
- return NULL;
- }
-
- PyObject *val = PyBytes_FromStringAndSize((const char *)sfnt.string, sfnt.string_len);
- if (val == NULL) {
- Py_DECREF(key);
- Py_DECREF(names);
- return NULL;
- }
-
- if (PyDict_SetItem(names, key, val)) {
- Py_DECREF(key);
- Py_DECREF(val);
- Py_DECREF(names);
- return NULL;
- }
-
- Py_DECREF(key);
- Py_DECREF(val);
- }
-
- return names;
-}
-
-const char *PyFT2Font_get_name_index__doc__ =
- "get_name_index(name)\n"
- "\n"
- "Returns the glyph index of a given glyph name.\n"
- "The glyph index 0 means `undefined character code'.\n";
-
-static PyObject *PyFT2Font_get_name_index(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- char *glyphname;
- long name_index;
-
- if (!PyArg_ParseTuple(args, "es:get_name_index", "ascii", &glyphname)) {
- return NULL;
- }
-
- CALL_CPP("get_name_index", name_index = self->x->get_name_index(glyphname));
-
- PyMem_Free(glyphname);
-
- return PyLong_FromLong(name_index);
-}
-
-const char *PyFT2Font_get_ps_font_info__doc__ =
- "get_ps_font_info()\n"
- "\n"
- "Return the information in the PS Font Info structure.\n";
-
-static PyObject *PyFT2Font_get_ps_font_info(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- PS_FontInfoRec fontinfo;
-
- FT_Error error = FT_Get_PS_Font_Info(self->x->get_face(), &fontinfo);
- if (error) {
- PyErr_SetString(PyExc_ValueError, "Could not get PS font info");
- return NULL;
- }
-
- return Py_BuildValue("ssssslbhH",
- fontinfo.version ? fontinfo.version : "",
- fontinfo.notice ? fontinfo.notice : "",
- fontinfo.full_name ? fontinfo.full_name : "",
- fontinfo.family_name ? fontinfo.family_name : "",
- fontinfo.weight ? fontinfo.weight : "",
- fontinfo.italic_angle,
- fontinfo.is_fixed_pitch,
- fontinfo.underline_position,
- fontinfo.underline_thickness);
-}
-
-const char *PyFT2Font_get_sfnt_table__doc__ =
- "get_sfnt_table(name)\n"
- "\n"
- "Return one of the following SFNT tables: head, maxp, OS/2, hhea, "
- "vhea, post, or pclt.\n";
-
-static PyObject *PyFT2Font_get_sfnt_table(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- char *tagname;
-
- if (!PyArg_ParseTuple(args, "es:get_sfnt_table", "ascii", &tagname)) {
- return NULL;
- }
-
- int tag;
- const char *tags[] = { "head", "maxp", "OS/2", "hhea", "vhea", "post", "pclt", NULL };
-
- for (tag = 0; tags[tag] != NULL; tag++) {
- if (strncmp(tagname, tags[tag], 5) == 0) {
- break;
- }
- }
-
- PyMem_Free(tagname);
-
- void *table = FT_Get_Sfnt_Table(self->x->get_face(), (FT_Sfnt_Tag)tag);
- if (!table) {
- Py_RETURN_NONE;
- }
-
- switch (tag) {
- case 0: {
- char head_dict[] =
- "{s:(h,H), s:(h,H), s:l, s:l, s:H, s:H,"
- "s:(l,l), s:(l,l), s:h, s:h, s:h, s:h, s:H, s:H, s:h, s:h, s:h}";
- TT_Header *t = (TT_Header *)table;
- return Py_BuildValue(head_dict,
- "version",
- FIXED_MAJOR(t->Table_Version),
- FIXED_MINOR(t->Table_Version),
- "fontRevision",
- FIXED_MAJOR(t->Font_Revision),
- FIXED_MINOR(t->Font_Revision),
- "checkSumAdjustment",
- t->CheckSum_Adjust,
- "magicNumber",
- t->Magic_Number,
- "flags",
- t->Flags,
- "unitsPerEm",
- t->Units_Per_EM,
- "created",
- t->Created[0],
- t->Created[1],
- "modified",
- t->Modified[0],
- t->Modified[1],
- "xMin",
- t->xMin,
- "yMin",
- t->yMin,
- "xMax",
- t->xMax,
- "yMax",
- t->yMax,
- "macStyle",
- t->Mac_Style,
- "lowestRecPPEM",
- t->Lowest_Rec_PPEM,
- "fontDirectionHint",
- t->Font_Direction,
- "indexToLocFormat",
- t->Index_To_Loc_Format,
- "glyphDataFormat",
- t->Glyph_Data_Format);
- }
- case 1: {
- char maxp_dict[] =
- "{s:(h,H), s:H, s:H, s:H, s:H, s:H, s:H,"
- "s:H, s:H, s:H, s:H, s:H, s:H, s:H, s:H}";
- TT_MaxProfile *t = (TT_MaxProfile *)table;
- return Py_BuildValue(maxp_dict,
- "version",
- FIXED_MAJOR(t->version),
- FIXED_MINOR(t->version),
- "numGlyphs",
- t->numGlyphs,
- "maxPoints",
- t->maxPoints,
- "maxContours",
- t->maxContours,
- "maxComponentPoints",
- t->maxCompositePoints,
- "maxComponentContours",
- t->maxCompositeContours,
- "maxZones",
- t->maxZones,
- "maxTwilightPoints",
- t->maxTwilightPoints,
- "maxStorage",
- t->maxStorage,
- "maxFunctionDefs",
- t->maxFunctionDefs,
- "maxInstructionDefs",
- t->maxInstructionDefs,
- "maxStackElements",
- t->maxStackElements,
- "maxSizeOfInstructions",
- t->maxSizeOfInstructions,
- "maxComponentElements",
- t->maxComponentElements,
- "maxComponentDepth",
- t->maxComponentDepth);
- }
- case 2: {
-#if PY3K
- char os_2_dict[] =
- "{s:H, s:h, s:H, s:H, s:H, s:h, s:h, s:h,"
- "s:h, s:h, s:h, s:h, s:h, s:h, s:h, s:h, s:y#, s:(kkkk),"
- "s:y#, s:H, s:H, s:H}";
-#else
- char os_2_dict[] =
- "{s:H, s:h, s:H, s:H, s:H, s:h, s:h, s:h,"
- "s:h, s:h, s:h, s:h, s:h, s:h, s:h, s:h, s:s#, s:(kkkk),"
- "s:s#, s:H, s:H, s:H}";
-#endif
- TT_OS2 *t = (TT_OS2 *)table;
- return Py_BuildValue(os_2_dict,
- "version",
- t->version,
- "xAvgCharWidth",
- t->xAvgCharWidth,
- "usWeightClass",
- t->usWeightClass,
- "usWidthClass",
- t->usWidthClass,
- "fsType",
- t->fsType,
- "ySubscriptXSize",
- t->ySubscriptXSize,
- "ySubscriptYSize",
- t->ySubscriptYSize,
- "ySubscriptXOffset",
- t->ySubscriptXOffset,
- "ySubscriptYOffset",
- t->ySubscriptYOffset,
- "ySuperscriptXSize",
- t->ySuperscriptXSize,
- "ySuperscriptYSize",
- t->ySuperscriptYSize,
- "ySuperscriptXOffset",
- t->ySuperscriptXOffset,
- "ySuperscriptYOffset",
- t->ySuperscriptYOffset,
- "yStrikeoutSize",
- t->yStrikeoutSize,
- "yStrikeoutPosition",
- t->yStrikeoutPosition,
- "sFamilyClass",
- t->sFamilyClass,
- "panose",
- t->panose,
- Py_ssize_t(10),
- "ulCharRange",
- t->ulUnicodeRange1,
- t->ulUnicodeRange2,
- t->ulUnicodeRange3,
- t->ulUnicodeRange4,
- "achVendID",
- t->achVendID,
- Py_ssize_t(4),
- "fsSelection",
- t->fsSelection,
- "fsFirstCharIndex",
- t->usFirstCharIndex,
- "fsLastCharIndex",
- t->usLastCharIndex);
- }
- case 3: {
- char hhea_dict[] =
- "{s:(h,H), s:h, s:h, s:h, s:H, s:h, s:h, s:h,"
- "s:h, s:h, s:h, s:h, s:H}";
- TT_HoriHeader *t = (TT_HoriHeader *)table;
- return Py_BuildValue(hhea_dict,
- "version",
- FIXED_MAJOR(t->Version),
- FIXED_MINOR(t->Version),
- "ascent",
- t->Ascender,
- "descent",
- t->Descender,
- "lineGap",
- t->Line_Gap,
- "advanceWidthMax",
- t->advance_Width_Max,
- "minLeftBearing",
- t->min_Left_Side_Bearing,
- "minRightBearing",
- t->min_Right_Side_Bearing,
- "xMaxExtent",
- t->xMax_Extent,
- "caretSlopeRise",
- t->caret_Slope_Rise,
- "caretSlopeRun",
- t->caret_Slope_Run,
- "caretOffset",
- t->caret_Offset,
- "metricDataFormat",
- t->metric_Data_Format,
- "numOfLongHorMetrics",
- t->number_Of_HMetrics);
- }
- case 4: {
- char vhea_dict[] =
- "{s:(h,H), s:h, s:h, s:h, s:H, s:h, s:h, s:h,"
- "s:h, s:h, s:h, s:h, s:H}";
- TT_VertHeader *t = (TT_VertHeader *)table;
- return Py_BuildValue(vhea_dict,
- "version",
- FIXED_MAJOR(t->Version),
- FIXED_MINOR(t->Version),
- "vertTypoAscender",
- t->Ascender,
- "vertTypoDescender",
- t->Descender,
- "vertTypoLineGap",
- t->Line_Gap,
- "advanceHeightMax",
- t->advance_Height_Max,
- "minTopSideBearing",
- t->min_Top_Side_Bearing,
- "minBottomSizeBearing",
- t->min_Bottom_Side_Bearing,
- "yMaxExtent",
- t->yMax_Extent,
- "caretSlopeRise",
- t->caret_Slope_Rise,
- "caretSlopeRun",
- t->caret_Slope_Run,
- "caretOffset",
- t->caret_Offset,
- "metricDataFormat",
- t->metric_Data_Format,
- "numOfLongVerMetrics",
- t->number_Of_VMetrics);
- }
- case 5: {
- char post_dict[] = "{s:(h,H), s:(h,H), s:h, s:h, s:k, s:k, s:k, s:k, s:k}";
- TT_Postscript *t = (TT_Postscript *)table;
- return Py_BuildValue(post_dict,
- "format",
- FIXED_MAJOR(t->FormatType),
- FIXED_MINOR(t->FormatType),
- "italicAngle",
- FIXED_MAJOR(t->italicAngle),
- FIXED_MINOR(t->italicAngle),
- "underlinePosition",
- t->underlinePosition,
- "underlineThickness",
- t->underlineThickness,
- "isFixedPitch",
- t->isFixedPitch,
- "minMemType42",
- t->minMemType42,
- "maxMemType42",
- t->maxMemType42,
- "minMemType1",
- t->minMemType1,
- "maxMemType1",
- t->maxMemType1);
- }
- case 6: {
- #if PY3K
- char pclt_dict[] =
- "{s:(h,H), s:k, s:H, s:H, s:H, s:H, s:H, s:H, s:y#, s:y#, s:b, "
- "s:b, s:b}";
- #else
- char pclt_dict[] =
- "{s:(h,H), s:k, s:H, s:H, s:H, s:H, s:H, s:H, s:s#, s:s#, s:b, "
- "s:b, s:b}";
- #endif
- TT_PCLT *t = (TT_PCLT *)table;
- return Py_BuildValue(pclt_dict,
- "version",
- FIXED_MAJOR(t->Version),
- FIXED_MINOR(t->Version),
- "fontNumber",
- t->FontNumber,
- "pitch",
- t->Pitch,
- "xHeight",
- t->xHeight,
- "style",
- t->Style,
- "typeFamily",
- t->TypeFamily,
- "capHeight",
- t->CapHeight,
- "symbolSet",
- t->SymbolSet,
- "typeFace",
- t->TypeFace,
- Py_ssize_t(16),
- "characterComplement",
- t->CharacterComplement,
- Py_ssize_t(8),
- "strokeWeight",
- t->StrokeWeight,
- "widthType",
- t->WidthType,
- "serifStyle",
- t->SerifStyle);
- }
- default:
- Py_RETURN_NONE;
- }
-}
-
-const char *PyFT2Font_get_path__doc__ =
- "get_path()\n"
- "\n"
- "Get the path data from the currently loaded glyph as a tuple of vertices, "
- "codes.\n";
-
-static PyObject *PyFT2Font_get_path(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- int count;
-
- CALL_CPP("get_path", (count = self->x->get_path_count()));
-
- npy_intp vertices_dims[2] = { count, 2 };
- numpy::array_view<double, 2> vertices(vertices_dims);
-
- npy_intp codes_dims[1] = { count };
- numpy::array_view<unsigned char, 1> codes(codes_dims);
-
- self->x->get_path(vertices.data(), codes.data());
-
- return Py_BuildValue("NN", vertices.pyobj(), codes.pyobj());
-}
-
-const char *PyFT2Font_get_image__doc__ =
- "get_image()\n"
- "\n"
- "Returns the underlying image buffer for this font object.\n";
-
-static PyObject *PyFT2Font_get_image(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- FT2Image &im = self->x->get_image();
- npy_intp dims[] = {(npy_intp)im.get_height(), (npy_intp)im.get_width() };
- return PyArray_SimpleNewFromData(2, dims, NPY_UBYTE, im.get_buffer());
-}
-
-static PyObject *PyFT2Font_postscript_name(PyFT2Font *self, void *closure)
-{
- const char *ps_name = FT_Get_Postscript_Name(self->x->get_face());
- if (ps_name == NULL) {
- ps_name = "UNAVAILABLE";
- }
-
- return PyUnicode_FromString(ps_name);
-}
-
-static PyObject *PyFT2Font_num_faces(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->num_faces);
-}
-
-static PyObject *PyFT2Font_family_name(PyFT2Font *self, void *closure)
-{
- const char *name = self->x->get_face()->family_name;
- if (name == NULL) {
- name = "UNAVAILABLE";
- }
- return PyUnicode_FromString(name);
-}
-
-static PyObject *PyFT2Font_style_name(PyFT2Font *self, void *closure)
-{
- const char *name = self->x->get_face()->style_name;
- if (name == NULL) {
- name = "UNAVAILABLE";
- }
- return PyUnicode_FromString(name);
-}
-
-static PyObject *PyFT2Font_face_flags(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->face_flags);
-}
-
-static PyObject *PyFT2Font_style_flags(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->style_flags);
-}
-
-static PyObject *PyFT2Font_num_glyphs(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->num_glyphs);
-}
-
-static PyObject *PyFT2Font_num_fixed_sizes(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->num_fixed_sizes);
-}
-
-static PyObject *PyFT2Font_num_charmaps(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->num_charmaps);
-}
-
-static PyObject *PyFT2Font_scalable(PyFT2Font *self, void *closure)
-{
- if (FT_IS_SCALABLE(self->x->get_face())) {
- Py_RETURN_TRUE;
- }
- Py_RETURN_FALSE;
-}
-
-static PyObject *PyFT2Font_units_per_EM(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->units_per_EM);
-}
-
-static PyObject *PyFT2Font_get_bbox(PyFT2Font *self, void *closure)
-{
- FT_BBox *bbox = &(self->x->get_face()->bbox);
-
- return Py_BuildValue("llll",
- bbox->xMin, bbox->yMin, bbox->xMax, bbox->yMax);
-}
-
-static PyObject *PyFT2Font_ascender(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->ascender);
-}
-
-static PyObject *PyFT2Font_descender(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->descender);
-}
-
-static PyObject *PyFT2Font_height(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->height);
-}
-
-static PyObject *PyFT2Font_max_advance_width(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->max_advance_width);
-}
-
-static PyObject *PyFT2Font_max_advance_height(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->max_advance_height);
-}
-
-static PyObject *PyFT2Font_underline_position(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->underline_position);
-}
-
-static PyObject *PyFT2Font_underline_thickness(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->underline_thickness);
-}
-
-static PyObject *PyFT2Font_fname(PyFT2Font *self, void *closure)
-{
- if (self->fname) {
- Py_INCREF(self->fname);
- return self->fname;
- }
-
- Py_RETURN_NONE;
-}
-
-static int PyFT2Font_get_buffer(PyFT2Font *self, Py_buffer *buf, int flags)
-{
- FT2Image &im = self->x->get_image();
-
- Py_INCREF(self);
- buf->obj = (PyObject *)self;
- buf->buf = im.get_buffer();
- buf->len = im.get_width() * im.get_height();
- buf->readonly = 0;
- buf->format = (char *)"B";
- buf->ndim = 2;
- self->shape[0] = im.get_height();
- self->shape[1] = im.get_width();
- buf->shape = self->shape;
- self->strides[0] = im.get_width();
- self->strides[1] = 1;
- buf->strides = self->strides;
- buf->suboffsets = NULL;
- buf->itemsize = 1;
- buf->internal = NULL;
-
- return 1;
-}
-
-static PyTypeObject *PyFT2Font_init_type(PyObject *m, PyTypeObject *type)
-{
- static PyGetSetDef getset[] = {
- {(char *)"postscript_name", (getter)PyFT2Font_postscript_name, NULL, NULL, NULL},
- {(char *)"num_faces", (getter)PyFT2Font_num_faces, NULL, NULL, NULL},
- {(char *)"family_name", (getter)PyFT2Font_family_name, NULL, NULL, NULL},
- {(char *)"style_name", (getter)PyFT2Font_style_name, NULL, NULL, NULL},
- {(char *)"face_flags", (getter)PyFT2Font_face_flags, NULL, NULL, NULL},
- {(char *)"style_flags", (getter)PyFT2Font_style_flags, NULL, NULL, NULL},
- {(char *)"num_glyphs", (getter)PyFT2Font_num_glyphs, NULL, NULL, NULL},
- {(char *)"num_fixed_sizes", (getter)PyFT2Font_num_fixed_sizes, NULL, NULL, NULL},
- {(char *)"num_charmaps", (getter)PyFT2Font_num_charmaps, NULL, NULL, NULL},
- {(char *)"scalable", (getter)PyFT2Font_scalable, NULL, NULL, NULL},
- {(char *)"units_per_EM", (getter)PyFT2Font_units_per_EM, NULL, NULL, NULL},
- {(char *)"bbox", (getter)PyFT2Font_get_bbox, NULL, NULL, NULL},
- {(char *)"ascender", (getter)PyFT2Font_ascender, NULL, NULL, NULL},
- {(char *)"descender", (getter)PyFT2Font_descender, NULL, NULL, NULL},
- {(char *)"height", (getter)PyFT2Font_height, NULL, NULL, NULL},
- {(char *)"max_advance_width", (getter)PyFT2Font_max_advance_width, NULL, NULL, NULL},
- {(char *)"max_advance_height", (getter)PyFT2Font_max_advance_height, NULL, NULL, NULL},
- {(char *)"underline_position", (getter)PyFT2Font_underline_position, NULL, NULL, NULL},
- {(char *)"underline_thickness", (getter)PyFT2Font_underline_thickness, NULL, NULL, NULL},
- {(char *)"fname", (getter)PyFT2Font_fname, NULL, NULL, NULL},
- {NULL}
- };
-
- static PyMethodDef methods[] = {
- {"clear", (PyCFunction)PyFT2Font_clear, METH_NOARGS, PyFT2Font_clear__doc__},
- {"set_size", (PyCFunction)PyFT2Font_set_size, METH_VARARGS, PyFT2Font_set_size__doc__},
- {"set_charmap", (PyCFunction)PyFT2Font_set_charmap, METH_VARARGS, PyFT2Font_set_charmap__doc__},
- {"select_charmap", (PyCFunction)PyFT2Font_select_charmap, METH_VARARGS, PyFT2Font_select_charmap__doc__},
- {"get_kerning", (PyCFunction)PyFT2Font_get_kerning, METH_VARARGS, PyFT2Font_get_kerning__doc__},
- {"set_text", (PyCFunction)PyFT2Font_set_text, METH_VARARGS|METH_KEYWORDS, PyFT2Font_set_text__doc__},
- {"get_num_glyphs", (PyCFunction)PyFT2Font_get_num_glyphs, METH_NOARGS, PyFT2Font_get_num_glyphs__doc__},
- {"load_char", (PyCFunction)PyFT2Font_load_char, METH_VARARGS|METH_KEYWORDS, PyFT2Font_load_char__doc__},
- {"load_glyph", (PyCFunction)PyFT2Font_load_glyph, METH_VARARGS|METH_KEYWORDS, PyFT2Font_load_glyph__doc__},
- {"get_width_height", (PyCFunction)PyFT2Font_get_width_height, METH_NOARGS, PyFT2Font_get_width_height__doc__},
- {"get_bitmap_offset", (PyCFunction)PyFT2Font_get_bitmap_offset, METH_NOARGS, PyFT2Font_get_bitmap_offset__doc__},
- {"get_descent", (PyCFunction)PyFT2Font_get_descent, METH_NOARGS, PyFT2Font_get_descent__doc__},
- {"draw_glyphs_to_bitmap", (PyCFunction)PyFT2Font_draw_glyphs_to_bitmap, METH_VARARGS|METH_KEYWORDS, PyFT2Font_draw_glyphs_to_bitmap__doc__},
- {"get_xys", (PyCFunction)PyFT2Font_get_xys, METH_VARARGS|METH_KEYWORDS, PyFT2Font_get_xys__doc__},
- {"draw_glyph_to_bitmap", (PyCFunction)PyFT2Font_draw_glyph_to_bitmap, METH_VARARGS|METH_KEYWORDS, PyFT2Font_draw_glyph_to_bitmap__doc__},
- {"get_glyph_name", (PyCFunction)PyFT2Font_get_glyph_name, METH_VARARGS, PyFT2Font_get_glyph_name__doc__},
- {"get_charmap", (PyCFunction)PyFT2Font_get_charmap, METH_NOARGS, PyFT2Font_get_charmap__doc__},
- {"get_char_index", (PyCFunction)PyFT2Font_get_char_index, METH_VARARGS, PyFT2Font_get_char_index__doc__},
- {"get_sfnt", (PyCFunction)PyFT2Font_get_sfnt, METH_NOARGS, PyFT2Font_get_sfnt__doc__},
- {"get_name_index", (PyCFunction)PyFT2Font_get_name_index, METH_VARARGS, PyFT2Font_get_name_index__doc__},
- {"get_ps_font_info", (PyCFunction)PyFT2Font_get_ps_font_info, METH_NOARGS, PyFT2Font_get_ps_font_info__doc__},
- {"get_sfnt_table", (PyCFunction)PyFT2Font_get_sfnt_table, METH_VARARGS, PyFT2Font_get_sfnt_table__doc__},
- {"get_path", (PyCFunction)PyFT2Font_get_path, METH_NOARGS, PyFT2Font_get_path__doc__},
- {"get_image", (PyCFunction)PyFT2Font_get_image, METH_NOARGS, PyFT2Font_get_path__doc__},
- {NULL}
- };
-
- static PyBufferProcs buffer_procs;
- memset(&buffer_procs, 0, sizeof(PyBufferProcs));
- buffer_procs.bf_getbuffer = (getbufferproc)PyFT2Font_get_buffer;
-
- memset(type, 0, sizeof(PyTypeObject));
- type->tp_name = "matplotlib.ft2font.FT2Font";
- type->tp_doc = PyFT2Font_init__doc__;
- type->tp_basicsize = sizeof(PyFT2Font);
- type->tp_dealloc = (destructor)PyFT2Font_dealloc;
- type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_NEWBUFFER;
- type->tp_methods = methods;
- type->tp_getset = getset;
- type->tp_new = PyFT2Font_new;
- type->tp_init = (initproc)PyFT2Font_init;
- type->tp_as_buffer = &buffer_procs;
-
- if (PyType_Ready(type) < 0) {
- return NULL;
- }
-
- if (PyModule_AddObject(m, "FT2Font", (PyObject *)type)) {
- return NULL;
- }
-
- return type;
-}
-
-extern "C" {
-
-#if PY3K
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "ft2font",
- NULL,
- 0,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit_ft2font(void)
-
-#else
-#define INITERROR return
-
-PyMODINIT_FUNC initft2font(void)
-#endif
-
-{
- PyObject *m;
-
-#if PY3K
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("ft2font", NULL, NULL);
-#endif
-
- if (m == NULL) {
- INITERROR;
- }
-
- if (!PyFT2Image_init_type(m, &PyFT2ImageType)) {
- INITERROR;
- }
-
- if (!PyGlyph_init_type(m, &PyGlyphType)) {
- INITERROR;
- }
-
- if (!PyFT2Font_init_type(m, &PyFT2FontType)) {
- INITERROR;
- }
-
- PyObject *d = PyModule_GetDict(m);
-
- if (add_dict_int(d, "SCALABLE", FT_FACE_FLAG_SCALABLE) ||
- add_dict_int(d, "FIXED_SIZES", FT_FACE_FLAG_FIXED_SIZES) ||
- add_dict_int(d, "FIXED_WIDTH", FT_FACE_FLAG_FIXED_WIDTH) ||
- add_dict_int(d, "SFNT", FT_FACE_FLAG_SFNT) ||
- add_dict_int(d, "HORIZONTAL", FT_FACE_FLAG_HORIZONTAL) ||
- add_dict_int(d, "VERTICAL", FT_FACE_FLAG_VERTICAL) ||
- add_dict_int(d, "KERNING", FT_FACE_FLAG_KERNING) ||
- add_dict_int(d, "FAST_GLYPHS", FT_FACE_FLAG_FAST_GLYPHS) ||
- add_dict_int(d, "MULTIPLE_MASTERS", FT_FACE_FLAG_MULTIPLE_MASTERS) ||
- add_dict_int(d, "GLYPH_NAMES", FT_FACE_FLAG_GLYPH_NAMES) ||
- add_dict_int(d, "EXTERNAL_STREAM", FT_FACE_FLAG_EXTERNAL_STREAM) ||
- add_dict_int(d, "ITALIC", FT_STYLE_FLAG_ITALIC) ||
- add_dict_int(d, "BOLD", FT_STYLE_FLAG_BOLD) ||
- add_dict_int(d, "KERNING_DEFAULT", FT_KERNING_DEFAULT) ||
- add_dict_int(d, "KERNING_UNFITTED", FT_KERNING_UNFITTED) ||
- add_dict_int(d, "KERNING_UNSCALED", FT_KERNING_UNSCALED) ||
- add_dict_int(d, "LOAD_DEFAULT", FT_LOAD_DEFAULT) ||
- add_dict_int(d, "LOAD_NO_SCALE", FT_LOAD_NO_SCALE) ||
- add_dict_int(d, "LOAD_NO_HINTING", FT_LOAD_NO_HINTING) ||
- add_dict_int(d, "LOAD_RENDER", FT_LOAD_RENDER) ||
- add_dict_int(d, "LOAD_NO_BITMAP", FT_LOAD_NO_BITMAP) ||
- add_dict_int(d, "LOAD_VERTICAL_LAYOUT", FT_LOAD_VERTICAL_LAYOUT) ||
- add_dict_int(d, "LOAD_FORCE_AUTOHINT", FT_LOAD_FORCE_AUTOHINT) ||
- add_dict_int(d, "LOAD_CROP_BITMAP", FT_LOAD_CROP_BITMAP) ||
- add_dict_int(d, "LOAD_PEDANTIC", FT_LOAD_PEDANTIC) ||
- add_dict_int(d, "LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH", FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH) ||
- add_dict_int(d, "LOAD_NO_RECURSE", FT_LOAD_NO_RECURSE) ||
- add_dict_int(d, "LOAD_IGNORE_TRANSFORM", FT_LOAD_IGNORE_TRANSFORM) ||
- add_dict_int(d, "LOAD_MONOCHROME", FT_LOAD_MONOCHROME) ||
- add_dict_int(d, "LOAD_LINEAR_DESIGN", FT_LOAD_LINEAR_DESIGN) ||
- add_dict_int(d, "LOAD_NO_AUTOHINT", (unsigned long)FT_LOAD_NO_AUTOHINT) ||
- add_dict_int(d, "LOAD_TARGET_NORMAL", (unsigned long)FT_LOAD_TARGET_NORMAL) ||
- add_dict_int(d, "LOAD_TARGET_LIGHT", (unsigned long)FT_LOAD_TARGET_LIGHT) ||
- add_dict_int(d, "LOAD_TARGET_MONO", (unsigned long)FT_LOAD_TARGET_MONO) ||
- add_dict_int(d, "LOAD_TARGET_LCD", (unsigned long)FT_LOAD_TARGET_LCD) ||
- add_dict_int(d, "LOAD_TARGET_LCD_V", (unsigned long)FT_LOAD_TARGET_LCD_V)) {
- INITERROR;
- }
-
- // initialize library
- int error = FT_Init_FreeType(&_ft2Library);
-
- if (error) {
- PyErr_SetString(PyExc_RuntimeError, "Could not initialize the freetype2 library");
- INITERROR;
- }
-
- {
- FT_Int major, minor, patch;
- char version_string[64];
-
- FT_Library_Version(_ft2Library, &major, &minor, &patch);
- sprintf(version_string, "%d.%d.%d", major, minor, patch);
- if (PyModule_AddStringConstant(m, "__freetype_version__", version_string)) {
- INITERROR;
- }
- }
-
- if (PyModule_AddStringConstant(m, "__freetype_build_type__", STRINGIFY(FREETYPE_BUILD_TYPE))) {
- INITERROR;
- }
-
- import_array();
-
-#if PY3K
- return m;
-#endif
-}
-
-} // extern "C"
diff --git a/contrib/python/matplotlib/py2/src/mplutils.cpp b/contrib/python/matplotlib/py2/src/mplutils.cpp
deleted file mode 100644
index bc09db52aa..0000000000
--- a/contrib/python/matplotlib/py2/src/mplutils.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#include "mplutils.h"
-
-int add_dict_int(PyObject *dict, const char *key, long val)
-{
- PyObject *valobj;
- valobj = PyLong_FromLong(val);
- if (valobj == NULL) {
- return 1;
- }
-
- if (PyDict_SetItemString(dict, (char *)key, valobj)) {
- Py_DECREF(valobj);
- return 1;
- }
-
- Py_DECREF(valobj);
-
- return 0;
-}
diff --git a/contrib/python/matplotlib/py2/src/mplutils.h b/contrib/python/matplotlib/py2/src/mplutils.h
deleted file mode 100644
index 4b59e08bbd..0000000000
--- a/contrib/python/matplotlib/py2/src/mplutils.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/* Small utilities that are shared by most extension modules. */
-
-#ifndef _MPLUTILS_H
-#define _MPLUTILS_H
-#define PY_SSIZE_T_CLEAN
-
-#if defined(_MSC_VER) && _MSC_VER <= 1600
-typedef unsigned __int8 uint8_t;
-#else
-#include <stdint.h>
-#endif
-
-#ifdef _POSIX_C_SOURCE
-# undef _POSIX_C_SOURCE
-#endif
-#ifndef _AIX
-#ifdef _XOPEN_SOURCE
-# undef _XOPEN_SOURCE
-#endif
-#endif
-
-// Prevent multiple conflicting definitions of swab from stdlib.h and unistd.h
-#if defined(__sun) || defined(sun)
-#if defined(_XPG4)
-#undef _XPG4
-#endif
-#if defined(_XPG3)
-#undef _XPG3
-#endif
-#endif
-
-#include <Python.h>
-
-#if PY_MAJOR_VERSION >= 3
-#define PY3K 1
-#define Py_TPFLAGS_HAVE_NEWBUFFER 0
-#else
-#define PY3K 0
-#endif
-
-#undef CLAMP
-#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
-
-#undef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-
-inline double mpl_round(double v)
-{
- return (double)(int)(v + ((v >= 0.0) ? 0.5 : -0.5));
-}
-
-enum {
- STOP = 0,
- MOVETO = 1,
- LINETO = 2,
- CURVE3 = 3,
- CURVE4 = 4,
- ENDPOLY = 0x4f
-};
-
-const size_t NUM_VERTICES[] = { 1, 1, 1, 2, 3, 1 };
-
-extern "C" int add_dict_int(PyObject *dict, const char *key, long val);
-
-#if defined(_MSC_VER) && (_MSC_VER < 1800)
-namespace std {
- inline bool isfinite(double num) { return _finite(num); }
-}
-#endif
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/numpy_cpp.h b/contrib/python/matplotlib/py2/src/numpy_cpp.h
deleted file mode 100644
index 75f773ee58..0000000000
--- a/contrib/python/matplotlib/py2/src/numpy_cpp.h
+++ /dev/null
@@ -1,569 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef _NUMPY_CPP_H_
-#define _NUMPY_CPP_H_
-#define PY_SSIZE_T_CLEAN
-/***************************************************************************
- * This file is based on original work by Mark Wiebe, available at:
- *
- * http://github.com/mwiebe/numpy-cpp
- *
- * However, the needs of matplotlib wrappers, such as treating an
- * empty array as having the correct dimensions, have made this rather
- * matplotlib-specific, so it's no longer compatible with the
- * original.
- */
-
-#include "py_exceptions.h"
-
-#include <complex>
-
-#ifdef _POSIX_C_SOURCE
-# undef _POSIX_C_SOURCE
-#endif
-#ifndef _AIX
-#ifdef _XOPEN_SOURCE
-# undef _XOPEN_SOURCE
-#endif
-#endif
-
-// Prevent multiple conflicting definitions of swab from stdlib.h and unistd.h
-#if defined(__sun) || defined(sun)
-#if defined(_XPG4)
-#undef _XPG4
-#endif
-#if defined(_XPG3)
-#undef _XPG3
-#endif
-#endif
-
-#include <Python.h>
-#include <numpy/ndarrayobject.h>
-
-namespace numpy
-{
-
-// Type traits for the NumPy types
-template <typename T>
-struct type_num_of;
-
-/* Be careful with bool arrays as python has sizeof(npy_bool) == 1, but it is
- * not always the case that sizeof(bool) == 1. Using the array_view_accessors
- * is always fine regardless of sizeof(bool), so do this rather than using
- * array.data() and pointer arithmetic which will not work correctly if
- * sizeof(bool) != 1. */
-template <> struct type_num_of<bool>
-{
- enum {
- value = NPY_BOOL
- };
-};
-template <>
-struct type_num_of<npy_byte>
-{
- enum {
- value = NPY_BYTE
- };
-};
-template <>
-struct type_num_of<npy_ubyte>
-{
- enum {
- value = NPY_UBYTE
- };
-};
-template <>
-struct type_num_of<npy_short>
-{
- enum {
- value = NPY_SHORT
- };
-};
-template <>
-struct type_num_of<npy_ushort>
-{
- enum {
- value = NPY_USHORT
- };
-};
-template <>
-struct type_num_of<npy_int>
-{
- enum {
- value = NPY_INT
- };
-};
-template <>
-struct type_num_of<npy_uint>
-{
- enum {
- value = NPY_UINT
- };
-};
-template <>
-struct type_num_of<npy_long>
-{
- enum {
- value = NPY_LONG
- };
-};
-template <>
-struct type_num_of<npy_ulong>
-{
- enum {
- value = NPY_ULONG
- };
-};
-template <>
-struct type_num_of<npy_longlong>
-{
- enum {
- value = NPY_LONGLONG
- };
-};
-template <>
-struct type_num_of<npy_ulonglong>
-{
- enum {
- value = NPY_ULONGLONG
- };
-};
-template <>
-struct type_num_of<npy_float>
-{
- enum {
- value = NPY_FLOAT
- };
-};
-template <>
-struct type_num_of<npy_double>
-{
- enum {
- value = NPY_DOUBLE
- };
-};
-#if NPY_LONGDOUBLE != NPY_DOUBLE
-template <>
-struct type_num_of<npy_longdouble>
-{
- enum {
- value = NPY_LONGDOUBLE
- };
-};
-#endif
-template <>
-struct type_num_of<npy_cfloat>
-{
- enum {
- value = NPY_CFLOAT
- };
-};
-template <>
-struct type_num_of<std::complex<npy_float> >
-{
- enum {
- value = NPY_CFLOAT
- };
-};
-template <>
-struct type_num_of<npy_cdouble>
-{
- enum {
- value = NPY_CDOUBLE
- };
-};
-template <>
-struct type_num_of<std::complex<npy_double> >
-{
- enum {
- value = NPY_CDOUBLE
- };
-};
-#if NPY_CLONGDOUBLE != NPY_CDOUBLE
-template <>
-struct type_num_of<npy_clongdouble>
-{
- enum {
- value = NPY_CLONGDOUBLE
- };
-};
-template <>
-struct type_num_of<std::complex<npy_longdouble> >
-{
- enum {
- value = NPY_CLONGDOUBLE
- };
-};
-#endif
-template <>
-struct type_num_of<PyObject *>
-{
- enum {
- value = NPY_OBJECT
- };
-};
-template <typename T>
-struct type_num_of<T &>
-{
- enum {
- value = type_num_of<T>::value
- };
-};
-template <typename T>
-struct type_num_of<const T>
-{
- enum {
- value = type_num_of<T>::value
- };
-};
-
-template <typename T>
-struct is_const
-{
- enum {
- value = false
- };
-};
-template <typename T>
-struct is_const<const T>
-{
- enum {
- value = true
- };
-};
-
-namespace detail
-{
-template <template <typename, int> class AV, typename T, int ND>
-class array_view_accessors;
-
-template <template <typename, int> class AV, typename T>
-class array_view_accessors<AV, T, 1>
-{
- public:
- typedef AV<T, 1> AVC;
- typedef T sub_t;
-
- T &operator()(npy_intp i)
- {
- AVC *self = static_cast<AVC *>(this);
-
- return *reinterpret_cast<T *>(self->m_data + self->m_strides[0] * i);
- }
-
- const T &operator()(npy_intp i) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return *reinterpret_cast<const T *>(self->m_data + self->m_strides[0] * i);
- }
-
- T &operator[](npy_intp i)
- {
- AVC *self = static_cast<AVC *>(this);
-
- return *reinterpret_cast<T *>(self->m_data + self->m_strides[0] * i);
- }
-
- const T &operator[](npy_intp i) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return *reinterpret_cast<const T *>(self->m_data + self->m_strides[0] * i);
- }
-};
-
-template <template <typename, int> class AV, typename T>
-class array_view_accessors<AV, T, 2>
-{
- public:
- typedef AV<T, 2> AVC;
- typedef AV<T, 1> sub_t;
-
- T &operator()(npy_intp i, npy_intp j)
- {
- AVC *self = static_cast<AVC *>(this);
-
- return *reinterpret_cast<T *>(self->m_data + self->m_strides[0] * i +
- self->m_strides[1] * j);
- }
-
- const T &operator()(npy_intp i, npy_intp j) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return *reinterpret_cast<const T *>(self->m_data + self->m_strides[0] * i +
- self->m_strides[1] * j);
- }
-
- sub_t subarray(npy_intp i) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return sub_t(self->m_arr,
- self->m_data + self->m_strides[0] * i,
- self->m_shape + 1,
- self->m_strides + 1);
- }
-};
-
-template <template <typename, int> class AV, typename T>
-class array_view_accessors<AV, T, 3>
-{
- public:
- typedef AV<T, 3> AVC;
- typedef AV<T, 2> sub_t;
-
- T &operator()(npy_intp i, npy_intp j, npy_intp k)
- {
- AVC *self = static_cast<AVC *>(this);
-
- return *reinterpret_cast<T *>(self->m_data + self->m_strides[0] * i +
- self->m_strides[1] * j + self->m_strides[2] * k);
- }
-
- const T &operator()(npy_intp i, npy_intp j, npy_intp k) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return *reinterpret_cast<const T *>(self->m_data + self->m_strides[0] * i +
- self->m_strides[1] * j + self->m_strides[2] * k);
- }
-
- sub_t subarray(npy_intp i) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return sub_t(self->m_arr,
- self->m_data + self->m_strides[0] * i,
- self->m_shape + 1,
- self->m_strides + 1);
- }
-
-
-};
-
-// When adding instantiations of array_view_accessors, remember to add entries
-// to zeros[] below.
-
-}
-
-static npy_intp zeros[] = { 0, 0, 0 };
-
-template <typename T, int ND>
-class array_view : public detail::array_view_accessors<array_view, T, ND>
-{
- friend class detail::array_view_accessors<numpy::array_view, T, ND>;
-
- private:
- // Copies of the array data
- PyArrayObject *m_arr;
- npy_intp *m_shape;
- npy_intp *m_strides;
- char *m_data;
-
- public:
- typedef T value_type;
-
- enum {
- ndim = ND
- };
-
- array_view() : m_arr(NULL), m_data(NULL)
- {
- m_shape = zeros;
- m_strides = zeros;
- }
-
- array_view(PyObject *arr, bool contiguous = false) : m_arr(NULL), m_data(NULL)
- {
- if (!set(arr, contiguous)) {
- throw py::exception();
- }
- }
-
- array_view(const array_view &other) : m_arr(NULL), m_data(NULL)
- {
- m_arr = other.m_arr;
- Py_XINCREF(m_arr);
- m_data = other.m_data;
- m_shape = other.m_shape;
- m_strides = other.m_strides;
- }
-
- array_view(PyArrayObject *arr, char *data, npy_intp *shape, npy_intp *strides)
- {
- m_arr = arr;
- Py_XINCREF(arr);
- m_data = data;
- m_shape = shape;
- m_strides = strides;
- }
-
- array_view(npy_intp shape[ND]) : m_arr(NULL), m_shape(NULL), m_strides(NULL), m_data(NULL)
- {
- PyObject *arr = PyArray_SimpleNew(ND, shape, type_num_of<T>::value);
- if (arr == NULL) {
- throw py::exception();
- }
- if (!set(arr, true)) {
- Py_DECREF(arr);
- throw py::exception();
- }
- Py_DECREF(arr);
- }
-
- ~array_view()
- {
- Py_XDECREF(m_arr);
- }
-
- array_view& operator=(const array_view &other)
- {
- if (this != &other)
- {
- Py_XDECREF(m_arr);
- m_arr = other.m_arr;
- Py_XINCREF(m_arr);
- m_data = other.m_data;
- m_shape = other.m_shape;
- m_strides = other.m_strides;
- }
- return *this;
- }
-
- int set(PyObject *arr, bool contiguous = false)
- {
- PyArrayObject *tmp;
-
- if (arr == NULL || arr == Py_None) {
- Py_XDECREF(m_arr);
- m_arr = NULL;
- m_data = NULL;
- m_shape = zeros;
- m_strides = zeros;
- } else {
- if (contiguous) {
- tmp = (PyArrayObject *)PyArray_ContiguousFromAny(arr, type_num_of<T>::value, 0, ND);
- } else {
- tmp = (PyArrayObject *)PyArray_FromObject(arr, type_num_of<T>::value, 0, ND);
- }
- if (tmp == NULL) {
- return 0;
- }
-
- if (PyArray_NDIM(tmp) == 0 || PyArray_DIM(tmp, 0) == 0) {
- Py_XDECREF(m_arr);
- m_arr = NULL;
- m_data = NULL;
- m_shape = zeros;
- m_strides = zeros;
- if (PyArray_NDIM(tmp) == 0 && ND == 0) {
- m_arr = tmp;
- return 1;
- }
- }
- if (PyArray_NDIM(tmp) != ND) {
- PyErr_Format(PyExc_ValueError,
- "Expected %d-dimensional array, got %d",
- ND,
- PyArray_NDIM(tmp));
- Py_DECREF(tmp);
- return 0;
- }
-
- /* Copy some of the data to the view object for faster access */
- Py_XDECREF(m_arr);
- m_arr = tmp;
- m_shape = PyArray_DIMS(m_arr);
- m_strides = PyArray_STRIDES(m_arr);
- m_data = (char *)PyArray_BYTES(tmp);
- }
-
- return 1;
- }
-
- npy_intp dim(size_t i) const
- {
- if (i >= ND) {
- return 0;
- }
- return m_shape[i];
- }
-
- /*
- In most cases, code should use size() instead of dim(0), since
- size() == 0 when any dimension is 0.
- */
- size_t size() const
- {
- bool empty = (ND == 0);
- for (size_t i = 0; i < ND; i++) {
- if (m_shape[i] == 0) {
- empty = true;
- }
- }
- if (empty) {
- return 0;
- } else {
- return (size_t)dim(0);
- }
- }
-
- bool empty() const
- {
- return size() == 0;
- }
-
- // Do not use this for array_view<bool, ND>. See comment near top of file.
- const T *data() const
- {
- return (const T *)m_data;
- }
-
- // Do not use this for array_view<bool, ND>. See comment near top of file.
- T *data()
- {
- return (T *)m_data;
- }
-
- // Return a new reference.
- PyObject *pyobj()
- {
- Py_XINCREF(m_arr);
- return (PyObject *)m_arr;
- }
-
- // Steal a reference.
- PyObject *pyobj_steal()
- {
- return (PyObject *)m_arr;
- }
-
- static int converter(PyObject *obj, void *arrp)
- {
- array_view<T, ND> *arr = (array_view<T, ND> *)arrp;
-
- if (!arr->set(obj)) {
- return 0;
- }
-
- return 1;
- }
-
- static int converter_contiguous(PyObject *obj, void *arrp)
- {
- array_view<T, ND> *arr = (array_view<T, ND> *)arrp;
-
- if (!arr->set(obj, true)) {
- return 0;
- }
-
- return 1;
- }
-};
-
-} // namespace numpy
-
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/path_cleanup.cpp b/contrib/python/matplotlib/py2/src/path_cleanup.cpp
deleted file mode 100644
index f9f2213b3d..0000000000
--- a/contrib/python/matplotlib/py2/src/path_cleanup.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#include <Python.h>
-#define NO_IMPORT_ARRAY
-#include "numpy/arrayobject.h"
-
-#include "py_converters.h"
-
-#include "py_adaptors.h"
-#include "agg_conv_transform.h"
-#include "path_converters.h"
-
-class PathCleanupIterator
-{
- typedef agg::conv_transform<py::PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removal_t;
- typedef PathClipper<nan_removal_t> clipped_t;
- typedef PathSnapper<clipped_t> snapped_t;
- typedef PathSimplifier<snapped_t> simplify_t;
- typedef Sketch<simplify_t> sketch_t;
-
- py::PathIterator m_path_iter;
- agg::trans_affine m_transform;
- transformed_path_t m_transformed;
- nan_removal_t m_nan_removed;
- clipped_t m_clipped;
- snapped_t m_snapped;
- simplify_t m_simplify;
- sketch_t m_sketch;
-
- public:
- PathCleanupIterator(PyObject *path,
- agg::trans_affine trans,
- bool remove_nans,
- bool do_clip,
- const agg::rect_base<double> &rect,
- e_snap_mode snap_mode,
- double stroke_width,
- bool do_simplify,
- double sketch_scale,
- double sketch_length,
- double sketch_randomness)
- : m_transform(trans),
- m_transformed(m_path_iter, m_transform),
- m_nan_removed(m_transformed, remove_nans, m_path_iter.has_curves()),
- m_clipped(m_nan_removed, do_clip && !m_path_iter.has_curves(), rect),
- m_snapped(m_clipped, snap_mode, m_path_iter.total_vertices(), stroke_width),
- m_simplify(m_snapped,
- do_simplify && m_path_iter.should_simplify(),
- m_path_iter.simplify_threshold()),
- m_sketch(m_simplify, sketch_scale, sketch_length, sketch_randomness)
- {
- convert_path(path, &m_path_iter);
-
- Py_INCREF(path);
- m_path_iter.rewind(0);
- }
-
- unsigned vertex(double *x, double *y)
- {
- return m_simplify.vertex(x, y);
- }
-};
-
-extern "C" {
-void *get_path_iterator(PyObject *path,
- PyObject *trans,
- int remove_nans,
- int do_clip,
- double rect[4],
- e_snap_mode snap_mode,
- double stroke_width,
- int do_simplify,
- double sketch_scale,
- double sketch_length,
- double sketch_randomness)
-{
- agg::trans_affine agg_trans;
- if (!convert_trans_affine(trans, &agg_trans)) {
- return NULL;
- }
- agg::rect_base<double> clip_rect(rect[0], rect[1], rect[2], rect[3]);
-
- PathCleanupIterator *pipeline = new PathCleanupIterator(path,
- agg_trans,
- remove_nans != 0,
- do_clip != 0,
- clip_rect,
- snap_mode,
- stroke_width,
- do_simplify != 0,
- sketch_scale,
- sketch_length,
- sketch_randomness);
-
- return (void *)pipeline;
-}
-
-unsigned get_vertex(void *pipeline, double *x, double *y)
-{
- PathCleanupIterator *pipeline_iter = (PathCleanupIterator *)pipeline;
-
- unsigned code = pipeline_iter->vertex(x, y);
- return code;
-}
-
-void free_path_iterator(void *pipeline)
-{
- PathCleanupIterator *pipeline_iter = (PathCleanupIterator *)pipeline;
-
- delete pipeline_iter;
-}
-}
diff --git a/contrib/python/matplotlib/py2/src/path_cleanup.h b/contrib/python/matplotlib/py2/src/path_cleanup.h
deleted file mode 100644
index b481395aa5..0000000000
--- a/contrib/python/matplotlib/py2/src/path_cleanup.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef PATH_CLEANUP_H
-#define PATH_CLEANUP_H
-
-#include <Python.h>
-
-enum e_snap_mode {
- SNAP_AUTO,
- SNAP_FALSE,
- SNAP_TRUE
-};
-
-void *get_path_iterator(PyObject *path,
- PyObject *trans,
- int remove_nans,
- int do_clip,
- double rect[4],
- enum e_snap_mode snap_mode,
- double stroke_width,
- int do_simplify);
-
-unsigned get_vertex(void *pipeline, double *x, double *y);
-
-void free_path_iterator(void *pipeline);
-
-#endif /* PATH_CLEANUP_H */
diff --git a/contrib/python/matplotlib/py2/src/path_converters.h b/contrib/python/matplotlib/py2/src/path_converters.h
deleted file mode 100644
index db40c18d5a..0000000000
--- a/contrib/python/matplotlib/py2/src/path_converters.h
+++ /dev/null
@@ -1,1011 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef __PATH_CONVERTERS_H__
-#define __PATH_CONVERTERS_H__
-
-#include <cmath>
-#include <stdint.h>
-#include "agg_path_storage.h"
-#include "agg_clip_liang_barsky.h"
-#include "mplutils.h"
-#include "agg_conv_segmentator.h"
-
-/*
- This file contains a number of vertex converters that modify
- paths. They all work as iterators, where the output is generated
- on-the-fly, and don't require a copy of the full data.
-
- Each class represents a discrete step in a "path-cleansing" pipeline.
- They are currently applied in the following order in the Agg backend:
-
- 1. Affine transformation (implemented in Agg, not here)
-
- 2. PathNanRemover: skips over segments containing non-finite numbers
- by inserting MOVETO commands
-
- 3. PathClipper: Clips line segments to a given rectangle. This is
- helpful for data reduction, and also to avoid a limitation in
- Agg where coordinates can not be larger than 24-bit signed
- integers.
-
- 4. PathSnapper: Rounds the path to the nearest center-pixels.
- This makes rectilinear curves look much better.
-
- 5. PathSimplifier: Removes line segments from highly dense paths
- that would not have an impact on their appearance. Speeds up
- rendering and reduces file sizes.
-
- 6. curve-to-line-segment conversion (implemented in Agg, not here)
-
- 7. stroking (implemented in Agg, not here)
- */
-
-/************************************************************
- This is a base class for vertex converters that need to queue their
- output. It is designed to be as fast as possible vs. the STL's queue
- which is more flexible.
- */
-template <int QueueSize>
-class EmbeddedQueue
-{
- protected:
- EmbeddedQueue() : m_queue_read(0), m_queue_write(0)
- {
- // empty
- }
-
- struct item
- {
- item()
- {
- }
-
- inline void set(const unsigned cmd_, const double x_, const double y_)
- {
- cmd = cmd_;
- x = x_;
- y = y_;
- }
- unsigned cmd;
- double x;
- double y;
- };
- int m_queue_read;
- int m_queue_write;
- item m_queue[QueueSize];
-
- inline void queue_push(const unsigned cmd, const double x, const double y)
- {
- m_queue[m_queue_write++].set(cmd, x, y);
- }
-
- inline bool queue_nonempty()
- {
- return m_queue_read < m_queue_write;
- }
-
- inline bool queue_pop(unsigned *cmd, double *x, double *y)
- {
- if (queue_nonempty()) {
- const item &front = m_queue[m_queue_read++];
- *cmd = front.cmd;
- *x = front.x;
- *y = front.y;
-
- return true;
- }
-
- m_queue_read = 0;
- m_queue_write = 0;
-
- return false;
- }
-
- inline void queue_clear()
- {
- m_queue_read = 0;
- m_queue_write = 0;
- }
-};
-
-/* Defines when path segment types have more than one vertex */
-static const size_t num_extra_points_map[] =
- {0, 0, 0, 1,
- 2, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0
- };
-
-/* An implementation of a simple linear congruential random number
- generator. This is a "classic" and fast RNG which works fine for
- our purposes of sketching lines, but should not be used for things
- that matter, like crypto. We are implementing this ourselves
- rather than using the C stdlib so that the seed state is not shared
- with other third-party code. There are recent C++ options, but we
- still require nothing later than C++98 for compatibility
- reasons. */
-class RandomNumberGenerator
-{
-private:
- /* These are the same constants from MS Visual C++, which
- has the nice property that the modulus is 2^32, thus
- saving an explicit modulo operation
- */
- static const uint32_t a = 214013;
- static const uint32_t c = 2531011;
- uint32_t m_seed;
-
-public:
- RandomNumberGenerator() : m_seed(0) {}
- RandomNumberGenerator(int seed) : m_seed(seed) {}
-
- void seed(int seed)
- {
- m_seed = seed;
- }
-
- double get_double()
- {
- m_seed = (a * m_seed + c);
- return (double)m_seed / (double)(1LL << 32);
- }
-};
-
-/*
- PathNanRemover is a vertex converter that removes non-finite values
- from the vertices list, and inserts MOVETO commands as necessary to
- skip over them. If a curve segment contains at least one non-finite
- value, the entire curve segment will be skipped.
- */
-template <class VertexSource>
-class PathNanRemover : protected EmbeddedQueue<4>
-{
- VertexSource *m_source;
- bool m_remove_nans;
- bool m_has_curves;
-
- public:
- /* has_curves should be true if the path contains bezier curve
- segments, as this requires a slower algorithm to remove the
- NaNs. When in doubt, set to true.
- */
- PathNanRemover(VertexSource &source, bool remove_nans, bool has_curves)
- : m_source(&source), m_remove_nans(remove_nans), m_has_curves(has_curves)
- {
- // empty
- }
-
- inline void rewind(unsigned path_id)
- {
- queue_clear();
- m_source->rewind(path_id);
- }
-
- inline unsigned vertex(double *x, double *y)
- {
- unsigned code;
-
- if (!m_remove_nans) {
- return m_source->vertex(x, y);
- }
-
- if (m_has_curves) {
- /* This is the slow method for when there might be curves. */
- if (queue_pop(&code, x, y)) {
- return code;
- }
-
- bool needs_move_to = false;
- while (true) {
- /* The approach here is to push each full curve
- segment into the queue. If any non-finite values
- are found along the way, the queue is emptied, and
- the next curve segment is handled. */
- code = m_source->vertex(x, y);
- if (code == agg::path_cmd_stop ||
- code == (agg::path_cmd_end_poly | agg::path_flags_close)) {
- return code;
- }
-
- if (needs_move_to) {
- queue_push(agg::path_cmd_move_to, *x, *y);
- }
-
- size_t num_extra_points = num_extra_points_map[code & 0xF];
- bool has_nan = (!(std::isfinite(*x) && std::isfinite(*y)));
- queue_push(code, *x, *y);
-
- /* Note: this test can not be short-circuited, since we need to
- advance through the entire curve no matter what */
- for (size_t i = 0; i < num_extra_points; ++i) {
- m_source->vertex(x, y);
- has_nan = has_nan || !(std::isfinite(*x) && std::isfinite(*y));
- queue_push(code, *x, *y);
- }
-
- if (!has_nan) {
- break;
- }
-
- queue_clear();
-
- /* If the last point is finite, we use that for the
- moveto, otherwise, we'll use the first vertex of
- the next curve. */
- if (std::isfinite(*x) && std::isfinite(*y)) {
- queue_push(agg::path_cmd_move_to, *x, *y);
- needs_move_to = false;
- } else {
- needs_move_to = true;
- }
- }
-
- if (queue_pop(&code, x, y)) {
- return code;
- } else {
- return agg::path_cmd_stop;
- }
- } else // !m_has_curves
- {
- /* This is the fast path for when we know we have no curves */
- code = m_source->vertex(x, y);
-
- if (code == agg::path_cmd_stop ||
- code == (agg::path_cmd_end_poly | agg::path_flags_close)) {
- return code;
- }
-
- if (!(std::isfinite(*x) && std::isfinite(*y))) {
- do {
- code = m_source->vertex(x, y);
- if (code == agg::path_cmd_stop ||
- code == (agg::path_cmd_end_poly | agg::path_flags_close)) {
- return code;
- }
- } while (!(std::isfinite(*x) && std::isfinite(*y)));
- return agg::path_cmd_move_to;
- }
-
- return code;
- }
- }
-};
-
-/************************************************************
- PathClipper uses the Liang-Barsky line clipping algorithm (as
- implemented in Agg) to clip the path to a given rectangle. Lines
- will never extend outside of the rectangle. Curve segments are not
- clipped, but are always included in their entirety.
- */
-template <class VertexSource>
-class PathClipper : public EmbeddedQueue<3>
-{
- VertexSource *m_source;
- bool m_do_clipping;
- agg::rect_base<double> m_cliprect;
- double m_lastX;
- double m_lastY;
- bool m_moveto;
- double m_initX;
- double m_initY;
- bool m_has_init;
-
- public:
- PathClipper(VertexSource &source, bool do_clipping, double width, double height)
- : m_source(&source),
- m_do_clipping(do_clipping),
- m_cliprect(-1.0, -1.0, width + 1.0, height + 1.0),
- m_moveto(true),
- m_has_init(false)
- {
- // empty
- }
-
- PathClipper(VertexSource &source, bool do_clipping, const agg::rect_base<double> &rect)
- : m_source(&source),
- m_do_clipping(do_clipping),
- m_cliprect(rect),
- m_moveto(true),
- m_has_init(false)
- {
- m_cliprect.x1 -= 1.0;
- m_cliprect.y1 -= 1.0;
- m_cliprect.x2 += 1.0;
- m_cliprect.y2 += 1.0;
- }
-
- inline void rewind(unsigned path_id)
- {
- m_has_init = false;
- m_moveto = true;
- m_source->rewind(path_id);
- }
-
- int draw_clipped_line(double x0, double y0, double x1, double y1)
- {
- unsigned moved = agg::clip_line_segment(&x0, &y0, &x1, &y1, m_cliprect);
- // moved >= 4 - Fully clipped
- // moved & 1 != 0 - First point has been moved
- // moved & 2 != 0 - Second point has been moved
- if (moved < 4) {
- if (moved & 1 || m_moveto) {
- queue_push(agg::path_cmd_move_to, x0, y0);
- }
- queue_push(agg::path_cmd_line_to, x1, y1);
-
- m_moveto = false;
- return 1;
- }
-
- return 0;
- }
-
- unsigned vertex(double *x, double *y)
- {
- unsigned code;
- bool emit_moveto = false;
-
- if (m_do_clipping) {
- /* This is the slow path where we actually do clipping */
-
- if (queue_pop(&code, x, y)) {
- return code;
- }
-
- while ((code = m_source->vertex(x, y)) != agg::path_cmd_stop) {
- emit_moveto = false;
-
- switch (code) {
- case (agg::path_cmd_end_poly | agg::path_flags_close):
- if (m_has_init) {
- draw_clipped_line(m_lastX, m_lastY, m_initX, m_initY);
- }
- queue_push(
- agg::path_cmd_end_poly | agg::path_flags_close,
- m_lastX, m_lastY);
- goto exit_loop;
-
- case agg::path_cmd_move_to:
-
- // was the last command a moveto (and we have
- // seen at least one command ?
- // if so, shove it in the queue if in clip box
- if (m_moveto && m_has_init &&
- m_lastX >= m_cliprect.x1 &&
- m_lastX <= m_cliprect.x2 &&
- m_lastY >= m_cliprect.y1 &&
- m_lastY <= m_cliprect.y2) {
- // push the last moveto onto the queue
- queue_push(agg::path_cmd_move_to, m_lastX, m_lastY);
- // flag that we need to emit it
- emit_moveto = true;
- }
- // update the internal state for this moveto
- m_initX = m_lastX = *x;
- m_initY = m_lastY = *y;
- m_has_init = true;
- m_moveto = true;
- // if the last command was moveto exit the loop to emit the code
- if (emit_moveto) {
- goto exit_loop;
- }
- // else, break and get the next point
- break;
-
- case agg::path_cmd_line_to:
- if (draw_clipped_line(m_lastX, m_lastY, *x, *y)) {
- m_lastX = *x;
- m_lastY = *y;
- goto exit_loop;
- }
- m_lastX = *x;
- m_lastY = *y;
- break;
-
- default:
- if (m_moveto) {
- queue_push(agg::path_cmd_move_to, m_lastX, m_lastY);
- m_moveto = false;
- }
-
- queue_push(code, *x, *y);
- m_lastX = *x;
- m_lastY = *y;
- goto exit_loop;
- }
- }
-
- exit_loop:
-
- if (queue_pop(&code, x, y)) {
- return code;
- }
-
- if (m_moveto &&
- m_lastX >= m_cliprect.x1 &&
- m_lastX <= m_cliprect.x2 &&
- m_lastY >= m_cliprect.y1 &&
- m_lastY <= m_cliprect.y2) {
- *x = m_lastX;
- *y = m_lastY;
- m_moveto = false;
- return agg::path_cmd_move_to;
- }
-
- return agg::path_cmd_stop;
- } else {
- // If not doing any clipping, just pass along the vertices
- // verbatim
- return m_source->vertex(x, y);
- }
- }
-};
-
-/************************************************************
- PathSnapper rounds vertices to their nearest center-pixels. This
- makes rectilinear paths (rectangles, horizontal and vertical lines
- etc.) look much cleaner.
-*/
-enum e_snap_mode {
- SNAP_AUTO,
- SNAP_FALSE,
- SNAP_TRUE
-};
-
-template <class VertexSource>
-class PathSnapper
-{
- private:
- VertexSource *m_source;
- bool m_snap;
- double m_snap_value;
-
- static bool should_snap(VertexSource &path, e_snap_mode snap_mode, unsigned total_vertices)
- {
- // If this contains only straight horizontal or vertical lines, it should be
- // snapped to the nearest pixels
- double x0 = 0, y0 = 0, x1 = 0, y1 = 0;
- unsigned code;
-
- switch (snap_mode) {
- case SNAP_AUTO:
- if (total_vertices > 1024) {
- return false;
- }
-
- code = path.vertex(&x0, &y0);
- if (code == agg::path_cmd_stop) {
- return false;
- }
-
- while ((code = path.vertex(&x1, &y1)) != agg::path_cmd_stop) {
- switch (code) {
- case agg::path_cmd_curve3:
- case agg::path_cmd_curve4:
- return false;
- case agg::path_cmd_line_to:
- if (!(fabs(x0 - x1) < 1e-4 || fabs(y0 - y1) < 1e-4)) {
- return false;
- }
- }
- x0 = x1;
- y0 = y1;
- }
-
- return true;
- case SNAP_FALSE:
- return false;
- case SNAP_TRUE:
- return true;
- }
-
- return false;
- }
-
- public:
- /*
- snap_mode should be one of:
- - SNAP_AUTO: Examine the path to determine if it should be snapped
- - SNAP_TRUE: Force snapping
- - SNAP_FALSE: No snapping
- */
- PathSnapper(VertexSource &source,
- e_snap_mode snap_mode,
- unsigned total_vertices = 15,
- double stroke_width = 0.0)
- : m_source(&source)
- {
- m_snap = should_snap(source, snap_mode, total_vertices);
-
- if (m_snap) {
- int is_odd = (int)mpl_round(stroke_width) % 2;
- m_snap_value = (is_odd) ? 0.5 : 0.0;
- }
-
- source.rewind(0);
- }
-
- inline void rewind(unsigned path_id)
- {
- m_source->rewind(path_id);
- }
-
- inline unsigned vertex(double *x, double *y)
- {
- unsigned code;
- code = m_source->vertex(x, y);
- if (m_snap && agg::is_vertex(code)) {
- *x = floor(*x + 0.5) + m_snap_value;
- *y = floor(*y + 0.5) + m_snap_value;
- }
- return code;
- }
-
- inline bool is_snapping()
- {
- return m_snap;
- }
-};
-
-/************************************************************
- PathSimplifier reduces the number of vertices in a dense path without
- changing its appearance.
-*/
-template <class VertexSource>
-class PathSimplifier : protected EmbeddedQueue<9>
-{
- public:
- /* Set simplify to true to perform simplification */
- PathSimplifier(VertexSource &source, bool do_simplify, double simplify_threshold)
- : m_source(&source),
- m_simplify(do_simplify),
- /* we square simplify_threshold so that we can compute
- norms without doing the square root every step. */
- m_simplify_threshold(simplify_threshold * simplify_threshold),
-
- m_moveto(true),
- m_after_moveto(false),
- m_clipped(false),
-
- // the x, y values from last iteration
- m_lastx(0.0),
- m_lasty(0.0),
-
- // the dx, dy comprising the original vector, used in conjunction
- // with m_currVecStart* to define the original vector.
- m_origdx(0.0),
- m_origdy(0.0),
-
- // the squared norm of the original vector
- m_origdNorm2(0.0),
-
- // maximum squared norm of vector in forward (parallel) direction
- m_dnorm2ForwardMax(0.0),
- // maximum squared norm of vector in backward (anti-parallel) direction
- m_dnorm2BackwardMax(0.0),
-
- // was the last point the furthest from lastWritten in the
- // forward (parallel) direction?
- m_lastForwardMax(false),
- // was the last point the furthest from lastWritten in the
- // backward (anti-parallel) direction?
- m_lastBackwardMax(false),
-
- // added to queue when _push is called
- m_nextX(0.0),
- m_nextY(0.0),
-
- // added to queue when _push is called if any backwards
- // (anti-parallel) vectors were observed
- m_nextBackwardX(0.0),
- m_nextBackwardY(0.0),
-
- // start of the current vector that is being simplified
- m_currVecStartX(0.0),
- m_currVecStartY(0.0)
- {
- // empty
- }
-
- inline void rewind(unsigned path_id)
- {
- queue_clear();
- m_moveto = true;
- m_source->rewind(path_id);
- }
-
- unsigned vertex(double *x, double *y)
- {
- unsigned cmd;
-
- /* The simplification algorithm doesn't support curves or compound paths
- so we just don't do it at all in that case... */
- if (!m_simplify) {
- return m_source->vertex(x, y);
- }
-
- /* idea: we can skip drawing many lines: we can combine
- sequential parallel lines into a
- single line instead of redrawing lines over the same
- points. The loop below works a bit like a state machine,
- where what it does depends on what it did in the last
- looping. To test whether sequential lines are close to
- parallel, I calculate the distance moved perpendicular to
- the last line. Once it gets too big, the lines cannot be
- combined. */
-
- /* This code was originally written by Allan Haldane and I
- have modified to work in-place -- meaning not creating an
- entirely new path list each time. In order to do that
- without too much additional code complexity, it keeps a
- small queue around so that multiple points can be emitted
- in a single call, and those points will be popped from the
- queue in subsequent calls. The following block will empty
- the queue before proceeding to the main loop below.
- -- Michael Droettboom */
-
- /* This code was originally written by Allan Haldane and
- updated by Michael Droettboom. I have modified it to
- handle anti-parallel vectors. This is done essentially
- the same way as parallel vectors, but requires a little
- additional book-keeping to track whether or not we have
- observed an anti-parallel vector during the current run.
- -- Kevin Rose */
-
- if (queue_pop(&cmd, x, y)) {
- return cmd;
- }
-
- /* The main simplification loop. The point is to consume only
- as many points as necessary until something has been added
- to the outbound queue, not to run through the entire path
- in one go. This eliminates the need to allocate and fill
- an entire additional path array on each draw. */
- while ((cmd = m_source->vertex(x, y)) != agg::path_cmd_stop) {
- /* if we are starting a new path segment, move to the first point
- + init */
-
- if (m_moveto || cmd == agg::path_cmd_move_to) {
- /* m_moveto check is not generally needed because
- m_source generates an initial moveto; but it is
- retained for safety in case circumstances arise
- where this is not true. */
- if (m_origdNorm2 != 0.0 && !m_after_moveto) {
- /* m_origdNorm2 is nonzero only if we have a
- vector; the m_after_moveto check ensures we
- push this vector to the queue only once. */
- _push(x, y);
- }
- m_after_moveto = true;
- m_lastx = *x;
- m_lasty = *y;
- m_moveto = false;
- m_origdNorm2 = 0.0;
- m_dnorm2BackwardMax = 0.0;
- m_clipped = true;
- if (queue_nonempty()) {
- /* If we did a push, empty the queue now. */
- break;
- }
- continue;
- }
- m_after_moveto = false;
-
- /* NOTE: We used to skip this very short segments, but if
- you have a lot of them cumulatively, you can miss
- maxima or minima in the data. */
-
- /* Don't render line segments less than one pixel long */
- /* if (fabs(*x - m_lastx) < 1.0 && fabs(*y - m_lasty) < 1.0) */
- /* { */
- /* continue; */
- /* } */
-
- /* if we have no orig vector, set it to this vector and
- continue. this orig vector is the reference vector we
- will build up the line to */
- if (m_origdNorm2 == 0.0) {
- if (m_clipped) {
- queue_push(agg::path_cmd_move_to, m_lastx, m_lasty);
- m_clipped = false;
- }
-
- m_origdx = *x - m_lastx;
- m_origdy = *y - m_lasty;
- m_origdNorm2 = m_origdx * m_origdx + m_origdy * m_origdy;
-
- // set all the variables to reflect this new orig vector
- m_dnorm2ForwardMax = m_origdNorm2;
- m_dnorm2BackwardMax = 0.0;
- m_lastForwardMax = true;
- m_lastBackwardMax = false;
-
- m_currVecStartX = m_lastx;
- m_currVecStartY = m_lasty;
- m_nextX = m_lastx = *x;
- m_nextY = m_lasty = *y;
- continue;
- }
-
- /* If got to here, then we have an orig vector and we just got
- a vector in the sequence. */
-
- /* Check that the perpendicular distance we have moved
- from the last written point compared to the line we are
- building is not too much. If o is the orig vector (we
- are building on), and v is the vector from the last
- written point to the current point, then the
- perpendicular vector is p = v - (o.v)o/(o.o)
- (here, a.b indicates the dot product of a and b). */
-
- /* get the v vector */
- double totdx = *x - m_currVecStartX;
- double totdy = *y - m_currVecStartY;
-
- /* get the dot product o.v */
- double totdot = m_origdx * totdx + m_origdy * totdy;
-
- /* get the para vector ( = (o.v)o/(o.o)) */
- double paradx = totdot * m_origdx / m_origdNorm2;
- double parady = totdot * m_origdy / m_origdNorm2;
-
- /* get the perp vector ( = v - para) */
- double perpdx = totdx - paradx;
- double perpdy = totdy - parady;
-
- /* get the squared norm of perp vector ( = p.p) */
- double perpdNorm2 = perpdx * perpdx + perpdy * perpdy;
-
- /* If the perpendicular vector is less than
- m_simplify_threshold pixels in size, then merge
- current x,y with the current vector */
- if (perpdNorm2 < m_simplify_threshold) {
- /* check if the current vector is parallel or
- anti-parallel to the orig vector. In either case,
- test if it is the longest of the vectors
- we are merging in that direction. If it is, then
- update the current vector in that direction. */
- double paradNorm2 = paradx * paradx + parady * parady;
-
- m_lastForwardMax = false;
- m_lastBackwardMax = false;
- if (totdot > 0.0) {
- if (paradNorm2 > m_dnorm2ForwardMax) {
- m_lastForwardMax = true;
- m_dnorm2ForwardMax = paradNorm2;
- m_nextX = *x;
- m_nextY = *y;
- }
- } else {
- if (paradNorm2 > m_dnorm2BackwardMax) {
- m_lastBackwardMax = true;
- m_dnorm2BackwardMax = paradNorm2;
- m_nextBackwardX = *x;
- m_nextBackwardY = *y;
- }
- }
-
- m_lastx = *x;
- m_lasty = *y;
- continue;
- }
-
- /* If we get here, then this vector was not similar enough to the
- line we are building, so we need to draw that line and start the
- next one. */
-
- /* If the line needs to extend in the opposite direction from the
- direction we are drawing in, move back to we start drawing from
- back there. */
- _push(x, y);
-
- break;
- }
-
- /* Fill the queue with the remaining vertices if we've finished the
- path in the above loop. */
- if (cmd == agg::path_cmd_stop) {
- if (m_origdNorm2 != 0.0) {
- queue_push((m_moveto || m_after_moveto) ? agg::path_cmd_move_to
- : agg::path_cmd_line_to,
- m_nextX,
- m_nextY);
- if (m_dnorm2BackwardMax > 0.0) {
- queue_push((m_moveto || m_after_moveto) ? agg::path_cmd_move_to
- : agg::path_cmd_line_to,
- m_nextBackwardX,
- m_nextBackwardY);
- }
- m_moveto = false;
- }
- queue_push((m_moveto || m_after_moveto) ? agg::path_cmd_move_to : agg::path_cmd_line_to,
- m_lastx,
- m_lasty);
- m_moveto = false;
- queue_push(agg::path_cmd_stop, 0.0, 0.0);
- }
-
- /* Return the first item in the queue, if any, otherwise
- indicate that we're done. */
- if (queue_pop(&cmd, x, y)) {
- return cmd;
- } else {
- return agg::path_cmd_stop;
- }
- }
-
- private:
- VertexSource *m_source;
- bool m_simplify;
- double m_simplify_threshold;
-
- bool m_moveto;
- bool m_after_moveto;
- bool m_clipped;
- double m_lastx, m_lasty;
-
- double m_origdx;
- double m_origdy;
- double m_origdNorm2;
- double m_dnorm2ForwardMax;
- double m_dnorm2BackwardMax;
- bool m_lastForwardMax;
- bool m_lastBackwardMax;
- double m_nextX;
- double m_nextY;
- double m_nextBackwardX;
- double m_nextBackwardY;
- double m_currVecStartX;
- double m_currVecStartY;
-
- inline void _push(double *x, double *y)
- {
- bool needToPushBack = (m_dnorm2BackwardMax > 0.0);
-
- /* If we observed any backward (anti-parallel) vectors, then
- we need to push both forward and backward vectors. */
- if (needToPushBack) {
- /* If the last vector seen was the maximum in the forward direction,
- then we need to push the forward after the backward. Otherwise,
- the last vector seen was the maximum in the backward direction,
- or somewhere in between, either way we are safe pushing forward
- before backward. */
- if (m_lastForwardMax) {
- queue_push(agg::path_cmd_line_to, m_nextBackwardX, m_nextBackwardY);
- queue_push(agg::path_cmd_line_to, m_nextX, m_nextY);
- } else {
- queue_push(agg::path_cmd_line_to, m_nextX, m_nextY);
- queue_push(agg::path_cmd_line_to, m_nextBackwardX, m_nextBackwardY);
- }
- } else {
- /* If we did not observe any backwards vectors, just push forward. */
- queue_push(agg::path_cmd_line_to, m_nextX, m_nextY);
- }
-
- /* If we clipped some segments between this line and the next line
- we are starting, we also need to move to the last point. */
- if (m_clipped) {
- queue_push(agg::path_cmd_move_to, m_lastx, m_lasty);
- } else if ((!m_lastForwardMax) && (!m_lastBackwardMax)) {
- /* If the last line was not the longest line, then move
- back to the end point of the last line in the
- sequence. Only do this if not clipped, since in that
- case lastx,lasty is not part of the line just drawn. */
-
- /* Would be move_to if not for the artifacts */
- queue_push(agg::path_cmd_line_to, m_lastx, m_lasty);
- }
-
- /* Now reset all the variables to get ready for the next line */
- m_origdx = *x - m_lastx;
- m_origdy = *y - m_lasty;
- m_origdNorm2 = m_origdx * m_origdx + m_origdy * m_origdy;
-
- m_dnorm2ForwardMax = m_origdNorm2;
- m_lastForwardMax = true;
- m_currVecStartX = m_queue[m_queue_write - 1].x;
- m_currVecStartY = m_queue[m_queue_write - 1].y;
- m_lastx = m_nextX = *x;
- m_lasty = m_nextY = *y;
- m_dnorm2BackwardMax = 0.0;
- m_lastBackwardMax = false;
-
- m_clipped = false;
- }
-};
-
-template <class VertexSource>
-class Sketch
-{
- public:
- /*
- scale: the scale of the wiggle perpendicular to the original
- line (in pixels)
-
- length: the base wavelength of the wiggle along the
- original line (in pixels)
-
- randomness: the factor that the sketch length will randomly
- shrink and expand.
- */
- Sketch(VertexSource &source, double scale, double length, double randomness)
- : m_source(&source),
- m_scale(scale),
- m_length(length),
- m_randomness(randomness),
- m_segmented(source),
- m_last_x(0.0),
- m_last_y(0.0),
- m_has_last(false),
- m_p(0.0),
- m_rand(0)
- {
- rewind(0);
- }
-
- unsigned vertex(double *x, double *y)
- {
- if (m_scale == 0.0) {
- return m_source->vertex(x, y);
- }
-
- unsigned code = m_segmented.vertex(x, y);
-
- if (code == agg::path_cmd_move_to) {
- m_has_last = false;
- m_p = 0.0;
- }
-
- if (m_has_last) {
- // We want the "cursor" along the sine wave to move at a
- // random rate.
- double d_rand = m_rand.get_double();
- double d_M_PI = 3.14159265358979323846;
- m_p += pow(m_randomness, d_rand * 2.0 - 1.0);
- double r = sin(m_p / (m_length / (d_M_PI * 2.0))) * m_scale;
- double den = m_last_x - *x;
- double num = m_last_y - *y;
- double len = num * num + den * den;
- m_last_x = *x;
- m_last_y = *y;
- if (len != 0) {
- len = sqrt(len);
- *x += r * num / len;
- *y += r * -den / len;
- }
- } else {
- m_last_x = *x;
- m_last_y = *y;
- }
-
- m_has_last = true;
-
- return code;
- }
-
- inline void rewind(unsigned path_id)
- {
- m_has_last = false;
- m_p = 0.0;
- if (m_scale != 0.0) {
- m_rand.seed(0);
- m_segmented.rewind(path_id);
- } else {
- m_source->rewind(path_id);
- }
- }
-
- private:
- VertexSource *m_source;
- double m_scale;
- double m_length;
- double m_randomness;
- agg::conv_segmentator<VertexSource> m_segmented;
- double m_last_x;
- double m_last_y;
- bool m_has_last;
- double m_p;
- RandomNumberGenerator m_rand;
-};
-
-#endif // __PATH_CONVERTERS_H__
diff --git a/contrib/python/matplotlib/py2/src/py_adaptors.h b/contrib/python/matplotlib/py2/src/py_adaptors.h
deleted file mode 100644
index 3d0dbdab45..0000000000
--- a/contrib/python/matplotlib/py2/src/py_adaptors.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef __PY_ADAPTORS_H__
-#define __PY_ADAPTORS_H__
-#define PY_SSIZE_T_CLEAN
-/***************************************************************************
- * This module contains a number of C++ classes that adapt Python data
- * structures to C++ and Agg-friendly interfaces.
- */
-
-#include <Python.h>
-
-#include "numpy/arrayobject.h"
-
-#include "py_exceptions.h"
-
-extern "C" {
-int convert_path(PyObject *obj, void *pathp);
-}
-
-namespace py
-{
-
-/************************************************************
- * py::PathIterator acts as a bridge between Numpy and Agg. Given a
- * pair of Numpy arrays, vertices and codes, it iterates over
- * those vertices and codes, using the standard Agg vertex source
- * interface:
- *
- * unsigned vertex(double* x, double* y)
- */
-class PathIterator
-{
- /* We hold references to the Python objects, not just the
- underlying data arrays, so that Python reference counting
- can work.
- */
- PyArrayObject *m_vertices;
- PyArrayObject *m_codes;
-
- unsigned m_iterator;
- unsigned m_total_vertices;
-
- /* This class doesn't actually do any simplification, but we
- store the value here, since it is obtained from the Python
- object.
- */
- bool m_should_simplify;
- double m_simplify_threshold;
-
- public:
- inline PathIterator()
- : m_vertices(NULL),
- m_codes(NULL),
- m_iterator(0),
- m_total_vertices(0),
- m_should_simplify(false),
- m_simplify_threshold(1.0 / 9.0)
- {
- }
-
- inline PathIterator(PyObject *vertices,
- PyObject *codes,
- bool should_simplify,
- double simplify_threshold)
- : m_vertices(NULL), m_codes(NULL), m_iterator(0)
- {
- if (!set(vertices, codes, should_simplify, simplify_threshold))
- throw py::exception();
- }
-
- inline PathIterator(PyObject *vertices, PyObject *codes)
- : m_vertices(NULL), m_codes(NULL), m_iterator(0)
- {
- if (!set(vertices, codes))
- throw py::exception();
- }
-
- inline PathIterator(const PathIterator &other)
- {
- Py_XINCREF(other.m_vertices);
- m_vertices = other.m_vertices;
-
- Py_XINCREF(other.m_codes);
- m_codes = other.m_codes;
-
- m_iterator = 0;
- m_total_vertices = other.m_total_vertices;
-
- m_should_simplify = other.m_should_simplify;
- m_simplify_threshold = other.m_simplify_threshold;
- }
-
- ~PathIterator()
- {
- Py_XDECREF(m_vertices);
- Py_XDECREF(m_codes);
- }
-
- inline int
- set(PyObject *vertices, PyObject *codes, bool should_simplify, double simplify_threshold)
- {
- m_should_simplify = should_simplify;
- m_simplify_threshold = simplify_threshold;
-
- Py_XDECREF(m_vertices);
- m_vertices = (PyArrayObject *)PyArray_FromObject(vertices, NPY_DOUBLE, 2, 2);
-
- if (!m_vertices || PyArray_DIM(m_vertices, 1) != 2) {
- PyErr_SetString(PyExc_ValueError, "Invalid vertices array");
- return 0;
- }
-
- Py_XDECREF(m_codes);
- m_codes = NULL;
-
- if (codes != NULL && codes != Py_None) {
- m_codes = (PyArrayObject *)PyArray_FromObject(codes, NPY_UINT8, 1, 1);
-
- if (!m_codes || PyArray_DIM(m_codes, 0) != PyArray_DIM(m_vertices, 0)) {
- PyErr_SetString(PyExc_ValueError, "Invalid codes array");
- return 0;
- }
- }
-
- m_total_vertices = (unsigned)PyArray_DIM(m_vertices, 0);
- m_iterator = 0;
-
- return 1;
- }
-
- inline int set(PyObject *vertices, PyObject *codes)
- {
- return set(vertices, codes, false, 0.0);
- }
-
- inline unsigned vertex(double *x, double *y)
- {
- if (m_iterator >= m_total_vertices) {
- *x = 0.0;
- *y = 0.0;
- return agg::path_cmd_stop;
- }
-
- const size_t idx = m_iterator++;
-
- char *pair = (char *)PyArray_GETPTR2(m_vertices, idx, 0);
- *x = *(double *)pair;
- *y = *(double *)(pair + PyArray_STRIDE(m_vertices, 1));
-
- if (m_codes != NULL) {
- return (unsigned)(*(char *)PyArray_GETPTR1(m_codes, idx));
- } else {
- return idx == 0 ? agg::path_cmd_move_to : agg::path_cmd_line_to;
- }
- }
-
- inline void rewind(unsigned path_id)
- {
- m_iterator = path_id;
- }
-
- inline unsigned total_vertices() const
- {
- return m_total_vertices;
- }
-
- inline bool should_simplify() const
- {
- return m_should_simplify;
- }
-
- inline double simplify_threshold() const
- {
- return m_simplify_threshold;
- }
-
- inline bool has_curves() const
- {
- return m_codes != NULL;
- }
-
- inline void *get_id()
- {
- return (void *)m_vertices;
- }
-};
-
-class PathGenerator
-{
- PyObject *m_paths;
- Py_ssize_t m_npaths;
-
- public:
- typedef PathIterator path_iterator;
-
- PathGenerator(PyObject *obj) : m_paths(NULL), m_npaths(0)
- {
- if (!set(obj)) {
- throw py::exception();
- }
- }
-
- ~PathGenerator()
- {
- Py_XDECREF(m_paths);
- }
-
- int set(PyObject *obj)
- {
- if (!PySequence_Check(obj)) {
- return 0;
- }
-
- m_paths = obj;
- Py_INCREF(m_paths);
-
- m_npaths = PySequence_Size(m_paths);
-
- return 1;
- }
-
- Py_ssize_t num_paths() const
- {
- return m_npaths;
- }
-
- Py_ssize_t size() const
- {
- return m_npaths;
- }
-
- path_iterator operator()(size_t i)
- {
- path_iterator path;
- PyObject *item;
-
- item = PySequence_GetItem(m_paths, i % m_npaths);
- if (item == NULL) {
- throw py::exception();
- }
- if (!convert_path(item, &path)) {
- throw py::exception();
- }
- Py_DECREF(item);
- return path;
- }
-};
-}
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/py_converters.cpp b/contrib/python/matplotlib/py2/src/py_converters.cpp
deleted file mode 100644
index 2d5d415a2c..0000000000
--- a/contrib/python/matplotlib/py2/src/py_converters.cpp
+++ /dev/null
@@ -1,619 +0,0 @@
-#define NO_IMPORT_ARRAY
-#define PY_SSIZE_T_CLEAN
-#include "py_converters.h"
-#include "numpy_cpp.h"
-
-#include "agg_basics.h"
-#include "agg_color_rgba.h"
-#include "agg_math_stroke.h"
-
-extern "C" {
-
-static int convert_string_enum(PyObject *obj, const char *name, const char **names, int *values, int *result)
-{
- PyObject *bytesobj;
- char *str;
-
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- if (PyUnicode_Check(obj)) {
- bytesobj = PyUnicode_AsASCIIString(obj);
- if (bytesobj == NULL) {
- return 0;
- }
- } else if (PyBytes_Check(obj)) {
- Py_INCREF(obj);
- bytesobj = obj;
- } else {
- PyErr_Format(PyExc_TypeError, "%s must be bytes or unicode", name);
- return 0;
- }
-
- str = PyBytes_AsString(bytesobj);
- if (str == NULL) {
- Py_DECREF(bytesobj);
- return 0;
- }
-
- for ( ; *names != NULL; names++, values++) {
- if (strncmp(str, *names, 64) == 0) {
- *result = *values;
- Py_DECREF(bytesobj);
- return 1;
- }
- }
-
- PyErr_Format(PyExc_ValueError, "invalid %s value", name);
- Py_DECREF(bytesobj);
- return 0;
-}
-
-int convert_from_method(PyObject *obj, const char *name, converter func, void *p)
-{
- PyObject *value;
-
- value = PyObject_CallMethod(obj, (char *)name, NULL);
- if (value == NULL) {
- if (!PyObject_HasAttrString(obj, (char *)name)) {
- PyErr_Clear();
- return 1;
- }
- return 0;
- }
-
- if (!func(value, p)) {
- Py_DECREF(value);
- return 0;
- }
-
- Py_DECREF(value);
- return 1;
-}
-
-int convert_from_attr(PyObject *obj, const char *name, converter func, void *p)
-{
- PyObject *value;
-
- value = PyObject_GetAttrString(obj, (char *)name);
- if (value == NULL) {
- if (!PyObject_HasAttrString(obj, (char *)name)) {
- PyErr_Clear();
- return 1;
- }
- return 0;
- }
-
- if (!func(value, p)) {
- Py_DECREF(value);
- return 0;
- }
-
- Py_DECREF(value);
- return 1;
-}
-
-int convert_double(PyObject *obj, void *p)
-{
- double *val = (double *)p;
-
- *val = PyFloat_AsDouble(obj);
- if (PyErr_Occurred()) {
- return 0;
- }
-
- return 1;
-}
-
-int convert_bool(PyObject *obj, void *p)
-{
- bool *val = (bool *)p;
-
- *val = PyObject_IsTrue(obj);
-
- return 1;
-}
-
-int convert_cap(PyObject *capobj, void *capp)
-{
- const char *names[] = {"butt", "round", "projecting", NULL};
- int values[] = {agg::butt_cap, agg::round_cap, agg::square_cap};
- int result = agg::butt_cap;
-
- if (!convert_string_enum(capobj, "capstyle", names, values, &result)) {
- return 0;
- }
-
- *(agg::line_cap_e *)capp = (agg::line_cap_e)result;
- return 1;
-}
-
-int convert_join(PyObject *joinobj, void *joinp)
-{
- const char *names[] = {"miter", "round", "bevel", NULL};
- int values[] = {agg::miter_join_revert, agg::round_join, agg::bevel_join};
- int result = agg::miter_join_revert;
-
- if (!convert_string_enum(joinobj, "joinstyle", names, values, &result)) {
- return 0;
- }
-
- *(agg::line_join_e *)joinp = (agg::line_join_e)result;
- return 1;
-}
-
-int convert_rect(PyObject *rectobj, void *rectp)
-{
- agg::rect_d *rect = (agg::rect_d *)rectp;
-
- if (rectobj == NULL || rectobj == Py_None) {
- rect->x1 = 0.0;
- rect->y1 = 0.0;
- rect->x2 = 0.0;
- rect->y2 = 0.0;
- } else {
- try
- {
- numpy::array_view<const double, 2> rect_arr(rectobj);
-
- if (rect_arr.dim(0) != 2 || rect_arr.dim(1) != 2) {
- PyErr_SetString(PyExc_ValueError, "Invalid bounding box");
- return 0;
- }
-
- rect->x1 = rect_arr(0, 0);
- rect->y1 = rect_arr(0, 1);
- rect->x2 = rect_arr(1, 0);
- rect->y2 = rect_arr(1, 1);
- }
- catch (py::exception &)
- {
- PyErr_Clear();
-
- try
- {
- numpy::array_view<const double, 1> rect_arr(rectobj);
-
- if (rect_arr.dim(0) != 4) {
- PyErr_SetString(PyExc_ValueError, "Invalid bounding box");
- return 0;
- }
-
- rect->x1 = rect_arr(0);
- rect->y1 = rect_arr(1);
- rect->x2 = rect_arr(2);
- rect->y2 = rect_arr(3);
- }
- catch (py::exception &)
- {
- return 0;
- }
- }
- }
-
- return 1;
-}
-
-int convert_rgba(PyObject *rgbaobj, void *rgbap)
-{
- agg::rgba *rgba = (agg::rgba *)rgbap;
-
- if (rgbaobj == NULL || rgbaobj == Py_None) {
- rgba->r = 0.0;
- rgba->g = 0.0;
- rgba->b = 0.0;
- rgba->a = 0.0;
- } else {
- rgba->a = 1.0;
- if (!PyArg_ParseTuple(
- rgbaobj, "ddd|d:rgba", &(rgba->r), &(rgba->g), &(rgba->b), &(rgba->a))) {
- return 0;
- }
- }
-
- return 1;
-}
-
-int convert_dashes(PyObject *dashobj, void *dashesp)
-{
- Dashes *dashes = (Dashes *)dashesp;
-
- if (dashobj == NULL && dashobj == Py_None) {
- return 1;
- }
-
- PyObject *dash_offset_obj = NULL;
- double dash_offset = 0.0;
- PyObject *dashes_seq = NULL;
- Py_ssize_t nentries;
-
- if (!PyArg_ParseTuple(dashobj, "OO:dashes", &dash_offset_obj, &dashes_seq)) {
- return 0;
- }
-
- if (dash_offset_obj != Py_None) {
- dash_offset = PyFloat_AsDouble(dash_offset_obj);
- if (PyErr_Occurred()) {
- return 0;
- }
- }
-
- if (dashes_seq == Py_None) {
- return 1;
- }
-
- if (!PySequence_Check(dashes_seq)) {
- PyErr_SetString(PyExc_TypeError, "Invalid dashes sequence");
- return 0;
- }
-
- nentries = PySequence_Size(dashes_seq);
- if (nentries % 2 != 0) {
- PyErr_Format(PyExc_ValueError, "dashes sequence must have an even number of elements");
- return 0;
- }
-
- for (Py_ssize_t i = 0; i < nentries; ++i) {
- PyObject *item;
- double length;
- double skip;
-
- item = PySequence_GetItem(dashes_seq, i);
- if (item == NULL) {
- return 0;
- }
- length = PyFloat_AsDouble(item);
- if (PyErr_Occurred()) {
- Py_DECREF(item);
- return 0;
- }
- Py_DECREF(item);
-
- ++i;
-
- item = PySequence_GetItem(dashes_seq, i);
- if (item == NULL) {
- return 0;
- }
- skip = PyFloat_AsDouble(item);
- if (PyErr_Occurred()) {
- Py_DECREF(item);
- return 0;
- }
- Py_DECREF(item);
-
- dashes->add_dash_pair(length, skip);
- }
-
- dashes->set_dash_offset(dash_offset);
-
- return 1;
-}
-
-int convert_dashes_vector(PyObject *obj, void *dashesp)
-{
- DashesVector *dashes = (DashesVector *)dashesp;
-
- if (!PySequence_Check(obj)) {
- return 0;
- }
-
- Py_ssize_t n = PySequence_Size(obj);
-
- for (Py_ssize_t i = 0; i < n; ++i) {
- PyObject *item;
- Dashes subdashes;
-
- item = PySequence_GetItem(obj, i);
- if (item == NULL) {
- return 0;
- }
-
- if (!convert_dashes(item, &subdashes)) {
- Py_DECREF(item);
- return 0;
- }
- Py_DECREF(item);
-
- dashes->push_back(subdashes);
- }
-
- return 1;
-}
-
-int convert_trans_affine(PyObject *obj, void *transp)
-{
- agg::trans_affine *trans = (agg::trans_affine *)transp;
-
- /** If None assume identity transform. */
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- try
- {
- numpy::array_view<const double, 2> matrix(obj);
-
- if (matrix.dim(0) == 3 && matrix.dim(1) == 3) {
- trans->sx = matrix(0, 0);
- trans->shx = matrix(0, 1);
- trans->tx = matrix(0, 2);
-
- trans->shy = matrix(1, 0);
- trans->sy = matrix(1, 1);
- trans->ty = matrix(1, 2);
-
- return 1;
- }
- }
- catch (py::exception &)
- {
- return 0;
- }
-
- PyErr_SetString(PyExc_ValueError, "Invalid affine transformation matrix");
- return 0;
-}
-
-int convert_path(PyObject *obj, void *pathp)
-{
- py::PathIterator *path = (py::PathIterator *)pathp;
-
- PyObject *vertices_obj = NULL;
- PyObject *codes_obj = NULL;
- PyObject *should_simplify_obj = NULL;
- PyObject *simplify_threshold_obj = NULL;
- bool should_simplify;
- double simplify_threshold;
-
- int status = 0;
-
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- vertices_obj = PyObject_GetAttrString(obj, "vertices");
- if (vertices_obj == NULL) {
- goto exit;
- }
-
- codes_obj = PyObject_GetAttrString(obj, "codes");
- if (codes_obj == NULL) {
- goto exit;
- }
-
- should_simplify_obj = PyObject_GetAttrString(obj, "should_simplify");
- if (should_simplify_obj == NULL) {
- goto exit;
- }
- should_simplify = PyObject_IsTrue(should_simplify_obj);
-
- simplify_threshold_obj = PyObject_GetAttrString(obj, "simplify_threshold");
- if (simplify_threshold_obj == NULL) {
- goto exit;
- }
- simplify_threshold = PyFloat_AsDouble(simplify_threshold_obj);
- if (PyErr_Occurred()) {
- goto exit;
- }
-
- if (!path->set(vertices_obj, codes_obj, should_simplify, simplify_threshold)) {
- goto exit;
- }
-
- status = 1;
-
-exit:
- Py_XDECREF(vertices_obj);
- Py_XDECREF(codes_obj);
- Py_XDECREF(should_simplify_obj);
- Py_XDECREF(simplify_threshold_obj);
-
- return status;
-}
-
-int convert_clippath(PyObject *clippath_tuple, void *clippathp)
-{
- ClipPath *clippath = (ClipPath *)clippathp;
- py::PathIterator path;
- agg::trans_affine trans;
-
- if (clippath_tuple != NULL && clippath_tuple != Py_None) {
- if (!PyArg_ParseTuple(clippath_tuple,
- "O&O&:clippath",
- &convert_path,
- &clippath->path,
- &convert_trans_affine,
- &clippath->trans)) {
- return 0;
- }
- }
-
- return 1;
-}
-
-int convert_snap(PyObject *obj, void *snapp)
-{
- e_snap_mode *snap = (e_snap_mode *)snapp;
-
- if (obj == NULL || obj == Py_None) {
- *snap = SNAP_AUTO;
- } else if (PyObject_IsTrue(obj)) {
- *snap = SNAP_TRUE;
- } else {
- *snap = SNAP_FALSE;
- }
-
- return 1;
-}
-
-int convert_sketch_params(PyObject *obj, void *sketchp)
-{
- SketchParams *sketch = (SketchParams *)sketchp;
-
- if (obj == NULL || obj == Py_None) {
- sketch->scale = 0.0;
- } else if (!PyArg_ParseTuple(obj,
- "ddd:sketch_params",
- &sketch->scale,
- &sketch->length,
- &sketch->randomness)) {
- return 0;
- }
-
- return 1;
-}
-
-int convert_gcagg(PyObject *pygc, void *gcp)
-{
- GCAgg *gc = (GCAgg *)gcp;
-
- if (!(convert_from_attr(pygc, "_linewidth", &convert_double, &gc->linewidth) &&
- convert_from_attr(pygc, "_alpha", &convert_double, &gc->alpha) &&
- convert_from_attr(pygc, "_forced_alpha", &convert_bool, &gc->forced_alpha) &&
- convert_from_attr(pygc, "_rgb", &convert_rgba, &gc->color) &&
- convert_from_attr(pygc, "_antialiased", &convert_bool, &gc->isaa) &&
- convert_from_attr(pygc, "_capstyle", &convert_cap, &gc->cap) &&
- convert_from_attr(pygc, "_joinstyle", &convert_join, &gc->join) &&
- convert_from_method(pygc, "get_dashes", &convert_dashes, &gc->dashes) &&
- convert_from_attr(pygc, "_cliprect", &convert_rect, &gc->cliprect) &&
- convert_from_method(pygc, "get_clip_path", &convert_clippath, &gc->clippath) &&
- convert_from_method(pygc, "get_snap", &convert_snap, &gc->snap_mode) &&
- convert_from_method(pygc, "get_hatch_path", &convert_path, &gc->hatchpath) &&
- convert_from_method(pygc, "get_hatch_color", &convert_rgba, &gc->hatch_color) &&
- convert_from_method(pygc, "get_hatch_linewidth", &convert_double, &gc->hatch_linewidth) &&
- convert_from_method(pygc, "get_sketch_params", &convert_sketch_params, &gc->sketch))) {
- return 0;
- }
-
- return 1;
-}
-
-int convert_offset_position(PyObject *obj, void *offsetp)
-{
- e_offset_position *offset = (e_offset_position *)offsetp;
- const char *names[] = {"data", NULL};
- int values[] = {OFFSET_POSITION_DATA};
- int result = (int)OFFSET_POSITION_FIGURE;
-
- if (!convert_string_enum(obj, "offset_position", names, values, &result)) {
- PyErr_Clear();
- }
-
- *offset = (e_offset_position)result;
-
- return 1;
-}
-
-int convert_face(PyObject *color, GCAgg &gc, agg::rgba *rgba)
-{
- if (!convert_rgba(color, rgba)) {
- return 0;
- }
-
- if (color != NULL && color != Py_None) {
- if (gc.forced_alpha || PySequence_Size(color) == 3) {
- rgba->a = gc.alpha;
- }
- }
-
- return 1;
-}
-
-int convert_points(PyObject *obj, void *pointsp)
-{
- numpy::array_view<double, 2> *points = (numpy::array_view<double, 2> *)pointsp;
-
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- points->set(obj);
-
- if (points->size() == 0) {
- return 1;
- }
-
- if (points->dim(1) != 2) {
- PyErr_Format(PyExc_ValueError,
- "Points must be Nx2 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT,
- points->dim(0), points->dim(1));
- return 0;
- }
-
- return 1;
-}
-
-int convert_transforms(PyObject *obj, void *transp)
-{
- numpy::array_view<double, 3> *trans = (numpy::array_view<double, 3> *)transp;
-
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- trans->set(obj);
-
- if (trans->size() == 0) {
- return 1;
- }
-
- if (trans->dim(1) != 3 || trans->dim(2) != 3) {
- PyErr_Format(PyExc_ValueError,
- "Transforms must be Nx3x3 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT "x%" NPY_INTP_FMT,
- trans->dim(0), trans->dim(1), trans->dim(2));
- return 0;
- }
-
- return 1;
-}
-
-int convert_bboxes(PyObject *obj, void *bboxp)
-{
- numpy::array_view<double, 3> *bbox = (numpy::array_view<double, 3> *)bboxp;
-
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- bbox->set(obj);
-
- if (bbox->size() == 0) {
- return 1;
- }
-
- if (bbox->dim(1) != 2 || bbox->dim(2) != 2) {
- PyErr_Format(PyExc_ValueError,
- "Bbox array must be Nx2x2 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT "x%" NPY_INTP_FMT,
- bbox->dim(0), bbox->dim(1), bbox->dim(2));
- return 0;
- }
-
- return 1;
-}
-
-int convert_colors(PyObject *obj, void *colorsp)
-{
- numpy::array_view<double, 2> *colors = (numpy::array_view<double, 2> *)colorsp;
-
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- colors->set(obj);
-
- if (colors->size() == 0) {
- return 1;
- }
-
- if (colors->dim(1) != 4) {
- PyErr_Format(PyExc_ValueError,
- "Colors array must be Nx4 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT,
- colors->dim(0), colors->dim(1));
- return 0;
- }
-
- return 1;
-}
-}
diff --git a/contrib/python/matplotlib/py2/src/py_converters.h b/contrib/python/matplotlib/py2/src/py_converters.h
deleted file mode 100644
index 02d84affe8..0000000000
--- a/contrib/python/matplotlib/py2/src/py_converters.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef __PY_CONVERTERS_H__
-#define __PY_CONVERTERS_H__
-
-/***************************************************************************
- * This module contains a number of conversion functions from Python types
- * to C++ types. Most of them meet the Python "converter" signature:
- *
- * typedef int (*converter)(PyObject *, void *);
- *
- * and thus can be passed as conversion functions to PyArg_ParseTuple
- * and friends.
- */
-
-#include <Python.h>
-#include "numpy_cpp.h"
-#include "_backend_agg_basic_types.h"
-
-extern "C" {
-typedef int (*converter)(PyObject *, void *);
-
-int convert_from_attr(PyObject *obj, const char *name, converter func, void *p);
-int convert_from_method(PyObject *obj, const char *name, converter func, void *p);
-
-int convert_double(PyObject *obj, void *p);
-int convert_bool(PyObject *obj, void *p);
-int convert_cap(PyObject *capobj, void *capp);
-int convert_join(PyObject *joinobj, void *joinp);
-int convert_rect(PyObject *rectobj, void *rectp);
-int convert_rgba(PyObject *rgbaocj, void *rgbap);
-int convert_dashes(PyObject *dashobj, void *gcp);
-int convert_dashes_vector(PyObject *obj, void *dashesp);
-int convert_trans_affine(PyObject *obj, void *transp);
-int convert_path(PyObject *obj, void *pathp);
-int convert_clippath(PyObject *clippath_tuple, void *clippathp);
-int convert_snap(PyObject *obj, void *snapp);
-int convert_offset_position(PyObject *obj, void *offsetp);
-int convert_sketch_params(PyObject *obj, void *sketchp);
-int convert_gcagg(PyObject *pygc, void *gcp);
-int convert_points(PyObject *pygc, void *pointsp);
-int convert_transforms(PyObject *pygc, void *transp);
-int convert_bboxes(PyObject *pygc, void *bboxp);
-int convert_colors(PyObject *pygc, void *colorsp);
-
-int convert_face(PyObject *color, GCAgg &gc, agg::rgba *rgba);
-}
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/py_exceptions.h b/contrib/python/matplotlib/py2/src/py_exceptions.h
deleted file mode 100644
index 1ee2d51903..0000000000
--- a/contrib/python/matplotlib/py2/src/py_exceptions.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef __PY_EXCEPTIONS_H__
-#define __PY_EXCEPTIONS_H__
-
-#include <exception>
-#include <stdexcept>
-
-namespace py
-{
-class exception : public std::exception
-{
- public:
- const char *what() const throw()
- {
- return "python error has been set";
- }
-};
-}
-
-#define CALL_CPP_FULL(name, a, cleanup, errorcode) \
- try \
- { \
- a; \
- } \
- catch (const py::exception &) \
- { \
- { \
- cleanup; \
- } \
- return (errorcode); \
- } \
- catch (const std::bad_alloc &) \
- { \
- PyErr_Format(PyExc_MemoryError, "In %s: Out of memory", (name)); \
- { \
- cleanup; \
- } \
- return (errorcode); \
- } \
- catch (const std::overflow_error &e) \
- { \
- PyErr_Format(PyExc_OverflowError, "In %s: %s", (name), e.what()); \
- { \
- cleanup; \
- } \
- return (errorcode); \
- } \
- catch (const std::runtime_error &e) \
- { \
- PyErr_Format(PyExc_RuntimeError, "In %s: %s", (name), e.what()); \
- { \
- cleanup; \
- } \
- return (errorcode); \
- } \
- catch (...) \
- { \
- PyErr_Format(PyExc_RuntimeError, "Unknown exception in %s", (name)); \
- { \
- cleanup; \
- } \
- return (errorcode); \
- }
-
-#define CALL_CPP_CLEANUP(name, a, cleanup) CALL_CPP_FULL(name, a, cleanup, NULL)
-
-#define CALL_CPP(name, a) CALL_CPP_FULL(name, a, , NULL)
-
-#define CALL_CPP_INIT(name, a) CALL_CPP_FULL(name, a, , -1)
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/qhull_wrap.c b/contrib/python/matplotlib/py2/src/qhull_wrap.c
deleted file mode 100644
index 836a16c555..0000000000
--- a/contrib/python/matplotlib/py2/src/qhull_wrap.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Wrapper module for libqhull, providing Delaunay triangulation.
- *
- * This module's methods should not be accessed directly. To obtain a Delaunay
- * triangulation, construct an instance of the matplotlib.tri.Triangulation
- * class without specifying a triangles array.
- */
-#define PY_SSIZE_T_CLEAN
-#include "Python.h"
-#include "numpy/noprefix.h"
-#include "qhull_ra.h"
-#include <stdio.h>
-
-
-#if PY_MAJOR_VERSION >= 3
-#define PY3K 1
-#else
-#define PY3K 0
-#endif
-
-#ifndef MPL_DEVNULL
-#error "MPL_DEVNULL must be defined as the OS-equivalent of /dev/null"
-#endif
-
-#define STRINGIFY(x) STR(x)
-#define STR(x) #x
-
-static qhT qhData;
-static qhT* qh = &qhData;
-
-static const char* qhull_error_msg[6] = {
- "", /* 0 = qh_ERRnone */
- "input inconsistency", /* 1 = qh_ERRinput */
- "singular input data", /* 2 = qh_ERRsingular */
- "precision error", /* 3 = qh_ERRprec */
- "insufficient memory", /* 4 = qh_ERRmem */
- "internal error"}; /* 5 = qh_ERRqhull */
-
-
-/* Return the indices of the 3 vertices that comprise the specified facet (i.e.
- * triangle). */
-static void
-get_facet_vertices(const facetT* facet, int indices[3])
-{
- vertexT *vertex, **vertexp;
- FOREACHvertex_(facet->vertices)
- *indices++ = qh_pointid(qh, vertex->point);
-}
-
-/* Return the indices of the 3 triangles that are neighbors of the specified
- * facet (triangle). */
-static void
-get_facet_neighbours(const facetT* facet, const int* tri_indices,
- int indices[3])
-{
- facetT *neighbor, **neighborp;
- FOREACHneighbor_(facet)
- *indices++ = (neighbor->upperdelaunay ? -1 : tri_indices[neighbor->id]);
-}
-
-/* Return 1 if the specified points arrays contain at least 3 unique points,
- * or 0 otherwise. */
-static int
-at_least_3_unique_points(int npoints, const double* x, const double* y)
-{
- int i;
- const int unique1 = 0; /* First unique point has index 0. */
- int unique2 = 0; /* Second unique point index is 0 until set. */
-
- if (npoints < 3)
- return 0;
-
- for (i = 1; i < npoints; ++i) {
- if (unique2 == 0) {
- /* Looking for second unique point. */
- if (x[i] != x[unique1] || y[i] != y[unique1])
- unique2 = i;
- }
- else {
- /* Looking for third unique point. */
- if ( (x[i] != x[unique1] || y[i] != y[unique1]) &&
- (x[i] != x[unique2] || y[i] != y[unique2]) ) {
- /* 3 unique points found, with indices 0, unique2 and i. */
- return 1;
- }
- }
- }
-
- /* Run out of points before 3 unique points found. */
- return 0;
-}
-
-/* Delaunay implementation methyod. If hide_qhull_errors is 1 then qhull error
- * messages are discarded; if it is 0 then they are written to stderr. */
-static PyObject*
-delaunay_impl(int npoints, const double* x, const double* y,
- int hide_qhull_errors)
-{
- coordT* points = NULL;
- facetT* facet;
- int i, ntri, max_facet_id;
- FILE* error_file = NULL; /* qhull expects a FILE* to write errors to. */
- int exitcode; /* Value returned from qh_new_qhull(). */
- int* tri_indices = NULL; /* Maps qhull facet id to triangle index. */
- int indices[3];
- int curlong, totlong; /* Memory remaining after qh_memfreeshort. */
- PyObject* tuple; /* Return tuple (triangles, neighbors). */
- const int ndim = 2;
- npy_intp dims[2];
- PyArrayObject* triangles = NULL;
- PyArrayObject* neighbors = NULL;
- int* triangles_ptr;
- int* neighbors_ptr;
- double x_mean = 0.0;
- double y_mean = 0.0;
-
- QHULL_LIB_CHECK
-
- /* Allocate points. */
- points = (coordT*)malloc(npoints*ndim*sizeof(coordT));
- if (points == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Could not allocate points array in qhull.delaunay");
- goto error_before_qhull;
- }
-
- /* Determine mean x, y coordinates. */
- for (i = 0; i < npoints; ++i) {
- x_mean += x[i];
- y_mean += y[i];
- }
- x_mean /= npoints;
- y_mean /= npoints;
-
- /* Prepare points array to pass to qhull. */
- for (i = 0; i < npoints; ++i) {
- points[2*i ] = x[i] - x_mean;
- points[2*i+1] = y[i] - y_mean;
- }
-
- /* qhull expects a FILE* to write errors to. */
- if (hide_qhull_errors) {
- /* qhull errors are ignored by writing to OS-equivalent of /dev/null.
- * Rather than have OS-specific code here, instead it is determined by
- * setupext.py and passed in via the macro MPL_DEVNULL. */
- error_file = fopen(STRINGIFY(MPL_DEVNULL), "w");
- if (error_file == NULL) {
- PyErr_SetString(PyExc_RuntimeError,
- "Could not open devnull in qhull.delaunay");
- goto error_before_qhull;
- }
- }
- else {
- /* qhull errors written to stderr. */
- error_file = stderr;
- }
-
- /* Perform Delaunay triangulation. */
- exitcode = qh_new_qhull(qh, ndim, npoints, points, False,
- "qhull d Qt Qbb Qc Qz", NULL, error_file);
- if (exitcode != qh_ERRnone) {
- PyErr_Format(PyExc_RuntimeError,
- "Error in qhull Delaunay triangulation calculation: %s (exitcode=%d)%s",
- qhull_error_msg[exitcode], exitcode,
- hide_qhull_errors ? "; use python verbose option (-v) to see original qhull error." : "");
- goto error;
- }
-
- /* Split facets so that they only have 3 points each. */
- qh_triangulate(qh);
-
- /* Determine ntri and max_facet_id.
- Note that libqhull uses macros to iterate through collections. */
- ntri = 0;
- FORALLfacets {
- if (!facet->upperdelaunay)
- ++ntri;
- }
-
- max_facet_id = qh->facet_id - 1;
-
- /* Create array to map facet id to triangle index. */
- tri_indices = (int*)malloc((max_facet_id+1)*sizeof(int));
- if (tri_indices == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Could not allocate triangle map in qhull.delaunay");
- goto error;
- }
-
- /* Allocate python arrays to return. */
- dims[0] = ntri;
- dims[1] = 3;
- triangles = (PyArrayObject*)PyArray_SimpleNew(ndim, dims, NPY_INT);
- if (triangles == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Could not allocate triangles array in qhull.delaunay");
- goto error;
- }
-
- neighbors = (PyArrayObject*)PyArray_SimpleNew(ndim, dims, NPY_INT);
- if (neighbors == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Could not allocate neighbors array in qhull.delaunay");
- goto error;
- }
-
- triangles_ptr = (int*)PyArray_DATA(triangles);
- neighbors_ptr = (int*)PyArray_DATA(neighbors);
-
- /* Determine triangles array and set tri_indices array. */
- i = 0;
- FORALLfacets {
- if (!facet->upperdelaunay) {
- tri_indices[facet->id] = i++;
- get_facet_vertices(facet, indices);
- *triangles_ptr++ = (facet->toporient ? indices[0] : indices[2]);
- *triangles_ptr++ = indices[1];
- *triangles_ptr++ = (facet->toporient ? indices[2] : indices[0]);
- }
- else
- tri_indices[facet->id] = -1;
- }
-
- /* Determine neighbors array. */
- FORALLfacets {
- if (!facet->upperdelaunay) {
- get_facet_neighbours(facet, tri_indices, indices);
- *neighbors_ptr++ = (facet->toporient ? indices[2] : indices[0]);
- *neighbors_ptr++ = (facet->toporient ? indices[0] : indices[2]);
- *neighbors_ptr++ = indices[1];
- }
- }
-
- /* Clean up. */
- qh_freeqhull(qh, !qh_ALL);
- qh_memfreeshort(qh, &curlong, &totlong);
- if (curlong || totlong)
- PyErr_WarnEx(PyExc_RuntimeWarning,
- "Qhull could not free all allocated memory", 1);
- if (hide_qhull_errors)
- fclose(error_file);
- free(tri_indices);
- free(points);
-
- tuple = PyTuple_New(2);
- PyTuple_SetItem(tuple, 0, (PyObject*)triangles);
- PyTuple_SetItem(tuple, 1, (PyObject*)neighbors);
- return tuple;
-
-error:
- /* Clean up. */
- Py_XDECREF(triangles);
- Py_XDECREF(neighbors);
- qh_freeqhull(qh, !qh_ALL);
- qh_memfreeshort(qh, &curlong, &totlong);
- /* Don't bother checking curlong and totlong as raising error anyway. */
- if (hide_qhull_errors)
- fclose(error_file);
- free(tri_indices);
-
-error_before_qhull:
- free(points);
-
- return NULL;
-}
-
-/* Process python arguments and call Delaunay implementation method. */
-static PyObject*
-delaunay(PyObject *self, PyObject *args)
-{
- PyObject* xarg;
- PyObject* yarg;
- PyArrayObject* xarray;
- PyArrayObject* yarray;
- PyObject* ret;
- int npoints;
- const double* x;
- const double* y;
-
- if (!PyArg_ParseTuple(args, "OO", &xarg, &yarg)) {
- PyErr_SetString(PyExc_ValueError, "expecting x and y arrays");
- return NULL;
- }
-
- xarray = (PyArrayObject*)PyArray_ContiguousFromObject(xarg, NPY_DOUBLE,
- 1, 1);
- yarray = (PyArrayObject*)PyArray_ContiguousFromObject(yarg, NPY_DOUBLE,
- 1, 1);
- if (xarray == 0 || yarray == 0 ||
- PyArray_DIM(xarray,0) != PyArray_DIM(yarray, 0)) {
- Py_XDECREF(xarray);
- Py_XDECREF(yarray);
- PyErr_SetString(PyExc_ValueError,
- "x and y must be 1D arrays of the same length");
- return NULL;
- }
-
- npoints = PyArray_DIM(xarray, 0);
-
- if (npoints < 3) {
- Py_XDECREF(xarray);
- Py_XDECREF(yarray);
- PyErr_SetString(PyExc_ValueError,
- "x and y arrays must have a length of at least 3");
- return NULL;
- }
-
- x = (const double*)PyArray_DATA(xarray);
- y = (const double*)PyArray_DATA(yarray);
-
- if (!at_least_3_unique_points(npoints, x, y)) {
- Py_XDECREF(xarray);
- Py_XDECREF(yarray);
- PyErr_SetString(PyExc_ValueError,
- "x and y arrays must consist of at least 3 unique points");
- return NULL;
- }
-
- ret = delaunay_impl(npoints, x, y, Py_VerboseFlag == 0);
-
- Py_XDECREF(xarray);
- Py_XDECREF(yarray);
- return ret;
-}
-
-/* Return qhull version string for assistance in debugging. */
-static PyObject*
-version(void)
-{
- return PyBytes_FromString(qh_version);
-}
-
-static PyMethodDef qhull_methods[] = {
- {"delaunay", (PyCFunction)delaunay, METH_VARARGS, ""},
- {"version", (PyCFunction)version, METH_NOARGS, ""},
- {NULL, NULL, 0, NULL}
-};
-
-#if PY3K
-static struct PyModuleDef qhull_module = {
- PyModuleDef_HEAD_INIT,
- "qhull",
- "Computing Delaunay triangulations.\n",
- -1,
- qhull_methods,
- NULL, NULL, NULL, NULL
-};
-
-#define ERROR_RETURN return NULL
-
-PyMODINIT_FUNC
-PyInit__qhull(void)
-#else
-#define ERROR_RETURN return
-
-PyMODINIT_FUNC
-init_qhull(void)
-#endif
-{
- PyObject* m;
-
- #if PY3K
- m = PyModule_Create(&qhull_module);
- #else
- m = Py_InitModule3("_qhull", qhull_methods,
- "Computing Delaunay triangulations.\n");
- #endif
-
- if (m == NULL) {
- ERROR_RETURN;
- }
-
- import_array();
-
- #if PY3K
- return m;
- #endif
-}
diff --git a/contrib/python/matplotlib/py2/src/ya.make b/contrib/python/matplotlib/py2/src/ya.make
deleted file mode 100644
index 486bc04e49..0000000000
--- a/contrib/python/matplotlib/py2/src/ya.make
+++ /dev/null
@@ -1,68 +0,0 @@
-PY2_LIBRARY()
-
-VERSION(2.2.5)
-
-LICENSE(PSF-2.0)
-
-NO_COMPILER_WARNINGS()
-
-PEERDIR(
- ADDINCL contrib/libs/freetype
- ADDINCL contrib/libs/libpng
- ADDINCL contrib/python/numpy
- contrib/libs/qhull
- contrib/python/matplotlib/py2/extern/agg24-svn
- contrib/python/matplotlib/py2/extern/ttconv
-)
-
-ADDINCL(
- contrib/libs/qhull/libqhull_r
- contrib/python/matplotlib/py2
- contrib/python/matplotlib/py2/extern
- contrib/python/matplotlib/py2/extern/agg24-svn/include
-)
-
-CFLAGS(
- -D_MULTIARRAYMODULE
- -DFREETYPE_BUILD_TYPE=local
- -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION
- -DMPL_DEVNULL=/dev/null
-)
-
-IF (OS_WINDOWS)
- LDFLAGS(
- Psapi.lib
- )
-ENDIF()
-
-PY_REGISTER(
- matplotlib._contour
- matplotlib._image # peerdir agg24-svn
- matplotlib._path # peerdir agg24-svn
- matplotlib._png
- matplotlib._qhull # peerdir libqhull
- matplotlib.backends._backend_agg # peerdir agg24-svn
- matplotlib.backends._tkagg
- matplotlib.ft2font
- matplotlib.ttconv # peerdir ttconv
-)
-
-SRCS(
- _backend_agg.cpp
- _backend_agg_wrapper.cpp
- _contour.cpp
- _contour_wrapper.cpp
- _image.cpp
- _image_wrapper.cpp
- _path_wrapper.cpp
- _png.cpp
- _tkagg.cpp
- _ttconv.cpp
- ft2font.cpp
- ft2font_wrapper.cpp
- mplutils.cpp
- py_converters.cpp
- qhull_wrap.c
-)
-
-END()
diff --git a/contrib/python/matplotlib/py2/ya.make b/contrib/python/matplotlib/py2/ya.make
deleted file mode 100644
index 1d5ee4878b..0000000000
--- a/contrib/python/matplotlib/py2/ya.make
+++ /dev/null
@@ -1,243 +0,0 @@
-PY2_LIBRARY()
-
-LICENSE(PSF-2.0)
-
-VERSION(2.2.5)
-
-PEERDIR(
- contrib/deprecated/python/backports.functools-lru-cache
- contrib/deprecated/python/functools32
- contrib/python/mock
- contrib/deprecated/python/subprocess32
- contrib/python/cycler
- contrib/python/python-dateutil
- contrib/python/kiwisolver
- contrib/python/matplotlib/py2/src
- contrib/python/matplotlib/py2/matplotlib/tri
- contrib/python/numpy
- contrib/python/pyparsing
- contrib/python/pytz
- contrib/python/six
-)
-
-NO_CHECK_IMPORTS(
- matplotlib.backends.*
- matplotlib.sphinxext.*
- matplotlib.testing.*
- mpl_toolkits.*
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_LINT()
-
-FROM_SANDBOX(FILE 1119073729 OUT_NOAUTO mpl-data.tar.gz)
-
-RESOURCE(
- mpl-data.tar.gz /mpl-data/mpl-data.tar.gz
-)
-
-PY_SRCS(
- TOP_LEVEL
- matplotlib/__init__.py
- matplotlib/_animation_data.py
- matplotlib/_cm.py
- matplotlib/_cm_listed.py
- matplotlib/_color_data.py
- matplotlib/_constrained_layout.py
- matplotlib/_layoutbox.py
- matplotlib/_mathtext_data.py
- matplotlib/_pylab_helpers.py
- matplotlib/_version.py
- matplotlib/afm.py
- matplotlib/animation.py
- matplotlib/artist.py
- matplotlib/axes/__init__.py
- matplotlib/axes/_axes.py
- matplotlib/axes/_base.py
- matplotlib/axes/_subplots.py
- matplotlib/axis.py
- matplotlib/backend_bases.py
- matplotlib/backend_managers.py
- matplotlib/backend_tools.py
- matplotlib/backends/__init__.py
- matplotlib/backends/_backend_tk.py
- matplotlib/backends/_gtk3_compat.py
- matplotlib/backends/backend_agg.py
- matplotlib/backends/backend_cairo.py
- matplotlib/backends/backend_gdk.py
- matplotlib/backends/backend_gtk.py
- matplotlib/backends/backend_gtk3.py
- matplotlib/backends/backend_gtk3agg.py
- matplotlib/backends/backend_gtk3cairo.py
- matplotlib/backends/backend_gtkagg.py
- matplotlib/backends/backend_gtkcairo.py
- matplotlib/backends/backend_macosx.py
- matplotlib/backends/backend_mixed.py
- matplotlib/backends/backend_nbagg.py
- matplotlib/backends/backend_pdf.py
- matplotlib/backends/backend_pgf.py
- matplotlib/backends/backend_ps.py
- matplotlib/backends/backend_qt4.py
- matplotlib/backends/backend_qt4agg.py
- matplotlib/backends/backend_qt4cairo.py
- matplotlib/backends/backend_qt5.py
- matplotlib/backends/backend_qt5agg.py
- matplotlib/backends/backend_qt5cairo.py
- matplotlib/backends/backend_svg.py
- matplotlib/backends/backend_template.py
- matplotlib/backends/backend_tkagg.py
- matplotlib/backends/backend_tkcairo.py
- matplotlib/backends/backend_webagg.py
- matplotlib/backends/backend_webagg_core.py
- matplotlib/backends/backend_wx.py
- matplotlib/backends/backend_wxagg.py
- matplotlib/backends/backend_wxcairo.py
- matplotlib/backends/qt_compat.py
- matplotlib/backends/qt_editor/__init__.py
- matplotlib/backends/qt_editor/figureoptions.py
- matplotlib/backends/qt_editor/formlayout.py
- matplotlib/backends/qt_editor/formsubplottool.py
- matplotlib/backends/tkagg.py
- matplotlib/backends/windowing.py
- matplotlib/backends/wx_compat.py
- matplotlib/bezier.py
- matplotlib/blocking_input.py
- matplotlib/category.py
- matplotlib/cbook/__init__.py
- matplotlib/cbook/_backports.py
- matplotlib/cbook/deprecation.py
- matplotlib/cm.py
- matplotlib/collections.py
- matplotlib/colorbar.py
- matplotlib/colors.py
- matplotlib/compat/__init__.py
- matplotlib/compat/subprocess.py
- matplotlib/container.py
- matplotlib/contour.py
- matplotlib/dates.py
- matplotlib/docstring.py
- matplotlib/dviread.py
- matplotlib/figure.py
- matplotlib/font_manager.py
- matplotlib/fontconfig_pattern.py
- matplotlib/gridspec.py
- matplotlib/hatch.py
- matplotlib/image.py
- matplotlib/legend.py
- matplotlib/legend_handler.py
- matplotlib/lines.py
- matplotlib/markers.py
- matplotlib/mathtext.py
- matplotlib/mlab.py
- matplotlib/offsetbox.py
- matplotlib/patches.py
- matplotlib/path.py
- matplotlib/patheffects.py
- matplotlib/projections/__init__.py
- matplotlib/projections/geo.py
- matplotlib/projections/polar.py
- matplotlib/pylab.py
- matplotlib/pyplot.py
- matplotlib/quiver.py
- matplotlib/rcsetup.py
- matplotlib/sankey.py
- matplotlib/scale.py
- matplotlib/sphinxext/__init__.py
- matplotlib/sphinxext/mathmpl.py
- matplotlib/sphinxext/only_directives.py
- matplotlib/sphinxext/plot_directive.py
- matplotlib/spines.py
- matplotlib/stackplot.py
- matplotlib/streamplot.py
- matplotlib/style/__init__.py
- matplotlib/style/core.py
- matplotlib/table.py
- matplotlib/testing/__init__.py
- matplotlib/testing/_nose/__init__.py
- matplotlib/testing/_nose/decorators.py
- matplotlib/testing/_nose/exceptions.py
- matplotlib/testing/_nose/plugins/__init__.py
- matplotlib/testing/_nose/plugins/knownfailure.py
- matplotlib/testing/_nose/plugins/performgc.py
- matplotlib/testing/compare.py
- matplotlib/testing/conftest.py
- matplotlib/testing/decorators.py
- matplotlib/testing/determinism.py
- matplotlib/testing/disable_internet.py
- matplotlib/testing/exceptions.py
- matplotlib/testing/jpl_units/Duration.py
- matplotlib/testing/jpl_units/Epoch.py
- matplotlib/testing/jpl_units/EpochConverter.py
- matplotlib/testing/jpl_units/StrConverter.py
- matplotlib/testing/jpl_units/UnitDbl.py
- matplotlib/testing/jpl_units/UnitDblConverter.py
- matplotlib/testing/jpl_units/UnitDblFormatter.py
- matplotlib/testing/jpl_units/__init__.py
- matplotlib/testing/noseclasses.py
- matplotlib/texmanager.py
- matplotlib/text.py
- matplotlib/textpath.py
- matplotlib/ticker.py
- matplotlib/tight_bbox.py
- matplotlib/tight_layout.py
- matplotlib/transforms.py
- matplotlib/type1font.py
- matplotlib/units.py
- matplotlib/widgets.py
- mpl_toolkits/__init__.py
- mpl_toolkits/axes_grid/__init__.py
- mpl_toolkits/axes_grid/anchored_artists.py
- mpl_toolkits/axes_grid/angle_helper.py
- mpl_toolkits/axes_grid/axes_divider.py
- mpl_toolkits/axes_grid/axes_grid.py
- mpl_toolkits/axes_grid/axes_rgb.py
- mpl_toolkits/axes_grid/axes_size.py
- mpl_toolkits/axes_grid/axis_artist.py
- mpl_toolkits/axes_grid/axisline_style.py
- mpl_toolkits/axes_grid/axislines.py
- mpl_toolkits/axes_grid/clip_path.py
- mpl_toolkits/axes_grid/colorbar.py
- mpl_toolkits/axes_grid/floating_axes.py
- mpl_toolkits/axes_grid/grid_finder.py
- mpl_toolkits/axes_grid/grid_helper_curvelinear.py
- mpl_toolkits/axes_grid/inset_locator.py
- mpl_toolkits/axes_grid/parasite_axes.py
- mpl_toolkits/axes_grid1/__init__.py
- mpl_toolkits/axes_grid1/anchored_artists.py
- mpl_toolkits/axes_grid1/axes_divider.py
- mpl_toolkits/axes_grid1/axes_grid.py
- mpl_toolkits/axes_grid1/axes_rgb.py
- mpl_toolkits/axes_grid1/axes_size.py
- mpl_toolkits/axes_grid1/colorbar.py
- mpl_toolkits/axes_grid1/inset_locator.py
- mpl_toolkits/axes_grid1/mpl_axes.py
- mpl_toolkits/axes_grid1/parasite_axes.py
- mpl_toolkits/axisartist/__init__.py
- mpl_toolkits/axisartist/angle_helper.py
- mpl_toolkits/axisartist/axes_divider.py
- mpl_toolkits/axisartist/axes_grid.py
- mpl_toolkits/axisartist/axes_rgb.py
- mpl_toolkits/axisartist/axis_artist.py
- mpl_toolkits/axisartist/axisline_style.py
- mpl_toolkits/axisartist/axislines.py
- mpl_toolkits/axisartist/clip_path.py
- mpl_toolkits/axisartist/floating_axes.py
- mpl_toolkits/axisartist/grid_finder.py
- mpl_toolkits/axisartist/grid_helper_curvelinear.py
- mpl_toolkits/axisartist/parasite_axes.py
- mpl_toolkits/mplot3d/__init__.py
- mpl_toolkits/mplot3d/art3d.py
- mpl_toolkits/mplot3d/axes3d.py
- mpl_toolkits/mplot3d/axis3d.py
- mpl_toolkits/mplot3d/proj3d.py
- pylab.py
-)
-
-END()
-
-RECURSE(
- extern
- matplotlib/tri
- src
-)
diff --git a/contrib/python/matplotlib/py3/.dist-info/METADATA b/contrib/python/matplotlib/py3/.dist-info/METADATA
deleted file mode 100644
index cdd2df573f..0000000000
--- a/contrib/python/matplotlib/py3/.dist-info/METADATA
+++ /dev/null
@@ -1,125 +0,0 @@
-Metadata-Version: 2.1
-Name: matplotlib
-Version: 3.8.2
-Summary: Python plotting package
-Home-page: https://matplotlib.org
-Download-URL: https://matplotlib.org/stable/users/installing/index.html
-Author: John D. Hunter, Michael Droettboom
-Author-email: matplotlib-users@python.org
-License: PSF
-Project-URL: Documentation, https://matplotlib.org
-Project-URL: Source Code, https://github.com/matplotlib/matplotlib
-Project-URL: Bug Tracker, https://github.com/matplotlib/matplotlib/issues
-Project-URL: Forum, https://discourse.matplotlib.org/
-Project-URL: Donate, https://numfocus.org/donate-to-matplotlib
-Platform: any
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Framework :: Matplotlib
-Classifier: Intended Audience :: Science/Research
-Classifier: Intended Audience :: Education
-Classifier: License :: OSI Approved :: Python Software Foundation License
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.9
-Classifier: Programming Language :: Python :: 3.10
-Classifier: Programming Language :: Python :: 3.11
-Classifier: Programming Language :: Python :: 3.12
-Classifier: Topic :: Scientific/Engineering :: Visualization
-Requires-Python: >=3.9
-Description-Content-Type: text/markdown
-License-File: LICENSE/LICENSE
-License-File: LICENSE/LICENSE_AMSFONTS
-License-File: LICENSE/LICENSE_BAKOMA
-License-File: LICENSE/LICENSE_CARLOGO
-License-File: LICENSE/LICENSE_COLORBREWER
-License-File: LICENSE/LICENSE_COURIERTEN
-License-File: LICENSE/LICENSE_JSXTOOLS_RESIZE_OBSERVER
-License-File: LICENSE/LICENSE_QHULL
-License-File: LICENSE/LICENSE_QT4_EDITOR
-License-File: LICENSE/LICENSE_SOLARIZED
-License-File: LICENSE/LICENSE_STIX
-License-File: LICENSE/LICENSE_YORICK
-Requires-Dist: contourpy >=1.0.1
-Requires-Dist: cycler >=0.10
-Requires-Dist: fonttools >=4.22.0
-Requires-Dist: kiwisolver >=1.3.1
-Requires-Dist: numpy <2,>=1.21
-Requires-Dist: packaging >=20.0
-Requires-Dist: pillow >=8
-Requires-Dist: pyparsing >=2.3.1
-Requires-Dist: python-dateutil >=2.7
-Requires-Dist: importlib-resources >=3.2.0 ; python_version<"3.10"
-
-[![PyPi](https://img.shields.io/pypi/v/matplotlib)](https://pypi.org/project/matplotlib/)
-[![Conda](https://img.shields.io/conda/vn/conda-forge/matplotlib)](https://anaconda.org/conda-forge/matplotlib)
-[![Downloads](https://img.shields.io/pypi/dm/matplotlib)](https://pypi.org/project/matplotlib)
-[![NUMFocus](https://img.shields.io/badge/powered%20by-NumFOCUS-orange.svg?style=flat&colorA=E1523D&colorB=007D8A)](https://numfocus.org)
-
-[![Discourse help forum](https://img.shields.io/badge/help_forum-discourse-blue.svg)](https://discourse.matplotlib.org)
-[![Gitter](https://badges.gitter.im/matplotlib/matplotlib.svg)](https://gitter.im/matplotlib/matplotlib)
-[![GitHub issues](https://img.shields.io/badge/issue_tracking-github-blue.svg)](https://github.com/matplotlib/matplotlib/issues)
-[![Contributing](https://img.shields.io/badge/PR-Welcome-%23FF8300.svg?)](https://matplotlib.org/stable/devel/index.html)
-
-[![GitHub actions status](https://github.com/matplotlib/matplotlib/workflows/Tests/badge.svg)](https://github.com/matplotlib/matplotlib/actions?query=workflow%3ATests)
-[![Azure pipelines status](https://dev.azure.com/matplotlib/matplotlib/_apis/build/status/matplotlib.matplotlib?branchName=main)](https://dev.azure.com/matplotlib/matplotlib/_build/latest?definitionId=1&branchName=main)
-[![AppVeyor status](https://ci.appveyor.com/api/projects/status/github/matplotlib/matplotlib?branch=main&svg=true)](https://ci.appveyor.com/project/matplotlib/matplotlib)
-[![Codecov status](https://codecov.io/github/matplotlib/matplotlib/badge.svg?branch=main&service=github)](https://app.codecov.io/gh/matplotlib/matplotlib)
-
-![Matplotlib logotype](https://matplotlib.org/_static/logo2.svg)
-
-Matplotlib is a comprehensive library for creating static, animated, and
-interactive visualizations in Python.
-
-Check out our [home page](https://matplotlib.org/) for more information.
-
-![image](https://matplotlib.org/_static/readme_preview.png)
-
-Matplotlib produces publication-quality figures in a variety of hardcopy
-formats and interactive environments across platforms. Matplotlib can be
-used in Python scripts, Python/IPython shells, web application servers,
-and various graphical user interface toolkits.
-
-## Install
-
-See the [install
-documentation](https://matplotlib.org/stable/users/installing/index.html),
-which is generated from `/doc/users/installing/index.rst`
-
-## Contribute
-
-You've discovered a bug or something else you want to change — excellent!
-
-You've worked out a way to fix it — even better!
-
-You want to tell us about it — best of all!
-
-Start at the [contributing
-guide](https://matplotlib.org/devdocs/devel/contributing.html)!
-
-## Contact
-
-[Discourse](https://discourse.matplotlib.org/) is the discussion forum
-for general questions and discussions and our recommended starting
-point.
-
-Our active mailing lists (which are mirrored on Discourse) are:
-
-- [Users](https://mail.python.org/mailman/listinfo/matplotlib-users)
- mailing list: <matplotlib-users@python.org>
-- [Announcement](https://mail.python.org/mailman/listinfo/matplotlib-announce)
- mailing list: <matplotlib-announce@python.org>
-- [Development](https://mail.python.org/mailman/listinfo/matplotlib-devel)
- mailing list: <matplotlib-devel@python.org>
-
-[Gitter](https://gitter.im/matplotlib/matplotlib) is for coordinating
-development and asking questions directly related to contributing to
-matplotlib.
-
-## Citing Matplotlib
-
-If Matplotlib contributes to a project that leads to publication, please
-acknowledge this by citing Matplotlib.
-
-[A ready-made citation
-entry](https://matplotlib.org/stable/users/project/citing.html) is
-available.
diff --git a/contrib/python/matplotlib/py3/.dist-info/top_level.txt b/contrib/python/matplotlib/py3/.dist-info/top_level.txt
deleted file mode 100644
index 0eb77e4d99..0000000000
--- a/contrib/python/matplotlib/py3/.dist-info/top_level.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-matplotlib
-mpl_toolkits
-pylab
diff --git a/contrib/python/matplotlib/py3/.yandex_meta/yamaker.yaml b/contrib/python/matplotlib/py3/.yandex_meta/yamaker.yaml
deleted file mode 100644
index 331cad9870..0000000000
--- a/contrib/python/matplotlib/py3/.yandex_meta/yamaker.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-requirements:
- - contrib/libs/freetype
- - contrib/libs/libpng
- - contrib/libs/qhull
- - contrib/python/matplotlib/py3/extern/agg24-svn
- - contrib/python/matplotlib/py3/extern/ttconv
-mark_as_sources:
- - matplotlib/testing/conftest.py
-exclude:
- - src/_macosx.m
- - src/.clang-format
- - src/doc/segment_intersects_rectangle.svg
-exclude_from_macros:
- - extern/*
-copy:
- - extern/*
- - src/*
-keep:
- - extern/ya.make
- - extern/*/ya.make
diff --git a/contrib/python/matplotlib/py3/LICENSE b/contrib/python/matplotlib/py3/LICENSE
deleted file mode 100644
index ec51537db2..0000000000
--- a/contrib/python/matplotlib/py3/LICENSE
+++ /dev/null
@@ -1,99 +0,0 @@
-License agreement for matplotlib versions 1.3.0 and later
-=========================================================
-
-1. This LICENSE AGREEMENT is between the Matplotlib Development Team
-("MDT"), and the Individual or Organization ("Licensee") accessing and
-otherwise using matplotlib software in source or binary form and its
-associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, MDT
-hereby grants Licensee a nonexclusive, royalty-free, world-wide license
-to reproduce, analyze, test, perform and/or display publicly, prepare
-derivative works, distribute, and otherwise use matplotlib
-alone or in any derivative version, provided, however, that MDT's
-License Agreement and MDT's notice of copyright, i.e., "Copyright (c)
-2012- Matplotlib Development Team; All Rights Reserved" are retained in
-matplotlib alone or in any derivative version prepared by
-Licensee.
-
-3. In the event Licensee prepares a derivative work that is based on or
-incorporates matplotlib or any part thereof, and wants to
-make the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to matplotlib .
-
-4. MDT is making matplotlib available to Licensee on an "AS
-IS" basis. MDT MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, MDT MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB
-WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. MDT SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF MATPLOTLIB
- FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR
-LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING
-MATPLOTLIB , OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF
-THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. Nothing in this License Agreement shall be deemed to create any
-relationship of agency, partnership, or joint venture between MDT and
-Licensee. This License Agreement does not grant permission to use MDT
-trademarks or trade name in a trademark sense to endorse or promote
-products or services of Licensee, or any third party.
-
-8. By copying, installing or otherwise using matplotlib ,
-Licensee agrees to be bound by the terms and conditions of this License
-Agreement.
-
-License agreement for matplotlib versions prior to 1.3.0
-========================================================
-
-1. This LICENSE AGREEMENT is between John D. Hunter ("JDH"), and the
-Individual or Organization ("Licensee") accessing and otherwise using
-matplotlib software in source or binary form and its associated
-documentation.
-
-2. Subject to the terms and conditions of this License Agreement, JDH
-hereby grants Licensee a nonexclusive, royalty-free, world-wide license
-to reproduce, analyze, test, perform and/or display publicly, prepare
-derivative works, distribute, and otherwise use matplotlib
-alone or in any derivative version, provided, however, that JDH's
-License Agreement and JDH's notice of copyright, i.e., "Copyright (c)
-2002-2011 John D. Hunter; All Rights Reserved" are retained in
-matplotlib alone or in any derivative version prepared by
-Licensee.
-
-3. In the event Licensee prepares a derivative work that is based on or
-incorporates matplotlib or any part thereof, and wants to
-make the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to matplotlib.
-
-4. JDH is making matplotlib available to Licensee on an "AS
-IS" basis. JDH MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, JDH MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF MATPLOTLIB
-WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. JDH SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF MATPLOTLIB
- FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR
-LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING
-MATPLOTLIB , OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF
-THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. Nothing in this License Agreement shall be deemed to create any
-relationship of agency, partnership, or joint venture between JDH and
-Licensee. This License Agreement does not grant permission to use JDH
-trademarks or trade name in a trademark sense to endorse or promote
-products or services of Licensee, or any third party.
-
-8. By copying, installing or otherwise using matplotlib,
-Licensee agrees to be bound by the terms and conditions of this License
-Agreement. \ No newline at end of file
diff --git a/contrib/python/matplotlib/py3/LICENSE_AMSFONTS b/contrib/python/matplotlib/py3/LICENSE_AMSFONTS
deleted file mode 100644
index 3627bb9bb6..0000000000
--- a/contrib/python/matplotlib/py3/LICENSE_AMSFONTS
+++ /dev/null
@@ -1,240 +0,0 @@
-The cmr10.pfb file is a Type-1 version of one of Knuth's Computer Modern fonts.
-It is included here as test data only, but the following license applies.
-
-Copyright (c) 1997, 2009, American Mathematical Society (http://www.ams.org).
-All Rights Reserved.
-
-"cmb10" is a Reserved Font Name for this Font Software.
-"cmbsy10" is a Reserved Font Name for this Font Software.
-"cmbsy5" is a Reserved Font Name for this Font Software.
-"cmbsy6" is a Reserved Font Name for this Font Software.
-"cmbsy7" is a Reserved Font Name for this Font Software.
-"cmbsy8" is a Reserved Font Name for this Font Software.
-"cmbsy9" is a Reserved Font Name for this Font Software.
-"cmbx10" is a Reserved Font Name for this Font Software.
-"cmbx12" is a Reserved Font Name for this Font Software.
-"cmbx5" is a Reserved Font Name for this Font Software.
-"cmbx6" is a Reserved Font Name for this Font Software.
-"cmbx7" is a Reserved Font Name for this Font Software.
-"cmbx8" is a Reserved Font Name for this Font Software.
-"cmbx9" is a Reserved Font Name for this Font Software.
-"cmbxsl10" is a Reserved Font Name for this Font Software.
-"cmbxti10" is a Reserved Font Name for this Font Software.
-"cmcsc10" is a Reserved Font Name for this Font Software.
-"cmcsc8" is a Reserved Font Name for this Font Software.
-"cmcsc9" is a Reserved Font Name for this Font Software.
-"cmdunh10" is a Reserved Font Name for this Font Software.
-"cmex10" is a Reserved Font Name for this Font Software.
-"cmex7" is a Reserved Font Name for this Font Software.
-"cmex8" is a Reserved Font Name for this Font Software.
-"cmex9" is a Reserved Font Name for this Font Software.
-"cmff10" is a Reserved Font Name for this Font Software.
-"cmfi10" is a Reserved Font Name for this Font Software.
-"cmfib8" is a Reserved Font Name for this Font Software.
-"cminch" is a Reserved Font Name for this Font Software.
-"cmitt10" is a Reserved Font Name for this Font Software.
-"cmmi10" is a Reserved Font Name for this Font Software.
-"cmmi12" is a Reserved Font Name for this Font Software.
-"cmmi5" is a Reserved Font Name for this Font Software.
-"cmmi6" is a Reserved Font Name for this Font Software.
-"cmmi7" is a Reserved Font Name for this Font Software.
-"cmmi8" is a Reserved Font Name for this Font Software.
-"cmmi9" is a Reserved Font Name for this Font Software.
-"cmmib10" is a Reserved Font Name for this Font Software.
-"cmmib5" is a Reserved Font Name for this Font Software.
-"cmmib6" is a Reserved Font Name for this Font Software.
-"cmmib7" is a Reserved Font Name for this Font Software.
-"cmmib8" is a Reserved Font Name for this Font Software.
-"cmmib9" is a Reserved Font Name for this Font Software.
-"cmr10" is a Reserved Font Name for this Font Software.
-"cmr12" is a Reserved Font Name for this Font Software.
-"cmr17" is a Reserved Font Name for this Font Software.
-"cmr5" is a Reserved Font Name for this Font Software.
-"cmr6" is a Reserved Font Name for this Font Software.
-"cmr7" is a Reserved Font Name for this Font Software.
-"cmr8" is a Reserved Font Name for this Font Software.
-"cmr9" is a Reserved Font Name for this Font Software.
-"cmsl10" is a Reserved Font Name for this Font Software.
-"cmsl12" is a Reserved Font Name for this Font Software.
-"cmsl8" is a Reserved Font Name for this Font Software.
-"cmsl9" is a Reserved Font Name for this Font Software.
-"cmsltt10" is a Reserved Font Name for this Font Software.
-"cmss10" is a Reserved Font Name for this Font Software.
-"cmss12" is a Reserved Font Name for this Font Software.
-"cmss17" is a Reserved Font Name for this Font Software.
-"cmss8" is a Reserved Font Name for this Font Software.
-"cmss9" is a Reserved Font Name for this Font Software.
-"cmssbx10" is a Reserved Font Name for this Font Software.
-"cmssdc10" is a Reserved Font Name for this Font Software.
-"cmssi10" is a Reserved Font Name for this Font Software.
-"cmssi12" is a Reserved Font Name for this Font Software.
-"cmssi17" is a Reserved Font Name for this Font Software.
-"cmssi8" is a Reserved Font Name for this Font Software.
-"cmssi9" is a Reserved Font Name for this Font Software.
-"cmssq8" is a Reserved Font Name for this Font Software.
-"cmssqi8" is a Reserved Font Name for this Font Software.
-"cmsy10" is a Reserved Font Name for this Font Software.
-"cmsy5" is a Reserved Font Name for this Font Software.
-"cmsy6" is a Reserved Font Name for this Font Software.
-"cmsy7" is a Reserved Font Name for this Font Software.
-"cmsy8" is a Reserved Font Name for this Font Software.
-"cmsy9" is a Reserved Font Name for this Font Software.
-"cmtcsc10" is a Reserved Font Name for this Font Software.
-"cmtex10" is a Reserved Font Name for this Font Software.
-"cmtex8" is a Reserved Font Name for this Font Software.
-"cmtex9" is a Reserved Font Name for this Font Software.
-"cmti10" is a Reserved Font Name for this Font Software.
-"cmti12" is a Reserved Font Name for this Font Software.
-"cmti7" is a Reserved Font Name for this Font Software.
-"cmti8" is a Reserved Font Name for this Font Software.
-"cmti9" is a Reserved Font Name for this Font Software.
-"cmtt10" is a Reserved Font Name for this Font Software.
-"cmtt12" is a Reserved Font Name for this Font Software.
-"cmtt8" is a Reserved Font Name for this Font Software.
-"cmtt9" is a Reserved Font Name for this Font Software.
-"cmu10" is a Reserved Font Name for this Font Software.
-"cmvtt10" is a Reserved Font Name for this Font Software.
-"euex10" is a Reserved Font Name for this Font Software.
-"euex7" is a Reserved Font Name for this Font Software.
-"euex8" is a Reserved Font Name for this Font Software.
-"euex9" is a Reserved Font Name for this Font Software.
-"eufb10" is a Reserved Font Name for this Font Software.
-"eufb5" is a Reserved Font Name for this Font Software.
-"eufb7" is a Reserved Font Name for this Font Software.
-"eufm10" is a Reserved Font Name for this Font Software.
-"eufm5" is a Reserved Font Name for this Font Software.
-"eufm7" is a Reserved Font Name for this Font Software.
-"eurb10" is a Reserved Font Name for this Font Software.
-"eurb5" is a Reserved Font Name for this Font Software.
-"eurb7" is a Reserved Font Name for this Font Software.
-"eurm10" is a Reserved Font Name for this Font Software.
-"eurm5" is a Reserved Font Name for this Font Software.
-"eurm7" is a Reserved Font Name for this Font Software.
-"eusb10" is a Reserved Font Name for this Font Software.
-"eusb5" is a Reserved Font Name for this Font Software.
-"eusb7" is a Reserved Font Name for this Font Software.
-"eusm10" is a Reserved Font Name for this Font Software.
-"eusm5" is a Reserved Font Name for this Font Software.
-"eusm7" is a Reserved Font Name for this Font Software.
-"lasy10" is a Reserved Font Name for this Font Software.
-"lasy5" is a Reserved Font Name for this Font Software.
-"lasy6" is a Reserved Font Name for this Font Software.
-"lasy7" is a Reserved Font Name for this Font Software.
-"lasy8" is a Reserved Font Name for this Font Software.
-"lasy9" is a Reserved Font Name for this Font Software.
-"lasyb10" is a Reserved Font Name for this Font Software.
-"lcircle1" is a Reserved Font Name for this Font Software.
-"lcirclew" is a Reserved Font Name for this Font Software.
-"lcmss8" is a Reserved Font Name for this Font Software.
-"lcmssb8" is a Reserved Font Name for this Font Software.
-"lcmssi8" is a Reserved Font Name for this Font Software.
-"line10" is a Reserved Font Name for this Font Software.
-"linew10" is a Reserved Font Name for this Font Software.
-"msam10" is a Reserved Font Name for this Font Software.
-"msam5" is a Reserved Font Name for this Font Software.
-"msam6" is a Reserved Font Name for this Font Software.
-"msam7" is a Reserved Font Name for this Font Software.
-"msam8" is a Reserved Font Name for this Font Software.
-"msam9" is a Reserved Font Name for this Font Software.
-"msbm10" is a Reserved Font Name for this Font Software.
-"msbm5" is a Reserved Font Name for this Font Software.
-"msbm6" is a Reserved Font Name for this Font Software.
-"msbm7" is a Reserved Font Name for this Font Software.
-"msbm8" is a Reserved Font Name for this Font Software.
-"msbm9" is a Reserved Font Name for this Font Software.
-"wncyb10" is a Reserved Font Name for this Font Software.
-"wncyi10" is a Reserved Font Name for this Font Software.
-"wncyr10" is a Reserved Font Name for this Font Software.
-"wncysc10" is a Reserved Font Name for this Font Software.
-"wncyss10" is a Reserved Font Name for this Font Software.
-
-This Font Software is licensed under the SIL Open Font License, Version 1.1.
-This license is copied below, and is also available with a FAQ at:
-http://scripts.sil.org/OFL
-
------------------------------------------------------------
-SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
------------------------------------------------------------
-
-PREAMBLE
-The goals of the Open Font License (OFL) are to stimulate worldwide
-development of collaborative font projects, to support the font creation
-efforts of academic and linguistic communities, and to provide a free and
-open framework in which fonts may be shared and improved in partnership
-with others.
-
-The OFL allows the licensed fonts to be used, studied, modified and
-redistributed freely as long as they are not sold by themselves. The
-fonts, including any derivative works, can be bundled, embedded,
-redistributed and/or sold with any software provided that any reserved
-names are not used by derivative works. The fonts and derivatives,
-however, cannot be released under any other type of license. The
-requirement for fonts to remain under this license does not apply
-to any document created using the fonts or their derivatives.
-
-DEFINITIONS
-"Font Software" refers to the set of files released by the Copyright
-Holder(s) under this license and clearly marked as such. This may
-include source files, build scripts and documentation.
-
-"Reserved Font Name" refers to any names specified as such after the
-copyright statement(s).
-
-"Original Version" refers to the collection of Font Software components as
-distributed by the Copyright Holder(s).
-
-"Modified Version" refers to any derivative made by adding to, deleting,
-or substituting -- in part or in whole -- any of the components of the
-Original Version, by changing formats or by porting the Font Software to a
-new environment.
-
-"Author" refers to any designer, engineer, programmer, technical
-writer or other person who contributed to the Font Software.
-
-PERMISSION & CONDITIONS
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of the Font Software, to use, study, copy, merge, embed, modify,
-redistribute, and sell modified and unmodified copies of the Font
-Software, subject to the following conditions:
-
-1) Neither the Font Software nor any of its individual components,
-in Original or Modified Versions, may be sold by itself.
-
-2) Original or Modified Versions of the Font Software may be bundled,
-redistributed and/or sold with any software, provided that each copy
-contains the above copyright notice and this license. These can be
-included either as stand-alone text files, human-readable headers or
-in the appropriate machine-readable metadata fields within text or
-binary files as long as those fields can be easily viewed by the user.
-
-3) No Modified Version of the Font Software may use the Reserved Font
-Name(s) unless explicit written permission is granted by the corresponding
-Copyright Holder. This restriction only applies to the primary font name as
-presented to the users.
-
-4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
-Software shall not be used to promote, endorse or advertise any
-Modified Version, except to acknowledge the contribution(s) of the
-Copyright Holder(s) and the Author(s) or with their explicit written
-permission.
-
-5) The Font Software, modified or unmodified, in part or in whole,
-must be distributed entirely under this license, and must not be
-distributed under any other license. The requirement for fonts to
-remain under this license does not apply to any document created
-using the Font Software.
-
-TERMINATION
-This license becomes null and void if any of the above conditions are
-not met.
-
-DISCLAIMER
-THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
-COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
-DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
-OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/contrib/python/matplotlib/py3/LICENSE_BAKOMA b/contrib/python/matplotlib/py3/LICENSE_BAKOMA
deleted file mode 100644
index 6200f085b9..0000000000
--- a/contrib/python/matplotlib/py3/LICENSE_BAKOMA
+++ /dev/null
@@ -1,40 +0,0 @@
-
- BaKoMa Fonts Licence
- --------------------
-
- This licence covers two font packs (known as BaKoMa Fonts Collection,
- which is available at `CTAN:fonts/cm/ps-type1/bakoma/'):
-
- 1) BaKoMa-CM (1.1/12-Nov-94)
- Computer Modern Fonts in PostScript Type 1 and TrueType font formats.
-
- 2) BaKoMa-AMS (1.2/19-Jan-95)
- AMS TeX fonts in PostScript Type 1 and TrueType font formats.
-
- Copyright (C) 1994, 1995, Basil K. Malyshev. All Rights Reserved.
-
- Permission to copy and distribute these fonts for any purpose is
- hereby granted without fee, provided that the above copyright notice,
- author statement and this permission notice appear in all copies of
- these fonts and related documentation.
-
- Permission to modify and distribute modified fonts for any purpose is
- hereby granted without fee, provided that the copyright notice,
- author statement, this permission notice and location of original
- fonts (http://www.ctan.org/tex-archive/fonts/cm/ps-type1/bakoma)
- appear in all copies of modified fonts and related documentation.
-
- Permission to use these fonts (embedding into PostScript, PDF, SVG
- and printing by using any software) is hereby granted without fee.
- It is not required to provide any notices about using these fonts.
-
- Basil K. Malyshev
- INSTITUTE FOR HIGH ENERGY PHYSICS
- IHEP, OMVT
- Moscow Region
- 142281 PROTVINO
- RUSSIA
-
- E-Mail: bakoma@mail.ru
- or malyshev@mail.ihep.ru
-
diff --git a/contrib/python/matplotlib/py3/LICENSE_CARLOGO b/contrib/python/matplotlib/py3/LICENSE_CARLOGO
deleted file mode 100644
index 8c99c656a0..0000000000
--- a/contrib/python/matplotlib/py3/LICENSE_CARLOGO
+++ /dev/null
@@ -1,45 +0,0 @@
-----> we renamed carlito -> carlogo to comply with the terms <----
-
-Copyright (c) 2010-2013 by tyPoland Lukasz Dziedzic with Reserved Font Name "Carlito".
-
-This Font Software is licensed under the SIL Open Font License, Version 1.1.
-This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL
-
------------------------------------------------------------
-SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
------------------------------------------------------------
-
-PREAMBLE
-The goals of the Open Font License (OFL) are to stimulate worldwide development of collaborative font projects, to support the font creation efforts of academic and linguistic communities, and to provide a free and open framework in which fonts may be shared and improved in partnership with others.
-
-The OFL allows the licensed fonts to be used, studied, modified and redistributed freely as long as they are not sold by themselves. The fonts, including any derivative works, can be bundled, embedded, redistributed and/or sold with any software provided that any reserved names are not used by derivative works. The fonts and derivatives, however, cannot be released under any other type of license. The requirement for fonts to remain under this license does not apply to any document created using the fonts or their derivatives.
-
-DEFINITIONS
-"Font Software" refers to the set of files released by the Copyright Holder(s) under this license and clearly marked as such. This may include source files, build scripts and documentation.
-
-"Reserved Font Name" refers to any names specified as such after the copyright statement(s).
-
-"Original Version" refers to the collection of Font Software components as distributed by the Copyright Holder(s).
-
-"Modified Version" refers to any derivative made by adding to, deleting, or substituting -- in part or in whole -- any of the components of the Original Version, by changing formats or by porting the Font Software to a new environment.
-
-"Author" refers to any designer, engineer, programmer, technical writer or other person who contributed to the Font Software.
-
-PERMISSION & CONDITIONS
-Permission is hereby granted, free of charge, to any person obtaining a copy of the Font Software, to use, study, copy, merge, embed, modify, redistribute, and sell modified and unmodified copies of the Font Software, subject to the following conditions:
-
-1) Neither the Font Software nor any of its individual components, in Original or Modified Versions, may be sold by itself.
-
-2) Original or Modified Versions of the Font Software may be bundled, redistributed and/or sold with any software, provided that each copy contains the above copyright notice and this license. These can be included either as stand-alone text files, human-readable headers or in the appropriate machine-readable metadata fields within text or binary files as long as those fields can be easily viewed by the user.
-
-3) No Modified Version of the Font Software may use the Reserved Font Name(s) unless explicit written permission is granted by the corresponding Copyright Holder. This restriction only applies to the primary font name as presented to the users.
-
-4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font Software shall not be used to promote, endorse or advertise any Modified Version, except to acknowledge the contribution(s) of the Copyright Holder(s) and the Author(s) or with their explicit written permission.
-
-5) The Font Software, modified or unmodified, in part or in whole, must be distributed entirely under this license, and must not be distributed under any other license. The requirement for fonts to remain under this license does not apply to any document created using the Font Software.
-
-TERMINATION
-This license becomes null and void if any of the above conditions are not met.
-
-DISCLAIMER
-THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT SOFTWARE. \ No newline at end of file
diff --git a/contrib/python/matplotlib/py3/LICENSE_COLORBREWER b/contrib/python/matplotlib/py3/LICENSE_COLORBREWER
deleted file mode 100644
index 7557bb7e76..0000000000
--- a/contrib/python/matplotlib/py3/LICENSE_COLORBREWER
+++ /dev/null
@@ -1,13 +0,0 @@
-Apache-Style Software License for ColorBrewer software and ColorBrewer Color Schemes
-
-Copyright (c) 2002 Cynthia Brewer, Mark Harrower, and The Pennsylvania State University.
-
-Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software distributed
-under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-CONDITIONS OF ANY KIND, either express or implied. See the License for the
-specific language governing permissions and limitations under the License. \ No newline at end of file
diff --git a/contrib/python/matplotlib/py3/LICENSE_COURIERTEN b/contrib/python/matplotlib/py3/LICENSE_COURIERTEN
deleted file mode 100644
index c6d3fd7410..0000000000
--- a/contrib/python/matplotlib/py3/LICENSE_COURIERTEN
+++ /dev/null
@@ -1,18 +0,0 @@
-The Courier10PitchBT-Bold.pfb file is a Type-1 version of
-Courier 10 Pitch BT Bold by Bitstream, obtained from
-<https://ctan.org/tex-archive/fonts/courierten>. It is included
-here as test data only, but the following license applies.
-
-
-(c) Copyright 1989-1992, Bitstream Inc., Cambridge, MA.
-
-You are hereby granted permission under all Bitstream propriety rights
-to use, copy, modify, sublicense, sell, and redistribute the 4 Bitstream
-Charter (r) Type 1 outline fonts and the 4 Courier Type 1 outline fonts
-for any purpose and without restriction; provided, that this notice is
-left intact on all copies of such fonts and that Bitstream's trademark
-is acknowledged as shown below on all unmodified copies of the 4 Charter
-Type 1 fonts.
-
-BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
-
diff --git a/contrib/python/matplotlib/py3/LICENSE_JSXTOOLS_RESIZE_OBSERVER b/contrib/python/matplotlib/py3/LICENSE_JSXTOOLS_RESIZE_OBSERVER
deleted file mode 100644
index 0bc1fa7060..0000000000
--- a/contrib/python/matplotlib/py3/LICENSE_JSXTOOLS_RESIZE_OBSERVER
+++ /dev/null
@@ -1,108 +0,0 @@
-# CC0 1.0 Universal
-
-## Statement of Purpose
-
-The laws of most jurisdictions throughout the world automatically confer
-exclusive Copyright and Related Rights (defined below) upon the creator and
-subsequent owner(s) (each and all, an “owner”) of an original work of
-authorship and/or a database (each, a “Work”).
-
-Certain owners wish to permanently relinquish those rights to a Work for the
-purpose of contributing to a commons of creative, cultural and scientific works
-(“Commons”) that the public can reliably and without fear of later claims of
-infringement build upon, modify, incorporate in other works, reuse and
-redistribute as freely as possible in any form whatsoever and for any purposes,
-including without limitation commercial purposes. These owners may contribute
-to the Commons to promote the ideal of a free culture and the further
-production of creative, cultural and scientific works, or to gain reputation or
-greater distribution for their Work in part through the use and efforts of
-others.
-
-For these and/or other purposes and motivations, and without any expectation of
-additional consideration or compensation, the person associating CC0 with a
-Work (the “Affirmer”), to the extent that he or she is an owner of Copyright
-and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and
-publicly distribute the Work under its terms, with knowledge of his or her
-Copyright and Related Rights in the Work and the meaning and intended legal
-effect of CC0 on those rights.
-
-1. Copyright and Related Rights. A Work made available under CC0 may be
- protected by copyright and related or neighboring rights (“Copyright and
- Related Rights”). Copyright and Related Rights include, but are not limited
- to, the following:
- 1. the right to reproduce, adapt, distribute, perform, display, communicate,
- and translate a Work;
- 2. moral rights retained by the original author(s) and/or performer(s);
- 3. publicity and privacy rights pertaining to a person’s image or likeness
- depicted in a Work;
- 4. rights protecting against unfair competition in regards to a Work,
- subject to the limitations in paragraph 4(i), below;
- 5. rights protecting the extraction, dissemination, use and reuse of data in
- a Work;
- 6. database rights (such as those arising under Directive 96/9/EC of the
- European Parliament and of the Council of 11 March 1996 on the legal
- protection of databases, and under any national implementation thereof,
- including any amended or successor version of such directive); and
- 7. other similar, equivalent or corresponding rights throughout the world
- based on applicable law or treaty, and any national implementations
- thereof.
-
-2. Waiver. To the greatest extent permitted by, but not in contravention of,
- applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
- unconditionally waives, abandons, and surrenders all of Affirmer’s Copyright
- and Related Rights and associated claims and causes of action, whether now
- known or unknown (including existing as well as future claims and causes of
- action), in the Work (i) in all territories worldwide, (ii) for the maximum
- duration provided by applicable law or treaty (including future time
- extensions), (iii) in any current or future medium and for any number of
- copies, and (iv) for any purpose whatsoever, including without limitation
- commercial, advertising or promotional purposes (the “Waiver”). Affirmer
- makes the Waiver for the benefit of each member of the public at large and
- to the detriment of Affirmer’s heirs and successors, fully intending that
- such Waiver shall not be subject to revocation, rescission, cancellation,
- termination, or any other legal or equitable action to disrupt the quiet
- enjoyment of the Work by the public as contemplated by Affirmer’s express
- Statement of Purpose.
-
-3. Public License Fallback. Should any part of the Waiver for any reason be
- judged legally invalid or ineffective under applicable law, then the Waiver
- shall be preserved to the maximum extent permitted taking into account
- Affirmer’s express Statement of Purpose. In addition, to the extent the
- Waiver is so judged Affirmer hereby grants to each affected person a
- royalty-free, non transferable, non sublicensable, non exclusive,
- irrevocable and unconditional license to exercise Affirmer’s Copyright and
- Related Rights in the Work (i) in all territories worldwide, (ii) for the
- maximum duration provided by applicable law or treaty (including future time
- extensions), (iii) in any current or future medium and for any number of
- copies, and (iv) for any purpose whatsoever, including without limitation
- commercial, advertising or promotional purposes (the “License”). The License
- shall be deemed effective as of the date CC0 was applied by Affirmer to the
- Work. Should any part of the License for any reason be judged legally
- invalid or ineffective under applicable law, such partial invalidity or
- ineffectiveness shall not invalidate the remainder of the License, and in
- such case Affirmer hereby affirms that he or she will not (i) exercise any
- of his or her remaining Copyright and Related Rights in the Work or (ii)
- assert any associated claims and causes of action with respect to the Work,
- in either case contrary to Affirmer’s express Statement of Purpose.
-
-4. Limitations and Disclaimers.
- 1. No trademark or patent rights held by Affirmer are waived, abandoned,
- surrendered, licensed or otherwise affected by this document.
- 2. Affirmer offers the Work as-is and makes no representations or warranties
- of any kind concerning the Work, express, implied, statutory or
- otherwise, including without limitation warranties of title,
- merchantability, fitness for a particular purpose, non infringement, or
- the absence of latent or other defects, accuracy, or the present or
- absence of errors, whether or not discoverable, all to the greatest
- extent permissible under applicable law.
- 3. Affirmer disclaims responsibility for clearing rights of other persons
- that may apply to the Work or any use thereof, including without
- limitation any person’s Copyright and Related Rights in the Work.
- Further, Affirmer disclaims responsibility for obtaining any necessary
- consents, permissions or other rights required for any use of the Work.
- 4. Affirmer understands and acknowledges that Creative Commons is not a
- party to this document and has no duty or obligation with respect to this
- CC0 or use of the Work.
-
-For more information, please see
-http://creativecommons.org/publicdomain/zero/1.0/.
diff --git a/contrib/python/matplotlib/py3/LICENSE_QHULL b/contrib/python/matplotlib/py3/LICENSE_QHULL
deleted file mode 100644
index 122a00a4fa..0000000000
--- a/contrib/python/matplotlib/py3/LICENSE_QHULL
+++ /dev/null
@@ -1,39 +0,0 @@
- Qhull, Copyright (c) 1993-2020
-
- C.B. Barber
- Arlington, MA
-
- and
-
- The National Science and Technology Research Center for
- Computation and Visualization of Geometric Structures
- (The Geometry Center)
- University of Minnesota
-
- email: qhull@qhull.org
-
-This software includes Qhull from C.B. Barber and The Geometry Center.
-Files derived from Qhull 1.0 are copyrighted by the Geometry Center. The
-remaining files are copyrighted by C.B. Barber. Qhull is free software
-and may be obtained via http from www.qhull.org. It may be freely copied,
-modified, and redistributed under the following conditions:
-
-1. All copyright notices must remain intact in all files.
-
-2. A copy of this text file must be distributed along with any copies
- of Qhull that you redistribute; this includes copies that you have
- modified, or copies of programs or other software products that
- include Qhull.
-
-3. If you modify Qhull, you must include a notice giving the
- name of the person performing the modification, the date of
- modification, and the reason for such modification.
-
-4. When distributing modified versions of Qhull, or other software
- products that include Qhull, you must provide notice that the original
- source code may be obtained as noted above.
-
-5. There is no warranty or other guarantee of fitness for Qhull, it is
- provided solely "as is". Bug reports or fixes may be sent to
- qhull_bug@qhull.org; the authors may or may not act on them as
- they desire.
diff --git a/contrib/python/matplotlib/py3/LICENSE_QT4_EDITOR b/contrib/python/matplotlib/py3/LICENSE_QT4_EDITOR
deleted file mode 100644
index 1c9d941973..0000000000
--- a/contrib/python/matplotlib/py3/LICENSE_QT4_EDITOR
+++ /dev/null
@@ -1,30 +0,0 @@
-
-Module creating PyQt4 form dialogs/layouts to edit various type of parameters
-
-
-formlayout License Agreement (MIT License)
-------------------------------------------
-
-Copyright (c) 2009 Pierre Raybaut
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-"""
diff --git a/contrib/python/matplotlib/py3/LICENSE_SOLARIZED b/contrib/python/matplotlib/py3/LICENSE_SOLARIZED
deleted file mode 100644
index 6e5a0475dd..0000000000
--- a/contrib/python/matplotlib/py3/LICENSE_SOLARIZED
+++ /dev/null
@@ -1,20 +0,0 @@
-https://github.com/altercation/solarized/blob/master/LICENSE
-Copyright (c) 2011 Ethan Schoonover
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/contrib/python/matplotlib/py3/LICENSE_STIX b/contrib/python/matplotlib/py3/LICENSE_STIX
deleted file mode 100644
index 2f7aeea331..0000000000
--- a/contrib/python/matplotlib/py3/LICENSE_STIX
+++ /dev/null
@@ -1,71 +0,0 @@
-TERMS AND CONDITIONS
-
- 1. Permission is hereby granted, free of charge, to any person
-obtaining a copy of the STIX Fonts-TM set accompanying this license
-(collectively, the "Fonts") and the associated documentation files
-(collectively with the Fonts, the "Font Software"), to reproduce and
-distribute the Font Software, including the rights to use, copy, merge
-and publish copies of the Font Software, and to permit persons to whom
-the Font Software is furnished to do so same, subject to the following
-terms and conditions (the "License").
-
- 2. The following copyright and trademark notice and these Terms and
-Conditions shall be included in all copies of one or more of the Font
-typefaces and any derivative work created as permitted under this
-License:
-
- Copyright (c) 2001-2005 by the STI Pub Companies, consisting of
-the American Institute of Physics, the American Chemical Society, the
-American Mathematical Society, the American Physical Society, Elsevier,
-Inc., and The Institute of Electrical and Electronic Engineers, Inc.
-Portions copyright (c) 1998-2003 by MicroPress, Inc. Portions copyright
-(c) 1990 by Elsevier, Inc. All rights reserved. STIX Fonts-TM is a
-trademark of The Institute of Electrical and Electronics Engineers, Inc.
-
- 3. You may (a) convert the Fonts from one format to another (e.g.,
-from TrueType to PostScript), in which case the normal and reasonable
-distortion that occurs during such conversion shall be permitted and (b)
-embed or include a subset of the Fonts in a document for the purposes of
-allowing users to read text in the document that utilizes the Fonts. In
-each case, you may use the STIX Fonts-TM mark to designate the resulting
-Fonts or subset of the Fonts.
-
- 4. You may also (a) add glyphs or characters to the Fonts, or modify
-the shape of existing glyphs, so long as the base set of glyphs is not
-removed and (b) delete glyphs or characters from the Fonts, provided
-that the resulting font set is distributed with the following
-disclaimer: "This [name] font does not include all the Unicode points
-covered in the STIX Fonts-TM set but may include others." In each case,
-the name used to denote the resulting font set shall not include the
-term "STIX" or any similar term.
-
- 5. You may charge a fee in connection with the distribution of the
-Font Software, provided that no copy of one or more of the individual
-Font typefaces that form the STIX Fonts-TM set may be sold by itself.
-
- 6. THE FONT SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY
-KIND, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-OF COPYRIGHT, PATENT, TRADEMARK OR OTHER RIGHT. IN NO EVENT SHALL
-MICROPRESS OR ANY OF THE STI PUB COMPANIES BE LIABLE FOR ANY CLAIM,
-DAMAGES OR OTHER LIABILITY, INCLUDING, BUT NOT LIMITED TO, ANY GENERAL,
-SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES, WHETHER IN AN
-ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM OR OUT OF THE USE OR
-INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE FONT
-SOFTWARE.
-
- 7. Except as contained in the notice set forth in Section 2, the
-names MicroPress Inc. and STI Pub Companies, as well as the names of the
-companies/organizations that compose the STI Pub Companies, shall not be
-used in advertising or otherwise to promote the sale, use or other
-dealings in the Font Software without the prior written consent of the
-respective company or organization.
-
- 8. This License shall become null and void in the event of any
-material breach of the Terms and Conditions herein by licensee.
-
- 9. A substantial portion of the STIX Fonts set was developed by
-MicroPress Inc. for the STI Pub Companies. To obtain additional
-mathematical fonts, please contact MicroPress, Inc., 68-30 Harrow
-Street, Forest Hills, NY 11375, USA - Phone: (718) 575-1816.
-
diff --git a/contrib/python/matplotlib/py3/LICENSE_YORICK b/contrib/python/matplotlib/py3/LICENSE_YORICK
deleted file mode 100644
index 8c908509a7..0000000000
--- a/contrib/python/matplotlib/py3/LICENSE_YORICK
+++ /dev/null
@@ -1,49 +0,0 @@
-BSD-style license for gist/yorick colormaps.
-
-Copyright:
-
- Copyright (c) 1996. The Regents of the University of California.
- All rights reserved.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose without fee is hereby granted, provided that this entire
-notice is included in all copies of any software which is or includes
-a copy or modification of this software and in all copies of the
-supporting documentation for such software.
-
-This work was produced at the University of California, Lawrence
-Livermore National Laboratory under contract no. W-7405-ENG-48 between
-the U.S. Department of Energy and The Regents of the University of
-California for the operation of UC LLNL.
-
-
- DISCLAIMER
-
-This software was prepared as an account of work sponsored by an
-agency of the United States Government. Neither the United States
-Government nor the University of California nor any of their
-employees, makes any warranty, express or implied, or assumes any
-liability or responsibility for the accuracy, completeness, or
-usefulness of any information, apparatus, product, or process
-disclosed, or represents that its use would not infringe
-privately-owned rights. Reference herein to any specific commercial
-products, process, or service by trade name, trademark, manufacturer,
-or otherwise, does not necessarily constitute or imply its
-endorsement, recommendation, or favoring by the United States
-Government or the University of California. The views and opinions of
-authors expressed herein do not necessarily state or reflect those of
-the United States Government or the University of California, and
-shall not be used for advertising or product endorsement purposes.
-
-
- AUTHOR
-
-David H. Munro wrote Yorick and Gist. Berkeley Yacc (byacc) generated
-the Yorick parser. The routines in Math are from LAPACK and FFTPACK;
-MathC contains C translations by David H. Munro. The algorithms for
-Yorick's random number generator and several special functions in
-Yorick/include were taken from Numerical Recipes by Press, et. al.,
-although the Yorick implementations are unrelated to those in
-Numerical Recipes. A small amount of code in Gist was adapted from
-the X11R4 release, copyright M.I.T. -- the complete copyright notice
-may be found in the (unused) file Gist/host.c.
diff --git a/contrib/python/matplotlib/py3/README.md b/contrib/python/matplotlib/py3/README.md
deleted file mode 100644
index 5e15c645c9..0000000000
--- a/contrib/python/matplotlib/py3/README.md
+++ /dev/null
@@ -1,73 +0,0 @@
-[![PyPi](https://img.shields.io/pypi/v/matplotlib)](https://pypi.org/project/matplotlib/)
-[![Conda](https://img.shields.io/conda/vn/conda-forge/matplotlib)](https://anaconda.org/conda-forge/matplotlib)
-[![Downloads](https://img.shields.io/pypi/dm/matplotlib)](https://pypi.org/project/matplotlib)
-[![NUMFocus](https://img.shields.io/badge/powered%20by-NumFOCUS-orange.svg?style=flat&colorA=E1523D&colorB=007D8A)](https://numfocus.org)
-
-[![Discourse help forum](https://img.shields.io/badge/help_forum-discourse-blue.svg)](https://discourse.matplotlib.org)
-[![Gitter](https://badges.gitter.im/matplotlib/matplotlib.svg)](https://gitter.im/matplotlib/matplotlib)
-[![GitHub issues](https://img.shields.io/badge/issue_tracking-github-blue.svg)](https://github.com/matplotlib/matplotlib/issues)
-[![Contributing](https://img.shields.io/badge/PR-Welcome-%23FF8300.svg?)](https://matplotlib.org/stable/devel/index.html)
-
-[![GitHub actions status](https://github.com/matplotlib/matplotlib/workflows/Tests/badge.svg)](https://github.com/matplotlib/matplotlib/actions?query=workflow%3ATests)
-[![Azure pipelines status](https://dev.azure.com/matplotlib/matplotlib/_apis/build/status/matplotlib.matplotlib?branchName=main)](https://dev.azure.com/matplotlib/matplotlib/_build/latest?definitionId=1&branchName=main)
-[![AppVeyor status](https://ci.appveyor.com/api/projects/status/github/matplotlib/matplotlib?branch=main&svg=true)](https://ci.appveyor.com/project/matplotlib/matplotlib)
-[![Codecov status](https://codecov.io/github/matplotlib/matplotlib/badge.svg?branch=main&service=github)](https://app.codecov.io/gh/matplotlib/matplotlib)
-
-![Matplotlib logotype](https://matplotlib.org/_static/logo2.svg)
-
-Matplotlib is a comprehensive library for creating static, animated, and
-interactive visualizations in Python.
-
-Check out our [home page](https://matplotlib.org/) for more information.
-
-![image](https://matplotlib.org/_static/readme_preview.png)
-
-Matplotlib produces publication-quality figures in a variety of hardcopy
-formats and interactive environments across platforms. Matplotlib can be
-used in Python scripts, Python/IPython shells, web application servers,
-and various graphical user interface toolkits.
-
-## Install
-
-See the [install
-documentation](https://matplotlib.org/stable/users/installing/index.html),
-which is generated from `/doc/users/installing/index.rst`
-
-## Contribute
-
-You've discovered a bug or something else you want to change — excellent!
-
-You've worked out a way to fix it — even better!
-
-You want to tell us about it — best of all!
-
-Start at the [contributing
-guide](https://matplotlib.org/devdocs/devel/contributing.html)!
-
-## Contact
-
-[Discourse](https://discourse.matplotlib.org/) is the discussion forum
-for general questions and discussions and our recommended starting
-point.
-
-Our active mailing lists (which are mirrored on Discourse) are:
-
-- [Users](https://mail.python.org/mailman/listinfo/matplotlib-users)
- mailing list: <matplotlib-users@python.org>
-- [Announcement](https://mail.python.org/mailman/listinfo/matplotlib-announce)
- mailing list: <matplotlib-announce@python.org>
-- [Development](https://mail.python.org/mailman/listinfo/matplotlib-devel)
- mailing list: <matplotlib-devel@python.org>
-
-[Gitter](https://gitter.im/matplotlib/matplotlib) is for coordinating
-development and asking questions directly related to contributing to
-matplotlib.
-
-## Citing Matplotlib
-
-If Matplotlib contributes to a project that leads to publication, please
-acknowledge this by citing Matplotlib.
-
-[A ready-made citation
-entry](https://matplotlib.org/stable/users/project/citing.html) is
-available.
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_alpha_mask_u8.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_alpha_mask_u8.h
deleted file mode 100644
index e301c10088..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_alpha_mask_u8.h
+++ /dev/null
@@ -1,499 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
-
- if(x < 0)
- {
- count += x;
- if(count <= 0)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
- 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)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
- 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)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
-
- if(x < 0)
- {
- count += x;
- if(count <= 0)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
- 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)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
- 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)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
-
- if(y < 0)
- {
- count += y;
- if(count <= 0)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
- 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)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
- 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)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
-
- if(y < 0)
- {
- count += y;
- if(count <= 0)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
- 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)
- {
- memset(dst, 0, num_pix * sizeof(cover_type));
- return;
- }
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_arc.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_arc.h
deleted file mode 100644
index 17e1d43473..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_arc.h
+++ /dev/null
@@ -1,74 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_array.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_array.h
deleted file mode 100644
index 8d56683840..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_array.h
+++ /dev/null
@@ -1,1119 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <stddef.h>
-#include <string.h>
-#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)
- {
- memcpy(m_array, c, sizeof(T) * Size);
- }
-
- const self_type& operator = (const T* c)
- {
- 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)
- {
- 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());
- 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()
- {
- 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);
- 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)
- {
- 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) 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) 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) 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
- {
- 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);
- 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)
- {
- 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)
- {
- 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++)
- {
- 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();
- 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)
- {
- memcpy(&((*this)[start + i]), data, sizeof(T));
- }
- else
- {
- T* ptr = data_ptr();
- 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((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)
- {
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_arrowhead.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_arrowhead.h
deleted file mode 100644
index 5e029ddee0..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_arrowhead.h
+++ /dev/null
@@ -1,82 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_basics.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_basics.h
deleted file mode 100644
index 309713002b..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_basics.h
+++ /dev/null
@@ -1,560 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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(floor(v));
- }
- AGG_INLINE unsigned ufloor(double v)
- {
- return unsigned(floor(v));
- }
- AGG_INLINE int iceil(double v)
- {
- return int(ceil(v));
- }
- AGG_INLINE unsigned uceil(double v)
- {
- return unsigned(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(ceil(v));
- }
- AGG_INLINE unsigned uceil(double v)
- {
- return unsigned(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)
- {
- return fabs(v1 - v2) <= double(epsilon);
- }
-}
-
-
-#endif
-
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bezier_arc.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bezier_arc.h
deleted file mode 100644
index 6d98d1a9f0..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bezier_arc.h
+++ /dev/null
@@ -1,159 +0,0 @@
-//----------------------------------------------------------------------------
-// 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) ? 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bitset_iterator.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bitset_iterator.h
deleted file mode 100644
index 7382d5c335..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bitset_iterator.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_blur.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_blur.h
deleted file mode 100644
index cd5713f314..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_blur.h
+++ /dev/null
@@ -1,1503 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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 * 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 / 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);
- 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
- {
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bounding_rect.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bounding_rect.h
deleted file mode 100644
index f13b863f0f..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bounding_rect.h
+++ /dev/null
@@ -1,116 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bspline.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bspline.h
deleted file mode 100644
index 2c1ed9a38c..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bspline.h
+++ /dev/null
@@ -1,76 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_clip_liang_barsky.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_clip_liang_barsky.h
deleted file mode 100644
index 4b5fedbab5..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_clip_liang_barsky.h
+++ /dev/null
@@ -1,333 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_color_gray.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_color_gray.h
deleted file mode 100644
index 8d5f2ed8d0..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_color_gray.h
+++ /dev/null
@@ -1,1047 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 = value_type((v_ > base_mask) ? 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); }
- };
-
-
- //===================================================================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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_color_rgba.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_color_rgba.h
deleted file mode 100644
index 74f871be17..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_color_rgba.h
+++ /dev/null
@@ -1,1353 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 = pow(t.r * s, gamma);
- t.g = pow(t.g * s, gamma);
- t.b = 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_config.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_config.h
deleted file mode 100644
index fa1dae2ba7..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_config.h
+++ /dev/null
@@ -1,44 +0,0 @@
-#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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_adaptor_vcgen.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_adaptor_vcgen.h
deleted file mode 100644
index a79f2208c6..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_adaptor_vcgen.h
+++ /dev/null
@@ -1,157 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_adaptor_vpgen.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_adaptor_vpgen.h
deleted file mode 100644
index d6b545ef1f..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_adaptor_vpgen.h
+++ /dev/null
@@ -1,159 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_bspline.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_bspline.h
deleted file mode 100644
index 13d22d9297..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_bspline.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_clip_polygon.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_clip_polygon.h
deleted file mode 100644
index 87537638dc..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_clip_polygon.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_clip_polyline.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_clip_polyline.h
deleted file mode 100644
index f3fc2888c2..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_clip_polyline.h
+++ /dev/null
@@ -1,63 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_close_polygon.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_close_polygon.h
deleted file mode 100644
index c46594fdfb..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_close_polygon.h
+++ /dev/null
@@ -1,125 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_concat.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_concat.h
deleted file mode 100644
index 745d349c6f..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_concat.h
+++ /dev/null
@@ -1,73 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_contour.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_contour.h
deleted file mode 100644
index b4b5a9047e..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_contour.h
+++ /dev/null
@@ -1,65 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_curve.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_curve.h
deleted file mode 100644
index d5b475de7a..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_curve.h
+++ /dev/null
@@ -1,201 +0,0 @@
-//----------------------------------------------------------------------------
-// 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;
- double ct2_y;
- double end_x;
- double end_y;
-
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_dash.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_dash.h
deleted file mode 100644
index 23c13ad0ab..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_dash.h
+++ /dev/null
@@ -1,68 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_gpc.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_gpc.h
deleted file mode 100644
index 2acada342d..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_gpc.h
+++ /dev/null
@@ -1,432 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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)
- {
- memset(&m_poly_a, 0, sizeof(m_poly_a));
- memset(&m_poly_b, 0, sizeof(m_poly_b));
- 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);
- 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);
- }
- 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;
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_marker.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_marker.h
deleted file mode 100644
index 2cd3cb403f..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_marker.h
+++ /dev/null
@@ -1,148 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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(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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_marker_adaptor.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_marker_adaptor.h
deleted file mode 100644
index 4486d6ace9..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_marker_adaptor.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_segmentator.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_segmentator.h
deleted file mode 100644
index e69a9e7d7d..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_segmentator.h
+++ /dev/null
@@ -1,48 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_shorten_path.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_shorten_path.h
deleted file mode 100644
index 5617e51d17..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_shorten_path.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_smooth_poly1.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_smooth_poly1.h
deleted file mode 100644
index 4ac4e3d6e2..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_smooth_poly1.h
+++ /dev/null
@@ -1,80 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_stroke.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_stroke.h
deleted file mode 100644
index e19a6b61f4..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_stroke.h
+++ /dev/null
@@ -1,73 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_transform.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_transform.h
deleted file mode 100644
index 0c88a245bd..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_transform.h
+++ /dev/null
@@ -1,68 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_unclose_polygon.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_unclose_polygon.h
deleted file mode 100644
index fe5c263810..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_unclose_polygon.h
+++ /dev/null
@@ -1,52 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_curves.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_curves.h
deleted file mode 100644
index 1ef02e8783..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_curves.h
+++ /dev/null
@@ -1,693 +0,0 @@
-//----------------------------------------------------------------------------
-// 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_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_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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_dda_line.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_dda_line.h
deleted file mode 100644
index f589e76b83..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_dda_line.h
+++ /dev/null
@@ -1,290 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <stdlib.h>
-#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(abs(m_x2_lr - m_x1_lr) < abs(m_y2_lr - m_y1_lr)),
- m_len(m_ver ? abs(m_y2_lr - m_y1_lr) :
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_ellipse.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_ellipse.h
deleted file mode 100644
index e78ce27dd9..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_ellipse.h
+++ /dev/null
@@ -1,123 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-
-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 = (fabs(m_rx) + fabs(m_ry)) / 2;
- double da = 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 + cos(angle) * m_rx;
- *y = m_y + sin(angle) * m_ry;
- m_step++;
- return ((m_step == 1) ? path_cmd_move_to : path_cmd_line_to);
- }
-
-}
-
-
-
-#endif
-
-
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_ellipse_bresenham.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_ellipse_bresenham.h
deleted file mode 100644
index ee3b9c4638..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_ellipse_bresenham.h
+++ /dev/null
@@ -1,113 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_embedded_raster_fonts.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_embedded_raster_fonts.h
deleted file mode 100644
index 9d522d671c..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_embedded_raster_fonts.h
+++ /dev/null
@@ -1,59 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_font_cache_manager.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_font_cache_manager.h
deleted file mode 100644
index fe9a9280fa..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_font_cache_manager.h
+++ /dev/null
@@ -1,409 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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(strlen(font_signature) + 1);
- strcpy(m_font_signature, font_signature);
- memset(m_glyphs, 0, sizeof(m_glyphs));
- }
-
- //--------------------------------------------------------------------
- bool font_is(const char* font_signature) const
- {
- return 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*));
- 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]);
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_font_cache_manager2.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_font_cache_manager2.h
deleted file mode 100644
index 75d311eff7..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_font_cache_manager2.h
+++ /dev/null
@@ -1,311 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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)
- { 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*));
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gamma_functions.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gamma_functions.h
deleted file mode 100644
index 5d720daa9a..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gamma_functions.h
+++ /dev/null
@@ -1,132 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gamma_lut.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gamma_lut.h
deleted file mode 100644
index ef1e38d809..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gamma_lut.h
+++ /dev/null
@@ -1,305 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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(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(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 (unsigned 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 (unsigned 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)
- {
- return float(x / 255.0);
- }
-
- static int8u alpha_to_sRGB(float x)
- {
- if (x <= 0) return 0;
- else if (x >= 1) return 255;
- else 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_glyph_raster_bin.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_glyph_raster_bin.h
deleted file mode 100644
index b0bf858efd..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_glyph_raster_bin.h
+++ /dev/null
@@ -1,155 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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;
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gradient_lut.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gradient_lut.h
deleted file mode 100644
index 9aaa426815..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gradient_lut.h
+++ /dev/null
@@ -1,244 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gsv_text.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gsv_text.h
deleted file mode 100644
index 16b3aeb33d..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gsv_text.h
+++ /dev/null
@@ -1,153 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_image_accessors.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_image_accessors.h
deleted file mode 100644
index c651d6d2e8..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_image_accessors.h
+++ /dev/null
@@ -1,481 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_image_filters.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_image_filters.h
deleted file mode 100644
index 8e1bc8f0db..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_image_filters.h
+++ /dev/null
@@ -1,448 +0,0 @@
-//----------------------------------------------------------------------------
-// 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)
- {
- 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 * 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 * 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 * 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 exp(-2.0 * x * x) * 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 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 (sin(x) / x) * (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 (sin(x) / x) * (0.42 + 0.5*cos(xr) + 0.08*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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_line_aa_basics.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_line_aa_basics.h
deleted file mode 100644
index c5acb18e79..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_line_aa_basics.h
+++ /dev/null
@@ -1,189 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <stdlib.h>
-#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(abs(x2_ - x1_)),
- dy(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 = abs(lp1.x2 - lp1.x1);
- lp1.dy = abs(lp1.y2 - lp1.y1);
-
- lp2.x1 = xmid;
- lp2.y1 = ymid;
- lp2.len = len2;
- lp2.dx = abs(lp2.x2 - lp2.x1);
- lp2.dy = 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_math.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_math.h
deleted file mode 100644
index 2ec49cf3ff..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_math.h
+++ /dev/null
@@ -1,437 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 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 = 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(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 = 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(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(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)fabs(x) + 6;
- if(fabs(x) > 5)
- {
- m1 = (int)(fabs(1.4 * x + 60 / x));
- }
- int m2 = (int)(n + 2 + 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(fabs(b - b1) < d)
- {
- return b;
- }
- b1 = b;
- m2 += 3;
- }
- }
-
-}
-
-
-#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_math_stroke.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_math_stroke.h
deleted file mode 100644
index 4871d96cef..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_math_stroke.h
+++ /dev/null
@@ -1,527 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 / 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 = atan2(dy1 * m_width_sign, dx1 * m_width_sign);
- double a2 = atan2(dy2 * m_width_sign, dx2 * m_width_sign);
- double da = a1 - a2;
- int i, n;
-
- da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
-
- 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 + cos(a1) * m_width, y + 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 + cos(a1) * m_width, y + 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 = 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 = atan2(dy1, -dx1);
- a1 += da;
- for(i = 0; i < n; i++)
- {
- add_vertex(vc, v0.x + cos(a1) * m_width,
- v0.y + sin(a1) * m_width);
- a1 += da;
- }
- }
- else
- {
- a1 = atan2(-dy1, dx1);
- a1 -= da;
- for(i = 0; i < n; i++)
- {
- add_vertex(vc, v0.x + cos(a1) * m_width,
- v0.y + 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 > agg::vertex_dist_epsilon && m_width > 0) ||
- (cp < -agg::vertex_dist_epsilon && 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 = 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_length.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_length.h
deleted file mode 100644
index 740ba31df2..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_length.h
+++ /dev/null
@@ -1,65 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_storage.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_storage.h
deleted file mode 100644
index c01b867f26..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_storage.h
+++ /dev/null
@@ -1,1545 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#include <math.h>
-#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)
- {
- memcpy(new_coords,
- m_coord_blocks,
- m_max_blocks * sizeof(T*));
-
- 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);
- }
- }
- }
-
-
-
- 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 = fabs(rx);
- ry = 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_storage_integer.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_storage_integer.h
deleted file mode 100644
index 7c48355993..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_storage_integer.h
+++ /dev/null
@@ -1,295 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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++)
- {
- 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;
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pattern_filters_rgba.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pattern_filters_rgba.h
deleted file mode 100644
index c1d174cacb..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pattern_filters_rgba.h
+++ /dev/null
@@ -1,123 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_amask_adaptor.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_amask_adaptor.h
deleted file mode 100644
index cf39c54ad5..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_amask_adaptor.h
+++ /dev/null
@@ -1,240 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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);
- memset(&m_span[0], amask_type::cover_full, len * sizeof(cover_type));
- }
-
- void init_span(unsigned len, const cover_type* covers)
- {
- realloc_span(len);
- 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 cover)
- {
- 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 cover)
- {
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_base.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_base.h
deleted file mode 100644
index 57ae19cfe0..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_base.h
+++ /dev/null
@@ -1,97 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_gray.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_gray.h
deleted file mode 100644
index 438f04d33d..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_gray.h
+++ /dev/null
@@ -1,737 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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
- {
- pix_width = sizeof(value_type) * Step,
- pix_step = Step,
- pix_offset = Offset,
- };
- struct pixel_type
- {
- value_type c[pix_step];
-
- 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 this + 1;
- }
-
- const pixel_type* next() const
- {
- return this + 1;
- }
-
- pixel_type* advance(int n)
- {
- return this + n;
- }
-
- const pixel_type* advance(int n) const
- {
- return this + n;
- }
- };
-
- 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))
- {
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgb.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgb.h
deleted file mode 100644
index 7095fbce58..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgb.h
+++ /dev/null
@@ -1,994 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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
- {
- pix_step = Step,
- pix_offset = Offset,
- pix_width = sizeof(value_type) * pix_step
- };
- struct pixel_type
- {
- value_type c[pix_step];
-
- 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 this + 1;
- }
-
- const pixel_type* next() const
- {
- return this + 1;
- }
-
- pixel_type* advance(int n)
- {
- return this + n;
- }
-
- const pixel_type* advance(int n) const
- {
- return this + n;
- }
- };
-
- 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))
- {
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgb_packed.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgb_packed.h
deleted file mode 100644
index d879517de6..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgb_packed.h
+++ /dev/null
@@ -1,1312 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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)
- {
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgba.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgba.h
deleted file mode 100644
index e9cd523b37..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgba.h
+++ /dev/null
@@ -1,2801 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#include <math.h>
-#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 r, value_type g, value_type b, value_type a, 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* p,
- value_type r, value_type g, value_type b, value_type a, cover_type cover)
- {
- // 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 r, value_type g, value_type b, 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 r, value_type g, value_type b, 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) * (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 op, 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 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_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 op, 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 op, 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
- {
- pix_step = 4,
- pix_width = sizeof(value_type) * pix_step,
- };
- struct pixel_type
- {
- value_type c[pix_step];
-
- 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 this + 1;
- }
-
- const pixel_type* next() const
- {
- return this + 1;
- }
-
- pixel_type* advance(int n)
- {
- return this + n;
- }
-
- const pixel_type* advance(int n) const
- {
- return this + n;
- }
- };
-
- 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))
- {
- 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
- {
- pix_step = 4,
- pix_width = sizeof(value_type) * pix_step,
- };
- struct pixel_type
- {
- value_type c[pix_step];
-
- 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 this + 1;
- }
-
- const pixel_type* next() const
- {
- return this + 1;
- }
-
- pixel_type* advance(int n)
- {
- return this + n;
- }
-
- const pixel_type* advance(int n) const
- {
- return this + n;
- }
- };
-
-
- 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)
- {
- make_pix(pix_value_ptr(x, y, 1), 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))
- {
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_transposer.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_transposer.h
deleted file mode 100644
index 64738b6c75..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_transposer.h
+++ /dev/null
@@ -1,157 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_cells_aa.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_cells_aa.h
deleted file mode 100644
index d1cc705405..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_cells_aa.h
+++ /dev/null
@@ -1,743 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <stdexcept>
-#include <string.h>
-#include <math.h>
-#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(0x7FFFFFFF),
- m_min_y(0x7FFFFFFF),
- m_max_x(-0x7FFFFFFF),
- m_max_y(-0x7FFFFFFF),
- 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 = 0x7FFFFFFF;
- m_min_y = 0x7FFFFFFF;
- m_max_x = -0x7FFFFFFF;
- m_max_y = -0x7FFFFFFF;
- }
-
- //------------------------------------------------------------------------
- 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) {
- throw std::overflow_error("Exceeded cell block limit");
- }
- 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, 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 = x2 - x1;
-
- if(dx < 0)
- {
- p = fx1 * (y2 - y1);
- first = 0;
- incr = -1;
- dx = -dx;
- }
-
- delta = p / dx;
- mod = 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 = p / dx;
- rem = 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 };
-
- int dx = x2 - x1;
-
- if(dx >= dx_limit || dx <= -dx_limit)
- {
- int cx = (x1 + x2) >> 1;
- int cy = (y1 + y2) >> 1;
- line(x1, y1, cx, cy);
- line(cx, cy, x2, y2);
- return;
- }
-
- int dy = y2 - 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 p, rem, mod, lift, delta, first, incr;
-
- 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 = p / dy;
- mod = 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 = p / dy;
- rem = 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)
- {
- 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 = 0x7FFFFFFF;
- m_curr_cell.y = 0x7FFFFFFF;
- 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) ? 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) ? 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_compound_aa.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_compound_aa.h
deleted file mode 100644
index 41d508010e..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_compound_aa.h
+++ /dev/null
@@ -1,663 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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 = 0x7FFFFFFF;
- y = 0x7FFFFFFF;
- 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 (ex - x) | (ey - y) | (left - c.left) | (right - 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(unsigned cell_block_limit=1024) :
- m_outline(cell_block_limit),
- 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(0x7FFFFFFF),
- m_max_style(-0x7FFFFFFF),
- m_start_x(0),
- m_start_y(0),
- m_scan_y(0x7FFFFFFF),
- 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 = 0x7FFFFFFF;
- m_max_style = -0x7FFFFFFF;
- m_scan_y = 0x7FFFFFFF;
- 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 = -0x7FFFFFFF;
- }
- ++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 = -0x7FFFFFFF;
-
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_outline.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_outline.h
deleted file mode 100644
index 65203e34c5..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_outline.h
+++ /dev/null
@@ -1,147 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_outline_aa.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_outline_aa.h
deleted file mode 100644
index a06bd1e843..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_outline_aa.h
+++ /dev/null
@@ -1,599 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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(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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_scanline_aa.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_scanline_aa.h
deleted file mode 100644
index 1583216646..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_scanline_aa.h
+++ /dev/null
@@ -1,481 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_scanline_aa_nogamma.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_scanline_aa_nogamma.h
deleted file mode 100644
index 7729b3359a..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_scanline_aa_nogamma.h
+++ /dev/null
@@ -1,482 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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 = 0x7FFFFFFF;
- y = 0x7FFFFFFF;
- cover = 0;
- area = 0;
- }
-
- void style(const cell_aa&) {}
-
- int not_equal(int ex, int ey, const cell_aa&) const
- {
- return ex != x || ey != 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_sl_clip.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_sl_clip.h
deleted file mode 100644
index e7ba065acc..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_sl_clip.h
+++ /dev/null
@@ -1,351 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 x1, coord_type y1, coord_type x2, coord_type y2) {}
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_base.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_base.h
deleted file mode 100644
index 527c62f789..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_base.h
+++ /dev/null
@@ -1,731 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_markers.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_markers.h
deleted file mode 100644
index 820f753079..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_markers.h
+++ /dev/null
@@ -1,706 +0,0 @@
-//----------------------------------------------------------------------------
-// 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;
- }
- }
-
-
- //--------------------------------------------------------------------
- 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;
- }
- }
-
- //--------------------------------------------------------------------
- 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;
- }
- }
-
- //--------------------------------------------------------------------
- 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;
- }
- }
-
- //--------------------------------------------------------------------
- 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;
- }
- }
- };
-
-}
-
-#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_mclip.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_mclip.h
deleted file mode 100644
index 96a7d4e094..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_mclip.h
+++ /dev/null
@@ -1,349 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_outline_aa.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_outline_aa.h
deleted file mode 100644
index ee564f04d5..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_outline_aa.h
+++ /dev/null
@@ -1,1837 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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 ? abs(lp.y2 - lp.y1) :
- 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 ? abs((lp.y2 >> line_subpixel_shift) - m_y) :
- 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; }
- 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(abs(sx - lp.x1) + 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(abs(ex - lp.x2) + 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(abs(sx - lp.x1) + 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(abs(ex - lp.x2) + 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_outline_image.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_outline_image.h
deleted file mode 100644
index 8abb9fa0bd..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_outline_image.h
+++ /dev/null
@@ -1,1036 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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() : m_source.pixel(x, y1);
- rgba pix2 = (y2 > h) ? rgba::no_color() : 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 ? abs(lp.y2 - lp.y1) :
- 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 ? abs((lp.y2 >> line_subpixel_shift) - m_y) :
- 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(abs(sx - lp.x1) + 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(abs(ex - lp.x2) + 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_primitives.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_primitives.h
deleted file mode 100644
index f008db7c94..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_primitives.h
+++ /dev/null
@@ -1,224 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_raster_text.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_raster_text.h
deleted file mode 100644
index 87b43f9600..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_raster_text.h
+++ /dev/null
@@ -1,264 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_scanline.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_scanline.h
deleted file mode 100644
index 6d65056c53..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_scanline.h
+++ /dev/null
@@ -1,852 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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(;;)
- {
- 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)
- {
- memset(mix_buffer + sl_start - min_x,
- 0,
- sl_len * sizeof(color_type));
-
- memset(cover_buffer + sl_start - min_x,
- 0,
- sl_len * sizeof(cover_type));
-
- int sl_y = 0x7FFFFFFF;
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rendering_buffer.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rendering_buffer.h
deleted file mode 100644
index 191347f63e..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rendering_buffer.h
+++ /dev/null
@@ -1,300 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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++)
- {
- 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++)
- {
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rendering_buffer_dynarow.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rendering_buffer_dynarow.h
deleted file mode 100644
index 188746f3d3..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rendering_buffer_dynarow.h
+++ /dev/null
@@ -1,137 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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)
- {
- 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);
- 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;
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rounded_rect.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rounded_rect.h
deleted file mode 100644
index fe8d26f71b..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rounded_rect.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_bin.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_bin.h
deleted file mode 100644
index 660292b613..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_bin.h
+++ /dev/null
@@ -1,264 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 min_x, int max_x)
- {
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_boolean_algebra.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_boolean_algebra.h
deleted file mode 100644
index bc2e9c9d51..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_boolean_algebra.h
+++ /dev/null
@@ -1,1567 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <stdlib.h>
-#include <math.h>
-#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(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, 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 + abs((int)span1->len) - 1;
- int xe2 = xb2 + 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 + abs((int)span1->len) - 1;
- --num1;
- }
-
- // Initialize span2 if there are spans
- //---------------
- if(num2)
- {
- span2 = sl2.begin();
- xb2 = span2->x;
- xe2 = xb2 + 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 + abs((int)span1->len) - 1;
- }
-
- // Retrieve a new span2 if it's invalid
- //----------------
- if(num2 && xb2 > xe2)
- {
- --num2;
- ++span2;
- xb2 = span2->x;
- xe2 = xb2 + 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_p.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_p.h
deleted file mode 100644
index 1d1cbe72f1..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_p.h
+++ /dev/null
@@ -1,329 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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)
- {
- 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)
- {
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_storage_aa.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_storage_aa.h
deleted file mode 100644
index b3471fce76..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_storage_aa.h
+++ /dev/null
@@ -1,815 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#include <stdlib.h>
-#include <math.h>
-#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];
- memcpy(ptr, cells, sizeof(T) * num_cells);
- return idx;
- }
- extra_span s;
- s.len = num_cells;
- s.ptr = pod_allocator<T>::allocate(num_cells);
- 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);
- 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( 0x7FFFFFFF),
- m_min_y( 0x7FFFFFFF),
- m_max_x(-0x7FFFFFFF),
- m_max_y(-0x7FFFFFFF),
- 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 = 0x7FFFFFFF;
- m_min_y = 0x7FFFFFFF;
- m_max_x = -0x7FFFFFFF;
- m_max_y = -0x7FFFFFFF;
- 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 = 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)
- {
- memcpy(data, covers, sizeof(T));
- data += sizeof(T);
- }
- else
- {
- 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(0x7FFFFFFF),
- m_min_y(0x7FFFFFFF),
- m_max_x(-0x7FFFFFFF),
- m_max_y(-0x7FFFFFFF)
- {}
-
- //--------------------------------------------------------------------
- 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(0x7FFFFFFF),
- m_min_y(0x7FFFFFFF),
- m_max_x(-0x7FFFFFFF),
- m_max_y(-0x7FFFFFFF)
- {}
-
- //--------------------------------------------------------------------
- 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 = 0x7FFFFFFF;
- m_min_y = 0x7FFFFFFF;
- m_max_x = -0x7FFFFFFF;
- m_max_y = -0x7FFFFFFF;
- }
-
- 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_int32u() + m_dx;
- m_min_y = read_int32u() + m_dy;
- m_max_x = read_int32u() + m_dx;
- m_max_y = read_int32u() + 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_storage_bin.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_storage_bin.h
deleted file mode 100644
index 3ab1adca51..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_storage_bin.h
+++ /dev/null
@@ -1,586 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#include <stdlib.h>
-#include <math.h>
-#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( 0x7FFFFFFF),
- m_min_y( 0x7FFFFFFF),
- m_max_x(-0x7FFFFFFF),
- m_max_y(-0x7FFFFFFF),
- 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 = 0x7FFFFFFF;
- m_min_y = 0x7FFFFFFF;
- m_max_x = -0x7FFFFFFF;
- m_max_y = -0x7FFFFFFF;
- 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)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(0x7FFFFFFF),
- m_min_y(0x7FFFFFFF),
- m_max_x(-0x7FFFFFFF),
- m_max_y(-0x7FFFFFFF)
- {}
-
- //--------------------------------------------------------------------
- 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(0x7FFFFFFF),
- m_min_y(0x7FFFFFFF),
- m_max_x(-0x7FFFFFFF),
- m_max_y(-0x7FFFFFFF)
- {}
-
- //--------------------------------------------------------------------
- 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 = 0x7FFFFFFF;
- m_min_y = 0x7FFFFFFF;
- m_max_x = -0x7FFFFFFF;
- m_max_y = -0x7FFFFFFF;
- }
-
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_u.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_u.h
deleted file mode 100644
index 2628f55f47..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_u.h
+++ /dev/null
@@ -1,499 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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;
- 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;
- 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;
- 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;
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_shorten_path.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_shorten_path.h
deleted file mode 100644
index dd9929ff97..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_shorten_path.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_simul_eq.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_simul_eq.h
deleted file mode 100644
index 3d0dce4b44..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_simul_eq.h
+++ /dev/null
@@ -1,147 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 = 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_allocator.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_allocator.h
deleted file mode 100644
index 201b69bb01..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_allocator.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_converter.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_converter.h
deleted file mode 100644
index 91d0f87c25..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_converter.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud.h
deleted file mode 100644
index 2986c88fee..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud.h
+++ /dev/null
@@ -1,172 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud_gray.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud_gray.h
deleted file mode 100644
index d5fc39d102..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud_gray.h
+++ /dev/null
@@ -1,241 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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 = (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 = 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud_rgba.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud_rgba.h
deleted file mode 100644
index 1b28572029..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud_rgba.h
+++ /dev/null
@@ -1,277 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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 = 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient.h
deleted file mode 100644
index 58b506dcfe..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient.h
+++ /dev/null
@@ -1,377 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#include <stdlib.h>
-#include <string.h>
-#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(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 + sqrt(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 = abs(x);
- int ay = 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 abs(x) * abs(y) / d;
- }
- };
-
- //========================================================gradient_sqrt_xy
- class gradient_sqrt_xy
- {
- public:
- static AGG_INLINE int calculate(int x, int y, int)
- {
- return fast_sqrt(abs(x) * abs(y));
- }
- };
-
- //==========================================================gradient_conic
- class gradient_conic
- {
- public:
- static AGG_INLINE int calculate(int x, int y, int d)
- {
- return uround(fabs(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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_alpha.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_alpha.h
deleted file mode 100644
index 2ec040e3b9..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_alpha.h
+++ /dev/null
@@ -1,126 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 = &af; }
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_contour.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_contour.h
deleted file mode 100644
index 899bb799b6..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_contour.h
+++ /dev/null
@@ -1,362 +0,0 @@
-//----------------------------------------------------------------------------
-// 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"
-
-#define infinity 1E20
-
-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 ] = float(-infinity );
- spang[1 ] = float(+infinity );
-
- 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 ] = float(+infinity);
-
- }
-
- 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)
- {
- 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 (1e20) 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 ] = float(infinity );
- }
- }
-
- }
-
- // 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 = 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] = sqrt(image[l]);
-
- if (min > image[l])
- {
- min = image[l];
- }
-
- if (max < image[l])
- {
- max = image[l];
- }
-
- }
- }
-
- // III. Convert To Grayscale
- if (min == max)
- {
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_image.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_image.h
deleted file mode 100644
index c99eaca166..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_image.h
+++ /dev/null
@@ -1,188 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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 ];
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter.h
deleted file mode 100644
index 2f613e5d86..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter.h
+++ /dev/null
@@ -1,246 +0,0 @@
-//----------------------------------------------------------------------------
-// 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);
-
- if(scale_x * scale_y > m_scale_limit)
- {
- scale_x = scale_x * m_scale_limit / (scale_x * scale_y);
- scale_y = scale_y * m_scale_limit / (scale_x * scale_y);
- }
-
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_gray.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_gray.h
deleted file mode 100644
index e2c688e004..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_gray.h
+++ /dev/null
@@ -1,723 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_rgb.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_rgb.h
deleted file mode 100644
index f78ae19c1b..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_rgb.h
+++ /dev/null
@@ -1,861 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_rgba.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_rgba.h
deleted file mode 100644
index af7a1a2ef0..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_rgba.h
+++ /dev/null
@@ -1,890 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_adaptor.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_adaptor.h
deleted file mode 100644
index 0fdfa77479..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_adaptor.h
+++ /dev/null
@@ -1,77 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_linear.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_linear.h
deleted file mode 100644
index ef10505ce1..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_linear.h
+++ /dev/null
@@ -1,232 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_persp.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_persp.h
deleted file mode 100644
index cad437e04f..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_persp.h
+++ /dev/null
@@ -1,462 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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/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/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/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/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/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/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/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/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/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/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/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/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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_trans.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_trans.h
deleted file mode 100644
index 32bc678a8e..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_trans.h
+++ /dev/null
@@ -1,92 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_gray.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_gray.h
deleted file mode 100644
index ae1a49f879..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_gray.h
+++ /dev/null
@@ -1,93 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_rgb.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_rgb.h
deleted file mode 100644
index 4850508af1..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_rgb.h
+++ /dev/null
@@ -1,96 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_rgba.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_rgba.h
deleted file mode 100644
index d47d2a6c02..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_rgba.h
+++ /dev/null
@@ -1,94 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_solid.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_solid.h
deleted file mode 100644
index ee46df9991..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_solid.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_subdiv_adaptor.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_subdiv_adaptor.h
deleted file mode 100644
index b5b855ec97..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_subdiv_adaptor.h
+++ /dev/null
@@ -1,141 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_affine.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_affine.h
deleted file mode 100644
index 1a61163883..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_affine.h
+++ /dev/null
@@ -1,518 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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.707106781 * sx + 0.707106781 * shx;
- double y = 0.707106781 * shy + 0.707106781 * sy;
- return 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 = cos(a);
- double sa = 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 = sqrt(sx * sx + shx * shx);
- *y = 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(cos(a), sin(a), -sin(a), 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, tan(y), 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(sqrt(dx * dx + dy * dy) / dist));
- }
- multiply(trans_affine_rotation(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(cos(a), sin(a))
- {}
-
-
- trans_affine_reflection(double x, double y) :
- trans_affine_reflection_unit(x / sqrt(x * x + y * y), y / sqrt(x * x + y * y))
- {}
- };
-
-}
-
-
-#endif
-
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_bilinear.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_bilinear.h
deleted file mode 100644
index f3ab596472..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_bilinear.h
+++ /dev/null
@@ -1,166 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_double_path.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_double_path.h
deleted file mode 100644
index c645a7f869..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_double_path.h
+++ /dev/null
@@ -1,131 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_perspective.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_perspective.h
deleted file mode 100644
index 7d4aa26c79..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_perspective.h
+++ /dev/null
@@ -1,731 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 "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 fabs(sx) > epsilon && fabs(sy) > epsilon && 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 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 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 = sqrt(sx * sx + shx * shx);
- *y = sqrt(shy * shy + sy * sy);
- }
-
-
-}
-
-#endif
-
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_single_path.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_single_path.h
deleted file mode 100644
index 9f4bf53bdb..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_single_path.h
+++ /dev/null
@@ -1,97 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_viewport.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_viewport.h
deleted file mode 100644
index 7088f99078..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_viewport.h
+++ /dev/null
@@ -1,303 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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
- {
- memcpy(ptr, this, sizeof(*this));
- }
-
- void deserialize(const int8u* ptr)
- {
- 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(fabs(m_world_x1 - m_world_x2) < epsilon ||
- fabs(m_world_y1 - m_world_y2) < epsilon ||
- fabs(m_device_x1 - m_device_x2) < epsilon ||
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_warp_magnifier.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_warp_magnifier.h
deleted file mode 100644
index 38a92dbec8..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_warp_magnifier.h
+++ /dev/null
@@ -1,56 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_bspline.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_bspline.h
deleted file mode 100644
index a2944548c0..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_bspline.h
+++ /dev/null
@@ -1,74 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_contour.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_contour.h
deleted file mode 100644
index 8c25da13f5..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_contour.h
+++ /dev/null
@@ -1,94 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_dash.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_dash.h
deleted file mode 100644
index c87dce4c81..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_dash.h
+++ /dev/null
@@ -1,93 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_markers_term.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_markers_term.h
deleted file mode 100644
index ee1e74e3eb..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_markers_term.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_smooth_poly1.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_smooth_poly1.h
deleted file mode 100644
index 80fc0fb796..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_smooth_poly1.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_stroke.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_stroke.h
deleted file mode 100644
index 778223fe40..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_stroke.h
+++ /dev/null
@@ -1,102 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_vertex_sequence.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_vertex_sequence.h
deleted file mode 100644
index 5adc671597..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_vertex_sequence.h
+++ /dev/null
@@ -1,135 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vertex_sequence.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vertex_sequence.h
deleted file mode 100644
index 2ad0701b37..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vertex_sequence.h
+++ /dev/null
@@ -1,172 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_clip_polygon.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_clip_polygon.h
deleted file mode 100644
index ded754e211..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_clip_polygon.h
+++ /dev/null
@@ -1,83 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_clip_polyline.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_clip_polyline.h
deleted file mode 100644
index b070a7759e..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_clip_polyline.h
+++ /dev/null
@@ -1,78 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_segmentator.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_segmentator.h
deleted file mode 100644
index 29b3c9fa6f..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_segmentator.h
+++ /dev/null
@@ -1,61 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_bezier_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_bezier_ctrl.h
deleted file mode 100644
index 01851eb3e1..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_bezier_ctrl.h
+++ /dev/null
@@ -1,196 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 i) 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_cbox_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_cbox_ctrl.h
deleted file mode 100644
index 7ecbce27f4..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_cbox_ctrl.h
+++ /dev/null
@@ -1,112 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_ctrl.h
deleted file mode 100644
index 7e811c63e1..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_ctrl.h
+++ /dev/null
@@ -1,118 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_gamma_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_gamma_ctrl.h
deleted file mode 100644
index 0a645a7146..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_gamma_ctrl.h
+++ /dev/null
@@ -1,170 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_gamma_spline.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_gamma_spline.h
deleted file mode 100644
index 4f21710d9f..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_gamma_spline.h
+++ /dev/null
@@ -1,95 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_polygon_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_polygon_ctrl.h
deleted file mode 100644
index 6f465d96b8..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_polygon_ctrl.h
+++ /dev/null
@@ -1,166 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 i) 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_rbox_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_rbox_ctrl.h
deleted file mode 100644
index 4d47bccdbb..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_rbox_ctrl.h
+++ /dev/null
@@ -1,141 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_scale_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_scale_ctrl.h
deleted file mode 100644
index b1e32c2037..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_scale_ctrl.h
+++ /dev/null
@@ -1,146 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_slider_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_slider_ctrl.h
deleted file mode 100644
index b50a95c59d..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_slider_ctrl.h
+++ /dev/null
@@ -1,150 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_spline_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_spline_ctrl.h
deleted file mode 100644
index 8477f27d78..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_spline_ctrl.h
+++ /dev/null
@@ -1,159 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/agg_platform_support.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/agg_platform_support.h
deleted file mode 100644
index 9a63411e50..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/agg_platform_support.h
+++ /dev/null
@@ -1,686 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/mac/agg_mac_pmap.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/mac/agg_mac_pmap.h
deleted file mode 100644
index d7860b6fee..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/mac/agg_mac_pmap.h
+++ /dev/null
@@ -1,87 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <stdio.h>
-#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/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/win32/agg_win32_bmp.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/win32/agg_win32_bmp.h
deleted file mode 100644
index 5391e8bb9b..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/win32/agg_win32_bmp.h
+++ /dev/null
@@ -1,117 +0,0 @@
-//----------------------------------------------------------------------------
-// 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>
-#include <stdio.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/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv.h
deleted file mode 100644
index 8b8a0a55d2..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv.h
+++ /dev/null
@@ -1,128 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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
- {
- 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
- {
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv_rgb16.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv_rgb16.h
deleted file mode 100644
index aaa41322c5..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv_rgb16.h
+++ /dev/null
@@ -1,285 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv_rgb8.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv_rgb8.h
deleted file mode 100644
index 609460dba4..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv_rgb8.h
+++ /dev/null
@@ -1,476 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/ChangeLog b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ChangeLog
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ChangeLog
+++ /dev/null
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_arc.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_arc.cpp
deleted file mode 100644
index df2c43a559..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_arc.cpp
+++ /dev/null
@@ -1,106 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 + cos(m_end) * m_rx;
- *y = m_y + sin(m_end) * m_ry;
- m_path_cmd = path_cmd_stop;
- return path_cmd_line_to;
- }
-
- *x = m_x + cos(m_angle) * m_rx;
- *y = m_y + 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 = (fabs(m_rx) + fabs(m_ry)) / 2;
- m_da = 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_arrowhead.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_arrowhead.cpp
deleted file mode 100644
index 1a6f8b4100..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_arrowhead.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_bezier_arc.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_bezier_arc.cpp
deleted file mode 100644
index 844d300c09..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_bezier_arc.cpp
+++ /dev/null
@@ -1,258 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 = cos(sweep_angle / 2.0);
- double y0 = 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 = sin(start_angle + sweep_angle / 2.0);
- double cs = 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 = 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(fabs(sweep_angle) < 1e-10)
- {
- m_num_vertices = 4;
- m_cmd = path_cmd_line_to;
- m_vertices[0] = x + rx * cos(start_angle);
- m_vertices[1] = y + ry * sin(start_angle);
- m_vertices[2] = x + rx * cos(start_angle + sweep_angle);
- m_vertices[3] = y + ry * 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 = cos(angle);
- double sin_a = 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 = sqrt(radii_check) * rx;
- ry = 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 * 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 = 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 * acos(v);
-
- // Calculate the sweep angle
- //------------------------
- n = 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 * 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_bspline.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_bspline.cpp
deleted file mode 100644
index e1fda9f51f..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_bspline.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_color_rgba.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_color_rgba.cpp
deleted file mode 100644
index 9fe1534b03..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_color_rgba.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_curves.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_curves.cpp
deleted file mode 100644
index 4701734718..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_curves.cpp
+++ /dev/null
@@ -1,613 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 = sqrt(dx1 * dx1 + dy1 * dy1) + 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 = 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 = fabs(atan2(y3 - y2, x3 - x2) - 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 = (sqrt(dx1 * dx1 + dy1 * dy1) +
- sqrt(dx2 * dx2 + dy2 * dy2) +
- 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 = fabs(((x2 - x4) * dy - (y2 - y4) * dx));
- double d3 = 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 = fabs(atan2(y4 - y3, x4 - x3) - 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 = fabs(atan2(y3 - y2, x3 - x2) - 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 = atan2(y3 - y2, x3 - x2);
- da1 = fabs(k - atan2(y2 - y1, x2 - x1));
- da2 = fabs(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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_embedded_raster_fonts.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_embedded_raster_fonts.cpp
deleted file mode 100644
index ee4dc65ee4..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_embedded_raster_fonts.cpp
+++ /dev/null
@@ -1,10426 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_gsv_text.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_gsv_text.cpp
deleted file mode 100644
index ffb24eb9b6..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_gsv_text.cpp
+++ /dev/null
@@ -1,675 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#include <stdio.h>
-#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 = fopen(file, "rb");
- if(fd)
- {
- unsigned len;
-
- fseek(fd, 0l, SEEK_END);
- len = ftell(fd);
- fseek(fd, 0l, SEEK_SET);
- if(len > 0)
- {
- m_loaded_font.resize(len);
- fread(&m_loaded_font[0], 1, len, fd);
- m_font = &m_loaded_font[0];
- }
- fclose(fd);
- }
- }
-
- //-------------------------------------------------------------------------
- void gsv_text::text(const char* text)
- {
- if(text == 0)
- {
- m_chr[0] = 0;
- m_text = m_chr;
- return;
- }
- unsigned new_size = strlen(text) + 1;
- if(new_size > m_text_buf.size())
- {
- m_text_buf.resize(new_size);
- }
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_image_filters.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_image_filters.cpp
deleted file mode 100644
index 549d9adbf5..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_image_filters.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_line_aa_basics.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_line_aa_basics.cpp
deleted file mode 100644
index 018d65366f..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_line_aa_basics.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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)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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_line_profile_aa.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_line_profile_aa.cpp
deleted file mode 100644
index 6066662cb9..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_line_profile_aa.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_rounded_rect.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_rounded_rect.cpp
deleted file mode 100644
index bebc063628..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_rounded_rect.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 = fabs(m_y2 - m_y1);
- double dy = 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_sqrt_tables.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_sqrt_tables.cpp
deleted file mode 100644
index 19a1bd8cb7..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_sqrt_tables.cpp
+++ /dev/null
@@ -1,115 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_affine.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_affine.cpp
deleted file mode 100644
index 99febc953a..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_affine.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 fabs(sx) > epsilon && 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 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_double_path.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_double_path.cpp
deleted file mode 100644
index cd40c7f586..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_double_path.cpp
+++ /dev/null
@@ -1,273 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_single_path.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_single_path.cpp
deleted file mode 100644
index 2120fc9b9b..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_single_path.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_warp_magnifier.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_warp_magnifier.cpp
deleted file mode 100644
index e65afabba7..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_warp_magnifier.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 = 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 = 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_bspline.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_bspline.cpp
deleted file mode 100644
index 4a0be6693e..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_bspline.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_contour.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_contour.cpp
deleted file mode 100644
index a6a99405ad..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_contour.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_dash.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_dash.cpp
deleted file mode 100644
index 129505786c..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_dash.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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(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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_markers_term.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_markers_term.cpp
deleted file mode 100644
index 3374ab5e82..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_markers_term.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_smooth_poly1.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_smooth_poly1.cpp
deleted file mode 100644
index ff7d488d39..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_smooth_poly1.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_stroke.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_stroke.cpp
deleted file mode 100644
index 2dae3e122b..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_stroke.cpp
+++ /dev/null
@@ -1,213 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_clip_polygon.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_clip_polygon.cpp
deleted file mode 100644
index 4524526017..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_clip_polygon.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_clip_polyline.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_clip_polyline.cpp
deleted file mode 100644
index 6840803a98..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_clip_polyline.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_segmentator.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_segmentator.cpp
deleted file mode 100644
index 49a45b6b13..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_segmentator.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <math.h>
-#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 = 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/authors b/contrib/python/matplotlib/py3/extern/agg24-svn/src/authors
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/authors
+++ /dev/null
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/copying b/contrib/python/matplotlib/py3/extern/agg24-svn/src/copying
deleted file mode 100644
index a08de15faa..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/copying
+++ /dev/null
@@ -1,11 +0,0 @@
-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.
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp
deleted file mode 100644
index 13a4c15af9..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp
+++ /dev/null
@@ -1,370 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 x, double y) 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 x, double y) 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp
deleted file mode 100644
index 3cf14f6a85..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp
deleted file mode 100644
index 7fd6448cd5..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp
+++ /dev/null
@@ -1,433 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp
deleted file mode 100644
index f720fddd8e..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp
deleted file mode 100644
index 40daee45e8..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp
+++ /dev/null
@@ -1,332 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 x, double y) 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 button_flag)
- {
- 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 x, double y)
- {
- bool ret = (m_node >= 0) || (m_edge >= 0);
- m_node = -1;
- m_edge = -1;
- return ret;
- }
-
-
- bool polygon_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up)
- {
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp
deleted file mode 100644
index 4e36b3b26b..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp
+++ /dev/null
@@ -1,325 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp
deleted file mode 100644
index 7f167792bd..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp
+++ /dev/null
@@ -1,454 +0,0 @@
-//----------------------------------------------------------------------------
-// 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;
- }
-
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp
deleted file mode 100644
index ad0048631c..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp
+++ /dev/null
@@ -1,349 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp
deleted file mode 100644
index 74808d4f87..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp
+++ /dev/null
@@ -1,407 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp
deleted file mode 100644
index b14d09cd1c..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp
+++ /dev/null
@@ -1,977 +0,0 @@
-//----------------------------------------------------------------------------
-// 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp
deleted file mode 100644
index 078e141ccb..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp
+++ /dev/null
@@ -1,990 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <stdio.h>
-
-#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 <string.h>
-#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) {
- sprintf(fAppPath, "%s", path.Path());
- } else {
- fprintf(stderr, "getting app parent folder failed: %s\n", strerror(ret));
- }
- } else {
- fprintf(stderr, "making app path failed: %s\n", strerror(ret));
- }
- } else {
- fprintf(stderr, "GetAppInfo() failed: %s\n", 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)
- {
- strcpy(m_caption, "Anti-Grain Geometry Application");
- }
-
-
- //------------------------------------------------------------------------
- platform_support::~platform_support()
- {
- delete m_specific;
- }
-
- //------------------------------------------------------------------------
- void platform_support::caption(const char* cap)
- {
- 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)
- {
- 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];
- 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()) {
- 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 {
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp
deleted file mode 100644
index 46b874d738..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp
+++ /dev/null
@@ -1,1601 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <time.h>
-#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;
- 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)
- {
- 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 = 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 = 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)
- {
- strcpy(m_caption, "AGG Application");
- }
-
- //------------------------------------------------------------------------
- platform_support::~platform_support()
- {
- delete m_specific;
- }
-
-
-
- //------------------------------------------------------------------------
- void platform_support::caption(const char* cap)
- {
- 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)
- {
- 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;
-
-//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))
-// {
-// // 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))
-// {
-// // 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)
- {
- 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)
- {
- fprintf(stderr,
- "RGB masks are not compatible with AGG pixel formats:\n"
- "R=%08x, R=%08x, B=%08x\n", r_mask, g_mask, b_mask);
- XCloseDisplay(m_specific->m_display);
- return false;
- }
-
-
-
- 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)];
-
- 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];
- strcpy(buf, file);
- int len = strlen(buf);
- if(len < 4 || strcasecmp(buf + len - 4, ".ppm") != 0)
- {
- strcat(buf, ".ppm");
- }
-
- FILE* fd = fopen(buf, "rb");
- if(fd == 0) return false;
-
- if((len = fread(buf, 1, 1022, fd)) == 0)
- {
- fclose(fd);
- return false;
- }
- buf[len] = 0;
-
- if(buf[0] != 'P' && buf[1] != '6')
- {
- fclose(fd);
- return false;
- }
-
- char* ptr = buf + 2;
-
- while(*ptr && !isdigit(*ptr)) ptr++;
- if(*ptr == 0)
- {
- fclose(fd);
- return false;
- }
-
- unsigned width = atoi(ptr);
- if(width == 0 || width > 4096)
- {
- fclose(fd);
- return false;
- }
- while(*ptr && isdigit(*ptr)) ptr++;
- while(*ptr && !isdigit(*ptr)) ptr++;
- if(*ptr == 0)
- {
- fclose(fd);
- return false;
- }
- unsigned height = atoi(ptr);
- if(height == 0 || height > 4096)
- {
- fclose(fd);
- return false;
- }
- while(*ptr && isdigit(*ptr)) ptr++;
- while(*ptr && !isdigit(*ptr)) ptr++;
- if(atoi(ptr) != 255)
- {
- fclose(fd);
- return false;
- }
- while(*ptr && isdigit(*ptr)) ptr++;
- if(*ptr == 0)
- {
- fclose(fd);
- return false;
- }
- ptr++;
- fseek(fd, long(ptr - buf), SEEK_SET);
-
- create_img(idx, width, height);
- bool ret = true;
-
- if(m_format == pix_format_rgb24)
- {
- fread(m_specific->m_buf_img[idx], 1, width * height * 3, fd);
- }
- 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);
-
- fread(buf_img, 1, width * height * 3, fd);
-
- 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;
- }
-
- 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];
- strcpy(buf, file);
- int len = strlen(buf);
- if(len < 4 || strcasecmp(buf + len - 4, ".ppm") != 0)
- {
- strcat(buf, ".ppm");
- }
-
- FILE* fd = fopen(buf, "wb");
- if(fd == 0) return false;
-
- unsigned w = rbuf_img(idx).width();
- unsigned h = rbuf_img(idx).height();
-
- 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;
- }
- fwrite(tmp_buf, 1, w * 3, fd);
- }
- delete [] tmp_buf;
- 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)
- {
- fprintf(stderr, "%s\n", msg);
- }
-
- //------------------------------------------------------------------------
- void platform_support::start_timer()
- {
- m_specific->m_sw_start = clock();
- }
-
- //------------------------------------------------------------------------
- double platform_support::elapsed_time() const
- {
- clock_t stop = 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp
deleted file mode 100644
index dc85fd69ff..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp
+++ /dev/null
@@ -1,298 +0,0 @@
-//----------------------------------------------------------------------------
-//
-//----------------------------------------------------------------------------
-// Contact: mcseemagg@yahoo.com
-// baer@karto.baug.ethz.ch
-//----------------------------------------------------------------------------
-//
-// class pixel_map
-//
-//----------------------------------------------------------------------------
-
-#include <string.h>
-#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)
- {
- memset(m_buf, clear_val, m_img_size);
- }
- }
-
-
-
- //------------------------------------------------------------------------
- void pixel_map::clear(unsigned clear_val)
- {
- if(m_buf) 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp
deleted file mode 100644
index f518dbe1f2..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp
+++ /dev/null
@@ -1,1053 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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)
- {
- 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)
- {
- strcpy(m_caption, "Anti-Grain Geometry Application");
- }
-
-
- //------------------------------------------------------------------------
- platform_support::~platform_support()
- {
- delete m_specific;
- }
-
-
-
- //------------------------------------------------------------------------
- void platform_support::caption(const char* cap)
- {
- 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];
- strcpy(fn, file);
- int len = 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
- {
- 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];
- strcpy(fn, file);
- int len = 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
- {
- 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 && strncmp (argv[1], "-psn", 4) == 0 ) {
- argc = 1;
- }
-
-launch:
- return agg_main(argc, argv);
-} \ No newline at end of file
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp
deleted file mode 100644
index 28c6436baa..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp
+++ /dev/null
@@ -1,708 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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)
- {
- 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);
- strcpy(m_caption, "Anti-Grain Geometry Application");
- }
-
-
- //------------------------------------------------------------------------
- platform_support::~platform_support()
- {
- delete m_specific;
- }
-
-
-
- //------------------------------------------------------------------------
- void platform_support::caption(const char* cap)
- {
- 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)
- {
- 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)
- {
- 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];
- strcpy(fn, file);
- int len = strlen(fn);
- if(len < 4 || strcmp(fn + len - 4, ".bmp") != 0)
- {
- strcat(fn, ".bmp");
- }
-
- SDL_Surface* tmp_surf = SDL_LoadBMP(fn);
- if (tmp_surf == 0)
- {
- 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];
- strcpy(fn, file);
- int len = strlen(fn);
- if(len < 4 || strcmp(fn + len - 4, ".bmp") != 0)
- {
- 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)
- {
- 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)
- {
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp
deleted file mode 100644
index ea9123802f..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp
+++ /dev/null
@@ -1,1655 +0,0 @@
-//----------------------------------------------------------------------------
-// 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 <string.h>
-#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)
- {
- strcpy(m_caption, "Anti-Grain Geometry Application");
- }
-
-
- //------------------------------------------------------------------------
- platform_support::~platform_support()
- {
- delete m_specific;
- }
-
-
-
- //------------------------------------------------------------------------
- void platform_support::caption(const char* cap)
- {
- 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];
- strcpy(fn, file);
- int len = strlen(fn);
- if(len < 4 || _stricmp(fn + len - 4, ".BMP") != 0)
- {
- 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];
- strcpy(fn, file);
- int len = strlen(fn);
- if(len < 4 || _stricmp(fn + len - 4, ".BMP") != 0)
- {
- 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 qotation: find one of separator symbols
- if(quote_chr == 0)
- {
- if(sep_len == 1)
- {
- found = check_chr(m_sep, c);
- }
- else
- {
- found = 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 [strlen(lpszCmdLine) + 3];
- char* argv_ptr = argv_str;
-
- char* argv[64];
- 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)
- {
- 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/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp
deleted file mode 100644
index 8c3bdc83fd..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp
+++ /dev/null
@@ -1,631 +0,0 @@
-//----------------------------------------------------------------------------
-//
-//----------------------------------------------------------------------------
-// Contact: mcseemagg@yahoo.com
-//----------------------------------------------------------------------------
-//
-// class pixel_map
-//
-//----------------------------------------------------------------------------
-
-#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)
- {
- 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)
- {
- memset(m_buf, clear_val, m_img_size);
- }
- return h_bitmap;
- }
-
-
-
- //------------------------------------------------------------------------
- void pixel_map::clear(unsigned clear_val)
- {
- if(m_buf) 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;
-
- fread(&bmf, sizeof(bmf), 1, fd);
- if(bmf.bfType != 0x4D42) goto bmperr;
-
- bmp_size = bmf.bfSize - sizeof(BITMAPFILEHEADER);
-
- bmi = (BITMAPINFO*) new unsigned char [bmp_size];
- if(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 = fopen(filename, "rb");
- bool ret = false;
- if(fd)
- {
- ret = load_from_bmp(fd);
- 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;
-
- fwrite(&bmf, sizeof(bmf), 1, fd);
- fwrite(m_bmp, m_full_size, 1, fd);
- return true;
- }
-
-
-
- //------------------------------------------------------------------------
- bool pixel_map::save_as_bmp(const char *filename) const
- {
- FILE *fd = fopen(filename, "wb");
- bool ret = false;
- if(fd)
- {
- ret = save_as_bmp(fd);
- 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;
- }
-}
-
-
-
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/ya.make b/contrib/python/matplotlib/py3/extern/agg24-svn/ya.make
deleted file mode 100644
index 6dd0f2d6f0..0000000000
--- a/contrib/python/matplotlib/py3/extern/agg24-svn/ya.make
+++ /dev/null
@@ -1,24 +0,0 @@
-LIBRARY()
-
-VERSION(Service-proxy-version)
-
-LICENSE(PSF-2.0)
-
-ADDINCL(
- contrib/python/matplotlib/py3/extern/agg24-svn/include
-)
-
-NO_COMPILER_WARNINGS()
-
-SRCS(
- src/agg_bezier_arc.cpp
- src/agg_curves.cpp
- src/agg_image_filters.cpp
- src/agg_trans_affine.cpp
- src/agg_vcgen_contour.cpp
- src/agg_vcgen_dash.cpp
- src/agg_vcgen_stroke.cpp
- src/agg_vpgen_segmentator.cpp
-)
-
-END()
diff --git a/contrib/python/matplotlib/py3/extern/ttconv/pprdrv.h b/contrib/python/matplotlib/py3/extern/ttconv/pprdrv.h
deleted file mode 100644
index 8c0b6c1955..0000000000
--- a/contrib/python/matplotlib/py3/extern/ttconv/pprdrv.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/*
- * Modified for use within matplotlib
- * 5 July 2007
- * Michael Droettboom
- */
-
-/*
-** ~ppr/src/include/pprdrv.h
-** Copyright 1995, Trinity College Computing Center.
-** Written by David Chappell.
-**
-** Permission to use, copy, modify, and distribute this software and its
-** documentation for any purpose and without fee is hereby granted, provided
-** that the above copyright notice appear in all copies and that both that
-** copyright notice and this permission notice appear in supporting
-** documentation. This software is provided "as is" without express or
-** implied warranty.
-**
-** This file last revised 5 December 1995.
-*/
-
-#include <vector>
-#include <cassert>
-
-/*
- * Encapsulates all of the output to write to an arbitrary output
- * function. This both removes the hardcoding of output to go to stdout
- * and makes output thread-safe. Michael Droettboom [06-07-07]
- */
-class TTStreamWriter
-{
- private:
- // Private copy and assignment
- TTStreamWriter& operator=(const TTStreamWriter& other);
- TTStreamWriter(const TTStreamWriter& other);
-
- public:
- TTStreamWriter() { }
- virtual ~TTStreamWriter() { }
-
- virtual void write(const char*) = 0;
-
- virtual void printf(const char* format, ...);
- virtual void put_char(int val);
- virtual void puts(const char* a);
- virtual void putline(const char* a);
-};
-
-void replace_newlines_with_spaces(char* a);
-
-/*
- * A simple class for all ttconv exceptions.
- */
-class TTException
-{
- const char* message;
- TTException& operator=(const TTStreamWriter& other);
- TTException(const TTStreamWriter& other);
-
-public:
- TTException(const char* message_) : message(message_) { }
- const char* getMessage()
- {
- return message;
- }
-};
-
-/*
-** No debug code will be included if this
-** is not defined:
-*/
-/* #define DEBUG 1 */
-
-/*
-** Uncomment the defines for the debugging
-** code you want to have included.
-*/
-#ifdef DEBUG
-#define DEBUG_TRUETYPE /* truetype fonts, conversion to Postscript */
-#endif
-
-#if DEBUG_TRUETYPE
-#define debug(...) printf(__VA_ARGS__)
-#else
-#define debug(...)
-#endif
-
-/* Do not change anything below this line. */
-
-enum font_type_enum
-{
- PS_TYPE_3 = 3,
- PS_TYPE_42 = 42,
- PS_TYPE_42_3_HYBRID = 43,
-};
-
-/* routines in pprdrv_tt.c */
-void insert_ttfont(const char *filename, TTStreamWriter& stream, font_type_enum target_type, std::vector<int>& glyph_ids);
-
-/* end of file */
diff --git a/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt.cpp b/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt.cpp
deleted file mode 100644
index a0c724c8aa..0000000000
--- a/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt.cpp
+++ /dev/null
@@ -1,1401 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/*
- * Modified for use within matplotlib
- * 5 July 2007
- * Michael Droettboom
- */
-
-/*
-** ~ppr/src/pprdrv/pprdrv_tt.c
-** Copyright 1995, Trinity College Computing Center.
-** Written by David Chappell.
-**
-** Permission to use, copy, modify, and distribute this software and its
-** documentation for any purpose and without fee is hereby granted, provided
-** that the above copyright notice appear in all copies and that both that
-** copyright notice and this permission notice appear in supporting
-** documentation. This software is provided "as is" without express or
-** implied warranty.
-**
-** TrueType font support. These functions allow PPR to generate
-** PostScript fonts from Microsoft compatible TrueType font files.
-**
-** Last revised 19 December 1995.
-*/
-
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include "pprdrv.h"
-#include "truetype.h"
-#include <sstream>
-#ifdef _POSIX_C_SOURCE
-# undef _POSIX_C_SOURCE
-#endif
-#ifndef _AIX
-#ifdef _XOPEN_SOURCE
-# undef _XOPEN_SOURCE
-#endif
-#endif
-#include <Python.h>
-
-/*==========================================================================
-** Convert the indicated Truetype font file to a type 42 or type 3
-** PostScript font and insert it in the output stream.
-**
-** All the routines from here to the end of file file are involved
-** in this process.
-==========================================================================*/
-
-/*---------------------------------------
-** Endian conversion routines.
-** These routines take a BYTE pointer
-** and return a value formed by reading
-** bytes starting at that point.
-**
-** These routines read the big-endian
-** values which are used in TrueType
-** font files.
----------------------------------------*/
-
-/*
-** Get an Unsigned 32 bit number.
-*/
-ULONG getULONG(BYTE *p)
-{
- int x;
- ULONG val=0;
-
- for (x=0; x<4; x++)
- {
- val *= 0x100;
- val += p[x];
- }
-
- return val;
-} /* end of ftohULONG() */
-
-/*
-** Get an unsigned 16 bit number.
-*/
-USHORT getUSHORT(BYTE *p)
-{
- int x;
- USHORT val=0;
-
- for (x=0; x<2; x++)
- {
- val *= 0x100;
- val += p[x];
- }
-
- return val;
-} /* end of getUSHORT() */
-
-/*
-** Get a 32 bit fixed point (16.16) number.
-** A special structure is used to return the value.
-*/
-Fixed getFixed(BYTE *s)
-{
- Fixed val={0,0};
-
- val.whole = ((s[0] * 256) + s[1]);
- val.fraction = ((s[2] * 256) + s[3]);
-
- return val;
-} /* end of getFixed() */
-
-/*-----------------------------------------------------------------------
-** Load a TrueType font table into memory and return a pointer to it.
-** The font's "file" and "offset_table" fields must be set before this
-** routine is called.
-**
-** This first argument is a TrueType font structure, the second
-** argument is the name of the table to retrieve. A table name
-** is always 4 characters, though the last characters may be
-** padding spaces.
------------------------------------------------------------------------*/
-BYTE *GetTable(struct TTFONT *font, const char *name)
-{
- BYTE *ptr;
- ULONG x;
- debug("GetTable(file,font,\"%s\")",name);
-
- /* We must search the table directory. */
- ptr = font->offset_table + 12;
- x=0;
- while (true)
- {
- if ( strncmp((const char*)ptr,name,4) == 0 )
- {
- ULONG offset,length;
- BYTE *table;
-
- offset = getULONG( ptr + 8 );
- length = getULONG( ptr + 12 );
- table = (BYTE*)calloc( sizeof(BYTE), length + 2 );
-
- try
- {
- debug("Loading table \"%s\" from offset %d, %d bytes",name,offset,length);
-
- if ( fseek( font->file, (long)offset, SEEK_SET ) )
- {
- throw TTException("TrueType font may be corrupt (reason 3)");
- }
-
- if ( fread(table,sizeof(BYTE),length,font->file) != (sizeof(BYTE) * length))
- {
- throw TTException("TrueType font may be corrupt (reason 4)");
- }
- }
- catch (TTException& )
- {
- free(table);
- throw;
- }
- /* Always NUL-terminate; add two in case of UTF16 strings. */
- table[length] = '\0';
- table[length + 1] = '\0';
- return table;
- }
-
- x++;
- ptr += 16;
- if (x == font->numTables)
- {
- throw TTException("TrueType font is missing table");
- }
- }
-
-} /* end of GetTable() */
-
-static void utf16be_to_ascii(char *dst, char *src, size_t length) {
- ++src;
- for (; *src != 0 && length; dst++, src += 2, --length) {
- *dst = *src;
- }
-}
-
-/*--------------------------------------------------------------------
-** Load the 'name' table, get information from it,
-** and store that information in the font structure.
-**
-** The 'name' table contains information such as the name of
-** the font, and it's PostScript name.
---------------------------------------------------------------------*/
-void Read_name(struct TTFONT *font)
-{
- BYTE *table_ptr,*ptr2;
- int numrecords; /* Number of strings in this table */
- BYTE *strings; /* pointer to start of string storage */
- int x;
- int platform; /* Current platform id */
- int nameid; /* name id, */
- int offset,length; /* offset and length of string. */
- debug("Read_name()");
-
- table_ptr = NULL;
-
- /* Set default values to avoid future references to undefined
- * pointers. Allocate each of PostName, FullName, FamilyName,
- * Version, and Style separately so they can be freed safely. */
- for (char **ptr = &(font->PostName); ptr != NULL; )
- {
- *ptr = (char*) calloc(sizeof(char), strlen("unknown")+1);
- strcpy(*ptr, "unknown");
- if (ptr == &(font->PostName)) ptr = &(font->FullName);
- else if (ptr == &(font->FullName)) ptr = &(font->FamilyName);
- else if (ptr == &(font->FamilyName)) ptr = &(font->Version);
- else if (ptr == &(font->Version)) ptr = &(font->Style);
- else ptr = NULL;
- }
- font->Copyright = font->Trademark = (char*)NULL;
-
- table_ptr = GetTable(font, "name"); /* pointer to table */
- try
- {
- numrecords = getUSHORT( table_ptr + 2 ); /* number of names */
- strings = table_ptr + getUSHORT( table_ptr + 4 ); /* start of string storage */
-
- ptr2 = table_ptr + 6;
- for (x=0; x < numrecords; x++,ptr2+=12)
- {
- platform = getUSHORT(ptr2);
- nameid = getUSHORT(ptr2+6);
- length = getUSHORT(ptr2+8);
- offset = getUSHORT(ptr2+10);
- debug("platform %d, encoding %d, language 0x%x, name %d, offset %d, length %d",
- platform,encoding,language,nameid,offset,length);
-
- /* Copyright notice */
- if ( platform == 1 && nameid == 0 )
- {
- font->Copyright = (char*)calloc(sizeof(char),length+1);
- strncpy(font->Copyright,(const char*)strings+offset,length);
- font->Copyright[length]='\0';
- replace_newlines_with_spaces(font->Copyright);
- debug("font->Copyright=\"%s\"",font->Copyright);
- continue;
- }
-
-
- /* Font Family name */
- if ( platform == 1 && nameid == 1 )
- {
- free(font->FamilyName);
- font->FamilyName = (char*)calloc(sizeof(char),length+1);
- strncpy(font->FamilyName,(const char*)strings+offset,length);
- font->FamilyName[length]='\0';
- replace_newlines_with_spaces(font->FamilyName);
- debug("font->FamilyName=\"%s\"",font->FamilyName);
- continue;
- }
-
-
- /* Font Family name */
- if ( platform == 1 && nameid == 2 )
- {
- free(font->Style);
- font->Style = (char*)calloc(sizeof(char),length+1);
- strncpy(font->Style,(const char*)strings+offset,length);
- font->Style[length]='\0';
- replace_newlines_with_spaces(font->Style);
- debug("font->Style=\"%s\"",font->Style);
- continue;
- }
-
-
- /* Full Font name */
- if ( platform == 1 && nameid == 4 )
- {
- free(font->FullName);
- font->FullName = (char*)calloc(sizeof(char),length+1);
- strncpy(font->FullName,(const char*)strings+offset,length);
- font->FullName[length]='\0';
- replace_newlines_with_spaces(font->FullName);
- debug("font->FullName=\"%s\"",font->FullName);
- continue;
- }
-
-
- /* Version string */
- if ( platform == 1 && nameid == 5 )
- {
- free(font->Version);
- font->Version = (char*)calloc(sizeof(char),length+1);
- strncpy(font->Version,(const char*)strings+offset,length);
- font->Version[length]='\0';
- replace_newlines_with_spaces(font->Version);
- debug("font->Version=\"%s\"",font->Version);
- continue;
- }
-
-
- /* PostScript name */
- if ( platform == 1 && nameid == 6 )
- {
- free(font->PostName);
- font->PostName = (char*)calloc(sizeof(char),length+1);
- strncpy(font->PostName,(const char*)strings+offset,length);
- font->PostName[length]='\0';
- replace_newlines_with_spaces(font->PostName);
- debug("font->PostName=\"%s\"",font->PostName);
- continue;
- }
-
- /* Microsoft-format PostScript name */
- if ( platform == 3 && nameid == 6 )
- {
- free(font->PostName);
- font->PostName = (char*)calloc(sizeof(char),length+1);
- utf16be_to_ascii(font->PostName, (char *)strings+offset, length);
- font->PostName[length/2]='\0';
- replace_newlines_with_spaces(font->PostName);
- debug("font->PostName=\"%s\"",font->PostName);
- continue;
- }
-
-
- /* Trademark string */
- if ( platform == 1 && nameid == 7 )
- {
- font->Trademark = (char*)calloc(sizeof(char),length+1);
- strncpy(font->Trademark,(const char*)strings+offset,length);
- font->Trademark[length]='\0';
- replace_newlines_with_spaces(font->Trademark);
- debug("font->Trademark=\"%s\"",font->Trademark);
- continue;
- }
- }
- }
- catch (TTException& )
- {
- free(table_ptr);
- throw;
- }
-
- free(table_ptr);
-} /* end of Read_name() */
-
-/*---------------------------------------------------------------------
-** Write the header for a PostScript font.
----------------------------------------------------------------------*/
-void ttfont_header(TTStreamWriter& stream, struct TTFONT *font)
-{
- int VMMin;
- int VMMax;
-
- /*
- ** To show that it is a TrueType font in PostScript format,
- ** we will begin the file with a specific string.
- ** This string also indicates the version of the TrueType
- ** specification on which the font is based and the
- ** font manufacturer's revision number for the font.
- */
- if ( font->target_type == PS_TYPE_42 ||
- font->target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.printf("%%!PS-TrueTypeFont-%d.%d-%d.%d\n",
- font->TTVersion.whole, font->TTVersion.fraction,
- font->MfrRevision.whole, font->MfrRevision.fraction);
- }
-
- /* If it is not a Type 42 font, we will use a different format. */
- else
- {
- stream.putline("%!PS-Adobe-3.0 Resource-Font");
- } /* See RBIIp 641 */
-
- /* We will make the title the name of the font. */
- stream.printf("%%%%Title: %s\n",font->FullName);
-
- /* If there is a Copyright notice, put it here too. */
- if ( font->Copyright != (char*)NULL )
- {
- stream.printf("%%%%Copyright: %s\n",font->Copyright);
- }
-
- /* We created this file. */
- if ( font->target_type == PS_TYPE_42 )
- {
- stream.putline("%%Creator: Converted from TrueType to type 42 by PPR");
- }
- else if (font->target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.putline("%%Creator: Converted from TypeType to type 42/type 3 hybrid by PPR");
- }
- else
- {
- stream.putline("%%Creator: Converted from TrueType to type 3 by PPR");
- }
-
- /* If VM usage information is available, print it. */
- if ( font->target_type == PS_TYPE_42 || font->target_type == PS_TYPE_42_3_HYBRID)
- {
- VMMin = (int)getULONG( font->post_table + 16 );
- VMMax = (int)getULONG( font->post_table + 20 );
- if ( VMMin > 0 && VMMax > 0 )
- stream.printf("%%%%VMUsage: %d %d\n",VMMin,VMMax);
- }
-
- /* Start the dictionary which will eventually */
- /* become the font. */
- if (font->target_type == PS_TYPE_42)
- {
- stream.putline("15 dict begin");
- }
- else
- {
- stream.putline("25 dict begin");
-
- /* Type 3 fonts will need some subroutines here. */
- stream.putline("/_d{bind def}bind def");
- stream.putline("/_m{moveto}_d");
- stream.putline("/_l{lineto}_d");
- stream.putline("/_cl{closepath eofill}_d");
- stream.putline("/_c{curveto}_d");
- stream.putline("/_sc{7 -1 roll{setcachedevice}{pop pop pop pop pop pop}ifelse}_d");
- stream.putline("/_e{exec}_d");
- }
-
- stream.printf("/FontName /%s def\n",font->PostName);
- stream.putline("/PaintType 0 def");
-
- if (font->target_type == PS_TYPE_42 || font->target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.putline("/FontMatrix[1 0 0 1 0 0]def");
- }
- else
- {
- stream.putline("/FontMatrix[.001 0 0 .001 0 0]def");
- }
-
- stream.printf("/FontBBox[%d %d %d %d]def\n",font->llx-1,font->lly-1,font->urx,font->ury);
- if (font->target_type == PS_TYPE_42 || font->target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.printf("/FontType 42 def\n", font->target_type );
- }
- else
- {
- stream.printf("/FontType 3 def\n", font->target_type );
- }
-} /* end of ttfont_header() */
-
-/*-------------------------------------------------------------
-** Define the encoding array for this font.
-** Since we don't really want to deal with converting all of
-** the possible font encodings in the wild to a standard PS
-** one, we just explicitly create one for each font.
--------------------------------------------------------------*/
-void ttfont_encoding(TTStreamWriter& stream, struct TTFONT *font, std::vector<int>& glyph_ids, font_type_enum target_type)
-{
- if (target_type == PS_TYPE_3 || target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.printf("/Encoding [ ");
-
- for (std::vector<int>::const_iterator i = glyph_ids.begin();
- i != glyph_ids.end(); ++i)
- {
- const char* name = ttfont_CharStrings_getname(font, *i);
- stream.printf("/%s ", name);
- }
-
- stream.printf("] def\n");
- }
- else
- {
- stream.putline("/Encoding StandardEncoding def");
- }
-} /* end of ttfont_encoding() */
-
-/*-----------------------------------------------------------
-** Create the optional "FontInfo" sub-dictionary.
------------------------------------------------------------*/
-void ttfont_FontInfo(TTStreamWriter& stream, struct TTFONT *font)
-{
- Fixed ItalicAngle;
-
- /* We create a sub dictionary named "FontInfo" where we */
- /* store information which though it is not used by the */
- /* interpreter, is useful to some programs which will */
- /* be printing with the font. */
- stream.putline("/FontInfo 10 dict dup begin");
-
- /* These names come from the TrueType font's "name" table. */
- stream.printf("/FamilyName (%s) def\n",font->FamilyName);
- stream.printf("/FullName (%s) def\n",font->FullName);
-
- if ( font->Copyright != (char*)NULL || font->Trademark != (char*)NULL )
- {
- stream.printf("/Notice (%s",
- font->Copyright != (char*)NULL ? font->Copyright : "");
- stream.printf("%s%s) def\n",
- font->Trademark != (char*)NULL ? " " : "",
- font->Trademark != (char*)NULL ? font->Trademark : "");
- }
-
- /* This information is not quite correct. */
- stream.printf("/Weight (%s) def\n",font->Style);
-
- /* Some fonts have this as "version". */
- stream.printf("/Version (%s) def\n",font->Version);
-
- /* Some information from the "post" table. */
- ItalicAngle = getFixed( font->post_table + 4 );
- stream.printf("/ItalicAngle %d.%d def\n",ItalicAngle.whole,ItalicAngle.fraction);
- stream.printf("/isFixedPitch %s def\n", getULONG( font->post_table + 12 ) ? "true" : "false" );
- stream.printf("/UnderlinePosition %d def\n", (int)getFWord( font->post_table + 8 ) );
- stream.printf("/UnderlineThickness %d def\n", (int)getFWord( font->post_table + 10 ) );
- stream.putline("end readonly def");
-} /* end of ttfont_FontInfo() */
-
-/*-------------------------------------------------------------------
-** sfnts routines
-** These routines generate the PostScript "sfnts" array which
-** contains one or more strings which contain a reduced version
-** of the TrueType font.
-**
-** A number of functions are required to accomplish this rather
-** complicated task.
--------------------------------------------------------------------*/
-int string_len;
-int line_len;
-bool in_string;
-
-/*
-** This is called once at the start.
-*/
-void sfnts_start(TTStreamWriter& stream)
-{
- stream.puts("/sfnts[<");
- in_string=true;
- string_len=0;
- line_len=8;
-} /* end of sfnts_start() */
-
-/*
-** Write a BYTE as a hexadecimal value as part of the sfnts array.
-*/
-void sfnts_pputBYTE(TTStreamWriter& stream, BYTE n)
-{
- static const char hexdigits[]="0123456789ABCDEF";
-
- if (!in_string)
- {
- stream.put_char('<');
- string_len=0;
- line_len++;
- in_string=true;
- }
-
- stream.put_char( hexdigits[ n / 16 ] );
- stream.put_char( hexdigits[ n % 16 ] );
- string_len++;
- line_len+=2;
-
- if (line_len > 70)
- {
- stream.put_char('\n');
- line_len=0;
- }
-
-} /* end of sfnts_pputBYTE() */
-
-/*
-** Write a USHORT as a hexadecimal value as part of the sfnts array.
-*/
-void sfnts_pputUSHORT(TTStreamWriter& stream, USHORT n)
-{
- sfnts_pputBYTE(stream, n / 256);
- sfnts_pputBYTE(stream, n % 256);
-} /* end of sfnts_pputUSHORT() */
-
-/*
-** Write a ULONG as part of the sfnts array.
-*/
-void sfnts_pputULONG(TTStreamWriter& stream, ULONG n)
-{
- int x1,x2,x3;
-
- x1 = n % 256;
- n /= 256;
- x2 = n % 256;
- n /= 256;
- x3 = n % 256;
- n /= 256;
-
- sfnts_pputBYTE(stream, n);
- sfnts_pputBYTE(stream, x3);
- sfnts_pputBYTE(stream, x2);
- sfnts_pputBYTE(stream, x1);
-} /* end of sfnts_pputULONG() */
-
-/*
-** This is called whenever it is
-** necessary to end a string in the sfnts array.
-**
-** (The array must be broken into strings which are
-** no longer than 64K characters.)
-*/
-void sfnts_end_string(TTStreamWriter& stream)
-{
- if (in_string)
- {
- string_len=0; /* fool sfnts_pputBYTE() */
-
-#ifdef DEBUG_TRUETYPE_INLINE
- puts("\n% dummy byte:\n");
-#endif
-
- sfnts_pputBYTE(stream, 0); /* extra byte for pre-2013 compatibility */
- stream.put_char('>');
- line_len++;
- }
- in_string=false;
-} /* end of sfnts_end_string() */
-
-/*
-** This is called at the start of each new table.
-** The argement is the length in bytes of the table
-** which will follow. If the new table will not fit
-** in the current string, a new one is started.
-*/
-void sfnts_new_table(TTStreamWriter& stream, ULONG length)
-{
- if ( (string_len + length) > 65528 )
- sfnts_end_string(stream);
-} /* end of sfnts_new_table() */
-
-/*
-** We may have to break up the 'glyf' table. That is the reason
-** why we provide this special routine to copy it into the sfnts
-** array.
-*/
-void sfnts_glyf_table(TTStreamWriter& stream, struct TTFONT *font, ULONG oldoffset, ULONG correct_total_length)
-{
- ULONG off;
- ULONG length;
- int c;
- ULONG total=0; /* running total of bytes written to table */
- int x;
- bool loca_is_local=false;
- debug("sfnts_glyf_table(font,%d)", (int)correct_total_length);
-
- if (font->loca_table == NULL)
- {
- font->loca_table = GetTable(font,"loca");
- loca_is_local = true;
- }
-
- /* Seek to proper position in the file. */
- fseek( font->file, oldoffset, SEEK_SET );
-
- /* Copy the glyphs one by one */
- for (x=0; x < font->numGlyphs; x++)
- {
- /* Read the glyph offset from the index-to-location table. */
- if (font->indexToLocFormat == 0)
- {
- off = getUSHORT( font->loca_table + (x * 2) );
- off *= 2;
- length = getUSHORT( font->loca_table + ((x+1) * 2) );
- length *= 2;
- length -= off;
- }
- else
- {
- off = getULONG( font->loca_table + (x * 4) );
- length = getULONG( font->loca_table + ((x+1) * 4) );
- length -= off;
- }
- debug("glyph length=%d",(int)length);
-
- /* Start new string if necessary. */
- sfnts_new_table( stream, (int)length );
-
- /*
- ** Make sure the glyph is padded out to a
- ** two byte boundary.
- */
- if ( length % 2 ) {
- throw TTException("TrueType font contains a 'glyf' table without 2 byte padding");
- }
-
- /* Copy the bytes of the glyph. */
- while ( length-- )
- {
- if ( (c = fgetc(font->file)) == EOF ) {
- throw TTException("TrueType font may be corrupt (reason 6)");
- }
-
- sfnts_pputBYTE(stream, c);
- total++; /* add to running total */
- }
-
- }
-
- if (loca_is_local)
- {
- free(font->loca_table);
- font->loca_table = NULL;
- }
-
- /* Pad out to full length from table directory */
- while ( total < correct_total_length )
- {
- sfnts_pputBYTE(stream, 0);
- total++;
- }
-
-} /* end of sfnts_glyf_table() */
-
-/*
-** Here is the routine which ties it all together.
-**
-** Create the array called "sfnts" which
-** holds the actual TrueType data.
-*/
-void ttfont_sfnts(TTStreamWriter& stream, struct TTFONT *font)
-{
- static const char *table_names[] = /* The names of all tables */
- {
- /* which it is worth while */
- "cvt ", /* to include in a Type 42 */
- "fpgm", /* PostScript font. */
- "glyf",
- "head",
- "hhea",
- "hmtx",
- "loca",
- "maxp",
- "prep"
- } ;
-
- struct /* The location of each of */
- {
- ULONG oldoffset; /* the above tables. */
- ULONG newoffset;
- ULONG length;
- ULONG checksum;
- } tables[9];
-
- BYTE *ptr; /* A pointer into the origional table directory. */
- ULONG x,y; /* General use loop countes. */
- int c; /* Input character. */
- int diff;
- ULONG nextoffset;
- int count; /* How many `important' tables did we find? */
-
- ptr = font->offset_table + 12;
- nextoffset=0;
- count=0;
-
- /*
- ** Find the tables we want and store there vital
- ** statistics in tables[].
- */
- ULONG num_tables_read = 0; /* Number of tables read from the directory */
- for (x = 0; x < 9; x++) {
- do {
- if (num_tables_read < font->numTables) {
- /* There are still tables to read from ptr */
- diff = strncmp((char*)ptr, table_names[x], 4);
-
- if (diff > 0) { /* If we are past it. */
- tables[x].length = 0;
- diff = 0;
- } else if (diff < 0) { /* If we haven't hit it yet. */
- ptr += 16;
- num_tables_read++;
- } else if (diff == 0) { /* Here it is! */
- tables[x].newoffset = nextoffset;
- tables[x].checksum = getULONG( ptr + 4 );
- tables[x].oldoffset = getULONG( ptr + 8 );
- tables[x].length = getULONG( ptr + 12 );
- nextoffset += ( ((tables[x].length + 3) / 4) * 4 );
- count++;
- ptr += 16;
- num_tables_read++;
- }
- } else {
- /* We've read the whole table directory already */
- /* Some tables couldn't be found */
- tables[x].length = 0;
- break; /* Proceed to next tables[x] */
- }
- } while (diff != 0);
-
- } /* end of for loop which passes over the table directory */
-
- /* Begin the sfnts array. */
- sfnts_start(stream);
-
- /* Generate the offset table header */
- /* Start by copying the TrueType version number. */
- ptr = font->offset_table;
- for (x=0; x < 4; x++)
- {
- sfnts_pputBYTE( stream, *(ptr++) );
- }
-
- /* Now, generate those silly numTables numbers. */
- sfnts_pputUSHORT(stream, count); /* number of tables */
-
- int search_range = 1;
- int entry_sel = 0;
-
- while (search_range <= count) {
- search_range <<= 1;
- entry_sel++;
- }
- entry_sel = entry_sel > 0 ? entry_sel - 1 : 0;
- search_range = (search_range >> 1) * 16;
- int range_shift = count * 16 - search_range;
-
- sfnts_pputUSHORT(stream, search_range); /* searchRange */
- sfnts_pputUSHORT(stream, entry_sel); /* entrySelector */
- sfnts_pputUSHORT(stream, range_shift); /* rangeShift */
-
- debug("only %d tables selected",count);
-
- /* Now, emmit the table directory. */
- for (x=0; x < 9; x++)
- {
- if ( tables[x].length == 0 ) /* Skip missing tables */
- {
- continue;
- }
-
- /* Name */
- sfnts_pputBYTE( stream, table_names[x][0] );
- sfnts_pputBYTE( stream, table_names[x][1] );
- sfnts_pputBYTE( stream, table_names[x][2] );
- sfnts_pputBYTE( stream, table_names[x][3] );
-
- /* Checksum */
- sfnts_pputULONG( stream, tables[x].checksum );
-
- /* Offset */
- sfnts_pputULONG( stream, tables[x].newoffset + 12 + (count * 16) );
-
- /* Length */
- sfnts_pputULONG( stream, tables[x].length );
- }
-
- /* Now, send the tables */
- for (x=0; x < 9; x++)
- {
- if ( tables[x].length == 0 ) /* skip tables that aren't there */
- {
- continue;
- }
- debug("emmiting table '%s'",table_names[x]);
-
- /* 'glyf' table gets special treatment */
- if ( strcmp(table_names[x],"glyf")==0 )
- {
- sfnts_glyf_table(stream,font,tables[x].oldoffset,tables[x].length);
- }
- else /* Other tables may not exceed */
- {
- /* 65535 bytes in length. */
- if ( tables[x].length > 65535 )
- {
- throw TTException("TrueType font has a table which is too long");
- }
-
- /* Start new string if necessary. */
- sfnts_new_table(stream, tables[x].length);
-
- /* Seek to proper position in the file. */
- fseek( font->file, tables[x].oldoffset, SEEK_SET );
-
- /* Copy the bytes of the table. */
- for ( y=0; y < tables[x].length; y++ )
- {
- if ( (c = fgetc(font->file)) == EOF )
- {
- throw TTException("TrueType font may be corrupt (reason 7)");
- }
-
- sfnts_pputBYTE(stream, c);
- }
- }
-
- /* Padd it out to a four byte boundary. */
- y=tables[x].length;
- while ( (y % 4) != 0 )
- {
- sfnts_pputBYTE(stream, 0);
- y++;
-#ifdef DEBUG_TRUETYPE_INLINE
- puts("\n% pad byte:\n");
-#endif
- }
-
- } /* End of loop for all tables */
-
- /* Close the array. */
- sfnts_end_string(stream);
- stream.putline("]def");
-} /* end of ttfont_sfnts() */
-
-/*--------------------------------------------------------------
-** Create the CharStrings dictionary which will translate
-** PostScript character names to TrueType font character
-** indexes.
-**
-** If we are creating a type 3 instead of a type 42 font,
-** this array will instead convert PostScript character names
-** to executable proceedures.
---------------------------------------------------------------*/
-const char *Apple_CharStrings[]=
-{
- ".notdef",".null","nonmarkingreturn","space","exclam","quotedbl","numbersign",
- "dollar","percent","ampersand","quotesingle","parenleft","parenright",
- "asterisk","plus", "comma","hyphen","period","slash","zero","one","two",
- "three","four","five","six","seven","eight","nine","colon","semicolon",
- "less","equal","greater","question","at","A","B","C","D","E","F","G","H","I",
- "J","K", "L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
- "bracketleft","backslash","bracketright","asciicircum","underscore","grave",
- "a","b","c","d","e","f","g","h","i","j","k", "l","m","n","o","p","q","r","s",
- "t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde",
- "Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis",
- "aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla",
- "eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex",
- "idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde",
- "uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent",
- "sterling","section","bullet","paragraph","germandbls","registered",
- "copyright","trademark","acute","dieresis","notequal","AE","Oslash",
- "infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff",
- "summation","product","pi","integral","ordfeminine","ordmasculine","Omega",
- "ae","oslash","questiondown","exclamdown","logicalnot","radical","florin",
- "approxequal","Delta","guillemotleft","guillemotright","ellipsis",
- "nobreakspace","Agrave","Atilde","Otilde","OE","oe","endash","emdash",
- "quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge",
- "ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright",
- "fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase",
- "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave",
- "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple",
- "Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde",
- "macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron",
- "Lslash","lslash","Scaron","scaron","Zcaron","zcaron","brokenbar","Eth","eth",
- "Yacute","yacute","Thorn","thorn","minus","multiply","onesuperior",
- "twosuperior","threesuperior","onehalf","onequarter","threequarters","franc",
- "Gbreve","gbreve","Idot","Scedilla","scedilla","Cacute","cacute","Ccaron",
- "ccaron","dmacron","markingspace","capslock","shift","propeller","enter",
- "markingtabrtol","markingtabltor","control","markingdeleteltor",
- "markingdeletertol","option","escape","parbreakltor","parbreakrtol",
- "newpage","checkmark","linebreakltor","linebreakrtol","markingnobreakspace",
- "diamond","appleoutline"
-};
-
-/*
-** This routine is called by the one below.
-** It is also called from pprdrv_tt2.c
-*/
-const char *ttfont_CharStrings_getname(struct TTFONT *font, int charindex)
-{
- int GlyphIndex;
- static char temp[80];
- char *ptr;
- ULONG len;
-
- Fixed post_format;
-
- /* The 'post' table format number. */
- post_format = getFixed( font->post_table );
-
- if ( post_format.whole != 2 || post_format.fraction != 0 )
- {
- /* We don't have a glyph name table, so generate a name.
- This generated name must match exactly the name that is
- generated by FT2Font in get_glyph_name */
- PyOS_snprintf(temp, 80, "uni%08x", charindex);
- return temp;
- }
-
- GlyphIndex = (int)getUSHORT( font->post_table + 34 + (charindex * 2) );
-
- if ( GlyphIndex <= 257 ) /* If a standard Apple name, */
- {
- return Apple_CharStrings[GlyphIndex];
- }
- else /* Otherwise, use one */
- {
- /* of the pascal strings. */
- GlyphIndex -= 258;
-
- /* Set pointer to start of Pascal strings. */
- ptr = (char*)(font->post_table + 34 + (font->numGlyphs * 2));
-
- len = (ULONG)*(ptr++); /* Step thru the strings */
- while (GlyphIndex--) /* until we get to the one */
- {
- /* that we want. */
- ptr += len;
- len = (ULONG)*(ptr++);
- }
-
- if ( len >= sizeof(temp) )
- {
- throw TTException("TrueType font file contains a very long PostScript name");
- }
-
- strncpy(temp,ptr,len); /* Copy the pascal string into */
- temp[len]='\0'; /* a buffer and make it ASCIIz. */
-
- return temp;
- }
-} /* end of ttfont_CharStrings_getname() */
-
-/*
-** This is the central routine of this section.
-*/
-void ttfont_CharStrings(TTStreamWriter& stream, struct TTFONT *font, std::vector<int>& glyph_ids)
-{
- Fixed post_format;
-
- /* The 'post' table format number. */
- post_format = getFixed( font->post_table );
-
- /* Emmit the start of the PostScript code to define the dictionary. */
- stream.printf("/CharStrings %d dict dup begin\n", glyph_ids.size()+1);
- /* Section 5.8.2 table 5.7 of the PS Language Ref says a CharStrings dictionary must contain an entry for .notdef */
- stream.printf("/.notdef 0 def\n");
-
- /* Emmit one key-value pair for each glyph. */
- for (std::vector<int>::const_iterator i = glyph_ids.begin();
- i != glyph_ids.end(); ++i)
- {
- if ((font->target_type == PS_TYPE_42 ||
- font->target_type == PS_TYPE_42_3_HYBRID)
- && *i < 256) /* type 42 */
- {
- stream.printf("/%s %d def\n",ttfont_CharStrings_getname(font, *i), *i);
- }
- else /* type 3 */
- {
- stream.printf("/%s{",ttfont_CharStrings_getname(font, *i));
-
- tt_type3_charproc(stream, font, *i);
-
- stream.putline("}_d"); /* "} bind def" */
- }
- }
-
- stream.putline("end readonly def");
-} /* end of ttfont_CharStrings() */
-
-/*----------------------------------------------------------------
-** Emmit the code to finish up the dictionary and turn
-** it into a font.
-----------------------------------------------------------------*/
-void ttfont_trailer(TTStreamWriter& stream, struct TTFONT *font)
-{
- /* If we are generating a type 3 font, we need to provide */
- /* a BuildGlyph and BuildChar proceedures. */
- if (font->target_type == PS_TYPE_3 ||
- font->target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.put_char('\n');
-
- stream.putline("/BuildGlyph");
- stream.putline(" {exch begin"); /* start font dictionary */
- stream.putline(" CharStrings exch");
- stream.putline(" 2 copy known not{pop /.notdef}if");
- stream.putline(" true 3 1 roll get exec");
- stream.putline(" end}_d");
-
- stream.put_char('\n');
-
- /* This proceedure is for compatibility with */
- /* level 1 interpreters. */
- stream.putline("/BuildChar {");
- stream.putline(" 1 index /Encoding get exch get");
- stream.putline(" 1 index /BuildGlyph get exec");
- stream.putline("}_d");
-
- stream.put_char('\n');
- }
-
- /* If we are generating a type 42 font, we need to check to see */
- /* if this PostScript interpreter understands type 42 fonts. If */
- /* it doesn't, we will hope that the Apple TrueType rasterizer */
- /* has been loaded and we will adjust the font accordingly. */
- /* I found out how to do this by examining a TrueType font */
- /* generated by a Macintosh. That is where the TrueType interpreter */
- /* setup instructions and part of BuildGlyph came from. */
- if (font->target_type == PS_TYPE_42 ||
- font->target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.put_char('\n');
-
- /* If we have no "resourcestatus" command, or FontType 42 */
- /* is unknown, leave "true" on the stack. */
- stream.putline("systemdict/resourcestatus known");
- stream.putline(" {42 /FontType resourcestatus");
- stream.putline(" {pop pop false}{true}ifelse}");
- stream.putline(" {true}ifelse");
-
- /* If true, execute code to produce an error message if */
- /* we can't find Apple's TrueDict in VM. */
- stream.putline("{/TrueDict where{pop}{(%%[ Error: no TrueType rasterizer ]%%)= flush}ifelse");
-
- /* Since we are expected to use Apple's TrueDict TrueType */
- /* reasterizer, change the font type to 3. */
- stream.putline("/FontType 3 def");
-
- /* Define a string to hold the state of the Apple */
- /* TrueType interpreter. */
- stream.putline(" /TrueState 271 string def");
-
- /* It looks like we get information about the resolution */
- /* of the printer and store it in the TrueState string. */
- stream.putline(" TrueDict begin sfnts save");
- stream.putline(" 72 0 matrix defaultmatrix dtransform dup");
- stream.putline(" mul exch dup mul add sqrt cvi 0 72 matrix");
- stream.putline(" defaultmatrix dtransform dup mul exch dup");
- stream.putline(" mul add sqrt cvi 3 -1 roll restore");
- stream.putline(" TrueState initer end");
-
- /* This BuildGlyph procedure will look the name up in the */
- /* CharStrings array, and then check to see if what it gets */
- /* is a procedure. If it is, it executes it, otherwise, it */
- /* lets the TrueType rasterizer loose on it. */
-
- /* When this proceedure is executed the stack contains */
- /* the font dictionary and the character name. We */
- /* exchange arguments and move the dictionary to the */
- /* dictionary stack. */
- stream.putline(" /BuildGlyph{exch begin");
- /* stack: charname */
-
- /* Put two copies of CharStrings on the stack and consume */
- /* one testing to see if the charname is defined in it, */
- /* leave the answer on the stack. */
- stream.putline(" CharStrings dup 2 index known");
- /* stack: charname CharStrings bool */
-
- /* Exchange the CharStrings dictionary and the charname, */
- /* but if the answer was false, replace the character name */
- /* with ".notdef". */
- stream.putline(" {exch}{exch pop /.notdef}ifelse");
- /* stack: CharStrings charname */
-
- /* Get the value from the CharStrings dictionary and see */
- /* if it is executable. */
- stream.putline(" get dup xcheck");
- /* stack: CharStrings_entry */
-
- /* If is a proceedure. Execute according to RBIIp 277-278. */
- stream.putline(" {currentdict systemdict begin begin exec end end}");
-
- /* Is a TrueType character index, let the rasterizer at it. */
- stream.putline(" {TrueDict begin /bander load cvlit exch TrueState render end}");
-
- stream.putline(" ifelse");
-
- /* Pop the font's dictionary off the stack. */
- stream.putline(" end}bind def");
-
- /* This is the level 1 compatibility BuildChar procedure. */
- /* See RBIIp 281. */
- stream.putline(" /BuildChar{");
- stream.putline(" 1 index /Encoding get exch get");
- stream.putline(" 1 index /BuildGlyph get exec");
- stream.putline(" }bind def");
-
- /* Here we close the condition which is true */
- /* if the printer has no built-in TrueType */
- /* rasterizer. */
- stream.putline("}if");
- stream.put_char('\n');
- } /* end of if Type 42 not understood. */
-
- stream.putline("FontName currentdict end definefont pop");
- /* stream.putline("%%EOF"); */
-} /* end of ttfont_trailer() */
-
-/*------------------------------------------------------------------
-** This is the externally callable routine which inserts the font.
-------------------------------------------------------------------*/
-
-void read_font(const char *filename, font_type_enum target_type, std::vector<int>& glyph_ids, TTFONT& font)
-{
- BYTE *ptr;
-
- /* Decide what type of PostScript font we will be generating. */
- font.target_type = target_type;
-
- if (font.target_type == PS_TYPE_42)
- {
- bool has_low = false;
- bool has_high = false;
-
- for (std::vector<int>::const_iterator i = glyph_ids.begin();
- i != glyph_ids.end(); ++i)
- {
- if (*i > 255)
- {
- has_high = true;
- if (has_low) break;
- }
- else
- {
- has_low = true;
- if (has_high) break;
- }
- }
-
- if (has_high && has_low)
- {
- font.target_type = PS_TYPE_42_3_HYBRID;
- }
- else if (has_high && !has_low)
- {
- font.target_type = PS_TYPE_3;
- }
- }
-
- /* Save the file name for error messages. */
- font.filename=filename;
-
- /* Open the font file */
- if ( (font.file = fopen(filename,"rb")) == (FILE*)NULL )
- {
- throw TTException("Failed to open TrueType font");
- }
-
- /* Allocate space for the unvarying part of the offset table. */
- assert(font.offset_table == NULL);
- font.offset_table = (BYTE*)calloc( 12, sizeof(BYTE) );
-
- /* Read the first part of the offset table. */
- if ( fread( font.offset_table, sizeof(BYTE), 12, font.file ) != 12 )
- {
- throw TTException("TrueType font may be corrupt (reason 1)");
- }
-
- /* Determine how many directory entries there are. */
- font.numTables = getUSHORT( font.offset_table + 4 );
- debug("numTables=%d",(int)font.numTables);
-
- /* Expand the memory block to hold the whole thing. */
- font.offset_table = (BYTE*)realloc( font.offset_table, sizeof(BYTE) * (12 + font.numTables * 16) );
-
- /* Read the rest of the table directory. */
- if ( fread( font.offset_table + 12, sizeof(BYTE), (font.numTables*16), font.file ) != (font.numTables*16) )
- {
- throw TTException("TrueType font may be corrupt (reason 2)");
- }
-
- /* Extract information from the "Offset" table. */
- font.TTVersion = getFixed( font.offset_table );
-
- /* Load the "head" table and extract information from it. */
- ptr = GetTable(&font, "head");
- try
- {
- font.MfrRevision = getFixed( ptr + 4 ); /* font revision number */
- font.unitsPerEm = getUSHORT( ptr + 18 );
- font.HUPM = font.unitsPerEm / 2;
- debug("unitsPerEm=%d",(int)font.unitsPerEm);
- font.llx = topost2( getFWord( ptr + 36 ) ); /* bounding box info */
- font.lly = topost2( getFWord( ptr + 38 ) );
- font.urx = topost2( getFWord( ptr + 40 ) );
- font.ury = topost2( getFWord( ptr + 42 ) );
- font.indexToLocFormat = getSHORT( ptr + 50 ); /* size of 'loca' data */
- if (font.indexToLocFormat != 0 && font.indexToLocFormat != 1)
- {
- throw TTException("TrueType font is unusable because indexToLocFormat != 0");
- }
- if ( getSHORT(ptr+52) != 0 )
- {
- throw TTException("TrueType font is unusable because glyphDataFormat != 0");
- }
- }
- catch (TTException& )
- {
- free(ptr);
- throw;
- }
- free(ptr);
-
- /* Load information from the "name" table. */
- Read_name(&font);
-
- /* We need to have the PostScript table around. */
- assert(font.post_table == NULL);
- font.post_table = GetTable(&font, "post");
- font.numGlyphs = getUSHORT( font.post_table + 32 );
-
- /* If we are generating a Type 3 font, we will need to */
- /* have the 'loca' and 'glyf' tables arround while */
- /* we are generating the CharStrings. */
- if (font.target_type == PS_TYPE_3 || font.target_type == PS_TYPE_42_3_HYBRID)
- {
- BYTE *ptr; /* We need only one value */
- ptr = GetTable(&font, "hhea");
- font.numberOfHMetrics = getUSHORT(ptr + 34);
- free(ptr);
-
- assert(font.loca_table == NULL);
- font.loca_table = GetTable(&font,"loca");
- assert(font.glyf_table == NULL);
- font.glyf_table = GetTable(&font,"glyf");
- assert(font.hmtx_table == NULL);
- font.hmtx_table = GetTable(&font,"hmtx");
- }
-
- if (glyph_ids.size() == 0)
- {
- glyph_ids.clear();
- glyph_ids.reserve(font.numGlyphs);
- for (int x = 0; x < font.numGlyphs; ++x)
- {
- glyph_ids.push_back(x);
- }
- }
- else if (font.target_type == PS_TYPE_3 ||
- font.target_type == PS_TYPE_42_3_HYBRID)
- {
- ttfont_add_glyph_dependencies(&font, glyph_ids);
- }
-
-} /* end of insert_ttfont() */
-
-void insert_ttfont(const char *filename, TTStreamWriter& stream,
- font_type_enum target_type, std::vector<int>& glyph_ids)
-{
- struct TTFONT font;
-
- read_font(filename, target_type, glyph_ids, font);
-
- /* Write the header for the PostScript font. */
- ttfont_header(stream, &font);
-
- /* Define the encoding. */
- ttfont_encoding(stream, &font, glyph_ids, target_type);
-
- /* Insert FontInfo dictionary. */
- ttfont_FontInfo(stream, &font);
-
- /* If we are generating a type 42 font, */
- /* emmit the sfnts array. */
- if (font.target_type == PS_TYPE_42 ||
- font.target_type == PS_TYPE_42_3_HYBRID)
- {
- ttfont_sfnts(stream, &font);
- }
-
- /* Emmit the CharStrings array. */
- ttfont_CharStrings(stream, &font, glyph_ids);
-
- /* Send the font trailer. */
- ttfont_trailer(stream, &font);
-
-} /* end of insert_ttfont() */
-
-TTFONT::TTFONT() :
- file(NULL),
- PostName(NULL),
- FullName(NULL),
- FamilyName(NULL),
- Style(NULL),
- Copyright(NULL),
- Version(NULL),
- Trademark(NULL),
- offset_table(NULL),
- post_table(NULL),
- loca_table(NULL),
- glyf_table(NULL),
- hmtx_table(NULL)
-{
-
-}
-
-TTFONT::~TTFONT()
-{
- if (file)
- {
- fclose(file);
- }
- free(PostName);
- free(FullName);
- free(FamilyName);
- free(Style);
- free(Copyright);
- free(Version);
- free(Trademark);
- free(offset_table);
- free(post_table);
- free(loca_table);
- free(glyf_table);
- free(hmtx_table);
-}
-
-/* end of file */
diff --git a/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt2.cpp b/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt2.cpp
deleted file mode 100644
index ec2298c8c4..0000000000
--- a/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt2.cpp
+++ /dev/null
@@ -1,693 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/*
- * Modified for use within matplotlib
- * 5 July 2007
- * Michael Droettboom
- */
-
-/*
-** ~ppr/src/pprdrv/pprdrv_tt2.c
-** Copyright 1995, Trinity College Computing Center.
-** Written by David Chappell.
-**
-** Permission to use, copy, modify, and distribute this software and its
-** documentation for any purpose and without fee is hereby granted, provided
-** that the above copyright notice appear in all copies and that both that
-** copyright notice and this permission notice appear in supporting
-** documentation. This software is provided "as is" without express or
-** implied warranty.
-**
-** TrueType font support. These functions allow PPR to generate
-** PostScript fonts from Microsoft compatible TrueType font files.
-**
-** The functions in this file do most of the work to convert a
-** TrueType font to a type 3 PostScript font.
-**
-** Most of the material in this file is derived from a program called
-** "ttf2ps" which L. S. Ng posted to the usenet news group
-** "comp.sources.postscript". The author did not provide a copyright
-** notice or indicate any restrictions on use.
-**
-** Last revised 11 July 1995.
-*/
-
-#include <cstdlib>
-#include <cmath>
-#include <cstring>
-#include <memory>
-#include "pprdrv.h"
-#include "truetype.h"
-#include <algorithm>
-#include <stack>
-#include <list>
-
-class GlyphToType3
-{
-private:
- GlyphToType3& operator=(const GlyphToType3& other);
- GlyphToType3(const GlyphToType3& other);
-
- /* The PostScript bounding box. */
- int llx,lly,urx,ury;
- int advance_width;
-
- /* Variables to hold the character data. */
- int *epts_ctr; /* array of contour endpoints */
- int num_pts, num_ctr; /* number of points, number of coutours */
- FWord *xcoor, *ycoor; /* arrays of x and y coordinates */
- BYTE *tt_flags; /* array of TrueType flags */
-
- int stack_depth; /* A book-keeping variable for keeping track of the depth of the PS stack */
-
- void load_char(TTFONT* font, BYTE *glyph);
- void stack(TTStreamWriter& stream, int new_elem);
- void stack_end(TTStreamWriter& stream);
- void PSConvert(TTStreamWriter& stream);
- void PSCurveto(TTStreamWriter& stream,
- FWord x0, FWord y0,
- FWord x1, FWord y1,
- FWord x2, FWord y2);
- void PSMoveto(TTStreamWriter& stream, int x, int y);
- void PSLineto(TTStreamWriter& stream, int x, int y);
- void do_composite(TTStreamWriter& stream, struct TTFONT *font, BYTE *glyph);
-
-public:
- GlyphToType3(TTStreamWriter& stream, struct TTFONT *font, int charindex, bool embedded = false);
- ~GlyphToType3();
-};
-
-// Each point on a TrueType contour is either on the path or off it (a
-// control point); here's a simple representation for building such
-// contours. Added by Jouni Seppänen 2012-05-27.
-enum Flag { ON_PATH, OFF_PATH };
-struct FlaggedPoint
-{
- enum Flag flag;
- FWord x;
- FWord y;
- FlaggedPoint(Flag flag_, FWord x_, FWord y_): flag(flag_), x(x_), y(y_) {};
-};
-
-/*
-** This routine is used to break the character
-** procedure up into a number of smaller
-** procedures. This is necessary so as not to
-** overflow the stack on certain level 1 interpreters.
-**
-** Prepare to push another item onto the stack,
-** starting a new proceedure if necessary.
-**
-** Not all the stack depth calculations in this routine
-** are perfectly accurate, but they do the job.
-*/
-void GlyphToType3::stack(TTStreamWriter& stream, int new_elem)
-{
- if ( num_pts > 25 ) /* Only do something of we will have a log of points. */
- {
- if (stack_depth == 0)
- {
- stream.put_char('{');
- stack_depth=1;
- }
-
- stack_depth += new_elem; /* Account for what we propose to add */
-
- if (stack_depth > 100)
- {
- stream.puts("}_e{");
- stack_depth = 3 + new_elem; /* A rough estimate */
- }
- }
-} /* end of stack() */
-
-void GlyphToType3::stack_end(TTStreamWriter& stream) /* called at end */
-{
- if ( stack_depth )
- {
- stream.puts("}_e");
- stack_depth=0;
- }
-} /* end of stack_end() */
-
-/*
-** We call this routine to emmit the PostScript code
-** for the character we have loaded with load_char().
-*/
-void GlyphToType3::PSConvert(TTStreamWriter& stream)
-{
- int j, k;
-
- /* Step thru the contours.
- * j = index to xcoor, ycoor, tt_flags (point data)
- * k = index to epts_ctr (which points belong to the same contour) */
- for(j = k = 0; k < num_ctr; k++)
- {
- // A TrueType contour consists of on-path and off-path points.
- // Two consecutive on-path points are to be joined with a
- // line; off-path points between on-path points indicate a
- // quadratic spline, where the off-path point is the control
- // point. Two consecutive off-path points have an implicit
- // on-path point midway between them.
- std::list<FlaggedPoint> points;
-
- // Represent flags and x/y coordinates as a C++ list
- for (; j <= epts_ctr[k]; j++)
- {
- if (!(tt_flags[j] & 1)) {
- points.push_back(FlaggedPoint(OFF_PATH, xcoor[j], ycoor[j]));
- } else {
- points.push_back(FlaggedPoint(ON_PATH, xcoor[j], ycoor[j]));
- }
- }
-
- if (points.size() == 0) {
- // Don't try to access the last element of an empty list
- continue;
- }
-
- // For any two consecutive off-path points, insert the implied
- // on-path point.
- FlaggedPoint prev = points.back();
- for (std::list<FlaggedPoint>::iterator it = points.begin();
- it != points.end();
- it++)
- {
- if (prev.flag == OFF_PATH && it->flag == OFF_PATH)
- {
- points.insert(it,
- FlaggedPoint(ON_PATH,
- (prev.x + it->x) / 2,
- (prev.y + it->y) / 2));
- }
- prev = *it;
- }
- // Handle the wrap-around: insert a point either at the beginning
- // or at the end that has the same coordinates as the opposite point.
- // This also ensures that the initial point is ON_PATH.
- if (points.front().flag == OFF_PATH)
- {
- assert(points.back().flag == ON_PATH);
- points.insert(points.begin(), points.back());
- }
- else
- {
- assert(points.front().flag == ON_PATH);
- points.push_back(points.front());
- }
-
- // The first point
- stack(stream, 3);
- PSMoveto(stream, points.front().x, points.front().y);
-
- // Step through the remaining points
- std::list<FlaggedPoint>::const_iterator it = points.begin();
- for (it++; it != points.end(); /* incremented inside */)
- {
- const FlaggedPoint& point = *it;
- if (point.flag == ON_PATH)
- {
- stack(stream, 3);
- PSLineto(stream, point.x, point.y);
- it++;
- } else {
- std::list<FlaggedPoint>::const_iterator prev = it, next = it;
- prev--;
- next++;
- assert(prev->flag == ON_PATH);
- assert(next->flag == ON_PATH);
- stack(stream, 7);
- PSCurveto(stream,
- prev->x, prev->y,
- point.x, point.y,
- next->x, next->y);
- it++;
- it++;
- }
- }
- }
-
- /* Now, we can fill the whole thing. */
- stack(stream, 1);
- stream.puts("_cl");
-} /* end of PSConvert() */
-
-void GlyphToType3::PSMoveto(TTStreamWriter& stream, int x, int y)
-{
- stream.printf("%d %d _m\n", x, y);
-}
-
-void GlyphToType3::PSLineto(TTStreamWriter& stream, int x, int y)
-{
- stream.printf("%d %d _l\n", x, y);
-}
-
-/*
-** Emit a PostScript "curveto" command, assuming the current point
-** is (x0, y0), the control point of a quadratic spline is (x1, y1),
-** and the endpoint is (x2, y2). Note that this requires a conversion,
-** since PostScript splines are cubic.
-*/
-void GlyphToType3::PSCurveto(TTStreamWriter& stream,
- FWord x0, FWord y0,
- FWord x1, FWord y1,
- FWord x2, FWord y2)
-{
- double sx[3], sy[3], cx[3], cy[3];
-
- sx[0] = x0;
- sy[0] = y0;
- sx[1] = x1;
- sy[1] = y1;
- sx[2] = x2;
- sy[2] = y2;
- cx[0] = (2*sx[1]+sx[0])/3;
- cy[0] = (2*sy[1]+sy[0])/3;
- cx[1] = (sx[2]+2*sx[1])/3;
- cy[1] = (sy[2]+2*sy[1])/3;
- cx[2] = sx[2];
- cy[2] = sy[2];
- stream.printf("%d %d %d %d %d %d _c\n",
- (int)cx[0], (int)cy[0], (int)cx[1], (int)cy[1],
- (int)cx[2], (int)cy[2]);
-}
-
-/*
-** Deallocate the structures which stored
-** the data for the last simple glyph.
-*/
-GlyphToType3::~GlyphToType3()
-{
- free(tt_flags); /* The flags array */
- free(xcoor); /* The X coordinates */
- free(ycoor); /* The Y coordinates */
- free(epts_ctr); /* The array of contour endpoints */
-}
-
-/*
-** Load the simple glyph data pointed to by glyph.
-** The pointer "glyph" should point 10 bytes into
-** the glyph data.
-*/
-void GlyphToType3::load_char(TTFONT* font, BYTE *glyph)
-{
- int x;
- BYTE c, ct;
-
- /* Read the contour endpoints list. */
- epts_ctr = (int *)calloc(num_ctr,sizeof(int));
- for (x = 0; x < num_ctr; x++)
- {
- epts_ctr[x] = getUSHORT(glyph);
- glyph += 2;
- }
-
- /* From the endpoint of the last contour, we can */
- /* determine the number of points. */
- num_pts = epts_ctr[num_ctr-1]+1;
-#ifdef DEBUG_TRUETYPE
- debug("num_pts=%d",num_pts);
- stream.printf("%% num_pts=%d\n",num_pts);
-#endif
-
- /* Skip the instructions. */
- x = getUSHORT(glyph);
- glyph += 2;
- glyph += x;
-
- /* Allocate space to hold the data. */
- tt_flags = (BYTE *)calloc(num_pts,sizeof(BYTE));
- xcoor = (FWord *)calloc(num_pts,sizeof(FWord));
- ycoor = (FWord *)calloc(num_pts,sizeof(FWord));
-
- /* Read the flags array, uncompressing it as we go. */
- /* There is danger of overflow here. */
- for (x = 0; x < num_pts; )
- {
- tt_flags[x++] = c = *(glyph++);
-
- if (c&8) /* If next byte is repeat count, */
- {
- ct = *(glyph++);
-
- if ( (x + ct) > num_pts )
- {
- throw TTException("Error in TT flags");
- }
-
- while (ct--)
- {
- tt_flags[x++] = c;
- }
- }
- }
-
- /* Read the x coordinates */
- for (x = 0; x < num_pts; x++)
- {
- if (tt_flags[x] & 2) /* one byte value with */
- {
- /* external sign */
- c = *(glyph++);
- xcoor[x] = (tt_flags[x] & 0x10) ? c : (-1 * (int)c);
- }
- else if (tt_flags[x] & 0x10) /* repeat last */
- {
- xcoor[x] = 0;
- }
- else /* two byte signed value */
- {
- xcoor[x] = getFWord(glyph);
- glyph+=2;
- }
- }
-
- /* Read the y coordinates */
- for (x = 0; x < num_pts; x++)
- {
- if (tt_flags[x] & 4) /* one byte value with */
- {
- /* external sign */
- c = *(glyph++);
- ycoor[x] = (tt_flags[x] & 0x20) ? c : (-1 * (int)c);
- }
- else if (tt_flags[x] & 0x20) /* repeat last value */
- {
- ycoor[x] = 0;
- }
- else /* two byte signed value */
- {
- ycoor[x] = getUSHORT(glyph);
- glyph+=2;
- }
- }
-
- /* Convert delta values to absolute values. */
- for (x = 1; x < num_pts; x++)
- {
- xcoor[x] += xcoor[x-1];
- ycoor[x] += ycoor[x-1];
- }
-
- for (x=0; x < num_pts; x++)
- {
- xcoor[x] = topost(xcoor[x]);
- ycoor[x] = topost(ycoor[x]);
- }
-
-} /* end of load_char() */
-
-/*
-** Emmit PostScript code for a composite character.
-*/
-void GlyphToType3::do_composite(TTStreamWriter& stream, struct TTFONT *font, BYTE *glyph)
-{
- USHORT flags;
- USHORT glyphIndex;
- int arg1;
- int arg2;
-
- /* Once around this loop for each component. */
- do
- {
- flags = getUSHORT(glyph); /* read the flags word */
- glyph += 2;
-
- glyphIndex = getUSHORT(glyph); /* read the glyphindex word */
- glyph += 2;
-
- if (flags & ARG_1_AND_2_ARE_WORDS)
- {
- /* The tt spec. seems to say these are signed. */
- arg1 = getSHORT(glyph);
- glyph += 2;
- arg2 = getSHORT(glyph);
- glyph += 2;
- }
- else /* The tt spec. does not clearly indicate */
- {
- /* whether these values are signed or not. */
- arg1 = *(signed char *)(glyph++);
- arg2 = *(signed char *)(glyph++);
- }
-
- if (flags & WE_HAVE_A_SCALE)
- {
- glyph += 2;
- }
- else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
- {
- glyph += 4;
- }
- else if (flags & WE_HAVE_A_TWO_BY_TWO)
- {
- glyph += 8;
- }
- else
- {
- }
-
- /* Debugging */
-#ifdef DEBUG_TRUETYPE
- stream.printf("%% flags=%d, arg1=%d, arg2=%d\n",
- (int)flags,arg1,arg2);
-#endif
-
- /* If we have an (X,Y) shift and it is non-zero, */
- /* translate the coordinate system. */
- if ( flags & ARGS_ARE_XY_VALUES )
- {
- if ( arg1 != 0 || arg2 != 0 )
- stream.printf("gsave %d %d translate\n", topost(arg1), topost(arg2) );
- }
- else
- {
- stream.printf("%% unimplemented shift, arg1=%d, arg2=%d\n",arg1,arg2);
- }
-
- /* Invoke the CharStrings procedure to print the component. */
- stream.printf("false CharStrings /%s get exec\n",
- ttfont_CharStrings_getname(font, glyphIndex));
-
- /* If we translated the coordinate system, */
- /* put it back the way it was. */
- if ( flags & ARGS_ARE_XY_VALUES && (arg1 != 0 || arg2 != 0) )
- {
- stream.puts("grestore ");
- }
-
- }
- while (flags & MORE_COMPONENTS);
-
-} /* end of do_composite() */
-
-/*
-** Return a pointer to a specific glyph's data.
-*/
-BYTE *find_glyph_data(struct TTFONT *font, int charindex)
-{
- ULONG off;
- ULONG length;
-
- /* Read the glyph offset from the index to location table. */
- if (font->indexToLocFormat == 0)
- {
- off = getUSHORT( font->loca_table + (charindex * 2) );
- off *= 2;
- length = getUSHORT( font->loca_table + ((charindex+1) * 2) );
- length *= 2;
- length -= off;
- }
- else
- {
- off = getULONG( font->loca_table + (charindex * 4) );
- length = getULONG( font->loca_table + ((charindex+1) * 4) );
- length -= off;
- }
-
- if (length > 0)
- {
- return font->glyf_table + off;
- }
- else
- {
- return (BYTE*)NULL;
- }
-
-} /* end of find_glyph_data() */
-
-GlyphToType3::GlyphToType3(TTStreamWriter& stream, struct TTFONT *font, int charindex, bool embedded /* = false */)
-{
- BYTE *glyph;
-
- tt_flags = NULL;
- xcoor = NULL;
- ycoor = NULL;
- epts_ctr = NULL;
- stack_depth = 0;
-
- /* Get a pointer to the data. */
- glyph = find_glyph_data( font, charindex );
-
- /* If the character is blank, it has no bounding box, */
- /* otherwise read the bounding box. */
- if ( glyph == (BYTE*)NULL )
- {
- llx=lly=urx=ury=0; /* A blank char has an all zero BoundingBox */
- num_ctr=0; /* Set this for later if()s */
- }
- else
- {
- /* Read the number of contours. */
- num_ctr = getSHORT(glyph);
-
- /* Read PostScript bounding box. */
- llx = getFWord(glyph + 2);
- lly = getFWord(glyph + 4);
- urx = getFWord(glyph + 6);
- ury = getFWord(glyph + 8);
-
- /* Advance the pointer. */
- glyph += 10;
- }
-
- /* If it is a simple character, load its data. */
- if (num_ctr > 0)
- {
- load_char(font, glyph);
- }
- else
- {
- num_pts=0;
- }
-
- /* Consult the horizontal metrics table to determine */
- /* the character width. */
- if ( charindex < font->numberOfHMetrics )
- {
- advance_width = getuFWord( font->hmtx_table + (charindex * 4) );
- }
- else
- {
- advance_width = getuFWord( font->hmtx_table + ((font->numberOfHMetrics-1) * 4) );
- }
-
- /* Execute setcachedevice in order to inform the font machinery */
- /* of the character bounding box and advance width. */
- stack(stream, 7);
- if (font->target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.printf("pop gsave .001 .001 scale %d 0 %d %d %d %d setcachedevice\n",
- topost(advance_width),
- topost(llx), topost(lly), topost(urx), topost(ury) );
- }
- else
- {
- stream.printf("%d 0 %d %d %d %d _sc\n",
- topost(advance_width),
- topost(llx), topost(lly), topost(urx), topost(ury) );
- }
-
- /* If it is a simple glyph, convert it, */
- /* otherwise, close the stack business. */
- if ( num_ctr > 0 ) /* simple */
- {
- PSConvert(stream);
- }
- else if ( num_ctr < 0 ) /* composite */
- {
- do_composite(stream, font, glyph);
- }
-
- if (font->target_type == PS_TYPE_42_3_HYBRID)
- {
- stream.printf("\ngrestore\n");
- }
-
- stack_end(stream);
-}
-
-/*
-** This is the routine which is called from pprdrv_tt.c.
-*/
-void tt_type3_charproc(TTStreamWriter& stream, struct TTFONT *font, int charindex)
-{
- GlyphToType3 glyph(stream, font, charindex);
-} /* end of tt_type3_charproc() */
-
-/*
-** Some of the given glyph ids may refer to composite glyphs.
-** This function adds all of the dependencies of those composite
-** glyphs to the glyph id vector. Michael Droettboom [06-07-07]
-*/
-void ttfont_add_glyph_dependencies(struct TTFONT *font, std::vector<int>& glyph_ids)
-{
- std::sort(glyph_ids.begin(), glyph_ids.end());
-
- std::stack<int> glyph_stack;
- for (std::vector<int>::iterator i = glyph_ids.begin();
- i != glyph_ids.end(); ++i)
- {
- glyph_stack.push(*i);
- }
-
- while (glyph_stack.size())
- {
- int gind = glyph_stack.top();
- glyph_stack.pop();
-
- BYTE* glyph = find_glyph_data( font, gind );
- if (glyph != (BYTE*)NULL)
- {
-
- int num_ctr = getSHORT(glyph);
- if (num_ctr <= 0) // This is a composite glyph
- {
-
- glyph += 10;
- USHORT flags = 0;
-
- do
- {
- flags = getUSHORT(glyph);
- glyph += 2;
- gind = (int)getUSHORT(glyph);
- glyph += 2;
-
- std::vector<int>::iterator insertion =
- std::lower_bound(glyph_ids.begin(), glyph_ids.end(), gind);
- if (insertion == glyph_ids.end() || *insertion != gind)
- {
- glyph_ids.insert(insertion, gind);
- glyph_stack.push(gind);
- }
-
- if (flags & ARG_1_AND_2_ARE_WORDS)
- {
- glyph += 4;
- }
- else
- {
- glyph += 2;
- }
-
- if (flags & WE_HAVE_A_SCALE)
- {
- glyph += 2;
- }
- else if (flags & WE_HAVE_AN_X_AND_Y_SCALE)
- {
- glyph += 4;
- }
- else if (flags & WE_HAVE_A_TWO_BY_TWO)
- {
- glyph += 8;
- }
- }
- while (flags & MORE_COMPONENTS);
- }
- }
- }
-}
-
-/* end of file */
diff --git a/contrib/python/matplotlib/py3/extern/ttconv/truetype.h b/contrib/python/matplotlib/py3/extern/ttconv/truetype.h
deleted file mode 100644
index 86be14fe37..0000000000
--- a/contrib/python/matplotlib/py3/extern/ttconv/truetype.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4 -*- */
-
-/*
- * Modified for use within matplotlib
- * 5 July 2007
- * Michael Droettboom
- */
-
-#include <stdio.h>
-
-/*
-** ~ppr/src/include/typetype.h
-**
-** Permission to use, copy, modify, and distribute this software and its
-** documentation for any purpose and without fee is hereby granted, provided
-** that the above copyright notice appear in all copies and that both that
-** copyright notice and this permission notice appear in supporting
-** documentation. This software is provided "as is" without express or
-** implied warranty.
-**
-** This include file is shared by the source files
-** "pprdrv/pprdrv_tt.c" and "pprdrv/pprdrv_tt2.c".
-**
-** Last modified 19 April 1995.
-*/
-
-/* Types used in TrueType font files. */
-#define BYTE unsigned char
-#define USHORT unsigned short int
-#define SHORT short signed int
-#define ULONG unsigned int
-#define FIXED long signed int
-#define FWord short signed int
-#define uFWord short unsigned int
-
-/* This structure stores a 16.16 bit fixed */
-/* point number. */
-typedef struct
- {
- short int whole;
- unsigned short int fraction;
- } Fixed;
-
-/* This structure tells what we have found out about */
-/* the current font. */
-struct TTFONT
- {
- // A quick-and-dirty way to create a minimum level of exception safety
- // Added by Michael Droettboom
- TTFONT();
- ~TTFONT();
-
- const char *filename; /* Name of TT file */
- FILE *file; /* the open TT file */
- font_type_enum target_type; /* 42 or 3 for PS, or -3 for PDF */
-
- ULONG numTables; /* number of tables present */
- char *PostName; /* Font's PostScript name */
- char *FullName; /* Font's full name */
- char *FamilyName; /* Font's family name */
- char *Style; /* Font's style string */
- char *Copyright; /* Font's copyright string */
- char *Version; /* Font's version string */
- char *Trademark; /* Font's trademark string */
- int llx,lly,urx,ury; /* bounding box */
-
- Fixed TTVersion; /* Truetype version number from offset table */
- Fixed MfrRevision; /* Revision number of this font */
-
- BYTE *offset_table; /* Offset table in memory */
- BYTE *post_table; /* 'post' table in memory */
-
- BYTE *loca_table; /* 'loca' table in memory */
- BYTE *glyf_table; /* 'glyf' table in memory */
- BYTE *hmtx_table; /* 'hmtx' table in memory */
-
- USHORT numberOfHMetrics;
- int unitsPerEm; /* unitsPerEm converted to int */
- int HUPM; /* half of above */
-
- int numGlyphs; /* from 'post' table */
-
- int indexToLocFormat; /* short or long offsets */
-};
-
-ULONG getULONG(BYTE *p);
-USHORT getUSHORT(BYTE *p);
-Fixed getFixed(BYTE *p);
-
-/*
-** Get an funits word.
-** since it is 16 bits long, we can
-** use getUSHORT() to do the real work.
-*/
-#define getFWord(x) (FWord)getUSHORT(x)
-#define getuFWord(x) (uFWord)getUSHORT(x)
-
-/*
-** We can get a SHORT by making USHORT signed.
-*/
-#define getSHORT(x) (SHORT)getUSHORT(x)
-
-/* This is the one routine in pprdrv_tt.c that is */
-/* called from pprdrv_tt.c. */
-const char *ttfont_CharStrings_getname(struct TTFONT *font, int charindex);
-
-void tt_type3_charproc(TTStreamWriter& stream, struct TTFONT *font, int charindex);
-
-/* Added 06-07-07 Michael Droettboom */
-void ttfont_add_glyph_dependencies(struct TTFONT *font, std::vector<int>& glypy_ids);
-
-/* This routine converts a number in the font's character coordinate */
-/* system to a number in a 1000 unit character system. */
-#define topost(x) (int)( ((int)(x) * 1000 + font->HUPM) / font->unitsPerEm )
-#define topost2(x) (int)( ((int)(x) * 1000 + font.HUPM) / font.unitsPerEm )
-
-/* Composite glyph values. */
-#define ARG_1_AND_2_ARE_WORDS 1
-#define ARGS_ARE_XY_VALUES 2
-#define ROUND_XY_TO_GRID 4
-#define WE_HAVE_A_SCALE 8
-/* RESERVED 16 */
-#define MORE_COMPONENTS 32
-#define WE_HAVE_AN_X_AND_Y_SCALE 64
-#define WE_HAVE_A_TWO_BY_TWO 128
-#define WE_HAVE_INSTRUCTIONS 256
-#define USE_MY_METRICS 512
-
-/* end of file */
diff --git a/contrib/python/matplotlib/py3/extern/ttconv/ttutil.cpp b/contrib/python/matplotlib/py3/extern/ttconv/ttutil.cpp
deleted file mode 100644
index 6028e1d45d..0000000000
--- a/contrib/python/matplotlib/py3/extern/ttconv/ttutil.cpp
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/*
- * Modified for use within matplotlib
- * 5 July 2007
- * Michael Droettboom
- */
-
-/* Very simple interface to the ppr TT routines */
-/* (c) Frank Siegert 1996 */
-
-#include <cstdio>
-#include <cstdarg>
-#include <cstdlib>
-#include "pprdrv.h"
-
-#define PRINTF_BUFFER_SIZE 512
-void TTStreamWriter::printf(const char* format, ...)
-{
- va_list arg_list;
- va_start(arg_list, format);
- char buffer[PRINTF_BUFFER_SIZE];
-
-#if defined(WIN32) || defined(_MSC_VER)
- int size = _vsnprintf(buffer, PRINTF_BUFFER_SIZE, format, arg_list);
-#else
- int size = vsnprintf(buffer, PRINTF_BUFFER_SIZE, format, arg_list);
-#endif
- if (size >= PRINTF_BUFFER_SIZE) {
- char* buffer2 = (char*)malloc(size);
-#if defined(WIN32) || defined(_MSC_VER)
- _vsnprintf(buffer2, size, format, arg_list);
-#else
- vsnprintf(buffer2, size, format, arg_list);
-#endif
- this->write(buffer2);
- free(buffer2);
- } else {
- this->write(buffer);
- }
-
- va_end(arg_list);
-}
-
-void TTStreamWriter::put_char(int val)
-{
- char c[2];
- c[0] = (char)val;
- c[1] = 0;
- this->write(c);
-}
-
-void TTStreamWriter::puts(const char *a)
-{
- this->write(a);
-}
-
-void TTStreamWriter::putline(const char *a)
-{
- this->write(a);
- this->write("\n");
-}
-
-void replace_newlines_with_spaces(char *a) {
- char* i = a;
- while (*i != 0) {
- if (*i == '\r' || *i == '\n')
- *i = ' ';
- i++;
- }
-}
diff --git a/contrib/python/matplotlib/py3/extern/ttconv/ya.make b/contrib/python/matplotlib/py3/extern/ttconv/ya.make
deleted file mode 100644
index f877dfcbd2..0000000000
--- a/contrib/python/matplotlib/py3/extern/ttconv/ya.make
+++ /dev/null
@@ -1,15 +0,0 @@
-PY23_LIBRARY()
-
-VERSION(Service-proxy-version)
-
-LICENSE(PSF-2.0)
-
-NO_COMPILER_WARNINGS()
-
-SRCS(
- pprdrv_tt.cpp
- pprdrv_tt2.cpp
- ttutil.cpp
-)
-
-END()
diff --git a/contrib/python/matplotlib/py3/extern/ya.make b/contrib/python/matplotlib/py3/extern/ya.make
deleted file mode 100644
index ef8acb58ea..0000000000
--- a/contrib/python/matplotlib/py3/extern/ya.make
+++ /dev/null
@@ -1,4 +0,0 @@
-RECURSE(
- agg24-svn
- ttconv
-)
diff --git a/contrib/python/matplotlib/py3/matplotlib/__init__.py b/contrib/python/matplotlib/py3/matplotlib/__init__.py
deleted file mode 100644
index 6023b86b2a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/__init__.py
+++ /dev/null
@@ -1,1519 +0,0 @@
-"""
-An object-oriented plotting library.
-
-A procedural interface is provided by the companion pyplot module,
-which may be imported directly, e.g.::
-
- import matplotlib.pyplot as plt
-
-or using ipython::
-
- ipython
-
-at your terminal, followed by::
-
- In [1]: %matplotlib
- In [2]: import matplotlib.pyplot as plt
-
-at the ipython shell prompt.
-
-For the most part, direct use of the explicit object-oriented library is
-encouraged when programming; the implicit pyplot interface is primarily for
-working interactively. The exceptions to this suggestion are the pyplot
-functions `.pyplot.figure`, `.pyplot.subplot`, `.pyplot.subplots`, and
-`.pyplot.savefig`, which can greatly simplify scripting. See
-:ref:`api_interfaces` for an explanation of the tradeoffs between the implicit
-and explicit interfaces.
-
-Modules include:
-
-:mod:`matplotlib.axes`
- The `~.axes.Axes` class. Most pyplot functions are wrappers for
- `~.axes.Axes` methods. The axes module is the highest level of OO
- access to the library.
-
-:mod:`matplotlib.figure`
- The `.Figure` class.
-
-:mod:`matplotlib.artist`
- The `.Artist` base class for all classes that draw things.
-
-:mod:`matplotlib.lines`
- The `.Line2D` class for drawing lines and markers.
-
-:mod:`matplotlib.patches`
- Classes for drawing polygons.
-
-:mod:`matplotlib.text`
- The `.Text` and `.Annotation` classes.
-
-:mod:`matplotlib.image`
- The `.AxesImage` and `.FigureImage` classes.
-
-:mod:`matplotlib.collections`
- Classes for efficient drawing of groups of lines or polygons.
-
-:mod:`matplotlib.colors`
- Color specifications and making colormaps.
-
-:mod:`matplotlib.cm`
- Colormaps, and the `.ScalarMappable` mixin class for providing color
- mapping functionality to other classes.
-
-:mod:`matplotlib.ticker`
- Calculation of tick mark locations and formatting of tick labels.
-
-:mod:`matplotlib.backends`
- A subpackage with modules for various GUI libraries and output formats.
-
-The base matplotlib namespace includes:
-
-`~matplotlib.rcParams`
- Default configuration settings; their defaults may be overridden using
- a :file:`matplotlibrc` file.
-
-`~matplotlib.use`
- Setting the Matplotlib backend. This should be called before any
- figure is created, because it is not possible to switch between
- different GUI backends after that.
-
-The following environment variables can be used to customize the behavior:
-
-:envvar:`MPLBACKEND`
- This optional variable can be set to choose the Matplotlib backend. See
- :ref:`what-is-a-backend`.
-
-:envvar:`MPLCONFIGDIR`
- This is the directory used to store user customizations to
- Matplotlib, as well as some caches to improve performance. If
- :envvar:`MPLCONFIGDIR` is not defined, :file:`{HOME}/.config/matplotlib`
- and :file:`{HOME}/.cache/matplotlib` are used on Linux, and
- :file:`{HOME}/.matplotlib` on other platforms, if they are
- writable. Otherwise, the Python standard library's `tempfile.gettempdir`
- is used to find a base directory in which the :file:`matplotlib`
- subdirectory is created.
-
-Matplotlib was initially written by John D. Hunter (1968-2012) and is now
-developed and maintained by a host of others.
-
-Occasionally the internal documentation (python docstrings) will refer
-to MATLAB®, a registered trademark of The MathWorks, Inc.
-
-"""
-
-__all__ = [
- "__bibtex__",
- "__version__",
- "__version_info__",
- "set_loglevel",
- "ExecutableNotFoundError",
- "get_configdir",
- "get_cachedir",
- "get_data_path",
- "matplotlib_fname",
- "MatplotlibDeprecationWarning",
- "RcParams",
- "rc_params",
- "rc_params_from_file",
- "rcParamsDefault",
- "rcParams",
- "rcParamsOrig",
- "defaultParams",
- "rc",
- "rcdefaults",
- "rc_file_defaults",
- "rc_file",
- "rc_context",
- "use",
- "get_backend",
- "interactive",
- "is_interactive",
- "colormaps",
- "color_sequences",
-]
-
-
-import atexit
-from collections import namedtuple
-from collections.abc import MutableMapping
-import contextlib
-import functools
-import importlib
-import inspect
-from inspect import Parameter
-import locale
-import logging
-import os
-from pathlib import Path
-import pprint
-import re
-import shutil
-import subprocess
-import sys
-import tempfile
-import warnings
-
-import numpy
-from packaging.version import parse as parse_version
-
-# cbook must import matplotlib only within function
-# definitions, so it is safe to import from it here.
-from . import _api, _version, cbook, _docstring, rcsetup
-from matplotlib.cbook import sanitize_sequence
-from matplotlib._api import MatplotlibDeprecationWarning
-from matplotlib.rcsetup import validate_backend, cycler
-
-
-_log = logging.getLogger(__name__)
-
-__bibtex__ = r"""@Article{Hunter:2007,
- Author = {Hunter, J. D.},
- Title = {Matplotlib: A 2D graphics environment},
- Journal = {Computing in Science \& Engineering},
- Volume = {9},
- Number = {3},
- Pages = {90--95},
- abstract = {Matplotlib is a 2D graphics package used for Python
- for application development, interactive scripting, and
- publication-quality image generation across user
- interfaces and operating systems.},
- publisher = {IEEE COMPUTER SOC},
- year = 2007
-}"""
-
-# modelled after sys.version_info
-_VersionInfo = namedtuple('_VersionInfo',
- 'major, minor, micro, releaselevel, serial')
-
-
-def _parse_to_version_info(version_str):
- """
- Parse a version string to a namedtuple analogous to sys.version_info.
-
- See:
- https://packaging.pypa.io/en/latest/version.html#packaging.version.parse
- https://docs.python.org/3/library/sys.html#sys.version_info
- """
- v = parse_version(version_str)
- if v.pre is None and v.post is None and v.dev is None:
- return _VersionInfo(v.major, v.minor, v.micro, 'final', 0)
- elif v.dev is not None:
- return _VersionInfo(v.major, v.minor, v.micro, 'alpha', v.dev)
- elif v.pre is not None:
- releaselevel = {
- 'a': 'alpha',
- 'b': 'beta',
- 'rc': 'candidate'}.get(v.pre[0], 'alpha')
- return _VersionInfo(v.major, v.minor, v.micro, releaselevel, v.pre[1])
- else:
- # fallback for v.post: guess-next-dev scheme from setuptools_scm
- return _VersionInfo(v.major, v.minor, v.micro + 1, 'alpha', v.post)
-
-
-def _get_version():
- """Return the version string used for __version__."""
- # Only shell out to a git subprocess if really needed, i.e. when we are in
- # a matplotlib git repo but not in a shallow clone, such as those used by
- # CI, as the latter would trigger a warning from setuptools_scm.
- root = Path(__file__).resolve().parents[2]
- if ((root / ".matplotlib-repo").exists()
- and (root / ".git").exists()
- and not (root / ".git/shallow").exists()):
- import setuptools_scm
- return setuptools_scm.get_version(
- root=root,
- version_scheme="release-branch-semver",
- local_scheme="node-and-date",
- fallback_version=_version.version,
- )
- else: # Get the version from the _version.py setuptools_scm file.
- return _version.version
-
-
-@_api.caching_module_getattr
-class __getattr__:
- __version__ = property(lambda self: _get_version())
- __version_info__ = property(
- lambda self: _parse_to_version_info(self.__version__))
-
-
-def _check_versions():
-
- # Quickfix to ensure Microsoft Visual C++ redistributable
- # DLLs are loaded before importing kiwisolver
- from . import ft2font
-
- for modname, minver in [
- ("cycler", "0.10"),
- ("dateutil", "2.7"),
- ("kiwisolver", "1.3.1"),
- ("numpy", "1.21"),
- ("pyparsing", "2.3.1"),
- ]:
- module = importlib.import_module(modname)
- if parse_version(module.__version__) < parse_version(minver):
- raise ImportError(f"Matplotlib requires {modname}>={minver}; "
- f"you have {module.__version__}")
-
-
-_check_versions()
-
-
-# The decorator ensures this always returns the same handler (and it is only
-# attached once).
-@functools.cache
-def _ensure_handler():
- """
- The first time this function is called, attach a `StreamHandler` using the
- same format as `logging.basicConfig` to the Matplotlib root logger.
-
- Return this handler every time this function is called.
- """
- handler = logging.StreamHandler()
- handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT))
- _log.addHandler(handler)
- return handler
-
-
-def set_loglevel(level):
- """
- Configure Matplotlib's logging levels.
-
- Matplotlib uses the standard library `logging` framework under the root
- logger 'matplotlib'. This is a helper function to:
-
- - set Matplotlib's root logger level
- - set the root logger handler's level, creating the handler
- if it does not exist yet
-
- Typically, one should call ``set_loglevel("info")`` or
- ``set_loglevel("debug")`` to get additional debugging information.
-
- Users or applications that are installing their own logging handlers
- may want to directly manipulate ``logging.getLogger('matplotlib')`` rather
- than use this function.
-
- Parameters
- ----------
- level : {"notset", "debug", "info", "warning", "error", "critical"}
- The log level of the handler.
-
- Notes
- -----
- The first time this function is called, an additional handler is attached
- to Matplotlib's root handler; this handler is reused every time and this
- function simply manipulates the logger and handler's level.
-
- """
- _log.setLevel(level.upper())
- _ensure_handler().setLevel(level.upper())
-
-
-def _logged_cached(fmt, func=None):
- """
- Decorator that logs a function's return value, and memoizes that value.
-
- After ::
-
- @_logged_cached(fmt)
- def func(): ...
-
- the first call to *func* will log its return value at the DEBUG level using
- %-format string *fmt*, and memoize it; later calls to *func* will directly
- return that value.
- """
- if func is None: # Return the actual decorator.
- return functools.partial(_logged_cached, fmt)
-
- called = False
- ret = None
-
- @functools.wraps(func)
- def wrapper(**kwargs):
- nonlocal called, ret
- if not called:
- ret = func(**kwargs)
- called = True
- _log.debug(fmt, ret)
- return ret
-
- return wrapper
-
-
-_ExecInfo = namedtuple("_ExecInfo", "executable raw_version version")
-
-
-class ExecutableNotFoundError(FileNotFoundError):
- """
- Error raised when an executable that Matplotlib optionally
- depends on can't be found.
- """
- pass
-
-
-@functools.cache
-def _get_executable_info(name):
- """
- Get the version of some executable that Matplotlib optionally depends on.
-
- .. warning::
- The list of executables that this function supports is set according to
- Matplotlib's internal needs, and may change without notice.
-
- Parameters
- ----------
- name : str
- The executable to query. The following values are currently supported:
- "dvipng", "gs", "inkscape", "magick", "pdftocairo", "pdftops". This
- list is subject to change without notice.
-
- Returns
- -------
- tuple
- A namedtuple with fields ``executable`` (`str`) and ``version``
- (`packaging.Version`, or ``None`` if the version cannot be determined).
-
- Raises
- ------
- ExecutableNotFoundError
- If the executable is not found or older than the oldest version
- supported by Matplotlib. For debugging purposes, it is also
- possible to "hide" an executable from Matplotlib by adding it to the
- :envvar:`_MPLHIDEEXECUTABLES` environment variable (a comma-separated
- list), which must be set prior to any calls to this function.
- ValueError
- If the executable is not one that we know how to query.
- """
-
- def impl(args, regex, min_ver=None, ignore_exit_code=False):
- # Execute the subprocess specified by args; capture stdout and stderr.
- # Search for a regex match in the output; if the match succeeds, the
- # first group of the match is the version.
- # Return an _ExecInfo if the executable exists, and has a version of
- # at least min_ver (if set); else, raise ExecutableNotFoundError.
- try:
- output = subprocess.check_output(
- args, stderr=subprocess.STDOUT,
- text=True, errors="replace")
- except subprocess.CalledProcessError as _cpe:
- if ignore_exit_code:
- output = _cpe.output
- else:
- raise ExecutableNotFoundError(str(_cpe)) from _cpe
- except OSError as _ose:
- raise ExecutableNotFoundError(str(_ose)) from _ose
- match = re.search(regex, output)
- if match:
- raw_version = match.group(1)
- version = parse_version(raw_version)
- if min_ver is not None and version < parse_version(min_ver):
- raise ExecutableNotFoundError(
- f"You have {args[0]} version {version} but the minimum "
- f"version supported by Matplotlib is {min_ver}")
- return _ExecInfo(args[0], raw_version, version)
- else:
- raise ExecutableNotFoundError(
- f"Failed to determine the version of {args[0]} from "
- f"{' '.join(args)}, which output {output}")
-
- if name in os.environ.get("_MPLHIDEEXECUTABLES", "").split(","):
- raise ExecutableNotFoundError(f"{name} was hidden")
-
- if name == "dvipng":
- return impl(["dvipng", "-version"], "(?m)^dvipng(?: .*)? (.+)", "1.6")
- elif name == "gs":
- execs = (["gswin32c", "gswin64c", "mgs", "gs"] # "mgs" for miktex.
- if sys.platform == "win32" else
- ["gs"])
- for e in execs:
- try:
- return impl([e, "--version"], "(.*)", "9")
- except ExecutableNotFoundError:
- pass
- message = "Failed to find a Ghostscript installation"
- raise ExecutableNotFoundError(message)
- elif name == "inkscape":
- try:
- # Try headless option first (needed for Inkscape version < 1.0):
- return impl(["inkscape", "--without-gui", "-V"],
- "Inkscape ([^ ]*)")
- except ExecutableNotFoundError:
- pass # Suppress exception chaining.
- # If --without-gui is not accepted, we may be using Inkscape >= 1.0 so
- # try without it:
- return impl(["inkscape", "-V"], "Inkscape ([^ ]*)")
- elif name == "magick":
- if sys.platform == "win32":
- # Check the registry to avoid confusing ImageMagick's convert with
- # Windows's builtin convert.exe.
- import winreg
- binpath = ""
- for flag in [0, winreg.KEY_WOW64_32KEY, winreg.KEY_WOW64_64KEY]:
- try:
- with winreg.OpenKeyEx(
- winreg.HKEY_LOCAL_MACHINE,
- r"Software\Imagemagick\Current",
- 0, winreg.KEY_QUERY_VALUE | flag) as hkey:
- binpath = winreg.QueryValueEx(hkey, "BinPath")[0]
- except OSError:
- pass
- path = None
- if binpath:
- for name in ["convert.exe", "magick.exe"]:
- candidate = Path(binpath, name)
- if candidate.exists():
- path = str(candidate)
- break
- if path is None:
- raise ExecutableNotFoundError(
- "Failed to find an ImageMagick installation")
- else:
- path = "convert"
- info = impl([path, "--version"], r"^Version: ImageMagick (\S*)")
- if info.raw_version == "7.0.10-34":
- # https://github.com/ImageMagick/ImageMagick/issues/2720
- raise ExecutableNotFoundError(
- f"You have ImageMagick {info.version}, which is unsupported")
- return info
- elif name == "pdftocairo":
- return impl(["pdftocairo", "-v"], "pdftocairo version (.*)")
- elif name == "pdftops":
- info = impl(["pdftops", "-v"], "^pdftops version (.*)",
- ignore_exit_code=True)
- if info and not (
- 3 <= info.version.major or
- # poppler version numbers.
- parse_version("0.9") <= info.version < parse_version("1.0")):
- raise ExecutableNotFoundError(
- f"You have pdftops version {info.version} but the minimum "
- f"version supported by Matplotlib is 3.0")
- return info
- else:
- raise ValueError(f"Unknown executable: {name!r}")
-
-
-def _get_xdg_config_dir():
- """
- Return the XDG configuration directory, according to the XDG base
- directory spec:
-
- https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
- """
- return os.environ.get('XDG_CONFIG_HOME') or str(Path.home() / ".config")
-
-
-def _get_xdg_cache_dir():
- """
- Return the XDG cache directory, according to the XDG base directory spec:
-
- https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
- """
- return os.environ.get('XDG_CACHE_HOME') or str(Path.home() / ".cache")
-
-
-def _get_config_or_cache_dir(xdg_base_getter):
- configdir = os.environ.get('MPLCONFIGDIR')
- if configdir:
- configdir = Path(configdir).resolve()
- elif sys.platform.startswith(('linux', 'freebsd')):
- # Only call _xdg_base_getter here so that MPLCONFIGDIR is tried first,
- # as _xdg_base_getter can throw.
- configdir = Path(xdg_base_getter(), "matplotlib")
- else:
- configdir = Path.home() / ".matplotlib"
- try:
- configdir.mkdir(parents=True, exist_ok=True)
- except OSError:
- pass
- else:
- if os.access(str(configdir), os.W_OK) and configdir.is_dir():
- return str(configdir)
- # If the config or cache directory cannot be created or is not a writable
- # directory, create a temporary one.
- try:
- tmpdir = tempfile.mkdtemp(prefix="matplotlib-")
- except OSError as exc:
- raise OSError(
- f"Matplotlib requires access to a writable cache directory, but the "
- f"default path ({configdir}) is not a writable directory, and a temporary "
- f"directory could not be created; set the MPLCONFIGDIR environment "
- f"variable to a writable directory") from exc
- os.environ["MPLCONFIGDIR"] = tmpdir
- atexit.register(shutil.rmtree, tmpdir)
- _log.warning(
- "Matplotlib created a temporary cache directory at %s because the default path "
- "(%s) is not a writable directory; it is highly recommended to set the "
- "MPLCONFIGDIR environment variable to a writable directory, in particular to "
- "speed up the import of Matplotlib and to better support multiprocessing.",
- tmpdir, configdir)
- return tmpdir
-
-
-@_logged_cached('CONFIGDIR=%s')
-def get_configdir():
- """
- Return the string path of the configuration directory.
-
- The directory is chosen as follows:
-
- 1. If the MPLCONFIGDIR environment variable is supplied, choose that.
- 2. On Linux, follow the XDG specification and look first in
- ``$XDG_CONFIG_HOME``, if defined, or ``$HOME/.config``. On other
- platforms, choose ``$HOME/.matplotlib``.
- 3. If the chosen directory exists and is writable, use that as the
- configuration directory.
- 4. Else, create a temporary directory, and use it as the configuration
- directory.
- """
- return _get_config_or_cache_dir(_get_xdg_config_dir)
-
-
-@_logged_cached('CACHEDIR=%s')
-def get_cachedir():
- """
- Return the string path of the cache directory.
-
- The procedure used to find the directory is the same as for
- `get_configdir`, except using ``$XDG_CACHE_HOME``/``$HOME/.cache`` instead.
- """
- return _get_config_or_cache_dir(_get_xdg_cache_dir)
-
-
-@_logged_cached('matplotlib data path: %s')
-def get_data_path():
- """Return the path to Matplotlib data."""
- return _get_internal_mpl_data()
-
-
-def _get_internal_mpl_data():
- import tempfile
- import __res
-
- tmp_dir = tempfile.mkdtemp(prefix='mpl-temp', dir=tempfile.gettempdir())
- for key, rel_path in __res.iter_keys(b"resfs/file/contrib/python/matplotlib/py3/matplotlib/mpl-data/"):
- filename = f"{tmp_dir}/{str(rel_path, 'ascii')}"
- os.makedirs(os.path.dirname(filename), exist_ok=True)
- with open(filename, 'wb') as f:
- f.write(__res.find(key))
-
- return tmp_dir
-
-
-def matplotlib_fname():
- """
- Get the location of the config file.
-
- The file location is determined in the following order
-
- - ``$PWD/matplotlibrc``
- - ``$MATPLOTLIBRC`` if it is not a directory
- - ``$MATPLOTLIBRC/matplotlibrc``
- - ``$MPLCONFIGDIR/matplotlibrc``
- - On Linux,
- - ``$XDG_CONFIG_HOME/matplotlib/matplotlibrc`` (if ``$XDG_CONFIG_HOME``
- is defined)
- - or ``$HOME/.config/matplotlib/matplotlibrc`` (if ``$XDG_CONFIG_HOME``
- is not defined)
- - On other platforms,
- - ``$HOME/.matplotlib/matplotlibrc`` if ``$HOME`` is defined
- - Lastly, it looks in ``$MATPLOTLIBDATA/matplotlibrc``, which should always
- exist.
- """
-
- def gen_candidates():
- # rely on down-stream code to make absolute. This protects us
- # from having to directly get the current working directory
- # which can fail if the user has ended up with a cwd that is
- # non-existent.
- yield 'matplotlibrc'
- try:
- matplotlibrc = os.environ['MATPLOTLIBRC']
- except KeyError:
- pass
- else:
- yield matplotlibrc
- yield os.path.join(matplotlibrc, 'matplotlibrc')
- yield os.path.join(get_configdir(), 'matplotlibrc')
- yield os.path.join(get_data_path(), 'matplotlibrc')
-
- for fname in gen_candidates():
- if os.path.exists(fname) and not os.path.isdir(fname):
- return fname
-
- raise RuntimeError("Could not find matplotlibrc file; your Matplotlib "
- "install is broken")
-
-
-# rcParams deprecated and automatically mapped to another key.
-# Values are tuples of (version, new_name, f_old2new, f_new2old).
-_deprecated_map = {}
-# rcParams deprecated; some can manually be mapped to another key.
-# Values are tuples of (version, new_name_or_None).
-_deprecated_ignore_map = {}
-# rcParams deprecated; can use None to suppress warnings; remain actually
-# listed in the rcParams.
-# Values are tuples of (version,)
-_deprecated_remain_as_none = {}
-
-
-@_docstring.Substitution(
- "\n".join(map("- {}".format, sorted(rcsetup._validators, key=str.lower)))
-)
-class RcParams(MutableMapping, dict):
- """
- A dict-like key-value store for config parameters, including validation.
-
- Validating functions are defined and associated with rc parameters in
- :mod:`matplotlib.rcsetup`.
-
- The list of rcParams is:
-
- %s
-
- See Also
- --------
- :ref:`customizing-with-matplotlibrc-files`
- """
-
- validate = rcsetup._validators
-
- # validate values on the way in
- def __init__(self, *args, **kwargs):
- self.update(*args, **kwargs)
-
- def _set(self, key, val):
- """
- Directly write data bypassing deprecation and validation logic.
-
- Notes
- -----
- As end user or downstream library you almost always should use
- ``rcParams[key] = val`` and not ``_set()``.
-
- There are only very few special cases that need direct data access.
- These cases previously used ``dict.__setitem__(rcParams, key, val)``,
- which is now deprecated and replaced by ``rcParams._set(key, val)``.
-
- Even though private, we guarantee API stability for ``rcParams._set``,
- i.e. it is subject to Matplotlib's API and deprecation policy.
-
- :meta public:
- """
- dict.__setitem__(self, key, val)
-
- def _get(self, key):
- """
- Directly read data bypassing deprecation, backend and validation
- logic.
-
- Notes
- -----
- As end user or downstream library you almost always should use
- ``val = rcParams[key]`` and not ``_get()``.
-
- There are only very few special cases that need direct data access.
- These cases previously used ``dict.__getitem__(rcParams, key, val)``,
- which is now deprecated and replaced by ``rcParams._get(key)``.
-
- Even though private, we guarantee API stability for ``rcParams._get``,
- i.e. it is subject to Matplotlib's API and deprecation policy.
-
- :meta public:
- """
- return dict.__getitem__(self, key)
-
- def __setitem__(self, key, val):
- try:
- if key in _deprecated_map:
- version, alt_key, alt_val, inverse_alt = _deprecated_map[key]
- _api.warn_deprecated(
- version, name=key, obj_type="rcparam", alternative=alt_key)
- key = alt_key
- val = alt_val(val)
- elif key in _deprecated_remain_as_none and val is not None:
- version, = _deprecated_remain_as_none[key]
- _api.warn_deprecated(version, name=key, obj_type="rcparam")
- elif key in _deprecated_ignore_map:
- version, alt_key = _deprecated_ignore_map[key]
- _api.warn_deprecated(
- version, name=key, obj_type="rcparam", alternative=alt_key)
- return
- elif key == 'backend':
- if val is rcsetup._auto_backend_sentinel:
- if 'backend' in self:
- return
- try:
- cval = self.validate[key](val)
- except ValueError as ve:
- raise ValueError(f"Key {key}: {ve}") from None
- self._set(key, cval)
- except KeyError as err:
- raise KeyError(
- f"{key} is not a valid rc parameter (see rcParams.keys() for "
- f"a list of valid parameters)") from err
-
- def __getitem__(self, key):
- if key in _deprecated_map:
- version, alt_key, alt_val, inverse_alt = _deprecated_map[key]
- _api.warn_deprecated(
- version, name=key, obj_type="rcparam", alternative=alt_key)
- return inverse_alt(self._get(alt_key))
-
- elif key in _deprecated_ignore_map:
- version, alt_key = _deprecated_ignore_map[key]
- _api.warn_deprecated(
- version, name=key, obj_type="rcparam", alternative=alt_key)
- return self._get(alt_key) if alt_key else None
-
- # In theory, this should only ever be used after the global rcParams
- # has been set up, but better be safe e.g. in presence of breakpoints.
- elif key == "backend" and self is globals().get("rcParams"):
- val = self._get(key)
- if val is rcsetup._auto_backend_sentinel:
- from matplotlib import pyplot as plt
- plt.switch_backend(rcsetup._auto_backend_sentinel)
-
- return self._get(key)
-
- def _get_backend_or_none(self):
- """Get the requested backend, if any, without triggering resolution."""
- backend = self._get("backend")
- return None if backend is rcsetup._auto_backend_sentinel else backend
-
- def __repr__(self):
- class_name = self.__class__.__name__
- indent = len(class_name) + 1
- with _api.suppress_matplotlib_deprecation_warning():
- repr_split = pprint.pformat(dict(self), indent=1,
- width=80 - indent).split('\n')
- repr_indented = ('\n' + ' ' * indent).join(repr_split)
- return f'{class_name}({repr_indented})'
-
- def __str__(self):
- return '\n'.join(map('{0[0]}: {0[1]}'.format, sorted(self.items())))
-
- def __iter__(self):
- """Yield sorted list of keys."""
- with _api.suppress_matplotlib_deprecation_warning():
- yield from sorted(dict.__iter__(self))
-
- def __len__(self):
- return dict.__len__(self)
-
- def find_all(self, pattern):
- """
- Return the subset of this RcParams dictionary whose keys match,
- using :func:`re.search`, the given ``pattern``.
-
- .. note::
-
- Changes to the returned dictionary are *not* propagated to
- the parent RcParams dictionary.
-
- """
- pattern_re = re.compile(pattern)
- return RcParams((key, value)
- for key, value in self.items()
- if pattern_re.search(key))
-
- def copy(self):
- """Copy this RcParams instance."""
- rccopy = RcParams()
- for k in self: # Skip deprecations and revalidation.
- rccopy._set(k, self._get(k))
- return rccopy
-
-
-def rc_params(fail_on_error=False):
- """Construct a `RcParams` instance from the default Matplotlib rc file."""
- return rc_params_from_file(matplotlib_fname(), fail_on_error)
-
-
-@functools.cache
-def _get_ssl_context():
- try:
- import certifi
- except ImportError:
- _log.debug("Could not import certifi.")
- return None
- import ssl
- return ssl.create_default_context(cafile=certifi.where())
-
-
-@contextlib.contextmanager
-def _open_file_or_url(fname):
- if (isinstance(fname, str)
- and fname.startswith(('http://', 'https://', 'ftp://', 'file:'))):
- import urllib.request
- ssl_ctx = _get_ssl_context()
- if ssl_ctx is None:
- _log.debug(
- "Could not get certifi ssl context, https may not work."
- )
- with urllib.request.urlopen(fname, context=ssl_ctx) as f:
- yield (line.decode('utf-8') for line in f)
- else:
- fname = os.path.expanduser(fname)
- with open(fname, encoding='utf-8') as f:
- yield f
-
-
-def _rc_params_in_file(fname, transform=lambda x: x, fail_on_error=False):
- """
- Construct a `RcParams` instance from file *fname*.
-
- Unlike `rc_params_from_file`, the configuration class only contains the
- parameters specified in the file (i.e. default values are not filled in).
-
- Parameters
- ----------
- fname : path-like
- The loaded file.
- transform : callable, default: the identity function
- A function called on each individual line of the file to transform it,
- before further parsing.
- fail_on_error : bool, default: False
- Whether invalid entries should result in an exception or a warning.
- """
- import matplotlib as mpl
- rc_temp = {}
- with _open_file_or_url(fname) as fd:
- try:
- for line_no, line in enumerate(fd, 1):
- line = transform(line)
- strippedline = cbook._strip_comment(line)
- if not strippedline:
- continue
- tup = strippedline.split(':', 1)
- if len(tup) != 2:
- _log.warning('Missing colon in file %r, line %d (%r)',
- fname, line_no, line.rstrip('\n'))
- continue
- key, val = tup
- key = key.strip()
- val = val.strip()
- if val.startswith('"') and val.endswith('"'):
- val = val[1:-1] # strip double quotes
- if key in rc_temp:
- _log.warning('Duplicate key in file %r, line %d (%r)',
- fname, line_no, line.rstrip('\n'))
- rc_temp[key] = (val, line, line_no)
- except UnicodeDecodeError:
- _log.warning('Cannot decode configuration file %r as utf-8.',
- fname)
- raise
-
- config = RcParams()
-
- for key, (val, line, line_no) in rc_temp.items():
- if key in rcsetup._validators:
- if fail_on_error:
- config[key] = val # try to convert to proper type or raise
- else:
- try:
- config[key] = val # try to convert to proper type or skip
- except Exception as msg:
- _log.warning('Bad value in file %r, line %d (%r): %s',
- fname, line_no, line.rstrip('\n'), msg)
- elif key in _deprecated_ignore_map:
- version, alt_key = _deprecated_ignore_map[key]
- _api.warn_deprecated(
- version, name=key, alternative=alt_key, obj_type='rcparam',
- addendum="Please update your matplotlibrc.")
- else:
- # __version__ must be looked up as an attribute to trigger the
- # module-level __getattr__.
- version = ('main' if '.post' in mpl.__version__
- else f'v{mpl.__version__}')
- _log.warning("""
-Bad key %(key)s in file %(fname)s, line %(line_no)s (%(line)r)
-You probably need to get an updated matplotlibrc file from
-https://github.com/matplotlib/matplotlib/blob/%(version)s/lib/matplotlib/mpl-data/matplotlibrc
-or from the matplotlib source distribution""",
- dict(key=key, fname=fname, line_no=line_no,
- line=line.rstrip('\n'), version=version))
- return config
-
-
-def rc_params_from_file(fname, fail_on_error=False, use_default_template=True):
- """
- Construct a `RcParams` from file *fname*.
-
- Parameters
- ----------
- fname : str or path-like
- A file with Matplotlib rc settings.
- fail_on_error : bool
- If True, raise an error when the parser fails to convert a parameter.
- use_default_template : bool
- If True, initialize with default parameters before updating with those
- in the given file. If False, the configuration class only contains the
- parameters specified in the file. (Useful for updating dicts.)
- """
- config_from_file = _rc_params_in_file(fname, fail_on_error=fail_on_error)
-
- if not use_default_template:
- return config_from_file
-
- with _api.suppress_matplotlib_deprecation_warning():
- config = RcParams({**rcParamsDefault, **config_from_file})
-
- if "".join(config['text.latex.preamble']):
- _log.info("""
-*****************************************************************
-You have the following UNSUPPORTED LaTeX preamble customizations:
-%s
-Please do not ask for support with these customizations active.
-*****************************************************************
-""", '\n'.join(config['text.latex.preamble']))
- _log.debug('loaded rc file %s', fname)
-
- return config
-
-
-# When constructing the global instances, we need to perform certain updates
-# by explicitly calling the superclass (dict.update, dict.items) to avoid
-# triggering resolution of _auto_backend_sentinel.
-rcParamsDefault = _rc_params_in_file(
- cbook._get_data_path("matplotlibrc"),
- # Strip leading comment.
- transform=lambda line: line[1:] if line.startswith("#") else line,
- fail_on_error=True)
-dict.update(rcParamsDefault, rcsetup._hardcoded_defaults)
-# Normally, the default matplotlibrc file contains *no* entry for backend (the
-# corresponding line starts with ##, not #; we fill on _auto_backend_sentinel
-# in that case. However, packagers can set a different default backend
-# (resulting in a normal `#backend: foo` line) in which case we should *not*
-# fill in _auto_backend_sentinel.
-dict.setdefault(rcParamsDefault, "backend", rcsetup._auto_backend_sentinel)
-rcParams = RcParams() # The global instance.
-dict.update(rcParams, dict.items(rcParamsDefault))
-dict.update(rcParams, _rc_params_in_file(matplotlib_fname()))
-rcParamsOrig = rcParams.copy()
-with _api.suppress_matplotlib_deprecation_warning():
- # This also checks that all rcParams are indeed listed in the template.
- # Assigning to rcsetup.defaultParams is left only for backcompat.
- defaultParams = rcsetup.defaultParams = {
- # We want to resolve deprecated rcParams, but not backend...
- key: [(rcsetup._auto_backend_sentinel if key == "backend" else
- rcParamsDefault[key]),
- validator]
- for key, validator in rcsetup._validators.items()}
-if rcParams['axes.formatter.use_locale']:
- locale.setlocale(locale.LC_ALL, '')
-
-
-def rc(group, **kwargs):
- """
- Set the current `.rcParams`. *group* is the grouping for the rc, e.g.,
- for ``lines.linewidth`` the group is ``lines``, for
- ``axes.facecolor``, the group is ``axes``, and so on. Group may
- also be a list or tuple of group names, e.g., (*xtick*, *ytick*).
- *kwargs* is a dictionary attribute name/value pairs, e.g.,::
-
- rc('lines', linewidth=2, color='r')
-
- sets the current `.rcParams` and is equivalent to::
-
- rcParams['lines.linewidth'] = 2
- rcParams['lines.color'] = 'r'
-
- The following aliases are available to save typing for interactive users:
-
- ===== =================
- Alias Property
- ===== =================
- 'lw' 'linewidth'
- 'ls' 'linestyle'
- 'c' 'color'
- 'fc' 'facecolor'
- 'ec' 'edgecolor'
- 'mew' 'markeredgewidth'
- 'aa' 'antialiased'
- ===== =================
-
- Thus you could abbreviate the above call as::
-
- rc('lines', lw=2, c='r')
-
- Note you can use python's kwargs dictionary facility to store
- dictionaries of default parameters. e.g., you can customize the
- font rc as follows::
-
- font = {'family' : 'monospace',
- 'weight' : 'bold',
- 'size' : 'larger'}
- rc('font', **font) # pass in the font dict as kwargs
-
- This enables you to easily switch between several configurations. Use
- ``matplotlib.style.use('default')`` or :func:`~matplotlib.rcdefaults` to
- restore the default `.rcParams` after changes.
-
- Notes
- -----
- Similar functionality is available by using the normal dict interface, i.e.
- ``rcParams.update({"lines.linewidth": 2, ...})`` (but ``rcParams.update``
- does not support abbreviations or grouping).
- """
-
- aliases = {
- 'lw': 'linewidth',
- 'ls': 'linestyle',
- 'c': 'color',
- 'fc': 'facecolor',
- 'ec': 'edgecolor',
- 'mew': 'markeredgewidth',
- 'aa': 'antialiased',
- }
-
- if isinstance(group, str):
- group = (group,)
- for g in group:
- for k, v in kwargs.items():
- name = aliases.get(k) or k
- key = f'{g}.{name}'
- try:
- rcParams[key] = v
- except KeyError as err:
- raise KeyError(('Unrecognized key "%s" for group "%s" and '
- 'name "%s"') % (key, g, name)) from err
-
-
-def rcdefaults():
- """
- Restore the `.rcParams` from Matplotlib's internal default style.
-
- Style-blacklisted `.rcParams` (defined in
- ``matplotlib.style.core.STYLE_BLACKLIST``) are not updated.
-
- See Also
- --------
- matplotlib.rc_file_defaults
- Restore the `.rcParams` from the rc file originally loaded by
- Matplotlib.
- matplotlib.style.use
- Use a specific style file. Call ``style.use('default')`` to restore
- the default style.
- """
- # Deprecation warnings were already handled when creating rcParamsDefault,
- # no need to reemit them here.
- with _api.suppress_matplotlib_deprecation_warning():
- from .style.core import STYLE_BLACKLIST
- rcParams.clear()
- rcParams.update({k: v for k, v in rcParamsDefault.items()
- if k not in STYLE_BLACKLIST})
-
-
-def rc_file_defaults():
- """
- Restore the `.rcParams` from the original rc file loaded by Matplotlib.
-
- Style-blacklisted `.rcParams` (defined in
- ``matplotlib.style.core.STYLE_BLACKLIST``) are not updated.
- """
- # Deprecation warnings were already handled when creating rcParamsOrig, no
- # need to reemit them here.
- with _api.suppress_matplotlib_deprecation_warning():
- from .style.core import STYLE_BLACKLIST
- rcParams.update({k: rcParamsOrig[k] for k in rcParamsOrig
- if k not in STYLE_BLACKLIST})
-
-
-def rc_file(fname, *, use_default_template=True):
- """
- Update `.rcParams` from file.
-
- Style-blacklisted `.rcParams` (defined in
- ``matplotlib.style.core.STYLE_BLACKLIST``) are not updated.
-
- Parameters
- ----------
- fname : str or path-like
- A file with Matplotlib rc settings.
-
- use_default_template : bool
- If True, initialize with default parameters before updating with those
- in the given file. If False, the current configuration persists
- and only the parameters specified in the file are updated.
- """
- # Deprecation warnings were already handled in rc_params_from_file, no need
- # to reemit them here.
- with _api.suppress_matplotlib_deprecation_warning():
- from .style.core import STYLE_BLACKLIST
- rc_from_file = rc_params_from_file(
- fname, use_default_template=use_default_template)
- rcParams.update({k: rc_from_file[k] for k in rc_from_file
- if k not in STYLE_BLACKLIST})
-
-
-@contextlib.contextmanager
-def rc_context(rc=None, fname=None):
- """
- Return a context manager for temporarily changing rcParams.
-
- The :rc:`backend` will not be reset by the context manager.
-
- rcParams changed both through the context manager invocation and
- in the body of the context will be reset on context exit.
-
- Parameters
- ----------
- rc : dict
- The rcParams to temporarily set.
- fname : str or path-like
- A file with Matplotlib rc settings. If both *fname* and *rc* are given,
- settings from *rc* take precedence.
-
- See Also
- --------
- :ref:`customizing-with-matplotlibrc-files`
-
- Examples
- --------
- Passing explicit values via a dict::
-
- with mpl.rc_context({'interactive': False}):
- fig, ax = plt.subplots()
- ax.plot(range(3), range(3))
- fig.savefig('example.png')
- plt.close(fig)
-
- Loading settings from a file::
-
- with mpl.rc_context(fname='print.rc'):
- plt.plot(x, y) # uses 'print.rc'
-
- Setting in the context body::
-
- with mpl.rc_context():
- # will be reset
- mpl.rcParams['lines.linewidth'] = 5
- plt.plot(x, y)
-
- """
- orig = dict(rcParams.copy())
- del orig['backend']
- try:
- if fname:
- rc_file(fname)
- if rc:
- rcParams.update(rc)
- yield
- finally:
- dict.update(rcParams, orig) # Revert to the original rcs.
-
-
-def use(backend, *, force=True):
- """
- Select the backend used for rendering and GUI integration.
-
- If pyplot is already imported, `~matplotlib.pyplot.switch_backend` is used
- and if the new backend is different than the current backend, all Figures
- will be closed.
-
- Parameters
- ----------
- backend : str
- The backend to switch to. This can either be one of the standard
- backend names, which are case-insensitive:
-
- - interactive backends:
- GTK3Agg, GTK3Cairo, GTK4Agg, GTK4Cairo, MacOSX, nbAgg, QtAgg,
- QtCairo, TkAgg, TkCairo, WebAgg, WX, WXAgg, WXCairo, Qt5Agg, Qt5Cairo
-
- - non-interactive backends:
- agg, cairo, pdf, pgf, ps, svg, template
-
- or a string of the form: ``module://my.module.name``.
-
- Switching to an interactive backend is not possible if an unrelated
- event loop has already been started (e.g., switching to GTK3Agg if a
- TkAgg window has already been opened). Switching to a non-interactive
- backend is always possible.
-
- force : bool, default: True
- If True (the default), raise an `ImportError` if the backend cannot be
- set up (either because it fails to import, or because an incompatible
- GUI interactive framework is already running); if False, silently
- ignore the failure.
-
- See Also
- --------
- :ref:`backends`
- matplotlib.get_backend
- matplotlib.pyplot.switch_backend
-
- """
- name = validate_backend(backend)
- # don't (prematurely) resolve the "auto" backend setting
- if rcParams._get_backend_or_none() == name:
- # Nothing to do if the requested backend is already set
- pass
- else:
- # if pyplot is not already imported, do not import it. Doing
- # so may trigger a `plt.switch_backend` to the _default_ backend
- # before we get a chance to change to the one the user just requested
- plt = sys.modules.get('matplotlib.pyplot')
- # if pyplot is imported, then try to change backends
- if plt is not None:
- try:
- # we need this import check here to re-raise if the
- # user does not have the libraries to support their
- # chosen backend installed.
- plt.switch_backend(name)
- except ImportError:
- if force:
- raise
- # if we have not imported pyplot, then we can set the rcParam
- # value which will be respected when the user finally imports
- # pyplot
- else:
- rcParams['backend'] = backend
- # if the user has asked for a given backend, do not helpfully
- # fallback
- rcParams['backend_fallback'] = False
-
-
-if os.environ.get('MPLBACKEND'):
- rcParams['backend'] = os.environ.get('MPLBACKEND')
-
-
-def get_backend():
- """
- Return the name of the current backend.
-
- See Also
- --------
- matplotlib.use
- """
- return rcParams['backend']
-
-
-def interactive(b):
- """
- Set whether to redraw after every plotting command (e.g. `.pyplot.xlabel`).
- """
- rcParams['interactive'] = b
-
-
-def is_interactive():
- """
- Return whether to redraw after every plotting command.
-
- .. note::
-
- This function is only intended for use in backends. End users should
- use `.pyplot.isinteractive` instead.
- """
- return rcParams['interactive']
-
-
-def _val_or_rc(val, rc_name):
- """
- If *val* is None, return ``mpl.rcParams[rc_name]``, otherwise return val.
- """
- return val if val is not None else rcParams[rc_name]
-
-
-def _init_tests():
- # The version of FreeType to install locally for running the
- # tests. This must match the value in `setupext.py`
- LOCAL_FREETYPE_VERSION = '2.6.1'
-
- from matplotlib import ft2font
- if (ft2font.__freetype_version__ != LOCAL_FREETYPE_VERSION or
- ft2font.__freetype_build_type__ != 'local'):
- _log.warning(
- f"Matplotlib is not built with the correct FreeType version to "
- f"run tests. Rebuild without setting system_freetype=1 in "
- f"mplsetup.cfg. Expect many image comparison failures below. "
- f"Expected freetype version {LOCAL_FREETYPE_VERSION}. "
- f"Found freetype version {ft2font.__freetype_version__}. "
- "Freetype build type is {}local".format(
- "" if ft2font.__freetype_build_type__ == 'local' else "not "))
-
-
-def _replacer(data, value):
- """
- Either returns ``data[value]`` or passes ``data`` back, converts either to
- a sequence.
- """
- try:
- # if key isn't a string don't bother
- if isinstance(value, str):
- # try to use __getitem__
- value = data[value]
- except Exception:
- # key does not exist, silently fall back to key
- pass
- return sanitize_sequence(value)
-
-
-def _label_from_arg(y, default_name):
- try:
- return y.name
- except AttributeError:
- if isinstance(default_name, str):
- return default_name
- return None
-
-
-def _add_data_doc(docstring, replace_names):
- """
- Add documentation for a *data* field to the given docstring.
-
- Parameters
- ----------
- docstring : str
- The input docstring.
- replace_names : list of str or None
- The list of parameter names which arguments should be replaced by
- ``data[name]`` (if ``data[name]`` does not throw an exception). If
- None, replacement is attempted for all arguments.
-
- Returns
- -------
- str
- The augmented docstring.
- """
- if (docstring is None
- or replace_names is not None and len(replace_names) == 0):
- return docstring
- docstring = inspect.cleandoc(docstring)
-
- data_doc = ("""\
- If given, all parameters also accept a string ``s``, which is
- interpreted as ``data[s]`` (unless this raises an exception)."""
- if replace_names is None else f"""\
- If given, the following parameters also accept a string ``s``, which is
- interpreted as ``data[s]`` (unless this raises an exception):
-
- {', '.join(map('*{}*'.format, replace_names))}""")
- # using string replacement instead of formatting has the advantages
- # 1) simpler indent handling
- # 2) prevent problems with formatting characters '{', '%' in the docstring
- if _log.level <= logging.DEBUG:
- # test_data_parameter_replacement() tests against these log messages
- # make sure to keep message and test in sync
- if "data : indexable object, optional" not in docstring:
- _log.debug("data parameter docstring error: no data parameter")
- if 'DATA_PARAMETER_PLACEHOLDER' not in docstring:
- _log.debug("data parameter docstring error: missing placeholder")
- return docstring.replace(' DATA_PARAMETER_PLACEHOLDER', data_doc)
-
-
-def _preprocess_data(func=None, *, replace_names=None, label_namer=None):
- """
- A decorator to add a 'data' kwarg to a function.
-
- When applied::
-
- @_preprocess_data()
- def func(ax, *args, **kwargs): ...
-
- the signature is modified to ``decorated(ax, *args, data=None, **kwargs)``
- with the following behavior:
-
- - if called with ``data=None``, forward the other arguments to ``func``;
- - otherwise, *data* must be a mapping; for any argument passed in as a
- string ``name``, replace the argument by ``data[name]`` (if this does not
- throw an exception), then forward the arguments to ``func``.
-
- In either case, any argument that is a `MappingView` is also converted to a
- list.
-
- Parameters
- ----------
- replace_names : list of str or None, default: None
- The list of parameter names for which lookup into *data* should be
- attempted. If None, replacement is attempted for all arguments.
- label_namer : str, default: None
- If set e.g. to "namer" (which must be a kwarg in the function's
- signature -- not as ``**kwargs``), if the *namer* argument passed in is
- a (string) key of *data* and no *label* kwarg is passed, then use the
- (string) value of the *namer* as *label*. ::
-
- @_preprocess_data(label_namer="foo")
- def func(foo, label=None): ...
-
- func("key", data={"key": value})
- # is equivalent to
- func.__wrapped__(value, label="key")
- """
-
- if func is None: # Return the actual decorator.
- return functools.partial(
- _preprocess_data,
- replace_names=replace_names, label_namer=label_namer)
-
- sig = inspect.signature(func)
- varargs_name = None
- varkwargs_name = None
- arg_names = []
- params = list(sig.parameters.values())
- for p in params:
- if p.kind is Parameter.VAR_POSITIONAL:
- varargs_name = p.name
- elif p.kind is Parameter.VAR_KEYWORD:
- varkwargs_name = p.name
- else:
- arg_names.append(p.name)
- data_param = Parameter("data", Parameter.KEYWORD_ONLY, default=None)
- if varkwargs_name:
- params.insert(-1, data_param)
- else:
- params.append(data_param)
- new_sig = sig.replace(parameters=params)
- arg_names = arg_names[1:] # remove the first "ax" / self arg
-
- assert {*arg_names}.issuperset(replace_names or []) or varkwargs_name, (
- "Matplotlib internal error: invalid replace_names "
- f"({replace_names!r}) for {func.__name__!r}")
- assert label_namer is None or label_namer in arg_names, (
- "Matplotlib internal error: invalid label_namer "
- f"({label_namer!r}) for {func.__name__!r}")
-
- @functools.wraps(func)
- def inner(ax, *args, data=None, **kwargs):
- if data is None:
- return func(ax, *map(sanitize_sequence, args), **kwargs)
-
- bound = new_sig.bind(ax, *args, **kwargs)
- auto_label = (bound.arguments.get(label_namer)
- or bound.kwargs.get(label_namer))
-
- for k, v in bound.arguments.items():
- if k == varkwargs_name:
- for k1, v1 in v.items():
- if replace_names is None or k1 in replace_names:
- v[k1] = _replacer(data, v1)
- elif k == varargs_name:
- if replace_names is None:
- bound.arguments[k] = tuple(_replacer(data, v1) for v1 in v)
- else:
- if replace_names is None or k in replace_names:
- bound.arguments[k] = _replacer(data, v)
-
- new_args = bound.args
- new_kwargs = bound.kwargs
-
- args_and_kwargs = {**bound.arguments, **bound.kwargs}
- if label_namer and "label" not in args_and_kwargs:
- new_kwargs["label"] = _label_from_arg(
- args_and_kwargs.get(label_namer), auto_label)
-
- return func(*new_args, **new_kwargs)
-
- inner.__doc__ = _add_data_doc(inner.__doc__, replace_names)
- inner.__signature__ = new_sig
- return inner
-
-
-_log.debug('interactive is %s', is_interactive())
-_log.debug('platform is %s', sys.platform)
-
-
-# workaround: we must defer colormaps import to after loading rcParams, because
-# colormap creation depends on rcParams
-from matplotlib.cm import _colormaps as colormaps
-from matplotlib.colors import _color_sequences as color_sequences
diff --git a/contrib/python/matplotlib/py3/matplotlib/__init__.pyi b/contrib/python/matplotlib/py3/matplotlib/__init__.pyi
deleted file mode 100644
index 8ef23a3dc4..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/__init__.pyi
+++ /dev/null
@@ -1,113 +0,0 @@
-__all__ = [
- "__bibtex__",
- "__version__",
- "__version_info__",
- "set_loglevel",
- "ExecutableNotFoundError",
- "get_configdir",
- "get_cachedir",
- "get_data_path",
- "matplotlib_fname",
- "MatplotlibDeprecationWarning",
- "RcParams",
- "rc_params",
- "rc_params_from_file",
- "rcParamsDefault",
- "rcParams",
- "rcParamsOrig",
- "defaultParams",
- "rc",
- "rcdefaults",
- "rc_file_defaults",
- "rc_file",
- "rc_context",
- "use",
- "get_backend",
- "interactive",
- "is_interactive",
- "colormaps",
- "color_sequences",
-]
-
-import os
-from pathlib import Path
-
-from collections.abc import Callable, Generator
-import contextlib
-from packaging.version import Version
-
-from matplotlib._api import MatplotlibDeprecationWarning
-from typing import Any, NamedTuple
-
-class _VersionInfo(NamedTuple):
- major: int
- minor: int
- micro: int
- releaselevel: str
- serial: int
-
-__bibtex__: str
-__version__: str
-__version_info__: _VersionInfo
-
-def set_loglevel(level: str) -> None: ...
-
-class _ExecInfo(NamedTuple):
- executable: str
- raw_version: str
- version: Version
-
-class ExecutableNotFoundError(FileNotFoundError): ...
-
-def _get_executable_info(name: str) -> _ExecInfo: ...
-def get_configdir() -> str: ...
-def get_cachedir() -> str: ...
-def get_data_path() -> str: ...
-def matplotlib_fname() -> str: ...
-
-class RcParams(dict[str, Any]):
- validate: dict[str, Callable]
- def __init__(self, *args, **kwargs) -> None: ...
- def __setitem__(self, key: str, val: Any) -> None: ...
- def __getitem__(self, key: str) -> Any: ...
- def __iter__(self) -> Generator[str, None, None]: ...
- def __len__(self) -> int: ...
- def find_all(self, pattern: str) -> RcParams: ...
- def copy(self) -> RcParams: ...
-
-def rc_params(fail_on_error: bool = ...) -> RcParams: ...
-def rc_params_from_file(
- fname: str | Path | os.PathLike,
- fail_on_error: bool = ...,
- use_default_template: bool = ...,
-) -> RcParams: ...
-
-rcParamsDefault: RcParams
-rcParams: RcParams
-rcParamsOrig: RcParams
-defaultParams: dict[str, Any]
-
-def rc(group: str, **kwargs) -> None: ...
-def rcdefaults() -> None: ...
-def rc_file_defaults() -> None: ...
-def rc_file(
- fname: str | Path | os.PathLike, *, use_default_template: bool = ...
-) -> None: ...
-@contextlib.contextmanager
-def rc_context(
- rc: dict[str, Any] | None = ..., fname: str | Path | os.PathLike | None = ...
-) -> Generator[None, None, None]: ...
-def use(backend: str, *, force: bool = ...) -> None: ...
-def get_backend() -> str: ...
-def interactive(b: bool) -> None: ...
-def is_interactive() -> bool: ...
-
-def _preprocess_data(
- func: Callable | None = ...,
- *,
- replace_names: list[str] | None = ...,
- label_namer: str | None = ...
-) -> Callable: ...
-
-from matplotlib.cm import _colormaps as colormaps
-from matplotlib.colors import _color_sequences as color_sequences
diff --git a/contrib/python/matplotlib/py3/matplotlib/_afm.py b/contrib/python/matplotlib/py3/matplotlib/_afm.py
deleted file mode 100644
index 558efe1639..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_afm.py
+++ /dev/null
@@ -1,532 +0,0 @@
-"""
-A python interface to Adobe Font Metrics Files.
-
-Although a number of other Python implementations exist, and may be more
-complete than this, it was decided not to go with them because they were
-either:
-
-1) copyrighted or used a non-BSD compatible license
-2) had too many dependencies and a free standing lib was needed
-3) did more than needed and it was easier to write afresh rather than
- figure out how to get just what was needed.
-
-It is pretty easy to use, and has no external dependencies:
-
->>> import matplotlib as mpl
->>> from pathlib import Path
->>> afm_path = Path(mpl.get_data_path(), 'fonts', 'afm', 'ptmr8a.afm')
->>>
->>> from matplotlib.afm import AFM
->>> with afm_path.open('rb') as fh:
-... afm = AFM(fh)
->>> afm.string_width_height('What the heck?')
-(6220.0, 694)
->>> afm.get_fontname()
-'Times-Roman'
->>> afm.get_kern_dist('A', 'f')
-0
->>> afm.get_kern_dist('A', 'y')
--92.0
->>> afm.get_bbox_char('!')
-[130, -9, 238, 676]
-
-As in the Adobe Font Metrics File Format Specification, all dimensions
-are given in units of 1/1000 of the scale factor (point size) of the font
-being used.
-"""
-
-from collections import namedtuple
-import logging
-import re
-
-from ._mathtext_data import uni2type1
-
-
-_log = logging.getLogger(__name__)
-
-
-def _to_int(x):
- # Some AFM files have floats where we are expecting ints -- there is
- # probably a better way to handle this (support floats, round rather than
- # truncate). But I don't know what the best approach is now and this
- # change to _to_int should at least prevent Matplotlib from crashing on
- # these. JDH (2009-11-06)
- return int(float(x))
-
-
-def _to_float(x):
- # Some AFM files use "," instead of "." as decimal separator -- this
- # shouldn't be ambiguous (unless someone is wicked enough to use "," as
- # thousands separator...).
- if isinstance(x, bytes):
- # Encoding doesn't really matter -- if we have codepoints >127 the call
- # to float() will error anyways.
- x = x.decode('latin-1')
- return float(x.replace(',', '.'))
-
-
-def _to_str(x):
- return x.decode('utf8')
-
-
-def _to_list_of_ints(s):
- s = s.replace(b',', b' ')
- return [_to_int(val) for val in s.split()]
-
-
-def _to_list_of_floats(s):
- return [_to_float(val) for val in s.split()]
-
-
-def _to_bool(s):
- if s.lower().strip() in (b'false', b'0', b'no'):
- return False
- else:
- return True
-
-
-def _parse_header(fh):
- """
- Read the font metrics header (up to the char metrics) and returns
- a dictionary mapping *key* to *val*. *val* will be converted to the
- appropriate python type as necessary; e.g.:
-
- * 'False'->False
- * '0'->0
- * '-168 -218 1000 898'-> [-168, -218, 1000, 898]
-
- Dictionary keys are
-
- StartFontMetrics, FontName, FullName, FamilyName, Weight,
- ItalicAngle, IsFixedPitch, FontBBox, UnderlinePosition,
- UnderlineThickness, Version, Notice, EncodingScheme, CapHeight,
- XHeight, Ascender, Descender, StartCharMetrics
- """
- header_converters = {
- b'StartFontMetrics': _to_float,
- b'FontName': _to_str,
- b'FullName': _to_str,
- b'FamilyName': _to_str,
- b'Weight': _to_str,
- b'ItalicAngle': _to_float,
- b'IsFixedPitch': _to_bool,
- b'FontBBox': _to_list_of_ints,
- b'UnderlinePosition': _to_float,
- b'UnderlineThickness': _to_float,
- b'Version': _to_str,
- # Some AFM files have non-ASCII characters (which are not allowed by
- # the spec). Given that there is actually no public API to even access
- # this field, just return it as straight bytes.
- b'Notice': lambda x: x,
- b'EncodingScheme': _to_str,
- b'CapHeight': _to_float, # Is the second version a mistake, or
- b'Capheight': _to_float, # do some AFM files contain 'Capheight'? -JKS
- b'XHeight': _to_float,
- b'Ascender': _to_float,
- b'Descender': _to_float,
- b'StdHW': _to_float,
- b'StdVW': _to_float,
- b'StartCharMetrics': _to_int,
- b'CharacterSet': _to_str,
- b'Characters': _to_int,
- }
- d = {}
- first_line = True
- for line in fh:
- line = line.rstrip()
- if line.startswith(b'Comment'):
- continue
- lst = line.split(b' ', 1)
- key = lst[0]
- if first_line:
- # AFM spec, Section 4: The StartFontMetrics keyword
- # [followed by a version number] must be the first line in
- # the file, and the EndFontMetrics keyword must be the
- # last non-empty line in the file. We just check the
- # first header entry.
- if key != b'StartFontMetrics':
- raise RuntimeError('Not an AFM file')
- first_line = False
- if len(lst) == 2:
- val = lst[1]
- else:
- val = b''
- try:
- converter = header_converters[key]
- except KeyError:
- _log.error("Found an unknown keyword in AFM header (was %r)", key)
- continue
- try:
- d[key] = converter(val)
- except ValueError:
- _log.error('Value error parsing header in AFM: %s, %s', key, val)
- continue
- if key == b'StartCharMetrics':
- break
- else:
- raise RuntimeError('Bad parse')
- return d
-
-
-CharMetrics = namedtuple('CharMetrics', 'width, name, bbox')
-CharMetrics.__doc__ = """
- Represents the character metrics of a single character.
-
- Notes
- -----
- The fields do currently only describe a subset of character metrics
- information defined in the AFM standard.
- """
-CharMetrics.width.__doc__ = """The character width (WX)."""
-CharMetrics.name.__doc__ = """The character name (N)."""
-CharMetrics.bbox.__doc__ = """
- The bbox of the character (B) as a tuple (*llx*, *lly*, *urx*, *ury*)."""
-
-
-def _parse_char_metrics(fh):
- """
- Parse the given filehandle for character metrics information and return
- the information as dicts.
-
- It is assumed that the file cursor is on the line behind
- 'StartCharMetrics'.
-
- Returns
- -------
- ascii_d : dict
- A mapping "ASCII num of the character" to `.CharMetrics`.
- name_d : dict
- A mapping "character name" to `.CharMetrics`.
-
- Notes
- -----
- This function is incomplete per the standard, but thus far parses
- all the sample afm files tried.
- """
- required_keys = {'C', 'WX', 'N', 'B'}
-
- ascii_d = {}
- name_d = {}
- for line in fh:
- # We are defensively letting values be utf8. The spec requires
- # ascii, but there are non-compliant fonts in circulation
- line = _to_str(line.rstrip()) # Convert from byte-literal
- if line.startswith('EndCharMetrics'):
- return ascii_d, name_d
- # Split the metric line into a dictionary, keyed by metric identifiers
- vals = dict(s.strip().split(' ', 1) for s in line.split(';') if s)
- # There may be other metrics present, but only these are needed
- if not required_keys.issubset(vals):
- raise RuntimeError('Bad char metrics line: %s' % line)
- num = _to_int(vals['C'])
- wx = _to_float(vals['WX'])
- name = vals['N']
- bbox = _to_list_of_floats(vals['B'])
- bbox = list(map(int, bbox))
- metrics = CharMetrics(wx, name, bbox)
- # Workaround: If the character name is 'Euro', give it the
- # corresponding character code, according to WinAnsiEncoding (see PDF
- # Reference).
- if name == 'Euro':
- num = 128
- elif name == 'minus':
- num = ord("\N{MINUS SIGN}") # 0x2212
- if num != -1:
- ascii_d[num] = metrics
- name_d[name] = metrics
- raise RuntimeError('Bad parse')
-
-
-def _parse_kern_pairs(fh):
- """
- Return a kern pairs dictionary; keys are (*char1*, *char2*) tuples and
- values are the kern pair value. For example, a kern pairs line like
- ``KPX A y -50``
-
- will be represented as::
-
- d[ ('A', 'y') ] = -50
-
- """
-
- line = next(fh)
- if not line.startswith(b'StartKernPairs'):
- raise RuntimeError('Bad start of kern pairs data: %s' % line)
-
- d = {}
- for line in fh:
- line = line.rstrip()
- if not line:
- continue
- if line.startswith(b'EndKernPairs'):
- next(fh) # EndKernData
- return d
- vals = line.split()
- if len(vals) != 4 or vals[0] != b'KPX':
- raise RuntimeError('Bad kern pairs line: %s' % line)
- c1, c2, val = _to_str(vals[1]), _to_str(vals[2]), _to_float(vals[3])
- d[(c1, c2)] = val
- raise RuntimeError('Bad kern pairs parse')
-
-
-CompositePart = namedtuple('CompositePart', 'name, dx, dy')
-CompositePart.__doc__ = """
- Represents the information on a composite element of a composite char."""
-CompositePart.name.__doc__ = """Name of the part, e.g. 'acute'."""
-CompositePart.dx.__doc__ = """x-displacement of the part from the origin."""
-CompositePart.dy.__doc__ = """y-displacement of the part from the origin."""
-
-
-def _parse_composites(fh):
- """
- Parse the given filehandle for composites information return them as a
- dict.
-
- It is assumed that the file cursor is on the line behind 'StartComposites'.
-
- Returns
- -------
- dict
- A dict mapping composite character names to a parts list. The parts
- list is a list of `.CompositePart` entries describing the parts of
- the composite.
-
- Examples
- --------
- A composite definition line::
-
- CC Aacute 2 ; PCC A 0 0 ; PCC acute 160 170 ;
-
- will be represented as::
-
- composites['Aacute'] = [CompositePart(name='A', dx=0, dy=0),
- CompositePart(name='acute', dx=160, dy=170)]
-
- """
- composites = {}
- for line in fh:
- line = line.rstrip()
- if not line:
- continue
- if line.startswith(b'EndComposites'):
- return composites
- vals = line.split(b';')
- cc = vals[0].split()
- name, _num_parts = cc[1], _to_int(cc[2])
- pccParts = []
- for s in vals[1:-1]:
- pcc = s.split()
- part = CompositePart(pcc[1], _to_float(pcc[2]), _to_float(pcc[3]))
- pccParts.append(part)
- composites[name] = pccParts
-
- raise RuntimeError('Bad composites parse')
-
-
-def _parse_optional(fh):
- """
- Parse the optional fields for kern pair data and composites.
-
- Returns
- -------
- kern_data : dict
- A dict containing kerning information. May be empty.
- See `._parse_kern_pairs`.
- composites : dict
- A dict containing composite information. May be empty.
- See `._parse_composites`.
- """
- optional = {
- b'StartKernData': _parse_kern_pairs,
- b'StartComposites': _parse_composites,
- }
-
- d = {b'StartKernData': {},
- b'StartComposites': {}}
- for line in fh:
- line = line.rstrip()
- if not line:
- continue
- key = line.split()[0]
-
- if key in optional:
- d[key] = optional[key](fh)
-
- return d[b'StartKernData'], d[b'StartComposites']
-
-
-class AFM:
-
- def __init__(self, fh):
- """Parse the AFM file in file object *fh*."""
- self._header = _parse_header(fh)
- self._metrics, self._metrics_by_name = _parse_char_metrics(fh)
- self._kern, self._composite = _parse_optional(fh)
-
- def get_bbox_char(self, c, isord=False):
- if not isord:
- c = ord(c)
- return self._metrics[c].bbox
-
- def string_width_height(self, s):
- """
- Return the string width (including kerning) and string height
- as a (*w*, *h*) tuple.
- """
- if not len(s):
- return 0, 0
- total_width = 0
- namelast = None
- miny = 1e9
- maxy = 0
- for c in s:
- if c == '\n':
- continue
- wx, name, bbox = self._metrics[ord(c)]
-
- total_width += wx + self._kern.get((namelast, name), 0)
- l, b, w, h = bbox
- miny = min(miny, b)
- maxy = max(maxy, b + h)
-
- namelast = name
-
- return total_width, maxy - miny
-
- def get_str_bbox_and_descent(self, s):
- """Return the string bounding box and the maximal descent."""
- if not len(s):
- return 0, 0, 0, 0, 0
- total_width = 0
- namelast = None
- miny = 1e9
- maxy = 0
- left = 0
- if not isinstance(s, str):
- s = _to_str(s)
- for c in s:
- if c == '\n':
- continue
- name = uni2type1.get(ord(c), f"uni{ord(c):04X}")
- try:
- wx, _, bbox = self._metrics_by_name[name]
- except KeyError:
- name = 'question'
- wx, _, bbox = self._metrics_by_name[name]
- total_width += wx + self._kern.get((namelast, name), 0)
- l, b, w, h = bbox
- left = min(left, l)
- miny = min(miny, b)
- maxy = max(maxy, b + h)
-
- namelast = name
-
- return left, miny, total_width, maxy - miny, -miny
-
- def get_str_bbox(self, s):
- """Return the string bounding box."""
- return self.get_str_bbox_and_descent(s)[:4]
-
- def get_name_char(self, c, isord=False):
- """Get the name of the character, i.e., ';' is 'semicolon'."""
- if not isord:
- c = ord(c)
- return self._metrics[c].name
-
- def get_width_char(self, c, isord=False):
- """
- Get the width of the character from the character metric WX field.
- """
- if not isord:
- c = ord(c)
- return self._metrics[c].width
-
- def get_width_from_char_name(self, name):
- """Get the width of the character from a type1 character name."""
- return self._metrics_by_name[name].width
-
- def get_height_char(self, c, isord=False):
- """Get the bounding box (ink) height of character *c* (space is 0)."""
- if not isord:
- c = ord(c)
- return self._metrics[c].bbox[-1]
-
- def get_kern_dist(self, c1, c2):
- """
- Return the kerning pair distance (possibly 0) for chars *c1* and *c2*.
- """
- name1, name2 = self.get_name_char(c1), self.get_name_char(c2)
- return self.get_kern_dist_from_name(name1, name2)
-
- def get_kern_dist_from_name(self, name1, name2):
- """
- Return the kerning pair distance (possibly 0) for chars
- *name1* and *name2*.
- """
- return self._kern.get((name1, name2), 0)
-
- def get_fontname(self):
- """Return the font name, e.g., 'Times-Roman'."""
- return self._header[b'FontName']
-
- @property
- def postscript_name(self): # For consistency with FT2Font.
- return self.get_fontname()
-
- def get_fullname(self):
- """Return the font full name, e.g., 'Times-Roman'."""
- name = self._header.get(b'FullName')
- if name is None: # use FontName as a substitute
- name = self._header[b'FontName']
- return name
-
- def get_familyname(self):
- """Return the font family name, e.g., 'Times'."""
- name = self._header.get(b'FamilyName')
- if name is not None:
- return name
-
- # FamilyName not specified so we'll make a guess
- name = self.get_fullname()
- extras = (r'(?i)([ -](regular|plain|italic|oblique|bold|semibold|'
- r'light|ultralight|extra|condensed))+$')
- return re.sub(extras, '', name)
-
- @property
- def family_name(self):
- """The font family name, e.g., 'Times'."""
- return self.get_familyname()
-
- def get_weight(self):
- """Return the font weight, e.g., 'Bold' or 'Roman'."""
- return self._header[b'Weight']
-
- def get_angle(self):
- """Return the fontangle as float."""
- return self._header[b'ItalicAngle']
-
- def get_capheight(self):
- """Return the cap height as float."""
- return self._header[b'CapHeight']
-
- def get_xheight(self):
- """Return the xheight as float."""
- return self._header[b'XHeight']
-
- def get_underline_thickness(self):
- """Return the underline thickness as float."""
- return self._header[b'UnderlineThickness']
-
- def get_horizontal_stem_width(self):
- """
- Return the standard horizontal stem width as float, or *None* if
- not specified in AFM file.
- """
- return self._header.get(b'StdHW', None)
-
- def get_vertical_stem_width(self):
- """
- Return the standard vertical stem width as float, or *None* if
- not specified in AFM file.
- """
- return self._header.get(b'StdVW', None)
diff --git a/contrib/python/matplotlib/py3/matplotlib/_animation_data.py b/contrib/python/matplotlib/py3/matplotlib/_animation_data.py
deleted file mode 100644
index 4bf2ae3148..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_animation_data.py
+++ /dev/null
@@ -1,262 +0,0 @@
-# JavaScript template for HTMLWriter
-JS_INCLUDE = """
-<link rel="stylesheet"
-href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
-<script language="javascript">
- function isInternetExplorer() {
- ua = navigator.userAgent;
- /* MSIE used to detect old browsers and Trident used to newer ones*/
- return ua.indexOf("MSIE ") > -1 || ua.indexOf("Trident/") > -1;
- }
-
- /* Define the Animation class */
- function Animation(frames, img_id, slider_id, interval, loop_select_id){
- this.img_id = img_id;
- this.slider_id = slider_id;
- this.loop_select_id = loop_select_id;
- this.interval = interval;
- this.current_frame = 0;
- this.direction = 0;
- this.timer = null;
- this.frames = new Array(frames.length);
-
- for (var i=0; i<frames.length; i++)
- {
- this.frames[i] = new Image();
- this.frames[i].src = frames[i];
- }
- var slider = document.getElementById(this.slider_id);
- slider.max = this.frames.length - 1;
- if (isInternetExplorer()) {
- // switch from oninput to onchange because IE <= 11 does not conform
- // with W3C specification. It ignores oninput and onchange behaves
- // like oninput. In contrast, Microsoft Edge behaves correctly.
- slider.setAttribute('onchange', slider.getAttribute('oninput'));
- slider.setAttribute('oninput', null);
- }
- this.set_frame(this.current_frame);
- }
-
- Animation.prototype.get_loop_state = function(){
- var button_group = document[this.loop_select_id].state;
- for (var i = 0; i < button_group.length; i++) {
- var button = button_group[i];
- if (button.checked) {
- return button.value;
- }
- }
- return undefined;
- }
-
- Animation.prototype.set_frame = function(frame){
- this.current_frame = frame;
- document.getElementById(this.img_id).src =
- this.frames[this.current_frame].src;
- document.getElementById(this.slider_id).value = this.current_frame;
- }
-
- Animation.prototype.next_frame = function()
- {
- this.set_frame(Math.min(this.frames.length - 1, this.current_frame + 1));
- }
-
- Animation.prototype.previous_frame = function()
- {
- this.set_frame(Math.max(0, this.current_frame - 1));
- }
-
- Animation.prototype.first_frame = function()
- {
- this.set_frame(0);
- }
-
- Animation.prototype.last_frame = function()
- {
- this.set_frame(this.frames.length - 1);
- }
-
- Animation.prototype.slower = function()
- {
- this.interval /= 0.7;
- if(this.direction > 0){this.play_animation();}
- else if(this.direction < 0){this.reverse_animation();}
- }
-
- Animation.prototype.faster = function()
- {
- this.interval *= 0.7;
- if(this.direction > 0){this.play_animation();}
- else if(this.direction < 0){this.reverse_animation();}
- }
-
- Animation.prototype.anim_step_forward = function()
- {
- this.current_frame += 1;
- if(this.current_frame < this.frames.length){
- this.set_frame(this.current_frame);
- }else{
- var loop_state = this.get_loop_state();
- if(loop_state == "loop"){
- this.first_frame();
- }else if(loop_state == "reflect"){
- this.last_frame();
- this.reverse_animation();
- }else{
- this.pause_animation();
- this.last_frame();
- }
- }
- }
-
- Animation.prototype.anim_step_reverse = function()
- {
- this.current_frame -= 1;
- if(this.current_frame >= 0){
- this.set_frame(this.current_frame);
- }else{
- var loop_state = this.get_loop_state();
- if(loop_state == "loop"){
- this.last_frame();
- }else if(loop_state == "reflect"){
- this.first_frame();
- this.play_animation();
- }else{
- this.pause_animation();
- this.first_frame();
- }
- }
- }
-
- Animation.prototype.pause_animation = function()
- {
- this.direction = 0;
- if (this.timer){
- clearInterval(this.timer);
- this.timer = null;
- }
- }
-
- Animation.prototype.play_animation = function()
- {
- this.pause_animation();
- this.direction = 1;
- var t = this;
- if (!this.timer) this.timer = setInterval(function() {
- t.anim_step_forward();
- }, this.interval);
- }
-
- Animation.prototype.reverse_animation = function()
- {
- this.pause_animation();
- this.direction = -1;
- var t = this;
- if (!this.timer) this.timer = setInterval(function() {
- t.anim_step_reverse();
- }, this.interval);
- }
-</script>
-"""
-
-
-# Style definitions for the HTML template
-STYLE_INCLUDE = """
-<style>
-.animation {
- display: inline-block;
- text-align: center;
-}
-input[type=range].anim-slider {
- width: 374px;
- margin-left: auto;
- margin-right: auto;
-}
-.anim-buttons {
- margin: 8px 0px;
-}
-.anim-buttons button {
- padding: 0;
- width: 36px;
-}
-.anim-state label {
- margin-right: 8px;
-}
-.anim-state input {
- margin: 0;
- vertical-align: middle;
-}
-</style>
-"""
-
-
-# HTML template for HTMLWriter
-DISPLAY_TEMPLATE = """
-<div class="animation">
- <img id="_anim_img{id}">
- <div class="anim-controls">
- <input id="_anim_slider{id}" type="range" class="anim-slider"
- name="points" min="0" max="1" step="1" value="0"
- oninput="anim{id}.set_frame(parseInt(this.value));">
- <div class="anim-buttons">
- <button title="Decrease speed" aria-label="Decrease speed" onclick="anim{id}.slower()">
- <i class="fa fa-minus"></i></button>
- <button title="First frame" aria-label="First frame" onclick="anim{id}.first_frame()">
- <i class="fa fa-fast-backward"></i></button>
- <button title="Previous frame" aria-label="Previous frame" onclick="anim{id}.previous_frame()">
- <i class="fa fa-step-backward"></i></button>
- <button title="Play backwards" aria-label="Play backwards" onclick="anim{id}.reverse_animation()">
- <i class="fa fa-play fa-flip-horizontal"></i></button>
- <button title="Pause" aria-label="Pause" onclick="anim{id}.pause_animation()">
- <i class="fa fa-pause"></i></button>
- <button title="Play" aria-label="Play" onclick="anim{id}.play_animation()">
- <i class="fa fa-play"></i></button>
- <button title="Next frame" aria-label="Next frame" onclick="anim{id}.next_frame()">
- <i class="fa fa-step-forward"></i></button>
- <button title="Last frame" aria-label="Last frame" onclick="anim{id}.last_frame()">
- <i class="fa fa-fast-forward"></i></button>
- <button title="Increase speed" aria-label="Increase speed" onclick="anim{id}.faster()">
- <i class="fa fa-plus"></i></button>
- </div>
- <form title="Repetition mode" aria-label="Repetition mode" action="#n" name="_anim_loop_select{id}"
- class="anim-state">
- <input type="radio" name="state" value="once" id="_anim_radio1_{id}"
- {once_checked}>
- <label for="_anim_radio1_{id}">Once</label>
- <input type="radio" name="state" value="loop" id="_anim_radio2_{id}"
- {loop_checked}>
- <label for="_anim_radio2_{id}">Loop</label>
- <input type="radio" name="state" value="reflect" id="_anim_radio3_{id}"
- {reflect_checked}>
- <label for="_anim_radio3_{id}">Reflect</label>
- </form>
- </div>
-</div>
-
-
-<script language="javascript">
- /* Instantiate the Animation class. */
- /* The IDs given should match those used in the template above. */
- (function() {{
- var img_id = "_anim_img{id}";
- var slider_id = "_anim_slider{id}";
- var loop_select_id = "_anim_loop_select{id}";
- var frames = new Array({Nframes});
- {fill_frames}
-
- /* set a timeout to make sure all the above elements are created before
- the object is initialized. */
- setTimeout(function() {{
- anim{id} = new Animation(frames, img_id, slider_id, {interval},
- loop_select_id);
- }}, 0);
- }})()
-</script>
-"""
-
-
-INCLUDED_FRAMES = """
- for (var i=0; i<{Nframes}; i++){{
- frames[i] = "{frame_dir}/frame" + ("0000000" + i).slice(-7) +
- ".{frame_format}";
- }}
-"""
diff --git a/contrib/python/matplotlib/py3/matplotlib/_api/__init__.py b/contrib/python/matplotlib/py3/matplotlib/_api/__init__.py
deleted file mode 100644
index 13319d867d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_api/__init__.py
+++ /dev/null
@@ -1,381 +0,0 @@
-"""
-Helper functions for managing the Matplotlib API.
-
-This documentation is only relevant for Matplotlib developers, not for users.
-
-.. warning::
-
- This module and its submodules are for internal use only. Do not use them
- in your own code. We may change the API at any time with no warning.
-
-"""
-
-import functools
-import itertools
-import re
-import sys
-import warnings
-
-from .deprecation import (
- deprecated, warn_deprecated,
- rename_parameter, delete_parameter, make_keyword_only,
- deprecate_method_override, deprecate_privatize_attribute,
- suppress_matplotlib_deprecation_warning,
- MatplotlibDeprecationWarning)
-
-
-class classproperty:
- """
- Like `property`, but also triggers on access via the class, and it is the
- *class* that's passed as argument.
-
- Examples
- --------
- ::
-
- class C:
- @classproperty
- def foo(cls):
- return cls.__name__
-
- assert C.foo == "C"
- """
-
- def __init__(self, fget, fset=None, fdel=None, doc=None):
- self._fget = fget
- if fset is not None or fdel is not None:
- raise ValueError('classproperty only implements fget.')
- self.fset = fset
- self.fdel = fdel
- # docs are ignored for now
- self._doc = doc
-
- def __get__(self, instance, owner):
- return self._fget(owner)
-
- @property
- def fget(self):
- return self._fget
-
-
-# In the following check_foo() functions, the first parameter is positional-only to make
-# e.g. `_api.check_isinstance([...], types=foo)` work.
-
-def check_isinstance(types, /, **kwargs):
- """
- For each *key, value* pair in *kwargs*, check that *value* is an instance
- of one of *types*; if not, raise an appropriate TypeError.
-
- As a special case, a ``None`` entry in *types* is treated as NoneType.
-
- Examples
- --------
- >>> _api.check_isinstance((SomeClass, None), arg=arg)
- """
- none_type = type(None)
- types = ((types,) if isinstance(types, type) else
- (none_type,) if types is None else
- tuple(none_type if tp is None else tp for tp in types))
-
- def type_name(tp):
- return ("None" if tp is none_type
- else tp.__qualname__ if tp.__module__ == "builtins"
- else f"{tp.__module__}.{tp.__qualname__}")
-
- for k, v in kwargs.items():
- if not isinstance(v, types):
- names = [*map(type_name, types)]
- if "None" in names: # Move it to the end for better wording.
- names.remove("None")
- names.append("None")
- raise TypeError(
- "{!r} must be an instance of {}, not a {}".format(
- k,
- ", ".join(names[:-1]) + " or " + names[-1]
- if len(names) > 1 else names[0],
- type_name(type(v))))
-
-
-def check_in_list(values, /, *, _print_supported_values=True, **kwargs):
- """
- For each *key, value* pair in *kwargs*, check that *value* is in *values*;
- if not, raise an appropriate ValueError.
-
- Parameters
- ----------
- values : iterable
- Sequence of values to check on.
- _print_supported_values : bool, default: True
- Whether to print *values* when raising ValueError.
- **kwargs : dict
- *key, value* pairs as keyword arguments to find in *values*.
-
- Raises
- ------
- ValueError
- If any *value* in *kwargs* is not found in *values*.
-
- Examples
- --------
- >>> _api.check_in_list(["foo", "bar"], arg=arg, other_arg=other_arg)
- """
- if not kwargs:
- raise TypeError("No argument to check!")
- for key, val in kwargs.items():
- if val not in values:
- msg = f"{val!r} is not a valid value for {key}"
- if _print_supported_values:
- msg += f"; supported values are {', '.join(map(repr, values))}"
- raise ValueError(msg)
-
-
-def check_shape(shape, /, **kwargs):
- """
- For each *key, value* pair in *kwargs*, check that *value* has the shape *shape*;
- if not, raise an appropriate ValueError.
-
- *None* in the shape is treated as a "free" size that can have any length.
- e.g. (None, 2) -> (N, 2)
-
- The values checked must be numpy arrays.
-
- Examples
- --------
- To check for (N, 2) shaped arrays
-
- >>> _api.check_shape((None, 2), arg=arg, other_arg=other_arg)
- """
- for k, v in kwargs.items():
- data_shape = v.shape
-
- if (len(data_shape) != len(shape)
- or any(s != t and t is not None for s, t in zip(data_shape, shape))):
- dim_labels = iter(itertools.chain(
- 'NMLKJIH',
- (f"D{i}" for i in itertools.count())))
- text_shape = ", ".join([str(n) if n is not None else next(dim_labels)
- for n in shape[::-1]][::-1])
- if len(shape) == 1:
- text_shape += ","
-
- raise ValueError(
- f"{k!r} must be {len(shape)}D with shape ({text_shape}), "
- f"but your input has shape {v.shape}"
- )
-
-
-def check_getitem(mapping, /, **kwargs):
- """
- *kwargs* must consist of a single *key, value* pair. If *key* is in
- *mapping*, return ``mapping[value]``; else, raise an appropriate
- ValueError.
-
- Examples
- --------
- >>> _api.check_getitem({"foo": "bar"}, arg=arg)
- """
- if len(kwargs) != 1:
- raise ValueError("check_getitem takes a single keyword argument")
- (k, v), = kwargs.items()
- try:
- return mapping[v]
- except KeyError:
- raise ValueError(
- f"{v!r} is not a valid value for {k}; supported values are "
- f"{', '.join(map(repr, mapping))}") from None
-
-
-def caching_module_getattr(cls):
- """
- Helper decorator for implementing module-level ``__getattr__`` as a class.
-
- This decorator must be used at the module toplevel as follows::
-
- @caching_module_getattr
- class __getattr__: # The class *must* be named ``__getattr__``.
- @property # Only properties are taken into account.
- def name(self): ...
-
- The ``__getattr__`` class will be replaced by a ``__getattr__``
- function such that trying to access ``name`` on the module will
- resolve the corresponding property (which may be decorated e.g. with
- ``_api.deprecated`` for deprecating module globals). The properties are
- all implicitly cached. Moreover, a suitable AttributeError is generated
- and raised if no property with the given name exists.
- """
-
- assert cls.__name__ == "__getattr__"
- # Don't accidentally export cls dunders.
- props = {name: prop for name, prop in vars(cls).items()
- if isinstance(prop, property)}
- instance = cls()
-
- @functools.cache
- def __getattr__(name):
- if name in props:
- return props[name].__get__(instance)
- raise AttributeError(
- f"module {cls.__module__!r} has no attribute {name!r}")
-
- return __getattr__
-
-
-def define_aliases(alias_d, cls=None):
- """
- Class decorator for defining property aliases.
-
- Use as ::
-
- @_api.define_aliases({"property": ["alias", ...], ...})
- class C: ...
-
- For each property, if the corresponding ``get_property`` is defined in the
- class so far, an alias named ``get_alias`` will be defined; the same will
- be done for setters. If neither the getter nor the setter exists, an
- exception will be raised.
-
- The alias map is stored as the ``_alias_map`` attribute on the class and
- can be used by `.normalize_kwargs` (which assumes that higher priority
- aliases come last).
- """
- if cls is None: # Return the actual class decorator.
- return functools.partial(define_aliases, alias_d)
-
- def make_alias(name): # Enforce a closure over *name*.
- @functools.wraps(getattr(cls, name))
- def method(self, *args, **kwargs):
- return getattr(self, name)(*args, **kwargs)
- return method
-
- for prop, aliases in alias_d.items():
- exists = False
- for prefix in ["get_", "set_"]:
- if prefix + prop in vars(cls):
- exists = True
- for alias in aliases:
- method = make_alias(prefix + prop)
- method.__name__ = prefix + alias
- method.__doc__ = f"Alias for `{prefix + prop}`."
- setattr(cls, prefix + alias, method)
- if not exists:
- raise ValueError(
- f"Neither getter nor setter exists for {prop!r}")
-
- def get_aliased_and_aliases(d):
- return {*d, *(alias for aliases in d.values() for alias in aliases)}
-
- preexisting_aliases = getattr(cls, "_alias_map", {})
- conflicting = (get_aliased_and_aliases(preexisting_aliases)
- & get_aliased_and_aliases(alias_d))
- if conflicting:
- # Need to decide on conflict resolution policy.
- raise NotImplementedError(
- f"Parent class already defines conflicting aliases: {conflicting}")
- cls._alias_map = {**preexisting_aliases, **alias_d}
- return cls
-
-
-def select_matching_signature(funcs, *args, **kwargs):
- """
- Select and call the function that accepts ``*args, **kwargs``.
-
- *funcs* is a list of functions which should not raise any exception (other
- than `TypeError` if the arguments passed do not match their signature).
-
- `select_matching_signature` tries to call each of the functions in *funcs*
- with ``*args, **kwargs`` (in the order in which they are given). Calls
- that fail with a `TypeError` are silently skipped. As soon as a call
- succeeds, `select_matching_signature` returns its return value. If no
- function accepts ``*args, **kwargs``, then the `TypeError` raised by the
- last failing call is re-raised.
-
- Callers should normally make sure that any ``*args, **kwargs`` can only
- bind a single *func* (to avoid any ambiguity), although this is not checked
- by `select_matching_signature`.
-
- Notes
- -----
- `select_matching_signature` is intended to help implementing
- signature-overloaded functions. In general, such functions should be
- avoided, except for back-compatibility concerns. A typical use pattern is
- ::
-
- def my_func(*args, **kwargs):
- params = select_matching_signature(
- [lambda old1, old2: locals(), lambda new: locals()],
- *args, **kwargs)
- if "old1" in params:
- warn_deprecated(...)
- old1, old2 = params.values() # note that locals() is ordered.
- else:
- new, = params.values()
- # do things with params
-
- which allows *my_func* to be called either with two parameters (*old1* and
- *old2*) or a single one (*new*). Note that the new signature is given
- last, so that callers get a `TypeError` corresponding to the new signature
- if the arguments they passed in do not match any signature.
- """
- # Rather than relying on locals() ordering, one could have just used func's
- # signature (``bound = inspect.signature(func).bind(*args, **kwargs);
- # bound.apply_defaults(); return bound``) but that is significantly slower.
- for i, func in enumerate(funcs):
- try:
- return func(*args, **kwargs)
- except TypeError:
- if i == len(funcs) - 1:
- raise
-
-
-def nargs_error(name, takes, given):
- """Generate a TypeError to be raised by function calls with wrong arity."""
- return TypeError(f"{name}() takes {takes} positional arguments but "
- f"{given} were given")
-
-
-def kwarg_error(name, kw):
- """
- Generate a TypeError to be raised by function calls with wrong kwarg.
-
- Parameters
- ----------
- name : str
- The name of the calling function.
- kw : str or Iterable[str]
- Either the invalid keyword argument name, or an iterable yielding
- invalid keyword arguments (e.g., a ``kwargs`` dict).
- """
- if not isinstance(kw, str):
- kw = next(iter(kw))
- return TypeError(f"{name}() got an unexpected keyword argument '{kw}'")
-
-
-def recursive_subclasses(cls):
- """Yield *cls* and direct and indirect subclasses of *cls*."""
- yield cls
- for subcls in cls.__subclasses__():
- yield from recursive_subclasses(subcls)
-
-
-def warn_external(message, category=None):
- """
- `warnings.warn` wrapper that sets *stacklevel* to "outside Matplotlib".
-
- The original emitter of the warning can be obtained by patching this
- function back to `warnings.warn`, i.e. ``_api.warn_external =
- warnings.warn`` (or ``functools.partial(warnings.warn, stacklevel=2)``,
- etc.).
- """
- frame = sys._getframe()
- for stacklevel in itertools.count(1):
- if frame is None:
- # when called in embedded context may hit frame is None
- break
- if not re.match(r"\A(matplotlib|mpl_toolkits)(\Z|\.(?!tests\.))",
- # Work around sphinx-gallery not setting __name__.
- frame.f_globals.get("__name__", "")):
- break
- frame = frame.f_back
- # preemptively break reference cycle between locals and the frame
- del frame
- warnings.warn(message, category, stacklevel)
diff --git a/contrib/python/matplotlib/py3/matplotlib/_api/__init__.pyi b/contrib/python/matplotlib/py3/matplotlib/_api/__init__.pyi
deleted file mode 100644
index 4baff7cd80..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_api/__init__.pyi
+++ /dev/null
@@ -1,59 +0,0 @@
-from collections.abc import Callable, Generator, Mapping, Sequence
-from typing import Any, Iterable, TypeVar, overload
-
-from numpy.typing import NDArray
-
-from .deprecation import ( # noqa: re-exported API
- deprecated as deprecated,
- warn_deprecated as warn_deprecated,
- rename_parameter as rename_parameter,
- delete_parameter as delete_parameter,
- make_keyword_only as make_keyword_only,
- deprecate_method_override as deprecate_method_override,
- deprecate_privatize_attribute as deprecate_privatize_attribute,
- suppress_matplotlib_deprecation_warning as suppress_matplotlib_deprecation_warning,
- MatplotlibDeprecationWarning as MatplotlibDeprecationWarning,
-)
-
-_T = TypeVar("_T")
-
-class classproperty(Any):
- def __init__(
- self,
- fget: Callable[[_T], Any],
- fset: None = ...,
- fdel: None = ...,
- doc: str | None = None,
- ): ...
- # Replace return with Self when py3.9 is dropped
- @overload
- def __get__(self, instance: None, owner: None) -> classproperty: ...
- @overload
- def __get__(self, instance: object, owner: type[object]) -> Any: ...
- @property
- def fget(self) -> Callable[[_T], Any]: ...
-
-def check_isinstance(
- types: type | tuple[type | None, ...], /, **kwargs: Any
-) -> None: ...
-def check_in_list(
- values: Sequence[Any], /, *, _print_supported_values: bool = ..., **kwargs: Any
-) -> None: ...
-def check_shape(shape: tuple[int | None, ...], /, **kwargs: NDArray) -> None: ...
-def check_getitem(mapping: Mapping[Any, Any], /, **kwargs: Any) -> Any: ...
-def caching_module_getattr(cls: type) -> Callable[[str], Any]: ...
-@overload
-def define_aliases(
- alias_d: dict[str, list[str]], cls: None = ...
-) -> Callable[[type[_T]], type[_T]]: ...
-@overload
-def define_aliases(alias_d: dict[str, list[str]], cls: type[_T]) -> type[_T]: ...
-def select_matching_signature(
- funcs: list[Callable], *args: Any, **kwargs: Any
-) -> Any: ...
-def nargs_error(name: str, takes: int | str, given: int) -> TypeError: ...
-def kwarg_error(name: str, kw: str | Iterable[str]) -> TypeError: ...
-def recursive_subclasses(cls: type) -> Generator[type, None, None]: ...
-def warn_external(
- message: str | Warning, category: type[Warning] | None = ...
-) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/_api/deprecation.py b/contrib/python/matplotlib/py3/matplotlib/_api/deprecation.py
deleted file mode 100644
index 7c304173b2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_api/deprecation.py
+++ /dev/null
@@ -1,510 +0,0 @@
-"""
-Helper functions for deprecating parts of the Matplotlib API.
-
-This documentation is only relevant for Matplotlib developers, not for users.
-
-.. warning::
-
- This module is for internal use only. Do not use it in your own code.
- We may change the API at any time with no warning.
-
-"""
-
-import contextlib
-import functools
-import inspect
-import math
-import warnings
-
-
-class MatplotlibDeprecationWarning(DeprecationWarning):
- """A class for issuing deprecation warnings for Matplotlib users."""
-
-
-def _generate_deprecation_warning(
- since, message='', name='', alternative='', pending=False, obj_type='',
- addendum='', *, removal=''):
- if pending:
- if removal:
- raise ValueError(
- "A pending deprecation cannot have a scheduled removal")
- else:
- removal = f"in {removal}" if removal else "two minor releases later"
- if not message:
- message = (
- ("The %(name)s %(obj_type)s" if obj_type else "%(name)s")
- + (" will be deprecated in a future version"
- if pending else
- (" was deprecated in Matplotlib %(since)s"
- + (" and will be removed %(removal)s" if removal else "")))
- + "."
- + (" Use %(alternative)s instead." if alternative else "")
- + (" %(addendum)s" if addendum else ""))
- warning_cls = (PendingDeprecationWarning if pending
- else MatplotlibDeprecationWarning)
- return warning_cls(message % dict(
- func=name, name=name, obj_type=obj_type, since=since, removal=removal,
- alternative=alternative, addendum=addendum))
-
-
-def warn_deprecated(
- since, *, message='', name='', alternative='', pending=False,
- obj_type='', addendum='', removal=''):
- """
- Display a standardized deprecation.
-
- Parameters
- ----------
- since : str
- The release at which this API became deprecated.
- message : str, optional
- Override the default deprecation message. The ``%(since)s``,
- ``%(name)s``, ``%(alternative)s``, ``%(obj_type)s``, ``%(addendum)s``,
- and ``%(removal)s`` format specifiers will be replaced by the values
- of the respective arguments passed to this function.
- name : str, optional
- The name of the deprecated object.
- alternative : str, optional
- An alternative API that the user may use in place of the deprecated
- API. The deprecation warning will tell the user about this alternative
- if provided.
- pending : bool, optional
- If True, uses a PendingDeprecationWarning instead of a
- DeprecationWarning. Cannot be used together with *removal*.
- obj_type : str, optional
- The object type being deprecated.
- addendum : str, optional
- Additional text appended directly to the final message.
- removal : str, optional
- The expected removal version. With the default (an empty string), a
- removal version is automatically computed from *since*. Set to other
- Falsy values to not schedule a removal date. Cannot be used together
- with *pending*.
-
- Examples
- --------
- ::
-
- # To warn of the deprecation of "matplotlib.name_of_module"
- warn_deprecated('1.4.0', name='matplotlib.name_of_module',
- obj_type='module')
- """
- warning = _generate_deprecation_warning(
- since, message, name, alternative, pending, obj_type, addendum,
- removal=removal)
- from . import warn_external
- warn_external(warning, category=MatplotlibDeprecationWarning)
-
-
-def deprecated(since, *, message='', name='', alternative='', pending=False,
- obj_type=None, addendum='', removal=''):
- """
- Decorator to mark a function, a class, or a property as deprecated.
-
- When deprecating a classmethod, a staticmethod, or a property, the
- ``@deprecated`` decorator should go *under* ``@classmethod`` and
- ``@staticmethod`` (i.e., `deprecated` should directly decorate the
- underlying callable), but *over* ``@property``.
-
- When deprecating a class ``C`` intended to be used as a base class in a
- multiple inheritance hierarchy, ``C`` *must* define an ``__init__`` method
- (if ``C`` instead inherited its ``__init__`` from its own base class, then
- ``@deprecated`` would mess up ``__init__`` inheritance when installing its
- own (deprecation-emitting) ``C.__init__``).
-
- Parameters are the same as for `warn_deprecated`, except that *obj_type*
- defaults to 'class' if decorating a class, 'attribute' if decorating a
- property, and 'function' otherwise.
-
- Examples
- --------
- ::
-
- @deprecated('1.4.0')
- def the_function_to_deprecate():
- pass
- """
-
- def deprecate(obj, message=message, name=name, alternative=alternative,
- pending=pending, obj_type=obj_type, addendum=addendum):
- from matplotlib._api import classproperty
-
- if isinstance(obj, type):
- if obj_type is None:
- obj_type = "class"
- func = obj.__init__
- name = name or obj.__name__
- old_doc = obj.__doc__
-
- def finalize(wrapper, new_doc):
- try:
- obj.__doc__ = new_doc
- except AttributeError: # Can't set on some extension objects.
- pass
- obj.__init__ = functools.wraps(obj.__init__)(wrapper)
- return obj
-
- elif isinstance(obj, (property, classproperty)):
- if obj_type is None:
- obj_type = "attribute"
- func = None
- name = name or obj.fget.__name__
- old_doc = obj.__doc__
-
- class _deprecated_property(type(obj)):
- def __get__(self, instance, owner=None):
- if instance is not None or owner is not None \
- and isinstance(self, classproperty):
- emit_warning()
- return super().__get__(instance, owner)
-
- def __set__(self, instance, value):
- if instance is not None:
- emit_warning()
- return super().__set__(instance, value)
-
- def __delete__(self, instance):
- if instance is not None:
- emit_warning()
- return super().__delete__(instance)
-
- def __set_name__(self, owner, set_name):
- nonlocal name
- if name == "<lambda>":
- name = set_name
-
- def finalize(_, new_doc):
- return _deprecated_property(
- fget=obj.fget, fset=obj.fset, fdel=obj.fdel, doc=new_doc)
-
- else:
- if obj_type is None:
- obj_type = "function"
- func = obj
- name = name or obj.__name__
- old_doc = func.__doc__
-
- def finalize(wrapper, new_doc):
- wrapper = functools.wraps(func)(wrapper)
- wrapper.__doc__ = new_doc
- return wrapper
-
- def emit_warning():
- warn_deprecated(
- since, message=message, name=name, alternative=alternative,
- pending=pending, obj_type=obj_type, addendum=addendum,
- removal=removal)
-
- def wrapper(*args, **kwargs):
- emit_warning()
- return func(*args, **kwargs)
-
- old_doc = inspect.cleandoc(old_doc or '').strip('\n')
-
- notes_header = '\nNotes\n-----'
- second_arg = ' '.join([t.strip() for t in
- (message, f"Use {alternative} instead."
- if alternative else "", addendum) if t])
- new_doc = (f"[*Deprecated*] {old_doc}\n"
- f"{notes_header if notes_header not in old_doc else ''}\n"
- f".. deprecated:: {since}\n"
- f" {second_arg}")
-
- if not old_doc:
- # This is to prevent a spurious 'unexpected unindent' warning from
- # docutils when the original docstring was blank.
- new_doc += r'\ '
-
- return finalize(wrapper, new_doc)
-
- return deprecate
-
-
-class deprecate_privatize_attribute:
- """
- Helper to deprecate public access to an attribute (or method).
-
- This helper should only be used at class scope, as follows::
-
- class Foo:
- attr = _deprecate_privatize_attribute(*args, **kwargs)
-
- where *all* parameters are forwarded to `deprecated`. This form makes
- ``attr`` a property which forwards read and write access to ``self._attr``
- (same name but with a leading underscore), with a deprecation warning.
- Note that the attribute name is derived from *the name this helper is
- assigned to*. This helper also works for deprecating methods.
- """
-
- def __init__(self, *args, **kwargs):
- self.deprecator = deprecated(*args, **kwargs)
-
- def __set_name__(self, owner, name):
- setattr(owner, name, self.deprecator(
- property(lambda self: getattr(self, f"_{name}"),
- lambda self, value: setattr(self, f"_{name}", value)),
- name=name))
-
-
-# Used by _copy_docstring_and_deprecators to redecorate pyplot wrappers and
-# boilerplate.py to retrieve original signatures. It may seem natural to store
-# this information as an attribute on the wrapper, but if the wrapper gets
-# itself functools.wraps()ed, then such attributes are silently propagated to
-# the outer wrapper, which is not desired.
-DECORATORS = {}
-
-
-def rename_parameter(since, old, new, func=None):
- """
- Decorator indicating that parameter *old* of *func* is renamed to *new*.
-
- The actual implementation of *func* should use *new*, not *old*. If *old*
- is passed to *func*, a DeprecationWarning is emitted, and its value is
- used, even if *new* is also passed by keyword (this is to simplify pyplot
- wrapper functions, which always pass *new* explicitly to the Axes method).
- If *new* is also passed but positionally, a TypeError will be raised by the
- underlying function during argument binding.
-
- Examples
- --------
- ::
-
- @_api.rename_parameter("3.1", "bad_name", "good_name")
- def func(good_name): ...
- """
-
- decorator = functools.partial(rename_parameter, since, old, new)
-
- if func is None:
- return decorator
-
- signature = inspect.signature(func)
- assert old not in signature.parameters, (
- f"Matplotlib internal error: {old!r} cannot be a parameter for "
- f"{func.__name__}()")
- assert new in signature.parameters, (
- f"Matplotlib internal error: {new!r} must be a parameter for "
- f"{func.__name__}()")
-
- @functools.wraps(func)
- def wrapper(*args, **kwargs):
- if old in kwargs:
- warn_deprecated(
- since, message=f"The {old!r} parameter of {func.__name__}() "
- f"has been renamed {new!r} since Matplotlib {since}; support "
- f"for the old name will be dropped %(removal)s.")
- kwargs[new] = kwargs.pop(old)
- return func(*args, **kwargs)
-
- # wrapper() must keep the same documented signature as func(): if we
- # instead made both *old* and *new* appear in wrapper()'s signature, they
- # would both show up in the pyplot function for an Axes method as well and
- # pyplot would explicitly pass both arguments to the Axes method.
-
- DECORATORS[wrapper] = decorator
- return wrapper
-
-
-class _deprecated_parameter_class:
- def __repr__(self):
- return "<deprecated parameter>"
-
-
-_deprecated_parameter = _deprecated_parameter_class()
-
-
-def delete_parameter(since, name, func=None, **kwargs):
- """
- Decorator indicating that parameter *name* of *func* is being deprecated.
-
- The actual implementation of *func* should keep the *name* parameter in its
- signature, or accept a ``**kwargs`` argument (through which *name* would be
- passed).
-
- Parameters that come after the deprecated parameter effectively become
- keyword-only (as they cannot be passed positionally without triggering the
- DeprecationWarning on the deprecated parameter), and should be marked as
- such after the deprecation period has passed and the deprecated parameter
- is removed.
-
- Parameters other than *since*, *name*, and *func* are keyword-only and
- forwarded to `.warn_deprecated`.
-
- Examples
- --------
- ::
-
- @_api.delete_parameter("3.1", "unused")
- def func(used_arg, other_arg, unused, more_args): ...
- """
-
- decorator = functools.partial(delete_parameter, since, name, **kwargs)
-
- if func is None:
- return decorator
-
- signature = inspect.signature(func)
- # Name of `**kwargs` parameter of the decorated function, typically
- # "kwargs" if such a parameter exists, or None if the decorated function
- # doesn't accept `**kwargs`.
- kwargs_name = next((param.name for param in signature.parameters.values()
- if param.kind == inspect.Parameter.VAR_KEYWORD), None)
- if name in signature.parameters:
- kind = signature.parameters[name].kind
- is_varargs = kind is inspect.Parameter.VAR_POSITIONAL
- is_varkwargs = kind is inspect.Parameter.VAR_KEYWORD
- if not is_varargs and not is_varkwargs:
- name_idx = (
- # Deprecated parameter can't be passed positionally.
- math.inf if kind is inspect.Parameter.KEYWORD_ONLY
- # If call site has no more than this number of parameters, the
- # deprecated parameter can't have been passed positionally.
- else [*signature.parameters].index(name))
- func.__signature__ = signature = signature.replace(parameters=[
- param.replace(default=_deprecated_parameter)
- if param.name == name else param
- for param in signature.parameters.values()])
- else:
- name_idx = -1 # Deprecated parameter can always have been passed.
- else:
- is_varargs = is_varkwargs = False
- # Deprecated parameter can't be passed positionally.
- name_idx = math.inf
- assert kwargs_name, (
- f"Matplotlib internal error: {name!r} must be a parameter for "
- f"{func.__name__}()")
-
- addendum = kwargs.pop('addendum', None)
-
- @functools.wraps(func)
- def wrapper(*inner_args, **inner_kwargs):
- if len(inner_args) <= name_idx and name not in inner_kwargs:
- # Early return in the simple, non-deprecated case (much faster than
- # calling bind()).
- return func(*inner_args, **inner_kwargs)
- arguments = signature.bind(*inner_args, **inner_kwargs).arguments
- if is_varargs and arguments.get(name):
- warn_deprecated(
- since, message=f"Additional positional arguments to "
- f"{func.__name__}() are deprecated since %(since)s and "
- f"support for them will be removed %(removal)s.")
- elif is_varkwargs and arguments.get(name):
- warn_deprecated(
- since, message=f"Additional keyword arguments to "
- f"{func.__name__}() are deprecated since %(since)s and "
- f"support for them will be removed %(removal)s.")
- # We cannot just check `name not in arguments` because the pyplot
- # wrappers always pass all arguments explicitly.
- elif any(name in d and d[name] != _deprecated_parameter
- for d in [arguments, arguments.get(kwargs_name, {})]):
- deprecation_addendum = (
- f"If any parameter follows {name!r}, they should be passed as "
- f"keyword, not positionally.")
- warn_deprecated(
- since,
- name=repr(name),
- obj_type=f"parameter of {func.__name__}()",
- addendum=(addendum + " " + deprecation_addendum) if addendum
- else deprecation_addendum,
- **kwargs)
- return func(*inner_args, **inner_kwargs)
-
- DECORATORS[wrapper] = decorator
- return wrapper
-
-
-def make_keyword_only(since, name, func=None):
- """
- Decorator indicating that passing parameter *name* (or any of the following
- ones) positionally to *func* is being deprecated.
-
- When used on a method that has a pyplot wrapper, this should be the
- outermost decorator, so that :file:`boilerplate.py` can access the original
- signature.
- """
-
- decorator = functools.partial(make_keyword_only, since, name)
-
- if func is None:
- return decorator
-
- signature = inspect.signature(func)
- POK = inspect.Parameter.POSITIONAL_OR_KEYWORD
- KWO = inspect.Parameter.KEYWORD_ONLY
- assert (name in signature.parameters
- and signature.parameters[name].kind == POK), (
- f"Matplotlib internal error: {name!r} must be a positional-or-keyword "
- f"parameter for {func.__name__}()")
- names = [*signature.parameters]
- name_idx = names.index(name)
- kwonly = [name for name in names[name_idx:]
- if signature.parameters[name].kind == POK]
-
- @functools.wraps(func)
- def wrapper(*args, **kwargs):
- # Don't use signature.bind here, as it would fail when stacked with
- # rename_parameter and an "old" argument name is passed in
- # (signature.bind would fail, but the actual call would succeed).
- if len(args) > name_idx:
- warn_deprecated(
- since, message="Passing the %(name)s %(obj_type)s "
- "positionally is deprecated since Matplotlib %(since)s; the "
- "parameter will become keyword-only %(removal)s.",
- name=name, obj_type=f"parameter of {func.__name__}()")
- return func(*args, **kwargs)
-
- # Don't modify *func*'s signature, as boilerplate.py needs it.
- wrapper.__signature__ = signature.replace(parameters=[
- param.replace(kind=KWO) if param.name in kwonly else param
- for param in signature.parameters.values()])
- DECORATORS[wrapper] = decorator
- return wrapper
-
-
-def deprecate_method_override(method, obj, *, allow_empty=False, **kwargs):
- """
- Return ``obj.method`` with a deprecation if it was overridden, else None.
-
- Parameters
- ----------
- method
- An unbound method, i.e. an expression of the form
- ``Class.method_name``. Remember that within the body of a method, one
- can always use ``__class__`` to refer to the class that is currently
- being defined.
- obj
- Either an object of the class where *method* is defined, or a subclass
- of that class.
- allow_empty : bool, default: False
- Whether to allow overrides by "empty" methods without emitting a
- warning.
- **kwargs
- Additional parameters passed to `warn_deprecated` to generate the
- deprecation warning; must at least include the "since" key.
- """
-
- def empty(): pass
- def empty_with_docstring(): """doc"""
-
- name = method.__name__
- bound_child = getattr(obj, name)
- bound_base = (
- method # If obj is a class, then we need to use unbound methods.
- if isinstance(bound_child, type(empty)) and isinstance(obj, type)
- else method.__get__(obj))
- if (bound_child != bound_base
- and (not allow_empty
- or (getattr(getattr(bound_child, "__code__", None),
- "co_code", None)
- not in [empty.__code__.co_code,
- empty_with_docstring.__code__.co_code]))):
- warn_deprecated(**{"name": name, "obj_type": "method", **kwargs})
- return bound_child
- return None
-
-
-@contextlib.contextmanager
-def suppress_matplotlib_deprecation_warning():
- with warnings.catch_warnings():
- warnings.simplefilter("ignore", MatplotlibDeprecationWarning)
- yield
diff --git a/contrib/python/matplotlib/py3/matplotlib/_api/deprecation.pyi b/contrib/python/matplotlib/py3/matplotlib/_api/deprecation.pyi
deleted file mode 100644
index 9619d1b484..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_api/deprecation.pyi
+++ /dev/null
@@ -1,76 +0,0 @@
-from collections.abc import Callable
-import contextlib
-from typing import Any, TypedDict, TypeVar, overload
-from typing_extensions import (
- ParamSpec, # < Py 3.10
- Unpack, # < Py 3.11
-)
-
-_P = ParamSpec("_P")
-_R = TypeVar("_R")
-_T = TypeVar("_T")
-
-class MatplotlibDeprecationWarning(DeprecationWarning): ...
-
-class DeprecationKwargs(TypedDict, total=False):
- message: str
- alternative: str
- pending: bool
- obj_type: str
- addendum: str
- removal: str
-
-class NamedDeprecationKwargs(DeprecationKwargs, total=False):
- name: str
-
-def warn_deprecated(since: str, **kwargs: Unpack[NamedDeprecationKwargs]) -> None: ...
-def deprecated(
- since: str, **kwargs: Unpack[NamedDeprecationKwargs]
-) -> Callable[[_T], _T]: ...
-
-class deprecate_privatize_attribute(Any):
- def __init__(self, since: str, **kwargs: Unpack[NamedDeprecationKwargs]): ...
- def __set_name__(self, owner: type[object], name: str) -> None: ...
-
-DECORATORS: dict[Callable, Callable] = ...
-
-@overload
-def rename_parameter(
- since: str, old: str, new: str, func: None = ...
-) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ...
-@overload
-def rename_parameter(
- since: str, old: str, new: str, func: Callable[_P, _R]
-) -> Callable[_P, _R]: ...
-
-class _deprecated_parameter_class: ...
-
-_deprecated_parameter: _deprecated_parameter_class
-
-@overload
-def delete_parameter(
- since: str, name: str, func: None = ..., **kwargs: Unpack[DeprecationKwargs]
-) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ...
-@overload
-def delete_parameter(
- since: str, name: str, func: Callable[_P, _R], **kwargs: Unpack[DeprecationKwargs]
-) -> Callable[_P, _R]: ...
-@overload
-def make_keyword_only(
- since: str, name: str, func: None = ...
-) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ...
-@overload
-def make_keyword_only(
- since: str, name: str, func: Callable[_P, _R]
-) -> Callable[_P, _R]: ...
-def deprecate_method_override(
- method: Callable[_P, _R],
- obj: object | type,
- *,
- allow_empty: bool = ...,
- since: str,
- **kwargs: Unpack[NamedDeprecationKwargs]
-) -> Callable[_P, _R]: ...
-def suppress_matplotlib_deprecation_warning() -> (
- contextlib.AbstractContextManager[None]
-): ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/_blocking_input.py b/contrib/python/matplotlib/py3/matplotlib/_blocking_input.py
deleted file mode 100644
index 45f0775714..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_blocking_input.py
+++ /dev/null
@@ -1,30 +0,0 @@
-def blocking_input_loop(figure, event_names, timeout, handler):
- """
- Run *figure*'s event loop while listening to interactive events.
-
- The events listed in *event_names* are passed to *handler*.
-
- This function is used to implement `.Figure.waitforbuttonpress`,
- `.Figure.ginput`, and `.Axes.clabel`.
-
- Parameters
- ----------
- figure : `~matplotlib.figure.Figure`
- event_names : list of str
- The names of the events passed to *handler*.
- timeout : float
- If positive, the event loop is stopped after *timeout* seconds.
- handler : Callable[[Event], Any]
- Function called for each event; it can force an early exit of the event
- loop by calling ``canvas.stop_event_loop()``.
- """
- if figure.canvas.manager:
- figure.show() # Ensure that the figure is shown if we are managing it.
- # Connect the events to the on_event function call.
- cids = [figure.canvas.mpl_connect(name, handler) for name in event_names]
- try:
- figure.canvas.start_event_loop(timeout) # Start event loop.
- finally: # Run even on exception like ctrl-c.
- # Disconnect the callbacks.
- for cid in cids:
- figure.canvas.mpl_disconnect(cid)
diff --git a/contrib/python/matplotlib/py3/matplotlib/_c_internal_utils.pyi b/contrib/python/matplotlib/py3/matplotlib/_c_internal_utils.pyi
deleted file mode 100644
index 3a211223be..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_c_internal_utils.pyi
+++ /dev/null
@@ -1 +0,0 @@
-def display_is_valid() -> bool: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/_cm.py b/contrib/python/matplotlib/py3/matplotlib/_cm.py
deleted file mode 100644
index b7a7c87895..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_cm.py
+++ /dev/null
@@ -1,1440 +0,0 @@
-"""
-Nothing here but dictionaries for generating LinearSegmentedColormaps,
-and a dictionary of these dictionaries.
-
-Documentation for each is in pyplot.colormaps(). Please update this
-with the purpose and type of your colormap if you add data for one here.
-"""
-
-from functools import partial
-
-import numpy as np
-
-_binary_data = {
- 'red': ((0., 1., 1.), (1., 0., 0.)),
- 'green': ((0., 1., 1.), (1., 0., 0.)),
- 'blue': ((0., 1., 1.), (1., 0., 0.))
- }
-
-_autumn_data = {'red': ((0., 1.0, 1.0), (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.), (1.0, 1.0, 1.0)),
- 'blue': ((0., 0., 0.), (1.0, 0., 0.))}
-
-_bone_data = {'red': ((0., 0., 0.),
- (0.746032, 0.652778, 0.652778),
- (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.),
- (0.365079, 0.319444, 0.319444),
- (0.746032, 0.777778, 0.777778),
- (1.0, 1.0, 1.0)),
- 'blue': ((0., 0., 0.),
- (0.365079, 0.444444, 0.444444),
- (1.0, 1.0, 1.0))}
-
-_cool_data = {'red': ((0., 0., 0.), (1.0, 1.0, 1.0)),
- 'green': ((0., 1., 1.), (1.0, 0., 0.)),
- 'blue': ((0., 1., 1.), (1.0, 1., 1.))}
-
-_copper_data = {'red': ((0., 0., 0.),
- (0.809524, 1.000000, 1.000000),
- (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.),
- (1.0, 0.7812, 0.7812)),
- 'blue': ((0., 0., 0.),
- (1.0, 0.4975, 0.4975))}
-
-def _flag_red(x): return 0.75 * np.sin((x * 31.5 + 0.25) * np.pi) + 0.5
-def _flag_green(x): return np.sin(x * 31.5 * np.pi)
-def _flag_blue(x): return 0.75 * np.sin((x * 31.5 - 0.25) * np.pi) + 0.5
-_flag_data = {'red': _flag_red, 'green': _flag_green, 'blue': _flag_blue}
-
-def _prism_red(x): return 0.75 * np.sin((x * 20.9 + 0.25) * np.pi) + 0.67
-def _prism_green(x): return 0.75 * np.sin((x * 20.9 - 0.25) * np.pi) + 0.33
-def _prism_blue(x): return -1.1 * np.sin((x * 20.9) * np.pi)
-_prism_data = {'red': _prism_red, 'green': _prism_green, 'blue': _prism_blue}
-
-def _ch_helper(gamma, s, r, h, p0, p1, x):
- """Helper function for generating picklable cubehelix colormaps."""
- # Apply gamma factor to emphasise low or high intensity values
- xg = x ** gamma
- # Calculate amplitude and angle of deviation from the black to white
- # diagonal in the plane of constant perceived intensity.
- a = h * xg * (1 - xg) / 2
- phi = 2 * np.pi * (s / 3 + r * x)
- return xg + a * (p0 * np.cos(phi) + p1 * np.sin(phi))
-
-def cubehelix(gamma=1.0, s=0.5, r=-1.5, h=1.0):
- """
- Return custom data dictionary of (r, g, b) conversion functions, which can
- be used with :func:`register_cmap`, for the cubehelix color scheme.
-
- Unlike most other color schemes cubehelix was designed by D.A. Green to
- be monotonically increasing in terms of perceived brightness.
- Also, when printed on a black and white postscript printer, the scheme
- results in a greyscale with monotonically increasing brightness.
- This color scheme is named cubehelix because the (r, g, b) values produced
- can be visualised as a squashed helix around the diagonal in the
- (r, g, b) color cube.
-
- For a unit color cube (i.e. 3D coordinates for (r, g, b) each in the
- range 0 to 1) the color scheme starts at (r, g, b) = (0, 0, 0), i.e. black,
- and finishes at (r, g, b) = (1, 1, 1), i.e. white. For some fraction *x*,
- between 0 and 1, the color is the corresponding grey value at that
- fraction along the black to white diagonal (x, x, x) plus a color
- element. This color element is calculated in a plane of constant
- perceived intensity and controlled by the following parameters.
-
- Parameters
- ----------
- gamma : float, default: 1
- Gamma factor emphasizing either low intensity values (gamma < 1), or
- high intensity values (gamma > 1).
- s : float, default: 0.5 (purple)
- The starting color.
- r : float, default: -1.5
- The number of r, g, b rotations in color that are made from the start
- to the end of the color scheme. The default of -1.5 corresponds to ->
- B -> G -> R -> B.
- h : float, default: 1
- The hue, i.e. how saturated the colors are. If this parameter is zero
- then the color scheme is purely a greyscale.
- """
- return {'red': partial(_ch_helper, gamma, s, r, h, -0.14861, 1.78277),
- 'green': partial(_ch_helper, gamma, s, r, h, -0.29227, -0.90649),
- 'blue': partial(_ch_helper, gamma, s, r, h, 1.97294, 0.0)}
-
-_cubehelix_data = cubehelix()
-
-_bwr_data = ((0.0, 0.0, 1.0), (1.0, 1.0, 1.0), (1.0, 0.0, 0.0))
-_brg_data = ((0.0, 0.0, 1.0), (1.0, 0.0, 0.0), (0.0, 1.0, 0.0))
-
-# Gnuplot palette functions
-def _g0(x): return 0
-def _g1(x): return 0.5
-def _g2(x): return 1
-def _g3(x): return x
-def _g4(x): return x ** 2
-def _g5(x): return x ** 3
-def _g6(x): return x ** 4
-def _g7(x): return np.sqrt(x)
-def _g8(x): return np.sqrt(np.sqrt(x))
-def _g9(x): return np.sin(x * np.pi / 2)
-def _g10(x): return np.cos(x * np.pi / 2)
-def _g11(x): return np.abs(x - 0.5)
-def _g12(x): return (2 * x - 1) ** 2
-def _g13(x): return np.sin(x * np.pi)
-def _g14(x): return np.abs(np.cos(x * np.pi))
-def _g15(x): return np.sin(x * 2 * np.pi)
-def _g16(x): return np.cos(x * 2 * np.pi)
-def _g17(x): return np.abs(np.sin(x * 2 * np.pi))
-def _g18(x): return np.abs(np.cos(x * 2 * np.pi))
-def _g19(x): return np.abs(np.sin(x * 4 * np.pi))
-def _g20(x): return np.abs(np.cos(x * 4 * np.pi))
-def _g21(x): return 3 * x
-def _g22(x): return 3 * x - 1
-def _g23(x): return 3 * x - 2
-def _g24(x): return np.abs(3 * x - 1)
-def _g25(x): return np.abs(3 * x - 2)
-def _g26(x): return (3 * x - 1) / 2
-def _g27(x): return (3 * x - 2) / 2
-def _g28(x): return np.abs((3 * x - 1) / 2)
-def _g29(x): return np.abs((3 * x - 2) / 2)
-def _g30(x): return x / 0.32 - 0.78125
-def _g31(x): return 2 * x - 0.84
-def _g32(x):
- ret = np.zeros(len(x))
- m = (x < 0.25)
- ret[m] = 4 * x[m]
- m = (x >= 0.25) & (x < 0.92)
- ret[m] = -2 * x[m] + 1.84
- m = (x >= 0.92)
- ret[m] = x[m] / 0.08 - 11.5
- return ret
-def _g33(x): return np.abs(2 * x - 0.5)
-def _g34(x): return 2 * x
-def _g35(x): return 2 * x - 0.5
-def _g36(x): return 2 * x - 1
-
-gfunc = {i: globals()[f"_g{i}"] for i in range(37)}
-
-_gnuplot_data = {
- 'red': gfunc[7],
- 'green': gfunc[5],
- 'blue': gfunc[15],
-}
-
-_gnuplot2_data = {
- 'red': gfunc[30],
- 'green': gfunc[31],
- 'blue': gfunc[32],
-}
-
-_ocean_data = {
- 'red': gfunc[23],
- 'green': gfunc[28],
- 'blue': gfunc[3],
-}
-
-_afmhot_data = {
- 'red': gfunc[34],
- 'green': gfunc[35],
- 'blue': gfunc[36],
-}
-
-_rainbow_data = {
- 'red': gfunc[33],
- 'green': gfunc[13],
- 'blue': gfunc[10],
-}
-
-_seismic_data = (
- (0.0, 0.0, 0.3), (0.0, 0.0, 1.0),
- (1.0, 1.0, 1.0), (1.0, 0.0, 0.0),
- (0.5, 0.0, 0.0))
-
-_terrain_data = (
- (0.00, (0.2, 0.2, 0.6)),
- (0.15, (0.0, 0.6, 1.0)),
- (0.25, (0.0, 0.8, 0.4)),
- (0.50, (1.0, 1.0, 0.6)),
- (0.75, (0.5, 0.36, 0.33)),
- (1.00, (1.0, 1.0, 1.0)))
-
-_gray_data = {'red': ((0., 0, 0), (1., 1, 1)),
- 'green': ((0., 0, 0), (1., 1, 1)),
- 'blue': ((0., 0, 0), (1., 1, 1))}
-
-_hot_data = {'red': ((0., 0.0416, 0.0416),
- (0.365079, 1.000000, 1.000000),
- (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.),
- (0.365079, 0.000000, 0.000000),
- (0.746032, 1.000000, 1.000000),
- (1.0, 1.0, 1.0)),
- 'blue': ((0., 0., 0.),
- (0.746032, 0.000000, 0.000000),
- (1.0, 1.0, 1.0))}
-
-_hsv_data = {'red': ((0., 1., 1.),
- (0.158730, 1.000000, 1.000000),
- (0.174603, 0.968750, 0.968750),
- (0.333333, 0.031250, 0.031250),
- (0.349206, 0.000000, 0.000000),
- (0.666667, 0.000000, 0.000000),
- (0.682540, 0.031250, 0.031250),
- (0.841270, 0.968750, 0.968750),
- (0.857143, 1.000000, 1.000000),
- (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.),
- (0.158730, 0.937500, 0.937500),
- (0.174603, 1.000000, 1.000000),
- (0.507937, 1.000000, 1.000000),
- (0.666667, 0.062500, 0.062500),
- (0.682540, 0.000000, 0.000000),
- (1.0, 0., 0.)),
- 'blue': ((0., 0., 0.),
- (0.333333, 0.000000, 0.000000),
- (0.349206, 0.062500, 0.062500),
- (0.507937, 1.000000, 1.000000),
- (0.841270, 1.000000, 1.000000),
- (0.857143, 0.937500, 0.937500),
- (1.0, 0.09375, 0.09375))}
-
-_jet_data = {'red': ((0.00, 0, 0),
- (0.35, 0, 0),
- (0.66, 1, 1),
- (0.89, 1, 1),
- (1.00, 0.5, 0.5)),
- 'green': ((0.000, 0, 0),
- (0.125, 0, 0),
- (0.375, 1, 1),
- (0.640, 1, 1),
- (0.910, 0, 0),
- (1.000, 0, 0)),
- 'blue': ((0.00, 0.5, 0.5),
- (0.11, 1, 1),
- (0.34, 1, 1),
- (0.65, 0, 0),
- (1.00, 0, 0))}
-
-_pink_data = {'red': ((0., 0.1178, 0.1178), (0.015873, 0.195857, 0.195857),
- (0.031746, 0.250661, 0.250661),
- (0.047619, 0.295468, 0.295468),
- (0.063492, 0.334324, 0.334324),
- (0.079365, 0.369112, 0.369112),
- (0.095238, 0.400892, 0.400892),
- (0.111111, 0.430331, 0.430331),
- (0.126984, 0.457882, 0.457882),
- (0.142857, 0.483867, 0.483867),
- (0.158730, 0.508525, 0.508525),
- (0.174603, 0.532042, 0.532042),
- (0.190476, 0.554563, 0.554563),
- (0.206349, 0.576204, 0.576204),
- (0.222222, 0.597061, 0.597061),
- (0.238095, 0.617213, 0.617213),
- (0.253968, 0.636729, 0.636729),
- (0.269841, 0.655663, 0.655663),
- (0.285714, 0.674066, 0.674066),
- (0.301587, 0.691980, 0.691980),
- (0.317460, 0.709441, 0.709441),
- (0.333333, 0.726483, 0.726483),
- (0.349206, 0.743134, 0.743134),
- (0.365079, 0.759421, 0.759421),
- (0.380952, 0.766356, 0.766356),
- (0.396825, 0.773229, 0.773229),
- (0.412698, 0.780042, 0.780042),
- (0.428571, 0.786796, 0.786796),
- (0.444444, 0.793492, 0.793492),
- (0.460317, 0.800132, 0.800132),
- (0.476190, 0.806718, 0.806718),
- (0.492063, 0.813250, 0.813250),
- (0.507937, 0.819730, 0.819730),
- (0.523810, 0.826160, 0.826160),
- (0.539683, 0.832539, 0.832539),
- (0.555556, 0.838870, 0.838870),
- (0.571429, 0.845154, 0.845154),
- (0.587302, 0.851392, 0.851392),
- (0.603175, 0.857584, 0.857584),
- (0.619048, 0.863731, 0.863731),
- (0.634921, 0.869835, 0.869835),
- (0.650794, 0.875897, 0.875897),
- (0.666667, 0.881917, 0.881917),
- (0.682540, 0.887896, 0.887896),
- (0.698413, 0.893835, 0.893835),
- (0.714286, 0.899735, 0.899735),
- (0.730159, 0.905597, 0.905597),
- (0.746032, 0.911421, 0.911421),
- (0.761905, 0.917208, 0.917208),
- (0.777778, 0.922958, 0.922958),
- (0.793651, 0.928673, 0.928673),
- (0.809524, 0.934353, 0.934353),
- (0.825397, 0.939999, 0.939999),
- (0.841270, 0.945611, 0.945611),
- (0.857143, 0.951190, 0.951190),
- (0.873016, 0.956736, 0.956736),
- (0.888889, 0.962250, 0.962250),
- (0.904762, 0.967733, 0.967733),
- (0.920635, 0.973185, 0.973185),
- (0.936508, 0.978607, 0.978607),
- (0.952381, 0.983999, 0.983999),
- (0.968254, 0.989361, 0.989361),
- (0.984127, 0.994695, 0.994695), (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.), (0.015873, 0.102869, 0.102869),
- (0.031746, 0.145479, 0.145479),
- (0.047619, 0.178174, 0.178174),
- (0.063492, 0.205738, 0.205738),
- (0.079365, 0.230022, 0.230022),
- (0.095238, 0.251976, 0.251976),
- (0.111111, 0.272166, 0.272166),
- (0.126984, 0.290957, 0.290957),
- (0.142857, 0.308607, 0.308607),
- (0.158730, 0.325300, 0.325300),
- (0.174603, 0.341178, 0.341178),
- (0.190476, 0.356348, 0.356348),
- (0.206349, 0.370899, 0.370899),
- (0.222222, 0.384900, 0.384900),
- (0.238095, 0.398410, 0.398410),
- (0.253968, 0.411476, 0.411476),
- (0.269841, 0.424139, 0.424139),
- (0.285714, 0.436436, 0.436436),
- (0.301587, 0.448395, 0.448395),
- (0.317460, 0.460044, 0.460044),
- (0.333333, 0.471405, 0.471405),
- (0.349206, 0.482498, 0.482498),
- (0.365079, 0.493342, 0.493342),
- (0.380952, 0.517549, 0.517549),
- (0.396825, 0.540674, 0.540674),
- (0.412698, 0.562849, 0.562849),
- (0.428571, 0.584183, 0.584183),
- (0.444444, 0.604765, 0.604765),
- (0.460317, 0.624669, 0.624669),
- (0.476190, 0.643958, 0.643958),
- (0.492063, 0.662687, 0.662687),
- (0.507937, 0.680900, 0.680900),
- (0.523810, 0.698638, 0.698638),
- (0.539683, 0.715937, 0.715937),
- (0.555556, 0.732828, 0.732828),
- (0.571429, 0.749338, 0.749338),
- (0.587302, 0.765493, 0.765493),
- (0.603175, 0.781313, 0.781313),
- (0.619048, 0.796819, 0.796819),
- (0.634921, 0.812029, 0.812029),
- (0.650794, 0.826960, 0.826960),
- (0.666667, 0.841625, 0.841625),
- (0.682540, 0.856040, 0.856040),
- (0.698413, 0.870216, 0.870216),
- (0.714286, 0.884164, 0.884164),
- (0.730159, 0.897896, 0.897896),
- (0.746032, 0.911421, 0.911421),
- (0.761905, 0.917208, 0.917208),
- (0.777778, 0.922958, 0.922958),
- (0.793651, 0.928673, 0.928673),
- (0.809524, 0.934353, 0.934353),
- (0.825397, 0.939999, 0.939999),
- (0.841270, 0.945611, 0.945611),
- (0.857143, 0.951190, 0.951190),
- (0.873016, 0.956736, 0.956736),
- (0.888889, 0.962250, 0.962250),
- (0.904762, 0.967733, 0.967733),
- (0.920635, 0.973185, 0.973185),
- (0.936508, 0.978607, 0.978607),
- (0.952381, 0.983999, 0.983999),
- (0.968254, 0.989361, 0.989361),
- (0.984127, 0.994695, 0.994695), (1.0, 1.0, 1.0)),
- 'blue': ((0., 0., 0.), (0.015873, 0.102869, 0.102869),
- (0.031746, 0.145479, 0.145479),
- (0.047619, 0.178174, 0.178174),
- (0.063492, 0.205738, 0.205738),
- (0.079365, 0.230022, 0.230022),
- (0.095238, 0.251976, 0.251976),
- (0.111111, 0.272166, 0.272166),
- (0.126984, 0.290957, 0.290957),
- (0.142857, 0.308607, 0.308607),
- (0.158730, 0.325300, 0.325300),
- (0.174603, 0.341178, 0.341178),
- (0.190476, 0.356348, 0.356348),
- (0.206349, 0.370899, 0.370899),
- (0.222222, 0.384900, 0.384900),
- (0.238095, 0.398410, 0.398410),
- (0.253968, 0.411476, 0.411476),
- (0.269841, 0.424139, 0.424139),
- (0.285714, 0.436436, 0.436436),
- (0.301587, 0.448395, 0.448395),
- (0.317460, 0.460044, 0.460044),
- (0.333333, 0.471405, 0.471405),
- (0.349206, 0.482498, 0.482498),
- (0.365079, 0.493342, 0.493342),
- (0.380952, 0.503953, 0.503953),
- (0.396825, 0.514344, 0.514344),
- (0.412698, 0.524531, 0.524531),
- (0.428571, 0.534522, 0.534522),
- (0.444444, 0.544331, 0.544331),
- (0.460317, 0.553966, 0.553966),
- (0.476190, 0.563436, 0.563436),
- (0.492063, 0.572750, 0.572750),
- (0.507937, 0.581914, 0.581914),
- (0.523810, 0.590937, 0.590937),
- (0.539683, 0.599824, 0.599824),
- (0.555556, 0.608581, 0.608581),
- (0.571429, 0.617213, 0.617213),
- (0.587302, 0.625727, 0.625727),
- (0.603175, 0.634126, 0.634126),
- (0.619048, 0.642416, 0.642416),
- (0.634921, 0.650600, 0.650600),
- (0.650794, 0.658682, 0.658682),
- (0.666667, 0.666667, 0.666667),
- (0.682540, 0.674556, 0.674556),
- (0.698413, 0.682355, 0.682355),
- (0.714286, 0.690066, 0.690066),
- (0.730159, 0.697691, 0.697691),
- (0.746032, 0.705234, 0.705234),
- (0.761905, 0.727166, 0.727166),
- (0.777778, 0.748455, 0.748455),
- (0.793651, 0.769156, 0.769156),
- (0.809524, 0.789314, 0.789314),
- (0.825397, 0.808969, 0.808969),
- (0.841270, 0.828159, 0.828159),
- (0.857143, 0.846913, 0.846913),
- (0.873016, 0.865261, 0.865261),
- (0.888889, 0.883229, 0.883229),
- (0.904762, 0.900837, 0.900837),
- (0.920635, 0.918109, 0.918109),
- (0.936508, 0.935061, 0.935061),
- (0.952381, 0.951711, 0.951711),
- (0.968254, 0.968075, 0.968075),
- (0.984127, 0.984167, 0.984167), (1.0, 1.0, 1.0))}
-
-_spring_data = {'red': ((0., 1., 1.), (1.0, 1.0, 1.0)),
- 'green': ((0., 0., 0.), (1.0, 1.0, 1.0)),
- 'blue': ((0., 1., 1.), (1.0, 0.0, 0.0))}
-
-
-_summer_data = {'red': ((0., 0., 0.), (1.0, 1.0, 1.0)),
- 'green': ((0., 0.5, 0.5), (1.0, 1.0, 1.0)),
- 'blue': ((0., 0.4, 0.4), (1.0, 0.4, 0.4))}
-
-
-_winter_data = {'red': ((0., 0., 0.), (1.0, 0.0, 0.0)),
- 'green': ((0., 0., 0.), (1.0, 1.0, 1.0)),
- 'blue': ((0., 1., 1.), (1.0, 0.5, 0.5))}
-
-_nipy_spectral_data = {
- 'red': [
- (0.0, 0.0, 0.0), (0.05, 0.4667, 0.4667),
- (0.10, 0.5333, 0.5333), (0.15, 0.0, 0.0),
- (0.20, 0.0, 0.0), (0.25, 0.0, 0.0),
- (0.30, 0.0, 0.0), (0.35, 0.0, 0.0),
- (0.40, 0.0, 0.0), (0.45, 0.0, 0.0),
- (0.50, 0.0, 0.0), (0.55, 0.0, 0.0),
- (0.60, 0.0, 0.0), (0.65, 0.7333, 0.7333),
- (0.70, 0.9333, 0.9333), (0.75, 1.0, 1.0),
- (0.80, 1.0, 1.0), (0.85, 1.0, 1.0),
- (0.90, 0.8667, 0.8667), (0.95, 0.80, 0.80),
- (1.0, 0.80, 0.80),
- ],
- 'green': [
- (0.0, 0.0, 0.0), (0.05, 0.0, 0.0),
- (0.10, 0.0, 0.0), (0.15, 0.0, 0.0),
- (0.20, 0.0, 0.0), (0.25, 0.4667, 0.4667),
- (0.30, 0.6000, 0.6000), (0.35, 0.6667, 0.6667),
- (0.40, 0.6667, 0.6667), (0.45, 0.6000, 0.6000),
- (0.50, 0.7333, 0.7333), (0.55, 0.8667, 0.8667),
- (0.60, 1.0, 1.0), (0.65, 1.0, 1.0),
- (0.70, 0.9333, 0.9333), (0.75, 0.8000, 0.8000),
- (0.80, 0.6000, 0.6000), (0.85, 0.0, 0.0),
- (0.90, 0.0, 0.0), (0.95, 0.0, 0.0),
- (1.0, 0.80, 0.80),
- ],
- 'blue': [
- (0.0, 0.0, 0.0), (0.05, 0.5333, 0.5333),
- (0.10, 0.6000, 0.6000), (0.15, 0.6667, 0.6667),
- (0.20, 0.8667, 0.8667), (0.25, 0.8667, 0.8667),
- (0.30, 0.8667, 0.8667), (0.35, 0.6667, 0.6667),
- (0.40, 0.5333, 0.5333), (0.45, 0.0, 0.0),
- (0.5, 0.0, 0.0), (0.55, 0.0, 0.0),
- (0.60, 0.0, 0.0), (0.65, 0.0, 0.0),
- (0.70, 0.0, 0.0), (0.75, 0.0, 0.0),
- (0.80, 0.0, 0.0), (0.85, 0.0, 0.0),
- (0.90, 0.0, 0.0), (0.95, 0.0, 0.0),
- (1.0, 0.80, 0.80),
- ],
-}
-
-
-# 34 colormaps based on color specifications and designs
-# developed by Cynthia Brewer (https://colorbrewer2.org/).
-# The ColorBrewer palettes have been included under the terms
-# of an Apache-stype license (for details, see the file
-# LICENSE_COLORBREWER in the license directory of the matplotlib
-# source distribution).
-
-# RGB values taken from Brewer's Excel sheet, divided by 255
-
-_Blues_data = (
- (0.96862745098039216, 0.98431372549019602, 1.0 ),
- (0.87058823529411766, 0.92156862745098034, 0.96862745098039216),
- (0.77647058823529413, 0.85882352941176465, 0.93725490196078431),
- (0.61960784313725492, 0.792156862745098 , 0.88235294117647056),
- (0.41960784313725491, 0.68235294117647061, 0.83921568627450982),
- (0.25882352941176473, 0.5725490196078431 , 0.77647058823529413),
- (0.12941176470588237, 0.44313725490196076, 0.70980392156862748),
- (0.03137254901960784, 0.31764705882352939, 0.61176470588235299),
- (0.03137254901960784, 0.18823529411764706, 0.41960784313725491)
- )
-
-_BrBG_data = (
- (0.32941176470588235, 0.18823529411764706, 0.0196078431372549 ),
- (0.5490196078431373 , 0.31764705882352939, 0.0392156862745098 ),
- (0.74901960784313726, 0.50588235294117645, 0.17647058823529413),
- (0.87450980392156863, 0.76078431372549016, 0.49019607843137253),
- (0.96470588235294119, 0.90980392156862744, 0.76470588235294112),
- (0.96078431372549022, 0.96078431372549022, 0.96078431372549022),
- (0.7803921568627451 , 0.91764705882352937, 0.89803921568627454),
- (0.50196078431372548, 0.80392156862745101, 0.75686274509803919),
- (0.20784313725490197, 0.59215686274509804, 0.5607843137254902 ),
- (0.00392156862745098, 0.4 , 0.36862745098039218),
- (0.0 , 0.23529411764705882, 0.18823529411764706)
- )
-
-_BuGn_data = (
- (0.96862745098039216, 0.9882352941176471 , 0.99215686274509807),
- (0.89803921568627454, 0.96078431372549022, 0.97647058823529409),
- (0.8 , 0.92549019607843142, 0.90196078431372551),
- (0.6 , 0.84705882352941175, 0.78823529411764703),
- (0.4 , 0.76078431372549016, 0.64313725490196083),
- (0.25490196078431371, 0.68235294117647061, 0.46274509803921571),
- (0.13725490196078433, 0.54509803921568623, 0.27058823529411763),
- (0.0 , 0.42745098039215684, 0.17254901960784313),
- (0.0 , 0.26666666666666666, 0.10588235294117647)
- )
-
-_BuPu_data = (
- (0.96862745098039216, 0.9882352941176471 , 0.99215686274509807),
- (0.8784313725490196 , 0.92549019607843142, 0.95686274509803926),
- (0.74901960784313726, 0.82745098039215681, 0.90196078431372551),
- (0.61960784313725492, 0.73725490196078436, 0.85490196078431369),
- (0.5490196078431373 , 0.58823529411764708, 0.77647058823529413),
- (0.5490196078431373 , 0.41960784313725491, 0.69411764705882351),
- (0.53333333333333333, 0.25490196078431371, 0.61568627450980395),
- (0.50588235294117645, 0.05882352941176471, 0.48627450980392156),
- (0.30196078431372547, 0.0 , 0.29411764705882354)
- )
-
-_GnBu_data = (
- (0.96862745098039216, 0.9882352941176471 , 0.94117647058823528),
- (0.8784313725490196 , 0.95294117647058818, 0.85882352941176465),
- (0.8 , 0.92156862745098034, 0.77254901960784317),
- (0.6588235294117647 , 0.8666666666666667 , 0.70980392156862748),
- (0.4823529411764706 , 0.8 , 0.7686274509803922 ),
- (0.30588235294117649, 0.70196078431372544, 0.82745098039215681),
- (0.16862745098039217, 0.5490196078431373 , 0.74509803921568629),
- (0.03137254901960784, 0.40784313725490196, 0.67450980392156867),
- (0.03137254901960784, 0.25098039215686274, 0.50588235294117645)
- )
-
-_Greens_data = (
- (0.96862745098039216, 0.9882352941176471 , 0.96078431372549022),
- (0.89803921568627454, 0.96078431372549022, 0.8784313725490196 ),
- (0.7803921568627451 , 0.9137254901960784 , 0.75294117647058822),
- (0.63137254901960782, 0.85098039215686272, 0.60784313725490191),
- (0.45490196078431372, 0.7686274509803922 , 0.46274509803921571),
- (0.25490196078431371, 0.6705882352941176 , 0.36470588235294116),
- (0.13725490196078433, 0.54509803921568623, 0.27058823529411763),
- (0.0 , 0.42745098039215684, 0.17254901960784313),
- (0.0 , 0.26666666666666666, 0.10588235294117647)
- )
-
-_Greys_data = (
- (1.0 , 1.0 , 1.0 ),
- (0.94117647058823528, 0.94117647058823528, 0.94117647058823528),
- (0.85098039215686272, 0.85098039215686272, 0.85098039215686272),
- (0.74117647058823533, 0.74117647058823533, 0.74117647058823533),
- (0.58823529411764708, 0.58823529411764708, 0.58823529411764708),
- (0.45098039215686275, 0.45098039215686275, 0.45098039215686275),
- (0.32156862745098042, 0.32156862745098042, 0.32156862745098042),
- (0.14509803921568629, 0.14509803921568629, 0.14509803921568629),
- (0.0 , 0.0 , 0.0 )
- )
-
-_Oranges_data = (
- (1.0 , 0.96078431372549022, 0.92156862745098034),
- (0.99607843137254903, 0.90196078431372551, 0.80784313725490198),
- (0.99215686274509807, 0.81568627450980391, 0.63529411764705879),
- (0.99215686274509807, 0.68235294117647061, 0.41960784313725491),
- (0.99215686274509807, 0.55294117647058827, 0.23529411764705882),
- (0.94509803921568625, 0.41176470588235292, 0.07450980392156863),
- (0.85098039215686272, 0.28235294117647058, 0.00392156862745098),
- (0.65098039215686276, 0.21176470588235294, 0.01176470588235294),
- (0.49803921568627452, 0.15294117647058825, 0.01568627450980392)
- )
-
-_OrRd_data = (
- (1.0 , 0.96862745098039216, 0.92549019607843142),
- (0.99607843137254903, 0.90980392156862744, 0.78431372549019607),
- (0.99215686274509807, 0.83137254901960789, 0.61960784313725492),
- (0.99215686274509807, 0.73333333333333328, 0.51764705882352946),
- (0.9882352941176471 , 0.55294117647058827, 0.34901960784313724),
- (0.93725490196078431, 0.396078431372549 , 0.28235294117647058),
- (0.84313725490196079, 0.18823529411764706, 0.12156862745098039),
- (0.70196078431372544, 0.0 , 0.0 ),
- (0.49803921568627452, 0.0 , 0.0 )
- )
-
-_PiYG_data = (
- (0.55686274509803924, 0.00392156862745098, 0.32156862745098042),
- (0.77254901960784317, 0.10588235294117647, 0.49019607843137253),
- (0.87058823529411766, 0.46666666666666667, 0.68235294117647061),
- (0.94509803921568625, 0.71372549019607845, 0.85490196078431369),
- (0.99215686274509807, 0.8784313725490196 , 0.93725490196078431),
- (0.96862745098039216, 0.96862745098039216, 0.96862745098039216),
- (0.90196078431372551, 0.96078431372549022, 0.81568627450980391),
- (0.72156862745098038, 0.88235294117647056, 0.52549019607843139),
- (0.49803921568627452, 0.73725490196078436, 0.25490196078431371),
- (0.30196078431372547, 0.5725490196078431 , 0.12941176470588237),
- (0.15294117647058825, 0.39215686274509803, 0.09803921568627451)
- )
-
-_PRGn_data = (
- (0.25098039215686274, 0.0 , 0.29411764705882354),
- (0.46274509803921571, 0.16470588235294117, 0.51372549019607838),
- (0.6 , 0.4392156862745098 , 0.6705882352941176 ),
- (0.76078431372549016, 0.6470588235294118 , 0.81176470588235294),
- (0.90588235294117647, 0.83137254901960789, 0.90980392156862744),
- (0.96862745098039216, 0.96862745098039216, 0.96862745098039216),
- (0.85098039215686272, 0.94117647058823528, 0.82745098039215681),
- (0.65098039215686276, 0.85882352941176465, 0.62745098039215685),
- (0.35294117647058826, 0.68235294117647061, 0.38039215686274508),
- (0.10588235294117647, 0.47058823529411764, 0.21568627450980393),
- (0.0 , 0.26666666666666666, 0.10588235294117647)
- )
-
-_PuBu_data = (
- (1.0 , 0.96862745098039216, 0.98431372549019602),
- (0.92549019607843142, 0.90588235294117647, 0.94901960784313721),
- (0.81568627450980391, 0.81960784313725488, 0.90196078431372551),
- (0.65098039215686276, 0.74117647058823533, 0.85882352941176465),
- (0.45490196078431372, 0.66274509803921566, 0.81176470588235294),
- (0.21176470588235294, 0.56470588235294117, 0.75294117647058822),
- (0.0196078431372549 , 0.4392156862745098 , 0.69019607843137254),
- (0.01568627450980392, 0.35294117647058826, 0.55294117647058827),
- (0.00784313725490196, 0.2196078431372549 , 0.34509803921568627)
- )
-
-_PuBuGn_data = (
- (1.0 , 0.96862745098039216, 0.98431372549019602),
- (0.92549019607843142, 0.88627450980392153, 0.94117647058823528),
- (0.81568627450980391, 0.81960784313725488, 0.90196078431372551),
- (0.65098039215686276, 0.74117647058823533, 0.85882352941176465),
- (0.40392156862745099, 0.66274509803921566, 0.81176470588235294),
- (0.21176470588235294, 0.56470588235294117, 0.75294117647058822),
- (0.00784313725490196, 0.50588235294117645, 0.54117647058823526),
- (0.00392156862745098, 0.42352941176470588, 0.34901960784313724),
- (0.00392156862745098, 0.27450980392156865, 0.21176470588235294)
- )
-
-_PuOr_data = (
- (0.49803921568627452, 0.23137254901960785, 0.03137254901960784),
- (0.70196078431372544, 0.34509803921568627, 0.02352941176470588),
- (0.8784313725490196 , 0.50980392156862742, 0.07843137254901961),
- (0.99215686274509807, 0.72156862745098038, 0.38823529411764707),
- (0.99607843137254903, 0.8784313725490196 , 0.71372549019607845),
- (0.96862745098039216, 0.96862745098039216, 0.96862745098039216),
- (0.84705882352941175, 0.85490196078431369, 0.92156862745098034),
- (0.69803921568627447, 0.6705882352941176 , 0.82352941176470584),
- (0.50196078431372548, 0.45098039215686275, 0.67450980392156867),
- (0.32941176470588235, 0.15294117647058825, 0.53333333333333333),
- (0.17647058823529413, 0.0 , 0.29411764705882354)
- )
-
-_PuRd_data = (
- (0.96862745098039216, 0.95686274509803926, 0.97647058823529409),
- (0.90588235294117647, 0.88235294117647056, 0.93725490196078431),
- (0.83137254901960789, 0.72549019607843135, 0.85490196078431369),
- (0.78823529411764703, 0.58039215686274515, 0.7803921568627451 ),
- (0.87450980392156863, 0.396078431372549 , 0.69019607843137254),
- (0.90588235294117647, 0.16078431372549021, 0.54117647058823526),
- (0.80784313725490198, 0.07058823529411765, 0.33725490196078434),
- (0.59607843137254901, 0.0 , 0.2627450980392157 ),
- (0.40392156862745099, 0.0 , 0.12156862745098039)
- )
-
-_Purples_data = (
- (0.9882352941176471 , 0.98431372549019602, 0.99215686274509807),
- (0.93725490196078431, 0.92941176470588238, 0.96078431372549022),
- (0.85490196078431369, 0.85490196078431369, 0.92156862745098034),
- (0.73725490196078436, 0.74117647058823533, 0.86274509803921573),
- (0.61960784313725492, 0.60392156862745094, 0.78431372549019607),
- (0.50196078431372548, 0.49019607843137253, 0.72941176470588232),
- (0.41568627450980394, 0.31764705882352939, 0.63921568627450975),
- (0.32941176470588235, 0.15294117647058825, 0.5607843137254902 ),
- (0.24705882352941178, 0.0 , 0.49019607843137253)
- )
-
-_RdBu_data = (
- (0.40392156862745099, 0.0 , 0.12156862745098039),
- (0.69803921568627447, 0.09411764705882353, 0.16862745098039217),
- (0.83921568627450982, 0.37647058823529411, 0.30196078431372547),
- (0.95686274509803926, 0.6470588235294118 , 0.50980392156862742),
- (0.99215686274509807, 0.85882352941176465, 0.7803921568627451 ),
- (0.96862745098039216, 0.96862745098039216, 0.96862745098039216),
- (0.81960784313725488, 0.89803921568627454, 0.94117647058823528),
- (0.5725490196078431 , 0.77254901960784317, 0.87058823529411766),
- (0.2627450980392157 , 0.57647058823529407, 0.76470588235294112),
- (0.12941176470588237, 0.4 , 0.67450980392156867),
- (0.0196078431372549 , 0.18823529411764706, 0.38039215686274508)
- )
-
-_RdGy_data = (
- (0.40392156862745099, 0.0 , 0.12156862745098039),
- (0.69803921568627447, 0.09411764705882353, 0.16862745098039217),
- (0.83921568627450982, 0.37647058823529411, 0.30196078431372547),
- (0.95686274509803926, 0.6470588235294118 , 0.50980392156862742),
- (0.99215686274509807, 0.85882352941176465, 0.7803921568627451 ),
- (1.0 , 1.0 , 1.0 ),
- (0.8784313725490196 , 0.8784313725490196 , 0.8784313725490196 ),
- (0.72941176470588232, 0.72941176470588232, 0.72941176470588232),
- (0.52941176470588236, 0.52941176470588236, 0.52941176470588236),
- (0.30196078431372547, 0.30196078431372547, 0.30196078431372547),
- (0.10196078431372549, 0.10196078431372549, 0.10196078431372549)
- )
-
-_RdPu_data = (
- (1.0 , 0.96862745098039216, 0.95294117647058818),
- (0.99215686274509807, 0.8784313725490196 , 0.86666666666666667),
- (0.9882352941176471 , 0.77254901960784317, 0.75294117647058822),
- (0.98039215686274506, 0.62352941176470589, 0.70980392156862748),
- (0.96862745098039216, 0.40784313725490196, 0.63137254901960782),
- (0.86666666666666667, 0.20392156862745098, 0.59215686274509804),
- (0.68235294117647061, 0.00392156862745098, 0.49411764705882355),
- (0.47843137254901963, 0.00392156862745098, 0.46666666666666667),
- (0.28627450980392155, 0.0 , 0.41568627450980394)
- )
-
-_RdYlBu_data = (
- (0.6470588235294118 , 0.0 , 0.14901960784313725),
- (0.84313725490196079, 0.18823529411764706 , 0.15294117647058825),
- (0.95686274509803926, 0.42745098039215684 , 0.2627450980392157 ),
- (0.99215686274509807, 0.68235294117647061 , 0.38039215686274508),
- (0.99607843137254903, 0.8784313725490196 , 0.56470588235294117),
- (1.0 , 1.0 , 0.74901960784313726),
- (0.8784313725490196 , 0.95294117647058818 , 0.97254901960784312),
- (0.6705882352941176 , 0.85098039215686272 , 0.9137254901960784 ),
- (0.45490196078431372, 0.67843137254901964 , 0.81960784313725488),
- (0.27058823529411763, 0.45882352941176469 , 0.70588235294117652),
- (0.19215686274509805, 0.21176470588235294 , 0.58431372549019611)
- )
-
-_RdYlGn_data = (
- (0.6470588235294118 , 0.0 , 0.14901960784313725),
- (0.84313725490196079, 0.18823529411764706 , 0.15294117647058825),
- (0.95686274509803926, 0.42745098039215684 , 0.2627450980392157 ),
- (0.99215686274509807, 0.68235294117647061 , 0.38039215686274508),
- (0.99607843137254903, 0.8784313725490196 , 0.54509803921568623),
- (1.0 , 1.0 , 0.74901960784313726),
- (0.85098039215686272, 0.93725490196078431 , 0.54509803921568623),
- (0.65098039215686276, 0.85098039215686272 , 0.41568627450980394),
- (0.4 , 0.74117647058823533 , 0.38823529411764707),
- (0.10196078431372549, 0.59607843137254901 , 0.31372549019607843),
- (0.0 , 0.40784313725490196 , 0.21568627450980393)
- )
-
-_Reds_data = (
- (1.0 , 0.96078431372549022 , 0.94117647058823528),
- (0.99607843137254903, 0.8784313725490196 , 0.82352941176470584),
- (0.9882352941176471 , 0.73333333333333328 , 0.63137254901960782),
- (0.9882352941176471 , 0.5725490196078431 , 0.44705882352941179),
- (0.98431372549019602, 0.41568627450980394 , 0.29019607843137257),
- (0.93725490196078431, 0.23137254901960785 , 0.17254901960784313),
- (0.79607843137254897, 0.094117647058823528, 0.11372549019607843),
- (0.6470588235294118 , 0.058823529411764705, 0.08235294117647058),
- (0.40392156862745099, 0.0 , 0.05098039215686274)
- )
-
-_Spectral_data = (
- (0.61960784313725492, 0.003921568627450980, 0.25882352941176473),
- (0.83529411764705885, 0.24313725490196078 , 0.30980392156862746),
- (0.95686274509803926, 0.42745098039215684 , 0.2627450980392157 ),
- (0.99215686274509807, 0.68235294117647061 , 0.38039215686274508),
- (0.99607843137254903, 0.8784313725490196 , 0.54509803921568623),
- (1.0 , 1.0 , 0.74901960784313726),
- (0.90196078431372551, 0.96078431372549022 , 0.59607843137254901),
- (0.6705882352941176 , 0.8666666666666667 , 0.64313725490196083),
- (0.4 , 0.76078431372549016 , 0.6470588235294118 ),
- (0.19607843137254902, 0.53333333333333333 , 0.74117647058823533),
- (0.36862745098039218, 0.30980392156862746 , 0.63529411764705879)
- )
-
-_YlGn_data = (
- (1.0 , 1.0 , 0.89803921568627454),
- (0.96862745098039216, 0.9882352941176471 , 0.72549019607843135),
- (0.85098039215686272, 0.94117647058823528 , 0.63921568627450975),
- (0.67843137254901964, 0.8666666666666667 , 0.55686274509803924),
- (0.47058823529411764, 0.77647058823529413 , 0.47450980392156861),
- (0.25490196078431371, 0.6705882352941176 , 0.36470588235294116),
- (0.13725490196078433, 0.51764705882352946 , 0.2627450980392157 ),
- (0.0 , 0.40784313725490196 , 0.21568627450980393),
- (0.0 , 0.27058823529411763 , 0.16078431372549021)
- )
-
-_YlGnBu_data = (
- (1.0 , 1.0 , 0.85098039215686272),
- (0.92941176470588238, 0.97254901960784312 , 0.69411764705882351),
- (0.7803921568627451 , 0.9137254901960784 , 0.70588235294117652),
- (0.49803921568627452, 0.80392156862745101 , 0.73333333333333328),
- (0.25490196078431371, 0.71372549019607845 , 0.7686274509803922 ),
- (0.11372549019607843, 0.56862745098039214 , 0.75294117647058822),
- (0.13333333333333333, 0.36862745098039218 , 0.6588235294117647 ),
- (0.14509803921568629, 0.20392156862745098 , 0.58039215686274515),
- (0.03137254901960784, 0.11372549019607843 , 0.34509803921568627)
- )
-
-_YlOrBr_data = (
- (1.0 , 1.0 , 0.89803921568627454),
- (1.0 , 0.96862745098039216 , 0.73725490196078436),
- (0.99607843137254903, 0.8901960784313725 , 0.56862745098039214),
- (0.99607843137254903, 0.7686274509803922 , 0.30980392156862746),
- (0.99607843137254903, 0.6 , 0.16078431372549021),
- (0.92549019607843142, 0.4392156862745098 , 0.07843137254901961),
- (0.8 , 0.29803921568627451 , 0.00784313725490196),
- (0.6 , 0.20392156862745098 , 0.01568627450980392),
- (0.4 , 0.14509803921568629 , 0.02352941176470588)
- )
-
-_YlOrRd_data = (
- (1.0 , 1.0 , 0.8 ),
- (1.0 , 0.92941176470588238 , 0.62745098039215685),
- (0.99607843137254903, 0.85098039215686272 , 0.46274509803921571),
- (0.99607843137254903, 0.69803921568627447 , 0.29803921568627451),
- (0.99215686274509807, 0.55294117647058827 , 0.23529411764705882),
- (0.9882352941176471 , 0.30588235294117649 , 0.16470588235294117),
- (0.8901960784313725 , 0.10196078431372549 , 0.10980392156862745),
- (0.74117647058823533, 0.0 , 0.14901960784313725),
- (0.50196078431372548, 0.0 , 0.14901960784313725)
- )
-
-
-# ColorBrewer's qualitative maps, implemented using ListedColormap
-# for use with mpl.colors.NoNorm
-
-_Accent_data = (
- (0.49803921568627452, 0.78823529411764703, 0.49803921568627452),
- (0.74509803921568629, 0.68235294117647061, 0.83137254901960789),
- (0.99215686274509807, 0.75294117647058822, 0.52549019607843139),
- (1.0, 1.0, 0.6 ),
- (0.2196078431372549, 0.42352941176470588, 0.69019607843137254),
- (0.94117647058823528, 0.00784313725490196, 0.49803921568627452),
- (0.74901960784313726, 0.35686274509803922, 0.09019607843137254),
- (0.4, 0.4, 0.4 ),
- )
-
-_Dark2_data = (
- (0.10588235294117647, 0.61960784313725492, 0.46666666666666667),
- (0.85098039215686272, 0.37254901960784315, 0.00784313725490196),
- (0.45882352941176469, 0.4392156862745098, 0.70196078431372544),
- (0.90588235294117647, 0.16078431372549021, 0.54117647058823526),
- (0.4, 0.65098039215686276, 0.11764705882352941),
- (0.90196078431372551, 0.6705882352941176, 0.00784313725490196),
- (0.65098039215686276, 0.46274509803921571, 0.11372549019607843),
- (0.4, 0.4, 0.4 ),
- )
-
-_Paired_data = (
- (0.65098039215686276, 0.80784313725490198, 0.8901960784313725 ),
- (0.12156862745098039, 0.47058823529411764, 0.70588235294117652),
- (0.69803921568627447, 0.87450980392156863, 0.54117647058823526),
- (0.2, 0.62745098039215685, 0.17254901960784313),
- (0.98431372549019602, 0.60392156862745094, 0.6 ),
- (0.8901960784313725, 0.10196078431372549, 0.10980392156862745),
- (0.99215686274509807, 0.74901960784313726, 0.43529411764705883),
- (1.0, 0.49803921568627452, 0.0 ),
- (0.792156862745098, 0.69803921568627447, 0.83921568627450982),
- (0.41568627450980394, 0.23921568627450981, 0.60392156862745094),
- (1.0, 1.0, 0.6 ),
- (0.69411764705882351, 0.34901960784313724, 0.15686274509803921),
- )
-
-_Pastel1_data = (
- (0.98431372549019602, 0.70588235294117652, 0.68235294117647061),
- (0.70196078431372544, 0.80392156862745101, 0.8901960784313725 ),
- (0.8, 0.92156862745098034, 0.77254901960784317),
- (0.87058823529411766, 0.79607843137254897, 0.89411764705882357),
- (0.99607843137254903, 0.85098039215686272, 0.65098039215686276),
- (1.0, 1.0, 0.8 ),
- (0.89803921568627454, 0.84705882352941175, 0.74117647058823533),
- (0.99215686274509807, 0.85490196078431369, 0.92549019607843142),
- (0.94901960784313721, 0.94901960784313721, 0.94901960784313721),
- )
-
-_Pastel2_data = (
- (0.70196078431372544, 0.88627450980392153, 0.80392156862745101),
- (0.99215686274509807, 0.80392156862745101, 0.67450980392156867),
- (0.79607843137254897, 0.83529411764705885, 0.90980392156862744),
- (0.95686274509803926, 0.792156862745098, 0.89411764705882357),
- (0.90196078431372551, 0.96078431372549022, 0.78823529411764703),
- (1.0, 0.94901960784313721, 0.68235294117647061),
- (0.94509803921568625, 0.88627450980392153, 0.8 ),
- (0.8, 0.8, 0.8 ),
- )
-
-_Set1_data = (
- (0.89411764705882357, 0.10196078431372549, 0.10980392156862745),
- (0.21568627450980393, 0.49411764705882355, 0.72156862745098038),
- (0.30196078431372547, 0.68627450980392157, 0.29019607843137257),
- (0.59607843137254901, 0.30588235294117649, 0.63921568627450975),
- (1.0, 0.49803921568627452, 0.0 ),
- (1.0, 1.0, 0.2 ),
- (0.65098039215686276, 0.33725490196078434, 0.15686274509803921),
- (0.96862745098039216, 0.50588235294117645, 0.74901960784313726),
- (0.6, 0.6, 0.6),
- )
-
-_Set2_data = (
- (0.4, 0.76078431372549016, 0.6470588235294118 ),
- (0.9882352941176471, 0.55294117647058827, 0.3843137254901961 ),
- (0.55294117647058827, 0.62745098039215685, 0.79607843137254897),
- (0.90588235294117647, 0.54117647058823526, 0.76470588235294112),
- (0.65098039215686276, 0.84705882352941175, 0.32941176470588235),
- (1.0, 0.85098039215686272, 0.18431372549019609),
- (0.89803921568627454, 0.7686274509803922, 0.58039215686274515),
- (0.70196078431372544, 0.70196078431372544, 0.70196078431372544),
- )
-
-_Set3_data = (
- (0.55294117647058827, 0.82745098039215681, 0.7803921568627451 ),
- (1.0, 1.0, 0.70196078431372544),
- (0.74509803921568629, 0.72941176470588232, 0.85490196078431369),
- (0.98431372549019602, 0.50196078431372548, 0.44705882352941179),
- (0.50196078431372548, 0.69411764705882351, 0.82745098039215681),
- (0.99215686274509807, 0.70588235294117652, 0.3843137254901961 ),
- (0.70196078431372544, 0.87058823529411766, 0.41176470588235292),
- (0.9882352941176471, 0.80392156862745101, 0.89803921568627454),
- (0.85098039215686272, 0.85098039215686272, 0.85098039215686272),
- (0.73725490196078436, 0.50196078431372548, 0.74117647058823533),
- (0.8, 0.92156862745098034, 0.77254901960784317),
- (1.0, 0.92941176470588238, 0.43529411764705883),
- )
-
-
-# The next 7 palettes are from the Yorick scientific visualization package,
-# an evolution of the GIST package, both by David H. Munro.
-# They are released under a BSD-like license (see LICENSE_YORICK in
-# the license directory of the matplotlib source distribution).
-#
-# Most palette functions have been reduced to simple function descriptions
-# by Reinier Heeres, since the rgb components were mostly straight lines.
-# gist_earth_data and gist_ncar_data were simplified by a script and some
-# manual effort.
-
-_gist_earth_data = \
-{'red': (
-(0.0, 0.0, 0.0000),
-(0.2824, 0.1882, 0.1882),
-(0.4588, 0.2714, 0.2714),
-(0.5490, 0.4719, 0.4719),
-(0.6980, 0.7176, 0.7176),
-(0.7882, 0.7553, 0.7553),
-(1.0000, 0.9922, 0.9922),
-), 'green': (
-(0.0, 0.0, 0.0000),
-(0.0275, 0.0000, 0.0000),
-(0.1098, 0.1893, 0.1893),
-(0.1647, 0.3035, 0.3035),
-(0.2078, 0.3841, 0.3841),
-(0.2824, 0.5020, 0.5020),
-(0.5216, 0.6397, 0.6397),
-(0.6980, 0.7171, 0.7171),
-(0.7882, 0.6392, 0.6392),
-(0.7922, 0.6413, 0.6413),
-(0.8000, 0.6447, 0.6447),
-(0.8078, 0.6481, 0.6481),
-(0.8157, 0.6549, 0.6549),
-(0.8667, 0.6991, 0.6991),
-(0.8745, 0.7103, 0.7103),
-(0.8824, 0.7216, 0.7216),
-(0.8902, 0.7323, 0.7323),
-(0.8980, 0.7430, 0.7430),
-(0.9412, 0.8275, 0.8275),
-(0.9569, 0.8635, 0.8635),
-(0.9647, 0.8816, 0.8816),
-(0.9961, 0.9733, 0.9733),
-(1.0000, 0.9843, 0.9843),
-), 'blue': (
-(0.0, 0.0, 0.0000),
-(0.0039, 0.1684, 0.1684),
-(0.0078, 0.2212, 0.2212),
-(0.0275, 0.4329, 0.4329),
-(0.0314, 0.4549, 0.4549),
-(0.2824, 0.5004, 0.5004),
-(0.4667, 0.2748, 0.2748),
-(0.5451, 0.3205, 0.3205),
-(0.7843, 0.3961, 0.3961),
-(0.8941, 0.6651, 0.6651),
-(1.0000, 0.9843, 0.9843),
-)}
-
-_gist_gray_data = {
- 'red': gfunc[3],
- 'green': gfunc[3],
- 'blue': gfunc[3],
-}
-
-def _gist_heat_red(x): return 1.5 * x
-def _gist_heat_green(x): return 2 * x - 1
-def _gist_heat_blue(x): return 4 * x - 3
-_gist_heat_data = {
- 'red': _gist_heat_red, 'green': _gist_heat_green, 'blue': _gist_heat_blue}
-
-_gist_ncar_data = \
-{'red': (
-(0.0, 0.0, 0.0000),
-(0.3098, 0.0000, 0.0000),
-(0.3725, 0.3993, 0.3993),
-(0.4235, 0.5003, 0.5003),
-(0.5333, 1.0000, 1.0000),
-(0.7922, 1.0000, 1.0000),
-(0.8471, 0.6218, 0.6218),
-(0.8980, 0.9235, 0.9235),
-(1.0000, 0.9961, 0.9961),
-), 'green': (
-(0.0, 0.0, 0.0000),
-(0.0510, 0.3722, 0.3722),
-(0.1059, 0.0000, 0.0000),
-(0.1569, 0.7202, 0.7202),
-(0.1608, 0.7537, 0.7537),
-(0.1647, 0.7752, 0.7752),
-(0.2157, 1.0000, 1.0000),
-(0.2588, 0.9804, 0.9804),
-(0.2706, 0.9804, 0.9804),
-(0.3176, 1.0000, 1.0000),
-(0.3686, 0.8081, 0.8081),
-(0.4275, 1.0000, 1.0000),
-(0.5216, 1.0000, 1.0000),
-(0.6314, 0.7292, 0.7292),
-(0.6863, 0.2796, 0.2796),
-(0.7451, 0.0000, 0.0000),
-(0.7922, 0.0000, 0.0000),
-(0.8431, 0.1753, 0.1753),
-(0.8980, 0.5000, 0.5000),
-(1.0000, 0.9725, 0.9725),
-), 'blue': (
-(0.0, 0.5020, 0.5020),
-(0.0510, 0.0222, 0.0222),
-(0.1098, 1.0000, 1.0000),
-(0.2039, 1.0000, 1.0000),
-(0.2627, 0.6145, 0.6145),
-(0.3216, 0.0000, 0.0000),
-(0.4157, 0.0000, 0.0000),
-(0.4745, 0.2342, 0.2342),
-(0.5333, 0.0000, 0.0000),
-(0.5804, 0.0000, 0.0000),
-(0.6314, 0.0549, 0.0549),
-(0.6902, 0.0000, 0.0000),
-(0.7373, 0.0000, 0.0000),
-(0.7922, 0.9738, 0.9738),
-(0.8000, 1.0000, 1.0000),
-(0.8431, 1.0000, 1.0000),
-(0.8980, 0.9341, 0.9341),
-(1.0000, 0.9961, 0.9961),
-)}
-
-_gist_rainbow_data = (
- (0.000, (1.00, 0.00, 0.16)),
- (0.030, (1.00, 0.00, 0.00)),
- (0.215, (1.00, 1.00, 0.00)),
- (0.400, (0.00, 1.00, 0.00)),
- (0.586, (0.00, 1.00, 1.00)),
- (0.770, (0.00, 0.00, 1.00)),
- (0.954, (1.00, 0.00, 1.00)),
- (1.000, (1.00, 0.00, 0.75))
-)
-
-_gist_stern_data = {
- 'red': (
- (0.000, 0.000, 0.000), (0.0547, 1.000, 1.000),
- (0.250, 0.027, 0.250), # (0.2500, 0.250, 0.250),
- (1.000, 1.000, 1.000)),
- 'green': ((0, 0, 0), (1, 1, 1)),
- 'blue': (
- (0.000, 0.000, 0.000), (0.500, 1.000, 1.000),
- (0.735, 0.000, 0.000), (1.000, 1.000, 1.000))
-}
-
-def _gist_yarg(x): return 1 - x
-_gist_yarg_data = {'red': _gist_yarg, 'green': _gist_yarg, 'blue': _gist_yarg}
-
-# This bipolar colormap was generated from CoolWarmFloat33.csv of
-# "Diverging Color Maps for Scientific Visualization" by Kenneth Moreland.
-# <http://www.kennethmoreland.com/color-maps/>
-_coolwarm_data = {
- 'red': [
- (0.0, 0.2298057, 0.2298057),
- (0.03125, 0.26623388, 0.26623388),
- (0.0625, 0.30386891, 0.30386891),
- (0.09375, 0.342804478, 0.342804478),
- (0.125, 0.38301334, 0.38301334),
- (0.15625, 0.424369608, 0.424369608),
- (0.1875, 0.46666708, 0.46666708),
- (0.21875, 0.509635204, 0.509635204),
- (0.25, 0.552953156, 0.552953156),
- (0.28125, 0.596262162, 0.596262162),
- (0.3125, 0.639176211, 0.639176211),
- (0.34375, 0.681291281, 0.681291281),
- (0.375, 0.722193294, 0.722193294),
- (0.40625, 0.761464949, 0.761464949),
- (0.4375, 0.798691636, 0.798691636),
- (0.46875, 0.833466556, 0.833466556),
- (0.5, 0.865395197, 0.865395197),
- (0.53125, 0.897787179, 0.897787179),
- (0.5625, 0.924127593, 0.924127593),
- (0.59375, 0.944468518, 0.944468518),
- (0.625, 0.958852946, 0.958852946),
- (0.65625, 0.96732803, 0.96732803),
- (0.6875, 0.969954137, 0.969954137),
- (0.71875, 0.966811177, 0.966811177),
- (0.75, 0.958003065, 0.958003065),
- (0.78125, 0.943660866, 0.943660866),
- (0.8125, 0.923944917, 0.923944917),
- (0.84375, 0.89904617, 0.89904617),
- (0.875, 0.869186849, 0.869186849),
- (0.90625, 0.834620542, 0.834620542),
- (0.9375, 0.795631745, 0.795631745),
- (0.96875, 0.752534934, 0.752534934),
- (1.0, 0.705673158, 0.705673158)],
- 'green': [
- (0.0, 0.298717966, 0.298717966),
- (0.03125, 0.353094838, 0.353094838),
- (0.0625, 0.406535296, 0.406535296),
- (0.09375, 0.458757618, 0.458757618),
- (0.125, 0.50941904, 0.50941904),
- (0.15625, 0.558148092, 0.558148092),
- (0.1875, 0.604562568, 0.604562568),
- (0.21875, 0.648280772, 0.648280772),
- (0.25, 0.688929332, 0.688929332),
- (0.28125, 0.726149107, 0.726149107),
- (0.3125, 0.759599947, 0.759599947),
- (0.34375, 0.788964712, 0.788964712),
- (0.375, 0.813952739, 0.813952739),
- (0.40625, 0.834302879, 0.834302879),
- (0.4375, 0.849786142, 0.849786142),
- (0.46875, 0.860207984, 0.860207984),
- (0.5, 0.86541021, 0.86541021),
- (0.53125, 0.848937047, 0.848937047),
- (0.5625, 0.827384882, 0.827384882),
- (0.59375, 0.800927443, 0.800927443),
- (0.625, 0.769767752, 0.769767752),
- (0.65625, 0.734132809, 0.734132809),
- (0.6875, 0.694266682, 0.694266682),
- (0.71875, 0.650421156, 0.650421156),
- (0.75, 0.602842431, 0.602842431),
- (0.78125, 0.551750968, 0.551750968),
- (0.8125, 0.49730856, 0.49730856),
- (0.84375, 0.439559467, 0.439559467),
- (0.875, 0.378313092, 0.378313092),
- (0.90625, 0.312874446, 0.312874446),
- (0.9375, 0.24128379, 0.24128379),
- (0.96875, 0.157246067, 0.157246067),
- (1.0, 0.01555616, 0.01555616)],
- 'blue': [
- (0.0, 0.753683153, 0.753683153),
- (0.03125, 0.801466763, 0.801466763),
- (0.0625, 0.84495867, 0.84495867),
- (0.09375, 0.883725899, 0.883725899),
- (0.125, 0.917387822, 0.917387822),
- (0.15625, 0.945619588, 0.945619588),
- (0.1875, 0.968154911, 0.968154911),
- (0.21875, 0.98478814, 0.98478814),
- (0.25, 0.995375608, 0.995375608),
- (0.28125, 0.999836203, 0.999836203),
- (0.3125, 0.998151185, 0.998151185),
- (0.34375, 0.990363227, 0.990363227),
- (0.375, 0.976574709, 0.976574709),
- (0.40625, 0.956945269, 0.956945269),
- (0.4375, 0.931688648, 0.931688648),
- (0.46875, 0.901068838, 0.901068838),
- (0.5, 0.865395561, 0.865395561),
- (0.53125, 0.820880546, 0.820880546),
- (0.5625, 0.774508472, 0.774508472),
- (0.59375, 0.726736146, 0.726736146),
- (0.625, 0.678007945, 0.678007945),
- (0.65625, 0.628751763, 0.628751763),
- (0.6875, 0.579375448, 0.579375448),
- (0.71875, 0.530263762, 0.530263762),
- (0.75, 0.481775914, 0.481775914),
- (0.78125, 0.434243684, 0.434243684),
- (0.8125, 0.387970225, 0.387970225),
- (0.84375, 0.343229596, 0.343229596),
- (0.875, 0.300267182, 0.300267182),
- (0.90625, 0.259301199, 0.259301199),
- (0.9375, 0.220525627, 0.220525627),
- (0.96875, 0.184115123, 0.184115123),
- (1.0, 0.150232812, 0.150232812)]
- }
-
-# Implementation of Carey Rappaport's CMRmap.
-# See `A Color Map for Effective Black-and-White Rendering of Color-Scale
-# Images' by Carey Rappaport
-# https://www.mathworks.com/matlabcentral/fileexchange/2662-cmrmap-m
-_CMRmap_data = {'red': ((0.000, 0.00, 0.00),
- (0.125, 0.15, 0.15),
- (0.250, 0.30, 0.30),
- (0.375, 0.60, 0.60),
- (0.500, 1.00, 1.00),
- (0.625, 0.90, 0.90),
- (0.750, 0.90, 0.90),
- (0.875, 0.90, 0.90),
- (1.000, 1.00, 1.00)),
- 'green': ((0.000, 0.00, 0.00),
- (0.125, 0.15, 0.15),
- (0.250, 0.15, 0.15),
- (0.375, 0.20, 0.20),
- (0.500, 0.25, 0.25),
- (0.625, 0.50, 0.50),
- (0.750, 0.75, 0.75),
- (0.875, 0.90, 0.90),
- (1.000, 1.00, 1.00)),
- 'blue': ((0.000, 0.00, 0.00),
- (0.125, 0.50, 0.50),
- (0.250, 0.75, 0.75),
- (0.375, 0.50, 0.50),
- (0.500, 0.15, 0.15),
- (0.625, 0.00, 0.00),
- (0.750, 0.10, 0.10),
- (0.875, 0.50, 0.50),
- (1.000, 1.00, 1.00))}
-
-
-# An MIT licensed, colorblind-friendly heatmap from Wistia:
-# https://github.com/wistia/heatmap-palette
-# https://wistia.com/learn/culture/heatmaps-for-colorblindness
-#
-# >>> import matplotlib.colors as c
-# >>> colors = ["#e4ff7a", "#ffe81a", "#ffbd00", "#ffa000", "#fc7f00"]
-# >>> cm = c.LinearSegmentedColormap.from_list('wistia', colors)
-# >>> _wistia_data = cm._segmentdata
-# >>> del _wistia_data['alpha']
-#
-_wistia_data = {
- 'red': [(0.0, 0.8941176470588236, 0.8941176470588236),
- (0.25, 1.0, 1.0),
- (0.5, 1.0, 1.0),
- (0.75, 1.0, 1.0),
- (1.0, 0.9882352941176471, 0.9882352941176471)],
- 'green': [(0.0, 1.0, 1.0),
- (0.25, 0.9098039215686274, 0.9098039215686274),
- (0.5, 0.7411764705882353, 0.7411764705882353),
- (0.75, 0.6274509803921569, 0.6274509803921569),
- (1.0, 0.4980392156862745, 0.4980392156862745)],
- 'blue': [(0.0, 0.47843137254901963, 0.47843137254901963),
- (0.25, 0.10196078431372549, 0.10196078431372549),
- (0.5, 0.0, 0.0),
- (0.75, 0.0, 0.0),
- (1.0, 0.0, 0.0)],
-}
-
-
-# Categorical palettes from Vega:
-# https://github.com/vega/vega/wiki/Scales
-# (divided by 255)
-#
-
-_tab10_data = (
- (0.12156862745098039, 0.4666666666666667, 0.7058823529411765 ), # 1f77b4
- (1.0, 0.4980392156862745, 0.054901960784313725), # ff7f0e
- (0.17254901960784313, 0.6274509803921569, 0.17254901960784313 ), # 2ca02c
- (0.8392156862745098, 0.15294117647058825, 0.1568627450980392 ), # d62728
- (0.5803921568627451, 0.403921568627451, 0.7411764705882353 ), # 9467bd
- (0.5490196078431373, 0.33725490196078434, 0.29411764705882354 ), # 8c564b
- (0.8901960784313725, 0.4666666666666667, 0.7607843137254902 ), # e377c2
- (0.4980392156862745, 0.4980392156862745, 0.4980392156862745 ), # 7f7f7f
- (0.7372549019607844, 0.7411764705882353, 0.13333333333333333 ), # bcbd22
- (0.09019607843137255, 0.7450980392156863, 0.8117647058823529), # 17becf
-)
-
-_tab20_data = (
- (0.12156862745098039, 0.4666666666666667, 0.7058823529411765 ), # 1f77b4
- (0.6823529411764706, 0.7803921568627451, 0.9098039215686274 ), # aec7e8
- (1.0, 0.4980392156862745, 0.054901960784313725), # ff7f0e
- (1.0, 0.7333333333333333, 0.47058823529411764 ), # ffbb78
- (0.17254901960784313, 0.6274509803921569, 0.17254901960784313 ), # 2ca02c
- (0.596078431372549, 0.8745098039215686, 0.5411764705882353 ), # 98df8a
- (0.8392156862745098, 0.15294117647058825, 0.1568627450980392 ), # d62728
- (1.0, 0.596078431372549, 0.5882352941176471 ), # ff9896
- (0.5803921568627451, 0.403921568627451, 0.7411764705882353 ), # 9467bd
- (0.7725490196078432, 0.6901960784313725, 0.8352941176470589 ), # c5b0d5
- (0.5490196078431373, 0.33725490196078434, 0.29411764705882354 ), # 8c564b
- (0.7686274509803922, 0.611764705882353, 0.5803921568627451 ), # c49c94
- (0.8901960784313725, 0.4666666666666667, 0.7607843137254902 ), # e377c2
- (0.9686274509803922, 0.7137254901960784, 0.8235294117647058 ), # f7b6d2
- (0.4980392156862745, 0.4980392156862745, 0.4980392156862745 ), # 7f7f7f
- (0.7803921568627451, 0.7803921568627451, 0.7803921568627451 ), # c7c7c7
- (0.7372549019607844, 0.7411764705882353, 0.13333333333333333 ), # bcbd22
- (0.8588235294117647, 0.8588235294117647, 0.5529411764705883 ), # dbdb8d
- (0.09019607843137255, 0.7450980392156863, 0.8117647058823529 ), # 17becf
- (0.6196078431372549, 0.8549019607843137, 0.8980392156862745), # 9edae5
-)
-
-_tab20b_data = (
- (0.2235294117647059, 0.23137254901960785, 0.4745098039215686 ), # 393b79
- (0.3215686274509804, 0.32941176470588235, 0.6392156862745098 ), # 5254a3
- (0.4196078431372549, 0.43137254901960786, 0.8117647058823529 ), # 6b6ecf
- (0.611764705882353, 0.6196078431372549, 0.8705882352941177 ), # 9c9ede
- (0.38823529411764707, 0.4745098039215686, 0.2235294117647059 ), # 637939
- (0.5490196078431373, 0.6352941176470588, 0.3215686274509804 ), # 8ca252
- (0.7098039215686275, 0.8117647058823529, 0.4196078431372549 ), # b5cf6b
- (0.807843137254902, 0.8588235294117647, 0.611764705882353 ), # cedb9c
- (0.5490196078431373, 0.42745098039215684, 0.19215686274509805), # 8c6d31
- (0.7411764705882353, 0.6196078431372549, 0.2235294117647059 ), # bd9e39
- (0.9058823529411765, 0.7294117647058823, 0.3215686274509804 ), # e7ba52
- (0.9058823529411765, 0.796078431372549, 0.5803921568627451 ), # e7cb94
- (0.5176470588235295, 0.23529411764705882, 0.2235294117647059 ), # 843c39
- (0.6784313725490196, 0.28627450980392155, 0.2901960784313726 ), # ad494a
- (0.8392156862745098, 0.3803921568627451, 0.4196078431372549 ), # d6616b
- (0.9058823529411765, 0.5882352941176471, 0.611764705882353 ), # e7969c
- (0.4823529411764706, 0.2549019607843137, 0.45098039215686275), # 7b4173
- (0.6470588235294118, 0.3176470588235294, 0.5803921568627451 ), # a55194
- (0.807843137254902, 0.42745098039215684, 0.7411764705882353 ), # ce6dbd
- (0.8705882352941177, 0.6196078431372549, 0.8392156862745098 ), # de9ed6
-)
-
-_tab20c_data = (
- (0.19215686274509805, 0.5098039215686274, 0.7411764705882353 ), # 3182bd
- (0.4196078431372549, 0.6823529411764706, 0.8392156862745098 ), # 6baed6
- (0.6196078431372549, 0.792156862745098, 0.8823529411764706 ), # 9ecae1
- (0.7764705882352941, 0.8588235294117647, 0.9372549019607843 ), # c6dbef
- (0.9019607843137255, 0.3333333333333333, 0.050980392156862744), # e6550d
- (0.9921568627450981, 0.5529411764705883, 0.23529411764705882 ), # fd8d3c
- (0.9921568627450981, 0.6823529411764706, 0.4196078431372549 ), # fdae6b
- (0.9921568627450981, 0.8156862745098039, 0.6352941176470588 ), # fdd0a2
- (0.19215686274509805, 0.6392156862745098, 0.32941176470588235 ), # 31a354
- (0.4549019607843137, 0.7686274509803922, 0.4627450980392157 ), # 74c476
- (0.6313725490196078, 0.8509803921568627, 0.6078431372549019 ), # a1d99b
- (0.7803921568627451, 0.9137254901960784, 0.7529411764705882 ), # c7e9c0
- (0.4588235294117647, 0.4196078431372549, 0.6941176470588235 ), # 756bb1
- (0.6196078431372549, 0.6039215686274509, 0.7843137254901961 ), # 9e9ac8
- (0.7372549019607844, 0.7411764705882353, 0.8627450980392157 ), # bcbddc
- (0.8549019607843137, 0.8549019607843137, 0.9215686274509803 ), # dadaeb
- (0.38823529411764707, 0.38823529411764707, 0.38823529411764707 ), # 636363
- (0.5882352941176471, 0.5882352941176471, 0.5882352941176471 ), # 969696
- (0.7411764705882353, 0.7411764705882353, 0.7411764705882353 ), # bdbdbd
- (0.8509803921568627, 0.8509803921568627, 0.8509803921568627 ), # d9d9d9
-)
-
-
-datad = {
- 'Blues': _Blues_data,
- 'BrBG': _BrBG_data,
- 'BuGn': _BuGn_data,
- 'BuPu': _BuPu_data,
- 'CMRmap': _CMRmap_data,
- 'GnBu': _GnBu_data,
- 'Greens': _Greens_data,
- 'Greys': _Greys_data,
- 'OrRd': _OrRd_data,
- 'Oranges': _Oranges_data,
- 'PRGn': _PRGn_data,
- 'PiYG': _PiYG_data,
- 'PuBu': _PuBu_data,
- 'PuBuGn': _PuBuGn_data,
- 'PuOr': _PuOr_data,
- 'PuRd': _PuRd_data,
- 'Purples': _Purples_data,
- 'RdBu': _RdBu_data,
- 'RdGy': _RdGy_data,
- 'RdPu': _RdPu_data,
- 'RdYlBu': _RdYlBu_data,
- 'RdYlGn': _RdYlGn_data,
- 'Reds': _Reds_data,
- 'Spectral': _Spectral_data,
- 'Wistia': _wistia_data,
- 'YlGn': _YlGn_data,
- 'YlGnBu': _YlGnBu_data,
- 'YlOrBr': _YlOrBr_data,
- 'YlOrRd': _YlOrRd_data,
- 'afmhot': _afmhot_data,
- 'autumn': _autumn_data,
- 'binary': _binary_data,
- 'bone': _bone_data,
- 'brg': _brg_data,
- 'bwr': _bwr_data,
- 'cool': _cool_data,
- 'coolwarm': _coolwarm_data,
- 'copper': _copper_data,
- 'cubehelix': _cubehelix_data,
- 'flag': _flag_data,
- 'gist_earth': _gist_earth_data,
- 'gist_gray': _gist_gray_data,
- 'gist_heat': _gist_heat_data,
- 'gist_ncar': _gist_ncar_data,
- 'gist_rainbow': _gist_rainbow_data,
- 'gist_stern': _gist_stern_data,
- 'gist_yarg': _gist_yarg_data,
- 'gnuplot': _gnuplot_data,
- 'gnuplot2': _gnuplot2_data,
- 'gray': _gray_data,
- 'hot': _hot_data,
- 'hsv': _hsv_data,
- 'jet': _jet_data,
- 'nipy_spectral': _nipy_spectral_data,
- 'ocean': _ocean_data,
- 'pink': _pink_data,
- 'prism': _prism_data,
- 'rainbow': _rainbow_data,
- 'seismic': _seismic_data,
- 'spring': _spring_data,
- 'summer': _summer_data,
- 'terrain': _terrain_data,
- 'winter': _winter_data,
- # Qualitative
- 'Accent': {'listed': _Accent_data},
- 'Dark2': {'listed': _Dark2_data},
- 'Paired': {'listed': _Paired_data},
- 'Pastel1': {'listed': _Pastel1_data},
- 'Pastel2': {'listed': _Pastel2_data},
- 'Set1': {'listed': _Set1_data},
- 'Set2': {'listed': _Set2_data},
- 'Set3': {'listed': _Set3_data},
- 'tab10': {'listed': _tab10_data},
- 'tab20': {'listed': _tab20_data},
- 'tab20b': {'listed': _tab20b_data},
- 'tab20c': {'listed': _tab20c_data},
-}
diff --git a/contrib/python/matplotlib/py3/matplotlib/_cm_listed.py b/contrib/python/matplotlib/py3/matplotlib/_cm_listed.py
deleted file mode 100644
index a331ad74a5..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_cm_listed.py
+++ /dev/null
@@ -1,2071 +0,0 @@
-from .colors import ListedColormap
-
-_magma_data = [[0.001462, 0.000466, 0.013866],
- [0.002258, 0.001295, 0.018331],
- [0.003279, 0.002305, 0.023708],
- [0.004512, 0.003490, 0.029965],
- [0.005950, 0.004843, 0.037130],
- [0.007588, 0.006356, 0.044973],
- [0.009426, 0.008022, 0.052844],
- [0.011465, 0.009828, 0.060750],
- [0.013708, 0.011771, 0.068667],
- [0.016156, 0.013840, 0.076603],
- [0.018815, 0.016026, 0.084584],
- [0.021692, 0.018320, 0.092610],
- [0.024792, 0.020715, 0.100676],
- [0.028123, 0.023201, 0.108787],
- [0.031696, 0.025765, 0.116965],
- [0.035520, 0.028397, 0.125209],
- [0.039608, 0.031090, 0.133515],
- [0.043830, 0.033830, 0.141886],
- [0.048062, 0.036607, 0.150327],
- [0.052320, 0.039407, 0.158841],
- [0.056615, 0.042160, 0.167446],
- [0.060949, 0.044794, 0.176129],
- [0.065330, 0.047318, 0.184892],
- [0.069764, 0.049726, 0.193735],
- [0.074257, 0.052017, 0.202660],
- [0.078815, 0.054184, 0.211667],
- [0.083446, 0.056225, 0.220755],
- [0.088155, 0.058133, 0.229922],
- [0.092949, 0.059904, 0.239164],
- [0.097833, 0.061531, 0.248477],
- [0.102815, 0.063010, 0.257854],
- [0.107899, 0.064335, 0.267289],
- [0.113094, 0.065492, 0.276784],
- [0.118405, 0.066479, 0.286321],
- [0.123833, 0.067295, 0.295879],
- [0.129380, 0.067935, 0.305443],
- [0.135053, 0.068391, 0.315000],
- [0.140858, 0.068654, 0.324538],
- [0.146785, 0.068738, 0.334011],
- [0.152839, 0.068637, 0.343404],
- [0.159018, 0.068354, 0.352688],
- [0.165308, 0.067911, 0.361816],
- [0.171713, 0.067305, 0.370771],
- [0.178212, 0.066576, 0.379497],
- [0.184801, 0.065732, 0.387973],
- [0.191460, 0.064818, 0.396152],
- [0.198177, 0.063862, 0.404009],
- [0.204935, 0.062907, 0.411514],
- [0.211718, 0.061992, 0.418647],
- [0.218512, 0.061158, 0.425392],
- [0.225302, 0.060445, 0.431742],
- [0.232077, 0.059889, 0.437695],
- [0.238826, 0.059517, 0.443256],
- [0.245543, 0.059352, 0.448436],
- [0.252220, 0.059415, 0.453248],
- [0.258857, 0.059706, 0.457710],
- [0.265447, 0.060237, 0.461840],
- [0.271994, 0.060994, 0.465660],
- [0.278493, 0.061978, 0.469190],
- [0.284951, 0.063168, 0.472451],
- [0.291366, 0.064553, 0.475462],
- [0.297740, 0.066117, 0.478243],
- [0.304081, 0.067835, 0.480812],
- [0.310382, 0.069702, 0.483186],
- [0.316654, 0.071690, 0.485380],
- [0.322899, 0.073782, 0.487408],
- [0.329114, 0.075972, 0.489287],
- [0.335308, 0.078236, 0.491024],
- [0.341482, 0.080564, 0.492631],
- [0.347636, 0.082946, 0.494121],
- [0.353773, 0.085373, 0.495501],
- [0.359898, 0.087831, 0.496778],
- [0.366012, 0.090314, 0.497960],
- [0.372116, 0.092816, 0.499053],
- [0.378211, 0.095332, 0.500067],
- [0.384299, 0.097855, 0.501002],
- [0.390384, 0.100379, 0.501864],
- [0.396467, 0.102902, 0.502658],
- [0.402548, 0.105420, 0.503386],
- [0.408629, 0.107930, 0.504052],
- [0.414709, 0.110431, 0.504662],
- [0.420791, 0.112920, 0.505215],
- [0.426877, 0.115395, 0.505714],
- [0.432967, 0.117855, 0.506160],
- [0.439062, 0.120298, 0.506555],
- [0.445163, 0.122724, 0.506901],
- [0.451271, 0.125132, 0.507198],
- [0.457386, 0.127522, 0.507448],
- [0.463508, 0.129893, 0.507652],
- [0.469640, 0.132245, 0.507809],
- [0.475780, 0.134577, 0.507921],
- [0.481929, 0.136891, 0.507989],
- [0.488088, 0.139186, 0.508011],
- [0.494258, 0.141462, 0.507988],
- [0.500438, 0.143719, 0.507920],
- [0.506629, 0.145958, 0.507806],
- [0.512831, 0.148179, 0.507648],
- [0.519045, 0.150383, 0.507443],
- [0.525270, 0.152569, 0.507192],
- [0.531507, 0.154739, 0.506895],
- [0.537755, 0.156894, 0.506551],
- [0.544015, 0.159033, 0.506159],
- [0.550287, 0.161158, 0.505719],
- [0.556571, 0.163269, 0.505230],
- [0.562866, 0.165368, 0.504692],
- [0.569172, 0.167454, 0.504105],
- [0.575490, 0.169530, 0.503466],
- [0.581819, 0.171596, 0.502777],
- [0.588158, 0.173652, 0.502035],
- [0.594508, 0.175701, 0.501241],
- [0.600868, 0.177743, 0.500394],
- [0.607238, 0.179779, 0.499492],
- [0.613617, 0.181811, 0.498536],
- [0.620005, 0.183840, 0.497524],
- [0.626401, 0.185867, 0.496456],
- [0.632805, 0.187893, 0.495332],
- [0.639216, 0.189921, 0.494150],
- [0.645633, 0.191952, 0.492910],
- [0.652056, 0.193986, 0.491611],
- [0.658483, 0.196027, 0.490253],
- [0.664915, 0.198075, 0.488836],
- [0.671349, 0.200133, 0.487358],
- [0.677786, 0.202203, 0.485819],
- [0.684224, 0.204286, 0.484219],
- [0.690661, 0.206384, 0.482558],
- [0.697098, 0.208501, 0.480835],
- [0.703532, 0.210638, 0.479049],
- [0.709962, 0.212797, 0.477201],
- [0.716387, 0.214982, 0.475290],
- [0.722805, 0.217194, 0.473316],
- [0.729216, 0.219437, 0.471279],
- [0.735616, 0.221713, 0.469180],
- [0.742004, 0.224025, 0.467018],
- [0.748378, 0.226377, 0.464794],
- [0.754737, 0.228772, 0.462509],
- [0.761077, 0.231214, 0.460162],
- [0.767398, 0.233705, 0.457755],
- [0.773695, 0.236249, 0.455289],
- [0.779968, 0.238851, 0.452765],
- [0.786212, 0.241514, 0.450184],
- [0.792427, 0.244242, 0.447543],
- [0.798608, 0.247040, 0.444848],
- [0.804752, 0.249911, 0.442102],
- [0.810855, 0.252861, 0.439305],
- [0.816914, 0.255895, 0.436461],
- [0.822926, 0.259016, 0.433573],
- [0.828886, 0.262229, 0.430644],
- [0.834791, 0.265540, 0.427671],
- [0.840636, 0.268953, 0.424666],
- [0.846416, 0.272473, 0.421631],
- [0.852126, 0.276106, 0.418573],
- [0.857763, 0.279857, 0.415496],
- [0.863320, 0.283729, 0.412403],
- [0.868793, 0.287728, 0.409303],
- [0.874176, 0.291859, 0.406205],
- [0.879464, 0.296125, 0.403118],
- [0.884651, 0.300530, 0.400047],
- [0.889731, 0.305079, 0.397002],
- [0.894700, 0.309773, 0.393995],
- [0.899552, 0.314616, 0.391037],
- [0.904281, 0.319610, 0.388137],
- [0.908884, 0.324755, 0.385308],
- [0.913354, 0.330052, 0.382563],
- [0.917689, 0.335500, 0.379915],
- [0.921884, 0.341098, 0.377376],
- [0.925937, 0.346844, 0.374959],
- [0.929845, 0.352734, 0.372677],
- [0.933606, 0.358764, 0.370541],
- [0.937221, 0.364929, 0.368567],
- [0.940687, 0.371224, 0.366762],
- [0.944006, 0.377643, 0.365136],
- [0.947180, 0.384178, 0.363701],
- [0.950210, 0.390820, 0.362468],
- [0.953099, 0.397563, 0.361438],
- [0.955849, 0.404400, 0.360619],
- [0.958464, 0.411324, 0.360014],
- [0.960949, 0.418323, 0.359630],
- [0.963310, 0.425390, 0.359469],
- [0.965549, 0.432519, 0.359529],
- [0.967671, 0.439703, 0.359810],
- [0.969680, 0.446936, 0.360311],
- [0.971582, 0.454210, 0.361030],
- [0.973381, 0.461520, 0.361965],
- [0.975082, 0.468861, 0.363111],
- [0.976690, 0.476226, 0.364466],
- [0.978210, 0.483612, 0.366025],
- [0.979645, 0.491014, 0.367783],
- [0.981000, 0.498428, 0.369734],
- [0.982279, 0.505851, 0.371874],
- [0.983485, 0.513280, 0.374198],
- [0.984622, 0.520713, 0.376698],
- [0.985693, 0.528148, 0.379371],
- [0.986700, 0.535582, 0.382210],
- [0.987646, 0.543015, 0.385210],
- [0.988533, 0.550446, 0.388365],
- [0.989363, 0.557873, 0.391671],
- [0.990138, 0.565296, 0.395122],
- [0.990871, 0.572706, 0.398714],
- [0.991558, 0.580107, 0.402441],
- [0.992196, 0.587502, 0.406299],
- [0.992785, 0.594891, 0.410283],
- [0.993326, 0.602275, 0.414390],
- [0.993834, 0.609644, 0.418613],
- [0.994309, 0.616999, 0.422950],
- [0.994738, 0.624350, 0.427397],
- [0.995122, 0.631696, 0.431951],
- [0.995480, 0.639027, 0.436607],
- [0.995810, 0.646344, 0.441361],
- [0.996096, 0.653659, 0.446213],
- [0.996341, 0.660969, 0.451160],
- [0.996580, 0.668256, 0.456192],
- [0.996775, 0.675541, 0.461314],
- [0.996925, 0.682828, 0.466526],
- [0.997077, 0.690088, 0.471811],
- [0.997186, 0.697349, 0.477182],
- [0.997254, 0.704611, 0.482635],
- [0.997325, 0.711848, 0.488154],
- [0.997351, 0.719089, 0.493755],
- [0.997351, 0.726324, 0.499428],
- [0.997341, 0.733545, 0.505167],
- [0.997285, 0.740772, 0.510983],
- [0.997228, 0.747981, 0.516859],
- [0.997138, 0.755190, 0.522806],
- [0.997019, 0.762398, 0.528821],
- [0.996898, 0.769591, 0.534892],
- [0.996727, 0.776795, 0.541039],
- [0.996571, 0.783977, 0.547233],
- [0.996369, 0.791167, 0.553499],
- [0.996162, 0.798348, 0.559820],
- [0.995932, 0.805527, 0.566202],
- [0.995680, 0.812706, 0.572645],
- [0.995424, 0.819875, 0.579140],
- [0.995131, 0.827052, 0.585701],
- [0.994851, 0.834213, 0.592307],
- [0.994524, 0.841387, 0.598983],
- [0.994222, 0.848540, 0.605696],
- [0.993866, 0.855711, 0.612482],
- [0.993545, 0.862859, 0.619299],
- [0.993170, 0.870024, 0.626189],
- [0.992831, 0.877168, 0.633109],
- [0.992440, 0.884330, 0.640099],
- [0.992089, 0.891470, 0.647116],
- [0.991688, 0.898627, 0.654202],
- [0.991332, 0.905763, 0.661309],
- [0.990930, 0.912915, 0.668481],
- [0.990570, 0.920049, 0.675675],
- [0.990175, 0.927196, 0.682926],
- [0.989815, 0.934329, 0.690198],
- [0.989434, 0.941470, 0.697519],
- [0.989077, 0.948604, 0.704863],
- [0.988717, 0.955742, 0.712242],
- [0.988367, 0.962878, 0.719649],
- [0.988033, 0.970012, 0.727077],
- [0.987691, 0.977154, 0.734536],
- [0.987387, 0.984288, 0.742002],
- [0.987053, 0.991438, 0.749504]]
-
-_inferno_data = [[0.001462, 0.000466, 0.013866],
- [0.002267, 0.001270, 0.018570],
- [0.003299, 0.002249, 0.024239],
- [0.004547, 0.003392, 0.030909],
- [0.006006, 0.004692, 0.038558],
- [0.007676, 0.006136, 0.046836],
- [0.009561, 0.007713, 0.055143],
- [0.011663, 0.009417, 0.063460],
- [0.013995, 0.011225, 0.071862],
- [0.016561, 0.013136, 0.080282],
- [0.019373, 0.015133, 0.088767],
- [0.022447, 0.017199, 0.097327],
- [0.025793, 0.019331, 0.105930],
- [0.029432, 0.021503, 0.114621],
- [0.033385, 0.023702, 0.123397],
- [0.037668, 0.025921, 0.132232],
- [0.042253, 0.028139, 0.141141],
- [0.046915, 0.030324, 0.150164],
- [0.051644, 0.032474, 0.159254],
- [0.056449, 0.034569, 0.168414],
- [0.061340, 0.036590, 0.177642],
- [0.066331, 0.038504, 0.186962],
- [0.071429, 0.040294, 0.196354],
- [0.076637, 0.041905, 0.205799],
- [0.081962, 0.043328, 0.215289],
- [0.087411, 0.044556, 0.224813],
- [0.092990, 0.045583, 0.234358],
- [0.098702, 0.046402, 0.243904],
- [0.104551, 0.047008, 0.253430],
- [0.110536, 0.047399, 0.262912],
- [0.116656, 0.047574, 0.272321],
- [0.122908, 0.047536, 0.281624],
- [0.129285, 0.047293, 0.290788],
- [0.135778, 0.046856, 0.299776],
- [0.142378, 0.046242, 0.308553],
- [0.149073, 0.045468, 0.317085],
- [0.155850, 0.044559, 0.325338],
- [0.162689, 0.043554, 0.333277],
- [0.169575, 0.042489, 0.340874],
- [0.176493, 0.041402, 0.348111],
- [0.183429, 0.040329, 0.354971],
- [0.190367, 0.039309, 0.361447],
- [0.197297, 0.038400, 0.367535],
- [0.204209, 0.037632, 0.373238],
- [0.211095, 0.037030, 0.378563],
- [0.217949, 0.036615, 0.383522],
- [0.224763, 0.036405, 0.388129],
- [0.231538, 0.036405, 0.392400],
- [0.238273, 0.036621, 0.396353],
- [0.244967, 0.037055, 0.400007],
- [0.251620, 0.037705, 0.403378],
- [0.258234, 0.038571, 0.406485],
- [0.264810, 0.039647, 0.409345],
- [0.271347, 0.040922, 0.411976],
- [0.277850, 0.042353, 0.414392],
- [0.284321, 0.043933, 0.416608],
- [0.290763, 0.045644, 0.418637],
- [0.297178, 0.047470, 0.420491],
- [0.303568, 0.049396, 0.422182],
- [0.309935, 0.051407, 0.423721],
- [0.316282, 0.053490, 0.425116],
- [0.322610, 0.055634, 0.426377],
- [0.328921, 0.057827, 0.427511],
- [0.335217, 0.060060, 0.428524],
- [0.341500, 0.062325, 0.429425],
- [0.347771, 0.064616, 0.430217],
- [0.354032, 0.066925, 0.430906],
- [0.360284, 0.069247, 0.431497],
- [0.366529, 0.071579, 0.431994],
- [0.372768, 0.073915, 0.432400],
- [0.379001, 0.076253, 0.432719],
- [0.385228, 0.078591, 0.432955],
- [0.391453, 0.080927, 0.433109],
- [0.397674, 0.083257, 0.433183],
- [0.403894, 0.085580, 0.433179],
- [0.410113, 0.087896, 0.433098],
- [0.416331, 0.090203, 0.432943],
- [0.422549, 0.092501, 0.432714],
- [0.428768, 0.094790, 0.432412],
- [0.434987, 0.097069, 0.432039],
- [0.441207, 0.099338, 0.431594],
- [0.447428, 0.101597, 0.431080],
- [0.453651, 0.103848, 0.430498],
- [0.459875, 0.106089, 0.429846],
- [0.466100, 0.108322, 0.429125],
- [0.472328, 0.110547, 0.428334],
- [0.478558, 0.112764, 0.427475],
- [0.484789, 0.114974, 0.426548],
- [0.491022, 0.117179, 0.425552],
- [0.497257, 0.119379, 0.424488],
- [0.503493, 0.121575, 0.423356],
- [0.509730, 0.123769, 0.422156],
- [0.515967, 0.125960, 0.420887],
- [0.522206, 0.128150, 0.419549],
- [0.528444, 0.130341, 0.418142],
- [0.534683, 0.132534, 0.416667],
- [0.540920, 0.134729, 0.415123],
- [0.547157, 0.136929, 0.413511],
- [0.553392, 0.139134, 0.411829],
- [0.559624, 0.141346, 0.410078],
- [0.565854, 0.143567, 0.408258],
- [0.572081, 0.145797, 0.406369],
- [0.578304, 0.148039, 0.404411],
- [0.584521, 0.150294, 0.402385],
- [0.590734, 0.152563, 0.400290],
- [0.596940, 0.154848, 0.398125],
- [0.603139, 0.157151, 0.395891],
- [0.609330, 0.159474, 0.393589],
- [0.615513, 0.161817, 0.391219],
- [0.621685, 0.164184, 0.388781],
- [0.627847, 0.166575, 0.386276],
- [0.633998, 0.168992, 0.383704],
- [0.640135, 0.171438, 0.381065],
- [0.646260, 0.173914, 0.378359],
- [0.652369, 0.176421, 0.375586],
- [0.658463, 0.178962, 0.372748],
- [0.664540, 0.181539, 0.369846],
- [0.670599, 0.184153, 0.366879],
- [0.676638, 0.186807, 0.363849],
- [0.682656, 0.189501, 0.360757],
- [0.688653, 0.192239, 0.357603],
- [0.694627, 0.195021, 0.354388],
- [0.700576, 0.197851, 0.351113],
- [0.706500, 0.200728, 0.347777],
- [0.712396, 0.203656, 0.344383],
- [0.718264, 0.206636, 0.340931],
- [0.724103, 0.209670, 0.337424],
- [0.729909, 0.212759, 0.333861],
- [0.735683, 0.215906, 0.330245],
- [0.741423, 0.219112, 0.326576],
- [0.747127, 0.222378, 0.322856],
- [0.752794, 0.225706, 0.319085],
- [0.758422, 0.229097, 0.315266],
- [0.764010, 0.232554, 0.311399],
- [0.769556, 0.236077, 0.307485],
- [0.775059, 0.239667, 0.303526],
- [0.780517, 0.243327, 0.299523],
- [0.785929, 0.247056, 0.295477],
- [0.791293, 0.250856, 0.291390],
- [0.796607, 0.254728, 0.287264],
- [0.801871, 0.258674, 0.283099],
- [0.807082, 0.262692, 0.278898],
- [0.812239, 0.266786, 0.274661],
- [0.817341, 0.270954, 0.270390],
- [0.822386, 0.275197, 0.266085],
- [0.827372, 0.279517, 0.261750],
- [0.832299, 0.283913, 0.257383],
- [0.837165, 0.288385, 0.252988],
- [0.841969, 0.292933, 0.248564],
- [0.846709, 0.297559, 0.244113],
- [0.851384, 0.302260, 0.239636],
- [0.855992, 0.307038, 0.235133],
- [0.860533, 0.311892, 0.230606],
- [0.865006, 0.316822, 0.226055],
- [0.869409, 0.321827, 0.221482],
- [0.873741, 0.326906, 0.216886],
- [0.878001, 0.332060, 0.212268],
- [0.882188, 0.337287, 0.207628],
- [0.886302, 0.342586, 0.202968],
- [0.890341, 0.347957, 0.198286],
- [0.894305, 0.353399, 0.193584],
- [0.898192, 0.358911, 0.188860],
- [0.902003, 0.364492, 0.184116],
- [0.905735, 0.370140, 0.179350],
- [0.909390, 0.375856, 0.174563],
- [0.912966, 0.381636, 0.169755],
- [0.916462, 0.387481, 0.164924],
- [0.919879, 0.393389, 0.160070],
- [0.923215, 0.399359, 0.155193],
- [0.926470, 0.405389, 0.150292],
- [0.929644, 0.411479, 0.145367],
- [0.932737, 0.417627, 0.140417],
- [0.935747, 0.423831, 0.135440],
- [0.938675, 0.430091, 0.130438],
- [0.941521, 0.436405, 0.125409],
- [0.944285, 0.442772, 0.120354],
- [0.946965, 0.449191, 0.115272],
- [0.949562, 0.455660, 0.110164],
- [0.952075, 0.462178, 0.105031],
- [0.954506, 0.468744, 0.099874],
- [0.956852, 0.475356, 0.094695],
- [0.959114, 0.482014, 0.089499],
- [0.961293, 0.488716, 0.084289],
- [0.963387, 0.495462, 0.079073],
- [0.965397, 0.502249, 0.073859],
- [0.967322, 0.509078, 0.068659],
- [0.969163, 0.515946, 0.063488],
- [0.970919, 0.522853, 0.058367],
- [0.972590, 0.529798, 0.053324],
- [0.974176, 0.536780, 0.048392],
- [0.975677, 0.543798, 0.043618],
- [0.977092, 0.550850, 0.039050],
- [0.978422, 0.557937, 0.034931],
- [0.979666, 0.565057, 0.031409],
- [0.980824, 0.572209, 0.028508],
- [0.981895, 0.579392, 0.026250],
- [0.982881, 0.586606, 0.024661],
- [0.983779, 0.593849, 0.023770],
- [0.984591, 0.601122, 0.023606],
- [0.985315, 0.608422, 0.024202],
- [0.985952, 0.615750, 0.025592],
- [0.986502, 0.623105, 0.027814],
- [0.986964, 0.630485, 0.030908],
- [0.987337, 0.637890, 0.034916],
- [0.987622, 0.645320, 0.039886],
- [0.987819, 0.652773, 0.045581],
- [0.987926, 0.660250, 0.051750],
- [0.987945, 0.667748, 0.058329],
- [0.987874, 0.675267, 0.065257],
- [0.987714, 0.682807, 0.072489],
- [0.987464, 0.690366, 0.079990],
- [0.987124, 0.697944, 0.087731],
- [0.986694, 0.705540, 0.095694],
- [0.986175, 0.713153, 0.103863],
- [0.985566, 0.720782, 0.112229],
- [0.984865, 0.728427, 0.120785],
- [0.984075, 0.736087, 0.129527],
- [0.983196, 0.743758, 0.138453],
- [0.982228, 0.751442, 0.147565],
- [0.981173, 0.759135, 0.156863],
- [0.980032, 0.766837, 0.166353],
- [0.978806, 0.774545, 0.176037],
- [0.977497, 0.782258, 0.185923],
- [0.976108, 0.789974, 0.196018],
- [0.974638, 0.797692, 0.206332],
- [0.973088, 0.805409, 0.216877],
- [0.971468, 0.813122, 0.227658],
- [0.969783, 0.820825, 0.238686],
- [0.968041, 0.828515, 0.249972],
- [0.966243, 0.836191, 0.261534],
- [0.964394, 0.843848, 0.273391],
- [0.962517, 0.851476, 0.285546],
- [0.960626, 0.859069, 0.298010],
- [0.958720, 0.866624, 0.310820],
- [0.956834, 0.874129, 0.323974],
- [0.954997, 0.881569, 0.337475],
- [0.953215, 0.888942, 0.351369],
- [0.951546, 0.896226, 0.365627],
- [0.950018, 0.903409, 0.380271],
- [0.948683, 0.910473, 0.395289],
- [0.947594, 0.917399, 0.410665],
- [0.946809, 0.924168, 0.426373],
- [0.946392, 0.930761, 0.442367],
- [0.946403, 0.937159, 0.458592],
- [0.946903, 0.943348, 0.474970],
- [0.947937, 0.949318, 0.491426],
- [0.949545, 0.955063, 0.507860],
- [0.951740, 0.960587, 0.524203],
- [0.954529, 0.965896, 0.540361],
- [0.957896, 0.971003, 0.556275],
- [0.961812, 0.975924, 0.571925],
- [0.966249, 0.980678, 0.587206],
- [0.971162, 0.985282, 0.602154],
- [0.976511, 0.989753, 0.616760],
- [0.982257, 0.994109, 0.631017],
- [0.988362, 0.998364, 0.644924]]
-
-_plasma_data = [[0.050383, 0.029803, 0.527975],
- [0.063536, 0.028426, 0.533124],
- [0.075353, 0.027206, 0.538007],
- [0.086222, 0.026125, 0.542658],
- [0.096379, 0.025165, 0.547103],
- [0.105980, 0.024309, 0.551368],
- [0.115124, 0.023556, 0.555468],
- [0.123903, 0.022878, 0.559423],
- [0.132381, 0.022258, 0.563250],
- [0.140603, 0.021687, 0.566959],
- [0.148607, 0.021154, 0.570562],
- [0.156421, 0.020651, 0.574065],
- [0.164070, 0.020171, 0.577478],
- [0.171574, 0.019706, 0.580806],
- [0.178950, 0.019252, 0.584054],
- [0.186213, 0.018803, 0.587228],
- [0.193374, 0.018354, 0.590330],
- [0.200445, 0.017902, 0.593364],
- [0.207435, 0.017442, 0.596333],
- [0.214350, 0.016973, 0.599239],
- [0.221197, 0.016497, 0.602083],
- [0.227983, 0.016007, 0.604867],
- [0.234715, 0.015502, 0.607592],
- [0.241396, 0.014979, 0.610259],
- [0.248032, 0.014439, 0.612868],
- [0.254627, 0.013882, 0.615419],
- [0.261183, 0.013308, 0.617911],
- [0.267703, 0.012716, 0.620346],
- [0.274191, 0.012109, 0.622722],
- [0.280648, 0.011488, 0.625038],
- [0.287076, 0.010855, 0.627295],
- [0.293478, 0.010213, 0.629490],
- [0.299855, 0.009561, 0.631624],
- [0.306210, 0.008902, 0.633694],
- [0.312543, 0.008239, 0.635700],
- [0.318856, 0.007576, 0.637640],
- [0.325150, 0.006915, 0.639512],
- [0.331426, 0.006261, 0.641316],
- [0.337683, 0.005618, 0.643049],
- [0.343925, 0.004991, 0.644710],
- [0.350150, 0.004382, 0.646298],
- [0.356359, 0.003798, 0.647810],
- [0.362553, 0.003243, 0.649245],
- [0.368733, 0.002724, 0.650601],
- [0.374897, 0.002245, 0.651876],
- [0.381047, 0.001814, 0.653068],
- [0.387183, 0.001434, 0.654177],
- [0.393304, 0.001114, 0.655199],
- [0.399411, 0.000859, 0.656133],
- [0.405503, 0.000678, 0.656977],
- [0.411580, 0.000577, 0.657730],
- [0.417642, 0.000564, 0.658390],
- [0.423689, 0.000646, 0.658956],
- [0.429719, 0.000831, 0.659425],
- [0.435734, 0.001127, 0.659797],
- [0.441732, 0.001540, 0.660069],
- [0.447714, 0.002080, 0.660240],
- [0.453677, 0.002755, 0.660310],
- [0.459623, 0.003574, 0.660277],
- [0.465550, 0.004545, 0.660139],
- [0.471457, 0.005678, 0.659897],
- [0.477344, 0.006980, 0.659549],
- [0.483210, 0.008460, 0.659095],
- [0.489055, 0.010127, 0.658534],
- [0.494877, 0.011990, 0.657865],
- [0.500678, 0.014055, 0.657088],
- [0.506454, 0.016333, 0.656202],
- [0.512206, 0.018833, 0.655209],
- [0.517933, 0.021563, 0.654109],
- [0.523633, 0.024532, 0.652901],
- [0.529306, 0.027747, 0.651586],
- [0.534952, 0.031217, 0.650165],
- [0.540570, 0.034950, 0.648640],
- [0.546157, 0.038954, 0.647010],
- [0.551715, 0.043136, 0.645277],
- [0.557243, 0.047331, 0.643443],
- [0.562738, 0.051545, 0.641509],
- [0.568201, 0.055778, 0.639477],
- [0.573632, 0.060028, 0.637349],
- [0.579029, 0.064296, 0.635126],
- [0.584391, 0.068579, 0.632812],
- [0.589719, 0.072878, 0.630408],
- [0.595011, 0.077190, 0.627917],
- [0.600266, 0.081516, 0.625342],
- [0.605485, 0.085854, 0.622686],
- [0.610667, 0.090204, 0.619951],
- [0.615812, 0.094564, 0.617140],
- [0.620919, 0.098934, 0.614257],
- [0.625987, 0.103312, 0.611305],
- [0.631017, 0.107699, 0.608287],
- [0.636008, 0.112092, 0.605205],
- [0.640959, 0.116492, 0.602065],
- [0.645872, 0.120898, 0.598867],
- [0.650746, 0.125309, 0.595617],
- [0.655580, 0.129725, 0.592317],
- [0.660374, 0.134144, 0.588971],
- [0.665129, 0.138566, 0.585582],
- [0.669845, 0.142992, 0.582154],
- [0.674522, 0.147419, 0.578688],
- [0.679160, 0.151848, 0.575189],
- [0.683758, 0.156278, 0.571660],
- [0.688318, 0.160709, 0.568103],
- [0.692840, 0.165141, 0.564522],
- [0.697324, 0.169573, 0.560919],
- [0.701769, 0.174005, 0.557296],
- [0.706178, 0.178437, 0.553657],
- [0.710549, 0.182868, 0.550004],
- [0.714883, 0.187299, 0.546338],
- [0.719181, 0.191729, 0.542663],
- [0.723444, 0.196158, 0.538981],
- [0.727670, 0.200586, 0.535293],
- [0.731862, 0.205013, 0.531601],
- [0.736019, 0.209439, 0.527908],
- [0.740143, 0.213864, 0.524216],
- [0.744232, 0.218288, 0.520524],
- [0.748289, 0.222711, 0.516834],
- [0.752312, 0.227133, 0.513149],
- [0.756304, 0.231555, 0.509468],
- [0.760264, 0.235976, 0.505794],
- [0.764193, 0.240396, 0.502126],
- [0.768090, 0.244817, 0.498465],
- [0.771958, 0.249237, 0.494813],
- [0.775796, 0.253658, 0.491171],
- [0.779604, 0.258078, 0.487539],
- [0.783383, 0.262500, 0.483918],
- [0.787133, 0.266922, 0.480307],
- [0.790855, 0.271345, 0.476706],
- [0.794549, 0.275770, 0.473117],
- [0.798216, 0.280197, 0.469538],
- [0.801855, 0.284626, 0.465971],
- [0.805467, 0.289057, 0.462415],
- [0.809052, 0.293491, 0.458870],
- [0.812612, 0.297928, 0.455338],
- [0.816144, 0.302368, 0.451816],
- [0.819651, 0.306812, 0.448306],
- [0.823132, 0.311261, 0.444806],
- [0.826588, 0.315714, 0.441316],
- [0.830018, 0.320172, 0.437836],
- [0.833422, 0.324635, 0.434366],
- [0.836801, 0.329105, 0.430905],
- [0.840155, 0.333580, 0.427455],
- [0.843484, 0.338062, 0.424013],
- [0.846788, 0.342551, 0.420579],
- [0.850066, 0.347048, 0.417153],
- [0.853319, 0.351553, 0.413734],
- [0.856547, 0.356066, 0.410322],
- [0.859750, 0.360588, 0.406917],
- [0.862927, 0.365119, 0.403519],
- [0.866078, 0.369660, 0.400126],
- [0.869203, 0.374212, 0.396738],
- [0.872303, 0.378774, 0.393355],
- [0.875376, 0.383347, 0.389976],
- [0.878423, 0.387932, 0.386600],
- [0.881443, 0.392529, 0.383229],
- [0.884436, 0.397139, 0.379860],
- [0.887402, 0.401762, 0.376494],
- [0.890340, 0.406398, 0.373130],
- [0.893250, 0.411048, 0.369768],
- [0.896131, 0.415712, 0.366407],
- [0.898984, 0.420392, 0.363047],
- [0.901807, 0.425087, 0.359688],
- [0.904601, 0.429797, 0.356329],
- [0.907365, 0.434524, 0.352970],
- [0.910098, 0.439268, 0.349610],
- [0.912800, 0.444029, 0.346251],
- [0.915471, 0.448807, 0.342890],
- [0.918109, 0.453603, 0.339529],
- [0.920714, 0.458417, 0.336166],
- [0.923287, 0.463251, 0.332801],
- [0.925825, 0.468103, 0.329435],
- [0.928329, 0.472975, 0.326067],
- [0.930798, 0.477867, 0.322697],
- [0.933232, 0.482780, 0.319325],
- [0.935630, 0.487712, 0.315952],
- [0.937990, 0.492667, 0.312575],
- [0.940313, 0.497642, 0.309197],
- [0.942598, 0.502639, 0.305816],
- [0.944844, 0.507658, 0.302433],
- [0.947051, 0.512699, 0.299049],
- [0.949217, 0.517763, 0.295662],
- [0.951344, 0.522850, 0.292275],
- [0.953428, 0.527960, 0.288883],
- [0.955470, 0.533093, 0.285490],
- [0.957469, 0.538250, 0.282096],
- [0.959424, 0.543431, 0.278701],
- [0.961336, 0.548636, 0.275305],
- [0.963203, 0.553865, 0.271909],
- [0.965024, 0.559118, 0.268513],
- [0.966798, 0.564396, 0.265118],
- [0.968526, 0.569700, 0.261721],
- [0.970205, 0.575028, 0.258325],
- [0.971835, 0.580382, 0.254931],
- [0.973416, 0.585761, 0.251540],
- [0.974947, 0.591165, 0.248151],
- [0.976428, 0.596595, 0.244767],
- [0.977856, 0.602051, 0.241387],
- [0.979233, 0.607532, 0.238013],
- [0.980556, 0.613039, 0.234646],
- [0.981826, 0.618572, 0.231287],
- [0.983041, 0.624131, 0.227937],
- [0.984199, 0.629718, 0.224595],
- [0.985301, 0.635330, 0.221265],
- [0.986345, 0.640969, 0.217948],
- [0.987332, 0.646633, 0.214648],
- [0.988260, 0.652325, 0.211364],
- [0.989128, 0.658043, 0.208100],
- [0.989935, 0.663787, 0.204859],
- [0.990681, 0.669558, 0.201642],
- [0.991365, 0.675355, 0.198453],
- [0.991985, 0.681179, 0.195295],
- [0.992541, 0.687030, 0.192170],
- [0.993032, 0.692907, 0.189084],
- [0.993456, 0.698810, 0.186041],
- [0.993814, 0.704741, 0.183043],
- [0.994103, 0.710698, 0.180097],
- [0.994324, 0.716681, 0.177208],
- [0.994474, 0.722691, 0.174381],
- [0.994553, 0.728728, 0.171622],
- [0.994561, 0.734791, 0.168938],
- [0.994495, 0.740880, 0.166335],
- [0.994355, 0.746995, 0.163821],
- [0.994141, 0.753137, 0.161404],
- [0.993851, 0.759304, 0.159092],
- [0.993482, 0.765499, 0.156891],
- [0.993033, 0.771720, 0.154808],
- [0.992505, 0.777967, 0.152855],
- [0.991897, 0.784239, 0.151042],
- [0.991209, 0.790537, 0.149377],
- [0.990439, 0.796859, 0.147870],
- [0.989587, 0.803205, 0.146529],
- [0.988648, 0.809579, 0.145357],
- [0.987621, 0.815978, 0.144363],
- [0.986509, 0.822401, 0.143557],
- [0.985314, 0.828846, 0.142945],
- [0.984031, 0.835315, 0.142528],
- [0.982653, 0.841812, 0.142303],
- [0.981190, 0.848329, 0.142279],
- [0.979644, 0.854866, 0.142453],
- [0.977995, 0.861432, 0.142808],
- [0.976265, 0.868016, 0.143351],
- [0.974443, 0.874622, 0.144061],
- [0.972530, 0.881250, 0.144923],
- [0.970533, 0.887896, 0.145919],
- [0.968443, 0.894564, 0.147014],
- [0.966271, 0.901249, 0.148180],
- [0.964021, 0.907950, 0.149370],
- [0.961681, 0.914672, 0.150520],
- [0.959276, 0.921407, 0.151566],
- [0.956808, 0.928152, 0.152409],
- [0.954287, 0.934908, 0.152921],
- [0.951726, 0.941671, 0.152925],
- [0.949151, 0.948435, 0.152178],
- [0.946602, 0.955190, 0.150328],
- [0.944152, 0.961916, 0.146861],
- [0.941896, 0.968590, 0.140956],
- [0.940015, 0.975158, 0.131326]]
-
-_viridis_data = [[0.267004, 0.004874, 0.329415],
- [0.268510, 0.009605, 0.335427],
- [0.269944, 0.014625, 0.341379],
- [0.271305, 0.019942, 0.347269],
- [0.272594, 0.025563, 0.353093],
- [0.273809, 0.031497, 0.358853],
- [0.274952, 0.037752, 0.364543],
- [0.276022, 0.044167, 0.370164],
- [0.277018, 0.050344, 0.375715],
- [0.277941, 0.056324, 0.381191],
- [0.278791, 0.062145, 0.386592],
- [0.279566, 0.067836, 0.391917],
- [0.280267, 0.073417, 0.397163],
- [0.280894, 0.078907, 0.402329],
- [0.281446, 0.084320, 0.407414],
- [0.281924, 0.089666, 0.412415],
- [0.282327, 0.094955, 0.417331],
- [0.282656, 0.100196, 0.422160],
- [0.282910, 0.105393, 0.426902],
- [0.283091, 0.110553, 0.431554],
- [0.283197, 0.115680, 0.436115],
- [0.283229, 0.120777, 0.440584],
- [0.283187, 0.125848, 0.444960],
- [0.283072, 0.130895, 0.449241],
- [0.282884, 0.135920, 0.453427],
- [0.282623, 0.140926, 0.457517],
- [0.282290, 0.145912, 0.461510],
- [0.281887, 0.150881, 0.465405],
- [0.281412, 0.155834, 0.469201],
- [0.280868, 0.160771, 0.472899],
- [0.280255, 0.165693, 0.476498],
- [0.279574, 0.170599, 0.479997],
- [0.278826, 0.175490, 0.483397],
- [0.278012, 0.180367, 0.486697],
- [0.277134, 0.185228, 0.489898],
- [0.276194, 0.190074, 0.493001],
- [0.275191, 0.194905, 0.496005],
- [0.274128, 0.199721, 0.498911],
- [0.273006, 0.204520, 0.501721],
- [0.271828, 0.209303, 0.504434],
- [0.270595, 0.214069, 0.507052],
- [0.269308, 0.218818, 0.509577],
- [0.267968, 0.223549, 0.512008],
- [0.266580, 0.228262, 0.514349],
- [0.265145, 0.232956, 0.516599],
- [0.263663, 0.237631, 0.518762],
- [0.262138, 0.242286, 0.520837],
- [0.260571, 0.246922, 0.522828],
- [0.258965, 0.251537, 0.524736],
- [0.257322, 0.256130, 0.526563],
- [0.255645, 0.260703, 0.528312],
- [0.253935, 0.265254, 0.529983],
- [0.252194, 0.269783, 0.531579],
- [0.250425, 0.274290, 0.533103],
- [0.248629, 0.278775, 0.534556],
- [0.246811, 0.283237, 0.535941],
- [0.244972, 0.287675, 0.537260],
- [0.243113, 0.292092, 0.538516],
- [0.241237, 0.296485, 0.539709],
- [0.239346, 0.300855, 0.540844],
- [0.237441, 0.305202, 0.541921],
- [0.235526, 0.309527, 0.542944],
- [0.233603, 0.313828, 0.543914],
- [0.231674, 0.318106, 0.544834],
- [0.229739, 0.322361, 0.545706],
- [0.227802, 0.326594, 0.546532],
- [0.225863, 0.330805, 0.547314],
- [0.223925, 0.334994, 0.548053],
- [0.221989, 0.339161, 0.548752],
- [0.220057, 0.343307, 0.549413],
- [0.218130, 0.347432, 0.550038],
- [0.216210, 0.351535, 0.550627],
- [0.214298, 0.355619, 0.551184],
- [0.212395, 0.359683, 0.551710],
- [0.210503, 0.363727, 0.552206],
- [0.208623, 0.367752, 0.552675],
- [0.206756, 0.371758, 0.553117],
- [0.204903, 0.375746, 0.553533],
- [0.203063, 0.379716, 0.553925],
- [0.201239, 0.383670, 0.554294],
- [0.199430, 0.387607, 0.554642],
- [0.197636, 0.391528, 0.554969],
- [0.195860, 0.395433, 0.555276],
- [0.194100, 0.399323, 0.555565],
- [0.192357, 0.403199, 0.555836],
- [0.190631, 0.407061, 0.556089],
- [0.188923, 0.410910, 0.556326],
- [0.187231, 0.414746, 0.556547],
- [0.185556, 0.418570, 0.556753],
- [0.183898, 0.422383, 0.556944],
- [0.182256, 0.426184, 0.557120],
- [0.180629, 0.429975, 0.557282],
- [0.179019, 0.433756, 0.557430],
- [0.177423, 0.437527, 0.557565],
- [0.175841, 0.441290, 0.557685],
- [0.174274, 0.445044, 0.557792],
- [0.172719, 0.448791, 0.557885],
- [0.171176, 0.452530, 0.557965],
- [0.169646, 0.456262, 0.558030],
- [0.168126, 0.459988, 0.558082],
- [0.166617, 0.463708, 0.558119],
- [0.165117, 0.467423, 0.558141],
- [0.163625, 0.471133, 0.558148],
- [0.162142, 0.474838, 0.558140],
- [0.160665, 0.478540, 0.558115],
- [0.159194, 0.482237, 0.558073],
- [0.157729, 0.485932, 0.558013],
- [0.156270, 0.489624, 0.557936],
- [0.154815, 0.493313, 0.557840],
- [0.153364, 0.497000, 0.557724],
- [0.151918, 0.500685, 0.557587],
- [0.150476, 0.504369, 0.557430],
- [0.149039, 0.508051, 0.557250],
- [0.147607, 0.511733, 0.557049],
- [0.146180, 0.515413, 0.556823],
- [0.144759, 0.519093, 0.556572],
- [0.143343, 0.522773, 0.556295],
- [0.141935, 0.526453, 0.555991],
- [0.140536, 0.530132, 0.555659],
- [0.139147, 0.533812, 0.555298],
- [0.137770, 0.537492, 0.554906],
- [0.136408, 0.541173, 0.554483],
- [0.135066, 0.544853, 0.554029],
- [0.133743, 0.548535, 0.553541],
- [0.132444, 0.552216, 0.553018],
- [0.131172, 0.555899, 0.552459],
- [0.129933, 0.559582, 0.551864],
- [0.128729, 0.563265, 0.551229],
- [0.127568, 0.566949, 0.550556],
- [0.126453, 0.570633, 0.549841],
- [0.125394, 0.574318, 0.549086],
- [0.124395, 0.578002, 0.548287],
- [0.123463, 0.581687, 0.547445],
- [0.122606, 0.585371, 0.546557],
- [0.121831, 0.589055, 0.545623],
- [0.121148, 0.592739, 0.544641],
- [0.120565, 0.596422, 0.543611],
- [0.120092, 0.600104, 0.542530],
- [0.119738, 0.603785, 0.541400],
- [0.119512, 0.607464, 0.540218],
- [0.119423, 0.611141, 0.538982],
- [0.119483, 0.614817, 0.537692],
- [0.119699, 0.618490, 0.536347],
- [0.120081, 0.622161, 0.534946],
- [0.120638, 0.625828, 0.533488],
- [0.121380, 0.629492, 0.531973],
- [0.122312, 0.633153, 0.530398],
- [0.123444, 0.636809, 0.528763],
- [0.124780, 0.640461, 0.527068],
- [0.126326, 0.644107, 0.525311],
- [0.128087, 0.647749, 0.523491],
- [0.130067, 0.651384, 0.521608],
- [0.132268, 0.655014, 0.519661],
- [0.134692, 0.658636, 0.517649],
- [0.137339, 0.662252, 0.515571],
- [0.140210, 0.665859, 0.513427],
- [0.143303, 0.669459, 0.511215],
- [0.146616, 0.673050, 0.508936],
- [0.150148, 0.676631, 0.506589],
- [0.153894, 0.680203, 0.504172],
- [0.157851, 0.683765, 0.501686],
- [0.162016, 0.687316, 0.499129],
- [0.166383, 0.690856, 0.496502],
- [0.170948, 0.694384, 0.493803],
- [0.175707, 0.697900, 0.491033],
- [0.180653, 0.701402, 0.488189],
- [0.185783, 0.704891, 0.485273],
- [0.191090, 0.708366, 0.482284],
- [0.196571, 0.711827, 0.479221],
- [0.202219, 0.715272, 0.476084],
- [0.208030, 0.718701, 0.472873],
- [0.214000, 0.722114, 0.469588],
- [0.220124, 0.725509, 0.466226],
- [0.226397, 0.728888, 0.462789],
- [0.232815, 0.732247, 0.459277],
- [0.239374, 0.735588, 0.455688],
- [0.246070, 0.738910, 0.452024],
- [0.252899, 0.742211, 0.448284],
- [0.259857, 0.745492, 0.444467],
- [0.266941, 0.748751, 0.440573],
- [0.274149, 0.751988, 0.436601],
- [0.281477, 0.755203, 0.432552],
- [0.288921, 0.758394, 0.428426],
- [0.296479, 0.761561, 0.424223],
- [0.304148, 0.764704, 0.419943],
- [0.311925, 0.767822, 0.415586],
- [0.319809, 0.770914, 0.411152],
- [0.327796, 0.773980, 0.406640],
- [0.335885, 0.777018, 0.402049],
- [0.344074, 0.780029, 0.397381],
- [0.352360, 0.783011, 0.392636],
- [0.360741, 0.785964, 0.387814],
- [0.369214, 0.788888, 0.382914],
- [0.377779, 0.791781, 0.377939],
- [0.386433, 0.794644, 0.372886],
- [0.395174, 0.797475, 0.367757],
- [0.404001, 0.800275, 0.362552],
- [0.412913, 0.803041, 0.357269],
- [0.421908, 0.805774, 0.351910],
- [0.430983, 0.808473, 0.346476],
- [0.440137, 0.811138, 0.340967],
- [0.449368, 0.813768, 0.335384],
- [0.458674, 0.816363, 0.329727],
- [0.468053, 0.818921, 0.323998],
- [0.477504, 0.821444, 0.318195],
- [0.487026, 0.823929, 0.312321],
- [0.496615, 0.826376, 0.306377],
- [0.506271, 0.828786, 0.300362],
- [0.515992, 0.831158, 0.294279],
- [0.525776, 0.833491, 0.288127],
- [0.535621, 0.835785, 0.281908],
- [0.545524, 0.838039, 0.275626],
- [0.555484, 0.840254, 0.269281],
- [0.565498, 0.842430, 0.262877],
- [0.575563, 0.844566, 0.256415],
- [0.585678, 0.846661, 0.249897],
- [0.595839, 0.848717, 0.243329],
- [0.606045, 0.850733, 0.236712],
- [0.616293, 0.852709, 0.230052],
- [0.626579, 0.854645, 0.223353],
- [0.636902, 0.856542, 0.216620],
- [0.647257, 0.858400, 0.209861],
- [0.657642, 0.860219, 0.203082],
- [0.668054, 0.861999, 0.196293],
- [0.678489, 0.863742, 0.189503],
- [0.688944, 0.865448, 0.182725],
- [0.699415, 0.867117, 0.175971],
- [0.709898, 0.868751, 0.169257],
- [0.720391, 0.870350, 0.162603],
- [0.730889, 0.871916, 0.156029],
- [0.741388, 0.873449, 0.149561],
- [0.751884, 0.874951, 0.143228],
- [0.762373, 0.876424, 0.137064],
- [0.772852, 0.877868, 0.131109],
- [0.783315, 0.879285, 0.125405],
- [0.793760, 0.880678, 0.120005],
- [0.804182, 0.882046, 0.114965],
- [0.814576, 0.883393, 0.110347],
- [0.824940, 0.884720, 0.106217],
- [0.835270, 0.886029, 0.102646],
- [0.845561, 0.887322, 0.099702],
- [0.855810, 0.888601, 0.097452],
- [0.866013, 0.889868, 0.095953],
- [0.876168, 0.891125, 0.095250],
- [0.886271, 0.892374, 0.095374],
- [0.896320, 0.893616, 0.096335],
- [0.906311, 0.894855, 0.098125],
- [0.916242, 0.896091, 0.100717],
- [0.926106, 0.897330, 0.104071],
- [0.935904, 0.898570, 0.108131],
- [0.945636, 0.899815, 0.112838],
- [0.955300, 0.901065, 0.118128],
- [0.964894, 0.902323, 0.123941],
- [0.974417, 0.903590, 0.130215],
- [0.983868, 0.904867, 0.136897],
- [0.993248, 0.906157, 0.143936]]
-
-_cividis_data = [[0.000000, 0.135112, 0.304751],
- [0.000000, 0.138068, 0.311105],
- [0.000000, 0.141013, 0.317579],
- [0.000000, 0.143951, 0.323982],
- [0.000000, 0.146877, 0.330479],
- [0.000000, 0.149791, 0.337065],
- [0.000000, 0.152673, 0.343704],
- [0.000000, 0.155377, 0.350500],
- [0.000000, 0.157932, 0.357521],
- [0.000000, 0.160495, 0.364534],
- [0.000000, 0.163058, 0.371608],
- [0.000000, 0.165621, 0.378769],
- [0.000000, 0.168204, 0.385902],
- [0.000000, 0.170800, 0.393100],
- [0.000000, 0.173420, 0.400353],
- [0.000000, 0.176082, 0.407577],
- [0.000000, 0.178802, 0.414764],
- [0.000000, 0.181610, 0.421859],
- [0.000000, 0.184550, 0.428802],
- [0.000000, 0.186915, 0.435532],
- [0.000000, 0.188769, 0.439563],
- [0.000000, 0.190950, 0.441085],
- [0.000000, 0.193366, 0.441561],
- [0.003602, 0.195911, 0.441564],
- [0.017852, 0.198528, 0.441248],
- [0.032110, 0.201199, 0.440785],
- [0.046205, 0.203903, 0.440196],
- [0.058378, 0.206629, 0.439531],
- [0.068968, 0.209372, 0.438863],
- [0.078624, 0.212122, 0.438105],
- [0.087465, 0.214879, 0.437342],
- [0.095645, 0.217643, 0.436593],
- [0.103401, 0.220406, 0.435790],
- [0.110658, 0.223170, 0.435067],
- [0.117612, 0.225935, 0.434308],
- [0.124291, 0.228697, 0.433547],
- [0.130669, 0.231458, 0.432840],
- [0.136830, 0.234216, 0.432148],
- [0.142852, 0.236972, 0.431404],
- [0.148638, 0.239724, 0.430752],
- [0.154261, 0.242475, 0.430120],
- [0.159733, 0.245221, 0.429528],
- [0.165113, 0.247965, 0.428908],
- [0.170362, 0.250707, 0.428325],
- [0.175490, 0.253444, 0.427790],
- [0.180503, 0.256180, 0.427299],
- [0.185453, 0.258914, 0.426788],
- [0.190303, 0.261644, 0.426329],
- [0.195057, 0.264372, 0.425924],
- [0.199764, 0.267099, 0.425497],
- [0.204385, 0.269823, 0.425126],
- [0.208926, 0.272546, 0.424809],
- [0.213431, 0.275266, 0.424480],
- [0.217863, 0.277985, 0.424206],
- [0.222264, 0.280702, 0.423914],
- [0.226598, 0.283419, 0.423678],
- [0.230871, 0.286134, 0.423498],
- [0.235120, 0.288848, 0.423304],
- [0.239312, 0.291562, 0.423167],
- [0.243485, 0.294274, 0.423014],
- [0.247605, 0.296986, 0.422917],
- [0.251675, 0.299698, 0.422873],
- [0.255731, 0.302409, 0.422814],
- [0.259740, 0.305120, 0.422810],
- [0.263738, 0.307831, 0.422789],
- [0.267693, 0.310542, 0.422821],
- [0.271639, 0.313253, 0.422837],
- [0.275513, 0.315965, 0.422979],
- [0.279411, 0.318677, 0.423031],
- [0.283240, 0.321390, 0.423211],
- [0.287065, 0.324103, 0.423373],
- [0.290884, 0.326816, 0.423517],
- [0.294669, 0.329531, 0.423716],
- [0.298421, 0.332247, 0.423973],
- [0.302169, 0.334963, 0.424213],
- [0.305886, 0.337681, 0.424512],
- [0.309601, 0.340399, 0.424790],
- [0.313287, 0.343120, 0.425120],
- [0.316941, 0.345842, 0.425512],
- [0.320595, 0.348565, 0.425889],
- [0.324250, 0.351289, 0.426250],
- [0.327875, 0.354016, 0.426670],
- [0.331474, 0.356744, 0.427144],
- [0.335073, 0.359474, 0.427605],
- [0.338673, 0.362206, 0.428053],
- [0.342246, 0.364939, 0.428559],
- [0.345793, 0.367676, 0.429127],
- [0.349341, 0.370414, 0.429685],
- [0.352892, 0.373153, 0.430226],
- [0.356418, 0.375896, 0.430823],
- [0.359916, 0.378641, 0.431501],
- [0.363446, 0.381388, 0.432075],
- [0.366923, 0.384139, 0.432796],
- [0.370430, 0.386890, 0.433428],
- [0.373884, 0.389646, 0.434209],
- [0.377371, 0.392404, 0.434890],
- [0.380830, 0.395164, 0.435653],
- [0.384268, 0.397928, 0.436475],
- [0.387705, 0.400694, 0.437305],
- [0.391151, 0.403464, 0.438096],
- [0.394568, 0.406236, 0.438986],
- [0.397991, 0.409011, 0.439848],
- [0.401418, 0.411790, 0.440708],
- [0.404820, 0.414572, 0.441642],
- [0.408226, 0.417357, 0.442570],
- [0.411607, 0.420145, 0.443577],
- [0.414992, 0.422937, 0.444578],
- [0.418383, 0.425733, 0.445560],
- [0.421748, 0.428531, 0.446640],
- [0.425120, 0.431334, 0.447692],
- [0.428462, 0.434140, 0.448864],
- [0.431817, 0.436950, 0.449982],
- [0.435168, 0.439763, 0.451134],
- [0.438504, 0.442580, 0.452341],
- [0.441810, 0.445402, 0.453659],
- [0.445148, 0.448226, 0.454885],
- [0.448447, 0.451053, 0.456264],
- [0.451759, 0.453887, 0.457582],
- [0.455072, 0.456718, 0.458976],
- [0.458366, 0.459552, 0.460457],
- [0.461616, 0.462405, 0.461969],
- [0.464947, 0.465241, 0.463395],
- [0.468254, 0.468083, 0.464908],
- [0.471501, 0.470960, 0.466357],
- [0.474812, 0.473832, 0.467681],
- [0.478186, 0.476699, 0.468845],
- [0.481622, 0.479573, 0.469767],
- [0.485141, 0.482451, 0.470384],
- [0.488697, 0.485318, 0.471008],
- [0.492278, 0.488198, 0.471453],
- [0.495913, 0.491076, 0.471751],
- [0.499552, 0.493960, 0.472032],
- [0.503185, 0.496851, 0.472305],
- [0.506866, 0.499743, 0.472432],
- [0.510540, 0.502643, 0.472550],
- [0.514226, 0.505546, 0.472640],
- [0.517920, 0.508454, 0.472707],
- [0.521643, 0.511367, 0.472639],
- [0.525348, 0.514285, 0.472660],
- [0.529086, 0.517207, 0.472543],
- [0.532829, 0.520135, 0.472401],
- [0.536553, 0.523067, 0.472352],
- [0.540307, 0.526005, 0.472163],
- [0.544069, 0.528948, 0.471947],
- [0.547840, 0.531895, 0.471704],
- [0.551612, 0.534849, 0.471439],
- [0.555393, 0.537807, 0.471147],
- [0.559181, 0.540771, 0.470829],
- [0.562972, 0.543741, 0.470488],
- [0.566802, 0.546715, 0.469988],
- [0.570607, 0.549695, 0.469593],
- [0.574417, 0.552682, 0.469172],
- [0.578236, 0.555673, 0.468724],
- [0.582087, 0.558670, 0.468118],
- [0.585916, 0.561674, 0.467618],
- [0.589753, 0.564682, 0.467090],
- [0.593622, 0.567697, 0.466401],
- [0.597469, 0.570718, 0.465821],
- [0.601354, 0.573743, 0.465074],
- [0.605211, 0.576777, 0.464441],
- [0.609105, 0.579816, 0.463638],
- [0.612977, 0.582861, 0.462950],
- [0.616852, 0.585913, 0.462237],
- [0.620765, 0.588970, 0.461351],
- [0.624654, 0.592034, 0.460583],
- [0.628576, 0.595104, 0.459641],
- [0.632506, 0.598180, 0.458668],
- [0.636412, 0.601264, 0.457818],
- [0.640352, 0.604354, 0.456791],
- [0.644270, 0.607450, 0.455886],
- [0.648222, 0.610553, 0.454801],
- [0.652178, 0.613664, 0.453689],
- [0.656114, 0.616780, 0.452702],
- [0.660082, 0.619904, 0.451534],
- [0.664055, 0.623034, 0.450338],
- [0.668008, 0.626171, 0.449270],
- [0.671991, 0.629316, 0.448018],
- [0.675981, 0.632468, 0.446736],
- [0.679979, 0.635626, 0.445424],
- [0.683950, 0.638793, 0.444251],
- [0.687957, 0.641966, 0.442886],
- [0.691971, 0.645145, 0.441491],
- [0.695985, 0.648334, 0.440072],
- [0.700008, 0.651529, 0.438624],
- [0.704037, 0.654731, 0.437147],
- [0.708067, 0.657942, 0.435647],
- [0.712105, 0.661160, 0.434117],
- [0.716177, 0.664384, 0.432386],
- [0.720222, 0.667618, 0.430805],
- [0.724274, 0.670859, 0.429194],
- [0.728334, 0.674107, 0.427554],
- [0.732422, 0.677364, 0.425717],
- [0.736488, 0.680629, 0.424028],
- [0.740589, 0.683900, 0.422131],
- [0.744664, 0.687181, 0.420393],
- [0.748772, 0.690470, 0.418448],
- [0.752886, 0.693766, 0.416472],
- [0.756975, 0.697071, 0.414659],
- [0.761096, 0.700384, 0.412638],
- [0.765223, 0.703705, 0.410587],
- [0.769353, 0.707035, 0.408516],
- [0.773486, 0.710373, 0.406422],
- [0.777651, 0.713719, 0.404112],
- [0.781795, 0.717074, 0.401966],
- [0.785965, 0.720438, 0.399613],
- [0.790116, 0.723810, 0.397423],
- [0.794298, 0.727190, 0.395016],
- [0.798480, 0.730580, 0.392597],
- [0.802667, 0.733978, 0.390153],
- [0.806859, 0.737385, 0.387684],
- [0.811054, 0.740801, 0.385198],
- [0.815274, 0.744226, 0.382504],
- [0.819499, 0.747659, 0.379785],
- [0.823729, 0.751101, 0.377043],
- [0.827959, 0.754553, 0.374292],
- [0.832192, 0.758014, 0.371529],
- [0.836429, 0.761483, 0.368747],
- [0.840693, 0.764962, 0.365746],
- [0.844957, 0.768450, 0.362741],
- [0.849223, 0.771947, 0.359729],
- [0.853515, 0.775454, 0.356500],
- [0.857809, 0.778969, 0.353259],
- [0.862105, 0.782494, 0.350011],
- [0.866421, 0.786028, 0.346571],
- [0.870717, 0.789572, 0.343333],
- [0.875057, 0.793125, 0.339685],
- [0.879378, 0.796687, 0.336241],
- [0.883720, 0.800258, 0.332599],
- [0.888081, 0.803839, 0.328770],
- [0.892440, 0.807430, 0.324968],
- [0.896818, 0.811030, 0.320982],
- [0.901195, 0.814639, 0.317021],
- [0.905589, 0.818257, 0.312889],
- [0.910000, 0.821885, 0.308594],
- [0.914407, 0.825522, 0.304348],
- [0.918828, 0.829168, 0.299960],
- [0.923279, 0.832822, 0.295244],
- [0.927724, 0.836486, 0.290611],
- [0.932180, 0.840159, 0.285880],
- [0.936660, 0.843841, 0.280876],
- [0.941147, 0.847530, 0.275815],
- [0.945654, 0.851228, 0.270532],
- [0.950178, 0.854933, 0.265085],
- [0.954725, 0.858646, 0.259365],
- [0.959284, 0.862365, 0.253563],
- [0.963872, 0.866089, 0.247445],
- [0.968469, 0.869819, 0.241310],
- [0.973114, 0.873550, 0.234677],
- [0.977780, 0.877281, 0.227954],
- [0.982497, 0.881008, 0.220878],
- [0.987293, 0.884718, 0.213336],
- [0.992218, 0.888385, 0.205468],
- [0.994847, 0.892954, 0.203445],
- [0.995249, 0.898384, 0.207561],
- [0.995503, 0.903866, 0.212370],
- [0.995737, 0.909344, 0.217772]]
-
-_twilight_data = [
- [0.88575015840754434, 0.85000924943067835, 0.8879736506427196],
- [0.88378520195539056, 0.85072940540310626, 0.88723222096949894],
- [0.88172231059285788, 0.85127594077653468, 0.88638056925514819],
- [0.8795410528270573, 0.85165675407495722, 0.8854143767924102],
- [0.87724880858965482, 0.85187028338870274, 0.88434120381311432],
- [0.87485347508575972, 0.85191526123023187, 0.88316926967613829],
- [0.87233134085124076, 0.85180165478080894, 0.88189704355001619],
- [0.86970474853509816, 0.85152403004797894, 0.88053883390003362],
- [0.86696015505333579, 0.8510896085314068, 0.87909766977173343],
- [0.86408985081463996, 0.85050391167507788, 0.87757925784892632],
- [0.86110245436899846, 0.84976754857001258, 0.87599242923439569],
- [0.85798259245670372, 0.84888934810281835, 0.87434038553446281],
- [0.85472593189256985, 0.84787488124672816, 0.8726282980930582],
- [0.85133714570857189, 0.84672735796116472, 0.87086081657350445],
- [0.84780710702577922, 0.8454546229209523, 0.86904036783694438],
- [0.8441261828674842, 0.84406482711037389, 0.86716973322690072],
- [0.84030420805957784, 0.8425605950855084, 0.865250882410458],
- [0.83634031809191178, 0.84094796518951942, 0.86328528001070159],
- [0.83222705712934408, 0.83923490627754482, 0.86127563500427884],
- [0.82796894316013536, 0.83742600751395202, 0.85922399451306786],
- [0.82357429680252847, 0.83552487764795436, 0.85713191328514948],
- [0.81904654677937527, 0.8335364929949034, 0.85500206287010105],
- [0.81438982121143089, 0.83146558694197847, 0.85283759062147024],
- [0.8095999819094809, 0.82931896673505456, 0.85064441601050367],
- [0.80469164429814577, 0.82709838780560663, 0.84842449296974021],
- [0.79967075421267997, 0.82480781812080928, 0.84618210029578533],
- [0.79454305089231114, 0.82245116226304615, 0.84392184786827984],
- [0.78931445564608915, 0.82003213188702007, 0.8416486380471222],
- [0.78399101042764918, 0.81755426400533426, 0.83936747464036732],
- [0.77857892008227592, 0.81502089378742548, 0.8370834463093898],
- [0.77308416590170936, 0.81243524735466011, 0.83480172950579679],
- [0.76751108504417864, 0.8098007598713145, 0.83252816638059668],
- [0.76186907937980286, 0.80711949387647486, 0.830266486168872],
- [0.75616443584381976, 0.80439408733477935, 0.82802138994719998],
- [0.75040346765406696, 0.80162699008965321, 0.82579737851082424],
- [0.74459247771890169, 0.79882047719583249, 0.82359867586156521],
- [0.73873771700494939, 0.79597665735031009, 0.82142922780433014],
- [0.73284543645523459, 0.79309746468844067, 0.81929263384230377],
- [0.72692177512829703, 0.7901846863592763, 0.81719217466726379],
- [0.72097280665536778, 0.78723995923452639, 0.81513073920879264],
- [0.71500403076252128, 0.78426487091581187, 0.81311116559949914],
- [0.70902078134539304, 0.78126088716070907, 0.81113591855117928],
- [0.7030297722540817, 0.77822904973358131, 0.80920618848056969],
- [0.6970365443886174, 0.77517050008066057, 0.80732335380063447],
- [0.69104641009309098, 0.77208629460678091, 0.80548841690679074],
- [0.68506446154395928, 0.7689774029354699, 0.80370206267176914],
- [0.67909554499882152, 0.76584472131395898, 0.8019646617300199],
- [0.67314422559426212, 0.76268908733890484, 0.80027628545809526],
- [0.66721479803752815, 0.7595112803730375, 0.79863674654537764],
- [0.6613112930078745, 0.75631202708719025, 0.7970456043491897],
- [0.65543692326454717, 0.75309208756768431, 0.79550271129031047],
- [0.64959573004253479, 0.74985201221941766, 0.79400674021499107],
- [0.6437910831099849, 0.7465923800833657, 0.79255653201306053],
- [0.63802586828545982, 0.74331376714033193, 0.79115100459573173],
- [0.6323027138710603, 0.74001672160131404, 0.78978892762640429],
- [0.62662402022604591, 0.73670175403699445, 0.78846901316334561],
- [0.62099193064817548, 0.73336934798923203, 0.78718994624696581],
- [0.61540846411770478, 0.73001995232739691, 0.78595022706750484],
- [0.60987543176093062, 0.72665398759758293, 0.78474835732694714],
- [0.60439434200274855, 0.7232718614323369, 0.78358295593535587],
- [0.5989665814482068, 0.71987394892246725, 0.78245259899346642],
- [0.59359335696837223, 0.7164606049658685, 0.78135588237640097],
- [0.58827579780555495, 0.71303214646458135, 0.78029141405636515],
- [0.58301487036932409, 0.70958887676997473, 0.77925781820476592],
- [0.5778116438998202, 0.70613106157153982, 0.77825345121025524],
- [0.5726668948158774, 0.7026589535425779, 0.77727702680911992],
- [0.56758117853861967, 0.69917279302646274, 0.77632748534275298],
- [0.56255515357219343, 0.69567278381629649, 0.77540359142309845],
- [0.55758940419605174, 0.69215911458254054, 0.7745041337932782],
- [0.55268450589347129, 0.68863194515166382, 0.7736279426902245],
- [0.54784098153018634, 0.68509142218509878, 0.77277386473440868],
- [0.54305932424018233, 0.68153767253065878, 0.77194079697835083],
- [0.53834015575176275, 0.67797081129095405, 0.77112734439057717],
- [0.53368389147728401, 0.67439093705212727, 0.7703325054879735],
- [0.529090861832473, 0.67079812302806219, 0.76955552292313134],
- [0.52456151470593582, 0.66719242996142225, 0.76879541714230948],
- [0.52009627392235558, 0.66357391434030388, 0.76805119403344102],
- [0.5156955988596057, 0.65994260812897998, 0.76732191489596169],
- [0.51135992541601927, 0.65629853981831865, 0.76660663780645333],
- [0.50708969576451657, 0.65264172403146448, 0.76590445660835849],
- [0.5028853540415561, 0.64897216734095264, 0.76521446718174913],
- [0.49874733661356069, 0.6452898684900934, 0.76453578734180083],
- [0.4946761847863938, 0.64159484119504429, 0.76386719002130909],
- [0.49067224938561221, 0.63788704858847078, 0.76320812763163837],
- [0.4867359599430568, 0.63416646251100506, 0.76255780085924041],
- [0.4828677867260272, 0.6304330455306234, 0.76191537149895305],
- [0.47906816236197386, 0.62668676251860134, 0.76128000375662419],
- [0.47533752394906287, 0.62292757283835809, 0.76065085571817748],
- [0.47167629518877091, 0.61915543242884641, 0.76002709227883047],
- [0.46808490970531597, 0.61537028695790286, 0.75940789891092741],
- [0.46456376716303932, 0.61157208822864151, 0.75879242623025811],
- [0.46111326647023881, 0.607760777169989, 0.75817986436807139],
- [0.45773377230160567, 0.60393630046586455, 0.75756936901859162],
- [0.45442563977552913, 0.60009859503858665, 0.75696013660606487],
- [0.45118918687617743, 0.59624762051353541, 0.75635120643246645],
- [0.44802470933589172, 0.59238331452146575, 0.75574176474107924],
- [0.44493246854215379, 0.5885055998308617, 0.7551311041857901],
- [0.44191271766696399, 0.58461441100175571, 0.75451838884410671],
- [0.43896563958048396, 0.58070969241098491, 0.75390276208285945],
- [0.43609138958356369, 0.57679137998186081, 0.7532834105961016],
- [0.43329008867358393, 0.57285941625606673, 0.75265946532566674],
- [0.43056179073057571, 0.56891374572457176, 0.75203008099312696],
- [0.42790652284925834, 0.5649543060909209, 0.75139443521914839],
- [0.42532423665011354, 0.56098104959950301, 0.75075164989005116],
- [0.42281485675772662, 0.55699392126996583, 0.75010086988227642],
- [0.42037822361396326, 0.55299287158108168, 0.7494412559451894],
- [0.41801414079233629, 0.54897785421888889, 0.74877193167001121],
- [0.4157223260454232, 0.54494882715350401, 0.74809204459000522],
- [0.41350245743314729, 0.54090574771098476, 0.74740073297543086],
- [0.41135414697304568, 0.53684857765005933, 0.74669712855065784],
- [0.4092768899914751, 0.53277730177130322, 0.74598030635707824],
- [0.40727018694219069, 0.52869188011057411, 0.74524942637581271],
- [0.40533343789303178, 0.52459228174983119, 0.74450365836708132],
- [0.40346600333905397, 0.52047847653840029, 0.74374215223567086],
- [0.40166714010896104, 0.51635044969688759, 0.7429640345324835],
- [0.39993606933454834, 0.51220818143218516, 0.74216844571317986],
- [0.3982719152586337, 0.50805166539276136, 0.74135450918099721],
- [0.39667374905665609, 0.50388089053847973, 0.74052138580516735],
- [0.39514058808207631, 0.49969585326377758, 0.73966820211715711],
- [0.39367135736822567, 0.49549655777451179, 0.738794102296364],
- [0.39226494876209317, 0.49128300332899261, 0.73789824784475078],
- [0.39092017571994903, 0.48705520251223039, 0.73697977133881254],
- [0.38963580160340855, 0.48281316715123496, 0.73603782546932739],
- [0.38841053300842432, 0.47855691131792805, 0.73507157641157261],
- [0.38724301459330251, 0.47428645933635388, 0.73408016787854391],
- [0.38613184178892102, 0.4700018340988123, 0.7330627749243106],
- [0.38507556793651387, 0.46570306719930193, 0.73201854033690505],
- [0.38407269378943537, 0.46139018782416635, 0.73094665432902683],
- [0.38312168084402748, 0.45706323581407199, 0.72984626791353258],
- [0.38222094988570376, 0.45272225034283325, 0.72871656144003782],
- [0.38136887930454161, 0.44836727669277859, 0.72755671317141346],
- [0.38056380696565623, 0.44399837208633719, 0.72636587045135315],
- [0.37980403744848751, 0.43961558821222629, 0.72514323778761092],
- [0.37908789283110761, 0.43521897612544935, 0.72388798691323131],
- [0.378413635091359, 0.43080859411413064, 0.72259931993061044],
- [0.37777949753513729, 0.4263845142616835, 0.72127639993530235],
- [0.37718371844251231, 0.42194680223454828, 0.71991841524475775],
- [0.37662448930806297, 0.41749553747893614, 0.71852454736176108],
- [0.37610001286385814, 0.41303079952477062, 0.71709396919920232],
- [0.37560846919442398, 0.40855267638072096, 0.71562585091587549],
- [0.37514802505380473, 0.4040612609993941, 0.7141193695725726],
- [0.37471686019302231, 0.3995566498711684, 0.71257368516500463],
- [0.37431313199312338, 0.39503894828283309, 0.71098796522377461],
- [0.37393499330475782, 0.39050827529375831, 0.70936134293478448],
- [0.3735806215098284, 0.38596474386057539, 0.70769297607310577],
- [0.37324816143326384, 0.38140848555753937, 0.70598200974806036],
- [0.37293578646665032, 0.37683963835219841, 0.70422755780589941],
- [0.37264166757849604, 0.37225835004836849, 0.7024287314570723],
- [0.37236397858465387, 0.36766477862108266, 0.70058463496520773],
- [0.37210089702443822, 0.36305909736982378, 0.69869434615073722],
- [0.3718506155898596, 0.35844148285875221, 0.69675695810256544],
- [0.37161133234400479, 0.3538121372967869, 0.69477149919380887],
- [0.37138124223736607, 0.34917126878479027, 0.69273703471928827],
- [0.37115856636209105, 0.34451911410230168, 0.69065253586464992],
- [0.37094151551337329, 0.33985591488818123, 0.68851703379505125],
- [0.37072833279422668, 0.33518193808489577, 0.68632948169606767],
- [0.37051738634484427, 0.33049741244307851, 0.68408888788857214],
- [0.37030682071842685, 0.32580269697872455, 0.68179411684486679],
- [0.37009487130772695, 0.3210981375964933, 0.67944405399056851],
- [0.36987980329025361, 0.31638410101153364, 0.67703755438090574],
- [0.36965987626565955, 0.31166098762951971, 0.67457344743419545],
- [0.36943334591276228, 0.30692923551862339, 0.67205052849120617],
- [0.36919847837592484, 0.30218932176507068, 0.66946754331614522],
- [0.36895355306596778, 0.29744175492366276, 0.66682322089824264],
- [0.36869682231895268, 0.29268709856150099, 0.66411625298236909],
- [0.36842655638020444, 0.28792596437778462, 0.66134526910944602],
- [0.36814101479899719, 0.28315901221182987, 0.65850888806972308],
- [0.36783843696531082, 0.27838697181297761, 0.65560566838453704],
- [0.36751707094367697, 0.27361063317090978, 0.65263411711618635],
- [0.36717513650699446, 0.26883085667326956, 0.64959272297892245],
- [0.36681085540107988, 0.26404857724525643, 0.64647991652908243],
- [0.36642243251550632, 0.25926481158628106, 0.64329409140765537],
- [0.36600853966739794, 0.25448043878086224, 0.64003361803368586],
- [0.36556698373538982, 0.24969683475296395, 0.63669675187488584],
- [0.36509579845886808, 0.24491536803550484, 0.63328173520055586],
- [0.36459308890125008, 0.24013747024823828, 0.62978680155026101],
- [0.36405693022088509, 0.23536470386204195, 0.62621013451953023],
- [0.36348537610385145, 0.23059876218396419, 0.62254988622392882],
- [0.36287643560041027, 0.22584149293287031, 0.61880417410823019],
- [0.36222809558295926, 0.22109488427338303, 0.61497112346096128],
- [0.36153829010998356, 0.21636111429594002, 0.61104880679640927],
- [0.36080493826624654, 0.21164251793458128, 0.60703532172064711],
- [0.36002681809096376, 0.20694122817889948, 0.60292845431916875],
- [0.35920088560930186, 0.20226037920758122, 0.5987265295935138],
- [0.35832489966617809, 0.197602942459778, 0.59442768517501066],
- [0.35739663292915563, 0.19297208197842461, 0.59003011251063131],
- [0.35641381143126327, 0.18837119869242164, 0.5855320765920552],
- [0.35537415306906722, 0.18380392577704466, 0.58093191431832802],
- [0.35427534960663759, 0.17927413271618647, 0.57622809660668717],
- [0.35311574421123737, 0.17478570377561287, 0.57141871523555288],
- [0.35189248608873791, 0.17034320478524959, 0.56650284911216653],
- [0.35060304441931012, 0.16595129984720861, 0.56147964703993225],
- [0.34924513554955644, 0.16161477763045118, 0.55634837474163779],
- [0.34781653238777782, 0.15733863511152979, 0.55110853452703257],
- [0.34631507175793091, 0.15312802296627787, 0.5457599924248665],
- [0.34473901574536375, 0.14898820589826409, 0.54030245920406539],
- [0.34308600291572294, 0.14492465359918028, 0.53473704282067103],
- [0.34135411074506483, 0.1409427920655632, 0.52906500940336754],
- [0.33954168752669694, 0.13704801896718169, 0.52328797535085236],
- [0.33764732090671112, 0.13324562282438077, 0.51740807573979475],
- [0.33566978565015315, 0.12954074251271822, 0.51142807215168951],
- [0.33360804901486002, 0.12593818301005921, 0.50535164796654897],
- [0.33146154891145124, 0.12244245263391232, 0.49918274588431072],
- [0.32923005203231409, 0.11905764321981127, 0.49292595612342666],
- [0.3269137124539796, 0.1157873496841953, 0.48658646495697461],
- [0.32451307931207785, 0.11263459791730848, 0.48017007211645196],
- [0.32202882276069322, 0.10960114111258401, 0.47368494725726878],
- [0.31946262395497965, 0.10668879882392659, 0.46713728801395243],
- [0.31681648089023501, 0.10389861387653518, 0.46053414662739794],
- [0.31409278414755532, 0.10123077676403242, 0.45388335612058467],
- [0.31129434479712365, 0.098684771934052201, 0.44719313715161618],
- [0.30842444457210105, 0.096259385340577736, 0.44047194882050544],
- [0.30548675819945936, 0.093952764840823738, 0.43372849999361113],
- [0.30248536364574252, 0.091761187397303601, 0.42697404043749887],
- [0.29942483960214772, 0.089682253716750038, 0.42021619665853854],
- [0.29631000388905288, 0.087713250960463951, 0.41346259134143476],
- [0.29314593096985248, 0.085850656889620708, 0.40672178082365834],
- [0.28993792445176608, 0.08409078829085731, 0.40000214725256295],
- [0.28669151388283165, 0.082429873848480689, 0.39331182532243375],
- [0.28341239797185225, 0.080864153365499375, 0.38665868550105914],
- [0.28010638576975472, 0.079389994802261526, 0.38005028528138707],
- [0.27677939615815589, 0.078003941033788216, 0.37349382846504675],
- [0.27343739342450812, 0.076702800237496066, 0.36699616136347685],
- [0.27008637749114051, 0.075483675584275545, 0.36056376228111864],
- [0.26673233211995284, 0.074344018028546205, 0.35420276066240958],
- [0.26338121807151404, 0.073281657939897077, 0.34791888996380105],
- [0.26003895187439957, 0.072294781043362205, 0.3417175669546984],
- [0.25671191651083902, 0.071380106242082242, 0.33560648984600089],
- [0.25340685873736807, 0.070533582926851829, 0.3295945757321303],
- [0.25012845306199383, 0.069758206429106989, 0.32368100685760637],
- [0.24688226237958999, 0.069053639449204451, 0.31786993834254956],
- [0.24367372557466271, 0.068419855150922693, 0.31216524050888372],
- [0.24050813332295939, 0.067857103814855602, 0.30657054493678321],
- [0.23739062429054825, 0.067365888050555517, 0.30108922184065873],
- [0.23433055727563878, 0.066935599661639394, 0.29574009929867601],
- [0.23132955273021344, 0.066576186939090592, 0.29051361067988485],
- [0.2283917709422868, 0.06628997924139618, 0.28541074411068496],
- [0.22552164337737857, 0.066078173119395595, 0.28043398847505197],
- [0.22272706739121817, 0.065933790675651943, 0.27559714652053702],
- [0.22001251100779617, 0.065857918918907604, 0.27090279994325861],
- [0.21737845072382705, 0.065859661233562045, 0.26634209349669508],
- [0.21482843531473683, 0.065940385613778491, 0.26191675992376573],
- [0.21237411048541005, 0.066085024661758446, 0.25765165093569542],
- [0.21001214221188125, 0.066308573918947178, 0.2535289048041211],
- [0.2077442377448806, 0.06661453200418091, 0.24954644291943817],
- [0.20558051999470117, 0.066990462397868739, 0.24572497420147632],
- [0.20352007949514977, 0.067444179612424215, 0.24205576625191821],
- [0.20156133764129841, 0.067983271026200248, 0.23852974228695395],
- [0.19971571438603364, 0.068592710553704722, 0.23517094067076993],
- [0.19794834061899208, 0.069314066071660657, 0.23194647381302336],
- [0.1960826032659409, 0.070321227242423623, 0.22874673279569585],
- [0.19410351363791453, 0.071608304856891569, 0.22558727307410353],
- [0.19199449184606268, 0.073182830649273306, 0.22243385243433622],
- [0.18975853639094634, 0.075019861862143766, 0.2193005075652994],
- [0.18739228342697645, 0.077102096899588329, 0.21618875376309582],
- [0.18488035509396164, 0.079425730279723883, 0.21307651648984993],
- [0.18774482037046955, 0.077251588468039312, 0.21387448578597812],
- [0.19049578401722037, 0.075311278416787641, 0.2146562337112265],
- [0.1931548636579131, 0.073606819040117955, 0.21542362939081539],
- [0.19571853588267552, 0.072157781039602742, 0.21617499187076789],
- [0.19819343656336558, 0.070974625252738788, 0.21690975060032436],
- [0.20058760685133747, 0.070064576149984209, 0.21762721310371608],
- [0.20290365333558247, 0.069435248580458964, 0.21833167885096033],
- [0.20531725273301316, 0.068919592266397572, 0.21911516689288835],
- [0.20785704662965598, 0.068484398797025281, 0.22000133917653536],
- [0.21052882914958676, 0.06812195249816172, 0.22098759107715404],
- [0.2133313859647627, 0.067830148426026665, 0.22207043213024291],
- [0.21625279838647882, 0.067616330270516389, 0.22324568672294431],
- [0.21930503925136402, 0.067465786362940039, 0.22451023616807558],
- [0.22247308588973624, 0.067388214053092838, 0.22585960379408354],
- [0.2257539681670791, 0.067382132300147474, 0.22728984778098055],
- [0.22915620278592841, 0.067434730871152565, 0.22879681433956656],
- [0.23266299920501882, 0.067557104388479783, 0.23037617493752832],
- [0.23627495835774248, 0.06774359820987802, 0.23202360805926608],
- [0.23999586188690308, 0.067985029964779953, 0.23373434258507808],
- [0.24381149720247919, 0.068289851529011875, 0.23550427698321885],
- [0.24772092990501099, 0.068653337909486523, 0.2373288009471749],
- [0.25172899728289466, 0.069064630826035506, 0.23920260612763083],
- [0.25582135547481771, 0.06953231029187984, 0.24112190491594204],
- [0.25999463887892144, 0.070053855603861875, 0.24308218808684579],
- [0.26425512207060942, 0.070616595622995437, 0.24507758869355967],
- [0.26859095948172862, 0.071226716277922458, 0.24710443563450618],
- [0.27299701518897301, 0.071883555446163511, 0.24915847093232929],
- [0.27747150809142801, 0.072582969899254779, 0.25123493995942769],
- [0.28201746297366942, 0.073315693214040967, 0.25332800295084507],
- [0.28662309235899847, 0.074088460826808866, 0.25543478673717029],
- [0.29128515387578635, 0.074899049847466703, 0.25755101595750435],
- [0.2960004726065818, 0.075745336000958424, 0.25967245030364566],
- [0.30077276812918691, 0.076617824336164764, 0.26179294097819672],
- [0.30559226007249934, 0.077521963107537312, 0.26391006692119662],
- [0.31045520848595526, 0.078456871676182177, 0.2660200572779356],
- [0.31535870009205808, 0.079420997315243186, 0.26811904076941961],
- [0.32029986557994061, 0.080412994737554838, 0.27020322893039511],
- [0.32527888860401261, 0.081428390076546092, 0.27226772884656186],
- [0.33029174471181438, 0.08246763389003825, 0.27430929404579435],
- [0.33533353224455448, 0.083532434119003962, 0.27632534356790039],
- [0.34040164359597463, 0.084622236191702671, 0.27831254595259397],
- [0.34549355713871799, 0.085736654965126335, 0.28026769921081435],
- [0.35060678246032478, 0.08687555176033529, 0.28218770540182386],
- [0.35573889947341125, 0.088038974350243354, 0.2840695897279818],
- [0.36088752387578377, 0.089227194362745205, 0.28591050458531014],
- [0.36605031412464006, 0.090440685427697898, 0.2877077458811747],
- [0.37122508431309342, 0.091679997480262732, 0.28945865397633169],
- [0.3764103053221462, 0.092945198093777909, 0.29116024157313919],
- [0.38160247377467543, 0.094238731263712183, 0.29281107506269488],
- [0.38679939079544168, 0.09556181960083443, 0.29440901248173756],
- [0.39199887556812907, 0.09691583650296684, 0.29595212005509081],
- [0.39719876876325577, 0.098302320968278623, 0.29743856476285779],
- [0.40239692379737496, 0.099722930314950553, 0.29886674369733968],
- [0.40759120392688708, 0.10117945586419633, 0.30023519507728602],
- [0.41277985630360303, 0.1026734006932461, 0.30154226437468967],
- [0.41796105205173684, 0.10420644885760968, 0.30278652039631843],
- [0.42313214269556043, 0.10578120994917611, 0.3039675809469457],
- [0.42829101315789753, 0.1073997763055258, 0.30508479060294547],
- [0.4334355841041439, 0.1090642347484701, 0.30613767928289148],
- [0.43856378187931538, 0.11077667828375456, 0.30712600062348083],
- [0.44367358645071275, 0.11253912421257944, 0.30804973095465449],
- [0.44876299173174822, 0.11435355574622549, 0.30890905921943196],
- [0.45383005086999889, 0.11622183788331528, 0.30970441249844921],
- [0.45887288947308297, 0.11814571137706886, 0.31043636979038808],
- [0.46389102840284874, 0.12012561256850712, 0.31110343446582983],
- [0.46888111384598413, 0.12216445576414045, 0.31170911458932665],
- [0.473841437035254, 0.12426354237989065, 0.31225470169927194],
- [0.47877034239726296, 0.12642401401409453, 0.31274172735821959],
- [0.48366628618847957, 0.12864679022013889, 0.31317188565991266],
- [0.48852847371852987, 0.13093210934893723, 0.31354553695453014],
- [0.49335504375145617, 0.13328091630401023, 0.31386561956734976],
- [0.49814435462074153, 0.13569380302451714, 0.314135190862664],
- [0.50289524974970612, 0.13817086581280427, 0.31435662153833671],
- [0.50760681181053691, 0.14071192654913128, 0.31453200120082569],
- [0.51227835105321762, 0.14331656120063752, 0.3146630922831542],
- [0.51690848800544464, 0.14598463068714407, 0.31475407592280041],
- [0.52149652863229956, 0.14871544765633712, 0.31480767954534428],
- [0.52604189625477482, 0.15150818660835483, 0.31482653406646727],
- [0.53054420489856446, 0.15436183633886777, 0.31481299789187128],
- [0.5350027976174474, 0.15727540775107324, 0.31477085207396532],
- [0.53941736649199057, 0.16024769309971934, 0.31470295028655965],
- [0.54378771313608565, 0.16327738551419116, 0.31461204226295625],
- [0.54811370033467621, 0.1663630904279047, 0.31450102990914708],
- [0.55239521572711914, 0.16950338809328983, 0.31437291554615371],
- [0.55663229034969341, 0.17269677158182117, 0.31423043195101424],
- [0.56082499039117173, 0.17594170887918095, 0.31407639883970623],
- [0.56497343529017696, 0.17923664950367169, 0.3139136046337036],
- [0.56907784784011428, 0.18258004462335425, 0.31374440956796529],
- [0.57313845754107873, 0.18597036007065024, 0.31357126868520002],
- [0.57715550812992045, 0.18940601489760422, 0.31339704333572083],
- [0.58112932761586555, 0.19288548904692518, 0.31322399394183942],
- [0.58506024396466882, 0.19640737049066315, 0.31305401163732732],
- [0.58894861935544707, 0.19997020971775276, 0.31288922211590126],
- [0.59279480536520257, 0.20357251410079796, 0.31273234839304942],
- [0.59659918109122367, 0.207212956082026, 0.31258523031121233],
- [0.60036213010411577, 0.21089030138947745, 0.31244934410414688],
- [0.60408401696732739, 0.21460331490206347, 0.31232652641170694],
- [0.60776523994818654, 0.21835070166659282, 0.31221903291870201],
- [0.6114062072731884, 0.22213124697023234, 0.31212881396435238],
- [0.61500723236391375, 0.22594402043981826, 0.31205680685765741],
- [0.61856865258877192, 0.22978799249179921, 0.31200463838728931],
- [0.62209079821082613, 0.2336621873300741, 0.31197383273627388],
- [0.62557416500434959, 0.23756535071152696, 0.31196698314912269],
- [0.62901892016985872, 0.24149689191922535, 0.31198447195645718],
- [0.63242534854210275, 0.24545598775548677, 0.31202765974624452],
- [0.6357937104834237, 0.24944185818822678, 0.31209793953300591],
- [0.6391243387840212, 0.25345365461983138, 0.31219689612063978],
- [0.642417577481186, 0.257490519876798, 0.31232631707560987],
- [0.64567349382645434, 0.26155203161615281, 0.31248673753935263],
- [0.64889230169458245, 0.26563755336209077, 0.31267941819570189],
- [0.65207417290277303, 0.26974650525236699, 0.31290560605819168],
- [0.65521932609327127, 0.27387826652410152, 0.3131666792687211],
- [0.6583280801134499, 0.27803210957665631, 0.3134643447952643],
- [0.66140037532601781, 0.28220778870555907, 0.31379912926498488],
- [0.66443632469878844, 0.28640483614256179, 0.31417223403606975],
- [0.66743603766369131, 0.29062280081258873, 0.31458483752056837],
- [0.67039959547676198, 0.29486126309253047, 0.31503813956872212],
- [0.67332725564817331, 0.29911962764489264, 0.31553372323982209],
- [0.67621897924409746, 0.30339762792450425, 0.3160724937230589],
- [0.67907474028157344, 0.30769497879760166, 0.31665545668946665],
- [0.68189457150944521, 0.31201133280550686, 0.31728380489244951],
- [0.68467850942494535, 0.31634634821222207, 0.31795870784057567],
- [0.68742656435169625, 0.32069970535138104, 0.31868137622277692],
- [0.6901389321505248, 0.32507091815606004, 0.31945332332898302],
- [0.69281544846764931, 0.32945984647042675, 0.3202754315314667],
- [0.69545608346891119, 0.33386622163232865, 0.32114884306985791],
- [0.6980608153581771, 0.33828976326048621, 0.32207478855218091],
- [0.70062962477242097, 0.34273019305341756, 0.32305449047765694],
- [0.70316249458814151, 0.34718723719597999, 0.32408913679491225],
- [0.70565951122610093, 0.35166052978120937, 0.32518014084085567],
- [0.70812059568420482, 0.35614985523380299, 0.32632861885644465],
- [0.7105456546582587, 0.36065500290840113, 0.32753574162788762],
- [0.71293466839773467, 0.36517570519856757, 0.3288027427038317],
- [0.71528760614847287, 0.36971170225223449, 0.3301308728723546],
- [0.71760444908133847, 0.37426272710686193, 0.33152138620958932],
- [0.71988521490549851, 0.37882848839337313, 0.33297555200245399],
- [0.7221299918421461, 0.38340864508963057, 0.33449469983585844],
- [0.72433865647781592, 0.38800301593162145, 0.33607995965691828],
- [0.72651122900227549, 0.3926113126792577, 0.3377325942005665],
- [0.72864773856716547, 0.39723324476747235, 0.33945384341064017],
- [0.73074820754845171, 0.401868526884681, 0.3412449533046818],
- [0.73281270506268747, 0.4065168468778026, 0.34310715173410822],
- [0.73484133598564938, 0.41117787004519513, 0.34504169470809071],
- [0.73683422173585866, 0.41585125850290111, 0.34704978520758401],
- [0.73879140024599266, 0.42053672992315327, 0.34913260148542435],
- [0.74071301619506091, 0.4252339389526239, 0.35129130890802607],
- [0.7425992159973317, 0.42994254036133867, 0.35352709245374592],
- [0.74445018676570673, 0.43466217184617112, 0.35584108091122535],
- [0.74626615789163442, 0.43939245044973502, 0.35823439142300639],
- [0.74804739275559562, 0.44413297780351974, 0.36070813602540136],
- [0.74979420547170472, 0.44888333481548809, 0.36326337558360278],
- [0.75150685045891663, 0.45364314496866825, 0.36590112443835765],
- [0.75318566369046569, 0.45841199172949604, 0.36862236642234769],
- [0.75483105066959544, 0.46318942799460555, 0.3714280448394211],
- [0.75644341577140706, 0.46797501437948458, 0.37431909037543515],
- [0.75802325538455839, 0.4727682731566229, 0.37729635531096678],
- [0.75957111105340058, 0.47756871222057079, 0.380360657784311],
- [0.7610876378057071, 0.48237579130289127, 0.38351275723852291],
- [0.76257333554052609, 0.48718906673415824, 0.38675335037837993],
- [0.76402885609288662, 0.49200802533379656, 0.39008308392311997],
- [0.76545492593330511, 0.49683212909727231, 0.39350254000115381],
- [0.76685228950643891, 0.5016608471009063, 0.39701221751773474],
- [0.76822176599735303, 0.50649362371287909, 0.40061257089416885],
- [0.7695642334401418, 0.5113298901696085, 0.40430398069682483],
- [0.77088091962302474, 0.51616892643469103, 0.40808667584648967],
- [0.77217257229605551, 0.5210102658711383, 0.41196089987122869],
- [0.77344021829889886, 0.52585332093451564, 0.41592679539764366],
- [0.77468494746063199, 0.53069749384776732, 0.41998440356963762],
- [0.77590790730685699, 0.53554217882461186, 0.42413367909988375],
- [0.7771103295521099, 0.54038674910561235, 0.42837450371258479],
- [0.77829345807633121, 0.54523059488426595, 0.432706647838971],
- [0.77945862731506643, 0.55007308413977274, 0.43712979856444761],
- [0.78060774749483774, 0.55491335744890613, 0.44164332426364639],
- [0.78174180478981836, 0.55975098052594863, 0.44624687186865436],
- [0.78286225264440912, 0.56458533111166875, 0.45093985823706345],
- [0.78397060836414478, 0.56941578326710418, 0.45572154742892063],
- [0.78506845019606841, 0.5742417003617839, 0.46059116206904965],
- [0.78615737132332963, 0.5790624629815756, 0.46554778281918402],
- [0.78723904108188347, 0.58387743744557208, 0.47059039582133383],
- [0.78831514045623963, 0.58868600173562435, 0.47571791879076081],
- [0.78938737766251943, 0.5934875421745599, 0.48092913815357724],
- [0.79045776847727878, 0.59828134277062461, 0.48622257801969754],
- [0.79152832843475607, 0.60306670593147205, 0.49159667021646397],
- [0.79260034304237448, 0.60784322087037024, 0.49705020621532009],
- [0.79367559698664958, 0.61261029334072192, 0.50258161291269432],
- [0.79475585972654039, 0.61736734400220705, 0.50818921213102985],
- [0.79584292379583765, 0.62211378808451145, 0.51387124091909786],
- [0.79693854719951607, 0.62684905679296699, 0.5196258425240281],
- [0.79804447815136637, 0.63157258225089552, 0.52545108144834785],
- [0.7991624518501963, 0.63628379372029187, 0.53134495942561433],
- [0.80029415389753977, 0.64098213306749863, 0.53730535185141037],
- [0.80144124292560048, 0.64566703459218766, 0.5433300863249918],
- [0.80260531146112946, 0.65033793748103852, 0.54941691584603647],
- [0.80378792531077625, 0.65499426549472628, 0.55556350867083815],
- [0.80499054790810298, 0.65963545027564163, 0.56176745110546977],
- [0.80621460526927058, 0.66426089585282289, 0.56802629178649788],
- [0.8074614045096935, 0.6688700095398864, 0.57433746373459582],
- [0.80873219170089694, 0.67346216702194517, 0.58069834805576737],
- [0.81002809466520687, 0.67803672673971815, 0.58710626908082753],
- [0.81135014011763329, 0.68259301546243389, 0.59355848909050757],
- [0.81269922039881493, 0.68713033714618876, 0.60005214820435104],
- [0.81407611046993344, 0.69164794791482131, 0.6065843782630862],
- [0.81548146627279483, 0.69614505508308089, 0.61315221209322646],
- [0.81691575775055891, 0.70062083014783982, 0.61975260637257923],
- [0.81837931164498223, 0.70507438189635097, 0.62638245478933297],
- [0.81987230650455289, 0.70950474978787481, 0.63303857040067113],
- [0.8213947205565636, 0.7139109141951604, 0.63971766697672761],
- [0.82294635110428427, 0.71829177331290062, 0.6464164243818421],
- [0.8245268129450285, 0.72264614312088882, 0.65313137915422603],
- [0.82613549710580259, 0.72697275518238258, 0.65985900156216504],
- [0.8277716072353446, 0.73127023324078089, 0.66659570204682972],
- [0.82943407816481474, 0.7355371221572935, 0.67333772009301907],
- [0.83112163529096306, 0.73977184647638616, 0.68008125203631464],
- [0.83283277185777982, 0.74397271817459876, 0.68682235874648545],
- [0.8345656905566583, 0.7481379479992134, 0.69355697649863846],
- [0.83631898844737929, 0.75226548952875261, 0.70027999028864962],
- [0.83809123476131964, 0.75635314860808633, 0.70698561390212977],
- [0.83987839884120874, 0.76039907199779677, 0.71367147811129228],
- [0.84167750766845151, 0.76440101200982946, 0.72033299387284622],
- [0.84348529222933699, 0.76835660399870176, 0.72696536998972039],
- [0.84529810731955113, 0.77226338601044719, 0.73356368240541492],
- [0.84711195507965098, 0.77611880236047159, 0.74012275762807056],
- [0.84892245563117641, 0.77992021407650147, 0.74663719293664366],
- [0.85072697023178789, 0.78366457342383888, 0.7530974636118285],
- [0.85251907207708444, 0.78734936133548439, 0.7594994148789691],
- [0.85429219611470464, 0.79097196777091994, 0.76583801477914104],
- [0.85604022314725403, 0.79452963601550608, 0.77210610037674143],
- [0.85775662943504905, 0.79801963142713928, 0.77829571667247499],
- [0.8594346370300241, 0.8014392309950078, 0.78439788751383921],
- [0.86107117027565516, 0.80478517909812231, 0.79039529663736285],
- [0.86265601051127572, 0.80805523804261525, 0.796282666437655],
- [0.86418343723941027, 0.81124644224653542, 0.80204612696863953],
- [0.86564934325605325, 0.81435544067514909, 0.80766972324164554],
- [0.86705314907048503, 0.81737804041911244, 0.81313419626911398],
- [0.86839954695818633, 0.82030875512181523, 0.81841638963128993],
- [0.86969131502613806, 0.82314158859569164, 0.82350476683173168],
- [0.87093846717297507, 0.82586857889438514, 0.82838497261149613],
- [0.87215331978454325, 0.82848052823709672, 0.8330486712880828],
- [0.87335171360916275, 0.83096715251272624, 0.83748851001197089],
- [0.87453793320260187, 0.83331972948645461, 0.84171925358069011],
- [0.87571458709961403, 0.8355302318472394, 0.84575537519027078],
- [0.87687848451614692, 0.83759238071186537, 0.84961373549150254],
- [0.87802298436649007, 0.83950165618540074, 0.85330645352458923],
- [0.87913244240792765, 0.84125554884475906, 0.85685572291039636],
- [0.88019293315695812, 0.84285224824778615, 0.86027399927156634],
- [0.88119169871341951, 0.84429066717717349, 0.86356595168669881],
- [0.88211542489401606, 0.84557007254559347, 0.86673765046233331],
- [0.88295168595448525, 0.84668970275699273, 0.86979617048190971],
- [0.88369127145898041, 0.84764891761519268, 0.87274147101441557],
- [0.88432713054113543, 0.84844741572055415, 0.87556785228242973],
- [0.88485138159908572, 0.84908426422893801, 0.87828235285372469],
- [0.88525897972630474, 0.84955892810989209, 0.88088414794024839],
- [0.88554714811952384, 0.84987174283631584, 0.88336206121170946],
- [0.88571155122845646, 0.85002186115856315, 0.88572538990087124]]
-
-_twilight_shifted_data = (_twilight_data[len(_twilight_data)//2:] +
- _twilight_data[:len(_twilight_data)//2])
-_twilight_shifted_data.reverse()
-_turbo_data = [[0.18995, 0.07176, 0.23217],
- [0.19483, 0.08339, 0.26149],
- [0.19956, 0.09498, 0.29024],
- [0.20415, 0.10652, 0.31844],
- [0.20860, 0.11802, 0.34607],
- [0.21291, 0.12947, 0.37314],
- [0.21708, 0.14087, 0.39964],
- [0.22111, 0.15223, 0.42558],
- [0.22500, 0.16354, 0.45096],
- [0.22875, 0.17481, 0.47578],
- [0.23236, 0.18603, 0.50004],
- [0.23582, 0.19720, 0.52373],
- [0.23915, 0.20833, 0.54686],
- [0.24234, 0.21941, 0.56942],
- [0.24539, 0.23044, 0.59142],
- [0.24830, 0.24143, 0.61286],
- [0.25107, 0.25237, 0.63374],
- [0.25369, 0.26327, 0.65406],
- [0.25618, 0.27412, 0.67381],
- [0.25853, 0.28492, 0.69300],
- [0.26074, 0.29568, 0.71162],
- [0.26280, 0.30639, 0.72968],
- [0.26473, 0.31706, 0.74718],
- [0.26652, 0.32768, 0.76412],
- [0.26816, 0.33825, 0.78050],
- [0.26967, 0.34878, 0.79631],
- [0.27103, 0.35926, 0.81156],
- [0.27226, 0.36970, 0.82624],
- [0.27334, 0.38008, 0.84037],
- [0.27429, 0.39043, 0.85393],
- [0.27509, 0.40072, 0.86692],
- [0.27576, 0.41097, 0.87936],
- [0.27628, 0.42118, 0.89123],
- [0.27667, 0.43134, 0.90254],
- [0.27691, 0.44145, 0.91328],
- [0.27701, 0.45152, 0.92347],
- [0.27698, 0.46153, 0.93309],
- [0.27680, 0.47151, 0.94214],
- [0.27648, 0.48144, 0.95064],
- [0.27603, 0.49132, 0.95857],
- [0.27543, 0.50115, 0.96594],
- [0.27469, 0.51094, 0.97275],
- [0.27381, 0.52069, 0.97899],
- [0.27273, 0.53040, 0.98461],
- [0.27106, 0.54015, 0.98930],
- [0.26878, 0.54995, 0.99303],
- [0.26592, 0.55979, 0.99583],
- [0.26252, 0.56967, 0.99773],
- [0.25862, 0.57958, 0.99876],
- [0.25425, 0.58950, 0.99896],
- [0.24946, 0.59943, 0.99835],
- [0.24427, 0.60937, 0.99697],
- [0.23874, 0.61931, 0.99485],
- [0.23288, 0.62923, 0.99202],
- [0.22676, 0.63913, 0.98851],
- [0.22039, 0.64901, 0.98436],
- [0.21382, 0.65886, 0.97959],
- [0.20708, 0.66866, 0.97423],
- [0.20021, 0.67842, 0.96833],
- [0.19326, 0.68812, 0.96190],
- [0.18625, 0.69775, 0.95498],
- [0.17923, 0.70732, 0.94761],
- [0.17223, 0.71680, 0.93981],
- [0.16529, 0.72620, 0.93161],
- [0.15844, 0.73551, 0.92305],
- [0.15173, 0.74472, 0.91416],
- [0.14519, 0.75381, 0.90496],
- [0.13886, 0.76279, 0.89550],
- [0.13278, 0.77165, 0.88580],
- [0.12698, 0.78037, 0.87590],
- [0.12151, 0.78896, 0.86581],
- [0.11639, 0.79740, 0.85559],
- [0.11167, 0.80569, 0.84525],
- [0.10738, 0.81381, 0.83484],
- [0.10357, 0.82177, 0.82437],
- [0.10026, 0.82955, 0.81389],
- [0.09750, 0.83714, 0.80342],
- [0.09532, 0.84455, 0.79299],
- [0.09377, 0.85175, 0.78264],
- [0.09287, 0.85875, 0.77240],
- [0.09267, 0.86554, 0.76230],
- [0.09320, 0.87211, 0.75237],
- [0.09451, 0.87844, 0.74265],
- [0.09662, 0.88454, 0.73316],
- [0.09958, 0.89040, 0.72393],
- [0.10342, 0.89600, 0.71500],
- [0.10815, 0.90142, 0.70599],
- [0.11374, 0.90673, 0.69651],
- [0.12014, 0.91193, 0.68660],
- [0.12733, 0.91701, 0.67627],
- [0.13526, 0.92197, 0.66556],
- [0.14391, 0.92680, 0.65448],
- [0.15323, 0.93151, 0.64308],
- [0.16319, 0.93609, 0.63137],
- [0.17377, 0.94053, 0.61938],
- [0.18491, 0.94484, 0.60713],
- [0.19659, 0.94901, 0.59466],
- [0.20877, 0.95304, 0.58199],
- [0.22142, 0.95692, 0.56914],
- [0.23449, 0.96065, 0.55614],
- [0.24797, 0.96423, 0.54303],
- [0.26180, 0.96765, 0.52981],
- [0.27597, 0.97092, 0.51653],
- [0.29042, 0.97403, 0.50321],
- [0.30513, 0.97697, 0.48987],
- [0.32006, 0.97974, 0.47654],
- [0.33517, 0.98234, 0.46325],
- [0.35043, 0.98477, 0.45002],
- [0.36581, 0.98702, 0.43688],
- [0.38127, 0.98909, 0.42386],
- [0.39678, 0.99098, 0.41098],
- [0.41229, 0.99268, 0.39826],
- [0.42778, 0.99419, 0.38575],
- [0.44321, 0.99551, 0.37345],
- [0.45854, 0.99663, 0.36140],
- [0.47375, 0.99755, 0.34963],
- [0.48879, 0.99828, 0.33816],
- [0.50362, 0.99879, 0.32701],
- [0.51822, 0.99910, 0.31622],
- [0.53255, 0.99919, 0.30581],
- [0.54658, 0.99907, 0.29581],
- [0.56026, 0.99873, 0.28623],
- [0.57357, 0.99817, 0.27712],
- [0.58646, 0.99739, 0.26849],
- [0.59891, 0.99638, 0.26038],
- [0.61088, 0.99514, 0.25280],
- [0.62233, 0.99366, 0.24579],
- [0.63323, 0.99195, 0.23937],
- [0.64362, 0.98999, 0.23356],
- [0.65394, 0.98775, 0.22835],
- [0.66428, 0.98524, 0.22370],
- [0.67462, 0.98246, 0.21960],
- [0.68494, 0.97941, 0.21602],
- [0.69525, 0.97610, 0.21294],
- [0.70553, 0.97255, 0.21032],
- [0.71577, 0.96875, 0.20815],
- [0.72596, 0.96470, 0.20640],
- [0.73610, 0.96043, 0.20504],
- [0.74617, 0.95593, 0.20406],
- [0.75617, 0.95121, 0.20343],
- [0.76608, 0.94627, 0.20311],
- [0.77591, 0.94113, 0.20310],
- [0.78563, 0.93579, 0.20336],
- [0.79524, 0.93025, 0.20386],
- [0.80473, 0.92452, 0.20459],
- [0.81410, 0.91861, 0.20552],
- [0.82333, 0.91253, 0.20663],
- [0.83241, 0.90627, 0.20788],
- [0.84133, 0.89986, 0.20926],
- [0.85010, 0.89328, 0.21074],
- [0.85868, 0.88655, 0.21230],
- [0.86709, 0.87968, 0.21391],
- [0.87530, 0.87267, 0.21555],
- [0.88331, 0.86553, 0.21719],
- [0.89112, 0.85826, 0.21880],
- [0.89870, 0.85087, 0.22038],
- [0.90605, 0.84337, 0.22188],
- [0.91317, 0.83576, 0.22328],
- [0.92004, 0.82806, 0.22456],
- [0.92666, 0.82025, 0.22570],
- [0.93301, 0.81236, 0.22667],
- [0.93909, 0.80439, 0.22744],
- [0.94489, 0.79634, 0.22800],
- [0.95039, 0.78823, 0.22831],
- [0.95560, 0.78005, 0.22836],
- [0.96049, 0.77181, 0.22811],
- [0.96507, 0.76352, 0.22754],
- [0.96931, 0.75519, 0.22663],
- [0.97323, 0.74682, 0.22536],
- [0.97679, 0.73842, 0.22369],
- [0.98000, 0.73000, 0.22161],
- [0.98289, 0.72140, 0.21918],
- [0.98549, 0.71250, 0.21650],
- [0.98781, 0.70330, 0.21358],
- [0.98986, 0.69382, 0.21043],
- [0.99163, 0.68408, 0.20706],
- [0.99314, 0.67408, 0.20348],
- [0.99438, 0.66386, 0.19971],
- [0.99535, 0.65341, 0.19577],
- [0.99607, 0.64277, 0.19165],
- [0.99654, 0.63193, 0.18738],
- [0.99675, 0.62093, 0.18297],
- [0.99672, 0.60977, 0.17842],
- [0.99644, 0.59846, 0.17376],
- [0.99593, 0.58703, 0.16899],
- [0.99517, 0.57549, 0.16412],
- [0.99419, 0.56386, 0.15918],
- [0.99297, 0.55214, 0.15417],
- [0.99153, 0.54036, 0.14910],
- [0.98987, 0.52854, 0.14398],
- [0.98799, 0.51667, 0.13883],
- [0.98590, 0.50479, 0.13367],
- [0.98360, 0.49291, 0.12849],
- [0.98108, 0.48104, 0.12332],
- [0.97837, 0.46920, 0.11817],
- [0.97545, 0.45740, 0.11305],
- [0.97234, 0.44565, 0.10797],
- [0.96904, 0.43399, 0.10294],
- [0.96555, 0.42241, 0.09798],
- [0.96187, 0.41093, 0.09310],
- [0.95801, 0.39958, 0.08831],
- [0.95398, 0.38836, 0.08362],
- [0.94977, 0.37729, 0.07905],
- [0.94538, 0.36638, 0.07461],
- [0.94084, 0.35566, 0.07031],
- [0.93612, 0.34513, 0.06616],
- [0.93125, 0.33482, 0.06218],
- [0.92623, 0.32473, 0.05837],
- [0.92105, 0.31489, 0.05475],
- [0.91572, 0.30530, 0.05134],
- [0.91024, 0.29599, 0.04814],
- [0.90463, 0.28696, 0.04516],
- [0.89888, 0.27824, 0.04243],
- [0.89298, 0.26981, 0.03993],
- [0.88691, 0.26152, 0.03753],
- [0.88066, 0.25334, 0.03521],
- [0.87422, 0.24526, 0.03297],
- [0.86760, 0.23730, 0.03082],
- [0.86079, 0.22945, 0.02875],
- [0.85380, 0.22170, 0.02677],
- [0.84662, 0.21407, 0.02487],
- [0.83926, 0.20654, 0.02305],
- [0.83172, 0.19912, 0.02131],
- [0.82399, 0.19182, 0.01966],
- [0.81608, 0.18462, 0.01809],
- [0.80799, 0.17753, 0.01660],
- [0.79971, 0.17055, 0.01520],
- [0.79125, 0.16368, 0.01387],
- [0.78260, 0.15693, 0.01264],
- [0.77377, 0.15028, 0.01148],
- [0.76476, 0.14374, 0.01041],
- [0.75556, 0.13731, 0.00942],
- [0.74617, 0.13098, 0.00851],
- [0.73661, 0.12477, 0.00769],
- [0.72686, 0.11867, 0.00695],
- [0.71692, 0.11268, 0.00629],
- [0.70680, 0.10680, 0.00571],
- [0.69650, 0.10102, 0.00522],
- [0.68602, 0.09536, 0.00481],
- [0.67535, 0.08980, 0.00449],
- [0.66449, 0.08436, 0.00424],
- [0.65345, 0.07902, 0.00408],
- [0.64223, 0.07380, 0.00401],
- [0.63082, 0.06868, 0.00401],
- [0.61923, 0.06367, 0.00410],
- [0.60746, 0.05878, 0.00427],
- [0.59550, 0.05399, 0.00453],
- [0.58336, 0.04931, 0.00486],
- [0.57103, 0.04474, 0.00529],
- [0.55852, 0.04028, 0.00579],
- [0.54583, 0.03593, 0.00638],
- [0.53295, 0.03169, 0.00705],
- [0.51989, 0.02756, 0.00780],
- [0.50664, 0.02354, 0.00863],
- [0.49321, 0.01963, 0.00955],
- [0.47960, 0.01583, 0.01055]]
-
-
-cmaps = {
- name: ListedColormap(data, name=name) for name, data in [
- ('magma', _magma_data),
- ('inferno', _inferno_data),
- ('plasma', _plasma_data),
- ('viridis', _viridis_data),
- ('cividis', _cividis_data),
- ('twilight', _twilight_data),
- ('twilight_shifted', _twilight_shifted_data),
- ('turbo', _turbo_data),
- ]}
diff --git a/contrib/python/matplotlib/py3/matplotlib/_color_data.py b/contrib/python/matplotlib/py3/matplotlib/_color_data.py
deleted file mode 100644
index 44f97adbb7..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_color_data.py
+++ /dev/null
@@ -1,1141 +0,0 @@
-BASE_COLORS = {
- 'b': (0, 0, 1), # blue
- 'g': (0, 0.5, 0), # green
- 'r': (1, 0, 0), # red
- 'c': (0, 0.75, 0.75), # cyan
- 'm': (0.75, 0, 0.75), # magenta
- 'y': (0.75, 0.75, 0), # yellow
- 'k': (0, 0, 0), # black
- 'w': (1, 1, 1), # white
-}
-
-
-# These colors are from Tableau
-TABLEAU_COLORS = {
- 'tab:blue': '#1f77b4',
- 'tab:orange': '#ff7f0e',
- 'tab:green': '#2ca02c',
- 'tab:red': '#d62728',
- 'tab:purple': '#9467bd',
- 'tab:brown': '#8c564b',
- 'tab:pink': '#e377c2',
- 'tab:gray': '#7f7f7f',
- 'tab:olive': '#bcbd22',
- 'tab:cyan': '#17becf',
-}
-
-
-# This mapping of color names -> hex values is taken from
-# a survey run by Randall Munroe see:
-# https://blog.xkcd.com/2010/05/03/color-survey-results/
-# for more details. The results are hosted at
-# https://xkcd.com/color/rgb/
-# and also available as a text file at
-# https://xkcd.com/color/rgb.txt
-#
-# License: https://creativecommons.org/publicdomain/zero/1.0/
-XKCD_COLORS = {
- 'cloudy blue': '#acc2d9',
- 'dark pastel green': '#56ae57',
- 'dust': '#b2996e',
- 'electric lime': '#a8ff04',
- 'fresh green': '#69d84f',
- 'light eggplant': '#894585',
- 'nasty green': '#70b23f',
- 'really light blue': '#d4ffff',
- 'tea': '#65ab7c',
- 'warm purple': '#952e8f',
- 'yellowish tan': '#fcfc81',
- 'cement': '#a5a391',
- 'dark grass green': '#388004',
- 'dusty teal': '#4c9085',
- 'grey teal': '#5e9b8a',
- 'macaroni and cheese': '#efb435',
- 'pinkish tan': '#d99b82',
- 'spruce': '#0a5f38',
- 'strong blue': '#0c06f7',
- 'toxic green': '#61de2a',
- 'windows blue': '#3778bf',
- 'blue blue': '#2242c7',
- 'blue with a hint of purple': '#533cc6',
- 'booger': '#9bb53c',
- 'bright sea green': '#05ffa6',
- 'dark green blue': '#1f6357',
- 'deep turquoise': '#017374',
- 'green teal': '#0cb577',
- 'strong pink': '#ff0789',
- 'bland': '#afa88b',
- 'deep aqua': '#08787f',
- 'lavender pink': '#dd85d7',
- 'light moss green': '#a6c875',
- 'light seafoam green': '#a7ffb5',
- 'olive yellow': '#c2b709',
- 'pig pink': '#e78ea5',
- 'deep lilac': '#966ebd',
- 'desert': '#ccad60',
- 'dusty lavender': '#ac86a8',
- 'purpley grey': '#947e94',
- 'purply': '#983fb2',
- 'candy pink': '#ff63e9',
- 'light pastel green': '#b2fba5',
- 'boring green': '#63b365',
- 'kiwi green': '#8ee53f',
- 'light grey green': '#b7e1a1',
- 'orange pink': '#ff6f52',
- 'tea green': '#bdf8a3',
- 'very light brown': '#d3b683',
- 'egg shell': '#fffcc4',
- 'eggplant purple': '#430541',
- 'powder pink': '#ffb2d0',
- 'reddish grey': '#997570',
- 'baby shit brown': '#ad900d',
- 'liliac': '#c48efd',
- 'stormy blue': '#507b9c',
- 'ugly brown': '#7d7103',
- 'custard': '#fffd78',
- 'darkish pink': '#da467d',
- 'deep brown': '#410200',
- 'greenish beige': '#c9d179',
- 'manilla': '#fffa86',
- 'off blue': '#5684ae',
- 'battleship grey': '#6b7c85',
- 'browny green': '#6f6c0a',
- 'bruise': '#7e4071',
- 'kelley green': '#009337',
- 'sickly yellow': '#d0e429',
- 'sunny yellow': '#fff917',
- 'azul': '#1d5dec',
- 'darkgreen': '#054907',
- 'green/yellow': '#b5ce08',
- 'lichen': '#8fb67b',
- 'light light green': '#c8ffb0',
- 'pale gold': '#fdde6c',
- 'sun yellow': '#ffdf22',
- 'tan green': '#a9be70',
- 'burple': '#6832e3',
- 'butterscotch': '#fdb147',
- 'toupe': '#c7ac7d',
- 'dark cream': '#fff39a',
- 'indian red': '#850e04',
- 'light lavendar': '#efc0fe',
- 'poison green': '#40fd14',
- 'baby puke green': '#b6c406',
- 'bright yellow green': '#9dff00',
- 'charcoal grey': '#3c4142',
- 'squash': '#f2ab15',
- 'cinnamon': '#ac4f06',
- 'light pea green': '#c4fe82',
- 'radioactive green': '#2cfa1f',
- 'raw sienna': '#9a6200',
- 'baby purple': '#ca9bf7',
- 'cocoa': '#875f42',
- 'light royal blue': '#3a2efe',
- 'orangeish': '#fd8d49',
- 'rust brown': '#8b3103',
- 'sand brown': '#cba560',
- 'swamp': '#698339',
- 'tealish green': '#0cdc73',
- 'burnt siena': '#b75203',
- 'camo': '#7f8f4e',
- 'dusk blue': '#26538d',
- 'fern': '#63a950',
- 'old rose': '#c87f89',
- 'pale light green': '#b1fc99',
- 'peachy pink': '#ff9a8a',
- 'rosy pink': '#f6688e',
- 'light bluish green': '#76fda8',
- 'light bright green': '#53fe5c',
- 'light neon green': '#4efd54',
- 'light seafoam': '#a0febf',
- 'tiffany blue': '#7bf2da',
- 'washed out green': '#bcf5a6',
- 'browny orange': '#ca6b02',
- 'nice blue': '#107ab0',
- 'sapphire': '#2138ab',
- 'greyish teal': '#719f91',
- 'orangey yellow': '#fdb915',
- 'parchment': '#fefcaf',
- 'straw': '#fcf679',
- 'very dark brown': '#1d0200',
- 'terracota': '#cb6843',
- 'ugly blue': '#31668a',
- 'clear blue': '#247afd',
- 'creme': '#ffffb6',
- 'foam green': '#90fda9',
- 'grey/green': '#86a17d',
- 'light gold': '#fddc5c',
- 'seafoam blue': '#78d1b6',
- 'topaz': '#13bbaf',
- 'violet pink': '#fb5ffc',
- 'wintergreen': '#20f986',
- 'yellow tan': '#ffe36e',
- 'dark fuchsia': '#9d0759',
- 'indigo blue': '#3a18b1',
- 'light yellowish green': '#c2ff89',
- 'pale magenta': '#d767ad',
- 'rich purple': '#720058',
- 'sunflower yellow': '#ffda03',
- 'green/blue': '#01c08d',
- 'leather': '#ac7434',
- 'racing green': '#014600',
- 'vivid purple': '#9900fa',
- 'dark royal blue': '#02066f',
- 'hazel': '#8e7618',
- 'muted pink': '#d1768f',
- 'booger green': '#96b403',
- 'canary': '#fdff63',
- 'cool grey': '#95a3a6',
- 'dark taupe': '#7f684e',
- 'darkish purple': '#751973',
- 'true green': '#089404',
- 'coral pink': '#ff6163',
- 'dark sage': '#598556',
- 'dark slate blue': '#214761',
- 'flat blue': '#3c73a8',
- 'mushroom': '#ba9e88',
- 'rich blue': '#021bf9',
- 'dirty purple': '#734a65',
- 'greenblue': '#23c48b',
- 'icky green': '#8fae22',
- 'light khaki': '#e6f2a2',
- 'warm blue': '#4b57db',
- 'dark hot pink': '#d90166',
- 'deep sea blue': '#015482',
- 'carmine': '#9d0216',
- 'dark yellow green': '#728f02',
- 'pale peach': '#ffe5ad',
- 'plum purple': '#4e0550',
- 'golden rod': '#f9bc08',
- 'neon red': '#ff073a',
- 'old pink': '#c77986',
- 'very pale blue': '#d6fffe',
- 'blood orange': '#fe4b03',
- 'grapefruit': '#fd5956',
- 'sand yellow': '#fce166',
- 'clay brown': '#b2713d',
- 'dark blue grey': '#1f3b4d',
- 'flat green': '#699d4c',
- 'light green blue': '#56fca2',
- 'warm pink': '#fb5581',
- 'dodger blue': '#3e82fc',
- 'gross green': '#a0bf16',
- 'ice': '#d6fffa',
- 'metallic blue': '#4f738e',
- 'pale salmon': '#ffb19a',
- 'sap green': '#5c8b15',
- 'algae': '#54ac68',
- 'bluey grey': '#89a0b0',
- 'greeny grey': '#7ea07a',
- 'highlighter green': '#1bfc06',
- 'light light blue': '#cafffb',
- 'light mint': '#b6ffbb',
- 'raw umber': '#a75e09',
- 'vivid blue': '#152eff',
- 'deep lavender': '#8d5eb7',
- 'dull teal': '#5f9e8f',
- 'light greenish blue': '#63f7b4',
- 'mud green': '#606602',
- 'pinky': '#fc86aa',
- 'red wine': '#8c0034',
- 'shit green': '#758000',
- 'tan brown': '#ab7e4c',
- 'darkblue': '#030764',
- 'rosa': '#fe86a4',
- 'lipstick': '#d5174e',
- 'pale mauve': '#fed0fc',
- 'claret': '#680018',
- 'dandelion': '#fedf08',
- 'orangered': '#fe420f',
- 'poop green': '#6f7c00',
- 'ruby': '#ca0147',
- 'dark': '#1b2431',
- 'greenish turquoise': '#00fbb0',
- 'pastel red': '#db5856',
- 'piss yellow': '#ddd618',
- 'bright cyan': '#41fdfe',
- 'dark coral': '#cf524e',
- 'algae green': '#21c36f',
- 'darkish red': '#a90308',
- 'reddy brown': '#6e1005',
- 'blush pink': '#fe828c',
- 'camouflage green': '#4b6113',
- 'lawn green': '#4da409',
- 'putty': '#beae8a',
- 'vibrant blue': '#0339f8',
- 'dark sand': '#a88f59',
- 'purple/blue': '#5d21d0',
- 'saffron': '#feb209',
- 'twilight': '#4e518b',
- 'warm brown': '#964e02',
- 'bluegrey': '#85a3b2',
- 'bubble gum pink': '#ff69af',
- 'duck egg blue': '#c3fbf4',
- 'greenish cyan': '#2afeb7',
- 'petrol': '#005f6a',
- 'royal': '#0c1793',
- 'butter': '#ffff81',
- 'dusty orange': '#f0833a',
- 'off yellow': '#f1f33f',
- 'pale olive green': '#b1d27b',
- 'orangish': '#fc824a',
- 'leaf': '#71aa34',
- 'light blue grey': '#b7c9e2',
- 'dried blood': '#4b0101',
- 'lightish purple': '#a552e6',
- 'rusty red': '#af2f0d',
- 'lavender blue': '#8b88f8',
- 'light grass green': '#9af764',
- 'light mint green': '#a6fbb2',
- 'sunflower': '#ffc512',
- 'velvet': '#750851',
- 'brick orange': '#c14a09',
- 'lightish red': '#fe2f4a',
- 'pure blue': '#0203e2',
- 'twilight blue': '#0a437a',
- 'violet red': '#a50055',
- 'yellowy brown': '#ae8b0c',
- 'carnation': '#fd798f',
- 'muddy yellow': '#bfac05',
- 'dark seafoam green': '#3eaf76',
- 'deep rose': '#c74767',
- 'dusty red': '#b9484e',
- 'grey/blue': '#647d8e',
- 'lemon lime': '#bffe28',
- 'purple/pink': '#d725de',
- 'brown yellow': '#b29705',
- 'purple brown': '#673a3f',
- 'wisteria': '#a87dc2',
- 'banana yellow': '#fafe4b',
- 'lipstick red': '#c0022f',
- 'water blue': '#0e87cc',
- 'brown grey': '#8d8468',
- 'vibrant purple': '#ad03de',
- 'baby green': '#8cff9e',
- 'barf green': '#94ac02',
- 'eggshell blue': '#c4fff7',
- 'sandy yellow': '#fdee73',
- 'cool green': '#33b864',
- 'pale': '#fff9d0',
- 'blue/grey': '#758da3',
- 'hot magenta': '#f504c9',
- 'greyblue': '#77a1b5',
- 'purpley': '#8756e4',
- 'baby shit green': '#889717',
- 'brownish pink': '#c27e79',
- 'dark aquamarine': '#017371',
- 'diarrhea': '#9f8303',
- 'light mustard': '#f7d560',
- 'pale sky blue': '#bdf6fe',
- 'turtle green': '#75b84f',
- 'bright olive': '#9cbb04',
- 'dark grey blue': '#29465b',
- 'greeny brown': '#696006',
- 'lemon green': '#adf802',
- 'light periwinkle': '#c1c6fc',
- 'seaweed green': '#35ad6b',
- 'sunshine yellow': '#fffd37',
- 'ugly purple': '#a442a0',
- 'medium pink': '#f36196',
- 'puke brown': '#947706',
- 'very light pink': '#fff4f2',
- 'viridian': '#1e9167',
- 'bile': '#b5c306',
- 'faded yellow': '#feff7f',
- 'very pale green': '#cffdbc',
- 'vibrant green': '#0add08',
- 'bright lime': '#87fd05',
- 'spearmint': '#1ef876',
- 'light aquamarine': '#7bfdc7',
- 'light sage': '#bcecac',
- 'yellowgreen': '#bbf90f',
- 'baby poo': '#ab9004',
- 'dark seafoam': '#1fb57a',
- 'deep teal': '#00555a',
- 'heather': '#a484ac',
- 'rust orange': '#c45508',
- 'dirty blue': '#3f829d',
- 'fern green': '#548d44',
- 'bright lilac': '#c95efb',
- 'weird green': '#3ae57f',
- 'peacock blue': '#016795',
- 'avocado green': '#87a922',
- 'faded orange': '#f0944d',
- 'grape purple': '#5d1451',
- 'hot green': '#25ff29',
- 'lime yellow': '#d0fe1d',
- 'mango': '#ffa62b',
- 'shamrock': '#01b44c',
- 'bubblegum': '#ff6cb5',
- 'purplish brown': '#6b4247',
- 'vomit yellow': '#c7c10c',
- 'pale cyan': '#b7fffa',
- 'key lime': '#aeff6e',
- 'tomato red': '#ec2d01',
- 'lightgreen': '#76ff7b',
- 'merlot': '#730039',
- 'night blue': '#040348',
- 'purpleish pink': '#df4ec8',
- 'apple': '#6ecb3c',
- 'baby poop green': '#8f9805',
- 'green apple': '#5edc1f',
- 'heliotrope': '#d94ff5',
- 'yellow/green': '#c8fd3d',
- 'almost black': '#070d0d',
- 'cool blue': '#4984b8',
- 'leafy green': '#51b73b',
- 'mustard brown': '#ac7e04',
- 'dusk': '#4e5481',
- 'dull brown': '#876e4b',
- 'frog green': '#58bc08',
- 'vivid green': '#2fef10',
- 'bright light green': '#2dfe54',
- 'fluro green': '#0aff02',
- 'kiwi': '#9cef43',
- 'seaweed': '#18d17b',
- 'navy green': '#35530a',
- 'ultramarine blue': '#1805db',
- 'iris': '#6258c4',
- 'pastel orange': '#ff964f',
- 'yellowish orange': '#ffab0f',
- 'perrywinkle': '#8f8ce7',
- 'tealish': '#24bca8',
- 'dark plum': '#3f012c',
- 'pear': '#cbf85f',
- 'pinkish orange': '#ff724c',
- 'midnight purple': '#280137',
- 'light urple': '#b36ff6',
- 'dark mint': '#48c072',
- 'greenish tan': '#bccb7a',
- 'light burgundy': '#a8415b',
- 'turquoise blue': '#06b1c4',
- 'ugly pink': '#cd7584',
- 'sandy': '#f1da7a',
- 'electric pink': '#ff0490',
- 'muted purple': '#805b87',
- 'mid green': '#50a747',
- 'greyish': '#a8a495',
- 'neon yellow': '#cfff04',
- 'banana': '#ffff7e',
- 'carnation pink': '#ff7fa7',
- 'tomato': '#ef4026',
- 'sea': '#3c9992',
- 'muddy brown': '#886806',
- 'turquoise green': '#04f489',
- 'buff': '#fef69e',
- 'fawn': '#cfaf7b',
- 'muted blue': '#3b719f',
- 'pale rose': '#fdc1c5',
- 'dark mint green': '#20c073',
- 'amethyst': '#9b5fc0',
- 'blue/green': '#0f9b8e',
- 'chestnut': '#742802',
- 'sick green': '#9db92c',
- 'pea': '#a4bf20',
- 'rusty orange': '#cd5909',
- 'stone': '#ada587',
- 'rose red': '#be013c',
- 'pale aqua': '#b8ffeb',
- 'deep orange': '#dc4d01',
- 'earth': '#a2653e',
- 'mossy green': '#638b27',
- 'grassy green': '#419c03',
- 'pale lime green': '#b1ff65',
- 'light grey blue': '#9dbcd4',
- 'pale grey': '#fdfdfe',
- 'asparagus': '#77ab56',
- 'blueberry': '#464196',
- 'purple red': '#990147',
- 'pale lime': '#befd73',
- 'greenish teal': '#32bf84',
- 'caramel': '#af6f09',
- 'deep magenta': '#a0025c',
- 'light peach': '#ffd8b1',
- 'milk chocolate': '#7f4e1e',
- 'ocher': '#bf9b0c',
- 'off green': '#6ba353',
- 'purply pink': '#f075e6',
- 'lightblue': '#7bc8f6',
- 'dusky blue': '#475f94',
- 'golden': '#f5bf03',
- 'light beige': '#fffeb6',
- 'butter yellow': '#fffd74',
- 'dusky purple': '#895b7b',
- 'french blue': '#436bad',
- 'ugly yellow': '#d0c101',
- 'greeny yellow': '#c6f808',
- 'orangish red': '#f43605',
- 'shamrock green': '#02c14d',
- 'orangish brown': '#b25f03',
- 'tree green': '#2a7e19',
- 'deep violet': '#490648',
- 'gunmetal': '#536267',
- 'blue/purple': '#5a06ef',
- 'cherry': '#cf0234',
- 'sandy brown': '#c4a661',
- 'warm grey': '#978a84',
- 'dark indigo': '#1f0954',
- 'midnight': '#03012d',
- 'bluey green': '#2bb179',
- 'grey pink': '#c3909b',
- 'soft purple': '#a66fb5',
- 'blood': '#770001',
- 'brown red': '#922b05',
- 'medium grey': '#7d7f7c',
- 'berry': '#990f4b',
- 'poo': '#8f7303',
- 'purpley pink': '#c83cb9',
- 'light salmon': '#fea993',
- 'snot': '#acbb0d',
- 'easter purple': '#c071fe',
- 'light yellow green': '#ccfd7f',
- 'dark navy blue': '#00022e',
- 'drab': '#828344',
- 'light rose': '#ffc5cb',
- 'rouge': '#ab1239',
- 'purplish red': '#b0054b',
- 'slime green': '#99cc04',
- 'baby poop': '#937c00',
- 'irish green': '#019529',
- 'pink/purple': '#ef1de7',
- 'dark navy': '#000435',
- 'greeny blue': '#42b395',
- 'light plum': '#9d5783',
- 'pinkish grey': '#c8aca9',
- 'dirty orange': '#c87606',
- 'rust red': '#aa2704',
- 'pale lilac': '#e4cbff',
- 'orangey red': '#fa4224',
- 'primary blue': '#0804f9',
- 'kermit green': '#5cb200',
- 'brownish purple': '#76424e',
- 'murky green': '#6c7a0e',
- 'wheat': '#fbdd7e',
- 'very dark purple': '#2a0134',
- 'bottle green': '#044a05',
- 'watermelon': '#fd4659',
- 'deep sky blue': '#0d75f8',
- 'fire engine red': '#fe0002',
- 'yellow ochre': '#cb9d06',
- 'pumpkin orange': '#fb7d07',
- 'pale olive': '#b9cc81',
- 'light lilac': '#edc8ff',
- 'lightish green': '#61e160',
- 'carolina blue': '#8ab8fe',
- 'mulberry': '#920a4e',
- 'shocking pink': '#fe02a2',
- 'auburn': '#9a3001',
- 'bright lime green': '#65fe08',
- 'celadon': '#befdb7',
- 'pinkish brown': '#b17261',
- 'poo brown': '#885f01',
- 'bright sky blue': '#02ccfe',
- 'celery': '#c1fd95',
- 'dirt brown': '#836539',
- 'strawberry': '#fb2943',
- 'dark lime': '#84b701',
- 'copper': '#b66325',
- 'medium brown': '#7f5112',
- 'muted green': '#5fa052',
- "robin's egg": '#6dedfd',
- 'bright aqua': '#0bf9ea',
- 'bright lavender': '#c760ff',
- 'ivory': '#ffffcb',
- 'very light purple': '#f6cefc',
- 'light navy': '#155084',
- 'pink red': '#f5054f',
- 'olive brown': '#645403',
- 'poop brown': '#7a5901',
- 'mustard green': '#a8b504',
- 'ocean green': '#3d9973',
- 'very dark blue': '#000133',
- 'dusty green': '#76a973',
- 'light navy blue': '#2e5a88',
- 'minty green': '#0bf77d',
- 'adobe': '#bd6c48',
- 'barney': '#ac1db8',
- 'jade green': '#2baf6a',
- 'bright light blue': '#26f7fd',
- 'light lime': '#aefd6c',
- 'dark khaki': '#9b8f55',
- 'orange yellow': '#ffad01',
- 'ocre': '#c69c04',
- 'maize': '#f4d054',
- 'faded pink': '#de9dac',
- 'british racing green': '#05480d',
- 'sandstone': '#c9ae74',
- 'mud brown': '#60460f',
- 'light sea green': '#98f6b0',
- 'robin egg blue': '#8af1fe',
- 'aqua marine': '#2ee8bb',
- 'dark sea green': '#11875d',
- 'soft pink': '#fdb0c0',
- 'orangey brown': '#b16002',
- 'cherry red': '#f7022a',
- 'burnt yellow': '#d5ab09',
- 'brownish grey': '#86775f',
- 'camel': '#c69f59',
- 'purplish grey': '#7a687f',
- 'marine': '#042e60',
- 'greyish pink': '#c88d94',
- 'pale turquoise': '#a5fbd5',
- 'pastel yellow': '#fffe71',
- 'bluey purple': '#6241c7',
- 'canary yellow': '#fffe40',
- 'faded red': '#d3494e',
- 'sepia': '#985e2b',
- 'coffee': '#a6814c',
- 'bright magenta': '#ff08e8',
- 'mocha': '#9d7651',
- 'ecru': '#feffca',
- 'purpleish': '#98568d',
- 'cranberry': '#9e003a',
- 'darkish green': '#287c37',
- 'brown orange': '#b96902',
- 'dusky rose': '#ba6873',
- 'melon': '#ff7855',
- 'sickly green': '#94b21c',
- 'silver': '#c5c9c7',
- 'purply blue': '#661aee',
- 'purpleish blue': '#6140ef',
- 'hospital green': '#9be5aa',
- 'shit brown': '#7b5804',
- 'mid blue': '#276ab3',
- 'amber': '#feb308',
- 'easter green': '#8cfd7e',
- 'soft blue': '#6488ea',
- 'cerulean blue': '#056eee',
- 'golden brown': '#b27a01',
- 'bright turquoise': '#0ffef9',
- 'red pink': '#fa2a55',
- 'red purple': '#820747',
- 'greyish brown': '#7a6a4f',
- 'vermillion': '#f4320c',
- 'russet': '#a13905',
- 'steel grey': '#6f828a',
- 'lighter purple': '#a55af4',
- 'bright violet': '#ad0afd',
- 'prussian blue': '#004577',
- 'slate green': '#658d6d',
- 'dirty pink': '#ca7b80',
- 'dark blue green': '#005249',
- 'pine': '#2b5d34',
- 'yellowy green': '#bff128',
- 'dark gold': '#b59410',
- 'bluish': '#2976bb',
- 'darkish blue': '#014182',
- 'dull red': '#bb3f3f',
- 'pinky red': '#fc2647',
- 'bronze': '#a87900',
- 'pale teal': '#82cbb2',
- 'military green': '#667c3e',
- 'barbie pink': '#fe46a5',
- 'bubblegum pink': '#fe83cc',
- 'pea soup green': '#94a617',
- 'dark mustard': '#a88905',
- 'shit': '#7f5f00',
- 'medium purple': '#9e43a2',
- 'very dark green': '#062e03',
- 'dirt': '#8a6e45',
- 'dusky pink': '#cc7a8b',
- 'red violet': '#9e0168',
- 'lemon yellow': '#fdff38',
- 'pistachio': '#c0fa8b',
- 'dull yellow': '#eedc5b',
- 'dark lime green': '#7ebd01',
- 'denim blue': '#3b5b92',
- 'teal blue': '#01889f',
- 'lightish blue': '#3d7afd',
- 'purpley blue': '#5f34e7',
- 'light indigo': '#6d5acf',
- 'swamp green': '#748500',
- 'brown green': '#706c11',
- 'dark maroon': '#3c0008',
- 'hot purple': '#cb00f5',
- 'dark forest green': '#002d04',
- 'faded blue': '#658cbb',
- 'drab green': '#749551',
- 'light lime green': '#b9ff66',
- 'snot green': '#9dc100',
- 'yellowish': '#faee66',
- 'light blue green': '#7efbb3',
- 'bordeaux': '#7b002c',
- 'light mauve': '#c292a1',
- 'ocean': '#017b92',
- 'marigold': '#fcc006',
- 'muddy green': '#657432',
- 'dull orange': '#d8863b',
- 'steel': '#738595',
- 'electric purple': '#aa23ff',
- 'fluorescent green': '#08ff08',
- 'yellowish brown': '#9b7a01',
- 'blush': '#f29e8e',
- 'soft green': '#6fc276',
- 'bright orange': '#ff5b00',
- 'lemon': '#fdff52',
- 'purple grey': '#866f85',
- 'acid green': '#8ffe09',
- 'pale lavender': '#eecffe',
- 'violet blue': '#510ac9',
- 'light forest green': '#4f9153',
- 'burnt red': '#9f2305',
- 'khaki green': '#728639',
- 'cerise': '#de0c62',
- 'faded purple': '#916e99',
- 'apricot': '#ffb16d',
- 'dark olive green': '#3c4d03',
- 'grey brown': '#7f7053',
- 'green grey': '#77926f',
- 'true blue': '#010fcc',
- 'pale violet': '#ceaefa',
- 'periwinkle blue': '#8f99fb',
- 'light sky blue': '#c6fcff',
- 'blurple': '#5539cc',
- 'green brown': '#544e03',
- 'bluegreen': '#017a79',
- 'bright teal': '#01f9c6',
- 'brownish yellow': '#c9b003',
- 'pea soup': '#929901',
- 'forest': '#0b5509',
- 'barney purple': '#a00498',
- 'ultramarine': '#2000b1',
- 'purplish': '#94568c',
- 'puke yellow': '#c2be0e',
- 'bluish grey': '#748b97',
- 'dark periwinkle': '#665fd1',
- 'dark lilac': '#9c6da5',
- 'reddish': '#c44240',
- 'light maroon': '#a24857',
- 'dusty purple': '#825f87',
- 'terra cotta': '#c9643b',
- 'avocado': '#90b134',
- 'marine blue': '#01386a',
- 'teal green': '#25a36f',
- 'slate grey': '#59656d',
- 'lighter green': '#75fd63',
- 'electric green': '#21fc0d',
- 'dusty blue': '#5a86ad',
- 'golden yellow': '#fec615',
- 'bright yellow': '#fffd01',
- 'light lavender': '#dfc5fe',
- 'umber': '#b26400',
- 'poop': '#7f5e00',
- 'dark peach': '#de7e5d',
- 'jungle green': '#048243',
- 'eggshell': '#ffffd4',
- 'denim': '#3b638c',
- 'yellow brown': '#b79400',
- 'dull purple': '#84597e',
- 'chocolate brown': '#411900',
- 'wine red': '#7b0323',
- 'neon blue': '#04d9ff',
- 'dirty green': '#667e2c',
- 'light tan': '#fbeeac',
- 'ice blue': '#d7fffe',
- 'cadet blue': '#4e7496',
- 'dark mauve': '#874c62',
- 'very light blue': '#d5ffff',
- 'grey purple': '#826d8c',
- 'pastel pink': '#ffbacd',
- 'very light green': '#d1ffbd',
- 'dark sky blue': '#448ee4',
- 'evergreen': '#05472a',
- 'dull pink': '#d5869d',
- 'aubergine': '#3d0734',
- 'mahogany': '#4a0100',
- 'reddish orange': '#f8481c',
- 'deep green': '#02590f',
- 'vomit green': '#89a203',
- 'purple pink': '#e03fd8',
- 'dusty pink': '#d58a94',
- 'faded green': '#7bb274',
- 'camo green': '#526525',
- 'pinky purple': '#c94cbe',
- 'pink purple': '#db4bda',
- 'brownish red': '#9e3623',
- 'dark rose': '#b5485d',
- 'mud': '#735c12',
- 'brownish': '#9c6d57',
- 'emerald green': '#028f1e',
- 'pale brown': '#b1916e',
- 'dull blue': '#49759c',
- 'burnt umber': '#a0450e',
- 'medium green': '#39ad48',
- 'clay': '#b66a50',
- 'light aqua': '#8cffdb',
- 'light olive green': '#a4be5c',
- 'brownish orange': '#cb7723',
- 'dark aqua': '#05696b',
- 'purplish pink': '#ce5dae',
- 'dark salmon': '#c85a53',
- 'greenish grey': '#96ae8d',
- 'jade': '#1fa774',
- 'ugly green': '#7a9703',
- 'dark beige': '#ac9362',
- 'emerald': '#01a049',
- 'pale red': '#d9544d',
- 'light magenta': '#fa5ff7',
- 'sky': '#82cafc',
- 'light cyan': '#acfffc',
- 'yellow orange': '#fcb001',
- 'reddish purple': '#910951',
- 'reddish pink': '#fe2c54',
- 'orchid': '#c875c4',
- 'dirty yellow': '#cdc50a',
- 'orange red': '#fd411e',
- 'deep red': '#9a0200',
- 'orange brown': '#be6400',
- 'cobalt blue': '#030aa7',
- 'neon pink': '#fe019a',
- 'rose pink': '#f7879a',
- 'greyish purple': '#887191',
- 'raspberry': '#b00149',
- 'aqua green': '#12e193',
- 'salmon pink': '#fe7b7c',
- 'tangerine': '#ff9408',
- 'brownish green': '#6a6e09',
- 'red brown': '#8b2e16',
- 'greenish brown': '#696112',
- 'pumpkin': '#e17701',
- 'pine green': '#0a481e',
- 'charcoal': '#343837',
- 'baby pink': '#ffb7ce',
- 'cornflower': '#6a79f7',
- 'blue violet': '#5d06e9',
- 'chocolate': '#3d1c02',
- 'greyish green': '#82a67d',
- 'scarlet': '#be0119',
- 'green yellow': '#c9ff27',
- 'dark olive': '#373e02',
- 'sienna': '#a9561e',
- 'pastel purple': '#caa0ff',
- 'terracotta': '#ca6641',
- 'aqua blue': '#02d8e9',
- 'sage green': '#88b378',
- 'blood red': '#980002',
- 'deep pink': '#cb0162',
- 'grass': '#5cac2d',
- 'moss': '#769958',
- 'pastel blue': '#a2bffe',
- 'bluish green': '#10a674',
- 'green blue': '#06b48b',
- 'dark tan': '#af884a',
- 'greenish blue': '#0b8b87',
- 'pale orange': '#ffa756',
- 'vomit': '#a2a415',
- 'forrest green': '#154406',
- 'dark lavender': '#856798',
- 'dark violet': '#34013f',
- 'purple blue': '#632de9',
- 'dark cyan': '#0a888a',
- 'olive drab': '#6f7632',
- 'pinkish': '#d46a7e',
- 'cobalt': '#1e488f',
- 'neon purple': '#bc13fe',
- 'light turquoise': '#7ef4cc',
- 'apple green': '#76cd26',
- 'dull green': '#74a662',
- 'wine': '#80013f',
- 'powder blue': '#b1d1fc',
- 'off white': '#ffffe4',
- 'electric blue': '#0652ff',
- 'dark turquoise': '#045c5a',
- 'blue purple': '#5729ce',
- 'azure': '#069af3',
- 'bright red': '#ff000d',
- 'pinkish red': '#f10c45',
- 'cornflower blue': '#5170d7',
- 'light olive': '#acbf69',
- 'grape': '#6c3461',
- 'greyish blue': '#5e819d',
- 'purplish blue': '#601ef9',
- 'yellowish green': '#b0dd16',
- 'greenish yellow': '#cdfd02',
- 'medium blue': '#2c6fbb',
- 'dusty rose': '#c0737a',
- 'light violet': '#d6b4fc',
- 'midnight blue': '#020035',
- 'bluish purple': '#703be7',
- 'red orange': '#fd3c06',
- 'dark magenta': '#960056',
- 'greenish': '#40a368',
- 'ocean blue': '#03719c',
- 'coral': '#fc5a50',
- 'cream': '#ffffc2',
- 'reddish brown': '#7f2b0a',
- 'burnt sienna': '#b04e0f',
- 'brick': '#a03623',
- 'sage': '#87ae73',
- 'grey green': '#789b73',
- 'white': '#ffffff',
- "robin's egg blue": '#98eff9',
- 'moss green': '#658b38',
- 'steel blue': '#5a7d9a',
- 'eggplant': '#380835',
- 'light yellow': '#fffe7a',
- 'leaf green': '#5ca904',
- 'light grey': '#d8dcd6',
- 'puke': '#a5a502',
- 'pinkish purple': '#d648d7',
- 'sea blue': '#047495',
- 'pale purple': '#b790d4',
- 'slate blue': '#5b7c99',
- 'blue grey': '#607c8e',
- 'hunter green': '#0b4008',
- 'fuchsia': '#ed0dd9',
- 'crimson': '#8c000f',
- 'pale yellow': '#ffff84',
- 'ochre': '#bf9005',
- 'mustard yellow': '#d2bd0a',
- 'light red': '#ff474c',
- 'cerulean': '#0485d1',
- 'pale pink': '#ffcfdc',
- 'deep blue': '#040273',
- 'rust': '#a83c09',
- 'light teal': '#90e4c1',
- 'slate': '#516572',
- 'goldenrod': '#fac205',
- 'dark yellow': '#d5b60a',
- 'dark grey': '#363737',
- 'army green': '#4b5d16',
- 'grey blue': '#6b8ba4',
- 'seafoam': '#80f9ad',
- 'puce': '#a57e52',
- 'spring green': '#a9f971',
- 'dark orange': '#c65102',
- 'sand': '#e2ca76',
- 'pastel green': '#b0ff9d',
- 'mint': '#9ffeb0',
- 'light orange': '#fdaa48',
- 'bright pink': '#fe01b1',
- 'chartreuse': '#c1f80a',
- 'deep purple': '#36013f',
- 'dark brown': '#341c02',
- 'taupe': '#b9a281',
- 'pea green': '#8eab12',
- 'puke green': '#9aae07',
- 'kelly green': '#02ab2e',
- 'seafoam green': '#7af9ab',
- 'blue green': '#137e6d',
- 'khaki': '#aaa662',
- 'burgundy': '#610023',
- 'dark teal': '#014d4e',
- 'brick red': '#8f1402',
- 'royal purple': '#4b006e',
- 'plum': '#580f41',
- 'mint green': '#8fff9f',
- 'gold': '#dbb40c',
- 'baby blue': '#a2cffe',
- 'yellow green': '#c0fb2d',
- 'bright purple': '#be03fd',
- 'dark red': '#840000',
- 'pale blue': '#d0fefe',
- 'grass green': '#3f9b0b',
- 'navy': '#01153e',
- 'aquamarine': '#04d8b2',
- 'burnt orange': '#c04e01',
- 'neon green': '#0cff0c',
- 'bright blue': '#0165fc',
- 'rose': '#cf6275',
- 'light pink': '#ffd1df',
- 'mustard': '#ceb301',
- 'indigo': '#380282',
- 'lime': '#aaff32',
- 'sea green': '#53fca1',
- 'periwinkle': '#8e82fe',
- 'dark pink': '#cb416b',
- 'olive green': '#677a04',
- 'peach': '#ffb07c',
- 'pale green': '#c7fdb5',
- 'light brown': '#ad8150',
- 'hot pink': '#ff028d',
- 'black': '#000000',
- 'lilac': '#cea2fd',
- 'navy blue': '#001146',
- 'royal blue': '#0504aa',
- 'beige': '#e6daa6',
- 'salmon': '#ff796c',
- 'olive': '#6e750e',
- 'maroon': '#650021',
- 'bright green': '#01ff07',
- 'dark purple': '#35063e',
- 'mauve': '#ae7181',
- 'forest green': '#06470c',
- 'aqua': '#13eac9',
- 'cyan': '#00ffff',
- 'tan': '#d1b26f',
- 'dark blue': '#00035b',
- 'lavender': '#c79fef',
- 'turquoise': '#06c2ac',
- 'dark green': '#033500',
- 'violet': '#9a0eea',
- 'light purple': '#bf77f6',
- 'lime green': '#89fe05',
- 'grey': '#929591',
- 'sky blue': '#75bbfd',
- 'yellow': '#ffff14',
- 'magenta': '#c20078',
- 'light green': '#96f97b',
- 'orange': '#f97306',
- 'teal': '#029386',
- 'light blue': '#95d0fc',
- 'red': '#e50000',
- 'brown': '#653700',
- 'pink': '#ff81c0',
- 'blue': '#0343df',
- 'green': '#15b01a',
- 'purple': '#7e1e9c'}
-
-# Normalize name to "xkcd:<name>" to avoid name collisions.
-XKCD_COLORS = {'xkcd:' + name: value for name, value in XKCD_COLORS.items()}
-
-
-# https://drafts.csswg.org/css-color-4/#named-colors
-CSS4_COLORS = {
- 'aliceblue': '#F0F8FF',
- 'antiquewhite': '#FAEBD7',
- 'aqua': '#00FFFF',
- 'aquamarine': '#7FFFD4',
- 'azure': '#F0FFFF',
- 'beige': '#F5F5DC',
- 'bisque': '#FFE4C4',
- 'black': '#000000',
- 'blanchedalmond': '#FFEBCD',
- 'blue': '#0000FF',
- 'blueviolet': '#8A2BE2',
- 'brown': '#A52A2A',
- 'burlywood': '#DEB887',
- 'cadetblue': '#5F9EA0',
- 'chartreuse': '#7FFF00',
- 'chocolate': '#D2691E',
- 'coral': '#FF7F50',
- 'cornflowerblue': '#6495ED',
- 'cornsilk': '#FFF8DC',
- 'crimson': '#DC143C',
- 'cyan': '#00FFFF',
- 'darkblue': '#00008B',
- 'darkcyan': '#008B8B',
- 'darkgoldenrod': '#B8860B',
- 'darkgray': '#A9A9A9',
- 'darkgreen': '#006400',
- 'darkgrey': '#A9A9A9',
- 'darkkhaki': '#BDB76B',
- 'darkmagenta': '#8B008B',
- 'darkolivegreen': '#556B2F',
- 'darkorange': '#FF8C00',
- 'darkorchid': '#9932CC',
- 'darkred': '#8B0000',
- 'darksalmon': '#E9967A',
- 'darkseagreen': '#8FBC8F',
- 'darkslateblue': '#483D8B',
- 'darkslategray': '#2F4F4F',
- 'darkslategrey': '#2F4F4F',
- 'darkturquoise': '#00CED1',
- 'darkviolet': '#9400D3',
- 'deeppink': '#FF1493',
- 'deepskyblue': '#00BFFF',
- 'dimgray': '#696969',
- 'dimgrey': '#696969',
- 'dodgerblue': '#1E90FF',
- 'firebrick': '#B22222',
- 'floralwhite': '#FFFAF0',
- 'forestgreen': '#228B22',
- 'fuchsia': '#FF00FF',
- 'gainsboro': '#DCDCDC',
- 'ghostwhite': '#F8F8FF',
- 'gold': '#FFD700',
- 'goldenrod': '#DAA520',
- 'gray': '#808080',
- 'green': '#008000',
- 'greenyellow': '#ADFF2F',
- 'grey': '#808080',
- 'honeydew': '#F0FFF0',
- 'hotpink': '#FF69B4',
- 'indianred': '#CD5C5C',
- 'indigo': '#4B0082',
- 'ivory': '#FFFFF0',
- 'khaki': '#F0E68C',
- 'lavender': '#E6E6FA',
- 'lavenderblush': '#FFF0F5',
- 'lawngreen': '#7CFC00',
- 'lemonchiffon': '#FFFACD',
- 'lightblue': '#ADD8E6',
- 'lightcoral': '#F08080',
- 'lightcyan': '#E0FFFF',
- 'lightgoldenrodyellow': '#FAFAD2',
- 'lightgray': '#D3D3D3',
- 'lightgreen': '#90EE90',
- 'lightgrey': '#D3D3D3',
- 'lightpink': '#FFB6C1',
- 'lightsalmon': '#FFA07A',
- 'lightseagreen': '#20B2AA',
- 'lightskyblue': '#87CEFA',
- 'lightslategray': '#778899',
- 'lightslategrey': '#778899',
- 'lightsteelblue': '#B0C4DE',
- 'lightyellow': '#FFFFE0',
- 'lime': '#00FF00',
- 'limegreen': '#32CD32',
- 'linen': '#FAF0E6',
- 'magenta': '#FF00FF',
- 'maroon': '#800000',
- 'mediumaquamarine': '#66CDAA',
- 'mediumblue': '#0000CD',
- 'mediumorchid': '#BA55D3',
- 'mediumpurple': '#9370DB',
- 'mediumseagreen': '#3CB371',
- 'mediumslateblue': '#7B68EE',
- 'mediumspringgreen': '#00FA9A',
- 'mediumturquoise': '#48D1CC',
- 'mediumvioletred': '#C71585',
- 'midnightblue': '#191970',
- 'mintcream': '#F5FFFA',
- 'mistyrose': '#FFE4E1',
- 'moccasin': '#FFE4B5',
- 'navajowhite': '#FFDEAD',
- 'navy': '#000080',
- 'oldlace': '#FDF5E6',
- 'olive': '#808000',
- 'olivedrab': '#6B8E23',
- 'orange': '#FFA500',
- 'orangered': '#FF4500',
- 'orchid': '#DA70D6',
- 'palegoldenrod': '#EEE8AA',
- 'palegreen': '#98FB98',
- 'paleturquoise': '#AFEEEE',
- 'palevioletred': '#DB7093',
- 'papayawhip': '#FFEFD5',
- 'peachpuff': '#FFDAB9',
- 'peru': '#CD853F',
- 'pink': '#FFC0CB',
- 'plum': '#DDA0DD',
- 'powderblue': '#B0E0E6',
- 'purple': '#800080',
- 'rebeccapurple': '#663399',
- 'red': '#FF0000',
- 'rosybrown': '#BC8F8F',
- 'royalblue': '#4169E1',
- 'saddlebrown': '#8B4513',
- 'salmon': '#FA8072',
- 'sandybrown': '#F4A460',
- 'seagreen': '#2E8B57',
- 'seashell': '#FFF5EE',
- 'sienna': '#A0522D',
- 'silver': '#C0C0C0',
- 'skyblue': '#87CEEB',
- 'slateblue': '#6A5ACD',
- 'slategray': '#708090',
- 'slategrey': '#708090',
- 'snow': '#FFFAFA',
- 'springgreen': '#00FF7F',
- 'steelblue': '#4682B4',
- 'tan': '#D2B48C',
- 'teal': '#008080',
- 'thistle': '#D8BFD8',
- 'tomato': '#FF6347',
- 'turquoise': '#40E0D0',
- 'violet': '#EE82EE',
- 'wheat': '#F5DEB3',
- 'white': '#FFFFFF',
- 'whitesmoke': '#F5F5F5',
- 'yellow': '#FFFF00',
- 'yellowgreen': '#9ACD32'}
diff --git a/contrib/python/matplotlib/py3/matplotlib/_color_data.pyi b/contrib/python/matplotlib/py3/matplotlib/_color_data.pyi
deleted file mode 100644
index feb3de9c30..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_color_data.pyi
+++ /dev/null
@@ -1,6 +0,0 @@
-from .typing import ColorType
-
-BASE_COLORS: dict[str, ColorType]
-TABLEAU_COLORS: dict[str, ColorType]
-XKCD_COLORS: dict[str, ColorType]
-CSS4_COLORS: dict[str, ColorType]
diff --git a/contrib/python/matplotlib/py3/matplotlib/_constrained_layout.py b/contrib/python/matplotlib/py3/matplotlib/_constrained_layout.py
deleted file mode 100644
index 907e7a2497..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_constrained_layout.py
+++ /dev/null
@@ -1,794 +0,0 @@
-"""
-Adjust subplot layouts so that there are no overlapping axes or axes
-decorations. All axes decorations are dealt with (labels, ticks, titles,
-ticklabels) and some dependent artists are also dealt with (colorbar,
-suptitle).
-
-Layout is done via `~matplotlib.gridspec`, with one constraint per gridspec,
-so it is possible to have overlapping axes if the gridspecs overlap (i.e.
-using `~matplotlib.gridspec.GridSpecFromSubplotSpec`). Axes placed using
-``figure.subplots()`` or ``figure.add_subplots()`` will participate in the
-layout. Axes manually placed via ``figure.add_axes()`` will not.
-
-See Tutorial: :ref:`constrainedlayout_guide`
-
-General idea:
--------------
-
-First, a figure has a gridspec that divides the figure into nrows and ncols,
-with heights and widths set by ``height_ratios`` and ``width_ratios``,
-often just set to 1 for an equal grid.
-
-Subplotspecs that are derived from this gridspec can contain either a
-``SubPanel``, a ``GridSpecFromSubplotSpec``, or an ``Axes``. The ``SubPanel``
-and ``GridSpecFromSubplotSpec`` are dealt with recursively and each contain an
-analogous layout.
-
-Each ``GridSpec`` has a ``_layoutgrid`` attached to it. The ``_layoutgrid``
-has the same logical layout as the ``GridSpec``. Each row of the grid spec
-has a top and bottom "margin" and each column has a left and right "margin".
-The "inner" height of each row is constrained to be the same (or as modified
-by ``height_ratio``), and the "inner" width of each column is
-constrained to be the same (as modified by ``width_ratio``), where "inner"
-is the width or height of each column/row minus the size of the margins.
-
-Then the size of the margins for each row and column are determined as the
-max width of the decorators on each axes that has decorators in that margin.
-For instance, a normal axes would have a left margin that includes the
-left ticklabels, and the ylabel if it exists. The right margin may include a
-colorbar, the bottom margin the xaxis decorations, and the top margin the
-title.
-
-With these constraints, the solver then finds appropriate bounds for the
-columns and rows. It's possible that the margins take up the whole figure,
-in which case the algorithm is not applied and a warning is raised.
-
-See the tutorial :ref:`constrainedlayout_guide`
-for more discussion of the algorithm with examples.
-"""
-
-import logging
-
-import numpy as np
-
-from matplotlib import _api, artist as martist
-import matplotlib.transforms as mtransforms
-import matplotlib._layoutgrid as mlayoutgrid
-
-
-_log = logging.getLogger(__name__)
-
-
-######################################################
-def do_constrained_layout(fig, h_pad, w_pad,
- hspace=None, wspace=None, rect=(0, 0, 1, 1),
- compress=False):
- """
- Do the constrained_layout. Called at draw time in
- ``figure.constrained_layout()``
-
- Parameters
- ----------
- fig : `~matplotlib.figure.Figure`
- `.Figure` instance to do the layout in.
-
- h_pad, w_pad : float
- Padding around the axes elements in figure-normalized units.
-
- hspace, wspace : float
- Fraction of the figure to dedicate to space between the
- axes. These are evenly spread between the gaps between the axes.
- A value of 0.2 for a three-column layout would have a space
- of 0.1 of the figure width between each column.
- If h/wspace < h/w_pad, then the pads are used instead.
-
- rect : tuple of 4 floats
- Rectangle in figure coordinates to perform constrained layout in
- [left, bottom, width, height], each from 0-1.
-
- compress : bool
- Whether to shift Axes so that white space in between them is
- removed. This is useful for simple grids of fixed-aspect Axes (e.g.
- a grid of images).
-
- Returns
- -------
- layoutgrid : private debugging structure
- """
-
- renderer = fig._get_renderer()
- # make layoutgrid tree...
- layoutgrids = make_layoutgrids(fig, None, rect=rect)
- if not layoutgrids['hasgrids']:
- _api.warn_external('There are no gridspecs with layoutgrids. '
- 'Possibly did not call parent GridSpec with the'
- ' "figure" keyword')
- return
-
- for _ in range(2):
- # do the algorithm twice. This has to be done because decorations
- # change size after the first re-position (i.e. x/yticklabels get
- # larger/smaller). This second reposition tends to be much milder,
- # so doing twice makes things work OK.
-
- # make margins for all the axes and subfigures in the
- # figure. Add margins for colorbars...
- make_layout_margins(layoutgrids, fig, renderer, h_pad=h_pad,
- w_pad=w_pad, hspace=hspace, wspace=wspace)
- make_margin_suptitles(layoutgrids, fig, renderer, h_pad=h_pad,
- w_pad=w_pad)
-
- # if a layout is such that a columns (or rows) margin has no
- # constraints, we need to make all such instances in the grid
- # match in margin size.
- match_submerged_margins(layoutgrids, fig)
-
- # update all the variables in the layout.
- layoutgrids[fig].update_variables()
-
- warn_collapsed = ('constrained_layout not applied because '
- 'axes sizes collapsed to zero. Try making '
- 'figure larger or axes decorations smaller.')
- if check_no_collapsed_axes(layoutgrids, fig):
- reposition_axes(layoutgrids, fig, renderer, h_pad=h_pad,
- w_pad=w_pad, hspace=hspace, wspace=wspace)
- if compress:
- layoutgrids = compress_fixed_aspect(layoutgrids, fig)
- layoutgrids[fig].update_variables()
- if check_no_collapsed_axes(layoutgrids, fig):
- reposition_axes(layoutgrids, fig, renderer, h_pad=h_pad,
- w_pad=w_pad, hspace=hspace, wspace=wspace)
- else:
- _api.warn_external(warn_collapsed)
- else:
- _api.warn_external(warn_collapsed)
- reset_margins(layoutgrids, fig)
- return layoutgrids
-
-
-def make_layoutgrids(fig, layoutgrids, rect=(0, 0, 1, 1)):
- """
- Make the layoutgrid tree.
-
- (Sub)Figures get a layoutgrid so we can have figure margins.
-
- Gridspecs that are attached to axes get a layoutgrid so axes
- can have margins.
- """
-
- if layoutgrids is None:
- layoutgrids = dict()
- layoutgrids['hasgrids'] = False
- if not hasattr(fig, '_parent'):
- # top figure; pass rect as parent to allow user-specified
- # margins
- layoutgrids[fig] = mlayoutgrid.LayoutGrid(parent=rect, name='figlb')
- else:
- # subfigure
- gs = fig._subplotspec.get_gridspec()
- # it is possible the gridspec containing this subfigure hasn't
- # been added to the tree yet:
- layoutgrids = make_layoutgrids_gs(layoutgrids, gs)
- # add the layoutgrid for the subfigure:
- parentlb = layoutgrids[gs]
- layoutgrids[fig] = mlayoutgrid.LayoutGrid(
- parent=parentlb,
- name='panellb',
- parent_inner=True,
- nrows=1, ncols=1,
- parent_pos=(fig._subplotspec.rowspan,
- fig._subplotspec.colspan))
- # recursively do all subfigures in this figure...
- for sfig in fig.subfigs:
- layoutgrids = make_layoutgrids(sfig, layoutgrids)
-
- # for each axes at the local level add its gridspec:
- for ax in fig._localaxes:
- gs = ax.get_gridspec()
- if gs is not None:
- layoutgrids = make_layoutgrids_gs(layoutgrids, gs)
-
- return layoutgrids
-
-
-def make_layoutgrids_gs(layoutgrids, gs):
- """
- Make the layoutgrid for a gridspec (and anything nested in the gridspec)
- """
-
- if gs in layoutgrids or gs.figure is None:
- return layoutgrids
- # in order to do constrained_layout there has to be at least *one*
- # gridspec in the tree:
- layoutgrids['hasgrids'] = True
- if not hasattr(gs, '_subplot_spec'):
- # normal gridspec
- parent = layoutgrids[gs.figure]
- layoutgrids[gs] = mlayoutgrid.LayoutGrid(
- parent=parent,
- parent_inner=True,
- name='gridspec',
- ncols=gs._ncols, nrows=gs._nrows,
- width_ratios=gs.get_width_ratios(),
- height_ratios=gs.get_height_ratios())
- else:
- # this is a gridspecfromsubplotspec:
- subplot_spec = gs._subplot_spec
- parentgs = subplot_spec.get_gridspec()
- # if a nested gridspec it is possible the parent is not in there yet:
- if parentgs not in layoutgrids:
- layoutgrids = make_layoutgrids_gs(layoutgrids, parentgs)
- subspeclb = layoutgrids[parentgs]
- # gridspecfromsubplotspec need an outer container:
- # get a unique representation:
- rep = (gs, 'top')
- if rep not in layoutgrids:
- layoutgrids[rep] = mlayoutgrid.LayoutGrid(
- parent=subspeclb,
- name='top',
- nrows=1, ncols=1,
- parent_pos=(subplot_spec.rowspan, subplot_spec.colspan))
- layoutgrids[gs] = mlayoutgrid.LayoutGrid(
- parent=layoutgrids[rep],
- name='gridspec',
- nrows=gs._nrows, ncols=gs._ncols,
- width_ratios=gs.get_width_ratios(),
- height_ratios=gs.get_height_ratios())
- return layoutgrids
-
-
-def check_no_collapsed_axes(layoutgrids, fig):
- """
- Check that no axes have collapsed to zero size.
- """
- for sfig in fig.subfigs:
- ok = check_no_collapsed_axes(layoutgrids, sfig)
- if not ok:
- return False
- for ax in fig.axes:
- gs = ax.get_gridspec()
- if gs in layoutgrids: # also implies gs is not None.
- lg = layoutgrids[gs]
- for i in range(gs.nrows):
- for j in range(gs.ncols):
- bb = lg.get_inner_bbox(i, j)
- if bb.width <= 0 or bb.height <= 0:
- return False
- return True
-
-
-def compress_fixed_aspect(layoutgrids, fig):
- gs = None
- for ax in fig.axes:
- if ax.get_subplotspec() is None:
- continue
- ax.apply_aspect()
- sub = ax.get_subplotspec()
- _gs = sub.get_gridspec()
- if gs is None:
- gs = _gs
- extraw = np.zeros(gs.ncols)
- extrah = np.zeros(gs.nrows)
- elif _gs != gs:
- raise ValueError('Cannot do compressed layout if axes are not'
- 'all from the same gridspec')
- orig = ax.get_position(original=True)
- actual = ax.get_position(original=False)
- dw = orig.width - actual.width
- if dw > 0:
- extraw[sub.colspan] = np.maximum(extraw[sub.colspan], dw)
- dh = orig.height - actual.height
- if dh > 0:
- extrah[sub.rowspan] = np.maximum(extrah[sub.rowspan], dh)
-
- if gs is None:
- raise ValueError('Cannot do compressed layout if no axes '
- 'are part of a gridspec.')
- w = np.sum(extraw) / 2
- layoutgrids[fig].edit_margin_min('left', w)
- layoutgrids[fig].edit_margin_min('right', w)
-
- h = np.sum(extrah) / 2
- layoutgrids[fig].edit_margin_min('top', h)
- layoutgrids[fig].edit_margin_min('bottom', h)
- return layoutgrids
-
-
-def get_margin_from_padding(obj, *, w_pad=0, h_pad=0,
- hspace=0, wspace=0):
-
- ss = obj._subplotspec
- gs = ss.get_gridspec()
-
- if hasattr(gs, 'hspace'):
- _hspace = (gs.hspace if gs.hspace is not None else hspace)
- _wspace = (gs.wspace if gs.wspace is not None else wspace)
- else:
- _hspace = (gs._hspace if gs._hspace is not None else hspace)
- _wspace = (gs._wspace if gs._wspace is not None else wspace)
-
- _wspace = _wspace / 2
- _hspace = _hspace / 2
-
- nrows, ncols = gs.get_geometry()
- # there are two margins for each direction. The "cb"
- # margins are for pads and colorbars, the non-"cb" are
- # for the axes decorations (labels etc).
- margin = {'leftcb': w_pad, 'rightcb': w_pad,
- 'bottomcb': h_pad, 'topcb': h_pad,
- 'left': 0, 'right': 0,
- 'top': 0, 'bottom': 0}
- if _wspace / ncols > w_pad:
- if ss.colspan.start > 0:
- margin['leftcb'] = _wspace / ncols
- if ss.colspan.stop < ncols:
- margin['rightcb'] = _wspace / ncols
- if _hspace / nrows > h_pad:
- if ss.rowspan.stop < nrows:
- margin['bottomcb'] = _hspace / nrows
- if ss.rowspan.start > 0:
- margin['topcb'] = _hspace / nrows
-
- return margin
-
-
-def make_layout_margins(layoutgrids, fig, renderer, *, w_pad=0, h_pad=0,
- hspace=0, wspace=0):
- """
- For each axes, make a margin between the *pos* layoutbox and the
- *axes* layoutbox be a minimum size that can accommodate the
- decorations on the axis.
-
- Then make room for colorbars.
-
- Parameters
- ----------
- layoutgrids : dict
- fig : `~matplotlib.figure.Figure`
- `.Figure` instance to do the layout in.
- renderer : `~matplotlib.backend_bases.RendererBase` subclass.
- The renderer to use.
- w_pad, h_pad : float, default: 0
- Width and height padding (in fraction of figure).
- hspace, wspace : float, default: 0
- Width and height padding as fraction of figure size divided by
- number of columns or rows.
- """
- for sfig in fig.subfigs: # recursively make child panel margins
- ss = sfig._subplotspec
- gs = ss.get_gridspec()
-
- make_layout_margins(layoutgrids, sfig, renderer,
- w_pad=w_pad, h_pad=h_pad,
- hspace=hspace, wspace=wspace)
-
- margins = get_margin_from_padding(sfig, w_pad=0, h_pad=0,
- hspace=hspace, wspace=wspace)
- layoutgrids[gs].edit_outer_margin_mins(margins, ss)
-
- for ax in fig._localaxes:
- if not ax.get_subplotspec() or not ax.get_in_layout():
- continue
-
- ss = ax.get_subplotspec()
- gs = ss.get_gridspec()
-
- if gs not in layoutgrids:
- return
-
- margin = get_margin_from_padding(ax, w_pad=w_pad, h_pad=h_pad,
- hspace=hspace, wspace=wspace)
- pos, bbox = get_pos_and_bbox(ax, renderer)
- # the margin is the distance between the bounding box of the axes
- # and its position (plus the padding from above)
- margin['left'] += pos.x0 - bbox.x0
- margin['right'] += bbox.x1 - pos.x1
- # remember that rows are ordered from top:
- margin['bottom'] += pos.y0 - bbox.y0
- margin['top'] += bbox.y1 - pos.y1
-
- # make margin for colorbars. These margins go in the
- # padding margin, versus the margin for axes decorators.
- for cbax in ax._colorbars:
- # note pad is a fraction of the parent width...
- pad = colorbar_get_pad(layoutgrids, cbax)
- # colorbars can be child of more than one subplot spec:
- cbp_rspan, cbp_cspan = get_cb_parent_spans(cbax)
- loc = cbax._colorbar_info['location']
- cbpos, cbbbox = get_pos_and_bbox(cbax, renderer)
- if loc == 'right':
- if cbp_cspan.stop == ss.colspan.stop:
- # only increase if the colorbar is on the right edge
- margin['rightcb'] += cbbbox.width + pad
- elif loc == 'left':
- if cbp_cspan.start == ss.colspan.start:
- # only increase if the colorbar is on the left edge
- margin['leftcb'] += cbbbox.width + pad
- elif loc == 'top':
- if cbp_rspan.start == ss.rowspan.start:
- margin['topcb'] += cbbbox.height + pad
- else:
- if cbp_rspan.stop == ss.rowspan.stop:
- margin['bottomcb'] += cbbbox.height + pad
- # If the colorbars are wider than the parent box in the
- # cross direction
- if loc in ['top', 'bottom']:
- if (cbp_cspan.start == ss.colspan.start and
- cbbbox.x0 < bbox.x0):
- margin['left'] += bbox.x0 - cbbbox.x0
- if (cbp_cspan.stop == ss.colspan.stop and
- cbbbox.x1 > bbox.x1):
- margin['right'] += cbbbox.x1 - bbox.x1
- # or taller:
- if loc in ['left', 'right']:
- if (cbp_rspan.stop == ss.rowspan.stop and
- cbbbox.y0 < bbox.y0):
- margin['bottom'] += bbox.y0 - cbbbox.y0
- if (cbp_rspan.start == ss.rowspan.start and
- cbbbox.y1 > bbox.y1):
- margin['top'] += cbbbox.y1 - bbox.y1
- # pass the new margins down to the layout grid for the solution...
- layoutgrids[gs].edit_outer_margin_mins(margin, ss)
-
- # make margins for figure-level legends:
- for leg in fig.legends:
- inv_trans_fig = None
- if leg._outside_loc and leg._bbox_to_anchor is None:
- if inv_trans_fig is None:
- inv_trans_fig = fig.transFigure.inverted().transform_bbox
- bbox = inv_trans_fig(leg.get_tightbbox(renderer))
- w = bbox.width + 2 * w_pad
- h = bbox.height + 2 * h_pad
- legendloc = leg._outside_loc
- if legendloc == 'lower':
- layoutgrids[fig].edit_margin_min('bottom', h)
- elif legendloc == 'upper':
- layoutgrids[fig].edit_margin_min('top', h)
- if legendloc == 'right':
- layoutgrids[fig].edit_margin_min('right', w)
- elif legendloc == 'left':
- layoutgrids[fig].edit_margin_min('left', w)
-
-
-def make_margin_suptitles(layoutgrids, fig, renderer, *, w_pad=0, h_pad=0):
- # Figure out how large the suptitle is and make the
- # top level figure margin larger.
-
- inv_trans_fig = fig.transFigure.inverted().transform_bbox
- # get the h_pad and w_pad as distances in the local subfigure coordinates:
- padbox = mtransforms.Bbox([[0, 0], [w_pad, h_pad]])
- padbox = (fig.transFigure -
- fig.transSubfigure).transform_bbox(padbox)
- h_pad_local = padbox.height
- w_pad_local = padbox.width
-
- for sfig in fig.subfigs:
- make_margin_suptitles(layoutgrids, sfig, renderer,
- w_pad=w_pad, h_pad=h_pad)
-
- if fig._suptitle is not None and fig._suptitle.get_in_layout():
- p = fig._suptitle.get_position()
- if getattr(fig._suptitle, '_autopos', False):
- fig._suptitle.set_position((p[0], 1 - h_pad_local))
- bbox = inv_trans_fig(fig._suptitle.get_tightbbox(renderer))
- layoutgrids[fig].edit_margin_min('top', bbox.height + 2 * h_pad)
-
- if fig._supxlabel is not None and fig._supxlabel.get_in_layout():
- p = fig._supxlabel.get_position()
- if getattr(fig._supxlabel, '_autopos', False):
- fig._supxlabel.set_position((p[0], h_pad_local))
- bbox = inv_trans_fig(fig._supxlabel.get_tightbbox(renderer))
- layoutgrids[fig].edit_margin_min('bottom',
- bbox.height + 2 * h_pad)
-
- if fig._supylabel is not None and fig._supylabel.get_in_layout():
- p = fig._supylabel.get_position()
- if getattr(fig._supylabel, '_autopos', False):
- fig._supylabel.set_position((w_pad_local, p[1]))
- bbox = inv_trans_fig(fig._supylabel.get_tightbbox(renderer))
- layoutgrids[fig].edit_margin_min('left', bbox.width + 2 * w_pad)
-
-
-def match_submerged_margins(layoutgrids, fig):
- """
- Make the margins that are submerged inside an Axes the same size.
-
- This allows axes that span two columns (or rows) that are offset
- from one another to have the same size.
-
- This gives the proper layout for something like::
- fig = plt.figure(constrained_layout=True)
- axs = fig.subplot_mosaic("AAAB\nCCDD")
-
- Without this routine, the axes D will be wider than C, because the
- margin width between the two columns in C has no width by default,
- whereas the margins between the two columns of D are set by the
- width of the margin between A and B. However, obviously the user would
- like C and D to be the same size, so we need to add constraints to these
- "submerged" margins.
-
- This routine makes all the interior margins the same, and the spacing
- between the three columns in A and the two column in C are all set to the
- margins between the two columns of D.
-
- See test_constrained_layout::test_constrained_layout12 for an example.
- """
-
- for sfig in fig.subfigs:
- match_submerged_margins(layoutgrids, sfig)
-
- axs = [a for a in fig.get_axes()
- if a.get_subplotspec() is not None and a.get_in_layout()]
-
- for ax1 in axs:
- ss1 = ax1.get_subplotspec()
- if ss1.get_gridspec() not in layoutgrids:
- axs.remove(ax1)
- continue
- lg1 = layoutgrids[ss1.get_gridspec()]
-
- # interior columns:
- if len(ss1.colspan) > 1:
- maxsubl = np.max(
- lg1.margin_vals['left'][ss1.colspan[1:]] +
- lg1.margin_vals['leftcb'][ss1.colspan[1:]]
- )
- maxsubr = np.max(
- lg1.margin_vals['right'][ss1.colspan[:-1]] +
- lg1.margin_vals['rightcb'][ss1.colspan[:-1]]
- )
- for ax2 in axs:
- ss2 = ax2.get_subplotspec()
- lg2 = layoutgrids[ss2.get_gridspec()]
- if lg2 is not None and len(ss2.colspan) > 1:
- maxsubl2 = np.max(
- lg2.margin_vals['left'][ss2.colspan[1:]] +
- lg2.margin_vals['leftcb'][ss2.colspan[1:]])
- if maxsubl2 > maxsubl:
- maxsubl = maxsubl2
- maxsubr2 = np.max(
- lg2.margin_vals['right'][ss2.colspan[:-1]] +
- lg2.margin_vals['rightcb'][ss2.colspan[:-1]])
- if maxsubr2 > maxsubr:
- maxsubr = maxsubr2
- for i in ss1.colspan[1:]:
- lg1.edit_margin_min('left', maxsubl, cell=i)
- for i in ss1.colspan[:-1]:
- lg1.edit_margin_min('right', maxsubr, cell=i)
-
- # interior rows:
- if len(ss1.rowspan) > 1:
- maxsubt = np.max(
- lg1.margin_vals['top'][ss1.rowspan[1:]] +
- lg1.margin_vals['topcb'][ss1.rowspan[1:]]
- )
- maxsubb = np.max(
- lg1.margin_vals['bottom'][ss1.rowspan[:-1]] +
- lg1.margin_vals['bottomcb'][ss1.rowspan[:-1]]
- )
-
- for ax2 in axs:
- ss2 = ax2.get_subplotspec()
- lg2 = layoutgrids[ss2.get_gridspec()]
- if lg2 is not None:
- if len(ss2.rowspan) > 1:
- maxsubt = np.max([np.max(
- lg2.margin_vals['top'][ss2.rowspan[1:]] +
- lg2.margin_vals['topcb'][ss2.rowspan[1:]]
- ), maxsubt])
- maxsubb = np.max([np.max(
- lg2.margin_vals['bottom'][ss2.rowspan[:-1]] +
- lg2.margin_vals['bottomcb'][ss2.rowspan[:-1]]
- ), maxsubb])
- for i in ss1.rowspan[1:]:
- lg1.edit_margin_min('top', maxsubt, cell=i)
- for i in ss1.rowspan[:-1]:
- lg1.edit_margin_min('bottom', maxsubb, cell=i)
-
-
-def get_cb_parent_spans(cbax):
- """
- Figure out which subplotspecs this colorbar belongs to.
-
- Parameters
- ----------
- cbax : `~matplotlib.axes.Axes`
- Axes for the colorbar.
- """
- rowstart = np.inf
- rowstop = -np.inf
- colstart = np.inf
- colstop = -np.inf
- for parent in cbax._colorbar_info['parents']:
- ss = parent.get_subplotspec()
- rowstart = min(ss.rowspan.start, rowstart)
- rowstop = max(ss.rowspan.stop, rowstop)
- colstart = min(ss.colspan.start, colstart)
- colstop = max(ss.colspan.stop, colstop)
-
- rowspan = range(rowstart, rowstop)
- colspan = range(colstart, colstop)
- return rowspan, colspan
-
-
-def get_pos_and_bbox(ax, renderer):
- """
- Get the position and the bbox for the axes.
-
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- renderer : `~matplotlib.backend_bases.RendererBase` subclass.
-
- Returns
- -------
- pos : `~matplotlib.transforms.Bbox`
- Position in figure coordinates.
- bbox : `~matplotlib.transforms.Bbox`
- Tight bounding box in figure coordinates.
- """
- fig = ax.figure
- pos = ax.get_position(original=True)
- # pos is in panel co-ords, but we need in figure for the layout
- pos = pos.transformed(fig.transSubfigure - fig.transFigure)
- tightbbox = martist._get_tightbbox_for_layout_only(ax, renderer)
- if tightbbox is None:
- bbox = pos
- else:
- bbox = tightbbox.transformed(fig.transFigure.inverted())
- return pos, bbox
-
-
-def reposition_axes(layoutgrids, fig, renderer, *,
- w_pad=0, h_pad=0, hspace=0, wspace=0):
- """
- Reposition all the axes based on the new inner bounding box.
- """
- trans_fig_to_subfig = fig.transFigure - fig.transSubfigure
- for sfig in fig.subfigs:
- bbox = layoutgrids[sfig].get_outer_bbox()
- sfig._redo_transform_rel_fig(
- bbox=bbox.transformed(trans_fig_to_subfig))
- reposition_axes(layoutgrids, sfig, renderer,
- w_pad=w_pad, h_pad=h_pad,
- wspace=wspace, hspace=hspace)
-
- for ax in fig._localaxes:
- if ax.get_subplotspec() is None or not ax.get_in_layout():
- continue
-
- # grid bbox is in Figure coordinates, but we specify in panel
- # coordinates...
- ss = ax.get_subplotspec()
- gs = ss.get_gridspec()
- if gs not in layoutgrids:
- return
-
- bbox = layoutgrids[gs].get_inner_bbox(rows=ss.rowspan,
- cols=ss.colspan)
-
- # transform from figure to panel for set_position:
- newbbox = trans_fig_to_subfig.transform_bbox(bbox)
- ax._set_position(newbbox)
-
- # move the colorbars:
- # we need to keep track of oldw and oldh if there is more than
- # one colorbar:
- offset = {'left': 0, 'right': 0, 'bottom': 0, 'top': 0}
- for nn, cbax in enumerate(ax._colorbars[::-1]):
- if ax == cbax._colorbar_info['parents'][0]:
- reposition_colorbar(layoutgrids, cbax, renderer,
- offset=offset)
-
-
-def reposition_colorbar(layoutgrids, cbax, renderer, *, offset=None):
- """
- Place the colorbar in its new place.
-
- Parameters
- ----------
- layoutgrids : dict
- cbax : `~matplotlib.axes.Axes`
- Axes for the colorbar.
- renderer : `~matplotlib.backend_bases.RendererBase` subclass.
- The renderer to use.
- offset : array-like
- Offset the colorbar needs to be pushed to in order to
- account for multiple colorbars.
- """
-
- parents = cbax._colorbar_info['parents']
- gs = parents[0].get_gridspec()
- fig = cbax.figure
- trans_fig_to_subfig = fig.transFigure - fig.transSubfigure
-
- cb_rspans, cb_cspans = get_cb_parent_spans(cbax)
- bboxparent = layoutgrids[gs].get_bbox_for_cb(rows=cb_rspans,
- cols=cb_cspans)
- pb = layoutgrids[gs].get_inner_bbox(rows=cb_rspans, cols=cb_cspans)
-
- location = cbax._colorbar_info['location']
- anchor = cbax._colorbar_info['anchor']
- fraction = cbax._colorbar_info['fraction']
- aspect = cbax._colorbar_info['aspect']
- shrink = cbax._colorbar_info['shrink']
-
- cbpos, cbbbox = get_pos_and_bbox(cbax, renderer)
-
- # Colorbar gets put at extreme edge of outer bbox of the subplotspec
- # It needs to be moved in by: 1) a pad 2) its "margin" 3) by
- # any colorbars already added at this location:
- cbpad = colorbar_get_pad(layoutgrids, cbax)
- if location in ('left', 'right'):
- # fraction and shrink are fractions of parent
- pbcb = pb.shrunk(fraction, shrink).anchored(anchor, pb)
- # The colorbar is at the left side of the parent. Need
- # to translate to right (or left)
- if location == 'right':
- lmargin = cbpos.x0 - cbbbox.x0
- dx = bboxparent.x1 - pbcb.x0 + offset['right']
- dx += cbpad + lmargin
- offset['right'] += cbbbox.width + cbpad
- pbcb = pbcb.translated(dx, 0)
- else:
- lmargin = cbpos.x0 - cbbbox.x0
- dx = bboxparent.x0 - pbcb.x0 # edge of parent
- dx += -cbbbox.width - cbpad + lmargin - offset['left']
- offset['left'] += cbbbox.width + cbpad
- pbcb = pbcb.translated(dx, 0)
- else: # horizontal axes:
- pbcb = pb.shrunk(shrink, fraction).anchored(anchor, pb)
- if location == 'top':
- bmargin = cbpos.y0 - cbbbox.y0
- dy = bboxparent.y1 - pbcb.y0 + offset['top']
- dy += cbpad + bmargin
- offset['top'] += cbbbox.height + cbpad
- pbcb = pbcb.translated(0, dy)
- else:
- bmargin = cbpos.y0 - cbbbox.y0
- dy = bboxparent.y0 - pbcb.y0
- dy += -cbbbox.height - cbpad + bmargin - offset['bottom']
- offset['bottom'] += cbbbox.height + cbpad
- pbcb = pbcb.translated(0, dy)
-
- pbcb = trans_fig_to_subfig.transform_bbox(pbcb)
- cbax.set_transform(fig.transSubfigure)
- cbax._set_position(pbcb)
- cbax.set_anchor(anchor)
- if location in ['bottom', 'top']:
- aspect = 1 / aspect
- cbax.set_box_aspect(aspect)
- cbax.set_aspect('auto')
- return offset
-
-
-def reset_margins(layoutgrids, fig):
- """
- Reset the margins in the layoutboxes of *fig*.
-
- Margins are usually set as a minimum, so if the figure gets smaller
- the minimum needs to be zero in order for it to grow again.
- """
- for sfig in fig.subfigs:
- reset_margins(layoutgrids, sfig)
- for ax in fig.axes:
- if ax.get_in_layout():
- gs = ax.get_gridspec()
- if gs in layoutgrids: # also implies gs is not None.
- layoutgrids[gs].reset_margins()
- layoutgrids[fig].reset_margins()
-
-
-def colorbar_get_pad(layoutgrids, cax):
- parents = cax._colorbar_info['parents']
- gs = parents[0].get_gridspec()
-
- cb_rspans, cb_cspans = get_cb_parent_spans(cax)
- bboxouter = layoutgrids[gs].get_inner_bbox(rows=cb_rspans, cols=cb_cspans)
-
- if cax._colorbar_info['location'] in ['right', 'left']:
- size = bboxouter.width
- else:
- size = bboxouter.height
-
- return cax._colorbar_info['pad'] * size
diff --git a/contrib/python/matplotlib/py3/matplotlib/_docstring.py b/contrib/python/matplotlib/py3/matplotlib/_docstring.py
deleted file mode 100644
index ecd209ca08..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_docstring.py
+++ /dev/null
@@ -1,97 +0,0 @@
-import inspect
-
-from . import _api
-
-
-class Substitution:
- """
- A decorator that performs %-substitution on an object's docstring.
-
- This decorator should be robust even if ``obj.__doc__`` is None (for
- example, if -OO was passed to the interpreter).
-
- Usage: construct a docstring.Substitution with a sequence or dictionary
- suitable for performing substitution; then decorate a suitable function
- with the constructed object, e.g.::
-
- sub_author_name = Substitution(author='Jason')
-
- @sub_author_name
- def some_function(x):
- "%(author)s wrote this function"
-
- # note that some_function.__doc__ is now "Jason wrote this function"
-
- One can also use positional arguments::
-
- sub_first_last_names = Substitution('Edgar Allen', 'Poe')
-
- @sub_first_last_names
- def some_function(x):
- "%s %s wrote the Raven"
- """
- def __init__(self, *args, **kwargs):
- if args and kwargs:
- raise TypeError("Only positional or keyword args are allowed")
- self.params = args or kwargs
-
- def __call__(self, func):
- if func.__doc__:
- func.__doc__ = inspect.cleandoc(func.__doc__) % self.params
- return func
-
- def update(self, *args, **kwargs):
- """
- Update ``self.params`` (which must be a dict) with the supplied args.
- """
- self.params.update(*args, **kwargs)
-
-
-class _ArtistKwdocLoader(dict):
- def __missing__(self, key):
- if not key.endswith(":kwdoc"):
- raise KeyError(key)
- name = key[:-len(":kwdoc")]
- from matplotlib.artist import Artist, kwdoc
- try:
- cls, = [cls for cls in _api.recursive_subclasses(Artist)
- if cls.__name__ == name]
- except ValueError as e:
- raise KeyError(key) from e
- return self.setdefault(key, kwdoc(cls))
-
-
-class _ArtistPropertiesSubstitution(Substitution):
- """
- A `.Substitution` with two additional features:
-
- - Substitutions of the form ``%(classname:kwdoc)s`` (ending with the
- literal ":kwdoc" suffix) trigger lookup of an Artist subclass with the
- given *classname*, and are substituted with the `.kwdoc` of that class.
- - Decorating a class triggers substitution both on the class docstring and
- on the class' ``__init__`` docstring (which is a commonly required
- pattern for Artist subclasses).
- """
-
- def __init__(self):
- self.params = _ArtistKwdocLoader()
-
- def __call__(self, obj):
- super().__call__(obj)
- if isinstance(obj, type) and obj.__init__ != object.__init__:
- self(obj.__init__)
- return obj
-
-
-def copy(source):
- """Copy a docstring from another source function (if present)."""
- def do_copy(target):
- if source.__doc__:
- target.__doc__ = source.__doc__
- return target
- return do_copy
-
-
-# Create a decorator that will house the various docstring snippets reused
-# throughout Matplotlib.
-dedent_interpd = interpd = _ArtistPropertiesSubstitution()
diff --git a/contrib/python/matplotlib/py3/matplotlib/_docstring.pyi b/contrib/python/matplotlib/py3/matplotlib/_docstring.pyi
deleted file mode 100644
index 0377dc5fe9..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_docstring.pyi
+++ /dev/null
@@ -1,29 +0,0 @@
-from typing import Any, Callable, TypeVar, overload
-
-
-_T = TypeVar('_T')
-
-
-class Substitution:
- @overload
- def __init__(self, *args: str): ...
- @overload
- def __init__(self, **kwargs: str): ...
- def __call__(self, func: _T) -> _T: ...
- def update(self, *args, **kwargs): ... # type: ignore[no-untyped-def]
-
-
-class _ArtistKwdocLoader(dict[str, str]):
- def __missing__(self, key: str) -> str: ...
-
-
-class _ArtistPropertiesSubstitution(Substitution):
- def __init__(self) -> None: ...
- def __call__(self, obj: _T) -> _T: ...
-
-
-def copy(source: Any) -> Callable[[_T], _T]: ...
-
-
-dedent_interpd: _ArtistPropertiesSubstitution
-interpd: _ArtistPropertiesSubstitution
diff --git a/contrib/python/matplotlib/py3/matplotlib/_enums.py b/contrib/python/matplotlib/py3/matplotlib/_enums.py
deleted file mode 100644
index c8c50f7c30..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_enums.py
+++ /dev/null
@@ -1,185 +0,0 @@
-"""
-Enums representing sets of strings that Matplotlib uses as input parameters.
-
-Matplotlib often uses simple data types like strings or tuples to define a
-concept; e.g. the line capstyle can be specified as one of 'butt', 'round',
-or 'projecting'. The classes in this module are used internally and serve to
-document these concepts formally.
-
-As an end-user you will not use these classes directly, but only the values
-they define.
-"""
-
-from enum import Enum, auto
-from matplotlib import _docstring
-
-
-class _AutoStringNameEnum(Enum):
- """Automate the ``name = 'name'`` part of making a (str, Enum)."""
-
- def _generate_next_value_(name, start, count, last_values):
- return name
-
- def __hash__(self):
- return str(self).__hash__()
-
-
-class JoinStyle(str, _AutoStringNameEnum):
- """
- Define how the connection between two line segments is drawn.
-
- For a visual impression of each *JoinStyle*, `view these docs online
- <JoinStyle>`, or run `JoinStyle.demo`.
-
- Lines in Matplotlib are typically defined by a 1D `~.path.Path` and a
- finite ``linewidth``, where the underlying 1D `~.path.Path` represents the
- center of the stroked line.
-
- By default, `~.backend_bases.GraphicsContextBase` defines the boundaries of
- a stroked line to simply be every point within some radius,
- ``linewidth/2``, away from any point of the center line. However, this
- results in corners appearing "rounded", which may not be the desired
- behavior if you are drawing, for example, a polygon or pointed star.
-
- **Supported values:**
-
- .. rst-class:: value-list
-
- 'miter'
- the "arrow-tip" style. Each boundary of the filled-in area will
- extend in a straight line parallel to the tangent vector of the
- centerline at the point it meets the corner, until they meet in a
- sharp point.
- 'round'
- stokes every point within a radius of ``linewidth/2`` of the center
- lines.
- 'bevel'
- the "squared-off" style. It can be thought of as a rounded corner
- where the "circular" part of the corner has been cut off.
-
- .. note::
-
- Very long miter tips are cut off (to form a *bevel*) after a
- backend-dependent limit called the "miter limit", which specifies the
- maximum allowed ratio of miter length to line width. For example, the
- PDF backend uses the default value of 10 specified by the PDF standard,
- while the SVG backend does not even specify the miter limit, resulting
- in a default value of 4 per the SVG specification. Matplotlib does not
- currently allow the user to adjust this parameter.
-
- A more detailed description of the effect of a miter limit can be found
- in the `Mozilla Developer Docs
- <https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-miterlimit>`_
-
- .. plot::
- :alt: Demo of possible JoinStyle's
-
- from matplotlib._enums import JoinStyle
- JoinStyle.demo()
-
- """
-
- miter = auto()
- round = auto()
- bevel = auto()
-
- @staticmethod
- def demo():
- """Demonstrate how each JoinStyle looks for various join angles."""
- import numpy as np
- import matplotlib.pyplot as plt
-
- def plot_angle(ax, x, y, angle, style):
- phi = np.radians(angle)
- xx = [x + .5, x, x + .5*np.cos(phi)]
- yy = [y, y, y + .5*np.sin(phi)]
- ax.plot(xx, yy, lw=12, color='tab:blue', solid_joinstyle=style)
- ax.plot(xx, yy, lw=1, color='black')
- ax.plot(xx[1], yy[1], 'o', color='tab:red', markersize=3)
-
- fig, ax = plt.subplots(figsize=(5, 4), constrained_layout=True)
- ax.set_title('Join style')
- for x, style in enumerate(['miter', 'round', 'bevel']):
- ax.text(x, 5, style)
- for y, angle in enumerate([20, 45, 60, 90, 120]):
- plot_angle(ax, x, y, angle, style)
- if x == 0:
- ax.text(-1.3, y, f'{angle} degrees')
- ax.set_xlim(-1.5, 2.75)
- ax.set_ylim(-.5, 5.5)
- ax.set_axis_off()
- fig.show()
-
-
-JoinStyle.input_description = "{" \
- + ", ".join([f"'{js.name}'" for js in JoinStyle]) \
- + "}"
-
-
-class CapStyle(str, _AutoStringNameEnum):
- r"""
- Define how the two endpoints (caps) of an unclosed line are drawn.
-
- How to draw the start and end points of lines that represent a closed curve
- (i.e. that end in a `~.path.Path.CLOSEPOLY`) is controlled by the line's
- `JoinStyle`. For all other lines, how the start and end points are drawn is
- controlled by the *CapStyle*.
-
- For a visual impression of each *CapStyle*, `view these docs online
- <CapStyle>` or run `CapStyle.demo`.
-
- By default, `~.backend_bases.GraphicsContextBase` draws a stroked line as
- squared off at its endpoints.
-
- **Supported values:**
-
- .. rst-class:: value-list
-
- 'butt'
- the line is squared off at its endpoint.
- 'projecting'
- the line is squared off as in *butt*, but the filled in area
- extends beyond the endpoint a distance of ``linewidth/2``.
- 'round'
- like *butt*, but a semicircular cap is added to the end of the
- line, of radius ``linewidth/2``.
-
- .. plot::
- :alt: Demo of possible CapStyle's
-
- from matplotlib._enums import CapStyle
- CapStyle.demo()
-
- """
- butt = auto()
- projecting = auto()
- round = auto()
-
- @staticmethod
- def demo():
- """Demonstrate how each CapStyle looks for a thick line segment."""
- import matplotlib.pyplot as plt
-
- fig = plt.figure(figsize=(4, 1.2))
- ax = fig.add_axes([0, 0, 1, 0.8])
- ax.set_title('Cap style')
-
- for x, style in enumerate(['butt', 'round', 'projecting']):
- ax.text(x+0.25, 0.85, style, ha='center')
- xx = [x, x+0.5]
- yy = [0, 0]
- ax.plot(xx, yy, lw=12, color='tab:blue', solid_capstyle=style)
- ax.plot(xx, yy, lw=1, color='black')
- ax.plot(xx, yy, 'o', color='tab:red', markersize=3)
-
- ax.set_ylim(-.5, 1.5)
- ax.set_axis_off()
- fig.show()
-
-
-CapStyle.input_description = "{" \
- + ", ".join([f"'{cs.name}'" for cs in CapStyle]) \
- + "}"
-
-_docstring.interpd.update({'JoinStyle': JoinStyle.input_description,
- 'CapStyle': CapStyle.input_description})
diff --git a/contrib/python/matplotlib/py3/matplotlib/_enums.pyi b/contrib/python/matplotlib/py3/matplotlib/_enums.pyi
deleted file mode 100644
index 351088b364..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_enums.pyi
+++ /dev/null
@@ -1,18 +0,0 @@
-from enum import Enum
-
-class _AutoStringNameEnum(Enum):
- def __hash__(self) -> int: ...
-
-class JoinStyle(str, _AutoStringNameEnum):
- miter: str
- round: str
- bevel: str
- @staticmethod
- def demo() -> None: ...
-
-class CapStyle(str, _AutoStringNameEnum):
- butt: str
- projecting: str
- round: str
- @staticmethod
- def demo() -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/_fontconfig_pattern.py b/contrib/python/matplotlib/py3/matplotlib/_fontconfig_pattern.py
deleted file mode 100644
index d3933b9f39..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_fontconfig_pattern.py
+++ /dev/null
@@ -1,120 +0,0 @@
-"""
-A module for parsing and generating `fontconfig patterns`_.
-
-.. _fontconfig patterns:
- https://www.freedesktop.org/software/fontconfig/fontconfig-user.html
-"""
-
-# This class logically belongs in `matplotlib.font_manager`, but placing it
-# there would have created cyclical dependency problems, because it also needs
-# to be available from `matplotlib.rcsetup` (for parsing matplotlibrc files).
-
-from functools import lru_cache, partial
-import re
-
-from pyparsing import (
- Group, Optional, ParseException, Regex, StringEnd, Suppress, ZeroOrMore)
-
-from matplotlib import _api
-
-
-_family_punc = r'\\\-:,'
-_family_unescape = partial(re.compile(r'\\(?=[%s])' % _family_punc).sub, '')
-_family_escape = partial(re.compile(r'(?=[%s])' % _family_punc).sub, r'\\')
-_value_punc = r'\\=_:,'
-_value_unescape = partial(re.compile(r'\\(?=[%s])' % _value_punc).sub, '')
-_value_escape = partial(re.compile(r'(?=[%s])' % _value_punc).sub, r'\\')
-
-
-_CONSTANTS = {
- 'thin': ('weight', 'light'),
- 'extralight': ('weight', 'light'),
- 'ultralight': ('weight', 'light'),
- 'light': ('weight', 'light'),
- 'book': ('weight', 'book'),
- 'regular': ('weight', 'regular'),
- 'normal': ('weight', 'normal'),
- 'medium': ('weight', 'medium'),
- 'demibold': ('weight', 'demibold'),
- 'semibold': ('weight', 'semibold'),
- 'bold': ('weight', 'bold'),
- 'extrabold': ('weight', 'extra bold'),
- 'black': ('weight', 'black'),
- 'heavy': ('weight', 'heavy'),
- 'roman': ('slant', 'normal'),
- 'italic': ('slant', 'italic'),
- 'oblique': ('slant', 'oblique'),
- 'ultracondensed': ('width', 'ultra-condensed'),
- 'extracondensed': ('width', 'extra-condensed'),
- 'condensed': ('width', 'condensed'),
- 'semicondensed': ('width', 'semi-condensed'),
- 'expanded': ('width', 'expanded'),
- 'extraexpanded': ('width', 'extra-expanded'),
- 'ultraexpanded': ('width', 'ultra-expanded'),
-}
-
-
-@lru_cache # The parser instance is a singleton.
-def _make_fontconfig_parser():
- def comma_separated(elem):
- return elem + ZeroOrMore(Suppress(",") + elem)
-
- family = Regex(fr"([^{_family_punc}]|(\\[{_family_punc}]))*")
- size = Regex(r"([0-9]+\.?[0-9]*|\.[0-9]+)")
- name = Regex(r"[a-z]+")
- value = Regex(fr"([^{_value_punc}]|(\\[{_value_punc}]))*")
- # replace trailing `| name` by oneOf(_CONSTANTS) in mpl 3.9.
- prop = Group((name + Suppress("=") + comma_separated(value)) | name)
- return (
- Optional(comma_separated(family)("families"))
- + Optional("-" + comma_separated(size)("sizes"))
- + ZeroOrMore(":" + prop("properties*"))
- + StringEnd()
- )
-
-
-# `parse_fontconfig_pattern` is a bottleneck during the tests because it is
-# repeatedly called when the rcParams are reset (to validate the default
-# fonts). In practice, the cache size doesn't grow beyond a few dozen entries
-# during the test suite.
-@lru_cache
-def parse_fontconfig_pattern(pattern):
- """
- Parse a fontconfig *pattern* into a dict that can initialize a
- `.font_manager.FontProperties` object.
- """
- parser = _make_fontconfig_parser()
- try:
- parse = parser.parseString(pattern)
- except ParseException as err:
- # explain becomes a plain method on pyparsing 3 (err.explain(0)).
- raise ValueError("\n" + ParseException.explain(err, 0)) from None
- parser.resetCache()
- props = {}
- if "families" in parse:
- props["family"] = [*map(_family_unescape, parse["families"])]
- if "sizes" in parse:
- props["size"] = [*parse["sizes"]]
- for prop in parse.get("properties", []):
- if len(prop) == 1:
- if prop[0] not in _CONSTANTS:
- _api.warn_deprecated(
- "3.7", message=f"Support for unknown constants "
- f"({prop[0]!r}) is deprecated since %(since)s and "
- f"will be removed %(removal)s.")
- continue
- prop = _CONSTANTS[prop[0]]
- k, *v = prop
- props.setdefault(k, []).extend(map(_value_unescape, v))
- return props
-
-
-def generate_fontconfig_pattern(d):
- """Convert a `.FontProperties` to a fontconfig pattern string."""
- kvs = [(k, getattr(d, f"get_{k}")())
- for k in ["style", "variant", "weight", "stretch", "file", "size"]]
- # Families is given first without a leading keyword. Other entries (which
- # are necessarily scalar) are given as key=value, skipping Nones.
- return (",".join(_family_escape(f) for f in d.get_family())
- + "".join(f":{k}={_value_escape(str(v))}"
- for k, v in kvs if v is not None))
diff --git a/contrib/python/matplotlib/py3/matplotlib/_image.pyi b/contrib/python/matplotlib/py3/matplotlib/_image.pyi
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_image.pyi
+++ /dev/null
diff --git a/contrib/python/matplotlib/py3/matplotlib/_internal_utils.py b/contrib/python/matplotlib/py3/matplotlib/_internal_utils.py
deleted file mode 100644
index 0223aa593b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_internal_utils.py
+++ /dev/null
@@ -1,64 +0,0 @@
-"""
-Internal debugging utilities, that are not expected to be used in the rest of
-the codebase.
-
-WARNING: Code in this module may change without prior notice!
-"""
-
-from io import StringIO
-from pathlib import Path
-import subprocess
-
-from matplotlib.transforms import TransformNode
-
-
-def graphviz_dump_transform(transform, dest, *, highlight=None):
- """
- Generate a graphical representation of the transform tree for *transform*
- using the :program:`dot` program (which this function depends on). The
- output format (png, dot, etc.) is determined from the suffix of *dest*.
-
- Parameters
- ----------
- transform : `~matplotlib.transform.Transform`
- The represented transform.
- dest : str
- Output filename. The extension must be one of the formats supported
- by :program:`dot`, e.g. png, svg, dot, ...
- (see https://www.graphviz.org/doc/info/output.html).
- highlight : list of `~matplotlib.transform.Transform` or None
- The transforms in the tree to be drawn in bold.
- If *None*, *transform* is highlighted.
- """
-
- if highlight is None:
- highlight = [transform]
- seen = set()
-
- def recurse(root, buf):
- if id(root) in seen:
- return
- seen.add(id(root))
- props = {}
- label = type(root).__name__
- if root._invalid:
- label = f'[{label}]'
- if root in highlight:
- props['style'] = 'bold'
- props['shape'] = 'box'
- props['label'] = '"%s"' % label
- props = ' '.join(map('{0[0]}={0[1]}'.format, props.items()))
- buf.write(f'{id(root)} [{props}];\n')
- for key, val in vars(root).items():
- if isinstance(val, TransformNode) and id(root) in val._parents:
- buf.write(f'"{id(root)}" -> "{id(val)}" '
- f'[label="{key}", fontsize=10];\n')
- recurse(val, buf)
-
- buf = StringIO()
- buf.write('digraph G {\n')
- recurse(transform, buf)
- buf.write('}\n')
- subprocess.run(
- ['dot', '-T', Path(dest).suffix[1:], '-o', dest],
- input=buf.getvalue().encode('utf-8'), check=True)
diff --git a/contrib/python/matplotlib/py3/matplotlib/_layoutgrid.py b/contrib/python/matplotlib/py3/matplotlib/_layoutgrid.py
deleted file mode 100644
index 8bef928311..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_layoutgrid.py
+++ /dev/null
@@ -1,547 +0,0 @@
-"""
-A layoutgrid is a nrows by ncols set of boxes, meant to be used by
-`._constrained_layout`, each box is analogous to a subplotspec element of
-a gridspec.
-
-Each box is defined by left[ncols], right[ncols], bottom[nrows] and top[nrows],
-and by two editable margins for each side. The main margin gets its value
-set by the size of ticklabels, titles, etc on each axes that is in the figure.
-The outer margin is the padding around the axes, and space for any
-colorbars.
-
-The "inner" widths and heights of these boxes are then constrained to be the
-same (relative the values of `width_ratios[ncols]` and `height_ratios[nrows]`).
-
-The layoutgrid is then constrained to be contained within a parent layoutgrid,
-its column(s) and row(s) specified when it is created.
-"""
-
-import itertools
-import kiwisolver as kiwi
-import logging
-import numpy as np
-
-import matplotlib as mpl
-import matplotlib.patches as mpatches
-from matplotlib.transforms import Bbox
-
-_log = logging.getLogger(__name__)
-
-
-class LayoutGrid:
- """
- Analogous to a gridspec, and contained in another LayoutGrid.
- """
-
- def __init__(self, parent=None, parent_pos=(0, 0),
- parent_inner=False, name='', ncols=1, nrows=1,
- h_pad=None, w_pad=None, width_ratios=None,
- height_ratios=None):
- Variable = kiwi.Variable
- self.parent_pos = parent_pos
- self.parent_inner = parent_inner
- self.name = name + seq_id()
- if isinstance(parent, LayoutGrid):
- self.name = f'{parent.name}.{self.name}'
- self.nrows = nrows
- self.ncols = ncols
- self.height_ratios = np.atleast_1d(height_ratios)
- if height_ratios is None:
- self.height_ratios = np.ones(nrows)
- self.width_ratios = np.atleast_1d(width_ratios)
- if width_ratios is None:
- self.width_ratios = np.ones(ncols)
-
- sn = self.name + '_'
- if not isinstance(parent, LayoutGrid):
- # parent can be a rect if not a LayoutGrid
- # allows specifying a rectangle to contain the layout.
- self.solver = kiwi.Solver()
- else:
- parent.add_child(self, *parent_pos)
- self.solver = parent.solver
- # keep track of artist associated w/ this layout. Can be none
- self.artists = np.empty((nrows, ncols), dtype=object)
- self.children = np.empty((nrows, ncols), dtype=object)
-
- self.margins = {}
- self.margin_vals = {}
- # all the boxes in each column share the same left/right margins:
- for todo in ['left', 'right', 'leftcb', 'rightcb']:
- # track the value so we can change only if a margin is larger
- # than the current value
- self.margin_vals[todo] = np.zeros(ncols)
-
- sol = self.solver
-
- self.lefts = [Variable(f'{sn}lefts[{i}]') for i in range(ncols)]
- self.rights = [Variable(f'{sn}rights[{i}]') for i in range(ncols)]
- for todo in ['left', 'right', 'leftcb', 'rightcb']:
- self.margins[todo] = [Variable(f'{sn}margins[{todo}][{i}]')
- for i in range(ncols)]
- for i in range(ncols):
- sol.addEditVariable(self.margins[todo][i], 'strong')
-
- for todo in ['bottom', 'top', 'bottomcb', 'topcb']:
- self.margins[todo] = np.empty((nrows), dtype=object)
- self.margin_vals[todo] = np.zeros(nrows)
-
- self.bottoms = [Variable(f'{sn}bottoms[{i}]') for i in range(nrows)]
- self.tops = [Variable(f'{sn}tops[{i}]') for i in range(nrows)]
- for todo in ['bottom', 'top', 'bottomcb', 'topcb']:
- self.margins[todo] = [Variable(f'{sn}margins[{todo}][{i}]')
- for i in range(nrows)]
- for i in range(nrows):
- sol.addEditVariable(self.margins[todo][i], 'strong')
-
- # set these margins to zero by default. They will be edited as
- # children are filled.
- self.reset_margins()
- self.add_constraints(parent)
-
- self.h_pad = h_pad
- self.w_pad = w_pad
-
- def __repr__(self):
- str = f'LayoutBox: {self.name:25s} {self.nrows}x{self.ncols},\n'
- for i in range(self.nrows):
- for j in range(self.ncols):
- str += f'{i}, {j}: '\
- f'L{self.lefts[j].value():1.3f}, ' \
- f'B{self.bottoms[i].value():1.3f}, ' \
- f'R{self.rights[j].value():1.3f}, ' \
- f'T{self.tops[i].value():1.3f}, ' \
- f'ML{self.margins["left"][j].value():1.3f}, ' \
- f'MR{self.margins["right"][j].value():1.3f}, ' \
- f'MB{self.margins["bottom"][i].value():1.3f}, ' \
- f'MT{self.margins["top"][i].value():1.3f}, \n'
- return str
-
- def reset_margins(self):
- """
- Reset all the margins to zero. Must do this after changing
- figure size, for instance, because the relative size of the
- axes labels etc changes.
- """
- for todo in ['left', 'right', 'bottom', 'top',
- 'leftcb', 'rightcb', 'bottomcb', 'topcb']:
- self.edit_margins(todo, 0.0)
-
- def add_constraints(self, parent):
- # define self-consistent constraints
- self.hard_constraints()
- # define relationship with parent layoutgrid:
- self.parent_constraints(parent)
- # define relative widths of the grid cells to each other
- # and stack horizontally and vertically.
- self.grid_constraints()
-
- def hard_constraints(self):
- """
- These are the redundant constraints, plus ones that make the
- rest of the code easier.
- """
- for i in range(self.ncols):
- hc = [self.rights[i] >= self.lefts[i],
- (self.rights[i] - self.margins['right'][i] -
- self.margins['rightcb'][i] >=
- self.lefts[i] - self.margins['left'][i] -
- self.margins['leftcb'][i])
- ]
- for c in hc:
- self.solver.addConstraint(c | 'required')
-
- for i in range(self.nrows):
- hc = [self.tops[i] >= self.bottoms[i],
- (self.tops[i] - self.margins['top'][i] -
- self.margins['topcb'][i] >=
- self.bottoms[i] - self.margins['bottom'][i] -
- self.margins['bottomcb'][i])
- ]
- for c in hc:
- self.solver.addConstraint(c | 'required')
-
- def add_child(self, child, i=0, j=0):
- # np.ix_ returns the cross product of i and j indices
- self.children[np.ix_(np.atleast_1d(i), np.atleast_1d(j))] = child
-
- def parent_constraints(self, parent):
- # constraints that are due to the parent...
- # i.e. the first column's left is equal to the
- # parent's left, the last column right equal to the
- # parent's right...
- if not isinstance(parent, LayoutGrid):
- # specify a rectangle in figure coordinates
- hc = [self.lefts[0] == parent[0],
- self.rights[-1] == parent[0] + parent[2],
- # top and bottom reversed order...
- self.tops[0] == parent[1] + parent[3],
- self.bottoms[-1] == parent[1]]
- else:
- rows, cols = self.parent_pos
- rows = np.atleast_1d(rows)
- cols = np.atleast_1d(cols)
-
- left = parent.lefts[cols[0]]
- right = parent.rights[cols[-1]]
- top = parent.tops[rows[0]]
- bottom = parent.bottoms[rows[-1]]
- if self.parent_inner:
- # the layout grid is contained inside the inner
- # grid of the parent.
- left += parent.margins['left'][cols[0]]
- left += parent.margins['leftcb'][cols[0]]
- right -= parent.margins['right'][cols[-1]]
- right -= parent.margins['rightcb'][cols[-1]]
- top -= parent.margins['top'][rows[0]]
- top -= parent.margins['topcb'][rows[0]]
- bottom += parent.margins['bottom'][rows[-1]]
- bottom += parent.margins['bottomcb'][rows[-1]]
- hc = [self.lefts[0] == left,
- self.rights[-1] == right,
- # from top to bottom
- self.tops[0] == top,
- self.bottoms[-1] == bottom]
- for c in hc:
- self.solver.addConstraint(c | 'required')
-
- def grid_constraints(self):
- # constrain the ratio of the inner part of the grids
- # to be the same (relative to width_ratios)
-
- # constrain widths:
- w = (self.rights[0] - self.margins['right'][0] -
- self.margins['rightcb'][0])
- w = (w - self.lefts[0] - self.margins['left'][0] -
- self.margins['leftcb'][0])
- w0 = w / self.width_ratios[0]
- # from left to right
- for i in range(1, self.ncols):
- w = (self.rights[i] - self.margins['right'][i] -
- self.margins['rightcb'][i])
- w = (w - self.lefts[i] - self.margins['left'][i] -
- self.margins['leftcb'][i])
- c = (w == w0 * self.width_ratios[i])
- self.solver.addConstraint(c | 'strong')
- # constrain the grid cells to be directly next to each other.
- c = (self.rights[i - 1] == self.lefts[i])
- self.solver.addConstraint(c | 'strong')
-
- # constrain heights:
- h = self.tops[0] - self.margins['top'][0] - self.margins['topcb'][0]
- h = (h - self.bottoms[0] - self.margins['bottom'][0] -
- self.margins['bottomcb'][0])
- h0 = h / self.height_ratios[0]
- # from top to bottom:
- for i in range(1, self.nrows):
- h = (self.tops[i] - self.margins['top'][i] -
- self.margins['topcb'][i])
- h = (h - self.bottoms[i] - self.margins['bottom'][i] -
- self.margins['bottomcb'][i])
- c = (h == h0 * self.height_ratios[i])
- self.solver.addConstraint(c | 'strong')
- # constrain the grid cells to be directly above each other.
- c = (self.bottoms[i - 1] == self.tops[i])
- self.solver.addConstraint(c | 'strong')
-
- # Margin editing: The margins are variable and meant to
- # contain things of a fixed size like axes labels, tick labels, titles
- # etc
- def edit_margin(self, todo, size, cell):
- """
- Change the size of the margin for one cell.
-
- Parameters
- ----------
- todo : string (one of 'left', 'right', 'bottom', 'top')
- margin to alter.
-
- size : float
- Size of the margin. If it is larger than the existing minimum it
- updates the margin size. Fraction of figure size.
-
- cell : int
- Cell column or row to edit.
- """
- self.solver.suggestValue(self.margins[todo][cell], size)
- self.margin_vals[todo][cell] = size
-
- def edit_margin_min(self, todo, size, cell=0):
- """
- Change the minimum size of the margin for one cell.
-
- Parameters
- ----------
- todo : string (one of 'left', 'right', 'bottom', 'top')
- margin to alter.
-
- size : float
- Minimum size of the margin . If it is larger than the
- existing minimum it updates the margin size. Fraction of
- figure size.
-
- cell : int
- Cell column or row to edit.
- """
-
- if size > self.margin_vals[todo][cell]:
- self.edit_margin(todo, size, cell)
-
- def edit_margins(self, todo, size):
- """
- Change the size of all the margin of all the cells in the layout grid.
-
- Parameters
- ----------
- todo : string (one of 'left', 'right', 'bottom', 'top')
- margin to alter.
-
- size : float
- Size to set the margins. Fraction of figure size.
- """
-
- for i in range(len(self.margin_vals[todo])):
- self.edit_margin(todo, size, i)
-
- def edit_all_margins_min(self, todo, size):
- """
- Change the minimum size of all the margin of all
- the cells in the layout grid.
-
- Parameters
- ----------
- todo : {'left', 'right', 'bottom', 'top'}
- The margin to alter.
-
- size : float
- Minimum size of the margin. If it is larger than the
- existing minimum it updates the margin size. Fraction of
- figure size.
- """
-
- for i in range(len(self.margin_vals[todo])):
- self.edit_margin_min(todo, size, i)
-
- def edit_outer_margin_mins(self, margin, ss):
- """
- Edit all four margin minimums in one statement.
-
- Parameters
- ----------
- margin : dict
- size of margins in a dict with keys 'left', 'right', 'bottom',
- 'top'
-
- ss : SubplotSpec
- defines the subplotspec these margins should be applied to
- """
-
- self.edit_margin_min('left', margin['left'], ss.colspan.start)
- self.edit_margin_min('leftcb', margin['leftcb'], ss.colspan.start)
- self.edit_margin_min('right', margin['right'], ss.colspan.stop - 1)
- self.edit_margin_min('rightcb', margin['rightcb'], ss.colspan.stop - 1)
- # rows are from the top down:
- self.edit_margin_min('top', margin['top'], ss.rowspan.start)
- self.edit_margin_min('topcb', margin['topcb'], ss.rowspan.start)
- self.edit_margin_min('bottom', margin['bottom'], ss.rowspan.stop - 1)
- self.edit_margin_min('bottomcb', margin['bottomcb'],
- ss.rowspan.stop - 1)
-
- def get_margins(self, todo, col):
- """Return the margin at this position"""
- return self.margin_vals[todo][col]
-
- def get_outer_bbox(self, rows=0, cols=0):
- """
- Return the outer bounding box of the subplot specs
- given by rows and cols. rows and cols can be spans.
- """
- rows = np.atleast_1d(rows)
- cols = np.atleast_1d(cols)
-
- bbox = Bbox.from_extents(
- self.lefts[cols[0]].value(),
- self.bottoms[rows[-1]].value(),
- self.rights[cols[-1]].value(),
- self.tops[rows[0]].value())
- return bbox
-
- def get_inner_bbox(self, rows=0, cols=0):
- """
- Return the inner bounding box of the subplot specs
- given by rows and cols. rows and cols can be spans.
- """
- rows = np.atleast_1d(rows)
- cols = np.atleast_1d(cols)
-
- bbox = Bbox.from_extents(
- (self.lefts[cols[0]].value() +
- self.margins['left'][cols[0]].value() +
- self.margins['leftcb'][cols[0]].value()),
- (self.bottoms[rows[-1]].value() +
- self.margins['bottom'][rows[-1]].value() +
- self.margins['bottomcb'][rows[-1]].value()),
- (self.rights[cols[-1]].value() -
- self.margins['right'][cols[-1]].value() -
- self.margins['rightcb'][cols[-1]].value()),
- (self.tops[rows[0]].value() -
- self.margins['top'][rows[0]].value() -
- self.margins['topcb'][rows[0]].value())
- )
- return bbox
-
- def get_bbox_for_cb(self, rows=0, cols=0):
- """
- Return the bounding box that includes the
- decorations but, *not* the colorbar...
- """
- rows = np.atleast_1d(rows)
- cols = np.atleast_1d(cols)
-
- bbox = Bbox.from_extents(
- (self.lefts[cols[0]].value() +
- self.margins['leftcb'][cols[0]].value()),
- (self.bottoms[rows[-1]].value() +
- self.margins['bottomcb'][rows[-1]].value()),
- (self.rights[cols[-1]].value() -
- self.margins['rightcb'][cols[-1]].value()),
- (self.tops[rows[0]].value() -
- self.margins['topcb'][rows[0]].value())
- )
- return bbox
-
- def get_left_margin_bbox(self, rows=0, cols=0):
- """
- Return the left margin bounding box of the subplot specs
- given by rows and cols. rows and cols can be spans.
- """
- rows = np.atleast_1d(rows)
- cols = np.atleast_1d(cols)
-
- bbox = Bbox.from_extents(
- (self.lefts[cols[0]].value() +
- self.margins['leftcb'][cols[0]].value()),
- (self.bottoms[rows[-1]].value()),
- (self.lefts[cols[0]].value() +
- self.margins['leftcb'][cols[0]].value() +
- self.margins['left'][cols[0]].value()),
- (self.tops[rows[0]].value()))
- return bbox
-
- def get_bottom_margin_bbox(self, rows=0, cols=0):
- """
- Return the left margin bounding box of the subplot specs
- given by rows and cols. rows and cols can be spans.
- """
- rows = np.atleast_1d(rows)
- cols = np.atleast_1d(cols)
-
- bbox = Bbox.from_extents(
- (self.lefts[cols[0]].value()),
- (self.bottoms[rows[-1]].value() +
- self.margins['bottomcb'][rows[-1]].value()),
- (self.rights[cols[-1]].value()),
- (self.bottoms[rows[-1]].value() +
- self.margins['bottom'][rows[-1]].value() +
- self.margins['bottomcb'][rows[-1]].value()
- ))
- return bbox
-
- def get_right_margin_bbox(self, rows=0, cols=0):
- """
- Return the left margin bounding box of the subplot specs
- given by rows and cols. rows and cols can be spans.
- """
- rows = np.atleast_1d(rows)
- cols = np.atleast_1d(cols)
-
- bbox = Bbox.from_extents(
- (self.rights[cols[-1]].value() -
- self.margins['right'][cols[-1]].value() -
- self.margins['rightcb'][cols[-1]].value()),
- (self.bottoms[rows[-1]].value()),
- (self.rights[cols[-1]].value() -
- self.margins['rightcb'][cols[-1]].value()),
- (self.tops[rows[0]].value()))
- return bbox
-
- def get_top_margin_bbox(self, rows=0, cols=0):
- """
- Return the left margin bounding box of the subplot specs
- given by rows and cols. rows and cols can be spans.
- """
- rows = np.atleast_1d(rows)
- cols = np.atleast_1d(cols)
-
- bbox = Bbox.from_extents(
- (self.lefts[cols[0]].value()),
- (self.tops[rows[0]].value() -
- self.margins['topcb'][rows[0]].value()),
- (self.rights[cols[-1]].value()),
- (self.tops[rows[0]].value() -
- self.margins['topcb'][rows[0]].value() -
- self.margins['top'][rows[0]].value()))
- return bbox
-
- def update_variables(self):
- """
- Update the variables for the solver attached to this layoutgrid.
- """
- self.solver.updateVariables()
-
-_layoutboxobjnum = itertools.count()
-
-
-def seq_id():
- """Generate a short sequential id for layoutbox objects."""
- return '%06d' % next(_layoutboxobjnum)
-
-
-def plot_children(fig, lg=None, level=0):
- """Simple plotting to show where boxes are."""
- if lg is None:
- _layoutgrids = fig.get_layout_engine().execute(fig)
- lg = _layoutgrids[fig]
- colors = mpl.rcParams["axes.prop_cycle"].by_key()["color"]
- col = colors[level]
- for i in range(lg.nrows):
- for j in range(lg.ncols):
- bb = lg.get_outer_bbox(rows=i, cols=j)
- fig.add_artist(
- mpatches.Rectangle(bb.p0, bb.width, bb.height, linewidth=1,
- edgecolor='0.7', facecolor='0.7',
- alpha=0.2, transform=fig.transFigure,
- zorder=-3))
- bbi = lg.get_inner_bbox(rows=i, cols=j)
- fig.add_artist(
- mpatches.Rectangle(bbi.p0, bbi.width, bbi.height, linewidth=2,
- edgecolor=col, facecolor='none',
- transform=fig.transFigure, zorder=-2))
-
- bbi = lg.get_left_margin_bbox(rows=i, cols=j)
- fig.add_artist(
- mpatches.Rectangle(bbi.p0, bbi.width, bbi.height, linewidth=0,
- edgecolor='none', alpha=0.2,
- facecolor=[0.5, 0.7, 0.5],
- transform=fig.transFigure, zorder=-2))
- bbi = lg.get_right_margin_bbox(rows=i, cols=j)
- fig.add_artist(
- mpatches.Rectangle(bbi.p0, bbi.width, bbi.height, linewidth=0,
- edgecolor='none', alpha=0.2,
- facecolor=[0.7, 0.5, 0.5],
- transform=fig.transFigure, zorder=-2))
- bbi = lg.get_bottom_margin_bbox(rows=i, cols=j)
- fig.add_artist(
- mpatches.Rectangle(bbi.p0, bbi.width, bbi.height, linewidth=0,
- edgecolor='none', alpha=0.2,
- facecolor=[0.5, 0.5, 0.7],
- transform=fig.transFigure, zorder=-2))
- bbi = lg.get_top_margin_bbox(rows=i, cols=j)
- fig.add_artist(
- mpatches.Rectangle(bbi.p0, bbi.width, bbi.height, linewidth=0,
- edgecolor='none', alpha=0.2,
- facecolor=[0.7, 0.2, 0.7],
- transform=fig.transFigure, zorder=-2))
- for ch in lg.children.flat:
- if ch is not None:
- plot_children(fig, ch, level=level+1)
diff --git a/contrib/python/matplotlib/py3/matplotlib/_mathtext.py b/contrib/python/matplotlib/py3/matplotlib/_mathtext.py
deleted file mode 100644
index b23cb67116..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_mathtext.py
+++ /dev/null
@@ -1,2851 +0,0 @@
-"""
-Implementation details for :mod:`.mathtext`.
-"""
-
-from __future__ import annotations
-
-import abc
-import copy
-import enum
-import functools
-import logging
-import os
-import re
-import types
-import unicodedata
-import string
-import typing as T
-from typing import NamedTuple
-
-import numpy as np
-from pyparsing import (
- Empty, Forward, Literal, NotAny, oneOf, OneOrMore, Optional,
- ParseBaseException, ParseException, ParseExpression, ParseFatalException,
- ParserElement, ParseResults, QuotedString, Regex, StringEnd, ZeroOrMore,
- pyparsing_common, Group)
-
-import matplotlib as mpl
-from . import cbook
-from ._mathtext_data import (
- latex_to_bakoma, stix_glyph_fixes, stix_virtual_fonts, tex2uni)
-from .font_manager import FontProperties, findfont, get_font
-from .ft2font import FT2Font, FT2Image, KERNING_DEFAULT
-
-from packaging.version import parse as parse_version
-from pyparsing import __version__ as pyparsing_version
-if parse_version(pyparsing_version).major < 3:
- from pyparsing import nestedExpr as nested_expr
-else:
- from pyparsing import nested_expr
-
-if T.TYPE_CHECKING:
- from collections.abc import Iterable
- from .ft2font import Glyph
-
-ParserElement.enablePackrat()
-_log = logging.getLogger("matplotlib.mathtext")
-
-
-##############################################################################
-# FONTS
-
-
-def get_unicode_index(symbol: str) -> int: # Publicly exported.
- r"""
- Return the integer index (from the Unicode table) of *symbol*.
-
- Parameters
- ----------
- symbol : str
- A single (Unicode) character, a TeX command (e.g. r'\pi') or a Type1
- symbol name (e.g. 'phi').
- """
- try: # This will succeed if symbol is a single Unicode char
- return ord(symbol)
- except TypeError:
- pass
- try: # Is symbol a TeX symbol (i.e. \alpha)
- return tex2uni[symbol.strip("\\")]
- except KeyError as err:
- raise ValueError(
- f"{symbol!r} is not a valid Unicode character or TeX/Type1 symbol"
- ) from err
-
-
-class VectorParse(NamedTuple):
- """
- The namedtuple type returned by ``MathTextParser("path").parse(...)``.
-
- Attributes
- ----------
- width, height, depth : float
- The global metrics.
- glyphs : list
- The glyphs including their positions.
- rect : list
- The list of rectangles.
- """
- width: float
- height: float
- depth: float
- glyphs: list[tuple[FT2Font, float, int, float, float]]
- rects: list[tuple[float, float, float, float]]
-
-VectorParse.__module__ = "matplotlib.mathtext"
-
-
-class RasterParse(NamedTuple):
- """
- The namedtuple type returned by ``MathTextParser("agg").parse(...)``.
-
- Attributes
- ----------
- ox, oy : float
- The offsets are always zero.
- width, height, depth : float
- The global metrics.
- image : FT2Image
- A raster image.
- """
- ox: float
- oy: float
- width: float
- height: float
- depth: float
- image: FT2Image
-
-RasterParse.__module__ = "matplotlib.mathtext"
-
-
-class Output:
- r"""
- Result of `ship`\ping a box: lists of positioned glyphs and rectangles.
-
- This class is not exposed to end users, but converted to a `VectorParse` or
- a `RasterParse` by `.MathTextParser.parse`.
- """
-
- def __init__(self, box: Box):
- self.box = box
- self.glyphs: list[tuple[float, float, FontInfo]] = [] # (ox, oy, info)
- self.rects: list[tuple[float, float, float, float]] = [] # (x1, y1, x2, y2)
-
- def to_vector(self) -> VectorParse:
- w, h, d = map(
- np.ceil, [self.box.width, self.box.height, self.box.depth])
- gs = [(info.font, info.fontsize, info.num, ox, h - oy + info.offset)
- for ox, oy, info in self.glyphs]
- rs = [(x1, h - y2, x2 - x1, y2 - y1)
- for x1, y1, x2, y2 in self.rects]
- return VectorParse(w, h + d, d, gs, rs)
-
- def to_raster(self, *, antialiased: bool) -> RasterParse:
- # Metrics y's and mathtext y's are oriented in opposite directions,
- # hence the switch between ymin and ymax.
- xmin = min([*[ox + info.metrics.xmin for ox, oy, info in self.glyphs],
- *[x1 for x1, y1, x2, y2 in self.rects], 0]) - 1
- ymin = min([*[oy - info.metrics.ymax for ox, oy, info in self.glyphs],
- *[y1 for x1, y1, x2, y2 in self.rects], 0]) - 1
- xmax = max([*[ox + info.metrics.xmax for ox, oy, info in self.glyphs],
- *[x2 for x1, y1, x2, y2 in self.rects], 0]) + 1
- ymax = max([*[oy - info.metrics.ymin for ox, oy, info in self.glyphs],
- *[y2 for x1, y1, x2, y2 in self.rects], 0]) + 1
- w = xmax - xmin
- h = ymax - ymin - self.box.depth
- d = ymax - ymin - self.box.height
- image = FT2Image(np.ceil(w), np.ceil(h + max(d, 0)))
-
- # Ideally, we could just use self.glyphs and self.rects here, shifting
- # their coordinates by (-xmin, -ymin), but this yields slightly
- # different results due to floating point slop; shipping twice is the
- # old approach and keeps baseline images backcompat.
- shifted = ship(self.box, (-xmin, -ymin))
-
- for ox, oy, info in shifted.glyphs:
- info.font.draw_glyph_to_bitmap(
- image, ox, oy - info.metrics.iceberg, info.glyph,
- antialiased=antialiased)
- for x1, y1, x2, y2 in shifted.rects:
- height = max(int(y2 - y1) - 1, 0)
- if height == 0:
- center = (y2 + y1) / 2
- y = int(center - (height + 1) / 2)
- else:
- y = int(y1)
- image.draw_rect_filled(int(x1), y, np.ceil(x2), y + height)
- return RasterParse(0, 0, w, h + d, d, image)
-
-
-class FontMetrics(NamedTuple):
- """
- Metrics of a font.
-
- Attributes
- ----------
- advance : float
- The advance distance (in points) of the glyph.
- height : float
- The height of the glyph in points.
- width : float
- The width of the glyph in points.
- xmin, xmax, ymin, ymax : float
- The ink rectangle of the glyph.
- iceberg : float
- The distance from the baseline to the top of the glyph. (This corresponds to
- TeX's definition of "height".)
- slanted : bool
- Whether the glyph should be considered as "slanted" (currently used for kerning
- sub/superscripts).
- """
- advance: float
- height: float
- width: float
- xmin: float
- xmax: float
- ymin: float
- ymax: float
- iceberg: float
- slanted: bool
-
-
-class FontInfo(NamedTuple):
- font: FT2Font
- fontsize: float
- postscript_name: str
- metrics: FontMetrics
- num: int
- glyph: Glyph
- offset: float
-
-
-class Fonts(abc.ABC):
- """
- An abstract base class for a system of fonts to use for mathtext.
-
- The class must be able to take symbol keys and font file names and
- return the character metrics. It also delegates to a backend class
- to do the actual drawing.
- """
-
- def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int):
- """
- Parameters
- ----------
- default_font_prop : `~.font_manager.FontProperties`
- The default non-math font, or the base font for Unicode (generic)
- font rendering.
- load_glyph_flags : int
- Flags passed to the glyph loader (e.g. ``FT_Load_Glyph`` and
- ``FT_Load_Char`` for FreeType-based fonts).
- """
- self.default_font_prop = default_font_prop
- self.load_glyph_flags = load_glyph_flags
-
- def get_kern(self, font1: str, fontclass1: str, sym1: str, fontsize1: float,
- font2: str, fontclass2: str, sym2: str, fontsize2: float,
- dpi: float) -> float:
- """
- Get the kerning distance for font between *sym1* and *sym2*.
-
- See `~.Fonts.get_metrics` for a detailed description of the parameters.
- """
- return 0.
-
- def _get_font(self, font: str) -> FT2Font:
- raise NotImplementedError
-
- def _get_info(self, font: str, font_class: str, sym: str, fontsize: float,
- dpi: float) -> FontInfo:
- raise NotImplementedError
-
- def get_metrics(self, font: str, font_class: str, sym: str, fontsize: float,
- dpi: float) -> FontMetrics:
- r"""
- Parameters
- ----------
- font : str
- One of the TeX font names: "tt", "it", "rm", "cal", "sf", "bf",
- "default", "regular", "bb", "frak", "scr". "default" and "regular"
- are synonyms and use the non-math font.
- font_class : str
- One of the TeX font names (as for *font*), but **not** "bb",
- "frak", or "scr". This is used to combine two font classes. The
- only supported combination currently is ``get_metrics("frak", "bf",
- ...)``.
- sym : str
- A symbol in raw TeX form, e.g., "1", "x", or "\sigma".
- fontsize : float
- Font size in points.
- dpi : float
- Rendering dots-per-inch.
-
- Returns
- -------
- FontMetrics
- """
- info = self._get_info(font, font_class, sym, fontsize, dpi)
- return info.metrics
-
- def render_glyph(self, output: Output, ox: float, oy: float, font: str,
- font_class: str, sym: str, fontsize: float, dpi: float) -> None:
- """
- At position (*ox*, *oy*), draw the glyph specified by the remaining
- parameters (see `get_metrics` for their detailed description).
- """
- info = self._get_info(font, font_class, sym, fontsize, dpi)
- output.glyphs.append((ox, oy, info))
-
- def render_rect_filled(self, output: Output,
- x1: float, y1: float, x2: float, y2: float) -> None:
- """
- Draw a filled rectangle from (*x1*, *y1*) to (*x2*, *y2*).
- """
- output.rects.append((x1, y1, x2, y2))
-
- def get_xheight(self, font: str, fontsize: float, dpi: float) -> float:
- """
- Get the xheight for the given *font* and *fontsize*.
- """
- raise NotImplementedError()
-
- def get_underline_thickness(self, font: str, fontsize: float, dpi: float) -> float:
- """
- Get the line thickness that matches the given font. Used as a
- base unit for drawing lines such as in a fraction or radical.
- """
- raise NotImplementedError()
-
- def get_sized_alternatives_for_symbol(self, fontname: str,
- sym: str) -> list[tuple[str, str]]:
- """
- Override if your font provides multiple sizes of the same
- symbol. Should return a list of symbols matching *sym* in
- various sizes. The expression renderer will select the most
- appropriate size for a given situation from this list.
- """
- return [(fontname, sym)]
-
-
-class TruetypeFonts(Fonts, metaclass=abc.ABCMeta):
- """
- A generic base class for all font setups that use Truetype fonts
- (through FT2Font).
- """
-
- def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int):
- super().__init__(default_font_prop, load_glyph_flags)
- # Per-instance cache.
- self._get_info = functools.cache(self._get_info) # type: ignore[method-assign]
- self._fonts = {}
- self.fontmap: dict[str | int, str] = {}
-
- filename = findfont(self.default_font_prop)
- default_font = get_font(filename)
- self._fonts['default'] = default_font
- self._fonts['regular'] = default_font
-
- def _get_font(self, font: str | int) -> FT2Font:
- if font in self.fontmap:
- basename = self.fontmap[font]
- else:
- # NOTE: An int is only passed by subclasses which have placed int keys into
- # `self.fontmap`, so we must cast this to confirm it to typing.
- basename = T.cast(str, font)
- cached_font = self._fonts.get(basename)
- if cached_font is None and os.path.exists(basename):
- cached_font = get_font(basename)
- self._fonts[basename] = cached_font
- self._fonts[cached_font.postscript_name] = cached_font
- self._fonts[cached_font.postscript_name.lower()] = cached_font
- return T.cast(FT2Font, cached_font) # FIXME: Not sure this is guaranteed.
-
- def _get_offset(self, font: FT2Font, glyph: Glyph, fontsize: float,
- dpi: float) -> float:
- if font.postscript_name == 'Cmex10':
- return (glyph.height / 64 / 2) + (fontsize/3 * dpi/72)
- return 0.
-
- def _get_glyph(self, fontname: str, font_class: str,
- sym: str) -> tuple[FT2Font, int, bool]:
- raise NotImplementedError
-
- # The return value of _get_info is cached per-instance.
- def _get_info(self, fontname: str, font_class: str, sym: str, fontsize: float,
- dpi: float) -> FontInfo:
- font, num, slanted = self._get_glyph(fontname, font_class, sym)
- font.set_size(fontsize, dpi)
- glyph = font.load_char(num, flags=self.load_glyph_flags)
-
- xmin, ymin, xmax, ymax = [val/64.0 for val in glyph.bbox]
- offset = self._get_offset(font, glyph, fontsize, dpi)
- metrics = FontMetrics(
- advance = glyph.linearHoriAdvance/65536.0,
- height = glyph.height/64.0,
- width = glyph.width/64.0,
- xmin = xmin,
- xmax = xmax,
- ymin = ymin+offset,
- ymax = ymax+offset,
- # iceberg is the equivalent of TeX's "height"
- iceberg = glyph.horiBearingY/64.0 + offset,
- slanted = slanted
- )
-
- return FontInfo(
- font = font,
- fontsize = fontsize,
- postscript_name = font.postscript_name,
- metrics = metrics,
- num = num,
- glyph = glyph,
- offset = offset
- )
-
- def get_xheight(self, fontname: str, fontsize: float, dpi: float) -> float:
- font = self._get_font(fontname)
- font.set_size(fontsize, dpi)
- pclt = font.get_sfnt_table('pclt')
- if pclt is None:
- # Some fonts don't store the xHeight, so we do a poor man's xHeight
- metrics = self.get_metrics(
- fontname, mpl.rcParams['mathtext.default'], 'x', fontsize, dpi)
- return metrics.iceberg
- xHeight = (pclt['xHeight'] / 64.0) * (fontsize / 12.0) * (dpi / 100.0)
- return xHeight
-
- def get_underline_thickness(self, font: str, fontsize: float, dpi: float) -> float:
- # This function used to grab underline thickness from the font
- # metrics, but that information is just too un-reliable, so it
- # is now hardcoded.
- return ((0.75 / 12.0) * fontsize * dpi) / 72.0
-
- def get_kern(self, font1: str, fontclass1: str, sym1: str, fontsize1: float,
- font2: str, fontclass2: str, sym2: str, fontsize2: float,
- dpi: float) -> float:
- if font1 == font2 and fontsize1 == fontsize2:
- info1 = self._get_info(font1, fontclass1, sym1, fontsize1, dpi)
- info2 = self._get_info(font2, fontclass2, sym2, fontsize2, dpi)
- font = info1.font
- return font.get_kerning(info1.num, info2.num, KERNING_DEFAULT) / 64
- return super().get_kern(font1, fontclass1, sym1, fontsize1,
- font2, fontclass2, sym2, fontsize2, dpi)
-
-
-class BakomaFonts(TruetypeFonts):
- """
- Use the Bakoma TrueType fonts for rendering.
-
- Symbols are strewn about a number of font files, each of which has
- its own proprietary 8-bit encoding.
- """
- _fontmap = {
- 'cal': 'cmsy10',
- 'rm': 'cmr10',
- 'tt': 'cmtt10',
- 'it': 'cmmi10',
- 'bf': 'cmb10',
- 'sf': 'cmss10',
- 'ex': 'cmex10',
- }
-
- def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int):
- self._stix_fallback = StixFonts(default_font_prop, load_glyph_flags)
-
- super().__init__(default_font_prop, load_glyph_flags)
- for key, val in self._fontmap.items():
- fullpath = findfont(val)
- self.fontmap[key] = fullpath
- self.fontmap[val] = fullpath
-
- _slanted_symbols = set(r"\int \oint".split())
-
- def _get_glyph(self, fontname: str, font_class: str,
- sym: str) -> tuple[FT2Font, int, bool]:
- font = None
- if fontname in self.fontmap and sym in latex_to_bakoma:
- basename, num = latex_to_bakoma[sym]
- slanted = (basename == "cmmi10") or sym in self._slanted_symbols
- font = self._get_font(basename)
- elif len(sym) == 1:
- slanted = (fontname == "it")
- font = self._get_font(fontname)
- if font is not None:
- num = ord(sym)
- if font is not None and font.get_char_index(num) != 0:
- return font, num, slanted
- else:
- return self._stix_fallback._get_glyph(fontname, font_class, sym)
-
- # The Bakoma fonts contain many pre-sized alternatives for the
- # delimiters. The AutoSizedChar class will use these alternatives
- # and select the best (closest sized) glyph.
- _size_alternatives = {
- '(': [('rm', '('), ('ex', '\xa1'), ('ex', '\xb3'),
- ('ex', '\xb5'), ('ex', '\xc3')],
- ')': [('rm', ')'), ('ex', '\xa2'), ('ex', '\xb4'),
- ('ex', '\xb6'), ('ex', '\x21')],
- '{': [('cal', '{'), ('ex', '\xa9'), ('ex', '\x6e'),
- ('ex', '\xbd'), ('ex', '\x28')],
- '}': [('cal', '}'), ('ex', '\xaa'), ('ex', '\x6f'),
- ('ex', '\xbe'), ('ex', '\x29')],
- # The fourth size of '[' is mysteriously missing from the BaKoMa
- # font, so I've omitted it for both '[' and ']'
- '[': [('rm', '['), ('ex', '\xa3'), ('ex', '\x68'),
- ('ex', '\x22')],
- ']': [('rm', ']'), ('ex', '\xa4'), ('ex', '\x69'),
- ('ex', '\x23')],
- r'\lfloor': [('ex', '\xa5'), ('ex', '\x6a'),
- ('ex', '\xb9'), ('ex', '\x24')],
- r'\rfloor': [('ex', '\xa6'), ('ex', '\x6b'),
- ('ex', '\xba'), ('ex', '\x25')],
- r'\lceil': [('ex', '\xa7'), ('ex', '\x6c'),
- ('ex', '\xbb'), ('ex', '\x26')],
- r'\rceil': [('ex', '\xa8'), ('ex', '\x6d'),
- ('ex', '\xbc'), ('ex', '\x27')],
- r'\langle': [('ex', '\xad'), ('ex', '\x44'),
- ('ex', '\xbf'), ('ex', '\x2a')],
- r'\rangle': [('ex', '\xae'), ('ex', '\x45'),
- ('ex', '\xc0'), ('ex', '\x2b')],
- r'\__sqrt__': [('ex', '\x70'), ('ex', '\x71'),
- ('ex', '\x72'), ('ex', '\x73')],
- r'\backslash': [('ex', '\xb2'), ('ex', '\x2f'),
- ('ex', '\xc2'), ('ex', '\x2d')],
- r'/': [('rm', '/'), ('ex', '\xb1'), ('ex', '\x2e'),
- ('ex', '\xcb'), ('ex', '\x2c')],
- r'\widehat': [('rm', '\x5e'), ('ex', '\x62'), ('ex', '\x63'),
- ('ex', '\x64')],
- r'\widetilde': [('rm', '\x7e'), ('ex', '\x65'), ('ex', '\x66'),
- ('ex', '\x67')],
- r'<': [('cal', 'h'), ('ex', 'D')],
- r'>': [('cal', 'i'), ('ex', 'E')]
- }
-
- for alias, target in [(r'\leftparen', '('),
- (r'\rightparent', ')'),
- (r'\leftbrace', '{'),
- (r'\rightbrace', '}'),
- (r'\leftbracket', '['),
- (r'\rightbracket', ']'),
- (r'\{', '{'),
- (r'\}', '}'),
- (r'\[', '['),
- (r'\]', ']')]:
- _size_alternatives[alias] = _size_alternatives[target]
-
- def get_sized_alternatives_for_symbol(self, fontname: str,
- sym: str) -> list[tuple[str, str]]:
- return self._size_alternatives.get(sym, [(fontname, sym)])
-
-
-class UnicodeFonts(TruetypeFonts):
- """
- An abstract base class for handling Unicode fonts.
-
- While some reasonably complete Unicode fonts (such as DejaVu) may
- work in some situations, the only Unicode font I'm aware of with a
- complete set of math symbols is STIX.
-
- This class will "fallback" on the Bakoma fonts when a required
- symbol cannot be found in the font.
- """
-
- # Some glyphs are not present in the `cmr10` font, and must be brought in
- # from `cmsy10`. Map the Unicode indices of those glyphs to the indices at
- # which they are found in `cmsy10`.
- _cmr10_substitutions = {
- 0x00D7: 0x00A3, # Multiplication sign.
- 0x2212: 0x00A1, # Minus sign.
- }
-
- def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int):
- # This must come first so the backend's owner is set correctly
- fallback_rc = mpl.rcParams['mathtext.fallback']
- font_cls: type[TruetypeFonts] | None = {
- 'stix': StixFonts,
- 'stixsans': StixSansFonts,
- 'cm': BakomaFonts
- }.get(fallback_rc)
- self._fallback_font = (font_cls(default_font_prop, load_glyph_flags)
- if font_cls else None)
-
- super().__init__(default_font_prop, load_glyph_flags)
- for texfont in "cal rm tt it bf sf bfit".split():
- prop = mpl.rcParams['mathtext.' + texfont]
- font = findfont(prop)
- self.fontmap[texfont] = font
- prop = FontProperties('cmex10')
- font = findfont(prop)
- self.fontmap['ex'] = font
-
- # include STIX sized alternatives for glyphs if fallback is STIX
- if isinstance(self._fallback_font, StixFonts):
- stixsizedaltfonts = {
- 0: 'STIXGeneral',
- 1: 'STIXSizeOneSym',
- 2: 'STIXSizeTwoSym',
- 3: 'STIXSizeThreeSym',
- 4: 'STIXSizeFourSym',
- 5: 'STIXSizeFiveSym'}
-
- for size, name in stixsizedaltfonts.items():
- fullpath = findfont(name)
- self.fontmap[size] = fullpath
- self.fontmap[name] = fullpath
-
- _slanted_symbols = set(r"\int \oint".split())
-
- def _map_virtual_font(self, fontname: str, font_class: str,
- uniindex: int) -> tuple[str, int]:
- return fontname, uniindex
-
- def _get_glyph(self, fontname: str, font_class: str,
- sym: str) -> tuple[FT2Font, int, bool]:
- try:
- uniindex = get_unicode_index(sym)
- found_symbol = True
- except ValueError:
- uniindex = ord('?')
- found_symbol = False
- _log.warning("No TeX to Unicode mapping for %a.", sym)
-
- fontname, uniindex = self._map_virtual_font(
- fontname, font_class, uniindex)
-
- new_fontname = fontname
-
- # Only characters in the "Letter" class should be italicized in 'it'
- # mode. Greek capital letters should be Roman.
- if found_symbol:
- if fontname == 'it' and uniindex < 0x10000:
- char = chr(uniindex)
- if (unicodedata.category(char)[0] != "L"
- or unicodedata.name(char).startswith("GREEK CAPITAL")):
- new_fontname = 'rm'
-
- slanted = (new_fontname == 'it') or sym in self._slanted_symbols
- found_symbol = False
- font = self._get_font(new_fontname)
- if font is not None:
- if (uniindex in self._cmr10_substitutions
- and font.family_name == "cmr10"):
- font = get_font(
- cbook._get_data_path("fonts/ttf/cmsy10.ttf"))
- uniindex = self._cmr10_substitutions[uniindex]
- glyphindex = font.get_char_index(uniindex)
- if glyphindex != 0:
- found_symbol = True
-
- if not found_symbol:
- if self._fallback_font:
- if (fontname in ('it', 'regular')
- and isinstance(self._fallback_font, StixFonts)):
- fontname = 'rm'
-
- g = self._fallback_font._get_glyph(fontname, font_class, sym)
- family = g[0].family_name
- if family in list(BakomaFonts._fontmap.values()):
- family = "Computer Modern"
- _log.info("Substituting symbol %s from %s", sym, family)
- return g
-
- else:
- if (fontname in ('it', 'regular')
- and isinstance(self, StixFonts)):
- return self._get_glyph('rm', font_class, sym)
- _log.warning("Font %r does not have a glyph for %a [U+%x], "
- "substituting with a dummy symbol.",
- new_fontname, sym, uniindex)
- font = self._get_font('rm')
- uniindex = 0xA4 # currency char, for lack of anything better
- slanted = False
-
- return font, uniindex, slanted
-
- def get_sized_alternatives_for_symbol(self, fontname: str,
- sym: str) -> list[tuple[str, str]]:
- if self._fallback_font:
- return self._fallback_font.get_sized_alternatives_for_symbol(
- fontname, sym)
- return [(fontname, sym)]
-
-
-class DejaVuFonts(UnicodeFonts, metaclass=abc.ABCMeta):
- _fontmap: dict[str | int, str] = {}
-
- def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int):
- # This must come first so the backend's owner is set correctly
- if isinstance(self, DejaVuSerifFonts):
- self._fallback_font = StixFonts(default_font_prop, load_glyph_flags)
- else:
- self._fallback_font = StixSansFonts(default_font_prop, load_glyph_flags)
- self.bakoma = BakomaFonts(default_font_prop, load_glyph_flags)
- TruetypeFonts.__init__(self, default_font_prop, load_glyph_flags)
- # Include Stix sized alternatives for glyphs
- self._fontmap.update({
- 1: 'STIXSizeOneSym',
- 2: 'STIXSizeTwoSym',
- 3: 'STIXSizeThreeSym',
- 4: 'STIXSizeFourSym',
- 5: 'STIXSizeFiveSym',
- })
- for key, name in self._fontmap.items():
- fullpath = findfont(name)
- self.fontmap[key] = fullpath
- self.fontmap[name] = fullpath
-
- def _get_glyph(self, fontname: str, font_class: str,
- sym: str) -> tuple[FT2Font, int, bool]:
- # Override prime symbol to use Bakoma.
- if sym == r'\prime':
- return self.bakoma._get_glyph(fontname, font_class, sym)
- else:
- # check whether the glyph is available in the display font
- uniindex = get_unicode_index(sym)
- font = self._get_font('ex')
- if font is not None:
- glyphindex = font.get_char_index(uniindex)
- if glyphindex != 0:
- return super()._get_glyph('ex', font_class, sym)
- # otherwise return regular glyph
- return super()._get_glyph(fontname, font_class, sym)
-
-
-class DejaVuSerifFonts(DejaVuFonts):
- """
- A font handling class for the DejaVu Serif fonts
-
- If a glyph is not found it will fallback to Stix Serif
- """
- _fontmap = {
- 'rm': 'DejaVu Serif',
- 'it': 'DejaVu Serif:italic',
- 'bf': 'DejaVu Serif:weight=bold',
- 'bfit': 'DejaVu Serif:italic:bold',
- 'sf': 'DejaVu Sans',
- 'tt': 'DejaVu Sans Mono',
- 'ex': 'DejaVu Serif Display',
- 0: 'DejaVu Serif',
- }
-
-
-class DejaVuSansFonts(DejaVuFonts):
- """
- A font handling class for the DejaVu Sans fonts
-
- If a glyph is not found it will fallback to Stix Sans
- """
- _fontmap = {
- 'rm': 'DejaVu Sans',
- 'it': 'DejaVu Sans:italic',
- 'bf': 'DejaVu Sans:weight=bold',
- 'bfit': 'DejaVu Sans:italic:bold',
- 'sf': 'DejaVu Sans',
- 'tt': 'DejaVu Sans Mono',
- 'ex': 'DejaVu Sans Display',
- 0: 'DejaVu Sans',
- }
-
-
-class StixFonts(UnicodeFonts):
- """
- A font handling class for the STIX fonts.
-
- In addition to what UnicodeFonts provides, this class:
-
- - supports "virtual fonts" which are complete alpha numeric
- character sets with different font styles at special Unicode
- code points, such as "Blackboard".
-
- - handles sized alternative characters for the STIXSizeX fonts.
- """
- _fontmap: dict[str | int, str] = {
- 'rm': 'STIXGeneral',
- 'it': 'STIXGeneral:italic',
- 'bf': 'STIXGeneral:weight=bold',
- 'bfit': 'STIXGeneral:italic:bold',
- 'nonunirm': 'STIXNonUnicode',
- 'nonuniit': 'STIXNonUnicode:italic',
- 'nonunibf': 'STIXNonUnicode:weight=bold',
- 0: 'STIXGeneral',
- 1: 'STIXSizeOneSym',
- 2: 'STIXSizeTwoSym',
- 3: 'STIXSizeThreeSym',
- 4: 'STIXSizeFourSym',
- 5: 'STIXSizeFiveSym',
- }
- _fallback_font = None
- _sans = False
-
- def __init__(self, default_font_prop: FontProperties, load_glyph_flags: int):
- TruetypeFonts.__init__(self, default_font_prop, load_glyph_flags)
- for key, name in self._fontmap.items():
- fullpath = findfont(name)
- self.fontmap[key] = fullpath
- self.fontmap[name] = fullpath
-
- def _map_virtual_font(self, fontname: str, font_class: str,
- uniindex: int) -> tuple[str, int]:
- # Handle these "fonts" that are actually embedded in
- # other fonts.
- font_mapping = stix_virtual_fonts.get(fontname)
- if (self._sans and font_mapping is None
- and fontname not in ('regular', 'default')):
- font_mapping = stix_virtual_fonts['sf']
- doing_sans_conversion = True
- else:
- doing_sans_conversion = False
-
- if isinstance(font_mapping, dict):
- try:
- mapping = font_mapping[font_class]
- except KeyError:
- mapping = font_mapping['rm']
- elif isinstance(font_mapping, list):
- mapping = font_mapping
- else:
- mapping = None
-
- if mapping is not None:
- # Binary search for the source glyph
- lo = 0
- hi = len(mapping)
- while lo < hi:
- mid = (lo+hi)//2
- range = mapping[mid]
- if uniindex < range[0]:
- hi = mid
- elif uniindex <= range[1]:
- break
- else:
- lo = mid + 1
-
- if range[0] <= uniindex <= range[1]:
- uniindex = uniindex - range[0] + range[3]
- fontname = range[2]
- elif not doing_sans_conversion:
- # This will generate a dummy character
- uniindex = 0x1
- fontname = mpl.rcParams['mathtext.default']
-
- # Fix some incorrect glyphs.
- if fontname in ('rm', 'it'):
- uniindex = stix_glyph_fixes.get(uniindex, uniindex)
-
- # Handle private use area glyphs
- if fontname in ('it', 'rm', 'bf', 'bfit') and 0xe000 <= uniindex <= 0xf8ff:
- fontname = 'nonuni' + fontname
-
- return fontname, uniindex
-
- @functools.cache
- def get_sized_alternatives_for_symbol( # type: ignore[override]
- self,
- fontname: str,
- sym: str) -> list[tuple[str, str]] | list[tuple[int, str]]:
- fixes = {
- '\\{': '{', '\\}': '}', '\\[': '[', '\\]': ']',
- '<': '\N{MATHEMATICAL LEFT ANGLE BRACKET}',
- '>': '\N{MATHEMATICAL RIGHT ANGLE BRACKET}',
- }
- sym = fixes.get(sym, sym)
- try:
- uniindex = get_unicode_index(sym)
- except ValueError:
- return [(fontname, sym)]
- alternatives = [(i, chr(uniindex)) for i in range(6)
- if self._get_font(i).get_char_index(uniindex) != 0]
- # The largest size of the radical symbol in STIX has incorrect
- # metrics that cause it to be disconnected from the stem.
- if sym == r'\__sqrt__':
- alternatives = alternatives[:-1]
- return alternatives
-
-
-class StixSansFonts(StixFonts):
- """
- A font handling class for the STIX fonts (that uses sans-serif
- characters by default).
- """
- _sans = True
-
-
-##############################################################################
-# TeX-LIKE BOX MODEL
-
-# The following is based directly on the document 'woven' from the
-# TeX82 source code. This information is also available in printed
-# form:
-#
-# Knuth, Donald E.. 1986. Computers and Typesetting, Volume B:
-# TeX: The Program. Addison-Wesley Professional.
-#
-# The most relevant "chapters" are:
-# Data structures for boxes and their friends
-# Shipping pages out (ship())
-# Packaging (hpack() and vpack())
-# Data structures for math mode
-# Subroutines for math mode
-# Typesetting math formulas
-#
-# Many of the docstrings below refer to a numbered "node" in that
-# book, e.g., node123
-#
-# Note that (as TeX) y increases downward, unlike many other parts of
-# matplotlib.
-
-# How much text shrinks when going to the next-smallest level.
-SHRINK_FACTOR = 0.7
-# The number of different sizes of chars to use, beyond which they will not
-# get any smaller
-NUM_SIZE_LEVELS = 6
-
-
-class FontConstantsBase:
- """
- A set of constants that controls how certain things, such as sub-
- and superscripts are laid out. These are all metrics that can't
- be reliably retrieved from the font metrics in the font itself.
- """
- # Percentage of x-height of additional horiz. space after sub/superscripts
- script_space: T.ClassVar[float] = 0.05
-
- # Percentage of x-height that sub/superscripts drop below the baseline
- subdrop: T.ClassVar[float] = 0.4
-
- # Percentage of x-height that superscripts are raised from the baseline
- sup1: T.ClassVar[float] = 0.7
-
- # Percentage of x-height that subscripts drop below the baseline
- sub1: T.ClassVar[float] = 0.3
-
- # Percentage of x-height that subscripts drop below the baseline when a
- # superscript is present
- sub2: T.ClassVar[float] = 0.5
-
- # Percentage of x-height that sub/superscripts are offset relative to the
- # nucleus edge for non-slanted nuclei
- delta: T.ClassVar[float] = 0.025
-
- # Additional percentage of last character height above 2/3 of the
- # x-height that superscripts are offset relative to the subscript
- # for slanted nuclei
- delta_slanted: T.ClassVar[float] = 0.2
-
- # Percentage of x-height that superscripts and subscripts are offset for
- # integrals
- delta_integral: T.ClassVar[float] = 0.1
-
-
-class ComputerModernFontConstants(FontConstantsBase):
- script_space = 0.075
- subdrop = 0.2
- sup1 = 0.45
- sub1 = 0.2
- sub2 = 0.3
- delta = 0.075
- delta_slanted = 0.3
- delta_integral = 0.3
-
-
-class STIXFontConstants(FontConstantsBase):
- script_space = 0.1
- sup1 = 0.8
- sub2 = 0.6
- delta = 0.05
- delta_slanted = 0.3
- delta_integral = 0.3
-
-
-class STIXSansFontConstants(FontConstantsBase):
- script_space = 0.05
- sup1 = 0.8
- delta_slanted = 0.6
- delta_integral = 0.3
-
-
-class DejaVuSerifFontConstants(FontConstantsBase):
- pass
-
-
-class DejaVuSansFontConstants(FontConstantsBase):
- pass
-
-
-# Maps font family names to the FontConstantBase subclass to use
-_font_constant_mapping = {
- 'DejaVu Sans': DejaVuSansFontConstants,
- 'DejaVu Sans Mono': DejaVuSansFontConstants,
- 'DejaVu Serif': DejaVuSerifFontConstants,
- 'cmb10': ComputerModernFontConstants,
- 'cmex10': ComputerModernFontConstants,
- 'cmmi10': ComputerModernFontConstants,
- 'cmr10': ComputerModernFontConstants,
- 'cmss10': ComputerModernFontConstants,
- 'cmsy10': ComputerModernFontConstants,
- 'cmtt10': ComputerModernFontConstants,
- 'STIXGeneral': STIXFontConstants,
- 'STIXNonUnicode': STIXFontConstants,
- 'STIXSizeFiveSym': STIXFontConstants,
- 'STIXSizeFourSym': STIXFontConstants,
- 'STIXSizeThreeSym': STIXFontConstants,
- 'STIXSizeTwoSym': STIXFontConstants,
- 'STIXSizeOneSym': STIXFontConstants,
- # Map the fonts we used to ship, just for good measure
- 'Bitstream Vera Sans': DejaVuSansFontConstants,
- 'Bitstream Vera': DejaVuSansFontConstants,
- }
-
-
-def _get_font_constant_set(state: ParserState) -> type[FontConstantsBase]:
- constants = _font_constant_mapping.get(
- state.fontset._get_font(state.font).family_name, FontConstantsBase)
- # STIX sans isn't really its own fonts, just different code points
- # in the STIX fonts, so we have to detect this one separately.
- if (constants is STIXFontConstants and
- isinstance(state.fontset, StixSansFonts)):
- return STIXSansFontConstants
- return constants
-
-
-class Node:
- """A node in the TeX box model."""
-
- def __init__(self) -> None:
- self.size = 0
-
- def __repr__(self) -> str:
- return type(self).__name__
-
- def get_kerning(self, next: Node | None) -> float:
- return 0.0
-
- def shrink(self) -> None:
- """
- Shrinks one level smaller. There are only three levels of
- sizes, after which things will no longer get smaller.
- """
- self.size += 1
-
- def render(self, output: Output, x: float, y: float) -> None:
- """Render this node."""
-
-
-class Box(Node):
- """A node with a physical location."""
-
- def __init__(self, width: float, height: float, depth: float) -> None:
- super().__init__()
- self.width = width
- self.height = height
- self.depth = depth
-
- def shrink(self) -> None:
- super().shrink()
- if self.size < NUM_SIZE_LEVELS:
- self.width *= SHRINK_FACTOR
- self.height *= SHRINK_FACTOR
- self.depth *= SHRINK_FACTOR
-
- def render(self, output: Output, # type: ignore[override]
- x1: float, y1: float, x2: float, y2: float) -> None:
- pass
-
-
-class Vbox(Box):
- """A box with only height (zero width)."""
-
- def __init__(self, height: float, depth: float):
- super().__init__(0., height, depth)
-
-
-class Hbox(Box):
- """A box with only width (zero height and depth)."""
-
- def __init__(self, width: float):
- super().__init__(width, 0., 0.)
-
-
-class Char(Node):
- """
- A single character.
-
- Unlike TeX, the font information and metrics are stored with each `Char`
- to make it easier to lookup the font metrics when needed. Note that TeX
- boxes have a width, height, and depth, unlike Type1 and TrueType which use
- a full bounding box and an advance in the x-direction. The metrics must
- be converted to the TeX model, and the advance (if different from width)
- must be converted into a `Kern` node when the `Char` is added to its parent
- `Hlist`.
- """
-
- def __init__(self, c: str, state: ParserState):
- super().__init__()
- self.c = c
- self.fontset = state.fontset
- self.font = state.font
- self.font_class = state.font_class
- self.fontsize = state.fontsize
- self.dpi = state.dpi
- # The real width, height and depth will be set during the
- # pack phase, after we know the real fontsize
- self._update_metrics()
-
- def __repr__(self) -> str:
- return '`%s`' % self.c
-
- def _update_metrics(self) -> None:
- metrics = self._metrics = self.fontset.get_metrics(
- self.font, self.font_class, self.c, self.fontsize, self.dpi)
- if self.c == ' ':
- self.width = metrics.advance
- else:
- self.width = metrics.width
- self.height = metrics.iceberg
- self.depth = -(metrics.iceberg - metrics.height)
-
- def is_slanted(self) -> bool:
- return self._metrics.slanted
-
- def get_kerning(self, next: Node | None) -> float:
- """
- Return the amount of kerning between this and the given character.
-
- This method is called when characters are strung together into `Hlist`
- to create `Kern` nodes.
- """
- advance = self._metrics.advance - self.width
- kern = 0.
- if isinstance(next, Char):
- kern = self.fontset.get_kern(
- self.font, self.font_class, self.c, self.fontsize,
- next.font, next.font_class, next.c, next.fontsize,
- self.dpi)
- return advance + kern
-
- def render(self, output: Output, x: float, y: float) -> None:
- self.fontset.render_glyph(
- output, x, y,
- self.font, self.font_class, self.c, self.fontsize, self.dpi)
-
- def shrink(self) -> None:
- super().shrink()
- if self.size < NUM_SIZE_LEVELS:
- self.fontsize *= SHRINK_FACTOR
- self.width *= SHRINK_FACTOR
- self.height *= SHRINK_FACTOR
- self.depth *= SHRINK_FACTOR
-
-
-class Accent(Char):
- """
- The font metrics need to be dealt with differently for accents,
- since they are already offset correctly from the baseline in
- TrueType fonts.
- """
- def _update_metrics(self) -> None:
- metrics = self._metrics = self.fontset.get_metrics(
- self.font, self.font_class, self.c, self.fontsize, self.dpi)
- self.width = metrics.xmax - metrics.xmin
- self.height = metrics.ymax - metrics.ymin
- self.depth = 0
-
- def shrink(self) -> None:
- super().shrink()
- self._update_metrics()
-
- def render(self, output: Output, x: float, y: float) -> None:
- self.fontset.render_glyph(
- output, x - self._metrics.xmin, y + self._metrics.ymin,
- self.font, self.font_class, self.c, self.fontsize, self.dpi)
-
-
-class List(Box):
- """A list of nodes (either horizontal or vertical)."""
-
- def __init__(self, elements: T.Sequence[Node]):
- super().__init__(0., 0., 0.)
- self.shift_amount = 0. # An arbitrary offset
- self.children = [*elements] # The child nodes of this list
- # The following parameters are set in the vpack and hpack functions
- self.glue_set = 0. # The glue setting of this list
- self.glue_sign = 0 # 0: normal, -1: shrinking, 1: stretching
- self.glue_order = 0 # The order of infinity (0 - 3) for the glue
-
- def __repr__(self) -> str:
- return '{}<w={:.02f} h={:.02f} d={:.02f} s={:.02f}>[{}]'.format(
- super().__repr__(),
- self.width, self.height,
- self.depth, self.shift_amount,
- ', '.join([repr(x) for x in self.children]))
-
- def _set_glue(self, x: float, sign: int, totals: list[float],
- error_type: str) -> None:
- self.glue_order = o = next(
- # Highest order of glue used by the members of this list.
- (i for i in range(len(totals))[::-1] if totals[i] != 0), 0)
- self.glue_sign = sign
- if totals[o] != 0.:
- self.glue_set = x / totals[o]
- else:
- self.glue_sign = 0
- self.glue_ratio = 0.
- if o == 0:
- if len(self.children):
- _log.warning("%s %s: %r",
- error_type, type(self).__name__, self)
-
- def shrink(self) -> None:
- for child in self.children:
- child.shrink()
- super().shrink()
- if self.size < NUM_SIZE_LEVELS:
- self.shift_amount *= SHRINK_FACTOR
- self.glue_set *= SHRINK_FACTOR
-
-
-class Hlist(List):
- """A horizontal list of boxes."""
-
- def __init__(self, elements: T.Sequence[Node], w: float = 0.0,
- m: T.Literal['additional', 'exactly'] = 'additional',
- do_kern: bool = True):
- super().__init__(elements)
- if do_kern:
- self.kern()
- self.hpack(w=w, m=m)
-
- def kern(self) -> None:
- """
- Insert `Kern` nodes between `Char` nodes to set kerning.
-
- The `Char` nodes themselves determine the amount of kerning they need
- (in `~Char.get_kerning`), and this function just creates the correct
- linked list.
- """
- new_children = []
- num_children = len(self.children)
- if num_children:
- for i in range(num_children):
- elem = self.children[i]
- if i < num_children - 1:
- next = self.children[i + 1]
- else:
- next = None
-
- new_children.append(elem)
- kerning_distance = elem.get_kerning(next)
- if kerning_distance != 0.:
- kern = Kern(kerning_distance)
- new_children.append(kern)
- self.children = new_children
-
- def hpack(self, w: float = 0.0,
- m: T.Literal['additional', 'exactly'] = 'additional') -> None:
- r"""
- Compute the dimensions of the resulting boxes, and adjust the glue if
- one of those dimensions is pre-specified. The computed sizes normally
- enclose all of the material inside the new box; but some items may
- stick out if negative glue is used, if the box is overfull, or if a
- ``\vbox`` includes other boxes that have been shifted left.
-
- Parameters
- ----------
- w : float, default: 0
- A width.
- m : {'exactly', 'additional'}, default: 'additional'
- Whether to produce a box whose width is 'exactly' *w*; or a box
- with the natural width of the contents, plus *w* ('additional').
-
- Notes
- -----
- The defaults produce a box with the natural width of the contents.
- """
- # I don't know why these get reset in TeX. Shift_amount is pretty
- # much useless if we do.
- # self.shift_amount = 0.
- h = 0.
- d = 0.
- x = 0.
- total_stretch = [0.] * 4
- total_shrink = [0.] * 4
- for p in self.children:
- if isinstance(p, Char):
- x += p.width
- h = max(h, p.height)
- d = max(d, p.depth)
- elif isinstance(p, Box):
- x += p.width
- if not np.isinf(p.height) and not np.isinf(p.depth):
- s = getattr(p, 'shift_amount', 0.)
- h = max(h, p.height - s)
- d = max(d, p.depth + s)
- elif isinstance(p, Glue):
- glue_spec = p.glue_spec
- x += glue_spec.width
- total_stretch[glue_spec.stretch_order] += glue_spec.stretch
- total_shrink[glue_spec.shrink_order] += glue_spec.shrink
- elif isinstance(p, Kern):
- x += p.width
- self.height = h
- self.depth = d
-
- if m == 'additional':
- w += x
- self.width = w
- x = w - x
-
- if x == 0.:
- self.glue_sign = 0
- self.glue_order = 0
- self.glue_ratio = 0.
- return
- if x > 0.:
- self._set_glue(x, 1, total_stretch, "Overful")
- else:
- self._set_glue(x, -1, total_shrink, "Underful")
-
-
-class Vlist(List):
- """A vertical list of boxes."""
-
- def __init__(self, elements: T.Sequence[Node], h: float = 0.0,
- m: T.Literal['additional', 'exactly'] = 'additional'):
- super().__init__(elements)
- self.vpack(h=h, m=m)
-
- def vpack(self, h: float = 0.0,
- m: T.Literal['additional', 'exactly'] = 'additional',
- l: float = np.inf) -> None:
- """
- Compute the dimensions of the resulting boxes, and to adjust the glue
- if one of those dimensions is pre-specified.
-
- Parameters
- ----------
- h : float, default: 0
- A height.
- m : {'exactly', 'additional'}, default: 'additional'
- Whether to produce a box whose height is 'exactly' *h*; or a box
- with the natural height of the contents, plus *h* ('additional').
- l : float, default: np.inf
- The maximum height.
-
- Notes
- -----
- The defaults produce a box with the natural height of the contents.
- """
- # I don't know why these get reset in TeX. Shift_amount is pretty
- # much useless if we do.
- # self.shift_amount = 0.
- w = 0.
- d = 0.
- x = 0.
- total_stretch = [0.] * 4
- total_shrink = [0.] * 4
- for p in self.children:
- if isinstance(p, Box):
- x += d + p.height
- d = p.depth
- if not np.isinf(p.width):
- s = getattr(p, 'shift_amount', 0.)
- w = max(w, p.width + s)
- elif isinstance(p, Glue):
- x += d
- d = 0.
- glue_spec = p.glue_spec
- x += glue_spec.width
- total_stretch[glue_spec.stretch_order] += glue_spec.stretch
- total_shrink[glue_spec.shrink_order] += glue_spec.shrink
- elif isinstance(p, Kern):
- x += d + p.width
- d = 0.
- elif isinstance(p, Char):
- raise RuntimeError(
- "Internal mathtext error: Char node found in Vlist")
-
- self.width = w
- if d > l:
- x += d - l
- self.depth = l
- else:
- self.depth = d
-
- if m == 'additional':
- h += x
- self.height = h
- x = h - x
-
- if x == 0:
- self.glue_sign = 0
- self.glue_order = 0
- self.glue_ratio = 0.
- return
-
- if x > 0.:
- self._set_glue(x, 1, total_stretch, "Overful")
- else:
- self._set_glue(x, -1, total_shrink, "Underful")
-
-
-class Rule(Box):
- """
- A solid black rectangle.
-
- It has *width*, *depth*, and *height* fields just as in an `Hlist`.
- However, if any of these dimensions is inf, the actual value will be
- determined by running the rule up to the boundary of the innermost
- enclosing box. This is called a "running dimension". The width is never
- running in an `Hlist`; the height and depth are never running in a `Vlist`.
- """
-
- def __init__(self, width: float, height: float, depth: float, state: ParserState):
- super().__init__(width, height, depth)
- self.fontset = state.fontset
-
- def render(self, output: Output, # type: ignore[override]
- x: float, y: float, w: float, h: float) -> None:
- self.fontset.render_rect_filled(output, x, y, x + w, y + h)
-
-
-class Hrule(Rule):
- """Convenience class to create a horizontal rule."""
-
- def __init__(self, state: ParserState, thickness: float | None = None):
- if thickness is None:
- thickness = state.get_current_underline_thickness()
- height = depth = thickness * 0.5
- super().__init__(np.inf, height, depth, state)
-
-
-class Vrule(Rule):
- """Convenience class to create a vertical rule."""
-
- def __init__(self, state: ParserState):
- thickness = state.get_current_underline_thickness()
- super().__init__(thickness, np.inf, np.inf, state)
-
-
-class _GlueSpec(NamedTuple):
- width: float
- stretch: float
- stretch_order: int
- shrink: float
- shrink_order: int
-
-
-_GlueSpec._named = { # type: ignore[attr-defined]
- 'fil': _GlueSpec(0., 1., 1, 0., 0),
- 'fill': _GlueSpec(0., 1., 2, 0., 0),
- 'filll': _GlueSpec(0., 1., 3, 0., 0),
- 'neg_fil': _GlueSpec(0., 0., 0, 1., 1),
- 'neg_fill': _GlueSpec(0., 0., 0, 1., 2),
- 'neg_filll': _GlueSpec(0., 0., 0, 1., 3),
- 'empty': _GlueSpec(0., 0., 0, 0., 0),
- 'ss': _GlueSpec(0., 1., 1, -1., 1),
-}
-
-
-class Glue(Node):
- """
- Most of the information in this object is stored in the underlying
- ``_GlueSpec`` class, which is shared between multiple glue objects.
- (This is a memory optimization which probably doesn't matter anymore, but
- it's easier to stick to what TeX does.)
- """
-
- def __init__(self,
- glue_type: _GlueSpec | T.Literal["fil", "fill", "filll",
- "neg_fil", "neg_fill", "neg_filll",
- "empty", "ss"]):
- super().__init__()
- if isinstance(glue_type, str):
- glue_spec = _GlueSpec._named[glue_type] # type: ignore[attr-defined]
- elif isinstance(glue_type, _GlueSpec):
- glue_spec = glue_type
- else:
- raise ValueError("glue_type must be a glue spec name or instance")
- self.glue_spec = glue_spec
-
- def shrink(self) -> None:
- super().shrink()
- if self.size < NUM_SIZE_LEVELS:
- g = self.glue_spec
- self.glue_spec = g._replace(width=g.width * SHRINK_FACTOR)
-
-
-class HCentered(Hlist):
- """
- A convenience class to create an `Hlist` whose contents are
- centered within its enclosing box.
- """
-
- def __init__(self, elements: list[Node]):
- super().__init__([Glue('ss'), *elements, Glue('ss')], do_kern=False)
-
-
-class VCentered(Vlist):
- """
- A convenience class to create a `Vlist` whose contents are
- centered within its enclosing box.
- """
-
- def __init__(self, elements: list[Node]):
- super().__init__([Glue('ss'), *elements, Glue('ss')])
-
-
-class Kern(Node):
- """
- A `Kern` node has a width field to specify a (normally
- negative) amount of spacing. This spacing correction appears in
- horizontal lists between letters like A and V when the font
- designer said that it looks better to move them closer together or
- further apart. A kern node can also appear in a vertical list,
- when its *width* denotes additional spacing in the vertical
- direction.
- """
-
- height = 0
- depth = 0
-
- def __init__(self, width: float):
- super().__init__()
- self.width = width
-
- def __repr__(self) -> str:
- return "k%.02f" % self.width
-
- def shrink(self) -> None:
- super().shrink()
- if self.size < NUM_SIZE_LEVELS:
- self.width *= SHRINK_FACTOR
-
-
-class AutoHeightChar(Hlist):
- """
- A character as close to the given height and depth as possible.
-
- When using a font with multiple height versions of some characters (such as
- the BaKoMa fonts), the correct glyph will be selected, otherwise this will
- always just return a scaled version of the glyph.
- """
-
- def __init__(self, c: str, height: float, depth: float, state: ParserState,
- always: bool = False, factor: float | None = None):
- alternatives = state.fontset.get_sized_alternatives_for_symbol(
- state.font, c)
-
- xHeight = state.fontset.get_xheight(
- state.font, state.fontsize, state.dpi)
-
- state = state.copy()
- target_total = height + depth
- for fontname, sym in alternatives:
- state.font = fontname
- char = Char(sym, state)
- # Ensure that size 0 is chosen when the text is regular sized but
- # with descender glyphs by subtracting 0.2 * xHeight
- if char.height + char.depth >= target_total - 0.2 * xHeight:
- break
-
- shift = 0.0
- if state.font != 0 or len(alternatives) == 1:
- if factor is None:
- factor = target_total / (char.height + char.depth)
- state.fontsize *= factor
- char = Char(sym, state)
-
- shift = (depth - char.depth)
-
- super().__init__([char])
- self.shift_amount = shift
-
-
-class AutoWidthChar(Hlist):
- """
- A character as close to the given width as possible.
-
- When using a font with multiple width versions of some characters (such as
- the BaKoMa fonts), the correct glyph will be selected, otherwise this will
- always just return a scaled version of the glyph.
- """
-
- def __init__(self, c: str, width: float, state: ParserState, always: bool = False,
- char_class: type[Char] = Char):
- alternatives = state.fontset.get_sized_alternatives_for_symbol(
- state.font, c)
-
- state = state.copy()
- for fontname, sym in alternatives:
- state.font = fontname
- char = char_class(sym, state)
- if char.width >= width:
- break
-
- factor = width / char.width
- state.fontsize *= factor
- char = char_class(sym, state)
-
- super().__init__([char])
- self.width = char.width
-
-
-def ship(box: Box, xy: tuple[float, float] = (0, 0)) -> Output:
- """
- Ship out *box* at offset *xy*, converting it to an `Output`.
-
- Since boxes can be inside of boxes inside of boxes, the main work of `ship`
- is done by two mutually recursive routines, `hlist_out` and `vlist_out`,
- which traverse the `Hlist` nodes and `Vlist` nodes inside of horizontal
- and vertical boxes. The global variables used in TeX to store state as it
- processes have become local variables here.
- """
- ox, oy = xy
- cur_v = 0.
- cur_h = 0.
- off_h = ox
- off_v = oy + box.height
- output = Output(box)
-
- def clamp(value: float) -> float:
- return -1e9 if value < -1e9 else +1e9 if value > +1e9 else value
-
- def hlist_out(box: Hlist) -> None:
- nonlocal cur_v, cur_h, off_h, off_v
-
- cur_g = 0
- cur_glue = 0.
- glue_order = box.glue_order
- glue_sign = box.glue_sign
- base_line = cur_v
- left_edge = cur_h
-
- for p in box.children:
- if isinstance(p, Char):
- p.render(output, cur_h + off_h, cur_v + off_v)
- cur_h += p.width
- elif isinstance(p, Kern):
- cur_h += p.width
- elif isinstance(p, List):
- # node623
- if len(p.children) == 0:
- cur_h += p.width
- else:
- edge = cur_h
- cur_v = base_line + p.shift_amount
- if isinstance(p, Hlist):
- hlist_out(p)
- elif isinstance(p, Vlist):
- # p.vpack(box.height + box.depth, 'exactly')
- vlist_out(p)
- else:
- assert False, "unreachable code"
- cur_h = edge + p.width
- cur_v = base_line
- elif isinstance(p, Box):
- # node624
- rule_height = p.height
- rule_depth = p.depth
- rule_width = p.width
- if np.isinf(rule_height):
- rule_height = box.height
- if np.isinf(rule_depth):
- rule_depth = box.depth
- if rule_height > 0 and rule_width > 0:
- cur_v = base_line + rule_depth
- p.render(output,
- cur_h + off_h, cur_v + off_v,
- rule_width, rule_height)
- cur_v = base_line
- cur_h += rule_width
- elif isinstance(p, Glue):
- # node625
- glue_spec = p.glue_spec
- rule_width = glue_spec.width - cur_g
- if glue_sign != 0: # normal
- if glue_sign == 1: # stretching
- if glue_spec.stretch_order == glue_order:
- cur_glue += glue_spec.stretch
- cur_g = round(clamp(box.glue_set * cur_glue))
- elif glue_spec.shrink_order == glue_order:
- cur_glue += glue_spec.shrink
- cur_g = round(clamp(box.glue_set * cur_glue))
- rule_width += cur_g
- cur_h += rule_width
-
- def vlist_out(box: Vlist) -> None:
- nonlocal cur_v, cur_h, off_h, off_v
-
- cur_g = 0
- cur_glue = 0.
- glue_order = box.glue_order
- glue_sign = box.glue_sign
- left_edge = cur_h
- cur_v -= box.height
- top_edge = cur_v
-
- for p in box.children:
- if isinstance(p, Kern):
- cur_v += p.width
- elif isinstance(p, List):
- if len(p.children) == 0:
- cur_v += p.height + p.depth
- else:
- cur_v += p.height
- cur_h = left_edge + p.shift_amount
- save_v = cur_v
- p.width = box.width
- if isinstance(p, Hlist):
- hlist_out(p)
- elif isinstance(p, Vlist):
- vlist_out(p)
- else:
- assert False, "unreachable code"
- cur_v = save_v + p.depth
- cur_h = left_edge
- elif isinstance(p, Box):
- rule_height = p.height
- rule_depth = p.depth
- rule_width = p.width
- if np.isinf(rule_width):
- rule_width = box.width
- rule_height += rule_depth
- if rule_height > 0 and rule_depth > 0:
- cur_v += rule_height
- p.render(output,
- cur_h + off_h, cur_v + off_v,
- rule_width, rule_height)
- elif isinstance(p, Glue):
- glue_spec = p.glue_spec
- rule_height = glue_spec.width - cur_g
- if glue_sign != 0: # normal
- if glue_sign == 1: # stretching
- if glue_spec.stretch_order == glue_order:
- cur_glue += glue_spec.stretch
- cur_g = round(clamp(box.glue_set * cur_glue))
- elif glue_spec.shrink_order == glue_order: # shrinking
- cur_glue += glue_spec.shrink
- cur_g = round(clamp(box.glue_set * cur_glue))
- rule_height += cur_g
- cur_v += rule_height
- elif isinstance(p, Char):
- raise RuntimeError(
- "Internal mathtext error: Char node found in vlist")
-
- assert isinstance(box, Hlist)
- hlist_out(box)
- return output
-
-
-##############################################################################
-# PARSER
-
-
-def Error(msg: str) -> ParserElement:
- """Helper class to raise parser errors."""
- def raise_error(s: str, loc: int, toks: ParseResults) -> T.Any:
- raise ParseFatalException(s, loc, msg)
-
- return Empty().setParseAction(raise_error)
-
-
-class ParserState:
- """
- Parser state.
-
- States are pushed and popped from a stack as necessary, and the "current"
- state is always at the top of the stack.
-
- Upon entering and leaving a group { } or math/non-math, the stack is pushed
- and popped accordingly.
- """
-
- def __init__(self, fontset: Fonts, font: str, font_class: str, fontsize: float,
- dpi: float):
- self.fontset = fontset
- self._font = font
- self.font_class = font_class
- self.fontsize = fontsize
- self.dpi = dpi
-
- def copy(self) -> ParserState:
- return copy.copy(self)
-
- @property
- def font(self) -> str:
- return self._font
-
- @font.setter
- def font(self, name: str) -> None:
- if name in ('rm', 'it', 'bf', 'bfit'):
- self.font_class = name
- self._font = name
-
- def get_current_underline_thickness(self) -> float:
- """Return the underline thickness for this state."""
- return self.fontset.get_underline_thickness(
- self.font, self.fontsize, self.dpi)
-
-
-def cmd(expr: str, args: ParserElement) -> ParserElement:
- r"""
- Helper to define TeX commands.
-
- ``cmd("\cmd", args)`` is equivalent to
- ``"\cmd" - (args | Error("Expected \cmd{arg}{...}"))`` where the names in
- the error message are taken from element names in *args*. If *expr*
- already includes arguments (e.g. "\cmd{arg}{...}"), then they are stripped
- when constructing the parse element, but kept (and *expr* is used as is) in
- the error message.
- """
-
- def names(elt: ParserElement) -> T.Generator[str, None, None]:
- if isinstance(elt, ParseExpression):
- for expr in elt.exprs:
- yield from names(expr)
- elif elt.resultsName:
- yield elt.resultsName
-
- csname = expr.split("{", 1)[0]
- err = (csname + "".join("{%s}" % name for name in names(args))
- if expr == csname else expr)
- return csname - (args | Error(f"Expected {err}"))
-
-
-class Parser:
- """
- A pyparsing-based parser for strings containing math expressions.
-
- Raw text may also appear outside of pairs of ``$``.
-
- The grammar is based directly on that in TeX, though it cuts a few corners.
- """
-
- class _MathStyle(enum.Enum):
- DISPLAYSTYLE = 0
- TEXTSTYLE = 1
- SCRIPTSTYLE = 2
- SCRIPTSCRIPTSTYLE = 3
-
- _binary_operators = set(
- '+ * - \N{MINUS SIGN}'
- r'''
- \pm \sqcap \rhd
- \mp \sqcup \unlhd
- \times \vee \unrhd
- \div \wedge \oplus
- \ast \setminus \ominus
- \star \wr \otimes
- \circ \diamond \oslash
- \bullet \bigtriangleup \odot
- \cdot \bigtriangledown \bigcirc
- \cap \triangleleft \dagger
- \cup \triangleright \ddagger
- \uplus \lhd \amalg
- \dotplus \dotminus \Cap
- \Cup \barwedge \boxdot
- \boxminus \boxplus \boxtimes
- \curlyvee \curlywedge \divideontimes
- \doublebarwedge \leftthreetimes \rightthreetimes
- \slash \veebar \barvee
- \cupdot \intercal \amalg
- \circledcirc \circleddash \circledast
- \boxbar \obar \merge
- \minuscolon \dotsminusdots
- '''.split())
-
- _relation_symbols = set(r'''
- = < > :
- \leq \geq \equiv \models
- \prec \succ \sim \perp
- \preceq \succeq \simeq \mid
- \ll \gg \asymp \parallel
- \subset \supset \approx \bowtie
- \subseteq \supseteq \cong \Join
- \sqsubset \sqsupset \neq \smile
- \sqsubseteq \sqsupseteq \doteq \frown
- \in \ni \propto \vdash
- \dashv \dots \doteqdot \leqq
- \geqq \lneqq \gneqq \lessgtr
- \leqslant \geqslant \eqgtr \eqless
- \eqslantless \eqslantgtr \lesseqgtr \backsim
- \backsimeq \lesssim \gtrsim \precsim
- \precnsim \gnsim \lnsim \succsim
- \succnsim \nsim \lesseqqgtr \gtreqqless
- \gtreqless \subseteqq \supseteqq \subsetneqq
- \supsetneqq \lessapprox \approxeq \gtrapprox
- \precapprox \succapprox \precnapprox \succnapprox
- \npreccurlyeq \nsucccurlyeq \nsqsubseteq \nsqsupseteq
- \sqsubsetneq \sqsupsetneq \nlesssim \ngtrsim
- \nlessgtr \ngtrless \lnapprox \gnapprox
- \napprox \approxeq \approxident \lll
- \ggg \nparallel \Vdash \Vvdash
- \nVdash \nvdash \vDash \nvDash
- \nVDash \oequal \simneqq \triangle
- \triangleq \triangleeq \triangleleft
- \triangleright \ntriangleleft \ntriangleright
- \trianglelefteq \ntrianglelefteq \trianglerighteq
- \ntrianglerighteq \blacktriangleleft \blacktriangleright
- \equalparallel \measuredrightangle \varlrtriangle
- \Doteq \Bumpeq \Subset \Supset
- \backepsilon \because \therefore \bot
- \top \bumpeq \circeq \coloneq
- \curlyeqprec \curlyeqsucc \eqcirc \eqcolon
- \eqsim \fallingdotseq \gtrdot \gtrless
- \ltimes \rtimes \lessdot \ne
- \ncong \nequiv \ngeq \ngtr
- \nleq \nless \nmid \notin
- \nprec \nsubset \nsubseteq \nsucc
- \nsupset \nsupseteq \pitchfork \preccurlyeq
- \risingdotseq \subsetneq \succcurlyeq \supsetneq
- \varpropto \vartriangleleft \scurel
- \vartriangleright \rightangle \equal \backcong
- \eqdef \wedgeq \questeq \between
- \veeeq \disin \varisins \isins
- \isindot \varisinobar \isinobar \isinvb
- \isinE \nisd \varnis \nis
- \varniobar \niobar \bagmember \ratio
- \Equiv \stareq \measeq \arceq
- \rightassert \rightModels \smallin \smallowns
- \notsmallowns \nsimeq'''.split())
-
- _arrow_symbols = set(r"""
- \leftarrow \longleftarrow \uparrow \Leftarrow \Longleftarrow
- \Uparrow \rightarrow \longrightarrow \downarrow \Rightarrow
- \Longrightarrow \Downarrow \leftrightarrow \updownarrow
- \longleftrightarrow \updownarrow \Leftrightarrow
- \Longleftrightarrow \Updownarrow \mapsto \longmapsto \nearrow
- \hookleftarrow \hookrightarrow \searrow \leftharpoonup
- \rightharpoonup \swarrow \leftharpoondown \rightharpoondown
- \nwarrow \rightleftharpoons \leadsto \dashrightarrow
- \dashleftarrow \leftleftarrows \leftrightarrows \Lleftarrow
- \Rrightarrow \twoheadleftarrow \leftarrowtail \looparrowleft
- \leftrightharpoons \curvearrowleft \circlearrowleft \Lsh
- \upuparrows \upharpoonleft \downharpoonleft \multimap
- \leftrightsquigarrow \rightrightarrows \rightleftarrows
- \rightrightarrows \rightleftarrows \twoheadrightarrow
- \rightarrowtail \looparrowright \rightleftharpoons
- \curvearrowright \circlearrowright \Rsh \downdownarrows
- \upharpoonright \downharpoonright \rightsquigarrow \nleftarrow
- \nrightarrow \nLeftarrow \nRightarrow \nleftrightarrow
- \nLeftrightarrow \to \Swarrow \Searrow \Nwarrow \Nearrow
- \leftsquigarrow \overleftarrow \overleftrightarrow \cwopencirclearrow
- \downzigzagarrow \cupleftarrow \rightzigzagarrow \twoheaddownarrow
- \updownarrowbar \twoheaduparrow \rightarrowbar \updownarrows
- \barleftarrow \mapsfrom \mapsdown \mapsup \Ldsh \Rdsh
- """.split())
-
- _spaced_symbols = _binary_operators | _relation_symbols | _arrow_symbols
-
- _punctuation_symbols = set(r', ; . ! \ldotp \cdotp'.split())
-
- _overunder_symbols = set(r'''
- \sum \prod \coprod \bigcap \bigcup \bigsqcup \bigvee
- \bigwedge \bigodot \bigotimes \bigoplus \biguplus
- '''.split())
-
- _overunder_functions = set("lim liminf limsup sup max min".split())
-
- _dropsub_symbols = set(r'\int \oint \iint \oiint \iiint \oiiint \iiiint'.split())
-
- _fontnames = set("rm cal it tt sf bf bfit "
- "default bb frak scr regular".split())
-
- _function_names = set("""
- arccos csc ker min arcsin deg lg Pr arctan det lim sec arg dim
- liminf sin cos exp limsup sinh cosh gcd ln sup cot hom log tan
- coth inf max tanh""".split())
-
- _ambi_delims = set(r"""
- | \| / \backslash \uparrow \downarrow \updownarrow \Uparrow
- \Downarrow \Updownarrow . \vert \Vert""".split())
- _left_delims = set(r"""
- ( [ \{ < \lfloor \langle \lceil \lbrace \leftbrace \lbrack \leftparen \lgroup
- """.split())
- _right_delims = set(r"""
- ) ] \} > \rfloor \rangle \rceil \rbrace \rightbrace \rbrack \rightparen \rgroup
- """.split())
- _delims = _left_delims | _right_delims | _ambi_delims
-
- _small_greek = set([unicodedata.name(chr(i)).split()[-1].lower() for i in
- range(ord('\N{GREEK SMALL LETTER ALPHA}'),
- ord('\N{GREEK SMALL LETTER OMEGA}') + 1)])
- _latin_alphabets = set(string.ascii_letters)
-
- def __init__(self) -> None:
- p = types.SimpleNamespace()
-
- def set_names_and_parse_actions() -> None:
- for key, val in vars(p).items():
- if not key.startswith('_'):
- # Set names on (almost) everything -- very useful for debugging
- # token, placeable, and auto_delim are forward references which
- # are left without names to ensure useful error messages
- if key not in ("token", "placeable", "auto_delim"):
- val.setName(key)
- # Set actions
- if hasattr(self, key):
- val.setParseAction(getattr(self, key))
-
- # Root definitions.
-
- # In TeX parlance, a csname is a control sequence name (a "\foo").
- def csnames(group: str, names: Iterable[str]) -> Regex:
- ends_with_alpha = []
- ends_with_nonalpha = []
- for name in names:
- if name[-1].isalpha():
- ends_with_alpha.append(name)
- else:
- ends_with_nonalpha.append(name)
- return Regex(
- r"\\(?P<{group}>(?:{alpha})(?![A-Za-z]){additional}{nonalpha})".format(
- group=group,
- alpha="|".join(map(re.escape, ends_with_alpha)),
- additional="|" if ends_with_nonalpha else "",
- nonalpha="|".join(map(re.escape, ends_with_nonalpha)),
- )
- )
-
- p.float_literal = Regex(r"[-+]?([0-9]+\.?[0-9]*|\.[0-9]+)")
- p.space = oneOf(self._space_widths)("space")
-
- p.style_literal = oneOf(
- [str(e.value) for e in self._MathStyle])("style_literal")
-
- p.symbol = Regex(
- r"[a-zA-Z0-9 +\-*/<>=:,.;!\?&'@()\[\]|\U00000080-\U0001ffff]"
- r"|\\[%${}\[\]_|]"
- + r"|\\(?:{})(?![A-Za-z])".format(
- "|".join(map(re.escape, tex2uni)))
- )("sym").leaveWhitespace()
- p.unknown_symbol = Regex(r"\\[A-Za-z]+")("name")
-
- p.font = csnames("font", self._fontnames)
- p.start_group = Optional(r"\math" + oneOf(self._fontnames)("font")) + "{"
- p.end_group = Literal("}")
-
- p.delim = oneOf(self._delims)
-
- # Mutually recursive definitions. (Minimizing the number of Forward
- # elements is important for speed.)
- p.auto_delim = Forward()
- p.placeable = Forward()
- p.required_group = Forward()
- p.optional_group = Forward()
- p.token = Forward()
-
- set_names_and_parse_actions() # for mutually recursive definitions.
-
- p.optional_group <<= "{" + ZeroOrMore(p.token)("group") + "}"
- p.required_group <<= "{" + OneOrMore(p.token)("group") + "}"
-
- p.customspace = cmd(r"\hspace", "{" + p.float_literal("space") + "}")
-
- p.accent = (
- csnames("accent", [*self._accent_map, *self._wide_accents])
- - p.placeable("sym"))
-
- p.function = csnames("name", self._function_names)
-
- p.group = p.start_group + ZeroOrMore(p.token)("group") + p.end_group
- p.unclosed_group = (p.start_group + ZeroOrMore(p.token)("group") + StringEnd())
-
- p.frac = cmd(r"\frac", p.required_group("num") + p.required_group("den"))
- p.dfrac = cmd(r"\dfrac", p.required_group("num") + p.required_group("den"))
- p.binom = cmd(r"\binom", p.required_group("num") + p.required_group("den"))
-
- p.genfrac = cmd(
- r"\genfrac",
- "{" + Optional(p.delim)("ldelim") + "}"
- + "{" + Optional(p.delim)("rdelim") + "}"
- + "{" + p.float_literal("rulesize") + "}"
- + "{" + Optional(p.style_literal)("style") + "}"
- + p.required_group("num")
- + p.required_group("den"))
-
- p.sqrt = cmd(
- r"\sqrt{value}",
- Optional("[" + OneOrMore(NotAny("]") + p.token)("root") + "]")
- + p.required_group("value"))
-
- p.overline = cmd(r"\overline", p.required_group("body"))
-
- p.overset = cmd(
- r"\overset",
- p.optional_group("annotation") + p.optional_group("body"))
- p.underset = cmd(
- r"\underset",
- p.optional_group("annotation") + p.optional_group("body"))
-
- p.text = cmd(r"\text", QuotedString('{', '\\', endQuoteChar="}"))
-
- p.substack = cmd(r"\substack",
- nested_expr(opener="{", closer="}",
- content=Group(OneOrMore(p.token)) +
- ZeroOrMore(Literal("\\\\").suppress()))("parts"))
-
- p.subsuper = (
- (Optional(p.placeable)("nucleus")
- + OneOrMore(oneOf(["_", "^"]) - p.placeable)("subsuper")
- + Regex("'*")("apostrophes"))
- | Regex("'+")("apostrophes")
- | (p.placeable("nucleus") + Regex("'*")("apostrophes"))
- )
-
- p.simple = p.space | p.customspace | p.font | p.subsuper
-
- p.token <<= (
- p.simple
- | p.auto_delim
- | p.unclosed_group
- | p.unknown_symbol # Must be last
- )
-
- p.operatorname = cmd(r"\operatorname", "{" + ZeroOrMore(p.simple)("name") + "}")
-
- p.boldsymbol = cmd(
- r"\boldsymbol", "{" + ZeroOrMore(p.simple)("value") + "}")
-
- p.placeable <<= (
- p.accent # Must be before symbol as all accents are symbols
- | p.symbol # Must be second to catch all named symbols and single
- # chars not in a group
- | p.function
- | p.operatorname
- | p.group
- | p.frac
- | p.dfrac
- | p.binom
- | p.genfrac
- | p.overset
- | p.underset
- | p.sqrt
- | p.overline
- | p.text
- | p.boldsymbol
- | p.substack
- )
-
- mdelim = r"\middle" - (p.delim("mdelim") | Error("Expected a delimiter"))
- p.auto_delim <<= (
- r"\left" - (p.delim("left") | Error("Expected a delimiter"))
- + ZeroOrMore(p.simple | p.auto_delim | mdelim)("mid")
- + r"\right" - (p.delim("right") | Error("Expected a delimiter"))
- )
-
- # Leaf definitions.
- p.math = OneOrMore(p.token)
- p.math_string = QuotedString('$', '\\', unquoteResults=False)
- p.non_math = Regex(r"(?:(?:\\[$])|[^$])*").leaveWhitespace()
- p.main = (
- p.non_math + ZeroOrMore(p.math_string + p.non_math) + StringEnd()
- )
- set_names_and_parse_actions() # for leaf definitions.
-
- self._expression = p.main
- self._math_expression = p.math
-
- # To add space to nucleus operators after sub/superscripts
- self._in_subscript_or_superscript = False
-
- def parse(self, s: str, fonts_object: Fonts, fontsize: float, dpi: float) -> Hlist:
- """
- Parse expression *s* using the given *fonts_object* for
- output, at the given *fontsize* and *dpi*.
-
- Returns the parse tree of `Node` instances.
- """
- self._state_stack = [
- ParserState(fonts_object, 'default', 'rm', fontsize, dpi)]
- self._em_width_cache: dict[tuple[str, float, float], float] = {}
- try:
- result = self._expression.parseString(s)
- except ParseBaseException as err:
- # explain becomes a plain method on pyparsing 3 (err.explain(0)).
- raise ValueError("\n" + ParseException.explain(err, 0)) from None
- self._state_stack = []
- self._in_subscript_or_superscript = False
- # prevent operator spacing from leaking into a new expression
- self._em_width_cache = {}
- ParserElement.resetCache()
- return T.cast(Hlist, result[0]) # Known return type from main.
-
- def get_state(self) -> ParserState:
- """Get the current `State` of the parser."""
- return self._state_stack[-1]
-
- def pop_state(self) -> None:
- """Pop a `State` off of the stack."""
- self._state_stack.pop()
-
- def push_state(self) -> None:
- """Push a new `State` onto the stack, copying the current state."""
- self._state_stack.append(self.get_state().copy())
-
- def main(self, toks: ParseResults) -> list[Hlist]:
- return [Hlist(toks.asList())]
-
- def math_string(self, toks: ParseResults) -> ParseResults:
- return self._math_expression.parseString(toks[0][1:-1], parseAll=True)
-
- def math(self, toks: ParseResults) -> T.Any:
- hlist = Hlist(toks.asList())
- self.pop_state()
- return [hlist]
-
- def non_math(self, toks: ParseResults) -> T.Any:
- s = toks[0].replace(r'\$', '$')
- symbols = [Char(c, self.get_state()) for c in s]
- hlist = Hlist(symbols)
- # We're going into math now, so set font to 'it'
- self.push_state()
- self.get_state().font = mpl.rcParams['mathtext.default']
- return [hlist]
-
- float_literal = staticmethod(pyparsing_common.convertToFloat)
-
- def text(self, toks: ParseResults) -> T.Any:
- self.push_state()
- state = self.get_state()
- state.font = 'rm'
- hlist = Hlist([Char(c, state) for c in toks[1]])
- self.pop_state()
- return [hlist]
-
- def _make_space(self, percentage: float) -> Kern:
- # In TeX, an em (the unit usually used to measure horizontal lengths)
- # is not the width of the character 'm'; it is the same in different
- # font styles (e.g. roman or italic). Mathtext, however, uses 'm' in
- # the italic style so that horizontal spaces don't depend on the
- # current font style.
- state = self.get_state()
- key = (state.font, state.fontsize, state.dpi)
- width = self._em_width_cache.get(key)
- if width is None:
- metrics = state.fontset.get_metrics(
- 'it', mpl.rcParams['mathtext.default'], 'm',
- state.fontsize, state.dpi)
- width = metrics.advance
- self._em_width_cache[key] = width
- return Kern(width * percentage)
-
- _space_widths = {
- r'\,': 0.16667, # 3/18 em = 3 mu
- r'\thinspace': 0.16667, # 3/18 em = 3 mu
- r'\/': 0.16667, # 3/18 em = 3 mu
- r'\>': 0.22222, # 4/18 em = 4 mu
- r'\:': 0.22222, # 4/18 em = 4 mu
- r'\;': 0.27778, # 5/18 em = 5 mu
- r'\ ': 0.33333, # 6/18 em = 6 mu
- r'~': 0.33333, # 6/18 em = 6 mu, nonbreakable
- r'\enspace': 0.5, # 9/18 em = 9 mu
- r'\quad': 1, # 1 em = 18 mu
- r'\qquad': 2, # 2 em = 36 mu
- r'\!': -0.16667, # -3/18 em = -3 mu
- }
-
- def space(self, toks: ParseResults) -> T.Any:
- num = self._space_widths[toks["space"]]
- box = self._make_space(num)
- return [box]
-
- def customspace(self, toks: ParseResults) -> T.Any:
- return [self._make_space(toks["space"])]
-
- def symbol(self, s: str, loc: int,
- toks: ParseResults | dict[str, str]) -> T.Any:
- c = toks["sym"]
- if c == "-":
- # "U+2212 minus sign is the preferred representation of the unary
- # and binary minus sign rather than the ASCII-derived U+002D
- # hyphen-minus, because minus sign is unambiguous and because it
- # is rendered with a more desirable length, usually longer than a
- # hyphen." (https://www.unicode.org/reports/tr25/)
- c = "\N{MINUS SIGN}"
- try:
- char = Char(c, self.get_state())
- except ValueError as err:
- raise ParseFatalException(s, loc,
- "Unknown symbol: %s" % c) from err
-
- if c in self._spaced_symbols:
- # iterate until we find previous character, needed for cases
- # such as ${ -2}$, $ -2$, or $ -2$.
- prev_char = next((c for c in s[:loc][::-1] if c != ' '), '')
- # Binary operators at start of string should not be spaced
- # Also, operators in sub- or superscripts should not be spaced
- if (self._in_subscript_or_superscript or (
- c in self._binary_operators and (
- len(s[:loc].split()) == 0 or prev_char == '{' or
- prev_char in self._left_delims))):
- return [char]
- else:
- return [Hlist([self._make_space(0.2),
- char,
- self._make_space(0.2)],
- do_kern=True)]
- elif c in self._punctuation_symbols:
- prev_char = next((c for c in s[:loc][::-1] if c != ' '), '')
- next_char = next((c for c in s[loc + 1:] if c != ' '), '')
-
- # Do not space commas between brackets
- if c == ',':
- if prev_char == '{' and next_char == '}':
- return [char]
-
- # Do not space dots as decimal separators
- if c == '.' and prev_char.isdigit() and next_char.isdigit():
- return [char]
- else:
- return [Hlist([char, self._make_space(0.2)], do_kern=True)]
- return [char]
-
- def unknown_symbol(self, s: str, loc: int, toks: ParseResults) -> T.Any:
- raise ParseFatalException(s, loc, f"Unknown symbol: {toks['name']}")
-
- _accent_map = {
- r'hat': r'\circumflexaccent',
- r'breve': r'\combiningbreve',
- r'bar': r'\combiningoverline',
- r'grave': r'\combininggraveaccent',
- r'acute': r'\combiningacuteaccent',
- r'tilde': r'\combiningtilde',
- r'dot': r'\combiningdotabove',
- r'ddot': r'\combiningdiaeresis',
- r'dddot': r'\combiningthreedotsabove',
- r'ddddot': r'\combiningfourdotsabove',
- r'vec': r'\combiningrightarrowabove',
- r'"': r'\combiningdiaeresis',
- r"`": r'\combininggraveaccent',
- r"'": r'\combiningacuteaccent',
- r'~': r'\combiningtilde',
- r'.': r'\combiningdotabove',
- r'^': r'\circumflexaccent',
- r'overrightarrow': r'\rightarrow',
- r'overleftarrow': r'\leftarrow',
- r'mathring': r'\circ',
- }
-
- _wide_accents = set(r"widehat widetilde widebar".split())
-
- def accent(self, toks: ParseResults) -> T.Any:
- state = self.get_state()
- thickness = state.get_current_underline_thickness()
- accent = toks["accent"]
- sym = toks["sym"]
- accent_box: Node
- if accent in self._wide_accents:
- accent_box = AutoWidthChar(
- '\\' + accent, sym.width, state, char_class=Accent)
- else:
- accent_box = Accent(self._accent_map[accent], state)
- if accent == 'mathring':
- accent_box.shrink()
- accent_box.shrink()
- centered = HCentered([Hbox(sym.width / 4.0), accent_box])
- centered.hpack(sym.width, 'exactly')
- return Vlist([
- centered,
- Vbox(0., thickness * 2.0),
- Hlist([sym])
- ])
-
- def function(self, s: str, loc: int, toks: ParseResults) -> T.Any:
- hlist = self.operatorname(s, loc, toks)
- hlist.function_name = toks["name"]
- return hlist
-
- def operatorname(self, s: str, loc: int, toks: ParseResults) -> T.Any:
- self.push_state()
- state = self.get_state()
- state.font = 'rm'
- hlist_list: list[Node] = []
- # Change the font of Chars, but leave Kerns alone
- name = toks["name"]
- for c in name:
- if isinstance(c, Char):
- c.font = 'rm'
- c._update_metrics()
- hlist_list.append(c)
- elif isinstance(c, str):
- hlist_list.append(Char(c, state))
- else:
- hlist_list.append(c)
- next_char_loc = loc + len(name) + 1
- if isinstance(name, ParseResults):
- next_char_loc += len('operatorname{}')
- next_char = next((c for c in s[next_char_loc:] if c != ' '), '')
- delimiters = self._delims | {'^', '_'}
- if (next_char not in delimiters and
- name not in self._overunder_functions):
- # Add thin space except when followed by parenthesis, bracket, etc.
- hlist_list += [self._make_space(self._space_widths[r'\,'])]
- self.pop_state()
- # if followed by a super/subscript, set flag to true
- # This flag tells subsuper to add space after this operator
- if next_char in {'^', '_'}:
- self._in_subscript_or_superscript = True
- else:
- self._in_subscript_or_superscript = False
-
- return Hlist(hlist_list)
-
- def start_group(self, toks: ParseResults) -> T.Any:
- self.push_state()
- # Deal with LaTeX-style font tokens
- if toks.get("font"):
- self.get_state().font = toks.get("font")
- return []
-
- def group(self, toks: ParseResults) -> T.Any:
- grp = Hlist(toks.get("group", []))
- return [grp]
-
- def required_group(self, toks: ParseResults) -> T.Any:
- return Hlist(toks.get("group", []))
-
- optional_group = required_group
-
- def end_group(self) -> T.Any:
- self.pop_state()
- return []
-
- def unclosed_group(self, s: str, loc: int, toks: ParseResults) -> T.Any:
- raise ParseFatalException(s, len(s), "Expected '}'")
-
- def font(self, toks: ParseResults) -> T.Any:
- self.get_state().font = toks["font"]
- return []
-
- def is_overunder(self, nucleus: Node) -> bool:
- if isinstance(nucleus, Char):
- return nucleus.c in self._overunder_symbols
- elif isinstance(nucleus, Hlist) and hasattr(nucleus, 'function_name'):
- return nucleus.function_name in self._overunder_functions
- return False
-
- def is_dropsub(self, nucleus: Node) -> bool:
- if isinstance(nucleus, Char):
- return nucleus.c in self._dropsub_symbols
- return False
-
- def is_slanted(self, nucleus: Node) -> bool:
- if isinstance(nucleus, Char):
- return nucleus.is_slanted()
- return False
-
- def subsuper(self, s: str, loc: int, toks: ParseResults) -> T.Any:
- nucleus = toks.get("nucleus", Hbox(0))
- subsuper = toks.get("subsuper", [])
- napostrophes = len(toks.get("apostrophes", []))
-
- if not subsuper and not napostrophes:
- return nucleus
-
- sub = super = None
- while subsuper:
- op, arg, *subsuper = subsuper
- if op == '_':
- if sub is not None:
- raise ParseFatalException("Double subscript")
- sub = arg
- else:
- if super is not None:
- raise ParseFatalException("Double superscript")
- super = arg
-
- state = self.get_state()
- rule_thickness = state.fontset.get_underline_thickness(
- state.font, state.fontsize, state.dpi)
- xHeight = state.fontset.get_xheight(
- state.font, state.fontsize, state.dpi)
-
- if napostrophes:
- if super is None:
- super = Hlist([])
- for i in range(napostrophes):
- super.children.extend(self.symbol(s, loc, {"sym": "\\prime"}))
- # kern() and hpack() needed to get the metrics right after
- # extending
- super.kern()
- super.hpack()
-
- # Handle over/under symbols, such as sum or prod
- if self.is_overunder(nucleus):
- vlist = []
- shift = 0.
- width = nucleus.width
- if super is not None:
- super.shrink()
- width = max(width, super.width)
- if sub is not None:
- sub.shrink()
- width = max(width, sub.width)
-
- vgap = rule_thickness * 3.0
- if super is not None:
- hlist = HCentered([super])
- hlist.hpack(width, 'exactly')
- vlist.extend([hlist, Vbox(0, vgap)])
- hlist = HCentered([nucleus])
- hlist.hpack(width, 'exactly')
- vlist.append(hlist)
- if sub is not None:
- hlist = HCentered([sub])
- hlist.hpack(width, 'exactly')
- vlist.extend([Vbox(0, vgap), hlist])
- shift = hlist.height + vgap + nucleus.depth
- vlt = Vlist(vlist)
- vlt.shift_amount = shift
- result = Hlist([vlt])
- return [result]
-
- # We remove kerning on the last character for consistency (otherwise
- # it will compute kerning based on non-shrunk characters and may put
- # them too close together when superscripted)
- # We change the width of the last character to match the advance to
- # consider some fonts with weird metrics: e.g. stix's f has a width of
- # 7.75 and a kerning of -4.0 for an advance of 3.72, and we want to put
- # the superscript at the advance
- last_char = nucleus
- if isinstance(nucleus, Hlist):
- new_children = nucleus.children
- if len(new_children):
- # remove last kern
- if (isinstance(new_children[-1], Kern) and
- hasattr(new_children[-2], '_metrics')):
- new_children = new_children[:-1]
- last_char = new_children[-1]
- if hasattr(last_char, '_metrics'):
- last_char.width = last_char._metrics.advance
- # create new Hlist without kerning
- nucleus = Hlist(new_children, do_kern=False)
- else:
- if isinstance(nucleus, Char):
- last_char.width = last_char._metrics.advance
- nucleus = Hlist([nucleus])
-
- # Handle regular sub/superscripts
- constants = _get_font_constant_set(state)
- lc_height = last_char.height
- lc_baseline = 0
- if self.is_dropsub(last_char):
- lc_baseline = last_char.depth
-
- # Compute kerning for sub and super
- superkern = constants.delta * xHeight
- subkern = constants.delta * xHeight
- if self.is_slanted(last_char):
- superkern += constants.delta * xHeight
- superkern += (constants.delta_slanted *
- (lc_height - xHeight * 2. / 3.))
- if self.is_dropsub(last_char):
- subkern = (3 * constants.delta -
- constants.delta_integral) * lc_height
- superkern = (3 * constants.delta +
- constants.delta_integral) * lc_height
- else:
- subkern = 0
-
- x: List
- if super is None:
- # node757
- # Note: One of super or sub must be a Node if we're in this function, but
- # mypy can't know this, since it can't interpret pyparsing expressions,
- # hence the cast.
- x = Hlist([Kern(subkern), T.cast(Node, sub)])
- x.shrink()
- if self.is_dropsub(last_char):
- shift_down = lc_baseline + constants.subdrop * xHeight
- else:
- shift_down = constants.sub1 * xHeight
- x.shift_amount = shift_down
- else:
- x = Hlist([Kern(superkern), super])
- x.shrink()
- if self.is_dropsub(last_char):
- shift_up = lc_height - constants.subdrop * xHeight
- else:
- shift_up = constants.sup1 * xHeight
- if sub is None:
- x.shift_amount = -shift_up
- else: # Both sub and superscript
- y = Hlist([Kern(subkern), sub])
- y.shrink()
- if self.is_dropsub(last_char):
- shift_down = lc_baseline + constants.subdrop * xHeight
- else:
- shift_down = constants.sub2 * xHeight
- # If sub and superscript collide, move super up
- clr = (2.0 * rule_thickness -
- ((shift_up - x.depth) - (y.height - shift_down)))
- if clr > 0.:
- shift_up += clr
- x = Vlist([
- x,
- Kern((shift_up - x.depth) - (y.height - shift_down)),
- y])
- x.shift_amount = shift_down
-
- if not self.is_dropsub(last_char):
- x.width += constants.script_space * xHeight
-
- # Do we need to add a space after the nucleus?
- # To find out, check the flag set by operatorname
- spaced_nucleus = [nucleus, x]
- if self._in_subscript_or_superscript:
- spaced_nucleus += [self._make_space(self._space_widths[r'\,'])]
- self._in_subscript_or_superscript = False
-
- result = Hlist(spaced_nucleus)
- return [result]
-
- def _genfrac(self, ldelim: str, rdelim: str, rule: float | None, style: _MathStyle,
- num: Hlist, den: Hlist) -> T.Any:
- state = self.get_state()
- thickness = state.get_current_underline_thickness()
-
- for _ in range(style.value):
- num.shrink()
- den.shrink()
- cnum = HCentered([num])
- cden = HCentered([den])
- width = max(num.width, den.width)
- cnum.hpack(width, 'exactly')
- cden.hpack(width, 'exactly')
- vlist = Vlist([cnum, # numerator
- Vbox(0, thickness * 2.0), # space
- Hrule(state, rule), # rule
- Vbox(0, thickness * 2.0), # space
- cden # denominator
- ])
-
- # Shift so the fraction line sits in the middle of the
- # equals sign
- metrics = state.fontset.get_metrics(
- state.font, mpl.rcParams['mathtext.default'],
- '=', state.fontsize, state.dpi)
- shift = (cden.height -
- ((metrics.ymax + metrics.ymin) / 2 -
- thickness * 3.0))
- vlist.shift_amount = shift
-
- result = [Hlist([vlist, Hbox(thickness * 2.)])]
- if ldelim or rdelim:
- if ldelim == '':
- ldelim = '.'
- if rdelim == '':
- rdelim = '.'
- return self._auto_sized_delimiter(ldelim,
- T.cast(list[T.Union[Box, Char, str]],
- result),
- rdelim)
- return result
-
- def style_literal(self, toks: ParseResults) -> T.Any:
- return self._MathStyle(int(toks["style_literal"]))
-
- def genfrac(self, toks: ParseResults) -> T.Any:
- return self._genfrac(
- toks.get("ldelim", ""), toks.get("rdelim", ""),
- toks["rulesize"], toks.get("style", self._MathStyle.TEXTSTYLE),
- toks["num"], toks["den"])
-
- def frac(self, toks: ParseResults) -> T.Any:
- return self._genfrac(
- "", "", self.get_state().get_current_underline_thickness(),
- self._MathStyle.TEXTSTYLE, toks["num"], toks["den"])
-
- def dfrac(self, toks: ParseResults) -> T.Any:
- return self._genfrac(
- "", "", self.get_state().get_current_underline_thickness(),
- self._MathStyle.DISPLAYSTYLE, toks["num"], toks["den"])
-
- def binom(self, toks: ParseResults) -> T.Any:
- return self._genfrac(
- "(", ")", 0,
- self._MathStyle.TEXTSTYLE, toks["num"], toks["den"])
-
- def _genset(self, s: str, loc: int, toks: ParseResults) -> T.Any:
- annotation = toks["annotation"]
- body = toks["body"]
- thickness = self.get_state().get_current_underline_thickness()
-
- annotation.shrink()
- cannotation = HCentered([annotation])
- cbody = HCentered([body])
- width = max(cannotation.width, cbody.width)
- cannotation.hpack(width, 'exactly')
- cbody.hpack(width, 'exactly')
-
- vgap = thickness * 3
- if s[loc + 1] == "u": # \underset
- vlist = Vlist([cbody, # body
- Vbox(0, vgap), # space
- cannotation # annotation
- ])
- # Shift so the body sits in the same vertical position
- vlist.shift_amount = cbody.depth + cannotation.height + vgap
- else: # \overset
- vlist = Vlist([cannotation, # annotation
- Vbox(0, vgap), # space
- cbody # body
- ])
-
- # To add horizontal gap between symbols: wrap the Vlist into
- # an Hlist and extend it with an Hbox(0, horizontal_gap)
- return vlist
-
- overset = underset = _genset
-
- def sqrt(self, toks: ParseResults) -> T.Any:
- root = toks.get("root")
- body = toks["value"]
- state = self.get_state()
- thickness = state.get_current_underline_thickness()
-
- # Determine the height of the body, and add a little extra to
- # the height so it doesn't seem cramped
- height = body.height - body.shift_amount + thickness * 5.0
- depth = body.depth + body.shift_amount
- check = AutoHeightChar(r'\__sqrt__', height, depth, state, always=True)
- height = check.height - check.shift_amount
- depth = check.depth + check.shift_amount
-
- # Put a little extra space to the left and right of the body
- padded_body = Hlist([Hbox(2 * thickness), body, Hbox(2 * thickness)])
- rightside = Vlist([Hrule(state), Glue('fill'), padded_body])
- # Stretch the glue between the hrule and the body
- rightside.vpack(height + (state.fontsize * state.dpi) / (100.0 * 12.0),
- 'exactly', depth)
-
- # Add the root and shift it upward so it is above the tick.
- # The value of 0.6 is a hard-coded hack ;)
- if not root:
- root = Box(check.width * 0.5, 0., 0.)
- else:
- root = Hlist(root)
- root.shrink()
- root.shrink()
-
- root_vlist = Vlist([Hlist([root])])
- root_vlist.shift_amount = -height * 0.6
-
- hlist = Hlist([root_vlist, # Root
- # Negative kerning to put root over tick
- Kern(-check.width * 0.5),
- check, # Check
- rightside]) # Body
- return [hlist]
-
- def overline(self, toks: ParseResults) -> T.Any:
- body = toks["body"]
-
- state = self.get_state()
- thickness = state.get_current_underline_thickness()
-
- height = body.height - body.shift_amount + thickness * 3.0
- depth = body.depth + body.shift_amount
-
- # Place overline above body
- rightside = Vlist([Hrule(state), Glue('fill'), Hlist([body])])
-
- # Stretch the glue between the hrule and the body
- rightside.vpack(height + (state.fontsize * state.dpi) / (100.0 * 12.0),
- 'exactly', depth)
-
- hlist = Hlist([rightside])
- return [hlist]
-
- def _auto_sized_delimiter(self, front: str,
- middle: list[Box | Char | str],
- back: str) -> T.Any:
- state = self.get_state()
- if len(middle):
- height = max([x.height for x in middle if not isinstance(x, str)])
- depth = max([x.depth for x in middle if not isinstance(x, str)])
- factor = None
- for idx, el in enumerate(middle):
- if isinstance(el, str) and el == '\\middle':
- c = T.cast(str, middle[idx + 1]) # Should be one of p.delims.
- if c != '.':
- middle[idx + 1] = AutoHeightChar(
- c, height, depth, state, factor=factor)
- else:
- middle.remove(c)
- del middle[idx]
- # There should only be \middle and its delimiter as str, which have
- # just been removed.
- middle_part = T.cast(list[T.Union[Box, Char]], middle)
- else:
- height = 0
- depth = 0
- factor = 1.0
- middle_part = []
-
- parts: list[Node] = []
- # \left. and \right. aren't supposed to produce any symbols
- if front != '.':
- parts.append(
- AutoHeightChar(front, height, depth, state, factor=factor))
- parts.extend(middle_part)
- if back != '.':
- parts.append(
- AutoHeightChar(back, height, depth, state, factor=factor))
- hlist = Hlist(parts)
- return hlist
-
- def auto_delim(self, toks: ParseResults) -> T.Any:
- return self._auto_sized_delimiter(
- toks["left"],
- # if "mid" in toks ... can be removed when requiring pyparsing 3.
- toks["mid"].asList() if "mid" in toks else [],
- toks["right"])
-
- def boldsymbol(self, toks: ParseResults) -> T.Any:
- self.push_state()
- state = self.get_state()
- hlist: list[Node] = []
- name = toks["value"]
- for c in name:
- if isinstance(c, Hlist):
- k = c.children[1]
- if isinstance(k, Char):
- k.font = "bf"
- k._update_metrics()
- hlist.append(c)
- elif isinstance(c, Char):
- c.font = "bf"
- if (c.c in self._latin_alphabets or
- c.c[1:] in self._small_greek):
- c.font = "bfit"
- c._update_metrics()
- c._update_metrics()
- hlist.append(c)
- else:
- hlist.append(c)
- self.pop_state()
-
- return Hlist(hlist)
-
- def substack(self, toks: ParseResults) -> T.Any:
- parts = toks["parts"]
- state = self.get_state()
- thickness = state.get_current_underline_thickness()
-
- hlist = [Hlist(k) for k in parts[0]]
- max_width = max(map(lambda c: c.width, hlist))
-
- vlist = []
- for sub in hlist:
- cp = HCentered([sub])
- cp.hpack(max_width, 'exactly')
- vlist.append(cp)
-
- stack = [val
- for pair in zip(vlist, [Vbox(0, thickness * 2)] * len(vlist))
- for val in pair]
- del stack[-1]
- vlt = Vlist(stack)
- result = [Hlist([vlt])]
- return result
diff --git a/contrib/python/matplotlib/py3/matplotlib/_mathtext_data.py b/contrib/python/matplotlib/py3/matplotlib/_mathtext_data.py
deleted file mode 100644
index baaee1b876..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_mathtext_data.py
+++ /dev/null
@@ -1,1311 +0,0 @@
-"""
-font data tables for truetype and afm computer modern fonts
-"""
-
-from __future__ import annotations
-
-
-latex_to_bakoma = {
- '\\__sqrt__' : ('cmex10', 0x70),
- '\\bigcap' : ('cmex10', 0x5c),
- '\\bigcup' : ('cmex10', 0x5b),
- '\\bigodot' : ('cmex10', 0x4b),
- '\\bigoplus' : ('cmex10', 0x4d),
- '\\bigotimes' : ('cmex10', 0x4f),
- '\\biguplus' : ('cmex10', 0x5d),
- '\\bigvee' : ('cmex10', 0x5f),
- '\\bigwedge' : ('cmex10', 0x5e),
- '\\coprod' : ('cmex10', 0x61),
- '\\int' : ('cmex10', 0x5a),
- '\\langle' : ('cmex10', 0xad),
- '\\leftangle' : ('cmex10', 0xad),
- '\\leftbrace' : ('cmex10', 0xa9),
- '\\oint' : ('cmex10', 0x49),
- '\\prod' : ('cmex10', 0x59),
- '\\rangle' : ('cmex10', 0xae),
- '\\rightangle' : ('cmex10', 0xae),
- '\\rightbrace' : ('cmex10', 0xaa),
- '\\sum' : ('cmex10', 0x58),
- '\\widehat' : ('cmex10', 0x62),
- '\\widetilde' : ('cmex10', 0x65),
- '\\{' : ('cmex10', 0xa9),
- '\\}' : ('cmex10', 0xaa),
- '{' : ('cmex10', 0xa9),
- '}' : ('cmex10', 0xaa),
-
- ',' : ('cmmi10', 0x3b),
- '.' : ('cmmi10', 0x3a),
- '/' : ('cmmi10', 0x3d),
- '<' : ('cmmi10', 0x3c),
- '>' : ('cmmi10', 0x3e),
- '\\alpha' : ('cmmi10', 0xae),
- '\\beta' : ('cmmi10', 0xaf),
- '\\chi' : ('cmmi10', 0xc2),
- '\\combiningrightarrowabove' : ('cmmi10', 0x7e),
- '\\delta' : ('cmmi10', 0xb1),
- '\\ell' : ('cmmi10', 0x60),
- '\\epsilon' : ('cmmi10', 0xb2),
- '\\eta' : ('cmmi10', 0xb4),
- '\\flat' : ('cmmi10', 0x5b),
- '\\frown' : ('cmmi10', 0x5f),
- '\\gamma' : ('cmmi10', 0xb0),
- '\\imath' : ('cmmi10', 0x7b),
- '\\iota' : ('cmmi10', 0xb6),
- '\\jmath' : ('cmmi10', 0x7c),
- '\\kappa' : ('cmmi10', 0x2219),
- '\\lambda' : ('cmmi10', 0xb8),
- '\\leftharpoondown' : ('cmmi10', 0x29),
- '\\leftharpoonup' : ('cmmi10', 0x28),
- '\\mu' : ('cmmi10', 0xb9),
- '\\natural' : ('cmmi10', 0x5c),
- '\\nu' : ('cmmi10', 0xba),
- '\\omega' : ('cmmi10', 0x21),
- '\\phi' : ('cmmi10', 0xc1),
- '\\pi' : ('cmmi10', 0xbc),
- '\\psi' : ('cmmi10', 0xc3),
- '\\rho' : ('cmmi10', 0xbd),
- '\\rightharpoondown' : ('cmmi10', 0x2b),
- '\\rightharpoonup' : ('cmmi10', 0x2a),
- '\\sharp' : ('cmmi10', 0x5d),
- '\\sigma' : ('cmmi10', 0xbe),
- '\\smile' : ('cmmi10', 0x5e),
- '\\tau' : ('cmmi10', 0xbf),
- '\\theta' : ('cmmi10', 0xb5),
- '\\triangleleft' : ('cmmi10', 0x2f),
- '\\triangleright' : ('cmmi10', 0x2e),
- '\\upsilon' : ('cmmi10', 0xc0),
- '\\varepsilon' : ('cmmi10', 0x22),
- '\\varphi' : ('cmmi10', 0x27),
- '\\varrho' : ('cmmi10', 0x25),
- '\\varsigma' : ('cmmi10', 0x26),
- '\\vartheta' : ('cmmi10', 0x23),
- '\\wp' : ('cmmi10', 0x7d),
- '\\xi' : ('cmmi10', 0xbb),
- '\\zeta' : ('cmmi10', 0xb3),
-
- '!' : ('cmr10', 0x21),
- '%' : ('cmr10', 0x25),
- '&' : ('cmr10', 0x26),
- '(' : ('cmr10', 0x28),
- ')' : ('cmr10', 0x29),
- '+' : ('cmr10', 0x2b),
- '0' : ('cmr10', 0x30),
- '1' : ('cmr10', 0x31),
- '2' : ('cmr10', 0x32),
- '3' : ('cmr10', 0x33),
- '4' : ('cmr10', 0x34),
- '5' : ('cmr10', 0x35),
- '6' : ('cmr10', 0x36),
- '7' : ('cmr10', 0x37),
- '8' : ('cmr10', 0x38),
- '9' : ('cmr10', 0x39),
- ':' : ('cmr10', 0x3a),
- ';' : ('cmr10', 0x3b),
- '=' : ('cmr10', 0x3d),
- '?' : ('cmr10', 0x3f),
- '@' : ('cmr10', 0x40),
- '[' : ('cmr10', 0x5b),
- '\\#' : ('cmr10', 0x23),
- '\\$' : ('cmr10', 0x24),
- '\\%' : ('cmr10', 0x25),
- '\\Delta' : ('cmr10', 0xa2),
- '\\Gamma' : ('cmr10', 0xa1),
- '\\Lambda' : ('cmr10', 0xa4),
- '\\Omega' : ('cmr10', 0xad),
- '\\Phi' : ('cmr10', 0xa9),
- '\\Pi' : ('cmr10', 0xa6),
- '\\Psi' : ('cmr10', 0xaa),
- '\\Sigma' : ('cmr10', 0xa7),
- '\\Theta' : ('cmr10', 0xa3),
- '\\Upsilon' : ('cmr10', 0xa8),
- '\\Xi' : ('cmr10', 0xa5),
- '\\circumflexaccent' : ('cmr10', 0x5e),
- '\\combiningacuteaccent' : ('cmr10', 0xb6),
- '\\combiningbreve' : ('cmr10', 0xb8),
- '\\combiningdiaeresis' : ('cmr10', 0xc4),
- '\\combiningdotabove' : ('cmr10', 0x5f),
- '\\combininggraveaccent' : ('cmr10', 0xb5),
- '\\combiningoverline' : ('cmr10', 0xb9),
- '\\combiningtilde' : ('cmr10', 0x7e),
- '\\leftbracket' : ('cmr10', 0x5b),
- '\\leftparen' : ('cmr10', 0x28),
- '\\rightbracket' : ('cmr10', 0x5d),
- '\\rightparen' : ('cmr10', 0x29),
- '\\widebar' : ('cmr10', 0xb9),
- ']' : ('cmr10', 0x5d),
-
- '*' : ('cmsy10', 0xa4),
- '\N{MINUS SIGN}' : ('cmsy10', 0xa1),
- '\\Downarrow' : ('cmsy10', 0x2b),
- '\\Im' : ('cmsy10', 0x3d),
- '\\Leftarrow' : ('cmsy10', 0x28),
- '\\Leftrightarrow' : ('cmsy10', 0x2c),
- '\\P' : ('cmsy10', 0x7b),
- '\\Re' : ('cmsy10', 0x3c),
- '\\Rightarrow' : ('cmsy10', 0x29),
- '\\S' : ('cmsy10', 0x78),
- '\\Uparrow' : ('cmsy10', 0x2a),
- '\\Updownarrow' : ('cmsy10', 0x6d),
- '\\Vert' : ('cmsy10', 0x6b),
- '\\aleph' : ('cmsy10', 0x40),
- '\\approx' : ('cmsy10', 0xbc),
- '\\ast' : ('cmsy10', 0xa4),
- '\\asymp' : ('cmsy10', 0xb3),
- '\\backslash' : ('cmsy10', 0x6e),
- '\\bigcirc' : ('cmsy10', 0xb0),
- '\\bigtriangledown' : ('cmsy10', 0x35),
- '\\bigtriangleup' : ('cmsy10', 0x34),
- '\\bot' : ('cmsy10', 0x3f),
- '\\bullet' : ('cmsy10', 0xb2),
- '\\cap' : ('cmsy10', 0x5c),
- '\\cdot' : ('cmsy10', 0xa2),
- '\\circ' : ('cmsy10', 0xb1),
- '\\clubsuit' : ('cmsy10', 0x7c),
- '\\cup' : ('cmsy10', 0x5b),
- '\\dag' : ('cmsy10', 0x79),
- '\\dashv' : ('cmsy10', 0x61),
- '\\ddag' : ('cmsy10', 0x7a),
- '\\diamond' : ('cmsy10', 0xa6),
- '\\diamondsuit' : ('cmsy10', 0x7d),
- '\\div' : ('cmsy10', 0xa5),
- '\\downarrow' : ('cmsy10', 0x23),
- '\\emptyset' : ('cmsy10', 0x3b),
- '\\equiv' : ('cmsy10', 0xb4),
- '\\exists' : ('cmsy10', 0x39),
- '\\forall' : ('cmsy10', 0x38),
- '\\geq' : ('cmsy10', 0xb8),
- '\\gg' : ('cmsy10', 0xc0),
- '\\heartsuit' : ('cmsy10', 0x7e),
- '\\in' : ('cmsy10', 0x32),
- '\\infty' : ('cmsy10', 0x31),
- '\\lbrace' : ('cmsy10', 0x66),
- '\\lceil' : ('cmsy10', 0x64),
- '\\leftarrow' : ('cmsy10', 0xc3),
- '\\leftrightarrow' : ('cmsy10', 0x24),
- '\\leq' : ('cmsy10', 0x2219),
- '\\lfloor' : ('cmsy10', 0x62),
- '\\ll' : ('cmsy10', 0xbf),
- '\\mid' : ('cmsy10', 0x6a),
- '\\mp' : ('cmsy10', 0xa8),
- '\\nabla' : ('cmsy10', 0x72),
- '\\nearrow' : ('cmsy10', 0x25),
- '\\neg' : ('cmsy10', 0x3a),
- '\\ni' : ('cmsy10', 0x33),
- '\\nwarrow' : ('cmsy10', 0x2d),
- '\\odot' : ('cmsy10', 0xaf),
- '\\ominus' : ('cmsy10', 0xaa),
- '\\oplus' : ('cmsy10', 0xa9),
- '\\oslash' : ('cmsy10', 0xae),
- '\\otimes' : ('cmsy10', 0xad),
- '\\pm' : ('cmsy10', 0xa7),
- '\\prec' : ('cmsy10', 0xc1),
- '\\preceq' : ('cmsy10', 0xb9),
- '\\prime' : ('cmsy10', 0x30),
- '\\propto' : ('cmsy10', 0x2f),
- '\\rbrace' : ('cmsy10', 0x67),
- '\\rceil' : ('cmsy10', 0x65),
- '\\rfloor' : ('cmsy10', 0x63),
- '\\rightarrow' : ('cmsy10', 0x21),
- '\\searrow' : ('cmsy10', 0x26),
- '\\sim' : ('cmsy10', 0xbb),
- '\\simeq' : ('cmsy10', 0x27),
- '\\slash' : ('cmsy10', 0x36),
- '\\spadesuit' : ('cmsy10', 0xc4),
- '\\sqcap' : ('cmsy10', 0x75),
- '\\sqcup' : ('cmsy10', 0x74),
- '\\sqsubseteq' : ('cmsy10', 0x76),
- '\\sqsupseteq' : ('cmsy10', 0x77),
- '\\subset' : ('cmsy10', 0xbd),
- '\\subseteq' : ('cmsy10', 0xb5),
- '\\succ' : ('cmsy10', 0xc2),
- '\\succeq' : ('cmsy10', 0xba),
- '\\supset' : ('cmsy10', 0xbe),
- '\\supseteq' : ('cmsy10', 0xb6),
- '\\swarrow' : ('cmsy10', 0x2e),
- '\\times' : ('cmsy10', 0xa3),
- '\\to' : ('cmsy10', 0x21),
- '\\top' : ('cmsy10', 0x3e),
- '\\uparrow' : ('cmsy10', 0x22),
- '\\updownarrow' : ('cmsy10', 0x6c),
- '\\uplus' : ('cmsy10', 0x5d),
- '\\vdash' : ('cmsy10', 0x60),
- '\\vee' : ('cmsy10', 0x5f),
- '\\vert' : ('cmsy10', 0x6a),
- '\\wedge' : ('cmsy10', 0x5e),
- '\\wr' : ('cmsy10', 0x6f),
- '\\|' : ('cmsy10', 0x6b),
- '|' : ('cmsy10', 0x6a),
-
- '\\_' : ('cmtt10', 0x5f)
-}
-
-# Automatically generated.
-
-type12uni = {
- 'aring' : 229,
- 'quotedblright' : 8221,
- 'V' : 86,
- 'dollar' : 36,
- 'four' : 52,
- 'Yacute' : 221,
- 'P' : 80,
- 'underscore' : 95,
- 'p' : 112,
- 'Otilde' : 213,
- 'perthousand' : 8240,
- 'zero' : 48,
- 'dotlessi' : 305,
- 'Scaron' : 352,
- 'zcaron' : 382,
- 'egrave' : 232,
- 'section' : 167,
- 'Icircumflex' : 206,
- 'ntilde' : 241,
- 'ampersand' : 38,
- 'dotaccent' : 729,
- 'degree' : 176,
- 'K' : 75,
- 'acircumflex' : 226,
- 'Aring' : 197,
- 'k' : 107,
- 'smalltilde' : 732,
- 'Agrave' : 192,
- 'divide' : 247,
- 'ocircumflex' : 244,
- 'asciitilde' : 126,
- 'two' : 50,
- 'E' : 69,
- 'scaron' : 353,
- 'F' : 70,
- 'bracketleft' : 91,
- 'asciicircum' : 94,
- 'f' : 102,
- 'ordmasculine' : 186,
- 'mu' : 181,
- 'paragraph' : 182,
- 'nine' : 57,
- 'v' : 118,
- 'guilsinglleft' : 8249,
- 'backslash' : 92,
- 'six' : 54,
- 'A' : 65,
- 'icircumflex' : 238,
- 'a' : 97,
- 'ogonek' : 731,
- 'q' : 113,
- 'oacute' : 243,
- 'ograve' : 242,
- 'edieresis' : 235,
- 'comma' : 44,
- 'otilde' : 245,
- 'guillemotright' : 187,
- 'ecircumflex' : 234,
- 'greater' : 62,
- 'uacute' : 250,
- 'L' : 76,
- 'bullet' : 8226,
- 'cedilla' : 184,
- 'ydieresis' : 255,
- 'l' : 108,
- 'logicalnot' : 172,
- 'exclamdown' : 161,
- 'endash' : 8211,
- 'agrave' : 224,
- 'Adieresis' : 196,
- 'germandbls' : 223,
- 'Odieresis' : 214,
- 'space' : 32,
- 'quoteright' : 8217,
- 'ucircumflex' : 251,
- 'G' : 71,
- 'quoteleft' : 8216,
- 'W' : 87,
- 'Q' : 81,
- 'g' : 103,
- 'w' : 119,
- 'question' : 63,
- 'one' : 49,
- 'ring' : 730,
- 'figuredash' : 8210,
- 'B' : 66,
- 'iacute' : 237,
- 'Ydieresis' : 376,
- 'R' : 82,
- 'b' : 98,
- 'r' : 114,
- 'Ccedilla' : 199,
- 'minus' : 8722,
- 'Lslash' : 321,
- 'Uacute' : 218,
- 'yacute' : 253,
- 'Ucircumflex' : 219,
- 'quotedbl' : 34,
- 'onehalf' : 189,
- 'Thorn' : 222,
- 'M' : 77,
- 'eight' : 56,
- 'multiply' : 215,
- 'grave' : 96,
- 'Ocircumflex' : 212,
- 'm' : 109,
- 'Ugrave' : 217,
- 'guilsinglright' : 8250,
- 'Ntilde' : 209,
- 'questiondown' : 191,
- 'Atilde' : 195,
- 'ccedilla' : 231,
- 'Z' : 90,
- 'copyright' : 169,
- 'yen' : 165,
- 'Eacute' : 201,
- 'H' : 72,
- 'X' : 88,
- 'Idieresis' : 207,
- 'bar' : 124,
- 'h' : 104,
- 'x' : 120,
- 'udieresis' : 252,
- 'ordfeminine' : 170,
- 'braceleft' : 123,
- 'macron' : 175,
- 'atilde' : 227,
- 'Acircumflex' : 194,
- 'Oslash' : 216,
- 'C' : 67,
- 'quotedblleft' : 8220,
- 'S' : 83,
- 'exclam' : 33,
- 'Zcaron' : 381,
- 'equal' : 61,
- 's' : 115,
- 'eth' : 240,
- 'Egrave' : 200,
- 'hyphen' : 45,
- 'period' : 46,
- 'igrave' : 236,
- 'colon' : 58,
- 'Ecircumflex' : 202,
- 'trademark' : 8482,
- 'Aacute' : 193,
- 'cent' : 162,
- 'lslash' : 322,
- 'c' : 99,
- 'N' : 78,
- 'breve' : 728,
- 'Oacute' : 211,
- 'guillemotleft' : 171,
- 'n' : 110,
- 'idieresis' : 239,
- 'braceright' : 125,
- 'seven' : 55,
- 'brokenbar' : 166,
- 'ugrave' : 249,
- 'periodcentered' : 183,
- 'sterling' : 163,
- 'I' : 73,
- 'Y' : 89,
- 'Eth' : 208,
- 'emdash' : 8212,
- 'i' : 105,
- 'daggerdbl' : 8225,
- 'y' : 121,
- 'plusminus' : 177,
- 'less' : 60,
- 'Udieresis' : 220,
- 'D' : 68,
- 'five' : 53,
- 'T' : 84,
- 'oslash' : 248,
- 'acute' : 180,
- 'd' : 100,
- 'OE' : 338,
- 'Igrave' : 204,
- 't' : 116,
- 'parenright' : 41,
- 'adieresis' : 228,
- 'quotesingle' : 39,
- 'twodotenleader' : 8229,
- 'slash' : 47,
- 'ellipsis' : 8230,
- 'numbersign' : 35,
- 'odieresis' : 246,
- 'O' : 79,
- 'oe' : 339,
- 'o' : 111,
- 'Edieresis' : 203,
- 'plus' : 43,
- 'dagger' : 8224,
- 'three' : 51,
- 'hungarumlaut' : 733,
- 'parenleft' : 40,
- 'fraction' : 8260,
- 'registered' : 174,
- 'J' : 74,
- 'dieresis' : 168,
- 'Ograve' : 210,
- 'j' : 106,
- 'z' : 122,
- 'ae' : 230,
- 'semicolon' : 59,
- 'at' : 64,
- 'Iacute' : 205,
- 'percent' : 37,
- 'bracketright' : 93,
- 'AE' : 198,
- 'asterisk' : 42,
- 'aacute' : 225,
- 'U' : 85,
- 'eacute' : 233,
- 'e' : 101,
- 'thorn' : 254,
- 'u' : 117,
-}
-
-uni2type1 = {v: k for k, v in type12uni.items()}
-
-# The script below is to sort and format the tex2uni dict
-
-## For decimal values: int(hex(v), 16)
-# newtex = {k: hex(v) for k, v in tex2uni.items()}
-# sd = dict(sorted(newtex.items(), key=lambda item: item[0]))
-#
-## For formatting the sorted dictionary with proper spacing
-## the value '24' comes from finding the longest string in
-## the newtex keys with len(max(newtex, key=len))
-# for key in sd:
-# print("{0:24} : {1: <s},".format("'" + key + "'", sd[key]))
-
-tex2uni = {
- '#' : 0x23,
- '$' : 0x24,
- '%' : 0x25,
- 'AA' : 0xc5,
- 'AE' : 0xc6,
- 'BbbC' : 0x2102,
- 'BbbN' : 0x2115,
- 'BbbP' : 0x2119,
- 'BbbQ' : 0x211a,
- 'BbbR' : 0x211d,
- 'BbbZ' : 0x2124,
- 'Bumpeq' : 0x224e,
- 'Cap' : 0x22d2,
- 'Colon' : 0x2237,
- 'Cup' : 0x22d3,
- 'DH' : 0xd0,
- 'Delta' : 0x394,
- 'Doteq' : 0x2251,
- 'Downarrow' : 0x21d3,
- 'Equiv' : 0x2263,
- 'Finv' : 0x2132,
- 'Game' : 0x2141,
- 'Gamma' : 0x393,
- 'H' : 0x30b,
- 'Im' : 0x2111,
- 'Join' : 0x2a1d,
- 'L' : 0x141,
- 'Lambda' : 0x39b,
- 'Ldsh' : 0x21b2,
- 'Leftarrow' : 0x21d0,
- 'Leftrightarrow' : 0x21d4,
- 'Lleftarrow' : 0x21da,
- 'Longleftarrow' : 0x27f8,
- 'Longleftrightarrow' : 0x27fa,
- 'Longrightarrow' : 0x27f9,
- 'Lsh' : 0x21b0,
- 'Nearrow' : 0x21d7,
- 'Nwarrow' : 0x21d6,
- 'O' : 0xd8,
- 'OE' : 0x152,
- 'Omega' : 0x3a9,
- 'P' : 0xb6,
- 'Phi' : 0x3a6,
- 'Pi' : 0x3a0,
- 'Psi' : 0x3a8,
- 'QED' : 0x220e,
- 'Rdsh' : 0x21b3,
- 'Re' : 0x211c,
- 'Rightarrow' : 0x21d2,
- 'Rrightarrow' : 0x21db,
- 'Rsh' : 0x21b1,
- 'S' : 0xa7,
- 'Searrow' : 0x21d8,
- 'Sigma' : 0x3a3,
- 'Subset' : 0x22d0,
- 'Supset' : 0x22d1,
- 'Swarrow' : 0x21d9,
- 'Theta' : 0x398,
- 'Thorn' : 0xde,
- 'Uparrow' : 0x21d1,
- 'Updownarrow' : 0x21d5,
- 'Upsilon' : 0x3a5,
- 'Vdash' : 0x22a9,
- 'Vert' : 0x2016,
- 'Vvdash' : 0x22aa,
- 'Xi' : 0x39e,
- '_' : 0x5f,
- '__sqrt__' : 0x221a,
- 'aa' : 0xe5,
- 'ac' : 0x223e,
- 'acute' : 0x301,
- 'acwopencirclearrow' : 0x21ba,
- 'adots' : 0x22f0,
- 'ae' : 0xe6,
- 'aleph' : 0x2135,
- 'alpha' : 0x3b1,
- 'amalg' : 0x2a3f,
- 'angle' : 0x2220,
- 'approx' : 0x2248,
- 'approxeq' : 0x224a,
- 'approxident' : 0x224b,
- 'arceq' : 0x2258,
- 'ast' : 0x2217,
- 'asterisk' : 0x2a,
- 'asymp' : 0x224d,
- 'backcong' : 0x224c,
- 'backepsilon' : 0x3f6,
- 'backprime' : 0x2035,
- 'backsim' : 0x223d,
- 'backsimeq' : 0x22cd,
- 'backslash' : 0x5c,
- 'bagmember' : 0x22ff,
- 'bar' : 0x304,
- 'barleftarrow' : 0x21e4,
- 'barvee' : 0x22bd,
- 'barwedge' : 0x22bc,
- 'because' : 0x2235,
- 'beta' : 0x3b2,
- 'beth' : 0x2136,
- 'between' : 0x226c,
- 'bigcap' : 0x22c2,
- 'bigcirc' : 0x25cb,
- 'bigcup' : 0x22c3,
- 'bigodot' : 0x2a00,
- 'bigoplus' : 0x2a01,
- 'bigotimes' : 0x2a02,
- 'bigsqcup' : 0x2a06,
- 'bigstar' : 0x2605,
- 'bigtriangledown' : 0x25bd,
- 'bigtriangleup' : 0x25b3,
- 'biguplus' : 0x2a04,
- 'bigvee' : 0x22c1,
- 'bigwedge' : 0x22c0,
- 'blacksquare' : 0x25a0,
- 'blacktriangle' : 0x25b4,
- 'blacktriangledown' : 0x25be,
- 'blacktriangleleft' : 0x25c0,
- 'blacktriangleright' : 0x25b6,
- 'bot' : 0x22a5,
- 'bowtie' : 0x22c8,
- 'boxbar' : 0x25eb,
- 'boxdot' : 0x22a1,
- 'boxminus' : 0x229f,
- 'boxplus' : 0x229e,
- 'boxtimes' : 0x22a0,
- 'breve' : 0x306,
- 'bullet' : 0x2219,
- 'bumpeq' : 0x224f,
- 'c' : 0x327,
- 'candra' : 0x310,
- 'cap' : 0x2229,
- 'carriagereturn' : 0x21b5,
- 'cdot' : 0x22c5,
- 'cdotp' : 0xb7,
- 'cdots' : 0x22ef,
- 'cent' : 0xa2,
- 'check' : 0x30c,
- 'checkmark' : 0x2713,
- 'chi' : 0x3c7,
- 'circ' : 0x2218,
- 'circeq' : 0x2257,
- 'circlearrowleft' : 0x21ba,
- 'circlearrowright' : 0x21bb,
- 'circledR' : 0xae,
- 'circledS' : 0x24c8,
- 'circledast' : 0x229b,
- 'circledcirc' : 0x229a,
- 'circleddash' : 0x229d,
- 'circumflexaccent' : 0x302,
- 'clubsuit' : 0x2663,
- 'clubsuitopen' : 0x2667,
- 'colon' : 0x3a,
- 'coloneq' : 0x2254,
- 'combiningacuteaccent' : 0x301,
- 'combiningbreve' : 0x306,
- 'combiningdiaeresis' : 0x308,
- 'combiningdotabove' : 0x307,
- 'combiningfourdotsabove' : 0x20dc,
- 'combininggraveaccent' : 0x300,
- 'combiningoverline' : 0x304,
- 'combiningrightarrowabove' : 0x20d7,
- 'combiningthreedotsabove' : 0x20db,
- 'combiningtilde' : 0x303,
- 'complement' : 0x2201,
- 'cong' : 0x2245,
- 'coprod' : 0x2210,
- 'copyright' : 0xa9,
- 'cup' : 0x222a,
- 'cupdot' : 0x228d,
- 'cupleftarrow' : 0x228c,
- 'curlyeqprec' : 0x22de,
- 'curlyeqsucc' : 0x22df,
- 'curlyvee' : 0x22ce,
- 'curlywedge' : 0x22cf,
- 'curvearrowleft' : 0x21b6,
- 'curvearrowright' : 0x21b7,
- 'cwopencirclearrow' : 0x21bb,
- 'd' : 0x323,
- 'dag' : 0x2020,
- 'dagger' : 0x2020,
- 'daleth' : 0x2138,
- 'danger' : 0x2621,
- 'dashleftarrow' : 0x290e,
- 'dashrightarrow' : 0x290f,
- 'dashv' : 0x22a3,
- 'ddag' : 0x2021,
- 'ddagger' : 0x2021,
- 'ddddot' : 0x20dc,
- 'dddot' : 0x20db,
- 'ddot' : 0x308,
- 'ddots' : 0x22f1,
- 'degree' : 0xb0,
- 'delta' : 0x3b4,
- 'dh' : 0xf0,
- 'diamond' : 0x22c4,
- 'diamondsuit' : 0x2662,
- 'digamma' : 0x3dd,
- 'disin' : 0x22f2,
- 'div' : 0xf7,
- 'divideontimes' : 0x22c7,
- 'dot' : 0x307,
- 'doteq' : 0x2250,
- 'doteqdot' : 0x2251,
- 'dotminus' : 0x2238,
- 'dotplus' : 0x2214,
- 'dots' : 0x2026,
- 'dotsminusdots' : 0x223a,
- 'doublebarwedge' : 0x2306,
- 'downarrow' : 0x2193,
- 'downdownarrows' : 0x21ca,
- 'downharpoonleft' : 0x21c3,
- 'downharpoonright' : 0x21c2,
- 'downzigzagarrow' : 0x21af,
- 'ell' : 0x2113,
- 'emdash' : 0x2014,
- 'emptyset' : 0x2205,
- 'endash' : 0x2013,
- 'epsilon' : 0x3b5,
- 'eqcirc' : 0x2256,
- 'eqcolon' : 0x2255,
- 'eqdef' : 0x225d,
- 'eqgtr' : 0x22dd,
- 'eqless' : 0x22dc,
- 'eqsim' : 0x2242,
- 'eqslantgtr' : 0x2a96,
- 'eqslantless' : 0x2a95,
- 'equal' : 0x3d,
- 'equalparallel' : 0x22d5,
- 'equiv' : 0x2261,
- 'eta' : 0x3b7,
- 'eth' : 0xf0,
- 'exists' : 0x2203,
- 'fallingdotseq' : 0x2252,
- 'flat' : 0x266d,
- 'forall' : 0x2200,
- 'frakC' : 0x212d,
- 'frakZ' : 0x2128,
- 'frown' : 0x2322,
- 'gamma' : 0x3b3,
- 'geq' : 0x2265,
- 'geqq' : 0x2267,
- 'geqslant' : 0x2a7e,
- 'gg' : 0x226b,
- 'ggg' : 0x22d9,
- 'gimel' : 0x2137,
- 'gnapprox' : 0x2a8a,
- 'gneqq' : 0x2269,
- 'gnsim' : 0x22e7,
- 'grave' : 0x300,
- 'greater' : 0x3e,
- 'gtrapprox' : 0x2a86,
- 'gtrdot' : 0x22d7,
- 'gtreqless' : 0x22db,
- 'gtreqqless' : 0x2a8c,
- 'gtrless' : 0x2277,
- 'gtrsim' : 0x2273,
- 'guillemotleft' : 0xab,
- 'guillemotright' : 0xbb,
- 'guilsinglleft' : 0x2039,
- 'guilsinglright' : 0x203a,
- 'hat' : 0x302,
- 'hbar' : 0x127,
- 'heartsuit' : 0x2661,
- 'hermitmatrix' : 0x22b9,
- 'hookleftarrow' : 0x21a9,
- 'hookrightarrow' : 0x21aa,
- 'hslash' : 0x210f,
- 'i' : 0x131,
- 'iiiint' : 0x2a0c,
- 'iiint' : 0x222d,
- 'iint' : 0x222c,
- 'imageof' : 0x22b7,
- 'imath' : 0x131,
- 'in' : 0x2208,
- 'increment' : 0x2206,
- 'infty' : 0x221e,
- 'int' : 0x222b,
- 'intercal' : 0x22ba,
- 'invnot' : 0x2310,
- 'iota' : 0x3b9,
- 'isinE' : 0x22f9,
- 'isindot' : 0x22f5,
- 'isinobar' : 0x22f7,
- 'isins' : 0x22f4,
- 'isinvb' : 0x22f8,
- 'jmath' : 0x237,
- 'k' : 0x328,
- 'kappa' : 0x3ba,
- 'kernelcontraction' : 0x223b,
- 'l' : 0x142,
- 'lambda' : 0x3bb,
- 'lambdabar' : 0x19b,
- 'langle' : 0x27e8,
- 'lasp' : 0x2bd,
- 'lbrace' : 0x7b,
- 'lbrack' : 0x5b,
- 'lceil' : 0x2308,
- 'ldots' : 0x2026,
- 'leadsto' : 0x21dd,
- 'leftarrow' : 0x2190,
- 'leftarrowtail' : 0x21a2,
- 'leftbrace' : 0x7b,
- 'leftharpoonaccent' : 0x20d0,
- 'leftharpoondown' : 0x21bd,
- 'leftharpoonup' : 0x21bc,
- 'leftleftarrows' : 0x21c7,
- 'leftparen' : 0x28,
- 'leftrightarrow' : 0x2194,
- 'leftrightarrows' : 0x21c6,
- 'leftrightharpoons' : 0x21cb,
- 'leftrightsquigarrow' : 0x21ad,
- 'leftsquigarrow' : 0x219c,
- 'leftthreetimes' : 0x22cb,
- 'leq' : 0x2264,
- 'leqq' : 0x2266,
- 'leqslant' : 0x2a7d,
- 'less' : 0x3c,
- 'lessapprox' : 0x2a85,
- 'lessdot' : 0x22d6,
- 'lesseqgtr' : 0x22da,
- 'lesseqqgtr' : 0x2a8b,
- 'lessgtr' : 0x2276,
- 'lesssim' : 0x2272,
- 'lfloor' : 0x230a,
- 'lgroup' : 0x27ee,
- 'lhd' : 0x25c1,
- 'll' : 0x226a,
- 'llcorner' : 0x231e,
- 'lll' : 0x22d8,
- 'lnapprox' : 0x2a89,
- 'lneqq' : 0x2268,
- 'lnsim' : 0x22e6,
- 'longleftarrow' : 0x27f5,
- 'longleftrightarrow' : 0x27f7,
- 'longmapsto' : 0x27fc,
- 'longrightarrow' : 0x27f6,
- 'looparrowleft' : 0x21ab,
- 'looparrowright' : 0x21ac,
- 'lq' : 0x2018,
- 'lrcorner' : 0x231f,
- 'ltimes' : 0x22c9,
- 'macron' : 0xaf,
- 'maltese' : 0x2720,
- 'mapsdown' : 0x21a7,
- 'mapsfrom' : 0x21a4,
- 'mapsto' : 0x21a6,
- 'mapsup' : 0x21a5,
- 'measeq' : 0x225e,
- 'measuredangle' : 0x2221,
- 'measuredrightangle' : 0x22be,
- 'merge' : 0x2a55,
- 'mho' : 0x2127,
- 'mid' : 0x2223,
- 'minus' : 0x2212,
- 'minuscolon' : 0x2239,
- 'models' : 0x22a7,
- 'mp' : 0x2213,
- 'mu' : 0x3bc,
- 'multimap' : 0x22b8,
- 'nLeftarrow' : 0x21cd,
- 'nLeftrightarrow' : 0x21ce,
- 'nRightarrow' : 0x21cf,
- 'nVDash' : 0x22af,
- 'nVdash' : 0x22ae,
- 'nabla' : 0x2207,
- 'napprox' : 0x2249,
- 'natural' : 0x266e,
- 'ncong' : 0x2247,
- 'ne' : 0x2260,
- 'nearrow' : 0x2197,
- 'neg' : 0xac,
- 'neq' : 0x2260,
- 'nequiv' : 0x2262,
- 'nexists' : 0x2204,
- 'ngeq' : 0x2271,
- 'ngtr' : 0x226f,
- 'ngtrless' : 0x2279,
- 'ngtrsim' : 0x2275,
- 'ni' : 0x220b,
- 'niobar' : 0x22fe,
- 'nis' : 0x22fc,
- 'nisd' : 0x22fa,
- 'nleftarrow' : 0x219a,
- 'nleftrightarrow' : 0x21ae,
- 'nleq' : 0x2270,
- 'nless' : 0x226e,
- 'nlessgtr' : 0x2278,
- 'nlesssim' : 0x2274,
- 'nmid' : 0x2224,
- 'not' : 0x338,
- 'notin' : 0x2209,
- 'notsmallowns' : 0x220c,
- 'nparallel' : 0x2226,
- 'nprec' : 0x2280,
- 'npreccurlyeq' : 0x22e0,
- 'nrightarrow' : 0x219b,
- 'nsim' : 0x2241,
- 'nsimeq' : 0x2244,
- 'nsqsubseteq' : 0x22e2,
- 'nsqsupseteq' : 0x22e3,
- 'nsubset' : 0x2284,
- 'nsubseteq' : 0x2288,
- 'nsucc' : 0x2281,
- 'nsucccurlyeq' : 0x22e1,
- 'nsupset' : 0x2285,
- 'nsupseteq' : 0x2289,
- 'ntriangleleft' : 0x22ea,
- 'ntrianglelefteq' : 0x22ec,
- 'ntriangleright' : 0x22eb,
- 'ntrianglerighteq' : 0x22ed,
- 'nu' : 0x3bd,
- 'nvDash' : 0x22ad,
- 'nvdash' : 0x22ac,
- 'nwarrow' : 0x2196,
- 'o' : 0xf8,
- 'obar' : 0x233d,
- 'ocirc' : 0x30a,
- 'odot' : 0x2299,
- 'oe' : 0x153,
- 'oequal' : 0x229c,
- 'oiiint' : 0x2230,
- 'oiint' : 0x222f,
- 'oint' : 0x222e,
- 'omega' : 0x3c9,
- 'ominus' : 0x2296,
- 'oplus' : 0x2295,
- 'origof' : 0x22b6,
- 'oslash' : 0x2298,
- 'otimes' : 0x2297,
- 'overarc' : 0x311,
- 'overleftarrow' : 0x20d6,
- 'overleftrightarrow' : 0x20e1,
- 'parallel' : 0x2225,
- 'partial' : 0x2202,
- 'perp' : 0x27c2,
- 'perthousand' : 0x2030,
- 'phi' : 0x3d5,
- 'pi' : 0x3c0,
- 'pitchfork' : 0x22d4,
- 'plus' : 0x2b,
- 'pm' : 0xb1,
- 'prec' : 0x227a,
- 'precapprox' : 0x2ab7,
- 'preccurlyeq' : 0x227c,
- 'preceq' : 0x227c,
- 'precnapprox' : 0x2ab9,
- 'precnsim' : 0x22e8,
- 'precsim' : 0x227e,
- 'prime' : 0x2032,
- 'prod' : 0x220f,
- 'propto' : 0x221d,
- 'prurel' : 0x22b0,
- 'psi' : 0x3c8,
- 'quad' : 0x2003,
- 'questeq' : 0x225f,
- 'rangle' : 0x27e9,
- 'rasp' : 0x2bc,
- 'ratio' : 0x2236,
- 'rbrace' : 0x7d,
- 'rbrack' : 0x5d,
- 'rceil' : 0x2309,
- 'rfloor' : 0x230b,
- 'rgroup' : 0x27ef,
- 'rhd' : 0x25b7,
- 'rho' : 0x3c1,
- 'rightModels' : 0x22ab,
- 'rightangle' : 0x221f,
- 'rightarrow' : 0x2192,
- 'rightarrowbar' : 0x21e5,
- 'rightarrowtail' : 0x21a3,
- 'rightassert' : 0x22a6,
- 'rightbrace' : 0x7d,
- 'rightharpoonaccent' : 0x20d1,
- 'rightharpoondown' : 0x21c1,
- 'rightharpoonup' : 0x21c0,
- 'rightleftarrows' : 0x21c4,
- 'rightleftharpoons' : 0x21cc,
- 'rightparen' : 0x29,
- 'rightrightarrows' : 0x21c9,
- 'rightsquigarrow' : 0x219d,
- 'rightthreetimes' : 0x22cc,
- 'rightzigzagarrow' : 0x21dd,
- 'ring' : 0x2da,
- 'risingdotseq' : 0x2253,
- 'rq' : 0x2019,
- 'rtimes' : 0x22ca,
- 'scrB' : 0x212c,
- 'scrE' : 0x2130,
- 'scrF' : 0x2131,
- 'scrH' : 0x210b,
- 'scrI' : 0x2110,
- 'scrL' : 0x2112,
- 'scrM' : 0x2133,
- 'scrR' : 0x211b,
- 'scre' : 0x212f,
- 'scrg' : 0x210a,
- 'scro' : 0x2134,
- 'scurel' : 0x22b1,
- 'searrow' : 0x2198,
- 'setminus' : 0x2216,
- 'sharp' : 0x266f,
- 'sigma' : 0x3c3,
- 'sim' : 0x223c,
- 'simeq' : 0x2243,
- 'simneqq' : 0x2246,
- 'sinewave' : 0x223f,
- 'slash' : 0x2215,
- 'smallin' : 0x220a,
- 'smallintclockwise' : 0x2231,
- 'smallointctrcclockwise' : 0x2233,
- 'smallowns' : 0x220d,
- 'smallsetminus' : 0x2216,
- 'smallvarointclockwise' : 0x2232,
- 'smile' : 0x2323,
- 'solbar' : 0x233f,
- 'spadesuit' : 0x2660,
- 'spadesuitopen' : 0x2664,
- 'sphericalangle' : 0x2222,
- 'sqcap' : 0x2293,
- 'sqcup' : 0x2294,
- 'sqsubset' : 0x228f,
- 'sqsubseteq' : 0x2291,
- 'sqsubsetneq' : 0x22e4,
- 'sqsupset' : 0x2290,
- 'sqsupseteq' : 0x2292,
- 'sqsupsetneq' : 0x22e5,
- 'ss' : 0xdf,
- 'star' : 0x22c6,
- 'stareq' : 0x225b,
- 'sterling' : 0xa3,
- 'subset' : 0x2282,
- 'subseteq' : 0x2286,
- 'subseteqq' : 0x2ac5,
- 'subsetneq' : 0x228a,
- 'subsetneqq' : 0x2acb,
- 'succ' : 0x227b,
- 'succapprox' : 0x2ab8,
- 'succcurlyeq' : 0x227d,
- 'succeq' : 0x227d,
- 'succnapprox' : 0x2aba,
- 'succnsim' : 0x22e9,
- 'succsim' : 0x227f,
- 'sum' : 0x2211,
- 'supset' : 0x2283,
- 'supseteq' : 0x2287,
- 'supseteqq' : 0x2ac6,
- 'supsetneq' : 0x228b,
- 'supsetneqq' : 0x2acc,
- 'swarrow' : 0x2199,
- 't' : 0x361,
- 'tau' : 0x3c4,
- 'textasciiacute' : 0xb4,
- 'textasciicircum' : 0x5e,
- 'textasciigrave' : 0x60,
- 'textasciitilde' : 0x7e,
- 'textexclamdown' : 0xa1,
- 'textquestiondown' : 0xbf,
- 'textquotedblleft' : 0x201c,
- 'textquotedblright' : 0x201d,
- 'therefore' : 0x2234,
- 'theta' : 0x3b8,
- 'thickspace' : 0x2005,
- 'thorn' : 0xfe,
- 'tilde' : 0x303,
- 'times' : 0xd7,
- 'to' : 0x2192,
- 'top' : 0x22a4,
- 'triangle' : 0x25b3,
- 'triangledown' : 0x25bf,
- 'triangleeq' : 0x225c,
- 'triangleleft' : 0x25c1,
- 'trianglelefteq' : 0x22b4,
- 'triangleq' : 0x225c,
- 'triangleright' : 0x25b7,
- 'trianglerighteq' : 0x22b5,
- 'turnednot' : 0x2319,
- 'twoheaddownarrow' : 0x21a1,
- 'twoheadleftarrow' : 0x219e,
- 'twoheadrightarrow' : 0x21a0,
- 'twoheaduparrow' : 0x219f,
- 'ulcorner' : 0x231c,
- 'underbar' : 0x331,
- 'unlhd' : 0x22b4,
- 'unrhd' : 0x22b5,
- 'uparrow' : 0x2191,
- 'updownarrow' : 0x2195,
- 'updownarrowbar' : 0x21a8,
- 'updownarrows' : 0x21c5,
- 'upharpoonleft' : 0x21bf,
- 'upharpoonright' : 0x21be,
- 'uplus' : 0x228e,
- 'upsilon' : 0x3c5,
- 'upuparrows' : 0x21c8,
- 'urcorner' : 0x231d,
- 'vDash' : 0x22a8,
- 'varepsilon' : 0x3b5,
- 'varisinobar' : 0x22f6,
- 'varisins' : 0x22f3,
- 'varkappa' : 0x3f0,
- 'varlrtriangle' : 0x22bf,
- 'varniobar' : 0x22fd,
- 'varnis' : 0x22fb,
- 'varnothing' : 0x2205,
- 'varphi' : 0x3c6,
- 'varpi' : 0x3d6,
- 'varpropto' : 0x221d,
- 'varrho' : 0x3f1,
- 'varsigma' : 0x3c2,
- 'vartheta' : 0x3d1,
- 'vartriangle' : 0x25b5,
- 'vartriangleleft' : 0x22b2,
- 'vartriangleright' : 0x22b3,
- 'vdash' : 0x22a2,
- 'vdots' : 0x22ee,
- 'vec' : 0x20d7,
- 'vee' : 0x2228,
- 'veebar' : 0x22bb,
- 'veeeq' : 0x225a,
- 'vert' : 0x7c,
- 'wedge' : 0x2227,
- 'wedgeq' : 0x2259,
- 'widebar' : 0x305,
- 'widehat' : 0x302,
- 'widetilde' : 0x303,
- 'wp' : 0x2118,
- 'wr' : 0x2240,
- 'xi' : 0x3be,
- 'yen' : 0xa5,
- 'zeta' : 0x3b6,
- '{' : 0x7b,
- '|' : 0x2016,
- '}' : 0x7d,
-}
-
-# Each element is a 4-tuple of the form:
-# src_start, src_end, dst_font, dst_start
-#
-stix_virtual_fonts: dict[str, dict[str, list[tuple[int, int, str, int]]] |
- list[tuple[int, int, str, int]]] = {
- 'bb':
- {
- 'rm':
- [
- (0x0030, 0x0039, 'rm', 0x1d7d8), # 0-9
- (0x0041, 0x0042, 'rm', 0x1d538), # A-B
- (0x0043, 0x0043, 'rm', 0x2102), # C
- (0x0044, 0x0047, 'rm', 0x1d53b), # D-G
- (0x0048, 0x0048, 'rm', 0x210d), # H
- (0x0049, 0x004d, 'rm', 0x1d540), # I-M
- (0x004e, 0x004e, 'rm', 0x2115), # N
- (0x004f, 0x004f, 'rm', 0x1d546), # O
- (0x0050, 0x0051, 'rm', 0x2119), # P-Q
- (0x0052, 0x0052, 'rm', 0x211d), # R
- (0x0053, 0x0059, 'rm', 0x1d54a), # S-Y
- (0x005a, 0x005a, 'rm', 0x2124), # Z
- (0x0061, 0x007a, 'rm', 0x1d552), # a-z
- (0x0393, 0x0393, 'rm', 0x213e), # \Gamma
- (0x03a0, 0x03a0, 'rm', 0x213f), # \Pi
- (0x03a3, 0x03a3, 'rm', 0x2140), # \Sigma
- (0x03b3, 0x03b3, 'rm', 0x213d), # \gamma
- (0x03c0, 0x03c0, 'rm', 0x213c), # \pi
- ],
- 'it':
- [
- (0x0030, 0x0039, 'rm', 0x1d7d8), # 0-9
- (0x0041, 0x0042, 'it', 0xe154), # A-B
- (0x0043, 0x0043, 'it', 0x2102), # C
- (0x0044, 0x0044, 'it', 0x2145), # D
- (0x0045, 0x0047, 'it', 0xe156), # E-G
- (0x0048, 0x0048, 'it', 0x210d), # H
- (0x0049, 0x004d, 'it', 0xe159), # I-M
- (0x004e, 0x004e, 'it', 0x2115), # N
- (0x004f, 0x004f, 'it', 0xe15e), # O
- (0x0050, 0x0051, 'it', 0x2119), # P-Q
- (0x0052, 0x0052, 'it', 0x211d), # R
- (0x0053, 0x0059, 'it', 0xe15f), # S-Y
- (0x005a, 0x005a, 'it', 0x2124), # Z
- (0x0061, 0x0063, 'it', 0xe166), # a-c
- (0x0064, 0x0065, 'it', 0x2146), # d-e
- (0x0066, 0x0068, 'it', 0xe169), # f-h
- (0x0069, 0x006a, 'it', 0x2148), # i-j
- (0x006b, 0x007a, 'it', 0xe16c), # k-z
- (0x0393, 0x0393, 'it', 0x213e), # \Gamma (not in beta STIX fonts)
- (0x03a0, 0x03a0, 'it', 0x213f), # \Pi
- (0x03a3, 0x03a3, 'it', 0x2140), # \Sigma (not in beta STIX fonts)
- (0x03b3, 0x03b3, 'it', 0x213d), # \gamma (not in beta STIX fonts)
- (0x03c0, 0x03c0, 'it', 0x213c), # \pi
- ],
- 'bf':
- [
- (0x0030, 0x0039, 'rm', 0x1d7d8), # 0-9
- (0x0041, 0x0042, 'bf', 0xe38a), # A-B
- (0x0043, 0x0043, 'bf', 0x2102), # C
- (0x0044, 0x0044, 'bf', 0x2145), # D
- (0x0045, 0x0047, 'bf', 0xe38d), # E-G
- (0x0048, 0x0048, 'bf', 0x210d), # H
- (0x0049, 0x004d, 'bf', 0xe390), # I-M
- (0x004e, 0x004e, 'bf', 0x2115), # N
- (0x004f, 0x004f, 'bf', 0xe395), # O
- (0x0050, 0x0051, 'bf', 0x2119), # P-Q
- (0x0052, 0x0052, 'bf', 0x211d), # R
- (0x0053, 0x0059, 'bf', 0xe396), # S-Y
- (0x005a, 0x005a, 'bf', 0x2124), # Z
- (0x0061, 0x0063, 'bf', 0xe39d), # a-c
- (0x0064, 0x0065, 'bf', 0x2146), # d-e
- (0x0066, 0x0068, 'bf', 0xe3a2), # f-h
- (0x0069, 0x006a, 'bf', 0x2148), # i-j
- (0x006b, 0x007a, 'bf', 0xe3a7), # k-z
- (0x0393, 0x0393, 'bf', 0x213e), # \Gamma
- (0x03a0, 0x03a0, 'bf', 0x213f), # \Pi
- (0x03a3, 0x03a3, 'bf', 0x2140), # \Sigma
- (0x03b3, 0x03b3, 'bf', 0x213d), # \gamma
- (0x03c0, 0x03c0, 'bf', 0x213c), # \pi
- ],
- },
- 'cal':
- [
- (0x0041, 0x005a, 'it', 0xe22d), # A-Z
- ],
- 'frak':
- {
- 'rm':
- [
- (0x0041, 0x0042, 'rm', 0x1d504), # A-B
- (0x0043, 0x0043, 'rm', 0x212d), # C
- (0x0044, 0x0047, 'rm', 0x1d507), # D-G
- (0x0048, 0x0048, 'rm', 0x210c), # H
- (0x0049, 0x0049, 'rm', 0x2111), # I
- (0x004a, 0x0051, 'rm', 0x1d50d), # J-Q
- (0x0052, 0x0052, 'rm', 0x211c), # R
- (0x0053, 0x0059, 'rm', 0x1d516), # S-Y
- (0x005a, 0x005a, 'rm', 0x2128), # Z
- (0x0061, 0x007a, 'rm', 0x1d51e), # a-z
- ],
- 'bf':
- [
- (0x0041, 0x005a, 'bf', 0x1d56c), # A-Z
- (0x0061, 0x007a, 'bf', 0x1d586), # a-z
- ],
- },
- 'scr':
- [
- (0x0041, 0x0041, 'it', 0x1d49c), # A
- (0x0042, 0x0042, 'it', 0x212c), # B
- (0x0043, 0x0044, 'it', 0x1d49e), # C-D
- (0x0045, 0x0046, 'it', 0x2130), # E-F
- (0x0047, 0x0047, 'it', 0x1d4a2), # G
- (0x0048, 0x0048, 'it', 0x210b), # H
- (0x0049, 0x0049, 'it', 0x2110), # I
- (0x004a, 0x004b, 'it', 0x1d4a5), # J-K
- (0x004c, 0x004c, 'it', 0x2112), # L
- (0x004d, 0x004d, 'it', 0x2133), # M
- (0x004e, 0x0051, 'it', 0x1d4a9), # N-Q
- (0x0052, 0x0052, 'it', 0x211b), # R
- (0x0053, 0x005a, 'it', 0x1d4ae), # S-Z
- (0x0061, 0x0064, 'it', 0x1d4b6), # a-d
- (0x0065, 0x0065, 'it', 0x212f), # e
- (0x0066, 0x0066, 'it', 0x1d4bb), # f
- (0x0067, 0x0067, 'it', 0x210a), # g
- (0x0068, 0x006e, 'it', 0x1d4bd), # h-n
- (0x006f, 0x006f, 'it', 0x2134), # o
- (0x0070, 0x007a, 'it', 0x1d4c5), # p-z
- ],
- 'sf':
- {
- 'rm':
- [
- (0x0030, 0x0039, 'rm', 0x1d7e2), # 0-9
- (0x0041, 0x005a, 'rm', 0x1d5a0), # A-Z
- (0x0061, 0x007a, 'rm', 0x1d5ba), # a-z
- (0x0391, 0x03a9, 'rm', 0xe17d), # \Alpha-\Omega
- (0x03b1, 0x03c9, 'rm', 0xe196), # \alpha-\omega
- (0x03d1, 0x03d1, 'rm', 0xe1b0), # theta variant
- (0x03d5, 0x03d5, 'rm', 0xe1b1), # phi variant
- (0x03d6, 0x03d6, 'rm', 0xe1b3), # pi variant
- (0x03f1, 0x03f1, 'rm', 0xe1b2), # rho variant
- (0x03f5, 0x03f5, 'rm', 0xe1af), # lunate epsilon
- (0x2202, 0x2202, 'rm', 0xe17c), # partial differential
- ],
- 'it':
- [
- # These numerals are actually upright. We don't actually
- # want italic numerals ever.
- (0x0030, 0x0039, 'rm', 0x1d7e2), # 0-9
- (0x0041, 0x005a, 'it', 0x1d608), # A-Z
- (0x0061, 0x007a, 'it', 0x1d622), # a-z
- (0x0391, 0x03a9, 'rm', 0xe17d), # \Alpha-\Omega
- (0x03b1, 0x03c9, 'it', 0xe1d8), # \alpha-\omega
- (0x03d1, 0x03d1, 'it', 0xe1f2), # theta variant
- (0x03d5, 0x03d5, 'it', 0xe1f3), # phi variant
- (0x03d6, 0x03d6, 'it', 0xe1f5), # pi variant
- (0x03f1, 0x03f1, 'it', 0xe1f4), # rho variant
- (0x03f5, 0x03f5, 'it', 0xe1f1), # lunate epsilon
- ],
- 'bf':
- [
- (0x0030, 0x0039, 'bf', 0x1d7ec), # 0-9
- (0x0041, 0x005a, 'bf', 0x1d5d4), # A-Z
- (0x0061, 0x007a, 'bf', 0x1d5ee), # a-z
- (0x0391, 0x03a9, 'bf', 0x1d756), # \Alpha-\Omega
- (0x03b1, 0x03c9, 'bf', 0x1d770), # \alpha-\omega
- (0x03d1, 0x03d1, 'bf', 0x1d78b), # theta variant
- (0x03d5, 0x03d5, 'bf', 0x1d78d), # phi variant
- (0x03d6, 0x03d6, 'bf', 0x1d78f), # pi variant
- (0x03f0, 0x03f0, 'bf', 0x1d78c), # kappa variant
- (0x03f1, 0x03f1, 'bf', 0x1d78e), # rho variant
- (0x03f5, 0x03f5, 'bf', 0x1d78a), # lunate epsilon
- (0x2202, 0x2202, 'bf', 0x1d789), # partial differential
- (0x2207, 0x2207, 'bf', 0x1d76f), # \Nabla
- ],
- 'bfit':
- [
- (0x0041, 0x005a, 'bfit', 0x1d468), # A-Z
- (0x0061, 0x007a, 'bfit', 0x1d482), # a-z
- (0x0393, 0x03a9, 'bfit', 0x1d71e), # \Gamma-\Omega
- (0x03b1, 0x03c9, 'bfit', 0x1d736), # \alpha-\omega
- ],
- },
- 'tt':
- [
- (0x0030, 0x0039, 'rm', 0x1d7f6), # 0-9
- (0x0041, 0x005a, 'rm', 0x1d670), # A-Z
- (0x0061, 0x007a, 'rm', 0x1d68a) # a-z
- ],
- }
-
-
-# Fix some incorrect glyphs.
-stix_glyph_fixes = {
- # Cap and Cup glyphs are swapped.
- 0x22d2: 0x22d3,
- 0x22d3: 0x22d2,
-}
diff --git a/contrib/python/matplotlib/py3/matplotlib/_path.pyi b/contrib/python/matplotlib/py3/matplotlib/_path.pyi
deleted file mode 100644
index 456905528b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_path.pyi
+++ /dev/null
@@ -1,9 +0,0 @@
-from collections.abc import Sequence
-
-import numpy as np
-
-from .transforms import BboxBase
-
-def affine_transform(points: np.ndarray, trans: np.ndarray) -> np.ndarray: ...
-def count_bboxes_overlapping_bbox(bbox: BboxBase, bboxes: Sequence[BboxBase]) -> int: ...
-def update_path_extents(path, trans, rect, minpos, ignore): ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/_pylab_helpers.py b/contrib/python/matplotlib/py3/matplotlib/_pylab_helpers.py
deleted file mode 100644
index d32a69d4ff..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_pylab_helpers.py
+++ /dev/null
@@ -1,135 +0,0 @@
-"""
-Manage figures for the pyplot interface.
-"""
-
-import atexit
-from collections import OrderedDict
-
-
-class Gcf:
- """
- Singleton to maintain the relation between figures and their managers, and
- keep track of and "active" figure and manager.
-
- The canvas of a figure created through pyplot is associated with a figure
- manager, which handles the interaction between the figure and the backend.
- pyplot keeps track of figure managers using an identifier, the "figure
- number" or "manager number" (which can actually be any hashable value);
- this number is available as the :attr:`number` attribute of the manager.
-
- This class is never instantiated; it consists of an `OrderedDict` mapping
- figure/manager numbers to managers, and a set of class methods that
- manipulate this `OrderedDict`.
-
- Attributes
- ----------
- figs : OrderedDict
- `OrderedDict` mapping numbers to managers; the active manager is at the
- end.
- """
-
- figs = OrderedDict()
-
- @classmethod
- def get_fig_manager(cls, num):
- """
- If manager number *num* exists, make it the active one and return it;
- otherwise return *None*.
- """
- manager = cls.figs.get(num, None)
- if manager is not None:
- cls.set_active(manager)
- return manager
-
- @classmethod
- def destroy(cls, num):
- """
- Destroy manager *num* -- either a manager instance or a manager number.
-
- In the interactive backends, this is bound to the window "destroy" and
- "delete" events.
-
- It is recommended to pass a manager instance, to avoid confusion when
- two managers share the same number.
- """
- if all(hasattr(num, attr) for attr in ["num", "destroy"]):
- manager = num
- if cls.figs.get(manager.num) is manager:
- cls.figs.pop(manager.num)
- else:
- try:
- manager = cls.figs.pop(num)
- except KeyError:
- return
- if hasattr(manager, "_cidgcf"):
- manager.canvas.mpl_disconnect(manager._cidgcf)
- manager.destroy()
- del manager, num
-
- @classmethod
- def destroy_fig(cls, fig):
- """Destroy figure *fig*."""
- num = next((manager.num for manager in cls.figs.values()
- if manager.canvas.figure == fig), None)
- if num is not None:
- cls.destroy(num)
-
- @classmethod
- def destroy_all(cls):
- """Destroy all figures."""
- for manager in list(cls.figs.values()):
- manager.canvas.mpl_disconnect(manager._cidgcf)
- manager.destroy()
- cls.figs.clear()
-
- @classmethod
- def has_fignum(cls, num):
- """Return whether figure number *num* exists."""
- return num in cls.figs
-
- @classmethod
- def get_all_fig_managers(cls):
- """Return a list of figure managers."""
- return list(cls.figs.values())
-
- @classmethod
- def get_num_fig_managers(cls):
- """Return the number of figures being managed."""
- return len(cls.figs)
-
- @classmethod
- def get_active(cls):
- """Return the active manager, or *None* if there is no manager."""
- return next(reversed(cls.figs.values())) if cls.figs else None
-
- @classmethod
- def _set_new_active_manager(cls, manager):
- """Adopt *manager* into pyplot and make it the active manager."""
- if not hasattr(manager, "_cidgcf"):
- manager._cidgcf = manager.canvas.mpl_connect(
- "button_press_event", lambda event: cls.set_active(manager))
- fig = manager.canvas.figure
- fig.number = manager.num
- label = fig.get_label()
- if label:
- manager.set_window_title(label)
- cls.set_active(manager)
-
- @classmethod
- def set_active(cls, manager):
- """Make *manager* the active manager."""
- cls.figs[manager.num] = manager
- cls.figs.move_to_end(manager.num)
-
- @classmethod
- def draw_all(cls, force=False):
- """
- Redraw all stale managed figures, or, if *force* is True, all managed
- figures.
- """
- for manager in cls.get_all_fig_managers():
- if force or manager.canvas.figure.stale:
- manager.canvas.draw_idle()
-
-
-atexit.register(Gcf.destroy_all)
diff --git a/contrib/python/matplotlib/py3/matplotlib/_pylab_helpers.pyi b/contrib/python/matplotlib/py3/matplotlib/_pylab_helpers.pyi
deleted file mode 100644
index bdd8cfba31..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_pylab_helpers.pyi
+++ /dev/null
@@ -1,29 +0,0 @@
-from collections import OrderedDict
-
-from matplotlib.backend_bases import FigureManagerBase
-from matplotlib.figure import Figure
-
-class Gcf:
- figs: OrderedDict[int, FigureManagerBase]
- @classmethod
- def get_fig_manager(cls, num: int) -> FigureManagerBase | None: ...
- @classmethod
- def destroy(cls, num: int | FigureManagerBase) -> None: ...
- @classmethod
- def destroy_fig(cls, fig: Figure) -> None: ...
- @classmethod
- def destroy_all(cls) -> None: ...
- @classmethod
- def has_fignum(cls, num: int) -> bool: ...
- @classmethod
- def get_all_fig_managers(cls) -> list[FigureManagerBase]: ...
- @classmethod
- def get_num_fig_managers(cls) -> int: ...
- @classmethod
- def get_active(cls) -> FigureManagerBase | None: ...
- @classmethod
- def _set_new_active_manager(cls, manager: FigureManagerBase) -> None: ...
- @classmethod
- def set_active(cls, manager: FigureManagerBase) -> None: ...
- @classmethod
- def draw_all(cls, force: bool = ...) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/_qhull.pyi b/contrib/python/matplotlib/py3/matplotlib/_qhull.pyi
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_qhull.pyi
+++ /dev/null
diff --git a/contrib/python/matplotlib/py3/matplotlib/_text_helpers.py b/contrib/python/matplotlib/py3/matplotlib/_text_helpers.py
deleted file mode 100644
index 18bfb550c9..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_text_helpers.py
+++ /dev/null
@@ -1,74 +0,0 @@
-"""
-Low-level text helper utilities.
-"""
-
-import dataclasses
-
-from . import _api
-from .ft2font import KERNING_DEFAULT, LOAD_NO_HINTING
-
-
-LayoutItem = dataclasses.make_dataclass(
- "LayoutItem", ["ft_object", "char", "glyph_idx", "x", "prev_kern"])
-
-
-def warn_on_missing_glyph(codepoint):
- _api.warn_external(
- "Glyph {} ({}) missing from current font.".format(
- codepoint,
- chr(codepoint).encode("ascii", "namereplace").decode("ascii")))
- block = ("Hebrew" if 0x0590 <= codepoint <= 0x05ff else
- "Arabic" if 0x0600 <= codepoint <= 0x06ff else
- "Devanagari" if 0x0900 <= codepoint <= 0x097f else
- "Bengali" if 0x0980 <= codepoint <= 0x09ff else
- "Gurmukhi" if 0x0a00 <= codepoint <= 0x0a7f else
- "Gujarati" if 0x0a80 <= codepoint <= 0x0aff else
- "Oriya" if 0x0b00 <= codepoint <= 0x0b7f else
- "Tamil" if 0x0b80 <= codepoint <= 0x0bff else
- "Telugu" if 0x0c00 <= codepoint <= 0x0c7f else
- "Kannada" if 0x0c80 <= codepoint <= 0x0cff else
- "Malayalam" if 0x0d00 <= codepoint <= 0x0d7f else
- "Sinhala" if 0x0d80 <= codepoint <= 0x0dff else
- None)
- if block:
- _api.warn_external(
- f"Matplotlib currently does not support {block} natively.")
-
-
-def layout(string, font, *, kern_mode=KERNING_DEFAULT):
- """
- Render *string* with *font*. For each character in *string*, yield a
- (glyph-index, x-position) pair. When such a pair is yielded, the font's
- glyph is set to the corresponding character.
-
- Parameters
- ----------
- string : str
- The string to be rendered.
- font : FT2Font
- The font.
- kern_mode : int
- A FreeType kerning mode.
-
- Yields
- ------
- glyph_index : int
- x_position : float
- """
- x = 0
- prev_glyph_idx = None
- char_to_font = font._get_fontmap(string)
- base_font = font
- for char in string:
- # This has done the fallback logic
- font = char_to_font.get(char, base_font)
- glyph_idx = font.get_char_index(ord(char))
- kern = (
- base_font.get_kerning(prev_glyph_idx, glyph_idx, kern_mode) / 64
- if prev_glyph_idx is not None else 0.
- )
- x += kern
- glyph = font.load_glyph(glyph_idx, flags=LOAD_NO_HINTING)
- yield LayoutItem(font, char, glyph_idx, x, kern)
- x += glyph.linearHoriAdvance / 65536
- prev_glyph_idx = glyph_idx
diff --git a/contrib/python/matplotlib/py3/matplotlib/_tight_bbox.py b/contrib/python/matplotlib/py3/matplotlib/_tight_bbox.py
deleted file mode 100644
index db72bbdff0..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_tight_bbox.py
+++ /dev/null
@@ -1,84 +0,0 @@
-"""
-Helper module for the *bbox_inches* parameter in `.Figure.savefig`.
-"""
-
-from matplotlib.transforms import Bbox, TransformedBbox, Affine2D
-
-
-def adjust_bbox(fig, bbox_inches, fixed_dpi=None):
- """
- Temporarily adjust the figure so that only the specified area
- (bbox_inches) is saved.
-
- It modifies fig.bbox, fig.bbox_inches,
- fig.transFigure._boxout, and fig.patch. While the figure size
- changes, the scale of the original figure is conserved. A
- function which restores the original values are returned.
- """
- origBbox = fig.bbox
- origBboxInches = fig.bbox_inches
- _boxout = fig.transFigure._boxout
-
- old_aspect = []
- locator_list = []
- sentinel = object()
- for ax in fig.axes:
- locator = ax.get_axes_locator()
- if locator is not None:
- ax.apply_aspect(locator(ax, None))
- locator_list.append(locator)
- current_pos = ax.get_position(original=False).frozen()
- ax.set_axes_locator(lambda a, r, _pos=current_pos: _pos)
- # override the method that enforces the aspect ratio on the Axes
- if 'apply_aspect' in ax.__dict__:
- old_aspect.append(ax.apply_aspect)
- else:
- old_aspect.append(sentinel)
- ax.apply_aspect = lambda pos=None: None
-
- def restore_bbox():
- for ax, loc, aspect in zip(fig.axes, locator_list, old_aspect):
- ax.set_axes_locator(loc)
- if aspect is sentinel:
- # delete our no-op function which un-hides the original method
- del ax.apply_aspect
- else:
- ax.apply_aspect = aspect
-
- fig.bbox = origBbox
- fig.bbox_inches = origBboxInches
- fig.transFigure._boxout = _boxout
- fig.transFigure.invalidate()
- fig.patch.set_bounds(0, 0, 1, 1)
-
- if fixed_dpi is None:
- fixed_dpi = fig.dpi
- tr = Affine2D().scale(fixed_dpi)
- dpi_scale = fixed_dpi / fig.dpi
-
- fig.bbox_inches = Bbox.from_bounds(0, 0, *bbox_inches.size)
- x0, y0 = tr.transform(bbox_inches.p0)
- w1, h1 = fig.bbox.size * dpi_scale
- fig.transFigure._boxout = Bbox.from_bounds(-x0, -y0, w1, h1)
- fig.transFigure.invalidate()
-
- fig.bbox = TransformedBbox(fig.bbox_inches, tr)
-
- fig.patch.set_bounds(x0 / w1, y0 / h1,
- fig.bbox.width / w1, fig.bbox.height / h1)
-
- return restore_bbox
-
-
-def process_figure_for_rasterizing(fig, bbox_inches_restore, fixed_dpi=None):
- """
- A function that needs to be called when figure dpi changes during the
- drawing (e.g., rasterizing). It recovers the bbox and re-adjust it with
- the new dpi.
- """
-
- bbox_inches, restore_bbox = bbox_inches_restore
- restore_bbox()
- r = adjust_bbox(fig, bbox_inches, fixed_dpi)
-
- return bbox_inches, r
diff --git a/contrib/python/matplotlib/py3/matplotlib/_tight_layout.py b/contrib/python/matplotlib/py3/matplotlib/_tight_layout.py
deleted file mode 100644
index e99ba49bd2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_tight_layout.py
+++ /dev/null
@@ -1,301 +0,0 @@
-"""
-Routines to adjust subplot params so that subplots are
-nicely fit in the figure. In doing so, only axis labels, tick labels, axes
-titles and offsetboxes that are anchored to axes are currently considered.
-
-Internally, this module assumes that the margins (left margin, etc.) which are
-differences between ``Axes.get_tightbbox`` and ``Axes.bbox`` are independent of
-Axes position. This may fail if ``Axes.adjustable`` is ``datalim`` as well as
-such cases as when left or right margin are affected by xlabel.
-"""
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, artist as martist
-from matplotlib.font_manager import FontProperties
-from matplotlib.transforms import Bbox
-
-
-def _auto_adjust_subplotpars(
- fig, renderer, shape, span_pairs, subplot_list,
- ax_bbox_list=None, pad=1.08, h_pad=None, w_pad=None, rect=None):
- """
- Return a dict of subplot parameters to adjust spacing between subplots
- or ``None`` if resulting axes would have zero height or width.
-
- Note that this function ignores geometry information of subplot itself, but
- uses what is given by the *shape* and *subplot_list* parameters. Also, the
- results could be incorrect if some subplots have ``adjustable=datalim``.
-
- Parameters
- ----------
- shape : tuple[int, int]
- Number of rows and columns of the grid.
- span_pairs : list[tuple[slice, slice]]
- List of rowspans and colspans occupied by each subplot.
- subplot_list : list of subplots
- List of subplots that will be used to calculate optimal subplot_params.
- pad : float
- Padding between the figure edge and the edges of subplots, as a
- fraction of the font size.
- h_pad, w_pad : float
- Padding (height/width) between edges of adjacent subplots, as a
- fraction of the font size. Defaults to *pad*.
- rect : tuple
- (left, bottom, right, top), default: None.
- """
- rows, cols = shape
-
- font_size_inch = (FontProperties(
- size=mpl.rcParams["font.size"]).get_size_in_points() / 72)
- pad_inch = pad * font_size_inch
- vpad_inch = h_pad * font_size_inch if h_pad is not None else pad_inch
- hpad_inch = w_pad * font_size_inch if w_pad is not None else pad_inch
-
- if len(span_pairs) != len(subplot_list) or len(subplot_list) == 0:
- raise ValueError
-
- if rect is None:
- margin_left = margin_bottom = margin_right = margin_top = None
- else:
- margin_left, margin_bottom, _right, _top = rect
- margin_right = 1 - _right if _right else None
- margin_top = 1 - _top if _top else None
-
- vspaces = np.zeros((rows + 1, cols))
- hspaces = np.zeros((rows, cols + 1))
-
- if ax_bbox_list is None:
- ax_bbox_list = [
- Bbox.union([ax.get_position(original=True) for ax in subplots])
- for subplots in subplot_list]
-
- for subplots, ax_bbox, (rowspan, colspan) in zip(
- subplot_list, ax_bbox_list, span_pairs):
- if all(not ax.get_visible() for ax in subplots):
- continue
-
- bb = []
- for ax in subplots:
- if ax.get_visible():
- bb += [martist._get_tightbbox_for_layout_only(ax, renderer)]
-
- tight_bbox_raw = Bbox.union(bb)
- tight_bbox = fig.transFigure.inverted().transform_bbox(tight_bbox_raw)
-
- hspaces[rowspan, colspan.start] += ax_bbox.xmin - tight_bbox.xmin # l
- hspaces[rowspan, colspan.stop] += tight_bbox.xmax - ax_bbox.xmax # r
- vspaces[rowspan.start, colspan] += tight_bbox.ymax - ax_bbox.ymax # t
- vspaces[rowspan.stop, colspan] += ax_bbox.ymin - tight_bbox.ymin # b
-
- fig_width_inch, fig_height_inch = fig.get_size_inches()
-
- # margins can be negative for axes with aspect applied, so use max(, 0) to
- # make them nonnegative.
- if not margin_left:
- margin_left = max(hspaces[:, 0].max(), 0) + pad_inch/fig_width_inch
- suplabel = fig._supylabel
- if suplabel and suplabel.get_in_layout():
- rel_width = fig.transFigure.inverted().transform_bbox(
- suplabel.get_window_extent(renderer)).width
- margin_left += rel_width + pad_inch/fig_width_inch
- if not margin_right:
- margin_right = max(hspaces[:, -1].max(), 0) + pad_inch/fig_width_inch
- if not margin_top:
- margin_top = max(vspaces[0, :].max(), 0) + pad_inch/fig_height_inch
- if fig._suptitle and fig._suptitle.get_in_layout():
- rel_height = fig.transFigure.inverted().transform_bbox(
- fig._suptitle.get_window_extent(renderer)).height
- margin_top += rel_height + pad_inch/fig_height_inch
- if not margin_bottom:
- margin_bottom = max(vspaces[-1, :].max(), 0) + pad_inch/fig_height_inch
- suplabel = fig._supxlabel
- if suplabel and suplabel.get_in_layout():
- rel_height = fig.transFigure.inverted().transform_bbox(
- suplabel.get_window_extent(renderer)).height
- margin_bottom += rel_height + pad_inch/fig_height_inch
-
- if margin_left + margin_right >= 1:
- _api.warn_external('Tight layout not applied. The left and right '
- 'margins cannot be made large enough to '
- 'accommodate all axes decorations.')
- return None
- if margin_bottom + margin_top >= 1:
- _api.warn_external('Tight layout not applied. The bottom and top '
- 'margins cannot be made large enough to '
- 'accommodate all axes decorations.')
- return None
-
- kwargs = dict(left=margin_left,
- right=1 - margin_right,
- bottom=margin_bottom,
- top=1 - margin_top)
-
- if cols > 1:
- hspace = hspaces[:, 1:-1].max() + hpad_inch / fig_width_inch
- # axes widths:
- h_axes = (1 - margin_right - margin_left - hspace * (cols - 1)) / cols
- if h_axes < 0:
- _api.warn_external('Tight layout not applied. tight_layout '
- 'cannot make axes width small enough to '
- 'accommodate all axes decorations')
- return None
- else:
- kwargs["wspace"] = hspace / h_axes
- if rows > 1:
- vspace = vspaces[1:-1, :].max() + vpad_inch / fig_height_inch
- v_axes = (1 - margin_top - margin_bottom - vspace * (rows - 1)) / rows
- if v_axes < 0:
- _api.warn_external('Tight layout not applied. tight_layout '
- 'cannot make axes height small enough to '
- 'accommodate all axes decorations.')
- return None
- else:
- kwargs["hspace"] = vspace / v_axes
-
- return kwargs
-
-
-def get_subplotspec_list(axes_list, grid_spec=None):
- """
- Return a list of subplotspec from the given list of axes.
-
- For an instance of axes that does not support subplotspec, None is inserted
- in the list.
-
- If grid_spec is given, None is inserted for those not from the given
- grid_spec.
- """
- subplotspec_list = []
- for ax in axes_list:
- axes_or_locator = ax.get_axes_locator()
- if axes_or_locator is None:
- axes_or_locator = ax
-
- if hasattr(axes_or_locator, "get_subplotspec"):
- subplotspec = axes_or_locator.get_subplotspec()
- if subplotspec is not None:
- subplotspec = subplotspec.get_topmost_subplotspec()
- gs = subplotspec.get_gridspec()
- if grid_spec is not None:
- if gs != grid_spec:
- subplotspec = None
- elif gs.locally_modified_subplot_params():
- subplotspec = None
- else:
- subplotspec = None
-
- subplotspec_list.append(subplotspec)
-
- return subplotspec_list
-
-
-def get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer,
- pad=1.08, h_pad=None, w_pad=None, rect=None):
- """
- Return subplot parameters for tight-layouted-figure with specified padding.
-
- Parameters
- ----------
- fig : Figure
- axes_list : list of Axes
- subplotspec_list : list of `.SubplotSpec`
- The subplotspecs of each axes.
- renderer : renderer
- pad : float
- Padding between the figure edge and the edges of subplots, as a
- fraction of the font size.
- h_pad, w_pad : float
- Padding (height/width) between edges of adjacent subplots. Defaults to
- *pad*.
- rect : tuple (left, bottom, right, top), default: None.
- rectangle in normalized figure coordinates
- that the whole subplots area (including labels) will fit into.
- Defaults to using the entire figure.
-
- Returns
- -------
- subplotspec or None
- subplotspec kwargs to be passed to `.Figure.subplots_adjust` or
- None if tight_layout could not be accomplished.
- """
-
- # Multiple axes can share same subplotspec (e.g., if using axes_grid1);
- # we need to group them together.
- ss_to_subplots = {ss: [] for ss in subplotspec_list}
- for ax, ss in zip(axes_list, subplotspec_list):
- ss_to_subplots[ss].append(ax)
- if ss_to_subplots.pop(None, None):
- _api.warn_external(
- "This figure includes Axes that are not compatible with "
- "tight_layout, so results might be incorrect.")
- if not ss_to_subplots:
- return {}
- subplot_list = list(ss_to_subplots.values())
- ax_bbox_list = [ss.get_position(fig) for ss in ss_to_subplots]
-
- max_nrows = max(ss.get_gridspec().nrows for ss in ss_to_subplots)
- max_ncols = max(ss.get_gridspec().ncols for ss in ss_to_subplots)
-
- span_pairs = []
- for ss in ss_to_subplots:
- # The intent here is to support axes from different gridspecs where
- # one's nrows (or ncols) is a multiple of the other (e.g. 2 and 4),
- # but this doesn't actually work because the computed wspace, in
- # relative-axes-height, corresponds to different physical spacings for
- # the 2-row grid and the 4-row grid. Still, this code is left, mostly
- # for backcompat.
- rows, cols = ss.get_gridspec().get_geometry()
- div_row, mod_row = divmod(max_nrows, rows)
- div_col, mod_col = divmod(max_ncols, cols)
- if mod_row != 0:
- _api.warn_external('tight_layout not applied: number of rows '
- 'in subplot specifications must be '
- 'multiples of one another.')
- return {}
- if mod_col != 0:
- _api.warn_external('tight_layout not applied: number of '
- 'columns in subplot specifications must be '
- 'multiples of one another.')
- return {}
- span_pairs.append((
- slice(ss.rowspan.start * div_row, ss.rowspan.stop * div_row),
- slice(ss.colspan.start * div_col, ss.colspan.stop * div_col)))
-
- kwargs = _auto_adjust_subplotpars(fig, renderer,
- shape=(max_nrows, max_ncols),
- span_pairs=span_pairs,
- subplot_list=subplot_list,
- ax_bbox_list=ax_bbox_list,
- pad=pad, h_pad=h_pad, w_pad=w_pad)
-
- # kwargs can be none if tight_layout fails...
- if rect is not None and kwargs is not None:
- # if rect is given, the whole subplots area (including
- # labels) will fit into the rect instead of the
- # figure. Note that the rect argument of
- # *auto_adjust_subplotpars* specify the area that will be
- # covered by the total area of axes.bbox. Thus we call
- # auto_adjust_subplotpars twice, where the second run
- # with adjusted rect parameters.
-
- left, bottom, right, top = rect
- if left is not None:
- left += kwargs["left"]
- if bottom is not None:
- bottom += kwargs["bottom"]
- if right is not None:
- right -= (1 - kwargs["right"])
- if top is not None:
- top -= (1 - kwargs["top"])
-
- kwargs = _auto_adjust_subplotpars(fig, renderer,
- shape=(max_nrows, max_ncols),
- span_pairs=span_pairs,
- subplot_list=subplot_list,
- ax_bbox_list=ax_bbox_list,
- pad=pad, h_pad=h_pad, w_pad=w_pad,
- rect=(left, bottom, right, top))
-
- return kwargs
diff --git a/contrib/python/matplotlib/py3/matplotlib/_tri.pyi b/contrib/python/matplotlib/py3/matplotlib/_tri.pyi
deleted file mode 100644
index cab7fcf2bc..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_tri.pyi
+++ /dev/null
@@ -1,23 +0,0 @@
-# This is a private module implemented in C++
-# As such these type stubs are overly generic, but here to allow these types
-# as return types for public methods
-from typing import Any
-
-class TrapezoidMapTriFinder:
- def __init__(self, *args, **kwargs) -> None: ...
- def find_many(self, *args, **kwargs) -> Any: ...
- def get_tree_stats(self, *args, **kwargs) -> Any: ...
- def initialize(self, *args, **kwargs) -> Any: ...
- def print_tree(self, *args, **kwargs) -> Any: ...
-
-class TriContourGenerator:
- def __init__(self, *args, **kwargs) -> None: ...
- def create_contour(self, *args, **kwargs) -> Any: ...
- def create_filled_contour(self, *args, **kwargs) -> Any: ...
-
-class Triangulation:
- def __init__(self, *args, **kwargs) -> None: ...
- def calculate_plane_coefficients(self, *args, **kwargs) -> Any: ...
- def get_edges(self, *args, **kwargs) -> Any: ...
- def get_neighbors(self, *args, **kwargs) -> Any: ...
- def set_mask(self, *args, **kwargs) -> Any: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/_ttconv.pyi b/contrib/python/matplotlib/py3/matplotlib/_ttconv.pyi
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_ttconv.pyi
+++ /dev/null
diff --git a/contrib/python/matplotlib/py3/matplotlib/_type1font.py b/contrib/python/matplotlib/py3/matplotlib/_type1font.py
deleted file mode 100644
index a3124a2457..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_type1font.py
+++ /dev/null
@@ -1,876 +0,0 @@
-"""
-A class representing a Type 1 font.
-
-This version reads pfa and pfb files and splits them for embedding in
-pdf files. It also supports SlantFont and ExtendFont transformations,
-similarly to pdfTeX and friends. There is no support yet for subsetting.
-
-Usage::
-
- font = Type1Font(filename)
- clear_part, encrypted_part, finale = font.parts
- slanted_font = font.transform({'slant': 0.167})
- extended_font = font.transform({'extend': 1.2})
-
-Sources:
-
-* Adobe Technical Note #5040, Supporting Downloadable PostScript
- Language Fonts.
-
-* Adobe Type 1 Font Format, Adobe Systems Incorporated, third printing,
- v1.1, 1993. ISBN 0-201-57044-0.
-"""
-
-import binascii
-import functools
-import logging
-import re
-import string
-import struct
-
-import numpy as np
-
-from matplotlib.cbook import _format_approx
-from . import _api
-
-_log = logging.getLogger(__name__)
-
-
-class _Token:
- """
- A token in a PostScript stream.
-
- Attributes
- ----------
- pos : int
- Position, i.e. offset from the beginning of the data.
- raw : str
- Raw text of the token.
- kind : str
- Description of the token (for debugging or testing).
- """
- __slots__ = ('pos', 'raw')
- kind = '?'
-
- def __init__(self, pos, raw):
- _log.debug('type1font._Token %s at %d: %r', self.kind, pos, raw)
- self.pos = pos
- self.raw = raw
-
- def __str__(self):
- return f"<{self.kind} {self.raw} @{self.pos}>"
-
- def endpos(self):
- """Position one past the end of the token"""
- return self.pos + len(self.raw)
-
- def is_keyword(self, *names):
- """Is this a name token with one of the names?"""
- return False
-
- def is_slash_name(self):
- """Is this a name token that starts with a slash?"""
- return False
-
- def is_delim(self):
- """Is this a delimiter token?"""
- return False
-
- def is_number(self):
- """Is this a number token?"""
- return False
-
- def value(self):
- return self.raw
-
-
-class _NameToken(_Token):
- kind = 'name'
-
- def is_slash_name(self):
- return self.raw.startswith('/')
-
- def value(self):
- return self.raw[1:]
-
-
-class _BooleanToken(_Token):
- kind = 'boolean'
-
- def value(self):
- return self.raw == 'true'
-
-
-class _KeywordToken(_Token):
- kind = 'keyword'
-
- def is_keyword(self, *names):
- return self.raw in names
-
-
-class _DelimiterToken(_Token):
- kind = 'delimiter'
-
- def is_delim(self):
- return True
-
- def opposite(self):
- return {'[': ']', ']': '[',
- '{': '}', '}': '{',
- '<<': '>>', '>>': '<<'
- }[self.raw]
-
-
-class _WhitespaceToken(_Token):
- kind = 'whitespace'
-
-
-class _StringToken(_Token):
- kind = 'string'
- _escapes_re = re.compile(r'\\([\\()nrtbf]|[0-7]{1,3})')
- _replacements = {'\\': '\\', '(': '(', ')': ')', 'n': '\n',
- 'r': '\r', 't': '\t', 'b': '\b', 'f': '\f'}
- _ws_re = re.compile('[\0\t\r\f\n ]')
-
- @classmethod
- def _escape(cls, match):
- group = match.group(1)
- try:
- return cls._replacements[group]
- except KeyError:
- return chr(int(group, 8))
-
- @functools.lru_cache
- def value(self):
- if self.raw[0] == '(':
- return self._escapes_re.sub(self._escape, self.raw[1:-1])
- else:
- data = self._ws_re.sub('', self.raw[1:-1])
- if len(data) % 2 == 1:
- data += '0'
- return binascii.unhexlify(data)
-
-
-class _BinaryToken(_Token):
- kind = 'binary'
-
- def value(self):
- return self.raw[1:]
-
-
-class _NumberToken(_Token):
- kind = 'number'
-
- def is_number(self):
- return True
-
- def value(self):
- if '.' not in self.raw:
- return int(self.raw)
- else:
- return float(self.raw)
-
-
-def _tokenize(data: bytes, skip_ws: bool):
- """
- A generator that produces _Token instances from Type-1 font code.
-
- The consumer of the generator may send an integer to the tokenizer to
- indicate that the next token should be _BinaryToken of the given length.
-
- Parameters
- ----------
- data : bytes
- The data of the font to tokenize.
-
- skip_ws : bool
- If true, the generator will drop any _WhitespaceTokens from the output.
- """
-
- text = data.decode('ascii', 'replace')
- whitespace_or_comment_re = re.compile(r'[\0\t\r\f\n ]+|%[^\r\n]*')
- token_re = re.compile(r'/{0,2}[^]\0\t\r\f\n ()<>{}/%[]+')
- instring_re = re.compile(r'[()\\]')
- hex_re = re.compile(r'^<[0-9a-fA-F\0\t\r\f\n ]*>$')
- oct_re = re.compile(r'[0-7]{1,3}')
- pos = 0
- next_binary = None
-
- while pos < len(text):
- if next_binary is not None:
- n = next_binary
- next_binary = (yield _BinaryToken(pos, data[pos:pos+n]))
- pos += n
- continue
- match = whitespace_or_comment_re.match(text, pos)
- if match:
- if not skip_ws:
- next_binary = (yield _WhitespaceToken(pos, match.group()))
- pos = match.end()
- elif text[pos] == '(':
- # PostScript string rules:
- # - parentheses must be balanced
- # - backslashes escape backslashes and parens
- # - also codes \n\r\t\b\f and octal escapes are recognized
- # - other backslashes do not escape anything
- start = pos
- pos += 1
- depth = 1
- while depth:
- match = instring_re.search(text, pos)
- if match is None:
- raise ValueError(
- f'Unterminated string starting at {start}')
- pos = match.end()
- if match.group() == '(':
- depth += 1
- elif match.group() == ')':
- depth -= 1
- else: # a backslash
- char = text[pos]
- if char in r'\()nrtbf':
- pos += 1
- else:
- octal = oct_re.match(text, pos)
- if octal:
- pos = octal.end()
- else:
- pass # non-escaping backslash
- next_binary = (yield _StringToken(start, text[start:pos]))
- elif text[pos:pos + 2] in ('<<', '>>'):
- next_binary = (yield _DelimiterToken(pos, text[pos:pos + 2]))
- pos += 2
- elif text[pos] == '<':
- start = pos
- try:
- pos = text.index('>', pos) + 1
- except ValueError as e:
- raise ValueError(f'Unterminated hex string starting at {start}'
- ) from e
- if not hex_re.match(text[start:pos]):
- raise ValueError(f'Malformed hex string starting at {start}')
- next_binary = (yield _StringToken(pos, text[start:pos]))
- else:
- match = token_re.match(text, pos)
- if match:
- raw = match.group()
- if raw.startswith('/'):
- next_binary = (yield _NameToken(pos, raw))
- elif match.group() in ('true', 'false'):
- next_binary = (yield _BooleanToken(pos, raw))
- else:
- try:
- float(raw)
- next_binary = (yield _NumberToken(pos, raw))
- except ValueError:
- next_binary = (yield _KeywordToken(pos, raw))
- pos = match.end()
- else:
- next_binary = (yield _DelimiterToken(pos, text[pos]))
- pos += 1
-
-
-class _BalancedExpression(_Token):
- pass
-
-
-def _expression(initial, tokens, data):
- """
- Consume some number of tokens and return a balanced PostScript expression.
-
- Parameters
- ----------
- initial : _Token
- The token that triggered parsing a balanced expression.
- tokens : iterator of _Token
- Following tokens.
- data : bytes
- Underlying data that the token positions point to.
-
- Returns
- -------
- _BalancedExpression
- """
- delim_stack = []
- token = initial
- while True:
- if token.is_delim():
- if token.raw in ('[', '{'):
- delim_stack.append(token)
- elif token.raw in (']', '}'):
- if not delim_stack:
- raise RuntimeError(f"unmatched closing token {token}")
- match = delim_stack.pop()
- if match.raw != token.opposite():
- raise RuntimeError(
- f"opening token {match} closed by {token}"
- )
- if not delim_stack:
- break
- else:
- raise RuntimeError(f'unknown delimiter {token}')
- elif not delim_stack:
- break
- token = next(tokens)
- return _BalancedExpression(
- initial.pos,
- data[initial.pos:token.endpos()].decode('ascii', 'replace')
- )
-
-
-class Type1Font:
- """
- A class representing a Type-1 font, for use by backends.
-
- Attributes
- ----------
- parts : tuple
- A 3-tuple of the cleartext part, the encrypted part, and the finale of
- zeros.
-
- decrypted : bytes
- The decrypted form of ``parts[1]``.
-
- prop : dict[str, Any]
- A dictionary of font properties. Noteworthy keys include:
-
- - FontName: PostScript name of the font
- - Encoding: dict from numeric codes to glyph names
- - FontMatrix: bytes object encoding a matrix
- - UniqueID: optional font identifier, dropped when modifying the font
- - CharStrings: dict from glyph names to byte code
- - Subrs: array of byte code subroutines
- - OtherSubrs: bytes object encoding some PostScript code
- """
- __slots__ = ('parts', 'decrypted', 'prop', '_pos', '_abbr')
- # the _pos dict contains (begin, end) indices to parts[0] + decrypted
- # so that they can be replaced when transforming the font;
- # but since sometimes a definition appears in both parts[0] and decrypted,
- # _pos[name] is an array of such pairs
- #
- # _abbr maps three standard abbreviations to their particular names in
- # this font (e.g. 'RD' is named '-|' in some fonts)
-
- def __init__(self, input):
- """
- Initialize a Type-1 font.
-
- Parameters
- ----------
- input : str or 3-tuple
- Either a pfb file name, or a 3-tuple of already-decoded Type-1
- font `~.Type1Font.parts`.
- """
- if isinstance(input, tuple) and len(input) == 3:
- self.parts = input
- else:
- with open(input, 'rb') as file:
- data = self._read(file)
- self.parts = self._split(data)
-
- self.decrypted = self._decrypt(self.parts[1], 'eexec')
- self._abbr = {'RD': 'RD', 'ND': 'ND', 'NP': 'NP'}
- self._parse()
-
- def _read(self, file):
- """Read the font from a file, decoding into usable parts."""
- rawdata = file.read()
- if not rawdata.startswith(b'\x80'):
- return rawdata
-
- data = b''
- while rawdata:
- if not rawdata.startswith(b'\x80'):
- raise RuntimeError('Broken pfb file (expected byte 128, '
- 'got %d)' % rawdata[0])
- type = rawdata[1]
- if type in (1, 2):
- length, = struct.unpack('<i', rawdata[2:6])
- segment = rawdata[6:6 + length]
- rawdata = rawdata[6 + length:]
-
- if type == 1: # ASCII text: include verbatim
- data += segment
- elif type == 2: # binary data: encode in hexadecimal
- data += binascii.hexlify(segment)
- elif type == 3: # end of file
- break
- else:
- raise RuntimeError('Unknown segment type %d in pfb file' % type)
-
- return data
-
- def _split(self, data):
- """
- Split the Type 1 font into its three main parts.
-
- The three parts are: (1) the cleartext part, which ends in a
- eexec operator; (2) the encrypted part; (3) the fixed part,
- which contains 512 ASCII zeros possibly divided on various
- lines, a cleartomark operator, and possibly something else.
- """
-
- # Cleartext part: just find the eexec and skip whitespace
- idx = data.index(b'eexec')
- idx += len(b'eexec')
- while data[idx] in b' \t\r\n':
- idx += 1
- len1 = idx
-
- # Encrypted part: find the cleartomark operator and count
- # zeros backward
- idx = data.rindex(b'cleartomark') - 1
- zeros = 512
- while zeros and data[idx] in b'0' or data[idx] in b'\r\n':
- if data[idx] in b'0':
- zeros -= 1
- idx -= 1
- if zeros:
- # this may have been a problem on old implementations that
- # used the zeros as necessary padding
- _log.info('Insufficiently many zeros in Type 1 font')
-
- # Convert encrypted part to binary (if we read a pfb file, we may end
- # up converting binary to hexadecimal to binary again; but if we read
- # a pfa file, this part is already in hex, and I am not quite sure if
- # even the pfb format guarantees that it will be in binary).
- idx1 = len1 + ((idx - len1 + 2) & ~1) # ensure an even number of bytes
- binary = binascii.unhexlify(data[len1:idx1])
-
- return data[:len1], binary, data[idx+1:]
-
- @staticmethod
- def _decrypt(ciphertext, key, ndiscard=4):
- """
- Decrypt ciphertext using the Type-1 font algorithm.
-
- The algorithm is described in Adobe's "Adobe Type 1 Font Format".
- The key argument can be an integer, or one of the strings
- 'eexec' and 'charstring', which map to the key specified for the
- corresponding part of Type-1 fonts.
-
- The ndiscard argument should be an integer, usually 4.
- That number of bytes is discarded from the beginning of plaintext.
- """
-
- key = _api.check_getitem({'eexec': 55665, 'charstring': 4330}, key=key)
- plaintext = []
- for byte in ciphertext:
- plaintext.append(byte ^ (key >> 8))
- key = ((key+byte) * 52845 + 22719) & 0xffff
-
- return bytes(plaintext[ndiscard:])
-
- @staticmethod
- def _encrypt(plaintext, key, ndiscard=4):
- """
- Encrypt plaintext using the Type-1 font algorithm.
-
- The algorithm is described in Adobe's "Adobe Type 1 Font Format".
- The key argument can be an integer, or one of the strings
- 'eexec' and 'charstring', which map to the key specified for the
- corresponding part of Type-1 fonts.
-
- The ndiscard argument should be an integer, usually 4. That
- number of bytes is prepended to the plaintext before encryption.
- This function prepends NUL bytes for reproducibility, even though
- the original algorithm uses random bytes, presumably to avoid
- cryptanalysis.
- """
-
- key = _api.check_getitem({'eexec': 55665, 'charstring': 4330}, key=key)
- ciphertext = []
- for byte in b'\0' * ndiscard + plaintext:
- c = byte ^ (key >> 8)
- ciphertext.append(c)
- key = ((key + c) * 52845 + 22719) & 0xffff
-
- return bytes(ciphertext)
-
- def _parse(self):
- """
- Find the values of various font properties. This limited kind
- of parsing is described in Chapter 10 "Adobe Type Manager
- Compatibility" of the Type-1 spec.
- """
- # Start with reasonable defaults
- prop = {'Weight': 'Regular', 'ItalicAngle': 0.0, 'isFixedPitch': False,
- 'UnderlinePosition': -100, 'UnderlineThickness': 50}
- pos = {}
- data = self.parts[0] + self.decrypted
-
- source = _tokenize(data, True)
- while True:
- # See if there is a key to be assigned a value
- # e.g. /FontName in /FontName /Helvetica def
- try:
- token = next(source)
- except StopIteration:
- break
- if token.is_delim():
- # skip over this - we want top-level keys only
- _expression(token, source, data)
- if token.is_slash_name():
- key = token.value()
- keypos = token.pos
- else:
- continue
-
- # Some values need special parsing
- if key in ('Subrs', 'CharStrings', 'Encoding', 'OtherSubrs'):
- prop[key], endpos = {
- 'Subrs': self._parse_subrs,
- 'CharStrings': self._parse_charstrings,
- 'Encoding': self._parse_encoding,
- 'OtherSubrs': self._parse_othersubrs
- }[key](source, data)
- pos.setdefault(key, []).append((keypos, endpos))
- continue
-
- try:
- token = next(source)
- except StopIteration:
- break
-
- if isinstance(token, _KeywordToken):
- # constructs like
- # FontDirectory /Helvetica known {...} {...} ifelse
- # mean the key was not really a key
- continue
-
- if token.is_delim():
- value = _expression(token, source, data).raw
- else:
- value = token.value()
-
- # look for a 'def' possibly preceded by access modifiers
- try:
- kw = next(
- kw for kw in source
- if not kw.is_keyword('readonly', 'noaccess', 'executeonly')
- )
- except StopIteration:
- break
-
- # sometimes noaccess def and readonly def are abbreviated
- if kw.is_keyword('def', self._abbr['ND'], self._abbr['NP']):
- prop[key] = value
- pos.setdefault(key, []).append((keypos, kw.endpos()))
-
- # detect the standard abbreviations
- if value == '{noaccess def}':
- self._abbr['ND'] = key
- elif value == '{noaccess put}':
- self._abbr['NP'] = key
- elif value == '{string currentfile exch readstring pop}':
- self._abbr['RD'] = key
-
- # Fill in the various *Name properties
- if 'FontName' not in prop:
- prop['FontName'] = (prop.get('FullName') or
- prop.get('FamilyName') or
- 'Unknown')
- if 'FullName' not in prop:
- prop['FullName'] = prop['FontName']
- if 'FamilyName' not in prop:
- extras = ('(?i)([ -](regular|plain|italic|oblique|(semi)?bold|'
- '(ultra)?light|extra|condensed))+$')
- prop['FamilyName'] = re.sub(extras, '', prop['FullName'])
- # Decrypt the encrypted parts
- ndiscard = prop.get('lenIV', 4)
- cs = prop['CharStrings']
- for key, value in cs.items():
- cs[key] = self._decrypt(value, 'charstring', ndiscard)
- if 'Subrs' in prop:
- prop['Subrs'] = [
- self._decrypt(value, 'charstring', ndiscard)
- for value in prop['Subrs']
- ]
-
- self.prop = prop
- self._pos = pos
-
- def _parse_subrs(self, tokens, _data):
- count_token = next(tokens)
- if not count_token.is_number():
- raise RuntimeError(
- f"Token following /Subrs must be a number, was {count_token}"
- )
- count = count_token.value()
- array = [None] * count
- next(t for t in tokens if t.is_keyword('array'))
- for _ in range(count):
- next(t for t in tokens if t.is_keyword('dup'))
- index_token = next(tokens)
- if not index_token.is_number():
- raise RuntimeError(
- "Token following dup in Subrs definition must be a "
- f"number, was {index_token}"
- )
- nbytes_token = next(tokens)
- if not nbytes_token.is_number():
- raise RuntimeError(
- "Second token following dup in Subrs definition must "
- f"be a number, was {nbytes_token}"
- )
- token = next(tokens)
- if not token.is_keyword(self._abbr['RD']):
- raise RuntimeError(
- f"Token preceding subr must be {self._abbr['RD']}, "
- f"was {token}"
- )
- binary_token = tokens.send(1+nbytes_token.value())
- array[index_token.value()] = binary_token.value()
-
- return array, next(tokens).endpos()
-
- @staticmethod
- def _parse_charstrings(tokens, _data):
- count_token = next(tokens)
- if not count_token.is_number():
- raise RuntimeError(
- "Token following /CharStrings must be a number, "
- f"was {count_token}"
- )
- count = count_token.value()
- charstrings = {}
- next(t for t in tokens if t.is_keyword('begin'))
- while True:
- token = next(t for t in tokens
- if t.is_keyword('end') or t.is_slash_name())
- if token.raw == 'end':
- return charstrings, token.endpos()
- glyphname = token.value()
- nbytes_token = next(tokens)
- if not nbytes_token.is_number():
- raise RuntimeError(
- f"Token following /{glyphname} in CharStrings definition "
- f"must be a number, was {nbytes_token}"
- )
- next(tokens) # usually RD or |-
- binary_token = tokens.send(1+nbytes_token.value())
- charstrings[glyphname] = binary_token.value()
-
- @staticmethod
- def _parse_encoding(tokens, _data):
- # this only works for encodings that follow the Adobe manual
- # but some old fonts include non-compliant data - we log a warning
- # and return a possibly incomplete encoding
- encoding = {}
- while True:
- token = next(t for t in tokens
- if t.is_keyword('StandardEncoding', 'dup', 'def'))
- if token.is_keyword('StandardEncoding'):
- return _StandardEncoding, token.endpos()
- if token.is_keyword('def'):
- return encoding, token.endpos()
- index_token = next(tokens)
- if not index_token.is_number():
- _log.warning(
- f"Parsing encoding: expected number, got {index_token}"
- )
- continue
- name_token = next(tokens)
- if not name_token.is_slash_name():
- _log.warning(
- f"Parsing encoding: expected slash-name, got {name_token}"
- )
- continue
- encoding[index_token.value()] = name_token.value()
-
- @staticmethod
- def _parse_othersubrs(tokens, data):
- init_pos = None
- while True:
- token = next(tokens)
- if init_pos is None:
- init_pos = token.pos
- if token.is_delim():
- _expression(token, tokens, data)
- elif token.is_keyword('def', 'ND', '|-'):
- return data[init_pos:token.endpos()], token.endpos()
-
- def transform(self, effects):
- """
- Return a new font that is slanted and/or extended.
-
- Parameters
- ----------
- effects : dict
- A dict with optional entries:
-
- - 'slant' : float, default: 0
- Tangent of the angle that the font is to be slanted to the
- right. Negative values slant to the left.
- - 'extend' : float, default: 1
- Scaling factor for the font width. Values less than 1 condense
- the glyphs.
-
- Returns
- -------
- `Type1Font`
- """
- fontname = self.prop['FontName']
- italicangle = self.prop['ItalicAngle']
-
- array = [
- float(x) for x in (self.prop['FontMatrix']
- .lstrip('[').rstrip(']').split())
- ]
- oldmatrix = np.eye(3, 3)
- oldmatrix[0:3, 0] = array[::2]
- oldmatrix[0:3, 1] = array[1::2]
- modifier = np.eye(3, 3)
-
- if 'slant' in effects:
- slant = effects['slant']
- fontname += f'_Slant_{int(1000 * slant)}'
- italicangle = round(
- float(italicangle) - np.arctan(slant) / np.pi * 180,
- 5
- )
- modifier[1, 0] = slant
-
- if 'extend' in effects:
- extend = effects['extend']
- fontname += f'_Extend_{int(1000 * extend)}'
- modifier[0, 0] = extend
-
- newmatrix = np.dot(modifier, oldmatrix)
- array[::2] = newmatrix[0:3, 0]
- array[1::2] = newmatrix[0:3, 1]
- fontmatrix = (
- f"[{' '.join(_format_approx(x, 6) for x in array)}]"
- )
- replacements = (
- [(x, f'/FontName/{fontname} def')
- for x in self._pos['FontName']]
- + [(x, f'/ItalicAngle {italicangle} def')
- for x in self._pos['ItalicAngle']]
- + [(x, f'/FontMatrix {fontmatrix} readonly def')
- for x in self._pos['FontMatrix']]
- + [(x, '') for x in self._pos.get('UniqueID', [])]
- )
-
- data = bytearray(self.parts[0])
- data.extend(self.decrypted)
- len0 = len(self.parts[0])
- for (pos0, pos1), value in sorted(replacements, reverse=True):
- data[pos0:pos1] = value.encode('ascii', 'replace')
- if pos0 < len(self.parts[0]):
- if pos1 >= len(self.parts[0]):
- raise RuntimeError(
- f"text to be replaced with {value} spans "
- "the eexec boundary"
- )
- len0 += len(value) - pos1 + pos0
-
- data = bytes(data)
- return Type1Font((
- data[:len0],
- self._encrypt(data[len0:], 'eexec'),
- self.parts[2]
- ))
-
-
-_StandardEncoding = {
- **{ord(letter): letter for letter in string.ascii_letters},
- 0: '.notdef',
- 32: 'space',
- 33: 'exclam',
- 34: 'quotedbl',
- 35: 'numbersign',
- 36: 'dollar',
- 37: 'percent',
- 38: 'ampersand',
- 39: 'quoteright',
- 40: 'parenleft',
- 41: 'parenright',
- 42: 'asterisk',
- 43: 'plus',
- 44: 'comma',
- 45: 'hyphen',
- 46: 'period',
- 47: 'slash',
- 48: 'zero',
- 49: 'one',
- 50: 'two',
- 51: 'three',
- 52: 'four',
- 53: 'five',
- 54: 'six',
- 55: 'seven',
- 56: 'eight',
- 57: 'nine',
- 58: 'colon',
- 59: 'semicolon',
- 60: 'less',
- 61: 'equal',
- 62: 'greater',
- 63: 'question',
- 64: 'at',
- 91: 'bracketleft',
- 92: 'backslash',
- 93: 'bracketright',
- 94: 'asciicircum',
- 95: 'underscore',
- 96: 'quoteleft',
- 123: 'braceleft',
- 124: 'bar',
- 125: 'braceright',
- 126: 'asciitilde',
- 161: 'exclamdown',
- 162: 'cent',
- 163: 'sterling',
- 164: 'fraction',
- 165: 'yen',
- 166: 'florin',
- 167: 'section',
- 168: 'currency',
- 169: 'quotesingle',
- 170: 'quotedblleft',
- 171: 'guillemotleft',
- 172: 'guilsinglleft',
- 173: 'guilsinglright',
- 174: 'fi',
- 175: 'fl',
- 177: 'endash',
- 178: 'dagger',
- 179: 'daggerdbl',
- 180: 'periodcentered',
- 182: 'paragraph',
- 183: 'bullet',
- 184: 'quotesinglbase',
- 185: 'quotedblbase',
- 186: 'quotedblright',
- 187: 'guillemotright',
- 188: 'ellipsis',
- 189: 'perthousand',
- 191: 'questiondown',
- 193: 'grave',
- 194: 'acute',
- 195: 'circumflex',
- 196: 'tilde',
- 197: 'macron',
- 198: 'breve',
- 199: 'dotaccent',
- 200: 'dieresis',
- 202: 'ring',
- 203: 'cedilla',
- 205: 'hungarumlaut',
- 206: 'ogonek',
- 207: 'caron',
- 208: 'emdash',
- 225: 'AE',
- 227: 'ordfeminine',
- 232: 'Lslash',
- 233: 'Oslash',
- 234: 'OE',
- 235: 'ordmasculine',
- 241: 'ae',
- 245: 'dotlessi',
- 248: 'lslash',
- 249: 'oslash',
- 250: 'oe',
- 251: 'germandbls',
-}
diff --git a/contrib/python/matplotlib/py3/matplotlib/_version.py b/contrib/python/matplotlib/py3/matplotlib/_version.py
deleted file mode 100644
index f14d882a3d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/_version.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# file generated by setuptools_scm
-# don't change, don't track in version control
-TYPE_CHECKING = False
-if TYPE_CHECKING:
- from typing import Tuple, Union
- VERSION_TUPLE = Tuple[Union[int, str], ...]
-else:
- VERSION_TUPLE = object
-
-version: str
-__version__: str
-__version_tuple__: VERSION_TUPLE
-version_tuple: VERSION_TUPLE
-
-__version__ = version = '3.8.2'
-__version_tuple__ = version_tuple = (3, 8, 2)
diff --git a/contrib/python/matplotlib/py3/matplotlib/animation.py b/contrib/python/matplotlib/py3/matplotlib/animation.py
deleted file mode 100644
index e9b1c23658..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/animation.py
+++ /dev/null
@@ -1,1804 +0,0 @@
-# TODO:
-# * Documentation -- this will need a new section of the User's Guide.
-# Both for Animations and just timers.
-# - Also need to update
-# https://scipy-cookbook.readthedocs.io/items/Matplotlib_Animations.html
-# * Blit
-# * Currently broken with Qt4 for widgets that don't start on screen
-# * Still a few edge cases that aren't working correctly
-# * Can this integrate better with existing matplotlib animation artist flag?
-# - If animated removes from default draw(), perhaps we could use this to
-# simplify initial draw.
-# * Example
-# * Frameless animation - pure procedural with no loop
-# * Need example that uses something like inotify or subprocess
-# * Complex syncing examples
-# * Movies
-# * Can blit be enabled for movies?
-# * Need to consider event sources to allow clicking through multiple figures
-
-
-import abc
-import base64
-import contextlib
-from io import BytesIO, TextIOWrapper
-import itertools
-import logging
-from pathlib import Path
-import shutil
-import subprocess
-import sys
-from tempfile import TemporaryDirectory
-import uuid
-import warnings
-
-import numpy as np
-from PIL import Image
-
-import matplotlib as mpl
-from matplotlib._animation_data import (
- DISPLAY_TEMPLATE, INCLUDED_FRAMES, JS_INCLUDE, STYLE_INCLUDE)
-from matplotlib import _api, cbook
-import matplotlib.colors as mcolors
-
-_log = logging.getLogger(__name__)
-
-# Process creation flag for subprocess to prevent it raising a terminal
-# window. See for example https://stackoverflow.com/q/24130623/
-subprocess_creation_flags = (
- subprocess.CREATE_NO_WINDOW if sys.platform == 'win32' else 0)
-
-# Other potential writing methods:
-# * http://pymedia.org/
-# * libming (produces swf) python wrappers: https://github.com/libming/libming
-# * Wrap x264 API:
-
-# (https://stackoverflow.com/q/2940671/)
-
-
-def adjusted_figsize(w, h, dpi, n):
- """
- Compute figure size so that pixels are a multiple of n.
-
- Parameters
- ----------
- w, h : float
- Size in inches.
-
- dpi : float
- The dpi.
-
- n : int
- The target multiple.
-
- Returns
- -------
- wnew, hnew : float
- The new figure size in inches.
- """
-
- # this maybe simplified if / when we adopt consistent rounding for
- # pixel size across the whole library
- def correct_roundoff(x, dpi, n):
- if int(x*dpi) % n != 0:
- if int(np.nextafter(x, np.inf)*dpi) % n == 0:
- x = np.nextafter(x, np.inf)
- elif int(np.nextafter(x, -np.inf)*dpi) % n == 0:
- x = np.nextafter(x, -np.inf)
- return x
-
- wnew = int(w * dpi / n) * n / dpi
- hnew = int(h * dpi / n) * n / dpi
- return correct_roundoff(wnew, dpi, n), correct_roundoff(hnew, dpi, n)
-
-
-class MovieWriterRegistry:
- """Registry of available writer classes by human readable name."""
-
- def __init__(self):
- self._registered = dict()
-
- def register(self, name):
- """
- Decorator for registering a class under a name.
-
- Example use::
-
- @registry.register(name)
- class Foo:
- pass
- """
- def wrapper(writer_cls):
- self._registered[name] = writer_cls
- return writer_cls
- return wrapper
-
- def is_available(self, name):
- """
- Check if given writer is available by name.
-
- Parameters
- ----------
- name : str
-
- Returns
- -------
- bool
- """
- try:
- cls = self._registered[name]
- except KeyError:
- return False
- return cls.isAvailable()
-
- def __iter__(self):
- """Iterate over names of available writer class."""
- for name in self._registered:
- if self.is_available(name):
- yield name
-
- def list(self):
- """Get a list of available MovieWriters."""
- return [*self]
-
- def __getitem__(self, name):
- """Get an available writer class from its name."""
- if self.is_available(name):
- return self._registered[name]
- raise RuntimeError(f"Requested MovieWriter ({name}) not available")
-
-
-writers = MovieWriterRegistry()
-
-
-class AbstractMovieWriter(abc.ABC):
- """
- Abstract base class for writing movies, providing a way to grab frames by
- calling `~AbstractMovieWriter.grab_frame`.
-
- `setup` is called to start the process and `finish` is called afterwards.
- `saving` is provided as a context manager to facilitate this process as ::
-
- with moviewriter.saving(fig, outfile='myfile.mp4', dpi=100):
- # Iterate over frames
- moviewriter.grab_frame(**savefig_kwargs)
-
- The use of the context manager ensures that `setup` and `finish` are
- performed as necessary.
-
- An instance of a concrete subclass of this class can be given as the
- ``writer`` argument of `Animation.save()`.
- """
-
- def __init__(self, fps=5, metadata=None, codec=None, bitrate=None):
- self.fps = fps
- self.metadata = metadata if metadata is not None else {}
- self.codec = mpl._val_or_rc(codec, 'animation.codec')
- self.bitrate = mpl._val_or_rc(bitrate, 'animation.bitrate')
-
- @abc.abstractmethod
- def setup(self, fig, outfile, dpi=None):
- """
- Setup for writing the movie file.
-
- Parameters
- ----------
- fig : `~matplotlib.figure.Figure`
- The figure object that contains the information for frames.
- outfile : str
- The filename of the resulting movie file.
- dpi : float, default: ``fig.dpi``
- The DPI (or resolution) for the file. This controls the size
- in pixels of the resulting movie file.
- """
- # Check that path is valid
- Path(outfile).parent.resolve(strict=True)
- self.outfile = outfile
- self.fig = fig
- if dpi is None:
- dpi = self.fig.dpi
- self.dpi = dpi
-
- @property
- def frame_size(self):
- """A tuple ``(width, height)`` in pixels of a movie frame."""
- w, h = self.fig.get_size_inches()
- return int(w * self.dpi), int(h * self.dpi)
-
- @abc.abstractmethod
- def grab_frame(self, **savefig_kwargs):
- """
- Grab the image information from the figure and save as a movie frame.
-
- All keyword arguments in *savefig_kwargs* are passed on to the
- `~.Figure.savefig` call that saves the figure. However, several
- keyword arguments that are supported by `~.Figure.savefig` may not be
- passed as they are controlled by the MovieWriter:
-
- - *dpi*, *bbox_inches*: These may not be passed because each frame of the
- animation much be exactly the same size in pixels.
- - *format*: This is controlled by the MovieWriter.
- """
-
- @abc.abstractmethod
- def finish(self):
- """Finish any processing for writing the movie."""
-
- @contextlib.contextmanager
- def saving(self, fig, outfile, dpi, *args, **kwargs):
- """
- Context manager to facilitate writing the movie file.
-
- ``*args, **kw`` are any parameters that should be passed to `setup`.
- """
- if mpl.rcParams['savefig.bbox'] == 'tight':
- _log.info("Disabling savefig.bbox = 'tight', as it may cause "
- "frame size to vary, which is inappropriate for "
- "animation.")
-
- # This particular sequence is what contextlib.contextmanager wants
- self.setup(fig, outfile, dpi, *args, **kwargs)
- with mpl.rc_context({'savefig.bbox': None}):
- try:
- yield self
- finally:
- self.finish()
-
-
-class MovieWriter(AbstractMovieWriter):
- """
- Base class for writing movies.
-
- This is a base class for MovieWriter subclasses that write a movie frame
- data to a pipe. You cannot instantiate this class directly.
- See examples for how to use its subclasses.
-
- Attributes
- ----------
- frame_format : str
- The format used in writing frame data, defaults to 'rgba'.
- fig : `~matplotlib.figure.Figure`
- The figure to capture data from.
- This must be provided by the subclasses.
- """
-
- # Builtin writer subclasses additionally define the _exec_key and _args_key
- # attributes, which indicate the rcParams entries where the path to the
- # executable and additional command-line arguments to the executable are
- # stored. Third-party writers cannot meaningfully set these as they cannot
- # extend rcParams with new keys.
-
- # Pipe-based writers only support RGBA, but file-based ones support more
- # formats.
- supported_formats = ["rgba"]
-
- def __init__(self, fps=5, codec=None, bitrate=None, extra_args=None,
- metadata=None):
- """
- Parameters
- ----------
- fps : int, default: 5
- Movie frame rate (per second).
- codec : str or None, default: :rc:`animation.codec`
- The codec to use.
- bitrate : int, default: :rc:`animation.bitrate`
- The bitrate of the movie, in kilobits per second. Higher values
- means higher quality movies, but increase the file size. A value
- of -1 lets the underlying movie encoder select the bitrate.
- extra_args : list of str or None, optional
- Extra command-line arguments passed to the underlying movie encoder. These
- arguments are passed last to the encoder, just before the filename. The
- default, None, means to use :rc:`animation.[name-of-encoder]_args` for the
- builtin writers.
- metadata : dict[str, str], default: {}
- A dictionary of keys and values for metadata to include in the
- output file. Some keys that may be of use include:
- title, artist, genre, subject, copyright, srcform, comment.
- """
- if type(self) is MovieWriter:
- # TODO MovieWriter is still an abstract class and needs to be
- # extended with a mixin. This should be clearer in naming
- # and description. For now, just give a reasonable error
- # message to users.
- raise TypeError(
- 'MovieWriter cannot be instantiated directly. Please use one '
- 'of its subclasses.')
-
- super().__init__(fps=fps, metadata=metadata, codec=codec,
- bitrate=bitrate)
- self.frame_format = self.supported_formats[0]
- self.extra_args = extra_args
-
- def _adjust_frame_size(self):
- if self.codec == 'h264':
- wo, ho = self.fig.get_size_inches()
- w, h = adjusted_figsize(wo, ho, self.dpi, 2)
- if (wo, ho) != (w, h):
- self.fig.set_size_inches(w, h, forward=True)
- _log.info('figure size in inches has been adjusted '
- 'from %s x %s to %s x %s', wo, ho, w, h)
- else:
- w, h = self.fig.get_size_inches()
- _log.debug('frame size in pixels is %s x %s', *self.frame_size)
- return w, h
-
- def setup(self, fig, outfile, dpi=None):
- # docstring inherited
- super().setup(fig, outfile, dpi=dpi)
- self._w, self._h = self._adjust_frame_size()
- # Run here so that grab_frame() can write the data to a pipe. This
- # eliminates the need for temp files.
- self._run()
-
- def _run(self):
- # Uses subprocess to call the program for assembling frames into a
- # movie file. *args* returns the sequence of command line arguments
- # from a few configuration options.
- command = self._args()
- _log.info('MovieWriter._run: running command: %s',
- cbook._pformat_subprocess(command))
- PIPE = subprocess.PIPE
- self._proc = subprocess.Popen(
- command, stdin=PIPE, stdout=PIPE, stderr=PIPE,
- creationflags=subprocess_creation_flags)
-
- def finish(self):
- """Finish any processing for writing the movie."""
- out, err = self._proc.communicate()
- # Use the encoding/errors that universal_newlines would use.
- out = TextIOWrapper(BytesIO(out)).read()
- err = TextIOWrapper(BytesIO(err)).read()
- if out:
- _log.log(
- logging.WARNING if self._proc.returncode else logging.DEBUG,
- "MovieWriter stdout:\n%s", out)
- if err:
- _log.log(
- logging.WARNING if self._proc.returncode else logging.DEBUG,
- "MovieWriter stderr:\n%s", err)
- if self._proc.returncode:
- raise subprocess.CalledProcessError(
- self._proc.returncode, self._proc.args, out, err)
-
- def grab_frame(self, **savefig_kwargs):
- # docstring inherited
- _validate_grabframe_kwargs(savefig_kwargs)
- _log.debug('MovieWriter.grab_frame: Grabbing frame.')
- # Readjust the figure size in case it has been changed by the user.
- # All frames must have the same size to save the movie correctly.
- self.fig.set_size_inches(self._w, self._h)
- # Save the figure data to the sink, using the frame format and dpi.
- self.fig.savefig(self._proc.stdin, format=self.frame_format,
- dpi=self.dpi, **savefig_kwargs)
-
- def _args(self):
- """Assemble list of encoder-specific command-line arguments."""
- return NotImplementedError("args needs to be implemented by subclass.")
-
- @classmethod
- def bin_path(cls):
- """
- Return the binary path to the commandline tool used by a specific
- subclass. This is a class method so that the tool can be looked for
- before making a particular MovieWriter subclass available.
- """
- return str(mpl.rcParams[cls._exec_key])
-
- @classmethod
- def isAvailable(cls):
- """Return whether a MovieWriter subclass is actually available."""
- return shutil.which(cls.bin_path()) is not None
-
-
-class FileMovieWriter(MovieWriter):
- """
- `MovieWriter` for writing to individual files and stitching at the end.
-
- This must be sub-classed to be useful.
- """
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- self.frame_format = mpl.rcParams['animation.frame_format']
-
- def setup(self, fig, outfile, dpi=None, frame_prefix=None):
- """
- Setup for writing the movie file.
-
- Parameters
- ----------
- fig : `~matplotlib.figure.Figure`
- The figure to grab the rendered frames from.
- outfile : str
- The filename of the resulting movie file.
- dpi : float, default: ``fig.dpi``
- The dpi of the output file. This, with the figure size,
- controls the size in pixels of the resulting movie file.
- frame_prefix : str, optional
- The filename prefix to use for temporary files. If *None* (the
- default), files are written to a temporary directory which is
- deleted by `finish`; if not *None*, no temporary files are
- deleted.
- """
- # Check that path is valid
- Path(outfile).parent.resolve(strict=True)
- self.fig = fig
- self.outfile = outfile
- if dpi is None:
- dpi = self.fig.dpi
- self.dpi = dpi
- self._adjust_frame_size()
-
- if frame_prefix is None:
- self._tmpdir = TemporaryDirectory()
- self.temp_prefix = str(Path(self._tmpdir.name, 'tmp'))
- else:
- self._tmpdir = None
- self.temp_prefix = frame_prefix
- self._frame_counter = 0 # used for generating sequential file names
- self._temp_paths = list()
- self.fname_format_str = '%s%%07d.%s'
-
- def __del__(self):
- if hasattr(self, '_tmpdir') and self._tmpdir:
- self._tmpdir.cleanup()
-
- @property
- def frame_format(self):
- """
- Format (png, jpeg, etc.) to use for saving the frames, which can be
- decided by the individual subclasses.
- """
- return self._frame_format
-
- @frame_format.setter
- def frame_format(self, frame_format):
- if frame_format in self.supported_formats:
- self._frame_format = frame_format
- else:
- _api.warn_external(
- f"Ignoring file format {frame_format!r} which is not "
- f"supported by {type(self).__name__}; using "
- f"{self.supported_formats[0]} instead.")
- self._frame_format = self.supported_formats[0]
-
- def _base_temp_name(self):
- # Generates a template name (without number) given the frame format
- # for extension and the prefix.
- return self.fname_format_str % (self.temp_prefix, self.frame_format)
-
- def grab_frame(self, **savefig_kwargs):
- # docstring inherited
- # Creates a filename for saving using basename and counter.
- _validate_grabframe_kwargs(savefig_kwargs)
- path = Path(self._base_temp_name() % self._frame_counter)
- self._temp_paths.append(path) # Record the filename for later use.
- self._frame_counter += 1 # Ensures each created name is unique.
- _log.debug('FileMovieWriter.grab_frame: Grabbing frame %d to path=%s',
- self._frame_counter, path)
- with open(path, 'wb') as sink: # Save figure to the sink.
- self.fig.savefig(sink, format=self.frame_format, dpi=self.dpi,
- **savefig_kwargs)
-
- def finish(self):
- # Call run here now that all frame grabbing is done. All temp files
- # are available to be assembled.
- try:
- self._run()
- super().finish()
- finally:
- if self._tmpdir:
- _log.debug(
- 'MovieWriter: clearing temporary path=%s', self._tmpdir
- )
- self._tmpdir.cleanup()
-
-
-@writers.register('pillow')
-class PillowWriter(AbstractMovieWriter):
- @classmethod
- def isAvailable(cls):
- return True
-
- def setup(self, fig, outfile, dpi=None):
- super().setup(fig, outfile, dpi=dpi)
- self._frames = []
-
- def grab_frame(self, **savefig_kwargs):
- _validate_grabframe_kwargs(savefig_kwargs)
- buf = BytesIO()
- self.fig.savefig(
- buf, **{**savefig_kwargs, "format": "rgba", "dpi": self.dpi})
- self._frames.append(Image.frombuffer(
- "RGBA", self.frame_size, buf.getbuffer(), "raw", "RGBA", 0, 1))
-
- def finish(self):
- self._frames[0].save(
- self.outfile, save_all=True, append_images=self._frames[1:],
- duration=int(1000 / self.fps), loop=0)
-
-
-# Base class of ffmpeg information. Has the config keys and the common set
-# of arguments that controls the *output* side of things.
-class FFMpegBase:
- """
- Mixin class for FFMpeg output.
-
- This is a base class for the concrete `FFMpegWriter` and `FFMpegFileWriter`
- classes.
- """
-
- _exec_key = 'animation.ffmpeg_path'
- _args_key = 'animation.ffmpeg_args'
-
- @property
- def output_args(self):
- args = []
- if Path(self.outfile).suffix == '.gif':
- self.codec = 'gif'
- else:
- args.extend(['-vcodec', self.codec])
- extra_args = (self.extra_args if self.extra_args is not None
- else mpl.rcParams[self._args_key])
- # For h264, the default format is yuv444p, which is not compatible
- # with quicktime (and others). Specifying yuv420p fixes playback on
- # iOS, as well as HTML5 video in firefox and safari (on both Win and
- # OSX). Also fixes internet explorer. This is as of 2015/10/29.
- if self.codec == 'h264' and '-pix_fmt' not in extra_args:
- args.extend(['-pix_fmt', 'yuv420p'])
- # For GIF, we're telling FFMPEG to split the video stream, to generate
- # a palette, and then use it for encoding.
- elif self.codec == 'gif' and '-filter_complex' not in extra_args:
- args.extend(['-filter_complex',
- 'split [a][b];[a] palettegen [p];[b][p] paletteuse'])
- if self.bitrate > 0:
- args.extend(['-b', '%dk' % self.bitrate]) # %dk: bitrate in kbps.
- for k, v in self.metadata.items():
- args.extend(['-metadata', f'{k}={v}'])
- args.extend(extra_args)
-
- return args + ['-y', self.outfile]
-
-
-# Combine FFMpeg options with pipe-based writing
-@writers.register('ffmpeg')
-class FFMpegWriter(FFMpegBase, MovieWriter):
- """
- Pipe-based ffmpeg writer.
-
- Frames are streamed directly to ffmpeg via a pipe and written in a single pass.
-
- This effectively works as a slideshow input to ffmpeg with the fps passed as
- ``-framerate``, so see also `their notes on frame rates`_ for further details.
-
- .. _their notes on frame rates: https://trac.ffmpeg.org/wiki/Slideshow#Framerates
- """
- def _args(self):
- # Returns the command line parameters for subprocess to use
- # ffmpeg to create a movie using a pipe.
- args = [self.bin_path(), '-f', 'rawvideo', '-vcodec', 'rawvideo',
- '-s', '%dx%d' % self.frame_size, '-pix_fmt', self.frame_format,
- '-framerate', str(self.fps)]
- # Logging is quieted because subprocess.PIPE has limited buffer size.
- # If you have a lot of frames in your animation and set logging to
- # DEBUG, you will have a buffer overrun.
- if _log.getEffectiveLevel() > logging.DEBUG:
- args += ['-loglevel', 'error']
- args += ['-i', 'pipe:'] + self.output_args
- return args
-
-
-# Combine FFMpeg options with temp file-based writing
-@writers.register('ffmpeg_file')
-class FFMpegFileWriter(FFMpegBase, FileMovieWriter):
- """
- File-based ffmpeg writer.
-
- Frames are written to temporary files on disk and then stitched together at the end.
-
- This effectively works as a slideshow input to ffmpeg with the fps passed as
- ``-framerate``, so see also `their notes on frame rates`_ for further details.
-
- .. _their notes on frame rates: https://trac.ffmpeg.org/wiki/Slideshow#Framerates
- """
- supported_formats = ['png', 'jpeg', 'tiff', 'raw', 'rgba']
-
- def _args(self):
- # Returns the command line parameters for subprocess to use
- # ffmpeg to create a movie using a collection of temp images
- args = []
- # For raw frames, we need to explicitly tell ffmpeg the metadata.
- if self.frame_format in {'raw', 'rgba'}:
- args += [
- '-f', 'image2', '-vcodec', 'rawvideo',
- '-video_size', '%dx%d' % self.frame_size,
- '-pixel_format', 'rgba',
- ]
- args += ['-framerate', str(self.fps), '-i', self._base_temp_name()]
- if not self._tmpdir:
- args += ['-frames:v', str(self._frame_counter)]
- # Logging is quieted because subprocess.PIPE has limited buffer size.
- # If you have a lot of frames in your animation and set logging to
- # DEBUG, you will have a buffer overrun.
- if _log.getEffectiveLevel() > logging.DEBUG:
- args += ['-loglevel', 'error']
- return [self.bin_path(), *args, *self.output_args]
-
-
-# Base class for animated GIFs with ImageMagick
-class ImageMagickBase:
- """
- Mixin class for ImageMagick output.
-
- This is a base class for the concrete `ImageMagickWriter` and
- `ImageMagickFileWriter` classes, which define an ``input_names`` attribute
- (or property) specifying the input names passed to ImageMagick.
- """
-
- _exec_key = 'animation.convert_path'
- _args_key = 'animation.convert_args'
-
- def _args(self):
- # ImageMagick does not recognize "raw".
- fmt = "rgba" if self.frame_format == "raw" else self.frame_format
- extra_args = (self.extra_args if self.extra_args is not None
- else mpl.rcParams[self._args_key])
- return [
- self.bin_path(),
- "-size", "%ix%i" % self.frame_size,
- "-depth", "8",
- "-delay", str(100 / self.fps),
- "-loop", "0",
- f"{fmt}:{self.input_names}",
- *extra_args,
- self.outfile,
- ]
-
- @classmethod
- def bin_path(cls):
- binpath = super().bin_path()
- if binpath == 'convert':
- binpath = mpl._get_executable_info('magick').executable
- return binpath
-
- @classmethod
- def isAvailable(cls):
- try:
- return super().isAvailable()
- except mpl.ExecutableNotFoundError as _enf:
- # May be raised by get_executable_info.
- _log.debug('ImageMagick unavailable due to: %s', _enf)
- return False
-
-
-# Combine ImageMagick options with pipe-based writing
-@writers.register('imagemagick')
-class ImageMagickWriter(ImageMagickBase, MovieWriter):
- """
- Pipe-based animated gif writer.
-
- Frames are streamed directly to ImageMagick via a pipe and written
- in a single pass.
- """
-
- input_names = "-" # stdin
-
-
-# Combine ImageMagick options with temp file-based writing
-@writers.register('imagemagick_file')
-class ImageMagickFileWriter(ImageMagickBase, FileMovieWriter):
- """
- File-based animated gif writer.
-
- Frames are written to temporary files on disk and then stitched
- together at the end.
- """
-
- supported_formats = ['png', 'jpeg', 'tiff', 'raw', 'rgba']
- input_names = property(
- lambda self: f'{self.temp_prefix}*.{self.frame_format}')
-
-
-# Taken directly from jakevdp's JSAnimation package at
-# http://github.com/jakevdp/JSAnimation
-def _included_frames(frame_count, frame_format, frame_dir):
- return INCLUDED_FRAMES.format(Nframes=frame_count,
- frame_dir=frame_dir,
- frame_format=frame_format)
-
-
-def _embedded_frames(frame_list, frame_format):
- """frame_list should be a list of base64-encoded png files"""
- if frame_format == 'svg':
- # Fix MIME type for svg
- frame_format = 'svg+xml'
- template = ' frames[{0}] = "data:image/{1};base64,{2}"\n'
- return "\n" + "".join(
- template.format(i, frame_format, frame_data.replace('\n', '\\\n'))
- for i, frame_data in enumerate(frame_list))
-
-
-@writers.register('html')
-class HTMLWriter(FileMovieWriter):
- """Writer for JavaScript-based HTML movies."""
-
- supported_formats = ['png', 'jpeg', 'tiff', 'svg']
-
- @classmethod
- def isAvailable(cls):
- return True
-
- def __init__(self, fps=30, codec=None, bitrate=None, extra_args=None,
- metadata=None, embed_frames=False, default_mode='loop',
- embed_limit=None):
-
- if extra_args:
- _log.warning("HTMLWriter ignores 'extra_args'")
- extra_args = () # Don't lookup nonexistent rcParam[args_key].
- self.embed_frames = embed_frames
- self.default_mode = default_mode.lower()
- _api.check_in_list(['loop', 'once', 'reflect'],
- default_mode=self.default_mode)
-
- # Save embed limit, which is given in MB
- self._bytes_limit = mpl._val_or_rc(embed_limit, 'animation.embed_limit')
- # Convert from MB to bytes
- self._bytes_limit *= 1024 * 1024
-
- super().__init__(fps, codec, bitrate, extra_args, metadata)
-
- def setup(self, fig, outfile, dpi=None, frame_dir=None):
- outfile = Path(outfile)
- _api.check_in_list(['.html', '.htm'], outfile_extension=outfile.suffix)
-
- self._saved_frames = []
- self._total_bytes = 0
- self._hit_limit = False
-
- if not self.embed_frames:
- if frame_dir is None:
- frame_dir = outfile.with_name(outfile.stem + '_frames')
- frame_dir.mkdir(parents=True, exist_ok=True)
- frame_prefix = frame_dir / 'frame'
- else:
- frame_prefix = None
-
- super().setup(fig, outfile, dpi, frame_prefix)
- self._clear_temp = False
-
- def grab_frame(self, **savefig_kwargs):
- _validate_grabframe_kwargs(savefig_kwargs)
- if self.embed_frames:
- # Just stop processing if we hit the limit
- if self._hit_limit:
- return
- f = BytesIO()
- self.fig.savefig(f, format=self.frame_format,
- dpi=self.dpi, **savefig_kwargs)
- imgdata64 = base64.encodebytes(f.getvalue()).decode('ascii')
- self._total_bytes += len(imgdata64)
- if self._total_bytes >= self._bytes_limit:
- _log.warning(
- "Animation size has reached %s bytes, exceeding the limit "
- "of %s. If you're sure you want a larger animation "
- "embedded, set the animation.embed_limit rc parameter to "
- "a larger value (in MB). This and further frames will be "
- "dropped.", self._total_bytes, self._bytes_limit)
- self._hit_limit = True
- else:
- self._saved_frames.append(imgdata64)
- else:
- return super().grab_frame(**savefig_kwargs)
-
- def finish(self):
- # save the frames to an html file
- if self.embed_frames:
- fill_frames = _embedded_frames(self._saved_frames,
- self.frame_format)
- frame_count = len(self._saved_frames)
- else:
- # temp names is filled by FileMovieWriter
- frame_count = len(self._temp_paths)
- fill_frames = _included_frames(
- frame_count, self.frame_format,
- self._temp_paths[0].parent.relative_to(self.outfile.parent))
- mode_dict = dict(once_checked='',
- loop_checked='',
- reflect_checked='')
- mode_dict[self.default_mode + '_checked'] = 'checked'
-
- interval = 1000 // self.fps
-
- with open(self.outfile, 'w') as of:
- of.write(JS_INCLUDE + STYLE_INCLUDE)
- of.write(DISPLAY_TEMPLATE.format(id=uuid.uuid4().hex,
- Nframes=frame_count,
- fill_frames=fill_frames,
- interval=interval,
- **mode_dict))
-
- # Duplicate the temporary file clean up logic from
- # FileMovieWriter.finish. We cannot call the inherited version of
- # finish because it assumes that there is a subprocess that we either
- # need to call to merge many frames together or that there is a
- # subprocess call that we need to clean up.
- if self._tmpdir:
- _log.debug('MovieWriter: clearing temporary path=%s', self._tmpdir)
- self._tmpdir.cleanup()
-
-
-class Animation:
- """
- A base class for Animations.
-
- This class is not usable as is, and should be subclassed to provide needed
- behavior.
-
- .. note::
-
- You must store the created Animation in a variable that lives as long
- as the animation should run. Otherwise, the Animation object will be
- garbage-collected and the animation stops.
-
- Parameters
- ----------
- fig : `~matplotlib.figure.Figure`
- The figure object used to get needed events, such as draw or resize.
-
- event_source : object, optional
- A class that can run a callback when desired events
- are generated, as well as be stopped and started.
-
- Examples include timers (see `TimedAnimation`) and file
- system notifications.
-
- blit : bool, default: False
- Whether blitting is used to optimize drawing. If the backend does not
- support blitting, then this parameter has no effect.
-
- See Also
- --------
- FuncAnimation, ArtistAnimation
- """
-
- def __init__(self, fig, event_source=None, blit=False):
- self._draw_was_started = False
-
- self._fig = fig
- # Disables blitting for backends that don't support it. This
- # allows users to request it if available, but still have a
- # fallback that works if it is not.
- self._blit = blit and fig.canvas.supports_blit
-
- # These are the basics of the animation. The frame sequence represents
- # information for each frame of the animation and depends on how the
- # drawing is handled by the subclasses. The event source fires events
- # that cause the frame sequence to be iterated.
- self.frame_seq = self.new_frame_seq()
- self.event_source = event_source
-
- # Instead of starting the event source now, we connect to the figure's
- # draw_event, so that we only start once the figure has been drawn.
- self._first_draw_id = fig.canvas.mpl_connect('draw_event', self._start)
-
- # Connect to the figure's close_event so that we don't continue to
- # fire events and try to draw to a deleted figure.
- self._close_id = self._fig.canvas.mpl_connect('close_event',
- self._stop)
- if self._blit:
- self._setup_blit()
-
- def __del__(self):
- if not getattr(self, '_draw_was_started', True):
- warnings.warn(
- 'Animation was deleted without rendering anything. This is '
- 'most likely not intended. To prevent deletion, assign the '
- 'Animation to a variable, e.g. `anim`, that exists until you '
- 'output the Animation using `plt.show()` or '
- '`anim.save()`.'
- )
-
- def _start(self, *args):
- """
- Starts interactive animation. Adds the draw frame command to the GUI
- handler, calls show to start the event loop.
- """
- # Do not start the event source if saving() it.
- if self._fig.canvas.is_saving():
- return
- # First disconnect our draw event handler
- self._fig.canvas.mpl_disconnect(self._first_draw_id)
-
- # Now do any initial draw
- self._init_draw()
-
- # Add our callback for stepping the animation and
- # actually start the event_source.
- self.event_source.add_callback(self._step)
- self.event_source.start()
-
- def _stop(self, *args):
- # On stop we disconnect all of our events.
- if self._blit:
- self._fig.canvas.mpl_disconnect(self._resize_id)
- self._fig.canvas.mpl_disconnect(self._close_id)
- self.event_source.remove_callback(self._step)
- self.event_source = None
-
- def save(self, filename, writer=None, fps=None, dpi=None, codec=None,
- bitrate=None, extra_args=None, metadata=None, extra_anim=None,
- savefig_kwargs=None, *, progress_callback=None):
- """
- Save the animation as a movie file by drawing every frame.
-
- Parameters
- ----------
- filename : str
- The output filename, e.g., :file:`mymovie.mp4`.
-
- writer : `MovieWriter` or str, default: :rc:`animation.writer`
- A `MovieWriter` instance to use or a key that identifies a
- class to use, such as 'ffmpeg'.
-
- fps : int, optional
- Movie frame rate (per second). If not set, the frame rate from the
- animation's frame interval.
-
- dpi : float, default: :rc:`savefig.dpi`
- Controls the dots per inch for the movie frames. Together with
- the figure's size in inches, this controls the size of the movie.
-
- codec : str, default: :rc:`animation.codec`.
- The video codec to use. Not all codecs are supported by a given
- `MovieWriter`.
-
- bitrate : int, default: :rc:`animation.bitrate`
- The bitrate of the movie, in kilobits per second. Higher values
- means higher quality movies, but increase the file size. A value
- of -1 lets the underlying movie encoder select the bitrate.
-
- extra_args : list of str or None, optional
- Extra command-line arguments passed to the underlying movie encoder. These
- arguments are passed last to the encoder, just before the output filename.
- The default, None, means to use :rc:`animation.[name-of-encoder]_args` for
- the builtin writers.
-
- metadata : dict[str, str], default: {}
- Dictionary of keys and values for metadata to include in
- the output file. Some keys that may be of use include:
- title, artist, genre, subject, copyright, srcform, comment.
-
- extra_anim : list, default: []
- Additional `Animation` objects that should be included
- in the saved movie file. These need to be from the same
- `.Figure` instance. Also, animation frames will
- just be simply combined, so there should be a 1:1 correspondence
- between the frames from the different animations.
-
- savefig_kwargs : dict, default: {}
- Keyword arguments passed to each `~.Figure.savefig` call used to
- save the individual frames.
-
- progress_callback : function, optional
- A callback function that will be called for every frame to notify
- the saving progress. It must have the signature ::
-
- def func(current_frame: int, total_frames: int) -> Any
-
- where *current_frame* is the current frame number and *total_frames* is the
- total number of frames to be saved. *total_frames* is set to None, if the
- total number of frames cannot be determined. Return values may exist but are
- ignored.
-
- Example code to write the progress to stdout::
-
- progress_callback = lambda i, n: print(f'Saving frame {i}/{n}')
-
- Notes
- -----
- *fps*, *codec*, *bitrate*, *extra_args* and *metadata* are used to
- construct a `.MovieWriter` instance and can only be passed if
- *writer* is a string. If they are passed as non-*None* and *writer*
- is a `.MovieWriter`, a `RuntimeError` will be raised.
- """
-
- all_anim = [self]
- if extra_anim is not None:
- all_anim.extend(anim for anim in extra_anim
- if anim._fig is self._fig)
-
- # Disable "Animation was deleted without rendering" warning.
- for anim in all_anim:
- anim._draw_was_started = True
-
- if writer is None:
- writer = mpl.rcParams['animation.writer']
- elif (not isinstance(writer, str) and
- any(arg is not None
- for arg in (fps, codec, bitrate, extra_args, metadata))):
- raise RuntimeError('Passing in values for arguments '
- 'fps, codec, bitrate, extra_args, or metadata '
- 'is not supported when writer is an existing '
- 'MovieWriter instance. These should instead be '
- 'passed as arguments when creating the '
- 'MovieWriter instance.')
-
- if savefig_kwargs is None:
- savefig_kwargs = {}
- else:
- # we are going to mutate this below
- savefig_kwargs = dict(savefig_kwargs)
-
- if fps is None and hasattr(self, '_interval'):
- # Convert interval in ms to frames per second
- fps = 1000. / self._interval
-
- # Re-use the savefig DPI for ours if none is given
- dpi = mpl._val_or_rc(dpi, 'savefig.dpi')
- if dpi == 'figure':
- dpi = self._fig.dpi
-
- writer_kwargs = {}
- if codec is not None:
- writer_kwargs['codec'] = codec
- if bitrate is not None:
- writer_kwargs['bitrate'] = bitrate
- if extra_args is not None:
- writer_kwargs['extra_args'] = extra_args
- if metadata is not None:
- writer_kwargs['metadata'] = metadata
-
- # If we have the name of a writer, instantiate an instance of the
- # registered class.
- if isinstance(writer, str):
- try:
- writer_cls = writers[writer]
- except RuntimeError: # Raised if not available.
- writer_cls = PillowWriter # Always available.
- _log.warning("MovieWriter %s unavailable; using Pillow "
- "instead.", writer)
- writer = writer_cls(fps, **writer_kwargs)
- _log.info('Animation.save using %s', type(writer))
-
- if 'bbox_inches' in savefig_kwargs:
- _log.warning("Warning: discarding the 'bbox_inches' argument in "
- "'savefig_kwargs' as it may cause frame size "
- "to vary, which is inappropriate for animation.")
- savefig_kwargs.pop('bbox_inches')
-
- # Create a new sequence of frames for saved data. This is different
- # from new_frame_seq() to give the ability to save 'live' generated
- # frame information to be saved later.
- # TODO: Right now, after closing the figure, saving a movie won't work
- # since GUI widgets are gone. Either need to remove extra code to
- # allow for this non-existent use case or find a way to make it work.
-
- facecolor = savefig_kwargs.get('facecolor',
- mpl.rcParams['savefig.facecolor'])
- if facecolor == 'auto':
- facecolor = self._fig.get_facecolor()
-
- def _pre_composite_to_white(color):
- r, g, b, a = mcolors.to_rgba(color)
- return a * np.array([r, g, b]) + 1 - a
-
- savefig_kwargs['facecolor'] = _pre_composite_to_white(facecolor)
- savefig_kwargs['transparent'] = False # just to be safe!
- # canvas._is_saving = True makes the draw_event animation-starting
- # callback a no-op; canvas.manager = None prevents resizing the GUI
- # widget (both are likewise done in savefig()).
- with writer.saving(self._fig, filename, dpi), \
- cbook._setattr_cm(self._fig.canvas, _is_saving=True, manager=None):
- for anim in all_anim:
- anim._init_draw() # Clear the initial frame
- frame_number = 0
- # TODO: Currently only FuncAnimation has a save_count
- # attribute. Can we generalize this to all Animations?
- save_count_list = [getattr(a, '_save_count', None)
- for a in all_anim]
- if None in save_count_list:
- total_frames = None
- else:
- total_frames = sum(save_count_list)
- for data in zip(*[a.new_saved_frame_seq() for a in all_anim]):
- for anim, d in zip(all_anim, data):
- # TODO: See if turning off blit is really necessary
- anim._draw_next_frame(d, blit=False)
- if progress_callback is not None:
- progress_callback(frame_number, total_frames)
- frame_number += 1
- writer.grab_frame(**savefig_kwargs)
-
- def _step(self, *args):
- """
- Handler for getting events. By default, gets the next frame in the
- sequence and hands the data off to be drawn.
- """
- # Returns True to indicate that the event source should continue to
- # call _step, until the frame sequence reaches the end of iteration,
- # at which point False will be returned.
- try:
- framedata = next(self.frame_seq)
- self._draw_next_frame(framedata, self._blit)
- return True
- except StopIteration:
- return False
-
- def new_frame_seq(self):
- """Return a new sequence of frame information."""
- # Default implementation is just an iterator over self._framedata
- return iter(self._framedata)
-
- def new_saved_frame_seq(self):
- """Return a new sequence of saved/cached frame information."""
- # Default is the same as the regular frame sequence
- return self.new_frame_seq()
-
- def _draw_next_frame(self, framedata, blit):
- # Breaks down the drawing of the next frame into steps of pre- and
- # post- draw, as well as the drawing of the frame itself.
- self._pre_draw(framedata, blit)
- self._draw_frame(framedata)
- self._post_draw(framedata, blit)
-
- def _init_draw(self):
- # Initial draw to clear the frame. Also used by the blitting code
- # when a clean base is required.
- self._draw_was_started = True
-
- def _pre_draw(self, framedata, blit):
- # Perform any cleaning or whatnot before the drawing of the frame.
- # This default implementation allows blit to clear the frame.
- if blit:
- self._blit_clear(self._drawn_artists)
-
- def _draw_frame(self, framedata):
- # Performs actual drawing of the frame.
- raise NotImplementedError('Needs to be implemented by subclasses to'
- ' actually make an animation.')
-
- def _post_draw(self, framedata, blit):
- # After the frame is rendered, this handles the actual flushing of
- # the draw, which can be a direct draw_idle() or make use of the
- # blitting.
- if blit and self._drawn_artists:
- self._blit_draw(self._drawn_artists)
- else:
- self._fig.canvas.draw_idle()
-
- # The rest of the code in this class is to facilitate easy blitting
- def _blit_draw(self, artists):
- # Handles blitted drawing, which renders only the artists given instead
- # of the entire figure.
- updated_ax = {a.axes for a in artists}
- # Enumerate artists to cache Axes backgrounds. We do not draw
- # artists yet to not cache foreground from plots with shared axes
- for ax in updated_ax:
- # If we haven't cached the background for the current view of this
- # Axes object, do so now. This might not always be reliable, but
- # it's an attempt to automate the process.
- cur_view = ax._get_view()
- view, bg = self._blit_cache.get(ax, (object(), None))
- if cur_view != view:
- self._blit_cache[ax] = (
- cur_view, ax.figure.canvas.copy_from_bbox(ax.bbox))
- # Make a separate pass to draw foreground.
- for a in artists:
- a.axes.draw_artist(a)
- # After rendering all the needed artists, blit each Axes individually.
- for ax in updated_ax:
- ax.figure.canvas.blit(ax.bbox)
-
- def _blit_clear(self, artists):
- # Get a list of the Axes that need clearing from the artists that
- # have been drawn. Grab the appropriate saved background from the
- # cache and restore.
- axes = {a.axes for a in artists}
- for ax in axes:
- try:
- view, bg = self._blit_cache[ax]
- except KeyError:
- continue
- if ax._get_view() == view:
- ax.figure.canvas.restore_region(bg)
- else:
- self._blit_cache.pop(ax)
-
- def _setup_blit(self):
- # Setting up the blit requires: a cache of the background for the Axes
- self._blit_cache = dict()
- self._drawn_artists = []
- # _post_draw needs to be called first to initialize the renderer
- self._post_draw(None, self._blit)
- # Then we need to clear the Frame for the initial draw
- # This is typically handled in _on_resize because QT and Tk
- # emit a resize event on launch, but the macosx backend does not,
- # thus we force it here for everyone for consistency
- self._init_draw()
- # Connect to future resize events
- self._resize_id = self._fig.canvas.mpl_connect('resize_event',
- self._on_resize)
-
- def _on_resize(self, event):
- # On resize, we need to disable the resize event handling so we don't
- # get too many events. Also stop the animation events, so that
- # we're paused. Reset the cache and re-init. Set up an event handler
- # to catch once the draw has actually taken place.
- self._fig.canvas.mpl_disconnect(self._resize_id)
- self.event_source.stop()
- self._blit_cache.clear()
- self._init_draw()
- self._resize_id = self._fig.canvas.mpl_connect('draw_event',
- self._end_redraw)
-
- def _end_redraw(self, event):
- # Now that the redraw has happened, do the post draw flushing and
- # blit handling. Then re-enable all of the original events.
- self._post_draw(None, False)
- self.event_source.start()
- self._fig.canvas.mpl_disconnect(self._resize_id)
- self._resize_id = self._fig.canvas.mpl_connect('resize_event',
- self._on_resize)
-
- def to_html5_video(self, embed_limit=None):
- """
- Convert the animation to an HTML5 ``<video>`` tag.
-
- This saves the animation as an h264 video, encoded in base64
- directly into the HTML5 video tag. This respects :rc:`animation.writer`
- and :rc:`animation.bitrate`. This also makes use of the
- *interval* to control the speed, and uses the *repeat*
- parameter to decide whether to loop.
-
- Parameters
- ----------
- embed_limit : float, optional
- Limit, in MB, of the returned animation. No animation is created
- if the limit is exceeded.
- Defaults to :rc:`animation.embed_limit` = 20.0.
-
- Returns
- -------
- str
- An HTML5 video tag with the animation embedded as base64 encoded
- h264 video.
- If the *embed_limit* is exceeded, this returns the string
- "Video too large to embed."
- """
- VIDEO_TAG = r'''<video {size} {options}>
- <source type="video/mp4" src="data:video/mp4;base64,{video}">
- Your browser does not support the video tag.
-</video>'''
- # Cache the rendering of the video as HTML
- if not hasattr(self, '_base64_video'):
- # Save embed limit, which is given in MB
- embed_limit = mpl._val_or_rc(embed_limit, 'animation.embed_limit')
-
- # Convert from MB to bytes
- embed_limit *= 1024 * 1024
-
- # Can't open a NamedTemporaryFile twice on Windows, so use a
- # TemporaryDirectory instead.
- with TemporaryDirectory() as tmpdir:
- path = Path(tmpdir, "temp.m4v")
- # We create a writer manually so that we can get the
- # appropriate size for the tag
- Writer = writers[mpl.rcParams['animation.writer']]
- writer = Writer(codec='h264',
- bitrate=mpl.rcParams['animation.bitrate'],
- fps=1000. / self._interval)
- self.save(str(path), writer=writer)
- # Now open and base64 encode.
- vid64 = base64.encodebytes(path.read_bytes())
-
- vid_len = len(vid64)
- if vid_len >= embed_limit:
- _log.warning(
- "Animation movie is %s bytes, exceeding the limit of %s. "
- "If you're sure you want a large animation embedded, set "
- "the animation.embed_limit rc parameter to a larger value "
- "(in MB).", vid_len, embed_limit)
- else:
- self._base64_video = vid64.decode('ascii')
- self._video_size = 'width="{}" height="{}"'.format(
- *writer.frame_size)
-
- # If we exceeded the size, this attribute won't exist
- if hasattr(self, '_base64_video'):
- # Default HTML5 options are to autoplay and display video controls
- options = ['controls', 'autoplay']
-
- # If we're set to repeat, make it loop
- if getattr(self, '_repeat', False):
- options.append('loop')
-
- return VIDEO_TAG.format(video=self._base64_video,
- size=self._video_size,
- options=' '.join(options))
- else:
- return 'Video too large to embed.'
-
- def to_jshtml(self, fps=None, embed_frames=True, default_mode=None):
- """
- Generate HTML representation of the animation.
-
- Parameters
- ----------
- fps : int, optional
- Movie frame rate (per second). If not set, the frame rate from
- the animation's frame interval.
- embed_frames : bool, optional
- default_mode : str, optional
- What to do when the animation ends. Must be one of ``{'loop',
- 'once', 'reflect'}``. Defaults to ``'loop'`` if the *repeat*
- parameter is True, otherwise ``'once'``.
- """
- if fps is None and hasattr(self, '_interval'):
- # Convert interval in ms to frames per second
- fps = 1000 / self._interval
-
- # If we're not given a default mode, choose one base on the value of
- # the _repeat attribute
- if default_mode is None:
- default_mode = 'loop' if getattr(self, '_repeat',
- False) else 'once'
-
- if not hasattr(self, "_html_representation"):
- # Can't open a NamedTemporaryFile twice on Windows, so use a
- # TemporaryDirectory instead.
- with TemporaryDirectory() as tmpdir:
- path = Path(tmpdir, "temp.html")
- writer = HTMLWriter(fps=fps,
- embed_frames=embed_frames,
- default_mode=default_mode)
- self.save(str(path), writer=writer)
- self._html_representation = path.read_text()
-
- return self._html_representation
-
- def _repr_html_(self):
- """IPython display hook for rendering."""
- fmt = mpl.rcParams['animation.html']
- if fmt == 'html5':
- return self.to_html5_video()
- elif fmt == 'jshtml':
- return self.to_jshtml()
-
- def pause(self):
- """Pause the animation."""
- self.event_source.stop()
- if self._blit:
- for artist in self._drawn_artists:
- artist.set_animated(False)
-
- def resume(self):
- """Resume the animation."""
- self.event_source.start()
- if self._blit:
- for artist in self._drawn_artists:
- artist.set_animated(True)
-
-
-class TimedAnimation(Animation):
- """
- `Animation` subclass for time-based animation.
-
- A new frame is drawn every *interval* milliseconds.
-
- .. note::
-
- You must store the created Animation in a variable that lives as long
- as the animation should run. Otherwise, the Animation object will be
- garbage-collected and the animation stops.
-
- Parameters
- ----------
- fig : `~matplotlib.figure.Figure`
- The figure object used to get needed events, such as draw or resize.
- interval : int, default: 200
- Delay between frames in milliseconds.
- repeat_delay : int, default: 0
- The delay in milliseconds between consecutive animation runs, if
- *repeat* is True.
- repeat : bool, default: True
- Whether the animation repeats when the sequence of frames is completed.
- blit : bool, default: False
- Whether blitting is used to optimize drawing.
- """
- def __init__(self, fig, interval=200, repeat_delay=0, repeat=True,
- event_source=None, *args, **kwargs):
- self._interval = interval
- # Undocumented support for repeat_delay = None as backcompat.
- self._repeat_delay = repeat_delay if repeat_delay is not None else 0
- self._repeat = repeat
- # If we're not given an event source, create a new timer. This permits
- # sharing timers between animation objects for syncing animations.
- if event_source is None:
- event_source = fig.canvas.new_timer(interval=self._interval)
- super().__init__(fig, event_source=event_source, *args, **kwargs)
-
- def _step(self, *args):
- """Handler for getting events."""
- # Extends the _step() method for the Animation class. If
- # Animation._step signals that it reached the end and we want to
- # repeat, we refresh the frame sequence and return True. If
- # _repeat_delay is set, change the event_source's interval to our loop
- # delay and set the callback to one which will then set the interval
- # back.
- still_going = super()._step(*args)
- if not still_going:
- if self._repeat:
- # Restart the draw loop
- self._init_draw()
- self.frame_seq = self.new_frame_seq()
- self.event_source.interval = self._repeat_delay
- return True
- else:
- # We are done with the animation. Call pause to remove
- # animated flags from artists that were using blitting
- self.pause()
- if self._blit:
- # Remove the resize callback if we were blitting
- self._fig.canvas.mpl_disconnect(self._resize_id)
- self._fig.canvas.mpl_disconnect(self._close_id)
- self.event_source = None
- return False
-
- self.event_source.interval = self._interval
- return True
-
- repeat = _api.deprecate_privatize_attribute("3.7")
-
-
-class ArtistAnimation(TimedAnimation):
- """
- `TimedAnimation` subclass that creates an animation by using a fixed
- set of `.Artist` objects.
-
- Before creating an instance, all plotting should have taken place
- and the relevant artists saved.
-
- .. note::
-
- You must store the created Animation in a variable that lives as long
- as the animation should run. Otherwise, the Animation object will be
- garbage-collected and the animation stops.
-
- Parameters
- ----------
- fig : `~matplotlib.figure.Figure`
- The figure object used to get needed events, such as draw or resize.
- artists : list
- Each list entry is a collection of `.Artist` objects that are made
- visible on the corresponding frame. Other artists are made invisible.
- interval : int, default: 200
- Delay between frames in milliseconds.
- repeat_delay : int, default: 0
- The delay in milliseconds between consecutive animation runs, if
- *repeat* is True.
- repeat : bool, default: True
- Whether the animation repeats when the sequence of frames is completed.
- blit : bool, default: False
- Whether blitting is used to optimize drawing.
- """
-
- def __init__(self, fig, artists, *args, **kwargs):
- # Internal list of artists drawn in the most recent frame.
- self._drawn_artists = []
-
- # Use the list of artists as the framedata, which will be iterated
- # over by the machinery.
- self._framedata = artists
- super().__init__(fig, *args, **kwargs)
-
- def _init_draw(self):
- super()._init_draw()
- # Make all the artists involved in *any* frame invisible
- figs = set()
- for f in self.new_frame_seq():
- for artist in f:
- artist.set_visible(False)
- artist.set_animated(self._blit)
- # Assemble a list of unique figures that need flushing
- if artist.get_figure() not in figs:
- figs.add(artist.get_figure())
-
- # Flush the needed figures
- for fig in figs:
- fig.canvas.draw_idle()
-
- def _pre_draw(self, framedata, blit):
- """Clears artists from the last frame."""
- if blit:
- # Let blit handle clearing
- self._blit_clear(self._drawn_artists)
- else:
- # Otherwise, make all the artists from the previous frame invisible
- for artist in self._drawn_artists:
- artist.set_visible(False)
-
- def _draw_frame(self, artists):
- # Save the artists that were passed in as framedata for the other
- # steps (esp. blitting) to use.
- self._drawn_artists = artists
-
- # Make all the artists from the current frame visible
- for artist in artists:
- artist.set_visible(True)
-
-
-class FuncAnimation(TimedAnimation):
- """
- `TimedAnimation` subclass that makes an animation by repeatedly calling
- a function *func*.
-
- .. note::
-
- You must store the created Animation in a variable that lives as long
- as the animation should run. Otherwise, the Animation object will be
- garbage-collected and the animation stops.
-
- Parameters
- ----------
- fig : `~matplotlib.figure.Figure`
- The figure object used to get needed events, such as draw or resize.
-
- func : callable
- The function to call at each frame. The first argument will
- be the next value in *frames*. Any additional positional
- arguments can be supplied using `functools.partial` or via the *fargs*
- parameter.
-
- The required signature is::
-
- def func(frame, *fargs) -> iterable_of_artists
-
- It is often more convenient to provide the arguments using
- `functools.partial`. In this way it is also possible to pass keyword
- arguments. To pass a function with both positional and keyword
- arguments, set all arguments as keyword arguments, just leaving the
- *frame* argument unset::
-
- def func(frame, art, *, y=None):
- ...
-
- ani = FuncAnimation(fig, partial(func, art=ln, y='foo'))
-
- If ``blit == True``, *func* must return an iterable of all artists
- that were modified or created. This information is used by the blitting
- algorithm to determine which parts of the figure have to be updated.
- The return value is unused if ``blit == False`` and may be omitted in
- that case.
-
- frames : iterable, int, generator function, or None, optional
- Source of data to pass *func* and each frame of the animation
-
- - If an iterable, then simply use the values provided. If the
- iterable has a length, it will override the *save_count* kwarg.
-
- - If an integer, then equivalent to passing ``range(frames)``
-
- - If a generator function, then must have the signature::
-
- def gen_function() -> obj
-
- - If *None*, then equivalent to passing ``itertools.count``.
-
- In all of these cases, the values in *frames* is simply passed through
- to the user-supplied *func* and thus can be of any type.
-
- init_func : callable, optional
- A function used to draw a clear frame. If not given, the results of
- drawing from the first item in the frames sequence will be used. This
- function will be called once before the first frame.
-
- The required signature is::
-
- def init_func() -> iterable_of_artists
-
- If ``blit == True``, *init_func* must return an iterable of artists
- to be re-drawn. This information is used by the blitting algorithm to
- determine which parts of the figure have to be updated. The return
- value is unused if ``blit == False`` and may be omitted in that case.
-
- fargs : tuple or None, optional
- Additional arguments to pass to each call to *func*. Note: the use of
- `functools.partial` is preferred over *fargs*. See *func* for details.
-
- save_count : int, optional
- Fallback for the number of values from *frames* to cache. This is
- only used if the number of frames cannot be inferred from *frames*,
- i.e. when it's an iterator without length or a generator.
-
- interval : int, default: 200
- Delay between frames in milliseconds.
-
- repeat_delay : int, default: 0
- The delay in milliseconds between consecutive animation runs, if
- *repeat* is True.
-
- repeat : bool, default: True
- Whether the animation repeats when the sequence of frames is completed.
-
- blit : bool, default: False
- Whether blitting is used to optimize drawing. Note: when using
- blitting, any animated artists will be drawn according to their zorder;
- however, they will be drawn on top of any previous artists, regardless
- of their zorder.
-
- cache_frame_data : bool, default: True
- Whether frame data is cached. Disabling cache might be helpful when
- frames contain large objects.
- """
- def __init__(self, fig, func, frames=None, init_func=None, fargs=None,
- save_count=None, *, cache_frame_data=True, **kwargs):
- if fargs:
- self._args = fargs
- else:
- self._args = ()
- self._func = func
- self._init_func = init_func
-
- # Amount of framedata to keep around for saving movies. This is only
- # used if we don't know how many frames there will be: in the case
- # of no generator or in the case of a callable.
- self._save_count = save_count
- # Set up a function that creates a new iterable when needed. If nothing
- # is passed in for frames, just use itertools.count, which will just
- # keep counting from 0. A callable passed in for frames is assumed to
- # be a generator. An iterable will be used as is, and anything else
- # will be treated as a number of frames.
- if frames is None:
- self._iter_gen = itertools.count
- elif callable(frames):
- self._iter_gen = frames
- elif np.iterable(frames):
- if kwargs.get('repeat', True):
- self._tee_from = frames
- def iter_frames(frames=frames):
- this, self._tee_from = itertools.tee(self._tee_from, 2)
- yield from this
- self._iter_gen = iter_frames
- else:
- self._iter_gen = lambda: iter(frames)
- if hasattr(frames, '__len__'):
- self._save_count = len(frames)
- if save_count is not None:
- _api.warn_external(
- f"You passed in an explicit {save_count=} "
- "which is being ignored in favor of "
- f"{len(frames)=}."
- )
- else:
- self._iter_gen = lambda: iter(range(frames))
- self._save_count = frames
- if save_count is not None:
- _api.warn_external(
- f"You passed in an explicit {save_count=} which is being "
- f"ignored in favor of {frames=}."
- )
- if self._save_count is None and cache_frame_data:
- _api.warn_external(
- f"{frames=!r} which we can infer the length of, "
- "did not pass an explicit *save_count* "
- f"and passed {cache_frame_data=}. To avoid a possibly "
- "unbounded cache, frame data caching has been disabled. "
- "To suppress this warning either pass "
- "`cache_frame_data=False` or `save_count=MAX_FRAMES`."
- )
- cache_frame_data = False
-
- self._cache_frame_data = cache_frame_data
-
- # Needs to be initialized so the draw functions work without checking
- self._save_seq = []
-
- super().__init__(fig, **kwargs)
-
- # Need to reset the saved seq, since right now it will contain data
- # for a single frame from init, which is not what we want.
- self._save_seq = []
-
- def new_frame_seq(self):
- # Use the generating function to generate a new frame sequence
- return self._iter_gen()
-
- def new_saved_frame_seq(self):
- # Generate an iterator for the sequence of saved data. If there are
- # no saved frames, generate a new frame sequence and take the first
- # save_count entries in it.
- if self._save_seq:
- # While iterating we are going to update _save_seq
- # so make a copy to safely iterate over
- self._old_saved_seq = list(self._save_seq)
- return iter(self._old_saved_seq)
- else:
- if self._save_count is None:
- frame_seq = self.new_frame_seq()
-
- def gen():
- try:
- while True:
- yield next(frame_seq)
- except StopIteration:
- pass
- return gen()
- else:
- return itertools.islice(self.new_frame_seq(), self._save_count)
-
- def _init_draw(self):
- super()._init_draw()
- # Initialize the drawing either using the given init_func or by
- # calling the draw function with the first item of the frame sequence.
- # For blitting, the init_func should return a sequence of modified
- # artists.
- if self._init_func is None:
- try:
- frame_data = next(self.new_frame_seq())
- except StopIteration:
- # we can't start the iteration, it may have already been
- # exhausted by a previous save or just be 0 length.
- # warn and bail.
- warnings.warn(
- "Can not start iterating the frames for the initial draw. "
- "This can be caused by passing in a 0 length sequence "
- "for *frames*.\n\n"
- "If you passed *frames* as a generator "
- "it may be exhausted due to a previous display or save."
- )
- return
- self._draw_frame(frame_data)
- else:
- self._drawn_artists = self._init_func()
- if self._blit:
- if self._drawn_artists is None:
- raise RuntimeError('The init_func must return a '
- 'sequence of Artist objects.')
- for a in self._drawn_artists:
- a.set_animated(self._blit)
- self._save_seq = []
-
- def _draw_frame(self, framedata):
- if self._cache_frame_data:
- # Save the data for potential saving of movies.
- self._save_seq.append(framedata)
- self._save_seq = self._save_seq[-self._save_count:]
-
- # Call the func with framedata and args. If blitting is desired,
- # func needs to return a sequence of any artists that were modified.
- self._drawn_artists = self._func(framedata, *self._args)
-
- if self._blit:
-
- err = RuntimeError('The animation function must return a sequence '
- 'of Artist objects.')
- try:
- # check if a sequence
- iter(self._drawn_artists)
- except TypeError:
- raise err from None
-
- # check each item if it's artist
- for i in self._drawn_artists:
- if not isinstance(i, mpl.artist.Artist):
- raise err
-
- self._drawn_artists = sorted(self._drawn_artists,
- key=lambda x: x.get_zorder())
-
- for a in self._drawn_artists:
- a.set_animated(self._blit)
-
- save_count = _api.deprecate_privatize_attribute("3.7")
-
-
-def _validate_grabframe_kwargs(savefig_kwargs):
- if mpl.rcParams['savefig.bbox'] == 'tight':
- raise ValueError(
- f"{mpl.rcParams['savefig.bbox']=} must not be 'tight' as it "
- "may cause frame size to vary, which is inappropriate for animation."
- )
- for k in ('dpi', 'bbox_inches', 'format'):
- if k in savefig_kwargs:
- raise TypeError(
- f"grab_frame got an unexpected keyword argument {k!r}"
- )
diff --git a/contrib/python/matplotlib/py3/matplotlib/animation.pyi b/contrib/python/matplotlib/py3/matplotlib/animation.pyi
deleted file mode 100644
index de1b9926af..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/animation.pyi
+++ /dev/null
@@ -1,219 +0,0 @@
-import abc
-from collections.abc import Callable, Collection, Iterable, Sequence, Generator
-import contextlib
-from pathlib import Path
-from matplotlib.artist import Artist
-from matplotlib.backend_bases import TimerBase
-from matplotlib.figure import Figure
-
-from typing import Any
-
-subprocess_creation_flags: int
-
-def adjusted_figsize(w: float, h: float, dpi: float, n: int) -> tuple[float, float]: ...
-
-class MovieWriterRegistry:
- def __init__(self) -> None: ...
- def register(
- self, name: str
- ) -> Callable[[type[AbstractMovieWriter]], type[AbstractMovieWriter]]: ...
- def is_available(self, name: str) -> bool: ...
- def __iter__(self) -> Generator[str, None, None]: ...
- def list(self) -> list[str]: ...
- def __getitem__(self, name: str) -> type[AbstractMovieWriter]: ...
-
-writers: MovieWriterRegistry
-
-class AbstractMovieWriter(abc.ABC, metaclass=abc.ABCMeta):
- fps: int
- metadata: dict[str, str]
- codec: str
- bitrate: int
- def __init__(
- self,
- fps: int = ...,
- metadata: dict[str, str] | None = ...,
- codec: str | None = ...,
- bitrate: int | None = ...,
- ) -> None: ...
- outfile: str | Path
- fig: Figure
- dpi: float
-
- @abc.abstractmethod
- def setup(self, fig: Figure, outfile: str | Path, dpi: float | None = ...) -> None: ...
- @property
- def frame_size(self) -> tuple[int, int]: ...
- @abc.abstractmethod
- def grab_frame(self, **savefig_kwargs) -> None: ...
- @abc.abstractmethod
- def finish(self) -> None: ...
- @contextlib.contextmanager
- def saving(
- self, fig: Figure, outfile: str | Path, dpi: float | None, *args, **kwargs
- ) -> Generator[AbstractMovieWriter, None, None]: ...
-
-class MovieWriter(AbstractMovieWriter):
- supported_formats: list[str]
- frame_format: str
- extra_args: list[str] | None
- def __init__(
- self,
- fps: int = ...,
- codec: str | None = ...,
- bitrate: int | None = ...,
- extra_args: list[str] | None = ...,
- metadata: dict[str, str] | None = ...,
- ) -> None: ...
- def setup(self, fig: Figure, outfile: str | Path, dpi: float | None = ...) -> None: ...
- def grab_frame(self, **savefig_kwargs) -> None: ...
- def finish(self) -> None: ...
- @classmethod
- def bin_path(cls) -> str: ...
- @classmethod
- def isAvailable(cls) -> bool: ...
-
-class FileMovieWriter(MovieWriter):
- fig: Figure
- outfile: str | Path
- dpi: float
- temp_prefix: str
- fname_format_str: str
- def setup(
- self,
- fig: Figure,
- outfile: str | Path,
- dpi: float | None = ...,
- frame_prefix: str | Path | None = ...,
- ) -> None: ...
- def __del__(self) -> None: ...
- @property
- def frame_format(self) -> str: ...
- @frame_format.setter
- def frame_format(self, frame_format: str) -> None: ...
-
-class PillowWriter(AbstractMovieWriter):
- @classmethod
- def isAvailable(cls) -> bool: ...
- def setup(
- self, fig: Figure, outfile: str | Path, dpi: float | None = ...
- ) -> None: ...
- def grab_frame(self, **savefig_kwargs) -> None: ...
- def finish(self) -> None: ...
-
-class FFMpegBase:
- codec: str
- @property
- def output_args(self) -> list[str]: ...
-
-class FFMpegWriter(FFMpegBase, MovieWriter): ...
-
-class FFMpegFileWriter(FFMpegBase, FileMovieWriter):
- supported_formats: list[str]
-
-class ImageMagickBase:
- @classmethod
- def bin_path(cls) -> str: ...
- @classmethod
- def isAvailable(cls) -> bool: ...
-
-class ImageMagickWriter(ImageMagickBase, MovieWriter):
- input_names: str
-
-class ImageMagickFileWriter(ImageMagickBase, FileMovieWriter):
- supported_formats: list[str]
- @property
- def input_names(self) -> str: ...
-
-class HTMLWriter(FileMovieWriter):
- supported_formats: list[str]
- @classmethod
- def isAvailable(cls) -> bool: ...
- embed_frames: bool
- default_mode: str
- def __init__(
- self,
- fps: int = ...,
- codec: str | None = ...,
- bitrate: int | None = ...,
- extra_args: list[str] | None = ...,
- metadata: dict[str, str] | None = ...,
- embed_frames: bool = ...,
- default_mode: str = ...,
- embed_limit: float | None = ...,
- ) -> None: ...
- def setup(
- self,
- fig: Figure,
- outfile: str | Path,
- dpi: float | None = ...,
- frame_dir: str | Path | None = ...,
- ) -> None: ...
- def grab_frame(self, **savefig_kwargs): ...
- def finish(self) -> None: ...
-
-class Animation:
- frame_seq: Iterable[Artist]
- event_source: Any
- def __init__(
- self, fig: Figure, event_source: Any | None = ..., blit: bool = ...
- ) -> None: ...
- def __del__(self) -> None: ...
- def save(
- self,
- filename: str | Path,
- writer: AbstractMovieWriter | str | None = ...,
- fps: int | None = ...,
- dpi: float | None = ...,
- codec: str | None = ...,
- bitrate: int | None = ...,
- extra_args: list[str] | None = ...,
- metadata: dict[str, str] | None = ...,
- extra_anim: list[Animation] | None = ...,
- savefig_kwargs: dict[str, Any] | None = ...,
- *,
- progress_callback: Callable[[int, int], Any] | None = ...
- ) -> None: ...
- def new_frame_seq(self) -> Iterable[Artist]: ...
- def new_saved_frame_seq(self) -> Iterable[Artist]: ...
- def to_html5_video(self, embed_limit: float | None = ...) -> str: ...
- def to_jshtml(
- self,
- fps: int | None = ...,
- embed_frames: bool = ...,
- default_mode: str | None = ...,
- ) -> str: ...
- def _repr_html_(self) -> str: ...
- def pause(self) -> None: ...
- def resume(self) -> None: ...
-
-class TimedAnimation(Animation):
- repeat: bool
- def __init__(
- self,
- fig: Figure,
- interval: int = ...,
- repeat_delay: int = ...,
- repeat: bool = ...,
- event_source: TimerBase | None = ...,
- *args,
- **kwargs
- ) -> None: ...
-
-class ArtistAnimation(TimedAnimation):
- def __init__(self, fig: Figure, artists: Sequence[Collection[Artist]], *args, **kwargs) -> None: ...
-
-class FuncAnimation(TimedAnimation):
- save_count: int
- def __init__(
- self,
- fig: Figure,
- func: Callable[..., Iterable[Artist]],
- frames: Iterable[Artist] | int | Callable[[], Generator] | None = ...,
- init_func: Callable[[], Iterable[Artist]] | None = ...,
- fargs: tuple[Any, ...] | None = ...,
- save_count: int | None = ...,
- *,
- cache_frame_data: bool = ...,
- **kwargs
- ) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/artist.py b/contrib/python/matplotlib/py3/matplotlib/artist.py
deleted file mode 100644
index 04eaa6cf75..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/artist.py
+++ /dev/null
@@ -1,1860 +0,0 @@
-from collections import namedtuple
-import contextlib
-from functools import cache, wraps
-import inspect
-from inspect import Signature, Parameter
-import logging
-from numbers import Number, Real
-import re
-import warnings
-
-import numpy as np
-
-import matplotlib as mpl
-from . import _api, cbook
-from .colors import BoundaryNorm
-from .cm import ScalarMappable
-from .path import Path
-from .transforms import (BboxBase, Bbox, IdentityTransform, Transform, TransformedBbox,
- TransformedPatchPath, TransformedPath)
-
-_log = logging.getLogger(__name__)
-
-
-def _prevent_rasterization(draw):
- # We assume that by default artists are not allowed to rasterize (unless
- # its draw method is explicitly decorated). If it is being drawn after a
- # rasterized artist and it has reached a raster_depth of 0, we stop
- # rasterization so that it does not affect the behavior of normal artist
- # (e.g., change in dpi).
-
- @wraps(draw)
- def draw_wrapper(artist, renderer, *args, **kwargs):
- if renderer._raster_depth == 0 and renderer._rasterizing:
- # Only stop when we are not in a rasterized parent
- # and something has been rasterized since last stop.
- renderer.stop_rasterizing()
- renderer._rasterizing = False
-
- return draw(artist, renderer, *args, **kwargs)
-
- draw_wrapper._supports_rasterization = False
- return draw_wrapper
-
-
-def allow_rasterization(draw):
- """
- Decorator for Artist.draw method. Provides routines
- that run before and after the draw call. The before and after functions
- are useful for changing artist-dependent renderer attributes or making
- other setup function calls, such as starting and flushing a mixed-mode
- renderer.
- """
-
- @wraps(draw)
- def draw_wrapper(artist, renderer):
- try:
- if artist.get_rasterized():
- if renderer._raster_depth == 0 and not renderer._rasterizing:
- renderer.start_rasterizing()
- renderer._rasterizing = True
- renderer._raster_depth += 1
- else:
- if renderer._raster_depth == 0 and renderer._rasterizing:
- # Only stop when we are not in a rasterized parent
- # and something has be rasterized since last stop
- renderer.stop_rasterizing()
- renderer._rasterizing = False
-
- if artist.get_agg_filter() is not None:
- renderer.start_filter()
-
- return draw(artist, renderer)
- finally:
- if artist.get_agg_filter() is not None:
- renderer.stop_filter(artist.get_agg_filter())
- if artist.get_rasterized():
- renderer._raster_depth -= 1
- if (renderer._rasterizing and artist.figure and
- artist.figure.suppressComposite):
- # restart rasterizing to prevent merging
- renderer.stop_rasterizing()
- renderer.start_rasterizing()
-
- draw_wrapper._supports_rasterization = True
- return draw_wrapper
-
-
-def _finalize_rasterization(draw):
- """
- Decorator for Artist.draw method. Needed on the outermost artist, i.e.
- Figure, to finish up if the render is still in rasterized mode.
- """
- @wraps(draw)
- def draw_wrapper(artist, renderer, *args, **kwargs):
- result = draw(artist, renderer, *args, **kwargs)
- if renderer._rasterizing:
- renderer.stop_rasterizing()
- renderer._rasterizing = False
- return result
- return draw_wrapper
-
-
-def _stale_axes_callback(self, val):
- if self.axes:
- self.axes.stale = val
-
-
-_XYPair = namedtuple("_XYPair", "x y")
-
-
-class _Unset:
- def __repr__(self):
- return "<UNSET>"
-_UNSET = _Unset()
-
-
-class Artist:
- """
- Abstract base class for objects that render into a FigureCanvas.
-
- Typically, all visible elements in a figure are subclasses of Artist.
- """
-
- zorder = 0
-
- def __init_subclass__(cls):
-
- # Decorate draw() method so that all artists are able to stop
- # rastrization when necessary. If the artist's draw method is already
- # decorated (has a `_supports_rasterization` attribute), it won't be
- # decorated.
-
- if not hasattr(cls.draw, "_supports_rasterization"):
- cls.draw = _prevent_rasterization(cls.draw)
-
- # Inject custom set() methods into the subclass with signature and
- # docstring based on the subclasses' properties.
-
- if not hasattr(cls.set, '_autogenerated_signature'):
- # Don't overwrite cls.set if the subclass or one of its parents
- # has defined a set method set itself.
- # If there was no explicit definition, cls.set is inherited from
- # the hierarchy of auto-generated set methods, which hold the
- # flag _autogenerated_signature.
- return
-
- cls.set = lambda self, **kwargs: Artist.set(self, **kwargs)
- cls.set.__name__ = "set"
- cls.set.__qualname__ = f"{cls.__qualname__}.set"
- cls._update_set_signature_and_docstring()
-
- _PROPERTIES_EXCLUDED_FROM_SET = [
- 'navigate_mode', # not a user-facing function
- 'figure', # changing the figure is such a profound operation
- # that we don't want this in set()
- '3d_properties', # cannot be used as a keyword due to leading digit
- ]
-
- @classmethod
- def _update_set_signature_and_docstring(cls):
- """
- Update the signature of the set function to list all properties
- as keyword arguments.
-
- Property aliases are not listed in the signature for brevity, but
- are still accepted as keyword arguments.
- """
- cls.set.__signature__ = Signature(
- [Parameter("self", Parameter.POSITIONAL_OR_KEYWORD),
- *[Parameter(prop, Parameter.KEYWORD_ONLY, default=_UNSET)
- for prop in ArtistInspector(cls).get_setters()
- if prop not in Artist._PROPERTIES_EXCLUDED_FROM_SET]])
- cls.set._autogenerated_signature = True
-
- cls.set.__doc__ = (
- "Set multiple properties at once.\n\n"
- "Supported properties are\n\n"
- + kwdoc(cls))
-
- def __init__(self):
- self._stale = True
- self.stale_callback = None
- self._axes = None
- self.figure = None
-
- self._transform = None
- self._transformSet = False
- self._visible = True
- self._animated = False
- self._alpha = None
- self.clipbox = None
- self._clippath = None
- self._clipon = True
- self._label = ''
- self._picker = None
- self._rasterized = False
- self._agg_filter = None
- # Normally, artist classes need to be queried for mouseover info if and
- # only if they override get_cursor_data.
- self._mouseover = type(self).get_cursor_data != Artist.get_cursor_data
- self._callbacks = cbook.CallbackRegistry(signals=["pchanged"])
- try:
- self.axes = None
- except AttributeError:
- # Handle self.axes as a read-only property, as in Figure.
- pass
- self._remove_method = None
- self._url = None
- self._gid = None
- self._snap = None
- self._sketch = mpl.rcParams['path.sketch']
- self._path_effects = mpl.rcParams['path.effects']
- self._sticky_edges = _XYPair([], [])
- self._in_layout = True
-
- def __getstate__(self):
- d = self.__dict__.copy()
- d['stale_callback'] = None
- return d
-
- def remove(self):
- """
- Remove the artist from the figure if possible.
-
- The effect will not be visible until the figure is redrawn, e.g.,
- with `.FigureCanvasBase.draw_idle`. Call `~.axes.Axes.relim` to
- update the axes limits if desired.
-
- Note: `~.axes.Axes.relim` will not see collections even if the
- collection was added to the axes with *autolim* = True.
-
- Note: there is no support for removing the artist's legend entry.
- """
-
- # There is no method to set the callback. Instead, the parent should
- # set the _remove_method attribute directly. This would be a
- # protected attribute if Python supported that sort of thing. The
- # callback has one parameter, which is the child to be removed.
- if self._remove_method is not None:
- self._remove_method(self)
- # clear stale callback
- self.stale_callback = None
- _ax_flag = False
- if hasattr(self, 'axes') and self.axes:
- # remove from the mouse hit list
- self.axes._mouseover_set.discard(self)
- self.axes.stale = True
- self.axes = None # decouple the artist from the Axes
- _ax_flag = True
-
- if self.figure:
- if not _ax_flag:
- self.figure.stale = True
- self.figure = None
-
- else:
- raise NotImplementedError('cannot remove artist')
- # TODO: the fix for the collections relim problem is to move the
- # limits calculation into the artist itself, including the property of
- # whether or not the artist should affect the limits. Then there will
- # be no distinction between axes.add_line, axes.add_patch, etc.
- # TODO: add legend support
-
- def have_units(self):
- """Return whether units are set on any axis."""
- ax = self.axes
- return ax and any(axis.have_units() for axis in ax._axis_map.values())
-
- def convert_xunits(self, x):
- """
- Convert *x* using the unit type of the xaxis.
-
- If the artist is not contained in an Axes or if the xaxis does not
- have units, *x* itself is returned.
- """
- ax = getattr(self, 'axes', None)
- if ax is None or ax.xaxis is None:
- return x
- return ax.xaxis.convert_units(x)
-
- def convert_yunits(self, y):
- """
- Convert *y* using the unit type of the yaxis.
-
- If the artist is not contained in an Axes or if the yaxis does not
- have units, *y* itself is returned.
- """
- ax = getattr(self, 'axes', None)
- if ax is None or ax.yaxis is None:
- return y
- return ax.yaxis.convert_units(y)
-
- @property
- def axes(self):
- """The `~.axes.Axes` instance the artist resides in, or *None*."""
- return self._axes
-
- @axes.setter
- def axes(self, new_axes):
- if (new_axes is not None and self._axes is not None
- and new_axes != self._axes):
- raise ValueError("Can not reset the axes. You are probably "
- "trying to re-use an artist in more than one "
- "Axes which is not supported")
- self._axes = new_axes
- if new_axes is not None and new_axes is not self:
- self.stale_callback = _stale_axes_callback
-
- @property
- def stale(self):
- """
- Whether the artist is 'stale' and needs to be re-drawn for the output
- to match the internal state of the artist.
- """
- return self._stale
-
- @stale.setter
- def stale(self, val):
- self._stale = val
-
- # if the artist is animated it does not take normal part in the
- # draw stack and is not expected to be drawn as part of the normal
- # draw loop (when not saving) so do not propagate this change
- if self._animated:
- return
-
- if val and self.stale_callback is not None:
- self.stale_callback(self, val)
-
- def get_window_extent(self, renderer=None):
- """
- Get the artist's bounding box in display space.
-
- The bounding box' width and height are nonnegative.
-
- Subclasses should override for inclusion in the bounding box
- "tight" calculation. Default is to return an empty bounding
- box at 0, 0.
-
- Be careful when using this function, the results will not update
- if the artist window extent of the artist changes. The extent
- can change due to any changes in the transform stack, such as
- changing the axes limits, the figure size, or the canvas used
- (as is done when saving a figure). This can lead to unexpected
- behavior where interactive figures will look fine on the screen,
- but will save incorrectly.
- """
- return Bbox([[0, 0], [0, 0]])
-
- def get_tightbbox(self, renderer=None):
- """
- Like `.Artist.get_window_extent`, but includes any clipping.
-
- Parameters
- ----------
- renderer : `~matplotlib.backend_bases.RendererBase` subclass, optional
- renderer that will be used to draw the figures (i.e.
- ``fig.canvas.get_renderer()``)
-
- Returns
- -------
- `.Bbox` or None
- The enclosing bounding box (in figure pixel coordinates).
- Returns None if clipping results in no intersection.
- """
- bbox = self.get_window_extent(renderer)
- if self.get_clip_on():
- clip_box = self.get_clip_box()
- if clip_box is not None:
- bbox = Bbox.intersection(bbox, clip_box)
- clip_path = self.get_clip_path()
- if clip_path is not None and bbox is not None:
- clip_path = clip_path.get_fully_transformed_path()
- bbox = Bbox.intersection(bbox, clip_path.get_extents())
- return bbox
-
- def add_callback(self, func):
- """
- Add a callback function that will be called whenever one of the
- `.Artist`'s properties changes.
-
- Parameters
- ----------
- func : callable
- The callback function. It must have the signature::
-
- def func(artist: Artist) -> Any
-
- where *artist* is the calling `.Artist`. Return values may exist
- but are ignored.
-
- Returns
- -------
- int
- The observer id associated with the callback. This id can be
- used for removing the callback with `.remove_callback` later.
-
- See Also
- --------
- remove_callback
- """
- # Wrapping func in a lambda ensures it can be connected multiple times
- # and never gets weakref-gc'ed.
- return self._callbacks.connect("pchanged", lambda: func(self))
-
- def remove_callback(self, oid):
- """
- Remove a callback based on its observer id.
-
- See Also
- --------
- add_callback
- """
- self._callbacks.disconnect(oid)
-
- def pchanged(self):
- """
- Call all of the registered callbacks.
-
- This function is triggered internally when a property is changed.
-
- See Also
- --------
- add_callback
- remove_callback
- """
- self._callbacks.process("pchanged")
-
- def is_transform_set(self):
- """
- Return whether the Artist has an explicitly set transform.
-
- This is *True* after `.set_transform` has been called.
- """
- return self._transformSet
-
- def set_transform(self, t):
- """
- Set the artist transform.
-
- Parameters
- ----------
- t : `~matplotlib.transforms.Transform`
- """
- self._transform = t
- self._transformSet = True
- self.pchanged()
- self.stale = True
-
- def get_transform(self):
- """Return the `.Transform` instance used by this artist."""
- if self._transform is None:
- self._transform = IdentityTransform()
- elif (not isinstance(self._transform, Transform)
- and hasattr(self._transform, '_as_mpl_transform')):
- self._transform = self._transform._as_mpl_transform(self.axes)
- return self._transform
-
- def get_children(self):
- r"""Return a list of the child `.Artist`\s of this `.Artist`."""
- return []
-
- def _different_canvas(self, event):
- """
- Check whether an *event* occurred on a canvas other that this artist's canvas.
-
- If this method returns True, the event definitely occurred on a different
- canvas; if it returns False, either it occurred on the same canvas, or we may
- not have enough information to know.
-
- Subclasses should start their definition of `contains` as follows::
-
- if self._different_canvas(mouseevent):
- return False, {}
- # subclass-specific implementation follows
- """
- return (getattr(event, "canvas", None) is not None and self.figure is not None
- and event.canvas is not self.figure.canvas)
-
- def contains(self, mouseevent):
- """
- Test whether the artist contains the mouse event.
-
- Parameters
- ----------
- mouseevent : `~matplotlib.backend_bases.MouseEvent`
-
- Returns
- -------
- contains : bool
- Whether any values are within the radius.
- details : dict
- An artist-specific dictionary of details of the event context,
- such as which points are contained in the pick radius. See the
- individual Artist subclasses for details.
- """
- inside, info = self._default_contains(mouseevent)
- if inside is not None:
- return inside, info
- _log.warning("%r needs 'contains' method", self.__class__.__name__)
- return False, {}
-
- def pickable(self):
- """
- Return whether the artist is pickable.
-
- See Also
- --------
- set_picker, get_picker, pick
- """
- return self.figure is not None and self._picker is not None
-
- def pick(self, mouseevent):
- """
- Process a pick event.
-
- Each child artist will fire a pick event if *mouseevent* is over
- the artist and the artist has picker set.
-
- See Also
- --------
- set_picker, get_picker, pickable
- """
- from .backend_bases import PickEvent # Circular import.
- # Pick self
- if self.pickable():
- picker = self.get_picker()
- if callable(picker):
- inside, prop = picker(self, mouseevent)
- else:
- inside, prop = self.contains(mouseevent)
- if inside:
- PickEvent("pick_event", self.figure.canvas,
- mouseevent, self, **prop)._process()
-
- # Pick children
- for a in self.get_children():
- # make sure the event happened in the same Axes
- ax = getattr(a, 'axes', None)
- if (mouseevent.inaxes is None or ax is None
- or mouseevent.inaxes == ax):
- # we need to check if mouseevent.inaxes is None
- # because some objects associated with an Axes (e.g., a
- # tick label) can be outside the bounding box of the
- # Axes and inaxes will be None
- # also check that ax is None so that it traverse objects
- # which do not have an axes property but children might
- a.pick(mouseevent)
-
- def set_picker(self, picker):
- """
- Define the picking behavior of the artist.
-
- Parameters
- ----------
- picker : None or bool or float or callable
- This can be one of the following:
-
- - *None*: Picking is disabled for this artist (default).
-
- - A boolean: If *True* then picking will be enabled and the
- artist will fire a pick event if the mouse event is over
- the artist.
-
- - A float: If picker is a number it is interpreted as an
- epsilon tolerance in points and the artist will fire
- off an event if its data is within epsilon of the mouse
- event. For some artists like lines and patch collections,
- the artist may provide additional data to the pick event
- that is generated, e.g., the indices of the data within
- epsilon of the pick event
-
- - A function: If picker is callable, it is a user supplied
- function which determines whether the artist is hit by the
- mouse event::
-
- hit, props = picker(artist, mouseevent)
-
- to determine the hit test. if the mouse event is over the
- artist, return *hit=True* and props is a dictionary of
- properties you want added to the PickEvent attributes.
- """
- self._picker = picker
-
- def get_picker(self):
- """
- Return the picking behavior of the artist.
-
- The possible values are described in `.set_picker`.
-
- See Also
- --------
- set_picker, pickable, pick
- """
- return self._picker
-
- def get_url(self):
- """Return the url."""
- return self._url
-
- def set_url(self, url):
- """
- Set the url for the artist.
-
- Parameters
- ----------
- url : str
- """
- self._url = url
-
- def get_gid(self):
- """Return the group id."""
- return self._gid
-
- def set_gid(self, gid):
- """
- Set the (group) id for the artist.
-
- Parameters
- ----------
- gid : str
- """
- self._gid = gid
-
- def get_snap(self):
- """
- Return the snap setting.
-
- See `.set_snap` for details.
- """
- if mpl.rcParams['path.snap']:
- return self._snap
- else:
- return False
-
- def set_snap(self, snap):
- """
- Set the snapping behavior.
-
- Snapping aligns positions with the pixel grid, which results in
- clearer images. For example, if a black line of 1px width was
- defined at a position in between two pixels, the resulting image
- would contain the interpolated value of that line in the pixel grid,
- which would be a grey value on both adjacent pixel positions. In
- contrast, snapping will move the line to the nearest integer pixel
- value, so that the resulting image will really contain a 1px wide
- black line.
-
- Snapping is currently only supported by the Agg and MacOSX backends.
-
- Parameters
- ----------
- snap : bool or None
- Possible values:
-
- - *True*: Snap vertices to the nearest pixel center.
- - *False*: Do not modify vertex positions.
- - *None*: (auto) If the path contains only rectilinear line
- segments, round to the nearest pixel center.
- """
- self._snap = snap
- self.stale = True
-
- def get_sketch_params(self):
- """
- Return the sketch parameters for the artist.
-
- Returns
- -------
- tuple or None
-
- A 3-tuple with the following elements:
-
- - *scale*: The amplitude of the wiggle perpendicular to the
- source line.
- - *length*: The length of the wiggle along the line.
- - *randomness*: The scale factor by which the length is
- shrunken or expanded.
-
- Returns *None* if no sketch parameters were set.
- """
- return self._sketch
-
- def set_sketch_params(self, scale=None, length=None, randomness=None):
- """
- Set the sketch parameters.
-
- Parameters
- ----------
- scale : float, optional
- The amplitude of the wiggle perpendicular to the source
- line, in pixels. If scale is `None`, or not provided, no
- sketch filter will be provided.
- length : float, optional
- The length of the wiggle along the line, in pixels
- (default 128.0)
- randomness : float, optional
- The scale factor by which the length is shrunken or
- expanded (default 16.0)
-
- The PGF backend uses this argument as an RNG seed and not as
- described above. Using the same seed yields the same random shape.
-
- .. ACCEPTS: (scale: float, length: float, randomness: float)
- """
- if scale is None:
- self._sketch = None
- else:
- self._sketch = (scale, length or 128.0, randomness or 16.0)
- self.stale = True
-
- def set_path_effects(self, path_effects):
- """
- Set the path effects.
-
- Parameters
- ----------
- path_effects : list of `.AbstractPathEffect`
- """
- self._path_effects = path_effects
- self.stale = True
-
- def get_path_effects(self):
- return self._path_effects
-
- def get_figure(self):
- """Return the `.Figure` instance the artist belongs to."""
- return self.figure
-
- def set_figure(self, fig):
- """
- Set the `.Figure` instance the artist belongs to.
-
- Parameters
- ----------
- fig : `~matplotlib.figure.Figure`
- """
- # if this is a no-op just return
- if self.figure is fig:
- return
- # if we currently have a figure (the case of both `self.figure`
- # and *fig* being none is taken care of above) we then user is
- # trying to change the figure an artist is associated with which
- # is not allowed for the same reason as adding the same instance
- # to more than one Axes
- if self.figure is not None:
- raise RuntimeError("Can not put single artist in "
- "more than one figure")
- self.figure = fig
- if self.figure and self.figure is not self:
- self.pchanged()
- self.stale = True
-
- def set_clip_box(self, clipbox):
- """
- Set the artist's clip `.Bbox`.
-
- Parameters
- ----------
- clipbox : `~matplotlib.transforms.BboxBase` or None
- Will typically be created from a `.TransformedBbox`. For instance,
- ``TransformedBbox(Bbox([[0, 0], [1, 1]]), ax.transAxes)`` is the default
- clipping for an artist added to an Axes.
-
- """
- _api.check_isinstance((BboxBase, None), clipbox=clipbox)
- if clipbox != self.clipbox:
- self.clipbox = clipbox
- self.pchanged()
- self.stale = True
-
- def set_clip_path(self, path, transform=None):
- """
- Set the artist's clip path.
-
- Parameters
- ----------
- path : `~matplotlib.patches.Patch` or `.Path` or `.TransformedPath` or None
- The clip path. If given a `.Path`, *transform* must be provided as
- well. If *None*, a previously set clip path is removed.
- transform : `~matplotlib.transforms.Transform`, optional
- Only used if *path* is a `.Path`, in which case the given `.Path`
- is converted to a `.TransformedPath` using *transform*.
-
- Notes
- -----
- For efficiency, if *path* is a `.Rectangle` this method will set the
- clipping box to the corresponding rectangle and set the clipping path
- to ``None``.
-
- For technical reasons (support of `~.Artist.set`), a tuple
- (*path*, *transform*) is also accepted as a single positional
- parameter.
-
- .. ACCEPTS: Patch or (Path, Transform) or None
- """
- from matplotlib.patches import Patch, Rectangle
-
- success = False
- if transform is None:
- if isinstance(path, Rectangle):
- self.clipbox = TransformedBbox(Bbox.unit(),
- path.get_transform())
- self._clippath = None
- success = True
- elif isinstance(path, Patch):
- self._clippath = TransformedPatchPath(path)
- success = True
- elif isinstance(path, tuple):
- path, transform = path
-
- if path is None:
- self._clippath = None
- success = True
- elif isinstance(path, Path):
- self._clippath = TransformedPath(path, transform)
- success = True
- elif isinstance(path, TransformedPatchPath):
- self._clippath = path
- success = True
- elif isinstance(path, TransformedPath):
- self._clippath = path
- success = True
-
- if not success:
- raise TypeError(
- "Invalid arguments to set_clip_path, of type "
- f"{type(path).__name__} and {type(transform).__name__}")
- # This may result in the callbacks being hit twice, but guarantees they
- # will be hit at least once.
- self.pchanged()
- self.stale = True
-
- def get_alpha(self):
- """
- Return the alpha value used for blending - not supported on all
- backends.
- """
- return self._alpha
-
- def get_visible(self):
- """Return the visibility."""
- return self._visible
-
- def get_animated(self):
- """Return whether the artist is animated."""
- return self._animated
-
- def get_in_layout(self):
- """
- Return boolean flag, ``True`` if artist is included in layout
- calculations.
-
- E.g. :ref:`constrainedlayout_guide`,
- `.Figure.tight_layout()`, and
- ``fig.savefig(fname, bbox_inches='tight')``.
- """
- return self._in_layout
-
- def _fully_clipped_to_axes(self):
- """
- Return a boolean flag, ``True`` if the artist is clipped to the Axes
- and can thus be skipped in layout calculations. Requires `get_clip_on`
- is True, one of `clip_box` or `clip_path` is set, ``clip_box.extents``
- is equivalent to ``ax.bbox.extents`` (if set), and ``clip_path._patch``
- is equivalent to ``ax.patch`` (if set).
- """
- # Note that ``clip_path.get_fully_transformed_path().get_extents()``
- # cannot be directly compared to ``axes.bbox.extents`` because the
- # extents may be undefined (i.e. equivalent to ``Bbox.null()``)
- # before the associated artist is drawn, and this method is meant
- # to determine whether ``axes.get_tightbbox()`` may bypass drawing
- clip_box = self.get_clip_box()
- clip_path = self.get_clip_path()
- return (self.axes is not None
- and self.get_clip_on()
- and (clip_box is not None or clip_path is not None)
- and (clip_box is None
- or np.all(clip_box.extents == self.axes.bbox.extents))
- and (clip_path is None
- or isinstance(clip_path, TransformedPatchPath)
- and clip_path._patch is self.axes.patch))
-
- def get_clip_on(self):
- """Return whether the artist uses clipping."""
- return self._clipon
-
- def get_clip_box(self):
- """Return the clipbox."""
- return self.clipbox
-
- def get_clip_path(self):
- """Return the clip path."""
- return self._clippath
-
- def get_transformed_clip_path_and_affine(self):
- """
- Return the clip path with the non-affine part of its
- transformation applied, and the remaining affine part of its
- transformation.
- """
- if self._clippath is not None:
- return self._clippath.get_transformed_path_and_affine()
- return None, None
-
- def set_clip_on(self, b):
- """
- Set whether the artist uses clipping.
-
- When False, artists will be visible outside the Axes which
- can lead to unexpected results.
-
- Parameters
- ----------
- b : bool
- """
- self._clipon = b
- # This may result in the callbacks being hit twice, but ensures they
- # are hit at least once
- self.pchanged()
- self.stale = True
-
- def _set_gc_clip(self, gc):
- """Set the clip properly for the gc."""
- if self._clipon:
- if self.clipbox is not None:
- gc.set_clip_rectangle(self.clipbox)
- gc.set_clip_path(self._clippath)
- else:
- gc.set_clip_rectangle(None)
- gc.set_clip_path(None)
-
- def get_rasterized(self):
- """Return whether the artist is to be rasterized."""
- return self._rasterized
-
- def set_rasterized(self, rasterized):
- """
- Force rasterized (bitmap) drawing for vector graphics output.
-
- Rasterized drawing is not supported by all artists. If you try to
- enable this on an artist that does not support it, the command has no
- effect and a warning will be issued.
-
- This setting is ignored for pixel-based output.
-
- See also :doc:`/gallery/misc/rasterization_demo`.
-
- Parameters
- ----------
- rasterized : bool
- """
- supports_rasterization = getattr(self.draw,
- "_supports_rasterization", False)
- if rasterized and not supports_rasterization:
- _api.warn_external(f"Rasterization of '{self}' will be ignored")
-
- self._rasterized = rasterized
-
- def get_agg_filter(self):
- """Return filter function to be used for agg filter."""
- return self._agg_filter
-
- def set_agg_filter(self, filter_func):
- """
- Set the agg filter.
-
- Parameters
- ----------
- filter_func : callable
- A filter function, which takes a (m, n, depth) float array
- and a dpi value, and returns a (m, n, depth) array and two
- offsets from the bottom left corner of the image
-
- .. ACCEPTS: a filter function, which takes a (m, n, 3) float array
- and a dpi value, and returns a (m, n, 3) array and two offsets
- from the bottom left corner of the image
- """
- self._agg_filter = filter_func
- self.stale = True
-
- def draw(self, renderer):
- """
- Draw the Artist (and its children) using the given renderer.
-
- This has no effect if the artist is not visible (`.Artist.get_visible`
- returns False).
-
- Parameters
- ----------
- renderer : `~matplotlib.backend_bases.RendererBase` subclass.
-
- Notes
- -----
- This method is overridden in the Artist subclasses.
- """
- if not self.get_visible():
- return
- self.stale = False
-
- def set_alpha(self, alpha):
- """
- Set the alpha value used for blending - not supported on all backends.
-
- Parameters
- ----------
- alpha : scalar or None
- *alpha* must be within the 0-1 range, inclusive.
- """
- if alpha is not None and not isinstance(alpha, Real):
- raise TypeError(
- f'alpha must be numeric or None, not {type(alpha)}')
- if alpha is not None and not (0 <= alpha <= 1):
- raise ValueError(f'alpha ({alpha}) is outside 0-1 range')
- if alpha != self._alpha:
- self._alpha = alpha
- self.pchanged()
- self.stale = True
-
- def _set_alpha_for_array(self, alpha):
- """
- Set the alpha value used for blending - not supported on all backends.
-
- Parameters
- ----------
- alpha : array-like or scalar or None
- All values must be within the 0-1 range, inclusive.
- Masked values and nans are not supported.
- """
- if isinstance(alpha, str):
- raise TypeError("alpha must be numeric or None, not a string")
- if not np.iterable(alpha):
- Artist.set_alpha(self, alpha)
- return
- alpha = np.asarray(alpha)
- if not (0 <= alpha.min() and alpha.max() <= 1):
- raise ValueError('alpha must be between 0 and 1, inclusive, '
- f'but min is {alpha.min()}, max is {alpha.max()}')
- self._alpha = alpha
- self.pchanged()
- self.stale = True
-
- def set_visible(self, b):
- """
- Set the artist's visibility.
-
- Parameters
- ----------
- b : bool
- """
- if b != self._visible:
- self._visible = b
- self.pchanged()
- self.stale = True
-
- def set_animated(self, b):
- """
- Set whether the artist is intended to be used in an animation.
-
- If True, the artist is excluded from regular drawing of the figure.
- You have to call `.Figure.draw_artist` / `.Axes.draw_artist`
- explicitly on the artist. This approach is used to speed up animations
- using blitting.
-
- See also `matplotlib.animation` and
- :ref:`blitting`.
-
- Parameters
- ----------
- b : bool
- """
- if self._animated != b:
- self._animated = b
- self.pchanged()
-
- def set_in_layout(self, in_layout):
- """
- Set if artist is to be included in layout calculations,
- E.g. :ref:`constrainedlayout_guide`,
- `.Figure.tight_layout()`, and
- ``fig.savefig(fname, bbox_inches='tight')``.
-
- Parameters
- ----------
- in_layout : bool
- """
- self._in_layout = in_layout
-
- def get_label(self):
- """Return the label used for this artist in the legend."""
- return self._label
-
- def set_label(self, s):
- """
- Set a label that will be displayed in the legend.
-
- Parameters
- ----------
- s : object
- *s* will be converted to a string by calling `str`.
- """
- label = str(s) if s is not None else None
- if label != self._label:
- self._label = label
- self.pchanged()
- self.stale = True
-
- def get_zorder(self):
- """Return the artist's zorder."""
- return self.zorder
-
- def set_zorder(self, level):
- """
- Set the zorder for the artist. Artists with lower zorder
- values are drawn first.
-
- Parameters
- ----------
- level : float
- """
- if level is None:
- level = self.__class__.zorder
- if level != self.zorder:
- self.zorder = level
- self.pchanged()
- self.stale = True
-
- @property
- def sticky_edges(self):
- """
- ``x`` and ``y`` sticky edge lists for autoscaling.
-
- When performing autoscaling, if a data limit coincides with a value in
- the corresponding sticky_edges list, then no margin will be added--the
- view limit "sticks" to the edge. A typical use case is histograms,
- where one usually expects no margin on the bottom edge (0) of the
- histogram.
-
- Moreover, margin expansion "bumps" against sticky edges and cannot
- cross them. For example, if the upper data limit is 1.0, the upper
- view limit computed by simple margin application is 1.2, but there is a
- sticky edge at 1.1, then the actual upper view limit will be 1.1.
-
- This attribute cannot be assigned to; however, the ``x`` and ``y``
- lists can be modified in place as needed.
-
- Examples
- --------
- >>> artist.sticky_edges.x[:] = (xmin, xmax)
- >>> artist.sticky_edges.y[:] = (ymin, ymax)
-
- """
- return self._sticky_edges
-
- def update_from(self, other):
- """Copy properties from *other* to *self*."""
- self._transform = other._transform
- self._transformSet = other._transformSet
- self._visible = other._visible
- self._alpha = other._alpha
- self.clipbox = other.clipbox
- self._clipon = other._clipon
- self._clippath = other._clippath
- self._label = other._label
- self._sketch = other._sketch
- self._path_effects = other._path_effects
- self.sticky_edges.x[:] = other.sticky_edges.x.copy()
- self.sticky_edges.y[:] = other.sticky_edges.y.copy()
- self.pchanged()
- self.stale = True
-
- def properties(self):
- """Return a dictionary of all the properties of the artist."""
- return ArtistInspector(self).properties()
-
- def _update_props(self, props, errfmt):
- """
- Helper for `.Artist.set` and `.Artist.update`.
-
- *errfmt* is used to generate error messages for invalid property
- names; it gets formatted with ``type(self)`` and the property name.
- """
- ret = []
- with cbook._setattr_cm(self, eventson=False):
- for k, v in props.items():
- # Allow attributes we want to be able to update through
- # art.update, art.set, setp.
- if k == "axes":
- ret.append(setattr(self, k, v))
- else:
- func = getattr(self, f"set_{k}", None)
- if not callable(func):
- raise AttributeError(
- errfmt.format(cls=type(self), prop_name=k))
- ret.append(func(v))
- if ret:
- self.pchanged()
- self.stale = True
- return ret
-
- def update(self, props):
- """
- Update this artist's properties from the dict *props*.
-
- Parameters
- ----------
- props : dict
- """
- return self._update_props(
- props, "{cls.__name__!r} object has no property {prop_name!r}")
-
- def _internal_update(self, kwargs):
- """
- Update artist properties without prenormalizing them, but generating
- errors as if calling `set`.
-
- The lack of prenormalization is to maintain backcompatibility.
- """
- return self._update_props(
- kwargs, "{cls.__name__}.set() got an unexpected keyword argument "
- "{prop_name!r}")
-
- def set(self, **kwargs):
- # docstring and signature are auto-generated via
- # Artist._update_set_signature_and_docstring() at the end of the
- # module.
- return self._internal_update(cbook.normalize_kwargs(kwargs, self))
-
- @contextlib.contextmanager
- def _cm_set(self, **kwargs):
- """
- `.Artist.set` context-manager that restores original values at exit.
- """
- orig_vals = {k: getattr(self, f"get_{k}")() for k in kwargs}
- try:
- self.set(**kwargs)
- yield
- finally:
- self.set(**orig_vals)
-
- def findobj(self, match=None, include_self=True):
- """
- Find artist objects.
-
- Recursively find all `.Artist` instances contained in the artist.
-
- Parameters
- ----------
- match
- A filter criterion for the matches. This can be
-
- - *None*: Return all objects contained in artist.
- - A function with signature ``def match(artist: Artist) -> bool``.
- The result will only contain artists for which the function
- returns *True*.
- - A class instance: e.g., `.Line2D`. The result will only contain
- artists of this class or its subclasses (``isinstance`` check).
-
- include_self : bool
- Include *self* in the list to be checked for a match.
-
- Returns
- -------
- list of `.Artist`
-
- """
- if match is None: # always return True
- def matchfunc(x):
- return True
- elif isinstance(match, type) and issubclass(match, Artist):
- def matchfunc(x):
- return isinstance(x, match)
- elif callable(match):
- matchfunc = match
- else:
- raise ValueError('match must be None, a matplotlib.artist.Artist '
- 'subclass, or a callable')
-
- artists = sum([c.findobj(matchfunc) for c in self.get_children()], [])
- if include_self and matchfunc(self):
- artists.append(self)
- return artists
-
- def get_cursor_data(self, event):
- """
- Return the cursor data for a given event.
-
- .. note::
- This method is intended to be overridden by artist subclasses.
- As an end-user of Matplotlib you will most likely not call this
- method yourself.
-
- Cursor data can be used by Artists to provide additional context
- information for a given event. The default implementation just returns
- *None*.
-
- Subclasses can override the method and return arbitrary data. However,
- when doing so, they must ensure that `.format_cursor_data` can convert
- the data to a string representation.
-
- The only current use case is displaying the z-value of an `.AxesImage`
- in the status bar of a plot window, while moving the mouse.
-
- Parameters
- ----------
- event : `~matplotlib.backend_bases.MouseEvent`
-
- See Also
- --------
- format_cursor_data
-
- """
- return None
-
- def format_cursor_data(self, data):
- """
- Return a string representation of *data*.
-
- .. note::
- This method is intended to be overridden by artist subclasses.
- As an end-user of Matplotlib you will most likely not call this
- method yourself.
-
- The default implementation converts ints and floats and arrays of ints
- and floats into a comma-separated string enclosed in square brackets,
- unless the artist has an associated colorbar, in which case scalar
- values are formatted using the colorbar's formatter.
-
- See Also
- --------
- get_cursor_data
- """
- if np.ndim(data) == 0 and isinstance(self, ScalarMappable):
- # This block logically belongs to ScalarMappable, but can't be
- # implemented in it because most ScalarMappable subclasses inherit
- # from Artist first and from ScalarMappable second, so
- # Artist.format_cursor_data would always have precedence over
- # ScalarMappable.format_cursor_data.
- n = self.cmap.N
- if np.ma.getmask(data):
- return "[]"
- normed = self.norm(data)
- if np.isfinite(normed):
- if isinstance(self.norm, BoundaryNorm):
- # not an invertible normalization mapping
- cur_idx = np.argmin(np.abs(self.norm.boundaries - data))
- neigh_idx = max(0, cur_idx - 1)
- # use max diff to prevent delta == 0
- delta = np.diff(
- self.norm.boundaries[neigh_idx:cur_idx + 2]
- ).max()
-
- else:
- # Midpoints of neighboring color intervals.
- neighbors = self.norm.inverse(
- (int(normed * n) + np.array([0, 1])) / n)
- delta = abs(neighbors - data).max()
- g_sig_digits = cbook._g_sig_digits(data, delta)
- else:
- g_sig_digits = 3 # Consistent with default below.
- return f"[{data:-#.{g_sig_digits}g}]"
- else:
- try:
- data[0]
- except (TypeError, IndexError):
- data = [data]
- data_str = ', '.join(f'{item:0.3g}' for item in data
- if isinstance(item, Number))
- return "[" + data_str + "]"
-
- def get_mouseover(self):
- """
- Return whether this artist is queried for custom context information
- when the mouse cursor moves over it.
- """
- return self._mouseover
-
- def set_mouseover(self, mouseover):
- """
- Set whether this artist is queried for custom context information when
- the mouse cursor moves over it.
-
- Parameters
- ----------
- mouseover : bool
-
- See Also
- --------
- get_cursor_data
- .ToolCursorPosition
- .NavigationToolbar2
- """
- self._mouseover = bool(mouseover)
- ax = self.axes
- if ax:
- if self._mouseover:
- ax._mouseover_set.add(self)
- else:
- ax._mouseover_set.discard(self)
-
- mouseover = property(get_mouseover, set_mouseover) # backcompat.
-
-
-def _get_tightbbox_for_layout_only(obj, *args, **kwargs):
- """
- Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
- *for_layout_only* kwarg; this helper tries to use the kwarg but skips it
- when encountering third-party subclasses that do not support it.
- """
- try:
- return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
- except TypeError:
- return obj.get_tightbbox(*args, **kwargs)
-
-
-class ArtistInspector:
- """
- A helper class to inspect an `~matplotlib.artist.Artist` and return
- information about its settable properties and their current values.
- """
-
- def __init__(self, o):
- r"""
- Initialize the artist inspector with an `Artist` or an iterable of
- `Artist`\s. If an iterable is used, we assume it is a homogeneous
- sequence (all `Artist`\s are of the same type) and it is your
- responsibility to make sure this is so.
- """
- if not isinstance(o, Artist):
- if np.iterable(o):
- o = list(o)
- if len(o):
- o = o[0]
-
- self.oorig = o
- if not isinstance(o, type):
- o = type(o)
- self.o = o
-
- self.aliasd = self.get_aliases()
-
- def get_aliases(self):
- """
- Get a dict mapping property fullnames to sets of aliases for each alias
- in the :class:`~matplotlib.artist.ArtistInspector`.
-
- e.g., for lines::
-
- {'markerfacecolor': {'mfc'},
- 'linewidth' : {'lw'},
- }
- """
- names = [name for name in dir(self.o)
- if name.startswith(('set_', 'get_'))
- and callable(getattr(self.o, name))]
- aliases = {}
- for name in names:
- func = getattr(self.o, name)
- if not self.is_alias(func):
- continue
- propname = re.search(f"`({name[:4]}.*)`", # get_.*/set_.*
- inspect.getdoc(func)).group(1)
- aliases.setdefault(propname[4:], set()).add(name[4:])
- return aliases
-
- _get_valid_values_regex = re.compile(
- r"\n\s*(?:\.\.\s+)?ACCEPTS:\s*((?:.|\n)*?)(?:$|(?:\n\n))"
- )
-
- def get_valid_values(self, attr):
- """
- Get the legal arguments for the setter associated with *attr*.
-
- This is done by querying the docstring of the setter for a line that
- begins with "ACCEPTS:" or ".. ACCEPTS:", and then by looking for a
- numpydoc-style documentation for the setter's first argument.
- """
-
- name = 'set_%s' % attr
- if not hasattr(self.o, name):
- raise AttributeError(f'{self.o} has no function {name}')
- func = getattr(self.o, name)
-
- docstring = inspect.getdoc(func)
- if docstring is None:
- return 'unknown'
-
- if docstring.startswith('Alias for '):
- return None
-
- match = self._get_valid_values_regex.search(docstring)
- if match is not None:
- return re.sub("\n *", " ", match.group(1))
-
- # Much faster than list(inspect.signature(func).parameters)[1],
- # although barely relevant wrt. matplotlib's total import time.
- param_name = func.__code__.co_varnames[1]
- # We could set the presence * based on whether the parameter is a
- # varargs (it can't be a varkwargs) but it's not really worth it.
- match = re.search(fr"(?m)^ *\*?{param_name} : (.+)", docstring)
- if match:
- return match.group(1)
-
- return 'unknown'
-
- def _replace_path(self, source_class):
- """
- Changes the full path to the public API path that is used
- in sphinx. This is needed for links to work.
- """
- replace_dict = {'_base._AxesBase': 'Axes',
- '_axes.Axes': 'Axes'}
- for key, value in replace_dict.items():
- source_class = source_class.replace(key, value)
- return source_class
-
- def get_setters(self):
- """
- Get the attribute strings with setters for object.
-
- For example, for a line, return ``['markerfacecolor', 'linewidth',
- ....]``.
- """
- setters = []
- for name in dir(self.o):
- if not name.startswith('set_'):
- continue
- func = getattr(self.o, name)
- if (not callable(func)
- or self.number_of_parameters(func) < 2
- or self.is_alias(func)):
- continue
- setters.append(name[4:])
- return setters
-
- @staticmethod
- @cache
- def number_of_parameters(func):
- """Return number of parameters of the callable *func*."""
- return len(inspect.signature(func).parameters)
-
- @staticmethod
- @cache
- def is_alias(method):
- """
- Return whether the object *method* is an alias for another method.
- """
-
- ds = inspect.getdoc(method)
- if ds is None:
- return False
-
- return ds.startswith('Alias for ')
-
- def aliased_name(self, s):
- """
- Return 'PROPNAME or alias' if *s* has an alias, else return 'PROPNAME'.
-
- For example, for the line markerfacecolor property, which has an
- alias, return 'markerfacecolor or mfc' and for the transform
- property, which does not, return 'transform'.
- """
- aliases = ''.join(' or %s' % x for x in sorted(self.aliasd.get(s, [])))
- return s + aliases
-
- _NOT_LINKABLE = {
- # A set of property setter methods that are not available in our
- # current docs. This is a workaround used to prevent trying to link
- # these setters which would lead to "target reference not found"
- # warnings during doc build.
- 'matplotlib.image._ImageBase.set_alpha',
- 'matplotlib.image._ImageBase.set_array',
- 'matplotlib.image._ImageBase.set_data',
- 'matplotlib.image._ImageBase.set_filternorm',
- 'matplotlib.image._ImageBase.set_filterrad',
- 'matplotlib.image._ImageBase.set_interpolation',
- 'matplotlib.image._ImageBase.set_interpolation_stage',
- 'matplotlib.image._ImageBase.set_resample',
- 'matplotlib.text._AnnotationBase.set_annotation_clip',
- }
-
- def aliased_name_rest(self, s, target):
- """
- Return 'PROPNAME or alias' if *s* has an alias, else return 'PROPNAME',
- formatted for reST.
-
- For example, for the line markerfacecolor property, which has an
- alias, return 'markerfacecolor or mfc' and for the transform
- property, which does not, return 'transform'.
- """
- # workaround to prevent "reference target not found"
- if target in self._NOT_LINKABLE:
- return f'``{s}``'
-
- aliases = ''.join(' or %s' % x for x in sorted(self.aliasd.get(s, [])))
- return f':meth:`{s} <{target}>`{aliases}'
-
- def pprint_setters(self, prop=None, leadingspace=2):
- """
- If *prop* is *None*, return a list of strings of all settable
- properties and their valid values.
-
- If *prop* is not *None*, it is a valid property name and that
- property will be returned as a string of property : valid
- values.
- """
- if leadingspace:
- pad = ' ' * leadingspace
- else:
- pad = ''
- if prop is not None:
- accepts = self.get_valid_values(prop)
- return f'{pad}{prop}: {accepts}'
-
- lines = []
- for prop in sorted(self.get_setters()):
- accepts = self.get_valid_values(prop)
- name = self.aliased_name(prop)
- lines.append(f'{pad}{name}: {accepts}')
- return lines
-
- def pprint_setters_rest(self, prop=None, leadingspace=4):
- """
- If *prop* is *None*, return a list of reST-formatted strings of all
- settable properties and their valid values.
-
- If *prop* is not *None*, it is a valid property name and that
- property will be returned as a string of "property : valid"
- values.
- """
- if leadingspace:
- pad = ' ' * leadingspace
- else:
- pad = ''
- if prop is not None:
- accepts = self.get_valid_values(prop)
- return f'{pad}{prop}: {accepts}'
-
- prop_and_qualnames = []
- for prop in sorted(self.get_setters()):
- # Find the parent method which actually provides the docstring.
- for cls in self.o.__mro__:
- method = getattr(cls, f"set_{prop}", None)
- if method and method.__doc__ is not None:
- break
- else: # No docstring available.
- method = getattr(self.o, f"set_{prop}")
- prop_and_qualnames.append(
- (prop, f"{method.__module__}.{method.__qualname__}"))
-
- names = [self.aliased_name_rest(prop, target)
- .replace('_base._AxesBase', 'Axes')
- .replace('_axes.Axes', 'Axes')
- for prop, target in prop_and_qualnames]
- accepts = [self.get_valid_values(prop)
- for prop, _ in prop_and_qualnames]
-
- col0_len = max(len(n) for n in names)
- col1_len = max(len(a) for a in accepts)
- table_formatstr = pad + ' ' + '=' * col0_len + ' ' + '=' * col1_len
-
- return [
- '',
- pad + '.. table::',
- pad + ' :class: property-table',
- '',
- table_formatstr,
- pad + ' ' + 'Property'.ljust(col0_len)
- + ' ' + 'Description'.ljust(col1_len),
- table_formatstr,
- *[pad + ' ' + n.ljust(col0_len) + ' ' + a.ljust(col1_len)
- for n, a in zip(names, accepts)],
- table_formatstr,
- '',
- ]
-
- def properties(self):
- """Return a dictionary mapping property name -> value."""
- o = self.oorig
- getters = [name for name in dir(o)
- if name.startswith('get_') and callable(getattr(o, name))]
- getters.sort()
- d = {}
- for name in getters:
- func = getattr(o, name)
- if self.is_alias(func):
- continue
- try:
- with warnings.catch_warnings():
- warnings.simplefilter('ignore')
- val = func()
- except Exception:
- continue
- else:
- d[name[4:]] = val
- return d
-
- def pprint_getters(self):
- """Return the getters and actual values as list of strings."""
- lines = []
- for name, val in sorted(self.properties().items()):
- if getattr(val, 'shape', ()) != () and len(val) > 6:
- s = str(val[:6]) + '...'
- else:
- s = str(val)
- s = s.replace('\n', ' ')
- if len(s) > 50:
- s = s[:50] + '...'
- name = self.aliased_name(name)
- lines.append(f' {name} = {s}')
- return lines
-
-
-def getp(obj, property=None):
- """
- Return the value of an `.Artist`'s *property*, or print all of them.
-
- Parameters
- ----------
- obj : `~matplotlib.artist.Artist`
- The queried artist; e.g., a `.Line2D`, a `.Text`, or an `~.axes.Axes`.
-
- property : str or None, default: None
- If *property* is 'somename', this function returns
- ``obj.get_somename()``.
-
- If it's None (or unset), it *prints* all gettable properties from
- *obj*. Many properties have aliases for shorter typing, e.g. 'lw' is
- an alias for 'linewidth'. In the output, aliases and full property
- names will be listed as:
-
- property or alias = value
-
- e.g.:
-
- linewidth or lw = 2
-
- See Also
- --------
- setp
- """
- if property is None:
- insp = ArtistInspector(obj)
- ret = insp.pprint_getters()
- print('\n'.join(ret))
- return
- return getattr(obj, 'get_' + property)()
-
-# alias
-get = getp
-
-
-def setp(obj, *args, file=None, **kwargs):
- """
- Set one or more properties on an `.Artist`, or list allowed values.
-
- Parameters
- ----------
- obj : `~matplotlib.artist.Artist` or list of `.Artist`
- The artist(s) whose properties are being set or queried. When setting
- properties, all artists are affected; when querying the allowed values,
- only the first instance in the sequence is queried.
-
- For example, two lines can be made thicker and red with a single call:
-
- >>> x = arange(0, 1, 0.01)
- >>> lines = plot(x, sin(2*pi*x), x, sin(4*pi*x))
- >>> setp(lines, linewidth=2, color='r')
-
- file : file-like, default: `sys.stdout`
- Where `setp` writes its output when asked to list allowed values.
-
- >>> with open('output.log') as file:
- ... setp(line, file=file)
-
- The default, ``None``, means `sys.stdout`.
-
- *args, **kwargs
- The properties to set. The following combinations are supported:
-
- - Set the linestyle of a line to be dashed:
-
- >>> line, = plot([1, 2, 3])
- >>> setp(line, linestyle='--')
-
- - Set multiple properties at once:
-
- >>> setp(line, linewidth=2, color='r')
-
- - List allowed values for a line's linestyle:
-
- >>> setp(line, 'linestyle')
- linestyle: {'-', '--', '-.', ':', '', (offset, on-off-seq), ...}
-
- - List all properties that can be set, and their allowed values:
-
- >>> setp(line)
- agg_filter: a filter function, ...
- [long output listing omitted]
-
- `setp` also supports MATLAB style string/value pairs. For example, the
- following are equivalent:
-
- >>> setp(lines, 'linewidth', 2, 'color', 'r') # MATLAB style
- >>> setp(lines, linewidth=2, color='r') # Python style
-
- See Also
- --------
- getp
- """
-
- if isinstance(obj, Artist):
- objs = [obj]
- else:
- objs = list(cbook.flatten(obj))
-
- if not objs:
- return
-
- insp = ArtistInspector(objs[0])
-
- if not kwargs and len(args) < 2:
- if args:
- print(insp.pprint_setters(prop=args[0]), file=file)
- else:
- print('\n'.join(insp.pprint_setters()), file=file)
- return
-
- if len(args) % 2:
- raise ValueError('The set args must be string, value pairs')
-
- funcvals = dict(zip(args[::2], args[1::2]))
- ret = [o.update(funcvals) for o in objs] + [o.set(**kwargs) for o in objs]
- return list(cbook.flatten(ret))
-
-
-def kwdoc(artist):
- r"""
- Inspect an `~matplotlib.artist.Artist` class (using `.ArtistInspector`) and
- return information about its settable properties and their current values.
-
- Parameters
- ----------
- artist : `~matplotlib.artist.Artist` or an iterable of `Artist`\s
-
- Returns
- -------
- str
- The settable properties of *artist*, as plain text if
- :rc:`docstring.hardcopy` is False and as a rst table (intended for
- use in Sphinx) if it is True.
- """
- ai = ArtistInspector(artist)
- return ('\n'.join(ai.pprint_setters_rest(leadingspace=4))
- if mpl.rcParams['docstring.hardcopy'] else
- 'Properties:\n' + '\n'.join(ai.pprint_setters(leadingspace=4)))
-
-# We defer this to the end of them module, because it needs ArtistInspector
-# to be defined.
-Artist._update_set_signature_and_docstring()
diff --git a/contrib/python/matplotlib/py3/matplotlib/artist.pyi b/contrib/python/matplotlib/py3/matplotlib/artist.pyi
deleted file mode 100644
index 101e97a9a0..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/artist.pyi
+++ /dev/null
@@ -1,181 +0,0 @@
-from .axes._base import _AxesBase
-from .backend_bases import RendererBase, MouseEvent
-from .figure import Figure, SubFigure
-from .path import Path
-from .patches import Patch
-from .patheffects import AbstractPathEffect
-from .transforms import (
- BboxBase,
- Bbox,
- Transform,
- TransformedPatchPath,
- TransformedPath,
-)
-
-import numpy as np
-
-from collections.abc import Callable, Iterable
-from typing import Any, NamedTuple, TextIO, overload
-from numpy.typing import ArrayLike
-
-def allow_rasterization(draw): ...
-
-class _XYPair(NamedTuple):
- x: ArrayLike
- y: ArrayLike
-
-class _Unset: ...
-
-class Artist:
- zorder: float
- stale_callback: Callable[[Artist, bool], None] | None
- figure: Figure | SubFigure | None
- clipbox: BboxBase | None
- def __init__(self) -> None: ...
- def remove(self) -> None: ...
- def have_units(self) -> bool: ...
- # TODO units
- def convert_xunits(self, x): ...
- def convert_yunits(self, y): ...
- @property
- def axes(self) -> _AxesBase | None: ...
- @axes.setter
- def axes(self, new_axes: _AxesBase | None) -> None: ...
- @property
- def stale(self) -> bool: ...
- @stale.setter
- def stale(self, val: bool) -> None: ...
- def get_window_extent(self, renderer: RendererBase | None = ...) -> Bbox: ...
- def get_tightbbox(self, renderer: RendererBase | None = ...) -> Bbox | None: ...
- def add_callback(self, func: Callable[[Artist], Any]) -> int: ...
- def remove_callback(self, oid: int) -> None: ...
- def pchanged(self) -> None: ...
- def is_transform_set(self) -> bool: ...
- def set_transform(self, t: Transform | None) -> None: ...
- def get_transform(self) -> Transform: ...
- def get_children(self) -> list[Artist]: ...
- # TODO can these dicts be type narrowed? e.g. str keys
- def contains(self, mouseevent: MouseEvent) -> tuple[bool, dict[Any, Any]]: ...
- def pickable(self) -> bool: ...
- def pick(self, mouseevent: MouseEvent) -> None: ...
- def set_picker(
- self,
- picker: None
- | bool
- | float
- | Callable[[Artist, MouseEvent], tuple[bool, dict[Any, Any]]],
- ) -> None: ...
- def get_picker(
- self,
- ) -> None | bool | float | Callable[
- [Artist, MouseEvent], tuple[bool, dict[Any, Any]]
- ]: ...
- def get_url(self) -> str | None: ...
- def set_url(self, url: str | None) -> None: ...
- def get_gid(self) -> str | None: ...
- def set_gid(self, gid: str | None) -> None: ...
- def get_snap(self) -> bool | None: ...
- def set_snap(self, snap: bool | None) -> None: ...
- def get_sketch_params(self) -> tuple[float, float, float] | None: ...
- def set_sketch_params(
- self,
- scale: float | None = ...,
- length: float | None = ...,
- randomness: float | None = ...,
- ) -> None: ...
- def set_path_effects(self, path_effects: list[AbstractPathEffect]) -> None: ...
- def get_path_effects(self) -> list[AbstractPathEffect]: ...
- def get_figure(self) -> Figure | None: ...
- def set_figure(self, fig: Figure) -> None: ...
- def set_clip_box(self, clipbox: BboxBase | None) -> None: ...
- def set_clip_path(
- self,
- path: Patch | Path | TransformedPath | TransformedPatchPath | None,
- transform: Transform | None = ...,
- ) -> None: ...
- def get_alpha(self) -> float | None: ...
- def get_visible(self) -> bool: ...
- def get_animated(self) -> bool: ...
- def get_in_layout(self) -> bool: ...
- def get_clip_on(self) -> bool: ...
- def get_clip_box(self) -> Bbox | None: ...
- def get_clip_path(
- self,
- ) -> Patch | Path | TransformedPath | TransformedPatchPath | None: ...
- def get_transformed_clip_path_and_affine(
- self,
- ) -> tuple[None, None] | tuple[Path, Transform]: ...
- def set_clip_on(self, b: bool) -> None: ...
- def get_rasterized(self) -> bool: ...
- def set_rasterized(self, rasterized: bool) -> None: ...
- def get_agg_filter(self) -> Callable[[ArrayLike, float], tuple[np.ndarray, float, float]] | None: ...
- def set_agg_filter(
- self, filter_func: Callable[[ArrayLike, float], tuple[np.ndarray, float, float]] | None
- ) -> None: ...
- def draw(self, renderer: RendererBase) -> None: ...
- def set_alpha(self, alpha: float | None) -> None: ...
- def set_visible(self, b: bool) -> None: ...
- def set_animated(self, b: bool) -> None: ...
- def set_in_layout(self, in_layout: bool) -> None: ...
- def get_label(self) -> object: ...
- def set_label(self, s: object) -> None: ...
- def get_zorder(self) -> float: ...
- def set_zorder(self, level: float) -> None: ...
- @property
- def sticky_edges(self) -> _XYPair: ...
- def update_from(self, other: Artist) -> None: ...
- def properties(self) -> dict[str, Any]: ...
- def update(self, props: dict[str, Any]) -> list[Any]: ...
- def _internal_update(self, kwargs: Any) -> list[Any]: ...
- def set(self, **kwargs: Any) -> list[Any]: ...
- def findobj(
- self,
- match: None | Callable[[Artist], bool] | type[Artist] = ...,
- include_self: bool = ...,
- ) -> list[Artist]: ...
- def get_cursor_data(self, event: MouseEvent) -> Any: ...
- def format_cursor_data(self, data: Any) -> str: ...
- def get_mouseover(self) -> bool: ...
- def set_mouseover(self, mouseover: bool) -> None: ...
- @property
- def mouseover(self) -> bool: ...
- @mouseover.setter
- def mouseover(self, mouseover: bool) -> None: ...
-
-class ArtistInspector:
- oorig: Artist | type[Artist]
- o: type[Artist]
- aliasd: dict[str, set[str]]
- def __init__(
- self, o: Artist | type[Artist] | Iterable[Artist | type[Artist]]
- ) -> None: ...
- def get_aliases(self) -> dict[str, set[str]]: ...
- def get_valid_values(self, attr: str) -> str | None: ...
- def get_setters(self) -> list[str]: ...
- @staticmethod
- def number_of_parameters(func: Callable) -> int: ...
- @staticmethod
- def is_alias(method: Callable) -> bool: ...
- def aliased_name(self, s: str) -> str: ...
- def aliased_name_rest(self, s: str, target: str) -> str: ...
- @overload
- def pprint_setters(
- self, prop: None = ..., leadingspace: int = ...
- ) -> list[str]: ...
- @overload
- def pprint_setters(self, prop: str, leadingspace: int = ...) -> str: ...
- @overload
- def pprint_setters_rest(
- self, prop: None = ..., leadingspace: int = ...
- ) -> list[str]: ...
- @overload
- def pprint_setters_rest(self, prop: str, leadingspace: int = ...) -> str: ...
- def properties(self) -> dict[str, Any]: ...
- def pprint_getters(self) -> list[str]: ...
-
-def getp(obj: Artist, property: str | None = ...) -> Any: ...
-
-get = getp
-
-def setp(obj: Artist, *args, file: TextIO | None = ..., **kwargs) -> list[Any] | None: ...
-def kwdoc(artist: Artist | type[Artist] | Iterable[Artist | type[Artist]]) -> str: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/axes/__init__.py b/contrib/python/matplotlib/py3/matplotlib/axes/__init__.py
deleted file mode 100644
index f8c40889bc..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/axes/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from . import _base
-from ._axes import *
-
-# Backcompat.
-from ._axes import Axes as Subplot
-
-
-class _SubplotBaseMeta(type):
- def __instancecheck__(self, obj):
- return (isinstance(obj, _base._AxesBase)
- and obj.get_subplotspec() is not None)
-
-
-class SubplotBase(metaclass=_SubplotBaseMeta):
- pass
-
-
-def subplot_class_factory(cls): return cls
diff --git a/contrib/python/matplotlib/py3/matplotlib/axes/__init__.pyi b/contrib/python/matplotlib/py3/matplotlib/axes/__init__.pyi
deleted file mode 100644
index 7df38b8bde..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/axes/__init__.pyi
+++ /dev/null
@@ -1,16 +0,0 @@
-from typing import TypeVar
-
-from ._axes import Axes as Axes
-
-
-_T = TypeVar("_T")
-
-# Backcompat.
-Subplot = Axes
-
-class _SubplotBaseMeta(type):
- def __instancecheck__(self, obj) -> bool: ...
-
-class SubplotBase(metaclass=_SubplotBaseMeta): ...
-
-def subplot_class_factory(cls: type[_T]) -> type[_T]: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/axes/_axes.py b/contrib/python/matplotlib/py3/matplotlib/axes/_axes.py
deleted file mode 100644
index b4a41099be..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/axes/_axes.py
+++ /dev/null
@@ -1,8454 +0,0 @@
-import functools
-import itertools
-import logging
-import math
-from numbers import Integral, Number, Real
-
-import numpy as np
-from numpy import ma
-
-import matplotlib as mpl
-import matplotlib.category # Register category unit converter as side effect.
-import matplotlib.cbook as cbook
-import matplotlib.collections as mcoll
-import matplotlib.colors as mcolors
-import matplotlib.contour as mcontour
-import matplotlib.dates # noqa # Register date unit converter as side effect.
-import matplotlib.image as mimage
-import matplotlib.legend as mlegend
-import matplotlib.lines as mlines
-import matplotlib.markers as mmarkers
-import matplotlib.mlab as mlab
-import matplotlib.patches as mpatches
-import matplotlib.path as mpath
-import matplotlib.quiver as mquiver
-import matplotlib.stackplot as mstack
-import matplotlib.streamplot as mstream
-import matplotlib.table as mtable
-import matplotlib.text as mtext
-import matplotlib.ticker as mticker
-import matplotlib.transforms as mtransforms
-import matplotlib.tri as mtri
-import matplotlib.units as munits
-from matplotlib import _api, _docstring, _preprocess_data
-from matplotlib.axes._base import (
- _AxesBase, _TransformedBoundsLocator, _process_plot_format)
-from matplotlib.axes._secondary_axes import SecondaryAxis
-from matplotlib.container import BarContainer, ErrorbarContainer, StemContainer
-
-_log = logging.getLogger(__name__)
-
-
-# The axes module contains all the wrappers to plotting functions.
-# All the other methods should go in the _AxesBase class.
-
-
-@_docstring.interpd
-class Axes(_AxesBase):
- """
- An Axes object encapsulates all the elements of an individual (sub-)plot in
- a figure.
-
- It contains most of the (sub-)plot elements: `~.axis.Axis`,
- `~.axis.Tick`, `~.lines.Line2D`, `~.text.Text`, `~.patches.Polygon`, etc.,
- and sets the coordinate system.
-
- Like all visible elements in a figure, Axes is an `.Artist` subclass.
-
- The `Axes` instance supports callbacks through a callbacks attribute which
- is a `~.cbook.CallbackRegistry` instance. The events you can connect to
- are 'xlim_changed' and 'ylim_changed' and the callback will be called with
- func(*ax*) where *ax* is the `Axes` instance.
-
- .. note::
-
- As a user, you do not instantiate Axes directly, but use Axes creation
- methods instead; e.g. from `.pyplot` or `.Figure`:
- `~.pyplot.subplots`, `~.pyplot.subplot_mosaic` or `.Figure.add_axes`.
-
- Attributes
- ----------
- dataLim : `.Bbox`
- The bounding box enclosing all data displayed in the Axes.
- viewLim : `.Bbox`
- The view limits in data coordinates.
-
- """
- ### Labelling, legend and texts
-
- def get_title(self, loc="center"):
- """
- Get an Axes title.
-
- Get one of the three available Axes titles. The available titles
- are positioned above the Axes in the center, flush with the left
- edge, and flush with the right edge.
-
- Parameters
- ----------
- loc : {'center', 'left', 'right'}, str, default: 'center'
- Which title to return.
-
- Returns
- -------
- str
- The title text string.
-
- """
- titles = {'left': self._left_title,
- 'center': self.title,
- 'right': self._right_title}
- title = _api.check_getitem(titles, loc=loc.lower())
- return title.get_text()
-
- def set_title(self, label, fontdict=None, loc=None, pad=None, *, y=None,
- **kwargs):
- """
- Set a title for the Axes.
-
- Set one of the three available Axes titles. The available titles
- are positioned above the Axes in the center, flush with the left
- edge, and flush with the right edge.
-
- Parameters
- ----------
- label : str
- Text to use for the title
-
- fontdict : dict
-
- .. admonition:: Discouraged
-
- The use of *fontdict* is discouraged. Parameters should be passed as
- individual keyword arguments or using dictionary-unpacking
- ``set_title(..., **fontdict)``.
-
- A dictionary controlling the appearance of the title text,
- the default *fontdict* is::
-
- {'fontsize': rcParams['axes.titlesize'],
- 'fontweight': rcParams['axes.titleweight'],
- 'color': rcParams['axes.titlecolor'],
- 'verticalalignment': 'baseline',
- 'horizontalalignment': loc}
-
- loc : {'center', 'left', 'right'}, default: :rc:`axes.titlelocation`
- Which title to set.
-
- y : float, default: :rc:`axes.titley`
- Vertical Axes location for the title (1.0 is the top). If
- None (the default) and :rc:`axes.titley` is also None, y is
- determined automatically to avoid decorators on the Axes.
-
- pad : float, default: :rc:`axes.titlepad`
- The offset of the title from the top of the Axes, in points.
-
- Returns
- -------
- `.Text`
- The matplotlib text instance representing the title
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.text.Text` properties
- Other keyword arguments are text properties, see `.Text` for a list
- of valid text properties.
- """
- if loc is None:
- loc = mpl.rcParams['axes.titlelocation']
-
- if y is None:
- y = mpl.rcParams['axes.titley']
- if y is None:
- y = 1.0
- else:
- self._autotitlepos = False
- kwargs['y'] = y
-
- titles = {'left': self._left_title,
- 'center': self.title,
- 'right': self._right_title}
- title = _api.check_getitem(titles, loc=loc.lower())
- default = {
- 'fontsize': mpl.rcParams['axes.titlesize'],
- 'fontweight': mpl.rcParams['axes.titleweight'],
- 'verticalalignment': 'baseline',
- 'horizontalalignment': loc.lower()}
- titlecolor = mpl.rcParams['axes.titlecolor']
- if not cbook._str_lower_equal(titlecolor, 'auto'):
- default["color"] = titlecolor
- if pad is None:
- pad = mpl.rcParams['axes.titlepad']
- self._set_title_offset_trans(float(pad))
- title.set_text(label)
- title.update(default)
- if fontdict is not None:
- title.update(fontdict)
- title._internal_update(kwargs)
- return title
-
- def get_legend_handles_labels(self, legend_handler_map=None):
- """
- Return handles and labels for legend
-
- ``ax.legend()`` is equivalent to ::
-
- h, l = ax.get_legend_handles_labels()
- ax.legend(h, l)
- """
- # pass through to legend.
- handles, labels = mlegend._get_legend_handles_labels(
- [self], legend_handler_map)
- return handles, labels
-
- @_docstring.dedent_interpd
- def legend(self, *args, **kwargs):
- """
- Place a legend on the Axes.
-
- Call signatures::
-
- legend()
- legend(handles, labels)
- legend(handles=handles)
- legend(labels)
-
- The call signatures correspond to the following different ways to use
- this method:
-
- **1. Automatic detection of elements to be shown in the legend**
-
- The elements to be added to the legend are automatically determined,
- when you do not pass in any extra arguments.
-
- In this case, the labels are taken from the artist. You can specify
- them either at artist creation or by calling the
- :meth:`~.Artist.set_label` method on the artist::
-
- ax.plot([1, 2, 3], label='Inline label')
- ax.legend()
-
- or::
-
- line, = ax.plot([1, 2, 3])
- line.set_label('Label via method')
- ax.legend()
-
- .. note::
- Specific artists can be excluded from the automatic legend element
- selection by using a label starting with an underscore, "_".
- A string starting with an underscore is the default label for all
- artists, so calling `.Axes.legend` without any arguments and
- without setting the labels manually will result in no legend being
- drawn.
-
-
- **2. Explicitly listing the artists and labels in the legend**
-
- For full control of which artists have a legend entry, it is possible
- to pass an iterable of legend artists followed by an iterable of
- legend labels respectively::
-
- ax.legend([line1, line2, line3], ['label1', 'label2', 'label3'])
-
-
- **3. Explicitly listing the artists in the legend**
-
- This is similar to 2, but the labels are taken from the artists'
- label properties. Example::
-
- line1, = ax.plot([1, 2, 3], label='label1')
- line2, = ax.plot([1, 2, 3], label='label2')
- ax.legend(handles=[line1, line2])
-
-
- **4. Labeling existing plot elements**
-
- .. admonition:: Discouraged
-
- This call signature is discouraged, because the relation between
- plot elements and labels is only implicit by their order and can
- easily be mixed up.
-
- To make a legend for all artists on an Axes, call this function with
- an iterable of strings, one for each legend item. For example::
-
- ax.plot([1, 2, 3])
- ax.plot([5, 6, 7])
- ax.legend(['First line', 'Second line'])
-
-
- Parameters
- ----------
- handles : sequence of (`.Artist` or tuple of `.Artist`), optional
- A list of Artists (lines, patches) to be added to the legend.
- Use this together with *labels*, if you need full control on what
- is shown in the legend and the automatic mechanism described above
- is not sufficient.
-
- The length of handles and labels should be the same in this
- case. If they are not, they are truncated to the smaller length.
-
- If an entry contains a tuple, then the legend handler for all Artists in the
- tuple will be placed alongside a single label.
-
- labels : list of str, optional
- A list of labels to show next to the artists.
- Use this together with *handles*, if you need full control on what
- is shown in the legend and the automatic mechanism described above
- is not sufficient.
-
- Returns
- -------
- `~matplotlib.legend.Legend`
-
- Other Parameters
- ----------------
- %(_legend_kw_axes)s
-
- See Also
- --------
- .Figure.legend
-
- Notes
- -----
- Some artists are not supported by this function. See
- :ref:`legend_guide` for details.
-
- Examples
- --------
- .. plot:: gallery/text_labels_and_annotations/legend.py
- """
- handles, labels, kwargs = mlegend._parse_legend_args([self], *args, **kwargs)
- self.legend_ = mlegend.Legend(self, handles, labels, **kwargs)
- self.legend_._remove_method = self._remove_legend
- return self.legend_
-
- def _remove_legend(self, legend):
- self.legend_ = None
-
- def inset_axes(self, bounds, *, transform=None, zorder=5, **kwargs):
- """
- Add a child inset Axes to this existing Axes.
-
- Warnings
- --------
- This method is experimental as of 3.0, and the API may change.
-
- Parameters
- ----------
- bounds : [x0, y0, width, height]
- Lower-left corner of inset Axes, and its width and height.
-
- transform : `.Transform`
- Defaults to `ax.transAxes`, i.e. the units of *rect* are in
- Axes-relative coordinates.
-
- projection : {None, 'aitoff', 'hammer', 'lambert', 'mollweide', \
-'polar', 'rectilinear', str}, optional
- The projection type of the inset `~.axes.Axes`. *str* is the name
- of a custom projection, see `~matplotlib.projections`. The default
- None results in a 'rectilinear' projection.
-
- polar : bool, default: False
- If True, equivalent to projection='polar'.
-
- axes_class : subclass type of `~.axes.Axes`, optional
- The `.axes.Axes` subclass that is instantiated. This parameter
- is incompatible with *projection* and *polar*. See
- :ref:`axisartist_users-guide-index` for examples.
-
- zorder : number
- Defaults to 5 (same as `.Axes.legend`). Adjust higher or lower
- to change whether it is above or below data plotted on the
- parent Axes.
-
- **kwargs
- Other keyword arguments are passed on to the inset Axes class.
-
- Returns
- -------
- ax
- The created `~.axes.Axes` instance.
-
- Examples
- --------
- This example makes two inset Axes, the first is in Axes-relative
- coordinates, and the second in data-coordinates::
-
- fig, ax = plt.subplots()
- ax.plot(range(10))
- axin1 = ax.inset_axes([0.8, 0.1, 0.15, 0.15])
- axin2 = ax.inset_axes(
- [5, 7, 2.3, 2.3], transform=ax.transData)
-
- """
- if transform is None:
- transform = self.transAxes
- kwargs.setdefault('label', 'inset_axes')
-
- # This puts the rectangle into figure-relative coordinates.
- inset_locator = _TransformedBoundsLocator(bounds, transform)
- bounds = inset_locator(self, None).bounds
- projection_class, pkw = self.figure._process_projection_requirements(**kwargs)
- inset_ax = projection_class(self.figure, bounds, zorder=zorder, **pkw)
-
- # this locator lets the axes move if in data coordinates.
- # it gets called in `ax.apply_aspect() (of all places)
- inset_ax.set_axes_locator(inset_locator)
-
- self.add_child_axes(inset_ax)
-
- return inset_ax
-
- @_docstring.dedent_interpd
- def indicate_inset(self, bounds, inset_ax=None, *, transform=None,
- facecolor='none', edgecolor='0.5', alpha=0.5,
- zorder=4.99, **kwargs):
- """
- Add an inset indicator to the Axes. This is a rectangle on the plot
- at the position indicated by *bounds* that optionally has lines that
- connect the rectangle to an inset Axes (`.Axes.inset_axes`).
-
- Warnings
- --------
- This method is experimental as of 3.0, and the API may change.
-
- Parameters
- ----------
- bounds : [x0, y0, width, height]
- Lower-left corner of rectangle to be marked, and its width
- and height.
-
- inset_ax : `.Axes`
- An optional inset Axes to draw connecting lines to. Two lines are
- drawn connecting the indicator box to the inset Axes on corners
- chosen so as to not overlap with the indicator box.
-
- transform : `.Transform`
- Transform for the rectangle coordinates. Defaults to
- `ax.transAxes`, i.e. the units of *rect* are in Axes-relative
- coordinates.
-
- facecolor : color, default: 'none'
- Facecolor of the rectangle.
-
- edgecolor : color, default: '0.5'
- Color of the rectangle and color of the connecting lines.
-
- alpha : float, default: 0.5
- Transparency of the rectangle and connector lines.
-
- zorder : float, default: 4.99
- Drawing order of the rectangle and connector lines. The default,
- 4.99, is just below the default level of inset Axes.
-
- **kwargs
- Other keyword arguments are passed on to the `.Rectangle` patch:
-
- %(Rectangle:kwdoc)s
-
- Returns
- -------
- rectangle_patch : `.patches.Rectangle`
- The indicator frame.
-
- connector_lines : 4-tuple of `.patches.ConnectionPatch`
- The four connector lines connecting to (lower_left, upper_left,
- lower_right upper_right) corners of *inset_ax*. Two lines are
- set with visibility to *False*, but the user can set the
- visibility to True if the automatic choice is not deemed correct.
-
- """
- # to make the axes connectors work, we need to apply the aspect to
- # the parent axes.
- self.apply_aspect()
-
- if transform is None:
- transform = self.transData
- kwargs.setdefault('label', '_indicate_inset')
-
- x, y, width, height = bounds
- rectangle_patch = mpatches.Rectangle(
- (x, y), width, height,
- facecolor=facecolor, edgecolor=edgecolor, alpha=alpha,
- zorder=zorder, transform=transform, **kwargs)
- self.add_patch(rectangle_patch)
-
- connects = []
-
- if inset_ax is not None:
- # connect the inset_axes to the rectangle
- for xy_inset_ax in [(0, 0), (0, 1), (1, 0), (1, 1)]:
- # inset_ax positions are in axes coordinates
- # The 0, 1 values define the four edges if the inset_ax
- # lower_left, upper_left, lower_right upper_right.
- ex, ey = xy_inset_ax
- if self.xaxis.get_inverted():
- ex = 1 - ex
- if self.yaxis.get_inverted():
- ey = 1 - ey
- xy_data = x + ex * width, y + ey * height
- p = mpatches.ConnectionPatch(
- xyA=xy_inset_ax, coordsA=inset_ax.transAxes,
- xyB=xy_data, coordsB=self.transData,
- arrowstyle="-", zorder=zorder,
- edgecolor=edgecolor, alpha=alpha)
- connects.append(p)
- self.add_patch(p)
-
- # decide which two of the lines to keep visible....
- pos = inset_ax.get_position()
- bboxins = pos.transformed(self.figure.transSubfigure)
- rectbbox = mtransforms.Bbox.from_bounds(
- *bounds
- ).transformed(transform)
- x0 = rectbbox.x0 < bboxins.x0
- x1 = rectbbox.x1 < bboxins.x1
- y0 = rectbbox.y0 < bboxins.y0
- y1 = rectbbox.y1 < bboxins.y1
- connects[0].set_visible(x0 ^ y0)
- connects[1].set_visible(x0 == y1)
- connects[2].set_visible(x1 == y0)
- connects[3].set_visible(x1 ^ y1)
-
- return rectangle_patch, tuple(connects) if connects else None
-
- def indicate_inset_zoom(self, inset_ax, **kwargs):
- """
- Add an inset indicator rectangle to the Axes based on the axis
- limits for an *inset_ax* and draw connectors between *inset_ax*
- and the rectangle.
-
- Warnings
- --------
- This method is experimental as of 3.0, and the API may change.
-
- Parameters
- ----------
- inset_ax : `.Axes`
- Inset Axes to draw connecting lines to. Two lines are
- drawn connecting the indicator box to the inset Axes on corners
- chosen so as to not overlap with the indicator box.
-
- **kwargs
- Other keyword arguments are passed on to `.Axes.indicate_inset`
-
- Returns
- -------
- rectangle_patch : `.patches.Rectangle`
- Rectangle artist.
-
- connector_lines : 4-tuple of `.patches.ConnectionPatch`
- Each of four connector lines coming from the rectangle drawn on
- this axis, in the order lower left, upper left, lower right,
- upper right.
- Two are set with visibility to *False*, but the user can
- set the visibility to *True* if the automatic choice is not deemed
- correct.
- """
-
- xlim = inset_ax.get_xlim()
- ylim = inset_ax.get_ylim()
- rect = (xlim[0], ylim[0], xlim[1] - xlim[0], ylim[1] - ylim[0])
- return self.indicate_inset(rect, inset_ax, **kwargs)
-
- @_docstring.dedent_interpd
- def secondary_xaxis(self, location, *, functions=None, **kwargs):
- """
- Add a second x-axis to this `~.axes.Axes`.
-
- For example if we want to have a second scale for the data plotted on
- the xaxis.
-
- %(_secax_docstring)s
-
- Examples
- --------
- The main axis shows frequency, and the secondary axis shows period.
-
- .. plot::
-
- fig, ax = plt.subplots()
- ax.loglog(range(1, 360, 5), range(1, 360, 5))
- ax.set_xlabel('frequency [Hz]')
-
- def invert(x):
- # 1/x with special treatment of x == 0
- x = np.array(x).astype(float)
- near_zero = np.isclose(x, 0)
- x[near_zero] = np.inf
- x[~near_zero] = 1 / x[~near_zero]
- return x
-
- # the inverse of 1/x is itself
- secax = ax.secondary_xaxis('top', functions=(invert, invert))
- secax.set_xlabel('Period [s]')
- plt.show()
- """
- if location in ['top', 'bottom'] or isinstance(location, Real):
- secondary_ax = SecondaryAxis(self, 'x', location, functions,
- **kwargs)
- self.add_child_axes(secondary_ax)
- return secondary_ax
- else:
- raise ValueError('secondary_xaxis location must be either '
- 'a float or "top"/"bottom"')
-
- @_docstring.dedent_interpd
- def secondary_yaxis(self, location, *, functions=None, **kwargs):
- """
- Add a second y-axis to this `~.axes.Axes`.
-
- For example if we want to have a second scale for the data plotted on
- the yaxis.
-
- %(_secax_docstring)s
-
- Examples
- --------
- Add a secondary Axes that converts from radians to degrees
-
- .. plot::
-
- fig, ax = plt.subplots()
- ax.plot(range(1, 360, 5), range(1, 360, 5))
- ax.set_ylabel('degrees')
- secax = ax.secondary_yaxis('right', functions=(np.deg2rad,
- np.rad2deg))
- secax.set_ylabel('radians')
- """
- if location in ['left', 'right'] or isinstance(location, Real):
- secondary_ax = SecondaryAxis(self, 'y', location,
- functions, **kwargs)
- self.add_child_axes(secondary_ax)
- return secondary_ax
- else:
- raise ValueError('secondary_yaxis location must be either '
- 'a float or "left"/"right"')
-
- @_docstring.dedent_interpd
- def text(self, x, y, s, fontdict=None, **kwargs):
- """
- Add text to the Axes.
-
- Add the text *s* to the Axes at location *x*, *y* in data coordinates.
-
- Parameters
- ----------
- x, y : float
- The position to place the text. By default, this is in data
- coordinates. The coordinate system can be changed using the
- *transform* parameter.
-
- s : str
- The text.
-
- fontdict : dict, default: None
-
- .. admonition:: Discouraged
-
- The use of *fontdict* is discouraged. Parameters should be passed as
- individual keyword arguments or using dictionary-unpacking
- ``text(..., **fontdict)``.
-
- A dictionary to override the default text properties. If fontdict
- is None, the defaults are determined by `.rcParams`.
-
- Returns
- -------
- `.Text`
- The created `.Text` instance.
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.text.Text` properties.
- Other miscellaneous text parameters.
-
- %(Text:kwdoc)s
-
- Examples
- --------
- Individual keyword arguments can be used to override any given
- parameter::
-
- >>> text(x, y, s, fontsize=12)
-
- The default transform specifies that text is in data coords,
- alternatively, you can specify text in axis coords ((0, 0) is
- lower-left and (1, 1) is upper-right). The example below places
- text in the center of the Axes::
-
- >>> text(0.5, 0.5, 'matplotlib', horizontalalignment='center',
- ... verticalalignment='center', transform=ax.transAxes)
-
- You can put a rectangular box around the text instance (e.g., to
- set a background color) by using the keyword *bbox*. *bbox* is
- a dictionary of `~matplotlib.patches.Rectangle`
- properties. For example::
-
- >>> text(x, y, s, bbox=dict(facecolor='red', alpha=0.5))
- """
- effective_kwargs = {
- 'verticalalignment': 'baseline',
- 'horizontalalignment': 'left',
- 'transform': self.transData,
- 'clip_on': False,
- **(fontdict if fontdict is not None else {}),
- **kwargs,
- }
- t = mtext.Text(x, y, text=s, **effective_kwargs)
- if t.get_clip_path() is None:
- t.set_clip_path(self.patch)
- self._add_text(t)
- return t
-
- @_docstring.dedent_interpd
- def annotate(self, text, xy, xytext=None, xycoords='data', textcoords=None,
- arrowprops=None, annotation_clip=None, **kwargs):
- # Signature must match Annotation. This is verified in
- # test_annotate_signature().
- a = mtext.Annotation(text, xy, xytext=xytext, xycoords=xycoords,
- textcoords=textcoords, arrowprops=arrowprops,
- annotation_clip=annotation_clip, **kwargs)
- a.set_transform(mtransforms.IdentityTransform())
- if kwargs.get('clip_on', False) and a.get_clip_path() is None:
- a.set_clip_path(self.patch)
- self._add_text(a)
- return a
- annotate.__doc__ = mtext.Annotation.__init__.__doc__
- #### Lines and spans
-
- @_docstring.dedent_interpd
- def axhline(self, y=0, xmin=0, xmax=1, **kwargs):
- """
- Add a horizontal line across the Axes.
-
- Parameters
- ----------
- y : float, default: 0
- y position in data coordinates of the horizontal line.
-
- xmin : float, default: 0
- Should be between 0 and 1, 0 being the far left of the plot, 1 the
- far right of the plot.
-
- xmax : float, default: 1
- Should be between 0 and 1, 0 being the far left of the plot, 1 the
- far right of the plot.
-
- Returns
- -------
- `~matplotlib.lines.Line2D`
-
- Other Parameters
- ----------------
- **kwargs
- Valid keyword arguments are `.Line2D` properties, except for
- 'transform':
-
- %(Line2D:kwdoc)s
-
- See Also
- --------
- hlines : Add horizontal lines in data coordinates.
- axhspan : Add a horizontal span (rectangle) across the axis.
- axline : Add a line with an arbitrary slope.
-
- Examples
- --------
- * draw a thick red hline at 'y' = 0 that spans the xrange::
-
- >>> axhline(linewidth=4, color='r')
-
- * draw a default hline at 'y' = 1 that spans the xrange::
-
- >>> axhline(y=1)
-
- * draw a default hline at 'y' = .5 that spans the middle half of
- the xrange::
-
- >>> axhline(y=.5, xmin=0.25, xmax=0.75)
- """
- self._check_no_units([xmin, xmax], ['xmin', 'xmax'])
- if "transform" in kwargs:
- raise ValueError("'transform' is not allowed as a keyword "
- "argument; axhline generates its own transform.")
- ymin, ymax = self.get_ybound()
-
- # Strip away the units for comparison with non-unitized bounds.
- yy, = self._process_unit_info([("y", y)], kwargs)
- scaley = (yy < ymin) or (yy > ymax)
-
- trans = self.get_yaxis_transform(which='grid')
- l = mlines.Line2D([xmin, xmax], [y, y], transform=trans, **kwargs)
- self.add_line(l)
- if scaley:
- self._request_autoscale_view("y")
- return l
-
- @_docstring.dedent_interpd
- def axvline(self, x=0, ymin=0, ymax=1, **kwargs):
- """
- Add a vertical line across the Axes.
-
- Parameters
- ----------
- x : float, default: 0
- x position in data coordinates of the vertical line.
-
- ymin : float, default: 0
- Should be between 0 and 1, 0 being the bottom of the plot, 1 the
- top of the plot.
-
- ymax : float, default: 1
- Should be between 0 and 1, 0 being the bottom of the plot, 1 the
- top of the plot.
-
- Returns
- -------
- `~matplotlib.lines.Line2D`
-
- Other Parameters
- ----------------
- **kwargs
- Valid keyword arguments are `.Line2D` properties, except for
- 'transform':
-
- %(Line2D:kwdoc)s
-
- See Also
- --------
- vlines : Add vertical lines in data coordinates.
- axvspan : Add a vertical span (rectangle) across the axis.
- axline : Add a line with an arbitrary slope.
-
- Examples
- --------
- * draw a thick red vline at *x* = 0 that spans the yrange::
-
- >>> axvline(linewidth=4, color='r')
-
- * draw a default vline at *x* = 1 that spans the yrange::
-
- >>> axvline(x=1)
-
- * draw a default vline at *x* = .5 that spans the middle half of
- the yrange::
-
- >>> axvline(x=.5, ymin=0.25, ymax=0.75)
- """
- self._check_no_units([ymin, ymax], ['ymin', 'ymax'])
- if "transform" in kwargs:
- raise ValueError("'transform' is not allowed as a keyword "
- "argument; axvline generates its own transform.")
- xmin, xmax = self.get_xbound()
-
- # Strip away the units for comparison with non-unitized bounds.
- xx, = self._process_unit_info([("x", x)], kwargs)
- scalex = (xx < xmin) or (xx > xmax)
-
- trans = self.get_xaxis_transform(which='grid')
- l = mlines.Line2D([x, x], [ymin, ymax], transform=trans, **kwargs)
- self.add_line(l)
- if scalex:
- self._request_autoscale_view("x")
- return l
-
- @staticmethod
- def _check_no_units(vals, names):
- # Helper method to check that vals are not unitized
- for val, name in zip(vals, names):
- if not munits._is_natively_supported(val):
- raise ValueError(f"{name} must be a single scalar value, "
- f"but got {val}")
-
- @_docstring.dedent_interpd
- def axline(self, xy1, xy2=None, *, slope=None, **kwargs):
- """
- Add an infinitely long straight line.
-
- The line can be defined either by two points *xy1* and *xy2*, or
- by one point *xy1* and a *slope*.
-
- This draws a straight line "on the screen", regardless of the x and y
- scales, and is thus also suitable for drawing exponential decays in
- semilog plots, power laws in loglog plots, etc. However, *slope*
- should only be used with linear scales; It has no clear meaning for
- all other scales, and thus the behavior is undefined. Please specify
- the line using the points *xy1*, *xy2* for non-linear scales.
-
- The *transform* keyword argument only applies to the points *xy1*,
- *xy2*. The *slope* (if given) is always in data coordinates. This can
- be used e.g. with ``ax.transAxes`` for drawing grid lines with a fixed
- slope.
-
- Parameters
- ----------
- xy1, xy2 : (float, float)
- Points for the line to pass through.
- Either *xy2* or *slope* has to be given.
- slope : float, optional
- The slope of the line. Either *xy2* or *slope* has to be given.
-
- Returns
- -------
- `.Line2D`
-
- Other Parameters
- ----------------
- **kwargs
- Valid kwargs are `.Line2D` properties
-
- %(Line2D:kwdoc)s
-
- See Also
- --------
- axhline : for horizontal lines
- axvline : for vertical lines
-
- Examples
- --------
- Draw a thick red line passing through (0, 0) and (1, 1)::
-
- >>> axline((0, 0), (1, 1), linewidth=4, color='r')
- """
- if slope is not None and (self.get_xscale() != 'linear' or
- self.get_yscale() != 'linear'):
- raise TypeError("'slope' cannot be used with non-linear scales")
-
- datalim = [xy1] if xy2 is None else [xy1, xy2]
- if "transform" in kwargs:
- # if a transform is passed (i.e. line points not in data space),
- # data limits should not be adjusted.
- datalim = []
-
- line = mlines.AxLine(xy1, xy2, slope, **kwargs)
- # Like add_line, but correctly handling data limits.
- self._set_artist_props(line)
- if line.get_clip_path() is None:
- line.set_clip_path(self.patch)
- if not line.get_label():
- line.set_label(f"_child{len(self._children)}")
- self._children.append(line)
- line._remove_method = self._children.remove
- self.update_datalim(datalim)
-
- self._request_autoscale_view()
- return line
-
- @_docstring.dedent_interpd
- def axhspan(self, ymin, ymax, xmin=0, xmax=1, **kwargs):
- """
- Add a horizontal span (rectangle) across the Axes.
-
- The rectangle spans from *ymin* to *ymax* vertically, and, by default,
- the whole x-axis horizontally. The x-span can be set using *xmin*
- (default: 0) and *xmax* (default: 1) which are in axis units; e.g.
- ``xmin = 0.5`` always refers to the middle of the x-axis regardless of
- the limits set by `~.Axes.set_xlim`.
-
- Parameters
- ----------
- ymin : float
- Lower y-coordinate of the span, in data units.
- ymax : float
- Upper y-coordinate of the span, in data units.
- xmin : float, default: 0
- Lower x-coordinate of the span, in x-axis (0-1) units.
- xmax : float, default: 1
- Upper x-coordinate of the span, in x-axis (0-1) units.
-
- Returns
- -------
- `~matplotlib.patches.Polygon`
- Horizontal span (rectangle) from (xmin, ymin) to (xmax, ymax).
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.patches.Polygon` properties
-
- %(Polygon:kwdoc)s
-
- See Also
- --------
- axvspan : Add a vertical span across the Axes.
- """
- # Strip units away.
- self._check_no_units([xmin, xmax], ['xmin', 'xmax'])
- (ymin, ymax), = self._process_unit_info([("y", [ymin, ymax])], kwargs)
-
- verts = (xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)
- p = mpatches.Polygon(verts, **kwargs)
- p.set_transform(self.get_yaxis_transform(which="grid"))
- self.add_patch(p)
- self._request_autoscale_view("y")
- return p
-
- @_docstring.dedent_interpd
- def axvspan(self, xmin, xmax, ymin=0, ymax=1, **kwargs):
- """
- Add a vertical span (rectangle) across the Axes.
-
- The rectangle spans from *xmin* to *xmax* horizontally, and, by
- default, the whole y-axis vertically. The y-span can be set using
- *ymin* (default: 0) and *ymax* (default: 1) which are in axis units;
- e.g. ``ymin = 0.5`` always refers to the middle of the y-axis
- regardless of the limits set by `~.Axes.set_ylim`.
-
- Parameters
- ----------
- xmin : float
- Lower x-coordinate of the span, in data units.
- xmax : float
- Upper x-coordinate of the span, in data units.
- ymin : float, default: 0
- Lower y-coordinate of the span, in y-axis units (0-1).
- ymax : float, default: 1
- Upper y-coordinate of the span, in y-axis units (0-1).
-
- Returns
- -------
- `~matplotlib.patches.Polygon`
- Vertical span (rectangle) from (xmin, ymin) to (xmax, ymax).
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.patches.Polygon` properties
-
- %(Polygon:kwdoc)s
-
- See Also
- --------
- axhspan : Add a horizontal span across the Axes.
-
- Examples
- --------
- Draw a vertical, green, translucent rectangle from x = 1.25 to
- x = 1.55 that spans the yrange of the Axes.
-
- >>> axvspan(1.25, 1.55, facecolor='g', alpha=0.5)
-
- """
- # Strip units away.
- self._check_no_units([ymin, ymax], ['ymin', 'ymax'])
- (xmin, xmax), = self._process_unit_info([("x", [xmin, xmax])], kwargs)
-
- verts = [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)]
- p = mpatches.Polygon(verts, **kwargs)
- p.set_transform(self.get_xaxis_transform(which="grid"))
- p.get_path()._interpolation_steps = 100
- self.add_patch(p)
- self._request_autoscale_view("x")
- return p
-
- @_preprocess_data(replace_names=["y", "xmin", "xmax", "colors"],
- label_namer="y")
- def hlines(self, y, xmin, xmax, colors=None, linestyles='solid',
- label='', **kwargs):
- """
- Plot horizontal lines at each *y* from *xmin* to *xmax*.
-
- Parameters
- ----------
- y : float or array-like
- y-indexes where to plot the lines.
-
- xmin, xmax : float or array-like
- Respective beginning and end of each line. If scalars are
- provided, all lines will have the same length.
-
- colors : color or list of colors, default: :rc:`lines.color`
-
- linestyles : {'solid', 'dashed', 'dashdot', 'dotted'}, default: 'solid'
-
- label : str, default: ''
-
- Returns
- -------
- `~matplotlib.collections.LineCollection`
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
- **kwargs : `~matplotlib.collections.LineCollection` properties.
-
- See Also
- --------
- vlines : vertical lines
- axhline : horizontal line across the Axes
- """
-
- # We do the conversion first since not all unitized data is uniform
- xmin, xmax, y = self._process_unit_info(
- [("x", xmin), ("x", xmax), ("y", y)], kwargs)
-
- if not np.iterable(y):
- y = [y]
- if not np.iterable(xmin):
- xmin = [xmin]
- if not np.iterable(xmax):
- xmax = [xmax]
-
- # Create and combine masked_arrays from input
- y, xmin, xmax = cbook._combine_masks(y, xmin, xmax)
- y = np.ravel(y)
- xmin = np.ravel(xmin)
- xmax = np.ravel(xmax)
-
- masked_verts = np.ma.empty((len(y), 2, 2))
- masked_verts[:, 0, 0] = xmin
- masked_verts[:, 0, 1] = y
- masked_verts[:, 1, 0] = xmax
- masked_verts[:, 1, 1] = y
-
- lines = mcoll.LineCollection(masked_verts, colors=colors,
- linestyles=linestyles, label=label)
- self.add_collection(lines, autolim=False)
- lines._internal_update(kwargs)
-
- if len(y) > 0:
- # Extreme values of xmin/xmax/y. Using masked_verts here handles
- # the case of y being a masked *object* array (as can be generated
- # e.g. by errorbar()), which would make nanmin/nanmax stumble.
- updatex = True
- updatey = True
- if self.name == "rectilinear":
- datalim = lines.get_datalim(self.transData)
- t = lines.get_transform()
- updatex, updatey = t.contains_branch_seperately(self.transData)
- minx = np.nanmin(datalim.xmin)
- maxx = np.nanmax(datalim.xmax)
- miny = np.nanmin(datalim.ymin)
- maxy = np.nanmax(datalim.ymax)
- else:
- minx = np.nanmin(masked_verts[..., 0])
- maxx = np.nanmax(masked_verts[..., 0])
- miny = np.nanmin(masked_verts[..., 1])
- maxy = np.nanmax(masked_verts[..., 1])
-
- corners = (minx, miny), (maxx, maxy)
- self.update_datalim(corners, updatex, updatey)
- self._request_autoscale_view()
- return lines
-
- @_preprocess_data(replace_names=["x", "ymin", "ymax", "colors"],
- label_namer="x")
- def vlines(self, x, ymin, ymax, colors=None, linestyles='solid',
- label='', **kwargs):
- """
- Plot vertical lines at each *x* from *ymin* to *ymax*.
-
- Parameters
- ----------
- x : float or array-like
- x-indexes where to plot the lines.
-
- ymin, ymax : float or array-like
- Respective beginning and end of each line. If scalars are
- provided, all lines will have the same length.
-
- colors : color or list of colors, default: :rc:`lines.color`
-
- linestyles : {'solid', 'dashed', 'dashdot', 'dotted'}, default: 'solid'
-
- label : str, default: ''
-
- Returns
- -------
- `~matplotlib.collections.LineCollection`
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
- **kwargs : `~matplotlib.collections.LineCollection` properties.
-
- See Also
- --------
- hlines : horizontal lines
- axvline : vertical line across the Axes
- """
-
- # We do the conversion first since not all unitized data is uniform
- x, ymin, ymax = self._process_unit_info(
- [("x", x), ("y", ymin), ("y", ymax)], kwargs)
-
- if not np.iterable(x):
- x = [x]
- if not np.iterable(ymin):
- ymin = [ymin]
- if not np.iterable(ymax):
- ymax = [ymax]
-
- # Create and combine masked_arrays from input
- x, ymin, ymax = cbook._combine_masks(x, ymin, ymax)
- x = np.ravel(x)
- ymin = np.ravel(ymin)
- ymax = np.ravel(ymax)
-
- masked_verts = np.ma.empty((len(x), 2, 2))
- masked_verts[:, 0, 0] = x
- masked_verts[:, 0, 1] = ymin
- masked_verts[:, 1, 0] = x
- masked_verts[:, 1, 1] = ymax
-
- lines = mcoll.LineCollection(masked_verts, colors=colors,
- linestyles=linestyles, label=label)
- self.add_collection(lines, autolim=False)
- lines._internal_update(kwargs)
-
- if len(x) > 0:
- # Extreme values of x/ymin/ymax. Using masked_verts here handles
- # the case of x being a masked *object* array (as can be generated
- # e.g. by errorbar()), which would make nanmin/nanmax stumble.
- updatex = True
- updatey = True
- if self.name == "rectilinear":
- datalim = lines.get_datalim(self.transData)
- t = lines.get_transform()
- updatex, updatey = t.contains_branch_seperately(self.transData)
- minx = np.nanmin(datalim.xmin)
- maxx = np.nanmax(datalim.xmax)
- miny = np.nanmin(datalim.ymin)
- maxy = np.nanmax(datalim.ymax)
- else:
- minx = np.nanmin(masked_verts[..., 0])
- maxx = np.nanmax(masked_verts[..., 0])
- miny = np.nanmin(masked_verts[..., 1])
- maxy = np.nanmax(masked_verts[..., 1])
-
- corners = (minx, miny), (maxx, maxy)
- self.update_datalim(corners, updatex, updatey)
- self._request_autoscale_view()
- return lines
-
- @_preprocess_data(replace_names=["positions", "lineoffsets",
- "linelengths", "linewidths",
- "colors", "linestyles"])
- @_docstring.dedent_interpd
- def eventplot(self, positions, orientation='horizontal', lineoffsets=1,
- linelengths=1, linewidths=None, colors=None, alpha=None,
- linestyles='solid', **kwargs):
- """
- Plot identical parallel lines at the given positions.
-
- This type of plot is commonly used in neuroscience for representing
- neural events, where it is usually called a spike raster, dot raster,
- or raster plot.
-
- However, it is useful in any situation where you wish to show the
- timing or position of multiple sets of discrete events, such as the
- arrival times of people to a business on each day of the month or the
- date of hurricanes each year of the last century.
-
- Parameters
- ----------
- positions : array-like or list of array-like
- A 1D array-like defines the positions of one sequence of events.
-
- Multiple groups of events may be passed as a list of array-likes.
- Each group can be styled independently by passing lists of values
- to *lineoffsets*, *linelengths*, *linewidths*, *colors* and
- *linestyles*.
-
- Note that *positions* can be a 2D array, but in practice different
- event groups usually have different counts so that one will use a
- list of different-length arrays rather than a 2D array.
-
- orientation : {'horizontal', 'vertical'}, default: 'horizontal'
- The direction of the event sequence:
-
- - 'horizontal': the events are arranged horizontally.
- The indicator lines are vertical.
- - 'vertical': the events are arranged vertically.
- The indicator lines are horizontal.
-
- lineoffsets : float or array-like, default: 1
- The offset of the center of the lines from the origin, in the
- direction orthogonal to *orientation*.
-
- If *positions* is 2D, this can be a sequence with length matching
- the length of *positions*.
-
- linelengths : float or array-like, default: 1
- The total height of the lines (i.e. the lines stretches from
- ``lineoffset - linelength/2`` to ``lineoffset + linelength/2``).
-
- If *positions* is 2D, this can be a sequence with length matching
- the length of *positions*.
-
- linewidths : float or array-like, default: :rc:`lines.linewidth`
- The line width(s) of the event lines, in points.
-
- If *positions* is 2D, this can be a sequence with length matching
- the length of *positions*.
-
- colors : color or list of colors, default: :rc:`lines.color`
- The color(s) of the event lines.
-
- If *positions* is 2D, this can be a sequence with length matching
- the length of *positions*.
-
- alpha : float or array-like, default: 1
- The alpha blending value(s), between 0 (transparent) and 1
- (opaque).
-
- If *positions* is 2D, this can be a sequence with length matching
- the length of *positions*.
-
- linestyles : str or tuple or list of such values, default: 'solid'
- Default is 'solid'. Valid strings are ['solid', 'dashed',
- 'dashdot', 'dotted', '-', '--', '-.', ':']. Dash tuples
- should be of the form::
-
- (offset, onoffseq),
-
- where *onoffseq* is an even length tuple of on and off ink
- in points.
-
- If *positions* is 2D, this can be a sequence with length matching
- the length of *positions*.
-
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Other keyword arguments are line collection properties. See
- `.LineCollection` for a list of the valid properties.
-
- Returns
- -------
- list of `.EventCollection`
- The `.EventCollection` that were added.
-
- Notes
- -----
- For *linelengths*, *linewidths*, *colors*, *alpha* and *linestyles*, if
- only a single value is given, that value is applied to all lines. If an
- array-like is given, it must have the same length as *positions*, and
- each value will be applied to the corresponding row of the array.
-
- Examples
- --------
- .. plot:: gallery/lines_bars_and_markers/eventplot_demo.py
- """
-
- lineoffsets, linelengths = self._process_unit_info(
- [("y", lineoffsets), ("y", linelengths)], kwargs)
-
- # fix positions, noting that it can be a list of lists:
- if not np.iterable(positions):
- positions = [positions]
- elif any(np.iterable(position) for position in positions):
- positions = [np.asanyarray(position) for position in positions]
- else:
- positions = [np.asanyarray(positions)]
-
- poss = []
- for position in positions:
- poss += self._process_unit_info([("x", position)], kwargs)
- positions = poss
-
- # prevent 'singular' keys from **kwargs dict from overriding the effect
- # of 'plural' keyword arguments (e.g. 'color' overriding 'colors')
- colors = cbook._local_over_kwdict(colors, kwargs, 'color')
- linewidths = cbook._local_over_kwdict(linewidths, kwargs, 'linewidth')
- linestyles = cbook._local_over_kwdict(linestyles, kwargs, 'linestyle')
-
- if not np.iterable(lineoffsets):
- lineoffsets = [lineoffsets]
- if not np.iterable(linelengths):
- linelengths = [linelengths]
- if not np.iterable(linewidths):
- linewidths = [linewidths]
- if not np.iterable(colors):
- colors = [colors]
- if not np.iterable(alpha):
- alpha = [alpha]
- if hasattr(linestyles, 'lower') or not np.iterable(linestyles):
- linestyles = [linestyles]
-
- lineoffsets = np.asarray(lineoffsets)
- linelengths = np.asarray(linelengths)
- linewidths = np.asarray(linewidths)
-
- if len(lineoffsets) == 0:
- raise ValueError('lineoffsets cannot be empty')
- if len(linelengths) == 0:
- raise ValueError('linelengths cannot be empty')
- if len(linestyles) == 0:
- raise ValueError('linestyles cannot be empty')
- if len(linewidths) == 0:
- raise ValueError('linewidths cannot be empty')
- if len(alpha) == 0:
- raise ValueError('alpha cannot be empty')
- if len(colors) == 0:
- colors = [None]
- try:
- # Early conversion of the colors into RGBA values to take care
- # of cases like colors='0.5' or colors='C1'. (Issue #8193)
- colors = mcolors.to_rgba_array(colors)
- except ValueError:
- # Will fail if any element of *colors* is None. But as long
- # as len(colors) == 1 or len(positions), the rest of the
- # code should process *colors* properly.
- pass
-
- if len(lineoffsets) == 1 and len(positions) != 1:
- lineoffsets = np.tile(lineoffsets, len(positions))
- lineoffsets[0] = 0
- lineoffsets = np.cumsum(lineoffsets)
- if len(linelengths) == 1:
- linelengths = np.tile(linelengths, len(positions))
- if len(linewidths) == 1:
- linewidths = np.tile(linewidths, len(positions))
- if len(colors) == 1:
- colors = list(colors) * len(positions)
- if len(alpha) == 1:
- alpha = list(alpha) * len(positions)
- if len(linestyles) == 1:
- linestyles = [linestyles] * len(positions)
-
- if len(lineoffsets) != len(positions):
- raise ValueError('lineoffsets and positions are unequal sized '
- 'sequences')
- if len(linelengths) != len(positions):
- raise ValueError('linelengths and positions are unequal sized '
- 'sequences')
- if len(linewidths) != len(positions):
- raise ValueError('linewidths and positions are unequal sized '
- 'sequences')
- if len(colors) != len(positions):
- raise ValueError('colors and positions are unequal sized '
- 'sequences')
- if len(alpha) != len(positions):
- raise ValueError('alpha and positions are unequal sized '
- 'sequences')
- if len(linestyles) != len(positions):
- raise ValueError('linestyles and positions are unequal sized '
- 'sequences')
-
- colls = []
- for position, lineoffset, linelength, linewidth, color, alpha_, \
- linestyle in \
- zip(positions, lineoffsets, linelengths, linewidths,
- colors, alpha, linestyles):
- coll = mcoll.EventCollection(position,
- orientation=orientation,
- lineoffset=lineoffset,
- linelength=linelength,
- linewidth=linewidth,
- color=color,
- alpha=alpha_,
- linestyle=linestyle)
- self.add_collection(coll, autolim=False)
- coll._internal_update(kwargs)
- colls.append(coll)
-
- if len(positions) > 0:
- # try to get min/max
- min_max = [(np.min(_p), np.max(_p)) for _p in positions
- if len(_p) > 0]
- # if we have any non-empty positions, try to autoscale
- if len(min_max) > 0:
- mins, maxes = zip(*min_max)
- minpos = np.min(mins)
- maxpos = np.max(maxes)
-
- minline = (lineoffsets - linelengths).min()
- maxline = (lineoffsets + linelengths).max()
-
- if orientation == "vertical":
- corners = (minline, minpos), (maxline, maxpos)
- else: # "horizontal"
- corners = (minpos, minline), (maxpos, maxline)
- self.update_datalim(corners)
- self._request_autoscale_view()
-
- return colls
-
- #### Basic plotting
-
- # Uses a custom implementation of data-kwarg handling in
- # _process_plot_var_args.
- @_docstring.dedent_interpd
- def plot(self, *args, scalex=True, scaley=True, data=None, **kwargs):
- """
- Plot y versus x as lines and/or markers.
-
- Call signatures::
-
- plot([x], y, [fmt], *, data=None, **kwargs)
- plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
-
- The coordinates of the points or line nodes are given by *x*, *y*.
-
- The optional parameter *fmt* is a convenient way for defining basic
- formatting like color, marker and linestyle. It's a shortcut string
- notation described in the *Notes* section below.
-
- >>> plot(x, y) # plot x and y using default line style and color
- >>> plot(x, y, 'bo') # plot x and y using blue circle markers
- >>> plot(y) # plot y using x as index array 0..N-1
- >>> plot(y, 'r+') # ditto, but with red plusses
-
- You can use `.Line2D` properties as keyword arguments for more
- control on the appearance. Line properties and *fmt* can be mixed.
- The following two calls yield identical results:
-
- >>> plot(x, y, 'go--', linewidth=2, markersize=12)
- >>> plot(x, y, color='green', marker='o', linestyle='dashed',
- ... linewidth=2, markersize=12)
-
- When conflicting with *fmt*, keyword arguments take precedence.
-
-
- **Plotting labelled data**
-
- There's a convenient way for plotting objects with labelled data (i.e.
- data that can be accessed by index ``obj['y']``). Instead of giving
- the data in *x* and *y*, you can provide the object in the *data*
- parameter and just give the labels for *x* and *y*::
-
- >>> plot('xlabel', 'ylabel', data=obj)
-
- All indexable objects are supported. This could e.g. be a `dict`, a
- `pandas.DataFrame` or a structured numpy array.
-
-
- **Plotting multiple sets of data**
-
- There are various ways to plot multiple sets of data.
-
- - The most straight forward way is just to call `plot` multiple times.
- Example:
-
- >>> plot(x1, y1, 'bo')
- >>> plot(x2, y2, 'go')
-
- - If *x* and/or *y* are 2D arrays a separate data set will be drawn
- for every column. If both *x* and *y* are 2D, they must have the
- same shape. If only one of them is 2D with shape (N, m) the other
- must have length N and will be used for every data set m.
-
- Example:
-
- >>> x = [1, 2, 3]
- >>> y = np.array([[1, 2], [3, 4], [5, 6]])
- >>> plot(x, y)
-
- is equivalent to:
-
- >>> for col in range(y.shape[1]):
- ... plot(x, y[:, col])
-
- - The third way is to specify multiple sets of *[x]*, *y*, *[fmt]*
- groups::
-
- >>> plot(x1, y1, 'g^', x2, y2, 'g-')
-
- In this case, any additional keyword argument applies to all
- datasets. Also, this syntax cannot be combined with the *data*
- parameter.
-
- By default, each line is assigned a different style specified by a
- 'style cycle'. The *fmt* and line property parameters are only
- necessary if you want explicit deviations from these defaults.
- Alternatively, you can also change the style cycle using
- :rc:`axes.prop_cycle`.
-
-
- Parameters
- ----------
- x, y : array-like or scalar
- The horizontal / vertical coordinates of the data points.
- *x* values are optional and default to ``range(len(y))``.
-
- Commonly, these parameters are 1D arrays.
-
- They can also be scalars, or two-dimensional (in that case, the
- columns represent separate data sets).
-
- These arguments cannot be passed as keywords.
-
- fmt : str, optional
- A format string, e.g. 'ro' for red circles. See the *Notes*
- section for a full description of the format strings.
-
- Format strings are just an abbreviation for quickly setting
- basic line properties. All of these and more can also be
- controlled by keyword arguments.
-
- This argument cannot be passed as keyword.
-
- data : indexable object, optional
- An object with labelled data. If given, provide the label names to
- plot in *x* and *y*.
-
- .. note::
- Technically there's a slight ambiguity in calls where the
- second label is a valid *fmt*. ``plot('n', 'o', data=obj)``
- could be ``plt(x, y)`` or ``plt(y, fmt)``. In such cases,
- the former interpretation is chosen, but a warning is issued.
- You may suppress the warning by adding an empty format string
- ``plot('n', 'o', '', data=obj)``.
-
- Returns
- -------
- list of `.Line2D`
- A list of lines representing the plotted data.
-
- Other Parameters
- ----------------
- scalex, scaley : bool, default: True
- These parameters determine if the view limits are adapted to the
- data limits. The values are passed on to
- `~.axes.Axes.autoscale_view`.
-
- **kwargs : `~matplotlib.lines.Line2D` properties, optional
- *kwargs* are used to specify properties like a line label (for
- auto legends), linewidth, antialiasing, marker face color.
- Example::
-
- >>> plot([1, 2, 3], [1, 2, 3], 'go-', label='line 1', linewidth=2)
- >>> plot([1, 2, 3], [1, 4, 9], 'rs', label='line 2')
-
- If you specify multiple lines with one plot call, the kwargs apply
- to all those lines. In case the label object is iterable, each
- element is used as labels for each set of data.
-
- Here is a list of available `.Line2D` properties:
-
- %(Line2D:kwdoc)s
-
- See Also
- --------
- scatter : XY scatter plot with markers of varying size and/or color (
- sometimes also called bubble chart).
-
- Notes
- -----
- **Format Strings**
-
- A format string consists of a part for color, marker and line::
-
- fmt = '[marker][line][color]'
-
- Each of them is optional. If not provided, the value from the style
- cycle is used. Exception: If ``line`` is given, but no ``marker``,
- the data will be a line without markers.
-
- Other combinations such as ``[color][marker][line]`` are also
- supported, but note that their parsing may be ambiguous.
-
- **Markers**
-
- ============= ===============================
- character description
- ============= ===============================
- ``'.'`` point marker
- ``','`` pixel marker
- ``'o'`` circle marker
- ``'v'`` triangle_down marker
- ``'^'`` triangle_up marker
- ``'<'`` triangle_left marker
- ``'>'`` triangle_right marker
- ``'1'`` tri_down marker
- ``'2'`` tri_up marker
- ``'3'`` tri_left marker
- ``'4'`` tri_right marker
- ``'8'`` octagon marker
- ``'s'`` square marker
- ``'p'`` pentagon marker
- ``'P'`` plus (filled) marker
- ``'*'`` star marker
- ``'h'`` hexagon1 marker
- ``'H'`` hexagon2 marker
- ``'+'`` plus marker
- ``'x'`` x marker
- ``'X'`` x (filled) marker
- ``'D'`` diamond marker
- ``'d'`` thin_diamond marker
- ``'|'`` vline marker
- ``'_'`` hline marker
- ============= ===============================
-
- **Line Styles**
-
- ============= ===============================
- character description
- ============= ===============================
- ``'-'`` solid line style
- ``'--'`` dashed line style
- ``'-.'`` dash-dot line style
- ``':'`` dotted line style
- ============= ===============================
-
- Example format strings::
-
- 'b' # blue markers with default shape
- 'or' # red circles
- '-g' # green solid line
- '--' # dashed line with default color
- '^k:' # black triangle_up markers connected by a dotted line
-
- **Colors**
-
- The supported color abbreviations are the single letter codes
-
- ============= ===============================
- character color
- ============= ===============================
- ``'b'`` blue
- ``'g'`` green
- ``'r'`` red
- ``'c'`` cyan
- ``'m'`` magenta
- ``'y'`` yellow
- ``'k'`` black
- ``'w'`` white
- ============= ===============================
-
- and the ``'CN'`` colors that index into the default property cycle.
-
- If the color is the only part of the format string, you can
- additionally use any `matplotlib.colors` spec, e.g. full names
- (``'green'``) or hex strings (``'#008000'``).
- """
- kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
- lines = [*self._get_lines(self, *args, data=data, **kwargs)]
- for line in lines:
- self.add_line(line)
- if scalex:
- self._request_autoscale_view("x")
- if scaley:
- self._request_autoscale_view("y")
- return lines
-
- @_preprocess_data(replace_names=["x", "y"], label_namer="y")
- @_docstring.dedent_interpd
- def plot_date(self, x, y, fmt='o', tz=None, xdate=True, ydate=False,
- **kwargs):
- """
- [*Discouraged*] Plot coercing the axis to treat floats as dates.
-
- .. admonition:: Discouraged
-
- This method exists for historic reasons and will be deprecated in
- the future.
-
- - ``datetime``-like data should directly be plotted using
- `~.Axes.plot`.
- - If you need to plot plain numeric data as :ref:`date-format` or
- need to set a timezone, call ``ax.xaxis.axis_date`` /
- ``ax.yaxis.axis_date`` before `~.Axes.plot`. See
- `.Axis.axis_date`.
-
- Similar to `.plot`, this plots *y* vs. *x* as lines or markers.
- However, the axis labels are formatted as dates depending on *xdate*
- and *ydate*. Note that `.plot` will work with `datetime` and
- `numpy.datetime64` objects without resorting to this method.
-
- Parameters
- ----------
- x, y : array-like
- The coordinates of the data points. If *xdate* or *ydate* is
- *True*, the respective values *x* or *y* are interpreted as
- :ref:`Matplotlib dates <date-format>`.
-
- fmt : str, optional
- The plot format string. For details, see the corresponding
- parameter in `.plot`.
-
- tz : timezone string or `datetime.tzinfo`, default: :rc:`timezone`
- The time zone to use in labeling dates.
-
- xdate : bool, default: True
- If *True*, the *x*-axis will be interpreted as Matplotlib dates.
-
- ydate : bool, default: False
- If *True*, the *y*-axis will be interpreted as Matplotlib dates.
-
- Returns
- -------
- list of `.Line2D`
- Objects representing the plotted data.
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
- **kwargs
- Keyword arguments control the `.Line2D` properties:
-
- %(Line2D:kwdoc)s
-
- See Also
- --------
- matplotlib.dates : Helper functions on dates.
- matplotlib.dates.date2num : Convert dates to num.
- matplotlib.dates.num2date : Convert num to dates.
- matplotlib.dates.drange : Create an equally spaced sequence of dates.
-
- Notes
- -----
- If you are using custom date tickers and formatters, it may be
- necessary to set the formatters/locators after the call to
- `.plot_date`. `.plot_date` will set the default tick locator to
- `.AutoDateLocator` (if the tick locator is not already set to a
- `.DateLocator` instance) and the default tick formatter to
- `.AutoDateFormatter` (if the tick formatter is not already set to a
- `.DateFormatter` instance).
- """
- if xdate:
- self.xaxis_date(tz)
- if ydate:
- self.yaxis_date(tz)
- return self.plot(x, y, fmt, **kwargs)
-
- # @_preprocess_data() # let 'plot' do the unpacking..
- @_docstring.dedent_interpd
- def loglog(self, *args, **kwargs):
- """
- Make a plot with log scaling on both the x- and y-axis.
-
- Call signatures::
-
- loglog([x], y, [fmt], data=None, **kwargs)
- loglog([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
-
- This is just a thin wrapper around `.plot` which additionally changes
- both the x-axis and the y-axis to log scaling. All the concepts and
- parameters of plot can be used here as well.
-
- The additional parameters *base*, *subs* and *nonpositive* control the
- x/y-axis properties. They are just forwarded to `.Axes.set_xscale` and
- `.Axes.set_yscale`. To use different properties on the x-axis and the
- y-axis, use e.g.
- ``ax.set_xscale("log", base=10); ax.set_yscale("log", base=2)``.
-
- Parameters
- ----------
- base : float, default: 10
- Base of the logarithm.
-
- subs : sequence, optional
- The location of the minor ticks. If *None*, reasonable locations
- are automatically chosen depending on the number of decades in the
- plot. See `.Axes.set_xscale`/`.Axes.set_yscale` for details.
-
- nonpositive : {'mask', 'clip'}, default: 'clip'
- Non-positive values can be masked as invalid, or clipped to a very
- small positive number.
-
- **kwargs
- All parameters supported by `.plot`.
-
- Returns
- -------
- list of `.Line2D`
- Objects representing the plotted data.
- """
- dx = {k: v for k, v in kwargs.items()
- if k in ['base', 'subs', 'nonpositive',
- 'basex', 'subsx', 'nonposx']}
- self.set_xscale('log', **dx)
- dy = {k: v for k, v in kwargs.items()
- if k in ['base', 'subs', 'nonpositive',
- 'basey', 'subsy', 'nonposy']}
- self.set_yscale('log', **dy)
- return self.plot(
- *args, **{k: v for k, v in kwargs.items() if k not in {*dx, *dy}})
-
- # @_preprocess_data() # let 'plot' do the unpacking..
- @_docstring.dedent_interpd
- def semilogx(self, *args, **kwargs):
- """
- Make a plot with log scaling on the x-axis.
-
- Call signatures::
-
- semilogx([x], y, [fmt], data=None, **kwargs)
- semilogx([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
-
- This is just a thin wrapper around `.plot` which additionally changes
- the x-axis to log scaling. All the concepts and parameters of plot can
- be used here as well.
-
- The additional parameters *base*, *subs*, and *nonpositive* control the
- x-axis properties. They are just forwarded to `.Axes.set_xscale`.
-
- Parameters
- ----------
- base : float, default: 10
- Base of the x logarithm.
-
- subs : array-like, optional
- The location of the minor xticks. If *None*, reasonable locations
- are automatically chosen depending on the number of decades in the
- plot. See `.Axes.set_xscale` for details.
-
- nonpositive : {'mask', 'clip'}, default: 'clip'
- Non-positive values in x can be masked as invalid, or clipped to a
- very small positive number.
-
- **kwargs
- All parameters supported by `.plot`.
-
- Returns
- -------
- list of `.Line2D`
- Objects representing the plotted data.
- """
- d = {k: v for k, v in kwargs.items()
- if k in ['base', 'subs', 'nonpositive',
- 'basex', 'subsx', 'nonposx']}
- self.set_xscale('log', **d)
- return self.plot(
- *args, **{k: v for k, v in kwargs.items() if k not in d})
-
- # @_preprocess_data() # let 'plot' do the unpacking..
- @_docstring.dedent_interpd
- def semilogy(self, *args, **kwargs):
- """
- Make a plot with log scaling on the y-axis.
-
- Call signatures::
-
- semilogy([x], y, [fmt], data=None, **kwargs)
- semilogy([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)
-
- This is just a thin wrapper around `.plot` which additionally changes
- the y-axis to log scaling. All the concepts and parameters of plot can
- be used here as well.
-
- The additional parameters *base*, *subs*, and *nonpositive* control the
- y-axis properties. They are just forwarded to `.Axes.set_yscale`.
-
- Parameters
- ----------
- base : float, default: 10
- Base of the y logarithm.
-
- subs : array-like, optional
- The location of the minor yticks. If *None*, reasonable locations
- are automatically chosen depending on the number of decades in the
- plot. See `.Axes.set_yscale` for details.
-
- nonpositive : {'mask', 'clip'}, default: 'clip'
- Non-positive values in y can be masked as invalid, or clipped to a
- very small positive number.
-
- **kwargs
- All parameters supported by `.plot`.
-
- Returns
- -------
- list of `.Line2D`
- Objects representing the plotted data.
- """
- d = {k: v for k, v in kwargs.items()
- if k in ['base', 'subs', 'nonpositive',
- 'basey', 'subsy', 'nonposy']}
- self.set_yscale('log', **d)
- return self.plot(
- *args, **{k: v for k, v in kwargs.items() if k not in d})
-
- @_preprocess_data(replace_names=["x"], label_namer="x")
- def acorr(self, x, **kwargs):
- """
- Plot the autocorrelation of *x*.
-
- Parameters
- ----------
- x : array-like
-
- detrend : callable, default: `.mlab.detrend_none` (no detrending)
- A detrending function applied to *x*. It must have the
- signature ::
-
- detrend(x: np.ndarray) -> np.ndarray
-
- normed : bool, default: True
- If ``True``, input vectors are normalised to unit length.
-
- usevlines : bool, default: True
- Determines the plot style.
-
- If ``True``, vertical lines are plotted from 0 to the acorr value
- using `.Axes.vlines`. Additionally, a horizontal line is plotted
- at y=0 using `.Axes.axhline`.
-
- If ``False``, markers are plotted at the acorr values using
- `.Axes.plot`.
-
- maxlags : int, default: 10
- Number of lags to show. If ``None``, will return all
- ``2 * len(x) - 1`` lags.
-
- Returns
- -------
- lags : array (length ``2*maxlags+1``)
- The lag vector.
- c : array (length ``2*maxlags+1``)
- The auto correlation vector.
- line : `.LineCollection` or `.Line2D`
- `.Artist` added to the Axes of the correlation:
-
- - `.LineCollection` if *usevlines* is True.
- - `.Line2D` if *usevlines* is False.
- b : `~matplotlib.lines.Line2D` or None
- Horizontal line at 0 if *usevlines* is True
- None *usevlines* is False.
-
- Other Parameters
- ----------------
- linestyle : `~matplotlib.lines.Line2D` property, optional
- The linestyle for plotting the data points.
- Only used if *usevlines* is ``False``.
-
- marker : str, default: 'o'
- The marker for plotting the data points.
- Only used if *usevlines* is ``False``.
-
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Additional parameters are passed to `.Axes.vlines` and
- `.Axes.axhline` if *usevlines* is ``True``; otherwise they are
- passed to `.Axes.plot`.
-
- Notes
- -----
- The cross correlation is performed with `numpy.correlate` with
- ``mode = "full"``.
- """
- return self.xcorr(x, x, **kwargs)
-
- @_preprocess_data(replace_names=["x", "y"], label_namer="y")
- def xcorr(self, x, y, normed=True, detrend=mlab.detrend_none,
- usevlines=True, maxlags=10, **kwargs):
- r"""
- Plot the cross correlation between *x* and *y*.
-
- The correlation with lag k is defined as
- :math:`\sum_n x[n+k] \cdot y^*[n]`, where :math:`y^*` is the complex
- conjugate of :math:`y`.
-
- Parameters
- ----------
- x, y : array-like of length n
-
- detrend : callable, default: `.mlab.detrend_none` (no detrending)
- A detrending function applied to *x* and *y*. It must have the
- signature ::
-
- detrend(x: np.ndarray) -> np.ndarray
-
- normed : bool, default: True
- If ``True``, input vectors are normalised to unit length.
-
- usevlines : bool, default: True
- Determines the plot style.
-
- If ``True``, vertical lines are plotted from 0 to the xcorr value
- using `.Axes.vlines`. Additionally, a horizontal line is plotted
- at y=0 using `.Axes.axhline`.
-
- If ``False``, markers are plotted at the xcorr values using
- `.Axes.plot`.
-
- maxlags : int, default: 10
- Number of lags to show. If None, will return all ``2 * len(x) - 1``
- lags.
-
- Returns
- -------
- lags : array (length ``2*maxlags+1``)
- The lag vector.
- c : array (length ``2*maxlags+1``)
- The auto correlation vector.
- line : `.LineCollection` or `.Line2D`
- `.Artist` added to the Axes of the correlation:
-
- - `.LineCollection` if *usevlines* is True.
- - `.Line2D` if *usevlines* is False.
- b : `~matplotlib.lines.Line2D` or None
- Horizontal line at 0 if *usevlines* is True
- None *usevlines* is False.
-
- Other Parameters
- ----------------
- linestyle : `~matplotlib.lines.Line2D` property, optional
- The linestyle for plotting the data points.
- Only used if *usevlines* is ``False``.
-
- marker : str, default: 'o'
- The marker for plotting the data points.
- Only used if *usevlines* is ``False``.
-
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Additional parameters are passed to `.Axes.vlines` and
- `.Axes.axhline` if *usevlines* is ``True``; otherwise they are
- passed to `.Axes.plot`.
-
- Notes
- -----
- The cross correlation is performed with `numpy.correlate` with
- ``mode = "full"``.
- """
- Nx = len(x)
- if Nx != len(y):
- raise ValueError('x and y must be equal length')
-
- x = detrend(np.asarray(x))
- y = detrend(np.asarray(y))
-
- correls = np.correlate(x, y, mode="full")
-
- if normed:
- correls = correls / np.sqrt(np.dot(x, x) * np.dot(y, y))
-
- if maxlags is None:
- maxlags = Nx - 1
-
- if maxlags >= Nx or maxlags < 1:
- raise ValueError('maxlags must be None or strictly '
- 'positive < %d' % Nx)
-
- lags = np.arange(-maxlags, maxlags + 1)
- correls = correls[Nx - 1 - maxlags:Nx + maxlags]
-
- if usevlines:
- a = self.vlines(lags, [0], correls, **kwargs)
- # Make label empty so only vertical lines get a legend entry
- kwargs.pop('label', '')
- b = self.axhline(**kwargs)
- else:
- kwargs.setdefault('marker', 'o')
- kwargs.setdefault('linestyle', 'None')
- a, = self.plot(lags, correls, **kwargs)
- b = None
- return lags, correls, a, b
-
- #### Specialized plotting
-
- # @_preprocess_data() # let 'plot' do the unpacking..
- def step(self, x, y, *args, where='pre', data=None, **kwargs):
- """
- Make a step plot.
-
- Call signatures::
-
- step(x, y, [fmt], *, data=None, where='pre', **kwargs)
- step(x, y, [fmt], x2, y2, [fmt2], ..., *, where='pre', **kwargs)
-
- This is just a thin wrapper around `.plot` which changes some
- formatting options. Most of the concepts and parameters of plot can be
- used here as well.
-
- .. note::
-
- This method uses a standard plot with a step drawstyle: The *x*
- values are the reference positions and steps extend left/right/both
- directions depending on *where*.
-
- For the common case where you know the values and edges of the
- steps, use `~.Axes.stairs` instead.
-
- Parameters
- ----------
- x : array-like
- 1D sequence of x positions. It is assumed, but not checked, that
- it is uniformly increasing.
-
- y : array-like
- 1D sequence of y levels.
-
- fmt : str, optional
- A format string, e.g. 'g' for a green line. See `.plot` for a more
- detailed description.
-
- Note: While full format strings are accepted, it is recommended to
- only specify the color. Line styles are currently ignored (use
- the keyword argument *linestyle* instead). Markers are accepted
- and plotted on the given positions, however, this is a rarely
- needed feature for step plots.
-
- where : {'pre', 'post', 'mid'}, default: 'pre'
- Define where the steps should be placed:
-
- - 'pre': The y value is continued constantly to the left from
- every *x* position, i.e. the interval ``(x[i-1], x[i]]`` has the
- value ``y[i]``.
- - 'post': The y value is continued constantly to the right from
- every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the
- value ``y[i]``.
- - 'mid': Steps occur half-way between the *x* positions.
-
- data : indexable object, optional
- An object with labelled data. If given, provide the label names to
- plot in *x* and *y*.
-
- **kwargs
- Additional parameters are the same as those for `.plot`.
-
- Returns
- -------
- list of `.Line2D`
- Objects representing the plotted data.
- """
- _api.check_in_list(('pre', 'post', 'mid'), where=where)
- kwargs['drawstyle'] = 'steps-' + where
- return self.plot(x, y, *args, data=data, **kwargs)
-
- @staticmethod
- def _convert_dx(dx, x0, xconv, convert):
- """
- Small helper to do logic of width conversion flexibly.
-
- *dx* and *x0* have units, but *xconv* has already been converted
- to unitless (and is an ndarray). This allows the *dx* to have units
- that are different from *x0*, but are still accepted by the
- ``__add__`` operator of *x0*.
- """
-
- # x should be an array...
- assert type(xconv) is np.ndarray
-
- if xconv.size == 0:
- # xconv has already been converted, but maybe empty...
- return convert(dx)
-
- try:
- # attempt to add the width to x0; this works for
- # datetime+timedelta, for instance
-
- # only use the first element of x and x0. This saves
- # having to be sure addition works across the whole
- # vector. This is particularly an issue if
- # x0 and dx are lists so x0 + dx just concatenates the lists.
- # We can't just cast x0 and dx to numpy arrays because that
- # removes the units from unit packages like `pint` that
- # wrap numpy arrays.
- try:
- x0 = cbook._safe_first_finite(x0)
- except (TypeError, IndexError, KeyError):
- pass
-
- try:
- x = cbook._safe_first_finite(xconv)
- except (TypeError, IndexError, KeyError):
- x = xconv
-
- delist = False
- if not np.iterable(dx):
- dx = [dx]
- delist = True
- dx = [convert(x0 + ddx) - x for ddx in dx]
- if delist:
- dx = dx[0]
- except (ValueError, TypeError, AttributeError):
- # if the above fails (for any reason) just fallback to what
- # we do by default and convert dx by itself.
- dx = convert(dx)
- return dx
-
- @_preprocess_data()
- @_docstring.dedent_interpd
- def bar(self, x, height, width=0.8, bottom=None, *, align="center",
- **kwargs):
- r"""
- Make a bar plot.
-
- The bars are positioned at *x* with the given *align*\ment. Their
- dimensions are given by *height* and *width*. The vertical baseline
- is *bottom* (default 0).
-
- Many parameters can take either a single value applying to all bars
- or a sequence of values, one for each bar.
-
- Parameters
- ----------
- x : float or array-like
- The x coordinates of the bars. See also *align* for the
- alignment of the bars to the coordinates.
-
- height : float or array-like
- The height(s) of the bars.
-
- Note that if *bottom* has units (e.g. datetime), *height* should be in
- units that are a difference from the value of *bottom* (e.g. timedelta).
-
- width : float or array-like, default: 0.8
- The width(s) of the bars.
-
- Note that if *x* has units (e.g. datetime), then *width* should be in
- units that are a difference (e.g. timedelta) around the *x* values.
-
- bottom : float or array-like, default: 0
- The y coordinate(s) of the bottom side(s) of the bars.
-
- Note that if *bottom* has units, then the y-axis will get a Locator and
- Formatter appropriate for the units (e.g. dates, or categorical).
-
- align : {'center', 'edge'}, default: 'center'
- Alignment of the bars to the *x* coordinates:
-
- - 'center': Center the base on the *x* positions.
- - 'edge': Align the left edges of the bars with the *x* positions.
-
- To align the bars on the right edge pass a negative *width* and
- ``align='edge'``.
-
- Returns
- -------
- `.BarContainer`
- Container with all the bars and optionally errorbars.
-
- Other Parameters
- ----------------
- color : color or list of color, optional
- The colors of the bar faces.
-
- edgecolor : color or list of color, optional
- The colors of the bar edges.
-
- linewidth : float or array-like, optional
- Width of the bar edge(s). If 0, don't draw edges.
-
- tick_label : str or list of str, optional
- The tick labels of the bars.
- Default: None (Use default numeric labels.)
-
- label : str or list of str, optional
- A single label is attached to the resulting `.BarContainer` as a
- label for the whole dataset.
- If a list is provided, it must be the same length as *x* and
- labels the individual bars. Repeated labels are not de-duplicated
- and will cause repeated label entries, so this is best used when
- bars also differ in style (e.g., by passing a list to *color*.)
-
- xerr, yerr : float or array-like of shape(N,) or shape(2, N), optional
- If not *None*, add horizontal / vertical errorbars to the bar tips.
- The values are +/- sizes relative to the data:
-
- - scalar: symmetric +/- values for all bars
- - shape(N,): symmetric +/- values for each bar
- - shape(2, N): Separate - and + values for each bar. First row
- contains the lower errors, the second row contains the upper
- errors.
- - *None*: No errorbar. (Default)
-
- See :doc:`/gallery/statistics/errorbar_features` for an example on
- the usage of *xerr* and *yerr*.
-
- ecolor : color or list of color, default: 'black'
- The line color of the errorbars.
-
- capsize : float, default: :rc:`errorbar.capsize`
- The length of the error bar caps in points.
-
- error_kw : dict, optional
- Dictionary of keyword arguments to be passed to the
- `~.Axes.errorbar` method. Values of *ecolor* or *capsize* defined
- here take precedence over the independent keyword arguments.
-
- log : bool, default: False
- If *True*, set the y-axis to be log scale.
-
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs : `.Rectangle` properties
-
- %(Rectangle:kwdoc)s
-
- See Also
- --------
- barh : Plot a horizontal bar plot.
-
- Notes
- -----
- Stacked bars can be achieved by passing individual *bottom* values per
- bar. See :doc:`/gallery/lines_bars_and_markers/bar_stacked`.
- """
- kwargs = cbook.normalize_kwargs(kwargs, mpatches.Patch)
- color = kwargs.pop('color', None)
- if color is None:
- color = self._get_patches_for_fill.get_next_color()
- edgecolor = kwargs.pop('edgecolor', None)
- linewidth = kwargs.pop('linewidth', None)
- hatch = kwargs.pop('hatch', None)
-
- # Because xerr and yerr will be passed to errorbar, most dimension
- # checking and processing will be left to the errorbar method.
- xerr = kwargs.pop('xerr', None)
- yerr = kwargs.pop('yerr', None)
- error_kw = kwargs.pop('error_kw', {})
- ezorder = error_kw.pop('zorder', None)
- if ezorder is None:
- ezorder = kwargs.get('zorder', None)
- if ezorder is not None:
- # If using the bar zorder, increment slightly to make sure
- # errorbars are drawn on top of bars
- ezorder += 0.01
- error_kw.setdefault('zorder', ezorder)
- ecolor = kwargs.pop('ecolor', 'k')
- capsize = kwargs.pop('capsize', mpl.rcParams["errorbar.capsize"])
- error_kw.setdefault('ecolor', ecolor)
- error_kw.setdefault('capsize', capsize)
-
- # The keyword argument *orientation* is used by barh() to defer all
- # logic and drawing to bar(). It is considered internal and is
- # intentionally not mentioned in the docstring.
- orientation = kwargs.pop('orientation', 'vertical')
- _api.check_in_list(['vertical', 'horizontal'], orientation=orientation)
- log = kwargs.pop('log', False)
- label = kwargs.pop('label', '')
- tick_labels = kwargs.pop('tick_label', None)
-
- y = bottom # Matches barh call signature.
- if orientation == 'vertical':
- if y is None:
- y = 0
- else: # horizontal
- if x is None:
- x = 0
-
- if orientation == 'vertical':
- # It is possible for y (bottom) to contain unit information.
- # However, it is also possible for y=0 for the default and height
- # to contain unit information. This will prioritize the units of y.
- self._process_unit_info(
- [("x", x), ("y", y), ("y", height)], kwargs, convert=False)
- if log:
- self.set_yscale('log', nonpositive='clip')
- else: # horizontal
- # It is possible for x (left) to contain unit information.
- # However, it is also possible for x=0 for the default and width
- # to contain unit information. This will prioritize the units of x.
- self._process_unit_info(
- [("x", x), ("x", width), ("y", y)], kwargs, convert=False)
- if log:
- self.set_xscale('log', nonpositive='clip')
-
- # lets do some conversions now since some types cannot be
- # subtracted uniformly
- if self.xaxis is not None:
- x0 = x
- x = np.asarray(self.convert_xunits(x))
- width = self._convert_dx(width, x0, x, self.convert_xunits)
- if xerr is not None:
- xerr = self._convert_dx(xerr, x0, x, self.convert_xunits)
- if self.yaxis is not None:
- y0 = y
- y = np.asarray(self.convert_yunits(y))
- height = self._convert_dx(height, y0, y, self.convert_yunits)
- if yerr is not None:
- yerr = self._convert_dx(yerr, y0, y, self.convert_yunits)
-
- x, height, width, y, linewidth, hatch = np.broadcast_arrays(
- # Make args iterable too.
- np.atleast_1d(x), height, width, y, linewidth, hatch)
-
- # Now that units have been converted, set the tick locations.
- if orientation == 'vertical':
- tick_label_axis = self.xaxis
- tick_label_position = x
- else: # horizontal
- tick_label_axis = self.yaxis
- tick_label_position = y
-
- if not isinstance(label, str) and np.iterable(label):
- bar_container_label = '_nolegend_'
- patch_labels = label
- else:
- bar_container_label = label
- patch_labels = ['_nolegend_'] * len(x)
- if len(patch_labels) != len(x):
- raise ValueError(f'number of labels ({len(patch_labels)}) '
- f'does not match number of bars ({len(x)}).')
-
- linewidth = itertools.cycle(np.atleast_1d(linewidth))
- hatch = itertools.cycle(np.atleast_1d(hatch))
- color = itertools.chain(itertools.cycle(mcolors.to_rgba_array(color)),
- # Fallback if color == "none".
- itertools.repeat('none'))
- if edgecolor is None:
- edgecolor = itertools.repeat(None)
- else:
- edgecolor = itertools.chain(
- itertools.cycle(mcolors.to_rgba_array(edgecolor)),
- # Fallback if edgecolor == "none".
- itertools.repeat('none'))
-
- # We will now resolve the alignment and really have
- # left, bottom, width, height vectors
- _api.check_in_list(['center', 'edge'], align=align)
- if align == 'center':
- if orientation == 'vertical':
- try:
- left = x - width / 2
- except TypeError as e:
- raise TypeError(f'the dtypes of parameters x ({x.dtype}) '
- f'and width ({width.dtype}) '
- f'are incompatible') from e
- bottom = y
- else: # horizontal
- try:
- bottom = y - height / 2
- except TypeError as e:
- raise TypeError(f'the dtypes of parameters y ({y.dtype}) '
- f'and height ({height.dtype}) '
- f'are incompatible') from e
- left = x
- else: # edge
- left = x
- bottom = y
-
- patches = []
- args = zip(left, bottom, width, height, color, edgecolor, linewidth,
- hatch, patch_labels)
- for l, b, w, h, c, e, lw, htch, lbl in args:
- r = mpatches.Rectangle(
- xy=(l, b), width=w, height=h,
- facecolor=c,
- edgecolor=e,
- linewidth=lw,
- label=lbl,
- hatch=htch,
- )
- r._internal_update(kwargs)
- r.get_path()._interpolation_steps = 100
- if orientation == 'vertical':
- r.sticky_edges.y.append(b)
- else: # horizontal
- r.sticky_edges.x.append(l)
- self.add_patch(r)
- patches.append(r)
-
- if xerr is not None or yerr is not None:
- if orientation == 'vertical':
- # using list comps rather than arrays to preserve unit info
- ex = [l + 0.5 * w for l, w in zip(left, width)]
- ey = [b + h for b, h in zip(bottom, height)]
-
- else: # horizontal
- # using list comps rather than arrays to preserve unit info
- ex = [l + w for l, w in zip(left, width)]
- ey = [b + 0.5 * h for b, h in zip(bottom, height)]
-
- error_kw.setdefault("label", '_nolegend_')
-
- errorbar = self.errorbar(ex, ey,
- yerr=yerr, xerr=xerr,
- fmt='none', **error_kw)
- else:
- errorbar = None
-
- self._request_autoscale_view()
-
- if orientation == 'vertical':
- datavalues = height
- else: # horizontal
- datavalues = width
-
- bar_container = BarContainer(patches, errorbar, datavalues=datavalues,
- orientation=orientation,
- label=bar_container_label)
- self.add_container(bar_container)
-
- if tick_labels is not None:
- tick_labels = np.broadcast_to(tick_labels, len(patches))
- tick_label_axis.set_ticks(tick_label_position)
- tick_label_axis.set_ticklabels(tick_labels)
-
- return bar_container
-
- # @_preprocess_data() # let 'bar' do the unpacking..
- @_docstring.dedent_interpd
- def barh(self, y, width, height=0.8, left=None, *, align="center",
- data=None, **kwargs):
- r"""
- Make a horizontal bar plot.
-
- The bars are positioned at *y* with the given *align*\ment. Their
- dimensions are given by *width* and *height*. The horizontal baseline
- is *left* (default 0).
-
- Many parameters can take either a single value applying to all bars
- or a sequence of values, one for each bar.
-
- Parameters
- ----------
- y : float or array-like
- The y coordinates of the bars. See also *align* for the
- alignment of the bars to the coordinates.
-
- width : float or array-like
- The width(s) of the bars.
-
- Note that if *left* has units (e.g. datetime), *width* should be in
- units that are a difference from the value of *left* (e.g. timedelta).
-
- height : float or array-like, default: 0.8
- The heights of the bars.
-
- Note that if *y* has units (e.g. datetime), then *height* should be in
- units that are a difference (e.g. timedelta) around the *y* values.
-
- left : float or array-like, default: 0
- The x coordinates of the left side(s) of the bars.
-
- Note that if *left* has units, then the x-axis will get a Locator and
- Formatter appropriate for the units (e.g. dates, or categorical).
-
- align : {'center', 'edge'}, default: 'center'
- Alignment of the base to the *y* coordinates*:
-
- - 'center': Center the bars on the *y* positions.
- - 'edge': Align the bottom edges of the bars with the *y*
- positions.
-
- To align the bars on the top edge pass a negative *height* and
- ``align='edge'``.
-
- Returns
- -------
- `.BarContainer`
- Container with all the bars and optionally errorbars.
-
- Other Parameters
- ----------------
- color : color or list of color, optional
- The colors of the bar faces.
-
- edgecolor : color or list of color, optional
- The colors of the bar edges.
-
- linewidth : float or array-like, optional
- Width of the bar edge(s). If 0, don't draw edges.
-
- tick_label : str or list of str, optional
- The tick labels of the bars.
- Default: None (Use default numeric labels.)
-
- label : str or list of str, optional
- A single label is attached to the resulting `.BarContainer` as a
- label for the whole dataset.
- If a list is provided, it must be the same length as *y* and
- labels the individual bars. Repeated labels are not de-duplicated
- and will cause repeated label entries, so this is best used when
- bars also differ in style (e.g., by passing a list to *color*.)
-
- xerr, yerr : float or array-like of shape(N,) or shape(2, N), optional
- If not *None*, add horizontal / vertical errorbars to the bar tips.
- The values are +/- sizes relative to the data:
-
- - scalar: symmetric +/- values for all bars
- - shape(N,): symmetric +/- values for each bar
- - shape(2, N): Separate - and + values for each bar. First row
- contains the lower errors, the second row contains the upper
- errors.
- - *None*: No errorbar. (default)
-
- See :doc:`/gallery/statistics/errorbar_features` for an example on
- the usage of *xerr* and *yerr*.
-
- ecolor : color or list of color, default: 'black'
- The line color of the errorbars.
-
- capsize : float, default: :rc:`errorbar.capsize`
- The length of the error bar caps in points.
-
- error_kw : dict, optional
- Dictionary of keyword arguments to be passed to the
- `~.Axes.errorbar` method. Values of *ecolor* or *capsize* defined
- here take precedence over the independent keyword arguments.
-
- log : bool, default: False
- If ``True``, set the x-axis to be log scale.
-
- data : indexable object, optional
- If given, all parameters also accept a string ``s``, which is
- interpreted as ``data[s]`` (unless this raises an exception).
-
- **kwargs : `.Rectangle` properties
-
- %(Rectangle:kwdoc)s
-
- See Also
- --------
- bar : Plot a vertical bar plot.
-
- Notes
- -----
- Stacked bars can be achieved by passing individual *left* values per
- bar. See
- :doc:`/gallery/lines_bars_and_markers/horizontal_barchart_distribution`.
- """
- kwargs.setdefault('orientation', 'horizontal')
- patches = self.bar(x=left, height=height, width=width, bottom=y,
- align=align, data=data, **kwargs)
- return patches
-
- def bar_label(self, container, labels=None, *, fmt="%g", label_type="edge",
- padding=0, **kwargs):
- """
- Label a bar plot.
-
- Adds labels to bars in the given `.BarContainer`.
- You may need to adjust the axis limits to fit the labels.
-
- Parameters
- ----------
- container : `.BarContainer`
- Container with all the bars and optionally errorbars, likely
- returned from `.bar` or `.barh`.
-
- labels : array-like, optional
- A list of label texts, that should be displayed. If not given, the
- label texts will be the data values formatted with *fmt*.
-
- fmt : str or callable, default: '%g'
- An unnamed %-style or {}-style format string for the label or a
- function to call with the value as the first argument.
- When *fmt* is a string and can be interpreted in both formats,
- %-style takes precedence over {}-style.
-
- .. versionadded:: 3.7
- Support for {}-style format string and callables.
-
- label_type : {'edge', 'center'}, default: 'edge'
- The label type. Possible values:
-
- - 'edge': label placed at the end-point of the bar segment, and the
- value displayed will be the position of that end-point.
- - 'center': label placed in the center of the bar segment, and the
- value displayed will be the length of that segment.
- (useful for stacked bars, i.e.,
- :doc:`/gallery/lines_bars_and_markers/bar_label_demo`)
-
- padding : float, default: 0
- Distance of label from the end of the bar, in points.
-
- **kwargs
- Any remaining keyword arguments are passed through to
- `.Axes.annotate`. The alignment parameters (
- *horizontalalignment* / *ha*, *verticalalignment* / *va*) are
- not supported because the labels are automatically aligned to
- the bars.
-
- Returns
- -------
- list of `.Annotation`
- A list of `.Annotation` instances for the labels.
- """
- for key in ['horizontalalignment', 'ha', 'verticalalignment', 'va']:
- if key in kwargs:
- raise ValueError(
- f"Passing {key!r} to bar_label() is not supported.")
-
- a, b = self.yaxis.get_view_interval()
- y_inverted = a > b
- c, d = self.xaxis.get_view_interval()
- x_inverted = c > d
-
- # want to know whether to put label on positive or negative direction
- # cannot use np.sign here because it will return 0 if x == 0
- def sign(x):
- return 1 if x >= 0 else -1
-
- _api.check_in_list(['edge', 'center'], label_type=label_type)
-
- bars = container.patches
- errorbar = container.errorbar
- datavalues = container.datavalues
- orientation = container.orientation
-
- if errorbar:
- # check "ErrorbarContainer" for the definition of these elements
- lines = errorbar.lines # attribute of "ErrorbarContainer" (tuple)
- barlinecols = lines[2] # 0: data_line, 1: caplines, 2: barlinecols
- barlinecol = barlinecols[0] # the "LineCollection" of error bars
- errs = barlinecol.get_segments()
- else:
- errs = []
-
- if labels is None:
- labels = []
-
- annotations = []
-
- for bar, err, dat, lbl in itertools.zip_longest(
- bars, errs, datavalues, labels
- ):
- (x0, y0), (x1, y1) = bar.get_bbox().get_points()
- xc, yc = (x0 + x1) / 2, (y0 + y1) / 2
-
- if orientation == "vertical":
- extrema = max(y0, y1) if dat >= 0 else min(y0, y1)
- length = abs(y0 - y1)
- else: # horizontal
- extrema = max(x0, x1) if dat >= 0 else min(x0, x1)
- length = abs(x0 - x1)
-
- if err is None or np.size(err) == 0:
- endpt = extrema
- elif orientation == "vertical":
- endpt = err[:, 1].max() if dat >= 0 else err[:, 1].min()
- else: # horizontal
- endpt = err[:, 0].max() if dat >= 0 else err[:, 0].min()
-
- if label_type == "center":
- value = sign(dat) * length
- else: # edge
- value = extrema
-
- if label_type == "center":
- xy = (0.5, 0.5)
- kwargs["xycoords"] = (
- lambda r, b=bar:
- mtransforms.Bbox.intersection(
- b.get_window_extent(r), b.get_clip_box()
- ) or mtransforms.Bbox.null()
- )
- else: # edge
- if orientation == "vertical":
- xy = xc, endpt
- else: # horizontal
- xy = endpt, yc
-
- if orientation == "vertical":
- y_direction = -1 if y_inverted else 1
- xytext = 0, y_direction * sign(dat) * padding
- else: # horizontal
- x_direction = -1 if x_inverted else 1
- xytext = x_direction * sign(dat) * padding, 0
-
- if label_type == "center":
- ha, va = "center", "center"
- else: # edge
- if orientation == "vertical":
- ha = 'center'
- if y_inverted:
- va = 'top' if dat > 0 else 'bottom' # also handles NaN
- else:
- va = 'top' if dat < 0 else 'bottom' # also handles NaN
- else: # horizontal
- if x_inverted:
- ha = 'right' if dat > 0 else 'left' # also handles NaN
- else:
- ha = 'right' if dat < 0 else 'left' # also handles NaN
- va = 'center'
-
- if np.isnan(dat):
- lbl = ''
-
- if lbl is None:
- if isinstance(fmt, str):
- lbl = cbook._auto_format_str(fmt, value)
- elif callable(fmt):
- lbl = fmt(value)
- else:
- raise TypeError("fmt must be a str or callable")
- annotation = self.annotate(lbl,
- xy, xytext, textcoords="offset points",
- ha=ha, va=va, **kwargs)
- annotations.append(annotation)
-
- return annotations
-
- @_preprocess_data()
- @_docstring.dedent_interpd
- def broken_barh(self, xranges, yrange, **kwargs):
- """
- Plot a horizontal sequence of rectangles.
-
- A rectangle is drawn for each element of *xranges*. All rectangles
- have the same vertical position and size defined by *yrange*.
-
- Parameters
- ----------
- xranges : sequence of tuples (*xmin*, *xwidth*)
- The x-positions and extents of the rectangles. For each tuple
- (*xmin*, *xwidth*) a rectangle is drawn from *xmin* to *xmin* +
- *xwidth*.
- yrange : (*ymin*, *yheight*)
- The y-position and extent for all the rectangles.
-
- Returns
- -------
- `~.collections.PolyCollection`
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
- **kwargs : `.PolyCollection` properties
-
- Each *kwarg* can be either a single argument applying to all
- rectangles, e.g.::
-
- facecolors='black'
-
- or a sequence of arguments over which is cycled, e.g.::
-
- facecolors=('black', 'blue')
-
- would create interleaving black and blue rectangles.
-
- Supported keywords:
-
- %(PolyCollection:kwdoc)s
- """
- # process the unit information
- xdata = cbook._safe_first_finite(xranges) if len(xranges) else None
- ydata = cbook._safe_first_finite(yrange) if len(yrange) else None
- self._process_unit_info(
- [("x", xdata), ("y", ydata)], kwargs, convert=False)
-
- vertices = []
- y0, dy = yrange
- y0, y1 = self.convert_yunits((y0, y0 + dy))
- for xr in xranges: # convert the absolute values, not the x and dx
- try:
- x0, dx = xr
- except Exception:
- raise ValueError(
- "each range in xrange must be a sequence with two "
- "elements (i.e. xrange must be an (N, 2) array)") from None
- x0, x1 = self.convert_xunits((x0, x0 + dx))
- vertices.append([(x0, y0), (x0, y1), (x1, y1), (x1, y0)])
-
- col = mcoll.PolyCollection(np.array(vertices), **kwargs)
- self.add_collection(col, autolim=True)
- self._request_autoscale_view()
-
- return col
-
- @_preprocess_data()
- def stem(self, *args, linefmt=None, markerfmt=None, basefmt=None, bottom=0,
- label=None, orientation='vertical'):
- """
- Create a stem plot.
-
- A stem plot draws lines perpendicular to a baseline at each location
- *locs* from the baseline to *heads*, and places a marker there. For
- vertical stem plots (the default), the *locs* are *x* positions, and
- the *heads* are *y* values. For horizontal stem plots, the *locs* are
- *y* positions, and the *heads* are *x* values.
-
- Call signature::
-
- stem([locs,] heads, linefmt=None, markerfmt=None, basefmt=None)
-
- The *locs*-positions are optional. *linefmt* may be provided as
- positional, but all other formats must be provided as keyword
- arguments.
-
- Parameters
- ----------
- locs : array-like, default: (0, 1, ..., len(heads) - 1)
- For vertical stem plots, the x-positions of the stems.
- For horizontal stem plots, the y-positions of the stems.
-
- heads : array-like
- For vertical stem plots, the y-values of the stem heads.
- For horizontal stem plots, the x-values of the stem heads.
-
- linefmt : str, optional
- A string defining the color and/or linestyle of the vertical lines:
-
- ========= =============
- Character Line Style
- ========= =============
- ``'-'`` solid line
- ``'--'`` dashed line
- ``'-.'`` dash-dot line
- ``':'`` dotted line
- ========= =============
-
- Default: 'C0-', i.e. solid line with the first color of the color
- cycle.
-
- Note: Markers specified through this parameter (e.g. 'x') will be
- silently ignored. Instead, markers should be specified using
- *markerfmt*.
-
- markerfmt : str, optional
- A string defining the color and/or shape of the markers at the stem
- heads. If the marker is not given, use the marker 'o', i.e. filled
- circles. If the color is not given, use the color from *linefmt*.
-
- basefmt : str, default: 'C3-' ('C2-' in classic mode)
- A format string defining the properties of the baseline.
-
- orientation : {'vertical', 'horizontal'}, default: 'vertical'
- If 'vertical', will produce a plot with stems oriented vertically,
- If 'horizontal', the stems will be oriented horizontally.
-
- bottom : float, default: 0
- The y/x-position of the baseline (depending on orientation).
-
- label : str, default: None
- The label to use for the stems in legends.
-
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- Returns
- -------
- `.StemContainer`
- The container may be treated like a tuple
- (*markerline*, *stemlines*, *baseline*)
-
- Notes
- -----
- .. seealso::
- The MATLAB function
- `stem <https://www.mathworks.com/help/matlab/ref/stem.html>`_
- which inspired this method.
- """
- if not 1 <= len(args) <= 3:
- raise _api.nargs_error('stem', '1-3', len(args))
- _api.check_in_list(['horizontal', 'vertical'], orientation=orientation)
-
- if len(args) == 1:
- heads, = args
- locs = np.arange(len(heads))
- args = ()
- elif isinstance(args[1], str):
- heads, *args = args
- locs = np.arange(len(heads))
- else:
- locs, heads, *args = args
-
- if orientation == 'vertical':
- locs, heads = self._process_unit_info([("x", locs), ("y", heads)])
- else: # horizontal
- heads, locs = self._process_unit_info([("x", heads), ("y", locs)])
-
- # resolve line format
- if linefmt is None:
- linefmt = args[0] if len(args) > 0 else "C0-"
- linestyle, linemarker, linecolor = _process_plot_format(linefmt)
-
- # resolve marker format
- if markerfmt is None:
- # if not given as kwarg, fall back to 'o'
- markerfmt = "o"
- if markerfmt == '':
- markerfmt = ' ' # = empty line style; '' would resolve rcParams
- markerstyle, markermarker, markercolor = \
- _process_plot_format(markerfmt)
- if markermarker is None:
- markermarker = 'o'
- if markerstyle is None:
- markerstyle = 'None'
- if markercolor is None:
- markercolor = linecolor
-
- # resolve baseline format
- if basefmt is None:
- basefmt = ("C2-" if mpl.rcParams["_internal.classic_mode"] else
- "C3-")
- basestyle, basemarker, basecolor = _process_plot_format(basefmt)
-
- # New behaviour in 3.1 is to use a LineCollection for the stemlines
- if linestyle is None:
- linestyle = mpl.rcParams['lines.linestyle']
- xlines = self.vlines if orientation == "vertical" else self.hlines
- stemlines = xlines(
- locs, bottom, heads,
- colors=linecolor, linestyles=linestyle, label="_nolegend_")
-
- if orientation == 'horizontal':
- marker_x = heads
- marker_y = locs
- baseline_x = [bottom, bottom]
- baseline_y = [np.min(locs), np.max(locs)]
- else:
- marker_x = locs
- marker_y = heads
- baseline_x = [np.min(locs), np.max(locs)]
- baseline_y = [bottom, bottom]
-
- markerline, = self.plot(marker_x, marker_y,
- color=markercolor, linestyle=markerstyle,
- marker=markermarker, label="_nolegend_")
-
- baseline, = self.plot(baseline_x, baseline_y,
- color=basecolor, linestyle=basestyle,
- marker=basemarker, label="_nolegend_")
-
- stem_container = StemContainer((markerline, stemlines, baseline),
- label=label)
- self.add_container(stem_container)
- return stem_container
-
- @_preprocess_data(replace_names=["x", "explode", "labels", "colors"])
- def pie(self, x, explode=None, labels=None, colors=None,
- autopct=None, pctdistance=0.6, shadow=False, labeldistance=1.1,
- startangle=0, radius=1, counterclock=True,
- wedgeprops=None, textprops=None, center=(0, 0),
- frame=False, rotatelabels=False, *, normalize=True, hatch=None):
- """
- Plot a pie chart.
-
- Make a pie chart of array *x*. The fractional area of each wedge is
- given by ``x/sum(x)``.
-
- The wedges are plotted counterclockwise, by default starting from the
- x-axis.
-
- Parameters
- ----------
- x : 1D array-like
- The wedge sizes.
-
- explode : array-like, default: None
- If not *None*, is a ``len(x)`` array which specifies the fraction
- of the radius with which to offset each wedge.
-
- labels : list, default: None
- A sequence of strings providing the labels for each wedge
-
- colors : color or array-like of color, default: None
- A sequence of colors through which the pie chart will cycle. If
- *None*, will use the colors in the currently active cycle.
-
- hatch : str or list, default: None
- Hatching pattern applied to all pie wedges or sequence of patterns
- through which the chart will cycle. For a list of valid patterns,
- see :doc:`/gallery/shapes_and_collections/hatch_style_reference`.
-
- .. versionadded:: 3.7
-
- autopct : None or str or callable, default: None
- If not *None*, *autopct* is a string or function used to label the
- wedges with their numeric value. The label will be placed inside
- the wedge. If *autopct* is a format string, the label will be
- ``fmt % pct``. If *autopct* is a function, then it will be called.
-
- pctdistance : float, default: 0.6
- The relative distance along the radius at which the text
- generated by *autopct* is drawn. To draw the text outside the pie,
- set *pctdistance* > 1. This parameter is ignored if *autopct* is
- ``None``.
-
- labeldistance : float or None, default: 1.1
- The relative distance along the radius at which the labels are
- drawn. To draw the labels inside the pie, set *labeldistance* < 1.
- If set to ``None``, labels are not drawn but are still stored for
- use in `.legend`.
-
- shadow : bool or dict, default: False
- If bool, whether to draw a shadow beneath the pie. If dict, draw a shadow
- passing the properties in the dict to `.Shadow`.
-
- .. versionadded:: 3.8
- *shadow* can be a dict.
-
- startangle : float, default: 0 degrees
- The angle by which the start of the pie is rotated,
- counterclockwise from the x-axis.
-
- radius : float, default: 1
- The radius of the pie.
-
- counterclock : bool, default: True
- Specify fractions direction, clockwise or counterclockwise.
-
- wedgeprops : dict, default: None
- Dict of arguments passed to each `.patches.Wedge` of the pie.
- For example, ``wedgeprops = {'linewidth': 3}`` sets the width of
- the wedge border lines equal to 3. By default, ``clip_on=False``.
- When there is a conflict between these properties and other
- keywords, properties passed to *wedgeprops* take precedence.
-
- textprops : dict, default: None
- Dict of arguments to pass to the text objects.
-
- center : (float, float), default: (0, 0)
- The coordinates of the center of the chart.
-
- frame : bool, default: False
- Plot Axes frame with the chart if true.
-
- rotatelabels : bool, default: False
- Rotate each label to the angle of the corresponding slice if true.
-
- normalize : bool, default: True
- When *True*, always make a full pie by normalizing x so that
- ``sum(x) == 1``. *False* makes a partial pie if ``sum(x) <= 1``
- and raises a `ValueError` for ``sum(x) > 1``.
-
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- Returns
- -------
- patches : list
- A sequence of `matplotlib.patches.Wedge` instances
-
- texts : list
- A list of the label `.Text` instances.
-
- autotexts : list
- A list of `.Text` instances for the numeric labels. This will only
- be returned if the parameter *autopct* is not *None*.
-
- Notes
- -----
- The pie chart will probably look best if the figure and Axes are
- square, or the Axes aspect is equal.
- This method sets the aspect ratio of the axis to "equal".
- The Axes aspect ratio can be controlled with `.Axes.set_aspect`.
- """
- self.set_aspect('equal')
- # The use of float32 is "historical", but can't be changed without
- # regenerating the test baselines.
- x = np.asarray(x, np.float32)
- if x.ndim > 1:
- raise ValueError("x must be 1D")
-
- if np.any(x < 0):
- raise ValueError("Wedge sizes 'x' must be non negative values")
-
- sx = x.sum()
-
- if normalize:
- x = x / sx
- elif sx > 1:
- raise ValueError('Cannot plot an unnormalized pie with sum(x) > 1')
- if labels is None:
- labels = [''] * len(x)
- if explode is None:
- explode = [0] * len(x)
- if len(x) != len(labels):
- raise ValueError("'label' must be of length 'x'")
- if len(x) != len(explode):
- raise ValueError("'explode' must be of length 'x'")
- if colors is None:
- get_next_color = self._get_patches_for_fill.get_next_color
- else:
- color_cycle = itertools.cycle(colors)
-
- def get_next_color():
- return next(color_cycle)
-
- hatch_cycle = itertools.cycle(np.atleast_1d(hatch))
-
- _api.check_isinstance(Real, radius=radius, startangle=startangle)
- if radius <= 0:
- raise ValueError(f'radius must be a positive number, not {radius}')
-
- # Starting theta1 is the start fraction of the circle
- theta1 = startangle / 360
-
- if wedgeprops is None:
- wedgeprops = {}
- if textprops is None:
- textprops = {}
-
- texts = []
- slices = []
- autotexts = []
-
- for frac, label, expl in zip(x, labels, explode):
- x, y = center
- theta2 = (theta1 + frac) if counterclock else (theta1 - frac)
- thetam = 2 * np.pi * 0.5 * (theta1 + theta2)
- x += expl * math.cos(thetam)
- y += expl * math.sin(thetam)
-
- w = mpatches.Wedge((x, y), radius, 360. * min(theta1, theta2),
- 360. * max(theta1, theta2),
- facecolor=get_next_color(),
- hatch=next(hatch_cycle),
- clip_on=False,
- label=label)
- w.set(**wedgeprops)
- slices.append(w)
- self.add_patch(w)
-
- if shadow:
- # Make sure to add a shadow after the call to add_patch so the
- # figure and transform props will be set.
- shadow_dict = {'ox': -0.02, 'oy': -0.02, 'label': '_nolegend_'}
- if isinstance(shadow, dict):
- shadow_dict.update(shadow)
- self.add_patch(mpatches.Shadow(w, **shadow_dict))
-
- if labeldistance is not None:
- xt = x + labeldistance * radius * math.cos(thetam)
- yt = y + labeldistance * radius * math.sin(thetam)
- label_alignment_h = 'left' if xt > 0 else 'right'
- label_alignment_v = 'center'
- label_rotation = 'horizontal'
- if rotatelabels:
- label_alignment_v = 'bottom' if yt > 0 else 'top'
- label_rotation = (np.rad2deg(thetam)
- + (0 if xt > 0 else 180))
- t = self.text(xt, yt, label,
- clip_on=False,
- horizontalalignment=label_alignment_h,
- verticalalignment=label_alignment_v,
- rotation=label_rotation,
- size=mpl.rcParams['xtick.labelsize'])
- t.set(**textprops)
- texts.append(t)
-
- if autopct is not None:
- xt = x + pctdistance * radius * math.cos(thetam)
- yt = y + pctdistance * radius * math.sin(thetam)
- if isinstance(autopct, str):
- s = autopct % (100. * frac)
- elif callable(autopct):
- s = autopct(100. * frac)
- else:
- raise TypeError(
- 'autopct must be callable or a format string')
- t = self.text(xt, yt, s,
- clip_on=False,
- horizontalalignment='center',
- verticalalignment='center')
- t.set(**textprops)
- autotexts.append(t)
-
- theta1 = theta2
-
- if frame:
- self._request_autoscale_view()
- else:
- self.set(frame_on=False, xticks=[], yticks=[],
- xlim=(-1.25 + center[0], 1.25 + center[0]),
- ylim=(-1.25 + center[1], 1.25 + center[1]))
-
- if autopct is None:
- return slices, texts
- else:
- return slices, texts, autotexts
-
- @staticmethod
- def _errorevery_to_mask(x, errorevery):
- """
- Normalize `errorbar`'s *errorevery* to be a boolean mask for data *x*.
-
- This function is split out to be usable both by 2D and 3D errorbars.
- """
- if isinstance(errorevery, Integral):
- errorevery = (0, errorevery)
- if isinstance(errorevery, tuple):
- if (len(errorevery) == 2 and
- isinstance(errorevery[0], Integral) and
- isinstance(errorevery[1], Integral)):
- errorevery = slice(errorevery[0], None, errorevery[1])
- else:
- raise ValueError(
- f'{errorevery=!r} is a not a tuple of two integers')
- elif isinstance(errorevery, slice):
- pass
- elif not isinstance(errorevery, str) and np.iterable(errorevery):
- try:
- x[errorevery] # fancy indexing
- except (ValueError, IndexError) as err:
- raise ValueError(
- f"{errorevery=!r} is iterable but not a valid NumPy fancy "
- "index to match 'xerr'/'yerr'") from err
- else:
- raise ValueError(f"{errorevery=!r} is not a recognized value")
- everymask = np.zeros(len(x), bool)
- everymask[errorevery] = True
- return everymask
-
- @_preprocess_data(replace_names=["x", "y", "xerr", "yerr"],
- label_namer="y")
- @_docstring.dedent_interpd
- def errorbar(self, x, y, yerr=None, xerr=None,
- fmt='', ecolor=None, elinewidth=None, capsize=None,
- barsabove=False, lolims=False, uplims=False,
- xlolims=False, xuplims=False, errorevery=1, capthick=None,
- **kwargs):
- """
- Plot y versus x as lines and/or markers with attached errorbars.
-
- *x*, *y* define the data locations, *xerr*, *yerr* define the errorbar
- sizes. By default, this draws the data markers/lines as well as the
- errorbars. Use fmt='none' to draw errorbars without any data markers.
-
- .. versionadded:: 3.7
- Caps and error lines are drawn in polar coordinates on polar plots.
-
-
- Parameters
- ----------
- x, y : float or array-like
- The data positions.
-
- xerr, yerr : float or array-like, shape(N,) or shape(2, N), optional
- The errorbar sizes:
-
- - scalar: Symmetric +/- values for all data points.
- - shape(N,): Symmetric +/-values for each data point.
- - shape(2, N): Separate - and + values for each bar. First row
- contains the lower errors, the second row contains the upper
- errors.
- - *None*: No errorbar.
-
- All values must be >= 0.
-
- See :doc:`/gallery/statistics/errorbar_features`
- for an example on the usage of ``xerr`` and ``yerr``.
-
- fmt : str, default: ''
- The format for the data points / data lines. See `.plot` for
- details.
-
- Use 'none' (case-insensitive) to plot errorbars without any data
- markers.
-
- ecolor : color, default: None
- The color of the errorbar lines. If None, use the color of the
- line connecting the markers.
-
- elinewidth : float, default: None
- The linewidth of the errorbar lines. If None, the linewidth of
- the current style is used.
-
- capsize : float, default: :rc:`errorbar.capsize`
- The length of the error bar caps in points.
-
- capthick : float, default: None
- An alias to the keyword argument *markeredgewidth* (a.k.a. *mew*).
- This setting is a more sensible name for the property that
- controls the thickness of the error bar cap in points. For
- backwards compatibility, if *mew* or *markeredgewidth* are given,
- then they will over-ride *capthick*. This may change in future
- releases.
-
- barsabove : bool, default: False
- If True, will plot the errorbars above the plot
- symbols. Default is below.
-
- lolims, uplims, xlolims, xuplims : bool or array-like, default: False
- These arguments can be used to indicate that a value gives only
- upper/lower limits. In that case a caret symbol is used to
- indicate this. *lims*-arguments may be scalars, or array-likes of
- the same length as *xerr* and *yerr*. To use limits with inverted
- axes, `~.Axes.set_xlim` or `~.Axes.set_ylim` must be called before
- :meth:`errorbar`. Note the tricky parameter names: setting e.g.
- *lolims* to True means that the y-value is a *lower* limit of the
- True value, so, only an *upward*-pointing arrow will be drawn!
-
- errorevery : int or (int, int), default: 1
- draws error bars on a subset of the data. *errorevery* =N draws
- error bars on the points (x[::N], y[::N]).
- *errorevery* =(start, N) draws error bars on the points
- (x[start::N], y[start::N]). e.g. errorevery=(6, 3)
- adds error bars to the data at (x[6], x[9], x[12], x[15], ...).
- Used to avoid overlapping error bars when two series share x-axis
- values.
-
- Returns
- -------
- `.ErrorbarContainer`
- The container contains:
-
- - plotline: `~matplotlib.lines.Line2D` instance of x, y plot markers
- and/or line.
- - caplines: A tuple of `~matplotlib.lines.Line2D` instances of the error
- bar caps.
- - barlinecols: A tuple of `.LineCollection` with the horizontal and
- vertical error ranges.
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- All other keyword arguments are passed on to the `~.Axes.plot` call
- drawing the markers. For example, this code makes big red squares
- with thick green edges::
-
- x, y, yerr = rand(3, 10)
- errorbar(x, y, yerr, marker='s', mfc='red',
- mec='green', ms=20, mew=4)
-
- where *mfc*, *mec*, *ms* and *mew* are aliases for the longer
- property names, *markerfacecolor*, *markeredgecolor*, *markersize*
- and *markeredgewidth*.
-
- Valid kwargs for the marker properties are:
-
- - *dashes*
- - *dash_capstyle*
- - *dash_joinstyle*
- - *drawstyle*
- - *fillstyle*
- - *linestyle*
- - *marker*
- - *markeredgecolor*
- - *markeredgewidth*
- - *markerfacecolor*
- - *markerfacecoloralt*
- - *markersize*
- - *markevery*
- - *solid_capstyle*
- - *solid_joinstyle*
-
- Refer to the corresponding `.Line2D` property for more details:
-
- %(Line2D:kwdoc)s
- """
- kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
- # Drop anything that comes in as None to use the default instead.
- kwargs = {k: v for k, v in kwargs.items() if v is not None}
- kwargs.setdefault('zorder', 2)
-
- # Casting to object arrays preserves units.
- if not isinstance(x, np.ndarray):
- x = np.asarray(x, dtype=object)
- if not isinstance(y, np.ndarray):
- y = np.asarray(y, dtype=object)
-
- def _upcast_err(err):
- """
- Safely handle tuple of containers that carry units.
-
- This function covers the case where the input to the xerr/yerr is a
- length 2 tuple of equal length ndarray-subclasses that carry the
- unit information in the container.
-
- If we have a tuple of nested numpy array (subclasses), we defer
- coercing the units to be consistent to the underlying unit
- library (and implicitly the broadcasting).
-
- Otherwise, fallback to casting to an object array.
- """
-
- if (
- # make sure it is not a scalar
- np.iterable(err) and
- # and it is not empty
- len(err) > 0 and
- # and the first element is an array sub-class use
- # safe_first_element because getitem is index-first not
- # location first on pandas objects so err[0] almost always
- # fails.
- isinstance(cbook._safe_first_finite(err), np.ndarray)
- ):
- # Get the type of the first element
- atype = type(cbook._safe_first_finite(err))
- # Promote the outer container to match the inner container
- if atype is np.ndarray:
- # Converts using np.asarray, because data cannot
- # be directly passed to init of np.ndarray
- return np.asarray(err, dtype=object)
- # If atype is not np.ndarray, directly pass data to init.
- # This works for types such as unyts and astropy units
- return atype(err)
- # Otherwise wrap it in an object array
- return np.asarray(err, dtype=object)
-
- if xerr is not None and not isinstance(xerr, np.ndarray):
- xerr = _upcast_err(xerr)
- if yerr is not None and not isinstance(yerr, np.ndarray):
- yerr = _upcast_err(yerr)
- x, y = np.atleast_1d(x, y) # Make sure all the args are iterable.
- if len(x) != len(y):
- raise ValueError("'x' and 'y' must have the same size")
-
- everymask = self._errorevery_to_mask(x, errorevery)
-
- label = kwargs.pop("label", None)
- kwargs['label'] = '_nolegend_'
-
- # Create the main line and determine overall kwargs for child artists.
- # We avoid calling self.plot() directly, or self._get_lines(), because
- # that would call self._process_unit_info again, and do other indirect
- # data processing.
- (data_line, base_style), = self._get_lines._plot_args(
- self, (x, y) if fmt == '' else (x, y, fmt), kwargs, return_kwargs=True)
-
- # Do this after creating `data_line` to avoid modifying `base_style`.
- if barsabove:
- data_line.set_zorder(kwargs['zorder'] - .1)
- else:
- data_line.set_zorder(kwargs['zorder'] + .1)
-
- # Add line to plot, or throw it away and use it to determine kwargs.
- if fmt.lower() != 'none':
- self.add_line(data_line)
- else:
- data_line = None
- # Remove alpha=0 color that _get_lines._plot_args returns for
- # 'none' format, and replace it with user-specified color, if
- # supplied.
- base_style.pop('color')
- if 'color' in kwargs:
- base_style['color'] = kwargs.pop('color')
-
- if 'color' not in base_style:
- base_style['color'] = 'C0'
- if ecolor is None:
- ecolor = base_style['color']
-
- # Eject any line-specific information from format string, as it's not
- # needed for bars or caps.
- for key in ['marker', 'markersize', 'markerfacecolor',
- 'markerfacecoloralt',
- 'markeredgewidth', 'markeredgecolor', 'markevery',
- 'linestyle', 'fillstyle', 'drawstyle', 'dash_capstyle',
- 'dash_joinstyle', 'solid_capstyle', 'solid_joinstyle',
- 'dashes']:
- base_style.pop(key, None)
-
- # Make the style dict for the line collections (the bars).
- eb_lines_style = {**base_style, 'color': ecolor}
-
- if elinewidth is not None:
- eb_lines_style['linewidth'] = elinewidth
- elif 'linewidth' in kwargs:
- eb_lines_style['linewidth'] = kwargs['linewidth']
-
- for key in ('transform', 'alpha', 'zorder', 'rasterized'):
- if key in kwargs:
- eb_lines_style[key] = kwargs[key]
-
- # Make the style dict for caps (the "hats").
- eb_cap_style = {**base_style, 'linestyle': 'none'}
- if capsize is None:
- capsize = mpl.rcParams["errorbar.capsize"]
- if capsize > 0:
- eb_cap_style['markersize'] = 2. * capsize
- if capthick is not None:
- eb_cap_style['markeredgewidth'] = capthick
-
- # For backwards-compat, allow explicit setting of
- # 'markeredgewidth' to over-ride capthick.
- for key in ('markeredgewidth', 'transform', 'alpha',
- 'zorder', 'rasterized'):
- if key in kwargs:
- eb_cap_style[key] = kwargs[key]
- eb_cap_style['color'] = ecolor
-
- barcols = []
- caplines = {'x': [], 'y': []}
-
- # Vectorized fancy-indexer.
- def apply_mask(arrays, mask):
- return [array[mask] for array in arrays]
-
- # dep: dependent dataset, indep: independent dataset
- for (dep_axis, dep, err, lolims, uplims, indep, lines_func,
- marker, lomarker, himarker) in [
- ("x", x, xerr, xlolims, xuplims, y, self.hlines,
- "|", mlines.CARETRIGHTBASE, mlines.CARETLEFTBASE),
- ("y", y, yerr, lolims, uplims, x, self.vlines,
- "_", mlines.CARETUPBASE, mlines.CARETDOWNBASE),
- ]:
- if err is None:
- continue
- lolims = np.broadcast_to(lolims, len(dep)).astype(bool)
- uplims = np.broadcast_to(uplims, len(dep)).astype(bool)
- try:
- np.broadcast_to(err, (2, len(dep)))
- except ValueError:
- raise ValueError(
- f"'{dep_axis}err' (shape: {np.shape(err)}) must be a "
- f"scalar or a 1D or (2, n) array-like whose shape matches "
- f"'{dep_axis}' (shape: {np.shape(dep)})") from None
- res = np.zeros(err.shape, dtype=bool) # Default in case of nan
- if np.any(np.less(err, -err, out=res, where=(err == err))):
- # like err<0, but also works for timedelta and nan.
- raise ValueError(
- f"'{dep_axis}err' must not contain negative values")
- # This is like
- # elow, ehigh = np.broadcast_to(...)
- # return dep - elow * ~lolims, dep + ehigh * ~uplims
- # except that broadcast_to would strip units.
- low, high = dep + np.vstack([-(1 - lolims), 1 - uplims]) * err
- barcols.append(lines_func(
- *apply_mask([indep, low, high], everymask), **eb_lines_style))
- if self.name == "polar" and dep_axis == "x":
- for b in barcols:
- for p in b.get_paths():
- p._interpolation_steps = 2
- # Normal errorbars for points without upper/lower limits.
- nolims = ~(lolims | uplims)
- if nolims.any() and capsize > 0:
- indep_masked, lo_masked, hi_masked = apply_mask(
- [indep, low, high], nolims & everymask)
- for lh_masked in [lo_masked, hi_masked]:
- # Since this has to work for x and y as dependent data, we
- # first set both x and y to the independent variable and
- # overwrite the respective dependent data in a second step.
- line = mlines.Line2D(indep_masked, indep_masked,
- marker=marker, **eb_cap_style)
- line.set(**{f"{dep_axis}data": lh_masked})
- caplines[dep_axis].append(line)
- for idx, (lims, hl) in enumerate([(lolims, high), (uplims, low)]):
- if not lims.any():
- continue
- hlmarker = (
- himarker
- if self._axis_map[dep_axis].get_inverted() ^ idx
- else lomarker)
- x_masked, y_masked, hl_masked = apply_mask(
- [x, y, hl], lims & everymask)
- # As above, we set the dependent data in a second step.
- line = mlines.Line2D(x_masked, y_masked,
- marker=hlmarker, **eb_cap_style)
- line.set(**{f"{dep_axis}data": hl_masked})
- caplines[dep_axis].append(line)
- if capsize > 0:
- caplines[dep_axis].append(mlines.Line2D(
- x_masked, y_masked, marker=marker, **eb_cap_style))
- if self.name == 'polar':
- for axis in caplines:
- for l in caplines[axis]:
- # Rotate caps to be perpendicular to the error bars
- for theta, r in zip(l.get_xdata(), l.get_ydata()):
- rotation = mtransforms.Affine2D().rotate(theta)
- if axis == 'y':
- rotation.rotate(-np.pi / 2)
- ms = mmarkers.MarkerStyle(marker=marker,
- transform=rotation)
- self.add_line(mlines.Line2D([theta], [r], marker=ms,
- **eb_cap_style))
- else:
- for axis in caplines:
- for l in caplines[axis]:
- self.add_line(l)
-
- self._request_autoscale_view()
- caplines = caplines['x'] + caplines['y']
- errorbar_container = ErrorbarContainer(
- (data_line, tuple(caplines), tuple(barcols)),
- has_xerr=(xerr is not None), has_yerr=(yerr is not None),
- label=label)
- self.containers.append(errorbar_container)
-
- return errorbar_container # (l0, caplines, barcols)
-
- @_preprocess_data()
- def boxplot(self, x, notch=None, sym=None, vert=None, whis=None,
- positions=None, widths=None, patch_artist=None,
- bootstrap=None, usermedians=None, conf_intervals=None,
- meanline=None, showmeans=None, showcaps=None,
- showbox=None, showfliers=None, boxprops=None,
- labels=None, flierprops=None, medianprops=None,
- meanprops=None, capprops=None, whiskerprops=None,
- manage_ticks=True, autorange=False, zorder=None,
- capwidths=None):
- """
- Draw a box and whisker plot.
-
- The box extends from the first quartile (Q1) to the third
- quartile (Q3) of the data, with a line at the median.
- The whiskers extend from the box to the farthest data point
- lying within 1.5x the inter-quartile range (IQR) from the box.
- Flier points are those past the end of the whiskers.
- See https://en.wikipedia.org/wiki/Box_plot for reference.
-
- .. code-block:: none
-
- Q1-1.5IQR Q1 median Q3 Q3+1.5IQR
- |-----:-----|
- o |--------| : |--------| o o
- |-----:-----|
- flier <-----------> fliers
- IQR
-
-
- Parameters
- ----------
- x : Array or a sequence of vectors.
- The input data. If a 2D array, a boxplot is drawn for each column
- in *x*. If a sequence of 1D arrays, a boxplot is drawn for each
- array in *x*.
-
- notch : bool, default: False
- Whether to draw a notched boxplot (`True`), or a rectangular
- boxplot (`False`). The notches represent the confidence interval
- (CI) around the median. The documentation for *bootstrap*
- describes how the locations of the notches are computed by
- default, but their locations may also be overridden by setting the
- *conf_intervals* parameter.
-
- .. note::
-
- In cases where the values of the CI are less than the
- lower quartile or greater than the upper quartile, the
- notches will extend beyond the box, giving it a
- distinctive "flipped" appearance. This is expected
- behavior and consistent with other statistical
- visualization packages.
-
- sym : str, optional
- The default symbol for flier points. An empty string ('') hides
- the fliers. If `None`, then the fliers default to 'b+'. More
- control is provided by the *flierprops* parameter.
-
- vert : bool, default: True
- If `True`, draws vertical boxes.
- If `False`, draw horizontal boxes.
-
- whis : float or (float, float), default: 1.5
- The position of the whiskers.
-
- If a float, the lower whisker is at the lowest datum above
- ``Q1 - whis*(Q3-Q1)``, and the upper whisker at the highest datum
- below ``Q3 + whis*(Q3-Q1)``, where Q1 and Q3 are the first and
- third quartiles. The default value of ``whis = 1.5`` corresponds
- to Tukey's original definition of boxplots.
-
- If a pair of floats, they indicate the percentiles at which to
- draw the whiskers (e.g., (5, 95)). In particular, setting this to
- (0, 100) results in whiskers covering the whole range of the data.
-
- In the edge case where ``Q1 == Q3``, *whis* is automatically set
- to (0, 100) (cover the whole range of the data) if *autorange* is
- True.
-
- Beyond the whiskers, data are considered outliers and are plotted
- as individual points.
-
- bootstrap : int, optional
- Specifies whether to bootstrap the confidence intervals
- around the median for notched boxplots. If *bootstrap* is
- None, no bootstrapping is performed, and notches are
- calculated using a Gaussian-based asymptotic approximation
- (see McGill, R., Tukey, J.W., and Larsen, W.A., 1978, and
- Kendall and Stuart, 1967). Otherwise, bootstrap specifies
- the number of times to bootstrap the median to determine its
- 95% confidence intervals. Values between 1000 and 10000 are
- recommended.
-
- usermedians : 1D array-like, optional
- A 1D array-like of length ``len(x)``. Each entry that is not
- `None` forces the value of the median for the corresponding
- dataset. For entries that are `None`, the medians are computed
- by Matplotlib as normal.
-
- conf_intervals : array-like, optional
- A 2D array-like of shape ``(len(x), 2)``. Each entry that is not
- None forces the location of the corresponding notch (which is
- only drawn if *notch* is `True`). For entries that are `None`,
- the notches are computed by the method specified by the other
- parameters (e.g., *bootstrap*).
-
- positions : array-like, optional
- The positions of the boxes. The ticks and limits are
- automatically set to match the positions. Defaults to
- ``range(1, N+1)`` where N is the number of boxes to be drawn.
-
- widths : float or array-like
- The widths of the boxes. The default is 0.5, or ``0.15*(distance
- between extreme positions)``, if that is smaller.
-
- patch_artist : bool, default: False
- If `False` produces boxes with the Line2D artist. Otherwise,
- boxes are drawn with Patch artists.
-
- labels : sequence, optional
- Labels for each dataset (one per dataset).
-
- manage_ticks : bool, default: True
- If True, the tick locations and labels will be adjusted to match
- the boxplot positions.
-
- autorange : bool, default: False
- When `True` and the data are distributed such that the 25th and
- 75th percentiles are equal, *whis* is set to (0, 100) such
- that the whisker ends are at the minimum and maximum of the data.
-
- meanline : bool, default: False
- If `True` (and *showmeans* is `True`), will try to render the
- mean as a line spanning the full width of the box according to
- *meanprops* (see below). Not recommended if *shownotches* is also
- True. Otherwise, means will be shown as points.
-
- zorder : float, default: ``Line2D.zorder = 2``
- The zorder of the boxplot.
-
- Returns
- -------
- dict
- A dictionary mapping each component of the boxplot to a list
- of the `.Line2D` instances created. That dictionary has the
- following keys (assuming vertical boxplots):
-
- - ``boxes``: the main body of the boxplot showing the
- quartiles and the median's confidence intervals if
- enabled.
-
- - ``medians``: horizontal lines at the median of each box.
-
- - ``whiskers``: the vertical lines extending to the most
- extreme, non-outlier data points.
-
- - ``caps``: the horizontal lines at the ends of the
- whiskers.
-
- - ``fliers``: points representing data that extend beyond
- the whiskers (fliers).
-
- - ``means``: points or lines representing the means.
-
- Other Parameters
- ----------------
- showcaps : bool, default: True
- Show the caps on the ends of whiskers.
- showbox : bool, default: True
- Show the central box.
- showfliers : bool, default: True
- Show the outliers beyond the caps.
- showmeans : bool, default: False
- Show the arithmetic means.
- capprops : dict, default: None
- The style of the caps.
- capwidths : float or array, default: None
- The widths of the caps.
- boxprops : dict, default: None
- The style of the box.
- whiskerprops : dict, default: None
- The style of the whiskers.
- flierprops : dict, default: None
- The style of the fliers.
- medianprops : dict, default: None
- The style of the median.
- meanprops : dict, default: None
- The style of the mean.
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- See Also
- --------
- violinplot : Draw an estimate of the probability density function.
- """
-
- # Missing arguments default to rcParams.
- if whis is None:
- whis = mpl.rcParams['boxplot.whiskers']
- if bootstrap is None:
- bootstrap = mpl.rcParams['boxplot.bootstrap']
-
- bxpstats = cbook.boxplot_stats(x, whis=whis, bootstrap=bootstrap,
- labels=labels, autorange=autorange)
- if notch is None:
- notch = mpl.rcParams['boxplot.notch']
- if vert is None:
- vert = mpl.rcParams['boxplot.vertical']
- if patch_artist is None:
- patch_artist = mpl.rcParams['boxplot.patchartist']
- if meanline is None:
- meanline = mpl.rcParams['boxplot.meanline']
- if showmeans is None:
- showmeans = mpl.rcParams['boxplot.showmeans']
- if showcaps is None:
- showcaps = mpl.rcParams['boxplot.showcaps']
- if showbox is None:
- showbox = mpl.rcParams['boxplot.showbox']
- if showfliers is None:
- showfliers = mpl.rcParams['boxplot.showfliers']
-
- if boxprops is None:
- boxprops = {}
- if whiskerprops is None:
- whiskerprops = {}
- if capprops is None:
- capprops = {}
- if medianprops is None:
- medianprops = {}
- if meanprops is None:
- meanprops = {}
- if flierprops is None:
- flierprops = {}
-
- if patch_artist:
- boxprops['linestyle'] = 'solid' # Not consistent with bxp.
- if 'color' in boxprops:
- boxprops['edgecolor'] = boxprops.pop('color')
-
- # if non-default sym value, put it into the flier dictionary
- # the logic for providing the default symbol ('b+') now lives
- # in bxp in the initial value of flierkw
- # handle all of the *sym* related logic here so we only have to pass
- # on the flierprops dict.
- if sym is not None:
- # no-flier case, which should really be done with
- # 'showfliers=False' but none-the-less deal with it to keep back
- # compatibility
- if sym == '':
- # blow away existing dict and make one for invisible markers
- flierprops = dict(linestyle='none', marker='', color='none')
- # turn the fliers off just to be safe
- showfliers = False
- # now process the symbol string
- else:
- # process the symbol string
- # discarded linestyle
- _, marker, color = _process_plot_format(sym)
- # if we have a marker, use it
- if marker is not None:
- flierprops['marker'] = marker
- # if we have a color, use it
- if color is not None:
- # assume that if color is passed in the user want
- # filled symbol, if the users want more control use
- # flierprops
- flierprops['color'] = color
- flierprops['markerfacecolor'] = color
- flierprops['markeredgecolor'] = color
-
- # replace medians if necessary:
- if usermedians is not None:
- if (len(np.ravel(usermedians)) != len(bxpstats) or
- np.shape(usermedians)[0] != len(bxpstats)):
- raise ValueError(
- "'usermedians' and 'x' have different lengths")
- else:
- # reassign medians as necessary
- for stats, med in zip(bxpstats, usermedians):
- if med is not None:
- stats['med'] = med
-
- if conf_intervals is not None:
- if len(conf_intervals) != len(bxpstats):
- raise ValueError(
- "'conf_intervals' and 'x' have different lengths")
- else:
- for stats, ci in zip(bxpstats, conf_intervals):
- if ci is not None:
- if len(ci) != 2:
- raise ValueError('each confidence interval must '
- 'have two values')
- else:
- if ci[0] is not None:
- stats['cilo'] = ci[0]
- if ci[1] is not None:
- stats['cihi'] = ci[1]
-
- artists = self.bxp(bxpstats, positions=positions, widths=widths,
- vert=vert, patch_artist=patch_artist,
- shownotches=notch, showmeans=showmeans,
- showcaps=showcaps, showbox=showbox,
- boxprops=boxprops, flierprops=flierprops,
- medianprops=medianprops, meanprops=meanprops,
- meanline=meanline, showfliers=showfliers,
- capprops=capprops, whiskerprops=whiskerprops,
- manage_ticks=manage_ticks, zorder=zorder,
- capwidths=capwidths)
- return artists
-
- def bxp(self, bxpstats, positions=None, widths=None, vert=True,
- patch_artist=False, shownotches=False, showmeans=False,
- showcaps=True, showbox=True, showfliers=True,
- boxprops=None, whiskerprops=None, flierprops=None,
- medianprops=None, capprops=None, meanprops=None,
- meanline=False, manage_ticks=True, zorder=None,
- capwidths=None):
- """
- Drawing function for box and whisker plots.
-
- Make a box and whisker plot for each column of *x* or each
- vector in sequence *x*. The box extends from the lower to
- upper quartile values of the data, with a line at the median.
- The whiskers extend from the box to show the range of the
- data. Flier points are those past the end of the whiskers.
-
- Parameters
- ----------
- bxpstats : list of dicts
- A list of dictionaries containing stats for each boxplot.
- Required keys are:
-
- - ``med``: Median (scalar).
- - ``q1``, ``q3``: First & third quartiles (scalars).
- - ``whislo``, ``whishi``: Lower & upper whisker positions (scalars).
-
- Optional keys are:
-
- - ``mean``: Mean (scalar). Needed if ``showmeans=True``.
- - ``fliers``: Data beyond the whiskers (array-like).
- Needed if ``showfliers=True``.
- - ``cilo``, ``cihi``: Lower & upper confidence intervals
- about the median. Needed if ``shownotches=True``.
- - ``label``: Name of the dataset (str). If available,
- this will be used a tick label for the boxplot
-
- positions : array-like, default: [1, 2, ..., n]
- The positions of the boxes. The ticks and limits
- are automatically set to match the positions.
-
- widths : float or array-like, default: None
- The widths of the boxes. The default is
- ``clip(0.15*(distance between extreme positions), 0.15, 0.5)``.
-
- capwidths : float or array-like, default: None
- Either a scalar or a vector and sets the width of each cap.
- The default is ``0.5*(width of the box)``, see *widths*.
-
- vert : bool, default: True
- If `True` (default), makes the boxes vertical.
- If `False`, makes horizontal boxes.
-
- patch_artist : bool, default: False
- If `False` produces boxes with the `.Line2D` artist.
- If `True` produces boxes with the `~matplotlib.patches.Patch` artist.
-
- shownotches, showmeans, showcaps, showbox, showfliers : bool
- Whether to draw the CI notches, the mean value (both default to
- False), the caps, the box, and the fliers (all three default to
- True).
-
- boxprops, whiskerprops, capprops, flierprops, medianprops, meanprops :\
- dict, optional
- Artist properties for the boxes, whiskers, caps, fliers, medians, and
- means.
-
- meanline : bool, default: False
- If `True` (and *showmeans* is `True`), will try to render the mean
- as a line spanning the full width of the box according to
- *meanprops*. Not recommended if *shownotches* is also True.
- Otherwise, means will be shown as points.
-
- manage_ticks : bool, default: True
- If True, the tick locations and labels will be adjusted to match the
- boxplot positions.
-
- zorder : float, default: ``Line2D.zorder = 2``
- The zorder of the resulting boxplot.
-
- Returns
- -------
- dict
- A dictionary mapping each component of the boxplot to a list
- of the `.Line2D` instances created. That dictionary has the
- following keys (assuming vertical boxplots):
-
- - ``boxes``: main bodies of the boxplot showing the quartiles, and
- the median's confidence intervals if enabled.
- - ``medians``: horizontal lines at the median of each box.
- - ``whiskers``: vertical lines up to the last non-outlier data.
- - ``caps``: horizontal lines at the ends of the whiskers.
- - ``fliers``: points representing data beyond the whiskers (fliers).
- - ``means``: points or lines representing the means.
-
- Examples
- --------
- .. plot:: gallery/statistics/bxp.py
- """
- # Clamp median line to edge of box by default.
- medianprops = {
- "solid_capstyle": "butt",
- "dash_capstyle": "butt",
- **(medianprops or {}),
- }
- meanprops = {
- "solid_capstyle": "butt",
- "dash_capstyle": "butt",
- **(meanprops or {}),
- }
-
- # lists of artists to be output
- whiskers = []
- caps = []
- boxes = []
- medians = []
- means = []
- fliers = []
-
- # empty list of xticklabels
- datalabels = []
-
- # Use default zorder if none specified
- if zorder is None:
- zorder = mlines.Line2D.zorder
-
- zdelta = 0.1
-
- def merge_kw_rc(subkey, explicit, zdelta=0, usemarker=True):
- d = {k.split('.')[-1]: v for k, v in mpl.rcParams.items()
- if k.startswith(f'boxplot.{subkey}props')}
- d['zorder'] = zorder + zdelta
- if not usemarker:
- d['marker'] = ''
- d.update(cbook.normalize_kwargs(explicit, mlines.Line2D))
- return d
-
- box_kw = {
- 'linestyle': mpl.rcParams['boxplot.boxprops.linestyle'],
- 'linewidth': mpl.rcParams['boxplot.boxprops.linewidth'],
- 'edgecolor': mpl.rcParams['boxplot.boxprops.color'],
- 'facecolor': ('white' if mpl.rcParams['_internal.classic_mode']
- else mpl.rcParams['patch.facecolor']),
- 'zorder': zorder,
- **cbook.normalize_kwargs(boxprops, mpatches.PathPatch)
- } if patch_artist else merge_kw_rc('box', boxprops, usemarker=False)
- whisker_kw = merge_kw_rc('whisker', whiskerprops, usemarker=False)
- cap_kw = merge_kw_rc('cap', capprops, usemarker=False)
- flier_kw = merge_kw_rc('flier', flierprops)
- median_kw = merge_kw_rc('median', medianprops, zdelta, usemarker=False)
- mean_kw = merge_kw_rc('mean', meanprops, zdelta)
- removed_prop = 'marker' if meanline else 'linestyle'
- # Only remove the property if it's not set explicitly as a parameter.
- if meanprops is None or removed_prop not in meanprops:
- mean_kw[removed_prop] = ''
-
- # vertical or horizontal plot?
- maybe_swap = slice(None) if vert else slice(None, None, -1)
-
- def do_plot(xs, ys, **kwargs):
- return self.plot(*[xs, ys][maybe_swap], **kwargs)[0]
-
- def do_patch(xs, ys, **kwargs):
- path = mpath.Path._create_closed(
- np.column_stack([xs, ys][maybe_swap]))
- patch = mpatches.PathPatch(path, **kwargs)
- self.add_artist(patch)
- return patch
-
- # input validation
- N = len(bxpstats)
- datashape_message = ("List of boxplot statistics and `{0}` "
- "values must have same the length")
- # check position
- if positions is None:
- positions = list(range(1, N + 1))
- elif len(positions) != N:
- raise ValueError(datashape_message.format("positions"))
-
- positions = np.array(positions)
- if len(positions) > 0 and not all(isinstance(p, Real) for p in positions):
- raise TypeError("positions should be an iterable of numbers")
-
- # width
- if widths is None:
- widths = [np.clip(0.15 * np.ptp(positions), 0.15, 0.5)] * N
- elif np.isscalar(widths):
- widths = [widths] * N
- elif len(widths) != N:
- raise ValueError(datashape_message.format("widths"))
-
- # capwidth
- if capwidths is None:
- capwidths = 0.5 * np.array(widths)
- elif np.isscalar(capwidths):
- capwidths = [capwidths] * N
- elif len(capwidths) != N:
- raise ValueError(datashape_message.format("capwidths"))
-
- for pos, width, stats, capwidth in zip(positions, widths, bxpstats,
- capwidths):
- # try to find a new label
- datalabels.append(stats.get('label', pos))
-
- # whisker coords
- whis_x = [pos, pos]
- whislo_y = [stats['q1'], stats['whislo']]
- whishi_y = [stats['q3'], stats['whishi']]
- # cap coords
- cap_left = pos - capwidth * 0.5
- cap_right = pos + capwidth * 0.5
- cap_x = [cap_left, cap_right]
- cap_lo = np.full(2, stats['whislo'])
- cap_hi = np.full(2, stats['whishi'])
- # box and median coords
- box_left = pos - width * 0.5
- box_right = pos + width * 0.5
- med_y = [stats['med'], stats['med']]
- # notched boxes
- if shownotches:
- notch_left = pos - width * 0.25
- notch_right = pos + width * 0.25
- box_x = [box_left, box_right, box_right, notch_right,
- box_right, box_right, box_left, box_left, notch_left,
- box_left, box_left]
- box_y = [stats['q1'], stats['q1'], stats['cilo'],
- stats['med'], stats['cihi'], stats['q3'],
- stats['q3'], stats['cihi'], stats['med'],
- stats['cilo'], stats['q1']]
- med_x = [notch_left, notch_right]
- # plain boxes
- else:
- box_x = [box_left, box_right, box_right, box_left, box_left]
- box_y = [stats['q1'], stats['q1'], stats['q3'], stats['q3'],
- stats['q1']]
- med_x = [box_left, box_right]
-
- # maybe draw the box
- if showbox:
- do_box = do_patch if patch_artist else do_plot
- boxes.append(do_box(box_x, box_y, **box_kw))
- # draw the whiskers
- whiskers.append(do_plot(whis_x, whislo_y, **whisker_kw))
- whiskers.append(do_plot(whis_x, whishi_y, **whisker_kw))
- # maybe draw the caps
- if showcaps:
- caps.append(do_plot(cap_x, cap_lo, **cap_kw))
- caps.append(do_plot(cap_x, cap_hi, **cap_kw))
- # draw the medians
- medians.append(do_plot(med_x, med_y, **median_kw))
- # maybe draw the means
- if showmeans:
- if meanline:
- means.append(do_plot(
- [box_left, box_right], [stats['mean'], stats['mean']],
- **mean_kw
- ))
- else:
- means.append(do_plot([pos], [stats['mean']], **mean_kw))
- # maybe draw the fliers
- if showfliers:
- flier_x = np.full(len(stats['fliers']), pos, dtype=np.float64)
- flier_y = stats['fliers']
- fliers.append(do_plot(flier_x, flier_y, **flier_kw))
-
- if manage_ticks:
- axis_name = "x" if vert else "y"
- interval = getattr(self.dataLim, f"interval{axis_name}")
- axis = self._axis_map[axis_name]
- positions = axis.convert_units(positions)
- # The 0.5 additional padding ensures reasonable-looking boxes
- # even when drawing a single box. We set the sticky edge to
- # prevent margins expansion, in order to match old behavior (back
- # when separate calls to boxplot() would completely reset the axis
- # limits regardless of what was drawn before). The sticky edges
- # are attached to the median lines, as they are always present.
- interval[:] = (min(interval[0], min(positions) - .5),
- max(interval[1], max(positions) + .5))
- for median, position in zip(medians, positions):
- getattr(median.sticky_edges, axis_name).extend(
- [position - .5, position + .5])
- # Modified from Axis.set_ticks and Axis.set_ticklabels.
- locator = axis.get_major_locator()
- if not isinstance(axis.get_major_locator(),
- mticker.FixedLocator):
- locator = mticker.FixedLocator([])
- axis.set_major_locator(locator)
- locator.locs = np.array([*locator.locs, *positions])
- formatter = axis.get_major_formatter()
- if not isinstance(axis.get_major_formatter(),
- mticker.FixedFormatter):
- formatter = mticker.FixedFormatter([])
- axis.set_major_formatter(formatter)
- formatter.seq = [*formatter.seq, *datalabels]
-
- self._request_autoscale_view()
-
- return dict(whiskers=whiskers, caps=caps, boxes=boxes,
- medians=medians, fliers=fliers, means=means)
-
- @staticmethod
- def _parse_scatter_color_args(c, edgecolors, kwargs, xsize,
- get_next_color_func):
- """
- Helper function to process color related arguments of `.Axes.scatter`.
-
- Argument precedence for facecolors:
-
- - c (if not None)
- - kwargs['facecolor']
- - kwargs['facecolors']
- - kwargs['color'] (==kwcolor)
- - 'b' if in classic mode else the result of ``get_next_color_func()``
-
- Argument precedence for edgecolors:
-
- - kwargs['edgecolor']
- - edgecolors (is an explicit kw argument in scatter())
- - kwargs['color'] (==kwcolor)
- - 'face' if not in classic mode else None
-
- Parameters
- ----------
- c : color or sequence or sequence of color or None
- See argument description of `.Axes.scatter`.
- edgecolors : color or sequence of color or {'face', 'none'} or None
- See argument description of `.Axes.scatter`.
- kwargs : dict
- Additional kwargs. If these keys exist, we pop and process them:
- 'facecolors', 'facecolor', 'edgecolor', 'color'
- Note: The dict is modified by this function.
- xsize : int
- The size of the x and y arrays passed to `.Axes.scatter`.
- get_next_color_func : callable
- A callable that returns a color. This color is used as facecolor
- if no other color is provided.
-
- Note, that this is a function rather than a fixed color value to
- support conditional evaluation of the next color. As of the
- current implementation obtaining the next color from the
- property cycle advances the cycle. This must only happen if we
- actually use the color, which will only be decided within this
- method.
-
- Returns
- -------
- c
- The input *c* if it was not *None*, else a color derived from the
- other inputs or defaults.
- colors : array(N, 4) or None
- The facecolors as RGBA values, or *None* if a colormap is used.
- edgecolors
- The edgecolor.
-
- """
- facecolors = kwargs.pop('facecolors', None)
- facecolors = kwargs.pop('facecolor', facecolors)
- edgecolors = kwargs.pop('edgecolor', edgecolors)
-
- kwcolor = kwargs.pop('color', None)
-
- if kwcolor is not None and c is not None:
- raise ValueError("Supply a 'c' argument or a 'color'"
- " kwarg but not both; they differ but"
- " their functionalities overlap.")
-
- if kwcolor is not None:
- try:
- mcolors.to_rgba_array(kwcolor)
- except ValueError as err:
- raise ValueError(
- "'color' kwarg must be a color or sequence of color "
- "specs. For a sequence of values to be color-mapped, use "
- "the 'c' argument instead.") from err
- if edgecolors is None:
- edgecolors = kwcolor
- if facecolors is None:
- facecolors = kwcolor
-
- if edgecolors is None and not mpl.rcParams['_internal.classic_mode']:
- edgecolors = mpl.rcParams['scatter.edgecolors']
-
- c_was_none = c is None
- if c is None:
- c = (facecolors if facecolors is not None
- else "b" if mpl.rcParams['_internal.classic_mode']
- else get_next_color_func())
- c_is_string_or_strings = (
- isinstance(c, str)
- or (np.iterable(c) and len(c) > 0
- and isinstance(cbook._safe_first_finite(c), str)))
-
- def invalid_shape_exception(csize, xsize):
- return ValueError(
- f"'c' argument has {csize} elements, which is inconsistent "
- f"with 'x' and 'y' with size {xsize}.")
-
- c_is_mapped = False # Unless proven otherwise below.
- valid_shape = True # Unless proven otherwise below.
- if not c_was_none and kwcolor is None and not c_is_string_or_strings:
- try: # First, does 'c' look suitable for value-mapping?
- c = np.asanyarray(c, dtype=float)
- except ValueError:
- pass # Failed to convert to float array; must be color specs.
- else:
- # handle the documented special case of a 2D array with 1
- # row which as RGB(A) to broadcast.
- if c.shape == (1, 4) or c.shape == (1, 3):
- c_is_mapped = False
- if c.size != xsize:
- valid_shape = False
- # If c can be either mapped values or an RGB(A) color, prefer
- # the former if shapes match, the latter otherwise.
- elif c.size == xsize:
- c = c.ravel()
- c_is_mapped = True
- else: # Wrong size; it must not be intended for mapping.
- if c.shape in ((3,), (4,)):
- _api.warn_external(
- "*c* argument looks like a single numeric RGB or "
- "RGBA sequence, which should be avoided as value-"
- "mapping will have precedence in case its length "
- "matches with *x* & *y*. Please use the *color* "
- "keyword-argument or provide a 2D array "
- "with a single row if you intend to specify "
- "the same RGB or RGBA value for all points.")
- valid_shape = False
- if not c_is_mapped:
- try: # Is 'c' acceptable as PathCollection facecolors?
- colors = mcolors.to_rgba_array(c)
- except (TypeError, ValueError) as err:
- if "RGBA values should be within 0-1 range" in str(err):
- raise
- else:
- if not valid_shape:
- raise invalid_shape_exception(c.size, xsize) from err
- # Both the mapping *and* the RGBA conversion failed: pretty
- # severe failure => one may appreciate a verbose feedback.
- raise ValueError(
- f"'c' argument must be a color, a sequence of colors, "
- f"or a sequence of numbers, not {c!r}") from err
- else:
- if len(colors) not in (0, 1, xsize):
- # NB: remember that a single color is also acceptable.
- # Besides *colors* will be an empty array if c == 'none'.
- raise invalid_shape_exception(len(colors), xsize)
- else:
- colors = None # use cmap, norm after collection is created
- return c, colors, edgecolors
-
- @_preprocess_data(replace_names=["x", "y", "s", "linewidths",
- "edgecolors", "c", "facecolor",
- "facecolors", "color"],
- label_namer="y")
- @_docstring.interpd
- def scatter(self, x, y, s=None, c=None, marker=None, cmap=None, norm=None,
- vmin=None, vmax=None, alpha=None, linewidths=None, *,
- edgecolors=None, plotnonfinite=False, **kwargs):
- """
- A scatter plot of *y* vs. *x* with varying marker size and/or color.
-
- Parameters
- ----------
- x, y : float or array-like, shape (n, )
- The data positions.
-
- s : float or array-like, shape (n, ), optional
- The marker size in points**2 (typographic points are 1/72 in.).
- Default is ``rcParams['lines.markersize'] ** 2``.
-
- The linewidth and edgecolor can visually interact with the marker
- size, and can lead to artifacts if the marker size is smaller than
- the linewidth.
-
- If the linewidth is greater than 0 and the edgecolor is anything
- but *'none'*, then the effective size of the marker will be
- increased by half the linewidth because the stroke will be centered
- on the edge of the shape.
-
- To eliminate the marker edge either set *linewidth=0* or
- *edgecolor='none'*.
-
- c : array-like or list of colors or color, optional
- The marker colors. Possible values:
-
- - A scalar or sequence of n numbers to be mapped to colors using
- *cmap* and *norm*.
- - A 2D array in which the rows are RGB or RGBA.
- - A sequence of colors of length n.
- - A single color format string.
-
- Note that *c* should not be a single numeric RGB or RGBA sequence
- because that is indistinguishable from an array of values to be
- colormapped. If you want to specify the same RGB or RGBA value for
- all points, use a 2D array with a single row. Otherwise,
- value-matching will have precedence in case of a size matching with
- *x* and *y*.
-
- If you wish to specify a single color for all points
- prefer the *color* keyword argument.
-
- Defaults to `None`. In that case the marker color is determined
- by the value of *color*, *facecolor* or *facecolors*. In case
- those are not specified or `None`, the marker color is determined
- by the next color of the ``Axes``' current "shape and fill" color
- cycle. This cycle defaults to :rc:`axes.prop_cycle`.
-
- marker : `~.markers.MarkerStyle`, default: :rc:`scatter.marker`
- The marker style. *marker* can be either an instance of the class
- or the text shorthand for a particular marker.
- See :mod:`matplotlib.markers` for more information about marker
- styles.
-
- %(cmap_doc)s
-
- This parameter is ignored if *c* is RGB(A).
-
- %(norm_doc)s
-
- This parameter is ignored if *c* is RGB(A).
-
- %(vmin_vmax_doc)s
-
- This parameter is ignored if *c* is RGB(A).
-
- alpha : float, default: None
- The alpha blending value, between 0 (transparent) and 1 (opaque).
-
- linewidths : float or array-like, default: :rc:`lines.linewidth`
- The linewidth of the marker edges. Note: The default *edgecolors*
- is 'face'. You may want to change this as well.
-
- edgecolors : {'face', 'none', *None*} or color or sequence of color, \
-default: :rc:`scatter.edgecolors`
- The edge color of the marker. Possible values:
-
- - 'face': The edge color will always be the same as the face color.
- - 'none': No patch boundary will be drawn.
- - A color or sequence of colors.
-
- For non-filled markers, *edgecolors* is ignored. Instead, the color
- is determined like with 'face', i.e. from *c*, *colors*, or
- *facecolors*.
-
- plotnonfinite : bool, default: False
- Whether to plot points with nonfinite *c* (i.e. ``inf``, ``-inf``
- or ``nan``). If ``True`` the points are drawn with the *bad*
- colormap color (see `.Colormap.set_bad`).
-
- Returns
- -------
- `~matplotlib.collections.PathCollection`
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
- **kwargs : `~matplotlib.collections.Collection` properties
-
- See Also
- --------
- plot : To plot scatter plots when markers are identical in size and
- color.
-
- Notes
- -----
- * The `.plot` function will be faster for scatterplots where markers
- don't vary in size or color.
-
- * Any or all of *x*, *y*, *s*, and *c* may be masked arrays, in which
- case all masks will be combined and only unmasked points will be
- plotted.
-
- * Fundamentally, scatter works with 1D arrays; *x*, *y*, *s*, and *c*
- may be input as N-D arrays, but within scatter they will be
- flattened. The exception is *c*, which will be flattened only if its
- size matches the size of *x* and *y*.
-
- """
- # add edgecolors and linewidths to kwargs so they
- # can be processed by normailze_kwargs
- if edgecolors is not None:
- kwargs.update({'edgecolors': edgecolors})
- if linewidths is not None:
- kwargs.update({'linewidths': linewidths})
-
- kwargs = cbook.normalize_kwargs(kwargs, mcoll.Collection)
- # re direct linewidth and edgecolor so it can be
- # further processed by the rest of the function
- linewidths = kwargs.pop('linewidth', None)
- edgecolors = kwargs.pop('edgecolor', None)
- # Process **kwargs to handle aliases, conflicts with explicit kwargs:
- x, y = self._process_unit_info([("x", x), ("y", y)], kwargs)
- # np.ma.ravel yields an ndarray, not a masked array,
- # unless its argument is a masked array.
- x = np.ma.ravel(x)
- y = np.ma.ravel(y)
- if x.size != y.size:
- raise ValueError("x and y must be the same size")
-
- if s is None:
- s = (20 if mpl.rcParams['_internal.classic_mode'] else
- mpl.rcParams['lines.markersize'] ** 2.0)
- s = np.ma.ravel(s)
- if (len(s) not in (1, x.size) or
- (not np.issubdtype(s.dtype, np.floating) and
- not np.issubdtype(s.dtype, np.integer))):
- raise ValueError(
- "s must be a scalar, "
- "or float array-like with the same size as x and y")
-
- # get the original edgecolor the user passed before we normalize
- orig_edgecolor = edgecolors
- if edgecolors is None:
- orig_edgecolor = kwargs.get('edgecolor', None)
- c, colors, edgecolors = \
- self._parse_scatter_color_args(
- c, edgecolors, kwargs, x.size,
- get_next_color_func=self._get_patches_for_fill.get_next_color)
-
- if plotnonfinite and colors is None:
- c = np.ma.masked_invalid(c)
- x, y, s, edgecolors, linewidths = \
- cbook._combine_masks(x, y, s, edgecolors, linewidths)
- else:
- x, y, s, c, colors, edgecolors, linewidths = \
- cbook._combine_masks(
- x, y, s, c, colors, edgecolors, linewidths)
- # Unmask edgecolors if it was actually a single RGB or RGBA.
- if (x.size in (3, 4)
- and np.ma.is_masked(edgecolors)
- and not np.ma.is_masked(orig_edgecolor)):
- edgecolors = edgecolors.data
-
- scales = s # Renamed for readability below.
-
- # load default marker from rcParams
- if marker is None:
- marker = mpl.rcParams['scatter.marker']
-
- if isinstance(marker, mmarkers.MarkerStyle):
- marker_obj = marker
- else:
- marker_obj = mmarkers.MarkerStyle(marker)
-
- path = marker_obj.get_path().transformed(
- marker_obj.get_transform())
- if not marker_obj.is_filled():
- if orig_edgecolor is not None:
- _api.warn_external(
- f"You passed a edgecolor/edgecolors ({orig_edgecolor!r}) "
- f"for an unfilled marker ({marker!r}). Matplotlib is "
- "ignoring the edgecolor in favor of the facecolor. This "
- "behavior may change in the future."
- )
- # We need to handle markers that cannot be filled (like
- # '+' and 'x') differently than markers that can be
- # filled, but have their fillstyle set to 'none'. This is
- # to get:
- #
- # - respecting the fillestyle if set
- # - maintaining back-compatibility for querying the facecolor of
- # the un-fillable markers.
- #
- # While not an ideal situation, but is better than the
- # alternatives.
- if marker_obj.get_fillstyle() == 'none':
- # promote the facecolor to be the edgecolor
- edgecolors = colors
- # set the facecolor to 'none' (at the last chance) because
- # we cannot fill a path if the facecolor is non-null
- # (which is defendable at the renderer level).
- colors = 'none'
- else:
- # if we are not nulling the face color we can do this
- # simpler
- edgecolors = 'face'
-
- if linewidths is None:
- linewidths = mpl.rcParams['lines.linewidth']
- elif np.iterable(linewidths):
- linewidths = [
- lw if lw is not None else mpl.rcParams['lines.linewidth']
- for lw in linewidths]
-
- offsets = np.ma.column_stack([x, y])
-
- collection = mcoll.PathCollection(
- (path,), scales,
- facecolors=colors,
- edgecolors=edgecolors,
- linewidths=linewidths,
- offsets=offsets,
- offset_transform=kwargs.pop('transform', self.transData),
- alpha=alpha,
- )
- collection.set_transform(mtransforms.IdentityTransform())
- if colors is None:
- collection.set_array(c)
- collection.set_cmap(cmap)
- collection.set_norm(norm)
- collection._scale_norm(norm, vmin, vmax)
- else:
- extra_kwargs = {
- 'cmap': cmap, 'norm': norm, 'vmin': vmin, 'vmax': vmax
- }
- extra_keys = [k for k, v in extra_kwargs.items() if v is not None]
- if any(extra_keys):
- keys_str = ", ".join(f"'{k}'" for k in extra_keys)
- _api.warn_external(
- "No data for colormapping provided via 'c'. "
- f"Parameters {keys_str} will be ignored")
- collection._internal_update(kwargs)
-
- # Classic mode only:
- # ensure there are margins to allow for the
- # finite size of the symbols. In v2.x, margins
- # are present by default, so we disable this
- # scatter-specific override.
- if mpl.rcParams['_internal.classic_mode']:
- if self._xmargin < 0.05 and x.size > 0:
- self.set_xmargin(0.05)
- if self._ymargin < 0.05 and x.size > 0:
- self.set_ymargin(0.05)
-
- self.add_collection(collection)
- self._request_autoscale_view()
-
- return collection
-
- @_preprocess_data(replace_names=["x", "y", "C"], label_namer="y")
- @_docstring.dedent_interpd
- def hexbin(self, x, y, C=None, gridsize=100, bins=None,
- xscale='linear', yscale='linear', extent=None,
- cmap=None, norm=None, vmin=None, vmax=None,
- alpha=None, linewidths=None, edgecolors='face',
- reduce_C_function=np.mean, mincnt=None, marginals=False,
- **kwargs):
- """
- Make a 2D hexagonal binning plot of points *x*, *y*.
-
- If *C* is *None*, the value of the hexagon is determined by the number
- of points in the hexagon. Otherwise, *C* specifies values at the
- coordinate (x[i], y[i]). For each hexagon, these values are reduced
- using *reduce_C_function*.
-
- Parameters
- ----------
- x, y : array-like
- The data positions. *x* and *y* must be of the same length.
-
- C : array-like, optional
- If given, these values are accumulated in the bins. Otherwise,
- every point has a value of 1. Must be of the same length as *x*
- and *y*.
-
- gridsize : int or (int, int), default: 100
- If a single int, the number of hexagons in the *x*-direction.
- The number of hexagons in the *y*-direction is chosen such that
- the hexagons are approximately regular.
-
- Alternatively, if a tuple (*nx*, *ny*), the number of hexagons
- in the *x*-direction and the *y*-direction. In the
- *y*-direction, counting is done along vertically aligned
- hexagons, not along the zig-zag chains of hexagons; see the
- following illustration.
-
- .. plot::
-
- import numpy
- import matplotlib.pyplot as plt
-
- np.random.seed(19680801)
- n= 300
- x = np.random.standard_normal(n)
- y = np.random.standard_normal(n)
-
- fig, ax = plt.subplots(figsize=(4, 4))
- h = ax.hexbin(x, y, gridsize=(5, 3))
- hx, hy = h.get_offsets().T
- ax.plot(hx[24::3], hy[24::3], 'ro-')
- ax.plot(hx[-3:], hy[-3:], 'ro-')
- ax.set_title('gridsize=(5, 3)')
- ax.axis('off')
-
- To get approximately regular hexagons, choose
- :math:`n_x = \\sqrt{3}\\,n_y`.
-
- bins : 'log' or int or sequence, default: None
- Discretization of the hexagon values.
-
- - If *None*, no binning is applied; the color of each hexagon
- directly corresponds to its count value.
- - If 'log', use a logarithmic scale for the colormap.
- Internally, :math:`log_{10}(i+1)` is used to determine the
- hexagon color. This is equivalent to ``norm=LogNorm()``.
- - If an integer, divide the counts in the specified number
- of bins, and color the hexagons accordingly.
- - If a sequence of values, the values of the lower bound of
- the bins to be used.
-
- xscale : {'linear', 'log'}, default: 'linear'
- Use a linear or log10 scale on the horizontal axis.
-
- yscale : {'linear', 'log'}, default: 'linear'
- Use a linear or log10 scale on the vertical axis.
-
- mincnt : int >= 0, default: *None*
- If not *None*, only display cells with at least *mincnt*
- number of points in the cell.
-
- marginals : bool, default: *False*
- If marginals is *True*, plot the marginal density as
- colormapped rectangles along the bottom of the x-axis and
- left of the y-axis.
-
- extent : 4-tuple of float, default: *None*
- The limits of the bins (xmin, xmax, ymin, ymax).
- The default assigns the limits based on
- *gridsize*, *x*, *y*, *xscale* and *yscale*.
-
- If *xscale* or *yscale* is set to 'log', the limits are
- expected to be the exponent for a power of 10. E.g. for
- x-limits of 1 and 50 in 'linear' scale and y-limits
- of 10 and 1000 in 'log' scale, enter (1, 50, 1, 3).
-
- Returns
- -------
- `~matplotlib.collections.PolyCollection`
- A `.PolyCollection` defining the hexagonal bins.
-
- - `.PolyCollection.get_offsets` contains a Mx2 array containing
- the x, y positions of the M hexagon centers.
- - `.PolyCollection.get_array` contains the values of the M
- hexagons.
-
- If *marginals* is *True*, horizontal
- bar and vertical bar (both PolyCollections) will be attached
- to the return collection as attributes *hbar* and *vbar*.
-
- Other Parameters
- ----------------
- %(cmap_doc)s
-
- %(norm_doc)s
-
- %(vmin_vmax_doc)s
-
- alpha : float between 0 and 1, optional
- The alpha blending value, between 0 (transparent) and 1 (opaque).
-
- linewidths : float, default: *None*
- If *None*, defaults to :rc:`patch.linewidth`.
-
- edgecolors : {'face', 'none', *None*} or color, default: 'face'
- The color of the hexagon edges. Possible values are:
-
- - 'face': Draw the edges in the same color as the fill color.
- - 'none': No edges are drawn. This can sometimes lead to unsightly
- unpainted pixels between the hexagons.
- - *None*: Draw outlines in the default color.
- - An explicit color.
-
- reduce_C_function : callable, default: `numpy.mean`
- The function to aggregate *C* within the bins. It is ignored if
- *C* is not given. This must have the signature::
-
- def reduce_C_function(C: array) -> float
-
- Commonly used functions are:
-
- - `numpy.mean`: average of the points
- - `numpy.sum`: integral of the point values
- - `numpy.amax`: value taken from the largest point
-
- By default will only reduce cells with at least 1 point because some
- reduction functions (such as `numpy.amax`) will error/warn with empty
- input. Changing *mincnt* will adjust the cutoff, and if set to 0 will
- pass empty input to the reduction function.
-
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs : `~matplotlib.collections.PolyCollection` properties
- All other keyword arguments are passed on to `.PolyCollection`:
-
- %(PolyCollection:kwdoc)s
-
- See Also
- --------
- hist2d : 2D histogram rectangular bins
- """
- self._process_unit_info([("x", x), ("y", y)], kwargs, convert=False)
-
- x, y, C = cbook.delete_masked_points(x, y, C)
-
- # Set the size of the hexagon grid
- if np.iterable(gridsize):
- nx, ny = gridsize
- else:
- nx = gridsize
- ny = int(nx / math.sqrt(3))
- # Count the number of data in each hexagon
- x = np.asarray(x, float)
- y = np.asarray(y, float)
-
- # Will be log()'d if necessary, and then rescaled.
- tx = x
- ty = y
-
- if xscale == 'log':
- if np.any(x <= 0.0):
- raise ValueError(
- "x contains non-positive values, so cannot be log-scaled")
- tx = np.log10(tx)
- if yscale == 'log':
- if np.any(y <= 0.0):
- raise ValueError(
- "y contains non-positive values, so cannot be log-scaled")
- ty = np.log10(ty)
- if extent is not None:
- xmin, xmax, ymin, ymax = extent
- else:
- xmin, xmax = (tx.min(), tx.max()) if len(x) else (0, 1)
- ymin, ymax = (ty.min(), ty.max()) if len(y) else (0, 1)
-
- # to avoid issues with singular data, expand the min/max pairs
- xmin, xmax = mtransforms.nonsingular(xmin, xmax, expander=0.1)
- ymin, ymax = mtransforms.nonsingular(ymin, ymax, expander=0.1)
-
- nx1 = nx + 1
- ny1 = ny + 1
- nx2 = nx
- ny2 = ny
- n = nx1 * ny1 + nx2 * ny2
-
- # In the x-direction, the hexagons exactly cover the region from
- # xmin to xmax. Need some padding to avoid roundoff errors.
- padding = 1.e-9 * (xmax - xmin)
- xmin -= padding
- xmax += padding
- sx = (xmax - xmin) / nx
- sy = (ymax - ymin) / ny
- # Positions in hexagon index coordinates.
- ix = (tx - xmin) / sx
- iy = (ty - ymin) / sy
- ix1 = np.round(ix).astype(int)
- iy1 = np.round(iy).astype(int)
- ix2 = np.floor(ix).astype(int)
- iy2 = np.floor(iy).astype(int)
- # flat indices, plus one so that out-of-range points go to position 0.
- i1 = np.where((0 <= ix1) & (ix1 < nx1) & (0 <= iy1) & (iy1 < ny1),
- ix1 * ny1 + iy1 + 1, 0)
- i2 = np.where((0 <= ix2) & (ix2 < nx2) & (0 <= iy2) & (iy2 < ny2),
- ix2 * ny2 + iy2 + 1, 0)
-
- d1 = (ix - ix1) ** 2 + 3.0 * (iy - iy1) ** 2
- d2 = (ix - ix2 - 0.5) ** 2 + 3.0 * (iy - iy2 - 0.5) ** 2
- bdist = (d1 < d2)
-
- if C is None: # [1:] drops out-of-range points.
- counts1 = np.bincount(i1[bdist], minlength=1 + nx1 * ny1)[1:]
- counts2 = np.bincount(i2[~bdist], minlength=1 + nx2 * ny2)[1:]
- accum = np.concatenate([counts1, counts2]).astype(float)
- if mincnt is not None:
- accum[accum < mincnt] = np.nan
- C = np.ones(len(x))
- else:
- # store the C values in a list per hexagon index
- Cs_at_i1 = [[] for _ in range(1 + nx1 * ny1)]
- Cs_at_i2 = [[] for _ in range(1 + nx2 * ny2)]
- for i in range(len(x)):
- if bdist[i]:
- Cs_at_i1[i1[i]].append(C[i])
- else:
- Cs_at_i2[i2[i]].append(C[i])
- if mincnt is None:
- mincnt = 1
- accum = np.array(
- [reduce_C_function(acc) if len(acc) >= mincnt else np.nan
- for Cs_at_i in [Cs_at_i1, Cs_at_i2]
- for acc in Cs_at_i[1:]], # [1:] drops out-of-range points.
- float)
-
- good_idxs = ~np.isnan(accum)
-
- offsets = np.zeros((n, 2), float)
- offsets[:nx1 * ny1, 0] = np.repeat(np.arange(nx1), ny1)
- offsets[:nx1 * ny1, 1] = np.tile(np.arange(ny1), nx1)
- offsets[nx1 * ny1:, 0] = np.repeat(np.arange(nx2) + 0.5, ny2)
- offsets[nx1 * ny1:, 1] = np.tile(np.arange(ny2), nx2) + 0.5
- offsets[:, 0] *= sx
- offsets[:, 1] *= sy
- offsets[:, 0] += xmin
- offsets[:, 1] += ymin
- # remove accumulation bins with no data
- offsets = offsets[good_idxs, :]
- accum = accum[good_idxs]
-
- polygon = [sx, sy / 3] * np.array(
- [[.5, -.5], [.5, .5], [0., 1.], [-.5, .5], [-.5, -.5], [0., -1.]])
-
- if linewidths is None:
- linewidths = [mpl.rcParams['patch.linewidth']]
-
- if xscale == 'log' or yscale == 'log':
- polygons = np.expand_dims(polygon, 0) + np.expand_dims(offsets, 1)
- if xscale == 'log':
- polygons[:, :, 0] = 10.0 ** polygons[:, :, 0]
- xmin = 10.0 ** xmin
- xmax = 10.0 ** xmax
- self.set_xscale(xscale)
- if yscale == 'log':
- polygons[:, :, 1] = 10.0 ** polygons[:, :, 1]
- ymin = 10.0 ** ymin
- ymax = 10.0 ** ymax
- self.set_yscale(yscale)
- collection = mcoll.PolyCollection(
- polygons,
- edgecolors=edgecolors,
- linewidths=linewidths,
- )
- else:
- collection = mcoll.PolyCollection(
- [polygon],
- edgecolors=edgecolors,
- linewidths=linewidths,
- offsets=offsets,
- offset_transform=mtransforms.AffineDeltaTransform(
- self.transData),
- )
-
- # Set normalizer if bins is 'log'
- if bins == 'log':
- if norm is not None:
- _api.warn_external("Only one of 'bins' and 'norm' arguments "
- f"can be supplied, ignoring bins={bins}")
- else:
- norm = mcolors.LogNorm(vmin=vmin, vmax=vmax)
- vmin = vmax = None
- bins = None
-
- # autoscale the norm with current accum values if it hasn't been set
- if norm is not None:
- if norm.vmin is None and norm.vmax is None:
- norm.autoscale(accum)
-
- if bins is not None:
- if not np.iterable(bins):
- minimum, maximum = min(accum), max(accum)
- bins -= 1 # one less edge than bins
- bins = minimum + (maximum - minimum) * np.arange(bins) / bins
- bins = np.sort(bins)
- accum = bins.searchsorted(accum)
-
- collection.set_array(accum)
- collection.set_cmap(cmap)
- collection.set_norm(norm)
- collection.set_alpha(alpha)
- collection._internal_update(kwargs)
- collection._scale_norm(norm, vmin, vmax)
-
- corners = ((xmin, ymin), (xmax, ymax))
- self.update_datalim(corners)
- self._request_autoscale_view(tight=True)
-
- # add the collection last
- self.add_collection(collection, autolim=False)
- if not marginals:
- return collection
-
- # Process marginals
- bars = []
- for zname, z, zmin, zmax, zscale, nbins in [
- ("x", x, xmin, xmax, xscale, nx),
- ("y", y, ymin, ymax, yscale, 2 * ny),
- ]:
-
- if zscale == "log":
- bin_edges = np.geomspace(zmin, zmax, nbins + 1)
- else:
- bin_edges = np.linspace(zmin, zmax, nbins + 1)
-
- verts = np.empty((nbins, 4, 2))
- verts[:, 0, 0] = verts[:, 1, 0] = bin_edges[:-1]
- verts[:, 2, 0] = verts[:, 3, 0] = bin_edges[1:]
- verts[:, 0, 1] = verts[:, 3, 1] = .00
- verts[:, 1, 1] = verts[:, 2, 1] = .05
- if zname == "y":
- verts = verts[:, :, ::-1] # Swap x and y.
-
- # Sort z-values into bins defined by bin_edges.
- bin_idxs = np.searchsorted(bin_edges, z) - 1
- values = np.empty(nbins)
- for i in range(nbins):
- # Get C-values for each bin, and compute bin value with
- # reduce_C_function.
- ci = C[bin_idxs == i]
- values[i] = reduce_C_function(ci) if len(ci) > 0 else np.nan
-
- mask = ~np.isnan(values)
- verts = verts[mask]
- values = values[mask]
-
- trans = getattr(self, f"get_{zname}axis_transform")(which="grid")
- bar = mcoll.PolyCollection(
- verts, transform=trans, edgecolors="face")
- bar.set_array(values)
- bar.set_cmap(cmap)
- bar.set_norm(norm)
- bar.set_alpha(alpha)
- bar._internal_update(kwargs)
- bars.append(self.add_collection(bar, autolim=False))
-
- collection.hbar, collection.vbar = bars
-
- def on_changed(collection):
- collection.hbar.set_cmap(collection.get_cmap())
- collection.hbar.set_cmap(collection.get_cmap())
- collection.vbar.set_clim(collection.get_clim())
- collection.vbar.set_clim(collection.get_clim())
-
- collection.callbacks.connect('changed', on_changed)
-
- return collection
-
- @_docstring.dedent_interpd
- def arrow(self, x, y, dx, dy, **kwargs):
- """
- Add an arrow to the Axes.
-
- This draws an arrow from ``(x, y)`` to ``(x+dx, y+dy)``.
-
- Parameters
- ----------
- %(FancyArrow)s
-
- Returns
- -------
- `.FancyArrow`
- The created `.FancyArrow` object.
-
- Notes
- -----
- The resulting arrow is affected by the Axes aspect ratio and limits.
- This may produce an arrow whose head is not square with its stem. To
- create an arrow whose head is square with its stem,
- use :meth:`annotate` for example:
-
- >>> ax.annotate("", xy=(0.5, 0.5), xytext=(0, 0),
- ... arrowprops=dict(arrowstyle="->"))
-
- """
- # Strip away units for the underlying patch since units
- # do not make sense to most patch-like code
- x = self.convert_xunits(x)
- y = self.convert_yunits(y)
- dx = self.convert_xunits(dx)
- dy = self.convert_yunits(dy)
-
- a = mpatches.FancyArrow(x, y, dx, dy, **kwargs)
- self.add_patch(a)
- self._request_autoscale_view()
- return a
-
- @_docstring.copy(mquiver.QuiverKey.__init__)
- def quiverkey(self, Q, X, Y, U, label, **kwargs):
- qk = mquiver.QuiverKey(Q, X, Y, U, label, **kwargs)
- self.add_artist(qk)
- return qk
-
- # Handle units for x and y, if they've been passed
- def _quiver_units(self, args, kwargs):
- if len(args) > 3:
- x, y = args[0:2]
- x, y = self._process_unit_info([("x", x), ("y", y)], kwargs)
- return (x, y) + args[2:]
- return args
-
- # args can be a combination of X, Y, U, V, C and all should be replaced
- @_preprocess_data()
- @_docstring.dedent_interpd
- def quiver(self, *args, **kwargs):
- """%(quiver_doc)s"""
- # Make sure units are handled for x and y values
- args = self._quiver_units(args, kwargs)
- q = mquiver.Quiver(self, *args, **kwargs)
- self.add_collection(q, autolim=True)
- self._request_autoscale_view()
- return q
-
- # args can be some combination of X, Y, U, V, C and all should be replaced
- @_preprocess_data()
- @_docstring.dedent_interpd
- def barbs(self, *args, **kwargs):
- """%(barbs_doc)s"""
- # Make sure units are handled for x and y values
- args = self._quiver_units(args, kwargs)
- b = mquiver.Barbs(self, *args, **kwargs)
- self.add_collection(b, autolim=True)
- self._request_autoscale_view()
- return b
-
- # Uses a custom implementation of data-kwarg handling in
- # _process_plot_var_args.
- def fill(self, *args, data=None, **kwargs):
- """
- Plot filled polygons.
-
- Parameters
- ----------
- *args : sequence of x, y, [color]
- Each polygon is defined by the lists of *x* and *y* positions of
- its nodes, optionally followed by a *color* specifier. See
- :mod:`matplotlib.colors` for supported color specifiers. The
- standard color cycle is used for polygons without a color
- specifier.
-
- You can plot multiple polygons by providing multiple *x*, *y*,
- *[color]* groups.
-
- For example, each of the following is legal::
-
- ax.fill(x, y) # a polygon with default color
- ax.fill(x, y, "b") # a blue polygon
- ax.fill(x, y, x2, y2) # two polygons
- ax.fill(x, y, "b", x2, y2, "r") # a blue and a red polygon
-
- data : indexable object, optional
- An object with labelled data. If given, provide the label names to
- plot in *x* and *y*, e.g.::
-
- ax.fill("time", "signal",
- data={"time": [0, 1, 2], "signal": [0, 1, 0]})
-
- Returns
- -------
- list of `~matplotlib.patches.Polygon`
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.patches.Polygon` properties
-
- Notes
- -----
- Use :meth:`fill_between` if you would like to fill the region between
- two curves.
- """
- # For compatibility(!), get aliases from Line2D rather than Patch.
- kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
- # _get_patches_for_fill returns a generator, convert it to a list.
- patches = [*self._get_patches_for_fill(self, *args, data=data, **kwargs)]
- for poly in patches:
- self.add_patch(poly)
- self._request_autoscale_view()
- return patches
-
- def _fill_between_x_or_y(
- self, ind_dir, ind, dep1, dep2=0, *,
- where=None, interpolate=False, step=None, **kwargs):
- # Common implementation between fill_between (*ind_dir*="x") and
- # fill_betweenx (*ind_dir*="y"). *ind* is the independent variable,
- # *dep* the dependent variable. The docstring below is interpolated
- # to generate both methods' docstrings.
- """
- Fill the area between two {dir} curves.
-
- The curves are defined by the points (*{ind}*, *{dep}1*) and (*{ind}*,
- *{dep}2*). This creates one or multiple polygons describing the filled
- area.
-
- You may exclude some {dir} sections from filling using *where*.
-
- By default, the edges connect the given points directly. Use *step*
- if the filling should be a step function, i.e. constant in between
- *{ind}*.
-
- Parameters
- ----------
- {ind} : array (length N)
- The {ind} coordinates of the nodes defining the curves.
-
- {dep}1 : array (length N) or scalar
- The {dep} coordinates of the nodes defining the first curve.
-
- {dep}2 : array (length N) or scalar, default: 0
- The {dep} coordinates of the nodes defining the second curve.
-
- where : array of bool (length N), optional
- Define *where* to exclude some {dir} regions from being filled.
- The filled regions are defined by the coordinates ``{ind}[where]``.
- More precisely, fill between ``{ind}[i]`` and ``{ind}[i+1]`` if
- ``where[i] and where[i+1]``. Note that this definition implies
- that an isolated *True* value between two *False* values in *where*
- will not result in filling. Both sides of the *True* position
- remain unfilled due to the adjacent *False* values.
-
- interpolate : bool, default: False
- This option is only relevant if *where* is used and the two curves
- are crossing each other.
-
- Semantically, *where* is often used for *{dep}1* > *{dep}2* or
- similar. By default, the nodes of the polygon defining the filled
- region will only be placed at the positions in the *{ind}* array.
- Such a polygon cannot describe the above semantics close to the
- intersection. The {ind}-sections containing the intersection are
- simply clipped.
-
- Setting *interpolate* to *True* will calculate the actual
- intersection point and extend the filled region up to this point.
-
- step : {{'pre', 'post', 'mid'}}, optional
- Define *step* if the filling should be a step function,
- i.e. constant in between *{ind}*. The value determines where the
- step will occur:
-
- - 'pre': The y value is continued constantly to the left from
- every *x* position, i.e. the interval ``(x[i-1], x[i]]`` has the
- value ``y[i]``.
- - 'post': The y value is continued constantly to the right from
- every *x* position, i.e. the interval ``[x[i], x[i+1])`` has the
- value ``y[i]``.
- - 'mid': Steps occur half-way between the *x* positions.
-
- Returns
- -------
- `.PolyCollection`
- A `.PolyCollection` containing the plotted polygons.
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- All other keyword arguments are passed on to `.PolyCollection`.
- They control the `.Polygon` properties:
-
- %(PolyCollection:kwdoc)s
-
- See Also
- --------
- fill_between : Fill between two sets of y-values.
- fill_betweenx : Fill between two sets of x-values.
- """
-
- dep_dir = {"x": "y", "y": "x"}[ind_dir]
-
- if not mpl.rcParams["_internal.classic_mode"]:
- kwargs = cbook.normalize_kwargs(kwargs, mcoll.Collection)
- if not any(c in kwargs for c in ("color", "facecolor")):
- kwargs["facecolor"] = \
- self._get_patches_for_fill.get_next_color()
-
- # Handle united data, such as dates
- ind, dep1, dep2 = map(
- ma.masked_invalid, self._process_unit_info(
- [(ind_dir, ind), (dep_dir, dep1), (dep_dir, dep2)], kwargs))
-
- for name, array in [
- (ind_dir, ind), (f"{dep_dir}1", dep1), (f"{dep_dir}2", dep2)]:
- if array.ndim > 1:
- raise ValueError(f"{name!r} is not 1-dimensional")
-
- if where is None:
- where = True
- else:
- where = np.asarray(where, dtype=bool)
- if where.size != ind.size:
- raise ValueError(f"where size ({where.size}) does not match "
- f"{ind_dir} size ({ind.size})")
- where = where & ~functools.reduce(
- np.logical_or, map(np.ma.getmaskarray, [ind, dep1, dep2]))
-
- ind, dep1, dep2 = np.broadcast_arrays(
- np.atleast_1d(ind), dep1, dep2, subok=True)
-
- polys = []
- for idx0, idx1 in cbook.contiguous_regions(where):
- indslice = ind[idx0:idx1]
- dep1slice = dep1[idx0:idx1]
- dep2slice = dep2[idx0:idx1]
- if step is not None:
- step_func = cbook.STEP_LOOKUP_MAP["steps-" + step]
- indslice, dep1slice, dep2slice = \
- step_func(indslice, dep1slice, dep2slice)
-
- if not len(indslice):
- continue
-
- N = len(indslice)
- pts = np.zeros((2 * N + 2, 2))
-
- if interpolate:
- def get_interp_point(idx):
- im1 = max(idx - 1, 0)
- ind_values = ind[im1:idx+1]
- diff_values = dep1[im1:idx+1] - dep2[im1:idx+1]
- dep1_values = dep1[im1:idx+1]
-
- if len(diff_values) == 2:
- if np.ma.is_masked(diff_values[1]):
- return ind[im1], dep1[im1]
- elif np.ma.is_masked(diff_values[0]):
- return ind[idx], dep1[idx]
-
- diff_order = diff_values.argsort()
- diff_root_ind = np.interp(
- 0, diff_values[diff_order], ind_values[diff_order])
- ind_order = ind_values.argsort()
- diff_root_dep = np.interp(
- diff_root_ind,
- ind_values[ind_order], dep1_values[ind_order])
- return diff_root_ind, diff_root_dep
-
- start = get_interp_point(idx0)
- end = get_interp_point(idx1)
- else:
- # Handle scalar dep2 (e.g. 0): the fill should go all
- # the way down to 0 even if none of the dep1 sample points do.
- start = indslice[0], dep2slice[0]
- end = indslice[-1], dep2slice[-1]
-
- pts[0] = start
- pts[N + 1] = end
-
- pts[1:N+1, 0] = indslice
- pts[1:N+1, 1] = dep1slice
- pts[N+2:, 0] = indslice[::-1]
- pts[N+2:, 1] = dep2slice[::-1]
-
- if ind_dir == "y":
- pts = pts[:, ::-1]
-
- polys.append(pts)
-
- collection = mcoll.PolyCollection(polys, **kwargs)
-
- # now update the datalim and autoscale
- pts = np.vstack([np.hstack([ind[where, None], dep1[where, None]]),
- np.hstack([ind[where, None], dep2[where, None]])])
- if ind_dir == "y":
- pts = pts[:, ::-1]
-
- up_x = up_y = True
- if "transform" in kwargs:
- up_x, up_y = kwargs["transform"].contains_branch_seperately(self.transData)
- self.update_datalim(pts, updatex=up_x, updatey=up_y)
-
- self.add_collection(collection, autolim=False)
- self._request_autoscale_view()
- return collection
-
- def fill_between(self, x, y1, y2=0, where=None, interpolate=False,
- step=None, **kwargs):
- return self._fill_between_x_or_y(
- "x", x, y1, y2,
- where=where, interpolate=interpolate, step=step, **kwargs)
-
- if _fill_between_x_or_y.__doc__:
- fill_between.__doc__ = _fill_between_x_or_y.__doc__.format(
- dir="horizontal", ind="x", dep="y"
- )
- fill_between = _preprocess_data(
- _docstring.dedent_interpd(fill_between),
- replace_names=["x", "y1", "y2", "where"])
-
- def fill_betweenx(self, y, x1, x2=0, where=None,
- step=None, interpolate=False, **kwargs):
- return self._fill_between_x_or_y(
- "y", y, x1, x2,
- where=where, interpolate=interpolate, step=step, **kwargs)
-
- if _fill_between_x_or_y.__doc__:
- fill_betweenx.__doc__ = _fill_between_x_or_y.__doc__.format(
- dir="vertical", ind="y", dep="x"
- )
- fill_betweenx = _preprocess_data(
- _docstring.dedent_interpd(fill_betweenx),
- replace_names=["y", "x1", "x2", "where"])
-
- #### plotting z(x, y): imshow, pcolor and relatives, contour
-
- @_preprocess_data()
- @_docstring.interpd
- def imshow(self, X, cmap=None, norm=None, *, aspect=None,
- interpolation=None, alpha=None,
- vmin=None, vmax=None, origin=None, extent=None,
- interpolation_stage=None, filternorm=True, filterrad=4.0,
- resample=None, url=None, **kwargs):
- """
- Display data as an image, i.e., on a 2D regular raster.
-
- The input may either be actual RGB(A) data, or 2D scalar data, which
- will be rendered as a pseudocolor image. For displaying a grayscale
- image, set up the colormapping using the parameters
- ``cmap='gray', vmin=0, vmax=255``.
-
- The number of pixels used to render an image is set by the Axes size
- and the figure *dpi*. This can lead to aliasing artifacts when
- the image is resampled, because the displayed image size will usually
- not match the size of *X* (see
- :doc:`/gallery/images_contours_and_fields/image_antialiasing`).
- The resampling can be controlled via the *interpolation* parameter
- and/or :rc:`image.interpolation`.
-
- Parameters
- ----------
- X : array-like or PIL image
- The image data. Supported array shapes are:
-
- - (M, N): an image with scalar data. The values are mapped to
- colors using normalization and a colormap. See parameters *norm*,
- *cmap*, *vmin*, *vmax*.
- - (M, N, 3): an image with RGB values (0-1 float or 0-255 int).
- - (M, N, 4): an image with RGBA values (0-1 float or 0-255 int),
- i.e. including transparency.
-
- The first two dimensions (M, N) define the rows and columns of
- the image.
-
- Out-of-range RGB(A) values are clipped.
-
- %(cmap_doc)s
-
- This parameter is ignored if *X* is RGB(A).
-
- %(norm_doc)s
-
- This parameter is ignored if *X* is RGB(A).
-
- %(vmin_vmax_doc)s
-
- This parameter is ignored if *X* is RGB(A).
-
- aspect : {'equal', 'auto'} or float or None, default: None
- The aspect ratio of the Axes. This parameter is particularly
- relevant for images since it determines whether data pixels are
- square.
-
- This parameter is a shortcut for explicitly calling
- `.Axes.set_aspect`. See there for further details.
-
- - 'equal': Ensures an aspect ratio of 1. Pixels will be square
- (unless pixel sizes are explicitly made non-square in data
- coordinates using *extent*).
- - 'auto': The Axes is kept fixed and the aspect is adjusted so
- that the data fit in the Axes. In general, this will result in
- non-square pixels.
-
- Normally, None (the default) means to use :rc:`image.aspect`. However, if
- the image uses a transform that does not contain the axes data transform,
- then None means to not modify the axes aspect at all (in that case, directly
- call `.Axes.set_aspect` if desired).
-
- interpolation : str, default: :rc:`image.interpolation`
- The interpolation method used.
-
- Supported values are 'none', 'antialiased', 'nearest', 'bilinear',
- 'bicubic', 'spline16', 'spline36', 'hanning', 'hamming', 'hermite',
- 'kaiser', 'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell',
- 'sinc', 'lanczos', 'blackman'.
-
- The data *X* is resampled to the pixel size of the image on the
- figure canvas, using the interpolation method to either up- or
- downsample the data.
-
- If *interpolation* is 'none', then for the ps, pdf, and svg
- backends no down- or upsampling occurs, and the image data is
- passed to the backend as a native image. Note that different ps,
- pdf, and svg viewers may display these raw pixels differently. On
- other backends, 'none' is the same as 'nearest'.
-
- If *interpolation* is the default 'antialiased', then 'nearest'
- interpolation is used if the image is upsampled by more than a
- factor of three (i.e. the number of display pixels is at least
- three times the size of the data array). If the upsampling rate is
- smaller than 3, or the image is downsampled, then 'hanning'
- interpolation is used to act as an anti-aliasing filter, unless the
- image happens to be upsampled by exactly a factor of two or one.
-
- See
- :doc:`/gallery/images_contours_and_fields/interpolation_methods`
- for an overview of the supported interpolation methods, and
- :doc:`/gallery/images_contours_and_fields/image_antialiasing` for
- a discussion of image antialiasing.
-
- Some interpolation methods require an additional radius parameter,
- which can be set by *filterrad*. Additionally, the antigrain image
- resize filter is controlled by the parameter *filternorm*.
-
- interpolation_stage : {'data', 'rgba'}, default: 'data'
- If 'data', interpolation
- is carried out on the data provided by the user. If 'rgba', the
- interpolation is carried out after the colormapping has been
- applied (visual interpolation).
-
- alpha : float or array-like, optional
- The alpha blending value, between 0 (transparent) and 1 (opaque).
- If *alpha* is an array, the alpha blending values are applied pixel
- by pixel, and *alpha* must have the same shape as *X*.
-
- origin : {'upper', 'lower'}, default: :rc:`image.origin`
- Place the [0, 0] index of the array in the upper left or lower
- left corner of the Axes. The convention (the default) 'upper' is
- typically used for matrices and images.
-
- Note that the vertical axis points upward for 'lower'
- but downward for 'upper'.
-
- See the :ref:`imshow_extent` tutorial for
- examples and a more detailed description.
-
- extent : floats (left, right, bottom, top), optional
- The bounding box in data coordinates that the image will fill.
- These values may be unitful and match the units of the Axes.
- The image is stretched individually along x and y to fill the box.
-
- The default extent is determined by the following conditions.
- Pixels have unit size in data coordinates. Their centers are on
- integer coordinates, and their center coordinates range from 0 to
- columns-1 horizontally and from 0 to rows-1 vertically.
-
- Note that the direction of the vertical axis and thus the default
- values for top and bottom depend on *origin*:
-
- - For ``origin == 'upper'`` the default is
- ``(-0.5, numcols-0.5, numrows-0.5, -0.5)``.
- - For ``origin == 'lower'`` the default is
- ``(-0.5, numcols-0.5, -0.5, numrows-0.5)``.
-
- See the :ref:`imshow_extent` tutorial for
- examples and a more detailed description.
-
- filternorm : bool, default: True
- A parameter for the antigrain image resize filter (see the
- antigrain documentation). If *filternorm* is set, the filter
- normalizes integer values and corrects the rounding errors. It
- doesn't do anything with the source floating point values, 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.
-
- filterrad : float > 0, default: 4.0
- The filter radius for filters that have a radius parameter, i.e.
- when interpolation is one of: 'sinc', 'lanczos' or 'blackman'.
-
- resample : bool, default: :rc:`image.resample`
- When *True*, use a full resampling method. When *False*, only
- resample when the output image is larger than the input image.
-
- url : str, optional
- Set the url of the created `.AxesImage`. See `.Artist.set_url`.
-
- Returns
- -------
- `~matplotlib.image.AxesImage`
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs : `~matplotlib.artist.Artist` properties
- These parameters are passed on to the constructor of the
- `.AxesImage` artist.
-
- See Also
- --------
- matshow : Plot a matrix or an array as an image.
-
- Notes
- -----
- Unless *extent* is used, pixel centers will be located at integer
- coordinates. In other words: the origin will coincide with the center
- of pixel (0, 0).
-
- There are two common representations for RGB images with an alpha
- channel:
-
- - Straight (unassociated) alpha: R, G, and B channels represent the
- color of the pixel, disregarding its opacity.
- - Premultiplied (associated) alpha: R, G, and B channels represent
- the color of the pixel, adjusted for its opacity by multiplication.
-
- `~matplotlib.pyplot.imshow` expects RGB images adopting the straight
- (unassociated) alpha representation.
- """
- im = mimage.AxesImage(self, cmap=cmap, norm=norm,
- interpolation=interpolation, origin=origin,
- extent=extent, filternorm=filternorm,
- filterrad=filterrad, resample=resample,
- interpolation_stage=interpolation_stage,
- **kwargs)
-
- if aspect is None and not (
- im.is_transform_set()
- and not im.get_transform().contains_branch(self.transData)):
- aspect = mpl.rcParams['image.aspect']
- if aspect is not None:
- self.set_aspect(aspect)
-
- im.set_data(X)
- im.set_alpha(alpha)
- if im.get_clip_path() is None:
- # image does not already have clipping set, clip to axes patch
- im.set_clip_path(self.patch)
- im._scale_norm(norm, vmin, vmax)
- im.set_url(url)
-
- # update ax.dataLim, and, if autoscaling, set viewLim
- # to tightly fit the image, regardless of dataLim.
- im.set_extent(im.get_extent())
-
- self.add_image(im)
- return im
-
- def _pcolorargs(self, funcname, *args, shading='auto', **kwargs):
- # - create X and Y if not present;
- # - reshape X and Y as needed if they are 1-D;
- # - check for proper sizes based on `shading` kwarg;
- # - reset shading if shading='auto' to flat or nearest
- # depending on size;
-
- _valid_shading = ['gouraud', 'nearest', 'flat', 'auto']
- try:
- _api.check_in_list(_valid_shading, shading=shading)
- except ValueError:
- _api.warn_external(f"shading value '{shading}' not in list of "
- f"valid values {_valid_shading}. Setting "
- "shading='auto'.")
- shading = 'auto'
-
- if len(args) == 1:
- C = np.asanyarray(args[0])
- nrows, ncols = C.shape[:2]
- if shading in ['gouraud', 'nearest']:
- X, Y = np.meshgrid(np.arange(ncols), np.arange(nrows))
- else:
- X, Y = np.meshgrid(np.arange(ncols + 1), np.arange(nrows + 1))
- shading = 'flat'
- C = cbook.safe_masked_invalid(C, copy=True)
- return X, Y, C, shading
-
- if len(args) == 3:
- # Check x and y for bad data...
- C = np.asanyarray(args[2])
- # unit conversion allows e.g. datetime objects as axis values
- X, Y = args[:2]
- X, Y = self._process_unit_info([("x", X), ("y", Y)], kwargs)
- X, Y = [cbook.safe_masked_invalid(a, copy=True) for a in [X, Y]]
-
- if funcname == 'pcolormesh':
- if np.ma.is_masked(X) or np.ma.is_masked(Y):
- raise ValueError(
- 'x and y arguments to pcolormesh cannot have '
- 'non-finite values or be of type '
- 'numpy.ma.MaskedArray with masked values')
- nrows, ncols = C.shape[:2]
- else:
- raise _api.nargs_error(funcname, takes="1 or 3", given=len(args))
-
- Nx = X.shape[-1]
- Ny = Y.shape[0]
- if X.ndim != 2 or X.shape[0] == 1:
- x = X.reshape(1, Nx)
- X = x.repeat(Ny, axis=0)
- if Y.ndim != 2 or Y.shape[1] == 1:
- y = Y.reshape(Ny, 1)
- Y = y.repeat(Nx, axis=1)
- if X.shape != Y.shape:
- raise TypeError(f'Incompatible X, Y inputs to {funcname}; '
- f'see help({funcname})')
-
- if shading == 'auto':
- if ncols == Nx and nrows == Ny:
- shading = 'nearest'
- else:
- shading = 'flat'
-
- if shading == 'flat':
- if (Nx, Ny) != (ncols + 1, nrows + 1):
- raise TypeError(f"Dimensions of C {C.shape} should"
- f" be one smaller than X({Nx}) and Y({Ny})"
- f" while using shading='flat'"
- f" see help({funcname})")
- else: # ['nearest', 'gouraud']:
- if (Nx, Ny) != (ncols, nrows):
- raise TypeError('Dimensions of C %s are incompatible with'
- ' X (%d) and/or Y (%d); see help(%s)' % (
- C.shape, Nx, Ny, funcname))
- if shading == 'nearest':
- # grid is specified at the center, so define corners
- # at the midpoints between the grid centers and then use the
- # flat algorithm.
- def _interp_grid(X):
- # helper for below
- if np.shape(X)[1] > 1:
- dX = np.diff(X, axis=1)/2.
- if not (np.all(dX >= 0) or np.all(dX <= 0)):
- _api.warn_external(
- f"The input coordinates to {funcname} are "
- "interpreted as cell centers, but are not "
- "monotonically increasing or decreasing. "
- "This may lead to incorrectly calculated cell "
- "edges, in which case, please supply "
- f"explicit cell edges to {funcname}.")
-
- hstack = np.ma.hstack if np.ma.isMA(X) else np.hstack
- X = hstack((X[:, [0]] - dX[:, [0]],
- X[:, :-1] + dX,
- X[:, [-1]] + dX[:, [-1]]))
- else:
- # This is just degenerate, but we can't reliably guess
- # a dX if there is just one value.
- X = np.hstack((X, X))
- return X
-
- if ncols == Nx:
- X = _interp_grid(X)
- Y = _interp_grid(Y)
- if nrows == Ny:
- X = _interp_grid(X.T).T
- Y = _interp_grid(Y.T).T
- shading = 'flat'
-
- C = cbook.safe_masked_invalid(C, copy=True)
- return X, Y, C, shading
-
- @_preprocess_data()
- @_docstring.dedent_interpd
- def pcolor(self, *args, shading=None, alpha=None, norm=None, cmap=None,
- vmin=None, vmax=None, **kwargs):
- r"""
- Create a pseudocolor plot with a non-regular rectangular grid.
-
- Call signature::
-
- pcolor([X, Y,] C, **kwargs)
-
- *X* and *Y* can be used to specify the corners of the quadrilaterals.
-
- .. hint::
-
- ``pcolor()`` can be very slow for large arrays. In most
- cases you should use the similar but much faster
- `~.Axes.pcolormesh` instead. See
- :ref:`Differences between pcolor() and pcolormesh()
- <differences-pcolor-pcolormesh>` for a discussion of the
- differences.
-
- Parameters
- ----------
- C : 2D array-like
- The color-mapped values. Color-mapping is controlled by *cmap*,
- *norm*, *vmin*, and *vmax*.
-
- X, Y : array-like, optional
- The coordinates of the corners of quadrilaterals of a pcolormesh::
-
- (X[i+1, j], Y[i+1, j]) (X[i+1, j+1], Y[i+1, j+1])
- ●╶───╴●
- │ │
- ●╶───╴●
- (X[i, j], Y[i, j]) (X[i, j+1], Y[i, j+1])
-
- Note that the column index corresponds to the x-coordinate, and
- the row index corresponds to y. For details, see the
- :ref:`Notes <axes-pcolormesh-grid-orientation>` section below.
-
- If ``shading='flat'`` the dimensions of *X* and *Y* should be one
- greater than those of *C*, and the quadrilateral is colored due
- to the value at ``C[i, j]``. If *X*, *Y* and *C* have equal
- dimensions, a warning will be raised and the last row and column
- of *C* will be ignored.
-
- If ``shading='nearest'``, the dimensions of *X* and *Y* should be
- the same as those of *C* (if not, a ValueError will be raised). The
- color ``C[i, j]`` will be centered on ``(X[i, j], Y[i, j])``.
-
- If *X* and/or *Y* are 1-D arrays or column vectors they will be
- expanded as needed into the appropriate 2D arrays, making a
- rectangular grid.
-
- shading : {'flat', 'nearest', 'auto'}, default: :rc:`pcolor.shading`
- The fill style for the quadrilateral. Possible values:
-
- - 'flat': A solid color is used for each quad. The color of the
- quad (i, j), (i+1, j), (i, j+1), (i+1, j+1) is given by
- ``C[i, j]``. The dimensions of *X* and *Y* should be
- one greater than those of *C*; if they are the same as *C*,
- then a deprecation warning is raised, and the last row
- and column of *C* are dropped.
- - 'nearest': Each grid point will have a color centered on it,
- extending halfway between the adjacent grid centers. The
- dimensions of *X* and *Y* must be the same as *C*.
- - 'auto': Choose 'flat' if dimensions of *X* and *Y* are one
- larger than *C*. Choose 'nearest' if dimensions are the same.
-
- See :doc:`/gallery/images_contours_and_fields/pcolormesh_grids`
- for more description.
-
- %(cmap_doc)s
-
- %(norm_doc)s
-
- %(vmin_vmax_doc)s
-
- edgecolors : {'none', None, 'face', color, color sequence}, optional
- The color of the edges. Defaults to 'none'. Possible values:
-
- - 'none' or '': No edge.
- - *None*: :rc:`patch.edgecolor` will be used. Note that currently
- :rc:`patch.force_edgecolor` has to be True for this to work.
- - 'face': Use the adjacent face color.
- - A color or sequence of colors will set the edge color.
-
- The singular form *edgecolor* works as an alias.
-
- alpha : float, default: None
- The alpha blending value of the face color, between 0 (transparent)
- and 1 (opaque). Note: The edgecolor is currently not affected by
- this.
-
- snap : bool, default: False
- Whether to snap the mesh to pixel boundaries.
-
- Returns
- -------
- `matplotlib.collections.PolyQuadMesh`
-
- Other Parameters
- ----------------
- antialiaseds : bool, default: False
- The default *antialiaseds* is False if the default
- *edgecolors*\ ="none" is used. This eliminates artificial lines
- at patch boundaries, and works regardless of the value of alpha.
- If *edgecolors* is not "none", then the default *antialiaseds*
- is taken from :rc:`patch.antialiased`.
- Stroking the edges may be preferred if *alpha* is 1, but will
- cause artifacts otherwise.
-
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Additionally, the following arguments are allowed. They are passed
- along to the `~matplotlib.collections.PolyQuadMesh` constructor:
-
- %(PolyCollection:kwdoc)s
-
- See Also
- --------
- pcolormesh : for an explanation of the differences between
- pcolor and pcolormesh.
- imshow : If *X* and *Y* are each equidistant, `~.Axes.imshow` can be a
- faster alternative.
-
- Notes
- -----
- **Masked arrays**
-
- *X*, *Y* and *C* may be masked arrays. If either ``C[i, j]``, or one
- of the vertices surrounding ``C[i, j]`` (*X* or *Y* at
- ``[i, j], [i+1, j], [i, j+1], [i+1, j+1]``) is masked, nothing is
- plotted.
-
- .. _axes-pcolor-grid-orientation:
-
- **Grid orientation**
-
- The grid orientation follows the standard matrix convention: An array
- *C* with shape (nrows, ncolumns) is plotted with the column number as
- *X* and the row number as *Y*.
- """
-
- if shading is None:
- shading = mpl.rcParams['pcolor.shading']
- shading = shading.lower()
- X, Y, C, shading = self._pcolorargs('pcolor', *args, shading=shading,
- kwargs=kwargs)
- linewidths = (0.25,)
- if 'linewidth' in kwargs:
- kwargs['linewidths'] = kwargs.pop('linewidth')
- kwargs.setdefault('linewidths', linewidths)
-
- if 'edgecolor' in kwargs:
- kwargs['edgecolors'] = kwargs.pop('edgecolor')
- ec = kwargs.setdefault('edgecolors', 'none')
-
- # aa setting will default via collections to patch.antialiased
- # unless the boundary is not stroked, in which case the
- # default will be False; with unstroked boundaries, aa
- # makes artifacts that are often disturbing.
- if 'antialiaseds' in kwargs:
- kwargs['antialiased'] = kwargs.pop('antialiaseds')
- if 'antialiased' not in kwargs and cbook._str_lower_equal(ec, "none"):
- kwargs['antialiased'] = False
-
- kwargs.setdefault('snap', False)
-
- if np.ma.isMaskedArray(X) or np.ma.isMaskedArray(Y):
- stack = np.ma.stack
- X = np.ma.asarray(X)
- Y = np.ma.asarray(Y)
- # For bounds collections later
- x = X.compressed()
- y = Y.compressed()
- else:
- stack = np.stack
- x = X
- y = Y
- coords = stack([X, Y], axis=-1)
-
- collection = mcoll.PolyQuadMesh(
- coords, array=C, cmap=cmap, norm=norm, alpha=alpha, **kwargs)
- collection._scale_norm(norm, vmin, vmax)
-
- # Transform from native to data coordinates?
- t = collection._transform
- if (not isinstance(t, mtransforms.Transform) and
- hasattr(t, '_as_mpl_transform')):
- t = t._as_mpl_transform(self.axes)
-
- if t and any(t.contains_branch_seperately(self.transData)):
- trans_to_data = t - self.transData
- pts = np.vstack([x, y]).T.astype(float)
- transformed_pts = trans_to_data.transform(pts)
- x = transformed_pts[..., 0]
- y = transformed_pts[..., 1]
-
- self.add_collection(collection, autolim=False)
-
- minx = np.min(x)
- maxx = np.max(x)
- miny = np.min(y)
- maxy = np.max(y)
- collection.sticky_edges.x[:] = [minx, maxx]
- collection.sticky_edges.y[:] = [miny, maxy]
- corners = (minx, miny), (maxx, maxy)
- self.update_datalim(corners)
- self._request_autoscale_view()
- return collection
-
- @_preprocess_data()
- @_docstring.dedent_interpd
- def pcolormesh(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
- vmax=None, shading=None, antialiased=False, **kwargs):
- """
- Create a pseudocolor plot with a non-regular rectangular grid.
-
- Call signature::
-
- pcolormesh([X, Y,] C, **kwargs)
-
- *X* and *Y* can be used to specify the corners of the quadrilaterals.
-
- .. hint::
-
- `~.Axes.pcolormesh` is similar to `~.Axes.pcolor`. It is much faster
- and preferred in most cases. For a detailed discussion on the
- differences see :ref:`Differences between pcolor() and pcolormesh()
- <differences-pcolor-pcolormesh>`.
-
- Parameters
- ----------
- C : array-like
- The mesh data. Supported array shapes are:
-
- - (M, N) or M*N: a mesh with scalar data. The values are mapped to
- colors using normalization and a colormap. See parameters *norm*,
- *cmap*, *vmin*, *vmax*.
- - (M, N, 3): an image with RGB values (0-1 float or 0-255 int).
- - (M, N, 4): an image with RGBA values (0-1 float or 0-255 int),
- i.e. including transparency.
-
- The first two dimensions (M, N) define the rows and columns of
- the mesh data.
-
- X, Y : array-like, optional
- The coordinates of the corners of quadrilaterals of a pcolormesh::
-
- (X[i+1, j], Y[i+1, j]) (X[i+1, j+1], Y[i+1, j+1])
- ●╶───╴●
- │ │
- ●╶───╴●
- (X[i, j], Y[i, j]) (X[i, j+1], Y[i, j+1])
-
- Note that the column index corresponds to the x-coordinate, and
- the row index corresponds to y. For details, see the
- :ref:`Notes <axes-pcolormesh-grid-orientation>` section below.
-
- If ``shading='flat'`` the dimensions of *X* and *Y* should be one
- greater than those of *C*, and the quadrilateral is colored due
- to the value at ``C[i, j]``. If *X*, *Y* and *C* have equal
- dimensions, a warning will be raised and the last row and column
- of *C* will be ignored.
-
- If ``shading='nearest'`` or ``'gouraud'``, the dimensions of *X*
- and *Y* should be the same as those of *C* (if not, a ValueError
- will be raised). For ``'nearest'`` the color ``C[i, j]`` is
- centered on ``(X[i, j], Y[i, j])``. For ``'gouraud'``, a smooth
- interpolation is caried out between the quadrilateral corners.
-
- If *X* and/or *Y* are 1-D arrays or column vectors they will be
- expanded as needed into the appropriate 2D arrays, making a
- rectangular grid.
-
- %(cmap_doc)s
-
- %(norm_doc)s
-
- %(vmin_vmax_doc)s
-
- edgecolors : {'none', None, 'face', color, color sequence}, optional
- The color of the edges. Defaults to 'none'. Possible values:
-
- - 'none' or '': No edge.
- - *None*: :rc:`patch.edgecolor` will be used. Note that currently
- :rc:`patch.force_edgecolor` has to be True for this to work.
- - 'face': Use the adjacent face color.
- - A color or sequence of colors will set the edge color.
-
- The singular form *edgecolor* works as an alias.
-
- alpha : float, default: None
- The alpha blending value, between 0 (transparent) and 1 (opaque).
-
- shading : {'flat', 'nearest', 'gouraud', 'auto'}, optional
- The fill style for the quadrilateral; defaults to
- :rc:`pcolor.shading`. Possible values:
-
- - 'flat': A solid color is used for each quad. The color of the
- quad (i, j), (i+1, j), (i, j+1), (i+1, j+1) is given by
- ``C[i, j]``. The dimensions of *X* and *Y* should be
- one greater than those of *C*; if they are the same as *C*,
- then a deprecation warning is raised, and the last row
- and column of *C* are dropped.
- - 'nearest': Each grid point will have a color centered on it,
- extending halfway between the adjacent grid centers. The
- dimensions of *X* and *Y* must be the same as *C*.
- - 'gouraud': Each quad will be Gouraud shaded: The color of the
- corners (i', j') are given by ``C[i', j']``. The color values of
- the area in between is interpolated from the corner values.
- The dimensions of *X* and *Y* must be the same as *C*. When
- Gouraud shading is used, *edgecolors* is ignored.
- - 'auto': Choose 'flat' if dimensions of *X* and *Y* are one
- larger than *C*. Choose 'nearest' if dimensions are the same.
-
- See :doc:`/gallery/images_contours_and_fields/pcolormesh_grids`
- for more description.
-
- snap : bool, default: False
- Whether to snap the mesh to pixel boundaries.
-
- rasterized : bool, optional
- Rasterize the pcolormesh when drawing vector graphics. This can
- speed up rendering and produce smaller files for large data sets.
- See also :doc:`/gallery/misc/rasterization_demo`.
-
- Returns
- -------
- `matplotlib.collections.QuadMesh`
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Additionally, the following arguments are allowed. They are passed
- along to the `~matplotlib.collections.QuadMesh` constructor:
-
- %(QuadMesh:kwdoc)s
-
- See Also
- --------
- pcolor : An alternative implementation with slightly different
- features. For a detailed discussion on the differences see
- :ref:`Differences between pcolor() and pcolormesh()
- <differences-pcolor-pcolormesh>`.
- imshow : If *X* and *Y* are each equidistant, `~.Axes.imshow` can be a
- faster alternative.
-
- Notes
- -----
- **Masked arrays**
-
- *C* may be a masked array. If ``C[i, j]`` is masked, the corresponding
- quadrilateral will be transparent. Masking of *X* and *Y* is not
- supported. Use `~.Axes.pcolor` if you need this functionality.
-
- .. _axes-pcolormesh-grid-orientation:
-
- **Grid orientation**
-
- The grid orientation follows the standard matrix convention: An array
- *C* with shape (nrows, ncolumns) is plotted with the column number as
- *X* and the row number as *Y*.
-
- .. _differences-pcolor-pcolormesh:
-
- **Differences between pcolor() and pcolormesh()**
-
- Both methods are used to create a pseudocolor plot of a 2D array
- using quadrilaterals.
-
- The main difference lies in the created object and internal data
- handling:
- While `~.Axes.pcolor` returns a `.PolyQuadMesh`, `~.Axes.pcolormesh`
- returns a `.QuadMesh`. The latter is more specialized for the given
- purpose and thus is faster. It should almost always be preferred.
-
- There is also a slight difference in the handling of masked arrays.
- Both `~.Axes.pcolor` and `~.Axes.pcolormesh` support masked arrays
- for *C*. However, only `~.Axes.pcolor` supports masked arrays for *X*
- and *Y*. The reason lies in the internal handling of the masked values.
- `~.Axes.pcolor` leaves out the respective polygons from the
- PolyQuadMesh. `~.Axes.pcolormesh` sets the facecolor of the masked
- elements to transparent. You can see the difference when using
- edgecolors. While all edges are drawn irrespective of masking in a
- QuadMesh, the edge between two adjacent masked quadrilaterals in
- `~.Axes.pcolor` is not drawn as the corresponding polygons do not
- exist in the PolyQuadMesh. Because PolyQuadMesh draws each individual
- polygon, it also supports applying hatches and linestyles to the collection.
-
- Another difference is the support of Gouraud shading in
- `~.Axes.pcolormesh`, which is not available with `~.Axes.pcolor`.
-
- """
- if shading is None:
- shading = mpl.rcParams['pcolor.shading']
- shading = shading.lower()
- kwargs.setdefault('edgecolors', 'none')
-
- X, Y, C, shading = self._pcolorargs('pcolormesh', *args,
- shading=shading, kwargs=kwargs)
- coords = np.stack([X, Y], axis=-1)
-
- kwargs.setdefault('snap', mpl.rcParams['pcolormesh.snap'])
-
- collection = mcoll.QuadMesh(
- coords, antialiased=antialiased, shading=shading,
- array=C, cmap=cmap, norm=norm, alpha=alpha, **kwargs)
- collection._scale_norm(norm, vmin, vmax)
-
- coords = coords.reshape(-1, 2) # flatten the grid structure; keep x, y
-
- # Transform from native to data coordinates?
- t = collection._transform
- if (not isinstance(t, mtransforms.Transform) and
- hasattr(t, '_as_mpl_transform')):
- t = t._as_mpl_transform(self.axes)
-
- if t and any(t.contains_branch_seperately(self.transData)):
- trans_to_data = t - self.transData
- coords = trans_to_data.transform(coords)
-
- self.add_collection(collection, autolim=False)
-
- minx, miny = np.min(coords, axis=0)
- maxx, maxy = np.max(coords, axis=0)
- collection.sticky_edges.x[:] = [minx, maxx]
- collection.sticky_edges.y[:] = [miny, maxy]
- corners = (minx, miny), (maxx, maxy)
- self.update_datalim(corners)
- self._request_autoscale_view()
- return collection
-
- @_preprocess_data()
- @_docstring.dedent_interpd
- def pcolorfast(self, *args, alpha=None, norm=None, cmap=None, vmin=None,
- vmax=None, **kwargs):
- """
- Create a pseudocolor plot with a non-regular rectangular grid.
-
- Call signature::
-
- ax.pcolorfast([X, Y], C, /, **kwargs)
-
- This method is similar to `~.Axes.pcolor` and `~.Axes.pcolormesh`.
- It's designed to provide the fastest pcolor-type plotting with the
- Agg backend. To achieve this, it uses different algorithms internally
- depending on the complexity of the input grid (regular rectangular,
- non-regular rectangular or arbitrary quadrilateral).
-
- .. warning::
-
- This method is experimental. Compared to `~.Axes.pcolor` or
- `~.Axes.pcolormesh` it has some limitations:
-
- - It supports only flat shading (no outlines)
- - It lacks support for log scaling of the axes.
- - It does not have a pyplot wrapper.
-
- Parameters
- ----------
- C : array-like
- The image data. Supported array shapes are:
-
- - (M, N): an image with scalar data. Color-mapping is controlled
- by *cmap*, *norm*, *vmin*, and *vmax*.
- - (M, N, 3): an image with RGB values (0-1 float or 0-255 int).
- - (M, N, 4): an image with RGBA values (0-1 float or 0-255 int),
- i.e. including transparency.
-
- The first two dimensions (M, N) define the rows and columns of
- the image.
-
- This parameter can only be passed positionally.
-
- X, Y : tuple or array-like, default: ``(0, N)``, ``(0, M)``
- *X* and *Y* are used to specify the coordinates of the
- quadrilaterals. There are different ways to do this:
-
- - Use tuples ``X=(xmin, xmax)`` and ``Y=(ymin, ymax)`` to define
- a *uniform rectangular grid*.
-
- The tuples define the outer edges of the grid. All individual
- quadrilaterals will be of the same size. This is the fastest
- version.
-
- - Use 1D arrays *X*, *Y* to specify a *non-uniform rectangular
- grid*.
-
- In this case *X* and *Y* have to be monotonic 1D arrays of length
- *N+1* and *M+1*, specifying the x and y boundaries of the cells.
-
- The speed is intermediate. Note: The grid is checked, and if
- found to be uniform the fast version is used.
-
- - Use 2D arrays *X*, *Y* if you need an *arbitrary quadrilateral
- grid* (i.e. if the quadrilaterals are not rectangular).
-
- In this case *X* and *Y* are 2D arrays with shape (M + 1, N + 1),
- specifying the x and y coordinates of the corners of the colored
- quadrilaterals.
-
- This is the most general, but the slowest to render. It may
- produce faster and more compact output using ps, pdf, and
- svg backends, however.
-
- These arguments can only be passed positionally.
-
- %(cmap_doc)s
-
- This parameter is ignored if *C* is RGB(A).
-
- %(norm_doc)s
-
- This parameter is ignored if *C* is RGB(A).
-
- %(vmin_vmax_doc)s
-
- This parameter is ignored if *C* is RGB(A).
-
- alpha : float, default: None
- The alpha blending value, between 0 (transparent) and 1 (opaque).
-
- snap : bool, default: False
- Whether to snap the mesh to pixel boundaries.
-
- Returns
- -------
- `.AxesImage` or `.PcolorImage` or `.QuadMesh`
- The return type depends on the type of grid:
-
- - `.AxesImage` for a regular rectangular grid.
- - `.PcolorImage` for a non-regular rectangular grid.
- - `.QuadMesh` for a non-rectangular grid.
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Supported additional parameters depend on the type of grid.
- See return types of *image* for further description.
- """
-
- C = args[-1]
- nr, nc = np.shape(C)[:2]
- if len(args) == 1:
- style = "image"
- x = [0, nc]
- y = [0, nr]
- elif len(args) == 3:
- x, y = args[:2]
- x = np.asarray(x)
- y = np.asarray(y)
- if x.ndim == 1 and y.ndim == 1:
- if x.size == 2 and y.size == 2:
- style = "image"
- else:
- dx = np.diff(x)
- dy = np.diff(y)
- if (np.ptp(dx) < 0.01 * abs(dx.mean()) and
- np.ptp(dy) < 0.01 * abs(dy.mean())):
- style = "image"
- else:
- style = "pcolorimage"
- elif x.ndim == 2 and y.ndim == 2:
- style = "quadmesh"
- else:
- raise TypeError("arguments do not match valid signatures")
- else:
- raise _api.nargs_error('pcolorfast', '1 or 3', len(args))
-
- if style == "quadmesh":
- # data point in each cell is value at lower left corner
- coords = np.stack([x, y], axis=-1)
- if np.ndim(C) not in {2, 3}:
- raise ValueError("C must be 2D or 3D")
- collection = mcoll.QuadMesh(
- coords, array=C,
- alpha=alpha, cmap=cmap, norm=norm,
- antialiased=False, edgecolors="none")
- self.add_collection(collection, autolim=False)
- xl, xr, yb, yt = x.min(), x.max(), y.min(), y.max()
- ret = collection
-
- else: # It's one of the two image styles.
- extent = xl, xr, yb, yt = x[0], x[-1], y[0], y[-1]
- if style == "image":
- im = mimage.AxesImage(
- self, cmap=cmap, norm=norm,
- data=C, alpha=alpha, extent=extent,
- interpolation='nearest', origin='lower',
- **kwargs)
- elif style == "pcolorimage":
- im = mimage.PcolorImage(
- self, x, y, C,
- cmap=cmap, norm=norm, alpha=alpha, extent=extent,
- **kwargs)
- self.add_image(im)
- ret = im
-
- if np.ndim(C) == 2: # C.ndim == 3 is RGB(A) so doesn't need scaling.
- ret._scale_norm(norm, vmin, vmax)
-
- if ret.get_clip_path() is None:
- # image does not already have clipping set, clip to axes patch
- ret.set_clip_path(self.patch)
-
- ret.sticky_edges.x[:] = [xl, xr]
- ret.sticky_edges.y[:] = [yb, yt]
- self.update_datalim(np.array([[xl, yb], [xr, yt]]))
- self._request_autoscale_view(tight=True)
- return ret
-
- @_preprocess_data()
- @_docstring.dedent_interpd
- def contour(self, *args, **kwargs):
- """
- Plot contour lines.
-
- Call signature::
-
- contour([X, Y,] Z, [levels], **kwargs)
- %(contour_doc)s
- """
- kwargs['filled'] = False
- contours = mcontour.QuadContourSet(self, *args, **kwargs)
- self._request_autoscale_view()
- return contours
-
- @_preprocess_data()
- @_docstring.dedent_interpd
- def contourf(self, *args, **kwargs):
- """
- Plot filled contours.
-
- Call signature::
-
- contourf([X, Y,] Z, [levels], **kwargs)
- %(contour_doc)s
- """
- kwargs['filled'] = True
- contours = mcontour.QuadContourSet(self, *args, **kwargs)
- self._request_autoscale_view()
- return contours
-
- def clabel(self, CS, levels=None, **kwargs):
- """
- Label a contour plot.
-
- Adds labels to line contours in given `.ContourSet`.
-
- Parameters
- ----------
- CS : `.ContourSet` instance
- Line contours to label.
-
- levels : array-like, optional
- A list of level values, that should be labeled. The list must be
- a subset of ``CS.levels``. If not given, all levels are labeled.
-
- **kwargs
- All other parameters are documented in `~.ContourLabeler.clabel`.
- """
- return CS.clabel(levels, **kwargs)
-
- #### Data analysis
-
- @_preprocess_data(replace_names=["x", 'weights'], label_namer="x")
- def hist(self, x, bins=None, range=None, density=False, weights=None,
- cumulative=False, bottom=None, histtype='bar', align='mid',
- orientation='vertical', rwidth=None, log=False,
- color=None, label=None, stacked=False, **kwargs):
- """
- Compute and plot a histogram.
-
- This method uses `numpy.histogram` to bin the data in *x* and count the
- number of values in each bin, then draws the distribution either as a
- `.BarContainer` or `.Polygon`. The *bins*, *range*, *density*, and
- *weights* parameters are forwarded to `numpy.histogram`.
-
- If the data has already been binned and counted, use `~.bar` or
- `~.stairs` to plot the distribution::
-
- counts, bins = np.histogram(x)
- plt.stairs(counts, bins)
-
- Alternatively, plot pre-computed bins and counts using ``hist()`` by
- treating each bin as a single point with a weight equal to its count::
-
- plt.hist(bins[:-1], bins, weights=counts)
-
- The data input *x* can be a singular array, a list of datasets of
- potentially different lengths ([*x0*, *x1*, ...]), or a 2D ndarray in
- which each column is a dataset. Note that the ndarray form is
- transposed relative to the list form. If the input is an array, then
- the return value is a tuple (*n*, *bins*, *patches*); if the input is a
- sequence of arrays, then the return value is a tuple
- ([*n0*, *n1*, ...], *bins*, [*patches0*, *patches1*, ...]).
-
- Masked arrays are not supported.
-
- Parameters
- ----------
- x : (n,) array or sequence of (n,) arrays
- Input values, this takes either a single array or a sequence of
- arrays which are not required to be of the same length.
-
- bins : int or sequence or str, default: :rc:`hist.bins`
- If *bins* is an integer, it defines the number of equal-width bins
- in the range.
-
- If *bins* is a sequence, it defines the bin edges, including the
- left edge of the first bin and the right edge of the last bin;
- in this case, bins may be unequally spaced. All but the last
- (righthand-most) bin is half-open. In other words, if *bins* is::
-
- [1, 2, 3, 4]
-
- then the first bin is ``[1, 2)`` (including 1, but excluding 2) and
- the second ``[2, 3)``. The last bin, however, is ``[3, 4]``, which
- *includes* 4.
-
- If *bins* is a string, it is one of the binning strategies
- supported by `numpy.histogram_bin_edges`: 'auto', 'fd', 'doane',
- 'scott', 'stone', 'rice', 'sturges', or 'sqrt'.
-
- range : tuple or None, default: None
- The lower and upper range of the bins. Lower and upper outliers
- are ignored. If not provided, *range* is ``(x.min(), x.max())``.
- Range has no effect if *bins* is a sequence.
-
- If *bins* is a sequence or *range* is specified, autoscaling
- is based on the specified bin range instead of the
- range of x.
-
- density : bool, default: False
- If ``True``, draw and return a probability density: each bin
- will display the bin's raw count divided by the total number of
- counts *and the bin width*
- (``density = counts / (sum(counts) * np.diff(bins))``),
- so that the area under the histogram integrates to 1
- (``np.sum(density * np.diff(bins)) == 1``).
-
- If *stacked* is also ``True``, the sum of the histograms is
- normalized to 1.
-
- weights : (n,) array-like or None, default: None
- An array of weights, of the same shape as *x*. Each value in
- *x* only contributes its associated weight towards the bin count
- (instead of 1). If *density* is ``True``, the weights are
- normalized, so that the integral of the density over the range
- remains 1.
-
- cumulative : bool or -1, default: False
- If ``True``, then a histogram is computed where each bin gives the
- counts in that bin plus all bins for smaller values. The last bin
- gives the total number of datapoints.
-
- If *density* is also ``True`` then the histogram is normalized such
- that the last bin equals 1.
-
- If *cumulative* is a number less than 0 (e.g., -1), the direction
- of accumulation is reversed. In this case, if *density* is also
- ``True``, then the histogram is normalized such that the first bin
- equals 1.
-
- bottom : array-like, scalar, or None, default: None
- Location of the bottom of each bin, i.e. bins are drawn from
- ``bottom`` to ``bottom + hist(x, bins)`` If a scalar, the bottom
- of each bin is shifted by the same amount. If an array, each bin
- is shifted independently and the length of bottom must match the
- number of bins. If None, defaults to 0.
-
- histtype : {'bar', 'barstacked', 'step', 'stepfilled'}, default: 'bar'
- The type of histogram to draw.
-
- - 'bar' is a traditional bar-type histogram. If multiple data
- are given the bars are arranged side by side.
- - 'barstacked' is a bar-type histogram where multiple
- data are stacked on top of each other.
- - 'step' generates a lineplot that is by default unfilled.
- - 'stepfilled' generates a lineplot that is by default filled.
-
- align : {'left', 'mid', 'right'}, default: 'mid'
- The horizontal alignment of the histogram bars.
-
- - 'left': bars are centered on the left bin edges.
- - 'mid': bars are centered between the bin edges.
- - 'right': bars are centered on the right bin edges.
-
- orientation : {'vertical', 'horizontal'}, default: 'vertical'
- If 'horizontal', `~.Axes.barh` will be used for bar-type histograms
- and the *bottom* kwarg will be the left edges.
-
- rwidth : float or None, default: None
- The relative width of the bars as a fraction of the bin width. If
- ``None``, automatically compute the width.
-
- Ignored if *histtype* is 'step' or 'stepfilled'.
-
- log : bool, default: False
- If ``True``, the histogram axis will be set to a log scale.
-
- color : color or array-like of colors or None, default: None
- Color or sequence of colors, one per dataset. Default (``None``)
- uses the standard line color sequence.
-
- label : str or None, default: None
- String, or sequence of strings to match multiple datasets. Bar
- charts yield multiple patches per dataset, but only the first gets
- the label, so that `~.Axes.legend` will work as expected.
-
- stacked : bool, default: False
- If ``True``, multiple data are stacked on top of each other If
- ``False`` multiple data are arranged side by side if histtype is
- 'bar' or on top of each other if histtype is 'step'
-
- Returns
- -------
- n : array or list of arrays
- The values of the histogram bins. See *density* and *weights* for a
- description of the possible semantics. If input *x* is an array,
- then this is an array of length *nbins*. If input is a sequence of
- arrays ``[data1, data2, ...]``, then this is a list of arrays with
- the values of the histograms for each of the arrays in the same
- order. The dtype of the array *n* (or of its element arrays) will
- always be float even if no weighting or normalization is used.
-
- bins : array
- The edges of the bins. Length nbins + 1 (nbins left edges and right
- edge of last bin). Always a single array even when multiple data
- sets are passed in.
-
- patches : `.BarContainer` or list of a single `.Polygon` or list of \
-such objects
- Container of individual artists used to create the histogram
- or list of such containers if there are multiple input datasets.
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- `~matplotlib.patches.Patch` properties
-
- See Also
- --------
- hist2d : 2D histogram with rectangular bins
- hexbin : 2D histogram with hexagonal bins
- stairs : Plot a pre-computed histogram
- bar : Plot a pre-computed histogram
-
- Notes
- -----
- For large numbers of bins (>1000), plotting can be significantly
- accelerated by using `~.Axes.stairs` to plot a pre-computed histogram
- (``plt.stairs(*np.histogram(data))``), or by setting *histtype* to
- 'step' or 'stepfilled' rather than 'bar' or 'barstacked'.
- """
- # Avoid shadowing the builtin.
- bin_range = range
- from builtins import range
-
- if np.isscalar(x):
- x = [x]
-
- if bins is None:
- bins = mpl.rcParams['hist.bins']
-
- # Validate string inputs here to avoid cluttering subsequent code.
- _api.check_in_list(['bar', 'barstacked', 'step', 'stepfilled'],
- histtype=histtype)
- _api.check_in_list(['left', 'mid', 'right'], align=align)
- _api.check_in_list(['horizontal', 'vertical'], orientation=orientation)
-
- if histtype == 'barstacked' and not stacked:
- stacked = True
-
- # Massage 'x' for processing.
- x = cbook._reshape_2D(x, 'x')
- nx = len(x) # number of datasets
-
- # Process unit information. _process_unit_info sets the unit and
- # converts the first dataset; then we convert each following dataset
- # one at a time.
- if orientation == "vertical":
- convert_units = self.convert_xunits
- x = [*self._process_unit_info([("x", x[0])], kwargs),
- *map(convert_units, x[1:])]
- else: # horizontal
- convert_units = self.convert_yunits
- x = [*self._process_unit_info([("y", x[0])], kwargs),
- *map(convert_units, x[1:])]
-
- if bin_range is not None:
- bin_range = convert_units(bin_range)
-
- if not cbook.is_scalar_or_string(bins):
- bins = convert_units(bins)
-
- # We need to do to 'weights' what was done to 'x'
- if weights is not None:
- w = cbook._reshape_2D(weights, 'weights')
- else:
- w = [None] * nx
-
- if len(w) != nx:
- raise ValueError('weights should have the same shape as x')
-
- input_empty = True
- for xi, wi in zip(x, w):
- len_xi = len(xi)
- if wi is not None and len(wi) != len_xi:
- raise ValueError('weights should have the same shape as x')
- if len_xi:
- input_empty = False
-
- if color is None:
- colors = [self._get_lines.get_next_color() for i in range(nx)]
- else:
- colors = mcolors.to_rgba_array(color)
- if len(colors) != nx:
- raise ValueError(f"The 'color' keyword argument must have one "
- f"color per dataset, but {nx} datasets and "
- f"{len(colors)} colors were provided")
-
- hist_kwargs = dict()
-
- # if the bin_range is not given, compute without nan numpy
- # does not do this for us when guessing the range (but will
- # happily ignore nans when computing the histogram).
- if bin_range is None:
- xmin = np.inf
- xmax = -np.inf
- for xi in x:
- if len(xi):
- # python's min/max ignore nan,
- # np.minnan returns nan for all nan input
- xmin = min(xmin, np.nanmin(xi))
- xmax = max(xmax, np.nanmax(xi))
- if xmin <= xmax: # Only happens if we have seen a finite value.
- bin_range = (xmin, xmax)
-
- # If bins are not specified either explicitly or via range,
- # we need to figure out the range required for all datasets,
- # and supply that to np.histogram.
- if not input_empty and len(x) > 1:
- if weights is not None:
- _w = np.concatenate(w)
- else:
- _w = None
- bins = np.histogram_bin_edges(
- np.concatenate(x), bins, bin_range, _w)
- else:
- hist_kwargs['range'] = bin_range
-
- density = bool(density)
- if density and not stacked:
- hist_kwargs['density'] = density
-
- # List to store all the top coordinates of the histograms
- tops = [] # Will have shape (n_datasets, n_bins).
- # Loop through datasets
- for i in range(nx):
- # this will automatically overwrite bins,
- # so that each histogram uses the same bins
- m, bins = np.histogram(x[i], bins, weights=w[i], **hist_kwargs)
- tops.append(m)
- tops = np.array(tops, float) # causes problems later if it's an int
- bins = np.array(bins, float) # causes problems if float16
- if stacked:
- tops = tops.cumsum(axis=0)
- # If a stacked density plot, normalize so the area of all the
- # stacked histograms together is 1
- if density:
- tops = (tops / np.diff(bins)) / tops[-1].sum()
- if cumulative:
- slc = slice(None)
- if isinstance(cumulative, Number) and cumulative < 0:
- slc = slice(None, None, -1)
- if density:
- tops = (tops * np.diff(bins))[:, slc].cumsum(axis=1)[:, slc]
- else:
- tops = tops[:, slc].cumsum(axis=1)[:, slc]
-
- patches = []
-
- if histtype.startswith('bar'):
-
- totwidth = np.diff(bins)
-
- if rwidth is not None:
- dr = np.clip(rwidth, 0, 1)
- elif (len(tops) > 1 and
- ((not stacked) or mpl.rcParams['_internal.classic_mode'])):
- dr = 0.8
- else:
- dr = 1.0
-
- if histtype == 'bar' and not stacked:
- width = dr * totwidth / nx
- dw = width
- boffset = -0.5 * dr * totwidth * (1 - 1 / nx)
- elif histtype == 'barstacked' or stacked:
- width = dr * totwidth
- boffset, dw = 0.0, 0.0
-
- if align == 'mid':
- boffset += 0.5 * totwidth
- elif align == 'right':
- boffset += totwidth
-
- if orientation == 'horizontal':
- _barfunc = self.barh
- bottom_kwarg = 'left'
- else: # orientation == 'vertical'
- _barfunc = self.bar
- bottom_kwarg = 'bottom'
-
- for top, color in zip(tops, colors):
- if bottom is None:
- bottom = np.zeros(len(top))
- if stacked:
- height = top - bottom
- else:
- height = top
- bars = _barfunc(bins[:-1]+boffset, height, width,
- align='center', log=log,
- color=color, **{bottom_kwarg: bottom})
- patches.append(bars)
- if stacked:
- bottom = top
- boffset += dw
- # Remove stickies from all bars but the lowest ones, as otherwise
- # margin expansion would be unable to cross the stickies in the
- # middle of the bars.
- for bars in patches[1:]:
- for patch in bars:
- patch.sticky_edges.x[:] = patch.sticky_edges.y[:] = []
-
- elif histtype.startswith('step'):
- # these define the perimeter of the polygon
- x = np.zeros(4 * len(bins) - 3)
- y = np.zeros(4 * len(bins) - 3)
-
- x[0:2*len(bins)-1:2], x[1:2*len(bins)-1:2] = bins, bins[:-1]
- x[2*len(bins)-1:] = x[1:2*len(bins)-1][::-1]
-
- if bottom is None:
- bottom = 0
-
- y[1:2*len(bins)-1:2] = y[2:2*len(bins):2] = bottom
- y[2*len(bins)-1:] = y[1:2*len(bins)-1][::-1]
-
- if log:
- if orientation == 'horizontal':
- self.set_xscale('log', nonpositive='clip')
- else: # orientation == 'vertical'
- self.set_yscale('log', nonpositive='clip')
-
- if align == 'left':
- x -= 0.5*(bins[1]-bins[0])
- elif align == 'right':
- x += 0.5*(bins[1]-bins[0])
-
- # If fill kwarg is set, it will be passed to the patch collection,
- # overriding this
- fill = (histtype == 'stepfilled')
-
- xvals, yvals = [], []
- for top in tops:
- if stacked:
- # top of the previous polygon becomes the bottom
- y[2*len(bins)-1:] = y[1:2*len(bins)-1][::-1]
- # set the top of this polygon
- y[1:2*len(bins)-1:2] = y[2:2*len(bins):2] = top + bottom
-
- # The starting point of the polygon has not yet been
- # updated. So far only the endpoint was adjusted. This
- # assignment closes the polygon. The redundant endpoint is
- # later discarded (for step and stepfilled).
- y[0] = y[-1]
-
- if orientation == 'horizontal':
- xvals.append(y.copy())
- yvals.append(x.copy())
- else:
- xvals.append(x.copy())
- yvals.append(y.copy())
-
- # stepfill is closed, step is not
- split = -1 if fill else 2 * len(bins)
- # add patches in reverse order so that when stacking,
- # items lower in the stack are plotted on top of
- # items higher in the stack
- for x, y, color in reversed(list(zip(xvals, yvals, colors))):
- patches.append(self.fill(
- x[:split], y[:split],
- closed=True if fill else None,
- facecolor=color,
- edgecolor=None if fill else color,
- fill=fill if fill else None,
- zorder=None if fill else mlines.Line2D.zorder))
- for patch_list in patches:
- for patch in patch_list:
- if orientation == 'vertical':
- patch.sticky_edges.y.append(0)
- elif orientation == 'horizontal':
- patch.sticky_edges.x.append(0)
-
- # we return patches, so put it back in the expected order
- patches.reverse()
-
- # If None, make all labels None (via zip_longest below); otherwise,
- # cast each element to str, but keep a single str as it.
- labels = [] if label is None else np.atleast_1d(np.asarray(label, str))
- for patch, lbl in itertools.zip_longest(patches, labels):
- if patch:
- p = patch[0]
- p._internal_update(kwargs)
- if lbl is not None:
- p.set_label(lbl)
- for p in patch[1:]:
- p._internal_update(kwargs)
- p.set_label('_nolegend_')
-
- if nx == 1:
- return tops[0], bins, patches[0]
- else:
- patch_type = ("BarContainer" if histtype.startswith("bar")
- else "list[Polygon]")
- return tops, bins, cbook.silent_list(patch_type, patches)
-
- @_preprocess_data()
- def stairs(self, values, edges=None, *,
- orientation='vertical', baseline=0, fill=False, **kwargs):
- """
- A stepwise constant function as a line with bounding edges
- or a filled plot.
-
- Parameters
- ----------
- values : array-like
- The step heights.
-
- edges : array-like
- The edge positions, with ``len(edges) == len(vals) + 1``,
- between which the curve takes on vals values.
-
- orientation : {'vertical', 'horizontal'}, default: 'vertical'
- The direction of the steps. Vertical means that *values* are along
- the y-axis, and edges are along the x-axis.
-
- baseline : float, array-like or None, default: 0
- The bottom value of the bounding edges or when
- ``fill=True``, position of lower edge. If *fill* is
- True or an array is passed to *baseline*, a closed
- path is drawn.
-
- fill : bool, default: False
- Whether the area under the step curve should be filled.
-
- Returns
- -------
- StepPatch : `~matplotlib.patches.StepPatch`
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- `~matplotlib.patches.StepPatch` properties
-
- """
-
- if 'color' in kwargs:
- _color = kwargs.pop('color')
- else:
- _color = self._get_lines.get_next_color()
- if fill:
- kwargs.setdefault('linewidth', 0)
- kwargs.setdefault('facecolor', _color)
- else:
- kwargs.setdefault('edgecolor', _color)
-
- if edges is None:
- edges = np.arange(len(values) + 1)
-
- edges, values, baseline = self._process_unit_info(
- [("x", edges), ("y", values), ("y", baseline)], kwargs)
-
- patch = mpatches.StepPatch(values,
- edges,
- baseline=baseline,
- orientation=orientation,
- fill=fill,
- **kwargs)
- self.add_patch(patch)
- if baseline is None:
- baseline = 0
- if orientation == 'vertical':
- patch.sticky_edges.y.append(np.min(baseline))
- self.update_datalim([(edges[0], np.min(baseline))])
- else:
- patch.sticky_edges.x.append(np.min(baseline))
- self.update_datalim([(np.min(baseline), edges[0])])
- self._request_autoscale_view()
- return patch
-
- @_preprocess_data(replace_names=["x", "y", "weights"])
- @_docstring.dedent_interpd
- def hist2d(self, x, y, bins=10, range=None, density=False, weights=None,
- cmin=None, cmax=None, **kwargs):
- """
- Make a 2D histogram plot.
-
- Parameters
- ----------
- x, y : array-like, shape (n, )
- Input values
-
- bins : None or int or [int, int] or array-like or [array, array]
-
- The bin specification:
-
- - If int, the number of bins for the two dimensions
- (``nx = ny = bins``).
- - If ``[int, int]``, the number of bins in each dimension
- (``nx, ny = bins``).
- - If array-like, the bin edges for the two dimensions
- (``x_edges = y_edges = bins``).
- - If ``[array, array]``, the bin edges in each dimension
- (``x_edges, y_edges = bins``).
-
- The default value is 10.
-
- range : array-like shape(2, 2), optional
- The leftmost and rightmost edges of the bins along each dimension
- (if not specified explicitly in the bins parameters): ``[[xmin,
- xmax], [ymin, ymax]]``. All values outside of this range will be
- considered outliers and not tallied in the histogram.
-
- density : bool, default: False
- Normalize histogram. See the documentation for the *density*
- parameter of `~.Axes.hist` for more details.
-
- weights : array-like, shape (n, ), optional
- An array of values w_i weighing each sample (x_i, y_i).
-
- cmin, cmax : float, default: None
- All bins that has count less than *cmin* or more than *cmax* will not be
- displayed (set to NaN before passing to `~.Axes.pcolormesh`) and these count
- values in the return value count histogram will also be set to nan upon
- return.
-
- Returns
- -------
- h : 2D array
- The bi-dimensional histogram of samples x and y. Values in x are
- histogrammed along the first dimension and values in y are
- histogrammed along the second dimension.
- xedges : 1D array
- The bin edges along the x-axis.
- yedges : 1D array
- The bin edges along the y-axis.
- image : `~.matplotlib.collections.QuadMesh`
-
- Other Parameters
- ----------------
- %(cmap_doc)s
-
- %(norm_doc)s
-
- %(vmin_vmax_doc)s
-
- alpha : ``0 <= scalar <= 1`` or ``None``, optional
- The alpha blending value.
-
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Additional parameters are passed along to the
- `~.Axes.pcolormesh` method and `~matplotlib.collections.QuadMesh`
- constructor.
-
- See Also
- --------
- hist : 1D histogram plotting
- hexbin : 2D histogram with hexagonal bins
-
- Notes
- -----
- - Currently ``hist2d`` calculates its own axis limits, and any limits
- previously set are ignored.
- - Rendering the histogram with a logarithmic color scale is
- accomplished by passing a `.colors.LogNorm` instance to the *norm*
- keyword argument. Likewise, power-law normalization (similar
- in effect to gamma correction) can be accomplished with
- `.colors.PowerNorm`.
- """
-
- h, xedges, yedges = np.histogram2d(x, y, bins=bins, range=range,
- density=density, weights=weights)
-
- if cmin is not None:
- h[h < cmin] = None
- if cmax is not None:
- h[h > cmax] = None
-
- pc = self.pcolormesh(xedges, yedges, h.T, **kwargs)
- self.set_xlim(xedges[0], xedges[-1])
- self.set_ylim(yedges[0], yedges[-1])
-
- return h, xedges, yedges, pc
-
- @_preprocess_data(replace_names=["x", "weights"], label_namer="x")
- @_docstring.dedent_interpd
- def ecdf(self, x, weights=None, *, complementary=False,
- orientation="vertical", compress=False, **kwargs):
- """
- Compute and plot the empirical cumulative distribution function of *x*.
-
- .. versionadded:: 3.8
-
- Parameters
- ----------
- x : 1d array-like
- The input data. Infinite entries are kept (and move the relevant
- end of the ecdf from 0/1), but NaNs and masked values are errors.
-
- weights : 1d array-like or None, default: None
- The weights of the entries; must have the same shape as *x*.
- Weights corresponding to NaN data points are dropped, and then the
- remaining weights are normalized to sum to 1. If unset, all
- entries have the same weight.
-
- complementary : bool, default: False
- Whether to plot a cumulative distribution function, which increases
- from 0 to 1 (the default), or a complementary cumulative
- distribution function, which decreases from 1 to 0.
-
- orientation : {"vertical", "horizontal"}, default: "vertical"
- Whether the entries are plotted along the x-axis ("vertical", the
- default) or the y-axis ("horizontal"). This parameter takes the
- same values as in `~.Axes.hist`.
-
- compress : bool, default: False
- Whether multiple entries with the same values are grouped together
- (with a summed weight) before plotting. This is mainly useful if
- *x* contains many identical data points, to decrease the rendering
- complexity of the plot. If *x* contains no duplicate points, this
- has no effect and just uses some time and memory.
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Keyword arguments control the `.Line2D` properties:
-
- %(Line2D:kwdoc)s
-
- Returns
- -------
- `.Line2D`
-
- Notes
- -----
- The ecdf plot can be thought of as a cumulative histogram with one bin
- per data entry; i.e. it reports on the entire dataset without any
- arbitrary binning.
-
- If *x* contains NaNs or masked entries, either remove them first from
- the array (if they should not taken into account), or replace them by
- -inf or +inf (if they should be sorted at the beginning or the end of
- the array).
- """
- _api.check_in_list(["horizontal", "vertical"], orientation=orientation)
- if "drawstyle" in kwargs or "ds" in kwargs:
- raise TypeError("Cannot pass 'drawstyle' or 'ds' to ecdf()")
- if np.ma.getmask(x).any():
- raise ValueError("ecdf() does not support masked entries")
- x = np.asarray(x)
- if np.isnan(x).any():
- raise ValueError("ecdf() does not support NaNs")
- argsort = np.argsort(x)
- x = x[argsort]
- if weights is None:
- # Ensure that we end at exactly 1, avoiding floating point errors.
- cum_weights = (1 + np.arange(len(x))) / len(x)
- else:
- weights = np.take(weights, argsort) # Reorder weights like we reordered x.
- cum_weights = np.cumsum(weights / np.sum(weights))
- if compress:
- # Get indices of unique x values.
- compress_idxs = [0, *(x[:-1] != x[1:]).nonzero()[0] + 1]
- x = x[compress_idxs]
- cum_weights = cum_weights[compress_idxs]
- if orientation == "vertical":
- if not complementary:
- line, = self.plot([x[0], *x], [0, *cum_weights],
- drawstyle="steps-post", **kwargs)
- else:
- line, = self.plot([*x, x[-1]], [1, *1 - cum_weights],
- drawstyle="steps-pre", **kwargs)
- line.sticky_edges.y[:] = [0, 1]
- else: # orientation == "horizontal":
- if not complementary:
- line, = self.plot([0, *cum_weights], [x[0], *x],
- drawstyle="steps-pre", **kwargs)
- else:
- line, = self.plot([1, *1 - cum_weights], [*x, x[-1]],
- drawstyle="steps-post", **kwargs)
- line.sticky_edges.x[:] = [0, 1]
- return line
-
- @_preprocess_data(replace_names=["x"])
- @_docstring.dedent_interpd
- def psd(self, x, NFFT=None, Fs=None, Fc=None, detrend=None,
- window=None, noverlap=None, pad_to=None,
- sides=None, scale_by_freq=None, return_line=None, **kwargs):
- r"""
- Plot the power spectral density.
-
- The power spectral density :math:`P_{xx}` by Welch's average
- periodogram method. The vector *x* is divided into *NFFT* length
- segments. Each segment is detrended by function *detrend* and
- windowed by function *window*. *noverlap* gives the length of
- the overlap between segments. The :math:`|\mathrm{fft}(i)|^2`
- of each segment :math:`i` are averaged to compute :math:`P_{xx}`,
- with a scaling to correct for power loss due to windowing.
-
- If len(*x*) < *NFFT*, it will be zero padded to *NFFT*.
-
- Parameters
- ----------
- x : 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(PSD)s
-
- noverlap : int, default: 0 (no overlap)
- The number of points of overlap between segments.
-
- Fc : int, default: 0
- The center frequency of *x*, which offsets the x extents of the
- plot to reflect the frequency range used when a signal is acquired
- and then filtered and downsampled to baseband.
-
- return_line : bool, default: False
- Whether to include the line object plotted in the returned values.
-
- Returns
- -------
- Pxx : 1-D array
- The values for the power spectrum :math:`P_{xx}` before scaling
- (real valued).
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *Pxx*.
-
- line : `~matplotlib.lines.Line2D`
- The line created by this function.
- Only returned if *return_line* is True.
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Keyword arguments control the `.Line2D` properties:
-
- %(Line2D:kwdoc)s
-
- See Also
- --------
- specgram
- Differs in the default overlap; in not returning the mean of the
- segment periodograms; in returning the times of the segments; and
- in plotting a colormap instead of a line.
- magnitude_spectrum
- Plots the magnitude spectrum.
- csd
- Plots the spectral density between two signals.
-
- Notes
- -----
- For plotting, the power is plotted as
- :math:`10\log_{10}(P_{xx})` for decibels, though *Pxx* itself
- is returned.
-
- References
- ----------
- Bendat & Piersol -- Random Data: Analysis and Measurement Procedures,
- John Wiley & Sons (1986)
- """
- if Fc is None:
- Fc = 0
-
- pxx, freqs = mlab.psd(x=x, NFFT=NFFT, Fs=Fs, detrend=detrend,
- window=window, noverlap=noverlap, pad_to=pad_to,
- sides=sides, scale_by_freq=scale_by_freq)
- freqs += Fc
-
- if scale_by_freq in (None, True):
- psd_units = 'dB/Hz'
- else:
- psd_units = 'dB'
-
- line = self.plot(freqs, 10 * np.log10(pxx), **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Power Spectral Density (%s)' % psd_units)
- self.grid(True)
-
- vmin, vmax = self.get_ybound()
- step = max(10 * int(np.log10(vmax - vmin)), 1)
- ticks = np.arange(math.floor(vmin), math.ceil(vmax) + 1, step)
- self.set_yticks(ticks)
-
- if return_line is None or not return_line:
- return pxx, freqs
- else:
- return pxx, freqs, line
-
- @_preprocess_data(replace_names=["x", "y"], label_namer="y")
- @_docstring.dedent_interpd
- def csd(self, x, y, NFFT=None, Fs=None, Fc=None, detrend=None,
- window=None, noverlap=None, pad_to=None,
- sides=None, scale_by_freq=None, return_line=None, **kwargs):
- r"""
- Plot the cross-spectral density.
-
- The cross spectral density :math:`P_{xy}` by Welch's average
- periodogram method. The vectors *x* and *y* are divided into
- *NFFT* length segments. Each segment is detrended by function
- *detrend* and windowed by function *window*. *noverlap* gives
- the length of the overlap between segments. The product of
- the direct FFTs of *x* and *y* are averaged over each segment
- to compute :math:`P_{xy}`, with a scaling to correct for power
- loss due to windowing.
-
- If len(*x*) < *NFFT* or len(*y*) < *NFFT*, they will be zero
- padded to *NFFT*.
-
- Parameters
- ----------
- x, y : 1-D arrays or sequences
- Arrays or sequences containing the data.
-
- %(Spectral)s
-
- %(PSD)s
-
- noverlap : int, default: 0 (no overlap)
- The number of points of overlap between segments.
-
- Fc : int, default: 0
- The center frequency of *x*, which offsets the x extents of the
- plot to reflect the frequency range used when a signal is acquired
- and then filtered and downsampled to baseband.
-
- return_line : bool, default: False
- Whether to include the line object plotted in the returned values.
-
- Returns
- -------
- Pxy : 1-D array
- The values for the cross spectrum :math:`P_{xy}` before scaling
- (complex valued).
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *Pxy*.
-
- line : `~matplotlib.lines.Line2D`
- The line created by this function.
- Only returned if *return_line* is True.
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Keyword arguments control the `.Line2D` properties:
-
- %(Line2D:kwdoc)s
-
- See Also
- --------
- psd : is equivalent to setting ``y = x``.
-
- Notes
- -----
- For plotting, the power is plotted as
- :math:`10 \log_{10}(P_{xy})` for decibels, though :math:`P_{xy}` itself
- is returned.
-
- References
- ----------
- Bendat & Piersol -- Random Data: Analysis and Measurement Procedures,
- John Wiley & Sons (1986)
- """
- if Fc is None:
- Fc = 0
-
- pxy, freqs = mlab.csd(x=x, y=y, NFFT=NFFT, Fs=Fs, detrend=detrend,
- window=window, noverlap=noverlap, pad_to=pad_to,
- sides=sides, scale_by_freq=scale_by_freq)
- # pxy is complex
- freqs += Fc
-
- line = self.plot(freqs, 10 * np.log10(np.abs(pxy)), **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Cross Spectrum Magnitude (dB)')
- self.grid(True)
-
- vmin, vmax = self.get_ybound()
- step = max(10 * int(np.log10(vmax - vmin)), 1)
- ticks = np.arange(math.floor(vmin), math.ceil(vmax) + 1, step)
- self.set_yticks(ticks)
-
- if return_line is None or not return_line:
- return pxy, freqs
- else:
- return pxy, freqs, line
-
- @_preprocess_data(replace_names=["x"])
- @_docstring.dedent_interpd
- def magnitude_spectrum(self, x, Fs=None, Fc=None, window=None,
- pad_to=None, sides=None, scale=None,
- **kwargs):
- """
- Plot the magnitude spectrum.
-
- Compute the magnitude spectrum of *x*. Data is padded to a
- length of *pad_to* and the windowing function *window* is applied to
- the signal.
-
- Parameters
- ----------
- x : 1-D array or sequence
- Array or sequence containing the data.
-
- %(Spectral)s
-
- %(Single_Spectrum)s
-
- scale : {'default', 'linear', 'dB'}
- The scaling of the values in the *spec*. 'linear' is no scaling.
- 'dB' returns the values in dB scale, i.e., the dB amplitude
- (20 * log10). 'default' is 'linear'.
-
- Fc : int, default: 0
- The center frequency of *x*, which offsets the x extents of the
- plot to reflect the frequency range used when a signal is acquired
- and then filtered and downsampled to baseband.
-
- Returns
- -------
- spectrum : 1-D array
- The values for the magnitude spectrum before scaling (real valued).
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *spectrum*.
-
- line : `~matplotlib.lines.Line2D`
- The line created by this function.
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Keyword arguments control the `.Line2D` properties:
-
- %(Line2D:kwdoc)s
-
- See Also
- --------
- psd
- Plots the power spectral density.
- angle_spectrum
- Plots the angles of the corresponding frequencies.
- phase_spectrum
- Plots the phase (unwrapped angle) of the corresponding frequencies.
- specgram
- Can plot the magnitude spectrum of segments within the signal in a
- colormap.
- """
- if Fc is None:
- Fc = 0
-
- spec, freqs = mlab.magnitude_spectrum(x=x, Fs=Fs, window=window,
- pad_to=pad_to, sides=sides)
- freqs += Fc
-
- yunits = _api.check_getitem(
- {None: 'energy', 'default': 'energy', 'linear': 'energy',
- 'dB': 'dB'},
- scale=scale)
- if yunits == 'energy':
- Z = spec
- else: # yunits == 'dB'
- Z = 20. * np.log10(spec)
-
- line, = self.plot(freqs, Z, **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Magnitude (%s)' % yunits)
-
- return spec, freqs, line
-
- @_preprocess_data(replace_names=["x"])
- @_docstring.dedent_interpd
- def angle_spectrum(self, x, Fs=None, Fc=None, window=None,
- pad_to=None, sides=None, **kwargs):
- """
- Plot the angle spectrum.
-
- Compute the angle spectrum (wrapped phase spectrum) of *x*.
- Data is padded to a length of *pad_to* and the windowing function
- *window* is applied to the signal.
-
- Parameters
- ----------
- x : 1-D array or sequence
- Array or sequence containing the data.
-
- %(Spectral)s
-
- %(Single_Spectrum)s
-
- Fc : int, default: 0
- The center frequency of *x*, which offsets the x extents of the
- plot to reflect the frequency range used when a signal is acquired
- and then filtered and downsampled to baseband.
-
- Returns
- -------
- spectrum : 1-D array
- The values for the angle spectrum in radians (real valued).
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *spectrum*.
-
- line : `~matplotlib.lines.Line2D`
- The line created by this function.
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Keyword arguments control the `.Line2D` properties:
-
- %(Line2D:kwdoc)s
-
- See Also
- --------
- magnitude_spectrum
- Plots the magnitudes of the corresponding frequencies.
- phase_spectrum
- Plots the unwrapped version of this function.
- specgram
- Can plot the angle spectrum of segments within the signal in a
- colormap.
- """
- if Fc is None:
- Fc = 0
-
- spec, freqs = mlab.angle_spectrum(x=x, Fs=Fs, window=window,
- pad_to=pad_to, sides=sides)
- freqs += Fc
-
- lines = self.plot(freqs, spec, **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Angle (radians)')
-
- return spec, freqs, lines[0]
-
- @_preprocess_data(replace_names=["x"])
- @_docstring.dedent_interpd
- def phase_spectrum(self, x, Fs=None, Fc=None, window=None,
- pad_to=None, sides=None, **kwargs):
- """
- Plot the phase spectrum.
-
- Compute the phase spectrum (unwrapped angle spectrum) of *x*.
- Data is padded to a length of *pad_to* and the windowing function
- *window* is applied to the signal.
-
- Parameters
- ----------
- x : 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(Single_Spectrum)s
-
- Fc : int, default: 0
- The center frequency of *x*, which offsets the x extents of the
- plot to reflect the frequency range used when a signal is acquired
- and then filtered and downsampled to baseband.
-
- Returns
- -------
- spectrum : 1-D array
- The values for the phase spectrum in radians (real valued).
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *spectrum*.
-
- line : `~matplotlib.lines.Line2D`
- The line created by this function.
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Keyword arguments control the `.Line2D` properties:
-
- %(Line2D:kwdoc)s
-
- See Also
- --------
- magnitude_spectrum
- Plots the magnitudes of the corresponding frequencies.
- angle_spectrum
- Plots the wrapped version of this function.
- specgram
- Can plot the phase spectrum of segments within the signal in a
- colormap.
- """
- if Fc is None:
- Fc = 0
-
- spec, freqs = mlab.phase_spectrum(x=x, Fs=Fs, window=window,
- pad_to=pad_to, sides=sides)
- freqs += Fc
-
- lines = self.plot(freqs, spec, **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Phase (radians)')
-
- return spec, freqs, lines[0]
-
- @_preprocess_data(replace_names=["x", "y"])
- @_docstring.dedent_interpd
- def cohere(self, x, y, NFFT=256, Fs=2, Fc=0, detrend=mlab.detrend_none,
- window=mlab.window_hanning, noverlap=0, pad_to=None,
- sides='default', scale_by_freq=None, **kwargs):
- r"""
- Plot the coherence between *x* and *y*.
-
- Coherence is the normalized cross spectral density:
-
- .. math::
-
- C_{xy} = \frac{|P_{xy}|^2}{P_{xx}P_{yy}}
-
- Parameters
- ----------
- %(Spectral)s
-
- %(PSD)s
-
- noverlap : int, default: 0 (no overlap)
- The number of points of overlap between blocks.
-
- Fc : int, default: 0
- The center frequency of *x*, which offsets the x extents of the
- plot to reflect the frequency range used when a signal is acquired
- and then filtered and downsampled to baseband.
-
- Returns
- -------
- Cxy : 1-D array
- The coherence vector.
-
- freqs : 1-D array
- The frequencies for the elements in *Cxy*.
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Keyword arguments control the `.Line2D` properties:
-
- %(Line2D:kwdoc)s
-
- References
- ----------
- Bendat & Piersol -- Random Data: Analysis and Measurement Procedures,
- John Wiley & Sons (1986)
- """
- cxy, freqs = mlab.cohere(x=x, y=y, NFFT=NFFT, Fs=Fs, detrend=detrend,
- window=window, noverlap=noverlap,
- scale_by_freq=scale_by_freq, sides=sides,
- pad_to=pad_to)
- freqs += Fc
-
- self.plot(freqs, cxy, **kwargs)
- self.set_xlabel('Frequency')
- self.set_ylabel('Coherence')
- self.grid(True)
-
- return cxy, freqs
-
- @_preprocess_data(replace_names=["x"])
- @_docstring.dedent_interpd
- def specgram(self, x, NFFT=None, Fs=None, Fc=None, detrend=None,
- window=None, noverlap=None,
- cmap=None, xextent=None, pad_to=None, sides=None,
- scale_by_freq=None, mode=None, scale=None,
- vmin=None, vmax=None, **kwargs):
- """
- Plot a spectrogram.
-
- Compute and plot a spectrogram of data in *x*. Data are split into
- *NFFT* length segments and the spectrum of each section is
- computed. The windowing function *window* is applied to each
- segment, and the amount of overlap of each segment is
- specified with *noverlap*. The spectrogram is plotted as a colormap
- (using imshow).
-
- Parameters
- ----------
- x : 1-D array or sequence
- Array or sequence containing the data.
-
- %(Spectral)s
-
- %(PSD)s
-
- mode : {'default', 'psd', 'magnitude', 'angle', 'phase'}
- What sort of spectrum to use. Default is 'psd', which takes the
- power spectral density. 'magnitude' returns the magnitude
- spectrum. 'angle' returns the phase spectrum without unwrapping.
- 'phase' returns the phase spectrum with unwrapping.
-
- noverlap : int, default: 128
- The number of points of overlap between blocks.
-
- scale : {'default', 'linear', 'dB'}
- The scaling of the values in the *spec*. 'linear' is no scaling.
- 'dB' returns the values in dB scale. When *mode* is 'psd',
- this is dB power (10 * log10). Otherwise, this is dB amplitude
- (20 * log10). 'default' is 'dB' if *mode* is 'psd' or
- 'magnitude' and 'linear' otherwise. This must be 'linear'
- if *mode* is 'angle' or 'phase'.
-
- Fc : int, default: 0
- The center frequency of *x*, which offsets the x extents of the
- plot to reflect the frequency range used when a signal is acquired
- and then filtered and downsampled to baseband.
-
- cmap : `.Colormap`, default: :rc:`image.cmap`
-
- xextent : *None* or (xmin, xmax)
- The image extent along the x-axis. The default sets *xmin* to the
- left border of the first bin (*spectrum* column) and *xmax* to the
- right border of the last bin. Note that for *noverlap>0* the width
- of the bins is smaller than those of the segments.
-
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Additional keyword arguments are passed on to `~.axes.Axes.imshow`
- which makes the specgram image. The origin keyword argument
- is not supported.
-
- Returns
- -------
- spectrum : 2D array
- Columns are the periodograms of successive segments.
-
- freqs : 1-D array
- The frequencies corresponding to the rows in *spectrum*.
-
- t : 1-D array
- The times corresponding to midpoints of segments (i.e., the columns
- in *spectrum*).
-
- im : `.AxesImage`
- The image created by imshow containing the spectrogram.
-
- See Also
- --------
- psd
- Differs in the default overlap; in returning the mean of the
- segment periodograms; in not returning times; and in generating a
- line plot instead of colormap.
- magnitude_spectrum
- A single spectrum, similar to having a single segment when *mode*
- is 'magnitude'. Plots a line instead of a colormap.
- angle_spectrum
- A single spectrum, similar to having a single segment when *mode*
- is 'angle'. Plots a line instead of a colormap.
- phase_spectrum
- A single spectrum, similar to having a single segment when *mode*
- is 'phase'. Plots a line instead of a colormap.
-
- Notes
- -----
- The parameters *detrend* and *scale_by_freq* do only apply when *mode*
- is set to 'psd'.
- """
- if NFFT is None:
- NFFT = 256 # same default as in mlab.specgram()
- if Fc is None:
- Fc = 0 # same default as in mlab._spectral_helper()
- if noverlap is None:
- noverlap = 128 # same default as in mlab.specgram()
- if Fs is None:
- Fs = 2 # same default as in mlab._spectral_helper()
-
- if mode == 'complex':
- raise ValueError('Cannot plot a complex specgram')
-
- if scale is None or scale == 'default':
- if mode in ['angle', 'phase']:
- scale = 'linear'
- else:
- scale = 'dB'
- elif mode in ['angle', 'phase'] and scale == 'dB':
- raise ValueError('Cannot use dB scale with angle or phase mode')
-
- spec, freqs, t = mlab.specgram(x=x, NFFT=NFFT, Fs=Fs,
- detrend=detrend, window=window,
- noverlap=noverlap, pad_to=pad_to,
- sides=sides,
- scale_by_freq=scale_by_freq,
- mode=mode)
-
- if scale == 'linear':
- Z = spec
- elif scale == 'dB':
- if mode is None or mode == 'default' or mode == 'psd':
- Z = 10. * np.log10(spec)
- else:
- Z = 20. * np.log10(spec)
- else:
- raise ValueError(f'Unknown scale {scale!r}')
-
- Z = np.flipud(Z)
-
- if xextent is None:
- # padding is needed for first and last segment:
- pad_xextent = (NFFT-noverlap) / Fs / 2
- xextent = np.min(t) - pad_xextent, np.max(t) + pad_xextent
- xmin, xmax = xextent
- freqs += Fc
- extent = xmin, xmax, freqs[0], freqs[-1]
-
- if 'origin' in kwargs:
- raise _api.kwarg_error("specgram", "origin")
-
- im = self.imshow(Z, cmap, extent=extent, vmin=vmin, vmax=vmax,
- origin='upper', **kwargs)
- self.axis('auto')
-
- return spec, freqs, t, im
-
- @_docstring.dedent_interpd
- def spy(self, Z, precision=0, marker=None, markersize=None,
- aspect='equal', origin="upper", **kwargs):
- """
- Plot the sparsity pattern of a 2D array.
-
- This visualizes the non-zero values of the array.
-
- Two plotting styles are available: image and marker. Both
- are available for full arrays, but only the marker style
- works for `scipy.sparse.spmatrix` instances.
-
- **Image style**
-
- If *marker* and *markersize* are *None*, `~.Axes.imshow` is used. Any
- extra remaining keyword arguments are passed to this method.
-
- **Marker style**
-
- If *Z* is a `scipy.sparse.spmatrix` or *marker* or *markersize* are
- *None*, a `.Line2D` object will be returned with the value of marker
- determining the marker type, and any remaining keyword arguments
- passed to `~.Axes.plot`.
-
- Parameters
- ----------
- Z : (M, N) array-like
- The array to be plotted.
-
- precision : float or 'present', default: 0
- If *precision* is 0, any non-zero value will be plotted. Otherwise,
- values of :math:`|Z| > precision` will be plotted.
-
- For `scipy.sparse.spmatrix` instances, you can also
- pass 'present'. In this case any value present in the array
- will be plotted, even if it is identically zero.
-
- aspect : {'equal', 'auto', None} or float, default: 'equal'
- The aspect ratio of the Axes. This parameter is particularly
- relevant for images since it determines whether data pixels are
- square.
-
- This parameter is a shortcut for explicitly calling
- `.Axes.set_aspect`. See there for further details.
-
- - 'equal': Ensures an aspect ratio of 1. Pixels will be square.
- - 'auto': The Axes is kept fixed and the aspect is adjusted so
- that the data fit in the Axes. In general, this will result in
- non-square pixels.
- - *None*: Use :rc:`image.aspect`.
-
- origin : {'upper', 'lower'}, default: :rc:`image.origin`
- Place the [0, 0] index of the array in the upper left or lower left
- corner of the Axes. The convention 'upper' is typically used for
- matrices and images.
-
- Returns
- -------
- `~matplotlib.image.AxesImage` or `.Line2D`
- The return type depends on the plotting style (see above).
-
- Other Parameters
- ----------------
- **kwargs
- The supported additional parameters depend on the plotting style.
-
- For the image style, you can pass the following additional
- parameters of `~.Axes.imshow`:
-
- - *cmap*
- - *alpha*
- - *url*
- - any `.Artist` properties (passed on to the `.AxesImage`)
-
- For the marker style, you can pass any `.Line2D` property except
- for *linestyle*:
-
- %(Line2D:kwdoc)s
- """
- if marker is None and markersize is None and hasattr(Z, 'tocoo'):
- marker = 's'
- _api.check_in_list(["upper", "lower"], origin=origin)
- if marker is None and markersize is None:
- Z = np.asarray(Z)
- mask = np.abs(Z) > precision
-
- if 'cmap' not in kwargs:
- kwargs['cmap'] = mcolors.ListedColormap(['w', 'k'],
- name='binary')
- if 'interpolation' in kwargs:
- raise _api.kwarg_error("spy", "interpolation")
- if 'norm' not in kwargs:
- kwargs['norm'] = mcolors.NoNorm()
- ret = self.imshow(mask, interpolation='nearest',
- aspect=aspect, origin=origin,
- **kwargs)
- else:
- if hasattr(Z, 'tocoo'):
- c = Z.tocoo()
- if precision == 'present':
- y = c.row
- x = c.col
- else:
- nonzero = np.abs(c.data) > precision
- y = c.row[nonzero]
- x = c.col[nonzero]
- else:
- Z = np.asarray(Z)
- nonzero = np.abs(Z) > precision
- y, x = np.nonzero(nonzero)
- if marker is None:
- marker = 's'
- if markersize is None:
- markersize = 10
- if 'linestyle' in kwargs:
- raise _api.kwarg_error("spy", "linestyle")
- ret = mlines.Line2D(
- x, y, linestyle='None', marker=marker, markersize=markersize,
- **kwargs)
- self.add_line(ret)
- nr, nc = Z.shape
- self.set_xlim(-0.5, nc - 0.5)
- if origin == "upper":
- self.set_ylim(nr - 0.5, -0.5)
- else:
- self.set_ylim(-0.5, nr - 0.5)
- self.set_aspect(aspect)
- self.title.set_y(1.05)
- if origin == "upper":
- self.xaxis.tick_top()
- else: # lower
- self.xaxis.tick_bottom()
- self.xaxis.set_ticks_position('both')
- self.xaxis.set_major_locator(
- mticker.MaxNLocator(nbins=9, steps=[1, 2, 5, 10], integer=True))
- self.yaxis.set_major_locator(
- mticker.MaxNLocator(nbins=9, steps=[1, 2, 5, 10], integer=True))
- return ret
-
- def matshow(self, Z, **kwargs):
- """
- Plot the values of a 2D matrix or array as color-coded image.
-
- The matrix will be shown the way it would be printed, with the first
- row at the top. Row and column numbering is zero-based.
-
- Parameters
- ----------
- Z : (M, N) array-like
- The matrix to be displayed.
-
- Returns
- -------
- `~matplotlib.image.AxesImage`
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.axes.Axes.imshow` arguments
-
- See Also
- --------
- imshow : More general function to plot data on a 2D regular raster.
-
- Notes
- -----
- This is just a convenience function wrapping `.imshow` to set useful
- defaults for displaying a matrix. In particular:
-
- - Set ``origin='upper'``.
- - Set ``interpolation='nearest'``.
- - Set ``aspect='equal'``.
- - Ticks are placed to the left and above.
- - Ticks are formatted to show integer indices.
-
- """
- Z = np.asanyarray(Z)
- kw = {'origin': 'upper',
- 'interpolation': 'nearest',
- 'aspect': 'equal', # (already the imshow default)
- **kwargs}
- im = self.imshow(Z, **kw)
- self.title.set_y(1.05)
- self.xaxis.tick_top()
- self.xaxis.set_ticks_position('both')
- self.xaxis.set_major_locator(
- mticker.MaxNLocator(nbins=9, steps=[1, 2, 5, 10], integer=True))
- self.yaxis.set_major_locator(
- mticker.MaxNLocator(nbins=9, steps=[1, 2, 5, 10], integer=True))
- return im
-
- @_preprocess_data(replace_names=["dataset"])
- def violinplot(self, dataset, positions=None, vert=True, widths=0.5,
- showmeans=False, showextrema=True, showmedians=False,
- quantiles=None, points=100, bw_method=None):
- """
- Make a violin plot.
-
- Make a violin plot for each column of *dataset* or each vector in
- sequence *dataset*. Each filled area extends to represent the
- entire data range, with optional lines at the mean, the median,
- the minimum, the maximum, and user-specified quantiles.
-
- Parameters
- ----------
- dataset : Array or a sequence of vectors.
- The input data.
-
- positions : array-like, default: [1, 2, ..., n]
- The positions of the violins. The ticks and limits are
- automatically set to match the positions.
-
- vert : bool, default: True.
- If true, creates a vertical violin plot.
- Otherwise, creates a horizontal violin plot.
-
- widths : array-like, default: 0.5
- Either a scalar or a vector that sets the maximal width of
- each violin. The default is 0.5, which uses about half of the
- available horizontal space.
-
- showmeans : bool, default: False
- If `True`, will toggle rendering of the means.
-
- showextrema : bool, default: True
- If `True`, will toggle rendering of the extrema.
-
- showmedians : bool, default: False
- If `True`, will toggle rendering of the medians.
-
- quantiles : array-like, default: None
- If not None, set a list of floats in interval [0, 1] for each violin,
- which stands for the quantiles that will be rendered for that
- violin.
-
- points : int, default: 100
- Defines the number of points to evaluate each of the
- gaussian kernel density estimations at.
-
- bw_method : str, scalar or callable, optional
- The method used to calculate the estimator bandwidth. This can be
- 'scott', 'silverman', a scalar constant or a callable. If a
- scalar, this will be used directly as `kde.factor`. If a
- callable, it should take a `matplotlib.mlab.GaussianKDE` instance as
- its only parameter and return a scalar. If None (default), 'scott'
- is used.
-
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- Returns
- -------
- dict
- A dictionary mapping each component of the violinplot to a
- list of the corresponding collection instances created. The
- dictionary has the following keys:
-
- - ``bodies``: A list of the `~.collections.PolyCollection`
- instances containing the filled area of each violin.
-
- - ``cmeans``: A `~.collections.LineCollection` instance that marks
- the mean values of each of the violin's distribution.
-
- - ``cmins``: A `~.collections.LineCollection` instance that marks
- the bottom of each violin's distribution.
-
- - ``cmaxes``: A `~.collections.LineCollection` instance that marks
- the top of each violin's distribution.
-
- - ``cbars``: A `~.collections.LineCollection` instance that marks
- the centers of each violin's distribution.
-
- - ``cmedians``: A `~.collections.LineCollection` instance that
- marks the median values of each of the violin's distribution.
-
- - ``cquantiles``: A `~.collections.LineCollection` instance created
- to identify the quantile values of each of the violin's
- distribution.
-
- """
-
- def _kde_method(X, coords):
- # Unpack in case of e.g. Pandas or xarray object
- X = cbook._unpack_to_numpy(X)
- # fallback gracefully if the vector contains only one value
- if np.all(X[0] == X):
- return (X[0] == coords).astype(float)
- kde = mlab.GaussianKDE(X, bw_method)
- return kde.evaluate(coords)
-
- vpstats = cbook.violin_stats(dataset, _kde_method, points=points,
- quantiles=quantiles)
- return self.violin(vpstats, positions=positions, vert=vert,
- widths=widths, showmeans=showmeans,
- showextrema=showextrema, showmedians=showmedians)
-
- def violin(self, vpstats, positions=None, vert=True, widths=0.5,
- showmeans=False, showextrema=True, showmedians=False):
- """
- Drawing function for violin plots.
-
- Draw a violin plot for each column of *vpstats*. Each filled area
- extends to represent the entire data range, with optional lines at the
- mean, the median, the minimum, the maximum, and the quantiles values.
-
- Parameters
- ----------
- vpstats : list of dicts
- A list of dictionaries containing stats for each violin plot.
- Required keys are:
-
- - ``coords``: A list of scalars containing the coordinates that
- the violin's kernel density estimate were evaluated at.
-
- - ``vals``: A list of scalars containing the values of the
- kernel density estimate at each of the coordinates given
- in *coords*.
-
- - ``mean``: The mean value for this violin's dataset.
-
- - ``median``: The median value for this violin's dataset.
-
- - ``min``: The minimum value for this violin's dataset.
-
- - ``max``: The maximum value for this violin's dataset.
-
- Optional keys are:
-
- - ``quantiles``: A list of scalars containing the quantile values
- for this violin's dataset.
-
- positions : array-like, default: [1, 2, ..., n]
- The positions of the violins. The ticks and limits are
- automatically set to match the positions.
-
- vert : bool, default: True.
- If true, plots the violins vertically.
- Otherwise, plots the violins horizontally.
-
- widths : array-like, default: 0.5
- Either a scalar or a vector that sets the maximal width of
- each violin. The default is 0.5, which uses about half of the
- available horizontal space.
-
- showmeans : bool, default: False
- If true, will toggle rendering of the means.
-
- showextrema : bool, default: True
- If true, will toggle rendering of the extrema.
-
- showmedians : bool, default: False
- If true, will toggle rendering of the medians.
-
- Returns
- -------
- dict
- A dictionary mapping each component of the violinplot to a
- list of the corresponding collection instances created. The
- dictionary has the following keys:
-
- - ``bodies``: A list of the `~.collections.PolyCollection`
- instances containing the filled area of each violin.
-
- - ``cmeans``: A `~.collections.LineCollection` instance that marks
- the mean values of each of the violin's distribution.
-
- - ``cmins``: A `~.collections.LineCollection` instance that marks
- the bottom of each violin's distribution.
-
- - ``cmaxes``: A `~.collections.LineCollection` instance that marks
- the top of each violin's distribution.
-
- - ``cbars``: A `~.collections.LineCollection` instance that marks
- the centers of each violin's distribution.
-
- - ``cmedians``: A `~.collections.LineCollection` instance that
- marks the median values of each of the violin's distribution.
-
- - ``cquantiles``: A `~.collections.LineCollection` instance created
- to identify the quantiles values of each of the violin's
- distribution.
- """
-
- # Statistical quantities to be plotted on the violins
- means = []
- mins = []
- maxes = []
- medians = []
- quantiles = []
-
- qlens = [] # Number of quantiles in each dataset.
-
- artists = {} # Collections to be returned
-
- N = len(vpstats)
- datashape_message = ("List of violinplot statistics and `{0}` "
- "values must have the same length")
-
- # Validate positions
- if positions is None:
- positions = range(1, N + 1)
- elif len(positions) != N:
- raise ValueError(datashape_message.format("positions"))
-
- # Validate widths
- if np.isscalar(widths):
- widths = [widths] * N
- elif len(widths) != N:
- raise ValueError(datashape_message.format("widths"))
-
- # Calculate ranges for statistics lines (shape (2, N)).
- line_ends = [[-0.25], [0.25]] * np.array(widths) + positions
-
- # Colors.
- if mpl.rcParams['_internal.classic_mode']:
- fillcolor = 'y'
- linecolor = 'r'
- else:
- fillcolor = linecolor = self._get_lines.get_next_color()
-
- # Check whether we are rendering vertically or horizontally
- if vert:
- fill = self.fill_betweenx
- perp_lines = functools.partial(self.hlines, colors=linecolor)
- par_lines = functools.partial(self.vlines, colors=linecolor)
- else:
- fill = self.fill_between
- perp_lines = functools.partial(self.vlines, colors=linecolor)
- par_lines = functools.partial(self.hlines, colors=linecolor)
-
- # Render violins
- bodies = []
- for stats, pos, width in zip(vpstats, positions, widths):
- # The 0.5 factor reflects the fact that we plot from v-p to v+p.
- vals = np.array(stats['vals'])
- vals = 0.5 * width * vals / vals.max()
- bodies += [fill(stats['coords'], -vals + pos, vals + pos,
- facecolor=fillcolor, alpha=0.3)]
- means.append(stats['mean'])
- mins.append(stats['min'])
- maxes.append(stats['max'])
- medians.append(stats['median'])
- q = stats.get('quantiles') # a list of floats, or None
- if q is None:
- q = []
- quantiles.extend(q)
- qlens.append(len(q))
- artists['bodies'] = bodies
-
- if showmeans: # Render means
- artists['cmeans'] = perp_lines(means, *line_ends)
- if showextrema: # Render extrema
- artists['cmaxes'] = perp_lines(maxes, *line_ends)
- artists['cmins'] = perp_lines(mins, *line_ends)
- artists['cbars'] = par_lines(positions, mins, maxes)
- if showmedians: # Render medians
- artists['cmedians'] = perp_lines(medians, *line_ends)
- if quantiles: # Render quantiles: each width is repeated qlen times.
- artists['cquantiles'] = perp_lines(
- quantiles, *np.repeat(line_ends, qlens, axis=1))
-
- return artists
-
- # Methods that are entirely implemented in other modules.
-
- table = mtable.table
-
- # args can be either Y or y1, y2, ... and all should be replaced
- stackplot = _preprocess_data()(mstack.stackplot)
-
- streamplot = _preprocess_data(
- replace_names=["x", "y", "u", "v", "start_points"])(mstream.streamplot)
-
- tricontour = mtri.tricontour
- tricontourf = mtri.tricontourf
- tripcolor = mtri.tripcolor
- triplot = mtri.triplot
-
- def _get_aspect_ratio(self):
- """
- Convenience method to calculate the aspect ratio of the axes in
- the display coordinate system.
- """
- figure_size = self.get_figure().get_size_inches()
- ll, ur = self.get_position() * figure_size
- width, height = ur - ll
- return height / (width * self.get_data_ratio())
diff --git a/contrib/python/matplotlib/py3/matplotlib/axes/_axes.pyi b/contrib/python/matplotlib/py3/matplotlib/axes/_axes.pyi
deleted file mode 100644
index 9602db3b95..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/axes/_axes.pyi
+++ /dev/null
@@ -1,767 +0,0 @@
-from matplotlib.axes._base import _AxesBase
-from matplotlib.axes._secondary_axes import SecondaryAxis
-
-from matplotlib.artist import Artist
-from matplotlib.backend_bases import RendererBase
-from matplotlib.collections import (
- Collection,
- LineCollection,
- BrokenBarHCollection,
- PathCollection,
- PolyCollection,
- EventCollection,
- QuadMesh,
-)
-from matplotlib.colors import Colormap, Normalize
-from matplotlib.container import BarContainer, ErrorbarContainer, StemContainer
-from matplotlib.contour import ContourSet, QuadContourSet
-from matplotlib.image import AxesImage, PcolorImage
-from matplotlib.legend import Legend
-from matplotlib.legend_handler import HandlerBase
-from matplotlib.lines import Line2D
-from matplotlib.mlab import GaussianKDE
-from matplotlib.patches import Rectangle, FancyArrow, Polygon, StepPatch, Wedge
-from matplotlib.quiver import Quiver, QuiverKey, Barbs
-from matplotlib.text import Annotation, Text
-from matplotlib.transforms import Transform, Bbox
-import matplotlib.tri as mtri
-import matplotlib.table as mtable
-import matplotlib.stackplot as mstack
-import matplotlib.streamplot as mstream
-
-import datetime
-import PIL.Image
-from collections.abc import Callable, Sequence
-from typing import Any, Literal, overload
-import numpy as np
-from numpy.typing import ArrayLike
-from matplotlib.typing import ColorType, MarkerType, LineStyleType
-
-class Axes(_AxesBase):
- def get_title(self, loc: Literal["left", "center", "right"] = ...) -> str: ...
- def set_title(
- self,
- label: str,
- fontdict: dict[str, Any] | None = ...,
- loc: Literal["left", "center", "right"] | None = ...,
- pad: float | None = ...,
- *,
- y: float | None = ...,
- **kwargs
- ) -> Text: ...
- def get_legend_handles_labels(
- self, legend_handler_map: dict[type, HandlerBase] | None = ...
- ) -> tuple[list[Artist], list[Any]]: ...
- legend_: Legend | None
-
- @overload
- def legend(self) -> Legend: ...
- @overload
- def legend(self, handles: Sequence[Artist | tuple[Artist, ...]], labels: Sequence[str], **kwargs) -> Legend: ...
- @overload
- def legend(self, *, handles: Sequence[Artist | tuple[Artist, ...]], **kwargs) -> Legend: ...
- @overload
- def legend(self, labels: Sequence[str], **kwargs) -> Legend: ...
- @overload
- def legend(self, **kwargs) -> Legend: ...
-
- def inset_axes(
- self,
- bounds: tuple[float, float, float, float],
- *,
- transform: Transform | None = ...,
- zorder: float = ...,
- **kwargs
- ) -> Axes: ...
- def indicate_inset(
- self,
- bounds: tuple[float, float, float, float],
- inset_ax: Axes | None = ...,
- *,
- transform: Transform | None = ...,
- facecolor: ColorType = ...,
- edgecolor: ColorType = ...,
- alpha: float = ...,
- zorder: float = ...,
- **kwargs
- ) -> Rectangle: ...
- def indicate_inset_zoom(self, inset_ax: Axes, **kwargs) -> Rectangle: ...
- def secondary_xaxis(
- self,
- location: Literal["top", "bottom"] | float,
- *,
- functions: tuple[
- Callable[[ArrayLike], ArrayLike], Callable[[ArrayLike], ArrayLike]
- ]
- | Transform
- | None = ...,
- **kwargs
- ) -> SecondaryAxis: ...
- def secondary_yaxis(
- self,
- location: Literal["left", "right"] | float,
- *,
- functions: tuple[
- Callable[[ArrayLike], ArrayLike], Callable[[ArrayLike], ArrayLike]
- ]
- | Transform
- | None = ...,
- **kwargs
- ) -> SecondaryAxis: ...
- def text(
- self,
- x: float,
- y: float,
- s: str,
- fontdict: dict[str, Any] | None = ...,
- **kwargs
- ) -> Text: ...
- def annotate(
- self,
- text: str,
- xy: tuple[float, float],
- xytext: tuple[float, float] | None = ...,
- xycoords: str
- | Artist
- | Transform
- | Callable[[RendererBase], Bbox | Transform]
- | tuple[float, float] = ...,
- textcoords: str
- | Artist
- | Transform
- | Callable[[RendererBase], Bbox | Transform]
- | tuple[float, float]
- | None = ...,
- arrowprops: dict[str, Any] | None = ...,
- annotation_clip: bool | None = ...,
- **kwargs
- ) -> Annotation: ...
- def axhline(
- self, y: float = ..., xmin: float = ..., xmax: float = ..., **kwargs
- ) -> Line2D: ...
- def axvline(
- self, x: float = ..., ymin: float = ..., ymax: float = ..., **kwargs
- ) -> Line2D: ...
-
- # TODO: Could separate the xy2 and slope signatures
- def axline(
- self,
- xy1: tuple[float, float],
- xy2: tuple[float, float] | None = ...,
- *,
- slope: float | None = ...,
- **kwargs
- ) -> Line2D: ...
- def axhspan(
- self, ymin: float, ymax: float, xmin: float = ..., xmax: float = ..., **kwargs
- ) -> Polygon: ...
- def axvspan(
- self, xmin: float, xmax: float, ymin: float = ..., ymax: float = ..., **kwargs
- ) -> Polygon: ...
- def hlines(
- self,
- y: float | ArrayLike,
- xmin: float | ArrayLike,
- xmax: float | ArrayLike,
- colors: ColorType | Sequence[ColorType] | None = ...,
- linestyles: LineStyleType = ...,
- label: str = ...,
- *,
- data=...,
- **kwargs
- ) -> LineCollection: ...
- def vlines(
- self,
- x: float | ArrayLike,
- ymin: float | ArrayLike,
- ymax: float | ArrayLike,
- colors: ColorType | Sequence[ColorType] | None = ...,
- linestyles: LineStyleType = ...,
- label: str = ...,
- *,
- data=...,
- **kwargs
- ) -> LineCollection: ...
- def eventplot(
- self,
- positions: ArrayLike | Sequence[ArrayLike],
- orientation: Literal["horizontal", "vertical"] = ...,
- lineoffsets: float | Sequence[float] = ...,
- linelengths: float | Sequence[float] = ...,
- linewidths: float | Sequence[float] | None = ...,
- colors: ColorType | Sequence[ColorType] | None = ...,
- alpha: float | Sequence[float] | None = ...,
- linestyles: LineStyleType | Sequence[LineStyleType] = ...,
- *,
- data=...,
- **kwargs
- ) -> EventCollection: ...
- def plot(
- self,
- *args: float | ArrayLike | str,
- scalex: bool = ...,
- scaley: bool = ...,
- data = ...,
- **kwargs
- ) -> list[Line2D]: ...
- def plot_date(
- self,
- x: ArrayLike,
- y: ArrayLike,
- fmt: str = ...,
- tz: str | datetime.tzinfo | None = ...,
- xdate: bool = ...,
- ydate: bool = ...,
- *,
- data=...,
- **kwargs
- ) -> list[Line2D]: ...
- def loglog(self, *args, **kwargs) -> list[Line2D]: ...
- def semilogx(self, *args, **kwargs) -> list[Line2D]: ...
- def semilogy(self, *args, **kwargs) -> list[Line2D]: ...
- def acorr(
- self, x: ArrayLike, *, data=..., **kwargs
- ) -> tuple[np.ndarray, np.ndarray, LineCollection | Line2D, Line2D | None]: ...
- def xcorr(
- self,
- x: ArrayLike,
- y: ArrayLike,
- normed: bool = ...,
- detrend: Callable[[ArrayLike], ArrayLike] = ...,
- usevlines: bool = ...,
- maxlags: int = ...,
- *,
- data = ...,
- **kwargs
- ) -> tuple[np.ndarray, np.ndarray, LineCollection | Line2D, Line2D | None]: ...
- def step(
- self,
- x: ArrayLike,
- y: ArrayLike,
- *args,
- where: Literal["pre", "post", "mid"] = ...,
- data = ...,
- **kwargs
- ) -> list[Line2D]: ...
- def bar(
- self,
- x: float | ArrayLike,
- height: float | ArrayLike,
- width: float | ArrayLike = ...,
- bottom: float | ArrayLike | None = ...,
- *,
- align: Literal["center", "edge"] = ...,
- data = ...,
- **kwargs
- ) -> BarContainer: ...
- def barh(
- self,
- y: float | ArrayLike,
- width: float | ArrayLike,
- height: float | ArrayLike = ...,
- left: float | ArrayLike | None = ...,
- *,
- align: Literal["center", "edge"] = ...,
- data = ...,
- **kwargs
- ) -> BarContainer: ...
- def bar_label(
- self,
- container: BarContainer,
- labels: ArrayLike | None = ...,
- *,
- fmt: str | Callable[[float], str] = ...,
- label_type: Literal["center", "edge"] = ...,
- padding: float = ...,
- **kwargs
- ) -> list[Annotation]: ...
- def broken_barh(
- self,
- xranges: Sequence[tuple[float, float]],
- yrange: tuple[float, float],
- *,
- data=...,
- **kwargs
- ) -> BrokenBarHCollection: ...
- def stem(
- self,
- *args: ArrayLike | str,
- linefmt: str | None = ...,
- markerfmt: str | None = ...,
- basefmt: str | None = ...,
- bottom: float = ...,
- label: str | None = ...,
- orientation: Literal["vertical", "horizontal"] = ...,
- data=...,
- ) -> StemContainer: ...
-
- # TODO: data kwarg preprocessor?
- def pie(
- self,
- x: ArrayLike,
- explode: ArrayLike | None = ...,
- labels: Sequence[str] | None = ...,
- colors: ColorType | Sequence[ColorType] | None = ...,
- autopct: str | Callable[[float], str] | None = ...,
- pctdistance: float = ...,
- shadow: bool = ...,
- labeldistance: float | None = ...,
- startangle: float = ...,
- radius: float = ...,
- counterclock: bool = ...,
- wedgeprops: dict[str, Any] | None = ...,
- textprops: dict[str, Any] | None = ...,
- center: tuple[float, float] = ...,
- frame: bool = ...,
- rotatelabels: bool = ...,
- *,
- normalize: bool = ...,
- hatch: str | Sequence[str] | None = ...,
- data=...,
- ) -> tuple[list[Wedge], list[Text]] | tuple[
- list[Wedge], list[Text], list[Text]
- ]: ...
- def errorbar(
- self,
- x: float | ArrayLike,
- y: float | ArrayLike,
- yerr: float | ArrayLike | None = ...,
- xerr: float | ArrayLike | None = ...,
- fmt: str = ...,
- ecolor: ColorType | None = ...,
- elinewidth: float | None = ...,
- capsize: float | None = ...,
- barsabove: bool = ...,
- lolims: bool | ArrayLike = ...,
- uplims: bool | ArrayLike = ...,
- xlolims: bool | ArrayLike = ...,
- xuplims: bool | ArrayLike = ...,
- errorevery: int | tuple[int, int] = ...,
- capthick: float | None = ...,
- *,
- data=...,
- **kwargs
- ) -> ErrorbarContainer: ...
- def boxplot(
- self,
- x: ArrayLike | Sequence[ArrayLike],
- notch: bool | None = ...,
- sym: str | None = ...,
- vert: bool | None = ...,
- whis: float | tuple[float, float] | None = ...,
- positions: ArrayLike | None = ...,
- widths: float | ArrayLike | None = ...,
- patch_artist: bool | None = ...,
- bootstrap: int | None = ...,
- usermedians: ArrayLike | None = ...,
- conf_intervals: ArrayLike | None = ...,
- meanline: bool | None = ...,
- showmeans: bool | None = ...,
- showcaps: bool | None = ...,
- showbox: bool | None = ...,
- showfliers: bool | None = ...,
- boxprops: dict[str, Any] | None = ...,
- labels: Sequence[str] | None = ...,
- flierprops: dict[str, Any] | None = ...,
- medianprops: dict[str, Any] | None = ...,
- meanprops: dict[str, Any] | None = ...,
- capprops: dict[str, Any] | None = ...,
- whiskerprops: dict[str, Any] | None = ...,
- manage_ticks: bool = ...,
- autorange: bool = ...,
- zorder: float | None = ...,
- capwidths: float | ArrayLike | None = ...,
- *,
- data=...,
- ) -> dict[str, Any]: ...
- def bxp(
- self,
- bxpstats: Sequence[dict[str, Any]],
- positions: ArrayLike | None = ...,
- widths: float | ArrayLike | None = ...,
- vert: bool = ...,
- patch_artist: bool = ...,
- shownotches: bool = ...,
- showmeans: bool = ...,
- showcaps: bool = ...,
- showbox: bool = ...,
- showfliers: bool = ...,
- boxprops: dict[str, Any] | None = ...,
- whiskerprops: dict[str, Any] | None = ...,
- flierprops: dict[str, Any] | None = ...,
- medianprops: dict[str, Any] | None = ...,
- capprops: dict[str, Any] | None = ...,
- meanprops: dict[str, Any] | None = ...,
- meanline: bool = ...,
- manage_ticks: bool = ...,
- zorder: float | None = ...,
- capwidths: float | ArrayLike | None = ...,
- ) -> dict[str, Any]: ...
- def scatter(
- self,
- x: float | ArrayLike,
- y: float | ArrayLike,
- s: float | ArrayLike | None = ...,
- c: ArrayLike | Sequence[ColorType] | ColorType | None = ...,
- marker: MarkerType | None = ...,
- cmap: str | Colormap | None = ...,
- norm: str | Normalize | None = ...,
- vmin: float | None = ...,
- vmax: float | None = ...,
- alpha: float | None = ...,
- linewidths: float | Sequence[float] | None = ...,
- *,
- edgecolors: Literal["face", "none"] | ColorType | Sequence[ColorType] | None = ...,
- plotnonfinite: bool = ...,
- data=...,
- **kwargs
- ) -> PathCollection: ...
- def hexbin(
- self,
- x: ArrayLike,
- y: ArrayLike,
- C: ArrayLike | None = ...,
- gridsize: int | tuple[int, int] = ...,
- bins: Literal["log"] | int | Sequence[float] | None = ...,
- xscale: Literal["linear", "log"] = ...,
- yscale: Literal["linear", "log"] = ...,
- extent: tuple[float, float, float, float] | None = ...,
- cmap: str | Colormap | None = ...,
- norm: str | Normalize | None = ...,
- vmin: float | None = ...,
- vmax: float | None = ...,
- alpha: float | None = ...,
- linewidths: float | None = ...,
- edgecolors: Literal["face", "none"] | ColorType = ...,
- reduce_C_function: Callable[[np.ndarray | list[float]], float] = ...,
- mincnt: int | None = ...,
- marginals: bool = ...,
- *,
- data=...,
- **kwargs
- ) -> PolyCollection: ...
- def arrow(
- self, x: float, y: float, dx: float, dy: float, **kwargs
- ) -> FancyArrow: ...
- def quiverkey(
- self, Q: Quiver, X: float, Y: float, U: float, label: str, **kwargs
- ) -> QuiverKey: ...
- def quiver(self, *args, data=..., **kwargs) -> Quiver: ...
- def barbs(self, *args, data=..., **kwargs) -> Barbs: ...
- def fill(self, *args, data=..., **kwargs) -> list[Polygon]: ...
- def fill_between(
- self,
- x: ArrayLike,
- y1: ArrayLike | float,
- y2: ArrayLike | float = ...,
- where: Sequence[bool] | None = ...,
- interpolate: bool = ...,
- step: Literal["pre", "post", "mid"] | None = ...,
- *,
- data=...,
- **kwargs
- ) -> PolyCollection: ...
- def fill_betweenx(
- self,
- y: ArrayLike,
- x1: ArrayLike | float,
- x2: ArrayLike | float = ...,
- where: Sequence[bool] | None = ...,
- step: Literal["pre", "post", "mid"] | None = ...,
- interpolate: bool = ...,
- *,
- data=...,
- **kwargs
- ) -> PolyCollection: ...
- def imshow(
- self,
- X: ArrayLike | PIL.Image.Image,
- cmap: str | Colormap | None = ...,
- norm: str | Normalize | None = ...,
- *,
- aspect: Literal["equal", "auto"] | float | None = ...,
- interpolation: str | None = ...,
- alpha: float | ArrayLike | None = ...,
- vmin: float | None = ...,
- vmax: float | None = ...,
- origin: Literal["upper", "lower"] | None = ...,
- extent: tuple[float, float, float, float] | None = ...,
- interpolation_stage: Literal["data", "rgba"] | None = ...,
- filternorm: bool = ...,
- filterrad: float = ...,
- resample: bool | None = ...,
- url: str | None = ...,
- data=...,
- **kwargs
- ) -> AxesImage: ...
- def pcolor(
- self,
- *args: ArrayLike,
- shading: Literal["flat", "nearest", "auto"] | None = ...,
- alpha: float | None = ...,
- norm: str | Normalize | None = ...,
- cmap: str | Colormap | None = ...,
- vmin: float | None = ...,
- vmax: float | None = ...,
- data=...,
- **kwargs
- ) -> Collection: ...
- def pcolormesh(
- self,
- *args: ArrayLike,
- alpha: float | None = ...,
- norm: str | Normalize | None = ...,
- cmap: str | Colormap | None = ...,
- vmin: float | None = ...,
- vmax: float | None = ...,
- shading: Literal["flat", "nearest", "gouraud", "auto"] | None = ...,
- antialiased: bool = ...,
- data=...,
- **kwargs
- ) -> QuadMesh: ...
- def pcolorfast(
- self,
- *args: ArrayLike | tuple[float, float],
- alpha: float | None = ...,
- norm: str | Normalize | None = ...,
- cmap: str | Colormap | None = ...,
- vmin: float | None = ...,
- vmax: float | None = ...,
- data=...,
- **kwargs
- ) -> AxesImage | PcolorImage | QuadMesh: ...
- def contour(self, *args, data=..., **kwargs) -> QuadContourSet: ...
- def contourf(self, *args, data=..., **kwargs) -> QuadContourSet: ...
- def clabel(
- self, CS: ContourSet, levels: ArrayLike | None = ..., **kwargs
- ) -> list[Text]: ...
- def hist(
- self,
- x: ArrayLike | Sequence[ArrayLike],
- bins: int | Sequence[float] | str | None = ...,
- range: tuple[float, float] | None = ...,
- density: bool = ...,
- weights: ArrayLike | None = ...,
- cumulative: bool | float = ...,
- bottom: ArrayLike | float | None = ...,
- histtype: Literal["bar", "barstacked", "step", "stepfilled"] = ...,
- align: Literal["left", "mid", "right"] = ...,
- orientation: Literal["vertical", "horizontal"] = ...,
- rwidth: float | None = ...,
- log: bool = ...,
- color: ColorType | Sequence[ColorType] | None = ...,
- label: str | Sequence[str] | None = ...,
- stacked: bool = ...,
- *,
- data=...,
- **kwargs
- ) -> tuple[
- np.ndarray | list[np.ndarray],
- np.ndarray,
- BarContainer | Polygon | list[BarContainer | Polygon],
- ]: ...
- def stairs(
- self,
- values: ArrayLike,
- edges: ArrayLike | None = ...,
- *,
- orientation: Literal["vertical", "horizontal"] = ...,
- baseline: float | ArrayLike | None = ...,
- fill: bool = ...,
- data=...,
- **kwargs
- ) -> StepPatch: ...
- def hist2d(
- self,
- x: ArrayLike,
- y: ArrayLike,
- bins: None
- | int
- | tuple[int, int]
- | ArrayLike
- | tuple[ArrayLike, ArrayLike] = ...,
- range: ArrayLike | None = ...,
- density: bool = ...,
- weights: ArrayLike | None = ...,
- cmin: float | None = ...,
- cmax: float | None = ...,
- *,
- data=...,
- **kwargs
- ) -> tuple[np.ndarray, np.ndarray, np.ndarray, QuadMesh]: ...
- def ecdf(
- self,
- x: ArrayLike,
- weights: ArrayLike | None = ...,
- *,
- complementary: bool=...,
- orientation: Literal["vertical", "horizonatal"]=...,
- compress: bool=...,
- data=...,
- **kwargs
- ) -> Line2D: ...
- def psd(
- self,
- x: ArrayLike,
- NFFT: int | None = ...,
- Fs: float | None = ...,
- Fc: int | None = ...,
- detrend: Literal["none", "mean", "linear"]
- | Callable[[ArrayLike], ArrayLike]
- | None = ...,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = ...,
- noverlap: int | None = ...,
- pad_to: int | None = ...,
- sides: Literal["default", "onesided", "twosided"] | None = ...,
- scale_by_freq: bool | None = ...,
- return_line: bool | None = ...,
- *,
- data=...,
- **kwargs
- ) -> tuple[np.ndarray, np.ndarray] | tuple[np.ndarray, np.ndarray, Line2D]: ...
- def csd(
- self,
- x: ArrayLike,
- y: ArrayLike,
- NFFT: int | None = ...,
- Fs: float | None = ...,
- Fc: int | None = ...,
- detrend: Literal["none", "mean", "linear"]
- | Callable[[ArrayLike], ArrayLike]
- | None = ...,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = ...,
- noverlap: int | None = ...,
- pad_to: int | None = ...,
- sides: Literal["default", "onesided", "twosided"] | None = ...,
- scale_by_freq: bool | None = ...,
- return_line: bool | None = ...,
- *,
- data=...,
- **kwargs
- ) -> tuple[np.ndarray, np.ndarray] | tuple[np.ndarray, np.ndarray, Line2D]: ...
- def magnitude_spectrum(
- self,
- x: ArrayLike,
- Fs: float | None = ...,
- Fc: int | None = ...,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = ...,
- pad_to: int | None = ...,
- sides: Literal["default", "onesided", "twosided"] | None = ...,
- scale: Literal["default", "linear", "dB"] | None = ...,
- *,
- data=...,
- **kwargs
- ) -> tuple[np.ndarray, np.ndarray, Line2D]: ...
- def angle_spectrum(
- self,
- x: ArrayLike,
- Fs: float | None = ...,
- Fc: int | None = ...,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = ...,
- pad_to: int | None = ...,
- sides: Literal["default", "onesided", "twosided"] | None = ...,
- *,
- data=...,
- **kwargs
- ) -> tuple[np.ndarray, np.ndarray, Line2D]: ...
- def phase_spectrum(
- self,
- x: ArrayLike,
- Fs: float | None = ...,
- Fc: int | None = ...,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = ...,
- pad_to: int | None = ...,
- sides: Literal["default", "onesided", "twosided"] | None = ...,
- *,
- data=...,
- **kwargs
- ) -> tuple[np.ndarray, np.ndarray, Line2D]: ...
- def cohere(
- self,
- x: ArrayLike,
- y: ArrayLike,
- NFFT: int = ...,
- Fs: float = ...,
- Fc: int = ...,
- detrend: Literal["none", "mean", "linear"]
- | Callable[[ArrayLike], ArrayLike] = ...,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike = ...,
- noverlap: int = ...,
- pad_to: int | None = ...,
- sides: Literal["default", "onesided", "twosided"] = ...,
- scale_by_freq: bool | None = ...,
- *,
- data=...,
- **kwargs
- ) -> tuple[np.ndarray, np.ndarray]: ...
- def specgram(
- self,
- x: ArrayLike,
- NFFT: int | None = ...,
- Fs: float | None = ...,
- Fc: int | None = ...,
- detrend: Literal["none", "mean", "linear"]
- | Callable[[ArrayLike], ArrayLike]
- | None = ...,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = ...,
- noverlap: int | None = ...,
- cmap: str | Colormap | None = ...,
- xextent: tuple[float, float] | None = ...,
- pad_to: int | None = ...,
- sides: Literal["default", "onesided", "twosided"] | None = ...,
- scale_by_freq: bool | None = ...,
- mode: Literal["default", "psd", "magnitude", "angle", "phase"] | None = ...,
- scale: Literal["default", "linear", "dB"] | None = ...,
- vmin: float | None = ...,
- vmax: float | None = ...,
- *,
- data=...,
- **kwargs
- ) -> tuple[np.ndarray, np.ndarray, np.ndarray, AxesImage]: ...
- def spy(
- self,
- Z: ArrayLike,
- precision: float | Literal["present"] = ...,
- marker: str | None = ...,
- markersize: float | None = ...,
- aspect: Literal["equal", "auto"] | float | None = ...,
- origin: Literal["upper", "lower"] = ...,
- **kwargs
- ) -> AxesImage: ...
- def matshow(self, Z: ArrayLike, **kwargs) -> AxesImage: ...
- def violinplot(
- self,
- dataset: ArrayLike | Sequence[ArrayLike],
- positions: ArrayLike | None = ...,
- vert: bool = ...,
- widths: float | ArrayLike = ...,
- showmeans: bool = ...,
- showextrema: bool = ...,
- showmedians: bool = ...,
- quantiles: Sequence[float | Sequence[float]] | None = ...,
- points: int = ...,
- bw_method: Literal["scott", "silverman"]
- | float
- | Callable[[GaussianKDE], float]
- | None = ...,
- *,
- data=...,
- ) -> dict[str, Collection]: ...
- def violin(
- self,
- vpstats: Sequence[dict[str, Any]],
- positions: ArrayLike | None = ...,
- vert: bool = ...,
- widths: float | ArrayLike = ...,
- showmeans: bool = ...,
- showextrema: bool = ...,
- showmedians: bool = ...,
- ) -> dict[str, Collection]: ...
-
- table = mtable.table
- stackplot = mstack.stackplot
- streamplot = mstream.streamplot
- tricontour = mtri.tricontour
- tricontourf = mtri.tricontourf
- tripcolor = mtri.tripcolor
- triplot = mtri.triplot
diff --git a/contrib/python/matplotlib/py3/matplotlib/axes/_base.py b/contrib/python/matplotlib/py3/matplotlib/axes/_base.py
deleted file mode 100644
index 68cd5c7b06..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/axes/_base.py
+++ /dev/null
@@ -1,4644 +0,0 @@
-from collections.abc import Iterable, Sequence
-from contextlib import ExitStack
-import functools
-import inspect
-import logging
-from numbers import Real
-from operator import attrgetter
-import types
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, cbook, _docstring, offsetbox
-import matplotlib.artist as martist
-import matplotlib.axis as maxis
-from matplotlib.cbook import _OrderedSet, _check_1d, index_of
-import matplotlib.collections as mcoll
-import matplotlib.colors as mcolors
-import matplotlib.font_manager as font_manager
-from matplotlib.gridspec import SubplotSpec
-import matplotlib.image as mimage
-import matplotlib.lines as mlines
-import matplotlib.patches as mpatches
-from matplotlib.rcsetup import cycler, validate_axisbelow
-import matplotlib.spines as mspines
-import matplotlib.table as mtable
-import matplotlib.text as mtext
-import matplotlib.ticker as mticker
-import matplotlib.transforms as mtransforms
-
-_log = logging.getLogger(__name__)
-
-
-class _axis_method_wrapper:
- """
- Helper to generate Axes methods wrapping Axis methods.
-
- After ::
-
- get_foo = _axis_method_wrapper("xaxis", "get_bar")
-
- (in the body of a class) ``get_foo`` is a method that forwards it arguments
- to the ``get_bar`` method of the ``xaxis`` attribute, and gets its
- signature and docstring from ``Axis.get_bar``.
-
- The docstring of ``get_foo`` is built by replacing "this Axis" by "the
- {attr_name}" (i.e., "the xaxis", "the yaxis") in the wrapped method's
- dedented docstring; additional replacements can be given in *doc_sub*.
- """
-
- def __init__(self, attr_name, method_name, *, doc_sub=None):
- self.attr_name = attr_name
- self.method_name = method_name
- # Immediately put the docstring in ``self.__doc__`` so that docstring
- # manipulations within the class body work as expected.
- doc = inspect.getdoc(getattr(maxis.Axis, method_name))
- self._missing_subs = []
- if doc:
- doc_sub = {"this Axis": f"the {self.attr_name}", **(doc_sub or {})}
- for k, v in doc_sub.items():
- if k not in doc: # Delay raising error until we know qualname.
- self._missing_subs.append(k)
- doc = doc.replace(k, v)
- self.__doc__ = doc
-
- def __set_name__(self, owner, name):
- # This is called at the end of the class body as
- # ``self.__set_name__(cls, name_under_which_self_is_assigned)``; we
- # rely on that to give the wrapper the correct __name__/__qualname__.
- get_method = attrgetter(f"{self.attr_name}.{self.method_name}")
-
- def wrapper(self, *args, **kwargs):
- return get_method(self)(*args, **kwargs)
-
- wrapper.__module__ = owner.__module__
- wrapper.__name__ = name
- wrapper.__qualname__ = f"{owner.__qualname__}.{name}"
- wrapper.__doc__ = self.__doc__
- # Manually copy the signature instead of using functools.wraps because
- # displaying the Axis method source when asking for the Axes method
- # source would be confusing.
- wrapper.__signature__ = inspect.signature(
- getattr(maxis.Axis, self.method_name))
-
- if self._missing_subs:
- raise ValueError(
- "The definition of {} expected that the docstring of Axis.{} "
- "contains {!r} as substrings".format(
- wrapper.__qualname__, self.method_name,
- ", ".join(map(repr, self._missing_subs))))
-
- setattr(owner, name, wrapper)
-
-
-class _TransformedBoundsLocator:
- """
- Axes locator for `.Axes.inset_axes` and similarly positioned Axes.
-
- The locator is a callable object used in `.Axes.set_aspect` to compute the
- Axes location depending on the renderer.
- """
-
- def __init__(self, bounds, transform):
- """
- *bounds* (a ``[l, b, w, h]`` rectangle) and *transform* together
- specify the position of the inset Axes.
- """
- self._bounds = bounds
- self._transform = transform
-
- def __call__(self, ax, renderer):
- # Subtracting transSubfigure will typically rely on inverted(),
- # freezing the transform; thus, this needs to be delayed until draw
- # time as transSubfigure may otherwise change after this is evaluated.
- return mtransforms.TransformedBbox(
- mtransforms.Bbox.from_bounds(*self._bounds),
- self._transform - ax.figure.transSubfigure)
-
-
-def _process_plot_format(fmt, *, ambiguous_fmt_datakey=False):
- """
- Convert a MATLAB style color/line style format string to a (*linestyle*,
- *marker*, *color*) tuple.
-
- Example format strings include:
-
- * 'ko': black circles
- * '.b': blue dots
- * 'r--': red dashed lines
- * 'C2--': the third color in the color cycle, dashed lines
-
- The format is absolute in the sense that if a linestyle or marker is not
- defined in *fmt*, there is no line or marker. This is expressed by
- returning 'None' for the respective quantity.
-
- See Also
- --------
- matplotlib.Line2D.lineStyles, matplotlib.colors.cnames
- All possible styles and color format strings.
- """
-
- linestyle = None
- marker = None
- color = None
-
- # Is fmt just a colorspec?
- try:
- color = mcolors.to_rgba(fmt)
-
- # We need to differentiate grayscale '1.0' from tri_down marker '1'
- try:
- fmtint = str(int(fmt))
- except ValueError:
- return linestyle, marker, color # Yes
- else:
- if fmt != fmtint:
- # user definitely doesn't want tri_down marker
- return linestyle, marker, color # Yes
- else:
- # ignore converted color
- color = None
- except ValueError:
- pass # No, not just a color.
-
- errfmt = ("{!r} is neither a data key nor a valid format string ({})"
- if ambiguous_fmt_datakey else
- "{!r} is not a valid format string ({})")
-
- i = 0
- while i < len(fmt):
- c = fmt[i]
- if fmt[i:i+2] in mlines.lineStyles: # First, the two-char styles.
- if linestyle is not None:
- raise ValueError(errfmt.format(fmt, "two linestyle symbols"))
- linestyle = fmt[i:i+2]
- i += 2
- elif c in mlines.lineStyles:
- if linestyle is not None:
- raise ValueError(errfmt.format(fmt, "two linestyle symbols"))
- linestyle = c
- i += 1
- elif c in mlines.lineMarkers:
- if marker is not None:
- raise ValueError(errfmt.format(fmt, "two marker symbols"))
- marker = c
- i += 1
- elif c in mcolors.get_named_colors_mapping():
- if color is not None:
- raise ValueError(errfmt.format(fmt, "two color symbols"))
- color = c
- i += 1
- elif c == 'C' and i < len(fmt) - 1:
- color_cycle_number = int(fmt[i + 1])
- color = mcolors.to_rgba(f"C{color_cycle_number}")
- i += 2
- else:
- raise ValueError(
- errfmt.format(fmt, f"unrecognized character {c!r}"))
-
- if linestyle is None and marker is None:
- linestyle = mpl.rcParams['lines.linestyle']
- if linestyle is None:
- linestyle = 'None'
- if marker is None:
- marker = 'None'
-
- return linestyle, marker, color
-
-
-class _process_plot_var_args:
- """
- Process variable length arguments to `~.Axes.plot`, to support ::
-
- plot(t, s)
- plot(t1, s1, t2, s2)
- plot(t1, s1, 'ko', t2, s2)
- plot(t1, s1, 'ko', t2, s2, 'r--', t3, e3)
-
- an arbitrary number of *x*, *y*, *fmt* are allowed
- """
-
- def __init__(self, command='plot'):
- self.command = command
- self.set_prop_cycle(None)
-
- def set_prop_cycle(self, cycler):
- if cycler is None:
- cycler = mpl.rcParams['axes.prop_cycle']
- self._idx = 0
- self._cycler_items = [*cycler]
- self._prop_keys = cycler.keys # This should make a copy
-
- def __call__(self, axes, *args, data=None, **kwargs):
- axes._process_unit_info(kwargs=kwargs)
-
- for pos_only in "xy":
- if pos_only in kwargs:
- raise _api.kwarg_error(self.command, pos_only)
-
- if not args:
- return
-
- if data is None: # Process dict views
- args = [cbook.sanitize_sequence(a) for a in args]
- else: # Process the 'data' kwarg.
- replaced = [mpl._replacer(data, arg) for arg in args]
- if len(args) == 1:
- label_namer_idx = 0
- elif len(args) == 2: # Can be x, y or y, c.
- # Figure out what the second argument is.
- # 1) If the second argument cannot be a format shorthand, the
- # second argument is the label_namer.
- # 2) Otherwise (it could have been a format shorthand),
- # a) if we did perform a substitution, emit a warning, and
- # use it as label_namer.
- # b) otherwise, it is indeed a format shorthand; use the
- # first argument as label_namer.
- try:
- _process_plot_format(args[1])
- except ValueError: # case 1)
- label_namer_idx = 1
- else:
- if replaced[1] is not args[1]: # case 2a)
- _api.warn_external(
- f"Second argument {args[1]!r} is ambiguous: could "
- f"be a format string but is in 'data'; using as "
- f"data. If it was intended as data, set the "
- f"format string to an empty string to suppress "
- f"this warning. If it was intended as a format "
- f"string, explicitly pass the x-values as well. "
- f"Alternatively, rename the entry in 'data'.",
- RuntimeWarning)
- label_namer_idx = 1
- else: # case 2b)
- label_namer_idx = 0
- elif len(args) == 3:
- label_namer_idx = 1
- else:
- raise ValueError(
- "Using arbitrary long args with data is not supported due "
- "to ambiguity of arguments; use multiple plotting calls "
- "instead")
- if kwargs.get("label") is None:
- kwargs["label"] = mpl._label_from_arg(
- replaced[label_namer_idx], args[label_namer_idx])
- args = replaced
- ambiguous_fmt_datakey = data is not None and len(args) == 2
-
- if len(args) >= 4 and not cbook.is_scalar_or_string(
- kwargs.get("label")):
- raise ValueError("plot() with multiple groups of data (i.e., "
- "pairs of x and y) does not support multiple "
- "labels")
-
- # Repeatedly grab (x, y) or (x, y, format) from the front of args and
- # massage them into arguments to plot() or fill().
-
- while args:
- this, args = args[:2], args[2:]
- if args and isinstance(args[0], str):
- this += args[0],
- args = args[1:]
- yield from self._plot_args(
- axes, this, kwargs, ambiguous_fmt_datakey=ambiguous_fmt_datakey)
-
- def get_next_color(self):
- """Return the next color in the cycle."""
- if 'color' not in self._prop_keys:
- return 'k'
- c = self._cycler_items[self._idx]['color']
- self._idx = (self._idx + 1) % len(self._cycler_items)
- return c
-
- def _getdefaults(self, ignore, kw):
- """
- If some keys in the property cycle (excluding those in the set
- *ignore*) are absent or set to None in the dict *kw*, return a copy
- of the next entry in the property cycle, excluding keys in *ignore*.
- Otherwise, don't advance the property cycle, and return an empty dict.
- """
- prop_keys = self._prop_keys - ignore
- if any(kw.get(k, None) is None for k in prop_keys):
- # Need to copy this dictionary or else the next time around
- # in the cycle, the dictionary could be missing entries.
- default_dict = self._cycler_items[self._idx].copy()
- self._idx = (self._idx + 1) % len(self._cycler_items)
- for p in ignore:
- default_dict.pop(p, None)
- else:
- default_dict = {}
- return default_dict
-
- def _setdefaults(self, defaults, kw):
- """
- Add to the dict *kw* the entries in the dict *default* that are absent
- or set to None in *kw*.
- """
- for k in defaults:
- if kw.get(k, None) is None:
- kw[k] = defaults[k]
-
- def _makeline(self, axes, x, y, kw, kwargs):
- kw = {**kw, **kwargs} # Don't modify the original kw.
- default_dict = self._getdefaults(set(), kw)
- self._setdefaults(default_dict, kw)
- seg = mlines.Line2D(x, y, **kw)
- return seg, kw
-
- def _makefill(self, axes, x, y, kw, kwargs):
- # Polygon doesn't directly support unitized inputs.
- x = axes.convert_xunits(x)
- y = axes.convert_yunits(y)
-
- kw = kw.copy() # Don't modify the original kw.
- kwargs = kwargs.copy()
-
- # Ignore 'marker'-related properties as they aren't Polygon
- # properties, but they are Line2D properties, and so they are
- # likely to appear in the default cycler construction.
- # This is done here to the defaults dictionary as opposed to the
- # other two dictionaries because we do want to capture when a
- # *user* explicitly specifies a marker which should be an error.
- # We also want to prevent advancing the cycler if there are no
- # defaults needed after ignoring the given properties.
- ignores = {'marker', 'markersize', 'markeredgecolor',
- 'markerfacecolor', 'markeredgewidth'}
- # Also ignore anything provided by *kwargs*.
- for k, v in kwargs.items():
- if v is not None:
- ignores.add(k)
-
- # Only using the first dictionary to use as basis
- # for getting defaults for back-compat reasons.
- # Doing it with both seems to mess things up in
- # various places (probably due to logic bugs elsewhere).
- default_dict = self._getdefaults(ignores, kw)
- self._setdefaults(default_dict, kw)
-
- # Looks like we don't want "color" to be interpreted to
- # mean both facecolor and edgecolor for some reason.
- # So the "kw" dictionary is thrown out, and only its
- # 'color' value is kept and translated as a 'facecolor'.
- # This design should probably be revisited as it increases
- # complexity.
- facecolor = kw.get('color', None)
-
- # Throw out 'color' as it is now handled as a facecolor
- default_dict.pop('color', None)
-
- # To get other properties set from the cycler
- # modify the kwargs dictionary.
- self._setdefaults(default_dict, kwargs)
-
- seg = mpatches.Polygon(np.column_stack((x, y)),
- facecolor=facecolor,
- fill=kwargs.get('fill', True),
- closed=kw['closed'])
- seg.set(**kwargs)
- return seg, kwargs
-
- def _plot_args(self, axes, tup, kwargs, *,
- return_kwargs=False, ambiguous_fmt_datakey=False):
- """
- Process the arguments of ``plot([x], y, [fmt], **kwargs)`` calls.
-
- This processes a single set of ([x], y, [fmt]) parameters; i.e. for
- ``plot(x, y, x2, y2)`` it will be called twice. Once for (x, y) and
- once for (x2, y2).
-
- x and y may be 2D and thus can still represent multiple datasets.
-
- For multiple datasets, if the keyword argument *label* is a list, this
- will unpack the list and assign the individual labels to the datasets.
-
- Parameters
- ----------
- tup : tuple
- A tuple of the positional parameters. This can be one of
-
- - (y,)
- - (x, y)
- - (y, fmt)
- - (x, y, fmt)
-
- kwargs : dict
- The keyword arguments passed to ``plot()``.
-
- return_kwargs : bool
- Whether to also return the effective keyword arguments after label
- unpacking as well.
-
- ambiguous_fmt_datakey : bool
- Whether the format string in *tup* could also have been a
- misspelled data key.
-
- Returns
- -------
- result
- If *return_kwargs* is false, a list of Artists representing the
- dataset(s).
- If *return_kwargs* is true, a list of (Artist, effective_kwargs)
- representing the dataset(s). See *return_kwargs*.
- The Artist is either `.Line2D` (if called from ``plot()``) or
- `.Polygon` otherwise.
- """
- if len(tup) > 1 and isinstance(tup[-1], str):
- # xy is tup with fmt stripped (could still be (y,) only)
- *xy, fmt = tup
- linestyle, marker, color = _process_plot_format(
- fmt, ambiguous_fmt_datakey=ambiguous_fmt_datakey)
- elif len(tup) == 3:
- raise ValueError('third arg must be a format string')
- else:
- xy = tup
- linestyle, marker, color = None, None, None
-
- # Don't allow any None value; these would be up-converted to one
- # element array of None which causes problems downstream.
- if any(v is None for v in tup):
- raise ValueError("x, y, and format string must not be None")
-
- kw = {}
- for prop_name, val in zip(('linestyle', 'marker', 'color'),
- (linestyle, marker, color)):
- if val is not None:
- # check for conflicts between fmt and kwargs
- if (fmt.lower() != 'none'
- and prop_name in kwargs
- and val != 'None'):
- # Technically ``plot(x, y, 'o', ls='--')`` is a conflict
- # because 'o' implicitly unsets the linestyle
- # (linestyle='None').
- # We'll gracefully not warn in this case because an
- # explicit set via kwargs can be seen as intention to
- # override an implicit unset.
- # Note: We don't val.lower() != 'none' because val is not
- # necessarily a string (can be a tuple for colors). This
- # is safe, because *val* comes from _process_plot_format()
- # which only returns 'None'.
- _api.warn_external(
- f"{prop_name} is redundantly defined by the "
- f"'{prop_name}' keyword argument and the fmt string "
- f'"{fmt}" (-> {prop_name}={val!r}). The keyword '
- f"argument will take precedence.")
- kw[prop_name] = val
-
- if len(xy) == 2:
- x = _check_1d(xy[0])
- y = _check_1d(xy[1])
- else:
- x, y = index_of(xy[-1])
-
- if axes.xaxis is not None:
- axes.xaxis.update_units(x)
- if axes.yaxis is not None:
- axes.yaxis.update_units(y)
-
- if x.shape[0] != y.shape[0]:
- raise ValueError(f"x and y must have same first dimension, but "
- f"have shapes {x.shape} and {y.shape}")
- if x.ndim > 2 or y.ndim > 2:
- raise ValueError(f"x and y can be no greater than 2D, but have "
- f"shapes {x.shape} and {y.shape}")
- if x.ndim == 1:
- x = x[:, np.newaxis]
- if y.ndim == 1:
- y = y[:, np.newaxis]
-
- if self.command == 'plot':
- make_artist = self._makeline
- else:
- kw['closed'] = kwargs.get('closed', True)
- make_artist = self._makefill
-
- ncx, ncy = x.shape[1], y.shape[1]
- if ncx > 1 and ncy > 1 and ncx != ncy:
- raise ValueError(f"x has {ncx} columns but y has {ncy} columns")
- if ncx == 0 or ncy == 0:
- return []
-
- label = kwargs.get('label')
- n_datasets = max(ncx, ncy)
- if n_datasets > 1 and not cbook.is_scalar_or_string(label):
- if len(label) != n_datasets:
- raise ValueError(f"label must be scalar or have the same "
- f"length as the input data, but found "
- f"{len(label)} for {n_datasets} datasets.")
- labels = label
- else:
- labels = [label] * n_datasets
-
- result = (make_artist(axes, x[:, j % ncx], y[:, j % ncy], kw,
- {**kwargs, 'label': label})
- for j, label in enumerate(labels))
-
- if return_kwargs:
- return list(result)
- else:
- return [l[0] for l in result]
-
-
-@_api.define_aliases({"facecolor": ["fc"]})
-class _AxesBase(martist.Artist):
- name = "rectilinear"
-
- # axis names are the prefixes for the attributes that contain the
- # respective axis; e.g. 'x' <-> self.xaxis, containing an XAxis.
- # Note that PolarAxes uses these attributes as well, so that we have
- # 'x' <-> self.xaxis, containing a ThetaAxis. In particular we do not
- # have 'theta' in _axis_names.
- # In practice, this is ('x', 'y') for all 2D Axes and ('x', 'y', 'z')
- # for Axes3D.
- _axis_names = ("x", "y")
- _shared_axes = {name: cbook.Grouper() for name in _axis_names}
- _twinned_axes = cbook.Grouper()
-
- _subclass_uses_cla = False
-
- @property
- def _axis_map(self):
- """A mapping of axis names, e.g. 'x', to `Axis` instances."""
- return {name: getattr(self, f"{name}axis")
- for name in self._axis_names}
-
- def __str__(self):
- return "{0}({1[0]:g},{1[1]:g};{1[2]:g}x{1[3]:g})".format(
- type(self).__name__, self._position.bounds)
-
- def __init__(self, fig,
- *args,
- facecolor=None, # defaults to rc axes.facecolor
- frameon=True,
- sharex=None, # use Axes instance's xaxis info
- sharey=None, # use Axes instance's yaxis info
- label='',
- xscale=None,
- yscale=None,
- box_aspect=None,
- **kwargs
- ):
- """
- Build an Axes in a figure.
-
- Parameters
- ----------
- fig : `~matplotlib.figure.Figure`
- The Axes is built in the `.Figure` *fig*.
-
- *args
- ``*args`` can be a single ``(left, bottom, width, height)``
- rectangle or a single `.Bbox`. This specifies the rectangle (in
- figure coordinates) where the Axes is positioned.
-
- ``*args`` can also consist of three numbers or a single three-digit
- number; in the latter case, the digits are considered as
- independent numbers. The numbers are interpreted as ``(nrows,
- ncols, index)``: ``(nrows, ncols)`` specifies the size of an array
- of subplots, and ``index`` is the 1-based index of the subplot
- being created. Finally, ``*args`` can also directly be a
- `.SubplotSpec` instance.
-
- sharex, sharey : `~matplotlib.axes.Axes`, optional
- The x- or y-`~.matplotlib.axis` is shared with the x- or y-axis in
- the input `~.axes.Axes`.
-
- frameon : bool, default: True
- Whether the Axes frame is visible.
-
- box_aspect : float, optional
- Set a fixed aspect for the Axes box, i.e. the ratio of height to
- width. See `~.axes.Axes.set_box_aspect` for details.
-
- **kwargs
- Other optional keyword arguments:
-
- %(Axes:kwdoc)s
-
- Returns
- -------
- `~.axes.Axes`
- The new `~.axes.Axes` object.
- """
-
- super().__init__()
- if "rect" in kwargs:
- if args:
- raise TypeError(
- "'rect' cannot be used together with positional arguments")
- rect = kwargs.pop("rect")
- _api.check_isinstance((mtransforms.Bbox, Iterable), rect=rect)
- args = (rect,)
- subplotspec = None
- if len(args) == 1 and isinstance(args[0], mtransforms.Bbox):
- self._position = args[0]
- elif len(args) == 1 and np.iterable(args[0]):
- self._position = mtransforms.Bbox.from_bounds(*args[0])
- else:
- self._position = self._originalPosition = mtransforms.Bbox.unit()
- subplotspec = SubplotSpec._from_subplot_args(fig, args)
- if self._position.width < 0 or self._position.height < 0:
- raise ValueError('Width and height specified must be non-negative')
- self._originalPosition = self._position.frozen()
- self.axes = self
- self._aspect = 'auto'
- self._adjustable = 'box'
- self._anchor = 'C'
- self._stale_viewlims = {name: False for name in self._axis_names}
- self._sharex = sharex
- self._sharey = sharey
- self.set_label(label)
- self.set_figure(fig)
- # The subplotspec needs to be set after the figure (so that
- # figure-level subplotpars are taken into account), but the figure
- # needs to be set after self._position is initialized.
- if subplotspec:
- self.set_subplotspec(subplotspec)
- else:
- self._subplotspec = None
- self.set_box_aspect(box_aspect)
- self._axes_locator = None # Optionally set via update(kwargs).
-
- self._children = []
-
- # placeholder for any colorbars added that use this Axes.
- # (see colorbar.py):
- self._colorbars = []
- self.spines = mspines.Spines.from_dict(self._gen_axes_spines())
-
- # this call may differ for non-sep axes, e.g., polar
- self._init_axis()
- if facecolor is None:
- facecolor = mpl.rcParams['axes.facecolor']
- self._facecolor = facecolor
- self._frameon = frameon
- self.set_axisbelow(mpl.rcParams['axes.axisbelow'])
-
- self._rasterization_zorder = None
- self.clear()
-
- # funcs used to format x and y - fall back on major formatters
- self.fmt_xdata = None
- self.fmt_ydata = None
-
- self.set_navigate(True)
- self.set_navigate_mode(None)
-
- if xscale:
- self.set_xscale(xscale)
- if yscale:
- self.set_yscale(yscale)
-
- self._internal_update(kwargs)
-
- for name, axis in self._axis_map.items():
- axis.callbacks._connect_picklable(
- 'units', self._unit_change_handler(name))
-
- rcParams = mpl.rcParams
- self.tick_params(
- top=rcParams['xtick.top'] and rcParams['xtick.minor.top'],
- bottom=rcParams['xtick.bottom'] and rcParams['xtick.minor.bottom'],
- labeltop=(rcParams['xtick.labeltop'] and
- rcParams['xtick.minor.top']),
- labelbottom=(rcParams['xtick.labelbottom'] and
- rcParams['xtick.minor.bottom']),
- left=rcParams['ytick.left'] and rcParams['ytick.minor.left'],
- right=rcParams['ytick.right'] and rcParams['ytick.minor.right'],
- labelleft=(rcParams['ytick.labelleft'] and
- rcParams['ytick.minor.left']),
- labelright=(rcParams['ytick.labelright'] and
- rcParams['ytick.minor.right']),
- which='minor')
-
- self.tick_params(
- top=rcParams['xtick.top'] and rcParams['xtick.major.top'],
- bottom=rcParams['xtick.bottom'] and rcParams['xtick.major.bottom'],
- labeltop=(rcParams['xtick.labeltop'] and
- rcParams['xtick.major.top']),
- labelbottom=(rcParams['xtick.labelbottom'] and
- rcParams['xtick.major.bottom']),
- left=rcParams['ytick.left'] and rcParams['ytick.major.left'],
- right=rcParams['ytick.right'] and rcParams['ytick.major.right'],
- labelleft=(rcParams['ytick.labelleft'] and
- rcParams['ytick.major.left']),
- labelright=(rcParams['ytick.labelright'] and
- rcParams['ytick.major.right']),
- which='major')
-
- def __init_subclass__(cls, **kwargs):
- parent_uses_cla = super(cls, cls)._subclass_uses_cla
- if 'cla' in cls.__dict__:
- _api.warn_deprecated(
- '3.6',
- pending=True,
- message=f'Overriding `Axes.cla` in {cls.__qualname__} is '
- 'pending deprecation in %(since)s and will be fully '
- 'deprecated in favor of `Axes.clear` in the future. '
- 'Please report '
- f'this to the {cls.__module__!r} author.')
- cls._subclass_uses_cla = 'cla' in cls.__dict__ or parent_uses_cla
- super().__init_subclass__(**kwargs)
-
- def __getstate__(self):
- state = super().__getstate__()
- # Prune the sharing & twinning info to only contain the current group.
- state["_shared_axes"] = {
- name: self._shared_axes[name].get_siblings(self)
- for name in self._axis_names if self in self._shared_axes[name]}
- state["_twinned_axes"] = (self._twinned_axes.get_siblings(self)
- if self in self._twinned_axes else None)
- return state
-
- def __setstate__(self, state):
- # Merge the grouping info back into the global groupers.
- shared_axes = state.pop("_shared_axes")
- for name, shared_siblings in shared_axes.items():
- self._shared_axes[name].join(*shared_siblings)
- twinned_siblings = state.pop("_twinned_axes")
- if twinned_siblings:
- self._twinned_axes.join(*twinned_siblings)
- self.__dict__ = state
- self._stale = True
-
- def __repr__(self):
- fields = []
- if self.get_label():
- fields += [f"label={self.get_label()!r}"]
- if hasattr(self, "get_title"):
- titles = {}
- for k in ["left", "center", "right"]:
- title = self.get_title(loc=k)
- if title:
- titles[k] = title
- if titles:
- fields += [f"title={titles}"]
- for name, axis in self._axis_map.items():
- if axis.get_label() and axis.get_label().get_text():
- fields += [f"{name}label={axis.get_label().get_text()!r}"]
- return f"<{self.__class__.__name__}: " + ", ".join(fields) + ">"
-
- def get_subplotspec(self):
- """Return the `.SubplotSpec` associated with the subplot, or None."""
- return self._subplotspec
-
- def set_subplotspec(self, subplotspec):
- """Set the `.SubplotSpec`. associated with the subplot."""
- self._subplotspec = subplotspec
- self._set_position(subplotspec.get_position(self.figure))
-
- def get_gridspec(self):
- """Return the `.GridSpec` associated with the subplot, or None."""
- return self._subplotspec.get_gridspec() if self._subplotspec else None
-
- def get_window_extent(self, renderer=None):
- """
- Return the Axes bounding box in display space.
-
- This bounding box does not include the spines, ticks, ticklabels,
- or other labels. For a bounding box including these elements use
- `~matplotlib.axes.Axes.get_tightbbox`.
-
- See Also
- --------
- matplotlib.axes.Axes.get_tightbbox
- matplotlib.axis.Axis.get_tightbbox
- matplotlib.spines.Spine.get_window_extent
- """
- return self.bbox
-
- def _init_axis(self):
- # This is moved out of __init__ because non-separable axes don't use it
- self.xaxis = maxis.XAxis(self, clear=False)
- self.spines.bottom.register_axis(self.xaxis)
- self.spines.top.register_axis(self.xaxis)
- self.yaxis = maxis.YAxis(self, clear=False)
- self.spines.left.register_axis(self.yaxis)
- self.spines.right.register_axis(self.yaxis)
-
- def set_figure(self, fig):
- # docstring inherited
- super().set_figure(fig)
-
- self.bbox = mtransforms.TransformedBbox(self._position,
- fig.transSubfigure)
- # these will be updated later as data is added
- self.dataLim = mtransforms.Bbox.null()
- self._viewLim = mtransforms.Bbox.unit()
- self.transScale = mtransforms.TransformWrapper(
- mtransforms.IdentityTransform())
-
- self._set_lim_and_transforms()
-
- def _unstale_viewLim(self):
- # We should arrange to store this information once per share-group
- # instead of on every axis.
- need_scale = {
- name: any(ax._stale_viewlims[name]
- for ax in self._shared_axes[name].get_siblings(self))
- for name in self._axis_names}
- if any(need_scale.values()):
- for name in need_scale:
- for ax in self._shared_axes[name].get_siblings(self):
- ax._stale_viewlims[name] = False
- self.autoscale_view(**{f"scale{name}": scale
- for name, scale in need_scale.items()})
-
- @property
- def viewLim(self):
- self._unstale_viewLim()
- return self._viewLim
-
- def _request_autoscale_view(self, axis="all", tight=None):
- """
- Mark a single axis, or all of them, as stale wrt. autoscaling.
-
- No computation is performed until the next autoscaling; thus, separate
- calls to control individual axises incur negligible performance cost.
-
- Parameters
- ----------
- axis : str, default: "all"
- Either an element of ``self._axis_names``, or "all".
- tight : bool or None, default: None
- """
- axis_names = _api.check_getitem(
- {**{k: [k] for k in self._axis_names}, "all": self._axis_names},
- axis=axis)
- for name in axis_names:
- self._stale_viewlims[name] = True
- if tight is not None:
- self._tight = tight
-
- def _set_lim_and_transforms(self):
- """
- Set the *_xaxis_transform*, *_yaxis_transform*, *transScale*,
- *transData*, *transLimits* and *transAxes* transformations.
-
- .. note::
-
- This method is primarily used by rectilinear projections of the
- `~matplotlib.axes.Axes` class, and is meant to be overridden by
- new kinds of projection Axes that need different transformations
- and limits. (See `~matplotlib.projections.polar.PolarAxes` for an
- example.)
- """
- self.transAxes = mtransforms.BboxTransformTo(self.bbox)
-
- # Transforms the x and y axis separately by a scale factor.
- # It is assumed that this part will have non-linear components
- # (e.g., for a log scale).
- self.transScale = mtransforms.TransformWrapper(
- mtransforms.IdentityTransform())
-
- # An affine transformation on the data, generally to limit the
- # range of the axes
- self.transLimits = mtransforms.BboxTransformFrom(
- mtransforms.TransformedBbox(self._viewLim, self.transScale))
-
- # The parentheses are important for efficiency here -- they
- # group the last two (which are usually affines) separately
- # from the first (which, with log-scaling can be non-affine).
- self.transData = self.transScale + (self.transLimits + self.transAxes)
-
- self._xaxis_transform = mtransforms.blended_transform_factory(
- self.transData, self.transAxes)
- self._yaxis_transform = mtransforms.blended_transform_factory(
- self.transAxes, self.transData)
-
- def get_xaxis_transform(self, which='grid'):
- """
- Get the transformation used for drawing x-axis labels, ticks
- and gridlines. The x-direction is in data coordinates and the
- y-direction is in axis coordinates.
-
- .. note::
-
- This transformation is primarily used by the
- `~matplotlib.axis.Axis` class, and is meant to be
- overridden by new kinds of projections that may need to
- place axis elements in different locations.
-
- Parameters
- ----------
- which : {'grid', 'tick1', 'tick2'}
- """
- if which == 'grid':
- return self._xaxis_transform
- elif which == 'tick1':
- # for cartesian projection, this is bottom spine
- return self.spines.bottom.get_spine_transform()
- elif which == 'tick2':
- # for cartesian projection, this is top spine
- return self.spines.top.get_spine_transform()
- else:
- raise ValueError(f'unknown value for which: {which!r}')
-
- def get_xaxis_text1_transform(self, pad_points):
- """
- Returns
- -------
- transform : Transform
- The transform used for drawing x-axis labels, which will add
- *pad_points* of padding (in points) between the axis and the label.
- The x-direction is in data coordinates and the y-direction is in
- axis coordinates
- valign : {'center', 'top', 'bottom', 'baseline', 'center_baseline'}
- The text vertical alignment.
- halign : {'center', 'left', 'right'}
- The text horizontal alignment.
-
- Notes
- -----
- This transformation is primarily used by the `~matplotlib.axis.Axis`
- class, and is meant to be overridden by new kinds of projections that
- may need to place axis elements in different locations.
- """
- labels_align = mpl.rcParams["xtick.alignment"]
- return (self.get_xaxis_transform(which='tick1') +
- mtransforms.ScaledTranslation(0, -1 * pad_points / 72,
- self.figure.dpi_scale_trans),
- "top", labels_align)
-
- def get_xaxis_text2_transform(self, pad_points):
- """
- Returns
- -------
- transform : Transform
- The transform used for drawing secondary x-axis labels, which will
- add *pad_points* of padding (in points) between the axis and the
- label. The x-direction is in data coordinates and the y-direction
- is in axis coordinates
- valign : {'center', 'top', 'bottom', 'baseline', 'center_baseline'}
- The text vertical alignment.
- halign : {'center', 'left', 'right'}
- The text horizontal alignment.
-
- Notes
- -----
- This transformation is primarily used by the `~matplotlib.axis.Axis`
- class, and is meant to be overridden by new kinds of projections that
- may need to place axis elements in different locations.
- """
- labels_align = mpl.rcParams["xtick.alignment"]
- return (self.get_xaxis_transform(which='tick2') +
- mtransforms.ScaledTranslation(0, pad_points / 72,
- self.figure.dpi_scale_trans),
- "bottom", labels_align)
-
- def get_yaxis_transform(self, which='grid'):
- """
- Get the transformation used for drawing y-axis labels, ticks
- and gridlines. The x-direction is in axis coordinates and the
- y-direction is in data coordinates.
-
- .. note::
-
- This transformation is primarily used by the
- `~matplotlib.axis.Axis` class, and is meant to be
- overridden by new kinds of projections that may need to
- place axis elements in different locations.
-
- Parameters
- ----------
- which : {'grid', 'tick1', 'tick2'}
- """
- if which == 'grid':
- return self._yaxis_transform
- elif which == 'tick1':
- # for cartesian projection, this is bottom spine
- return self.spines.left.get_spine_transform()
- elif which == 'tick2':
- # for cartesian projection, this is top spine
- return self.spines.right.get_spine_transform()
- else:
- raise ValueError(f'unknown value for which: {which!r}')
-
- def get_yaxis_text1_transform(self, pad_points):
- """
- Returns
- -------
- transform : Transform
- The transform used for drawing y-axis labels, which will add
- *pad_points* of padding (in points) between the axis and the label.
- The x-direction is in axis coordinates and the y-direction is in
- data coordinates
- valign : {'center', 'top', 'bottom', 'baseline', 'center_baseline'}
- The text vertical alignment.
- halign : {'center', 'left', 'right'}
- The text horizontal alignment.
-
- Notes
- -----
- This transformation is primarily used by the `~matplotlib.axis.Axis`
- class, and is meant to be overridden by new kinds of projections that
- may need to place axis elements in different locations.
- """
- labels_align = mpl.rcParams["ytick.alignment"]
- return (self.get_yaxis_transform(which='tick1') +
- mtransforms.ScaledTranslation(-1 * pad_points / 72, 0,
- self.figure.dpi_scale_trans),
- labels_align, "right")
-
- def get_yaxis_text2_transform(self, pad_points):
- """
- Returns
- -------
- transform : Transform
- The transform used for drawing secondart y-axis labels, which will
- add *pad_points* of padding (in points) between the axis and the
- label. The x-direction is in axis coordinates and the y-direction
- is in data coordinates
- valign : {'center', 'top', 'bottom', 'baseline', 'center_baseline'}
- The text vertical alignment.
- halign : {'center', 'left', 'right'}
- The text horizontal alignment.
-
- Notes
- -----
- This transformation is primarily used by the `~matplotlib.axis.Axis`
- class, and is meant to be overridden by new kinds of projections that
- may need to place axis elements in different locations.
- """
- labels_align = mpl.rcParams["ytick.alignment"]
- return (self.get_yaxis_transform(which='tick2') +
- mtransforms.ScaledTranslation(pad_points / 72, 0,
- self.figure.dpi_scale_trans),
- labels_align, "left")
-
- def _update_transScale(self):
- self.transScale.set(
- mtransforms.blended_transform_factory(
- self.xaxis.get_transform(), self.yaxis.get_transform()))
-
- def get_position(self, original=False):
- """
- Return the position of the Axes within the figure as a `.Bbox`.
-
- Parameters
- ----------
- original : bool
- If ``True``, return the original position. Otherwise, return the
- active position. For an explanation of the positions see
- `.set_position`.
-
- Returns
- -------
- `.Bbox`
-
- """
- if original:
- return self._originalPosition.frozen()
- else:
- locator = self.get_axes_locator()
- if not locator:
- self.apply_aspect()
- return self._position.frozen()
-
- def set_position(self, pos, which='both'):
- """
- Set the Axes position.
-
- Axes have two position attributes. The 'original' position is the
- position allocated for the Axes. The 'active' position is the
- position the Axes is actually drawn at. These positions are usually
- the same unless a fixed aspect is set to the Axes. See
- `.Axes.set_aspect` for details.
-
- Parameters
- ----------
- pos : [left, bottom, width, height] or `~matplotlib.transforms.Bbox`
- The new position of the Axes in `.Figure` coordinates.
-
- which : {'both', 'active', 'original'}, default: 'both'
- Determines which position variables to change.
-
- See Also
- --------
- matplotlib.transforms.Bbox.from_bounds
- matplotlib.transforms.Bbox.from_extents
- """
- self._set_position(pos, which=which)
- # because this is being called externally to the library we
- # don't let it be in the layout.
- self.set_in_layout(False)
-
- def _set_position(self, pos, which='both'):
- """
- Private version of set_position.
-
- Call this internally to get the same functionality of `set_position`,
- but not to take the axis out of the constrained_layout hierarchy.
- """
- if not isinstance(pos, mtransforms.BboxBase):
- pos = mtransforms.Bbox.from_bounds(*pos)
- for ax in self._twinned_axes.get_siblings(self):
- if which in ('both', 'active'):
- ax._position.set(pos)
- if which in ('both', 'original'):
- ax._originalPosition.set(pos)
- self.stale = True
-
- def reset_position(self):
- """
- Reset the active position to the original position.
-
- This undoes changes to the active position (as defined in
- `.set_position`) which may have been performed to satisfy fixed-aspect
- constraints.
- """
- for ax in self._twinned_axes.get_siblings(self):
- pos = ax.get_position(original=True)
- ax.set_position(pos, which='active')
-
- def set_axes_locator(self, locator):
- """
- Set the Axes locator.
-
- Parameters
- ----------
- locator : Callable[[Axes, Renderer], Bbox]
- """
- self._axes_locator = locator
- self.stale = True
-
- def get_axes_locator(self):
- """
- Return the axes_locator.
- """
- return self._axes_locator
-
- def _set_artist_props(self, a):
- """Set the boilerplate props for artists added to Axes."""
- a.set_figure(self.figure)
- if not a.is_transform_set():
- a.set_transform(self.transData)
-
- a.axes = self
- if a.get_mouseover():
- self._mouseover_set.add(a)
-
- def _gen_axes_patch(self):
- """
- Returns
- -------
- Patch
- The patch used to draw the background of the Axes. It is also used
- as the clipping path for any data elements on the Axes.
-
- In the standard Axes, this is a rectangle, but in other projections
- it may not be.
-
- Notes
- -----
- Intended to be overridden by new projection types.
- """
- return mpatches.Rectangle((0.0, 0.0), 1.0, 1.0)
-
- def _gen_axes_spines(self, locations=None, offset=0.0, units='inches'):
- """
- Returns
- -------
- dict
- Mapping of spine names to `.Line2D` or `.Patch` instances that are
- used to draw Axes spines.
-
- In the standard Axes, spines are single line segments, but in other
- projections they may not be.
-
- Notes
- -----
- Intended to be overridden by new projection types.
- """
- return {side: mspines.Spine.linear_spine(self, side)
- for side in ['left', 'right', 'bottom', 'top']}
-
- def sharex(self, other):
- """
- Share the x-axis with *other*.
-
- This is equivalent to passing ``sharex=other`` when constructing the
- Axes, and cannot be used if the x-axis is already being shared with
- another Axes.
- """
- _api.check_isinstance(_AxesBase, other=other)
- if self._sharex is not None and other is not self._sharex:
- raise ValueError("x-axis is already shared")
- self._shared_axes["x"].join(self, other)
- self._sharex = other
- self.xaxis.major = other.xaxis.major # Ticker instances holding
- self.xaxis.minor = other.xaxis.minor # locator and formatter.
- x0, x1 = other.get_xlim()
- self.set_xlim(x0, x1, emit=False, auto=other.get_autoscalex_on())
- self.xaxis._scale = other.xaxis._scale
-
- def sharey(self, other):
- """
- Share the y-axis with *other*.
-
- This is equivalent to passing ``sharey=other`` when constructing the
- Axes, and cannot be used if the y-axis is already being shared with
- another Axes.
- """
- _api.check_isinstance(_AxesBase, other=other)
- if self._sharey is not None and other is not self._sharey:
- raise ValueError("y-axis is already shared")
- self._shared_axes["y"].join(self, other)
- self._sharey = other
- self.yaxis.major = other.yaxis.major # Ticker instances holding
- self.yaxis.minor = other.yaxis.minor # locator and formatter.
- y0, y1 = other.get_ylim()
- self.set_ylim(y0, y1, emit=False, auto=other.get_autoscaley_on())
- self.yaxis._scale = other.yaxis._scale
-
- def __clear(self):
- """Clear the Axes."""
- # The actual implementation of clear() as long as clear() has to be
- # an adapter delegating to the correct implementation.
- # The implementation can move back into clear() when the
- # deprecation on cla() subclassing expires.
-
- # stash the current visibility state
- if hasattr(self, 'patch'):
- patch_visible = self.patch.get_visible()
- else:
- patch_visible = True
-
- xaxis_visible = self.xaxis.get_visible()
- yaxis_visible = self.yaxis.get_visible()
-
- for axis in self._axis_map.values():
- axis.clear() # Also resets the scale to linear.
- for spine in self.spines.values():
- spine._clear() # Use _clear to not clear Axis again
-
- self.ignore_existing_data_limits = True
- self.callbacks = cbook.CallbackRegistry(
- signals=["xlim_changed", "ylim_changed", "zlim_changed"])
-
- # update the minor locator for x and y axis based on rcParams
- if mpl.rcParams['xtick.minor.visible']:
- self.xaxis.set_minor_locator(mticker.AutoMinorLocator())
- if mpl.rcParams['ytick.minor.visible']:
- self.yaxis.set_minor_locator(mticker.AutoMinorLocator())
-
- self._xmargin = mpl.rcParams['axes.xmargin']
- self._ymargin = mpl.rcParams['axes.ymargin']
- self._tight = None
- self._use_sticky_edges = True
-
- self._get_lines = _process_plot_var_args()
- self._get_patches_for_fill = _process_plot_var_args('fill')
-
- self._gridOn = mpl.rcParams['axes.grid']
- old_children, self._children = self._children, []
- for chld in old_children:
- chld.axes = chld.figure = None
- self._mouseover_set = _OrderedSet()
- self.child_axes = []
- self._current_image = None # strictly for pyplot via _sci, _gci
- self._projection_init = None # strictly for pyplot.subplot
- self.legend_ = None
- self.containers = []
-
- self.grid(False) # Disable grid on init to use rcParameter
- self.grid(self._gridOn, which=mpl.rcParams['axes.grid.which'],
- axis=mpl.rcParams['axes.grid.axis'])
- props = font_manager.FontProperties(
- size=mpl.rcParams['axes.titlesize'],
- weight=mpl.rcParams['axes.titleweight'])
-
- y = mpl.rcParams['axes.titley']
- if y is None:
- y = 1.0
- self._autotitlepos = True
- else:
- self._autotitlepos = False
-
- self.title = mtext.Text(
- x=0.5, y=y, text='',
- fontproperties=props,
- verticalalignment='baseline',
- horizontalalignment='center',
- )
- self._left_title = mtext.Text(
- x=0.0, y=y, text='',
- fontproperties=props.copy(),
- verticalalignment='baseline',
- horizontalalignment='left', )
- self._right_title = mtext.Text(
- x=1.0, y=y, text='',
- fontproperties=props.copy(),
- verticalalignment='baseline',
- horizontalalignment='right',
- )
- title_offset_points = mpl.rcParams['axes.titlepad']
- # refactor this out so it can be called in ax.set_title if
- # pad argument used...
- self._set_title_offset_trans(title_offset_points)
-
- for _title in (self.title, self._left_title, self._right_title):
- self._set_artist_props(_title)
-
- # The patch draws the background of the Axes. We want this to be below
- # the other artists. We use the frame to draw the edges so we are
- # setting the edgecolor to None.
- self.patch = self._gen_axes_patch()
- self.patch.set_figure(self.figure)
- self.patch.set_facecolor(self._facecolor)
- self.patch.set_edgecolor('none')
- self.patch.set_linewidth(0)
- self.patch.set_transform(self.transAxes)
-
- self.set_axis_on()
-
- self.xaxis.set_clip_path(self.patch)
- self.yaxis.set_clip_path(self.patch)
-
- if self._sharex is not None:
- self.xaxis.set_visible(xaxis_visible)
- self.patch.set_visible(patch_visible)
- if self._sharey is not None:
- self.yaxis.set_visible(yaxis_visible)
- self.patch.set_visible(patch_visible)
-
- # This comes last, as the call to _set_lim may trigger an autoscale (in
- # case of shared axes), requiring children to be already set up.
- for name, axis in self._axis_map.items():
- share = getattr(self, f"_share{name}")
- if share is not None:
- getattr(self, f"share{name}")(share)
- else:
- # Although the scale was set to linear as part of clear,
- # polar requires that _set_scale is called again
- if self.name == "polar":
- axis._set_scale("linear")
- axis._set_lim(0, 1, auto=True)
- self._update_transScale()
-
- self.stale = True
-
- def clear(self):
- """Clear the Axes."""
- # Act as an alias, or as the superclass implementation depending on the
- # subclass implementation.
- if self._subclass_uses_cla:
- self.cla()
- else:
- self.__clear()
-
- def cla(self):
- """Clear the Axes."""
- # Act as an alias, or as the superclass implementation depending on the
- # subclass implementation.
- if self._subclass_uses_cla:
- self.__clear()
- else:
- self.clear()
-
- class ArtistList(Sequence):
- """
- A sublist of Axes children based on their type.
-
- The type-specific children sublists were made immutable in Matplotlib
- 3.7. In the future these artist lists may be replaced by tuples. Use
- as if this is a tuple already.
- """
- def __init__(self, axes, prop_name,
- valid_types=None, invalid_types=None):
- """
- Parameters
- ----------
- axes : `~matplotlib.axes.Axes`
- The Axes from which this sublist will pull the children
- Artists.
- prop_name : str
- The property name used to access this sublist from the Axes;
- used to generate deprecation warnings.
- valid_types : list of type, optional
- A list of types that determine which children will be returned
- by this sublist. If specified, then the Artists in the sublist
- must be instances of any of these types. If unspecified, then
- any type of Artist is valid (unless limited by
- *invalid_types*.)
- invalid_types : tuple, optional
- A list of types that determine which children will *not* be
- returned by this sublist. If specified, then Artists in the
- sublist will never be an instance of these types. Otherwise, no
- types will be excluded.
- """
- self._axes = axes
- self._prop_name = prop_name
- self._type_check = lambda artist: (
- (not valid_types or isinstance(artist, valid_types)) and
- (not invalid_types or not isinstance(artist, invalid_types))
- )
-
- def __repr__(self):
- return f'<Axes.ArtistList of {len(self)} {self._prop_name}>'
-
- def __len__(self):
- return sum(self._type_check(artist)
- for artist in self._axes._children)
-
- def __iter__(self):
- for artist in list(self._axes._children):
- if self._type_check(artist):
- yield artist
-
- def __getitem__(self, key):
- return [artist
- for artist in self._axes._children
- if self._type_check(artist)][key]
-
- def __add__(self, other):
- if isinstance(other, (list, _AxesBase.ArtistList)):
- return [*self, *other]
- if isinstance(other, (tuple, _AxesBase.ArtistList)):
- return (*self, *other)
- return NotImplemented
-
- def __radd__(self, other):
- if isinstance(other, list):
- return other + list(self)
- if isinstance(other, tuple):
- return other + tuple(self)
- return NotImplemented
-
- @property
- def artists(self):
- return self.ArtistList(self, 'artists', invalid_types=(
- mcoll.Collection, mimage.AxesImage, mlines.Line2D, mpatches.Patch,
- mtable.Table, mtext.Text))
-
- @property
- def collections(self):
- return self.ArtistList(self, 'collections',
- valid_types=mcoll.Collection)
-
- @property
- def images(self):
- return self.ArtistList(self, 'images', valid_types=mimage.AxesImage)
-
- @property
- def lines(self):
- return self.ArtistList(self, 'lines', valid_types=mlines.Line2D)
-
- @property
- def patches(self):
- return self.ArtistList(self, 'patches', valid_types=mpatches.Patch)
-
- @property
- def tables(self):
- return self.ArtistList(self, 'tables', valid_types=mtable.Table)
-
- @property
- def texts(self):
- return self.ArtistList(self, 'texts', valid_types=mtext.Text)
-
- def get_facecolor(self):
- """Get the facecolor of the Axes."""
- return self.patch.get_facecolor()
-
- def set_facecolor(self, color):
- """
- Set the facecolor of the Axes.
-
- Parameters
- ----------
- color : color
- """
- self._facecolor = color
- self.stale = True
- return self.patch.set_facecolor(color)
-
- def _set_title_offset_trans(self, title_offset_points):
- """
- Set the offset for the title either from :rc:`axes.titlepad`
- or from set_title kwarg ``pad``.
- """
- self.titleOffsetTrans = mtransforms.ScaledTranslation(
- 0.0, title_offset_points / 72,
- self.figure.dpi_scale_trans)
- for _title in (self.title, self._left_title, self._right_title):
- _title.set_transform(self.transAxes + self.titleOffsetTrans)
- _title.set_clip_box(None)
-
- def set_prop_cycle(self, *args, **kwargs):
- """
- Set the property cycle of the Axes.
-
- The property cycle controls the style properties such as color,
- marker and linestyle of future plot commands. The style properties
- of data already added to the Axes are not modified.
-
- Call signatures::
-
- set_prop_cycle(cycler)
- set_prop_cycle(label=values[, label2=values2[, ...]])
- set_prop_cycle(label, values)
-
- Form 1 sets given `~cycler.Cycler` object.
-
- Form 2 creates a `~cycler.Cycler` which cycles over one or more
- properties simultaneously and set it as the property cycle of the
- Axes. If multiple properties are given, their value lists must have
- the same length. This is just a shortcut for explicitly creating a
- cycler and passing it to the function, i.e. it's short for
- ``set_prop_cycle(cycler(label=values label2=values2, ...))``.
-
- Form 3 creates a `~cycler.Cycler` for a single property and set it
- as the property cycle of the Axes. This form exists for compatibility
- with the original `cycler.cycler` interface. Its use is discouraged
- in favor of the kwarg form, i.e. ``set_prop_cycle(label=values)``.
-
- Parameters
- ----------
- cycler : `~cycler.Cycler`
- Set the given Cycler. *None* resets to the cycle defined by the
- current style.
-
- .. ACCEPTS: `~cycler.Cycler`
-
- label : str
- The property key. Must be a valid `.Artist` property.
- For example, 'color' or 'linestyle'. Aliases are allowed,
- such as 'c' for 'color' and 'lw' for 'linewidth'.
-
- values : iterable
- Finite-length iterable of the property values. These values
- are validated and will raise a ValueError if invalid.
-
- See Also
- --------
- matplotlib.rcsetup.cycler
- Convenience function for creating validated cyclers for properties.
- cycler.cycler
- The original function for creating unvalidated cyclers.
-
- Examples
- --------
- Setting the property cycle for a single property:
-
- >>> ax.set_prop_cycle(color=['red', 'green', 'blue'])
-
- Setting the property cycle for simultaneously cycling over multiple
- properties (e.g. red circle, green plus, blue cross):
-
- >>> ax.set_prop_cycle(color=['red', 'green', 'blue'],
- ... marker=['o', '+', 'x'])
-
- """
- if args and kwargs:
- raise TypeError("Cannot supply both positional and keyword "
- "arguments to this method.")
- # Can't do `args == (None,)` as that crashes cycler.
- if len(args) == 1 and args[0] is None:
- prop_cycle = None
- else:
- prop_cycle = cycler(*args, **kwargs)
- self._get_lines.set_prop_cycle(prop_cycle)
- self._get_patches_for_fill.set_prop_cycle(prop_cycle)
-
- def get_aspect(self):
- """
- Return the aspect ratio of the axes scaling.
-
- This is either "auto" or a float giving the ratio of y/x-scale.
- """
- return self._aspect
-
- def set_aspect(self, aspect, adjustable=None, anchor=None, share=False):
- """
- Set the aspect ratio of the axes scaling, i.e. y/x-scale.
-
- Parameters
- ----------
- aspect : {'auto', 'equal'} or float
- Possible values:
-
- - 'auto': fill the position rectangle with data.
- - 'equal': same as ``aspect=1``, i.e. same scaling for x and y.
- - *float*: The displayed size of 1 unit in y-data coordinates will
- be *aspect* times the displayed size of 1 unit in x-data
- coordinates; e.g. for ``aspect=2`` a square in data coordinates
- will be rendered with a height of twice its width.
-
- adjustable : None or {'box', 'datalim'}, optional
- If not ``None``, this defines which parameter will be adjusted to
- meet the required aspect. See `.set_adjustable` for further
- details.
-
- anchor : None or str or (float, float), optional
- If not ``None``, this defines where the Axes will be drawn if there
- is extra space due to aspect constraints. The most common way
- to specify the anchor are abbreviations of cardinal directions:
-
- ===== =====================
- value description
- ===== =====================
- 'C' centered
- 'SW' lower left corner
- 'S' middle of bottom edge
- 'SE' lower right corner
- etc.
- ===== =====================
-
- See `~.Axes.set_anchor` for further details.
-
- share : bool, default: False
- If ``True``, apply the settings to all shared Axes.
-
- See Also
- --------
- matplotlib.axes.Axes.set_adjustable
- Set how the Axes adjusts to achieve the required aspect ratio.
- matplotlib.axes.Axes.set_anchor
- Set the position in case of extra space.
- """
- if cbook._str_equal(aspect, 'equal'):
- aspect = 1
- if not cbook._str_equal(aspect, 'auto'):
- aspect = float(aspect) # raise ValueError if necessary
- if aspect <= 0 or not np.isfinite(aspect):
- raise ValueError("aspect must be finite and positive ")
-
- if share:
- axes = {sibling for name in self._axis_names
- for sibling in self._shared_axes[name].get_siblings(self)}
- else:
- axes = [self]
-
- for ax in axes:
- ax._aspect = aspect
-
- if adjustable is None:
- adjustable = self._adjustable
- self.set_adjustable(adjustable, share=share) # Handle sharing.
-
- if anchor is not None:
- self.set_anchor(anchor, share=share)
- self.stale = True
-
- def get_adjustable(self):
- """
- Return whether the Axes will adjust its physical dimension ('box') or
- its data limits ('datalim') to achieve the desired aspect ratio.
-
- See Also
- --------
- matplotlib.axes.Axes.set_adjustable
- Set how the Axes adjusts to achieve the required aspect ratio.
- matplotlib.axes.Axes.set_aspect
- For a description of aspect handling.
- """
- return self._adjustable
-
- def set_adjustable(self, adjustable, share=False):
- """
- Set how the Axes adjusts to achieve the required aspect ratio.
-
- Parameters
- ----------
- adjustable : {'box', 'datalim'}
- If 'box', change the physical dimensions of the Axes.
- If 'datalim', change the ``x`` or ``y`` data limits.
-
- share : bool, default: False
- If ``True``, apply the settings to all shared Axes.
-
- See Also
- --------
- matplotlib.axes.Axes.set_aspect
- For a description of aspect handling.
-
- Notes
- -----
- Shared Axes (of which twinned Axes are a special case)
- impose restrictions on how aspect ratios can be imposed.
- For twinned Axes, use 'datalim'. For Axes that share both
- x and y, use 'box'. Otherwise, either 'datalim' or 'box'
- may be used. These limitations are partly a requirement
- to avoid over-specification, and partly a result of the
- particular implementation we are currently using, in
- which the adjustments for aspect ratios are done sequentially
- and independently on each Axes as it is drawn.
- """
- _api.check_in_list(["box", "datalim"], adjustable=adjustable)
- if share:
- axs = {sibling for name in self._axis_names
- for sibling in self._shared_axes[name].get_siblings(self)}
- else:
- axs = [self]
- if (adjustable == "datalim"
- and any(getattr(ax.get_data_ratio, "__func__", None)
- != _AxesBase.get_data_ratio
- for ax in axs)):
- # Limits adjustment by apply_aspect assumes that the axes' aspect
- # ratio can be computed from the data limits and scales.
- raise ValueError("Cannot set Axes adjustable to 'datalim' for "
- "Axes which override 'get_data_ratio'")
- for ax in axs:
- ax._adjustable = adjustable
- self.stale = True
-
- def get_box_aspect(self):
- """
- Return the Axes box aspect, i.e. the ratio of height to width.
-
- The box aspect is ``None`` (i.e. chosen depending on the available
- figure space) unless explicitly specified.
-
- See Also
- --------
- matplotlib.axes.Axes.set_box_aspect
- for a description of box aspect.
- matplotlib.axes.Axes.set_aspect
- for a description of aspect handling.
- """
- return self._box_aspect
-
- def set_box_aspect(self, aspect=None):
- """
- Set the Axes box aspect, i.e. the ratio of height to width.
-
- This defines the aspect of the Axes in figure space and is not to be
- confused with the data aspect (see `~.Axes.set_aspect`).
-
- Parameters
- ----------
- aspect : float or None
- Changes the physical dimensions of the Axes, such that the ratio
- of the Axes height to the Axes width in physical units is equal to
- *aspect*. Defining a box aspect will change the *adjustable*
- property to 'datalim' (see `~.Axes.set_adjustable`).
-
- *None* will disable a fixed box aspect so that height and width
- of the Axes are chosen independently.
-
- See Also
- --------
- matplotlib.axes.Axes.set_aspect
- for a description of aspect handling.
- """
- axs = {*self._twinned_axes.get_siblings(self),
- *self._twinned_axes.get_siblings(self)}
-
- if aspect is not None:
- aspect = float(aspect)
- # when box_aspect is set to other than ´None`,
- # adjustable must be "datalim"
- for ax in axs:
- ax.set_adjustable("datalim")
-
- for ax in axs:
- ax._box_aspect = aspect
- ax.stale = True
-
- def get_anchor(self):
- """
- Get the anchor location.
-
- See Also
- --------
- matplotlib.axes.Axes.set_anchor
- for a description of the anchor.
- matplotlib.axes.Axes.set_aspect
- for a description of aspect handling.
- """
- return self._anchor
-
- def set_anchor(self, anchor, share=False):
- """
- Define the anchor location.
-
- The actual drawing area (active position) of the Axes may be smaller
- than the Bbox (original position) when a fixed aspect is required. The
- anchor defines where the drawing area will be located within the
- available space.
-
- Parameters
- ----------
- anchor : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', ...}
- Either an (*x*, *y*) pair of relative coordinates (0 is left or
- bottom, 1 is right or top), 'C' (center), or a cardinal direction
- ('SW', southwest, is bottom left, etc.). str inputs are shorthands
- for (*x*, *y*) coordinates, as shown in the following diagram::
-
- ┌─────────────────┬─────────────────┬─────────────────┐
- │ 'NW' (0.0, 1.0) │ 'N' (0.5, 1.0) │ 'NE' (1.0, 1.0) │
- ├─────────────────┼─────────────────┼─────────────────┤
- │ 'W' (0.0, 0.5) │ 'C' (0.5, 0.5) │ 'E' (1.0, 0.5) │
- ├─────────────────┼─────────────────┼─────────────────┤
- │ 'SW' (0.0, 0.0) │ 'S' (0.5, 0.0) │ 'SE' (1.0, 0.0) │
- └─────────────────┴─────────────────┴─────────────────┘
-
- share : bool, default: False
- If ``True``, apply the settings to all shared Axes.
-
- See Also
- --------
- matplotlib.axes.Axes.set_aspect
- for a description of aspect handling.
- """
- if not (anchor in mtransforms.Bbox.coefs or len(anchor) == 2):
- raise ValueError('argument must be among %s' %
- ', '.join(mtransforms.Bbox.coefs))
- if share:
- axes = {sibling for name in self._axis_names
- for sibling in self._shared_axes[name].get_siblings(self)}
- else:
- axes = [self]
- for ax in axes:
- ax._anchor = anchor
-
- self.stale = True
-
- def get_data_ratio(self):
- """
- Return the aspect ratio of the scaled data.
-
- Notes
- -----
- This method is intended to be overridden by new projection types.
- """
- txmin, txmax = self.xaxis.get_transform().transform(self.get_xbound())
- tymin, tymax = self.yaxis.get_transform().transform(self.get_ybound())
- xsize = max(abs(txmax - txmin), 1e-30)
- ysize = max(abs(tymax - tymin), 1e-30)
- return ysize / xsize
-
- def apply_aspect(self, position=None):
- """
- Adjust the Axes for a specified data aspect ratio.
-
- Depending on `.get_adjustable` this will modify either the
- Axes box (position) or the view limits. In the former case,
- `~matplotlib.axes.Axes.get_anchor` will affect the position.
-
- Parameters
- ----------
- position : None or .Bbox
- If not ``None``, this defines the position of the
- Axes within the figure as a Bbox. See `~.Axes.get_position`
- for further details.
-
- Notes
- -----
- This is called automatically when each Axes is drawn. You may need
- to call it yourself if you need to update the Axes position and/or
- view limits before the Figure is drawn.
-
- See Also
- --------
- matplotlib.axes.Axes.set_aspect
- For a description of aspect ratio handling.
- matplotlib.axes.Axes.set_adjustable
- Set how the Axes adjusts to achieve the required aspect ratio.
- matplotlib.axes.Axes.set_anchor
- Set the position in case of extra space.
- """
- if position is None:
- position = self.get_position(original=True)
-
- aspect = self.get_aspect()
-
- if aspect == 'auto' and self._box_aspect is None:
- self._set_position(position, which='active')
- return
-
- trans = self.get_figure().transSubfigure
- bb = mtransforms.Bbox.unit().transformed(trans)
- # this is the physical aspect of the panel (or figure):
- fig_aspect = bb.height / bb.width
-
- if self._adjustable == 'box':
- if self in self._twinned_axes:
- raise RuntimeError("Adjustable 'box' is not allowed in a "
- "twinned Axes; use 'datalim' instead")
- box_aspect = aspect * self.get_data_ratio()
- pb = position.frozen()
- pb1 = pb.shrunk_to_aspect(box_aspect, pb, fig_aspect)
- self._set_position(pb1.anchored(self.get_anchor(), pb), 'active')
- return
-
- # The following is only seen if self._adjustable == 'datalim'
- if self._box_aspect is not None:
- pb = position.frozen()
- pb1 = pb.shrunk_to_aspect(self._box_aspect, pb, fig_aspect)
- self._set_position(pb1.anchored(self.get_anchor(), pb), 'active')
- if aspect == "auto":
- return
-
- # reset active to original in case it had been changed by prior use
- # of 'box'
- if self._box_aspect is None:
- self._set_position(position, which='active')
- else:
- position = pb1.anchored(self.get_anchor(), pb)
-
- x_trf = self.xaxis.get_transform()
- y_trf = self.yaxis.get_transform()
- xmin, xmax = x_trf.transform(self.get_xbound())
- ymin, ymax = y_trf.transform(self.get_ybound())
- xsize = max(abs(xmax - xmin), 1e-30)
- ysize = max(abs(ymax - ymin), 1e-30)
-
- box_aspect = fig_aspect * (position.height / position.width)
- data_ratio = box_aspect / aspect
-
- y_expander = data_ratio * xsize / ysize - 1
- # If y_expander > 0, the dy/dx viewLim ratio needs to increase
- if abs(y_expander) < 0.005:
- return
-
- dL = self.dataLim
- x0, x1 = x_trf.transform(dL.intervalx)
- y0, y1 = y_trf.transform(dL.intervaly)
- xr = 1.05 * (x1 - x0)
- yr = 1.05 * (y1 - y0)
-
- xmarg = xsize - xr
- ymarg = ysize - yr
- Ysize = data_ratio * xsize
- Xsize = ysize / data_ratio
- Xmarg = Xsize - xr
- Ymarg = Ysize - yr
- # Setting these targets to, e.g., 0.05*xr does not seem to help.
- xm = 0
- ym = 0
-
- shared_x = self in self._shared_axes["x"]
- shared_y = self in self._shared_axes["y"]
-
- if shared_x and shared_y:
- raise RuntimeError("set_aspect(..., adjustable='datalim') or "
- "axis('equal') are not allowed when both axes "
- "are shared. Try set_aspect(..., "
- "adjustable='box').")
-
- # If y is shared, then we are only allowed to change x, etc.
- if shared_y:
- adjust_y = False
- else:
- if xmarg > xm and ymarg > ym:
- adjy = ((Ymarg > 0 and y_expander < 0) or
- (Xmarg < 0 and y_expander > 0))
- else:
- adjy = y_expander > 0
- adjust_y = shared_x or adjy # (Ymarg > xmarg)
-
- if adjust_y:
- yc = 0.5 * (ymin + ymax)
- y0 = yc - Ysize / 2.0
- y1 = yc + Ysize / 2.0
- self.set_ybound(y_trf.inverted().transform([y0, y1]))
- else:
- xc = 0.5 * (xmin + xmax)
- x0 = xc - Xsize / 2.0
- x1 = xc + Xsize / 2.0
- self.set_xbound(x_trf.inverted().transform([x0, x1]))
-
- def axis(self, arg=None, /, *, emit=True, **kwargs):
- """
- Convenience method to get or set some axis properties.
-
- Call signatures::
-
- xmin, xmax, ymin, ymax = axis()
- xmin, xmax, ymin, ymax = axis([xmin, xmax, ymin, ymax])
- xmin, xmax, ymin, ymax = axis(option)
- xmin, xmax, ymin, ymax = axis(**kwargs)
-
- Parameters
- ----------
- xmin, xmax, ymin, ymax : float, optional
- The axis limits to be set. This can also be achieved using ::
-
- ax.set(xlim=(xmin, xmax), ylim=(ymin, ymax))
-
- option : bool or str
- If a bool, turns axis lines and labels on or off. If a string,
- possible values are:
-
- ================ ===========================================================
- Value Description
- ================ ===========================================================
- 'off' or `False` Hide all axis decorations, i.e. axis labels, spines,
- tick marks, tick labels, and grid lines.
- This is the same as `~.Axes.set_axis_off()`.
- 'on' or `True` Do not hide all axis decorations, i.e. axis labels, spines,
- tick marks, tick labels, and grid lines.
- This is the same as `~.Axes.set_axis_on()`.
- 'equal' Set equal scaling (i.e., make circles circular) by
- changing the axis limits. This is the same as
- ``ax.set_aspect('equal', adjustable='datalim')``.
- Explicit data limits may not be respected in this case.
- 'scaled' Set equal scaling (i.e., make circles circular) by
- changing dimensions of the plot box. This is the same as
- ``ax.set_aspect('equal', adjustable='box', anchor='C')``.
- Additionally, further autoscaling will be disabled.
- 'tight' Set limits just large enough to show all data, then
- disable further autoscaling.
- 'auto' Automatic scaling (fill plot box with data).
- 'image' 'scaled' with axis limits equal to data limits.
- 'square' Square plot; similar to 'scaled', but initially forcing
- ``xmax-xmin == ymax-ymin``.
- ================ ===========================================================
-
- emit : bool, default: True
- Whether observers are notified of the axis limit change.
- This option is passed on to `~.Axes.set_xlim` and
- `~.Axes.set_ylim`.
-
- Returns
- -------
- xmin, xmax, ymin, ymax : float
- The axis limits.
-
- See Also
- --------
- matplotlib.axes.Axes.set_xlim
- matplotlib.axes.Axes.set_ylim
-
- Notes
- -----
- For 3D axes, this method additionally takes *zmin*, *zmax* as
- parameters and likewise returns them.
- """
- if isinstance(arg, (str, bool)):
- if arg is True:
- arg = 'on'
- if arg is False:
- arg = 'off'
- arg = arg.lower()
- if arg == 'on':
- self.set_axis_on()
- elif arg == 'off':
- self.set_axis_off()
- elif arg in [
- 'equal', 'tight', 'scaled', 'auto', 'image', 'square']:
- self.set_autoscale_on(True)
- self.set_aspect('auto')
- self.autoscale_view(tight=False)
- if arg == 'equal':
- self.set_aspect('equal', adjustable='datalim')
- elif arg == 'scaled':
- self.set_aspect('equal', adjustable='box', anchor='C')
- self.set_autoscale_on(False) # Req. by Mark Bakker
- elif arg == 'tight':
- self.autoscale_view(tight=True)
- self.set_autoscale_on(False)
- elif arg == 'image':
- self.autoscale_view(tight=True)
- self.set_autoscale_on(False)
- self.set_aspect('equal', adjustable='box', anchor='C')
- elif arg == 'square':
- self.set_aspect('equal', adjustable='box', anchor='C')
- self.set_autoscale_on(False)
- xlim = self.get_xlim()
- ylim = self.get_ylim()
- edge_size = max(np.diff(xlim), np.diff(ylim))[0]
- self.set_xlim([xlim[0], xlim[0] + edge_size],
- emit=emit, auto=False)
- self.set_ylim([ylim[0], ylim[0] + edge_size],
- emit=emit, auto=False)
- else:
- raise ValueError(f"Unrecognized string {arg!r} to axis; "
- "try 'on' or 'off'")
- else:
- if arg is not None:
- if len(arg) != 2*len(self._axis_names):
- raise TypeError(
- "The first argument to axis() must be an iterable of the form "
- "[{}]".format(", ".join(
- f"{name}min, {name}max" for name in self._axis_names)))
- limits = {
- name: arg[2*i:2*(i+1)]
- for i, name in enumerate(self._axis_names)
- }
- else:
- limits = {}
- for name in self._axis_names:
- ax_min = kwargs.pop(f'{name}min', None)
- ax_max = kwargs.pop(f'{name}max', None)
- limits[name] = (ax_min, ax_max)
- for name, (ax_min, ax_max) in limits.items():
- ax_auto = (None # Keep autoscale state as is.
- if ax_min is None and ax_max is None
- else False) # Turn off autoscale.
- set_ax_lim = getattr(self, f'set_{name}lim')
- set_ax_lim(ax_min, ax_max, emit=emit, auto=ax_auto)
- if kwargs:
- raise _api.kwarg_error("axis", kwargs)
- lims = ()
- for name in self._axis_names:
- get_ax_lim = getattr(self, f'get_{name}lim')
- lims += get_ax_lim()
- return lims
-
- def get_legend(self):
- """Return the `.Legend` instance, or None if no legend is defined."""
- return self.legend_
-
- def get_images(self):
- r"""Return a list of `.AxesImage`\s contained by the Axes."""
- return cbook.silent_list('AxesImage', self.images)
-
- def get_lines(self):
- """Return a list of lines contained by the Axes."""
- return cbook.silent_list('Line2D', self.lines)
-
- def get_xaxis(self):
- """
- [*Discouraged*] Return the XAxis instance.
-
- .. admonition:: Discouraged
-
- The use of this function is discouraged. You should instead
- directly access the attribute ``ax.xaxis``.
- """
- return self.xaxis
-
- def get_yaxis(self):
- """
- [*Discouraged*] Return the YAxis instance.
-
- .. admonition:: Discouraged
-
- The use of this function is discouraged. You should instead
- directly access the attribute ``ax.yaxis``.
- """
- return self.yaxis
-
- get_xgridlines = _axis_method_wrapper("xaxis", "get_gridlines")
- get_xticklines = _axis_method_wrapper("xaxis", "get_ticklines")
- get_ygridlines = _axis_method_wrapper("yaxis", "get_gridlines")
- get_yticklines = _axis_method_wrapper("yaxis", "get_ticklines")
-
- # Adding and tracking artists
-
- def _sci(self, im):
- """
- Set the current image.
-
- This image will be the target of colormap functions like
- ``pyplot.viridis``, and other functions such as `~.pyplot.clim`. The
- current image is an attribute of the current Axes.
- """
- _api.check_isinstance((mcoll.Collection, mimage.AxesImage), im=im)
- if im not in self._children:
- raise ValueError("Argument must be an image or collection in this Axes")
- self._current_image = im
-
- def _gci(self):
- """Helper for `~matplotlib.pyplot.gci`; do not use elsewhere."""
- return self._current_image
-
- def has_data(self):
- """
- Return whether any artists have been added to the Axes.
-
- This should not be used to determine whether the *dataLim*
- need to be updated, and may not actually be useful for
- anything.
- """
- return any(isinstance(a, (mcoll.Collection, mimage.AxesImage,
- mlines.Line2D, mpatches.Patch))
- for a in self._children)
-
- def add_artist(self, a):
- """
- Add an `.Artist` to the Axes; return the artist.
-
- Use `add_artist` only for artists for which there is no dedicated
- "add" method; and if necessary, use a method such as `update_datalim`
- to manually update the dataLim if the artist is to be included in
- autoscaling.
-
- If no ``transform`` has been specified when creating the artist (e.g.
- ``artist.get_transform() == None``) then the transform is set to
- ``ax.transData``.
- """
- a.axes = self
- self._children.append(a)
- a._remove_method = self._children.remove
- self._set_artist_props(a)
- if a.get_clip_path() is None:
- a.set_clip_path(self.patch)
- self.stale = True
- return a
-
- def add_child_axes(self, ax):
- """
- Add an `.AxesBase` to the Axes' children; return the child Axes.
-
- This is the lowlevel version. See `.axes.Axes.inset_axes`.
- """
-
- # normally Axes have themselves as the Axes, but these need to have
- # their parent...
- # Need to bypass the getter...
- ax._axes = self
- ax.stale_callback = martist._stale_axes_callback
-
- self.child_axes.append(ax)
- ax._remove_method = functools.partial(
- self.figure._remove_axes, owners=[self.child_axes])
- self.stale = True
- return ax
-
- def add_collection(self, collection, autolim=True):
- """
- Add a `.Collection` to the Axes; return the collection.
- """
- _api.check_isinstance(mcoll.Collection, collection=collection)
- if not collection.get_label():
- collection.set_label(f'_child{len(self._children)}')
- self._children.append(collection)
- collection._remove_method = self._children.remove
- self._set_artist_props(collection)
-
- if collection.get_clip_path() is None:
- collection.set_clip_path(self.patch)
-
- if autolim:
- # Make sure viewLim is not stale (mostly to match
- # pre-lazy-autoscale behavior, which is not really better).
- self._unstale_viewLim()
- datalim = collection.get_datalim(self.transData)
- points = datalim.get_points()
- if not np.isinf(datalim.minpos).all():
- # By definition, if minpos (minimum positive value) is set
- # (i.e., non-inf), then min(points) <= minpos <= max(points),
- # and minpos would be superfluous. However, we add minpos to
- # the call so that self.dataLim will update its own minpos.
- # This ensures that log scales see the correct minimum.
- points = np.concatenate([points, [datalim.minpos]])
- self.update_datalim(points)
-
- self.stale = True
- return collection
-
- def add_image(self, image):
- """
- Add an `.AxesImage` to the Axes; return the image.
- """
- _api.check_isinstance(mimage.AxesImage, image=image)
- self._set_artist_props(image)
- if not image.get_label():
- image.set_label(f'_child{len(self._children)}')
- self._children.append(image)
- image._remove_method = self._children.remove
- self.stale = True
- return image
-
- def _update_image_limits(self, image):
- xmin, xmax, ymin, ymax = image.get_extent()
- self.axes.update_datalim(((xmin, ymin), (xmax, ymax)))
-
- def add_line(self, line):
- """
- Add a `.Line2D` to the Axes; return the line.
- """
- _api.check_isinstance(mlines.Line2D, line=line)
- self._set_artist_props(line)
- if line.get_clip_path() is None:
- line.set_clip_path(self.patch)
-
- self._update_line_limits(line)
- if not line.get_label():
- line.set_label(f'_child{len(self._children)}')
- self._children.append(line)
- line._remove_method = self._children.remove
- self.stale = True
- return line
-
- def _add_text(self, txt):
- """
- Add a `.Text` to the Axes; return the text.
- """
- _api.check_isinstance(mtext.Text, txt=txt)
- self._set_artist_props(txt)
- self._children.append(txt)
- txt._remove_method = self._children.remove
- self.stale = True
- return txt
-
- def _update_line_limits(self, line):
- """
- Figures out the data limit of the given line, updating self.dataLim.
- """
- path = line.get_path()
- if path.vertices.size == 0:
- return
-
- line_trf = line.get_transform()
-
- if line_trf == self.transData:
- data_path = path
- elif any(line_trf.contains_branch_seperately(self.transData)):
- # Compute the transform from line coordinates to data coordinates.
- trf_to_data = line_trf - self.transData
- # If transData is affine we can use the cached non-affine component
- # of line's path (since the non-affine part of line_trf is
- # entirely encapsulated in trf_to_data).
- if self.transData.is_affine:
- line_trans_path = line._get_transformed_path()
- na_path, _ = line_trans_path.get_transformed_path_and_affine()
- data_path = trf_to_data.transform_path_affine(na_path)
- else:
- data_path = trf_to_data.transform_path(path)
- else:
- # For backwards compatibility we update the dataLim with the
- # coordinate range of the given path, even though the coordinate
- # systems are completely different. This may occur in situations
- # such as when ax.transAxes is passed through for absolute
- # positioning.
- data_path = path
-
- if not data_path.vertices.size:
- return
-
- updatex, updatey = line_trf.contains_branch_seperately(self.transData)
- if self.name != "rectilinear":
- # This block is mostly intended to handle axvline in polar plots,
- # for which updatey would otherwise be True.
- if updatex and line_trf == self.get_yaxis_transform():
- updatex = False
- if updatey and line_trf == self.get_xaxis_transform():
- updatey = False
- self.dataLim.update_from_path(data_path,
- self.ignore_existing_data_limits,
- updatex=updatex, updatey=updatey)
- self.ignore_existing_data_limits = False
-
- def add_patch(self, p):
- """
- Add a `.Patch` to the Axes; return the patch.
- """
- _api.check_isinstance(mpatches.Patch, p=p)
- self._set_artist_props(p)
- if p.get_clip_path() is None:
- p.set_clip_path(self.patch)
- self._update_patch_limits(p)
- self._children.append(p)
- p._remove_method = self._children.remove
- return p
-
- def _update_patch_limits(self, patch):
- """Update the data limits for the given patch."""
- # hist can add zero height Rectangles, which is useful to keep
- # the bins, counts and patches lined up, but it throws off log
- # scaling. We'll ignore rects with zero height or width in
- # the auto-scaling
-
- # cannot check for '==0' since unitized data may not compare to zero
- # issue #2150 - we update the limits if patch has non zero width
- # or height.
- if (isinstance(patch, mpatches.Rectangle) and
- ((not patch.get_width()) and (not patch.get_height()))):
- return
- p = patch.get_path()
- # Get all vertices on the path
- # Loop through each segment to get extrema for Bezier curve sections
- vertices = []
- for curve, code in p.iter_bezier(simplify=False):
- # Get distance along the curve of any extrema
- _, dzeros = curve.axis_aligned_extrema()
- # Calculate vertices of start, end and any extrema in between
- vertices.append(curve([0, *dzeros, 1]))
-
- if len(vertices):
- vertices = np.vstack(vertices)
-
- patch_trf = patch.get_transform()
- updatex, updatey = patch_trf.contains_branch_seperately(self.transData)
- if not (updatex or updatey):
- return
- if self.name != "rectilinear":
- # As in _update_line_limits, but for axvspan.
- if updatex and patch_trf == self.get_yaxis_transform():
- updatex = False
- if updatey and patch_trf == self.get_xaxis_transform():
- updatey = False
- trf_to_data = patch_trf - self.transData
- xys = trf_to_data.transform(vertices)
- self.update_datalim(xys, updatex=updatex, updatey=updatey)
-
- def add_table(self, tab):
- """
- Add a `.Table` to the Axes; return the table.
- """
- _api.check_isinstance(mtable.Table, tab=tab)
- self._set_artist_props(tab)
- self._children.append(tab)
- if tab.get_clip_path() is None:
- tab.set_clip_path(self.patch)
- tab._remove_method = self._children.remove
- return tab
-
- def add_container(self, container):
- """
- Add a `.Container` to the Axes' containers; return the container.
- """
- label = container.get_label()
- if not label:
- container.set_label('_container%d' % len(self.containers))
- self.containers.append(container)
- container._remove_method = self.containers.remove
- return container
-
- def _unit_change_handler(self, axis_name, event=None):
- """
- Process axis units changes: requests updates to data and view limits.
- """
- if event is None: # Allow connecting `self._unit_change_handler(name)`
- return functools.partial(
- self._unit_change_handler, axis_name, event=object())
- _api.check_in_list(self._axis_map, axis_name=axis_name)
- for line in self.lines:
- line.recache_always()
- self.relim()
- self._request_autoscale_view(axis_name)
-
- def relim(self, visible_only=False):
- """
- Recompute the data limits based on current artists.
-
- At present, `.Collection` instances are not supported.
-
- Parameters
- ----------
- visible_only : bool, default: False
- Whether to exclude invisible artists.
- """
- # Collections are deliberately not supported (yet); see
- # the TODO note in artists.py.
- self.dataLim.ignore(True)
- self.dataLim.set_points(mtransforms.Bbox.null().get_points())
- self.ignore_existing_data_limits = True
-
- for artist in self._children:
- if not visible_only or artist.get_visible():
- if isinstance(artist, mlines.Line2D):
- self._update_line_limits(artist)
- elif isinstance(artist, mpatches.Patch):
- self._update_patch_limits(artist)
- elif isinstance(artist, mimage.AxesImage):
- self._update_image_limits(artist)
-
- def update_datalim(self, xys, updatex=True, updatey=True):
- """
- Extend the `~.Axes.dataLim` Bbox to include the given points.
-
- If no data is set currently, the Bbox will ignore its limits and set
- the bound to be the bounds of the xydata (*xys*). Otherwise, it will
- compute the bounds of the union of its current data and the data in
- *xys*.
-
- Parameters
- ----------
- xys : 2D array-like
- The points to include in the data limits Bbox. This can be either
- a list of (x, y) tuples or a (N, 2) array.
-
- updatex, updatey : bool, default: True
- Whether to update the x/y limits.
- """
- xys = np.asarray(xys)
- if not np.any(np.isfinite(xys)):
- return
- self.dataLim.update_from_data_xy(xys, self.ignore_existing_data_limits,
- updatex=updatex, updatey=updatey)
- self.ignore_existing_data_limits = False
-
- def _process_unit_info(self, datasets=None, kwargs=None, *, convert=True):
- """
- Set axis units based on *datasets* and *kwargs*, and optionally apply
- unit conversions to *datasets*.
-
- Parameters
- ----------
- datasets : list
- List of (axis_name, dataset) pairs (where the axis name is defined
- as in `._axis_map`). Individual datasets can also be None
- (which gets passed through).
- kwargs : dict
- Other parameters from which unit info (i.e., the *xunits*,
- *yunits*, *zunits* (for 3D Axes), *runits* and *thetaunits* (for
- polar) entries) is popped, if present. Note that this dict is
- mutated in-place!
- convert : bool, default: True
- Whether to return the original datasets or the converted ones.
-
- Returns
- -------
- list
- Either the original datasets if *convert* is False, or the
- converted ones if *convert* is True (the default).
- """
- # The API makes datasets a list of pairs rather than an axis_name to
- # dataset mapping because it is sometimes necessary to process multiple
- # datasets for a single axis, and concatenating them may be tricky
- # (e.g. if some are scalars, etc.).
- datasets = datasets or []
- kwargs = kwargs or {}
- axis_map = self._axis_map
- for axis_name, data in datasets:
- try:
- axis = axis_map[axis_name]
- except KeyError:
- raise ValueError(f"Invalid axis name: {axis_name!r}") from None
- # Update from data if axis is already set but no unit is set yet.
- if axis is not None and data is not None and not axis.have_units():
- axis.update_units(data)
- for axis_name, axis in axis_map.items():
- # Return if no axis is set.
- if axis is None:
- continue
- # Check for units in the kwargs, and if present update axis.
- units = kwargs.pop(f"{axis_name}units", axis.units)
- if self.name == "polar":
- # Special case: polar supports "thetaunits"/"runits".
- polar_units = {"x": "thetaunits", "y": "runits"}
- units = kwargs.pop(polar_units[axis_name], units)
- if units != axis.units and units is not None:
- axis.set_units(units)
- # If the units being set imply a different converter,
- # we need to update again.
- for dataset_axis_name, data in datasets:
- if dataset_axis_name == axis_name and data is not None:
- axis.update_units(data)
- return [axis_map[axis_name].convert_units(data)
- if convert and data is not None else data
- for axis_name, data in datasets]
-
- def in_axes(self, mouseevent):
- """
- Return whether the given event (in display coords) is in the Axes.
- """
- return self.patch.contains(mouseevent)[0]
-
- get_autoscalex_on = _axis_method_wrapper("xaxis", "_get_autoscale_on")
- get_autoscaley_on = _axis_method_wrapper("yaxis", "_get_autoscale_on")
- set_autoscalex_on = _axis_method_wrapper("xaxis", "_set_autoscale_on")
- set_autoscaley_on = _axis_method_wrapper("yaxis", "_set_autoscale_on")
-
- def get_autoscale_on(self):
- """Return True if each axis is autoscaled, False otherwise."""
- return all(axis._get_autoscale_on()
- for axis in self._axis_map.values())
-
- def set_autoscale_on(self, b):
- """
- Set whether autoscaling is applied to each axis on the next draw or
- call to `.Axes.autoscale_view`.
-
- Parameters
- ----------
- b : bool
- """
- for axis in self._axis_map.values():
- axis._set_autoscale_on(b)
-
- @property
- def use_sticky_edges(self):
- """
- When autoscaling, whether to obey all `Artist.sticky_edges`.
-
- Default is ``True``.
-
- Setting this to ``False`` ensures that the specified margins
- will be applied, even if the plot includes an image, for
- example, which would otherwise force a view limit to coincide
- with its data limit.
-
- The changing this property does not change the plot until
- `autoscale` or `autoscale_view` is called.
- """
- return self._use_sticky_edges
-
- @use_sticky_edges.setter
- def use_sticky_edges(self, b):
- self._use_sticky_edges = bool(b)
- # No effect until next autoscaling, which will mark the Axes as stale.
-
- def set_xmargin(self, m):
- """
- Set padding of X data limits prior to autoscaling.
-
- *m* times the data interval will be added to each end of that interval
- before it is used in autoscaling. If *m* is negative, this will clip
- the data range instead of expanding it.
-
- For example, if your data is in the range [0, 2], a margin of 0.1 will
- result in a range [-0.2, 2.2]; a margin of -0.1 will result in a range
- of [0.2, 1.8].
-
- Parameters
- ----------
- m : float greater than -0.5
- """
- if m <= -0.5:
- raise ValueError("margin must be greater than -0.5")
- self._xmargin = m
- self._request_autoscale_view("x")
- self.stale = True
-
- def set_ymargin(self, m):
- """
- Set padding of Y data limits prior to autoscaling.
-
- *m* times the data interval will be added to each end of that interval
- before it is used in autoscaling. If *m* is negative, this will clip
- the data range instead of expanding it.
-
- For example, if your data is in the range [0, 2], a margin of 0.1 will
- result in a range [-0.2, 2.2]; a margin of -0.1 will result in a range
- of [0.2, 1.8].
-
- Parameters
- ----------
- m : float greater than -0.5
- """
- if m <= -0.5:
- raise ValueError("margin must be greater than -0.5")
- self._ymargin = m
- self._request_autoscale_view("y")
- self.stale = True
-
- def margins(self, *margins, x=None, y=None, tight=True):
- """
- Set or retrieve autoscaling margins.
-
- The padding added to each limit of the Axes is the *margin*
- times the data interval. All input parameters must be floats
- greater than -0.5. Passing both positional and keyword
- arguments is invalid and will raise a TypeError. If no
- arguments (positional or otherwise) are provided, the current
- margins will remain unchanged and simply be returned.
-
- Specifying any margin changes only the autoscaling; for example,
- if *xmargin* is not None, then *xmargin* times the X data
- interval will be added to each end of that interval before
- it is used in autoscaling.
-
- Parameters
- ----------
- *margins : float, optional
- If a single positional argument is provided, it specifies
- both margins of the x-axis and y-axis limits. If two
- positional arguments are provided, they will be interpreted
- as *xmargin*, *ymargin*. If setting the margin on a single
- axis is desired, use the keyword arguments described below.
-
- x, y : float, optional
- Specific margin values for the x-axis and y-axis,
- respectively. These cannot be used with positional
- arguments, but can be used individually to alter on e.g.,
- only the y-axis.
-
- tight : bool or None, default: True
- The *tight* parameter is passed to `~.axes.Axes.autoscale_view`,
- which is executed after a margin is changed; the default
- here is *True*, on the assumption that when margins are
- specified, no additional padding to match tick marks is
- usually desired. Setting *tight* to *None* preserves
- the previous setting.
-
- Returns
- -------
- xmargin, ymargin : float
-
- Notes
- -----
- If a previously used Axes method such as :meth:`pcolor` has set
- :attr:`use_sticky_edges` to `True`, only the limits not set by
- the "sticky artists" will be modified. To force all of the
- margins to be set, set :attr:`use_sticky_edges` to `False`
- before calling :meth:`margins`.
- """
-
- if margins and (x is not None or y is not None):
- raise TypeError('Cannot pass both positional and keyword '
- 'arguments for x and/or y.')
- elif len(margins) == 1:
- x = y = margins[0]
- elif len(margins) == 2:
- x, y = margins
- elif margins:
- raise TypeError('Must pass a single positional argument for all '
- 'margins, or one for each margin (x, y).')
-
- if x is None and y is None:
- if tight is not True:
- _api.warn_external(f'ignoring tight={tight!r} in get mode')
- return self._xmargin, self._ymargin
-
- if tight is not None:
- self._tight = tight
- if x is not None:
- self.set_xmargin(x)
- if y is not None:
- self.set_ymargin(y)
-
- def set_rasterization_zorder(self, z):
- """
- Set the zorder threshold for rasterization for vector graphics output.
-
- All artists with a zorder below the given value will be rasterized if
- they support rasterization.
-
- This setting is ignored for pixel-based output.
-
- See also :doc:`/gallery/misc/rasterization_demo`.
-
- Parameters
- ----------
- z : float or None
- The zorder below which artists are rasterized.
- If ``None`` rasterization based on zorder is deactivated.
- """
- self._rasterization_zorder = z
- self.stale = True
-
- def get_rasterization_zorder(self):
- """Return the zorder value below which artists will be rasterized."""
- return self._rasterization_zorder
-
- def autoscale(self, enable=True, axis='both', tight=None):
- """
- Autoscale the axis view to the data (toggle).
-
- Convenience method for simple axis view autoscaling.
- It turns autoscaling on or off, and then,
- if autoscaling for either axis is on, it performs
- the autoscaling on the specified axis or Axes.
-
- Parameters
- ----------
- enable : bool or None, default: True
- True turns autoscaling on, False turns it off.
- None leaves the autoscaling state unchanged.
- axis : {'both', 'x', 'y'}, default: 'both'
- The axis on which to operate. (For 3D Axes, *axis* can also be set
- to 'z', and 'both' refers to all three axes.)
- tight : bool or None, default: None
- If True, first set the margins to zero. Then, this argument is
- forwarded to `~.axes.Axes.autoscale_view` (regardless of
- its value); see the description of its behavior there.
- """
- if enable is None:
- scalex = True
- scaley = True
- else:
- if axis in ['x', 'both']:
- self.set_autoscalex_on(bool(enable))
- scalex = self.get_autoscalex_on()
- else:
- scalex = False
- if axis in ['y', 'both']:
- self.set_autoscaley_on(bool(enable))
- scaley = self.get_autoscaley_on()
- else:
- scaley = False
- if tight and scalex:
- self._xmargin = 0
- if tight and scaley:
- self._ymargin = 0
- if scalex:
- self._request_autoscale_view("x", tight=tight)
- if scaley:
- self._request_autoscale_view("y", tight=tight)
-
- def autoscale_view(self, tight=None, scalex=True, scaley=True):
- """
- Autoscale the view limits using the data limits.
-
- Parameters
- ----------
- tight : bool or None
- If *True*, only expand the axis limits using the margins. Note
- that unlike for `autoscale`, ``tight=True`` does *not* set the
- margins to zero.
-
- If *False* and :rc:`axes.autolimit_mode` is 'round_numbers', then
- after expansion by the margins, further expand the axis limits
- using the axis major locator.
-
- If None (the default), reuse the value set in the previous call to
- `autoscale_view` (the initial value is False, but the default style
- sets :rc:`axes.autolimit_mode` to 'data', in which case this
- behaves like True).
-
- scalex : bool, default: True
- Whether to autoscale the x-axis.
-
- scaley : bool, default: True
- Whether to autoscale the y-axis.
-
- Notes
- -----
- The autoscaling preserves any preexisting axis direction reversal.
-
- The data limits are not updated automatically when artist data are
- changed after the artist has been added to an Axes instance. In that
- case, use :meth:`matplotlib.axes.Axes.relim` prior to calling
- autoscale_view.
-
- If the views of the Axes are fixed, e.g. via `set_xlim`, they will
- not be changed by autoscale_view().
- See :meth:`matplotlib.axes.Axes.autoscale` for an alternative.
- """
- if tight is not None:
- self._tight = bool(tight)
-
- x_stickies = y_stickies = np.array([])
- if self.use_sticky_edges:
- if self._xmargin and scalex and self.get_autoscalex_on():
- x_stickies = np.sort(np.concatenate([
- artist.sticky_edges.x
- for ax in self._shared_axes["x"].get_siblings(self)
- for artist in ax.get_children()]))
- if self._ymargin and scaley and self.get_autoscaley_on():
- y_stickies = np.sort(np.concatenate([
- artist.sticky_edges.y
- for ax in self._shared_axes["y"].get_siblings(self)
- for artist in ax.get_children()]))
- if self.get_xscale() == 'log':
- x_stickies = x_stickies[x_stickies > 0]
- if self.get_yscale() == 'log':
- y_stickies = y_stickies[y_stickies > 0]
-
- def handle_single_axis(
- scale, shared_axes, name, axis, margin, stickies, set_bound):
-
- if not (scale and axis._get_autoscale_on()):
- return # nothing to do...
-
- shared = shared_axes.get_siblings(self)
- # Base autoscaling on finite data limits when there is at least one
- # finite data limit among all the shared_axes and intervals.
- values = [val for ax in shared
- for val in getattr(ax.dataLim, f"interval{name}")
- if np.isfinite(val)]
- if values:
- x0, x1 = (min(values), max(values))
- elif getattr(self._viewLim, f"mutated{name}")():
- # No data, but explicit viewLims already set:
- # in mutatedx or mutatedy.
- return
- else:
- x0, x1 = (-np.inf, np.inf)
- # If x0 and x1 are nonfinite, get default limits from the locator.
- locator = axis.get_major_locator()
- x0, x1 = locator.nonsingular(x0, x1)
- # Find the minimum minpos for use in the margin calculation.
- minimum_minpos = min(
- getattr(ax.dataLim, f"minpos{name}") for ax in shared)
-
- # Prevent margin addition from crossing a sticky value. A small
- # tolerance must be added due to floating point issues with
- # streamplot; it is defined relative to x0, x1, x1-x0 but has
- # no absolute term (e.g. "+1e-8") to avoid issues when working with
- # datasets where all values are tiny (less than 1e-8).
- tol = 1e-5 * max(abs(x0), abs(x1), abs(x1 - x0))
- # Index of largest element < x0 + tol, if any.
- i0 = stickies.searchsorted(x0 + tol) - 1
- x0bound = stickies[i0] if i0 != -1 else None
- # Index of smallest element > x1 - tol, if any.
- i1 = stickies.searchsorted(x1 - tol)
- x1bound = stickies[i1] if i1 != len(stickies) else None
-
- # Add the margin in figure space and then transform back, to handle
- # non-linear scales.
- transform = axis.get_transform()
- inverse_trans = transform.inverted()
- x0, x1 = axis._scale.limit_range_for_scale(x0, x1, minimum_minpos)
- x0t, x1t = transform.transform([x0, x1])
- delta = (x1t - x0t) * margin
- if not np.isfinite(delta):
- delta = 0 # If a bound isn't finite, set margin to zero.
- x0, x1 = inverse_trans.transform([x0t - delta, x1t + delta])
-
- # Apply sticky bounds.
- if x0bound is not None:
- x0 = max(x0, x0bound)
- if x1bound is not None:
- x1 = min(x1, x1bound)
-
- if not self._tight:
- x0, x1 = locator.view_limits(x0, x1)
- set_bound(x0, x1)
- # End of definition of internal function 'handle_single_axis'.
-
- handle_single_axis(
- scalex, self._shared_axes["x"], 'x', self.xaxis, self._xmargin,
- x_stickies, self.set_xbound)
- handle_single_axis(
- scaley, self._shared_axes["y"], 'y', self.yaxis, self._ymargin,
- y_stickies, self.set_ybound)
-
- def _update_title_position(self, renderer):
- """
- Update the title position based on the bounding box enclosing
- all the ticklabels and x-axis spine and xlabel...
- """
- if self._autotitlepos is not None and not self._autotitlepos:
- _log.debug('title position was updated manually, not adjusting')
- return
-
- titles = (self.title, self._left_title, self._right_title)
-
- # Need to check all our twins too, and all the children as well.
- axs = self._twinned_axes.get_siblings(self) + self.child_axes
- for ax in self.child_axes: # Child positions must be updated first.
- locator = ax.get_axes_locator()
- ax.apply_aspect(locator(self, renderer) if locator else None)
-
- for title in titles:
- x, _ = title.get_position()
- # need to start again in case of window resizing
- title.set_position((x, 1.0))
- top = -np.inf
- for ax in axs:
- bb = None
- if (ax.xaxis.get_ticks_position() in ['top', 'unknown']
- or ax.xaxis.get_label_position() == 'top'):
- bb = ax.xaxis.get_tightbbox(renderer)
- if bb is None:
- if 'outline' in ax.spines:
- # Special case for colorbars:
- bb = ax.spines['outline'].get_window_extent()
- else:
- bb = ax.get_window_extent(renderer)
- top = max(top, bb.ymax)
- if title.get_text():
- ax.yaxis.get_tightbbox(renderer) # update offsetText
- if ax.yaxis.offsetText.get_text():
- bb = ax.yaxis.offsetText.get_tightbbox(renderer)
- if bb.intersection(title.get_tightbbox(renderer), bb):
- top = bb.ymax
- if top < 0:
- # the top of Axes is not even on the figure, so don't try and
- # automatically place it.
- _log.debug('top of Axes not in the figure, so title not moved')
- return
- if title.get_window_extent(renderer).ymin < top:
- _, y = self.transAxes.inverted().transform((0, top))
- title.set_position((x, y))
- # empirically, this doesn't always get the min to top,
- # so we need to adjust again.
- if title.get_window_extent(renderer).ymin < top:
- _, y = self.transAxes.inverted().transform(
- (0., 2 * top - title.get_window_extent(renderer).ymin))
- title.set_position((x, y))
-
- ymax = max(title.get_position()[1] for title in titles)
- for title in titles:
- # now line up all the titles at the highest baseline.
- x, _ = title.get_position()
- title.set_position((x, ymax))
-
- # Drawing
- @martist.allow_rasterization
- def draw(self, renderer):
- # docstring inherited
- if renderer is None:
- raise RuntimeError('No renderer defined')
- if not self.get_visible():
- return
- self._unstale_viewLim()
-
- renderer.open_group('axes', gid=self.get_gid())
-
- # prevent triggering call backs during the draw process
- self._stale = True
-
- # loop over self and child Axes...
- locator = self.get_axes_locator()
- self.apply_aspect(locator(self, renderer) if locator else None)
-
- artists = self.get_children()
- artists.remove(self.patch)
-
- # the frame draws the edges around the Axes patch -- we
- # decouple these so the patch can be in the background and the
- # frame in the foreground. Do this before drawing the axis
- # objects so that the spine has the opportunity to update them.
- if not (self.axison and self._frameon):
- for spine in self.spines.values():
- artists.remove(spine)
-
- self._update_title_position(renderer)
-
- if not self.axison:
- for _axis in self._axis_map.values():
- artists.remove(_axis)
-
- if not self.figure.canvas.is_saving():
- artists = [
- a for a in artists
- if not a.get_animated() or isinstance(a, mimage.AxesImage)]
- artists = sorted(artists, key=attrgetter('zorder'))
-
- # rasterize artists with negative zorder
- # if the minimum zorder is negative, start rasterization
- rasterization_zorder = self._rasterization_zorder
-
- if (rasterization_zorder is not None and
- artists and artists[0].zorder < rasterization_zorder):
- split_index = np.searchsorted(
- [art.zorder for art in artists],
- rasterization_zorder, side='right'
- )
- artists_rasterized = artists[:split_index]
- artists = artists[split_index:]
- else:
- artists_rasterized = []
-
- if self.axison and self._frameon:
- if artists_rasterized:
- artists_rasterized = [self.patch] + artists_rasterized
- else:
- artists = [self.patch] + artists
-
- if artists_rasterized:
- _draw_rasterized(self.figure, artists_rasterized, renderer)
-
- mimage._draw_list_compositing_images(
- renderer, self, artists, self.figure.suppressComposite)
-
- renderer.close_group('axes')
- self.stale = False
-
- def draw_artist(self, a):
- """
- Efficiently redraw a single artist.
- """
- a.draw(self.figure.canvas.get_renderer())
-
- def redraw_in_frame(self):
- """
- Efficiently redraw Axes data, but not axis ticks, labels, etc.
- """
- with ExitStack() as stack:
- for artist in [*self._axis_map.values(),
- self.title, self._left_title, self._right_title]:
- stack.enter_context(artist._cm_set(visible=False))
- self.draw(self.figure.canvas.get_renderer())
-
- # Axes rectangle characteristics
-
- def get_frame_on(self):
- """Get whether the Axes rectangle patch is drawn."""
- return self._frameon
-
- def set_frame_on(self, b):
- """
- Set whether the Axes rectangle patch is drawn.
-
- Parameters
- ----------
- b : bool
- """
- self._frameon = b
- self.stale = True
-
- def get_axisbelow(self):
- """
- Get whether axis ticks and gridlines are above or below most artists.
-
- Returns
- -------
- bool or 'line'
-
- See Also
- --------
- set_axisbelow
- """
- return self._axisbelow
-
- def set_axisbelow(self, b):
- """
- Set whether axis ticks and gridlines are above or below most artists.
-
- This controls the zorder of the ticks and gridlines. For more
- information on the zorder see :doc:`/gallery/misc/zorder_demo`.
-
- Parameters
- ----------
- b : bool or 'line'
- Possible values:
-
- - *True* (zorder = 0.5): Ticks and gridlines are below all Artists.
- - 'line' (zorder = 1.5): Ticks and gridlines are above patches
- (e.g. rectangles, with default zorder = 1) but still below lines
- and markers (with their default zorder = 2).
- - *False* (zorder = 2.5): Ticks and gridlines are above patches
- and lines / markers.
-
- See Also
- --------
- get_axisbelow
- """
- # Check that b is True, False or 'line'
- self._axisbelow = axisbelow = validate_axisbelow(b)
- zorder = {
- True: 0.5,
- 'line': 1.5,
- False: 2.5,
- }[axisbelow]
- for axis in self._axis_map.values():
- axis.set_zorder(zorder)
- self.stale = True
-
- @_docstring.dedent_interpd
- def grid(self, visible=None, which='major', axis='both', **kwargs):
- """
- Configure the grid lines.
-
- Parameters
- ----------
- visible : bool or None, optional
- Whether to show the grid lines. If any *kwargs* are supplied, it
- is assumed you want the grid on and *visible* will be set to True.
-
- If *visible* is *None* and there are no *kwargs*, this toggles the
- visibility of the lines.
-
- which : {'major', 'minor', 'both'}, optional
- The grid lines to apply the changes on.
-
- axis : {'both', 'x', 'y'}, optional
- The axis to apply the changes on.
-
- **kwargs : `~matplotlib.lines.Line2D` properties
- Define the line properties of the grid, e.g.::
-
- grid(color='r', linestyle='-', linewidth=2)
-
- Valid keyword arguments are:
-
- %(Line2D:kwdoc)s
-
- Notes
- -----
- The axis is drawn as a unit, so the effective zorder for drawing the
- grid is determined by the zorder of each axis, not by the zorder of the
- `.Line2D` objects comprising the grid. Therefore, to set grid zorder,
- use `.set_axisbelow` or, for more control, call the
- `~.Artist.set_zorder` method of each axis.
- """
- _api.check_in_list(['x', 'y', 'both'], axis=axis)
- if axis in ['x', 'both']:
- self.xaxis.grid(visible, which=which, **kwargs)
- if axis in ['y', 'both']:
- self.yaxis.grid(visible, which=which, **kwargs)
-
- def ticklabel_format(self, *, axis='both', style='', scilimits=None,
- useOffset=None, useLocale=None, useMathText=None):
- r"""
- Configure the `.ScalarFormatter` used by default for linear Axes.
-
- If a parameter is not set, the corresponding property of the formatter
- is left unchanged.
-
- Parameters
- ----------
- axis : {'x', 'y', 'both'}, default: 'both'
- The axis to configure. Only major ticks are affected.
-
- style : {'sci', 'scientific', 'plain'}
- Whether to use scientific notation.
- The formatter default is to use scientific notation.
-
- scilimits : pair of ints (m, n)
- Scientific notation is used only for numbers outside the range
- 10\ :sup:`m` to 10\ :sup:`n` (and only if the formatter is
- configured to use scientific notation at all). Use (0, 0) to
- include all numbers. Use (m, m) where m != 0 to fix the order of
- magnitude to 10\ :sup:`m`.
- The formatter default is :rc:`axes.formatter.limits`.
-
- useOffset : bool or float
- If True, the offset is calculated as needed.
- If False, no offset is used.
- If a numeric value, it sets the offset.
- The formatter default is :rc:`axes.formatter.useoffset`.
-
- useLocale : bool
- Whether to format the number using the current locale or using the
- C (English) locale. This affects e.g. the decimal separator. The
- formatter default is :rc:`axes.formatter.use_locale`.
-
- useMathText : bool
- Render the offset and scientific notation in mathtext.
- The formatter default is :rc:`axes.formatter.use_mathtext`.
-
- Raises
- ------
- AttributeError
- If the current formatter is not a `.ScalarFormatter`.
- """
- style = style.lower()
- axis = axis.lower()
- if scilimits is not None:
- try:
- m, n = scilimits
- m + n + 1 # check that both are numbers
- except (ValueError, TypeError) as err:
- raise ValueError("scilimits must be a sequence of 2 integers"
- ) from err
- STYLES = {'sci': True, 'scientific': True, 'plain': False, '': None}
- is_sci_style = _api.check_getitem(STYLES, style=style)
- axis_map = {**{k: [v] for k, v in self._axis_map.items()},
- 'both': list(self._axis_map.values())}
- axises = _api.check_getitem(axis_map, axis=axis)
- try:
- for axis in axises:
- if is_sci_style is not None:
- axis.major.formatter.set_scientific(is_sci_style)
- if scilimits is not None:
- axis.major.formatter.set_powerlimits(scilimits)
- if useOffset is not None:
- axis.major.formatter.set_useOffset(useOffset)
- if useLocale is not None:
- axis.major.formatter.set_useLocale(useLocale)
- if useMathText is not None:
- axis.major.formatter.set_useMathText(useMathText)
- except AttributeError as err:
- raise AttributeError(
- "This method only works with the ScalarFormatter") from err
-
- def locator_params(self, axis='both', tight=None, **kwargs):
- """
- Control behavior of major tick locators.
-
- Because the locator is involved in autoscaling, `~.Axes.autoscale_view`
- is called automatically after the parameters are changed.
-
- Parameters
- ----------
- axis : {'both', 'x', 'y'}, default: 'both'
- The axis on which to operate. (For 3D Axes, *axis* can also be
- set to 'z', and 'both' refers to all three axes.)
- tight : bool or None, optional
- Parameter passed to `~.Axes.autoscale_view`.
- Default is None, for no change.
-
- Other Parameters
- ----------------
- **kwargs
- Remaining keyword arguments are passed to directly to the
- ``set_params()`` method of the locator. Supported keywords depend
- on the type of the locator. See for example
- `~.ticker.MaxNLocator.set_params` for the `.ticker.MaxNLocator`
- used by default for linear.
-
- Examples
- --------
- When plotting small subplots, one might want to reduce the maximum
- number of ticks and use tight bounds, for example::
-
- ax.locator_params(tight=True, nbins=4)
-
- """
- _api.check_in_list([*self._axis_names, "both"], axis=axis)
- for name in self._axis_names:
- if axis in [name, "both"]:
- loc = self._axis_map[name].get_major_locator()
- loc.set_params(**kwargs)
- self._request_autoscale_view(name, tight=tight)
- self.stale = True
-
- def tick_params(self, axis='both', **kwargs):
- """
- Change the appearance of ticks, tick labels, and gridlines.
-
- Tick properties that are not explicitly set using the keyword
- arguments remain unchanged unless *reset* is True. For the current
- style settings, see `.Axis.get_tick_params`.
-
- Parameters
- ----------
- axis : {'x', 'y', 'both'}, default: 'both'
- The axis to which the parameters are applied.
- which : {'major', 'minor', 'both'}, default: 'major'
- The group of ticks to which the parameters are applied.
- reset : bool, default: False
- Whether to reset the ticks to defaults before updating them.
-
- Other Parameters
- ----------------
- direction : {'in', 'out', 'inout'}
- Puts ticks inside the Axes, outside the Axes, or both.
- length : float
- Tick length in points.
- width : float
- Tick width in points.
- color : color
- Tick color.
- pad : float
- Distance in points between tick and label.
- labelsize : float or str
- Tick label font size in points or as a string (e.g., 'large').
- labelcolor : color
- Tick label color.
- labelfontfamily : str
- Tick label font.
- colors : color
- Tick color and label color.
- zorder : float
- Tick and label zorder.
- bottom, top, left, right : bool
- Whether to draw the respective ticks.
- labelbottom, labeltop, labelleft, labelright : bool
- Whether to draw the respective tick labels.
- labelrotation : float
- Tick label rotation
- grid_color : color
- Gridline color.
- grid_alpha : float
- Transparency of gridlines: 0 (transparent) to 1 (opaque).
- grid_linewidth : float
- Width of gridlines in points.
- grid_linestyle : str
- Any valid `.Line2D` line style spec.
-
- Examples
- --------
- ::
-
- ax.tick_params(direction='out', length=6, width=2, colors='r',
- grid_color='r', grid_alpha=0.5)
-
- This will make all major ticks be red, pointing out of the box,
- and with dimensions 6 points by 2 points. Tick labels will
- also be red. Gridlines will be red and translucent.
-
- """
- _api.check_in_list(['x', 'y', 'both'], axis=axis)
- if axis in ['x', 'both']:
- xkw = dict(kwargs)
- xkw.pop('left', None)
- xkw.pop('right', None)
- xkw.pop('labelleft', None)
- xkw.pop('labelright', None)
- self.xaxis.set_tick_params(**xkw)
- if axis in ['y', 'both']:
- ykw = dict(kwargs)
- ykw.pop('top', None)
- ykw.pop('bottom', None)
- ykw.pop('labeltop', None)
- ykw.pop('labelbottom', None)
- self.yaxis.set_tick_params(**ykw)
-
- def set_axis_off(self):
- """
- Hide all visual components of the x- and y-axis.
-
- This sets a flag to suppress drawing of all axis decorations, i.e.
- axis labels, axis spines, and the axis tick component (tick markers,
- tick labels, and grid lines). Individual visibility settings of these
- components are ignored as long as `set_axis_off()` is in effect.
- """
- self.axison = False
- self.stale = True
-
- def set_axis_on(self):
- """
- Do not hide all visual components of the x- and y-axis.
-
- This reverts the effect of a prior `.set_axis_off()` call. Whether the
- individual axis decorations are drawn is controlled by their respective
- visibility settings.
-
- This is on by default.
- """
- self.axison = True
- self.stale = True
-
- # data limits, ticks, tick labels, and formatting
-
- def get_xlabel(self):
- """
- Get the xlabel text string.
- """
- label = self.xaxis.get_label()
- return label.get_text()
-
- def set_xlabel(self, xlabel, fontdict=None, labelpad=None, *,
- loc=None, **kwargs):
- """
- Set the label for the x-axis.
-
- Parameters
- ----------
- xlabel : str
- The label text.
-
- labelpad : float, default: :rc:`axes.labelpad`
- Spacing in points from the Axes bounding box including ticks
- and tick labels. If None, the previous value is left as is.
-
- loc : {'left', 'center', 'right'}, default: :rc:`xaxis.labellocation`
- The label position. This is a high-level alternative for passing
- parameters *x* and *horizontalalignment*.
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.text.Text` properties
- `.Text` properties control the appearance of the label.
-
- See Also
- --------
- text : Documents the properties supported by `.Text`.
- """
- if labelpad is not None:
- self.xaxis.labelpad = labelpad
- protected_kw = ['x', 'horizontalalignment', 'ha']
- if {*kwargs} & {*protected_kw}:
- if loc is not None:
- raise TypeError(f"Specifying 'loc' is disallowed when any of "
- f"its corresponding low level keyword "
- f"arguments ({protected_kw}) are also "
- f"supplied")
-
- else:
- loc = (loc if loc is not None
- else mpl.rcParams['xaxis.labellocation'])
- _api.check_in_list(('left', 'center', 'right'), loc=loc)
-
- x = {
- 'left': 0,
- 'center': 0.5,
- 'right': 1,
- }[loc]
- kwargs.update(x=x, horizontalalignment=loc)
-
- return self.xaxis.set_label_text(xlabel, fontdict, **kwargs)
-
- def invert_xaxis(self):
- """
- Invert the x-axis.
-
- See Also
- --------
- xaxis_inverted
- get_xlim, set_xlim
- get_xbound, set_xbound
- """
- self.xaxis.set_inverted(not self.xaxis.get_inverted())
-
- xaxis_inverted = _axis_method_wrapper("xaxis", "get_inverted")
-
- def get_xbound(self):
- """
- Return the lower and upper x-axis bounds, in increasing order.
-
- See Also
- --------
- set_xbound
- get_xlim, set_xlim
- invert_xaxis, xaxis_inverted
- """
- left, right = self.get_xlim()
- if left < right:
- return left, right
- else:
- return right, left
-
- def set_xbound(self, lower=None, upper=None):
- """
- Set the lower and upper numerical bounds of the x-axis.
-
- This method will honor axis inversion regardless of parameter order.
- It will not change the autoscaling setting (`.get_autoscalex_on()`).
-
- Parameters
- ----------
- lower, upper : float or None
- The lower and upper bounds. If *None*, the respective axis bound
- is not modified.
-
- .. ACCEPTS: (lower: float, upper: float)
-
- See Also
- --------
- get_xbound
- get_xlim, set_xlim
- invert_xaxis, xaxis_inverted
- """
- if upper is None and np.iterable(lower):
- lower, upper = lower
-
- old_lower, old_upper = self.get_xbound()
- if lower is None:
- lower = old_lower
- if upper is None:
- upper = old_upper
-
- self.set_xlim(sorted((lower, upper),
- reverse=bool(self.xaxis_inverted())),
- auto=None)
-
- def get_xlim(self):
- """
- Return the x-axis view limits.
-
- Returns
- -------
- left, right : (float, float)
- The current x-axis limits in data coordinates.
-
- See Also
- --------
- .Axes.set_xlim
- .Axes.set_xbound, .Axes.get_xbound
- .Axes.invert_xaxis, .Axes.xaxis_inverted
-
- Notes
- -----
- The x-axis may be inverted, in which case the *left* value will
- be greater than the *right* value.
- """
- return tuple(self.viewLim.intervalx)
-
- def _validate_converted_limits(self, limit, convert):
- """
- Raise ValueError if converted limits are non-finite.
-
- Note that this function also accepts None as a limit argument.
-
- Returns
- -------
- The limit value after call to convert(), or None if limit is None.
- """
- if limit is not None:
- converted_limit = convert(limit)
- if isinstance(converted_limit, np.ndarray):
- converted_limit = converted_limit.squeeze()
- if (isinstance(converted_limit, Real)
- and not np.isfinite(converted_limit)):
- raise ValueError("Axis limits cannot be NaN or Inf")
- return converted_limit
-
- def set_xlim(self, left=None, right=None, *, emit=True, auto=False,
- xmin=None, xmax=None):
- """
- Set the x-axis view limits.
-
- Parameters
- ----------
- left : float, optional
- The left xlim in data coordinates. Passing *None* leaves the
- limit unchanged.
-
- The left and right xlims may also be passed as the tuple
- (*left*, *right*) as the first positional argument (or as
- the *left* keyword argument).
-
- .. ACCEPTS: (left: float, right: float)
-
- right : float, optional
- The right xlim in data coordinates. Passing *None* leaves the
- limit unchanged.
-
- emit : bool, default: True
- Whether to notify observers of limit change.
-
- auto : bool or None, default: False
- Whether to turn on autoscaling of the x-axis. True turns on,
- False turns off, None leaves unchanged.
-
- xmin, xmax : float, optional
- They are equivalent to left and right respectively, and it is an
- error to pass both *xmin* and *left* or *xmax* and *right*.
-
- Returns
- -------
- left, right : (float, float)
- The new x-axis limits in data coordinates.
-
- See Also
- --------
- get_xlim
- set_xbound, get_xbound
- invert_xaxis, xaxis_inverted
-
- Notes
- -----
- The *left* value may be greater than the *right* value, in which
- case the x-axis values will decrease from left to right.
-
- Examples
- --------
- >>> set_xlim(left, right)
- >>> set_xlim((left, right))
- >>> left, right = set_xlim(left, right)
-
- One limit may be left unchanged.
-
- >>> set_xlim(right=right_lim)
-
- Limits may be passed in reverse order to flip the direction of
- the x-axis. For example, suppose *x* represents the number of
- years before present. The x-axis limits might be set like the
- following so 5000 years ago is on the left of the plot and the
- present is on the right.
-
- >>> set_xlim(5000, 0)
- """
- if right is None and np.iterable(left):
- left, right = left
- if xmin is not None:
- if left is not None:
- raise TypeError("Cannot pass both 'left' and 'xmin'")
- left = xmin
- if xmax is not None:
- if right is not None:
- raise TypeError("Cannot pass both 'right' and 'xmax'")
- right = xmax
- return self.xaxis._set_lim(left, right, emit=emit, auto=auto)
-
- get_xscale = _axis_method_wrapper("xaxis", "get_scale")
- set_xscale = _axis_method_wrapper("xaxis", "_set_axes_scale")
- get_xticks = _axis_method_wrapper("xaxis", "get_ticklocs")
- set_xticks = _axis_method_wrapper("xaxis", "set_ticks",
- doc_sub={'set_ticks': 'set_xticks'})
- get_xmajorticklabels = _axis_method_wrapper("xaxis", "get_majorticklabels")
- get_xminorticklabels = _axis_method_wrapper("xaxis", "get_minorticklabels")
- get_xticklabels = _axis_method_wrapper("xaxis", "get_ticklabels")
- set_xticklabels = _axis_method_wrapper(
- "xaxis", "set_ticklabels",
- doc_sub={"Axis.set_ticks": "Axes.set_xticks"})
-
- def get_ylabel(self):
- """
- Get the ylabel text string.
- """
- label = self.yaxis.get_label()
- return label.get_text()
-
- def set_ylabel(self, ylabel, fontdict=None, labelpad=None, *,
- loc=None, **kwargs):
- """
- Set the label for the y-axis.
-
- Parameters
- ----------
- ylabel : str
- The label text.
-
- labelpad : float, default: :rc:`axes.labelpad`
- Spacing in points from the Axes bounding box including ticks
- and tick labels. If None, the previous value is left as is.
-
- loc : {'bottom', 'center', 'top'}, default: :rc:`yaxis.labellocation`
- The label position. This is a high-level alternative for passing
- parameters *y* and *horizontalalignment*.
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.text.Text` properties
- `.Text` properties control the appearance of the label.
-
- See Also
- --------
- text : Documents the properties supported by `.Text`.
- """
- if labelpad is not None:
- self.yaxis.labelpad = labelpad
- protected_kw = ['y', 'horizontalalignment', 'ha']
- if {*kwargs} & {*protected_kw}:
- if loc is not None:
- raise TypeError(f"Specifying 'loc' is disallowed when any of "
- f"its corresponding low level keyword "
- f"arguments ({protected_kw}) are also "
- f"supplied")
-
- else:
- loc = (loc if loc is not None
- else mpl.rcParams['yaxis.labellocation'])
- _api.check_in_list(('bottom', 'center', 'top'), loc=loc)
-
- y, ha = {
- 'bottom': (0, 'left'),
- 'center': (0.5, 'center'),
- 'top': (1, 'right')
- }[loc]
- kwargs.update(y=y, horizontalalignment=ha)
-
- return self.yaxis.set_label_text(ylabel, fontdict, **kwargs)
-
- def invert_yaxis(self):
- """
- Invert the y-axis.
-
- See Also
- --------
- yaxis_inverted
- get_ylim, set_ylim
- get_ybound, set_ybound
- """
- self.yaxis.set_inverted(not self.yaxis.get_inverted())
-
- yaxis_inverted = _axis_method_wrapper("yaxis", "get_inverted")
-
- def get_ybound(self):
- """
- Return the lower and upper y-axis bounds, in increasing order.
-
- See Also
- --------
- set_ybound
- get_ylim, set_ylim
- invert_yaxis, yaxis_inverted
- """
- bottom, top = self.get_ylim()
- if bottom < top:
- return bottom, top
- else:
- return top, bottom
-
- def set_ybound(self, lower=None, upper=None):
- """
- Set the lower and upper numerical bounds of the y-axis.
-
- This method will honor axis inversion regardless of parameter order.
- It will not change the autoscaling setting (`.get_autoscaley_on()`).
-
- Parameters
- ----------
- lower, upper : float or None
- The lower and upper bounds. If *None*, the respective axis bound
- is not modified.
-
- .. ACCEPTS: (lower: float, upper: float)
-
- See Also
- --------
- get_ybound
- get_ylim, set_ylim
- invert_yaxis, yaxis_inverted
- """
- if upper is None and np.iterable(lower):
- lower, upper = lower
-
- old_lower, old_upper = self.get_ybound()
- if lower is None:
- lower = old_lower
- if upper is None:
- upper = old_upper
-
- self.set_ylim(sorted((lower, upper),
- reverse=bool(self.yaxis_inverted())),
- auto=None)
-
- def get_ylim(self):
- """
- Return the y-axis view limits.
-
- Returns
- -------
- bottom, top : (float, float)
- The current y-axis limits in data coordinates.
-
- See Also
- --------
- .Axes.set_ylim
- .Axes.set_ybound, .Axes.get_ybound
- .Axes.invert_yaxis, .Axes.yaxis_inverted
-
- Notes
- -----
- The y-axis may be inverted, in which case the *bottom* value
- will be greater than the *top* value.
- """
- return tuple(self.viewLim.intervaly)
-
- def set_ylim(self, bottom=None, top=None, *, emit=True, auto=False,
- ymin=None, ymax=None):
- """
- Set the y-axis view limits.
-
- Parameters
- ----------
- bottom : float, optional
- The bottom ylim in data coordinates. Passing *None* leaves the
- limit unchanged.
-
- The bottom and top ylims may also be passed as the tuple
- (*bottom*, *top*) as the first positional argument (or as
- the *bottom* keyword argument).
-
- .. ACCEPTS: (bottom: float, top: float)
-
- top : float, optional
- The top ylim in data coordinates. Passing *None* leaves the
- limit unchanged.
-
- emit : bool, default: True
- Whether to notify observers of limit change.
-
- auto : bool or None, default: False
- Whether to turn on autoscaling of the y-axis. *True* turns on,
- *False* turns off, *None* leaves unchanged.
-
- ymin, ymax : float, optional
- They are equivalent to bottom and top respectively, and it is an
- error to pass both *ymin* and *bottom* or *ymax* and *top*.
-
- Returns
- -------
- bottom, top : (float, float)
- The new y-axis limits in data coordinates.
-
- See Also
- --------
- get_ylim
- set_ybound, get_ybound
- invert_yaxis, yaxis_inverted
-
- Notes
- -----
- The *bottom* value may be greater than the *top* value, in which
- case the y-axis values will decrease from *bottom* to *top*.
-
- Examples
- --------
- >>> set_ylim(bottom, top)
- >>> set_ylim((bottom, top))
- >>> bottom, top = set_ylim(bottom, top)
-
- One limit may be left unchanged.
-
- >>> set_ylim(top=top_lim)
-
- Limits may be passed in reverse order to flip the direction of
- the y-axis. For example, suppose ``y`` represents depth of the
- ocean in m. The y-axis limits might be set like the following
- so 5000 m depth is at the bottom of the plot and the surface,
- 0 m, is at the top.
-
- >>> set_ylim(5000, 0)
- """
- if top is None and np.iterable(bottom):
- bottom, top = bottom
- if ymin is not None:
- if bottom is not None:
- raise TypeError("Cannot pass both 'bottom' and 'ymin'")
- bottom = ymin
- if ymax is not None:
- if top is not None:
- raise TypeError("Cannot pass both 'top' and 'ymax'")
- top = ymax
- return self.yaxis._set_lim(bottom, top, emit=emit, auto=auto)
-
- get_yscale = _axis_method_wrapper("yaxis", "get_scale")
- set_yscale = _axis_method_wrapper("yaxis", "_set_axes_scale")
- get_yticks = _axis_method_wrapper("yaxis", "get_ticklocs")
- set_yticks = _axis_method_wrapper("yaxis", "set_ticks",
- doc_sub={'set_ticks': 'set_yticks'})
- get_ymajorticklabels = _axis_method_wrapper("yaxis", "get_majorticklabels")
- get_yminorticklabels = _axis_method_wrapper("yaxis", "get_minorticklabels")
- get_yticklabels = _axis_method_wrapper("yaxis", "get_ticklabels")
- set_yticklabels = _axis_method_wrapper(
- "yaxis", "set_ticklabels",
- doc_sub={"Axis.set_ticks": "Axes.set_yticks"})
-
- xaxis_date = _axis_method_wrapper("xaxis", "axis_date")
- yaxis_date = _axis_method_wrapper("yaxis", "axis_date")
-
- def format_xdata(self, x):
- """
- Return *x* formatted as an x-value.
-
- This function will use the `.fmt_xdata` attribute if it is not None,
- else will fall back on the xaxis major formatter.
- """
- return (self.fmt_xdata if self.fmt_xdata is not None
- else self.xaxis.get_major_formatter().format_data_short)(x)
-
- def format_ydata(self, y):
- """
- Return *y* formatted as a y-value.
-
- This function will use the `.fmt_ydata` attribute if it is not None,
- else will fall back on the yaxis major formatter.
- """
- return (self.fmt_ydata if self.fmt_ydata is not None
- else self.yaxis.get_major_formatter().format_data_short)(y)
-
- def format_coord(self, x, y):
- """Return a format string formatting the *x*, *y* coordinates."""
- return "x={} y={}".format(
- "???" if x is None else self.format_xdata(x),
- "???" if y is None else self.format_ydata(y),
- )
-
- def minorticks_on(self):
- """
- Display minor ticks on the Axes.
-
- Displaying minor ticks may reduce performance; you may turn them off
- using `minorticks_off()` if drawing speed is a problem.
- """
- for ax in (self.xaxis, self.yaxis):
- scale = ax.get_scale()
- if scale == 'log':
- s = ax._scale
- ax.set_minor_locator(mticker.LogLocator(s.base, s.subs))
- elif scale == 'symlog':
- s = ax._scale
- ax.set_minor_locator(
- mticker.SymmetricalLogLocator(s._transform, s.subs))
- else:
- ax.set_minor_locator(mticker.AutoMinorLocator())
-
- def minorticks_off(self):
- """Remove minor ticks from the Axes."""
- self.xaxis.set_minor_locator(mticker.NullLocator())
- self.yaxis.set_minor_locator(mticker.NullLocator())
-
- # Interactive manipulation
-
- def can_zoom(self):
- """
- Return whether this Axes supports the zoom box button functionality.
- """
- return True
-
- def can_pan(self):
- """
- Return whether this Axes supports any pan/zoom button functionality.
- """
- return True
-
- def get_navigate(self):
- """
- Get whether the Axes responds to navigation commands.
- """
- return self._navigate
-
- def set_navigate(self, b):
- """
- Set whether the Axes responds to navigation toolbar commands.
-
- Parameters
- ----------
- b : bool
- """
- self._navigate = b
-
- def get_navigate_mode(self):
- """
- Get the navigation toolbar button status: 'PAN', 'ZOOM', or None.
- """
- return self._navigate_mode
-
- def set_navigate_mode(self, b):
- """
- Set the navigation toolbar button status.
-
- .. warning::
- This is not a user-API function.
-
- """
- self._navigate_mode = b
-
- def _get_view(self):
- """
- Save information required to reproduce the current view.
-
- This method is called before a view is changed, such as during a pan or zoom
- initiated by the user. It returns an opaque object that describes the current
- view, in a format compatible with :meth:`_set_view`.
-
- The default implementation saves the view limits and autoscaling state.
- Subclasses may override this as needed, as long as :meth:`_set_view` is also
- adjusted accordingly.
- """
- return {
- "xlim": self.get_xlim(), "autoscalex_on": self.get_autoscalex_on(),
- "ylim": self.get_ylim(), "autoscaley_on": self.get_autoscaley_on(),
- }
-
- def _set_view(self, view):
- """
- Apply a previously saved view.
-
- This method is called when restoring a view (with the return value of
- :meth:`_get_view` as argument), such as with the navigation buttons.
-
- Subclasses that override :meth:`_get_view` also need to override this method
- accordingly.
- """
- self.set(**view)
-
- def _prepare_view_from_bbox(self, bbox, direction='in',
- mode=None, twinx=False, twiny=False):
- """
- Helper function to prepare the new bounds from a bbox.
-
- This helper function returns the new x and y bounds from the zoom
- bbox. This a convenience method to abstract the bbox logic
- out of the base setter.
- """
- if len(bbox) == 3:
- xp, yp, scl = bbox # Zooming code
- if scl == 0: # Should not happen
- scl = 1.
- if scl > 1:
- direction = 'in'
- else:
- direction = 'out'
- scl = 1/scl
- # get the limits of the axes
- (xmin, ymin), (xmax, ymax) = self.transData.transform(
- np.transpose([self.get_xlim(), self.get_ylim()]))
- # set the range
- xwidth = xmax - xmin
- ywidth = ymax - ymin
- xcen = (xmax + xmin)*.5
- ycen = (ymax + ymin)*.5
- xzc = (xp*(scl - 1) + xcen)/scl
- yzc = (yp*(scl - 1) + ycen)/scl
- bbox = [xzc - xwidth/2./scl, yzc - ywidth/2./scl,
- xzc + xwidth/2./scl, yzc + ywidth/2./scl]
- elif len(bbox) != 4:
- # should be len 3 or 4 but nothing else
- _api.warn_external(
- "Warning in _set_view_from_bbox: bounding box is not a tuple "
- "of length 3 or 4. Ignoring the view change.")
- return
-
- # Original limits.
- xmin0, xmax0 = self.get_xbound()
- ymin0, ymax0 = self.get_ybound()
- # The zoom box in screen coords.
- startx, starty, stopx, stopy = bbox
- # Convert to data coords.
- (startx, starty), (stopx, stopy) = self.transData.inverted().transform(
- [(startx, starty), (stopx, stopy)])
- # Clip to axes limits.
- xmin, xmax = np.clip(sorted([startx, stopx]), xmin0, xmax0)
- ymin, ymax = np.clip(sorted([starty, stopy]), ymin0, ymax0)
- # Don't double-zoom twinned axes or if zooming only the other axis.
- if twinx or mode == "y":
- xmin, xmax = xmin0, xmax0
- if twiny or mode == "x":
- ymin, ymax = ymin0, ymax0
-
- if direction == "in":
- new_xbound = xmin, xmax
- new_ybound = ymin, ymax
-
- elif direction == "out":
- x_trf = self.xaxis.get_transform()
- sxmin0, sxmax0, sxmin, sxmax = x_trf.transform(
- [xmin0, xmax0, xmin, xmax]) # To screen space.
- factor = (sxmax0 - sxmin0) / (sxmax - sxmin) # Unzoom factor.
- # Move original bounds away by
- # (factor) x (distance between unzoom box and Axes bbox).
- sxmin1 = sxmin0 - factor * (sxmin - sxmin0)
- sxmax1 = sxmax0 + factor * (sxmax0 - sxmax)
- # And back to data space.
- new_xbound = x_trf.inverted().transform([sxmin1, sxmax1])
-
- y_trf = self.yaxis.get_transform()
- symin0, symax0, symin, symax = y_trf.transform(
- [ymin0, ymax0, ymin, ymax])
- factor = (symax0 - symin0) / (symax - symin)
- symin1 = symin0 - factor * (symin - symin0)
- symax1 = symax0 + factor * (symax0 - symax)
- new_ybound = y_trf.inverted().transform([symin1, symax1])
-
- return new_xbound, new_ybound
-
- def _set_view_from_bbox(self, bbox, direction='in',
- mode=None, twinx=False, twiny=False):
- """
- Update view from a selection bbox.
-
- .. note::
-
- Intended to be overridden by new projection types, but if not, the
- default implementation sets the view limits to the bbox directly.
-
- Parameters
- ----------
- bbox : 4-tuple or 3 tuple
- * If bbox is a 4 tuple, it is the selected bounding box limits,
- in *display* coordinates.
- * If bbox is a 3 tuple, it is an (xp, yp, scl) triple, where
- (xp, yp) is the center of zooming and scl the scale factor to
- zoom by.
-
- direction : str
- The direction to apply the bounding box.
- * `'in'` - The bounding box describes the view directly, i.e.,
- it zooms in.
- * `'out'` - The bounding box describes the size to make the
- existing view, i.e., it zooms out.
-
- mode : str or None
- The selection mode, whether to apply the bounding box in only the
- `'x'` direction, `'y'` direction or both (`None`).
-
- twinx : bool
- Whether this axis is twinned in the *x*-direction.
-
- twiny : bool
- Whether this axis is twinned in the *y*-direction.
- """
- new_xbound, new_ybound = self._prepare_view_from_bbox(
- bbox, direction=direction, mode=mode, twinx=twinx, twiny=twiny)
- if not twinx and mode != "y":
- self.set_xbound(new_xbound)
- self.set_autoscalex_on(False)
- if not twiny and mode != "x":
- self.set_ybound(new_ybound)
- self.set_autoscaley_on(False)
-
- def start_pan(self, x, y, button):
- """
- Called when a pan operation has started.
-
- Parameters
- ----------
- x, y : float
- The mouse coordinates in display coords.
- button : `.MouseButton`
- The pressed mouse button.
-
- Notes
- -----
- This is intended to be overridden by new projection types.
- """
- self._pan_start = types.SimpleNamespace(
- lim=self.viewLim.frozen(),
- trans=self.transData.frozen(),
- trans_inverse=self.transData.inverted().frozen(),
- bbox=self.bbox.frozen(),
- x=x,
- y=y)
-
- def end_pan(self):
- """
- Called when a pan operation completes (when the mouse button is up.)
-
- Notes
- -----
- This is intended to be overridden by new projection types.
- """
- del self._pan_start
-
- def _get_pan_points(self, button, key, x, y):
- """
- Helper function to return the new points after a pan.
-
- This helper function returns the points on the axis after a pan has
- occurred. This is a convenience method to abstract the pan logic
- out of the base setter.
- """
- def format_deltas(key, dx, dy):
- if key == 'control':
- if abs(dx) > abs(dy):
- dy = dx
- else:
- dx = dy
- elif key == 'x':
- dy = 0
- elif key == 'y':
- dx = 0
- elif key == 'shift':
- if 2 * abs(dx) < abs(dy):
- dx = 0
- elif 2 * abs(dy) < abs(dx):
- dy = 0
- elif abs(dx) > abs(dy):
- dy = dy / abs(dy) * abs(dx)
- else:
- dx = dx / abs(dx) * abs(dy)
- return dx, dy
-
- p = self._pan_start
- dx = x - p.x
- dy = y - p.y
- if dx == dy == 0:
- return
- if button == 1:
- dx, dy = format_deltas(key, dx, dy)
- result = p.bbox.translated(-dx, -dy).transformed(p.trans_inverse)
- elif button == 3:
- try:
- dx = -dx / self.bbox.width
- dy = -dy / self.bbox.height
- dx, dy = format_deltas(key, dx, dy)
- if self.get_aspect() != 'auto':
- dx = dy = 0.5 * (dx + dy)
- alpha = np.power(10.0, (dx, dy))
- start = np.array([p.x, p.y])
- oldpoints = p.lim.transformed(p.trans)
- newpoints = start + alpha * (oldpoints - start)
- result = (mtransforms.Bbox(newpoints)
- .transformed(p.trans_inverse))
- except OverflowError:
- _api.warn_external('Overflow while panning')
- return
- else:
- return
-
- valid = np.isfinite(result.transformed(p.trans))
- points = result.get_points().astype(object)
- # Just ignore invalid limits (typically, underflow in log-scale).
- points[~valid] = None
- return points
-
- def drag_pan(self, button, key, x, y):
- """
- Called when the mouse moves during a pan operation.
-
- Parameters
- ----------
- button : `.MouseButton`
- The pressed mouse button.
- key : str or None
- The pressed key, if any.
- x, y : float
- The mouse coordinates in display coords.
-
- Notes
- -----
- This is intended to be overridden by new projection types.
- """
- points = self._get_pan_points(button, key, x, y)
- if points is not None:
- self.set_xlim(points[:, 0])
- self.set_ylim(points[:, 1])
-
- def get_children(self):
- # docstring inherited.
- return [
- *self._children,
- *self.spines.values(),
- *self._axis_map.values(),
- self.title, self._left_title, self._right_title,
- *self.child_axes,
- *([self.legend_] if self.legend_ is not None else []),
- self.patch,
- ]
-
- def contains(self, mouseevent):
- # docstring inherited.
- return self.patch.contains(mouseevent)
-
- def contains_point(self, point):
- """
- Return whether *point* (pair of pixel coordinates) is inside the Axes
- patch.
- """
- return self.patch.contains_point(point, radius=1.0)
-
- def get_default_bbox_extra_artists(self):
- """
- Return a default list of artists that are used for the bounding box
- calculation.
-
- Artists are excluded either by not being visible or
- ``artist.set_in_layout(False)``.
- """
-
- artists = self.get_children()
-
- for axis in self._axis_map.values():
- # axis tight bboxes are calculated separately inside
- # Axes.get_tightbbox() using for_layout_only=True
- artists.remove(axis)
- if not (self.axison and self._frameon):
- # don't do bbox on spines if frame not on.
- for spine in self.spines.values():
- artists.remove(spine)
-
- artists.remove(self.title)
- artists.remove(self._left_title)
- artists.remove(self._right_title)
-
- # always include types that do not internally implement clipping
- # to Axes. may have clip_on set to True and clip_box equivalent
- # to ax.bbox but then ignore these properties during draws.
- noclip = (_AxesBase, maxis.Axis,
- offsetbox.AnnotationBbox, offsetbox.OffsetBox)
- return [a for a in artists if a.get_visible() and a.get_in_layout()
- and (isinstance(a, noclip) or not a._fully_clipped_to_axes())]
-
- @_api.make_keyword_only("3.8", "call_axes_locator")
- def get_tightbbox(self, renderer=None, call_axes_locator=True,
- bbox_extra_artists=None, *, for_layout_only=False):
- """
- Return the tight bounding box of the Axes, including axis and their
- decorators (xlabel, title, etc).
-
- Artists that have ``artist.set_in_layout(False)`` are not included
- in the bbox.
-
- Parameters
- ----------
- renderer : `.RendererBase` subclass
- renderer that will be used to draw the figures (i.e.
- ``fig.canvas.get_renderer()``)
-
- bbox_extra_artists : list of `.Artist` or ``None``
- List of artists to include in the tight bounding box. If
- ``None`` (default), then all artist children of the Axes are
- included in the tight bounding box.
-
- call_axes_locator : bool, default: True
- If *call_axes_locator* is ``False``, it does not call the
- ``_axes_locator`` attribute, which is necessary to get the correct
- bounding box. ``call_axes_locator=False`` can be used if the
- caller is only interested in the relative size of the tightbbox
- compared to the Axes bbox.
-
- for_layout_only : default: False
- The bounding box will *not* include the x-extent of the title and
- the xlabel, or the y-extent of the ylabel.
-
- Returns
- -------
- `.BboxBase`
- Bounding box in figure pixel coordinates.
-
- See Also
- --------
- matplotlib.axes.Axes.get_window_extent
- matplotlib.axis.Axis.get_tightbbox
- matplotlib.spines.Spine.get_window_extent
- """
-
- bb = []
- if renderer is None:
- renderer = self.figure._get_renderer()
-
- if not self.get_visible():
- return None
-
- locator = self.get_axes_locator()
- self.apply_aspect(
- locator(self, renderer) if locator and call_axes_locator else None)
-
- for axis in self._axis_map.values():
- if self.axison and axis.get_visible():
- ba = martist._get_tightbbox_for_layout_only(axis, renderer)
- if ba:
- bb.append(ba)
- self._update_title_position(renderer)
- axbbox = self.get_window_extent(renderer)
- bb.append(axbbox)
-
- for title in [self.title, self._left_title, self._right_title]:
- if title.get_visible():
- bt = title.get_window_extent(renderer)
- if for_layout_only and bt.width > 0:
- # make the title bbox 1 pixel wide so its width
- # is not accounted for in bbox calculations in
- # tight/constrained_layout
- bt.x0 = (bt.x0 + bt.x1) / 2 - 0.5
- bt.x1 = bt.x0 + 1.0
- bb.append(bt)
-
- bbox_artists = bbox_extra_artists
- if bbox_artists is None:
- bbox_artists = self.get_default_bbox_extra_artists()
-
- for a in bbox_artists:
- bbox = a.get_tightbbox(renderer)
- if (bbox is not None
- and 0 < bbox.width < np.inf
- and 0 < bbox.height < np.inf):
- bb.append(bbox)
- return mtransforms.Bbox.union(
- [b for b in bb if b.width != 0 or b.height != 0])
-
- def _make_twin_axes(self, *args, **kwargs):
- """Make a twinx Axes of self. This is used for twinx and twiny."""
- if 'sharex' in kwargs and 'sharey' in kwargs:
- # The following line is added in v2.2 to avoid breaking Seaborn,
- # which currently uses this internal API.
- if kwargs["sharex"] is not self and kwargs["sharey"] is not self:
- raise ValueError("Twinned Axes may share only one axis")
- ss = self.get_subplotspec()
- if ss:
- twin = self.figure.add_subplot(ss, *args, **kwargs)
- else:
- twin = self.figure.add_axes(
- self.get_position(True), *args, **kwargs,
- axes_locator=_TransformedBoundsLocator(
- [0, 0, 1, 1], self.transAxes))
- self.set_adjustable('datalim')
- twin.set_adjustable('datalim')
- self._twinned_axes.join(self, twin)
- return twin
-
- def twinx(self):
- """
- Create a twin Axes sharing the xaxis.
-
- Create a new Axes with an invisible x-axis and an independent
- y-axis positioned opposite to the original one (i.e. at right). The
- x-axis autoscale setting will be inherited from the original
- Axes. To ensure that the tick marks of both y-axes align, see
- `~matplotlib.ticker.LinearLocator`.
-
- Returns
- -------
- Axes
- The newly created Axes instance
-
- Notes
- -----
- For those who are 'picking' artists while using twinx, pick
- events are only called for the artists in the top-most Axes.
- """
- ax2 = self._make_twin_axes(sharex=self)
- ax2.yaxis.tick_right()
- ax2.yaxis.set_label_position('right')
- ax2.yaxis.set_offset_position('right')
- ax2.set_autoscalex_on(self.get_autoscalex_on())
- self.yaxis.tick_left()
- ax2.xaxis.set_visible(False)
- ax2.patch.set_visible(False)
- ax2.xaxis.units = self.xaxis.units
- return ax2
-
- def twiny(self):
- """
- Create a twin Axes sharing the yaxis.
-
- Create a new Axes with an invisible y-axis and an independent
- x-axis positioned opposite to the original one (i.e. at top). The
- y-axis autoscale setting will be inherited from the original Axes.
- To ensure that the tick marks of both x-axes align, see
- `~matplotlib.ticker.LinearLocator`.
-
- Returns
- -------
- Axes
- The newly created Axes instance
-
- Notes
- -----
- For those who are 'picking' artists while using twiny, pick
- events are only called for the artists in the top-most Axes.
- """
- ax2 = self._make_twin_axes(sharey=self)
- ax2.xaxis.tick_top()
- ax2.xaxis.set_label_position('top')
- ax2.set_autoscaley_on(self.get_autoscaley_on())
- self.xaxis.tick_bottom()
- ax2.yaxis.set_visible(False)
- ax2.patch.set_visible(False)
- ax2.yaxis.units = self.yaxis.units
- return ax2
-
- def get_shared_x_axes(self):
- """Return an immutable view on the shared x-axes Grouper."""
- return cbook.GrouperView(self._shared_axes["x"])
-
- def get_shared_y_axes(self):
- """Return an immutable view on the shared y-axes Grouper."""
- return cbook.GrouperView(self._shared_axes["y"])
-
- def label_outer(self, remove_inner_ticks=False):
- """
- Only show "outer" labels and tick labels.
-
- x-labels are only kept for subplots on the last row (or first row, if
- labels are on the top side); y-labels only for subplots on the first
- column (or last column, if labels are on the right side).
-
- Parameters
- ----------
- remove_inner_ticks : bool, default: False
- If True, remove the inner ticks as well (not only tick labels).
-
- .. versionadded:: 3.8
- """
- self._label_outer_xaxis(skip_non_rectangular_axes=False,
- remove_inner_ticks=remove_inner_ticks)
- self._label_outer_yaxis(skip_non_rectangular_axes=False,
- remove_inner_ticks=remove_inner_ticks)
-
- def _label_outer_xaxis(self, *, skip_non_rectangular_axes,
- remove_inner_ticks=False):
- # see documentation in label_outer.
- if skip_non_rectangular_axes and not isinstance(self.patch,
- mpl.patches.Rectangle):
- return
- ss = self.get_subplotspec()
- if not ss:
- return
- label_position = self.xaxis.get_label_position()
- if not ss.is_first_row(): # Remove top label/ticklabels/offsettext.
- if label_position == "top":
- self.set_xlabel("")
- top_kw = {'top': False} if remove_inner_ticks else {}
- self.xaxis.set_tick_params(
- which="both", labeltop=False, **top_kw)
- if self.xaxis.offsetText.get_position()[1] == 1:
- self.xaxis.offsetText.set_visible(False)
- if not ss.is_last_row(): # Remove bottom label/ticklabels/offsettext.
- if label_position == "bottom":
- self.set_xlabel("")
- bottom_kw = {'bottom': False} if remove_inner_ticks else {}
- self.xaxis.set_tick_params(
- which="both", labelbottom=False, **bottom_kw)
- if self.xaxis.offsetText.get_position()[1] == 0:
- self.xaxis.offsetText.set_visible(False)
-
- def _label_outer_yaxis(self, *, skip_non_rectangular_axes,
- remove_inner_ticks=False):
- # see documentation in label_outer.
- if skip_non_rectangular_axes and not isinstance(self.patch,
- mpl.patches.Rectangle):
- return
- ss = self.get_subplotspec()
- if not ss:
- return
- label_position = self.yaxis.get_label_position()
- if not ss.is_first_col(): # Remove left label/ticklabels/offsettext.
- if label_position == "left":
- self.set_ylabel("")
- left_kw = {'left': False} if remove_inner_ticks else {}
- self.yaxis.set_tick_params(
- which="both", labelleft=False, **left_kw)
- if self.yaxis.offsetText.get_position()[0] == 0:
- self.yaxis.offsetText.set_visible(False)
- if not ss.is_last_col(): # Remove right label/ticklabels/offsettext.
- if label_position == "right":
- self.set_ylabel("")
- right_kw = {'right': False} if remove_inner_ticks else {}
- self.yaxis.set_tick_params(
- which="both", labelright=False, **right_kw)
- if self.yaxis.offsetText.get_position()[0] == 1:
- self.yaxis.offsetText.set_visible(False)
-
-
-def _draw_rasterized(figure, artists, renderer):
- """
- A helper function for rasterizing the list of artists.
-
- The bookkeeping to track if we are or are not in rasterizing mode
- with the mixed-mode backends is relatively complicated and is now
- handled in the matplotlib.artist.allow_rasterization decorator.
-
- This helper defines the absolute minimum methods and attributes on a
- shim class to be compatible with that decorator and then uses it to
- rasterize the list of artists.
-
- This is maybe too-clever, but allows us to re-use the same code that is
- used on normal artists to participate in the "are we rasterizing"
- accounting.
-
- Please do not use this outside of the "rasterize below a given zorder"
- functionality of Axes.
-
- Parameters
- ----------
- figure : matplotlib.figure.Figure
- The figure all of the artists belong to (not checked). We need this
- because we can at the figure level suppress composition and insert each
- rasterized artist as its own image.
-
- artists : List[matplotlib.artist.Artist]
- The list of Artists to be rasterized. These are assumed to all
- be in the same Figure.
-
- renderer : matplotlib.backendbases.RendererBase
- The currently active renderer
-
- Returns
- -------
- None
-
- """
- class _MinimalArtist:
- def get_rasterized(self):
- return True
-
- def get_agg_filter(self):
- return None
-
- def __init__(self, figure, artists):
- self.figure = figure
- self.artists = artists
-
- @martist.allow_rasterization
- def draw(self, renderer):
- for a in self.artists:
- a.draw(renderer)
-
- return _MinimalArtist(figure, artists).draw(renderer)
diff --git a/contrib/python/matplotlib/py3/matplotlib/axes/_base.pyi b/contrib/python/matplotlib/py3/matplotlib/axes/_base.pyi
deleted file mode 100644
index 6adbb3e6f0..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/axes/_base.pyi
+++ /dev/null
@@ -1,453 +0,0 @@
-import matplotlib.artist as martist
-
-import datetime
-from collections.abc import Callable, Iterable, Iterator, Sequence
-from matplotlib import cbook
-from matplotlib.artist import Artist
-from matplotlib.axis import XAxis, YAxis, Tick
-from matplotlib.backend_bases import RendererBase, MouseButton, MouseEvent
-from matplotlib.cbook import CallbackRegistry
-from matplotlib.container import Container
-from matplotlib.collections import Collection
-from matplotlib.cm import ScalarMappable
-from matplotlib.legend import Legend
-from matplotlib.lines import Line2D
-from matplotlib.gridspec import SubplotSpec, GridSpec
-from matplotlib.figure import Figure
-from matplotlib.image import AxesImage
-from matplotlib.patches import Patch
-from matplotlib.scale import ScaleBase
-from matplotlib.spines import Spines
-from matplotlib.table import Table
-from matplotlib.text import Text
-from matplotlib.transforms import Transform, Bbox
-
-from cycler import Cycler
-
-import numpy as np
-from numpy.typing import ArrayLike
-from typing import Any, Literal, TypeVar, overload
-from matplotlib.typing import ColorType
-
-_T = TypeVar("_T", bound=Artist)
-
-class _axis_method_wrapper:
- attr_name: str
- method_name: str
- __doc__: str
- def __init__(
- self, attr_name: str, method_name: str, *, doc_sub: dict[str, str] | None = ...
- ) -> None: ...
- def __set_name__(self, owner: Any, name: str) -> None: ...
-
-class _AxesBase(martist.Artist):
- name: str
- patch: Patch
- spines: Spines
- fmt_xdata: Callable[[float], str] | None
- fmt_ydata: Callable[[float], str] | None
- xaxis: XAxis
- yaxis: YAxis
- bbox: Bbox
- dataLim: Bbox
- transAxes: Transform
- transScale: Transform
- transLimits: Transform
- transData: Transform
- ignore_existing_data_limits: bool
- axison: bool
- containers: list[Container]
- callbacks: CallbackRegistry
- child_axes: list[_AxesBase]
- legend_: Legend | None
- title: Text
- _projection_init: Any
-
- def __init__(
- self,
- fig: Figure,
- *args: tuple[float, float, float, float] | Bbox | int,
- facecolor: ColorType | None = ...,
- frameon: bool = ...,
- sharex: _AxesBase | None = ...,
- sharey: _AxesBase | None = ...,
- label: Any = ...,
- xscale: str | ScaleBase | None = ...,
- yscale: str | ScaleBase | None = ...,
- box_aspect: float | None = ...,
- **kwargs
- ) -> None: ...
- def get_subplotspec(self) -> SubplotSpec | None: ...
- def set_subplotspec(self, subplotspec: SubplotSpec) -> None: ...
- def get_gridspec(self) -> GridSpec | None: ...
- def set_figure(self, fig: Figure) -> None: ...
- @property
- def viewLim(self) -> Bbox: ...
- def get_xaxis_transform(
- self, which: Literal["grid", "tick1", "tick2"] = ...
- ) -> Transform: ...
- def get_xaxis_text1_transform(
- self, pad_points: float
- ) -> tuple[
- Transform,
- Literal["center", "top", "bottom", "baseline", "center_baseline"],
- Literal["center", "left", "right"],
- ]: ...
- def get_xaxis_text2_transform(
- self, pad_points
- ) -> tuple[
- Transform,
- Literal["center", "top", "bottom", "baseline", "center_baseline"],
- Literal["center", "left", "right"],
- ]: ...
- def get_yaxis_transform(
- self, which: Literal["grid", "tick1", "tick2"] = ...
- ) -> Transform: ...
- def get_yaxis_text1_transform(
- self, pad_points
- ) -> tuple[
- Transform,
- Literal["center", "top", "bottom", "baseline", "center_baseline"],
- Literal["center", "left", "right"],
- ]: ...
- def get_yaxis_text2_transform(
- self, pad_points
- ) -> tuple[
- Transform,
- Literal["center", "top", "bottom", "baseline", "center_baseline"],
- Literal["center", "left", "right"],
- ]: ...
- def get_position(self, original: bool = ...) -> Bbox: ...
- def set_position(
- self,
- pos: Bbox | tuple[float, float, float, float],
- which: Literal["both", "active", "original"] = ...,
- ) -> None: ...
- def reset_position(self) -> None: ...
- def set_axes_locator(
- self, locator: Callable[[_AxesBase, RendererBase], Bbox]
- ) -> None: ...
- def get_axes_locator(self) -> Callable[[_AxesBase, RendererBase], Bbox]: ...
- def sharex(self, other: _AxesBase) -> None: ...
- def sharey(self, other: _AxesBase) -> None: ...
- def clear(self) -> None: ...
- def cla(self) -> None: ...
-
- class ArtistList(Sequence[_T]):
- def __init__(
- self,
- axes: _AxesBase,
- prop_name: str,
- valid_types: type | Iterable[type] | None = ...,
- invalid_types: type | Iterable[type] | None = ...,
- ) -> None: ...
- def __len__(self) -> int: ...
- def __iter__(self) -> Iterator[_T]: ...
- @overload
- def __getitem__(self, key: int) -> _T: ...
- @overload
- def __getitem__(self, key: slice) -> list[_T]: ...
-
- @overload
- def __add__(self, other: _AxesBase.ArtistList[_T]) -> list[_T]: ...
- @overload
- def __add__(self, other: list[Any]) -> list[Any]: ...
- @overload
- def __add__(self, other: tuple[Any]) -> tuple[Any]: ...
-
- @overload
- def __radd__(self, other: _AxesBase.ArtistList[_T]) -> list[_T]: ...
- @overload
- def __radd__(self, other: list[Any]) -> list[Any]: ...
- @overload
- def __radd__(self, other: tuple[Any]) -> tuple[Any]: ...
-
- @property
- def artists(self) -> _AxesBase.ArtistList[Artist]: ...
- @property
- def collections(self) -> _AxesBase.ArtistList[Collection]: ...
- @property
- def images(self) -> _AxesBase.ArtistList[AxesImage]: ...
- @property
- def lines(self) -> _AxesBase.ArtistList[Line2D]: ...
- @property
- def patches(self) -> _AxesBase.ArtistList[Patch]: ...
- @property
- def tables(self) -> _AxesBase.ArtistList[Table]: ...
- @property
- def texts(self) -> _AxesBase.ArtistList[Text]: ...
- def get_facecolor(self) -> ColorType: ...
- def set_facecolor(self, color: ColorType | None) -> None: ...
- @overload
- def set_prop_cycle(self, cycler: Cycler) -> None: ...
- @overload
- def set_prop_cycle(self, label: str, values: Iterable[Any]) -> None: ...
- @overload
- def set_prop_cycle(self, **kwargs: Iterable[Any]) -> None: ...
- def get_aspect(self) -> float | Literal["auto"]: ...
- def set_aspect(
- self,
- aspect: float | Literal["auto", "equal"],
- adjustable: Literal["box", "datalim"] | None = ...,
- anchor: str | tuple[float, float] | None = ...,
- share: bool = ...,
- ) -> None: ...
- def get_adjustable(self) -> Literal["box", "datalim"]: ...
- def set_adjustable(
- self, adjustable: Literal["box", "datalim"], share: bool = ...
- ) -> None: ...
- def get_box_aspect(self) -> float | None: ...
- def set_box_aspect(self, aspect: float | None = ...) -> None: ...
- def get_anchor(self) -> str | tuple[float, float]: ...
- def set_anchor(
- self, anchor: str | tuple[float, float], share: bool = ...
- ) -> None: ...
- def get_data_ratio(self) -> float: ...
- def apply_aspect(self, position: Bbox | None = ...) -> None: ...
- @overload
- def axis(
- self,
- arg: tuple[float, float, float, float] | bool | str | None = ...,
- /,
- *,
- emit: bool = ...
- ) -> tuple[float, float, float, float]: ...
- @overload
- def axis(
- self,
- *,
- emit: bool = ...,
- xmin: float | None = ...,
- xmax: float | None = ...,
- ymin: float | None = ...,
- ymax: float | None = ...
- ) -> tuple[float, float, float, float]: ...
- def get_legend(self) -> Legend: ...
- def get_images(self) -> list[AxesImage]: ...
- def get_lines(self) -> list[Line2D]: ...
- def get_xaxis(self) -> XAxis: ...
- def get_yaxis(self) -> YAxis: ...
- def has_data(self) -> bool: ...
- def add_artist(self, a: Artist) -> Artist: ...
- def add_child_axes(self, ax: _AxesBase) -> _AxesBase: ...
- def add_collection(
- self, collection: Collection, autolim: bool = ...
- ) -> Collection: ...
- def add_image(self, image: AxesImage) -> AxesImage: ...
- def add_line(self, line: Line2D) -> Line2D: ...
- def add_patch(self, p: Patch) -> Patch: ...
- def add_table(self, tab: Table) -> Table: ...
- def add_container(self, container: Container) -> Container: ...
- def relim(self, visible_only: bool = ...) -> None: ...
- def update_datalim(
- self, xys: ArrayLike, updatex: bool = ..., updatey: bool = ...
- ) -> None: ...
- def in_axes(self, mouseevent: MouseEvent) -> bool: ...
- def get_autoscale_on(self) -> bool: ...
- def set_autoscale_on(self, b: bool) -> None: ...
- @property
- def use_sticky_edges(self) -> bool: ...
- @use_sticky_edges.setter
- def use_sticky_edges(self, b: bool) -> None: ...
- def set_xmargin(self, m: float) -> None: ...
- def set_ymargin(self, m: float) -> None: ...
-
- # Probably could be made better with overloads
- def margins(
- self,
- *margins: float,
- x: float | None = ...,
- y: float | None = ...,
- tight: bool | None = ...
- ) -> tuple[float, float] | None: ...
- def set_rasterization_zorder(self, z: float | None) -> None: ...
- def get_rasterization_zorder(self) -> float | None: ...
- def autoscale(
- self,
- enable: bool = ...,
- axis: Literal["both", "x", "y"] = ...,
- tight: bool | None = ...,
- ) -> None: ...
- def autoscale_view(
- self, tight: bool | None = ..., scalex: bool = ..., scaley: bool = ...
- ) -> None: ...
- def draw_artist(self, a: Artist) -> None: ...
- def redraw_in_frame(self) -> None: ...
- def get_frame_on(self) -> bool: ...
- def set_frame_on(self, b: bool) -> None: ...
- def get_axisbelow(self) -> bool | Literal["line"]: ...
- def set_axisbelow(self, b: bool | Literal["line"]) -> None: ...
- def grid(
- self,
- visible: bool | None = ...,
- which: Literal["major", "minor", "both"] = ...,
- axis: Literal["both", "x", "y"] = ...,
- **kwargs
- ) -> None: ...
- def ticklabel_format(
- self,
- *,
- axis: Literal["both", "x", "y"] = ...,
- style: Literal["", "sci", "scientific", "plain"] = ...,
- scilimits: tuple[int, int] | None = ...,
- useOffset: bool | float | None = ...,
- useLocale: bool | None = ...,
- useMathText: bool | None = ...
- ) -> None: ...
- def locator_params(
- self, axis: Literal["both", "x", "y"] = ..., tight: bool | None = ..., **kwargs
- ) -> None: ...
- def tick_params(self, axis: Literal["both", "x", "y"] = ..., **kwargs) -> None: ...
- def set_axis_off(self) -> None: ...
- def set_axis_on(self) -> None: ...
- def get_xlabel(self) -> str: ...
- def set_xlabel(
- self,
- xlabel: str,
- fontdict: dict[str, Any] | None = ...,
- labelpad: float | None = ...,
- *,
- loc: Literal["left", "center", "right"] | None = ...,
- **kwargs
- ) -> Text: ...
- def invert_xaxis(self) -> None: ...
- def get_xbound(self) -> tuple[float, float]: ...
- def set_xbound(
- self, lower: float | None = ..., upper: float | None = ...
- ) -> None: ...
- def get_xlim(self) -> tuple[float, float]: ...
- def set_xlim(
- self,
- left: float | tuple[float, float] | None = ...,
- right: float | None = ...,
- *,
- emit: bool = ...,
- auto: bool | None = ...,
- xmin: float | None = ...,
- xmax: float | None = ...
- ) -> tuple[float, float]: ...
- def get_ylabel(self) -> str: ...
- def set_ylabel(
- self,
- ylabel: str,
- fontdict: dict[str, Any] | None = ...,
- labelpad: float | None = ...,
- *,
- loc: Literal["bottom", "center", "top"] | None = ...,
- **kwargs
- ) -> Text: ...
- def invert_yaxis(self) -> None: ...
- def get_ybound(self) -> tuple[float, float]: ...
- def set_ybound(
- self, lower: float | None = ..., upper: float | None = ...
- ) -> None: ...
- def get_ylim(self) -> tuple[float, float]: ...
- def set_ylim(
- self,
- bottom: float | tuple[float, float] | None = ...,
- top: float | None = ...,
- *,
- emit: bool = ...,
- auto: bool | None = ...,
- ymin: float | None = ...,
- ymax: float | None = ...
- ) -> tuple[float, float]: ...
- def format_xdata(self, x: float) -> str: ...
- def format_ydata(self, y: float) -> str: ...
- def format_coord(self, x: float, y: float) -> str: ...
- def minorticks_on(self) -> None: ...
- def minorticks_off(self) -> None: ...
- def can_zoom(self) -> bool: ...
- def can_pan(self) -> bool: ...
- def get_navigate(self) -> bool: ...
- def set_navigate(self, b: bool) -> None: ...
- def get_navigate_mode(self) -> Literal["PAN", "ZOOM"] | None: ...
- def set_navigate_mode(self, b: Literal["PAN", "ZOOM"] | None) -> None: ...
- def start_pan(self, x: float, y: float, button: MouseButton) -> None: ...
- def end_pan(self) -> None: ...
- def drag_pan(
- self, button: MouseButton, key: str | None, x: float, y: float
- ) -> None: ...
- def get_children(self) -> list[Artist]: ...
- def contains_point(self, point: tuple[int, int]) -> bool: ...
- def get_default_bbox_extra_artists(self) -> list[Artist]: ...
- def get_tightbbox(
- self,
- renderer: RendererBase | None = ...,
- *,
- call_axes_locator: bool = ...,
- bbox_extra_artists: Sequence[Artist] | None = ...,
- for_layout_only: bool = ...
- ) -> Bbox | None: ...
- def twinx(self) -> _AxesBase: ...
- def twiny(self) -> _AxesBase: ...
- def get_shared_x_axes(self) -> cbook.GrouperView: ...
- def get_shared_y_axes(self) -> cbook.GrouperView: ...
- def label_outer(self, remove_inner_ticks: bool = ...) -> None: ...
-
- # The methods underneath this line are added via the `_axis_method_wrapper` class
- # Initially they are set to an object, but that object uses `__set_name__` to override
- # itself with a method modified from the Axis methods for the x or y Axis.
- # As such, they are typed according to the resultant method rather than as that object.
-
- def get_xgridlines(self) -> list[Line2D]: ...
- def get_xticklines(self, minor: bool = ...) -> list[Line2D]: ...
- def get_ygridlines(self) -> list[Line2D]: ...
- def get_yticklines(self, minor: bool = ...) -> list[Line2D]: ...
- def _sci(self, im: ScalarMappable) -> None: ...
- def get_autoscalex_on(self) -> bool: ...
- def get_autoscaley_on(self) -> bool: ...
- def set_autoscalex_on(self, b: bool) -> None: ...
- def set_autoscaley_on(self, b: bool) -> None: ...
- def xaxis_inverted(self) -> bool: ...
- def get_xscale(self) -> str: ...
- def set_xscale(self, value: str | ScaleBase, **kwargs) -> None: ...
- def get_xticks(self, *, minor: bool = ...) -> np.ndarray: ...
- def set_xticks(
- self,
- ticks: ArrayLike,
- labels: Iterable[str] | None = ...,
- *,
- minor: bool = ...,
- **kwargs
- ) -> list[Tick]: ...
- def get_xmajorticklabels(self) -> list[Text]: ...
- def get_xminorticklabels(self) -> list[Text]: ...
- def get_xticklabels(
- self, minor: bool = ..., which: Literal["major", "minor", "both"] | None = ...
- ) -> list[Text]: ...
- def set_xticklabels(
- self,
- labels: Iterable[str | Text],
- *,
- minor: bool = ...,
- fontdict: dict[str, Any] | None = ...,
- **kwargs
- ) -> list[Text]: ...
- def yaxis_inverted(self) -> bool: ...
- def get_yscale(self) -> str: ...
- def set_yscale(self, value: str | ScaleBase, **kwargs) -> None: ...
- def get_yticks(self, *, minor: bool = ...) -> np.ndarray: ...
- def set_yticks(
- self,
- ticks: ArrayLike,
- labels: Iterable[str] | None = ...,
- *,
- minor: bool = ...,
- **kwargs
- ) -> list[Tick]: ...
- def get_ymajorticklabels(self) -> list[Text]: ...
- def get_yminorticklabels(self) -> list[Text]: ...
- def get_yticklabels(
- self, minor: bool = ..., which: Literal["major", "minor", "both"] | None = ...
- ) -> list[Text]: ...
- def set_yticklabels(
- self,
- labels: Iterable[str | Text],
- *,
- minor: bool = ...,
- fontdict: dict[str, Any] | None = ...,
- **kwargs
- ) -> list[Text]: ...
- def xaxis_date(self, tz: str | datetime.tzinfo | None = ...) -> None: ...
- def yaxis_date(self, tz: str | datetime.tzinfo | None = ...) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/axes/_secondary_axes.py b/contrib/python/matplotlib/py3/matplotlib/axes/_secondary_axes.py
deleted file mode 100644
index f0ab4f3e3b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/axes/_secondary_axes.py
+++ /dev/null
@@ -1,283 +0,0 @@
-import numbers
-
-import numpy as np
-
-from matplotlib import _api, _docstring
-import matplotlib.ticker as mticker
-from matplotlib.axes._base import _AxesBase, _TransformedBoundsLocator
-from matplotlib.axis import Axis
-
-
-class SecondaryAxis(_AxesBase):
- """
- General class to hold a Secondary_X/Yaxis.
- """
-
- def __init__(self, parent, orientation, location, functions, **kwargs):
- """
- See `.secondary_xaxis` and `.secondary_yaxis` for the doc string.
- While there is no need for this to be private, it should really be
- called by those higher level functions.
- """
- _api.check_in_list(["x", "y"], orientation=orientation)
- self._functions = functions
- self._parent = parent
- self._orientation = orientation
- self._ticks_set = False
-
- if self._orientation == 'x':
- super().__init__(self._parent.figure, [0, 1., 1, 0.0001], **kwargs)
- self._axis = self.xaxis
- self._locstrings = ['top', 'bottom']
- self._otherstrings = ['left', 'right']
- else: # 'y'
- super().__init__(self._parent.figure, [0, 1., 0.0001, 1], **kwargs)
- self._axis = self.yaxis
- self._locstrings = ['right', 'left']
- self._otherstrings = ['top', 'bottom']
- self._parentscale = None
- # this gets positioned w/o constrained_layout so exclude:
-
- self.set_location(location)
- self.set_functions(functions)
-
- # styling:
- otheraxis = self.yaxis if self._orientation == 'x' else self.xaxis
- otheraxis.set_major_locator(mticker.NullLocator())
- otheraxis.set_ticks_position('none')
-
- self.spines[self._otherstrings].set_visible(False)
- self.spines[self._locstrings].set_visible(True)
-
- if self._pos < 0.5:
- # flip the location strings...
- self._locstrings = self._locstrings[::-1]
- self.set_alignment(self._locstrings[0])
-
- def set_alignment(self, align):
- """
- Set if axes spine and labels are drawn at top or bottom (or left/right)
- of the axes.
-
- Parameters
- ----------
- align : {'top', 'bottom', 'left', 'right'}
- Either 'top' or 'bottom' for orientation='x' or
- 'left' or 'right' for orientation='y' axis.
- """
- _api.check_in_list(self._locstrings, align=align)
- if align == self._locstrings[1]: # Need to change the orientation.
- self._locstrings = self._locstrings[::-1]
- self.spines[self._locstrings[0]].set_visible(True)
- self.spines[self._locstrings[1]].set_visible(False)
- self._axis.set_ticks_position(align)
- self._axis.set_label_position(align)
-
- def set_location(self, location):
- """
- Set the vertical or horizontal location of the axes in
- parent-normalized coordinates.
-
- Parameters
- ----------
- location : {'top', 'bottom', 'left', 'right'} or float
- The position to put the secondary axis. Strings can be 'top' or
- 'bottom' for orientation='x' and 'right' or 'left' for
- orientation='y'. A float indicates the relative position on the
- parent axes to put the new axes, 0.0 being the bottom (or left)
- and 1.0 being the top (or right).
- """
-
- # This puts the rectangle into figure-relative coordinates.
- if isinstance(location, str):
- _api.check_in_list(self._locstrings, location=location)
- self._pos = 1. if location in ('top', 'right') else 0.
- elif isinstance(location, numbers.Real):
- self._pos = location
- else:
- raise ValueError(
- f"location must be {self._locstrings[0]!r}, "
- f"{self._locstrings[1]!r}, or a float, not {location!r}")
-
- self._loc = location
-
- if self._orientation == 'x':
- # An x-secondary axes is like an inset axes from x = 0 to x = 1 and
- # from y = pos to y = pos + eps, in the parent's transAxes coords.
- bounds = [0, self._pos, 1., 1e-10]
- else: # 'y'
- bounds = [self._pos, 0, 1e-10, 1]
-
- # this locator lets the axes move in the parent axes coordinates.
- # so it never needs to know where the parent is explicitly in
- # figure coordinates.
- # it gets called in ax.apply_aspect() (of all places)
- self.set_axes_locator(
- _TransformedBoundsLocator(bounds, self._parent.transAxes))
-
- def apply_aspect(self, position=None):
- # docstring inherited.
- self._set_lims()
- super().apply_aspect(position)
-
- @_docstring.copy(Axis.set_ticks)
- def set_ticks(self, ticks, labels=None, *, minor=False, **kwargs):
- ret = self._axis.set_ticks(ticks, labels, minor=minor, **kwargs)
- self.stale = True
- self._ticks_set = True
- return ret
-
- def set_functions(self, functions):
- """
- Set how the secondary axis converts limits from the parent axes.
-
- Parameters
- ----------
- functions : 2-tuple of func, or `Transform` with an inverse.
- Transform between the parent axis values and the secondary axis
- values.
-
- If supplied as a 2-tuple of functions, the first function is
- the forward transform function and the second is the inverse
- transform.
-
- If a transform is supplied, then the transform must have an
- inverse.
- """
- if (isinstance(functions, tuple) and len(functions) == 2 and
- callable(functions[0]) and callable(functions[1])):
- # make an arbitrary convert from a two-tuple of functions
- # forward and inverse.
- self._functions = functions
- elif functions is None:
- self._functions = (lambda x: x, lambda x: x)
- else:
- raise ValueError('functions argument of secondary axes '
- 'must be a two-tuple of callable functions '
- 'with the first function being the transform '
- 'and the second being the inverse')
- self._set_scale()
-
- def draw(self, renderer):
- """
- Draw the secondary axes.
-
- Consults the parent axes for its limits and converts them
- using the converter specified by
- `~.axes._secondary_axes.set_functions` (or *functions*
- parameter when axes initialized.)
- """
- self._set_lims()
- # this sets the scale in case the parent has set its scale.
- self._set_scale()
- super().draw(renderer)
-
- def _set_scale(self):
- """
- Check if parent has set its scale
- """
-
- if self._orientation == 'x':
- pscale = self._parent.xaxis.get_scale()
- set_scale = self.set_xscale
- else: # 'y'
- pscale = self._parent.yaxis.get_scale()
- set_scale = self.set_yscale
- if pscale == self._parentscale:
- return
-
- if self._ticks_set:
- ticks = self._axis.get_ticklocs()
-
- # need to invert the roles here for the ticks to line up.
- set_scale('functionlog' if pscale == 'log' else 'function',
- functions=self._functions[::-1])
-
- # OK, set_scale sets the locators, but if we've called
- # axsecond.set_ticks, we want to keep those.
- if self._ticks_set:
- self._axis.set_major_locator(mticker.FixedLocator(ticks))
-
- # If the parent scale doesn't change, we can skip this next time.
- self._parentscale = pscale
-
- def _set_lims(self):
- """
- Set the limits based on parent limits and the convert method
- between the parent and this secondary axes.
- """
- if self._orientation == 'x':
- lims = self._parent.get_xlim()
- set_lim = self.set_xlim
- else: # 'y'
- lims = self._parent.get_ylim()
- set_lim = self.set_ylim
- order = lims[0] < lims[1]
- lims = self._functions[0](np.array(lims))
- neworder = lims[0] < lims[1]
- if neworder != order:
- # Flip because the transform will take care of the flipping.
- lims = lims[::-1]
- set_lim(lims)
-
- def set_aspect(self, *args, **kwargs):
- """
- Secondary axes cannot set the aspect ratio, so calling this just
- sets a warning.
- """
- _api.warn_external("Secondary axes can't set the aspect ratio")
-
- def set_color(self, color):
- """
- Change the color of the secondary axes and all decorators.
-
- Parameters
- ----------
- color : color
- """
- axis = self._axis_map[self._orientation]
- axis.set_tick_params(colors=color)
- for spine in self.spines.values():
- if spine.axis is axis:
- spine.set_color(color)
- axis.label.set_color(color)
-
-
-_secax_docstring = '''
-Warnings
---------
-This method is experimental as of 3.1, and the API may change.
-
-Parameters
-----------
-location : {'top', 'bottom', 'left', 'right'} or float
- The position to put the secondary axis. Strings can be 'top' or
- 'bottom' for orientation='x' and 'right' or 'left' for
- orientation='y'. A float indicates the relative position on the
- parent axes to put the new axes, 0.0 being the bottom (or left)
- and 1.0 being the top (or right).
-
-functions : 2-tuple of func, or Transform with an inverse
-
- If a 2-tuple of functions, the user specifies the transform
- function and its inverse. i.e.
- ``functions=(lambda x: 2 / x, lambda x: 2 / x)`` would be an
- reciprocal transform with a factor of 2. Both functions must accept
- numpy arrays as input.
-
- The user can also directly supply a subclass of
- `.transforms.Transform` so long as it has an inverse.
-
- See :doc:`/gallery/subplots_axes_and_figures/secondary_axis`
- for examples of making these conversions.
-
-Returns
--------
-ax : axes._secondary_axes.SecondaryAxis
-
-Other Parameters
-----------------
-**kwargs : `~matplotlib.axes.Axes` properties.
- Other miscellaneous axes parameters.
-'''
-_docstring.interpd.update(_secax_docstring=_secax_docstring)
diff --git a/contrib/python/matplotlib/py3/matplotlib/axes/_secondary_axes.pyi b/contrib/python/matplotlib/py3/matplotlib/axes/_secondary_axes.pyi
deleted file mode 100644
index dcf1d2eb77..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/axes/_secondary_axes.pyi
+++ /dev/null
@@ -1,42 +0,0 @@
-from matplotlib.axes._base import _AxesBase
-from matplotlib.axis import Tick
-
-from matplotlib.transforms import Transform
-
-from collections.abc import Callable, Iterable
-from typing import Literal
-from numpy.typing import ArrayLike
-from matplotlib.typing import ColorType
-
-class SecondaryAxis(_AxesBase):
- def __init__(
- self,
- parent: _AxesBase,
- orientation: Literal["x", "y"],
- location: Literal["top", "bottom", "right", "left"] | float,
- functions: tuple[
- Callable[[ArrayLike], ArrayLike], Callable[[ArrayLike], ArrayLike]
- ]
- | Transform,
- **kwargs
- ) -> None: ...
- def set_alignment(
- self, align: Literal["top", "bottom", "right", "left"]
- ) -> None: ...
- def set_location(
- self, location: Literal["top", "bottom", "right", "left"] | float
- ) -> None: ...
- def set_ticks(
- self,
- ticks: ArrayLike,
- labels: Iterable[str] | None = ...,
- *,
- minor: bool = ...,
- **kwargs
- ) -> list[Tick]: ...
- def set_functions(
- self,
- functions: tuple[Callable[[ArrayLike], ArrayLike], Callable[[ArrayLike], ArrayLike]] | Transform,
- ) -> None: ...
- def set_aspect(self, *args, **kwargs) -> None: ...
- def set_color(self, color: ColorType) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/axis.py b/contrib/python/matplotlib/py3/matplotlib/axis.py
deleted file mode 100644
index 9adfb2cde7..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/axis.py
+++ /dev/null
@@ -1,2766 +0,0 @@
-"""
-Classes for the ticks and x- and y-axis.
-"""
-
-import datetime
-import functools
-import logging
-from numbers import Real
-import warnings
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, cbook
-import matplotlib.artist as martist
-import matplotlib.colors as mcolors
-import matplotlib.lines as mlines
-import matplotlib.scale as mscale
-import matplotlib.text as mtext
-import matplotlib.ticker as mticker
-import matplotlib.transforms as mtransforms
-import matplotlib.units as munits
-
-_log = logging.getLogger(__name__)
-
-GRIDLINE_INTERPOLATION_STEPS = 180
-
-# This list is being used for compatibility with Axes.grid, which
-# allows all Line2D kwargs.
-_line_inspector = martist.ArtistInspector(mlines.Line2D)
-_line_param_names = _line_inspector.get_setters()
-_line_param_aliases = [list(d)[0] for d in _line_inspector.aliasd.values()]
-_gridline_param_names = ['grid_' + name
- for name in _line_param_names + _line_param_aliases]
-
-_MARKER_DICT = {
- 'out': (mlines.TICKDOWN, mlines.TICKUP),
- 'in': (mlines.TICKUP, mlines.TICKDOWN),
- 'inout': ('|', '|'),
-}
-
-
-class Tick(martist.Artist):
- """
- Abstract base class for the axis ticks, grid lines and labels.
-
- Ticks mark a position on an Axis. They contain two lines as markers and
- two labels; one each for the bottom and top positions (in case of an
- `.XAxis`) or for the left and right positions (in case of a `.YAxis`).
-
- Attributes
- ----------
- tick1line : `~matplotlib.lines.Line2D`
- The left/bottom tick marker.
- tick2line : `~matplotlib.lines.Line2D`
- The right/top tick marker.
- gridline : `~matplotlib.lines.Line2D`
- The grid line associated with the label position.
- label1 : `~matplotlib.text.Text`
- The left/bottom tick label.
- label2 : `~matplotlib.text.Text`
- The right/top tick label.
-
- """
- def __init__(
- self, axes, loc, *,
- size=None, # points
- width=None,
- color=None,
- tickdir=None,
- pad=None,
- labelsize=None,
- labelcolor=None,
- labelfontfamily=None,
- zorder=None,
- gridOn=None, # defaults to axes.grid depending on axes.grid.which
- tick1On=True,
- tick2On=True,
- label1On=True,
- label2On=False,
- major=True,
- labelrotation=0,
- grid_color=None,
- grid_linestyle=None,
- grid_linewidth=None,
- grid_alpha=None,
- **kwargs, # Other Line2D kwargs applied to gridlines.
- ):
- """
- bbox is the Bound2D bounding box in display coords of the Axes
- loc is the tick location in data coords
- size is the tick size in points
- """
- super().__init__()
-
- if gridOn is None:
- which = mpl.rcParams['axes.grid.which']
- if major and (which in ('both', 'major')):
- gridOn = mpl.rcParams['axes.grid']
- elif (not major) and (which in ('both', 'minor')):
- gridOn = mpl.rcParams['axes.grid']
- else:
- gridOn = False
-
- self.set_figure(axes.figure)
- self.axes = axes
-
- self._loc = loc
- self._major = major
-
- name = self.__name__
- major_minor = "major" if major else "minor"
-
- if size is None:
- size = mpl.rcParams[f"{name}.{major_minor}.size"]
- self._size = size
-
- if width is None:
- width = mpl.rcParams[f"{name}.{major_minor}.width"]
- self._width = width
-
- if color is None:
- color = mpl.rcParams[f"{name}.color"]
-
- if pad is None:
- pad = mpl.rcParams[f"{name}.{major_minor}.pad"]
- self._base_pad = pad
-
- if labelcolor is None:
- labelcolor = mpl.rcParams[f"{name}.labelcolor"]
-
- if cbook._str_equal(labelcolor, 'inherit'):
- # inherit from tick color
- labelcolor = mpl.rcParams[f"{name}.color"]
-
- if labelsize is None:
- labelsize = mpl.rcParams[f"{name}.labelsize"]
-
- self._set_labelrotation(labelrotation)
-
- if zorder is None:
- if major:
- zorder = mlines.Line2D.zorder + 0.01
- else:
- zorder = mlines.Line2D.zorder
- self._zorder = zorder
-
- grid_color = mpl._val_or_rc(grid_color, "grid.color")
- grid_linestyle = mpl._val_or_rc(grid_linestyle, "grid.linestyle")
- grid_linewidth = mpl._val_or_rc(grid_linewidth, "grid.linewidth")
- if grid_alpha is None and not mcolors._has_alpha_channel(grid_color):
- # alpha precedence: kwarg > color alpha > rcParams['grid.alpha']
- # Note: only resolve to rcParams if the color does not have alpha
- # otherwise `grid(color=(1, 1, 1, 0.5))` would work like
- # grid(color=(1, 1, 1, 0.5), alpha=rcParams['grid.alpha'])
- # so the that the rcParams default would override color alpha.
- grid_alpha = mpl.rcParams["grid.alpha"]
- grid_kw = {k[5:]: v for k, v in kwargs.items()}
-
- self.tick1line = mlines.Line2D(
- [], [],
- color=color, linestyle="none", zorder=zorder, visible=tick1On,
- markeredgecolor=color, markersize=size, markeredgewidth=width,
- )
- self.tick2line = mlines.Line2D(
- [], [],
- color=color, linestyle="none", zorder=zorder, visible=tick2On,
- markeredgecolor=color, markersize=size, markeredgewidth=width,
- )
- self.gridline = mlines.Line2D(
- [], [],
- color=grid_color, alpha=grid_alpha, visible=gridOn,
- linestyle=grid_linestyle, linewidth=grid_linewidth, marker="",
- **grid_kw,
- )
- self.gridline.get_path()._interpolation_steps = \
- GRIDLINE_INTERPOLATION_STEPS
- self.label1 = mtext.Text(
- np.nan, np.nan,
- fontsize=labelsize, color=labelcolor, visible=label1On,
- fontfamily=labelfontfamily, rotation=self._labelrotation[1])
- self.label2 = mtext.Text(
- np.nan, np.nan,
- fontsize=labelsize, color=labelcolor, visible=label2On,
- fontfamily=labelfontfamily, rotation=self._labelrotation[1])
-
- self._apply_tickdir(tickdir)
-
- for artist in [self.tick1line, self.tick2line, self.gridline,
- self.label1, self.label2]:
- self._set_artist_props(artist)
-
- self.update_position(loc)
-
- def _set_labelrotation(self, labelrotation):
- if isinstance(labelrotation, str):
- mode = labelrotation
- angle = 0
- elif isinstance(labelrotation, (tuple, list)):
- mode, angle = labelrotation
- else:
- mode = 'default'
- angle = labelrotation
- _api.check_in_list(['auto', 'default'], labelrotation=mode)
- self._labelrotation = (mode, angle)
-
- def _apply_tickdir(self, tickdir):
- """Set tick direction. Valid values are 'out', 'in', 'inout'."""
- # This method is responsible for updating `_pad`, and, in subclasses,
- # for setting the tick{1,2}line markers as well. From the user
- # perspective this should always be called though _apply_params, which
- # further updates ticklabel positions using the new pads.
- if tickdir is None:
- tickdir = mpl.rcParams[f'{self.__name__}.direction']
- else:
- _api.check_in_list(['in', 'out', 'inout'], tickdir=tickdir)
- self._tickdir = tickdir
- self._pad = self._base_pad + self.get_tick_padding()
-
- def get_tickdir(self):
- return self._tickdir
-
- def get_tick_padding(self):
- """Get the length of the tick outside of the Axes."""
- padding = {
- 'in': 0.0,
- 'inout': 0.5,
- 'out': 1.0
- }
- return self._size * padding[self._tickdir]
-
- def get_children(self):
- children = [self.tick1line, self.tick2line,
- self.gridline, self.label1, self.label2]
- return children
-
- @_api.rename_parameter("3.8", "clippath", "path")
- def set_clip_path(self, path, transform=None):
- # docstring inherited
- super().set_clip_path(path, transform)
- self.gridline.set_clip_path(path, transform)
- self.stale = True
-
- def contains(self, mouseevent):
- """
- Test whether the mouse event occurred in the Tick marks.
-
- This function always returns false. It is more useful to test if the
- axis as a whole contains the mouse rather than the set of tick marks.
- """
- return False, {}
-
- def set_pad(self, val):
- """
- Set the tick label pad in points
-
- Parameters
- ----------
- val : float
- """
- self._apply_params(pad=val)
- self.stale = True
-
- def get_pad(self):
- """Get the value of the tick label pad in points."""
- return self._base_pad
-
- def _get_text1(self):
- """Get the default Text 1 instance."""
-
- def _get_text2(self):
- """Get the default Text 2 instance."""
-
- def _get_tick1line(self):
- """Get the default `.Line2D` instance for tick1."""
-
- def _get_tick2line(self):
- """Get the default `.Line2D` instance for tick2."""
-
- def _get_gridline(self):
- """Get the default grid `.Line2D` instance for this tick."""
-
- def get_loc(self):
- """Return the tick location (data coords) as a scalar."""
- return self._loc
-
- @martist.allow_rasterization
- def draw(self, renderer):
- if not self.get_visible():
- self.stale = False
- return
- renderer.open_group(self.__name__, gid=self.get_gid())
- for artist in [self.gridline, self.tick1line, self.tick2line,
- self.label1, self.label2]:
- artist.draw(renderer)
- renderer.close_group(self.__name__)
- self.stale = False
-
- @_api.deprecated("3.8")
- def set_label1(self, s):
- """
- Set the label1 text.
-
- Parameters
- ----------
- s : str
- """
- self.label1.set_text(s)
- self.stale = True
-
- set_label = set_label1
-
- @_api.deprecated("3.8")
- def set_label2(self, s):
- """
- Set the label2 text.
-
- Parameters
- ----------
- s : str
- """
- self.label2.set_text(s)
- self.stale = True
-
- def set_url(self, url):
- """
- Set the url of label1 and label2.
-
- Parameters
- ----------
- url : str
- """
- super().set_url(url)
- self.label1.set_url(url)
- self.label2.set_url(url)
- self.stale = True
-
- def _set_artist_props(self, a):
- a.set_figure(self.figure)
-
- def get_view_interval(self):
- """
- Return the view limits ``(min, max)`` of the axis the tick belongs to.
- """
- raise NotImplementedError('Derived must override')
-
- def _apply_params(self, **kwargs):
- for name, target in [("gridOn", self.gridline),
- ("tick1On", self.tick1line),
- ("tick2On", self.tick2line),
- ("label1On", self.label1),
- ("label2On", self.label2)]:
- if name in kwargs:
- target.set_visible(kwargs.pop(name))
- if any(k in kwargs for k in ['size', 'width', 'pad', 'tickdir']):
- self._size = kwargs.pop('size', self._size)
- # Width could be handled outside this block, but it is
- # convenient to leave it here.
- self._width = kwargs.pop('width', self._width)
- self._base_pad = kwargs.pop('pad', self._base_pad)
- # _apply_tickdir uses _size and _base_pad to make _pad, and also
- # sets the ticklines markers.
- self._apply_tickdir(kwargs.pop('tickdir', self._tickdir))
- for line in (self.tick1line, self.tick2line):
- line.set_markersize(self._size)
- line.set_markeredgewidth(self._width)
- # _get_text1_transform uses _pad from _apply_tickdir.
- trans = self._get_text1_transform()[0]
- self.label1.set_transform(trans)
- trans = self._get_text2_transform()[0]
- self.label2.set_transform(trans)
- tick_kw = {k: v for k, v in kwargs.items() if k in ['color', 'zorder']}
- if 'color' in kwargs:
- tick_kw['markeredgecolor'] = kwargs['color']
- self.tick1line.set(**tick_kw)
- self.tick2line.set(**tick_kw)
- for k, v in tick_kw.items():
- setattr(self, '_' + k, v)
-
- if 'labelrotation' in kwargs:
- self._set_labelrotation(kwargs.pop('labelrotation'))
- self.label1.set(rotation=self._labelrotation[1])
- self.label2.set(rotation=self._labelrotation[1])
-
- label_kw = {k[5:]: v for k, v in kwargs.items()
- if k in ['labelsize', 'labelcolor', 'labelfontfamily']}
- self.label1.set(**label_kw)
- self.label2.set(**label_kw)
-
- grid_kw = {k[5:]: v for k, v in kwargs.items()
- if k in _gridline_param_names}
- self.gridline.set(**grid_kw)
-
- def update_position(self, loc):
- """Set the location of tick in data coords with scalar *loc*."""
- raise NotImplementedError('Derived must override')
-
- def _get_text1_transform(self):
- raise NotImplementedError('Derived must override')
-
- def _get_text2_transform(self):
- raise NotImplementedError('Derived must override')
-
-
-class XTick(Tick):
- """
- Contains all the Artists needed to make an x tick - the tick line,
- the label text and the grid line
- """
- __name__ = 'xtick'
-
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- # x in data coords, y in axes coords
- ax = self.axes
- self.tick1line.set(
- data=([0], [0]), transform=ax.get_xaxis_transform("tick1"))
- self.tick2line.set(
- data=([0], [1]), transform=ax.get_xaxis_transform("tick2"))
- self.gridline.set(
- data=([0, 0], [0, 1]), transform=ax.get_xaxis_transform("grid"))
- # the y loc is 3 points below the min of y axis
- trans, va, ha = self._get_text1_transform()
- self.label1.set(
- x=0, y=0,
- verticalalignment=va, horizontalalignment=ha, transform=trans,
- )
- trans, va, ha = self._get_text2_transform()
- self.label2.set(
- x=0, y=1,
- verticalalignment=va, horizontalalignment=ha, transform=trans,
- )
-
- def _get_text1_transform(self):
- return self.axes.get_xaxis_text1_transform(self._pad)
-
- def _get_text2_transform(self):
- return self.axes.get_xaxis_text2_transform(self._pad)
-
- def _apply_tickdir(self, tickdir):
- # docstring inherited
- super()._apply_tickdir(tickdir)
- mark1, mark2 = _MARKER_DICT[self._tickdir]
- self.tick1line.set_marker(mark1)
- self.tick2line.set_marker(mark2)
-
- def update_position(self, loc):
- """Set the location of tick in data coords with scalar *loc*."""
- self.tick1line.set_xdata((loc,))
- self.tick2line.set_xdata((loc,))
- self.gridline.set_xdata((loc,))
- self.label1.set_x(loc)
- self.label2.set_x(loc)
- self._loc = loc
- self.stale = True
-
- def get_view_interval(self):
- # docstring inherited
- return self.axes.viewLim.intervalx
-
-
-class YTick(Tick):
- """
- Contains all the Artists needed to make a Y tick - the tick line,
- the label text and the grid line
- """
- __name__ = 'ytick'
-
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- # x in axes coords, y in data coords
- ax = self.axes
- self.tick1line.set(
- data=([0], [0]), transform=ax.get_yaxis_transform("tick1"))
- self.tick2line.set(
- data=([1], [0]), transform=ax.get_yaxis_transform("tick2"))
- self.gridline.set(
- data=([0, 1], [0, 0]), transform=ax.get_yaxis_transform("grid"))
- # the y loc is 3 points below the min of y axis
- trans, va, ha = self._get_text1_transform()
- self.label1.set(
- x=0, y=0,
- verticalalignment=va, horizontalalignment=ha, transform=trans,
- )
- trans, va, ha = self._get_text2_transform()
- self.label2.set(
- x=1, y=0,
- verticalalignment=va, horizontalalignment=ha, transform=trans,
- )
-
- def _get_text1_transform(self):
- return self.axes.get_yaxis_text1_transform(self._pad)
-
- def _get_text2_transform(self):
- return self.axes.get_yaxis_text2_transform(self._pad)
-
- def _apply_tickdir(self, tickdir):
- # docstring inherited
- super()._apply_tickdir(tickdir)
- mark1, mark2 = {
- 'out': (mlines.TICKLEFT, mlines.TICKRIGHT),
- 'in': (mlines.TICKRIGHT, mlines.TICKLEFT),
- 'inout': ('_', '_'),
- }[self._tickdir]
- self.tick1line.set_marker(mark1)
- self.tick2line.set_marker(mark2)
-
- def update_position(self, loc):
- """Set the location of tick in data coords with scalar *loc*."""
- self.tick1line.set_ydata((loc,))
- self.tick2line.set_ydata((loc,))
- self.gridline.set_ydata((loc,))
- self.label1.set_y(loc)
- self.label2.set_y(loc)
- self._loc = loc
- self.stale = True
-
- def get_view_interval(self):
- # docstring inherited
- return self.axes.viewLim.intervaly
-
-
-class Ticker:
- """
- A container for the objects defining tick position and format.
-
- Attributes
- ----------
- locator : `~matplotlib.ticker.Locator` subclass
- Determines the positions of the ticks.
- formatter : `~matplotlib.ticker.Formatter` subclass
- Determines the format of the tick labels.
- """
-
- def __init__(self):
- self._locator = None
- self._formatter = None
- self._locator_is_default = True
- self._formatter_is_default = True
-
- @property
- def locator(self):
- return self._locator
-
- @locator.setter
- def locator(self, locator):
- if not isinstance(locator, mticker.Locator):
- raise TypeError('locator must be a subclass of '
- 'matplotlib.ticker.Locator')
- self._locator = locator
-
- @property
- def formatter(self):
- return self._formatter
-
- @formatter.setter
- def formatter(self, formatter):
- if not isinstance(formatter, mticker.Formatter):
- raise TypeError('formatter must be a subclass of '
- 'matplotlib.ticker.Formatter')
- self._formatter = formatter
-
-
-class _LazyTickList:
- """
- A descriptor for lazy instantiation of tick lists.
-
- See comment above definition of the ``majorTicks`` and ``minorTicks``
- attributes.
- """
-
- def __init__(self, major):
- self._major = major
-
- def __get__(self, instance, owner):
- if instance is None:
- return self
- else:
- # instance._get_tick() can itself try to access the majorTicks
- # attribute (e.g. in certain projection classes which override
- # e.g. get_xaxis_text1_transform). In order to avoid infinite
- # recursion, first set the majorTicks on the instance to an empty
- # list, then create the tick and append it.
- if self._major:
- instance.majorTicks = []
- tick = instance._get_tick(major=True)
- instance.majorTicks.append(tick)
- return instance.majorTicks
- else:
- instance.minorTicks = []
- tick = instance._get_tick(major=False)
- instance.minorTicks.append(tick)
- return instance.minorTicks
-
-
-class Axis(martist.Artist):
- """
- Base class for `.XAxis` and `.YAxis`.
-
- Attributes
- ----------
- isDefault_label : bool
-
- axes : `~matplotlib.axes.Axes`
- The `~.axes.Axes` to which the Axis belongs.
- major : `~matplotlib.axis.Ticker`
- Determines the major tick positions and their label format.
- minor : `~matplotlib.axis.Ticker`
- Determines the minor tick positions and their label format.
- callbacks : `~matplotlib.cbook.CallbackRegistry`
-
- label : `~matplotlib.text.Text`
- The axis label.
- labelpad : float
- The distance between the axis label and the tick labels.
- Defaults to :rc:`axes.labelpad` = 4.
- offsetText : `~matplotlib.text.Text`
- A `.Text` object containing the data offset of the ticks (if any).
- pickradius : float
- The acceptance radius for containment tests. See also `.Axis.contains`.
- majorTicks : list of `.Tick`
- The major ticks.
-
- .. warning::
-
- Ticks are not guaranteed to be persistent. Various operations
- can create, delete and modify the Tick instances. There is an
- imminent risk that changes to individual ticks will not
- survive if you work on the figure further (including also
- panning/zooming on a displayed figure).
-
- Working on the individual ticks is a method of last resort.
- Use `.set_tick_params` instead if possible.
-
- minorTicks : list of `.Tick`
- The minor ticks.
- """
- OFFSETTEXTPAD = 3
- # The class used in _get_tick() to create tick instances. Must either be
- # overwritten in subclasses, or subclasses must reimplement _get_tick().
- _tick_class = None
-
- def __str__(self):
- return "{}({},{})".format(
- type(self).__name__, *self.axes.transAxes.transform((0, 0)))
-
- def __init__(self, axes, *, pickradius=15, clear=True):
- """
- Parameters
- ----------
- axes : `~matplotlib.axes.Axes`
- The `~.axes.Axes` to which the created Axis belongs.
- pickradius : float
- The acceptance radius for containment tests. See also
- `.Axis.contains`.
- clear : bool, default: True
- Whether to clear the Axis on creation. This is not required, e.g., when
- creating an Axis as part of an Axes, as ``Axes.clear`` will call
- ``Axis.clear``.
- .. versionadded:: 3.8
- """
- super().__init__()
- self._remove_overlapping_locs = True
-
- self.set_figure(axes.figure)
-
- self.isDefault_label = True
-
- self.axes = axes
- self.major = Ticker()
- self.minor = Ticker()
- self.callbacks = cbook.CallbackRegistry(signals=["units"])
-
- self._autolabelpos = True
-
- self.label = mtext.Text(
- np.nan, np.nan,
- fontsize=mpl.rcParams['axes.labelsize'],
- fontweight=mpl.rcParams['axes.labelweight'],
- color=mpl.rcParams['axes.labelcolor'],
- )
- self._set_artist_props(self.label)
- self.offsetText = mtext.Text(np.nan, np.nan)
- self._set_artist_props(self.offsetText)
-
- self.labelpad = mpl.rcParams['axes.labelpad']
-
- self.pickradius = pickradius
-
- # Initialize here for testing; later add API
- self._major_tick_kw = dict()
- self._minor_tick_kw = dict()
-
- if clear:
- self.clear()
- else:
- self.converter = None
- self.units = None
-
- self._autoscale_on = True
-
- @property
- def isDefault_majloc(self):
- return self.major._locator_is_default
-
- @isDefault_majloc.setter
- def isDefault_majloc(self, value):
- self.major._locator_is_default = value
-
- @property
- def isDefault_majfmt(self):
- return self.major._formatter_is_default
-
- @isDefault_majfmt.setter
- def isDefault_majfmt(self, value):
- self.major._formatter_is_default = value
-
- @property
- def isDefault_minloc(self):
- return self.minor._locator_is_default
-
- @isDefault_minloc.setter
- def isDefault_minloc(self, value):
- self.minor._locator_is_default = value
-
- @property
- def isDefault_minfmt(self):
- return self.minor._formatter_is_default
-
- @isDefault_minfmt.setter
- def isDefault_minfmt(self, value):
- self.minor._formatter_is_default = value
-
- def _get_shared_axes(self):
- """Return Grouper of shared axes for current axis."""
- return self.axes._shared_axes[
- self._get_axis_name()].get_siblings(self.axes)
-
- def _get_shared_axis(self):
- """Return list of shared axis for current axis."""
- name = self._get_axis_name()
- return [ax._axis_map[name] for ax in self._get_shared_axes()]
-
- def _get_axis_name(self):
- """Return the axis name."""
- return [name for name, axis in self.axes._axis_map.items()
- if axis is self][0]
-
- # During initialization, Axis objects often create ticks that are later
- # unused; this turns out to be a very slow step. Instead, use a custom
- # descriptor to make the tick lists lazy and instantiate them as needed.
- majorTicks = _LazyTickList(major=True)
- minorTicks = _LazyTickList(major=False)
-
- def get_remove_overlapping_locs(self):
- return self._remove_overlapping_locs
-
- def set_remove_overlapping_locs(self, val):
- self._remove_overlapping_locs = bool(val)
-
- remove_overlapping_locs = property(
- get_remove_overlapping_locs, set_remove_overlapping_locs,
- doc=('If minor ticker locations that overlap with major '
- 'ticker locations should be trimmed.'))
-
- def set_label_coords(self, x, y, transform=None):
- """
- Set the coordinates of the label.
-
- By default, the x coordinate of the y label and the y coordinate of the
- x label are determined by the tick label bounding boxes, but this can
- lead to poor alignment of multiple labels if there are multiple axes.
-
- You can also specify the coordinate system of the label with the
- transform. If None, the default coordinate system will be the axes
- coordinate system: (0, 0) is bottom left, (0.5, 0.5) is center, etc.
- """
- self._autolabelpos = False
- if transform is None:
- transform = self.axes.transAxes
-
- self.label.set_transform(transform)
- self.label.set_position((x, y))
- self.stale = True
-
- def get_transform(self):
- """Return the transform used in the Axis' scale"""
- return self._scale.get_transform()
-
- def get_scale(self):
- """Return this Axis' scale (as a str)."""
- return self._scale.name
-
- def _set_scale(self, value, **kwargs):
- if not isinstance(value, mscale.ScaleBase):
- self._scale = mscale.scale_factory(value, self, **kwargs)
- else:
- self._scale = value
- self._scale.set_default_locators_and_formatters(self)
-
- self.isDefault_majloc = True
- self.isDefault_minloc = True
- self.isDefault_majfmt = True
- self.isDefault_minfmt = True
-
- # This method is directly wrapped by Axes.set_{x,y}scale.
- def _set_axes_scale(self, value, **kwargs):
- """
- Set this Axis' scale.
-
- Parameters
- ----------
- value : {"linear", "log", "symlog", "logit", ...} or `.ScaleBase`
- The axis scale type to apply.
-
- **kwargs
- Different keyword arguments are accepted, depending on the scale.
- See the respective class keyword arguments:
-
- - `matplotlib.scale.LinearScale`
- - `matplotlib.scale.LogScale`
- - `matplotlib.scale.SymmetricalLogScale`
- - `matplotlib.scale.LogitScale`
- - `matplotlib.scale.FuncScale`
-
- Notes
- -----
- By default, Matplotlib supports the above-mentioned scales.
- Additionally, custom scales may be registered using
- `matplotlib.scale.register_scale`. These scales can then also
- be used here.
- """
- name = self._get_axis_name()
- old_default_lims = (self.get_major_locator()
- .nonsingular(-np.inf, np.inf))
- for ax in self._get_shared_axes():
- ax._axis_map[name]._set_scale(value, **kwargs)
- ax._update_transScale()
- ax.stale = True
- new_default_lims = (self.get_major_locator()
- .nonsingular(-np.inf, np.inf))
- if old_default_lims != new_default_lims:
- # Force autoscaling now, to take advantage of the scale locator's
- # nonsingular() before it possibly gets swapped out by the user.
- self.axes.autoscale_view(
- **{f"scale{k}": k == name for k in self.axes._axis_names})
-
- def limit_range_for_scale(self, vmin, vmax):
- return self._scale.limit_range_for_scale(vmin, vmax, self.get_minpos())
-
- def _get_autoscale_on(self):
- """Return whether this Axis is autoscaled."""
- return self._autoscale_on
-
- def _set_autoscale_on(self, b):
- """
- Set whether this Axis is autoscaled when drawing or by
- `.Axes.autoscale_view`.
-
- Parameters
- ----------
- b : bool
- """
- self._autoscale_on = b
-
- def get_children(self):
- return [self.label, self.offsetText,
- *self.get_major_ticks(), *self.get_minor_ticks()]
-
- def _reset_major_tick_kw(self):
- self._major_tick_kw.clear()
- self._major_tick_kw['gridOn'] = (
- mpl.rcParams['axes.grid'] and
- mpl.rcParams['axes.grid.which'] in ('both', 'major'))
-
- def _reset_minor_tick_kw(self):
- self._minor_tick_kw.clear()
- self._minor_tick_kw['gridOn'] = (
- mpl.rcParams['axes.grid'] and
- mpl.rcParams['axes.grid.which'] in ('both', 'minor'))
-
- def clear(self):
- """
- Clear the axis.
-
- This resets axis properties to their default values:
-
- - the label
- - the scale
- - locators, formatters and ticks
- - major and minor grid
- - units
- - registered callbacks
- """
- self.label._reset_visual_defaults()
- # The above resets the label formatting using text rcParams,
- # so we then update the formatting using axes rcParams
- self.label.set_color(mpl.rcParams['axes.labelcolor'])
- self.label.set_fontsize(mpl.rcParams['axes.labelsize'])
- self.label.set_fontweight(mpl.rcParams['axes.labelweight'])
- self.offsetText._reset_visual_defaults()
- self.labelpad = mpl.rcParams['axes.labelpad']
-
- self._init()
-
- self._set_scale('linear')
-
- # Clear the callback registry for this axis, or it may "leak"
- self.callbacks = cbook.CallbackRegistry(signals=["units"])
-
- # whether the grids are on
- self._major_tick_kw['gridOn'] = (
- mpl.rcParams['axes.grid'] and
- mpl.rcParams['axes.grid.which'] in ('both', 'major'))
- self._minor_tick_kw['gridOn'] = (
- mpl.rcParams['axes.grid'] and
- mpl.rcParams['axes.grid.which'] in ('both', 'minor'))
- self.reset_ticks()
-
- self.converter = None
- self.units = None
- self.stale = True
-
- def reset_ticks(self):
- """
- Re-initialize the major and minor Tick lists.
-
- Each list starts with a single fresh Tick.
- """
- # Restore the lazy tick lists.
- try:
- del self.majorTicks
- except AttributeError:
- pass
- try:
- del self.minorTicks
- except AttributeError:
- pass
- try:
- self.set_clip_path(self.axes.patch)
- except AttributeError:
- pass
-
- def set_tick_params(self, which='major', reset=False, **kwargs):
- """
- Set appearance parameters for ticks, ticklabels, and gridlines.
-
- For documentation of keyword arguments, see
- :meth:`matplotlib.axes.Axes.tick_params`.
-
- See Also
- --------
- .Axis.get_tick_params
- View the current style settings for ticks, ticklabels, and
- gridlines.
- """
- _api.check_in_list(['major', 'minor', 'both'], which=which)
- kwtrans = self._translate_tick_params(kwargs)
-
- # the kwargs are stored in self._major/minor_tick_kw so that any
- # future new ticks will automatically get them
- if reset:
- if which in ['major', 'both']:
- self._reset_major_tick_kw()
- self._major_tick_kw.update(kwtrans)
- if which in ['minor', 'both']:
- self._reset_minor_tick_kw()
- self._minor_tick_kw.update(kwtrans)
- self.reset_ticks()
- else:
- if which in ['major', 'both']:
- self._major_tick_kw.update(kwtrans)
- for tick in self.majorTicks:
- tick._apply_params(**kwtrans)
- if which in ['minor', 'both']:
- self._minor_tick_kw.update(kwtrans)
- for tick in self.minorTicks:
- tick._apply_params(**kwtrans)
- # labelOn and labelcolor also apply to the offset text.
- if 'label1On' in kwtrans or 'label2On' in kwtrans:
- self.offsetText.set_visible(
- self._major_tick_kw.get('label1On', False)
- or self._major_tick_kw.get('label2On', False))
- if 'labelcolor' in kwtrans:
- self.offsetText.set_color(kwtrans['labelcolor'])
-
- self.stale = True
-
- def get_tick_params(self, which='major'):
- """
- Get appearance parameters for ticks, ticklabels, and gridlines.
-
- .. versionadded:: 3.7
-
- Parameters
- ----------
- which : {'major', 'minor'}, default: 'major'
- The group of ticks for which the parameters are retrieved.
-
- Returns
- -------
- dict
- Properties for styling tick elements added to the axis.
-
- Notes
- -----
- This method returns the appearance parameters for styling *new*
- elements added to this axis and may be different from the values
- on current elements if they were modified directly by the user
- (e.g., via ``set_*`` methods on individual tick objects).
-
- Examples
- --------
- ::
-
- >>> ax.yaxis.set_tick_params(labelsize=30, labelcolor='red',
- direction='out', which='major')
- >>> ax.yaxis.get_tick_params(which='major')
- {'direction': 'out',
- 'left': True,
- 'right': False,
- 'labelleft': True,
- 'labelright': False,
- 'gridOn': False,
- 'labelsize': 30,
- 'labelcolor': 'red'}
- >>> ax.yaxis.get_tick_params(which='minor')
- {'left': True,
- 'right': False,
- 'labelleft': True,
- 'labelright': False,
- 'gridOn': False}
-
-
- """
- _api.check_in_list(['major', 'minor'], which=which)
- if which == 'major':
- return self._translate_tick_params(
- self._major_tick_kw, reverse=True
- )
- return self._translate_tick_params(self._minor_tick_kw, reverse=True)
-
- @staticmethod
- def _translate_tick_params(kw, reverse=False):
- """
- Translate the kwargs supported by `.Axis.set_tick_params` to kwargs
- supported by `.Tick._apply_params`.
-
- In particular, this maps axis specific names like 'top', 'left'
- to the generic tick1, tick2 logic of the axis. Additionally, there
- are some other name translations.
-
- Returns a new dict of translated kwargs.
-
- Note: Use reverse=True to translate from those supported by
- `.Tick._apply_params` back to those supported by
- `.Axis.set_tick_params`.
- """
- kw_ = {**kw}
-
- # The following lists may be moved to a more accessible location.
- allowed_keys = [
- 'size', 'width', 'color', 'tickdir', 'pad',
- 'labelsize', 'labelcolor', 'labelfontfamily', 'zorder', 'gridOn',
- 'tick1On', 'tick2On', 'label1On', 'label2On',
- 'length', 'direction', 'left', 'bottom', 'right', 'top',
- 'labelleft', 'labelbottom', 'labelright', 'labeltop',
- 'labelrotation',
- *_gridline_param_names]
-
- keymap = {
- # tick_params key -> axis key
- 'length': 'size',
- 'direction': 'tickdir',
- 'rotation': 'labelrotation',
- 'left': 'tick1On',
- 'bottom': 'tick1On',
- 'right': 'tick2On',
- 'top': 'tick2On',
- 'labelleft': 'label1On',
- 'labelbottom': 'label1On',
- 'labelright': 'label2On',
- 'labeltop': 'label2On',
- }
- if reverse:
- kwtrans = {
- oldkey: kw_.pop(newkey)
- for oldkey, newkey in keymap.items() if newkey in kw_
- }
- else:
- kwtrans = {
- newkey: kw_.pop(oldkey)
- for oldkey, newkey in keymap.items() if oldkey in kw_
- }
- if 'colors' in kw_:
- c = kw_.pop('colors')
- kwtrans['color'] = c
- kwtrans['labelcolor'] = c
- # Maybe move the checking up to the caller of this method.
- for key in kw_:
- if key not in allowed_keys:
- raise ValueError(
- "keyword %s is not recognized; valid keywords are %s"
- % (key, allowed_keys))
- kwtrans.update(kw_)
- return kwtrans
-
- @_api.rename_parameter("3.8", "clippath", "path")
- def set_clip_path(self, path, transform=None):
- super().set_clip_path(path, transform)
- for child in self.majorTicks + self.minorTicks:
- child.set_clip_path(path, transform)
- self.stale = True
-
- def get_view_interval(self):
- """Return the ``(min, max)`` view limits of this axis."""
- raise NotImplementedError('Derived must override')
-
- def set_view_interval(self, vmin, vmax, ignore=False):
- """
- Set the axis view limits. This method is for internal use; Matplotlib
- users should typically use e.g. `~.Axes.set_xlim` or `~.Axes.set_ylim`.
-
- If *ignore* is False (the default), this method will never reduce the
- preexisting view limits, only expand them if *vmin* or *vmax* are not
- within them. Moreover, the order of *vmin* and *vmax* does not matter;
- the orientation of the axis will not change.
-
- If *ignore* is True, the view limits will be set exactly to ``(vmin,
- vmax)`` in that order.
- """
- raise NotImplementedError('Derived must override')
-
- def get_data_interval(self):
- """Return the ``(min, max)`` data limits of this axis."""
- raise NotImplementedError('Derived must override')
-
- def set_data_interval(self, vmin, vmax, ignore=False):
- """
- Set the axis data limits. This method is for internal use.
-
- If *ignore* is False (the default), this method will never reduce the
- preexisting data limits, only expand them if *vmin* or *vmax* are not
- within them. Moreover, the order of *vmin* and *vmax* does not matter;
- the orientation of the axis will not change.
-
- If *ignore* is True, the data limits will be set exactly to ``(vmin,
- vmax)`` in that order.
- """
- raise NotImplementedError('Derived must override')
-
- def get_inverted(self):
- """
- Return whether this Axis is oriented in the "inverse" direction.
-
- The "normal" direction is increasing to the right for the x-axis and to
- the top for the y-axis; the "inverse" direction is increasing to the
- left for the x-axis and to the bottom for the y-axis.
- """
- low, high = self.get_view_interval()
- return high < low
-
- def set_inverted(self, inverted):
- """
- Set whether this Axis is oriented in the "inverse" direction.
-
- The "normal" direction is increasing to the right for the x-axis and to
- the top for the y-axis; the "inverse" direction is increasing to the
- left for the x-axis and to the bottom for the y-axis.
- """
- a, b = self.get_view_interval()
- # cast to bool to avoid bad interaction between python 3.8 and np.bool_
- self._set_lim(*sorted((a, b), reverse=bool(inverted)), auto=None)
-
- def set_default_intervals(self):
- """
- Set the default limits for the axis data and view interval if they
- have not been not mutated yet.
- """
- # this is mainly in support of custom object plotting. For
- # example, if someone passes in a datetime object, we do not
- # know automagically how to set the default min/max of the
- # data and view limits. The unit conversion AxisInfo
- # interface provides a hook for custom types to register
- # default limits through the AxisInfo.default_limits
- # attribute, and the derived code below will check for that
- # and use it if it's available (else just use 0..1)
-
- def _set_lim(self, v0, v1, *, emit=True, auto):
- """
- Set view limits.
-
- This method is a helper for the Axes ``set_xlim``, ``set_ylim``, and
- ``set_zlim`` methods.
-
- Parameters
- ----------
- v0, v1 : float
- The view limits. (Passing *v0* as a (low, high) pair is not
- supported; normalization must occur in the Axes setters.)
- emit : bool, default: True
- Whether to notify observers of limit change.
- auto : bool or None, default: False
- Whether to turn on autoscaling of the x-axis. True turns on, False
- turns off, None leaves unchanged.
- """
- name = self._get_axis_name()
-
- self.axes._process_unit_info([(name, (v0, v1))], convert=False)
- v0 = self.axes._validate_converted_limits(v0, self.convert_units)
- v1 = self.axes._validate_converted_limits(v1, self.convert_units)
-
- if v0 is None or v1 is None:
- # Axes init calls set_xlim(0, 1) before get_xlim() can be called,
- # so only grab the limits if we really need them.
- old0, old1 = self.get_view_interval()
- if v0 is None:
- v0 = old0
- if v1 is None:
- v1 = old1
-
- if self.get_scale() == 'log' and (v0 <= 0 or v1 <= 0):
- # Axes init calls set_xlim(0, 1) before get_xlim() can be called,
- # so only grab the limits if we really need them.
- old0, old1 = self.get_view_interval()
- if v0 <= 0:
- _api.warn_external(f"Attempt to set non-positive {name}lim on "
- f"a log-scaled axis will be ignored.")
- v0 = old0
- if v1 <= 0:
- _api.warn_external(f"Attempt to set non-positive {name}lim on "
- f"a log-scaled axis will be ignored.")
- v1 = old1
- if v0 == v1:
- _api.warn_external(
- f"Attempting to set identical low and high {name}lims "
- f"makes transformation singular; automatically expanding.")
- reverse = bool(v0 > v1) # explicit cast needed for python3.8+np.bool_.
- v0, v1 = self.get_major_locator().nonsingular(v0, v1)
- v0, v1 = self.limit_range_for_scale(v0, v1)
- v0, v1 = sorted([v0, v1], reverse=bool(reverse))
-
- self.set_view_interval(v0, v1, ignore=True)
- # Mark viewlims as no longer stale without triggering an autoscale.
- for ax in self._get_shared_axes():
- ax._stale_viewlims[name] = False
- if auto is not None:
- self._set_autoscale_on(bool(auto))
-
- if emit:
- self.axes.callbacks.process(f"{name}lim_changed", self.axes)
- # Call all of the other axes that are shared with this one
- for other in self._get_shared_axes():
- if other is self.axes:
- continue
- other._axis_map[name]._set_lim(v0, v1, emit=False, auto=auto)
- if emit:
- other.callbacks.process(f"{name}lim_changed", other)
- if other.figure != self.figure:
- other.figure.canvas.draw_idle()
-
- self.stale = True
- return v0, v1
-
- def _set_artist_props(self, a):
- if a is None:
- return
- a.set_figure(self.figure)
-
- def _update_ticks(self):
- """
- Update ticks (position and labels) using the current data interval of
- the axes. Return the list of ticks that will be drawn.
- """
- major_locs = self.get_majorticklocs()
- major_labels = self.major.formatter.format_ticks(major_locs)
- major_ticks = self.get_major_ticks(len(major_locs))
- for tick, loc, label in zip(major_ticks, major_locs, major_labels):
- tick.update_position(loc)
- tick.label1.set_text(label)
- tick.label2.set_text(label)
- minor_locs = self.get_minorticklocs()
- minor_labels = self.minor.formatter.format_ticks(minor_locs)
- minor_ticks = self.get_minor_ticks(len(minor_locs))
- for tick, loc, label in zip(minor_ticks, minor_locs, minor_labels):
- tick.update_position(loc)
- tick.label1.set_text(label)
- tick.label2.set_text(label)
- ticks = [*major_ticks, *minor_ticks]
-
- view_low, view_high = self.get_view_interval()
- if view_low > view_high:
- view_low, view_high = view_high, view_low
-
- interval_t = self.get_transform().transform([view_low, view_high])
-
- ticks_to_draw = []
- for tick in ticks:
- try:
- loc_t = self.get_transform().transform(tick.get_loc())
- except AssertionError:
- # transforms.transform doesn't allow masked values but
- # some scales might make them, so we need this try/except.
- pass
- else:
- if mtransforms._interval_contains_close(interval_t, loc_t):
- ticks_to_draw.append(tick)
-
- return ticks_to_draw
-
- def _get_ticklabel_bboxes(self, ticks, renderer=None):
- """Return lists of bboxes for ticks' label1's and label2's."""
- if renderer is None:
- renderer = self.figure._get_renderer()
- return ([tick.label1.get_window_extent(renderer)
- for tick in ticks if tick.label1.get_visible()],
- [tick.label2.get_window_extent(renderer)
- for tick in ticks if tick.label2.get_visible()])
-
- def get_tightbbox(self, renderer=None, *, for_layout_only=False):
- """
- Return a bounding box that encloses the axis. It only accounts
- tick labels, axis label, and offsetText.
-
- If *for_layout_only* is True, then the width of the label (if this
- is an x-axis) or the height of the label (if this is a y-axis) is
- collapsed to near zero. This allows tight/constrained_layout to ignore
- too-long labels when doing their layout.
- """
- if not self.get_visible():
- return
- if renderer is None:
- renderer = self.figure._get_renderer()
- ticks_to_draw = self._update_ticks()
-
- self._update_label_position(renderer)
-
- # go back to just this axis's tick labels
- tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
-
- self._update_offset_text_position(tlb1, tlb2)
- self.offsetText.set_text(self.major.formatter.get_offset())
-
- bboxes = [
- *(a.get_window_extent(renderer)
- for a in [self.offsetText]
- if a.get_visible()),
- *tlb1, *tlb2,
- ]
- # take care of label
- if self.label.get_visible():
- bb = self.label.get_window_extent(renderer)
- # for constrained/tight_layout, we want to ignore the label's
- # width/height because the adjustments they make can't be improved.
- # this code collapses the relevant direction
- if for_layout_only:
- if self.axis_name == "x" and bb.width > 0:
- bb.x0 = (bb.x0 + bb.x1) / 2 - 0.5
- bb.x1 = bb.x0 + 1.0
- if self.axis_name == "y" and bb.height > 0:
- bb.y0 = (bb.y0 + bb.y1) / 2 - 0.5
- bb.y1 = bb.y0 + 1.0
- bboxes.append(bb)
- bboxes = [b for b in bboxes
- if 0 < b.width < np.inf and 0 < b.height < np.inf]
- if bboxes:
- return mtransforms.Bbox.union(bboxes)
- else:
- return None
-
- def get_tick_padding(self):
- values = []
- if len(self.majorTicks):
- values.append(self.majorTicks[0].get_tick_padding())
- if len(self.minorTicks):
- values.append(self.minorTicks[0].get_tick_padding())
- return max(values, default=0)
-
- @martist.allow_rasterization
- def draw(self, renderer, *args, **kwargs):
- # docstring inherited
-
- if not self.get_visible():
- return
- renderer.open_group(__name__, gid=self.get_gid())
-
- ticks_to_draw = self._update_ticks()
- tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)
-
- for tick in ticks_to_draw:
- tick.draw(renderer)
-
- # Shift label away from axes to avoid overlapping ticklabels.
- self._update_label_position(renderer)
- self.label.draw(renderer)
-
- self._update_offset_text_position(tlb1, tlb2)
- self.offsetText.set_text(self.major.formatter.get_offset())
- self.offsetText.draw(renderer)
-
- renderer.close_group(__name__)
- self.stale = False
-
- def get_gridlines(self):
- r"""Return this Axis' grid lines as a list of `.Line2D`\s."""
- ticks = self.get_major_ticks()
- return cbook.silent_list('Line2D gridline',
- [tick.gridline for tick in ticks])
-
- def get_label(self):
- """Return the axis label as a Text instance."""
- return self.label
-
- def get_offset_text(self):
- """Return the axis offsetText as a Text instance."""
- return self.offsetText
-
- def get_pickradius(self):
- """Return the depth of the axis used by the picker."""
- return self._pickradius
-
- def get_majorticklabels(self):
- """Return this Axis' major tick labels, as a list of `~.text.Text`."""
- self._update_ticks()
- ticks = self.get_major_ticks()
- labels1 = [tick.label1 for tick in ticks if tick.label1.get_visible()]
- labels2 = [tick.label2 for tick in ticks if tick.label2.get_visible()]
- return labels1 + labels2
-
- def get_minorticklabels(self):
- """Return this Axis' minor tick labels, as a list of `~.text.Text`."""
- self._update_ticks()
- ticks = self.get_minor_ticks()
- labels1 = [tick.label1 for tick in ticks if tick.label1.get_visible()]
- labels2 = [tick.label2 for tick in ticks if tick.label2.get_visible()]
- return labels1 + labels2
-
- def get_ticklabels(self, minor=False, which=None):
- """
- Get this Axis' tick labels.
-
- Parameters
- ----------
- minor : bool
- Whether to return the minor or the major ticklabels.
-
- which : None, ('minor', 'major', 'both')
- Overrides *minor*.
-
- Selects which ticklabels to return
-
- Returns
- -------
- list of `~matplotlib.text.Text`
- """
- if which is not None:
- if which == 'minor':
- return self.get_minorticklabels()
- elif which == 'major':
- return self.get_majorticklabels()
- elif which == 'both':
- return self.get_majorticklabels() + self.get_minorticklabels()
- else:
- _api.check_in_list(['major', 'minor', 'both'], which=which)
- if minor:
- return self.get_minorticklabels()
- return self.get_majorticklabels()
-
- def get_majorticklines(self):
- r"""Return this Axis' major tick lines as a list of `.Line2D`\s."""
- lines = []
- ticks = self.get_major_ticks()
- for tick in ticks:
- lines.append(tick.tick1line)
- lines.append(tick.tick2line)
- return cbook.silent_list('Line2D ticklines', lines)
-
- def get_minorticklines(self):
- r"""Return this Axis' minor tick lines as a list of `.Line2D`\s."""
- lines = []
- ticks = self.get_minor_ticks()
- for tick in ticks:
- lines.append(tick.tick1line)
- lines.append(tick.tick2line)
- return cbook.silent_list('Line2D ticklines', lines)
-
- def get_ticklines(self, minor=False):
- r"""Return this Axis' tick lines as a list of `.Line2D`\s."""
- if minor:
- return self.get_minorticklines()
- return self.get_majorticklines()
-
- def get_majorticklocs(self):
- """Return this Axis' major tick locations in data coordinates."""
- return self.major.locator()
-
- def get_minorticklocs(self):
- """Return this Axis' minor tick locations in data coordinates."""
- # Remove minor ticks duplicating major ticks.
- minor_locs = np.asarray(self.minor.locator())
- if self.remove_overlapping_locs:
- major_locs = self.major.locator()
- transform = self._scale.get_transform()
- tr_minor_locs = transform.transform(minor_locs)
- tr_major_locs = transform.transform(major_locs)
- lo, hi = sorted(transform.transform(self.get_view_interval()))
- # Use the transformed view limits as scale. 1e-5 is the default
- # rtol for np.isclose.
- tol = (hi - lo) * 1e-5
- mask = np.isclose(tr_minor_locs[:, None], tr_major_locs[None, :],
- atol=tol, rtol=0).any(axis=1)
- minor_locs = minor_locs[~mask]
- return minor_locs
-
- def get_ticklocs(self, *, minor=False):
- """
- Return this Axis' tick locations in data coordinates.
-
- The locations are not clipped to the current axis limits and hence
- may contain locations that are not visible in the output.
-
- Parameters
- ----------
- minor : bool, default: False
- True to return the minor tick directions,
- False to return the major tick directions.
-
- Returns
- -------
- array of tick locations
- """
- return self.get_minorticklocs() if minor else self.get_majorticklocs()
-
- def get_ticks_direction(self, minor=False):
- """
- Return an array of this Axis' tick directions.
-
- Parameters
- ----------
- minor : bool, default: False
- True to return the minor tick directions,
- False to return the major tick directions.
-
- Returns
- -------
- array of tick directions
- """
- if minor:
- return np.array(
- [tick._tickdir for tick in self.get_minor_ticks()])
- else:
- return np.array(
- [tick._tickdir for tick in self.get_major_ticks()])
-
- def _get_tick(self, major):
- """Return the default tick instance."""
- if self._tick_class is None:
- raise NotImplementedError(
- f"The Axis subclass {self.__class__.__name__} must define "
- "_tick_class or reimplement _get_tick()")
- tick_kw = self._major_tick_kw if major else self._minor_tick_kw
- return self._tick_class(self.axes, 0, major=major, **tick_kw)
-
- def _get_tick_label_size(self, axis_name):
- """
- Return the text size of tick labels for this Axis.
-
- This is a convenience function to avoid having to create a `Tick` in
- `.get_tick_space`, since it is expensive.
- """
- tick_kw = self._major_tick_kw
- size = tick_kw.get('labelsize',
- mpl.rcParams[f'{axis_name}tick.labelsize'])
- return mtext.FontProperties(size=size).get_size_in_points()
-
- def _copy_tick_props(self, src, dest):
- """Copy the properties from *src* tick to *dest* tick."""
- if src is None or dest is None:
- return
- dest.label1.update_from(src.label1)
- dest.label2.update_from(src.label2)
- dest.tick1line.update_from(src.tick1line)
- dest.tick2line.update_from(src.tick2line)
- dest.gridline.update_from(src.gridline)
-
- def get_label_text(self):
- """Get the text of the label."""
- return self.label.get_text()
-
- def get_major_locator(self):
- """Get the locator of the major ticker."""
- return self.major.locator
-
- def get_minor_locator(self):
- """Get the locator of the minor ticker."""
- return self.minor.locator
-
- def get_major_formatter(self):
- """Get the formatter of the major ticker."""
- return self.major.formatter
-
- def get_minor_formatter(self):
- """Get the formatter of the minor ticker."""
- return self.minor.formatter
-
- def get_major_ticks(self, numticks=None):
- r"""
- Return the list of major `.Tick`\s.
-
- .. warning::
-
- Ticks are not guaranteed to be persistent. Various operations
- can create, delete and modify the Tick instances. There is an
- imminent risk that changes to individual ticks will not
- survive if you work on the figure further (including also
- panning/zooming on a displayed figure).
-
- Working on the individual ticks is a method of last resort.
- Use `.set_tick_params` instead if possible.
- """
- if numticks is None:
- numticks = len(self.get_majorticklocs())
-
- while len(self.majorTicks) < numticks:
- # Update the new tick label properties from the old.
- tick = self._get_tick(major=True)
- self.majorTicks.append(tick)
- self._copy_tick_props(self.majorTicks[0], tick)
-
- return self.majorTicks[:numticks]
-
- def get_minor_ticks(self, numticks=None):
- r"""
- Return the list of minor `.Tick`\s.
-
- .. warning::
-
- Ticks are not guaranteed to be persistent. Various operations
- can create, delete and modify the Tick instances. There is an
- imminent risk that changes to individual ticks will not
- survive if you work on the figure further (including also
- panning/zooming on a displayed figure).
-
- Working on the individual ticks is a method of last resort.
- Use `.set_tick_params` instead if possible.
- """
- if numticks is None:
- numticks = len(self.get_minorticklocs())
-
- while len(self.minorTicks) < numticks:
- # Update the new tick label properties from the old.
- tick = self._get_tick(major=False)
- self.minorTicks.append(tick)
- self._copy_tick_props(self.minorTicks[0], tick)
-
- return self.minorTicks[:numticks]
-
- def grid(self, visible=None, which='major', **kwargs):
- """
- Configure the grid lines.
-
- Parameters
- ----------
- visible : bool or None
- Whether to show the grid lines. If any *kwargs* are supplied, it
- is assumed you want the grid on and *visible* will be set to True.
-
- If *visible* is *None* and there are no *kwargs*, this toggles the
- visibility of the lines.
-
- which : {'major', 'minor', 'both'}
- The grid lines to apply the changes on.
-
- **kwargs : `~matplotlib.lines.Line2D` properties
- Define the line properties of the grid, e.g.::
-
- grid(color='r', linestyle='-', linewidth=2)
- """
- if kwargs:
- if visible is None:
- visible = True
- elif not visible: # something false-like but not None
- _api.warn_external('First parameter to grid() is false, '
- 'but line properties are supplied. The '
- 'grid will be enabled.')
- visible = True
- which = which.lower()
- _api.check_in_list(['major', 'minor', 'both'], which=which)
- gridkw = {f'grid_{name}': value for name, value in kwargs.items()}
- if which in ['minor', 'both']:
- gridkw['gridOn'] = (not self._minor_tick_kw['gridOn']
- if visible is None else visible)
- self.set_tick_params(which='minor', **gridkw)
- if which in ['major', 'both']:
- gridkw['gridOn'] = (not self._major_tick_kw['gridOn']
- if visible is None else visible)
- self.set_tick_params(which='major', **gridkw)
- self.stale = True
-
- def update_units(self, data):
- """
- Introspect *data* for units converter and update the
- ``axis.converter`` instance if necessary. Return *True*
- if *data* is registered for unit conversion.
- """
- converter = munits.registry.get_converter(data)
- if converter is None:
- return False
-
- neednew = self.converter != converter
- self.converter = converter
- default = self.converter.default_units(data, self)
- if default is not None and self.units is None:
- self.set_units(default)
-
- elif neednew:
- self._update_axisinfo()
- self.stale = True
- return True
-
- def _update_axisinfo(self):
- """
- Check the axis converter for the stored units to see if the
- axis info needs to be updated.
- """
- if self.converter is None:
- return
-
- info = self.converter.axisinfo(self.units, self)
-
- if info is None:
- return
- if info.majloc is not None and \
- self.major.locator != info.majloc and self.isDefault_majloc:
- self.set_major_locator(info.majloc)
- self.isDefault_majloc = True
- if info.minloc is not None and \
- self.minor.locator != info.minloc and self.isDefault_minloc:
- self.set_minor_locator(info.minloc)
- self.isDefault_minloc = True
- if info.majfmt is not None and \
- self.major.formatter != info.majfmt and self.isDefault_majfmt:
- self.set_major_formatter(info.majfmt)
- self.isDefault_majfmt = True
- if info.minfmt is not None and \
- self.minor.formatter != info.minfmt and self.isDefault_minfmt:
- self.set_minor_formatter(info.minfmt)
- self.isDefault_minfmt = True
- if info.label is not None and self.isDefault_label:
- self.set_label_text(info.label)
- self.isDefault_label = True
-
- self.set_default_intervals()
-
- def have_units(self):
- return self.converter is not None or self.units is not None
-
- def convert_units(self, x):
- # If x is natively supported by Matplotlib, doesn't need converting
- if munits._is_natively_supported(x):
- return x
-
- if self.converter is None:
- self.converter = munits.registry.get_converter(x)
-
- if self.converter is None:
- return x
- try:
- ret = self.converter.convert(x, self.units, self)
- except Exception as e:
- raise munits.ConversionError('Failed to convert value(s) to axis '
- f'units: {x!r}') from e
- return ret
-
- def set_units(self, u):
- """
- Set the units for axis.
-
- Parameters
- ----------
- u : units tag
-
- Notes
- -----
- The units of any shared axis will also be updated.
- """
- if u == self.units:
- return
- for axis in self._get_shared_axis():
- axis.units = u
- axis._update_axisinfo()
- axis.callbacks.process('units')
- axis.stale = True
-
- def get_units(self):
- """Return the units for axis."""
- return self.units
-
- def set_label_text(self, label, fontdict=None, **kwargs):
- """
- Set the text value of the axis label.
-
- Parameters
- ----------
- label : str
- Text string.
- fontdict : dict
- Text properties.
-
- .. admonition:: Discouraged
-
- The use of *fontdict* is discouraged. Parameters should be passed as
- individual keyword arguments or using dictionary-unpacking
- ``set_label_text(..., **fontdict)``.
-
- **kwargs
- Merged into fontdict.
- """
- self.isDefault_label = False
- self.label.set_text(label)
- if fontdict is not None:
- self.label.update(fontdict)
- self.label.update(kwargs)
- self.stale = True
- return self.label
-
- def set_major_formatter(self, formatter):
- """
- Set the formatter of the major ticker.
-
- In addition to a `~matplotlib.ticker.Formatter` instance,
- this also accepts a ``str`` or function.
-
- For a ``str`` a `~matplotlib.ticker.StrMethodFormatter` is used.
- The field used for the value must be labeled ``'x'`` and the field used
- for the position must be labeled ``'pos'``.
- See the `~matplotlib.ticker.StrMethodFormatter` documentation for
- more information.
-
- For a function, a `~matplotlib.ticker.FuncFormatter` is used.
- The function must take two inputs (a tick value ``x`` and a
- position ``pos``), and return a string containing the corresponding
- tick label.
- See the `~matplotlib.ticker.FuncFormatter` documentation for
- more information.
-
- Parameters
- ----------
- formatter : `~matplotlib.ticker.Formatter`, ``str``, or function
- """
- self._set_formatter(formatter, self.major)
-
- def set_minor_formatter(self, formatter):
- """
- Set the formatter of the minor ticker.
-
- In addition to a `~matplotlib.ticker.Formatter` instance,
- this also accepts a ``str`` or function.
- See `.Axis.set_major_formatter` for more information.
-
- Parameters
- ----------
- formatter : `~matplotlib.ticker.Formatter`, ``str``, or function
- """
- self._set_formatter(formatter, self.minor)
-
- def _set_formatter(self, formatter, level):
- if isinstance(formatter, str):
- formatter = mticker.StrMethodFormatter(formatter)
- # Don't allow any other TickHelper to avoid easy-to-make errors,
- # like using a Locator instead of a Formatter.
- elif (callable(formatter) and
- not isinstance(formatter, mticker.TickHelper)):
- formatter = mticker.FuncFormatter(formatter)
- else:
- _api.check_isinstance(mticker.Formatter, formatter=formatter)
-
- if (isinstance(formatter, mticker.FixedFormatter)
- and len(formatter.seq) > 0
- and not isinstance(level.locator, mticker.FixedLocator)):
- _api.warn_external('FixedFormatter should only be used together '
- 'with FixedLocator')
-
- if level == self.major:
- self.isDefault_majfmt = False
- else:
- self.isDefault_minfmt = False
-
- level.formatter = formatter
- formatter.set_axis(self)
- self.stale = True
-
- def set_major_locator(self, locator):
- """
- Set the locator of the major ticker.
-
- Parameters
- ----------
- locator : `~matplotlib.ticker.Locator`
- """
- _api.check_isinstance(mticker.Locator, locator=locator)
- self.isDefault_majloc = False
- self.major.locator = locator
- if self.major.formatter:
- self.major.formatter._set_locator(locator)
- locator.set_axis(self)
- self.stale = True
-
- def set_minor_locator(self, locator):
- """
- Set the locator of the minor ticker.
-
- Parameters
- ----------
- locator : `~matplotlib.ticker.Locator`
- """
- _api.check_isinstance(mticker.Locator, locator=locator)
- self.isDefault_minloc = False
- self.minor.locator = locator
- if self.minor.formatter:
- self.minor.formatter._set_locator(locator)
- locator.set_axis(self)
- self.stale = True
-
- def set_pickradius(self, pickradius):
- """
- Set the depth of the axis used by the picker.
-
- Parameters
- ----------
- pickradius : float
- The acceptance radius for containment tests.
- See also `.Axis.contains`.
- """
- if not isinstance(pickradius, Real) or pickradius < 0:
- raise ValueError("pick radius should be a distance")
- self._pickradius = pickradius
-
- pickradius = property(
- get_pickradius, set_pickradius, doc="The acceptance radius for "
- "containment tests. See also `.Axis.contains`.")
-
- # Helper for set_ticklabels. Defining it here makes it picklable.
- @staticmethod
- def _format_with_dict(tickd, x, pos):
- return tickd.get(x, "")
-
- @_api.rename_parameter("3.7", "ticklabels", "labels")
- def set_ticklabels(self, labels, *, minor=False, fontdict=None, **kwargs):
- r"""
- [*Discouraged*] Set this Axis' tick labels with list of string labels.
-
- .. admonition:: Discouraged
-
- The use of this method is discouraged, because of the dependency on
- tick positions. In most cases, you'll want to use
- ``Axes.set_[x/y/z]ticks(positions, labels)`` or ``Axis.set_ticks``
- instead.
-
- If you are using this method, you should always fix the tick
- positions before, e.g. by using `.Axis.set_ticks` or by explicitly
- setting a `~.ticker.FixedLocator`. Otherwise, ticks are free to
- move and the labels may end up in unexpected positions.
-
- Parameters
- ----------
- labels : sequence of str or of `.Text`\s
- Texts for labeling each tick location in the sequence set by
- `.Axis.set_ticks`; the number of labels must match the number of
- locations.
-
- minor : bool
- If True, set minor ticks instead of major ticks.
-
- fontdict : dict, optional
-
- .. admonition:: Discouraged
-
- The use of *fontdict* is discouraged. Parameters should be passed as
- individual keyword arguments or using dictionary-unpacking
- ``set_ticklabels(..., **fontdict)``.
-
- A dictionary controlling the appearance of the ticklabels.
- The default *fontdict* is::
-
- {'fontsize': rcParams['axes.titlesize'],
- 'fontweight': rcParams['axes.titleweight'],
- 'verticalalignment': 'baseline',
- 'horizontalalignment': loc}
-
- **kwargs
- Text properties.
-
- .. warning::
-
- This only sets the properties of the current ticks.
- Ticks are not guaranteed to be persistent. Various operations
- can create, delete and modify the Tick instances. There is an
- imminent risk that these settings can get lost if you work on
- the figure further (including also panning/zooming on a
- displayed figure).
-
- Use `.set_tick_params` instead if possible.
-
- Returns
- -------
- list of `.Text`\s
- For each tick, includes ``tick.label1`` if it is visible, then
- ``tick.label2`` if it is visible, in that order.
- """
- try:
- labels = [t.get_text() if hasattr(t, 'get_text') else t
- for t in labels]
- except TypeError:
- raise TypeError(f"{labels:=} must be a sequence") from None
- locator = (self.get_minor_locator() if minor
- else self.get_major_locator())
- if not labels:
- # eg labels=[]:
- formatter = mticker.NullFormatter()
- elif isinstance(locator, mticker.FixedLocator):
- # Passing [] as a list of labels is often used as a way to
- # remove all tick labels, so only error for > 0 labels
- if len(locator.locs) != len(labels) and len(labels) != 0:
- raise ValueError(
- "The number of FixedLocator locations"
- f" ({len(locator.locs)}), usually from a call to"
- " set_ticks, does not match"
- f" the number of labels ({len(labels)}).")
- tickd = {loc: lab for loc, lab in zip(locator.locs, labels)}
- func = functools.partial(self._format_with_dict, tickd)
- formatter = mticker.FuncFormatter(func)
- else:
- _api.warn_external(
- "set_ticklabels() should only be used with a fixed number of "
- "ticks, i.e. after set_ticks() or using a FixedLocator.")
- formatter = mticker.FixedFormatter(labels)
-
- with warnings.catch_warnings():
- warnings.filterwarnings(
- "ignore",
- message="FixedFormatter should only be used together with FixedLocator")
- if minor:
- self.set_minor_formatter(formatter)
- locs = self.get_minorticklocs()
- ticks = self.get_minor_ticks(len(locs))
- else:
- self.set_major_formatter(formatter)
- locs = self.get_majorticklocs()
- ticks = self.get_major_ticks(len(locs))
-
- ret = []
- if fontdict is not None:
- kwargs.update(fontdict)
- for pos, (loc, tick) in enumerate(zip(locs, ticks)):
- tick.update_position(loc)
- tick_label = formatter(loc, pos)
- # deal with label1
- tick.label1.set_text(tick_label)
- tick.label1._internal_update(kwargs)
- # deal with label2
- tick.label2.set_text(tick_label)
- tick.label2._internal_update(kwargs)
- # only return visible tick labels
- if tick.label1.get_visible():
- ret.append(tick.label1)
- if tick.label2.get_visible():
- ret.append(tick.label2)
-
- self.stale = True
- return ret
-
- def _set_tick_locations(self, ticks, *, minor=False):
- # see docstring of set_ticks
-
- # XXX if the user changes units, the information will be lost here
- ticks = self.convert_units(ticks)
- locator = mticker.FixedLocator(ticks) # validate ticks early.
- if len(ticks):
- for axis in self._get_shared_axis():
- # set_view_interval maintains any preexisting inversion.
- axis.set_view_interval(min(ticks), max(ticks))
- self.axes.stale = True
- if minor:
- self.set_minor_locator(locator)
- return self.get_minor_ticks(len(ticks))
- else:
- self.set_major_locator(locator)
- return self.get_major_ticks(len(ticks))
-
- def set_ticks(self, ticks, labels=None, *, minor=False, **kwargs):
- """
- Set this Axis' tick locations and optionally tick labels.
-
- If necessary, the view limits of the Axis are expanded so that all
- given ticks are visible.
-
- Parameters
- ----------
- ticks : 1D array-like
- Array of tick locations. The axis `.Locator` is replaced by a
- `~.ticker.FixedLocator`.
-
- The values may be either floats or in axis units.
-
- Pass an empty list to remove all ticks::
-
- set_ticks([])
-
- Some tick formatters will not label arbitrary tick positions;
- e.g. log formatters only label decade ticks by default. In
- such a case you can set a formatter explicitly on the axis
- using `.Axis.set_major_formatter` or provide formatted
- *labels* yourself.
- labels : list of str, optional
- Tick labels for each location in *ticks*. *labels* must be of the same
- length as *ticks*. If not set, the labels are generate using the axis
- tick `.Formatter`.
- minor : bool, default: False
- If ``False``, set the major ticks; if ``True``, the minor ticks.
- **kwargs
- `.Text` properties for the labels. Using these is only allowed if
- you pass *labels*. In other cases, please use `~.Axes.tick_params`.
-
- Notes
- -----
- The mandatory expansion of the view limits is an intentional design
- choice to prevent the surprise of a non-visible tick. If you need
- other limits, you should set the limits explicitly after setting the
- ticks.
- """
- if labels is None and kwargs:
- first_key = next(iter(kwargs))
- raise ValueError(
- f"Incorrect use of keyword argument {first_key!r}. Keyword arguments "
- "other than 'minor' modify the text labels and can only be used if "
- "'labels' are passed as well.")
- result = self._set_tick_locations(ticks, minor=minor)
- if labels is not None:
- self.set_ticklabels(labels, minor=minor, **kwargs)
- return result
-
- def _get_tick_boxes_siblings(self, renderer):
- """
- Get the bounding boxes for this `.axis` and its siblings
- as set by `.Figure.align_xlabels` or `.Figure.align_ylabels`.
-
- By default, it just gets bboxes for *self*.
- """
- # Get the Grouper keeping track of x or y label groups for this figure.
- name = self._get_axis_name()
- if name not in self.figure._align_label_groups:
- return [], []
- grouper = self.figure._align_label_groups[name]
- bboxes = []
- bboxes2 = []
- # If we want to align labels from other Axes:
- for ax in grouper.get_siblings(self.axes):
- axis = ax._axis_map[name]
- ticks_to_draw = axis._update_ticks()
- tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
- bboxes.extend(tlb)
- bboxes2.extend(tlb2)
- return bboxes, bboxes2
-
- def _update_label_position(self, renderer):
- """
- Update the label position based on the bounding box enclosing
- all the ticklabels and axis spine.
- """
- raise NotImplementedError('Derived must override')
-
- def _update_offset_text_position(self, bboxes, bboxes2):
- """
- Update the offset text position based on the sequence of bounding
- boxes of all the ticklabels.
- """
- raise NotImplementedError('Derived must override')
-
- def axis_date(self, tz=None):
- """
- Set up axis ticks and labels to treat data along this Axis as dates.
-
- Parameters
- ----------
- tz : str or `datetime.tzinfo`, default: :rc:`timezone`
- The timezone used to create date labels.
- """
- # By providing a sample datetime instance with the desired timezone,
- # the registered converter can be selected, and the "units" attribute,
- # which is the timezone, can be set.
- if isinstance(tz, str):
- import dateutil.tz
- tz = dateutil.tz.gettz(tz)
- self.update_units(datetime.datetime(2009, 1, 1, 0, 0, 0, 0, tz))
-
- def get_tick_space(self):
- """Return the estimated number of ticks that can fit on the axis."""
- # Must be overridden in the subclass
- raise NotImplementedError()
-
- def _get_ticks_position(self):
- """
- Helper for `XAxis.get_ticks_position` and `YAxis.get_ticks_position`.
-
- Check the visibility of tick1line, label1, tick2line, and label2 on
- the first major and the first minor ticks, and return
-
- - 1 if only tick1line and label1 are visible (which corresponds to
- "bottom" for the x-axis and "left" for the y-axis);
- - 2 if only tick2line and label2 are visible (which corresponds to
- "top" for the x-axis and "right" for the y-axis);
- - "default" if only tick1line, tick2line and label1 are visible;
- - "unknown" otherwise.
- """
- major = self.majorTicks[0]
- minor = self.minorTicks[0]
- if all(tick.tick1line.get_visible()
- and not tick.tick2line.get_visible()
- and tick.label1.get_visible()
- and not tick.label2.get_visible()
- for tick in [major, minor]):
- return 1
- elif all(tick.tick2line.get_visible()
- and not tick.tick1line.get_visible()
- and tick.label2.get_visible()
- and not tick.label1.get_visible()
- for tick in [major, minor]):
- return 2
- elif all(tick.tick1line.get_visible()
- and tick.tick2line.get_visible()
- and tick.label1.get_visible()
- and not tick.label2.get_visible()
- for tick in [major, minor]):
- return "default"
- else:
- return "unknown"
-
- def get_label_position(self):
- """
- Return the label position (top or bottom)
- """
- return self.label_position
-
- def set_label_position(self, position):
- """
- Set the label position (top or bottom)
-
- Parameters
- ----------
- position : {'top', 'bottom'}
- """
- raise NotImplementedError()
-
- def get_minpos(self):
- raise NotImplementedError()
-
-
-def _make_getset_interval(method_name, lim_name, attr_name):
- """
- Helper to generate ``get_{data,view}_interval`` and
- ``set_{data,view}_interval`` implementations.
- """
-
- def getter(self):
- # docstring inherited.
- return getattr(getattr(self.axes, lim_name), attr_name)
-
- def setter(self, vmin, vmax, ignore=False):
- # docstring inherited.
- if ignore:
- setattr(getattr(self.axes, lim_name), attr_name, (vmin, vmax))
- else:
- oldmin, oldmax = getter(self)
- if oldmin < oldmax:
- setter(self, min(vmin, vmax, oldmin), max(vmin, vmax, oldmax),
- ignore=True)
- else:
- setter(self, max(vmin, vmax, oldmin), min(vmin, vmax, oldmax),
- ignore=True)
- self.stale = True
-
- getter.__name__ = f"get_{method_name}_interval"
- setter.__name__ = f"set_{method_name}_interval"
-
- return getter, setter
-
-
-class XAxis(Axis):
- __name__ = 'xaxis'
- axis_name = 'x' #: Read-only name identifying the axis.
- _tick_class = XTick
-
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- self._init()
-
- def _init(self):
- """
- Initialize the label and offsetText instance values and
- `label_position` / `offset_text_position`.
- """
- # x in axes coords, y in display coords (to be updated at draw time by
- # _update_label_positions and _update_offset_text_position).
- self.label.set(
- x=0.5, y=0,
- verticalalignment='top', horizontalalignment='center',
- transform=mtransforms.blended_transform_factory(
- self.axes.transAxes, mtransforms.IdentityTransform()),
- )
- self.label_position = 'bottom'
-
- if mpl.rcParams['xtick.labelcolor'] == 'inherit':
- tick_color = mpl.rcParams['xtick.color']
- else:
- tick_color = mpl.rcParams['xtick.labelcolor']
-
- self.offsetText.set(
- x=1, y=0,
- verticalalignment='top', horizontalalignment='right',
- transform=mtransforms.blended_transform_factory(
- self.axes.transAxes, mtransforms.IdentityTransform()),
- fontsize=mpl.rcParams['xtick.labelsize'],
- color=tick_color
- )
- self.offset_text_position = 'bottom'
-
- def contains(self, mouseevent):
- """Test whether the mouse event occurred in the x-axis."""
- if self._different_canvas(mouseevent):
- return False, {}
- x, y = mouseevent.x, mouseevent.y
- try:
- trans = self.axes.transAxes.inverted()
- xaxes, yaxes = trans.transform((x, y))
- except ValueError:
- return False, {}
- (l, b), (r, t) = self.axes.transAxes.transform([(0, 0), (1, 1)])
- inaxis = 0 <= xaxes <= 1 and (
- b - self._pickradius < y < b or
- t < y < t + self._pickradius)
- return inaxis, {}
-
- def set_label_position(self, position):
- """
- Set the label position (top or bottom)
-
- Parameters
- ----------
- position : {'top', 'bottom'}
- """
- self.label.set_verticalalignment(_api.check_getitem({
- 'top': 'baseline', 'bottom': 'top',
- }, position=position))
- self.label_position = position
- self.stale = True
-
- def _update_label_position(self, renderer):
- """
- Update the label position based on the bounding box enclosing
- all the ticklabels and axis spine
- """
- if not self._autolabelpos:
- return
-
- # get bounding boxes for this axis and any siblings
- # that have been set by `fig.align_xlabels()`
- bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
-
- x, y = self.label.get_position()
- if self.label_position == 'bottom':
- try:
- spine = self.axes.spines['bottom']
- spinebbox = spine.get_window_extent()
- except KeyError:
- # use Axes if spine doesn't exist
- spinebbox = self.axes.bbox
- bbox = mtransforms.Bbox.union(bboxes + [spinebbox])
- bottom = bbox.y0
-
- self.label.set_position(
- (x, bottom - self.labelpad * self.figure.dpi / 72)
- )
- else:
- try:
- spine = self.axes.spines['top']
- spinebbox = spine.get_window_extent()
- except KeyError:
- # use Axes if spine doesn't exist
- spinebbox = self.axes.bbox
- bbox = mtransforms.Bbox.union(bboxes2 + [spinebbox])
- top = bbox.y1
-
- self.label.set_position(
- (x, top + self.labelpad * self.figure.dpi / 72)
- )
-
- def _update_offset_text_position(self, bboxes, bboxes2):
- """
- Update the offset_text position based on the sequence of bounding
- boxes of all the ticklabels
- """
- x, y = self.offsetText.get_position()
- if not hasattr(self, '_tick_position'):
- self._tick_position = 'bottom'
- if self._tick_position == 'bottom':
- if not len(bboxes):
- bottom = self.axes.bbox.ymin
- else:
- bbox = mtransforms.Bbox.union(bboxes)
- bottom = bbox.y0
- y = bottom - self.OFFSETTEXTPAD * self.figure.dpi / 72
- else:
- if not len(bboxes2):
- top = self.axes.bbox.ymax
- else:
- bbox = mtransforms.Bbox.union(bboxes2)
- top = bbox.y1
- y = top + self.OFFSETTEXTPAD * self.figure.dpi / 72
- self.offsetText.set_position((x, y))
-
- def set_ticks_position(self, position):
- """
- Set the ticks position.
-
- Parameters
- ----------
- position : {'top', 'bottom', 'both', 'default', 'none'}
- 'both' sets the ticks to appear on both positions, but does not
- change the tick labels. 'default' resets the tick positions to
- the default: ticks on both positions, labels at bottom. 'none'
- can be used if you don't want any ticks. 'none' and 'both'
- affect only the ticks, not the labels.
- """
- if position == 'top':
- self.set_tick_params(which='both', top=True, labeltop=True,
- bottom=False, labelbottom=False)
- self._tick_position = 'top'
- self.offsetText.set_verticalalignment('bottom')
- elif position == 'bottom':
- self.set_tick_params(which='both', top=False, labeltop=False,
- bottom=True, labelbottom=True)
- self._tick_position = 'bottom'
- self.offsetText.set_verticalalignment('top')
- elif position == 'both':
- self.set_tick_params(which='both', top=True,
- bottom=True)
- elif position == 'none':
- self.set_tick_params(which='both', top=False,
- bottom=False)
- elif position == 'default':
- self.set_tick_params(which='both', top=True, labeltop=False,
- bottom=True, labelbottom=True)
- self._tick_position = 'bottom'
- self.offsetText.set_verticalalignment('top')
- else:
- _api.check_in_list(['top', 'bottom', 'both', 'default', 'none'],
- position=position)
- self.stale = True
-
- def tick_top(self):
- """
- Move ticks and ticklabels (if present) to the top of the Axes.
- """
- label = True
- if 'label1On' in self._major_tick_kw:
- label = (self._major_tick_kw['label1On']
- or self._major_tick_kw['label2On'])
- self.set_ticks_position('top')
- # If labels were turned off before this was called, leave them off.
- self.set_tick_params(which='both', labeltop=label)
-
- def tick_bottom(self):
- """
- Move ticks and ticklabels (if present) to the bottom of the Axes.
- """
- label = True
- if 'label1On' in self._major_tick_kw:
- label = (self._major_tick_kw['label1On']
- or self._major_tick_kw['label2On'])
- self.set_ticks_position('bottom')
- # If labels were turned off before this was called, leave them off.
- self.set_tick_params(which='both', labelbottom=label)
-
- def get_ticks_position(self):
- """
- Return the ticks position ("top", "bottom", "default", or "unknown").
- """
- return {1: "bottom", 2: "top",
- "default": "default", "unknown": "unknown"}[
- self._get_ticks_position()]
-
- get_view_interval, set_view_interval = _make_getset_interval(
- "view", "viewLim", "intervalx")
- get_data_interval, set_data_interval = _make_getset_interval(
- "data", "dataLim", "intervalx")
-
- def get_minpos(self):
- return self.axes.dataLim.minposx
-
- def set_default_intervals(self):
- # docstring inherited
- # only change view if dataLim has not changed and user has
- # not changed the view:
- if (not self.axes.dataLim.mutatedx() and
- not self.axes.viewLim.mutatedx()):
- if self.converter is not None:
- info = self.converter.axisinfo(self.units, self)
- if info.default_limits is not None:
- xmin, xmax = self.convert_units(info.default_limits)
- self.axes.viewLim.intervalx = xmin, xmax
- self.stale = True
-
- def get_tick_space(self):
- ends = mtransforms.Bbox.unit().transformed(
- self.axes.transAxes - self.figure.dpi_scale_trans)
- length = ends.width * 72
- # There is a heuristic here that the aspect ratio of tick text
- # is no more than 3:1
- size = self._get_tick_label_size('x') * 3
- if size > 0:
- return int(np.floor(length / size))
- else:
- return 2**31 - 1
-
-
-class YAxis(Axis):
- __name__ = 'yaxis'
- axis_name = 'y' #: Read-only name identifying the axis.
- _tick_class = YTick
-
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- self._init()
-
- def _init(self):
- """
- Initialize the label and offsetText instance values and
- `label_position` / `offset_text_position`.
- """
- # x in display coords, y in axes coords (to be updated at draw time by
- # _update_label_positions and _update_offset_text_position).
- self.label.set(
- x=0, y=0.5,
- verticalalignment='bottom', horizontalalignment='center',
- rotation='vertical', rotation_mode='anchor',
- transform=mtransforms.blended_transform_factory(
- mtransforms.IdentityTransform(), self.axes.transAxes),
- )
- self.label_position = 'left'
-
- if mpl.rcParams['ytick.labelcolor'] == 'inherit':
- tick_color = mpl.rcParams['ytick.color']
- else:
- tick_color = mpl.rcParams['ytick.labelcolor']
-
- # x in axes coords, y in display coords(!).
- self.offsetText.set(
- x=0, y=0.5,
- verticalalignment='baseline', horizontalalignment='left',
- transform=mtransforms.blended_transform_factory(
- self.axes.transAxes, mtransforms.IdentityTransform()),
- fontsize=mpl.rcParams['ytick.labelsize'],
- color=tick_color
- )
- self.offset_text_position = 'left'
-
- def contains(self, mouseevent):
- # docstring inherited
- if self._different_canvas(mouseevent):
- return False, {}
- x, y = mouseevent.x, mouseevent.y
- try:
- trans = self.axes.transAxes.inverted()
- xaxes, yaxes = trans.transform((x, y))
- except ValueError:
- return False, {}
- (l, b), (r, t) = self.axes.transAxes.transform([(0, 0), (1, 1)])
- inaxis = 0 <= yaxes <= 1 and (
- l - self._pickradius < x < l or
- r < x < r + self._pickradius)
- return inaxis, {}
-
- def set_label_position(self, position):
- """
- Set the label position (left or right)
-
- Parameters
- ----------
- position : {'left', 'right'}
- """
- self.label.set_rotation_mode('anchor')
- self.label.set_verticalalignment(_api.check_getitem({
- 'left': 'bottom', 'right': 'top',
- }, position=position))
- self.label_position = position
- self.stale = True
-
- def _update_label_position(self, renderer):
- """
- Update the label position based on the bounding box enclosing
- all the ticklabels and axis spine
- """
- if not self._autolabelpos:
- return
-
- # get bounding boxes for this axis and any siblings
- # that have been set by `fig.align_ylabels()`
- bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
- x, y = self.label.get_position()
- if self.label_position == 'left':
- try:
- spine = self.axes.spines['left']
- spinebbox = spine.get_window_extent()
- except KeyError:
- # use Axes if spine doesn't exist
- spinebbox = self.axes.bbox
- bbox = mtransforms.Bbox.union(bboxes + [spinebbox])
- left = bbox.x0
- self.label.set_position(
- (left - self.labelpad * self.figure.dpi / 72, y)
- )
-
- else:
- try:
- spine = self.axes.spines['right']
- spinebbox = spine.get_window_extent()
- except KeyError:
- # use Axes if spine doesn't exist
- spinebbox = self.axes.bbox
-
- bbox = mtransforms.Bbox.union(bboxes2 + [spinebbox])
- right = bbox.x1
- self.label.set_position(
- (right + self.labelpad * self.figure.dpi / 72, y)
- )
-
- def _update_offset_text_position(self, bboxes, bboxes2):
- """
- Update the offset_text position based on the sequence of bounding
- boxes of all the ticklabels
- """
- x, _ = self.offsetText.get_position()
- if 'outline' in self.axes.spines:
- # Special case for colorbars:
- bbox = self.axes.spines['outline'].get_window_extent()
- else:
- bbox = self.axes.bbox
- top = bbox.ymax
- self.offsetText.set_position(
- (x, top + self.OFFSETTEXTPAD * self.figure.dpi / 72)
- )
-
- def set_offset_position(self, position):
- """
- Parameters
- ----------
- position : {'left', 'right'}
- """
- x, y = self.offsetText.get_position()
- x = _api.check_getitem({'left': 0, 'right': 1}, position=position)
-
- self.offsetText.set_ha(position)
- self.offsetText.set_position((x, y))
- self.stale = True
-
- def set_ticks_position(self, position):
- """
- Set the ticks position.
-
- Parameters
- ----------
- position : {'left', 'right', 'both', 'default', 'none'}
- 'both' sets the ticks to appear on both positions, but does not
- change the tick labels. 'default' resets the tick positions to
- the default: ticks on both positions, labels at left. 'none'
- can be used if you don't want any ticks. 'none' and 'both'
- affect only the ticks, not the labels.
- """
- if position == 'right':
- self.set_tick_params(which='both', right=True, labelright=True,
- left=False, labelleft=False)
- self.set_offset_position(position)
- elif position == 'left':
- self.set_tick_params(which='both', right=False, labelright=False,
- left=True, labelleft=True)
- self.set_offset_position(position)
- elif position == 'both':
- self.set_tick_params(which='both', right=True,
- left=True)
- elif position == 'none':
- self.set_tick_params(which='both', right=False,
- left=False)
- elif position == 'default':
- self.set_tick_params(which='both', right=True, labelright=False,
- left=True, labelleft=True)
- else:
- _api.check_in_list(['left', 'right', 'both', 'default', 'none'],
- position=position)
- self.stale = True
-
- def tick_right(self):
- """
- Move ticks and ticklabels (if present) to the right of the Axes.
- """
- label = True
- if 'label1On' in self._major_tick_kw:
- label = (self._major_tick_kw['label1On']
- or self._major_tick_kw['label2On'])
- self.set_ticks_position('right')
- # if labels were turned off before this was called
- # leave them off
- self.set_tick_params(which='both', labelright=label)
-
- def tick_left(self):
- """
- Move ticks and ticklabels (if present) to the left of the Axes.
- """
- label = True
- if 'label1On' in self._major_tick_kw:
- label = (self._major_tick_kw['label1On']
- or self._major_tick_kw['label2On'])
- self.set_ticks_position('left')
- # if labels were turned off before this was called
- # leave them off
- self.set_tick_params(which='both', labelleft=label)
-
- def get_ticks_position(self):
- """
- Return the ticks position ("left", "right", "default", or "unknown").
- """
- return {1: "left", 2: "right",
- "default": "default", "unknown": "unknown"}[
- self._get_ticks_position()]
-
- get_view_interval, set_view_interval = _make_getset_interval(
- "view", "viewLim", "intervaly")
- get_data_interval, set_data_interval = _make_getset_interval(
- "data", "dataLim", "intervaly")
-
- def get_minpos(self):
- return self.axes.dataLim.minposy
-
- def set_default_intervals(self):
- # docstring inherited
- # only change view if dataLim has not changed and user has
- # not changed the view:
- if (not self.axes.dataLim.mutatedy() and
- not self.axes.viewLim.mutatedy()):
- if self.converter is not None:
- info = self.converter.axisinfo(self.units, self)
- if info.default_limits is not None:
- ymin, ymax = self.convert_units(info.default_limits)
- self.axes.viewLim.intervaly = ymin, ymax
- self.stale = True
-
- def get_tick_space(self):
- ends = mtransforms.Bbox.unit().transformed(
- self.axes.transAxes - self.figure.dpi_scale_trans)
- length = ends.height * 72
- # Having a spacing of at least 2 just looks good.
- size = self._get_tick_label_size('y') * 2
- if size > 0:
- return int(np.floor(length / size))
- else:
- return 2**31 - 1
diff --git a/contrib/python/matplotlib/py3/matplotlib/axis.pyi b/contrib/python/matplotlib/py3/matplotlib/axis.pyi
deleted file mode 100644
index 5ca8fcb6fd..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/axis.pyi
+++ /dev/null
@@ -1,278 +0,0 @@
-from collections.abc import Callable, Iterable, Sequence
-import datetime
-from typing import Any, Literal, overload
-
-import numpy as np
-from numpy.typing import ArrayLike
-
-import matplotlib.artist as martist
-from matplotlib import cbook
-from matplotlib.axes import Axes
-from matplotlib.backend_bases import RendererBase
-from matplotlib.lines import Line2D
-from matplotlib.text import Text
-from matplotlib.ticker import Locator, Formatter
-from matplotlib.transforms import Transform, Bbox
-from matplotlib.typing import ColorType
-
-
-GRIDLINE_INTERPOLATION_STEPS: int
-
-class Tick(martist.Artist):
- axes: Axes
- tick1line: Line2D
- tick2line: Line2D
- gridline: Line2D
- label1: Text
- label2: Text
- def __init__(
- self,
- axes: Axes,
- loc: float,
- *,
- size: float | None = ...,
- width: float | None = ...,
- color: ColorType | None = ...,
- tickdir: Literal["in", "inout", "out"] | None = ...,
- pad: float | None = ...,
- labelsize: float | None = ...,
- labelcolor: ColorType | None = ...,
- labelfontfamily: str | Sequence[str] | None = ...,
- zorder: float | None = ...,
- gridOn: bool | None = ...,
- tick1On: bool = ...,
- tick2On: bool = ...,
- label1On: bool = ...,
- label2On: bool = ...,
- major: bool = ...,
- labelrotation: float = ...,
- grid_color: ColorType | None = ...,
- grid_linestyle: str | None = ...,
- grid_linewidth: float | None = ...,
- grid_alpha: float | None = ...,
- **kwargs
- ) -> None: ...
- def get_tickdir(self) -> Literal["in", "inout", "out"]: ...
- def get_tick_padding(self) -> float: ...
- def get_children(self) -> list[martist.Artist]: ...
- stale: bool
- def set_pad(self, val: float) -> None: ...
- def get_pad(self) -> None: ...
- def get_loc(self) -> float: ...
- def set_label1(self, s: object) -> None: ...
- def set_label(self, s: object) -> None: ...
- def set_label2(self, s: object) -> None: ...
- def set_url(self, url: str | None) -> None: ...
- def get_view_interval(self) -> ArrayLike: ...
- def update_position(self, loc: float) -> None: ...
-
-class XTick(Tick):
- __name__: str
- def __init__(self, *args, **kwargs) -> None: ...
- stale: bool
- def update_position(self, loc: float) -> None: ...
- def get_view_interval(self) -> np.ndarray: ...
-
-class YTick(Tick):
- __name__: str
- def __init__(self, *args, **kwargs) -> None: ...
- stale: bool
- def update_position(self, loc: float) -> None: ...
- def get_view_interval(self) -> np.ndarray: ...
-
-class Ticker:
- def __init__(self) -> None: ...
- @property
- def locator(self) -> Locator | None: ...
- @locator.setter
- def locator(self, locator: Locator) -> None: ...
- @property
- def formatter(self) -> Formatter | None: ...
- @formatter.setter
- def formatter(self, formatter: Formatter) -> None: ...
-
-class _LazyTickList:
- def __init__(self, major: bool) -> None: ...
- # Replace return with Self when py3.9 is dropped
- @overload
- def __get__(self, instance: None, owner: None) -> _LazyTickList: ...
- @overload
- def __get__(self, instance: Axis, owner: type[Axis]) -> list[Tick]: ...
-
-class Axis(martist.Artist):
- OFFSETTEXTPAD: int
- isDefault_label: bool
- axes: Axes
- major: Ticker
- minor: Ticker
- callbacks: cbook.CallbackRegistry
- label: Text
- offsetText: Text
- labelpad: float
- pickradius: float
- def __init__(self, axes, *, pickradius: float = ...,
- clear: bool = ...) -> None: ...
- @property
- def isDefault_majloc(self) -> bool: ...
- @isDefault_majloc.setter
- def isDefault_majloc(self, value: bool) -> None: ...
- @property
- def isDefault_majfmt(self) -> bool: ...
- @isDefault_majfmt.setter
- def isDefault_majfmt(self, value: bool) -> None: ...
- @property
- def isDefault_minloc(self) -> bool: ...
- @isDefault_minloc.setter
- def isDefault_minloc(self, value: bool) -> None: ...
- @property
- def isDefault_minfmt(self) -> bool: ...
- @isDefault_minfmt.setter
- def isDefault_minfmt(self, value: bool) -> None: ...
- majorTicks: _LazyTickList
- minorTicks: _LazyTickList
- def get_remove_overlapping_locs(self) -> bool: ...
- def set_remove_overlapping_locs(self, val: bool) -> None: ...
- @property
- def remove_overlapping_locs(self) -> bool: ...
- @remove_overlapping_locs.setter
- def remove_overlapping_locs(self, val: bool) -> None: ...
- stale: bool
- def set_label_coords(
- self, x: float, y: float, transform: Transform | None = ...
- ) -> None: ...
- def get_transform(self) -> Transform: ...
- def get_scale(self) -> str: ...
- def limit_range_for_scale(
- self, vmin: float, vmax: float
- ) -> tuple[float, float]: ...
- def get_children(self) -> list[martist.Artist]: ...
- # TODO units
- converter: Any
- units: Any
- def clear(self) -> None: ...
- def reset_ticks(self) -> None: ...
- def set_tick_params(
- self,
- which: Literal["major", "minor", "both"] = ...,
- reset: bool = ...,
- **kwargs
- ) -> None: ...
- def get_tick_params(
- self, which: Literal["major", "minor"] = ...
- ) -> dict[str, Any]: ...
- def get_view_interval(self) -> tuple[float, float]: ...
- def set_view_interval(
- self, vmin: float, vmax: float, ignore: bool = ...
- ) -> None: ...
- def get_data_interval(self) -> tuple[float, float]: ...
- def set_data_interval(
- self, vmin: float, vmax: float, ignore: bool = ...
- ) -> None: ...
- def get_inverted(self) -> bool: ...
- def set_inverted(self, inverted: bool) -> None: ...
- def set_default_intervals(self) -> None: ...
- def get_tightbbox(
- self, renderer: RendererBase | None = ..., *, for_layout_only: bool = ...
- ) -> Bbox | None: ...
- def get_tick_padding(self) -> float: ...
- def get_gridlines(self) -> list[Line2D]: ...
- def get_label(self) -> Text: ...
- def get_offset_text(self) -> Text: ...
- def get_pickradius(self) -> float: ...
- def get_majorticklabels(self) -> list[Text]: ...
- def get_minorticklabels(self) -> list[Text]: ...
- def get_ticklabels(
- self, minor: bool = ..., which: Literal["major", "minor", "both"] | None = ...
- ) -> list[Text]: ...
- def get_majorticklines(self) -> list[Line2D]: ...
- def get_minorticklines(self) -> list[Line2D]: ...
- def get_ticklines(self, minor: bool = ...) -> list[Line2D]: ...
- def get_majorticklocs(self) -> np.ndarray: ...
- def get_minorticklocs(self) -> np.ndarray: ...
- def get_ticklocs(self, *, minor: bool = ...) -> np.ndarray: ...
- def get_ticks_direction(self, minor: bool = ...) -> np.ndarray: ...
- def get_label_text(self) -> str: ...
- def get_major_locator(self) -> Locator: ...
- def get_minor_locator(self) -> Locator: ...
- def get_major_formatter(self) -> Formatter: ...
- def get_minor_formatter(self) -> Formatter: ...
- def get_major_ticks(self, numticks: int | None = ...) -> list[Tick]: ...
- def get_minor_ticks(self, numticks: int | None = ...) -> list[Tick]: ...
- def grid(
- self,
- visible: bool | None = ...,
- which: Literal["major", "minor", "both"] = ...,
- **kwargs
- ) -> None: ...
- # TODO units
- def update_units(self, data): ...
- def have_units(self) -> bool: ...
- def convert_units(self, x): ...
- def set_units(self, u) -> None: ...
- def get_units(self): ...
- def set_label_text(
- self, label: str, fontdict: dict[str, Any] | None = ..., **kwargs
- ) -> Text: ...
- def set_major_formatter(
- self, formatter: Formatter | str | Callable[[float, float], str]
- ) -> None: ...
- def set_minor_formatter(
- self, formatter: Formatter | str | Callable[[float, float], str]
- ) -> None: ...
- def set_major_locator(self, locator: Locator) -> None: ...
- def set_minor_locator(self, locator: Locator) -> None: ...
- def set_pickradius(self, pickradius: float) -> None: ...
- def set_ticklabels(
- self,
- labels: Iterable[str | Text],
- *,
- minor: bool = ...,
- fontdict: dict[str, Any] | None = ...,
- **kwargs
- ) -> list[Text]: ...
- def set_ticks(
- self,
- ticks: ArrayLike,
- labels: Iterable[str] | None = ...,
- *,
- minor: bool = ...,
- **kwargs
- ) -> list[Tick]: ...
- def axis_date(self, tz: str | datetime.tzinfo | None = ...) -> None: ...
- def get_tick_space(self) -> int: ...
- def get_label_position(self) -> Literal["top", "bottom"]: ...
- def set_label_position(
- self, position: Literal["top", "bottom", "left", "right"]
- ) -> None: ...
- def get_minpos(self) -> float: ...
-
-class XAxis(Axis):
- __name__: str
- axis_name: str
- def __init__(self, *args, **kwargs) -> None: ...
- label_position: Literal["bottom", "top"]
- stale: bool
- def set_label_position(self, position: Literal["bottom", "top"]) -> None: ... # type: ignore[override]
- def set_ticks_position(
- self, position: Literal["top", "bottom", "both", "default", "none"]
- ) -> None: ...
- def tick_top(self) -> None: ...
- def tick_bottom(self) -> None: ...
- def get_ticks_position(self) -> Literal["top", "bottom", "default", "unknown"]: ...
- def get_tick_space(self) -> int: ...
-
-class YAxis(Axis):
- __name__: str
- axis_name: str
- def __init__(self, *args, **kwargs) -> None: ...
- label_position: Literal["left", "right"]
- stale: bool
- def set_label_position(self, position: Literal["left", "right"]) -> None: ... # type: ignore[override]
- def set_offset_position(self, position: Literal["left", "right"]) -> None: ...
- def set_ticks_position(
- self, position: Literal["left", "right", "both", "default", "none"]
- ) -> None: ...
- def tick_right(self) -> None: ...
- def tick_left(self) -> None: ...
- def get_ticks_position(self) -> Literal["left", "right", "default", "unknown"]: ...
- def get_tick_space(self) -> int: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/backend_bases.py b/contrib/python/matplotlib/py3/matplotlib/backend_bases.py
deleted file mode 100644
index 958b6e0e1c..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backend_bases.py
+++ /dev/null
@@ -1,3483 +0,0 @@
-"""
-Abstract base classes define the primitives that renderers and
-graphics contexts must implement to serve as a Matplotlib backend.
-
-`RendererBase`
- An abstract base class to handle drawing/rendering operations.
-
-`FigureCanvasBase`
- The abstraction layer that separates the `.Figure` from the backend
- specific details like a user interface drawing area.
-
-`GraphicsContextBase`
- An abstract base class that provides color, line styles, etc.
-
-`Event`
- The base class for all of the Matplotlib event handling. Derived classes
- such as `KeyEvent` and `MouseEvent` store the meta data like keys and
- buttons pressed, x and y locations in pixel and `~.axes.Axes` coordinates.
-
-`ShowBase`
- The base class for the ``Show`` class of each interactive backend; the
- 'show' callable is then set to ``Show.__call__``.
-
-`ToolContainerBase`
- The base class for the Toolbar class of each interactive backend.
-"""
-
-from collections import namedtuple
-from contextlib import ExitStack, contextmanager, nullcontext
-from enum import Enum, IntEnum
-import functools
-import importlib
-import inspect
-import io
-import itertools
-import logging
-import os
-import sys
-import time
-import weakref
-from weakref import WeakKeyDictionary
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import (
- _api, backend_tools as tools, cbook, colors, _docstring, text,
- _tight_bbox, transforms, widgets, is_interactive, rcParams)
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_managers import ToolManager
-from matplotlib.cbook import _setattr_cm
-from matplotlib.layout_engine import ConstrainedLayoutEngine
-from matplotlib.path import Path
-from matplotlib.texmanager import TexManager
-from matplotlib.transforms import Affine2D
-from matplotlib._enums import JoinStyle, CapStyle
-
-
-_log = logging.getLogger(__name__)
-_default_filetypes = {
- 'eps': 'Encapsulated Postscript',
- 'jpg': 'Joint Photographic Experts Group',
- 'jpeg': 'Joint Photographic Experts Group',
- 'pdf': 'Portable Document Format',
- 'pgf': 'PGF code for LaTeX',
- 'png': 'Portable Network Graphics',
- 'ps': 'Postscript',
- 'raw': 'Raw RGBA bitmap',
- 'rgba': 'Raw RGBA bitmap',
- 'svg': 'Scalable Vector Graphics',
- 'svgz': 'Scalable Vector Graphics',
- 'tif': 'Tagged Image File Format',
- 'tiff': 'Tagged Image File Format',
- 'webp': 'WebP Image Format',
-}
-_default_backends = {
- 'eps': 'matplotlib.backends.backend_ps',
- 'jpg': 'matplotlib.backends.backend_agg',
- 'jpeg': 'matplotlib.backends.backend_agg',
- 'pdf': 'matplotlib.backends.backend_pdf',
- 'pgf': 'matplotlib.backends.backend_pgf',
- 'png': 'matplotlib.backends.backend_agg',
- 'ps': 'matplotlib.backends.backend_ps',
- 'raw': 'matplotlib.backends.backend_agg',
- 'rgba': 'matplotlib.backends.backend_agg',
- 'svg': 'matplotlib.backends.backend_svg',
- 'svgz': 'matplotlib.backends.backend_svg',
- 'tif': 'matplotlib.backends.backend_agg',
- 'tiff': 'matplotlib.backends.backend_agg',
- 'webp': 'matplotlib.backends.backend_agg',
-}
-
-
-def _safe_pyplot_import():
- """
- Import and return ``pyplot``, correctly setting the backend if one is
- already forced.
- """
- try:
- import matplotlib.pyplot as plt
- except ImportError: # Likely due to a framework mismatch.
- current_framework = cbook._get_running_interactive_framework()
- if current_framework is None:
- raise # No, something else went wrong, likely with the install...
- backend_mapping = {
- 'qt': 'qtagg',
- 'gtk3': 'gtk3agg',
- 'gtk4': 'gtk4agg',
- 'wx': 'wxagg',
- 'tk': 'tkagg',
- 'macosx': 'macosx',
- 'headless': 'agg',
- }
- backend = backend_mapping[current_framework]
- rcParams["backend"] = mpl.rcParamsOrig["backend"] = backend
- import matplotlib.pyplot as plt # Now this should succeed.
- return plt
-
-
-def register_backend(format, backend, description=None):
- """
- Register a backend for saving to a given file format.
-
- Parameters
- ----------
- format : str
- File extension
- backend : module string or canvas class
- Backend for handling file output
- description : str, default: ""
- Description of the file type.
- """
- if description is None:
- description = ''
- _default_backends[format] = backend
- _default_filetypes[format] = description
-
-
-def get_registered_canvas_class(format):
- """
- Return the registered default canvas for given file format.
- Handles deferred import of required backend.
- """
- if format not in _default_backends:
- return None
- backend_class = _default_backends[format]
- if isinstance(backend_class, str):
- backend_class = importlib.import_module(backend_class).FigureCanvas
- _default_backends[format] = backend_class
- return backend_class
-
-
-class RendererBase:
- """
- An abstract base class to handle drawing/rendering operations.
-
- The following methods must be implemented in the backend for full
- functionality (though just implementing `draw_path` alone would give a
- highly capable backend):
-
- * `draw_path`
- * `draw_image`
- * `draw_gouraud_triangles`
-
- The following methods *should* be implemented in the backend for
- optimization reasons:
-
- * `draw_text`
- * `draw_markers`
- * `draw_path_collection`
- * `draw_quad_mesh`
- """
- def __init__(self):
- super().__init__()
- self._texmanager = None
- self._text2path = text.TextToPath()
- self._raster_depth = 0
- self._rasterizing = False
-
- def open_group(self, s, gid=None):
- """
- Open a grouping element with label *s* and *gid* (if set) as id.
-
- Only used by the SVG renderer.
- """
-
- def close_group(self, s):
- """
- Close a grouping element with label *s*.
-
- Only used by the SVG renderer.
- """
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- """Draw a `~.path.Path` instance using the given affine transform."""
- raise NotImplementedError
-
- def draw_markers(self, gc, marker_path, marker_trans, path,
- trans, rgbFace=None):
- """
- Draw a marker at each of *path*'s vertices (excluding control points).
-
- The base (fallback) implementation makes multiple calls to `draw_path`.
- Backends may want to override this method in order to draw the marker
- only once and reuse it multiple times.
-
- Parameters
- ----------
- gc : `.GraphicsContextBase`
- The graphics context.
- marker_path : `~matplotlib.path.Path`
- The path for the marker.
- marker_trans : `~matplotlib.transforms.Transform`
- An affine transform applied to the marker.
- path : `~matplotlib.path.Path`
- The locations to draw the markers.
- trans : `~matplotlib.transforms.Transform`
- An affine transform applied to the path.
- rgbFace : color, optional
- """
- for vertices, codes in path.iter_segments(trans, simplify=False):
- if len(vertices):
- x, y = vertices[-2:]
- self.draw_path(gc, marker_path,
- marker_trans +
- transforms.Affine2D().translate(x, y),
- rgbFace)
-
- def draw_path_collection(self, gc, master_transform, paths, all_transforms,
- offsets, offset_trans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position):
- """
- Draw a collection of *paths*.
-
- Each path is first transformed by the corresponding entry
- in *all_transforms* (a list of (3, 3) matrices) and then by
- *master_transform*. They are then translated by the corresponding
- entry in *offsets*, which has been first transformed by *offset_trans*.
-
- *facecolors*, *edgecolors*, *linewidths*, *linestyles*, and
- *antialiased* are lists that set the corresponding properties.
-
- *offset_position* is unused now, but the argument is kept for
- backwards compatibility.
-
- The base (fallback) implementation makes multiple calls to `draw_path`.
- Backends may want to override this in order to render each set of
- path data only once, and then reference that path multiple times with
- the different offsets, colors, styles etc. The generator methods
- `_iter_collection_raw_paths` and `_iter_collection` are provided to
- help with (and standardize) the implementation across backends. It
- is highly recommended to use those generators, so that changes to the
- behavior of `draw_path_collection` can be made globally.
- """
- path_ids = self._iter_collection_raw_paths(master_transform,
- paths, all_transforms)
-
- for xo, yo, path_id, gc0, rgbFace in self._iter_collection(
- gc, list(path_ids), offsets, offset_trans,
- facecolors, edgecolors, linewidths, linestyles,
- antialiaseds, urls, offset_position):
- path, transform = path_id
- # Only apply another translation if we have an offset, else we
- # reuse the initial transform.
- if xo != 0 or yo != 0:
- # The transformation can be used by multiple paths. Since
- # translate is a inplace operation, we need to copy the
- # transformation by .frozen() before applying the translation.
- transform = transform.frozen()
- transform.translate(xo, yo)
- self.draw_path(gc0, path, transform, rgbFace)
-
- def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight,
- coordinates, offsets, offsetTrans, facecolors,
- antialiased, edgecolors):
- """
- Draw a quadmesh.
-
- The base (fallback) implementation converts the quadmesh to paths and
- then calls `draw_path_collection`.
- """
-
- from matplotlib.collections import QuadMesh
- paths = QuadMesh._convert_mesh_to_paths(coordinates)
-
- if edgecolors is None:
- edgecolors = facecolors
- linewidths = np.array([gc.get_linewidth()], float)
-
- return self.draw_path_collection(
- gc, master_transform, paths, [], offsets, offsetTrans, facecolors,
- edgecolors, linewidths, [], [antialiased], [None], 'screen')
-
- @_api.deprecated("3.7", alternative="draw_gouraud_triangles")
- def draw_gouraud_triangle(self, gc, points, colors, transform):
- """
- Draw a Gouraud-shaded triangle.
-
- Parameters
- ----------
- gc : `.GraphicsContextBase`
- The graphics context.
- points : (3, 2) array-like
- Array of (x, y) points for the triangle.
- colors : (3, 4) array-like
- RGBA colors for each point of the triangle.
- transform : `~matplotlib.transforms.Transform`
- An affine transform to apply to the points.
- """
- raise NotImplementedError
-
- def draw_gouraud_triangles(self, gc, triangles_array, colors_array,
- transform):
- """
- Draw a series of Gouraud triangles.
-
- Parameters
- ----------
- gc : `.GraphicsContextBase`
- The graphics context.
- triangles_array : (N, 3, 2) array-like
- Array of *N* (x, y) points for the triangles.
- colors_array : (N, 3, 4) array-like
- Array of *N* RGBA colors for each point of the triangles.
- transform : `~matplotlib.transforms.Transform`
- An affine transform to apply to the points.
- """
- raise NotImplementedError
-
- def _iter_collection_raw_paths(self, master_transform, paths,
- all_transforms):
- """
- Helper method (along with `_iter_collection`) to implement
- `draw_path_collection` in a memory-efficient manner.
-
- This method yields all of the base path/transform combinations, given a
- master transform, a list of paths and list of transforms.
-
- The arguments should be exactly what is passed in to
- `draw_path_collection`.
-
- The backend should take each yielded path and transform and create an
- object that can be referenced (reused) later.
- """
- Npaths = len(paths)
- Ntransforms = len(all_transforms)
- N = max(Npaths, Ntransforms)
-
- if Npaths == 0:
- return
-
- transform = transforms.IdentityTransform()
- for i in range(N):
- path = paths[i % Npaths]
- if Ntransforms:
- transform = Affine2D(all_transforms[i % Ntransforms])
- yield path, transform + master_transform
-
- def _iter_collection_uses_per_path(self, paths, all_transforms,
- offsets, facecolors, edgecolors):
- """
- Compute how many times each raw path object returned by
- `_iter_collection_raw_paths` would be used when calling
- `_iter_collection`. This is intended for the backend to decide
- on the tradeoff between using the paths in-line and storing
- them once and reusing. Rounds up in case the number of uses
- is not the same for every path.
- """
- Npaths = len(paths)
- if Npaths == 0 or len(facecolors) == len(edgecolors) == 0:
- return 0
- Npath_ids = max(Npaths, len(all_transforms))
- N = max(Npath_ids, len(offsets))
- return (N + Npath_ids - 1) // Npath_ids
-
- def _iter_collection(self, gc, path_ids, offsets, offset_trans, facecolors,
- edgecolors, linewidths, linestyles,
- antialiaseds, urls, offset_position):
- """
- Helper method (along with `_iter_collection_raw_paths`) to implement
- `draw_path_collection` in a memory-efficient manner.
-
- This method yields all of the path, offset and graphics context
- combinations to draw the path collection. The caller should already
- have looped over the results of `_iter_collection_raw_paths` to draw
- this collection.
-
- The arguments should be the same as that passed into
- `draw_path_collection`, with the exception of *path_ids*, which is a
- list of arbitrary objects that the backend will use to reference one of
- the paths created in the `_iter_collection_raw_paths` stage.
-
- Each yielded result is of the form::
-
- xo, yo, path_id, gc, rgbFace
-
- where *xo*, *yo* is an offset; *path_id* is one of the elements of
- *path_ids*; *gc* is a graphics context and *rgbFace* is a color to
- use for filling the path.
- """
- Npaths = len(path_ids)
- Noffsets = len(offsets)
- N = max(Npaths, Noffsets)
- Nfacecolors = len(facecolors)
- Nedgecolors = len(edgecolors)
- Nlinewidths = len(linewidths)
- Nlinestyles = len(linestyles)
- Nurls = len(urls)
-
- if (Nfacecolors == 0 and Nedgecolors == 0) or Npaths == 0:
- return
-
- gc0 = self.new_gc()
- gc0.copy_properties(gc)
-
- def cycle_or_default(seq, default=None):
- # Cycle over *seq* if it is not empty; else always yield *default*.
- return (itertools.cycle(seq) if len(seq)
- else itertools.repeat(default))
-
- pathids = cycle_or_default(path_ids)
- toffsets = cycle_or_default(offset_trans.transform(offsets), (0, 0))
- fcs = cycle_or_default(facecolors)
- ecs = cycle_or_default(edgecolors)
- lws = cycle_or_default(linewidths)
- lss = cycle_or_default(linestyles)
- aas = cycle_or_default(antialiaseds)
- urls = cycle_or_default(urls)
-
- if Nedgecolors == 0:
- gc0.set_linewidth(0.0)
-
- for pathid, (xo, yo), fc, ec, lw, ls, aa, url in itertools.islice(
- zip(pathids, toffsets, fcs, ecs, lws, lss, aas, urls), N):
- if not (np.isfinite(xo) and np.isfinite(yo)):
- continue
- if Nedgecolors:
- if Nlinewidths:
- gc0.set_linewidth(lw)
- if Nlinestyles:
- gc0.set_dashes(*ls)
- if len(ec) == 4 and ec[3] == 0.0:
- gc0.set_linewidth(0)
- else:
- gc0.set_foreground(ec)
- if fc is not None and len(fc) == 4 and fc[3] == 0:
- fc = None
- gc0.set_antialiased(aa)
- if Nurls:
- gc0.set_url(url)
- yield xo, yo, pathid, gc0, fc
- gc0.restore()
-
- def get_image_magnification(self):
- """
- Get the factor by which to magnify images passed to `draw_image`.
- Allows a backend to have images at a different resolution to other
- artists.
- """
- return 1.0
-
- def draw_image(self, gc, x, y, im, transform=None):
- """
- Draw an RGBA image.
-
- Parameters
- ----------
- gc : `.GraphicsContextBase`
- A graphics context with clipping information.
-
- x : scalar
- The distance in physical units (i.e., dots or pixels) from the left
- hand side of the canvas.
-
- y : scalar
- The distance in physical units (i.e., dots or pixels) from the
- bottom side of the canvas.
-
- im : (N, M, 4) array of `numpy.uint8`
- An array of RGBA pixels.
-
- transform : `~matplotlib.transforms.Affine2DBase`
- If and only if the concrete backend is written such that
- `option_scale_image` returns ``True``, an affine transformation
- (i.e., an `.Affine2DBase`) *may* be passed to `draw_image`. The
- translation vector of the transformation is given in physical units
- (i.e., dots or pixels). Note that the transformation does not
- override *x* and *y*, and has to be applied *before* translating
- the result by *x* and *y* (this can be accomplished by adding *x*
- and *y* to the translation vector defined by *transform*).
- """
- raise NotImplementedError
-
- def option_image_nocomposite(self):
- """
- Return whether image composition by Matplotlib should be skipped.
-
- Raster backends should usually return False (letting the C-level
- rasterizer take care of image composition); vector backends should
- usually return ``not rcParams["image.composite_image"]``.
- """
- return False
-
- def option_scale_image(self):
- """
- Return whether arbitrary affine transformations in `draw_image` are
- supported (True for most vector backends).
- """
- return False
-
- def draw_tex(self, gc, x, y, s, prop, angle, *, mtext=None):
- """
- Draw a TeX instance.
-
- Parameters
- ----------
- gc : `.GraphicsContextBase`
- The graphics context.
- x : float
- The x location of the text in display coords.
- y : float
- The y location of the text baseline in display coords.
- s : str
- The TeX text string.
- prop : `~matplotlib.font_manager.FontProperties`
- The font properties.
- angle : float
- The rotation angle in degrees anti-clockwise.
- mtext : `~matplotlib.text.Text`
- The original text object to be rendered.
- """
- self._draw_text_as_path(gc, x, y, s, prop, angle, ismath="TeX")
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- """
- Draw a text instance.
-
- Parameters
- ----------
- gc : `.GraphicsContextBase`
- The graphics context.
- x : float
- The x location of the text in display coords.
- y : float
- The y location of the text baseline in display coords.
- s : str
- The text string.
- prop : `~matplotlib.font_manager.FontProperties`
- The font properties.
- angle : float
- The rotation angle in degrees anti-clockwise.
- ismath : bool or "TeX"
- If True, use mathtext parser. If "TeX", use tex for rendering.
- mtext : `~matplotlib.text.Text`
- The original text object to be rendered.
-
- Notes
- -----
- **Note for backend implementers:**
-
- When you are trying to determine if you have gotten your bounding box
- right (which is what enables the text layout/alignment to work
- properly), it helps to change the line in text.py::
-
- if 0: bbox_artist(self, renderer)
-
- to if 1, and then the actual bounding box will be plotted along with
- your text.
- """
-
- self._draw_text_as_path(gc, x, y, s, prop, angle, ismath)
-
- def _get_text_path_transform(self, x, y, s, prop, angle, ismath):
- """
- Return the text path and transform.
-
- Parameters
- ----------
- x : float
- The x location of the text in display coords.
- y : float
- The y location of the text baseline in display coords.
- s : str
- The text to be converted.
- prop : `~matplotlib.font_manager.FontProperties`
- The font property.
- angle : float
- Angle in degrees to render the text at.
- ismath : bool or "TeX"
- If True, use mathtext parser. If "TeX", use tex for rendering.
- """
-
- text2path = self._text2path
- fontsize = self.points_to_pixels(prop.get_size_in_points())
- verts, codes = text2path.get_text_path(prop, s, ismath=ismath)
-
- path = Path(verts, codes)
- angle = np.deg2rad(angle)
- if self.flipy():
- width, height = self.get_canvas_width_height()
- transform = (Affine2D()
- .scale(fontsize / text2path.FONT_SCALE)
- .rotate(angle)
- .translate(x, height - y))
- else:
- transform = (Affine2D()
- .scale(fontsize / text2path.FONT_SCALE)
- .rotate(angle)
- .translate(x, y))
-
- return path, transform
-
- def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath):
- """
- Draw the text by converting them to paths using `.TextToPath`.
-
- Parameters
- ----------
- gc : `.GraphicsContextBase`
- The graphics context.
- x : float
- The x location of the text in display coords.
- y : float
- The y location of the text baseline in display coords.
- s : str
- The text to be converted.
- prop : `~matplotlib.font_manager.FontProperties`
- The font property.
- angle : float
- Angle in degrees to render the text at.
- ismath : bool or "TeX"
- If True, use mathtext parser. If "TeX", use tex for rendering.
- """
- path, transform = self._get_text_path_transform(
- x, y, s, prop, angle, ismath)
- color = gc.get_rgb()
- gc.set_linewidth(0.0)
- self.draw_path(gc, path, transform, rgbFace=color)
-
- def get_text_width_height_descent(self, s, prop, ismath):
- """
- Get the width, height, and descent (offset from the bottom to the baseline), in
- display coords, of the string *s* with `.FontProperties` *prop*.
-
- Whitespace at the start and the end of *s* is included in the reported width.
- """
- fontsize = prop.get_size_in_points()
-
- if ismath == 'TeX':
- # todo: handle properties
- return self.get_texmanager().get_text_width_height_descent(
- s, fontsize, renderer=self)
-
- dpi = self.points_to_pixels(72)
- if ismath:
- dims = self._text2path.mathtext_parser.parse(s, dpi, prop)
- return dims[0:3] # return width, height, descent
-
- flags = self._text2path._get_hinting_flag()
- font = self._text2path._get_font(prop)
- font.set_size(fontsize, dpi)
- # the width and height of unrotated string
- font.set_text(s, 0.0, flags=flags)
- w, h = font.get_width_height()
- d = font.get_descent()
- w /= 64.0 # convert from subpixels
- h /= 64.0
- d /= 64.0
- return w, h, d
-
- def flipy(self):
- """
- Return whether y values increase from top to bottom.
-
- Note that this only affects drawing of texts.
- """
- return True
-
- def get_canvas_width_height(self):
- """Return the canvas width and height in display coords."""
- return 1, 1
-
- def get_texmanager(self):
- """Return the `.TexManager` instance."""
- if self._texmanager is None:
- self._texmanager = TexManager()
- return self._texmanager
-
- def new_gc(self):
- """Return an instance of a `.GraphicsContextBase`."""
- return GraphicsContextBase()
-
- def points_to_pixels(self, points):
- """
- Convert points to display units.
-
- You need to override this function (unless your backend
- doesn't have a dpi, e.g., postscript or svg). Some imaging
- systems assume some value for pixels per inch::
-
- points to pixels = points * pixels_per_inch/72 * dpi/72
-
- Parameters
- ----------
- points : float or array-like
-
- Returns
- -------
- Points converted to pixels
- """
- return points
-
- def start_rasterizing(self):
- """
- Switch to the raster renderer.
-
- Used by `.MixedModeRenderer`.
- """
-
- def stop_rasterizing(self):
- """
- Switch back to the vector renderer and draw the contents of the raster
- renderer as an image on the vector renderer.
-
- Used by `.MixedModeRenderer`.
- """
-
- def start_filter(self):
- """
- Switch to a temporary renderer for image filtering effects.
-
- Currently only supported by the agg renderer.
- """
-
- def stop_filter(self, filter_func):
- """
- Switch back to the original renderer. The contents of the temporary
- renderer is processed with the *filter_func* and is drawn on the
- original renderer as an image.
-
- Currently only supported by the agg renderer.
- """
-
- def _draw_disabled(self):
- """
- Context manager to temporary disable drawing.
-
- This is used for getting the drawn size of Artists. This lets us
- run the draw process to update any Python state but does not pay the
- cost of the draw_XYZ calls on the canvas.
- """
- no_ops = {
- meth_name: lambda *args, **kwargs: None
- for meth_name in dir(RendererBase)
- if (meth_name.startswith("draw_")
- or meth_name in ["open_group", "close_group"])
- }
-
- return _setattr_cm(self, **no_ops)
-
-
-class GraphicsContextBase:
- """An abstract base class that provides color, line styles, etc."""
-
- def __init__(self):
- self._alpha = 1.0
- self._forced_alpha = False # if True, _alpha overrides A from RGBA
- self._antialiased = 1 # use 0, 1 not True, False for extension code
- self._capstyle = CapStyle('butt')
- self._cliprect = None
- self._clippath = None
- self._dashes = 0, None
- self._joinstyle = JoinStyle('round')
- self._linestyle = 'solid'
- self._linewidth = 1
- self._rgb = (0.0, 0.0, 0.0, 1.0)
- self._hatch = None
- self._hatch_color = colors.to_rgba(rcParams['hatch.color'])
- self._hatch_linewidth = rcParams['hatch.linewidth']
- self._url = None
- self._gid = None
- self._snap = None
- self._sketch = None
-
- def copy_properties(self, gc):
- """Copy properties from *gc* to self."""
- self._alpha = gc._alpha
- self._forced_alpha = gc._forced_alpha
- self._antialiased = gc._antialiased
- self._capstyle = gc._capstyle
- self._cliprect = gc._cliprect
- self._clippath = gc._clippath
- self._dashes = gc._dashes
- self._joinstyle = gc._joinstyle
- self._linestyle = gc._linestyle
- self._linewidth = gc._linewidth
- self._rgb = gc._rgb
- self._hatch = gc._hatch
- self._hatch_color = gc._hatch_color
- self._hatch_linewidth = gc._hatch_linewidth
- self._url = gc._url
- self._gid = gc._gid
- self._snap = gc._snap
- self._sketch = gc._sketch
-
- def restore(self):
- """
- Restore the graphics context from the stack - needed only
- for backends that save graphics contexts on a stack.
- """
-
- def get_alpha(self):
- """
- Return the alpha value used for blending - not supported on all
- backends.
- """
- return self._alpha
-
- def get_antialiased(self):
- """Return whether the object should try to do antialiased rendering."""
- return self._antialiased
-
- def get_capstyle(self):
- """Return the `.CapStyle`."""
- return self._capstyle.name
-
- def get_clip_rectangle(self):
- """
- Return the clip rectangle as a `~matplotlib.transforms.Bbox` instance.
- """
- return self._cliprect
-
- def get_clip_path(self):
- """
- Return the clip path in the form (path, transform), where path
- is a `~.path.Path` instance, and transform is
- an affine transform to apply to the path before clipping.
- """
- if self._clippath is not None:
- tpath, tr = self._clippath.get_transformed_path_and_affine()
- if np.all(np.isfinite(tpath.vertices)):
- return tpath, tr
- else:
- _log.warning("Ill-defined clip_path detected. Returning None.")
- return None, None
- return None, None
-
- def get_dashes(self):
- """
- Return the dash style as an (offset, dash-list) pair.
-
- See `.set_dashes` for details.
-
- Default value is (None, None).
- """
- return self._dashes
-
- def get_forced_alpha(self):
- """
- Return whether the value given by get_alpha() should be used to
- override any other alpha-channel values.
- """
- return self._forced_alpha
-
- def get_joinstyle(self):
- """Return the `.JoinStyle`."""
- return self._joinstyle.name
-
- def get_linewidth(self):
- """Return the line width in points."""
- return self._linewidth
-
- def get_rgb(self):
- """Return a tuple of three or four floats from 0-1."""
- return self._rgb
-
- def get_url(self):
- """Return a url if one is set, None otherwise."""
- return self._url
-
- def get_gid(self):
- """Return the object identifier if one is set, None otherwise."""
- return self._gid
-
- def get_snap(self):
- """
- Return the snap setting, which can be:
-
- * True: snap vertices to the nearest pixel center
- * False: leave vertices as-is
- * None: (auto) If the path contains only rectilinear line segments,
- round to the nearest pixel center
- """
- return self._snap
-
- def set_alpha(self, alpha):
- """
- Set the alpha value used for blending - not supported on all backends.
-
- If ``alpha=None`` (the default), the alpha components of the
- foreground and fill colors will be used to set their respective
- transparencies (where applicable); otherwise, ``alpha`` will override
- them.
- """
- if alpha is not None:
- self._alpha = alpha
- self._forced_alpha = True
- else:
- self._alpha = 1.0
- self._forced_alpha = False
- self.set_foreground(self._rgb, isRGBA=True)
-
- def set_antialiased(self, b):
- """Set whether object should be drawn with antialiased rendering."""
- # Use ints to make life easier on extension code trying to read the gc.
- self._antialiased = int(bool(b))
-
- @_docstring.interpd
- def set_capstyle(self, cs):
- """
- Set how to draw endpoints of lines.
-
- Parameters
- ----------
- cs : `.CapStyle` or %(CapStyle)s
- """
- self._capstyle = CapStyle(cs)
-
- def set_clip_rectangle(self, rectangle):
- """Set the clip rectangle to a `.Bbox` or None."""
- self._cliprect = rectangle
-
- def set_clip_path(self, path):
- """Set the clip path to a `.TransformedPath` or None."""
- _api.check_isinstance((transforms.TransformedPath, None), path=path)
- self._clippath = path
-
- def set_dashes(self, dash_offset, dash_list):
- """
- Set the dash style for the gc.
-
- Parameters
- ----------
- dash_offset : float
- Distance, in points, into the dash pattern at which to
- start the pattern. It is usually set to 0.
- dash_list : array-like or None
- The on-off sequence as points. None specifies a solid line. All
- values must otherwise be non-negative (:math:`\\ge 0`).
-
- Notes
- -----
- See p. 666 of the PostScript
- `Language Reference
- <https://www.adobe.com/jp/print/postscript/pdfs/PLRM.pdf>`_
- for more info.
- """
- if dash_list is not None:
- dl = np.asarray(dash_list)
- if np.any(dl < 0.0):
- raise ValueError(
- "All values in the dash list must be non-negative")
- if dl.size and not np.any(dl > 0.0):
- raise ValueError(
- 'At least one value in the dash list must be positive')
- self._dashes = dash_offset, dash_list
-
- def set_foreground(self, fg, isRGBA=False):
- """
- Set the foreground color.
-
- Parameters
- ----------
- fg : color
- isRGBA : bool
- If *fg* is known to be an ``(r, g, b, a)`` tuple, *isRGBA* can be
- set to True to improve performance.
- """
- if self._forced_alpha and isRGBA:
- self._rgb = fg[:3] + (self._alpha,)
- elif self._forced_alpha:
- self._rgb = colors.to_rgba(fg, self._alpha)
- elif isRGBA:
- self._rgb = fg
- else:
- self._rgb = colors.to_rgba(fg)
-
- @_docstring.interpd
- def set_joinstyle(self, js):
- """
- Set how to draw connections between line segments.
-
- Parameters
- ----------
- js : `.JoinStyle` or %(JoinStyle)s
- """
- self._joinstyle = JoinStyle(js)
-
- def set_linewidth(self, w):
- """Set the linewidth in points."""
- self._linewidth = float(w)
-
- def set_url(self, url):
- """Set the url for links in compatible backends."""
- self._url = url
-
- def set_gid(self, id):
- """Set the id."""
- self._gid = id
-
- def set_snap(self, snap):
- """
- Set the snap setting which may be:
-
- * True: snap vertices to the nearest pixel center
- * False: leave vertices as-is
- * None: (auto) If the path contains only rectilinear line segments,
- round to the nearest pixel center
- """
- self._snap = snap
-
- def set_hatch(self, hatch):
- """Set the hatch style (for fills)."""
- self._hatch = hatch
-
- def get_hatch(self):
- """Get the current hatch style."""
- return self._hatch
-
- def get_hatch_path(self, density=6.0):
- """Return a `.Path` for the current hatch."""
- hatch = self.get_hatch()
- if hatch is None:
- return None
- return Path.hatch(hatch, density)
-
- def get_hatch_color(self):
- """Get the hatch color."""
- return self._hatch_color
-
- def set_hatch_color(self, hatch_color):
- """Set the hatch color."""
- self._hatch_color = hatch_color
-
- def get_hatch_linewidth(self):
- """Get the hatch linewidth."""
- return self._hatch_linewidth
-
- def get_sketch_params(self):
- """
- Return the sketch parameters for the artist.
-
- Returns
- -------
- tuple or `None`
-
- A 3-tuple with the following elements:
-
- * ``scale``: The amplitude of the wiggle perpendicular to the
- source line.
- * ``length``: The length of the wiggle along the line.
- * ``randomness``: The scale factor by which the length is
- shrunken or expanded.
-
- May return `None` if no sketch parameters were set.
- """
- return self._sketch
-
- def set_sketch_params(self, scale=None, length=None, randomness=None):
- """
- Set the sketch parameters.
-
- Parameters
- ----------
- scale : float, optional
- The amplitude of the wiggle perpendicular to the source line, in
- pixels. If scale is `None`, or not provided, no sketch filter will
- be provided.
- length : float, default: 128
- The length of the wiggle along the line, in pixels.
- randomness : float, default: 16
- The scale factor by which the length is shrunken or expanded.
- """
- self._sketch = (
- None if scale is None
- else (scale, length or 128., randomness or 16.))
-
-
-class TimerBase:
- """
- A base class for providing timer events, useful for things animations.
- Backends need to implement a few specific methods in order to use their
- own timing mechanisms so that the timer events are integrated into their
- event loops.
-
- Subclasses must override the following methods:
-
- - ``_timer_start``: Backend-specific code for starting the timer.
- - ``_timer_stop``: Backend-specific code for stopping the timer.
-
- Subclasses may additionally override the following methods:
-
- - ``_timer_set_single_shot``: Code for setting the timer to single shot
- operating mode, if supported by the timer object. If not, the `Timer`
- class itself will store the flag and the ``_on_timer`` method should be
- overridden to support such behavior.
-
- - ``_timer_set_interval``: Code for setting the interval on the timer, if
- there is a method for doing so on the timer object.
-
- - ``_on_timer``: The internal function that any timer object should call,
- which will handle the task of running all callbacks that have been set.
- """
-
- def __init__(self, interval=None, callbacks=None):
- """
- Parameters
- ----------
- interval : int, default: 1000ms
- The time between timer events in milliseconds. Will be stored as
- ``timer.interval``.
- callbacks : list[tuple[callable, tuple, dict]]
- List of (func, args, kwargs) tuples that will be called upon timer
- events. This list is accessible as ``timer.callbacks`` and can be
- manipulated directly, or the functions `~.TimerBase.add_callback`
- and `~.TimerBase.remove_callback` can be used.
- """
- self.callbacks = [] if callbacks is None else callbacks.copy()
- # Set .interval and not ._interval to go through the property setter.
- self.interval = 1000 if interval is None else interval
- self.single_shot = False
-
- def __del__(self):
- """Need to stop timer and possibly disconnect timer."""
- self._timer_stop()
-
- def start(self, interval=None):
- """
- Start the timer object.
-
- Parameters
- ----------
- interval : int, optional
- Timer interval in milliseconds; overrides a previously set interval
- if provided.
- """
- if interval is not None:
- self.interval = interval
- self._timer_start()
-
- def stop(self):
- """Stop the timer."""
- self._timer_stop()
-
- def _timer_start(self):
- pass
-
- def _timer_stop(self):
- pass
-
- @property
- def interval(self):
- """The time between timer events, in milliseconds."""
- return self._interval
-
- @interval.setter
- def interval(self, interval):
- # Force to int since none of the backends actually support fractional
- # milliseconds, and some error or give warnings.
- # Some backends also fail when interval == 0, so ensure >= 1 msec
- interval = max(int(interval), 1)
- self._interval = interval
- self._timer_set_interval()
-
- @property
- def single_shot(self):
- """Whether this timer should stop after a single run."""
- return self._single
-
- @single_shot.setter
- def single_shot(self, ss):
- self._single = ss
- self._timer_set_single_shot()
-
- def add_callback(self, func, *args, **kwargs):
- """
- Register *func* to be called by timer when the event fires. Any
- additional arguments provided will be passed to *func*.
-
- This function returns *func*, which makes it possible to use it as a
- decorator.
- """
- self.callbacks.append((func, args, kwargs))
- return func
-
- def remove_callback(self, func, *args, **kwargs):
- """
- Remove *func* from list of callbacks.
-
- *args* and *kwargs* are optional and used to distinguish between copies
- of the same function registered to be called with different arguments.
- This behavior is deprecated. In the future, ``*args, **kwargs`` won't
- be considered anymore; to keep a specific callback removable by itself,
- pass it to `add_callback` as a `functools.partial` object.
- """
- if args or kwargs:
- _api.warn_deprecated(
- "3.1", message="In a future version, Timer.remove_callback "
- "will not take *args, **kwargs anymore, but remove all "
- "callbacks where the callable matches; to keep a specific "
- "callback removable by itself, pass it to add_callback as a "
- "functools.partial object.")
- self.callbacks.remove((func, args, kwargs))
- else:
- funcs = [c[0] for c in self.callbacks]
- if func in funcs:
- self.callbacks.pop(funcs.index(func))
-
- def _timer_set_interval(self):
- """Used to set interval on underlying timer object."""
-
- def _timer_set_single_shot(self):
- """Used to set single shot on underlying timer object."""
-
- def _on_timer(self):
- """
- Runs all function that have been registered as callbacks. Functions
- can return False (or 0) if they should not be called any more. If there
- are no callbacks, the timer is automatically stopped.
- """
- for func, args, kwargs in self.callbacks:
- ret = func(*args, **kwargs)
- # docstring above explains why we use `if ret == 0` here,
- # instead of `if not ret`.
- # This will also catch `ret == False` as `False == 0`
- # but does not annoy the linters
- # https://docs.python.org/3/library/stdtypes.html#boolean-values
- if ret == 0:
- self.callbacks.remove((func, args, kwargs))
-
- if len(self.callbacks) == 0:
- self.stop()
-
-
-class Event:
- """
- A Matplotlib event.
-
- The following attributes are defined and shown with their default values.
- Subclasses may define additional attributes.
-
- Attributes
- ----------
- name : str
- The event name.
- canvas : `FigureCanvasBase`
- The backend-specific canvas instance generating the event.
- guiEvent
- The GUI event that triggered the Matplotlib event.
- """
-
- def __init__(self, name, canvas, guiEvent=None):
- self.name = name
- self.canvas = canvas
- self._guiEvent = guiEvent
- self._guiEvent_deleted = False
-
- def _process(self):
- """Process this event on ``self.canvas``, then unset ``guiEvent``."""
- self.canvas.callbacks.process(self.name, self)
- self._guiEvent_deleted = True
-
- @property
- def guiEvent(self):
- # After deprecation elapses: remove _guiEvent_deleted; make guiEvent a plain
- # attribute set to None by _process.
- if self._guiEvent_deleted:
- _api.warn_deprecated(
- "3.8", message="Accessing guiEvent outside of the original GUI event "
- "handler is unsafe and deprecated since %(since)s; in the future, the "
- "attribute will be set to None after quitting the event handler. You "
- "may separately record the value of the guiEvent attribute at your own "
- "risk.")
- return self._guiEvent
-
-
-class DrawEvent(Event):
- """
- An event triggered by a draw operation on the canvas.
-
- In most backends, callbacks subscribed to this event will be fired after
- the rendering is complete but before the screen is updated. Any extra
- artists drawn to the canvas's renderer will be reflected without an
- explicit call to ``blit``.
-
- .. warning::
-
- Calling ``canvas.draw`` and ``canvas.blit`` in these callbacks may
- not be safe with all backends and may cause infinite recursion.
-
- A DrawEvent has a number of special attributes in addition to those defined
- by the parent `Event` class.
-
- Attributes
- ----------
- renderer : `RendererBase`
- The renderer for the draw event.
- """
- def __init__(self, name, canvas, renderer):
- super().__init__(name, canvas)
- self.renderer = renderer
-
-
-class ResizeEvent(Event):
- """
- An event triggered by a canvas resize.
-
- A ResizeEvent has a number of special attributes in addition to those
- defined by the parent `Event` class.
-
- Attributes
- ----------
- width : int
- Width of the canvas in pixels.
- height : int
- Height of the canvas in pixels.
- """
-
- def __init__(self, name, canvas):
- super().__init__(name, canvas)
- self.width, self.height = canvas.get_width_height()
-
-
-class CloseEvent(Event):
- """An event triggered by a figure being closed."""
-
-
-class LocationEvent(Event):
- """
- An event that has a screen location.
-
- A LocationEvent has a number of special attributes in addition to those
- defined by the parent `Event` class.
-
- Attributes
- ----------
- x, y : int or None
- Event location in pixels from bottom left of canvas.
- inaxes : `~matplotlib.axes.Axes` or None
- The `~.axes.Axes` instance over which the mouse is, if any.
- xdata, ydata : float or None
- Data coordinates of the mouse within *inaxes*, or *None* if the mouse
- is not over an Axes.
- modifiers : frozenset
- The keyboard modifiers currently being pressed (except for KeyEvent).
- """
-
- # Fully delete all occurrences of lastevent after deprecation elapses.
- _lastevent = None
- lastevent = _api.deprecated("3.8")(
- _api.classproperty(lambda cls: cls._lastevent))
- _last_axes_ref = None
-
- def __init__(self, name, canvas, x, y, guiEvent=None, *, modifiers=None):
- super().__init__(name, canvas, guiEvent=guiEvent)
- # x position - pixels from left of canvas
- self.x = int(x) if x is not None else x
- # y position - pixels from right of canvas
- self.y = int(y) if y is not None else y
- self.inaxes = None # the Axes instance the mouse is over
- self.xdata = None # x coord of mouse in data coords
- self.ydata = None # y coord of mouse in data coords
- self.modifiers = frozenset(modifiers if modifiers is not None else [])
-
- if x is None or y is None:
- # cannot check if event was in Axes if no (x, y) info
- return
-
- self._set_inaxes(self.canvas.inaxes((x, y))
- if self.canvas.mouse_grabber is None else
- self.canvas.mouse_grabber,
- (x, y))
-
- # Splitting _set_inaxes out is useful for the axes_leave_event handler: it
- # needs to generate synthetic LocationEvents with manually-set inaxes. In
- # that latter case, xy has already been cast to int so it can directly be
- # read from self.x, self.y; in the normal case, however, it is more
- # accurate to pass the untruncated float x, y values passed to the ctor.
-
- def _set_inaxes(self, inaxes, xy=None):
- self.inaxes = inaxes
- if inaxes is not None:
- try:
- self.xdata, self.ydata = inaxes.transData.inverted().transform(
- xy if xy is not None else (self.x, self.y))
- except ValueError:
- pass
-
-
-class MouseButton(IntEnum):
- LEFT = 1
- MIDDLE = 2
- RIGHT = 3
- BACK = 8
- FORWARD = 9
-
-
-class MouseEvent(LocationEvent):
- """
- A mouse event ('button_press_event', 'button_release_event', \
-'scroll_event', 'motion_notify_event').
-
- A MouseEvent has a number of special attributes in addition to those
- defined by the parent `Event` and `LocationEvent` classes.
-
- Attributes
- ----------
- button : None or `MouseButton` or {'up', 'down'}
- The button pressed. 'up' and 'down' are used for scroll events.
-
- Note that LEFT and RIGHT actually refer to the "primary" and
- "secondary" buttons, i.e. if the user inverts their left and right
- buttons ("left-handed setting") then the LEFT button will be the one
- physically on the right.
-
- If this is unset, *name* is "scroll_event", and *step* is nonzero, then
- this will be set to "up" or "down" depending on the sign of *step*.
-
- key : None or str
- The key pressed when the mouse event triggered, e.g. 'shift'.
- See `KeyEvent`.
-
- .. warning::
- This key is currently obtained from the last 'key_press_event' or
- 'key_release_event' that occurred within the canvas. Thus, if the
- last change of keyboard state occurred while the canvas did not have
- focus, this attribute will be wrong. On the other hand, the
- ``modifiers`` attribute should always be correct, but it can only
- report on modifier keys.
-
- step : float
- The number of scroll steps (positive for 'up', negative for 'down').
- This applies only to 'scroll_event' and defaults to 0 otherwise.
-
- dblclick : bool
- Whether the event is a double-click. This applies only to
- 'button_press_event' and is False otherwise. In particular, it's
- not used in 'button_release_event'.
-
- Examples
- --------
- ::
-
- def on_press(event):
- print('you pressed', event.button, event.xdata, event.ydata)
-
- cid = fig.canvas.mpl_connect('button_press_event', on_press)
- """
-
- def __init__(self, name, canvas, x, y, button=None, key=None,
- step=0, dblclick=False, guiEvent=None, *, modifiers=None):
- super().__init__(
- name, canvas, x, y, guiEvent=guiEvent, modifiers=modifiers)
- if button in MouseButton.__members__.values():
- button = MouseButton(button)
- if name == "scroll_event" and button is None:
- if step > 0:
- button = "up"
- elif step < 0:
- button = "down"
- self.button = button
- self.key = key
- self.step = step
- self.dblclick = dblclick
-
- def __str__(self):
- return (f"{self.name}: "
- f"xy=({self.x}, {self.y}) xydata=({self.xdata}, {self.ydata}) "
- f"button={self.button} dblclick={self.dblclick} "
- f"inaxes={self.inaxes}")
-
-
-class PickEvent(Event):
- """
- A pick event.
-
- This event is fired when the user picks a location on the canvas
- sufficiently close to an artist that has been made pickable with
- `.Artist.set_picker`.
-
- A PickEvent has a number of special attributes in addition to those defined
- by the parent `Event` class.
-
- Attributes
- ----------
- mouseevent : `MouseEvent`
- The mouse event that generated the pick.
- artist : `~matplotlib.artist.Artist`
- The picked artist. Note that artists are not pickable by default
- (see `.Artist.set_picker`).
- other
- Additional attributes may be present depending on the type of the
- picked object; e.g., a `.Line2D` pick may define different extra
- attributes than a `.PatchCollection` pick.
-
- Examples
- --------
- Bind a function ``on_pick()`` to pick events, that prints the coordinates
- of the picked data point::
-
- ax.plot(np.rand(100), 'o', picker=5) # 5 points tolerance
-
- def on_pick(event):
- line = event.artist
- xdata, ydata = line.get_data()
- ind = event.ind
- print(f'on pick line: {xdata[ind]:.3f}, {ydata[ind]:.3f}')
-
- cid = fig.canvas.mpl_connect('pick_event', on_pick)
- """
-
- def __init__(self, name, canvas, mouseevent, artist,
- guiEvent=None, **kwargs):
- if guiEvent is None:
- guiEvent = mouseevent.guiEvent
- super().__init__(name, canvas, guiEvent)
- self.mouseevent = mouseevent
- self.artist = artist
- self.__dict__.update(kwargs)
-
-
-class KeyEvent(LocationEvent):
- """
- A key event (key press, key release).
-
- A KeyEvent has a number of special attributes in addition to those defined
- by the parent `Event` and `LocationEvent` classes.
-
- Attributes
- ----------
- key : None or str
- The key(s) pressed. Could be *None*, a single case sensitive Unicode
- character ("g", "G", "#", etc.), a special key ("control", "shift",
- "f1", "up", etc.) or a combination of the above (e.g., "ctrl+alt+g",
- "ctrl+alt+G").
-
- Notes
- -----
- Modifier keys will be prefixed to the pressed key and will be in the order
- "ctrl", "alt", "super". The exception to this rule is when the pressed key
- is itself a modifier key, therefore "ctrl+alt" and "alt+control" can both
- be valid key values.
-
- Examples
- --------
- ::
-
- def on_key(event):
- print('you pressed', event.key, event.xdata, event.ydata)
-
- cid = fig.canvas.mpl_connect('key_press_event', on_key)
- """
-
- def __init__(self, name, canvas, key, x=0, y=0, guiEvent=None):
- super().__init__(name, canvas, x, y, guiEvent=guiEvent)
- self.key = key
-
-
-# Default callback for key events.
-def _key_handler(event):
- # Dead reckoning of key.
- if event.name == "key_press_event":
- event.canvas._key = event.key
- elif event.name == "key_release_event":
- event.canvas._key = None
-
-
-# Default callback for mouse events.
-def _mouse_handler(event):
- # Dead-reckoning of button and key.
- if event.name == "button_press_event":
- event.canvas._button = event.button
- elif event.name == "button_release_event":
- event.canvas._button = None
- elif event.name == "motion_notify_event" and event.button is None:
- event.button = event.canvas._button
- if event.key is None:
- event.key = event.canvas._key
- # Emit axes_enter/axes_leave.
- if event.name == "motion_notify_event":
- last_ref = LocationEvent._last_axes_ref
- last_axes = last_ref() if last_ref else None
- if last_axes != event.inaxes:
- if last_axes is not None:
- # Create a synthetic LocationEvent for the axes_leave_event.
- # Its inaxes attribute needs to be manually set (because the
- # cursor is actually *out* of that axes at that point); this is
- # done with the internal _set_inaxes method which ensures that
- # the xdata and ydata attributes are also correct.
- try:
- leave_event = LocationEvent(
- "axes_leave_event", last_axes.figure.canvas,
- event.x, event.y, event.guiEvent,
- modifiers=event.modifiers)
- leave_event._set_inaxes(last_axes)
- last_axes.figure.canvas.callbacks.process(
- "axes_leave_event", leave_event)
- except Exception:
- pass # The last canvas may already have been torn down.
- if event.inaxes is not None:
- event.canvas.callbacks.process("axes_enter_event", event)
- LocationEvent._last_axes_ref = (
- weakref.ref(event.inaxes) if event.inaxes else None)
- LocationEvent._lastevent = (
- None if event.name == "figure_leave_event" else event)
-
-
-def _get_renderer(figure, print_method=None):
- """
- Get the renderer that would be used to save a `.Figure`.
-
- If you need a renderer without any active draw methods use
- renderer._draw_disabled to temporary patch them out at your call site.
- """
- # This is implemented by triggering a draw, then immediately jumping out of
- # Figure.draw() by raising an exception.
-
- class Done(Exception):
- pass
-
- def _draw(renderer): raise Done(renderer)
-
- with cbook._setattr_cm(figure, draw=_draw), ExitStack() as stack:
- if print_method is None:
- fmt = figure.canvas.get_default_filetype()
- # Even for a canvas' default output type, a canvas switch may be
- # needed, e.g. for FigureCanvasBase.
- print_method = stack.enter_context(
- figure.canvas._switch_canvas_and_return_print_method(fmt))
- try:
- print_method(io.BytesIO())
- except Done as exc:
- renderer, = exc.args
- return renderer
- else:
- raise RuntimeError(f"{print_method} did not call Figure.draw, so "
- f"no renderer is available")
-
-
-def _no_output_draw(figure):
- # _no_output_draw was promoted to the figure level, but
- # keep this here in case someone was calling it...
- figure.draw_without_rendering()
-
-
-def _is_non_interactive_terminal_ipython(ip):
- """
- Return whether we are in a terminal IPython, but non interactive.
-
- When in _terminal_ IPython, ip.parent will have and `interact` attribute,
- if this attribute is False we do not setup eventloop integration as the
- user will _not_ interact with IPython. In all other case (ZMQKernel, or is
- interactive), we do.
- """
- return (hasattr(ip, 'parent')
- and (ip.parent is not None)
- and getattr(ip.parent, 'interact', None) is False)
-
-
-class FigureCanvasBase:
- """
- The canvas the figure renders into.
-
- Attributes
- ----------
- figure : `~matplotlib.figure.Figure`
- A high-level figure instance.
- """
-
- # Set to one of {"qt", "gtk3", "gtk4", "wx", "tk", "macosx"} if an
- # interactive framework is required, or None otherwise.
- required_interactive_framework = None
-
- # The manager class instantiated by new_manager.
- # (This is defined as a classproperty because the manager class is
- # currently defined *after* the canvas class, but one could also assign
- # ``FigureCanvasBase.manager_class = FigureManagerBase``
- # after defining both classes.)
- manager_class = _api.classproperty(lambda cls: FigureManagerBase)
-
- events = [
- 'resize_event',
- 'draw_event',
- 'key_press_event',
- 'key_release_event',
- 'button_press_event',
- 'button_release_event',
- 'scroll_event',
- 'motion_notify_event',
- 'pick_event',
- 'figure_enter_event',
- 'figure_leave_event',
- 'axes_enter_event',
- 'axes_leave_event',
- 'close_event'
- ]
-
- fixed_dpi = None
-
- filetypes = _default_filetypes
-
- @_api.classproperty
- def supports_blit(cls):
- """If this Canvas sub-class supports blitting."""
- return (hasattr(cls, "copy_from_bbox")
- and hasattr(cls, "restore_region"))
-
- def __init__(self, figure=None):
- from matplotlib.figure import Figure
- self._fix_ipython_backend2gui()
- self._is_idle_drawing = True
- self._is_saving = False
- if figure is None:
- figure = Figure()
- figure.set_canvas(self)
- self.figure = figure
- self.manager = None
- self.widgetlock = widgets.LockDraw()
- self._button = None # the button pressed
- self._key = None # the key pressed
- self.mouse_grabber = None # the Axes currently grabbing mouse
- self.toolbar = None # NavigationToolbar2 will set me
- self._is_idle_drawing = False
- # We don't want to scale up the figure DPI more than once.
- figure._original_dpi = figure.dpi
- self._device_pixel_ratio = 1
- super().__init__() # Typically the GUI widget init (if any).
-
- callbacks = property(lambda self: self.figure._canvas_callbacks)
- button_pick_id = property(lambda self: self.figure._button_pick_id)
- scroll_pick_id = property(lambda self: self.figure._scroll_pick_id)
-
- @classmethod
- @functools.cache
- def _fix_ipython_backend2gui(cls):
- # Fix hard-coded module -> toolkit mapping in IPython (used for
- # `ipython --auto`). This cannot be done at import time due to
- # ordering issues, so we do it when creating a canvas, and should only
- # be done once per class (hence the `cache`).
- if sys.modules.get("IPython") is None:
- return
- import IPython
- ip = IPython.get_ipython()
- if not ip:
- return
- from IPython.core import pylabtools as pt
- if (not hasattr(pt, "backend2gui")
- or not hasattr(ip, "enable_matplotlib")):
- # In case we ever move the patch to IPython and remove these APIs,
- # don't break on our side.
- return
- backend2gui_rif = {
- "qt": "qt",
- "gtk3": "gtk3",
- "gtk4": "gtk4",
- "wx": "wx",
- "macosx": "osx",
- }.get(cls.required_interactive_framework)
- if backend2gui_rif:
- if _is_non_interactive_terminal_ipython(ip):
- ip.enable_gui(backend2gui_rif)
-
- @classmethod
- def new_manager(cls, figure, num):
- """
- Create a new figure manager for *figure*, using this canvas class.
-
- Notes
- -----
- This method should not be reimplemented in subclasses. If
- custom manager creation logic is needed, please reimplement
- ``FigureManager.create_with_canvas``.
- """
- return cls.manager_class.create_with_canvas(cls, figure, num)
-
- @contextmanager
- def _idle_draw_cntx(self):
- self._is_idle_drawing = True
- try:
- yield
- finally:
- self._is_idle_drawing = False
-
- def is_saving(self):
- """
- Return whether the renderer is in the process of saving
- to a file, rather than rendering for an on-screen buffer.
- """
- return self._is_saving
-
- def blit(self, bbox=None):
- """Blit the canvas in bbox (default entire canvas)."""
-
- def inaxes(self, xy):
- """
- Return the topmost visible `~.axes.Axes` containing the point *xy*.
-
- Parameters
- ----------
- xy : (float, float)
- (x, y) pixel positions from left/bottom of the canvas.
-
- Returns
- -------
- `~matplotlib.axes.Axes` or None
- The topmost visible Axes containing the point, or None if there
- is no Axes at the point.
- """
- axes_list = [a for a in self.figure.get_axes()
- if a.patch.contains_point(xy) and a.get_visible()]
- if axes_list:
- axes = cbook._topmost_artist(axes_list)
- else:
- axes = None
-
- return axes
-
- def grab_mouse(self, ax):
- """
- Set the child `~.axes.Axes` which is grabbing the mouse events.
-
- Usually called by the widgets themselves. It is an error to call this
- if the mouse is already grabbed by another Axes.
- """
- if self.mouse_grabber not in (None, ax):
- raise RuntimeError("Another Axes already grabs mouse input")
- self.mouse_grabber = ax
-
- def release_mouse(self, ax):
- """
- Release the mouse grab held by the `~.axes.Axes` *ax*.
-
- Usually called by the widgets. It is ok to call this even if *ax*
- doesn't have the mouse grab currently.
- """
- if self.mouse_grabber is ax:
- self.mouse_grabber = None
-
- def set_cursor(self, cursor):
- """
- Set the current cursor.
-
- This may have no effect if the backend does not display anything.
-
- If required by the backend, this method should trigger an update in
- the backend event loop after the cursor is set, as this method may be
- called e.g. before a long-running task during which the GUI is not
- updated.
-
- Parameters
- ----------
- cursor : `.Cursors`
- The cursor to display over the canvas. Note: some backends may
- change the cursor for the entire window.
- """
-
- def draw(self, *args, **kwargs):
- """
- Render the `.Figure`.
-
- This method must walk the artist tree, even if no output is produced,
- because it triggers deferred work that users may want to access
- before saving output to disk. For example computing limits,
- auto-limits, and tick values.
- """
-
- def draw_idle(self, *args, **kwargs):
- """
- Request a widget redraw once control returns to the GUI event loop.
-
- Even if multiple calls to `draw_idle` occur before control returns
- to the GUI event loop, the figure will only be rendered once.
-
- Notes
- -----
- Backends may choose to override the method and implement their own
- strategy to prevent multiple renderings.
-
- """
- if not self._is_idle_drawing:
- with self._idle_draw_cntx():
- self.draw(*args, **kwargs)
-
- @property
- def device_pixel_ratio(self):
- """
- The ratio of physical to logical pixels used for the canvas on screen.
-
- By default, this is 1, meaning physical and logical pixels are the same
- size. Subclasses that support High DPI screens may set this property to
- indicate that said ratio is different. All Matplotlib interaction,
- unless working directly with the canvas, remains in logical pixels.
-
- """
- return self._device_pixel_ratio
-
- def _set_device_pixel_ratio(self, ratio):
- """
- Set the ratio of physical to logical pixels used for the canvas.
-
- Subclasses that support High DPI screens can set this property to
- indicate that said ratio is different. The canvas itself will be
- created at the physical size, while the client side will use the
- logical size. Thus the DPI of the Figure will change to be scaled by
- this ratio. Implementations that support High DPI screens should use
- physical pixels for events so that transforms back to Axes space are
- correct.
-
- By default, this is 1, meaning physical and logical pixels are the same
- size.
-
- Parameters
- ----------
- ratio : float
- The ratio of logical to physical pixels used for the canvas.
-
- Returns
- -------
- bool
- Whether the ratio has changed. Backends may interpret this as a
- signal to resize the window, repaint the canvas, or change any
- other relevant properties.
- """
- if self._device_pixel_ratio == ratio:
- return False
- # In cases with mixed resolution displays, we need to be careful if the
- # device pixel ratio changes - in this case we need to resize the
- # canvas accordingly. Some backends provide events that indicate a
- # change in DPI, but those that don't will update this before drawing.
- dpi = ratio * self.figure._original_dpi
- self.figure._set_dpi(dpi, forward=False)
- self._device_pixel_ratio = ratio
- return True
-
- def get_width_height(self, *, physical=False):
- """
- Return the figure width and height in integral points or pixels.
-
- When the figure is used on High DPI screens (and the backend supports
- it), the truncation to integers occurs after scaling by the device
- pixel ratio.
-
- Parameters
- ----------
- physical : bool, default: False
- Whether to return true physical pixels or logical pixels. Physical
- pixels may be used by backends that support HiDPI, but still
- configure the canvas using its actual size.
-
- Returns
- -------
- width, height : int
- The size of the figure, in points or pixels, depending on the
- backend.
- """
- return tuple(int(size / (1 if physical else self.device_pixel_ratio))
- for size in self.figure.bbox.max)
-
- @classmethod
- def get_supported_filetypes(cls):
- """Return dict of savefig file formats supported by this backend."""
- return cls.filetypes
-
- @classmethod
- def get_supported_filetypes_grouped(cls):
- """
- Return a dict of savefig file formats supported by this backend,
- where the keys are a file type name, such as 'Joint Photographic
- Experts Group', and the values are a list of filename extensions used
- for that filetype, such as ['jpg', 'jpeg'].
- """
- groupings = {}
- for ext, name in cls.filetypes.items():
- groupings.setdefault(name, []).append(ext)
- groupings[name].sort()
- return groupings
-
- @contextmanager
- def _switch_canvas_and_return_print_method(self, fmt, backend=None):
- """
- Context manager temporarily setting the canvas for saving the figure::
-
- with canvas._switch_canvas_and_return_print_method(fmt, backend) \\
- as print_method:
- # ``print_method`` is a suitable ``print_{fmt}`` method, and
- # the figure's canvas is temporarily switched to the method's
- # canvas within the with... block. ``print_method`` is also
- # wrapped to suppress extra kwargs passed by ``print_figure``.
-
- Parameters
- ----------
- fmt : str
- If *backend* is None, then determine a suitable canvas class for
- saving to format *fmt* -- either the current canvas class, if it
- supports *fmt*, or whatever `get_registered_canvas_class` returns;
- switch the figure canvas to that canvas class.
- backend : str or None, default: None
- If not None, switch the figure canvas to the ``FigureCanvas`` class
- of the given backend.
- """
- canvas = None
- if backend is not None:
- # Return a specific canvas class, if requested.
- canvas_class = (
- importlib.import_module(cbook._backend_module_name(backend))
- .FigureCanvas)
- if not hasattr(canvas_class, f"print_{fmt}"):
- raise ValueError(
- f"The {backend!r} backend does not support {fmt} output")
- canvas = canvas_class(self.figure)
- elif hasattr(self, f"print_{fmt}"):
- # Return the current canvas if it supports the requested format.
- canvas = self
- else:
- # Return a default canvas for the requested format, if it exists.
- canvas_class = get_registered_canvas_class(fmt)
- if canvas_class is None:
- raise ValueError(
- "Format {!r} is not supported (supported formats: {})".format(
- fmt, ", ".join(sorted(self.get_supported_filetypes()))))
- canvas = canvas_class(self.figure)
- canvas._is_saving = self._is_saving
- meth = getattr(canvas, f"print_{fmt}")
- mod = (meth.func.__module__
- if hasattr(meth, "func") # partialmethod, e.g. backend_wx.
- else meth.__module__)
- if mod.startswith(("matplotlib.", "mpl_toolkits.")):
- optional_kws = { # Passed by print_figure for other renderers.
- "dpi", "facecolor", "edgecolor", "orientation",
- "bbox_inches_restore"}
- skip = optional_kws - {*inspect.signature(meth).parameters}
- print_method = functools.wraps(meth)(lambda *args, **kwargs: meth(
- *args, **{k: v for k, v in kwargs.items() if k not in skip}))
- else: # Let third-parties do as they see fit.
- print_method = meth
- try:
- yield print_method
- finally:
- self.figure.canvas = self
-
- def print_figure(
- self, filename, dpi=None, facecolor=None, edgecolor=None,
- orientation='portrait', format=None, *,
- bbox_inches=None, pad_inches=None, bbox_extra_artists=None,
- backend=None, **kwargs):
- """
- Render the figure to hardcopy. Set the figure patch face and edge
- colors. This is useful because some of the GUIs have a gray figure
- face color background and you'll probably want to override this on
- hardcopy.
-
- Parameters
- ----------
- filename : str or path-like or file-like
- The file where the figure is saved.
-
- dpi : float, default: :rc:`savefig.dpi`
- The dots per inch to save the figure in.
-
- facecolor : color or 'auto', default: :rc:`savefig.facecolor`
- The facecolor of the figure. If 'auto', use the current figure
- facecolor.
-
- edgecolor : color or 'auto', default: :rc:`savefig.edgecolor`
- The edgecolor of the figure. If 'auto', use the current figure
- edgecolor.
-
- orientation : {'landscape', 'portrait'}, default: 'portrait'
- Only currently applies to PostScript printing.
-
- format : str, optional
- Force a specific file format. If not given, the format is inferred
- from the *filename* extension, and if that fails from
- :rc:`savefig.format`.
-
- bbox_inches : 'tight' or `.Bbox`, default: :rc:`savefig.bbox`
- Bounding box in inches: only the given portion of the figure is
- saved. If 'tight', try to figure out the tight bbox of the figure.
-
- pad_inches : float or 'layout', default: :rc:`savefig.pad_inches`
- Amount of padding in inches around the figure when bbox_inches is
- 'tight'. If 'layout' use the padding from the constrained or
- compressed layout engine; ignored if one of those engines is not in
- use.
-
- bbox_extra_artists : list of `~matplotlib.artist.Artist`, optional
- A list of extra artists that will be considered when the
- tight bbox is calculated.
-
- backend : str, optional
- Use a non-default backend to render the file, e.g. to render a
- png file with the "cairo" backend rather than the default "agg",
- or a pdf file with the "pgf" backend rather than the default
- "pdf". Note that the default backend is normally sufficient. See
- :ref:`the-builtin-backends` for a list of valid backends for each
- file format. Custom backends can be referenced as "module://...".
- """
- if format is None:
- # get format from filename, or from backend's default filetype
- if isinstance(filename, os.PathLike):
- filename = os.fspath(filename)
- if isinstance(filename, str):
- format = os.path.splitext(filename)[1][1:]
- if format is None or format == '':
- format = self.get_default_filetype()
- if isinstance(filename, str):
- filename = filename.rstrip('.') + '.' + format
- format = format.lower()
-
- if dpi is None:
- dpi = rcParams['savefig.dpi']
- if dpi == 'figure':
- dpi = getattr(self.figure, '_original_dpi', self.figure.dpi)
-
- if kwargs.get("papertype") == 'auto':
- # When deprecation elapses, remove backend_ps._get_papertype & its callers.
- _api.warn_deprecated(
- "3.8", name="papertype='auto'", addendum="Pass an explicit paper type, "
- "'figure', or omit the *papertype* argument entirely.")
-
- # Remove the figure manager, if any, to avoid resizing the GUI widget.
- with cbook._setattr_cm(self, manager=None), \
- self._switch_canvas_and_return_print_method(format, backend) \
- as print_method, \
- cbook._setattr_cm(self.figure, dpi=dpi), \
- cbook._setattr_cm(self.figure.canvas, _device_pixel_ratio=1), \
- cbook._setattr_cm(self.figure.canvas, _is_saving=True), \
- ExitStack() as stack:
-
- for prop in ["facecolor", "edgecolor"]:
- color = locals()[prop]
- if color is None:
- color = rcParams[f"savefig.{prop}"]
- if not cbook._str_equal(color, "auto"):
- stack.enter_context(self.figure._cm_set(**{prop: color}))
-
- if bbox_inches is None:
- bbox_inches = rcParams['savefig.bbox']
-
- layout_engine = self.figure.get_layout_engine()
- if layout_engine is not None or bbox_inches == "tight":
- # we need to trigger a draw before printing to make sure
- # CL works. "tight" also needs a draw to get the right
- # locations:
- renderer = _get_renderer(
- self.figure,
- functools.partial(
- print_method, orientation=orientation)
- )
- # we do this instead of `self.figure.draw_without_rendering`
- # so that we can inject the orientation
- with getattr(renderer, "_draw_disabled", nullcontext)():
- self.figure.draw(renderer)
- if bbox_inches:
- if bbox_inches == "tight":
- bbox_inches = self.figure.get_tightbbox(
- renderer, bbox_extra_artists=bbox_extra_artists)
- if (isinstance(layout_engine, ConstrainedLayoutEngine) and
- pad_inches == "layout"):
- h_pad = layout_engine.get()["h_pad"]
- w_pad = layout_engine.get()["w_pad"]
- else:
- if pad_inches in [None, "layout"]:
- pad_inches = rcParams['savefig.pad_inches']
- h_pad = w_pad = pad_inches
- bbox_inches = bbox_inches.padded(w_pad, h_pad)
-
- # call adjust_bbox to save only the given area
- restore_bbox = _tight_bbox.adjust_bbox(
- self.figure, bbox_inches, self.figure.canvas.fixed_dpi)
-
- _bbox_inches_restore = (bbox_inches, restore_bbox)
- else:
- _bbox_inches_restore = None
-
- # we have already done layout above, so turn it off:
- stack.enter_context(self.figure._cm_set(layout_engine='none'))
- try:
- # _get_renderer may change the figure dpi (as vector formats
- # force the figure dpi to 72), so we need to set it again here.
- with cbook._setattr_cm(self.figure, dpi=dpi):
- result = print_method(
- filename,
- facecolor=facecolor,
- edgecolor=edgecolor,
- orientation=orientation,
- bbox_inches_restore=_bbox_inches_restore,
- **kwargs)
- finally:
- if bbox_inches and restore_bbox:
- restore_bbox()
-
- return result
-
- @classmethod
- def get_default_filetype(cls):
- """
- Return the default savefig file format as specified in
- :rc:`savefig.format`.
-
- The returned string does not include a period. This method is
- overridden in backends that only support a single file type.
- """
- return rcParams['savefig.format']
-
- def get_default_filename(self):
- """
- Return a string, which includes extension, suitable for use as
- a default filename.
- """
- basename = (self.manager.get_window_title() if self.manager is not None
- else '')
- basename = (basename or 'image').replace(' ', '_')
- filetype = self.get_default_filetype()
- filename = basename + '.' + filetype
- return filename
-
- @_api.deprecated("3.8")
- def switch_backends(self, FigureCanvasClass):
- """
- Instantiate an instance of FigureCanvasClass
-
- This is used for backend switching, e.g., to instantiate a
- FigureCanvasPS from a FigureCanvasGTK. Note, deep copying is
- not done, so any changes to one of the instances (e.g., setting
- figure size or line props), will be reflected in the other
- """
- newCanvas = FigureCanvasClass(self.figure)
- newCanvas._is_saving = self._is_saving
- return newCanvas
-
- def mpl_connect(self, s, func):
- """
- Bind function *func* to event *s*.
-
- Parameters
- ----------
- s : str
- One of the following events ids:
-
- - 'button_press_event'
- - 'button_release_event'
- - 'draw_event'
- - 'key_press_event'
- - 'key_release_event'
- - 'motion_notify_event'
- - 'pick_event'
- - 'resize_event'
- - 'scroll_event'
- - 'figure_enter_event',
- - 'figure_leave_event',
- - 'axes_enter_event',
- - 'axes_leave_event'
- - 'close_event'.
-
- func : callable
- The callback function to be executed, which must have the
- signature::
-
- def func(event: Event) -> Any
-
- For the location events (button and key press/release), if the
- mouse is over the Axes, the ``inaxes`` attribute of the event will
- be set to the `~matplotlib.axes.Axes` the event occurs is over, and
- additionally, the variables ``xdata`` and ``ydata`` attributes will
- be set to the mouse location in data coordinates. See `.KeyEvent`
- and `.MouseEvent` for more info.
-
- .. note::
-
- If func is a method, this only stores a weak reference to the
- method. Thus, the figure does not influence the lifetime of
- the associated object. Usually, you want to make sure that the
- object is kept alive throughout the lifetime of the figure by
- holding a reference to it.
-
- Returns
- -------
- cid
- A connection id that can be used with
- `.FigureCanvasBase.mpl_disconnect`.
-
- Examples
- --------
- ::
-
- def on_press(event):
- print('you pressed', event.button, event.xdata, event.ydata)
-
- cid = canvas.mpl_connect('button_press_event', on_press)
- """
-
- return self.callbacks.connect(s, func)
-
- def mpl_disconnect(self, cid):
- """
- Disconnect the callback with id *cid*.
-
- Examples
- --------
- ::
-
- cid = canvas.mpl_connect('button_press_event', on_press)
- # ... later
- canvas.mpl_disconnect(cid)
- """
- self.callbacks.disconnect(cid)
-
- # Internal subclasses can override _timer_cls instead of new_timer, though
- # this is not a public API for third-party subclasses.
- _timer_cls = TimerBase
-
- def new_timer(self, interval=None, callbacks=None):
- """
- Create a new backend-specific subclass of `.Timer`.
-
- This is useful for getting periodic events through the backend's native
- event loop. Implemented only for backends with GUIs.
-
- Parameters
- ----------
- interval : int
- Timer interval in milliseconds.
-
- callbacks : list[tuple[callable, tuple, dict]]
- Sequence of (func, args, kwargs) where ``func(*args, **kwargs)``
- will be executed by the timer every *interval*.
-
- Callbacks which return ``False`` or ``0`` will be removed from the
- timer.
-
- Examples
- --------
- >>> timer = fig.canvas.new_timer(callbacks=[(f1, (1,), {'a': 3})])
- """
- return self._timer_cls(interval=interval, callbacks=callbacks)
-
- def flush_events(self):
- """
- Flush the GUI events for the figure.
-
- Interactive backends need to reimplement this method.
- """
-
- def start_event_loop(self, timeout=0):
- """
- Start a blocking event loop.
-
- Such an event loop is used by interactive functions, such as
- `~.Figure.ginput` and `~.Figure.waitforbuttonpress`, to wait for
- events.
-
- The event loop blocks until a callback function triggers
- `stop_event_loop`, or *timeout* is reached.
-
- If *timeout* is 0 or negative, never timeout.
-
- Only interactive backends need to reimplement this method and it relies
- on `flush_events` being properly implemented.
-
- Interactive backends should implement this in a more native way.
- """
- if timeout <= 0:
- timeout = np.inf
- timestep = 0.01
- counter = 0
- self._looping = True
- while self._looping and counter * timestep < timeout:
- self.flush_events()
- time.sleep(timestep)
- counter += 1
-
- def stop_event_loop(self):
- """
- Stop the current blocking event loop.
-
- Interactive backends need to reimplement this to match
- `start_event_loop`
- """
- self._looping = False
-
-
-def key_press_handler(event, canvas=None, toolbar=None):
- """
- Implement the default Matplotlib key bindings for the canvas and toolbar
- described at :ref:`key-event-handling`.
-
- Parameters
- ----------
- event : `KeyEvent`
- A key press/release event.
- canvas : `FigureCanvasBase`, default: ``event.canvas``
- The backend-specific canvas instance. This parameter is kept for
- back-compatibility, but, if set, should always be equal to
- ``event.canvas``.
- toolbar : `NavigationToolbar2`, default: ``event.canvas.toolbar``
- The navigation cursor toolbar. This parameter is kept for
- back-compatibility, but, if set, should always be equal to
- ``event.canvas.toolbar``.
- """
- # these bindings happen whether you are over an Axes or not
-
- if event.key is None:
- return
- if canvas is None:
- canvas = event.canvas
- if toolbar is None:
- toolbar = canvas.toolbar
-
- # Load key-mappings from rcParams.
- fullscreen_keys = rcParams['keymap.fullscreen']
- home_keys = rcParams['keymap.home']
- back_keys = rcParams['keymap.back']
- forward_keys = rcParams['keymap.forward']
- pan_keys = rcParams['keymap.pan']
- zoom_keys = rcParams['keymap.zoom']
- save_keys = rcParams['keymap.save']
- quit_keys = rcParams['keymap.quit']
- quit_all_keys = rcParams['keymap.quit_all']
- grid_keys = rcParams['keymap.grid']
- grid_minor_keys = rcParams['keymap.grid_minor']
- toggle_yscale_keys = rcParams['keymap.yscale']
- toggle_xscale_keys = rcParams['keymap.xscale']
-
- # toggle fullscreen mode ('f', 'ctrl + f')
- if event.key in fullscreen_keys:
- try:
- canvas.manager.full_screen_toggle()
- except AttributeError:
- pass
-
- # quit the figure (default key 'ctrl+w')
- if event.key in quit_keys:
- Gcf.destroy_fig(canvas.figure)
- if event.key in quit_all_keys:
- Gcf.destroy_all()
-
- if toolbar is not None:
- # home or reset mnemonic (default key 'h', 'home' and 'r')
- if event.key in home_keys:
- toolbar.home()
- # forward / backward keys to enable left handed quick navigation
- # (default key for backward: 'left', 'backspace' and 'c')
- elif event.key in back_keys:
- toolbar.back()
- # (default key for forward: 'right' and 'v')
- elif event.key in forward_keys:
- toolbar.forward()
- # pan mnemonic (default key 'p')
- elif event.key in pan_keys:
- toolbar.pan()
- toolbar._update_cursor(event)
- # zoom mnemonic (default key 'o')
- elif event.key in zoom_keys:
- toolbar.zoom()
- toolbar._update_cursor(event)
- # saving current figure (default key 's')
- elif event.key in save_keys:
- toolbar.save_figure()
-
- if event.inaxes is None:
- return
-
- # these bindings require the mouse to be over an Axes to trigger
- def _get_uniform_gridstate(ticks):
- # Return True/False if all grid lines are on or off, None if they are
- # not all in the same state.
- if all(tick.gridline.get_visible() for tick in ticks):
- return True
- elif not any(tick.gridline.get_visible() for tick in ticks):
- return False
- else:
- return None
-
- ax = event.inaxes
- # toggle major grids in current Axes (default key 'g')
- # Both here and below (for 'G'), we do nothing if *any* grid (major or
- # minor, x or y) is not in a uniform state, to avoid messing up user
- # customization.
- if (event.key in grid_keys
- # Exclude minor grids not in a uniform state.
- and None not in [_get_uniform_gridstate(ax.xaxis.minorTicks),
- _get_uniform_gridstate(ax.yaxis.minorTicks)]):
- x_state = _get_uniform_gridstate(ax.xaxis.majorTicks)
- y_state = _get_uniform_gridstate(ax.yaxis.majorTicks)
- cycle = [(False, False), (True, False), (True, True), (False, True)]
- try:
- x_state, y_state = (
- cycle[(cycle.index((x_state, y_state)) + 1) % len(cycle)])
- except ValueError:
- # Exclude major grids not in a uniform state.
- pass
- else:
- # If turning major grids off, also turn minor grids off.
- ax.grid(x_state, which="major" if x_state else "both", axis="x")
- ax.grid(y_state, which="major" if y_state else "both", axis="y")
- canvas.draw_idle()
- # toggle major and minor grids in current Axes (default key 'G')
- if (event.key in grid_minor_keys
- # Exclude major grids not in a uniform state.
- and None not in [_get_uniform_gridstate(ax.xaxis.majorTicks),
- _get_uniform_gridstate(ax.yaxis.majorTicks)]):
- x_state = _get_uniform_gridstate(ax.xaxis.minorTicks)
- y_state = _get_uniform_gridstate(ax.yaxis.minorTicks)
- cycle = [(False, False), (True, False), (True, True), (False, True)]
- try:
- x_state, y_state = (
- cycle[(cycle.index((x_state, y_state)) + 1) % len(cycle)])
- except ValueError:
- # Exclude minor grids not in a uniform state.
- pass
- else:
- ax.grid(x_state, which="both", axis="x")
- ax.grid(y_state, which="both", axis="y")
- canvas.draw_idle()
- # toggle scaling of y-axes between 'log and 'linear' (default key 'l')
- elif event.key in toggle_yscale_keys:
- scale = ax.get_yscale()
- if scale == 'log':
- ax.set_yscale('linear')
- ax.figure.canvas.draw_idle()
- elif scale == 'linear':
- try:
- ax.set_yscale('log')
- except ValueError as exc:
- _log.warning(str(exc))
- ax.set_yscale('linear')
- ax.figure.canvas.draw_idle()
- # toggle scaling of x-axes between 'log and 'linear' (default key 'k')
- elif event.key in toggle_xscale_keys:
- scalex = ax.get_xscale()
- if scalex == 'log':
- ax.set_xscale('linear')
- ax.figure.canvas.draw_idle()
- elif scalex == 'linear':
- try:
- ax.set_xscale('log')
- except ValueError as exc:
- _log.warning(str(exc))
- ax.set_xscale('linear')
- ax.figure.canvas.draw_idle()
-
-
-def button_press_handler(event, canvas=None, toolbar=None):
- """
- The default Matplotlib button actions for extra mouse buttons.
-
- Parameters are as for `key_press_handler`, except that *event* is a
- `MouseEvent`.
- """
- if canvas is None:
- canvas = event.canvas
- if toolbar is None:
- toolbar = canvas.toolbar
- if toolbar is not None:
- button_name = str(MouseButton(event.button))
- if button_name in rcParams['keymap.back']:
- toolbar.back()
- elif button_name in rcParams['keymap.forward']:
- toolbar.forward()
-
-
-class NonGuiException(Exception):
- """Raised when trying show a figure in a non-GUI backend."""
- pass
-
-
-class FigureManagerBase:
- """
- A backend-independent abstraction of a figure container and controller.
-
- The figure manager is used by pyplot to interact with the window in a
- backend-independent way. It's an adapter for the real (GUI) framework that
- represents the visual figure on screen.
-
- GUI backends define from this class to translate common operations such
- as *show* or *resize* to the GUI-specific code. Non-GUI backends do not
- support these operations an can just use the base class.
-
- This following basic operations are accessible:
-
- **Window operations**
-
- - `~.FigureManagerBase.show`
- - `~.FigureManagerBase.destroy`
- - `~.FigureManagerBase.full_screen_toggle`
- - `~.FigureManagerBase.resize`
- - `~.FigureManagerBase.get_window_title`
- - `~.FigureManagerBase.set_window_title`
-
- **Key and mouse button press handling**
-
- The figure manager sets up default key and mouse button press handling by
- hooking up the `.key_press_handler` to the matplotlib event system. This
- ensures the same shortcuts and mouse actions across backends.
-
- **Other operations**
-
- Subclasses will have additional attributes and functions to access
- additional functionality. This is of course backend-specific. For example,
- most GUI backends have ``window`` and ``toolbar`` attributes that give
- access to the native GUI widgets of the respective framework.
-
- Attributes
- ----------
- canvas : `FigureCanvasBase`
- The backend-specific canvas instance.
-
- num : int or str
- The figure number.
-
- key_press_handler_id : int
- The default key handler cid, when using the toolmanager.
- To disable the default key press handling use::
-
- figure.canvas.mpl_disconnect(
- figure.canvas.manager.key_press_handler_id)
-
- button_press_handler_id : int
- The default mouse button handler cid, when using the toolmanager.
- To disable the default button press handling use::
-
- figure.canvas.mpl_disconnect(
- figure.canvas.manager.button_press_handler_id)
- """
-
- _toolbar2_class = None
- _toolmanager_toolbar_class = None
-
- def __init__(self, canvas, num):
- self.canvas = canvas
- canvas.manager = self # store a pointer to parent
- self.num = num
- self.set_window_title(f"Figure {num:d}")
-
- self.key_press_handler_id = None
- self.button_press_handler_id = None
- if rcParams['toolbar'] != 'toolmanager':
- self.key_press_handler_id = self.canvas.mpl_connect(
- 'key_press_event', key_press_handler)
- self.button_press_handler_id = self.canvas.mpl_connect(
- 'button_press_event', button_press_handler)
-
- self.toolmanager = (ToolManager(canvas.figure)
- if mpl.rcParams['toolbar'] == 'toolmanager'
- else None)
- if (mpl.rcParams["toolbar"] == "toolbar2"
- and self._toolbar2_class):
- self.toolbar = self._toolbar2_class(self.canvas)
- elif (mpl.rcParams["toolbar"] == "toolmanager"
- and self._toolmanager_toolbar_class):
- self.toolbar = self._toolmanager_toolbar_class(self.toolmanager)
- else:
- self.toolbar = None
-
- if self.toolmanager:
- tools.add_tools_to_manager(self.toolmanager)
- if self.toolbar:
- tools.add_tools_to_container(self.toolbar)
-
- @self.canvas.figure.add_axobserver
- def notify_axes_change(fig):
- # Called whenever the current Axes is changed.
- if self.toolmanager is None and self.toolbar is not None:
- self.toolbar.update()
-
- @classmethod
- def create_with_canvas(cls, canvas_class, figure, num):
- """
- Create a manager for a given *figure* using a specific *canvas_class*.
-
- Backends should override this method if they have specific needs for
- setting up the canvas or the manager.
- """
- return cls(canvas_class(figure), num)
-
- @classmethod
- def start_main_loop(cls):
- """
- Start the main event loop.
-
- This method is called by `.FigureManagerBase.pyplot_show`, which is the
- implementation of `.pyplot.show`. To customize the behavior of
- `.pyplot.show`, interactive backends should usually override
- `~.FigureManagerBase.start_main_loop`; if more customized logic is
- necessary, `~.FigureManagerBase.pyplot_show` can also be overridden.
- """
-
- @classmethod
- def pyplot_show(cls, *, block=None):
- """
- Show all figures. This method is the implementation of `.pyplot.show`.
-
- To customize the behavior of `.pyplot.show`, interactive backends
- should usually override `~.FigureManagerBase.start_main_loop`; if more
- customized logic is necessary, `~.FigureManagerBase.pyplot_show` can
- also be overridden.
-
- Parameters
- ----------
- block : bool, optional
- Whether to block by calling ``start_main_loop``. The default,
- None, means to block if we are neither in IPython's ``%pylab`` mode
- nor in ``interactive`` mode.
- """
- managers = Gcf.get_all_fig_managers()
- if not managers:
- return
- for manager in managers:
- try:
- manager.show() # Emits a warning for non-interactive backend.
- except NonGuiException as exc:
- _api.warn_external(str(exc))
- if block is None:
- # Hack: Are we in IPython's %pylab mode? In pylab mode, IPython
- # (>= 0.10) tacks a _needmain attribute onto pyplot.show (always
- # set to False).
- pyplot_show = getattr(sys.modules.get("matplotlib.pyplot"), "show", None)
- ipython_pylab = hasattr(pyplot_show, "_needmain")
- block = not ipython_pylab and not is_interactive()
- if block:
- cls.start_main_loop()
-
- def show(self):
- """
- For GUI backends, show the figure window and redraw.
- For non-GUI backends, raise an exception, unless running headless (i.e.
- on Linux with an unset DISPLAY); this exception is converted to a
- warning in `.Figure.show`.
- """
- # This should be overridden in GUI backends.
- if sys.platform == "linux" and not os.environ.get("DISPLAY"):
- # We cannot check _get_running_interactive_framework() ==
- # "headless" because that would also suppress the warning when
- # $DISPLAY exists but is invalid, which is more likely an error and
- # thus warrants a warning.
- return
- raise NonGuiException(
- f"{type(self.canvas).__name__} is non-interactive, and thus cannot be "
- f"shown")
-
- def destroy(self):
- pass
-
- def full_screen_toggle(self):
- pass
-
- def resize(self, w, h):
- """For GUI backends, resize the window (in physical pixels)."""
-
- def get_window_title(self):
- """
- Return the title text of the window containing the figure, or None
- if there is no window (e.g., a PS backend).
- """
- return 'image'
-
- def set_window_title(self, title):
- """
- Set the title text of the window containing the figure.
-
- This has no effect for non-GUI (e.g., PS) backends.
- """
-
-
-cursors = tools.cursors
-
-
-class _Mode(str, Enum):
- NONE = ""
- PAN = "pan/zoom"
- ZOOM = "zoom rect"
-
- def __str__(self):
- return self.value
-
- @property
- def _navigate_mode(self):
- return self.name if self is not _Mode.NONE else None
-
-
-class NavigationToolbar2:
- """
- Base class for the navigation cursor, version 2.
-
- Backends must implement a canvas that handles connections for
- 'button_press_event' and 'button_release_event'. See
- :meth:`FigureCanvasBase.mpl_connect` for more information.
-
- They must also define
-
- :meth:`save_figure`
- Save the current figure.
-
- :meth:`draw_rubberband` (optional)
- Draw the zoom to rect "rubberband" rectangle.
-
- :meth:`set_message` (optional)
- Display message.
-
- :meth:`set_history_buttons` (optional)
- You can change the history back / forward buttons to indicate disabled / enabled
- state.
-
- and override ``__init__`` to set up the toolbar -- without forgetting to
- call the base-class init. Typically, ``__init__`` needs to set up toolbar
- buttons connected to the `home`, `back`, `forward`, `pan`, `zoom`, and
- `save_figure` methods and using standard icons in the "images" subdirectory
- of the data path.
-
- That's it, we'll do the rest!
- """
-
- # list of toolitems to add to the toolbar, format is:
- # (
- # text, # the text of the button (often not visible to users)
- # tooltip_text, # the tooltip shown on hover (where possible)
- # image_file, # name of the image for the button (without the extension)
- # name_of_method, # name of the method in NavigationToolbar2 to call
- # )
- toolitems = (
- ('Home', 'Reset original view', 'home', 'home'),
- ('Back', 'Back to previous view', 'back', 'back'),
- ('Forward', 'Forward to next view', 'forward', 'forward'),
- (None, None, None, None),
- ('Pan',
- 'Left button pans, Right button zooms\n'
- 'x/y fixes axis, CTRL fixes aspect',
- 'move', 'pan'),
- ('Zoom', 'Zoom to rectangle\nx/y fixes axis', 'zoom_to_rect', 'zoom'),
- ('Subplots', 'Configure subplots', 'subplots', 'configure_subplots'),
- (None, None, None, None),
- ('Save', 'Save the figure', 'filesave', 'save_figure'),
- )
-
- def __init__(self, canvas):
- self.canvas = canvas
- canvas.toolbar = self
- self._nav_stack = cbook._Stack()
- # This cursor will be set after the initial draw.
- self._last_cursor = tools.Cursors.POINTER
-
- self._id_press = self.canvas.mpl_connect(
- 'button_press_event', self._zoom_pan_handler)
- self._id_release = self.canvas.mpl_connect(
- 'button_release_event', self._zoom_pan_handler)
- self._id_drag = self.canvas.mpl_connect(
- 'motion_notify_event', self.mouse_move)
- self._pan_info = None
- self._zoom_info = None
-
- self.mode = _Mode.NONE # a mode string for the status bar
- self.set_history_buttons()
-
- def set_message(self, s):
- """Display a message on toolbar or in status bar."""
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- """
- Draw a rectangle rubberband to indicate zoom limits.
-
- Note that it is not guaranteed that ``x0 <= x1`` and ``y0 <= y1``.
- """
-
- def remove_rubberband(self):
- """Remove the rubberband."""
-
- def home(self, *args):
- """
- Restore the original view.
-
- For convenience of being directly connected as a GUI callback, which
- often get passed additional parameters, this method accepts arbitrary
- parameters, but does not use them.
- """
- self._nav_stack.home()
- self.set_history_buttons()
- self._update_view()
-
- def back(self, *args):
- """
- Move back up the view lim stack.
-
- For convenience of being directly connected as a GUI callback, which
- often get passed additional parameters, this method accepts arbitrary
- parameters, but does not use them.
- """
- self._nav_stack.back()
- self.set_history_buttons()
- self._update_view()
-
- def forward(self, *args):
- """
- Move forward in the view lim stack.
-
- For convenience of being directly connected as a GUI callback, which
- often get passed additional parameters, this method accepts arbitrary
- parameters, but does not use them.
- """
- self._nav_stack.forward()
- self.set_history_buttons()
- self._update_view()
-
- def _update_cursor(self, event):
- """
- Update the cursor after a mouse move event or a tool (de)activation.
- """
- if self.mode and event.inaxes and event.inaxes.get_navigate():
- if (self.mode == _Mode.ZOOM
- and self._last_cursor != tools.Cursors.SELECT_REGION):
- self.canvas.set_cursor(tools.Cursors.SELECT_REGION)
- self._last_cursor = tools.Cursors.SELECT_REGION
- elif (self.mode == _Mode.PAN
- and self._last_cursor != tools.Cursors.MOVE):
- self.canvas.set_cursor(tools.Cursors.MOVE)
- self._last_cursor = tools.Cursors.MOVE
- elif self._last_cursor != tools.Cursors.POINTER:
- self.canvas.set_cursor(tools.Cursors.POINTER)
- self._last_cursor = tools.Cursors.POINTER
-
- @contextmanager
- def _wait_cursor_for_draw_cm(self):
- """
- Set the cursor to a wait cursor when drawing the canvas.
-
- In order to avoid constantly changing the cursor when the canvas
- changes frequently, do nothing if this context was triggered during the
- last second. (Optimally we'd prefer only setting the wait cursor if
- the *current* draw takes too long, but the current draw blocks the GUI
- thread).
- """
- self._draw_time, last_draw_time = (
- time.time(), getattr(self, "_draw_time", -np.inf))
- if self._draw_time - last_draw_time > 1:
- try:
- self.canvas.set_cursor(tools.Cursors.WAIT)
- yield
- finally:
- self.canvas.set_cursor(self._last_cursor)
- else:
- yield
-
- @staticmethod
- def _mouse_event_to_message(event):
- if event.inaxes and event.inaxes.get_navigate():
- try:
- s = event.inaxes.format_coord(event.xdata, event.ydata)
- except (ValueError, OverflowError):
- pass
- else:
- s = s.rstrip()
- artists = [a for a in event.inaxes._mouseover_set
- if a.contains(event)[0] and a.get_visible()]
- if artists:
- a = cbook._topmost_artist(artists)
- if a is not event.inaxes.patch:
- data = a.get_cursor_data(event)
- if data is not None:
- data_str = a.format_cursor_data(data).rstrip()
- if data_str:
- s = s + '\n' + data_str
- return s
- return ""
-
- def mouse_move(self, event):
- self._update_cursor(event)
- self.set_message(self._mouse_event_to_message(event))
-
- def _zoom_pan_handler(self, event):
- if self.mode == _Mode.PAN:
- if event.name == "button_press_event":
- self.press_pan(event)
- elif event.name == "button_release_event":
- self.release_pan(event)
- if self.mode == _Mode.ZOOM:
- if event.name == "button_press_event":
- self.press_zoom(event)
- elif event.name == "button_release_event":
- self.release_zoom(event)
-
- def pan(self, *args):
- """
- Toggle the pan/zoom tool.
-
- Pan with left button, zoom with right.
- """
- if not self.canvas.widgetlock.available(self):
- self.set_message("pan unavailable")
- return
- if self.mode == _Mode.PAN:
- self.mode = _Mode.NONE
- self.canvas.widgetlock.release(self)
- else:
- self.mode = _Mode.PAN
- self.canvas.widgetlock(self)
- for a in self.canvas.figure.get_axes():
- a.set_navigate_mode(self.mode._navigate_mode)
-
- _PanInfo = namedtuple("_PanInfo", "button axes cid")
-
- def press_pan(self, event):
- """Callback for mouse button press in pan/zoom mode."""
- if (event.button not in [MouseButton.LEFT, MouseButton.RIGHT]
- or event.x is None or event.y is None):
- return
- axes = [a for a in self.canvas.figure.get_axes()
- if a.in_axes(event) and a.get_navigate() and a.can_pan()]
- if not axes:
- return
- if self._nav_stack() is None:
- self.push_current() # set the home button to this view
- for ax in axes:
- ax.start_pan(event.x, event.y, event.button)
- self.canvas.mpl_disconnect(self._id_drag)
- id_drag = self.canvas.mpl_connect("motion_notify_event", self.drag_pan)
- self._pan_info = self._PanInfo(
- button=event.button, axes=axes, cid=id_drag)
-
- def drag_pan(self, event):
- """Callback for dragging in pan/zoom mode."""
- for ax in self._pan_info.axes:
- # Using the recorded button at the press is safer than the current
- # button, as multiple buttons can get pressed during motion.
- ax.drag_pan(self._pan_info.button, event.key, event.x, event.y)
- self.canvas.draw_idle()
-
- def release_pan(self, event):
- """Callback for mouse button release in pan/zoom mode."""
- if self._pan_info is None:
- return
- self.canvas.mpl_disconnect(self._pan_info.cid)
- self._id_drag = self.canvas.mpl_connect(
- 'motion_notify_event', self.mouse_move)
- for ax in self._pan_info.axes:
- ax.end_pan()
- self.canvas.draw_idle()
- self._pan_info = None
- self.push_current()
-
- def zoom(self, *args):
- if not self.canvas.widgetlock.available(self):
- self.set_message("zoom unavailable")
- return
- """Toggle zoom to rect mode."""
- if self.mode == _Mode.ZOOM:
- self.mode = _Mode.NONE
- self.canvas.widgetlock.release(self)
- else:
- self.mode = _Mode.ZOOM
- self.canvas.widgetlock(self)
- for a in self.canvas.figure.get_axes():
- a.set_navigate_mode(self.mode._navigate_mode)
-
- _ZoomInfo = namedtuple("_ZoomInfo", "direction start_xy axes cid cbar")
-
- def press_zoom(self, event):
- """Callback for mouse button press in zoom to rect mode."""
- if (event.button not in [MouseButton.LEFT, MouseButton.RIGHT]
- or event.x is None or event.y is None):
- return
- axes = [a for a in self.canvas.figure.get_axes()
- if a.in_axes(event) and a.get_navigate() and a.can_zoom()]
- if not axes:
- return
- if self._nav_stack() is None:
- self.push_current() # set the home button to this view
- id_zoom = self.canvas.mpl_connect(
- "motion_notify_event", self.drag_zoom)
- # A colorbar is one-dimensional, so we extend the zoom rectangle out
- # to the edge of the Axes bbox in the other dimension. To do that we
- # store the orientation of the colorbar for later.
- if hasattr(axes[0], "_colorbar"):
- cbar = axes[0]._colorbar.orientation
- else:
- cbar = None
- self._zoom_info = self._ZoomInfo(
- direction="in" if event.button == 1 else "out",
- start_xy=(event.x, event.y), axes=axes, cid=id_zoom, cbar=cbar)
-
- def drag_zoom(self, event):
- """Callback for dragging in zoom mode."""
- start_xy = self._zoom_info.start_xy
- ax = self._zoom_info.axes[0]
- (x1, y1), (x2, y2) = np.clip(
- [start_xy, [event.x, event.y]], ax.bbox.min, ax.bbox.max)
- key = event.key
- # Force the key on colorbars to extend the short-axis bbox
- if self._zoom_info.cbar == "horizontal":
- key = "x"
- elif self._zoom_info.cbar == "vertical":
- key = "y"
- if key == "x":
- y1, y2 = ax.bbox.intervaly
- elif key == "y":
- x1, x2 = ax.bbox.intervalx
-
- self.draw_rubberband(event, x1, y1, x2, y2)
-
- def release_zoom(self, event):
- """Callback for mouse button release in zoom to rect mode."""
- if self._zoom_info is None:
- return
-
- # We don't check the event button here, so that zooms can be cancelled
- # by (pressing and) releasing another mouse button.
- self.canvas.mpl_disconnect(self._zoom_info.cid)
- self.remove_rubberband()
-
- start_x, start_y = self._zoom_info.start_xy
- key = event.key
- # Force the key on colorbars to ignore the zoom-cancel on the
- # short-axis side
- if self._zoom_info.cbar == "horizontal":
- key = "x"
- elif self._zoom_info.cbar == "vertical":
- key = "y"
- # Ignore single clicks: 5 pixels is a threshold that allows the user to
- # "cancel" a zoom action by zooming by less than 5 pixels.
- if ((abs(event.x - start_x) < 5 and key != "y") or
- (abs(event.y - start_y) < 5 and key != "x")):
- self.canvas.draw_idle()
- self._zoom_info = None
- return
-
- for i, ax in enumerate(self._zoom_info.axes):
- # Detect whether this Axes is twinned with an earlier Axes in the
- # list of zoomed Axes, to avoid double zooming.
- twinx = any(ax.get_shared_x_axes().joined(ax, prev)
- for prev in self._zoom_info.axes[:i])
- twiny = any(ax.get_shared_y_axes().joined(ax, prev)
- for prev in self._zoom_info.axes[:i])
- ax._set_view_from_bbox(
- (start_x, start_y, event.x, event.y),
- self._zoom_info.direction, key, twinx, twiny)
-
- self.canvas.draw_idle()
- self._zoom_info = None
- self.push_current()
-
- def push_current(self):
- """Push the current view limits and position onto the stack."""
- self._nav_stack.push(
- WeakKeyDictionary(
- {ax: (ax._get_view(),
- # Store both the original and modified positions.
- (ax.get_position(True).frozen(),
- ax.get_position().frozen()))
- for ax in self.canvas.figure.axes}))
- self.set_history_buttons()
-
- def _update_view(self):
- """
- Update the viewlim and position from the view and position stack for
- each Axes.
- """
- nav_info = self._nav_stack()
- if nav_info is None:
- return
- # Retrieve all items at once to avoid any risk of GC deleting an Axes
- # while in the middle of the loop below.
- items = list(nav_info.items())
- for ax, (view, (pos_orig, pos_active)) in items:
- ax._set_view(view)
- # Restore both the original and modified positions
- ax._set_position(pos_orig, 'original')
- ax._set_position(pos_active, 'active')
- self.canvas.draw_idle()
-
- def configure_subplots(self, *args):
- if hasattr(self, "subplot_tool"):
- self.subplot_tool.figure.canvas.manager.show()
- return
- # This import needs to happen here due to circular imports.
- from matplotlib.figure import Figure
- with mpl.rc_context({"toolbar": "none"}): # No navbar for the toolfig.
- manager = type(self.canvas).new_manager(Figure(figsize=(6, 3)), -1)
- manager.set_window_title("Subplot configuration tool")
- tool_fig = manager.canvas.figure
- tool_fig.subplots_adjust(top=0.9)
- self.subplot_tool = widgets.SubplotTool(self.canvas.figure, tool_fig)
- cid = self.canvas.mpl_connect(
- "close_event", lambda e: manager.destroy())
-
- def on_tool_fig_close(e):
- self.canvas.mpl_disconnect(cid)
- del self.subplot_tool
-
- tool_fig.canvas.mpl_connect("close_event", on_tool_fig_close)
- manager.show()
- return self.subplot_tool
-
- def save_figure(self, *args):
- """Save the current figure."""
- raise NotImplementedError
-
- def update(self):
- """Reset the Axes stack."""
- self._nav_stack.clear()
- self.set_history_buttons()
-
- def set_history_buttons(self):
- """Enable or disable the back/forward button."""
-
-
-class ToolContainerBase:
- """
- Base class for all tool containers, e.g. toolbars.
-
- Attributes
- ----------
- toolmanager : `.ToolManager`
- The tools with which this `ToolContainer` wants to communicate.
- """
-
- _icon_extension = '.png'
- """
- Toolcontainer button icon image format extension
-
- **String**: Image extension
- """
-
- def __init__(self, toolmanager):
- self.toolmanager = toolmanager
- toolmanager.toolmanager_connect(
- 'tool_message_event',
- lambda event: self.set_message(event.message))
- toolmanager.toolmanager_connect(
- 'tool_removed_event',
- lambda event: self.remove_toolitem(event.tool.name))
-
- def _tool_toggled_cbk(self, event):
- """
- Capture the 'tool_trigger_[name]'
-
- This only gets used for toggled tools.
- """
- self.toggle_toolitem(event.tool.name, event.tool.toggled)
-
- def add_tool(self, tool, group, position=-1):
- """
- Add a tool to this container.
-
- Parameters
- ----------
- tool : tool_like
- The tool to add, see `.ToolManager.get_tool`.
- group : str
- The name of the group to add this tool to.
- position : int, default: -1
- The position within the group to place this tool.
- """
- tool = self.toolmanager.get_tool(tool)
- image = self._get_image_filename(tool.image)
- toggle = getattr(tool, 'toggled', None) is not None
- self.add_toolitem(tool.name, group, position,
- image, tool.description, toggle)
- if toggle:
- self.toolmanager.toolmanager_connect('tool_trigger_%s' % tool.name,
- self._tool_toggled_cbk)
- # If initially toggled
- if tool.toggled:
- self.toggle_toolitem(tool.name, True)
-
- def _get_image_filename(self, image):
- """Find the image based on its name."""
- if not image:
- return None
-
- basedir = cbook._get_data_path("images")
- for fname in [
- image,
- image + self._icon_extension,
- str(basedir / image),
- str(basedir / (image + self._icon_extension)),
- ]:
- if os.path.isfile(fname):
- return fname
-
- def trigger_tool(self, name):
- """
- Trigger the tool.
-
- Parameters
- ----------
- name : str
- Name (id) of the tool triggered from within the container.
- """
- self.toolmanager.trigger_tool(name, sender=self)
-
- def add_toolitem(self, name, group, position, image, description, toggle):
- """
- Add a toolitem to the container.
-
- This method must be implemented per backend.
-
- The callback associated with the button click event,
- must be *exactly* ``self.trigger_tool(name)``.
-
- Parameters
- ----------
- name : str
- Name of the tool to add, this gets used as the tool's ID and as the
- default label of the buttons.
- group : str
- Name of the group that this tool belongs to.
- position : int
- Position of the tool within its group, if -1 it goes at the end.
- image : str
- Filename of the image for the button or `None`.
- description : str
- Description of the tool, used for the tooltips.
- toggle : bool
- * `True` : The button is a toggle (change the pressed/unpressed
- state between consecutive clicks).
- * `False` : The button is a normal button (returns to unpressed
- state after release).
- """
- raise NotImplementedError
-
- def toggle_toolitem(self, name, toggled):
- """
- Toggle the toolitem without firing event.
-
- Parameters
- ----------
- name : str
- Id of the tool to toggle.
- toggled : bool
- Whether to set this tool as toggled or not.
- """
- raise NotImplementedError
-
- def remove_toolitem(self, name):
- """
- Remove a toolitem from the `ToolContainer`.
-
- This method must get implemented per backend.
-
- Called when `.ToolManager` emits a `tool_removed_event`.
-
- Parameters
- ----------
- name : str
- Name of the tool to remove.
- """
- raise NotImplementedError
-
- def set_message(self, s):
- """
- Display a message on the toolbar.
-
- Parameters
- ----------
- s : str
- Message text.
- """
- raise NotImplementedError
-
-
-class _Backend:
- # A backend can be defined by using the following pattern:
- #
- # @_Backend.export
- # class FooBackend(_Backend):
- # # override the attributes and methods documented below.
-
- # `backend_version` may be overridden by the subclass.
- backend_version = "unknown"
-
- # The `FigureCanvas` class must be defined.
- FigureCanvas = None
-
- # For interactive backends, the `FigureManager` class must be overridden.
- FigureManager = FigureManagerBase
-
- # For interactive backends, `mainloop` should be a function taking no
- # argument and starting the backend main loop. It should be left as None
- # for non-interactive backends.
- mainloop = None
-
- # The following methods will be automatically defined and exported, but
- # can be overridden.
-
- @classmethod
- def new_figure_manager(cls, num, *args, **kwargs):
- """Create a new figure manager instance."""
- # This import needs to happen here due to circular imports.
- from matplotlib.figure import Figure
- fig_cls = kwargs.pop('FigureClass', Figure)
- fig = fig_cls(*args, **kwargs)
- return cls.new_figure_manager_given_figure(num, fig)
-
- @classmethod
- def new_figure_manager_given_figure(cls, num, figure):
- """Create a new figure manager instance for the given figure."""
- return cls.FigureCanvas.new_manager(figure, num)
-
- @classmethod
- def draw_if_interactive(cls):
- manager_class = cls.FigureCanvas.manager_class
- # Interactive backends reimplement start_main_loop or pyplot_show.
- backend_is_interactive = (
- manager_class.start_main_loop != FigureManagerBase.start_main_loop
- or manager_class.pyplot_show != FigureManagerBase.pyplot_show)
- if backend_is_interactive and is_interactive():
- manager = Gcf.get_active()
- if manager:
- manager.canvas.draw_idle()
-
- @classmethod
- def show(cls, *, block=None):
- """
- Show all figures.
-
- `show` blocks by calling `mainloop` if *block* is ``True``, or if it
- is ``None`` and we are neither in IPython's ``%pylab`` mode, nor in
- `interactive` mode.
- """
- managers = Gcf.get_all_fig_managers()
- if not managers:
- return
- for manager in managers:
- try:
- manager.show() # Emits a warning for non-interactive backend.
- except NonGuiException as exc:
- _api.warn_external(str(exc))
- if cls.mainloop is None:
- return
- if block is None:
- # Hack: Are we in IPython's %pylab mode? In pylab mode, IPython
- # (>= 0.10) tacks a _needmain attribute onto pyplot.show (always
- # set to False).
- pyplot_show = getattr(sys.modules.get("matplotlib.pyplot"), "show", None)
- ipython_pylab = hasattr(pyplot_show, "_needmain")
- block = not ipython_pylab and not is_interactive()
- if block:
- cls.mainloop()
-
- # This method is the one actually exporting the required methods.
-
- @staticmethod
- def export(cls):
- for name in [
- "backend_version",
- "FigureCanvas",
- "FigureManager",
- "new_figure_manager",
- "new_figure_manager_given_figure",
- "draw_if_interactive",
- "show",
- ]:
- setattr(sys.modules[cls.__module__], name, getattr(cls, name))
-
- # For back-compatibility, generate a shim `Show` class.
-
- class Show(ShowBase):
- def mainloop(self):
- return cls.mainloop()
-
- setattr(sys.modules[cls.__module__], "Show", Show)
- return cls
-
-
-class ShowBase(_Backend):
- """
- Simple base class to generate a ``show()`` function in backends.
-
- Subclass must override ``mainloop()`` method.
- """
-
- def __call__(self, block=None):
- return self.show(block=block)
diff --git a/contrib/python/matplotlib/py3/matplotlib/backend_bases.pyi b/contrib/python/matplotlib/py3/matplotlib/backend_bases.pyi
deleted file mode 100644
index 0ae88cf18a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backend_bases.pyi
+++ /dev/null
@@ -1,490 +0,0 @@
-from enum import Enum, IntEnum
-import os
-from matplotlib import (
- cbook,
- transforms,
- widgets,
- _api,
-)
-from matplotlib.artist import Artist
-from matplotlib.axes import Axes
-from matplotlib.backend_managers import ToolManager
-from matplotlib.backend_tools import Cursors, ToolBase
-from matplotlib.colorbar import Colorbar
-from matplotlib.figure import Figure
-from matplotlib.font_manager import FontProperties
-from matplotlib.path import Path
-from matplotlib.texmanager import TexManager
-from matplotlib.text import Text
-from matplotlib.transforms import Bbox, BboxBase, Transform, TransformedPath
-
-from collections.abc import Callable, Iterable, Sequence
-from typing import Any, IO, Literal, NamedTuple, TypeVar
-from numpy.typing import ArrayLike
-from .typing import ColorType, LineStyleType, CapStyleType, JoinStyleType
-
-def register_backend(
- format: str, backend: str | type[FigureCanvasBase], description: str | None = ...
-) -> None: ...
-def get_registered_canvas_class(format: str) -> type[FigureCanvasBase]: ...
-
-class RendererBase:
- def __init__(self) -> None: ...
- def open_group(self, s: str, gid: str | None = ...) -> None: ...
- def close_group(self, s: str) -> None: ...
- def draw_path(
- self,
- gc: GraphicsContextBase,
- path: Path,
- transform: Transform,
- rgbFace: ColorType | None = ...,
- ) -> None: ...
- def draw_markers(
- self,
- gc: GraphicsContextBase,
- marker_path: Path,
- marker_trans: Transform,
- path: Path,
- trans: Transform,
- rgbFace: ColorType | None = ...,
- ) -> None: ...
- def draw_path_collection(
- self,
- gc: GraphicsContextBase,
- master_transform: Transform,
- paths: Sequence[Path],
- all_transforms: Sequence[ArrayLike],
- offsets: ArrayLike | Sequence[ArrayLike],
- offset_trans: Transform,
- facecolors: ColorType | Sequence[ColorType],
- edgecolors: ColorType | Sequence[ColorType],
- linewidths: float | Sequence[float],
- linestyles: LineStyleType | Sequence[LineStyleType],
- antialiaseds: bool | Sequence[bool],
- urls: str | Sequence[str],
- offset_position: Any,
- ) -> None: ...
- def draw_quad_mesh(
- self,
- gc: GraphicsContextBase,
- master_transform: Transform,
- meshWidth,
- meshHeight,
- coordinates: ArrayLike,
- offsets: ArrayLike | Sequence[ArrayLike],
- offsetTrans: Transform,
- facecolors: Sequence[ColorType],
- antialiased: bool,
- edgecolors: Sequence[ColorType] | ColorType | None,
- ) -> None: ...
- def draw_gouraud_triangle(
- self,
- gc: GraphicsContextBase,
- points: ArrayLike,
- colors: ArrayLike,
- transform: Transform,
- ) -> None: ...
- def draw_gouraud_triangles(
- self,
- gc: GraphicsContextBase,
- triangles_array: ArrayLike,
- colors_array: ArrayLike,
- transform: Transform,
- ) -> None: ...
- def get_image_magnification(self) -> float: ...
- def draw_image(
- self,
- gc: GraphicsContextBase,
- x: float,
- y: float,
- im: ArrayLike,
- transform: transforms.Affine2DBase | None = ...,
- ) -> None: ...
- def option_image_nocomposite(self) -> bool: ...
- def option_scale_image(self) -> bool: ...
- def draw_tex(
- self,
- gc: GraphicsContextBase,
- x: float,
- y: float,
- s: str,
- prop: FontProperties,
- angle: float,
- *,
- mtext: Text | None = ...
- ) -> None: ...
- def draw_text(
- self,
- gc: GraphicsContextBase,
- x: float,
- y: float,
- s: str,
- prop: FontProperties,
- angle: float,
- ismath: bool | Literal["TeX"] = ...,
- mtext: Text | None = ...,
- ) -> None: ...
- def get_text_width_height_descent(
- self, s: str, prop: FontProperties, ismath: bool | Literal["TeX"]
- ) -> tuple[float, float, float]: ...
- def flipy(self) -> bool: ...
- def get_canvas_width_height(self) -> tuple[float, float]: ...
- def get_texmanager(self) -> TexManager: ...
- def new_gc(self) -> GraphicsContextBase: ...
- def points_to_pixels(self, points: ArrayLike) -> ArrayLike: ...
- def start_rasterizing(self) -> None: ...
- def stop_rasterizing(self) -> None: ...
- def start_filter(self) -> None: ...
- def stop_filter(self, filter_func) -> None: ...
-
-class GraphicsContextBase:
- def __init__(self) -> None: ...
- def copy_properties(self, gc: GraphicsContextBase) -> None: ...
- def restore(self) -> None: ...
- def get_alpha(self) -> float: ...
- def get_antialiased(self) -> int: ...
- def get_capstyle(self) -> Literal["butt", "projecting", "round"]: ...
- def get_clip_rectangle(self) -> Bbox | None: ...
- def get_clip_path(
- self,
- ) -> tuple[TransformedPath, Transform] | tuple[None, None]: ...
- def get_dashes(self) -> tuple[float, ArrayLike | None]: ...
- def get_forced_alpha(self) -> bool: ...
- def get_joinstyle(self) -> Literal["miter", "round", "bevel"]: ...
- def get_linewidth(self) -> float: ...
- def get_rgb(self) -> tuple[float, float, float, float]: ...
- def get_url(self) -> str | None: ...
- def get_gid(self) -> int | None: ...
- def get_snap(self) -> bool | None: ...
- def set_alpha(self, alpha: float) -> None: ...
- def set_antialiased(self, b: bool) -> None: ...
- def set_capstyle(self, cs: CapStyleType) -> None: ...
- def set_clip_rectangle(self, rectangle: Bbox | None) -> None: ...
- def set_clip_path(self, path: TransformedPath | None) -> None: ...
- def set_dashes(self, dash_offset: float, dash_list: ArrayLike | None) -> None: ...
- def set_foreground(self, fg: ColorType, isRGBA: bool = ...) -> None: ...
- def set_joinstyle(self, js: JoinStyleType) -> None: ...
- def set_linewidth(self, w: float) -> None: ...
- def set_url(self, url: str | None) -> None: ...
- def set_gid(self, id: int | None) -> None: ...
- def set_snap(self, snap: bool | None) -> None: ...
- def set_hatch(self, hatch: str | None) -> None: ...
- def get_hatch(self) -> str | None: ...
- def get_hatch_path(self, density: float = ...) -> Path: ...
- def get_hatch_color(self) -> ColorType: ...
- def set_hatch_color(self, hatch_color: ColorType) -> None: ...
- def get_hatch_linewidth(self) -> float: ...
- def get_sketch_params(self) -> tuple[float, float, float] | None: ...
- def set_sketch_params(
- self,
- scale: float | None = ...,
- length: float | None = ...,
- randomness: float | None = ...,
- ) -> None: ...
-
-class TimerBase:
- callbacks: list[tuple[Callable, tuple, dict[str, Any]]]
- def __init__(
- self,
- interval: int | None = ...,
- callbacks: list[tuple[Callable, tuple, dict[str, Any]]] | None = ...,
- ) -> None: ...
- def __del__(self) -> None: ...
- def start(self, interval: int | None = ...) -> None: ...
- def stop(self) -> None: ...
- @property
- def interval(self) -> int: ...
- @interval.setter
- def interval(self, interval: int) -> None: ...
- @property
- def single_shot(self) -> bool: ...
- @single_shot.setter
- def single_shot(self, ss: bool) -> None: ...
- def add_callback(self, func: Callable, *args, **kwargs) -> Callable: ...
- def remove_callback(self, func: Callable, *args, **kwargs) -> None: ...
-
-class Event:
- name: str
- canvas: FigureCanvasBase
- def __init__(
- self, name: str, canvas: FigureCanvasBase, guiEvent: Any | None = ...
- ) -> None: ...
-
- @property
- def guiEvent(self) -> Any: ...
-
-class DrawEvent(Event):
- renderer: RendererBase
- def __init__(
- self, name: str, canvas: FigureCanvasBase, renderer: RendererBase
- ) -> None: ...
-
-class ResizeEvent(Event):
- width: int
- height: int
- def __init__(self, name: str, canvas: FigureCanvasBase) -> None: ...
-
-class CloseEvent(Event): ...
-
-class LocationEvent(Event):
- lastevent: Event | None
- x: int
- y: int
- inaxes: Axes | None
- xdata: float | None
- ydata: float | None
- def __init__(
- self,
- name: str,
- canvas: FigureCanvasBase,
- x: int,
- y: int,
- guiEvent: Any | None = ...,
- *,
- modifiers: Iterable[str] | None = ...,
- ) -> None: ...
-
-class MouseButton(IntEnum):
- LEFT: int
- MIDDLE: int
- RIGHT: int
- BACK: int
- FORWARD: int
-
-class MouseEvent(LocationEvent):
- button: MouseButton | Literal["up", "down"] | None
- key: str | None
- step: float
- dblclick: bool
- def __init__(
- self,
- name: str,
- canvas: FigureCanvasBase,
- x: int,
- y: int,
- button: MouseButton | Literal["up", "down"] | None = ...,
- key: str | None = ...,
- step: float = ...,
- dblclick: bool = ...,
- guiEvent: Any | None = ...,
- *,
- modifiers: Iterable[str] | None = ...,
- ) -> None: ...
-
-class PickEvent(Event):
- mouseevent: MouseEvent
- artist: Artist
- def __init__(
- self,
- name: str,
- canvas: FigureCanvasBase,
- mouseevent: MouseEvent,
- artist: Artist,
- guiEvent: Any | None = ...,
- **kwargs
- ) -> None: ...
-
-class KeyEvent(LocationEvent):
- key: str | None
- def __init__(
- self,
- name: str,
- canvas: FigureCanvasBase,
- key: str | None,
- x: int = ...,
- y: int = ...,
- guiEvent: Any | None = ...,
- ) -> None: ...
-
-class FigureCanvasBase:
- required_interactive_framework: str | None
-
- @_api.classproperty
- def manager_class(cls) -> type[FigureManagerBase]: ...
- events: list[str]
- fixed_dpi: None | float
- filetypes: dict[str, str]
-
- @_api.classproperty
- def supports_blit(cls) -> bool: ...
-
- figure: Figure
- manager: None | FigureManagerBase
- widgetlock: widgets.LockDraw
- mouse_grabber: None | Axes
- toolbar: None | NavigationToolbar2
- def __init__(self, figure: Figure | None = ...) -> None: ...
- @property
- def callbacks(self) -> cbook.CallbackRegistry: ...
- @property
- def button_pick_id(self) -> int: ...
- @property
- def scroll_pick_id(self) -> int: ...
- @classmethod
- def new_manager(cls, figure: Figure, num: int | str) -> FigureManagerBase: ...
- def is_saving(self) -> bool: ...
- def blit(self, bbox: BboxBase | None = ...) -> None: ...
- def inaxes(self, xy: tuple[float, float]) -> Axes | None: ...
- def grab_mouse(self, ax: Axes) -> None: ...
- def release_mouse(self, ax: Axes) -> None: ...
- def set_cursor(self, cursor: Cursors) -> None: ...
- def draw(self, *args, **kwargs) -> None: ...
- def draw_idle(self, *args, **kwargs) -> None: ...
- @property
- def device_pixel_ratio(self) -> float: ...
- def get_width_height(self, *, physical: bool = ...) -> tuple[int, int]: ...
- @classmethod
- def get_supported_filetypes(cls) -> dict[str, str]: ...
- @classmethod
- def get_supported_filetypes_grouped(cls) -> dict[str, list[str]]: ...
- def print_figure(
- self,
- filename: str | os.PathLike | IO,
- dpi: float | None = ...,
- facecolor: ColorType | Literal["auto"] | None = ...,
- edgecolor: ColorType | Literal["auto"] | None = ...,
- orientation: str = ...,
- format: str | None = ...,
- *,
- bbox_inches: Literal["tight"] | Bbox | None = ...,
- pad_inches: float | None = ...,
- bbox_extra_artists: list[Artist] | None = ...,
- backend: str | None = ...,
- **kwargs
- ) -> Any: ...
- @classmethod
- def get_default_filetype(cls) -> str: ...
- def get_default_filename(self) -> str: ...
- _T = TypeVar("_T", bound=FigureCanvasBase)
- def switch_backends(self, FigureCanvasClass: type[_T]) -> _T: ...
- def mpl_connect(self, s: str, func: Callable[[Event], Any]) -> int: ...
- def mpl_disconnect(self, cid: int) -> None: ...
- def new_timer(
- self,
- interval: int | None = ...,
- callbacks: list[tuple[Callable, tuple, dict[str, Any]]] | None = ...,
- ) -> TimerBase: ...
- def flush_events(self) -> None: ...
- def start_event_loop(self, timeout: float = ...) -> None: ...
- def stop_event_loop(self) -> None: ...
-
-def key_press_handler(
- event: KeyEvent,
- canvas: FigureCanvasBase | None = ...,
- toolbar: NavigationToolbar2 | None = ...,
-) -> None: ...
-def button_press_handler(
- event: MouseEvent,
- canvas: FigureCanvasBase | None = ...,
- toolbar: NavigationToolbar2 | None = ...,
-) -> None: ...
-
-class NonGuiException(Exception): ...
-
-class FigureManagerBase:
- canvas: FigureCanvasBase
- num: int | str
- key_press_handler_id: int | None
- button_press_handler_id: int | None
- toolmanager: ToolManager | None
- toolbar: NavigationToolbar2 | ToolContainerBase | None
- def __init__(self, canvas: FigureCanvasBase, num: int | str) -> None: ...
- @classmethod
- def create_with_canvas(
- cls, canvas_class: type[FigureCanvasBase], figure: Figure, num: int | str
- ) -> FigureManagerBase: ...
- @classmethod
- def start_main_loop(cls) -> None: ...
- @classmethod
- def pyplot_show(cls, *, block: bool | None = ...) -> None: ...
- def show(self) -> None: ...
- def destroy(self) -> None: ...
- def full_screen_toggle(self) -> None: ...
- def resize(self, w: int, h: int) -> None: ...
- def get_window_title(self) -> str: ...
- def set_window_title(self, title: str) -> None: ...
-
-cursors = Cursors
-
-class _Mode(str, Enum):
- NONE: str
- PAN: str
- ZOOM: str
-
-class NavigationToolbar2:
- toolitems: tuple[tuple[str, ...] | tuple[None, ...], ...]
- canvas: FigureCanvasBase
- mode: _Mode
- def __init__(self, canvas: FigureCanvasBase) -> None: ...
- def set_message(self, s: str) -> None: ...
- def draw_rubberband(
- self, event: Event, x0: float, y0: float, x1: float, y1: float
- ) -> None: ...
- def remove_rubberband(self) -> None: ...
- def home(self, *args) -> None: ...
- def back(self, *args) -> None: ...
- def forward(self, *args) -> None: ...
- def mouse_move(self, event: MouseEvent) -> None: ...
- def pan(self, *args) -> None: ...
-
- class _PanInfo(NamedTuple):
- button: MouseButton
- axes: list[Axes]
- cid: int
- def press_pan(self, event: Event) -> None: ...
- def drag_pan(self, event: Event) -> None: ...
- def release_pan(self, event: Event) -> None: ...
- def zoom(self, *args) -> None: ...
-
- class _ZoomInfo(NamedTuple):
- direction: Literal["in", "out"]
- start_xy: tuple[float, float]
- axes: list[Axes]
- cid: int
- cbar: Colorbar
- def press_zoom(self, event: Event) -> None: ...
- def drag_zoom(self, event: Event) -> None: ...
- def release_zoom(self, event: Event) -> None: ...
- def push_current(self) -> None: ...
- subplot_tool: widgets.SubplotTool
- def configure_subplots(self, *args): ...
- def save_figure(self, *args) -> None: ...
- def update(self) -> None: ...
- def set_history_buttons(self) -> None: ...
-
-class ToolContainerBase:
- toolmanager: ToolManager
- def __init__(self, toolmanager: ToolManager) -> None: ...
- def add_tool(self, tool: ToolBase, group: str, position: int = ...) -> None: ...
- def trigger_tool(self, name: str) -> None: ...
- def add_toolitem(
- self,
- name: str,
- group: str,
- position: int,
- image: str,
- description: str,
- toggle: bool,
- ) -> None: ...
- def toggle_toolitem(self, name: str, toggled: bool) -> None: ...
- def remove_toolitem(self, name: str) -> None: ...
- def set_message(self, s: str) -> None: ...
-
-class _Backend:
- backend_version: str
- FigureCanvas: type[FigureCanvasBase] | None
- FigureManager: type[FigureManagerBase]
- mainloop: None | Callable[[], Any]
- @classmethod
- def new_figure_manager(cls, num: int | str, *args, **kwargs) -> FigureManagerBase: ...
- @classmethod
- def new_figure_manager_given_figure(cls, num: int | str, figure: Figure) -> FigureManagerBase: ...
- @classmethod
- def draw_if_interactive(cls) -> None: ...
- @classmethod
- def show(cls, *, block: bool | None = ...) -> None: ...
- @staticmethod
- def export(cls) -> type[_Backend]: ...
-
-class ShowBase(_Backend):
- def __call__(self, block: bool | None = ...) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/backend_managers.py b/contrib/python/matplotlib/py3/matplotlib/backend_managers.py
deleted file mode 100644
index 76f15030bc..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backend_managers.py
+++ /dev/null
@@ -1,387 +0,0 @@
-from matplotlib import _api, backend_tools, cbook, widgets
-
-
-class ToolEvent:
- """Event for tool manipulation (add/remove)."""
- def __init__(self, name, sender, tool, data=None):
- self.name = name
- self.sender = sender
- self.tool = tool
- self.data = data
-
-
-class ToolTriggerEvent(ToolEvent):
- """Event to inform that a tool has been triggered."""
- def __init__(self, name, sender, tool, canvasevent=None, data=None):
- super().__init__(name, sender, tool, data)
- self.canvasevent = canvasevent
-
-
-class ToolManagerMessageEvent:
- """
- Event carrying messages from toolmanager.
-
- Messages usually get displayed to the user by the toolbar.
- """
- def __init__(self, name, sender, message):
- self.name = name
- self.sender = sender
- self.message = message
-
-
-class ToolManager:
- """
- Manager for actions triggered by user interactions (key press, toolbar
- clicks, ...) on a Figure.
-
- Attributes
- ----------
- figure : `.Figure`
- keypresslock : `~matplotlib.widgets.LockDraw`
- `.LockDraw` object to know if the `canvas` key_press_event is locked.
- messagelock : `~matplotlib.widgets.LockDraw`
- `.LockDraw` object to know if the message is available to write.
- """
-
- def __init__(self, figure=None):
-
- self._key_press_handler_id = None
-
- self._tools = {}
- self._keys = {}
- self._toggled = {}
- self._callbacks = cbook.CallbackRegistry()
-
- # to process keypress event
- self.keypresslock = widgets.LockDraw()
- self.messagelock = widgets.LockDraw()
-
- self._figure = None
- self.set_figure(figure)
-
- @property
- def canvas(self):
- """Canvas managed by FigureManager."""
- if not self._figure:
- return None
- return self._figure.canvas
-
- @property
- def figure(self):
- """Figure that holds the canvas."""
- return self._figure
-
- @figure.setter
- def figure(self, figure):
- self.set_figure(figure)
-
- def set_figure(self, figure, update_tools=True):
- """
- Bind the given figure to the tools.
-
- Parameters
- ----------
- figure : `.Figure`
- update_tools : bool, default: True
- Force tools to update figure.
- """
- if self._key_press_handler_id:
- self.canvas.mpl_disconnect(self._key_press_handler_id)
- self._figure = figure
- if figure:
- self._key_press_handler_id = self.canvas.mpl_connect(
- 'key_press_event', self._key_press)
- if update_tools:
- for tool in self._tools.values():
- tool.figure = figure
-
- def toolmanager_connect(self, s, func):
- """
- Connect event with string *s* to *func*.
-
- Parameters
- ----------
- s : str
- The name of the event. The following events are recognized:
-
- - 'tool_message_event'
- - 'tool_removed_event'
- - 'tool_added_event'
-
- For every tool added a new event is created
-
- - 'tool_trigger_TOOLNAME', where TOOLNAME is the id of the tool.
-
- func : callable
- Callback function for the toolmanager event with signature::
-
- def func(event: ToolEvent) -> Any
-
- Returns
- -------
- cid
- The callback id for the connection. This can be used in
- `.toolmanager_disconnect`.
- """
- return self._callbacks.connect(s, func)
-
- def toolmanager_disconnect(self, cid):
- """
- Disconnect callback id *cid*.
-
- Example usage::
-
- cid = toolmanager.toolmanager_connect('tool_trigger_zoom', onpress)
- #...later
- toolmanager.toolmanager_disconnect(cid)
- """
- return self._callbacks.disconnect(cid)
-
- def message_event(self, message, sender=None):
- """Emit a `ToolManagerMessageEvent`."""
- if sender is None:
- sender = self
-
- s = 'tool_message_event'
- event = ToolManagerMessageEvent(s, sender, message)
- self._callbacks.process(s, event)
-
- @property
- def active_toggle(self):
- """Currently toggled tools."""
- return self._toggled
-
- def get_tool_keymap(self, name):
- """
- Return the keymap associated with the specified tool.
-
- Parameters
- ----------
- name : str
- Name of the Tool.
-
- Returns
- -------
- list of str
- List of keys associated with the tool.
- """
-
- keys = [k for k, i in self._keys.items() if i == name]
- return keys
-
- def _remove_keys(self, name):
- for k in self.get_tool_keymap(name):
- del self._keys[k]
-
- def update_keymap(self, name, key):
- """
- Set the keymap to associate with the specified tool.
-
- Parameters
- ----------
- name : str
- Name of the Tool.
- key : str or list of str
- Keys to associate with the tool.
- """
- if name not in self._tools:
- raise KeyError(f'{name!r} not in Tools')
- self._remove_keys(name)
- if isinstance(key, str):
- key = [key]
- for k in key:
- if k in self._keys:
- _api.warn_external(
- f'Key {k} changed from {self._keys[k]} to {name}')
- self._keys[k] = name
-
- def remove_tool(self, name):
- """
- Remove tool named *name*.
-
- Parameters
- ----------
- name : str
- Name of the tool.
- """
- tool = self.get_tool(name)
- if getattr(tool, 'toggled', False): # If it's a toggled toggle tool, untoggle
- self.trigger_tool(tool, 'toolmanager')
- self._remove_keys(name)
- event = ToolEvent('tool_removed_event', self, tool)
- self._callbacks.process(event.name, event)
- del self._tools[name]
-
- def add_tool(self, name, tool, *args, **kwargs):
- """
- Add *tool* to `ToolManager`.
-
- If successful, adds a new event ``tool_trigger_{name}`` where
- ``{name}`` is the *name* of the tool; the event is fired every time the
- tool is triggered.
-
- Parameters
- ----------
- name : str
- Name of the tool, treated as the ID, has to be unique.
- tool : type
- Class of the tool to be added. A subclass will be used
- instead if one was registered for the current canvas class.
- *args, **kwargs
- Passed to the *tool*'s constructor.
-
- See Also
- --------
- matplotlib.backend_tools.ToolBase : The base class for tools.
- """
-
- tool_cls = backend_tools._find_tool_class(type(self.canvas), tool)
- if not tool_cls:
- raise ValueError('Impossible to find class for %s' % str(tool))
-
- if name in self._tools:
- _api.warn_external('A "Tool class" with the same name already '
- 'exists, not added')
- return self._tools[name]
-
- tool_obj = tool_cls(self, name, *args, **kwargs)
- self._tools[name] = tool_obj
-
- if tool_obj.default_keymap is not None:
- self.update_keymap(name, tool_obj.default_keymap)
-
- # For toggle tools init the radio_group in self._toggled
- if isinstance(tool_obj, backend_tools.ToolToggleBase):
- # None group is not mutually exclusive, a set is used to keep track
- # of all toggled tools in this group
- if tool_obj.radio_group is None:
- self._toggled.setdefault(None, set())
- else:
- self._toggled.setdefault(tool_obj.radio_group, None)
-
- # If initially toggled
- if tool_obj.toggled:
- self._handle_toggle(tool_obj, None, None)
- tool_obj.set_figure(self.figure)
-
- event = ToolEvent('tool_added_event', self, tool_obj)
- self._callbacks.process(event.name, event)
-
- return tool_obj
-
- def _handle_toggle(self, tool, canvasevent, data):
- """
- Toggle tools, need to untoggle prior to using other Toggle tool.
- Called from trigger_tool.
-
- Parameters
- ----------
- tool : `.ToolBase`
- canvasevent : Event
- Original Canvas event or None.
- data : object
- Extra data to pass to the tool when triggering.
- """
-
- radio_group = tool.radio_group
- # radio_group None is not mutually exclusive
- # just keep track of toggled tools in this group
- if radio_group is None:
- if tool.name in self._toggled[None]:
- self._toggled[None].remove(tool.name)
- else:
- self._toggled[None].add(tool.name)
- return
-
- # If the tool already has a toggled state, untoggle it
- if self._toggled[radio_group] == tool.name:
- toggled = None
- # If no tool was toggled in the radio_group
- # toggle it
- elif self._toggled[radio_group] is None:
- toggled = tool.name
- # Other tool in the radio_group is toggled
- else:
- # Untoggle previously toggled tool
- self.trigger_tool(self._toggled[radio_group],
- self,
- canvasevent,
- data)
- toggled = tool.name
-
- # Keep track of the toggled tool in the radio_group
- self._toggled[radio_group] = toggled
-
- def trigger_tool(self, name, sender=None, canvasevent=None, data=None):
- """
- Trigger a tool and emit the ``tool_trigger_{name}`` event.
-
- Parameters
- ----------
- name : str
- Name of the tool.
- sender : object
- Object that wishes to trigger the tool.
- canvasevent : Event
- Original Canvas event or None.
- data : object
- Extra data to pass to the tool when triggering.
- """
- tool = self.get_tool(name)
- if tool is None:
- return
-
- if sender is None:
- sender = self
-
- if isinstance(tool, backend_tools.ToolToggleBase):
- self._handle_toggle(tool, canvasevent, data)
-
- tool.trigger(sender, canvasevent, data) # Actually trigger Tool.
-
- s = 'tool_trigger_%s' % name
- event = ToolTriggerEvent(s, sender, tool, canvasevent, data)
- self._callbacks.process(s, event)
-
- def _key_press(self, event):
- if event.key is None or self.keypresslock.locked():
- return
-
- name = self._keys.get(event.key, None)
- if name is None:
- return
- self.trigger_tool(name, canvasevent=event)
-
- @property
- def tools(self):
- """A dict mapping tool name -> controlled tool."""
- return self._tools
-
- def get_tool(self, name, warn=True):
- """
- Return the tool object with the given name.
-
- For convenience, this passes tool objects through.
-
- Parameters
- ----------
- name : str or `.ToolBase`
- Name of the tool, or the tool itself.
- warn : bool, default: True
- Whether a warning should be emitted it no tool with the given name
- exists.
-
- Returns
- -------
- `.ToolBase` or None
- The tool or None if no tool with the given name exists.
- """
- if (isinstance(name, backend_tools.ToolBase)
- and name.name in self._tools):
- return name
- if name not in self._tools:
- if warn:
- _api.warn_external(
- f"ToolManager does not control tool {name!r}")
- return None
- return self._tools[name]
diff --git a/contrib/python/matplotlib/py3/matplotlib/backend_managers.pyi b/contrib/python/matplotlib/py3/matplotlib/backend_managers.pyi
deleted file mode 100644
index 9e59acb14e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backend_managers.pyi
+++ /dev/null
@@ -1,64 +0,0 @@
-from matplotlib import backend_tools, widgets
-from matplotlib.backend_bases import FigureCanvasBase
-from matplotlib.figure import Figure
-
-from collections.abc import Callable, Iterable
-from typing import Any, TypeVar
-
-class ToolEvent:
- name: str
- sender: Any
- tool: backend_tools.ToolBase
- data: Any
- def __init__(self, name, sender, tool, data: Any | None = ...) -> None: ...
-
-class ToolTriggerEvent(ToolEvent):
- canvasevent: ToolEvent
- def __init__(
- self,
- name,
- sender,
- tool,
- canvasevent: ToolEvent | None = ...,
- data: Any | None = ...,
- ) -> None: ...
-
-class ToolManagerMessageEvent:
- name: str
- sender: Any
- message: str
- def __init__(self, name: str, sender: Any, message: str) -> None: ...
-
-class ToolManager:
- keypresslock: widgets.LockDraw
- messagelock: widgets.LockDraw
- def __init__(self, figure: Figure | None = ...) -> None: ...
- @property
- def canvas(self) -> FigureCanvasBase | None: ...
- @property
- def figure(self) -> Figure | None: ...
- @figure.setter
- def figure(self, figure: Figure) -> None: ...
- def set_figure(self, figure: Figure, update_tools: bool = ...) -> None: ...
- def toolmanager_connect(self, s: str, func: Callable[[ToolEvent], Any]) -> int: ...
- def toolmanager_disconnect(self, cid: int) -> None: ...
- def message_event(self, message: str, sender: Any | None = ...) -> None: ...
- @property
- def active_toggle(self) -> dict[str | None, list[str] | str]: ...
- def get_tool_keymap(self, name: str) -> list[str]: ...
- def update_keymap(self, name: str, key: str | Iterable[str]) -> None: ...
- def remove_tool(self, name: str) -> None: ...
- _T = TypeVar("_T", bound=backend_tools.ToolBase)
- def add_tool(self, name: str, tool: type[_T], *args, **kwargs) -> _T: ...
- def trigger_tool(
- self,
- name: str | backend_tools.ToolBase,
- sender: Any | None = ...,
- canvasevent: ToolEvent | None = ...,
- data: Any | None = ...,
- ) -> None: ...
- @property
- def tools(self) -> dict[str, backend_tools.ToolBase]: ...
- def get_tool(
- self, name: str | backend_tools.ToolBase, warn: bool = ...
- ) -> backend_tools.ToolBase | None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/backend_tools.py b/contrib/python/matplotlib/py3/matplotlib/backend_tools.py
deleted file mode 100644
index ac2a20f1ff..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backend_tools.py
+++ /dev/null
@@ -1,1003 +0,0 @@
-"""
-Abstract base classes define the primitives for Tools.
-These tools are used by `matplotlib.backend_managers.ToolManager`
-
-:class:`ToolBase`
- Simple stateless tool
-
-:class:`ToolToggleBase`
- Tool that has two states, only one Toggle tool can be
- active at any given time for the same
- `matplotlib.backend_managers.ToolManager`
-"""
-
-import enum
-import functools
-import re
-import time
-from types import SimpleNamespace
-import uuid
-from weakref import WeakKeyDictionary
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib._pylab_helpers import Gcf
-from matplotlib import _api, cbook
-
-
-class Cursors(enum.IntEnum): # Must subclass int for the macOS backend.
- """Backend-independent cursor types."""
- POINTER = enum.auto()
- HAND = enum.auto()
- SELECT_REGION = enum.auto()
- MOVE = enum.auto()
- WAIT = enum.auto()
- RESIZE_HORIZONTAL = enum.auto()
- RESIZE_VERTICAL = enum.auto()
-cursors = Cursors # Backcompat.
-
-
-# _tool_registry, _register_tool_class, and _find_tool_class implement a
-# mechanism through which ToolManager.add_tool can determine whether a subclass
-# of the requested tool class has been registered (either for the current
-# canvas class or for a parent class), in which case that tool subclass will be
-# instantiated instead. This is the mechanism used e.g. to allow different
-# GUI backends to implement different specializations for ConfigureSubplots.
-
-
-_tool_registry = set()
-
-
-def _register_tool_class(canvas_cls, tool_cls=None):
- """Decorator registering *tool_cls* as a tool class for *canvas_cls*."""
- if tool_cls is None:
- return functools.partial(_register_tool_class, canvas_cls)
- _tool_registry.add((canvas_cls, tool_cls))
- return tool_cls
-
-
-def _find_tool_class(canvas_cls, tool_cls):
- """Find a subclass of *tool_cls* registered for *canvas_cls*."""
- for canvas_parent in canvas_cls.__mro__:
- for tool_child in _api.recursive_subclasses(tool_cls):
- if (canvas_parent, tool_child) in _tool_registry:
- return tool_child
- return tool_cls
-
-
-# Views positions tool
-_views_positions = 'viewpos'
-
-
-class ToolBase:
- """
- Base tool class.
-
- A base tool, only implements `trigger` method or no method at all.
- The tool is instantiated by `matplotlib.backend_managers.ToolManager`.
- """
-
- default_keymap = None
- """
- Keymap to associate with this tool.
-
- ``list[str]``: List of keys that will trigger this tool when a keypress
- event is emitted on ``self.figure.canvas``. Note that this attribute is
- looked up on the instance, and can therefore be a property (this is used
- e.g. by the built-in tools to load the rcParams at instantiation time).
- """
-
- description = None
- """
- Description of the Tool.
-
- `str`: Tooltip used if the Tool is included in a Toolbar.
- """
-
- image = None
- """
- Filename of the image.
-
- `str`: Filename of the image to use in a Toolbar. If None, the *name* is
- used as a label in the toolbar button.
- """
-
- def __init__(self, toolmanager, name):
- self._name = name
- self._toolmanager = toolmanager
- self._figure = None
-
- name = property(
- lambda self: self._name,
- doc="The tool id (str, must be unique among tools of a tool manager).")
- toolmanager = property(
- lambda self: self._toolmanager,
- doc="The `.ToolManager` that controls this tool.")
- canvas = property(
- lambda self: self._figure.canvas if self._figure is not None else None,
- doc="The canvas of the figure affected by this tool, or None.")
-
- def set_figure(self, figure):
- self._figure = figure
-
- figure = property(
- lambda self: self._figure,
- # The setter must explicitly call self.set_figure so that subclasses can
- # meaningfully override it.
- lambda self, figure: self.set_figure(figure),
- doc="The Figure affected by this tool, or None.")
-
- def _make_classic_style_pseudo_toolbar(self):
- """
- Return a placeholder object with a single `canvas` attribute.
-
- This is useful to reuse the implementations of tools already provided
- by the classic Toolbars.
- """
- return SimpleNamespace(canvas=self.canvas)
-
- def trigger(self, sender, event, data=None):
- """
- Called when this tool gets used.
-
- This method is called by `.ToolManager.trigger_tool`.
-
- Parameters
- ----------
- event : `.Event`
- The canvas event that caused this tool to be called.
- sender : object
- Object that requested the tool to be triggered.
- data : object
- Extra data.
- """
- pass
-
-
-class ToolToggleBase(ToolBase):
- """
- Toggleable tool.
-
- Every time it is triggered, it switches between enable and disable.
-
- Parameters
- ----------
- ``*args``
- Variable length argument to be used by the Tool.
- ``**kwargs``
- `toggled` if present and True, sets the initial state of the Tool
- Arbitrary keyword arguments to be consumed by the Tool
- """
-
- radio_group = None
- """
- Attribute to group 'radio' like tools (mutually exclusive).
-
- `str` that identifies the group or **None** if not belonging to a group.
- """
-
- cursor = None
- """Cursor to use when the tool is active."""
-
- default_toggled = False
- """Default of toggled state."""
-
- def __init__(self, *args, **kwargs):
- self._toggled = kwargs.pop('toggled', self.default_toggled)
- super().__init__(*args, **kwargs)
-
- def trigger(self, sender, event, data=None):
- """Calls `enable` or `disable` based on `toggled` value."""
- if self._toggled:
- self.disable(event)
- else:
- self.enable(event)
- self._toggled = not self._toggled
-
- def enable(self, event=None):
- """
- Enable the toggle tool.
-
- `trigger` calls this method when `toggled` is False.
- """
- pass
-
- def disable(self, event=None):
- """
- Disable the toggle tool.
-
- `trigger` call this method when `toggled` is True.
-
- This can happen in different circumstances.
-
- * Click on the toolbar tool button.
- * Call to `matplotlib.backend_managers.ToolManager.trigger_tool`.
- * Another `ToolToggleBase` derived tool is triggered
- (from the same `.ToolManager`).
- """
- pass
-
- @property
- def toggled(self):
- """State of the toggled tool."""
- return self._toggled
-
- def set_figure(self, figure):
- toggled = self.toggled
- if toggled:
- if self.figure:
- self.trigger(self, None)
- else:
- # if no figure the internal state is not changed
- # we change it here so next call to trigger will change it back
- self._toggled = False
- super().set_figure(figure)
- if toggled:
- if figure:
- self.trigger(self, None)
- else:
- # if there is no figure, trigger won't change the internal
- # state we change it back
- self._toggled = True
-
-
-class ToolSetCursor(ToolBase):
- """
- Change to the current cursor while inaxes.
-
- This tool, keeps track of all `ToolToggleBase` derived tools, and updates
- the cursor when a tool gets triggered.
- """
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- self._id_drag = None
- self._current_tool = None
- self._default_cursor = cursors.POINTER
- self._last_cursor = self._default_cursor
- self.toolmanager.toolmanager_connect('tool_added_event',
- self._add_tool_cbk)
- # process current tools
- for tool in self.toolmanager.tools.values():
- self._add_tool(tool)
-
- def set_figure(self, figure):
- if self._id_drag:
- self.canvas.mpl_disconnect(self._id_drag)
- super().set_figure(figure)
- if figure:
- self._id_drag = self.canvas.mpl_connect(
- 'motion_notify_event', self._set_cursor_cbk)
-
- def _tool_trigger_cbk(self, event):
- if event.tool.toggled:
- self._current_tool = event.tool
- else:
- self._current_tool = None
- self._set_cursor_cbk(event.canvasevent)
-
- def _add_tool(self, tool):
- """Set the cursor when the tool is triggered."""
- if getattr(tool, 'cursor', None) is not None:
- self.toolmanager.toolmanager_connect('tool_trigger_%s' % tool.name,
- self._tool_trigger_cbk)
-
- def _add_tool_cbk(self, event):
- """Process every newly added tool."""
- if event.tool is self:
- return
- self._add_tool(event.tool)
-
- def _set_cursor_cbk(self, event):
- if not event or not self.canvas:
- return
- if (self._current_tool and getattr(event, "inaxes", None)
- and event.inaxes.get_navigate()):
- if self._last_cursor != self._current_tool.cursor:
- self.canvas.set_cursor(self._current_tool.cursor)
- self._last_cursor = self._current_tool.cursor
- elif self._last_cursor != self._default_cursor:
- self.canvas.set_cursor(self._default_cursor)
- self._last_cursor = self._default_cursor
-
-
-class ToolCursorPosition(ToolBase):
- """
- Send message with the current pointer position.
-
- This tool runs in the background reporting the position of the cursor.
- """
- def __init__(self, *args, **kwargs):
- self._id_drag = None
- super().__init__(*args, **kwargs)
-
- def set_figure(self, figure):
- if self._id_drag:
- self.canvas.mpl_disconnect(self._id_drag)
- super().set_figure(figure)
- if figure:
- self._id_drag = self.canvas.mpl_connect(
- 'motion_notify_event', self.send_message)
-
- def send_message(self, event):
- """Call `matplotlib.backend_managers.ToolManager.message_event`."""
- if self.toolmanager.messagelock.locked():
- return
-
- from matplotlib.backend_bases import NavigationToolbar2
- message = NavigationToolbar2._mouse_event_to_message(event)
- self.toolmanager.message_event(message, self)
-
-
-class RubberbandBase(ToolBase):
- """Draw and remove a rubberband."""
- def trigger(self, sender, event, data=None):
- """Call `draw_rubberband` or `remove_rubberband` based on data."""
- if not self.figure.canvas.widgetlock.available(sender):
- return
- if data is not None:
- self.draw_rubberband(*data)
- else:
- self.remove_rubberband()
-
- def draw_rubberband(self, *data):
- """
- Draw rubberband.
-
- This method must get implemented per backend.
- """
- raise NotImplementedError
-
- def remove_rubberband(self):
- """
- Remove rubberband.
-
- This method should get implemented per backend.
- """
- pass
-
-
-class ToolQuit(ToolBase):
- """Tool to call the figure manager destroy method."""
-
- description = 'Quit the figure'
- default_keymap = property(lambda self: mpl.rcParams['keymap.quit'])
-
- def trigger(self, sender, event, data=None):
- Gcf.destroy_fig(self.figure)
-
-
-class ToolQuitAll(ToolBase):
- """Tool to call the figure manager destroy method."""
-
- description = 'Quit all figures'
- default_keymap = property(lambda self: mpl.rcParams['keymap.quit_all'])
-
- def trigger(self, sender, event, data=None):
- Gcf.destroy_all()
-
-
-class ToolGrid(ToolBase):
- """Tool to toggle the major grids of the figure."""
-
- description = 'Toggle major grids'
- default_keymap = property(lambda self: mpl.rcParams['keymap.grid'])
-
- def trigger(self, sender, event, data=None):
- sentinel = str(uuid.uuid4())
- # Trigger grid switching by temporarily setting :rc:`keymap.grid`
- # to a unique key and sending an appropriate event.
- with cbook._setattr_cm(event, key=sentinel), \
- mpl.rc_context({'keymap.grid': sentinel}):
- mpl.backend_bases.key_press_handler(event, self.figure.canvas)
-
-
-class ToolMinorGrid(ToolBase):
- """Tool to toggle the major and minor grids of the figure."""
-
- description = 'Toggle major and minor grids'
- default_keymap = property(lambda self: mpl.rcParams['keymap.grid_minor'])
-
- def trigger(self, sender, event, data=None):
- sentinel = str(uuid.uuid4())
- # Trigger grid switching by temporarily setting :rc:`keymap.grid_minor`
- # to a unique key and sending an appropriate event.
- with cbook._setattr_cm(event, key=sentinel), \
- mpl.rc_context({'keymap.grid_minor': sentinel}):
- mpl.backend_bases.key_press_handler(event, self.figure.canvas)
-
-
-class ToolFullScreen(ToolBase):
- """Tool to toggle full screen."""
-
- description = 'Toggle fullscreen mode'
- default_keymap = property(lambda self: mpl.rcParams['keymap.fullscreen'])
-
- def trigger(self, sender, event, data=None):
- self.figure.canvas.manager.full_screen_toggle()
-
-
-class AxisScaleBase(ToolToggleBase):
- """Base Tool to toggle between linear and logarithmic."""
-
- def trigger(self, sender, event, data=None):
- if event.inaxes is None:
- return
- super().trigger(sender, event, data)
-
- def enable(self, event=None):
- self.set_scale(event.inaxes, 'log')
- self.figure.canvas.draw_idle()
-
- def disable(self, event=None):
- self.set_scale(event.inaxes, 'linear')
- self.figure.canvas.draw_idle()
-
-
-class ToolYScale(AxisScaleBase):
- """Tool to toggle between linear and logarithmic scales on the Y axis."""
-
- description = 'Toggle scale Y axis'
- default_keymap = property(lambda self: mpl.rcParams['keymap.yscale'])
-
- def set_scale(self, ax, scale):
- ax.set_yscale(scale)
-
-
-class ToolXScale(AxisScaleBase):
- """Tool to toggle between linear and logarithmic scales on the X axis."""
-
- description = 'Toggle scale X axis'
- default_keymap = property(lambda self: mpl.rcParams['keymap.xscale'])
-
- def set_scale(self, ax, scale):
- ax.set_xscale(scale)
-
-
-class ToolViewsPositions(ToolBase):
- """
- Auxiliary Tool to handle changes in views and positions.
-
- Runs in the background and should get used by all the tools that
- need to access the figure's history of views and positions, e.g.
-
- * `ToolZoom`
- * `ToolPan`
- * `ToolHome`
- * `ToolBack`
- * `ToolForward`
- """
-
- def __init__(self, *args, **kwargs):
- self.views = WeakKeyDictionary()
- self.positions = WeakKeyDictionary()
- self.home_views = WeakKeyDictionary()
- super().__init__(*args, **kwargs)
-
- def add_figure(self, figure):
- """Add the current figure to the stack of views and positions."""
-
- if figure not in self.views:
- self.views[figure] = cbook._Stack()
- self.positions[figure] = cbook._Stack()
- self.home_views[figure] = WeakKeyDictionary()
- # Define Home
- self.push_current(figure)
- # Make sure we add a home view for new axes as they're added
- figure.add_axobserver(lambda fig: self.update_home_views(fig))
-
- def clear(self, figure):
- """Reset the axes stack."""
- if figure in self.views:
- self.views[figure].clear()
- self.positions[figure].clear()
- self.home_views[figure].clear()
- self.update_home_views()
-
- def update_view(self):
- """
- Update the view limits and position for each axes from the current
- stack position. If any axes are present in the figure that aren't in
- the current stack position, use the home view limits for those axes and
- don't update *any* positions.
- """
-
- views = self.views[self.figure]()
- if views is None:
- return
- pos = self.positions[self.figure]()
- if pos is None:
- return
- home_views = self.home_views[self.figure]
- all_axes = self.figure.get_axes()
- for a in all_axes:
- if a in views:
- cur_view = views[a]
- else:
- cur_view = home_views[a]
- a._set_view(cur_view)
-
- if set(all_axes).issubset(pos):
- for a in all_axes:
- # Restore both the original and modified positions
- a._set_position(pos[a][0], 'original')
- a._set_position(pos[a][1], 'active')
-
- self.figure.canvas.draw_idle()
-
- def push_current(self, figure=None):
- """
- Push the current view limits and position onto their respective stacks.
- """
- if not figure:
- figure = self.figure
- views = WeakKeyDictionary()
- pos = WeakKeyDictionary()
- for a in figure.get_axes():
- views[a] = a._get_view()
- pos[a] = self._axes_pos(a)
- self.views[figure].push(views)
- self.positions[figure].push(pos)
-
- def _axes_pos(self, ax):
- """
- Return the original and modified positions for the specified axes.
-
- Parameters
- ----------
- ax : matplotlib.axes.Axes
- The `.Axes` to get the positions for.
-
- Returns
- -------
- original_position, modified_position
- A tuple of the original and modified positions.
- """
-
- return (ax.get_position(True).frozen(),
- ax.get_position().frozen())
-
- def update_home_views(self, figure=None):
- """
- Make sure that ``self.home_views`` has an entry for all axes present
- in the figure.
- """
-
- if not figure:
- figure = self.figure
- for a in figure.get_axes():
- if a not in self.home_views[figure]:
- self.home_views[figure][a] = a._get_view()
-
- def home(self):
- """Recall the first view and position from the stack."""
- self.views[self.figure].home()
- self.positions[self.figure].home()
-
- def back(self):
- """Back one step in the stack of views and positions."""
- self.views[self.figure].back()
- self.positions[self.figure].back()
-
- def forward(self):
- """Forward one step in the stack of views and positions."""
- self.views[self.figure].forward()
- self.positions[self.figure].forward()
-
-
-class ViewsPositionsBase(ToolBase):
- """Base class for `ToolHome`, `ToolBack` and `ToolForward`."""
-
- _on_trigger = None
-
- def trigger(self, sender, event, data=None):
- self.toolmanager.get_tool(_views_positions).add_figure(self.figure)
- getattr(self.toolmanager.get_tool(_views_positions),
- self._on_trigger)()
- self.toolmanager.get_tool(_views_positions).update_view()
-
-
-class ToolHome(ViewsPositionsBase):
- """Restore the original view limits."""
-
- description = 'Reset original view'
- image = 'home'
- default_keymap = property(lambda self: mpl.rcParams['keymap.home'])
- _on_trigger = 'home'
-
-
-class ToolBack(ViewsPositionsBase):
- """Move back up the view limits stack."""
-
- description = 'Back to previous view'
- image = 'back'
- default_keymap = property(lambda self: mpl.rcParams['keymap.back'])
- _on_trigger = 'back'
-
-
-class ToolForward(ViewsPositionsBase):
- """Move forward in the view lim stack."""
-
- description = 'Forward to next view'
- image = 'forward'
- default_keymap = property(lambda self: mpl.rcParams['keymap.forward'])
- _on_trigger = 'forward'
-
-
-class ConfigureSubplotsBase(ToolBase):
- """Base tool for the configuration of subplots."""
-
- description = 'Configure subplots'
- image = 'subplots'
-
-
-class SaveFigureBase(ToolBase):
- """Base tool for figure saving."""
-
- description = 'Save the figure'
- image = 'filesave'
- default_keymap = property(lambda self: mpl.rcParams['keymap.save'])
-
-
-class ZoomPanBase(ToolToggleBase):
- """Base class for `ToolZoom` and `ToolPan`."""
- def __init__(self, *args):
- super().__init__(*args)
- self._button_pressed = None
- self._xypress = None
- self._idPress = None
- self._idRelease = None
- self._idScroll = None
- self.base_scale = 2.
- self.scrollthresh = .5 # .5 second scroll threshold
- self.lastscroll = time.time()-self.scrollthresh
-
- def enable(self, event=None):
- """Connect press/release events and lock the canvas."""
- self.figure.canvas.widgetlock(self)
- self._idPress = self.figure.canvas.mpl_connect(
- 'button_press_event', self._press)
- self._idRelease = self.figure.canvas.mpl_connect(
- 'button_release_event', self._release)
- self._idScroll = self.figure.canvas.mpl_connect(
- 'scroll_event', self.scroll_zoom)
-
- def disable(self, event=None):
- """Release the canvas and disconnect press/release events."""
- self._cancel_action()
- self.figure.canvas.widgetlock.release(self)
- self.figure.canvas.mpl_disconnect(self._idPress)
- self.figure.canvas.mpl_disconnect(self._idRelease)
- self.figure.canvas.mpl_disconnect(self._idScroll)
-
- def trigger(self, sender, event, data=None):
- self.toolmanager.get_tool(_views_positions).add_figure(self.figure)
- super().trigger(sender, event, data)
- new_navigate_mode = self.name.upper() if self.toggled else None
- for ax in self.figure.axes:
- ax.set_navigate_mode(new_navigate_mode)
-
- def scroll_zoom(self, event):
- # https://gist.github.com/tacaswell/3144287
- if event.inaxes is None:
- return
-
- if event.button == 'up':
- # deal with zoom in
- scl = self.base_scale
- elif event.button == 'down':
- # deal with zoom out
- scl = 1/self.base_scale
- else:
- # deal with something that should never happen
- scl = 1
-
- ax = event.inaxes
- ax._set_view_from_bbox([event.x, event.y, scl])
-
- # If last scroll was done within the timing threshold, delete the
- # previous view
- if (time.time()-self.lastscroll) < self.scrollthresh:
- self.toolmanager.get_tool(_views_positions).back()
-
- self.figure.canvas.draw_idle() # force re-draw
-
- self.lastscroll = time.time()
- self.toolmanager.get_tool(_views_positions).push_current()
-
-
-class ToolZoom(ZoomPanBase):
- """A Tool for zooming using a rectangle selector."""
-
- description = 'Zoom to rectangle'
- image = 'zoom_to_rect'
- default_keymap = property(lambda self: mpl.rcParams['keymap.zoom'])
- cursor = cursors.SELECT_REGION
- radio_group = 'default'
-
- def __init__(self, *args):
- super().__init__(*args)
- self._ids_zoom = []
-
- def _cancel_action(self):
- for zoom_id in self._ids_zoom:
- self.figure.canvas.mpl_disconnect(zoom_id)
- self.toolmanager.trigger_tool('rubberband', self)
- self.figure.canvas.draw_idle()
- self._xypress = None
- self._button_pressed = None
- self._ids_zoom = []
- return
-
- def _press(self, event):
- """Callback for mouse button presses in zoom-to-rectangle mode."""
-
- # If we're already in the middle of a zoom, pressing another
- # button works to "cancel"
- if self._ids_zoom:
- self._cancel_action()
-
- if event.button == 1:
- self._button_pressed = 1
- elif event.button == 3:
- self._button_pressed = 3
- else:
- self._cancel_action()
- return
-
- x, y = event.x, event.y
-
- self._xypress = []
- for i, a in enumerate(self.figure.get_axes()):
- if (x is not None and y is not None and a.in_axes(event) and
- a.get_navigate() and a.can_zoom()):
- self._xypress.append((x, y, a, i, a._get_view()))
-
- id1 = self.figure.canvas.mpl_connect(
- 'motion_notify_event', self._mouse_move)
- id2 = self.figure.canvas.mpl_connect(
- 'key_press_event', self._switch_on_zoom_mode)
- id3 = self.figure.canvas.mpl_connect(
- 'key_release_event', self._switch_off_zoom_mode)
-
- self._ids_zoom = id1, id2, id3
- self._zoom_mode = event.key
-
- def _switch_on_zoom_mode(self, event):
- self._zoom_mode = event.key
- self._mouse_move(event)
-
- def _switch_off_zoom_mode(self, event):
- self._zoom_mode = None
- self._mouse_move(event)
-
- def _mouse_move(self, event):
- """Callback for mouse moves in zoom-to-rectangle mode."""
-
- if self._xypress:
- x, y = event.x, event.y
- lastx, lasty, a, ind, view = self._xypress[0]
- (x1, y1), (x2, y2) = np.clip(
- [[lastx, lasty], [x, y]], a.bbox.min, a.bbox.max)
- if self._zoom_mode == "x":
- y1, y2 = a.bbox.intervaly
- elif self._zoom_mode == "y":
- x1, x2 = a.bbox.intervalx
- self.toolmanager.trigger_tool(
- 'rubberband', self, data=(x1, y1, x2, y2))
-
- def _release(self, event):
- """Callback for mouse button releases in zoom-to-rectangle mode."""
-
- for zoom_id in self._ids_zoom:
- self.figure.canvas.mpl_disconnect(zoom_id)
- self._ids_zoom = []
-
- if not self._xypress:
- self._cancel_action()
- return
-
- done_ax = []
-
- for cur_xypress in self._xypress:
- x, y = event.x, event.y
- lastx, lasty, a, _ind, view = cur_xypress
- # ignore singular clicks - 5 pixels is a threshold
- if abs(x - lastx) < 5 or abs(y - lasty) < 5:
- self._cancel_action()
- return
-
- # detect twinx, twiny axes and avoid double zooming
- twinx = any(a.get_shared_x_axes().joined(a, a1) for a1 in done_ax)
- twiny = any(a.get_shared_y_axes().joined(a, a1) for a1 in done_ax)
- done_ax.append(a)
-
- if self._button_pressed == 1:
- direction = 'in'
- elif self._button_pressed == 3:
- direction = 'out'
- else:
- continue
-
- a._set_view_from_bbox((lastx, lasty, x, y), direction,
- self._zoom_mode, twinx, twiny)
-
- self._zoom_mode = None
- self.toolmanager.get_tool(_views_positions).push_current()
- self._cancel_action()
-
-
-class ToolPan(ZoomPanBase):
- """Pan axes with left mouse, zoom with right."""
-
- default_keymap = property(lambda self: mpl.rcParams['keymap.pan'])
- description = 'Pan axes with left mouse, zoom with right'
- image = 'move'
- cursor = cursors.MOVE
- radio_group = 'default'
-
- def __init__(self, *args):
- super().__init__(*args)
- self._id_drag = None
-
- def _cancel_action(self):
- self._button_pressed = None
- self._xypress = []
- self.figure.canvas.mpl_disconnect(self._id_drag)
- self.toolmanager.messagelock.release(self)
- self.figure.canvas.draw_idle()
-
- def _press(self, event):
- if event.button == 1:
- self._button_pressed = 1
- elif event.button == 3:
- self._button_pressed = 3
- else:
- self._cancel_action()
- return
-
- x, y = event.x, event.y
-
- self._xypress = []
- for i, a in enumerate(self.figure.get_axes()):
- if (x is not None and y is not None and a.in_axes(event) and
- a.get_navigate() and a.can_pan()):
- a.start_pan(x, y, event.button)
- self._xypress.append((a, i))
- self.toolmanager.messagelock(self)
- self._id_drag = self.figure.canvas.mpl_connect(
- 'motion_notify_event', self._mouse_move)
-
- def _release(self, event):
- if self._button_pressed is None:
- self._cancel_action()
- return
-
- self.figure.canvas.mpl_disconnect(self._id_drag)
- self.toolmanager.messagelock.release(self)
-
- for a, _ind in self._xypress:
- a.end_pan()
- if not self._xypress:
- self._cancel_action()
- return
-
- self.toolmanager.get_tool(_views_positions).push_current()
- self._cancel_action()
-
- def _mouse_move(self, event):
- for a, _ind in self._xypress:
- # safer to use the recorded button at the _press than current
- # button: # multiple button can get pressed during motion...
- a.drag_pan(self._button_pressed, event.key, event.x, event.y)
- self.toolmanager.canvas.draw_idle()
-
-
-class ToolHelpBase(ToolBase):
- description = 'Print tool list, shortcuts and description'
- default_keymap = property(lambda self: mpl.rcParams['keymap.help'])
- image = 'help'
-
- @staticmethod
- def format_shortcut(key_sequence):
- """
- Convert a shortcut string from the notation used in rc config to the
- standard notation for displaying shortcuts, e.g. 'ctrl+a' -> 'Ctrl+A'.
- """
- return (key_sequence if len(key_sequence) == 1 else
- re.sub(r"\+[A-Z]", r"+Shift\g<0>", key_sequence).title())
-
- def _format_tool_keymap(self, name):
- keymaps = self.toolmanager.get_tool_keymap(name)
- return ", ".join(self.format_shortcut(keymap) for keymap in keymaps)
-
- def _get_help_entries(self):
- return [(name, self._format_tool_keymap(name), tool.description)
- for name, tool in sorted(self.toolmanager.tools.items())
- if tool.description]
-
- def _get_help_text(self):
- entries = self._get_help_entries()
- entries = ["{}: {}\n\t{}".format(*entry) for entry in entries]
- return "\n".join(entries)
-
- def _get_help_html(self):
- fmt = "<tr><td>{}</td><td>{}</td><td>{}</td></tr>"
- rows = [fmt.format(
- "<b>Action</b>", "<b>Shortcuts</b>", "<b>Description</b>")]
- rows += [fmt.format(*row) for row in self._get_help_entries()]
- return ("<style>td {padding: 0px 4px}</style>"
- "<table><thead>" + rows[0] + "</thead>"
- "<tbody>".join(rows[1:]) + "</tbody></table>")
-
-
-class ToolCopyToClipboardBase(ToolBase):
- """Tool to copy the figure to the clipboard."""
-
- description = 'Copy the canvas figure to clipboard'
- default_keymap = property(lambda self: mpl.rcParams['keymap.copy'])
-
- def trigger(self, *args, **kwargs):
- message = "Copy tool is not available"
- self.toolmanager.message_event(message, self)
-
-
-default_tools = {'home': ToolHome, 'back': ToolBack, 'forward': ToolForward,
- 'zoom': ToolZoom, 'pan': ToolPan,
- 'subplots': ConfigureSubplotsBase,
- 'save': SaveFigureBase,
- 'grid': ToolGrid,
- 'grid_minor': ToolMinorGrid,
- 'fullscreen': ToolFullScreen,
- 'quit': ToolQuit,
- 'quit_all': ToolQuitAll,
- 'xscale': ToolXScale,
- 'yscale': ToolYScale,
- 'position': ToolCursorPosition,
- _views_positions: ToolViewsPositions,
- 'cursor': ToolSetCursor,
- 'rubberband': RubberbandBase,
- 'help': ToolHelpBase,
- 'copy': ToolCopyToClipboardBase,
- }
-
-default_toolbar_tools = [['navigation', ['home', 'back', 'forward']],
- ['zoompan', ['pan', 'zoom', 'subplots']],
- ['io', ['save', 'help']]]
-
-
-def add_tools_to_manager(toolmanager, tools=default_tools):
- """
- Add multiple tools to a `.ToolManager`.
-
- Parameters
- ----------
- toolmanager : `.backend_managers.ToolManager`
- Manager to which the tools are added.
- tools : {str: class_like}, optional
- The tools to add in a {name: tool} dict, see
- `.backend_managers.ToolManager.add_tool` for more info.
- """
-
- for name, tool in tools.items():
- toolmanager.add_tool(name, tool)
-
-
-def add_tools_to_container(container, tools=default_toolbar_tools):
- """
- Add multiple tools to the container.
-
- Parameters
- ----------
- container : Container
- `.backend_bases.ToolContainerBase` object that will get the tools
- added.
- tools : list, optional
- List in the form ``[[group1, [tool1, tool2 ...]], [group2, [...]]]``
- where the tools ``[tool1, tool2, ...]`` will display in group1.
- See `.backend_bases.ToolContainerBase.add_tool` for details.
- """
-
- for group, grouptools in tools:
- for position, tool in enumerate(grouptools):
- container.add_tool(tool, group, position)
diff --git a/contrib/python/matplotlib/py3/matplotlib/backend_tools.pyi b/contrib/python/matplotlib/py3/matplotlib/backend_tools.pyi
deleted file mode 100644
index 446f713292..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backend_tools.pyi
+++ /dev/null
@@ -1,121 +0,0 @@
-import enum
-from matplotlib import cbook
-from matplotlib.axes import Axes
-from matplotlib.backend_bases import ToolContainerBase, FigureCanvasBase
-from matplotlib.backend_managers import ToolManager, ToolEvent
-from matplotlib.figure import Figure
-from matplotlib.scale import ScaleBase
-
-from typing import Any
-
-class Cursors(enum.IntEnum):
- POINTER: int
- HAND: int
- SELECT_REGION: int
- MOVE: int
- WAIT: int
- RESIZE_HORIZONTAL: int
- RESIZE_VERTICAL: int
-
-cursors = Cursors
-
-class ToolBase:
- @property
- def default_keymap(self) -> list[str] | None: ...
- description: str | None
- image: str | None
- def __init__(self, toolmanager: ToolManager, name: str) -> None: ...
- @property
- def name(self) -> str: ...
- @property
- def toolmanager(self) -> ToolManager: ...
- @property
- def canvas(self) -> FigureCanvasBase | None: ...
- @property
- def figure(self) -> Figure | None: ...
- @figure.setter
- def figure(self, figure: Figure | None) -> None: ...
- def set_figure(self, figure: Figure | None) -> None: ...
- def trigger(self, sender: Any, event: ToolEvent, data: Any = ...) -> None: ...
-
-class ToolToggleBase(ToolBase):
- radio_group: str | None
- cursor: Cursors | None
- default_toggled: bool
- def __init__(self, *args, **kwargs) -> None: ...
- def enable(self, event: ToolEvent | None = ...) -> None: ...
- def disable(self, event: ToolEvent | None = ...) -> None: ...
- @property
- def toggled(self) -> bool: ...
- def set_figure(self, figure: Figure | None) -> None: ...
-
-class ToolSetCursor(ToolBase): ...
-
-class ToolCursorPosition(ToolBase):
- def send_message(self, event: ToolEvent) -> None: ...
-
-class RubberbandBase(ToolBase):
- def draw_rubberband(self, *data) -> None: ...
- def remove_rubberband(self) -> None: ...
-
-class ToolQuit(ToolBase): ...
-class ToolQuitAll(ToolBase): ...
-class ToolGrid(ToolBase): ...
-class ToolMinorGrid(ToolBase): ...
-class ToolFullScreen(ToolBase): ...
-
-class AxisScaleBase(ToolToggleBase):
- def enable(self, event: ToolEvent | None = ...) -> None: ...
- def disable(self, event: ToolEvent | None = ...) -> None: ...
-
-class ToolYScale(AxisScaleBase):
- def set_scale(self, ax: Axes, scale: str | ScaleBase) -> None: ...
-
-class ToolXScale(AxisScaleBase):
- def set_scale(self, ax, scale: str | ScaleBase) -> None: ...
-
-class ToolViewsPositions(ToolBase):
- views: dict[Figure | Axes, cbook.Stack]
- positions: dict[Figure | Axes, cbook.Stack]
- home_views: dict[Figure, dict[Axes, tuple[float, float, float, float]]]
- def add_figure(self, figure: Figure) -> None: ...
- def clear(self, figure: Figure) -> None: ...
- def update_view(self) -> None: ...
- def push_current(self, figure: Figure | None = ...) -> None: ...
- def update_home_views(self, figure: Figure | None = ...) -> None: ...
- def home(self) -> None: ...
- def back(self) -> None: ...
- def forward(self) -> None: ...
-
-class ViewsPositionsBase(ToolBase): ...
-class ToolHome(ViewsPositionsBase): ...
-class ToolBack(ViewsPositionsBase): ...
-class ToolForward(ViewsPositionsBase): ...
-class ConfigureSubplotsBase(ToolBase): ...
-class SaveFigureBase(ToolBase): ...
-
-class ZoomPanBase(ToolToggleBase):
- base_scale: float
- scrollthresh: float
- lastscroll: float
- def __init__(self, *args) -> None: ...
- def enable(self, event: ToolEvent | None = ...) -> None: ...
- def disable(self, event: ToolEvent | None = ...) -> None: ...
- def scroll_zoom(self, event: ToolEvent) -> None: ...
-
-class ToolZoom(ZoomPanBase): ...
-class ToolPan(ZoomPanBase): ...
-
-class ToolHelpBase(ToolBase):
- @staticmethod
- def format_shortcut(key_sequence: str) -> str: ...
-
-class ToolCopyToClipboardBase(ToolBase): ...
-
-default_tools: dict[str, ToolBase]
-default_toolbar_tools: list[list[str | list[str]]]
-
-def add_tools_to_manager(
- toolmanager: ToolManager, tools: dict[str, type[ToolBase]] = ...
-) -> None: ...
-def add_tools_to_container(container: ToolContainerBase, tools: list[Any] = ...) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/__init__.py b/contrib/python/matplotlib/py3/matplotlib/backends/__init__.py
deleted file mode 100644
index 3e687f85b0..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# NOTE: plt.switch_backend() (called at import time) will add a "backend"
-# attribute here for backcompat.
-_QT_FORCE_QT5_BINDING = False
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/_backend_agg.pyi b/contrib/python/matplotlib/py3/matplotlib/backends/_backend_agg.pyi
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/_backend_agg.pyi
+++ /dev/null
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/_backend_gtk.py b/contrib/python/matplotlib/py3/matplotlib/backends/_backend_gtk.py
deleted file mode 100644
index 565d929320..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/_backend_gtk.py
+++ /dev/null
@@ -1,332 +0,0 @@
-"""
-Common code for GTK3 and GTK4 backends.
-"""
-
-import logging
-import sys
-
-import matplotlib as mpl
-from matplotlib import _api, backend_tools, cbook
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2,
- TimerBase)
-from matplotlib.backend_tools import Cursors
-
-import gi
-# The GTK3/GTK4 backends will have already called `gi.require_version` to set
-# the desired GTK.
-from gi.repository import Gdk, Gio, GLib, Gtk
-
-
-try:
- gi.require_foreign("cairo")
-except ImportError as e:
- raise ImportError("Gtk-based backends require cairo") from e
-
-_log = logging.getLogger(__name__)
-_application = None # Placeholder
-
-
-def _shutdown_application(app):
- # The application might prematurely shut down if Ctrl-C'd out of IPython,
- # so close all windows.
- for win in app.get_windows():
- win.close()
- # The PyGObject wrapper incorrectly thinks that None is not allowed, or we
- # would call this:
- # Gio.Application.set_default(None)
- # Instead, we set this property and ignore default applications with it:
- app._created_by_matplotlib = True
- global _application
- _application = None
-
-
-def _create_application():
- global _application
-
- if _application is None:
- app = Gio.Application.get_default()
- if app is None or getattr(app, '_created_by_matplotlib', False):
- # display_is_valid returns False only if on Linux and neither X11
- # nor Wayland display can be opened.
- if not mpl._c_internal_utils.display_is_valid():
- raise RuntimeError('Invalid DISPLAY variable')
- _application = Gtk.Application.new('org.matplotlib.Matplotlib3',
- Gio.ApplicationFlags.NON_UNIQUE)
- # The activate signal must be connected, but we don't care for
- # handling it, since we don't do any remote processing.
- _application.connect('activate', lambda *args, **kwargs: None)
- _application.connect('shutdown', _shutdown_application)
- _application.register()
- cbook._setup_new_guiapp()
- else:
- _application = app
-
- return _application
-
-
-def mpl_to_gtk_cursor_name(mpl_cursor):
- return _api.check_getitem({
- Cursors.MOVE: "move",
- Cursors.HAND: "pointer",
- Cursors.POINTER: "default",
- Cursors.SELECT_REGION: "crosshair",
- Cursors.WAIT: "wait",
- Cursors.RESIZE_HORIZONTAL: "ew-resize",
- Cursors.RESIZE_VERTICAL: "ns-resize",
- }, cursor=mpl_cursor)
-
-
-class TimerGTK(TimerBase):
- """Subclass of `.TimerBase` using GTK timer events."""
-
- def __init__(self, *args, **kwargs):
- self._timer = None
- super().__init__(*args, **kwargs)
-
- def _timer_start(self):
- # Need to stop it, otherwise we potentially leak a timer id that will
- # never be stopped.
- self._timer_stop()
- self._timer = GLib.timeout_add(self._interval, self._on_timer)
-
- def _timer_stop(self):
- if self._timer is not None:
- GLib.source_remove(self._timer)
- self._timer = None
-
- def _timer_set_interval(self):
- # Only stop and restart it if the timer has already been started.
- if self._timer is not None:
- self._timer_stop()
- self._timer_start()
-
- def _on_timer(self):
- super()._on_timer()
-
- # Gtk timeout_add() requires that the callback returns True if it
- # is to be called again.
- if self.callbacks and not self._single:
- return True
- else:
- self._timer = None
- return False
-
-
-class _FigureCanvasGTK(FigureCanvasBase):
- _timer_cls = TimerGTK
-
-
-class _FigureManagerGTK(FigureManagerBase):
- """
- Attributes
- ----------
- canvas : `FigureCanvas`
- The FigureCanvas instance
- num : int or str
- The Figure number
- toolbar : Gtk.Toolbar or Gtk.Box
- The toolbar
- vbox : Gtk.VBox
- The Gtk.VBox containing the canvas and toolbar
- window : Gtk.Window
- The Gtk.Window
- """
-
- def __init__(self, canvas, num):
- self._gtk_ver = gtk_ver = Gtk.get_major_version()
-
- app = _create_application()
- self.window = Gtk.Window()
- app.add_window(self.window)
- super().__init__(canvas, num)
-
- if gtk_ver == 3:
- self.window.set_wmclass("matplotlib", "Matplotlib")
- icon_ext = "png" if sys.platform == "win32" else "svg"
- self.window.set_icon_from_file(
- str(cbook._get_data_path(f"images/matplotlib.{icon_ext}")))
-
- self.vbox = Gtk.Box()
- self.vbox.set_property("orientation", Gtk.Orientation.VERTICAL)
-
- if gtk_ver == 3:
- self.window.add(self.vbox)
- self.vbox.show()
- self.canvas.show()
- self.vbox.pack_start(self.canvas, True, True, 0)
- elif gtk_ver == 4:
- self.window.set_child(self.vbox)
- self.vbox.prepend(self.canvas)
-
- # calculate size for window
- w, h = self.canvas.get_width_height()
-
- if self.toolbar is not None:
- if gtk_ver == 3:
- self.toolbar.show()
- self.vbox.pack_end(self.toolbar, False, False, 0)
- elif gtk_ver == 4:
- sw = Gtk.ScrolledWindow(vscrollbar_policy=Gtk.PolicyType.NEVER)
- sw.set_child(self.toolbar)
- self.vbox.append(sw)
- min_size, nat_size = self.toolbar.get_preferred_size()
- h += nat_size.height
-
- self.window.set_default_size(w, h)
-
- self._destroying = False
- self.window.connect("destroy", lambda *args: Gcf.destroy(self))
- self.window.connect({3: "delete_event", 4: "close-request"}[gtk_ver],
- lambda *args: Gcf.destroy(self))
- if mpl.is_interactive():
- self.window.show()
- self.canvas.draw_idle()
-
- self.canvas.grab_focus()
-
- def destroy(self, *args):
- if self._destroying:
- # Otherwise, this can be called twice when the user presses 'q',
- # which calls Gcf.destroy(self), then this destroy(), then triggers
- # Gcf.destroy(self) once again via
- # `connect("destroy", lambda *args: Gcf.destroy(self))`.
- return
- self._destroying = True
- self.window.destroy()
- self.canvas.destroy()
-
- @classmethod
- def start_main_loop(cls):
- global _application
- if _application is None:
- return
-
- try:
- _application.run() # Quits when all added windows close.
- except KeyboardInterrupt:
- # Ensure all windows can process their close event from
- # _shutdown_application.
- context = GLib.MainContext.default()
- while context.pending():
- context.iteration(True)
- raise
- finally:
- # Running after quit is undefined, so create a new one next time.
- _application = None
-
- def show(self):
- # show the figure window
- self.window.show()
- self.canvas.draw()
- if mpl.rcParams["figure.raise_window"]:
- meth_name = {3: "get_window", 4: "get_surface"}[self._gtk_ver]
- if getattr(self.window, meth_name)():
- self.window.present()
- else:
- # If this is called by a callback early during init,
- # self.window (a GtkWindow) may not have an associated
- # low-level GdkWindow (on GTK3) or GdkSurface (on GTK4) yet,
- # and present() would crash.
- _api.warn_external("Cannot raise window yet to be setup")
-
- def full_screen_toggle(self):
- is_fullscreen = {
- 3: lambda w: (w.get_window().get_state()
- & Gdk.WindowState.FULLSCREEN),
- 4: lambda w: w.is_fullscreen(),
- }[self._gtk_ver]
- if is_fullscreen(self.window):
- self.window.unfullscreen()
- else:
- self.window.fullscreen()
-
- def get_window_title(self):
- return self.window.get_title()
-
- def set_window_title(self, title):
- self.window.set_title(title)
-
- def resize(self, width, height):
- width = int(width / self.canvas.device_pixel_ratio)
- height = int(height / self.canvas.device_pixel_ratio)
- if self.toolbar:
- min_size, nat_size = self.toolbar.get_preferred_size()
- height += nat_size.height
- canvas_size = self.canvas.get_allocation()
- if self._gtk_ver >= 4 or canvas_size.width == canvas_size.height == 1:
- # A canvas size of (1, 1) cannot exist in most cases, because
- # window decorations would prevent such a small window. This call
- # must be before the window has been mapped and widgets have been
- # sized, so just change the window's starting size.
- self.window.set_default_size(width, height)
- else:
- self.window.resize(width, height)
-
-
-class _NavigationToolbar2GTK(NavigationToolbar2):
- # Must be implemented in GTK3/GTK4 backends:
- # * __init__
- # * save_figure
-
- def set_message(self, s):
- escaped = GLib.markup_escape_text(s)
- self.message.set_markup(f'<small>{escaped}</small>')
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- height = self.canvas.figure.bbox.height
- y1 = height - y1
- y0 = height - y0
- rect = [int(val) for val in (x0, y0, x1 - x0, y1 - y0)]
- self.canvas._draw_rubberband(rect)
-
- def remove_rubberband(self):
- self.canvas._draw_rubberband(None)
-
- def _update_buttons_checked(self):
- for name, active in [("Pan", "PAN"), ("Zoom", "ZOOM")]:
- button = self._gtk_ids.get(name)
- if button:
- with button.handler_block(button._signal_handler):
- button.set_active(self.mode.name == active)
-
- def pan(self, *args):
- super().pan(*args)
- self._update_buttons_checked()
-
- def zoom(self, *args):
- super().zoom(*args)
- self._update_buttons_checked()
-
- def set_history_buttons(self):
- can_backward = self._nav_stack._pos > 0
- can_forward = self._nav_stack._pos < len(self._nav_stack) - 1
- if 'Back' in self._gtk_ids:
- self._gtk_ids['Back'].set_sensitive(can_backward)
- if 'Forward' in self._gtk_ids:
- self._gtk_ids['Forward'].set_sensitive(can_forward)
-
-
-class RubberbandGTK(backend_tools.RubberbandBase):
- def draw_rubberband(self, x0, y0, x1, y1):
- _NavigationToolbar2GTK.draw_rubberband(
- self._make_classic_style_pseudo_toolbar(), None, x0, y0, x1, y1)
-
- def remove_rubberband(self):
- _NavigationToolbar2GTK.remove_rubberband(
- self._make_classic_style_pseudo_toolbar())
-
-
-class ConfigureSubplotsGTK(backend_tools.ConfigureSubplotsBase):
- def trigger(self, *args):
- _NavigationToolbar2GTK.configure_subplots(self, None)
-
-
-class _BackendGTK(_Backend):
- backend_version = "{}.{}.{}".format(
- Gtk.get_major_version(),
- Gtk.get_minor_version(),
- Gtk.get_micro_version(),
- )
- mainloop = _FigureManagerGTK.start_main_loop
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/_backend_pdf_ps.py b/contrib/python/matplotlib/py3/matplotlib/backends/_backend_pdf_ps.py
deleted file mode 100644
index ce55df523d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/_backend_pdf_ps.py
+++ /dev/null
@@ -1,145 +0,0 @@
-"""
-Common functionality between the PDF and PS backends.
-"""
-
-from io import BytesIO
-import functools
-
-from fontTools import subset
-
-import matplotlib as mpl
-from .. import font_manager, ft2font
-from .._afm import AFM
-from ..backend_bases import RendererBase
-
-
-@functools.lru_cache(50)
-def _cached_get_afm_from_fname(fname):
- with open(fname, "rb") as fh:
- return AFM(fh)
-
-
-def get_glyphs_subset(fontfile, characters):
- """
- Subset a TTF font
-
- Reads the named fontfile and restricts the font to the characters.
- Returns a serialization of the subset font as file-like object.
-
- Parameters
- ----------
- fontfile : str
- Path to the font file
- characters : str
- Continuous set of characters to include in subset
- """
-
- options = subset.Options(glyph_names=True, recommended_glyphs=True)
-
- # Prevent subsetting extra tables.
- options.drop_tables += [
- 'FFTM', # FontForge Timestamp.
- 'PfEd', # FontForge personal table.
- 'BDF', # X11 BDF header.
- 'meta', # Metadata stores design/supported languages (meaningless for subsets).
- ]
-
- # if fontfile is a ttc, specify font number
- if fontfile.endswith(".ttc"):
- options.font_number = 0
-
- with subset.load_font(fontfile, options) as font:
- subsetter = subset.Subsetter(options=options)
- subsetter.populate(text=characters)
- subsetter.subset(font)
- fh = BytesIO()
- font.save(fh, reorderTables=False)
- return fh
-
-
-class CharacterTracker:
- """
- Helper for font subsetting by the pdf and ps backends.
-
- Maintains a mapping of font paths to the set of character codepoints that
- are being used from that font.
- """
-
- def __init__(self):
- self.used = {}
-
- def track(self, font, s):
- """Record that string *s* is being typeset using font *font*."""
- char_to_font = font._get_fontmap(s)
- for _c, _f in char_to_font.items():
- self.used.setdefault(_f.fname, set()).add(ord(_c))
-
- def track_glyph(self, font, glyph):
- """Record that codepoint *glyph* is being typeset using font *font*."""
- self.used.setdefault(font.fname, set()).add(glyph)
-
-
-class RendererPDFPSBase(RendererBase):
- # The following attributes must be defined by the subclasses:
- # - _afm_font_dir
- # - _use_afm_rc_name
-
- def __init__(self, width, height):
- super().__init__()
- self.width = width
- self.height = height
-
- def flipy(self):
- # docstring inherited
- return False # y increases from bottom to top.
-
- def option_scale_image(self):
- # docstring inherited
- return True # PDF and PS support arbitrary image scaling.
-
- def option_image_nocomposite(self):
- # docstring inherited
- # Decide whether to composite image based on rcParam value.
- return not mpl.rcParams["image.composite_image"]
-
- def get_canvas_width_height(self):
- # docstring inherited
- return self.width * 72.0, self.height * 72.0
-
- def get_text_width_height_descent(self, s, prop, ismath):
- # docstring inherited
- if ismath == "TeX":
- return super().get_text_width_height_descent(s, prop, ismath)
- elif ismath:
- parse = self._text2path.mathtext_parser.parse(s, 72, prop)
- return parse.width, parse.height, parse.depth
- elif mpl.rcParams[self._use_afm_rc_name]:
- font = self._get_font_afm(prop)
- l, b, w, h, d = font.get_str_bbox_and_descent(s)
- scale = prop.get_size_in_points() / 1000
- w *= scale
- h *= scale
- d *= scale
- return w, h, d
- else:
- font = self._get_font_ttf(prop)
- font.set_text(s, 0.0, flags=ft2font.LOAD_NO_HINTING)
- w, h = font.get_width_height()
- d = font.get_descent()
- scale = 1 / 64
- w *= scale
- h *= scale
- d *= scale
- return w, h, d
-
- def _get_font_afm(self, prop):
- fname = font_manager.findfont(
- prop, fontext="afm", directory=self._afm_font_dir)
- return _cached_get_afm_from_fname(fname)
-
- def _get_font_ttf(self, prop):
- fnames = font_manager.fontManager._find_fonts_by_props(prop)
- font = font_manager.get_font(fnames)
- font.clear()
- font.set_size(prop.get_size_in_points(), 72)
- return font
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/_backend_tk.py b/contrib/python/matplotlib/py3/matplotlib/backends/_backend_tk.py
deleted file mode 100644
index 89c380f8c9..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/_backend_tk.py
+++ /dev/null
@@ -1,1074 +0,0 @@
-import uuid
-import weakref
-from contextlib import contextmanager
-import logging
-import math
-import os.path
-import pathlib
-import sys
-import tkinter as tk
-import tkinter.filedialog
-import tkinter.font
-import tkinter.messagebox
-from tkinter.simpledialog import SimpleDialog
-
-import numpy as np
-from PIL import Image, ImageTk
-
-import matplotlib as mpl
-from matplotlib import _api, backend_tools, cbook, _c_internal_utils
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2,
- TimerBase, ToolContainerBase, cursors, _Mode,
- CloseEvent, KeyEvent, LocationEvent, MouseEvent, ResizeEvent)
-from matplotlib._pylab_helpers import Gcf
-from . import _tkagg
-
-
-_log = logging.getLogger(__name__)
-cursord = {
- cursors.MOVE: "fleur",
- cursors.HAND: "hand2",
- cursors.POINTER: "arrow",
- cursors.SELECT_REGION: "crosshair",
- cursors.WAIT: "watch",
- cursors.RESIZE_HORIZONTAL: "sb_h_double_arrow",
- cursors.RESIZE_VERTICAL: "sb_v_double_arrow",
-}
-
-
-@contextmanager
-def _restore_foreground_window_at_end():
- foreground = _c_internal_utils.Win32_GetForegroundWindow()
- try:
- yield
- finally:
- if mpl.rcParams['tk.window_focus']:
- _c_internal_utils.Win32_SetForegroundWindow(foreground)
-
-
-_blit_args = {}
-# Initialize to a non-empty string that is not a Tcl command
-_blit_tcl_name = "mpl_blit_" + uuid.uuid4().hex
-
-TK_PHOTO_COMPOSITE_OVERLAY = 0 # apply transparency rules pixel-wise
-TK_PHOTO_COMPOSITE_SET = 1 # set image buffer directly
-
-
-def _blit(argsid):
- """
- Thin wrapper to blit called via tkapp.call.
-
- *argsid* is a unique string identifier to fetch the correct arguments from
- the ``_blit_args`` dict, since arguments cannot be passed directly.
- """
- photoimage, dataptr, offsets, bboxptr, comp_rule = _blit_args.pop(argsid)
- if not photoimage.tk.call("info", "commands", photoimage):
- return
- _tkagg.blit(photoimage.tk.interpaddr(), str(photoimage), dataptr,
- comp_rule, offsets, bboxptr)
-
-
-def blit(photoimage, aggimage, offsets, bbox=None):
- """
- Blit *aggimage* to *photoimage*.
-
- *offsets* is a tuple describing how to fill the ``offset`` field of the
- ``Tk_PhotoImageBlock`` struct: it should be (0, 1, 2, 3) for RGBA8888 data,
- (2, 1, 0, 3) for little-endian ARBG32 (i.e. GBRA8888) data and (1, 2, 3, 0)
- for big-endian ARGB32 (i.e. ARGB8888) data.
-
- If *bbox* is passed, it defines the region that gets blitted. That region
- will be composed with the previous data according to the alpha channel.
- Blitting will be clipped to pixels inside the canvas, including silently
- doing nothing if the *bbox* region is entirely outside the canvas.
-
- Tcl events must be dispatched to trigger a blit from a non-Tcl thread.
- """
- data = np.asarray(aggimage)
- height, width = data.shape[:2]
- dataptr = (height, width, data.ctypes.data)
- if bbox is not None:
- (x1, y1), (x2, y2) = bbox.__array__()
- x1 = max(math.floor(x1), 0)
- x2 = min(math.ceil(x2), width)
- y1 = max(math.floor(y1), 0)
- y2 = min(math.ceil(y2), height)
- if (x1 > x2) or (y1 > y2):
- return
- bboxptr = (x1, x2, y1, y2)
- comp_rule = TK_PHOTO_COMPOSITE_OVERLAY
- else:
- bboxptr = (0, width, 0, height)
- comp_rule = TK_PHOTO_COMPOSITE_SET
-
- # NOTE: _tkagg.blit is thread unsafe and will crash the process if called
- # from a thread (GH#13293). Instead of blanking and blitting here,
- # use tkapp.call to post a cross-thread event if this function is called
- # from a non-Tcl thread.
-
- # tkapp.call coerces all arguments to strings, so to avoid string parsing
- # within _blit, pack up the arguments into a global data structure.
- args = photoimage, dataptr, offsets, bboxptr, comp_rule
- # Need a unique key to avoid thread races.
- # Again, make the key a string to avoid string parsing in _blit.
- argsid = str(id(args))
- _blit_args[argsid] = args
-
- try:
- photoimage.tk.call(_blit_tcl_name, argsid)
- except tk.TclError as e:
- if "invalid command name" not in str(e):
- raise
- photoimage.tk.createcommand(_blit_tcl_name, _blit)
- photoimage.tk.call(_blit_tcl_name, argsid)
-
-
-class TimerTk(TimerBase):
- """Subclass of `backend_bases.TimerBase` using Tk timer events."""
-
- def __init__(self, parent, *args, **kwargs):
- self._timer = None
- super().__init__(*args, **kwargs)
- self.parent = parent
-
- def _timer_start(self):
- self._timer_stop()
- self._timer = self.parent.after(self._interval, self._on_timer)
-
- def _timer_stop(self):
- if self._timer is not None:
- self.parent.after_cancel(self._timer)
- self._timer = None
-
- def _on_timer(self):
- super()._on_timer()
- # Tk after() is only a single shot, so we need to add code here to
- # reset the timer if we're not operating in single shot mode. However,
- # if _timer is None, this means that _timer_stop has been called; so
- # don't recreate the timer in that case.
- if not self._single and self._timer:
- if self._interval > 0:
- self._timer = self.parent.after(self._interval, self._on_timer)
- else:
- # Edge case: Tcl after 0 *prepends* events to the queue
- # so a 0 interval does not allow any other events to run.
- # This incantation is cancellable and runs as fast as possible
- # while also allowing events and drawing every frame. GH#18236
- self._timer = self.parent.after_idle(
- lambda: self.parent.after(self._interval, self._on_timer)
- )
- else:
- self._timer = None
-
-
-class FigureCanvasTk(FigureCanvasBase):
- required_interactive_framework = "tk"
- manager_class = _api.classproperty(lambda cls: FigureManagerTk)
-
- def __init__(self, figure=None, master=None):
- super().__init__(figure)
- self._idle_draw_id = None
- self._event_loop_id = None
- w, h = self.get_width_height(physical=True)
- self._tkcanvas = tk.Canvas(
- master=master, background="white",
- width=w, height=h, borderwidth=0, highlightthickness=0)
- self._tkphoto = tk.PhotoImage(
- master=self._tkcanvas, width=w, height=h)
- self._tkcanvas_image_region = self._tkcanvas.create_image(
- w//2, h//2, image=self._tkphoto)
- self._tkcanvas.bind("<Configure>", self.resize)
- if sys.platform == 'win32':
- self._tkcanvas.bind("<Map>", self._update_device_pixel_ratio)
- self._tkcanvas.bind("<Key>", self.key_press)
- self._tkcanvas.bind("<Motion>", self.motion_notify_event)
- self._tkcanvas.bind("<Enter>", self.enter_notify_event)
- self._tkcanvas.bind("<Leave>", self.leave_notify_event)
- self._tkcanvas.bind("<KeyRelease>", self.key_release)
- for name in ["<Button-1>", "<Button-2>", "<Button-3>"]:
- self._tkcanvas.bind(name, self.button_press_event)
- for name in [
- "<Double-Button-1>", "<Double-Button-2>", "<Double-Button-3>"]:
- self._tkcanvas.bind(name, self.button_dblclick_event)
- for name in [
- "<ButtonRelease-1>", "<ButtonRelease-2>", "<ButtonRelease-3>"]:
- self._tkcanvas.bind(name, self.button_release_event)
-
- # Mouse wheel on Linux generates button 4/5 events
- for name in "<Button-4>", "<Button-5>":
- self._tkcanvas.bind(name, self.scroll_event)
- # Mouse wheel for windows goes to the window with the focus.
- # Since the canvas won't usually have the focus, bind the
- # event to the window containing the canvas instead.
- # See https://wiki.tcl-lang.org/3893 (mousewheel) for details
- root = self._tkcanvas.winfo_toplevel()
-
- # Prevent long-lived references via tkinter callback structure GH-24820
- weakself = weakref.ref(self)
- weakroot = weakref.ref(root)
-
- def scroll_event_windows(event):
- self = weakself()
- if self is None:
- root = weakroot()
- if root is not None:
- root.unbind("<MouseWheel>", scroll_event_windows_id)
- return
- return self.scroll_event_windows(event)
- scroll_event_windows_id = root.bind("<MouseWheel>", scroll_event_windows, "+")
-
- # Can't get destroy events by binding to _tkcanvas. Therefore, bind
- # to the window and filter.
- def filter_destroy(event):
- self = weakself()
- if self is None:
- root = weakroot()
- if root is not None:
- root.unbind("<Destroy>", filter_destroy_id)
- return
- if event.widget is self._tkcanvas:
- CloseEvent("close_event", self)._process()
- filter_destroy_id = root.bind("<Destroy>", filter_destroy, "+")
-
- self._tkcanvas.focus_set()
-
- self._rubberband_rect_black = None
- self._rubberband_rect_white = None
-
- def _update_device_pixel_ratio(self, event=None):
- # Tk gives scaling with respect to 72 DPI, but Windows screens are
- # scaled vs 96 dpi, and pixel ratio settings are given in whole
- # percentages, so round to 2 digits.
- ratio = round(self._tkcanvas.tk.call('tk', 'scaling') / (96 / 72), 2)
- if self._set_device_pixel_ratio(ratio):
- # The easiest way to resize the canvas is to resize the canvas
- # widget itself, since we implement all the logic for resizing the
- # canvas backing store on that event.
- w, h = self.get_width_height(physical=True)
- self._tkcanvas.configure(width=w, height=h)
-
- def resize(self, event):
- width, height = event.width, event.height
-
- # compute desired figure size in inches
- dpival = self.figure.dpi
- winch = width / dpival
- hinch = height / dpival
- self.figure.set_size_inches(winch, hinch, forward=False)
-
- self._tkcanvas.delete(self._tkcanvas_image_region)
- self._tkphoto.configure(width=int(width), height=int(height))
- self._tkcanvas_image_region = self._tkcanvas.create_image(
- int(width / 2), int(height / 2), image=self._tkphoto)
- ResizeEvent("resize_event", self)._process()
- self.draw_idle()
-
- def draw_idle(self):
- # docstring inherited
- if self._idle_draw_id:
- return
-
- def idle_draw(*args):
- try:
- self.draw()
- finally:
- self._idle_draw_id = None
-
- self._idle_draw_id = self._tkcanvas.after_idle(idle_draw)
-
- def get_tk_widget(self):
- """
- Return the Tk widget used to implement FigureCanvasTkAgg.
-
- Although the initial implementation uses a Tk canvas, this routine
- is intended to hide that fact.
- """
- return self._tkcanvas
-
- def _event_mpl_coords(self, event):
- # calling canvasx/canvasy allows taking scrollbars into account (i.e.
- # the top of the widget may have been scrolled out of view).
- return (self._tkcanvas.canvasx(event.x),
- # flipy so y=0 is bottom of canvas
- self.figure.bbox.height - self._tkcanvas.canvasy(event.y))
-
- def motion_notify_event(self, event):
- MouseEvent("motion_notify_event", self,
- *self._event_mpl_coords(event),
- modifiers=self._mpl_modifiers(event),
- guiEvent=event)._process()
-
- def enter_notify_event(self, event):
- LocationEvent("figure_enter_event", self,
- *self._event_mpl_coords(event),
- modifiers=self._mpl_modifiers(event),
- guiEvent=event)._process()
-
- def leave_notify_event(self, event):
- LocationEvent("figure_leave_event", self,
- *self._event_mpl_coords(event),
- modifiers=self._mpl_modifiers(event),
- guiEvent=event)._process()
-
- def button_press_event(self, event, dblclick=False):
- # set focus to the canvas so that it can receive keyboard events
- self._tkcanvas.focus_set()
-
- num = getattr(event, 'num', None)
- if sys.platform == 'darwin': # 2 and 3 are reversed.
- num = {2: 3, 3: 2}.get(num, num)
- MouseEvent("button_press_event", self,
- *self._event_mpl_coords(event), num, dblclick=dblclick,
- modifiers=self._mpl_modifiers(event),
- guiEvent=event)._process()
-
- def button_dblclick_event(self, event):
- self.button_press_event(event, dblclick=True)
-
- def button_release_event(self, event):
- num = getattr(event, 'num', None)
- if sys.platform == 'darwin': # 2 and 3 are reversed.
- num = {2: 3, 3: 2}.get(num, num)
- MouseEvent("button_release_event", self,
- *self._event_mpl_coords(event), num,
- modifiers=self._mpl_modifiers(event),
- guiEvent=event)._process()
-
- def scroll_event(self, event):
- num = getattr(event, 'num', None)
- step = 1 if num == 4 else -1 if num == 5 else 0
- MouseEvent("scroll_event", self,
- *self._event_mpl_coords(event), step=step,
- modifiers=self._mpl_modifiers(event),
- guiEvent=event)._process()
-
- def scroll_event_windows(self, event):
- """MouseWheel event processor"""
- # need to find the window that contains the mouse
- w = event.widget.winfo_containing(event.x_root, event.y_root)
- if w != self._tkcanvas:
- return
- x = self._tkcanvas.canvasx(event.x_root - w.winfo_rootx())
- y = (self.figure.bbox.height
- - self._tkcanvas.canvasy(event.y_root - w.winfo_rooty()))
- step = event.delta / 120
- MouseEvent("scroll_event", self,
- x, y, step=step, modifiers=self._mpl_modifiers(event),
- guiEvent=event)._process()
-
- @staticmethod
- def _mpl_modifiers(event, *, exclude=None):
- # add modifier keys to the key string. Bit details originate from
- # http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm
- # BIT_SHIFT = 0x001; BIT_CAPSLOCK = 0x002; BIT_CONTROL = 0x004;
- # BIT_LEFT_ALT = 0x008; BIT_NUMLOCK = 0x010; BIT_RIGHT_ALT = 0x080;
- # BIT_MB_1 = 0x100; BIT_MB_2 = 0x200; BIT_MB_3 = 0x400;
- # In general, the modifier key is excluded from the modifier flag,
- # however this is not the case on "darwin", so double check that
- # we aren't adding repeat modifier flags to a modifier key.
- modifiers = [
- ("ctrl", 1 << 2, "control"),
- ("alt", 1 << 17, "alt"),
- ("shift", 1 << 0, "shift"),
- ] if sys.platform == "win32" else [
- ("ctrl", 1 << 2, "control"),
- ("alt", 1 << 4, "alt"),
- ("shift", 1 << 0, "shift"),
- ("cmd", 1 << 3, "cmd"),
- ] if sys.platform == "darwin" else [
- ("ctrl", 1 << 2, "control"),
- ("alt", 1 << 3, "alt"),
- ("shift", 1 << 0, "shift"),
- ("super", 1 << 6, "super"),
- ]
- return [name for name, mask, key in modifiers
- if event.state & mask and exclude != key]
-
- def _get_key(self, event):
- unikey = event.char
- key = cbook._unikey_or_keysym_to_mplkey(unikey, event.keysym)
- if key is not None:
- mods = self._mpl_modifiers(event, exclude=key)
- # shift is not added to the keys as this is already accounted for.
- if "shift" in mods and unikey:
- mods.remove("shift")
- return "+".join([*mods, key])
-
- def key_press(self, event):
- KeyEvent("key_press_event", self,
- self._get_key(event), *self._event_mpl_coords(event),
- guiEvent=event)._process()
-
- def key_release(self, event):
- KeyEvent("key_release_event", self,
- self._get_key(event), *self._event_mpl_coords(event),
- guiEvent=event)._process()
-
- def new_timer(self, *args, **kwargs):
- # docstring inherited
- return TimerTk(self._tkcanvas, *args, **kwargs)
-
- def flush_events(self):
- # docstring inherited
- self._tkcanvas.update()
-
- def start_event_loop(self, timeout=0):
- # docstring inherited
- if timeout > 0:
- milliseconds = int(1000 * timeout)
- if milliseconds > 0:
- self._event_loop_id = self._tkcanvas.after(
- milliseconds, self.stop_event_loop)
- else:
- self._event_loop_id = self._tkcanvas.after_idle(
- self.stop_event_loop)
- self._tkcanvas.mainloop()
-
- def stop_event_loop(self):
- # docstring inherited
- if self._event_loop_id:
- self._tkcanvas.after_cancel(self._event_loop_id)
- self._event_loop_id = None
- self._tkcanvas.quit()
-
- def set_cursor(self, cursor):
- try:
- self._tkcanvas.configure(cursor=cursord[cursor])
- except tkinter.TclError:
- pass
-
-
-class FigureManagerTk(FigureManagerBase):
- """
- Attributes
- ----------
- canvas : `FigureCanvas`
- The FigureCanvas instance
- num : int or str
- The Figure number
- toolbar : tk.Toolbar
- The tk.Toolbar
- window : tk.Window
- The tk.Window
- """
-
- _owns_mainloop = False
-
- def __init__(self, canvas, num, window):
- self.window = window
- super().__init__(canvas, num)
- self.window.withdraw()
- # packing toolbar first, because if space is getting low, last packed
- # widget is getting shrunk first (-> the canvas)
- self.canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=1)
-
- # If the window has per-monitor DPI awareness, then setup a Tk variable
- # to store the DPI, which will be updated by the C code, and the trace
- # will handle it on the Python side.
- window_frame = int(window.wm_frame(), 16)
- self._window_dpi = tk.IntVar(master=window, value=96,
- name=f'window_dpi{window_frame}')
- self._window_dpi_cbname = ''
- if _tkagg.enable_dpi_awareness(window_frame, window.tk.interpaddr()):
- self._window_dpi_cbname = self._window_dpi.trace_add(
- 'write', self._update_window_dpi)
-
- self._shown = False
-
- @classmethod
- def create_with_canvas(cls, canvas_class, figure, num):
- # docstring inherited
- with _restore_foreground_window_at_end():
- if cbook._get_running_interactive_framework() is None:
- cbook._setup_new_guiapp()
- _c_internal_utils.Win32_SetProcessDpiAwareness_max()
- window = tk.Tk(className="matplotlib")
- window.withdraw()
-
- # Put a Matplotlib icon on the window rather than the default tk
- # icon. See https://www.tcl.tk/man/tcl/TkCmd/wm.html#M50
- #
- # `ImageTk` can be replaced with `tk` whenever the minimum
- # supported Tk version is increased to 8.6, as Tk 8.6+ natively
- # supports PNG images.
- icon_fname = str(cbook._get_data_path(
- 'images/matplotlib.png'))
- icon_img = ImageTk.PhotoImage(file=icon_fname, master=window)
-
- icon_fname_large = str(cbook._get_data_path(
- 'images/matplotlib_large.png'))
- icon_img_large = ImageTk.PhotoImage(
- file=icon_fname_large, master=window)
-
- window.iconphoto(False, icon_img_large, icon_img)
-
- canvas = canvas_class(figure, master=window)
- manager = cls(canvas, num, window)
- if mpl.is_interactive():
- manager.show()
- canvas.draw_idle()
- return manager
-
- @classmethod
- def start_main_loop(cls):
- managers = Gcf.get_all_fig_managers()
- if managers:
- first_manager = managers[0]
- manager_class = type(first_manager)
- if manager_class._owns_mainloop:
- return
- manager_class._owns_mainloop = True
- try:
- first_manager.window.mainloop()
- finally:
- manager_class._owns_mainloop = False
-
- def _update_window_dpi(self, *args):
- newdpi = self._window_dpi.get()
- self.window.call('tk', 'scaling', newdpi / 72)
- if self.toolbar and hasattr(self.toolbar, '_rescale'):
- self.toolbar._rescale()
- self.canvas._update_device_pixel_ratio()
-
- def resize(self, width, height):
- max_size = 1_400_000 # the measured max on xorg 1.20.8 was 1_409_023
-
- if (width > max_size or height > max_size) and sys.platform == 'linux':
- raise ValueError(
- 'You have requested to resize the '
- f'Tk window to ({width}, {height}), one of which '
- f'is bigger than {max_size}. At larger sizes xorg will '
- 'either exit with an error on newer versions (~1.20) or '
- 'cause corruption on older version (~1.19). We '
- 'do not expect a window over a million pixel wide or tall '
- 'to be intended behavior.')
- self.canvas._tkcanvas.configure(width=width, height=height)
-
- def show(self):
- with _restore_foreground_window_at_end():
- if not self._shown:
- def destroy(*args):
- Gcf.destroy(self)
- self.window.protocol("WM_DELETE_WINDOW", destroy)
- self.window.deiconify()
- self.canvas._tkcanvas.focus_set()
- else:
- self.canvas.draw_idle()
- if mpl.rcParams['figure.raise_window']:
- self.canvas.manager.window.attributes('-topmost', 1)
- self.canvas.manager.window.attributes('-topmost', 0)
- self._shown = True
-
- def destroy(self, *args):
- if self.canvas._idle_draw_id:
- self.canvas._tkcanvas.after_cancel(self.canvas._idle_draw_id)
- if self.canvas._event_loop_id:
- self.canvas._tkcanvas.after_cancel(self.canvas._event_loop_id)
- if self._window_dpi_cbname:
- self._window_dpi.trace_remove('write', self._window_dpi_cbname)
-
- # NOTE: events need to be flushed before issuing destroy (GH #9956),
- # however, self.window.update() can break user code. An async callback
- # is the safest way to achieve a complete draining of the event queue,
- # but it leaks if no tk event loop is running. Therefore we explicitly
- # check for an event loop and choose our best guess.
- def delayed_destroy():
- self.window.destroy()
-
- if self._owns_mainloop and not Gcf.get_num_fig_managers():
- self.window.quit()
-
- if cbook._get_running_interactive_framework() == "tk":
- # "after idle after 0" avoids Tcl error/race (GH #19940)
- self.window.after_idle(self.window.after, 0, delayed_destroy)
- else:
- self.window.update()
- delayed_destroy()
-
- def get_window_title(self):
- return self.window.wm_title()
-
- def set_window_title(self, title):
- self.window.wm_title(title)
-
- def full_screen_toggle(self):
- is_fullscreen = bool(self.window.attributes('-fullscreen'))
- self.window.attributes('-fullscreen', not is_fullscreen)
-
-
-class NavigationToolbar2Tk(NavigationToolbar2, tk.Frame):
- def __init__(self, canvas, window=None, *, pack_toolbar=True):
- """
- Parameters
- ----------
- canvas : `FigureCanvas`
- The figure canvas on which to operate.
- window : tk.Window
- The tk.Window which owns this toolbar.
- pack_toolbar : bool, default: True
- If True, add the toolbar to the parent's pack manager's packing
- list during initialization with ``side="bottom"`` and ``fill="x"``.
- If you want to use the toolbar with a different layout manager, use
- ``pack_toolbar=False``.
- """
-
- if window is None:
- window = canvas.get_tk_widget().master
- tk.Frame.__init__(self, master=window, borderwidth=2,
- width=int(canvas.figure.bbox.width), height=50)
-
- self._buttons = {}
- for text, tooltip_text, image_file, callback in self.toolitems:
- if text is None:
- # Add a spacer; return value is unused.
- self._Spacer()
- else:
- self._buttons[text] = button = self._Button(
- text,
- str(cbook._get_data_path(f"images/{image_file}.png")),
- toggle=callback in ["zoom", "pan"],
- command=getattr(self, callback),
- )
- if tooltip_text is not None:
- ToolTip.createToolTip(button, tooltip_text)
-
- self._label_font = tkinter.font.Font(root=window, size=10)
-
- # This filler item ensures the toolbar is always at least two text
- # lines high. Otherwise the canvas gets redrawn as the mouse hovers
- # over images because those use two-line messages which resize the
- # toolbar.
- label = tk.Label(master=self, font=self._label_font,
- text='\N{NO-BREAK SPACE}\n\N{NO-BREAK SPACE}')
- label.pack(side=tk.RIGHT)
-
- self.message = tk.StringVar(master=self)
- self._message_label = tk.Label(master=self, font=self._label_font,
- textvariable=self.message,
- justify=tk.RIGHT)
- self._message_label.pack(side=tk.RIGHT)
-
- NavigationToolbar2.__init__(self, canvas)
- if pack_toolbar:
- self.pack(side=tk.BOTTOM, fill=tk.X)
-
- def _rescale(self):
- """
- Scale all children of the toolbar to current DPI setting.
-
- Before this is called, the Tk scaling setting will have been updated to
- match the new DPI. Tk widgets do not update for changes to scaling, but
- all measurements made after the change will match the new scaling. Thus
- this function re-applies all the same sizes in points, which Tk will
- scale correctly to pixels.
- """
- for widget in self.winfo_children():
- if isinstance(widget, (tk.Button, tk.Checkbutton)):
- if hasattr(widget, '_image_file'):
- # Explicit class because ToolbarTk calls _rescale.
- NavigationToolbar2Tk._set_image_for_button(self, widget)
- else:
- # Text-only button is handled by the font setting instead.
- pass
- elif isinstance(widget, tk.Frame):
- widget.configure(height='18p')
- widget.pack_configure(padx='3p')
- elif isinstance(widget, tk.Label):
- pass # Text is handled by the font setting instead.
- else:
- _log.warning('Unknown child class %s', widget.winfo_class)
- self._label_font.configure(size=10)
-
- def _update_buttons_checked(self):
- # sync button checkstates to match active mode
- for text, mode in [('Zoom', _Mode.ZOOM), ('Pan', _Mode.PAN)]:
- if text in self._buttons:
- if self.mode == mode:
- self._buttons[text].select() # NOT .invoke()
- else:
- self._buttons[text].deselect()
-
- def pan(self, *args):
- super().pan(*args)
- self._update_buttons_checked()
-
- def zoom(self, *args):
- super().zoom(*args)
- self._update_buttons_checked()
-
- def set_message(self, s):
- self.message.set(s)
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- # Block copied from remove_rubberband for backend_tools convenience.
- if self.canvas._rubberband_rect_white:
- self.canvas._tkcanvas.delete(self.canvas._rubberband_rect_white)
- if self.canvas._rubberband_rect_black:
- self.canvas._tkcanvas.delete(self.canvas._rubberband_rect_black)
- height = self.canvas.figure.bbox.height
- y0 = height - y0
- y1 = height - y1
- self.canvas._rubberband_rect_black = (
- self.canvas._tkcanvas.create_rectangle(
- x0, y0, x1, y1))
- self.canvas._rubberband_rect_white = (
- self.canvas._tkcanvas.create_rectangle(
- x0, y0, x1, y1, outline='white', dash=(3, 3)))
-
- def remove_rubberband(self):
- if self.canvas._rubberband_rect_white:
- self.canvas._tkcanvas.delete(self.canvas._rubberband_rect_white)
- self.canvas._rubberband_rect_white = None
- if self.canvas._rubberband_rect_black:
- self.canvas._tkcanvas.delete(self.canvas._rubberband_rect_black)
- self.canvas._rubberband_rect_black = None
-
- def _set_image_for_button(self, button):
- """
- Set the image for a button based on its pixel size.
-
- The pixel size is determined by the DPI scaling of the window.
- """
- if button._image_file is None:
- return
-
- # Allow _image_file to be relative to Matplotlib's "images" data
- # directory.
- path_regular = cbook._get_data_path('images', button._image_file)
- path_large = path_regular.with_name(
- path_regular.name.replace('.png', '_large.png'))
- size = button.winfo_pixels('18p')
-
- # Nested functions because ToolbarTk calls _Button.
- def _get_color(color_name):
- # `winfo_rgb` returns an (r, g, b) tuple in the range 0-65535
- return button.winfo_rgb(button.cget(color_name))
-
- def _is_dark(color):
- if isinstance(color, str):
- color = _get_color(color)
- return max(color) < 65535 / 2
-
- def _recolor_icon(image, color):
- image_data = np.asarray(image).copy()
- black_mask = (image_data[..., :3] == 0).all(axis=-1)
- image_data[black_mask, :3] = color
- return Image.fromarray(image_data, mode="RGBA")
-
- # Use the high-resolution (48x48 px) icon if it exists and is needed
- with Image.open(path_large if (size > 24 and path_large.exists())
- else path_regular) as im:
- # assure a RGBA image as foreground color is RGB
- im = im.convert("RGBA")
- image = ImageTk.PhotoImage(im.resize((size, size)), master=self)
- button._ntimage = image
-
- # create a version of the icon with the button's text color
- foreground = (255 / 65535) * np.array(
- button.winfo_rgb(button.cget("foreground")))
- im_alt = _recolor_icon(im, foreground)
- image_alt = ImageTk.PhotoImage(
- im_alt.resize((size, size)), master=self)
- button._ntimage_alt = image_alt
-
- if _is_dark("background"):
- # For Checkbuttons, we need to set `image` and `selectimage` at
- # the same time. Otherwise, when updating the `image` option
- # (such as when changing DPI), if the old `selectimage` has
- # just been overwritten, Tk will throw an error.
- image_kwargs = {"image": image_alt}
- else:
- image_kwargs = {"image": image}
- # Checkbuttons may switch the background to `selectcolor` in the
- # checked state, so check separately which image it needs to use in
- # that state to still ensure enough contrast with the background.
- if (
- isinstance(button, tk.Checkbutton)
- and button.cget("selectcolor") != ""
- ):
- if self._windowingsystem != "x11":
- selectcolor = "selectcolor"
- else:
- # On X11, selectcolor isn't used directly for indicator-less
- # buttons. See `::tk::CheckEnter` in the Tk button.tcl source
- # code for details.
- r1, g1, b1 = _get_color("selectcolor")
- r2, g2, b2 = _get_color("activebackground")
- selectcolor = ((r1+r2)/2, (g1+g2)/2, (b1+b2)/2)
- if _is_dark(selectcolor):
- image_kwargs["selectimage"] = image_alt
- else:
- image_kwargs["selectimage"] = image
-
- button.configure(**image_kwargs, height='18p', width='18p')
-
- def _Button(self, text, image_file, toggle, command):
- if not toggle:
- b = tk.Button(
- master=self, text=text, command=command,
- relief="flat", overrelief="groove", borderwidth=1,
- )
- else:
- # There is a bug in tkinter included in some python 3.6 versions
- # that without this variable, produces a "visual" toggling of
- # other near checkbuttons
- # https://bugs.python.org/issue29402
- # https://bugs.python.org/issue25684
- var = tk.IntVar(master=self)
- b = tk.Checkbutton(
- master=self, text=text, command=command, indicatoron=False,
- variable=var, offrelief="flat", overrelief="groove",
- borderwidth=1
- )
- b.var = var
- b._image_file = image_file
- if image_file is not None:
- # Explicit class because ToolbarTk calls _Button.
- NavigationToolbar2Tk._set_image_for_button(self, b)
- else:
- b.configure(font=self._label_font)
- b.pack(side=tk.LEFT)
- return b
-
- def _Spacer(self):
- # Buttons are also 18pt high.
- s = tk.Frame(master=self, height='18p', relief=tk.RIDGE, bg='DarkGray')
- s.pack(side=tk.LEFT, padx='3p')
- return s
-
- def save_figure(self, *args):
- filetypes = self.canvas.get_supported_filetypes_grouped()
- tk_filetypes = [
- (name, " ".join(f"*.{ext}" for ext in exts))
- for name, exts in sorted(filetypes.items())
- ]
-
- default_extension = self.canvas.get_default_filetype()
- default_filetype = self.canvas.get_supported_filetypes()[default_extension]
- filetype_variable = tk.StringVar(self, default_filetype)
-
- # adding a default extension seems to break the
- # asksaveasfilename dialog when you choose various save types
- # from the dropdown. Passing in the empty string seems to
- # work - JDH!
- # defaultextension = self.canvas.get_default_filetype()
- defaultextension = ''
- initialdir = os.path.expanduser(mpl.rcParams['savefig.directory'])
- # get_default_filename() contains the default extension. On some platforms,
- # choosing a different extension from the dropdown does not overwrite it,
- # so we need to remove it to make the dropdown functional.
- initialfile = pathlib.Path(self.canvas.get_default_filename()).stem
- fname = tkinter.filedialog.asksaveasfilename(
- master=self.canvas.get_tk_widget().master,
- title='Save the figure',
- filetypes=tk_filetypes,
- defaultextension=defaultextension,
- initialdir=initialdir,
- initialfile=initialfile,
- typevariable=filetype_variable
- )
-
- if fname in ["", ()]:
- return
- # Save dir for next time, unless empty str (i.e., use cwd).
- if initialdir != "":
- mpl.rcParams['savefig.directory'] = (
- os.path.dirname(str(fname)))
-
- # If the filename contains an extension, let savefig() infer the file
- # format from that. If it does not, use the selected dropdown option.
- if pathlib.Path(fname).suffix[1:] != "":
- extension = None
- else:
- extension = filetypes[filetype_variable.get()][0]
-
- try:
- self.canvas.figure.savefig(fname, format=extension)
- except Exception as e:
- tkinter.messagebox.showerror("Error saving file", str(e))
-
- def set_history_buttons(self):
- state_map = {True: tk.NORMAL, False: tk.DISABLED}
- can_back = self._nav_stack._pos > 0
- can_forward = self._nav_stack._pos < len(self._nav_stack) - 1
-
- if "Back" in self._buttons:
- self._buttons['Back']['state'] = state_map[can_back]
-
- if "Forward" in self._buttons:
- self._buttons['Forward']['state'] = state_map[can_forward]
-
-
-class ToolTip:
- """
- Tooltip recipe from
- http://www.voidspace.org.uk/python/weblog/arch_d7_2006_07_01.shtml#e387
- """
- @staticmethod
- def createToolTip(widget, text):
- toolTip = ToolTip(widget)
- def enter(event):
- toolTip.showtip(text)
- def leave(event):
- toolTip.hidetip()
- widget.bind('<Enter>', enter)
- widget.bind('<Leave>', leave)
-
- def __init__(self, widget):
- self.widget = widget
- self.tipwindow = None
- self.id = None
- self.x = self.y = 0
-
- def showtip(self, text):
- """Display text in tooltip window."""
- self.text = text
- if self.tipwindow or not self.text:
- return
- x, y, _, _ = self.widget.bbox("insert")
- x = x + self.widget.winfo_rootx() + self.widget.winfo_width()
- y = y + self.widget.winfo_rooty()
- self.tipwindow = tw = tk.Toplevel(self.widget)
- tw.wm_overrideredirect(1)
- tw.wm_geometry("+%d+%d" % (x, y))
- try:
- # For Mac OS
- tw.tk.call("::tk::unsupported::MacWindowStyle",
- "style", tw._w,
- "help", "noActivates")
- except tk.TclError:
- pass
- label = tk.Label(tw, text=self.text, justify=tk.LEFT,
- relief=tk.SOLID, borderwidth=1)
- label.pack(ipadx=1)
-
- def hidetip(self):
- tw = self.tipwindow
- self.tipwindow = None
- if tw:
- tw.destroy()
-
-
-@backend_tools._register_tool_class(FigureCanvasTk)
-class RubberbandTk(backend_tools.RubberbandBase):
- def draw_rubberband(self, x0, y0, x1, y1):
- NavigationToolbar2Tk.draw_rubberband(
- self._make_classic_style_pseudo_toolbar(), None, x0, y0, x1, y1)
-
- def remove_rubberband(self):
- NavigationToolbar2Tk.remove_rubberband(
- self._make_classic_style_pseudo_toolbar())
-
-
-class ToolbarTk(ToolContainerBase, tk.Frame):
- def __init__(self, toolmanager, window=None):
- ToolContainerBase.__init__(self, toolmanager)
- if window is None:
- window = self.toolmanager.canvas.get_tk_widget().master
- xmin, xmax = self.toolmanager.canvas.figure.bbox.intervalx
- height, width = 50, xmax - xmin
- tk.Frame.__init__(self, master=window,
- width=int(width), height=int(height),
- borderwidth=2)
- self._label_font = tkinter.font.Font(size=10)
- # This filler item ensures the toolbar is always at least two text
- # lines high. Otherwise the canvas gets redrawn as the mouse hovers
- # over images because those use two-line messages which resize the
- # toolbar.
- label = tk.Label(master=self, font=self._label_font,
- text='\N{NO-BREAK SPACE}\n\N{NO-BREAK SPACE}')
- label.pack(side=tk.RIGHT)
- self._message = tk.StringVar(master=self)
- self._message_label = tk.Label(master=self, font=self._label_font,
- textvariable=self._message)
- self._message_label.pack(side=tk.RIGHT)
- self._toolitems = {}
- self.pack(side=tk.TOP, fill=tk.X)
- self._groups = {}
-
- def _rescale(self):
- return NavigationToolbar2Tk._rescale(self)
-
- def add_toolitem(
- self, name, group, position, image_file, description, toggle):
- frame = self._get_groupframe(group)
- buttons = frame.pack_slaves()
- if position >= len(buttons) or position < 0:
- before = None
- else:
- before = buttons[position]
- button = NavigationToolbar2Tk._Button(frame, name, image_file, toggle,
- lambda: self._button_click(name))
- button.pack_configure(before=before)
- if description is not None:
- ToolTip.createToolTip(button, description)
- self._toolitems.setdefault(name, [])
- self._toolitems[name].append(button)
-
- def _get_groupframe(self, group):
- if group not in self._groups:
- if self._groups:
- self._add_separator()
- frame = tk.Frame(master=self, borderwidth=0)
- frame.pack(side=tk.LEFT, fill=tk.Y)
- frame._label_font = self._label_font
- self._groups[group] = frame
- return self._groups[group]
-
- def _add_separator(self):
- return NavigationToolbar2Tk._Spacer(self)
-
- def _button_click(self, name):
- self.trigger_tool(name)
-
- def toggle_toolitem(self, name, toggled):
- if name not in self._toolitems:
- return
- for toolitem in self._toolitems[name]:
- if toggled:
- toolitem.select()
- else:
- toolitem.deselect()
-
- def remove_toolitem(self, name):
- for toolitem in self._toolitems[name]:
- toolitem.pack_forget()
- del self._toolitems[name]
-
- def set_message(self, s):
- self._message.set(s)
-
-
-@backend_tools._register_tool_class(FigureCanvasTk)
-class SaveFigureTk(backend_tools.SaveFigureBase):
- def trigger(self, *args):
- NavigationToolbar2Tk.save_figure(
- self._make_classic_style_pseudo_toolbar())
-
-
-@backend_tools._register_tool_class(FigureCanvasTk)
-class ConfigureSubplotsTk(backend_tools.ConfigureSubplotsBase):
- def trigger(self, *args):
- NavigationToolbar2Tk.configure_subplots(self)
-
-
-@backend_tools._register_tool_class(FigureCanvasTk)
-class HelpTk(backend_tools.ToolHelpBase):
- def trigger(self, *args):
- dialog = SimpleDialog(
- self.figure.canvas._tkcanvas, self._get_help_text(), ["OK"])
- dialog.done = lambda num: dialog.frame.master.withdraw()
-
-
-Toolbar = ToolbarTk
-FigureManagerTk._toolbar2_class = NavigationToolbar2Tk
-FigureManagerTk._toolmanager_toolbar_class = ToolbarTk
-
-
-@_Backend.export
-class _BackendTk(_Backend):
- backend_version = tk.TkVersion
- FigureCanvas = FigureCanvasTk
- FigureManager = FigureManagerTk
- mainloop = FigureManagerTk.start_main_loop
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/_macosx.pyi b/contrib/python/matplotlib/py3/matplotlib/backends/_macosx.pyi
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/_macosx.pyi
+++ /dev/null
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/_tkagg.pyi b/contrib/python/matplotlib/py3/matplotlib/backends/_tkagg.pyi
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/_tkagg.pyi
+++ /dev/null
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_agg.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_agg.py
deleted file mode 100644
index 470ce9d925..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_agg.py
+++ /dev/null
@@ -1,544 +0,0 @@
-"""
-An `Anti-Grain Geometry`_ (AGG) backend.
-
-Features that are implemented:
-
-* capstyles and join styles
-* dashes
-* linewidth
-* lines, rectangles, ellipses
-* clipping to a rectangle
-* output to RGBA and Pillow-supported image formats
-* alpha blending
-* DPI scaling properly - everything scales properly (dashes, linewidths, etc)
-* draw polygon
-* freetype2 w/ ft2font
-
-Still TODO:
-
-* integrate screen dpi w/ ppi and text
-
-.. _Anti-Grain Geometry: http://agg.sourceforge.net/antigrain.com
-"""
-
-from contextlib import nullcontext
-from math import radians, cos, sin
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, cbook
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, RendererBase)
-from matplotlib.font_manager import fontManager as _fontManager, get_font
-from matplotlib.ft2font import (LOAD_FORCE_AUTOHINT, LOAD_NO_HINTING,
- LOAD_DEFAULT, LOAD_NO_AUTOHINT)
-from matplotlib.mathtext import MathTextParser
-from matplotlib.path import Path
-from matplotlib.transforms import Bbox, BboxBase
-from matplotlib.backends._backend_agg import RendererAgg as _RendererAgg
-
-
-def get_hinting_flag():
- mapping = {
- 'default': LOAD_DEFAULT,
- 'no_autohint': LOAD_NO_AUTOHINT,
- 'force_autohint': LOAD_FORCE_AUTOHINT,
- 'no_hinting': LOAD_NO_HINTING,
- True: LOAD_FORCE_AUTOHINT,
- False: LOAD_NO_HINTING,
- 'either': LOAD_DEFAULT,
- 'native': LOAD_NO_AUTOHINT,
- 'auto': LOAD_FORCE_AUTOHINT,
- 'none': LOAD_NO_HINTING,
- }
- return mapping[mpl.rcParams['text.hinting']]
-
-
-class RendererAgg(RendererBase):
- """
- The renderer handles all the drawing primitives using a graphics
- context instance that controls the colors/styles
- """
-
- def __init__(self, width, height, dpi):
- super().__init__()
-
- self.dpi = dpi
- self.width = width
- self.height = height
- self._renderer = _RendererAgg(int(width), int(height), dpi)
- self._filter_renderers = []
-
- self._update_methods()
- self.mathtext_parser = MathTextParser('agg')
-
- self.bbox = Bbox.from_bounds(0, 0, self.width, self.height)
-
- def __getstate__(self):
- # We only want to preserve the init keywords of the Renderer.
- # Anything else can be re-created.
- return {'width': self.width, 'height': self.height, 'dpi': self.dpi}
-
- def __setstate__(self, state):
- self.__init__(state['width'], state['height'], state['dpi'])
-
- def _update_methods(self):
- self.draw_gouraud_triangle = self._renderer.draw_gouraud_triangle
- self.draw_gouraud_triangles = self._renderer.draw_gouraud_triangles
- self.draw_image = self._renderer.draw_image
- self.draw_markers = self._renderer.draw_markers
- self.draw_path_collection = self._renderer.draw_path_collection
- self.draw_quad_mesh = self._renderer.draw_quad_mesh
- self.copy_from_bbox = self._renderer.copy_from_bbox
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- # docstring inherited
- nmax = mpl.rcParams['agg.path.chunksize'] # here at least for testing
- npts = path.vertices.shape[0]
-
- if (npts > nmax > 100 and path.should_simplify and
- rgbFace is None and gc.get_hatch() is None):
- nch = np.ceil(npts / nmax)
- chsize = int(np.ceil(npts / nch))
- i0 = np.arange(0, npts, chsize)
- i1 = np.zeros_like(i0)
- i1[:-1] = i0[1:] - 1
- i1[-1] = npts
- for ii0, ii1 in zip(i0, i1):
- v = path.vertices[ii0:ii1, :]
- c = path.codes
- if c is not None:
- c = c[ii0:ii1]
- c[0] = Path.MOVETO # move to end of last chunk
- p = Path(v, c)
- p.simplify_threshold = path.simplify_threshold
- try:
- self._renderer.draw_path(gc, p, transform, rgbFace)
- except OverflowError:
- msg = (
- "Exceeded cell block limit in Agg.\n\n"
- "Please reduce the value of "
- f"rcParams['agg.path.chunksize'] (currently {nmax}) "
- "or increase the path simplification threshold"
- "(rcParams['path.simplify_threshold'] = "
- f"{mpl.rcParams['path.simplify_threshold']:.2f} by "
- "default and path.simplify_threshold = "
- f"{path.simplify_threshold:.2f} on the input)."
- )
- raise OverflowError(msg) from None
- else:
- try:
- self._renderer.draw_path(gc, path, transform, rgbFace)
- except OverflowError:
- cant_chunk = ''
- if rgbFace is not None:
- cant_chunk += "- cannot split filled path\n"
- if gc.get_hatch() is not None:
- cant_chunk += "- cannot split hatched path\n"
- if not path.should_simplify:
- cant_chunk += "- path.should_simplify is False\n"
- if len(cant_chunk):
- msg = (
- "Exceeded cell block limit in Agg, however for the "
- "following reasons:\n\n"
- f"{cant_chunk}\n"
- "we cannot automatically split up this path to draw."
- "\n\nPlease manually simplify your path."
- )
-
- else:
- inc_threshold = (
- "or increase the path simplification threshold"
- "(rcParams['path.simplify_threshold'] = "
- f"{mpl.rcParams['path.simplify_threshold']} "
- "by default and path.simplify_threshold "
- f"= {path.simplify_threshold} "
- "on the input)."
- )
- if nmax > 100:
- msg = (
- "Exceeded cell block limit in Agg. Please reduce "
- "the value of rcParams['agg.path.chunksize'] "
- f"(currently {nmax}) {inc_threshold}"
- )
- else:
- msg = (
- "Exceeded cell block limit in Agg. Please set "
- "the value of rcParams['agg.path.chunksize'], "
- f"(currently {nmax}) to be greater than 100 "
- + inc_threshold
- )
-
- raise OverflowError(msg) from None
-
- def draw_mathtext(self, gc, x, y, s, prop, angle):
- """Draw mathtext using :mod:`matplotlib.mathtext`."""
- ox, oy, width, height, descent, font_image = \
- self.mathtext_parser.parse(s, self.dpi, prop,
- antialiased=gc.get_antialiased())
-
- xd = descent * sin(radians(angle))
- yd = descent * cos(radians(angle))
- x = round(x + ox + xd)
- y = round(y - oy + yd)
- self._renderer.draw_text_image(font_image, x, y + 1, angle, gc)
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- # docstring inherited
- if ismath:
- return self.draw_mathtext(gc, x, y, s, prop, angle)
- font = self._prepare_font(prop)
- # We pass '0' for angle here, since it will be rotated (in raster
- # space) in the following call to draw_text_image).
- font.set_text(s, 0, flags=get_hinting_flag())
- font.draw_glyphs_to_bitmap(
- antialiased=gc.get_antialiased())
- d = font.get_descent() / 64.0
- # The descent needs to be adjusted for the angle.
- xo, yo = font.get_bitmap_offset()
- xo /= 64.0
- yo /= 64.0
- xd = d * sin(radians(angle))
- yd = d * cos(radians(angle))
- x = round(x + xo + xd)
- y = round(y + yo + yd)
- self._renderer.draw_text_image(font, x, y + 1, angle, gc)
-
- def get_text_width_height_descent(self, s, prop, ismath):
- # docstring inherited
-
- _api.check_in_list(["TeX", True, False], ismath=ismath)
- if ismath == "TeX":
- return super().get_text_width_height_descent(s, prop, ismath)
-
- if ismath:
- ox, oy, width, height, descent, font_image = \
- self.mathtext_parser.parse(s, self.dpi, prop)
- return width, height, descent
-
- font = self._prepare_font(prop)
- font.set_text(s, 0.0, flags=get_hinting_flag())
- w, h = font.get_width_height() # width and height of unrotated string
- d = font.get_descent()
- w /= 64.0 # convert from subpixels
- h /= 64.0
- d /= 64.0
- return w, h, d
-
- def draw_tex(self, gc, x, y, s, prop, angle, *, mtext=None):
- # docstring inherited
- # todo, handle props, angle, origins
- size = prop.get_size_in_points()
-
- texmanager = self.get_texmanager()
-
- Z = texmanager.get_grey(s, size, self.dpi)
- Z = np.array(Z * 255.0, np.uint8)
-
- w, h, d = self.get_text_width_height_descent(s, prop, ismath="TeX")
- xd = d * sin(radians(angle))
- yd = d * cos(radians(angle))
- x = round(x + xd)
- y = round(y + yd)
- self._renderer.draw_text_image(Z, x, y, angle, gc)
-
- def get_canvas_width_height(self):
- # docstring inherited
- return self.width, self.height
-
- def _prepare_font(self, font_prop):
- """
- Get the `.FT2Font` for *font_prop*, clear its buffer, and set its size.
- """
- font = get_font(_fontManager._find_fonts_by_props(font_prop))
- font.clear()
- size = font_prop.get_size_in_points()
- font.set_size(size, self.dpi)
- return font
-
- def points_to_pixels(self, points):
- # docstring inherited
- return points * self.dpi / 72
-
- def buffer_rgba(self):
- return memoryview(self._renderer)
-
- def tostring_argb(self):
- return np.asarray(self._renderer).take([3, 0, 1, 2], axis=2).tobytes()
-
- @_api.deprecated("3.8", alternative="buffer_rgba")
- def tostring_rgb(self):
- return np.asarray(self._renderer).take([0, 1, 2], axis=2).tobytes()
-
- def clear(self):
- self._renderer.clear()
-
- def option_image_nocomposite(self):
- # docstring inherited
-
- # It is generally faster to composite each image directly to
- # the Figure, and there's no file size benefit to compositing
- # with the Agg backend
- return True
-
- def option_scale_image(self):
- # docstring inherited
- return False
-
- def restore_region(self, region, bbox=None, xy=None):
- """
- Restore the saved region. If bbox (instance of BboxBase, or
- its extents) is given, only the region specified by the bbox
- will be restored. *xy* (a pair of floats) optionally
- specifies the new position (the LLC of the original region,
- not the LLC of the bbox) where the region will be restored.
-
- >>> region = renderer.copy_from_bbox()
- >>> x1, y1, x2, y2 = region.get_extents()
- >>> renderer.restore_region(region, bbox=(x1+dx, y1, x2, y2),
- ... xy=(x1-dx, y1))
-
- """
- if bbox is not None or xy is not None:
- if bbox is None:
- x1, y1, x2, y2 = region.get_extents()
- elif isinstance(bbox, BboxBase):
- x1, y1, x2, y2 = bbox.extents
- else:
- x1, y1, x2, y2 = bbox
-
- if xy is None:
- ox, oy = x1, y1
- else:
- ox, oy = xy
-
- # The incoming data is float, but the _renderer type-checking wants
- # to see integers.
- self._renderer.restore_region(region, int(x1), int(y1),
- int(x2), int(y2), int(ox), int(oy))
-
- else:
- self._renderer.restore_region(region)
-
- def start_filter(self):
- """
- Start filtering. It simply creates a new canvas (the old one is saved).
- """
- self._filter_renderers.append(self._renderer)
- self._renderer = _RendererAgg(int(self.width), int(self.height),
- self.dpi)
- self._update_methods()
-
- def stop_filter(self, post_processing):
- """
- Save the current canvas as an image and apply post processing.
-
- The *post_processing* function::
-
- def post_processing(image, dpi):
- # ny, nx, depth = image.shape
- # image (numpy array) has RGBA channels and has a depth of 4.
- ...
- # create a new_image (numpy array of 4 channels, size can be
- # different). The resulting image may have offsets from
- # lower-left corner of the original image
- return new_image, offset_x, offset_y
-
- The saved renderer is restored and the returned image from
- post_processing is plotted (using draw_image) on it.
- """
- orig_img = np.asarray(self.buffer_rgba())
- slice_y, slice_x = cbook._get_nonzero_slices(orig_img[..., 3])
- cropped_img = orig_img[slice_y, slice_x]
-
- self._renderer = self._filter_renderers.pop()
- self._update_methods()
-
- if cropped_img.size:
- img, ox, oy = post_processing(cropped_img / 255, self.dpi)
- gc = self.new_gc()
- if img.dtype.kind == 'f':
- img = np.asarray(img * 255., np.uint8)
- self._renderer.draw_image(
- gc, slice_x.start + ox, int(self.height) - slice_y.stop + oy,
- img[::-1])
-
-
-class FigureCanvasAgg(FigureCanvasBase):
- # docstring inherited
-
- _lastKey = None # Overwritten per-instance on the first draw.
-
- def copy_from_bbox(self, bbox):
- renderer = self.get_renderer()
- return renderer.copy_from_bbox(bbox)
-
- def restore_region(self, region, bbox=None, xy=None):
- renderer = self.get_renderer()
- return renderer.restore_region(region, bbox, xy)
-
- def draw(self):
- # docstring inherited
- self.renderer = self.get_renderer()
- self.renderer.clear()
- # Acquire a lock on the shared font cache.
- with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
- else nullcontext()):
- self.figure.draw(self.renderer)
- # A GUI class may be need to update a window using this draw, so
- # don't forget to call the superclass.
- super().draw()
-
- def get_renderer(self):
- w, h = self.figure.bbox.size
- key = w, h, self.figure.dpi
- reuse_renderer = (self._lastKey == key)
- if not reuse_renderer:
- self.renderer = RendererAgg(w, h, self.figure.dpi)
- self._lastKey = key
- return self.renderer
-
- @_api.deprecated("3.8", alternative="buffer_rgba")
- def tostring_rgb(self):
- """
- Get the image as RGB `bytes`.
-
- `draw` must be called at least once before this function will work and
- to update the renderer for any subsequent changes to the Figure.
- """
- return self.renderer.tostring_rgb()
-
- def tostring_argb(self):
- """
- Get the image as ARGB `bytes`.
-
- `draw` must be called at least once before this function will work and
- to update the renderer for any subsequent changes to the Figure.
- """
- return self.renderer.tostring_argb()
-
- def buffer_rgba(self):
- """
- Get the image as a `memoryview` to the renderer's buffer.
-
- `draw` must be called at least once before this function will work and
- to update the renderer for any subsequent changes to the Figure.
- """
- return self.renderer.buffer_rgba()
-
- def print_raw(self, filename_or_obj, *, metadata=None):
- if metadata is not None:
- raise ValueError("metadata not supported for raw/rgba")
- FigureCanvasAgg.draw(self)
- renderer = self.get_renderer()
- with cbook.open_file_cm(filename_or_obj, "wb") as fh:
- fh.write(renderer.buffer_rgba())
-
- print_rgba = print_raw
-
- def _print_pil(self, filename_or_obj, fmt, pil_kwargs, metadata=None):
- """
- Draw the canvas, then save it using `.image.imsave` (to which
- *pil_kwargs* and *metadata* are forwarded).
- """
- FigureCanvasAgg.draw(self)
- mpl.image.imsave(
- filename_or_obj, self.buffer_rgba(), format=fmt, origin="upper",
- dpi=self.figure.dpi, metadata=metadata, pil_kwargs=pil_kwargs)
-
- def print_png(self, filename_or_obj, *, metadata=None, pil_kwargs=None):
- """
- Write the figure to a PNG file.
-
- Parameters
- ----------
- filename_or_obj : str or path-like or file-like
- The file to write to.
-
- metadata : dict, optional
- Metadata in the PNG file as key-value pairs of bytes or latin-1
- encodable strings.
- According to the PNG specification, keys must be shorter than 79
- chars.
-
- The `PNG specification`_ defines some common keywords that may be
- used as appropriate:
-
- - Title: Short (one line) title or caption for image.
- - Author: Name of image's creator.
- - Description: Description of image (possibly long).
- - Copyright: Copyright notice.
- - Creation Time: Time of original image creation
- (usually RFC 1123 format).
- - Software: Software used to create the image.
- - Disclaimer: Legal disclaimer.
- - Warning: Warning of nature of content.
- - Source: Device used to create the image.
- - Comment: Miscellaneous comment;
- conversion from other image format.
-
- Other keywords may be invented for other purposes.
-
- If 'Software' is not given, an autogenerated value for Matplotlib
- will be used. This can be removed by setting it to *None*.
-
- For more details see the `PNG specification`_.
-
- .. _PNG specification: \
- https://www.w3.org/TR/2003/REC-PNG-20031110/#11keywords
-
- pil_kwargs : dict, optional
- Keyword arguments passed to `PIL.Image.Image.save`.
-
- If the 'pnginfo' key is present, it completely overrides
- *metadata*, including the default 'Software' key.
- """
- self._print_pil(filename_or_obj, "png", pil_kwargs, metadata)
-
- def print_to_buffer(self):
- FigureCanvasAgg.draw(self)
- renderer = self.get_renderer()
- return (bytes(renderer.buffer_rgba()),
- (int(renderer.width), int(renderer.height)))
-
- # Note that these methods should typically be called via savefig() and
- # print_figure(), and the latter ensures that `self.figure.dpi` already
- # matches the dpi kwarg (if any).
-
- def print_jpg(self, filename_or_obj, *, metadata=None, pil_kwargs=None):
- # savefig() has already applied savefig.facecolor; we now set it to
- # white to make imsave() blend semi-transparent figures against an
- # assumed white background.
- with mpl.rc_context({"savefig.facecolor": "white"}):
- self._print_pil(filename_or_obj, "jpeg", pil_kwargs, metadata)
-
- print_jpeg = print_jpg
-
- def print_tif(self, filename_or_obj, *, metadata=None, pil_kwargs=None):
- self._print_pil(filename_or_obj, "tiff", pil_kwargs, metadata)
-
- print_tiff = print_tif
-
- def print_webp(self, filename_or_obj, *, metadata=None, pil_kwargs=None):
- self._print_pil(filename_or_obj, "webp", pil_kwargs, metadata)
-
- print_jpg.__doc__, print_tif.__doc__, print_webp.__doc__ = map(
- """
- Write the figure to a {} file.
-
- Parameters
- ----------
- filename_or_obj : str or path-like or file-like
- The file to write to.
- pil_kwargs : dict, optional
- Additional keyword arguments that are passed to
- `PIL.Image.Image.save` when saving the figure.
- """.format, ["JPEG", "TIFF", "WebP"])
-
-
-@_Backend.export
-class _BackendAgg(_Backend):
- backend_version = 'v2.2'
- FigureCanvas = FigureCanvasAgg
- FigureManager = FigureManagerBase
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_cairo.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_cairo.py
deleted file mode 100644
index 421d857b0a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_cairo.py
+++ /dev/null
@@ -1,500 +0,0 @@
-"""
-A Cairo backend for Matplotlib
-==============================
-:Author: Steve Chaplin and others
-
-This backend depends on cairocffi or pycairo.
-"""
-
-import functools
-import gzip
-import math
-
-import numpy as np
-
-try:
- import cairo
- if cairo.version_info < (1, 14, 0): # Introduced set_device_scale.
- raise ImportError(f"Cairo backend requires cairo>=1.14.0, "
- f"but only {cairo.version_info} is available")
-except ImportError:
- try:
- import cairocffi as cairo
- except ImportError as err:
- raise ImportError(
- "cairo backend requires that pycairo>=1.14.0 or cairocffi "
- "is installed") from err
-
-from .. import _api, cbook, font_manager
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase,
- RendererBase)
-from matplotlib.font_manager import ttfFontProperty
-from matplotlib.path import Path
-from matplotlib.transforms import Affine2D
-
-
-def _append_path(ctx, path, transform, clip=None):
- for points, code in path.iter_segments(
- transform, remove_nans=True, clip=clip):
- if code == Path.MOVETO:
- ctx.move_to(*points)
- elif code == Path.CLOSEPOLY:
- ctx.close_path()
- elif code == Path.LINETO:
- ctx.line_to(*points)
- elif code == Path.CURVE3:
- cur = np.asarray(ctx.get_current_point())
- a = points[:2]
- b = points[-2:]
- ctx.curve_to(*(cur / 3 + a * 2 / 3), *(a * 2 / 3 + b / 3), *b)
- elif code == Path.CURVE4:
- ctx.curve_to(*points)
-
-
-def _cairo_font_args_from_font_prop(prop):
- """
- Convert a `.FontProperties` or a `.FontEntry` to arguments that can be
- passed to `.Context.select_font_face`.
- """
- def attr(field):
- try:
- return getattr(prop, f"get_{field}")()
- except AttributeError:
- return getattr(prop, field)
-
- name = attr("name")
- slant = getattr(cairo, f"FONT_SLANT_{attr('style').upper()}")
- weight = attr("weight")
- weight = (cairo.FONT_WEIGHT_NORMAL
- if font_manager.weight_dict.get(weight, weight) < 550
- else cairo.FONT_WEIGHT_BOLD)
- return name, slant, weight
-
-
-class RendererCairo(RendererBase):
- def __init__(self, dpi):
- self.dpi = dpi
- self.gc = GraphicsContextCairo(renderer=self)
- self.width = None
- self.height = None
- self.text_ctx = cairo.Context(
- cairo.ImageSurface(cairo.FORMAT_ARGB32, 1, 1))
- super().__init__()
-
- def set_context(self, ctx):
- surface = ctx.get_target()
- if hasattr(surface, "get_width") and hasattr(surface, "get_height"):
- size = surface.get_width(), surface.get_height()
- elif hasattr(surface, "get_extents"): # GTK4 RecordingSurface.
- ext = surface.get_extents()
- size = ext.width, ext.height
- else: # vector surfaces.
- ctx.save()
- ctx.reset_clip()
- rect, *rest = ctx.copy_clip_rectangle_list()
- if rest:
- raise TypeError("Cannot infer surface size")
- _, _, *size = rect
- ctx.restore()
- self.gc.ctx = ctx
- self.width, self.height = size
-
- def _fill_and_stroke(self, ctx, fill_c, alpha, alpha_overrides):
- if fill_c is not None:
- ctx.save()
- if len(fill_c) == 3 or alpha_overrides:
- ctx.set_source_rgba(fill_c[0], fill_c[1], fill_c[2], alpha)
- else:
- ctx.set_source_rgba(fill_c[0], fill_c[1], fill_c[2], fill_c[3])
- ctx.fill_preserve()
- ctx.restore()
- ctx.stroke()
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- # docstring inherited
- ctx = gc.ctx
- # Clip the path to the actual rendering extents if it isn't filled.
- clip = (ctx.clip_extents()
- if rgbFace is None and gc.get_hatch() is None
- else None)
- transform = (transform
- + Affine2D().scale(1, -1).translate(0, self.height))
- ctx.new_path()
- _append_path(ctx, path, transform, clip)
- self._fill_and_stroke(
- ctx, rgbFace, gc.get_alpha(), gc.get_forced_alpha())
-
- def draw_markers(self, gc, marker_path, marker_trans, path, transform,
- rgbFace=None):
- # docstring inherited
-
- ctx = gc.ctx
- ctx.new_path()
- # Create the path for the marker; it needs to be flipped here already!
- _append_path(ctx, marker_path, marker_trans + Affine2D().scale(1, -1))
- marker_path = ctx.copy_path_flat()
-
- # Figure out whether the path has a fill
- x1, y1, x2, y2 = ctx.fill_extents()
- if x1 == 0 and y1 == 0 and x2 == 0 and y2 == 0:
- filled = False
- # No fill, just unset this (so we don't try to fill it later on)
- rgbFace = None
- else:
- filled = True
-
- transform = (transform
- + Affine2D().scale(1, -1).translate(0, self.height))
-
- ctx.new_path()
- for i, (vertices, codes) in enumerate(
- path.iter_segments(transform, simplify=False)):
- if len(vertices):
- x, y = vertices[-2:]
- ctx.save()
-
- # Translate and apply path
- ctx.translate(x, y)
- ctx.append_path(marker_path)
-
- ctx.restore()
-
- # Slower code path if there is a fill; we need to draw
- # the fill and stroke for each marker at the same time.
- # Also flush out the drawing every once in a while to
- # prevent the paths from getting way too long.
- if filled or i % 1000 == 0:
- self._fill_and_stroke(
- ctx, rgbFace, gc.get_alpha(), gc.get_forced_alpha())
-
- # Fast path, if there is no fill, draw everything in one step
- if not filled:
- self._fill_and_stroke(
- ctx, rgbFace, gc.get_alpha(), gc.get_forced_alpha())
-
- def draw_image(self, gc, x, y, im):
- im = cbook._unmultiplied_rgba8888_to_premultiplied_argb32(im[::-1])
- surface = cairo.ImageSurface.create_for_data(
- im.ravel().data, cairo.FORMAT_ARGB32,
- im.shape[1], im.shape[0], im.shape[1] * 4)
- ctx = gc.ctx
- y = self.height - y - im.shape[0]
-
- ctx.save()
- ctx.set_source_surface(surface, float(x), float(y))
- ctx.paint()
- ctx.restore()
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- # docstring inherited
-
- # Note: (x, y) are device/display coords, not user-coords, unlike other
- # draw_* methods
- if ismath:
- self._draw_mathtext(gc, x, y, s, prop, angle)
-
- else:
- ctx = gc.ctx
- ctx.new_path()
- ctx.move_to(x, y)
-
- ctx.save()
- ctx.select_font_face(*_cairo_font_args_from_font_prop(prop))
- ctx.set_font_size(self.points_to_pixels(prop.get_size_in_points()))
- opts = cairo.FontOptions()
- opts.set_antialias(gc.get_antialiased())
- ctx.set_font_options(opts)
- if angle:
- ctx.rotate(np.deg2rad(-angle))
- ctx.show_text(s)
- ctx.restore()
-
- def _draw_mathtext(self, gc, x, y, s, prop, angle):
- ctx = gc.ctx
- width, height, descent, glyphs, rects = \
- self._text2path.mathtext_parser.parse(s, self.dpi, prop)
-
- ctx.save()
- ctx.translate(x, y)
- if angle:
- ctx.rotate(np.deg2rad(-angle))
-
- for font, fontsize, idx, ox, oy in glyphs:
- ctx.new_path()
- ctx.move_to(ox, -oy)
- ctx.select_font_face(
- *_cairo_font_args_from_font_prop(ttfFontProperty(font)))
- ctx.set_font_size(self.points_to_pixels(fontsize))
- ctx.show_text(chr(idx))
-
- for ox, oy, w, h in rects:
- ctx.new_path()
- ctx.rectangle(ox, -oy, w, -h)
- ctx.set_source_rgb(0, 0, 0)
- ctx.fill_preserve()
-
- ctx.restore()
-
- def get_canvas_width_height(self):
- # docstring inherited
- return self.width, self.height
-
- def get_text_width_height_descent(self, s, prop, ismath):
- # docstring inherited
-
- if ismath == 'TeX':
- return super().get_text_width_height_descent(s, prop, ismath)
-
- if ismath:
- width, height, descent, *_ = \
- self._text2path.mathtext_parser.parse(s, self.dpi, prop)
- return width, height, descent
-
- ctx = self.text_ctx
- # problem - scale remembers last setting and font can become
- # enormous causing program to crash
- # save/restore prevents the problem
- ctx.save()
- ctx.select_font_face(*_cairo_font_args_from_font_prop(prop))
- ctx.set_font_size(self.points_to_pixels(prop.get_size_in_points()))
-
- y_bearing, w, h = ctx.text_extents(s)[1:4]
- ctx.restore()
-
- return w, h, h + y_bearing
-
- def new_gc(self):
- # docstring inherited
- self.gc.ctx.save()
- self.gc._alpha = 1
- self.gc._forced_alpha = False # if True, _alpha overrides A from RGBA
- return self.gc
-
- def points_to_pixels(self, points):
- # docstring inherited
- return points / 72 * self.dpi
-
-
-class GraphicsContextCairo(GraphicsContextBase):
- _joind = {
- 'bevel': cairo.LINE_JOIN_BEVEL,
- 'miter': cairo.LINE_JOIN_MITER,
- 'round': cairo.LINE_JOIN_ROUND,
- }
-
- _capd = {
- 'butt': cairo.LINE_CAP_BUTT,
- 'projecting': cairo.LINE_CAP_SQUARE,
- 'round': cairo.LINE_CAP_ROUND,
- }
-
- def __init__(self, renderer):
- super().__init__()
- self.renderer = renderer
-
- def restore(self):
- self.ctx.restore()
-
- def set_alpha(self, alpha):
- super().set_alpha(alpha)
- _alpha = self.get_alpha()
- rgb = self._rgb
- if self.get_forced_alpha():
- self.ctx.set_source_rgba(rgb[0], rgb[1], rgb[2], _alpha)
- else:
- self.ctx.set_source_rgba(rgb[0], rgb[1], rgb[2], rgb[3])
-
- def set_antialiased(self, b):
- self.ctx.set_antialias(
- cairo.ANTIALIAS_DEFAULT if b else cairo.ANTIALIAS_NONE)
-
- def get_antialiased(self):
- return self.ctx.get_antialias()
-
- def set_capstyle(self, cs):
- self.ctx.set_line_cap(_api.check_getitem(self._capd, capstyle=cs))
- self._capstyle = cs
-
- def set_clip_rectangle(self, rectangle):
- if not rectangle:
- return
- x, y, w, h = np.round(rectangle.bounds)
- ctx = self.ctx
- ctx.new_path()
- ctx.rectangle(x, self.renderer.height - h - y, w, h)
- ctx.clip()
-
- def set_clip_path(self, path):
- if not path:
- return
- tpath, affine = path.get_transformed_path_and_affine()
- ctx = self.ctx
- ctx.new_path()
- affine = (affine
- + Affine2D().scale(1, -1).translate(0, self.renderer.height))
- _append_path(ctx, tpath, affine)
- ctx.clip()
-
- def set_dashes(self, offset, dashes):
- self._dashes = offset, dashes
- if dashes is None:
- self.ctx.set_dash([], 0) # switch dashes off
- else:
- self.ctx.set_dash(
- list(self.renderer.points_to_pixels(np.asarray(dashes))),
- offset)
-
- def set_foreground(self, fg, isRGBA=None):
- super().set_foreground(fg, isRGBA)
- if len(self._rgb) == 3:
- self.ctx.set_source_rgb(*self._rgb)
- else:
- self.ctx.set_source_rgba(*self._rgb)
-
- def get_rgb(self):
- return self.ctx.get_source().get_rgba()[:3]
-
- def set_joinstyle(self, js):
- self.ctx.set_line_join(_api.check_getitem(self._joind, joinstyle=js))
- self._joinstyle = js
-
- def set_linewidth(self, w):
- self._linewidth = float(w)
- self.ctx.set_line_width(self.renderer.points_to_pixels(w))
-
-
-class _CairoRegion:
- def __init__(self, slices, data):
- self._slices = slices
- self._data = data
-
-
-class FigureCanvasCairo(FigureCanvasBase):
- @property
- def _renderer(self):
- # In theory, _renderer should be set in __init__, but GUI canvas
- # subclasses (FigureCanvasFooCairo) don't always interact well with
- # multiple inheritance (FigureCanvasFoo inits but doesn't super-init
- # FigureCanvasCairo), so initialize it in the getter instead.
- if not hasattr(self, "_cached_renderer"):
- self._cached_renderer = RendererCairo(self.figure.dpi)
- return self._cached_renderer
-
- def get_renderer(self):
- return self._renderer
-
- def copy_from_bbox(self, bbox):
- surface = self._renderer.gc.ctx.get_target()
- if not isinstance(surface, cairo.ImageSurface):
- raise RuntimeError(
- "copy_from_bbox only works when rendering to an ImageSurface")
- sw = surface.get_width()
- sh = surface.get_height()
- x0 = math.ceil(bbox.x0)
- x1 = math.floor(bbox.x1)
- y0 = math.ceil(sh - bbox.y1)
- y1 = math.floor(sh - bbox.y0)
- if not (0 <= x0 and x1 <= sw and bbox.x0 <= bbox.x1
- and 0 <= y0 and y1 <= sh and bbox.y0 <= bbox.y1):
- raise ValueError("Invalid bbox")
- sls = slice(y0, y0 + max(y1 - y0, 0)), slice(x0, x0 + max(x1 - x0, 0))
- data = (np.frombuffer(surface.get_data(), np.uint32)
- .reshape((sh, sw))[sls].copy())
- return _CairoRegion(sls, data)
-
- def restore_region(self, region):
- surface = self._renderer.gc.ctx.get_target()
- if not isinstance(surface, cairo.ImageSurface):
- raise RuntimeError(
- "restore_region only works when rendering to an ImageSurface")
- surface.flush()
- sw = surface.get_width()
- sh = surface.get_height()
- sly, slx = region._slices
- (np.frombuffer(surface.get_data(), np.uint32)
- .reshape((sh, sw))[sly, slx]) = region._data
- surface.mark_dirty_rectangle(
- slx.start, sly.start, slx.stop - slx.start, sly.stop - sly.start)
-
- def print_png(self, fobj):
- self._get_printed_image_surface().write_to_png(fobj)
-
- def print_rgba(self, fobj):
- width, height = self.get_width_height()
- buf = self._get_printed_image_surface().get_data()
- fobj.write(cbook._premultiplied_argb32_to_unmultiplied_rgba8888(
- np.asarray(buf).reshape((width, height, 4))))
-
- print_raw = print_rgba
-
- def _get_printed_image_surface(self):
- self._renderer.dpi = self.figure.dpi
- width, height = self.get_width_height()
- surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
- self._renderer.set_context(cairo.Context(surface))
- self.figure.draw(self._renderer)
- return surface
-
- def _save(self, fmt, fobj, *, orientation='portrait'):
- # save PDF/PS/SVG
-
- dpi = 72
- self.figure.dpi = dpi
- w_in, h_in = self.figure.get_size_inches()
- width_in_points, height_in_points = w_in * dpi, h_in * dpi
-
- if orientation == 'landscape':
- width_in_points, height_in_points = (
- height_in_points, width_in_points)
-
- if fmt == 'ps':
- if not hasattr(cairo, 'PSSurface'):
- raise RuntimeError('cairo has not been compiled with PS '
- 'support enabled')
- surface = cairo.PSSurface(fobj, width_in_points, height_in_points)
- elif fmt == 'pdf':
- if not hasattr(cairo, 'PDFSurface'):
- raise RuntimeError('cairo has not been compiled with PDF '
- 'support enabled')
- surface = cairo.PDFSurface(fobj, width_in_points, height_in_points)
- elif fmt in ('svg', 'svgz'):
- if not hasattr(cairo, 'SVGSurface'):
- raise RuntimeError('cairo has not been compiled with SVG '
- 'support enabled')
- if fmt == 'svgz':
- if isinstance(fobj, str):
- fobj = gzip.GzipFile(fobj, 'wb')
- else:
- fobj = gzip.GzipFile(None, 'wb', fileobj=fobj)
- surface = cairo.SVGSurface(fobj, width_in_points, height_in_points)
- else:
- raise ValueError(f"Unknown format: {fmt!r}")
-
- self._renderer.dpi = self.figure.dpi
- self._renderer.set_context(cairo.Context(surface))
- ctx = self._renderer.gc.ctx
-
- if orientation == 'landscape':
- ctx.rotate(np.pi / 2)
- ctx.translate(0, -height_in_points)
- # Perhaps add an '%%Orientation: Landscape' comment?
-
- self.figure.draw(self._renderer)
-
- ctx.show_page()
- surface.finish()
- if fmt == 'svgz':
- fobj.close()
-
- print_pdf = functools.partialmethod(_save, "pdf")
- print_ps = functools.partialmethod(_save, "ps")
- print_svg = functools.partialmethod(_save, "svg")
- print_svgz = functools.partialmethod(_save, "svgz")
-
-
-@_Backend.export
-class _BackendCairo(_Backend):
- backend_version = cairo.version
- FigureCanvas = FigureCanvasCairo
- FigureManager = FigureManagerBase
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk3.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk3.py
deleted file mode 100644
index d6acd5547b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk3.py
+++ /dev/null
@@ -1,587 +0,0 @@
-import functools
-import logging
-import os
-from pathlib import Path
-
-import matplotlib as mpl
-from matplotlib import _api, backend_tools, cbook
-from matplotlib.backend_bases import (
- ToolContainerBase, CloseEvent, KeyEvent, LocationEvent, MouseEvent,
- ResizeEvent)
-
-try:
- import gi
-except ImportError as err:
- raise ImportError("The GTK3 backends require PyGObject") from err
-
-try:
- # :raises ValueError: If module/version is already loaded, already
- # required, or unavailable.
- gi.require_version("Gtk", "3.0")
-except ValueError as e:
- # in this case we want to re-raise as ImportError so the
- # auto-backend selection logic correctly skips.
- raise ImportError(e) from e
-
-from gi.repository import Gio, GLib, GObject, Gtk, Gdk
-from . import _backend_gtk
-from ._backend_gtk import ( # noqa: F401 # pylint: disable=W0611
- _BackendGTK, _FigureCanvasGTK, _FigureManagerGTK, _NavigationToolbar2GTK,
- TimerGTK as TimerGTK3,
-)
-
-
-_log = logging.getLogger(__name__)
-
-
-@functools.cache
-def _mpl_to_gtk_cursor(mpl_cursor):
- return Gdk.Cursor.new_from_name(
- Gdk.Display.get_default(),
- _backend_gtk.mpl_to_gtk_cursor_name(mpl_cursor))
-
-
-class FigureCanvasGTK3(_FigureCanvasGTK, Gtk.DrawingArea):
- required_interactive_framework = "gtk3"
- manager_class = _api.classproperty(lambda cls: FigureManagerGTK3)
- # Setting this as a static constant prevents
- # this resulting expression from leaking
- event_mask = (Gdk.EventMask.BUTTON_PRESS_MASK
- | Gdk.EventMask.BUTTON_RELEASE_MASK
- | Gdk.EventMask.EXPOSURE_MASK
- | Gdk.EventMask.KEY_PRESS_MASK
- | Gdk.EventMask.KEY_RELEASE_MASK
- | Gdk.EventMask.ENTER_NOTIFY_MASK
- | Gdk.EventMask.LEAVE_NOTIFY_MASK
- | Gdk.EventMask.POINTER_MOTION_MASK
- | Gdk.EventMask.SCROLL_MASK)
-
- def __init__(self, figure=None):
- super().__init__(figure=figure)
-
- self._idle_draw_id = 0
- self._rubberband_rect = None
-
- self.connect('scroll_event', self.scroll_event)
- self.connect('button_press_event', self.button_press_event)
- self.connect('button_release_event', self.button_release_event)
- self.connect('configure_event', self.configure_event)
- self.connect('screen-changed', self._update_device_pixel_ratio)
- self.connect('notify::scale-factor', self._update_device_pixel_ratio)
- self.connect('draw', self.on_draw_event)
- self.connect('draw', self._post_draw)
- self.connect('key_press_event', self.key_press_event)
- self.connect('key_release_event', self.key_release_event)
- self.connect('motion_notify_event', self.motion_notify_event)
- self.connect('enter_notify_event', self.enter_notify_event)
- self.connect('leave_notify_event', self.leave_notify_event)
- self.connect('size_allocate', self.size_allocate)
-
- self.set_events(self.__class__.event_mask)
-
- self.set_can_focus(True)
-
- css = Gtk.CssProvider()
- css.load_from_data(b".matplotlib-canvas { background-color: white; }")
- style_ctx = self.get_style_context()
- style_ctx.add_provider(css, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
- style_ctx.add_class("matplotlib-canvas")
-
- def destroy(self):
- CloseEvent("close_event", self)._process()
-
- def set_cursor(self, cursor):
- # docstring inherited
- window = self.get_property("window")
- if window is not None:
- window.set_cursor(_mpl_to_gtk_cursor(cursor))
- context = GLib.MainContext.default()
- context.iteration(True)
-
- def _mpl_coords(self, event=None):
- """
- Convert the position of a GTK event, or of the current cursor position
- if *event* is None, to Matplotlib coordinates.
-
- GTK use logical pixels, but the figure is scaled to physical pixels for
- rendering. Transform to physical pixels so that all of the down-stream
- transforms work as expected.
-
- Also, the origin is different and needs to be corrected.
- """
- if event is None:
- window = self.get_window()
- t, x, y, state = window.get_device_position(
- window.get_display().get_device_manager().get_client_pointer())
- else:
- x, y = event.x, event.y
- x = x * self.device_pixel_ratio
- # flip y so y=0 is bottom of canvas
- y = self.figure.bbox.height - y * self.device_pixel_ratio
- return x, y
-
- def scroll_event(self, widget, event):
- step = 1 if event.direction == Gdk.ScrollDirection.UP else -1
- MouseEvent("scroll_event", self,
- *self._mpl_coords(event), step=step,
- modifiers=self._mpl_modifiers(event.state),
- guiEvent=event)._process()
- return False # finish event propagation?
-
- def button_press_event(self, widget, event):
- MouseEvent("button_press_event", self,
- *self._mpl_coords(event), event.button,
- modifiers=self._mpl_modifiers(event.state),
- guiEvent=event)._process()
- return False # finish event propagation?
-
- def button_release_event(self, widget, event):
- MouseEvent("button_release_event", self,
- *self._mpl_coords(event), event.button,
- modifiers=self._mpl_modifiers(event.state),
- guiEvent=event)._process()
- return False # finish event propagation?
-
- def key_press_event(self, widget, event):
- KeyEvent("key_press_event", self,
- self._get_key(event), *self._mpl_coords(),
- guiEvent=event)._process()
- return True # stop event propagation
-
- def key_release_event(self, widget, event):
- KeyEvent("key_release_event", self,
- self._get_key(event), *self._mpl_coords(),
- guiEvent=event)._process()
- return True # stop event propagation
-
- def motion_notify_event(self, widget, event):
- MouseEvent("motion_notify_event", self, *self._mpl_coords(event),
- modifiers=self._mpl_modifiers(event.state),
- guiEvent=event)._process()
- return False # finish event propagation?
-
- def enter_notify_event(self, widget, event):
- gtk_mods = Gdk.Keymap.get_for_display(
- self.get_display()).get_modifier_state()
- LocationEvent("figure_enter_event", self, *self._mpl_coords(event),
- modifiers=self._mpl_modifiers(gtk_mods),
- guiEvent=event)._process()
-
- def leave_notify_event(self, widget, event):
- gtk_mods = Gdk.Keymap.get_for_display(
- self.get_display()).get_modifier_state()
- LocationEvent("figure_leave_event", self, *self._mpl_coords(event),
- modifiers=self._mpl_modifiers(gtk_mods),
- guiEvent=event)._process()
-
- def size_allocate(self, widget, allocation):
- dpival = self.figure.dpi
- winch = allocation.width * self.device_pixel_ratio / dpival
- hinch = allocation.height * self.device_pixel_ratio / dpival
- self.figure.set_size_inches(winch, hinch, forward=False)
- ResizeEvent("resize_event", self)._process()
- self.draw_idle()
-
- @staticmethod
- def _mpl_modifiers(event_state, *, exclude=None):
- modifiers = [
- ("ctrl", Gdk.ModifierType.CONTROL_MASK, "control"),
- ("alt", Gdk.ModifierType.MOD1_MASK, "alt"),
- ("shift", Gdk.ModifierType.SHIFT_MASK, "shift"),
- ("super", Gdk.ModifierType.MOD4_MASK, "super"),
- ]
- return [name for name, mask, key in modifiers
- if exclude != key and event_state & mask]
-
- def _get_key(self, event):
- unikey = chr(Gdk.keyval_to_unicode(event.keyval))
- key = cbook._unikey_or_keysym_to_mplkey(
- unikey, Gdk.keyval_name(event.keyval))
- mods = self._mpl_modifiers(event.state, exclude=key)
- if "shift" in mods and unikey.isprintable():
- mods.remove("shift")
- return "+".join([*mods, key])
-
- def _update_device_pixel_ratio(self, *args, **kwargs):
- # We need to be careful in cases with mixed resolution displays if
- # device_pixel_ratio changes.
- if self._set_device_pixel_ratio(self.get_scale_factor()):
- # The easiest way to resize the canvas is to emit a resize event
- # since we implement all the logic for resizing the canvas for that
- # event.
- self.queue_resize()
- self.queue_draw()
-
- def configure_event(self, widget, event):
- if widget.get_property("window") is None:
- return
- w = event.width * self.device_pixel_ratio
- h = event.height * self.device_pixel_ratio
- if w < 3 or h < 3:
- return # empty fig
- # resize the figure (in inches)
- dpi = self.figure.dpi
- self.figure.set_size_inches(w / dpi, h / dpi, forward=False)
- return False # finish event propagation?
-
- def _draw_rubberband(self, rect):
- self._rubberband_rect = rect
- # TODO: Only update the rubberband area.
- self.queue_draw()
-
- def _post_draw(self, widget, ctx):
- if self._rubberband_rect is None:
- return
-
- x0, y0, w, h = (dim / self.device_pixel_ratio
- for dim in self._rubberband_rect)
- x1 = x0 + w
- y1 = y0 + h
-
- # Draw the lines from x0, y0 towards x1, y1 so that the
- # dashes don't "jump" when moving the zoom box.
- ctx.move_to(x0, y0)
- ctx.line_to(x0, y1)
- ctx.move_to(x0, y0)
- ctx.line_to(x1, y0)
- ctx.move_to(x0, y1)
- ctx.line_to(x1, y1)
- ctx.move_to(x1, y0)
- ctx.line_to(x1, y1)
-
- ctx.set_antialias(1)
- ctx.set_line_width(1)
- ctx.set_dash((3, 3), 0)
- ctx.set_source_rgb(0, 0, 0)
- ctx.stroke_preserve()
-
- ctx.set_dash((3, 3), 3)
- ctx.set_source_rgb(1, 1, 1)
- ctx.stroke()
-
- def on_draw_event(self, widget, ctx):
- # to be overwritten by GTK3Agg or GTK3Cairo
- pass
-
- def draw(self):
- # docstring inherited
- if self.is_drawable():
- self.queue_draw()
-
- def draw_idle(self):
- # docstring inherited
- if self._idle_draw_id != 0:
- return
- def idle_draw(*args):
- try:
- self.draw()
- finally:
- self._idle_draw_id = 0
- return False
- self._idle_draw_id = GLib.idle_add(idle_draw)
-
- def flush_events(self):
- # docstring inherited
- context = GLib.MainContext.default()
- while context.pending():
- context.iteration(True)
-
-
-class NavigationToolbar2GTK3(_NavigationToolbar2GTK, Gtk.Toolbar):
- def __init__(self, canvas):
- GObject.GObject.__init__(self)
-
- self.set_style(Gtk.ToolbarStyle.ICONS)
-
- self._gtk_ids = {}
- for text, tooltip_text, image_file, callback in self.toolitems:
- if text is None:
- self.insert(Gtk.SeparatorToolItem(), -1)
- continue
- image = Gtk.Image.new_from_gicon(
- Gio.Icon.new_for_string(
- str(cbook._get_data_path('images',
- f'{image_file}-symbolic.svg'))),
- Gtk.IconSize.LARGE_TOOLBAR)
- self._gtk_ids[text] = button = (
- Gtk.ToggleToolButton() if callback in ['zoom', 'pan'] else
- Gtk.ToolButton())
- button.set_label(text)
- button.set_icon_widget(image)
- # Save the handler id, so that we can block it as needed.
- button._signal_handler = button.connect(
- 'clicked', getattr(self, callback))
- button.set_tooltip_text(tooltip_text)
- self.insert(button, -1)
-
- # This filler item ensures the toolbar is always at least two text
- # lines high. Otherwise the canvas gets redrawn as the mouse hovers
- # over images because those use two-line messages which resize the
- # toolbar.
- toolitem = Gtk.ToolItem()
- self.insert(toolitem, -1)
- label = Gtk.Label()
- label.set_markup(
- '<small>\N{NO-BREAK SPACE}\n\N{NO-BREAK SPACE}</small>')
- toolitem.set_expand(True) # Push real message to the right.
- toolitem.add(label)
-
- toolitem = Gtk.ToolItem()
- self.insert(toolitem, -1)
- self.message = Gtk.Label()
- self.message.set_justify(Gtk.Justification.RIGHT)
- toolitem.add(self.message)
-
- self.show_all()
-
- _NavigationToolbar2GTK.__init__(self, canvas)
-
- def save_figure(self, *args):
- dialog = Gtk.FileChooserDialog(
- title="Save the figure",
- parent=self.canvas.get_toplevel(),
- action=Gtk.FileChooserAction.SAVE,
- buttons=(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
- Gtk.STOCK_SAVE, Gtk.ResponseType.OK),
- )
- for name, fmts \
- in self.canvas.get_supported_filetypes_grouped().items():
- ff = Gtk.FileFilter()
- ff.set_name(name)
- for fmt in fmts:
- ff.add_pattern(f'*.{fmt}')
- dialog.add_filter(ff)
- if self.canvas.get_default_filetype() in fmts:
- dialog.set_filter(ff)
-
- @functools.partial(dialog.connect, "notify::filter")
- def on_notify_filter(*args):
- name = dialog.get_filter().get_name()
- fmt = self.canvas.get_supported_filetypes_grouped()[name][0]
- dialog.set_current_name(
- str(Path(dialog.get_current_name()).with_suffix(f'.{fmt}')))
-
- dialog.set_current_folder(mpl.rcParams["savefig.directory"])
- dialog.set_current_name(self.canvas.get_default_filename())
- dialog.set_do_overwrite_confirmation(True)
-
- response = dialog.run()
- fname = dialog.get_filename()
- ff = dialog.get_filter() # Doesn't autoadjust to filename :/
- fmt = self.canvas.get_supported_filetypes_grouped()[ff.get_name()][0]
- dialog.destroy()
- if response != Gtk.ResponseType.OK:
- return
- # Save dir for next time, unless empty str (which means use cwd).
- if mpl.rcParams['savefig.directory']:
- mpl.rcParams['savefig.directory'] = os.path.dirname(fname)
- try:
- self.canvas.figure.savefig(fname, format=fmt)
- except Exception as e:
- dialog = Gtk.MessageDialog(
- parent=self.canvas.get_toplevel(), message_format=str(e),
- type=Gtk.MessageType.ERROR, buttons=Gtk.ButtonsType.OK)
- dialog.run()
- dialog.destroy()
-
-
-class ToolbarGTK3(ToolContainerBase, Gtk.Box):
- _icon_extension = '-symbolic.svg'
-
- def __init__(self, toolmanager):
- ToolContainerBase.__init__(self, toolmanager)
- Gtk.Box.__init__(self)
- self.set_property('orientation', Gtk.Orientation.HORIZONTAL)
- self._message = Gtk.Label()
- self._message.set_justify(Gtk.Justification.RIGHT)
- self.pack_end(self._message, False, False, 0)
- self.show_all()
- self._groups = {}
- self._toolitems = {}
-
- def add_toolitem(self, name, group, position, image_file, description,
- toggle):
- if toggle:
- button = Gtk.ToggleToolButton()
- else:
- button = Gtk.ToolButton()
- button.set_label(name)
-
- if image_file is not None:
- image = Gtk.Image.new_from_gicon(
- Gio.Icon.new_for_string(image_file),
- Gtk.IconSize.LARGE_TOOLBAR)
- button.set_icon_widget(image)
-
- if position is None:
- position = -1
-
- self._add_button(button, group, position)
- signal = button.connect('clicked', self._call_tool, name)
- button.set_tooltip_text(description)
- button.show_all()
- self._toolitems.setdefault(name, [])
- self._toolitems[name].append((button, signal))
-
- def _add_button(self, button, group, position):
- if group not in self._groups:
- if self._groups:
- self._add_separator()
- toolbar = Gtk.Toolbar()
- toolbar.set_style(Gtk.ToolbarStyle.ICONS)
- self.pack_start(toolbar, False, False, 0)
- toolbar.show_all()
- self._groups[group] = toolbar
- self._groups[group].insert(button, position)
-
- def _call_tool(self, btn, name):
- self.trigger_tool(name)
-
- def toggle_toolitem(self, name, toggled):
- if name not in self._toolitems:
- return
- for toolitem, signal in self._toolitems[name]:
- toolitem.handler_block(signal)
- toolitem.set_active(toggled)
- toolitem.handler_unblock(signal)
-
- def remove_toolitem(self, name):
- if name not in self._toolitems:
- self.toolmanager.message_event(f'{name} not in toolbar', self)
- return
-
- for group in self._groups:
- for toolitem, _signal in self._toolitems[name]:
- if toolitem in self._groups[group]:
- self._groups[group].remove(toolitem)
- del self._toolitems[name]
-
- def _add_separator(self):
- sep = Gtk.Separator()
- sep.set_property("orientation", Gtk.Orientation.VERTICAL)
- self.pack_start(sep, False, True, 0)
- sep.show_all()
-
- def set_message(self, s):
- self._message.set_label(s)
-
-
-@backend_tools._register_tool_class(FigureCanvasGTK3)
-class SaveFigureGTK3(backend_tools.SaveFigureBase):
- def trigger(self, *args, **kwargs):
- NavigationToolbar2GTK3.save_figure(
- self._make_classic_style_pseudo_toolbar())
-
-
-@backend_tools._register_tool_class(FigureCanvasGTK3)
-class HelpGTK3(backend_tools.ToolHelpBase):
- def _normalize_shortcut(self, key):
- """
- Convert Matplotlib key presses to GTK+ accelerator identifiers.
-
- Related to `FigureCanvasGTK3._get_key`.
- """
- special = {
- 'backspace': 'BackSpace',
- 'pagedown': 'Page_Down',
- 'pageup': 'Page_Up',
- 'scroll_lock': 'Scroll_Lock',
- }
-
- parts = key.split('+')
- mods = ['<' + mod + '>' for mod in parts[:-1]]
- key = parts[-1]
-
- if key in special:
- key = special[key]
- elif len(key) > 1:
- key = key.capitalize()
- elif key.isupper():
- mods += ['<shift>']
-
- return ''.join(mods) + key
-
- def _is_valid_shortcut(self, key):
- """
- Check for a valid shortcut to be displayed.
-
- - GTK will never send 'cmd+' (see `FigureCanvasGTK3._get_key`).
- - The shortcut window only shows keyboard shortcuts, not mouse buttons.
- """
- return 'cmd+' not in key and not key.startswith('MouseButton.')
-
- def _show_shortcuts_window(self):
- section = Gtk.ShortcutsSection()
-
- for name, tool in sorted(self.toolmanager.tools.items()):
- if not tool.description:
- continue
-
- # Putting everything in a separate group allows GTK to
- # automatically split them into separate columns/pages, which is
- # useful because we have lots of shortcuts, some with many keys
- # that are very wide.
- group = Gtk.ShortcutsGroup()
- section.add(group)
- # A hack to remove the title since we have no group naming.
- group.forall(lambda widget, data: widget.set_visible(False), None)
-
- shortcut = Gtk.ShortcutsShortcut(
- accelerator=' '.join(
- self._normalize_shortcut(key)
- for key in self.toolmanager.get_tool_keymap(name)
- if self._is_valid_shortcut(key)),
- title=tool.name,
- subtitle=tool.description)
- group.add(shortcut)
-
- window = Gtk.ShortcutsWindow(
- title='Help',
- modal=True,
- transient_for=self._figure.canvas.get_toplevel())
- section.show() # Must be done explicitly before add!
- window.add(section)
-
- window.show_all()
-
- def _show_shortcuts_dialog(self):
- dialog = Gtk.MessageDialog(
- self._figure.canvas.get_toplevel(),
- 0, Gtk.MessageType.INFO, Gtk.ButtonsType.OK, self._get_help_text(),
- title="Help")
- dialog.run()
- dialog.destroy()
-
- def trigger(self, *args):
- if Gtk.check_version(3, 20, 0) is None:
- self._show_shortcuts_window()
- else:
- self._show_shortcuts_dialog()
-
-
-@backend_tools._register_tool_class(FigureCanvasGTK3)
-class ToolCopyToClipboardGTK3(backend_tools.ToolCopyToClipboardBase):
- def trigger(self, *args, **kwargs):
- clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)
- window = self.canvas.get_window()
- x, y, width, height = window.get_geometry()
- pb = Gdk.pixbuf_get_from_window(window, x, y, width, height)
- clipboard.set_image(pb)
-
-
-Toolbar = ToolbarGTK3
-backend_tools._register_tool_class(
- FigureCanvasGTK3, _backend_gtk.ConfigureSubplotsGTK)
-backend_tools._register_tool_class(
- FigureCanvasGTK3, _backend_gtk.RubberbandGTK)
-
-
-class FigureManagerGTK3(_FigureManagerGTK):
- _toolbar2_class = NavigationToolbar2GTK3
- _toolmanager_toolbar_class = ToolbarGTK3
-
-
-@_BackendGTK.export
-class _BackendGTK3(_BackendGTK):
- FigureCanvas = FigureCanvasGTK3
- FigureManager = FigureManagerGTK3
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk3agg.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk3agg.py
deleted file mode 100644
index a006a4c6f1..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk3agg.py
+++ /dev/null
@@ -1,69 +0,0 @@
-import numpy as np
-
-from .. import cbook, transforms
-from . import backend_agg, backend_gtk3
-from .backend_gtk3 import Gtk, _BackendGTK3
-
-import cairo # Presence of cairo is already checked by _backend_gtk.
-
-
-class FigureCanvasGTK3Agg(backend_agg.FigureCanvasAgg,
- backend_gtk3.FigureCanvasGTK3):
- def __init__(self, figure):
- super().__init__(figure=figure)
- self._bbox_queue = []
-
- def on_draw_event(self, widget, ctx):
- scale = self.device_pixel_ratio
- allocation = self.get_allocation()
- w = allocation.width * scale
- h = allocation.height * scale
-
- if not len(self._bbox_queue):
- Gtk.render_background(
- self.get_style_context(), ctx,
- allocation.x, allocation.y,
- allocation.width, allocation.height)
- bbox_queue = [transforms.Bbox([[0, 0], [w, h]])]
- else:
- bbox_queue = self._bbox_queue
-
- for bbox in bbox_queue:
- x = int(bbox.x0)
- y = h - int(bbox.y1)
- width = int(bbox.x1) - int(bbox.x0)
- height = int(bbox.y1) - int(bbox.y0)
-
- buf = cbook._unmultiplied_rgba8888_to_premultiplied_argb32(
- np.asarray(self.copy_from_bbox(bbox)))
- image = cairo.ImageSurface.create_for_data(
- buf.ravel().data, cairo.FORMAT_ARGB32, width, height)
- image.set_device_scale(scale, scale)
- ctx.set_source_surface(image, x / scale, y / scale)
- ctx.paint()
-
- if len(self._bbox_queue):
- self._bbox_queue = []
-
- return False
-
- def blit(self, bbox=None):
- # If bbox is None, blit the entire canvas to gtk. Otherwise
- # blit only the area defined by the bbox.
- if bbox is None:
- bbox = self.figure.bbox
-
- scale = self.device_pixel_ratio
- allocation = self.get_allocation()
- x = int(bbox.x0 / scale)
- y = allocation.height - int(bbox.y1 / scale)
- width = (int(bbox.x1) - int(bbox.x0)) // scale
- height = (int(bbox.y1) - int(bbox.y0)) // scale
-
- self._bbox_queue.append(bbox)
- self.queue_draw_area(x, y, width, height)
-
-
-@_BackendGTK3.export
-class _BackendGTK3Cairo(_BackendGTK3):
- FigureCanvas = FigureCanvasGTK3Agg
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk3cairo.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk3cairo.py
deleted file mode 100644
index 1da8419e53..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk3cairo.py
+++ /dev/null
@@ -1,26 +0,0 @@
-from contextlib import nullcontext
-
-from .backend_cairo import FigureCanvasCairo
-from .backend_gtk3 import Gtk, FigureCanvasGTK3, _BackendGTK3
-
-
-class FigureCanvasGTK3Cairo(FigureCanvasCairo, FigureCanvasGTK3):
- def on_draw_event(self, widget, ctx):
- with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
- else nullcontext()):
- self._renderer.set_context(ctx)
- scale = self.device_pixel_ratio
- # Scale physical drawing to logical size.
- ctx.scale(1 / scale, 1 / scale)
- allocation = self.get_allocation()
- Gtk.render_background(
- self.get_style_context(), ctx,
- allocation.x, allocation.y,
- allocation.width, allocation.height)
- self._renderer.dpi = self.figure.dpi
- self.figure.draw(self._renderer)
-
-
-@_BackendGTK3.export
-class _BackendGTK3Cairo(_BackendGTK3):
- FigureCanvas = FigureCanvasGTK3Cairo
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk4.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk4.py
deleted file mode 100644
index cb4006048d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk4.py
+++ /dev/null
@@ -1,606 +0,0 @@
-import functools
-import io
-import os
-
-import matplotlib as mpl
-from matplotlib import _api, backend_tools, cbook
-from matplotlib.backend_bases import (
- ToolContainerBase, KeyEvent, LocationEvent, MouseEvent, ResizeEvent,
- CloseEvent)
-
-try:
- import gi
-except ImportError as err:
- raise ImportError("The GTK4 backends require PyGObject") from err
-
-try:
- # :raises ValueError: If module/version is already loaded, already
- # required, or unavailable.
- gi.require_version("Gtk", "4.0")
-except ValueError as e:
- # in this case we want to re-raise as ImportError so the
- # auto-backend selection logic correctly skips.
- raise ImportError(e) from e
-
-from gi.repository import Gio, GLib, Gtk, Gdk, GdkPixbuf
-from . import _backend_gtk
-from ._backend_gtk import ( # noqa: F401 # pylint: disable=W0611
- _BackendGTK, _FigureCanvasGTK, _FigureManagerGTK, _NavigationToolbar2GTK,
- TimerGTK as TimerGTK4,
-)
-
-
-class FigureCanvasGTK4(_FigureCanvasGTK, Gtk.DrawingArea):
- required_interactive_framework = "gtk4"
- supports_blit = False
- manager_class = _api.classproperty(lambda cls: FigureManagerGTK4)
- _context_is_scaled = False
-
- def __init__(self, figure=None):
- super().__init__(figure=figure)
-
- self.set_hexpand(True)
- self.set_vexpand(True)
-
- self._idle_draw_id = 0
- self._rubberband_rect = None
-
- self.set_draw_func(self._draw_func)
- self.connect('resize', self.resize_event)
- self.connect('notify::scale-factor', self._update_device_pixel_ratio)
-
- click = Gtk.GestureClick()
- click.set_button(0) # All buttons.
- click.connect('pressed', self.button_press_event)
- click.connect('released', self.button_release_event)
- self.add_controller(click)
-
- key = Gtk.EventControllerKey()
- key.connect('key-pressed', self.key_press_event)
- key.connect('key-released', self.key_release_event)
- self.add_controller(key)
-
- motion = Gtk.EventControllerMotion()
- motion.connect('motion', self.motion_notify_event)
- motion.connect('enter', self.enter_notify_event)
- motion.connect('leave', self.leave_notify_event)
- self.add_controller(motion)
-
- scroll = Gtk.EventControllerScroll.new(
- Gtk.EventControllerScrollFlags.VERTICAL)
- scroll.connect('scroll', self.scroll_event)
- self.add_controller(scroll)
-
- self.set_focusable(True)
-
- css = Gtk.CssProvider()
- style = '.matplotlib-canvas { background-color: white; }'
- if Gtk.check_version(4, 9, 3) is None:
- css.load_from_data(style, -1)
- else:
- css.load_from_data(style.encode('utf-8'))
- style_ctx = self.get_style_context()
- style_ctx.add_provider(css, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
- style_ctx.add_class("matplotlib-canvas")
-
- def destroy(self):
- CloseEvent("close_event", self)._process()
-
- def set_cursor(self, cursor):
- # docstring inherited
- self.set_cursor_from_name(_backend_gtk.mpl_to_gtk_cursor_name(cursor))
-
- def _mpl_coords(self, xy=None):
- """
- Convert the *xy* position of a GTK event, or of the current cursor
- position if *xy* is None, to Matplotlib coordinates.
-
- GTK use logical pixels, but the figure is scaled to physical pixels for
- rendering. Transform to physical pixels so that all of the down-stream
- transforms work as expected.
-
- Also, the origin is different and needs to be corrected.
- """
- if xy is None:
- surface = self.get_native().get_surface()
- is_over, x, y, mask = surface.get_device_position(
- self.get_display().get_default_seat().get_pointer())
- else:
- x, y = xy
- x = x * self.device_pixel_ratio
- # flip y so y=0 is bottom of canvas
- y = self.figure.bbox.height - y * self.device_pixel_ratio
- return x, y
-
- def scroll_event(self, controller, dx, dy):
- MouseEvent(
- "scroll_event", self, *self._mpl_coords(), step=dy,
- modifiers=self._mpl_modifiers(controller),
- )._process()
- return True
-
- def button_press_event(self, controller, n_press, x, y):
- MouseEvent(
- "button_press_event", self, *self._mpl_coords((x, y)),
- controller.get_current_button(),
- modifiers=self._mpl_modifiers(controller),
- )._process()
- self.grab_focus()
-
- def button_release_event(self, controller, n_press, x, y):
- MouseEvent(
- "button_release_event", self, *self._mpl_coords((x, y)),
- controller.get_current_button(),
- modifiers=self._mpl_modifiers(controller),
- )._process()
-
- def key_press_event(self, controller, keyval, keycode, state):
- KeyEvent(
- "key_press_event", self, self._get_key(keyval, keycode, state),
- *self._mpl_coords(),
- )._process()
- return True
-
- def key_release_event(self, controller, keyval, keycode, state):
- KeyEvent(
- "key_release_event", self, self._get_key(keyval, keycode, state),
- *self._mpl_coords(),
- )._process()
- return True
-
- def motion_notify_event(self, controller, x, y):
- MouseEvent(
- "motion_notify_event", self, *self._mpl_coords((x, y)),
- modifiers=self._mpl_modifiers(controller),
- )._process()
-
- def enter_notify_event(self, controller, x, y):
- LocationEvent(
- "figure_enter_event", self, *self._mpl_coords((x, y)),
- modifiers=self._mpl_modifiers(),
- )._process()
-
- def leave_notify_event(self, controller):
- LocationEvent(
- "figure_leave_event", self, *self._mpl_coords(),
- modifiers=self._mpl_modifiers(),
- )._process()
-
- def resize_event(self, area, width, height):
- self._update_device_pixel_ratio()
- dpi = self.figure.dpi
- winch = width * self.device_pixel_ratio / dpi
- hinch = height * self.device_pixel_ratio / dpi
- self.figure.set_size_inches(winch, hinch, forward=False)
- ResizeEvent("resize_event", self)._process()
- self.draw_idle()
-
- def _mpl_modifiers(self, controller=None):
- if controller is None:
- surface = self.get_native().get_surface()
- is_over, x, y, event_state = surface.get_device_position(
- self.get_display().get_default_seat().get_pointer())
- else:
- event_state = controller.get_current_event_state()
- mod_table = [
- ("ctrl", Gdk.ModifierType.CONTROL_MASK),
- ("alt", Gdk.ModifierType.ALT_MASK),
- ("shift", Gdk.ModifierType.SHIFT_MASK),
- ("super", Gdk.ModifierType.SUPER_MASK),
- ]
- return [name for name, mask in mod_table if event_state & mask]
-
- def _get_key(self, keyval, keycode, state):
- unikey = chr(Gdk.keyval_to_unicode(keyval))
- key = cbook._unikey_or_keysym_to_mplkey(
- unikey,
- Gdk.keyval_name(keyval))
- modifiers = [
- ("ctrl", Gdk.ModifierType.CONTROL_MASK, "control"),
- ("alt", Gdk.ModifierType.ALT_MASK, "alt"),
- ("shift", Gdk.ModifierType.SHIFT_MASK, "shift"),
- ("super", Gdk.ModifierType.SUPER_MASK, "super"),
- ]
- mods = [
- mod for mod, mask, mod_key in modifiers
- if (mod_key != key and state & mask
- and not (mod == "shift" and unikey.isprintable()))]
- return "+".join([*mods, key])
-
- def _update_device_pixel_ratio(self, *args, **kwargs):
- # We need to be careful in cases with mixed resolution displays if
- # device_pixel_ratio changes.
- if self._set_device_pixel_ratio(self.get_scale_factor()):
- self.draw()
-
- def _draw_rubberband(self, rect):
- self._rubberband_rect = rect
- # TODO: Only update the rubberband area.
- self.queue_draw()
-
- def _draw_func(self, drawing_area, ctx, width, height):
- self.on_draw_event(self, ctx)
- self._post_draw(self, ctx)
-
- def _post_draw(self, widget, ctx):
- if self._rubberband_rect is None:
- return
-
- lw = 1
- dash = 3
- if not self._context_is_scaled:
- x0, y0, w, h = (dim / self.device_pixel_ratio
- for dim in self._rubberband_rect)
- else:
- x0, y0, w, h = self._rubberband_rect
- lw *= self.device_pixel_ratio
- dash *= self.device_pixel_ratio
- x1 = x0 + w
- y1 = y0 + h
-
- # Draw the lines from x0, y0 towards x1, y1 so that the
- # dashes don't "jump" when moving the zoom box.
- ctx.move_to(x0, y0)
- ctx.line_to(x0, y1)
- ctx.move_to(x0, y0)
- ctx.line_to(x1, y0)
- ctx.move_to(x0, y1)
- ctx.line_to(x1, y1)
- ctx.move_to(x1, y0)
- ctx.line_to(x1, y1)
-
- ctx.set_antialias(1)
- ctx.set_line_width(lw)
- ctx.set_dash((dash, dash), 0)
- ctx.set_source_rgb(0, 0, 0)
- ctx.stroke_preserve()
-
- ctx.set_dash((dash, dash), dash)
- ctx.set_source_rgb(1, 1, 1)
- ctx.stroke()
-
- def on_draw_event(self, widget, ctx):
- # to be overwritten by GTK4Agg or GTK4Cairo
- pass
-
- def draw(self):
- # docstring inherited
- if self.is_drawable():
- self.queue_draw()
-
- def draw_idle(self):
- # docstring inherited
- if self._idle_draw_id != 0:
- return
- def idle_draw(*args):
- try:
- self.draw()
- finally:
- self._idle_draw_id = 0
- return False
- self._idle_draw_id = GLib.idle_add(idle_draw)
-
- def flush_events(self):
- # docstring inherited
- context = GLib.MainContext.default()
- while context.pending():
- context.iteration(True)
-
-
-class NavigationToolbar2GTK4(_NavigationToolbar2GTK, Gtk.Box):
- def __init__(self, canvas):
- Gtk.Box.__init__(self)
-
- self.add_css_class('toolbar')
-
- self._gtk_ids = {}
- for text, tooltip_text, image_file, callback in self.toolitems:
- if text is None:
- self.append(Gtk.Separator())
- continue
- image = Gtk.Image.new_from_gicon(
- Gio.Icon.new_for_string(
- str(cbook._get_data_path('images',
- f'{image_file}-symbolic.svg'))))
- self._gtk_ids[text] = button = (
- Gtk.ToggleButton() if callback in ['zoom', 'pan'] else
- Gtk.Button())
- button.set_child(image)
- button.add_css_class('flat')
- button.add_css_class('image-button')
- # Save the handler id, so that we can block it as needed.
- button._signal_handler = button.connect(
- 'clicked', getattr(self, callback))
- button.set_tooltip_text(tooltip_text)
- self.append(button)
-
- # This filler item ensures the toolbar is always at least two text
- # lines high. Otherwise the canvas gets redrawn as the mouse hovers
- # over images because those use two-line messages which resize the
- # toolbar.
- label = Gtk.Label()
- label.set_markup(
- '<small>\N{NO-BREAK SPACE}\n\N{NO-BREAK SPACE}</small>')
- label.set_hexpand(True) # Push real message to the right.
- self.append(label)
-
- self.message = Gtk.Label()
- self.message.set_justify(Gtk.Justification.RIGHT)
- self.append(self.message)
-
- _NavigationToolbar2GTK.__init__(self, canvas)
-
- def save_figure(self, *args):
- dialog = Gtk.FileChooserNative(
- title='Save the figure',
- transient_for=self.canvas.get_root(),
- action=Gtk.FileChooserAction.SAVE,
- modal=True)
- self._save_dialog = dialog # Must keep a reference.
-
- ff = Gtk.FileFilter()
- ff.set_name('All files')
- ff.add_pattern('*')
- dialog.add_filter(ff)
- dialog.set_filter(ff)
-
- formats = []
- default_format = None
- for i, (name, fmts) in enumerate(
- self.canvas.get_supported_filetypes_grouped().items()):
- ff = Gtk.FileFilter()
- ff.set_name(name)
- for fmt in fmts:
- ff.add_pattern(f'*.{fmt}')
- dialog.add_filter(ff)
- formats.append(name)
- if self.canvas.get_default_filetype() in fmts:
- default_format = i
- # Setting the choice doesn't always work, so make sure the default
- # format is first.
- formats = [formats[default_format], *formats[:default_format],
- *formats[default_format+1:]]
- dialog.add_choice('format', 'File format', formats, formats)
- dialog.set_choice('format', formats[default_format])
-
- dialog.set_current_folder(Gio.File.new_for_path(
- os.path.expanduser(mpl.rcParams['savefig.directory'])))
- dialog.set_current_name(self.canvas.get_default_filename())
-
- @functools.partial(dialog.connect, 'response')
- def on_response(dialog, response):
- file = dialog.get_file()
- fmt = dialog.get_choice('format')
- fmt = self.canvas.get_supported_filetypes_grouped()[fmt][0]
- dialog.destroy()
- self._save_dialog = None
- if response != Gtk.ResponseType.ACCEPT:
- return
- # Save dir for next time, unless empty str (which means use cwd).
- if mpl.rcParams['savefig.directory']:
- parent = file.get_parent()
- mpl.rcParams['savefig.directory'] = parent.get_path()
- try:
- self.canvas.figure.savefig(file.get_path(), format=fmt)
- except Exception as e:
- msg = Gtk.MessageDialog(
- transient_for=self.canvas.get_root(),
- message_type=Gtk.MessageType.ERROR,
- buttons=Gtk.ButtonsType.OK, modal=True,
- text=str(e))
- msg.show()
-
- dialog.show()
-
-
-class ToolbarGTK4(ToolContainerBase, Gtk.Box):
- _icon_extension = '-symbolic.svg'
-
- def __init__(self, toolmanager):
- ToolContainerBase.__init__(self, toolmanager)
- Gtk.Box.__init__(self)
- self.set_property('orientation', Gtk.Orientation.HORIZONTAL)
-
- # Tool items are created later, but must appear before the message.
- self._tool_box = Gtk.Box()
- self.append(self._tool_box)
- self._groups = {}
- self._toolitems = {}
-
- # This filler item ensures the toolbar is always at least two text
- # lines high. Otherwise the canvas gets redrawn as the mouse hovers
- # over images because those use two-line messages which resize the
- # toolbar.
- label = Gtk.Label()
- label.set_markup(
- '<small>\N{NO-BREAK SPACE}\n\N{NO-BREAK SPACE}</small>')
- label.set_hexpand(True) # Push real message to the right.
- self.append(label)
-
- self._message = Gtk.Label()
- self._message.set_justify(Gtk.Justification.RIGHT)
- self.append(self._message)
-
- def add_toolitem(self, name, group, position, image_file, description,
- toggle):
- if toggle:
- button = Gtk.ToggleButton()
- else:
- button = Gtk.Button()
- button.set_label(name)
- button.add_css_class('flat')
-
- if image_file is not None:
- image = Gtk.Image.new_from_gicon(
- Gio.Icon.new_for_string(image_file))
- button.set_child(image)
- button.add_css_class('image-button')
-
- if position is None:
- position = -1
-
- self._add_button(button, group, position)
- signal = button.connect('clicked', self._call_tool, name)
- button.set_tooltip_text(description)
- self._toolitems.setdefault(name, [])
- self._toolitems[name].append((button, signal))
-
- def _find_child_at_position(self, group, position):
- children = [None]
- child = self._groups[group].get_first_child()
- while child is not None:
- children.append(child)
- child = child.get_next_sibling()
- return children[position]
-
- def _add_button(self, button, group, position):
- if group not in self._groups:
- if self._groups:
- self._add_separator()
- group_box = Gtk.Box()
- self._tool_box.append(group_box)
- self._groups[group] = group_box
- self._groups[group].insert_child_after(
- button, self._find_child_at_position(group, position))
-
- def _call_tool(self, btn, name):
- self.trigger_tool(name)
-
- def toggle_toolitem(self, name, toggled):
- if name not in self._toolitems:
- return
- for toolitem, signal in self._toolitems[name]:
- toolitem.handler_block(signal)
- toolitem.set_active(toggled)
- toolitem.handler_unblock(signal)
-
- def remove_toolitem(self, name):
- if name not in self._toolitems:
- self.toolmanager.message_event(f'{name} not in toolbar', self)
- return
-
- for group in self._groups:
- for toolitem, _signal in self._toolitems[name]:
- if toolitem in self._groups[group]:
- self._groups[group].remove(toolitem)
- del self._toolitems[name]
-
- def _add_separator(self):
- sep = Gtk.Separator()
- sep.set_property("orientation", Gtk.Orientation.VERTICAL)
- self._tool_box.append(sep)
-
- def set_message(self, s):
- self._message.set_label(s)
-
-
-@backend_tools._register_tool_class(FigureCanvasGTK4)
-class SaveFigureGTK4(backend_tools.SaveFigureBase):
- def trigger(self, *args, **kwargs):
- NavigationToolbar2GTK4.save_figure(
- self._make_classic_style_pseudo_toolbar())
-
-
-@backend_tools._register_tool_class(FigureCanvasGTK4)
-class HelpGTK4(backend_tools.ToolHelpBase):
- def _normalize_shortcut(self, key):
- """
- Convert Matplotlib key presses to GTK+ accelerator identifiers.
-
- Related to `FigureCanvasGTK4._get_key`.
- """
- special = {
- 'backspace': 'BackSpace',
- 'pagedown': 'Page_Down',
- 'pageup': 'Page_Up',
- 'scroll_lock': 'Scroll_Lock',
- }
-
- parts = key.split('+')
- mods = ['<' + mod + '>' for mod in parts[:-1]]
- key = parts[-1]
-
- if key in special:
- key = special[key]
- elif len(key) > 1:
- key = key.capitalize()
- elif key.isupper():
- mods += ['<shift>']
-
- return ''.join(mods) + key
-
- def _is_valid_shortcut(self, key):
- """
- Check for a valid shortcut to be displayed.
-
- - GTK will never send 'cmd+' (see `FigureCanvasGTK4._get_key`).
- - The shortcut window only shows keyboard shortcuts, not mouse buttons.
- """
- return 'cmd+' not in key and not key.startswith('MouseButton.')
-
- def trigger(self, *args):
- section = Gtk.ShortcutsSection()
-
- for name, tool in sorted(self.toolmanager.tools.items()):
- if not tool.description:
- continue
-
- # Putting everything in a separate group allows GTK to
- # automatically split them into separate columns/pages, which is
- # useful because we have lots of shortcuts, some with many keys
- # that are very wide.
- group = Gtk.ShortcutsGroup()
- section.append(group)
- # A hack to remove the title since we have no group naming.
- child = group.get_first_child()
- while child is not None:
- child.set_visible(False)
- child = child.get_next_sibling()
-
- shortcut = Gtk.ShortcutsShortcut(
- accelerator=' '.join(
- self._normalize_shortcut(key)
- for key in self.toolmanager.get_tool_keymap(name)
- if self._is_valid_shortcut(key)),
- title=tool.name,
- subtitle=tool.description)
- group.append(shortcut)
-
- window = Gtk.ShortcutsWindow(
- title='Help',
- modal=True,
- transient_for=self._figure.canvas.get_root())
- window.set_child(section)
-
- window.show()
-
-
-@backend_tools._register_tool_class(FigureCanvasGTK4)
-class ToolCopyToClipboardGTK4(backend_tools.ToolCopyToClipboardBase):
- def trigger(self, *args, **kwargs):
- with io.BytesIO() as f:
- self.canvas.print_rgba(f)
- w, h = self.canvas.get_width_height()
- pb = GdkPixbuf.Pixbuf.new_from_data(f.getbuffer(),
- GdkPixbuf.Colorspace.RGB, True,
- 8, w, h, w*4)
- clipboard = self.canvas.get_clipboard()
- clipboard.set(pb)
-
-
-backend_tools._register_tool_class(
- FigureCanvasGTK4, _backend_gtk.ConfigureSubplotsGTK)
-backend_tools._register_tool_class(
- FigureCanvasGTK4, _backend_gtk.RubberbandGTK)
-Toolbar = ToolbarGTK4
-
-
-class FigureManagerGTK4(_FigureManagerGTK):
- _toolbar2_class = NavigationToolbar2GTK4
- _toolmanager_toolbar_class = ToolbarGTK4
-
-
-@_BackendGTK.export
-class _BackendGTK4(_BackendGTK):
- FigureCanvas = FigureCanvasGTK4
- FigureManager = FigureManagerGTK4
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk4agg.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk4agg.py
deleted file mode 100644
index efddfec560..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk4agg.py
+++ /dev/null
@@ -1,36 +0,0 @@
-import numpy as np
-
-from .. import cbook
-from . import backend_agg, backend_gtk4
-from .backend_gtk4 import Gtk, _BackendGTK4
-
-import cairo # Presence of cairo is already checked by _backend_gtk.
-
-
-class FigureCanvasGTK4Agg(backend_agg.FigureCanvasAgg,
- backend_gtk4.FigureCanvasGTK4):
-
- def on_draw_event(self, widget, ctx):
- scale = self.device_pixel_ratio
- allocation = self.get_allocation()
-
- Gtk.render_background(
- self.get_style_context(), ctx,
- allocation.x, allocation.y,
- allocation.width, allocation.height)
-
- buf = cbook._unmultiplied_rgba8888_to_premultiplied_argb32(
- np.asarray(self.get_renderer().buffer_rgba()))
- height, width, _ = buf.shape
- image = cairo.ImageSurface.create_for_data(
- buf.ravel().data, cairo.FORMAT_ARGB32, width, height)
- image.set_device_scale(scale, scale)
- ctx.set_source_surface(image, 0, 0)
- ctx.paint()
-
- return False
-
-
-@_BackendGTK4.export
-class _BackendGTK4Agg(_BackendGTK4):
- FigureCanvas = FigureCanvasGTK4Agg
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk4cairo.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk4cairo.py
deleted file mode 100644
index d57f53fb28..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_gtk4cairo.py
+++ /dev/null
@@ -1,28 +0,0 @@
-from contextlib import nullcontext
-
-from .backend_cairo import FigureCanvasCairo
-from .backend_gtk4 import Gtk, FigureCanvasGTK4, _BackendGTK4
-
-
-class FigureCanvasGTK4Cairo(FigureCanvasCairo, FigureCanvasGTK4):
- _context_is_scaled = True
-
- def on_draw_event(self, widget, ctx):
- with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
- else nullcontext()):
- self._renderer.set_context(ctx)
- scale = self.device_pixel_ratio
- # Scale physical drawing to logical size.
- ctx.scale(1 / scale, 1 / scale)
- allocation = self.get_allocation()
- Gtk.render_background(
- self.get_style_context(), ctx,
- allocation.x, allocation.y,
- allocation.width, allocation.height)
- self._renderer.dpi = self.figure.dpi
- self.figure.draw(self._renderer)
-
-
-@_BackendGTK4.export
-class _BackendGTK4Cairo(_BackendGTK4):
- FigureCanvas = FigureCanvasGTK4Cairo
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_macosx.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_macosx.py
deleted file mode 100644
index a39f5b5b14..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_macosx.py
+++ /dev/null
@@ -1,236 +0,0 @@
-import contextlib
-import os
-import signal
-import socket
-
-import matplotlib as mpl
-from matplotlib import _api, cbook
-from matplotlib._pylab_helpers import Gcf
-from . import _macosx
-from .backend_agg import FigureCanvasAgg
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2,
- ResizeEvent, TimerBase)
-
-
-class TimerMac(_macosx.Timer, TimerBase):
- """Subclass of `.TimerBase` using CFRunLoop timer events."""
- # completely implemented at the C-level (in _macosx.Timer)
-
-
-class FigureCanvasMac(FigureCanvasAgg, _macosx.FigureCanvas, FigureCanvasBase):
- # docstring inherited
-
- # Ideally this class would be `class FCMacAgg(FCAgg, FCMac)`
- # (FC=FigureCanvas) where FCMac would be an ObjC-implemented mac-specific
- # class also inheriting from FCBase (this is the approach with other GUI
- # toolkits). However, writing an extension type inheriting from a Python
- # base class is slightly tricky (the extension type must be a heap type),
- # and we can just as well lift the FCBase base up one level, keeping it *at
- # the end* to have the right method resolution order.
-
- # Events such as button presses, mouse movements, and key presses are
- # handled in C and events (MouseEvent, etc.) are triggered from there.
-
- required_interactive_framework = "macosx"
- _timer_cls = TimerMac
- manager_class = _api.classproperty(lambda cls: FigureManagerMac)
-
- def __init__(self, figure):
- super().__init__(figure=figure)
- self._draw_pending = False
- self._is_drawing = False
- # Keep track of the timers that are alive
- self._timers = set()
-
- def draw(self):
- """Render the figure and update the macosx canvas."""
- # The renderer draw is done here; delaying causes problems with code
- # that uses the result of the draw() to update plot elements.
- if self._is_drawing:
- return
- with cbook._setattr_cm(self, _is_drawing=True):
- super().draw()
- self.update()
-
- def draw_idle(self):
- # docstring inherited
- if not (getattr(self, '_draw_pending', False) or
- getattr(self, '_is_drawing', False)):
- self._draw_pending = True
- # Add a singleshot timer to the eventloop that will call back
- # into the Python method _draw_idle to take care of the draw
- self._single_shot_timer(self._draw_idle)
-
- def _single_shot_timer(self, callback):
- """Add a single shot timer with the given callback"""
- # We need to explicitly stop and remove the timer after
- # firing, otherwise segfaults will occur when trying to deallocate
- # the singleshot timers.
- def callback_func(callback, timer):
- callback()
- self._timers.remove(timer)
- timer.stop()
- timer = self.new_timer(interval=0)
- timer.single_shot = True
- timer.add_callback(callback_func, callback, timer)
- self._timers.add(timer)
- timer.start()
-
- def _draw_idle(self):
- """
- Draw method for singleshot timer
-
- This draw method can be added to a singleshot timer, which can
- accumulate draws while the eventloop is spinning. This method will
- then only draw the first time and short-circuit the others.
- """
- with self._idle_draw_cntx():
- if not self._draw_pending:
- # Short-circuit because our draw request has already been
- # taken care of
- return
- self._draw_pending = False
- self.draw()
-
- def blit(self, bbox=None):
- # docstring inherited
- super().blit(bbox)
- self.update()
-
- def resize(self, width, height):
- # Size from macOS is logical pixels, dpi is physical.
- scale = self.figure.dpi / self.device_pixel_ratio
- width /= scale
- height /= scale
- self.figure.set_size_inches(width, height, forward=False)
- ResizeEvent("resize_event", self)._process()
- self.draw_idle()
-
- def start_event_loop(self, timeout=0):
- # docstring inherited
- with _maybe_allow_interrupt():
- # Call the objc implementation of the event loop after
- # setting up the interrupt handling
- self._start_event_loop(timeout=timeout)
-
-
-class NavigationToolbar2Mac(_macosx.NavigationToolbar2, NavigationToolbar2):
-
- def __init__(self, canvas):
- data_path = cbook._get_data_path('images')
- _, tooltips, image_names, _ = zip(*NavigationToolbar2.toolitems)
- _macosx.NavigationToolbar2.__init__(
- self, canvas,
- tuple(str(data_path / image_name) + ".pdf"
- for image_name in image_names if image_name is not None),
- tuple(tooltip for tooltip in tooltips if tooltip is not None))
- NavigationToolbar2.__init__(self, canvas)
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- self.canvas.set_rubberband(int(x0), int(y0), int(x1), int(y1))
-
- def remove_rubberband(self):
- self.canvas.remove_rubberband()
-
- def save_figure(self, *args):
- directory = os.path.expanduser(mpl.rcParams['savefig.directory'])
- filename = _macosx.choose_save_file('Save the figure',
- directory,
- self.canvas.get_default_filename())
- if filename is None: # Cancel
- return
- # Save dir for next time, unless empty str (which means use cwd).
- if mpl.rcParams['savefig.directory']:
- mpl.rcParams['savefig.directory'] = os.path.dirname(filename)
- self.canvas.figure.savefig(filename)
-
-
-class FigureManagerMac(_macosx.FigureManager, FigureManagerBase):
- _toolbar2_class = NavigationToolbar2Mac
-
- def __init__(self, canvas, num):
- self._shown = False
- _macosx.FigureManager.__init__(self, canvas)
- icon_path = str(cbook._get_data_path('images/matplotlib.pdf'))
- _macosx.FigureManager.set_icon(icon_path)
- FigureManagerBase.__init__(self, canvas, num)
- self._set_window_mode(mpl.rcParams["macosx.window_mode"])
- if self.toolbar is not None:
- self.toolbar.update()
- if mpl.is_interactive():
- self.show()
- self.canvas.draw_idle()
-
- def _close_button_pressed(self):
- Gcf.destroy(self)
- self.canvas.flush_events()
-
- def destroy(self):
- # We need to clear any pending timers that never fired, otherwise
- # we get a memory leak from the timer callbacks holding a reference
- while self.canvas._timers:
- timer = self.canvas._timers.pop()
- timer.stop()
- super().destroy()
-
- @classmethod
- def start_main_loop(cls):
- # Set up a SIGINT handler to allow terminating a plot via CTRL-C.
- # The logic is largely copied from qt_compat._maybe_allow_interrupt; see its
- # docstring for details. Parts are implemented by wake_on_fd_write in ObjC.
- with _maybe_allow_interrupt():
- _macosx.show()
-
- def show(self):
- if not self._shown:
- self._show()
- self._shown = True
- if mpl.rcParams["figure.raise_window"]:
- self._raise()
-
-
-@contextlib.contextmanager
-def _maybe_allow_interrupt():
- """
- This manager allows to terminate a plot by sending a SIGINT. It is
- necessary because the running backend prevents Python interpreter to
- run and process signals (i.e., to raise KeyboardInterrupt exception). To
- solve this one needs to somehow wake up the interpreter and make it close
- the plot window. The implementation is taken from qt_compat, see that
- docstring for a more detailed description.
- """
- old_sigint_handler = signal.getsignal(signal.SIGINT)
- if old_sigint_handler in (None, signal.SIG_IGN, signal.SIG_DFL):
- yield
- return
-
- handler_args = None
- wsock, rsock = socket.socketpair()
- wsock.setblocking(False)
- rsock.setblocking(False)
- old_wakeup_fd = signal.set_wakeup_fd(wsock.fileno())
- _macosx.wake_on_fd_write(rsock.fileno())
-
- def handle(*args):
- nonlocal handler_args
- handler_args = args
- _macosx.stop()
-
- signal.signal(signal.SIGINT, handle)
- try:
- yield
- finally:
- wsock.close()
- rsock.close()
- signal.set_wakeup_fd(old_wakeup_fd)
- signal.signal(signal.SIGINT, old_sigint_handler)
- if handler_args is not None:
- old_sigint_handler(*handler_args)
-
-
-@_Backend.export
-class _BackendMac(_Backend):
- FigureCanvas = FigureCanvasMac
- FigureManager = FigureManagerMac
- mainloop = FigureManagerMac.start_main_loop
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_mixed.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_mixed.py
deleted file mode 100644
index 6571d1928c..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_mixed.py
+++ /dev/null
@@ -1,119 +0,0 @@
-import numpy as np
-
-from matplotlib import cbook
-from .backend_agg import RendererAgg
-from matplotlib._tight_bbox import process_figure_for_rasterizing
-
-
-class MixedModeRenderer:
- """
- A helper class to implement a renderer that switches between
- vector and raster drawing. An example may be a PDF writer, where
- most things are drawn with PDF vector commands, but some very
- complex objects, such as quad meshes, are rasterised and then
- output as images.
- """
- def __init__(self, figure, width, height, dpi, vector_renderer,
- raster_renderer_class=None,
- bbox_inches_restore=None):
- """
- Parameters
- ----------
- figure : `~matplotlib.figure.Figure`
- The figure instance.
- width : scalar
- The width of the canvas in logical units
- height : scalar
- The height of the canvas in logical units
- dpi : float
- The dpi of the canvas
- vector_renderer : `~matplotlib.backend_bases.RendererBase`
- An instance of a subclass of
- `~matplotlib.backend_bases.RendererBase` that will be used for the
- vector drawing.
- raster_renderer_class : `~matplotlib.backend_bases.RendererBase`
- The renderer class to use for the raster drawing. If not provided,
- this will use the Agg backend (which is currently the only viable
- option anyway.)
-
- """
- if raster_renderer_class is None:
- raster_renderer_class = RendererAgg
-
- self._raster_renderer_class = raster_renderer_class
- self._width = width
- self._height = height
- self.dpi = dpi
-
- self._vector_renderer = vector_renderer
-
- self._raster_renderer = None
-
- # A reference to the figure is needed as we need to change
- # the figure dpi before and after the rasterization. Although
- # this looks ugly, I couldn't find a better solution. -JJL
- self.figure = figure
- self._figdpi = figure.dpi
-
- self._bbox_inches_restore = bbox_inches_restore
-
- self._renderer = vector_renderer
-
- def __getattr__(self, attr):
- # Proxy everything that hasn't been overridden to the base
- # renderer. Things that *are* overridden can call methods
- # on self._renderer directly, but must not cache/store
- # methods (because things like RendererAgg change their
- # methods on the fly in order to optimise proxying down
- # to the underlying C implementation).
- return getattr(self._renderer, attr)
-
- def start_rasterizing(self):
- """
- Enter "raster" mode. All subsequent drawing commands (until
- `stop_rasterizing` is called) will be drawn with the raster backend.
- """
- # change the dpi of the figure temporarily.
- self.figure.dpi = self.dpi
- if self._bbox_inches_restore: # when tight bbox is used
- r = process_figure_for_rasterizing(self.figure,
- self._bbox_inches_restore)
- self._bbox_inches_restore = r
-
- self._raster_renderer = self._raster_renderer_class(
- self._width*self.dpi, self._height*self.dpi, self.dpi)
- self._renderer = self._raster_renderer
-
- def stop_rasterizing(self):
- """
- Exit "raster" mode. All of the drawing that was done since
- the last `start_rasterizing` call will be copied to the
- vector backend by calling draw_image.
- """
-
- self._renderer = self._vector_renderer
-
- height = self._height * self.dpi
- img = np.asarray(self._raster_renderer.buffer_rgba())
- slice_y, slice_x = cbook._get_nonzero_slices(img[..., 3])
- cropped_img = img[slice_y, slice_x]
- if cropped_img.size:
- gc = self._renderer.new_gc()
- # TODO: If the mixedmode resolution differs from the figure's
- # dpi, the image must be scaled (dpi->_figdpi). Not all
- # backends support this.
- self._renderer.draw_image(
- gc,
- slice_x.start * self._figdpi / self.dpi,
- (height - slice_y.stop) * self._figdpi / self.dpi,
- cropped_img[::-1])
- self._raster_renderer = None
-
- # restore the figure dpi.
- self.figure.dpi = self._figdpi
-
- if self._bbox_inches_restore: # when tight bbox is used
- r = process_figure_for_rasterizing(self.figure,
- self._bbox_inches_restore,
- self._figdpi)
- self._bbox_inches_restore = r
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_nbagg.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_nbagg.py
deleted file mode 100644
index c5f1a503e8..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_nbagg.py
+++ /dev/null
@@ -1,243 +0,0 @@
-"""Interactive figures in the IPython notebook."""
-# Note: There is a notebook in
-# lib/matplotlib/backends/web_backend/nbagg_uat.ipynb to help verify
-# that changes made maintain expected behaviour.
-
-from base64 import b64encode
-import io
-import json
-import pathlib
-import uuid
-
-from ipykernel.comm import Comm
-from IPython.display import display, Javascript, HTML
-
-from matplotlib import is_interactive
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import _Backend, CloseEvent, NavigationToolbar2
-from .backend_webagg_core import (
- FigureCanvasWebAggCore, FigureManagerWebAgg, NavigationToolbar2WebAgg)
-from .backend_webagg_core import ( # noqa: F401 # pylint: disable=W0611
- TimerTornado, TimerAsyncio)
-
-
-def connection_info():
- """
- Return a string showing the figure and connection status for the backend.
-
- This is intended as a diagnostic tool, and not for general use.
- """
- result = [
- '{fig} - {socket}'.format(
- fig=(manager.canvas.figure.get_label()
- or f"Figure {manager.num}"),
- socket=manager.web_sockets)
- for manager in Gcf.get_all_fig_managers()
- ]
- if not is_interactive():
- result.append(f'Figures pending show: {len(Gcf.figs)}')
- return '\n'.join(result)
-
-
-_FONT_AWESOME_CLASSES = { # font-awesome 4 names
- 'home': 'fa fa-home',
- 'back': 'fa fa-arrow-left',
- 'forward': 'fa fa-arrow-right',
- 'zoom_to_rect': 'fa fa-square-o',
- 'move': 'fa fa-arrows',
- 'download': 'fa fa-floppy-o',
- None: None
-}
-
-
-class NavigationIPy(NavigationToolbar2WebAgg):
-
- # Use the standard toolbar items + download button
- toolitems = [(text, tooltip_text,
- _FONT_AWESOME_CLASSES[image_file], name_of_method)
- for text, tooltip_text, image_file, name_of_method
- in (NavigationToolbar2.toolitems +
- (('Download', 'Download plot', 'download', 'download'),))
- if image_file in _FONT_AWESOME_CLASSES]
-
-
-class FigureManagerNbAgg(FigureManagerWebAgg):
- _toolbar2_class = ToolbarCls = NavigationIPy
-
- def __init__(self, canvas, num):
- self._shown = False
- super().__init__(canvas, num)
-
- @classmethod
- def create_with_canvas(cls, canvas_class, figure, num):
- canvas = canvas_class(figure)
- manager = cls(canvas, num)
- if is_interactive():
- manager.show()
- canvas.draw_idle()
-
- def destroy(event):
- canvas.mpl_disconnect(cid)
- Gcf.destroy(manager)
-
- cid = canvas.mpl_connect('close_event', destroy)
- return manager
-
- def display_js(self):
- # XXX How to do this just once? It has to deal with multiple
- # browser instances using the same kernel (require.js - but the
- # file isn't static?).
- display(Javascript(FigureManagerNbAgg.get_javascript()))
-
- def show(self):
- if not self._shown:
- self.display_js()
- self._create_comm()
- else:
- self.canvas.draw_idle()
- self._shown = True
- # plt.figure adds an event which makes the figure in focus the active
- # one. Disable this behaviour, as it results in figures being put as
- # the active figure after they have been shown, even in non-interactive
- # mode.
- if hasattr(self, '_cidgcf'):
- self.canvas.mpl_disconnect(self._cidgcf)
- if not is_interactive():
- from matplotlib._pylab_helpers import Gcf
- Gcf.figs.pop(self.num, None)
-
- def reshow(self):
- """
- A special method to re-show the figure in the notebook.
-
- """
- self._shown = False
- self.show()
-
- @property
- def connected(self):
- return bool(self.web_sockets)
-
- @classmethod
- def get_javascript(cls, stream=None):
- if stream is None:
- output = io.StringIO()
- else:
- output = stream
- super().get_javascript(stream=output)
- import pkgutil
- data = pkgutil.get_data(__package__, "web_backend/js/nbagg_mpl.js").decode("utf-8")
- output.write(data)
- if stream is None:
- return output.getvalue()
-
- def _create_comm(self):
- comm = CommSocket(self)
- self.add_web_socket(comm)
- return comm
-
- def destroy(self):
- self._send_event('close')
- # need to copy comms as callbacks will modify this list
- for comm in list(self.web_sockets):
- comm.on_close()
- self.clearup_closed()
-
- def clearup_closed(self):
- """Clear up any closed Comms."""
- self.web_sockets = {socket for socket in self.web_sockets
- if socket.is_open()}
-
- if len(self.web_sockets) == 0:
- CloseEvent("close_event", self.canvas)._process()
-
- def remove_comm(self, comm_id):
- self.web_sockets = {socket for socket in self.web_sockets
- if socket.comm.comm_id != comm_id}
-
-
-class FigureCanvasNbAgg(FigureCanvasWebAggCore):
- manager_class = FigureManagerNbAgg
-
-
-class CommSocket:
- """
- Manages the Comm connection between IPython and the browser (client).
-
- Comms are 2 way, with the CommSocket being able to publish a message
- via the send_json method, and handle a message with on_message. On the
- JS side figure.send_message and figure.ws.onmessage do the sending and
- receiving respectively.
-
- """
- def __init__(self, manager):
- self.supports_binary = None
- self.manager = manager
- self.uuid = str(uuid.uuid4())
- # Publish an output area with a unique ID. The javascript can then
- # hook into this area.
- display(HTML("<div id=%r></div>" % self.uuid))
- try:
- self.comm = Comm('matplotlib', data={'id': self.uuid})
- except AttributeError as err:
- raise RuntimeError('Unable to create an IPython notebook Comm '
- 'instance. Are you in the IPython '
- 'notebook?') from err
- self.comm.on_msg(self.on_message)
-
- manager = self.manager
- self._ext_close = False
-
- def _on_close(close_message):
- self._ext_close = True
- manager.remove_comm(close_message['content']['comm_id'])
- manager.clearup_closed()
-
- self.comm.on_close(_on_close)
-
- def is_open(self):
- return not (self._ext_close or self.comm._closed)
-
- def on_close(self):
- # When the socket is closed, deregister the websocket with
- # the FigureManager.
- if self.is_open():
- try:
- self.comm.close()
- except KeyError:
- # apparently already cleaned it up?
- pass
-
- def send_json(self, content):
- self.comm.send({'data': json.dumps(content)})
-
- def send_binary(self, blob):
- if self.supports_binary:
- self.comm.send({'blob': 'image/png'}, buffers=[blob])
- else:
- # The comm is ASCII, so we send the image in base64 encoded data
- # URL form.
- data = b64encode(blob).decode('ascii')
- data_uri = f"data:image/png;base64,{data}"
- self.comm.send({'data': data_uri})
-
- def on_message(self, message):
- # The 'supports_binary' message is relevant to the
- # websocket itself. The other messages get passed along
- # to matplotlib as-is.
-
- # Every message has a "type" and a "figure_id".
- message = json.loads(message['content']['data'])
- if message['type'] == 'closing':
- self.on_close()
- self.manager.clearup_closed()
- elif message['type'] == 'supports_binary':
- self.supports_binary = message['value']
- else:
- self.manager.handle_json(message)
-
-
-@_Backend.export
-class _BackendNbAgg(_Backend):
- FigureCanvas = FigureCanvasNbAgg
- FigureManager = FigureManagerNbAgg
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_pdf.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_pdf.py
deleted file mode 100644
index aa4883135d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_pdf.py
+++ /dev/null
@@ -1,2827 +0,0 @@
-"""
-A PDF Matplotlib backend.
-
-Author: Jouni K Seppänen <jks@iki.fi> and others.
-"""
-
-import codecs
-from datetime import timezone
-from datetime import datetime
-from enum import Enum
-from functools import total_ordering
-from io import BytesIO
-import itertools
-import logging
-import math
-import os
-import string
-import struct
-import sys
-import time
-import types
-import warnings
-import zlib
-
-import numpy as np
-from PIL import Image
-
-import matplotlib as mpl
-from matplotlib import _api, _text_helpers, _type1font, cbook, dviread
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase,
- RendererBase)
-from matplotlib.backends.backend_mixed import MixedModeRenderer
-from matplotlib.figure import Figure
-from matplotlib.font_manager import get_font, fontManager as _fontManager
-from matplotlib._afm import AFM
-from matplotlib.ft2font import (FIXED_WIDTH, ITALIC, LOAD_NO_SCALE,
- LOAD_NO_HINTING, KERNING_UNFITTED, FT2Font)
-from matplotlib.transforms import Affine2D, BboxBase
-from matplotlib.path import Path
-from matplotlib.dates import UTC
-from matplotlib import _path
-from . import _backend_pdf_ps
-
-_log = logging.getLogger(__name__)
-
-# Overview
-#
-# The low-level knowledge about pdf syntax lies mainly in the pdfRepr
-# function and the classes Reference, Name, Operator, and Stream. The
-# PdfFile class knows about the overall structure of pdf documents.
-# It provides a "write" method for writing arbitrary strings in the
-# file, and an "output" method that passes objects through the pdfRepr
-# function before writing them in the file. The output method is
-# called by the RendererPdf class, which contains the various draw_foo
-# methods. RendererPdf contains a GraphicsContextPdf instance, and
-# each draw_foo calls self.check_gc before outputting commands. This
-# method checks whether the pdf graphics state needs to be modified
-# and outputs the necessary commands. GraphicsContextPdf represents
-# the graphics state, and its "delta" method returns the commands that
-# modify the state.
-
-# Add "pdf.use14corefonts: True" in your configuration file to use only
-# the 14 PDF core fonts. These fonts do not need to be embedded; every
-# PDF viewing application is required to have them. This results in very
-# light PDF files you can use directly in LaTeX or ConTeXt documents
-# generated with pdfTeX, without any conversion.
-
-# These fonts are: Helvetica, Helvetica-Bold, Helvetica-Oblique,
-# Helvetica-BoldOblique, Courier, Courier-Bold, Courier-Oblique,
-# Courier-BoldOblique, Times-Roman, Times-Bold, Times-Italic,
-# Times-BoldItalic, Symbol, ZapfDingbats.
-#
-# Some tricky points:
-#
-# 1. The clip path can only be widened by popping from the state
-# stack. Thus the state must be pushed onto the stack before narrowing
-# the clip path. This is taken care of by GraphicsContextPdf.
-#
-# 2. Sometimes it is necessary to refer to something (e.g., font,
-# image, or extended graphics state, which contains the alpha value)
-# in the page stream by a name that needs to be defined outside the
-# stream. PdfFile provides the methods fontName, imageObject, and
-# alphaState for this purpose. The implementations of these methods
-# should perhaps be generalized.
-
-# TODOs:
-#
-# * encoding of fonts, including mathtext fonts and Unicode support
-# * TTF support has lots of small TODOs, e.g., how do you know if a font
-# is serif/sans-serif, or symbolic/non-symbolic?
-# * draw_quad_mesh
-
-
-def _fill(strings, linelen=75):
- """
- Make one string from sequence of strings, with whitespace in between.
-
- The whitespace is chosen to form lines of at most *linelen* characters,
- if possible.
- """
- currpos = 0
- lasti = 0
- result = []
- for i, s in enumerate(strings):
- length = len(s)
- if currpos + length < linelen:
- currpos += length + 1
- else:
- result.append(b' '.join(strings[lasti:i]))
- lasti = i
- currpos = length
- result.append(b' '.join(strings[lasti:]))
- return b'\n'.join(result)
-
-
-def _create_pdf_info_dict(backend, metadata):
- """
- Create a PDF infoDict based on user-supplied metadata.
-
- A default ``Creator``, ``Producer``, and ``CreationDate`` are added, though
- the user metadata may override it. The date may be the current time, or a
- time set by the ``SOURCE_DATE_EPOCH`` environment variable.
-
- Metadata is verified to have the correct keys and their expected types. Any
- unknown keys/types will raise a warning.
-
- Parameters
- ----------
- backend : str
- The name of the backend to use in the Producer value.
-
- metadata : dict[str, Union[str, datetime, Name]]
- A dictionary of metadata supplied by the user with information
- following the PDF specification, also defined in
- `~.backend_pdf.PdfPages` below.
-
- If any value is *None*, then the key will be removed. This can be used
- to remove any pre-defined values.
-
- Returns
- -------
- dict[str, Union[str, datetime, Name]]
- A validated dictionary of metadata.
- """
-
- # get source date from SOURCE_DATE_EPOCH, if set
- # See https://reproducible-builds.org/specs/source-date-epoch/
- source_date_epoch = os.getenv("SOURCE_DATE_EPOCH")
- if source_date_epoch:
- source_date = datetime.fromtimestamp(int(source_date_epoch), timezone.utc)
- source_date = source_date.replace(tzinfo=UTC)
- else:
- source_date = datetime.today()
-
- info = {
- 'Creator': f'Matplotlib v{mpl.__version__}, https://matplotlib.org',
- 'Producer': f'Matplotlib {backend} backend v{mpl.__version__}',
- 'CreationDate': source_date,
- **metadata
- }
- info = {k: v for (k, v) in info.items() if v is not None}
-
- def is_string_like(x):
- return isinstance(x, str)
- is_string_like.text_for_warning = "an instance of str"
-
- def is_date(x):
- return isinstance(x, datetime)
- is_date.text_for_warning = "an instance of datetime.datetime"
-
- def check_trapped(x):
- if isinstance(x, Name):
- return x.name in (b'True', b'False', b'Unknown')
- else:
- return x in ('True', 'False', 'Unknown')
- check_trapped.text_for_warning = 'one of {"True", "False", "Unknown"}'
-
- keywords = {
- 'Title': is_string_like,
- 'Author': is_string_like,
- 'Subject': is_string_like,
- 'Keywords': is_string_like,
- 'Creator': is_string_like,
- 'Producer': is_string_like,
- 'CreationDate': is_date,
- 'ModDate': is_date,
- 'Trapped': check_trapped,
- }
- for k in info:
- if k not in keywords:
- _api.warn_external(f'Unknown infodict keyword: {k!r}. '
- f'Must be one of {set(keywords)!r}.')
- elif not keywords[k](info[k]):
- _api.warn_external(f'Bad value for infodict keyword {k}. '
- f'Got {info[k]!r} which is not '
- f'{keywords[k].text_for_warning}.')
- if 'Trapped' in info:
- info['Trapped'] = Name(info['Trapped'])
-
- return info
-
-
-def _datetime_to_pdf(d):
- """
- Convert a datetime to a PDF string representing it.
-
- Used for PDF and PGF.
- """
- r = d.strftime('D:%Y%m%d%H%M%S')
- z = d.utcoffset()
- if z is not None:
- z = z.seconds
- else:
- if time.daylight:
- z = time.altzone
- else:
- z = time.timezone
- if z == 0:
- r += 'Z'
- elif z < 0:
- r += "+%02d'%02d'" % ((-z) // 3600, (-z) % 3600)
- else:
- r += "-%02d'%02d'" % (z // 3600, z % 3600)
- return r
-
-
-def _calculate_quad_point_coordinates(x, y, width, height, angle=0):
- """
- Calculate the coordinates of rectangle when rotated by angle around x, y
- """
-
- angle = math.radians(-angle)
- sin_angle = math.sin(angle)
- cos_angle = math.cos(angle)
- a = x + height * sin_angle
- b = y + height * cos_angle
- c = x + width * cos_angle + height * sin_angle
- d = y - width * sin_angle + height * cos_angle
- e = x + width * cos_angle
- f = y - width * sin_angle
- return ((x, y), (e, f), (c, d), (a, b))
-
-
-def _get_coordinates_of_block(x, y, width, height, angle=0):
- """
- Get the coordinates of rotated rectangle and rectangle that covers the
- rotated rectangle.
- """
-
- vertices = _calculate_quad_point_coordinates(x, y, width,
- height, angle)
-
- # Find min and max values for rectangle
- # adjust so that QuadPoints is inside Rect
- # PDF docs says that QuadPoints should be ignored if any point lies
- # outside Rect, but for Acrobat it is enough that QuadPoints is on the
- # border of Rect.
-
- pad = 0.00001 if angle % 90 else 0
- min_x = min(v[0] for v in vertices) - pad
- min_y = min(v[1] for v in vertices) - pad
- max_x = max(v[0] for v in vertices) + pad
- max_y = max(v[1] for v in vertices) + pad
- return (tuple(itertools.chain.from_iterable(vertices)),
- (min_x, min_y, max_x, max_y))
-
-
-def _get_link_annotation(gc, x, y, width, height, angle=0):
- """
- Create a link annotation object for embedding URLs.
- """
- quadpoints, rect = _get_coordinates_of_block(x, y, width, height, angle)
- link_annotation = {
- 'Type': Name('Annot'),
- 'Subtype': Name('Link'),
- 'Rect': rect,
- 'Border': [0, 0, 0],
- 'A': {
- 'S': Name('URI'),
- 'URI': gc.get_url(),
- },
- }
- if angle % 90:
- # Add QuadPoints
- link_annotation['QuadPoints'] = quadpoints
- return link_annotation
-
-
-# PDF strings are supposed to be able to include any eight-bit data, except
-# that unbalanced parens and backslashes must be escaped by a backslash.
-# However, sf bug #2708559 shows that the carriage return character may get
-# read as a newline; these characters correspond to \gamma and \Omega in TeX's
-# math font encoding. Escaping them fixes the bug.
-_str_escapes = str.maketrans({
- '\\': '\\\\', '(': '\\(', ')': '\\)', '\n': '\\n', '\r': '\\r'})
-
-
-def pdfRepr(obj):
- """Map Python objects to PDF syntax."""
-
- # Some objects defined later have their own pdfRepr method.
- if hasattr(obj, 'pdfRepr'):
- return obj.pdfRepr()
-
- # Floats. PDF does not have exponential notation (1.0e-10) so we
- # need to use %f with some precision. Perhaps the precision
- # should adapt to the magnitude of the number?
- elif isinstance(obj, (float, np.floating)):
- if not np.isfinite(obj):
- raise ValueError("Can only output finite numbers in PDF")
- r = b"%.10f" % obj
- return r.rstrip(b'0').rstrip(b'.')
-
- # Booleans. Needs to be tested before integers since
- # isinstance(True, int) is true.
- elif isinstance(obj, bool):
- return [b'false', b'true'][obj]
-
- # Integers are written as such.
- elif isinstance(obj, (int, np.integer)):
- return b"%d" % obj
-
- # Non-ASCII Unicode strings are encoded in UTF-16BE with byte-order mark.
- elif isinstance(obj, str):
- return pdfRepr(obj.encode('ascii') if obj.isascii()
- else codecs.BOM_UTF16_BE + obj.encode('UTF-16BE'))
-
- # Strings are written in parentheses, with backslashes and parens
- # escaped. Actually balanced parens are allowed, but it is
- # simpler to escape them all. TODO: cut long strings into lines;
- # I believe there is some maximum line length in PDF.
- # Despite the extra decode/encode, translate is faster than regex.
- elif isinstance(obj, bytes):
- return (
- b'(' +
- obj.decode('latin-1').translate(_str_escapes).encode('latin-1')
- + b')')
-
- # Dictionaries. The keys must be PDF names, so if we find strings
- # there, we make Name objects from them. The values may be
- # anything, so the caller must ensure that PDF names are
- # represented as Name objects.
- elif isinstance(obj, dict):
- return _fill([
- b"<<",
- *[Name(k).pdfRepr() + b" " + pdfRepr(v) for k, v in obj.items()],
- b">>",
- ])
-
- # Lists.
- elif isinstance(obj, (list, tuple)):
- return _fill([b"[", *[pdfRepr(val) for val in obj], b"]"])
-
- # The null keyword.
- elif obj is None:
- return b'null'
-
- # A date.
- elif isinstance(obj, datetime):
- return pdfRepr(_datetime_to_pdf(obj))
-
- # A bounding box
- elif isinstance(obj, BboxBase):
- return _fill([pdfRepr(val) for val in obj.bounds])
-
- else:
- raise TypeError(f"Don't know a PDF representation for {type(obj)} "
- "objects")
-
-
-def _font_supports_glyph(fonttype, glyph):
- """
- Returns True if the font is able to provide codepoint *glyph* in a PDF.
-
- For a Type 3 font, this method returns True only for single-byte
- characters. For Type 42 fonts this method return True if the character is
- from the Basic Multilingual Plane.
- """
- if fonttype == 3:
- return glyph <= 255
- if fonttype == 42:
- return glyph <= 65535
- raise NotImplementedError()
-
-
-class Reference:
- """
- PDF reference object.
-
- Use PdfFile.reserveObject() to create References.
- """
-
- def __init__(self, id):
- self.id = id
-
- def __repr__(self):
- return "<Reference %d>" % self.id
-
- def pdfRepr(self):
- return b"%d 0 R" % self.id
-
- def write(self, contents, file):
- write = file.write
- write(b"%d 0 obj\n" % self.id)
- write(pdfRepr(contents))
- write(b"\nendobj\n")
-
-
-@total_ordering
-class Name:
- """PDF name object."""
- __slots__ = ('name',)
- _hexify = {c: '#%02x' % c
- for c in {*range(256)} - {*range(ord('!'), ord('~') + 1)}}
-
- def __init__(self, name):
- if isinstance(name, Name):
- self.name = name.name
- else:
- if isinstance(name, bytes):
- name = name.decode('ascii')
- self.name = name.translate(self._hexify).encode('ascii')
-
- def __repr__(self):
- return "<Name %s>" % self.name
-
- def __str__(self):
- return '/' + self.name.decode('ascii')
-
- def __eq__(self, other):
- return isinstance(other, Name) and self.name == other.name
-
- def __lt__(self, other):
- return isinstance(other, Name) and self.name < other.name
-
- def __hash__(self):
- return hash(self.name)
-
- def pdfRepr(self):
- return b'/' + self.name
-
-
-class Verbatim:
- """Store verbatim PDF command content for later inclusion in the stream."""
- def __init__(self, x):
- self._x = x
-
- def pdfRepr(self):
- return self._x
-
-
-class Op(Enum):
- """PDF operators (not an exhaustive list)."""
-
- close_fill_stroke = b'b'
- fill_stroke = b'B'
- fill = b'f'
- closepath = b'h'
- close_stroke = b's'
- stroke = b'S'
- endpath = b'n'
- begin_text = b'BT'
- end_text = b'ET'
- curveto = b'c'
- rectangle = b're'
- lineto = b'l'
- moveto = b'm'
- concat_matrix = b'cm'
- use_xobject = b'Do'
- setgray_stroke = b'G'
- setgray_nonstroke = b'g'
- setrgb_stroke = b'RG'
- setrgb_nonstroke = b'rg'
- setcolorspace_stroke = b'CS'
- setcolorspace_nonstroke = b'cs'
- setcolor_stroke = b'SCN'
- setcolor_nonstroke = b'scn'
- setdash = b'd'
- setlinejoin = b'j'
- setlinecap = b'J'
- setgstate = b'gs'
- gsave = b'q'
- grestore = b'Q'
- textpos = b'Td'
- selectfont = b'Tf'
- textmatrix = b'Tm'
- show = b'Tj'
- showkern = b'TJ'
- setlinewidth = b'w'
- clip = b'W'
- shading = b'sh'
-
- def pdfRepr(self):
- return self.value
-
- @classmethod
- def paint_path(cls, fill, stroke):
- """
- Return the PDF operator to paint a path.
-
- Parameters
- ----------
- fill : bool
- Fill the path with the fill color.
- stroke : bool
- Stroke the outline of the path with the line color.
- """
- if stroke:
- if fill:
- return cls.fill_stroke
- else:
- return cls.stroke
- else:
- if fill:
- return cls.fill
- else:
- return cls.endpath
-
-
-class Stream:
- """
- PDF stream object.
-
- This has no pdfRepr method. Instead, call begin(), then output the
- contents of the stream by calling write(), and finally call end().
- """
- __slots__ = ('id', 'len', 'pdfFile', 'file', 'compressobj', 'extra', 'pos')
-
- def __init__(self, id, len, file, extra=None, png=None):
- """
- Parameters
- ----------
- id : int
- Object id of the stream.
- len : Reference or None
- An unused Reference object for the length of the stream;
- None means to use a memory buffer so the length can be inlined.
- file : PdfFile
- The underlying object to write the stream to.
- extra : dict from Name to anything, or None
- Extra key-value pairs to include in the stream header.
- png : dict or None
- If the data is already png encoded, the decode parameters.
- """
- self.id = id # object id
- self.len = len # id of length object
- self.pdfFile = file
- self.file = file.fh # file to which the stream is written
- self.compressobj = None # compression object
- if extra is None:
- self.extra = dict()
- else:
- self.extra = extra.copy()
- if png is not None:
- self.extra.update({'Filter': Name('FlateDecode'),
- 'DecodeParms': png})
-
- self.pdfFile.recordXref(self.id)
- if mpl.rcParams['pdf.compression'] and not png:
- self.compressobj = zlib.compressobj(
- mpl.rcParams['pdf.compression'])
- if self.len is None:
- self.file = BytesIO()
- else:
- self._writeHeader()
- self.pos = self.file.tell()
-
- def _writeHeader(self):
- write = self.file.write
- write(b"%d 0 obj\n" % self.id)
- dict = self.extra
- dict['Length'] = self.len
- if mpl.rcParams['pdf.compression']:
- dict['Filter'] = Name('FlateDecode')
-
- write(pdfRepr(dict))
- write(b"\nstream\n")
-
- def end(self):
- """Finalize stream."""
-
- self._flush()
- if self.len is None:
- contents = self.file.getvalue()
- self.len = len(contents)
- self.file = self.pdfFile.fh
- self._writeHeader()
- self.file.write(contents)
- self.file.write(b"\nendstream\nendobj\n")
- else:
- length = self.file.tell() - self.pos
- self.file.write(b"\nendstream\nendobj\n")
- self.pdfFile.writeObject(self.len, length)
-
- def write(self, data):
- """Write some data on the stream."""
-
- if self.compressobj is None:
- self.file.write(data)
- else:
- compressed = self.compressobj.compress(data)
- self.file.write(compressed)
-
- def _flush(self):
- """Flush the compression object."""
-
- if self.compressobj is not None:
- compressed = self.compressobj.flush()
- self.file.write(compressed)
- self.compressobj = None
-
-
-def _get_pdf_charprocs(font_path, glyph_ids):
- font = get_font(font_path, hinting_factor=1)
- conv = 1000 / font.units_per_EM # Conversion to PS units (1/1000's).
- procs = {}
- for glyph_id in glyph_ids:
- g = font.load_glyph(glyph_id, LOAD_NO_SCALE)
- # NOTE: We should be using round(), but instead use
- # "(x+.5).astype(int)" to keep backcompat with the old ttconv code
- # (this is different for negative x's).
- d1 = (np.array([g.horiAdvance, 0, *g.bbox]) * conv + .5).astype(int)
- v, c = font.get_path()
- v = (v * 64).astype(int) # Back to TrueType's internal units (1/64's).
- # Backcompat with old ttconv code: control points between two quads are
- # omitted if they are exactly at the midpoint between the control of
- # the quad before and the quad after, but ttconv used to interpolate
- # *after* conversion to PS units, causing floating point errors. Here
- # we reproduce ttconv's logic, detecting these "implicit" points and
- # re-interpolating them. Note that occasionally (e.g. with DejaVu Sans
- # glyph "0") a point detected as "implicit" is actually explicit, and
- # will thus be shifted by 1.
- quads, = np.nonzero(c == 3)
- quads_on = quads[1::2]
- quads_mid_on = np.array(
- sorted({*quads_on} & {*(quads - 1)} & {*(quads + 1)}), int)
- implicit = quads_mid_on[
- (v[quads_mid_on] # As above, use astype(int), not // division
- == ((v[quads_mid_on - 1] + v[quads_mid_on + 1]) / 2).astype(int))
- .all(axis=1)]
- if (font.postscript_name, glyph_id) in [
- ("DejaVuSerif-Italic", 77), # j
- ("DejaVuSerif-Italic", 135), # \AA
- ]:
- v[:, 0] -= 1 # Hard-coded backcompat (FreeType shifts glyph by 1).
- v = (v * conv + .5).astype(int) # As above re: truncation vs rounding.
- v[implicit] = (( # Fix implicit points; again, truncate.
- (v[implicit - 1] + v[implicit + 1]) / 2).astype(int))
- procs[font.get_glyph_name(glyph_id)] = (
- " ".join(map(str, d1)).encode("ascii") + b" d1\n"
- + _path.convert_to_string(
- Path(v, c), None, None, False, None, -1,
- # no code for quad Beziers triggers auto-conversion to cubics.
- [b"m", b"l", b"", b"c", b"h"], True)
- + b"f")
- return procs
-
-
-class PdfFile:
- """PDF file object."""
-
- def __init__(self, filename, metadata=None):
- """
- Parameters
- ----------
- filename : str or path-like or file-like
- Output target; if a string, a file will be opened for writing.
-
- metadata : dict from strings to strings and dates
- Information dictionary object (see PDF reference section 10.2.1
- 'Document Information Dictionary'), e.g.:
- ``{'Creator': 'My software', 'Author': 'Me', 'Title': 'Awesome'}``.
-
- The standard keys are 'Title', 'Author', 'Subject', 'Keywords',
- 'Creator', 'Producer', 'CreationDate', 'ModDate', and
- 'Trapped'. Values have been predefined for 'Creator', 'Producer'
- and 'CreationDate'. They can be removed by setting them to `None`.
- """
- super().__init__()
-
- self._object_seq = itertools.count(1) # consumed by reserveObject
- self.xrefTable = [[0, 65535, 'the zero object']]
- self.passed_in_file_object = False
- self.original_file_like = None
- self.tell_base = 0
- fh, opened = cbook.to_filehandle(filename, "wb", return_opened=True)
- if not opened:
- try:
- self.tell_base = filename.tell()
- except OSError:
- fh = BytesIO()
- self.original_file_like = filename
- else:
- fh = filename
- self.passed_in_file_object = True
-
- self.fh = fh
- self.currentstream = None # stream object to write to, if any
- fh.write(b"%PDF-1.4\n") # 1.4 is the first version to have alpha
- # Output some eight-bit chars as a comment so various utilities
- # recognize the file as binary by looking at the first few
- # lines (see note in section 3.4.1 of the PDF reference).
- fh.write(b"%\254\334 \253\272\n")
-
- self.rootObject = self.reserveObject('root')
- self.pagesObject = self.reserveObject('pages')
- self.pageList = []
- self.fontObject = self.reserveObject('fonts')
- self._extGStateObject = self.reserveObject('extended graphics states')
- self.hatchObject = self.reserveObject('tiling patterns')
- self.gouraudObject = self.reserveObject('Gouraud triangles')
- self.XObjectObject = self.reserveObject('external objects')
- self.resourceObject = self.reserveObject('resources')
-
- root = {'Type': Name('Catalog'),
- 'Pages': self.pagesObject}
- self.writeObject(self.rootObject, root)
-
- self.infoDict = _create_pdf_info_dict('pdf', metadata or {})
-
- self.fontNames = {} # maps filenames to internal font names
- self._internal_font_seq = (Name(f'F{i}') for i in itertools.count(1))
- self.dviFontInfo = {} # maps dvi font names to embedding information
- # differently encoded Type-1 fonts may share the same descriptor
- self.type1Descriptors = {}
- self._character_tracker = _backend_pdf_ps.CharacterTracker()
-
- self.alphaStates = {} # maps alpha values to graphics state objects
- self._alpha_state_seq = (Name(f'A{i}') for i in itertools.count(1))
- self._soft_mask_states = {}
- self._soft_mask_seq = (Name(f'SM{i}') for i in itertools.count(1))
- self._soft_mask_groups = []
- self.hatchPatterns = {}
- self._hatch_pattern_seq = (Name(f'H{i}') for i in itertools.count(1))
- self.gouraudTriangles = []
-
- self._images = {}
- self._image_seq = (Name(f'I{i}') for i in itertools.count(1))
-
- self.markers = {}
- self.multi_byte_charprocs = {}
-
- self.paths = []
-
- # A list of annotations for each page. Each entry is a tuple of the
- # overall Annots object reference that's inserted into the page object,
- # followed by a list of the actual annotations.
- self._annotations = []
- # For annotations added before a page is created; mostly for the
- # purpose of newTextnote.
- self.pageAnnotations = []
-
- # The PDF spec recommends to include every procset
- procsets = [Name(x) for x in "PDF Text ImageB ImageC ImageI".split()]
-
- # Write resource dictionary.
- # Possibly TODO: more general ExtGState (graphics state dictionaries)
- # ColorSpace Pattern Shading Properties
- resources = {'Font': self.fontObject,
- 'XObject': self.XObjectObject,
- 'ExtGState': self._extGStateObject,
- 'Pattern': self.hatchObject,
- 'Shading': self.gouraudObject,
- 'ProcSet': procsets}
- self.writeObject(self.resourceObject, resources)
-
- def newPage(self, width, height):
- self.endStream()
-
- self.width, self.height = width, height
- contentObject = self.reserveObject('page contents')
- annotsObject = self.reserveObject('annotations')
- thePage = {'Type': Name('Page'),
- 'Parent': self.pagesObject,
- 'Resources': self.resourceObject,
- 'MediaBox': [0, 0, 72 * width, 72 * height],
- 'Contents': contentObject,
- 'Annots': annotsObject,
- }
- pageObject = self.reserveObject('page')
- self.writeObject(pageObject, thePage)
- self.pageList.append(pageObject)
- self._annotations.append((annotsObject, self.pageAnnotations))
-
- self.beginStream(contentObject.id,
- self.reserveObject('length of content stream'))
- # Initialize the pdf graphics state to match the default Matplotlib
- # graphics context (colorspace and joinstyle).
- self.output(Name('DeviceRGB'), Op.setcolorspace_stroke)
- self.output(Name('DeviceRGB'), Op.setcolorspace_nonstroke)
- self.output(GraphicsContextPdf.joinstyles['round'], Op.setlinejoin)
-
- # Clear the list of annotations for the next page
- self.pageAnnotations = []
-
- def newTextnote(self, text, positionRect=[-100, -100, 0, 0]):
- # Create a new annotation of type text
- theNote = {'Type': Name('Annot'),
- 'Subtype': Name('Text'),
- 'Contents': text,
- 'Rect': positionRect,
- }
- self.pageAnnotations.append(theNote)
-
- def _get_subsetted_psname(self, ps_name, charmap):
- def toStr(n, base):
- if n < base:
- return string.ascii_uppercase[n]
- else:
- return (
- toStr(n // base, base) + string.ascii_uppercase[n % base]
- )
-
- # encode to string using base 26
- hashed = hash(frozenset(charmap.keys())) % ((sys.maxsize + 1) * 2)
- prefix = toStr(hashed, 26)
-
- # get first 6 characters from prefix
- return prefix[:6] + "+" + ps_name
-
- def finalize(self):
- """Write out the various deferred objects and the pdf end matter."""
-
- self.endStream()
- self._write_annotations()
- self.writeFonts()
- self.writeExtGSTates()
- self._write_soft_mask_groups()
- self.writeHatches()
- self.writeGouraudTriangles()
- xobjects = {
- name: ob for image, name, ob in self._images.values()}
- for tup in self.markers.values():
- xobjects[tup[0]] = tup[1]
- for name, value in self.multi_byte_charprocs.items():
- xobjects[name] = value
- for name, path, trans, ob, join, cap, padding, filled, stroked \
- in self.paths:
- xobjects[name] = ob
- self.writeObject(self.XObjectObject, xobjects)
- self.writeImages()
- self.writeMarkers()
- self.writePathCollectionTemplates()
- self.writeObject(self.pagesObject,
- {'Type': Name('Pages'),
- 'Kids': self.pageList,
- 'Count': len(self.pageList)})
- self.writeInfoDict()
-
- # Finalize the file
- self.writeXref()
- self.writeTrailer()
-
- def close(self):
- """Flush all buffers and free all resources."""
-
- self.endStream()
- if self.passed_in_file_object:
- self.fh.flush()
- else:
- if self.original_file_like is not None:
- self.original_file_like.write(self.fh.getvalue())
- self.fh.close()
-
- def write(self, data):
- if self.currentstream is None:
- self.fh.write(data)
- else:
- self.currentstream.write(data)
-
- def output(self, *data):
- self.write(_fill([pdfRepr(x) for x in data]))
- self.write(b'\n')
-
- def beginStream(self, id, len, extra=None, png=None):
- assert self.currentstream is None
- self.currentstream = Stream(id, len, self, extra, png)
-
- def endStream(self):
- if self.currentstream is not None:
- self.currentstream.end()
- self.currentstream = None
-
- def outputStream(self, ref, data, *, extra=None):
- self.beginStream(ref.id, None, extra)
- self.currentstream.write(data)
- self.endStream()
-
- def _write_annotations(self):
- for annotsObject, annotations in self._annotations:
- self.writeObject(annotsObject, annotations)
-
- def fontName(self, fontprop):
- """
- Select a font based on fontprop and return a name suitable for
- Op.selectfont. If fontprop is a string, it will be interpreted
- as the filename of the font.
- """
-
- if isinstance(fontprop, str):
- filenames = [fontprop]
- elif mpl.rcParams['pdf.use14corefonts']:
- filenames = _fontManager._find_fonts_by_props(
- fontprop, fontext='afm', directory=RendererPdf._afm_font_dir
- )
- else:
- filenames = _fontManager._find_fonts_by_props(fontprop)
- first_Fx = None
- for fname in filenames:
- Fx = self.fontNames.get(fname)
- if not first_Fx:
- first_Fx = Fx
- if Fx is None:
- Fx = next(self._internal_font_seq)
- self.fontNames[fname] = Fx
- _log.debug('Assigning font %s = %r', Fx, fname)
- if not first_Fx:
- first_Fx = Fx
-
- # find_fontsprop's first value always adheres to
- # findfont's value, so technically no behaviour change
- return first_Fx
-
- def dviFontName(self, dvifont):
- """
- Given a dvi font object, return a name suitable for Op.selectfont.
- This registers the font information in ``self.dviFontInfo`` if not yet
- registered.
- """
-
- dvi_info = self.dviFontInfo.get(dvifont.texname)
- if dvi_info is not None:
- return dvi_info.pdfname
-
- tex_font_map = dviread.PsfontsMap(dviread.find_tex_file('pdftex.map'))
- psfont = tex_font_map[dvifont.texname]
- if psfont.filename is None:
- raise ValueError(
- "No usable font file found for {} (TeX: {}); "
- "the font may lack a Type-1 version"
- .format(psfont.psname, dvifont.texname))
-
- pdfname = next(self._internal_font_seq)
- _log.debug('Assigning font %s = %s (dvi)', pdfname, dvifont.texname)
- self.dviFontInfo[dvifont.texname] = types.SimpleNamespace(
- dvifont=dvifont,
- pdfname=pdfname,
- fontfile=psfont.filename,
- basefont=psfont.psname,
- encodingfile=psfont.encoding,
- effects=psfont.effects)
- return pdfname
-
- def writeFonts(self):
- fonts = {}
- for dviname, info in sorted(self.dviFontInfo.items()):
- Fx = info.pdfname
- _log.debug('Embedding Type-1 font %s from dvi.', dviname)
- fonts[Fx] = self._embedTeXFont(info)
- for filename in sorted(self.fontNames):
- Fx = self.fontNames[filename]
- _log.debug('Embedding font %s.', filename)
- if filename.endswith('.afm'):
- # from pdf.use14corefonts
- _log.debug('Writing AFM font.')
- fonts[Fx] = self._write_afm_font(filename)
- else:
- # a normal TrueType font
- _log.debug('Writing TrueType font.')
- chars = self._character_tracker.used.get(filename)
- if chars:
- fonts[Fx] = self.embedTTF(filename, chars)
- self.writeObject(self.fontObject, fonts)
-
- def _write_afm_font(self, filename):
- with open(filename, 'rb') as fh:
- font = AFM(fh)
- fontname = font.get_fontname()
- fontdict = {'Type': Name('Font'),
- 'Subtype': Name('Type1'),
- 'BaseFont': Name(fontname),
- 'Encoding': Name('WinAnsiEncoding')}
- fontdictObject = self.reserveObject('font dictionary')
- self.writeObject(fontdictObject, fontdict)
- return fontdictObject
-
- def _embedTeXFont(self, fontinfo):
- _log.debug('Embedding TeX font %s - fontinfo=%s',
- fontinfo.dvifont.texname, fontinfo.__dict__)
-
- # Widths
- widthsObject = self.reserveObject('font widths')
- self.writeObject(widthsObject, fontinfo.dvifont.widths)
-
- # Font dictionary
- fontdictObject = self.reserveObject('font dictionary')
- fontdict = {
- 'Type': Name('Font'),
- 'Subtype': Name('Type1'),
- 'FirstChar': 0,
- 'LastChar': len(fontinfo.dvifont.widths) - 1,
- 'Widths': widthsObject,
- }
-
- # Encoding (if needed)
- if fontinfo.encodingfile is not None:
- fontdict['Encoding'] = {
- 'Type': Name('Encoding'),
- 'Differences': [
- 0, *map(Name, dviread._parse_enc(fontinfo.encodingfile))],
- }
-
- # If no file is specified, stop short
- if fontinfo.fontfile is None:
- _log.warning(
- "Because of TeX configuration (pdftex.map, see updmap option "
- "pdftexDownloadBase14) the font %s is not embedded. This is "
- "deprecated as of PDF 1.5 and it may cause the consumer "
- "application to show something that was not intended.",
- fontinfo.basefont)
- fontdict['BaseFont'] = Name(fontinfo.basefont)
- self.writeObject(fontdictObject, fontdict)
- return fontdictObject
-
- # We have a font file to embed - read it in and apply any effects
- t1font = _type1font.Type1Font(fontinfo.fontfile)
- if fontinfo.effects:
- t1font = t1font.transform(fontinfo.effects)
- fontdict['BaseFont'] = Name(t1font.prop['FontName'])
-
- # Font descriptors may be shared between differently encoded
- # Type-1 fonts, so only create a new descriptor if there is no
- # existing descriptor for this font.
- effects = (fontinfo.effects.get('slant', 0.0),
- fontinfo.effects.get('extend', 1.0))
- fontdesc = self.type1Descriptors.get((fontinfo.fontfile, effects))
- if fontdesc is None:
- fontdesc = self.createType1Descriptor(t1font, fontinfo.fontfile)
- self.type1Descriptors[(fontinfo.fontfile, effects)] = fontdesc
- fontdict['FontDescriptor'] = fontdesc
-
- self.writeObject(fontdictObject, fontdict)
- return fontdictObject
-
- def createType1Descriptor(self, t1font, fontfile):
- # Create and write the font descriptor and the font file
- # of a Type-1 font
- fontdescObject = self.reserveObject('font descriptor')
- fontfileObject = self.reserveObject('font file')
-
- italic_angle = t1font.prop['ItalicAngle']
- fixed_pitch = t1font.prop['isFixedPitch']
-
- flags = 0
- # fixed width
- if fixed_pitch:
- flags |= 1 << 0
- # TODO: serif
- if 0:
- flags |= 1 << 1
- # TODO: symbolic (most TeX fonts are)
- if 1:
- flags |= 1 << 2
- # non-symbolic
- else:
- flags |= 1 << 5
- # italic
- if italic_angle:
- flags |= 1 << 6
- # TODO: all caps
- if 0:
- flags |= 1 << 16
- # TODO: small caps
- if 0:
- flags |= 1 << 17
- # TODO: force bold
- if 0:
- flags |= 1 << 18
-
- ft2font = get_font(fontfile)
-
- descriptor = {
- 'Type': Name('FontDescriptor'),
- 'FontName': Name(t1font.prop['FontName']),
- 'Flags': flags,
- 'FontBBox': ft2font.bbox,
- 'ItalicAngle': italic_angle,
- 'Ascent': ft2font.ascender,
- 'Descent': ft2font.descender,
- 'CapHeight': 1000, # TODO: find this out
- 'XHeight': 500, # TODO: this one too
- 'FontFile': fontfileObject,
- 'FontFamily': t1font.prop['FamilyName'],
- 'StemV': 50, # TODO
- # (see also revision 3874; but not all TeX distros have AFM files!)
- # 'FontWeight': a number where 400 = Regular, 700 = Bold
- }
-
- self.writeObject(fontdescObject, descriptor)
-
- self.outputStream(fontfileObject, b"".join(t1font.parts[:2]),
- extra={'Length1': len(t1font.parts[0]),
- 'Length2': len(t1font.parts[1]),
- 'Length3': 0})
-
- return fontdescObject
-
- def _get_xobject_glyph_name(self, filename, glyph_name):
- Fx = self.fontName(filename)
- return "-".join([
- Fx.name.decode(),
- os.path.splitext(os.path.basename(filename))[0],
- glyph_name])
-
- _identityToUnicodeCMap = b"""/CIDInit /ProcSet findresource begin
-12 dict begin
-begincmap
-/CIDSystemInfo
-<< /Registry (Adobe)
- /Ordering (UCS)
- /Supplement 0
->> def
-/CMapName /Adobe-Identity-UCS def
-/CMapType 2 def
-1 begincodespacerange
-<0000> <ffff>
-endcodespacerange
-%d beginbfrange
-%s
-endbfrange
-endcmap
-CMapName currentdict /CMap defineresource pop
-end
-end"""
-
- def embedTTF(self, filename, characters):
- """Embed the TTF font from the named file into the document."""
-
- font = get_font(filename)
- fonttype = mpl.rcParams['pdf.fonttype']
-
- def cvt(length, upe=font.units_per_EM, nearest=True):
- """Convert font coordinates to PDF glyph coordinates."""
- value = length / upe * 1000
- if nearest:
- return round(value)
- # Best(?) to round away from zero for bounding boxes and the like.
- if value < 0:
- return math.floor(value)
- else:
- return math.ceil(value)
-
- def embedTTFType3(font, characters, descriptor):
- """The Type 3-specific part of embedding a Truetype font"""
- widthsObject = self.reserveObject('font widths')
- fontdescObject = self.reserveObject('font descriptor')
- fontdictObject = self.reserveObject('font dictionary')
- charprocsObject = self.reserveObject('character procs')
- differencesArray = []
- firstchar, lastchar = 0, 255
- bbox = [cvt(x, nearest=False) for x in font.bbox]
-
- fontdict = {
- 'Type': Name('Font'),
- 'BaseFont': ps_name,
- 'FirstChar': firstchar,
- 'LastChar': lastchar,
- 'FontDescriptor': fontdescObject,
- 'Subtype': Name('Type3'),
- 'Name': descriptor['FontName'],
- 'FontBBox': bbox,
- 'FontMatrix': [.001, 0, 0, .001, 0, 0],
- 'CharProcs': charprocsObject,
- 'Encoding': {
- 'Type': Name('Encoding'),
- 'Differences': differencesArray},
- 'Widths': widthsObject
- }
-
- from encodings import cp1252
-
- # Make the "Widths" array
- def get_char_width(charcode):
- s = ord(cp1252.decoding_table[charcode])
- width = font.load_char(
- s, flags=LOAD_NO_SCALE | LOAD_NO_HINTING).horiAdvance
- return cvt(width)
- with warnings.catch_warnings():
- # Ignore 'Required glyph missing from current font' warning
- # from ft2font: here we're just building the widths table, but
- # the missing glyphs may not even be used in the actual string.
- warnings.filterwarnings("ignore")
- widths = [get_char_width(charcode)
- for charcode in range(firstchar, lastchar+1)]
- descriptor['MaxWidth'] = max(widths)
-
- # Make the "Differences" array, sort the ccodes < 255 from
- # the multi-byte ccodes, and build the whole set of glyph ids
- # that we need from this font.
- glyph_ids = []
- differences = []
- multi_byte_chars = set()
- for c in characters:
- ccode = c
- gind = font.get_char_index(ccode)
- glyph_ids.append(gind)
- glyph_name = font.get_glyph_name(gind)
- if ccode <= 255:
- differences.append((ccode, glyph_name))
- else:
- multi_byte_chars.add(glyph_name)
- differences.sort()
-
- last_c = -2
- for c, name in differences:
- if c != last_c + 1:
- differencesArray.append(c)
- differencesArray.append(Name(name))
- last_c = c
-
- # Make the charprocs array.
- rawcharprocs = _get_pdf_charprocs(filename, glyph_ids)
- charprocs = {}
- for charname in sorted(rawcharprocs):
- stream = rawcharprocs[charname]
- charprocDict = {}
- # The 2-byte characters are used as XObjects, so they
- # need extra info in their dictionary
- if charname in multi_byte_chars:
- charprocDict = {'Type': Name('XObject'),
- 'Subtype': Name('Form'),
- 'BBox': bbox}
- # Each glyph includes bounding box information,
- # but xpdf and ghostscript can't handle it in a
- # Form XObject (they segfault!!!), so we remove it
- # from the stream here. It's not needed anyway,
- # since the Form XObject includes it in its BBox
- # value.
- stream = stream[stream.find(b"d1") + 2:]
- charprocObject = self.reserveObject('charProc')
- self.outputStream(charprocObject, stream, extra=charprocDict)
-
- # Send the glyphs with ccode > 255 to the XObject dictionary,
- # and the others to the font itself
- if charname in multi_byte_chars:
- name = self._get_xobject_glyph_name(filename, charname)
- self.multi_byte_charprocs[name] = charprocObject
- else:
- charprocs[charname] = charprocObject
-
- # Write everything out
- self.writeObject(fontdictObject, fontdict)
- self.writeObject(fontdescObject, descriptor)
- self.writeObject(widthsObject, widths)
- self.writeObject(charprocsObject, charprocs)
-
- return fontdictObject
-
- def embedTTFType42(font, characters, descriptor):
- """The Type 42-specific part of embedding a Truetype font"""
- fontdescObject = self.reserveObject('font descriptor')
- cidFontDictObject = self.reserveObject('CID font dictionary')
- type0FontDictObject = self.reserveObject('Type 0 font dictionary')
- cidToGidMapObject = self.reserveObject('CIDToGIDMap stream')
- fontfileObject = self.reserveObject('font file stream')
- wObject = self.reserveObject('Type 0 widths')
- toUnicodeMapObject = self.reserveObject('ToUnicode map')
-
- subset_str = "".join(chr(c) for c in characters)
- _log.debug("SUBSET %s characters: %s", filename, subset_str)
- fontdata = _backend_pdf_ps.get_glyphs_subset(filename, subset_str)
- _log.debug(
- "SUBSET %s %d -> %d", filename,
- os.stat(filename).st_size, fontdata.getbuffer().nbytes
- )
-
- # We need this ref for XObjects
- full_font = font
-
- # reload the font object from the subset
- # (all the necessary data could probably be obtained directly
- # using fontLib.ttLib)
- font = FT2Font(fontdata)
-
- cidFontDict = {
- 'Type': Name('Font'),
- 'Subtype': Name('CIDFontType2'),
- 'BaseFont': ps_name,
- 'CIDSystemInfo': {
- 'Registry': 'Adobe',
- 'Ordering': 'Identity',
- 'Supplement': 0},
- 'FontDescriptor': fontdescObject,
- 'W': wObject,
- 'CIDToGIDMap': cidToGidMapObject
- }
-
- type0FontDict = {
- 'Type': Name('Font'),
- 'Subtype': Name('Type0'),
- 'BaseFont': ps_name,
- 'Encoding': Name('Identity-H'),
- 'DescendantFonts': [cidFontDictObject],
- 'ToUnicode': toUnicodeMapObject
- }
-
- # Make fontfile stream
- descriptor['FontFile2'] = fontfileObject
- self.outputStream(
- fontfileObject, fontdata.getvalue(),
- extra={'Length1': fontdata.getbuffer().nbytes})
-
- # Make the 'W' (Widths) array, CidToGidMap and ToUnicode CMap
- # at the same time
- cid_to_gid_map = ['\0'] * 65536
- widths = []
- max_ccode = 0
- for c in characters:
- ccode = c
- gind = font.get_char_index(ccode)
- glyph = font.load_char(ccode,
- flags=LOAD_NO_SCALE | LOAD_NO_HINTING)
- widths.append((ccode, cvt(glyph.horiAdvance)))
- if ccode < 65536:
- cid_to_gid_map[ccode] = chr(gind)
- max_ccode = max(ccode, max_ccode)
- widths.sort()
- cid_to_gid_map = cid_to_gid_map[:max_ccode + 1]
-
- last_ccode = -2
- w = []
- max_width = 0
- unicode_groups = []
- for ccode, width in widths:
- if ccode != last_ccode + 1:
- w.append(ccode)
- w.append([width])
- unicode_groups.append([ccode, ccode])
- else:
- w[-1].append(width)
- unicode_groups[-1][1] = ccode
- max_width = max(max_width, width)
- last_ccode = ccode
-
- unicode_bfrange = []
- for start, end in unicode_groups:
- # Ensure the CID map contains only chars from BMP
- if start > 65535:
- continue
- end = min(65535, end)
-
- unicode_bfrange.append(
- b"<%04x> <%04x> [%s]" %
- (start, end,
- b" ".join(b"<%04x>" % x for x in range(start, end+1))))
- unicode_cmap = (self._identityToUnicodeCMap %
- (len(unicode_groups), b"\n".join(unicode_bfrange)))
-
- # Add XObjects for unsupported chars
- glyph_ids = []
- for ccode in characters:
- if not _font_supports_glyph(fonttype, ccode):
- gind = full_font.get_char_index(ccode)
- glyph_ids.append(gind)
-
- bbox = [cvt(x, nearest=False) for x in full_font.bbox]
- rawcharprocs = _get_pdf_charprocs(filename, glyph_ids)
- for charname in sorted(rawcharprocs):
- stream = rawcharprocs[charname]
- charprocDict = {'Type': Name('XObject'),
- 'Subtype': Name('Form'),
- 'BBox': bbox}
- # Each glyph includes bounding box information,
- # but xpdf and ghostscript can't handle it in a
- # Form XObject (they segfault!!!), so we remove it
- # from the stream here. It's not needed anyway,
- # since the Form XObject includes it in its BBox
- # value.
- stream = stream[stream.find(b"d1") + 2:]
- charprocObject = self.reserveObject('charProc')
- self.outputStream(charprocObject, stream, extra=charprocDict)
-
- name = self._get_xobject_glyph_name(filename, charname)
- self.multi_byte_charprocs[name] = charprocObject
-
- # CIDToGIDMap stream
- cid_to_gid_map = "".join(cid_to_gid_map).encode("utf-16be")
- self.outputStream(cidToGidMapObject, cid_to_gid_map)
-
- # ToUnicode CMap
- self.outputStream(toUnicodeMapObject, unicode_cmap)
-
- descriptor['MaxWidth'] = max_width
-
- # Write everything out
- self.writeObject(cidFontDictObject, cidFontDict)
- self.writeObject(type0FontDictObject, type0FontDict)
- self.writeObject(fontdescObject, descriptor)
- self.writeObject(wObject, w)
-
- return type0FontDictObject
-
- # Beginning of main embedTTF function...
-
- ps_name = self._get_subsetted_psname(
- font.postscript_name,
- font.get_charmap()
- )
- ps_name = ps_name.encode('ascii', 'replace')
- ps_name = Name(ps_name)
- pclt = font.get_sfnt_table('pclt') or {'capHeight': 0, 'xHeight': 0}
- post = font.get_sfnt_table('post') or {'italicAngle': (0, 0)}
- ff = font.face_flags
- sf = font.style_flags
-
- flags = 0
- symbolic = False # ps_name.name in ('Cmsy10', 'Cmmi10', 'Cmex10')
- if ff & FIXED_WIDTH:
- flags |= 1 << 0
- if 0: # TODO: serif
- flags |= 1 << 1
- if symbolic:
- flags |= 1 << 2
- else:
- flags |= 1 << 5
- if sf & ITALIC:
- flags |= 1 << 6
- if 0: # TODO: all caps
- flags |= 1 << 16
- if 0: # TODO: small caps
- flags |= 1 << 17
- if 0: # TODO: force bold
- flags |= 1 << 18
-
- descriptor = {
- 'Type': Name('FontDescriptor'),
- 'FontName': ps_name,
- 'Flags': flags,
- 'FontBBox': [cvt(x, nearest=False) for x in font.bbox],
- 'Ascent': cvt(font.ascender, nearest=False),
- 'Descent': cvt(font.descender, nearest=False),
- 'CapHeight': cvt(pclt['capHeight'], nearest=False),
- 'XHeight': cvt(pclt['xHeight']),
- 'ItalicAngle': post['italicAngle'][1], # ???
- 'StemV': 0 # ???
- }
-
- if fonttype == 3:
- return embedTTFType3(font, characters, descriptor)
- elif fonttype == 42:
- return embedTTFType42(font, characters, descriptor)
-
- def alphaState(self, alpha):
- """Return name of an ExtGState that sets alpha to the given value."""
-
- state = self.alphaStates.get(alpha, None)
- if state is not None:
- return state[0]
-
- name = next(self._alpha_state_seq)
- self.alphaStates[alpha] = \
- (name, {'Type': Name('ExtGState'),
- 'CA': alpha[0], 'ca': alpha[1]})
- return name
-
- def _soft_mask_state(self, smask):
- """
- Return an ExtGState that sets the soft mask to the given shading.
-
- Parameters
- ----------
- smask : Reference
- Reference to a shading in DeviceGray color space, whose luminosity
- is to be used as the alpha channel.
-
- Returns
- -------
- Name
- """
-
- state = self._soft_mask_states.get(smask, None)
- if state is not None:
- return state[0]
-
- name = next(self._soft_mask_seq)
- groupOb = self.reserveObject('transparency group for soft mask')
- self._soft_mask_states[smask] = (
- name,
- {
- 'Type': Name('ExtGState'),
- 'AIS': False,
- 'SMask': {
- 'Type': Name('Mask'),
- 'S': Name('Luminosity'),
- 'BC': [1],
- 'G': groupOb
- }
- }
- )
- self._soft_mask_groups.append((
- groupOb,
- {
- 'Type': Name('XObject'),
- 'Subtype': Name('Form'),
- 'FormType': 1,
- 'Group': {
- 'S': Name('Transparency'),
- 'CS': Name('DeviceGray')
- },
- 'Matrix': [1, 0, 0, 1, 0, 0],
- 'Resources': {'Shading': {'S': smask}},
- 'BBox': [0, 0, 1, 1]
- },
- [Name('S'), Op.shading]
- ))
- return name
-
- def writeExtGSTates(self):
- self.writeObject(
- self._extGStateObject,
- dict([
- *self.alphaStates.values(),
- *self._soft_mask_states.values()
- ])
- )
-
- def _write_soft_mask_groups(self):
- for ob, attributes, content in self._soft_mask_groups:
- self.beginStream(ob.id, None, attributes)
- self.output(*content)
- self.endStream()
-
- def hatchPattern(self, hatch_style):
- # The colors may come in as numpy arrays, which aren't hashable
- if hatch_style is not None:
- edge, face, hatch = hatch_style
- if edge is not None:
- edge = tuple(edge)
- if face is not None:
- face = tuple(face)
- hatch_style = (edge, face, hatch)
-
- pattern = self.hatchPatterns.get(hatch_style, None)
- if pattern is not None:
- return pattern
-
- name = next(self._hatch_pattern_seq)
- self.hatchPatterns[hatch_style] = name
- return name
-
- def writeHatches(self):
- hatchDict = dict()
- sidelen = 72.0
- for hatch_style, name in self.hatchPatterns.items():
- ob = self.reserveObject('hatch pattern')
- hatchDict[name] = ob
- res = {'Procsets':
- [Name(x) for x in "PDF Text ImageB ImageC ImageI".split()]}
- self.beginStream(
- ob.id, None,
- {'Type': Name('Pattern'),
- 'PatternType': 1, 'PaintType': 1, 'TilingType': 1,
- 'BBox': [0, 0, sidelen, sidelen],
- 'XStep': sidelen, 'YStep': sidelen,
- 'Resources': res,
- # Change origin to match Agg at top-left.
- 'Matrix': [1, 0, 0, 1, 0, self.height * 72]})
-
- stroke_rgb, fill_rgb, hatch = hatch_style
- self.output(stroke_rgb[0], stroke_rgb[1], stroke_rgb[2],
- Op.setrgb_stroke)
- if fill_rgb is not None:
- self.output(fill_rgb[0], fill_rgb[1], fill_rgb[2],
- Op.setrgb_nonstroke,
- 0, 0, sidelen, sidelen, Op.rectangle,
- Op.fill)
-
- self.output(mpl.rcParams['hatch.linewidth'], Op.setlinewidth)
-
- self.output(*self.pathOperations(
- Path.hatch(hatch),
- Affine2D().scale(sidelen),
- simplify=False))
- self.output(Op.fill_stroke)
-
- self.endStream()
- self.writeObject(self.hatchObject, hatchDict)
-
- def addGouraudTriangles(self, points, colors):
- """
- Add a Gouraud triangle shading.
-
- Parameters
- ----------
- points : np.ndarray
- Triangle vertices, shape (n, 3, 2)
- where n = number of triangles, 3 = vertices, 2 = x, y.
- colors : np.ndarray
- Vertex colors, shape (n, 3, 1) or (n, 3, 4)
- as with points, but last dimension is either (gray,)
- or (r, g, b, alpha).
-
- Returns
- -------
- Name, Reference
- """
- name = Name('GT%d' % len(self.gouraudTriangles))
- ob = self.reserveObject(f'Gouraud triangle {name}')
- self.gouraudTriangles.append((name, ob, points, colors))
- return name, ob
-
- def writeGouraudTriangles(self):
- gouraudDict = dict()
- for name, ob, points, colors in self.gouraudTriangles:
- gouraudDict[name] = ob
- shape = points.shape
- flat_points = points.reshape((shape[0] * shape[1], 2))
- colordim = colors.shape[2]
- assert colordim in (1, 4)
- flat_colors = colors.reshape((shape[0] * shape[1], colordim))
- if colordim == 4:
- # strip the alpha channel
- colordim = 3
- points_min = np.min(flat_points, axis=0) - (1 << 8)
- points_max = np.max(flat_points, axis=0) + (1 << 8)
- factor = 0xffffffff / (points_max - points_min)
-
- self.beginStream(
- ob.id, None,
- {'ShadingType': 4,
- 'BitsPerCoordinate': 32,
- 'BitsPerComponent': 8,
- 'BitsPerFlag': 8,
- 'ColorSpace': Name(
- 'DeviceRGB' if colordim == 3 else 'DeviceGray'
- ),
- 'AntiAlias': False,
- 'Decode': ([points_min[0], points_max[0],
- points_min[1], points_max[1]]
- + [0, 1] * colordim),
- })
-
- streamarr = np.empty(
- (shape[0] * shape[1],),
- dtype=[('flags', 'u1'),
- ('points', '>u4', (2,)),
- ('colors', 'u1', (colordim,))])
- streamarr['flags'] = 0
- streamarr['points'] = (flat_points - points_min) * factor
- streamarr['colors'] = flat_colors[:, :colordim] * 255.0
-
- self.write(streamarr.tobytes())
- self.endStream()
- self.writeObject(self.gouraudObject, gouraudDict)
-
- def imageObject(self, image):
- """Return name of an image XObject representing the given image."""
-
- entry = self._images.get(id(image), None)
- if entry is not None:
- return entry[1]
-
- name = next(self._image_seq)
- ob = self.reserveObject(f'image {name}')
- self._images[id(image)] = (image, name, ob)
- return name
-
- def _unpack(self, im):
- """
- Unpack image array *im* into ``(data, alpha)``, which have shape
- ``(height, width, 3)`` (RGB) or ``(height, width, 1)`` (grayscale or
- alpha), except that alpha is None if the image is fully opaque.
- """
- im = im[::-1]
- if im.ndim == 2:
- return im, None
- else:
- rgb = im[:, :, :3]
- rgb = np.array(rgb, order='C')
- # PDF needs a separate alpha image
- if im.shape[2] == 4:
- alpha = im[:, :, 3][..., None]
- if np.all(alpha == 255):
- alpha = None
- else:
- alpha = np.array(alpha, order='C')
- else:
- alpha = None
- return rgb, alpha
-
- def _writePng(self, img):
- """
- Write the image *img* into the pdf file using png
- predictors with Flate compression.
- """
- buffer = BytesIO()
- img.save(buffer, format="png")
- buffer.seek(8)
- png_data = b''
- bit_depth = palette = None
- while True:
- length, type = struct.unpack(b'!L4s', buffer.read(8))
- if type in [b'IHDR', b'PLTE', b'IDAT']:
- data = buffer.read(length)
- if len(data) != length:
- raise RuntimeError("truncated data")
- if type == b'IHDR':
- bit_depth = int(data[8])
- elif type == b'PLTE':
- palette = data
- elif type == b'IDAT':
- png_data += data
- elif type == b'IEND':
- break
- else:
- buffer.seek(length, 1)
- buffer.seek(4, 1) # skip CRC
- return png_data, bit_depth, palette
-
- def _writeImg(self, data, id, smask=None):
- """
- Write the image *data*, of shape ``(height, width, 1)`` (grayscale) or
- ``(height, width, 3)`` (RGB), as pdf object *id* and with the soft mask
- (alpha channel) *smask*, which should be either None or a ``(height,
- width, 1)`` array.
- """
- height, width, color_channels = data.shape
- obj = {'Type': Name('XObject'),
- 'Subtype': Name('Image'),
- 'Width': width,
- 'Height': height,
- 'ColorSpace': Name({1: 'DeviceGray', 3: 'DeviceRGB'}[color_channels]),
- 'BitsPerComponent': 8}
- if smask:
- obj['SMask'] = smask
- if mpl.rcParams['pdf.compression']:
- if data.shape[-1] == 1:
- data = data.squeeze(axis=-1)
- png = {'Predictor': 10, 'Colors': color_channels, 'Columns': width}
- img = Image.fromarray(data)
- img_colors = img.getcolors(maxcolors=256)
- if color_channels == 3 and img_colors is not None:
- # Convert to indexed color if there are 256 colors or fewer. This can
- # significantly reduce the file size.
- num_colors = len(img_colors)
- palette = np.array([comp for _, color in img_colors for comp in color],
- dtype=np.uint8)
- palette24 = ((palette[0::3].astype(np.uint32) << 16) |
- (palette[1::3].astype(np.uint32) << 8) |
- palette[2::3])
- rgb24 = ((data[:, :, 0].astype(np.uint32) << 16) |
- (data[:, :, 1].astype(np.uint32) << 8) |
- data[:, :, 2])
- indices = np.argsort(palette24).astype(np.uint8)
- rgb8 = indices[np.searchsorted(palette24, rgb24, sorter=indices)]
- img = Image.fromarray(rgb8, mode='P')
- img.putpalette(palette)
- png_data, bit_depth, palette = self._writePng(img)
- if bit_depth is None or palette is None:
- raise RuntimeError("invalid PNG header")
- palette = palette[:num_colors * 3] # Trim padding; remove for Pillow>=9
- obj['ColorSpace'] = [Name('Indexed'), Name('DeviceRGB'),
- num_colors - 1, palette]
- obj['BitsPerComponent'] = bit_depth
- png['Colors'] = 1
- png['BitsPerComponent'] = bit_depth
- else:
- png_data, _, _ = self._writePng(img)
- else:
- png = None
- self.beginStream(
- id,
- self.reserveObject('length of image stream'),
- obj,
- png=png
- )
- if png:
- self.currentstream.write(png_data)
- else:
- self.currentstream.write(data.tobytes())
- self.endStream()
-
- def writeImages(self):
- for img, name, ob in self._images.values():
- data, adata = self._unpack(img)
- if adata is not None:
- smaskObject = self.reserveObject("smask")
- self._writeImg(adata, smaskObject.id)
- else:
- smaskObject = None
- self._writeImg(data, ob.id, smaskObject)
-
- def markerObject(self, path, trans, fill, stroke, lw, joinstyle,
- capstyle):
- """Return name of a marker XObject representing the given path."""
- # self.markers used by markerObject, writeMarkers, close:
- # mapping from (path operations, fill?, stroke?) to
- # [name, object reference, bounding box, linewidth]
- # This enables different draw_markers calls to share the XObject
- # if the gc is sufficiently similar: colors etc can vary, but
- # the choices of whether to fill and whether to stroke cannot.
- # We need a bounding box enclosing all of the XObject path,
- # but since line width may vary, we store the maximum of all
- # occurring line widths in self.markers.
- # close() is somewhat tightly coupled in that it expects the
- # first two components of each value in self.markers to be the
- # name and object reference.
- pathops = self.pathOperations(path, trans, simplify=False)
- key = (tuple(pathops), bool(fill), bool(stroke), joinstyle, capstyle)
- result = self.markers.get(key)
- if result is None:
- name = Name('M%d' % len(self.markers))
- ob = self.reserveObject('marker %d' % len(self.markers))
- bbox = path.get_extents(trans)
- self.markers[key] = [name, ob, bbox, lw]
- else:
- if result[-1] < lw:
- result[-1] = lw
- name = result[0]
- return name
-
- def writeMarkers(self):
- for ((pathops, fill, stroke, joinstyle, capstyle),
- (name, ob, bbox, lw)) in self.markers.items():
- # bbox wraps the exact limits of the control points, so half a line
- # will appear outside it. If the join style is miter and the line
- # is not parallel to the edge, then the line will extend even
- # further. From the PDF specification, Section 8.4.3.5, the miter
- # limit is miterLength / lineWidth and from Table 52, the default
- # is 10. With half the miter length outside, that works out to the
- # following padding:
- bbox = bbox.padded(lw * 5)
- self.beginStream(
- ob.id, None,
- {'Type': Name('XObject'), 'Subtype': Name('Form'),
- 'BBox': list(bbox.extents)})
- self.output(GraphicsContextPdf.joinstyles[joinstyle],
- Op.setlinejoin)
- self.output(GraphicsContextPdf.capstyles[capstyle], Op.setlinecap)
- self.output(*pathops)
- self.output(Op.paint_path(fill, stroke))
- self.endStream()
-
- def pathCollectionObject(self, gc, path, trans, padding, filled, stroked):
- name = Name('P%d' % len(self.paths))
- ob = self.reserveObject('path %d' % len(self.paths))
- self.paths.append(
- (name, path, trans, ob, gc.get_joinstyle(), gc.get_capstyle(),
- padding, filled, stroked))
- return name
-
- def writePathCollectionTemplates(self):
- for (name, path, trans, ob, joinstyle, capstyle, padding, filled,
- stroked) in self.paths:
- pathops = self.pathOperations(path, trans, simplify=False)
- bbox = path.get_extents(trans)
- if not np.all(np.isfinite(bbox.extents)):
- extents = [0, 0, 0, 0]
- else:
- bbox = bbox.padded(padding)
- extents = list(bbox.extents)
- self.beginStream(
- ob.id, None,
- {'Type': Name('XObject'), 'Subtype': Name('Form'),
- 'BBox': extents})
- self.output(GraphicsContextPdf.joinstyles[joinstyle],
- Op.setlinejoin)
- self.output(GraphicsContextPdf.capstyles[capstyle], Op.setlinecap)
- self.output(*pathops)
- self.output(Op.paint_path(filled, stroked))
- self.endStream()
-
- @staticmethod
- def pathOperations(path, transform, clip=None, simplify=None, sketch=None):
- return [Verbatim(_path.convert_to_string(
- path, transform, clip, simplify, sketch,
- 6,
- [Op.moveto.value, Op.lineto.value, b'', Op.curveto.value,
- Op.closepath.value],
- True))]
-
- def writePath(self, path, transform, clip=False, sketch=None):
- if clip:
- clip = (0.0, 0.0, self.width * 72, self.height * 72)
- simplify = path.should_simplify
- else:
- clip = None
- simplify = False
- cmds = self.pathOperations(path, transform, clip, simplify=simplify,
- sketch=sketch)
- self.output(*cmds)
-
- def reserveObject(self, name=''):
- """
- Reserve an ID for an indirect object.
-
- The name is used for debugging in case we forget to print out
- the object with writeObject.
- """
- id = next(self._object_seq)
- self.xrefTable.append([None, 0, name])
- return Reference(id)
-
- def recordXref(self, id):
- self.xrefTable[id][0] = self.fh.tell() - self.tell_base
-
- def writeObject(self, object, contents):
- self.recordXref(object.id)
- object.write(contents, self)
-
- def writeXref(self):
- """Write out the xref table."""
- self.startxref = self.fh.tell() - self.tell_base
- self.write(b"xref\n0 %d\n" % len(self.xrefTable))
- for i, (offset, generation, name) in enumerate(self.xrefTable):
- if offset is None:
- raise AssertionError(
- 'No offset for object %d (%s)' % (i, name))
- else:
- key = b"f" if name == 'the zero object' else b"n"
- text = b"%010d %05d %b \n" % (offset, generation, key)
- self.write(text)
-
- def writeInfoDict(self):
- """Write out the info dictionary, checking it for good form"""
-
- self.infoObject = self.reserveObject('info')
- self.writeObject(self.infoObject, self.infoDict)
-
- def writeTrailer(self):
- """Write out the PDF trailer."""
-
- self.write(b"trailer\n")
- self.write(pdfRepr(
- {'Size': len(self.xrefTable),
- 'Root': self.rootObject,
- 'Info': self.infoObject}))
- # Could add 'ID'
- self.write(b"\nstartxref\n%d\n%%%%EOF\n" % self.startxref)
-
-
-class RendererPdf(_backend_pdf_ps.RendererPDFPSBase):
-
- _afm_font_dir = cbook._get_data_path("fonts/pdfcorefonts")
- _use_afm_rc_name = "pdf.use14corefonts"
-
- def __init__(self, file, image_dpi, height, width):
- super().__init__(width, height)
- self.file = file
- self.gc = self.new_gc()
- self.image_dpi = image_dpi
-
- def finalize(self):
- self.file.output(*self.gc.finalize())
-
- def check_gc(self, gc, fillcolor=None):
- orig_fill = getattr(gc, '_fillcolor', (0., 0., 0.))
- gc._fillcolor = fillcolor
-
- orig_alphas = getattr(gc, '_effective_alphas', (1.0, 1.0))
-
- if gc.get_rgb() is None:
- # It should not matter what color here since linewidth should be
- # 0 unless affected by global settings in rcParams, hence setting
- # zero alpha just in case.
- gc.set_foreground((0, 0, 0, 0), isRGBA=True)
-
- if gc._forced_alpha:
- gc._effective_alphas = (gc._alpha, gc._alpha)
- elif fillcolor is None or len(fillcolor) < 4:
- gc._effective_alphas = (gc._rgb[3], 1.0)
- else:
- gc._effective_alphas = (gc._rgb[3], fillcolor[3])
-
- delta = self.gc.delta(gc)
- if delta:
- self.file.output(*delta)
-
- # Restore gc to avoid unwanted side effects
- gc._fillcolor = orig_fill
- gc._effective_alphas = orig_alphas
-
- def get_image_magnification(self):
- return self.image_dpi/72.0
-
- def draw_image(self, gc, x, y, im, transform=None):
- # docstring inherited
-
- h, w = im.shape[:2]
- if w == 0 or h == 0:
- return
-
- if transform is None:
- # If there's no transform, alpha has already been applied
- gc.set_alpha(1.0)
-
- self.check_gc(gc)
-
- w = 72.0 * w / self.image_dpi
- h = 72.0 * h / self.image_dpi
-
- imob = self.file.imageObject(im)
-
- if transform is None:
- self.file.output(Op.gsave,
- w, 0, 0, h, x, y, Op.concat_matrix,
- imob, Op.use_xobject, Op.grestore)
- else:
- tr1, tr2, tr3, tr4, tr5, tr6 = transform.frozen().to_values()
-
- self.file.output(Op.gsave,
- 1, 0, 0, 1, x, y, Op.concat_matrix,
- tr1, tr2, tr3, tr4, tr5, tr6, Op.concat_matrix,
- imob, Op.use_xobject, Op.grestore)
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- # docstring inherited
- self.check_gc(gc, rgbFace)
- self.file.writePath(
- path, transform,
- rgbFace is None and gc.get_hatch_path() is None,
- gc.get_sketch_params())
- self.file.output(self.gc.paint())
-
- def draw_path_collection(self, gc, master_transform, paths, all_transforms,
- offsets, offset_trans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position):
- # We can only reuse the objects if the presence of fill and
- # stroke (and the amount of alpha for each) is the same for
- # all of them
- can_do_optimization = True
- facecolors = np.asarray(facecolors)
- edgecolors = np.asarray(edgecolors)
-
- if not len(facecolors):
- filled = False
- can_do_optimization = not gc.get_hatch()
- else:
- if np.all(facecolors[:, 3] == facecolors[0, 3]):
- filled = facecolors[0, 3] != 0.0
- else:
- can_do_optimization = False
-
- if not len(edgecolors):
- stroked = False
- else:
- if np.all(np.asarray(linewidths) == 0.0):
- stroked = False
- elif np.all(edgecolors[:, 3] == edgecolors[0, 3]):
- stroked = edgecolors[0, 3] != 0.0
- else:
- can_do_optimization = False
-
- # Is the optimization worth it? Rough calculation:
- # cost of emitting a path in-line is len_path * uses_per_path
- # cost of XObject is len_path + 5 for the definition,
- # uses_per_path for the uses
- len_path = len(paths[0].vertices) if len(paths) > 0 else 0
- uses_per_path = self._iter_collection_uses_per_path(
- paths, all_transforms, offsets, facecolors, edgecolors)
- should_do_optimization = \
- len_path + uses_per_path + 5 < len_path * uses_per_path
-
- if (not can_do_optimization) or (not should_do_optimization):
- return RendererBase.draw_path_collection(
- self, gc, master_transform, paths, all_transforms,
- offsets, offset_trans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position)
-
- padding = np.max(linewidths)
- path_codes = []
- for i, (path, transform) in enumerate(self._iter_collection_raw_paths(
- master_transform, paths, all_transforms)):
- name = self.file.pathCollectionObject(
- gc, path, transform, padding, filled, stroked)
- path_codes.append(name)
-
- output = self.file.output
- output(*self.gc.push())
- lastx, lasty = 0, 0
- for xo, yo, path_id, gc0, rgbFace in self._iter_collection(
- gc, path_codes, offsets, offset_trans,
- facecolors, edgecolors, linewidths, linestyles,
- antialiaseds, urls, offset_position):
-
- self.check_gc(gc0, rgbFace)
- dx, dy = xo - lastx, yo - lasty
- output(1, 0, 0, 1, dx, dy, Op.concat_matrix, path_id,
- Op.use_xobject)
- lastx, lasty = xo, yo
- output(*self.gc.pop())
-
- def draw_markers(self, gc, marker_path, marker_trans, path, trans,
- rgbFace=None):
- # docstring inherited
-
- # Same logic as in draw_path_collection
- len_marker_path = len(marker_path)
- uses = len(path)
- if len_marker_path * uses < len_marker_path + uses + 5:
- RendererBase.draw_markers(self, gc, marker_path, marker_trans,
- path, trans, rgbFace)
- return
-
- self.check_gc(gc, rgbFace)
- fill = gc.fill(rgbFace)
- stroke = gc.stroke()
-
- output = self.file.output
- marker = self.file.markerObject(
- marker_path, marker_trans, fill, stroke, self.gc._linewidth,
- gc.get_joinstyle(), gc.get_capstyle())
-
- output(Op.gsave)
- lastx, lasty = 0, 0
- for vertices, code in path.iter_segments(
- trans,
- clip=(0, 0, self.file.width*72, self.file.height*72),
- simplify=False):
- if len(vertices):
- x, y = vertices[-2:]
- if not (0 <= x <= self.file.width * 72
- and 0 <= y <= self.file.height * 72):
- continue
- dx, dy = x - lastx, y - lasty
- output(1, 0, 0, 1, dx, dy, Op.concat_matrix,
- marker, Op.use_xobject)
- lastx, lasty = x, y
- output(Op.grestore)
-
- def draw_gouraud_triangle(self, gc, points, colors, trans):
- self.draw_gouraud_triangles(gc, points.reshape((1, 3, 2)),
- colors.reshape((1, 3, 4)), trans)
-
- def draw_gouraud_triangles(self, gc, points, colors, trans):
- assert len(points) == len(colors)
- if len(points) == 0:
- return
- assert points.ndim == 3
- assert points.shape[1] == 3
- assert points.shape[2] == 2
- assert colors.ndim == 3
- assert colors.shape[1] == 3
- assert colors.shape[2] in (1, 4)
-
- shape = points.shape
- points = points.reshape((shape[0] * shape[1], 2))
- tpoints = trans.transform(points)
- tpoints = tpoints.reshape(shape)
- name, _ = self.file.addGouraudTriangles(tpoints, colors)
- output = self.file.output
-
- if colors.shape[2] == 1:
- # grayscale
- gc.set_alpha(1.0)
- self.check_gc(gc)
- output(name, Op.shading)
- return
-
- alpha = colors[0, 0, 3]
- if np.allclose(alpha, colors[:, :, 3]):
- # single alpha value
- gc.set_alpha(alpha)
- self.check_gc(gc)
- output(name, Op.shading)
- else:
- # varying alpha: use a soft mask
- alpha = colors[:, :, 3][:, :, None]
- _, smask_ob = self.file.addGouraudTriangles(tpoints, alpha)
- gstate = self.file._soft_mask_state(smask_ob)
- output(Op.gsave, gstate, Op.setgstate,
- name, Op.shading,
- Op.grestore)
-
- def _setup_textpos(self, x, y, angle, oldx=0, oldy=0, oldangle=0):
- if angle == oldangle == 0:
- self.file.output(x - oldx, y - oldy, Op.textpos)
- else:
- angle = math.radians(angle)
- self.file.output(math.cos(angle), math.sin(angle),
- -math.sin(angle), math.cos(angle),
- x, y, Op.textmatrix)
- self.file.output(0, 0, Op.textpos)
-
- def draw_mathtext(self, gc, x, y, s, prop, angle):
- # TODO: fix positioning and encoding
- width, height, descent, glyphs, rects = \
- self._text2path.mathtext_parser.parse(s, 72, prop)
-
- if gc.get_url() is not None:
- self.file._annotations[-1][1].append(_get_link_annotation(
- gc, x, y, width, height, angle))
-
- fonttype = mpl.rcParams['pdf.fonttype']
-
- # Set up a global transformation matrix for the whole math expression
- a = math.radians(angle)
- self.file.output(Op.gsave)
- self.file.output(math.cos(a), math.sin(a),
- -math.sin(a), math.cos(a),
- x, y, Op.concat_matrix)
-
- self.check_gc(gc, gc._rgb)
- prev_font = None, None
- oldx, oldy = 0, 0
- unsupported_chars = []
-
- self.file.output(Op.begin_text)
- for font, fontsize, num, ox, oy in glyphs:
- self.file._character_tracker.track_glyph(font, num)
- fontname = font.fname
- if not _font_supports_glyph(fonttype, num):
- # Unsupported chars (i.e. multibyte in Type 3 or beyond BMP in
- # Type 42) must be emitted separately (below).
- unsupported_chars.append((font, fontsize, ox, oy, num))
- else:
- self._setup_textpos(ox, oy, 0, oldx, oldy)
- oldx, oldy = ox, oy
- if (fontname, fontsize) != prev_font:
- self.file.output(self.file.fontName(fontname), fontsize,
- Op.selectfont)
- prev_font = fontname, fontsize
- self.file.output(self.encode_string(chr(num), fonttype),
- Op.show)
- self.file.output(Op.end_text)
-
- for font, fontsize, ox, oy, num in unsupported_chars:
- self._draw_xobject_glyph(
- font, fontsize, font.get_char_index(num), ox, oy)
-
- # Draw any horizontal lines in the math layout
- for ox, oy, width, height in rects:
- self.file.output(Op.gsave, ox, oy, width, height,
- Op.rectangle, Op.fill, Op.grestore)
-
- # Pop off the global transformation
- self.file.output(Op.grestore)
-
- def draw_tex(self, gc, x, y, s, prop, angle, *, mtext=None):
- # docstring inherited
- texmanager = self.get_texmanager()
- fontsize = prop.get_size_in_points()
- dvifile = texmanager.make_dvi(s, fontsize)
- with dviread.Dvi(dvifile, 72) as dvi:
- page, = dvi
-
- if gc.get_url() is not None:
- self.file._annotations[-1][1].append(_get_link_annotation(
- gc, x, y, page.width, page.height, angle))
-
- # Gather font information and do some setup for combining
- # characters into strings. The variable seq will contain a
- # sequence of font and text entries. A font entry is a list
- # ['font', name, size] where name is a Name object for the
- # font. A text entry is ['text', x, y, glyphs, x+w] where x
- # and y are the starting coordinates, w is the width, and
- # glyphs is a list; in this phase it will always contain just
- # one single-character string, but later it may have longer
- # strings interspersed with kern amounts.
- oldfont, seq = None, []
- for x1, y1, dvifont, glyph, width in page.text:
- if dvifont != oldfont:
- pdfname = self.file.dviFontName(dvifont)
- seq += [['font', pdfname, dvifont.size]]
- oldfont = dvifont
- seq += [['text', x1, y1, [bytes([glyph])], x1+width]]
-
- # Find consecutive text strings with constant y coordinate and
- # combine into a sequence of strings and kerns, or just one
- # string (if any kerns would be less than 0.1 points).
- i, curx, fontsize = 0, 0, None
- while i < len(seq)-1:
- elt, nxt = seq[i:i+2]
- if elt[0] == 'font':
- fontsize = elt[2]
- elif elt[0] == nxt[0] == 'text' and elt[2] == nxt[2]:
- offset = elt[4] - nxt[1]
- if abs(offset) < 0.1:
- elt[3][-1] += nxt[3][0]
- elt[4] += nxt[4]-nxt[1]
- else:
- elt[3] += [offset*1000.0/fontsize, nxt[3][0]]
- elt[4] = nxt[4]
- del seq[i+1]
- continue
- i += 1
-
- # Create a transform to map the dvi contents to the canvas.
- mytrans = Affine2D().rotate_deg(angle).translate(x, y)
-
- # Output the text.
- self.check_gc(gc, gc._rgb)
- self.file.output(Op.begin_text)
- curx, cury, oldx, oldy = 0, 0, 0, 0
- for elt in seq:
- if elt[0] == 'font':
- self.file.output(elt[1], elt[2], Op.selectfont)
- elif elt[0] == 'text':
- curx, cury = mytrans.transform((elt[1], elt[2]))
- self._setup_textpos(curx, cury, angle, oldx, oldy)
- oldx, oldy = curx, cury
- if len(elt[3]) == 1:
- self.file.output(elt[3][0], Op.show)
- else:
- self.file.output(elt[3], Op.showkern)
- else:
- assert False
- self.file.output(Op.end_text)
-
- # Then output the boxes (e.g., variable-length lines of square
- # roots).
- boxgc = self.new_gc()
- boxgc.copy_properties(gc)
- boxgc.set_linewidth(0)
- pathops = [Path.MOVETO, Path.LINETO, Path.LINETO, Path.LINETO,
- Path.CLOSEPOLY]
- for x1, y1, h, w in page.boxes:
- path = Path([[x1, y1], [x1+w, y1], [x1+w, y1+h], [x1, y1+h],
- [0, 0]], pathops)
- self.draw_path(boxgc, path, mytrans, gc._rgb)
-
- def encode_string(self, s, fonttype):
- if fonttype in (1, 3):
- return s.encode('cp1252', 'replace')
- return s.encode('utf-16be', 'replace')
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- # docstring inherited
-
- # TODO: combine consecutive texts into one BT/ET delimited section
-
- self.check_gc(gc, gc._rgb)
- if ismath:
- return self.draw_mathtext(gc, x, y, s, prop, angle)
-
- fontsize = prop.get_size_in_points()
-
- if mpl.rcParams['pdf.use14corefonts']:
- font = self._get_font_afm(prop)
- fonttype = 1
- else:
- font = self._get_font_ttf(prop)
- self.file._character_tracker.track(font, s)
- fonttype = mpl.rcParams['pdf.fonttype']
-
- if gc.get_url() is not None:
- font.set_text(s)
- width, height = font.get_width_height()
- self.file._annotations[-1][1].append(_get_link_annotation(
- gc, x, y, width / 64, height / 64, angle))
-
- # If fonttype is neither 3 nor 42, emit the whole string at once
- # without manual kerning.
- if fonttype not in [3, 42]:
- self.file.output(Op.begin_text,
- self.file.fontName(prop), fontsize, Op.selectfont)
- self._setup_textpos(x, y, angle)
- self.file.output(self.encode_string(s, fonttype),
- Op.show, Op.end_text)
-
- # A sequence of characters is broken into multiple chunks. The chunking
- # serves two purposes:
- # - For Type 3 fonts, there is no way to access multibyte characters,
- # as they cannot have a CIDMap. Therefore, in this case we break
- # the string into chunks, where each chunk contains either a string
- # of consecutive 1-byte characters or a single multibyte character.
- # - A sequence of 1-byte characters is split into chunks to allow for
- # kerning adjustments between consecutive chunks.
- #
- # Each chunk is emitted with a separate command: 1-byte characters use
- # the regular text show command (TJ) with appropriate kerning between
- # chunks, whereas multibyte characters use the XObject command (Do).
- else:
- # List of (ft_object, start_x, [prev_kern, char, char, ...]),
- # w/o zero kerns.
- singlebyte_chunks = []
- # List of (ft_object, start_x, glyph_index).
- multibyte_glyphs = []
- prev_was_multibyte = True
- prev_font = font
- for item in _text_helpers.layout(
- s, font, kern_mode=KERNING_UNFITTED):
- if _font_supports_glyph(fonttype, ord(item.char)):
- if prev_was_multibyte or item.ft_object != prev_font:
- singlebyte_chunks.append((item.ft_object, item.x, []))
- prev_font = item.ft_object
- if item.prev_kern:
- singlebyte_chunks[-1][2].append(item.prev_kern)
- singlebyte_chunks[-1][2].append(item.char)
- prev_was_multibyte = False
- else:
- multibyte_glyphs.append(
- (item.ft_object, item.x, item.glyph_idx)
- )
- prev_was_multibyte = True
- # Do the rotation and global translation as a single matrix
- # concatenation up front
- self.file.output(Op.gsave)
- a = math.radians(angle)
- self.file.output(math.cos(a), math.sin(a),
- -math.sin(a), math.cos(a),
- x, y, Op.concat_matrix)
- # Emit all the 1-byte characters in a BT/ET group.
-
- self.file.output(Op.begin_text)
- prev_start_x = 0
- for ft_object, start_x, kerns_or_chars in singlebyte_chunks:
- ft_name = self.file.fontName(ft_object.fname)
- self.file.output(ft_name, fontsize, Op.selectfont)
- self._setup_textpos(start_x, 0, 0, prev_start_x, 0, 0)
- self.file.output(
- # See pdf spec "Text space details" for the 1000/fontsize
- # (aka. 1000/T_fs) factor.
- [-1000 * next(group) / fontsize if tp == float # a kern
- else self.encode_string("".join(group), fonttype)
- for tp, group in itertools.groupby(kerns_or_chars, type)],
- Op.showkern)
- prev_start_x = start_x
- self.file.output(Op.end_text)
- # Then emit all the multibyte characters, one at a time.
- for ft_object, start_x, glyph_idx in multibyte_glyphs:
- self._draw_xobject_glyph(
- ft_object, fontsize, glyph_idx, start_x, 0
- )
- self.file.output(Op.grestore)
-
- def _draw_xobject_glyph(self, font, fontsize, glyph_idx, x, y):
- """Draw a multibyte character from a Type 3 font as an XObject."""
- glyph_name = font.get_glyph_name(glyph_idx)
- name = self.file._get_xobject_glyph_name(font.fname, glyph_name)
- self.file.output(
- Op.gsave,
- 0.001 * fontsize, 0, 0, 0.001 * fontsize, x, y, Op.concat_matrix,
- Name(name), Op.use_xobject,
- Op.grestore,
- )
-
- def new_gc(self):
- # docstring inherited
- return GraphicsContextPdf(self.file)
-
-
-class GraphicsContextPdf(GraphicsContextBase):
-
- def __init__(self, file):
- super().__init__()
- self._fillcolor = (0.0, 0.0, 0.0)
- self._effective_alphas = (1.0, 1.0)
- self.file = file
- self.parent = None
-
- def __repr__(self):
- d = dict(self.__dict__)
- del d['file']
- del d['parent']
- return repr(d)
-
- def stroke(self):
- """
- Predicate: does the path need to be stroked (its outline drawn)?
- This tests for the various conditions that disable stroking
- the path, in which case it would presumably be filled.
- """
- # _linewidth > 0: in pdf a line of width 0 is drawn at minimum
- # possible device width, but e.g., agg doesn't draw at all
- return (self._linewidth > 0 and self._alpha > 0 and
- (len(self._rgb) <= 3 or self._rgb[3] != 0.0))
-
- def fill(self, *args):
- """
- Predicate: does the path need to be filled?
-
- An optional argument can be used to specify an alternative
- _fillcolor, as needed by RendererPdf.draw_markers.
- """
- if len(args):
- _fillcolor = args[0]
- else:
- _fillcolor = self._fillcolor
- return (self._hatch or
- (_fillcolor is not None and
- (len(_fillcolor) <= 3 or _fillcolor[3] != 0.0)))
-
- def paint(self):
- """
- Return the appropriate pdf operator to cause the path to be
- stroked, filled, or both.
- """
- return Op.paint_path(self.fill(), self.stroke())
-
- capstyles = {'butt': 0, 'round': 1, 'projecting': 2}
- joinstyles = {'miter': 0, 'round': 1, 'bevel': 2}
-
- def capstyle_cmd(self, style):
- return [self.capstyles[style], Op.setlinecap]
-
- def joinstyle_cmd(self, style):
- return [self.joinstyles[style], Op.setlinejoin]
-
- def linewidth_cmd(self, width):
- return [width, Op.setlinewidth]
-
- def dash_cmd(self, dashes):
- offset, dash = dashes
- if dash is None:
- dash = []
- offset = 0
- return [list(dash), offset, Op.setdash]
-
- def alpha_cmd(self, alpha, forced, effective_alphas):
- name = self.file.alphaState(effective_alphas)
- return [name, Op.setgstate]
-
- def hatch_cmd(self, hatch, hatch_color):
- if not hatch:
- if self._fillcolor is not None:
- return self.fillcolor_cmd(self._fillcolor)
- else:
- return [Name('DeviceRGB'), Op.setcolorspace_nonstroke]
- else:
- hatch_style = (hatch_color, self._fillcolor, hatch)
- name = self.file.hatchPattern(hatch_style)
- return [Name('Pattern'), Op.setcolorspace_nonstroke,
- name, Op.setcolor_nonstroke]
-
- def rgb_cmd(self, rgb):
- if mpl.rcParams['pdf.inheritcolor']:
- return []
- if rgb[0] == rgb[1] == rgb[2]:
- return [rgb[0], Op.setgray_stroke]
- else:
- return [*rgb[:3], Op.setrgb_stroke]
-
- def fillcolor_cmd(self, rgb):
- if rgb is None or mpl.rcParams['pdf.inheritcolor']:
- return []
- elif rgb[0] == rgb[1] == rgb[2]:
- return [rgb[0], Op.setgray_nonstroke]
- else:
- return [*rgb[:3], Op.setrgb_nonstroke]
-
- def push(self):
- parent = GraphicsContextPdf(self.file)
- parent.copy_properties(self)
- parent.parent = self.parent
- self.parent = parent
- return [Op.gsave]
-
- def pop(self):
- assert self.parent is not None
- self.copy_properties(self.parent)
- self.parent = self.parent.parent
- return [Op.grestore]
-
- def clip_cmd(self, cliprect, clippath):
- """Set clip rectangle. Calls `.pop()` and `.push()`."""
- cmds = []
- # Pop graphics state until we hit the right one or the stack is empty
- while ((self._cliprect, self._clippath) != (cliprect, clippath)
- and self.parent is not None):
- cmds.extend(self.pop())
- # Unless we hit the right one, set the clip polygon
- if ((self._cliprect, self._clippath) != (cliprect, clippath) or
- self.parent is None):
- cmds.extend(self.push())
- if self._cliprect != cliprect:
- cmds.extend([cliprect, Op.rectangle, Op.clip, Op.endpath])
- if self._clippath != clippath:
- path, affine = clippath.get_transformed_path_and_affine()
- cmds.extend(
- PdfFile.pathOperations(path, affine, simplify=False) +
- [Op.clip, Op.endpath])
- return cmds
-
- commands = (
- # must come first since may pop
- (('_cliprect', '_clippath'), clip_cmd),
- (('_alpha', '_forced_alpha', '_effective_alphas'), alpha_cmd),
- (('_capstyle',), capstyle_cmd),
- (('_fillcolor',), fillcolor_cmd),
- (('_joinstyle',), joinstyle_cmd),
- (('_linewidth',), linewidth_cmd),
- (('_dashes',), dash_cmd),
- (('_rgb',), rgb_cmd),
- # must come after fillcolor and rgb
- (('_hatch', '_hatch_color'), hatch_cmd),
- )
-
- def delta(self, other):
- """
- Copy properties of other into self and return PDF commands
- needed to transform *self* into *other*.
- """
- cmds = []
- fill_performed = False
- for params, cmd in self.commands:
- different = False
- for p in params:
- ours = getattr(self, p)
- theirs = getattr(other, p)
- try:
- if ours is None or theirs is None:
- different = ours is not theirs
- else:
- different = bool(ours != theirs)
- except ValueError:
- ours = np.asarray(ours)
- theirs = np.asarray(theirs)
- different = (ours.shape != theirs.shape or
- np.any(ours != theirs))
- if different:
- break
-
- # Need to update hatching if we also updated fillcolor
- if params == ('_hatch', '_hatch_color') and fill_performed:
- different = True
-
- if different:
- if params == ('_fillcolor',):
- fill_performed = True
- theirs = [getattr(other, p) for p in params]
- cmds.extend(cmd(self, *theirs))
- for p in params:
- setattr(self, p, getattr(other, p))
- return cmds
-
- def copy_properties(self, other):
- """
- Copy properties of other into self.
- """
- super().copy_properties(other)
- fillcolor = getattr(other, '_fillcolor', self._fillcolor)
- effective_alphas = getattr(other, '_effective_alphas',
- self._effective_alphas)
- self._fillcolor = fillcolor
- self._effective_alphas = effective_alphas
-
- def finalize(self):
- """
- Make sure every pushed graphics state is popped.
- """
- cmds = []
- while self.parent is not None:
- cmds.extend(self.pop())
- return cmds
-
-
-class PdfPages:
- """
- A multi-page PDF file.
-
- Examples
- --------
- >>> import matplotlib.pyplot as plt
- >>> # Initialize:
- >>> with PdfPages('foo.pdf') as pdf:
- ... # As many times as you like, create a figure fig and save it:
- ... fig = plt.figure()
- ... pdf.savefig(fig)
- ... # When no figure is specified the current figure is saved
- ... pdf.savefig()
-
- Notes
- -----
- In reality `PdfPages` is a thin wrapper around `PdfFile`, in order to avoid
- confusion when using `~.pyplot.savefig` and forgetting the format argument.
- """
-
- _UNSET = object()
-
- def __init__(self, filename, keep_empty=_UNSET, metadata=None):
- """
- Create a new PdfPages object.
-
- Parameters
- ----------
- filename : str or path-like or file-like
- Plots using `PdfPages.savefig` will be written to a file at this location.
- The file is opened when a figure is saved for the first time (overwriting
- any older file with the same name).
-
- keep_empty : bool, optional
- If set to False, then empty pdf files will be deleted automatically
- when closed.
-
- metadata : dict, optional
- Information dictionary object (see PDF reference section 10.2.1
- 'Document Information Dictionary'), e.g.:
- ``{'Creator': 'My software', 'Author': 'Me', 'Title': 'Awesome'}``.
-
- The standard keys are 'Title', 'Author', 'Subject', 'Keywords',
- 'Creator', 'Producer', 'CreationDate', 'ModDate', and
- 'Trapped'. Values have been predefined for 'Creator', 'Producer'
- and 'CreationDate'. They can be removed by setting them to `None`.
- """
- self._filename = filename
- self._metadata = metadata
- self._file = None
- if keep_empty and keep_empty is not self._UNSET:
- _api.warn_deprecated("3.8", message=(
- "Keeping empty pdf files is deprecated since %(since)s and support "
- "will be removed %(removal)s."))
- self._keep_empty = keep_empty
-
- keep_empty = _api.deprecate_privatize_attribute("3.8")
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self.close()
-
- def _ensure_file(self):
- if self._file is None:
- self._file = PdfFile(self._filename, metadata=self._metadata) # init.
- return self._file
-
- def close(self):
- """
- Finalize this object, making the underlying file a complete
- PDF file.
- """
- if self._file is not None:
- self._file.finalize()
- self._file.close()
- self._file = None
- elif self._keep_empty: # True *or* UNSET.
- _api.warn_deprecated("3.8", message=(
- "Keeping empty pdf files is deprecated since %(since)s and support "
- "will be removed %(removal)s."))
- PdfFile(self._filename, metadata=self._metadata) # touch the file.
-
- def infodict(self):
- """
- Return a modifiable information dictionary object
- (see PDF reference section 10.2.1 'Document Information
- Dictionary').
- """
- return self._ensure_file().infoDict
-
- def savefig(self, figure=None, **kwargs):
- """
- Save a `.Figure` to this file as a new page.
-
- Any other keyword arguments are passed to `~.Figure.savefig`.
-
- Parameters
- ----------
- figure : `.Figure` or int, default: the active figure
- The figure, or index of the figure, that is saved to the file.
- """
- if not isinstance(figure, Figure):
- if figure is None:
- manager = Gcf.get_active()
- else:
- manager = Gcf.get_fig_manager(figure)
- if manager is None:
- raise ValueError(f"No figure {figure}")
- figure = manager.canvas.figure
- # Force use of pdf backend, as PdfPages is tightly coupled with it.
- with cbook._setattr_cm(figure, canvas=FigureCanvasPdf(figure)):
- figure.savefig(self, format="pdf", **kwargs)
-
- def get_pagecount(self):
- """Return the current number of pages in the multipage pdf file."""
- return len(self._ensure_file().pageList)
-
- def attach_note(self, text, positionRect=[-100, -100, 0, 0]):
- """
- Add a new text note to the page to be saved next. The optional
- positionRect specifies the position of the new note on the
- page. It is outside the page per default to make sure it is
- invisible on printouts.
- """
- self._ensure_file().newTextnote(text, positionRect)
-
-
-class FigureCanvasPdf(FigureCanvasBase):
- # docstring inherited
-
- fixed_dpi = 72
- filetypes = {'pdf': 'Portable Document Format'}
-
- def get_default_filetype(self):
- return 'pdf'
-
- def print_pdf(self, filename, *,
- bbox_inches_restore=None, metadata=None):
-
- dpi = self.figure.dpi
- self.figure.dpi = 72 # there are 72 pdf points to an inch
- width, height = self.figure.get_size_inches()
- if isinstance(filename, PdfPages):
- file = filename._ensure_file()
- else:
- file = PdfFile(filename, metadata=metadata)
- try:
- file.newPage(width, height)
- renderer = MixedModeRenderer(
- self.figure, width, height, dpi,
- RendererPdf(file, dpi, height, width),
- bbox_inches_restore=bbox_inches_restore)
- self.figure.draw(renderer)
- renderer.finalize()
- if not isinstance(filename, PdfPages):
- file.finalize()
- finally:
- if isinstance(filename, PdfPages): # finish off this page
- file.endStream()
- else: # we opened the file above; now finish it off
- file.close()
-
- def draw(self):
- self.figure.draw_without_rendering()
- return super().draw()
-
-
-FigureManagerPdf = FigureManagerBase
-
-
-@_Backend.export
-class _BackendPdf(_Backend):
- FigureCanvas = FigureCanvasPdf
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_pgf.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_pgf.py
deleted file mode 100644
index ccf4b800a6..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_pgf.py
+++ /dev/null
@@ -1,1009 +0,0 @@
-import codecs
-import datetime
-import functools
-from io import BytesIO
-import logging
-import math
-import os
-import pathlib
-import shutil
-import subprocess
-from tempfile import TemporaryDirectory
-import weakref
-
-from PIL import Image
-
-import matplotlib as mpl
-from matplotlib import _api, cbook, font_manager as fm
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, RendererBase
-)
-from matplotlib.backends.backend_mixed import MixedModeRenderer
-from matplotlib.backends.backend_pdf import (
- _create_pdf_info_dict, _datetime_to_pdf)
-from matplotlib.path import Path
-from matplotlib.figure import Figure
-from matplotlib._pylab_helpers import Gcf
-
-_log = logging.getLogger(__name__)
-
-
-# Note: When formatting floating point values, it is important to use the
-# %f/{:f} format rather than %s/{} to avoid triggering scientific notation,
-# which is not recognized by TeX.
-
-def _get_preamble():
- """Prepare a LaTeX preamble based on the rcParams configuration."""
- preamble = [
- # Remove Matplotlib's custom command \mathdefault. (Not using
- # \mathnormal instead since this looks odd with Computer Modern.)
- r"\def\mathdefault#1{#1}",
- # Use displaystyle for all math.
- r"\everymath=\expandafter{\the\everymath\displaystyle}",
- # Allow pgf.preamble to override the above definitions.
- mpl.rcParams["pgf.preamble"],
- ]
- if mpl.rcParams["pgf.texsystem"] != "pdflatex":
- preamble.append("\\usepackage{fontspec}")
- if mpl.rcParams["pgf.rcfonts"]:
- families = ["serif", "sans\\-serif", "monospace"]
- commands = ["setmainfont", "setsansfont", "setmonofont"]
- for family, command in zip(families, commands):
- # 1) Forward slashes also work on Windows, so don't mess with
- # backslashes. 2) The dirname needs to include a separator.
- path = pathlib.Path(fm.findfont(family))
- preamble.append(r"\%s{%s}[Path=\detokenize{%s/}]" % (
- command, path.name, path.parent.as_posix()))
- preamble.append(mpl.texmanager._usepackage_if_not_loaded(
- "underscore", option="strings")) # Documented as "must come last".
- return "\n".join(preamble)
-
-
-# It's better to use only one unit for all coordinates, since the
-# arithmetic in latex seems to produce inaccurate conversions.
-latex_pt_to_in = 1. / 72.27
-latex_in_to_pt = 1. / latex_pt_to_in
-mpl_pt_to_in = 1. / 72.
-mpl_in_to_pt = 1. / mpl_pt_to_in
-
-
-def _tex_escape(text):
- r"""
- Do some necessary and/or useful substitutions for texts to be included in
- LaTeX documents.
- """
- return text.replace("\N{MINUS SIGN}", r"\ensuremath{-}")
-
-
-def _writeln(fh, line):
- # Ending lines with a % prevents TeX from inserting spurious spaces
- # (https://tex.stackexchange.com/questions/7453).
- fh.write(line)
- fh.write("%\n")
-
-
-def _escape_and_apply_props(s, prop):
- """
- Generate a TeX string that renders string *s* with font properties *prop*,
- also applying any required escapes to *s*.
- """
- commands = []
-
- families = {"serif": r"\rmfamily", "sans": r"\sffamily",
- "sans-serif": r"\sffamily", "monospace": r"\ttfamily"}
- family = prop.get_family()[0]
- if family in families:
- commands.append(families[family])
- elif (any(font.name == family for font in fm.fontManager.ttflist)
- and mpl.rcParams["pgf.texsystem"] != "pdflatex"):
- commands.append(r"\setmainfont{%s}\rmfamily" % family)
- else:
- _log.warning("Ignoring unknown font: %s", family)
-
- size = prop.get_size_in_points()
- commands.append(r"\fontsize{%f}{%f}" % (size, size * 1.2))
-
- styles = {"normal": r"", "italic": r"\itshape", "oblique": r"\slshape"}
- commands.append(styles[prop.get_style()])
-
- boldstyles = ["semibold", "demibold", "demi", "bold", "heavy",
- "extra bold", "black"]
- if prop.get_weight() in boldstyles:
- commands.append(r"\bfseries")
-
- commands.append(r"\selectfont")
- return (
- "{"
- + "".join(commands)
- + r"\catcode`\^=\active\def^{\ifmmode\sp\else\^{}\fi}"
- # It should normally be enough to set the catcode of % to 12 ("normal
- # character"); this works on TeXLive 2021 but not on 2018, so we just
- # make it active too.
- + r"\catcode`\%=\active\def%{\%}"
- + _tex_escape(s)
- + "}"
- )
-
-
-def _metadata_to_str(key, value):
- """Convert metadata key/value to a form that hyperref accepts."""
- if isinstance(value, datetime.datetime):
- value = _datetime_to_pdf(value)
- elif key == 'Trapped':
- value = value.name.decode('ascii')
- else:
- value = str(value)
- return f'{key}={{{value}}}'
-
-
-def make_pdf_to_png_converter():
- """Return a function that converts a pdf file to a png file."""
- try:
- mpl._get_executable_info("pdftocairo")
- except mpl.ExecutableNotFoundError:
- pass
- else:
- return lambda pdffile, pngfile, dpi: subprocess.check_output(
- ["pdftocairo", "-singlefile", "-transp", "-png", "-r", "%d" % dpi,
- pdffile, os.path.splitext(pngfile)[0]],
- stderr=subprocess.STDOUT)
- try:
- gs_info = mpl._get_executable_info("gs")
- except mpl.ExecutableNotFoundError:
- pass
- else:
- return lambda pdffile, pngfile, dpi: subprocess.check_output(
- [gs_info.executable,
- '-dQUIET', '-dSAFER', '-dBATCH', '-dNOPAUSE', '-dNOPROMPT',
- '-dUseCIEColor', '-dTextAlphaBits=4',
- '-dGraphicsAlphaBits=4', '-dDOINTERPOLATE',
- '-sDEVICE=pngalpha', '-sOutputFile=%s' % pngfile,
- '-r%d' % dpi, pdffile],
- stderr=subprocess.STDOUT)
- raise RuntimeError("No suitable pdf to png renderer found.")
-
-
-class LatexError(Exception):
- def __init__(self, message, latex_output=""):
- super().__init__(message)
- self.latex_output = latex_output
-
- def __str__(self):
- s, = self.args
- if self.latex_output:
- s += "\n" + self.latex_output
- return s
-
-
-class LatexManager:
- """
- The LatexManager opens an instance of the LaTeX application for
- determining the metrics of text elements. The LaTeX environment can be
- modified by setting fonts and/or a custom preamble in `.rcParams`.
- """
-
- @staticmethod
- def _build_latex_header():
- latex_header = [
- r"\documentclass{article}",
- # Include TeX program name as a comment for cache invalidation.
- # TeX does not allow this to be the first line.
- rf"% !TeX program = {mpl.rcParams['pgf.texsystem']}",
- # Test whether \includegraphics supports interpolate option.
- r"\usepackage{graphicx}",
- _get_preamble(),
- r"\begin{document}",
- r"\typeout{pgf_backend_query_start}",
- ]
- return "\n".join(latex_header)
-
- @classmethod
- def _get_cached_or_new(cls):
- """
- Return the previous LatexManager if the header and tex system did not
- change, or a new instance otherwise.
- """
- return cls._get_cached_or_new_impl(cls._build_latex_header())
-
- @classmethod
- @functools.lru_cache(1)
- def _get_cached_or_new_impl(cls, header): # Helper for _get_cached_or_new.
- return cls()
-
- def _stdin_writeln(self, s):
- if self.latex is None:
- self._setup_latex_process()
- self.latex.stdin.write(s)
- self.latex.stdin.write("\n")
- self.latex.stdin.flush()
-
- def _expect(self, s):
- s = list(s)
- chars = []
- while True:
- c = self.latex.stdout.read(1)
- chars.append(c)
- if chars[-len(s):] == s:
- break
- if not c:
- self.latex.kill()
- self.latex = None
- raise LatexError("LaTeX process halted", "".join(chars))
- return "".join(chars)
-
- def _expect_prompt(self):
- return self._expect("\n*")
-
- def __init__(self):
- # create a tmp directory for running latex, register it for deletion
- self._tmpdir = TemporaryDirectory()
- self.tmpdir = self._tmpdir.name
- self._finalize_tmpdir = weakref.finalize(self, self._tmpdir.cleanup)
-
- # test the LaTeX setup to ensure a clean startup of the subprocess
- self._setup_latex_process(expect_reply=False)
- stdout, stderr = self.latex.communicate("\n\\makeatletter\\@@end\n")
- if self.latex.returncode != 0:
- raise LatexError(
- f"LaTeX errored (probably missing font or error in preamble) "
- f"while processing the following input:\n"
- f"{self._build_latex_header()}",
- stdout)
- self.latex = None # Will be set up on first use.
- # Per-instance cache.
- self._get_box_metrics = functools.lru_cache(self._get_box_metrics)
-
- def _setup_latex_process(self, *, expect_reply=True):
- # Open LaTeX process for real work; register it for deletion. On
- # Windows, we must ensure that the subprocess has quit before being
- # able to delete the tmpdir in which it runs; in order to do so, we
- # must first `kill()` it, and then `communicate()` with it.
- try:
- self.latex = subprocess.Popen(
- [mpl.rcParams["pgf.texsystem"], "-halt-on-error"],
- stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- encoding="utf-8", cwd=self.tmpdir)
- except FileNotFoundError as err:
- raise RuntimeError(
- f"{mpl.rcParams['pgf.texsystem']!r} not found; install it or change "
- f"rcParams['pgf.texsystem'] to an available TeX implementation"
- ) from err
- except OSError as err:
- raise RuntimeError(
- f"Error starting {mpl.rcParams['pgf.texsystem']!r}") from err
-
- def finalize_latex(latex):
- latex.kill()
- latex.communicate()
-
- self._finalize_latex = weakref.finalize(
- self, finalize_latex, self.latex)
- # write header with 'pgf_backend_query_start' token
- self._stdin_writeln(self._build_latex_header())
- if expect_reply: # read until 'pgf_backend_query_start' token appears
- self._expect("*pgf_backend_query_start")
- self._expect_prompt()
-
- def get_width_height_descent(self, text, prop):
- """
- Get the width, total height, and descent (in TeX points) for a text
- typeset by the current LaTeX environment.
- """
- return self._get_box_metrics(_escape_and_apply_props(text, prop))
-
- def _get_box_metrics(self, tex):
- """
- Get the width, total height and descent (in TeX points) for a TeX
- command's output in the current LaTeX environment.
- """
- # This method gets wrapped in __init__ for per-instance caching.
- self._stdin_writeln( # Send textbox to TeX & request metrics typeout.
- # \sbox doesn't handle catcode assignments inside its argument,
- # so repeat the assignment of the catcode of "^" and "%" outside.
- r"{\catcode`\^=\active\catcode`\%%=\active\sbox0{%s}"
- r"\typeout{\the\wd0,\the\ht0,\the\dp0}}"
- % tex)
- try:
- answer = self._expect_prompt()
- except LatexError as err:
- # Here and below, use '{}' instead of {!r} to avoid doubling all
- # backslashes.
- raise ValueError("Error measuring {}\nLaTeX Output:\n{}"
- .format(tex, err.latex_output)) from err
- try:
- # Parse metrics from the answer string. Last line is prompt, and
- # next-to-last-line is blank line from \typeout.
- width, height, offset = answer.splitlines()[-3].split(",")
- except Exception as err:
- raise ValueError("Error measuring {}\nLaTeX Output:\n{}"
- .format(tex, answer)) from err
- w, h, o = float(width[:-2]), float(height[:-2]), float(offset[:-2])
- # The height returned from LaTeX goes from base to top;
- # the height Matplotlib expects goes from bottom to top.
- return w, h + o, o
-
-
-@functools.lru_cache(1)
-def _get_image_inclusion_command():
- man = LatexManager._get_cached_or_new()
- man._stdin_writeln(
- r"\includegraphics[interpolate=true]{%s}"
- # Don't mess with backslashes on Windows.
- % cbook._get_data_path("images/matplotlib.png").as_posix())
- try:
- man._expect_prompt()
- return r"\includegraphics"
- except LatexError:
- # Discard the broken manager.
- LatexManager._get_cached_or_new_impl.cache_clear()
- return r"\pgfimage"
-
-
-class RendererPgf(RendererBase):
-
- def __init__(self, figure, fh):
- """
- Create a new PGF renderer that translates any drawing instruction
- into text commands to be interpreted in a latex pgfpicture environment.
-
- Attributes
- ----------
- figure : `~matplotlib.figure.Figure`
- Matplotlib figure to initialize height, width and dpi from.
- fh : file-like
- File handle for the output of the drawing commands.
- """
-
- super().__init__()
- self.dpi = figure.dpi
- self.fh = fh
- self.figure = figure
- self.image_counter = 0
-
- def draw_markers(self, gc, marker_path, marker_trans, path, trans,
- rgbFace=None):
- # docstring inherited
-
- _writeln(self.fh, r"\begin{pgfscope}")
-
- # convert from display units to in
- f = 1. / self.dpi
-
- # set style and clip
- self._print_pgf_clip(gc)
- self._print_pgf_path_styles(gc, rgbFace)
-
- # build marker definition
- bl, tr = marker_path.get_extents(marker_trans).get_points()
- coords = bl[0] * f, bl[1] * f, tr[0] * f, tr[1] * f
- _writeln(self.fh,
- r"\pgfsys@defobject{currentmarker}"
- r"{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}{" % coords)
- self._print_pgf_path(None, marker_path, marker_trans)
- self._pgf_path_draw(stroke=gc.get_linewidth() != 0.0,
- fill=rgbFace is not None)
- _writeln(self.fh, r"}")
-
- maxcoord = 16383 / 72.27 * self.dpi # Max dimensions in LaTeX.
- clip = (-maxcoord, -maxcoord, maxcoord, maxcoord)
-
- # draw marker for each vertex
- for point, code in path.iter_segments(trans, simplify=False,
- clip=clip):
- x, y = point[0] * f, point[1] * f
- _writeln(self.fh, r"\begin{pgfscope}")
- _writeln(self.fh, r"\pgfsys@transformshift{%fin}{%fin}" % (x, y))
- _writeln(self.fh, r"\pgfsys@useobject{currentmarker}{}")
- _writeln(self.fh, r"\end{pgfscope}")
-
- _writeln(self.fh, r"\end{pgfscope}")
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- # docstring inherited
- _writeln(self.fh, r"\begin{pgfscope}")
- # draw the path
- self._print_pgf_clip(gc)
- self._print_pgf_path_styles(gc, rgbFace)
- self._print_pgf_path(gc, path, transform, rgbFace)
- self._pgf_path_draw(stroke=gc.get_linewidth() != 0.0,
- fill=rgbFace is not None)
- _writeln(self.fh, r"\end{pgfscope}")
-
- # if present, draw pattern on top
- if gc.get_hatch():
- _writeln(self.fh, r"\begin{pgfscope}")
- self._print_pgf_path_styles(gc, rgbFace)
-
- # combine clip and path for clipping
- self._print_pgf_clip(gc)
- self._print_pgf_path(gc, path, transform, rgbFace)
- _writeln(self.fh, r"\pgfusepath{clip}")
-
- # build pattern definition
- _writeln(self.fh,
- r"\pgfsys@defobject{currentpattern}"
- r"{\pgfqpoint{0in}{0in}}{\pgfqpoint{1in}{1in}}{")
- _writeln(self.fh, r"\begin{pgfscope}")
- _writeln(self.fh,
- r"\pgfpathrectangle"
- r"{\pgfqpoint{0in}{0in}}{\pgfqpoint{1in}{1in}}")
- _writeln(self.fh, r"\pgfusepath{clip}")
- scale = mpl.transforms.Affine2D().scale(self.dpi)
- self._print_pgf_path(None, gc.get_hatch_path(), scale)
- self._pgf_path_draw(stroke=True)
- _writeln(self.fh, r"\end{pgfscope}")
- _writeln(self.fh, r"}")
- # repeat pattern, filling the bounding rect of the path
- f = 1. / self.dpi
- (xmin, ymin), (xmax, ymax) = \
- path.get_extents(transform).get_points()
- xmin, xmax = f * xmin, f * xmax
- ymin, ymax = f * ymin, f * ymax
- repx, repy = math.ceil(xmax - xmin), math.ceil(ymax - ymin)
- _writeln(self.fh,
- r"\pgfsys@transformshift{%fin}{%fin}" % (xmin, ymin))
- for iy in range(repy):
- for ix in range(repx):
- _writeln(self.fh, r"\pgfsys@useobject{currentpattern}{}")
- _writeln(self.fh, r"\pgfsys@transformshift{1in}{0in}")
- _writeln(self.fh, r"\pgfsys@transformshift{-%din}{0in}" % repx)
- _writeln(self.fh, r"\pgfsys@transformshift{0in}{1in}")
-
- _writeln(self.fh, r"\end{pgfscope}")
-
- def _print_pgf_clip(self, gc):
- f = 1. / self.dpi
- # check for clip box
- bbox = gc.get_clip_rectangle()
- if bbox:
- p1, p2 = bbox.get_points()
- w, h = p2 - p1
- coords = p1[0] * f, p1[1] * f, w * f, h * f
- _writeln(self.fh,
- r"\pgfpathrectangle"
- r"{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}"
- % coords)
- _writeln(self.fh, r"\pgfusepath{clip}")
-
- # check for clip path
- clippath, clippath_trans = gc.get_clip_path()
- if clippath is not None:
- self._print_pgf_path(gc, clippath, clippath_trans)
- _writeln(self.fh, r"\pgfusepath{clip}")
-
- def _print_pgf_path_styles(self, gc, rgbFace):
- # cap style
- capstyles = {"butt": r"\pgfsetbuttcap",
- "round": r"\pgfsetroundcap",
- "projecting": r"\pgfsetrectcap"}
- _writeln(self.fh, capstyles[gc.get_capstyle()])
-
- # join style
- joinstyles = {"miter": r"\pgfsetmiterjoin",
- "round": r"\pgfsetroundjoin",
- "bevel": r"\pgfsetbeveljoin"}
- _writeln(self.fh, joinstyles[gc.get_joinstyle()])
-
- # filling
- has_fill = rgbFace is not None
-
- if gc.get_forced_alpha():
- fillopacity = strokeopacity = gc.get_alpha()
- else:
- strokeopacity = gc.get_rgb()[3]
- fillopacity = rgbFace[3] if has_fill and len(rgbFace) > 3 else 1.0
-
- if has_fill:
- _writeln(self.fh,
- r"\definecolor{currentfill}{rgb}{%f,%f,%f}"
- % tuple(rgbFace[:3]))
- _writeln(self.fh, r"\pgfsetfillcolor{currentfill}")
- if has_fill and fillopacity != 1.0:
- _writeln(self.fh, r"\pgfsetfillopacity{%f}" % fillopacity)
-
- # linewidth and color
- lw = gc.get_linewidth() * mpl_pt_to_in * latex_in_to_pt
- stroke_rgba = gc.get_rgb()
- _writeln(self.fh, r"\pgfsetlinewidth{%fpt}" % lw)
- _writeln(self.fh,
- r"\definecolor{currentstroke}{rgb}{%f,%f,%f}"
- % stroke_rgba[:3])
- _writeln(self.fh, r"\pgfsetstrokecolor{currentstroke}")
- if strokeopacity != 1.0:
- _writeln(self.fh, r"\pgfsetstrokeopacity{%f}" % strokeopacity)
-
- # line style
- dash_offset, dash_list = gc.get_dashes()
- if dash_list is None:
- _writeln(self.fh, r"\pgfsetdash{}{0pt}")
- else:
- _writeln(self.fh,
- r"\pgfsetdash{%s}{%fpt}"
- % ("".join(r"{%fpt}" % dash for dash in dash_list),
- dash_offset))
-
- def _print_pgf_path(self, gc, path, transform, rgbFace=None):
- f = 1. / self.dpi
- # check for clip box / ignore clip for filled paths
- bbox = gc.get_clip_rectangle() if gc else None
- maxcoord = 16383 / 72.27 * self.dpi # Max dimensions in LaTeX.
- if bbox and (rgbFace is None):
- p1, p2 = bbox.get_points()
- clip = (max(p1[0], -maxcoord), max(p1[1], -maxcoord),
- min(p2[0], maxcoord), min(p2[1], maxcoord))
- else:
- clip = (-maxcoord, -maxcoord, maxcoord, maxcoord)
- # build path
- for points, code in path.iter_segments(transform, clip=clip):
- if code == Path.MOVETO:
- x, y = tuple(points)
- _writeln(self.fh,
- r"\pgfpathmoveto{\pgfqpoint{%fin}{%fin}}" %
- (f * x, f * y))
- elif code == Path.CLOSEPOLY:
- _writeln(self.fh, r"\pgfpathclose")
- elif code == Path.LINETO:
- x, y = tuple(points)
- _writeln(self.fh,
- r"\pgfpathlineto{\pgfqpoint{%fin}{%fin}}" %
- (f * x, f * y))
- elif code == Path.CURVE3:
- cx, cy, px, py = tuple(points)
- coords = cx * f, cy * f, px * f, py * f
- _writeln(self.fh,
- r"\pgfpathquadraticcurveto"
- r"{\pgfqpoint{%fin}{%fin}}{\pgfqpoint{%fin}{%fin}}"
- % coords)
- elif code == Path.CURVE4:
- c1x, c1y, c2x, c2y, px, py = tuple(points)
- coords = c1x * f, c1y * f, c2x * f, c2y * f, px * f, py * f
- _writeln(self.fh,
- r"\pgfpathcurveto"
- r"{\pgfqpoint{%fin}{%fin}}"
- r"{\pgfqpoint{%fin}{%fin}}"
- r"{\pgfqpoint{%fin}{%fin}}"
- % coords)
-
- # apply pgf decorators
- sketch_params = gc.get_sketch_params() if gc else None
- if sketch_params is not None:
- # Only "length" directly maps to "segment length" in PGF's API.
- # PGF uses "amplitude" to pass the combined deviation in both x-
- # and y-direction, while matplotlib only varies the length of the
- # wiggle along the line ("randomness" and "length" parameters)
- # and has a separate "scale" argument for the amplitude.
- # -> Use "randomness" as PRNG seed to allow the user to force the
- # same shape on multiple sketched lines
- scale, length, randomness = sketch_params
- if scale is not None:
- # make matplotlib and PGF rendering visually similar
- length *= 0.5
- scale *= 2
- # PGF guarantees that repeated loading is a no-op
- _writeln(self.fh, r"\usepgfmodule{decorations}")
- _writeln(self.fh, r"\usepgflibrary{decorations.pathmorphing}")
- _writeln(self.fh, r"\pgfkeys{/pgf/decoration/.cd, "
- f"segment length = {(length * f):f}in, "
- f"amplitude = {(scale * f):f}in}}")
- _writeln(self.fh, f"\\pgfmathsetseed{{{int(randomness)}}}")
- _writeln(self.fh, r"\pgfdecoratecurrentpath{random steps}")
-
- def _pgf_path_draw(self, stroke=True, fill=False):
- actions = []
- if stroke:
- actions.append("stroke")
- if fill:
- actions.append("fill")
- _writeln(self.fh, r"\pgfusepath{%s}" % ",".join(actions))
-
- def option_scale_image(self):
- # docstring inherited
- return True
-
- def option_image_nocomposite(self):
- # docstring inherited
- return not mpl.rcParams['image.composite_image']
-
- def draw_image(self, gc, x, y, im, transform=None):
- # docstring inherited
-
- h, w = im.shape[:2]
- if w == 0 or h == 0:
- return
-
- if not os.path.exists(getattr(self.fh, "name", "")):
- raise ValueError(
- "streamed pgf-code does not support raster graphics, consider "
- "using the pgf-to-pdf option")
-
- # save the images to png files
- path = pathlib.Path(self.fh.name)
- fname_img = "%s-img%d.png" % (path.stem, self.image_counter)
- Image.fromarray(im[::-1]).save(path.parent / fname_img)
- self.image_counter += 1
-
- # reference the image in the pgf picture
- _writeln(self.fh, r"\begin{pgfscope}")
- self._print_pgf_clip(gc)
- f = 1. / self.dpi # from display coords to inch
- if transform is None:
- _writeln(self.fh,
- r"\pgfsys@transformshift{%fin}{%fin}" % (x * f, y * f))
- w, h = w * f, h * f
- else:
- tr1, tr2, tr3, tr4, tr5, tr6 = transform.frozen().to_values()
- _writeln(self.fh,
- r"\pgfsys@transformcm{%f}{%f}{%f}{%f}{%fin}{%fin}" %
- (tr1 * f, tr2 * f, tr3 * f, tr4 * f,
- (tr5 + x) * f, (tr6 + y) * f))
- w = h = 1 # scale is already included in the transform
- interp = str(transform is None).lower() # interpolation in PDF reader
- _writeln(self.fh,
- r"\pgftext[left,bottom]"
- r"{%s[interpolate=%s,width=%fin,height=%fin]{%s}}" %
- (_get_image_inclusion_command(),
- interp, w, h, fname_img))
- _writeln(self.fh, r"\end{pgfscope}")
-
- def draw_tex(self, gc, x, y, s, prop, angle, *, mtext=None):
- # docstring inherited
- self.draw_text(gc, x, y, s, prop, angle, ismath="TeX", mtext=mtext)
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- # docstring inherited
-
- # prepare string for tex
- s = _escape_and_apply_props(s, prop)
-
- _writeln(self.fh, r"\begin{pgfscope}")
- self._print_pgf_clip(gc)
-
- alpha = gc.get_alpha()
- if alpha != 1.0:
- _writeln(self.fh, r"\pgfsetfillopacity{%f}" % alpha)
- _writeln(self.fh, r"\pgfsetstrokeopacity{%f}" % alpha)
- rgb = tuple(gc.get_rgb())[:3]
- _writeln(self.fh, r"\definecolor{textcolor}{rgb}{%f,%f,%f}" % rgb)
- _writeln(self.fh, r"\pgfsetstrokecolor{textcolor}")
- _writeln(self.fh, r"\pgfsetfillcolor{textcolor}")
- s = r"\color{textcolor}" + s
-
- dpi = self.figure.dpi
- text_args = []
- if mtext and (
- (angle == 0 or
- mtext.get_rotation_mode() == "anchor") and
- mtext.get_verticalalignment() != "center_baseline"):
- # if text anchoring can be supported, get the original coordinates
- # and add alignment information
- pos = mtext.get_unitless_position()
- x, y = mtext.get_transform().transform(pos)
- halign = {"left": "left", "right": "right", "center": ""}
- valign = {"top": "top", "bottom": "bottom",
- "baseline": "base", "center": ""}
- text_args.extend([
- f"x={x/dpi:f}in",
- f"y={y/dpi:f}in",
- halign[mtext.get_horizontalalignment()],
- valign[mtext.get_verticalalignment()],
- ])
- else:
- # if not, use the text layout provided by Matplotlib.
- text_args.append(f"x={x/dpi:f}in, y={y/dpi:f}in, left, base")
-
- if angle != 0:
- text_args.append("rotate=%f" % angle)
-
- _writeln(self.fh, r"\pgftext[%s]{%s}" % (",".join(text_args), s))
- _writeln(self.fh, r"\end{pgfscope}")
-
- def get_text_width_height_descent(self, s, prop, ismath):
- # docstring inherited
- # get text metrics in units of latex pt, convert to display units
- w, h, d = (LatexManager._get_cached_or_new()
- .get_width_height_descent(s, prop))
- # TODO: this should be latex_pt_to_in instead of mpl_pt_to_in
- # but having a little bit more space around the text looks better,
- # plus the bounding box reported by LaTeX is VERY narrow
- f = mpl_pt_to_in * self.dpi
- return w * f, h * f, d * f
-
- def flipy(self):
- # docstring inherited
- return False
-
- def get_canvas_width_height(self):
- # docstring inherited
- return (self.figure.get_figwidth() * self.dpi,
- self.figure.get_figheight() * self.dpi)
-
- def points_to_pixels(self, points):
- # docstring inherited
- return points * mpl_pt_to_in * self.dpi
-
-
-class FigureCanvasPgf(FigureCanvasBase):
- filetypes = {"pgf": "LaTeX PGF picture",
- "pdf": "LaTeX compiled PGF picture",
- "png": "Portable Network Graphics", }
-
- def get_default_filetype(self):
- return 'pdf'
-
- def _print_pgf_to_fh(self, fh, *, bbox_inches_restore=None):
-
- header_text = """%% Creator: Matplotlib, PGF backend
-%%
-%% To include the figure in your LaTeX document, write
-%% \\input{<filename>.pgf}
-%%
-%% Make sure the required packages are loaded in your preamble
-%% \\usepackage{pgf}
-%%
-%% Also ensure that all the required font packages are loaded; for instance,
-%% the lmodern package is sometimes necessary when using math font.
-%% \\usepackage{lmodern}
-%%
-%% Figures using additional raster images can only be included by \\input if
-%% they are in the same directory as the main LaTeX file. For loading figures
-%% from other directories you can use the `import` package
-%% \\usepackage{import}
-%%
-%% and then include the figures with
-%% \\import{<path to file>}{<filename>.pgf}
-%%
-"""
-
- # append the preamble used by the backend as a comment for debugging
- header_info_preamble = ["%% Matplotlib used the following preamble"]
- for line in _get_preamble().splitlines():
- header_info_preamble.append("%% " + line)
- header_info_preamble.append("%%")
- header_info_preamble = "\n".join(header_info_preamble)
-
- # get figure size in inch
- w, h = self.figure.get_figwidth(), self.figure.get_figheight()
- dpi = self.figure.dpi
-
- # create pgfpicture environment and write the pgf code
- fh.write(header_text)
- fh.write(header_info_preamble)
- fh.write("\n")
- _writeln(fh, r"\begingroup")
- _writeln(fh, r"\makeatletter")
- _writeln(fh, r"\begin{pgfpicture}")
- _writeln(fh,
- r"\pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{%fin}{%fin}}"
- % (w, h))
- _writeln(fh, r"\pgfusepath{use as bounding box, clip}")
- renderer = MixedModeRenderer(self.figure, w, h, dpi,
- RendererPgf(self.figure, fh),
- bbox_inches_restore=bbox_inches_restore)
- self.figure.draw(renderer)
-
- # end the pgfpicture environment
- _writeln(fh, r"\end{pgfpicture}")
- _writeln(fh, r"\makeatother")
- _writeln(fh, r"\endgroup")
-
- def print_pgf(self, fname_or_fh, **kwargs):
- """
- Output pgf macros for drawing the figure so it can be included and
- rendered in latex documents.
- """
- with cbook.open_file_cm(fname_or_fh, "w", encoding="utf-8") as file:
- if not cbook.file_requires_unicode(file):
- file = codecs.getwriter("utf-8")(file)
- self._print_pgf_to_fh(file, **kwargs)
-
- def print_pdf(self, fname_or_fh, *, metadata=None, **kwargs):
- """Use LaTeX to compile a pgf generated figure to pdf."""
- w, h = self.figure.get_size_inches()
-
- info_dict = _create_pdf_info_dict('pgf', metadata or {})
- pdfinfo = ','.join(
- _metadata_to_str(k, v) for k, v in info_dict.items())
-
- # print figure to pgf and compile it with latex
- with TemporaryDirectory() as tmpdir:
- tmppath = pathlib.Path(tmpdir)
- self.print_pgf(tmppath / "figure.pgf", **kwargs)
- (tmppath / "figure.tex").write_text(
- "\n".join([
- r"\documentclass[12pt]{article}",
- r"\usepackage[pdfinfo={%s}]{hyperref}" % pdfinfo,
- r"\usepackage[papersize={%fin,%fin}, margin=0in]{geometry}"
- % (w, h),
- r"\usepackage{pgf}",
- _get_preamble(),
- r"\begin{document}",
- r"\centering",
- r"\input{figure.pgf}",
- r"\end{document}",
- ]), encoding="utf-8")
- texcommand = mpl.rcParams["pgf.texsystem"]
- cbook._check_and_log_subprocess(
- [texcommand, "-interaction=nonstopmode", "-halt-on-error",
- "figure.tex"], _log, cwd=tmpdir)
- with (tmppath / "figure.pdf").open("rb") as orig, \
- cbook.open_file_cm(fname_or_fh, "wb") as dest:
- shutil.copyfileobj(orig, dest) # copy file contents to target
-
- def print_png(self, fname_or_fh, **kwargs):
- """Use LaTeX to compile a pgf figure to pdf and convert it to png."""
- converter = make_pdf_to_png_converter()
- with TemporaryDirectory() as tmpdir:
- tmppath = pathlib.Path(tmpdir)
- pdf_path = tmppath / "figure.pdf"
- png_path = tmppath / "figure.png"
- self.print_pdf(pdf_path, **kwargs)
- converter(pdf_path, png_path, dpi=self.figure.dpi)
- with png_path.open("rb") as orig, \
- cbook.open_file_cm(fname_or_fh, "wb") as dest:
- shutil.copyfileobj(orig, dest) # copy file contents to target
-
- def get_renderer(self):
- return RendererPgf(self.figure, None)
-
- def draw(self):
- self.figure.draw_without_rendering()
- return super().draw()
-
-
-FigureManagerPgf = FigureManagerBase
-
-
-@_Backend.export
-class _BackendPgf(_Backend):
- FigureCanvas = FigureCanvasPgf
-
-
-class PdfPages:
- """
- A multi-page PDF file using the pgf backend
-
- Examples
- --------
- >>> import matplotlib.pyplot as plt
- >>> # Initialize:
- >>> with PdfPages('foo.pdf') as pdf:
- ... # As many times as you like, create a figure fig and save it:
- ... fig = plt.figure()
- ... pdf.savefig(fig)
- ... # When no figure is specified the current figure is saved
- ... pdf.savefig()
- """
-
- _UNSET = object()
-
- def __init__(self, filename, *, keep_empty=_UNSET, metadata=None):
- """
- Create a new PdfPages object.
-
- Parameters
- ----------
- filename : str or path-like
- Plots using `PdfPages.savefig` will be written to a file at this
- location. Any older file with the same name is overwritten.
-
- keep_empty : bool, default: True
- If set to False, then empty pdf files will be deleted automatically
- when closed.
-
- metadata : dict, optional
- Information dictionary object (see PDF reference section 10.2.1
- 'Document Information Dictionary'), e.g.:
- ``{'Creator': 'My software', 'Author': 'Me', 'Title': 'Awesome'}``.
-
- The standard keys are 'Title', 'Author', 'Subject', 'Keywords',
- 'Creator', 'Producer', 'CreationDate', 'ModDate', and
- 'Trapped'. Values have been predefined for 'Creator', 'Producer'
- and 'CreationDate'. They can be removed by setting them to `None`.
-
- Note that some versions of LaTeX engines may ignore the 'Producer'
- key and set it to themselves.
- """
- self._output_name = filename
- self._n_figures = 0
- if keep_empty and keep_empty is not self._UNSET:
- _api.warn_deprecated("3.8", message=(
- "Keeping empty pdf files is deprecated since %(since)s and support "
- "will be removed %(removal)s."))
- self._keep_empty = keep_empty
- self._metadata = (metadata or {}).copy()
- self._info_dict = _create_pdf_info_dict('pgf', self._metadata)
- self._file = BytesIO()
-
- keep_empty = _api.deprecate_privatize_attribute("3.8")
-
- def _write_header(self, width_inches, height_inches):
- pdfinfo = ','.join(
- _metadata_to_str(k, v) for k, v in self._info_dict.items())
- latex_header = "\n".join([
- r"\documentclass[12pt]{article}",
- r"\usepackage[pdfinfo={%s}]{hyperref}" % pdfinfo,
- r"\usepackage[papersize={%fin,%fin}, margin=0in]{geometry}"
- % (width_inches, height_inches),
- r"\usepackage{pgf}",
- _get_preamble(),
- r"\setlength{\parindent}{0pt}",
- r"\begin{document}%",
- ])
- self._file.write(latex_header.encode('utf-8'))
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self.close()
-
- def close(self):
- """
- Finalize this object, running LaTeX in a temporary directory
- and moving the final pdf file to *filename*.
- """
- self._file.write(rb'\end{document}\n')
- if self._n_figures > 0:
- self._run_latex()
- elif self._keep_empty:
- _api.warn_deprecated("3.8", message=(
- "Keeping empty pdf files is deprecated since %(since)s and support "
- "will be removed %(removal)s."))
- open(self._output_name, 'wb').close()
- self._file.close()
-
- def _run_latex(self):
- texcommand = mpl.rcParams["pgf.texsystem"]
- with TemporaryDirectory() as tmpdir:
- tex_source = pathlib.Path(tmpdir, "pdf_pages.tex")
- tex_source.write_bytes(self._file.getvalue())
- cbook._check_and_log_subprocess(
- [texcommand, "-interaction=nonstopmode", "-halt-on-error",
- tex_source],
- _log, cwd=tmpdir)
- shutil.move(tex_source.with_suffix(".pdf"), self._output_name)
-
- def savefig(self, figure=None, **kwargs):
- """
- Save a `.Figure` to this file as a new page.
-
- Any other keyword arguments are passed to `~.Figure.savefig`.
-
- Parameters
- ----------
- figure : `.Figure` or int, default: the active figure
- The figure, or index of the figure, that is saved to the file.
- """
- if not isinstance(figure, Figure):
- if figure is None:
- manager = Gcf.get_active()
- else:
- manager = Gcf.get_fig_manager(figure)
- if manager is None:
- raise ValueError(f"No figure {figure}")
- figure = manager.canvas.figure
-
- with cbook._setattr_cm(figure, canvas=FigureCanvasPgf(figure)):
- width, height = figure.get_size_inches()
- if self._n_figures == 0:
- self._write_header(width, height)
- else:
- # \pdfpagewidth and \pdfpageheight exist on pdftex, xetex, and
- # luatex<0.85; they were renamed to \pagewidth and \pageheight
- # on luatex>=0.85.
- self._file.write(
- (
- r'\newpage'
- r'\ifdefined\pdfpagewidth\pdfpagewidth'
- fr'\else\pagewidth\fi={width}in'
- r'\ifdefined\pdfpageheight\pdfpageheight'
- fr'\else\pageheight\fi={height}in'
- '%%\n'
- ).encode("ascii")
- )
- figure.savefig(self._file, format="pgf", **kwargs)
- self._n_figures += 1
-
- def get_pagecount(self):
- """Return the current number of pages in the multipage pdf file."""
- return self._n_figures
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_ps.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_ps.py
deleted file mode 100644
index 2f9faa0ef6..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_ps.py
+++ /dev/null
@@ -1,1340 +0,0 @@
-"""
-A PostScript backend, which can produce both PostScript .ps and .eps.
-"""
-
-import codecs
-import datetime
-from enum import Enum
-import functools
-from io import StringIO
-import itertools
-import logging
-import os
-import pathlib
-import shutil
-from tempfile import TemporaryDirectory
-import time
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, cbook, _path, _text_helpers
-from matplotlib._afm import AFM
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, RendererBase)
-from matplotlib.cbook import is_writable_file_like, file_requires_unicode
-from matplotlib.font_manager import get_font
-from matplotlib.ft2font import LOAD_NO_SCALE, FT2Font
-from matplotlib._ttconv import convert_ttf_to_ps
-from matplotlib._mathtext_data import uni2type1
-from matplotlib.path import Path
-from matplotlib.texmanager import TexManager
-from matplotlib.transforms import Affine2D
-from matplotlib.backends.backend_mixed import MixedModeRenderer
-from . import _backend_pdf_ps
-
-
-_log = logging.getLogger(__name__)
-debugPS = False
-
-
-@_api.deprecated("3.7")
-class PsBackendHelper:
- def __init__(self):
- self._cached = {}
-
-
-@_api.caching_module_getattr
-class __getattr__:
- # module-level deprecations
- ps_backend_helper = _api.deprecated("3.7", obj_type="")(
- property(lambda self: PsBackendHelper()))
- psDefs = _api.deprecated("3.8", obj_type="")(property(lambda self: _psDefs))
-
-
-papersize = {'letter': (8.5, 11),
- 'legal': (8.5, 14),
- 'ledger': (11, 17),
- 'a0': (33.11, 46.81),
- 'a1': (23.39, 33.11),
- 'a2': (16.54, 23.39),
- 'a3': (11.69, 16.54),
- 'a4': (8.27, 11.69),
- 'a5': (5.83, 8.27),
- 'a6': (4.13, 5.83),
- 'a7': (2.91, 4.13),
- 'a8': (2.05, 2.91),
- 'a9': (1.46, 2.05),
- 'a10': (1.02, 1.46),
- 'b0': (40.55, 57.32),
- 'b1': (28.66, 40.55),
- 'b2': (20.27, 28.66),
- 'b3': (14.33, 20.27),
- 'b4': (10.11, 14.33),
- 'b5': (7.16, 10.11),
- 'b6': (5.04, 7.16),
- 'b7': (3.58, 5.04),
- 'b8': (2.51, 3.58),
- 'b9': (1.76, 2.51),
- 'b10': (1.26, 1.76)}
-
-
-def _get_papertype(w, h):
- for key, (pw, ph) in sorted(papersize.items(), reverse=True):
- if key.startswith('l'):
- continue
- if w < pw and h < ph:
- return key
- return 'a0'
-
-
-def _nums_to_str(*args, sep=" "):
- return sep.join(f"{arg:1.3f}".rstrip("0").rstrip(".") for arg in args)
-
-
-def _move_path_to_path_or_stream(src, dst):
- """
- Move the contents of file at *src* to path-or-filelike *dst*.
-
- If *dst* is a path, the metadata of *src* are *not* copied.
- """
- if is_writable_file_like(dst):
- fh = (open(src, encoding='latin-1')
- if file_requires_unicode(dst)
- else open(src, 'rb'))
- with fh:
- shutil.copyfileobj(fh, dst)
- else:
- shutil.move(src, dst, copy_function=shutil.copyfile)
-
-
-def _font_to_ps_type3(font_path, chars):
- """
- Subset *chars* from the font at *font_path* into a Type 3 font.
-
- Parameters
- ----------
- font_path : path-like
- Path to the font to be subsetted.
- chars : str
- The characters to include in the subsetted font.
-
- Returns
- -------
- str
- The string representation of a Type 3 font, which can be included
- verbatim into a PostScript file.
- """
- font = get_font(font_path, hinting_factor=1)
- glyph_ids = [font.get_char_index(c) for c in chars]
-
- preamble = """\
-%!PS-Adobe-3.0 Resource-Font
-%%Creator: Converted from TrueType to Type 3 by Matplotlib.
-10 dict begin
-/FontName /{font_name} def
-/PaintType 0 def
-/FontMatrix [{inv_units_per_em} 0 0 {inv_units_per_em} 0 0] def
-/FontBBox [{bbox}] def
-/FontType 3 def
-/Encoding [{encoding}] def
-/CharStrings {num_glyphs} dict dup begin
-/.notdef 0 def
-""".format(font_name=font.postscript_name,
- inv_units_per_em=1 / font.units_per_EM,
- bbox=" ".join(map(str, font.bbox)),
- encoding=" ".join(f"/{font.get_glyph_name(glyph_id)}"
- for glyph_id in glyph_ids),
- num_glyphs=len(glyph_ids) + 1)
- postamble = """
-end readonly def
-
-/BuildGlyph {
- exch begin
- CharStrings exch
- 2 copy known not {pop /.notdef} if
- true 3 1 roll get exec
- end
-} _d
-
-/BuildChar {
- 1 index /Encoding get exch get
- 1 index /BuildGlyph get exec
-} _d
-
-FontName currentdict end definefont pop
-"""
-
- entries = []
- for glyph_id in glyph_ids:
- g = font.load_glyph(glyph_id, LOAD_NO_SCALE)
- v, c = font.get_path()
- entries.append(
- "/%(name)s{%(bbox)s sc\n" % {
- "name": font.get_glyph_name(glyph_id),
- "bbox": " ".join(map(str, [g.horiAdvance, 0, *g.bbox])),
- }
- + _path.convert_to_string(
- # Convert back to TrueType's internal units (1/64's).
- # (Other dimensions are already in these units.)
- Path(v * 64, c), None, None, False, None, 0,
- # No code for quad Beziers triggers auto-conversion to cubics.
- # Drop intermediate closepolys (relying on the outline
- # decomposer always explicitly moving to the closing point
- # first).
- [b"m", b"l", b"", b"c", b""], True).decode("ascii")
- + "ce} _d"
- )
-
- return preamble + "\n".join(entries) + postamble
-
-
-def _font_to_ps_type42(font_path, chars, fh):
- """
- Subset *chars* from the font at *font_path* into a Type 42 font at *fh*.
-
- Parameters
- ----------
- font_path : path-like
- Path to the font to be subsetted.
- chars : str
- The characters to include in the subsetted font.
- fh : file-like
- Where to write the font.
- """
- subset_str = ''.join(chr(c) for c in chars)
- _log.debug("SUBSET %s characters: %s", font_path, subset_str)
- try:
- fontdata = _backend_pdf_ps.get_glyphs_subset(font_path, subset_str)
- _log.debug("SUBSET %s %d -> %d", font_path, os.stat(font_path).st_size,
- fontdata.getbuffer().nbytes)
-
- # Give ttconv a subsetted font along with updated glyph_ids.
- font = FT2Font(fontdata)
- glyph_ids = [font.get_char_index(c) for c in chars]
- with TemporaryDirectory() as tmpdir:
- tmpfile = os.path.join(tmpdir, "tmp.ttf")
-
- with open(tmpfile, 'wb') as tmp:
- tmp.write(fontdata.getvalue())
-
- # TODO: allow convert_ttf_to_ps to input file objects (BytesIO)
- convert_ttf_to_ps(os.fsencode(tmpfile), fh, 42, glyph_ids)
- except RuntimeError:
- _log.warning(
- "The PostScript backend does not currently "
- "support the selected font.")
- raise
-
-
-def _log_if_debug_on(meth):
- """
- Wrap `RendererPS` method *meth* to emit a PS comment with the method name,
- if the global flag `debugPS` is set.
- """
- @functools.wraps(meth)
- def wrapper(self, *args, **kwargs):
- if debugPS:
- self._pswriter.write(f"% {meth.__name__}\n")
- return meth(self, *args, **kwargs)
-
- return wrapper
-
-
-class RendererPS(_backend_pdf_ps.RendererPDFPSBase):
- """
- The renderer handles all the drawing primitives using a graphics
- context instance that controls the colors/styles.
- """
-
- _afm_font_dir = cbook._get_data_path("fonts/afm")
- _use_afm_rc_name = "ps.useafm"
-
- def __init__(self, width, height, pswriter, imagedpi=72):
- # Although postscript itself is dpi independent, we need to inform the
- # image code about a requested dpi to generate high resolution images
- # and them scale them before embedding them.
- super().__init__(width, height)
- self._pswriter = pswriter
- if mpl.rcParams['text.usetex']:
- self.textcnt = 0
- self.psfrag = []
- self.imagedpi = imagedpi
-
- # current renderer state (None=uninitialised)
- self.color = None
- self.linewidth = None
- self.linejoin = None
- self.linecap = None
- self.linedash = None
- self.fontname = None
- self.fontsize = None
- self._hatches = {}
- self.image_magnification = imagedpi / 72
- self._clip_paths = {}
- self._path_collection_id = 0
-
- self._character_tracker = _backend_pdf_ps.CharacterTracker()
- self._logwarn_once = functools.cache(_log.warning)
-
- def _is_transparent(self, rgb_or_rgba):
- if rgb_or_rgba is None:
- return True # Consistent with rgbFace semantics.
- elif len(rgb_or_rgba) == 4:
- if rgb_or_rgba[3] == 0:
- return True
- if rgb_or_rgba[3] != 1:
- self._logwarn_once(
- "The PostScript backend does not support transparency; "
- "partially transparent artists will be rendered opaque.")
- return False
- else: # len() == 3.
- return False
-
- def set_color(self, r, g, b, store=True):
- if (r, g, b) != self.color:
- self._pswriter.write(f"{_nums_to_str(r)} setgray\n"
- if r == g == b else
- f"{_nums_to_str(r, g, b)} setrgbcolor\n")
- if store:
- self.color = (r, g, b)
-
- def set_linewidth(self, linewidth, store=True):
- linewidth = float(linewidth)
- if linewidth != self.linewidth:
- self._pswriter.write(f"{_nums_to_str(linewidth)} setlinewidth\n")
- if store:
- self.linewidth = linewidth
-
- @staticmethod
- def _linejoin_cmd(linejoin):
- # Support for directly passing integer values is for backcompat.
- linejoin = {'miter': 0, 'round': 1, 'bevel': 2, 0: 0, 1: 1, 2: 2}[
- linejoin]
- return f"{linejoin:d} setlinejoin\n"
-
- def set_linejoin(self, linejoin, store=True):
- if linejoin != self.linejoin:
- self._pswriter.write(self._linejoin_cmd(linejoin))
- if store:
- self.linejoin = linejoin
-
- @staticmethod
- def _linecap_cmd(linecap):
- # Support for directly passing integer values is for backcompat.
- linecap = {'butt': 0, 'round': 1, 'projecting': 2, 0: 0, 1: 1, 2: 2}[
- linecap]
- return f"{linecap:d} setlinecap\n"
-
- def set_linecap(self, linecap, store=True):
- if linecap != self.linecap:
- self._pswriter.write(self._linecap_cmd(linecap))
- if store:
- self.linecap = linecap
-
- def set_linedash(self, offset, seq, store=True):
- if self.linedash is not None:
- oldo, oldseq = self.linedash
- if np.array_equal(seq, oldseq) and oldo == offset:
- return
-
- self._pswriter.write(f"[{_nums_to_str(*seq)}] {_nums_to_str(offset)} setdash\n"
- if seq is not None and len(seq) else
- "[] 0 setdash\n")
- if store:
- self.linedash = (offset, seq)
-
- def set_font(self, fontname, fontsize, store=True):
- if (fontname, fontsize) != (self.fontname, self.fontsize):
- self._pswriter.write(f"/{fontname} {fontsize:1.3f} selectfont\n")
- if store:
- self.fontname = fontname
- self.fontsize = fontsize
-
- def create_hatch(self, hatch):
- sidelen = 72
- if hatch in self._hatches:
- return self._hatches[hatch]
- name = 'H%d' % len(self._hatches)
- linewidth = mpl.rcParams['hatch.linewidth']
- pageheight = self.height * 72
- self._pswriter.write(f"""\
- << /PatternType 1
- /PaintType 2
- /TilingType 2
- /BBox[0 0 {sidelen:d} {sidelen:d}]
- /XStep {sidelen:d}
- /YStep {sidelen:d}
-
- /PaintProc {{
- pop
- {linewidth:g} setlinewidth
-{self._convert_path(
- Path.hatch(hatch), Affine2D().scale(sidelen), simplify=False)}
- gsave
- fill
- grestore
- stroke
- }} bind
- >>
- matrix
- 0 {pageheight:g} translate
- makepattern
- /{name} exch def
-""")
- self._hatches[hatch] = name
- return name
-
- def get_image_magnification(self):
- """
- Get the factor by which to magnify images passed to draw_image.
- Allows a backend to have images at a different resolution to other
- artists.
- """
- return self.image_magnification
-
- def _convert_path(self, path, transform, clip=False, simplify=None):
- if clip:
- clip = (0.0, 0.0, self.width * 72.0, self.height * 72.0)
- else:
- clip = None
- return _path.convert_to_string(
- path, transform, clip, simplify, None,
- 6, [b"m", b"l", b"", b"c", b"cl"], True).decode("ascii")
-
- def _get_clip_cmd(self, gc):
- clip = []
- rect = gc.get_clip_rectangle()
- if rect is not None:
- clip.append(f"{_nums_to_str(*rect.p0, *rect.size)} rectclip\n")
- path, trf = gc.get_clip_path()
- if path is not None:
- key = (path, id(trf))
- custom_clip_cmd = self._clip_paths.get(key)
- if custom_clip_cmd is None:
- custom_clip_cmd = "c%d" % len(self._clip_paths)
- self._pswriter.write(f"""\
-/{custom_clip_cmd} {{
-{self._convert_path(path, trf, simplify=False)}
-clip
-newpath
-}} bind def
-""")
- self._clip_paths[key] = custom_clip_cmd
- clip.append(f"{custom_clip_cmd}\n")
- return "".join(clip)
-
- @_log_if_debug_on
- def draw_image(self, gc, x, y, im, transform=None):
- # docstring inherited
-
- h, w = im.shape[:2]
- imagecmd = "false 3 colorimage"
- data = im[::-1, :, :3] # Vertically flipped rgb values.
- hexdata = data.tobytes().hex("\n", -64) # Linewrap to 128 chars.
-
- if transform is None:
- matrix = "1 0 0 1 0 0"
- xscale = w / self.image_magnification
- yscale = h / self.image_magnification
- else:
- matrix = " ".join(map(str, transform.frozen().to_values()))
- xscale = 1.0
- yscale = 1.0
-
- self._pswriter.write(f"""\
-gsave
-{self._get_clip_cmd(gc)}
-{x:g} {y:g} translate
-[{matrix}] concat
-{xscale:g} {yscale:g} scale
-/DataString {w:d} string def
-{w:d} {h:d} 8 [ {w:d} 0 0 -{h:d} 0 {h:d} ]
-{{
-currentfile DataString readhexstring pop
-}} bind {imagecmd}
-{hexdata}
-grestore
-""")
-
- @_log_if_debug_on
- def draw_path(self, gc, path, transform, rgbFace=None):
- # docstring inherited
- clip = rgbFace is None and gc.get_hatch_path() is None
- simplify = path.should_simplify and clip
- ps = self._convert_path(path, transform, clip=clip, simplify=simplify)
- self._draw_ps(ps, gc, rgbFace)
-
- @_log_if_debug_on
- def draw_markers(
- self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
- # docstring inherited
-
- ps_color = (
- None
- if self._is_transparent(rgbFace)
- else f'{_nums_to_str(rgbFace[0])} setgray'
- if rgbFace[0] == rgbFace[1] == rgbFace[2]
- else f'{_nums_to_str(*rgbFace[:3])} setrgbcolor')
-
- # construct the generic marker command:
-
- # don't want the translate to be global
- ps_cmd = ['/o {', 'gsave', 'newpath', 'translate']
-
- lw = gc.get_linewidth()
- alpha = (gc.get_alpha()
- if gc.get_forced_alpha() or len(gc.get_rgb()) == 3
- else gc.get_rgb()[3])
- stroke = lw > 0 and alpha > 0
- if stroke:
- ps_cmd.append('%.1f setlinewidth' % lw)
- ps_cmd.append(self._linejoin_cmd(gc.get_joinstyle()))
- ps_cmd.append(self._linecap_cmd(gc.get_capstyle()))
-
- ps_cmd.append(self._convert_path(marker_path, marker_trans,
- simplify=False))
-
- if rgbFace:
- if stroke:
- ps_cmd.append('gsave')
- if ps_color:
- ps_cmd.extend([ps_color, 'fill'])
- if stroke:
- ps_cmd.append('grestore')
-
- if stroke:
- ps_cmd.append('stroke')
- ps_cmd.extend(['grestore', '} bind def'])
-
- for vertices, code in path.iter_segments(
- trans,
- clip=(0, 0, self.width*72, self.height*72),
- simplify=False):
- if len(vertices):
- x, y = vertices[-2:]
- ps_cmd.append(f"{x:g} {y:g} o")
-
- ps = '\n'.join(ps_cmd)
- self._draw_ps(ps, gc, rgbFace, fill=False, stroke=False)
-
- @_log_if_debug_on
- def draw_path_collection(self, gc, master_transform, paths, all_transforms,
- offsets, offset_trans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position):
- # Is the optimization worth it? Rough calculation:
- # cost of emitting a path in-line is
- # (len_path + 2) * uses_per_path
- # cost of definition+use is
- # (len_path + 3) + 3 * uses_per_path
- len_path = len(paths[0].vertices) if len(paths) > 0 else 0
- uses_per_path = self._iter_collection_uses_per_path(
- paths, all_transforms, offsets, facecolors, edgecolors)
- should_do_optimization = \
- len_path + 3 * uses_per_path + 3 < (len_path + 2) * uses_per_path
- if not should_do_optimization:
- return RendererBase.draw_path_collection(
- self, gc, master_transform, paths, all_transforms,
- offsets, offset_trans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position)
-
- path_codes = []
- for i, (path, transform) in enumerate(self._iter_collection_raw_paths(
- master_transform, paths, all_transforms)):
- name = 'p%d_%d' % (self._path_collection_id, i)
- path_bytes = self._convert_path(path, transform, simplify=False)
- self._pswriter.write(f"""\
-/{name} {{
-newpath
-translate
-{path_bytes}
-}} bind def
-""")
- path_codes.append(name)
-
- for xo, yo, path_id, gc0, rgbFace in self._iter_collection(
- gc, path_codes, offsets, offset_trans,
- facecolors, edgecolors, linewidths, linestyles,
- antialiaseds, urls, offset_position):
- ps = f"{xo:g} {yo:g} {path_id}"
- self._draw_ps(ps, gc0, rgbFace)
-
- self._path_collection_id += 1
-
- @_log_if_debug_on
- def draw_tex(self, gc, x, y, s, prop, angle, *, mtext=None):
- # docstring inherited
- if self._is_transparent(gc.get_rgb()):
- return # Special handling for fully transparent.
-
- if not hasattr(self, "psfrag"):
- self._logwarn_once(
- "The PS backend determines usetex status solely based on "
- "rcParams['text.usetex'] and does not support having "
- "usetex=True only for some elements; this element will thus "
- "be rendered as if usetex=False.")
- self.draw_text(gc, x, y, s, prop, angle, False, mtext)
- return
-
- w, h, bl = self.get_text_width_height_descent(s, prop, ismath="TeX")
- fontsize = prop.get_size_in_points()
- thetext = 'psmarker%d' % self.textcnt
- color = _nums_to_str(*gc.get_rgb()[:3], sep=',')
- fontcmd = {'sans-serif': r'{\sffamily %s}',
- 'monospace': r'{\ttfamily %s}'}.get(
- mpl.rcParams['font.family'][0], r'{\rmfamily %s}')
- s = fontcmd % s
- tex = r'\color[rgb]{%s} %s' % (color, s)
-
- # Stick to bottom-left alignment, so subtract descent from the text-normal
- # direction since text is normally positioned by its baseline.
- rangle = np.radians(angle + 90)
- pos = _nums_to_str(x - bl * np.cos(rangle), y - bl * np.sin(rangle))
- self.psfrag.append(
- r'\psfrag{%s}[bl][bl][1][%f]{\fontsize{%f}{%f}%s}' % (
- thetext, angle, fontsize, fontsize*1.25, tex))
-
- self._pswriter.write(f"""\
-gsave
-{pos} moveto
-({thetext})
-show
-grestore
-""")
- self.textcnt += 1
-
- @_log_if_debug_on
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- # docstring inherited
-
- if self._is_transparent(gc.get_rgb()):
- return # Special handling for fully transparent.
-
- if ismath == 'TeX':
- return self.draw_tex(gc, x, y, s, prop, angle)
-
- if ismath:
- return self.draw_mathtext(gc, x, y, s, prop, angle)
-
- stream = [] # list of (ps_name, x, char_name)
-
- if mpl.rcParams['ps.useafm']:
- font = self._get_font_afm(prop)
- ps_name = (font.postscript_name.encode("ascii", "replace")
- .decode("ascii"))
- scale = 0.001 * prop.get_size_in_points()
- thisx = 0
- last_name = None # kerns returns 0 for None.
- for c in s:
- name = uni2type1.get(ord(c), f"uni{ord(c):04X}")
- try:
- width = font.get_width_from_char_name(name)
- except KeyError:
- name = 'question'
- width = font.get_width_char('?')
- kern = font.get_kern_dist_from_name(last_name, name)
- last_name = name
- thisx += kern * scale
- stream.append((ps_name, thisx, name))
- thisx += width * scale
-
- else:
- font = self._get_font_ttf(prop)
- self._character_tracker.track(font, s)
- for item in _text_helpers.layout(s, font):
- ps_name = (item.ft_object.postscript_name
- .encode("ascii", "replace").decode("ascii"))
- glyph_name = item.ft_object.get_glyph_name(item.glyph_idx)
- stream.append((ps_name, item.x, glyph_name))
- self.set_color(*gc.get_rgb())
-
- for ps_name, group in itertools. \
- groupby(stream, lambda entry: entry[0]):
- self.set_font(ps_name, prop.get_size_in_points(), False)
- thetext = "\n".join(f"{x:g} 0 m /{name:s} glyphshow"
- for _, x, name in group)
- self._pswriter.write(f"""\
-gsave
-{self._get_clip_cmd(gc)}
-{x:g} {y:g} translate
-{angle:g} rotate
-{thetext}
-grestore
-""")
-
- @_log_if_debug_on
- def draw_mathtext(self, gc, x, y, s, prop, angle):
- """Draw the math text using matplotlib.mathtext."""
- width, height, descent, glyphs, rects = \
- self._text2path.mathtext_parser.parse(s, 72, prop)
- self.set_color(*gc.get_rgb())
- self._pswriter.write(
- f"gsave\n"
- f"{x:g} {y:g} translate\n"
- f"{angle:g} rotate\n")
- lastfont = None
- for font, fontsize, num, ox, oy in glyphs:
- self._character_tracker.track_glyph(font, num)
- if (font.postscript_name, fontsize) != lastfont:
- lastfont = font.postscript_name, fontsize
- self._pswriter.write(
- f"/{font.postscript_name} {fontsize} selectfont\n")
- glyph_name = (
- font.get_name_char(chr(num)) if isinstance(font, AFM) else
- font.get_glyph_name(font.get_char_index(num)))
- self._pswriter.write(
- f"{ox:g} {oy:g} moveto\n"
- f"/{glyph_name} glyphshow\n")
- for ox, oy, w, h in rects:
- self._pswriter.write(f"{ox} {oy} {w} {h} rectfill\n")
- self._pswriter.write("grestore\n")
-
- @_log_if_debug_on
- def draw_gouraud_triangle(self, gc, points, colors, trans):
- self.draw_gouraud_triangles(gc, points.reshape((1, 3, 2)),
- colors.reshape((1, 3, 4)), trans)
-
- @_log_if_debug_on
- def draw_gouraud_triangles(self, gc, points, colors, trans):
- assert len(points) == len(colors)
- if len(points) == 0:
- return
- assert points.ndim == 3
- assert points.shape[1] == 3
- assert points.shape[2] == 2
- assert colors.ndim == 3
- assert colors.shape[1] == 3
- assert colors.shape[2] == 4
-
- shape = points.shape
- flat_points = points.reshape((shape[0] * shape[1], 2))
- flat_points = trans.transform(flat_points)
- flat_colors = colors.reshape((shape[0] * shape[1], 4))
- points_min = np.min(flat_points, axis=0) - (1 << 12)
- points_max = np.max(flat_points, axis=0) + (1 << 12)
- factor = np.ceil((2 ** 32 - 1) / (points_max - points_min))
-
- xmin, ymin = points_min
- xmax, ymax = points_max
-
- data = np.empty(
- shape[0] * shape[1],
- dtype=[('flags', 'u1'), ('points', '2>u4'), ('colors', '3u1')])
- data['flags'] = 0
- data['points'] = (flat_points - points_min) * factor
- data['colors'] = flat_colors[:, :3] * 255.0
- hexdata = data.tobytes().hex("\n", -64) # Linewrap to 128 chars.
-
- self._pswriter.write(f"""\
-gsave
-<< /ShadingType 4
- /ColorSpace [/DeviceRGB]
- /BitsPerCoordinate 32
- /BitsPerComponent 8
- /BitsPerFlag 8
- /AntiAlias true
- /Decode [ {xmin:g} {xmax:g} {ymin:g} {ymax:g} 0 1 0 1 0 1 ]
- /DataSource <
-{hexdata}
->
->>
-shfill
-grestore
-""")
-
- def _draw_ps(self, ps, gc, rgbFace, *, fill=True, stroke=True):
- """
- Emit the PostScript snippet *ps* with all the attributes from *gc*
- applied. *ps* must consist of PostScript commands to construct a path.
-
- The *fill* and/or *stroke* kwargs can be set to False if the *ps*
- string already includes filling and/or stroking, in which case
- `_draw_ps` is just supplying properties and clipping.
- """
- write = self._pswriter.write
- mightstroke = (gc.get_linewidth() > 0
- and not self._is_transparent(gc.get_rgb()))
- if not mightstroke:
- stroke = False
- if self._is_transparent(rgbFace):
- fill = False
- hatch = gc.get_hatch()
-
- if mightstroke:
- self.set_linewidth(gc.get_linewidth())
- self.set_linejoin(gc.get_joinstyle())
- self.set_linecap(gc.get_capstyle())
- self.set_linedash(*gc.get_dashes())
- if mightstroke or hatch:
- self.set_color(*gc.get_rgb()[:3])
- write('gsave\n')
-
- write(self._get_clip_cmd(gc))
-
- write(ps.strip())
- write("\n")
-
- if fill:
- if stroke or hatch:
- write("gsave\n")
- self.set_color(*rgbFace[:3], store=False)
- write("fill\n")
- if stroke or hatch:
- write("grestore\n")
-
- if hatch:
- hatch_name = self.create_hatch(hatch)
- write("gsave\n")
- write(_nums_to_str(*gc.get_hatch_color()[:3]))
- write(f" {hatch_name} setpattern fill grestore\n")
-
- if stroke:
- write("stroke\n")
-
- write("grestore\n")
-
-
-class _Orientation(Enum):
- portrait, landscape = range(2)
-
- def swap_if_landscape(self, shape):
- return shape[::-1] if self.name == "landscape" else shape
-
-
-class FigureCanvasPS(FigureCanvasBase):
- fixed_dpi = 72
- filetypes = {'ps': 'Postscript',
- 'eps': 'Encapsulated Postscript'}
-
- def get_default_filetype(self):
- return 'ps'
-
- def _print_ps(
- self, fmt, outfile, *,
- metadata=None, papertype=None, orientation='portrait',
- bbox_inches_restore=None, **kwargs):
-
- dpi = self.figure.dpi
- self.figure.dpi = 72 # Override the dpi kwarg
-
- dsc_comments = {}
- if isinstance(outfile, (str, os.PathLike)):
- filename = pathlib.Path(outfile).name
- dsc_comments["Title"] = \
- filename.encode("ascii", "replace").decode("ascii")
- dsc_comments["Creator"] = (metadata or {}).get(
- "Creator",
- f"Matplotlib v{mpl.__version__}, https://matplotlib.org/")
- # See https://reproducible-builds.org/specs/source-date-epoch/
- source_date_epoch = os.getenv("SOURCE_DATE_EPOCH")
- dsc_comments["CreationDate"] = (
- datetime.datetime.fromtimestamp(
- int(source_date_epoch),
- datetime.timezone.utc).strftime("%a %b %d %H:%M:%S %Y")
- if source_date_epoch
- else time.ctime())
- dsc_comments = "\n".join(
- f"%%{k}: {v}" for k, v in dsc_comments.items())
-
- if papertype is None:
- papertype = mpl.rcParams['ps.papersize']
- papertype = papertype.lower()
- _api.check_in_list(['figure', 'auto', *papersize], papertype=papertype)
-
- orientation = _api.check_getitem(
- _Orientation, orientation=orientation.lower())
-
- printer = (self._print_figure_tex
- if mpl.rcParams['text.usetex'] else
- self._print_figure)
- printer(fmt, outfile, dpi=dpi, dsc_comments=dsc_comments,
- orientation=orientation, papertype=papertype,
- bbox_inches_restore=bbox_inches_restore, **kwargs)
-
- def _print_figure(
- self, fmt, outfile, *,
- dpi, dsc_comments, orientation, papertype,
- bbox_inches_restore=None):
- """
- Render the figure to a filesystem path or a file-like object.
-
- Parameters are as for `.print_figure`, except that *dsc_comments* is a
- string containing Document Structuring Convention comments,
- generated from the *metadata* parameter to `.print_figure`.
- """
- is_eps = fmt == 'eps'
- if not (isinstance(outfile, (str, os.PathLike))
- or is_writable_file_like(outfile)):
- raise ValueError("outfile must be a path or a file-like object")
-
- # find the appropriate papertype
- width, height = self.figure.get_size_inches()
- if papertype == 'auto':
- papertype = _get_papertype(*orientation.swap_if_landscape((width, height)))
-
- if is_eps or papertype == 'figure':
- paper_width, paper_height = width, height
- else:
- paper_width, paper_height = orientation.swap_if_landscape(
- papersize[papertype])
-
- # center the figure on the paper
- xo = 72 * 0.5 * (paper_width - width)
- yo = 72 * 0.5 * (paper_height - height)
-
- llx = xo
- lly = yo
- urx = llx + self.figure.bbox.width
- ury = lly + self.figure.bbox.height
- rotation = 0
- if orientation is _Orientation.landscape:
- llx, lly, urx, ury = lly, llx, ury, urx
- xo, yo = 72 * paper_height - yo, xo
- rotation = 90
- bbox = (llx, lly, urx, ury)
-
- self._pswriter = StringIO()
-
- # mixed mode rendering
- ps_renderer = RendererPS(width, height, self._pswriter, imagedpi=dpi)
- renderer = MixedModeRenderer(
- self.figure, width, height, dpi, ps_renderer,
- bbox_inches_restore=bbox_inches_restore)
-
- self.figure.draw(renderer)
-
- def print_figure_impl(fh):
- # write the PostScript headers
- if is_eps:
- print("%!PS-Adobe-3.0 EPSF-3.0", file=fh)
- else:
- print("%!PS-Adobe-3.0", file=fh)
- if papertype != 'figure':
- print(f"%%DocumentPaperSizes: {papertype}", file=fh)
- print("%%Pages: 1", file=fh)
- print(f"%%LanguageLevel: 3\n"
- f"{dsc_comments}\n"
- f"%%Orientation: {orientation.name}\n"
- f"{get_bbox_header(bbox)[0]}\n"
- f"%%EndComments\n",
- end="", file=fh)
-
- Ndict = len(_psDefs)
- print("%%BeginProlog", file=fh)
- if not mpl.rcParams['ps.useafm']:
- Ndict += len(ps_renderer._character_tracker.used)
- print("/mpldict %d dict def" % Ndict, file=fh)
- print("mpldict begin", file=fh)
- print("\n".join(_psDefs), file=fh)
- if not mpl.rcParams['ps.useafm']:
- for font_path, chars \
- in ps_renderer._character_tracker.used.items():
- if not chars:
- continue
- fonttype = mpl.rcParams['ps.fonttype']
- # Can't use more than 255 chars from a single Type 3 font.
- if len(chars) > 255:
- fonttype = 42
- fh.flush()
- if fonttype == 3:
- fh.write(_font_to_ps_type3(font_path, chars))
- else: # Type 42 only.
- _font_to_ps_type42(font_path, chars, fh)
- print("end", file=fh)
- print("%%EndProlog", file=fh)
-
- if not is_eps:
- print("%%Page: 1 1", file=fh)
- print("mpldict begin", file=fh)
-
- print("%s translate" % _nums_to_str(xo, yo), file=fh)
- if rotation:
- print("%d rotate" % rotation, file=fh)
- print(f"0 0 {_nums_to_str(width*72, height*72)} rectclip", file=fh)
-
- # write the figure
- print(self._pswriter.getvalue(), file=fh)
-
- # write the trailer
- print("end", file=fh)
- print("showpage", file=fh)
- if not is_eps:
- print("%%EOF", file=fh)
- fh.flush()
-
- if mpl.rcParams['ps.usedistiller']:
- # We are going to use an external program to process the output.
- # Write to a temporary file.
- with TemporaryDirectory() as tmpdir:
- tmpfile = os.path.join(tmpdir, "tmp.ps")
- with open(tmpfile, 'w', encoding='latin-1') as fh:
- print_figure_impl(fh)
- if mpl.rcParams['ps.usedistiller'] == 'ghostscript':
- _try_distill(gs_distill,
- tmpfile, is_eps, ptype=papertype, bbox=bbox)
- elif mpl.rcParams['ps.usedistiller'] == 'xpdf':
- _try_distill(xpdf_distill,
- tmpfile, is_eps, ptype=papertype, bbox=bbox)
- _move_path_to_path_or_stream(tmpfile, outfile)
-
- else: # Write directly to outfile.
- with cbook.open_file_cm(outfile, "w", encoding="latin-1") as file:
- if not file_requires_unicode(file):
- file = codecs.getwriter("latin-1")(file)
- print_figure_impl(file)
-
- def _print_figure_tex(
- self, fmt, outfile, *,
- dpi, dsc_comments, orientation, papertype,
- bbox_inches_restore=None):
- """
- If :rc:`text.usetex` is True, a temporary pair of tex/eps files
- are created to allow tex to manage the text layout via the PSFrags
- package. These files are processed to yield the final ps or eps file.
-
- The rest of the behavior is as for `._print_figure`.
- """
- is_eps = fmt == 'eps'
-
- width, height = self.figure.get_size_inches()
- xo = 0
- yo = 0
-
- llx = xo
- lly = yo
- urx = llx + self.figure.bbox.width
- ury = lly + self.figure.bbox.height
- bbox = (llx, lly, urx, ury)
-
- self._pswriter = StringIO()
-
- # mixed mode rendering
- ps_renderer = RendererPS(width, height, self._pswriter, imagedpi=dpi)
- renderer = MixedModeRenderer(self.figure,
- width, height, dpi, ps_renderer,
- bbox_inches_restore=bbox_inches_restore)
-
- self.figure.draw(renderer)
-
- # write to a temp file, we'll move it to outfile when done
- with TemporaryDirectory() as tmpdir:
- tmppath = pathlib.Path(tmpdir, "tmp.ps")
- tmppath.write_text(
- f"""\
-%!PS-Adobe-3.0 EPSF-3.0
-%%LanguageLevel: 3
-{dsc_comments}
-{get_bbox_header(bbox)[0]}
-%%EndComments
-%%BeginProlog
-/mpldict {len(_psDefs)} dict def
-mpldict begin
-{"".join(_psDefs)}
-end
-%%EndProlog
-mpldict begin
-{_nums_to_str(xo, yo)} translate
-0 0 {_nums_to_str(width*72, height*72)} rectclip
-{self._pswriter.getvalue()}
-end
-showpage
-""",
- encoding="latin-1")
-
- if orientation is _Orientation.landscape: # now, ready to rotate
- width, height = height, width
- bbox = (lly, llx, ury, urx)
-
- # set the paper size to the figure size if is_eps. The
- # resulting ps file has the given size with correct bounding
- # box so that there is no need to call 'pstoeps'
- if is_eps or papertype == 'figure':
- paper_width, paper_height = orientation.swap_if_landscape(
- self.figure.get_size_inches())
- else:
- if papertype == 'auto':
- papertype = _get_papertype(width, height)
- paper_width, paper_height = papersize[papertype]
-
- psfrag_rotated = _convert_psfrags(
- tmppath, ps_renderer.psfrag, paper_width, paper_height,
- orientation.name)
-
- if (mpl.rcParams['ps.usedistiller'] == 'ghostscript'
- or mpl.rcParams['text.usetex']):
- _try_distill(gs_distill,
- tmppath, is_eps, ptype=papertype, bbox=bbox,
- rotated=psfrag_rotated)
- elif mpl.rcParams['ps.usedistiller'] == 'xpdf':
- _try_distill(xpdf_distill,
- tmppath, is_eps, ptype=papertype, bbox=bbox,
- rotated=psfrag_rotated)
-
- _move_path_to_path_or_stream(tmppath, outfile)
-
- print_ps = functools.partialmethod(_print_ps, "ps")
- print_eps = functools.partialmethod(_print_ps, "eps")
-
- def draw(self):
- self.figure.draw_without_rendering()
- return super().draw()
-
-
-def _convert_psfrags(tmppath, psfrags, paper_width, paper_height, orientation):
- """
- When we want to use the LaTeX backend with postscript, we write PSFrag tags
- to a temporary postscript file, each one marking a position for LaTeX to
- render some text. convert_psfrags generates a LaTeX document containing the
- commands to convert those tags to text. LaTeX/dvips produces the postscript
- file that includes the actual text.
- """
- with mpl.rc_context({
- "text.latex.preamble":
- mpl.rcParams["text.latex.preamble"] +
- mpl.texmanager._usepackage_if_not_loaded("color") +
- mpl.texmanager._usepackage_if_not_loaded("graphicx") +
- mpl.texmanager._usepackage_if_not_loaded("psfrag") +
- r"\geometry{papersize={%(width)sin,%(height)sin},margin=0in}"
- % {"width": paper_width, "height": paper_height}
- }):
- dvifile = TexManager().make_dvi(
- "\n"
- r"\begin{figure}""\n"
- r" \centering\leavevmode""\n"
- r" %(psfrags)s""\n"
- r" \includegraphics*[angle=%(angle)s]{%(epsfile)s}""\n"
- r"\end{figure}"
- % {
- "psfrags": "\n".join(psfrags),
- "angle": 90 if orientation == 'landscape' else 0,
- "epsfile": tmppath.resolve().as_posix(),
- },
- fontsize=10) # tex's default fontsize.
-
- with TemporaryDirectory() as tmpdir:
- psfile = os.path.join(tmpdir, "tmp.ps")
- cbook._check_and_log_subprocess(
- ['dvips', '-q', '-R0', '-o', psfile, dvifile], _log)
- shutil.move(psfile, tmppath)
-
- # check if the dvips created a ps in landscape paper. Somehow,
- # above latex+dvips results in a ps file in a landscape mode for a
- # certain figure sizes (e.g., 8.3in, 5.8in which is a5). And the
- # bounding box of the final output got messed up. We check see if
- # the generated ps file is in landscape and return this
- # information. The return value is used in pstoeps step to recover
- # the correct bounding box. 2010-06-05 JJL
- with open(tmppath) as fh:
- psfrag_rotated = "Landscape" in fh.read(1000)
- return psfrag_rotated
-
-
-def _try_distill(func, tmppath, *args, **kwargs):
- try:
- func(str(tmppath), *args, **kwargs)
- except mpl.ExecutableNotFoundError as exc:
- _log.warning("%s. Distillation step skipped.", exc)
-
-
-def gs_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False):
- """
- Use ghostscript's pswrite or epswrite device to distill a file.
- This yields smaller files without illegal encapsulated postscript
- operators. The output is low-level, converting text to outlines.
- """
-
- if eps:
- paper_option = ["-dEPSCrop"]
- elif ptype == "figure":
- # The bbox will have its lower-left corner at (0, 0), so upper-right
- # corner corresponds with paper size.
- paper_option = [f"-dDEVICEWIDTHPOINTS={bbox[2]}",
- f"-dDEVICEHEIGHTPOINTS={bbox[3]}"]
- else:
- paper_option = [f"-sPAPERSIZE={ptype}"]
-
- psfile = tmpfile + '.ps'
- dpi = mpl.rcParams['ps.distiller.res']
-
- cbook._check_and_log_subprocess(
- [mpl._get_executable_info("gs").executable,
- "-dBATCH", "-dNOPAUSE", "-r%d" % dpi, "-sDEVICE=ps2write",
- *paper_option, f"-sOutputFile={psfile}", tmpfile],
- _log)
-
- os.remove(tmpfile)
- shutil.move(psfile, tmpfile)
-
- # While it is best if above steps preserve the original bounding
- # box, there seem to be cases when it is not. For those cases,
- # the original bbox can be restored during the pstoeps step.
-
- if eps:
- # For some versions of gs, above steps result in a ps file where the
- # original bbox is no more correct. Do not adjust bbox for now.
- pstoeps(tmpfile, bbox, rotated=rotated)
-
-
-def xpdf_distill(tmpfile, eps=False, ptype='letter', bbox=None, rotated=False):
- """
- Use ghostscript's ps2pdf and xpdf's/poppler's pdftops to distill a file.
- This yields smaller files without illegal encapsulated postscript
- operators. This distiller is preferred, generating high-level postscript
- output that treats text as text.
- """
- mpl._get_executable_info("gs") # Effectively checks for ps2pdf.
- mpl._get_executable_info("pdftops")
-
- if eps:
- paper_option = ["-dEPSCrop"]
- elif ptype == "figure":
- # The bbox will have its lower-left corner at (0, 0), so upper-right
- # corner corresponds with paper size.
- paper_option = [f"-dDEVICEWIDTHPOINTS#{bbox[2]}",
- f"-dDEVICEHEIGHTPOINTS#{bbox[3]}"]
- else:
- paper_option = [f"-sPAPERSIZE#{ptype}"]
-
- with TemporaryDirectory() as tmpdir:
- tmppdf = pathlib.Path(tmpdir, "tmp.pdf")
- tmpps = pathlib.Path(tmpdir, "tmp.ps")
- # Pass options as `-foo#bar` instead of `-foo=bar` to keep Windows
- # happy (https://ghostscript.com/doc/9.56.1/Use.htm#MS_Windows).
- cbook._check_and_log_subprocess(
- ["ps2pdf",
- "-dAutoFilterColorImages#false",
- "-dAutoFilterGrayImages#false",
- "-sAutoRotatePages#None",
- "-sGrayImageFilter#FlateEncode",
- "-sColorImageFilter#FlateEncode",
- *paper_option,
- tmpfile, tmppdf], _log)
- cbook._check_and_log_subprocess(
- ["pdftops", "-paper", "match", "-level3", tmppdf, tmpps], _log)
- shutil.move(tmpps, tmpfile)
- if eps:
- pstoeps(tmpfile)
-
-
-def get_bbox_header(lbrt, rotated=False):
- """
- Return a postscript header string for the given bbox lbrt=(l, b, r, t).
- Optionally, return rotate command.
- """
-
- l, b, r, t = lbrt
- if rotated:
- rotate = f"{l+r:.2f} {0:.2f} translate\n90 rotate"
- else:
- rotate = ""
- bbox_info = '%%%%BoundingBox: %d %d %d %d' % (l, b, np.ceil(r), np.ceil(t))
- hires_bbox_info = f'%%HiResBoundingBox: {l:.6f} {b:.6f} {r:.6f} {t:.6f}'
-
- return '\n'.join([bbox_info, hires_bbox_info]), rotate
-
-
-def pstoeps(tmpfile, bbox=None, rotated=False):
- """
- Convert the postscript to encapsulated postscript. The bbox of
- the eps file will be replaced with the given *bbox* argument. If
- None, original bbox will be used.
- """
-
- # if rotated==True, the output eps file need to be rotated
- if bbox:
- bbox_info, rotate = get_bbox_header(bbox, rotated=rotated)
- else:
- bbox_info, rotate = None, None
-
- epsfile = tmpfile + '.eps'
- with open(epsfile, 'wb') as epsh, open(tmpfile, 'rb') as tmph:
- write = epsh.write
- # Modify the header:
- for line in tmph:
- if line.startswith(b'%!PS'):
- write(b"%!PS-Adobe-3.0 EPSF-3.0\n")
- if bbox:
- write(bbox_info.encode('ascii') + b'\n')
- elif line.startswith(b'%%EndComments'):
- write(line)
- write(b'%%BeginProlog\n'
- b'save\n'
- b'countdictstack\n'
- b'mark\n'
- b'newpath\n'
- b'/showpage {} def\n'
- b'/setpagedevice {pop} def\n'
- b'%%EndProlog\n'
- b'%%Page 1 1\n')
- if rotate:
- write(rotate.encode('ascii') + b'\n')
- break
- elif bbox and line.startswith((b'%%Bound', b'%%HiResBound',
- b'%%DocumentMedia', b'%%Pages')):
- pass
- else:
- write(line)
- # Now rewrite the rest of the file, and modify the trailer.
- # This is done in a second loop such that the header of the embedded
- # eps file is not modified.
- for line in tmph:
- if line.startswith(b'%%EOF'):
- write(b'cleartomark\n'
- b'countdictstack\n'
- b'exch sub { end } repeat\n'
- b'restore\n'
- b'showpage\n'
- b'%%EOF\n')
- elif line.startswith(b'%%PageBoundingBox'):
- pass
- else:
- write(line)
-
- os.remove(tmpfile)
- shutil.move(epsfile, tmpfile)
-
-
-FigureManagerPS = FigureManagerBase
-
-
-# The following Python dictionary psDefs contains the entries for the
-# PostScript dictionary mpldict. This dictionary implements most of
-# the matplotlib primitives and some abbreviations.
-#
-# References:
-# https://www.adobe.com/content/dam/acom/en/devnet/actionscript/articles/PLRM.pdf
-# http://preserve.mactech.com/articles/mactech/Vol.09/09.04/PostscriptTutorial
-# http://www.math.ubc.ca/people/faculty/cass/graphics/text/www/
-#
-
-# The usage comments use the notation of the operator summary
-# in the PostScript Language reference manual.
-_psDefs = [
- # name proc *_d* -
- # Note that this cannot be bound to /d, because when embedding a Type3 font
- # we may want to define a "d" glyph using "/d{...} d" which would locally
- # overwrite the definition.
- "/_d { bind def } bind def",
- # x y *m* -
- "/m { moveto } _d",
- # x y *l* -
- "/l { lineto } _d",
- # x y *r* -
- "/r { rlineto } _d",
- # x1 y1 x2 y2 x y *c* -
- "/c { curveto } _d",
- # *cl* -
- "/cl { closepath } _d",
- # *ce* -
- "/ce { closepath eofill } _d",
- # wx wy llx lly urx ury *setcachedevice* -
- "/sc { setcachedevice } _d",
-]
-
-
-@_Backend.export
-class _BackendPS(_Backend):
- backend_version = 'Level II'
- FigureCanvas = FigureCanvasPS
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_qt.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_qt.py
deleted file mode 100644
index 4b3783bc87..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_qt.py
+++ /dev/null
@@ -1,1022 +0,0 @@
-import functools
-import os
-import sys
-import traceback
-
-import matplotlib as mpl
-from matplotlib import _api, backend_tools, cbook
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, NavigationToolbar2,
- TimerBase, cursors, ToolContainerBase, MouseButton,
- CloseEvent, KeyEvent, LocationEvent, MouseEvent, ResizeEvent)
-import matplotlib.backends.qt_editor.figureoptions as figureoptions
-from . import qt_compat
-from .qt_compat import (
- QtCore, QtGui, QtWidgets, __version__, QT_API,
- _to_int, _isdeleted, _maybe_allow_interrupt
-)
-
-
-# SPECIAL_KEYS are Qt::Key that do *not* return their Unicode name
-# instead they have manually specified names.
-SPECIAL_KEYS = {
- _to_int(getattr(QtCore.Qt.Key, k)): v for k, v in [
- ("Key_Escape", "escape"),
- ("Key_Tab", "tab"),
- ("Key_Backspace", "backspace"),
- ("Key_Return", "enter"),
- ("Key_Enter", "enter"),
- ("Key_Insert", "insert"),
- ("Key_Delete", "delete"),
- ("Key_Pause", "pause"),
- ("Key_SysReq", "sysreq"),
- ("Key_Clear", "clear"),
- ("Key_Home", "home"),
- ("Key_End", "end"),
- ("Key_Left", "left"),
- ("Key_Up", "up"),
- ("Key_Right", "right"),
- ("Key_Down", "down"),
- ("Key_PageUp", "pageup"),
- ("Key_PageDown", "pagedown"),
- ("Key_Shift", "shift"),
- # In OSX, the control and super (aka cmd/apple) keys are switched.
- ("Key_Control", "control" if sys.platform != "darwin" else "cmd"),
- ("Key_Meta", "meta" if sys.platform != "darwin" else "control"),
- ("Key_Alt", "alt"),
- ("Key_CapsLock", "caps_lock"),
- ("Key_F1", "f1"),
- ("Key_F2", "f2"),
- ("Key_F3", "f3"),
- ("Key_F4", "f4"),
- ("Key_F5", "f5"),
- ("Key_F6", "f6"),
- ("Key_F7", "f7"),
- ("Key_F8", "f8"),
- ("Key_F9", "f9"),
- ("Key_F10", "f10"),
- ("Key_F10", "f11"),
- ("Key_F12", "f12"),
- ("Key_Super_L", "super"),
- ("Key_Super_R", "super"),
- ]
-}
-# Define which modifier keys are collected on keyboard events.
-# Elements are (Qt::KeyboardModifiers, Qt::Key) tuples.
-# Order determines the modifier order (ctrl+alt+...) reported by Matplotlib.
-_MODIFIER_KEYS = [
- (_to_int(getattr(QtCore.Qt.KeyboardModifier, mod)),
- _to_int(getattr(QtCore.Qt.Key, key)))
- for mod, key in [
- ("ControlModifier", "Key_Control"),
- ("AltModifier", "Key_Alt"),
- ("ShiftModifier", "Key_Shift"),
- ("MetaModifier", "Key_Meta"),
- ]
-]
-cursord = {
- k: getattr(QtCore.Qt.CursorShape, v) for k, v in [
- (cursors.MOVE, "SizeAllCursor"),
- (cursors.HAND, "PointingHandCursor"),
- (cursors.POINTER, "ArrowCursor"),
- (cursors.SELECT_REGION, "CrossCursor"),
- (cursors.WAIT, "WaitCursor"),
- (cursors.RESIZE_HORIZONTAL, "SizeHorCursor"),
- (cursors.RESIZE_VERTICAL, "SizeVerCursor"),
- ]
-}
-
-
-# lru_cache keeps a reference to the QApplication instance, keeping it from
-# being GC'd.
-@functools.lru_cache(1)
-def _create_qApp():
- app = QtWidgets.QApplication.instance()
-
- # Create a new QApplication and configure it if none exists yet, as only
- # one QApplication can exist at a time.
- if app is None:
- # display_is_valid returns False only if on Linux and neither X11
- # nor Wayland display can be opened.
- if not mpl._c_internal_utils.display_is_valid():
- raise RuntimeError('Invalid DISPLAY variable')
-
- # Check to make sure a QApplication from a different major version
- # of Qt is not instantiated in the process
- if QT_API in {'PyQt6', 'PySide6'}:
- other_bindings = ('PyQt5', 'PySide2')
- qt_version = 6
- elif QT_API in {'PyQt5', 'PySide2'}:
- other_bindings = ('PyQt6', 'PySide6')
- qt_version = 5
- else:
- raise RuntimeError("Should never be here")
-
- for binding in other_bindings:
- mod = sys.modules.get(f'{binding}.QtWidgets')
- if mod is not None and mod.QApplication.instance() is not None:
- other_core = sys.modules.get(f'{binding}.QtCore')
- _api.warn_external(
- f'Matplotlib is using {QT_API} which wraps '
- f'{QtCore.qVersion()} however an instantiated '
- f'QApplication from {binding} which wraps '
- f'{other_core.qVersion()} exists. Mixing Qt major '
- 'versions may not work as expected.'
- )
- break
- if qt_version == 5:
- try:
- QtWidgets.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
- except AttributeError: # Only for Qt>=5.6, <6.
- pass
- try:
- QtWidgets.QApplication.setHighDpiScaleFactorRoundingPolicy(
- QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
- except AttributeError: # Only for Qt>=5.14.
- pass
- app = QtWidgets.QApplication(["matplotlib"])
- if sys.platform == "darwin":
- image = str(cbook._get_data_path('images/matplotlib.svg'))
- icon = QtGui.QIcon(image)
- app.setWindowIcon(icon)
- app.setQuitOnLastWindowClosed(True)
- cbook._setup_new_guiapp()
- if qt_version == 5:
- app.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps)
-
- return app
-
-
-class TimerQT(TimerBase):
- """Subclass of `.TimerBase` using QTimer events."""
-
- def __init__(self, *args, **kwargs):
- # Create a new timer and connect the timeout() signal to the
- # _on_timer method.
- self._timer = QtCore.QTimer()
- self._timer.timeout.connect(self._on_timer)
- super().__init__(*args, **kwargs)
-
- def __del__(self):
- # The check for deletedness is needed to avoid an error at animation
- # shutdown with PySide2.
- if not _isdeleted(self._timer):
- self._timer_stop()
-
- def _timer_set_single_shot(self):
- self._timer.setSingleShot(self._single)
-
- def _timer_set_interval(self):
- self._timer.setInterval(self._interval)
-
- def _timer_start(self):
- self._timer.start()
-
- def _timer_stop(self):
- self._timer.stop()
-
-
-class FigureCanvasQT(FigureCanvasBase, QtWidgets.QWidget):
- required_interactive_framework = "qt"
- _timer_cls = TimerQT
- manager_class = _api.classproperty(lambda cls: FigureManagerQT)
-
- buttond = {
- getattr(QtCore.Qt.MouseButton, k): v for k, v in [
- ("LeftButton", MouseButton.LEFT),
- ("RightButton", MouseButton.RIGHT),
- ("MiddleButton", MouseButton.MIDDLE),
- ("XButton1", MouseButton.BACK),
- ("XButton2", MouseButton.FORWARD),
- ]
- }
-
- def __init__(self, figure=None):
- _create_qApp()
- super().__init__(figure=figure)
-
- self._draw_pending = False
- self._is_drawing = False
- self._draw_rect_callback = lambda painter: None
- self._in_resize_event = False
-
- self.setAttribute(QtCore.Qt.WidgetAttribute.WA_OpaquePaintEvent)
- self.setMouseTracking(True)
- self.resize(*self.get_width_height())
-
- palette = QtGui.QPalette(QtGui.QColor("white"))
- self.setPalette(palette)
-
- def _update_pixel_ratio(self):
- if self._set_device_pixel_ratio(
- self.devicePixelRatioF() or 1): # rarely, devicePixelRatioF=0
- # The easiest way to resize the canvas is to emit a resizeEvent
- # since we implement all the logic for resizing the canvas for
- # that event.
- event = QtGui.QResizeEvent(self.size(), self.size())
- self.resizeEvent(event)
-
- def _update_screen(self, screen):
- # Handler for changes to a window's attached screen.
- self._update_pixel_ratio()
- if screen is not None:
- screen.physicalDotsPerInchChanged.connect(self._update_pixel_ratio)
- screen.logicalDotsPerInchChanged.connect(self._update_pixel_ratio)
-
- def showEvent(self, event):
- # Set up correct pixel ratio, and connect to any signal changes for it,
- # once the window is shown (and thus has these attributes).
- window = self.window().windowHandle()
- window.screenChanged.connect(self._update_screen)
- self._update_screen(window.screen())
-
- def set_cursor(self, cursor):
- # docstring inherited
- self.setCursor(_api.check_getitem(cursord, cursor=cursor))
-
- def mouseEventCoords(self, pos=None):
- """
- Calculate mouse coordinates in physical pixels.
-
- Qt uses logical pixels, but the figure is scaled to physical
- pixels for rendering. Transform to physical pixels so that
- all of the down-stream transforms work as expected.
-
- Also, the origin is different and needs to be corrected.
- """
- if pos is None:
- pos = self.mapFromGlobal(QtGui.QCursor.pos())
- elif hasattr(pos, "position"): # qt6 QtGui.QEvent
- pos = pos.position()
- elif hasattr(pos, "pos"): # qt5 QtCore.QEvent
- pos = pos.pos()
- # (otherwise, it's already a QPoint)
- x = pos.x()
- # flip y so y=0 is bottom of canvas
- y = self.figure.bbox.height / self.device_pixel_ratio - pos.y()
- return x * self.device_pixel_ratio, y * self.device_pixel_ratio
-
- def enterEvent(self, event):
- # Force querying of the modifiers, as the cached modifier state can
- # have been invalidated while the window was out of focus.
- mods = QtWidgets.QApplication.instance().queryKeyboardModifiers()
- LocationEvent("figure_enter_event", self,
- *self.mouseEventCoords(event),
- modifiers=self._mpl_modifiers(mods),
- guiEvent=event)._process()
-
- def leaveEvent(self, event):
- QtWidgets.QApplication.restoreOverrideCursor()
- LocationEvent("figure_leave_event", self,
- *self.mouseEventCoords(),
- modifiers=self._mpl_modifiers(),
- guiEvent=event)._process()
-
- def mousePressEvent(self, event):
- button = self.buttond.get(event.button())
- if button is not None:
- MouseEvent("button_press_event", self,
- *self.mouseEventCoords(event), button,
- modifiers=self._mpl_modifiers(),
- guiEvent=event)._process()
-
- def mouseDoubleClickEvent(self, event):
- button = self.buttond.get(event.button())
- if button is not None:
- MouseEvent("button_press_event", self,
- *self.mouseEventCoords(event), button, dblclick=True,
- modifiers=self._mpl_modifiers(),
- guiEvent=event)._process()
-
- def mouseMoveEvent(self, event):
- MouseEvent("motion_notify_event", self,
- *self.mouseEventCoords(event),
- modifiers=self._mpl_modifiers(),
- guiEvent=event)._process()
-
- def mouseReleaseEvent(self, event):
- button = self.buttond.get(event.button())
- if button is not None:
- MouseEvent("button_release_event", self,
- *self.mouseEventCoords(event), button,
- modifiers=self._mpl_modifiers(),
- guiEvent=event)._process()
-
- def wheelEvent(self, event):
- # from QWheelEvent::pixelDelta doc: pixelDelta is sometimes not
- # provided (`isNull()`) and is unreliable on X11 ("xcb").
- if (event.pixelDelta().isNull()
- or QtWidgets.QApplication.instance().platformName() == "xcb"):
- steps = event.angleDelta().y() / 120
- else:
- steps = event.pixelDelta().y()
- if steps:
- MouseEvent("scroll_event", self,
- *self.mouseEventCoords(event), step=steps,
- modifiers=self._mpl_modifiers(),
- guiEvent=event)._process()
-
- def keyPressEvent(self, event):
- key = self._get_key(event)
- if key is not None:
- KeyEvent("key_press_event", self,
- key, *self.mouseEventCoords(),
- guiEvent=event)._process()
-
- def keyReleaseEvent(self, event):
- key = self._get_key(event)
- if key is not None:
- KeyEvent("key_release_event", self,
- key, *self.mouseEventCoords(),
- guiEvent=event)._process()
-
- def resizeEvent(self, event):
- if self._in_resize_event: # Prevent PyQt6 recursion
- return
- self._in_resize_event = True
- try:
- w = event.size().width() * self.device_pixel_ratio
- h = event.size().height() * self.device_pixel_ratio
- dpival = self.figure.dpi
- winch = w / dpival
- hinch = h / dpival
- self.figure.set_size_inches(winch, hinch, forward=False)
- # pass back into Qt to let it finish
- QtWidgets.QWidget.resizeEvent(self, event)
- # emit our resize events
- ResizeEvent("resize_event", self)._process()
- self.draw_idle()
- finally:
- self._in_resize_event = False
-
- def sizeHint(self):
- w, h = self.get_width_height()
- return QtCore.QSize(w, h)
-
- def minumumSizeHint(self):
- return QtCore.QSize(10, 10)
-
- @staticmethod
- def _mpl_modifiers(modifiers=None, *, exclude=None):
- if modifiers is None:
- modifiers = QtWidgets.QApplication.instance().keyboardModifiers()
- modifiers = _to_int(modifiers)
- # get names of the pressed modifier keys
- # 'control' is named 'control' when a standalone key, but 'ctrl' when a
- # modifier
- # bit twiddling to pick out modifier keys from modifiers bitmask,
- # if exclude is a MODIFIER, it should not be duplicated in mods
- return [SPECIAL_KEYS[key].replace('control', 'ctrl')
- for mask, key in _MODIFIER_KEYS
- if exclude != key and modifiers & mask]
-
- def _get_key(self, event):
- event_key = event.key()
- mods = self._mpl_modifiers(exclude=event_key)
- try:
- # for certain keys (enter, left, backspace, etc) use a word for the
- # key, rather than Unicode
- key = SPECIAL_KEYS[event_key]
- except KeyError:
- # Unicode defines code points up to 0x10ffff (sys.maxunicode)
- # QT will use Key_Codes larger than that for keyboard keys that are
- # not Unicode characters (like multimedia keys)
- # skip these
- # if you really want them, you should add them to SPECIAL_KEYS
- if event_key > sys.maxunicode:
- return None
-
- key = chr(event_key)
- # qt delivers capitalized letters. fix capitalization
- # note that capslock is ignored
- if 'shift' in mods:
- mods.remove('shift')
- else:
- key = key.lower()
-
- return '+'.join(mods + [key])
-
- def flush_events(self):
- # docstring inherited
- QtWidgets.QApplication.instance().processEvents()
-
- def start_event_loop(self, timeout=0):
- # docstring inherited
- if hasattr(self, "_event_loop") and self._event_loop.isRunning():
- raise RuntimeError("Event loop already running")
- self._event_loop = event_loop = QtCore.QEventLoop()
- if timeout > 0:
- _ = QtCore.QTimer.singleShot(int(timeout * 1000), event_loop.quit)
-
- with _maybe_allow_interrupt(event_loop):
- qt_compat._exec(event_loop)
-
- def stop_event_loop(self, event=None):
- # docstring inherited
- if hasattr(self, "_event_loop"):
- self._event_loop.quit()
-
- def draw(self):
- """Render the figure, and queue a request for a Qt draw."""
- # The renderer draw is done here; delaying causes problems with code
- # that uses the result of the draw() to update plot elements.
- if self._is_drawing:
- return
- with cbook._setattr_cm(self, _is_drawing=True):
- super().draw()
- self.update()
-
- def draw_idle(self):
- """Queue redraw of the Agg buffer and request Qt paintEvent."""
- # The Agg draw needs to be handled by the same thread Matplotlib
- # modifies the scene graph from. Post Agg draw request to the
- # current event loop in order to ensure thread affinity and to
- # accumulate multiple draw requests from event handling.
- # TODO: queued signal connection might be safer than singleShot
- if not (getattr(self, '_draw_pending', False) or
- getattr(self, '_is_drawing', False)):
- self._draw_pending = True
- QtCore.QTimer.singleShot(0, self._draw_idle)
-
- def blit(self, bbox=None):
- # docstring inherited
- if bbox is None and self.figure:
- bbox = self.figure.bbox # Blit the entire canvas if bbox is None.
- # repaint uses logical pixels, not physical pixels like the renderer.
- l, b, w, h = [int(pt / self.device_pixel_ratio) for pt in bbox.bounds]
- t = b + h
- self.repaint(l, self.rect().height() - t, w, h)
-
- def _draw_idle(self):
- with self._idle_draw_cntx():
- if not self._draw_pending:
- return
- self._draw_pending = False
- if self.height() < 0 or self.width() < 0:
- return
- try:
- self.draw()
- except Exception:
- # Uncaught exceptions are fatal for PyQt5, so catch them.
- traceback.print_exc()
-
- def drawRectangle(self, rect):
- # Draw the zoom rectangle to the QPainter. _draw_rect_callback needs
- # to be called at the end of paintEvent.
- if rect is not None:
- x0, y0, w, h = [int(pt / self.device_pixel_ratio) for pt in rect]
- x1 = x0 + w
- y1 = y0 + h
- def _draw_rect_callback(painter):
- pen = QtGui.QPen(
- QtGui.QColor("black"),
- 1 / self.device_pixel_ratio
- )
-
- pen.setDashPattern([3, 3])
- for color, offset in [
- (QtGui.QColor("black"), 0),
- (QtGui.QColor("white"), 3),
- ]:
- pen.setDashOffset(offset)
- pen.setColor(color)
- painter.setPen(pen)
- # Draw the lines from x0, y0 towards x1, y1 so that the
- # dashes don't "jump" when moving the zoom box.
- painter.drawLine(x0, y0, x0, y1)
- painter.drawLine(x0, y0, x1, y0)
- painter.drawLine(x0, y1, x1, y1)
- painter.drawLine(x1, y0, x1, y1)
- else:
- def _draw_rect_callback(painter):
- return
- self._draw_rect_callback = _draw_rect_callback
- self.update()
-
-
-class MainWindow(QtWidgets.QMainWindow):
- closing = QtCore.Signal()
-
- def closeEvent(self, event):
- self.closing.emit()
- super().closeEvent(event)
-
-
-class FigureManagerQT(FigureManagerBase):
- """
- Attributes
- ----------
- canvas : `FigureCanvas`
- The FigureCanvas instance
- num : int or str
- The Figure number
- toolbar : qt.QToolBar
- The qt.QToolBar
- window : qt.QMainWindow
- The qt.QMainWindow
- """
-
- def __init__(self, canvas, num):
- self.window = MainWindow()
- super().__init__(canvas, num)
- self.window.closing.connect(self._widgetclosed)
-
- if sys.platform != "darwin":
- image = str(cbook._get_data_path('images/matplotlib.svg'))
- icon = QtGui.QIcon(image)
- self.window.setWindowIcon(icon)
-
- self.window._destroying = False
-
- if self.toolbar:
- self.window.addToolBar(self.toolbar)
- tbs_height = self.toolbar.sizeHint().height()
- else:
- tbs_height = 0
-
- # resize the main window so it will display the canvas with the
- # requested size:
- cs = canvas.sizeHint()
- cs_height = cs.height()
- height = cs_height + tbs_height
- self.window.resize(cs.width(), height)
-
- self.window.setCentralWidget(self.canvas)
-
- if mpl.is_interactive():
- self.window.show()
- self.canvas.draw_idle()
-
- # Give the keyboard focus to the figure instead of the manager:
- # StrongFocus accepts both tab and click to focus and will enable the
- # canvas to process event without clicking.
- # https://doc.qt.io/qt-5/qt.html#FocusPolicy-enum
- self.canvas.setFocusPolicy(QtCore.Qt.FocusPolicy.StrongFocus)
- self.canvas.setFocus()
-
- self.window.raise_()
-
- def full_screen_toggle(self):
- if self.window.isFullScreen():
- self.window.showNormal()
- else:
- self.window.showFullScreen()
-
- def _widgetclosed(self):
- CloseEvent("close_event", self.canvas)._process()
- if self.window._destroying:
- return
- self.window._destroying = True
- try:
- Gcf.destroy(self)
- except AttributeError:
- pass
- # It seems that when the python session is killed,
- # Gcf can get destroyed before the Gcf.destroy
- # line is run, leading to a useless AttributeError.
-
- def resize(self, width, height):
- # The Qt methods return sizes in 'virtual' pixels so we do need to
- # rescale from physical to logical pixels.
- width = int(width / self.canvas.device_pixel_ratio)
- height = int(height / self.canvas.device_pixel_ratio)
- extra_width = self.window.width() - self.canvas.width()
- extra_height = self.window.height() - self.canvas.height()
- self.canvas.resize(width, height)
- self.window.resize(width + extra_width, height + extra_height)
-
- @classmethod
- def start_main_loop(cls):
- qapp = QtWidgets.QApplication.instance()
- if qapp:
- with _maybe_allow_interrupt(qapp):
- qt_compat._exec(qapp)
-
- def show(self):
- self.window.show()
- if mpl.rcParams['figure.raise_window']:
- self.window.activateWindow()
- self.window.raise_()
-
- def destroy(self, *args):
- # check for qApp first, as PySide deletes it in its atexit handler
- if QtWidgets.QApplication.instance() is None:
- return
- if self.window._destroying:
- return
- self.window._destroying = True
- if self.toolbar:
- self.toolbar.destroy()
- self.window.close()
-
- def get_window_title(self):
- return self.window.windowTitle()
-
- def set_window_title(self, title):
- self.window.setWindowTitle(title)
-
-
-class NavigationToolbar2QT(NavigationToolbar2, QtWidgets.QToolBar):
- _message = QtCore.Signal(str) # Remove once deprecation below elapses.
- message = _api.deprecate_privatize_attribute("3.8")
-
- toolitems = [*NavigationToolbar2.toolitems]
- toolitems.insert(
- # Add 'customize' action after 'subplots'
- [name for name, *_ in toolitems].index("Subplots") + 1,
- ("Customize", "Edit axis, curve and image parameters",
- "qt4_editor_options", "edit_parameters"))
-
- def __init__(self, canvas, parent=None, coordinates=True):
- """coordinates: should we show the coordinates on the right?"""
- QtWidgets.QToolBar.__init__(self, parent)
- self.setAllowedAreas(QtCore.Qt.ToolBarArea(
- _to_int(QtCore.Qt.ToolBarArea.TopToolBarArea) |
- _to_int(QtCore.Qt.ToolBarArea.BottomToolBarArea)))
- self.coordinates = coordinates
- self._actions = {} # mapping of toolitem method names to QActions.
- self._subplot_dialog = None
-
- for text, tooltip_text, image_file, callback in self.toolitems:
- if text is None:
- self.addSeparator()
- else:
- a = self.addAction(self._icon(image_file + '.png'),
- text, getattr(self, callback))
- self._actions[callback] = a
- if callback in ['zoom', 'pan']:
- a.setCheckable(True)
- if tooltip_text is not None:
- a.setToolTip(tooltip_text)
-
- # Add the (x, y) location widget at the right side of the toolbar
- # The stretch factor is 1 which means any resizing of the toolbar
- # will resize this label instead of the buttons.
- if self.coordinates:
- self.locLabel = QtWidgets.QLabel("", self)
- self.locLabel.setAlignment(QtCore.Qt.AlignmentFlag(
- _to_int(QtCore.Qt.AlignmentFlag.AlignRight) |
- _to_int(QtCore.Qt.AlignmentFlag.AlignVCenter)))
-
- self.locLabel.setSizePolicy(QtWidgets.QSizePolicy(
- QtWidgets.QSizePolicy.Policy.Expanding,
- QtWidgets.QSizePolicy.Policy.Ignored,
- ))
- labelAction = self.addWidget(self.locLabel)
- labelAction.setVisible(True)
-
- NavigationToolbar2.__init__(self, canvas)
-
- def _icon(self, name):
- """
- Construct a `.QIcon` from an image file *name*, including the extension
- and relative to Matplotlib's "images" data directory.
- """
- # use a high-resolution icon with suffix '_large' if available
- # note: user-provided icons may not have '_large' versions
- path_regular = cbook._get_data_path('images', name)
- path_large = path_regular.with_name(
- path_regular.name.replace('.png', '_large.png'))
- filename = str(path_large if path_large.exists() else path_regular)
-
- pm = QtGui.QPixmap(filename)
- pm.setDevicePixelRatio(
- self.devicePixelRatioF() or 1) # rarely, devicePixelRatioF=0
- if self.palette().color(self.backgroundRole()).value() < 128:
- icon_color = self.palette().color(self.foregroundRole())
- mask = pm.createMaskFromColor(
- QtGui.QColor('black'),
- QtCore.Qt.MaskMode.MaskOutColor)
- pm.fill(icon_color)
- pm.setMask(mask)
- return QtGui.QIcon(pm)
-
- def edit_parameters(self):
- axes = self.canvas.figure.get_axes()
- if not axes:
- QtWidgets.QMessageBox.warning(
- self.canvas.parent(), "Error", "There are no axes to edit.")
- return
- elif len(axes) == 1:
- ax, = axes
- else:
- titles = [
- ax.get_label() or
- ax.get_title() or
- ax.get_title("left") or
- ax.get_title("right") or
- " - ".join(filter(None, [ax.get_xlabel(), ax.get_ylabel()])) or
- f"<anonymous {type(ax).__name__}>"
- for ax in axes]
- duplicate_titles = [
- title for title in titles if titles.count(title) > 1]
- for i, ax in enumerate(axes):
- if titles[i] in duplicate_titles:
- titles[i] += f" (id: {id(ax):#x})" # Deduplicate titles.
- item, ok = QtWidgets.QInputDialog.getItem(
- self.canvas.parent(),
- 'Customize', 'Select axes:', titles, 0, False)
- if not ok:
- return
- ax = axes[titles.index(item)]
- figureoptions.figure_edit(ax, self)
-
- def _update_buttons_checked(self):
- # sync button checkstates to match active mode
- if 'pan' in self._actions:
- self._actions['pan'].setChecked(self.mode.name == 'PAN')
- if 'zoom' in self._actions:
- self._actions['zoom'].setChecked(self.mode.name == 'ZOOM')
-
- def pan(self, *args):
- super().pan(*args)
- self._update_buttons_checked()
-
- def zoom(self, *args):
- super().zoom(*args)
- self._update_buttons_checked()
-
- def set_message(self, s):
- self._message.emit(s)
- if self.coordinates:
- self.locLabel.setText(s)
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- height = self.canvas.figure.bbox.height
- y1 = height - y1
- y0 = height - y0
- rect = [int(val) for val in (x0, y0, x1 - x0, y1 - y0)]
- self.canvas.drawRectangle(rect)
-
- def remove_rubberband(self):
- self.canvas.drawRectangle(None)
-
- def configure_subplots(self):
- if self._subplot_dialog is None:
- self._subplot_dialog = SubplotToolQt(
- self.canvas.figure, self.canvas.parent())
- self.canvas.mpl_connect(
- "close_event", lambda e: self._subplot_dialog.reject())
- self._subplot_dialog.update_from_current_subplotpars()
- self._subplot_dialog.show()
- return self._subplot_dialog
-
- def save_figure(self, *args):
- filetypes = self.canvas.get_supported_filetypes_grouped()
- sorted_filetypes = sorted(filetypes.items())
- default_filetype = self.canvas.get_default_filetype()
-
- startpath = os.path.expanduser(mpl.rcParams['savefig.directory'])
- start = os.path.join(startpath, self.canvas.get_default_filename())
- filters = []
- selectedFilter = None
- for name, exts in sorted_filetypes:
- exts_list = " ".join(['*.%s' % ext for ext in exts])
- filter = f'{name} ({exts_list})'
- if default_filetype in exts:
- selectedFilter = filter
- filters.append(filter)
- filters = ';;'.join(filters)
-
- fname, filter = QtWidgets.QFileDialog.getSaveFileName(
- self.canvas.parent(), "Choose a filename to save to", start,
- filters, selectedFilter)
- if fname:
- # Save dir for next time, unless empty str (i.e., use cwd).
- if startpath != "":
- mpl.rcParams['savefig.directory'] = os.path.dirname(fname)
- try:
- self.canvas.figure.savefig(fname)
- except Exception as e:
- QtWidgets.QMessageBox.critical(
- self, "Error saving file", str(e),
- QtWidgets.QMessageBox.StandardButton.Ok,
- QtWidgets.QMessageBox.StandardButton.NoButton)
-
- def set_history_buttons(self):
- can_backward = self._nav_stack._pos > 0
- can_forward = self._nav_stack._pos < len(self._nav_stack) - 1
- if 'back' in self._actions:
- self._actions['back'].setEnabled(can_backward)
- if 'forward' in self._actions:
- self._actions['forward'].setEnabled(can_forward)
-
-
-class SubplotToolQt(QtWidgets.QDialog):
- def __init__(self, targetfig, parent):
- super().__init__()
- self.setWindowIcon(QtGui.QIcon(
- str(cbook._get_data_path("images/matplotlib.png"))))
- self.setObjectName("SubplotTool")
- self._spinboxes = {}
- main_layout = QtWidgets.QHBoxLayout()
- self.setLayout(main_layout)
- for group, spinboxes, buttons in [
- ("Borders",
- ["top", "bottom", "left", "right"],
- [("Export values", self._export_values)]),
- ("Spacings",
- ["hspace", "wspace"],
- [("Tight layout", self._tight_layout),
- ("Reset", self._reset),
- ("Close", self.close)])]:
- layout = QtWidgets.QVBoxLayout()
- main_layout.addLayout(layout)
- box = QtWidgets.QGroupBox(group)
- layout.addWidget(box)
- inner = QtWidgets.QFormLayout(box)
- for name in spinboxes:
- self._spinboxes[name] = spinbox = QtWidgets.QDoubleSpinBox()
- spinbox.setRange(0, 1)
- spinbox.setDecimals(3)
- spinbox.setSingleStep(0.005)
- spinbox.setKeyboardTracking(False)
- spinbox.valueChanged.connect(self._on_value_changed)
- inner.addRow(name, spinbox)
- layout.addStretch(1)
- for name, method in buttons:
- button = QtWidgets.QPushButton(name)
- # Don't trigger on <enter>, which is used to input values.
- button.setAutoDefault(False)
- button.clicked.connect(method)
- layout.addWidget(button)
- if name == "Close":
- button.setFocus()
- self._figure = targetfig
- self._defaults = {}
- self._export_values_dialog = None
- self.update_from_current_subplotpars()
-
- def update_from_current_subplotpars(self):
- self._defaults = {spinbox: getattr(self._figure.subplotpars, name)
- for name, spinbox in self._spinboxes.items()}
- self._reset() # Set spinbox current values without triggering signals.
-
- def _export_values(self):
- # Explicitly round to 3 decimals (which is also the spinbox precision)
- # to avoid numbers of the form 0.100...001.
- self._export_values_dialog = QtWidgets.QDialog()
- layout = QtWidgets.QVBoxLayout()
- self._export_values_dialog.setLayout(layout)
- text = QtWidgets.QPlainTextEdit()
- text.setReadOnly(True)
- layout.addWidget(text)
- text.setPlainText(
- ",\n".join(f"{attr}={spinbox.value():.3}"
- for attr, spinbox in self._spinboxes.items()))
- # Adjust the height of the text widget to fit the whole text, plus
- # some padding.
- size = text.maximumSize()
- size.setHeight(
- QtGui.QFontMetrics(text.document().defaultFont())
- .size(0, text.toPlainText()).height() + 20)
- text.setMaximumSize(size)
- self._export_values_dialog.show()
-
- def _on_value_changed(self):
- spinboxes = self._spinboxes
- # Set all mins and maxes, so that this can also be used in _reset().
- for lower, higher in [("bottom", "top"), ("left", "right")]:
- spinboxes[higher].setMinimum(spinboxes[lower].value() + .001)
- spinboxes[lower].setMaximum(spinboxes[higher].value() - .001)
- self._figure.subplots_adjust(
- **{attr: spinbox.value() for attr, spinbox in spinboxes.items()})
- self._figure.canvas.draw_idle()
-
- def _tight_layout(self):
- self._figure.tight_layout()
- for attr, spinbox in self._spinboxes.items():
- spinbox.blockSignals(True)
- spinbox.setValue(getattr(self._figure.subplotpars, attr))
- spinbox.blockSignals(False)
- self._figure.canvas.draw_idle()
-
- def _reset(self):
- for spinbox, value in self._defaults.items():
- spinbox.setRange(0, 1)
- spinbox.blockSignals(True)
- spinbox.setValue(value)
- spinbox.blockSignals(False)
- self._on_value_changed()
-
-
-class ToolbarQt(ToolContainerBase, QtWidgets.QToolBar):
- def __init__(self, toolmanager, parent=None):
- ToolContainerBase.__init__(self, toolmanager)
- QtWidgets.QToolBar.__init__(self, parent)
- self.setAllowedAreas(QtCore.Qt.ToolBarArea(
- _to_int(QtCore.Qt.ToolBarArea.TopToolBarArea) |
- _to_int(QtCore.Qt.ToolBarArea.BottomToolBarArea)))
- message_label = QtWidgets.QLabel("")
- message_label.setAlignment(QtCore.Qt.AlignmentFlag(
- _to_int(QtCore.Qt.AlignmentFlag.AlignRight) |
- _to_int(QtCore.Qt.AlignmentFlag.AlignVCenter)))
- message_label.setSizePolicy(QtWidgets.QSizePolicy(
- QtWidgets.QSizePolicy.Policy.Expanding,
- QtWidgets.QSizePolicy.Policy.Ignored,
- ))
- self._message_action = self.addWidget(message_label)
- self._toolitems = {}
- self._groups = {}
-
- def add_toolitem(
- self, name, group, position, image_file, description, toggle):
-
- button = QtWidgets.QToolButton(self)
- if image_file:
- button.setIcon(NavigationToolbar2QT._icon(self, image_file))
- button.setText(name)
- if description:
- button.setToolTip(description)
-
- def handler():
- self.trigger_tool(name)
- if toggle:
- button.setCheckable(True)
- button.toggled.connect(handler)
- else:
- button.clicked.connect(handler)
-
- self._toolitems.setdefault(name, [])
- self._add_to_group(group, name, button, position)
- self._toolitems[name].append((button, handler))
-
- def _add_to_group(self, group, name, button, position):
- gr = self._groups.get(group, [])
- if not gr:
- sep = self.insertSeparator(self._message_action)
- gr.append(sep)
- before = gr[position]
- widget = self.insertWidget(before, button)
- gr.insert(position, widget)
- self._groups[group] = gr
-
- def toggle_toolitem(self, name, toggled):
- if name not in self._toolitems:
- return
- for button, handler in self._toolitems[name]:
- button.toggled.disconnect(handler)
- button.setChecked(toggled)
- button.toggled.connect(handler)
-
- def remove_toolitem(self, name):
- for button, handler in self._toolitems[name]:
- button.setParent(None)
- del self._toolitems[name]
-
- def set_message(self, s):
- self.widgetForAction(self._message_action).setText(s)
-
-
-@backend_tools._register_tool_class(FigureCanvasQT)
-class ConfigureSubplotsQt(backend_tools.ConfigureSubplotsBase):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- self._subplot_dialog = None
-
- def trigger(self, *args):
- NavigationToolbar2QT.configure_subplots(self)
-
-
-@backend_tools._register_tool_class(FigureCanvasQT)
-class SaveFigureQt(backend_tools.SaveFigureBase):
- def trigger(self, *args):
- NavigationToolbar2QT.save_figure(
- self._make_classic_style_pseudo_toolbar())
-
-
-@backend_tools._register_tool_class(FigureCanvasQT)
-class RubberbandQt(backend_tools.RubberbandBase):
- def draw_rubberband(self, x0, y0, x1, y1):
- NavigationToolbar2QT.draw_rubberband(
- self._make_classic_style_pseudo_toolbar(), None, x0, y0, x1, y1)
-
- def remove_rubberband(self):
- NavigationToolbar2QT.remove_rubberband(
- self._make_classic_style_pseudo_toolbar())
-
-
-@backend_tools._register_tool_class(FigureCanvasQT)
-class HelpQt(backend_tools.ToolHelpBase):
- def trigger(self, *args):
- QtWidgets.QMessageBox.information(None, "Help", self._get_help_html())
-
-
-@backend_tools._register_tool_class(FigureCanvasQT)
-class ToolCopyToClipboardQT(backend_tools.ToolCopyToClipboardBase):
- def trigger(self, *args, **kwargs):
- pixmap = self.canvas.grab()
- QtWidgets.QApplication.instance().clipboard().setPixmap(pixmap)
-
-
-FigureManagerQT._toolbar2_class = NavigationToolbar2QT
-FigureManagerQT._toolmanager_toolbar_class = ToolbarQt
-
-
-@_Backend.export
-class _BackendQT(_Backend):
- backend_version = __version__
- FigureCanvas = FigureCanvasQT
- FigureManager = FigureManagerQT
- mainloop = FigureManagerQT.start_main_loop
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_qt5.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_qt5.py
deleted file mode 100644
index d94062b723..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_qt5.py
+++ /dev/null
@@ -1,28 +0,0 @@
-from .. import backends
-
-backends._QT_FORCE_QT5_BINDING = True
-
-
-from .backend_qt import ( # noqa
- SPECIAL_KEYS,
- # Public API
- cursord, _create_qApp, _BackendQT, TimerQT, MainWindow, FigureCanvasQT,
- FigureManagerQT, ToolbarQt, NavigationToolbar2QT, SubplotToolQt,
- SaveFigureQt, ConfigureSubplotsQt, RubberbandQt,
- HelpQt, ToolCopyToClipboardQT,
- # internal re-exports
- FigureCanvasBase, FigureManagerBase, MouseButton, NavigationToolbar2,
- TimerBase, ToolContainerBase, figureoptions, Gcf
-)
-from . import backend_qt as _backend_qt # noqa
-
-
-@_BackendQT.export
-class _BackendQT5(_BackendQT):
- pass
-
-
-def __getattr__(name):
- if name == 'qApp':
- return _backend_qt.qApp
- raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_qt5agg.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_qt5agg.py
deleted file mode 100644
index 8a92fd5135..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_qt5agg.py
+++ /dev/null
@@ -1,14 +0,0 @@
-"""
-Render to qt from agg
-"""
-from .. import backends
-
-backends._QT_FORCE_QT5_BINDING = True
-from .backend_qtagg import ( # noqa: F401, E402 # pylint: disable=W0611
- _BackendQTAgg, FigureCanvasQTAgg, FigureManagerQT, NavigationToolbar2QT,
- FigureCanvasAgg, FigureCanvasQT)
-
-
-@_BackendQTAgg.export
-class _BackendQT5Agg(_BackendQTAgg):
- pass
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_qt5cairo.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_qt5cairo.py
deleted file mode 100644
index a4263f5971..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_qt5cairo.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from .. import backends
-
-backends._QT_FORCE_QT5_BINDING = True
-from .backend_qtcairo import ( # noqa: F401, E402 # pylint: disable=W0611
- _BackendQTCairo, FigureCanvasQTCairo, FigureCanvasCairo, FigureCanvasQT
-)
-
-
-@_BackendQTCairo.export
-class _BackendQT5Cairo(_BackendQTCairo):
- pass
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_qtagg.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_qtagg.py
deleted file mode 100644
index 256e50a3d1..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_qtagg.py
+++ /dev/null
@@ -1,86 +0,0 @@
-"""
-Render to qt from agg.
-"""
-
-import ctypes
-
-from matplotlib.transforms import Bbox
-
-from .qt_compat import QT_API, QtCore, QtGui
-from .backend_agg import FigureCanvasAgg
-from .backend_qt import _BackendQT, FigureCanvasQT
-from .backend_qt import ( # noqa: F401 # pylint: disable=W0611
- FigureManagerQT, NavigationToolbar2QT)
-
-
-class FigureCanvasQTAgg(FigureCanvasAgg, FigureCanvasQT):
-
- def paintEvent(self, event):
- """
- Copy the image from the Agg canvas to the qt.drawable.
-
- In Qt, all drawing should be done inside of here when a widget is
- shown onscreen.
- """
- self._draw_idle() # Only does something if a draw is pending.
-
- # If the canvas does not have a renderer, then give up and wait for
- # FigureCanvasAgg.draw(self) to be called.
- if not hasattr(self, 'renderer'):
- return
-
- painter = QtGui.QPainter(self)
- try:
- # See documentation of QRect: bottom() and right() are off
- # by 1, so use left() + width() and top() + height().
- rect = event.rect()
- # scale rect dimensions using the screen dpi ratio to get
- # correct values for the Figure coordinates (rather than
- # QT5's coords)
- width = rect.width() * self.device_pixel_ratio
- height = rect.height() * self.device_pixel_ratio
- left, top = self.mouseEventCoords(rect.topLeft())
- # shift the "top" by the height of the image to get the
- # correct corner for our coordinate system
- bottom = top - height
- # same with the right side of the image
- right = left + width
- # create a buffer using the image bounding box
- bbox = Bbox([[left, bottom], [right, top]])
- buf = memoryview(self.copy_from_bbox(bbox))
-
- if QT_API == "PyQt6":
- from PyQt6 import sip
- ptr = int(sip.voidptr(buf))
- else:
- ptr = buf
-
- painter.eraseRect(rect) # clear the widget canvas
- qimage = QtGui.QImage(ptr, buf.shape[1], buf.shape[0],
- QtGui.QImage.Format.Format_RGBA8888)
- qimage.setDevicePixelRatio(self.device_pixel_ratio)
- # set origin using original QT coordinates
- origin = QtCore.QPoint(rect.left(), rect.top())
- painter.drawImage(origin, qimage)
- # Adjust the buf reference count to work around a memory
- # leak bug in QImage under PySide.
- if QT_API == "PySide2" and QtCore.__version_info__ < (5, 12):
- ctypes.c_long.from_address(id(buf)).value = 1
-
- self._draw_rect_callback(painter)
- finally:
- painter.end()
-
- def print_figure(self, *args, **kwargs):
- super().print_figure(*args, **kwargs)
- # In some cases, Qt will itself trigger a paint event after closing the file
- # save dialog. When that happens, we need to be sure that the internal canvas is
- # re-drawn. However, if the user is using an automatically-chosen Qt backend but
- # saving with a different backend (such as pgf), we do not want to trigger a
- # full draw in Qt, so just set the flag for next time.
- self._draw_pending = True
-
-
-@_BackendQT.export
-class _BackendQTAgg(_BackendQT):
- FigureCanvas = FigureCanvasQTAgg
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_qtcairo.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_qtcairo.py
deleted file mode 100644
index 72eb2dc70b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_qtcairo.py
+++ /dev/null
@@ -1,46 +0,0 @@
-import ctypes
-
-from .backend_cairo import cairo, FigureCanvasCairo
-from .backend_qt import _BackendQT, FigureCanvasQT
-from .qt_compat import QT_API, QtCore, QtGui
-
-
-class FigureCanvasQTCairo(FigureCanvasCairo, FigureCanvasQT):
- def draw(self):
- if hasattr(self._renderer.gc, "ctx"):
- self._renderer.dpi = self.figure.dpi
- self.figure.draw(self._renderer)
- super().draw()
-
- def paintEvent(self, event):
- width = int(self.device_pixel_ratio * self.width())
- height = int(self.device_pixel_ratio * self.height())
- if (width, height) != self._renderer.get_canvas_width_height():
- surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
- self._renderer.set_context(cairo.Context(surface))
- self._renderer.dpi = self.figure.dpi
- self.figure.draw(self._renderer)
- buf = self._renderer.gc.ctx.get_target().get_data()
- if QT_API == "PyQt6":
- from PyQt6 import sip
- ptr = int(sip.voidptr(buf))
- else:
- ptr = buf
- qimage = QtGui.QImage(
- ptr, width, height,
- QtGui.QImage.Format.Format_ARGB32_Premultiplied)
- # Adjust the buf reference count to work around a memory leak bug in
- # QImage under PySide.
- if QT_API == "PySide2" and QtCore.__version_info__ < (5, 12):
- ctypes.c_long.from_address(id(buf)).value = 1
- qimage.setDevicePixelRatio(self.device_pixel_ratio)
- painter = QtGui.QPainter(self)
- painter.eraseRect(event.rect())
- painter.drawImage(0, 0, qimage)
- self._draw_rect_callback(painter)
- painter.end()
-
-
-@_BackendQT.export
-class _BackendQTCairo(_BackendQT):
- FigureCanvas = FigureCanvasQTCairo
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_svg.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_svg.py
deleted file mode 100644
index f62152ed1f..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_svg.py
+++ /dev/null
@@ -1,1368 +0,0 @@
-import base64
-import codecs
-import datetime
-import gzip
-import hashlib
-from io import BytesIO
-import itertools
-import logging
-import os
-import re
-import uuid
-
-import numpy as np
-from PIL import Image
-
-import matplotlib as mpl
-from matplotlib import cbook, font_manager as fm
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase, RendererBase)
-from matplotlib.backends.backend_mixed import MixedModeRenderer
-from matplotlib.colors import rgb2hex
-from matplotlib.dates import UTC
-from matplotlib.path import Path
-from matplotlib import _path
-from matplotlib.transforms import Affine2D, Affine2DBase
-
-
-_log = logging.getLogger(__name__)
-
-
-# ----------------------------------------------------------------------
-# SimpleXMLWriter class
-#
-# Based on an original by Fredrik Lundh, but modified here to:
-# 1. Support modern Python idioms
-# 2. Remove encoding support (it's handled by the file writer instead)
-# 3. Support proper indentation
-# 4. Minify things a little bit
-
-# --------------------------------------------------------------------
-# The SimpleXMLWriter module is
-#
-# Copyright (c) 2001-2004 by Fredrik Lundh
-#
-# By obtaining, using, and/or copying this software and/or its
-# associated documentation, you agree that you have read, understood,
-# and will comply with the following terms and conditions:
-#
-# Permission to use, copy, modify, and distribute this software and
-# its associated documentation for any purpose and without fee is
-# hereby granted, provided that the above copyright notice appears in
-# all copies, and that both that copyright notice and this permission
-# notice appear in supporting documentation, and that the name of
-# Secret Labs AB or the author not be used in advertising or publicity
-# pertaining to distribution of the software without specific, written
-# prior permission.
-#
-# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
-# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
-# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
-# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
-# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
-# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
-# OF THIS SOFTWARE.
-# --------------------------------------------------------------------
-
-
-def _escape_cdata(s):
- s = s.replace("&", "&amp;")
- s = s.replace("<", "&lt;")
- s = s.replace(">", "&gt;")
- return s
-
-
-_escape_xml_comment = re.compile(r'-(?=-)')
-
-
-def _escape_comment(s):
- s = _escape_cdata(s)
- return _escape_xml_comment.sub('- ', s)
-
-
-def _escape_attrib(s):
- s = s.replace("&", "&amp;")
- s = s.replace("'", "&apos;")
- s = s.replace('"', "&quot;")
- s = s.replace("<", "&lt;")
- s = s.replace(">", "&gt;")
- return s
-
-
-def _quote_escape_attrib(s):
- return ('"' + _escape_cdata(s) + '"' if '"' not in s else
- "'" + _escape_cdata(s) + "'" if "'" not in s else
- '"' + _escape_attrib(s) + '"')
-
-
-def _short_float_fmt(x):
- """
- Create a short string representation of a float, which is %f
- formatting with trailing zeros and the decimal point removed.
- """
- return f'{x:f}'.rstrip('0').rstrip('.')
-
-
-class XMLWriter:
- """
- Parameters
- ----------
- file : writable text file-like object
- """
-
- def __init__(self, file):
- self.__write = file.write
- if hasattr(file, "flush"):
- self.flush = file.flush
- self.__open = 0 # true if start tag is open
- self.__tags = []
- self.__data = []
- self.__indentation = " " * 64
-
- def __flush(self, indent=True):
- # flush internal buffers
- if self.__open:
- if indent:
- self.__write(">\n")
- else:
- self.__write(">")
- self.__open = 0
- if self.__data:
- data = ''.join(self.__data)
- self.__write(_escape_cdata(data))
- self.__data = []
-
- def start(self, tag, attrib={}, **extra):
- """
- Open a new element. Attributes can be given as keyword
- arguments, or as a string/string dictionary. The method returns
- an opaque identifier that can be passed to the :meth:`close`
- method, to close all open elements up to and including this one.
-
- Parameters
- ----------
- tag
- Element tag.
- attrib
- Attribute dictionary. Alternatively, attributes can be given as
- keyword arguments.
-
- Returns
- -------
- An element identifier.
- """
- self.__flush()
- tag = _escape_cdata(tag)
- self.__data = []
- self.__tags.append(tag)
- self.__write(self.__indentation[:len(self.__tags) - 1])
- self.__write(f"<{tag}")
- for k, v in {**attrib, **extra}.items():
- if v:
- k = _escape_cdata(k)
- v = _quote_escape_attrib(v)
- self.__write(f' {k}={v}')
- self.__open = 1
- return len(self.__tags) - 1
-
- def comment(self, comment):
- """
- Add a comment to the output stream.
-
- Parameters
- ----------
- comment : str
- Comment text.
- """
- self.__flush()
- self.__write(self.__indentation[:len(self.__tags)])
- self.__write(f"<!-- {_escape_comment(comment)} -->\n")
-
- def data(self, text):
- """
- Add character data to the output stream.
-
- Parameters
- ----------
- text : str
- Character data.
- """
- self.__data.append(text)
-
- def end(self, tag=None, indent=True):
- """
- Close the current element (opened by the most recent call to
- :meth:`start`).
-
- Parameters
- ----------
- tag
- Element tag. If given, the tag must match the start tag. If
- omitted, the current element is closed.
- indent : bool, default: True
- """
- if tag:
- assert self.__tags, f"unbalanced end({tag})"
- assert _escape_cdata(tag) == self.__tags[-1], \
- f"expected end({self.__tags[-1]}), got {tag}"
- else:
- assert self.__tags, "unbalanced end()"
- tag = self.__tags.pop()
- if self.__data:
- self.__flush(indent)
- elif self.__open:
- self.__open = 0
- self.__write("/>\n")
- return
- if indent:
- self.__write(self.__indentation[:len(self.__tags)])
- self.__write(f"</{tag}>\n")
-
- def close(self, id):
- """
- Close open elements, up to (and including) the element identified
- by the given identifier.
-
- Parameters
- ----------
- id
- Element identifier, as returned by the :meth:`start` method.
- """
- while len(self.__tags) > id:
- self.end()
-
- def element(self, tag, text=None, attrib={}, **extra):
- """
- Add an entire element. This is the same as calling :meth:`start`,
- :meth:`data`, and :meth:`end` in sequence. The *text* argument can be
- omitted.
- """
- self.start(tag, attrib, **extra)
- if text:
- self.data(text)
- self.end(indent=False)
-
- def flush(self):
- """Flush the output stream."""
- pass # replaced by the constructor
-
-
-def _generate_transform(transform_list):
- parts = []
- for type, value in transform_list:
- if (type == 'scale' and (value == (1,) or value == (1, 1))
- or type == 'translate' and value == (0, 0)
- or type == 'rotate' and value == (0,)):
- continue
- if type == 'matrix' and isinstance(value, Affine2DBase):
- value = value.to_values()
- parts.append('{}({})'.format(
- type, ' '.join(_short_float_fmt(x) for x in value)))
- return ' '.join(parts)
-
-
-def _generate_css(attrib):
- return "; ".join(f"{k}: {v}" for k, v in attrib.items())
-
-
-_capstyle_d = {'projecting': 'square', 'butt': 'butt', 'round': 'round'}
-
-
-def _check_is_str(info, key):
- if not isinstance(info, str):
- raise TypeError(f'Invalid type for {key} metadata. Expected str, not '
- f'{type(info)}.')
-
-
-def _check_is_iterable_of_str(infos, key):
- if np.iterable(infos):
- for info in infos:
- if not isinstance(info, str):
- raise TypeError(f'Invalid type for {key} metadata. Expected '
- f'iterable of str, not {type(info)}.')
- else:
- raise TypeError(f'Invalid type for {key} metadata. Expected str or '
- f'iterable of str, not {type(infos)}.')
-
-
-class RendererSVG(RendererBase):
- def __init__(self, width, height, svgwriter, basename=None, image_dpi=72,
- *, metadata=None):
- self.width = width
- self.height = height
- self.writer = XMLWriter(svgwriter)
- self.image_dpi = image_dpi # actual dpi at which we rasterize stuff
-
- if basename is None:
- basename = getattr(svgwriter, "name", "")
- if not isinstance(basename, str):
- basename = ""
- self.basename = basename
-
- self._groupd = {}
- self._image_counter = itertools.count()
- self._clipd = {}
- self._markers = {}
- self._path_collection_id = 0
- self._hatchd = {}
- self._has_gouraud = False
- self._n_gradients = 0
-
- super().__init__()
- self._glyph_map = dict()
- str_height = _short_float_fmt(height)
- str_width = _short_float_fmt(width)
- svgwriter.write(svgProlog)
- self._start_id = self.writer.start(
- 'svg',
- width=f'{str_width}pt',
- height=f'{str_height}pt',
- viewBox=f'0 0 {str_width} {str_height}',
- xmlns="http://www.w3.org/2000/svg",
- version="1.1",
- attrib={'xmlns:xlink': "http://www.w3.org/1999/xlink"})
- self._write_metadata(metadata)
- self._write_default_style()
-
- def finalize(self):
- self._write_clips()
- self._write_hatches()
- self.writer.close(self._start_id)
- self.writer.flush()
-
- def _write_metadata(self, metadata):
- # Add metadata following the Dublin Core Metadata Initiative, and the
- # Creative Commons Rights Expression Language. This is mainly for
- # compatibility with Inkscape.
- if metadata is None:
- metadata = {}
- metadata = {
- 'Format': 'image/svg+xml',
- 'Type': 'http://purl.org/dc/dcmitype/StillImage',
- 'Creator':
- f'Matplotlib v{mpl.__version__}, https://matplotlib.org/',
- **metadata
- }
- writer = self.writer
-
- if 'Title' in metadata:
- title = metadata['Title']
- _check_is_str(title, 'Title')
- writer.element('title', text=title)
-
- # Special handling.
- date = metadata.get('Date', None)
- if date is not None:
- if isinstance(date, str):
- dates = [date]
- elif isinstance(date, (datetime.datetime, datetime.date)):
- dates = [date.isoformat()]
- elif np.iterable(date):
- dates = []
- for d in date:
- if isinstance(d, str):
- dates.append(d)
- elif isinstance(d, (datetime.datetime, datetime.date)):
- dates.append(d.isoformat())
- else:
- raise TypeError(
- f'Invalid type for Date metadata. '
- f'Expected iterable of str, date, or datetime, '
- f'not {type(d)}.')
- else:
- raise TypeError(f'Invalid type for Date metadata. '
- f'Expected str, date, datetime, or iterable '
- f'of the same, not {type(date)}.')
- metadata['Date'] = '/'.join(dates)
- elif 'Date' not in metadata:
- # Do not add `Date` if the user explicitly set `Date` to `None`
- # Get source date from SOURCE_DATE_EPOCH, if set.
- # See https://reproducible-builds.org/specs/source-date-epoch/
- date = os.getenv("SOURCE_DATE_EPOCH")
- if date:
- date = datetime.datetime.fromtimestamp(int(date), datetime.timezone.utc)
- metadata['Date'] = date.replace(tzinfo=UTC).isoformat()
- else:
- metadata['Date'] = datetime.datetime.today().isoformat()
-
- mid = None
- def ensure_metadata(mid):
- if mid is not None:
- return mid
- mid = writer.start('metadata')
- writer.start('rdf:RDF', attrib={
- 'xmlns:dc': "http://purl.org/dc/elements/1.1/",
- 'xmlns:cc': "http://creativecommons.org/ns#",
- 'xmlns:rdf': "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
- })
- writer.start('cc:Work')
- return mid
-
- uri = metadata.pop('Type', None)
- if uri is not None:
- mid = ensure_metadata(mid)
- writer.element('dc:type', attrib={'rdf:resource': uri})
-
- # Single value only.
- for key in ['Title', 'Coverage', 'Date', 'Description', 'Format',
- 'Identifier', 'Language', 'Relation', 'Source']:
- info = metadata.pop(key, None)
- if info is not None:
- mid = ensure_metadata(mid)
- _check_is_str(info, key)
- writer.element(f'dc:{key.lower()}', text=info)
-
- # Multiple Agent values.
- for key in ['Creator', 'Contributor', 'Publisher', 'Rights']:
- agents = metadata.pop(key, None)
- if agents is None:
- continue
-
- if isinstance(agents, str):
- agents = [agents]
-
- _check_is_iterable_of_str(agents, key)
- # Now we know that we have an iterable of str
- mid = ensure_metadata(mid)
- writer.start(f'dc:{key.lower()}')
- for agent in agents:
- writer.start('cc:Agent')
- writer.element('dc:title', text=agent)
- writer.end('cc:Agent')
- writer.end(f'dc:{key.lower()}')
-
- # Multiple values.
- keywords = metadata.pop('Keywords', None)
- if keywords is not None:
- if isinstance(keywords, str):
- keywords = [keywords]
- _check_is_iterable_of_str(keywords, 'Keywords')
- # Now we know that we have an iterable of str
- mid = ensure_metadata(mid)
- writer.start('dc:subject')
- writer.start('rdf:Bag')
- for keyword in keywords:
- writer.element('rdf:li', text=keyword)
- writer.end('rdf:Bag')
- writer.end('dc:subject')
-
- if mid is not None:
- writer.close(mid)
-
- if metadata:
- raise ValueError('Unknown metadata key(s) passed to SVG writer: ' +
- ','.join(metadata))
-
- def _write_default_style(self):
- writer = self.writer
- default_style = _generate_css({
- 'stroke-linejoin': 'round',
- 'stroke-linecap': 'butt'})
- writer.start('defs')
- writer.element('style', type='text/css', text='*{%s}' % default_style)
- writer.end('defs')
-
- def _make_id(self, type, content):
- salt = mpl.rcParams['svg.hashsalt']
- if salt is None:
- salt = str(uuid.uuid4())
- m = hashlib.sha256()
- m.update(salt.encode('utf8'))
- m.update(str(content).encode('utf8'))
- return f'{type}{m.hexdigest()[:10]}'
-
- def _make_flip_transform(self, transform):
- return transform + Affine2D().scale(1, -1).translate(0, self.height)
-
- def _get_hatch(self, gc, rgbFace):
- """
- Create a new hatch pattern
- """
- if rgbFace is not None:
- rgbFace = tuple(rgbFace)
- edge = gc.get_hatch_color()
- if edge is not None:
- edge = tuple(edge)
- dictkey = (gc.get_hatch(), rgbFace, edge)
- oid = self._hatchd.get(dictkey)
- if oid is None:
- oid = self._make_id('h', dictkey)
- self._hatchd[dictkey] = ((gc.get_hatch_path(), rgbFace, edge), oid)
- else:
- _, oid = oid
- return oid
-
- def _write_hatches(self):
- if not len(self._hatchd):
- return
- HATCH_SIZE = 72
- writer = self.writer
- writer.start('defs')
- for (path, face, stroke), oid in self._hatchd.values():
- writer.start(
- 'pattern',
- id=oid,
- patternUnits="userSpaceOnUse",
- x="0", y="0", width=str(HATCH_SIZE),
- height=str(HATCH_SIZE))
- path_data = self._convert_path(
- path,
- Affine2D()
- .scale(HATCH_SIZE).scale(1.0, -1.0).translate(0, HATCH_SIZE),
- simplify=False)
- if face is None:
- fill = 'none'
- else:
- fill = rgb2hex(face)
- writer.element(
- 'rect',
- x="0", y="0", width=str(HATCH_SIZE+1),
- height=str(HATCH_SIZE+1),
- fill=fill)
- hatch_style = {
- 'fill': rgb2hex(stroke),
- 'stroke': rgb2hex(stroke),
- 'stroke-width': str(mpl.rcParams['hatch.linewidth']),
- 'stroke-linecap': 'butt',
- 'stroke-linejoin': 'miter'
- }
- if stroke[3] < 1:
- hatch_style['stroke-opacity'] = str(stroke[3])
- writer.element(
- 'path',
- d=path_data,
- style=_generate_css(hatch_style)
- )
- writer.end('pattern')
- writer.end('defs')
-
- def _get_style_dict(self, gc, rgbFace):
- """Generate a style string from the GraphicsContext and rgbFace."""
- attrib = {}
-
- forced_alpha = gc.get_forced_alpha()
-
- if gc.get_hatch() is not None:
- attrib['fill'] = f"url(#{self._get_hatch(gc, rgbFace)})"
- if (rgbFace is not None and len(rgbFace) == 4 and rgbFace[3] != 1.0
- and not forced_alpha):
- attrib['fill-opacity'] = _short_float_fmt(rgbFace[3])
- else:
- if rgbFace is None:
- attrib['fill'] = 'none'
- else:
- if tuple(rgbFace[:3]) != (0, 0, 0):
- attrib['fill'] = rgb2hex(rgbFace)
- if (len(rgbFace) == 4 and rgbFace[3] != 1.0
- and not forced_alpha):
- attrib['fill-opacity'] = _short_float_fmt(rgbFace[3])
-
- if forced_alpha and gc.get_alpha() != 1.0:
- attrib['opacity'] = _short_float_fmt(gc.get_alpha())
-
- offset, seq = gc.get_dashes()
- if seq is not None:
- attrib['stroke-dasharray'] = ','.join(
- _short_float_fmt(val) for val in seq)
- attrib['stroke-dashoffset'] = _short_float_fmt(float(offset))
-
- linewidth = gc.get_linewidth()
- if linewidth:
- rgb = gc.get_rgb()
- attrib['stroke'] = rgb2hex(rgb)
- if not forced_alpha and rgb[3] != 1.0:
- attrib['stroke-opacity'] = _short_float_fmt(rgb[3])
- if linewidth != 1.0:
- attrib['stroke-width'] = _short_float_fmt(linewidth)
- if gc.get_joinstyle() != 'round':
- attrib['stroke-linejoin'] = gc.get_joinstyle()
- if gc.get_capstyle() != 'butt':
- attrib['stroke-linecap'] = _capstyle_d[gc.get_capstyle()]
-
- return attrib
-
- def _get_style(self, gc, rgbFace):
- return _generate_css(self._get_style_dict(gc, rgbFace))
-
- def _get_clip_attrs(self, gc):
- cliprect = gc.get_clip_rectangle()
- clippath, clippath_trans = gc.get_clip_path()
- if clippath is not None:
- clippath_trans = self._make_flip_transform(clippath_trans)
- dictkey = (id(clippath), str(clippath_trans))
- elif cliprect is not None:
- x, y, w, h = cliprect.bounds
- y = self.height-(y+h)
- dictkey = (x, y, w, h)
- else:
- return {}
- clip = self._clipd.get(dictkey)
- if clip is None:
- oid = self._make_id('p', dictkey)
- if clippath is not None:
- self._clipd[dictkey] = ((clippath, clippath_trans), oid)
- else:
- self._clipd[dictkey] = (dictkey, oid)
- else:
- clip, oid = clip
- return {'clip-path': f'url(#{oid})'}
-
- def _write_clips(self):
- if not len(self._clipd):
- return
- writer = self.writer
- writer.start('defs')
- for clip, oid in self._clipd.values():
- writer.start('clipPath', id=oid)
- if len(clip) == 2:
- clippath, clippath_trans = clip
- path_data = self._convert_path(
- clippath, clippath_trans, simplify=False)
- writer.element('path', d=path_data)
- else:
- x, y, w, h = clip
- writer.element(
- 'rect',
- x=_short_float_fmt(x),
- y=_short_float_fmt(y),
- width=_short_float_fmt(w),
- height=_short_float_fmt(h))
- writer.end('clipPath')
- writer.end('defs')
-
- def open_group(self, s, gid=None):
- # docstring inherited
- if gid:
- self.writer.start('g', id=gid)
- else:
- self._groupd[s] = self._groupd.get(s, 0) + 1
- self.writer.start('g', id=f"{s}_{self._groupd[s]:d}")
-
- def close_group(self, s):
- # docstring inherited
- self.writer.end('g')
-
- def option_image_nocomposite(self):
- # docstring inherited
- return not mpl.rcParams['image.composite_image']
-
- def _convert_path(self, path, transform=None, clip=None, simplify=None,
- sketch=None):
- if clip:
- clip = (0.0, 0.0, self.width, self.height)
- else:
- clip = None
- return _path.convert_to_string(
- path, transform, clip, simplify, sketch, 6,
- [b'M', b'L', b'Q', b'C', b'z'], False).decode('ascii')
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- # docstring inherited
- trans_and_flip = self._make_flip_transform(transform)
- clip = (rgbFace is None and gc.get_hatch_path() is None)
- simplify = path.should_simplify and clip
- path_data = self._convert_path(
- path, trans_and_flip, clip=clip, simplify=simplify,
- sketch=gc.get_sketch_params())
-
- if gc.get_url() is not None:
- self.writer.start('a', {'xlink:href': gc.get_url()})
- self.writer.element('path', d=path_data, **self._get_clip_attrs(gc),
- style=self._get_style(gc, rgbFace))
- if gc.get_url() is not None:
- self.writer.end('a')
-
- def draw_markers(
- self, gc, marker_path, marker_trans, path, trans, rgbFace=None):
- # docstring inherited
-
- if not len(path.vertices):
- return
-
- writer = self.writer
- path_data = self._convert_path(
- marker_path,
- marker_trans + Affine2D().scale(1.0, -1.0),
- simplify=False)
- style = self._get_style_dict(gc, rgbFace)
- dictkey = (path_data, _generate_css(style))
- oid = self._markers.get(dictkey)
- style = _generate_css({k: v for k, v in style.items()
- if k.startswith('stroke')})
-
- if oid is None:
- oid = self._make_id('m', dictkey)
- writer.start('defs')
- writer.element('path', id=oid, d=path_data, style=style)
- writer.end('defs')
- self._markers[dictkey] = oid
-
- writer.start('g', **self._get_clip_attrs(gc))
- trans_and_flip = self._make_flip_transform(trans)
- attrib = {'xlink:href': f'#{oid}'}
- clip = (0, 0, self.width*72, self.height*72)
- for vertices, code in path.iter_segments(
- trans_and_flip, clip=clip, simplify=False):
- if len(vertices):
- x, y = vertices[-2:]
- attrib['x'] = _short_float_fmt(x)
- attrib['y'] = _short_float_fmt(y)
- attrib['style'] = self._get_style(gc, rgbFace)
- writer.element('use', attrib=attrib)
- writer.end('g')
-
- def draw_path_collection(self, gc, master_transform, paths, all_transforms,
- offsets, offset_trans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position):
- # Is the optimization worth it? Rough calculation:
- # cost of emitting a path in-line is
- # (len_path + 5) * uses_per_path
- # cost of definition+use is
- # (len_path + 3) + 9 * uses_per_path
- len_path = len(paths[0].vertices) if len(paths) > 0 else 0
- uses_per_path = self._iter_collection_uses_per_path(
- paths, all_transforms, offsets, facecolors, edgecolors)
- should_do_optimization = \
- len_path + 9 * uses_per_path + 3 < (len_path + 5) * uses_per_path
- if not should_do_optimization:
- return super().draw_path_collection(
- gc, master_transform, paths, all_transforms,
- offsets, offset_trans, facecolors, edgecolors,
- linewidths, linestyles, antialiaseds, urls,
- offset_position)
-
- writer = self.writer
- path_codes = []
- writer.start('defs')
- for i, (path, transform) in enumerate(self._iter_collection_raw_paths(
- master_transform, paths, all_transforms)):
- transform = Affine2D(transform.get_matrix()).scale(1.0, -1.0)
- d = self._convert_path(path, transform, simplify=False)
- oid = 'C{:x}_{:x}_{}'.format(
- self._path_collection_id, i, self._make_id('', d))
- writer.element('path', id=oid, d=d)
- path_codes.append(oid)
- writer.end('defs')
-
- for xo, yo, path_id, gc0, rgbFace in self._iter_collection(
- gc, path_codes, offsets, offset_trans,
- facecolors, edgecolors, linewidths, linestyles,
- antialiaseds, urls, offset_position):
- url = gc0.get_url()
- if url is not None:
- writer.start('a', attrib={'xlink:href': url})
- clip_attrs = self._get_clip_attrs(gc0)
- if clip_attrs:
- writer.start('g', **clip_attrs)
- attrib = {
- 'xlink:href': f'#{path_id}',
- 'x': _short_float_fmt(xo),
- 'y': _short_float_fmt(self.height - yo),
- 'style': self._get_style(gc0, rgbFace)
- }
- writer.element('use', attrib=attrib)
- if clip_attrs:
- writer.end('g')
- if url is not None:
- writer.end('a')
-
- self._path_collection_id += 1
-
- def draw_gouraud_triangle(self, gc, points, colors, trans):
- # docstring inherited
- self._draw_gouraud_triangle(gc, points, colors, trans)
-
- def _draw_gouraud_triangle(self, gc, points, colors, trans):
- # This uses a method described here:
- #
- # http://www.svgopen.org/2005/papers/Converting3DFaceToSVG/index.html
- #
- # that uses three overlapping linear gradients to simulate a
- # Gouraud triangle. Each gradient goes from fully opaque in
- # one corner to fully transparent along the opposite edge.
- # The line between the stop points is perpendicular to the
- # opposite edge. Underlying these three gradients is a solid
- # triangle whose color is the average of all three points.
-
- writer = self.writer
- if not self._has_gouraud:
- self._has_gouraud = True
- writer.start(
- 'filter',
- id='colorAdd')
- writer.element(
- 'feComposite',
- attrib={'in': 'SourceGraphic'},
- in2='BackgroundImage',
- operator='arithmetic',
- k2="1", k3="1")
- writer.end('filter')
- # feColorMatrix filter to correct opacity
- writer.start(
- 'filter',
- id='colorMat')
- writer.element(
- 'feColorMatrix',
- attrib={'type': 'matrix'},
- values='1 0 0 0 0 \n0 1 0 0 0 \n0 0 1 0 0' +
- ' \n1 1 1 1 0 \n0 0 0 0 1 ')
- writer.end('filter')
-
- avg_color = np.average(colors, axis=0)
- if avg_color[-1] == 0:
- # Skip fully-transparent triangles
- return
-
- trans_and_flip = self._make_flip_transform(trans)
- tpoints = trans_and_flip.transform(points)
-
- writer.start('defs')
- for i in range(3):
- x1, y1 = tpoints[i]
- x2, y2 = tpoints[(i + 1) % 3]
- x3, y3 = tpoints[(i + 2) % 3]
- rgba_color = colors[i]
-
- if x2 == x3:
- xb = x2
- yb = y1
- elif y2 == y3:
- xb = x1
- yb = y2
- else:
- m1 = (y2 - y3) / (x2 - x3)
- b1 = y2 - (m1 * x2)
- m2 = -(1.0 / m1)
- b2 = y1 - (m2 * x1)
- xb = (-b1 + b2) / (m1 - m2)
- yb = m2 * xb + b2
-
- writer.start(
- 'linearGradient',
- id=f"GR{self._n_gradients:x}_{i:d}",
- gradientUnits="userSpaceOnUse",
- x1=_short_float_fmt(x1), y1=_short_float_fmt(y1),
- x2=_short_float_fmt(xb), y2=_short_float_fmt(yb))
- writer.element(
- 'stop',
- offset='1',
- style=_generate_css({
- 'stop-color': rgb2hex(avg_color),
- 'stop-opacity': _short_float_fmt(rgba_color[-1])}))
- writer.element(
- 'stop',
- offset='0',
- style=_generate_css({'stop-color': rgb2hex(rgba_color),
- 'stop-opacity': "0"}))
-
- writer.end('linearGradient')
-
- writer.end('defs')
-
- # triangle formation using "path"
- dpath = "M " + _short_float_fmt(x1)+',' + _short_float_fmt(y1)
- dpath += " L " + _short_float_fmt(x2) + ',' + _short_float_fmt(y2)
- dpath += " " + _short_float_fmt(x3) + ',' + _short_float_fmt(y3) + " Z"
-
- writer.element(
- 'path',
- attrib={'d': dpath,
- 'fill': rgb2hex(avg_color),
- 'fill-opacity': '1',
- 'shape-rendering': "crispEdges"})
-
- writer.start(
- 'g',
- attrib={'stroke': "none",
- 'stroke-width': "0",
- 'shape-rendering': "crispEdges",
- 'filter': "url(#colorMat)"})
-
- writer.element(
- 'path',
- attrib={'d': dpath,
- 'fill': f'url(#GR{self._n_gradients:x}_0)',
- 'shape-rendering': "crispEdges"})
-
- writer.element(
- 'path',
- attrib={'d': dpath,
- 'fill': f'url(#GR{self._n_gradients:x}_1)',
- 'filter': 'url(#colorAdd)',
- 'shape-rendering': "crispEdges"})
-
- writer.element(
- 'path',
- attrib={'d': dpath,
- 'fill': f'url(#GR{self._n_gradients:x}_2)',
- 'filter': 'url(#colorAdd)',
- 'shape-rendering': "crispEdges"})
-
- writer.end('g')
-
- self._n_gradients += 1
-
- def draw_gouraud_triangles(self, gc, triangles_array, colors_array,
- transform):
- self.writer.start('g', **self._get_clip_attrs(gc))
- transform = transform.frozen()
- for tri, col in zip(triangles_array, colors_array):
- self._draw_gouraud_triangle(gc, tri, col, transform)
- self.writer.end('g')
-
- def option_scale_image(self):
- # docstring inherited
- return True
-
- def get_image_magnification(self):
- return self.image_dpi / 72.0
-
- def draw_image(self, gc, x, y, im, transform=None):
- # docstring inherited
-
- h, w = im.shape[:2]
-
- if w == 0 or h == 0:
- return
-
- clip_attrs = self._get_clip_attrs(gc)
- if clip_attrs:
- # Can't apply clip-path directly to the image because the image has
- # a transformation, which would also be applied to the clip-path.
- self.writer.start('g', **clip_attrs)
-
- url = gc.get_url()
- if url is not None:
- self.writer.start('a', attrib={'xlink:href': url})
-
- attrib = {}
- oid = gc.get_gid()
- if mpl.rcParams['svg.image_inline']:
- buf = BytesIO()
- Image.fromarray(im).save(buf, format="png")
- oid = oid or self._make_id('image', buf.getvalue())
- attrib['xlink:href'] = (
- "data:image/png;base64,\n" +
- base64.b64encode(buf.getvalue()).decode('ascii'))
- else:
- if self.basename is None:
- raise ValueError("Cannot save image data to filesystem when "
- "writing SVG to an in-memory buffer")
- filename = f'{self.basename}.image{next(self._image_counter)}.png'
- _log.info('Writing image file for inclusion: %s', filename)
- Image.fromarray(im).save(filename)
- oid = oid or 'Im_' + self._make_id('image', filename)
- attrib['xlink:href'] = filename
- attrib['id'] = oid
-
- if transform is None:
- w = 72.0 * w / self.image_dpi
- h = 72.0 * h / self.image_dpi
-
- self.writer.element(
- 'image',
- transform=_generate_transform([
- ('scale', (1, -1)), ('translate', (0, -h))]),
- x=_short_float_fmt(x),
- y=_short_float_fmt(-(self.height - y - h)),
- width=_short_float_fmt(w), height=_short_float_fmt(h),
- attrib=attrib)
- else:
- alpha = gc.get_alpha()
- if alpha != 1.0:
- attrib['opacity'] = _short_float_fmt(alpha)
-
- flipped = (
- Affine2D().scale(1.0 / w, 1.0 / h) +
- transform +
- Affine2D()
- .translate(x, y)
- .scale(1.0, -1.0)
- .translate(0.0, self.height))
-
- attrib['transform'] = _generate_transform(
- [('matrix', flipped.frozen())])
- attrib['style'] = (
- 'image-rendering:crisp-edges;'
- 'image-rendering:pixelated')
- self.writer.element(
- 'image',
- width=_short_float_fmt(w), height=_short_float_fmt(h),
- attrib=attrib)
-
- if url is not None:
- self.writer.end('a')
- if clip_attrs:
- self.writer.end('g')
-
- def _update_glyph_map_defs(self, glyph_map_new):
- """
- Emit definitions for not-yet-defined glyphs, and record them as having
- been defined.
- """
- writer = self.writer
- if glyph_map_new:
- writer.start('defs')
- for char_id, (vertices, codes) in glyph_map_new.items():
- char_id = self._adjust_char_id(char_id)
- # x64 to go back to FreeType's internal (integral) units.
- path_data = self._convert_path(
- Path(vertices * 64, codes), simplify=False)
- writer.element(
- 'path', id=char_id, d=path_data,
- transform=_generate_transform([('scale', (1 / 64,))]))
- writer.end('defs')
- self._glyph_map.update(glyph_map_new)
-
- def _adjust_char_id(self, char_id):
- return char_id.replace("%20", "_")
-
- def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath, mtext=None):
- # docstring inherited
- writer = self.writer
-
- writer.comment(s)
-
- glyph_map = self._glyph_map
-
- text2path = self._text2path
- color = rgb2hex(gc.get_rgb())
- fontsize = prop.get_size_in_points()
-
- style = {}
- if color != '#000000':
- style['fill'] = color
- alpha = gc.get_alpha() if gc.get_forced_alpha() else gc.get_rgb()[3]
- if alpha != 1:
- style['opacity'] = _short_float_fmt(alpha)
- font_scale = fontsize / text2path.FONT_SCALE
- attrib = {
- 'style': _generate_css(style),
- 'transform': _generate_transform([
- ('translate', (x, y)),
- ('rotate', (-angle,)),
- ('scale', (font_scale, -font_scale))]),
- }
- writer.start('g', attrib=attrib)
-
- if not ismath:
- font = text2path._get_font(prop)
- _glyphs = text2path.get_glyphs_with_font(
- font, s, glyph_map=glyph_map, return_new_glyphs_only=True)
- glyph_info, glyph_map_new, rects = _glyphs
- self._update_glyph_map_defs(glyph_map_new)
-
- for glyph_id, xposition, yposition, scale in glyph_info:
- attrib = {'xlink:href': f'#{glyph_id}'}
- if xposition != 0.0:
- attrib['x'] = _short_float_fmt(xposition)
- if yposition != 0.0:
- attrib['y'] = _short_float_fmt(yposition)
- writer.element('use', attrib=attrib)
-
- else:
- if ismath == "TeX":
- _glyphs = text2path.get_glyphs_tex(
- prop, s, glyph_map=glyph_map, return_new_glyphs_only=True)
- else:
- _glyphs = text2path.get_glyphs_mathtext(
- prop, s, glyph_map=glyph_map, return_new_glyphs_only=True)
- glyph_info, glyph_map_new, rects = _glyphs
- self._update_glyph_map_defs(glyph_map_new)
-
- for char_id, xposition, yposition, scale in glyph_info:
- char_id = self._adjust_char_id(char_id)
- writer.element(
- 'use',
- transform=_generate_transform([
- ('translate', (xposition, yposition)),
- ('scale', (scale,)),
- ]),
- attrib={'xlink:href': f'#{char_id}'})
-
- for verts, codes in rects:
- path = Path(verts, codes)
- path_data = self._convert_path(path, simplify=False)
- writer.element('path', d=path_data)
-
- writer.end('g')
-
- def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
- writer = self.writer
-
- color = rgb2hex(gc.get_rgb())
- style = {}
- if color != '#000000':
- style['fill'] = color
-
- alpha = gc.get_alpha() if gc.get_forced_alpha() else gc.get_rgb()[3]
- if alpha != 1:
- style['opacity'] = _short_float_fmt(alpha)
-
- if not ismath:
- attrib = {}
-
- font_parts = []
- if prop.get_style() != 'normal':
- font_parts.append(prop.get_style())
- if prop.get_variant() != 'normal':
- font_parts.append(prop.get_variant())
- weight = fm.weight_dict[prop.get_weight()]
- if weight != 400:
- font_parts.append(f'{weight}')
-
- def _normalize_sans(name):
- return 'sans-serif' if name in ['sans', 'sans serif'] else name
-
- def _expand_family_entry(fn):
- fn = _normalize_sans(fn)
- # prepend generic font families with all configured font names
- if fn in fm.font_family_aliases:
- # get all of the font names and fix spelling of sans-serif
- # (we accept 3 ways CSS only supports 1)
- for name in fm.FontManager._expand_aliases(fn):
- yield _normalize_sans(name)
- # whether a generic name or a family name, it must appear at
- # least once
- yield fn
-
- def _get_all_quoted_names(prop):
- # only quote specific names, not generic names
- return [name if name in fm.font_family_aliases else repr(name)
- for entry in prop.get_family()
- for name in _expand_family_entry(entry)]
-
- font_parts.extend([
- f'{_short_float_fmt(prop.get_size())}px',
- # ensure expansion, quoting, and dedupe of font names
- ", ".join(dict.fromkeys(_get_all_quoted_names(prop)))
- ])
- style['font'] = ' '.join(font_parts)
- if prop.get_stretch() != 'normal':
- style['font-stretch'] = prop.get_stretch()
- attrib['style'] = _generate_css(style)
-
- if mtext and (angle == 0 or mtext.get_rotation_mode() == "anchor"):
- # If text anchoring can be supported, get the original
- # coordinates and add alignment information.
-
- # Get anchor coordinates.
- transform = mtext.get_transform()
- ax, ay = transform.transform(mtext.get_unitless_position())
- ay = self.height - ay
-
- # Don't do vertical anchor alignment. Most applications do not
- # support 'alignment-baseline' yet. Apply the vertical layout
- # to the anchor point manually for now.
- angle_rad = np.deg2rad(angle)
- dir_vert = np.array([np.sin(angle_rad), np.cos(angle_rad)])
- v_offset = np.dot(dir_vert, [(x - ax), (y - ay)])
- ax = ax + v_offset * dir_vert[0]
- ay = ay + v_offset * dir_vert[1]
-
- ha_mpl_to_svg = {'left': 'start', 'right': 'end',
- 'center': 'middle'}
- style['text-anchor'] = ha_mpl_to_svg[mtext.get_ha()]
-
- attrib['x'] = _short_float_fmt(ax)
- attrib['y'] = _short_float_fmt(ay)
- attrib['style'] = _generate_css(style)
- attrib['transform'] = _generate_transform([
- ("rotate", (-angle, ax, ay))])
-
- else:
- attrib['transform'] = _generate_transform([
- ('translate', (x, y)),
- ('rotate', (-angle,))])
-
- writer.element('text', s, attrib=attrib)
-
- else:
- writer.comment(s)
-
- width, height, descent, glyphs, rects = \
- self._text2path.mathtext_parser.parse(s, 72, prop)
-
- # Apply attributes to 'g', not 'text', because we likely have some
- # rectangles as well with the same style and transformation.
- writer.start('g',
- style=_generate_css(style),
- transform=_generate_transform([
- ('translate', (x, y)),
- ('rotate', (-angle,))]),
- )
-
- writer.start('text')
-
- # Sort the characters by font, and output one tspan for each.
- spans = {}
- for font, fontsize, thetext, new_x, new_y in glyphs:
- entry = fm.ttfFontProperty(font)
- font_parts = []
- if entry.style != 'normal':
- font_parts.append(entry.style)
- if entry.variant != 'normal':
- font_parts.append(entry.variant)
- if entry.weight != 400:
- font_parts.append(f'{entry.weight}')
- font_parts.extend([
- f'{_short_float_fmt(fontsize)}px',
- f'{entry.name!r}', # ensure quoting
- ])
- style = {'font': ' '.join(font_parts)}
- if entry.stretch != 'normal':
- style['font-stretch'] = entry.stretch
- style = _generate_css(style)
- if thetext == 32:
- thetext = 0xa0 # non-breaking space
- spans.setdefault(style, []).append((new_x, -new_y, thetext))
-
- for style, chars in spans.items():
- chars.sort()
-
- if len({y for x, y, t in chars}) == 1: # Are all y's the same?
- ys = str(chars[0][1])
- else:
- ys = ' '.join(str(c[1]) for c in chars)
-
- attrib = {
- 'style': style,
- 'x': ' '.join(_short_float_fmt(c[0]) for c in chars),
- 'y': ys
- }
-
- writer.element(
- 'tspan',
- ''.join(chr(c[2]) for c in chars),
- attrib=attrib)
-
- writer.end('text')
-
- for x, y, width, height in rects:
- writer.element(
- 'rect',
- x=_short_float_fmt(x),
- y=_short_float_fmt(-y-1),
- width=_short_float_fmt(width),
- height=_short_float_fmt(height)
- )
-
- writer.end('g')
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- # docstring inherited
-
- clip_attrs = self._get_clip_attrs(gc)
- if clip_attrs:
- # Cannot apply clip-path directly to the text, because
- # it has a transformation
- self.writer.start('g', **clip_attrs)
-
- if gc.get_url() is not None:
- self.writer.start('a', {'xlink:href': gc.get_url()})
-
- if mpl.rcParams['svg.fonttype'] == 'path':
- self._draw_text_as_path(gc, x, y, s, prop, angle, ismath, mtext)
- else:
- self._draw_text_as_text(gc, x, y, s, prop, angle, ismath, mtext)
-
- if gc.get_url() is not None:
- self.writer.end('a')
-
- if clip_attrs:
- self.writer.end('g')
-
- def flipy(self):
- # docstring inherited
- return True
-
- def get_canvas_width_height(self):
- # docstring inherited
- return self.width, self.height
-
- def get_text_width_height_descent(self, s, prop, ismath):
- # docstring inherited
- return self._text2path.get_text_width_height_descent(s, prop, ismath)
-
-
-class FigureCanvasSVG(FigureCanvasBase):
- filetypes = {'svg': 'Scalable Vector Graphics',
- 'svgz': 'Scalable Vector Graphics'}
-
- fixed_dpi = 72
-
- def print_svg(self, filename, *, bbox_inches_restore=None, metadata=None):
- """
- Parameters
- ----------
- filename : str or path-like or file-like
- Output target; if a string, a file will be opened for writing.
-
- metadata : dict[str, Any], optional
- Metadata in the SVG file defined as key-value pairs of strings,
- datetimes, or lists of strings, e.g., ``{'Creator': 'My software',
- 'Contributor': ['Me', 'My Friend'], 'Title': 'Awesome'}``.
-
- The standard keys and their value types are:
-
- * *str*: ``'Coverage'``, ``'Description'``, ``'Format'``,
- ``'Identifier'``, ``'Language'``, ``'Relation'``, ``'Source'``,
- ``'Title'``, and ``'Type'``.
- * *str* or *list of str*: ``'Contributor'``, ``'Creator'``,
- ``'Keywords'``, ``'Publisher'``, and ``'Rights'``.
- * *str*, *date*, *datetime*, or *tuple* of same: ``'Date'``. If a
- non-*str*, then it will be formatted as ISO 8601.
-
- Values have been predefined for ``'Creator'``, ``'Date'``,
- ``'Format'``, and ``'Type'``. They can be removed by setting them
- to `None`.
-
- Information is encoded as `Dublin Core Metadata`__.
-
- .. _DC: https://www.dublincore.org/specifications/dublin-core/
-
- __ DC_
- """
- with cbook.open_file_cm(filename, "w", encoding="utf-8") as fh:
- if not cbook.file_requires_unicode(fh):
- fh = codecs.getwriter('utf-8')(fh)
- dpi = self.figure.dpi
- self.figure.dpi = 72
- width, height = self.figure.get_size_inches()
- w, h = width * 72, height * 72
- renderer = MixedModeRenderer(
- self.figure, width, height, dpi,
- RendererSVG(w, h, fh, image_dpi=dpi, metadata=metadata),
- bbox_inches_restore=bbox_inches_restore)
- self.figure.draw(renderer)
- renderer.finalize()
-
- def print_svgz(self, filename, **kwargs):
- with cbook.open_file_cm(filename, "wb") as fh, \
- gzip.GzipFile(mode='w', fileobj=fh) as gzipwriter:
- return self.print_svg(gzipwriter, **kwargs)
-
- def get_default_filetype(self):
- return 'svg'
-
- def draw(self):
- self.figure.draw_without_rendering()
- return super().draw()
-
-
-FigureManagerSVG = FigureManagerBase
-
-
-svgProlog = """\
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-"""
-
-
-@_Backend.export
-class _BackendSVG(_Backend):
- backend_version = mpl.__version__
- FigureCanvas = FigureCanvasSVG
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_template.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_template.py
deleted file mode 100644
index d997ec160a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_template.py
+++ /dev/null
@@ -1,213 +0,0 @@
-"""
-A fully functional, do-nothing backend intended as a template for backend
-writers. It is fully functional in that you can select it as a backend e.g.
-with ::
-
- import matplotlib
- matplotlib.use("template")
-
-and your program will (should!) run without error, though no output is
-produced. This provides a starting point for backend writers; you can
-selectively implement drawing methods (`~.RendererTemplate.draw_path`,
-`~.RendererTemplate.draw_image`, etc.) and slowly see your figure come to life
-instead having to have a full-blown implementation before getting any results.
-
-Copy this file to a directory outside the Matplotlib source tree, somewhere
-where Python can import it (by adding the directory to your ``sys.path`` or by
-packaging it as a normal Python package); if the backend is importable as
-``import my.backend`` you can then select it using ::
-
- import matplotlib
- matplotlib.use("module://my.backend")
-
-If your backend implements support for saving figures (i.e. has a `print_xyz`
-method), you can register it as the default handler for a given file type::
-
- from matplotlib.backend_bases import register_backend
- register_backend('xyz', 'my_backend', 'XYZ File Format')
- ...
- plt.savefig("figure.xyz")
-"""
-
-from matplotlib import _api
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.backend_bases import (
- FigureCanvasBase, FigureManagerBase, GraphicsContextBase, RendererBase)
-from matplotlib.figure import Figure
-
-
-class RendererTemplate(RendererBase):
- """
- The renderer handles drawing/rendering operations.
-
- This is a minimal do-nothing class that can be used to get started when
- writing a new backend. Refer to `.backend_bases.RendererBase` for
- documentation of the methods.
- """
-
- def __init__(self, dpi):
- super().__init__()
- self.dpi = dpi
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- pass
-
- # draw_markers is optional, and we get more correct relative
- # timings by leaving it out. backend implementers concerned with
- # performance will probably want to implement it
-# def draw_markers(self, gc, marker_path, marker_trans, path, trans,
-# rgbFace=None):
-# pass
-
- # draw_path_collection is optional, and we get more correct
- # relative timings by leaving it out. backend implementers concerned with
- # performance will probably want to implement it
-# def draw_path_collection(self, gc, master_transform, paths,
-# all_transforms, offsets, offset_trans,
-# facecolors, edgecolors, linewidths, linestyles,
-# antialiaseds):
-# pass
-
- # draw_quad_mesh is optional, and we get more correct
- # relative timings by leaving it out. backend implementers concerned with
- # performance will probably want to implement it
-# def draw_quad_mesh(self, gc, master_transform, meshWidth, meshHeight,
-# coordinates, offsets, offsetTrans, facecolors,
-# antialiased, edgecolors):
-# pass
-
- def draw_image(self, gc, x, y, im):
- pass
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- pass
-
- def flipy(self):
- # docstring inherited
- return True
-
- def get_canvas_width_height(self):
- # docstring inherited
- return 100, 100
-
- def get_text_width_height_descent(self, s, prop, ismath):
- return 1, 1, 1
-
- def new_gc(self):
- # docstring inherited
- return GraphicsContextTemplate()
-
- def points_to_pixels(self, points):
- # if backend doesn't have dpi, e.g., postscript or svg
- return points
- # elif backend assumes a value for pixels_per_inch
- # return points/72.0 * self.dpi.get() * pixels_per_inch/72.0
- # else
- # return points/72.0 * self.dpi.get()
-
-
-class GraphicsContextTemplate(GraphicsContextBase):
- """
- The graphics context provides the color, line styles, etc. See the cairo
- and postscript backends for examples of mapping the graphics context
- attributes (cap styles, join styles, line widths, colors) to a particular
- backend. In cairo this is done by wrapping a cairo.Context object and
- forwarding the appropriate calls to it using a dictionary mapping styles
- to gdk constants. In Postscript, all the work is done by the renderer,
- mapping line styles to postscript calls.
-
- If it's more appropriate to do the mapping at the renderer level (as in
- the postscript backend), you don't need to override any of the GC methods.
- If it's more appropriate to wrap an instance (as in the cairo backend) and
- do the mapping here, you'll need to override several of the setter
- methods.
-
- The base GraphicsContext stores colors as an RGB tuple on the unit
- interval, e.g., (0.5, 0.0, 1.0). You may need to map this to colors
- appropriate for your backend.
- """
-
-
-########################################################################
-#
-# The following functions and classes are for pyplot and implement
-# window/figure managers, etc.
-#
-########################################################################
-
-
-class FigureManagerTemplate(FigureManagerBase):
- """
- Helper class for pyplot mode, wraps everything up into a neat bundle.
-
- For non-interactive backends, the base class is sufficient. For
- interactive backends, see the documentation of the `.FigureManagerBase`
- class for the list of methods that can/should be overridden.
- """
-
-
-class FigureCanvasTemplate(FigureCanvasBase):
- """
- The canvas the figure renders into. Calls the draw and print fig
- methods, creates the renderers, etc.
-
- Note: GUI templates will want to connect events for button presses,
- mouse movements and key presses to functions that call the base
- class methods button_press_event, button_release_event,
- motion_notify_event, key_press_event, and key_release_event. See the
- implementations of the interactive backends for examples.
-
- Attributes
- ----------
- figure : `~matplotlib.figure.Figure`
- A high-level Figure instance
- """
-
- # The instantiated manager class. For further customization,
- # ``FigureManager.create_with_canvas`` can also be overridden; see the
- # wx-based backends for an example.
- manager_class = FigureManagerTemplate
-
- def draw(self):
- """
- Draw the figure using the renderer.
-
- It is important that this method actually walk the artist tree
- even if not output is produced because this will trigger
- deferred work (like computing limits auto-limits and tick
- values) that users may want access to before saving to disk.
- """
- renderer = RendererTemplate(self.figure.dpi)
- self.figure.draw(renderer)
-
- # You should provide a print_xxx function for every file format
- # you can write.
-
- # If the file type is not in the base set of filetypes,
- # you should add it to the class-scope filetypes dictionary as follows:
- filetypes = {**FigureCanvasBase.filetypes, 'foo': 'My magic Foo format'}
-
- def print_foo(self, filename, **kwargs):
- """
- Write out format foo.
-
- This method is normally called via `.Figure.savefig` and
- `.FigureCanvasBase.print_figure`, which take care of setting the figure
- facecolor, edgecolor, and dpi to the desired output values, and will
- restore them to the original values. Therefore, `print_foo` does not
- need to handle these settings.
- """
- self.draw()
-
- def get_default_filetype(self):
- return 'foo'
-
-
-########################################################################
-#
-# Now just provide the standard names that backend.__init__ is expecting
-#
-########################################################################
-
-FigureCanvas = FigureCanvasTemplate
-FigureManager = FigureManagerTemplate
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_tkagg.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_tkagg.py
deleted file mode 100644
index f95b6011ea..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_tkagg.py
+++ /dev/null
@@ -1,20 +0,0 @@
-from . import _backend_tk
-from .backend_agg import FigureCanvasAgg
-from ._backend_tk import _BackendTk, FigureCanvasTk
-from ._backend_tk import ( # noqa: F401 # pylint: disable=W0611
- FigureManagerTk, NavigationToolbar2Tk)
-
-
-class FigureCanvasTkAgg(FigureCanvasAgg, FigureCanvasTk):
- def draw(self):
- super().draw()
- self.blit()
-
- def blit(self, bbox=None):
- _backend_tk.blit(self._tkphoto, self.renderer.buffer_rgba(),
- (0, 1, 2, 3), bbox=bbox)
-
-
-@_BackendTk.export
-class _BackendTkAgg(_BackendTk):
- FigureCanvas = FigureCanvasTkAgg
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_tkcairo.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_tkcairo.py
deleted file mode 100644
index a6951c03c6..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_tkcairo.py
+++ /dev/null
@@ -1,26 +0,0 @@
-import sys
-
-import numpy as np
-
-from . import _backend_tk
-from .backend_cairo import cairo, FigureCanvasCairo
-from ._backend_tk import _BackendTk, FigureCanvasTk
-
-
-class FigureCanvasTkCairo(FigureCanvasCairo, FigureCanvasTk):
- def draw(self):
- width = int(self.figure.bbox.width)
- height = int(self.figure.bbox.height)
- surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
- self._renderer.set_context(cairo.Context(surface))
- self._renderer.dpi = self.figure.dpi
- self.figure.draw(self._renderer)
- buf = np.reshape(surface.get_data(), (height, width, 4))
- _backend_tk.blit(
- self._tkphoto, buf,
- (2, 1, 0, 3) if sys.byteorder == "little" else (1, 2, 3, 0))
-
-
-@_BackendTk.export
-class _BackendTkCairo(_BackendTk):
- FigureCanvas = FigureCanvasTkCairo
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_webagg.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_webagg.py
deleted file mode 100644
index 030ab8519b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_webagg.py
+++ /dev/null
@@ -1,352 +0,0 @@
-"""Displays Agg images in the browser, with interactivity."""
-
-# The WebAgg backend is divided into two modules:
-#
-# - `backend_webagg_core.py` contains code necessary to embed a WebAgg
-# plot inside of a web application, and communicate in an abstract
-# way over a web socket.
-#
-# - `backend_webagg.py` contains a concrete implementation of a basic
-# application, implemented with tornado.
-
-from contextlib import contextmanager
-import errno
-from io import BytesIO
-import json
-import mimetypes
-from pathlib import Path
-import random
-import sys
-import signal
-import threading
-import tempfile
-import os
-
-from library.python.resource import iteritems
-
-try:
- import tornado
-except ImportError as err:
- raise RuntimeError("The WebAgg backend requires Tornado.") from err
-
-import tornado.web
-import tornado.ioloop
-import tornado.websocket
-
-import matplotlib as mpl
-from matplotlib.backend_bases import _Backend
-from matplotlib._pylab_helpers import Gcf
-from . import backend_webagg_core as core
-from .backend_webagg_core import ( # noqa: F401 # pylint: disable=W0611
- TimerAsyncio, TimerTornado)
-
-
-@mpl._api.deprecated("3.7")
-class ServerThread(threading.Thread):
- def run(self):
- tornado.ioloop.IOLoop.instance().start()
-
-
-webagg_server_thread = threading.Thread(
- target=lambda: tornado.ioloop.IOLoop.instance().start())
-
-
-class FigureManagerWebAgg(core.FigureManagerWebAgg):
- _toolbar2_class = core.NavigationToolbar2WebAgg
-
- @classmethod
- def pyplot_show(cls, *, block=None):
- WebAggApplication.initialize()
-
- url = "http://{address}:{port}{prefix}".format(
- address=WebAggApplication.address,
- port=WebAggApplication.port,
- prefix=WebAggApplication.url_prefix)
-
- if mpl.rcParams['webagg.open_in_browser']:
- import webbrowser
- if not webbrowser.open(url):
- print(f"To view figure, visit {url}")
- else:
- print(f"To view figure, visit {url}")
-
- WebAggApplication.start()
-
-
-class FigureCanvasWebAgg(core.FigureCanvasWebAggCore):
- manager_class = FigureManagerWebAgg
-
-
-class WebAggApplication(tornado.web.Application):
- initialized = False
- started = False
-
- class FavIcon(tornado.web.RequestHandler):
- def get(self):
- self.set_header('Content-Type', 'image/png')
- self.write(Path(mpl.get_data_path(),
- 'images/matplotlib.png').read_bytes())
-
- class SingleFigurePage(tornado.web.RequestHandler):
- def __init__(self, application, request, *, url_prefix='', **kwargs):
- self.url_prefix = url_prefix
- super().__init__(application, request, **kwargs)
-
- def get(self, fignum):
- fignum = int(fignum)
- manager = Gcf.get_fig_manager(fignum)
-
- ws_uri = f'ws://{self.request.host}{self.url_prefix}/'
- self.render(
- "single_figure.html",
- prefix=self.url_prefix,
- ws_uri=ws_uri,
- fig_id=fignum,
- toolitems=core.NavigationToolbar2WebAgg.toolitems,
- canvas=manager.canvas)
-
- class AllFiguresPage(tornado.web.RequestHandler):
- def __init__(self, application, request, *, url_prefix='', **kwargs):
- self.url_prefix = url_prefix
- super().__init__(application, request, **kwargs)
-
- def get(self):
- ws_uri = f'ws://{self.request.host}{self.url_prefix}/'
- self.render(
- "all_figures.html",
- prefix=self.url_prefix,
- ws_uri=ws_uri,
- figures=sorted(Gcf.figs.items()),
- toolitems=core.NavigationToolbar2WebAgg.toolitems)
-
- class MplJs(tornado.web.RequestHandler):
- def get(self):
- self.set_header('Content-Type', 'application/javascript')
-
- js_content = core.FigureManagerWebAgg.get_javascript()
-
- self.write(js_content)
-
- class Download(tornado.web.RequestHandler):
- def get(self, fignum, fmt):
- fignum = int(fignum)
- manager = Gcf.get_fig_manager(fignum)
- self.set_header(
- 'Content-Type', mimetypes.types_map.get(fmt, 'binary'))
- buff = BytesIO()
- manager.canvas.figure.savefig(buff, format=fmt)
- self.write(buff.getvalue())
-
- class WebSocket(tornado.websocket.WebSocketHandler):
- supports_binary = True
-
- def open(self, fignum):
- self.fignum = int(fignum)
- self.manager = Gcf.get_fig_manager(self.fignum)
- self.manager.add_web_socket(self)
- if hasattr(self, 'set_nodelay'):
- self.set_nodelay(True)
-
- def on_close(self):
- self.manager.remove_web_socket(self)
-
- def on_message(self, message):
- message = json.loads(message)
- # The 'supports_binary' message is on a client-by-client
- # basis. The others affect the (shared) canvas as a
- # whole.
- if message['type'] == 'supports_binary':
- self.supports_binary = message['value']
- else:
- manager = Gcf.get_fig_manager(self.fignum)
- # It is possible for a figure to be closed,
- # but a stale figure UI is still sending messages
- # from the browser.
- if manager is not None:
- manager.handle_json(message)
-
- def send_json(self, content):
- self.write_message(json.dumps(content))
-
- def send_binary(self, blob):
- if self.supports_binary:
- self.write_message(blob, binary=True)
- else:
- data_uri = "data:image/png;base64,{}".format(
- blob.encode('base64').replace('\n', ''))
- self.write_message(data_uri)
-
- def __init__(self, url_prefix=''):
- if url_prefix:
- assert url_prefix[0] == '/' and url_prefix[-1] != '/', \
- 'url_prefix must start with a "/" and not end with one.'
-
- self._store_resources()
- package_resources_abspath = os.path.join(self._stored_package_path, core.FigureManagerWebAgg.get_static_file_path())
- super().__init__(
- [
- # Static files for the CSS and JS
- (url_prefix + r'/_static/(.*)',
- tornado.web.StaticFileHandler,
- {'path': package_resources_abspath}),
-
- # Static images for the toolbar
- (url_prefix + r'/_images/(.*)',
- tornado.web.StaticFileHandler,
- {'path': Path(mpl.get_data_path(), 'images')}),
-
- # A Matplotlib favicon
- (url_prefix + r'/favicon.ico', self.FavIcon),
-
- # The page that contains all of the pieces
- (url_prefix + r'/([0-9]+)', self.SingleFigurePage,
- {'url_prefix': url_prefix}),
-
- # The page that contains all of the figures
- (url_prefix + r'/?', self.AllFiguresPage,
- {'url_prefix': url_prefix}),
-
- (url_prefix + r'/js/mpl.js', self.MplJs),
-
- # Sends images and events to the browser, and receives
- # events from the browser
- (url_prefix + r'/([0-9]+)/ws', self.WebSocket),
-
- # Handles the downloading (i.e., saving) of static images
- (url_prefix + r'/([0-9]+)/download.([a-z0-9.]+)',
- self.Download),
- ],
- template_path=package_resources_abspath)
-
- def _store_resources(self):
- self._stored_package_dir = tempfile.TemporaryDirectory()
- self._stored_package_path = self._stored_package_dir.name
- package_path = os.path.join(*"contrib/python/matplotlib/py3/".split("/"))
- for key, data in iteritems(prefix="resfs/file/" + package_path, strip_prefix=True):
- path = os.path.join(self._stored_package_path, *os.path.split(package_path), *os.path.split(key))
- dir = os.path.dirname(path)
- if not os.path.exists(dir):
- os.makedirs(dir)
- with open(path, "wb") as file:
- file.write(data)
-
- @classmethod
- def initialize(cls, url_prefix='', port=None, address=None):
- if cls.initialized:
- return
-
- # Create the class instance
- app = cls(url_prefix=url_prefix)
-
- cls.url_prefix = url_prefix
-
- # This port selection algorithm is borrowed, more or less
- # verbatim, from IPython.
- def random_ports(port, n):
- """
- Generate a list of n random ports near the given port.
-
- The first 5 ports will be sequential, and the remaining n-5 will be
- randomly selected in the range [port-2*n, port+2*n].
- """
- for i in range(min(5, n)):
- yield port + i
- for i in range(n - 5):
- yield port + random.randint(-2 * n, 2 * n)
-
- if address is None:
- cls.address = mpl.rcParams['webagg.address']
- else:
- cls.address = address
- cls.port = mpl.rcParams['webagg.port']
- for port in random_ports(cls.port,
- mpl.rcParams['webagg.port_retries']):
- try:
- app.listen(port, cls.address)
- except OSError as e:
- if e.errno != errno.EADDRINUSE:
- raise
- else:
- cls.port = port
- break
- else:
- raise SystemExit(
- "The webagg server could not be started because an available "
- "port could not be found")
-
- cls.initialized = True
-
- @classmethod
- def start(cls):
- import asyncio
- try:
- asyncio.get_running_loop()
- except RuntimeError:
- pass
- else:
- cls.started = True
-
- if cls.started:
- return
-
- """
- IOLoop.running() was removed as of Tornado 2.4; see for example
- https://groups.google.com/forum/#!topic/python-tornado/QLMzkpQBGOY
- Thus there is no correct way to check if the loop has already been
- launched. We may end up with two concurrently running loops in that
- unlucky case with all the expected consequences.
- """
- ioloop = tornado.ioloop.IOLoop.instance()
-
- def shutdown():
- ioloop.stop()
- print("Server is stopped")
- sys.stdout.flush()
- cls.started = False
-
- @contextmanager
- def catch_sigint():
- old_handler = signal.signal(
- signal.SIGINT,
- lambda sig, frame: ioloop.add_callback_from_signal(shutdown))
- try:
- yield
- finally:
- signal.signal(signal.SIGINT, old_handler)
-
- # Set the flag to True *before* blocking on ioloop.start()
- cls.started = True
-
- print("Press Ctrl+C to stop WebAgg server")
- sys.stdout.flush()
- with catch_sigint():
- ioloop.start()
-
-
-def ipython_inline_display(figure):
- import tornado.template
-
- WebAggApplication.initialize()
- import asyncio
- try:
- asyncio.get_running_loop()
- except RuntimeError:
- if not webagg_server_thread.is_alive():
- webagg_server_thread.start()
-
- fignum = figure.number
- tpl = Path(core.FigureManagerWebAgg.get_static_file_path(),
- "ipython_inline_figure.html").read_text()
- t = tornado.template.Template(tpl)
- return t.generate(
- prefix=WebAggApplication.url_prefix,
- fig_id=fignum,
- toolitems=core.NavigationToolbar2WebAgg.toolitems,
- canvas=figure.canvas,
- port=WebAggApplication.port).decode('utf-8')
-
-
-@_Backend.export
-class _BackendWebAgg(_Backend):
- FigureCanvas = FigureCanvasWebAgg
- FigureManager = FigureManagerWebAgg
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_webagg_core.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_webagg_core.py
deleted file mode 100644
index 6c80bc2ba0..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_webagg_core.py
+++ /dev/null
@@ -1,518 +0,0 @@
-"""Displays Agg images in the browser, with interactivity."""
-# The WebAgg backend is divided into two modules:
-#
-# - `backend_webagg_core.py` contains code necessary to embed a WebAgg
-# plot inside of a web application, and communicate in an abstract
-# way over a web socket.
-#
-# - `backend_webagg.py` contains a concrete implementation of a basic
-# application, implemented with asyncio.
-
-import asyncio
-import datetime
-from io import BytesIO, StringIO
-import json
-import logging
-import os
-from pathlib import Path
-
-import numpy as np
-from PIL import Image
-
-from matplotlib import _api, backend_bases, backend_tools
-from matplotlib.backends import backend_agg
-from matplotlib.backend_bases import (
- _Backend, KeyEvent, LocationEvent, MouseEvent, ResizeEvent)
-
-_log = logging.getLogger(__name__)
-
-_SPECIAL_KEYS_LUT = {'Alt': 'alt',
- 'AltGraph': 'alt',
- 'CapsLock': 'caps_lock',
- 'Control': 'control',
- 'Meta': 'meta',
- 'NumLock': 'num_lock',
- 'ScrollLock': 'scroll_lock',
- 'Shift': 'shift',
- 'Super': 'super',
- 'Enter': 'enter',
- 'Tab': 'tab',
- 'ArrowDown': 'down',
- 'ArrowLeft': 'left',
- 'ArrowRight': 'right',
- 'ArrowUp': 'up',
- 'End': 'end',
- 'Home': 'home',
- 'PageDown': 'pagedown',
- 'PageUp': 'pageup',
- 'Backspace': 'backspace',
- 'Delete': 'delete',
- 'Insert': 'insert',
- 'Escape': 'escape',
- 'Pause': 'pause',
- 'Select': 'select',
- 'Dead': 'dead',
- 'F1': 'f1',
- 'F2': 'f2',
- 'F3': 'f3',
- 'F4': 'f4',
- 'F5': 'f5',
- 'F6': 'f6',
- 'F7': 'f7',
- 'F8': 'f8',
- 'F9': 'f9',
- 'F10': 'f10',
- 'F11': 'f11',
- 'F12': 'f12'}
-
-
-def _handle_key(key):
- """Handle key values"""
- value = key[key.index('k') + 1:]
- if 'shift+' in key:
- if len(value) == 1:
- key = key.replace('shift+', '')
- if value in _SPECIAL_KEYS_LUT:
- value = _SPECIAL_KEYS_LUT[value]
- key = key[:key.index('k')] + value
- return key
-
-
-class TimerTornado(backend_bases.TimerBase):
- def __init__(self, *args, **kwargs):
- self._timer = None
- super().__init__(*args, **kwargs)
-
- def _timer_start(self):
- import tornado
-
- self._timer_stop()
- if self._single:
- ioloop = tornado.ioloop.IOLoop.instance()
- self._timer = ioloop.add_timeout(
- datetime.timedelta(milliseconds=self.interval),
- self._on_timer)
- else:
- self._timer = tornado.ioloop.PeriodicCallback(
- self._on_timer,
- max(self.interval, 1e-6))
- self._timer.start()
-
- def _timer_stop(self):
- import tornado
-
- if self._timer is None:
- return
- elif self._single:
- ioloop = tornado.ioloop.IOLoop.instance()
- ioloop.remove_timeout(self._timer)
- else:
- self._timer.stop()
- self._timer = None
-
- def _timer_set_interval(self):
- # Only stop and restart it if the timer has already been started
- if self._timer is not None:
- self._timer_stop()
- self._timer_start()
-
-
-class TimerAsyncio(backend_bases.TimerBase):
- def __init__(self, *args, **kwargs):
- self._task = None
- super().__init__(*args, **kwargs)
-
- async def _timer_task(self, interval):
- while True:
- try:
- await asyncio.sleep(interval)
- self._on_timer()
-
- if self._single:
- break
- except asyncio.CancelledError:
- break
-
- def _timer_start(self):
- self._timer_stop()
-
- self._task = asyncio.ensure_future(
- self._timer_task(max(self.interval / 1_000., 1e-6))
- )
-
- def _timer_stop(self):
- if self._task is not None:
- self._task.cancel()
- self._task = None
-
- def _timer_set_interval(self):
- # Only stop and restart it if the timer has already been started
- if self._task is not None:
- self._timer_stop()
- self._timer_start()
-
-
-class FigureCanvasWebAggCore(backend_agg.FigureCanvasAgg):
- manager_class = _api.classproperty(lambda cls: FigureManagerWebAgg)
- _timer_cls = TimerAsyncio
- # Webagg and friends having the right methods, but still
- # having bugs in practice. Do not advertise that it works until
- # we can debug this.
- supports_blit = False
-
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- # Set to True when the renderer contains data that is newer
- # than the PNG buffer.
- self._png_is_old = True
- # Set to True by the `refresh` message so that the next frame
- # sent to the clients will be a full frame.
- self._force_full = True
- # The last buffer, for diff mode.
- self._last_buff = np.empty((0, 0))
- # Store the current image mode so that at any point, clients can
- # request the information. This should be changed by calling
- # self.set_image_mode(mode) so that the notification can be given
- # to the connected clients.
- self._current_image_mode = 'full'
- # Track mouse events to fill in the x, y position of key events.
- self._last_mouse_xy = (None, None)
-
- def show(self):
- # show the figure window
- from matplotlib.pyplot import show
- show()
-
- def draw(self):
- self._png_is_old = True
- try:
- super().draw()
- finally:
- self.manager.refresh_all() # Swap the frames.
-
- def blit(self, bbox=None):
- self._png_is_old = True
- self.manager.refresh_all()
-
- def draw_idle(self):
- self.send_event("draw")
-
- def set_cursor(self, cursor):
- # docstring inherited
- cursor = _api.check_getitem({
- backend_tools.Cursors.HAND: 'pointer',
- backend_tools.Cursors.POINTER: 'default',
- backend_tools.Cursors.SELECT_REGION: 'crosshair',
- backend_tools.Cursors.MOVE: 'move',
- backend_tools.Cursors.WAIT: 'wait',
- backend_tools.Cursors.RESIZE_HORIZONTAL: 'ew-resize',
- backend_tools.Cursors.RESIZE_VERTICAL: 'ns-resize',
- }, cursor=cursor)
- self.send_event('cursor', cursor=cursor)
-
- def set_image_mode(self, mode):
- """
- Set the image mode for any subsequent images which will be sent
- to the clients. The modes may currently be either 'full' or 'diff'.
-
- Note: diff images may not contain transparency, therefore upon
- draw this mode may be changed if the resulting image has any
- transparent component.
- """
- _api.check_in_list(['full', 'diff'], mode=mode)
- if self._current_image_mode != mode:
- self._current_image_mode = mode
- self.handle_send_image_mode(None)
-
- def get_diff_image(self):
- if self._png_is_old:
- renderer = self.get_renderer()
-
- pixels = np.asarray(renderer.buffer_rgba())
- # The buffer is created as type uint32 so that entire
- # pixels can be compared in one numpy call, rather than
- # needing to compare each plane separately.
- buff = pixels.view(np.uint32).squeeze(2)
-
- if (self._force_full
- # If the buffer has changed size we need to do a full draw.
- or buff.shape != self._last_buff.shape
- # If any pixels have transparency, we need to force a full
- # draw as we cannot overlay new on top of old.
- or (pixels[:, :, 3] != 255).any()):
- self.set_image_mode('full')
- output = buff
- else:
- self.set_image_mode('diff')
- diff = buff != self._last_buff
- output = np.where(diff, buff, 0)
-
- # Store the current buffer so we can compute the next diff.
- self._last_buff = buff.copy()
- self._force_full = False
- self._png_is_old = False
-
- data = output.view(dtype=np.uint8).reshape((*output.shape, 4))
- with BytesIO() as png:
- Image.fromarray(data).save(png, format="png")
- return png.getvalue()
-
- def handle_event(self, event):
- e_type = event['type']
- handler = getattr(self, f'handle_{e_type}',
- self.handle_unknown_event)
- return handler(event)
-
- def handle_unknown_event(self, event):
- _log.warning('Unhandled message type %s. %s', event["type"], event)
-
- def handle_ack(self, event):
- # Network latency tends to decrease if traffic is flowing
- # in both directions. Therefore, the browser sends back
- # an "ack" message after each image frame is received.
- # This could also be used as a simple sanity check in the
- # future, but for now the performance increase is enough
- # to justify it, even if the server does nothing with it.
- pass
-
- def handle_draw(self, event):
- self.draw()
-
- def _handle_mouse(self, event):
- x = event['x']
- y = event['y']
- y = self.get_renderer().height - y
- self._last_mouse_xy = x, y
- # JavaScript button numbers and Matplotlib button numbers are off by 1.
- button = event['button'] + 1
-
- e_type = event['type']
- modifiers = event['modifiers']
- guiEvent = event.get('guiEvent')
- if e_type in ['button_press', 'button_release']:
- MouseEvent(e_type + '_event', self, x, y, button,
- modifiers=modifiers, guiEvent=guiEvent)._process()
- elif e_type == 'dblclick':
- MouseEvent('button_press_event', self, x, y, button, dblclick=True,
- modifiers=modifiers, guiEvent=guiEvent)._process()
- elif e_type == 'scroll':
- MouseEvent('scroll_event', self, x, y, step=event['step'],
- modifiers=modifiers, guiEvent=guiEvent)._process()
- elif e_type == 'motion_notify':
- MouseEvent(e_type + '_event', self, x, y,
- modifiers=modifiers, guiEvent=guiEvent)._process()
- elif e_type in ['figure_enter', 'figure_leave']:
- LocationEvent(e_type + '_event', self, x, y,
- modifiers=modifiers, guiEvent=guiEvent)._process()
- handle_button_press = handle_button_release = handle_dblclick = \
- handle_figure_enter = handle_figure_leave = handle_motion_notify = \
- handle_scroll = _handle_mouse
-
- def _handle_key(self, event):
- KeyEvent(event['type'] + '_event', self,
- _handle_key(event['key']), *self._last_mouse_xy,
- guiEvent=event.get('guiEvent'))._process()
- handle_key_press = handle_key_release = _handle_key
-
- def handle_toolbar_button(self, event):
- # TODO: Be more suspicious of the input
- getattr(self.toolbar, event['name'])()
-
- def handle_refresh(self, event):
- figure_label = self.figure.get_label()
- if not figure_label:
- figure_label = f"Figure {self.manager.num}"
- self.send_event('figure_label', label=figure_label)
- self._force_full = True
- if self.toolbar:
- # Normal toolbar init would refresh this, but it happens before the
- # browser canvas is set up.
- self.toolbar.set_history_buttons()
- self.draw_idle()
-
- def handle_resize(self, event):
- x = int(event.get('width', 800)) * self.device_pixel_ratio
- y = int(event.get('height', 800)) * self.device_pixel_ratio
- fig = self.figure
- # An attempt at approximating the figure size in pixels.
- fig.set_size_inches(x / fig.dpi, y / fig.dpi, forward=False)
- # Acknowledge the resize, and force the viewer to update the
- # canvas size to the figure's new size (which is hopefully
- # identical or within a pixel or so).
- self._png_is_old = True
- self.manager.resize(*fig.bbox.size, forward=False)
- ResizeEvent('resize_event', self)._process()
- self.draw_idle()
-
- def handle_send_image_mode(self, event):
- # The client requests notification of what the current image mode is.
- self.send_event('image_mode', mode=self._current_image_mode)
-
- def handle_set_device_pixel_ratio(self, event):
- self._handle_set_device_pixel_ratio(event.get('device_pixel_ratio', 1))
-
- def handle_set_dpi_ratio(self, event):
- # This handler is for backwards-compatibility with older ipympl.
- self._handle_set_device_pixel_ratio(event.get('dpi_ratio', 1))
-
- def _handle_set_device_pixel_ratio(self, device_pixel_ratio):
- if self._set_device_pixel_ratio(device_pixel_ratio):
- self._force_full = True
- self.draw_idle()
-
- def send_event(self, event_type, **kwargs):
- if self.manager:
- self.manager._send_event(event_type, **kwargs)
-
-
-_ALLOWED_TOOL_ITEMS = {
- 'home',
- 'back',
- 'forward',
- 'pan',
- 'zoom',
- 'download',
- None,
-}
-
-
-class NavigationToolbar2WebAgg(backend_bases.NavigationToolbar2):
-
- # Use the standard toolbar items + download button
- toolitems = [
- (text, tooltip_text, image_file, name_of_method)
- for text, tooltip_text, image_file, name_of_method
- in (*backend_bases.NavigationToolbar2.toolitems,
- ('Download', 'Download plot', 'filesave', 'download'))
- if name_of_method in _ALLOWED_TOOL_ITEMS
- ]
-
- def __init__(self, canvas):
- self.message = ''
- super().__init__(canvas)
-
- def set_message(self, message):
- if message != self.message:
- self.canvas.send_event("message", message=message)
- self.message = message
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- self.canvas.send_event("rubberband", x0=x0, y0=y0, x1=x1, y1=y1)
-
- def remove_rubberband(self):
- self.canvas.send_event("rubberband", x0=-1, y0=-1, x1=-1, y1=-1)
-
- def save_figure(self, *args):
- """Save the current figure"""
- self.canvas.send_event('save')
-
- def pan(self):
- super().pan()
- self.canvas.send_event('navigate_mode', mode=self.mode.name)
-
- def zoom(self):
- super().zoom()
- self.canvas.send_event('navigate_mode', mode=self.mode.name)
-
- def set_history_buttons(self):
- can_backward = self._nav_stack._pos > 0
- can_forward = self._nav_stack._pos < len(self._nav_stack) - 1
- self.canvas.send_event('history_buttons',
- Back=can_backward, Forward=can_forward)
-
-
-class FigureManagerWebAgg(backend_bases.FigureManagerBase):
- # This must be None to not break ipympl
- _toolbar2_class = None
- ToolbarCls = NavigationToolbar2WebAgg
- _window_title = "Matplotlib"
-
- def __init__(self, canvas, num):
- self.web_sockets = set()
- super().__init__(canvas, num)
-
- def show(self):
- pass
-
- def resize(self, w, h, forward=True):
- self._send_event(
- 'resize',
- size=(w / self.canvas.device_pixel_ratio,
- h / self.canvas.device_pixel_ratio),
- forward=forward)
-
- def set_window_title(self, title):
- self._send_event('figure_label', label=title)
- self._window_title = title
-
- def get_window_title(self):
- return self._window_title
-
- # The following methods are specific to FigureManagerWebAgg
-
- def add_web_socket(self, web_socket):
- assert hasattr(web_socket, 'send_binary')
- assert hasattr(web_socket, 'send_json')
- self.web_sockets.add(web_socket)
- self.resize(*self.canvas.figure.bbox.size)
- self._send_event('refresh')
-
- def remove_web_socket(self, web_socket):
- self.web_sockets.remove(web_socket)
-
- def handle_json(self, content):
- self.canvas.handle_event(content)
-
- def refresh_all(self):
- if self.web_sockets:
- diff = self.canvas.get_diff_image()
- if diff is not None:
- for s in self.web_sockets:
- s.send_binary(diff)
-
- @classmethod
- def get_javascript(cls, stream=None):
- if stream is None:
- output = StringIO()
- else:
- output = stream
-
- import pkgutil
- data = pkgutil.get_data(__package__, "web_backend/js/mpl.js").decode("utf-8")
- output.write(data)
-
- toolitems = []
- for name, tooltip, image, method in cls.ToolbarCls.toolitems:
- if name is None:
- toolitems.append(['', '', '', ''])
- else:
- toolitems.append([name, tooltip, image, method])
- output.write(f"mpl.toolbar_items = {json.dumps(toolitems)};\n\n")
-
- extensions = []
- for filetype, ext in sorted(FigureCanvasWebAggCore.
- get_supported_filetypes_grouped().
- items()):
- extensions.append(ext[0])
- output.write(f"mpl.extensions = {json.dumps(extensions)};\n\n")
-
- output.write("mpl.default_extension = {};".format(
- json.dumps(FigureCanvasWebAggCore.get_default_filetype())))
-
- if stream is None:
- return output.getvalue()
-
- @classmethod
- def get_static_file_path(cls):
- return os.path.join(os.path.dirname(__file__), 'web_backend')
-
- def _send_event(self, event_type, **kwargs):
- payload = {'type': event_type, **kwargs}
- for s in self.web_sockets:
- s.send_json(payload)
-
-
-@_Backend.export
-class _BackendWebAggCoreAgg(_Backend):
- FigureCanvas = FigureCanvasWebAggCore
- FigureManager = FigureManagerWebAgg
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_wx.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_wx.py
deleted file mode 100644
index 218be89476..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_wx.py
+++ /dev/null
@@ -1,1332 +0,0 @@
-"""
-A wxPython backend for matplotlib.
-
-Originally contributed by Jeremy O'Donoghue (jeremy@o-donoghue.com) and John
-Hunter (jdhunter@ace.bsd.uchicago.edu).
-
-Copyright (C) Jeremy O'Donoghue & John Hunter, 2003-4.
-"""
-
-import functools
-import logging
-import math
-import pathlib
-import sys
-import weakref
-
-import numpy as np
-import PIL.Image
-
-import matplotlib as mpl
-from matplotlib.backend_bases import (
- _Backend, FigureCanvasBase, FigureManagerBase,
- GraphicsContextBase, MouseButton, NavigationToolbar2, RendererBase,
- TimerBase, ToolContainerBase, cursors,
- CloseEvent, KeyEvent, LocationEvent, MouseEvent, ResizeEvent)
-
-from matplotlib import _api, cbook, backend_tools
-from matplotlib._pylab_helpers import Gcf
-from matplotlib.path import Path
-from matplotlib.transforms import Affine2D
-
-import wx
-
-_log = logging.getLogger(__name__)
-
-# the True dots per inch on the screen; should be display dependent; see
-# http://groups.google.com/d/msg/comp.lang.postscript/-/omHAc9FEuAsJ?hl=en
-# for some info about screen dpi
-PIXELS_PER_INCH = 75
-
-
-# lru_cache holds a reference to the App and prevents it from being gc'ed.
-@functools.lru_cache(1)
-def _create_wxapp():
- wxapp = wx.App(False)
- wxapp.SetExitOnFrameDelete(True)
- cbook._setup_new_guiapp()
- return wxapp
-
-
-class TimerWx(TimerBase):
- """Subclass of `.TimerBase` using wx.Timer events."""
-
- def __init__(self, *args, **kwargs):
- self._timer = wx.Timer()
- self._timer.Notify = self._on_timer
- super().__init__(*args, **kwargs)
-
- def _timer_start(self):
- self._timer.Start(self._interval, self._single)
-
- def _timer_stop(self):
- self._timer.Stop()
-
- def _timer_set_interval(self):
- if self._timer.IsRunning():
- self._timer_start() # Restart with new interval.
-
-
-@_api.deprecated(
- "2.0", name="wx", obj_type="backend", removal="the future",
- alternative="wxagg",
- addendum="See the Matplotlib usage FAQ for more info on backends.")
-class RendererWx(RendererBase):
- """
- The renderer handles all the drawing primitives using a graphics
- context instance that controls the colors/styles. It acts as the
- 'renderer' instance used by many classes in the hierarchy.
- """
- # In wxPython, drawing is performed on a wxDC instance, which will
- # generally be mapped to the client area of the window displaying
- # the plot. Under wxPython, the wxDC instance has a wx.Pen which
- # describes the colour and weight of any lines drawn, and a wxBrush
- # which describes the fill colour of any closed polygon.
-
- # Font styles, families and weight.
- fontweights = {
- 100: wx.FONTWEIGHT_LIGHT,
- 200: wx.FONTWEIGHT_LIGHT,
- 300: wx.FONTWEIGHT_LIGHT,
- 400: wx.FONTWEIGHT_NORMAL,
- 500: wx.FONTWEIGHT_NORMAL,
- 600: wx.FONTWEIGHT_NORMAL,
- 700: wx.FONTWEIGHT_BOLD,
- 800: wx.FONTWEIGHT_BOLD,
- 900: wx.FONTWEIGHT_BOLD,
- 'ultralight': wx.FONTWEIGHT_LIGHT,
- 'light': wx.FONTWEIGHT_LIGHT,
- 'normal': wx.FONTWEIGHT_NORMAL,
- 'medium': wx.FONTWEIGHT_NORMAL,
- 'semibold': wx.FONTWEIGHT_NORMAL,
- 'bold': wx.FONTWEIGHT_BOLD,
- 'heavy': wx.FONTWEIGHT_BOLD,
- 'ultrabold': wx.FONTWEIGHT_BOLD,
- 'black': wx.FONTWEIGHT_BOLD,
- }
- fontangles = {
- 'italic': wx.FONTSTYLE_ITALIC,
- 'normal': wx.FONTSTYLE_NORMAL,
- 'oblique': wx.FONTSTYLE_SLANT,
- }
-
- # wxPython allows for portable font styles, choosing them appropriately for
- # the target platform. Map some standard font names to the portable styles.
- # QUESTION: Is it wise to agree to standard fontnames across all backends?
- fontnames = {
- 'Sans': wx.FONTFAMILY_SWISS,
- 'Roman': wx.FONTFAMILY_ROMAN,
- 'Script': wx.FONTFAMILY_SCRIPT,
- 'Decorative': wx.FONTFAMILY_DECORATIVE,
- 'Modern': wx.FONTFAMILY_MODERN,
- 'Courier': wx.FONTFAMILY_MODERN,
- 'courier': wx.FONTFAMILY_MODERN,
- }
-
- def __init__(self, bitmap, dpi):
- """Initialise a wxWindows renderer instance."""
- super().__init__()
- _log.debug("%s - __init__()", type(self))
- self.width = bitmap.GetWidth()
- self.height = bitmap.GetHeight()
- self.bitmap = bitmap
- self.fontd = {}
- self.dpi = dpi
- self.gc = None
-
- def flipy(self):
- # docstring inherited
- return True
-
- def get_text_width_height_descent(self, s, prop, ismath):
- # docstring inherited
-
- if ismath:
- s = cbook.strip_math(s)
-
- if self.gc is None:
- gc = self.new_gc()
- else:
- gc = self.gc
- gfx_ctx = gc.gfx_ctx
- font = self.get_wx_font(s, prop)
- gfx_ctx.SetFont(font, wx.BLACK)
- w, h, descent, leading = gfx_ctx.GetFullTextExtent(s)
-
- return w, h, descent
-
- def get_canvas_width_height(self):
- # docstring inherited
- return self.width, self.height
-
- def handle_clip_rectangle(self, gc):
- new_bounds = gc.get_clip_rectangle()
- if new_bounds is not None:
- new_bounds = new_bounds.bounds
- gfx_ctx = gc.gfx_ctx
- if gfx_ctx._lastcliprect != new_bounds:
- gfx_ctx._lastcliprect = new_bounds
- if new_bounds is None:
- gfx_ctx.ResetClip()
- else:
- gfx_ctx.Clip(new_bounds[0],
- self.height - new_bounds[1] - new_bounds[3],
- new_bounds[2], new_bounds[3])
-
- @staticmethod
- def convert_path(gfx_ctx, path, transform):
- wxpath = gfx_ctx.CreatePath()
- for points, code in path.iter_segments(transform):
- if code == Path.MOVETO:
- wxpath.MoveToPoint(*points)
- elif code == Path.LINETO:
- wxpath.AddLineToPoint(*points)
- elif code == Path.CURVE3:
- wxpath.AddQuadCurveToPoint(*points)
- elif code == Path.CURVE4:
- wxpath.AddCurveToPoint(*points)
- elif code == Path.CLOSEPOLY:
- wxpath.CloseSubpath()
- return wxpath
-
- def draw_path(self, gc, path, transform, rgbFace=None):
- # docstring inherited
- gc.select()
- self.handle_clip_rectangle(gc)
- gfx_ctx = gc.gfx_ctx
- transform = transform + \
- Affine2D().scale(1.0, -1.0).translate(0.0, self.height)
- wxpath = self.convert_path(gfx_ctx, path, transform)
- if rgbFace is not None:
- gfx_ctx.SetBrush(wx.Brush(gc.get_wxcolour(rgbFace)))
- gfx_ctx.DrawPath(wxpath)
- else:
- gfx_ctx.StrokePath(wxpath)
- gc.unselect()
-
- def draw_image(self, gc, x, y, im):
- bbox = gc.get_clip_rectangle()
- if bbox is not None:
- l, b, w, h = bbox.bounds
- else:
- l = 0
- b = 0
- w = self.width
- h = self.height
- rows, cols = im.shape[:2]
- bitmap = wx.Bitmap.FromBufferRGBA(cols, rows, im.tobytes())
- gc.select()
- gc.gfx_ctx.DrawBitmap(bitmap, int(l), int(self.height - b),
- int(w), int(-h))
- gc.unselect()
-
- def draw_text(self, gc, x, y, s, prop, angle, ismath=False, mtext=None):
- # docstring inherited
-
- if ismath:
- s = cbook.strip_math(s)
- _log.debug("%s - draw_text()", type(self))
- gc.select()
- self.handle_clip_rectangle(gc)
- gfx_ctx = gc.gfx_ctx
-
- font = self.get_wx_font(s, prop)
- color = gc.get_wxcolour(gc.get_rgb())
- gfx_ctx.SetFont(font, color)
-
- w, h, d = self.get_text_width_height_descent(s, prop, ismath)
- x = int(x)
- y = int(y - h)
-
- if angle == 0.0:
- gfx_ctx.DrawText(s, x, y)
- else:
- rads = math.radians(angle)
- xo = h * math.sin(rads)
- yo = h * math.cos(rads)
- gfx_ctx.DrawRotatedText(s, x - xo, y - yo, rads)
-
- gc.unselect()
-
- def new_gc(self):
- # docstring inherited
- _log.debug("%s - new_gc()", type(self))
- self.gc = GraphicsContextWx(self.bitmap, self)
- self.gc.select()
- self.gc.unselect()
- return self.gc
-
- def get_wx_font(self, s, prop):
- """Return a wx font. Cache font instances for efficiency."""
- _log.debug("%s - get_wx_font()", type(self))
- key = hash(prop)
- font = self.fontd.get(key)
- if font is not None:
- return font
- size = self.points_to_pixels(prop.get_size_in_points())
- # Font colour is determined by the active wx.Pen
- # TODO: It may be wise to cache font information
- self.fontd[key] = font = wx.Font( # Cache the font and gc.
- pointSize=round(size),
- family=self.fontnames.get(prop.get_name(), wx.ROMAN),
- style=self.fontangles[prop.get_style()],
- weight=self.fontweights[prop.get_weight()])
- return font
-
- def points_to_pixels(self, points):
- # docstring inherited
- return points * (PIXELS_PER_INCH / 72.0 * self.dpi / 72.0)
-
-
-class GraphicsContextWx(GraphicsContextBase):
- """
- The graphics context provides the color, line styles, etc.
-
- This class stores a reference to a wxMemoryDC, and a
- wxGraphicsContext that draws to it. Creating a wxGraphicsContext
- seems to be fairly heavy, so these objects are cached based on the
- bitmap object that is passed in.
-
- The base GraphicsContext stores colors as an RGB tuple on the unit
- interval, e.g., (0.5, 0.0, 1.0). wxPython uses an int interval, but
- since wxPython colour management is rather simple, I have not chosen
- to implement a separate colour manager class.
- """
- _capd = {'butt': wx.CAP_BUTT,
- 'projecting': wx.CAP_PROJECTING,
- 'round': wx.CAP_ROUND}
-
- _joind = {'bevel': wx.JOIN_BEVEL,
- 'miter': wx.JOIN_MITER,
- 'round': wx.JOIN_ROUND}
-
- _cache = weakref.WeakKeyDictionary()
-
- def __init__(self, bitmap, renderer):
- super().__init__()
- # assert self.Ok(), "wxMemoryDC not OK to use"
- _log.debug("%s - __init__(): %s", type(self), bitmap)
-
- dc, gfx_ctx = self._cache.get(bitmap, (None, None))
- if dc is None:
- dc = wx.MemoryDC(bitmap)
- gfx_ctx = wx.GraphicsContext.Create(dc)
- gfx_ctx._lastcliprect = None
- self._cache[bitmap] = dc, gfx_ctx
-
- self.bitmap = bitmap
- self.dc = dc
- self.gfx_ctx = gfx_ctx
- self._pen = wx.Pen('BLACK', 1, wx.SOLID)
- gfx_ctx.SetPen(self._pen)
- self.renderer = renderer
-
- def select(self):
- """Select the current bitmap into this wxDC instance."""
- if sys.platform == 'win32':
- self.dc.SelectObject(self.bitmap)
- self.IsSelected = True
-
- def unselect(self):
- """Select a Null bitmap into this wxDC instance."""
- if sys.platform == 'win32':
- self.dc.SelectObject(wx.NullBitmap)
- self.IsSelected = False
-
- def set_foreground(self, fg, isRGBA=None):
- # docstring inherited
- # Implementation note: wxPython has a separate concept of pen and
- # brush - the brush fills any outline trace left by the pen.
- # Here we set both to the same colour - if a figure is not to be
- # filled, the renderer will set the brush to be transparent
- # Same goes for text foreground...
- _log.debug("%s - set_foreground()", type(self))
- self.select()
- super().set_foreground(fg, isRGBA)
-
- self._pen.SetColour(self.get_wxcolour(self.get_rgb()))
- self.gfx_ctx.SetPen(self._pen)
- self.unselect()
-
- def set_linewidth(self, w):
- # docstring inherited
- w = float(w)
- _log.debug("%s - set_linewidth()", type(self))
- self.select()
- if 0 < w < 1:
- w = 1
- super().set_linewidth(w)
- lw = int(self.renderer.points_to_pixels(self._linewidth))
- if lw == 0:
- lw = 1
- self._pen.SetWidth(lw)
- self.gfx_ctx.SetPen(self._pen)
- self.unselect()
-
- def set_capstyle(self, cs):
- # docstring inherited
- _log.debug("%s - set_capstyle()", type(self))
- self.select()
- super().set_capstyle(cs)
- self._pen.SetCap(GraphicsContextWx._capd[self._capstyle])
- self.gfx_ctx.SetPen(self._pen)
- self.unselect()
-
- def set_joinstyle(self, js):
- # docstring inherited
- _log.debug("%s - set_joinstyle()", type(self))
- self.select()
- super().set_joinstyle(js)
- self._pen.SetJoin(GraphicsContextWx._joind[self._joinstyle])
- self.gfx_ctx.SetPen(self._pen)
- self.unselect()
-
- def get_wxcolour(self, color):
- """Convert an RGB(A) color to a wx.Colour."""
- _log.debug("%s - get_wx_color()", type(self))
- return wx.Colour(*[int(255 * x) for x in color])
-
-
-class _FigureCanvasWxBase(FigureCanvasBase, wx.Panel):
- """
- The FigureCanvas contains the figure and does event handling.
-
- In the wxPython backend, it is derived from wxPanel, and (usually) lives
- inside a frame instantiated by a FigureManagerWx. The parent window
- probably implements a wx.Sizer to control the displayed control size - but
- we give a hint as to our preferred minimum size.
- """
-
- required_interactive_framework = "wx"
- _timer_cls = TimerWx
- manager_class = _api.classproperty(lambda cls: FigureManagerWx)
-
- keyvald = {
- wx.WXK_CONTROL: 'control',
- wx.WXK_SHIFT: 'shift',
- wx.WXK_ALT: 'alt',
- wx.WXK_CAPITAL: 'caps_lock',
- wx.WXK_LEFT: 'left',
- wx.WXK_UP: 'up',
- wx.WXK_RIGHT: 'right',
- wx.WXK_DOWN: 'down',
- wx.WXK_ESCAPE: 'escape',
- wx.WXK_F1: 'f1',
- wx.WXK_F2: 'f2',
- wx.WXK_F3: 'f3',
- wx.WXK_F4: 'f4',
- wx.WXK_F5: 'f5',
- wx.WXK_F6: 'f6',
- wx.WXK_F7: 'f7',
- wx.WXK_F8: 'f8',
- wx.WXK_F9: 'f9',
- wx.WXK_F10: 'f10',
- wx.WXK_F11: 'f11',
- wx.WXK_F12: 'f12',
- wx.WXK_SCROLL: 'scroll_lock',
- wx.WXK_PAUSE: 'break',
- wx.WXK_BACK: 'backspace',
- wx.WXK_RETURN: 'enter',
- wx.WXK_INSERT: 'insert',
- wx.WXK_DELETE: 'delete',
- wx.WXK_HOME: 'home',
- wx.WXK_END: 'end',
- wx.WXK_PAGEUP: 'pageup',
- wx.WXK_PAGEDOWN: 'pagedown',
- wx.WXK_NUMPAD0: '0',
- wx.WXK_NUMPAD1: '1',
- wx.WXK_NUMPAD2: '2',
- wx.WXK_NUMPAD3: '3',
- wx.WXK_NUMPAD4: '4',
- wx.WXK_NUMPAD5: '5',
- wx.WXK_NUMPAD6: '6',
- wx.WXK_NUMPAD7: '7',
- wx.WXK_NUMPAD8: '8',
- wx.WXK_NUMPAD9: '9',
- wx.WXK_NUMPAD_ADD: '+',
- wx.WXK_NUMPAD_SUBTRACT: '-',
- wx.WXK_NUMPAD_MULTIPLY: '*',
- wx.WXK_NUMPAD_DIVIDE: '/',
- wx.WXK_NUMPAD_DECIMAL: 'dec',
- wx.WXK_NUMPAD_ENTER: 'enter',
- wx.WXK_NUMPAD_UP: 'up',
- wx.WXK_NUMPAD_RIGHT: 'right',
- wx.WXK_NUMPAD_DOWN: 'down',
- wx.WXK_NUMPAD_LEFT: 'left',
- wx.WXK_NUMPAD_PAGEUP: 'pageup',
- wx.WXK_NUMPAD_PAGEDOWN: 'pagedown',
- wx.WXK_NUMPAD_HOME: 'home',
- wx.WXK_NUMPAD_END: 'end',
- wx.WXK_NUMPAD_INSERT: 'insert',
- wx.WXK_NUMPAD_DELETE: 'delete',
- }
-
- def __init__(self, parent, id, figure=None):
- """
- Initialize a FigureWx instance.
-
- - Initialize the FigureCanvasBase and wxPanel parents.
- - Set event handlers for resize, paint, and keyboard and mouse
- interaction.
- """
-
- FigureCanvasBase.__init__(self, figure)
- w, h = map(math.ceil, self.figure.bbox.size)
- # Set preferred window size hint - helps the sizer, if one is connected
- wx.Panel.__init__(self, parent, id, size=wx.Size(w, h))
- # Create the drawing bitmap
- self.bitmap = wx.Bitmap(w, h)
- _log.debug("%s - __init__() - bitmap w:%d h:%d", type(self), w, h)
- self._isDrawn = False
- self._rubberband_rect = None
- self._rubberband_pen_black = wx.Pen('BLACK', 1, wx.PENSTYLE_SHORT_DASH)
- self._rubberband_pen_white = wx.Pen('WHITE', 1, wx.PENSTYLE_SOLID)
-
- self.Bind(wx.EVT_SIZE, self._on_size)
- self.Bind(wx.EVT_PAINT, self._on_paint)
- self.Bind(wx.EVT_CHAR_HOOK, self._on_key_down)
- self.Bind(wx.EVT_KEY_UP, self._on_key_up)
- self.Bind(wx.EVT_LEFT_DOWN, self._on_mouse_button)
- self.Bind(wx.EVT_LEFT_DCLICK, self._on_mouse_button)
- self.Bind(wx.EVT_LEFT_UP, self._on_mouse_button)
- self.Bind(wx.EVT_MIDDLE_DOWN, self._on_mouse_button)
- self.Bind(wx.EVT_MIDDLE_DCLICK, self._on_mouse_button)
- self.Bind(wx.EVT_MIDDLE_UP, self._on_mouse_button)
- self.Bind(wx.EVT_RIGHT_DOWN, self._on_mouse_button)
- self.Bind(wx.EVT_RIGHT_DCLICK, self._on_mouse_button)
- self.Bind(wx.EVT_RIGHT_UP, self._on_mouse_button)
- self.Bind(wx.EVT_MOUSE_AUX1_DOWN, self._on_mouse_button)
- self.Bind(wx.EVT_MOUSE_AUX1_UP, self._on_mouse_button)
- self.Bind(wx.EVT_MOUSE_AUX2_DOWN, self._on_mouse_button)
- self.Bind(wx.EVT_MOUSE_AUX2_UP, self._on_mouse_button)
- self.Bind(wx.EVT_MOUSE_AUX1_DCLICK, self._on_mouse_button)
- self.Bind(wx.EVT_MOUSE_AUX2_DCLICK, self._on_mouse_button)
- self.Bind(wx.EVT_MOUSEWHEEL, self._on_mouse_wheel)
- self.Bind(wx.EVT_MOTION, self._on_motion)
- self.Bind(wx.EVT_ENTER_WINDOW, self._on_enter)
- self.Bind(wx.EVT_LEAVE_WINDOW, self._on_leave)
-
- self.Bind(wx.EVT_MOUSE_CAPTURE_CHANGED, self._on_capture_lost)
- self.Bind(wx.EVT_MOUSE_CAPTURE_LOST, self._on_capture_lost)
-
- self.SetBackgroundStyle(wx.BG_STYLE_PAINT) # Reduce flicker.
- self.SetBackgroundColour(wx.WHITE)
-
- def Copy_to_Clipboard(self, event=None):
- """Copy bitmap of canvas to system clipboard."""
- bmp_obj = wx.BitmapDataObject()
- bmp_obj.SetBitmap(self.bitmap)
-
- if not wx.TheClipboard.IsOpened():
- open_success = wx.TheClipboard.Open()
- if open_success:
- wx.TheClipboard.SetData(bmp_obj)
- wx.TheClipboard.Flush()
- wx.TheClipboard.Close()
-
- def draw_idle(self):
- # docstring inherited
- _log.debug("%s - draw_idle()", type(self))
- self._isDrawn = False # Force redraw
- # Triggering a paint event is all that is needed to defer drawing
- # until later. The platform will send the event when it thinks it is
- # a good time (usually as soon as there are no other events pending).
- self.Refresh(eraseBackground=False)
-
- def flush_events(self):
- # docstring inherited
- wx.Yield()
-
- def start_event_loop(self, timeout=0):
- # docstring inherited
- if hasattr(self, '_event_loop'):
- raise RuntimeError("Event loop already running")
- timer = wx.Timer(self, id=wx.ID_ANY)
- if timeout > 0:
- timer.Start(int(timeout * 1000), oneShot=True)
- self.Bind(wx.EVT_TIMER, self.stop_event_loop, id=timer.GetId())
- # Event loop handler for start/stop event loop
- self._event_loop = wx.GUIEventLoop()
- self._event_loop.Run()
- timer.Stop()
-
- def stop_event_loop(self, event=None):
- # docstring inherited
- if hasattr(self, '_event_loop'):
- if self._event_loop.IsRunning():
- self._event_loop.Exit()
- del self._event_loop
-
- def _get_imagesave_wildcards(self):
- """Return the wildcard string for the filesave dialog."""
- default_filetype = self.get_default_filetype()
- filetypes = self.get_supported_filetypes_grouped()
- sorted_filetypes = sorted(filetypes.items())
- wildcards = []
- extensions = []
- filter_index = 0
- for i, (name, exts) in enumerate(sorted_filetypes):
- ext_list = ';'.join(['*.%s' % ext for ext in exts])
- extensions.append(exts[0])
- wildcard = f'{name} ({ext_list})|{ext_list}'
- if default_filetype in exts:
- filter_index = i
- wildcards.append(wildcard)
- wildcards = '|'.join(wildcards)
- return wildcards, extensions, filter_index
-
- def gui_repaint(self, drawDC=None):
- """
- Update the displayed image on the GUI canvas, using the supplied
- wx.PaintDC device context.
- """
- _log.debug("%s - gui_repaint()", type(self))
- # The "if self" check avoids a "wrapped C/C++ object has been deleted"
- # RuntimeError if doing things after window is closed.
- if not (self and self.IsShownOnScreen()):
- return
- if not drawDC: # not called from OnPaint use a ClientDC
- drawDC = wx.ClientDC(self)
- # For 'WX' backend on Windows, the bitmap cannot be in use by another
- # DC (see GraphicsContextWx._cache).
- bmp = (self.bitmap.ConvertToImage().ConvertToBitmap()
- if wx.Platform == '__WXMSW__'
- and isinstance(self.figure.canvas.get_renderer(), RendererWx)
- else self.bitmap)
- drawDC.DrawBitmap(bmp, 0, 0)
- if self._rubberband_rect is not None:
- # Some versions of wx+python don't support numpy.float64 here.
- x0, y0, x1, y1 = map(round, self._rubberband_rect)
- rect = [(x0, y0, x1, y0), (x1, y0, x1, y1),
- (x0, y0, x0, y1), (x0, y1, x1, y1)]
- drawDC.DrawLineList(rect, self._rubberband_pen_white)
- drawDC.DrawLineList(rect, self._rubberband_pen_black)
-
- filetypes = {
- **FigureCanvasBase.filetypes,
- 'bmp': 'Windows bitmap',
- 'jpeg': 'JPEG',
- 'jpg': 'JPEG',
- 'pcx': 'PCX',
- 'png': 'Portable Network Graphics',
- 'tif': 'Tagged Image Format File',
- 'tiff': 'Tagged Image Format File',
- 'xpm': 'X pixmap',
- }
-
- def _on_paint(self, event):
- """Called when wxPaintEvt is generated."""
- _log.debug("%s - _on_paint()", type(self))
- drawDC = wx.PaintDC(self)
- if not self._isDrawn:
- self.draw(drawDC=drawDC)
- else:
- self.gui_repaint(drawDC=drawDC)
- drawDC.Destroy()
-
- def _on_size(self, event):
- """
- Called when wxEventSize is generated.
-
- In this application we attempt to resize to fit the window, so it
- is better to take the performance hit and redraw the whole window.
- """
-
- _log.debug("%s - _on_size()", type(self))
- sz = self.GetParent().GetSizer()
- if sz:
- si = sz.GetItem(self)
- if sz and si and not si.Proportion and not si.Flag & wx.EXPAND:
- # managed by a sizer, but with a fixed size
- size = self.GetMinSize()
- else:
- # variable size
- size = self.GetClientSize()
- # Do not allow size to become smaller than MinSize
- size.IncTo(self.GetMinSize())
- if getattr(self, "_width", None):
- if size == (self._width, self._height):
- # no change in size
- return
- self._width, self._height = size
- self._isDrawn = False
-
- if self._width <= 1 or self._height <= 1:
- return # Empty figure
-
- # Create a new, correctly sized bitmap
- self.bitmap = wx.Bitmap(self._width, self._height)
-
- dpival = self.figure.dpi
- winch = self._width / dpival
- hinch = self._height / dpival
- self.figure.set_size_inches(winch, hinch, forward=False)
-
- # Rendering will happen on the associated paint event
- # so no need to do anything here except to make sure
- # the whole background is repainted.
- self.Refresh(eraseBackground=False)
- ResizeEvent("resize_event", self)._process()
- self.draw_idle()
-
- @staticmethod
- def _mpl_modifiers(event=None, *, exclude=None):
- mod_table = [
- ("ctrl", wx.MOD_CONTROL, wx.WXK_CONTROL),
- ("alt", wx.MOD_ALT, wx.WXK_ALT),
- ("shift", wx.MOD_SHIFT, wx.WXK_SHIFT),
- ]
- if event is not None:
- modifiers = event.GetModifiers()
- return [name for name, mod, key in mod_table
- if modifiers & mod and exclude != key]
- else:
- return [name for name, mod, key in mod_table
- if wx.GetKeyState(key)]
-
- def _get_key(self, event):
- keyval = event.KeyCode
- if keyval in self.keyvald:
- key = self.keyvald[keyval]
- elif keyval < 256:
- key = chr(keyval)
- # wx always returns an uppercase, so make it lowercase if the shift
- # key is not depressed (NOTE: this will not handle Caps Lock)
- if not event.ShiftDown():
- key = key.lower()
- else:
- return None
- mods = self._mpl_modifiers(event, exclude=keyval)
- if "shift" in mods and key.isupper():
- mods.remove("shift")
- return "+".join([*mods, key])
-
- def _mpl_coords(self, pos=None):
- """
- Convert a wx position, defaulting to the current cursor position, to
- Matplotlib coordinates.
- """
- if pos is None:
- pos = wx.GetMouseState()
- x, y = self.ScreenToClient(pos.X, pos.Y)
- else:
- x, y = pos.X, pos.Y
- # flip y so y=0 is bottom of canvas
- return x, self.figure.bbox.height - y
-
- def _on_key_down(self, event):
- """Capture key press."""
- KeyEvent("key_press_event", self,
- self._get_key(event), *self._mpl_coords(),
- guiEvent=event)._process()
- if self:
- event.Skip()
-
- def _on_key_up(self, event):
- """Release key."""
- KeyEvent("key_release_event", self,
- self._get_key(event), *self._mpl_coords(),
- guiEvent=event)._process()
- if self:
- event.Skip()
-
- def set_cursor(self, cursor):
- # docstring inherited
- cursor = wx.Cursor(_api.check_getitem({
- cursors.MOVE: wx.CURSOR_HAND,
- cursors.HAND: wx.CURSOR_HAND,
- cursors.POINTER: wx.CURSOR_ARROW,
- cursors.SELECT_REGION: wx.CURSOR_CROSS,
- cursors.WAIT: wx.CURSOR_WAIT,
- cursors.RESIZE_HORIZONTAL: wx.CURSOR_SIZEWE,
- cursors.RESIZE_VERTICAL: wx.CURSOR_SIZENS,
- }, cursor=cursor))
- self.SetCursor(cursor)
- self.Refresh()
-
- def _set_capture(self, capture=True):
- """Control wx mouse capture."""
- if self.HasCapture():
- self.ReleaseMouse()
- if capture:
- self.CaptureMouse()
-
- def _on_capture_lost(self, event):
- """Capture changed or lost"""
- self._set_capture(False)
-
- def _on_mouse_button(self, event):
- """Start measuring on an axis."""
- event.Skip()
- self._set_capture(event.ButtonDown() or event.ButtonDClick())
- x, y = self._mpl_coords(event)
- button_map = {
- wx.MOUSE_BTN_LEFT: MouseButton.LEFT,
- wx.MOUSE_BTN_MIDDLE: MouseButton.MIDDLE,
- wx.MOUSE_BTN_RIGHT: MouseButton.RIGHT,
- wx.MOUSE_BTN_AUX1: MouseButton.BACK,
- wx.MOUSE_BTN_AUX2: MouseButton.FORWARD,
- }
- button = event.GetButton()
- button = button_map.get(button, button)
- modifiers = self._mpl_modifiers(event)
- if event.ButtonDown():
- MouseEvent("button_press_event", self, x, y, button,
- modifiers=modifiers, guiEvent=event)._process()
- elif event.ButtonDClick():
- MouseEvent("button_press_event", self, x, y, button,
- dblclick=True, modifiers=modifiers,
- guiEvent=event)._process()
- elif event.ButtonUp():
- MouseEvent("button_release_event", self, x, y, button,
- modifiers=modifiers, guiEvent=event)._process()
-
- def _on_mouse_wheel(self, event):
- """Translate mouse wheel events into matplotlib events"""
- x, y = self._mpl_coords(event)
- # Convert delta/rotation/rate into a floating point step size
- step = event.LinesPerAction * event.WheelRotation / event.WheelDelta
- # Done handling event
- event.Skip()
- # Mac gives two events for every wheel event; skip every second one.
- if wx.Platform == '__WXMAC__':
- if not hasattr(self, '_skipwheelevent'):
- self._skipwheelevent = True
- elif self._skipwheelevent:
- self._skipwheelevent = False
- return # Return without processing event
- else:
- self._skipwheelevent = True
- MouseEvent("scroll_event", self, x, y, step=step,
- modifiers=self._mpl_modifiers(event),
- guiEvent=event)._process()
-
- def _on_motion(self, event):
- """Start measuring on an axis."""
- event.Skip()
- MouseEvent("motion_notify_event", self,
- *self._mpl_coords(event),
- modifiers=self._mpl_modifiers(event),
- guiEvent=event)._process()
-
- def _on_enter(self, event):
- """Mouse has entered the window."""
- event.Skip()
- LocationEvent("figure_enter_event", self,
- *self._mpl_coords(event),
- modifiers=self._mpl_modifiers(),
- guiEvent=event)._process()
-
- def _on_leave(self, event):
- """Mouse has left the window."""
- event.Skip()
- LocationEvent("figure_leave_event", self,
- *self._mpl_coords(event),
- modifiers=self._mpl_modifiers(),
- guiEvent=event)._process()
-
-
-class FigureCanvasWx(_FigureCanvasWxBase):
- # Rendering to a Wx canvas using the deprecated Wx renderer.
-
- def draw(self, drawDC=None):
- """
- Render the figure using RendererWx instance renderer, or using a
- previously defined renderer if none is specified.
- """
- _log.debug("%s - draw()", type(self))
- self.renderer = RendererWx(self.bitmap, self.figure.dpi)
- self.figure.draw(self.renderer)
- self._isDrawn = True
- self.gui_repaint(drawDC=drawDC)
-
- def _print_image(self, filetype, filename):
- bitmap = wx.Bitmap(math.ceil(self.figure.bbox.width),
- math.ceil(self.figure.bbox.height))
- self.figure.draw(RendererWx(bitmap, self.figure.dpi))
- saved_obj = (bitmap.ConvertToImage()
- if cbook.is_writable_file_like(filename)
- else bitmap)
- if not saved_obj.SaveFile(filename, filetype):
- raise RuntimeError(f'Could not save figure to {filename}')
- # draw() is required here since bits of state about the last renderer
- # are strewn about the artist draw methods. Do not remove the draw
- # without first verifying that these have been cleaned up. The artist
- # contains() methods will fail otherwise.
- if self._isDrawn:
- self.draw()
- # The "if self" check avoids a "wrapped C/C++ object has been deleted"
- # RuntimeError if doing things after window is closed.
- if self:
- self.Refresh()
-
- print_bmp = functools.partialmethod(
- _print_image, wx.BITMAP_TYPE_BMP)
- print_jpeg = print_jpg = functools.partialmethod(
- _print_image, wx.BITMAP_TYPE_JPEG)
- print_pcx = functools.partialmethod(
- _print_image, wx.BITMAP_TYPE_PCX)
- print_png = functools.partialmethod(
- _print_image, wx.BITMAP_TYPE_PNG)
- print_tiff = print_tif = functools.partialmethod(
- _print_image, wx.BITMAP_TYPE_TIF)
- print_xpm = functools.partialmethod(
- _print_image, wx.BITMAP_TYPE_XPM)
-
-
-class FigureFrameWx(wx.Frame):
- def __init__(self, num, fig, *, canvas_class):
- # On non-Windows platform, explicitly set the position - fix
- # positioning bug on some Linux platforms
- if wx.Platform == '__WXMSW__':
- pos = wx.DefaultPosition
- else:
- pos = wx.Point(20, 20)
- super().__init__(parent=None, id=-1, pos=pos)
- # Frame will be sized later by the Fit method
- _log.debug("%s - __init__()", type(self))
- _set_frame_icon(self)
-
- self.canvas = canvas_class(self, -1, fig)
- # Auto-attaches itself to self.canvas.manager
- manager = FigureManagerWx(self.canvas, num, self)
-
- toolbar = self.canvas.manager.toolbar
- if toolbar is not None:
- self.SetToolBar(toolbar)
-
- # On Windows, canvas sizing must occur after toolbar addition;
- # otherwise the toolbar further resizes the canvas.
- w, h = map(math.ceil, fig.bbox.size)
- self.canvas.SetInitialSize(wx.Size(w, h))
- self.canvas.SetMinSize((2, 2))
- self.canvas.SetFocus()
-
- self.Fit()
-
- self.Bind(wx.EVT_CLOSE, self._on_close)
-
- def _on_close(self, event):
- _log.debug("%s - on_close()", type(self))
- CloseEvent("close_event", self.canvas)._process()
- self.canvas.stop_event_loop()
- # set FigureManagerWx.frame to None to prevent repeated attempts to
- # close this frame from FigureManagerWx.destroy()
- self.canvas.manager.frame = None
- # remove figure manager from Gcf.figs
- Gcf.destroy(self.canvas.manager)
- try: # See issue 2941338.
- self.canvas.mpl_disconnect(self.canvas.toolbar._id_drag)
- except AttributeError: # If there's no toolbar.
- pass
- # Carry on with close event propagation, frame & children destruction
- event.Skip()
-
-
-class FigureManagerWx(FigureManagerBase):
- """
- Container/controller for the FigureCanvas and GUI frame.
-
- It is instantiated by Gcf whenever a new figure is created. Gcf is
- responsible for managing multiple instances of FigureManagerWx.
-
- Attributes
- ----------
- canvas : `FigureCanvas`
- a FigureCanvasWx(wx.Panel) instance
- window : wxFrame
- a wxFrame instance - wxpython.org/Phoenix/docs/html/Frame.html
- """
-
- def __init__(self, canvas, num, frame):
- _log.debug("%s - __init__()", type(self))
- self.frame = self.window = frame
- super().__init__(canvas, num)
-
- @classmethod
- def create_with_canvas(cls, canvas_class, figure, num):
- # docstring inherited
- wxapp = wx.GetApp() or _create_wxapp()
- frame = FigureFrameWx(num, figure, canvas_class=canvas_class)
- manager = figure.canvas.manager
- if mpl.is_interactive():
- manager.frame.Show()
- figure.canvas.draw_idle()
- return manager
-
- @classmethod
- def start_main_loop(cls):
- if not wx.App.IsMainLoopRunning():
- wxapp = wx.GetApp()
- if wxapp is not None:
- wxapp.MainLoop()
-
- def show(self):
- # docstring inherited
- self.frame.Show()
- self.canvas.draw()
- if mpl.rcParams['figure.raise_window']:
- self.frame.Raise()
-
- def destroy(self, *args):
- # docstring inherited
- _log.debug("%s - destroy()", type(self))
- frame = self.frame
- if frame: # Else, may have been already deleted, e.g. when closing.
- # As this can be called from non-GUI thread from plt.close use
- # wx.CallAfter to ensure thread safety.
- wx.CallAfter(frame.Close)
-
- def full_screen_toggle(self):
- # docstring inherited
- self.frame.ShowFullScreen(not self.frame.IsFullScreen())
-
- def get_window_title(self):
- # docstring inherited
- return self.window.GetTitle()
-
- def set_window_title(self, title):
- # docstring inherited
- self.window.SetTitle(title)
-
- def resize(self, width, height):
- # docstring inherited
- # Directly using SetClientSize doesn't handle the toolbar on Windows.
- self.window.SetSize(self.window.ClientToWindowSize(wx.Size(
- math.ceil(width), math.ceil(height))))
-
-
-def _load_bitmap(filename):
- """
- Load a wx.Bitmap from a file in the "images" directory of the Matplotlib
- data.
- """
- return wx.Bitmap(str(cbook._get_data_path('images', filename)))
-
-
-def _set_frame_icon(frame):
- bundle = wx.IconBundle()
- for image in ('matplotlib.png', 'matplotlib_large.png'):
- icon = wx.Icon(_load_bitmap(image))
- if not icon.IsOk():
- return
- bundle.AddIcon(icon)
- frame.SetIcons(bundle)
-
-
-class NavigationToolbar2Wx(NavigationToolbar2, wx.ToolBar):
- def __init__(self, canvas, coordinates=True, *, style=wx.TB_BOTTOM):
- wx.ToolBar.__init__(self, canvas.GetParent(), -1, style=style)
-
- if 'wxMac' in wx.PlatformInfo:
- self.SetToolBitmapSize((24, 24))
- self.wx_ids = {}
- for text, tooltip_text, image_file, callback in self.toolitems:
- if text is None:
- self.AddSeparator()
- continue
- self.wx_ids[text] = (
- self.AddTool(
- -1,
- bitmap=self._icon(f"{image_file}.png"),
- bmpDisabled=wx.NullBitmap,
- label=text, shortHelp=tooltip_text,
- kind=(wx.ITEM_CHECK if text in ["Pan", "Zoom"]
- else wx.ITEM_NORMAL))
- .Id)
- self.Bind(wx.EVT_TOOL, getattr(self, callback),
- id=self.wx_ids[text])
-
- self._coordinates = coordinates
- if self._coordinates:
- self.AddStretchableSpace()
- self._label_text = wx.StaticText(self, style=wx.ALIGN_RIGHT)
- self.AddControl(self._label_text)
-
- self.Realize()
-
- NavigationToolbar2.__init__(self, canvas)
-
- @staticmethod
- def _icon(name):
- """
- Construct a `wx.Bitmap` suitable for use as icon from an image file
- *name*, including the extension and relative to Matplotlib's "images"
- data directory.
- """
- pilimg = PIL.Image.open(cbook._get_data_path("images", name))
- # ensure RGBA as wx BitMap expects RGBA format
- image = np.array(pilimg.convert("RGBA"))
- try:
- dark = wx.SystemSettings.GetAppearance().IsDark()
- except AttributeError: # wxpython < 4.1
- # copied from wx's IsUsingDarkBackground / GetLuminance.
- bg = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)
- fg = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)
- # See wx.Colour.GetLuminance.
- bg_lum = (.299 * bg.red + .587 * bg.green + .114 * bg.blue) / 255
- fg_lum = (.299 * fg.red + .587 * fg.green + .114 * fg.blue) / 255
- dark = fg_lum - bg_lum > .2
- if dark:
- fg = wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOWTEXT)
- black_mask = (image[..., :3] == 0).all(axis=-1)
- image[black_mask, :3] = (fg.Red(), fg.Green(), fg.Blue())
- return wx.Bitmap.FromBufferRGBA(
- image.shape[1], image.shape[0], image.tobytes())
-
- def _update_buttons_checked(self):
- if "Pan" in self.wx_ids:
- self.ToggleTool(self.wx_ids["Pan"], self.mode.name == "PAN")
- if "Zoom" in self.wx_ids:
- self.ToggleTool(self.wx_ids["Zoom"], self.mode.name == "ZOOM")
-
- def zoom(self, *args):
- super().zoom(*args)
- self._update_buttons_checked()
-
- def pan(self, *args):
- super().pan(*args)
- self._update_buttons_checked()
-
- def save_figure(self, *args):
- # Fetch the required filename and file type.
- filetypes, exts, filter_index = self.canvas._get_imagesave_wildcards()
- default_file = self.canvas.get_default_filename()
- dialog = wx.FileDialog(
- self.canvas.GetParent(), "Save to file",
- mpl.rcParams["savefig.directory"], default_file, filetypes,
- wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
- dialog.SetFilterIndex(filter_index)
- if dialog.ShowModal() == wx.ID_OK:
- path = pathlib.Path(dialog.GetPath())
- _log.debug('%s - Save file path: %s', type(self), path)
- fmt = exts[dialog.GetFilterIndex()]
- ext = path.suffix[1:]
- if ext in self.canvas.get_supported_filetypes() and fmt != ext:
- # looks like they forgot to set the image type drop
- # down, going with the extension.
- _log.warning('extension %s did not match the selected '
- 'image type %s; going with %s',
- ext, fmt, ext)
- fmt = ext
- # Save dir for next time, unless empty str (which means use cwd).
- if mpl.rcParams["savefig.directory"]:
- mpl.rcParams["savefig.directory"] = str(path.parent)
- try:
- self.canvas.figure.savefig(path, format=fmt)
- except Exception as e:
- dialog = wx.MessageDialog(
- parent=self.canvas.GetParent(), message=str(e),
- caption='Matplotlib error')
- dialog.ShowModal()
- dialog.Destroy()
-
- def draw_rubberband(self, event, x0, y0, x1, y1):
- height = self.canvas.figure.bbox.height
- self.canvas._rubberband_rect = (x0, height - y0, x1, height - y1)
- self.canvas.Refresh()
-
- def remove_rubberband(self):
- self.canvas._rubberband_rect = None
- self.canvas.Refresh()
-
- def set_message(self, s):
- if self._coordinates:
- self._label_text.SetLabel(s)
-
- def set_history_buttons(self):
- can_backward = self._nav_stack._pos > 0
- can_forward = self._nav_stack._pos < len(self._nav_stack) - 1
- if 'Back' in self.wx_ids:
- self.EnableTool(self.wx_ids['Back'], can_backward)
- if 'Forward' in self.wx_ids:
- self.EnableTool(self.wx_ids['Forward'], can_forward)
-
-
-# tools for matplotlib.backend_managers.ToolManager:
-
-class ToolbarWx(ToolContainerBase, wx.ToolBar):
- def __init__(self, toolmanager, parent=None, style=wx.TB_BOTTOM):
- if parent is None:
- parent = toolmanager.canvas.GetParent()
- ToolContainerBase.__init__(self, toolmanager)
- wx.ToolBar.__init__(self, parent, -1, style=style)
- self._space = self.AddStretchableSpace()
- self._label_text = wx.StaticText(self, style=wx.ALIGN_RIGHT)
- self.AddControl(self._label_text)
- self._toolitems = {}
- self._groups = {} # Mapping of groups to the separator after them.
-
- def _get_tool_pos(self, tool):
- """
- Find the position (index) of a wx.ToolBarToolBase in a ToolBar.
-
- ``ToolBar.GetToolPos`` is not useful because wx assigns the same Id to
- all Separators and StretchableSpaces.
- """
- pos, = [pos for pos in range(self.ToolsCount)
- if self.GetToolByPos(pos) == tool]
- return pos
-
- def add_toolitem(self, name, group, position, image_file, description,
- toggle):
- # Find or create the separator that follows this group.
- if group not in self._groups:
- self._groups[group] = self.InsertSeparator(
- self._get_tool_pos(self._space))
- sep = self._groups[group]
- # List all separators.
- seps = [t for t in map(self.GetToolByPos, range(self.ToolsCount))
- if t.IsSeparator() and not t.IsStretchableSpace()]
- # Find where to insert the tool.
- if position >= 0:
- # Find the start of the group by looking for the separator
- # preceding this one; then move forward from it.
- start = (0 if sep == seps[0]
- else self._get_tool_pos(seps[seps.index(sep) - 1]) + 1)
- else:
- # Move backwards from this separator.
- start = self._get_tool_pos(sep) + 1
- idx = start + position
- if image_file:
- bmp = NavigationToolbar2Wx._icon(image_file)
- kind = wx.ITEM_NORMAL if not toggle else wx.ITEM_CHECK
- tool = self.InsertTool(idx, -1, name, bmp, wx.NullBitmap, kind,
- description or "")
- else:
- size = (self.GetTextExtent(name)[0] + 10, -1)
- if toggle:
- control = wx.ToggleButton(self, -1, name, size=size)
- else:
- control = wx.Button(self, -1, name, size=size)
- tool = self.InsertControl(idx, control, label=name)
- self.Realize()
-
- def handler(event):
- self.trigger_tool(name)
-
- if image_file:
- self.Bind(wx.EVT_TOOL, handler, tool)
- else:
- control.Bind(wx.EVT_LEFT_DOWN, handler)
-
- self._toolitems.setdefault(name, [])
- self._toolitems[name].append((tool, handler))
-
- def toggle_toolitem(self, name, toggled):
- if name not in self._toolitems:
- return
- for tool, handler in self._toolitems[name]:
- if not tool.IsControl():
- self.ToggleTool(tool.Id, toggled)
- else:
- tool.GetControl().SetValue(toggled)
- self.Refresh()
-
- def remove_toolitem(self, name):
- for tool, handler in self._toolitems[name]:
- self.DeleteTool(tool.Id)
- del self._toolitems[name]
-
- def set_message(self, s):
- self._label_text.SetLabel(s)
-
-
-@backend_tools._register_tool_class(_FigureCanvasWxBase)
-class ConfigureSubplotsWx(backend_tools.ConfigureSubplotsBase):
- def trigger(self, *args):
- NavigationToolbar2Wx.configure_subplots(self)
-
-
-@backend_tools._register_tool_class(_FigureCanvasWxBase)
-class SaveFigureWx(backend_tools.SaveFigureBase):
- def trigger(self, *args):
- NavigationToolbar2Wx.save_figure(
- self._make_classic_style_pseudo_toolbar())
-
-
-@backend_tools._register_tool_class(_FigureCanvasWxBase)
-class RubberbandWx(backend_tools.RubberbandBase):
- def draw_rubberband(self, x0, y0, x1, y1):
- NavigationToolbar2Wx.draw_rubberband(
- self._make_classic_style_pseudo_toolbar(), None, x0, y0, x1, y1)
-
- def remove_rubberband(self):
- NavigationToolbar2Wx.remove_rubberband(
- self._make_classic_style_pseudo_toolbar())
-
-
-class _HelpDialog(wx.Dialog):
- _instance = None # a reference to an open dialog singleton
- headers = [("Action", "Shortcuts", "Description")]
- widths = [100, 140, 300]
-
- def __init__(self, parent, help_entries):
- super().__init__(parent, title="Help",
- style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
-
- sizer = wx.BoxSizer(wx.VERTICAL)
- grid_sizer = wx.FlexGridSizer(0, 3, 8, 6)
- # create and add the entries
- bold = self.GetFont().MakeBold()
- for r, row in enumerate(self.headers + help_entries):
- for (col, width) in zip(row, self.widths):
- label = wx.StaticText(self, label=col)
- if r == 0:
- label.SetFont(bold)
- label.Wrap(width)
- grid_sizer.Add(label, 0, 0, 0)
- # finalize layout, create button
- sizer.Add(grid_sizer, 0, wx.ALL, 6)
- ok = wx.Button(self, wx.ID_OK)
- sizer.Add(ok, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 8)
- self.SetSizer(sizer)
- sizer.Fit(self)
- self.Layout()
- self.Bind(wx.EVT_CLOSE, self._on_close)
- ok.Bind(wx.EVT_BUTTON, self._on_close)
-
- def _on_close(self, event):
- _HelpDialog._instance = None # remove global reference
- self.DestroyLater()
- event.Skip()
-
- @classmethod
- def show(cls, parent, help_entries):
- # if no dialog is shown, create one; otherwise just re-raise it
- if cls._instance:
- cls._instance.Raise()
- return
- cls._instance = cls(parent, help_entries)
- cls._instance.Show()
-
-
-@backend_tools._register_tool_class(_FigureCanvasWxBase)
-class HelpWx(backend_tools.ToolHelpBase):
- def trigger(self, *args):
- _HelpDialog.show(self.figure.canvas.GetTopLevelParent(),
- self._get_help_entries())
-
-
-@backend_tools._register_tool_class(_FigureCanvasWxBase)
-class ToolCopyToClipboardWx(backend_tools.ToolCopyToClipboardBase):
- def trigger(self, *args, **kwargs):
- if not self.canvas._isDrawn:
- self.canvas.draw()
- if not self.canvas.bitmap.IsOk() or not wx.TheClipboard.Open():
- return
- try:
- wx.TheClipboard.SetData(wx.BitmapDataObject(self.canvas.bitmap))
- finally:
- wx.TheClipboard.Close()
-
-
-FigureManagerWx._toolbar2_class = NavigationToolbar2Wx
-FigureManagerWx._toolmanager_toolbar_class = ToolbarWx
-
-
-@_Backend.export
-class _BackendWx(_Backend):
- FigureCanvas = FigureCanvasWx
- FigureManager = FigureManagerWx
- mainloop = FigureManagerWx.start_main_loop
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_wxagg.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_wxagg.py
deleted file mode 100644
index a5a9de0715..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_wxagg.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import wx
-
-from .backend_agg import FigureCanvasAgg
-from .backend_wx import _BackendWx, _FigureCanvasWxBase
-from .backend_wx import ( # noqa: F401 # pylint: disable=W0611
- NavigationToolbar2Wx as NavigationToolbar2WxAgg)
-
-
-class FigureCanvasWxAgg(FigureCanvasAgg, _FigureCanvasWxBase):
- def draw(self, drawDC=None):
- """
- Render the figure using agg.
- """
- FigureCanvasAgg.draw(self)
- self.bitmap = _rgba_to_wx_bitmap(self.get_renderer().buffer_rgba())
- self._isDrawn = True
- self.gui_repaint(drawDC=drawDC)
-
- def blit(self, bbox=None):
- # docstring inherited
- bitmap = _rgba_to_wx_bitmap(self.get_renderer().buffer_rgba())
- if bbox is None:
- self.bitmap = bitmap
- else:
- srcDC = wx.MemoryDC(bitmap)
- destDC = wx.MemoryDC(self.bitmap)
- x = int(bbox.x0)
- y = int(self.bitmap.GetHeight() - bbox.y1)
- destDC.Blit(x, y, int(bbox.width), int(bbox.height), srcDC, x, y)
- destDC.SelectObject(wx.NullBitmap)
- srcDC.SelectObject(wx.NullBitmap)
- self.gui_repaint()
-
-
-def _rgba_to_wx_bitmap(rgba):
- """Convert an RGBA buffer to a wx.Bitmap."""
- h, w, _ = rgba.shape
- return wx.Bitmap.FromBufferRGBA(w, h, rgba)
-
-
-@_BackendWx.export
-class _BackendWxAgg(_BackendWx):
- FigureCanvas = FigureCanvasWxAgg
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/backend_wxcairo.py b/contrib/python/matplotlib/py3/matplotlib/backends/backend_wxcairo.py
deleted file mode 100644
index c53e6af4b8..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/backend_wxcairo.py
+++ /dev/null
@@ -1,23 +0,0 @@
-import wx.lib.wxcairo as wxcairo
-
-from .backend_cairo import cairo, FigureCanvasCairo
-from .backend_wx import _BackendWx, _FigureCanvasWxBase
-from .backend_wx import ( # noqa: F401 # pylint: disable=W0611
- NavigationToolbar2Wx as NavigationToolbar2WxCairo)
-
-
-class FigureCanvasWxCairo(FigureCanvasCairo, _FigureCanvasWxBase):
- def draw(self, drawDC=None):
- size = self.figure.bbox.size.astype(int)
- surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, *size)
- self._renderer.set_context(cairo.Context(surface))
- self._renderer.dpi = self.figure.dpi
- self.figure.draw(self._renderer)
- self.bitmap = wxcairo.BitmapFromImageSurface(surface)
- self._isDrawn = True
- self.gui_repaint(drawDC=drawDC)
-
-
-@_BackendWx.export
-class _BackendWxCairo(_BackendWx):
- FigureCanvas = FigureCanvasWxCairo
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/qt_compat.py b/contrib/python/matplotlib/py3/matplotlib/backends/qt_compat.py
deleted file mode 100644
index d587223ab9..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/qt_compat.py
+++ /dev/null
@@ -1,230 +0,0 @@
-"""
-Qt binding and backend selector.
-
-The selection logic is as follows:
-- if any of PyQt6, PySide6, PyQt5, or PySide2 have already been
- imported (checked in that order), use it;
-- otherwise, if the QT_API environment variable (used by Enthought) is set, use
- it to determine which binding to use;
-- otherwise, use whatever the rcParams indicate.
-"""
-
-import operator
-import os
-import platform
-import sys
-import signal
-import socket
-import contextlib
-
-from packaging.version import parse as parse_version
-
-import matplotlib as mpl
-
-from . import _QT_FORCE_QT5_BINDING
-
-QT_API_PYQT6 = "PyQt6"
-QT_API_PYSIDE6 = "PySide6"
-QT_API_PYQT5 = "PyQt5"
-QT_API_PYSIDE2 = "PySide2"
-QT_API_ENV = os.environ.get("QT_API")
-if QT_API_ENV is not None:
- QT_API_ENV = QT_API_ENV.lower()
-_ETS = { # Mapping of QT_API_ENV to requested binding.
- "pyqt6": QT_API_PYQT6, "pyside6": QT_API_PYSIDE6,
- "pyqt5": QT_API_PYQT5, "pyside2": QT_API_PYSIDE2,
-}
-# First, check if anything is already imported.
-if sys.modules.get("PyQt6.QtCore"):
- QT_API = QT_API_PYQT6
-elif sys.modules.get("PySide6.QtCore"):
- QT_API = QT_API_PYSIDE6
-elif sys.modules.get("PyQt5.QtCore"):
- QT_API = QT_API_PYQT5
-elif sys.modules.get("PySide2.QtCore"):
- QT_API = QT_API_PYSIDE2
-# Otherwise, check the QT_API environment variable (from Enthought). This can
-# only override the binding, not the backend (in other words, we check that the
-# requested backend actually matches). Use _get_backend_or_none to avoid
-# triggering backend resolution (which can result in a partially but
-# incompletely imported backend_qt5).
-elif (mpl.rcParams._get_backend_or_none() or "").lower().startswith("qt5"):
- if QT_API_ENV in ["pyqt5", "pyside2"]:
- QT_API = _ETS[QT_API_ENV]
- else:
- _QT_FORCE_QT5_BINDING = True # noqa
- QT_API = None
-# A non-Qt backend was selected but we still got there (possible, e.g., when
-# fully manually embedding Matplotlib in a Qt app without using pyplot).
-elif QT_API_ENV is None:
- QT_API = None
-elif QT_API_ENV in _ETS:
- QT_API = _ETS[QT_API_ENV]
-else:
- raise RuntimeError(
- "The environment variable QT_API has the unrecognized value {!r}; "
- "valid values are {}".format(QT_API_ENV, ", ".join(_ETS)))
-
-
-def _setup_pyqt5plus():
- global QtCore, QtGui, QtWidgets, __version__
- global _isdeleted, _to_int
-
- if QT_API == QT_API_PYQT6:
- from PyQt6 import QtCore, QtGui, QtWidgets, sip
- __version__ = QtCore.PYQT_VERSION_STR
- QtCore.Signal = QtCore.pyqtSignal
- QtCore.Slot = QtCore.pyqtSlot
- QtCore.Property = QtCore.pyqtProperty
- _isdeleted = sip.isdeleted
- _to_int = operator.attrgetter('value')
- elif QT_API == QT_API_PYSIDE6:
- from PySide6 import QtCore, QtGui, QtWidgets, __version__
- import shiboken6
- def _isdeleted(obj): return not shiboken6.isValid(obj)
- if parse_version(__version__) >= parse_version('6.4'):
- _to_int = operator.attrgetter('value')
- else:
- _to_int = int
- elif QT_API == QT_API_PYQT5:
- from PyQt5 import QtCore, QtGui, QtWidgets
- import sip
- __version__ = QtCore.PYQT_VERSION_STR
- QtCore.Signal = QtCore.pyqtSignal
- QtCore.Slot = QtCore.pyqtSlot
- QtCore.Property = QtCore.pyqtProperty
- _isdeleted = sip.isdeleted
- _to_int = int
- elif QT_API == QT_API_PYSIDE2:
- from PySide2 import QtCore, QtGui, QtWidgets, __version__
- try:
- from PySide2 import shiboken2
- except ImportError:
- import shiboken2
- def _isdeleted(obj):
- return not shiboken2.isValid(obj)
- _to_int = int
- else:
- raise AssertionError(f"Unexpected QT_API: {QT_API}")
-
-
-if QT_API in [QT_API_PYQT6, QT_API_PYQT5, QT_API_PYSIDE6, QT_API_PYSIDE2]:
- _setup_pyqt5plus()
-elif QT_API is None: # See above re: dict.__getitem__.
- if _QT_FORCE_QT5_BINDING:
- _candidates = [
- (_setup_pyqt5plus, QT_API_PYQT5),
- (_setup_pyqt5plus, QT_API_PYSIDE2),
- ]
- else:
- _candidates = [
- (_setup_pyqt5plus, QT_API_PYQT6),
- (_setup_pyqt5plus, QT_API_PYSIDE6),
- (_setup_pyqt5plus, QT_API_PYQT5),
- (_setup_pyqt5plus, QT_API_PYSIDE2),
- ]
- for _setup, QT_API in _candidates:
- try:
- _setup()
- except ImportError:
- continue
- break
- else:
- raise ImportError(
- "Failed to import any of the following Qt binding modules: {}"
- .format(", ".join([QT_API for _, QT_API in _candidates]))
- )
-else: # We should not get there.
- raise AssertionError(f"Unexpected QT_API: {QT_API}")
-_version_info = tuple(QtCore.QLibraryInfo.version().segments())
-
-
-if _version_info < (5, 12):
- raise ImportError(
- f"The Qt version imported is "
- f"{QtCore.QLibraryInfo.version().toString()} but Matplotlib requires "
- f"Qt>=5.12")
-
-
-# Fixes issues with Big Sur
-# https://bugreports.qt.io/browse/QTBUG-87014, fixed in qt 5.15.2
-if (sys.platform == 'darwin' and
- parse_version(platform.mac_ver()[0]) >= parse_version("10.16") and
- _version_info < (5, 15, 2)):
- os.environ.setdefault("QT_MAC_WANTS_LAYER", "1")
-
-
-# Backports.
-
-
-def _exec(obj):
- # exec on PyQt6, exec_ elsewhere.
- obj.exec() if hasattr(obj, "exec") else obj.exec_()
-
-
-@contextlib.contextmanager
-def _maybe_allow_interrupt(qapp):
- """
- This manager allows to terminate a plot by sending a SIGINT. It is
- necessary because the running Qt backend prevents Python interpreter to
- run and process signals (i.e., to raise KeyboardInterrupt exception). To
- solve this one needs to somehow wake up the interpreter and make it close
- the plot window. We do this by using the signal.set_wakeup_fd() function
- which organizes a write of the signal number into a socketpair connected
- to the QSocketNotifier (since it is part of the Qt backend, it can react
- to that write event). Afterwards, the Qt handler empties the socketpair
- by a recv() command to re-arm it (we need this if a signal different from
- SIGINT was caught by set_wakeup_fd() and we shall continue waiting). If
- the SIGINT was caught indeed, after exiting the on_signal() function the
- interpreter reacts to the SIGINT according to the handle() function which
- had been set up by a signal.signal() call: it causes the qt_object to
- exit by calling its quit() method. Finally, we call the old SIGINT
- handler with the same arguments that were given to our custom handle()
- handler.
-
- We do this only if the old handler for SIGINT was not None, which means
- that a non-python handler was installed, i.e. in Julia, and not SIG_IGN
- which means we should ignore the interrupts.
- """
-
- old_sigint_handler = signal.getsignal(signal.SIGINT)
- if old_sigint_handler in (None, signal.SIG_IGN, signal.SIG_DFL):
- yield
- return
-
- handler_args = None
- wsock, rsock = socket.socketpair()
- wsock.setblocking(False)
- rsock.setblocking(False)
- old_wakeup_fd = signal.set_wakeup_fd(wsock.fileno())
- sn = QtCore.QSocketNotifier(rsock.fileno(), QtCore.QSocketNotifier.Type.Read)
-
- # We do not actually care about this value other than running some Python code to
- # ensure that the interpreter has a chance to handle the signal in Python land. We
- # also need to drain the socket because it will be written to as part of the wakeup!
- # There are some cases where this may fire too soon / more than once on Windows so
- # we should be forgiving about reading an empty socket.
- # Clear the socket to re-arm the notifier.
- @sn.activated.connect
- def _may_clear_sock(*args):
- try:
- rsock.recv(1)
- except BlockingIOError:
- pass
-
- def handle(*args):
- nonlocal handler_args
- handler_args = args
- qapp.quit()
-
- signal.signal(signal.SIGINT, handle)
- try:
- yield
- finally:
- wsock.close()
- rsock.close()
- sn.setEnabled(False)
- signal.set_wakeup_fd(old_wakeup_fd)
- signal.signal(signal.SIGINT, old_sigint_handler)
- if handler_args is not None:
- old_sigint_handler(*handler_args)
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/qt_editor/__init__.py b/contrib/python/matplotlib/py3/matplotlib/backends/qt_editor/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/qt_editor/__init__.py
+++ /dev/null
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/qt_editor/_formlayout.py b/contrib/python/matplotlib/py3/matplotlib/backends/qt_editor/_formlayout.py
deleted file mode 100644
index fcf73cefba..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/qt_editor/_formlayout.py
+++ /dev/null
@@ -1,592 +0,0 @@
-"""
-formlayout
-==========
-
-Module creating Qt form dialogs/layouts to edit various type of parameters
-
-
-formlayout License Agreement (MIT License)
-------------------------------------------
-
-Copyright (c) 2009 Pierre Raybaut
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-"""
-
-# History:
-# 1.0.10: added float validator
-# (disable "Ok" and "Apply" button when not valid)
-# 1.0.7: added support for "Apply" button
-# 1.0.6: code cleaning
-
-__version__ = '1.0.10'
-__license__ = __doc__
-
-from ast import literal_eval
-
-import copy
-import datetime
-import logging
-from numbers import Integral, Real
-
-from matplotlib import _api, colors as mcolors
-from matplotlib.backends.qt_compat import _to_int, QtGui, QtWidgets, QtCore
-
-_log = logging.getLogger(__name__)
-
-BLACKLIST = {"title", "label"}
-
-
-class ColorButton(QtWidgets.QPushButton):
- """
- Color choosing push button
- """
- colorChanged = QtCore.Signal(QtGui.QColor)
-
- def __init__(self, parent=None):
- super().__init__(parent)
- self.setFixedSize(20, 20)
- self.setIconSize(QtCore.QSize(12, 12))
- self.clicked.connect(self.choose_color)
- self._color = QtGui.QColor()
-
- def choose_color(self):
- color = QtWidgets.QColorDialog.getColor(
- self._color, self.parentWidget(), "",
- QtWidgets.QColorDialog.ColorDialogOption.ShowAlphaChannel)
- if color.isValid():
- self.set_color(color)
-
- def get_color(self):
- return self._color
-
- @QtCore.Slot(QtGui.QColor)
- def set_color(self, color):
- if color != self._color:
- self._color = color
- self.colorChanged.emit(self._color)
- pixmap = QtGui.QPixmap(self.iconSize())
- pixmap.fill(color)
- self.setIcon(QtGui.QIcon(pixmap))
-
- color = QtCore.Property(QtGui.QColor, get_color, set_color)
-
-
-def to_qcolor(color):
- """Create a QColor from a matplotlib color"""
- qcolor = QtGui.QColor()
- try:
- rgba = mcolors.to_rgba(color)
- except ValueError:
- _api.warn_external(f'Ignoring invalid color {color!r}')
- return qcolor # return invalid QColor
- qcolor.setRgbF(*rgba)
- return qcolor
-
-
-class ColorLayout(QtWidgets.QHBoxLayout):
- """Color-specialized QLineEdit layout"""
- def __init__(self, color, parent=None):
- super().__init__()
- assert isinstance(color, QtGui.QColor)
- self.lineedit = QtWidgets.QLineEdit(
- mcolors.to_hex(color.getRgbF(), keep_alpha=True), parent)
- self.lineedit.editingFinished.connect(self.update_color)
- self.addWidget(self.lineedit)
- self.colorbtn = ColorButton(parent)
- self.colorbtn.color = color
- self.colorbtn.colorChanged.connect(self.update_text)
- self.addWidget(self.colorbtn)
-
- def update_color(self):
- color = self.text()
- qcolor = to_qcolor(color) # defaults to black if not qcolor.isValid()
- self.colorbtn.color = qcolor
-
- def update_text(self, color):
- self.lineedit.setText(mcolors.to_hex(color.getRgbF(), keep_alpha=True))
-
- def text(self):
- return self.lineedit.text()
-
-
-def font_is_installed(font):
- """Check if font is installed"""
- return [fam for fam in QtGui.QFontDatabase().families()
- if str(fam) == font]
-
-
-def tuple_to_qfont(tup):
- """
- Create a QFont from tuple:
- (family [string], size [int], italic [bool], bold [bool])
- """
- if not (isinstance(tup, tuple) and len(tup) == 4
- and font_is_installed(tup[0])
- and isinstance(tup[1], Integral)
- and isinstance(tup[2], bool)
- and isinstance(tup[3], bool)):
- return None
- font = QtGui.QFont()
- family, size, italic, bold = tup
- font.setFamily(family)
- font.setPointSize(size)
- font.setItalic(italic)
- font.setBold(bold)
- return font
-
-
-def qfont_to_tuple(font):
- return (str(font.family()), int(font.pointSize()),
- font.italic(), font.bold())
-
-
-class FontLayout(QtWidgets.QGridLayout):
- """Font selection"""
- def __init__(self, value, parent=None):
- super().__init__()
- font = tuple_to_qfont(value)
- assert font is not None
-
- # Font family
- self.family = QtWidgets.QFontComboBox(parent)
- self.family.setCurrentFont(font)
- self.addWidget(self.family, 0, 0, 1, -1)
-
- # Font size
- self.size = QtWidgets.QComboBox(parent)
- self.size.setEditable(True)
- sizelist = [*range(6, 12), *range(12, 30, 2), 36, 48, 72]
- size = font.pointSize()
- if size not in sizelist:
- sizelist.append(size)
- sizelist.sort()
- self.size.addItems([str(s) for s in sizelist])
- self.size.setCurrentIndex(sizelist.index(size))
- self.addWidget(self.size, 1, 0)
-
- # Italic or not
- self.italic = QtWidgets.QCheckBox(self.tr("Italic"), parent)
- self.italic.setChecked(font.italic())
- self.addWidget(self.italic, 1, 1)
-
- # Bold or not
- self.bold = QtWidgets.QCheckBox(self.tr("Bold"), parent)
- self.bold.setChecked(font.bold())
- self.addWidget(self.bold, 1, 2)
-
- def get_font(self):
- font = self.family.currentFont()
- font.setItalic(self.italic.isChecked())
- font.setBold(self.bold.isChecked())
- font.setPointSize(int(self.size.currentText()))
- return qfont_to_tuple(font)
-
-
-def is_edit_valid(edit):
- text = edit.text()
- state = edit.validator().validate(text, 0)[0]
- return state == QtGui.QDoubleValidator.State.Acceptable
-
-
-class FormWidget(QtWidgets.QWidget):
- update_buttons = QtCore.Signal()
-
- def __init__(self, data, comment="", with_margin=False, parent=None):
- """
- Parameters
- ----------
- data : list of (label, value) pairs
- The data to be edited in the form.
- comment : str, optional
- with_margin : bool, default: False
- If False, the form elements reach to the border of the widget.
- This is the desired behavior if the FormWidget is used as a widget
- alongside with other widgets such as a QComboBox, which also do
- not have a margin around them.
- However, a margin can be desired if the FormWidget is the only
- widget within a container, e.g. a tab in a QTabWidget.
- parent : QWidget or None
- The parent widget.
- """
- super().__init__(parent)
- self.data = copy.deepcopy(data)
- self.widgets = []
- self.formlayout = QtWidgets.QFormLayout(self)
- if not with_margin:
- self.formlayout.setContentsMargins(0, 0, 0, 0)
- if comment:
- self.formlayout.addRow(QtWidgets.QLabel(comment))
- self.formlayout.addRow(QtWidgets.QLabel(" "))
-
- def get_dialog(self):
- """Return FormDialog instance"""
- dialog = self.parent()
- while not isinstance(dialog, QtWidgets.QDialog):
- dialog = dialog.parent()
- return dialog
-
- def setup(self):
- for label, value in self.data:
- if label is None and value is None:
- # Separator: (None, None)
- self.formlayout.addRow(QtWidgets.QLabel(" "),
- QtWidgets.QLabel(" "))
- self.widgets.append(None)
- continue
- elif label is None:
- # Comment
- self.formlayout.addRow(QtWidgets.QLabel(value))
- self.widgets.append(None)
- continue
- elif tuple_to_qfont(value) is not None:
- field = FontLayout(value, self)
- elif (label.lower() not in BLACKLIST
- and mcolors.is_color_like(value)):
- field = ColorLayout(to_qcolor(value), self)
- elif isinstance(value, str):
- field = QtWidgets.QLineEdit(value, self)
- elif isinstance(value, (list, tuple)):
- if isinstance(value, tuple):
- value = list(value)
- # Note: get() below checks the type of value[0] in self.data so
- # it is essential that value gets modified in-place.
- # This means that the code is actually broken in the case where
- # value is a tuple, but fortunately we always pass a list...
- selindex = value.pop(0)
- field = QtWidgets.QComboBox(self)
- if isinstance(value[0], (list, tuple)):
- keys = [key for key, _val in value]
- value = [val for _key, val in value]
- else:
- keys = value
- field.addItems(value)
- if selindex in value:
- selindex = value.index(selindex)
- elif selindex in keys:
- selindex = keys.index(selindex)
- elif not isinstance(selindex, Integral):
- _log.warning(
- "index '%s' is invalid (label: %s, value: %s)",
- selindex, label, value)
- selindex = 0
- field.setCurrentIndex(selindex)
- elif isinstance(value, bool):
- field = QtWidgets.QCheckBox(self)
- field.setChecked(value)
- elif isinstance(value, Integral):
- field = QtWidgets.QSpinBox(self)
- field.setRange(-10**9, 10**9)
- field.setValue(value)
- elif isinstance(value, Real):
- field = QtWidgets.QLineEdit(repr(value), self)
- field.setCursorPosition(0)
- field.setValidator(QtGui.QDoubleValidator(field))
- field.validator().setLocale(QtCore.QLocale("C"))
- dialog = self.get_dialog()
- dialog.register_float_field(field)
- field.textChanged.connect(lambda text: dialog.update_buttons())
- elif isinstance(value, datetime.datetime):
- field = QtWidgets.QDateTimeEdit(self)
- field.setDateTime(value)
- elif isinstance(value, datetime.date):
- field = QtWidgets.QDateEdit(self)
- field.setDate(value)
- else:
- field = QtWidgets.QLineEdit(repr(value), self)
- self.formlayout.addRow(label, field)
- self.widgets.append(field)
-
- def get(self):
- valuelist = []
- for index, (label, value) in enumerate(self.data):
- field = self.widgets[index]
- if label is None:
- # Separator / Comment
- continue
- elif tuple_to_qfont(value) is not None:
- value = field.get_font()
- elif isinstance(value, str) or mcolors.is_color_like(value):
- value = str(field.text())
- elif isinstance(value, (list, tuple)):
- index = int(field.currentIndex())
- if isinstance(value[0], (list, tuple)):
- value = value[index][0]
- else:
- value = value[index]
- elif isinstance(value, bool):
- value = field.isChecked()
- elif isinstance(value, Integral):
- value = int(field.value())
- elif isinstance(value, Real):
- value = float(str(field.text()))
- elif isinstance(value, datetime.datetime):
- datetime_ = field.dateTime()
- if hasattr(datetime_, "toPyDateTime"):
- value = datetime_.toPyDateTime()
- else:
- value = datetime_.toPython()
- elif isinstance(value, datetime.date):
- date_ = field.date()
- if hasattr(date_, "toPyDate"):
- value = date_.toPyDate()
- else:
- value = date_.toPython()
- else:
- value = literal_eval(str(field.text()))
- valuelist.append(value)
- return valuelist
-
-
-class FormComboWidget(QtWidgets.QWidget):
- update_buttons = QtCore.Signal()
-
- def __init__(self, datalist, comment="", parent=None):
- super().__init__(parent)
- layout = QtWidgets.QVBoxLayout()
- self.setLayout(layout)
- self.combobox = QtWidgets.QComboBox()
- layout.addWidget(self.combobox)
-
- self.stackwidget = QtWidgets.QStackedWidget(self)
- layout.addWidget(self.stackwidget)
- self.combobox.currentIndexChanged.connect(
- self.stackwidget.setCurrentIndex)
-
- self.widgetlist = []
- for data, title, comment in datalist:
- self.combobox.addItem(title)
- widget = FormWidget(data, comment=comment, parent=self)
- self.stackwidget.addWidget(widget)
- self.widgetlist.append(widget)
-
- def setup(self):
- for widget in self.widgetlist:
- widget.setup()
-
- def get(self):
- return [widget.get() for widget in self.widgetlist]
-
-
-class FormTabWidget(QtWidgets.QWidget):
- update_buttons = QtCore.Signal()
-
- def __init__(self, datalist, comment="", parent=None):
- super().__init__(parent)
- layout = QtWidgets.QVBoxLayout()
- self.tabwidget = QtWidgets.QTabWidget()
- layout.addWidget(self.tabwidget)
- layout.setContentsMargins(0, 0, 0, 0)
- self.setLayout(layout)
- self.widgetlist = []
- for data, title, comment in datalist:
- if len(data[0]) == 3:
- widget = FormComboWidget(data, comment=comment, parent=self)
- else:
- widget = FormWidget(data, with_margin=True, comment=comment,
- parent=self)
- index = self.tabwidget.addTab(widget, title)
- self.tabwidget.setTabToolTip(index, comment)
- self.widgetlist.append(widget)
-
- def setup(self):
- for widget in self.widgetlist:
- widget.setup()
-
- def get(self):
- return [widget.get() for widget in self.widgetlist]
-
-
-class FormDialog(QtWidgets.QDialog):
- """Form Dialog"""
- def __init__(self, data, title="", comment="",
- icon=None, parent=None, apply=None):
- super().__init__(parent)
-
- self.apply_callback = apply
-
- # Form
- if isinstance(data[0][0], (list, tuple)):
- self.formwidget = FormTabWidget(data, comment=comment,
- parent=self)
- elif len(data[0]) == 3:
- self.formwidget = FormComboWidget(data, comment=comment,
- parent=self)
- else:
- self.formwidget = FormWidget(data, comment=comment,
- parent=self)
- layout = QtWidgets.QVBoxLayout()
- layout.addWidget(self.formwidget)
-
- self.float_fields = []
- self.formwidget.setup()
-
- # Button box
- self.bbox = bbox = QtWidgets.QDialogButtonBox(
- QtWidgets.QDialogButtonBox.StandardButton(
- _to_int(QtWidgets.QDialogButtonBox.StandardButton.Ok) |
- _to_int(QtWidgets.QDialogButtonBox.StandardButton.Cancel)
- ))
- self.formwidget.update_buttons.connect(self.update_buttons)
- if self.apply_callback is not None:
- apply_btn = bbox.addButton(
- QtWidgets.QDialogButtonBox.StandardButton.Apply)
- apply_btn.clicked.connect(self.apply)
-
- bbox.accepted.connect(self.accept)
- bbox.rejected.connect(self.reject)
- layout.addWidget(bbox)
-
- self.setLayout(layout)
-
- self.setWindowTitle(title)
- if not isinstance(icon, QtGui.QIcon):
- icon = QtWidgets.QWidget().style().standardIcon(
- QtWidgets.QStyle.SP_MessageBoxQuestion)
- self.setWindowIcon(icon)
-
- def register_float_field(self, field):
- self.float_fields.append(field)
-
- def update_buttons(self):
- valid = True
- for field in self.float_fields:
- if not is_edit_valid(field):
- valid = False
- for btn_type in ["Ok", "Apply"]:
- btn = self.bbox.button(
- getattr(QtWidgets.QDialogButtonBox.StandardButton,
- btn_type))
- if btn is not None:
- btn.setEnabled(valid)
-
- def accept(self):
- self.data = self.formwidget.get()
- self.apply_callback(self.data)
- super().accept()
-
- def reject(self):
- self.data = None
- super().reject()
-
- def apply(self):
- self.apply_callback(self.formwidget.get())
-
- def get(self):
- """Return form result"""
- return self.data
-
-
-def fedit(data, title="", comment="", icon=None, parent=None, apply=None):
- """
- Create form dialog
-
- data: datalist, datagroup
- title: str
- comment: str
- icon: QIcon instance
- parent: parent QWidget
- apply: apply callback (function)
-
- datalist: list/tuple of (field_name, field_value)
- datagroup: list/tuple of (datalist *or* datagroup, title, comment)
-
- -> one field for each member of a datalist
- -> one tab for each member of a top-level datagroup
- -> one page (of a multipage widget, each page can be selected with a combo
- box) for each member of a datagroup inside a datagroup
-
- Supported types for field_value:
- - int, float, str, bool
- - colors: in Qt-compatible text form, i.e. in hex format or name
- (red, ...) (automatically detected from a string)
- - list/tuple:
- * the first element will be the selected index (or value)
- * the other elements can be couples (key, value) or only values
- """
-
- # Create a QApplication instance if no instance currently exists
- # (e.g., if the module is used directly from the interpreter)
- if QtWidgets.QApplication.startingUp():
- _app = QtWidgets.QApplication([])
- dialog = FormDialog(data, title, comment, icon, parent, apply)
-
- if parent is not None:
- if hasattr(parent, "_fedit_dialog"):
- parent._fedit_dialog.close()
- parent._fedit_dialog = dialog
-
- dialog.show()
-
-
-if __name__ == "__main__":
-
- _app = QtWidgets.QApplication([])
-
- def create_datalist_example():
- return [('str', 'this is a string'),
- ('list', [0, '1', '3', '4']),
- ('list2', ['--', ('none', 'None'), ('--', 'Dashed'),
- ('-.', 'DashDot'), ('-', 'Solid'),
- ('steps', 'Steps'), (':', 'Dotted')]),
- ('float', 1.2),
- (None, 'Other:'),
- ('int', 12),
- ('font', ('Arial', 10, False, True)),
- ('color', '#123409'),
- ('bool', True),
- ('date', datetime.date(2010, 10, 10)),
- ('datetime', datetime.datetime(2010, 10, 10)),
- ]
-
- def create_datagroup_example():
- datalist = create_datalist_example()
- return ((datalist, "Category 1", "Category 1 comment"),
- (datalist, "Category 2", "Category 2 comment"),
- (datalist, "Category 3", "Category 3 comment"))
-
- # --------- datalist example
- datalist = create_datalist_example()
-
- def apply_test(data):
- print("data:", data)
- fedit(datalist, title="Example",
- comment="This is just an <b>example</b>.",
- apply=apply_test)
-
- _app.exec()
-
- # --------- datagroup example
- datagroup = create_datagroup_example()
- fedit(datagroup, "Global title",
- apply=apply_test)
- _app.exec()
-
- # --------- datagroup inside a datagroup example
- datalist = create_datalist_example()
- datagroup = create_datagroup_example()
- fedit(((datagroup, "Title 1", "Tab 1 comment"),
- (datalist, "Title 2", "Tab 2 comment"),
- (datalist, "Title 3", "Tab 3 comment")),
- "Global title",
- apply=apply_test)
- _app.exec()
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/qt_editor/figureoptions.py b/contrib/python/matplotlib/py3/matplotlib/backends/qt_editor/figureoptions.py
deleted file mode 100644
index c744ccc3ca..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/qt_editor/figureoptions.py
+++ /dev/null
@@ -1,263 +0,0 @@
-# Copyright © 2009 Pierre Raybaut
-# Licensed under the terms of the MIT License
-# see the Matplotlib licenses directory for a copy of the license
-
-
-"""Module that provides a GUI-based editor for Matplotlib's figure options."""
-
-from itertools import chain
-from matplotlib import cbook, cm, colors as mcolors, markers, image as mimage
-from matplotlib.backends.qt_compat import QtGui
-from matplotlib.backends.qt_editor import _formlayout
-from matplotlib.dates import DateConverter, num2date
-
-LINESTYLES = {'-': 'Solid',
- '--': 'Dashed',
- '-.': 'DashDot',
- ':': 'Dotted',
- 'None': 'None',
- }
-
-DRAWSTYLES = {
- 'default': 'Default',
- 'steps-pre': 'Steps (Pre)', 'steps': 'Steps (Pre)',
- 'steps-mid': 'Steps (Mid)',
- 'steps-post': 'Steps (Post)'}
-
-MARKERS = markers.MarkerStyle.markers
-
-
-def figure_edit(axes, parent=None):
- """Edit matplotlib figure options"""
- sep = (None, None) # separator
-
- # Get / General
- def convert_limits(lim, converter):
- """Convert axis limits for correct input editors."""
- if isinstance(converter, DateConverter):
- return map(num2date, lim)
- # Cast to builtin floats as they have nicer reprs.
- return map(float, lim)
-
- axis_map = axes._axis_map
- axis_limits = {
- name: tuple(convert_limits(
- getattr(axes, f'get_{name}lim')(), axis.converter
- ))
- for name, axis in axis_map.items()
- }
- general = [
- ('Title', axes.get_title()),
- sep,
- *chain.from_iterable([
- (
- (None, f"<b>{name.title()}-Axis</b>"),
- ('Min', axis_limits[name][0]),
- ('Max', axis_limits[name][1]),
- ('Label', axis.get_label().get_text()),
- ('Scale', [axis.get_scale(),
- 'linear', 'log', 'symlog', 'logit']),
- sep,
- )
- for name, axis in axis_map.items()
- ]),
- ('(Re-)Generate automatic legend', False),
- ]
-
- # Save the converter and unit data
- axis_converter = {
- name: axis.converter
- for name, axis in axis_map.items()
- }
- axis_units = {
- name: axis.get_units()
- for name, axis in axis_map.items()
- }
-
- # Get / Curves
- labeled_lines = []
- for line in axes.get_lines():
- label = line.get_label()
- if label == '_nolegend_':
- continue
- labeled_lines.append((label, line))
- curves = []
-
- def prepare_data(d, init):
- """
- Prepare entry for FormLayout.
-
- *d* is a mapping of shorthands to style names (a single style may
- have multiple shorthands, in particular the shorthands `None`,
- `"None"`, `"none"` and `""` are synonyms); *init* is one shorthand
- of the initial style.
-
- This function returns an list suitable for initializing a
- FormLayout combobox, namely `[initial_name, (shorthand,
- style_name), (shorthand, style_name), ...]`.
- """
- if init not in d:
- d = {**d, init: str(init)}
- # Drop duplicate shorthands from dict (by overwriting them during
- # the dict comprehension).
- name2short = {name: short for short, name in d.items()}
- # Convert back to {shorthand: name}.
- short2name = {short: name for name, short in name2short.items()}
- # Find the kept shorthand for the style specified by init.
- canonical_init = name2short[d[init]]
- # Sort by representation and prepend the initial value.
- return ([canonical_init] +
- sorted(short2name.items(),
- key=lambda short_and_name: short_and_name[1]))
-
- for label, line in labeled_lines:
- color = mcolors.to_hex(
- mcolors.to_rgba(line.get_color(), line.get_alpha()),
- keep_alpha=True)
- ec = mcolors.to_hex(
- mcolors.to_rgba(line.get_markeredgecolor(), line.get_alpha()),
- keep_alpha=True)
- fc = mcolors.to_hex(
- mcolors.to_rgba(line.get_markerfacecolor(), line.get_alpha()),
- keep_alpha=True)
- curvedata = [
- ('Label', label),
- sep,
- (None, '<b>Line</b>'),
- ('Line style', prepare_data(LINESTYLES, line.get_linestyle())),
- ('Draw style', prepare_data(DRAWSTYLES, line.get_drawstyle())),
- ('Width', line.get_linewidth()),
- ('Color (RGBA)', color),
- sep,
- (None, '<b>Marker</b>'),
- ('Style', prepare_data(MARKERS, line.get_marker())),
- ('Size', line.get_markersize()),
- ('Face color (RGBA)', fc),
- ('Edge color (RGBA)', ec)]
- curves.append([curvedata, label, ""])
- # Is there a curve displayed?
- has_curve = bool(curves)
-
- # Get ScalarMappables.
- labeled_mappables = []
- for mappable in [*axes.images, *axes.collections]:
- label = mappable.get_label()
- if label == '_nolegend_' or mappable.get_array() is None:
- continue
- labeled_mappables.append((label, mappable))
- mappables = []
- cmaps = [(cmap, name) for name, cmap in sorted(cm._colormaps.items())]
- for label, mappable in labeled_mappables:
- cmap = mappable.get_cmap()
- if cmap not in cm._colormaps.values():
- cmaps = [(cmap, cmap.name), *cmaps]
- low, high = mappable.get_clim()
- mappabledata = [
- ('Label', label),
- ('Colormap', [cmap.name] + cmaps),
- ('Min. value', low),
- ('Max. value', high),
- ]
- if hasattr(mappable, "get_interpolation"): # Images.
- interpolations = [
- (name, name) for name in sorted(mimage.interpolations_names)]
- mappabledata.append((
- 'Interpolation',
- [mappable.get_interpolation(), *interpolations]))
- mappables.append([mappabledata, label, ""])
- # Is there a scalarmappable displayed?
- has_sm = bool(mappables)
-
- datalist = [(general, "Axes", "")]
- if curves:
- datalist.append((curves, "Curves", ""))
- if mappables:
- datalist.append((mappables, "Images, etc.", ""))
-
- def apply_callback(data):
- """A callback to apply changes."""
- orig_limits = {
- name: getattr(axes, f"get_{name}lim")()
- for name in axis_map
- }
-
- general = data.pop(0)
- curves = data.pop(0) if has_curve else []
- mappables = data.pop(0) if has_sm else []
- if data:
- raise ValueError("Unexpected field")
-
- title = general.pop(0)
- axes.set_title(title)
- generate_legend = general.pop()
-
- for i, (name, axis) in enumerate(axis_map.items()):
- axis_min = general[4*i]
- axis_max = general[4*i + 1]
- axis_label = general[4*i + 2]
- axis_scale = general[4*i + 3]
- if axis.get_scale() != axis_scale:
- getattr(axes, f"set_{name}scale")(axis_scale)
-
- axis._set_lim(axis_min, axis_max, auto=False)
- axis.set_label_text(axis_label)
-
- # Restore the unit data
- axis.converter = axis_converter[name]
- axis.set_units(axis_units[name])
-
- # Set / Curves
- for index, curve in enumerate(curves):
- line = labeled_lines[index][1]
- (label, linestyle, drawstyle, linewidth, color, marker, markersize,
- markerfacecolor, markeredgecolor) = curve
- line.set_label(label)
- line.set_linestyle(linestyle)
- line.set_drawstyle(drawstyle)
- line.set_linewidth(linewidth)
- rgba = mcolors.to_rgba(color)
- line.set_alpha(None)
- line.set_color(rgba)
- if marker != 'none':
- line.set_marker(marker)
- line.set_markersize(markersize)
- line.set_markerfacecolor(markerfacecolor)
- line.set_markeredgecolor(markeredgecolor)
-
- # Set ScalarMappables.
- for index, mappable_settings in enumerate(mappables):
- mappable = labeled_mappables[index][1]
- if len(mappable_settings) == 5:
- label, cmap, low, high, interpolation = mappable_settings
- mappable.set_interpolation(interpolation)
- elif len(mappable_settings) == 4:
- label, cmap, low, high = mappable_settings
- mappable.set_label(label)
- mappable.set_cmap(cmap)
- mappable.set_clim(*sorted([low, high]))
-
- # re-generate legend, if checkbox is checked
- if generate_legend:
- draggable = None
- ncols = 1
- if axes.legend_ is not None:
- old_legend = axes.get_legend()
- draggable = old_legend._draggable is not None
- ncols = old_legend._ncols
- new_legend = axes.legend(ncols=ncols)
- if new_legend:
- new_legend.set_draggable(draggable)
-
- # Redraw
- figure = axes.get_figure()
- figure.canvas.draw()
- for name in axis_map:
- if getattr(axes, f"get_{name}lim")() != orig_limits[name]:
- figure.canvas.toolbar.push_current()
- break
-
- _formlayout.fedit(
- datalist, title="Figure options", parent=parent,
- icon=QtGui.QIcon(
- str(cbook._get_data_path('images', 'qt4_editor_options.svg'))),
- apply=apply_callback)
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/.eslintrc.js b/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/.eslintrc.js
deleted file mode 100644
index 6f3581a1c6..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/.eslintrc.js
+++ /dev/null
@@ -1,32 +0,0 @@
-module.exports = {
- root: true,
- ignorePatterns: ["jquery-ui-*/", "node_modules/"],
- env: {
- browser: true,
- jquery: true,
- },
- extends: ["eslint:recommended", "prettier"],
- globals: {
- IPython: "readonly",
- MozWebSocket: "readonly",
- },
- rules: {
- indent: ["error", 2, { SwitchCase: 1 }],
- "no-unused-vars": [
- "error",
- {
- argsIgnorePattern: "^_",
- },
- ],
- quotes: ["error", "double", { avoidEscape: true }],
- },
- overrides: [
- {
- files: "js/**/*.js",
- rules: {
- indent: ["error", 4, { SwitchCase: 1 }],
- quotes: ["error", "single", { avoidEscape: true }],
- },
- },
- ],
-};
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/.prettierignore b/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/.prettierignore
deleted file mode 100644
index 06a29c66e0..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/.prettierignore
+++ /dev/null
@@ -1,7 +0,0 @@
-node_modules/
-
-# Vendored dependencies
-css/boilerplate.css
-css/fbm.css
-css/page.css
-jquery-ui-*/
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/.prettierrc b/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/.prettierrc
deleted file mode 100644
index fe8d711065..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/.prettierrc
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "overrides": [
- {
- "files": "js/**/*.js",
- "options": {
- "singleQuote": true,
- "tabWidth": 4,
- }
- }
- ]
-}
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/all_figures.html b/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/all_figures.html
deleted file mode 100644
index 62f04b65c9..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/all_figures.html
+++ /dev/null
@@ -1,52 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <link rel="stylesheet" href="{{ prefix }}/_static/css/page.css" type="text/css">
- <link rel="stylesheet" href="{{ prefix }}/_static/css/boilerplate.css" type="text/css">
- <link rel="stylesheet" href="{{ prefix }}/_static/css/fbm.css" type="text/css">
- <link rel="stylesheet" href="{{ prefix }}/_static/css/mpl.css" type="text/css">
- <script src="{{ prefix }}/_static/js/mpl_tornado.js"></script>
- <script src="{{ prefix }}/js/mpl.js"></script>
-
- <script>
- function ready(fn) {
- if (document.readyState != "loading") {
- fn();
- } else {
- document.addEventListener("DOMContentLoaded", fn);
- }
- }
-
- function figure_ready(fig_id) {
- return function () {
- var main_div = document.querySelector("div#figures");
- var figure_div = document.createElement("div");
- figure_div.id = "figure-div";
- main_div.appendChild(figure_div);
- var websocket_type = mpl.get_websocket_type();
- var uri = "{{ ws_uri }}" + fig_id + "/ws";
- if (window.location.protocol === "https:") uri = uri.replace('ws:', 'wss:')
- var websocket = new websocket_type(uri);
- var fig = new mpl.figure(fig_id, websocket, mpl_ondownload, figure_div);
-
- fig.focus_on_mouseover = true;
-
- fig.canvas.setAttribute("tabindex", fig_id);
- }
- };
-
- {% for (fig_id, fig_manager) in figures %}
- ready(figure_ready({{ str(fig_id) }}));
- {% end %}
- </script>
-
- <title>MPL | WebAgg current figures</title>
-
- </head>
- <body>
- <div id="mpl-warnings" class="mpl-warnings"></div>
-
- <div id="figures" style="margin: 10px 10px;"></div>
-
- </body>
-</html>
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/css/boilerplate.css b/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/css/boilerplate.css
deleted file mode 100644
index 2b1535f449..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/css/boilerplate.css
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * HTML5 ✰ Boilerplate
- *
- * style.css contains a reset, font normalization and some base styles.
- *
- * Credit is left where credit is due.
- * Much inspiration was taken from these projects:
- * - yui.yahooapis.com/2.8.1/build/base/base.css
- * - camendesign.com/design/
- * - praegnanz.de/weblog/htmlcssjs-kickstart
- */
-
-
-/**
- * html5doctor.com Reset Stylesheet (Eric Meyer's Reset Reloaded + HTML5 baseline)
- * v1.6.1 2010-09-17 | Authors: Eric Meyer & Richard Clark
- * html5doctor.com/html-5-reset-stylesheet/
- */
-
-html, body, div, span, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
-small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td,
-article, aside, canvas, details, figcaption, figure,
-footer, header, hgroup, menu, nav, section, summary,
-time, mark, audio, video {
- margin: 0;
- padding: 0;
- border: 0;
- font-size: 100%;
- font: inherit;
- vertical-align: baseline;
-}
-
-sup { vertical-align: super; }
-sub { vertical-align: sub; }
-
-article, aside, details, figcaption, figure,
-footer, header, hgroup, menu, nav, section {
- display: block;
-}
-
-blockquote, q { quotes: none; }
-
-blockquote:before, blockquote:after,
-q:before, q:after { content: ""; content: none; }
-
-ins { background-color: #ff9; color: #000; text-decoration: none; }
-
-mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
-
-del { text-decoration: line-through; }
-
-abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
-
-table { border-collapse: collapse; border-spacing: 0; }
-
-hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; }
-
-input, select { vertical-align: middle; }
-
-
-/**
- * Font normalization inspired by YUI Library's fonts.css: developer.yahoo.com/yui/
- */
-
-body { font:13px/1.231 sans-serif; *font-size:small; } /* Hack retained to preserve specificity */
-select, input, textarea, button { font:99% sans-serif; }
-
-/* Normalize monospace sizing:
- en.wikipedia.org/wiki/MediaWiki_talk:Common.css/Archive_11#Teletype_style_fix_for_Chrome */
-pre, code, kbd, samp { font-family: monospace, sans-serif; }
-
-em,i { font-style: italic; }
-b,strong { font-weight: bold; }
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/css/fbm.css b/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/css/fbm.css
deleted file mode 100644
index ce35d99a5e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/css/fbm.css
+++ /dev/null
@@ -1,97 +0,0 @@
-
-/* Flexible box model classes */
-/* Taken from Alex Russell https://infrequently.org/2009/08/css-3-progress/ */
-
-.hbox {
- display: -webkit-box;
- -webkit-box-orient: horizontal;
- -webkit-box-align: stretch;
-
- display: -moz-box;
- -moz-box-orient: horizontal;
- -moz-box-align: stretch;
-
- display: box;
- box-orient: horizontal;
- box-align: stretch;
-}
-
-.hbox > * {
- -webkit-box-flex: 0;
- -moz-box-flex: 0;
- box-flex: 0;
-}
-
-.vbox {
- display: -webkit-box;
- -webkit-box-orient: vertical;
- -webkit-box-align: stretch;
-
- display: -moz-box;
- -moz-box-orient: vertical;
- -moz-box-align: stretch;
-
- display: box;
- box-orient: vertical;
- box-align: stretch;
-}
-
-.vbox > * {
- -webkit-box-flex: 0;
- -moz-box-flex: 0;
- box-flex: 0;
-}
-
-.reverse {
- -webkit-box-direction: reverse;
- -moz-box-direction: reverse;
- box-direction: reverse;
-}
-
-.box-flex0 {
- -webkit-box-flex: 0;
- -moz-box-flex: 0;
- box-flex: 0;
-}
-
-.box-flex1, .box-flex {
- -webkit-box-flex: 1;
- -moz-box-flex: 1;
- box-flex: 1;
-}
-
-.box-flex2 {
- -webkit-box-flex: 2;
- -moz-box-flex: 2;
- box-flex: 2;
-}
-
-.box-group1 {
- -webkit-box-flex-group: 1;
- -moz-box-flex-group: 1;
- box-flex-group: 1;
-}
-
-.box-group2 {
- -webkit-box-flex-group: 2;
- -moz-box-flex-group: 2;
- box-flex-group: 2;
-}
-
-.start {
- -webkit-box-pack: start;
- -moz-box-pack: start;
- box-pack: start;
-}
-
-.end {
- -webkit-box-pack: end;
- -moz-box-pack: end;
- box-pack: end;
-}
-
-.center {
- -webkit-box-pack: center;
- -moz-box-pack: center;
- box-pack: center;
-}
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/css/mpl.css b/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/css/mpl.css
deleted file mode 100644
index e55733d25e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/css/mpl.css
+++ /dev/null
@@ -1,84 +0,0 @@
-/* General styling */
-.ui-helper-clearfix:before,
-.ui-helper-clearfix:after {
- content: "";
- display: table;
- border-collapse: collapse;
-}
-.ui-helper-clearfix:after {
- clear: both;
-}
-
-/* Header */
-.ui-widget-header {
- border: 1px solid #dddddd;
- border-top-left-radius: 6px;
- border-top-right-radius: 6px;
- background: #e9e9e9;
- color: #333333;
- font-weight: bold;
-}
-
-/* Toolbar and items */
-.mpl-toolbar {
- width: 100%;
-}
-
-.mpl-toolbar div.mpl-button-group {
- display: inline-block;
-}
-
-.mpl-button-group + .mpl-button-group {
- margin-left: 0.5em;
-}
-
-.mpl-widget {
- background-color: #fff;
- border: 1px solid #ccc;
- display: inline-block;
- cursor: pointer;
- color: #333;
- padding: 6px;
- vertical-align: middle;
-}
-
-.mpl-widget:disabled,
-.mpl-widget[disabled] {
- background-color: #ddd;
- border-color: #ddd !important;
- cursor: not-allowed;
-}
-
-.mpl-widget:disabled img,
-.mpl-widget[disabled] img {
- /* Convert black to grey */
- filter: contrast(0%);
-}
-
-.mpl-widget.active img {
- /* Convert black to tab:blue, approximately */
- filter: invert(34%) sepia(97%) saturate(468%) hue-rotate(162deg) brightness(96%) contrast(91%);
-}
-
-button.mpl-widget:focus,
-button.mpl-widget:hover {
- background-color: #ddd;
- border-color: #aaa;
-}
-
-.mpl-button-group button.mpl-widget {
- margin-left: -1px;
-}
-.mpl-button-group button.mpl-widget:first-child {
- border-top-left-radius: 6px;
- border-bottom-left-radius: 6px;
- margin-left: 0px;
-}
-.mpl-button-group button.mpl-widget:last-child {
- border-top-right-radius: 6px;
- border-bottom-right-radius: 6px;
-}
-
-select.mpl-widget {
- cursor: default;
-}
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/css/page.css b/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/css/page.css
deleted file mode 100644
index ded0d92203..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/css/page.css
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Primary styles
- *
- * Author: IPython Development Team
- */
-
-
-body {
- background-color: white;
- /* This makes sure that the body covers the entire window and needs to
- be in a different element than the display: box in wrapper below */
- position: absolute;
- left: 0px;
- right: 0px;
- top: 0px;
- bottom: 0px;
- overflow: visible;
-}
-
-
-div#header {
- /* Initially hidden to prevent FLOUC */
- display: none;
- position: relative;
- height: 40px;
- padding: 5px;
- margin: 0px;
- width: 100%;
-}
-
-span#ipython_notebook {
- position: absolute;
- padding: 2px 2px 2px 5px;
-}
-
-span#ipython_notebook img {
- font-family: Verdana, "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif;
- height: 24px;
- text-decoration:none;
- display: inline;
- color: black;
-}
-
-#site {
- width: 100%;
- display: none;
-}
-
-/* We set the fonts by hand here to override the values in the theme */
-.ui-widget {
- font-family: "Lucinda Grande", "Lucinda Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
-}
-
-.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button {
- font-family: "Lucinda Grande", "Lucinda Sans Unicode", Helvetica, Arial, Verdana, sans-serif;
-}
-
-/* Smaller buttons */
-.ui-button .ui-button-text {
- padding: 0.2em 0.8em;
- font-size: 77%;
-}
-
-input.ui-button {
- padding: 0.3em 0.9em;
-}
-
-span#login_widget {
- float: right;
-}
-
-.border-box-sizing {
- box-sizing: border-box;
- -moz-box-sizing: border-box;
- -webkit-box-sizing: border-box;
-}
-
-#figure-div {
- display: inline-block;
- margin: 10px;
- vertical-align: top;
-}
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/ipython_inline_figure.html b/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/ipython_inline_figure.html
deleted file mode 100644
index b941d352a7..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/ipython_inline_figure.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<!-- Within the kernel, we don't know the address of the matplotlib
- websocket server, so we have to get in client-side and fetch our
- resources that way. -->
-<script>
- // We can't proceed until these JavaScript files are fetched, so
- // we fetch them synchronously
- $.ajaxSetup({async: false});
- $.getScript("http://" + window.location.hostname + ":{{ port }}{{prefix}}/_static/js/mpl_tornado.js");
- $.getScript("http://" + window.location.hostname + ":{{ port }}{{prefix}}/js/mpl.js");
- $.ajaxSetup({async: true});
-
- function init_figure{{ fig_id }}(e) {
- $('div.output').off('resize');
-
- var output_div = e.target.querySelector('div.output_subarea');
- var websocket_type = mpl.get_websocket_type();
- var websocket = new websocket_type(
- "ws://" + window.location.hostname + ":{{ port }}{{ prefix}}/" +
- {{ repr(str(fig_id)) }} + "/ws");
-
- var fig = new mpl.figure(
- {{repr(str(fig_id))}}, websocket, mpl_ondownload, output_div);
-
- // Fetch the first image
- fig.context.drawImage(fig.imageObj, 0, 0);
-
- fig.focus_on_mouseover = true;
- }
-
- // We can't initialize the figure contents until our content
- // has been added to the DOM. This is a bit of hack to get an
- // event for that.
- $('div.output').resize(init_figure{{ fig_id }});
-</script>
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/js/mpl.js b/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/js/mpl.js
deleted file mode 100644
index 140f590385..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/js/mpl.js
+++ /dev/null
@@ -1,695 +0,0 @@
-/* Put everything inside the global mpl namespace */
-/* global mpl */
-window.mpl = {};
-
-mpl.get_websocket_type = function () {
- if (typeof WebSocket !== 'undefined') {
- return WebSocket;
- } else if (typeof MozWebSocket !== 'undefined') {
- return MozWebSocket;
- } else {
- alert(
- 'Your browser does not have WebSocket support. ' +
- 'Please try Chrome, Safari or Firefox ≥ 6. ' +
- 'Firefox 4 and 5 are also supported but you ' +
- 'have to enable WebSockets in about:config.'
- );
- }
-};
-
-mpl.figure = function (figure_id, websocket, ondownload, parent_element) {
- this.id = figure_id;
-
- this.ws = websocket;
-
- this.supports_binary = this.ws.binaryType !== undefined;
-
- if (!this.supports_binary) {
- var warnings = document.getElementById('mpl-warnings');
- if (warnings) {
- warnings.style.display = 'block';
- warnings.textContent =
- 'This browser does not support binary websocket messages. ' +
- 'Performance may be slow.';
- }
- }
-
- this.imageObj = new Image();
-
- this.context = undefined;
- this.message = undefined;
- this.canvas = undefined;
- this.rubberband_canvas = undefined;
- this.rubberband_context = undefined;
- this.format_dropdown = undefined;
-
- this.image_mode = 'full';
-
- this.root = document.createElement('div');
- this.root.setAttribute('style', 'display: inline-block');
- this._root_extra_style(this.root);
-
- parent_element.appendChild(this.root);
-
- this._init_header(this);
- this._init_canvas(this);
- this._init_toolbar(this);
-
- var fig = this;
-
- this.waiting = false;
-
- this.ws.onopen = function () {
- fig.send_message('supports_binary', { value: fig.supports_binary });
- fig.send_message('send_image_mode', {});
- if (fig.ratio !== 1) {
- fig.send_message('set_device_pixel_ratio', {
- device_pixel_ratio: fig.ratio,
- });
- }
- fig.send_message('refresh', {});
- };
-
- this.imageObj.onload = function () {
- if (fig.image_mode === 'full') {
- // Full images could contain transparency (where diff images
- // almost always do), so we need to clear the canvas so that
- // there is no ghosting.
- fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);
- }
- fig.context.drawImage(fig.imageObj, 0, 0);
- };
-
- this.imageObj.onunload = function () {
- fig.ws.close();
- };
-
- this.ws.onmessage = this._make_on_message_function(this);
-
- this.ondownload = ondownload;
-};
-
-mpl.figure.prototype._init_header = function () {
- var titlebar = document.createElement('div');
- titlebar.classList =
- 'ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix';
- var titletext = document.createElement('div');
- titletext.classList = 'ui-dialog-title';
- titletext.setAttribute(
- 'style',
- 'width: 100%; text-align: center; padding: 3px;'
- );
- titlebar.appendChild(titletext);
- this.root.appendChild(titlebar);
- this.header = titletext;
-};
-
-mpl.figure.prototype._canvas_extra_style = function (_canvas_div) {};
-
-mpl.figure.prototype._root_extra_style = function (_canvas_div) {};
-
-mpl.figure.prototype._init_canvas = function () {
- var fig = this;
-
- var canvas_div = (this.canvas_div = document.createElement('div'));
- canvas_div.setAttribute('tabindex', '0');
- canvas_div.setAttribute(
- 'style',
- 'border: 1px solid #ddd;' +
- 'box-sizing: content-box;' +
- 'clear: both;' +
- 'min-height: 1px;' +
- 'min-width: 1px;' +
- 'outline: 0;' +
- 'overflow: hidden;' +
- 'position: relative;' +
- 'resize: both;' +
- 'z-index: 2;'
- );
-
- function on_keyboard_event_closure(name) {
- return function (event) {
- return fig.key_event(event, name);
- };
- }
-
- canvas_div.addEventListener(
- 'keydown',
- on_keyboard_event_closure('key_press')
- );
- canvas_div.addEventListener(
- 'keyup',
- on_keyboard_event_closure('key_release')
- );
-
- this._canvas_extra_style(canvas_div);
- this.root.appendChild(canvas_div);
-
- var canvas = (this.canvas = document.createElement('canvas'));
- canvas.classList.add('mpl-canvas');
- canvas.setAttribute(
- 'style',
- 'box-sizing: content-box;' +
- 'pointer-events: none;' +
- 'position: relative;' +
- 'z-index: 0;'
- );
-
- this.context = canvas.getContext('2d');
-
- var backingStore =
- this.context.backingStorePixelRatio ||
- this.context.webkitBackingStorePixelRatio ||
- this.context.mozBackingStorePixelRatio ||
- this.context.msBackingStorePixelRatio ||
- this.context.oBackingStorePixelRatio ||
- this.context.backingStorePixelRatio ||
- 1;
-
- this.ratio = (window.devicePixelRatio || 1) / backingStore;
-
- var rubberband_canvas = (this.rubberband_canvas = document.createElement(
- 'canvas'
- ));
- rubberband_canvas.setAttribute(
- 'style',
- 'box-sizing: content-box;' +
- 'left: 0;' +
- 'pointer-events: none;' +
- 'position: absolute;' +
- 'top: 0;' +
- 'z-index: 1;'
- );
-
- // Apply a ponyfill if ResizeObserver is not implemented by browser.
- if (this.ResizeObserver === undefined) {
- if (window.ResizeObserver !== undefined) {
- this.ResizeObserver = window.ResizeObserver;
- } else {
- var obs = _JSXTOOLS_RESIZE_OBSERVER({});
- this.ResizeObserver = obs.ResizeObserver;
- }
- }
-
- this.resizeObserverInstance = new this.ResizeObserver(function (entries) {
- var nentries = entries.length;
- for (var i = 0; i < nentries; i++) {
- var entry = entries[i];
- var width, height;
- if (entry.contentBoxSize) {
- if (entry.contentBoxSize instanceof Array) {
- // Chrome 84 implements new version of spec.
- width = entry.contentBoxSize[0].inlineSize;
- height = entry.contentBoxSize[0].blockSize;
- } else {
- // Firefox implements old version of spec.
- width = entry.contentBoxSize.inlineSize;
- height = entry.contentBoxSize.blockSize;
- }
- } else {
- // Chrome <84 implements even older version of spec.
- width = entry.contentRect.width;
- height = entry.contentRect.height;
- }
-
- // Keep the size of the canvas and rubber band canvas in sync with
- // the canvas container.
- if (entry.devicePixelContentBoxSize) {
- // Chrome 84 implements new version of spec.
- canvas.setAttribute(
- 'width',
- entry.devicePixelContentBoxSize[0].inlineSize
- );
- canvas.setAttribute(
- 'height',
- entry.devicePixelContentBoxSize[0].blockSize
- );
- } else {
- canvas.setAttribute('width', width * fig.ratio);
- canvas.setAttribute('height', height * fig.ratio);
- }
- /* This rescales the canvas back to display pixels, so that it
- * appears correct on HiDPI screens. */
- canvas.style.width = width + 'px';
- canvas.style.height = height + 'px';
-
- rubberband_canvas.setAttribute('width', width);
- rubberband_canvas.setAttribute('height', height);
-
- // And update the size in Python. We ignore the initial 0/0 size
- // that occurs as the element is placed into the DOM, which should
- // otherwise not happen due to the minimum size styling.
- if (fig.ws.readyState == 1 && width != 0 && height != 0) {
- fig.request_resize(width, height);
- }
- }
- });
- this.resizeObserverInstance.observe(canvas_div);
-
- function on_mouse_event_closure(name) {
- /* User Agent sniffing is bad, but WebKit is busted:
- * https://bugs.webkit.org/show_bug.cgi?id=144526
- * https://bugs.webkit.org/show_bug.cgi?id=181818
- * The worst that happens here is that they get an extra browser
- * selection when dragging, if this check fails to catch them.
- */
- var UA = navigator.userAgent;
- var isWebKit = /AppleWebKit/.test(UA) && !/Chrome/.test(UA);
- if(isWebKit) {
- return function (event) {
- /* This prevents the web browser from automatically changing to
- * the text insertion cursor when the button is pressed. We
- * want to control all of the cursor setting manually through
- * the 'cursor' event from matplotlib */
- event.preventDefault()
- return fig.mouse_event(event, name);
- };
- } else {
- return function (event) {
- return fig.mouse_event(event, name);
- };
- }
- }
-
- canvas_div.addEventListener(
- 'mousedown',
- on_mouse_event_closure('button_press')
- );
- canvas_div.addEventListener(
- 'mouseup',
- on_mouse_event_closure('button_release')
- );
- canvas_div.addEventListener(
- 'dblclick',
- on_mouse_event_closure('dblclick')
- );
- // Throttle sequential mouse events to 1 every 20ms.
- canvas_div.addEventListener(
- 'mousemove',
- on_mouse_event_closure('motion_notify')
- );
-
- canvas_div.addEventListener(
- 'mouseenter',
- on_mouse_event_closure('figure_enter')
- );
- canvas_div.addEventListener(
- 'mouseleave',
- on_mouse_event_closure('figure_leave')
- );
-
- canvas_div.addEventListener('wheel', function (event) {
- if (event.deltaY < 0) {
- event.step = 1;
- } else {
- event.step = -1;
- }
- on_mouse_event_closure('scroll')(event);
- });
-
- canvas_div.appendChild(canvas);
- canvas_div.appendChild(rubberband_canvas);
-
- this.rubberband_context = rubberband_canvas.getContext('2d');
- this.rubberband_context.strokeStyle = '#000000';
-
- this._resize_canvas = function (width, height, forward) {
- if (forward) {
- canvas_div.style.width = width + 'px';
- canvas_div.style.height = height + 'px';
- }
- };
-
- // Disable right mouse context menu.
- canvas_div.addEventListener('contextmenu', function (_e) {
- event.preventDefault();
- return false;
- });
-
- function set_focus() {
- canvas.focus();
- canvas_div.focus();
- }
-
- window.setTimeout(set_focus, 100);
-};
-
-mpl.figure.prototype._init_toolbar = function () {
- var fig = this;
-
- var toolbar = document.createElement('div');
- toolbar.classList = 'mpl-toolbar';
- this.root.appendChild(toolbar);
-
- function on_click_closure(name) {
- return function (_event) {
- return fig.toolbar_button_onclick(name);
- };
- }
-
- function on_mouseover_closure(tooltip) {
- return function (event) {
- if (!event.currentTarget.disabled) {
- return fig.toolbar_button_onmouseover(tooltip);
- }
- };
- }
-
- fig.buttons = {};
- var buttonGroup = document.createElement('div');
- buttonGroup.classList = 'mpl-button-group';
- for (var toolbar_ind in mpl.toolbar_items) {
- var name = mpl.toolbar_items[toolbar_ind][0];
- var tooltip = mpl.toolbar_items[toolbar_ind][1];
- var image = mpl.toolbar_items[toolbar_ind][2];
- var method_name = mpl.toolbar_items[toolbar_ind][3];
-
- if (!name) {
- /* Instead of a spacer, we start a new button group. */
- if (buttonGroup.hasChildNodes()) {
- toolbar.appendChild(buttonGroup);
- }
- buttonGroup = document.createElement('div');
- buttonGroup.classList = 'mpl-button-group';
- continue;
- }
-
- var button = (fig.buttons[name] = document.createElement('button'));
- button.classList = 'mpl-widget';
- button.setAttribute('role', 'button');
- button.setAttribute('aria-disabled', 'false');
- button.addEventListener('click', on_click_closure(method_name));
- button.addEventListener('mouseover', on_mouseover_closure(tooltip));
-
- var icon_img = document.createElement('img');
- icon_img.src = '_images/' + image + '.png';
- icon_img.srcset = '_images/' + image + '_large.png 2x';
- icon_img.alt = tooltip;
- button.appendChild(icon_img);
-
- buttonGroup.appendChild(button);
- }
-
- if (buttonGroup.hasChildNodes()) {
- toolbar.appendChild(buttonGroup);
- }
-
- var fmt_picker = document.createElement('select');
- fmt_picker.classList = 'mpl-widget';
- toolbar.appendChild(fmt_picker);
- this.format_dropdown = fmt_picker;
-
- for (var ind in mpl.extensions) {
- var fmt = mpl.extensions[ind];
- var option = document.createElement('option');
- option.selected = fmt === mpl.default_extension;
- option.innerHTML = fmt;
- fmt_picker.appendChild(option);
- }
-
- var status_bar = document.createElement('span');
- status_bar.classList = 'mpl-message';
- toolbar.appendChild(status_bar);
- this.message = status_bar;
-};
-
-mpl.figure.prototype.request_resize = function (x_pixels, y_pixels) {
- // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client,
- // which will in turn request a refresh of the image.
- this.send_message('resize', { width: x_pixels, height: y_pixels });
-};
-
-mpl.figure.prototype.send_message = function (type, properties) {
- properties['type'] = type;
- properties['figure_id'] = this.id;
- this.ws.send(JSON.stringify(properties));
-};
-
-mpl.figure.prototype.send_draw_message = function () {
- if (!this.waiting) {
- this.waiting = true;
- this.ws.send(JSON.stringify({ type: 'draw', figure_id: this.id }));
- }
-};
-
-mpl.figure.prototype.handle_save = function (fig, _msg) {
- var format_dropdown = fig.format_dropdown;
- var format = format_dropdown.options[format_dropdown.selectedIndex].value;
- fig.ondownload(fig, format);
-};
-
-mpl.figure.prototype.handle_resize = function (fig, msg) {
- var size = msg['size'];
- if (size[0] !== fig.canvas.width || size[1] !== fig.canvas.height) {
- fig._resize_canvas(size[0], size[1], msg['forward']);
- fig.send_message('refresh', {});
- }
-};
-
-mpl.figure.prototype.handle_rubberband = function (fig, msg) {
- var x0 = msg['x0'] / fig.ratio;
- var y0 = (fig.canvas.height - msg['y0']) / fig.ratio;
- var x1 = msg['x1'] / fig.ratio;
- var y1 = (fig.canvas.height - msg['y1']) / fig.ratio;
- x0 = Math.floor(x0) + 0.5;
- y0 = Math.floor(y0) + 0.5;
- x1 = Math.floor(x1) + 0.5;
- y1 = Math.floor(y1) + 0.5;
- var min_x = Math.min(x0, x1);
- var min_y = Math.min(y0, y1);
- var width = Math.abs(x1 - x0);
- var height = Math.abs(y1 - y0);
-
- fig.rubberband_context.clearRect(
- 0,
- 0,
- fig.canvas.width / fig.ratio,
- fig.canvas.height / fig.ratio
- );
-
- fig.rubberband_context.strokeRect(min_x, min_y, width, height);
-};
-
-mpl.figure.prototype.handle_figure_label = function (fig, msg) {
- // Updates the figure title.
- fig.header.textContent = msg['label'];
-};
-
-mpl.figure.prototype.handle_cursor = function (fig, msg) {
- fig.canvas_div.style.cursor = msg['cursor'];
-};
-
-mpl.figure.prototype.handle_message = function (fig, msg) {
- fig.message.textContent = msg['message'];
-};
-
-mpl.figure.prototype.handle_draw = function (fig, _msg) {
- // Request the server to send over a new figure.
- fig.send_draw_message();
-};
-
-mpl.figure.prototype.handle_image_mode = function (fig, msg) {
- fig.image_mode = msg['mode'];
-};
-
-mpl.figure.prototype.handle_history_buttons = function (fig, msg) {
- for (var key in msg) {
- if (!(key in fig.buttons)) {
- continue;
- }
- fig.buttons[key].disabled = !msg[key];
- fig.buttons[key].setAttribute('aria-disabled', !msg[key]);
- }
-};
-
-mpl.figure.prototype.handle_navigate_mode = function (fig, msg) {
- if (msg['mode'] === 'PAN') {
- fig.buttons['Pan'].classList.add('active');
- fig.buttons['Zoom'].classList.remove('active');
- } else if (msg['mode'] === 'ZOOM') {
- fig.buttons['Pan'].classList.remove('active');
- fig.buttons['Zoom'].classList.add('active');
- } else {
- fig.buttons['Pan'].classList.remove('active');
- fig.buttons['Zoom'].classList.remove('active');
- }
-};
-
-mpl.figure.prototype.updated_canvas_event = function () {
- // Called whenever the canvas gets updated.
- this.send_message('ack', {});
-};
-
-// A function to construct a web socket function for onmessage handling.
-// Called in the figure constructor.
-mpl.figure.prototype._make_on_message_function = function (fig) {
- return function socket_on_message(evt) {
- if (evt.data instanceof Blob) {
- var img = evt.data;
- if (img.type !== 'image/png') {
- /* FIXME: We get "Resource interpreted as Image but
- * transferred with MIME type text/plain:" errors on
- * Chrome. But how to set the MIME type? It doesn't seem
- * to be part of the websocket stream */
- img.type = 'image/png';
- }
-
- /* Free the memory for the previous frames */
- if (fig.imageObj.src) {
- (window.URL || window.webkitURL).revokeObjectURL(
- fig.imageObj.src
- );
- }
-
- fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL(
- img
- );
- fig.updated_canvas_event();
- fig.waiting = false;
- return;
- } else if (
- typeof evt.data === 'string' &&
- evt.data.slice(0, 21) === 'data:image/png;base64'
- ) {
- fig.imageObj.src = evt.data;
- fig.updated_canvas_event();
- fig.waiting = false;
- return;
- }
-
- var msg = JSON.parse(evt.data);
- var msg_type = msg['type'];
-
- // Call the "handle_{type}" callback, which takes
- // the figure and JSON message as its only arguments.
- try {
- var callback = fig['handle_' + msg_type];
- } catch (e) {
- console.log(
- "No handler for the '" + msg_type + "' message type: ",
- msg
- );
- return;
- }
-
- if (callback) {
- try {
- // console.log("Handling '" + msg_type + "' message: ", msg);
- callback(fig, msg);
- } catch (e) {
- console.log(
- "Exception inside the 'handler_" + msg_type + "' callback:",
- e,
- e.stack,
- msg
- );
- }
- }
- };
-};
-
-function getModifiers(event) {
- var mods = [];
- if (event.ctrlKey) {
- mods.push('ctrl');
- }
- if (event.altKey) {
- mods.push('alt');
- }
- if (event.shiftKey) {
- mods.push('shift');
- }
- if (event.metaKey) {
- mods.push('meta');
- }
- return mods;
-}
-
-/*
- * return a copy of an object with only non-object keys
- * we need this to avoid circular references
- * https://stackoverflow.com/a/24161582/3208463
- */
-function simpleKeys(original) {
- return Object.keys(original).reduce(function (obj, key) {
- if (typeof original[key] !== 'object') {
- obj[key] = original[key];
- }
- return obj;
- }, {});
-}
-
-mpl.figure.prototype.mouse_event = function (event, name) {
- if (name === 'button_press') {
- this.canvas.focus();
- this.canvas_div.focus();
- }
-
- // from https://stackoverflow.com/q/1114465
- var boundingRect = this.canvas.getBoundingClientRect();
- var x = (event.clientX - boundingRect.left) * this.ratio;
- var y = (event.clientY - boundingRect.top) * this.ratio;
-
- this.send_message(name, {
- x: x,
- y: y,
- button: event.button,
- step: event.step,
- modifiers: getModifiers(event),
- guiEvent: simpleKeys(event),
- });
-
- return false;
-};
-
-mpl.figure.prototype._key_event_extra = function (_event, _name) {
- // Handle any extra behaviour associated with a key event
-};
-
-mpl.figure.prototype.key_event = function (event, name) {
- // Prevent repeat events
- if (name === 'key_press') {
- if (event.key === this._key) {
- return;
- } else {
- this._key = event.key;
- }
- }
- if (name === 'key_release') {
- this._key = null;
- }
-
- var value = '';
- if (event.ctrlKey && event.key !== 'Control') {
- value += 'ctrl+';
- }
- else if (event.altKey && event.key !== 'Alt') {
- value += 'alt+';
- }
- else if (event.shiftKey && event.key !== 'Shift') {
- value += 'shift+';
- }
-
- value += 'k' + event.key;
-
- this._key_event_extra(event, name);
-
- this.send_message(name, { key: value, guiEvent: simpleKeys(event) });
- return false;
-};
-
-mpl.figure.prototype.toolbar_button_onclick = function (name) {
- if (name === 'download') {
- this.handle_save(this, null);
- } else {
- this.send_message('toolbar_button', { name: name });
- }
-};
-
-mpl.figure.prototype.toolbar_button_onmouseover = function (tooltip) {
- this.message.textContent = tooltip;
-};
-
-///////////////// REMAINING CONTENT GENERATED BY embed_js.py /////////////////
-// prettier-ignore
-var _JSXTOOLS_RESIZE_OBSERVER=function(A){var t,i=new WeakMap,n=new WeakMap,a=new WeakMap,r=new WeakMap,o=new Set;function s(e){if(!(this instanceof s))throw new TypeError("Constructor requires 'new' operator");i.set(this,e)}function h(){throw new TypeError("Function is not a constructor")}function c(e,t,i,n){e=0 in arguments?Number(arguments[0]):0,t=1 in arguments?Number(arguments[1]):0,i=2 in arguments?Number(arguments[2]):0,n=3 in arguments?Number(arguments[3]):0,this.right=(this.x=this.left=e)+(this.width=i),this.bottom=(this.y=this.top=t)+(this.height=n),Object.freeze(this)}function d(){t=requestAnimationFrame(d);var s=new WeakMap,p=new Set;o.forEach((function(t){r.get(t).forEach((function(i){var r=t instanceof window.SVGElement,o=a.get(t),d=r?0:parseFloat(o.paddingTop),f=r?0:parseFloat(o.paddingRight),l=r?0:parseFloat(o.paddingBottom),u=r?0:parseFloat(o.paddingLeft),g=r?0:parseFloat(o.borderTopWidth),m=r?0:parseFloat(o.borderRightWidth),w=r?0:parseFloat(o.borderBottomWidth),b=u+f,F=d+l,v=(r?0:parseFloat(o.borderLeftWidth))+m,W=g+w,y=r?0:t.offsetHeight-W-t.clientHeight,E=r?0:t.offsetWidth-v-t.clientWidth,R=b+v,z=F+W,M=r?t.width:parseFloat(o.width)-R-E,O=r?t.height:parseFloat(o.height)-z-y;if(n.has(t)){var k=n.get(t);if(k[0]===M&&k[1]===O)return}n.set(t,[M,O]);var S=Object.create(h.prototype);S.target=t,S.contentRect=new c(u,d,M,O),s.has(i)||(s.set(i,[]),p.add(i)),s.get(i).push(S)}))})),p.forEach((function(e){i.get(e).call(e,s.get(e),e)}))}return s.prototype.observe=function(i){if(i instanceof window.Element){r.has(i)||(r.set(i,new Set),o.add(i),a.set(i,window.getComputedStyle(i)));var n=r.get(i);n.has(this)||n.add(this),cancelAnimationFrame(t),t=requestAnimationFrame(d)}},s.prototype.unobserve=function(i){if(i instanceof window.Element&&r.has(i)){var n=r.get(i);n.has(this)&&(n.delete(this),n.size||(r.delete(i),o.delete(i))),n.size||r.delete(i),o.size||cancelAnimationFrame(t)}},A.DOMRectReadOnly=c,A.ResizeObserver=s,A.ResizeObserverEntry=h,A}; // eslint-disable-line
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/js/mpl_tornado.js b/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/js/mpl_tornado.js
deleted file mode 100644
index b3cab8b7b9..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/js/mpl_tornado.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/* This .js file contains functions for matplotlib's built-in
- tornado-based server, that are not relevant when embedding WebAgg
- in another web application. */
-
-/* exported mpl_ondownload */
-function mpl_ondownload(figure, format) {
- window.open(figure.id + '/download.' + format, '_blank');
-}
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/js/nbagg_mpl.js b/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/js/nbagg_mpl.js
deleted file mode 100644
index 26d79ff4e1..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/js/nbagg_mpl.js
+++ /dev/null
@@ -1,275 +0,0 @@
-/* global mpl */
-
-var comm_websocket_adapter = function (comm) {
- // Create a "websocket"-like object which calls the given IPython comm
- // object with the appropriate methods. Currently this is a non binary
- // socket, so there is still some room for performance tuning.
- var ws = {};
-
- ws.binaryType = comm.kernel.ws.binaryType;
- ws.readyState = comm.kernel.ws.readyState;
- function updateReadyState(_event) {
- if (comm.kernel.ws) {
- ws.readyState = comm.kernel.ws.readyState;
- } else {
- ws.readyState = 3; // Closed state.
- }
- }
- comm.kernel.ws.addEventListener('open', updateReadyState);
- comm.kernel.ws.addEventListener('close', updateReadyState);
- comm.kernel.ws.addEventListener('error', updateReadyState);
-
- ws.close = function () {
- comm.close();
- };
- ws.send = function (m) {
- //console.log('sending', m);
- comm.send(m);
- };
- // Register the callback with on_msg.
- comm.on_msg(function (msg) {
- //console.log('receiving', msg['content']['data'], msg);
- var data = msg['content']['data'];
- if (data['blob'] !== undefined) {
- data = {
- data: new Blob(msg['buffers'], { type: data['blob'] }),
- };
- }
- // Pass the mpl event to the overridden (by mpl) onmessage function.
- ws.onmessage(data);
- });
- return ws;
-};
-
-mpl.mpl_figure_comm = function (comm, msg) {
- // This is the function which gets called when the mpl process
- // starts-up an IPython Comm through the "matplotlib" channel.
-
- var id = msg.content.data.id;
- // Get hold of the div created by the display call when the Comm
- // socket was opened in Python.
- var element = document.getElementById(id);
- var ws_proxy = comm_websocket_adapter(comm);
-
- function ondownload(figure, _format) {
- window.open(figure.canvas.toDataURL());
- }
-
- var fig = new mpl.figure(id, ws_proxy, ondownload, element);
-
- // Call onopen now - mpl needs it, as it is assuming we've passed it a real
- // web socket which is closed, not our websocket->open comm proxy.
- ws_proxy.onopen();
-
- fig.parent_element = element;
- fig.cell_info = mpl.find_output_cell("<div id='" + id + "'></div>");
- if (!fig.cell_info) {
- console.error('Failed to find cell for figure', id, fig);
- return;
- }
- fig.cell_info[0].output_area.element.on(
- 'cleared',
- { fig: fig },
- fig._remove_fig_handler
- );
-};
-
-mpl.figure.prototype.handle_close = function (fig, msg) {
- var width = fig.canvas.width / fig.ratio;
- fig.cell_info[0].output_area.element.off(
- 'cleared',
- fig._remove_fig_handler
- );
- fig.resizeObserverInstance.unobserve(fig.canvas_div);
-
- // Update the output cell to use the data from the current canvas.
- fig.push_to_output();
- var dataURL = fig.canvas.toDataURL();
- // Re-enable the keyboard manager in IPython - without this line, in FF,
- // the notebook keyboard shortcuts fail.
- IPython.keyboard_manager.enable();
- fig.parent_element.innerHTML =
- '<img src="' + dataURL + '" width="' + width + '">';
- fig.close_ws(fig, msg);
-};
-
-mpl.figure.prototype.close_ws = function (fig, msg) {
- fig.send_message('closing', msg);
- // fig.ws.close()
-};
-
-mpl.figure.prototype.push_to_output = function (_remove_interactive) {
- // Turn the data on the canvas into data in the output cell.
- var width = this.canvas.width / this.ratio;
- var dataURL = this.canvas.toDataURL();
- this.cell_info[1]['text/html'] =
- '<img src="' + dataURL + '" width="' + width + '">';
-};
-
-mpl.figure.prototype.updated_canvas_event = function () {
- // Tell IPython that the notebook contents must change.
- IPython.notebook.set_dirty(true);
- this.send_message('ack', {});
- var fig = this;
- // Wait a second, then push the new image to the DOM so
- // that it is saved nicely (might be nice to debounce this).
- setTimeout(function () {
- fig.push_to_output();
- }, 1000);
-};
-
-mpl.figure.prototype._init_toolbar = function () {
- var fig = this;
-
- var toolbar = document.createElement('div');
- toolbar.classList = 'btn-toolbar';
- this.root.appendChild(toolbar);
-
- function on_click_closure(name) {
- return function (_event) {
- return fig.toolbar_button_onclick(name);
- };
- }
-
- function on_mouseover_closure(tooltip) {
- return function (event) {
- if (!event.currentTarget.disabled) {
- return fig.toolbar_button_onmouseover(tooltip);
- }
- };
- }
-
- fig.buttons = {};
- var buttonGroup = document.createElement('div');
- buttonGroup.classList = 'btn-group';
- var button;
- for (var toolbar_ind in mpl.toolbar_items) {
- var name = mpl.toolbar_items[toolbar_ind][0];
- var tooltip = mpl.toolbar_items[toolbar_ind][1];
- var image = mpl.toolbar_items[toolbar_ind][2];
- var method_name = mpl.toolbar_items[toolbar_ind][3];
-
- if (!name) {
- /* Instead of a spacer, we start a new button group. */
- if (buttonGroup.hasChildNodes()) {
- toolbar.appendChild(buttonGroup);
- }
- buttonGroup = document.createElement('div');
- buttonGroup.classList = 'btn-group';
- continue;
- }
-
- button = fig.buttons[name] = document.createElement('button');
- button.classList = 'btn btn-default';
- button.href = '#';
- button.title = name;
- button.innerHTML = '<i class="fa ' + image + ' fa-lg"></i>';
- button.addEventListener('click', on_click_closure(method_name));
- button.addEventListener('mouseover', on_mouseover_closure(tooltip));
- buttonGroup.appendChild(button);
- }
-
- if (buttonGroup.hasChildNodes()) {
- toolbar.appendChild(buttonGroup);
- }
-
- // Add the status bar.
- var status_bar = document.createElement('span');
- status_bar.classList = 'mpl-message pull-right';
- toolbar.appendChild(status_bar);
- this.message = status_bar;
-
- // Add the close button to the window.
- var buttongrp = document.createElement('div');
- buttongrp.classList = 'btn-group inline pull-right';
- button = document.createElement('button');
- button.classList = 'btn btn-mini btn-primary';
- button.href = '#';
- button.title = 'Stop Interaction';
- button.innerHTML = '<i class="fa fa-power-off icon-remove icon-large"></i>';
- button.addEventListener('click', function (_evt) {
- fig.handle_close(fig, {});
- });
- button.addEventListener(
- 'mouseover',
- on_mouseover_closure('Stop Interaction')
- );
- buttongrp.appendChild(button);
- var titlebar = this.root.querySelector('.ui-dialog-titlebar');
- titlebar.insertBefore(buttongrp, titlebar.firstChild);
-};
-
-mpl.figure.prototype._remove_fig_handler = function (event) {
- var fig = event.data.fig;
- if (event.target !== this) {
- // Ignore bubbled events from children.
- return;
- }
- fig.close_ws(fig, {});
-};
-
-mpl.figure.prototype._root_extra_style = function (el) {
- el.style.boxSizing = 'content-box'; // override notebook setting of border-box.
-};
-
-mpl.figure.prototype._canvas_extra_style = function (el) {
- // this is important to make the div 'focusable
- el.setAttribute('tabindex', 0);
- // reach out to IPython and tell the keyboard manager to turn it's self
- // off when our div gets focus
-
- // location in version 3
- if (IPython.notebook.keyboard_manager) {
- IPython.notebook.keyboard_manager.register_events(el);
- } else {
- // location in version 2
- IPython.keyboard_manager.register_events(el);
- }
-};
-
-mpl.figure.prototype._key_event_extra = function (event, _name) {
- // Check for shift+enter
- if (event.shiftKey && event.which === 13) {
- this.canvas_div.blur();
- // select the cell after this one
- var index = IPython.notebook.find_cell_index(this.cell_info[0]);
- IPython.notebook.select(index + 1);
- }
-};
-
-mpl.figure.prototype.handle_save = function (fig, _msg) {
- fig.ondownload(fig, null);
-};
-
-mpl.find_output_cell = function (html_output) {
- // Return the cell and output element which can be found *uniquely* in the notebook.
- // Note - this is a bit hacky, but it is done because the "notebook_saving.Notebook"
- // IPython event is triggered only after the cells have been serialised, which for
- // our purposes (turning an active figure into a static one), is too late.
- var cells = IPython.notebook.get_cells();
- var ncells = cells.length;
- for (var i = 0; i < ncells; i++) {
- var cell = cells[i];
- if (cell.cell_type === 'code') {
- for (var j = 0; j < cell.output_area.outputs.length; j++) {
- var data = cell.output_area.outputs[j];
- if (data.data) {
- // IPython >= 3 moved mimebundle to data attribute of output
- data = data.data;
- }
- if (data['text/html'] === html_output) {
- return [cell, data, j];
- }
- }
- }
- }
-};
-
-// Register the function which deals with the matplotlib target/channel.
-// The kernel may be null if the page has been refreshed.
-if (IPython.notebook.kernel !== null) {
- IPython.notebook.kernel.comm_manager.register_target(
- 'matplotlib',
- mpl.mpl_figure_comm
- );
-}
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/nbagg_uat.ipynb b/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/nbagg_uat.ipynb
deleted file mode 100644
index e9fc62bc28..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/nbagg_uat.ipynb
+++ /dev/null
@@ -1,631 +0,0 @@
-{
- "cells": [
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from imp import reload"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## UAT for NbAgg backend.\n",
- "\n",
- "The first line simply reloads matplotlib, uses the nbagg backend and then reloads the backend, just to ensure we have the latest modification to the backend code. Note: The underlying JavaScript will not be updated by this process, so a refresh of the browser after clearing the output and saving is necessary to clear everything fully."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import matplotlib\n",
- "reload(matplotlib)\n",
- "\n",
- "matplotlib.use('nbagg')\n",
- "\n",
- "import matplotlib.backends.backend_nbagg\n",
- "reload(matplotlib.backends.backend_nbagg)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 1 - Simple figure creation using pyplot\n",
- "\n",
- "Should produce a figure window which is interactive with the pan and zoom buttons. (Do not press the close button, but any others may be used)."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import matplotlib.backends.backend_webagg_core\n",
- "reload(matplotlib.backends.backend_webagg_core)\n",
- "\n",
- "import matplotlib.pyplot as plt\n",
- "plt.interactive(False)\n",
- "\n",
- "fig1 = plt.figure()\n",
- "plt.plot(range(10))\n",
- "\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 2 - Creation of another figure, without the need to do plt.figure.\n",
- "\n",
- "As above, a new figure should be created."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plt.plot([3, 2, 1])\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 3 - Connection info\n",
- "\n",
- "The printout should show that there are two figures which have active CommSockets, and no figures pending show."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "print(matplotlib.backends.backend_nbagg.connection_info())"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 4 - Closing figures\n",
- "\n",
- "Closing a specific figure instance should turn the figure into a plain image - the UI should have been removed. In this case, scroll back to the first figure and assert this is the case."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plt.close(fig1)\n",
- "plt.close('all')"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 5 - No show without plt.show in non-interactive mode\n",
- "\n",
- "Simply doing a plt.plot should not show a new figure, nor indeed update an existing one (easily verified in UAT 6).\n",
- "The output should simply be a list of Line2D instances."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plt.plot(range(10))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 6 - Connection information\n",
- "\n",
- "We just created a new figure, but didn't show it. Connection info should no longer have \"Figure 1\" (as we closed it in UAT 4) and should have figure 2 and 3, with Figure 3 without any connections. There should be 1 figure pending."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "print(matplotlib.backends.backend_nbagg.connection_info())"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 7 - Show of previously created figure\n",
- "\n",
- "We should be able to show a figure we've previously created. The following should produce two figure windows."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plt.show()\n",
- "plt.figure()\n",
- "plt.plot(range(5))\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 8 - Interactive mode\n",
- "\n",
- "In interactive mode, creating a line should result in a figure being shown."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plt.interactive(True)\n",
- "plt.figure()\n",
- "plt.plot([3, 2, 1])"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Subsequent lines should be added to the existing figure, rather than creating a new one."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plt.plot(range(3))"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Calling connection_info in interactive mode should not show any pending figures."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "print(matplotlib.backends.backend_nbagg.connection_info())"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Disable interactive mode again."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plt.interactive(False)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 9 - Multiple shows\n",
- "\n",
- "Unlike most of the other matplotlib backends, we may want to see a figure multiple times (with or without synchronisation between the views, though the former is not yet implemented). Assert that plt.gcf().canvas.manager.reshow() results in another figure window which is synchronised upon pan & zoom."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "plt.gcf().canvas.manager.reshow()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 10 - Saving notebook\n",
- "\n",
- "Saving the notebook (with CTRL+S or File->Save) should result in the saved notebook having static versions of the figures embedded within. The image should be the last update from user interaction and interactive plotting. (check by converting with ``ipython nbconvert <notebook>``)"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 11 - Creation of a new figure on second show\n",
- "\n",
- "Create a figure, show it, then create a new axes and show it. The result should be a new figure.\n",
- "\n",
- "**BUG: Sometimes this doesn't work - not sure why (@pelson).**"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "fig = plt.figure()\n",
- "plt.axes()\n",
- "plt.show()\n",
- "\n",
- "plt.plot([1, 2, 3])\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 12 - OO interface\n",
- "\n",
- "Should produce a new figure and plot it."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "from matplotlib.backends.backend_nbagg import new_figure_manager,show\n",
- "\n",
- "manager = new_figure_manager(1000)\n",
- "fig = manager.canvas.figure\n",
- "ax = fig.add_subplot(1,1,1)\n",
- "ax.plot([1,2,3])\n",
- "fig.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "## UAT 13 - Animation\n",
- "\n",
- "The following should generate an animated line:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import matplotlib.animation as animation\n",
- "import numpy as np\n",
- "\n",
- "fig, ax = plt.subplots()\n",
- "\n",
- "x = np.arange(0, 2*np.pi, 0.01) # x-array\n",
- "line, = ax.plot(x, np.sin(x))\n",
- "\n",
- "def animate(i):\n",
- " line.set_ydata(np.sin(x+i/10.0)) # update the data\n",
- " return line,\n",
- "\n",
- "#Init only required for blitting to give a clean slate.\n",
- "def init():\n",
- " line.set_ydata(np.ma.array(x, mask=True))\n",
- " return line,\n",
- "\n",
- "ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), init_func=init,\n",
- " interval=100., blit=True)\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 14 - Keyboard shortcuts in IPython after close of figure\n",
- "\n",
- "After closing the previous figure (with the close button above the figure) the IPython keyboard shortcuts should still function.\n",
- "\n",
- "### UAT 15 - Figure face colours\n",
- "\n",
- "The nbagg honours all colours apart from that of the figure.patch. The two plots below should produce a figure with a red background. There should be no yellow figure."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import matplotlib\n",
- "matplotlib.rcParams.update({'figure.facecolor': 'red',\n",
- " 'savefig.facecolor': 'yellow'})\n",
- "plt.figure()\n",
- "plt.plot([3, 2, 1])\n",
- "\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 16 - Events\n",
- "\n",
- "Pressing any keyboard key or mouse button (or scrolling) should cycle the line while the figure has focus. The figure should have focus by default when it is created and re-gain it by clicking on the canvas. Clicking anywhere outside of the figure should release focus, but moving the mouse out of the figure should not release focus."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import itertools\n",
- "fig, ax = plt.subplots()\n",
- "x = np.linspace(0,10,10000)\n",
- "y = np.sin(x)\n",
- "ln, = ax.plot(x,y)\n",
- "evt = []\n",
- "colors = iter(itertools.cycle(['r', 'g', 'b', 'k', 'c']))\n",
- "def on_event(event):\n",
- " if event.name.startswith('key'):\n",
- " fig.suptitle('%s: %s' % (event.name, event.key))\n",
- " elif event.name == 'scroll_event':\n",
- " fig.suptitle('%s: %s' % (event.name, event.step))\n",
- " else:\n",
- " fig.suptitle('%s: %s' % (event.name, event.button))\n",
- " evt.append(event)\n",
- " ln.set_color(next(colors))\n",
- " fig.canvas.draw()\n",
- " fig.canvas.draw_idle()\n",
- "\n",
- "fig.canvas.mpl_connect('button_press_event', on_event)\n",
- "fig.canvas.mpl_connect('button_release_event', on_event)\n",
- "fig.canvas.mpl_connect('scroll_event', on_event)\n",
- "fig.canvas.mpl_connect('key_press_event', on_event)\n",
- "fig.canvas.mpl_connect('key_release_event', on_event)\n",
- "\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 17 - Timers\n",
- "\n",
- "Single-shot timers follow a completely different code path in the nbagg backend than regular timers (such as those used in the animation example above.) The next set of tests ensures that both \"regular\" and \"single-shot\" timers work properly.\n",
- "\n",
- "The following should show a simple clock that updates twice a second:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import time\n",
- "\n",
- "fig, ax = plt.subplots()\n",
- "text = ax.text(0.5, 0.5, '', ha='center')\n",
- "\n",
- "def update(text):\n",
- " text.set(text=time.ctime())\n",
- " text.axes.figure.canvas.draw()\n",
- " \n",
- "timer = fig.canvas.new_timer(500, [(update, [text], {})])\n",
- "timer.start()\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "However, the following should only update once and then stop:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "fig, ax = plt.subplots()\n",
- "text = ax.text(0.5, 0.5, '', ha='center') \n",
- "timer = fig.canvas.new_timer(500, [(update, [text], {})])\n",
- "\n",
- "timer.single_shot = True\n",
- "timer.start()\n",
- "\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "And the next two examples should never show any visible text at all:"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "fig, ax = plt.subplots()\n",
- "text = ax.text(0.5, 0.5, '', ha='center')\n",
- "timer = fig.canvas.new_timer(500, [(update, [text], {})])\n",
- "\n",
- "timer.start()\n",
- "timer.stop()\n",
- "\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "fig, ax = plt.subplots()\n",
- "text = ax.text(0.5, 0.5, '', ha='center')\n",
- "timer = fig.canvas.new_timer(500, [(update, [text], {})])\n",
- "\n",
- "timer.single_shot = True\n",
- "timer.start()\n",
- "timer.stop()\n",
- "\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "### UAT 18 - stopping figure when removed from DOM\n",
- "\n",
- "When the div that contains from the figure is removed from the DOM the figure should shut down it's comm, and if the python-side figure has no more active comms, it should destroy the figure. Repeatedly running the cell below should always have the same figure number"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "fig, ax = plt.subplots()\n",
- "ax.plot(range(5))\n",
- "plt.show()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {},
- "source": [
- "Running the cell below will re-show the figure. After this, re-running the cell above should result in a new figure number."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "fig.canvas.manager.reshow()"
- ]
- },
- {
- "cell_type": "markdown",
- "metadata": {
- "collapsed": true
- },
- "source": [
- "### UAT 19 - Blitting\n",
- "\n",
- "Clicking on the figure should plot a green horizontal line moving up the axes."
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "import itertools\n",
- "\n",
- "cnt = itertools.count()\n",
- "bg = None\n",
- "\n",
- "def onclick_handle(event):\n",
- " \"\"\"Should draw elevating green line on each mouse click\"\"\"\n",
- " global bg\n",
- " if bg is None:\n",
- " bg = ax.figure.canvas.copy_from_bbox(ax.bbox) \n",
- " ax.figure.canvas.restore_region(bg)\n",
- "\n",
- " cur_y = (next(cnt) % 10) * 0.1\n",
- " ln.set_ydata([cur_y, cur_y])\n",
- " ax.draw_artist(ln)\n",
- " ax.figure.canvas.blit(ax.bbox)\n",
- "\n",
- "fig, ax = plt.subplots()\n",
- "ax.plot([0, 1], [0, 1], 'r')\n",
- "ln, = ax.plot([0, 1], [0, 0], 'g', animated=True)\n",
- "plt.show()\n",
- "ax.figure.canvas.draw()\n",
- "\n",
- "ax.figure.canvas.mpl_connect('button_press_event', onclick_handle)"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": []
- }
- ],
- "metadata": {
- "kernelspec": {
- "display_name": "Python 3",
- "language": "python",
- "name": "python3"
- },
- "language_info": {
- "codemirror_mode": {
- "name": "ipython",
- "version": 3
- },
- "file_extension": ".py",
- "mimetype": "text/x-python",
- "name": "python",
- "nbconvert_exporter": "python",
- "pygments_lexer": "ipython3",
- "version": "3.8.5"
- }
- },
- "nbformat": 4,
- "nbformat_minor": 1
-}
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/package.json b/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/package.json
deleted file mode 100644
index 95bd8fdf54..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/package.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "devDependencies": {
- "eslint": "^6.8.0",
- "eslint-config-prettier": "^6.10.1",
- "prettier": "^2.0.2"
- },
- "scripts": {
- "eslint": "eslint . --fix",
- "eslint:check": "eslint .",
- "lint": "npm run prettier && npm run eslint",
- "lint:check": "npm run prettier:check && npm run eslint:check",
- "prettier": "prettier --write \"**/*{.ts,.tsx,.js,.jsx,.css,.json}\"",
- "prettier:check": "prettier --check \"**/*{.ts,.tsx,.js,.jsx,.css,.json}\""
- },
- "dependencies": {
- "@jsxtools/resize-observer": "^1.0.4"
- }
-}
diff --git a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/single_figure.html b/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/single_figure.html
deleted file mode 100644
index ceaaab0066..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/backends/web_backend/single_figure.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
- <link rel="stylesheet" href="{{ prefix }}/_static/css/page.css" type="text/css">
- <link rel="stylesheet" href="{{ prefix }}/_static/css/boilerplate.css" type="text/css">
- <link rel="stylesheet" href="{{ prefix }}/_static/css/fbm.css" type="text/css">
- <link rel="stylesheet" href="{{ prefix }}/_static/css/mpl.css" type="text/css">
- <script src="{{ prefix }}/_static/js/mpl_tornado.js"></script>
- <script src="{{ prefix }}/js/mpl.js"></script>
- <script>
- function ready(fn) {
- if (document.readyState != "loading") {
- fn();
- } else {
- document.addEventListener("DOMContentLoaded", fn);
- }
- }
-
- ready(
- function () {
- var websocket_type = mpl.get_websocket_type();
- var uri = "{{ ws_uri }}" + {{ str(fig_id) }} + "/ws";
- if (window.location.protocol === 'https:') uri = uri.replace('ws:', 'wss:')
- var websocket = new websocket_type(uri);
- var fig = new mpl.figure(
- {{ str(fig_id) }}, websocket, mpl_ondownload,
- document.getElementById("figure"));
- }
- );
- </script>
-
- <title>matplotlib</title>
- </head>
-
- <body>
- <div id="mpl-warnings" class="mpl-warnings"></div>
- <div id="figure" style="margin: 10px 10px;"></div>
- </body>
-</html>
diff --git a/contrib/python/matplotlib/py3/matplotlib/bezier.py b/contrib/python/matplotlib/py3/matplotlib/bezier.py
deleted file mode 100644
index f310f287e2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/bezier.py
+++ /dev/null
@@ -1,594 +0,0 @@
-"""
-A module providing some utility functions regarding Bézier path manipulation.
-"""
-
-from functools import lru_cache
-import math
-import warnings
-
-import numpy as np
-
-from matplotlib import _api
-
-
-# same algorithm as 3.8's math.comb
-@np.vectorize
-@lru_cache(maxsize=128)
-def _comb(n, k):
- if k > n:
- return 0
- k = min(k, n - k)
- i = np.arange(1, k + 1)
- return np.prod((n + 1 - i)/i).astype(int)
-
-
-class NonIntersectingPathException(ValueError):
- pass
-
-
-# some functions
-
-
-def get_intersection(cx1, cy1, cos_t1, sin_t1,
- cx2, cy2, cos_t2, sin_t2):
- """
- Return the intersection between the line through (*cx1*, *cy1*) at angle
- *t1* and the line through (*cx2*, *cy2*) at angle *t2*.
- """
-
- # line1 => sin_t1 * (x - cx1) - cos_t1 * (y - cy1) = 0.
- # line1 => sin_t1 * x + cos_t1 * y = sin_t1*cx1 - cos_t1*cy1
-
- line1_rhs = sin_t1 * cx1 - cos_t1 * cy1
- line2_rhs = sin_t2 * cx2 - cos_t2 * cy2
-
- # rhs matrix
- a, b = sin_t1, -cos_t1
- c, d = sin_t2, -cos_t2
-
- ad_bc = a * d - b * c
- if abs(ad_bc) < 1e-12:
- raise ValueError("Given lines do not intersect. Please verify that "
- "the angles are not equal or differ by 180 degrees.")
-
- # rhs_inverse
- a_, b_ = d, -b
- c_, d_ = -c, a
- a_, b_, c_, d_ = [k / ad_bc for k in [a_, b_, c_, d_]]
-
- x = a_ * line1_rhs + b_ * line2_rhs
- y = c_ * line1_rhs + d_ * line2_rhs
-
- return x, y
-
-
-def get_normal_points(cx, cy, cos_t, sin_t, length):
- """
- For a line passing through (*cx*, *cy*) and having an angle *t*, return
- locations of the two points located along its perpendicular line at the
- distance of *length*.
- """
-
- if length == 0.:
- return cx, cy, cx, cy
-
- cos_t1, sin_t1 = sin_t, -cos_t
- cos_t2, sin_t2 = -sin_t, cos_t
-
- x1, y1 = length * cos_t1 + cx, length * sin_t1 + cy
- x2, y2 = length * cos_t2 + cx, length * sin_t2 + cy
-
- return x1, y1, x2, y2
-
-
-# BEZIER routines
-
-# subdividing bezier curve
-# http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/bezier-sub.html
-
-
-def _de_casteljau1(beta, t):
- next_beta = beta[:-1] * (1 - t) + beta[1:] * t
- return next_beta
-
-
-def split_de_casteljau(beta, t):
- """
- Split a Bézier segment defined by its control points *beta* into two
- separate segments divided at *t* and return their control points.
- """
- beta = np.asarray(beta)
- beta_list = [beta]
- while True:
- beta = _de_casteljau1(beta, t)
- beta_list.append(beta)
- if len(beta) == 1:
- break
- left_beta = [beta[0] for beta in beta_list]
- right_beta = [beta[-1] for beta in reversed(beta_list)]
-
- return left_beta, right_beta
-
-
-def find_bezier_t_intersecting_with_closedpath(
- bezier_point_at_t, inside_closedpath, t0=0., t1=1., tolerance=0.01):
- """
- Find the intersection of the Bézier curve with a closed path.
-
- The intersection point *t* is approximated by two parameters *t0*, *t1*
- such that *t0* <= *t* <= *t1*.
-
- Search starts from *t0* and *t1* and uses a simple bisecting algorithm
- therefore one of the end points must be inside the path while the other
- doesn't. The search stops when the distance of the points parametrized by
- *t0* and *t1* gets smaller than the given *tolerance*.
-
- Parameters
- ----------
- bezier_point_at_t : callable
- A function returning x, y coordinates of the Bézier at parameter *t*.
- It must have the signature::
-
- bezier_point_at_t(t: float) -> tuple[float, float]
-
- inside_closedpath : callable
- A function returning True if a given point (x, y) is inside the
- closed path. It must have the signature::
-
- inside_closedpath(point: tuple[float, float]) -> bool
-
- t0, t1 : float
- Start parameters for the search.
-
- tolerance : float
- Maximal allowed distance between the final points.
-
- Returns
- -------
- t0, t1 : float
- The Bézier path parameters.
- """
- start = bezier_point_at_t(t0)
- end = bezier_point_at_t(t1)
-
- start_inside = inside_closedpath(start)
- end_inside = inside_closedpath(end)
-
- if start_inside == end_inside and start != end:
- raise NonIntersectingPathException(
- "Both points are on the same side of the closed path")
-
- while True:
-
- # return if the distance is smaller than the tolerance
- if np.hypot(start[0] - end[0], start[1] - end[1]) < tolerance:
- return t0, t1
-
- # calculate the middle point
- middle_t = 0.5 * (t0 + t1)
- middle = bezier_point_at_t(middle_t)
- middle_inside = inside_closedpath(middle)
-
- if start_inside ^ middle_inside:
- t1 = middle_t
- end = middle
- else:
- t0 = middle_t
- start = middle
- start_inside = middle_inside
-
-
-class BezierSegment:
- """
- A d-dimensional Bézier segment.
-
- Parameters
- ----------
- control_points : (N, d) array
- Location of the *N* control points.
- """
-
- def __init__(self, control_points):
- self._cpoints = np.asarray(control_points)
- self._N, self._d = self._cpoints.shape
- self._orders = np.arange(self._N)
- coeff = [math.factorial(self._N - 1)
- // (math.factorial(i) * math.factorial(self._N - 1 - i))
- for i in range(self._N)]
- self._px = (self._cpoints.T * coeff).T
-
- def __call__(self, t):
- """
- Evaluate the Bézier curve at point(s) *t* in [0, 1].
-
- Parameters
- ----------
- t : (k,) array-like
- Points at which to evaluate the curve.
-
- Returns
- -------
- (k, d) array
- Value of the curve for each point in *t*.
- """
- t = np.asarray(t)
- return (np.power.outer(1 - t, self._orders[::-1])
- * np.power.outer(t, self._orders)) @ self._px
-
- def point_at_t(self, t):
- """
- Evaluate the curve at a single point, returning a tuple of *d* floats.
- """
- return tuple(self(t))
-
- @property
- def control_points(self):
- """The control points of the curve."""
- return self._cpoints
-
- @property
- def dimension(self):
- """The dimension of the curve."""
- return self._d
-
- @property
- def degree(self):
- """Degree of the polynomial. One less the number of control points."""
- return self._N - 1
-
- @property
- def polynomial_coefficients(self):
- r"""
- The polynomial coefficients of the Bézier curve.
-
- .. warning:: Follows opposite convention from `numpy.polyval`.
-
- Returns
- -------
- (n+1, d) array
- Coefficients after expanding in polynomial basis, where :math:`n`
- is the degree of the Bézier curve and :math:`d` its dimension.
- These are the numbers (:math:`C_j`) such that the curve can be
- written :math:`\sum_{j=0}^n C_j t^j`.
-
- Notes
- -----
- The coefficients are calculated as
-
- .. math::
-
- {n \choose j} \sum_{i=0}^j (-1)^{i+j} {j \choose i} P_i
-
- where :math:`P_i` are the control points of the curve.
- """
- n = self.degree
- # matplotlib uses n <= 4. overflow plausible starting around n = 15.
- if n > 10:
- warnings.warn("Polynomial coefficients formula unstable for high "
- "order Bezier curves!", RuntimeWarning)
- P = self.control_points
- j = np.arange(n+1)[:, None]
- i = np.arange(n+1)[None, :] # _comb is non-zero for i <= j
- prefactor = (-1)**(i + j) * _comb(j, i) # j on axis 0, i on axis 1
- return _comb(n, j) * prefactor @ P # j on axis 0, self.dimension on 1
-
- def axis_aligned_extrema(self):
- """
- Return the dimension and location of the curve's interior extrema.
-
- The extrema are the points along the curve where one of its partial
- derivatives is zero.
-
- Returns
- -------
- dims : array of int
- Index :math:`i` of the partial derivative which is zero at each
- interior extrema.
- dzeros : array of float
- Of same size as dims. The :math:`t` such that :math:`d/dx_i B(t) =
- 0`
- """
- n = self.degree
- if n <= 1:
- return np.array([]), np.array([])
- Cj = self.polynomial_coefficients
- dCj = np.arange(1, n+1)[:, None] * Cj[1:]
- dims = []
- roots = []
- for i, pi in enumerate(dCj.T):
- r = np.roots(pi[::-1])
- roots.append(r)
- dims.append(np.full_like(r, i))
- roots = np.concatenate(roots)
- dims = np.concatenate(dims)
- in_range = np.isreal(roots) & (roots >= 0) & (roots <= 1)
- return dims[in_range], np.real(roots)[in_range]
-
-
-def split_bezier_intersecting_with_closedpath(
- bezier, inside_closedpath, tolerance=0.01):
- """
- Split a Bézier curve into two at the intersection with a closed path.
-
- Parameters
- ----------
- bezier : (N, 2) array-like
- Control points of the Bézier segment. See `.BezierSegment`.
- inside_closedpath : callable
- A function returning True if a given point (x, y) is inside the
- closed path. See also `.find_bezier_t_intersecting_with_closedpath`.
- tolerance : float
- The tolerance for the intersection. See also
- `.find_bezier_t_intersecting_with_closedpath`.
-
- Returns
- -------
- left, right
- Lists of control points for the two Bézier segments.
- """
-
- bz = BezierSegment(bezier)
- bezier_point_at_t = bz.point_at_t
-
- t0, t1 = find_bezier_t_intersecting_with_closedpath(
- bezier_point_at_t, inside_closedpath, tolerance=tolerance)
-
- _left, _right = split_de_casteljau(bezier, (t0 + t1) / 2.)
- return _left, _right
-
-
-# matplotlib specific
-
-
-def split_path_inout(path, inside, tolerance=0.01, reorder_inout=False):
- """
- Divide a path into two segments at the point where ``inside(x, y)`` becomes
- False.
- """
- from .path import Path
- path_iter = path.iter_segments()
-
- ctl_points, command = next(path_iter)
- begin_inside = inside(ctl_points[-2:]) # true if begin point is inside
-
- ctl_points_old = ctl_points
-
- iold = 0
- i = 1
-
- for ctl_points, command in path_iter:
- iold = i
- i += len(ctl_points) // 2
- if inside(ctl_points[-2:]) != begin_inside:
- bezier_path = np.concatenate([ctl_points_old[-2:], ctl_points])
- break
- ctl_points_old = ctl_points
- else:
- raise ValueError("The path does not intersect with the patch")
-
- bp = bezier_path.reshape((-1, 2))
- left, right = split_bezier_intersecting_with_closedpath(
- bp, inside, tolerance)
- if len(left) == 2:
- codes_left = [Path.LINETO]
- codes_right = [Path.MOVETO, Path.LINETO]
- elif len(left) == 3:
- codes_left = [Path.CURVE3, Path.CURVE3]
- codes_right = [Path.MOVETO, Path.CURVE3, Path.CURVE3]
- elif len(left) == 4:
- codes_left = [Path.CURVE4, Path.CURVE4, Path.CURVE4]
- codes_right = [Path.MOVETO, Path.CURVE4, Path.CURVE4, Path.CURVE4]
- else:
- raise AssertionError("This should never be reached")
-
- verts_left = left[1:]
- verts_right = right[:]
-
- if path.codes is None:
- path_in = Path(np.concatenate([path.vertices[:i], verts_left]))
- path_out = Path(np.concatenate([verts_right, path.vertices[i:]]))
-
- else:
- path_in = Path(np.concatenate([path.vertices[:iold], verts_left]),
- np.concatenate([path.codes[:iold], codes_left]))
-
- path_out = Path(np.concatenate([verts_right, path.vertices[i:]]),
- np.concatenate([codes_right, path.codes[i:]]))
-
- if reorder_inout and not begin_inside:
- path_in, path_out = path_out, path_in
-
- return path_in, path_out
-
-
-def inside_circle(cx, cy, r):
- """
- Return a function that checks whether a point is in a circle with center
- (*cx*, *cy*) and radius *r*.
-
- The returned function has the signature::
-
- f(xy: tuple[float, float]) -> bool
- """
- r2 = r ** 2
-
- def _f(xy):
- x, y = xy
- return (x - cx) ** 2 + (y - cy) ** 2 < r2
- return _f
-
-
-# quadratic Bezier lines
-
-def get_cos_sin(x0, y0, x1, y1):
- dx, dy = x1 - x0, y1 - y0
- d = (dx * dx + dy * dy) ** .5
- # Account for divide by zero
- if d == 0:
- return 0.0, 0.0
- return dx / d, dy / d
-
-
-def check_if_parallel(dx1, dy1, dx2, dy2, tolerance=1.e-5):
- """
- Check if two lines are parallel.
-
- Parameters
- ----------
- dx1, dy1, dx2, dy2 : float
- The gradients *dy*/*dx* of the two lines.
- tolerance : float
- The angular tolerance in radians up to which the lines are considered
- parallel.
-
- Returns
- -------
- is_parallel
- - 1 if two lines are parallel in same direction.
- - -1 if two lines are parallel in opposite direction.
- - False otherwise.
- """
- theta1 = np.arctan2(dx1, dy1)
- theta2 = np.arctan2(dx2, dy2)
- dtheta = abs(theta1 - theta2)
- if dtheta < tolerance:
- return 1
- elif abs(dtheta - np.pi) < tolerance:
- return -1
- else:
- return False
-
-
-def get_parallels(bezier2, width):
- """
- Given the quadratic Bézier control points *bezier2*, returns
- control points of quadratic Bézier lines roughly parallel to given
- one separated by *width*.
- """
-
- # The parallel Bezier lines are constructed by following ways.
- # c1 and c2 are control points representing the start and end of the
- # Bezier line.
- # cm is the middle point
-
- c1x, c1y = bezier2[0]
- cmx, cmy = bezier2[1]
- c2x, c2y = bezier2[2]
-
- parallel_test = check_if_parallel(c1x - cmx, c1y - cmy,
- cmx - c2x, cmy - c2y)
-
- if parallel_test == -1:
- _api.warn_external(
- "Lines do not intersect. A straight line is used instead.")
- cos_t1, sin_t1 = get_cos_sin(c1x, c1y, c2x, c2y)
- cos_t2, sin_t2 = cos_t1, sin_t1
- else:
- # t1 and t2 is the angle between c1 and cm, cm, c2. They are
- # also an angle of the tangential line of the path at c1 and c2
- cos_t1, sin_t1 = get_cos_sin(c1x, c1y, cmx, cmy)
- cos_t2, sin_t2 = get_cos_sin(cmx, cmy, c2x, c2y)
-
- # find c1_left, c1_right which are located along the lines
- # through c1 and perpendicular to the tangential lines of the
- # Bezier path at a distance of width. Same thing for c2_left and
- # c2_right with respect to c2.
- c1x_left, c1y_left, c1x_right, c1y_right = (
- get_normal_points(c1x, c1y, cos_t1, sin_t1, width)
- )
- c2x_left, c2y_left, c2x_right, c2y_right = (
- get_normal_points(c2x, c2y, cos_t2, sin_t2, width)
- )
-
- # find cm_left which is the intersecting point of a line through
- # c1_left with angle t1 and a line through c2_left with angle
- # t2. Same with cm_right.
- try:
- cmx_left, cmy_left = get_intersection(c1x_left, c1y_left, cos_t1,
- sin_t1, c2x_left, c2y_left,
- cos_t2, sin_t2)
- cmx_right, cmy_right = get_intersection(c1x_right, c1y_right, cos_t1,
- sin_t1, c2x_right, c2y_right,
- cos_t2, sin_t2)
- except ValueError:
- # Special case straight lines, i.e., angle between two lines is
- # less than the threshold used by get_intersection (we don't use
- # check_if_parallel as the threshold is not the same).
- cmx_left, cmy_left = (
- 0.5 * (c1x_left + c2x_left), 0.5 * (c1y_left + c2y_left)
- )
- cmx_right, cmy_right = (
- 0.5 * (c1x_right + c2x_right), 0.5 * (c1y_right + c2y_right)
- )
-
- # the parallel Bezier lines are created with control points of
- # [c1_left, cm_left, c2_left] and [c1_right, cm_right, c2_right]
- path_left = [(c1x_left, c1y_left),
- (cmx_left, cmy_left),
- (c2x_left, c2y_left)]
- path_right = [(c1x_right, c1y_right),
- (cmx_right, cmy_right),
- (c2x_right, c2y_right)]
-
- return path_left, path_right
-
-
-def find_control_points(c1x, c1y, mmx, mmy, c2x, c2y):
- """
- Find control points of the Bézier curve passing through (*c1x*, *c1y*),
- (*mmx*, *mmy*), and (*c2x*, *c2y*), at parametric values 0, 0.5, and 1.
- """
- cmx = .5 * (4 * mmx - (c1x + c2x))
- cmy = .5 * (4 * mmy - (c1y + c2y))
- return [(c1x, c1y), (cmx, cmy), (c2x, c2y)]
-
-
-def make_wedged_bezier2(bezier2, width, w1=1., wm=0.5, w2=0.):
- """
- Being similar to `get_parallels`, returns control points of two quadratic
- Bézier lines having a width roughly parallel to given one separated by
- *width*.
- """
-
- # c1, cm, c2
- c1x, c1y = bezier2[0]
- cmx, cmy = bezier2[1]
- c3x, c3y = bezier2[2]
-
- # t1 and t2 is the angle between c1 and cm, cm, c3.
- # They are also an angle of the tangential line of the path at c1 and c3
- cos_t1, sin_t1 = get_cos_sin(c1x, c1y, cmx, cmy)
- cos_t2, sin_t2 = get_cos_sin(cmx, cmy, c3x, c3y)
-
- # find c1_left, c1_right which are located along the lines
- # through c1 and perpendicular to the tangential lines of the
- # Bezier path at a distance of width. Same thing for c3_left and
- # c3_right with respect to c3.
- c1x_left, c1y_left, c1x_right, c1y_right = (
- get_normal_points(c1x, c1y, cos_t1, sin_t1, width * w1)
- )
- c3x_left, c3y_left, c3x_right, c3y_right = (
- get_normal_points(c3x, c3y, cos_t2, sin_t2, width * w2)
- )
-
- # find c12, c23 and c123 which are middle points of c1-cm, cm-c3 and
- # c12-c23
- c12x, c12y = (c1x + cmx) * .5, (c1y + cmy) * .5
- c23x, c23y = (cmx + c3x) * .5, (cmy + c3y) * .5
- c123x, c123y = (c12x + c23x) * .5, (c12y + c23y) * .5
-
- # tangential angle of c123 (angle between c12 and c23)
- cos_t123, sin_t123 = get_cos_sin(c12x, c12y, c23x, c23y)
-
- c123x_left, c123y_left, c123x_right, c123y_right = (
- get_normal_points(c123x, c123y, cos_t123, sin_t123, width * wm)
- )
-
- path_left = find_control_points(c1x_left, c1y_left,
- c123x_left, c123y_left,
- c3x_left, c3y_left)
- path_right = find_control_points(c1x_right, c1y_right,
- c123x_right, c123y_right,
- c3x_right, c3y_right)
-
- return path_left, path_right
diff --git a/contrib/python/matplotlib/py3/matplotlib/bezier.pyi b/contrib/python/matplotlib/py3/matplotlib/bezier.pyi
deleted file mode 100644
index ad82b873af..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/bezier.pyi
+++ /dev/null
@@ -1,74 +0,0 @@
-from collections.abc import Callable
-from typing import Literal
-
-import numpy as np
-from numpy.typing import ArrayLike
-
-from .path import Path
-
-class NonIntersectingPathException(ValueError): ...
-
-def get_intersection(
- cx1: float,
- cy1: float,
- cos_t1: float,
- sin_t1: float,
- cx2: float,
- cy2: float,
- cos_t2: float,
- sin_t2: float,
-) -> tuple[float, float]: ...
-def get_normal_points(
- cx: float, cy: float, cos_t: float, sin_t: float, length: float
-) -> tuple[float, float, float, float]: ...
-def split_de_casteljau(beta: ArrayLike, t: float) -> tuple[np.ndarray, np.ndarray]: ...
-def find_bezier_t_intersecting_with_closedpath(
- bezier_point_at_t: Callable[[float], tuple[float, float]],
- inside_closedpath: Callable[[tuple[float, float]], bool],
- t0: float = ...,
- t1: float = ...,
- tolerance: float = ...,
-) -> tuple[float, float]: ...
-
-# TODO make generic over d, the dimension? ndarraydim
-class BezierSegment:
- def __init__(self, control_points: ArrayLike) -> None: ...
- def __call__(self, t: ArrayLike) -> np.ndarray: ...
- def point_at_t(self, t: float) -> tuple[float, ...]: ...
- @property
- def control_points(self) -> np.ndarray: ...
- @property
- def dimension(self) -> int: ...
- @property
- def degree(self) -> int: ...
- @property
- def polynomial_coefficients(self) -> np.ndarray: ...
- def axis_aligned_extrema(self) -> tuple[np.ndarray, np.ndarray]: ...
-
-def split_bezier_intersecting_with_closedpath(
- bezier: ArrayLike,
- inside_closedpath: Callable[[tuple[float, float]], bool],
- tolerance: float = ...,
-) -> tuple[np.ndarray, np.ndarray]: ...
-def split_path_inout(
- path: Path,
- inside: Callable[[tuple[float, float]], bool],
- tolerance: float = ...,
- reorder_inout: bool = ...,
-) -> tuple[Path, Path]: ...
-def inside_circle(
- cx: float, cy: float, r: float
-) -> Callable[[tuple[float, float]], bool]: ...
-def get_cos_sin(x0: float, y0: float, x1: float, y1: float) -> tuple[float, float]: ...
-def check_if_parallel(
- dx1: float, dy1: float, dx2: float, dy2: float, tolerance: float = ...
-) -> Literal[-1, False, 1]: ...
-def get_parallels(
- bezier2: ArrayLike, width: float
-) -> tuple[list[tuple[float, float]], list[tuple[float, float]]]: ...
-def find_control_points(
- c1x: float, c1y: float, mmx: float, mmy: float, c2x: float, c2y: float
-) -> list[tuple[float, float]]: ...
-def make_wedged_bezier2(
- bezier2: ArrayLike, width: float, w1: float = ..., wm: float = ..., w2: float = ...
-) -> tuple[list[tuple[float, float]], list[tuple[float, float]]]: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/category.py b/contrib/python/matplotlib/py3/matplotlib/category.py
deleted file mode 100644
index 4ac2379ea5..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/category.py
+++ /dev/null
@@ -1,233 +0,0 @@
-"""
-Plotting of string "category" data: ``plot(['d', 'f', 'a'], [1, 2, 3])`` will
-plot three points with x-axis values of 'd', 'f', 'a'.
-
-See :doc:`/gallery/lines_bars_and_markers/categorical_variables` for an
-example.
-
-The module uses Matplotlib's `matplotlib.units` mechanism to convert from
-strings to integers and provides a tick locator, a tick formatter, and the
-`.UnitData` class that creates and stores the string-to-integer mapping.
-"""
-
-from collections import OrderedDict
-import dateutil.parser
-import itertools
-import logging
-
-import numpy as np
-
-from matplotlib import _api, ticker, units
-
-
-_log = logging.getLogger(__name__)
-
-
-class StrCategoryConverter(units.ConversionInterface):
- @staticmethod
- def convert(value, unit, axis):
- """
- Convert strings in *value* to floats using mapping information stored
- in the *unit* object.
-
- Parameters
- ----------
- value : str or iterable
- Value or list of values to be converted.
- unit : `.UnitData`
- An object mapping strings to integers.
- axis : `~matplotlib.axis.Axis`
- The axis on which the converted value is plotted.
-
- .. note:: *axis* is unused.
-
- Returns
- -------
- float or `~numpy.ndarray` of float
- """
- if unit is None:
- raise ValueError(
- 'Missing category information for StrCategoryConverter; '
- 'this might be caused by unintendedly mixing categorical and '
- 'numeric data')
- StrCategoryConverter._validate_unit(unit)
- # dtype = object preserves numerical pass throughs
- values = np.atleast_1d(np.array(value, dtype=object))
- # force an update so it also does type checking
- unit.update(values)
- return np.vectorize(unit._mapping.__getitem__, otypes=[float])(values)
-
- @staticmethod
- def axisinfo(unit, axis):
- """
- Set the default axis ticks and labels.
-
- Parameters
- ----------
- unit : `.UnitData`
- object string unit information for value
- axis : `~matplotlib.axis.Axis`
- axis for which information is being set
-
- .. note:: *axis* is not used
-
- Returns
- -------
- `~matplotlib.units.AxisInfo`
- Information to support default tick labeling
-
- """
- StrCategoryConverter._validate_unit(unit)
- # locator and formatter take mapping dict because
- # args need to be pass by reference for updates
- majloc = StrCategoryLocator(unit._mapping)
- majfmt = StrCategoryFormatter(unit._mapping)
- return units.AxisInfo(majloc=majloc, majfmt=majfmt)
-
- @staticmethod
- def default_units(data, axis):
- """
- Set and update the `~matplotlib.axis.Axis` units.
-
- Parameters
- ----------
- data : str or iterable of str
- axis : `~matplotlib.axis.Axis`
- axis on which the data is plotted
-
- Returns
- -------
- `.UnitData`
- object storing string to integer mapping
- """
- # the conversion call stack is default_units -> axis_info -> convert
- if axis.units is None:
- axis.set_units(UnitData(data))
- else:
- axis.units.update(data)
- return axis.units
-
- @staticmethod
- def _validate_unit(unit):
- if not hasattr(unit, '_mapping'):
- raise ValueError(
- f'Provided unit "{unit}" is not valid for a categorical '
- 'converter, as it does not have a _mapping attribute.')
-
-
-class StrCategoryLocator(ticker.Locator):
- """Tick at every integer mapping of the string data."""
- def __init__(self, units_mapping):
- """
- Parameters
- ----------
- units_mapping : dict
- Mapping of category names (str) to indices (int).
- """
- self._units = units_mapping
-
- def __call__(self):
- # docstring inherited
- return list(self._units.values())
-
- def tick_values(self, vmin, vmax):
- # docstring inherited
- return self()
-
-
-class StrCategoryFormatter(ticker.Formatter):
- """String representation of the data at every tick."""
- def __init__(self, units_mapping):
- """
- Parameters
- ----------
- units_mapping : dict
- Mapping of category names (str) to indices (int).
- """
- self._units = units_mapping
-
- def __call__(self, x, pos=None):
- # docstring inherited
- return self.format_ticks([x])[0]
-
- def format_ticks(self, values):
- # docstring inherited
- r_mapping = {v: self._text(k) for k, v in self._units.items()}
- return [r_mapping.get(round(val), '') for val in values]
-
- @staticmethod
- def _text(value):
- """Convert text values into utf-8 or ascii strings."""
- if isinstance(value, bytes):
- value = value.decode(encoding='utf-8')
- elif not isinstance(value, str):
- value = str(value)
- return value
-
-
-class UnitData:
- def __init__(self, data=None):
- """
- Create mapping between unique categorical values and integer ids.
-
- Parameters
- ----------
- data : iterable
- sequence of string values
- """
- self._mapping = OrderedDict()
- self._counter = itertools.count()
- if data is not None:
- self.update(data)
-
- @staticmethod
- def _str_is_convertible(val):
- """
- Helper method to check whether a string can be parsed as float or date.
- """
- try:
- float(val)
- except ValueError:
- try:
- dateutil.parser.parse(val)
- except (ValueError, TypeError):
- # TypeError if dateutil >= 2.8.1 else ValueError
- return False
- return True
-
- def update(self, data):
- """
- Map new values to integer identifiers.
-
- Parameters
- ----------
- data : iterable of str or bytes
-
- Raises
- ------
- TypeError
- If elements in *data* are neither str nor bytes.
- """
- data = np.atleast_1d(np.array(data, dtype=object))
- # check if convertible to number:
- convertible = True
- for val in OrderedDict.fromkeys(data):
- # OrderedDict just iterates over unique values in data.
- _api.check_isinstance((str, bytes), value=val)
- if convertible:
- # this will only be called so long as convertible is True.
- convertible = self._str_is_convertible(val)
- if val not in self._mapping:
- self._mapping[val] = next(self._counter)
- if data.size and convertible:
- _log.info('Using categorical units to plot a list of strings '
- 'that are all parsable as floats or dates. If these '
- 'strings should be plotted as numbers, cast to the '
- 'appropriate data type before plotting.')
-
-
-# Register the converter with Matplotlib's unit framework
-units.registry[str] = StrCategoryConverter()
-units.registry[np.str_] = StrCategoryConverter()
-units.registry[bytes] = StrCategoryConverter()
-units.registry[np.bytes_] = StrCategoryConverter()
diff --git a/contrib/python/matplotlib/py3/matplotlib/cbook.py b/contrib/python/matplotlib/py3/matplotlib/cbook.py
deleted file mode 100644
index f02486a0e2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/cbook.py
+++ /dev/null
@@ -1,2350 +0,0 @@
-"""
-A collection of utility functions and classes. Originally, many
-(but not all) were from the Python Cookbook -- hence the name cbook.
-"""
-
-import collections
-import collections.abc
-import contextlib
-import functools
-import gzip
-import itertools
-import math
-import operator
-import os
-from pathlib import Path
-import shlex
-import subprocess
-import sys
-import time
-import traceback
-import types
-import weakref
-
-import numpy as np
-
-try:
- from numpy.exceptions import VisibleDeprecationWarning # numpy >= 1.25
-except ImportError:
- from numpy import VisibleDeprecationWarning
-
-import matplotlib
-from matplotlib import _api, _c_internal_utils
-
-
-def _get_running_interactive_framework():
- """
- Return the interactive framework whose event loop is currently running, if
- any, or "headless" if no event loop can be started, or None.
-
- Returns
- -------
- Optional[str]
- One of the following values: "qt", "gtk3", "gtk4", "wx", "tk",
- "macosx", "headless", ``None``.
- """
- # Use ``sys.modules.get(name)`` rather than ``name in sys.modules`` as
- # entries can also have been explicitly set to None.
- QtWidgets = (
- sys.modules.get("PyQt6.QtWidgets")
- or sys.modules.get("PySide6.QtWidgets")
- or sys.modules.get("PyQt5.QtWidgets")
- or sys.modules.get("PySide2.QtWidgets")
- )
- if QtWidgets and QtWidgets.QApplication.instance():
- return "qt"
- Gtk = sys.modules.get("gi.repository.Gtk")
- if Gtk:
- if Gtk.MAJOR_VERSION == 4:
- from gi.repository import GLib
- if GLib.main_depth():
- return "gtk4"
- if Gtk.MAJOR_VERSION == 3 and Gtk.main_level():
- return "gtk3"
- wx = sys.modules.get("wx")
- if wx and wx.GetApp():
- return "wx"
- tkinter = sys.modules.get("tkinter")
- if tkinter:
- codes = {tkinter.mainloop.__code__, tkinter.Misc.mainloop.__code__}
- for frame in sys._current_frames().values():
- while frame:
- if frame.f_code in codes:
- return "tk"
- frame = frame.f_back
- # premetively break reference cycle between locals and the frame
- del frame
- macosx = sys.modules.get("matplotlib.backends._macosx")
- if macosx and macosx.event_loop_is_running():
- return "macosx"
- if not _c_internal_utils.display_is_valid():
- return "headless"
- return None
-
-
-def _exception_printer(exc):
- if _get_running_interactive_framework() in ["headless", None]:
- raise exc
- else:
- traceback.print_exc()
-
-
-class _StrongRef:
- """
- Wrapper similar to a weakref, but keeping a strong reference to the object.
- """
-
- def __init__(self, obj):
- self._obj = obj
-
- def __call__(self):
- return self._obj
-
- def __eq__(self, other):
- return isinstance(other, _StrongRef) and self._obj == other._obj
-
- def __hash__(self):
- return hash(self._obj)
-
-
-def _weak_or_strong_ref(func, callback):
- """
- Return a `WeakMethod` wrapping *func* if possible, else a `_StrongRef`.
- """
- try:
- return weakref.WeakMethod(func, callback)
- except TypeError:
- return _StrongRef(func)
-
-
-class CallbackRegistry:
- """
- Handle registering, processing, blocking, and disconnecting
- for a set of signals and callbacks:
-
- >>> def oneat(x):
- ... print('eat', x)
- >>> def ondrink(x):
- ... print('drink', x)
-
- >>> from matplotlib.cbook import CallbackRegistry
- >>> callbacks = CallbackRegistry()
-
- >>> id_eat = callbacks.connect('eat', oneat)
- >>> id_drink = callbacks.connect('drink', ondrink)
-
- >>> callbacks.process('drink', 123)
- drink 123
- >>> callbacks.process('eat', 456)
- eat 456
- >>> callbacks.process('be merry', 456) # nothing will be called
-
- >>> callbacks.disconnect(id_eat)
- >>> callbacks.process('eat', 456) # nothing will be called
-
- >>> with callbacks.blocked(signal='drink'):
- ... callbacks.process('drink', 123) # nothing will be called
- >>> callbacks.process('drink', 123)
- drink 123
-
- In practice, one should always disconnect all callbacks when they are
- no longer needed to avoid dangling references (and thus memory leaks).
- However, real code in Matplotlib rarely does so, and due to its design,
- it is rather difficult to place this kind of code. To get around this,
- and prevent this class of memory leaks, we instead store weak references
- to bound methods only, so when the destination object needs to die, the
- CallbackRegistry won't keep it alive.
-
- Parameters
- ----------
- exception_handler : callable, optional
- If not None, *exception_handler* must be a function that takes an
- `Exception` as single parameter. It gets called with any `Exception`
- raised by the callbacks during `CallbackRegistry.process`, and may
- either re-raise the exception or handle it in another manner.
-
- The default handler prints the exception (with `traceback.print_exc`) if
- an interactive event loop is running; it re-raises the exception if no
- interactive event loop is running.
-
- signals : list, optional
- If not None, *signals* is a list of signals that this registry handles:
- attempting to `process` or to `connect` to a signal not in the list
- throws a `ValueError`. The default, None, does not restrict the
- handled signals.
- """
-
- # We maintain two mappings:
- # callbacks: signal -> {cid -> weakref-to-callback}
- # _func_cid_map: signal -> {weakref-to-callback -> cid}
-
- def __init__(self, exception_handler=_exception_printer, *, signals=None):
- self._signals = None if signals is None else list(signals) # Copy it.
- self.exception_handler = exception_handler
- self.callbacks = {}
- self._cid_gen = itertools.count()
- self._func_cid_map = {}
- # A hidden variable that marks cids that need to be pickled.
- self._pickled_cids = set()
-
- def __getstate__(self):
- return {
- **vars(self),
- # In general, callbacks may not be pickled, so we just drop them,
- # unless directed otherwise by self._pickled_cids.
- "callbacks": {s: {cid: proxy() for cid, proxy in d.items()
- if cid in self._pickled_cids}
- for s, d in self.callbacks.items()},
- # It is simpler to reconstruct this from callbacks in __setstate__.
- "_func_cid_map": None,
- "_cid_gen": next(self._cid_gen)
- }
-
- def __setstate__(self, state):
- cid_count = state.pop('_cid_gen')
- vars(self).update(state)
- self.callbacks = {
- s: {cid: _weak_or_strong_ref(func, self._remove_proxy)
- for cid, func in d.items()}
- for s, d in self.callbacks.items()}
- self._func_cid_map = {
- s: {proxy: cid for cid, proxy in d.items()}
- for s, d in self.callbacks.items()}
- self._cid_gen = itertools.count(cid_count)
-
- def connect(self, signal, func):
- """Register *func* to be called when signal *signal* is generated."""
- if self._signals is not None:
- _api.check_in_list(self._signals, signal=signal)
- self._func_cid_map.setdefault(signal, {})
- proxy = _weak_or_strong_ref(func, self._remove_proxy)
- if proxy in self._func_cid_map[signal]:
- return self._func_cid_map[signal][proxy]
- cid = next(self._cid_gen)
- self._func_cid_map[signal][proxy] = cid
- self.callbacks.setdefault(signal, {})
- self.callbacks[signal][cid] = proxy
- return cid
-
- def _connect_picklable(self, signal, func):
- """
- Like `.connect`, but the callback is kept when pickling/unpickling.
-
- Currently internal-use only.
- """
- cid = self.connect(signal, func)
- self._pickled_cids.add(cid)
- return cid
-
- # Keep a reference to sys.is_finalizing, as sys may have been cleared out
- # at that point.
- def _remove_proxy(self, proxy, *, _is_finalizing=sys.is_finalizing):
- if _is_finalizing():
- # Weakrefs can't be properly torn down at that point anymore.
- return
- for signal, proxy_to_cid in list(self._func_cid_map.items()):
- cid = proxy_to_cid.pop(proxy, None)
- if cid is not None:
- del self.callbacks[signal][cid]
- self._pickled_cids.discard(cid)
- break
- else:
- # Not found
- return
- # Clean up empty dicts
- if len(self.callbacks[signal]) == 0:
- del self.callbacks[signal]
- del self._func_cid_map[signal]
-
- def disconnect(self, cid):
- """
- Disconnect the callback registered with callback id *cid*.
-
- No error is raised if such a callback does not exist.
- """
- self._pickled_cids.discard(cid)
- # Clean up callbacks
- for signal, cid_to_proxy in list(self.callbacks.items()):
- proxy = cid_to_proxy.pop(cid, None)
- if proxy is not None:
- break
- else:
- # Not found
- return
-
- proxy_to_cid = self._func_cid_map[signal]
- for current_proxy, current_cid in list(proxy_to_cid.items()):
- if current_cid == cid:
- assert proxy is current_proxy
- del proxy_to_cid[current_proxy]
- # Clean up empty dicts
- if len(self.callbacks[signal]) == 0:
- del self.callbacks[signal]
- del self._func_cid_map[signal]
-
- def process(self, s, *args, **kwargs):
- """
- Process signal *s*.
-
- All of the functions registered to receive callbacks on *s* will be
- called with ``*args`` and ``**kwargs``.
- """
- if self._signals is not None:
- _api.check_in_list(self._signals, signal=s)
- for ref in list(self.callbacks.get(s, {}).values()):
- func = ref()
- if func is not None:
- try:
- func(*args, **kwargs)
- # this does not capture KeyboardInterrupt, SystemExit,
- # and GeneratorExit
- except Exception as exc:
- if self.exception_handler is not None:
- self.exception_handler(exc)
- else:
- raise
-
- @contextlib.contextmanager
- def blocked(self, *, signal=None):
- """
- Block callback signals from being processed.
-
- A context manager to temporarily block/disable callback signals
- from being processed by the registered listeners.
-
- Parameters
- ----------
- signal : str, optional
- The callback signal to block. The default is to block all signals.
- """
- orig = self.callbacks
- try:
- if signal is None:
- # Empty out the callbacks
- self.callbacks = {}
- else:
- # Only remove the specific signal
- self.callbacks = {k: orig[k] for k in orig if k != signal}
- yield
- finally:
- self.callbacks = orig
-
-
-class silent_list(list):
- """
- A list with a short ``repr()``.
-
- This is meant to be used for a homogeneous list of artists, so that they
- don't cause long, meaningless output.
-
- Instead of ::
-
- [<matplotlib.lines.Line2D object at 0x7f5749fed3c8>,
- <matplotlib.lines.Line2D object at 0x7f5749fed4e0>,
- <matplotlib.lines.Line2D object at 0x7f5758016550>]
-
- one will get ::
-
- <a list of 3 Line2D objects>
-
- If ``self.type`` is None, the type name is obtained from the first item in
- the list (if any).
- """
-
- def __init__(self, type, seq=None):
- self.type = type
- if seq is not None:
- self.extend(seq)
-
- def __repr__(self):
- if self.type is not None or len(self) != 0:
- tp = self.type if self.type is not None else type(self[0]).__name__
- return f"<a list of {len(self)} {tp} objects>"
- else:
- return "<an empty list>"
-
-
-def _local_over_kwdict(
- local_var, kwargs, *keys,
- warning_cls=_api.MatplotlibDeprecationWarning):
- out = local_var
- for key in keys:
- kwarg_val = kwargs.pop(key, None)
- if kwarg_val is not None:
- if out is None:
- out = kwarg_val
- else:
- _api.warn_external(f'"{key}" keyword argument will be ignored',
- warning_cls)
- return out
-
-
-def strip_math(s):
- """
- Remove latex formatting from mathtext.
-
- Only handles fully math and fully non-math strings.
- """
- if len(s) >= 2 and s[0] == s[-1] == "$":
- s = s[1:-1]
- for tex, plain in [
- (r"\times", "x"), # Specifically for Formatter support.
- (r"\mathdefault", ""),
- (r"\rm", ""),
- (r"\cal", ""),
- (r"\tt", ""),
- (r"\it", ""),
- ("\\", ""),
- ("{", ""),
- ("}", ""),
- ]:
- s = s.replace(tex, plain)
- return s
-
-
-def _strip_comment(s):
- """Strip everything from the first unquoted #."""
- pos = 0
- while True:
- quote_pos = s.find('"', pos)
- hash_pos = s.find('#', pos)
- if quote_pos < 0:
- without_comment = s if hash_pos < 0 else s[:hash_pos]
- return without_comment.strip()
- elif 0 <= hash_pos < quote_pos:
- return s[:hash_pos].strip()
- else:
- closing_quote_pos = s.find('"', quote_pos + 1)
- if closing_quote_pos < 0:
- raise ValueError(
- f"Missing closing quote in: {s!r}. If you need a double-"
- 'quote inside a string, use escaping: e.g. "the \" char"')
- pos = closing_quote_pos + 1 # behind closing quote
-
-
-def is_writable_file_like(obj):
- """Return whether *obj* looks like a file object with a *write* method."""
- return callable(getattr(obj, 'write', None))
-
-
-def file_requires_unicode(x):
- """
- Return whether the given writable file-like object requires Unicode to be
- written to it.
- """
- try:
- x.write(b'')
- except TypeError:
- return True
- else:
- return False
-
-
-def to_filehandle(fname, flag='r', return_opened=False, encoding=None):
- """
- Convert a path to an open file handle or pass-through a file-like object.
-
- Consider using `open_file_cm` instead, as it allows one to properly close
- newly created file objects more easily.
-
- Parameters
- ----------
- fname : str or path-like or file-like
- If `str` or `os.PathLike`, the file is opened using the flags specified
- by *flag* and *encoding*. If a file-like object, it is passed through.
- flag : str, default: 'r'
- Passed as the *mode* argument to `open` when *fname* is `str` or
- `os.PathLike`; ignored if *fname* is file-like.
- return_opened : bool, default: False
- If True, return both the file object and a boolean indicating whether
- this was a new file (that the caller needs to close). If False, return
- only the new file.
- encoding : str or None, default: None
- Passed as the *mode* argument to `open` when *fname* is `str` or
- `os.PathLike`; ignored if *fname* is file-like.
-
- Returns
- -------
- fh : file-like
- opened : bool
- *opened* is only returned if *return_opened* is True.
- """
- if isinstance(fname, os.PathLike):
- fname = os.fspath(fname)
- if isinstance(fname, str):
- if fname.endswith('.gz'):
- fh = gzip.open(fname, flag)
- elif fname.endswith('.bz2'):
- # python may not be compiled with bz2 support,
- # bury import until we need it
- import bz2
- fh = bz2.BZ2File(fname, flag)
- else:
- fh = open(fname, flag, encoding=encoding)
- opened = True
- elif hasattr(fname, 'seek'):
- fh = fname
- opened = False
- else:
- raise ValueError('fname must be a PathLike or file handle')
- if return_opened:
- return fh, opened
- return fh
-
-
-def open_file_cm(path_or_file, mode="r", encoding=None):
- r"""Pass through file objects and context-manage path-likes."""
- fh, opened = to_filehandle(path_or_file, mode, True, encoding)
- return fh if opened else contextlib.nullcontext(fh)
-
-
-def is_scalar_or_string(val):
- """Return whether the given object is a scalar or string like."""
- return isinstance(val, str) or not np.iterable(val)
-
-
-@_api.delete_parameter(
- "3.8", "np_load", alternative="open(get_sample_data(..., asfileobj=False))")
-def get_sample_data(fname, asfileobj=True, *, np_load=True):
- """
- Return a sample data file. *fname* is a path relative to the
- :file:`mpl-data/sample_data` directory. If *asfileobj* is `True`
- return a file object, otherwise just a file path.
-
- Sample data files are stored in the 'mpl-data/sample_data' directory within
- the Matplotlib package.
-
- If the filename ends in .gz, the file is implicitly ungzipped. If the
- filename ends with .npy or .npz, and *asfileobj* is `True`, the file is
- loaded with `numpy.load`.
- """
- path = _get_data_path('sample_data', fname)
- if asfileobj:
- suffix = path.suffix.lower()
- if suffix == '.gz':
- return gzip.open(path)
- elif suffix in ['.npy', '.npz']:
- if np_load:
- return np.load(path)
- else:
- return path.open('rb')
- elif suffix in ['.csv', '.xrc', '.txt']:
- return path.open('r')
- else:
- return path.open('rb')
- else:
- return str(path)
-
-
-def _get_data_path(*args):
- """
- Return the `pathlib.Path` to a resource file provided by Matplotlib.
-
- ``*args`` specify a path relative to the base data path.
- """
- return Path(matplotlib.get_data_path(), *args)
-
-
-def flatten(seq, scalarp=is_scalar_or_string):
- """
- Return a generator of flattened nested containers.
-
- For example:
-
- >>> from matplotlib.cbook import flatten
- >>> l = (('John', ['Hunter']), (1, 23), [[([42, (5, 23)], )]])
- >>> print(list(flatten(l)))
- ['John', 'Hunter', 1, 23, 42, 5, 23]
-
- By: Composite of Holger Krekel and Luther Blissett
- From: https://code.activestate.com/recipes/121294/
- and Recipe 1.12 in cookbook
- """
- for item in seq:
- if scalarp(item) or item is None:
- yield item
- else:
- yield from flatten(item, scalarp)
-
-
-@_api.deprecated("3.8")
-class Stack:
- """
- Stack of elements with a movable cursor.
-
- Mimics home/back/forward in a web browser.
- """
-
- def __init__(self, default=None):
- self.clear()
- self._default = default
-
- def __call__(self):
- """Return the current element, or None."""
- if not self._elements:
- return self._default
- else:
- return self._elements[self._pos]
-
- def __len__(self):
- return len(self._elements)
-
- def __getitem__(self, ind):
- return self._elements[ind]
-
- def forward(self):
- """Move the position forward and return the current element."""
- self._pos = min(self._pos + 1, len(self._elements) - 1)
- return self()
-
- def back(self):
- """Move the position back and return the current element."""
- if self._pos > 0:
- self._pos -= 1
- return self()
-
- def push(self, o):
- """
- Push *o* to the stack at current position. Discard all later elements.
-
- *o* is returned.
- """
- self._elements = self._elements[:self._pos + 1] + [o]
- self._pos = len(self._elements) - 1
- return self()
-
- def home(self):
- """
- Push the first element onto the top of the stack.
-
- The first element is returned.
- """
- if not self._elements:
- return
- self.push(self._elements[0])
- return self()
-
- def empty(self):
- """Return whether the stack is empty."""
- return len(self._elements) == 0
-
- def clear(self):
- """Empty the stack."""
- self._pos = -1
- self._elements = []
-
- def bubble(self, o):
- """
- Raise all references of *o* to the top of the stack, and return it.
-
- Raises
- ------
- ValueError
- If *o* is not in the stack.
- """
- if o not in self._elements:
- raise ValueError('Given element not contained in the stack')
- old_elements = self._elements.copy()
- self.clear()
- top_elements = []
- for elem in old_elements:
- if elem == o:
- top_elements.append(elem)
- else:
- self.push(elem)
- for _ in top_elements:
- self.push(o)
- return o
-
- def remove(self, o):
- """
- Remove *o* from the stack.
-
- Raises
- ------
- ValueError
- If *o* is not in the stack.
- """
- if o not in self._elements:
- raise ValueError('Given element not contained in the stack')
- old_elements = self._elements.copy()
- self.clear()
- for elem in old_elements:
- if elem != o:
- self.push(elem)
-
-
-class _Stack:
- """
- Stack of elements with a movable cursor.
-
- Mimics home/back/forward in a web browser.
- """
-
- def __init__(self):
- self._pos = -1
- self._elements = []
-
- def clear(self):
- """Empty the stack."""
- self._pos = -1
- self._elements = []
-
- def __call__(self):
- """Return the current element, or None."""
- return self._elements[self._pos] if self._elements else None
-
- def __len__(self):
- return len(self._elements)
-
- def __getitem__(self, ind):
- return self._elements[ind]
-
- def forward(self):
- """Move the position forward and return the current element."""
- self._pos = min(self._pos + 1, len(self._elements) - 1)
- return self()
-
- def back(self):
- """Move the position back and return the current element."""
- self._pos = max(self._pos - 1, 0)
- return self()
-
- def push(self, o):
- """
- Push *o* to the stack after the current position, and return *o*.
-
- Discard all later elements.
- """
- self._elements[self._pos + 1:] = [o]
- self._pos = len(self._elements) - 1
- return o
-
- def home(self):
- """
- Push the first element onto the top of the stack.
-
- The first element is returned.
- """
- return self.push(self._elements[0]) if self._elements else None
-
-
-def safe_masked_invalid(x, copy=False):
- x = np.array(x, subok=True, copy=copy)
- if not x.dtype.isnative:
- # If we have already made a copy, do the byteswap in place, else make a
- # copy with the byte order swapped.
- # Swap to native order.
- x = x.byteswap(inplace=copy).view(x.dtype.newbyteorder('N'))
- try:
- xm = np.ma.masked_where(~(np.isfinite(x)), x, copy=False)
- except TypeError:
- return x
- return xm
-
-
-def print_cycles(objects, outstream=sys.stdout, show_progress=False):
- """
- Print loops of cyclic references in the given *objects*.
-
- It is often useful to pass in ``gc.garbage`` to find the cycles that are
- preventing some objects from being garbage collected.
-
- Parameters
- ----------
- objects
- A list of objects to find cycles in.
- outstream
- The stream for output.
- show_progress : bool
- If True, print the number of objects reached as they are found.
- """
- import gc
-
- def print_path(path):
- for i, step in enumerate(path):
- # next "wraps around"
- next = path[(i + 1) % len(path)]
-
- outstream.write(" %s -- " % type(step))
- if isinstance(step, dict):
- for key, val in step.items():
- if val is next:
- outstream.write(f"[{key!r}]")
- break
- if key is next:
- outstream.write(f"[key] = {val!r}")
- break
- elif isinstance(step, list):
- outstream.write("[%d]" % step.index(next))
- elif isinstance(step, tuple):
- outstream.write("( tuple )")
- else:
- outstream.write(repr(step))
- outstream.write(" ->\n")
- outstream.write("\n")
-
- def recurse(obj, start, all, current_path):
- if show_progress:
- outstream.write("%d\r" % len(all))
-
- all[id(obj)] = None
-
- referents = gc.get_referents(obj)
- for referent in referents:
- # If we've found our way back to the start, this is
- # a cycle, so print it out
- if referent is start:
- print_path(current_path)
-
- # Don't go back through the original list of objects, or
- # through temporary references to the object, since those
- # are just an artifact of the cycle detector itself.
- elif referent is objects or isinstance(referent, types.FrameType):
- continue
-
- # We haven't seen this object before, so recurse
- elif id(referent) not in all:
- recurse(referent, start, all, current_path + [obj])
-
- for obj in objects:
- outstream.write(f"Examining: {obj!r}\n")
- recurse(obj, obj, {}, [])
-
-
-class Grouper:
- """
- A disjoint-set data structure.
-
- Objects can be joined using :meth:`join`, tested for connectedness
- using :meth:`joined`, and all disjoint sets can be retrieved by
- using the object as an iterator.
-
- The objects being joined must be hashable and weak-referenceable.
-
- Examples
- --------
- >>> from matplotlib.cbook import Grouper
- >>> class Foo:
- ... def __init__(self, s):
- ... self.s = s
- ... def __repr__(self):
- ... return self.s
- ...
- >>> a, b, c, d, e, f = [Foo(x) for x in 'abcdef']
- >>> grp = Grouper()
- >>> grp.join(a, b)
- >>> grp.join(b, c)
- >>> grp.join(d, e)
- >>> list(grp)
- [[a, b, c], [d, e]]
- >>> grp.joined(a, b)
- True
- >>> grp.joined(a, c)
- True
- >>> grp.joined(a, d)
- False
- """
-
- def __init__(self, init=()):
- self._mapping = weakref.WeakKeyDictionary(
- {x: weakref.WeakSet([x]) for x in init})
-
- def __getstate__(self):
- return {
- **vars(self),
- # Convert weak refs to strong ones.
- "_mapping": {k: set(v) for k, v in self._mapping.items()},
- }
-
- def __setstate__(self, state):
- vars(self).update(state)
- # Convert strong refs to weak ones.
- self._mapping = weakref.WeakKeyDictionary(
- {k: weakref.WeakSet(v) for k, v in self._mapping.items()})
-
- def __contains__(self, item):
- return item in self._mapping
-
- @_api.deprecated("3.8", alternative="none, you no longer need to clean a Grouper")
- def clean(self):
- """Clean dead weak references from the dictionary."""
-
- def join(self, a, *args):
- """
- Join given arguments into the same set. Accepts one or more arguments.
- """
- mapping = self._mapping
- set_a = mapping.setdefault(a, weakref.WeakSet([a]))
-
- for arg in args:
- set_b = mapping.get(arg, weakref.WeakSet([arg]))
- if set_b is not set_a:
- if len(set_b) > len(set_a):
- set_a, set_b = set_b, set_a
- set_a.update(set_b)
- for elem in set_b:
- mapping[elem] = set_a
-
- def joined(self, a, b):
- """Return whether *a* and *b* are members of the same set."""
- return (self._mapping.get(a, object()) is self._mapping.get(b))
-
- def remove(self, a):
- """Remove *a* from the grouper, doing nothing if it is not there."""
- set_a = self._mapping.pop(a, None)
- if set_a:
- set_a.remove(a)
-
- def __iter__(self):
- """
- Iterate over each of the disjoint sets as a list.
-
- The iterator is invalid if interleaved with calls to join().
- """
- unique_groups = {id(group): group for group in self._mapping.values()}
- for group in unique_groups.values():
- yield [x for x in group]
-
- def get_siblings(self, a):
- """Return all of the items joined with *a*, including itself."""
- siblings = self._mapping.get(a, [a])
- return [x for x in siblings]
-
-
-class GrouperView:
- """Immutable view over a `.Grouper`."""
-
- def __init__(self, grouper): self._grouper = grouper
- def __contains__(self, item): return item in self._grouper
- def __iter__(self): return iter(self._grouper)
- def joined(self, a, b): return self._grouper.joined(a, b)
- def get_siblings(self, a): return self._grouper.get_siblings(a)
-
-
-def simple_linear_interpolation(a, steps):
- """
- Resample an array with ``steps - 1`` points between original point pairs.
-
- Along each column of *a*, ``(steps - 1)`` points are introduced between
- each original values; the values are linearly interpolated.
-
- Parameters
- ----------
- a : array, shape (n, ...)
- steps : int
-
- Returns
- -------
- array
- shape ``((n - 1) * steps + 1, ...)``
- """
- fps = a.reshape((len(a), -1))
- xp = np.arange(len(a)) * steps
- x = np.arange((len(a) - 1) * steps + 1)
- return (np.column_stack([np.interp(x, xp, fp) for fp in fps.T])
- .reshape((len(x),) + a.shape[1:]))
-
-
-def delete_masked_points(*args):
- """
- Find all masked and/or non-finite points in a set of arguments,
- and return the arguments with only the unmasked points remaining.
-
- Arguments can be in any of 5 categories:
-
- 1) 1-D masked arrays
- 2) 1-D ndarrays
- 3) ndarrays with more than one dimension
- 4) other non-string iterables
- 5) anything else
-
- The first argument must be in one of the first four categories;
- any argument with a length differing from that of the first
- argument (and hence anything in category 5) then will be
- passed through unchanged.
-
- Masks are obtained from all arguments of the correct length
- in categories 1, 2, and 4; a point is bad if masked in a masked
- array or if it is a nan or inf. No attempt is made to
- extract a mask from categories 2, 3, and 4 if `numpy.isfinite`
- does not yield a Boolean array.
-
- All input arguments that are not passed unchanged are returned
- as ndarrays after removing the points or rows corresponding to
- masks in any of the arguments.
-
- A vastly simpler version of this function was originally
- written as a helper for Axes.scatter().
-
- """
- if not len(args):
- return ()
- if is_scalar_or_string(args[0]):
- raise ValueError("First argument must be a sequence")
- nrecs = len(args[0])
- margs = []
- seqlist = [False] * len(args)
- for i, x in enumerate(args):
- if not isinstance(x, str) and np.iterable(x) and len(x) == nrecs:
- seqlist[i] = True
- if isinstance(x, np.ma.MaskedArray):
- if x.ndim > 1:
- raise ValueError("Masked arrays must be 1-D")
- else:
- x = np.asarray(x)
- margs.append(x)
- masks = [] # List of masks that are True where good.
- for i, x in enumerate(margs):
- if seqlist[i]:
- if x.ndim > 1:
- continue # Don't try to get nan locations unless 1-D.
- if isinstance(x, np.ma.MaskedArray):
- masks.append(~np.ma.getmaskarray(x)) # invert the mask
- xd = x.data
- else:
- xd = x
- try:
- mask = np.isfinite(xd)
- if isinstance(mask, np.ndarray):
- masks.append(mask)
- except Exception: # Fixme: put in tuple of possible exceptions?
- pass
- if len(masks):
- mask = np.logical_and.reduce(masks)
- igood = mask.nonzero()[0]
- if len(igood) < nrecs:
- for i, x in enumerate(margs):
- if seqlist[i]:
- margs[i] = x[igood]
- for i, x in enumerate(margs):
- if seqlist[i] and isinstance(x, np.ma.MaskedArray):
- margs[i] = x.filled()
- return margs
-
-
-def _combine_masks(*args):
- """
- Find all masked and/or non-finite points in a set of arguments,
- and return the arguments as masked arrays with a common mask.
-
- Arguments can be in any of 5 categories:
-
- 1) 1-D masked arrays
- 2) 1-D ndarrays
- 3) ndarrays with more than one dimension
- 4) other non-string iterables
- 5) anything else
-
- The first argument must be in one of the first four categories;
- any argument with a length differing from that of the first
- argument (and hence anything in category 5) then will be
- passed through unchanged.
-
- Masks are obtained from all arguments of the correct length
- in categories 1, 2, and 4; a point is bad if masked in a masked
- array or if it is a nan or inf. No attempt is made to
- extract a mask from categories 2 and 4 if `numpy.isfinite`
- does not yield a Boolean array. Category 3 is included to
- support RGB or RGBA ndarrays, which are assumed to have only
- valid values and which are passed through unchanged.
-
- All input arguments that are not passed unchanged are returned
- as masked arrays if any masked points are found, otherwise as
- ndarrays.
-
- """
- if not len(args):
- return ()
- if is_scalar_or_string(args[0]):
- raise ValueError("First argument must be a sequence")
- nrecs = len(args[0])
- margs = [] # Output args; some may be modified.
- seqlist = [False] * len(args) # Flags: True if output will be masked.
- masks = [] # List of masks.
- for i, x in enumerate(args):
- if is_scalar_or_string(x) or len(x) != nrecs:
- margs.append(x) # Leave it unmodified.
- else:
- if isinstance(x, np.ma.MaskedArray) and x.ndim > 1:
- raise ValueError("Masked arrays must be 1-D")
- try:
- x = np.asanyarray(x)
- except (VisibleDeprecationWarning, ValueError):
- # NumPy 1.19 raises a warning about ragged arrays, but we want
- # to accept basically anything here.
- x = np.asanyarray(x, dtype=object)
- if x.ndim == 1:
- x = safe_masked_invalid(x)
- seqlist[i] = True
- if np.ma.is_masked(x):
- masks.append(np.ma.getmaskarray(x))
- margs.append(x) # Possibly modified.
- if len(masks):
- mask = np.logical_or.reduce(masks)
- for i, x in enumerate(margs):
- if seqlist[i]:
- margs[i] = np.ma.array(x, mask=mask)
- return margs
-
-
-def boxplot_stats(X, whis=1.5, bootstrap=None, labels=None,
- autorange=False):
- r"""
- Return a list of dictionaries of statistics used to draw a series of box
- and whisker plots using `~.Axes.bxp`.
-
- Parameters
- ----------
- X : array-like
- Data that will be represented in the boxplots. Should have 2 or
- fewer dimensions.
-
- whis : float or (float, float), default: 1.5
- The position of the whiskers.
-
- If a float, the lower whisker is at the lowest datum above
- ``Q1 - whis*(Q3-Q1)``, and the upper whisker at the highest datum below
- ``Q3 + whis*(Q3-Q1)``, where Q1 and Q3 are the first and third
- quartiles. The default value of ``whis = 1.5`` corresponds to Tukey's
- original definition of boxplots.
-
- If a pair of floats, they indicate the percentiles at which to draw the
- whiskers (e.g., (5, 95)). In particular, setting this to (0, 100)
- results in whiskers covering the whole range of the data.
-
- In the edge case where ``Q1 == Q3``, *whis* is automatically set to
- (0, 100) (cover the whole range of the data) if *autorange* is True.
-
- Beyond the whiskers, data are considered outliers and are plotted as
- individual points.
-
- bootstrap : int, optional
- Number of times the confidence intervals around the median
- should be bootstrapped (percentile method).
-
- labels : array-like, optional
- Labels for each dataset. Length must be compatible with
- dimensions of *X*.
-
- autorange : bool, optional (False)
- When `True` and the data are distributed such that the 25th and 75th
- percentiles are equal, ``whis`` is set to (0, 100) such that the
- whisker ends are at the minimum and maximum of the data.
-
- Returns
- -------
- list of dict
- A list of dictionaries containing the results for each column
- of data. Keys of each dictionary are the following:
-
- ======== ===================================
- Key Value Description
- ======== ===================================
- label tick label for the boxplot
- mean arithmetic mean value
- med 50th percentile
- q1 first quartile (25th percentile)
- q3 third quartile (75th percentile)
- iqr interquartile range
- cilo lower notch around the median
- cihi upper notch around the median
- whislo end of the lower whisker
- whishi end of the upper whisker
- fliers outliers
- ======== ===================================
-
- Notes
- -----
- Non-bootstrapping approach to confidence interval uses Gaussian-based
- asymptotic approximation:
-
- .. math::
-
- \mathrm{med} \pm 1.57 \times \frac{\mathrm{iqr}}{\sqrt{N}}
-
- General approach from:
- McGill, R., Tukey, J.W., and Larsen, W.A. (1978) "Variations of
- Boxplots", The American Statistician, 32:12-16.
- """
-
- def _bootstrap_median(data, N=5000):
- # determine 95% confidence intervals of the median
- M = len(data)
- percentiles = [2.5, 97.5]
-
- bs_index = np.random.randint(M, size=(N, M))
- bsData = data[bs_index]
- estimate = np.median(bsData, axis=1, overwrite_input=True)
-
- CI = np.percentile(estimate, percentiles)
- return CI
-
- def _compute_conf_interval(data, med, iqr, bootstrap):
- if bootstrap is not None:
- # Do a bootstrap estimate of notch locations.
- # get conf. intervals around median
- CI = _bootstrap_median(data, N=bootstrap)
- notch_min = CI[0]
- notch_max = CI[1]
- else:
-
- N = len(data)
- notch_min = med - 1.57 * iqr / np.sqrt(N)
- notch_max = med + 1.57 * iqr / np.sqrt(N)
-
- return notch_min, notch_max
-
- # output is a list of dicts
- bxpstats = []
-
- # convert X to a list of lists
- X = _reshape_2D(X, "X")
-
- ncols = len(X)
- if labels is None:
- labels = itertools.repeat(None)
- elif len(labels) != ncols:
- raise ValueError("Dimensions of labels and X must be compatible")
-
- input_whis = whis
- for ii, (x, label) in enumerate(zip(X, labels)):
-
- # empty dict
- stats = {}
- if label is not None:
- stats['label'] = label
-
- # restore whis to the input values in case it got changed in the loop
- whis = input_whis
-
- # note tricksiness, append up here and then mutate below
- bxpstats.append(stats)
-
- # if empty, bail
- if len(x) == 0:
- stats['fliers'] = np.array([])
- stats['mean'] = np.nan
- stats['med'] = np.nan
- stats['q1'] = np.nan
- stats['q3'] = np.nan
- stats['iqr'] = np.nan
- stats['cilo'] = np.nan
- stats['cihi'] = np.nan
- stats['whislo'] = np.nan
- stats['whishi'] = np.nan
- continue
-
- # up-convert to an array, just to be safe
- x = np.asarray(x)
-
- # arithmetic mean
- stats['mean'] = np.mean(x)
-
- # medians and quartiles
- q1, med, q3 = np.percentile(x, [25, 50, 75])
-
- # interquartile range
- stats['iqr'] = q3 - q1
- if stats['iqr'] == 0 and autorange:
- whis = (0, 100)
-
- # conf. interval around median
- stats['cilo'], stats['cihi'] = _compute_conf_interval(
- x, med, stats['iqr'], bootstrap
- )
-
- # lowest/highest non-outliers
- if np.iterable(whis) and not isinstance(whis, str):
- loval, hival = np.percentile(x, whis)
- elif np.isreal(whis):
- loval = q1 - whis * stats['iqr']
- hival = q3 + whis * stats['iqr']
- else:
- raise ValueError('whis must be a float or list of percentiles')
-
- # get high extreme
- wiskhi = x[x <= hival]
- if len(wiskhi) == 0 or np.max(wiskhi) < q3:
- stats['whishi'] = q3
- else:
- stats['whishi'] = np.max(wiskhi)
-
- # get low extreme
- wisklo = x[x >= loval]
- if len(wisklo) == 0 or np.min(wisklo) > q1:
- stats['whislo'] = q1
- else:
- stats['whislo'] = np.min(wisklo)
-
- # compute a single array of outliers
- stats['fliers'] = np.concatenate([
- x[x < stats['whislo']],
- x[x > stats['whishi']],
- ])
-
- # add in the remaining stats
- stats['q1'], stats['med'], stats['q3'] = q1, med, q3
-
- return bxpstats
-
-
-#: Maps short codes for line style to their full name used by backends.
-ls_mapper = {'-': 'solid', '--': 'dashed', '-.': 'dashdot', ':': 'dotted'}
-#: Maps full names for line styles used by backends to their short codes.
-ls_mapper_r = {v: k for k, v in ls_mapper.items()}
-
-
-def contiguous_regions(mask):
- """
- Return a list of (ind0, ind1) such that ``mask[ind0:ind1].all()`` is
- True and we cover all such regions.
- """
- mask = np.asarray(mask, dtype=bool)
-
- if not mask.size:
- return []
-
- # Find the indices of region changes, and correct offset
- idx, = np.nonzero(mask[:-1] != mask[1:])
- idx += 1
-
- # List operations are faster for moderately sized arrays
- idx = idx.tolist()
-
- # Add first and/or last index if needed
- if mask[0]:
- idx = [0] + idx
- if mask[-1]:
- idx.append(len(mask))
-
- return list(zip(idx[::2], idx[1::2]))
-
-
-def is_math_text(s):
- """
- Return whether the string *s* contains math expressions.
-
- This is done by checking whether *s* contains an even number of
- non-escaped dollar signs.
- """
- s = str(s)
- dollar_count = s.count(r'$') - s.count(r'\$')
- even_dollars = (dollar_count > 0 and dollar_count % 2 == 0)
- return even_dollars
-
-
-def _to_unmasked_float_array(x):
- """
- Convert a sequence to a float array; if input was a masked array, masked
- values are converted to nans.
- """
- if hasattr(x, 'mask'):
- return np.ma.asarray(x, float).filled(np.nan)
- else:
- return np.asarray(x, float)
-
-
-def _check_1d(x):
- """Convert scalars to 1D arrays; pass-through arrays as is."""
- # Unpack in case of e.g. Pandas or xarray object
- x = _unpack_to_numpy(x)
- # plot requires `shape` and `ndim`. If passed an
- # object that doesn't provide them, then force to numpy array.
- # Note this will strip unit information.
- if (not hasattr(x, 'shape') or
- not hasattr(x, 'ndim') or
- len(x.shape) < 1):
- return np.atleast_1d(x)
- else:
- return x
-
-
-def _reshape_2D(X, name):
- """
- Use Fortran ordering to convert ndarrays and lists of iterables to lists of
- 1D arrays.
-
- Lists of iterables are converted by applying `numpy.asanyarray` to each of
- their elements. 1D ndarrays are returned in a singleton list containing
- them. 2D ndarrays are converted to the list of their *columns*.
-
- *name* is used to generate the error message for invalid inputs.
- """
-
- # Unpack in case of e.g. Pandas or xarray object
- X = _unpack_to_numpy(X)
-
- # Iterate over columns for ndarrays.
- if isinstance(X, np.ndarray):
- X = X.T
-
- if len(X) == 0:
- return [[]]
- elif X.ndim == 1 and np.ndim(X[0]) == 0:
- # 1D array of scalars: directly return it.
- return [X]
- elif X.ndim in [1, 2]:
- # 2D array, or 1D array of iterables: flatten them first.
- return [np.reshape(x, -1) for x in X]
- else:
- raise ValueError(f'{name} must have 2 or fewer dimensions')
-
- # Iterate over list of iterables.
- if len(X) == 0:
- return [[]]
-
- result = []
- is_1d = True
- for xi in X:
- # check if this is iterable, except for strings which we
- # treat as singletons.
- if not isinstance(xi, str):
- try:
- iter(xi)
- except TypeError:
- pass
- else:
- is_1d = False
- xi = np.asanyarray(xi)
- nd = np.ndim(xi)
- if nd > 1:
- raise ValueError(f'{name} must have 2 or fewer dimensions')
- result.append(xi.reshape(-1))
-
- if is_1d:
- # 1D array of scalars: directly return it.
- return [np.reshape(result, -1)]
- else:
- # 2D array, or 1D array of iterables: use flattened version.
- return result
-
-
-def violin_stats(X, method, points=100, quantiles=None):
- """
- Return a list of dictionaries of data which can be used to draw a series
- of violin plots.
-
- See the ``Returns`` section below to view the required keys of the
- dictionary.
-
- Users can skip this function and pass a user-defined set of dictionaries
- with the same keys to `~.axes.Axes.violinplot` instead of using Matplotlib
- to do the calculations. See the *Returns* section below for the keys
- that must be present in the dictionaries.
-
- Parameters
- ----------
- X : array-like
- Sample data that will be used to produce the gaussian kernel density
- estimates. Must have 2 or fewer dimensions.
-
- method : callable
- The method used to calculate the kernel density estimate for each
- column of data. When called via ``method(v, coords)``, it should
- return a vector of the values of the KDE evaluated at the values
- specified in coords.
-
- points : int, default: 100
- Defines the number of points to evaluate each of the gaussian kernel
- density estimates at.
-
- quantiles : array-like, default: None
- Defines (if not None) a list of floats in interval [0, 1] for each
- column of data, which represents the quantiles that will be rendered
- for that column of data. Must have 2 or fewer dimensions. 1D array will
- be treated as a singleton list containing them.
-
- Returns
- -------
- list of dict
- A list of dictionaries containing the results for each column of data.
- The dictionaries contain at least the following:
-
- - coords: A list of scalars containing the coordinates this particular
- kernel density estimate was evaluated at.
- - vals: A list of scalars containing the values of the kernel density
- estimate at each of the coordinates given in *coords*.
- - mean: The mean value for this column of data.
- - median: The median value for this column of data.
- - min: The minimum value for this column of data.
- - max: The maximum value for this column of data.
- - quantiles: The quantile values for this column of data.
- """
-
- # List of dictionaries describing each of the violins.
- vpstats = []
-
- # Want X to be a list of data sequences
- X = _reshape_2D(X, "X")
-
- # Want quantiles to be as the same shape as data sequences
- if quantiles is not None and len(quantiles) != 0:
- quantiles = _reshape_2D(quantiles, "quantiles")
- # Else, mock quantiles if it's none or empty
- else:
- quantiles = [[]] * len(X)
-
- # quantiles should have the same size as dataset
- if len(X) != len(quantiles):
- raise ValueError("List of violinplot statistics and quantiles values"
- " must have the same length")
-
- # Zip x and quantiles
- for (x, q) in zip(X, quantiles):
- # Dictionary of results for this distribution
- stats = {}
-
- # Calculate basic stats for the distribution
- min_val = np.min(x)
- max_val = np.max(x)
- quantile_val = np.percentile(x, 100 * q)
-
- # Evaluate the kernel density estimate
- coords = np.linspace(min_val, max_val, points)
- stats['vals'] = method(x, coords)
- stats['coords'] = coords
-
- # Store additional statistics for this distribution
- stats['mean'] = np.mean(x)
- stats['median'] = np.median(x)
- stats['min'] = min_val
- stats['max'] = max_val
- stats['quantiles'] = np.atleast_1d(quantile_val)
-
- # Append to output
- vpstats.append(stats)
-
- return vpstats
-
-
-def pts_to_prestep(x, *args):
- """
- Convert continuous line to pre-steps.
-
- Given a set of ``N`` points, convert to ``2N - 1`` points, which when
- connected linearly give a step function which changes values at the
- beginning of the intervals.
-
- Parameters
- ----------
- x : array
- The x location of the steps. May be empty.
-
- y1, ..., yp : array
- y arrays to be turned into steps; all must be the same length as ``x``.
-
- Returns
- -------
- array
- The x and y values converted to steps in the same order as the input;
- can be unpacked as ``x_out, y1_out, ..., yp_out``. If the input is
- length ``N``, each of these arrays will be length ``2N + 1``. For
- ``N=0``, the length will be 0.
-
- Examples
- --------
- >>> x_s, y1_s, y2_s = pts_to_prestep(x, y1, y2)
- """
- steps = np.zeros((1 + len(args), max(2 * len(x) - 1, 0)))
- # In all `pts_to_*step` functions, only assign once using *x* and *args*,
- # as converting to an array may be expensive.
- steps[0, 0::2] = x
- steps[0, 1::2] = steps[0, 0:-2:2]
- steps[1:, 0::2] = args
- steps[1:, 1::2] = steps[1:, 2::2]
- return steps
-
-
-def pts_to_poststep(x, *args):
- """
- Convert continuous line to post-steps.
-
- Given a set of ``N`` points convert to ``2N + 1`` points, which when
- connected linearly give a step function which changes values at the end of
- the intervals.
-
- Parameters
- ----------
- x : array
- The x location of the steps. May be empty.
-
- y1, ..., yp : array
- y arrays to be turned into steps; all must be the same length as ``x``.
-
- Returns
- -------
- array
- The x and y values converted to steps in the same order as the input;
- can be unpacked as ``x_out, y1_out, ..., yp_out``. If the input is
- length ``N``, each of these arrays will be length ``2N + 1``. For
- ``N=0``, the length will be 0.
-
- Examples
- --------
- >>> x_s, y1_s, y2_s = pts_to_poststep(x, y1, y2)
- """
- steps = np.zeros((1 + len(args), max(2 * len(x) - 1, 0)))
- steps[0, 0::2] = x
- steps[0, 1::2] = steps[0, 2::2]
- steps[1:, 0::2] = args
- steps[1:, 1::2] = steps[1:, 0:-2:2]
- return steps
-
-
-def pts_to_midstep(x, *args):
- """
- Convert continuous line to mid-steps.
-
- Given a set of ``N`` points convert to ``2N`` points which when connected
- linearly give a step function which changes values at the middle of the
- intervals.
-
- Parameters
- ----------
- x : array
- The x location of the steps. May be empty.
-
- y1, ..., yp : array
- y arrays to be turned into steps; all must be the same length as
- ``x``.
-
- Returns
- -------
- array
- The x and y values converted to steps in the same order as the input;
- can be unpacked as ``x_out, y1_out, ..., yp_out``. If the input is
- length ``N``, each of these arrays will be length ``2N``.
-
- Examples
- --------
- >>> x_s, y1_s, y2_s = pts_to_midstep(x, y1, y2)
- """
- steps = np.zeros((1 + len(args), 2 * len(x)))
- x = np.asanyarray(x)
- steps[0, 1:-1:2] = steps[0, 2::2] = (x[:-1] + x[1:]) / 2
- steps[0, :1] = x[:1] # Also works for zero-sized input.
- steps[0, -1:] = x[-1:]
- steps[1:, 0::2] = args
- steps[1:, 1::2] = steps[1:, 0::2]
- return steps
-
-
-STEP_LOOKUP_MAP = {'default': lambda x, y: (x, y),
- 'steps': pts_to_prestep,
- 'steps-pre': pts_to_prestep,
- 'steps-post': pts_to_poststep,
- 'steps-mid': pts_to_midstep}
-
-
-def index_of(y):
- """
- A helper function to create reasonable x values for the given *y*.
-
- This is used for plotting (x, y) if x values are not explicitly given.
-
- First try ``y.index`` (assuming *y* is a `pandas.Series`), if that
- fails, use ``range(len(y))``.
-
- This will be extended in the future to deal with more types of
- labeled data.
-
- Parameters
- ----------
- y : float or array-like
-
- Returns
- -------
- x, y : ndarray
- The x and y values to plot.
- """
- try:
- return y.index.to_numpy(), y.to_numpy()
- except AttributeError:
- pass
- try:
- y = _check_1d(y)
- except (VisibleDeprecationWarning, ValueError):
- # NumPy 1.19 will warn on ragged input, and we can't actually use it.
- pass
- else:
- return np.arange(y.shape[0], dtype=float), y
- raise ValueError('Input could not be cast to an at-least-1D NumPy array')
-
-
-def safe_first_element(obj):
- """
- Return the first element in *obj*.
-
- This is a type-independent way of obtaining the first element,
- supporting both index access and the iterator protocol.
- """
- return _safe_first_finite(obj, skip_nonfinite=False)
-
-
-def _safe_first_finite(obj, *, skip_nonfinite=True):
- """
- Return the first finite element in *obj* if one is available and skip_nonfinite is
- True. Otherwise, return the first element.
-
- This is a method for internal use.
-
- This is a type-independent way of obtaining the first finite element, supporting
- both index access and the iterator protocol.
- """
- def safe_isfinite(val):
- if val is None:
- return False
- try:
- return math.isfinite(val)
- except (TypeError, ValueError):
- pass
- try:
- return np.isfinite(val) if np.isscalar(val) else True
- except TypeError:
- # This is something that NumPy cannot make heads or tails of,
- # assume "finite"
- return True
- if skip_nonfinite is False:
- if isinstance(obj, collections.abc.Iterator):
- # needed to accept `array.flat` as input.
- # np.flatiter reports as an instance of collections.Iterator
- # but can still be indexed via [].
- # This has the side effect of re-setting the iterator, but
- # that is acceptable.
- try:
- return obj[0]
- except TypeError:
- pass
- raise RuntimeError("matplotlib does not support generators "
- "as input")
- return next(iter(obj))
- elif isinstance(obj, np.flatiter):
- # TODO do the finite filtering on this
- return obj[0]
- elif isinstance(obj, collections.abc.Iterator):
- raise RuntimeError("matplotlib does not "
- "support generators as input")
- else:
- for val in obj:
- if safe_isfinite(val):
- return val
- return safe_first_element(obj)
-
-
-def sanitize_sequence(data):
- """
- Convert dictview objects to list. Other inputs are returned unchanged.
- """
- return (list(data) if isinstance(data, collections.abc.MappingView)
- else data)
-
-
-def normalize_kwargs(kw, alias_mapping=None):
- """
- Helper function to normalize kwarg inputs.
-
- Parameters
- ----------
- kw : dict or None
- A dict of keyword arguments. None is explicitly supported and treated
- as an empty dict, to support functions with an optional parameter of
- the form ``props=None``.
-
- alias_mapping : dict or Artist subclass or Artist instance, optional
- A mapping between a canonical name to a list of aliases, in order of
- precedence from lowest to highest.
-
- If the canonical value is not in the list it is assumed to have the
- highest priority.
-
- If an Artist subclass or instance is passed, use its properties alias
- mapping.
-
- Raises
- ------
- TypeError
- To match what Python raises if invalid arguments/keyword arguments are
- passed to a callable.
- """
- from matplotlib.artist import Artist
-
- if kw is None:
- return {}
-
- # deal with default value of alias_mapping
- if alias_mapping is None:
- alias_mapping = {}
- elif (isinstance(alias_mapping, type) and issubclass(alias_mapping, Artist)
- or isinstance(alias_mapping, Artist)):
- alias_mapping = getattr(alias_mapping, "_alias_map", {})
-
- to_canonical = {alias: canonical
- for canonical, alias_list in alias_mapping.items()
- for alias in alias_list}
- canonical_to_seen = {}
- ret = {} # output dictionary
-
- for k, v in kw.items():
- canonical = to_canonical.get(k, k)
- if canonical in canonical_to_seen:
- raise TypeError(f"Got both {canonical_to_seen[canonical]!r} and "
- f"{k!r}, which are aliases of one another")
- canonical_to_seen[canonical] = k
- ret[canonical] = v
-
- return ret
-
-
-@contextlib.contextmanager
-def _lock_path(path):
- """
- Context manager for locking a path.
-
- Usage::
-
- with _lock_path(path):
- ...
-
- Another thread or process that attempts to lock the same path will wait
- until this context manager is exited.
-
- The lock is implemented by creating a temporary file in the parent
- directory, so that directory must exist and be writable.
- """
- path = Path(path)
- lock_path = path.with_name(path.name + ".matplotlib-lock")
- retries = 50
- sleeptime = 0.1
- for _ in range(retries):
- try:
- with lock_path.open("xb"):
- break
- except FileExistsError:
- time.sleep(sleeptime)
- else:
- raise TimeoutError("""\
-Lock error: Matplotlib failed to acquire the following lock file:
- {}
-This maybe due to another process holding this lock file. If you are sure no
-other Matplotlib process is running, remove this file and try again.""".format(
- lock_path))
- try:
- yield
- finally:
- lock_path.unlink()
-
-
-def _topmost_artist(
- artists,
- _cached_max=functools.partial(max, key=operator.attrgetter("zorder"))):
- """
- Get the topmost artist of a list.
-
- In case of a tie, return the *last* of the tied artists, as it will be
- drawn on top of the others. `max` returns the first maximum in case of
- ties, so we need to iterate over the list in reverse order.
- """
- return _cached_max(reversed(artists))
-
-
-def _str_equal(obj, s):
- """
- Return whether *obj* is a string equal to string *s*.
-
- This helper solely exists to handle the case where *obj* is a numpy array,
- because in such cases, a naive ``obj == s`` would yield an array, which
- cannot be used in a boolean context.
- """
- return isinstance(obj, str) and obj == s
-
-
-def _str_lower_equal(obj, s):
- """
- Return whether *obj* is a string equal, when lowercased, to string *s*.
-
- This helper solely exists to handle the case where *obj* is a numpy array,
- because in such cases, a naive ``obj == s`` would yield an array, which
- cannot be used in a boolean context.
- """
- return isinstance(obj, str) and obj.lower() == s
-
-
-def _array_perimeter(arr):
- """
- Get the elements on the perimeter of *arr*.
-
- Parameters
- ----------
- arr : ndarray, shape (M, N)
- The input array.
-
- Returns
- -------
- ndarray, shape (2*(M - 1) + 2*(N - 1),)
- The elements on the perimeter of the array::
-
- [arr[0, 0], ..., arr[0, -1], ..., arr[-1, -1], ..., arr[-1, 0], ...]
-
- Examples
- --------
- >>> i, j = np.ogrid[:3, :4]
- >>> a = i*10 + j
- >>> a
- array([[ 0, 1, 2, 3],
- [10, 11, 12, 13],
- [20, 21, 22, 23]])
- >>> _array_perimeter(a)
- array([ 0, 1, 2, 3, 13, 23, 22, 21, 20, 10])
- """
- # note we use Python's half-open ranges to avoid repeating
- # the corners
- forward = np.s_[0:-1] # [0 ... -1)
- backward = np.s_[-1:0:-1] # [-1 ... 0)
- return np.concatenate((
- arr[0, forward],
- arr[forward, -1],
- arr[-1, backward],
- arr[backward, 0],
- ))
-
-
-def _unfold(arr, axis, size, step):
- """
- Append an extra dimension containing sliding windows along *axis*.
-
- All windows are of size *size* and begin with every *step* elements.
-
- Parameters
- ----------
- arr : ndarray, shape (N_1, ..., N_k)
- The input array
- axis : int
- Axis along which the windows are extracted
- size : int
- Size of the windows
- step : int
- Stride between first elements of subsequent windows.
-
- Returns
- -------
- ndarray, shape (N_1, ..., 1 + (N_axis-size)/step, ..., N_k, size)
-
- Examples
- --------
- >>> i, j = np.ogrid[:3, :7]
- >>> a = i*10 + j
- >>> a
- array([[ 0, 1, 2, 3, 4, 5, 6],
- [10, 11, 12, 13, 14, 15, 16],
- [20, 21, 22, 23, 24, 25, 26]])
- >>> _unfold(a, axis=1, size=3, step=2)
- array([[[ 0, 1, 2],
- [ 2, 3, 4],
- [ 4, 5, 6]],
- [[10, 11, 12],
- [12, 13, 14],
- [14, 15, 16]],
- [[20, 21, 22],
- [22, 23, 24],
- [24, 25, 26]]])
- """
- new_shape = [*arr.shape, size]
- new_strides = [*arr.strides, arr.strides[axis]]
- new_shape[axis] = (new_shape[axis] - size) // step + 1
- new_strides[axis] = new_strides[axis] * step
- return np.lib.stride_tricks.as_strided(arr,
- shape=new_shape,
- strides=new_strides,
- writeable=False)
-
-
-def _array_patch_perimeters(x, rstride, cstride):
- """
- Extract perimeters of patches from *arr*.
-
- Extracted patches are of size (*rstride* + 1) x (*cstride* + 1) and
- share perimeters with their neighbors. The ordering of the vertices matches
- that returned by ``_array_perimeter``.
-
- Parameters
- ----------
- x : ndarray, shape (N, M)
- Input array
- rstride : int
- Vertical (row) stride between corresponding elements of each patch
- cstride : int
- Horizontal (column) stride between corresponding elements of each patch
-
- Returns
- -------
- ndarray, shape (N/rstride * M/cstride, 2 * (rstride + cstride))
- """
- assert rstride > 0 and cstride > 0
- assert (x.shape[0] - 1) % rstride == 0
- assert (x.shape[1] - 1) % cstride == 0
- # We build up each perimeter from four half-open intervals. Here is an
- # illustrated explanation for rstride == cstride == 3
- #
- # T T T R
- # L R
- # L R
- # L B B B
- #
- # where T means that this element will be in the top array, R for right,
- # B for bottom and L for left. Each of the arrays below has a shape of:
- #
- # (number of perimeters that can be extracted vertically,
- # number of perimeters that can be extracted horizontally,
- # cstride for top and bottom and rstride for left and right)
- #
- # Note that _unfold doesn't incur any memory copies, so the only costly
- # operation here is the np.concatenate.
- top = _unfold(x[:-1:rstride, :-1], 1, cstride, cstride)
- bottom = _unfold(x[rstride::rstride, 1:], 1, cstride, cstride)[..., ::-1]
- right = _unfold(x[:-1, cstride::cstride], 0, rstride, rstride)
- left = _unfold(x[1:, :-1:cstride], 0, rstride, rstride)[..., ::-1]
- return (np.concatenate((top, right, bottom, left), axis=2)
- .reshape(-1, 2 * (rstride + cstride)))
-
-
-@contextlib.contextmanager
-def _setattr_cm(obj, **kwargs):
- """
- Temporarily set some attributes; restore original state at context exit.
- """
- sentinel = object()
- origs = {}
- for attr in kwargs:
- orig = getattr(obj, attr, sentinel)
- if attr in obj.__dict__ or orig is sentinel:
- # if we are pulling from the instance dict or the object
- # does not have this attribute we can trust the above
- origs[attr] = orig
- else:
- # if the attribute is not in the instance dict it must be
- # from the class level
- cls_orig = getattr(type(obj), attr)
- # if we are dealing with a property (but not a general descriptor)
- # we want to set the original value back.
- if isinstance(cls_orig, property):
- origs[attr] = orig
- # otherwise this is _something_ we are going to shadow at
- # the instance dict level from higher up in the MRO. We
- # are going to assume we can delattr(obj, attr) to clean
- # up after ourselves. It is possible that this code will
- # fail if used with a non-property custom descriptor which
- # implements __set__ (and __delete__ does not act like a
- # stack). However, this is an internal tool and we do not
- # currently have any custom descriptors.
- else:
- origs[attr] = sentinel
-
- try:
- for attr, val in kwargs.items():
- setattr(obj, attr, val)
- yield
- finally:
- for attr, orig in origs.items():
- if orig is sentinel:
- delattr(obj, attr)
- else:
- setattr(obj, attr, orig)
-
-
-class _OrderedSet(collections.abc.MutableSet):
- def __init__(self):
- self._od = collections.OrderedDict()
-
- def __contains__(self, key):
- return key in self._od
-
- def __iter__(self):
- return iter(self._od)
-
- def __len__(self):
- return len(self._od)
-
- def add(self, key):
- self._od.pop(key, None)
- self._od[key] = None
-
- def discard(self, key):
- self._od.pop(key, None)
-
-
-# Agg's buffers are unmultiplied RGBA8888, which neither PyQt<=5.1 nor cairo
-# support; however, both do support premultiplied ARGB32.
-
-
-def _premultiplied_argb32_to_unmultiplied_rgba8888(buf):
- """
- Convert a premultiplied ARGB32 buffer to an unmultiplied RGBA8888 buffer.
- """
- rgba = np.take( # .take() ensures C-contiguity of the result.
- buf,
- [2, 1, 0, 3] if sys.byteorder == "little" else [1, 2, 3, 0], axis=2)
- rgb = rgba[..., :-1]
- alpha = rgba[..., -1]
- # Un-premultiply alpha. The formula is the same as in cairo-png.c.
- mask = alpha != 0
- for channel in np.rollaxis(rgb, -1):
- channel[mask] = (
- (channel[mask].astype(int) * 255 + alpha[mask] // 2)
- // alpha[mask])
- return rgba
-
-
-def _unmultiplied_rgba8888_to_premultiplied_argb32(rgba8888):
- """
- Convert an unmultiplied RGBA8888 buffer to a premultiplied ARGB32 buffer.
- """
- if sys.byteorder == "little":
- argb32 = np.take(rgba8888, [2, 1, 0, 3], axis=2)
- rgb24 = argb32[..., :-1]
- alpha8 = argb32[..., -1:]
- else:
- argb32 = np.take(rgba8888, [3, 0, 1, 2], axis=2)
- alpha8 = argb32[..., :1]
- rgb24 = argb32[..., 1:]
- # Only bother premultiplying when the alpha channel is not fully opaque,
- # as the cost is not negligible. The unsafe cast is needed to do the
- # multiplication in-place in an integer buffer.
- if alpha8.min() != 0xff:
- np.multiply(rgb24, alpha8 / 0xff, out=rgb24, casting="unsafe")
- return argb32
-
-
-def _get_nonzero_slices(buf):
- """
- Return the bounds of the nonzero region of a 2D array as a pair of slices.
-
- ``buf[_get_nonzero_slices(buf)]`` is the smallest sub-rectangle in *buf*
- that encloses all non-zero entries in *buf*. If *buf* is fully zero, then
- ``(slice(0, 0), slice(0, 0))`` is returned.
- """
- x_nz, = buf.any(axis=0).nonzero()
- y_nz, = buf.any(axis=1).nonzero()
- if len(x_nz) and len(y_nz):
- l, r = x_nz[[0, -1]]
- b, t = y_nz[[0, -1]]
- return slice(b, t + 1), slice(l, r + 1)
- else:
- return slice(0, 0), slice(0, 0)
-
-
-def _pformat_subprocess(command):
- """Pretty-format a subprocess command for printing/logging purposes."""
- return (command if isinstance(command, str)
- else " ".join(shlex.quote(os.fspath(arg)) for arg in command))
-
-
-def _check_and_log_subprocess(command, logger, **kwargs):
- """
- Run *command*, returning its stdout output if it succeeds.
-
- If it fails (exits with nonzero return code), raise an exception whose text
- includes the failed command and captured stdout and stderr output.
-
- Regardless of the return code, the command is logged at DEBUG level on
- *logger*. In case of success, the output is likewise logged.
- """
- logger.debug('%s', _pformat_subprocess(command))
- proc = subprocess.run(command, capture_output=True, **kwargs)
- if proc.returncode:
- stdout = proc.stdout
- if isinstance(stdout, bytes):
- stdout = stdout.decode()
- stderr = proc.stderr
- if isinstance(stderr, bytes):
- stderr = stderr.decode()
- raise RuntimeError(
- f"The command\n"
- f" {_pformat_subprocess(command)}\n"
- f"failed and generated the following output:\n"
- f"{stdout}\n"
- f"and the following error:\n"
- f"{stderr}")
- if proc.stdout:
- logger.debug("stdout:\n%s", proc.stdout)
- if proc.stderr:
- logger.debug("stderr:\n%s", proc.stderr)
- return proc.stdout
-
-
-def _backend_module_name(name):
- """
- Convert a backend name (either a standard backend -- "Agg", "TkAgg", ... --
- or a custom backend -- "module://...") to the corresponding module name).
- """
- return (name[9:] if name.startswith("module://")
- else f"matplotlib.backends.backend_{name.lower()}")
-
-
-def _setup_new_guiapp():
- """
- Perform OS-dependent setup when Matplotlib creates a new GUI application.
- """
- # Windows: If not explicit app user model id has been set yet (so we're not
- # already embedded), then set it to "matplotlib", so that taskbar icons are
- # correct.
- try:
- _c_internal_utils.Win32_GetCurrentProcessExplicitAppUserModelID()
- except OSError:
- _c_internal_utils.Win32_SetCurrentProcessExplicitAppUserModelID(
- "matplotlib")
-
-
-def _format_approx(number, precision):
- """
- Format the number with at most the number of decimals given as precision.
- Remove trailing zeros and possibly the decimal point.
- """
- return f'{number:.{precision}f}'.rstrip('0').rstrip('.') or '0'
-
-
-def _g_sig_digits(value, delta):
- """
- Return the number of significant digits to %g-format *value*, assuming that
- it is known with an error of *delta*.
- """
- if delta == 0:
- # delta = 0 may occur when trying to format values over a tiny range;
- # in that case, replace it by the distance to the closest float.
- delta = abs(np.spacing(value))
- # If e.g. value = 45.67 and delta = 0.02, then we want to round to 2 digits
- # after the decimal point (floor(log10(0.02)) = -2); 45.67 contributes 2
- # digits before the decimal point (floor(log10(45.67)) + 1 = 2): the total
- # is 4 significant digits. A value of 0 contributes 1 "digit" before the
- # decimal point.
- # For inf or nan, the precision doesn't matter.
- return max(
- 0,
- (math.floor(math.log10(abs(value))) + 1 if value else 1)
- - math.floor(math.log10(delta))) if math.isfinite(value) else 0
-
-
-def _unikey_or_keysym_to_mplkey(unikey, keysym):
- """
- Convert a Unicode key or X keysym to a Matplotlib key name.
-
- The Unicode key is checked first; this avoids having to list most printable
- keysyms such as ``EuroSign``.
- """
- # For non-printable characters, gtk3 passes "\0" whereas tk passes an "".
- if unikey and unikey.isprintable():
- return unikey
- key = keysym.lower()
- if key.startswith("kp_"): # keypad_x (including kp_enter).
- key = key[3:]
- if key.startswith("page_"): # page_{up,down}
- key = key.replace("page_", "page")
- if key.endswith(("_l", "_r")): # alt_l, ctrl_l, shift_l.
- key = key[:-2]
- if sys.platform == "darwin" and key == "meta":
- # meta should be reported as command on mac
- key = "cmd"
- key = {
- "return": "enter",
- "prior": "pageup", # Used by tk.
- "next": "pagedown", # Used by tk.
- }.get(key, key)
- return key
-
-
-@functools.cache
-def _make_class_factory(mixin_class, fmt, attr_name=None):
- """
- Return a function that creates picklable classes inheriting from a mixin.
-
- After ::
-
- factory = _make_class_factory(FooMixin, fmt, attr_name)
- FooAxes = factory(Axes)
-
- ``Foo`` is a class that inherits from ``FooMixin`` and ``Axes`` and **is
- picklable** (picklability is what differentiates this from a plain call to
- `type`). Its ``__name__`` is set to ``fmt.format(Axes.__name__)`` and the
- base class is stored in the ``attr_name`` attribute, if not None.
-
- Moreover, the return value of ``factory`` is memoized: calls with the same
- ``Axes`` class always return the same subclass.
- """
-
- @functools.cache
- def class_factory(axes_class):
- # if we have already wrapped this class, declare victory!
- if issubclass(axes_class, mixin_class):
- return axes_class
-
- # The parameter is named "axes_class" for backcompat but is really just
- # a base class; no axes semantics are used.
- base_class = axes_class
-
- class subcls(mixin_class, base_class):
- # Better approximation than __module__ = "matplotlib.cbook".
- __module__ = mixin_class.__module__
-
- def __reduce__(self):
- return (_picklable_class_constructor,
- (mixin_class, fmt, attr_name, base_class),
- self.__getstate__())
-
- subcls.__name__ = subcls.__qualname__ = fmt.format(base_class.__name__)
- if attr_name is not None:
- setattr(subcls, attr_name, base_class)
- return subcls
-
- class_factory.__module__ = mixin_class.__module__
- return class_factory
-
-
-def _picklable_class_constructor(mixin_class, fmt, attr_name, base_class):
- """Internal helper for _make_class_factory."""
- factory = _make_class_factory(mixin_class, fmt, attr_name)
- cls = factory(base_class)
- return cls.__new__(cls)
-
-
-def _unpack_to_numpy(x):
- """Internal helper to extract data from e.g. pandas and xarray objects."""
- if isinstance(x, np.ndarray):
- # If numpy, return directly
- return x
- if hasattr(x, 'to_numpy'):
- # Assume that any to_numpy() method actually returns a numpy array
- return x.to_numpy()
- if hasattr(x, 'values'):
- xtmp = x.values
- # For example a dict has a 'values' attribute, but it is not a property
- # so in this case we do not want to return a function
- if isinstance(xtmp, np.ndarray):
- return xtmp
- return x
-
-
-def _auto_format_str(fmt, value):
- """
- Apply *value* to the format string *fmt*.
-
- This works both with unnamed %-style formatting and
- unnamed {}-style formatting. %-style formatting has priority.
- If *fmt* is %-style formattable that will be used. Otherwise,
- {}-formatting is applied. Strings without formatting placeholders
- are passed through as is.
-
- Examples
- --------
- >>> _auto_format_str('%.2f m', 0.2)
- '0.20 m'
- >>> _auto_format_str('{} m', 0.2)
- '0.2 m'
- >>> _auto_format_str('const', 0.2)
- 'const'
- >>> _auto_format_str('%d or {}', 0.2)
- '0 or {}'
- """
- try:
- return fmt % (value,)
- except (TypeError, ValueError):
- return fmt.format(value)
diff --git a/contrib/python/matplotlib/py3/matplotlib/cbook.pyi b/contrib/python/matplotlib/py3/matplotlib/cbook.pyi
deleted file mode 100644
index 227a23df41..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/cbook.pyi
+++ /dev/null
@@ -1,175 +0,0 @@
-import collections.abc
-from collections.abc import Callable, Collection, Generator, Iterable, Iterator
-import contextlib
-import os
-from pathlib import Path
-
-from matplotlib.artist import Artist
-
-import numpy as np
-from numpy.typing import ArrayLike
-
-from typing import (
- Any,
- Generic,
- IO,
- Literal,
- TypeVar,
- overload,
-)
-
-_T = TypeVar("_T")
-
-def _get_running_interactive_framework() -> str | None: ...
-
-class CallbackRegistry:
- exception_handler: Callable[[Exception], Any]
- callbacks: dict[Any, dict[int, Any]]
- def __init__(
- self,
- exception_handler: Callable[[Exception], Any] | None = ...,
- *,
- signals: Iterable[Any] | None = ...,
- ) -> None: ...
- def connect(self, signal: Any, func: Callable) -> int: ...
- def disconnect(self, cid: int) -> None: ...
- def process(self, s: Any, *args, **kwargs) -> None: ...
- def blocked(
- self, *, signal: Any | None = ...
- ) -> contextlib.AbstractContextManager[None]: ...
-
-class silent_list(list[_T]):
- type: str | None
- def __init__(self, type: str | None, seq: Iterable[_T] | None = ...) -> None: ...
-
-def strip_math(s: str) -> str: ...
-def is_writable_file_like(obj: Any) -> bool: ...
-def file_requires_unicode(x: Any) -> bool: ...
-@overload
-def to_filehandle(
- fname: str | os.PathLike | IO,
- flag: str = ...,
- return_opened: Literal[False] = ...,
- encoding: str | None = ...,
-) -> IO: ...
-@overload
-def to_filehandle(
- fname: str | os.PathLike | IO,
- flag: str,
- return_opened: Literal[True],
- encoding: str | None = ...,
-) -> tuple[IO, bool]: ...
-@overload
-def to_filehandle(
- fname: str | os.PathLike | IO,
- *, # if flag given, will match previous sig
- return_opened: Literal[True],
- encoding: str | None = ...,
-) -> tuple[IO, bool]: ...
-def open_file_cm(
- path_or_file: str | os.PathLike | IO,
- mode: str = ...,
- encoding: str | None = ...,
-) -> contextlib.AbstractContextManager[IO]: ...
-def is_scalar_or_string(val: Any) -> bool: ...
-@overload
-def get_sample_data(
- fname: str | os.PathLike, asfileobj: Literal[True] = ..., *, np_load: Literal[True]
-) -> np.ndarray: ...
-@overload
-def get_sample_data(
- fname: str | os.PathLike,
- asfileobj: Literal[True] = ...,
- *,
- np_load: Literal[False] = ...,
-) -> IO: ...
-@overload
-def get_sample_data(
- fname: str | os.PathLike, asfileobj: Literal[False], *, np_load: bool = ...
-) -> str: ...
-def _get_data_path(*args: Path | str) -> Path: ...
-def flatten(
- seq: Iterable[Any], scalarp: Callable[[Any], bool] = ...
-) -> Generator[Any, None, None]: ...
-
-class Stack(Generic[_T]):
- def __init__(self, default: _T | None = ...) -> None: ...
- def __call__(self) -> _T: ...
- def __len__(self) -> int: ...
- def __getitem__(self, ind: int) -> _T: ...
- def forward(self) -> _T: ...
- def back(self) -> _T: ...
- def push(self, o: _T) -> _T: ...
- def home(self) -> _T: ...
- def empty(self) -> bool: ...
- def clear(self) -> None: ...
- def bubble(self, o: _T) -> _T: ...
- def remove(self, o: _T) -> None: ...
-
-def safe_masked_invalid(x: ArrayLike, copy: bool = ...) -> np.ndarray: ...
-def print_cycles(
- objects: Iterable[Any], outstream: IO = ..., show_progress: bool = ...
-) -> None: ...
-
-class Grouper(Generic[_T]):
- def __init__(self, init: Iterable[_T] = ...) -> None: ...
- def __contains__(self, item: _T) -> bool: ...
- def clean(self) -> None: ...
- def join(self, a: _T, *args: _T) -> None: ...
- def joined(self, a: _T, b: _T) -> bool: ...
- def remove(self, a: _T) -> None: ...
- def __iter__(self) -> Iterator[list[_T]]: ...
- def get_siblings(self, a: _T) -> list[_T]: ...
-
-class GrouperView(Generic[_T]):
- def __init__(self, grouper: Grouper[_T]) -> None: ...
- def __contains__(self, item: _T) -> bool: ...
- def __iter__(self) -> Iterator[list[_T]]: ...
- def joined(self, a: _T, b: _T) -> bool: ...
- def get_siblings(self, a: _T) -> list[_T]: ...
-
-def simple_linear_interpolation(a: ArrayLike, steps: int) -> np.ndarray: ...
-def delete_masked_points(*args): ...
-def boxplot_stats(
- X: ArrayLike,
- whis: float | tuple[float, float] = ...,
- bootstrap: int | None = ...,
- labels: ArrayLike | None = ...,
- autorange: bool = ...,
-) -> list[dict[str, Any]]: ...
-
-ls_mapper: dict[str, str]
-ls_mapper_r: dict[str, str]
-
-def contiguous_regions(mask: ArrayLike) -> list[np.ndarray]: ...
-def is_math_text(s: str) -> bool: ...
-def violin_stats(
- X: ArrayLike, method: Callable, points: int = ..., quantiles: ArrayLike | None = ...
-) -> list[dict[str, Any]]: ...
-def pts_to_prestep(x: ArrayLike, *args: ArrayLike) -> np.ndarray: ...
-def pts_to_poststep(x: ArrayLike, *args: ArrayLike) -> np.ndarray: ...
-def pts_to_midstep(x: np.ndarray, *args: np.ndarray) -> np.ndarray: ...
-
-STEP_LOOKUP_MAP: dict[str, Callable]
-
-def index_of(y: float | ArrayLike) -> tuple[np.ndarray, np.ndarray]: ...
-def safe_first_element(obj: Collection[_T]) -> _T: ...
-def sanitize_sequence(data): ...
-def normalize_kwargs(
- kw: dict[str, Any],
- alias_mapping: dict[str, list[str]] | type[Artist] | Artist | None = ...,
-) -> dict[str, Any]: ...
-def _lock_path(path: str | os.PathLike) -> contextlib.AbstractContextManager[None]: ...
-def _str_equal(obj: Any, s: str) -> bool: ...
-def _setattr_cm(obj: Any, **kwargs) -> contextlib.AbstractContextManager[None]: ...
-
-class _OrderedSet(collections.abc.MutableSet):
- def __init__(self) -> None: ...
- def __contains__(self, key) -> bool: ...
- def __iter__(self): ...
- def __len__(self) -> int: ...
- def add(self, key) -> None: ...
- def discard(self, key) -> None: ...
-
-def _backend_module_name(name: str) -> str: ...
-def _format_approx(number: float, precision: int) -> str: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/cm.py b/contrib/python/matplotlib/py3/matplotlib/cm.py
deleted file mode 100644
index 3911986f36..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/cm.py
+++ /dev/null
@@ -1,745 +0,0 @@
-"""
-Builtin colormaps, colormap handling utilities, and the `ScalarMappable` mixin.
-
-.. seealso::
-
- :doc:`/gallery/color/colormap_reference` for a list of builtin colormaps.
-
- :ref:`colormap-manipulation` for examples of how to make
- colormaps.
-
- :ref:`colormaps` an in-depth discussion of choosing
- colormaps.
-
- :ref:`colormapnorms` for more details about data normalization.
-"""
-
-from collections.abc import Mapping
-import functools
-
-import numpy as np
-from numpy import ma
-
-import matplotlib as mpl
-from matplotlib import _api, colors, cbook, scale
-from matplotlib._cm import datad
-from matplotlib._cm_listed import cmaps as cmaps_listed
-
-
-_LUTSIZE = mpl.rcParams['image.lut']
-
-
-def _gen_cmap_registry():
- """
- Generate a dict mapping standard colormap names to standard colormaps, as
- well as the reversed colormaps.
- """
- cmap_d = {**cmaps_listed}
- for name, spec in datad.items():
- cmap_d[name] = ( # Precache the cmaps at a fixed lutsize..
- colors.LinearSegmentedColormap(name, spec, _LUTSIZE)
- if 'red' in spec else
- colors.ListedColormap(spec['listed'], name)
- if 'listed' in spec else
- colors.LinearSegmentedColormap.from_list(name, spec, _LUTSIZE))
-
- # Register colormap aliases for gray and grey.
- cmap_d['grey'] = cmap_d['gray']
- cmap_d['gist_grey'] = cmap_d['gist_gray']
- cmap_d['gist_yerg'] = cmap_d['gist_yarg']
- cmap_d['Grays'] = cmap_d['Greys']
-
- # Generate reversed cmaps.
- for cmap in list(cmap_d.values()):
- rmap = cmap.reversed()
- cmap_d[rmap.name] = rmap
- return cmap_d
-
-
-class ColormapRegistry(Mapping):
- r"""
- Container for colormaps that are known to Matplotlib by name.
-
- The universal registry instance is `matplotlib.colormaps`. There should be
- no need for users to instantiate `.ColormapRegistry` themselves.
-
- Read access uses a dict-like interface mapping names to `.Colormap`\s::
-
- import matplotlib as mpl
- cmap = mpl.colormaps['viridis']
-
- Returned `.Colormap`\s are copies, so that their modification does not
- change the global definition of the colormap.
-
- Additional colormaps can be added via `.ColormapRegistry.register`::
-
- mpl.colormaps.register(my_colormap)
-
- To get a list of all registered colormaps, you can do::
-
- from matplotlib import colormaps
- list(colormaps)
- """
- def __init__(self, cmaps):
- self._cmaps = cmaps
- self._builtin_cmaps = tuple(cmaps)
- # A shim to allow register_cmap() to force an override
- self._allow_override_builtin = False
-
- def __getitem__(self, item):
- try:
- return self._cmaps[item].copy()
- except KeyError:
- raise KeyError(f"{item!r} is not a known colormap name") from None
-
- def __iter__(self):
- return iter(self._cmaps)
-
- def __len__(self):
- return len(self._cmaps)
-
- def __str__(self):
- return ('ColormapRegistry; available colormaps:\n' +
- ', '.join(f"'{name}'" for name in self))
-
- def __call__(self):
- """
- Return a list of the registered colormap names.
-
- This exists only for backward-compatibility in `.pyplot` which had a
- ``plt.colormaps()`` method. The recommended way to get this list is
- now ``list(colormaps)``.
- """
- return list(self)
-
- def register(self, cmap, *, name=None, force=False):
- """
- Register a new colormap.
-
- The colormap name can then be used as a string argument to any ``cmap``
- parameter in Matplotlib. It is also available in ``pyplot.get_cmap``.
-
- The colormap registry stores a copy of the given colormap, so that
- future changes to the original colormap instance do not affect the
- registered colormap. Think of this as the registry taking a snapshot
- of the colormap at registration.
-
- Parameters
- ----------
- cmap : matplotlib.colors.Colormap
- The colormap to register.
-
- name : str, optional
- The name for the colormap. If not given, ``cmap.name`` is used.
-
- force : bool, default: False
- If False, a ValueError is raised if trying to overwrite an already
- registered name. True supports overwriting registered colormaps
- other than the builtin colormaps.
- """
- _api.check_isinstance(colors.Colormap, cmap=cmap)
-
- name = name or cmap.name
- if name in self:
- if not force:
- # don't allow registering an already existing cmap
- # unless explicitly asked to
- raise ValueError(
- f'A colormap named "{name}" is already registered.')
- elif (name in self._builtin_cmaps
- and not self._allow_override_builtin):
- # We don't allow overriding a builtin unless privately
- # coming from register_cmap()
- raise ValueError("Re-registering the builtin cmap "
- f"{name!r} is not allowed.")
-
- # Warn that we are updating an already existing colormap
- _api.warn_external(f"Overwriting the cmap {name!r} "
- "that was already in the registry.")
-
- self._cmaps[name] = cmap.copy()
- # Someone may set the extremes of a builtin colormap and want to register it
- # with a different name for future lookups. The object would still have the
- # builtin name, so we should update it to the registered name
- if self._cmaps[name].name != name:
- self._cmaps[name].name = name
-
- def unregister(self, name):
- """
- Remove a colormap from the registry.
-
- You cannot remove built-in colormaps.
-
- If the named colormap is not registered, returns with no error, raises
- if you try to de-register a default colormap.
-
- .. warning::
-
- Colormap names are currently a shared namespace that may be used
- by multiple packages. Use `unregister` only if you know you
- have registered that name before. In particular, do not
- unregister just in case to clean the name before registering a
- new colormap.
-
- Parameters
- ----------
- name : str
- The name of the colormap to be removed.
-
- Raises
- ------
- ValueError
- If you try to remove a default built-in colormap.
- """
- if name in self._builtin_cmaps:
- raise ValueError(f"cannot unregister {name!r} which is a builtin "
- "colormap.")
- self._cmaps.pop(name, None)
-
- def get_cmap(self, cmap):
- """
- Return a color map specified through *cmap*.
-
- Parameters
- ----------
- cmap : str or `~matplotlib.colors.Colormap` or None
-
- - if a `.Colormap`, return it
- - if a string, look it up in ``mpl.colormaps``
- - if None, return the Colormap defined in :rc:`image.cmap`
-
- Returns
- -------
- Colormap
- """
- # get the default color map
- if cmap is None:
- return self[mpl.rcParams["image.cmap"]]
-
- # if the user passed in a Colormap, simply return it
- if isinstance(cmap, colors.Colormap):
- return cmap
- if isinstance(cmap, str):
- _api.check_in_list(sorted(_colormaps), cmap=cmap)
- # otherwise, it must be a string so look it up
- return self[cmap]
- raise TypeError(
- 'get_cmap expects None or an instance of a str or Colormap . ' +
- f'you passed {cmap!r} of type {type(cmap)}'
- )
-
-
-# public access to the colormaps should be via `matplotlib.colormaps`. For now,
-# we still create the registry here, but that should stay an implementation
-# detail.
-_colormaps = ColormapRegistry(_gen_cmap_registry())
-globals().update(_colormaps)
-
-
-@_api.deprecated("3.7", alternative="``matplotlib.colormaps.register(name)``")
-def register_cmap(name=None, cmap=None, *, override_builtin=False):
- """
- Add a colormap to the set recognized by :func:`get_cmap`.
-
- Register a new colormap to be accessed by name ::
-
- LinearSegmentedColormap('swirly', data, lut)
- register_cmap(cmap=swirly_cmap)
-
- Parameters
- ----------
- name : str, optional
- The name that can be used in :func:`get_cmap` or :rc:`image.cmap`
-
- If absent, the name will be the :attr:`~matplotlib.colors.Colormap.name`
- attribute of the *cmap*.
-
- cmap : matplotlib.colors.Colormap
- Despite being the second argument and having a default value, this
- is a required argument.
-
- override_builtin : bool
-
- Allow built-in colormaps to be overridden by a user-supplied
- colormap.
-
- Please do not use this unless you are sure you need it.
- """
- _api.check_isinstance((str, None), name=name)
- if name is None:
- try:
- name = cmap.name
- except AttributeError as err:
- raise ValueError("Arguments must include a name or a "
- "Colormap") from err
- # override_builtin is allowed here for backward compatibility
- # this is just a shim to enable that to work privately in
- # the global ColormapRegistry
- _colormaps._allow_override_builtin = override_builtin
- _colormaps.register(cmap, name=name, force=override_builtin)
- _colormaps._allow_override_builtin = False
-
-
-def _get_cmap(name=None, lut=None):
- """
- Get a colormap instance, defaulting to rc values if *name* is None.
-
- Parameters
- ----------
- name : `~matplotlib.colors.Colormap` or str or None, default: None
- If a `.Colormap` instance, it will be returned. Otherwise, the name of
- a colormap known to Matplotlib, which will be resampled by *lut*. The
- default, None, means :rc:`image.cmap`.
- lut : int or None, default: None
- If *name* is not already a Colormap instance and *lut* is not None, the
- colormap will be resampled to have *lut* entries in the lookup table.
-
- Returns
- -------
- Colormap
- """
- if name is None:
- name = mpl.rcParams['image.cmap']
- if isinstance(name, colors.Colormap):
- return name
- _api.check_in_list(sorted(_colormaps), name=name)
- if lut is None:
- return _colormaps[name]
- else:
- return _colormaps[name].resampled(lut)
-
-# do it in two steps like this so we can have an un-deprecated version in
-# pyplot.
-get_cmap = _api.deprecated(
- '3.7',
- name='get_cmap',
- alternative=(
- "``matplotlib.colormaps[name]`` " +
- "or ``matplotlib.colormaps.get_cmap(obj)``"
- )
-)(_get_cmap)
-
-
-@_api.deprecated("3.7",
- alternative="``matplotlib.colormaps.unregister(name)``")
-def unregister_cmap(name):
- """
- Remove a colormap recognized by :func:`get_cmap`.
-
- You may not remove built-in colormaps.
-
- If the named colormap is not registered, returns with no error, raises
- if you try to de-register a default colormap.
-
- .. warning::
-
- Colormap names are currently a shared namespace that may be used
- by multiple packages. Use `unregister_cmap` only if you know you
- have registered that name before. In particular, do not
- unregister just in case to clean the name before registering a
- new colormap.
-
- Parameters
- ----------
- name : str
- The name of the colormap to be un-registered
-
- Returns
- -------
- ColorMap or None
- If the colormap was registered, return it if not return `None`
-
- Raises
- ------
- ValueError
- If you try to de-register a default built-in colormap.
- """
- cmap = _colormaps.get(name, None)
- _colormaps.unregister(name)
- return cmap
-
-
-def _auto_norm_from_scale(scale_cls):
- """
- Automatically generate a norm class from *scale_cls*.
-
- This differs from `.colors.make_norm_from_scale` in the following points:
-
- - This function is not a class decorator, but directly returns a norm class
- (as if decorating `.Normalize`).
- - The scale is automatically constructed with ``nonpositive="mask"``, if it
- supports such a parameter, to work around the difference in defaults
- between standard scales (which use "clip") and norms (which use "mask").
-
- Note that ``make_norm_from_scale`` caches the generated norm classes
- (not the instances) and reuses them for later calls. For example,
- ``type(_auto_norm_from_scale("log")) == LogNorm``.
- """
- # Actually try to construct an instance, to verify whether
- # ``nonpositive="mask"`` is supported.
- try:
- norm = colors.make_norm_from_scale(
- functools.partial(scale_cls, nonpositive="mask"))(
- colors.Normalize)()
- except TypeError:
- norm = colors.make_norm_from_scale(scale_cls)(
- colors.Normalize)()
- return type(norm)
-
-
-class ScalarMappable:
- """
- A mixin class to map scalar data to RGBA.
-
- The ScalarMappable applies data normalization before returning RGBA colors
- from the given colormap.
- """
-
- def __init__(self, norm=None, cmap=None):
- """
- Parameters
- ----------
- norm : `.Normalize` (or subclass thereof) or str or None
- The normalizing object which scales data, typically into the
- interval ``[0, 1]``.
- If a `str`, a `.Normalize` subclass is dynamically generated based
- on the scale with the corresponding name.
- If *None*, *norm* defaults to a *colors.Normalize* object which
- initializes its scaling based on the first data processed.
- cmap : str or `~matplotlib.colors.Colormap`
- The colormap used to map normalized data values to RGBA colors.
- """
- self._A = None
- self._norm = None # So that the setter knows we're initializing.
- self.set_norm(norm) # The Normalize instance of this ScalarMappable.
- self.cmap = None # So that the setter knows we're initializing.
- self.set_cmap(cmap) # The Colormap instance of this ScalarMappable.
- #: The last colorbar associated with this ScalarMappable. May be None.
- self.colorbar = None
- self.callbacks = cbook.CallbackRegistry(signals=["changed"])
-
- def _scale_norm(self, norm, vmin, vmax):
- """
- Helper for initial scaling.
-
- Used by public functions that create a ScalarMappable and support
- parameters *vmin*, *vmax* and *norm*. This makes sure that a *norm*
- will take precedence over *vmin*, *vmax*.
-
- Note that this method does not set the norm.
- """
- if vmin is not None or vmax is not None:
- self.set_clim(vmin, vmax)
- if isinstance(norm, colors.Normalize):
- raise ValueError(
- "Passing a Normalize instance simultaneously with "
- "vmin/vmax is not supported. Please pass vmin/vmax "
- "directly to the norm when creating it.")
-
- # always resolve the autoscaling so we have concrete limits
- # rather than deferring to draw time.
- self.autoscale_None()
-
- def to_rgba(self, x, alpha=None, bytes=False, norm=True):
- """
- Return a normalized RGBA array corresponding to *x*.
-
- In the normal case, *x* is a 1D or 2D sequence of scalars, and
- the corresponding `~numpy.ndarray` of RGBA values will be returned,
- based on the norm and colormap set for this ScalarMappable.
-
- There is one special case, for handling images that are already
- RGB or RGBA, such as might have been read from an image file.
- If *x* is an `~numpy.ndarray` with 3 dimensions,
- and the last dimension is either 3 or 4, then it will be
- treated as an RGB or RGBA array, and no mapping will be done.
- The array can be `~numpy.uint8`, or it can be floats with
- values in the 0-1 range; otherwise a ValueError will be raised.
- If it is a masked array, any masked elements will be set to 0 alpha.
- If the last dimension is 3, the *alpha* kwarg (defaulting to 1)
- will be used to fill in the transparency. If the last dimension
- is 4, the *alpha* kwarg is ignored; it does not
- replace the preexisting alpha. A ValueError will be raised
- if the third dimension is other than 3 or 4.
-
- In either case, if *bytes* is *False* (default), the RGBA
- array will be floats in the 0-1 range; if it is *True*,
- the returned RGBA array will be `~numpy.uint8` in the 0 to 255 range.
-
- If norm is False, no normalization of the input data is
- performed, and it is assumed to be in the range (0-1).
-
- """
- # First check for special case, image input:
- try:
- if x.ndim == 3:
- if x.shape[2] == 3:
- if alpha is None:
- alpha = 1
- if x.dtype == np.uint8:
- alpha = np.uint8(alpha * 255)
- m, n = x.shape[:2]
- xx = np.empty(shape=(m, n, 4), dtype=x.dtype)
- xx[:, :, :3] = x
- xx[:, :, 3] = alpha
- elif x.shape[2] == 4:
- xx = x
- else:
- raise ValueError("Third dimension must be 3 or 4")
- if xx.dtype.kind == 'f':
- if norm and (xx.max() > 1 or xx.min() < 0):
- raise ValueError("Floating point image RGB values "
- "must be in the 0..1 range.")
- if bytes:
- xx = (xx * 255).astype(np.uint8)
- elif xx.dtype == np.uint8:
- if not bytes:
- xx = xx.astype(np.float32) / 255
- else:
- raise ValueError("Image RGB array must be uint8 or "
- "floating point; found %s" % xx.dtype)
- # Account for any masked entries in the original array
- # If any of R, G, B, or A are masked for an entry, we set alpha to 0
- if np.ma.is_masked(x):
- xx[np.any(np.ma.getmaskarray(x), axis=2), 3] = 0
- return xx
- except AttributeError:
- # e.g., x is not an ndarray; so try mapping it
- pass
-
- # This is the normal case, mapping a scalar array:
- x = ma.asarray(x)
- if norm:
- x = self.norm(x)
- rgba = self.cmap(x, alpha=alpha, bytes=bytes)
- return rgba
-
- def set_array(self, A):
- """
- Set the value array from array-like *A*.
-
- Parameters
- ----------
- A : array-like or None
- The values that are mapped to colors.
-
- The base class `.ScalarMappable` does not make any assumptions on
- the dimensionality and shape of the value array *A*.
- """
- if A is None:
- self._A = None
- return
-
- A = cbook.safe_masked_invalid(A, copy=True)
- if not np.can_cast(A.dtype, float, "same_kind"):
- raise TypeError(f"Image data of dtype {A.dtype} cannot be "
- "converted to float")
-
- self._A = A
-
- def get_array(self):
- """
- Return the array of values, that are mapped to colors.
-
- The base class `.ScalarMappable` does not make any assumptions on
- the dimensionality and shape of the array.
- """
- return self._A
-
- def get_cmap(self):
- """Return the `.Colormap` instance."""
- return self.cmap
-
- def get_clim(self):
- """
- Return the values (min, max) that are mapped to the colormap limits.
- """
- return self.norm.vmin, self.norm.vmax
-
- def set_clim(self, vmin=None, vmax=None):
- """
- Set the norm limits for image scaling.
-
- Parameters
- ----------
- vmin, vmax : float
- The limits.
-
- The limits may also be passed as a tuple (*vmin*, *vmax*) as a
- single positional argument.
-
- .. ACCEPTS: (vmin: float, vmax: float)
- """
- # If the norm's limits are updated self.changed() will be called
- # through the callbacks attached to the norm
- if vmax is None:
- try:
- vmin, vmax = vmin
- except (TypeError, ValueError):
- pass
- if vmin is not None:
- self.norm.vmin = colors._sanitize_extrema(vmin)
- if vmax is not None:
- self.norm.vmax = colors._sanitize_extrema(vmax)
-
- def get_alpha(self):
- """
- Returns
- -------
- float
- Always returns 1.
- """
- # This method is intended to be overridden by Artist sub-classes
- return 1.
-
- def set_cmap(self, cmap):
- """
- Set the colormap for luminance data.
-
- Parameters
- ----------
- cmap : `.Colormap` or str or None
- """
- in_init = self.cmap is None
-
- self.cmap = _ensure_cmap(cmap)
- if not in_init:
- self.changed() # Things are not set up properly yet.
-
- @property
- def norm(self):
- return self._norm
-
- @norm.setter
- def norm(self, norm):
- _api.check_isinstance((colors.Normalize, str, None), norm=norm)
- if norm is None:
- norm = colors.Normalize()
- elif isinstance(norm, str):
- try:
- scale_cls = scale._scale_mapping[norm]
- except KeyError:
- raise ValueError(
- "Invalid norm str name; the following values are "
- f"supported: {', '.join(scale._scale_mapping)}"
- ) from None
- norm = _auto_norm_from_scale(scale_cls)()
-
- if norm is self.norm:
- # We aren't updating anything
- return
-
- in_init = self.norm is None
- # Remove the current callback and connect to the new one
- if not in_init:
- self.norm.callbacks.disconnect(self._id_norm)
- self._norm = norm
- self._id_norm = self.norm.callbacks.connect('changed',
- self.changed)
- if not in_init:
- self.changed()
-
- def set_norm(self, norm):
- """
- Set the normalization instance.
-
- Parameters
- ----------
- norm : `.Normalize` or str or None
-
- Notes
- -----
- If there are any colorbars using the mappable for this norm, setting
- the norm of the mappable will reset the norm, locator, and formatters
- on the colorbar to default.
- """
- self.norm = norm
-
- def autoscale(self):
- """
- Autoscale the scalar limits on the norm instance using the
- current array
- """
- if self._A is None:
- raise TypeError('You must first set_array for mappable')
- # If the norm's limits are updated self.changed() will be called
- # through the callbacks attached to the norm
- self.norm.autoscale(self._A)
-
- def autoscale_None(self):
- """
- Autoscale the scalar limits on the norm instance using the
- current array, changing only limits that are None
- """
- if self._A is None:
- raise TypeError('You must first set_array for mappable')
- # If the norm's limits are updated self.changed() will be called
- # through the callbacks attached to the norm
- self.norm.autoscale_None(self._A)
-
- def changed(self):
- """
- Call this whenever the mappable is changed to notify all the
- callbackSM listeners to the 'changed' signal.
- """
- self.callbacks.process('changed', self)
- self.stale = True
-
-
-# The docstrings here must be generic enough to apply to all relevant methods.
-mpl._docstring.interpd.update(
- cmap_doc="""\
-cmap : str or `~matplotlib.colors.Colormap`, default: :rc:`image.cmap`
- The Colormap instance or registered colormap name used to map scalar data
- to colors.""",
- norm_doc="""\
-norm : str or `~matplotlib.colors.Normalize`, optional
- The normalization method used to scale scalar data to the [0, 1] range
- before mapping to colors using *cmap*. By default, a linear scaling is
- used, mapping the lowest value to 0 and the highest to 1.
-
- If given, this can be one of the following:
-
- - An instance of `.Normalize` or one of its subclasses
- (see :ref:`colormapnorms`).
- - A scale name, i.e. one of "linear", "log", "symlog", "logit", etc. For a
- list of available scales, call `matplotlib.scale.get_scale_names()`.
- In that case, a suitable `.Normalize` subclass is dynamically generated
- and instantiated.""",
- vmin_vmax_doc="""\
-vmin, vmax : float, optional
- When using scalar data and no explicit *norm*, *vmin* and *vmax* define
- the data range that the colormap covers. By default, the colormap covers
- the complete value range of the supplied data. It is an error to use
- *vmin*/*vmax* when a *norm* instance is given (but using a `str` *norm*
- name together with *vmin*/*vmax* is acceptable).""",
-)
-
-
-def _ensure_cmap(cmap):
- """
- Ensure that we have a `.Colormap` object.
-
- For internal use to preserve type stability of errors.
-
- Parameters
- ----------
- cmap : None, str, Colormap
-
- - if a `Colormap`, return it
- - if a string, look it up in mpl.colormaps
- - if None, look up the default color map in mpl.colormaps
-
- Returns
- -------
- Colormap
-
- """
- if isinstance(cmap, colors.Colormap):
- return cmap
- cmap_name = cmap if cmap is not None else mpl.rcParams["image.cmap"]
- # use check_in_list to ensure type stability of the exception raised by
- # the internal usage of this (ValueError vs KeyError)
- if cmap_name not in _colormaps:
- _api.check_in_list(sorted(_colormaps), cmap=cmap_name)
- return mpl.colormaps[cmap_name]
diff --git a/contrib/python/matplotlib/py3/matplotlib/cm.pyi b/contrib/python/matplotlib/py3/matplotlib/cm.pyi
deleted file mode 100644
index be8f10b39c..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/cm.pyi
+++ /dev/null
@@ -1,54 +0,0 @@
-from collections.abc import Iterator, Mapping
-from matplotlib import cbook, colors
-from matplotlib.colorbar import Colorbar
-
-import numpy as np
-from numpy.typing import ArrayLike
-
-class ColormapRegistry(Mapping[str, colors.Colormap]):
- def __init__(self, cmaps: Mapping[str, colors.Colormap]) -> None: ...
- def __getitem__(self, item: str) -> colors.Colormap: ...
- def __iter__(self) -> Iterator[str]: ...
- def __len__(self) -> int: ...
- def __call__(self) -> list[str]: ...
- def register(
- self, cmap: colors.Colormap, *, name: str | None = ..., force: bool = ...
- ) -> None: ...
- def unregister(self, name: str) -> None: ...
- def get_cmap(self, cmap: str | colors.Colormap) -> colors.Colormap: ...
-
-_colormaps: ColormapRegistry = ...
-
-def get_cmap(name: str | colors.Colormap | None = ..., lut: int | None = ...) -> colors.Colormap: ...
-
-class ScalarMappable:
- cmap: colors.Colormap | None
- colorbar: Colorbar | None
- callbacks: cbook.CallbackRegistry
- def __init__(
- self,
- norm: colors.Normalize | None = ...,
- cmap: str | colors.Colormap | None = ...,
- ) -> None: ...
- def to_rgba(
- self,
- x: np.ndarray,
- alpha: float | ArrayLike | None = ...,
- bytes: bool = ...,
- norm: bool = ...,
- ) -> np.ndarray: ...
- def set_array(self, A: ArrayLike | None) -> None: ...
- def get_array(self) -> np.ndarray | None: ...
- def get_cmap(self) -> colors.Colormap: ...
- def get_clim(self) -> tuple[float, float]: ...
- def set_clim(self, vmin: float | tuple[float, float] | None = ..., vmax: float | None = ...) -> None: ...
- def get_alpha(self) -> float | None: ...
- def set_cmap(self, cmap: str | colors.Colormap) -> None: ...
- @property
- def norm(self) -> colors.Normalize: ...
- @norm.setter
- def norm(self, norm: colors.Normalize | str | None) -> None: ...
- def set_norm(self, norm: colors.Normalize | str | None) -> None: ...
- def autoscale(self) -> None: ...
- def autoscale_None(self) -> None: ...
- def changed(self) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/collections.py b/contrib/python/matplotlib/py3/matplotlib/collections.py
deleted file mode 100644
index 81db24d0c0..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/collections.py
+++ /dev/null
@@ -1,2394 +0,0 @@
-"""
-Classes for the efficient drawing of large collections of objects that
-share most properties, e.g., a large number of line segments or
-polygons.
-
-The classes are not meant to be as flexible as their single element
-counterparts (e.g., you may not be able to select all line styles) but
-they are meant to be fast for common use cases (e.g., a large set of solid
-line segments).
-"""
-
-import itertools
-import math
-from numbers import Number, Real
-import warnings
-
-import numpy as np
-
-import matplotlib as mpl
-from . import (_api, _path, artist, cbook, cm, colors as mcolors, _docstring,
- hatch as mhatch, lines as mlines, path as mpath, transforms)
-from ._enums import JoinStyle, CapStyle
-
-
-# "color" is excluded; it is a compound setter, and its docstring differs
-# in LineCollection.
-@_api.define_aliases({
- "antialiased": ["antialiaseds", "aa"],
- "edgecolor": ["edgecolors", "ec"],
- "facecolor": ["facecolors", "fc"],
- "linestyle": ["linestyles", "dashes", "ls"],
- "linewidth": ["linewidths", "lw"],
- "offset_transform": ["transOffset"],
-})
-class Collection(artist.Artist, cm.ScalarMappable):
- r"""
- Base class for Collections. Must be subclassed to be usable.
-
- A Collection represents a sequence of `.Patch`\es that can be drawn
- more efficiently together than individually. For example, when a single
- path is being drawn repeatedly at different offsets, the renderer can
- typically execute a ``draw_marker()`` call much more efficiently than a
- series of repeated calls to ``draw_path()`` with the offsets put in
- one-by-one.
-
- Most properties of a collection can be configured per-element. Therefore,
- Collections have "plural" versions of many of the properties of a `.Patch`
- (e.g. `.Collection.get_paths` instead of `.Patch.get_path`). Exceptions are
- the *zorder*, *hatch*, *pickradius*, *capstyle* and *joinstyle* properties,
- which can only be set globally for the whole collection.
-
- Besides these exceptions, all properties can be specified as single values
- (applying to all elements) or sequences of values. The property of the
- ``i``\th element of the collection is::
-
- prop[i % len(prop)]
-
- Each Collection can optionally be used as its own `.ScalarMappable` by
- passing the *norm* and *cmap* parameters to its constructor. If the
- Collection's `.ScalarMappable` matrix ``_A`` has been set (via a call
- to `.Collection.set_array`), then at draw time this internal scalar
- mappable will be used to set the ``facecolors`` and ``edgecolors``,
- ignoring those that were manually passed in.
- """
- #: Either a list of 3x3 arrays or an Nx3x3 array (representing N
- #: transforms), suitable for the `all_transforms` argument to
- #: `~matplotlib.backend_bases.RendererBase.draw_path_collection`;
- #: each 3x3 array is used to initialize an
- #: `~matplotlib.transforms.Affine2D` object.
- #: Each kind of collection defines this based on its arguments.
- _transforms = np.empty((0, 3, 3))
-
- # Whether to draw an edge by default. Set on a
- # subclass-by-subclass basis.
- _edge_default = False
-
- @_docstring.interpd
- def __init__(self, *,
- edgecolors=None,
- facecolors=None,
- linewidths=None,
- linestyles='solid',
- capstyle=None,
- joinstyle=None,
- antialiaseds=None,
- offsets=None,
- offset_transform=None,
- norm=None, # optional for ScalarMappable
- cmap=None, # ditto
- pickradius=5.0,
- hatch=None,
- urls=None,
- zorder=1,
- **kwargs
- ):
- """
- Parameters
- ----------
- edgecolors : color or list of colors, default: :rc:`patch.edgecolor`
- Edge color for each patch making up the collection. The special
- value 'face' can be passed to make the edgecolor match the
- facecolor.
- facecolors : color or list of colors, default: :rc:`patch.facecolor`
- Face color for each patch making up the collection.
- linewidths : float or list of floats, default: :rc:`patch.linewidth`
- Line width for each patch making up the collection.
- linestyles : str or tuple or list thereof, default: 'solid'
- Valid strings are ['solid', 'dashed', 'dashdot', 'dotted', '-',
- '--', '-.', ':']. Dash tuples should be of the form::
-
- (offset, onoffseq),
-
- where *onoffseq* is an even length tuple of on and off ink lengths
- in points. For examples, see
- :doc:`/gallery/lines_bars_and_markers/linestyles`.
- capstyle : `.CapStyle`-like, default: :rc:`patch.capstyle`
- Style to use for capping lines for all paths in the collection.
- Allowed values are %(CapStyle)s.
- joinstyle : `.JoinStyle`-like, default: :rc:`patch.joinstyle`
- Style to use for joining lines for all paths in the collection.
- Allowed values are %(JoinStyle)s.
- antialiaseds : bool or list of bool, default: :rc:`patch.antialiased`
- Whether each patch in the collection should be drawn with
- antialiasing.
- offsets : (float, float) or list thereof, default: (0, 0)
- A vector by which to translate each patch after rendering (default
- is no translation). The translation is performed in screen (pixel)
- coordinates (i.e. after the Artist's transform is applied).
- offset_transform : `~.Transform`, default: `.IdentityTransform`
- A single transform which will be applied to each *offsets* vector
- before it is used.
- cmap, norm
- Data normalization and colormapping parameters. See
- `.ScalarMappable` for a detailed description.
- hatch : str, optional
- Hatching pattern to use in filled paths, if any. Valid strings are
- ['/', '\\', '|', '-', '+', 'x', 'o', 'O', '.', '*']. See
- :doc:`/gallery/shapes_and_collections/hatch_style_reference` for
- the meaning of each hatch type.
- pickradius : float, default: 5.0
- If ``pickradius <= 0``, then `.Collection.contains` will return
- ``True`` whenever the test point is inside of one of the polygons
- formed by the control points of a Path in the Collection. On the
- other hand, if it is greater than 0, then we instead check if the
- test point is contained in a stroke of width ``2*pickradius``
- following any of the Paths in the Collection.
- urls : list of str, default: None
- A URL for each patch to link to once drawn. Currently only works
- for the SVG backend. See :doc:`/gallery/misc/hyperlinks_sgskip` for
- examples.
- zorder : float, default: 1
- The drawing order, shared by all Patches in the Collection. See
- :doc:`/gallery/misc/zorder_demo` for all defaults and examples.
- """
- artist.Artist.__init__(self)
- cm.ScalarMappable.__init__(self, norm, cmap)
- # list of un-scaled dash patterns
- # this is needed scaling the dash pattern by linewidth
- self._us_linestyles = [(0, None)]
- # list of dash patterns
- self._linestyles = [(0, None)]
- # list of unbroadcast/scaled linewidths
- self._us_lw = [0]
- self._linewidths = [0]
-
- self._gapcolor = None # Currently only used by LineCollection.
-
- # Flags set by _set_mappable_flags: are colors from mapping an array?
- self._face_is_mapped = None
- self._edge_is_mapped = None
- self._mapped_colors = None # calculated in update_scalarmappable
- self._hatch_color = mcolors.to_rgba(mpl.rcParams['hatch.color'])
- self.set_facecolor(facecolors)
- self.set_edgecolor(edgecolors)
- self.set_linewidth(linewidths)
- self.set_linestyle(linestyles)
- self.set_antialiased(antialiaseds)
- self.set_pickradius(pickradius)
- self.set_urls(urls)
- self.set_hatch(hatch)
- self.set_zorder(zorder)
-
- if capstyle:
- self.set_capstyle(capstyle)
- else:
- self._capstyle = None
-
- if joinstyle:
- self.set_joinstyle(joinstyle)
- else:
- self._joinstyle = None
-
- if offsets is not None:
- offsets = np.asanyarray(offsets, float)
- # Broadcast (2,) -> (1, 2) but nothing else.
- if offsets.shape == (2,):
- offsets = offsets[None, :]
-
- self._offsets = offsets
- self._offset_transform = offset_transform
-
- self._path_effects = None
- self._internal_update(kwargs)
- self._paths = None
-
- def get_paths(self):
- return self._paths
-
- def set_paths(self, paths):
- self._paths = paths
- self.stale = True
-
- def get_transforms(self):
- return self._transforms
-
- def get_offset_transform(self):
- """Return the `.Transform` instance used by this artist offset."""
- if self._offset_transform is None:
- self._offset_transform = transforms.IdentityTransform()
- elif (not isinstance(self._offset_transform, transforms.Transform)
- and hasattr(self._offset_transform, '_as_mpl_transform')):
- self._offset_transform = \
- self._offset_transform._as_mpl_transform(self.axes)
- return self._offset_transform
-
- def set_offset_transform(self, offset_transform):
- """
- Set the artist offset transform.
-
- Parameters
- ----------
- offset_transform : `.Transform`
- """
- self._offset_transform = offset_transform
-
- def get_datalim(self, transData):
- # Calculate the data limits and return them as a `.Bbox`.
- #
- # This operation depends on the transforms for the data in the
- # collection and whether the collection has offsets:
- #
- # 1. offsets = None, transform child of transData: use the paths for
- # the automatic limits (i.e. for LineCollection in streamline).
- # 2. offsets != None: offset_transform is child of transData:
- #
- # a. transform is child of transData: use the path + offset for
- # limits (i.e for bar).
- # b. transform is not a child of transData: just use the offsets
- # for the limits (i.e. for scatter)
- #
- # 3. otherwise return a null Bbox.
-
- transform = self.get_transform()
- offset_trf = self.get_offset_transform()
- if not (isinstance(offset_trf, transforms.IdentityTransform)
- or offset_trf.contains_branch(transData)):
- # if the offsets are in some coords other than data,
- # then don't use them for autoscaling.
- return transforms.Bbox.null()
-
- paths = self.get_paths()
- if not len(paths):
- # No paths to transform
- return transforms.Bbox.null()
-
- if not transform.is_affine:
- paths = [transform.transform_path_non_affine(p) for p in paths]
- # Don't convert transform to transform.get_affine() here because
- # we may have transform.contains_branch(transData) but not
- # transforms.get_affine().contains_branch(transData). But later,
- # be careful to only apply the affine part that remains.
-
- offsets = self.get_offsets()
-
- if any(transform.contains_branch_seperately(transData)):
- # collections that are just in data units (like quiver)
- # can properly have the axes limits set by their shape +
- # offset. LineCollections that have no offsets can
- # also use this algorithm (like streamplot).
- if isinstance(offsets, np.ma.MaskedArray):
- offsets = offsets.filled(np.nan)
- # get_path_collection_extents handles nan but not masked arrays
- return mpath.get_path_collection_extents(
- transform.get_affine() - transData, paths,
- self.get_transforms(),
- offset_trf.transform_non_affine(offsets),
- offset_trf.get_affine().frozen())
-
- # NOTE: None is the default case where no offsets were passed in
- if self._offsets is not None:
- # this is for collections that have their paths (shapes)
- # in physical, axes-relative, or figure-relative units
- # (i.e. like scatter). We can't uniquely set limits based on
- # those shapes, so we just set the limits based on their
- # location.
- offsets = (offset_trf - transData).transform(offsets)
- # note A-B means A B^{-1}
- offsets = np.ma.masked_invalid(offsets)
- if not offsets.mask.all():
- bbox = transforms.Bbox.null()
- bbox.update_from_data_xy(offsets)
- return bbox
- return transforms.Bbox.null()
-
- def get_window_extent(self, renderer=None):
- # TODO: check to ensure that this does not fail for
- # cases other than scatter plot legend
- return self.get_datalim(transforms.IdentityTransform())
-
- def _prepare_points(self):
- # Helper for drawing and hit testing.
-
- transform = self.get_transform()
- offset_trf = self.get_offset_transform()
- offsets = self.get_offsets()
- paths = self.get_paths()
-
- if self.have_units():
- paths = []
- for path in self.get_paths():
- vertices = path.vertices
- xs, ys = vertices[:, 0], vertices[:, 1]
- xs = self.convert_xunits(xs)
- ys = self.convert_yunits(ys)
- paths.append(mpath.Path(np.column_stack([xs, ys]), path.codes))
- xs = self.convert_xunits(offsets[:, 0])
- ys = self.convert_yunits(offsets[:, 1])
- offsets = np.ma.column_stack([xs, ys])
-
- if not transform.is_affine:
- paths = [transform.transform_path_non_affine(path)
- for path in paths]
- transform = transform.get_affine()
- if not offset_trf.is_affine:
- offsets = offset_trf.transform_non_affine(offsets)
- # This might have changed an ndarray into a masked array.
- offset_trf = offset_trf.get_affine()
-
- if isinstance(offsets, np.ma.MaskedArray):
- offsets = offsets.filled(np.nan)
- # Changing from a masked array to nan-filled ndarray
- # is probably most efficient at this point.
-
- return transform, offset_trf, offsets, paths
-
- @artist.allow_rasterization
- def draw(self, renderer):
- if not self.get_visible():
- return
- renderer.open_group(self.__class__.__name__, self.get_gid())
-
- self.update_scalarmappable()
-
- transform, offset_trf, offsets, paths = self._prepare_points()
-
- gc = renderer.new_gc()
- self._set_gc_clip(gc)
- gc.set_snap(self.get_snap())
-
- if self._hatch:
- gc.set_hatch(self._hatch)
- gc.set_hatch_color(self._hatch_color)
-
- if self.get_sketch_params() is not None:
- gc.set_sketch_params(*self.get_sketch_params())
-
- if self.get_path_effects():
- from matplotlib.patheffects import PathEffectRenderer
- renderer = PathEffectRenderer(self.get_path_effects(), renderer)
-
- # If the collection is made up of a single shape/color/stroke,
- # it can be rendered once and blitted multiple times, using
- # `draw_markers` rather than `draw_path_collection`. This is
- # *much* faster for Agg, and results in smaller file sizes in
- # PDF/SVG/PS.
-
- trans = self.get_transforms()
- facecolors = self.get_facecolor()
- edgecolors = self.get_edgecolor()
- do_single_path_optimization = False
- if (len(paths) == 1 and len(trans) <= 1 and
- len(facecolors) == 1 and len(edgecolors) == 1 and
- len(self._linewidths) == 1 and
- all(ls[1] is None for ls in self._linestyles) and
- len(self._antialiaseds) == 1 and len(self._urls) == 1 and
- self.get_hatch() is None):
- if len(trans):
- combined_transform = transforms.Affine2D(trans[0]) + transform
- else:
- combined_transform = transform
- extents = paths[0].get_extents(combined_transform)
- if (extents.width < self.figure.bbox.width
- and extents.height < self.figure.bbox.height):
- do_single_path_optimization = True
-
- if self._joinstyle:
- gc.set_joinstyle(self._joinstyle)
-
- if self._capstyle:
- gc.set_capstyle(self._capstyle)
-
- if do_single_path_optimization:
- gc.set_foreground(tuple(edgecolors[0]))
- gc.set_linewidth(self._linewidths[0])
- gc.set_dashes(*self._linestyles[0])
- gc.set_antialiased(self._antialiaseds[0])
- gc.set_url(self._urls[0])
- renderer.draw_markers(
- gc, paths[0], combined_transform.frozen(),
- mpath.Path(offsets), offset_trf, tuple(facecolors[0]))
- else:
- if self._gapcolor is not None:
- # First draw paths within the gaps.
- ipaths, ilinestyles = self._get_inverse_paths_linestyles()
- renderer.draw_path_collection(
- gc, transform.frozen(), ipaths,
- self.get_transforms(), offsets, offset_trf,
- [mcolors.to_rgba("none")], self._gapcolor,
- self._linewidths, ilinestyles,
- self._antialiaseds, self._urls,
- "screen")
-
- renderer.draw_path_collection(
- gc, transform.frozen(), paths,
- self.get_transforms(), offsets, offset_trf,
- self.get_facecolor(), self.get_edgecolor(),
- self._linewidths, self._linestyles,
- self._antialiaseds, self._urls,
- "screen") # offset_position, kept for backcompat.
-
- gc.restore()
- renderer.close_group(self.__class__.__name__)
- self.stale = False
-
- def set_pickradius(self, pickradius):
- """
- Set the pick radius used for containment tests.
-
- Parameters
- ----------
- pickradius : float
- Pick radius, in points.
- """
- if not isinstance(pickradius, Real):
- raise ValueError(
- f"pickradius must be a real-valued number, not {pickradius!r}")
- self._pickradius = pickradius
-
- def get_pickradius(self):
- return self._pickradius
-
- def contains(self, mouseevent):
- """
- Test whether the mouse event occurred in the collection.
-
- Returns ``bool, dict(ind=itemlist)``, where every item in itemlist
- contains the event.
- """
- if self._different_canvas(mouseevent) or not self.get_visible():
- return False, {}
- pickradius = (
- float(self._picker)
- if isinstance(self._picker, Number) and
- self._picker is not True # the bool, not just nonzero or 1
- else self._pickradius)
- if self.axes:
- self.axes._unstale_viewLim()
- transform, offset_trf, offsets, paths = self._prepare_points()
- # Tests if the point is contained on one of the polygons formed
- # by the control points of each of the paths. A point is considered
- # "on" a path if it would lie within a stroke of width 2*pickradius
- # following the path. If pickradius <= 0, then we instead simply check
- # if the point is *inside* of the path instead.
- ind = _path.point_in_path_collection(
- mouseevent.x, mouseevent.y, pickradius,
- transform.frozen(), paths, self.get_transforms(),
- offsets, offset_trf, pickradius <= 0)
- return len(ind) > 0, dict(ind=ind)
-
- def set_urls(self, urls):
- """
- Parameters
- ----------
- urls : list of str or None
-
- Notes
- -----
- URLs are currently only implemented by the SVG backend. They are
- ignored by all other backends.
- """
- self._urls = urls if urls is not None else [None]
- self.stale = True
-
- def get_urls(self):
- """
- Return a list of URLs, one for each element of the collection.
-
- The list contains *None* for elements without a URL. See
- :doc:`/gallery/misc/hyperlinks_sgskip` for an example.
- """
- return self._urls
-
- def set_hatch(self, hatch):
- r"""
- Set the hatching pattern
-
- *hatch* can be one of::
-
- / - diagonal hatching
- \ - back diagonal
- | - vertical
- - - horizontal
- + - crossed
- x - crossed diagonal
- o - small circle
- O - large circle
- . - dots
- * - stars
-
- Letters can be combined, in which case all the specified
- hatchings are done. If same letter repeats, it increases the
- density of hatching of that pattern.
-
- Hatching is supported in the PostScript, PDF, SVG and Agg
- backends only.
-
- Unlike other properties such as linewidth and colors, hatching
- can only be specified for the collection as a whole, not separately
- for each member.
-
- Parameters
- ----------
- hatch : {'/', '\\', '|', '-', '+', 'x', 'o', 'O', '.', '*'}
- """
- # Use validate_hatch(list) after deprecation.
- mhatch._validate_hatch_pattern(hatch)
- self._hatch = hatch
- self.stale = True
-
- def get_hatch(self):
- """Return the current hatching pattern."""
- return self._hatch
-
- def set_offsets(self, offsets):
- """
- Set the offsets for the collection.
-
- Parameters
- ----------
- offsets : (N, 2) or (2,) array-like
- """
- offsets = np.asanyarray(offsets)
- if offsets.shape == (2,): # Broadcast (2,) -> (1, 2) but nothing else.
- offsets = offsets[None, :]
- cstack = (np.ma.column_stack if isinstance(offsets, np.ma.MaskedArray)
- else np.column_stack)
- self._offsets = cstack(
- (np.asanyarray(self.convert_xunits(offsets[:, 0]), float),
- np.asanyarray(self.convert_yunits(offsets[:, 1]), float)))
- self.stale = True
-
- def get_offsets(self):
- """Return the offsets for the collection."""
- # Default to zeros in the no-offset (None) case
- return np.zeros((1, 2)) if self._offsets is None else self._offsets
-
- def _get_default_linewidth(self):
- # This may be overridden in a subclass.
- return mpl.rcParams['patch.linewidth'] # validated as float
-
- def set_linewidth(self, lw):
- """
- Set the linewidth(s) for the collection. *lw* can be a scalar
- or a sequence; if it is a sequence the patches will cycle
- through the sequence
-
- Parameters
- ----------
- lw : float or list of floats
- """
- if lw is None:
- lw = self._get_default_linewidth()
- # get the un-scaled/broadcast lw
- self._us_lw = np.atleast_1d(lw)
-
- # scale all of the dash patterns.
- self._linewidths, self._linestyles = self._bcast_lwls(
- self._us_lw, self._us_linestyles)
- self.stale = True
-
- def set_linestyle(self, ls):
- """
- Set the linestyle(s) for the collection.
-
- =========================== =================
- linestyle description
- =========================== =================
- ``'-'`` or ``'solid'`` solid line
- ``'--'`` or ``'dashed'`` dashed line
- ``'-.'`` or ``'dashdot'`` dash-dotted line
- ``':'`` or ``'dotted'`` dotted line
- =========================== =================
-
- Alternatively a dash tuple of the following form can be provided::
-
- (offset, onoffseq),
-
- where ``onoffseq`` is an even length tuple of on and off ink in points.
-
- Parameters
- ----------
- ls : str or tuple or list thereof
- Valid values for individual linestyles include {'-', '--', '-.',
- ':', '', (offset, on-off-seq)}. See `.Line2D.set_linestyle` for a
- complete description.
- """
- try:
- dashes = [mlines._get_dash_pattern(ls)]
- except ValueError:
- try:
- dashes = [mlines._get_dash_pattern(x) for x in ls]
- except ValueError as err:
- emsg = f'Do not know how to convert {ls!r} to dashes'
- raise ValueError(emsg) from err
-
- # get the list of raw 'unscaled' dash patterns
- self._us_linestyles = dashes
-
- # broadcast and scale the lw and dash patterns
- self._linewidths, self._linestyles = self._bcast_lwls(
- self._us_lw, self._us_linestyles)
-
- @_docstring.interpd
- def set_capstyle(self, cs):
- """
- Set the `.CapStyle` for the collection (for all its elements).
-
- Parameters
- ----------
- cs : `.CapStyle` or %(CapStyle)s
- """
- self._capstyle = CapStyle(cs)
-
- @_docstring.interpd
- def get_capstyle(self):
- """
- Return the cap style for the collection (for all its elements).
-
- Returns
- -------
- %(CapStyle)s or None
- """
- return self._capstyle.name if self._capstyle else None
-
- @_docstring.interpd
- def set_joinstyle(self, js):
- """
- Set the `.JoinStyle` for the collection (for all its elements).
-
- Parameters
- ----------
- js : `.JoinStyle` or %(JoinStyle)s
- """
- self._joinstyle = JoinStyle(js)
-
- @_docstring.interpd
- def get_joinstyle(self):
- """
- Return the join style for the collection (for all its elements).
-
- Returns
- -------
- %(JoinStyle)s or None
- """
- return self._joinstyle.name if self._joinstyle else None
-
- @staticmethod
- def _bcast_lwls(linewidths, dashes):
- """
- Internal helper function to broadcast + scale ls/lw
-
- In the collection drawing code, the linewidth and linestyle are cycled
- through as circular buffers (via ``v[i % len(v)]``). Thus, if we are
- going to scale the dash pattern at set time (not draw time) we need to
- do the broadcasting now and expand both lists to be the same length.
-
- Parameters
- ----------
- linewidths : list
- line widths of collection
- dashes : list
- dash specification (offset, (dash pattern tuple))
-
- Returns
- -------
- linewidths, dashes : list
- Will be the same length, dashes are scaled by paired linewidth
- """
- if mpl.rcParams['_internal.classic_mode']:
- return linewidths, dashes
- # make sure they are the same length so we can zip them
- if len(dashes) != len(linewidths):
- l_dashes = len(dashes)
- l_lw = len(linewidths)
- gcd = math.gcd(l_dashes, l_lw)
- dashes = list(dashes) * (l_lw // gcd)
- linewidths = list(linewidths) * (l_dashes // gcd)
-
- # scale the dash patterns
- dashes = [mlines._scale_dashes(o, d, lw)
- for (o, d), lw in zip(dashes, linewidths)]
-
- return linewidths, dashes
-
- def get_antialiased(self):
- """
- Get the antialiasing state for rendering.
-
- Returns
- -------
- array of bools
- """
- return self._antialiaseds
-
- def set_antialiased(self, aa):
- """
- Set the antialiasing state for rendering.
-
- Parameters
- ----------
- aa : bool or list of bools
- """
- if aa is None:
- aa = self._get_default_antialiased()
- self._antialiaseds = np.atleast_1d(np.asarray(aa, bool))
- self.stale = True
-
- def _get_default_antialiased(self):
- # This may be overridden in a subclass.
- return mpl.rcParams['patch.antialiased']
-
- def set_color(self, c):
- """
- Set both the edgecolor and the facecolor.
-
- Parameters
- ----------
- c : color or list of RGBA tuples
-
- See Also
- --------
- Collection.set_facecolor, Collection.set_edgecolor
- For setting the edge or face color individually.
- """
- self.set_facecolor(c)
- self.set_edgecolor(c)
-
- def _get_default_facecolor(self):
- # This may be overridden in a subclass.
- return mpl.rcParams['patch.facecolor']
-
- def _set_facecolor(self, c):
- if c is None:
- c = self._get_default_facecolor()
-
- self._facecolors = mcolors.to_rgba_array(c, self._alpha)
- self.stale = True
-
- def set_facecolor(self, c):
- """
- Set the facecolor(s) of the collection. *c* can be a color (all patches
- have same color), or a sequence of colors; if it is a sequence the
- patches will cycle through the sequence.
-
- If *c* is 'none', the patch will not be filled.
-
- Parameters
- ----------
- c : color or list of colors
- """
- if isinstance(c, str) and c.lower() in ("none", "face"):
- c = c.lower()
- self._original_facecolor = c
- self._set_facecolor(c)
-
- def get_facecolor(self):
- return self._facecolors
-
- def get_edgecolor(self):
- if cbook._str_equal(self._edgecolors, 'face'):
- return self.get_facecolor()
- else:
- return self._edgecolors
-
- def _get_default_edgecolor(self):
- # This may be overridden in a subclass.
- return mpl.rcParams['patch.edgecolor']
-
- def _set_edgecolor(self, c):
- set_hatch_color = True
- if c is None:
- if (mpl.rcParams['patch.force_edgecolor']
- or self._edge_default
- or cbook._str_equal(self._original_facecolor, 'none')):
- c = self._get_default_edgecolor()
- else:
- c = 'none'
- set_hatch_color = False
- if cbook._str_lower_equal(c, 'face'):
- self._edgecolors = 'face'
- self.stale = True
- return
- self._edgecolors = mcolors.to_rgba_array(c, self._alpha)
- if set_hatch_color and len(self._edgecolors):
- self._hatch_color = tuple(self._edgecolors[0])
- self.stale = True
-
- def set_edgecolor(self, c):
- """
- Set the edgecolor(s) of the collection.
-
- Parameters
- ----------
- c : color or list of colors or 'face'
- The collection edgecolor(s). If a sequence, the patches cycle
- through it. If 'face', match the facecolor.
- """
- # We pass through a default value for use in LineCollection.
- # This allows us to maintain None as the default indicator in
- # _original_edgecolor.
- if isinstance(c, str) and c.lower() in ("none", "face"):
- c = c.lower()
- self._original_edgecolor = c
- self._set_edgecolor(c)
-
- def set_alpha(self, alpha):
- """
- Set the transparency of the collection.
-
- Parameters
- ----------
- alpha : float or array of float or None
- If not None, *alpha* values must be between 0 and 1, inclusive.
- If an array is provided, its length must match the number of
- elements in the collection. Masked values and nans are not
- supported.
- """
- artist.Artist._set_alpha_for_array(self, alpha)
- self._set_facecolor(self._original_facecolor)
- self._set_edgecolor(self._original_edgecolor)
-
- set_alpha.__doc__ = artist.Artist._set_alpha_for_array.__doc__
-
- def get_linewidth(self):
- return self._linewidths
-
- def get_linestyle(self):
- return self._linestyles
-
- def _set_mappable_flags(self):
- """
- Determine whether edges and/or faces are color-mapped.
-
- This is a helper for update_scalarmappable.
- It sets Boolean flags '_edge_is_mapped' and '_face_is_mapped'.
-
- Returns
- -------
- mapping_change : bool
- True if either flag is True, or if a flag has changed.
- """
- # The flags are initialized to None to ensure this returns True
- # the first time it is called.
- edge0 = self._edge_is_mapped
- face0 = self._face_is_mapped
- # After returning, the flags must be Booleans, not None.
- self._edge_is_mapped = False
- self._face_is_mapped = False
- if self._A is not None:
- if not cbook._str_equal(self._original_facecolor, 'none'):
- self._face_is_mapped = True
- if cbook._str_equal(self._original_edgecolor, 'face'):
- self._edge_is_mapped = True
- else:
- if self._original_edgecolor is None:
- self._edge_is_mapped = True
-
- mapped = self._face_is_mapped or self._edge_is_mapped
- changed = (edge0 is None or face0 is None
- or self._edge_is_mapped != edge0
- or self._face_is_mapped != face0)
- return mapped or changed
-
- def update_scalarmappable(self):
- """
- Update colors from the scalar mappable array, if any.
-
- Assign colors to edges and faces based on the array and/or
- colors that were directly set, as appropriate.
- """
- if not self._set_mappable_flags():
- return
- # Allow possibility to call 'self.set_array(None)'.
- if self._A is not None:
- # QuadMesh can map 2d arrays (but pcolormesh supplies 1d array)
- if self._A.ndim > 1 and not isinstance(self, _MeshData):
- raise ValueError('Collections can only map rank 1 arrays')
- if np.iterable(self._alpha):
- if self._alpha.size != self._A.size:
- raise ValueError(
- f'Data array shape, {self._A.shape} '
- 'is incompatible with alpha array shape, '
- f'{self._alpha.shape}. '
- 'This can occur with the deprecated '
- 'behavior of the "flat" shading option, '
- 'in which a row and/or column of the data '
- 'array is dropped.')
- # pcolormesh, scatter, maybe others flatten their _A
- self._alpha = self._alpha.reshape(self._A.shape)
- self._mapped_colors = self.to_rgba(self._A, self._alpha)
-
- if self._face_is_mapped:
- self._facecolors = self._mapped_colors
- else:
- self._set_facecolor(self._original_facecolor)
- if self._edge_is_mapped:
- self._edgecolors = self._mapped_colors
- else:
- self._set_edgecolor(self._original_edgecolor)
- self.stale = True
-
- def get_fill(self):
- """Return whether face is colored."""
- return not cbook._str_lower_equal(self._original_facecolor, "none")
-
- def update_from(self, other):
- """Copy properties from other to self."""
-
- artist.Artist.update_from(self, other)
- self._antialiaseds = other._antialiaseds
- self._mapped_colors = other._mapped_colors
- self._edge_is_mapped = other._edge_is_mapped
- self._original_edgecolor = other._original_edgecolor
- self._edgecolors = other._edgecolors
- self._face_is_mapped = other._face_is_mapped
- self._original_facecolor = other._original_facecolor
- self._facecolors = other._facecolors
- self._linewidths = other._linewidths
- self._linestyles = other._linestyles
- self._us_linestyles = other._us_linestyles
- self._pickradius = other._pickradius
- self._hatch = other._hatch
-
- # update_from for scalarmappable
- self._A = other._A
- self.norm = other.norm
- self.cmap = other.cmap
- self.stale = True
-
-
-class _CollectionWithSizes(Collection):
- """
- Base class for collections that have an array of sizes.
- """
- _factor = 1.0
-
- def get_sizes(self):
- """
- Return the sizes ('areas') of the elements in the collection.
-
- Returns
- -------
- array
- The 'area' of each element.
- """
- return self._sizes
-
- def set_sizes(self, sizes, dpi=72.0):
- """
- Set the sizes of each member of the collection.
-
- Parameters
- ----------
- sizes : `numpy.ndarray` or None
- The size to set for each element of the collection. The
- value is the 'area' of the element.
- dpi : float, default: 72
- The dpi of the canvas.
- """
- if sizes is None:
- self._sizes = np.array([])
- self._transforms = np.empty((0, 3, 3))
- else:
- self._sizes = np.asarray(sizes)
- self._transforms = np.zeros((len(self._sizes), 3, 3))
- scale = np.sqrt(self._sizes) * dpi / 72.0 * self._factor
- self._transforms[:, 0, 0] = scale
- self._transforms[:, 1, 1] = scale
- self._transforms[:, 2, 2] = 1.0
- self.stale = True
-
- @artist.allow_rasterization
- def draw(self, renderer):
- self.set_sizes(self._sizes, self.figure.dpi)
- super().draw(renderer)
-
-
-class PathCollection(_CollectionWithSizes):
- r"""
- A collection of `~.path.Path`\s, as created by e.g. `~.Axes.scatter`.
- """
-
- def __init__(self, paths, sizes=None, **kwargs):
- """
- Parameters
- ----------
- paths : list of `.path.Path`
- The paths that will make up the `.Collection`.
- sizes : array-like
- The factor by which to scale each drawn `~.path.Path`. One unit
- squared in the Path's data space is scaled to be ``sizes**2``
- points when rendered.
- **kwargs
- Forwarded to `.Collection`.
- """
-
- super().__init__(**kwargs)
- self.set_paths(paths)
- self.set_sizes(sizes)
- self.stale = True
-
- def get_paths(self):
- return self._paths
-
- def legend_elements(self, prop="colors", num="auto",
- fmt=None, func=lambda x: x, **kwargs):
- """
- Create legend handles and labels for a PathCollection.
-
- Each legend handle is a `.Line2D` representing the Path that was drawn,
- and each label is a string what each Path represents.
-
- This is useful for obtaining a legend for a `~.Axes.scatter` plot;
- e.g.::
-
- scatter = plt.scatter([1, 2, 3], [4, 5, 6], c=[7, 2, 3])
- plt.legend(*scatter.legend_elements())
-
- creates three legend elements, one for each color with the numerical
- values passed to *c* as the labels.
-
- Also see the :ref:`automatedlegendcreation` example.
-
- Parameters
- ----------
- prop : {"colors", "sizes"}, default: "colors"
- If "colors", the legend handles will show the different colors of
- the collection. If "sizes", the legend will show the different
- sizes. To set both, use *kwargs* to directly edit the `.Line2D`
- properties.
- num : int, None, "auto" (default), array-like, or `~.ticker.Locator`
- Target number of elements to create.
- If None, use all unique elements of the mappable array. If an
- integer, target to use *num* elements in the normed range.
- If *"auto"*, try to determine which option better suits the nature
- of the data.
- The number of created elements may slightly deviate from *num* due
- to a `~.ticker.Locator` being used to find useful locations.
- If a list or array, use exactly those elements for the legend.
- Finally, a `~.ticker.Locator` can be provided.
- fmt : str, `~matplotlib.ticker.Formatter`, or None (default)
- The format or formatter to use for the labels. If a string must be
- a valid input for a `.StrMethodFormatter`. If None (the default),
- use a `.ScalarFormatter`.
- func : function, default: ``lambda x: x``
- Function to calculate the labels. Often the size (or color)
- argument to `~.Axes.scatter` will have been pre-processed by the
- user using a function ``s = f(x)`` to make the markers visible;
- e.g. ``size = np.log10(x)``. Providing the inverse of this
- function here allows that pre-processing to be inverted, so that
- the legend labels have the correct values; e.g. ``func = lambda
- x: 10**x``.
- **kwargs
- Allowed keyword arguments are *color* and *size*. E.g. it may be
- useful to set the color of the markers if *prop="sizes"* is used;
- similarly to set the size of the markers if *prop="colors"* is
- used. Any further parameters are passed onto the `.Line2D`
- instance. This may be useful to e.g. specify a different
- *markeredgecolor* or *alpha* for the legend handles.
-
- Returns
- -------
- handles : list of `.Line2D`
- Visual representation of each element of the legend.
- labels : list of str
- The string labels for elements of the legend.
- """
- handles = []
- labels = []
- hasarray = self.get_array() is not None
- if fmt is None:
- fmt = mpl.ticker.ScalarFormatter(useOffset=False, useMathText=True)
- elif isinstance(fmt, str):
- fmt = mpl.ticker.StrMethodFormatter(fmt)
- fmt.create_dummy_axis()
-
- if prop == "colors":
- if not hasarray:
- warnings.warn("Collection without array used. Make sure to "
- "specify the values to be colormapped via the "
- "`c` argument.")
- return handles, labels
- u = np.unique(self.get_array())
- size = kwargs.pop("size", mpl.rcParams["lines.markersize"])
- elif prop == "sizes":
- u = np.unique(self.get_sizes())
- color = kwargs.pop("color", "k")
- else:
- raise ValueError("Valid values for `prop` are 'colors' or "
- f"'sizes'. You supplied '{prop}' instead.")
-
- fu = func(u)
- fmt.axis.set_view_interval(fu.min(), fu.max())
- fmt.axis.set_data_interval(fu.min(), fu.max())
- if num == "auto":
- num = 9
- if len(u) <= num:
- num = None
- if num is None:
- values = u
- label_values = func(values)
- else:
- if prop == "colors":
- arr = self.get_array()
- elif prop == "sizes":
- arr = self.get_sizes()
- if isinstance(num, mpl.ticker.Locator):
- loc = num
- elif np.iterable(num):
- loc = mpl.ticker.FixedLocator(num)
- else:
- num = int(num)
- loc = mpl.ticker.MaxNLocator(nbins=num, min_n_ticks=num-1,
- steps=[1, 2, 2.5, 3, 5, 6, 8, 10])
- label_values = loc.tick_values(func(arr).min(), func(arr).max())
- cond = ((label_values >= func(arr).min()) &
- (label_values <= func(arr).max()))
- label_values = label_values[cond]
- yarr = np.linspace(arr.min(), arr.max(), 256)
- xarr = func(yarr)
- ix = np.argsort(xarr)
- values = np.interp(label_values, xarr[ix], yarr[ix])
-
- kw = {"markeredgewidth": self.get_linewidths()[0],
- "alpha": self.get_alpha(),
- **kwargs}
-
- for val, lab in zip(values, label_values):
- if prop == "colors":
- color = self.cmap(self.norm(val))
- elif prop == "sizes":
- size = np.sqrt(val)
- if np.isclose(size, 0.0):
- continue
- h = mlines.Line2D([0], [0], ls="", color=color, ms=size,
- marker=self.get_paths()[0], **kw)
- handles.append(h)
- if hasattr(fmt, "set_locs"):
- fmt.set_locs(label_values)
- l = fmt(lab)
- labels.append(l)
-
- return handles, labels
-
-
-class PolyCollection(_CollectionWithSizes):
-
- def __init__(self, verts, sizes=None, *, closed=True, **kwargs):
- """
- Parameters
- ----------
- verts : list of array-like
- The sequence of polygons [*verts0*, *verts1*, ...] where each
- element *verts_i* defines the vertices of polygon *i* as a 2D
- array-like of shape (M, 2).
- sizes : array-like, default: None
- Squared scaling factors for the polygons. The coordinates of each
- polygon *verts_i* are multiplied by the square-root of the
- corresponding entry in *sizes* (i.e., *sizes* specify the scaling
- of areas). The scaling is applied before the Artist master
- transform.
- closed : bool, default: True
- Whether the polygon should be closed by adding a CLOSEPOLY
- connection at the end.
- **kwargs
- Forwarded to `.Collection`.
- """
- super().__init__(**kwargs)
- self.set_sizes(sizes)
- self.set_verts(verts, closed)
- self.stale = True
-
- def set_verts(self, verts, closed=True):
- """
- Set the vertices of the polygons.
-
- Parameters
- ----------
- verts : list of array-like
- The sequence of polygons [*verts0*, *verts1*, ...] where each
- element *verts_i* defines the vertices of polygon *i* as a 2D
- array-like of shape (M, 2).
- closed : bool, default: True
- Whether the polygon should be closed by adding a CLOSEPOLY
- connection at the end.
- """
- self.stale = True
- if isinstance(verts, np.ma.MaskedArray):
- verts = verts.astype(float).filled(np.nan)
-
- # No need to do anything fancy if the path isn't closed.
- if not closed:
- self._paths = [mpath.Path(xy) for xy in verts]
- return
-
- # Fast path for arrays
- if isinstance(verts, np.ndarray) and len(verts.shape) == 3:
- verts_pad = np.concatenate((verts, verts[:, :1]), axis=1)
- # Creating the codes once is much faster than having Path do it
- # separately each time by passing closed=True.
- codes = np.empty(verts_pad.shape[1], dtype=mpath.Path.code_type)
- codes[:] = mpath.Path.LINETO
- codes[0] = mpath.Path.MOVETO
- codes[-1] = mpath.Path.CLOSEPOLY
- self._paths = [mpath.Path(xy, codes) for xy in verts_pad]
- return
-
- self._paths = []
- for xy in verts:
- if len(xy):
- self._paths.append(mpath.Path._create_closed(xy))
- else:
- self._paths.append(mpath.Path(xy))
-
- set_paths = set_verts
-
- def set_verts_and_codes(self, verts, codes):
- """Initialize vertices with path codes."""
- if len(verts) != len(codes):
- raise ValueError("'codes' must be a 1D list or array "
- "with the same length of 'verts'")
- self._paths = [mpath.Path(xy, cds) if len(xy) else mpath.Path(xy)
- for xy, cds in zip(verts, codes)]
- self.stale = True
-
- @classmethod
- @_api.deprecated("3.7", alternative="fill_between")
- def span_where(cls, x, ymin, ymax, where, **kwargs):
- """
- Return a `.BrokenBarHCollection` that plots horizontal bars from
- over the regions in *x* where *where* is True. The bars range
- on the y-axis from *ymin* to *ymax*
-
- *kwargs* are passed on to the collection.
- """
- xranges = []
- for ind0, ind1 in cbook.contiguous_regions(where):
- xslice = x[ind0:ind1]
- if not len(xslice):
- continue
- xranges.append((xslice[0], xslice[-1] - xslice[0]))
- return BrokenBarHCollection(xranges, [ymin, ymax - ymin], **kwargs)
-
-
-@_api.deprecated("3.7")
-class BrokenBarHCollection(PolyCollection):
- """
- A collection of horizontal bars spanning *yrange* with a sequence of
- *xranges*.
- """
- def __init__(self, xranges, yrange, **kwargs):
- """
- Parameters
- ----------
- xranges : list of (float, float)
- The sequence of (left-edge-position, width) pairs for each bar.
- yrange : (float, float)
- The (lower-edge, height) common to all bars.
- **kwargs
- Forwarded to `.Collection`.
- """
- ymin, ywidth = yrange
- ymax = ymin + ywidth
- verts = [[(xmin, ymin),
- (xmin, ymax),
- (xmin + xwidth, ymax),
- (xmin + xwidth, ymin),
- (xmin, ymin)] for xmin, xwidth in xranges]
- super().__init__(verts, **kwargs)
-
-
-class RegularPolyCollection(_CollectionWithSizes):
- """A collection of n-sided regular polygons."""
-
- _path_generator = mpath.Path.unit_regular_polygon
- _factor = np.pi ** (-1/2)
-
- def __init__(self,
- numsides,
- *,
- rotation=0,
- sizes=(1,),
- **kwargs):
- """
- Parameters
- ----------
- numsides : int
- The number of sides of the polygon.
- rotation : float
- The rotation of the polygon in radians.
- sizes : tuple of float
- The area of the circle circumscribing the polygon in points^2.
- **kwargs
- Forwarded to `.Collection`.
-
- Examples
- --------
- See :doc:`/gallery/event_handling/lasso_demo` for a complete example::
-
- offsets = np.random.rand(20, 2)
- facecolors = [cm.jet(x) for x in np.random.rand(20)]
-
- collection = RegularPolyCollection(
- numsides=5, # a pentagon
- rotation=0, sizes=(50,),
- facecolors=facecolors,
- edgecolors=("black",),
- linewidths=(1,),
- offsets=offsets,
- offset_transform=ax.transData,
- )
- """
- super().__init__(**kwargs)
- self.set_sizes(sizes)
- self._numsides = numsides
- self._paths = [self._path_generator(numsides)]
- self._rotation = rotation
- self.set_transform(transforms.IdentityTransform())
-
- def get_numsides(self):
- return self._numsides
-
- def get_rotation(self):
- return self._rotation
-
- @artist.allow_rasterization
- def draw(self, renderer):
- self.set_sizes(self._sizes, self.figure.dpi)
- self._transforms = [
- transforms.Affine2D(x).rotate(-self._rotation).get_matrix()
- for x in self._transforms
- ]
- # Explicitly not super().draw, because set_sizes must be called before
- # updating self._transforms.
- Collection.draw(self, renderer)
-
-
-class StarPolygonCollection(RegularPolyCollection):
- """Draw a collection of regular stars with *numsides* points."""
- _path_generator = mpath.Path.unit_regular_star
-
-
-class AsteriskPolygonCollection(RegularPolyCollection):
- """Draw a collection of regular asterisks with *numsides* points."""
- _path_generator = mpath.Path.unit_regular_asterisk
-
-
-class LineCollection(Collection):
- r"""
- Represents a sequence of `.Line2D`\s that should be drawn together.
-
- This class extends `.Collection` to represent a sequence of
- `.Line2D`\s instead of just a sequence of `.Patch`\s.
- Just as in `.Collection`, each property of a *LineCollection* may be either
- a single value or a list of values. This list is then used cyclically for
- each element of the LineCollection, so the property of the ``i``\th element
- of the collection is::
-
- prop[i % len(prop)]
-
- The properties of each member of a *LineCollection* default to their values
- in :rc:`lines.*` instead of :rc:`patch.*`, and the property *colors* is
- added in place of *edgecolors*.
- """
-
- _edge_default = True
-
- def __init__(self, segments, # Can be None.
- *,
- zorder=2, # Collection.zorder is 1
- **kwargs
- ):
- """
- Parameters
- ----------
- segments : list of array-like
- A sequence (*line0*, *line1*, *line2*) of lines, where each line is a list
- of points::
-
- lineN = [(x0, y0), (x1, y1), ... (xm, ym)]
-
- or the equivalent Mx2 numpy array with two columns. Each line
- can have a different number of segments.
- linewidths : float or list of float, default: :rc:`lines.linewidth`
- The width of each line in points.
- colors : color or list of color, default: :rc:`lines.color`
- A sequence of RGBA tuples (e.g., arbitrary color strings, etc, not
- allowed).
- antialiaseds : bool or list of bool, default: :rc:`lines.antialiased`
- Whether to use antialiasing for each line.
- zorder : float, default: 2
- zorder of the lines once drawn.
-
- facecolors : color or list of color, default: 'none'
- When setting *facecolors*, each line is interpreted as a boundary
- for an area, implicitly closing the path from the last point to the
- first point. The enclosed area is filled with *facecolor*.
- In order to manually specify what should count as the "interior" of
- each line, please use `.PathCollection` instead, where the
- "interior" can be specified by appropriate usage of
- `~.path.Path.CLOSEPOLY`.
-
- **kwargs
- Forwarded to `.Collection`.
- """
- # Unfortunately, mplot3d needs this explicit setting of 'facecolors'.
- kwargs.setdefault('facecolors', 'none')
- super().__init__(
- zorder=zorder,
- **kwargs)
- self.set_segments(segments)
-
- def set_segments(self, segments):
- if segments is None:
- return
-
- self._paths = [mpath.Path(seg) if isinstance(seg, np.ma.MaskedArray)
- else mpath.Path(np.asarray(seg, float))
- for seg in segments]
- self.stale = True
-
- set_verts = set_segments # for compatibility with PolyCollection
- set_paths = set_segments
-
- def get_segments(self):
- """
- Returns
- -------
- list
- List of segments in the LineCollection. Each list item contains an
- array of vertices.
- """
- segments = []
-
- for path in self._paths:
- vertices = [
- vertex
- for vertex, _
- # Never simplify here, we want to get the data-space values
- # back and there in no way to know the "right" simplification
- # threshold so never try.
- in path.iter_segments(simplify=False)
- ]
- vertices = np.asarray(vertices)
- segments.append(vertices)
-
- return segments
-
- def _get_default_linewidth(self):
- return mpl.rcParams['lines.linewidth']
-
- def _get_default_antialiased(self):
- return mpl.rcParams['lines.antialiased']
-
- def _get_default_edgecolor(self):
- return mpl.rcParams['lines.color']
-
- def _get_default_facecolor(self):
- return 'none'
-
- def set_alpha(self, alpha):
- # docstring inherited
- super().set_alpha(alpha)
- if self._gapcolor is not None:
- self.set_gapcolor(self._original_gapcolor)
-
- def set_color(self, c):
- """
- Set the edgecolor(s) of the LineCollection.
-
- Parameters
- ----------
- c : color or list of colors
- Single color (all lines have same color), or a
- sequence of RGBA tuples; if it is a sequence the lines will
- cycle through the sequence.
- """
- self.set_edgecolor(c)
-
- set_colors = set_color
-
- def get_color(self):
- return self._edgecolors
-
- get_colors = get_color # for compatibility with old versions
-
- def set_gapcolor(self, gapcolor):
- """
- Set a color to fill the gaps in the dashed line style.
-
- .. note::
-
- Striped lines are created by drawing two interleaved dashed lines.
- There can be overlaps between those two, which may result in
- artifacts when using transparency.
-
- This functionality is experimental and may change.
-
- Parameters
- ----------
- gapcolor : color or list of colors or None
- The color with which to fill the gaps. If None, the gaps are
- unfilled.
- """
- self._original_gapcolor = gapcolor
- self._set_gapcolor(gapcolor)
-
- def _set_gapcolor(self, gapcolor):
- if gapcolor is not None:
- gapcolor = mcolors.to_rgba_array(gapcolor, self._alpha)
- self._gapcolor = gapcolor
- self.stale = True
-
- def get_gapcolor(self):
- return self._gapcolor
-
- def _get_inverse_paths_linestyles(self):
- """
- Returns the path and pattern for the gaps in the non-solid lines.
-
- This path and pattern is the inverse of the path and pattern used to
- construct the non-solid lines. For solid lines, we set the inverse path
- to nans to prevent drawing an inverse line.
- """
- path_patterns = [
- (mpath.Path(np.full((1, 2), np.nan)), ls)
- if ls == (0, None) else
- (path, mlines._get_inverse_dash_pattern(*ls))
- for (path, ls) in
- zip(self._paths, itertools.cycle(self._linestyles))]
-
- return zip(*path_patterns)
-
-
-class EventCollection(LineCollection):
- """
- A collection of locations along a single axis at which an "event" occurred.
-
- The events are given by a 1-dimensional array. They do not have an
- amplitude and are displayed as parallel lines.
- """
-
- _edge_default = True
-
- def __init__(self,
- positions, # Cannot be None.
- orientation='horizontal',
- *,
- lineoffset=0,
- linelength=1,
- linewidth=None,
- color=None,
- linestyle='solid',
- antialiased=None,
- **kwargs
- ):
- """
- Parameters
- ----------
- positions : 1D array-like
- Each value is an event.
- orientation : {'horizontal', 'vertical'}, default: 'horizontal'
- The sequence of events is plotted along this direction.
- The marker lines of the single events are along the orthogonal
- direction.
- lineoffset : float, default: 0
- The offset of the center of the markers from the origin, in the
- direction orthogonal to *orientation*.
- linelength : float, default: 1
- The total height of the marker (i.e. the marker stretches from
- ``lineoffset - linelength/2`` to ``lineoffset + linelength/2``).
- linewidth : float or list thereof, default: :rc:`lines.linewidth`
- The line width of the event lines, in points.
- color : color or list of colors, default: :rc:`lines.color`
- The color of the event lines.
- linestyle : str or tuple or list thereof, default: 'solid'
- Valid strings are ['solid', 'dashed', 'dashdot', 'dotted',
- '-', '--', '-.', ':']. Dash tuples should be of the form::
-
- (offset, onoffseq),
-
- where *onoffseq* is an even length tuple of on and off ink
- in points.
- antialiased : bool or list thereof, default: :rc:`lines.antialiased`
- Whether to use antialiasing for drawing the lines.
- **kwargs
- Forwarded to `.LineCollection`.
-
- Examples
- --------
- .. plot:: gallery/lines_bars_and_markers/eventcollection_demo.py
- """
- super().__init__([],
- linewidths=linewidth, linestyles=linestyle,
- colors=color, antialiaseds=antialiased,
- **kwargs)
- self._is_horizontal = True # Initial value, may be switched below.
- self._linelength = linelength
- self._lineoffset = lineoffset
- self.set_orientation(orientation)
- self.set_positions(positions)
-
- def get_positions(self):
- """
- Return an array containing the floating-point values of the positions.
- """
- pos = 0 if self.is_horizontal() else 1
- return [segment[0, pos] for segment in self.get_segments()]
-
- def set_positions(self, positions):
- """Set the positions of the events."""
- if positions is None:
- positions = []
- if np.ndim(positions) != 1:
- raise ValueError('positions must be one-dimensional')
- lineoffset = self.get_lineoffset()
- linelength = self.get_linelength()
- pos_idx = 0 if self.is_horizontal() else 1
- segments = np.empty((len(positions), 2, 2))
- segments[:, :, pos_idx] = np.sort(positions)[:, None]
- segments[:, 0, 1 - pos_idx] = lineoffset + linelength / 2
- segments[:, 1, 1 - pos_idx] = lineoffset - linelength / 2
- self.set_segments(segments)
-
- def add_positions(self, position):
- """Add one or more events at the specified positions."""
- if position is None or (hasattr(position, 'len') and
- len(position) == 0):
- return
- positions = self.get_positions()
- positions = np.hstack([positions, np.asanyarray(position)])
- self.set_positions(positions)
- extend_positions = append_positions = add_positions
-
- def is_horizontal(self):
- """True if the eventcollection is horizontal, False if vertical."""
- return self._is_horizontal
-
- def get_orientation(self):
- """
- Return the orientation of the event line ('horizontal' or 'vertical').
- """
- return 'horizontal' if self.is_horizontal() else 'vertical'
-
- def switch_orientation(self):
- """
- Switch the orientation of the event line, either from vertical to
- horizontal or vice versus.
- """
- segments = self.get_segments()
- for i, segment in enumerate(segments):
- segments[i] = np.fliplr(segment)
- self.set_segments(segments)
- self._is_horizontal = not self.is_horizontal()
- self.stale = True
-
- def set_orientation(self, orientation):
- """
- Set the orientation of the event line.
-
- Parameters
- ----------
- orientation : {'horizontal', 'vertical'}
- """
- is_horizontal = _api.check_getitem(
- {"horizontal": True, "vertical": False},
- orientation=orientation)
- if is_horizontal == self.is_horizontal():
- return
- self.switch_orientation()
-
- def get_linelength(self):
- """Return the length of the lines used to mark each event."""
- return self._linelength
-
- def set_linelength(self, linelength):
- """Set the length of the lines used to mark each event."""
- if linelength == self.get_linelength():
- return
- lineoffset = self.get_lineoffset()
- segments = self.get_segments()
- pos = 1 if self.is_horizontal() else 0
- for segment in segments:
- segment[0, pos] = lineoffset + linelength / 2.
- segment[1, pos] = lineoffset - linelength / 2.
- self.set_segments(segments)
- self._linelength = linelength
-
- def get_lineoffset(self):
- """Return the offset of the lines used to mark each event."""
- return self._lineoffset
-
- def set_lineoffset(self, lineoffset):
- """Set the offset of the lines used to mark each event."""
- if lineoffset == self.get_lineoffset():
- return
- linelength = self.get_linelength()
- segments = self.get_segments()
- pos = 1 if self.is_horizontal() else 0
- for segment in segments:
- segment[0, pos] = lineoffset + linelength / 2.
- segment[1, pos] = lineoffset - linelength / 2.
- self.set_segments(segments)
- self._lineoffset = lineoffset
-
- def get_linewidth(self):
- """Get the width of the lines used to mark each event."""
- return super().get_linewidth()[0]
-
- def get_linewidths(self):
- return super().get_linewidth()
-
- def get_color(self):
- """Return the color of the lines used to mark each event."""
- return self.get_colors()[0]
-
-
-class CircleCollection(_CollectionWithSizes):
- """A collection of circles, drawn using splines."""
-
- _factor = np.pi ** (-1/2)
-
- def __init__(self, sizes, **kwargs):
- """
- Parameters
- ----------
- sizes : float or array-like
- The area of each circle in points^2.
- **kwargs
- Forwarded to `.Collection`.
- """
- super().__init__(**kwargs)
- self.set_sizes(sizes)
- self.set_transform(transforms.IdentityTransform())
- self._paths = [mpath.Path.unit_circle()]
-
-
-class EllipseCollection(Collection):
- """A collection of ellipses, drawn using splines."""
-
- def __init__(self, widths, heights, angles, *, units='points', **kwargs):
- """
- Parameters
- ----------
- widths : array-like
- The lengths of the first axes (e.g., major axis lengths).
- heights : array-like
- The lengths of second axes.
- angles : array-like
- The angles of the first axes, degrees CCW from the x-axis.
- units : {'points', 'inches', 'dots', 'width', 'height', 'x', 'y', 'xy'}
- The units in which majors and minors are given; 'width' and
- 'height' refer to the dimensions of the axes, while 'x' and 'y'
- refer to the *offsets* data units. 'xy' differs from all others in
- that the angle as plotted varies with the aspect ratio, and equals
- the specified angle only when the aspect ratio is unity. Hence
- it behaves the same as the `~.patches.Ellipse` with
- ``axes.transData`` as its transform.
- **kwargs
- Forwarded to `Collection`.
- """
- super().__init__(**kwargs)
- self._widths = 0.5 * np.asarray(widths).ravel()
- self._heights = 0.5 * np.asarray(heights).ravel()
- self._angles = np.deg2rad(angles).ravel()
- self._units = units
- self.set_transform(transforms.IdentityTransform())
- self._transforms = np.empty((0, 3, 3))
- self._paths = [mpath.Path.unit_circle()]
-
- def _set_transforms(self):
- """Calculate transforms immediately before drawing."""
-
- ax = self.axes
- fig = self.figure
-
- if self._units == 'xy':
- sc = 1
- elif self._units == 'x':
- sc = ax.bbox.width / ax.viewLim.width
- elif self._units == 'y':
- sc = ax.bbox.height / ax.viewLim.height
- elif self._units == 'inches':
- sc = fig.dpi
- elif self._units == 'points':
- sc = fig.dpi / 72.0
- elif self._units == 'width':
- sc = ax.bbox.width
- elif self._units == 'height':
- sc = ax.bbox.height
- elif self._units == 'dots':
- sc = 1.0
- else:
- raise ValueError(f'Unrecognized units: {self._units!r}')
-
- self._transforms = np.zeros((len(self._widths), 3, 3))
- widths = self._widths * sc
- heights = self._heights * sc
- sin_angle = np.sin(self._angles)
- cos_angle = np.cos(self._angles)
- self._transforms[:, 0, 0] = widths * cos_angle
- self._transforms[:, 0, 1] = heights * -sin_angle
- self._transforms[:, 1, 0] = widths * sin_angle
- self._transforms[:, 1, 1] = heights * cos_angle
- self._transforms[:, 2, 2] = 1.0
-
- _affine = transforms.Affine2D
- if self._units == 'xy':
- m = ax.transData.get_affine().get_matrix().copy()
- m[:2, 2:] = 0
- self.set_transform(_affine(m))
-
- @artist.allow_rasterization
- def draw(self, renderer):
- self._set_transforms()
- super().draw(renderer)
-
-
-class PatchCollection(Collection):
- """
- A generic collection of patches.
-
- PatchCollection draws faster than a large number of equivalent individual
- Patches. It also makes it easier to assign a colormap to a heterogeneous
- collection of patches.
- """
-
- def __init__(self, patches, *, match_original=False, **kwargs):
- """
- Parameters
- ----------
- patches : list of `.Patch`
- A sequence of Patch objects. This list may include
- a heterogeneous assortment of different patch types.
-
- match_original : bool, default: False
- If True, use the colors and linewidths of the original
- patches. If False, new colors may be assigned by
- providing the standard collection arguments, facecolor,
- edgecolor, linewidths, norm or cmap.
-
- **kwargs
- All other parameters are forwarded to `.Collection`.
-
- If any of *edgecolors*, *facecolors*, *linewidths*, *antialiaseds*
- are None, they default to their `.rcParams` patch setting, in
- sequence form.
-
- Notes
- -----
- The use of `~matplotlib.cm.ScalarMappable` functionality is optional.
- If the `~matplotlib.cm.ScalarMappable` matrix ``_A`` has been set (via
- a call to `~.ScalarMappable.set_array`), at draw time a call to scalar
- mappable will be made to set the face colors.
- """
-
- if match_original:
- def determine_facecolor(patch):
- if patch.get_fill():
- return patch.get_facecolor()
- return [0, 0, 0, 0]
-
- kwargs['facecolors'] = [determine_facecolor(p) for p in patches]
- kwargs['edgecolors'] = [p.get_edgecolor() for p in patches]
- kwargs['linewidths'] = [p.get_linewidth() for p in patches]
- kwargs['linestyles'] = [p.get_linestyle() for p in patches]
- kwargs['antialiaseds'] = [p.get_antialiased() for p in patches]
-
- super().__init__(**kwargs)
-
- self.set_paths(patches)
-
- def set_paths(self, patches):
- paths = [p.get_transform().transform_path(p.get_path())
- for p in patches]
- self._paths = paths
-
-
-class TriMesh(Collection):
- """
- Class for the efficient drawing of a triangular mesh using Gouraud shading.
-
- A triangular mesh is a `~matplotlib.tri.Triangulation` object.
- """
- def __init__(self, triangulation, **kwargs):
- super().__init__(**kwargs)
- self._triangulation = triangulation
- self._shading = 'gouraud'
-
- self._bbox = transforms.Bbox.unit()
-
- # Unfortunately this requires a copy, unless Triangulation
- # was rewritten.
- xy = np.hstack((triangulation.x.reshape(-1, 1),
- triangulation.y.reshape(-1, 1)))
- self._bbox.update_from_data_xy(xy)
-
- def get_paths(self):
- if self._paths is None:
- self.set_paths()
- return self._paths
-
- def set_paths(self):
- self._paths = self.convert_mesh_to_paths(self._triangulation)
-
- @staticmethod
- def convert_mesh_to_paths(tri):
- """
- Convert a given mesh into a sequence of `.Path` objects.
-
- This function is primarily of use to implementers of backends that do
- not directly support meshes.
- """
- triangles = tri.get_masked_triangles()
- verts = np.stack((tri.x[triangles], tri.y[triangles]), axis=-1)
- return [mpath.Path(x) for x in verts]
-
- @artist.allow_rasterization
- def draw(self, renderer):
- if not self.get_visible():
- return
- renderer.open_group(self.__class__.__name__, gid=self.get_gid())
- transform = self.get_transform()
-
- # Get a list of triangles and the color at each vertex.
- tri = self._triangulation
- triangles = tri.get_masked_triangles()
-
- verts = np.stack((tri.x[triangles], tri.y[triangles]), axis=-1)
-
- self.update_scalarmappable()
- colors = self._facecolors[triangles]
-
- gc = renderer.new_gc()
- self._set_gc_clip(gc)
- gc.set_linewidth(self.get_linewidth()[0])
- renderer.draw_gouraud_triangles(gc, verts, colors, transform.frozen())
- gc.restore()
- renderer.close_group(self.__class__.__name__)
-
-
-class _MeshData:
- r"""
- Class for managing the two dimensional coordinates of Quadrilateral meshes
- and the associated data with them. This class is a mixin and is intended to
- be used with another collection that will implement the draw separately.
-
- A quadrilateral mesh is a grid of M by N adjacent quadrilaterals that are
- defined via a (M+1, N+1) grid of vertices. The quadrilateral (m, n) is
- defined by the vertices ::
-
- (m+1, n) ----------- (m+1, n+1)
- / /
- / /
- / /
- (m, n) -------- (m, n+1)
-
- The mesh need not be regular and the polygons need not be convex.
-
- Parameters
- ----------
- coordinates : (M+1, N+1, 2) array-like
- The vertices. ``coordinates[m, n]`` specifies the (x, y) coordinates
- of vertex (m, n).
-
- shading : {'flat', 'gouraud'}, default: 'flat'
- """
- def __init__(self, coordinates, *, shading='flat'):
- _api.check_shape((None, None, 2), coordinates=coordinates)
- self._coordinates = coordinates
- self._shading = shading
-
- def set_array(self, A):
- """
- Set the data values.
-
- Parameters
- ----------
- A : array-like
- The mesh data. Supported array shapes are:
-
- - (M, N) or (M*N,): a mesh with scalar data. The values are mapped
- to colors using normalization and a colormap. See parameters
- *norm*, *cmap*, *vmin*, *vmax*.
- - (M, N, 3): an image with RGB values (0-1 float or 0-255 int).
- - (M, N, 4): an image with RGBA values (0-1 float or 0-255 int),
- i.e. including transparency.
-
- If the values are provided as a 2D grid, the shape must match the
- coordinates grid. If the values are 1D, they are reshaped to 2D.
- M, N follow from the coordinates grid, where the coordinates grid
- shape is (M, N) for 'gouraud' *shading* and (M+1, N+1) for 'flat'
- shading.
- """
- height, width = self._coordinates.shape[0:-1]
- if self._shading == 'flat':
- h, w = height - 1, width - 1
- else:
- h, w = height, width
- ok_shapes = [(h, w, 3), (h, w, 4), (h, w), (h * w,)]
- if A is not None:
- shape = np.shape(A)
- if shape not in ok_shapes:
- raise ValueError(
- f"For X ({width}) and Y ({height}) with {self._shading} "
- f"shading, A should have shape "
- f"{' or '.join(map(str, ok_shapes))}, not {A.shape}")
- return super().set_array(A)
-
- def get_coordinates(self):
- """
- Return the vertices of the mesh as an (M+1, N+1, 2) array.
-
- M, N are the number of quadrilaterals in the rows / columns of the
- mesh, corresponding to (M+1, N+1) vertices.
- The last dimension specifies the components (x, y).
- """
- return self._coordinates
-
- def get_edgecolor(self):
- # docstring inherited
- # Note that we want to return an array of shape (N*M, 4)
- # a flattened RGBA collection
- return super().get_edgecolor().reshape(-1, 4)
-
- def get_facecolor(self):
- # docstring inherited
- # Note that we want to return an array of shape (N*M, 4)
- # a flattened RGBA collection
- return super().get_facecolor().reshape(-1, 4)
-
- @staticmethod
- def _convert_mesh_to_paths(coordinates):
- """
- Convert a given mesh into a sequence of `.Path` objects.
-
- This function is primarily of use to implementers of backends that do
- not directly support quadmeshes.
- """
- if isinstance(coordinates, np.ma.MaskedArray):
- c = coordinates.data
- else:
- c = coordinates
- points = np.concatenate([
- c[:-1, :-1],
- c[:-1, 1:],
- c[1:, 1:],
- c[1:, :-1],
- c[:-1, :-1]
- ], axis=2).reshape((-1, 5, 2))
- return [mpath.Path(x) for x in points]
-
- def _convert_mesh_to_triangles(self, coordinates):
- """
- Convert a given mesh into a sequence of triangles, each point
- with its own color. The result can be used to construct a call to
- `~.RendererBase.draw_gouraud_triangles`.
- """
- if isinstance(coordinates, np.ma.MaskedArray):
- p = coordinates.data
- else:
- p = coordinates
-
- p_a = p[:-1, :-1]
- p_b = p[:-1, 1:]
- p_c = p[1:, 1:]
- p_d = p[1:, :-1]
- p_center = (p_a + p_b + p_c + p_d) / 4.0
- triangles = np.concatenate([
- p_a, p_b, p_center,
- p_b, p_c, p_center,
- p_c, p_d, p_center,
- p_d, p_a, p_center,
- ], axis=2).reshape((-1, 3, 2))
-
- c = self.get_facecolor().reshape((*coordinates.shape[:2], 4))
- z = self.get_array()
- mask = z.mask if np.ma.is_masked(z) else None
- if mask is not None:
- c[mask, 3] = np.nan
- c_a = c[:-1, :-1]
- c_b = c[:-1, 1:]
- c_c = c[1:, 1:]
- c_d = c[1:, :-1]
- c_center = (c_a + c_b + c_c + c_d) / 4.0
- colors = np.concatenate([
- c_a, c_b, c_center,
- c_b, c_c, c_center,
- c_c, c_d, c_center,
- c_d, c_a, c_center,
- ], axis=2).reshape((-1, 3, 4))
- tmask = np.isnan(colors[..., 2, 3])
- return triangles[~tmask], colors[~tmask]
-
-
-class QuadMesh(_MeshData, Collection):
- r"""
- Class for the efficient drawing of a quadrilateral mesh.
-
- A quadrilateral mesh is a grid of M by N adjacent quadrilaterals that are
- defined via a (M+1, N+1) grid of vertices. The quadrilateral (m, n) is
- defined by the vertices ::
-
- (m+1, n) ----------- (m+1, n+1)
- / /
- / /
- / /
- (m, n) -------- (m, n+1)
-
- The mesh need not be regular and the polygons need not be convex.
-
- Parameters
- ----------
- coordinates : (M+1, N+1, 2) array-like
- The vertices. ``coordinates[m, n]`` specifies the (x, y) coordinates
- of vertex (m, n).
-
- antialiased : bool, default: True
-
- shading : {'flat', 'gouraud'}, default: 'flat'
-
- Notes
- -----
- Unlike other `.Collection`\s, the default *pickradius* of `.QuadMesh` is 0,
- i.e. `~.Artist.contains` checks whether the test point is within any of the
- mesh quadrilaterals.
-
- """
-
- def __init__(self, coordinates, *, antialiased=True, shading='flat',
- **kwargs):
- kwargs.setdefault("pickradius", 0)
- super().__init__(coordinates=coordinates, shading=shading)
- Collection.__init__(self, **kwargs)
-
- self._antialiased = antialiased
- self._bbox = transforms.Bbox.unit()
- self._bbox.update_from_data_xy(self._coordinates.reshape(-1, 2))
- self.set_mouseover(False)
-
- def get_paths(self):
- if self._paths is None:
- self.set_paths()
- return self._paths
-
- def set_paths(self):
- self._paths = self._convert_mesh_to_paths(self._coordinates)
- self.stale = True
-
- def get_datalim(self, transData):
- return (self.get_transform() - transData).transform_bbox(self._bbox)
-
- @artist.allow_rasterization
- def draw(self, renderer):
- if not self.get_visible():
- return
- renderer.open_group(self.__class__.__name__, self.get_gid())
- transform = self.get_transform()
- offset_trf = self.get_offset_transform()
- offsets = self.get_offsets()
-
- if self.have_units():
- xs = self.convert_xunits(offsets[:, 0])
- ys = self.convert_yunits(offsets[:, 1])
- offsets = np.column_stack([xs, ys])
-
- self.update_scalarmappable()
-
- if not transform.is_affine:
- coordinates = self._coordinates.reshape((-1, 2))
- coordinates = transform.transform(coordinates)
- coordinates = coordinates.reshape(self._coordinates.shape)
- transform = transforms.IdentityTransform()
- else:
- coordinates = self._coordinates
-
- if not offset_trf.is_affine:
- offsets = offset_trf.transform_non_affine(offsets)
- offset_trf = offset_trf.get_affine()
-
- gc = renderer.new_gc()
- gc.set_snap(self.get_snap())
- self._set_gc_clip(gc)
- gc.set_linewidth(self.get_linewidth()[0])
-
- if self._shading == 'gouraud':
- triangles, colors = self._convert_mesh_to_triangles(coordinates)
- renderer.draw_gouraud_triangles(
- gc, triangles, colors, transform.frozen())
- else:
- renderer.draw_quad_mesh(
- gc, transform.frozen(),
- coordinates.shape[1] - 1, coordinates.shape[0] - 1,
- coordinates, offsets, offset_trf,
- # Backends expect flattened rgba arrays (n*m, 4) for fc and ec
- self.get_facecolor().reshape((-1, 4)),
- self._antialiased, self.get_edgecolors().reshape((-1, 4)))
- gc.restore()
- renderer.close_group(self.__class__.__name__)
- self.stale = False
-
- def get_cursor_data(self, event):
- contained, info = self.contains(event)
- if contained and self.get_array() is not None:
- return self.get_array().ravel()[info["ind"]]
- return None
-
-
-class PolyQuadMesh(_MeshData, PolyCollection):
- """
- Class for drawing a quadrilateral mesh as individual Polygons.
-
- A quadrilateral mesh is a grid of M by N adjacent quadrilaterals that are
- defined via a (M+1, N+1) grid of vertices. The quadrilateral (m, n) is
- defined by the vertices ::
-
- (m+1, n) ----------- (m+1, n+1)
- / /
- / /
- / /
- (m, n) -------- (m, n+1)
-
- The mesh need not be regular and the polygons need not be convex.
-
- Parameters
- ----------
- coordinates : (M+1, N+1, 2) array-like
- The vertices. ``coordinates[m, n]`` specifies the (x, y) coordinates
- of vertex (m, n).
-
- Notes
- -----
- Unlike `.QuadMesh`, this class will draw each cell as an individual Polygon.
- This is significantly slower, but allows for more flexibility when wanting
- to add additional properties to the cells, such as hatching.
-
- Another difference from `.QuadMesh` is that if any of the vertices or data
- of a cell are masked, that Polygon will **not** be drawn and it won't be in
- the list of paths returned.
- """
-
- def __init__(self, coordinates, **kwargs):
- # We need to keep track of whether we are using deprecated compression
- # Update it after the initializers
- self._deprecated_compression = False
- super().__init__(coordinates=coordinates)
- PolyCollection.__init__(self, verts=[], **kwargs)
- # Store this during the compression deprecation period
- self._original_mask = ~self._get_unmasked_polys()
- self._deprecated_compression = np.any(self._original_mask)
- # Setting the verts updates the paths of the PolyCollection
- # This is called after the initializers to make sure the kwargs
- # have all been processed and available for the masking calculations
- self._set_unmasked_verts()
-
- def _get_unmasked_polys(self):
- """Get the unmasked regions using the coordinates and array"""
- # mask(X) | mask(Y)
- mask = np.any(np.ma.getmaskarray(self._coordinates), axis=-1)
-
- # We want the shape of the polygon, which is the corner of each X/Y array
- mask = (mask[0:-1, 0:-1] | mask[1:, 1:] | mask[0:-1, 1:] | mask[1:, 0:-1])
-
- if (getattr(self, "_deprecated_compression", False) and
- np.any(self._original_mask)):
- return ~(mask | self._original_mask)
- # Take account of the array data too, temporarily avoiding
- # the compression warning and resetting the variable after the call
- with cbook._setattr_cm(self, _deprecated_compression=False):
- arr = self.get_array()
- if arr is not None:
- arr = np.ma.getmaskarray(arr)
- if arr.ndim == 3:
- # RGB(A) case
- mask |= np.any(arr, axis=-1)
- elif arr.ndim == 2:
- mask |= arr
- else:
- mask |= arr.reshape(self._coordinates[:-1, :-1, :].shape[:2])
- return ~mask
-
- def _set_unmasked_verts(self):
- X = self._coordinates[..., 0]
- Y = self._coordinates[..., 1]
-
- unmask = self._get_unmasked_polys()
- X1 = np.ma.filled(X[:-1, :-1])[unmask]
- Y1 = np.ma.filled(Y[:-1, :-1])[unmask]
- X2 = np.ma.filled(X[1:, :-1])[unmask]
- Y2 = np.ma.filled(Y[1:, :-1])[unmask]
- X3 = np.ma.filled(X[1:, 1:])[unmask]
- Y3 = np.ma.filled(Y[1:, 1:])[unmask]
- X4 = np.ma.filled(X[:-1, 1:])[unmask]
- Y4 = np.ma.filled(Y[:-1, 1:])[unmask]
- npoly = len(X1)
-
- xy = np.ma.stack([X1, Y1, X2, Y2, X3, Y3, X4, Y4, X1, Y1], axis=-1)
- verts = xy.reshape((npoly, 5, 2))
- self.set_verts(verts)
-
- def get_edgecolor(self):
- # docstring inherited
- # We only want to return the facecolors of the polygons
- # that were drawn.
- ec = super().get_edgecolor()
- unmasked_polys = self._get_unmasked_polys().ravel()
- if len(ec) != len(unmasked_polys):
- # Mapping is off
- return ec
- return ec[unmasked_polys, :]
-
- def get_facecolor(self):
- # docstring inherited
- # We only want to return the facecolors of the polygons
- # that were drawn.
- fc = super().get_facecolor()
- unmasked_polys = self._get_unmasked_polys().ravel()
- if len(fc) != len(unmasked_polys):
- # Mapping is off
- return fc
- return fc[unmasked_polys, :]
-
- def set_array(self, A):
- # docstring inherited
- prev_unmask = self._get_unmasked_polys()
- # MPL <3.8 compressed the mask, so we need to handle flattened 1d input
- # until the deprecation expires, also only warning when there are masked
- # elements and thus compression occurring.
- if self._deprecated_compression and np.ndim(A) == 1:
- _api.warn_deprecated("3.8", message="Setting a PolyQuadMesh array using "
- "the compressed values is deprecated. "
- "Pass the full 2D shape of the original array "
- f"{prev_unmask.shape} including the masked elements.")
- Afull = np.empty(self._original_mask.shape)
- Afull[~self._original_mask] = A
- # We also want to update the mask with any potential
- # new masked elements that came in. But, we don't want
- # to update any of the compression from the original
- mask = self._original_mask.copy()
- mask[~self._original_mask] |= np.ma.getmask(A)
- A = np.ma.array(Afull, mask=mask)
- return super().set_array(A)
- self._deprecated_compression = False
- super().set_array(A)
- # If the mask has changed at all we need to update
- # the set of Polys that we are drawing
- if not np.array_equal(prev_unmask, self._get_unmasked_polys()):
- self._set_unmasked_verts()
-
- def get_array(self):
- # docstring inherited
- # Can remove this entire function once the deprecation period ends
- A = super().get_array()
- if A is None:
- return
- if self._deprecated_compression and np.any(np.ma.getmask(A)):
- _api.warn_deprecated("3.8", message=(
- "Getting the array from a PolyQuadMesh will return the full "
- "array in the future (uncompressed). To get this behavior now "
- "set the PolyQuadMesh with a 2D array .set_array(data2d)."))
- # Setting an array of a polycollection required
- # compressing the array
- return np.ma.compressed(A)
- return A
diff --git a/contrib/python/matplotlib/py3/matplotlib/collections.pyi b/contrib/python/matplotlib/py3/matplotlib/collections.pyi
deleted file mode 100644
index 01682a55b3..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/collections.pyi
+++ /dev/null
@@ -1,242 +0,0 @@
-from collections.abc import Callable, Iterable, Sequence
-from typing import Literal
-
-import numpy as np
-from numpy.typing import ArrayLike, NDArray
-
-from . import artist, cm, transforms
-from .backend_bases import MouseEvent
-from .artist import Artist
-from .colors import Normalize, Colormap
-from .lines import Line2D
-from .path import Path
-from .patches import Patch
-from .ticker import Locator, Formatter
-from .tri import Triangulation
-from .typing import ColorType, LineStyleType, CapStyleType, JoinStyleType
-
-class Collection(artist.Artist, cm.ScalarMappable):
- def __init__(
- self,
- *,
- edgecolors: ColorType | Sequence[ColorType] | None = ...,
- facecolors: ColorType | Sequence[ColorType] | None = ...,
- linewidths: float | Sequence[float] | None = ...,
- linestyles: LineStyleType | Sequence[LineStyleType] = ...,
- capstyle: CapStyleType | None = ...,
- joinstyle: JoinStyleType | None = ...,
- antialiaseds: bool | Sequence[bool] | None = ...,
- offsets: tuple[float, float] | Sequence[tuple[float, float]] | None = ...,
- offset_transform: transforms.Transform | None = ...,
- norm: Normalize | None = ...,
- cmap: Colormap | None = ...,
- pickradius: float = ...,
- hatch: str | None = ...,
- urls: Sequence[str] | None = ...,
- zorder: float = ...,
- **kwargs
- ) -> None: ...
- def get_paths(self) -> Sequence[Path]: ...
- def set_paths(self, paths: Sequence[Path]) -> None: ...
- def get_transforms(self) -> Sequence[transforms.Transform]: ...
- def get_offset_transform(self) -> transforms.Transform: ...
- def set_offset_transform(self, offset_transform: transforms.Transform) -> None: ...
- def get_datalim(self, transData: transforms.Transform) -> transforms.Bbox: ...
- def set_pickradius(self, pickradius: float) -> None: ...
- def get_pickradius(self) -> float: ...
- def set_urls(self, urls: Sequence[str | None]) -> None: ...
- def get_urls(self) -> Sequence[str | None]: ...
- def set_hatch(self, hatch: str) -> None: ...
- def get_hatch(self) -> str: ...
- def set_offsets(self, offsets: ArrayLike) -> None: ...
- def get_offsets(self) -> ArrayLike: ...
- def set_linewidth(self, lw: float | Sequence[float]) -> None: ...
- def set_linestyle(self, ls: LineStyleType | Sequence[LineStyleType]) -> None: ...
- def set_capstyle(self, cs: CapStyleType) -> None: ...
- def get_capstyle(self) -> Literal["butt", "projecting", "round"] | None: ...
- def set_joinstyle(self, js: JoinStyleType) -> None: ...
- def get_joinstyle(self) -> Literal["miter", "round", "bevel"] | None: ...
- def set_antialiased(self, aa: bool | Sequence[bool]) -> None: ...
- def get_antialiased(self) -> NDArray[np.bool_]: ...
- def set_color(self, c: ColorType | Sequence[ColorType]) -> None: ...
- def set_facecolor(self, c: ColorType | Sequence[ColorType]) -> None: ...
- def get_facecolor(self) -> ColorType | Sequence[ColorType]: ...
- def get_edgecolor(self) -> ColorType | Sequence[ColorType]: ...
- def set_edgecolor(self, c: ColorType | Sequence[ColorType]) -> None: ...
- def set_alpha(self, alpha: float | Sequence[float] | None) -> None: ...
- def get_linewidth(self) -> float | Sequence[float]: ...
- def get_linestyle(self) -> LineStyleType | Sequence[LineStyleType]: ...
- def update_scalarmappable(self) -> None: ...
- def get_fill(self) -> bool: ...
- def update_from(self, other: Artist) -> None: ...
-
-class _CollectionWithSizes(Collection):
- def get_sizes(self) -> np.ndarray: ...
- def set_sizes(self, sizes: ArrayLike | None, dpi: float = ...) -> None: ...
-
-class PathCollection(_CollectionWithSizes):
- def __init__(
- self, paths: Sequence[Path], sizes: ArrayLike | None = ..., **kwargs
- ) -> None: ...
- def set_paths(self, paths: Sequence[Path]) -> None: ...
- def get_paths(self) -> Sequence[Path]: ...
- def legend_elements(
- self,
- prop: Literal["colors", "sizes"] = ...,
- num: int | Literal["auto"] | ArrayLike | Locator = ...,
- fmt: str | Formatter | None = ...,
- func: Callable[[ArrayLike], ArrayLike] = ...,
- **kwargs,
- ) -> tuple[list[Line2D], list[str]]: ...
-
-class PolyCollection(_CollectionWithSizes):
- def __init__(
- self,
- verts: Sequence[ArrayLike],
- sizes: ArrayLike | None = ...,
- *,
- closed: bool = ...,
- **kwargs
- ) -> None: ...
- def set_verts(
- self, verts: Sequence[ArrayLike | Path], closed: bool = ...
- ) -> None: ...
- def set_paths(self, verts: Sequence[Path], closed: bool = ...) -> None: ...
- def set_verts_and_codes(
- self, verts: Sequence[ArrayLike | Path], codes: Sequence[int]
- ) -> None: ...
-
-class BrokenBarHCollection(PolyCollection):
- def __init__(
- self,
- xranges: Iterable[tuple[float, float]],
- yrange: tuple[float, float],
- **kwargs
- ) -> None: ...
- @classmethod
- def span_where(
- cls, x: ArrayLike, ymin: float, ymax: float, where: ArrayLike, **kwargs
- ) -> BrokenBarHCollection: ...
-
-class RegularPolyCollection(_CollectionWithSizes):
- def __init__(
- self, numsides: int, *, rotation: float = ..., sizes: ArrayLike = ..., **kwargs
- ) -> None: ...
- def get_numsides(self) -> int: ...
- def get_rotation(self) -> float: ...
-
-class StarPolygonCollection(RegularPolyCollection): ...
-class AsteriskPolygonCollection(RegularPolyCollection): ...
-
-class LineCollection(Collection):
- def __init__(
- self, segments: Sequence[ArrayLike], *, zorder: float = ..., **kwargs
- ) -> None: ...
- def set_segments(self, segments: Sequence[ArrayLike] | None) -> None: ...
- def set_verts(self, segments: Sequence[ArrayLike] | None) -> None: ...
- def set_paths(self, segments: Sequence[ArrayLike] | None) -> None: ... # type: ignore[override]
- def get_segments(self) -> list[np.ndarray]: ...
- def set_color(self, c: ColorType | Sequence[ColorType]) -> None: ...
- def set_colors(self, c: ColorType | Sequence[ColorType]) -> None: ...
- def set_gapcolor(self, gapcolor: ColorType | Sequence[ColorType] | None) -> None: ...
- def get_color(self) -> ColorType | Sequence[ColorType]: ...
- def get_colors(self) -> ColorType | Sequence[ColorType]: ...
- def get_gapcolor(self) -> ColorType | Sequence[ColorType] | None: ...
-
-
-class EventCollection(LineCollection):
- def __init__(
- self,
- positions: ArrayLike,
- orientation: Literal["horizontal", "vertical"] = ...,
- *,
- lineoffset: float = ...,
- linelength: float = ...,
- linewidth: float | Sequence[float] | None = ...,
- color: ColorType | Sequence[ColorType] | None = ...,
- linestyle: LineStyleType | Sequence[LineStyleType] = ...,
- antialiased: bool | Sequence[bool] | None = ...,
- **kwargs
- ) -> None: ...
- def get_positions(self) -> list[float]: ...
- def set_positions(self, positions: Sequence[float] | None) -> None: ...
- def add_positions(self, position: Sequence[float] | None) -> None: ...
- def extend_positions(self, position: Sequence[float] | None) -> None: ...
- def append_positions(self, position: Sequence[float] | None) -> None: ...
- def is_horizontal(self) -> bool: ...
- def get_orientation(self) -> Literal["horizontal", "vertical"]: ...
- def switch_orientation(self) -> None: ...
- def set_orientation(
- self, orientation: Literal["horizontal", "vertical"]
- ) -> None: ...
- def get_linelength(self) -> float | Sequence[float]: ...
- def set_linelength(self, linelength: float | Sequence[float]) -> None: ...
- def get_lineoffset(self) -> float: ...
- def set_lineoffset(self, lineoffset: float) -> None: ...
- def get_linewidth(self) -> float: ...
- def get_linewidths(self) -> Sequence[float]: ...
- def get_color(self) -> ColorType: ...
-
-class CircleCollection(_CollectionWithSizes):
- def __init__(self, sizes: float | ArrayLike, **kwargs) -> None: ...
-
-class EllipseCollection(Collection):
- def __init__(
- self,
- widths: ArrayLike,
- heights: ArrayLike,
- angles: ArrayLike,
- *,
- units: Literal[
- "points", "inches", "dots", "width", "height", "x", "y", "xy"
- ] = ...,
- **kwargs
- ) -> None: ...
-
-class PatchCollection(Collection):
- def __init__(
- self, patches: Iterable[Patch], *, match_original: bool = ..., **kwargs
- ) -> None: ...
- def set_paths(self, patches: Iterable[Patch]) -> None: ... # type: ignore[override]
-
-class TriMesh(Collection):
- def __init__(self, triangulation: Triangulation, **kwargs) -> None: ...
- def get_paths(self) -> list[Path]: ...
- # Parent class has an argument, perhaps add a noop arg?
- def set_paths(self) -> None: ... # type: ignore[override]
- @staticmethod
- def convert_mesh_to_paths(tri: Triangulation) -> list[Path]: ...
-
-class _MeshData:
- def __init__(
- self,
- coordinates: ArrayLike,
- *,
- shading: Literal["flat", "gouraud"] = ...,
- ) -> None: ...
- def set_array(self, A: ArrayLike | None) -> None: ...
- def get_coordinates(self) -> ArrayLike: ...
- def get_facecolor(self) -> ColorType | Sequence[ColorType]: ...
- def get_edgecolor(self) -> ColorType | Sequence[ColorType]: ...
-
-class QuadMesh(_MeshData, Collection):
- def __init__(
- self,
- coordinates: ArrayLike,
- *,
- antialiased: bool = ...,
- shading: Literal["flat", "gouraud"] = ...,
- **kwargs
- ) -> None: ...
- def get_paths(self) -> list[Path]: ...
- # Parent class has an argument, perhaps add a noop arg?
- def set_paths(self) -> None: ... # type: ignore[override]
- def get_datalim(self, transData: transforms.Transform) -> transforms.Bbox: ...
- def get_cursor_data(self, event: MouseEvent) -> float: ...
-
-class PolyQuadMesh(_MeshData, PolyCollection):
- def __init__(
- self,
- coordinates: ArrayLike,
- **kwargs
- ) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/colorbar.py b/contrib/python/matplotlib/py3/matplotlib/colorbar.py
deleted file mode 100644
index 6c92f37953..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/colorbar.py
+++ /dev/null
@@ -1,1580 +0,0 @@
-"""
-Colorbars are a visualization of the mapping from scalar values to colors.
-In Matplotlib they are drawn into a dedicated `~.axes.Axes`.
-
-.. note::
- Colorbars are typically created through `.Figure.colorbar` or its pyplot
- wrapper `.pyplot.colorbar`, which internally use `.Colorbar` together with
- `.make_axes_gridspec` (for `.GridSpec`-positioned axes) or `.make_axes` (for
- non-`.GridSpec`-positioned axes).
-
- End-users most likely won't need to directly use this module's API.
-"""
-
-import logging
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, cbook, collections, cm, colors, contour, ticker
-import matplotlib.artist as martist
-import matplotlib.patches as mpatches
-import matplotlib.path as mpath
-import matplotlib.spines as mspines
-import matplotlib.transforms as mtransforms
-from matplotlib import _docstring
-
-_log = logging.getLogger(__name__)
-
-_docstring.interpd.update(
- _make_axes_kw_doc="""
-location : None or {'left', 'right', 'top', 'bottom'}
- The location, relative to the parent axes, where the colorbar axes
- is created. It also determines the *orientation* of the colorbar
- (colorbars on the left and right are vertical, colorbars at the top
- and bottom are horizontal). If None, the location will come from the
- *orientation* if it is set (vertical colorbars on the right, horizontal
- ones at the bottom), or default to 'right' if *orientation* is unset.
-
-orientation : None or {'vertical', 'horizontal'}
- The orientation of the colorbar. It is preferable to set the *location*
- of the colorbar, as that also determines the *orientation*; passing
- incompatible values for *location* and *orientation* raises an exception.
-
-fraction : float, default: 0.15
- Fraction of original axes to use for colorbar.
-
-shrink : float, default: 1.0
- Fraction by which to multiply the size of the colorbar.
-
-aspect : float, default: 20
- Ratio of long to short dimensions.
-
-pad : float, default: 0.05 if vertical, 0.15 if horizontal
- Fraction of original axes between colorbar and new image axes.
-
-anchor : (float, float), optional
- The anchor point of the colorbar axes.
- Defaults to (0.0, 0.5) if vertical; (0.5, 1.0) if horizontal.
-
-panchor : (float, float), or *False*, optional
- The anchor point of the colorbar parent axes. If *False*, the parent
- axes' anchor will be unchanged.
- Defaults to (1.0, 0.5) if vertical; (0.5, 0.0) if horizontal.""",
- _colormap_kw_doc="""
-extend : {'neither', 'both', 'min', 'max'}
- Make pointed end(s) for out-of-range values (unless 'neither'). These are
- set for a given colormap using the colormap set_under and set_over methods.
-
-extendfrac : {*None*, 'auto', length, lengths}
- If set to *None*, both the minimum and maximum triangular colorbar
- extensions will have a length of 5% of the interior colorbar length (this
- is the default setting).
-
- If set to 'auto', makes the triangular colorbar extensions the same lengths
- as the interior boxes (when *spacing* is set to 'uniform') or the same
- lengths as the respective adjacent interior boxes (when *spacing* is set to
- 'proportional').
-
- If a scalar, indicates the length of both the minimum and maximum
- triangular colorbar extensions as a fraction of the interior colorbar
- length. A two-element sequence of fractions may also be given, indicating
- the lengths of the minimum and maximum colorbar extensions respectively as
- a fraction of the interior colorbar length.
-
-extendrect : bool
- If *False* the minimum and maximum colorbar extensions will be triangular
- (the default). If *True* the extensions will be rectangular.
-
-spacing : {'uniform', 'proportional'}
- For discrete colorbars (`.BoundaryNorm` or contours), 'uniform' gives each
- color the same space; 'proportional' makes the space proportional to the
- data interval.
-
-ticks : None or list of ticks or Locator
- If None, ticks are determined automatically from the input.
-
-format : None or str or Formatter
- If None, `~.ticker.ScalarFormatter` is used.
- Format strings, e.g., ``"%4.2e"`` or ``"{x:.2e}"``, are supported.
- An alternative `~.ticker.Formatter` may be given instead.
-
-drawedges : bool
- Whether to draw lines at color boundaries.
-
-label : str
- The label on the colorbar's long axis.
-
-boundaries, values : None or a sequence
- If unset, the colormap will be displayed on a 0-1 scale.
- If sequences, *values* must have a length 1 less than *boundaries*. For
- each region delimited by adjacent entries in *boundaries*, the color mapped
- to the corresponding value in values will be used.
- Normally only useful for indexed colors (i.e. ``norm=NoNorm()``) or other
- unusual circumstances.""")
-
-
-def _set_ticks_on_axis_warn(*args, **kwargs):
- # a top level function which gets put in at the axes'
- # set_xticks and set_yticks by Colorbar.__init__.
- _api.warn_external("Use the colorbar set_ticks() method instead.")
-
-
-class _ColorbarSpine(mspines.Spine):
- def __init__(self, axes):
- self._ax = axes
- super().__init__(axes, 'colorbar', mpath.Path(np.empty((0, 2))))
- mpatches.Patch.set_transform(self, axes.transAxes)
-
- def get_window_extent(self, renderer=None):
- # This Spine has no Axis associated with it, and doesn't need to adjust
- # its location, so we can directly get the window extent from the
- # super-super-class.
- return mpatches.Patch.get_window_extent(self, renderer=renderer)
-
- def set_xy(self, xy):
- self._path = mpath.Path(xy, closed=True)
- self._xy = xy
- self.stale = True
-
- def draw(self, renderer):
- ret = mpatches.Patch.draw(self, renderer)
- self.stale = False
- return ret
-
-
-class _ColorbarAxesLocator:
- """
- Shrink the axes if there are triangular or rectangular extends.
- """
- def __init__(self, cbar):
- self._cbar = cbar
- self._orig_locator = cbar.ax._axes_locator
-
- def __call__(self, ax, renderer):
- if self._orig_locator is not None:
- pos = self._orig_locator(ax, renderer)
- else:
- pos = ax.get_position(original=True)
- if self._cbar.extend == 'neither':
- return pos
-
- y, extendlen = self._cbar._proportional_y()
- if not self._cbar._extend_lower():
- extendlen[0] = 0
- if not self._cbar._extend_upper():
- extendlen[1] = 0
- len = sum(extendlen) + 1
- shrink = 1 / len
- offset = extendlen[0] / len
- # we need to reset the aspect ratio of the axes to account
- # of the extends...
- if hasattr(ax, '_colorbar_info'):
- aspect = ax._colorbar_info['aspect']
- else:
- aspect = False
- # now shrink and/or offset to take into account the
- # extend tri/rectangles.
- if self._cbar.orientation == 'vertical':
- if aspect:
- self._cbar.ax.set_box_aspect(aspect*shrink)
- pos = pos.shrunk(1, shrink).translated(0, offset * pos.height)
- else:
- if aspect:
- self._cbar.ax.set_box_aspect(1/(aspect * shrink))
- pos = pos.shrunk(shrink, 1).translated(offset * pos.width, 0)
- return pos
-
- def get_subplotspec(self):
- # make tight_layout happy..
- return (
- self._cbar.ax.get_subplotspec()
- or getattr(self._orig_locator, "get_subplotspec", lambda: None)())
-
-
-@_docstring.interpd
-class Colorbar:
- r"""
- Draw a colorbar in an existing axes.
-
- Typically, colorbars are created using `.Figure.colorbar` or
- `.pyplot.colorbar` and associated with `.ScalarMappable`\s (such as an
- `.AxesImage` generated via `~.axes.Axes.imshow`).
-
- In order to draw a colorbar not associated with other elements in the
- figure, e.g. when showing a colormap by itself, one can create an empty
- `.ScalarMappable`, or directly pass *cmap* and *norm* instead of *mappable*
- to `Colorbar`.
-
- Useful public methods are :meth:`set_label` and :meth:`add_lines`.
-
- Attributes
- ----------
- ax : `~matplotlib.axes.Axes`
- The `~.axes.Axes` instance in which the colorbar is drawn.
- lines : list
- A list of `.LineCollection` (empty if no lines were drawn).
- dividers : `.LineCollection`
- A LineCollection (empty if *drawedges* is ``False``).
-
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The `~.axes.Axes` instance in which the colorbar is drawn.
-
- mappable : `.ScalarMappable`
- The mappable whose colormap and norm will be used.
-
- To show the under- and over- value colors, the mappable's norm should
- be specified as ::
-
- norm = colors.Normalize(clip=False)
-
- To show the colors versus index instead of on a 0-1 scale, use::
-
- norm=colors.NoNorm()
-
- cmap : `~matplotlib.colors.Colormap`, default: :rc:`image.cmap`
- The colormap to use. This parameter is ignored, unless *mappable* is
- None.
-
- norm : `~matplotlib.colors.Normalize`
- The normalization to use. This parameter is ignored, unless *mappable*
- is None.
-
- alpha : float
- The colorbar transparency between 0 (transparent) and 1 (opaque).
-
- orientation : None or {'vertical', 'horizontal'}
- If None, use the value determined by *location*. If both
- *orientation* and *location* are None then defaults to 'vertical'.
-
- ticklocation : {'auto', 'left', 'right', 'top', 'bottom'}
- The location of the colorbar ticks. The *ticklocation* must match
- *orientation*. For example, a horizontal colorbar can only have ticks
- at the top or the bottom. If 'auto', the ticks will be the same as
- *location*, so a colorbar to the left will have ticks to the left. If
- *location* is None, the ticks will be at the bottom for a horizontal
- colorbar and at the right for a vertical.
-
- drawedges : bool
- Whether to draw lines at color boundaries.
-
-
- %(_colormap_kw_doc)s
-
- location : None or {'left', 'right', 'top', 'bottom'}
- Set the *orientation* and *ticklocation* of the colorbar using a
- single argument. Colorbars on the left and right are vertical,
- colorbars at the top and bottom are horizontal. The *ticklocation* is
- the same as *location*, so if *location* is 'top', the ticks are on
- the top. *orientation* and/or *ticklocation* can be provided as well
- and overrides the value set by *location*, but there will be an error
- for incompatible combinations.
-
- .. versionadded:: 3.7
- """
-
- n_rasterize = 50 # rasterize solids if number of colors >= n_rasterize
-
- def __init__(self, ax, mappable=None, *, cmap=None,
- norm=None,
- alpha=None,
- values=None,
- boundaries=None,
- orientation=None,
- ticklocation='auto',
- extend=None,
- spacing='uniform', # uniform or proportional
- ticks=None,
- format=None,
- drawedges=False,
- extendfrac=None,
- extendrect=False,
- label='',
- location=None,
- ):
-
- if mappable is None:
- mappable = cm.ScalarMappable(norm=norm, cmap=cmap)
-
- self.mappable = mappable
- cmap = mappable.cmap
- norm = mappable.norm
-
- filled = True
- if isinstance(mappable, contour.ContourSet):
- cs = mappable
- alpha = cs.get_alpha()
- boundaries = cs._levels
- values = cs.cvalues
- extend = cs.extend
- filled = cs.filled
- if ticks is None:
- ticks = ticker.FixedLocator(cs.levels, nbins=10)
- elif isinstance(mappable, martist.Artist):
- alpha = mappable.get_alpha()
-
- mappable.colorbar = self
- mappable.colorbar_cid = mappable.callbacks.connect(
- 'changed', self.update_normal)
-
- location_orientation = _get_orientation_from_location(location)
-
- _api.check_in_list(
- [None, 'vertical', 'horizontal'], orientation=orientation)
- _api.check_in_list(
- ['auto', 'left', 'right', 'top', 'bottom'],
- ticklocation=ticklocation)
- _api.check_in_list(
- ['uniform', 'proportional'], spacing=spacing)
-
- if location_orientation is not None and orientation is not None:
- if location_orientation != orientation:
- raise TypeError(
- "location and orientation are mutually exclusive")
- else:
- orientation = orientation or location_orientation or "vertical"
-
- self.ax = ax
- self.ax._axes_locator = _ColorbarAxesLocator(self)
-
- if extend is None:
- if (not isinstance(mappable, contour.ContourSet)
- and getattr(cmap, 'colorbar_extend', False) is not False):
- extend = cmap.colorbar_extend
- elif hasattr(norm, 'extend'):
- extend = norm.extend
- else:
- extend = 'neither'
- self.alpha = None
- # Call set_alpha to handle array-like alphas properly
- self.set_alpha(alpha)
- self.cmap = cmap
- self.norm = norm
- self.values = values
- self.boundaries = boundaries
- self.extend = extend
- self._inside = _api.check_getitem(
- {'neither': slice(0, None), 'both': slice(1, -1),
- 'min': slice(1, None), 'max': slice(0, -1)},
- extend=extend)
- self.spacing = spacing
- self.orientation = orientation
- self.drawedges = drawedges
- self._filled = filled
- self.extendfrac = extendfrac
- self.extendrect = extendrect
- self._extend_patches = []
- self.solids = None
- self.solids_patches = []
- self.lines = []
-
- for spine in self.ax.spines.values():
- spine.set_visible(False)
- self.outline = self.ax.spines['outline'] = _ColorbarSpine(self.ax)
-
- self.dividers = collections.LineCollection(
- [],
- colors=[mpl.rcParams['axes.edgecolor']],
- linewidths=[0.5 * mpl.rcParams['axes.linewidth']],
- clip_on=False)
- self.ax.add_collection(self.dividers)
-
- self._locator = None
- self._minorlocator = None
- self._formatter = None
- self._minorformatter = None
-
- if ticklocation == 'auto':
- ticklocation = _get_ticklocation_from_orientation(
- orientation) if location is None else location
- self.ticklocation = ticklocation
-
- self.set_label(label)
- self._reset_locator_formatter_scale()
-
- if np.iterable(ticks):
- self._locator = ticker.FixedLocator(ticks, nbins=len(ticks))
- else:
- self._locator = ticks
-
- if isinstance(format, str):
- # Check format between FormatStrFormatter and StrMethodFormatter
- try:
- self._formatter = ticker.FormatStrFormatter(format)
- _ = self._formatter(0)
- except (TypeError, ValueError):
- self._formatter = ticker.StrMethodFormatter(format)
- else:
- self._formatter = format # Assume it is a Formatter or None
- self._draw_all()
-
- if isinstance(mappable, contour.ContourSet) and not mappable.filled:
- self.add_lines(mappable)
-
- # Link the Axes and Colorbar for interactive use
- self.ax._colorbar = self
- # Don't navigate on any of these types of mappables
- if (isinstance(self.norm, (colors.BoundaryNorm, colors.NoNorm)) or
- isinstance(self.mappable, contour.ContourSet)):
- self.ax.set_navigate(False)
-
- # These are the functions that set up interactivity on this colorbar
- self._interactive_funcs = ["_get_view", "_set_view",
- "_set_view_from_bbox", "drag_pan"]
- for x in self._interactive_funcs:
- setattr(self.ax, x, getattr(self, x))
- # Set the cla function to the cbar's method to override it
- self.ax.cla = self._cbar_cla
- # Callbacks for the extend calculations to handle inverting the axis
- self._extend_cid1 = self.ax.callbacks.connect(
- "xlim_changed", self._do_extends)
- self._extend_cid2 = self.ax.callbacks.connect(
- "ylim_changed", self._do_extends)
-
- @property
- def locator(self):
- """Major tick `.Locator` for the colorbar."""
- return self._long_axis().get_major_locator()
-
- @locator.setter
- def locator(self, loc):
- self._long_axis().set_major_locator(loc)
- self._locator = loc
-
- @property
- def minorlocator(self):
- """Minor tick `.Locator` for the colorbar."""
- return self._long_axis().get_minor_locator()
-
- @minorlocator.setter
- def minorlocator(self, loc):
- self._long_axis().set_minor_locator(loc)
- self._minorlocator = loc
-
- @property
- def formatter(self):
- """Major tick label `.Formatter` for the colorbar."""
- return self._long_axis().get_major_formatter()
-
- @formatter.setter
- def formatter(self, fmt):
- self._long_axis().set_major_formatter(fmt)
- self._formatter = fmt
-
- @property
- def minorformatter(self):
- """Minor tick `.Formatter` for the colorbar."""
- return self._long_axis().get_minor_formatter()
-
- @minorformatter.setter
- def minorformatter(self, fmt):
- self._long_axis().set_minor_formatter(fmt)
- self._minorformatter = fmt
-
- def _cbar_cla(self):
- """Function to clear the interactive colorbar state."""
- for x in self._interactive_funcs:
- delattr(self.ax, x)
- # We now restore the old cla() back and can call it directly
- del self.ax.cla
- self.ax.cla()
-
- def update_normal(self, mappable):
- """
- Update solid patches, lines, etc.
-
- This is meant to be called when the norm of the image or contour plot
- to which this colorbar belongs changes.
-
- If the norm on the mappable is different than before, this resets the
- locator and formatter for the axis, so if these have been customized,
- they will need to be customized again. However, if the norm only
- changes values of *vmin*, *vmax* or *cmap* then the old formatter
- and locator will be preserved.
- """
- _log.debug('colorbar update normal %r %r', mappable.norm, self.norm)
- self.mappable = mappable
- self.set_alpha(mappable.get_alpha())
- self.cmap = mappable.cmap
- if mappable.norm != self.norm:
- self.norm = mappable.norm
- self._reset_locator_formatter_scale()
-
- self._draw_all()
- if isinstance(self.mappable, contour.ContourSet):
- CS = self.mappable
- if not CS.filled:
- self.add_lines(CS)
- self.stale = True
-
- def _draw_all(self):
- """
- Calculate any free parameters based on the current cmap and norm,
- and do all the drawing.
- """
- if self.orientation == 'vertical':
- if mpl.rcParams['ytick.minor.visible']:
- self.minorticks_on()
- else:
- if mpl.rcParams['xtick.minor.visible']:
- self.minorticks_on()
- self._long_axis().set(label_position=self.ticklocation,
- ticks_position=self.ticklocation)
- self._short_axis().set_ticks([])
- self._short_axis().set_ticks([], minor=True)
-
- # Set self._boundaries and self._values, including extensions.
- # self._boundaries are the edges of each square of color, and
- # self._values are the value to map into the norm to get the
- # color:
- self._process_values()
- # Set self.vmin and self.vmax to first and last boundary, excluding
- # extensions:
- self.vmin, self.vmax = self._boundaries[self._inside][[0, -1]]
- # Compute the X/Y mesh.
- X, Y = self._mesh()
- # draw the extend triangles, and shrink the inner axes to accommodate.
- # also adds the outline path to self.outline spine:
- self._do_extends()
- lower, upper = self.vmin, self.vmax
- if self._long_axis().get_inverted():
- # If the axis is inverted, we need to swap the vmin/vmax
- lower, upper = upper, lower
- if self.orientation == 'vertical':
- self.ax.set_xlim(0, 1)
- self.ax.set_ylim(lower, upper)
- else:
- self.ax.set_ylim(0, 1)
- self.ax.set_xlim(lower, upper)
-
- # set up the tick locators and formatters. A bit complicated because
- # boundary norms + uniform spacing requires a manual locator.
- self.update_ticks()
-
- if self._filled:
- ind = np.arange(len(self._values))
- if self._extend_lower():
- ind = ind[1:]
- if self._extend_upper():
- ind = ind[:-1]
- self._add_solids(X, Y, self._values[ind, np.newaxis])
-
- def _add_solids(self, X, Y, C):
- """Draw the colors; optionally add separators."""
- # Cleanup previously set artists.
- if self.solids is not None:
- self.solids.remove()
- for solid in self.solids_patches:
- solid.remove()
- # Add new artist(s), based on mappable type. Use individual patches if
- # hatching is needed, pcolormesh otherwise.
- mappable = getattr(self, 'mappable', None)
- if (isinstance(mappable, contour.ContourSet)
- and any(hatch is not None for hatch in mappable.hatches)):
- self._add_solids_patches(X, Y, C, mappable)
- else:
- self.solids = self.ax.pcolormesh(
- X, Y, C, cmap=self.cmap, norm=self.norm, alpha=self.alpha,
- edgecolors='none', shading='flat')
- if not self.drawedges:
- if len(self._y) >= self.n_rasterize:
- self.solids.set_rasterized(True)
- self._update_dividers()
-
- def _update_dividers(self):
- if not self.drawedges:
- self.dividers.set_segments([])
- return
- # Place all *internal* dividers.
- if self.orientation == 'vertical':
- lims = self.ax.get_ylim()
- bounds = (lims[0] < self._y) & (self._y < lims[1])
- else:
- lims = self.ax.get_xlim()
- bounds = (lims[0] < self._y) & (self._y < lims[1])
- y = self._y[bounds]
- # And then add outer dividers if extensions are on.
- if self._extend_lower():
- y = np.insert(y, 0, lims[0])
- if self._extend_upper():
- y = np.append(y, lims[1])
- X, Y = np.meshgrid([0, 1], y)
- if self.orientation == 'vertical':
- segments = np.dstack([X, Y])
- else:
- segments = np.dstack([Y, X])
- self.dividers.set_segments(segments)
-
- def _add_solids_patches(self, X, Y, C, mappable):
- hatches = mappable.hatches * (len(C) + 1) # Have enough hatches.
- if self._extend_lower():
- # remove first hatch that goes into the extend patch
- hatches = hatches[1:]
- patches = []
- for i in range(len(X) - 1):
- xy = np.array([[X[i, 0], Y[i, 1]],
- [X[i, 1], Y[i, 0]],
- [X[i + 1, 1], Y[i + 1, 0]],
- [X[i + 1, 0], Y[i + 1, 1]]])
- patch = mpatches.PathPatch(mpath.Path(xy),
- facecolor=self.cmap(self.norm(C[i][0])),
- hatch=hatches[i], linewidth=0,
- antialiased=False, alpha=self.alpha)
- self.ax.add_patch(patch)
- patches.append(patch)
- self.solids_patches = patches
-
- def _do_extends(self, ax=None):
- """
- Add the extend tri/rectangles on the outside of the axes.
-
- ax is unused, but required due to the callbacks on xlim/ylim changed
- """
- # Clean up any previous extend patches
- for patch in self._extend_patches:
- patch.remove()
- self._extend_patches = []
- # extend lengths are fraction of the *inner* part of colorbar,
- # not the total colorbar:
- _, extendlen = self._proportional_y()
- bot = 0 - (extendlen[0] if self._extend_lower() else 0)
- top = 1 + (extendlen[1] if self._extend_upper() else 0)
-
- # xyout is the outline of the colorbar including the extend patches:
- if not self.extendrect:
- # triangle:
- xyout = np.array([[0, 0], [0.5, bot], [1, 0],
- [1, 1], [0.5, top], [0, 1], [0, 0]])
- else:
- # rectangle:
- xyout = np.array([[0, 0], [0, bot], [1, bot], [1, 0],
- [1, 1], [1, top], [0, top], [0, 1],
- [0, 0]])
-
- if self.orientation == 'horizontal':
- xyout = xyout[:, ::-1]
-
- # xyout is the path for the spine:
- self.outline.set_xy(xyout)
- if not self._filled:
- return
-
- # Make extend triangles or rectangles filled patches. These are
- # defined in the outer parent axes' coordinates:
- mappable = getattr(self, 'mappable', None)
- if (isinstance(mappable, contour.ContourSet)
- and any(hatch is not None for hatch in mappable.hatches)):
- hatches = mappable.hatches * (len(self._y) + 1)
- else:
- hatches = [None] * (len(self._y) + 1)
-
- if self._extend_lower():
- if not self.extendrect:
- # triangle
- xy = np.array([[0, 0], [0.5, bot], [1, 0]])
- else:
- # rectangle
- xy = np.array([[0, 0], [0, bot], [1., bot], [1, 0]])
- if self.orientation == 'horizontal':
- xy = xy[:, ::-1]
- # add the patch
- val = -1 if self._long_axis().get_inverted() else 0
- color = self.cmap(self.norm(self._values[val]))
- patch = mpatches.PathPatch(
- mpath.Path(xy), facecolor=color, alpha=self.alpha,
- linewidth=0, antialiased=False,
- transform=self.ax.transAxes,
- hatch=hatches[0], clip_on=False,
- # Place it right behind the standard patches, which is
- # needed if we updated the extends
- zorder=np.nextafter(self.ax.patch.zorder, -np.inf))
- self.ax.add_patch(patch)
- self._extend_patches.append(patch)
- # remove first hatch that goes into the extend patch
- hatches = hatches[1:]
- if self._extend_upper():
- if not self.extendrect:
- # triangle
- xy = np.array([[0, 1], [0.5, top], [1, 1]])
- else:
- # rectangle
- xy = np.array([[0, 1], [0, top], [1, top], [1, 1]])
- if self.orientation == 'horizontal':
- xy = xy[:, ::-1]
- # add the patch
- val = 0 if self._long_axis().get_inverted() else -1
- color = self.cmap(self.norm(self._values[val]))
- hatch_idx = len(self._y) - 1
- patch = mpatches.PathPatch(
- mpath.Path(xy), facecolor=color, alpha=self.alpha,
- linewidth=0, antialiased=False,
- transform=self.ax.transAxes, hatch=hatches[hatch_idx],
- clip_on=False,
- # Place it right behind the standard patches, which is
- # needed if we updated the extends
- zorder=np.nextafter(self.ax.patch.zorder, -np.inf))
- self.ax.add_patch(patch)
- self._extend_patches.append(patch)
-
- self._update_dividers()
-
- def add_lines(self, *args, **kwargs):
- """
- Draw lines on the colorbar.
-
- The lines are appended to the list :attr:`lines`.
-
- Parameters
- ----------
- levels : array-like
- The positions of the lines.
- colors : color or list of colors
- Either a single color applying to all lines or one color value for
- each line.
- linewidths : float or array-like
- Either a single linewidth applying to all lines or one linewidth
- for each line.
- erase : bool, default: True
- Whether to remove any previously added lines.
-
- Notes
- -----
- Alternatively, this method can also be called with the signature
- ``colorbar.add_lines(contour_set, erase=True)``, in which case
- *levels*, *colors*, and *linewidths* are taken from *contour_set*.
- """
- params = _api.select_matching_signature(
- [lambda self, CS, erase=True: locals(),
- lambda self, levels, colors, linewidths, erase=True: locals()],
- self, *args, **kwargs)
- if "CS" in params:
- self, cs, erase = params.values()
- if not isinstance(cs, contour.ContourSet) or cs.filled:
- raise ValueError("If a single artist is passed to add_lines, "
- "it must be a ContourSet of lines")
- # TODO: Make colorbar lines auto-follow changes in contour lines.
- return self.add_lines(
- cs.levels,
- cs.to_rgba(cs.cvalues, cs.alpha),
- cs.get_linewidths(),
- erase=erase)
- else:
- self, levels, colors, linewidths, erase = params.values()
-
- y = self._locate(levels)
- rtol = (self._y[-1] - self._y[0]) * 1e-10
- igood = (y < self._y[-1] + rtol) & (y > self._y[0] - rtol)
- y = y[igood]
- if np.iterable(colors):
- colors = np.asarray(colors)[igood]
- if np.iterable(linewidths):
- linewidths = np.asarray(linewidths)[igood]
- X, Y = np.meshgrid([0, 1], y)
- if self.orientation == 'vertical':
- xy = np.stack([X, Y], axis=-1)
- else:
- xy = np.stack([Y, X], axis=-1)
- col = collections.LineCollection(xy, linewidths=linewidths,
- colors=colors)
-
- if erase and self.lines:
- for lc in self.lines:
- lc.remove()
- self.lines = []
- self.lines.append(col)
-
- # make a clip path that is just a linewidth bigger than the axes...
- fac = np.max(linewidths) / 72
- xy = np.array([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]])
- inches = self.ax.get_figure().dpi_scale_trans
- # do in inches:
- xy = inches.inverted().transform(self.ax.transAxes.transform(xy))
- xy[[0, 1, 4], 1] -= fac
- xy[[2, 3], 1] += fac
- # back to axes units...
- xy = self.ax.transAxes.inverted().transform(inches.transform(xy))
- col.set_clip_path(mpath.Path(xy, closed=True),
- self.ax.transAxes)
- self.ax.add_collection(col)
- self.stale = True
-
- def update_ticks(self):
- """
- Set up the ticks and ticklabels. This should not be needed by users.
- """
- # Get the locator and formatter; defaults to self._locator if not None.
- self._get_ticker_locator_formatter()
- self._long_axis().set_major_locator(self._locator)
- self._long_axis().set_minor_locator(self._minorlocator)
- self._long_axis().set_major_formatter(self._formatter)
-
- def _get_ticker_locator_formatter(self):
- """
- Return the ``locator`` and ``formatter`` of the colorbar.
-
- If they have not been defined (i.e. are *None*), the formatter and
- locator are retrieved from the axis, or from the value of the
- boundaries for a boundary norm.
-
- Called by update_ticks...
- """
- locator = self._locator
- formatter = self._formatter
- minorlocator = self._minorlocator
- if isinstance(self.norm, colors.BoundaryNorm):
- b = self.norm.boundaries
- if locator is None:
- locator = ticker.FixedLocator(b, nbins=10)
- if minorlocator is None:
- minorlocator = ticker.FixedLocator(b)
- elif isinstance(self.norm, colors.NoNorm):
- if locator is None:
- # put ticks on integers between the boundaries of NoNorm
- nv = len(self._values)
- base = 1 + int(nv / 10)
- locator = ticker.IndexLocator(base=base, offset=.5)
- elif self.boundaries is not None:
- b = self._boundaries[self._inside]
- if locator is None:
- locator = ticker.FixedLocator(b, nbins=10)
- else: # most cases:
- if locator is None:
- # we haven't set the locator explicitly, so use the default
- # for this axis:
- locator = self._long_axis().get_major_locator()
- if minorlocator is None:
- minorlocator = self._long_axis().get_minor_locator()
-
- if minorlocator is None:
- minorlocator = ticker.NullLocator()
-
- if formatter is None:
- formatter = self._long_axis().get_major_formatter()
-
- self._locator = locator
- self._formatter = formatter
- self._minorlocator = minorlocator
- _log.debug('locator: %r', locator)
-
- def set_ticks(self, ticks, *, labels=None, minor=False, **kwargs):
- """
- Set tick locations.
-
- Parameters
- ----------
- ticks : 1D array-like
- List of tick locations.
- labels : list of str, optional
- List of tick labels. If not set, the labels show the data value.
- minor : bool, default: False
- If ``False``, set the major ticks; if ``True``, the minor ticks.
- **kwargs
- `.Text` properties for the labels. These take effect only if you
- pass *labels*. In other cases, please use `~.Axes.tick_params`.
- """
- if np.iterable(ticks):
- self._long_axis().set_ticks(ticks, labels=labels, minor=minor,
- **kwargs)
- self._locator = self._long_axis().get_major_locator()
- else:
- self._locator = ticks
- self._long_axis().set_major_locator(self._locator)
- self.stale = True
-
- def get_ticks(self, minor=False):
- """
- Return the ticks as a list of locations.
-
- Parameters
- ----------
- minor : boolean, default: False
- if True return the minor ticks.
- """
- if minor:
- return self._long_axis().get_minorticklocs()
- else:
- return self._long_axis().get_majorticklocs()
-
- def set_ticklabels(self, ticklabels, *, minor=False, **kwargs):
- """
- [*Discouraged*] Set tick labels.
-
- .. admonition:: Discouraged
-
- The use of this method is discouraged, because of the dependency
- on tick positions. In most cases, you'll want to use
- ``set_ticks(positions, labels=labels)`` instead.
-
- If you are using this method, you should always fix the tick
- positions before, e.g. by using `.Colorbar.set_ticks` or by
- explicitly setting a `~.ticker.FixedLocator` on the long axis
- of the colorbar. Otherwise, ticks are free to move and the
- labels may end up in unexpected positions.
-
- Parameters
- ----------
- ticklabels : sequence of str or of `.Text`
- Texts for labeling each tick location in the sequence set by
- `.Colorbar.set_ticks`; the number of labels must match the number
- of locations.
-
- update_ticks : bool, default: True
- This keyword argument is ignored and will be removed.
- Deprecated
-
- minor : bool
- If True, set minor ticks instead of major ticks.
-
- **kwargs
- `.Text` properties for the labels.
- """
- self._long_axis().set_ticklabels(ticklabels, minor=minor, **kwargs)
-
- def minorticks_on(self):
- """
- Turn on colorbar minor ticks.
- """
- self.ax.minorticks_on()
- self._short_axis().set_minor_locator(ticker.NullLocator())
-
- def minorticks_off(self):
- """Turn the minor ticks of the colorbar off."""
- self._minorlocator = ticker.NullLocator()
- self._long_axis().set_minor_locator(self._minorlocator)
-
- def set_label(self, label, *, loc=None, **kwargs):
- """
- Add a label to the long axis of the colorbar.
-
- Parameters
- ----------
- label : str
- The label text.
- loc : str, optional
- The location of the label.
-
- - For horizontal orientation one of {'left', 'center', 'right'}
- - For vertical orientation one of {'bottom', 'center', 'top'}
-
- Defaults to :rc:`xaxis.labellocation` or :rc:`yaxis.labellocation`
- depending on the orientation.
- **kwargs
- Keyword arguments are passed to `~.Axes.set_xlabel` /
- `~.Axes.set_ylabel`.
- Supported keywords are *labelpad* and `.Text` properties.
- """
- if self.orientation == "vertical":
- self.ax.set_ylabel(label, loc=loc, **kwargs)
- else:
- self.ax.set_xlabel(label, loc=loc, **kwargs)
- self.stale = True
-
- def set_alpha(self, alpha):
- """
- Set the transparency between 0 (transparent) and 1 (opaque).
-
- If an array is provided, *alpha* will be set to None to use the
- transparency values associated with the colormap.
- """
- self.alpha = None if isinstance(alpha, np.ndarray) else alpha
-
- def _set_scale(self, scale, **kwargs):
- """
- Set the colorbar long axis scale.
-
- Parameters
- ----------
- scale : {"linear", "log", "symlog", "logit", ...} or `.ScaleBase`
- The axis scale type to apply.
-
- **kwargs
- Different keyword arguments are accepted, depending on the scale.
- See the respective class keyword arguments:
-
- - `matplotlib.scale.LinearScale`
- - `matplotlib.scale.LogScale`
- - `matplotlib.scale.SymmetricalLogScale`
- - `matplotlib.scale.LogitScale`
- - `matplotlib.scale.FuncScale`
-
- Notes
- -----
- By default, Matplotlib supports the above-mentioned scales.
- Additionally, custom scales may be registered using
- `matplotlib.scale.register_scale`. These scales can then also
- be used here.
- """
- self._long_axis()._set_axes_scale(scale, **kwargs)
-
- def remove(self):
- """
- Remove this colorbar from the figure.
-
- If the colorbar was created with ``use_gridspec=True`` the previous
- gridspec is restored.
- """
- if hasattr(self.ax, '_colorbar_info'):
- parents = self.ax._colorbar_info['parents']
- for a in parents:
- if self.ax in a._colorbars:
- a._colorbars.remove(self.ax)
-
- self.ax.remove()
-
- self.mappable.callbacks.disconnect(self.mappable.colorbar_cid)
- self.mappable.colorbar = None
- self.mappable.colorbar_cid = None
- # Remove the extension callbacks
- self.ax.callbacks.disconnect(self._extend_cid1)
- self.ax.callbacks.disconnect(self._extend_cid2)
-
- try:
- ax = self.mappable.axes
- except AttributeError:
- return
- try:
- gs = ax.get_subplotspec().get_gridspec()
- subplotspec = gs.get_topmost_subplotspec()
- except AttributeError:
- # use_gridspec was False
- pos = ax.get_position(original=True)
- ax._set_position(pos)
- else:
- # use_gridspec was True
- ax.set_subplotspec(subplotspec)
-
- def _process_values(self):
- """
- Set `_boundaries` and `_values` based on the self.boundaries and
- self.values if not None, or based on the size of the colormap and
- the vmin/vmax of the norm.
- """
- if self.values is not None:
- # set self._boundaries from the values...
- self._values = np.array(self.values)
- if self.boundaries is None:
- # bracket values by 1/2 dv:
- b = np.zeros(len(self.values) + 1)
- b[1:-1] = 0.5 * (self._values[:-1] + self._values[1:])
- b[0] = 2.0 * b[1] - b[2]
- b[-1] = 2.0 * b[-2] - b[-3]
- self._boundaries = b
- return
- self._boundaries = np.array(self.boundaries)
- return
-
- # otherwise values are set from the boundaries
- if isinstance(self.norm, colors.BoundaryNorm):
- b = self.norm.boundaries
- elif isinstance(self.norm, colors.NoNorm):
- # NoNorm has N blocks, so N+1 boundaries, centered on integers:
- b = np.arange(self.cmap.N + 1) - .5
- elif self.boundaries is not None:
- b = self.boundaries
- else:
- # otherwise make the boundaries from the size of the cmap:
- N = self.cmap.N + 1
- b, _ = self._uniform_y(N)
- # add extra boundaries if needed:
- if self._extend_lower():
- b = np.hstack((b[0] - 1, b))
- if self._extend_upper():
- b = np.hstack((b, b[-1] + 1))
-
- # transform from 0-1 to vmin-vmax:
- if self.mappable.get_array() is not None:
- self.mappable.autoscale_None()
- if not self.norm.scaled():
- # If we still aren't scaled after autoscaling, use 0, 1 as default
- self.norm.vmin = 0
- self.norm.vmax = 1
- self.norm.vmin, self.norm.vmax = mtransforms.nonsingular(
- self.norm.vmin, self.norm.vmax, expander=0.1)
- if (not isinstance(self.norm, colors.BoundaryNorm) and
- (self.boundaries is None)):
- b = self.norm.inverse(b)
-
- self._boundaries = np.asarray(b, dtype=float)
- self._values = 0.5 * (self._boundaries[:-1] + self._boundaries[1:])
- if isinstance(self.norm, colors.NoNorm):
- self._values = (self._values + 0.00001).astype(np.int16)
-
- def _mesh(self):
- """
- Return the coordinate arrays for the colorbar pcolormesh/patches.
-
- These are scaled between vmin and vmax, and already handle colorbar
- orientation.
- """
- y, _ = self._proportional_y()
- # Use the vmin and vmax of the colorbar, which may not be the same
- # as the norm. There are situations where the colormap has a
- # narrower range than the colorbar and we want to accommodate the
- # extra contours.
- if (isinstance(self.norm, (colors.BoundaryNorm, colors.NoNorm))
- or self.boundaries is not None):
- # not using a norm.
- y = y * (self.vmax - self.vmin) + self.vmin
- else:
- # Update the norm values in a context manager as it is only
- # a temporary change and we don't want to propagate any signals
- # attached to the norm (callbacks.blocked).
- with self.norm.callbacks.blocked(), \
- cbook._setattr_cm(self.norm,
- vmin=self.vmin,
- vmax=self.vmax):
- y = self.norm.inverse(y)
- self._y = y
- X, Y = np.meshgrid([0., 1.], y)
- if self.orientation == 'vertical':
- return (X, Y)
- else:
- return (Y, X)
-
- def _forward_boundaries(self, x):
- # map boundaries equally between 0 and 1...
- b = self._boundaries
- y = np.interp(x, b, np.linspace(0, 1, len(b)))
- # the following avoids ticks in the extends:
- eps = (b[-1] - b[0]) * 1e-6
- # map these _well_ out of bounds to keep any ticks out
- # of the extends region...
- y[x < b[0]-eps] = -1
- y[x > b[-1]+eps] = 2
- return y
-
- def _inverse_boundaries(self, x):
- # invert the above...
- b = self._boundaries
- return np.interp(x, np.linspace(0, 1, len(b)), b)
-
- def _reset_locator_formatter_scale(self):
- """
- Reset the locator et al to defaults. Any user-hardcoded changes
- need to be re-entered if this gets called (either at init, or when
- the mappable normal gets changed: Colorbar.update_normal)
- """
- self._process_values()
- self._locator = None
- self._minorlocator = None
- self._formatter = None
- self._minorformatter = None
- if (isinstance(self.mappable, contour.ContourSet) and
- isinstance(self.norm, colors.LogNorm)):
- # if contours have lognorm, give them a log scale...
- self._set_scale('log')
- elif (self.boundaries is not None or
- isinstance(self.norm, colors.BoundaryNorm)):
- if self.spacing == 'uniform':
- funcs = (self._forward_boundaries, self._inverse_boundaries)
- self._set_scale('function', functions=funcs)
- elif self.spacing == 'proportional':
- self._set_scale('linear')
- elif getattr(self.norm, '_scale', None):
- # use the norm's scale (if it exists and is not None):
- self._set_scale(self.norm._scale)
- elif type(self.norm) is colors.Normalize:
- # plain Normalize:
- self._set_scale('linear')
- else:
- # norm._scale is None or not an attr: derive the scale from
- # the Norm:
- funcs = (self.norm, self.norm.inverse)
- self._set_scale('function', functions=funcs)
-
- def _locate(self, x):
- """
- Given a set of color data values, return their
- corresponding colorbar data coordinates.
- """
- if isinstance(self.norm, (colors.NoNorm, colors.BoundaryNorm)):
- b = self._boundaries
- xn = x
- else:
- # Do calculations using normalized coordinates so
- # as to make the interpolation more accurate.
- b = self.norm(self._boundaries, clip=False).filled()
- xn = self.norm(x, clip=False).filled()
-
- bunique = b[self._inside]
- yunique = self._y
-
- z = np.interp(xn, bunique, yunique)
- return z
-
- # trivial helpers
-
- def _uniform_y(self, N):
- """
- Return colorbar data coordinates for *N* uniformly
- spaced boundaries, plus extension lengths if required.
- """
- automin = automax = 1. / (N - 1.)
- extendlength = self._get_extension_lengths(self.extendfrac,
- automin, automax,
- default=0.05)
- y = np.linspace(0, 1, N)
- return y, extendlength
-
- def _proportional_y(self):
- """
- Return colorbar data coordinates for the boundaries of
- a proportional colorbar, plus extension lengths if required:
- """
- if (isinstance(self.norm, colors.BoundaryNorm) or
- self.boundaries is not None):
- y = (self._boundaries - self._boundaries[self._inside][0])
- y = y / (self._boundaries[self._inside][-1] -
- self._boundaries[self._inside][0])
- # need yscaled the same as the axes scale to get
- # the extend lengths.
- if self.spacing == 'uniform':
- yscaled = self._forward_boundaries(self._boundaries)
- else:
- yscaled = y
- else:
- y = self.norm(self._boundaries.copy())
- y = np.ma.filled(y, np.nan)
- # the norm and the scale should be the same...
- yscaled = y
- y = y[self._inside]
- yscaled = yscaled[self._inside]
- # normalize from 0..1:
- norm = colors.Normalize(y[0], y[-1])
- y = np.ma.filled(norm(y), np.nan)
- norm = colors.Normalize(yscaled[0], yscaled[-1])
- yscaled = np.ma.filled(norm(yscaled), np.nan)
- # make the lower and upper extend lengths proportional to the lengths
- # of the first and last boundary spacing (if extendfrac='auto'):
- automin = yscaled[1] - yscaled[0]
- automax = yscaled[-1] - yscaled[-2]
- extendlength = [0, 0]
- if self._extend_lower() or self._extend_upper():
- extendlength = self._get_extension_lengths(
- self.extendfrac, automin, automax, default=0.05)
- return y, extendlength
-
- def _get_extension_lengths(self, frac, automin, automax, default=0.05):
- """
- Return the lengths of colorbar extensions.
-
- This is a helper method for _uniform_y and _proportional_y.
- """
- # Set the default value.
- extendlength = np.array([default, default])
- if isinstance(frac, str):
- _api.check_in_list(['auto'], extendfrac=frac.lower())
- # Use the provided values when 'auto' is required.
- extendlength[:] = [automin, automax]
- elif frac is not None:
- try:
- # Try to set min and max extension fractions directly.
- extendlength[:] = frac
- # If frac is a sequence containing None then NaN may
- # be encountered. This is an error.
- if np.isnan(extendlength).any():
- raise ValueError()
- except (TypeError, ValueError) as err:
- # Raise an error on encountering an invalid value for frac.
- raise ValueError('invalid value for extendfrac') from err
- return extendlength
-
- def _extend_lower(self):
- """Return whether the lower limit is open ended."""
- minmax = "max" if self._long_axis().get_inverted() else "min"
- return self.extend in ('both', minmax)
-
- def _extend_upper(self):
- """Return whether the upper limit is open ended."""
- minmax = "min" if self._long_axis().get_inverted() else "max"
- return self.extend in ('both', minmax)
-
- def _long_axis(self):
- """Return the long axis"""
- if self.orientation == 'vertical':
- return self.ax.yaxis
- return self.ax.xaxis
-
- def _short_axis(self):
- """Return the short axis"""
- if self.orientation == 'vertical':
- return self.ax.xaxis
- return self.ax.yaxis
-
- def _get_view(self):
- # docstring inherited
- # An interactive view for a colorbar is the norm's vmin/vmax
- return self.norm.vmin, self.norm.vmax
-
- def _set_view(self, view):
- # docstring inherited
- # An interactive view for a colorbar is the norm's vmin/vmax
- self.norm.vmin, self.norm.vmax = view
-
- def _set_view_from_bbox(self, bbox, direction='in',
- mode=None, twinx=False, twiny=False):
- # docstring inherited
- # For colorbars, we use the zoom bbox to scale the norm's vmin/vmax
- new_xbound, new_ybound = self.ax._prepare_view_from_bbox(
- bbox, direction=direction, mode=mode, twinx=twinx, twiny=twiny)
- if self.orientation == 'horizontal':
- self.norm.vmin, self.norm.vmax = new_xbound
- elif self.orientation == 'vertical':
- self.norm.vmin, self.norm.vmax = new_ybound
-
- def drag_pan(self, button, key, x, y):
- # docstring inherited
- points = self.ax._get_pan_points(button, key, x, y)
- if points is not None:
- if self.orientation == 'horizontal':
- self.norm.vmin, self.norm.vmax = points[:, 0]
- elif self.orientation == 'vertical':
- self.norm.vmin, self.norm.vmax = points[:, 1]
-
-
-ColorbarBase = Colorbar # Backcompat API
-
-
-def _normalize_location_orientation(location, orientation):
- if location is None:
- location = _get_ticklocation_from_orientation(orientation)
- loc_settings = _api.check_getitem({
- "left": {"location": "left", "anchor": (1.0, 0.5),
- "panchor": (0.0, 0.5), "pad": 0.10},
- "right": {"location": "right", "anchor": (0.0, 0.5),
- "panchor": (1.0, 0.5), "pad": 0.05},
- "top": {"location": "top", "anchor": (0.5, 0.0),
- "panchor": (0.5, 1.0), "pad": 0.05},
- "bottom": {"location": "bottom", "anchor": (0.5, 1.0),
- "panchor": (0.5, 0.0), "pad": 0.15},
- }, location=location)
- loc_settings["orientation"] = _get_orientation_from_location(location)
- if orientation is not None and orientation != loc_settings["orientation"]:
- # Allow the user to pass both if they are consistent.
- raise TypeError("location and orientation are mutually exclusive")
- return loc_settings
-
-
-def _get_orientation_from_location(location):
- return _api.check_getitem(
- {None: None, "left": "vertical", "right": "vertical",
- "top": "horizontal", "bottom": "horizontal"}, location=location)
-
-
-def _get_ticklocation_from_orientation(orientation):
- return _api.check_getitem(
- {None: "right", "vertical": "right", "horizontal": "bottom"},
- orientation=orientation)
-
-
-@_docstring.interpd
-def make_axes(parents, location=None, orientation=None, fraction=0.15,
- shrink=1.0, aspect=20, **kwargs):
- """
- Create an `~.axes.Axes` suitable for a colorbar.
-
- The axes is placed in the figure of the *parents* axes, by resizing and
- repositioning *parents*.
-
- Parameters
- ----------
- parents : `~matplotlib.axes.Axes` or iterable or `numpy.ndarray` of `~.axes.Axes`
- The Axes to use as parents for placing the colorbar.
- %(_make_axes_kw_doc)s
-
- Returns
- -------
- cax : `~matplotlib.axes.Axes`
- The child axes.
- kwargs : dict
- The reduced keyword dictionary to be passed when creating the colorbar
- instance.
- """
- loc_settings = _normalize_location_orientation(location, orientation)
- # put appropriate values into the kwargs dict for passing back to
- # the Colorbar class
- kwargs['orientation'] = loc_settings['orientation']
- location = kwargs['ticklocation'] = loc_settings['location']
-
- anchor = kwargs.pop('anchor', loc_settings['anchor'])
- panchor = kwargs.pop('panchor', loc_settings['panchor'])
- aspect0 = aspect
- # turn parents into a list if it is not already. Note we cannot
- # use .flatten or .ravel as these copy the references rather than
- # reuse them, leading to a memory leak
- if isinstance(parents, np.ndarray):
- parents = list(parents.flat)
- elif np.iterable(parents):
- parents = list(parents)
- else:
- parents = [parents]
-
- fig = parents[0].get_figure()
-
- pad0 = 0.05 if fig.get_constrained_layout() else loc_settings['pad']
- pad = kwargs.pop('pad', pad0)
-
- if not all(fig is ax.get_figure() for ax in parents):
- raise ValueError('Unable to create a colorbar axes as not all '
- 'parents share the same figure.')
-
- # take a bounding box around all of the given axes
- parents_bbox = mtransforms.Bbox.union(
- [ax.get_position(original=True).frozen() for ax in parents])
-
- pb = parents_bbox
- if location in ('left', 'right'):
- if location == 'left':
- pbcb, _, pb1 = pb.splitx(fraction, fraction + pad)
- else:
- pb1, _, pbcb = pb.splitx(1 - fraction - pad, 1 - fraction)
- pbcb = pbcb.shrunk(1.0, shrink).anchored(anchor, pbcb)
- else:
- if location == 'bottom':
- pbcb, _, pb1 = pb.splity(fraction, fraction + pad)
- else:
- pb1, _, pbcb = pb.splity(1 - fraction - pad, 1 - fraction)
- pbcb = pbcb.shrunk(shrink, 1.0).anchored(anchor, pbcb)
-
- # define the aspect ratio in terms of y's per x rather than x's per y
- aspect = 1.0 / aspect
-
- # define a transform which takes us from old axes coordinates to
- # new axes coordinates
- shrinking_trans = mtransforms.BboxTransform(parents_bbox, pb1)
-
- # transform each of the axes in parents using the new transform
- for ax in parents:
- new_posn = shrinking_trans.transform(ax.get_position(original=True))
- new_posn = mtransforms.Bbox(new_posn)
- ax._set_position(new_posn)
- if panchor is not False:
- ax.set_anchor(panchor)
-
- cax = fig.add_axes(pbcb, label="<colorbar>")
- for a in parents:
- # tell the parent it has a colorbar
- a._colorbars += [cax]
- cax._colorbar_info = dict(
- parents=parents,
- location=location,
- shrink=shrink,
- anchor=anchor,
- panchor=panchor,
- fraction=fraction,
- aspect=aspect0,
- pad=pad)
- # and we need to set the aspect ratio by hand...
- cax.set_anchor(anchor)
- cax.set_box_aspect(aspect)
- cax.set_aspect('auto')
-
- return cax, kwargs
-
-
-@_docstring.interpd
-def make_axes_gridspec(parent, *, location=None, orientation=None,
- fraction=0.15, shrink=1.0, aspect=20, **kwargs):
- """
- Create an `~.axes.Axes` suitable for a colorbar.
-
- The axes is placed in the figure of the *parent* axes, by resizing and
- repositioning *parent*.
-
- This function is similar to `.make_axes` and mostly compatible with it.
- Primary differences are
-
- - `.make_axes_gridspec` requires the *parent* to have a subplotspec.
- - `.make_axes` positions the axes in figure coordinates;
- `.make_axes_gridspec` positions it using a subplotspec.
- - `.make_axes` updates the position of the parent. `.make_axes_gridspec`
- replaces the parent gridspec with a new one.
-
- Parameters
- ----------
- parent : `~matplotlib.axes.Axes`
- The Axes to use as parent for placing the colorbar.
- %(_make_axes_kw_doc)s
-
- Returns
- -------
- cax : `~matplotlib.axes.Axes`
- The child axes.
- kwargs : dict
- The reduced keyword dictionary to be passed when creating the colorbar
- instance.
- """
-
- loc_settings = _normalize_location_orientation(location, orientation)
- kwargs['orientation'] = loc_settings['orientation']
- location = kwargs['ticklocation'] = loc_settings['location']
-
- aspect0 = aspect
- anchor = kwargs.pop('anchor', loc_settings['anchor'])
- panchor = kwargs.pop('panchor', loc_settings['panchor'])
- pad = kwargs.pop('pad', loc_settings["pad"])
- wh_space = 2 * pad / (1 - pad)
-
- if location in ('left', 'right'):
- # for shrinking
- height_ratios = [
- (1-anchor[1])*(1-shrink), shrink, anchor[1]*(1-shrink)]
-
- if location == 'left':
- gs = parent.get_subplotspec().subgridspec(
- 1, 2, wspace=wh_space,
- width_ratios=[fraction, 1-fraction-pad])
- ss_main = gs[1]
- ss_cb = gs[0].subgridspec(
- 3, 1, hspace=0, height_ratios=height_ratios)[1]
- else:
- gs = parent.get_subplotspec().subgridspec(
- 1, 2, wspace=wh_space,
- width_ratios=[1-fraction-pad, fraction])
- ss_main = gs[0]
- ss_cb = gs[1].subgridspec(
- 3, 1, hspace=0, height_ratios=height_ratios)[1]
- else:
- # for shrinking
- width_ratios = [
- anchor[0]*(1-shrink), shrink, (1-anchor[0])*(1-shrink)]
-
- if location == 'bottom':
- gs = parent.get_subplotspec().subgridspec(
- 2, 1, hspace=wh_space,
- height_ratios=[1-fraction-pad, fraction])
- ss_main = gs[0]
- ss_cb = gs[1].subgridspec(
- 1, 3, wspace=0, width_ratios=width_ratios)[1]
- aspect = 1 / aspect
- else:
- gs = parent.get_subplotspec().subgridspec(
- 2, 1, hspace=wh_space,
- height_ratios=[fraction, 1-fraction-pad])
- ss_main = gs[1]
- ss_cb = gs[0].subgridspec(
- 1, 3, wspace=0, width_ratios=width_ratios)[1]
- aspect = 1 / aspect
-
- parent.set_subplotspec(ss_main)
- if panchor is not False:
- parent.set_anchor(panchor)
-
- fig = parent.get_figure()
- cax = fig.add_subplot(ss_cb, label="<colorbar>")
- cax.set_anchor(anchor)
- cax.set_box_aspect(aspect)
- cax.set_aspect('auto')
- cax._colorbar_info = dict(
- location=location,
- parents=[parent],
- shrink=shrink,
- anchor=anchor,
- panchor=panchor,
- fraction=fraction,
- aspect=aspect0,
- pad=pad)
-
- return cax, kwargs
diff --git a/contrib/python/matplotlib/py3/matplotlib/colorbar.pyi b/contrib/python/matplotlib/py3/matplotlib/colorbar.pyi
deleted file mode 100644
index f71c5759fc..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/colorbar.pyi
+++ /dev/null
@@ -1,136 +0,0 @@
-import matplotlib.spines as mspines
-from matplotlib import cm, collections, colors, contour
-from matplotlib.axes import Axes
-from matplotlib.backend_bases import RendererBase
-from matplotlib.patches import Patch
-from matplotlib.ticker import Locator, Formatter
-from matplotlib.transforms import Bbox
-
-import numpy as np
-from numpy.typing import ArrayLike
-from collections.abc import Sequence
-from typing import Any, Literal, overload
-from .typing import ColorType
-
-class _ColorbarSpine(mspines.Spines):
- def __init__(self, axes: Axes): ...
- def get_window_extent(self, renderer: RendererBase | None = ...) -> Bbox:...
- def set_xy(self, xy: ArrayLike) -> None: ...
- def draw(self, renderer: RendererBase | None) -> None:...
-
-
-class Colorbar:
- n_rasterize: int
- mappable: cm.ScalarMappable
- ax: Axes
- alpha: float | None
- cmap: colors.Colormap
- norm: colors.Normalize
- values: Sequence[float] | None
- boundaries: Sequence[float] | None
- extend: Literal["neither", "both", "min", "max"]
- spacing: Literal["uniform", "proportional"]
- orientation: Literal["vertical", "horizontal"]
- drawedges: bool
- extendfrac: Literal["auto"] | float | Sequence[float] | None
- extendrect: bool
- solids: None | collections.QuadMesh
- solids_patches: list[Patch]
- lines: list[collections.LineCollection]
- outline: _ColorbarSpine
- dividers: collections.LineCollection
- ticklocation: Literal["left", "right", "top", "bottom"]
- def __init__(
- self,
- ax: Axes,
- mappable: cm.ScalarMappable | None = ...,
- *,
- cmap: str | colors.Colormap | None = ...,
- norm: colors.Normalize | None = ...,
- alpha: float | None = ...,
- values: Sequence[float] | None = ...,
- boundaries: Sequence[float] | None = ...,
- orientation: Literal["vertical", "horizontal"] | None = ...,
- ticklocation: Literal["auto", "left", "right", "top", "bottom"] = ...,
- extend: Literal["neither", "both", "min", "max"] | None = ...,
- spacing: Literal["uniform", "proportional"] = ...,
- ticks: Sequence[float] | Locator | None = ...,
- format: str | Formatter | None = ...,
- drawedges: bool = ...,
- extendfrac: Literal["auto"] | float | Sequence[float] | None = ...,
- extendrect: bool = ...,
- label: str = ...,
- location: Literal["left", "right", "top", "bottom"] | None = ...
- ) -> None: ...
- @property
- def locator(self) -> Locator: ...
- @locator.setter
- def locator(self, loc: Locator) -> None: ...
- @property
- def minorlocator(self) -> Locator: ...
- @minorlocator.setter
- def minorlocator(self, loc: Locator) -> None: ...
- @property
- def formatter(self) -> Formatter: ...
- @formatter.setter
- def formatter(self, fmt: Formatter) -> None: ...
- @property
- def minorformatter(self) -> Formatter: ...
- @minorformatter.setter
- def minorformatter(self, fmt: Formatter) -> None: ...
- def update_normal(self, mappable: cm.ScalarMappable) -> None: ...
- @overload
- def add_lines(self, CS: contour.ContourSet, erase: bool = ...) -> None: ...
- @overload
- def add_lines(
- self,
- levels: ArrayLike,
- colors: ColorType | Sequence[ColorType],
- linewidths: float | ArrayLike,
- erase: bool = ...,
- ) -> None: ...
- def update_ticks(self) -> None: ...
- def set_ticks(
- self,
- ticks: Sequence[float] | Locator,
- *,
- labels: Sequence[str] | None = ...,
- minor: bool = ...,
- **kwargs
- ) -> None: ...
- def get_ticks(self, minor: bool = ...) -> np.ndarray: ...
- def set_ticklabels(
- self,
- ticklabels: Sequence[str],
- *,
- minor: bool = ...,
- **kwargs
- ) -> None: ...
- def minorticks_on(self) -> None: ...
- def minorticks_off(self) -> None: ...
- def set_label(self, label: str, *, loc: str | None = ..., **kwargs) -> None: ...
- def set_alpha(self, alpha: float | np.ndarray) -> None: ...
- def remove(self) -> None: ...
- def drag_pan(self, button: Any, key: Any, x: float, y: float) -> None: ...
-
-ColorbarBase = Colorbar
-
-def make_axes(
- parents: Axes | list[Axes] | np.ndarray,
- location: Literal["left", "right", "top", "bottom"] | None = ...,
- orientation: Literal["vertical", "horizontal"] | None = ...,
- fraction: float = ...,
- shrink: float = ...,
- aspect: float = ...,
- **kwargs
-) -> tuple[Axes, dict[str, Any]]: ...
-def make_axes_gridspec(
- parent: Axes,
- *,
- location: Literal["left", "right", "top", "bottom"] | None = ...,
- orientation: Literal["vertical", "horizontal"] | None = ...,
- fraction: float = ...,
- shrink: float = ...,
- aspect: float = ...,
- **kwargs
-) -> tuple[Axes, dict[str, Any]]: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/colors.py b/contrib/python/matplotlib/py3/matplotlib/colors.py
deleted file mode 100644
index bd89e70049..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/colors.py
+++ /dev/null
@@ -1,2762 +0,0 @@
-"""
-A module for converting numbers or color arguments to *RGB* or *RGBA*.
-
-*RGB* and *RGBA* are sequences of, respectively, 3 or 4 floats in the
-range 0-1.
-
-This module includes functions and classes for color specification conversions,
-and for mapping numbers to colors in a 1-D array of colors called a colormap.
-
-Mapping data onto colors using a colormap typically involves two steps: a data
-array is first mapped onto the range 0-1 using a subclass of `Normalize`,
-then this number is mapped to a color using a subclass of `Colormap`. Two
-subclasses of `Colormap` provided here: `LinearSegmentedColormap`, which uses
-piecewise-linear interpolation to define colormaps, and `ListedColormap`, which
-makes a colormap from a list of colors.
-
-.. seealso::
-
- :ref:`colormap-manipulation` for examples of how to
- make colormaps and
-
- :ref:`colormaps` for a list of built-in colormaps.
-
- :ref:`colormapnorms` for more details about data
- normalization
-
- More colormaps are available at palettable_.
-
-The module also provides functions for checking whether an object can be
-interpreted as a color (`is_color_like`), for converting such an object
-to an RGBA tuple (`to_rgba`) or to an HTML-like hex string in the
-"#rrggbb" format (`to_hex`), and a sequence of colors to an (n, 4)
-RGBA array (`to_rgba_array`). Caching is used for efficiency.
-
-Colors that Matplotlib recognizes are listed at
-:ref:`colors_def`.
-
-.. _palettable: https://jiffyclub.github.io/palettable/
-.. _xkcd color survey: https://xkcd.com/color/rgb/
-"""
-
-import base64
-from collections.abc import Sized, Sequence, Mapping
-import functools
-import importlib
-import inspect
-import io
-import itertools
-from numbers import Real
-import re
-
-from PIL import Image
-from PIL.PngImagePlugin import PngInfo
-
-import matplotlib as mpl
-import numpy as np
-from matplotlib import _api, _cm, cbook, scale
-from ._color_data import BASE_COLORS, TABLEAU_COLORS, CSS4_COLORS, XKCD_COLORS
-
-
-class _ColorMapping(dict):
- def __init__(self, mapping):
- super().__init__(mapping)
- self.cache = {}
-
- def __setitem__(self, key, value):
- super().__setitem__(key, value)
- self.cache.clear()
-
- def __delitem__(self, key):
- super().__delitem__(key)
- self.cache.clear()
-
-
-_colors_full_map = {}
-# Set by reverse priority order.
-_colors_full_map.update(XKCD_COLORS)
-_colors_full_map.update({k.replace('grey', 'gray'): v
- for k, v in XKCD_COLORS.items()
- if 'grey' in k})
-_colors_full_map.update(CSS4_COLORS)
-_colors_full_map.update(TABLEAU_COLORS)
-_colors_full_map.update({k.replace('gray', 'grey'): v
- for k, v in TABLEAU_COLORS.items()
- if 'gray' in k})
-_colors_full_map.update(BASE_COLORS)
-_colors_full_map = _ColorMapping(_colors_full_map)
-
-_REPR_PNG_SIZE = (512, 64)
-
-
-def get_named_colors_mapping():
- """Return the global mapping of names to named colors."""
- return _colors_full_map
-
-
-class ColorSequenceRegistry(Mapping):
- r"""
- Container for sequences of colors that are known to Matplotlib by name.
-
- The universal registry instance is `matplotlib.color_sequences`. There
- should be no need for users to instantiate `.ColorSequenceRegistry`
- themselves.
-
- Read access uses a dict-like interface mapping names to lists of colors::
-
- import matplotlib as mpl
- cmap = mpl.color_sequences['tab10']
-
- The returned lists are copies, so that their modification does not change
- the global definition of the color sequence.
-
- Additional color sequences can be added via
- `.ColorSequenceRegistry.register`::
-
- mpl.color_sequences.register('rgb', ['r', 'g', 'b'])
- """
-
- _BUILTIN_COLOR_SEQUENCES = {
- 'tab10': _cm._tab10_data,
- 'tab20': _cm._tab20_data,
- 'tab20b': _cm._tab20b_data,
- 'tab20c': _cm._tab20c_data,
- 'Pastel1': _cm._Pastel1_data,
- 'Pastel2': _cm._Pastel2_data,
- 'Paired': _cm._Paired_data,
- 'Accent': _cm._Accent_data,
- 'Dark2': _cm._Dark2_data,
- 'Set1': _cm._Set1_data,
- 'Set2': _cm._Set1_data,
- 'Set3': _cm._Set1_data,
- }
-
- def __init__(self):
- self._color_sequences = {**self._BUILTIN_COLOR_SEQUENCES}
-
- def __getitem__(self, item):
- try:
- return list(self._color_sequences[item])
- except KeyError:
- raise KeyError(f"{item!r} is not a known color sequence name")
-
- def __iter__(self):
- return iter(self._color_sequences)
-
- def __len__(self):
- return len(self._color_sequences)
-
- def __str__(self):
- return ('ColorSequenceRegistry; available colormaps:\n' +
- ', '.join(f"'{name}'" for name in self))
-
- def register(self, name, color_list):
- """
- Register a new color sequence.
-
- The color sequence registry stores a copy of the given *color_list*, so
- that future changes to the original list do not affect the registered
- color sequence. Think of this as the registry taking a snapshot
- of *color_list* at registration.
-
- Parameters
- ----------
- name : str
- The name for the color sequence.
-
- color_list : list of colors
- An iterable returning valid Matplotlib colors when iterating over.
- Note however that the returned color sequence will always be a
- list regardless of the input type.
-
- """
- if name in self._BUILTIN_COLOR_SEQUENCES:
- raise ValueError(f"{name!r} is a reserved name for a builtin "
- "color sequence")
-
- color_list = list(color_list) # force copy and coerce type to list
- for color in color_list:
- try:
- to_rgba(color)
- except ValueError:
- raise ValueError(
- f"{color!r} is not a valid color specification")
-
- self._color_sequences[name] = color_list
-
- def unregister(self, name):
- """
- Remove a sequence from the registry.
-
- You cannot remove built-in color sequences.
-
- If the name is not registered, returns with no error.
- """
- if name in self._BUILTIN_COLOR_SEQUENCES:
- raise ValueError(
- f"Cannot unregister builtin color sequence {name!r}")
- self._color_sequences.pop(name, None)
-
-
-_color_sequences = ColorSequenceRegistry()
-
-
-def _sanitize_extrema(ex):
- if ex is None:
- return ex
- try:
- ret = ex.item()
- except AttributeError:
- ret = float(ex)
- return ret
-
-_nth_color_re = re.compile(r"\AC[0-9]+\Z")
-
-
-def _is_nth_color(c):
- """Return whether *c* can be interpreted as an item in the color cycle."""
- return isinstance(c, str) and _nth_color_re.match(c)
-
-
-def is_color_like(c):
- """Return whether *c* can be interpreted as an RGB(A) color."""
- # Special-case nth color syntax because it cannot be parsed during setup.
- if _is_nth_color(c):
- return True
- try:
- to_rgba(c)
- except ValueError:
- return False
- else:
- return True
-
-
-def _has_alpha_channel(c):
- """Return whether *c* is a color with an alpha channel."""
- # 4-element sequences are interpreted as r, g, b, a
- return not isinstance(c, str) and len(c) == 4
-
-
-def _check_color_like(**kwargs):
- """
- For each *key, value* pair in *kwargs*, check that *value* is color-like.
- """
- for k, v in kwargs.items():
- if not is_color_like(v):
- raise ValueError(f"{v!r} is not a valid value for {k}")
-
-
-def same_color(c1, c2):
- """
- Return whether the colors *c1* and *c2* are the same.
-
- *c1*, *c2* can be single colors or lists/arrays of colors.
- """
- c1 = to_rgba_array(c1)
- c2 = to_rgba_array(c2)
- n1 = max(c1.shape[0], 1) # 'none' results in shape (0, 4), but is 1-elem
- n2 = max(c2.shape[0], 1) # 'none' results in shape (0, 4), but is 1-elem
-
- if n1 != n2:
- raise ValueError('Different number of elements passed.')
- # The following shape test is needed to correctly handle comparisons with
- # 'none', which results in a shape (0, 4) array and thus cannot be tested
- # via value comparison.
- return c1.shape == c2.shape and (c1 == c2).all()
-
-
-def to_rgba(c, alpha=None):
- """
- Convert *c* to an RGBA color.
-
- Parameters
- ----------
- c : Matplotlib color or ``np.ma.masked``
-
- alpha : float, optional
- If *alpha* is given, force the alpha value of the returned RGBA tuple
- to *alpha*.
-
- If None, the alpha value from *c* is used. If *c* does not have an
- alpha channel, then alpha defaults to 1.
-
- *alpha* is ignored for the color value ``"none"`` (case-insensitive),
- which always maps to ``(0, 0, 0, 0)``.
-
- Returns
- -------
- tuple
- Tuple of floats ``(r, g, b, a)``, where each channel (red, green, blue,
- alpha) can assume values between 0 and 1.
- """
- # Special-case nth color syntax because it should not be cached.
- if _is_nth_color(c):
- prop_cycler = mpl.rcParams['axes.prop_cycle']
- colors = prop_cycler.by_key().get('color', ['k'])
- c = colors[int(c[1:]) % len(colors)]
- try:
- rgba = _colors_full_map.cache[c, alpha]
- except (KeyError, TypeError): # Not in cache, or unhashable.
- rgba = None
- if rgba is None: # Suppress exception chaining of cache lookup failure.
- rgba = _to_rgba_no_colorcycle(c, alpha)
- try:
- _colors_full_map.cache[c, alpha] = rgba
- except TypeError:
- pass
- return rgba
-
-
-def _to_rgba_no_colorcycle(c, alpha=None):
- """
- Convert *c* to an RGBA color, with no support for color-cycle syntax.
-
- If *alpha* is given, force the alpha value of the returned RGBA tuple
- to *alpha*. Otherwise, the alpha value from *c* is used, if it has alpha
- information, or defaults to 1.
-
- *alpha* is ignored for the color value ``"none"`` (case-insensitive),
- which always maps to ``(0, 0, 0, 0)``.
- """
- if isinstance(c, tuple) and len(c) == 2:
- if alpha is None:
- c, alpha = c
- else:
- c = c[0]
- if alpha is not None and not 0 <= alpha <= 1:
- raise ValueError("'alpha' must be between 0 and 1, inclusive")
- orig_c = c
- if c is np.ma.masked:
- return (0., 0., 0., 0.)
- if isinstance(c, str):
- if c.lower() == "none":
- return (0., 0., 0., 0.)
- # Named color.
- try:
- # This may turn c into a non-string, so we check again below.
- c = _colors_full_map[c]
- except KeyError:
- if len(orig_c) != 1:
- try:
- c = _colors_full_map[c.lower()]
- except KeyError:
- pass
- if isinstance(c, str):
- # hex color in #rrggbb format.
- match = re.match(r"\A#[a-fA-F0-9]{6}\Z", c)
- if match:
- return (tuple(int(n, 16) / 255
- for n in [c[1:3], c[3:5], c[5:7]])
- + (alpha if alpha is not None else 1.,))
- # hex color in #rgb format, shorthand for #rrggbb.
- match = re.match(r"\A#[a-fA-F0-9]{3}\Z", c)
- if match:
- return (tuple(int(n, 16) / 255
- for n in [c[1]*2, c[2]*2, c[3]*2])
- + (alpha if alpha is not None else 1.,))
- # hex color with alpha in #rrggbbaa format.
- match = re.match(r"\A#[a-fA-F0-9]{8}\Z", c)
- if match:
- color = [int(n, 16) / 255
- for n in [c[1:3], c[3:5], c[5:7], c[7:9]]]
- if alpha is not None:
- color[-1] = alpha
- return tuple(color)
- # hex color with alpha in #rgba format, shorthand for #rrggbbaa.
- match = re.match(r"\A#[a-fA-F0-9]{4}\Z", c)
- if match:
- color = [int(n, 16) / 255
- for n in [c[1]*2, c[2]*2, c[3]*2, c[4]*2]]
- if alpha is not None:
- color[-1] = alpha
- return tuple(color)
- # string gray.
- try:
- c = float(c)
- except ValueError:
- pass
- else:
- if not (0 <= c <= 1):
- raise ValueError(
- f"Invalid string grayscale value {orig_c!r}. "
- f"Value must be within 0-1 range")
- return c, c, c, alpha if alpha is not None else 1.
- raise ValueError(f"Invalid RGBA argument: {orig_c!r}")
- # turn 2-D array into 1-D array
- if isinstance(c, np.ndarray):
- if c.ndim == 2 and c.shape[0] == 1:
- c = c.reshape(-1)
- # tuple color.
- if not np.iterable(c):
- raise ValueError(f"Invalid RGBA argument: {orig_c!r}")
- if len(c) not in [3, 4]:
- raise ValueError("RGBA sequence should have length 3 or 4")
- if not all(isinstance(x, Real) for x in c):
- # Checks that don't work: `map(float, ...)`, `np.array(..., float)` and
- # `np.array(...).astype(float)` would all convert "0.5" to 0.5.
- raise ValueError(f"Invalid RGBA argument: {orig_c!r}")
- # Return a tuple to prevent the cached value from being modified.
- c = tuple(map(float, c))
- if len(c) == 3 and alpha is None:
- alpha = 1
- if alpha is not None:
- c = c[:3] + (alpha,)
- if any(elem < 0 or elem > 1 for elem in c):
- raise ValueError("RGBA values should be within 0-1 range")
- return c
-
-
-def to_rgba_array(c, alpha=None):
- """
- Convert *c* to a (n, 4) array of RGBA colors.
-
- Parameters
- ----------
- c : Matplotlib color or array of colors
- If *c* is a masked array, an `~numpy.ndarray` is returned with a
- (0, 0, 0, 0) row for each masked value or row in *c*.
-
- alpha : float or sequence of floats, optional
- If *alpha* is given, force the alpha value of the returned RGBA tuple
- to *alpha*.
-
- If None, the alpha value from *c* is used. If *c* does not have an
- alpha channel, then alpha defaults to 1.
-
- *alpha* is ignored for the color value ``"none"`` (case-insensitive),
- which always maps to ``(0, 0, 0, 0)``.
-
- If *alpha* is a sequence and *c* is a single color, *c* will be
- repeated to match the length of *alpha*.
-
- Returns
- -------
- array
- (n, 4) array of RGBA colors, where each channel (red, green, blue,
- alpha) can assume values between 0 and 1.
- """
- if isinstance(c, tuple) and len(c) == 2 and isinstance(c[1], Real):
- if alpha is None:
- c, alpha = c
- else:
- c = c[0]
- # Special-case inputs that are already arrays, for performance. (If the
- # array has the wrong kind or shape, raise the error during one-at-a-time
- # conversion.)
- if np.iterable(alpha):
- alpha = np.asarray(alpha).ravel()
- if (isinstance(c, np.ndarray) and c.dtype.kind in "if"
- and c.ndim == 2 and c.shape[1] in [3, 4]):
- mask = c.mask.any(axis=1) if np.ma.is_masked(c) else None
- c = np.ma.getdata(c)
- if np.iterable(alpha):
- if c.shape[0] == 1 and alpha.shape[0] > 1:
- c = np.tile(c, (alpha.shape[0], 1))
- elif c.shape[0] != alpha.shape[0]:
- raise ValueError("The number of colors must match the number"
- " of alpha values if there are more than one"
- " of each.")
- if c.shape[1] == 3:
- result = np.column_stack([c, np.zeros(len(c))])
- result[:, -1] = alpha if alpha is not None else 1.
- elif c.shape[1] == 4:
- result = c.copy()
- if alpha is not None:
- result[:, -1] = alpha
- if mask is not None:
- result[mask] = 0
- if np.any((result < 0) | (result > 1)):
- raise ValueError("RGBA values should be within 0-1 range")
- return result
- # Handle single values.
- # Note that this occurs *after* handling inputs that are already arrays, as
- # `to_rgba(c, alpha)` (below) is expensive for such inputs, due to the need
- # to format the array in the ValueError message(!).
- if cbook._str_lower_equal(c, "none"):
- return np.zeros((0, 4), float)
- try:
- if np.iterable(alpha):
- return np.array([to_rgba(c, a) for a in alpha], float)
- else:
- return np.array([to_rgba(c, alpha)], float)
- except TypeError:
- pass
- except ValueError as e:
- if e.args == ("'alpha' must be between 0 and 1, inclusive", ):
- # ValueError is from _to_rgba_no_colorcycle().
- raise e
- if isinstance(c, str):
- raise ValueError(f"{c!r} is not a valid color value.")
-
- if len(c) == 0:
- return np.zeros((0, 4), float)
-
- # Quick path if the whole sequence can be directly converted to a numpy
- # array in one shot.
- if isinstance(c, Sequence):
- lens = {len(cc) if isinstance(cc, (list, tuple)) else -1 for cc in c}
- if lens == {3}:
- rgba = np.column_stack([c, np.ones(len(c))])
- elif lens == {4}:
- rgba = np.array(c)
- else:
- rgba = np.array([to_rgba(cc) for cc in c])
- else:
- rgba = np.array([to_rgba(cc) for cc in c])
-
- if alpha is not None:
- rgba[:, 3] = alpha
- return rgba
-
-
-def to_rgb(c):
- """Convert *c* to an RGB color, silently dropping the alpha channel."""
- return to_rgba(c)[:3]
-
-
-def to_hex(c, keep_alpha=False):
- """
- Convert *c* to a hex color.
-
- Parameters
- ----------
- c : :ref:`color <colors_def>` or `numpy.ma.masked`
-
- keep_alpha : bool, default: False
- If False, use the ``#rrggbb`` format, otherwise use ``#rrggbbaa``.
-
- Returns
- -------
- str
- ``#rrggbb`` or ``#rrggbbaa`` hex color string
- """
- c = to_rgba(c)
- if not keep_alpha:
- c = c[:3]
- return "#" + "".join(format(round(val * 255), "02x") for val in c)
-
-
-### Backwards-compatible color-conversion API
-
-
-cnames = CSS4_COLORS
-hexColorPattern = re.compile(r"\A#[a-fA-F0-9]{6}\Z")
-rgb2hex = to_hex
-hex2color = to_rgb
-
-
-class ColorConverter:
- """
- A class only kept for backwards compatibility.
-
- Its functionality is entirely provided by module-level functions.
- """
- colors = _colors_full_map
- cache = _colors_full_map.cache
- to_rgb = staticmethod(to_rgb)
- to_rgba = staticmethod(to_rgba)
- to_rgba_array = staticmethod(to_rgba_array)
-
-
-colorConverter = ColorConverter()
-
-
-### End of backwards-compatible color-conversion API
-
-
-def _create_lookup_table(N, data, gamma=1.0):
- r"""
- Create an *N* -element 1D lookup table.
-
- This assumes a mapping :math:`f : [0, 1] \rightarrow [0, 1]`. The returned
- data is an array of N values :math:`y = f(x)` where x is sampled from
- [0, 1].
-
- By default (*gamma* = 1) x is equidistantly sampled from [0, 1]. The
- *gamma* correction factor :math:`\gamma` distorts this equidistant
- sampling by :math:`x \rightarrow x^\gamma`.
-
- Parameters
- ----------
- N : int
- The number of elements of the created lookup table; at least 1.
-
- data : (M, 3) array-like or callable
- Defines the mapping :math:`f`.
-
- If a (M, 3) array-like, the rows define values (x, y0, y1). The x
- values must start with x=0, end with x=1, and all x values be in
- increasing order.
-
- A value between :math:`x_i` and :math:`x_{i+1}` is mapped to the range
- :math:`y^1_{i-1} \ldots y^0_i` by linear interpolation.
-
- For the simple case of a y-continuous mapping, y0 and y1 are identical.
-
- The two values of y are to allow for discontinuous mapping functions.
- E.g. a sawtooth with a period of 0.2 and an amplitude of 1 would be::
-
- [(0, 1, 0), (0.2, 1, 0), (0.4, 1, 0), ..., [(1, 1, 0)]
-
- In the special case of ``N == 1``, by convention the returned value
- is y0 for x == 1.
-
- If *data* is a callable, it must accept and return numpy arrays::
-
- data(x : ndarray) -> ndarray
-
- and map values between 0 - 1 to 0 - 1.
-
- gamma : float
- Gamma correction factor for input distribution x of the mapping.
-
- See also https://en.wikipedia.org/wiki/Gamma_correction.
-
- Returns
- -------
- array
- The lookup table where ``lut[x * (N-1)]`` gives the closest value
- for values of x between 0 and 1.
-
- Notes
- -----
- This function is internally used for `.LinearSegmentedColormap`.
- """
-
- if callable(data):
- xind = np.linspace(0, 1, N) ** gamma
- lut = np.clip(np.array(data(xind), dtype=float), 0, 1)
- return lut
-
- try:
- adata = np.array(data)
- except Exception as err:
- raise TypeError("data must be convertible to an array") from err
- _api.check_shape((None, 3), data=adata)
-
- x = adata[:, 0]
- y0 = adata[:, 1]
- y1 = adata[:, 2]
-
- if x[0] != 0. or x[-1] != 1.0:
- raise ValueError(
- "data mapping points must start with x=0 and end with x=1")
- if (np.diff(x) < 0).any():
- raise ValueError("data mapping points must have x in increasing order")
- # begin generation of lookup table
- if N == 1:
- # convention: use the y = f(x=1) value for a 1-element lookup table
- lut = np.array(y0[-1])
- else:
- x = x * (N - 1)
- xind = (N - 1) * np.linspace(0, 1, N) ** gamma
- ind = np.searchsorted(x, xind)[1:-1]
-
- distance = (xind[1:-1] - x[ind - 1]) / (x[ind] - x[ind - 1])
- lut = np.concatenate([
- [y1[0]],
- distance * (y0[ind] - y1[ind - 1]) + y1[ind - 1],
- [y0[-1]],
- ])
- # ensure that the lut is confined to values between 0 and 1 by clipping it
- return np.clip(lut, 0.0, 1.0)
-
-
-class Colormap:
- """
- Baseclass for all scalar to RGBA mappings.
-
- Typically, Colormap instances are used to convert data values (floats)
- from the interval ``[0, 1]`` to the RGBA color that the respective
- Colormap represents. For scaling of data into the ``[0, 1]`` interval see
- `matplotlib.colors.Normalize`. Subclasses of `matplotlib.cm.ScalarMappable`
- make heavy use of this ``data -> normalize -> map-to-color`` processing
- chain.
- """
-
- def __init__(self, name, N=256):
- """
- Parameters
- ----------
- name : str
- The name of the colormap.
- N : int
- The number of RGB quantization levels.
- """
- self.name = name
- self.N = int(N) # ensure that N is always int
- self._rgba_bad = (0.0, 0.0, 0.0, 0.0) # If bad, don't paint anything.
- self._rgba_under = None
- self._rgba_over = None
- self._i_under = self.N
- self._i_over = self.N + 1
- self._i_bad = self.N + 2
- self._isinit = False
- #: When this colormap exists on a scalar mappable and colorbar_extend
- #: is not False, colorbar creation will pick up ``colorbar_extend`` as
- #: the default value for the ``extend`` keyword in the
- #: `matplotlib.colorbar.Colorbar` constructor.
- self.colorbar_extend = False
-
- def __call__(self, X, alpha=None, bytes=False):
- r"""
- Parameters
- ----------
- X : float or int, `~numpy.ndarray` or scalar
- The data value(s) to convert to RGBA.
- For floats, *X* should be in the interval ``[0.0, 1.0]`` to
- return the RGBA values ``X*100`` percent along the Colormap line.
- For integers, *X* should be in the interval ``[0, Colormap.N)`` to
- return RGBA values *indexed* from the Colormap with index ``X``.
- alpha : float or array-like or None
- Alpha must be a scalar between 0 and 1, a sequence of such
- floats with shape matching X, or None.
- bytes : bool
- If False (default), the returned RGBA values will be floats in the
- interval ``[0, 1]`` otherwise they will be `numpy.uint8`\s in the
- interval ``[0, 255]``.
-
- Returns
- -------
- Tuple of RGBA values if X is scalar, otherwise an array of
- RGBA values with a shape of ``X.shape + (4, )``.
- """
- if not self._isinit:
- self._init()
-
- xa = np.array(X, copy=True)
- if not xa.dtype.isnative:
- # Native byteorder is faster.
- xa = xa.byteswap().view(xa.dtype.newbyteorder())
- if xa.dtype.kind == "f":
- xa *= self.N
- # xa == 1 (== N after multiplication) is not out of range.
- xa[xa == self.N] = self.N - 1
- # Pre-compute the masks before casting to int (which can truncate
- # negative values to zero or wrap large floats to negative ints).
- mask_under = xa < 0
- mask_over = xa >= self.N
- # If input was masked, get the bad mask from it; else mask out nans.
- mask_bad = X.mask if np.ma.is_masked(X) else np.isnan(xa)
- with np.errstate(invalid="ignore"):
- # We need this cast for unsigned ints as well as floats
- xa = xa.astype(int)
- xa[mask_under] = self._i_under
- xa[mask_over] = self._i_over
- xa[mask_bad] = self._i_bad
-
- lut = self._lut
- if bytes:
- lut = (lut * 255).astype(np.uint8)
-
- rgba = lut.take(xa, axis=0, mode='clip')
-
- if alpha is not None:
- alpha = np.clip(alpha, 0, 1)
- if bytes:
- alpha *= 255 # Will be cast to uint8 upon assignment.
- if alpha.shape not in [(), xa.shape]:
- raise ValueError(
- f"alpha is array-like but its shape {alpha.shape} does "
- f"not match that of X {xa.shape}")
- rgba[..., -1] = alpha
- # If the "bad" color is all zeros, then ignore alpha input.
- if (lut[-1] == 0).all():
- rgba[mask_bad] = (0, 0, 0, 0)
-
- if not np.iterable(X):
- rgba = tuple(rgba)
- return rgba
-
- def __copy__(self):
- cls = self.__class__
- cmapobject = cls.__new__(cls)
- cmapobject.__dict__.update(self.__dict__)
- if self._isinit:
- cmapobject._lut = np.copy(self._lut)
- return cmapobject
-
- def __eq__(self, other):
- if (not isinstance(other, Colormap) or
- self.colorbar_extend != other.colorbar_extend):
- return False
- # To compare lookup tables the Colormaps have to be initialized
- if not self._isinit:
- self._init()
- if not other._isinit:
- other._init()
- return np.array_equal(self._lut, other._lut)
-
- def get_bad(self):
- """Get the color for masked values."""
- if not self._isinit:
- self._init()
- return np.array(self._lut[self._i_bad])
-
- def set_bad(self, color='k', alpha=None):
- """Set the color for masked values."""
- self._rgba_bad = to_rgba(color, alpha)
- if self._isinit:
- self._set_extremes()
-
- def get_under(self):
- """Get the color for low out-of-range values."""
- if not self._isinit:
- self._init()
- return np.array(self._lut[self._i_under])
-
- def set_under(self, color='k', alpha=None):
- """Set the color for low out-of-range values."""
- self._rgba_under = to_rgba(color, alpha)
- if self._isinit:
- self._set_extremes()
-
- def get_over(self):
- """Get the color for high out-of-range values."""
- if not self._isinit:
- self._init()
- return np.array(self._lut[self._i_over])
-
- def set_over(self, color='k', alpha=None):
- """Set the color for high out-of-range values."""
- self._rgba_over = to_rgba(color, alpha)
- if self._isinit:
- self._set_extremes()
-
- def set_extremes(self, *, bad=None, under=None, over=None):
- """
- Set the colors for masked (*bad*) values and, when ``norm.clip =
- False``, low (*under*) and high (*over*) out-of-range values.
- """
- if bad is not None:
- self.set_bad(bad)
- if under is not None:
- self.set_under(under)
- if over is not None:
- self.set_over(over)
-
- def with_extremes(self, *, bad=None, under=None, over=None):
- """
- Return a copy of the colormap, for which the colors for masked (*bad*)
- values and, when ``norm.clip = False``, low (*under*) and high (*over*)
- out-of-range values, have been set accordingly.
- """
- new_cm = self.copy()
- new_cm.set_extremes(bad=bad, under=under, over=over)
- return new_cm
-
- def _set_extremes(self):
- if self._rgba_under:
- self._lut[self._i_under] = self._rgba_under
- else:
- self._lut[self._i_under] = self._lut[0]
- if self._rgba_over:
- self._lut[self._i_over] = self._rgba_over
- else:
- self._lut[self._i_over] = self._lut[self.N - 1]
- self._lut[self._i_bad] = self._rgba_bad
-
- def _init(self):
- """Generate the lookup table, ``self._lut``."""
- raise NotImplementedError("Abstract class only")
-
- def is_gray(self):
- """Return whether the colormap is grayscale."""
- if not self._isinit:
- self._init()
- return (np.all(self._lut[:, 0] == self._lut[:, 1]) and
- np.all(self._lut[:, 0] == self._lut[:, 2]))
-
- def resampled(self, lutsize):
- """Return a new colormap with *lutsize* entries."""
- if hasattr(self, '_resample'):
- _api.warn_external(
- "The ability to resample a color map is now public API "
- f"However the class {type(self)} still only implements "
- "the previous private _resample method. Please update "
- "your class."
- )
- return self._resample(lutsize)
-
- raise NotImplementedError()
-
- def reversed(self, name=None):
- """
- Return a reversed instance of the Colormap.
-
- .. note:: This function is not implemented for the base class.
-
- Parameters
- ----------
- name : str, optional
- The name for the reversed colormap. If None, the
- name is set to ``self.name + "_r"``.
-
- See Also
- --------
- LinearSegmentedColormap.reversed
- ListedColormap.reversed
- """
- raise NotImplementedError()
-
- def _repr_png_(self):
- """Generate a PNG representation of the Colormap."""
- X = np.tile(np.linspace(0, 1, _REPR_PNG_SIZE[0]),
- (_REPR_PNG_SIZE[1], 1))
- pixels = self(X, bytes=True)
- png_bytes = io.BytesIO()
- title = self.name + ' colormap'
- author = f'Matplotlib v{mpl.__version__}, https://matplotlib.org'
- pnginfo = PngInfo()
- pnginfo.add_text('Title', title)
- pnginfo.add_text('Description', title)
- pnginfo.add_text('Author', author)
- pnginfo.add_text('Software', author)
- Image.fromarray(pixels).save(png_bytes, format='png', pnginfo=pnginfo)
- return png_bytes.getvalue()
-
- def _repr_html_(self):
- """Generate an HTML representation of the Colormap."""
- png_bytes = self._repr_png_()
- png_base64 = base64.b64encode(png_bytes).decode('ascii')
- def color_block(color):
- hex_color = to_hex(color, keep_alpha=True)
- return (f'<div title="{hex_color}" '
- 'style="display: inline-block; '
- 'width: 1em; height: 1em; '
- 'margin: 0; '
- 'vertical-align: middle; '
- 'border: 1px solid #555; '
- f'background-color: {hex_color};"></div>')
-
- return ('<div style="vertical-align: middle;">'
- f'<strong>{self.name}</strong> '
- '</div>'
- '<div class="cmap"><img '
- f'alt="{self.name} colormap" '
- f'title="{self.name}" '
- 'style="border: 1px solid #555;" '
- f'src="data:image/png;base64,{png_base64}"></div>'
- '<div style="vertical-align: middle; '
- f'max-width: {_REPR_PNG_SIZE[0]+2}px; '
- 'display: flex; justify-content: space-between;">'
- '<div style="float: left;">'
- f'{color_block(self.get_under())} under'
- '</div>'
- '<div style="margin: 0 auto; display: inline-block;">'
- f'bad {color_block(self.get_bad())}'
- '</div>'
- '<div style="float: right;">'
- f'over {color_block(self.get_over())}'
- '</div>')
-
- def copy(self):
- """Return a copy of the colormap."""
- return self.__copy__()
-
-
-class LinearSegmentedColormap(Colormap):
- """
- Colormap objects based on lookup tables using linear segments.
-
- The lookup table is generated using linear interpolation for each
- primary color, with the 0-1 domain divided into any number of
- segments.
- """
-
- def __init__(self, name, segmentdata, N=256, gamma=1.0):
- """
- Create colormap from linear mapping segments
-
- segmentdata argument is a dictionary with a red, green and blue
- entries. Each entry should be a list of *x*, *y0*, *y1* tuples,
- forming rows in a table. Entries for alpha are optional.
-
- Example: suppose you want red to increase from 0 to 1 over
- the bottom half, green to do the same over the middle half,
- and blue over the top half. Then you would use::
-
- cdict = {'red': [(0.0, 0.0, 0.0),
- (0.5, 1.0, 1.0),
- (1.0, 1.0, 1.0)],
-
- 'green': [(0.0, 0.0, 0.0),
- (0.25, 0.0, 0.0),
- (0.75, 1.0, 1.0),
- (1.0, 1.0, 1.0)],
-
- 'blue': [(0.0, 0.0, 0.0),
- (0.5, 0.0, 0.0),
- (1.0, 1.0, 1.0)]}
-
- Each row in the table for a given color is a sequence of
- *x*, *y0*, *y1* tuples. In each sequence, *x* must increase
- monotonically from 0 to 1. For any input value *z* falling
- between *x[i]* and *x[i+1]*, the output value of a given color
- will be linearly interpolated between *y1[i]* and *y0[i+1]*::
-
- row i: x y0 y1
- /
- /
- row i+1: x y0 y1
-
- Hence y0 in the first row and y1 in the last row are never used.
-
- See Also
- --------
- LinearSegmentedColormap.from_list
- Static method; factory function for generating a smoothly-varying
- LinearSegmentedColormap.
- """
- # True only if all colors in map are identical; needed for contouring.
- self.monochrome = False
- super().__init__(name, N)
- self._segmentdata = segmentdata
- self._gamma = gamma
-
- def _init(self):
- self._lut = np.ones((self.N + 3, 4), float)
- self._lut[:-3, 0] = _create_lookup_table(
- self.N, self._segmentdata['red'], self._gamma)
- self._lut[:-3, 1] = _create_lookup_table(
- self.N, self._segmentdata['green'], self._gamma)
- self._lut[:-3, 2] = _create_lookup_table(
- self.N, self._segmentdata['blue'], self._gamma)
- if 'alpha' in self._segmentdata:
- self._lut[:-3, 3] = _create_lookup_table(
- self.N, self._segmentdata['alpha'], 1)
- self._isinit = True
- self._set_extremes()
-
- def set_gamma(self, gamma):
- """Set a new gamma value and regenerate colormap."""
- self._gamma = gamma
- self._init()
-
- @staticmethod
- def from_list(name, colors, N=256, gamma=1.0):
- """
- Create a `LinearSegmentedColormap` from a list of colors.
-
- Parameters
- ----------
- name : str
- The name of the colormap.
- colors : array-like of colors or array-like of (value, color)
- If only colors are given, they are equidistantly mapped from the
- range :math:`[0, 1]`; i.e. 0 maps to ``colors[0]`` and 1 maps to
- ``colors[-1]``.
- If (value, color) pairs are given, the mapping is from *value*
- to *color*. This can be used to divide the range unevenly.
- N : int
- The number of RGB quantization levels.
- gamma : float
- """
- if not np.iterable(colors):
- raise ValueError('colors must be iterable')
-
- if (isinstance(colors[0], Sized) and len(colors[0]) == 2
- and not isinstance(colors[0], str)):
- # List of value, color pairs
- vals, colors = zip(*colors)
- else:
- vals = np.linspace(0, 1, len(colors))
-
- r, g, b, a = to_rgba_array(colors).T
- cdict = {
- "red": np.column_stack([vals, r, r]),
- "green": np.column_stack([vals, g, g]),
- "blue": np.column_stack([vals, b, b]),
- "alpha": np.column_stack([vals, a, a]),
- }
-
- return LinearSegmentedColormap(name, cdict, N, gamma)
-
- def resampled(self, lutsize):
- """Return a new colormap with *lutsize* entries."""
- new_cmap = LinearSegmentedColormap(self.name, self._segmentdata,
- lutsize)
- new_cmap._rgba_over = self._rgba_over
- new_cmap._rgba_under = self._rgba_under
- new_cmap._rgba_bad = self._rgba_bad
- return new_cmap
-
- # Helper ensuring picklability of the reversed cmap.
- @staticmethod
- def _reverser(func, x):
- return func(1 - x)
-
- def reversed(self, name=None):
- """
- Return a reversed instance of the Colormap.
-
- Parameters
- ----------
- name : str, optional
- The name for the reversed colormap. If None, the
- name is set to ``self.name + "_r"``.
-
- Returns
- -------
- LinearSegmentedColormap
- The reversed colormap.
- """
- if name is None:
- name = self.name + "_r"
-
- # Using a partial object keeps the cmap picklable.
- data_r = {key: (functools.partial(self._reverser, data)
- if callable(data) else
- [(1.0 - x, y1, y0) for x, y0, y1 in reversed(data)])
- for key, data in self._segmentdata.items()}
-
- new_cmap = LinearSegmentedColormap(name, data_r, self.N, self._gamma)
- # Reverse the over/under values too
- new_cmap._rgba_over = self._rgba_under
- new_cmap._rgba_under = self._rgba_over
- new_cmap._rgba_bad = self._rgba_bad
- return new_cmap
-
-
-class ListedColormap(Colormap):
- """
- Colormap object generated from a list of colors.
-
- This may be most useful when indexing directly into a colormap,
- but it can also be used to generate special colormaps for ordinary
- mapping.
-
- Parameters
- ----------
- colors : list, array
- Sequence of Matplotlib color specifications (color names or RGB(A)
- values).
- name : str, optional
- String to identify the colormap.
- N : int, optional
- Number of entries in the map. The default is *None*, in which case
- there is one colormap entry for each element in the list of colors.
- If ::
-
- N < len(colors)
-
- the list will be truncated at *N*. If ::
-
- N > len(colors)
-
- the list will be extended by repetition.
- """
- def __init__(self, colors, name='from_list', N=None):
- self.monochrome = False # Are all colors identical? (for contour.py)
- if N is None:
- self.colors = colors
- N = len(colors)
- else:
- if isinstance(colors, str):
- self.colors = [colors] * N
- self.monochrome = True
- elif np.iterable(colors):
- if len(colors) == 1:
- self.monochrome = True
- self.colors = list(
- itertools.islice(itertools.cycle(colors), N))
- else:
- try:
- gray = float(colors)
- except TypeError:
- pass
- else:
- self.colors = [gray] * N
- self.monochrome = True
- super().__init__(name, N)
-
- def _init(self):
- self._lut = np.zeros((self.N + 3, 4), float)
- self._lut[:-3] = to_rgba_array(self.colors)
- self._isinit = True
- self._set_extremes()
-
- def resampled(self, lutsize):
- """Return a new colormap with *lutsize* entries."""
- colors = self(np.linspace(0, 1, lutsize))
- new_cmap = ListedColormap(colors, name=self.name)
- # Keep the over/under values too
- new_cmap._rgba_over = self._rgba_over
- new_cmap._rgba_under = self._rgba_under
- new_cmap._rgba_bad = self._rgba_bad
- return new_cmap
-
- def reversed(self, name=None):
- """
- Return a reversed instance of the Colormap.
-
- Parameters
- ----------
- name : str, optional
- The name for the reversed colormap. If None, the
- name is set to ``self.name + "_r"``.
-
- Returns
- -------
- ListedColormap
- A reversed instance of the colormap.
- """
- if name is None:
- name = self.name + "_r"
-
- colors_r = list(reversed(self.colors))
- new_cmap = ListedColormap(colors_r, name=name, N=self.N)
- # Reverse the over/under values too
- new_cmap._rgba_over = self._rgba_under
- new_cmap._rgba_under = self._rgba_over
- new_cmap._rgba_bad = self._rgba_bad
- return new_cmap
-
-
-class Normalize:
- """
- A class which, when called, linearly normalizes data into the
- ``[0.0, 1.0]`` interval.
- """
-
- def __init__(self, vmin=None, vmax=None, clip=False):
- """
- Parameters
- ----------
- vmin, vmax : float or None
- If *vmin* and/or *vmax* is not given, they are initialized from the
- minimum and maximum value, respectively, of the first input
- processed; i.e., ``__call__(A)`` calls ``autoscale_None(A)``.
-
- clip : bool, default: False
- Determines the behavior for mapping values outside the range
- ``[vmin, vmax]``.
-
- If clipping is off, values outside the range ``[vmin, vmax]`` are also
- transformed linearly, resulting in values outside ``[0, 1]``. For a
- standard use with colormaps, this behavior is desired because colormaps
- mark these outside values with specific colors for *over* or *under*.
-
- If ``True`` values falling outside the range ``[vmin, vmax]``,
- are mapped to 0 or 1, whichever is closer. This makes these values
- indistinguishable from regular boundary values and can lead to
- misinterpretation of the data.
-
- Notes
- -----
- Returns 0 if ``vmin == vmax``.
- """
- self._vmin = _sanitize_extrema(vmin)
- self._vmax = _sanitize_extrema(vmax)
- self._clip = clip
- self._scale = None
- self.callbacks = cbook.CallbackRegistry(signals=["changed"])
-
- @property
- def vmin(self):
- return self._vmin
-
- @vmin.setter
- def vmin(self, value):
- value = _sanitize_extrema(value)
- if value != self._vmin:
- self._vmin = value
- self._changed()
-
- @property
- def vmax(self):
- return self._vmax
-
- @vmax.setter
- def vmax(self, value):
- value = _sanitize_extrema(value)
- if value != self._vmax:
- self._vmax = value
- self._changed()
-
- @property
- def clip(self):
- return self._clip
-
- @clip.setter
- def clip(self, value):
- if value != self._clip:
- self._clip = value
- self._changed()
-
- def _changed(self):
- """
- Call this whenever the norm is changed to notify all the
- callback listeners to the 'changed' signal.
- """
- self.callbacks.process('changed')
-
- @staticmethod
- def process_value(value):
- """
- Homogenize the input *value* for easy and efficient normalization.
-
- *value* can be a scalar or sequence.
-
- Returns
- -------
- result : masked array
- Masked array with the same shape as *value*.
- is_scalar : bool
- Whether *value* is a scalar.
-
- Notes
- -----
- Float dtypes are preserved; integer types with two bytes or smaller are
- converted to np.float32, and larger types are converted to np.float64.
- Preserving float32 when possible, and using in-place operations,
- greatly improves speed for large arrays.
- """
- is_scalar = not np.iterable(value)
- if is_scalar:
- value = [value]
- dtype = np.min_scalar_type(value)
- if np.issubdtype(dtype, np.integer) or dtype.type is np.bool_:
- # bool_/int8/int16 -> float32; int32/int64 -> float64
- dtype = np.promote_types(dtype, np.float32)
- # ensure data passed in as an ndarray subclass are interpreted as
- # an ndarray. See issue #6622.
- mask = np.ma.getmask(value)
- data = np.asarray(value)
- result = np.ma.array(data, mask=mask, dtype=dtype, copy=True)
- return result, is_scalar
-
- def __call__(self, value, clip=None):
- """
- Normalize *value* data in the ``[vmin, vmax]`` interval into the
- ``[0.0, 1.0]`` interval and return it.
-
- Parameters
- ----------
- value
- Data to normalize.
- clip : bool, optional
- See the description of the parameter *clip* in `.Normalize`.
-
- If ``None``, defaults to ``self.clip`` (which defaults to
- ``False``).
-
- Notes
- -----
- If not already initialized, ``self.vmin`` and ``self.vmax`` are
- initialized using ``self.autoscale_None(value)``.
- """
- if clip is None:
- clip = self.clip
-
- result, is_scalar = self.process_value(value)
-
- if self.vmin is None or self.vmax is None:
- self.autoscale_None(result)
- # Convert at least to float, without losing precision.
- (vmin,), _ = self.process_value(self.vmin)
- (vmax,), _ = self.process_value(self.vmax)
- if vmin == vmax:
- result.fill(0) # Or should it be all masked? Or 0.5?
- elif vmin > vmax:
- raise ValueError("minvalue must be less than or equal to maxvalue")
- else:
- if clip:
- mask = np.ma.getmask(result)
- result = np.ma.array(np.clip(result.filled(vmax), vmin, vmax),
- mask=mask)
- # ma division is very slow; we can take a shortcut
- resdat = result.data
- resdat -= vmin
- resdat /= (vmax - vmin)
- result = np.ma.array(resdat, mask=result.mask, copy=False)
- if is_scalar:
- result = result[0]
- return result
-
- def inverse(self, value):
- if not self.scaled():
- raise ValueError("Not invertible until both vmin and vmax are set")
- (vmin,), _ = self.process_value(self.vmin)
- (vmax,), _ = self.process_value(self.vmax)
-
- if np.iterable(value):
- val = np.ma.asarray(value)
- return vmin + val * (vmax - vmin)
- else:
- return vmin + value * (vmax - vmin)
-
- def autoscale(self, A):
- """Set *vmin*, *vmax* to min, max of *A*."""
- with self.callbacks.blocked():
- # Pause callbacks while we are updating so we only get
- # a single update signal at the end
- self.vmin = self.vmax = None
- self.autoscale_None(A)
- self._changed()
-
- def autoscale_None(self, A):
- """If vmin or vmax are not set, use the min/max of *A* to set them."""
- A = np.asanyarray(A)
-
- if isinstance(A, np.ma.MaskedArray):
- # we need to make the distinction between an array, False, np.bool_(False)
- if A.mask is False or not A.mask.shape:
- A = A.data
-
- if self.vmin is None and A.size:
- self.vmin = A.min()
- if self.vmax is None and A.size:
- self.vmax = A.max()
-
- def scaled(self):
- """Return whether vmin and vmax are set."""
- return self.vmin is not None and self.vmax is not None
-
-
-class TwoSlopeNorm(Normalize):
- def __init__(self, vcenter, vmin=None, vmax=None):
- """
- Normalize data with a set center.
-
- Useful when mapping data with an unequal rates of change around a
- conceptual center, e.g., data that range from -2 to 4, with 0 as
- the midpoint.
-
- Parameters
- ----------
- vcenter : float
- The data value that defines ``0.5`` in the normalization.
- vmin : float, optional
- The data value that defines ``0.0`` in the normalization.
- Defaults to the min value of the dataset.
- vmax : float, optional
- The data value that defines ``1.0`` in the normalization.
- Defaults to the max value of the dataset.
-
- Examples
- --------
- This maps data value -4000 to 0., 0 to 0.5, and +10000 to 1.0; data
- between is linearly interpolated::
-
- >>> import matplotlib.colors as mcolors
- >>> offset = mcolors.TwoSlopeNorm(vmin=-4000.,
- vcenter=0., vmax=10000)
- >>> data = [-4000., -2000., 0., 2500., 5000., 7500., 10000.]
- >>> offset(data)
- array([0., 0.25, 0.5, 0.625, 0.75, 0.875, 1.0])
- """
-
- super().__init__(vmin=vmin, vmax=vmax)
- self._vcenter = vcenter
- if vcenter is not None and vmax is not None and vcenter >= vmax:
- raise ValueError('vmin, vcenter, and vmax must be in '
- 'ascending order')
- if vcenter is not None and vmin is not None and vcenter <= vmin:
- raise ValueError('vmin, vcenter, and vmax must be in '
- 'ascending order')
-
- @property
- def vcenter(self):
- return self._vcenter
-
- @vcenter.setter
- def vcenter(self, value):
- if value != self._vcenter:
- self._vcenter = value
- self._changed()
-
- def autoscale_None(self, A):
- """
- Get vmin and vmax.
-
- If vcenter isn't in the range [vmin, vmax], either vmin or vmax
- is expanded so that vcenter lies in the middle of the modified range
- [vmin, vmax].
- """
- super().autoscale_None(A)
- if self.vmin >= self.vcenter:
- self.vmin = self.vcenter - (self.vmax - self.vcenter)
- if self.vmax <= self.vcenter:
- self.vmax = self.vcenter + (self.vcenter - self.vmin)
-
- def __call__(self, value, clip=None):
- """
- Map value to the interval [0, 1]. The *clip* argument is unused.
- """
- result, is_scalar = self.process_value(value)
- self.autoscale_None(result) # sets self.vmin, self.vmax if None
-
- if not self.vmin <= self.vcenter <= self.vmax:
- raise ValueError("vmin, vcenter, vmax must increase monotonically")
- # note that we must extrapolate for tick locators:
- result = np.ma.masked_array(
- np.interp(result, [self.vmin, self.vcenter, self.vmax],
- [0, 0.5, 1], left=-np.inf, right=np.inf),
- mask=np.ma.getmask(result))
- if is_scalar:
- result = np.atleast_1d(result)[0]
- return result
-
- def inverse(self, value):
- if not self.scaled():
- raise ValueError("Not invertible until both vmin and vmax are set")
- (vmin,), _ = self.process_value(self.vmin)
- (vmax,), _ = self.process_value(self.vmax)
- (vcenter,), _ = self.process_value(self.vcenter)
- result = np.interp(value, [0, 0.5, 1], [vmin, vcenter, vmax],
- left=-np.inf, right=np.inf)
- return result
-
-
-class CenteredNorm(Normalize):
- def __init__(self, vcenter=0, halfrange=None, clip=False):
- """
- Normalize symmetrical data around a center (0 by default).
-
- Unlike `TwoSlopeNorm`, `CenteredNorm` applies an equal rate of change
- around the center.
-
- Useful when mapping symmetrical data around a conceptual center
- e.g., data that range from -2 to 4, with 0 as the midpoint, and
- with equal rates of change around that midpoint.
-
- Parameters
- ----------
- vcenter : float, default: 0
- The data value that defines ``0.5`` in the normalization.
- halfrange : float, optional
- The range of data values that defines a range of ``0.5`` in the
- normalization, so that *vcenter* - *halfrange* is ``0.0`` and
- *vcenter* + *halfrange* is ``1.0`` in the normalization.
- Defaults to the largest absolute difference to *vcenter* for
- the values in the dataset.
- clip : bool, default: False
- Determines the behavior for mapping values outside the range
- ``[vmin, vmax]``.
-
- If clipping is off, values outside the range ``[vmin, vmax]`` are also
- transformed, resulting in values outside ``[0, 1]``. For a
- standard use with colormaps, this behavior is desired because colormaps
- mark these outside values with specific colors for *over* or *under*.
-
- If ``True`` values falling outside the range ``[vmin, vmax]``,
- are mapped to 0 or 1, whichever is closer. This makes these values
- indistinguishable from regular boundary values and can lead to
- misinterpretation of the data.
-
- Examples
- --------
- This maps data values -2 to 0.25, 0 to 0.5, and 4 to 1.0
- (assuming equal rates of change above and below 0.0):
-
- >>> import matplotlib.colors as mcolors
- >>> norm = mcolors.CenteredNorm(halfrange=4.0)
- >>> data = [-2., 0., 4.]
- >>> norm(data)
- array([0.25, 0.5 , 1. ])
- """
- super().__init__(vmin=None, vmax=None, clip=clip)
- self._vcenter = vcenter
- # calling the halfrange setter to set vmin and vmax
- self.halfrange = halfrange
-
- def autoscale(self, A):
- """
- Set *halfrange* to ``max(abs(A-vcenter))``, then set *vmin* and *vmax*.
- """
- A = np.asanyarray(A)
- self.halfrange = max(self._vcenter-A.min(),
- A.max()-self._vcenter)
-
- def autoscale_None(self, A):
- """Set *vmin* and *vmax*."""
- A = np.asanyarray(A)
- if self.halfrange is None and A.size:
- self.autoscale(A)
-
- @property
- def vmin(self):
- return self._vmin
-
- @vmin.setter
- def vmin(self, value):
- value = _sanitize_extrema(value)
- if value != self._vmin:
- self._vmin = value
- self._vmax = 2*self.vcenter - value
- self._changed()
-
- @property
- def vmax(self):
- return self._vmax
-
- @vmax.setter
- def vmax(self, value):
- value = _sanitize_extrema(value)
- if value != self._vmax:
- self._vmax = value
- self._vmin = 2*self.vcenter - value
- self._changed()
-
- @property
- def vcenter(self):
- return self._vcenter
-
- @vcenter.setter
- def vcenter(self, vcenter):
- if vcenter != self._vcenter:
- self._vcenter = vcenter
- # Trigger an update of the vmin/vmax values through the setter
- self.halfrange = self.halfrange
- self._changed()
-
- @property
- def halfrange(self):
- if self.vmin is None or self.vmax is None:
- return None
- return (self.vmax - self.vmin) / 2
-
- @halfrange.setter
- def halfrange(self, halfrange):
- if halfrange is None:
- self.vmin = None
- self.vmax = None
- else:
- self.vmin = self.vcenter - abs(halfrange)
- self.vmax = self.vcenter + abs(halfrange)
-
-
-def make_norm_from_scale(scale_cls, base_norm_cls=None, *, init=None):
- """
- Decorator for building a `.Normalize` subclass from a `~.scale.ScaleBase`
- subclass.
-
- After ::
-
- @make_norm_from_scale(scale_cls)
- class norm_cls(Normalize):
- ...
-
- *norm_cls* is filled with methods so that normalization computations are
- forwarded to *scale_cls* (i.e., *scale_cls* is the scale that would be used
- for the colorbar of a mappable normalized with *norm_cls*).
-
- If *init* is not passed, then the constructor signature of *norm_cls*
- will be ``norm_cls(vmin=None, vmax=None, clip=False)``; these three
- parameters will be forwarded to the base class (``Normalize.__init__``),
- and a *scale_cls* object will be initialized with no arguments (other than
- a dummy axis).
-
- If the *scale_cls* constructor takes additional parameters, then *init*
- should be passed to `make_norm_from_scale`. It is a callable which is
- *only* used for its signature. First, this signature will become the
- signature of *norm_cls*. Second, the *norm_cls* constructor will bind the
- parameters passed to it using this signature, extract the bound *vmin*,
- *vmax*, and *clip* values, pass those to ``Normalize.__init__``, and
- forward the remaining bound values (including any defaults defined by the
- signature) to the *scale_cls* constructor.
- """
-
- if base_norm_cls is None:
- return functools.partial(make_norm_from_scale, scale_cls, init=init)
-
- if isinstance(scale_cls, functools.partial):
- scale_args = scale_cls.args
- scale_kwargs_items = tuple(scale_cls.keywords.items())
- scale_cls = scale_cls.func
- else:
- scale_args = scale_kwargs_items = ()
-
- if init is None:
- def init(vmin=None, vmax=None, clip=False): pass
-
- return _make_norm_from_scale(
- scale_cls, scale_args, scale_kwargs_items,
- base_norm_cls, inspect.signature(init))
-
-
-@functools.cache
-def _make_norm_from_scale(
- scale_cls, scale_args, scale_kwargs_items,
- base_norm_cls, bound_init_signature,
-):
- """
- Helper for `make_norm_from_scale`.
-
- This function is split out to enable caching (in particular so that
- different unpickles reuse the same class). In order to do so,
-
- - ``functools.partial`` *scale_cls* is expanded into ``func, args, kwargs``
- to allow memoizing returned norms (partial instances always compare
- unequal, but we can check identity based on ``func, args, kwargs``;
- - *init* is replaced by *init_signature*, as signatures are picklable,
- unlike to arbitrary lambdas.
- """
-
- class Norm(base_norm_cls):
- def __reduce__(self):
- cls = type(self)
- # If the class is toplevel-accessible, it is possible to directly
- # pickle it "by name". This is required to support norm classes
- # defined at a module's toplevel, as the inner base_norm_cls is
- # otherwise unpicklable (as it gets shadowed by the generated norm
- # class). If either import or attribute access fails, fall back to
- # the general path.
- try:
- if cls is getattr(importlib.import_module(cls.__module__),
- cls.__qualname__):
- return (_create_empty_object_of_class, (cls,), vars(self))
- except (ImportError, AttributeError):
- pass
- return (_picklable_norm_constructor,
- (scale_cls, scale_args, scale_kwargs_items,
- base_norm_cls, bound_init_signature),
- vars(self))
-
- def __init__(self, *args, **kwargs):
- ba = bound_init_signature.bind(*args, **kwargs)
- ba.apply_defaults()
- super().__init__(
- **{k: ba.arguments.pop(k) for k in ["vmin", "vmax", "clip"]})
- self._scale = functools.partial(
- scale_cls, *scale_args, **dict(scale_kwargs_items))(
- axis=None, **ba.arguments)
- self._trf = self._scale.get_transform()
-
- __init__.__signature__ = bound_init_signature.replace(parameters=[
- inspect.Parameter("self", inspect.Parameter.POSITIONAL_OR_KEYWORD),
- *bound_init_signature.parameters.values()])
-
- def __call__(self, value, clip=None):
- value, is_scalar = self.process_value(value)
- if self.vmin is None or self.vmax is None:
- self.autoscale_None(value)
- if self.vmin > self.vmax:
- raise ValueError("vmin must be less or equal to vmax")
- if self.vmin == self.vmax:
- return np.full_like(value, 0)
- if clip is None:
- clip = self.clip
- if clip:
- value = np.clip(value, self.vmin, self.vmax)
- t_value = self._trf.transform(value).reshape(np.shape(value))
- t_vmin, t_vmax = self._trf.transform([self.vmin, self.vmax])
- if not np.isfinite([t_vmin, t_vmax]).all():
- raise ValueError("Invalid vmin or vmax")
- t_value -= t_vmin
- t_value /= (t_vmax - t_vmin)
- t_value = np.ma.masked_invalid(t_value, copy=False)
- return t_value[0] if is_scalar else t_value
-
- def inverse(self, value):
- if not self.scaled():
- raise ValueError("Not invertible until scaled")
- if self.vmin > self.vmax:
- raise ValueError("vmin must be less or equal to vmax")
- t_vmin, t_vmax = self._trf.transform([self.vmin, self.vmax])
- if not np.isfinite([t_vmin, t_vmax]).all():
- raise ValueError("Invalid vmin or vmax")
- value, is_scalar = self.process_value(value)
- rescaled = value * (t_vmax - t_vmin)
- rescaled += t_vmin
- value = (self._trf
- .inverted()
- .transform(rescaled)
- .reshape(np.shape(value)))
- return value[0] if is_scalar else value
-
- def autoscale_None(self, A):
- # i.e. A[np.isfinite(...)], but also for non-array A's
- in_trf_domain = np.extract(np.isfinite(self._trf.transform(A)), A)
- if in_trf_domain.size == 0:
- in_trf_domain = np.ma.masked
- return super().autoscale_None(in_trf_domain)
-
- if base_norm_cls is Normalize:
- Norm.__name__ = f"{scale_cls.__name__}Norm"
- Norm.__qualname__ = f"{scale_cls.__qualname__}Norm"
- else:
- Norm.__name__ = base_norm_cls.__name__
- Norm.__qualname__ = base_norm_cls.__qualname__
- Norm.__module__ = base_norm_cls.__module__
- Norm.__doc__ = base_norm_cls.__doc__
-
- return Norm
-
-
-def _create_empty_object_of_class(cls):
- return cls.__new__(cls)
-
-
-def _picklable_norm_constructor(*args):
- return _create_empty_object_of_class(_make_norm_from_scale(*args))
-
-
-@make_norm_from_scale(
- scale.FuncScale,
- init=lambda functions, vmin=None, vmax=None, clip=False: None)
-class FuncNorm(Normalize):
- """
- Arbitrary normalization using functions for the forward and inverse.
-
- Parameters
- ----------
- functions : (callable, callable)
- two-tuple of the forward and inverse functions for the normalization.
- The forward function must be monotonic.
-
- Both functions must have the signature ::
-
- def forward(values: array-like) -> array-like
-
- vmin, vmax : float or None
- If *vmin* and/or *vmax* is not given, they are initialized from the
- minimum and maximum value, respectively, of the first input
- processed; i.e., ``__call__(A)`` calls ``autoscale_None(A)``.
-
- clip : bool, default: False
- Determines the behavior for mapping values outside the range
- ``[vmin, vmax]``.
-
- If clipping is off, values outside the range ``[vmin, vmax]`` are also
- transformed by the function, resulting in values outside ``[0, 1]``. For a
- standard use with colormaps, this behavior is desired because colormaps
- mark these outside values with specific colors for *over* or *under*.
-
- If ``True`` values falling outside the range ``[vmin, vmax]``,
- are mapped to 0 or 1, whichever is closer. This makes these values
- indistinguishable from regular boundary values and can lead to
- misinterpretation of the data.
- """
-
-
-LogNorm = make_norm_from_scale(
- functools.partial(scale.LogScale, nonpositive="mask"))(Normalize)
-LogNorm.__name__ = LogNorm.__qualname__ = "LogNorm"
-LogNorm.__doc__ = "Normalize a given value to the 0-1 range on a log scale."
-
-
-@make_norm_from_scale(
- scale.SymmetricalLogScale,
- init=lambda linthresh, linscale=1., vmin=None, vmax=None, clip=False, *,
- base=10: None)
-class SymLogNorm(Normalize):
- """
- The symmetrical logarithmic scale is logarithmic in both the
- positive and negative directions from the origin.
-
- Since the values close to zero tend toward infinity, there is a
- need to have a range around zero that is linear. The parameter
- *linthresh* allows the user to specify the size of this range
- (-*linthresh*, *linthresh*).
-
- Parameters
- ----------
- linthresh : float
- The range within which the plot is linear (to avoid having the plot
- go to infinity around zero).
- linscale : float, default: 1
- This allows the linear range (-*linthresh* to *linthresh*) to be
- stretched relative to the logarithmic range. Its value is the
- number of decades to use for each half of the linear range. For
- example, when *linscale* == 1.0 (the default), the space used for
- the positive and negative halves of the linear range will be equal
- to one decade in the logarithmic range.
- base : float, default: 10
- """
-
- @property
- def linthresh(self):
- return self._scale.linthresh
-
- @linthresh.setter
- def linthresh(self, value):
- self._scale.linthresh = value
-
-
-@make_norm_from_scale(
- scale.AsinhScale,
- init=lambda linear_width=1, vmin=None, vmax=None, clip=False: None)
-class AsinhNorm(Normalize):
- """
- The inverse hyperbolic sine scale is approximately linear near
- the origin, but becomes logarithmic for larger positive
- or negative values. Unlike the `SymLogNorm`, the transition between
- these linear and logarithmic regions is smooth, which may reduce
- the risk of visual artifacts.
-
- .. note::
-
- This API is provisional and may be revised in the future
- based on early user feedback.
-
- Parameters
- ----------
- linear_width : float, default: 1
- The effective width of the linear region, beyond which
- the transformation becomes asymptotically logarithmic
- """
-
- @property
- def linear_width(self):
- return self._scale.linear_width
-
- @linear_width.setter
- def linear_width(self, value):
- self._scale.linear_width = value
-
-
-class PowerNorm(Normalize):
- r"""
- Linearly map a given value to the 0-1 range and then apply
- a power-law normalization over that range.
-
- Parameters
- ----------
- gamma : float
- Power law exponent.
- vmin, vmax : float or None
- If *vmin* and/or *vmax* is not given, they are initialized from the
- minimum and maximum value, respectively, of the first input
- processed; i.e., ``__call__(A)`` calls ``autoscale_None(A)``.
- clip : bool, default: False
- Determines the behavior for mapping values outside the range
- ``[vmin, vmax]``.
-
- If clipping is off, values outside the range ``[vmin, vmax]`` are also
- transformed by the power function, resulting in values outside ``[0, 1]``. For
- a standard use with colormaps, this behavior is desired because colormaps
- mark these outside values with specific colors for *over* or *under*.
-
- If ``True`` values falling outside the range ``[vmin, vmax]``,
- are mapped to 0 or 1, whichever is closer. This makes these values
- indistinguishable from regular boundary values and can lead to
- misinterpretation of the data.
-
- Notes
- -----
- The normalization formula is
-
- .. math::
-
- \left ( \frac{x - v_{min}}{v_{max} - v_{min}} \right )^{\gamma}
- """
- def __init__(self, gamma, vmin=None, vmax=None, clip=False):
- super().__init__(vmin, vmax, clip)
- self.gamma = gamma
-
- def __call__(self, value, clip=None):
- if clip is None:
- clip = self.clip
-
- result, is_scalar = self.process_value(value)
-
- self.autoscale_None(result)
- gamma = self.gamma
- vmin, vmax = self.vmin, self.vmax
- if vmin > vmax:
- raise ValueError("minvalue must be less than or equal to maxvalue")
- elif vmin == vmax:
- result.fill(0)
- else:
- if clip:
- mask = np.ma.getmask(result)
- result = np.ma.array(np.clip(result.filled(vmax), vmin, vmax),
- mask=mask)
- resdat = result.data
- resdat -= vmin
- resdat[resdat < 0] = 0
- np.power(resdat, gamma, resdat)
- resdat /= (vmax - vmin) ** gamma
-
- result = np.ma.array(resdat, mask=result.mask, copy=False)
- if is_scalar:
- result = result[0]
- return result
-
- def inverse(self, value):
- if not self.scaled():
- raise ValueError("Not invertible until scaled")
- gamma = self.gamma
- vmin, vmax = self.vmin, self.vmax
-
- if np.iterable(value):
- val = np.ma.asarray(value)
- return np.ma.power(val, 1. / gamma) * (vmax - vmin) + vmin
- else:
- return pow(value, 1. / gamma) * (vmax - vmin) + vmin
-
-
-class BoundaryNorm(Normalize):
- """
- Generate a colormap index based on discrete intervals.
-
- Unlike `Normalize` or `LogNorm`, `BoundaryNorm` maps values to integers
- instead of to the interval 0-1.
- """
-
- # Mapping to the 0-1 interval could have been done via piece-wise linear
- # interpolation, but using integers seems simpler, and reduces the number
- # of conversions back and forth between int and float.
-
- def __init__(self, boundaries, ncolors, clip=False, *, extend='neither'):
- """
- Parameters
- ----------
- boundaries : array-like
- Monotonically increasing sequence of at least 2 bin edges: data
- falling in the n-th bin will be mapped to the n-th color.
-
- ncolors : int
- Number of colors in the colormap to be used.
-
- clip : bool, optional
- If clip is ``True``, out of range values are mapped to 0 if they
- are below ``boundaries[0]`` or mapped to ``ncolors - 1`` if they
- are above ``boundaries[-1]``.
-
- If clip is ``False``, out of range values are mapped to -1 if
- they are below ``boundaries[0]`` or mapped to *ncolors* if they are
- above ``boundaries[-1]``. These are then converted to valid indices
- by `Colormap.__call__`.
-
- extend : {'neither', 'both', 'min', 'max'}, default: 'neither'
- Extend the number of bins to include one or both of the
- regions beyond the boundaries. For example, if ``extend``
- is 'min', then the color to which the region between the first
- pair of boundaries is mapped will be distinct from the first
- color in the colormap, and by default a
- `~matplotlib.colorbar.Colorbar` will be drawn with
- the triangle extension on the left or lower end.
-
- Notes
- -----
- If there are fewer bins (including extensions) than colors, then the
- color index is chosen by linearly interpolating the ``[0, nbins - 1]``
- range onto the ``[0, ncolors - 1]`` range, effectively skipping some
- colors in the middle of the colormap.
- """
- if clip and extend != 'neither':
- raise ValueError("'clip=True' is not compatible with 'extend'")
- super().__init__(vmin=boundaries[0], vmax=boundaries[-1], clip=clip)
- self.boundaries = np.asarray(boundaries)
- self.N = len(self.boundaries)
- if self.N < 2:
- raise ValueError("You must provide at least 2 boundaries "
- f"(1 region) but you passed in {boundaries!r}")
- self.Ncmap = ncolors
- self.extend = extend
-
- self._scale = None # don't use the default scale.
-
- self._n_regions = self.N - 1 # number of colors needed
- self._offset = 0
- if extend in ('min', 'both'):
- self._n_regions += 1
- self._offset = 1
- if extend in ('max', 'both'):
- self._n_regions += 1
- if self._n_regions > self.Ncmap:
- raise ValueError(f"There are {self._n_regions} color bins "
- "including extensions, but ncolors = "
- f"{ncolors}; ncolors must equal or exceed the "
- "number of bins")
-
- def __call__(self, value, clip=None):
- """
- This method behaves similarly to `.Normalize.__call__`, except that it
- returns integers or arrays of int16.
- """
- if clip is None:
- clip = self.clip
-
- xx, is_scalar = self.process_value(value)
- mask = np.ma.getmaskarray(xx)
- # Fill masked values a value above the upper boundary
- xx = np.atleast_1d(xx.filled(self.vmax + 1))
- if clip:
- np.clip(xx, self.vmin, self.vmax, out=xx)
- max_col = self.Ncmap - 1
- else:
- max_col = self.Ncmap
- # this gives us the bins in the lookup table in the range
- # [0, _n_regions - 1] (the offset is set in the init)
- iret = np.digitize(xx, self.boundaries) - 1 + self._offset
- # if we have more colors than regions, stretch the region
- # index computed above to full range of the color bins. This
- # will make use of the full range (but skip some of the colors
- # in the middle) such that the first region is mapped to the
- # first color and the last region is mapped to the last color.
- if self.Ncmap > self._n_regions:
- if self._n_regions == 1:
- # special case the 1 region case, pick the middle color
- iret[iret == 0] = (self.Ncmap - 1) // 2
- else:
- # otherwise linearly remap the values from the region index
- # to the color index spaces
- iret = (self.Ncmap - 1) / (self._n_regions - 1) * iret
- # cast to 16bit integers in all cases
- iret = iret.astype(np.int16)
- iret[xx < self.vmin] = -1
- iret[xx >= self.vmax] = max_col
- ret = np.ma.array(iret, mask=mask)
- if is_scalar:
- ret = int(ret[0]) # assume python scalar
- return ret
-
- def inverse(self, value):
- """
- Raises
- ------
- ValueError
- BoundaryNorm is not invertible, so calling this method will always
- raise an error
- """
- raise ValueError("BoundaryNorm is not invertible")
-
-
-class NoNorm(Normalize):
- """
- Dummy replacement for `Normalize`, for the case where we want to use
- indices directly in a `~matplotlib.cm.ScalarMappable`.
- """
- def __call__(self, value, clip=None):
- if np.iterable(value):
- return np.ma.array(value)
- return value
-
- def inverse(self, value):
- if np.iterable(value):
- return np.ma.array(value)
- return value
-
-
-def rgb_to_hsv(arr):
- """
- Convert an array of float RGB values (in the range [0, 1]) to HSV values.
-
- Parameters
- ----------
- arr : (..., 3) array-like
- All values must be in the range [0, 1]
-
- Returns
- -------
- (..., 3) `~numpy.ndarray`
- Colors converted to HSV values in range [0, 1]
- """
- arr = np.asarray(arr)
-
- # check length of the last dimension, should be _some_ sort of rgb
- if arr.shape[-1] != 3:
- raise ValueError("Last dimension of input array must be 3; "
- f"shape {arr.shape} was found.")
-
- in_shape = arr.shape
- arr = np.array(
- arr, copy=False,
- dtype=np.promote_types(arr.dtype, np.float32), # Don't work on ints.
- ndmin=2, # In case input was 1D.
- )
- out = np.zeros_like(arr)
- arr_max = arr.max(-1)
- ipos = arr_max > 0
- delta = np.ptp(arr, -1)
- s = np.zeros_like(delta)
- s[ipos] = delta[ipos] / arr_max[ipos]
- ipos = delta > 0
- # red is max
- idx = (arr[..., 0] == arr_max) & ipos
- out[idx, 0] = (arr[idx, 1] - arr[idx, 2]) / delta[idx]
- # green is max
- idx = (arr[..., 1] == arr_max) & ipos
- out[idx, 0] = 2. + (arr[idx, 2] - arr[idx, 0]) / delta[idx]
- # blue is max
- idx = (arr[..., 2] == arr_max) & ipos
- out[idx, 0] = 4. + (arr[idx, 0] - arr[idx, 1]) / delta[idx]
-
- out[..., 0] = (out[..., 0] / 6.0) % 1.0
- out[..., 1] = s
- out[..., 2] = arr_max
-
- return out.reshape(in_shape)
-
-
-def hsv_to_rgb(hsv):
- """
- Convert HSV values to RGB.
-
- Parameters
- ----------
- hsv : (..., 3) array-like
- All values assumed to be in range [0, 1]
-
- Returns
- -------
- (..., 3) `~numpy.ndarray`
- Colors converted to RGB values in range [0, 1]
- """
- hsv = np.asarray(hsv)
-
- # check length of the last dimension, should be _some_ sort of rgb
- if hsv.shape[-1] != 3:
- raise ValueError("Last dimension of input array must be 3; "
- f"shape {hsv.shape} was found.")
-
- in_shape = hsv.shape
- hsv = np.array(
- hsv, copy=False,
- dtype=np.promote_types(hsv.dtype, np.float32), # Don't work on ints.
- ndmin=2, # In case input was 1D.
- )
-
- h = hsv[..., 0]
- s = hsv[..., 1]
- v = hsv[..., 2]
-
- r = np.empty_like(h)
- g = np.empty_like(h)
- b = np.empty_like(h)
-
- i = (h * 6.0).astype(int)
- f = (h * 6.0) - i
- p = v * (1.0 - s)
- q = v * (1.0 - s * f)
- t = v * (1.0 - s * (1.0 - f))
-
- idx = i % 6 == 0
- r[idx] = v[idx]
- g[idx] = t[idx]
- b[idx] = p[idx]
-
- idx = i == 1
- r[idx] = q[idx]
- g[idx] = v[idx]
- b[idx] = p[idx]
-
- idx = i == 2
- r[idx] = p[idx]
- g[idx] = v[idx]
- b[idx] = t[idx]
-
- idx = i == 3
- r[idx] = p[idx]
- g[idx] = q[idx]
- b[idx] = v[idx]
-
- idx = i == 4
- r[idx] = t[idx]
- g[idx] = p[idx]
- b[idx] = v[idx]
-
- idx = i == 5
- r[idx] = v[idx]
- g[idx] = p[idx]
- b[idx] = q[idx]
-
- idx = s == 0
- r[idx] = v[idx]
- g[idx] = v[idx]
- b[idx] = v[idx]
-
- rgb = np.stack([r, g, b], axis=-1)
-
- return rgb.reshape(in_shape)
-
-
-def _vector_magnitude(arr):
- # things that don't work here:
- # * np.linalg.norm: drops mask from ma.array
- # * np.sum: drops mask from ma.array unless entire vector is masked
- sum_sq = 0
- for i in range(arr.shape[-1]):
- sum_sq += arr[..., i, np.newaxis] ** 2
- return np.sqrt(sum_sq)
-
-
-class LightSource:
- """
- Create a light source coming from the specified azimuth and elevation.
- Angles are in degrees, with the azimuth measured
- clockwise from north and elevation up from the zero plane of the surface.
-
- `shade` is used to produce "shaded" RGB values for a data array.
- `shade_rgb` can be used to combine an RGB image with an elevation map.
- `hillshade` produces an illumination map of a surface.
- """
-
- def __init__(self, azdeg=315, altdeg=45, hsv_min_val=0, hsv_max_val=1,
- hsv_min_sat=1, hsv_max_sat=0):
- """
- Specify the azimuth (measured clockwise from south) and altitude
- (measured up from the plane of the surface) of the light source
- in degrees.
-
- Parameters
- ----------
- azdeg : float, default: 315 degrees (from the northwest)
- The azimuth (0-360, degrees clockwise from North) of the light
- source.
- altdeg : float, default: 45 degrees
- The altitude (0-90, degrees up from horizontal) of the light
- source.
- hsv_min_val : number, default: 0
- The minimum value ("v" in "hsv") that the *intensity* map can shift the
- output image to.
- hsv_max_val : number, default: 1
- The maximum value ("v" in "hsv") that the *intensity* map can shift the
- output image to.
- hsv_min_sat : number, default: 1
- The minimum saturation value that the *intensity* map can shift the output
- image to.
- hsv_max_sat : number, default: 0
- The maximum saturation value that the *intensity* map can shift the output
- image to.
-
- Notes
- -----
- For backwards compatibility, the parameters *hsv_min_val*,
- *hsv_max_val*, *hsv_min_sat*, and *hsv_max_sat* may be supplied at
- initialization as well. However, these parameters will only be used if
- "blend_mode='hsv'" is passed into `shade` or `shade_rgb`.
- See the documentation for `blend_hsv` for more details.
- """
- self.azdeg = azdeg
- self.altdeg = altdeg
- self.hsv_min_val = hsv_min_val
- self.hsv_max_val = hsv_max_val
- self.hsv_min_sat = hsv_min_sat
- self.hsv_max_sat = hsv_max_sat
-
- @property
- def direction(self):
- """The unit vector direction towards the light source."""
- # Azimuth is in degrees clockwise from North. Convert to radians
- # counterclockwise from East (mathematical notation).
- az = np.radians(90 - self.azdeg)
- alt = np.radians(self.altdeg)
- return np.array([
- np.cos(az) * np.cos(alt),
- np.sin(az) * np.cos(alt),
- np.sin(alt)
- ])
-
- def hillshade(self, elevation, vert_exag=1, dx=1, dy=1, fraction=1.):
- """
- Calculate the illumination intensity for a surface using the defined
- azimuth and elevation for the light source.
-
- This computes the normal vectors for the surface, and then passes them
- on to `shade_normals`
-
- Parameters
- ----------
- elevation : 2D array-like
- The height values used to generate an illumination map
- vert_exag : number, optional
- The amount to exaggerate the elevation values by when calculating
- illumination. This can be used either to correct for differences in
- units between the x-y coordinate system and the elevation
- coordinate system (e.g. decimal degrees vs. meters) or to
- exaggerate or de-emphasize topographic effects.
- dx : number, optional
- The x-spacing (columns) of the input *elevation* grid.
- dy : number, optional
- The y-spacing (rows) of the input *elevation* grid.
- fraction : number, optional
- Increases or decreases the contrast of the hillshade. Values
- greater than one will cause intermediate values to move closer to
- full illumination or shadow (and clipping any values that move
- beyond 0 or 1). Note that this is not visually or mathematically
- the same as vertical exaggeration.
-
- Returns
- -------
- `~numpy.ndarray`
- A 2D array of illumination values between 0-1, where 0 is
- completely in shadow and 1 is completely illuminated.
- """
-
- # Because most image and raster GIS data has the first row in the array
- # as the "top" of the image, dy is implicitly negative. This is
- # consistent to what `imshow` assumes, as well.
- dy = -dy
-
- # compute the normal vectors from the partial derivatives
- e_dy, e_dx = np.gradient(vert_exag * elevation, dy, dx)
-
- # .view is to keep subclasses
- normal = np.empty(elevation.shape + (3,)).view(type(elevation))
- normal[..., 0] = -e_dx
- normal[..., 1] = -e_dy
- normal[..., 2] = 1
- normal /= _vector_magnitude(normal)
-
- return self.shade_normals(normal, fraction)
-
- def shade_normals(self, normals, fraction=1.):
- """
- Calculate the illumination intensity for the normal vectors of a
- surface using the defined azimuth and elevation for the light source.
-
- Imagine an artificial sun placed at infinity in some azimuth and
- elevation position illuminating our surface. The parts of the surface
- that slope toward the sun should brighten while those sides facing away
- should become darker.
-
- Parameters
- ----------
- fraction : number, optional
- Increases or decreases the contrast of the hillshade. Values
- greater than one will cause intermediate values to move closer to
- full illumination or shadow (and clipping any values that move
- beyond 0 or 1). Note that this is not visually or mathematically
- the same as vertical exaggeration.
-
- Returns
- -------
- `~numpy.ndarray`
- A 2D array of illumination values between 0-1, where 0 is
- completely in shadow and 1 is completely illuminated.
- """
-
- intensity = normals.dot(self.direction)
-
- # Apply contrast stretch
- imin, imax = intensity.min(), intensity.max()
- intensity *= fraction
-
- # Rescale to 0-1, keeping range before contrast stretch
- # If constant slope, keep relative scaling (i.e. flat should be 0.5,
- # fully occluded 0, etc.)
- if (imax - imin) > 1e-6:
- # Strictly speaking, this is incorrect. Negative values should be
- # clipped to 0 because they're fully occluded. However, rescaling
- # in this manner is consistent with the previous implementation and
- # visually appears better than a "hard" clip.
- intensity -= imin
- intensity /= (imax - imin)
- intensity = np.clip(intensity, 0, 1)
-
- return intensity
-
- def shade(self, data, cmap, norm=None, blend_mode='overlay', vmin=None,
- vmax=None, vert_exag=1, dx=1, dy=1, fraction=1, **kwargs):
- """
- Combine colormapped data values with an illumination intensity map
- (a.k.a. "hillshade") of the values.
-
- Parameters
- ----------
- data : 2D array-like
- The height values used to generate a shaded map.
- cmap : `~matplotlib.colors.Colormap`
- The colormap used to color the *data* array. Note that this must be
- a `~matplotlib.colors.Colormap` instance. For example, rather than
- passing in ``cmap='gist_earth'``, use
- ``cmap=plt.get_cmap('gist_earth')`` instead.
- norm : `~matplotlib.colors.Normalize` instance, optional
- The normalization used to scale values before colormapping. If
- None, the input will be linearly scaled between its min and max.
- blend_mode : {'hsv', 'overlay', 'soft'} or callable, optional
- The type of blending used to combine the colormapped data
- values with the illumination intensity. Default is
- "overlay". Note that for most topographic surfaces,
- "overlay" or "soft" appear more visually realistic. If a
- user-defined function is supplied, it is expected to
- combine an (M, N, 3) RGB array of floats (ranging 0 to 1) with
- an (M, N, 1) hillshade array (also 0 to 1). (Call signature
- ``func(rgb, illum, **kwargs)``) Additional kwargs supplied
- to this function will be passed on to the *blend_mode*
- function.
- vmin : float or None, optional
- The minimum value used in colormapping *data*. If *None* the
- minimum value in *data* is used. If *norm* is specified, then this
- argument will be ignored.
- vmax : float or None, optional
- The maximum value used in colormapping *data*. If *None* the
- maximum value in *data* is used. If *norm* is specified, then this
- argument will be ignored.
- vert_exag : number, optional
- The amount to exaggerate the elevation values by when calculating
- illumination. This can be used either to correct for differences in
- units between the x-y coordinate system and the elevation
- coordinate system (e.g. decimal degrees vs. meters) or to
- exaggerate or de-emphasize topography.
- dx : number, optional
- The x-spacing (columns) of the input *elevation* grid.
- dy : number, optional
- The y-spacing (rows) of the input *elevation* grid.
- fraction : number, optional
- Increases or decreases the contrast of the hillshade. Values
- greater than one will cause intermediate values to move closer to
- full illumination or shadow (and clipping any values that move
- beyond 0 or 1). Note that this is not visually or mathematically
- the same as vertical exaggeration.
- **kwargs
- Additional kwargs are passed on to the *blend_mode* function.
-
- Returns
- -------
- `~numpy.ndarray`
- An (M, N, 4) array of floats ranging between 0-1.
- """
- if vmin is None:
- vmin = data.min()
- if vmax is None:
- vmax = data.max()
- if norm is None:
- norm = Normalize(vmin=vmin, vmax=vmax)
-
- rgb0 = cmap(norm(data))
- rgb1 = self.shade_rgb(rgb0, elevation=data, blend_mode=blend_mode,
- vert_exag=vert_exag, dx=dx, dy=dy,
- fraction=fraction, **kwargs)
- # Don't overwrite the alpha channel, if present.
- rgb0[..., :3] = rgb1[..., :3]
- return rgb0
-
- def shade_rgb(self, rgb, elevation, fraction=1., blend_mode='hsv',
- vert_exag=1, dx=1, dy=1, **kwargs):
- """
- Use this light source to adjust the colors of the *rgb* input array to
- give the impression of a shaded relief map with the given *elevation*.
-
- Parameters
- ----------
- rgb : array-like
- An (M, N, 3) RGB array, assumed to be in the range of 0 to 1.
- elevation : array-like
- An (M, N) array of the height values used to generate a shaded map.
- fraction : number
- Increases or decreases the contrast of the hillshade. Values
- greater than one will cause intermediate values to move closer to
- full illumination or shadow (and clipping any values that move
- beyond 0 or 1). Note that this is not visually or mathematically
- the same as vertical exaggeration.
- blend_mode : {'hsv', 'overlay', 'soft'} or callable, optional
- The type of blending used to combine the colormapped data values
- with the illumination intensity. For backwards compatibility, this
- defaults to "hsv". Note that for most topographic surfaces,
- "overlay" or "soft" appear more visually realistic. If a
- user-defined function is supplied, it is expected to combine an
- (M, N, 3) RGB array of floats (ranging 0 to 1) with an (M, N, 1)
- hillshade array (also 0 to 1). (Call signature
- ``func(rgb, illum, **kwargs)``)
- Additional kwargs supplied to this function will be passed on to
- the *blend_mode* function.
- vert_exag : number, optional
- The amount to exaggerate the elevation values by when calculating
- illumination. This can be used either to correct for differences in
- units between the x-y coordinate system and the elevation
- coordinate system (e.g. decimal degrees vs. meters) or to
- exaggerate or de-emphasize topography.
- dx : number, optional
- The x-spacing (columns) of the input *elevation* grid.
- dy : number, optional
- The y-spacing (rows) of the input *elevation* grid.
- **kwargs
- Additional kwargs are passed on to the *blend_mode* function.
-
- Returns
- -------
- `~numpy.ndarray`
- An (m, n, 3) array of floats ranging between 0-1.
- """
- # Calculate the "hillshade" intensity.
- intensity = self.hillshade(elevation, vert_exag, dx, dy, fraction)
- intensity = intensity[..., np.newaxis]
-
- # Blend the hillshade and rgb data using the specified mode
- lookup = {
- 'hsv': self.blend_hsv,
- 'soft': self.blend_soft_light,
- 'overlay': self.blend_overlay,
- }
- if blend_mode in lookup:
- blend = lookup[blend_mode](rgb, intensity, **kwargs)
- else:
- try:
- blend = blend_mode(rgb, intensity, **kwargs)
- except TypeError as err:
- raise ValueError('"blend_mode" must be callable or one of '
- f'{lookup.keys}') from err
-
- # Only apply result where hillshade intensity isn't masked
- if np.ma.is_masked(intensity):
- mask = intensity.mask[..., 0]
- for i in range(3):
- blend[..., i][mask] = rgb[..., i][mask]
-
- return blend
-
- def blend_hsv(self, rgb, intensity, hsv_max_sat=None, hsv_max_val=None,
- hsv_min_val=None, hsv_min_sat=None):
- """
- Take the input data array, convert to HSV values in the given colormap,
- then adjust those color values to give the impression of a shaded
- relief map with a specified light source. RGBA values are returned,
- which can then be used to plot the shaded image with imshow.
-
- The color of the resulting image will be darkened by moving the (s, v)
- values (in HSV colorspace) toward (hsv_min_sat, hsv_min_val) in the
- shaded regions, or lightened by sliding (s, v) toward (hsv_max_sat,
- hsv_max_val) in regions that are illuminated. The default extremes are
- chose so that completely shaded points are nearly black (s = 1, v = 0)
- and completely illuminated points are nearly white (s = 0, v = 1).
-
- Parameters
- ----------
- rgb : `~numpy.ndarray`
- An (M, N, 3) RGB array of floats ranging from 0 to 1 (color image).
- intensity : `~numpy.ndarray`
- An (M, N, 1) array of floats ranging from 0 to 1 (grayscale image).
- hsv_max_sat : number, optional
- The maximum saturation value that the *intensity* map can shift the output
- image to. If not provided, use the value provided upon initialization.
- hsv_min_sat : number, optional
- The minimum saturation value that the *intensity* map can shift the output
- image to. If not provided, use the value provided upon initialization.
- hsv_max_val : number, optional
- The maximum value ("v" in "hsv") that the *intensity* map can shift the
- output image to. If not provided, use the value provided upon
- initialization.
- hsv_min_val : number, optional
- The minimum value ("v" in "hsv") that the *intensity* map can shift the
- output image to. If not provided, use the value provided upon
- initialization.
-
- Returns
- -------
- `~numpy.ndarray`
- An (M, N, 3) RGB array representing the combined images.
- """
- # Backward compatibility...
- if hsv_max_sat is None:
- hsv_max_sat = self.hsv_max_sat
- if hsv_max_val is None:
- hsv_max_val = self.hsv_max_val
- if hsv_min_sat is None:
- hsv_min_sat = self.hsv_min_sat
- if hsv_min_val is None:
- hsv_min_val = self.hsv_min_val
-
- # Expects a 2D intensity array scaled between -1 to 1...
- intensity = intensity[..., 0]
- intensity = 2 * intensity - 1
-
- # Convert to rgb, then rgb to hsv
- hsv = rgb_to_hsv(rgb[:, :, 0:3])
- hue, sat, val = np.moveaxis(hsv, -1, 0)
-
- # Modify hsv values (in place) to simulate illumination.
- # putmask(A, mask, B) <=> A[mask] = B[mask]
- np.putmask(sat, (np.abs(sat) > 1.e-10) & (intensity > 0),
- (1 - intensity) * sat + intensity * hsv_max_sat)
- np.putmask(sat, (np.abs(sat) > 1.e-10) & (intensity < 0),
- (1 + intensity) * sat - intensity * hsv_min_sat)
- np.putmask(val, intensity > 0,
- (1 - intensity) * val + intensity * hsv_max_val)
- np.putmask(val, intensity < 0,
- (1 + intensity) * val - intensity * hsv_min_val)
- np.clip(hsv[:, :, 1:], 0, 1, out=hsv[:, :, 1:])
-
- # Convert modified hsv back to rgb.
- return hsv_to_rgb(hsv)
-
- def blend_soft_light(self, rgb, intensity):
- """
- Combine an RGB image with an intensity map using "soft light" blending,
- using the "pegtop" formula.
-
- Parameters
- ----------
- rgb : `~numpy.ndarray`
- An (M, N, 3) RGB array of floats ranging from 0 to 1 (color image).
- intensity : `~numpy.ndarray`
- An (M, N, 1) array of floats ranging from 0 to 1 (grayscale image).
-
- Returns
- -------
- `~numpy.ndarray`
- An (M, N, 3) RGB array representing the combined images.
- """
- return 2 * intensity * rgb + (1 - 2 * intensity) * rgb**2
-
- def blend_overlay(self, rgb, intensity):
- """
- Combine an RGB image with an intensity map using "overlay" blending.
-
- Parameters
- ----------
- rgb : `~numpy.ndarray`
- An (M, N, 3) RGB array of floats ranging from 0 to 1 (color image).
- intensity : `~numpy.ndarray`
- An (M, N, 1) array of floats ranging from 0 to 1 (grayscale image).
-
- Returns
- -------
- ndarray
- An (M, N, 3) RGB array representing the combined images.
- """
- low = 2 * intensity * rgb
- high = 1 - 2 * (1 - intensity) * (1 - rgb)
- return np.where(rgb <= 0.5, low, high)
-
-
-def from_levels_and_colors(levels, colors, extend='neither'):
- """
- A helper routine to generate a cmap and a norm instance which
- behave similar to contourf's levels and colors arguments.
-
- Parameters
- ----------
- levels : sequence of numbers
- The quantization levels used to construct the `BoundaryNorm`.
- Value ``v`` is quantized to level ``i`` if ``lev[i] <= v < lev[i+1]``.
- colors : sequence of colors
- The fill color to use for each level. If *extend* is "neither" there
- must be ``n_level - 1`` colors. For an *extend* of "min" or "max" add
- one extra color, and for an *extend* of "both" add two colors.
- extend : {'neither', 'min', 'max', 'both'}, optional
- The behaviour when a value falls out of range of the given levels.
- See `~.Axes.contourf` for details.
-
- Returns
- -------
- cmap : `~matplotlib.colors.Colormap`
- norm : `~matplotlib.colors.Normalize`
- """
- slice_map = {
- 'both': slice(1, -1),
- 'min': slice(1, None),
- 'max': slice(0, -1),
- 'neither': slice(0, None),
- }
- _api.check_in_list(slice_map, extend=extend)
- color_slice = slice_map[extend]
-
- n_data_colors = len(levels) - 1
- n_expected = n_data_colors + color_slice.start - (color_slice.stop or 0)
- if len(colors) != n_expected:
- raise ValueError(
- f'With extend == {extend!r} and {len(levels)} levels, '
- f'expected {n_expected} colors, but got {len(colors)}')
-
- cmap = ListedColormap(colors[color_slice], N=n_data_colors)
-
- if extend in ['min', 'both']:
- cmap.set_under(colors[0])
- else:
- cmap.set_under('none')
-
- if extend in ['max', 'both']:
- cmap.set_over(colors[-1])
- else:
- cmap.set_over('none')
-
- cmap.colorbar_extend = extend
-
- norm = BoundaryNorm(levels, ncolors=n_data_colors)
- return cmap, norm
diff --git a/contrib/python/matplotlib/py3/matplotlib/colors.pyi b/contrib/python/matplotlib/py3/matplotlib/colors.pyi
deleted file mode 100644
index 9bb1725f4f..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/colors.pyi
+++ /dev/null
@@ -1,354 +0,0 @@
-from collections.abc import Callable, Iterable, Iterator, Mapping, Sequence
-from matplotlib import cbook, scale
-import re
-
-from typing import Any, Literal, overload
-from .typing import ColorType
-
-import numpy as np
-from numpy.typing import ArrayLike
-
-# Explicitly export colors dictionaries which are imported in the impl
-BASE_COLORS: dict[str, ColorType]
-CSS4_COLORS: dict[str, ColorType]
-TABLEAU_COLORS: dict[str, ColorType]
-XKCD_COLORS: dict[str, ColorType]
-
-class _ColorMapping(dict[str, ColorType]):
- cache: dict[tuple[ColorType, float | None], tuple[float, float, float, float]]
- def __init__(self, mapping) -> None: ...
- def __setitem__(self, key, value) -> None: ...
- def __delitem__(self, key) -> None: ...
-
-def get_named_colors_mapping() -> _ColorMapping: ...
-
-class ColorSequenceRegistry(Mapping):
- def __init__(self) -> None: ...
- def __getitem__(self, item: str) -> list[ColorType]: ...
- def __iter__(self) -> Iterator[str]: ...
- def __len__(self) -> int: ...
- def register(self, name: str, color_list: Iterable[ColorType]) -> None: ...
- def unregister(self, name: str) -> None: ...
-
-_color_sequences: ColorSequenceRegistry = ...
-
-def is_color_like(c: Any) -> bool: ...
-def same_color(c1: ColorType, c2: ColorType) -> bool: ...
-def to_rgba(
- c: ColorType, alpha: float | None = ...
-) -> tuple[float, float, float, float]: ...
-def to_rgba_array(
- c: ColorType | ArrayLike, alpha: float | ArrayLike | None = ...
-) -> np.ndarray: ...
-def to_rgb(c: ColorType) -> tuple[float, float, float]: ...
-def to_hex(c: ColorType, keep_alpha: bool = ...) -> str: ...
-
-cnames: dict[str, ColorType]
-hexColorPattern: re.Pattern
-rgb2hex = to_hex
-hex2color = to_rgb
-
-class ColorConverter:
- colors: _ColorMapping
- cache: dict[tuple[ColorType, float | None], tuple[float, float, float, float]]
- @staticmethod
- def to_rgb(c: ColorType) -> tuple[float, float, float]: ...
- @staticmethod
- def to_rgba(
- c: ColorType, alpha: float | None = ...
- ) -> tuple[float, float, float, float]: ...
- @staticmethod
- def to_rgba_array(
- c: ColorType | ArrayLike, alpha: float | ArrayLike | None = ...
- ) -> np.ndarray: ...
-
-colorConverter: ColorConverter
-
-class Colormap:
- name: str
- N: int
- colorbar_extend: bool
- def __init__(self, name: str, N: int = ...) -> None: ...
- @overload
- def __call__(
- self, X: Sequence[float] | np.ndarray, alpha: ArrayLike | None = ..., bytes: bool = ...
- ) -> np.ndarray: ...
- @overload
- def __call__(
- self, X: float, alpha: float | None = ..., bytes: bool = ...
- ) -> tuple[float, float, float, float]: ...
- @overload
- def __call__(
- self, X: ArrayLike, alpha: ArrayLike | None = ..., bytes: bool = ...
- ) -> tuple[float, float, float, float] | np.ndarray: ...
- def __copy__(self) -> Colormap: ...
- def __eq__(self, other: object) -> bool: ...
- def get_bad(self) -> np.ndarray: ...
- def set_bad(self, color: ColorType = ..., alpha: float | None = ...) -> None: ...
- def get_under(self) -> np.ndarray: ...
- def set_under(self, color: ColorType = ..., alpha: float | None = ...) -> None: ...
- def get_over(self) -> np.ndarray: ...
- def set_over(self, color: ColorType = ..., alpha: float | None = ...) -> None: ...
- def set_extremes(
- self,
- *,
- bad: ColorType | None = ...,
- under: ColorType | None = ...,
- over: ColorType | None = ...
- ) -> None: ...
- def with_extremes(
- self,
- *,
- bad: ColorType | None = ...,
- under: ColorType | None = ...,
- over: ColorType | None = ...
- ) -> Colormap: ...
- def is_gray(self) -> bool: ...
- def resampled(self, lutsize: int) -> Colormap: ...
- def reversed(self, name: str | None = ...) -> Colormap: ...
- def _repr_html_(self) -> str: ...
- def _repr_png_(self) -> bytes: ...
- def copy(self) -> Colormap: ...
-
-class LinearSegmentedColormap(Colormap):
- monochrome: bool
- def __init__(
- self,
- name: str,
- segmentdata: dict[
- Literal["red", "green", "blue", "alpha"], Sequence[tuple[float, ...]]
- ],
- N: int = ...,
- gamma: float = ...,
- ) -> None: ...
- def set_gamma(self, gamma: float) -> None: ...
- @staticmethod
- def from_list(
- name: str, colors: ArrayLike, N: int = ..., gamma: float = ...
- ) -> LinearSegmentedColormap: ...
- def resampled(self, lutsize: int) -> LinearSegmentedColormap: ...
- def reversed(self, name: str | None = ...) -> LinearSegmentedColormap: ...
-
-class ListedColormap(Colormap):
- monochrome: bool
- colors: ArrayLike | ColorType
- def __init__(
- self, colors: ArrayLike | ColorType, name: str = ..., N: int | None = ...
- ) -> None: ...
- def resampled(self, lutsize: int) -> ListedColormap: ...
- def reversed(self, name: str | None = ...) -> ListedColormap: ...
-
-class Normalize:
- callbacks: cbook.CallbackRegistry
- def __init__(
- self, vmin: float | None = ..., vmax: float | None = ..., clip: bool = ...
- ) -> None: ...
- @property
- def vmin(self) -> float | None: ...
- @vmin.setter
- def vmin(self, value: float | None) -> None: ...
- @property
- def vmax(self) -> float | None: ...
- @vmax.setter
- def vmax(self, value: float | None) -> None: ...
- @property
- def clip(self) -> bool: ...
- @clip.setter
- def clip(self, value: bool) -> None: ...
- @staticmethod
- def process_value(value: ArrayLike) -> tuple[np.ma.MaskedArray, bool]: ...
- @overload
- def __call__(self, value: float, clip: bool | None = ...) -> float: ...
- @overload
- def __call__(self, value: np.ndarray, clip: bool | None = ...) -> np.ma.MaskedArray: ...
- @overload
- def __call__(self, value: ArrayLike, clip: bool | None = ...) -> ArrayLike: ...
- @overload
- def inverse(self, value: float) -> float: ...
- @overload
- def inverse(self, value: np.ndarray) -> np.ma.MaskedArray: ...
- @overload
- def inverse(self, value: ArrayLike) -> ArrayLike: ...
- def autoscale(self, A: ArrayLike) -> None: ...
- def autoscale_None(self, A: ArrayLike) -> None: ...
- def scaled(self) -> bool: ...
-
-class TwoSlopeNorm(Normalize):
- def __init__(
- self, vcenter: float, vmin: float | None = ..., vmax: float | None = ...
- ) -> None: ...
- @property
- def vcenter(self) -> float: ...
- @vcenter.setter
- def vcenter(self, value: float) -> None: ...
- def autoscale_None(self, A: ArrayLike) -> None: ...
-
-class CenteredNorm(Normalize):
- def __init__(
- self, vcenter: float = ..., halfrange: float | None = ..., clip: bool = ...
- ) -> None: ...
- @property
- def vcenter(self) -> float: ...
- @vcenter.setter
- def vcenter(self, vcenter: float) -> None: ...
- @property
- def halfrange(self) -> float: ...
- @halfrange.setter
- def halfrange(self, halfrange: float) -> None: ...
-
-@overload
-def make_norm_from_scale(
- scale_cls: type[scale.ScaleBase],
- base_norm_cls: type[Normalize],
- *,
- init: Callable | None = ...
-) -> type[Normalize]: ...
-@overload
-def make_norm_from_scale(
- scale_cls: type[scale.ScaleBase],
- base_norm_cls: None = ...,
- *,
- init: Callable | None = ...
-) -> Callable[[type[Normalize]], type[Normalize]]: ...
-
-class FuncNorm(Normalize):
- def __init__(
- self,
- functions: tuple[Callable, Callable],
- vmin: float | None = ...,
- vmax: float | None = ...,
- clip: bool = ...,
- ) -> None: ...
-class LogNorm(Normalize): ...
-
-class SymLogNorm(Normalize):
- def __init__(
- self,
- linthresh: float,
- linscale: float = ...,
- vmin: float | None = ...,
- vmax: float | None = ...,
- clip: bool = ...,
- *,
- base: float = ...,
- ) -> None: ...
- @property
- def linthresh(self) -> float: ...
- @linthresh.setter
- def linthresh(self, value: float) -> None: ...
-
-class AsinhNorm(Normalize):
- def __init__(
- self,
- linear_width: float = ...,
- vmin: float | None = ...,
- vmax: float | None = ...,
- clip: bool = ...,
- ) -> None: ...
- @property
- def linear_width(self) -> float: ...
- @linear_width.setter
- def linear_width(self, value: float) -> None: ...
-
-class PowerNorm(Normalize):
- gamma: float
- def __init__(
- self,
- gamma: float,
- vmin: float | None = ...,
- vmax: float | None = ...,
- clip: bool = ...,
- ) -> None: ...
-
-class BoundaryNorm(Normalize):
- boundaries: np.ndarray
- N: int
- Ncmap: int
- extend: Literal["neither", "both", "min", "max"]
- def __init__(
- self,
- boundaries: ArrayLike,
- ncolors: int,
- clip: bool = ...,
- *,
- extend: Literal["neither", "both", "min", "max"] = ...
- ) -> None: ...
-
-class NoNorm(Normalize): ...
-
-def rgb_to_hsv(arr: ArrayLike) -> np.ndarray: ...
-def hsv_to_rgb(hsv: ArrayLike) -> np.ndarray: ...
-
-class LightSource:
- azdeg: float
- altdeg: float
- hsv_min_val: float
- hsv_max_val: float
- hsv_min_sat: float
- hsv_max_sat: float
- def __init__(
- self,
- azdeg: float = ...,
- altdeg: float = ...,
- hsv_min_val: float = ...,
- hsv_max_val: float = ...,
- hsv_min_sat: float = ...,
- hsv_max_sat: float = ...,
- ) -> None: ...
- @property
- def direction(self) -> np.ndarray: ...
- def hillshade(
- self,
- elevation: ArrayLike,
- vert_exag: float = ...,
- dx: float = ...,
- dy: float = ...,
- fraction: float = ...,
- ) -> np.ndarray: ...
- def shade_normals(
- self, normals: np.ndarray, fraction: float = ...
- ) -> np.ndarray: ...
- def shade(
- self,
- data: ArrayLike,
- cmap: Colormap,
- norm: Normalize | None = ...,
- blend_mode: Literal["hsv", "overlay", "soft"] | Callable = ...,
- vmin: float | None = ...,
- vmax: float | None = ...,
- vert_exag: float = ...,
- dx: float = ...,
- dy: float = ...,
- fraction: float = ...,
- **kwargs
- ) -> np.ndarray: ...
- def shade_rgb(
- self,
- rgb: ArrayLike,
- elevation: ArrayLike,
- fraction: float = ...,
- blend_mode: Literal["hsv", "overlay", "soft"] | Callable = ...,
- vert_exag: float = ...,
- dx: float = ...,
- dy: float = ...,
- **kwargs
- ) -> np.ndarray: ...
- def blend_hsv(
- self,
- rgb: ArrayLike,
- intensity: ArrayLike,
- hsv_max_sat: float | None = ...,
- hsv_max_val: float | None = ...,
- hsv_min_val: float | None = ...,
- hsv_min_sat: float | None = ...,
- ) -> ArrayLike: ...
- def blend_soft_light(
- self, rgb: np.ndarray, intensity: np.ndarray
- ) -> np.ndarray: ...
- def blend_overlay(self, rgb: np.ndarray, intensity: np.ndarray) -> np.ndarray: ...
-
-def from_levels_and_colors(
- levels: Sequence[float],
- colors: Sequence[ColorType],
- extend: Literal["neither", "min", "max", "both"] = ...,
-) -> tuple[ListedColormap, BoundaryNorm]: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/container.py b/contrib/python/matplotlib/py3/matplotlib/container.py
deleted file mode 100644
index 0f082e298a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/container.py
+++ /dev/null
@@ -1,141 +0,0 @@
-from matplotlib import cbook
-from matplotlib.artist import Artist
-
-
-class Container(tuple):
- """
- Base class for containers.
-
- Containers are classes that collect semantically related Artists such as
- the bars of a bar plot.
- """
-
- def __repr__(self):
- return f"<{type(self).__name__} object of {len(self)} artists>"
-
- def __new__(cls, *args, **kwargs):
- return tuple.__new__(cls, args[0])
-
- def __init__(self, kl, label=None):
- self._callbacks = cbook.CallbackRegistry(signals=["pchanged"])
- self._remove_method = None
- self._label = str(label) if label is not None else None
-
- def remove(self):
- for c in cbook.flatten(
- self, scalarp=lambda x: isinstance(x, Artist)):
- if c is not None:
- c.remove()
- if self._remove_method:
- self._remove_method(self)
-
- def get_children(self):
- return [child for child in cbook.flatten(self) if child is not None]
-
- get_label = Artist.get_label
- set_label = Artist.set_label
- add_callback = Artist.add_callback
- remove_callback = Artist.remove_callback
- pchanged = Artist.pchanged
-
-
-class BarContainer(Container):
- """
- Container for the artists of bar plots (e.g. created by `.Axes.bar`).
-
- The container can be treated as a tuple of the *patches* themselves.
- Additionally, you can access these and further parameters by the
- attributes.
-
- Attributes
- ----------
- patches : list of :class:`~matplotlib.patches.Rectangle`
- The artists of the bars.
-
- errorbar : None or :class:`~matplotlib.container.ErrorbarContainer`
- A container for the error bar artists if error bars are present.
- *None* otherwise.
-
- datavalues : None or array-like
- The underlying data values corresponding to the bars.
-
- orientation : {'vertical', 'horizontal'}, default: None
- If 'vertical', the bars are assumed to be vertical.
- If 'horizontal', the bars are assumed to be horizontal.
-
- """
-
- def __init__(self, patches, errorbar=None, *, datavalues=None,
- orientation=None, **kwargs):
- self.patches = patches
- self.errorbar = errorbar
- self.datavalues = datavalues
- self.orientation = orientation
- super().__init__(patches, **kwargs)
-
-
-class ErrorbarContainer(Container):
- """
- Container for the artists of error bars (e.g. created by `.Axes.errorbar`).
-
- The container can be treated as the *lines* tuple itself.
- Additionally, you can access these and further parameters by the
- attributes.
-
- Attributes
- ----------
- lines : tuple
- Tuple of ``(data_line, caplines, barlinecols)``.
-
- - data_line : :class:`~matplotlib.lines.Line2D` instance of
- x, y plot markers and/or line.
- - caplines : tuple of :class:`~matplotlib.lines.Line2D` instances of
- the error bar caps.
- - barlinecols : list of :class:`~matplotlib.collections.LineCollection`
- with the horizontal and vertical error ranges.
-
- has_xerr, has_yerr : bool
- ``True`` if the errorbar has x/y errors.
-
- """
-
- def __init__(self, lines, has_xerr=False, has_yerr=False, **kwargs):
- self.lines = lines
- self.has_xerr = has_xerr
- self.has_yerr = has_yerr
- super().__init__(lines, **kwargs)
-
-
-class StemContainer(Container):
- """
- Container for the artists created in a :meth:`.Axes.stem` plot.
-
- The container can be treated like a namedtuple ``(markerline, stemlines,
- baseline)``.
-
- Attributes
- ----------
- markerline : :class:`~matplotlib.lines.Line2D`
- The artist of the markers at the stem heads.
-
- stemlines : list of :class:`~matplotlib.lines.Line2D`
- The artists of the vertical lines for all stems.
-
- baseline : :class:`~matplotlib.lines.Line2D`
- The artist of the horizontal baseline.
- """
- def __init__(self, markerline_stemlines_baseline, **kwargs):
- """
- Parameters
- ----------
- markerline_stemlines_baseline : tuple
- Tuple of ``(markerline, stemlines, baseline)``.
- ``markerline`` contains the `.LineCollection` of the markers,
- ``stemlines`` is a `.LineCollection` of the main lines,
- ``baseline`` is the `.Line2D` of the baseline.
- """
- markerline, stemlines, baseline = markerline_stemlines_baseline
- self.markerline = markerline
- self.stemlines = stemlines
- self.baseline = baseline
- super().__init__(markerline_stemlines_baseline, **kwargs)
diff --git a/contrib/python/matplotlib/py3/matplotlib/container.pyi b/contrib/python/matplotlib/py3/matplotlib/container.pyi
deleted file mode 100644
index 9cc2e1ac2a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/container.pyi
+++ /dev/null
@@ -1,56 +0,0 @@
-from matplotlib.artist import Artist
-from matplotlib.lines import Line2D
-from matplotlib.collections import LineCollection
-from matplotlib.patches import Rectangle
-
-from collections.abc import Callable
-from typing import Any, Literal
-from numpy.typing import ArrayLike
-
-class Container(tuple):
- def __new__(cls, *args, **kwargs): ...
- def __init__(self, kl, label: Any | None = ...) -> None: ...
- def remove(self) -> None: ...
- def get_children(self) -> list[Artist]: ...
- def get_label(self) -> str | None: ...
- def set_label(self, s: Any) -> None: ...
- def add_callback(self, func: Callable[[Artist], Any]) -> int: ...
- def remove_callback(self, oid: int) -> None: ...
- def pchanged(self) -> None: ...
-
-class BarContainer(Container):
- patches: list[Rectangle]
- errorbar: None | ErrorbarContainer
- datavalues: None | ArrayLike
- orientation: None | Literal["vertical", "horizontal"]
- def __init__(
- self,
- patches: list[Rectangle],
- errorbar: ErrorbarContainer | None = ...,
- *,
- datavalues: ArrayLike | None = ...,
- orientation: Literal["vertical", "horizontal"] | None = ...,
- **kwargs
- ) -> None: ...
-
-class ErrorbarContainer(Container):
- lines: tuple[Line2D, Line2D, LineCollection]
- has_xerr: bool
- has_yerr: bool
- def __init__(
- self,
- lines: tuple[Line2D, Line2D, LineCollection],
- has_xerr: bool = ...,
- has_yerr: bool = ...,
- **kwargs
- ) -> None: ...
-
-class StemContainer(Container):
- markerline: Line2D
- stemlines: LineCollection
- baseline: Line2D
- def __init__(
- self,
- markerline_stemlines_baseline: tuple[Line2D, LineCollection, Line2D],
- **kwargs
- ) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/contour.py b/contrib/python/matplotlib/py3/matplotlib/contour.py
deleted file mode 100644
index 6e88996864..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/contour.py
+++ /dev/null
@@ -1,1902 +0,0 @@
-"""
-Classes to support contour plotting and labelling for the Axes class.
-"""
-
-from contextlib import ExitStack
-import functools
-import math
-from numbers import Integral
-
-import numpy as np
-from numpy import ma
-
-import matplotlib as mpl
-from matplotlib import _api, _docstring
-from matplotlib.backend_bases import MouseButton
-from matplotlib.lines import Line2D
-from matplotlib.path import Path
-from matplotlib.text import Text
-import matplotlib.ticker as ticker
-import matplotlib.cm as cm
-import matplotlib.colors as mcolors
-import matplotlib.collections as mcoll
-import matplotlib.font_manager as font_manager
-import matplotlib.cbook as cbook
-import matplotlib.patches as mpatches
-import matplotlib.transforms as mtransforms
-
-
-@_api.deprecated("3.7", alternative="Text.set_transform_rotates_text")
-class ClabelText(Text):
- """
- Unlike the ordinary text, the get_rotation returns an updated
- angle in the pixel coordinate assuming that the input rotation is
- an angle in data coordinate (or whatever transform set).
- """
-
- def get_rotation(self):
- new_angle, = self.get_transform().transform_angles(
- [super().get_rotation()], [self.get_position()])
- return new_angle
-
-
-def _contour_labeler_event_handler(cs, inline, inline_spacing, event):
- canvas = cs.axes.figure.canvas
- is_button = event.name == "button_press_event"
- is_key = event.name == "key_press_event"
- # Quit (even if not in infinite mode; this is consistent with
- # MATLAB and sometimes quite useful, but will require the user to
- # test how many points were actually returned before using data).
- if (is_button and event.button == MouseButton.MIDDLE
- or is_key and event.key in ["escape", "enter"]):
- canvas.stop_event_loop()
- # Pop last click.
- elif (is_button and event.button == MouseButton.RIGHT
- or is_key and event.key in ["backspace", "delete"]):
- # Unfortunately, if one is doing inline labels, then there is currently
- # no way to fix the broken contour - once humpty-dumpty is broken, he
- # can't be put back together. In inline mode, this does nothing.
- if not inline:
- cs.pop_label()
- canvas.draw()
- # Add new click.
- elif (is_button and event.button == MouseButton.LEFT
- # On macOS/gtk, some keys return None.
- or is_key and event.key is not None):
- if cs.axes.contains(event)[0]:
- cs.add_label_near(event.x, event.y, transform=False,
- inline=inline, inline_spacing=inline_spacing)
- canvas.draw()
-
-
-class ContourLabeler:
- """Mixin to provide labelling capability to `.ContourSet`."""
-
- def clabel(self, levels=None, *,
- fontsize=None, inline=True, inline_spacing=5, fmt=None,
- colors=None, use_clabeltext=False, manual=False,
- rightside_up=True, zorder=None):
- """
- Label a contour plot.
-
- Adds labels to line contours in this `.ContourSet` (which inherits from
- this mixin class).
-
- Parameters
- ----------
- levels : array-like, optional
- A list of level values, that should be labeled. The list must be
- a subset of ``cs.levels``. If not given, all levels are labeled.
-
- fontsize : str or float, default: :rc:`font.size`
- Size in points or relative size e.g., 'smaller', 'x-large'.
- See `.Text.set_size` for accepted string values.
-
- colors : color or colors or None, default: None
- The label colors:
-
- - If *None*, the color of each label matches the color of
- the corresponding contour.
-
- - If one string color, e.g., *colors* = 'r' or *colors* =
- 'red', all labels will be plotted in this color.
-
- - If a tuple of colors (string, float, RGB, etc), different labels
- will be plotted in different colors in the order specified.
-
- inline : bool, default: True
- If ``True`` the underlying contour is removed where the label is
- placed.
-
- inline_spacing : float, default: 5
- Space in pixels to leave on each side of label when placing inline.
-
- This spacing will be exact for labels at locations where the
- contour is straight, less so for labels on curved contours.
-
- fmt : `.Formatter` or str or callable or dict, optional
- How the levels are formatted:
-
- - If a `.Formatter`, it is used to format all levels at once, using
- its `.Formatter.format_ticks` method.
- - If a str, it is interpreted as a %-style format string.
- - If a callable, it is called with one level at a time and should
- return the corresponding label.
- - If a dict, it should directly map levels to labels.
-
- The default is to use a standard `.ScalarFormatter`.
-
- manual : bool or iterable, default: False
- If ``True``, contour labels will be placed manually using
- mouse clicks. Click the first button near a contour to
- add a label, click the second button (or potentially both
- mouse buttons at once) to finish adding labels. The third
- button can be used to remove the last label added, but
- only if labels are not inline. Alternatively, the keyboard
- can be used to select label locations (enter to end label
- placement, delete or backspace act like the third mouse button,
- and any other key will select a label location).
-
- *manual* can also be an iterable object of (x, y) tuples.
- Contour labels will be created as if mouse is clicked at each
- (x, y) position.
-
- rightside_up : bool, default: True
- If ``True``, label rotations will always be plus
- or minus 90 degrees from level.
-
- use_clabeltext : bool, default: False
- If ``True``, use `.Text.set_transform_rotates_text` to ensure that
- label rotation is updated whenever the axes aspect changes.
-
- zorder : float or None, default: ``(2 + contour.get_zorder())``
- zorder of the contour labels.
-
- Returns
- -------
- labels
- A list of `.Text` instances for the labels.
- """
-
- # clabel basically takes the input arguments and uses them to
- # add a list of "label specific" attributes to the ContourSet
- # object. These attributes are all of the form label* and names
- # should be fairly self explanatory.
- #
- # Once these attributes are set, clabel passes control to the
- # labels method (case of automatic label placement) or
- # `BlockingContourLabeler` (case of manual label placement).
-
- if fmt is None:
- fmt = ticker.ScalarFormatter(useOffset=False)
- fmt.create_dummy_axis()
- self.labelFmt = fmt
- self._use_clabeltext = use_clabeltext
- # Detect if manual selection is desired and remove from argument list.
- self.labelManual = manual
- self.rightside_up = rightside_up
- self._clabel_zorder = 2 + self.get_zorder() if zorder is None else zorder
-
- if levels is None:
- levels = self.levels
- indices = list(range(len(self.cvalues)))
- else:
- levlabs = list(levels)
- indices, levels = [], []
- for i, lev in enumerate(self.levels):
- if lev in levlabs:
- indices.append(i)
- levels.append(lev)
- if len(levels) < len(levlabs):
- raise ValueError(f"Specified levels {levlabs} don't match "
- f"available levels {self.levels}")
- self.labelLevelList = levels
- self.labelIndiceList = indices
-
- self._label_font_props = font_manager.FontProperties(size=fontsize)
-
- if colors is None:
- self.labelMappable = self
- self.labelCValueList = np.take(self.cvalues, self.labelIndiceList)
- else:
- cmap = mcolors.ListedColormap(colors, N=len(self.labelLevelList))
- self.labelCValueList = list(range(len(self.labelLevelList)))
- self.labelMappable = cm.ScalarMappable(cmap=cmap,
- norm=mcolors.NoNorm())
-
- self.labelXYs = []
-
- if np.iterable(manual):
- for x, y in manual:
- self.add_label_near(x, y, inline, inline_spacing)
- elif manual:
- print('Select label locations manually using first mouse button.')
- print('End manual selection with second mouse button.')
- if not inline:
- print('Remove last label by clicking third mouse button.')
- mpl._blocking_input.blocking_input_loop(
- self.axes.figure, ["button_press_event", "key_press_event"],
- timeout=-1, handler=functools.partial(
- _contour_labeler_event_handler,
- self, inline, inline_spacing))
- else:
- self.labels(inline, inline_spacing)
-
- return cbook.silent_list('text.Text', self.labelTexts)
-
- @_api.deprecated("3.7", alternative="cs.labelTexts[0].get_font()")
- @property
- def labelFontProps(self):
- return self._label_font_props
-
- @_api.deprecated("3.7", alternative=(
- "[cs.labelTexts[0].get_font().get_size()] * len(cs.labelLevelList)"))
- @property
- def labelFontSizeList(self):
- return [self._label_font_props.get_size()] * len(self.labelLevelList)
-
- @_api.deprecated("3.7", alternative="cs.labelTexts")
- @property
- def labelTextsList(self):
- return cbook.silent_list('text.Text', self.labelTexts)
-
- def print_label(self, linecontour, labelwidth):
- """Return whether a contour is long enough to hold a label."""
- return (len(linecontour) > 10 * labelwidth
- or (len(linecontour)
- and (np.ptp(linecontour, axis=0) > 1.2 * labelwidth).any()))
-
- def too_close(self, x, y, lw):
- """Return whether a label is already near this location."""
- thresh = (1.2 * lw) ** 2
- return any((x - loc[0]) ** 2 + (y - loc[1]) ** 2 < thresh
- for loc in self.labelXYs)
-
- def _get_nth_label_width(self, nth):
- """Return the width of the *nth* label, in pixels."""
- fig = self.axes.figure
- renderer = fig._get_renderer()
- return (Text(0, 0,
- self.get_text(self.labelLevelList[nth], self.labelFmt),
- figure=fig, fontproperties=self._label_font_props)
- .get_window_extent(renderer).width)
-
- @_api.deprecated("3.7", alternative="Artist.set")
- def set_label_props(self, label, text, color):
- """Set the label properties - color, fontsize, text."""
- label.set_text(text)
- label.set_color(color)
- label.set_fontproperties(self._label_font_props)
- label.set_clip_box(self.axes.bbox)
-
- def get_text(self, lev, fmt):
- """Get the text of the label."""
- if isinstance(lev, str):
- return lev
- elif isinstance(fmt, dict):
- return fmt.get(lev, '%1.3f')
- elif callable(getattr(fmt, "format_ticks", None)):
- return fmt.format_ticks([*self.labelLevelList, lev])[-1]
- elif callable(fmt):
- return fmt(lev)
- else:
- return fmt % lev
-
- def locate_label(self, linecontour, labelwidth):
- """
- Find good place to draw a label (relatively flat part of the contour).
- """
- ctr_size = len(linecontour)
- n_blocks = int(np.ceil(ctr_size / labelwidth)) if labelwidth > 1 else 1
- block_size = ctr_size if n_blocks == 1 else int(labelwidth)
- # Split contour into blocks of length ``block_size``, filling the last
- # block by cycling the contour start (per `np.resize` semantics). (Due
- # to cycling, the index returned is taken modulo ctr_size.)
- xx = np.resize(linecontour[:, 0], (n_blocks, block_size))
- yy = np.resize(linecontour[:, 1], (n_blocks, block_size))
- yfirst = yy[:, :1]
- ylast = yy[:, -1:]
- xfirst = xx[:, :1]
- xlast = xx[:, -1:]
- s = (yfirst - yy) * (xlast - xfirst) - (xfirst - xx) * (ylast - yfirst)
- l = np.hypot(xlast - xfirst, ylast - yfirst)
- # Ignore warning that divide by zero throws, as this is a valid option
- with np.errstate(divide='ignore', invalid='ignore'):
- distances = (abs(s) / l).sum(axis=-1)
- # Labels are drawn in the middle of the block (``hbsize``) where the
- # contour is the closest (per ``distances``) to a straight line, but
- # not `too_close()` to a preexisting label.
- hbsize = block_size // 2
- adist = np.argsort(distances)
- # If all candidates are `too_close()`, go back to the straightest part
- # (``adist[0]``).
- for idx in np.append(adist, adist[0]):
- x, y = xx[idx, hbsize], yy[idx, hbsize]
- if not self.too_close(x, y, labelwidth):
- break
- return x, y, (idx * block_size + hbsize) % ctr_size
-
- def _split_path_and_get_label_rotation(self, path, idx, screen_pos, lw, spacing=5):
- """
- Prepare for insertion of a label at index *idx* of *path*.
-
- Parameters
- ----------
- path : Path
- The path where the label will be inserted, in data space.
- idx : int
- The vertex index after which the label will be inserted.
- screen_pos : (float, float)
- The position where the label will be inserted, in screen space.
- lw : float
- The label width, in screen space.
- spacing : float
- Extra spacing around the label, in screen space.
-
- Returns
- -------
- path : Path
- The path, broken so that the label can be drawn over it.
- angle : float
- The rotation of the label.
-
- Notes
- -----
- Both tasks are done together to avoid calculating path lengths multiple times,
- which is relatively costly.
-
- The method used here involves computing the path length along the contour in
- pixel coordinates and then looking (label width / 2) away from central point to
- determine rotation and then to break contour if desired. The extra spacing is
- taken into account when breaking the path, but not when computing the angle.
- """
- if hasattr(self, "_old_style_split_collections"):
- vis = False
- for coll in self._old_style_split_collections:
- vis |= coll.get_visible()
- coll.remove()
- self.set_visible(vis)
- del self._old_style_split_collections # Invalidate them.
-
- xys = path.vertices
- codes = path.codes
-
- # Insert a vertex at idx/pos (converting back to data space), if there isn't yet
- # a vertex there. With infinite precision one could also always insert the
- # extra vertex (it will get masked out by the label below anyways), but floating
- # point inaccuracies (the point can have undergone a data->screen->data
- # transform loop) can slightly shift the point and e.g. shift the angle computed
- # below from exactly zero to nonzero.
- pos = self.get_transform().inverted().transform(screen_pos)
- if not np.allclose(pos, xys[idx]):
- xys = np.insert(xys, idx, pos, axis=0)
- codes = np.insert(codes, idx, Path.LINETO)
-
- # Find the connected component where the label will be inserted. Note that a
- # path always starts with a MOVETO, and we consider there's an implicit
- # MOVETO (closing the last path) at the end.
- movetos = (codes == Path.MOVETO).nonzero()[0]
- start = movetos[movetos <= idx][-1]
- try:
- stop = movetos[movetos > idx][0]
- except IndexError:
- stop = len(codes)
-
- # Restrict ourselves to the connected component.
- cc_xys = xys[start:stop]
- idx -= start
-
- # If the path is closed, rotate it s.t. it starts at the label.
- is_closed_path = codes[stop - 1] == Path.CLOSEPOLY
- if is_closed_path:
- cc_xys = np.concatenate([cc_xys[idx:-1], cc_xys[:idx+1]])
- idx = 0
-
- # Like np.interp, but additionally vectorized over fp.
- def interp_vec(x, xp, fp): return [np.interp(x, xp, col) for col in fp.T]
-
- # Use cumulative path lengths ("cpl") as curvilinear coordinate along contour.
- screen_xys = self.get_transform().transform(cc_xys)
- path_cpls = np.insert(
- np.cumsum(np.hypot(*np.diff(screen_xys, axis=0).T)), 0, 0)
- path_cpls -= path_cpls[idx]
-
- # Use linear interpolation to get end coordinates of label.
- target_cpls = np.array([-lw/2, lw/2])
- if is_closed_path: # For closed paths, target from the other end.
- target_cpls[0] += (path_cpls[-1] - path_cpls[0])
- (sx0, sx1), (sy0, sy1) = interp_vec(target_cpls, path_cpls, screen_xys)
- angle = np.rad2deg(np.arctan2(sy1 - sy0, sx1 - sx0)) # Screen space.
- if self.rightside_up: # Fix angle so text is never upside-down
- angle = (angle + 90) % 180 - 90
-
- target_cpls += [-spacing, +spacing] # Expand range by spacing.
-
- # Get indices near points of interest; use -1 as out of bounds marker.
- i0, i1 = np.interp(target_cpls, path_cpls, range(len(path_cpls)),
- left=-1, right=-1)
- i0 = math.floor(i0)
- i1 = math.ceil(i1)
- (x0, x1), (y0, y1) = interp_vec(target_cpls, path_cpls, cc_xys)
-
- # Actually break contours (dropping zero-len parts).
- new_xy_blocks = []
- new_code_blocks = []
- if is_closed_path:
- if i0 != -1 and i1 != -1:
- # This is probably wrong in the case that the entire contour would
- # be discarded, but ensures that a valid path is returned and is
- # consistent with behavior of mpl <3.8
- points = cc_xys[i1:i0+1]
- new_xy_blocks.extend([[(x1, y1)], points, [(x0, y0)]])
- nlines = len(points) + 1
- new_code_blocks.extend([[Path.MOVETO], [Path.LINETO] * nlines])
- else:
- if i0 != -1:
- new_xy_blocks.extend([cc_xys[:i0 + 1], [(x0, y0)]])
- new_code_blocks.extend([[Path.MOVETO], [Path.LINETO] * (i0 + 1)])
- if i1 != -1:
- new_xy_blocks.extend([[(x1, y1)], cc_xys[i1:]])
- new_code_blocks.extend([
- [Path.MOVETO], [Path.LINETO] * (len(cc_xys) - i1)])
-
- # Back to the full path.
- xys = np.concatenate([xys[:start], *new_xy_blocks, xys[stop:]])
- codes = np.concatenate([codes[:start], *new_code_blocks, codes[stop:]])
-
- return angle, Path(xys, codes)
-
- @_api.deprecated("3.8")
- def calc_label_rot_and_inline(self, slc, ind, lw, lc=None, spacing=5):
- """
- Calculate the appropriate label rotation given the linecontour
- coordinates in screen units, the index of the label location and the
- label width.
-
- If *lc* is not None or empty, also break contours and compute
- inlining.
-
- *spacing* is the empty space to leave around the label, in pixels.
-
- Both tasks are done together to avoid calculating path lengths
- multiple times, which is relatively costly.
-
- The method used here involves computing the path length along the
- contour in pixel coordinates and then looking approximately (label
- width / 2) away from central point to determine rotation and then to
- break contour if desired.
- """
-
- if lc is None:
- lc = []
- # Half the label width
- hlw = lw / 2.0
-
- # Check if closed and, if so, rotate contour so label is at edge
- closed = _is_closed_polygon(slc)
- if closed:
- slc = np.concatenate([slc[ind:-1], slc[:ind + 1]])
- if len(lc): # Rotate lc also if not empty
- lc = np.concatenate([lc[ind:-1], lc[:ind + 1]])
- ind = 0
-
- # Calculate path lengths
- pl = np.zeros(slc.shape[0], dtype=float)
- dx = np.diff(slc, axis=0)
- pl[1:] = np.cumsum(np.hypot(dx[:, 0], dx[:, 1]))
- pl = pl - pl[ind]
-
- # Use linear interpolation to get points around label
- xi = np.array([-hlw, hlw])
- if closed: # Look at end also for closed contours
- dp = np.array([pl[-1], 0])
- else:
- dp = np.zeros_like(xi)
-
- # Get angle of vector between the two ends of the label - must be
- # calculated in pixel space for text rotation to work correctly.
- (dx,), (dy,) = (np.diff(np.interp(dp + xi, pl, slc_col))
- for slc_col in slc.T)
- rotation = np.rad2deg(np.arctan2(dy, dx))
-
- if self.rightside_up:
- # Fix angle so text is never upside-down
- rotation = (rotation + 90) % 180 - 90
-
- # Break contour if desired
- nlc = []
- if len(lc):
- # Expand range by spacing
- xi = dp + xi + np.array([-spacing, spacing])
-
- # Get (integer) indices near points of interest; use -1 as marker
- # for out of bounds.
- I = np.interp(xi, pl, np.arange(len(pl)), left=-1, right=-1)
- I = [np.floor(I[0]).astype(int), np.ceil(I[1]).astype(int)]
- if I[0] != -1:
- xy1 = [np.interp(xi[0], pl, lc_col) for lc_col in lc.T]
- if I[1] != -1:
- xy2 = [np.interp(xi[1], pl, lc_col) for lc_col in lc.T]
-
- # Actually break contours
- if closed:
- # This will remove contour if shorter than label
- if all(i != -1 for i in I):
- nlc.append(np.vstack([xy2, lc[I[1]:I[0]+1], xy1]))
- else:
- # These will remove pieces of contour if they have length zero
- if I[0] != -1:
- nlc.append(np.vstack([lc[:I[0]+1], xy1]))
- if I[1] != -1:
- nlc.append(np.vstack([xy2, lc[I[1]:]]))
-
- # The current implementation removes contours completely
- # covered by labels. Uncomment line below to keep
- # original contour if this is the preferred behavior.
- # if not len(nlc): nlc = [lc]
-
- return rotation, nlc
-
- def add_label(self, x, y, rotation, lev, cvalue):
- """Add contour label without `.Text.set_transform_rotates_text`."""
- data_x, data_y = self.axes.transData.inverted().transform((x, y))
- t = Text(
- data_x, data_y,
- text=self.get_text(lev, self.labelFmt),
- rotation=rotation,
- horizontalalignment='center', verticalalignment='center',
- zorder=self._clabel_zorder,
- color=self.labelMappable.to_rgba(cvalue, alpha=self.get_alpha()),
- fontproperties=self._label_font_props,
- clip_box=self.axes.bbox)
- self.labelTexts.append(t)
- self.labelCValues.append(cvalue)
- self.labelXYs.append((x, y))
- # Add label to plot here - useful for manual mode label selection
- self.axes.add_artist(t)
-
- def add_label_clabeltext(self, x, y, rotation, lev, cvalue):
- """Add contour label with `.Text.set_transform_rotates_text`."""
- self.add_label(x, y, rotation, lev, cvalue)
- # Grab the last added text, and reconfigure its rotation.
- t = self.labelTexts[-1]
- data_rotation, = self.axes.transData.inverted().transform_angles(
- [rotation], [[x, y]])
- t.set(rotation=data_rotation, transform_rotates_text=True)
-
- def add_label_near(self, x, y, inline=True, inline_spacing=5,
- transform=None):
- """
- Add a label near the point ``(x, y)``.
-
- Parameters
- ----------
- x, y : float
- The approximate location of the label.
- inline : bool, default: True
- If *True* remove the segment of the contour beneath the label.
- inline_spacing : int, default: 5
- Space in pixels to leave on each side of label when placing
- inline. This spacing will be exact for labels at locations where
- the contour is straight, less so for labels on curved contours.
- transform : `.Transform` or `False`, default: ``self.axes.transData``
- A transform applied to ``(x, y)`` before labeling. The default
- causes ``(x, y)`` to be interpreted as data coordinates. `False`
- is a synonym for `.IdentityTransform`; i.e. ``(x, y)`` should be
- interpreted as display coordinates.
- """
-
- if transform is None:
- transform = self.axes.transData
- if transform:
- x, y = transform.transform((x, y))
-
- idx_level_min, idx_vtx_min, proj = self._find_nearest_contour(
- (x, y), self.labelIndiceList)
- path = self._paths[idx_level_min]
- level = self.labelIndiceList.index(idx_level_min)
- label_width = self._get_nth_label_width(level)
- rotation, path = self._split_path_and_get_label_rotation(
- path, idx_vtx_min, proj, label_width, inline_spacing)
- self.add_label(*proj, rotation, self.labelLevelList[idx_level_min],
- self.labelCValueList[idx_level_min])
-
- if inline:
- self._paths[idx_level_min] = path
-
- def pop_label(self, index=-1):
- """Defaults to removing last label, but any index can be supplied"""
- self.labelCValues.pop(index)
- t = self.labelTexts.pop(index)
- t.remove()
-
- def labels(self, inline, inline_spacing):
-
- if self._use_clabeltext:
- add_label = self.add_label_clabeltext
- else:
- add_label = self.add_label
-
- for idx, (icon, lev, cvalue) in enumerate(zip(
- self.labelIndiceList,
- self.labelLevelList,
- self.labelCValueList,
- )):
- trans = self.get_transform()
- label_width = self._get_nth_label_width(idx)
- additions = []
- for subpath in self._paths[icon]._iter_connected_components():
- screen_xys = trans.transform(subpath.vertices)
- # Check if long enough for a label
- if self.print_label(screen_xys, label_width):
- x, y, idx = self.locate_label(screen_xys, label_width)
- rotation, path = self._split_path_and_get_label_rotation(
- subpath, idx, (x, y),
- label_width, inline_spacing)
- add_label(x, y, rotation, lev, cvalue) # Really add label.
- if inline: # If inline, add new contours
- additions.append(path)
- else: # If not adding label, keep old path
- additions.append(subpath)
- # After looping over all segments on a contour, replace old path by new one
- # if inlining.
- if inline:
- self._paths[icon] = Path.make_compound_path(*additions)
-
- def remove(self):
- super().remove()
- for text in self.labelTexts:
- text.remove()
-
-
-def _is_closed_polygon(X):
- """
- Return whether first and last object in a sequence are the same. These are
- presumably coordinates on a polygonal curve, in which case this function
- tests if that curve is closed.
- """
- return np.allclose(X[0], X[-1], rtol=1e-10, atol=1e-13)
-
-
-def _find_closest_point_on_path(xys, p):
- """
- Parameters
- ----------
- xys : (N, 2) array-like
- Coordinates of vertices.
- p : (float, float)
- Coordinates of point.
-
- Returns
- -------
- d2min : float
- Minimum square distance of *p* to *xys*.
- proj : (float, float)
- Projection of *p* onto *xys*.
- imin : (int, int)
- Consecutive indices of vertices of segment in *xys* where *proj* is.
- Segments are considered as including their end-points; i.e. if the
- closest point on the path is a node in *xys* with index *i*, this
- returns ``(i-1, i)``. For the special case where *xys* is a single
- point, this returns ``(0, 0)``.
- """
- if len(xys) == 1:
- return (((p - xys[0]) ** 2).sum(), xys[0], (0, 0))
- dxys = xys[1:] - xys[:-1] # Individual segment vectors.
- norms = (dxys ** 2).sum(axis=1)
- norms[norms == 0] = 1 # For zero-length segment, replace 0/0 by 0/1.
- rel_projs = np.clip( # Project onto each segment in relative 0-1 coords.
- ((p - xys[:-1]) * dxys).sum(axis=1) / norms,
- 0, 1)[:, None]
- projs = xys[:-1] + rel_projs * dxys # Projs. onto each segment, in (x, y).
- d2s = ((projs - p) ** 2).sum(axis=1) # Squared distances.
- imin = np.argmin(d2s)
- return (d2s[imin], projs[imin], (imin, imin+1))
-
-
-_docstring.interpd.update(contour_set_attributes=r"""
-Attributes
-----------
-ax : `~matplotlib.axes.Axes`
- The Axes object in which the contours are drawn.
-
-collections : `.silent_list` of `.PathCollection`\s
- The `.Artist`\s representing the contour. This is a list of
- `.PathCollection`\s for both line and filled contours.
-
-levels : array
- The values of the contour levels.
-
-layers : array
- Same as levels for line contours; half-way between
- levels for filled contours. See ``ContourSet._process_colors``.
-""")
-
-
-@_docstring.dedent_interpd
-class ContourSet(ContourLabeler, mcoll.Collection):
- """
- Store a set of contour lines or filled regions.
-
- User-callable method: `~.Axes.clabel`
-
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
-
- levels : [level0, level1, ..., leveln]
- A list of floating point numbers indicating the contour levels.
-
- allsegs : [level0segs, level1segs, ...]
- List of all the polygon segments for all the *levels*.
- For contour lines ``len(allsegs) == len(levels)``, and for
- filled contour regions ``len(allsegs) = len(levels)-1``. The lists
- should look like ::
-
- level0segs = [polygon0, polygon1, ...]
- polygon0 = [[x0, y0], [x1, y1], ...]
-
- allkinds : ``None`` or [level0kinds, level1kinds, ...]
- Optional list of all the polygon vertex kinds (code types), as
- described and used in Path. This is used to allow multiply-
- connected paths such as holes within filled polygons.
- If not ``None``, ``len(allkinds) == len(allsegs)``. The lists
- should look like ::
-
- level0kinds = [polygon0kinds, ...]
- polygon0kinds = [vertexcode0, vertexcode1, ...]
-
- If *allkinds* is not ``None``, usually all polygons for a
- particular contour level are grouped together so that
- ``level0segs = [polygon0]`` and ``level0kinds = [polygon0kinds]``.
-
- **kwargs
- Keyword arguments are as described in the docstring of
- `~.Axes.contour`.
-
- %(contour_set_attributes)s
- """
-
- def __init__(self, ax, *args,
- levels=None, filled=False, linewidths=None, linestyles=None,
- hatches=(None,), alpha=None, origin=None, extent=None,
- cmap=None, colors=None, norm=None, vmin=None, vmax=None,
- extend='neither', antialiased=None, nchunk=0, locator=None,
- transform=None, negative_linestyles=None, clip_path=None,
- **kwargs):
- """
- Draw contour lines or filled regions, depending on
- whether keyword arg *filled* is ``False`` (default) or ``True``.
-
- Call signature::
-
- ContourSet(ax, levels, allsegs, [allkinds], **kwargs)
-
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The `~.axes.Axes` object to draw on.
-
- levels : [level0, level1, ..., leveln]
- A list of floating point numbers indicating the contour
- levels.
-
- allsegs : [level0segs, level1segs, ...]
- List of all the polygon segments for all the *levels*.
- For contour lines ``len(allsegs) == len(levels)``, and for
- filled contour regions ``len(allsegs) = len(levels)-1``. The lists
- should look like ::
-
- level0segs = [polygon0, polygon1, ...]
- polygon0 = [[x0, y0], [x1, y1], ...]
-
- allkinds : [level0kinds, level1kinds, ...], optional
- Optional list of all the polygon vertex kinds (code types), as
- described and used in Path. This is used to allow multiply-
- connected paths such as holes within filled polygons.
- If not ``None``, ``len(allkinds) == len(allsegs)``. The lists
- should look like ::
-
- level0kinds = [polygon0kinds, ...]
- polygon0kinds = [vertexcode0, vertexcode1, ...]
-
- If *allkinds* is not ``None``, usually all polygons for a
- particular contour level are grouped together so that
- ``level0segs = [polygon0]`` and ``level0kinds = [polygon0kinds]``.
-
- **kwargs
- Keyword arguments are as described in the docstring of
- `~.Axes.contour`.
- """
- if antialiased is None and filled:
- # Eliminate artifacts; we are not stroking the boundaries.
- antialiased = False
- # The default for line contours will be taken from the
- # LineCollection default, which uses :rc:`lines.antialiased`.
- super().__init__(
- antialiaseds=antialiased,
- alpha=alpha,
- clip_path=clip_path,
- transform=transform,
- )
- self.axes = ax
- self.levels = levels
- self.filled = filled
- self.hatches = hatches
- self.origin = origin
- self.extent = extent
- self.colors = colors
- self.extend = extend
-
- self.nchunk = nchunk
- self.locator = locator
- if (isinstance(norm, mcolors.LogNorm)
- or isinstance(self.locator, ticker.LogLocator)):
- self.logscale = True
- if norm is None:
- norm = mcolors.LogNorm()
- else:
- self.logscale = False
-
- _api.check_in_list([None, 'lower', 'upper', 'image'], origin=origin)
- if self.extent is not None and len(self.extent) != 4:
- raise ValueError(
- "If given, 'extent' must be None or (x0, x1, y0, y1)")
- if self.colors is not None and cmap is not None:
- raise ValueError('Either colors or cmap must be None')
- if self.origin == 'image':
- self.origin = mpl.rcParams['image.origin']
-
- self._orig_linestyles = linestyles # Only kept for user access.
- self.negative_linestyles = negative_linestyles
- # If negative_linestyles was not defined as a keyword argument, define
- # negative_linestyles with rcParams
- if self.negative_linestyles is None:
- self.negative_linestyles = \
- mpl.rcParams['contour.negative_linestyle']
-
- kwargs = self._process_args(*args, **kwargs)
- self._process_levels()
-
- self._extend_min = self.extend in ['min', 'both']
- self._extend_max = self.extend in ['max', 'both']
- if self.colors is not None:
- ncolors = len(self.levels)
- if self.filled:
- ncolors -= 1
- i0 = 0
-
- # Handle the case where colors are given for the extended
- # parts of the contour.
-
- use_set_under_over = False
- # if we are extending the lower end, and we've been given enough
- # colors then skip the first color in the resulting cmap. For the
- # extend_max case we don't need to worry about passing more colors
- # than ncolors as ListedColormap will clip.
- total_levels = (ncolors +
- int(self._extend_min) +
- int(self._extend_max))
- if (len(self.colors) == total_levels and
- (self._extend_min or self._extend_max)):
- use_set_under_over = True
- if self._extend_min:
- i0 = 1
-
- cmap = mcolors.ListedColormap(self.colors[i0:None], N=ncolors)
-
- if use_set_under_over:
- if self._extend_min:
- cmap.set_under(self.colors[0])
- if self._extend_max:
- cmap.set_over(self.colors[-1])
-
- # label lists must be initialized here
- self.labelTexts = []
- self.labelCValues = []
-
- self.set_cmap(cmap)
- if norm is not None:
- self.set_norm(norm)
- with self.norm.callbacks.blocked(signal="changed"):
- if vmin is not None:
- self.norm.vmin = vmin
- if vmax is not None:
- self.norm.vmax = vmax
- self.norm._changed()
- self._process_colors()
-
- if self._paths is None:
- self._paths = self._make_paths_from_contour_generator()
-
- if self.filled:
- if linewidths is not None:
- _api.warn_external('linewidths is ignored by contourf')
- # Lower and upper contour levels.
- lowers, uppers = self._get_lowers_and_uppers()
- self.set(
- edgecolor="none",
- # Default zorder taken from Collection
- zorder=kwargs.pop("zorder", 1),
- )
-
- else:
- self.set(
- facecolor="none",
- linewidths=self._process_linewidths(linewidths),
- linestyle=self._process_linestyles(linestyles),
- # Default zorder taken from LineCollection, which is higher
- # than for filled contours so that lines are displayed on top.
- zorder=kwargs.pop("zorder", 2),
- label="_nolegend_",
- )
-
- self.axes.add_collection(self, autolim=False)
- self.sticky_edges.x[:] = [self._mins[0], self._maxs[0]]
- self.sticky_edges.y[:] = [self._mins[1], self._maxs[1]]
- self.axes.update_datalim([self._mins, self._maxs])
- self.axes.autoscale_view(tight=True)
-
- self.changed() # set the colors
-
- if kwargs:
- _api.warn_external(
- 'The following kwargs were not used by contour: ' +
- ", ".join(map(repr, kwargs))
- )
-
- allsegs = property(lambda self: [
- [subp.vertices for subp in p._iter_connected_components()]
- for p in self.get_paths()])
- allkinds = property(lambda self: [
- [subp.codes for subp in p._iter_connected_components()]
- for p in self.get_paths()])
- tcolors = _api.deprecated("3.8")(property(lambda self: [
- (tuple(rgba),) for rgba in self.to_rgba(self.cvalues, self.alpha)]))
- tlinewidths = _api.deprecated("3.8")(property(lambda self: [
- (w,) for w in self.get_linewidths()]))
- alpha = property(lambda self: self.get_alpha())
- linestyles = property(lambda self: self._orig_linestyles)
-
- @_api.deprecated("3.8", alternative="set_antialiased or get_antialiased",
- addendum="Note that get_antialiased returns an array.")
- @property
- def antialiased(self):
- return all(self.get_antialiased())
-
- @antialiased.setter
- def antialiased(self, aa):
- self.set_antialiased(aa)
-
- @_api.deprecated("3.8")
- @property
- def collections(self):
- # On access, make oneself invisible and instead add the old-style collections
- # (one PathCollection per level). We do not try to further split contours into
- # connected components as we already lost track of what pairs of contours need
- # to be considered as single units to draw filled regions with holes.
- if not hasattr(self, "_old_style_split_collections"):
- self.set_visible(False)
- fcs = self.get_facecolor()
- ecs = self.get_edgecolor()
- lws = self.get_linewidth()
- lss = self.get_linestyle()
- self._old_style_split_collections = []
- for idx, path in enumerate(self._paths):
- pc = mcoll.PathCollection(
- [path] if len(path.vertices) else [],
- alpha=self.get_alpha(),
- antialiaseds=self._antialiaseds[idx % len(self._antialiaseds)],
- transform=self.get_transform(),
- zorder=self.get_zorder(),
- label="_nolegend_",
- facecolor=fcs[idx] if len(fcs) else "none",
- edgecolor=ecs[idx] if len(ecs) else "none",
- linewidths=[lws[idx % len(lws)]],
- linestyles=[lss[idx % len(lss)]],
- )
- if self.filled:
- pc.set(hatch=self.hatches[idx % len(self.hatches)])
- self._old_style_split_collections.append(pc)
- for col in self._old_style_split_collections:
- self.axes.add_collection(col)
- return self._old_style_split_collections
-
- def get_transform(self):
- """Return the `.Transform` instance used by this ContourSet."""
- if self._transform is None:
- self._transform = self.axes.transData
- elif (not isinstance(self._transform, mtransforms.Transform)
- and hasattr(self._transform, '_as_mpl_transform')):
- self._transform = self._transform._as_mpl_transform(self.axes)
- return self._transform
-
- def __getstate__(self):
- state = self.__dict__.copy()
- # the C object _contour_generator cannot currently be pickled. This
- # isn't a big issue as it is not actually used once the contour has
- # been calculated.
- state['_contour_generator'] = None
- return state
-
- def legend_elements(self, variable_name='x', str_format=str):
- """
- Return a list of artists and labels suitable for passing through
- to `~.Axes.legend` which represent this ContourSet.
-
- The labels have the form "0 < x <= 1" stating the data ranges which
- the artists represent.
-
- Parameters
- ----------
- variable_name : str
- The string used inside the inequality used on the labels.
- str_format : function: float -> str
- Function used to format the numbers in the labels.
-
- Returns
- -------
- artists : list[`.Artist`]
- A list of the artists.
- labels : list[str]
- A list of the labels.
- """
- artists = []
- labels = []
-
- if self.filled:
- lowers, uppers = self._get_lowers_and_uppers()
- n_levels = len(self._paths)
- for idx in range(n_levels):
- artists.append(mpatches.Rectangle(
- (0, 0), 1, 1,
- facecolor=self.get_facecolor()[idx],
- hatch=self.hatches[idx % len(self.hatches)],
- ))
- lower = str_format(lowers[idx])
- upper = str_format(uppers[idx])
- if idx == 0 and self.extend in ('min', 'both'):
- labels.append(fr'${variable_name} \leq {lower}s$')
- elif idx == n_levels - 1 and self.extend in ('max', 'both'):
- labels.append(fr'${variable_name} > {upper}s$')
- else:
- labels.append(fr'${lower} < {variable_name} \leq {upper}$')
- else:
- for idx, level in enumerate(self.levels):
- artists.append(Line2D(
- [], [],
- color=self.get_edgecolor()[idx],
- linewidth=self.get_linewidths()[idx],
- linestyle=self.get_linestyles()[idx],
- ))
- labels.append(fr'${variable_name} = {str_format(level)}$')
-
- return artists, labels
-
- def _process_args(self, *args, **kwargs):
- """
- Process *args* and *kwargs*; override in derived classes.
-
- Must set self.levels, self.zmin and self.zmax, and update axes limits.
- """
- self.levels = args[0]
- allsegs = args[1]
- allkinds = args[2] if len(args) > 2 else None
- self.zmax = np.max(self.levels)
- self.zmin = np.min(self.levels)
-
- if allkinds is None:
- allkinds = [[None] * len(segs) for segs in allsegs]
-
- # Check lengths of levels and allsegs.
- if self.filled:
- if len(allsegs) != len(self.levels) - 1:
- raise ValueError('must be one less number of segments as '
- 'levels')
- else:
- if len(allsegs) != len(self.levels):
- raise ValueError('must be same number of segments as levels')
-
- # Check length of allkinds.
- if len(allkinds) != len(allsegs):
- raise ValueError('allkinds has different length to allsegs')
-
- # Determine x, y bounds and update axes data limits.
- flatseglist = [s for seg in allsegs for s in seg]
- points = np.concatenate(flatseglist, axis=0)
- self._mins = points.min(axis=0)
- self._maxs = points.max(axis=0)
-
- # Each entry in (allsegs, allkinds) is a list of (segs, kinds): segs is a list
- # of (N, 2) arrays of xy coordinates, kinds is a list of arrays of corresponding
- # pathcodes. However, kinds can also be None; in which case all paths in that
- # list are codeless (this case is normalized above). These lists are used to
- # construct paths, which then get concatenated.
- self._paths = [Path.make_compound_path(*map(Path, segs, kinds))
- for segs, kinds in zip(allsegs, allkinds)]
-
- return kwargs
-
- def _make_paths_from_contour_generator(self):
- """Compute ``paths`` using C extension."""
- if self._paths is not None:
- return self._paths
- paths = []
- empty_path = Path(np.empty((0, 2)))
- if self.filled:
- lowers, uppers = self._get_lowers_and_uppers()
- for level, level_upper in zip(lowers, uppers):
- vertices, kinds = \
- self._contour_generator.create_filled_contour(
- level, level_upper)
- paths.append(Path(np.concatenate(vertices), np.concatenate(kinds))
- if len(vertices) else empty_path)
- else:
- for level in self.levels:
- vertices, kinds = self._contour_generator.create_contour(level)
- paths.append(Path(np.concatenate(vertices), np.concatenate(kinds))
- if len(vertices) else empty_path)
- return paths
-
- def _get_lowers_and_uppers(self):
- """
- Return ``(lowers, uppers)`` for filled contours.
- """
- lowers = self._levels[:-1]
- if self.zmin == lowers[0]:
- # Include minimum values in lowest interval
- lowers = lowers.copy() # so we don't change self._levels
- if self.logscale:
- lowers[0] = 0.99 * self.zmin
- else:
- lowers[0] -= 1
- uppers = self._levels[1:]
- return (lowers, uppers)
-
- def changed(self):
- if not hasattr(self, "cvalues"):
- self._process_colors() # Sets cvalues.
- # Force an autoscale immediately because self.to_rgba() calls
- # autoscale_None() internally with the data passed to it,
- # so if vmin/vmax are not set yet, this would override them with
- # content from *cvalues* rather than levels like we want
- self.norm.autoscale_None(self.levels)
- self.set_array(self.cvalues)
- self.update_scalarmappable()
- alphas = np.broadcast_to(self.get_alpha(), len(self.cvalues))
- for label, cv, alpha in zip(self.labelTexts, self.labelCValues, alphas):
- label.set_alpha(alpha)
- label.set_color(self.labelMappable.to_rgba(cv))
- super().changed()
-
- def _autolev(self, N):
- """
- Select contour levels to span the data.
-
- The target number of levels, *N*, is used only when the
- scale is not log and default locator is used.
-
- We need two more levels for filled contours than for
- line contours, because for the latter we need to specify
- the lower and upper boundary of each range. For example,
- a single contour boundary, say at z = 0, requires only
- one contour line, but two filled regions, and therefore
- three levels to provide boundaries for both regions.
- """
- if self.locator is None:
- if self.logscale:
- self.locator = ticker.LogLocator()
- else:
- self.locator = ticker.MaxNLocator(N + 1, min_n_ticks=1)
-
- lev = self.locator.tick_values(self.zmin, self.zmax)
-
- try:
- if self.locator._symmetric:
- return lev
- except AttributeError:
- pass
-
- # Trim excess levels the locator may have supplied.
- under = np.nonzero(lev < self.zmin)[0]
- i0 = under[-1] if len(under) else 0
- over = np.nonzero(lev > self.zmax)[0]
- i1 = over[0] + 1 if len(over) else len(lev)
- if self.extend in ('min', 'both'):
- i0 += 1
- if self.extend in ('max', 'both'):
- i1 -= 1
-
- if i1 - i0 < 3:
- i0, i1 = 0, len(lev)
-
- return lev[i0:i1]
-
- def _process_contour_level_args(self, args, z_dtype):
- """
- Determine the contour levels and store in self.levels.
- """
- if self.levels is None:
- if args:
- levels_arg = args[0]
- elif np.issubdtype(z_dtype, bool):
- if self.filled:
- levels_arg = [0, .5, 1]
- else:
- levels_arg = [.5]
- else:
- levels_arg = 7 # Default, hard-wired.
- else:
- levels_arg = self.levels
- if isinstance(levels_arg, Integral):
- self.levels = self._autolev(levels_arg)
- else:
- self.levels = np.asarray(levels_arg, np.float64)
- if self.filled and len(self.levels) < 2:
- raise ValueError("Filled contours require at least 2 levels.")
- if len(self.levels) > 1 and np.min(np.diff(self.levels)) <= 0.0:
- raise ValueError("Contour levels must be increasing")
-
- def _process_levels(self):
- """
- Assign values to :attr:`layers` based on :attr:`levels`,
- adding extended layers as needed if contours are filled.
-
- For line contours, layers simply coincide with levels;
- a line is a thin layer. No extended levels are needed
- with line contours.
- """
- # Make a private _levels to include extended regions; we
- # want to leave the original levels attribute unchanged.
- # (Colorbar needs this even for line contours.)
- self._levels = list(self.levels)
-
- if self.logscale:
- lower, upper = 1e-250, 1e250
- else:
- lower, upper = -1e250, 1e250
-
- if self.extend in ('both', 'min'):
- self._levels.insert(0, lower)
- if self.extend in ('both', 'max'):
- self._levels.append(upper)
- self._levels = np.asarray(self._levels)
-
- if not self.filled:
- self.layers = self.levels
- return
-
- # Layer values are mid-way between levels in screen space.
- if self.logscale:
- # Avoid overflow by taking sqrt before multiplying.
- self.layers = (np.sqrt(self._levels[:-1])
- * np.sqrt(self._levels[1:]))
- else:
- self.layers = 0.5 * (self._levels[:-1] + self._levels[1:])
-
- def _process_colors(self):
- """
- Color argument processing for contouring.
-
- Note that we base the colormapping on the contour levels
- and layers, not on the actual range of the Z values. This
- means we don't have to worry about bad values in Z, and we
- always have the full dynamic range available for the selected
- levels.
-
- The color is based on the midpoint of the layer, except for
- extended end layers. By default, the norm vmin and vmax
- are the extreme values of the non-extended levels. Hence,
- the layer color extremes are not the extreme values of
- the colormap itself, but approach those values as the number
- of levels increases. An advantage of this scheme is that
- line contours, when added to filled contours, take on
- colors that are consistent with those of the filled regions;
- for example, a contour line on the boundary between two
- regions will have a color intermediate between those
- of the regions.
-
- """
- self.monochrome = self.cmap.monochrome
- if self.colors is not None:
- # Generate integers for direct indexing.
- i0, i1 = 0, len(self.levels)
- if self.filled:
- i1 -= 1
- # Out of range indices for over and under:
- if self.extend in ('both', 'min'):
- i0 -= 1
- if self.extend in ('both', 'max'):
- i1 += 1
- self.cvalues = list(range(i0, i1))
- self.set_norm(mcolors.NoNorm())
- else:
- self.cvalues = self.layers
- self.norm.autoscale_None(self.levels)
- self.set_array(self.cvalues)
- self.update_scalarmappable()
- if self.extend in ('both', 'max', 'min'):
- self.norm.clip = False
-
- def _process_linewidths(self, linewidths):
- Nlev = len(self.levels)
- if linewidths is None:
- default_linewidth = mpl.rcParams['contour.linewidth']
- if default_linewidth is None:
- default_linewidth = mpl.rcParams['lines.linewidth']
- return [default_linewidth] * Nlev
- elif not np.iterable(linewidths):
- return [linewidths] * Nlev
- else:
- linewidths = list(linewidths)
- return (linewidths * math.ceil(Nlev / len(linewidths)))[:Nlev]
-
- def _process_linestyles(self, linestyles):
- Nlev = len(self.levels)
- if linestyles is None:
- tlinestyles = ['solid'] * Nlev
- if self.monochrome:
- eps = - (self.zmax - self.zmin) * 1e-15
- for i, lev in enumerate(self.levels):
- if lev < eps:
- tlinestyles[i] = self.negative_linestyles
- else:
- if isinstance(linestyles, str):
- tlinestyles = [linestyles] * Nlev
- elif np.iterable(linestyles):
- tlinestyles = list(linestyles)
- if len(tlinestyles) < Nlev:
- nreps = int(np.ceil(Nlev / len(linestyles)))
- tlinestyles = tlinestyles * nreps
- if len(tlinestyles) > Nlev:
- tlinestyles = tlinestyles[:Nlev]
- else:
- raise ValueError("Unrecognized type for linestyles kwarg")
- return tlinestyles
-
- def _find_nearest_contour(self, xy, indices=None):
- """
- Find the point in the unfilled contour plot that is closest (in screen
- space) to point *xy*.
-
- Parameters
- ----------
- xy : tuple[float, float]
- The reference point (in screen space).
- indices : list of int or None, default: None
- Indices of contour levels to consider. If None (the default), all levels
- are considered.
-
- Returns
- -------
- idx_level_min : int
- The index of the contour level closest to *xy*.
- idx_vtx_min : int
- The index of the `.Path` segment closest to *xy* (at that level).
- proj : (float, float)
- The point in the contour plot closest to *xy*.
- """
-
- # Convert each contour segment to pixel coordinates and then compare the given
- # point to those coordinates for each contour. This is fast enough in normal
- # cases, but speedups may be possible.
-
- if self.filled:
- raise ValueError("Method does not support filled contours")
-
- if indices is None:
- indices = range(len(self._paths))
-
- d2min = np.inf
- idx_level_min = idx_vtx_min = proj_min = None
-
- for idx_level in indices:
- path = self._paths[idx_level]
- idx_vtx_start = 0
- for subpath in path._iter_connected_components():
- if not len(subpath.vertices):
- continue
- lc = self.get_transform().transform(subpath.vertices)
- d2, proj, leg = _find_closest_point_on_path(lc, xy)
- if d2 < d2min:
- d2min = d2
- idx_level_min = idx_level
- idx_vtx_min = leg[1] + idx_vtx_start
- proj_min = proj
- idx_vtx_start += len(subpath)
-
- return idx_level_min, idx_vtx_min, proj_min
-
- def find_nearest_contour(self, x, y, indices=None, pixel=True):
- """
- Find the point in the contour plot that is closest to ``(x, y)``.
-
- This method does not support filled contours.
-
- Parameters
- ----------
- x, y : float
- The reference point.
- indices : list of int or None, default: None
- Indices of contour levels to consider. If None (the default), all
- levels are considered.
- pixel : bool, default: True
- If *True*, measure distance in pixel (screen) space, which is
- useful for manual contour labeling; else, measure distance in axes
- space.
-
- Returns
- -------
- path : int
- The index of the path that is closest to ``(x, y)``. Each path corresponds
- to one contour level.
- subpath : int
- The index within that closest path of the subpath that is closest to
- ``(x, y)``. Each subpath corresponds to one unbroken contour line.
- index : int
- The index of the vertices within that subpath that are closest to
- ``(x, y)``.
- xmin, ymin : float
- The point in the contour plot that is closest to ``(x, y)``.
- d2 : float
- The squared distance from ``(xmin, ymin)`` to ``(x, y)``.
- """
- segment = index = d2 = None
-
- with ExitStack() as stack:
- if not pixel:
- # _find_nearest_contour works in pixel space. We want axes space, so
- # effectively disable the transformation here by setting to identity.
- stack.enter_context(self._cm_set(
- transform=mtransforms.IdentityTransform()))
-
- i_level, i_vtx, (xmin, ymin) = self._find_nearest_contour((x, y), indices)
-
- if i_level is not None:
- cc_cumlens = np.cumsum(
- [*map(len, self._paths[i_level]._iter_connected_components())])
- segment = cc_cumlens.searchsorted(i_vtx, "right")
- index = i_vtx if segment == 0 else i_vtx - cc_cumlens[segment - 1]
- d2 = (xmin-x)**2 + (ymin-y)**2
-
- return (i_level, segment, index, xmin, ymin, d2)
-
- def draw(self, renderer):
- paths = self._paths
- n_paths = len(paths)
- if not self.filled or all(hatch is None for hatch in self.hatches):
- super().draw(renderer)
- return
- # In presence of hatching, draw contours one at a time.
- for idx in range(n_paths):
- with cbook._setattr_cm(self, _paths=[paths[idx]]), self._cm_set(
- hatch=self.hatches[idx % len(self.hatches)],
- array=[self.get_array()[idx]],
- linewidths=[self.get_linewidths()[idx % len(self.get_linewidths())]],
- linestyles=[self.get_linestyles()[idx % len(self.get_linestyles())]],
- ):
- super().draw(renderer)
-
-
-@_docstring.dedent_interpd
-class QuadContourSet(ContourSet):
- """
- Create and store a set of contour lines or filled regions.
-
- This class is typically not instantiated directly by the user but by
- `~.Axes.contour` and `~.Axes.contourf`.
-
- %(contour_set_attributes)s
- """
-
- def _process_args(self, *args, corner_mask=None, algorithm=None, **kwargs):
- """
- Process args and kwargs.
- """
- if args and isinstance(args[0], QuadContourSet):
- if self.levels is None:
- self.levels = args[0].levels
- self.zmin = args[0].zmin
- self.zmax = args[0].zmax
- self._corner_mask = args[0]._corner_mask
- contour_generator = args[0]._contour_generator
- self._mins = args[0]._mins
- self._maxs = args[0]._maxs
- self._algorithm = args[0]._algorithm
- else:
- import contourpy
-
- if algorithm is None:
- algorithm = mpl.rcParams['contour.algorithm']
- mpl.rcParams.validate["contour.algorithm"](algorithm)
- self._algorithm = algorithm
-
- if corner_mask is None:
- if self._algorithm == "mpl2005":
- # mpl2005 does not support corner_mask=True so if not
- # specifically requested then disable it.
- corner_mask = False
- else:
- corner_mask = mpl.rcParams['contour.corner_mask']
- self._corner_mask = corner_mask
-
- x, y, z = self._contour_args(args, kwargs)
-
- contour_generator = contourpy.contour_generator(
- x, y, z, name=self._algorithm, corner_mask=self._corner_mask,
- line_type=contourpy.LineType.SeparateCode,
- fill_type=contourpy.FillType.OuterCode,
- chunk_size=self.nchunk)
-
- t = self.get_transform()
-
- # if the transform is not trans data, and some part of it
- # contains transData, transform the xs and ys to data coordinates
- if (t != self.axes.transData and
- any(t.contains_branch_seperately(self.axes.transData))):
- trans_to_data = t - self.axes.transData
- pts = np.vstack([x.flat, y.flat]).T
- transformed_pts = trans_to_data.transform(pts)
- x = transformed_pts[..., 0]
- y = transformed_pts[..., 1]
-
- self._mins = [ma.min(x), ma.min(y)]
- self._maxs = [ma.max(x), ma.max(y)]
-
- self._contour_generator = contour_generator
-
- return kwargs
-
- def _contour_args(self, args, kwargs):
- if self.filled:
- fn = 'contourf'
- else:
- fn = 'contour'
- nargs = len(args)
-
- if 0 < nargs <= 2:
- z, *args = args
- z = ma.asarray(z)
- x, y = self._initialize_x_y(z)
- elif 2 < nargs <= 4:
- x, y, z_orig, *args = args
- x, y, z = self._check_xyz(x, y, z_orig, kwargs)
-
- else:
- raise _api.nargs_error(fn, takes="from 1 to 4", given=nargs)
- z = ma.masked_invalid(z, copy=False)
- self.zmax = z.max().astype(float)
- self.zmin = z.min().astype(float)
- if self.logscale and self.zmin <= 0:
- z = ma.masked_where(z <= 0, z)
- _api.warn_external('Log scale: values of z <= 0 have been masked')
- self.zmin = z.min().astype(float)
- self._process_contour_level_args(args, z.dtype)
- return (x, y, z)
-
- def _check_xyz(self, x, y, z, kwargs):
- """
- Check that the shapes of the input arrays match; if x and y are 1D,
- convert them to 2D using meshgrid.
- """
- x, y = self.axes._process_unit_info([("x", x), ("y", y)], kwargs)
-
- x = np.asarray(x, dtype=np.float64)
- y = np.asarray(y, dtype=np.float64)
- z = ma.asarray(z)
-
- if z.ndim != 2:
- raise TypeError(f"Input z must be 2D, not {z.ndim}D")
- if z.shape[0] < 2 or z.shape[1] < 2:
- raise TypeError(f"Input z must be at least a (2, 2) shaped array, "
- f"but has shape {z.shape}")
- Ny, Nx = z.shape
-
- if x.ndim != y.ndim:
- raise TypeError(f"Number of dimensions of x ({x.ndim}) and y "
- f"({y.ndim}) do not match")
- if x.ndim == 1:
- nx, = x.shape
- ny, = y.shape
- if nx != Nx:
- raise TypeError(f"Length of x ({nx}) must match number of "
- f"columns in z ({Nx})")
- if ny != Ny:
- raise TypeError(f"Length of y ({ny}) must match number of "
- f"rows in z ({Ny})")
- x, y = np.meshgrid(x, y)
- elif x.ndim == 2:
- if x.shape != z.shape:
- raise TypeError(
- f"Shapes of x {x.shape} and z {z.shape} do not match")
- if y.shape != z.shape:
- raise TypeError(
- f"Shapes of y {y.shape} and z {z.shape} do not match")
- else:
- raise TypeError(f"Inputs x and y must be 1D or 2D, not {x.ndim}D")
-
- return x, y, z
-
- def _initialize_x_y(self, z):
- """
- Return X, Y arrays such that contour(Z) will match imshow(Z)
- if origin is not None.
- The center of pixel Z[i, j] depends on origin:
- if origin is None, x = j, y = i;
- if origin is 'lower', x = j + 0.5, y = i + 0.5;
- if origin is 'upper', x = j + 0.5, y = Nrows - i - 0.5
- If extent is not None, x and y will be scaled to match,
- as in imshow.
- If origin is None and extent is not None, then extent
- will give the minimum and maximum values of x and y.
- """
- if z.ndim != 2:
- raise TypeError(f"Input z must be 2D, not {z.ndim}D")
- elif z.shape[0] < 2 or z.shape[1] < 2:
- raise TypeError(f"Input z must be at least a (2, 2) shaped array, "
- f"but has shape {z.shape}")
- else:
- Ny, Nx = z.shape
- if self.origin is None: # Not for image-matching.
- if self.extent is None:
- return np.meshgrid(np.arange(Nx), np.arange(Ny))
- else:
- x0, x1, y0, y1 = self.extent
- x = np.linspace(x0, x1, Nx)
- y = np.linspace(y0, y1, Ny)
- return np.meshgrid(x, y)
- # Match image behavior:
- if self.extent is None:
- x0, x1, y0, y1 = (0, Nx, 0, Ny)
- else:
- x0, x1, y0, y1 = self.extent
- dx = (x1 - x0) / Nx
- dy = (y1 - y0) / Ny
- x = x0 + (np.arange(Nx) + 0.5) * dx
- y = y0 + (np.arange(Ny) + 0.5) * dy
- if self.origin == 'upper':
- y = y[::-1]
- return np.meshgrid(x, y)
-
-
-_docstring.interpd.update(contour_doc="""
-`.contour` and `.contourf` draw contour lines and filled contours,
-respectively. Except as noted, function signatures and return values
-are the same for both versions.
-
-Parameters
-----------
-X, Y : array-like, optional
- The coordinates of the values in *Z*.
-
- *X* and *Y* must both be 2D with the same shape as *Z* (e.g.
- created via `numpy.meshgrid`), or they must both be 1-D such
- that ``len(X) == N`` is the number of columns in *Z* and
- ``len(Y) == M`` is the number of rows in *Z*.
-
- *X* and *Y* must both be ordered monotonically.
-
- If not given, they are assumed to be integer indices, i.e.
- ``X = range(N)``, ``Y = range(M)``.
-
-Z : (M, N) array-like
- The height values over which the contour is drawn. Color-mapping is
- controlled by *cmap*, *norm*, *vmin*, and *vmax*.
-
-levels : int or array-like, optional
- Determines the number and positions of the contour lines / regions.
-
- If an int *n*, use `~matplotlib.ticker.MaxNLocator`, which tries
- to automatically choose no more than *n+1* "nice" contour levels
- between minimum and maximum numeric values of *Z*.
-
- If array-like, draw contour lines at the specified levels.
- The values must be in increasing order.
-
-Returns
--------
-`~.contour.QuadContourSet`
-
-Other Parameters
-----------------
-corner_mask : bool, default: :rc:`contour.corner_mask`
- Enable/disable corner masking, which only has an effect if *Z* is
- a masked array. If ``False``, any quad touching a masked point is
- masked out. If ``True``, only the triangular corners of quads
- nearest those points are always masked out, other triangular
- corners comprising three unmasked points are contoured as usual.
-
-colors : color string or sequence of colors, optional
- The colors of the levels, i.e. the lines for `.contour` and the
- areas for `.contourf`.
-
- The sequence is cycled for the levels in ascending order. If the
- sequence is shorter than the number of levels, it's repeated.
-
- As a shortcut, single color strings may be used in place of
- one-element lists, i.e. ``'red'`` instead of ``['red']`` to color
- all levels with the same color. This shortcut does only work for
- color strings, not for other ways of specifying colors.
-
- By default (value *None*), the colormap specified by *cmap*
- will be used.
-
-alpha : float, default: 1
- The alpha blending value, between 0 (transparent) and 1 (opaque).
-
-%(cmap_doc)s
-
- This parameter is ignored if *colors* is set.
-
-%(norm_doc)s
-
- This parameter is ignored if *colors* is set.
-
-%(vmin_vmax_doc)s
-
- If *vmin* or *vmax* are not given, the default color scaling is based on
- *levels*.
-
- This parameter is ignored if *colors* is set.
-
-origin : {*None*, 'upper', 'lower', 'image'}, default: None
- Determines the orientation and exact position of *Z* by specifying
- the position of ``Z[0, 0]``. This is only relevant, if *X*, *Y*
- are not given.
-
- - *None*: ``Z[0, 0]`` is at X=0, Y=0 in the lower left corner.
- - 'lower': ``Z[0, 0]`` is at X=0.5, Y=0.5 in the lower left corner.
- - 'upper': ``Z[0, 0]`` is at X=N+0.5, Y=0.5 in the upper left
- corner.
- - 'image': Use the value from :rc:`image.origin`.
-
-extent : (x0, x1, y0, y1), optional
- If *origin* is not *None*, then *extent* is interpreted as in
- `.imshow`: it gives the outer pixel boundaries. In this case, the
- position of Z[0, 0] is the center of the pixel, not a corner. If
- *origin* is *None*, then (*x0*, *y0*) is the position of Z[0, 0],
- and (*x1*, *y1*) is the position of Z[-1, -1].
-
- This argument is ignored if *X* and *Y* are specified in the call
- to contour.
-
-locator : ticker.Locator subclass, optional
- The locator is used to determine the contour levels if they
- are not given explicitly via *levels*.
- Defaults to `~.ticker.MaxNLocator`.
-
-extend : {'neither', 'both', 'min', 'max'}, default: 'neither'
- Determines the ``contourf``-coloring of values that are outside the
- *levels* range.
-
- If 'neither', values outside the *levels* range are not colored.
- If 'min', 'max' or 'both', color the values below, above or below
- and above the *levels* range.
-
- Values below ``min(levels)`` and above ``max(levels)`` are mapped
- to the under/over values of the `.Colormap`. Note that most
- colormaps do not have dedicated colors for these by default, so
- that the over and under values are the edge values of the colormap.
- You may want to set these values explicitly using
- `.Colormap.set_under` and `.Colormap.set_over`.
-
- .. note::
-
- An existing `.QuadContourSet` does not get notified if
- properties of its colormap are changed. Therefore, an explicit
- call `.QuadContourSet.changed()` is needed after modifying the
- colormap. The explicit call can be left out, if a colorbar is
- assigned to the `.QuadContourSet` because it internally calls
- `.QuadContourSet.changed()`.
-
- Example::
-
- x = np.arange(1, 10)
- y = x.reshape(-1, 1)
- h = x * y
-
- cs = plt.contourf(h, levels=[10, 30, 50],
- colors=['#808080', '#A0A0A0', '#C0C0C0'], extend='both')
- cs.cmap.set_over('red')
- cs.cmap.set_under('blue')
- cs.changed()
-
-xunits, yunits : registered units, optional
- Override axis units by specifying an instance of a
- :class:`matplotlib.units.ConversionInterface`.
-
-antialiased : bool, optional
- Enable antialiasing, overriding the defaults. For
- filled contours, the default is *False*. For line contours,
- it is taken from :rc:`lines.antialiased`.
-
-nchunk : int >= 0, optional
- If 0, no subdivision of the domain. Specify a positive integer to
- divide the domain into subdomains of *nchunk* by *nchunk* quads.
- Chunking reduces the maximum length of polygons generated by the
- contouring algorithm which reduces the rendering workload passed
- on to the backend and also requires slightly less RAM. It can
- however introduce rendering artifacts at chunk boundaries depending
- on the backend, the *antialiased* flag and value of *alpha*.
-
-linewidths : float or array-like, default: :rc:`contour.linewidth`
- *Only applies to* `.contour`.
-
- The line width of the contour lines.
-
- If a number, all levels will be plotted with this linewidth.
-
- If a sequence, the levels in ascending order will be plotted with
- the linewidths in the order specified.
-
- If None, this falls back to :rc:`lines.linewidth`.
-
-linestyles : {*None*, 'solid', 'dashed', 'dashdot', 'dotted'}, optional
- *Only applies to* `.contour`.
-
- If *linestyles* is *None*, the default is 'solid' unless the lines are
- monochrome. In that case, negative contours will instead take their
- linestyle from the *negative_linestyles* argument.
-
- *linestyles* can also be an iterable of the above strings specifying a set
- of linestyles to be used. If this iterable is shorter than the number of
- contour levels it will be repeated as necessary.
-
-negative_linestyles : {*None*, 'solid', 'dashed', 'dashdot', 'dotted'}, \
- optional
- *Only applies to* `.contour`.
-
- If *linestyles* is *None* and the lines are monochrome, this argument
- specifies the line style for negative contours.
-
- If *negative_linestyles* is *None*, the default is taken from
- :rc:`contour.negative_linestyles`.
-
- *negative_linestyles* can also be an iterable of the above strings
- specifying a set of linestyles to be used. If this iterable is shorter than
- the number of contour levels it will be repeated as necessary.
-
-hatches : list[str], optional
- *Only applies to* `.contourf`.
-
- A list of cross hatch patterns to use on the filled areas.
- If None, no hatching will be added to the contour.
- Hatching is supported in the PostScript, PDF, SVG and Agg
- backends only.
-
-algorithm : {'mpl2005', 'mpl2014', 'serial', 'threaded'}, optional
- Which contouring algorithm to use to calculate the contour lines and
- polygons. The algorithms are implemented in
- `ContourPy <https://github.com/contourpy/contourpy>`_, consult the
- `ContourPy documentation <https://contourpy.readthedocs.io>`_ for
- further information.
-
- The default is taken from :rc:`contour.algorithm`.
-
-clip_path : `~matplotlib.patches.Patch` or `.Path` or `.TransformedPath`
- Set the clip path. See `~matplotlib.artist.Artist.set_clip_path`.
-
- .. versionadded:: 3.8
-
-data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
-Notes
------
-1. `.contourf` differs from the MATLAB version in that it does not draw
- the polygon edges. To draw edges, add line contours with calls to
- `.contour`.
-
-2. `.contourf` fills intervals that are closed at the top; that is, for
- boundaries *z1* and *z2*, the filled region is::
-
- z1 < Z <= z2
-
- except for the lowest interval, which is closed on both sides (i.e.
- it includes the lowest value).
-
-3. `.contour` and `.contourf` use a `marching squares
- <https://en.wikipedia.org/wiki/Marching_squares>`_ algorithm to
- compute contour locations. More information can be found in
- `ContourPy documentation <https://contourpy.readthedocs.io>`_.
-""" % _docstring.interpd.params)
diff --git a/contrib/python/matplotlib/py3/matplotlib/contour.pyi b/contrib/python/matplotlib/py3/matplotlib/contour.pyi
deleted file mode 100644
index d7bddfe8f1..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/contour.pyi
+++ /dev/null
@@ -1,169 +0,0 @@
-import matplotlib.cm as cm
-from matplotlib.artist import Artist
-from matplotlib.axes import Axes
-from matplotlib.collections import Collection, PathCollection
-from matplotlib.colors import Colormap, Normalize
-from matplotlib.font_manager import FontProperties
-from matplotlib.path import Path
-from matplotlib.patches import Patch
-from matplotlib.text import Text
-from matplotlib.transforms import Transform, TransformedPatchPath, TransformedPath
-from matplotlib.ticker import Locator, Formatter
-
-from numpy.typing import ArrayLike
-import numpy as np
-from collections.abc import Callable, Iterable, Sequence
-from typing import Literal
-from .typing import ColorType
-
-class ClabelText(Text): ...
-
-class ContourLabeler:
- labelFmt: str | Formatter | Callable[[float], str] | dict[float, str]
- labelManual: bool | Iterable[tuple[float, float]]
- rightside_up: bool
- labelLevelList: list[float]
- labelIndiceList: list[int]
- labelMappable: cm.ScalarMappable
- labelCValueList: list[ColorType]
- labelXYs: list[tuple[float, float]]
- def clabel(
- self,
- levels: ArrayLike | None = ...,
- *,
- fontsize: str | float | None = ...,
- inline: bool = ...,
- inline_spacing: float = ...,
- fmt: str | Formatter | Callable[[float], str] | dict[float, str] | None = ...,
- colors: ColorType | Sequence[ColorType] | None = ...,
- use_clabeltext: bool = ...,
- manual: bool | Iterable[tuple[float, float]] = ...,
- rightside_up: bool = ...,
- zorder: float | None = ...
- ) -> list[Text]: ...
- @property
- def labelFontProps(self) -> FontProperties: ...
- @property
- def labelFontSizeList(self) -> list[float]: ...
- @property
- def labelTextsList(self) -> list[Text]: ...
- def print_label(self, linecontour: ArrayLike, labelwidth: float) -> bool: ...
- def too_close(self, x: float, y: float, lw: float) -> bool: ...
- def set_label_props(self, label: Text, text: str, color: ColorType) -> None: ...
- def get_text(
- self,
- lev: float,
- fmt: str | Formatter | Callable[[float], str] | dict[float, str],
- ) -> str: ...
- def locate_label(
- self, linecontour: ArrayLike, labelwidth: float
- ) -> tuple[float, float, float]: ...
- def calc_label_rot_and_inline(
- self,
- slc: ArrayLike,
- ind: int,
- lw: float,
- lc: ArrayLike | None = ...,
- spacing: int = ...,
- ) -> tuple[float, list[ArrayLike]]: ...
- def add_label(
- self, x: float, y: float, rotation: float, lev: float, cvalue: ColorType
- ) -> None: ...
- def add_label_clabeltext(
- self, x: float, y: float, rotation: float, lev: float, cvalue: ColorType
- ) -> None: ...
- def add_label_near(
- self,
- x: float,
- y: float,
- inline: bool = ...,
- inline_spacing: int = ...,
- transform: Transform | Literal[False] | None = ...,
- ) -> None: ...
- def pop_label(self, index: int = ...) -> None: ...
- def labels(self, inline: bool, inline_spacing: int) -> None: ...
- def remove(self) -> None: ...
-
-class ContourSet(ContourLabeler, Collection):
- axes: Axes
- levels: Iterable[float]
- filled: bool
- linewidths: float | ArrayLike | None
- hatches: Iterable[str | None]
- origin: Literal["upper", "lower", "image"] | None
- extent: tuple[float, float, float, float] | None
- colors: ColorType | Sequence[ColorType]
- extend: Literal["neither", "both", "min", "max"]
- nchunk: int
- locator: Locator | None
- logscale: bool
- negative_linestyles: None | Literal[
- "solid", "dashed", "dashdot", "dotted"
- ] | Iterable[Literal["solid", "dashed", "dashdot", "dotted"]]
- clip_path: Patch | Path | TransformedPath | TransformedPatchPath | None
- labelTexts: list[Text]
- labelCValues: list[ColorType]
- @property
- def tcolors(self) -> list[tuple[tuple[float, float, float, float]]]: ...
-
- # only for not filled
- @property
- def tlinewidths(self) -> list[tuple[float]]: ...
-
- @property
- def allkinds(self) -> list[list[np.ndarray | None]]: ...
- @property
- def allsegs(self) -> list[list[np.ndarray]]: ...
- @property
- def alpha(self) -> float | None: ...
- @property
- def antialiased(self) -> bool: ...
- @antialiased.setter
- def antialiased(self, aa: bool | Sequence[bool]) -> None: ...
- @property
- def collections(self) -> list[PathCollection]: ...
- @property
- def linestyles(self) -> (
- None |
- Literal["solid", "dashed", "dashdot", "dotted"] |
- Iterable[Literal["solid", "dashed", "dashdot", "dotted"]]
- ): ...
-
- def __init__(
- self,
- ax: Axes,
- *args,
- levels: Iterable[float] | None = ...,
- filled: bool = ...,
- linewidths: float | ArrayLike | None = ...,
- linestyles: Literal["solid", "dashed", "dashdot", "dotted"]
- | Iterable[Literal["solid", "dashed", "dashdot", "dotted"]]
- | None = ...,
- hatches: Iterable[str | None] = ...,
- alpha: float | None = ...,
- origin: Literal["upper", "lower", "image"] | None = ...,
- extent: tuple[float, float, float, float] | None = ...,
- cmap: str | Colormap | None = ...,
- colors: ColorType | Sequence[ColorType] | None = ...,
- norm: str | Normalize | None = ...,
- vmin: float | None = ...,
- vmax: float | None = ...,
- extend: Literal["neither", "both", "min", "max"] = ...,
- antialiased: bool | None = ...,
- nchunk: int = ...,
- locator: Locator | None = ...,
- transform: Transform | None = ...,
- negative_linestyles: Literal["solid", "dashed", "dashdot", "dotted"]
- | Iterable[Literal["solid", "dashed", "dashdot", "dotted"]]
- | None = ...,
- clip_path: Patch | Path | TransformedPath | TransformedPatchPath | None = ...,
- **kwargs
- ) -> None: ...
- def legend_elements(
- self, variable_name: str = ..., str_format: Callable[[float], str] = ...
- ) -> tuple[list[Artist], list[str]]: ...
- def find_nearest_contour(
- self, x: float, y: float, indices: Iterable[int] | None = ..., pixel: bool = ...
- ) -> tuple[int, int, int, float, float, float]: ...
-
-class QuadContourSet(ContourSet): ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/dates.py b/contrib/python/matplotlib/py3/matplotlib/dates.py
deleted file mode 100644
index a11e0d4f1e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/dates.py
+++ /dev/null
@@ -1,1894 +0,0 @@
-"""
-Matplotlib provides sophisticated date plotting capabilities, standing on the
-shoulders of python :mod:`datetime` and the add-on module dateutil_.
-
-By default, Matplotlib uses the units machinery described in
-`~matplotlib.units` to convert `datetime.datetime`, and `numpy.datetime64`
-objects when plotted on an x- or y-axis. The user does not
-need to do anything for dates to be formatted, but dates often have strict
-formatting needs, so this module provides many tick locators and formatters.
-A basic example using `numpy.datetime64` is::
-
- import numpy as np
-
- times = np.arange(np.datetime64('2001-01-02'),
- np.datetime64('2002-02-03'), np.timedelta64(75, 'm'))
- y = np.random.randn(len(times))
-
- fig, ax = plt.subplots()
- ax.plot(times, y)
-
-.. seealso::
-
- - :doc:`/gallery/text_labels_and_annotations/date`
- - :doc:`/gallery/ticks/date_concise_formatter`
- - :doc:`/gallery/ticks/date_demo_convert`
-
-.. _date-format:
-
-Matplotlib date format
-----------------------
-
-Matplotlib represents dates using floating point numbers specifying the number
-of days since a default epoch of 1970-01-01 UTC; for example,
-1970-01-01, 06:00 is the floating point number 0.25. The formatters and
-locators require the use of `datetime.datetime` objects, so only dates between
-year 0001 and 9999 can be represented. Microsecond precision
-is achievable for (approximately) 70 years on either side of the epoch, and
-20 microseconds for the rest of the allowable range of dates (year 0001 to
-9999). The epoch can be changed at import time via `.dates.set_epoch` or
-:rc:`dates.epoch` to other dates if necessary; see
-:doc:`/gallery/ticks/date_precision_and_epochs` for a discussion.
-
-.. note::
-
- Before Matplotlib 3.3, the epoch was 0000-12-31 which lost modern
- microsecond precision and also made the default axis limit of 0 an invalid
- datetime. In 3.3 the epoch was changed as above. To convert old
- ordinal floats to the new epoch, users can do::
-
- new_ordinal = old_ordinal + mdates.date2num(np.datetime64('0000-12-31'))
-
-
-There are a number of helper functions to convert between :mod:`datetime`
-objects and Matplotlib dates:
-
-.. currentmodule:: matplotlib.dates
-
-.. autosummary::
- :nosignatures:
-
- datestr2num
- date2num
- num2date
- num2timedelta
- drange
- set_epoch
- get_epoch
-
-.. note::
-
- Like Python's `datetime.datetime`, Matplotlib uses the Gregorian calendar
- for all conversions between dates and floating point numbers. This practice
- is not universal, and calendar differences can cause confusing
- differences between what Python and Matplotlib give as the number of days
- since 0001-01-01 and what other software and databases yield. For
- example, the US Naval Observatory uses a calendar that switches
- from Julian to Gregorian in October, 1582. Hence, using their
- calculator, the number of days between 0001-01-01 and 2006-04-01 is
- 732403, whereas using the Gregorian calendar via the datetime
- module we find::
-
- In [1]: date(2006, 4, 1).toordinal() - date(1, 1, 1).toordinal()
- Out[1]: 732401
-
-All the Matplotlib date converters, locators and formatters are timezone aware.
-If no explicit timezone is provided, :rc:`timezone` is assumed, provided as a
-string. If you want to use a different timezone, pass the *tz* keyword
-argument of `num2date` to any date tick locators or formatters you create. This
-can be either a `datetime.tzinfo` instance or a string with the timezone name
-that can be parsed by `~dateutil.tz.gettz`.
-
-A wide range of specific and general purpose date tick locators and
-formatters are provided in this module. See
-:mod:`matplotlib.ticker` for general information on tick locators
-and formatters. These are described below.
-
-The dateutil_ module provides additional code to handle date ticking, making it
-easy to place ticks on any kinds of dates. See examples below.
-
-.. _dateutil: https://dateutil.readthedocs.io
-
-.. _date-locators:
-
-Date tick locators
-------------------
-
-Most of the date tick locators can locate single or multiple ticks. For example::
-
- # import constants for the days of the week
- from matplotlib.dates import MO, TU, WE, TH, FR, SA, SU
-
- # tick on Mondays every week
- loc = WeekdayLocator(byweekday=MO, tz=tz)
-
- # tick on Mondays and Saturdays
- loc = WeekdayLocator(byweekday=(MO, SA))
-
-In addition, most of the constructors take an interval argument::
-
- # tick on Mondays every second week
- loc = WeekdayLocator(byweekday=MO, interval=2)
-
-The rrule locator allows completely general date ticking::
-
- # tick every 5th easter
- rule = rrulewrapper(YEARLY, byeaster=1, interval=5)
- loc = RRuleLocator(rule)
-
-The available date tick locators are:
-
-* `MicrosecondLocator`: Locate microseconds.
-
-* `SecondLocator`: Locate seconds.
-
-* `MinuteLocator`: Locate minutes.
-
-* `HourLocator`: Locate hours.
-
-* `DayLocator`: Locate specified days of the month.
-
-* `WeekdayLocator`: Locate days of the week, e.g., MO, TU.
-
-* `MonthLocator`: Locate months, e.g., 7 for July.
-
-* `YearLocator`: Locate years that are multiples of base.
-
-* `RRuleLocator`: Locate using a `rrulewrapper`.
- `rrulewrapper` is a simple wrapper around dateutil_'s `dateutil.rrule`
- which allow almost arbitrary date tick specifications.
- See :doc:`rrule example </gallery/ticks/date_demo_rrule>`.
-
-* `AutoDateLocator`: On autoscale, this class picks the best `DateLocator`
- (e.g., `RRuleLocator`) to set the view limits and the tick locations. If
- called with ``interval_multiples=True`` it will make ticks line up with
- sensible multiples of the tick intervals. For example, if the interval is
- 4 hours, it will pick hours 0, 4, 8, etc. as ticks. This behaviour is not
- guaranteed by default.
-
-.. _date-formatters:
-
-Date formatters
----------------
-
-The available date formatters are:
-
-* `AutoDateFormatter`: attempts to figure out the best format to use. This is
- most useful when used with the `AutoDateLocator`.
-
-* `ConciseDateFormatter`: also attempts to figure out the best format to use,
- and to make the format as compact as possible while still having complete
- date information. This is most useful when used with the `AutoDateLocator`.
-
-* `DateFormatter`: use `~datetime.datetime.strftime` format strings.
-"""
-
-import datetime
-import functools
-import logging
-import re
-
-from dateutil.rrule import (rrule, MO, TU, WE, TH, FR, SA, SU, YEARLY,
- MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY,
- SECONDLY)
-from dateutil.relativedelta import relativedelta
-import dateutil.parser
-import dateutil.tz
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, cbook, ticker, units
-
-__all__ = ('datestr2num', 'date2num', 'num2date', 'num2timedelta', 'drange',
- 'set_epoch', 'get_epoch', 'DateFormatter', 'ConciseDateFormatter',
- 'AutoDateFormatter', 'DateLocator', 'RRuleLocator',
- 'AutoDateLocator', 'YearLocator', 'MonthLocator', 'WeekdayLocator',
- 'DayLocator', 'HourLocator', 'MinuteLocator',
- 'SecondLocator', 'MicrosecondLocator',
- 'rrule', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA', 'SU',
- 'YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY',
- 'HOURLY', 'MINUTELY', 'SECONDLY', 'MICROSECONDLY', 'relativedelta',
- 'DateConverter', 'ConciseDateConverter', 'rrulewrapper')
-
-
-_log = logging.getLogger(__name__)
-UTC = datetime.timezone.utc
-
-
-@_api.caching_module_getattr
-class __getattr__:
- JULIAN_OFFSET = _api.deprecated("3.7")(property(lambda self: 1721424.5))
- # Julian date at 0000-12-31
- # note that the Julian day epoch is achievable w/
- # np.datetime64('-4713-11-24T12:00:00'); datetime64 is proleptic
- # Gregorian and BC has a one-year offset. So
- # np.datetime64('0000-12-31') - np.datetime64('-4713-11-24T12:00') =
- # 1721424.5
- # Ref: https://en.wikipedia.org/wiki/Julian_day
-
-
-def _get_tzinfo(tz=None):
- """
- Generate `~datetime.tzinfo` from a string or return `~datetime.tzinfo`.
- If None, retrieve the preferred timezone from the rcParams dictionary.
- """
- tz = mpl._val_or_rc(tz, 'timezone')
- if tz == 'UTC':
- return UTC
- if isinstance(tz, str):
- tzinfo = dateutil.tz.gettz(tz)
- if tzinfo is None:
- raise ValueError(f"{tz} is not a valid timezone as parsed by"
- " dateutil.tz.gettz.")
- return tzinfo
- if isinstance(tz, datetime.tzinfo):
- return tz
- raise TypeError(f"tz must be string or tzinfo subclass, not {tz!r}.")
-
-
-# Time-related constants.
-EPOCH_OFFSET = float(datetime.datetime(1970, 1, 1).toordinal())
-# EPOCH_OFFSET is not used by matplotlib
-MICROSECONDLY = SECONDLY + 1
-HOURS_PER_DAY = 24.
-MIN_PER_HOUR = 60.
-SEC_PER_MIN = 60.
-MONTHS_PER_YEAR = 12.
-
-DAYS_PER_WEEK = 7.
-DAYS_PER_MONTH = 30.
-DAYS_PER_YEAR = 365.0
-
-MINUTES_PER_DAY = MIN_PER_HOUR * HOURS_PER_DAY
-
-SEC_PER_HOUR = SEC_PER_MIN * MIN_PER_HOUR
-SEC_PER_DAY = SEC_PER_HOUR * HOURS_PER_DAY
-SEC_PER_WEEK = SEC_PER_DAY * DAYS_PER_WEEK
-
-MUSECONDS_PER_DAY = 1e6 * SEC_PER_DAY
-
-MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY = (
- MO, TU, WE, TH, FR, SA, SU)
-WEEKDAYS = (MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY)
-
-# default epoch: passed to np.datetime64...
-_epoch = None
-
-
-def _reset_epoch_test_example():
- """
- Reset the Matplotlib date epoch so it can be set again.
-
- Only for use in tests and examples.
- """
- global _epoch
- _epoch = None
-
-
-def set_epoch(epoch):
- """
- Set the epoch (origin for dates) for datetime calculations.
-
- The default epoch is :rc:`dates.epoch` (by default 1970-01-01T00:00).
-
- If microsecond accuracy is desired, the date being plotted needs to be
- within approximately 70 years of the epoch. Matplotlib internally
- represents dates as days since the epoch, so floating point dynamic
- range needs to be within a factor of 2^52.
-
- `~.dates.set_epoch` must be called before any dates are converted
- (i.e. near the import section) or a RuntimeError will be raised.
-
- See also :doc:`/gallery/ticks/date_precision_and_epochs`.
-
- Parameters
- ----------
- epoch : str
- valid UTC date parsable by `numpy.datetime64` (do not include
- timezone).
-
- """
- global _epoch
- if _epoch is not None:
- raise RuntimeError('set_epoch must be called before dates plotted.')
- _epoch = epoch
-
-
-def get_epoch():
- """
- Get the epoch used by `.dates`.
-
- Returns
- -------
- epoch : str
- String for the epoch (parsable by `numpy.datetime64`).
- """
- global _epoch
-
- _epoch = mpl._val_or_rc(_epoch, 'date.epoch')
- return _epoch
-
-
-def _dt64_to_ordinalf(d):
- """
- Convert `numpy.datetime64` or an `numpy.ndarray` of those types to
- Gregorian date as UTC float relative to the epoch (see `.get_epoch`).
- Roundoff is float64 precision. Practically: microseconds for dates
- between 290301 BC, 294241 AD, milliseconds for larger dates
- (see `numpy.datetime64`).
- """
-
- # the "extra" ensures that we at least allow the dynamic range out to
- # seconds. That should get out to +/-2e11 years.
- dseconds = d.astype('datetime64[s]')
- extra = (d - dseconds).astype('timedelta64[ns]')
- t0 = np.datetime64(get_epoch(), 's')
- dt = (dseconds - t0).astype(np.float64)
- dt += extra.astype(np.float64) / 1.0e9
- dt = dt / SEC_PER_DAY
-
- NaT_int = np.datetime64('NaT').astype(np.int64)
- d_int = d.astype(np.int64)
- dt[d_int == NaT_int] = np.nan
- return dt
-
-
-def _from_ordinalf(x, tz=None):
- """
- Convert Gregorian float of the date, preserving hours, minutes,
- seconds and microseconds. Return value is a `.datetime`.
-
- The input date *x* is a float in ordinal days at UTC, and the output will
- be the specified `.datetime` object corresponding to that time in
- timezone *tz*, or if *tz* is ``None``, in the timezone specified in
- :rc:`timezone`.
- """
-
- tz = _get_tzinfo(tz)
-
- dt = (np.datetime64(get_epoch()) +
- np.timedelta64(int(np.round(x * MUSECONDS_PER_DAY)), 'us'))
- if dt < np.datetime64('0001-01-01') or dt >= np.datetime64('10000-01-01'):
- raise ValueError(f'Date ordinal {x} converts to {dt} (using '
- f'epoch {get_epoch()}), but Matplotlib dates must be '
- 'between year 0001 and 9999.')
- # convert from datetime64 to datetime:
- dt = dt.tolist()
-
- # datetime64 is always UTC:
- dt = dt.replace(tzinfo=dateutil.tz.gettz('UTC'))
- # but maybe we are working in a different timezone so move.
- dt = dt.astimezone(tz)
- # fix round off errors
- if np.abs(x) > 70 * 365:
- # if x is big, round off to nearest twenty microseconds.
- # This avoids floating point roundoff error
- ms = round(dt.microsecond / 20) * 20
- if ms == 1000000:
- dt = dt.replace(microsecond=0) + datetime.timedelta(seconds=1)
- else:
- dt = dt.replace(microsecond=ms)
-
- return dt
-
-
-# a version of _from_ordinalf that can operate on numpy arrays
-_from_ordinalf_np_vectorized = np.vectorize(_from_ordinalf, otypes="O")
-# a version of dateutil.parser.parse that can operate on numpy arrays
-_dateutil_parser_parse_np_vectorized = np.vectorize(dateutil.parser.parse)
-
-
-def datestr2num(d, default=None):
- """
- Convert a date string to a datenum using `dateutil.parser.parse`.
-
- Parameters
- ----------
- d : str or sequence of str
- The dates to convert.
-
- default : datetime.datetime, optional
- The default date to use when fields are missing in *d*.
- """
- if isinstance(d, str):
- dt = dateutil.parser.parse(d, default=default)
- return date2num(dt)
- else:
- if default is not None:
- d = [date2num(dateutil.parser.parse(s, default=default))
- for s in d]
- return np.asarray(d)
- d = np.asarray(d)
- if not d.size:
- return d
- return date2num(_dateutil_parser_parse_np_vectorized(d))
-
-
-def date2num(d):
- """
- Convert datetime objects to Matplotlib dates.
-
- Parameters
- ----------
- d : `datetime.datetime` or `numpy.datetime64` or sequences of these
-
- Returns
- -------
- float or sequence of floats
- Number of days since the epoch. See `.get_epoch` for the
- epoch, which can be changed by :rc:`date.epoch` or `.set_epoch`. If
- the epoch is "1970-01-01T00:00:00" (default) then noon Jan 1 1970
- ("1970-01-01T12:00:00") returns 0.5.
-
- Notes
- -----
- The Gregorian calendar is assumed; this is not universal practice.
- For details see the module docstring.
- """
- # Unpack in case of e.g. Pandas or xarray object
- d = cbook._unpack_to_numpy(d)
-
- # make an iterable, but save state to unpack later:
- iterable = np.iterable(d)
- if not iterable:
- d = [d]
-
- masked = np.ma.is_masked(d)
- mask = np.ma.getmask(d)
- d = np.asarray(d)
-
- # convert to datetime64 arrays, if not already:
- if not np.issubdtype(d.dtype, np.datetime64):
- # datetime arrays
- if not d.size:
- # deals with an empty array...
- return d
- tzi = getattr(d[0], 'tzinfo', None)
- if tzi is not None:
- # make datetime naive:
- d = [dt.astimezone(UTC).replace(tzinfo=None) for dt in d]
- d = np.asarray(d)
- d = d.astype('datetime64[us]')
-
- d = np.ma.masked_array(d, mask=mask) if masked else d
- d = _dt64_to_ordinalf(d)
-
- return d if iterable else d[0]
-
-
-@_api.deprecated("3.7")
-def julian2num(j):
- """
- Convert a Julian date (or sequence) to a Matplotlib date (or sequence).
-
- Parameters
- ----------
- j : float or sequence of floats
- Julian dates (days relative to 4713 BC Jan 1, 12:00:00 Julian
- calendar or 4714 BC Nov 24, 12:00:00, proleptic Gregorian calendar).
-
- Returns
- -------
- float or sequence of floats
- Matplotlib dates (days relative to `.get_epoch`).
- """
- ep = np.datetime64(get_epoch(), 'h').astype(float) / 24.
- ep0 = np.datetime64('0000-12-31T00:00:00', 'h').astype(float) / 24.
- # Julian offset defined above is relative to 0000-12-31, but we need
- # relative to our current epoch:
- dt = __getattr__("JULIAN_OFFSET") - ep0 + ep
- return np.subtract(j, dt) # Handles both scalar & nonscalar j.
-
-
-@_api.deprecated("3.7")
-def num2julian(n):
- """
- Convert a Matplotlib date (or sequence) to a Julian date (or sequence).
-
- Parameters
- ----------
- n : float or sequence of floats
- Matplotlib dates (days relative to `.get_epoch`).
-
- Returns
- -------
- float or sequence of floats
- Julian dates (days relative to 4713 BC Jan 1, 12:00:00).
- """
- ep = np.datetime64(get_epoch(), 'h').astype(float) / 24.
- ep0 = np.datetime64('0000-12-31T00:00:00', 'h').astype(float) / 24.
- # Julian offset defined above is relative to 0000-12-31, but we need
- # relative to our current epoch:
- dt = __getattr__("JULIAN_OFFSET") - ep0 + ep
- return np.add(n, dt) # Handles both scalar & nonscalar j.
-
-
-def num2date(x, tz=None):
- """
- Convert Matplotlib dates to `~datetime.datetime` objects.
-
- Parameters
- ----------
- x : float or sequence of floats
- Number of days (fraction part represents hours, minutes, seconds)
- since the epoch. See `.get_epoch` for the
- epoch, which can be changed by :rc:`date.epoch` or `.set_epoch`.
- tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
- Timezone of *x*. If a string, *tz* is passed to `dateutil.tz`.
-
- Returns
- -------
- `~datetime.datetime` or sequence of `~datetime.datetime`
- Dates are returned in timezone *tz*.
-
- If *x* is a sequence, a sequence of `~datetime.datetime` objects will
- be returned.
-
- Notes
- -----
- The Gregorian calendar is assumed; this is not universal practice.
- For details, see the module docstring.
- """
- tz = _get_tzinfo(tz)
- return _from_ordinalf_np_vectorized(x, tz).tolist()
-
-
-_ordinalf_to_timedelta_np_vectorized = np.vectorize(
- lambda x: datetime.timedelta(days=x), otypes="O")
-
-
-def num2timedelta(x):
- """
- Convert number of days to a `~datetime.timedelta` object.
-
- If *x* is a sequence, a sequence of `~datetime.timedelta` objects will
- be returned.
-
- Parameters
- ----------
- x : float, sequence of floats
- Number of days. The fraction part represents hours, minutes, seconds.
-
- Returns
- -------
- `datetime.timedelta` or list[`datetime.timedelta`]
- """
- return _ordinalf_to_timedelta_np_vectorized(x).tolist()
-
-
-def drange(dstart, dend, delta):
- """
- Return a sequence of equally spaced Matplotlib dates.
-
- The dates start at *dstart* and reach up to, but not including *dend*.
- They are spaced by *delta*.
-
- Parameters
- ----------
- dstart, dend : `~datetime.datetime`
- The date limits.
- delta : `datetime.timedelta`
- Spacing of the dates.
-
- Returns
- -------
- `numpy.array`
- A list floats representing Matplotlib dates.
-
- """
- f1 = date2num(dstart)
- f2 = date2num(dend)
- step = delta.total_seconds() / SEC_PER_DAY
-
- # calculate the difference between dend and dstart in times of delta
- num = int(np.ceil((f2 - f1) / step))
-
- # calculate end of the interval which will be generated
- dinterval_end = dstart + num * delta
-
- # ensure, that an half open interval will be generated [dstart, dend)
- if dinterval_end >= dend:
- # if the endpoint is greater than or equal to dend,
- # just subtract one delta
- dinterval_end -= delta
- num -= 1
-
- f2 = date2num(dinterval_end) # new float-endpoint
- return np.linspace(f1, f2, num + 1)
-
-
-def _wrap_in_tex(text):
- p = r'([a-zA-Z]+)'
- ret_text = re.sub(p, r'}$\1$\\mathdefault{', text)
-
- # Braces ensure symbols are not spaced like binary operators.
- ret_text = ret_text.replace('-', '{-}').replace(':', '{:}')
- # To not concatenate space between numbers.
- ret_text = ret_text.replace(' ', r'\;')
- ret_text = '$\\mathdefault{' + ret_text + '}$'
- ret_text = ret_text.replace('$\\mathdefault{}$', '')
- return ret_text
-
-
-## date tick locators and formatters ###
-
-
-class DateFormatter(ticker.Formatter):
- """
- Format a tick (in days since the epoch) with a
- `~datetime.datetime.strftime` format string.
- """
-
- def __init__(self, fmt, tz=None, *, usetex=None):
- """
- Parameters
- ----------
- fmt : str
- `~datetime.datetime.strftime` format string
- tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
- Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
- usetex : bool, default: :rc:`text.usetex`
- To enable/disable the use of TeX's math mode for rendering the
- results of the formatter.
- """
- self.tz = _get_tzinfo(tz)
- self.fmt = fmt
- self._usetex = mpl._val_or_rc(usetex, 'text.usetex')
-
- def __call__(self, x, pos=0):
- result = num2date(x, self.tz).strftime(self.fmt)
- return _wrap_in_tex(result) if self._usetex else result
-
- def set_tzinfo(self, tz):
- self.tz = _get_tzinfo(tz)
-
-
-class ConciseDateFormatter(ticker.Formatter):
- """
- A `.Formatter` which attempts to figure out the best format to use for the
- date, and to make it as compact as possible, but still be complete. This is
- most useful when used with the `AutoDateLocator`::
-
- >>> locator = AutoDateLocator()
- >>> formatter = ConciseDateFormatter(locator)
-
- Parameters
- ----------
- locator : `.ticker.Locator`
- Locator that this axis is using.
-
- tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
- Ticks timezone, passed to `.dates.num2date`.
-
- formats : list of 6 strings, optional
- Format strings for 6 levels of tick labelling: mostly years,
- months, days, hours, minutes, and seconds. Strings use
- the same format codes as `~datetime.datetime.strftime`. Default is
- ``['%Y', '%b', '%d', '%H:%M', '%H:%M', '%S.%f']``
-
- zero_formats : list of 6 strings, optional
- Format strings for tick labels that are "zeros" for a given tick
- level. For instance, if most ticks are months, ticks around 1 Jan 2005
- will be labeled "Dec", "2005", "Feb". The default is
- ``['', '%Y', '%b', '%b-%d', '%H:%M', '%H:%M']``
-
- offset_formats : list of 6 strings, optional
- Format strings for the 6 levels that is applied to the "offset"
- string found on the right side of an x-axis, or top of a y-axis.
- Combined with the tick labels this should completely specify the
- date. The default is::
-
- ['', '%Y', '%Y-%b', '%Y-%b-%d', '%Y-%b-%d', '%Y-%b-%d %H:%M']
-
- show_offset : bool, default: True
- Whether to show the offset or not.
-
- usetex : bool, default: :rc:`text.usetex`
- To enable/disable the use of TeX's math mode for rendering the results
- of the formatter.
-
- Examples
- --------
- See :doc:`/gallery/ticks/date_concise_formatter`
-
- .. plot::
-
- import datetime
- import matplotlib.dates as mdates
-
- base = datetime.datetime(2005, 2, 1)
- dates = np.array([base + datetime.timedelta(hours=(2 * i))
- for i in range(732)])
- N = len(dates)
- np.random.seed(19680801)
- y = np.cumsum(np.random.randn(N))
-
- fig, ax = plt.subplots(constrained_layout=True)
- locator = mdates.AutoDateLocator()
- formatter = mdates.ConciseDateFormatter(locator)
- ax.xaxis.set_major_locator(locator)
- ax.xaxis.set_major_formatter(formatter)
-
- ax.plot(dates, y)
- ax.set_title('Concise Date Formatter')
-
- """
-
- def __init__(self, locator, tz=None, formats=None, offset_formats=None,
- zero_formats=None, show_offset=True, *, usetex=None):
- """
- Autoformat the date labels. The default format is used to form an
- initial string, and then redundant elements are removed.
- """
- self._locator = locator
- self._tz = tz
- self.defaultfmt = '%Y'
- # there are 6 levels with each level getting a specific format
- # 0: mostly years, 1: months, 2: days,
- # 3: hours, 4: minutes, 5: seconds
- if formats:
- if len(formats) != 6:
- raise ValueError('formats argument must be a list of '
- '6 format strings (or None)')
- self.formats = formats
- else:
- self.formats = ['%Y', # ticks are mostly years
- '%b', # ticks are mostly months
- '%d', # ticks are mostly days
- '%H:%M', # hrs
- '%H:%M', # min
- '%S.%f', # secs
- ]
- # fmt for zeros ticks at this level. These are
- # ticks that should be labeled w/ info the level above.
- # like 1 Jan can just be labelled "Jan". 02:02:00 can
- # just be labeled 02:02.
- if zero_formats:
- if len(zero_formats) != 6:
- raise ValueError('zero_formats argument must be a list of '
- '6 format strings (or None)')
- self.zero_formats = zero_formats
- elif formats:
- # use the users formats for the zero tick formats
- self.zero_formats = [''] + self.formats[:-1]
- else:
- # make the defaults a bit nicer:
- self.zero_formats = [''] + self.formats[:-1]
- self.zero_formats[3] = '%b-%d'
-
- if offset_formats:
- if len(offset_formats) != 6:
- raise ValueError('offset_formats argument must be a list of '
- '6 format strings (or None)')
- self.offset_formats = offset_formats
- else:
- self.offset_formats = ['',
- '%Y',
- '%Y-%b',
- '%Y-%b-%d',
- '%Y-%b-%d',
- '%Y-%b-%d %H:%M']
- self.offset_string = ''
- self.show_offset = show_offset
- self._usetex = mpl._val_or_rc(usetex, 'text.usetex')
-
- def __call__(self, x, pos=None):
- formatter = DateFormatter(self.defaultfmt, self._tz,
- usetex=self._usetex)
- return formatter(x, pos=pos)
-
- def format_ticks(self, values):
- tickdatetime = [num2date(value, tz=self._tz) for value in values]
- tickdate = np.array([tdt.timetuple()[:6] for tdt in tickdatetime])
-
- # basic algorithm:
- # 1) only display a part of the date if it changes over the ticks.
- # 2) don't display the smaller part of the date if:
- # it is always the same or if it is the start of the
- # year, month, day etc.
- # fmt for most ticks at this level
- fmts = self.formats
- # format beginnings of days, months, years, etc.
- zerofmts = self.zero_formats
- # offset fmt are for the offset in the upper left of the
- # or lower right of the axis.
- offsetfmts = self.offset_formats
- show_offset = self.show_offset
-
- # determine the level we will label at:
- # mostly 0: years, 1: months, 2: days,
- # 3: hours, 4: minutes, 5: seconds, 6: microseconds
- for level in range(5, -1, -1):
- unique = np.unique(tickdate[:, level])
- if len(unique) > 1:
- # if 1 is included in unique, the year is shown in ticks
- if level < 2 and np.any(unique == 1):
- show_offset = False
- break
- elif level == 0:
- # all tickdate are the same, so only micros might be different
- # set to the most precise (6: microseconds doesn't exist...)
- level = 5
-
- # level is the basic level we will label at.
- # now loop through and decide the actual ticklabels
- zerovals = [0, 1, 1, 0, 0, 0, 0]
- labels = [''] * len(tickdate)
- for nn in range(len(tickdate)):
- if level < 5:
- if tickdate[nn][level] == zerovals[level]:
- fmt = zerofmts[level]
- else:
- fmt = fmts[level]
- else:
- # special handling for seconds + microseconds
- if (tickdatetime[nn].second == tickdatetime[nn].microsecond
- == 0):
- fmt = zerofmts[level]
- else:
- fmt = fmts[level]
- labels[nn] = tickdatetime[nn].strftime(fmt)
-
- # special handling of seconds and microseconds:
- # strip extra zeros and decimal if possible.
- # this is complicated by two factors. 1) we have some level-4 strings
- # here (i.e. 03:00, '0.50000', '1.000') 2) we would like to have the
- # same number of decimals for each string (i.e. 0.5 and 1.0).
- if level >= 5:
- trailing_zeros = min(
- (len(s) - len(s.rstrip('0')) for s in labels if '.' in s),
- default=None)
- if trailing_zeros:
- for nn in range(len(labels)):
- if '.' in labels[nn]:
- labels[nn] = labels[nn][:-trailing_zeros].rstrip('.')
-
- if show_offset:
- # set the offset string:
- self.offset_string = tickdatetime[-1].strftime(offsetfmts[level])
- if self._usetex:
- self.offset_string = _wrap_in_tex(self.offset_string)
- else:
- self.offset_string = ''
-
- if self._usetex:
- return [_wrap_in_tex(l) for l in labels]
- else:
- return labels
-
- def get_offset(self):
- return self.offset_string
-
- def format_data_short(self, value):
- return num2date(value, tz=self._tz).strftime('%Y-%m-%d %H:%M:%S')
-
-
-class AutoDateFormatter(ticker.Formatter):
- """
- A `.Formatter` which attempts to figure out the best format to use. This
- is most useful when used with the `AutoDateLocator`.
-
- `.AutoDateFormatter` has a ``.scale`` dictionary that maps tick scales (the
- interval in days between one major tick) to format strings; this dictionary
- defaults to ::
-
- self.scaled = {
- DAYS_PER_YEAR: rcParams['date.autoformatter.year'],
- DAYS_PER_MONTH: rcParams['date.autoformatter.month'],
- 1: rcParams['date.autoformatter.day'],
- 1 / HOURS_PER_DAY: rcParams['date.autoformatter.hour'],
- 1 / MINUTES_PER_DAY: rcParams['date.autoformatter.minute'],
- 1 / SEC_PER_DAY: rcParams['date.autoformatter.second'],
- 1 / MUSECONDS_PER_DAY: rcParams['date.autoformatter.microsecond'],
- }
-
- The formatter uses the format string corresponding to the lowest key in
- the dictionary that is greater or equal to the current scale. Dictionary
- entries can be customized::
-
- locator = AutoDateLocator()
- formatter = AutoDateFormatter(locator)
- formatter.scaled[1/(24*60)] = '%M:%S' # only show min and sec
-
- Custom callables can also be used instead of format strings. The following
- example shows how to use a custom format function to strip trailing zeros
- from decimal seconds and adds the date to the first ticklabel::
-
- def my_format_function(x, pos=None):
- x = matplotlib.dates.num2date(x)
- if pos == 0:
- fmt = '%D %H:%M:%S.%f'
- else:
- fmt = '%H:%M:%S.%f'
- label = x.strftime(fmt)
- label = label.rstrip("0")
- label = label.rstrip(".")
- return label
-
- formatter.scaled[1/(24*60)] = my_format_function
- """
-
- # This can be improved by providing some user-level direction on
- # how to choose the best format (precedence, etc.).
-
- # Perhaps a 'struct' that has a field for each time-type where a
- # zero would indicate "don't show" and a number would indicate
- # "show" with some sort of priority. Same priorities could mean
- # show all with the same priority.
-
- # Or more simply, perhaps just a format string for each
- # possibility...
-
- def __init__(self, locator, tz=None, defaultfmt='%Y-%m-%d', *,
- usetex=None):
- """
- Autoformat the date labels.
-
- Parameters
- ----------
- locator : `.ticker.Locator`
- Locator that this axis is using.
-
- tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
- Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
-
- defaultfmt : str
- The default format to use if none of the values in ``self.scaled``
- are greater than the unit returned by ``locator._get_unit()``.
-
- usetex : bool, default: :rc:`text.usetex`
- To enable/disable the use of TeX's math mode for rendering the
- results of the formatter. If any entries in ``self.scaled`` are set
- as functions, then it is up to the customized function to enable or
- disable TeX's math mode itself.
- """
- self._locator = locator
- self._tz = tz
- self.defaultfmt = defaultfmt
- self._formatter = DateFormatter(self.defaultfmt, tz)
- rcParams = mpl.rcParams
- self._usetex = mpl._val_or_rc(usetex, 'text.usetex')
- self.scaled = {
- DAYS_PER_YEAR: rcParams['date.autoformatter.year'],
- DAYS_PER_MONTH: rcParams['date.autoformatter.month'],
- 1: rcParams['date.autoformatter.day'],
- 1 / HOURS_PER_DAY: rcParams['date.autoformatter.hour'],
- 1 / MINUTES_PER_DAY: rcParams['date.autoformatter.minute'],
- 1 / SEC_PER_DAY: rcParams['date.autoformatter.second'],
- 1 / MUSECONDS_PER_DAY: rcParams['date.autoformatter.microsecond']
- }
-
- def _set_locator(self, locator):
- self._locator = locator
-
- def __call__(self, x, pos=None):
- try:
- locator_unit_scale = float(self._locator._get_unit())
- except AttributeError:
- locator_unit_scale = 1
- # Pick the first scale which is greater than the locator unit.
- fmt = next((fmt for scale, fmt in sorted(self.scaled.items())
- if scale >= locator_unit_scale),
- self.defaultfmt)
-
- if isinstance(fmt, str):
- self._formatter = DateFormatter(fmt, self._tz, usetex=self._usetex)
- result = self._formatter(x, pos)
- elif callable(fmt):
- result = fmt(x, pos)
- else:
- raise TypeError(f'Unexpected type passed to {self!r}.')
-
- return result
-
-
-class rrulewrapper:
- """
- A simple wrapper around a `dateutil.rrule` allowing flexible
- date tick specifications.
- """
- def __init__(self, freq, tzinfo=None, **kwargs):
- """
- Parameters
- ----------
- freq : {YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY}
- Tick frequency. These constants are defined in `dateutil.rrule`,
- but they are accessible from `matplotlib.dates` as well.
- tzinfo : `datetime.tzinfo`, optional
- Time zone information. The default is None.
- **kwargs
- Additional keyword arguments are passed to the `dateutil.rrule`.
- """
- kwargs['freq'] = freq
- self._base_tzinfo = tzinfo
-
- self._update_rrule(**kwargs)
-
- def set(self, **kwargs):
- """Set parameters for an existing wrapper."""
- self._construct.update(kwargs)
-
- self._update_rrule(**self._construct)
-
- def _update_rrule(self, **kwargs):
- tzinfo = self._base_tzinfo
-
- # rrule does not play nicely with timezones - especially pytz time
- # zones, it's best to use naive zones and attach timezones once the
- # datetimes are returned
- if 'dtstart' in kwargs:
- dtstart = kwargs['dtstart']
- if dtstart.tzinfo is not None:
- if tzinfo is None:
- tzinfo = dtstart.tzinfo
- else:
- dtstart = dtstart.astimezone(tzinfo)
-
- kwargs['dtstart'] = dtstart.replace(tzinfo=None)
-
- if 'until' in kwargs:
- until = kwargs['until']
- if until.tzinfo is not None:
- if tzinfo is not None:
- until = until.astimezone(tzinfo)
- else:
- raise ValueError('until cannot be aware if dtstart '
- 'is naive and tzinfo is None')
-
- kwargs['until'] = until.replace(tzinfo=None)
-
- self._construct = kwargs.copy()
- self._tzinfo = tzinfo
- self._rrule = rrule(**self._construct)
-
- def _attach_tzinfo(self, dt, tzinfo):
- # pytz zones are attached by "localizing" the datetime
- if hasattr(tzinfo, 'localize'):
- return tzinfo.localize(dt, is_dst=True)
-
- return dt.replace(tzinfo=tzinfo)
-
- def _aware_return_wrapper(self, f, returns_list=False):
- """Decorator function that allows rrule methods to handle tzinfo."""
- # This is only necessary if we're actually attaching a tzinfo
- if self._tzinfo is None:
- return f
-
- # All datetime arguments must be naive. If they are not naive, they are
- # converted to the _tzinfo zone before dropping the zone.
- def normalize_arg(arg):
- if isinstance(arg, datetime.datetime) and arg.tzinfo is not None:
- if arg.tzinfo is not self._tzinfo:
- arg = arg.astimezone(self._tzinfo)
-
- return arg.replace(tzinfo=None)
-
- return arg
-
- def normalize_args(args, kwargs):
- args = tuple(normalize_arg(arg) for arg in args)
- kwargs = {kw: normalize_arg(arg) for kw, arg in kwargs.items()}
-
- return args, kwargs
-
- # There are two kinds of functions we care about - ones that return
- # dates and ones that return lists of dates.
- if not returns_list:
- def inner_func(*args, **kwargs):
- args, kwargs = normalize_args(args, kwargs)
- dt = f(*args, **kwargs)
- return self._attach_tzinfo(dt, self._tzinfo)
- else:
- def inner_func(*args, **kwargs):
- args, kwargs = normalize_args(args, kwargs)
- dts = f(*args, **kwargs)
- return [self._attach_tzinfo(dt, self._tzinfo) for dt in dts]
-
- return functools.wraps(f)(inner_func)
-
- def __getattr__(self, name):
- if name in self.__dict__:
- return self.__dict__[name]
-
- f = getattr(self._rrule, name)
-
- if name in {'after', 'before'}:
- return self._aware_return_wrapper(f)
- elif name in {'xafter', 'xbefore', 'between'}:
- return self._aware_return_wrapper(f, returns_list=True)
- else:
- return f
-
- def __setstate__(self, state):
- self.__dict__.update(state)
-
-
-class DateLocator(ticker.Locator):
- """
- Determines the tick locations when plotting dates.
-
- This class is subclassed by other Locators and
- is not meant to be used on its own.
- """
- hms0d = {'byhour': 0, 'byminute': 0, 'bysecond': 0}
-
- def __init__(self, tz=None):
- """
- Parameters
- ----------
- tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
- Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
- """
- self.tz = _get_tzinfo(tz)
-
- def set_tzinfo(self, tz):
- """
- Set timezone info.
-
- Parameters
- ----------
- tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
- Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
- """
- self.tz = _get_tzinfo(tz)
-
- def datalim_to_dt(self):
- """Convert axis data interval to datetime objects."""
- dmin, dmax = self.axis.get_data_interval()
- if dmin > dmax:
- dmin, dmax = dmax, dmin
-
- return num2date(dmin, self.tz), num2date(dmax, self.tz)
-
- def viewlim_to_dt(self):
- """Convert the view interval to datetime objects."""
- vmin, vmax = self.axis.get_view_interval()
- if vmin > vmax:
- vmin, vmax = vmax, vmin
- return num2date(vmin, self.tz), num2date(vmax, self.tz)
-
- def _get_unit(self):
- """
- Return how many days a unit of the locator is; used for
- intelligent autoscaling.
- """
- return 1
-
- def _get_interval(self):
- """
- Return the number of units for each tick.
- """
- return 1
-
- def nonsingular(self, vmin, vmax):
- """
- Given the proposed upper and lower extent, adjust the range
- if it is too close to being singular (i.e. a range of ~0).
- """
- if not np.isfinite(vmin) or not np.isfinite(vmax):
- # Except if there is no data, then use 1970 as default.
- return (date2num(datetime.date(1970, 1, 1)),
- date2num(datetime.date(1970, 1, 2)))
- if vmax < vmin:
- vmin, vmax = vmax, vmin
- unit = self._get_unit()
- interval = self._get_interval()
- if abs(vmax - vmin) < 1e-6:
- vmin -= 2 * unit * interval
- vmax += 2 * unit * interval
- return vmin, vmax
-
-
-class RRuleLocator(DateLocator):
- # use the dateutil rrule instance
-
- def __init__(self, o, tz=None):
- super().__init__(tz)
- self.rule = o
-
- def __call__(self):
- # if no data have been set, this will tank with a ValueError
- try:
- dmin, dmax = self.viewlim_to_dt()
- except ValueError:
- return []
-
- return self.tick_values(dmin, dmax)
-
- def tick_values(self, vmin, vmax):
- start, stop = self._create_rrule(vmin, vmax)
- dates = self.rule.between(start, stop, True)
- if len(dates) == 0:
- return date2num([vmin, vmax])
- return self.raise_if_exceeds(date2num(dates))
-
- def _create_rrule(self, vmin, vmax):
- # set appropriate rrule dtstart and until and return
- # start and end
- delta = relativedelta(vmax, vmin)
-
- # We need to cap at the endpoints of valid datetime
- try:
- start = vmin - delta
- except (ValueError, OverflowError):
- # cap
- start = datetime.datetime(1, 1, 1, 0, 0, 0,
- tzinfo=datetime.timezone.utc)
-
- try:
- stop = vmax + delta
- except (ValueError, OverflowError):
- # cap
- stop = datetime.datetime(9999, 12, 31, 23, 59, 59,
- tzinfo=datetime.timezone.utc)
-
- self.rule.set(dtstart=start, until=stop)
-
- return vmin, vmax
-
- def _get_unit(self):
- # docstring inherited
- freq = self.rule._rrule._freq
- return self.get_unit_generic(freq)
-
- @staticmethod
- def get_unit_generic(freq):
- if freq == YEARLY:
- return DAYS_PER_YEAR
- elif freq == MONTHLY:
- return DAYS_PER_MONTH
- elif freq == WEEKLY:
- return DAYS_PER_WEEK
- elif freq == DAILY:
- return 1.0
- elif freq == HOURLY:
- return 1.0 / HOURS_PER_DAY
- elif freq == MINUTELY:
- return 1.0 / MINUTES_PER_DAY
- elif freq == SECONDLY:
- return 1.0 / SEC_PER_DAY
- else:
- # error
- return -1 # or should this just return '1'?
-
- def _get_interval(self):
- return self.rule._rrule._interval
-
-
-class AutoDateLocator(DateLocator):
- """
- On autoscale, this class picks the best `DateLocator` to set the view
- limits and the tick locations.
-
- Attributes
- ----------
- intervald : dict
-
- Mapping of tick frequencies to multiples allowed for that ticking.
- The default is ::
-
- self.intervald = {
- YEARLY : [1, 2, 4, 5, 10, 20, 40, 50, 100, 200, 400, 500,
- 1000, 2000, 4000, 5000, 10000],
- MONTHLY : [1, 2, 3, 4, 6],
- DAILY : [1, 2, 3, 7, 14, 21],
- HOURLY : [1, 2, 3, 4, 6, 12],
- MINUTELY: [1, 5, 10, 15, 30],
- SECONDLY: [1, 5, 10, 15, 30],
- MICROSECONDLY: [1, 2, 5, 10, 20, 50, 100, 200, 500,
- 1000, 2000, 5000, 10000, 20000, 50000,
- 100000, 200000, 500000, 1000000],
- }
-
- where the keys are defined in `dateutil.rrule`.
-
- The interval is used to specify multiples that are appropriate for
- the frequency of ticking. For instance, every 7 days is sensible
- for daily ticks, but for minutes/seconds, 15 or 30 make sense.
-
- When customizing, you should only modify the values for the existing
- keys. You should not add or delete entries.
-
- Example for forcing ticks every 3 hours::
-
- locator = AutoDateLocator()
- locator.intervald[HOURLY] = [3] # only show every 3 hours
- """
-
- def __init__(self, tz=None, minticks=5, maxticks=None,
- interval_multiples=True):
- """
- Parameters
- ----------
- tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
- Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
- minticks : int
- The minimum number of ticks desired; controls whether ticks occur
- yearly, monthly, etc.
- maxticks : int
- The maximum number of ticks desired; controls the interval between
- ticks (ticking every other, every 3, etc.). For fine-grained
- control, this can be a dictionary mapping individual rrule
- frequency constants (YEARLY, MONTHLY, etc.) to their own maximum
- number of ticks. This can be used to keep the number of ticks
- appropriate to the format chosen in `AutoDateFormatter`. Any
- frequency not specified in this dictionary is given a default
- value.
- interval_multiples : bool, default: True
- Whether ticks should be chosen to be multiple of the interval,
- locking them to 'nicer' locations. For example, this will force
- the ticks to be at hours 0, 6, 12, 18 when hourly ticking is done
- at 6 hour intervals.
- """
- super().__init__(tz=tz)
- self._freq = YEARLY
- self._freqs = [YEARLY, MONTHLY, DAILY, HOURLY, MINUTELY,
- SECONDLY, MICROSECONDLY]
- self.minticks = minticks
-
- self.maxticks = {YEARLY: 11, MONTHLY: 12, DAILY: 11, HOURLY: 12,
- MINUTELY: 11, SECONDLY: 11, MICROSECONDLY: 8}
- if maxticks is not None:
- try:
- self.maxticks.update(maxticks)
- except TypeError:
- # Assume we were given an integer. Use this as the maximum
- # number of ticks for every frequency and create a
- # dictionary for this
- self.maxticks = dict.fromkeys(self._freqs, maxticks)
- self.interval_multiples = interval_multiples
- self.intervald = {
- YEARLY: [1, 2, 4, 5, 10, 20, 40, 50, 100, 200, 400, 500,
- 1000, 2000, 4000, 5000, 10000],
- MONTHLY: [1, 2, 3, 4, 6],
- DAILY: [1, 2, 3, 7, 14, 21],
- HOURLY: [1, 2, 3, 4, 6, 12],
- MINUTELY: [1, 5, 10, 15, 30],
- SECONDLY: [1, 5, 10, 15, 30],
- MICROSECONDLY: [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000,
- 5000, 10000, 20000, 50000, 100000, 200000, 500000,
- 1000000],
- }
- if interval_multiples:
- # Swap "3" for "4" in the DAILY list; If we use 3 we get bad
- # tick loc for months w/ 31 days: 1, 4, ..., 28, 31, 1
- # If we use 4 then we get: 1, 5, ... 25, 29, 1
- self.intervald[DAILY] = [1, 2, 4, 7, 14]
-
- self._byranges = [None, range(1, 13), range(1, 32),
- range(0, 24), range(0, 60), range(0, 60), None]
-
- def __call__(self):
- # docstring inherited
- dmin, dmax = self.viewlim_to_dt()
- locator = self.get_locator(dmin, dmax)
- return locator()
-
- def tick_values(self, vmin, vmax):
- return self.get_locator(vmin, vmax).tick_values(vmin, vmax)
-
- def nonsingular(self, vmin, vmax):
- # whatever is thrown at us, we can scale the unit.
- # But default nonsingular date plots at an ~4 year period.
- if not np.isfinite(vmin) or not np.isfinite(vmax):
- # Except if there is no data, then use 1970 as default.
- return (date2num(datetime.date(1970, 1, 1)),
- date2num(datetime.date(1970, 1, 2)))
- if vmax < vmin:
- vmin, vmax = vmax, vmin
- if vmin == vmax:
- vmin = vmin - DAYS_PER_YEAR * 2
- vmax = vmax + DAYS_PER_YEAR * 2
- return vmin, vmax
-
- def _get_unit(self):
- if self._freq in [MICROSECONDLY]:
- return 1. / MUSECONDS_PER_DAY
- else:
- return RRuleLocator.get_unit_generic(self._freq)
-
- def get_locator(self, dmin, dmax):
- """Pick the best locator based on a distance."""
- delta = relativedelta(dmax, dmin)
- tdelta = dmax - dmin
-
- # take absolute difference
- if dmin > dmax:
- delta = -delta
- tdelta = -tdelta
- # The following uses a mix of calls to relativedelta and timedelta
- # methods because there is incomplete overlap in the functionality of
- # these similar functions, and it's best to avoid doing our own math
- # whenever possible.
- numYears = float(delta.years)
- numMonths = numYears * MONTHS_PER_YEAR + delta.months
- numDays = tdelta.days # Avoids estimates of days/month, days/year.
- numHours = numDays * HOURS_PER_DAY + delta.hours
- numMinutes = numHours * MIN_PER_HOUR + delta.minutes
- numSeconds = np.floor(tdelta.total_seconds())
- numMicroseconds = np.floor(tdelta.total_seconds() * 1e6)
-
- nums = [numYears, numMonths, numDays, numHours, numMinutes,
- numSeconds, numMicroseconds]
-
- use_rrule_locator = [True] * 6 + [False]
-
- # Default setting of bymonth, etc. to pass to rrule
- # [unused (for year), bymonth, bymonthday, byhour, byminute,
- # bysecond, unused (for microseconds)]
- byranges = [None, 1, 1, 0, 0, 0, None]
-
- # Loop over all the frequencies and try to find one that gives at
- # least a minticks tick positions. Once this is found, look for
- # an interval from a list specific to that frequency that gives no
- # more than maxticks tick positions. Also, set up some ranges
- # (bymonth, etc.) as appropriate to be passed to rrulewrapper.
- for i, (freq, num) in enumerate(zip(self._freqs, nums)):
- # If this particular frequency doesn't give enough ticks, continue
- if num < self.minticks:
- # Since we're not using this particular frequency, set
- # the corresponding by_ to None so the rrule can act as
- # appropriate
- byranges[i] = None
- continue
-
- # Find the first available interval that doesn't give too many
- # ticks
- for interval in self.intervald[freq]:
- if num <= interval * (self.maxticks[freq] - 1):
- break
- else:
- if not (self.interval_multiples and freq == DAILY):
- _api.warn_external(
- f"AutoDateLocator was unable to pick an appropriate "
- f"interval for this date range. It may be necessary "
- f"to add an interval value to the AutoDateLocator's "
- f"intervald dictionary. Defaulting to {interval}.")
-
- # Set some parameters as appropriate
- self._freq = freq
-
- if self._byranges[i] and self.interval_multiples:
- byranges[i] = self._byranges[i][::interval]
- if i in (DAILY, WEEKLY):
- if interval == 14:
- # just make first and 15th. Avoids 30th.
- byranges[i] = [1, 15]
- elif interval == 7:
- byranges[i] = [1, 8, 15, 22]
-
- interval = 1
- else:
- byranges[i] = self._byranges[i]
- break
- else:
- interval = 1
-
- if (freq == YEARLY) and self.interval_multiples:
- locator = YearLocator(interval, tz=self.tz)
- elif use_rrule_locator[i]:
- _, bymonth, bymonthday, byhour, byminute, bysecond, _ = byranges
- rrule = rrulewrapper(self._freq, interval=interval,
- dtstart=dmin, until=dmax,
- bymonth=bymonth, bymonthday=bymonthday,
- byhour=byhour, byminute=byminute,
- bysecond=bysecond)
-
- locator = RRuleLocator(rrule, tz=self.tz)
- else:
- locator = MicrosecondLocator(interval, tz=self.tz)
- if date2num(dmin) > 70 * 365 and interval < 1000:
- _api.warn_external(
- 'Plotting microsecond time intervals for dates far from '
- f'the epoch (time origin: {get_epoch()}) is not well-'
- 'supported. See matplotlib.dates.set_epoch to change the '
- 'epoch.')
-
- locator.set_axis(self.axis)
- return locator
-
-
-class YearLocator(RRuleLocator):
- """
- Make ticks on a given day of each year that is a multiple of base.
-
- Examples::
-
- # Tick every year on Jan 1st
- locator = YearLocator()
-
- # Tick every 5 years on July 4th
- locator = YearLocator(5, month=7, day=4)
- """
- def __init__(self, base=1, month=1, day=1, tz=None):
- """
- Parameters
- ----------
- base : int, default: 1
- Mark ticks every *base* years.
- month : int, default: 1
- The month on which to place the ticks, starting from 1. Default is
- January.
- day : int, default: 1
- The day on which to place the ticks.
- tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
- Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
- """
- rule = rrulewrapper(YEARLY, interval=base, bymonth=month,
- bymonthday=day, **self.hms0d)
- super().__init__(rule, tz=tz)
- self.base = ticker._Edge_integer(base, 0)
-
- def _create_rrule(self, vmin, vmax):
- # 'start' needs to be a multiple of the interval to create ticks on
- # interval multiples when the tick frequency is YEARLY
- ymin = max(self.base.le(vmin.year) * self.base.step, 1)
- ymax = min(self.base.ge(vmax.year) * self.base.step, 9999)
-
- c = self.rule._construct
- replace = {'year': ymin,
- 'month': c.get('bymonth', 1),
- 'day': c.get('bymonthday', 1),
- 'hour': 0, 'minute': 0, 'second': 0}
-
- start = vmin.replace(**replace)
- stop = start.replace(year=ymax)
- self.rule.set(dtstart=start, until=stop)
-
- return start, stop
-
-
-class MonthLocator(RRuleLocator):
- """
- Make ticks on occurrences of each month, e.g., 1, 3, 12.
- """
- def __init__(self, bymonth=None, bymonthday=1, interval=1, tz=None):
- """
- Parameters
- ----------
- bymonth : int or list of int, default: all months
- Ticks will be placed on every month in *bymonth*. Default is
- ``range(1, 13)``, i.e. every month.
- bymonthday : int, default: 1
- The day on which to place the ticks.
- interval : int, default: 1
- The interval between each iteration. For example, if
- ``interval=2``, mark every second occurrence.
- tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
- Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
- """
- if bymonth is None:
- bymonth = range(1, 13)
-
- rule = rrulewrapper(MONTHLY, bymonth=bymonth, bymonthday=bymonthday,
- interval=interval, **self.hms0d)
- super().__init__(rule, tz=tz)
-
-
-class WeekdayLocator(RRuleLocator):
- """
- Make ticks on occurrences of each weekday.
- """
-
- def __init__(self, byweekday=1, interval=1, tz=None):
- """
- Parameters
- ----------
- byweekday : int or list of int, default: all days
- Ticks will be placed on every weekday in *byweekday*. Default is
- every day.
-
- Elements of *byweekday* must be one of MO, TU, WE, TH, FR, SA,
- SU, the constants from :mod:`dateutil.rrule`, which have been
- imported into the :mod:`matplotlib.dates` namespace.
- interval : int, default: 1
- The interval between each iteration. For example, if
- ``interval=2``, mark every second occurrence.
- tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
- Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
- """
- rule = rrulewrapper(DAILY, byweekday=byweekday,
- interval=interval, **self.hms0d)
- super().__init__(rule, tz=tz)
-
-
-class DayLocator(RRuleLocator):
- """
- Make ticks on occurrences of each day of the month. For example,
- 1, 15, 30.
- """
- def __init__(self, bymonthday=None, interval=1, tz=None):
- """
- Parameters
- ----------
- bymonthday : int or list of int, default: all days
- Ticks will be placed on every day in *bymonthday*. Default is
- ``bymonthday=range(1, 32)``, i.e., every day of the month.
- interval : int, default: 1
- The interval between each iteration. For example, if
- ``interval=2``, mark every second occurrence.
- tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
- Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
- """
- if interval != int(interval) or interval < 1:
- raise ValueError("interval must be an integer greater than 0")
- if bymonthday is None:
- bymonthday = range(1, 32)
-
- rule = rrulewrapper(DAILY, bymonthday=bymonthday,
- interval=interval, **self.hms0d)
- super().__init__(rule, tz=tz)
-
-
-class HourLocator(RRuleLocator):
- """
- Make ticks on occurrences of each hour.
- """
- def __init__(self, byhour=None, interval=1, tz=None):
- """
- Parameters
- ----------
- byhour : int or list of int, default: all hours
- Ticks will be placed on every hour in *byhour*. Default is
- ``byhour=range(24)``, i.e., every hour.
- interval : int, default: 1
- The interval between each iteration. For example, if
- ``interval=2``, mark every second occurrence.
- tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
- Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
- """
- if byhour is None:
- byhour = range(24)
-
- rule = rrulewrapper(HOURLY, byhour=byhour, interval=interval,
- byminute=0, bysecond=0)
- super().__init__(rule, tz=tz)
-
-
-class MinuteLocator(RRuleLocator):
- """
- Make ticks on occurrences of each minute.
- """
- def __init__(self, byminute=None, interval=1, tz=None):
- """
- Parameters
- ----------
- byminute : int or list of int, default: all minutes
- Ticks will be placed on every minute in *byminute*. Default is
- ``byminute=range(60)``, i.e., every minute.
- interval : int, default: 1
- The interval between each iteration. For example, if
- ``interval=2``, mark every second occurrence.
- tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
- Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
- """
- if byminute is None:
- byminute = range(60)
-
- rule = rrulewrapper(MINUTELY, byminute=byminute, interval=interval,
- bysecond=0)
- super().__init__(rule, tz=tz)
-
-
-class SecondLocator(RRuleLocator):
- """
- Make ticks on occurrences of each second.
- """
- def __init__(self, bysecond=None, interval=1, tz=None):
- """
- Parameters
- ----------
- bysecond : int or list of int, default: all seconds
- Ticks will be placed on every second in *bysecond*. Default is
- ``bysecond = range(60)``, i.e., every second.
- interval : int, default: 1
- The interval between each iteration. For example, if
- ``interval=2``, mark every second occurrence.
- tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
- Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
- """
- if bysecond is None:
- bysecond = range(60)
-
- rule = rrulewrapper(SECONDLY, bysecond=bysecond, interval=interval)
- super().__init__(rule, tz=tz)
-
-
-class MicrosecondLocator(DateLocator):
- """
- Make ticks on regular intervals of one or more microsecond(s).
-
- .. note::
-
- By default, Matplotlib uses a floating point representation of time in
- days since the epoch, so plotting data with
- microsecond time resolution does not work well for
- dates that are far (about 70 years) from the epoch (check with
- `~.dates.get_epoch`).
-
- If you want sub-microsecond resolution time plots, it is strongly
- recommended to use floating point seconds, not datetime-like
- time representation.
-
- If you really must use datetime.datetime() or similar and still
- need microsecond precision, change the time origin via
- `.dates.set_epoch` to something closer to the dates being plotted.
- See :doc:`/gallery/ticks/date_precision_and_epochs`.
-
- """
- def __init__(self, interval=1, tz=None):
- """
- Parameters
- ----------
- interval : int, default: 1
- The interval between each iteration. For example, if
- ``interval=2``, mark every second occurrence.
- tz : str or `~datetime.tzinfo`, default: :rc:`timezone`
- Ticks timezone. If a string, *tz* is passed to `dateutil.tz`.
- """
- super().__init__(tz=tz)
- self._interval = interval
- self._wrapped_locator = ticker.MultipleLocator(interval)
-
- def set_axis(self, axis):
- self._wrapped_locator.set_axis(axis)
- return super().set_axis(axis)
-
- def __call__(self):
- # if no data have been set, this will tank with a ValueError
- try:
- dmin, dmax = self.viewlim_to_dt()
- except ValueError:
- return []
-
- return self.tick_values(dmin, dmax)
-
- def tick_values(self, vmin, vmax):
- nmin, nmax = date2num((vmin, vmax))
- t0 = np.floor(nmin)
- nmax = nmax - t0
- nmin = nmin - t0
- nmin *= MUSECONDS_PER_DAY
- nmax *= MUSECONDS_PER_DAY
-
- ticks = self._wrapped_locator.tick_values(nmin, nmax)
-
- ticks = ticks / MUSECONDS_PER_DAY + t0
- return ticks
-
- def _get_unit(self):
- # docstring inherited
- return 1. / MUSECONDS_PER_DAY
-
- def _get_interval(self):
- # docstring inherited
- return self._interval
-
-
-class DateConverter(units.ConversionInterface):
- """
- Converter for `datetime.date` and `datetime.datetime` data, or for
- date/time data represented as it would be converted by `date2num`.
-
- The 'unit' tag for such data is None or a `~datetime.tzinfo` instance.
- """
-
- def __init__(self, *, interval_multiples=True):
- self._interval_multiples = interval_multiples
- super().__init__()
-
- def axisinfo(self, unit, axis):
- """
- Return the `~matplotlib.units.AxisInfo` for *unit*.
-
- *unit* is a `~datetime.tzinfo` instance or None.
- The *axis* argument is required but not used.
- """
- tz = unit
-
- majloc = AutoDateLocator(tz=tz,
- interval_multiples=self._interval_multiples)
- majfmt = AutoDateFormatter(majloc, tz=tz)
- datemin = datetime.date(1970, 1, 1)
- datemax = datetime.date(1970, 1, 2)
-
- return units.AxisInfo(majloc=majloc, majfmt=majfmt, label='',
- default_limits=(datemin, datemax))
-
- @staticmethod
- def convert(value, unit, axis):
- """
- If *value* is not already a number or sequence of numbers, convert it
- with `date2num`.
-
- The *unit* and *axis* arguments are not used.
- """
- return date2num(value)
-
- @staticmethod
- def default_units(x, axis):
- """
- Return the `~datetime.tzinfo` instance of *x* or of its first element,
- or None
- """
- if isinstance(x, np.ndarray):
- x = x.ravel()
-
- try:
- x = cbook._safe_first_finite(x)
- except (TypeError, StopIteration):
- pass
-
- try:
- return x.tzinfo
- except AttributeError:
- pass
- return None
-
-
-class ConciseDateConverter(DateConverter):
- # docstring inherited
-
- def __init__(self, formats=None, zero_formats=None, offset_formats=None,
- show_offset=True, *, interval_multiples=True):
- self._formats = formats
- self._zero_formats = zero_formats
- self._offset_formats = offset_formats
- self._show_offset = show_offset
- self._interval_multiples = interval_multiples
- super().__init__()
-
- def axisinfo(self, unit, axis):
- # docstring inherited
- tz = unit
- majloc = AutoDateLocator(tz=tz,
- interval_multiples=self._interval_multiples)
- majfmt = ConciseDateFormatter(majloc, tz=tz, formats=self._formats,
- zero_formats=self._zero_formats,
- offset_formats=self._offset_formats,
- show_offset=self._show_offset)
- datemin = datetime.date(1970, 1, 1)
- datemax = datetime.date(1970, 1, 2)
- return units.AxisInfo(majloc=majloc, majfmt=majfmt, label='',
- default_limits=(datemin, datemax))
-
-
-class _SwitchableDateConverter:
- """
- Helper converter-like object that generates and dispatches to
- temporary ConciseDateConverter or DateConverter instances based on
- :rc:`date.converter` and :rc:`date.interval_multiples`.
- """
-
- @staticmethod
- def _get_converter():
- converter_cls = {
- "concise": ConciseDateConverter, "auto": DateConverter}[
- mpl.rcParams["date.converter"]]
- interval_multiples = mpl.rcParams["date.interval_multiples"]
- return converter_cls(interval_multiples=interval_multiples)
-
- def axisinfo(self, *args, **kwargs):
- return self._get_converter().axisinfo(*args, **kwargs)
-
- def default_units(self, *args, **kwargs):
- return self._get_converter().default_units(*args, **kwargs)
-
- def convert(self, *args, **kwargs):
- return self._get_converter().convert(*args, **kwargs)
-
-
-units.registry[np.datetime64] = \
- units.registry[datetime.date] = \
- units.registry[datetime.datetime] = \
- _SwitchableDateConverter()
diff --git a/contrib/python/matplotlib/py3/matplotlib/dviread.py b/contrib/python/matplotlib/py3/matplotlib/dviread.py
deleted file mode 100644
index b2177e5087..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/dviread.py
+++ /dev/null
@@ -1,1149 +0,0 @@
-"""
-A module for reading dvi files output by TeX. Several limitations make
-this not (currently) useful as a general-purpose dvi preprocessor, but
-it is currently used by the pdf backend for processing usetex text.
-
-Interface::
-
- with Dvi(filename, 72) as dvi:
- # iterate over pages:
- for page in dvi:
- w, h, d = page.width, page.height, page.descent
- for x, y, font, glyph, width in page.text:
- fontname = font.texname
- pointsize = font.size
- ...
- for x, y, height, width in page.boxes:
- ...
-"""
-
-from collections import namedtuple
-import enum
-from functools import lru_cache, partial, wraps
-import logging
-import os
-from pathlib import Path
-import re
-import struct
-import subprocess
-import sys
-
-import numpy as np
-
-from matplotlib import _api, cbook
-
-_log = logging.getLogger(__name__)
-
-# Many dvi related files are looked for by external processes, require
-# additional parsing, and are used many times per rendering, which is why they
-# are cached using lru_cache().
-
-# Dvi is a bytecode format documented in
-# https://ctan.org/pkg/dvitype
-# https://texdoc.org/serve/dvitype.pdf/0
-#
-# The file consists of a preamble, some number of pages, a postamble,
-# and a finale. Different opcodes are allowed in different contexts,
-# so the Dvi object has a parser state:
-#
-# pre: expecting the preamble
-# outer: between pages (followed by a page or the postamble,
-# also e.g. font definitions are allowed)
-# page: processing a page
-# post_post: state after the postamble (our current implementation
-# just stops reading)
-# finale: the finale (unimplemented in our current implementation)
-
-_dvistate = enum.Enum('DviState', 'pre outer inpage post_post finale')
-
-# The marks on a page consist of text and boxes. A page also has dimensions.
-Page = namedtuple('Page', 'text boxes height width descent')
-Box = namedtuple('Box', 'x y height width')
-
-
-# Also a namedtuple, for backcompat.
-class Text(namedtuple('Text', 'x y font glyph width')):
- """
- A glyph in the dvi file.
-
- The *x* and *y* attributes directly position the glyph. The *font*,
- *glyph*, and *width* attributes are kept public for back-compatibility,
- but users wanting to draw the glyph themselves are encouraged to instead
- load the font specified by `font_path` at `font_size`, warp it with the
- effects specified by `font_effects`, and load the glyph specified by
- `glyph_name_or_index`.
- """
-
- def _get_pdftexmap_entry(self):
- return PsfontsMap(find_tex_file("pdftex.map"))[self.font.texname]
-
- @property
- def font_path(self):
- """The `~pathlib.Path` to the font for this glyph."""
- psfont = self._get_pdftexmap_entry()
- if psfont.filename is None:
- raise ValueError("No usable font file found for {} ({}); "
- "the font may lack a Type-1 version"
- .format(psfont.psname.decode("ascii"),
- psfont.texname.decode("ascii")))
- return Path(psfont.filename)
-
- @property
- def font_size(self):
- """The font size."""
- return self.font.size
-
- @property
- def font_effects(self):
- """
- The "font effects" dict for this glyph.
-
- This dict contains the values for this glyph of SlantFont and
- ExtendFont (if any), read off :file:`pdftex.map`.
- """
- return self._get_pdftexmap_entry().effects
-
- @property
- def glyph_name_or_index(self):
- """
- Either the glyph name or the native charmap glyph index.
-
- If :file:`pdftex.map` specifies an encoding for this glyph's font, that
- is a mapping of glyph indices to Adobe glyph names; use it to convert
- dvi indices to glyph names. Callers can then convert glyph names to
- glyph indices (with FT_Get_Name_Index/get_name_index), and load the
- glyph using FT_Load_Glyph/load_glyph.
-
- If :file:`pdftex.map` specifies no encoding, the indices directly map
- to the font's "native" charmap; glyphs should directly load using
- FT_Load_Char/load_char after selecting the native charmap.
- """
- entry = self._get_pdftexmap_entry()
- return (_parse_enc(entry.encoding)[self.glyph]
- if entry.encoding is not None else self.glyph)
-
-
-# Opcode argument parsing
-#
-# Each of the following functions takes a Dvi object and delta,
-# which is the difference between the opcode and the minimum opcode
-# with the same meaning. Dvi opcodes often encode the number of
-# argument bytes in this delta.
-
-def _arg_raw(dvi, delta):
- """Return *delta* without reading anything more from the dvi file."""
- return delta
-
-
-def _arg(nbytes, signed, dvi, _):
- """
- Read *nbytes* bytes, returning the bytes interpreted as a signed integer
- if *signed* is true, unsigned otherwise.
- """
- return dvi._arg(nbytes, signed)
-
-
-def _arg_slen(dvi, delta):
- """
- Read *delta* bytes, returning None if *delta* is zero, and the bytes
- interpreted as a signed integer otherwise.
- """
- if delta == 0:
- return None
- return dvi._arg(delta, True)
-
-
-def _arg_slen1(dvi, delta):
- """
- Read *delta*+1 bytes, returning the bytes interpreted as signed.
- """
- return dvi._arg(delta + 1, True)
-
-
-def _arg_ulen1(dvi, delta):
- """
- Read *delta*+1 bytes, returning the bytes interpreted as unsigned.
- """
- return dvi._arg(delta + 1, False)
-
-
-def _arg_olen1(dvi, delta):
- """
- Read *delta*+1 bytes, returning the bytes interpreted as
- unsigned integer for 0<=*delta*<3 and signed if *delta*==3.
- """
- return dvi._arg(delta + 1, delta == 3)
-
-
-_arg_mapping = dict(raw=_arg_raw,
- u1=partial(_arg, 1, False),
- u4=partial(_arg, 4, False),
- s4=partial(_arg, 4, True),
- slen=_arg_slen,
- olen1=_arg_olen1,
- slen1=_arg_slen1,
- ulen1=_arg_ulen1)
-
-
-def _dispatch(table, min, max=None, state=None, args=('raw',)):
- """
- Decorator for dispatch by opcode. Sets the values in *table*
- from *min* to *max* to this method, adds a check that the Dvi state
- matches *state* if not None, reads arguments from the file according
- to *args*.
-
- Parameters
- ----------
- table : dict[int, callable]
- The dispatch table to be filled in.
-
- min, max : int
- Range of opcodes that calls the registered function; *max* defaults to
- *min*.
-
- state : _dvistate, optional
- State of the Dvi object in which these opcodes are allowed.
-
- args : list[str], default: ['raw']
- Sequence of argument specifications:
-
- - 'raw': opcode minus minimum
- - 'u1': read one unsigned byte
- - 'u4': read four bytes, treat as an unsigned number
- - 's4': read four bytes, treat as a signed number
- - 'slen': read (opcode - minimum) bytes, treat as signed
- - 'slen1': read (opcode - minimum + 1) bytes, treat as signed
- - 'ulen1': read (opcode - minimum + 1) bytes, treat as unsigned
- - 'olen1': read (opcode - minimum + 1) bytes, treat as unsigned
- if under four bytes, signed if four bytes
- """
- def decorate(method):
- get_args = [_arg_mapping[x] for x in args]
-
- @wraps(method)
- def wrapper(self, byte):
- if state is not None and self.state != state:
- raise ValueError("state precondition failed")
- return method(self, *[f(self, byte-min) for f in get_args])
- if max is None:
- table[min] = wrapper
- else:
- for i in range(min, max+1):
- assert table[i] is None
- table[i] = wrapper
- return wrapper
- return decorate
-
-
-class Dvi:
- """
- A reader for a dvi ("device-independent") file, as produced by TeX.
-
- The current implementation can only iterate through pages in order,
- and does not even attempt to verify the postamble.
-
- This class can be used as a context manager to close the underlying
- file upon exit. Pages can be read via iteration. Here is an overly
- simple way to extract text without trying to detect whitespace::
-
- >>> with matplotlib.dviread.Dvi('input.dvi', 72) as dvi:
- ... for page in dvi:
- ... print(''.join(chr(t.glyph) for t in page.text))
- """
- # dispatch table
- _dtable = [None] * 256
- _dispatch = partial(_dispatch, _dtable)
-
- def __init__(self, filename, dpi):
- """
- Read the data from the file named *filename* and convert
- TeX's internal units to units of *dpi* per inch.
- *dpi* only sets the units and does not limit the resolution.
- Use None to return TeX's internal units.
- """
- _log.debug('Dvi: %s', filename)
- self.file = open(filename, 'rb')
- self.dpi = dpi
- self.fonts = {}
- self.state = _dvistate.pre
-
- def __enter__(self):
- """Context manager enter method, does nothing."""
- return self
-
- def __exit__(self, etype, evalue, etrace):
- """
- Context manager exit method, closes the underlying file if it is open.
- """
- self.close()
-
- def __iter__(self):
- """
- Iterate through the pages of the file.
-
- Yields
- ------
- Page
- Details of all the text and box objects on the page.
- The Page tuple contains lists of Text and Box tuples and
- the page dimensions, and the Text and Box tuples contain
- coordinates transformed into a standard Cartesian
- coordinate system at the dpi value given when initializing.
- The coordinates are floating point numbers, but otherwise
- precision is not lost and coordinate values are not clipped to
- integers.
- """
- while self._read():
- yield self._output()
-
- def close(self):
- """Close the underlying file if it is open."""
- if not self.file.closed:
- self.file.close()
-
- def _output(self):
- """
- Output the text and boxes belonging to the most recent page.
- page = dvi._output()
- """
- minx, miny, maxx, maxy = np.inf, np.inf, -np.inf, -np.inf
- maxy_pure = -np.inf
- for elt in self.text + self.boxes:
- if isinstance(elt, Box):
- x, y, h, w = elt
- e = 0 # zero depth
- else: # glyph
- x, y, font, g, w = elt
- h, e = font._height_depth_of(g)
- minx = min(minx, x)
- miny = min(miny, y - h)
- maxx = max(maxx, x + w)
- maxy = max(maxy, y + e)
- maxy_pure = max(maxy_pure, y)
- if self._baseline_v is not None:
- maxy_pure = self._baseline_v # This should normally be the case.
- self._baseline_v = None
-
- if not self.text and not self.boxes: # Avoid infs/nans from inf+/-inf.
- return Page(text=[], boxes=[], width=0, height=0, descent=0)
-
- if self.dpi is None:
- # special case for ease of debugging: output raw dvi coordinates
- return Page(text=self.text, boxes=self.boxes,
- width=maxx-minx, height=maxy_pure-miny,
- descent=maxy-maxy_pure)
-
- # convert from TeX's "scaled points" to dpi units
- d = self.dpi / (72.27 * 2**16)
- descent = (maxy - maxy_pure) * d
-
- text = [Text((x-minx)*d, (maxy-y)*d - descent, f, g, w*d)
- for (x, y, f, g, w) in self.text]
- boxes = [Box((x-minx)*d, (maxy-y)*d - descent, h*d, w*d)
- for (x, y, h, w) in self.boxes]
-
- return Page(text=text, boxes=boxes, width=(maxx-minx)*d,
- height=(maxy_pure-miny)*d, descent=descent)
-
- def _read(self):
- """
- Read one page from the file. Return True if successful,
- False if there were no more pages.
- """
- # Pages appear to start with the sequence
- # bop (begin of page)
- # xxx comment
- # <push, ..., pop> # if using chemformula
- # down
- # push
- # down
- # <push, push, xxx, right, xxx, pop, pop> # if using xcolor
- # down
- # push
- # down (possibly multiple)
- # push <= here, v is the baseline position.
- # etc.
- # (dviasm is useful to explore this structure.)
- # Thus, we use the vertical position at the first time the stack depth
- # reaches 3, while at least three "downs" have been executed (excluding
- # those popped out (corresponding to the chemformula preamble)), as the
- # baseline (the "down" count is necessary to handle xcolor).
- down_stack = [0]
- self._baseline_v = None
- while True:
- byte = self.file.read(1)[0]
- self._dtable[byte](self, byte)
- name = self._dtable[byte].__name__
- if name == "_push":
- down_stack.append(down_stack[-1])
- elif name == "_pop":
- down_stack.pop()
- elif name == "_down":
- down_stack[-1] += 1
- if (self._baseline_v is None
- and len(getattr(self, "stack", [])) == 3
- and down_stack[-1] >= 4):
- self._baseline_v = self.v
- if byte == 140: # end of page
- return True
- if self.state is _dvistate.post_post: # end of file
- self.close()
- return False
-
- def _arg(self, nbytes, signed=False):
- """
- Read and return an integer argument *nbytes* long.
- Signedness is determined by the *signed* keyword.
- """
- buf = self.file.read(nbytes)
- value = buf[0]
- if signed and value >= 0x80:
- value = value - 0x100
- for b in buf[1:]:
- value = 0x100*value + b
- return value
-
- @_dispatch(min=0, max=127, state=_dvistate.inpage)
- def _set_char_immediate(self, char):
- self._put_char_real(char)
- self.h += self.fonts[self.f]._width_of(char)
-
- @_dispatch(min=128, max=131, state=_dvistate.inpage, args=('olen1',))
- def _set_char(self, char):
- self._put_char_real(char)
- self.h += self.fonts[self.f]._width_of(char)
-
- @_dispatch(132, state=_dvistate.inpage, args=('s4', 's4'))
- def _set_rule(self, a, b):
- self._put_rule_real(a, b)
- self.h += b
-
- @_dispatch(min=133, max=136, state=_dvistate.inpage, args=('olen1',))
- def _put_char(self, char):
- self._put_char_real(char)
-
- def _put_char_real(self, char):
- font = self.fonts[self.f]
- if font._vf is None:
- self.text.append(Text(self.h, self.v, font, char,
- font._width_of(char)))
- else:
- scale = font._scale
- for x, y, f, g, w in font._vf[char].text:
- newf = DviFont(scale=_mul2012(scale, f._scale),
- tfm=f._tfm, texname=f.texname, vf=f._vf)
- self.text.append(Text(self.h + _mul2012(x, scale),
- self.v + _mul2012(y, scale),
- newf, g, newf._width_of(g)))
- self.boxes.extend([Box(self.h + _mul2012(x, scale),
- self.v + _mul2012(y, scale),
- _mul2012(a, scale), _mul2012(b, scale))
- for x, y, a, b in font._vf[char].boxes])
-
- @_dispatch(137, state=_dvistate.inpage, args=('s4', 's4'))
- def _put_rule(self, a, b):
- self._put_rule_real(a, b)
-
- def _put_rule_real(self, a, b):
- if a > 0 and b > 0:
- self.boxes.append(Box(self.h, self.v, a, b))
-
- @_dispatch(138)
- def _nop(self, _):
- pass
-
- @_dispatch(139, state=_dvistate.outer, args=('s4',)*11)
- def _bop(self, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9, p):
- self.state = _dvistate.inpage
- self.h, self.v, self.w, self.x, self.y, self.z = 0, 0, 0, 0, 0, 0
- self.stack = []
- self.text = [] # list of Text objects
- self.boxes = [] # list of Box objects
-
- @_dispatch(140, state=_dvistate.inpage)
- def _eop(self, _):
- self.state = _dvistate.outer
- del self.h, self.v, self.w, self.x, self.y, self.z, self.stack
-
- @_dispatch(141, state=_dvistate.inpage)
- def _push(self, _):
- self.stack.append((self.h, self.v, self.w, self.x, self.y, self.z))
-
- @_dispatch(142, state=_dvistate.inpage)
- def _pop(self, _):
- self.h, self.v, self.w, self.x, self.y, self.z = self.stack.pop()
-
- @_dispatch(min=143, max=146, state=_dvistate.inpage, args=('slen1',))
- def _right(self, b):
- self.h += b
-
- @_dispatch(min=147, max=151, state=_dvistate.inpage, args=('slen',))
- def _right_w(self, new_w):
- if new_w is not None:
- self.w = new_w
- self.h += self.w
-
- @_dispatch(min=152, max=156, state=_dvistate.inpage, args=('slen',))
- def _right_x(self, new_x):
- if new_x is not None:
- self.x = new_x
- self.h += self.x
-
- @_dispatch(min=157, max=160, state=_dvistate.inpage, args=('slen1',))
- def _down(self, a):
- self.v += a
-
- @_dispatch(min=161, max=165, state=_dvistate.inpage, args=('slen',))
- def _down_y(self, new_y):
- if new_y is not None:
- self.y = new_y
- self.v += self.y
-
- @_dispatch(min=166, max=170, state=_dvistate.inpage, args=('slen',))
- def _down_z(self, new_z):
- if new_z is not None:
- self.z = new_z
- self.v += self.z
-
- @_dispatch(min=171, max=234, state=_dvistate.inpage)
- def _fnt_num_immediate(self, k):
- self.f = k
-
- @_dispatch(min=235, max=238, state=_dvistate.inpage, args=('olen1',))
- def _fnt_num(self, new_f):
- self.f = new_f
-
- @_dispatch(min=239, max=242, args=('ulen1',))
- def _xxx(self, datalen):
- special = self.file.read(datalen)
- _log.debug(
- 'Dvi._xxx: encountered special: %s',
- ''.join([chr(ch) if 32 <= ch < 127 else '<%02x>' % ch
- for ch in special]))
-
- @_dispatch(min=243, max=246, args=('olen1', 'u4', 'u4', 'u4', 'u1', 'u1'))
- def _fnt_def(self, k, c, s, d, a, l):
- self._fnt_def_real(k, c, s, d, a, l)
-
- def _fnt_def_real(self, k, c, s, d, a, l):
- n = self.file.read(a + l)
- fontname = n[-l:].decode('ascii')
- tfm = _tfmfile(fontname)
- if c != 0 and tfm.checksum != 0 and c != tfm.checksum:
- raise ValueError('tfm checksum mismatch: %s' % n)
- try:
- vf = _vffile(fontname)
- except FileNotFoundError:
- vf = None
- self.fonts[k] = DviFont(scale=s, tfm=tfm, texname=n, vf=vf)
-
- @_dispatch(247, state=_dvistate.pre, args=('u1', 'u4', 'u4', 'u4', 'u1'))
- def _pre(self, i, num, den, mag, k):
- self.file.read(k) # comment in the dvi file
- if i != 2:
- raise ValueError("Unknown dvi format %d" % i)
- if num != 25400000 or den != 7227 * 2**16:
- raise ValueError("Nonstandard units in dvi file")
- # meaning: TeX always uses those exact values, so it
- # should be enough for us to support those
- # (There are 72.27 pt to an inch so 7227 pt =
- # 7227 * 2**16 sp to 100 in. The numerator is multiplied
- # by 10^5 to get units of 10**-7 meters.)
- if mag != 1000:
- raise ValueError("Nonstandard magnification in dvi file")
- # meaning: LaTeX seems to frown on setting \mag, so
- # I think we can assume this is constant
- self.state = _dvistate.outer
-
- @_dispatch(248, state=_dvistate.outer)
- def _post(self, _):
- self.state = _dvistate.post_post
- # TODO: actually read the postamble and finale?
- # currently post_post just triggers closing the file
-
- @_dispatch(249)
- def _post_post(self, _):
- raise NotImplementedError
-
- @_dispatch(min=250, max=255)
- def _malformed(self, offset):
- raise ValueError(f"unknown command: byte {250 + offset}")
-
-
-class DviFont:
- """
- Encapsulation of a font that a DVI file can refer to.
-
- This class holds a font's texname and size, supports comparison,
- and knows the widths of glyphs in the same units as the AFM file.
- There are also internal attributes (for use by dviread.py) that
- are *not* used for comparison.
-
- The size is in Adobe points (converted from TeX points).
-
- Parameters
- ----------
- scale : float
- Factor by which the font is scaled from its natural size.
- tfm : Tfm
- TeX font metrics for this font
- texname : bytes
- Name of the font as used internally by TeX and friends, as an ASCII
- bytestring. This is usually very different from any external font
- names; `PsfontsMap` can be used to find the external name of the font.
- vf : Vf
- A TeX "virtual font" file, or None if this font is not virtual.
-
- Attributes
- ----------
- texname : bytes
- size : float
- Size of the font in Adobe points, converted from the slightly
- smaller TeX points.
- widths : list
- Widths of glyphs in glyph-space units, typically 1/1000ths of
- the point size.
-
- """
- __slots__ = ('texname', 'size', 'widths', '_scale', '_vf', '_tfm')
-
- def __init__(self, scale, tfm, texname, vf):
- _api.check_isinstance(bytes, texname=texname)
- self._scale = scale
- self._tfm = tfm
- self.texname = texname
- self._vf = vf
- self.size = scale * (72.0 / (72.27 * 2**16))
- try:
- nchars = max(tfm.width) + 1
- except ValueError:
- nchars = 0
- self.widths = [(1000*tfm.width.get(char, 0)) >> 20
- for char in range(nchars)]
-
- def __eq__(self, other):
- return (type(self) is type(other)
- and self.texname == other.texname and self.size == other.size)
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def __repr__(self):
- return f"<{type(self).__name__}: {self.texname}>"
-
- def _width_of(self, char):
- """Width of char in dvi units."""
- width = self._tfm.width.get(char, None)
- if width is not None:
- return _mul2012(width, self._scale)
- _log.debug('No width for char %d in font %s.', char, self.texname)
- return 0
-
- def _height_depth_of(self, char):
- """Height and depth of char in dvi units."""
- result = []
- for metric, name in ((self._tfm.height, "height"),
- (self._tfm.depth, "depth")):
- value = metric.get(char, None)
- if value is None:
- _log.debug('No %s for char %d in font %s',
- name, char, self.texname)
- result.append(0)
- else:
- result.append(_mul2012(value, self._scale))
- # cmsyXX (symbols font) glyph 0 ("minus") has a nonzero descent
- # so that TeX aligns equations properly
- # (https://tex.stackexchange.com/q/526103/)
- # but we actually care about the rasterization depth to align
- # the dvipng-generated images.
- if re.match(br'^cmsy\d+$', self.texname) and char == 0:
- result[-1] = 0
- return result
-
-
-class Vf(Dvi):
- r"""
- A virtual font (\*.vf file) containing subroutines for dvi files.
-
- Parameters
- ----------
- filename : str or path-like
-
- Notes
- -----
- The virtual font format is a derivative of dvi:
- http://mirrors.ctan.org/info/knuth/virtual-fonts
- This class reuses some of the machinery of `Dvi`
- but replaces the `_read` loop and dispatch mechanism.
-
- Examples
- --------
- ::
-
- vf = Vf(filename)
- glyph = vf[code]
- glyph.text, glyph.boxes, glyph.width
- """
-
- def __init__(self, filename):
- super().__init__(filename, 0)
- try:
- self._first_font = None
- self._chars = {}
- self._read()
- finally:
- self.close()
-
- def __getitem__(self, code):
- return self._chars[code]
-
- def _read(self):
- """
- Read one page from the file. Return True if successful,
- False if there were no more pages.
- """
- packet_char, packet_ends = None, None
- packet_len, packet_width = None, None
- while True:
- byte = self.file.read(1)[0]
- # If we are in a packet, execute the dvi instructions
- if self.state is _dvistate.inpage:
- byte_at = self.file.tell()-1
- if byte_at == packet_ends:
- self._finalize_packet(packet_char, packet_width)
- packet_len, packet_char, packet_width = None, None, None
- # fall through to out-of-packet code
- elif byte_at > packet_ends:
- raise ValueError("Packet length mismatch in vf file")
- else:
- if byte in (139, 140) or byte >= 243:
- raise ValueError(
- "Inappropriate opcode %d in vf file" % byte)
- Dvi._dtable[byte](self, byte)
- continue
-
- # We are outside a packet
- if byte < 242: # a short packet (length given by byte)
- packet_len = byte
- packet_char, packet_width = self._arg(1), self._arg(3)
- packet_ends = self._init_packet(byte)
- self.state = _dvistate.inpage
- elif byte == 242: # a long packet
- packet_len, packet_char, packet_width = \
- [self._arg(x) for x in (4, 4, 4)]
- self._init_packet(packet_len)
- elif 243 <= byte <= 246:
- k = self._arg(byte - 242, byte == 246)
- c, s, d, a, l = [self._arg(x) for x in (4, 4, 4, 1, 1)]
- self._fnt_def_real(k, c, s, d, a, l)
- if self._first_font is None:
- self._first_font = k
- elif byte == 247: # preamble
- i, k = self._arg(1), self._arg(1)
- x = self.file.read(k)
- cs, ds = self._arg(4), self._arg(4)
- self._pre(i, x, cs, ds)
- elif byte == 248: # postamble (just some number of 248s)
- break
- else:
- raise ValueError("Unknown vf opcode %d" % byte)
-
- def _init_packet(self, pl):
- if self.state != _dvistate.outer:
- raise ValueError("Misplaced packet in vf file")
- self.h, self.v, self.w, self.x, self.y, self.z = 0, 0, 0, 0, 0, 0
- self.stack, self.text, self.boxes = [], [], []
- self.f = self._first_font
- return self.file.tell() + pl
-
- def _finalize_packet(self, packet_char, packet_width):
- self._chars[packet_char] = Page(
- text=self.text, boxes=self.boxes, width=packet_width,
- height=None, descent=None)
- self.state = _dvistate.outer
-
- def _pre(self, i, x, cs, ds):
- if self.state is not _dvistate.pre:
- raise ValueError("pre command in middle of vf file")
- if i != 202:
- raise ValueError("Unknown vf format %d" % i)
- if len(x):
- _log.debug('vf file comment: %s', x)
- self.state = _dvistate.outer
- # cs = checksum, ds = design size
-
-
-def _mul2012(num1, num2):
- """Multiply two numbers in 20.12 fixed point format."""
- # Separated into a function because >> has surprising precedence
- return (num1*num2) >> 20
-
-
-class Tfm:
- """
- A TeX Font Metric file.
-
- This implementation covers only the bare minimum needed by the Dvi class.
-
- Parameters
- ----------
- filename : str or path-like
-
- Attributes
- ----------
- checksum : int
- Used for verifying against the dvi file.
- design_size : int
- Design size of the font (unknown units)
- width, height, depth : dict
- Dimensions of each character, need to be scaled by the factor
- specified in the dvi file. These are dicts because indexing may
- not start from 0.
- """
- __slots__ = ('checksum', 'design_size', 'width', 'height', 'depth')
-
- def __init__(self, filename):
- _log.debug('opening tfm file %s', filename)
- with open(filename, 'rb') as file:
- header1 = file.read(24)
- lh, bc, ec, nw, nh, nd = struct.unpack('!6H', header1[2:14])
- _log.debug('lh=%d, bc=%d, ec=%d, nw=%d, nh=%d, nd=%d',
- lh, bc, ec, nw, nh, nd)
- header2 = file.read(4*lh)
- self.checksum, self.design_size = struct.unpack('!2I', header2[:8])
- # there is also encoding information etc.
- char_info = file.read(4*(ec-bc+1))
- widths = struct.unpack(f'!{nw}i', file.read(4*nw))
- heights = struct.unpack(f'!{nh}i', file.read(4*nh))
- depths = struct.unpack(f'!{nd}i', file.read(4*nd))
- self.width, self.height, self.depth = {}, {}, {}
- for idx, char in enumerate(range(bc, ec+1)):
- byte0 = char_info[4*idx]
- byte1 = char_info[4*idx+1]
- self.width[char] = widths[byte0]
- self.height[char] = heights[byte1 >> 4]
- self.depth[char] = depths[byte1 & 0xf]
-
-
-PsFont = namedtuple('PsFont', 'texname psname effects encoding filename')
-
-
-class PsfontsMap:
- """
- A psfonts.map formatted file, mapping TeX fonts to PS fonts.
-
- Parameters
- ----------
- filename : str or path-like
-
- Notes
- -----
- For historical reasons, TeX knows many Type-1 fonts by different
- names than the outside world. (For one thing, the names have to
- fit in eight characters.) Also, TeX's native fonts are not Type-1
- but Metafont, which is nontrivial to convert to PostScript except
- as a bitmap. While high-quality conversions to Type-1 format exist
- and are shipped with modern TeX distributions, we need to know
- which Type-1 fonts are the counterparts of which native fonts. For
- these reasons a mapping is needed from internal font names to font
- file names.
-
- A texmf tree typically includes mapping files called e.g.
- :file:`psfonts.map`, :file:`pdftex.map`, or :file:`dvipdfm.map`.
- The file :file:`psfonts.map` is used by :program:`dvips`,
- :file:`pdftex.map` by :program:`pdfTeX`, and :file:`dvipdfm.map`
- by :program:`dvipdfm`. :file:`psfonts.map` might avoid embedding
- the 35 PostScript fonts (i.e., have no filename for them, as in
- the Times-Bold example above), while the pdf-related files perhaps
- only avoid the "Base 14" pdf fonts. But the user may have
- configured these files differently.
-
- Examples
- --------
- >>> map = PsfontsMap(find_tex_file('pdftex.map'))
- >>> entry = map[b'ptmbo8r']
- >>> entry.texname
- b'ptmbo8r'
- >>> entry.psname
- b'Times-Bold'
- >>> entry.encoding
- '/usr/local/texlive/2008/texmf-dist/fonts/enc/dvips/base/8r.enc'
- >>> entry.effects
- {'slant': 0.16700000000000001}
- >>> entry.filename
- """
- __slots__ = ('_filename', '_unparsed', '_parsed')
-
- # Create a filename -> PsfontsMap cache, so that calling
- # `PsfontsMap(filename)` with the same filename a second time immediately
- # returns the same object.
- @lru_cache
- def __new__(cls, filename):
- self = object.__new__(cls)
- self._filename = os.fsdecode(filename)
- # Some TeX distributions have enormous pdftex.map files which would
- # take hundreds of milliseconds to parse, but it is easy enough to just
- # store the unparsed lines (keyed by the first word, which is the
- # texname) and parse them on-demand.
- with open(filename, 'rb') as file:
- self._unparsed = {}
- for line in file:
- tfmname = line.split(b' ', 1)[0]
- self._unparsed.setdefault(tfmname, []).append(line)
- self._parsed = {}
- return self
-
- def __getitem__(self, texname):
- assert isinstance(texname, bytes)
- if texname in self._unparsed:
- for line in self._unparsed.pop(texname):
- if self._parse_and_cache_line(line):
- break
- try:
- return self._parsed[texname]
- except KeyError:
- raise LookupError(
- f"An associated PostScript font (required by Matplotlib) "
- f"could not be found for TeX font {texname.decode('ascii')!r} "
- f"in {self._filename!r}; this problem can often be solved by "
- f"installing a suitable PostScript font package in your TeX "
- f"package manager") from None
-
- def _parse_and_cache_line(self, line):
- """
- Parse a line in the font mapping file.
-
- The format is (partially) documented at
- http://mirrors.ctan.org/systems/doc/pdftex/manual/pdftex-a.pdf
- https://tug.org/texinfohtml/dvips.html#psfonts_002emap
- Each line can have the following fields:
-
- - tfmname (first, only required field),
- - psname (defaults to tfmname, must come immediately after tfmname if
- present),
- - fontflags (integer, must come immediately after psname if present,
- ignored by us),
- - special (SlantFont and ExtendFont, only field that is double-quoted),
- - fontfile, encodingfile (optional, prefixed by <, <<, or <[; << always
- precedes a font, <[ always precedes an encoding, < can precede either
- but then an encoding file must have extension .enc; < and << also
- request different font subsetting behaviors but we ignore that; < can
- be separated from the filename by whitespace).
-
- special, fontfile, and encodingfile can appear in any order.
- """
- # If the map file specifies multiple encodings for a font, we
- # follow pdfTeX in choosing the last one specified. Such
- # entries are probably mistakes but they have occurred.
- # https://tex.stackexchange.com/q/10826/
-
- if not line or line.startswith((b" ", b"%", b"*", b";", b"#")):
- return
- tfmname = basename = special = encodingfile = fontfile = None
- is_subsetted = is_t1 = is_truetype = False
- matches = re.finditer(br'"([^"]*)(?:"|$)|(\S+)', line)
- for match in matches:
- quoted, unquoted = match.groups()
- if unquoted:
- if unquoted.startswith(b"<<"): # font
- fontfile = unquoted[2:]
- elif unquoted.startswith(b"<["): # encoding
- encodingfile = unquoted[2:]
- elif unquoted.startswith(b"<"): # font or encoding
- word = (
- # <foo => foo
- unquoted[1:]
- # < by itself => read the next word
- or next(filter(None, next(matches).groups())))
- if word.endswith(b".enc"):
- encodingfile = word
- else:
- fontfile = word
- is_subsetted = True
- elif tfmname is None:
- tfmname = unquoted
- elif basename is None:
- basename = unquoted
- elif quoted:
- special = quoted
- effects = {}
- if special:
- words = reversed(special.split())
- for word in words:
- if word == b"SlantFont":
- effects["slant"] = float(next(words))
- elif word == b"ExtendFont":
- effects["extend"] = float(next(words))
-
- # Verify some properties of the line that would cause it to be ignored
- # otherwise.
- if fontfile is not None:
- if fontfile.endswith((b".ttf", b".ttc")):
- is_truetype = True
- elif not fontfile.endswith(b".otf"):
- is_t1 = True
- elif basename is not None:
- is_t1 = True
- if is_truetype and is_subsetted and encodingfile is None:
- return
- if not is_t1 and ("slant" in effects or "extend" in effects):
- return
- if abs(effects.get("slant", 0)) > 1:
- return
- if abs(effects.get("extend", 0)) > 2:
- return
-
- if basename is None:
- basename = tfmname
- if encodingfile is not None:
- encodingfile = find_tex_file(encodingfile)
- if fontfile is not None:
- fontfile = find_tex_file(fontfile)
- self._parsed[tfmname] = PsFont(
- texname=tfmname, psname=basename, effects=effects,
- encoding=encodingfile, filename=fontfile)
- return True
-
-
-def _parse_enc(path):
- r"""
- Parse a \*.enc file referenced from a psfonts.map style file.
-
- The format supported by this function is a tiny subset of PostScript.
-
- Parameters
- ----------
- path : `os.PathLike`
-
- Returns
- -------
- list
- The nth entry of the list is the PostScript glyph name of the nth
- glyph.
- """
- no_comments = re.sub("%.*", "", Path(path).read_text(encoding="ascii"))
- array = re.search(r"(?s)\[(.*)\]", no_comments).group(1)
- lines = [line for line in array.split() if line]
- if all(line.startswith("/") for line in lines):
- return [line[1:] for line in lines]
- else:
- raise ValueError(f"Failed to parse {path} as Postscript encoding")
-
-
-class _LuatexKpsewhich:
- @lru_cache # A singleton.
- def __new__(cls):
- self = object.__new__(cls)
- self._proc = self._new_proc()
- return self
-
- def _new_proc(self):
- return subprocess.Popen(
- ["luatex", "--luaonly",
- str(cbook._get_data_path("kpsewhich.lua"))],
- stdin=subprocess.PIPE, stdout=subprocess.PIPE)
-
- def search(self, filename):
- if self._proc.poll() is not None: # Dead, restart it.
- self._proc = self._new_proc()
- self._proc.stdin.write(os.fsencode(filename) + b"\n")
- self._proc.stdin.flush()
- out = self._proc.stdout.readline().rstrip()
- return None if out == b"nil" else os.fsdecode(out)
-
-
-@lru_cache
-def find_tex_file(filename):
- """
- Find a file in the texmf tree using kpathsea_.
-
- The kpathsea library, provided by most existing TeX distributions, both
- on Unix-like systems and on Windows (MikTeX), is invoked via a long-lived
- luatex process if luatex is installed, or via kpsewhich otherwise.
-
- .. _kpathsea: https://www.tug.org/kpathsea/
-
- Parameters
- ----------
- filename : str or path-like
-
- Raises
- ------
- FileNotFoundError
- If the file is not found.
- """
-
- # we expect these to always be ascii encoded, but use utf-8
- # out of caution
- if isinstance(filename, bytes):
- filename = filename.decode('utf-8', errors='replace')
-
- try:
- lk = _LuatexKpsewhich()
- except FileNotFoundError:
- lk = None # Fallback to directly calling kpsewhich, as below.
-
- if lk:
- path = lk.search(filename)
- else:
- if sys.platform == 'win32':
- # On Windows only, kpathsea can use utf-8 for cmd args and output.
- # The `command_line_encoding` environment variable is set to force
- # it to always use utf-8 encoding. See Matplotlib issue #11848.
- kwargs = {'env': {**os.environ, 'command_line_encoding': 'utf-8'},
- 'encoding': 'utf-8'}
- else: # On POSIX, run through the equivalent of os.fsdecode().
- kwargs = {'encoding': sys.getfilesystemencoding(),
- 'errors': 'surrogateescape'}
-
- try:
- path = (cbook._check_and_log_subprocess(['kpsewhich', filename],
- _log, **kwargs)
- .rstrip('\n'))
- except (FileNotFoundError, RuntimeError):
- path = None
-
- if path:
- return path
- else:
- raise FileNotFoundError(
- f"Matplotlib's TeX implementation searched for a file named "
- f"{filename!r} in your texmf tree, but could not find it")
-
-
-@lru_cache
-def _fontfile(cls, suffix, texname):
- return cls(find_tex_file(texname + suffix))
-
-
-_tfmfile = partial(_fontfile, Tfm, ".tfm")
-_vffile = partial(_fontfile, Vf, ".vf")
-
-
-if __name__ == '__main__':
- from argparse import ArgumentParser
- import itertools
-
- parser = ArgumentParser()
- parser.add_argument("filename")
- parser.add_argument("dpi", nargs="?", type=float, default=None)
- args = parser.parse_args()
- with Dvi(args.filename, args.dpi) as dvi:
- fontmap = PsfontsMap(find_tex_file('pdftex.map'))
- for page in dvi:
- print(f"=== new page === "
- f"(w: {page.width}, h: {page.height}, d: {page.descent})")
- for font, group in itertools.groupby(
- page.text, lambda text: text.font):
- print(f"font: {font.texname.decode('latin-1')!r}\t"
- f"scale: {font._scale / 2 ** 20}")
- print("x", "y", "glyph", "chr", "w", "(glyphs)", sep="\t")
- for text in group:
- print(text.x, text.y, text.glyph,
- chr(text.glyph) if chr(text.glyph).isprintable()
- else ".",
- text.width, sep="\t")
- if page.boxes:
- print("x", "y", "h", "w", "", "(boxes)", sep="\t")
- for box in page.boxes:
- print(box.x, box.y, box.height, box.width, sep="\t")
diff --git a/contrib/python/matplotlib/py3/matplotlib/dviread.pyi b/contrib/python/matplotlib/py3/matplotlib/dviread.pyi
deleted file mode 100644
index bf5cfcbe31..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/dviread.pyi
+++ /dev/null
@@ -1,90 +0,0 @@
-from pathlib import Path
-import io
-import os
-from enum import Enum
-from collections.abc import Generator
-
-from typing import NamedTuple
-
-class _dvistate(Enum):
- pre: int
- outer: int
- inpage: int
- post_post: int
- finale: int
-
-class Page(NamedTuple):
- text: list[Text]
- boxes: list[Box]
- height: int
- width: int
- descent: int
-
-class Box(NamedTuple):
- x: int
- y: int
- height: int
- width: int
-
-class Text(NamedTuple):
- x: int
- y: int
- font: DviFont
- glyph: int
- width: int
- @property
- def font_path(self) -> Path: ...
- @property
- def font_size(self) -> float: ...
- @property
- def font_effects(self) -> dict[str, float]: ...
- @property
- def glyph_name_or_index(self) -> int | str: ...
-
-class Dvi:
- file: io.BufferedReader
- dpi: float | None
- fonts: dict[int, DviFont]
- state: _dvistate
- def __init__(self, filename: str | os.PathLike, dpi: float | None) -> None: ...
- # Replace return with Self when py3.9 is dropped
- def __enter__(self) -> Dvi: ...
- def __exit__(self, etype, evalue, etrace) -> None: ...
- def __iter__(self) -> Generator[Page, None, None]: ...
- def close(self) -> None: ...
-
-class DviFont:
- texname: bytes
- size: float
- widths: list[int]
- def __init__(
- self, scale: float, tfm: Tfm, texname: bytes, vf: Vf | None
- ) -> None: ...
- def __eq__(self, other: object) -> bool: ...
- def __ne__(self, other: object) -> bool: ...
-
-class Vf(Dvi):
- def __init__(self, filename: str | os.PathLike) -> None: ...
- def __getitem__(self, code: int) -> Page: ...
-
-class Tfm:
- checksum: int
- design_size: int
- width: dict[int, int]
- height: dict[int, int]
- depth: dict[int, int]
- def __init__(self, filename: str | os.PathLike) -> None: ...
-
-class PsFont(NamedTuple):
- texname: bytes
- psname: bytes
- effects: dict[str, float]
- encoding: None | bytes
- filename: str
-
-class PsfontsMap:
- # Replace return with Self when py3.9 is dropped
- def __new__(cls, filename: str | os.PathLike) -> PsfontsMap: ...
- def __getitem__(self, texname: bytes) -> PsFont: ...
-
-def find_tex_file(filename: str | os.PathLike) -> str: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/figure.py b/contrib/python/matplotlib/py3/matplotlib/figure.py
deleted file mode 100644
index e8a5f154d5..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/figure.py
+++ /dev/null
@@ -1,3626 +0,0 @@
-"""
-`matplotlib.figure` implements the following classes:
-
-`Figure`
- Top level `~matplotlib.artist.Artist`, which holds all plot elements.
- Many methods are implemented in `FigureBase`.
-
-`SubFigure`
- A logical figure inside a figure, usually added to a figure (or parent
- `SubFigure`) with `Figure.add_subfigure` or `Figure.subfigures` methods
- (provisional API v3.4).
-
-`SubplotParams`
- Control the default spacing between subplots.
-
-Figures are typically created using pyplot methods `~.pyplot.figure`,
-`~.pyplot.subplots`, and `~.pyplot.subplot_mosaic`.
-
-.. plot::
- :include-source:
-
- fig, ax = plt.subplots(figsize=(2, 2), facecolor='lightskyblue',
- layout='constrained')
- fig.suptitle('Figure')
- ax.set_title('Axes', loc='left', fontstyle='oblique', fontsize='medium')
-
-Some situations call for directly instantiating a `~.figure.Figure` class,
-usually inside an application of some sort (see :ref:`user_interfaces` for a
-list of examples) . More information about Figures can be found at
-:ref:`figure-intro`.
-"""
-
-from contextlib import ExitStack
-import inspect
-import itertools
-import logging
-from numbers import Integral
-import threading
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _blocking_input, backend_bases, _docstring, projections
-from matplotlib.artist import (
- Artist, allow_rasterization, _finalize_rasterization)
-from matplotlib.backend_bases import (
- DrawEvent, FigureCanvasBase, NonGuiException, MouseButton, _get_renderer)
-import matplotlib._api as _api
-import matplotlib.cbook as cbook
-import matplotlib.colorbar as cbar
-import matplotlib.image as mimage
-
-from matplotlib.axes import Axes
-from matplotlib.gridspec import GridSpec
-from matplotlib.layout_engine import (
- ConstrainedLayoutEngine, TightLayoutEngine, LayoutEngine,
- PlaceHolderLayoutEngine
-)
-import matplotlib.legend as mlegend
-from matplotlib.patches import Rectangle
-from matplotlib.text import Text
-from matplotlib.transforms import (Affine2D, Bbox, BboxTransformTo,
- TransformedBbox)
-
-_log = logging.getLogger(__name__)
-
-
-def _stale_figure_callback(self, val):
- if self.figure:
- self.figure.stale = val
-
-
-class _AxesStack:
- """
- Helper class to track axes in a figure.
-
- Axes are tracked both in the order in which they have been added
- (``self._axes`` insertion/iteration order) and in the separate "gca" stack
- (which is the index to which they map in the ``self._axes`` dict).
- """
-
- def __init__(self):
- self._axes = {} # Mapping of axes to "gca" order.
- self._counter = itertools.count()
-
- def as_list(self):
- """List the axes that have been added to the figure."""
- return [*self._axes] # This relies on dict preserving order.
-
- def remove(self, a):
- """Remove the axes from the stack."""
- self._axes.pop(a)
-
- def bubble(self, a):
- """Move an axes, which must already exist in the stack, to the top."""
- if a not in self._axes:
- raise ValueError("Axes has not been added yet")
- self._axes[a] = next(self._counter)
-
- def add(self, a):
- """Add an axes to the stack, ignoring it if already present."""
- if a not in self._axes:
- self._axes[a] = next(self._counter)
-
- def current(self):
- """Return the active axes, or None if the stack is empty."""
- return max(self._axes, key=self._axes.__getitem__, default=None)
-
- def __getstate__(self):
- return {
- **vars(self),
- "_counter": max(self._axes.values(), default=0)
- }
-
- def __setstate__(self, state):
- next_counter = state.pop('_counter')
- vars(self).update(state)
- self._counter = itertools.count(next_counter)
-
-
-class SubplotParams:
- """
- A class to hold the parameters for a subplot.
- """
-
- def __init__(self, left=None, bottom=None, right=None, top=None,
- wspace=None, hspace=None):
- """
- Defaults are given by :rc:`figure.subplot.[name]`.
-
- Parameters
- ----------
- left : float
- The position of the left edge of the subplots,
- as a fraction of the figure width.
- right : float
- The position of the right edge of the subplots,
- as a fraction of the figure width.
- bottom : float
- The position of the bottom edge of the subplots,
- as a fraction of the figure height.
- top : float
- The position of the top edge of the subplots,
- as a fraction of the figure height.
- wspace : float
- The width of the padding between subplots,
- as a fraction of the average Axes width.
- hspace : float
- The height of the padding between subplots,
- as a fraction of the average Axes height.
- """
- for key in ["left", "bottom", "right", "top", "wspace", "hspace"]:
- setattr(self, key, mpl.rcParams[f"figure.subplot.{key}"])
- self.update(left, bottom, right, top, wspace, hspace)
-
- def update(self, left=None, bottom=None, right=None, top=None,
- wspace=None, hspace=None):
- """
- Update the dimensions of the passed parameters. *None* means unchanged.
- """
- if ((left if left is not None else self.left)
- >= (right if right is not None else self.right)):
- raise ValueError('left cannot be >= right')
- if ((bottom if bottom is not None else self.bottom)
- >= (top if top is not None else self.top)):
- raise ValueError('bottom cannot be >= top')
- if left is not None:
- self.left = left
- if right is not None:
- self.right = right
- if bottom is not None:
- self.bottom = bottom
- if top is not None:
- self.top = top
- if wspace is not None:
- self.wspace = wspace
- if hspace is not None:
- self.hspace = hspace
-
-
-class FigureBase(Artist):
- """
- Base class for `.Figure` and `.SubFigure` containing the methods that add
- artists to the figure or subfigure, create Axes, etc.
- """
- def __init__(self, **kwargs):
- super().__init__()
- # remove the non-figure artist _axes property
- # as it makes no sense for a figure to be _in_ an Axes
- # this is used by the property methods in the artist base class
- # which are over-ridden in this class
- del self._axes
-
- self._suptitle = None
- self._supxlabel = None
- self._supylabel = None
-
- # groupers to keep track of x and y labels we want to align.
- # see self.align_xlabels and self.align_ylabels and
- # axis._get_tick_boxes_siblings
- self._align_label_groups = {"x": cbook.Grouper(), "y": cbook.Grouper()}
-
- self._localaxes = [] # track all axes
- self.artists = []
- self.lines = []
- self.patches = []
- self.texts = []
- self.images = []
- self.legends = []
- self.subfigs = []
- self.stale = True
- self.suppressComposite = None
- self.set(**kwargs)
-
- def _get_draw_artists(self, renderer):
- """Also runs apply_aspect"""
- artists = self.get_children()
- for sfig in self.subfigs:
- artists.remove(sfig)
- childa = sfig.get_children()
- for child in childa:
- if child in artists:
- artists.remove(child)
-
- artists.remove(self.patch)
- artists = sorted(
- (artist for artist in artists if not artist.get_animated()),
- key=lambda artist: artist.get_zorder())
- for ax in self._localaxes:
- locator = ax.get_axes_locator()
- ax.apply_aspect(locator(ax, renderer) if locator else None)
-
- for child in ax.get_children():
- if hasattr(child, 'apply_aspect'):
- locator = child.get_axes_locator()
- child.apply_aspect(
- locator(child, renderer) if locator else None)
- return artists
-
- def autofmt_xdate(
- self, bottom=0.2, rotation=30, ha='right', which='major'):
- """
- Date ticklabels often overlap, so it is useful to rotate them
- and right align them. Also, a common use case is a number of
- subplots with shared x-axis where the x-axis is date data. The
- ticklabels are often long, and it helps to rotate them on the
- bottom subplot and turn them off on other subplots, as well as
- turn off xlabels.
-
- Parameters
- ----------
- bottom : float, default: 0.2
- The bottom of the subplots for `subplots_adjust`.
- rotation : float, default: 30 degrees
- The rotation angle of the xtick labels in degrees.
- ha : {'left', 'center', 'right'}, default: 'right'
- The horizontal alignment of the xticklabels.
- which : {'major', 'minor', 'both'}, default: 'major'
- Selects which ticklabels to rotate.
- """
- _api.check_in_list(['major', 'minor', 'both'], which=which)
- allsubplots = all(ax.get_subplotspec() for ax in self.axes)
- if len(self.axes) == 1:
- for label in self.axes[0].get_xticklabels(which=which):
- label.set_ha(ha)
- label.set_rotation(rotation)
- else:
- if allsubplots:
- for ax in self.get_axes():
- if ax.get_subplotspec().is_last_row():
- for label in ax.get_xticklabels(which=which):
- label.set_ha(ha)
- label.set_rotation(rotation)
- else:
- for label in ax.get_xticklabels(which=which):
- label.set_visible(False)
- ax.set_xlabel('')
-
- if allsubplots:
- self.subplots_adjust(bottom=bottom)
- self.stale = True
-
- def get_children(self):
- """Get a list of artists contained in the figure."""
- return [self.patch,
- *self.artists,
- *self._localaxes,
- *self.lines,
- *self.patches,
- *self.texts,
- *self.images,
- *self.legends,
- *self.subfigs]
-
- def contains(self, mouseevent):
- """
- Test whether the mouse event occurred on the figure.
-
- Returns
- -------
- bool, {}
- """
- if self._different_canvas(mouseevent):
- return False, {}
- inside = self.bbox.contains(mouseevent.x, mouseevent.y)
- return inside, {}
-
- def get_window_extent(self, renderer=None):
- # docstring inherited
- return self.bbox
-
- def _suplabels(self, t, info, **kwargs):
- """
- Add a centered %(name)s to the figure.
-
- Parameters
- ----------
- t : str
- The %(name)s text.
- x : float, default: %(x0)s
- The x location of the text in figure coordinates.
- y : float, default: %(y0)s
- The y location of the text in figure coordinates.
- horizontalalignment, ha : {'center', 'left', 'right'}, default: %(ha)s
- The horizontal alignment of the text relative to (*x*, *y*).
- verticalalignment, va : {'top', 'center', 'bottom', 'baseline'}, \
-default: %(va)s
- The vertical alignment of the text relative to (*x*, *y*).
- fontsize, size : default: :rc:`figure.%(rc)ssize`
- The font size of the text. See `.Text.set_size` for possible
- values.
- fontweight, weight : default: :rc:`figure.%(rc)sweight`
- The font weight of the text. See `.Text.set_weight` for possible
- values.
-
- Returns
- -------
- text
- The `.Text` instance of the %(name)s.
-
- Other Parameters
- ----------------
- fontproperties : None or dict, optional
- A dict of font properties. If *fontproperties* is given the
- default values for font size and weight are taken from the
- `.FontProperties` defaults. :rc:`figure.%(rc)ssize` and
- :rc:`figure.%(rc)sweight` are ignored in this case.
-
- **kwargs
- Additional kwargs are `matplotlib.text.Text` properties.
- """
-
- suplab = getattr(self, info['name'])
-
- x = kwargs.pop('x', None)
- y = kwargs.pop('y', None)
- if info['name'] in ['_supxlabel', '_suptitle']:
- autopos = y is None
- elif info['name'] == '_supylabel':
- autopos = x is None
- if x is None:
- x = info['x0']
- if y is None:
- y = info['y0']
-
- if 'horizontalalignment' not in kwargs and 'ha' not in kwargs:
- kwargs['horizontalalignment'] = info['ha']
- if 'verticalalignment' not in kwargs and 'va' not in kwargs:
- kwargs['verticalalignment'] = info['va']
- if 'rotation' not in kwargs:
- kwargs['rotation'] = info['rotation']
-
- if 'fontproperties' not in kwargs:
- if 'fontsize' not in kwargs and 'size' not in kwargs:
- kwargs['size'] = mpl.rcParams[info['size']]
- if 'fontweight' not in kwargs and 'weight' not in kwargs:
- kwargs['weight'] = mpl.rcParams[info['weight']]
-
- sup = self.text(x, y, t, **kwargs)
- if suplab is not None:
- suplab.set_text(t)
- suplab.set_position((x, y))
- suplab.update_from(sup)
- sup.remove()
- else:
- suplab = sup
- suplab._autopos = autopos
- setattr(self, info['name'], suplab)
- self.stale = True
- return suplab
-
- @_docstring.Substitution(x0=0.5, y0=0.98, name='suptitle', ha='center',
- va='top', rc='title')
- @_docstring.copy(_suplabels)
- def suptitle(self, t, **kwargs):
- # docstring from _suplabels...
- info = {'name': '_suptitle', 'x0': 0.5, 'y0': 0.98,
- 'ha': 'center', 'va': 'top', 'rotation': 0,
- 'size': 'figure.titlesize', 'weight': 'figure.titleweight'}
- return self._suplabels(t, info, **kwargs)
-
- def get_suptitle(self):
- """Return the suptitle as string or an empty string if not set."""
- text_obj = self._suptitle
- return "" if text_obj is None else text_obj.get_text()
-
- @_docstring.Substitution(x0=0.5, y0=0.01, name='supxlabel', ha='center',
- va='bottom', rc='label')
- @_docstring.copy(_suplabels)
- def supxlabel(self, t, **kwargs):
- # docstring from _suplabels...
- info = {'name': '_supxlabel', 'x0': 0.5, 'y0': 0.01,
- 'ha': 'center', 'va': 'bottom', 'rotation': 0,
- 'size': 'figure.labelsize', 'weight': 'figure.labelweight'}
- return self._suplabels(t, info, **kwargs)
-
- def get_supxlabel(self):
- """Return the supxlabel as string or an empty string if not set."""
- text_obj = self._supxlabel
- return "" if text_obj is None else text_obj.get_text()
-
- @_docstring.Substitution(x0=0.02, y0=0.5, name='supylabel', ha='left',
- va='center', rc='label')
- @_docstring.copy(_suplabels)
- def supylabel(self, t, **kwargs):
- # docstring from _suplabels...
- info = {'name': '_supylabel', 'x0': 0.02, 'y0': 0.5,
- 'ha': 'left', 'va': 'center', 'rotation': 'vertical',
- 'rotation_mode': 'anchor', 'size': 'figure.labelsize',
- 'weight': 'figure.labelweight'}
- return self._suplabels(t, info, **kwargs)
-
- def get_supylabel(self):
- """Return the supylabel as string or an empty string if not set."""
- text_obj = self._supylabel
- return "" if text_obj is None else text_obj.get_text()
-
- def get_edgecolor(self):
- """Get the edge color of the Figure rectangle."""
- return self.patch.get_edgecolor()
-
- def get_facecolor(self):
- """Get the face color of the Figure rectangle."""
- return self.patch.get_facecolor()
-
- def get_frameon(self):
- """
- Return the figure's background patch visibility, i.e.
- whether the figure background will be drawn. Equivalent to
- ``Figure.patch.get_visible()``.
- """
- return self.patch.get_visible()
-
- def set_linewidth(self, linewidth):
- """
- Set the line width of the Figure rectangle.
-
- Parameters
- ----------
- linewidth : number
- """
- self.patch.set_linewidth(linewidth)
-
- def get_linewidth(self):
- """
- Get the line width of the Figure rectangle.
- """
- return self.patch.get_linewidth()
-
- def set_edgecolor(self, color):
- """
- Set the edge color of the Figure rectangle.
-
- Parameters
- ----------
- color : color
- """
- self.patch.set_edgecolor(color)
-
- def set_facecolor(self, color):
- """
- Set the face color of the Figure rectangle.
-
- Parameters
- ----------
- color : color
- """
- self.patch.set_facecolor(color)
-
- def set_frameon(self, b):
- """
- Set the figure's background patch visibility, i.e.
- whether the figure background will be drawn. Equivalent to
- ``Figure.patch.set_visible()``.
-
- Parameters
- ----------
- b : bool
- """
- self.patch.set_visible(b)
- self.stale = True
-
- frameon = property(get_frameon, set_frameon)
-
- def add_artist(self, artist, clip=False):
- """
- Add an `.Artist` to the figure.
-
- Usually artists are added to `~.axes.Axes` objects using
- `.Axes.add_artist`; this method can be used in the rare cases where
- one needs to add artists directly to the figure instead.
-
- Parameters
- ----------
- artist : `~matplotlib.artist.Artist`
- The artist to add to the figure. If the added artist has no
- transform previously set, its transform will be set to
- ``figure.transSubfigure``.
- clip : bool, default: False
- Whether the added artist should be clipped by the figure patch.
-
- Returns
- -------
- `~matplotlib.artist.Artist`
- The added artist.
- """
- artist.set_figure(self)
- self.artists.append(artist)
- artist._remove_method = self.artists.remove
-
- if not artist.is_transform_set():
- artist.set_transform(self.transSubfigure)
-
- if clip and artist.get_clip_path() is None:
- artist.set_clip_path(self.patch)
-
- self.stale = True
- return artist
-
- @_docstring.dedent_interpd
- def add_axes(self, *args, **kwargs):
- """
- Add an `~.axes.Axes` to the figure.
-
- Call signatures::
-
- add_axes(rect, projection=None, polar=False, **kwargs)
- add_axes(ax)
-
- Parameters
- ----------
- rect : tuple (left, bottom, width, height)
- The dimensions (left, bottom, width, height) of the new
- `~.axes.Axes`. All quantities are in fractions of figure width and
- height.
-
- projection : {None, 'aitoff', 'hammer', 'lambert', 'mollweide', \
-'polar', 'rectilinear', str}, optional
- The projection type of the `~.axes.Axes`. *str* is the name of
- a custom projection, see `~matplotlib.projections`. The default
- None results in a 'rectilinear' projection.
-
- polar : bool, default: False
- If True, equivalent to projection='polar'.
-
- axes_class : subclass type of `~.axes.Axes`, optional
- The `.axes.Axes` subclass that is instantiated. This parameter
- is incompatible with *projection* and *polar*. See
- :ref:`axisartist_users-guide-index` for examples.
-
- sharex, sharey : `~matplotlib.axes.Axes`, optional
- Share the x or y `~matplotlib.axis` with sharex and/or sharey.
- The axis will have the same limits, ticks, and scale as the axis
- of the shared axes.
-
- label : str
- A label for the returned Axes.
-
- Returns
- -------
- `~.axes.Axes`, or a subclass of `~.axes.Axes`
- The returned axes class depends on the projection used. It is
- `~.axes.Axes` if rectilinear projection is used and
- `.projections.polar.PolarAxes` if polar projection is used.
-
- Other Parameters
- ----------------
- **kwargs
- This method also takes the keyword arguments for
- the returned Axes class. The keyword arguments for the
- rectilinear Axes class `~.axes.Axes` can be found in
- the following table but there might also be other keyword
- arguments if another projection is used, see the actual Axes
- class.
-
- %(Axes:kwdoc)s
-
- Notes
- -----
- In rare circumstances, `.add_axes` may be called with a single
- argument, an Axes instance already created in the present figure but
- not in the figure's list of Axes.
-
- See Also
- --------
- .Figure.add_subplot
- .pyplot.subplot
- .pyplot.axes
- .Figure.subplots
- .pyplot.subplots
-
- Examples
- --------
- Some simple examples::
-
- rect = l, b, w, h
- fig = plt.figure()
- fig.add_axes(rect)
- fig.add_axes(rect, frameon=False, facecolor='g')
- fig.add_axes(rect, polar=True)
- ax = fig.add_axes(rect, projection='polar')
- fig.delaxes(ax)
- fig.add_axes(ax)
- """
-
- if not len(args) and 'rect' not in kwargs:
- raise TypeError(
- "add_axes() missing 1 required positional argument: 'rect'")
- elif 'rect' in kwargs:
- if len(args):
- raise TypeError(
- "add_axes() got multiple values for argument 'rect'")
- args = (kwargs.pop('rect'), )
-
- if isinstance(args[0], Axes):
- a, *extra_args = args
- key = a._projection_init
- if a.get_figure() is not self:
- raise ValueError(
- "The Axes must have been created in the present figure")
- else:
- rect, *extra_args = args
- if not np.isfinite(rect).all():
- raise ValueError(f'all entries in rect must be finite not {rect}')
- projection_class, pkw = self._process_projection_requirements(**kwargs)
-
- # create the new axes using the axes class given
- a = projection_class(self, rect, **pkw)
- key = (projection_class, pkw)
-
- if extra_args:
- _api.warn_deprecated(
- "3.8",
- name="Passing more than one positional argument to Figure.add_axes",
- addendum="Any additional positional arguments are currently ignored.")
- return self._add_axes_internal(a, key)
-
- @_docstring.dedent_interpd
- def add_subplot(self, *args, **kwargs):
- """
- Add an `~.axes.Axes` to the figure as part of a subplot arrangement.
-
- Call signatures::
-
- add_subplot(nrows, ncols, index, **kwargs)
- add_subplot(pos, **kwargs)
- add_subplot(ax)
- add_subplot()
-
- Parameters
- ----------
- *args : int, (int, int, *index*), or `.SubplotSpec`, default: (1, 1, 1)
- The position of the subplot described by one of
-
- - Three integers (*nrows*, *ncols*, *index*). The subplot will
- take the *index* position on a grid with *nrows* rows and
- *ncols* columns. *index* starts at 1 in the upper left corner
- and increases to the right. *index* can also be a two-tuple
- specifying the (*first*, *last*) indices (1-based, and including
- *last*) of the subplot, e.g., ``fig.add_subplot(3, 1, (1, 2))``
- makes a subplot that spans the upper 2/3 of the figure.
- - A 3-digit integer. The digits are interpreted as if given
- separately as three single-digit integers, i.e.
- ``fig.add_subplot(235)`` is the same as
- ``fig.add_subplot(2, 3, 5)``. Note that this can only be used
- if there are no more than 9 subplots.
- - A `.SubplotSpec`.
-
- In rare circumstances, `.add_subplot` may be called with a single
- argument, a subplot Axes instance already created in the
- present figure but not in the figure's list of Axes.
-
- projection : {None, 'aitoff', 'hammer', 'lambert', 'mollweide', \
-'polar', 'rectilinear', str}, optional
- The projection type of the subplot (`~.axes.Axes`). *str* is the
- name of a custom projection, see `~matplotlib.projections`. The
- default None results in a 'rectilinear' projection.
-
- polar : bool, default: False
- If True, equivalent to projection='polar'.
-
- axes_class : subclass type of `~.axes.Axes`, optional
- The `.axes.Axes` subclass that is instantiated. This parameter
- is incompatible with *projection* and *polar*. See
- :ref:`axisartist_users-guide-index` for examples.
-
- sharex, sharey : `~matplotlib.axes.Axes`, optional
- Share the x or y `~matplotlib.axis` with sharex and/or sharey.
- The axis will have the same limits, ticks, and scale as the axis
- of the shared axes.
-
- label : str
- A label for the returned Axes.
-
- Returns
- -------
- `~.axes.Axes`
-
- The Axes of the subplot. The returned Axes can actually be an
- instance of a subclass, such as `.projections.polar.PolarAxes` for
- polar projections.
-
- Other Parameters
- ----------------
- **kwargs
- This method also takes the keyword arguments for the returned Axes
- base class; except for the *figure* argument. The keyword arguments
- for the rectilinear base class `~.axes.Axes` can be found in
- the following table but there might also be other keyword
- arguments if another projection is used.
-
- %(Axes:kwdoc)s
-
- See Also
- --------
- .Figure.add_axes
- .pyplot.subplot
- .pyplot.axes
- .Figure.subplots
- .pyplot.subplots
-
- Examples
- --------
- ::
-
- fig = plt.figure()
-
- fig.add_subplot(231)
- ax1 = fig.add_subplot(2, 3, 1) # equivalent but more general
-
- fig.add_subplot(232, frameon=False) # subplot with no frame
- fig.add_subplot(233, projection='polar') # polar subplot
- fig.add_subplot(234, sharex=ax1) # subplot sharing x-axis with ax1
- fig.add_subplot(235, facecolor="red") # red subplot
-
- ax1.remove() # delete ax1 from the figure
- fig.add_subplot(ax1) # add ax1 back to the figure
- """
- if 'figure' in kwargs:
- # Axes itself allows for a 'figure' kwarg, but since we want to
- # bind the created Axes to self, it is not allowed here.
- raise _api.kwarg_error("add_subplot", "figure")
-
- if (len(args) == 1
- and isinstance(args[0], mpl.axes._base._AxesBase)
- and args[0].get_subplotspec()):
- ax = args[0]
- key = ax._projection_init
- if ax.get_figure() is not self:
- raise ValueError("The Axes must have been created in "
- "the present figure")
- else:
- if not args:
- args = (1, 1, 1)
- # Normalize correct ijk values to (i, j, k) here so that
- # add_subplot(211) == add_subplot(2, 1, 1). Invalid values will
- # trigger errors later (via SubplotSpec._from_subplot_args).
- if (len(args) == 1 and isinstance(args[0], Integral)
- and 100 <= args[0] <= 999):
- args = tuple(map(int, str(args[0])))
- projection_class, pkw = self._process_projection_requirements(**kwargs)
- ax = projection_class(self, *args, **pkw)
- key = (projection_class, pkw)
- return self._add_axes_internal(ax, key)
-
- def _add_axes_internal(self, ax, key):
- """Private helper for `add_axes` and `add_subplot`."""
- self._axstack.add(ax)
- if ax not in self._localaxes:
- self._localaxes.append(ax)
- self.sca(ax)
- ax._remove_method = self.delaxes
- # this is to support plt.subplot's re-selection logic
- ax._projection_init = key
- self.stale = True
- ax.stale_callback = _stale_figure_callback
- return ax
-
- def subplots(self, nrows=1, ncols=1, *, sharex=False, sharey=False,
- squeeze=True, width_ratios=None, height_ratios=None,
- subplot_kw=None, gridspec_kw=None):
- """
- Add a set of subplots to this figure.
-
- This utility wrapper makes it convenient to create common layouts of
- subplots in a single call.
-
- Parameters
- ----------
- nrows, ncols : int, default: 1
- Number of rows/columns of the subplot grid.
-
- sharex, sharey : bool or {'none', 'all', 'row', 'col'}, default: False
- Controls sharing of x-axis (*sharex*) or y-axis (*sharey*):
-
- - True or 'all': x- or y-axis will be shared among all subplots.
- - False or 'none': each subplot x- or y-axis will be independent.
- - 'row': each subplot row will share an x- or y-axis.
- - 'col': each subplot column will share an x- or y-axis.
-
- When subplots have a shared x-axis along a column, only the x tick
- labels of the bottom subplot are created. Similarly, when subplots
- have a shared y-axis along a row, only the y tick labels of the
- first column subplot are created. To later turn other subplots'
- ticklabels on, use `~matplotlib.axes.Axes.tick_params`.
-
- When subplots have a shared axis that has units, calling
- `.Axis.set_units` will update each axis with the new units.
-
- squeeze : bool, default: True
- - If True, extra dimensions are squeezed out from the returned
- array of Axes:
-
- - if only one subplot is constructed (nrows=ncols=1), the
- resulting single Axes object is returned as a scalar.
- - for Nx1 or 1xM subplots, the returned object is a 1D numpy
- object array of Axes objects.
- - for NxM, subplots with N>1 and M>1 are returned as a 2D array.
-
- - If False, no squeezing at all is done: the returned Axes object
- is always a 2D array containing Axes instances, even if it ends
- up being 1x1.
-
- width_ratios : array-like of length *ncols*, optional
- Defines the relative widths of the columns. Each column gets a
- relative width of ``width_ratios[i] / sum(width_ratios)``.
- If not given, all columns will have the same width. Equivalent
- to ``gridspec_kw={'width_ratios': [...]}``.
-
- height_ratios : array-like of length *nrows*, optional
- Defines the relative heights of the rows. Each row gets a
- relative height of ``height_ratios[i] / sum(height_ratios)``.
- If not given, all rows will have the same height. Equivalent
- to ``gridspec_kw={'height_ratios': [...]}``.
-
- subplot_kw : dict, optional
- Dict with keywords passed to the `.Figure.add_subplot` call used to
- create each subplot.
-
- gridspec_kw : dict, optional
- Dict with keywords passed to the
- `~matplotlib.gridspec.GridSpec` constructor used to create
- the grid the subplots are placed on.
-
- Returns
- -------
- `~.axes.Axes` or array of Axes
- Either a single `~matplotlib.axes.Axes` object or an array of Axes
- objects if more than one subplot was created. The dimensions of the
- resulting array can be controlled with the *squeeze* keyword, see
- above.
-
- See Also
- --------
- .pyplot.subplots
- .Figure.add_subplot
- .pyplot.subplot
-
- Examples
- --------
- ::
-
- # First create some toy data:
- x = np.linspace(0, 2*np.pi, 400)
- y = np.sin(x**2)
-
- # Create a figure
- fig = plt.figure()
-
- # Create a subplot
- ax = fig.subplots()
- ax.plot(x, y)
- ax.set_title('Simple plot')
-
- # Create two subplots and unpack the output array immediately
- ax1, ax2 = fig.subplots(1, 2, sharey=True)
- ax1.plot(x, y)
- ax1.set_title('Sharing Y axis')
- ax2.scatter(x, y)
-
- # Create four polar Axes and access them through the returned array
- axes = fig.subplots(2, 2, subplot_kw=dict(projection='polar'))
- axes[0, 0].plot(x, y)
- axes[1, 1].scatter(x, y)
-
- # Share an X-axis with each column of subplots
- fig.subplots(2, 2, sharex='col')
-
- # Share a Y-axis with each row of subplots
- fig.subplots(2, 2, sharey='row')
-
- # Share both X- and Y-axes with all subplots
- fig.subplots(2, 2, sharex='all', sharey='all')
-
- # Note that this is the same as
- fig.subplots(2, 2, sharex=True, sharey=True)
- """
- gridspec_kw = dict(gridspec_kw or {})
- if height_ratios is not None:
- if 'height_ratios' in gridspec_kw:
- raise ValueError("'height_ratios' must not be defined both as "
- "parameter and as key in 'gridspec_kw'")
- gridspec_kw['height_ratios'] = height_ratios
- if width_ratios is not None:
- if 'width_ratios' in gridspec_kw:
- raise ValueError("'width_ratios' must not be defined both as "
- "parameter and as key in 'gridspec_kw'")
- gridspec_kw['width_ratios'] = width_ratios
-
- gs = self.add_gridspec(nrows, ncols, figure=self, **gridspec_kw)
- axs = gs.subplots(sharex=sharex, sharey=sharey, squeeze=squeeze,
- subplot_kw=subplot_kw)
- return axs
-
- def delaxes(self, ax):
- """
- Remove the `~.axes.Axes` *ax* from the figure; update the current Axes.
- """
- self._remove_axes(ax, owners=[self._axstack, self._localaxes])
-
- def _remove_axes(self, ax, owners):
- """
- Common helper for removal of standard axes (via delaxes) and of child axes.
-
- Parameters
- ----------
- ax : `~.AxesBase`
- The Axes to remove.
- owners
- List of objects (list or _AxesStack) "owning" the axes, from which the Axes
- will be remove()d.
- """
- for owner in owners:
- owner.remove(ax)
-
- self._axobservers.process("_axes_change_event", self)
- self.stale = True
- self.canvas.release_mouse(ax)
-
- for name in ax._axis_names: # Break link between any shared axes
- grouper = ax._shared_axes[name]
- siblings = [other for other in grouper.get_siblings(ax) if other is not ax]
- if not siblings: # Axes was not shared along this axis; we're done.
- continue
- grouper.remove(ax)
- # Formatters and locators may previously have been associated with the now
- # removed axis. Update them to point to an axis still there (we can pick
- # any of them, and use the first sibling).
- remaining_axis = siblings[0]._axis_map[name]
- remaining_axis.get_major_formatter().set_axis(remaining_axis)
- remaining_axis.get_major_locator().set_axis(remaining_axis)
- remaining_axis.get_minor_formatter().set_axis(remaining_axis)
- remaining_axis.get_minor_locator().set_axis(remaining_axis)
-
- ax._twinned_axes.remove(ax) # Break link between any twinned axes.
-
- def clear(self, keep_observers=False):
- """
- Clear the figure.
-
- Parameters
- ----------
- keep_observers : bool, default: False
- Set *keep_observers* to True if, for example,
- a gui widget is tracking the Axes in the figure.
- """
- self.suppressComposite = None
-
- # first clear the axes in any subfigures
- for subfig in self.subfigs:
- subfig.clear(keep_observers=keep_observers)
- self.subfigs = []
-
- for ax in tuple(self.axes): # Iterate over the copy.
- ax.clear()
- self.delaxes(ax) # Remove ax from self._axstack.
-
- self.artists = []
- self.lines = []
- self.patches = []
- self.texts = []
- self.images = []
- self.legends = []
- if not keep_observers:
- self._axobservers = cbook.CallbackRegistry()
- self._suptitle = None
- self._supxlabel = None
- self._supylabel = None
-
- self.stale = True
-
- # synonym for `clear`.
- def clf(self, keep_observers=False):
- """
- [*Discouraged*] Alias for the `clear()` method.
-
- .. admonition:: Discouraged
-
- The use of ``clf()`` is discouraged. Use ``clear()`` instead.
-
- Parameters
- ----------
- keep_observers : bool, default: False
- Set *keep_observers* to True if, for example,
- a gui widget is tracking the Axes in the figure.
- """
- return self.clear(keep_observers=keep_observers)
-
- # Note: the docstring below is modified with replace for the pyplot
- # version of this function because the method name differs (plt.figlegend)
- # the replacements are:
- # " legend(" -> " figlegend(" for the signatures
- # "fig.legend(" -> "plt.figlegend" for the code examples
- # "ax.plot" -> "plt.plot" for consistency in using pyplot when able
- @_docstring.dedent_interpd
- def legend(self, *args, **kwargs):
- """
- Place a legend on the figure.
-
- Call signatures::
-
- legend()
- legend(handles, labels)
- legend(handles=handles)
- legend(labels)
-
- The call signatures correspond to the following different ways to use
- this method:
-
- **1. Automatic detection of elements to be shown in the legend**
-
- The elements to be added to the legend are automatically determined,
- when you do not pass in any extra arguments.
-
- In this case, the labels are taken from the artist. You can specify
- them either at artist creation or by calling the
- :meth:`~.Artist.set_label` method on the artist::
-
- ax.plot([1, 2, 3], label='Inline label')
- fig.legend()
-
- or::
-
- line, = ax.plot([1, 2, 3])
- line.set_label('Label via method')
- fig.legend()
-
- Specific lines can be excluded from the automatic legend element
- selection by defining a label starting with an underscore.
- This is default for all artists, so calling `.Figure.legend` without
- any arguments and without setting the labels manually will result in
- no legend being drawn.
-
-
- **2. Explicitly listing the artists and labels in the legend**
-
- For full control of which artists have a legend entry, it is possible
- to pass an iterable of legend artists followed by an iterable of
- legend labels respectively::
-
- fig.legend([line1, line2, line3], ['label1', 'label2', 'label3'])
-
-
- **3. Explicitly listing the artists in the legend**
-
- This is similar to 2, but the labels are taken from the artists'
- label properties. Example::
-
- line1, = ax1.plot([1, 2, 3], label='label1')
- line2, = ax2.plot([1, 2, 3], label='label2')
- fig.legend(handles=[line1, line2])
-
-
- **4. Labeling existing plot elements**
-
- .. admonition:: Discouraged
-
- This call signature is discouraged, because the relation between
- plot elements and labels is only implicit by their order and can
- easily be mixed up.
-
- To make a legend for all artists on all Axes, call this function with
- an iterable of strings, one for each legend item. For example::
-
- fig, (ax1, ax2) = plt.subplots(1, 2)
- ax1.plot([1, 3, 5], color='blue')
- ax2.plot([2, 4, 6], color='red')
- fig.legend(['the blues', 'the reds'])
-
-
- Parameters
- ----------
- handles : list of `.Artist`, optional
- A list of Artists (lines, patches) to be added to the legend.
- Use this together with *labels*, if you need full control on what
- is shown in the legend and the automatic mechanism described above
- is not sufficient.
-
- The length of handles and labels should be the same in this
- case. If they are not, they are truncated to the smaller length.
-
- labels : list of str, optional
- A list of labels to show next to the artists.
- Use this together with *handles*, if you need full control on what
- is shown in the legend and the automatic mechanism described above
- is not sufficient.
-
- Returns
- -------
- `~matplotlib.legend.Legend`
-
- Other Parameters
- ----------------
- %(_legend_kw_figure)s
-
- See Also
- --------
- .Axes.legend
-
- Notes
- -----
- Some artists are not supported by this function. See
- :ref:`legend_guide` for details.
- """
-
- handles, labels, kwargs = mlegend._parse_legend_args(self.axes, *args, **kwargs)
- # explicitly set the bbox transform if the user hasn't.
- kwargs.setdefault("bbox_transform", self.transSubfigure)
- l = mlegend.Legend(self, handles, labels, **kwargs)
- self.legends.append(l)
- l._remove_method = self.legends.remove
- self.stale = True
- return l
-
- @_docstring.dedent_interpd
- def text(self, x, y, s, fontdict=None, **kwargs):
- """
- Add text to figure.
-
- Parameters
- ----------
- x, y : float
- The position to place the text. By default, this is in figure
- coordinates, floats in [0, 1]. The coordinate system can be changed
- using the *transform* keyword.
-
- s : str
- The text string.
-
- fontdict : dict, optional
- A dictionary to override the default text properties. If not given,
- the defaults are determined by :rc:`font.*`. Properties passed as
- *kwargs* override the corresponding ones given in *fontdict*.
-
- Returns
- -------
- `~.text.Text`
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.text.Text` properties
- Other miscellaneous text parameters.
-
- %(Text:kwdoc)s
-
- See Also
- --------
- .Axes.text
- .pyplot.text
- """
- effective_kwargs = {
- 'transform': self.transSubfigure,
- **(fontdict if fontdict is not None else {}),
- **kwargs,
- }
- text = Text(x=x, y=y, text=s, **effective_kwargs)
- text.set_figure(self)
- text.stale_callback = _stale_figure_callback
-
- self.texts.append(text)
- text._remove_method = self.texts.remove
- self.stale = True
- return text
-
- @_docstring.dedent_interpd
- def colorbar(
- self, mappable, cax=None, ax=None, use_gridspec=True, **kwargs):
- """
- Add a colorbar to a plot.
-
- Parameters
- ----------
- mappable
- The `matplotlib.cm.ScalarMappable` (i.e., `.AxesImage`,
- `.ContourSet`, etc.) described by this colorbar. This argument is
- mandatory for the `.Figure.colorbar` method but optional for the
- `.pyplot.colorbar` function, which sets the default to the current
- image.
-
- Note that one can create a `.ScalarMappable` "on-the-fly" to
- generate colorbars not attached to a previously drawn artist, e.g.
- ::
-
- fig.colorbar(cm.ScalarMappable(norm=norm, cmap=cmap), ax=ax)
-
- cax : `~matplotlib.axes.Axes`, optional
- Axes into which the colorbar will be drawn. If `None`, then a new
- Axes is created and the space for it will be stolen from the Axes(s)
- specified in *ax*.
-
- ax : `~matplotlib.axes.Axes` or iterable or `numpy.ndarray` of Axes, optional
- The one or more parent Axes from which space for a new colorbar Axes
- will be stolen. This parameter is only used if *cax* is not set.
-
- Defaults to the Axes that contains the mappable used to create the
- colorbar.
-
- use_gridspec : bool, optional
- If *cax* is ``None``, a new *cax* is created as an instance of
- Axes. If *ax* is positioned with a subplotspec and *use_gridspec*
- is ``True``, then *cax* is also positioned with a subplotspec.
-
- Returns
- -------
- colorbar : `~matplotlib.colorbar.Colorbar`
-
- Other Parameters
- ----------------
- %(_make_axes_kw_doc)s
- %(_colormap_kw_doc)s
-
- Notes
- -----
- If *mappable* is a `~.contour.ContourSet`, its *extend* kwarg is
- included automatically.
-
- The *shrink* kwarg provides a simple way to scale the colorbar with
- respect to the axes. Note that if *cax* is specified, it determines the
- size of the colorbar, and *shrink* and *aspect* are ignored.
-
- For more precise control, you can manually specify the positions of the
- axes objects in which the mappable and the colorbar are drawn. In this
- case, do not use any of the axes properties kwargs.
-
- It is known that some vector graphics viewers (svg and pdf) render
- white gaps between segments of the colorbar. This is due to bugs in
- the viewers, not Matplotlib. As a workaround, the colorbar can be
- rendered with overlapping segments::
-
- cbar = colorbar()
- cbar.solids.set_edgecolor("face")
- draw()
-
- However, this has negative consequences in other circumstances, e.g.
- with semi-transparent images (alpha < 1) and colorbar extensions;
- therefore, this workaround is not used by default (see issue #1188).
-
- """
-
- if ax is None:
- ax = getattr(mappable, "axes", None)
-
- if cax is None:
- if ax is None:
- raise ValueError(
- 'Unable to determine Axes to steal space for Colorbar. '
- 'Either provide the *cax* argument to use as the Axes for '
- 'the Colorbar, provide the *ax* argument to steal space '
- 'from it, or add *mappable* to an Axes.')
- fig = ( # Figure of first axes; logic copied from make_axes.
- [*ax.flat] if isinstance(ax, np.ndarray)
- else [*ax] if np.iterable(ax)
- else [ax])[0].figure
- current_ax = fig.gca()
- if (fig.get_layout_engine() is not None and
- not fig.get_layout_engine().colorbar_gridspec):
- use_gridspec = False
- if (use_gridspec
- and isinstance(ax, mpl.axes._base._AxesBase)
- and ax.get_subplotspec()):
- cax, kwargs = cbar.make_axes_gridspec(ax, **kwargs)
- else:
- cax, kwargs = cbar.make_axes(ax, **kwargs)
- # make_axes calls add_{axes,subplot} which changes gca; undo that.
- fig.sca(current_ax)
- cax.grid(visible=False, which='both', axis='both')
-
- NON_COLORBAR_KEYS = [ # remove kws that cannot be passed to Colorbar
- 'fraction', 'pad', 'shrink', 'aspect', 'anchor', 'panchor']
- cb = cbar.Colorbar(cax, mappable, **{
- k: v for k, v in kwargs.items() if k not in NON_COLORBAR_KEYS})
- cax.figure.stale = True
- return cb
-
- def subplots_adjust(self, left=None, bottom=None, right=None, top=None,
- wspace=None, hspace=None):
- """
- Adjust the subplot layout parameters.
-
- Unset parameters are left unmodified; initial values are given by
- :rc:`figure.subplot.[name]`.
-
- Parameters
- ----------
- left : float, optional
- The position of the left edge of the subplots,
- as a fraction of the figure width.
- right : float, optional
- The position of the right edge of the subplots,
- as a fraction of the figure width.
- bottom : float, optional
- The position of the bottom edge of the subplots,
- as a fraction of the figure height.
- top : float, optional
- The position of the top edge of the subplots,
- as a fraction of the figure height.
- wspace : float, optional
- The width of the padding between subplots,
- as a fraction of the average Axes width.
- hspace : float, optional
- The height of the padding between subplots,
- as a fraction of the average Axes height.
- """
- if (self.get_layout_engine() is not None and
- not self.get_layout_engine().adjust_compatible):
- _api.warn_external(
- "This figure was using a layout engine that is "
- "incompatible with subplots_adjust and/or tight_layout; "
- "not calling subplots_adjust.")
- return
- self.subplotpars.update(left, bottom, right, top, wspace, hspace)
- for ax in self.axes:
- if ax.get_subplotspec() is not None:
- ax._set_position(ax.get_subplotspec().get_position(self))
- self.stale = True
-
- def align_xlabels(self, axs=None):
- """
- Align the xlabels of subplots in the same subplot column if label
- alignment is being done automatically (i.e. the label position is
- not manually set).
-
- Alignment persists for draw events after this is called.
-
- If a label is on the bottom, it is aligned with labels on Axes that
- also have their label on the bottom and that have the same
- bottom-most subplot row. If the label is on the top,
- it is aligned with labels on Axes with the same top-most row.
-
- Parameters
- ----------
- axs : list of `~matplotlib.axes.Axes`
- Optional list of (or `~numpy.ndarray`) `~matplotlib.axes.Axes`
- to align the xlabels.
- Default is to align all Axes on the figure.
-
- See Also
- --------
- matplotlib.figure.Figure.align_ylabels
- matplotlib.figure.Figure.align_labels
-
- Notes
- -----
- This assumes that ``axs`` are from the same `.GridSpec`, so that
- their `.SubplotSpec` positions correspond to figure positions.
-
- Examples
- --------
- Example with rotated xtick labels::
-
- fig, axs = plt.subplots(1, 2)
- for tick in axs[0].get_xticklabels():
- tick.set_rotation(55)
- axs[0].set_xlabel('XLabel 0')
- axs[1].set_xlabel('XLabel 1')
- fig.align_xlabels()
- """
- if axs is None:
- axs = self.axes
- axs = [ax for ax in np.ravel(axs) if ax.get_subplotspec() is not None]
- for ax in axs:
- _log.debug(' Working on: %s', ax.get_xlabel())
- rowspan = ax.get_subplotspec().rowspan
- pos = ax.xaxis.get_label_position() # top or bottom
- # Search through other axes for label positions that are same as
- # this one and that share the appropriate row number.
- # Add to a grouper associated with each axes of siblings.
- # This list is inspected in `axis.draw` by
- # `axis._update_label_position`.
- for axc in axs:
- if axc.xaxis.get_label_position() == pos:
- rowspanc = axc.get_subplotspec().rowspan
- if (pos == 'top' and rowspan.start == rowspanc.start or
- pos == 'bottom' and rowspan.stop == rowspanc.stop):
- # grouper for groups of xlabels to align
- self._align_label_groups['x'].join(ax, axc)
-
- def align_ylabels(self, axs=None):
- """
- Align the ylabels of subplots in the same subplot column if label
- alignment is being done automatically (i.e. the label position is
- not manually set).
-
- Alignment persists for draw events after this is called.
-
- If a label is on the left, it is aligned with labels on Axes that
- also have their label on the left and that have the same
- left-most subplot column. If the label is on the right,
- it is aligned with labels on Axes with the same right-most column.
-
- Parameters
- ----------
- axs : list of `~matplotlib.axes.Axes`
- Optional list (or `~numpy.ndarray`) of `~matplotlib.axes.Axes`
- to align the ylabels.
- Default is to align all Axes on the figure.
-
- See Also
- --------
- matplotlib.figure.Figure.align_xlabels
- matplotlib.figure.Figure.align_labels
-
- Notes
- -----
- This assumes that ``axs`` are from the same `.GridSpec`, so that
- their `.SubplotSpec` positions correspond to figure positions.
-
- Examples
- --------
- Example with large yticks labels::
-
- fig, axs = plt.subplots(2, 1)
- axs[0].plot(np.arange(0, 1000, 50))
- axs[0].set_ylabel('YLabel 0')
- axs[1].set_ylabel('YLabel 1')
- fig.align_ylabels()
- """
- if axs is None:
- axs = self.axes
- axs = [ax for ax in np.ravel(axs) if ax.get_subplotspec() is not None]
- for ax in axs:
- _log.debug(' Working on: %s', ax.get_ylabel())
- colspan = ax.get_subplotspec().colspan
- pos = ax.yaxis.get_label_position() # left or right
- # Search through other axes for label positions that are same as
- # this one and that share the appropriate column number.
- # Add to a list associated with each axes of siblings.
- # This list is inspected in `axis.draw` by
- # `axis._update_label_position`.
- for axc in axs:
- if axc.yaxis.get_label_position() == pos:
- colspanc = axc.get_subplotspec().colspan
- if (pos == 'left' and colspan.start == colspanc.start or
- pos == 'right' and colspan.stop == colspanc.stop):
- # grouper for groups of ylabels to align
- self._align_label_groups['y'].join(ax, axc)
-
- def align_labels(self, axs=None):
- """
- Align the xlabels and ylabels of subplots with the same subplots
- row or column (respectively) if label alignment is being
- done automatically (i.e. the label position is not manually set).
-
- Alignment persists for draw events after this is called.
-
- Parameters
- ----------
- axs : list of `~matplotlib.axes.Axes`
- Optional list (or `~numpy.ndarray`) of `~matplotlib.axes.Axes`
- to align the labels.
- Default is to align all Axes on the figure.
-
- See Also
- --------
- matplotlib.figure.Figure.align_xlabels
-
- matplotlib.figure.Figure.align_ylabels
- """
- self.align_xlabels(axs=axs)
- self.align_ylabels(axs=axs)
-
- def add_gridspec(self, nrows=1, ncols=1, **kwargs):
- """
- Return a `.GridSpec` that has this figure as a parent. This allows
- complex layout of Axes in the figure.
-
- Parameters
- ----------
- nrows : int, default: 1
- Number of rows in grid.
-
- ncols : int, default: 1
- Number of columns in grid.
-
- Returns
- -------
- `.GridSpec`
-
- Other Parameters
- ----------------
- **kwargs
- Keyword arguments are passed to `.GridSpec`.
-
- See Also
- --------
- matplotlib.pyplot.subplots
-
- Examples
- --------
- Adding a subplot that spans two rows::
-
- fig = plt.figure()
- gs = fig.add_gridspec(2, 2)
- ax1 = fig.add_subplot(gs[0, 0])
- ax2 = fig.add_subplot(gs[1, 0])
- # spans two rows:
- ax3 = fig.add_subplot(gs[:, 1])
-
- """
-
- _ = kwargs.pop('figure', None) # pop in case user has added this...
- gs = GridSpec(nrows=nrows, ncols=ncols, figure=self, **kwargs)
- return gs
-
- def subfigures(self, nrows=1, ncols=1, squeeze=True,
- wspace=None, hspace=None,
- width_ratios=None, height_ratios=None,
- **kwargs):
- """
- Add a set of subfigures to this figure or subfigure.
-
- A subfigure has the same artist methods as a figure, and is logically
- the same as a figure, but cannot print itself.
- See :doc:`/gallery/subplots_axes_and_figures/subfigures`.
-
- .. note::
- The *subfigure* concept is new in v3.4, and the API is still provisional.
-
- Parameters
- ----------
- nrows, ncols : int, default: 1
- Number of rows/columns of the subfigure grid.
-
- squeeze : bool, default: True
- If True, extra dimensions are squeezed out from the returned
- array of subfigures.
-
- wspace, hspace : float, default: None
- The amount of width/height reserved for space between subfigures,
- expressed as a fraction of the average subfigure width/height.
- If not given, the values will be inferred from rcParams if using
- constrained layout (see `~.ConstrainedLayoutEngine`), or zero if
- not using a layout engine.
-
- width_ratios : array-like of length *ncols*, optional
- Defines the relative widths of the columns. Each column gets a
- relative width of ``width_ratios[i] / sum(width_ratios)``.
- If not given, all columns will have the same width.
-
- height_ratios : array-like of length *nrows*, optional
- Defines the relative heights of the rows. Each row gets a
- relative height of ``height_ratios[i] / sum(height_ratios)``.
- If not given, all rows will have the same height.
- """
- gs = GridSpec(nrows=nrows, ncols=ncols, figure=self,
- wspace=wspace, hspace=hspace,
- width_ratios=width_ratios,
- height_ratios=height_ratios,
- left=0, right=1, bottom=0, top=1)
-
- sfarr = np.empty((nrows, ncols), dtype=object)
- for i in range(ncols):
- for j in range(nrows):
- sfarr[j, i] = self.add_subfigure(gs[j, i], **kwargs)
-
- if self.get_layout_engine() is None and (wspace is not None or
- hspace is not None):
- # Gridspec wspace and hspace is ignored on subfigure instantiation,
- # and no space is left. So need to account for it here if required.
- bottoms, tops, lefts, rights = gs.get_grid_positions(self)
- for sfrow, bottom, top in zip(sfarr, bottoms, tops):
- for sf, left, right in zip(sfrow, lefts, rights):
- bbox = Bbox.from_extents(left, bottom, right, top)
- sf._redo_transform_rel_fig(bbox=bbox)
-
- if squeeze:
- # Discarding unneeded dimensions that equal 1. If we only have one
- # subfigure, just return it instead of a 1-element array.
- return sfarr.item() if sfarr.size == 1 else sfarr.squeeze()
- else:
- # Returned axis array will be always 2-d, even if nrows=ncols=1.
- return sfarr
-
- def add_subfigure(self, subplotspec, **kwargs):
- """
- Add a `.SubFigure` to the figure as part of a subplot arrangement.
-
- Parameters
- ----------
- subplotspec : `.gridspec.SubplotSpec`
- Defines the region in a parent gridspec where the subfigure will
- be placed.
-
- Returns
- -------
- `.SubFigure`
-
- Other Parameters
- ----------------
- **kwargs
- Are passed to the `.SubFigure` object.
-
- See Also
- --------
- .Figure.subfigures
- """
- sf = SubFigure(self, subplotspec, **kwargs)
- self.subfigs += [sf]
- return sf
-
- def sca(self, a):
- """Set the current Axes to be *a* and return *a*."""
- self._axstack.bubble(a)
- self._axobservers.process("_axes_change_event", self)
- return a
-
- def gca(self):
- """
- Get the current Axes.
-
- If there is currently no Axes on this Figure, a new one is created
- using `.Figure.add_subplot`. (To test whether there is currently an
- Axes on a Figure, check whether ``figure.axes`` is empty. To test
- whether there is currently a Figure on the pyplot figure stack, check
- whether `.pyplot.get_fignums()` is empty.)
- """
- ax = self._axstack.current()
- return ax if ax is not None else self.add_subplot()
-
- def _gci(self):
- # Helper for `~matplotlib.pyplot.gci`. Do not use elsewhere.
- """
- Get the current colorable artist.
-
- Specifically, returns the current `.ScalarMappable` instance (`.Image`
- created by `imshow` or `figimage`, `.Collection` created by `pcolor` or
- `scatter`, etc.), or *None* if no such instance has been defined.
-
- The current image is an attribute of the current Axes, or the nearest
- earlier Axes in the current figure that contains an image.
-
- Notes
- -----
- Historically, the only colorable artists were images; hence the name
- ``gci`` (get current image).
- """
- # Look first for an image in the current Axes.
- ax = self._axstack.current()
- if ax is None:
- return None
- im = ax._gci()
- if im is not None:
- return im
- # If there is no image in the current Axes, search for
- # one in a previously created Axes. Whether this makes
- # sense is debatable, but it is the documented behavior.
- for ax in reversed(self.axes):
- im = ax._gci()
- if im is not None:
- return im
- return None
-
- def _process_projection_requirements(self, *, axes_class=None, polar=False,
- projection=None, **kwargs):
- """
- Handle the args/kwargs to add_axes/add_subplot/gca, returning::
-
- (axes_proj_class, proj_class_kwargs)
-
- which can be used for new Axes initialization/identification.
- """
- if axes_class is not None:
- if polar or projection is not None:
- raise ValueError(
- "Cannot combine 'axes_class' and 'projection' or 'polar'")
- projection_class = axes_class
- else:
-
- if polar:
- if projection is not None and projection != 'polar':
- raise ValueError(
- f"polar={polar}, yet projection={projection!r}. "
- "Only one of these arguments should be supplied."
- )
- projection = 'polar'
-
- if isinstance(projection, str) or projection is None:
- projection_class = projections.get_projection_class(projection)
- elif hasattr(projection, '_as_mpl_axes'):
- projection_class, extra_kwargs = projection._as_mpl_axes()
- kwargs.update(**extra_kwargs)
- else:
- raise TypeError(
- f"projection must be a string, None or implement a "
- f"_as_mpl_axes method, not {projection!r}")
- return projection_class, kwargs
-
- def get_default_bbox_extra_artists(self):
- bbox_artists = [artist for artist in self.get_children()
- if (artist.get_visible() and artist.get_in_layout())]
- for ax in self.axes:
- if ax.get_visible():
- bbox_artists.extend(ax.get_default_bbox_extra_artists())
- return bbox_artists
-
- @_api.make_keyword_only("3.8", "bbox_extra_artists")
- def get_tightbbox(self, renderer=None, bbox_extra_artists=None):
- """
- Return a (tight) bounding box of the figure *in inches*.
-
- Note that `.FigureBase` differs from all other artists, which return
- their `.Bbox` in pixels.
-
- Artists that have ``artist.set_in_layout(False)`` are not included
- in the bbox.
-
- Parameters
- ----------
- renderer : `.RendererBase` subclass
- Renderer that will be used to draw the figures (i.e.
- ``fig.canvas.get_renderer()``)
-
- bbox_extra_artists : list of `.Artist` or ``None``
- List of artists to include in the tight bounding box. If
- ``None`` (default), then all artist children of each Axes are
- included in the tight bounding box.
-
- Returns
- -------
- `.BboxBase`
- containing the bounding box (in figure inches).
- """
-
- if renderer is None:
- renderer = self.figure._get_renderer()
-
- bb = []
- if bbox_extra_artists is None:
- artists = self.get_default_bbox_extra_artists()
- else:
- artists = bbox_extra_artists
-
- for a in artists:
- bbox = a.get_tightbbox(renderer)
- if bbox is not None:
- bb.append(bbox)
-
- for ax in self.axes:
- if ax.get_visible():
- # some axes don't take the bbox_extra_artists kwarg so we
- # need this conditional....
- try:
- bbox = ax.get_tightbbox(
- renderer, bbox_extra_artists=bbox_extra_artists)
- except TypeError:
- bbox = ax.get_tightbbox(renderer)
- bb.append(bbox)
- bb = [b for b in bb
- if (np.isfinite(b.width) and np.isfinite(b.height)
- and (b.width != 0 or b.height != 0))]
-
- isfigure = hasattr(self, 'bbox_inches')
- if len(bb) == 0:
- if isfigure:
- return self.bbox_inches
- else:
- # subfigures do not have bbox_inches, but do have a bbox
- bb = [self.bbox]
-
- _bbox = Bbox.union(bb)
-
- if isfigure:
- # transform from pixels to inches...
- _bbox = TransformedBbox(_bbox, self.dpi_scale_trans.inverted())
-
- return _bbox
-
- @staticmethod
- def _norm_per_subplot_kw(per_subplot_kw):
- expanded = {}
- for k, v in per_subplot_kw.items():
- if isinstance(k, tuple):
- for sub_key in k:
- if sub_key in expanded:
- raise ValueError(f'The key {sub_key!r} appears multiple times.')
- expanded[sub_key] = v
- else:
- if k in expanded:
- raise ValueError(f'The key {k!r} appears multiple times.')
- expanded[k] = v
- return expanded
-
- @staticmethod
- def _normalize_grid_string(layout):
- if '\n' not in layout:
- # single-line string
- return [list(ln) for ln in layout.split(';')]
- else:
- # multi-line string
- layout = inspect.cleandoc(layout)
- return [list(ln) for ln in layout.strip('\n').split('\n')]
-
- def subplot_mosaic(self, mosaic, *, sharex=False, sharey=False,
- width_ratios=None, height_ratios=None,
- empty_sentinel='.',
- subplot_kw=None, per_subplot_kw=None, gridspec_kw=None):
- """
- Build a layout of Axes based on ASCII art or nested lists.
-
- This is a helper function to build complex GridSpec layouts visually.
-
- See :ref:`mosaic`
- for an example and full API documentation
-
- Parameters
- ----------
- mosaic : list of list of {hashable or nested} or str
-
- A visual layout of how you want your Axes to be arranged
- labeled as strings. For example ::
-
- x = [['A panel', 'A panel', 'edge'],
- ['C panel', '.', 'edge']]
-
- produces 4 Axes:
-
- - 'A panel' which is 1 row high and spans the first two columns
- - 'edge' which is 2 rows high and is on the right edge
- - 'C panel' which in 1 row and 1 column wide in the bottom left
- - a blank space 1 row and 1 column wide in the bottom center
-
- Any of the entries in the layout can be a list of lists
- of the same form to create nested layouts.
-
- If input is a str, then it can either be a multi-line string of
- the form ::
-
- '''
- AAE
- C.E
- '''
-
- where each character is a column and each line is a row. Or it
- can be a single-line string where rows are separated by ``;``::
-
- 'AB;CC'
-
- The string notation allows only single character Axes labels and
- does not support nesting but is very terse.
-
- The Axes identifiers may be `str` or a non-iterable hashable
- object (e.g. `tuple` s may not be used).
-
- sharex, sharey : bool, default: False
- If True, the x-axis (*sharex*) or y-axis (*sharey*) will be shared
- among all subplots. In that case, tick label visibility and axis
- units behave as for `subplots`. If False, each subplot's x- or
- y-axis will be independent.
-
- width_ratios : array-like of length *ncols*, optional
- Defines the relative widths of the columns. Each column gets a
- relative width of ``width_ratios[i] / sum(width_ratios)``.
- If not given, all columns will have the same width. Equivalent
- to ``gridspec_kw={'width_ratios': [...]}``. In the case of nested
- layouts, this argument applies only to the outer layout.
-
- height_ratios : array-like of length *nrows*, optional
- Defines the relative heights of the rows. Each row gets a
- relative height of ``height_ratios[i] / sum(height_ratios)``.
- If not given, all rows will have the same height. Equivalent
- to ``gridspec_kw={'height_ratios': [...]}``. In the case of nested
- layouts, this argument applies only to the outer layout.
-
- subplot_kw : dict, optional
- Dictionary with keywords passed to the `.Figure.add_subplot` call
- used to create each subplot. These values may be overridden by
- values in *per_subplot_kw*.
-
- per_subplot_kw : dict, optional
- A dictionary mapping the Axes identifiers or tuples of identifiers
- to a dictionary of keyword arguments to be passed to the
- `.Figure.add_subplot` call used to create each subplot. The values
- in these dictionaries have precedence over the values in
- *subplot_kw*.
-
- If *mosaic* is a string, and thus all keys are single characters,
- it is possible to use a single string instead of a tuple as keys;
- i.e. ``"AB"`` is equivalent to ``("A", "B")``.
-
- .. versionadded:: 3.7
-
- gridspec_kw : dict, optional
- Dictionary with keywords passed to the `.GridSpec` constructor used
- to create the grid the subplots are placed on. In the case of
- nested layouts, this argument applies only to the outer layout.
- For more complex layouts, users should use `.Figure.subfigures`
- to create the nesting.
-
- empty_sentinel : object, optional
- Entry in the layout to mean "leave this space empty". Defaults
- to ``'.'``. Note, if *layout* is a string, it is processed via
- `inspect.cleandoc` to remove leading white space, which may
- interfere with using white-space as the empty sentinel.
-
- Returns
- -------
- dict[label, Axes]
- A dictionary mapping the labels to the Axes objects. The order of
- the axes is left-to-right and top-to-bottom of their position in the
- total layout.
-
- """
- subplot_kw = subplot_kw or {}
- gridspec_kw = dict(gridspec_kw or {})
- per_subplot_kw = per_subplot_kw or {}
-
- if height_ratios is not None:
- if 'height_ratios' in gridspec_kw:
- raise ValueError("'height_ratios' must not be defined both as "
- "parameter and as key in 'gridspec_kw'")
- gridspec_kw['height_ratios'] = height_ratios
- if width_ratios is not None:
- if 'width_ratios' in gridspec_kw:
- raise ValueError("'width_ratios' must not be defined both as "
- "parameter and as key in 'gridspec_kw'")
- gridspec_kw['width_ratios'] = width_ratios
-
- # special-case string input
- if isinstance(mosaic, str):
- mosaic = self._normalize_grid_string(mosaic)
- per_subplot_kw = {
- tuple(k): v for k, v in per_subplot_kw.items()
- }
-
- per_subplot_kw = self._norm_per_subplot_kw(per_subplot_kw)
-
- # Only accept strict bools to allow a possible future API expansion.
- _api.check_isinstance(bool, sharex=sharex, sharey=sharey)
-
- def _make_array(inp):
- """
- Convert input into 2D array
-
- We need to have this internal function rather than
- ``np.asarray(..., dtype=object)`` so that a list of lists
- of lists does not get converted to an array of dimension > 2.
-
- Returns
- -------
- 2D object array
- """
- r0, *rest = inp
- if isinstance(r0, str):
- raise ValueError('List mosaic specification must be 2D')
- for j, r in enumerate(rest, start=1):
- if isinstance(r, str):
- raise ValueError('List mosaic specification must be 2D')
- if len(r0) != len(r):
- raise ValueError(
- "All of the rows must be the same length, however "
- f"the first row ({r0!r}) has length {len(r0)} "
- f"and row {j} ({r!r}) has length {len(r)}."
- )
- out = np.zeros((len(inp), len(r0)), dtype=object)
- for j, r in enumerate(inp):
- for k, v in enumerate(r):
- out[j, k] = v
- return out
-
- def _identify_keys_and_nested(mosaic):
- """
- Given a 2D object array, identify unique IDs and nested mosaics
-
- Parameters
- ----------
- mosaic : 2D object array
-
- Returns
- -------
- unique_ids : tuple
- The unique non-sub mosaic entries in this mosaic
- nested : dict[tuple[int, int], 2D object array]
- """
- # make sure we preserve the user supplied order
- unique_ids = cbook._OrderedSet()
- nested = {}
- for j, row in enumerate(mosaic):
- for k, v in enumerate(row):
- if v == empty_sentinel:
- continue
- elif not cbook.is_scalar_or_string(v):
- nested[(j, k)] = _make_array(v)
- else:
- unique_ids.add(v)
-
- return tuple(unique_ids), nested
-
- def _do_layout(gs, mosaic, unique_ids, nested):
- """
- Recursively do the mosaic.
-
- Parameters
- ----------
- gs : GridSpec
- mosaic : 2D object array
- The input converted to a 2D array for this level.
- unique_ids : tuple
- The identified scalar labels at this level of nesting.
- nested : dict[tuple[int, int]], 2D object array
- The identified nested mosaics, if any.
-
- Returns
- -------
- dict[label, Axes]
- A flat dict of all of the Axes created.
- """
- output = dict()
-
- # we need to merge together the Axes at this level and the axes
- # in the (recursively) nested sub-mosaics so that we can add
- # them to the figure in the "natural" order if you were to
- # ravel in c-order all of the Axes that will be created
- #
- # This will stash the upper left index of each object (axes or
- # nested mosaic) at this level
- this_level = dict()
-
- # go through the unique keys,
- for name in unique_ids:
- # sort out where each axes starts/ends
- indx = np.argwhere(mosaic == name)
- start_row, start_col = np.min(indx, axis=0)
- end_row, end_col = np.max(indx, axis=0) + 1
- # and construct the slice object
- slc = (slice(start_row, end_row), slice(start_col, end_col))
- # some light error checking
- if (mosaic[slc] != name).any():
- raise ValueError(
- f"While trying to layout\n{mosaic!r}\n"
- f"we found that the label {name!r} specifies a "
- "non-rectangular or non-contiguous area.")
- # and stash this slice for later
- this_level[(start_row, start_col)] = (name, slc, 'axes')
-
- # do the same thing for the nested mosaics (simpler because these
- # cannot be spans yet!)
- for (j, k), nested_mosaic in nested.items():
- this_level[(j, k)] = (None, nested_mosaic, 'nested')
-
- # now go through the things in this level and add them
- # in order left-to-right top-to-bottom
- for key in sorted(this_level):
- name, arg, method = this_level[key]
- # we are doing some hokey function dispatch here based
- # on the 'method' string stashed above to sort out if this
- # element is an Axes or a nested mosaic.
- if method == 'axes':
- slc = arg
- # add a single axes
- if name in output:
- raise ValueError(f"There are duplicate keys {name} "
- f"in the layout\n{mosaic!r}")
- ax = self.add_subplot(
- gs[slc], **{
- 'label': str(name),
- **subplot_kw,
- **per_subplot_kw.get(name, {})
- }
- )
- output[name] = ax
- elif method == 'nested':
- nested_mosaic = arg
- j, k = key
- # recursively add the nested mosaic
- rows, cols = nested_mosaic.shape
- nested_output = _do_layout(
- gs[j, k].subgridspec(rows, cols),
- nested_mosaic,
- *_identify_keys_and_nested(nested_mosaic)
- )
- overlap = set(output) & set(nested_output)
- if overlap:
- raise ValueError(
- f"There are duplicate keys {overlap} "
- f"between the outer layout\n{mosaic!r}\n"
- f"and the nested layout\n{nested_mosaic}"
- )
- output.update(nested_output)
- else:
- raise RuntimeError("This should never happen")
- return output
-
- mosaic = _make_array(mosaic)
- rows, cols = mosaic.shape
- gs = self.add_gridspec(rows, cols, **gridspec_kw)
- ret = _do_layout(gs, mosaic, *_identify_keys_and_nested(mosaic))
- ax0 = next(iter(ret.values()))
- for ax in ret.values():
- if sharex:
- ax.sharex(ax0)
- ax._label_outer_xaxis(skip_non_rectangular_axes=True)
- if sharey:
- ax.sharey(ax0)
- ax._label_outer_yaxis(skip_non_rectangular_axes=True)
- if extra := set(per_subplot_kw) - set(ret):
- raise ValueError(
- f"The keys {extra} are in *per_subplot_kw* "
- "but not in the mosaic."
- )
- return ret
-
- def _set_artist_props(self, a):
- if a != self:
- a.set_figure(self)
- a.stale_callback = _stale_figure_callback
- a.set_transform(self.transSubfigure)
-
-
-@_docstring.interpd
-class SubFigure(FigureBase):
- """
- Logical figure that can be placed inside a figure.
-
- Typically instantiated using `.Figure.add_subfigure` or
- `.SubFigure.add_subfigure`, or `.SubFigure.subfigures`. A subfigure has
- the same methods as a figure except for those particularly tied to the size
- or dpi of the figure, and is confined to a prescribed region of the figure.
- For example the following puts two subfigures side-by-side::
-
- fig = plt.figure()
- sfigs = fig.subfigures(1, 2)
- axsL = sfigs[0].subplots(1, 2)
- axsR = sfigs[1].subplots(2, 1)
-
- See :doc:`/gallery/subplots_axes_and_figures/subfigures`
-
- .. note::
- The *subfigure* concept is new in v3.4, and the API is still provisional.
- """
-
- def __init__(self, parent, subplotspec, *,
- facecolor=None,
- edgecolor=None,
- linewidth=0.0,
- frameon=None,
- **kwargs):
- """
- Parameters
- ----------
- parent : `.Figure` or `.SubFigure`
- Figure or subfigure that contains the SubFigure. SubFigures
- can be nested.
-
- subplotspec : `.gridspec.SubplotSpec`
- Defines the region in a parent gridspec where the subfigure will
- be placed.
-
- facecolor : default: ``"none"``
- The figure patch face color; transparent by default.
-
- edgecolor : default: :rc:`figure.edgecolor`
- The figure patch edge color.
-
- linewidth : float
- The linewidth of the frame (i.e. the edge linewidth of the figure
- patch).
-
- frameon : bool, default: :rc:`figure.frameon`
- If ``False``, suppress drawing the figure background patch.
-
- Other Parameters
- ----------------
- **kwargs : `.SubFigure` properties, optional
-
- %(SubFigure:kwdoc)s
- """
- super().__init__(**kwargs)
- if facecolor is None:
- facecolor = "none"
- if edgecolor is None:
- edgecolor = mpl.rcParams['figure.edgecolor']
- if frameon is None:
- frameon = mpl.rcParams['figure.frameon']
-
- self._subplotspec = subplotspec
- self._parent = parent
- self.figure = parent.figure
-
- # subfigures use the parent axstack
- self._axstack = parent._axstack
- self.subplotpars = parent.subplotpars
- self.dpi_scale_trans = parent.dpi_scale_trans
- self._axobservers = parent._axobservers
- self.canvas = parent.canvas
- self.transFigure = parent.transFigure
- self.bbox_relative = Bbox.null()
- self._redo_transform_rel_fig()
- self.figbbox = self._parent.figbbox
- self.bbox = TransformedBbox(self.bbox_relative,
- self._parent.transSubfigure)
- self.transSubfigure = BboxTransformTo(self.bbox)
-
- self.patch = Rectangle(
- xy=(0, 0), width=1, height=1, visible=frameon,
- facecolor=facecolor, edgecolor=edgecolor, linewidth=linewidth,
- # Don't let the figure patch influence bbox calculation.
- in_layout=False, transform=self.transSubfigure)
- self._set_artist_props(self.patch)
- self.patch.set_antialiased(False)
-
- @property
- def dpi(self):
- return self._parent.dpi
-
- @dpi.setter
- def dpi(self, value):
- self._parent.dpi = value
-
- def get_dpi(self):
- """
- Return the resolution of the parent figure in dots-per-inch as a float.
- """
- return self._parent.dpi
-
- def set_dpi(self, val):
- """
- Set the resolution of parent figure in dots-per-inch.
-
- Parameters
- ----------
- val : float
- """
- self._parent.dpi = val
- self.stale = True
-
- def _get_renderer(self):
- return self._parent._get_renderer()
-
- def _redo_transform_rel_fig(self, bbox=None):
- """
- Make the transSubfigure bbox relative to Figure transform.
-
- Parameters
- ----------
- bbox : bbox or None
- If not None, then the bbox is used for relative bounding box.
- Otherwise, it is calculated from the subplotspec.
- """
- if bbox is not None:
- self.bbox_relative.p0 = bbox.p0
- self.bbox_relative.p1 = bbox.p1
- return
- # need to figure out *where* this subplotspec is.
- gs = self._subplotspec.get_gridspec()
- wr = np.asarray(gs.get_width_ratios())
- hr = np.asarray(gs.get_height_ratios())
- dx = wr[self._subplotspec.colspan].sum() / wr.sum()
- dy = hr[self._subplotspec.rowspan].sum() / hr.sum()
- x0 = wr[:self._subplotspec.colspan.start].sum() / wr.sum()
- y0 = 1 - hr[:self._subplotspec.rowspan.stop].sum() / hr.sum()
- self.bbox_relative.p0 = (x0, y0)
- self.bbox_relative.p1 = (x0 + dx, y0 + dy)
-
- def get_constrained_layout(self):
- """
- Return whether constrained layout is being used.
-
- See :ref:`constrainedlayout_guide`.
- """
- return self._parent.get_constrained_layout()
-
- def get_constrained_layout_pads(self, relative=False):
- """
- Get padding for ``constrained_layout``.
-
- Returns a list of ``w_pad, h_pad`` in inches and
- ``wspace`` and ``hspace`` as fractions of the subplot.
-
- See :ref:`constrainedlayout_guide`.
-
- Parameters
- ----------
- relative : bool
- If `True`, then convert from inches to figure relative.
- """
- return self._parent.get_constrained_layout_pads(relative=relative)
-
- def get_layout_engine(self):
- return self._parent.get_layout_engine()
-
- @property
- def axes(self):
- """
- List of Axes in the SubFigure. You can access and modify the Axes
- in the SubFigure through this list.
-
- Modifying this list has no effect. Instead, use `~.SubFigure.add_axes`,
- `~.SubFigure.add_subplot` or `~.SubFigure.delaxes` to add or remove an
- Axes.
-
- Note: The `.SubFigure.axes` property and `~.SubFigure.get_axes` method
- are equivalent.
- """
- return self._localaxes[:]
-
- get_axes = axes.fget
-
- def draw(self, renderer):
- # docstring inherited
-
- # draw the figure bounding box, perhaps none for white figure
- if not self.get_visible():
- return
-
- artists = self._get_draw_artists(renderer)
-
- try:
- renderer.open_group('subfigure', gid=self.get_gid())
- self.patch.draw(renderer)
- mimage._draw_list_compositing_images(
- renderer, self, artists, self.figure.suppressComposite)
- for sfig in self.subfigs:
- sfig.draw(renderer)
- renderer.close_group('subfigure')
-
- finally:
- self.stale = False
-
-
-@_docstring.interpd
-class Figure(FigureBase):
- """
- The top level container for all the plot elements.
-
- Attributes
- ----------
- patch
- The `.Rectangle` instance representing the figure background patch.
-
- suppressComposite
- For multiple images, the figure will make composite images
- depending on the renderer option_image_nocomposite function. If
- *suppressComposite* is a boolean, this will override the renderer.
- """
-
- # we want to cache the fonts and mathtext at a global level so that when
- # multiple figures are created we can reuse them. This helps with a bug on
- # windows where the creation of too many figures leads to too many open
- # file handles and improves the performance of parsing mathtext. However,
- # these global caches are not thread safe. The solution here is to let the
- # Figure acquire a shared lock at the start of the draw, and release it when it
- # is done. This allows multiple renderers to share the cached fonts and
- # parsed text, but only one figure can draw at a time and so the font cache
- # and mathtext cache are used by only one renderer at a time.
-
- _render_lock = threading.RLock()
-
- def __str__(self):
- return "Figure(%gx%g)" % tuple(self.bbox.size)
-
- def __repr__(self):
- return "<{clsname} size {h:g}x{w:g} with {naxes} Axes>".format(
- clsname=self.__class__.__name__,
- h=self.bbox.size[0], w=self.bbox.size[1],
- naxes=len(self.axes),
- )
-
- def __init__(self,
- figsize=None,
- dpi=None,
- *,
- facecolor=None,
- edgecolor=None,
- linewidth=0.0,
- frameon=None,
- subplotpars=None, # rc figure.subplot.*
- tight_layout=None, # rc figure.autolayout
- constrained_layout=None, # rc figure.constrained_layout.use
- layout=None,
- **kwargs
- ):
- """
- Parameters
- ----------
- figsize : 2-tuple of floats, default: :rc:`figure.figsize`
- Figure dimension ``(width, height)`` in inches.
-
- dpi : float, default: :rc:`figure.dpi`
- Dots per inch.
-
- facecolor : default: :rc:`figure.facecolor`
- The figure patch facecolor.
-
- edgecolor : default: :rc:`figure.edgecolor`
- The figure patch edge color.
-
- linewidth : float
- The linewidth of the frame (i.e. the edge linewidth of the figure
- patch).
-
- frameon : bool, default: :rc:`figure.frameon`
- If ``False``, suppress drawing the figure background patch.
-
- subplotpars : `SubplotParams`
- Subplot parameters. If not given, the default subplot
- parameters :rc:`figure.subplot.*` are used.
-
- tight_layout : bool or dict, default: :rc:`figure.autolayout`
- Whether to use the tight layout mechanism. See `.set_tight_layout`.
-
- .. admonition:: Discouraged
-
- The use of this parameter is discouraged. Please use
- ``layout='tight'`` instead for the common case of
- ``tight_layout=True`` and use `.set_tight_layout` otherwise.
-
- constrained_layout : bool, default: :rc:`figure.constrained_layout.use`
- This is equal to ``layout='constrained'``.
-
- .. admonition:: Discouraged
-
- The use of this parameter is discouraged. Please use
- ``layout='constrained'`` instead.
-
- layout : {'constrained', 'compressed', 'tight', 'none', `.LayoutEngine`, \
-None}, default: None
- The layout mechanism for positioning of plot elements to avoid
- overlapping Axes decorations (labels, ticks, etc). Note that
- layout managers can have significant performance penalties.
-
- - 'constrained': The constrained layout solver adjusts axes sizes
- to avoid overlapping axes decorations. Can handle complex plot
- layouts and colorbars, and is thus recommended.
-
- See :ref:`constrainedlayout_guide` for examples.
-
- - 'compressed': uses the same algorithm as 'constrained', but
- removes extra space between fixed-aspect-ratio Axes. Best for
- simple grids of axes.
-
- - 'tight': Use the tight layout mechanism. This is a relatively
- simple algorithm that adjusts the subplot parameters so that
- decorations do not overlap.
-
- See :ref:`tight_layout_guide` for examples.
-
- - 'none': Do not use a layout engine.
-
- - A `.LayoutEngine` instance. Builtin layout classes are
- `.ConstrainedLayoutEngine` and `.TightLayoutEngine`, more easily
- accessible by 'constrained' and 'tight'. Passing an instance
- allows third parties to provide their own layout engine.
-
- If not given, fall back to using the parameters *tight_layout* and
- *constrained_layout*, including their config defaults
- :rc:`figure.autolayout` and :rc:`figure.constrained_layout.use`.
-
- Other Parameters
- ----------------
- **kwargs : `.Figure` properties, optional
-
- %(Figure:kwdoc)s
- """
- super().__init__(**kwargs)
- self.figure = self
- self._layout_engine = None
-
- if layout is not None:
- if (tight_layout is not None):
- _api.warn_external(
- "The Figure parameters 'layout' and 'tight_layout' cannot "
- "be used together. Please use 'layout' only.")
- if (constrained_layout is not None):
- _api.warn_external(
- "The Figure parameters 'layout' and 'constrained_layout' "
- "cannot be used together. Please use 'layout' only.")
- self.set_layout_engine(layout=layout)
- elif tight_layout is not None:
- if constrained_layout is not None:
- _api.warn_external(
- "The Figure parameters 'tight_layout' and "
- "'constrained_layout' cannot be used together. Please use "
- "'layout' parameter")
- self.set_layout_engine(layout='tight')
- if isinstance(tight_layout, dict):
- self.get_layout_engine().set(**tight_layout)
- elif constrained_layout is not None:
- if isinstance(constrained_layout, dict):
- self.set_layout_engine(layout='constrained')
- self.get_layout_engine().set(**constrained_layout)
- elif constrained_layout:
- self.set_layout_engine(layout='constrained')
-
- else:
- # everything is None, so use default:
- self.set_layout_engine(layout=layout)
-
- # Callbacks traditionally associated with the canvas (and exposed with
- # a proxy property), but that actually need to be on the figure for
- # pickling.
- self._canvas_callbacks = cbook.CallbackRegistry(
- signals=FigureCanvasBase.events)
- connect = self._canvas_callbacks._connect_picklable
- self._mouse_key_ids = [
- connect('key_press_event', backend_bases._key_handler),
- connect('key_release_event', backend_bases._key_handler),
- connect('key_release_event', backend_bases._key_handler),
- connect('button_press_event', backend_bases._mouse_handler),
- connect('button_release_event', backend_bases._mouse_handler),
- connect('scroll_event', backend_bases._mouse_handler),
- connect('motion_notify_event', backend_bases._mouse_handler),
- ]
- self._button_pick_id = connect('button_press_event', self.pick)
- self._scroll_pick_id = connect('scroll_event', self.pick)
-
- if figsize is None:
- figsize = mpl.rcParams['figure.figsize']
- if dpi is None:
- dpi = mpl.rcParams['figure.dpi']
- if facecolor is None:
- facecolor = mpl.rcParams['figure.facecolor']
- if edgecolor is None:
- edgecolor = mpl.rcParams['figure.edgecolor']
- if frameon is None:
- frameon = mpl.rcParams['figure.frameon']
-
- if not np.isfinite(figsize).all() or (np.array(figsize) < 0).any():
- raise ValueError('figure size must be positive finite not '
- f'{figsize}')
- self.bbox_inches = Bbox.from_bounds(0, 0, *figsize)
-
- self.dpi_scale_trans = Affine2D().scale(dpi)
- # do not use property as it will trigger
- self._dpi = dpi
- self.bbox = TransformedBbox(self.bbox_inches, self.dpi_scale_trans)
- self.figbbox = self.bbox
- self.transFigure = BboxTransformTo(self.bbox)
- self.transSubfigure = self.transFigure
-
- self.patch = Rectangle(
- xy=(0, 0), width=1, height=1, visible=frameon,
- facecolor=facecolor, edgecolor=edgecolor, linewidth=linewidth,
- # Don't let the figure patch influence bbox calculation.
- in_layout=False)
- self._set_artist_props(self.patch)
- self.patch.set_antialiased(False)
-
- FigureCanvasBase(self) # Set self.canvas.
-
- if subplotpars is None:
- subplotpars = SubplotParams()
-
- self.subplotpars = subplotpars
-
- self._axstack = _AxesStack() # track all figure axes and current axes
- self.clear()
-
- def pick(self, mouseevent):
- if not self.canvas.widgetlock.locked():
- super().pick(mouseevent)
-
- def _check_layout_engines_compat(self, old, new):
- """
- Helper for set_layout engine
-
- If the figure has used the old engine and added a colorbar then the
- value of colorbar_gridspec must be the same on the new engine.
- """
- if old is None or new is None:
- return True
- if old.colorbar_gridspec == new.colorbar_gridspec:
- return True
- # colorbar layout different, so check if any colorbars are on the
- # figure...
- for ax in self.axes:
- if hasattr(ax, '_colorbar'):
- # colorbars list themselves as a colorbar.
- return False
- return True
-
- def set_layout_engine(self, layout=None, **kwargs):
- """
- Set the layout engine for this figure.
-
- Parameters
- ----------
- layout : {'constrained', 'compressed', 'tight', 'none', `.LayoutEngine`, None}
-
- - 'constrained' will use `~.ConstrainedLayoutEngine`
- - 'compressed' will also use `~.ConstrainedLayoutEngine`, but with
- a correction that attempts to make a good layout for fixed-aspect
- ratio Axes.
- - 'tight' uses `~.TightLayoutEngine`
- - 'none' removes layout engine.
-
- If a `.LayoutEngine` instance, that instance will be used.
-
- If `None`, the behavior is controlled by :rc:`figure.autolayout`
- (which if `True` behaves as if 'tight' was passed) and
- :rc:`figure.constrained_layout.use` (which if `True` behaves as if
- 'constrained' was passed). If both are `True`,
- :rc:`figure.autolayout` takes priority.
-
- Users and libraries can define their own layout engines and pass
- the instance directly as well.
-
- **kwargs
- The keyword arguments are passed to the layout engine to set things
- like padding and margin sizes. Only used if *layout* is a string.
-
- """
- if layout is None:
- if mpl.rcParams['figure.autolayout']:
- layout = 'tight'
- elif mpl.rcParams['figure.constrained_layout.use']:
- layout = 'constrained'
- else:
- self._layout_engine = None
- return
- if layout == 'tight':
- new_layout_engine = TightLayoutEngine(**kwargs)
- elif layout == 'constrained':
- new_layout_engine = ConstrainedLayoutEngine(**kwargs)
- elif layout == 'compressed':
- new_layout_engine = ConstrainedLayoutEngine(compress=True,
- **kwargs)
- elif layout == 'none':
- if self._layout_engine is not None:
- new_layout_engine = PlaceHolderLayoutEngine(
- self._layout_engine.adjust_compatible,
- self._layout_engine.colorbar_gridspec
- )
- else:
- new_layout_engine = None
- elif isinstance(layout, LayoutEngine):
- new_layout_engine = layout
- else:
- raise ValueError(f"Invalid value for 'layout': {layout!r}")
-
- if self._check_layout_engines_compat(self._layout_engine,
- new_layout_engine):
- self._layout_engine = new_layout_engine
- else:
- raise RuntimeError('Colorbar layout of new layout engine not '
- 'compatible with old engine, and a colorbar '
- 'has been created. Engine not changed.')
-
- def get_layout_engine(self):
- return self._layout_engine
-
- # TODO: I'd like to dynamically add the _repr_html_ method
- # to the figure in the right context, but then IPython doesn't
- # use it, for some reason.
-
- def _repr_html_(self):
- # We can't use "isinstance" here, because then we'd end up importing
- # webagg unconditionally.
- if 'WebAgg' in type(self.canvas).__name__:
- from matplotlib.backends import backend_webagg
- return backend_webagg.ipython_inline_display(self)
-
- def show(self, warn=True):
- """
- If using a GUI backend with pyplot, display the figure window.
-
- If the figure was not created using `~.pyplot.figure`, it will lack
- a `~.backend_bases.FigureManagerBase`, and this method will raise an
- AttributeError.
-
- .. warning::
-
- This does not manage an GUI event loop. Consequently, the figure
- may only be shown briefly or not shown at all if you or your
- environment are not managing an event loop.
-
- Use cases for `.Figure.show` include running this from a GUI
- application (where there is persistently an event loop running) or
- from a shell, like IPython, that install an input hook to allow the
- interactive shell to accept input while the figure is also being
- shown and interactive. Some, but not all, GUI toolkits will
- register an input hook on import. See :ref:`cp_integration` for
- more details.
-
- If you're in a shell without input hook integration or executing a
- python script, you should use `matplotlib.pyplot.show` with
- ``block=True`` instead, which takes care of starting and running
- the event loop for you.
-
- Parameters
- ----------
- warn : bool, default: True
- If ``True`` and we are not running headless (i.e. on Linux with an
- unset DISPLAY), issue warning when called on a non-GUI backend.
-
- """
- if self.canvas.manager is None:
- raise AttributeError(
- "Figure.show works only for figures managed by pyplot, "
- "normally created by pyplot.figure()")
- try:
- self.canvas.manager.show()
- except NonGuiException as exc:
- if warn:
- _api.warn_external(str(exc))
-
- @property
- def axes(self):
- """
- List of Axes in the Figure. You can access and modify the Axes in the
- Figure through this list.
-
- Do not modify the list itself. Instead, use `~Figure.add_axes`,
- `~.Figure.add_subplot` or `~.Figure.delaxes` to add or remove an Axes.
-
- Note: The `.Figure.axes` property and `~.Figure.get_axes` method are
- equivalent.
- """
- return self._axstack.as_list()
-
- get_axes = axes.fget
-
- def _get_renderer(self):
- if hasattr(self.canvas, 'get_renderer'):
- return self.canvas.get_renderer()
- else:
- return _get_renderer(self)
-
- def _get_dpi(self):
- return self._dpi
-
- def _set_dpi(self, dpi, forward=True):
- """
- Parameters
- ----------
- dpi : float
-
- forward : bool
- Passed on to `~.Figure.set_size_inches`
- """
- if dpi == self._dpi:
- # We don't want to cause undue events in backends.
- return
- self._dpi = dpi
- self.dpi_scale_trans.clear().scale(dpi)
- w, h = self.get_size_inches()
- self.set_size_inches(w, h, forward=forward)
-
- dpi = property(_get_dpi, _set_dpi, doc="The resolution in dots per inch.")
-
- def get_tight_layout(self):
- """Return whether `.tight_layout` is called when drawing."""
- return isinstance(self.get_layout_engine(), TightLayoutEngine)
-
- @_api.deprecated("3.6", alternative="set_layout_engine",
- pending=True)
- def set_tight_layout(self, tight):
- """
- Set whether and how `.tight_layout` is called when drawing.
-
- Parameters
- ----------
- tight : bool or dict with keys "pad", "w_pad", "h_pad", "rect" or None
- If a bool, sets whether to call `.tight_layout` upon drawing.
- If ``None``, use :rc:`figure.autolayout` instead.
- If a dict, pass it as kwargs to `.tight_layout`, overriding the
- default paddings.
- """
- if tight is None:
- tight = mpl.rcParams['figure.autolayout']
- _tight = 'tight' if bool(tight) else 'none'
- _tight_parameters = tight if isinstance(tight, dict) else {}
- self.set_layout_engine(_tight, **_tight_parameters)
- self.stale = True
-
- def get_constrained_layout(self):
- """
- Return whether constrained layout is being used.
-
- See :ref:`constrainedlayout_guide`.
- """
- return isinstance(self.get_layout_engine(), ConstrainedLayoutEngine)
-
- @_api.deprecated("3.6", alternative="set_layout_engine('constrained')",
- pending=True)
- def set_constrained_layout(self, constrained):
- """
- Set whether ``constrained_layout`` is used upon drawing.
-
- If None, :rc:`figure.constrained_layout.use` value will be used.
-
- When providing a dict containing the keys ``w_pad``, ``h_pad``
- the default ``constrained_layout`` paddings will be
- overridden. These pads are in inches and default to 3.0/72.0.
- ``w_pad`` is the width padding and ``h_pad`` is the height padding.
-
- Parameters
- ----------
- constrained : bool or dict or None
- """
- if constrained is None:
- constrained = mpl.rcParams['figure.constrained_layout.use']
- _constrained = 'constrained' if bool(constrained) else 'none'
- _parameters = constrained if isinstance(constrained, dict) else {}
- self.set_layout_engine(_constrained, **_parameters)
- self.stale = True
-
- @_api.deprecated(
- "3.6", alternative="figure.get_layout_engine().set()",
- pending=True)
- def set_constrained_layout_pads(self, **kwargs):
- """
- Set padding for ``constrained_layout``.
-
- Tip: The parameters can be passed from a dictionary by using
- ``fig.set_constrained_layout(**pad_dict)``.
-
- See :ref:`constrainedlayout_guide`.
-
- Parameters
- ----------
- w_pad : float, default: :rc:`figure.constrained_layout.w_pad`
- Width padding in inches. This is the pad around Axes
- and is meant to make sure there is enough room for fonts to
- look good. Defaults to 3 pts = 0.04167 inches
-
- h_pad : float, default: :rc:`figure.constrained_layout.h_pad`
- Height padding in inches. Defaults to 3 pts.
-
- wspace : float, default: :rc:`figure.constrained_layout.wspace`
- Width padding between subplots, expressed as a fraction of the
- subplot width. The total padding ends up being w_pad + wspace.
-
- hspace : float, default: :rc:`figure.constrained_layout.hspace`
- Height padding between subplots, expressed as a fraction of the
- subplot width. The total padding ends up being h_pad + hspace.
-
- """
- if isinstance(self.get_layout_engine(), ConstrainedLayoutEngine):
- self.get_layout_engine().set(**kwargs)
-
- @_api.deprecated("3.6", alternative="fig.get_layout_engine().get()",
- pending=True)
- def get_constrained_layout_pads(self, relative=False):
- """
- Get padding for ``constrained_layout``.
-
- Returns a list of ``w_pad, h_pad`` in inches and
- ``wspace`` and ``hspace`` as fractions of the subplot.
- All values are None if ``constrained_layout`` is not used.
-
- See :ref:`constrainedlayout_guide`.
-
- Parameters
- ----------
- relative : bool
- If `True`, then convert from inches to figure relative.
- """
- if not isinstance(self.get_layout_engine(), ConstrainedLayoutEngine):
- return None, None, None, None
- info = self.get_layout_engine().get()
- w_pad = info['w_pad']
- h_pad = info['h_pad']
- wspace = info['wspace']
- hspace = info['hspace']
-
- if relative and (w_pad is not None or h_pad is not None):
- renderer = self._get_renderer()
- dpi = renderer.dpi
- w_pad = w_pad * dpi / renderer.width
- h_pad = h_pad * dpi / renderer.height
-
- return w_pad, h_pad, wspace, hspace
-
- def set_canvas(self, canvas):
- """
- Set the canvas that contains the figure
-
- Parameters
- ----------
- canvas : FigureCanvas
- """
- self.canvas = canvas
-
- @_docstring.interpd
- def figimage(self, X, xo=0, yo=0, alpha=None, norm=None, cmap=None,
- vmin=None, vmax=None, origin=None, resize=False, **kwargs):
- """
- Add a non-resampled image to the figure.
-
- The image is attached to the lower or upper left corner depending on
- *origin*.
-
- Parameters
- ----------
- X
- The image data. This is an array of one of the following shapes:
-
- - (M, N): an image with scalar data. Color-mapping is controlled
- by *cmap*, *norm*, *vmin*, and *vmax*.
- - (M, N, 3): an image with RGB values (0-1 float or 0-255 int).
- - (M, N, 4): an image with RGBA values (0-1 float or 0-255 int),
- i.e. including transparency.
-
- xo, yo : int
- The *x*/*y* image offset in pixels.
-
- alpha : None or float
- The alpha blending value.
-
- %(cmap_doc)s
-
- This parameter is ignored if *X* is RGB(A).
-
- %(norm_doc)s
-
- This parameter is ignored if *X* is RGB(A).
-
- %(vmin_vmax_doc)s
-
- This parameter is ignored if *X* is RGB(A).
-
- origin : {'upper', 'lower'}, default: :rc:`image.origin`
- Indicates where the [0, 0] index of the array is in the upper left
- or lower left corner of the axes.
-
- resize : bool
- If *True*, resize the figure to match the given image size.
-
- Returns
- -------
- `matplotlib.image.FigureImage`
-
- Other Parameters
- ----------------
- **kwargs
- Additional kwargs are `.Artist` kwargs passed on to `.FigureImage`.
-
- Notes
- -----
- figimage complements the Axes image (`~matplotlib.axes.Axes.imshow`)
- which will be resampled to fit the current Axes. If you want
- a resampled image to fill the entire figure, you can define an
- `~matplotlib.axes.Axes` with extent [0, 0, 1, 1].
-
- Examples
- --------
- ::
-
- f = plt.figure()
- nx = int(f.get_figwidth() * f.dpi)
- ny = int(f.get_figheight() * f.dpi)
- data = np.random.random((ny, nx))
- f.figimage(data)
- plt.show()
- """
- if resize:
- dpi = self.get_dpi()
- figsize = [x / dpi for x in (X.shape[1], X.shape[0])]
- self.set_size_inches(figsize, forward=True)
-
- im = mimage.FigureImage(self, cmap=cmap, norm=norm,
- offsetx=xo, offsety=yo,
- origin=origin, **kwargs)
- im.stale_callback = _stale_figure_callback
-
- im.set_array(X)
- im.set_alpha(alpha)
- if norm is None:
- im.set_clim(vmin, vmax)
- self.images.append(im)
- im._remove_method = self.images.remove
- self.stale = True
- return im
-
- def set_size_inches(self, w, h=None, forward=True):
- """
- Set the figure size in inches.
-
- Call signatures::
-
- fig.set_size_inches(w, h) # OR
- fig.set_size_inches((w, h))
-
- Parameters
- ----------
- w : (float, float) or float
- Width and height in inches (if height not specified as a separate
- argument) or width.
- h : float
- Height in inches.
- forward : bool, default: True
- If ``True``, the canvas size is automatically updated, e.g.,
- you can resize the figure window from the shell.
-
- See Also
- --------
- matplotlib.figure.Figure.get_size_inches
- matplotlib.figure.Figure.set_figwidth
- matplotlib.figure.Figure.set_figheight
-
- Notes
- -----
- To transform from pixels to inches divide by `Figure.dpi`.
- """
- if h is None: # Got called with a single pair as argument.
- w, h = w
- size = np.array([w, h])
- if not np.isfinite(size).all() or (size < 0).any():
- raise ValueError(f'figure size must be positive finite not {size}')
- self.bbox_inches.p1 = size
- if forward:
- manager = self.canvas.manager
- if manager is not None:
- manager.resize(*(size * self.dpi).astype(int))
- self.stale = True
-
- def get_size_inches(self):
- """
- Return the current size of the figure in inches.
-
- Returns
- -------
- ndarray
- The size (width, height) of the figure in inches.
-
- See Also
- --------
- matplotlib.figure.Figure.set_size_inches
- matplotlib.figure.Figure.get_figwidth
- matplotlib.figure.Figure.get_figheight
-
- Notes
- -----
- The size in pixels can be obtained by multiplying with `Figure.dpi`.
- """
- return np.array(self.bbox_inches.p1)
-
- def get_figwidth(self):
- """Return the figure width in inches."""
- return self.bbox_inches.width
-
- def get_figheight(self):
- """Return the figure height in inches."""
- return self.bbox_inches.height
-
- def get_dpi(self):
- """Return the resolution in dots per inch as a float."""
- return self.dpi
-
- def set_dpi(self, val):
- """
- Set the resolution of the figure in dots-per-inch.
-
- Parameters
- ----------
- val : float
- """
- self.dpi = val
- self.stale = True
-
- def set_figwidth(self, val, forward=True):
- """
- Set the width of the figure in inches.
-
- Parameters
- ----------
- val : float
- forward : bool
- See `set_size_inches`.
-
- See Also
- --------
- matplotlib.figure.Figure.set_figheight
- matplotlib.figure.Figure.set_size_inches
- """
- self.set_size_inches(val, self.get_figheight(), forward=forward)
-
- def set_figheight(self, val, forward=True):
- """
- Set the height of the figure in inches.
-
- Parameters
- ----------
- val : float
- forward : bool
- See `set_size_inches`.
-
- See Also
- --------
- matplotlib.figure.Figure.set_figwidth
- matplotlib.figure.Figure.set_size_inches
- """
- self.set_size_inches(self.get_figwidth(), val, forward=forward)
-
- def clear(self, keep_observers=False):
- # docstring inherited
- super().clear(keep_observers=keep_observers)
- # FigureBase.clear does not clear toolbars, as
- # only Figure can have toolbars
- toolbar = self.canvas.toolbar
- if toolbar is not None:
- toolbar.update()
-
- @_finalize_rasterization
- @allow_rasterization
- def draw(self, renderer):
- # docstring inherited
- if not self.get_visible():
- return
-
- with self._render_lock:
-
- artists = self._get_draw_artists(renderer)
- try:
- renderer.open_group('figure', gid=self.get_gid())
- if self.axes and self.get_layout_engine() is not None:
- try:
- self.get_layout_engine().execute(self)
- except ValueError:
- pass
- # ValueError can occur when resizing a window.
-
- self.patch.draw(renderer)
- mimage._draw_list_compositing_images(
- renderer, self, artists, self.suppressComposite)
-
- for sfig in self.subfigs:
- sfig.draw(renderer)
-
- renderer.close_group('figure')
- finally:
- self.stale = False
-
- DrawEvent("draw_event", self.canvas, renderer)._process()
-
- def draw_without_rendering(self):
- """
- Draw the figure with no output. Useful to get the final size of
- artists that require a draw before their size is known (e.g. text).
- """
- renderer = _get_renderer(self)
- with renderer._draw_disabled():
- self.draw(renderer)
-
- def draw_artist(self, a):
- """
- Draw `.Artist` *a* only.
- """
- a.draw(self.canvas.get_renderer())
-
- def __getstate__(self):
- state = super().__getstate__()
-
- # The canvas cannot currently be pickled, but this has the benefit
- # of meaning that a figure can be detached from one canvas, and
- # re-attached to another.
- state.pop("canvas")
-
- # discard any changes to the dpi due to pixel ratio changes
- state["_dpi"] = state.get('_original_dpi', state['_dpi'])
-
- # add version information to the state
- state['__mpl_version__'] = mpl.__version__
-
- # check whether the figure manager (if any) is registered with pyplot
- from matplotlib import _pylab_helpers
- if self.canvas.manager in _pylab_helpers.Gcf.figs.values():
- state['_restore_to_pylab'] = True
- return state
-
- def __setstate__(self, state):
- version = state.pop('__mpl_version__')
- restore_to_pylab = state.pop('_restore_to_pylab', False)
-
- if version != mpl.__version__:
- _api.warn_external(
- f"This figure was saved with matplotlib version {version} and "
- f"is unlikely to function correctly.")
-
- self.__dict__ = state
-
- # re-initialise some of the unstored state information
- FigureCanvasBase(self) # Set self.canvas.
-
- if restore_to_pylab:
- # lazy import to avoid circularity
- import matplotlib.pyplot as plt
- import matplotlib._pylab_helpers as pylab_helpers
- allnums = plt.get_fignums()
- num = max(allnums) + 1 if allnums else 1
- backend = plt._get_backend_mod()
- mgr = backend.new_figure_manager_given_figure(num, self)
- pylab_helpers.Gcf._set_new_active_manager(mgr)
- plt.draw_if_interactive()
-
- self.stale = True
-
- def add_axobserver(self, func):
- """Whenever the Axes state change, ``func(self)`` will be called."""
- # Connect a wrapper lambda and not func itself, to avoid it being
- # weakref-collected.
- self._axobservers.connect("_axes_change_event", lambda arg: func(arg))
-
- def savefig(self, fname, *, transparent=None, **kwargs):
- """
- Save the current figure.
-
- Call signature::
-
- savefig(fname, *, transparent=None, dpi='figure', format=None,
- metadata=None, bbox_inches=None, pad_inches=0.1,
- facecolor='auto', edgecolor='auto', backend=None,
- **kwargs
- )
-
- The available output formats depend on the backend being used.
-
- Parameters
- ----------
- fname : str or path-like or binary file-like
- A path, or a Python file-like object, or
- possibly some backend-dependent object such as
- `matplotlib.backends.backend_pdf.PdfPages`.
-
- If *format* is set, it determines the output format, and the file
- is saved as *fname*. Note that *fname* is used verbatim, and there
- is no attempt to make the extension, if any, of *fname* match
- *format*, and no extension is appended.
-
- If *format* is not set, then the format is inferred from the
- extension of *fname*, if there is one. If *format* is not
- set and *fname* has no extension, then the file is saved with
- :rc:`savefig.format` and the appropriate extension is appended to
- *fname*.
-
- Other Parameters
- ----------------
- transparent : bool, default: :rc:`savefig.transparent`
- If *True*, the Axes patches will all be transparent; the
- Figure patch will also be transparent unless *facecolor*
- and/or *edgecolor* are specified via kwargs.
-
- If *False* has no effect and the color of the Axes and
- Figure patches are unchanged (unless the Figure patch
- is specified via the *facecolor* and/or *edgecolor* keyword
- arguments in which case those colors are used).
-
- The transparency of these patches will be restored to their
- original values upon exit of this function.
-
- This is useful, for example, for displaying
- a plot on top of a colored background on a web page.
-
- dpi : float or 'figure', default: :rc:`savefig.dpi`
- The resolution in dots per inch. If 'figure', use the figure's
- dpi value.
-
- format : str
- The file format, e.g. 'png', 'pdf', 'svg', ... The behavior when
- this is unset is documented under *fname*.
-
- metadata : dict, optional
- Key/value pairs to store in the image metadata. The supported keys
- and defaults depend on the image format and backend:
-
- - 'png' with Agg backend: See the parameter ``metadata`` of
- `~.FigureCanvasAgg.print_png`.
- - 'pdf' with pdf backend: See the parameter ``metadata`` of
- `~.backend_pdf.PdfPages`.
- - 'svg' with svg backend: See the parameter ``metadata`` of
- `~.FigureCanvasSVG.print_svg`.
- - 'eps' and 'ps' with PS backend: Only 'Creator' is supported.
-
- Not supported for 'pgf', 'raw', and 'rgba' as those formats do not support
- embedding metadata.
- Does not currently support 'jpg', 'tiff', or 'webp', but may include
- embedding EXIF metadata in the future.
-
- bbox_inches : str or `.Bbox`, default: :rc:`savefig.bbox`
- Bounding box in inches: only the given portion of the figure is
- saved. If 'tight', try to figure out the tight bbox of the figure.
-
- pad_inches : float or 'layout', default: :rc:`savefig.pad_inches`
- Amount of padding in inches around the figure when bbox_inches is
- 'tight'. If 'layout' use the padding from the constrained or
- compressed layout engine; ignored if one of those engines is not in
- use.
-
- facecolor : color or 'auto', default: :rc:`savefig.facecolor`
- The facecolor of the figure. If 'auto', use the current figure
- facecolor.
-
- edgecolor : color or 'auto', default: :rc:`savefig.edgecolor`
- The edgecolor of the figure. If 'auto', use the current figure
- edgecolor.
-
- backend : str, optional
- Use a non-default backend to render the file, e.g. to render a
- png file with the "cairo" backend rather than the default "agg",
- or a pdf file with the "pgf" backend rather than the default
- "pdf". Note that the default backend is normally sufficient. See
- :ref:`the-builtin-backends` for a list of valid backends for each
- file format. Custom backends can be referenced as "module://...".
-
- orientation : {'landscape', 'portrait'}
- Currently only supported by the postscript backend.
-
- papertype : str
- One of 'letter', 'legal', 'executive', 'ledger', 'a0' through
- 'a10', 'b0' through 'b10'. Only supported for postscript
- output.
-
- bbox_extra_artists : list of `~matplotlib.artist.Artist`, optional
- A list of extra artists that will be considered when the
- tight bbox is calculated.
-
- pil_kwargs : dict, optional
- Additional keyword arguments that are passed to
- `PIL.Image.Image.save` when saving the figure.
-
- """
-
- kwargs.setdefault('dpi', mpl.rcParams['savefig.dpi'])
- if transparent is None:
- transparent = mpl.rcParams['savefig.transparent']
-
- with ExitStack() as stack:
- if transparent:
- def _recursively_make_subfig_transparent(exit_stack, subfig):
- exit_stack.enter_context(
- subfig.patch._cm_set(
- facecolor="none", edgecolor="none"))
- for ax in subfig.axes:
- exit_stack.enter_context(
- ax.patch._cm_set(
- facecolor="none", edgecolor="none"))
- for sub_subfig in subfig.subfigs:
- _recursively_make_subfig_transparent(
- exit_stack, sub_subfig)
-
- def _recursively_make_axes_transparent(exit_stack, ax):
- exit_stack.enter_context(
- ax.patch._cm_set(facecolor="none", edgecolor="none"))
- for child_ax in ax.child_axes:
- exit_stack.enter_context(
- child_ax.patch._cm_set(
- facecolor="none", edgecolor="none"))
- for child_childax in ax.child_axes:
- _recursively_make_axes_transparent(
- exit_stack, child_childax)
-
- kwargs.setdefault('facecolor', 'none')
- kwargs.setdefault('edgecolor', 'none')
- # set subfigure to appear transparent in printed image
- for subfig in self.subfigs:
- _recursively_make_subfig_transparent(stack, subfig)
- # set axes to be transparent
- for ax in self.axes:
- _recursively_make_axes_transparent(stack, ax)
- self.canvas.print_figure(fname, **kwargs)
-
- def ginput(self, n=1, timeout=30, show_clicks=True,
- mouse_add=MouseButton.LEFT,
- mouse_pop=MouseButton.RIGHT,
- mouse_stop=MouseButton.MIDDLE):
- """
- Blocking call to interact with a figure.
-
- Wait until the user clicks *n* times on the figure, and return the
- coordinates of each click in a list.
-
- There are three possible interactions:
-
- - Add a point.
- - Remove the most recently added point.
- - Stop the interaction and return the points added so far.
-
- The actions are assigned to mouse buttons via the arguments
- *mouse_add*, *mouse_pop* and *mouse_stop*.
-
- Parameters
- ----------
- n : int, default: 1
- Number of mouse clicks to accumulate. If negative, accumulate
- clicks until the input is terminated manually.
- timeout : float, default: 30 seconds
- Number of seconds to wait before timing out. If zero or negative
- will never time out.
- show_clicks : bool, default: True
- If True, show a red cross at the location of each click.
- mouse_add : `.MouseButton` or None, default: `.MouseButton.LEFT`
- Mouse button used to add points.
- mouse_pop : `.MouseButton` or None, default: `.MouseButton.RIGHT`
- Mouse button used to remove the most recently added point.
- mouse_stop : `.MouseButton` or None, default: `.MouseButton.MIDDLE`
- Mouse button used to stop input.
-
- Returns
- -------
- list of tuples
- A list of the clicked (x, y) coordinates.
-
- Notes
- -----
- The keyboard can also be used to select points in case your mouse
- does not have one or more of the buttons. The delete and backspace
- keys act like right-clicking (i.e., remove last point), the enter key
- terminates input and any other key (not already used by the window
- manager) selects a point.
- """
- clicks = []
- marks = []
-
- def handler(event):
- is_button = event.name == "button_press_event"
- is_key = event.name == "key_press_event"
- # Quit (even if not in infinite mode; this is consistent with
- # MATLAB and sometimes quite useful, but will require the user to
- # test how many points were actually returned before using data).
- if (is_button and event.button == mouse_stop
- or is_key and event.key in ["escape", "enter"]):
- self.canvas.stop_event_loop()
- # Pop last click.
- elif (is_button and event.button == mouse_pop
- or is_key and event.key in ["backspace", "delete"]):
- if clicks:
- clicks.pop()
- if show_clicks:
- marks.pop().remove()
- self.canvas.draw()
- # Add new click.
- elif (is_button and event.button == mouse_add
- # On macOS/gtk, some keys return None.
- or is_key and event.key is not None):
- if event.inaxes:
- clicks.append((event.xdata, event.ydata))
- _log.info("input %i: %f, %f",
- len(clicks), event.xdata, event.ydata)
- if show_clicks:
- line = mpl.lines.Line2D([event.xdata], [event.ydata],
- marker="+", color="r")
- event.inaxes.add_line(line)
- marks.append(line)
- self.canvas.draw()
- if len(clicks) == n and n > 0:
- self.canvas.stop_event_loop()
-
- _blocking_input.blocking_input_loop(
- self, ["button_press_event", "key_press_event"], timeout, handler)
-
- # Cleanup.
- for mark in marks:
- mark.remove()
- self.canvas.draw()
-
- return clicks
-
- def waitforbuttonpress(self, timeout=-1):
- """
- Blocking call to interact with the figure.
-
- Wait for user input and return True if a key was pressed, False if a
- mouse button was pressed and None if no input was given within
- *timeout* seconds. Negative values deactivate *timeout*.
- """
- event = None
-
- def handler(ev):
- nonlocal event
- event = ev
- self.canvas.stop_event_loop()
-
- _blocking_input.blocking_input_loop(
- self, ["button_press_event", "key_press_event"], timeout, handler)
-
- return None if event is None else event.name == "key_press_event"
-
- def tight_layout(self, *, pad=1.08, h_pad=None, w_pad=None, rect=None):
- """
- Adjust the padding between and around subplots.
-
- To exclude an artist on the Axes from the bounding box calculation
- that determines the subplot parameters (i.e. legend, or annotation),
- set ``a.set_in_layout(False)`` for that artist.
-
- Parameters
- ----------
- pad : float, default: 1.08
- Padding between the figure edge and the edges of subplots,
- as a fraction of the font size.
- h_pad, w_pad : float, default: *pad*
- Padding (height/width) between edges of adjacent subplots,
- as a fraction of the font size.
- rect : tuple (left, bottom, right, top), default: (0, 0, 1, 1)
- A rectangle in normalized figure coordinates into which the whole
- subplots area (including labels) will fit.
-
- See Also
- --------
- .Figure.set_layout_engine
- .pyplot.tight_layout
- """
- # note that here we do not permanently set the figures engine to
- # tight_layout but rather just perform the layout in place and remove
- # any previous engines.
- engine = TightLayoutEngine(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
- try:
- previous_engine = self.get_layout_engine()
- self.set_layout_engine(engine)
- engine.execute(self)
- if previous_engine is not None and not isinstance(
- previous_engine, (TightLayoutEngine, PlaceHolderLayoutEngine)
- ):
- _api.warn_external('The figure layout has changed to tight')
- finally:
- self.set_layout_engine('none')
-
-
-def figaspect(arg):
- """
- Calculate the width and height for a figure with a specified aspect ratio.
-
- While the height is taken from :rc:`figure.figsize`, the width is
- adjusted to match the desired aspect ratio. Additionally, it is ensured
- that the width is in the range [4., 16.] and the height is in the range
- [2., 16.]. If necessary, the default height is adjusted to ensure this.
-
- Parameters
- ----------
- arg : float or 2D array
- If a float, this defines the aspect ratio (i.e. the ratio height /
- width).
- In case of an array the aspect ratio is number of rows / number of
- columns, so that the array could be fitted in the figure undistorted.
-
- Returns
- -------
- width, height : float
- The figure size in inches.
-
- Notes
- -----
- If you want to create an Axes within the figure, that still preserves the
- aspect ratio, be sure to create it with equal width and height. See
- examples below.
-
- Thanks to Fernando Perez for this function.
-
- Examples
- --------
- Make a figure twice as tall as it is wide::
-
- w, h = figaspect(2.)
- fig = Figure(figsize=(w, h))
- ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
- ax.imshow(A, **kwargs)
-
- Make a figure with the proper aspect for an array::
-
- A = rand(5, 3)
- w, h = figaspect(A)
- fig = Figure(figsize=(w, h))
- ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
- ax.imshow(A, **kwargs)
- """
-
- isarray = hasattr(arg, 'shape') and not np.isscalar(arg)
-
- # min/max sizes to respect when autoscaling. If John likes the idea, they
- # could become rc parameters, for now they're hardwired.
- figsize_min = np.array((4.0, 2.0)) # min length for width/height
- figsize_max = np.array((16.0, 16.0)) # max length for width/height
-
- # Extract the aspect ratio of the array
- if isarray:
- nr, nc = arg.shape[:2]
- arr_ratio = nr / nc
- else:
- arr_ratio = arg
-
- # Height of user figure defaults
- fig_height = mpl.rcParams['figure.figsize'][1]
-
- # New size for the figure, keeping the aspect ratio of the caller
- newsize = np.array((fig_height / arr_ratio, fig_height))
-
- # Sanity checks, don't drop either dimension below figsize_min
- newsize /= min(1.0, *(newsize / figsize_min))
-
- # Avoid humongous windows as well
- newsize /= max(1.0, *(newsize / figsize_max))
-
- # Finally, if we have a really funky aspect ratio, break it but respect
- # the min/max dimensions (we don't want figures 10 feet tall!)
- newsize = np.clip(newsize, figsize_min, figsize_max)
- return newsize
diff --git a/contrib/python/matplotlib/py3/matplotlib/figure.pyi b/contrib/python/matplotlib/py3/matplotlib/figure.pyi
deleted file mode 100644
index 887b6ed5d8..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/figure.pyi
+++ /dev/null
@@ -1,416 +0,0 @@
-from collections.abc import Callable, Hashable, Iterable
-import os
-from typing import Any, IO, Literal, TypeVar, overload
-
-import numpy as np
-from numpy.typing import ArrayLike
-
-from matplotlib.artist import Artist
-from matplotlib.axes import Axes, SubplotBase
-from matplotlib.backend_bases import (
- FigureCanvasBase,
- MouseButton,
- MouseEvent,
- RendererBase,
-)
-from matplotlib.colors import Colormap, Normalize
-from matplotlib.colorbar import Colorbar
-from matplotlib.cm import ScalarMappable
-from matplotlib.gridspec import GridSpec, SubplotSpec
-from matplotlib.image import _ImageBase, FigureImage
-from matplotlib.layout_engine import LayoutEngine
-from matplotlib.legend import Legend
-from matplotlib.lines import Line2D
-from matplotlib.patches import Rectangle, Patch
-from matplotlib.text import Text
-from matplotlib.transforms import Affine2D, Bbox, BboxBase, Transform
-from .typing import ColorType, HashableList
-
-_T = TypeVar("_T")
-
-class SubplotParams:
- def __init__(
- self,
- left: float | None = ...,
- bottom: float | None = ...,
- right: float | None = ...,
- top: float | None = ...,
- wspace: float | None = ...,
- hspace: float | None = ...,
- ) -> None: ...
- left: float
- right: float
- bottom: float
- top: float
- wspace: float
- hspace: float
- def update(
- self,
- left: float | None = ...,
- bottom: float | None = ...,
- right: float | None = ...,
- top: float | None = ...,
- wspace: float | None = ...,
- hspace: float | None = ...,
- ) -> None: ...
-
-class FigureBase(Artist):
- artists: list[Artist]
- lines: list[Line2D]
- patches: list[Patch]
- texts: list[Text]
- images: list[_ImageBase]
- legends: list[Legend]
- subfigs: list[SubFigure]
- stale: bool
- suppressComposite: bool | None
- def __init__(self, **kwargs) -> None: ...
- def autofmt_xdate(
- self,
- bottom: float = ...,
- rotation: int = ...,
- ha: Literal["left", "center", "right"] = ...,
- which: Literal["major", "minor", "both"] = ...,
- ) -> None: ...
- def get_children(self) -> list[Artist]: ...
- def contains(self, mouseevent: MouseEvent) -> tuple[bool, dict[Any, Any]]: ...
- def suptitle(self, t: str, **kwargs) -> Text: ...
- def get_suptitle(self) -> str: ...
- def supxlabel(self, t: str, **kwargs) -> Text: ...
- def get_supxlabel(self) -> str: ...
- def supylabel(self, t: str, **kwargs) -> Text: ...
- def get_supylabel(self) -> str: ...
- def get_edgecolor(self) -> ColorType: ...
- def get_facecolor(self) -> ColorType: ...
- def get_frameon(self) -> bool: ...
- def set_linewidth(self, linewidth: float) -> None: ...
- def get_linewidth(self) -> float: ...
- def set_edgecolor(self, color: ColorType) -> None: ...
- def set_facecolor(self, color: ColorType) -> None: ...
- def set_frameon(self, b: bool) -> None: ...
- @property
- def frameon(self) -> bool: ...
- @frameon.setter
- def frameon(self, b: bool) -> None: ...
- def add_artist(self, artist: Artist, clip: bool = ...) -> Artist: ...
- @overload
- def add_axes(self, ax: Axes) -> Axes: ...
- @overload
- def add_axes(
- self,
- rect: tuple[float, float, float, float],
- projection: None | str = ...,
- polar: bool = ...,
- **kwargs
- ) -> Axes: ...
-
- # TODO: docstring indicates SubplotSpec a valid arg, but none of the listed signatures appear to be that
- @overload
- def add_subplot(
- self, nrows: int, ncols: int, index: int | tuple[int, int], **kwargs
- ) -> Axes: ...
- @overload
- def add_subplot(self, pos: int, **kwargs) -> Axes: ...
- @overload
- def add_subplot(self, ax: Axes, **kwargs) -> Axes: ...
- @overload
- def add_subplot(self, ax: SubplotSpec, **kwargs) -> Axes: ...
- @overload
- def add_subplot(self, **kwargs) -> Axes: ...
- @overload
- def subplots(
- self,
- nrows: int = ...,
- ncols: int = ...,
- *,
- sharex: bool | Literal["none", "all", "row", "col"] = ...,
- sharey: bool | Literal["none", "all", "row", "col"] = ...,
- squeeze: Literal[False],
- width_ratios: ArrayLike | None = ...,
- height_ratios: ArrayLike | None = ...,
- subplot_kw: dict[str, Any] | None = ...,
- gridspec_kw: dict[str, Any] | None = ...
- ) -> np.ndarray: ...
- @overload
- def subplots(
- self,
- nrows: int = ...,
- ncols: int = ...,
- *,
- sharex: bool | Literal["none", "all", "row", "col"] = ...,
- sharey: bool | Literal["none", "all", "row", "col"] = ...,
- squeeze: bool = ...,
- width_ratios: ArrayLike | None = ...,
- height_ratios: ArrayLike | None = ...,
- subplot_kw: dict[str, Any] | None = ...,
- gridspec_kw: dict[str, Any] | None = ...
- ) -> np.ndarray | SubplotBase | Axes: ...
- def delaxes(self, ax: Axes) -> None: ...
- def clear(self, keep_observers: bool = ...) -> None: ...
- def clf(self, keep_observers: bool = ...) -> None: ...
-
- @overload
- def legend(self) -> Legend: ...
- @overload
- def legend(self, handles: Iterable[Artist], labels: Iterable[str], **kwargs) -> Legend: ...
- @overload
- def legend(self, *, handles: Iterable[Artist], **kwargs) -> Legend: ...
- @overload
- def legend(self, labels: Iterable[str], **kwargs) -> Legend: ...
- @overload
- def legend(self, **kwargs) -> Legend: ...
-
- def text(
- self,
- x: float,
- y: float,
- s: str,
- fontdict: dict[str, Any] | None = ...,
- **kwargs
- ) -> Text: ...
- def colorbar(
- self,
- mappable: ScalarMappable,
- cax: Axes | None = ...,
- ax: Axes | Iterable[Axes] | None = ...,
- use_gridspec: bool = ...,
- **kwargs
- ) -> Colorbar: ...
- def subplots_adjust(
- self,
- left: float | None = ...,
- bottom: float | None = ...,
- right: float | None = ...,
- top: float | None = ...,
- wspace: float | None = ...,
- hspace: float | None = ...,
- ) -> None: ...
- def align_xlabels(self, axs: Iterable[Axes] | None = ...) -> None: ...
- def align_ylabels(self, axs: Iterable[Axes] | None = ...) -> None: ...
- def align_labels(self, axs: Iterable[Axes] | None = ...) -> None: ...
- def add_gridspec(self, nrows: int = ..., ncols: int = ..., **kwargs) -> GridSpec: ...
- @overload
- def subfigures(
- self,
- nrows: int = ...,
- ncols: int = ...,
- squeeze: Literal[False] = ...,
- wspace: float | None = ...,
- hspace: float | None = ...,
- width_ratios: ArrayLike | None = ...,
- height_ratios: ArrayLike | None = ...,
- **kwargs
- ) -> np.ndarray: ...
- @overload
- def subfigures(
- self,
- nrows: int = ...,
- ncols: int = ...,
- squeeze: Literal[True] = ...,
- wspace: float | None = ...,
- hspace: float | None = ...,
- width_ratios: ArrayLike | None = ...,
- height_ratios: ArrayLike | None = ...,
- **kwargs
- ) -> np.ndarray | SubFigure: ...
- def add_subfigure(self, subplotspec: SubplotSpec, **kwargs) -> SubFigure: ...
- def sca(self, a: Axes) -> Axes: ...
- def gca(self) -> Axes: ...
- def _gci(self) -> ScalarMappable | None: ...
- def _process_projection_requirements(
- self, *, axes_class=None, polar=False, projection=None, **kwargs
- ) -> tuple[type[Axes], dict[str, Any]]: ...
- def get_default_bbox_extra_artists(self) -> list[Artist]: ...
- def get_tightbbox(
- self,
- renderer: RendererBase | None = ...,
- *,
- bbox_extra_artists: Iterable[Artist] | None = ...,
- ) -> Bbox: ...
- @overload
- def subplot_mosaic(
- self,
- mosaic: str,
- *,
- sharex: bool = ...,
- sharey: bool = ...,
- width_ratios: ArrayLike | None = ...,
- height_ratios: ArrayLike | None = ...,
- empty_sentinel: str = ...,
- subplot_kw: dict[str, Any] | None = ...,
- per_subplot_kw: dict[str | tuple[str, ...], dict[str, Any]] | None = ...,
- gridspec_kw: dict[str, Any] | None = ...,
- ) -> dict[str, Axes]: ...
- @overload
- def subplot_mosaic(
- self,
- mosaic: list[HashableList[_T]],
- *,
- sharex: bool = ...,
- sharey: bool = ...,
- width_ratios: ArrayLike | None = ...,
- height_ratios: ArrayLike | None = ...,
- empty_sentinel: _T = ...,
- subplot_kw: dict[str, Any] | None = ...,
- per_subplot_kw: dict[_T | tuple[_T, ...], dict[str, Any]] | None = ...,
- gridspec_kw: dict[str, Any] | None = ...,
- ) -> dict[_T, Axes]: ...
- @overload
- def subplot_mosaic(
- self,
- mosaic: list[HashableList[Hashable]],
- *,
- sharex: bool = ...,
- sharey: bool = ...,
- width_ratios: ArrayLike | None = ...,
- height_ratios: ArrayLike | None = ...,
- empty_sentinel: Any = ...,
- subplot_kw: dict[str, Any] | None = ...,
- per_subplot_kw: dict[Hashable | tuple[Hashable, ...], dict[str, Any]] | None = ...,
- gridspec_kw: dict[str, Any] | None = ...,
- ) -> dict[Hashable, Axes]: ...
-
-class SubFigure(FigureBase):
- figure: Figure
- subplotpars: SubplotParams
- dpi_scale_trans: Affine2D
- canvas: FigureCanvasBase
- transFigure: Transform
- bbox_relative: Bbox
- figbbox: BboxBase
- bbox: BboxBase
- transSubfigure: Transform
- patch: Rectangle
- def __init__(
- self,
- parent: Figure | SubFigure,
- subplotspec: SubplotSpec,
- *,
- facecolor: ColorType | None = ...,
- edgecolor: ColorType | None = ...,
- linewidth: float = ...,
- frameon: bool | None = ...,
- **kwargs
- ) -> None: ...
- @property
- def dpi(self) -> float: ...
- @dpi.setter
- def dpi(self, value: float) -> None: ...
- def get_dpi(self) -> float: ...
- def set_dpi(self, val) -> None: ...
- def get_constrained_layout(self) -> bool: ...
- def get_constrained_layout_pads(
- self, relative: bool = ...
- ) -> tuple[float, float, float, float]: ...
- def get_layout_engine(self) -> LayoutEngine: ...
- @property # type: ignore[misc]
- def axes(self) -> list[Axes]: ... # type: ignore[override]
- def get_axes(self) -> list[Axes]: ...
-
-class Figure(FigureBase):
- figure: Figure
- bbox_inches: Bbox
- dpi_scale_trans: Affine2D
- bbox: BboxBase
- figbbox: BboxBase
- transFigure: Transform
- transSubfigure: Transform
- patch: Rectangle
- subplotpars: SubplotParams
- def __init__(
- self,
- figsize: tuple[float, float] | None = ...,
- dpi: float | None = ...,
- *,
- facecolor: ColorType | None = ...,
- edgecolor: ColorType | None = ...,
- linewidth: float = ...,
- frameon: bool | None = ...,
- subplotpars: SubplotParams | None = ...,
- tight_layout: bool | dict[str, Any] | None = ...,
- constrained_layout: bool | dict[str, Any] | None = ...,
- layout: Literal["constrained", "compressed", "tight"]
- | LayoutEngine
- | None = ...,
- **kwargs
- ) -> None: ...
- def pick(self, mouseevent: MouseEvent) -> None: ...
- def set_layout_engine(
- self,
- layout: Literal["constrained", "compressed", "tight", "none"]
- | LayoutEngine
- | None = ...,
- **kwargs
- ) -> None: ...
- def get_layout_engine(self) -> LayoutEngine | None: ...
- def _repr_html_(self) -> str | None: ...
- def show(self, warn: bool = ...) -> None: ...
- @property # type: ignore[misc]
- def axes(self) -> list[Axes]: ... # type: ignore[override]
- def get_axes(self) -> list[Axes]: ...
- @property
- def dpi(self) -> float: ...
- @dpi.setter
- def dpi(self, dpi: float) -> None: ...
- def get_tight_layout(self) -> bool: ...
- def get_constrained_layout_pads(
- self, relative: bool = ...
- ) -> tuple[float, float, float, float]: ...
- def get_constrained_layout(self) -> bool: ...
- canvas: FigureCanvasBase
- def set_canvas(self, canvas: FigureCanvasBase) -> None: ...
- def figimage(
- self,
- X: ArrayLike,
- xo: int = ...,
- yo: int = ...,
- alpha: float | None = ...,
- norm: str | Normalize | None = ...,
- cmap: str | Colormap | None = ...,
- vmin: float | None = ...,
- vmax: float | None = ...,
- origin: Literal["upper", "lower"] | None = ...,
- resize: bool = ...,
- **kwargs
- ) -> FigureImage: ...
- def set_size_inches(
- self, w: float | tuple[float, float], h: float | None = ..., forward: bool = ...
- ) -> None: ...
- def get_size_inches(self) -> np.ndarray: ...
- def get_figwidth(self) -> float: ...
- def get_figheight(self) -> float: ...
- def get_dpi(self) -> float: ...
- def set_dpi(self, val: float) -> None: ...
- def set_figwidth(self, val: float, forward: bool = ...) -> None: ...
- def set_figheight(self, val: float, forward: bool = ...) -> None: ...
- def clear(self, keep_observers: bool = ...) -> None: ...
- def draw_without_rendering(self) -> None: ...
- def draw_artist(self, a: Artist) -> None: ...
- def add_axobserver(self, func: Callable[[Figure], Any]) -> None: ...
- def savefig(
- self,
- fname: str | os.PathLike | IO,
- *,
- transparent: bool | None = ...,
- **kwargs
- ) -> None: ...
- def ginput(
- self,
- n: int = ...,
- timeout: float = ...,
- show_clicks: bool = ...,
- mouse_add: MouseButton = ...,
- mouse_pop: MouseButton = ...,
- mouse_stop: MouseButton = ...,
- ) -> list[tuple[int, int]]: ...
- def waitforbuttonpress(self, timeout: float = ...) -> None | bool: ...
- def tight_layout(
- self,
- *,
- pad: float = ...,
- h_pad: float | None = ...,
- w_pad: float | None = ...,
- rect: tuple[float, float, float, float] | None = ...
- ) -> None: ...
-
-def figaspect(arg: float | ArrayLike) -> tuple[float, float]: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/font_manager.py b/contrib/python/matplotlib/py3/matplotlib/font_manager.py
deleted file mode 100644
index a91ca4ba45..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/font_manager.py
+++ /dev/null
@@ -1,1584 +0,0 @@
-"""
-A module for finding, managing, and using fonts across platforms.
-
-This module provides a single `FontManager` instance, ``fontManager``, that can
-be shared across backends and platforms. The `findfont`
-function returns the best TrueType (TTF) font file in the local or
-system font path that matches the specified `FontProperties`
-instance. The `FontManager` also handles Adobe Font Metrics
-(AFM) font files for use by the PostScript backend.
-The `FontManager.addfont` function adds a custom font from a file without
-installing it into your operating system.
-
-The design is based on the `W3C Cascading Style Sheet, Level 1 (CSS1)
-font specification <http://www.w3.org/TR/1998/REC-CSS2-19980512/>`_.
-Future versions may implement the Level 2 or 2.1 specifications.
-"""
-
-# KNOWN ISSUES
-#
-# - documentation
-# - font variant is untested
-# - font stretch is incomplete
-# - font size is incomplete
-# - default font algorithm needs improvement and testing
-# - setWeights function needs improvement
-# - 'light' is an invalid weight value, remove it.
-
-from base64 import b64encode
-from collections import namedtuple
-import copy
-import dataclasses
-from functools import lru_cache
-from io import BytesIO
-import json
-import logging
-from numbers import Number
-import os
-from pathlib import Path
-import re
-import subprocess
-import sys
-import threading
-from typing import Union
-
-import matplotlib as mpl
-from matplotlib import _api, _afm, cbook, ft2font
-from matplotlib._fontconfig_pattern import (
- parse_fontconfig_pattern, generate_fontconfig_pattern)
-from matplotlib.rcsetup import _validators
-
-_log = logging.getLogger(__name__)
-
-font_scalings = {
- 'xx-small': 0.579,
- 'x-small': 0.694,
- 'small': 0.833,
- 'medium': 1.0,
- 'large': 1.200,
- 'x-large': 1.440,
- 'xx-large': 1.728,
- 'larger': 1.2,
- 'smaller': 0.833,
- None: 1.0,
-}
-stretch_dict = {
- 'ultra-condensed': 100,
- 'extra-condensed': 200,
- 'condensed': 300,
- 'semi-condensed': 400,
- 'normal': 500,
- 'semi-expanded': 600,
- 'semi-extended': 600,
- 'expanded': 700,
- 'extended': 700,
- 'extra-expanded': 800,
- 'extra-extended': 800,
- 'ultra-expanded': 900,
- 'ultra-extended': 900,
-}
-weight_dict = {
- 'ultralight': 100,
- 'light': 200,
- 'normal': 400,
- 'regular': 400,
- 'book': 400,
- 'medium': 500,
- 'roman': 500,
- 'semibold': 600,
- 'demibold': 600,
- 'demi': 600,
- 'bold': 700,
- 'heavy': 800,
- 'extra bold': 800,
- 'black': 900,
-}
-_weight_regexes = [
- # From fontconfig's FcFreeTypeQueryFaceInternal; not the same as
- # weight_dict!
- ("thin", 100),
- ("extralight", 200),
- ("ultralight", 200),
- ("demilight", 350),
- ("semilight", 350),
- ("light", 300), # Needs to come *after* demi/semilight!
- ("book", 380),
- ("regular", 400),
- ("normal", 400),
- ("medium", 500),
- ("demibold", 600),
- ("demi", 600),
- ("semibold", 600),
- ("extrabold", 800),
- ("superbold", 800),
- ("ultrabold", 800),
- ("bold", 700), # Needs to come *after* extra/super/ultrabold!
- ("ultrablack", 1000),
- ("superblack", 1000),
- ("extrablack", 1000),
- (r"\bultra", 1000),
- ("black", 900), # Needs to come *after* ultra/super/extrablack!
- ("heavy", 900),
-]
-font_family_aliases = {
- 'serif',
- 'sans-serif',
- 'sans serif',
- 'cursive',
- 'fantasy',
- 'monospace',
- 'sans',
-}
-
-_ExceptionProxy = namedtuple('_ExceptionProxy', ['klass', 'message'])
-
-# OS Font paths
-try:
- _HOME = Path.home()
-except Exception: # Exceptions thrown by home() are not specified...
- _HOME = Path(os.devnull) # Just an arbitrary path with no children.
-MSFolders = \
- r'Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
-MSFontDirectories = [
- r'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts',
- r'SOFTWARE\Microsoft\Windows\CurrentVersion\Fonts']
-MSUserFontDirectories = [
- str(_HOME / 'AppData/Local/Microsoft/Windows/Fonts'),
- str(_HOME / 'AppData/Roaming/Microsoft/Windows/Fonts'),
-]
-X11FontDirectories = [
- # an old standard installation point
- "/usr/X11R6/lib/X11/fonts/TTF/",
- "/usr/X11/lib/X11/fonts",
- # here is the new standard location for fonts
- "/usr/share/fonts/",
- # documented as a good place to install new fonts
- "/usr/local/share/fonts/",
- # common application, not really useful
- "/usr/lib/openoffice/share/fonts/truetype/",
- # user fonts
- str((Path(os.environ.get('XDG_DATA_HOME') or _HOME / ".local/share"))
- / "fonts"),
- str(_HOME / ".fonts"),
-]
-OSXFontDirectories = [
- "/Library/Fonts/",
- "/Network/Library/Fonts/",
- "/System/Library/Fonts/",
- # fonts installed via MacPorts
- "/opt/local/share/fonts",
- # user fonts
- str(_HOME / "Library/Fonts"),
-]
-
-
-def get_fontext_synonyms(fontext):
- """
- Return a list of file extensions that are synonyms for
- the given file extension *fileext*.
- """
- return {
- 'afm': ['afm'],
- 'otf': ['otf', 'ttc', 'ttf'],
- 'ttc': ['otf', 'ttc', 'ttf'],
- 'ttf': ['otf', 'ttc', 'ttf'],
- }[fontext]
-
-
-def list_fonts(directory, extensions):
- """
- Return a list of all fonts matching any of the extensions, found
- recursively under the directory.
- """
- extensions = ["." + ext for ext in extensions]
- return [os.path.join(dirpath, filename)
- # os.walk ignores access errors, unlike Path.glob.
- for dirpath, _, filenames in os.walk(directory)
- for filename in filenames
- if Path(filename).suffix.lower() in extensions]
-
-
-def win32FontDirectory():
- r"""
- Return the user-specified font directory for Win32. This is
- looked up from the registry key ::
-
- \\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Fonts
-
- If the key is not found, ``%WINDIR%\Fonts`` will be returned.
- """
- import winreg
- try:
- with winreg.OpenKey(winreg.HKEY_CURRENT_USER, MSFolders) as user:
- return winreg.QueryValueEx(user, 'Fonts')[0]
- except OSError:
- return os.path.join(os.environ['WINDIR'], 'Fonts')
-
-
-def _get_win32_installed_fonts():
- """List the font paths known to the Windows registry."""
- import winreg
- items = set()
- # Search and resolve fonts listed in the registry.
- for domain, base_dirs in [
- (winreg.HKEY_LOCAL_MACHINE, [win32FontDirectory()]), # System.
- (winreg.HKEY_CURRENT_USER, MSUserFontDirectories), # User.
- ]:
- for base_dir in base_dirs:
- for reg_path in MSFontDirectories:
- try:
- with winreg.OpenKey(domain, reg_path) as local:
- for j in range(winreg.QueryInfoKey(local)[1]):
- # value may contain the filename of the font or its
- # absolute path.
- key, value, tp = winreg.EnumValue(local, j)
- if not isinstance(value, str):
- continue
- try:
- # If value contains already an absolute path,
- # then it is not changed further.
- path = Path(base_dir, value).resolve()
- except RuntimeError:
- # Don't fail with invalid entries.
- continue
- items.add(path)
- except (OSError, MemoryError):
- continue
- return items
-
-
-@lru_cache
-def _get_fontconfig_fonts():
- """Cache and list the font paths known to ``fc-list``."""
- try:
- if b'--format' not in subprocess.check_output(['fc-list', '--help']):
- _log.warning( # fontconfig 2.7 implemented --format.
- 'Matplotlib needs fontconfig>=2.7 to query system fonts.')
- return []
- out = subprocess.check_output(['fc-list', '--format=%{file}\\n'])
- except (OSError, subprocess.CalledProcessError):
- return []
- return [Path(os.fsdecode(fname)) for fname in out.split(b'\n')]
-
-
-def findSystemFonts(fontpaths=None, fontext='ttf'):
- """
- Search for fonts in the specified font paths. If no paths are
- given, will use a standard set of system paths, as well as the
- list of fonts tracked by fontconfig if fontconfig is installed and
- available. A list of TrueType fonts are returned by default with
- AFM fonts as an option.
- """
- fontfiles = set()
- fontexts = get_fontext_synonyms(fontext)
-
- if fontpaths is None:
- if sys.platform == 'win32':
- installed_fonts = _get_win32_installed_fonts()
- fontpaths = []
- else:
- installed_fonts = _get_fontconfig_fonts()
- if sys.platform == 'darwin':
- fontpaths = [*X11FontDirectories, *OSXFontDirectories]
- else:
- fontpaths = X11FontDirectories
- fontfiles.update(str(path) for path in installed_fonts
- if path.suffix.lower()[1:] in fontexts)
-
- elif isinstance(fontpaths, str):
- fontpaths = [fontpaths]
-
- for path in fontpaths:
- fontfiles.update(map(os.path.abspath, list_fonts(path, fontexts)))
-
- return [fname for fname in fontfiles if os.path.exists(fname)]
-
-
-def _fontentry_helper_repr_png(fontent):
- from matplotlib.figure import Figure # Circular import.
- fig = Figure()
- font_path = Path(fontent.fname) if fontent.fname != '' else None
- fig.text(0, 0, fontent.name, font=font_path)
- with BytesIO() as buf:
- fig.savefig(buf, bbox_inches='tight', transparent=True)
- return buf.getvalue()
-
-
-def _fontentry_helper_repr_html(fontent):
- png_stream = _fontentry_helper_repr_png(fontent)
- png_b64 = b64encode(png_stream).decode()
- return f"<img src=\"data:image/png;base64, {png_b64}\" />"
-
-
-FontEntry = dataclasses.make_dataclass(
- 'FontEntry', [
- ('fname', str, dataclasses.field(default='')),
- ('name', str, dataclasses.field(default='')),
- ('style', str, dataclasses.field(default='normal')),
- ('variant', str, dataclasses.field(default='normal')),
- ('weight', Union[str, int], dataclasses.field(default='normal')),
- ('stretch', str, dataclasses.field(default='normal')),
- ('size', str, dataclasses.field(default='medium')),
- ],
- namespace={
- '__doc__': """
- A class for storing Font properties.
-
- It is used when populating the font lookup dictionary.
- """,
- '_repr_html_': lambda self: _fontentry_helper_repr_html(self),
- '_repr_png_': lambda self: _fontentry_helper_repr_png(self),
- }
-)
-
-
-def ttfFontProperty(font):
- """
- Extract information from a TrueType font file.
-
- Parameters
- ----------
- font : `.FT2Font`
- The TrueType font file from which information will be extracted.
-
- Returns
- -------
- `FontEntry`
- The extracted font properties.
-
- """
- name = font.family_name
-
- # Styles are: italic, oblique, and normal (default)
-
- sfnt = font.get_sfnt()
- mac_key = (1, # platform: macintosh
- 0, # id: roman
- 0) # langid: english
- ms_key = (3, # platform: microsoft
- 1, # id: unicode_cs
- 0x0409) # langid: english_united_states
-
- # These tables are actually mac_roman-encoded, but mac_roman support may be
- # missing in some alternative Python implementations and we are only going
- # to look for ASCII substrings, where any ASCII-compatible encoding works
- # - or big-endian UTF-16, since important Microsoft fonts use that.
- sfnt2 = (sfnt.get((*mac_key, 2), b'').decode('latin-1').lower() or
- sfnt.get((*ms_key, 2), b'').decode('utf_16_be').lower())
- sfnt4 = (sfnt.get((*mac_key, 4), b'').decode('latin-1').lower() or
- sfnt.get((*ms_key, 4), b'').decode('utf_16_be').lower())
-
- if sfnt4.find('oblique') >= 0:
- style = 'oblique'
- elif sfnt4.find('italic') >= 0:
- style = 'italic'
- elif sfnt2.find('regular') >= 0:
- style = 'normal'
- elif font.style_flags & ft2font.ITALIC:
- style = 'italic'
- else:
- style = 'normal'
-
- # Variants are: small-caps and normal (default)
-
- # !!!! Untested
- if name.lower() in ['capitals', 'small-caps']:
- variant = 'small-caps'
- else:
- variant = 'normal'
-
- # The weight-guessing algorithm is directly translated from fontconfig
- # 2.13.1's FcFreeTypeQueryFaceInternal (fcfreetype.c).
- wws_subfamily = 22
- typographic_subfamily = 16
- font_subfamily = 2
- styles = [
- sfnt.get((*mac_key, wws_subfamily), b'').decode('latin-1'),
- sfnt.get((*mac_key, typographic_subfamily), b'').decode('latin-1'),
- sfnt.get((*mac_key, font_subfamily), b'').decode('latin-1'),
- sfnt.get((*ms_key, wws_subfamily), b'').decode('utf-16-be'),
- sfnt.get((*ms_key, typographic_subfamily), b'').decode('utf-16-be'),
- sfnt.get((*ms_key, font_subfamily), b'').decode('utf-16-be'),
- ]
- styles = [*filter(None, styles)] or [font.style_name]
-
- def get_weight(): # From fontconfig's FcFreeTypeQueryFaceInternal.
- # OS/2 table weight.
- os2 = font.get_sfnt_table("OS/2")
- if os2 and os2["version"] != 0xffff:
- return os2["usWeightClass"]
- # PostScript font info weight.
- try:
- ps_font_info_weight = (
- font.get_ps_font_info()["weight"].replace(" ", "") or "")
- except ValueError:
- pass
- else:
- for regex, weight in _weight_regexes:
- if re.fullmatch(regex, ps_font_info_weight, re.I):
- return weight
- # Style name weight.
- for style in styles:
- style = style.replace(" ", "")
- for regex, weight in _weight_regexes:
- if re.search(regex, style, re.I):
- return weight
- if font.style_flags & ft2font.BOLD:
- return 700 # "bold"
- return 500 # "medium", not "regular"!
-
- weight = int(get_weight())
-
- # Stretch can be absolute and relative
- # Absolute stretches are: ultra-condensed, extra-condensed, condensed,
- # semi-condensed, normal, semi-expanded, expanded, extra-expanded,
- # and ultra-expanded.
- # Relative stretches are: wider, narrower
- # Child value is: inherit
-
- if any(word in sfnt4 for word in ['narrow', 'condensed', 'cond']):
- stretch = 'condensed'
- elif 'demi cond' in sfnt4:
- stretch = 'semi-condensed'
- elif any(word in sfnt4 for word in ['wide', 'expanded', 'extended']):
- stretch = 'expanded'
- else:
- stretch = 'normal'
-
- # Sizes can be absolute and relative.
- # Absolute sizes are: xx-small, x-small, small, medium, large, x-large,
- # and xx-large.
- # Relative sizes are: larger, smaller
- # Length value is an absolute font size, e.g., 12pt
- # Percentage values are in 'em's. Most robust specification.
-
- if not font.scalable:
- raise NotImplementedError("Non-scalable fonts are not supported")
- size = 'scalable'
-
- return FontEntry(font.fname, name, style, variant, weight, stretch, size)
-
-
-def afmFontProperty(fontpath, font):
- """
- Extract information from an AFM font file.
-
- Parameters
- ----------
- fontpath : str
- The filename corresponding to *font*.
- font : AFM
- The AFM font file from which information will be extracted.
-
- Returns
- -------
- `FontEntry`
- The extracted font properties.
- """
-
- name = font.get_familyname()
- fontname = font.get_fontname().lower()
-
- # Styles are: italic, oblique, and normal (default)
-
- if font.get_angle() != 0 or 'italic' in name.lower():
- style = 'italic'
- elif 'oblique' in name.lower():
- style = 'oblique'
- else:
- style = 'normal'
-
- # Variants are: small-caps and normal (default)
-
- # !!!! Untested
- if name.lower() in ['capitals', 'small-caps']:
- variant = 'small-caps'
- else:
- variant = 'normal'
-
- weight = font.get_weight().lower()
- if weight not in weight_dict:
- weight = 'normal'
-
- # Stretch can be absolute and relative
- # Absolute stretches are: ultra-condensed, extra-condensed, condensed,
- # semi-condensed, normal, semi-expanded, expanded, extra-expanded,
- # and ultra-expanded.
- # Relative stretches are: wider, narrower
- # Child value is: inherit
- if 'demi cond' in fontname:
- stretch = 'semi-condensed'
- elif any(word in fontname for word in ['narrow', 'cond']):
- stretch = 'condensed'
- elif any(word in fontname for word in ['wide', 'expanded', 'extended']):
- stretch = 'expanded'
- else:
- stretch = 'normal'
-
- # Sizes can be absolute and relative.
- # Absolute sizes are: xx-small, x-small, small, medium, large, x-large,
- # and xx-large.
- # Relative sizes are: larger, smaller
- # Length value is an absolute font size, e.g., 12pt
- # Percentage values are in 'em's. Most robust specification.
-
- # All AFM fonts are apparently scalable.
-
- size = 'scalable'
-
- return FontEntry(fontpath, name, style, variant, weight, stretch, size)
-
-
-class FontProperties:
- """
- A class for storing and manipulating font properties.
-
- The font properties are the six properties described in the
- `W3C Cascading Style Sheet, Level 1
- <http://www.w3.org/TR/1998/REC-CSS2-19980512/>`_ font
- specification and *math_fontfamily* for math fonts:
-
- - family: A list of font names in decreasing order of priority.
- The items may include a generic font family name, either 'sans-serif',
- 'serif', 'cursive', 'fantasy', or 'monospace'. In that case, the actual
- font to be used will be looked up from the associated rcParam during the
- search process in `.findfont`. Default: :rc:`font.family`
-
- - style: Either 'normal', 'italic' or 'oblique'.
- Default: :rc:`font.style`
-
- - variant: Either 'normal' or 'small-caps'.
- Default: :rc:`font.variant`
-
- - stretch: A numeric value in the range 0-1000 or one of
- 'ultra-condensed', 'extra-condensed', 'condensed',
- 'semi-condensed', 'normal', 'semi-expanded', 'expanded',
- 'extra-expanded' or 'ultra-expanded'. Default: :rc:`font.stretch`
-
- - weight: A numeric value in the range 0-1000 or one of
- 'ultralight', 'light', 'normal', 'regular', 'book', 'medium',
- 'roman', 'semibold', 'demibold', 'demi', 'bold', 'heavy',
- 'extra bold', 'black'. Default: :rc:`font.weight`
-
- - size: Either a relative value of 'xx-small', 'x-small',
- 'small', 'medium', 'large', 'x-large', 'xx-large' or an
- absolute font size, e.g., 10. Default: :rc:`font.size`
-
- - math_fontfamily: The family of fonts used to render math text.
- Supported values are: 'dejavusans', 'dejavuserif', 'cm',
- 'stix', 'stixsans' and 'custom'. Default: :rc:`mathtext.fontset`
-
- Alternatively, a font may be specified using the absolute path to a font
- file, by using the *fname* kwarg. However, in this case, it is typically
- simpler to just pass the path (as a `pathlib.Path`, not a `str`) to the
- *font* kwarg of the `.Text` object.
-
- The preferred usage of font sizes is to use the relative values,
- e.g., 'large', instead of absolute font sizes, e.g., 12. This
- approach allows all text sizes to be made larger or smaller based
- on the font manager's default font size.
-
- This class will also accept a fontconfig_ pattern_, if it is the only
- argument provided. This support does not depend on fontconfig; we are
- merely borrowing its pattern syntax for use here.
-
- .. _fontconfig: https://www.freedesktop.org/wiki/Software/fontconfig/
- .. _pattern:
- https://www.freedesktop.org/software/fontconfig/fontconfig-user.html
-
- Note that Matplotlib's internal font manager and fontconfig use a
- different algorithm to lookup fonts, so the results of the same pattern
- may be different in Matplotlib than in other applications that use
- fontconfig.
- """
-
- def __init__(self, family=None, style=None, variant=None, weight=None,
- stretch=None, size=None,
- fname=None, # if set, it's a hardcoded filename to use
- math_fontfamily=None):
- self.set_family(family)
- self.set_style(style)
- self.set_variant(variant)
- self.set_weight(weight)
- self.set_stretch(stretch)
- self.set_file(fname)
- self.set_size(size)
- self.set_math_fontfamily(math_fontfamily)
- # Treat family as a fontconfig pattern if it is the only parameter
- # provided. Even in that case, call the other setters first to set
- # attributes not specified by the pattern to the rcParams defaults.
- if (isinstance(family, str)
- and style is None and variant is None and weight is None
- and stretch is None and size is None and fname is None):
- self.set_fontconfig_pattern(family)
-
- @classmethod
- def _from_any(cls, arg):
- """
- Generic constructor which can build a `.FontProperties` from any of the
- following:
-
- - a `.FontProperties`: it is passed through as is;
- - `None`: a `.FontProperties` using rc values is used;
- - an `os.PathLike`: it is used as path to the font file;
- - a `str`: it is parsed as a fontconfig pattern;
- - a `dict`: it is passed as ``**kwargs`` to `.FontProperties`.
- """
- if arg is None:
- return cls()
- elif isinstance(arg, cls):
- return arg
- elif isinstance(arg, os.PathLike):
- return cls(fname=arg)
- elif isinstance(arg, str):
- return cls(arg)
- else:
- return cls(**arg)
-
- def __hash__(self):
- l = (tuple(self.get_family()),
- self.get_slant(),
- self.get_variant(),
- self.get_weight(),
- self.get_stretch(),
- self.get_size(),
- self.get_file(),
- self.get_math_fontfamily())
- return hash(l)
-
- def __eq__(self, other):
- return hash(self) == hash(other)
-
- def __str__(self):
- return self.get_fontconfig_pattern()
-
- def get_family(self):
- """
- Return a list of individual font family names or generic family names.
-
- The font families or generic font families (which will be resolved
- from their respective rcParams when searching for a matching font) in
- the order of preference.
- """
- return self._family
-
- def get_name(self):
- """
- Return the name of the font that best matches the font properties.
- """
- return get_font(findfont(self)).family_name
-
- def get_style(self):
- """
- Return the font style. Values are: 'normal', 'italic' or 'oblique'.
- """
- return self._slant
-
- def get_variant(self):
- """
- Return the font variant. Values are: 'normal' or 'small-caps'.
- """
- return self._variant
-
- def get_weight(self):
- """
- Set the font weight. Options are: A numeric value in the
- range 0-1000 or one of 'light', 'normal', 'regular', 'book',
- 'medium', 'roman', 'semibold', 'demibold', 'demi', 'bold',
- 'heavy', 'extra bold', 'black'
- """
- return self._weight
-
- def get_stretch(self):
- """
- Return the font stretch or width. Options are: 'ultra-condensed',
- 'extra-condensed', 'condensed', 'semi-condensed', 'normal',
- 'semi-expanded', 'expanded', 'extra-expanded', 'ultra-expanded'.
- """
- return self._stretch
-
- def get_size(self):
- """
- Return the font size.
- """
- return self._size
-
- def get_file(self):
- """
- Return the filename of the associated font.
- """
- return self._file
-
- def get_fontconfig_pattern(self):
- """
- Get a fontconfig_ pattern_ suitable for looking up the font as
- specified with fontconfig's ``fc-match`` utility.
-
- This support does not depend on fontconfig; we are merely borrowing its
- pattern syntax for use here.
- """
- return generate_fontconfig_pattern(self)
-
- def set_family(self, family):
- """
- Change the font family. Can be either an alias (generic name
- is CSS parlance), such as: 'serif', 'sans-serif', 'cursive',
- 'fantasy', or 'monospace', a real font name or a list of real
- font names. Real font names are not supported when
- :rc:`text.usetex` is `True`. Default: :rc:`font.family`
- """
- if family is None:
- family = mpl.rcParams['font.family']
- if isinstance(family, str):
- family = [family]
- self._family = family
-
- def set_style(self, style):
- """
- Set the font style.
-
- Parameters
- ----------
- style : {'normal', 'italic', 'oblique'}, default: :rc:`font.style`
- """
- if style is None:
- style = mpl.rcParams['font.style']
- _api.check_in_list(['normal', 'italic', 'oblique'], style=style)
- self._slant = style
-
- def set_variant(self, variant):
- """
- Set the font variant.
-
- Parameters
- ----------
- variant : {'normal', 'small-caps'}, default: :rc:`font.variant`
- """
- if variant is None:
- variant = mpl.rcParams['font.variant']
- _api.check_in_list(['normal', 'small-caps'], variant=variant)
- self._variant = variant
-
- def set_weight(self, weight):
- """
- Set the font weight.
-
- Parameters
- ----------
- weight : int or {'ultralight', 'light', 'normal', 'regular', 'book', \
-'medium', 'roman', 'semibold', 'demibold', 'demi', 'bold', 'heavy', \
-'extra bold', 'black'}, default: :rc:`font.weight`
- If int, must be in the range 0-1000.
- """
- if weight is None:
- weight = mpl.rcParams['font.weight']
- if weight in weight_dict:
- self._weight = weight
- return
- try:
- weight = int(weight)
- except ValueError:
- pass
- else:
- if 0 <= weight <= 1000:
- self._weight = weight
- return
- raise ValueError(f"{weight=} is invalid")
-
- def set_stretch(self, stretch):
- """
- Set the font stretch or width.
-
- Parameters
- ----------
- stretch : int or {'ultra-condensed', 'extra-condensed', 'condensed', \
-'semi-condensed', 'normal', 'semi-expanded', 'expanded', 'extra-expanded', \
-'ultra-expanded'}, default: :rc:`font.stretch`
- If int, must be in the range 0-1000.
- """
- if stretch is None:
- stretch = mpl.rcParams['font.stretch']
- if stretch in stretch_dict:
- self._stretch = stretch
- return
- try:
- stretch = int(stretch)
- except ValueError:
- pass
- else:
- if 0 <= stretch <= 1000:
- self._stretch = stretch
- return
- raise ValueError(f"{stretch=} is invalid")
-
- def set_size(self, size):
- """
- Set the font size.
-
- Parameters
- ----------
- size : float or {'xx-small', 'x-small', 'small', 'medium', \
-'large', 'x-large', 'xx-large'}, default: :rc:`font.size`
- If a float, the font size in points. The string values denote
- sizes relative to the default font size.
- """
- if size is None:
- size = mpl.rcParams['font.size']
- try:
- size = float(size)
- except ValueError:
- try:
- scale = font_scalings[size]
- except KeyError as err:
- raise ValueError(
- "Size is invalid. Valid font size are "
- + ", ".join(map(str, font_scalings))) from err
- else:
- size = scale * FontManager.get_default_size()
- if size < 1.0:
- _log.info('Fontsize %1.2f < 1.0 pt not allowed by FreeType. '
- 'Setting fontsize = 1 pt', size)
- size = 1.0
- self._size = size
-
- def set_file(self, file):
- """
- Set the filename of the fontfile to use. In this case, all
- other properties will be ignored.
- """
- self._file = os.fspath(file) if file is not None else None
-
- def set_fontconfig_pattern(self, pattern):
- """
- Set the properties by parsing a fontconfig_ *pattern*.
-
- This support does not depend on fontconfig; we are merely borrowing its
- pattern syntax for use here.
- """
- for key, val in parse_fontconfig_pattern(pattern).items():
- if type(val) is list:
- getattr(self, "set_" + key)(val[0])
- else:
- getattr(self, "set_" + key)(val)
-
- def get_math_fontfamily(self):
- """
- Return the name of the font family used for math text.
-
- The default font is :rc:`mathtext.fontset`.
- """
- return self._math_fontfamily
-
- def set_math_fontfamily(self, fontfamily):
- """
- Set the font family for text in math mode.
-
- If not set explicitly, :rc:`mathtext.fontset` will be used.
-
- Parameters
- ----------
- fontfamily : str
- The name of the font family.
-
- Available font families are defined in the
- :ref:`default matplotlibrc file <customizing-with-matplotlibrc-files>`.
-
- See Also
- --------
- .text.Text.get_math_fontfamily
- """
- if fontfamily is None:
- fontfamily = mpl.rcParams['mathtext.fontset']
- else:
- valid_fonts = _validators['mathtext.fontset'].valid.values()
- # _check_in_list() Validates the parameter math_fontfamily as
- # if it were passed to rcParams['mathtext.fontset']
- _api.check_in_list(valid_fonts, math_fontfamily=fontfamily)
- self._math_fontfamily = fontfamily
-
- def copy(self):
- """Return a copy of self."""
- return copy.copy(self)
-
- # Aliases
- set_name = set_family
- get_slant = get_style
- set_slant = set_style
- get_size_in_points = get_size
-
-
-class _JSONEncoder(json.JSONEncoder):
- def default(self, o):
- if isinstance(o, FontManager):
- return dict(o.__dict__, __class__='FontManager')
- elif isinstance(o, FontEntry):
- d = dict(o.__dict__, __class__='FontEntry')
- try:
- # Cache paths of fonts shipped with Matplotlib relative to the
- # Matplotlib data path, which helps in the presence of venvs.
- d["fname"] = str(
- Path(d["fname"]).relative_to(mpl.get_data_path()))
- except ValueError:
- pass
- return d
- else:
- return super().default(o)
-
-
-def _json_decode(o):
- cls = o.pop('__class__', None)
- if cls is None:
- return o
- elif cls == 'FontManager':
- r = FontManager.__new__(FontManager)
- r.__dict__.update(o)
- return r
- elif cls == 'FontEntry':
- r = FontEntry.__new__(FontEntry)
- r.__dict__.update(o)
- if not os.path.isabs(r.fname):
- r.fname = os.path.join(mpl.get_data_path(), r.fname)
- return r
- else:
- raise ValueError("Don't know how to deserialize __class__=%s" % cls)
-
-
-def json_dump(data, filename):
- """
- Dump `FontManager` *data* as JSON to the file named *filename*.
-
- See Also
- --------
- json_load
-
- Notes
- -----
- File paths that are children of the Matplotlib data path (typically, fonts
- shipped with Matplotlib) are stored relative to that data path (to remain
- valid across virtualenvs).
-
- This function temporarily locks the output file to prevent multiple
- processes from overwriting one another's output.
- """
- with cbook._lock_path(filename), open(filename, 'w') as fh:
- try:
- json.dump(data, fh, cls=_JSONEncoder, indent=2)
- except OSError as e:
- _log.warning('Could not save font_manager cache %s', e)
-
-
-def json_load(filename):
- """
- Load a `FontManager` from the JSON file named *filename*.
-
- See Also
- --------
- json_dump
- """
- with open(filename) as fh:
- return json.load(fh, object_hook=_json_decode)
-
-
-class FontManager:
- """
- On import, the `FontManager` singleton instance creates a list of ttf and
- afm fonts and caches their `FontProperties`. The `FontManager.findfont`
- method does a nearest neighbor search to find the font that most closely
- matches the specification. If no good enough match is found, the default
- font is returned.
-
- Fonts added with the `FontManager.addfont` method will not persist in the
- cache; therefore, `addfont` will need to be called every time Matplotlib is
- imported. This method should only be used if and when a font cannot be
- installed on your operating system by other means.
-
- Notes
- -----
- The `FontManager.addfont` method must be called on the global `FontManager`
- instance.
-
- Example usage::
-
- import matplotlib.pyplot as plt
- from matplotlib import font_manager
-
- font_dirs = ["/resources/fonts"] # The path to the custom font file.
- font_files = font_manager.findSystemFonts(fontpaths=font_dirs)
-
- for font_file in font_files:
- font_manager.fontManager.addfont(font_file)
- """
- # Increment this version number whenever the font cache data
- # format or behavior has changed and requires an existing font
- # cache files to be rebuilt.
- __version__ = 330
-
- def __init__(self, size=None, weight='normal'):
- self._version = self.__version__
-
- self.__default_weight = weight
- self.default_size = size
-
- # Create list of font paths.
- paths = [cbook._get_data_path('fonts', subdir)
- for subdir in ['ttf', 'afm', 'pdfcorefonts']]
- _log.debug('font search path %s', paths)
-
- self.defaultFamily = {
- 'ttf': 'DejaVu Sans',
- 'afm': 'Helvetica'}
-
- self.afmlist = []
- self.ttflist = []
-
- # Delay the warning by 5s.
- timer = threading.Timer(5, lambda: _log.warning(
- 'Matplotlib is building the font cache; this may take a moment.'))
- timer.start()
- try:
- for fontext in ["afm", "ttf"]:
- for path in [*findSystemFonts(paths, fontext=fontext),
- *findSystemFonts(fontext=fontext)]:
- try:
- self.addfont(path)
- except OSError as exc:
- _log.info("Failed to open font file %s: %s", path, exc)
- except Exception as exc:
- _log.info("Failed to extract font properties from %s: "
- "%s", path, exc)
- finally:
- timer.cancel()
-
- def addfont(self, path):
- """
- Cache the properties of the font at *path* to make it available to the
- `FontManager`. The type of font is inferred from the path suffix.
-
- Parameters
- ----------
- path : str or path-like
-
- Notes
- -----
- This method is useful for adding a custom font without installing it in
- your operating system. See the `FontManager` singleton instance for
- usage and caveats about this function.
- """
- # Convert to string in case of a path as
- # afmFontProperty and FT2Font expect this
- path = os.fsdecode(path)
- if Path(path).suffix.lower() == ".afm":
- with open(path, "rb") as fh:
- font = _afm.AFM(fh)
- prop = afmFontProperty(path, font)
- self.afmlist.append(prop)
- else:
- font = ft2font.FT2Font(path)
- prop = ttfFontProperty(font)
- self.ttflist.append(prop)
- self._findfont_cached.cache_clear()
-
- @property
- def defaultFont(self):
- # Lazily evaluated (findfont then caches the result) to avoid including
- # the venv path in the json serialization.
- return {ext: self.findfont(family, fontext=ext)
- for ext, family in self.defaultFamily.items()}
-
- def get_default_weight(self):
- """
- Return the default font weight.
- """
- return self.__default_weight
-
- @staticmethod
- def get_default_size():
- """
- Return the default font size.
- """
- return mpl.rcParams['font.size']
-
- def set_default_weight(self, weight):
- """
- Set the default font weight. The initial value is 'normal'.
- """
- self.__default_weight = weight
-
- @staticmethod
- def _expand_aliases(family):
- if family in ('sans', 'sans serif'):
- family = 'sans-serif'
- return mpl.rcParams['font.' + family]
-
- # Each of the scoring functions below should return a value between
- # 0.0 (perfect match) and 1.0 (terrible match)
- def score_family(self, families, family2):
- """
- Return a match score between the list of font families in
- *families* and the font family name *family2*.
-
- An exact match at the head of the list returns 0.0.
-
- A match further down the list will return between 0 and 1.
-
- No match will return 1.0.
- """
- if not isinstance(families, (list, tuple)):
- families = [families]
- elif len(families) == 0:
- return 1.0
- family2 = family2.lower()
- step = 1 / len(families)
- for i, family1 in enumerate(families):
- family1 = family1.lower()
- if family1 in font_family_aliases:
- options = [*map(str.lower, self._expand_aliases(family1))]
- if family2 in options:
- idx = options.index(family2)
- return (i + (idx / len(options))) * step
- elif family1 == family2:
- # The score should be weighted by where in the
- # list the font was found.
- return i * step
- return 1.0
-
- def score_style(self, style1, style2):
- """
- Return a match score between *style1* and *style2*.
-
- An exact match returns 0.0.
-
- A match between 'italic' and 'oblique' returns 0.1.
-
- No match returns 1.0.
- """
- if style1 == style2:
- return 0.0
- elif (style1 in ('italic', 'oblique')
- and style2 in ('italic', 'oblique')):
- return 0.1
- return 1.0
-
- def score_variant(self, variant1, variant2):
- """
- Return a match score between *variant1* and *variant2*.
-
- An exact match returns 0.0, otherwise 1.0.
- """
- if variant1 == variant2:
- return 0.0
- else:
- return 1.0
-
- def score_stretch(self, stretch1, stretch2):
- """
- Return a match score between *stretch1* and *stretch2*.
-
- The result is the absolute value of the difference between the
- CSS numeric values of *stretch1* and *stretch2*, normalized
- between 0.0 and 1.0.
- """
- try:
- stretchval1 = int(stretch1)
- except ValueError:
- stretchval1 = stretch_dict.get(stretch1, 500)
- try:
- stretchval2 = int(stretch2)
- except ValueError:
- stretchval2 = stretch_dict.get(stretch2, 500)
- return abs(stretchval1 - stretchval2) / 1000.0
-
- def score_weight(self, weight1, weight2):
- """
- Return a match score between *weight1* and *weight2*.
-
- The result is 0.0 if both weight1 and weight 2 are given as strings
- and have the same value.
-
- Otherwise, the result is the absolute value of the difference between
- the CSS numeric values of *weight1* and *weight2*, normalized between
- 0.05 and 1.0.
- """
- # exact match of the weight names, e.g. weight1 == weight2 == "regular"
- if cbook._str_equal(weight1, weight2):
- return 0.0
- w1 = weight1 if isinstance(weight1, Number) else weight_dict[weight1]
- w2 = weight2 if isinstance(weight2, Number) else weight_dict[weight2]
- return 0.95 * (abs(w1 - w2) / 1000) + 0.05
-
- def score_size(self, size1, size2):
- """
- Return a match score between *size1* and *size2*.
-
- If *size2* (the size specified in the font file) is 'scalable', this
- function always returns 0.0, since any font size can be generated.
-
- Otherwise, the result is the absolute distance between *size1* and
- *size2*, normalized so that the usual range of font sizes (6pt -
- 72pt) will lie between 0.0 and 1.0.
- """
- if size2 == 'scalable':
- return 0.0
- # Size value should have already been
- try:
- sizeval1 = float(size1)
- except ValueError:
- sizeval1 = self.default_size * font_scalings[size1]
- try:
- sizeval2 = float(size2)
- except ValueError:
- return 1.0
- return abs(sizeval1 - sizeval2) / 72
-
- def findfont(self, prop, fontext='ttf', directory=None,
- fallback_to_default=True, rebuild_if_missing=True):
- """
- Find a font that most closely matches the given font properties.
-
- Parameters
- ----------
- prop : str or `~matplotlib.font_manager.FontProperties`
- The font properties to search for. This can be either a
- `.FontProperties` object or a string defining a
- `fontconfig patterns`_.
-
- fontext : {'ttf', 'afm'}, default: 'ttf'
- The extension of the font file:
-
- - 'ttf': TrueType and OpenType fonts (.ttf, .ttc, .otf)
- - 'afm': Adobe Font Metrics (.afm)
-
- directory : str, optional
- If given, only search this directory and its subdirectories.
-
- fallback_to_default : bool
- If True, will fall back to the default font family (usually
- "DejaVu Sans" or "Helvetica") if the first lookup hard-fails.
-
- rebuild_if_missing : bool
- Whether to rebuild the font cache and search again if the first
- match appears to point to a nonexisting font (i.e., the font cache
- contains outdated entries).
-
- Returns
- -------
- str
- The filename of the best matching font.
-
- Notes
- -----
- This performs a nearest neighbor search. Each font is given a
- similarity score to the target font properties. The first font with
- the highest score is returned. If no matches below a certain
- threshold are found, the default font (usually DejaVu Sans) is
- returned.
-
- The result is cached, so subsequent lookups don't have to
- perform the O(n) nearest neighbor search.
-
- See the `W3C Cascading Style Sheet, Level 1
- <http://www.w3.org/TR/1998/REC-CSS2-19980512/>`_ documentation
- for a description of the font finding algorithm.
-
- .. _fontconfig patterns:
- https://www.freedesktop.org/software/fontconfig/fontconfig-user.html
- """
- # Pass the relevant rcParams (and the font manager, as `self`) to
- # _findfont_cached so to prevent using a stale cache entry after an
- # rcParam was changed.
- rc_params = tuple(tuple(mpl.rcParams[key]) for key in [
- "font.serif", "font.sans-serif", "font.cursive", "font.fantasy",
- "font.monospace"])
- ret = self._findfont_cached(
- prop, fontext, directory, fallback_to_default, rebuild_if_missing,
- rc_params)
- if isinstance(ret, _ExceptionProxy):
- raise ret.klass(ret.message)
- return ret
-
- def get_font_names(self):
- """Return the list of available fonts."""
- return list({font.name for font in self.ttflist})
-
- def _find_fonts_by_props(self, prop, fontext='ttf', directory=None,
- fallback_to_default=True, rebuild_if_missing=True):
- """
- Find font families that most closely match the given properties.
-
- Parameters
- ----------
- prop : str or `~matplotlib.font_manager.FontProperties`
- The font properties to search for. This can be either a
- `.FontProperties` object or a string defining a
- `fontconfig patterns`_.
-
- fontext : {'ttf', 'afm'}, default: 'ttf'
- The extension of the font file:
-
- - 'ttf': TrueType and OpenType fonts (.ttf, .ttc, .otf)
- - 'afm': Adobe Font Metrics (.afm)
-
- directory : str, optional
- If given, only search this directory and its subdirectories.
-
- fallback_to_default : bool
- If True, will fall back to the default font family (usually
- "DejaVu Sans" or "Helvetica") if none of the families were found.
-
- rebuild_if_missing : bool
- Whether to rebuild the font cache and search again if the first
- match appears to point to a nonexisting font (i.e., the font cache
- contains outdated entries).
-
- Returns
- -------
- list[str]
- The paths of the fonts found
-
- Notes
- -----
- This is an extension/wrapper of the original findfont API, which only
- returns a single font for given font properties. Instead, this API
- returns a dict containing multiple fonts and their filepaths
- which closely match the given font properties. Since this internally
- uses the original API, there's no change to the logic of performing the
- nearest neighbor search. See `findfont` for more details.
- """
-
- prop = FontProperties._from_any(prop)
-
- fpaths = []
- for family in prop.get_family():
- cprop = prop.copy()
- cprop.set_family(family) # set current prop's family
-
- try:
- fpaths.append(
- self.findfont(
- cprop, fontext, directory,
- fallback_to_default=False, # don't fallback to default
- rebuild_if_missing=rebuild_if_missing,
- )
- )
- except ValueError:
- if family in font_family_aliases:
- _log.warning(
- "findfont: Generic family %r not found because "
- "none of the following families were found: %s",
- family, ", ".join(self._expand_aliases(family))
- )
- else:
- _log.warning("findfont: Font family %r not found.", family)
-
- # only add default family if no other font was found and
- # fallback_to_default is enabled
- if not fpaths:
- if fallback_to_default:
- dfamily = self.defaultFamily[fontext]
- cprop = prop.copy()
- cprop.set_family(dfamily)
- fpaths.append(
- self.findfont(
- cprop, fontext, directory,
- fallback_to_default=True,
- rebuild_if_missing=rebuild_if_missing,
- )
- )
- else:
- raise ValueError("Failed to find any font, and fallback "
- "to the default font was disabled")
-
- return fpaths
-
- @lru_cache(1024)
- def _findfont_cached(self, prop, fontext, directory, fallback_to_default,
- rebuild_if_missing, rc_params):
-
- prop = FontProperties._from_any(prop)
-
- fname = prop.get_file()
- if fname is not None:
- return fname
-
- if fontext == 'afm':
- fontlist = self.afmlist
- else:
- fontlist = self.ttflist
-
- best_score = 1e64
- best_font = None
-
- _log.debug('findfont: Matching %s.', prop)
- for font in fontlist:
- if (directory is not None and
- Path(directory) not in Path(font.fname).parents):
- continue
- # Matching family should have top priority, so multiply it by 10.
- score = (self.score_family(prop.get_family(), font.name) * 10
- + self.score_style(prop.get_style(), font.style)
- + self.score_variant(prop.get_variant(), font.variant)
- + self.score_weight(prop.get_weight(), font.weight)
- + self.score_stretch(prop.get_stretch(), font.stretch)
- + self.score_size(prop.get_size(), font.size))
- _log.debug('findfont: score(%s) = %s', font, score)
- if score < best_score:
- best_score = score
- best_font = font
- if score == 0:
- break
-
- if best_font is None or best_score >= 10.0:
- if fallback_to_default:
- _log.warning(
- 'findfont: Font family %s not found. Falling back to %s.',
- prop.get_family(), self.defaultFamily[fontext])
- for family in map(str.lower, prop.get_family()):
- if family in font_family_aliases:
- _log.warning(
- "findfont: Generic family %r not found because "
- "none of the following families were found: %s",
- family, ", ".join(self._expand_aliases(family)))
- default_prop = prop.copy()
- default_prop.set_family(self.defaultFamily[fontext])
- return self.findfont(default_prop, fontext, directory,
- fallback_to_default=False)
- else:
- # This return instead of raise is intentional, as we wish to
- # cache that it was not found, which will not occur if it was
- # actually raised.
- return _ExceptionProxy(
- ValueError,
- f"Failed to find font {prop}, and fallback to the default font was disabled"
- )
- else:
- _log.debug('findfont: Matching %s to %s (%r) with score of %f.',
- prop, best_font.name, best_font.fname, best_score)
- result = best_font.fname
-
- if not os.path.isfile(result):
- if rebuild_if_missing:
- _log.info(
- 'findfont: Found a missing font file. Rebuilding cache.')
- new_fm = _load_fontmanager(try_read_cache=False)
- # Replace self by the new fontmanager, because users may have
- # a reference to this specific instance.
- # TODO: _load_fontmanager should really be (used by) a method
- # modifying the instance in place.
- vars(self).update(vars(new_fm))
- return self.findfont(
- prop, fontext, directory, rebuild_if_missing=False)
- else:
- # This return instead of raise is intentional, as we wish to
- # cache that it was not found, which will not occur if it was
- # actually raised.
- return _ExceptionProxy(ValueError, "No valid font could be found")
-
- return _cached_realpath(result)
-
-
-@lru_cache
-def is_opentype_cff_font(filename):
- """
- Return whether the given font is a Postscript Compact Font Format Font
- embedded in an OpenType wrapper. Used by the PostScript and PDF backends
- that cannot subset these fonts.
- """
- if os.path.splitext(filename)[1].lower() == '.otf':
- with open(filename, 'rb') as fd:
- return fd.read(4) == b"OTTO"
- else:
- return False
-
-
-@lru_cache(64)
-def _get_font(font_filepaths, hinting_factor, *, _kerning_factor, thread_id):
- first_fontpath, *rest = font_filepaths
- return ft2font.FT2Font(
- first_fontpath, hinting_factor,
- _fallback_list=[
- ft2font.FT2Font(
- fpath, hinting_factor,
- _kerning_factor=_kerning_factor
- )
- for fpath in rest
- ],
- _kerning_factor=_kerning_factor
- )
-
-
-# FT2Font objects cannot be used across fork()s because they reference the same
-# FT_Library object. While invalidating *all* existing FT2Fonts after a fork
-# would be too complicated to be worth it, the main way FT2Fonts get reused is
-# via the cache of _get_font, which we can empty upon forking (not on Windows,
-# which has no fork() or register_at_fork()).
-if hasattr(os, "register_at_fork"):
- os.register_at_fork(after_in_child=_get_font.cache_clear)
-
-
-@lru_cache(64)
-def _cached_realpath(path):
- # Resolving the path avoids embedding the font twice in pdf/ps output if a
- # single font is selected using two different relative paths.
- return os.path.realpath(path)
-
-
-def get_font(font_filepaths, hinting_factor=None):
- """
- Get an `.ft2font.FT2Font` object given a list of file paths.
-
- Parameters
- ----------
- font_filepaths : Iterable[str, Path, bytes], str, Path, bytes
- Relative or absolute paths to the font files to be used.
-
- If a single string, bytes, or `pathlib.Path`, then it will be treated
- as a list with that entry only.
-
- If more than one filepath is passed, then the returned FT2Font object
- will fall back through the fonts, in the order given, to find a needed
- glyph.
-
- Returns
- -------
- `.ft2font.FT2Font`
-
- """
- if isinstance(font_filepaths, (str, Path, bytes)):
- paths = (_cached_realpath(font_filepaths),)
- else:
- paths = tuple(_cached_realpath(fname) for fname in font_filepaths)
-
- if hinting_factor is None:
- hinting_factor = mpl.rcParams['text.hinting_factor']
-
- return _get_font(
- # must be a tuple to be cached
- paths,
- hinting_factor,
- _kerning_factor=mpl.rcParams['text.kerning_factor'],
- # also key on the thread ID to prevent segfaults with multi-threading
- thread_id=threading.get_ident()
- )
-
-
-def _load_fontmanager(*, try_read_cache=True):
- fm_path = Path(
- mpl.get_cachedir(), f"fontlist-v{FontManager.__version__}.json")
- if try_read_cache:
- try:
- fm = json_load(fm_path)
- except Exception:
- pass
- else:
- if getattr(fm, "_version", object()) == FontManager.__version__:
- _log.debug("Using fontManager instance from %s", fm_path)
- return fm
- fm = FontManager()
- json_dump(fm, fm_path)
- _log.info("generated new fontManager")
- return fm
-
-
-fontManager = _load_fontmanager()
-findfont = fontManager.findfont
-get_font_names = fontManager.get_font_names
diff --git a/contrib/python/matplotlib/py3/matplotlib/font_manager.pyi b/contrib/python/matplotlib/py3/matplotlib/font_manager.pyi
deleted file mode 100644
index 48d0e362d5..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/font_manager.pyi
+++ /dev/null
@@ -1,136 +0,0 @@
-from dataclasses import dataclass
-import os
-
-from matplotlib._afm import AFM
-from matplotlib import ft2font
-
-from pathlib import Path
-
-from collections.abc import Iterable
-from typing import Any, Literal
-
-font_scalings: dict[str | None, float]
-stretch_dict: dict[str, int]
-weight_dict: dict[str, int]
-font_family_aliases: set[str]
-MSFolders: str
-MSFontDirectories: list[str]
-MSUserFontDirectories: list[str]
-X11FontDirectories: list[str]
-OSXFontDirectories: list[str]
-
-def get_fontext_synonyms(fontext: str) -> list[str]: ...
-def list_fonts(directory: str, extensions: Iterable[str]) -> list[str]: ...
-def win32FontDirectory() -> str: ...
-def _get_fontconfig_fonts() -> list[Path]: ...
-def findSystemFonts(
- fontpaths: Iterable[str | os.PathLike | Path] | None = ..., fontext: str = ...
-) -> list[str]: ...
-@dataclass
-class FontEntry:
- fname: str = ...
- name: str = ...
- style: str = ...
- variant: str = ...
- weight: str | int = ...
- stretch: str = ...
- size: str = ...
- def _repr_html_(self) -> str: ...
- def _repr_png_(self) -> bytes: ...
-
-def ttfFontProperty(font: ft2font.FT2Font) -> FontEntry: ...
-def afmFontProperty(fontpath: str, font: AFM) -> FontEntry: ...
-
-class FontProperties:
- def __init__(
- self,
- family: str | Iterable[str] | None = ...,
- style: Literal["normal", "italic", "oblique"] | None = ...,
- variant: Literal["normal", "small-caps"] | None = ...,
- weight: int | str | None = ...,
- stretch: int | str | None = ...,
- size: float | str | None = ...,
- fname: str | os.PathLike | Path | None = ...,
- math_fontfamily: str | None = ...,
- ) -> None: ...
- def __hash__(self) -> int: ...
- def __eq__(self, other: object) -> bool: ...
- def get_family(self) -> list[str]: ...
- def get_name(self) -> str: ...
- def get_style(self) -> Literal["normal", "italic", "oblique"]: ...
- def get_variant(self) -> Literal["normal", "small-caps"]: ...
- def get_weight(self) -> int | str: ...
- def get_stretch(self) -> int | str: ...
- def get_size(self) -> float: ...
- def get_file(self) -> str | bytes | None: ...
- def get_fontconfig_pattern(self) -> dict[str, list[Any]]: ...
- def set_family(self, family: str | Iterable[str] | None) -> None: ...
- def set_style(
- self, style: Literal["normal", "italic", "oblique"] | None
- ) -> None: ...
- def set_variant(self, variant: Literal["normal", "small-caps"] | None) -> None: ...
- def set_weight(self, weight: int | str | None) -> None: ...
- def set_stretch(self, stretch: int | str | None) -> None: ...
- def set_size(self, size: float | str | None) -> None: ...
- def set_file(self, file: str | os.PathLike | Path | None) -> None: ...
- def set_fontconfig_pattern(self, pattern: str) -> None: ...
- def get_math_fontfamily(self) -> str: ...
- def set_math_fontfamily(self, fontfamily: str | None) -> None: ...
- def copy(self) -> FontProperties: ...
- # Aliases
- set_name = set_family
- get_slant = get_style
- set_slant = set_style
- get_size_in_points = get_size
-
-def json_dump(data: FontManager, filename: str | Path | os.PathLike) -> None: ...
-def json_load(filename: str | Path | os.PathLike) -> FontManager: ...
-
-class FontManager:
- __version__: int
- default_size: float | None
- defaultFamily: dict[str, str]
- afmlist: list[FontEntry]
- ttflist: list[FontEntry]
- def __init__(self, size: float | None = ..., weight: str = ...) -> None: ...
- def addfont(self, path: str | Path | os.PathLike) -> None: ...
- @property
- def defaultFont(self) -> dict[str, str]: ...
- def get_default_weight(self) -> str: ...
- @staticmethod
- def get_default_size() -> float: ...
- def set_default_weight(self, weight: str) -> None: ...
- def score_family(
- self, families: str | list[str] | tuple[str], family2: str
- ) -> float: ...
- def score_style(self, style1: str, style2: str) -> float: ...
- def score_variant(self, variant1: str, variant2: str) -> float: ...
- def score_stretch(self, stretch1: str | int, stretch2: str | int) -> float: ...
- def score_weight(self, weight1: str | float, weight2: str | float) -> float: ...
- def score_size(self, size1: str | float, size2: str | float) -> float: ...
- def findfont(
- self,
- prop: str | FontProperties,
- fontext: Literal["ttf", "afm"] = ...,
- directory: str | None = ...,
- fallback_to_default: bool = ...,
- rebuild_if_missing: bool = ...,
- ) -> str: ...
- def get_font_names(self) -> list[str]: ...
-
-def is_opentype_cff_font(filename: str) -> bool: ...
-def get_font(
- font_filepaths: Iterable[str | Path | bytes] | str | Path | bytes,
- hinting_factor: int | None = ...,
-) -> ft2font.FT2Font: ...
-
-fontManager: FontManager
-
-def findfont(
- prop: str | FontProperties,
- fontext: Literal["ttf", "afm"] = ...,
- directory: str | None = ...,
- fallback_to_default: bool = ...,
- rebuild_if_missing: bool = ...,
-) -> str: ...
-def get_font_names() -> list[str]: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/ft2font.pyi b/contrib/python/matplotlib/py3/matplotlib/ft2font.pyi
deleted file mode 100644
index 6a0716e993..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/ft2font.pyi
+++ /dev/null
@@ -1,253 +0,0 @@
-from typing import BinaryIO, Literal, TypedDict, overload
-
-import numpy as np
-from numpy.typing import NDArray
-
-__freetype_build_type__: str
-__freetype_version__: str
-BOLD: int
-EXTERNAL_STREAM: int
-FAST_GLYPHS: int
-FIXED_SIZES: int
-FIXED_WIDTH: int
-GLYPH_NAMES: int
-HORIZONTAL: int
-ITALIC: int
-KERNING: int
-KERNING_DEFAULT: int
-KERNING_UNFITTED: int
-KERNING_UNSCALED: int
-LOAD_CROP_BITMAP: int
-LOAD_DEFAULT: int
-LOAD_FORCE_AUTOHINT: int
-LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH: int
-LOAD_IGNORE_TRANSFORM: int
-LOAD_LINEAR_DESIGN: int
-LOAD_MONOCHROME: int
-LOAD_NO_AUTOHINT: int
-LOAD_NO_BITMAP: int
-LOAD_NO_HINTING: int
-LOAD_NO_RECURSE: int
-LOAD_NO_SCALE: int
-LOAD_PEDANTIC: int
-LOAD_RENDER: int
-LOAD_TARGET_LCD: int
-LOAD_TARGET_LCD_V: int
-LOAD_TARGET_LIGHT: int
-LOAD_TARGET_MONO: int
-LOAD_TARGET_NORMAL: int
-LOAD_VERTICAL_LAYOUT: int
-MULTIPLE_MASTERS: int
-SCALABLE: int
-SFNT: int
-VERTICAL: int
-
-class _SfntHeadDict(TypedDict):
- version: tuple[int, int]
- fontRevision: tuple[int, int]
- checkSumAdjustment: int
- magicNumber: int
- flags: int
- unitsPerEm: int
- created: tuple[int, int]
- modified: tuple[int, int]
- xMin: int
- yMin: int
- xMax: int
- yMax: int
- macStyle: int
- lowestRecPPEM: int
- fontDirectionHint: int
- indexToLocFormat: int
- glyphDataFormat: int
-
-class _SfntMaxpDict(TypedDict):
- version: tuple[int, int]
- numGlyphs: int
- maxPoints: int
- maxContours: int
- maxComponentPoints: int
- maxComponentContours: int
- maxZones: int
- maxTwilightPoints: int
- maxStorage: int
- maxFunctionDefs: int
- maxInstructionDefs: int
- maxStackElements: int
- maxSizeOfInstructions: int
- maxComponentElements: int
- maxComponentDepth: int
-
-class _SfntOs2Dict(TypedDict):
- version: int
- xAvgCharWidth: int
- usWeightClass: int
- usWidthClass: int
- fsType: int
- ySubscriptXSize: int
- ySubscriptYSize: int
- ySubscriptXOffset: int
- ySubscriptYOffset: int
- ySuperscriptXSize: int
- ySuperscriptYSize: int
- ySuperscriptXOffset: int
- ySuperscriptYOffset: int
- yStrikeoutSize: int
- yStrikeoutPosition: int
- sFamilyClass: int
- panose: bytes
- ulCharRange: tuple[int, int, int, int]
- achVendID: bytes
- fsSelection: int
- fsFirstCharIndex: int
- fsLastCharIndex: int
-
-class _SfntHheaDict(TypedDict):
- version: tuple[int, int]
- ascent: int
- descent: int
- lineGap: int
- advanceWidthMax: int
- minLeftBearing: int
- minRightBearing: int
- xMaxExtent: int
- caretSlopeRise: int
- caretSlopeRun: int
- caretOffset: int
- metricDataFormat: int
- numOfLongHorMetrics: int
-
-class _SfntVheaDict(TypedDict):
- version: tuple[int, int]
- vertTypoAscender: int
- vertTypoDescender: int
- vertTypoLineGap: int
- advanceHeightMax: int
- minTopSideBearing: int
- minBottomSizeBearing: int
- yMaxExtent: int
- caretSlopeRise: int
- caretSlopeRun: int
- caretOffset: int
- metricDataFormat: int
- numOfLongVerMetrics: int
-
-class _SfntPostDict(TypedDict):
- format: tuple[int, int]
- italicAngle: tuple[int, int]
- underlinePosition: int
- underlineThickness: int
- isFixedPitch: int
- minMemType42: int
- maxMemType42: int
- minMemType1: int
- maxMemType1: int
-
-class _SfntPcltDict(TypedDict):
- version: tuple[int, int]
- fontNumber: int
- pitch: int
- xHeight: int
- style: int
- typeFamily: int
- capHeight: int
- symbolSet: int
- typeFace: bytes
- characterComplement: bytes
- strokeWeight: int
- widthType: int
- serifStyle: int
-
-class FT2Font:
- ascender: int
- bbox: tuple[int, int, int, int]
- descender: int
- face_flags: int
- family_name: str
- fname: str
- height: int
- max_advance_height: int
- max_advance_width: int
- num_charmaps: int
- num_faces: int
- num_fixed_sizes: int
- num_glyphs: int
- postscript_name: str
- scalable: bool
- style_flags: int
- style_name: str
- underline_position: int
- underline_thickness: int
- units_per_EM: int
-
- def __init__(
- self,
- filename: str | BinaryIO,
- hinting_factor: int = ...,
- *,
- _fallback_list: list[FT2Font] | None = ...,
- _kerning_factor: int = ...
- ) -> None: ...
- def _get_fontmap(self, string: str) -> dict[str, FT2Font]: ...
- def clear(self) -> None: ...
- def draw_glyph_to_bitmap(
- self, image: FT2Image, x: float, y: float, glyph: Glyph, antialiased: bool = ...
- ) -> None: ...
- def draw_glyphs_to_bitmap(self, antialiased: bool = ...) -> None: ...
- def get_bitmap_offset(self) -> tuple[int, int]: ...
- def get_char_index(self, codepoint: int) -> int: ...
- def get_charmap(self) -> dict[int, int]: ...
- def get_descent(self) -> int: ...
- def get_glyph_name(self, index: int) -> str: ...
- def get_image(self) -> NDArray[np.uint8]: ...
- def get_kerning(self, left: int, right: int, mode: int) -> int: ...
- def get_name_index(self, name: str) -> int: ...
- def get_num_glyphs(self) -> int: ...
- def get_path(self) -> tuple[NDArray[np.float64], NDArray[np.int8]]: ...
- def get_ps_font_info(
- self,
- ) -> tuple[str, str, str, str, str, int, int, int, int]: ...
- def get_sfnt(self) -> dict[tuple[int, int, int, int], bytes]: ...
- @overload
- def get_sfnt_table(self, name: Literal["head"]) -> _SfntHeadDict | None: ...
- @overload
- def get_sfnt_table(self, name: Literal["maxp"]) -> _SfntMaxpDict | None: ...
- @overload
- def get_sfnt_table(self, name: Literal["OS/2"]) -> _SfntOs2Dict | None: ...
- @overload
- def get_sfnt_table(self, name: Literal["hhea"]) -> _SfntHheaDict | None: ...
- @overload
- def get_sfnt_table(self, name: Literal["vhea"]) -> _SfntVheaDict | None: ...
- @overload
- def get_sfnt_table(self, name: Literal["post"]) -> _SfntPostDict | None: ...
- @overload
- def get_sfnt_table(self, name: Literal["pclt"]) -> _SfntPcltDict | None: ...
- def get_width_height(self) -> tuple[int, int]: ...
- def get_xys(self, antialiased: bool = ...) -> NDArray[np.float64]: ...
- def load_char(self, charcode: int, flags: int = ...) -> Glyph: ...
- def load_glyph(self, glyphindex: int, flags: int = ...) -> Glyph: ...
- def select_charmap(self, i: int) -> None: ...
- def set_charmap(self, i: int) -> None: ...
- def set_size(self, ptsize: float, dpi: float) -> None: ...
- def set_text(
- self, string: str, angle: float = ..., flags: int = ...
- ) -> NDArray[np.float64]: ...
-
-class FT2Image: # TODO: When updating mypy>=1.4, subclass from Buffer.
- def __init__(self, width: float, height: float) -> None: ...
- def draw_rect(self, x0: float, y0: float, x1: float, y1: float) -> None: ...
- def draw_rect_filled(self, x0: float, y0: float, x1: float, y1: float) -> None: ...
-
-class Glyph:
- width: int
- height: int
- horiBearingX: int
- horiBearingY: int
- horiAdvance: int
- linearHoriAdvance: int
- vertBearingX: int
- vertBearingY: int
- vertAdvance: int
-
- @property
- def bbox(self) -> tuple[int, int, int, int]: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/gridspec.py b/contrib/python/matplotlib/py3/matplotlib/gridspec.py
deleted file mode 100644
index b2f1b5d8ff..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/gridspec.py
+++ /dev/null
@@ -1,738 +0,0 @@
-r"""
-:mod:`~matplotlib.gridspec` contains classes that help to layout multiple
-`~.axes.Axes` in a grid-like pattern within a figure.
-
-The `GridSpec` specifies the overall grid structure. Individual cells within
-the grid are referenced by `SubplotSpec`\s.
-
-Often, users need not access this module directly, and can use higher-level
-methods like `~.pyplot.subplots`, `~.pyplot.subplot_mosaic` and
-`~.Figure.subfigures`. See the tutorial :ref:`arranging_axes` for a guide.
-"""
-
-import copy
-import logging
-from numbers import Integral
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, _pylab_helpers, _tight_layout
-from matplotlib.transforms import Bbox
-
-_log = logging.getLogger(__name__)
-
-
-class GridSpecBase:
- """
- A base class of GridSpec that specifies the geometry of the grid
- that a subplot will be placed.
- """
-
- def __init__(self, nrows, ncols, height_ratios=None, width_ratios=None):
- """
- Parameters
- ----------
- nrows, ncols : int
- The number of rows and columns of the grid.
- width_ratios : array-like of length *ncols*, optional
- Defines the relative widths of the columns. Each column gets a
- relative width of ``width_ratios[i] / sum(width_ratios)``.
- If not given, all columns will have the same width.
- height_ratios : array-like of length *nrows*, optional
- Defines the relative heights of the rows. Each row gets a
- relative height of ``height_ratios[i] / sum(height_ratios)``.
- If not given, all rows will have the same height.
- """
- if not isinstance(nrows, Integral) or nrows <= 0:
- raise ValueError(
- f"Number of rows must be a positive integer, not {nrows!r}")
- if not isinstance(ncols, Integral) or ncols <= 0:
- raise ValueError(
- f"Number of columns must be a positive integer, not {ncols!r}")
- self._nrows, self._ncols = nrows, ncols
- self.set_height_ratios(height_ratios)
- self.set_width_ratios(width_ratios)
-
- def __repr__(self):
- height_arg = (f', height_ratios={self._row_height_ratios!r}'
- if len(set(self._row_height_ratios)) != 1 else '')
- width_arg = (f', width_ratios={self._col_width_ratios!r}'
- if len(set(self._col_width_ratios)) != 1 else '')
- return '{clsname}({nrows}, {ncols}{optionals})'.format(
- clsname=self.__class__.__name__,
- nrows=self._nrows,
- ncols=self._ncols,
- optionals=height_arg + width_arg,
- )
-
- nrows = property(lambda self: self._nrows,
- doc="The number of rows in the grid.")
- ncols = property(lambda self: self._ncols,
- doc="The number of columns in the grid.")
-
- def get_geometry(self):
- """
- Return a tuple containing the number of rows and columns in the grid.
- """
- return self._nrows, self._ncols
-
- def get_subplot_params(self, figure=None):
- # Must be implemented in subclasses
- pass
-
- def new_subplotspec(self, loc, rowspan=1, colspan=1):
- """
- Create and return a `.SubplotSpec` instance.
-
- Parameters
- ----------
- loc : (int, int)
- The position of the subplot in the grid as
- ``(row_index, column_index)``.
- rowspan, colspan : int, default: 1
- The number of rows and columns the subplot should span in the grid.
- """
- loc1, loc2 = loc
- subplotspec = self[loc1:loc1+rowspan, loc2:loc2+colspan]
- return subplotspec
-
- def set_width_ratios(self, width_ratios):
- """
- Set the relative widths of the columns.
-
- *width_ratios* must be of length *ncols*. Each column gets a relative
- width of ``width_ratios[i] / sum(width_ratios)``.
- """
- if width_ratios is None:
- width_ratios = [1] * self._ncols
- elif len(width_ratios) != self._ncols:
- raise ValueError('Expected the given number of width ratios to '
- 'match the number of columns of the grid')
- self._col_width_ratios = width_ratios
-
- def get_width_ratios(self):
- """
- Return the width ratios.
-
- This is *None* if no width ratios have been set explicitly.
- """
- return self._col_width_ratios
-
- def set_height_ratios(self, height_ratios):
- """
- Set the relative heights of the rows.
-
- *height_ratios* must be of length *nrows*. Each row gets a relative
- height of ``height_ratios[i] / sum(height_ratios)``.
- """
- if height_ratios is None:
- height_ratios = [1] * self._nrows
- elif len(height_ratios) != self._nrows:
- raise ValueError('Expected the given number of height ratios to '
- 'match the number of rows of the grid')
- self._row_height_ratios = height_ratios
-
- def get_height_ratios(self):
- """
- Return the height ratios.
-
- This is *None* if no height ratios have been set explicitly.
- """
- return self._row_height_ratios
-
- @_api.delete_parameter("3.7", "raw")
- def get_grid_positions(self, fig, raw=False):
- """
- Return the positions of the grid cells in figure coordinates.
-
- Parameters
- ----------
- fig : `~matplotlib.figure.Figure`
- The figure the grid should be applied to. The subplot parameters
- (margins and spacing between subplots) are taken from *fig*.
- raw : bool, default: False
- If *True*, the subplot parameters of the figure are not taken
- into account. The grid spans the range [0, 1] in both directions
- without margins and there is no space between grid cells. This is
- used for constrained_layout.
-
- Returns
- -------
- bottoms, tops, lefts, rights : array
- The bottom, top, left, right positions of the grid cells in
- figure coordinates.
- """
- nrows, ncols = self.get_geometry()
-
- if raw:
- left = 0.
- right = 1.
- bottom = 0.
- top = 1.
- wspace = 0.
- hspace = 0.
- else:
- subplot_params = self.get_subplot_params(fig)
- left = subplot_params.left
- right = subplot_params.right
- bottom = subplot_params.bottom
- top = subplot_params.top
- wspace = subplot_params.wspace
- hspace = subplot_params.hspace
- tot_width = right - left
- tot_height = top - bottom
-
- # calculate accumulated heights of columns
- cell_h = tot_height / (nrows + hspace*(nrows-1))
- sep_h = hspace * cell_h
- norm = cell_h * nrows / sum(self._row_height_ratios)
- cell_heights = [r * norm for r in self._row_height_ratios]
- sep_heights = [0] + ([sep_h] * (nrows-1))
- cell_hs = np.cumsum(np.column_stack([sep_heights, cell_heights]).flat)
-
- # calculate accumulated widths of rows
- cell_w = tot_width / (ncols + wspace*(ncols-1))
- sep_w = wspace * cell_w
- norm = cell_w * ncols / sum(self._col_width_ratios)
- cell_widths = [r * norm for r in self._col_width_ratios]
- sep_widths = [0] + ([sep_w] * (ncols-1))
- cell_ws = np.cumsum(np.column_stack([sep_widths, cell_widths]).flat)
-
- fig_tops, fig_bottoms = (top - cell_hs).reshape((-1, 2)).T
- fig_lefts, fig_rights = (left + cell_ws).reshape((-1, 2)).T
- return fig_bottoms, fig_tops, fig_lefts, fig_rights
-
- @staticmethod
- def _check_gridspec_exists(figure, nrows, ncols):
- """
- Check if the figure already has a gridspec with these dimensions,
- or create a new one
- """
- for ax in figure.get_axes():
- gs = ax.get_gridspec()
- if gs is not None:
- if hasattr(gs, 'get_topmost_subplotspec'):
- # This is needed for colorbar gridspec layouts.
- # This is probably OK because this whole logic tree
- # is for when the user is doing simple things with the
- # add_subplot command. For complicated layouts
- # like subgridspecs the proper gridspec is passed in...
- gs = gs.get_topmost_subplotspec().get_gridspec()
- if gs.get_geometry() == (nrows, ncols):
- return gs
- # else gridspec not found:
- return GridSpec(nrows, ncols, figure=figure)
-
- def __getitem__(self, key):
- """Create and return a `.SubplotSpec` instance."""
- nrows, ncols = self.get_geometry()
-
- def _normalize(key, size, axis): # Includes last index.
- orig_key = key
- if isinstance(key, slice):
- start, stop, _ = key.indices(size)
- if stop > start:
- return start, stop - 1
- raise IndexError("GridSpec slice would result in no space "
- "allocated for subplot")
- else:
- if key < 0:
- key = key + size
- if 0 <= key < size:
- return key, key
- elif axis is not None:
- raise IndexError(f"index {orig_key} is out of bounds for "
- f"axis {axis} with size {size}")
- else: # flat index
- raise IndexError(f"index {orig_key} is out of bounds for "
- f"GridSpec with size {size}")
-
- if isinstance(key, tuple):
- try:
- k1, k2 = key
- except ValueError as err:
- raise ValueError("Unrecognized subplot spec") from err
- num1, num2 = np.ravel_multi_index(
- [_normalize(k1, nrows, 0), _normalize(k2, ncols, 1)],
- (nrows, ncols))
- else: # Single key
- num1, num2 = _normalize(key, nrows * ncols, None)
-
- return SubplotSpec(self, num1, num2)
-
- def subplots(self, *, sharex=False, sharey=False, squeeze=True,
- subplot_kw=None):
- """
- Add all subplots specified by this `GridSpec` to its parent figure.
-
- See `.Figure.subplots` for detailed documentation.
- """
-
- figure = self.figure
-
- if figure is None:
- raise ValueError("GridSpec.subplots() only works for GridSpecs "
- "created with a parent figure")
-
- if not isinstance(sharex, str):
- sharex = "all" if sharex else "none"
- if not isinstance(sharey, str):
- sharey = "all" if sharey else "none"
-
- _api.check_in_list(["all", "row", "col", "none", False, True],
- sharex=sharex, sharey=sharey)
- if subplot_kw is None:
- subplot_kw = {}
- # don't mutate kwargs passed by user...
- subplot_kw = subplot_kw.copy()
-
- # Create array to hold all axes.
- axarr = np.empty((self._nrows, self._ncols), dtype=object)
- for row in range(self._nrows):
- for col in range(self._ncols):
- shared_with = {"none": None, "all": axarr[0, 0],
- "row": axarr[row, 0], "col": axarr[0, col]}
- subplot_kw["sharex"] = shared_with[sharex]
- subplot_kw["sharey"] = shared_with[sharey]
- axarr[row, col] = figure.add_subplot(
- self[row, col], **subplot_kw)
-
- # turn off redundant tick labeling
- if sharex in ["col", "all"]:
- for ax in axarr.flat:
- ax._label_outer_xaxis(skip_non_rectangular_axes=True)
- if sharey in ["row", "all"]:
- for ax in axarr.flat:
- ax._label_outer_yaxis(skip_non_rectangular_axes=True)
-
- if squeeze:
- # Discarding unneeded dimensions that equal 1. If we only have one
- # subplot, just return it instead of a 1-element array.
- return axarr.item() if axarr.size == 1 else axarr.squeeze()
- else:
- # Returned axis array will be always 2-d, even if nrows=ncols=1.
- return axarr
-
-
-class GridSpec(GridSpecBase):
- """
- A grid layout to place subplots within a figure.
-
- The location of the grid cells is determined in a similar way to
- `~.figure.SubplotParams` using *left*, *right*, *top*, *bottom*, *wspace*
- and *hspace*.
-
- Indexing a GridSpec instance returns a `.SubplotSpec`.
- """
- def __init__(self, nrows, ncols, figure=None,
- left=None, bottom=None, right=None, top=None,
- wspace=None, hspace=None,
- width_ratios=None, height_ratios=None):
- """
- Parameters
- ----------
- nrows, ncols : int
- The number of rows and columns of the grid.
-
- figure : `.Figure`, optional
- Only used for constrained layout to create a proper layoutgrid.
-
- left, right, top, bottom : float, optional
- Extent of the subplots as a fraction of figure width or height.
- Left cannot be larger than right, and bottom cannot be larger than
- top. If not given, the values will be inferred from a figure or
- rcParams at draw time. See also `GridSpec.get_subplot_params`.
-
- wspace : float, optional
- The amount of width reserved for space between subplots,
- expressed as a fraction of the average axis width.
- If not given, the values will be inferred from a figure or
- rcParams when necessary. See also `GridSpec.get_subplot_params`.
-
- hspace : float, optional
- The amount of height reserved for space between subplots,
- expressed as a fraction of the average axis height.
- If not given, the values will be inferred from a figure or
- rcParams when necessary. See also `GridSpec.get_subplot_params`.
-
- width_ratios : array-like of length *ncols*, optional
- Defines the relative widths of the columns. Each column gets a
- relative width of ``width_ratios[i] / sum(width_ratios)``.
- If not given, all columns will have the same width.
-
- height_ratios : array-like of length *nrows*, optional
- Defines the relative heights of the rows. Each row gets a
- relative height of ``height_ratios[i] / sum(height_ratios)``.
- If not given, all rows will have the same height.
-
- """
- self.left = left
- self.bottom = bottom
- self.right = right
- self.top = top
- self.wspace = wspace
- self.hspace = hspace
- self.figure = figure
-
- super().__init__(nrows, ncols,
- width_ratios=width_ratios,
- height_ratios=height_ratios)
-
- _AllowedKeys = ["left", "bottom", "right", "top", "wspace", "hspace"]
-
- def update(self, **kwargs):
- """
- Update the subplot parameters of the grid.
-
- Parameters that are not explicitly given are not changed. Setting a
- parameter to *None* resets it to :rc:`figure.subplot.*`.
-
- Parameters
- ----------
- left, right, top, bottom : float or None, optional
- Extent of the subplots as a fraction of figure width or height.
- wspace, hspace : float, optional
- Spacing between the subplots as a fraction of the average subplot
- width / height.
- """
- for k, v in kwargs.items():
- if k in self._AllowedKeys:
- setattr(self, k, v)
- else:
- raise AttributeError(f"{k} is an unknown keyword")
- for figmanager in _pylab_helpers.Gcf.figs.values():
- for ax in figmanager.canvas.figure.axes:
- if ax.get_subplotspec() is not None:
- ss = ax.get_subplotspec().get_topmost_subplotspec()
- if ss.get_gridspec() == self:
- ax._set_position(
- ax.get_subplotspec().get_position(ax.figure))
-
- def get_subplot_params(self, figure=None):
- """
- Return the `.SubplotParams` for the GridSpec.
-
- In order of precedence the values are taken from
-
- - non-*None* attributes of the GridSpec
- - the provided *figure*
- - :rc:`figure.subplot.*`
-
- Note that the ``figure`` attribute of the GridSpec is always ignored.
- """
- if figure is None:
- kw = {k: mpl.rcParams["figure.subplot."+k]
- for k in self._AllowedKeys}
- subplotpars = mpl.figure.SubplotParams(**kw)
- else:
- subplotpars = copy.copy(figure.subplotpars)
-
- subplotpars.update(**{k: getattr(self, k) for k in self._AllowedKeys})
-
- return subplotpars
-
- def locally_modified_subplot_params(self):
- """
- Return a list of the names of the subplot parameters explicitly set
- in the GridSpec.
-
- This is a subset of the attributes of `.SubplotParams`.
- """
- return [k for k in self._AllowedKeys if getattr(self, k)]
-
- def tight_layout(self, figure, renderer=None,
- pad=1.08, h_pad=None, w_pad=None, rect=None):
- """
- Adjust subplot parameters to give specified padding.
-
- Parameters
- ----------
- figure : `.Figure`
- The figure.
- renderer : `.RendererBase` subclass, optional
- The renderer to be used.
- pad : float
- Padding between the figure edge and the edges of subplots, as a
- fraction of the font-size.
- h_pad, w_pad : float, optional
- Padding (height/width) between edges of adjacent subplots.
- Defaults to *pad*.
- rect : tuple (left, bottom, right, top), default: None
- (left, bottom, right, top) rectangle in normalized figure
- coordinates that the whole subplots area (including labels) will
- fit into. Default (None) is the whole figure.
- """
- if renderer is None:
- renderer = figure._get_renderer()
- kwargs = _tight_layout.get_tight_layout_figure(
- figure, figure.axes,
- _tight_layout.get_subplotspec_list(figure.axes, grid_spec=self),
- renderer, pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
- if kwargs:
- self.update(**kwargs)
-
-
-class GridSpecFromSubplotSpec(GridSpecBase):
- """
- GridSpec whose subplot layout parameters are inherited from the
- location specified by a given SubplotSpec.
- """
- def __init__(self, nrows, ncols,
- subplot_spec,
- wspace=None, hspace=None,
- height_ratios=None, width_ratios=None):
- """
- Parameters
- ----------
- nrows, ncols : int
- Number of rows and number of columns of the grid.
- subplot_spec : SubplotSpec
- Spec from which the layout parameters are inherited.
- wspace, hspace : float, optional
- See `GridSpec` for more details. If not specified default values
- (from the figure or rcParams) are used.
- height_ratios : array-like of length *nrows*, optional
- See `GridSpecBase` for details.
- width_ratios : array-like of length *ncols*, optional
- See `GridSpecBase` for details.
- """
- self._wspace = wspace
- self._hspace = hspace
- self._subplot_spec = subplot_spec
- self.figure = self._subplot_spec.get_gridspec().figure
- super().__init__(nrows, ncols,
- width_ratios=width_ratios,
- height_ratios=height_ratios)
-
- def get_subplot_params(self, figure=None):
- """Return a dictionary of subplot layout parameters."""
- hspace = (self._hspace if self._hspace is not None
- else figure.subplotpars.hspace if figure is not None
- else mpl.rcParams["figure.subplot.hspace"])
- wspace = (self._wspace if self._wspace is not None
- else figure.subplotpars.wspace if figure is not None
- else mpl.rcParams["figure.subplot.wspace"])
-
- figbox = self._subplot_spec.get_position(figure)
- left, bottom, right, top = figbox.extents
-
- return mpl.figure.SubplotParams(left=left, right=right,
- bottom=bottom, top=top,
- wspace=wspace, hspace=hspace)
-
- def get_topmost_subplotspec(self):
- """
- Return the topmost `.SubplotSpec` instance associated with the subplot.
- """
- return self._subplot_spec.get_topmost_subplotspec()
-
-
-class SubplotSpec:
- """
- The location of a subplot in a `GridSpec`.
-
- .. note::
-
- Likely, you will never instantiate a `SubplotSpec` yourself. Instead,
- you will typically obtain one from a `GridSpec` using item-access.
-
- Parameters
- ----------
- gridspec : `~matplotlib.gridspec.GridSpec`
- The GridSpec, which the subplot is referencing.
- num1, num2 : int
- The subplot will occupy the *num1*-th cell of the given
- *gridspec*. If *num2* is provided, the subplot will span between
- *num1*-th cell and *num2*-th cell **inclusive**.
-
- The index starts from 0.
- """
- def __init__(self, gridspec, num1, num2=None):
- self._gridspec = gridspec
- self.num1 = num1
- self.num2 = num2
-
- def __repr__(self):
- return (f"{self.get_gridspec()}["
- f"{self.rowspan.start}:{self.rowspan.stop}, "
- f"{self.colspan.start}:{self.colspan.stop}]")
-
- @staticmethod
- def _from_subplot_args(figure, args):
- """
- Construct a `.SubplotSpec` from a parent `.Figure` and either
-
- - a `.SubplotSpec` -- returned as is;
- - one or three numbers -- a MATLAB-style subplot specifier.
- """
- if len(args) == 1:
- arg, = args
- if isinstance(arg, SubplotSpec):
- return arg
- elif not isinstance(arg, Integral):
- raise ValueError(
- f"Single argument to subplot must be a three-digit "
- f"integer, not {arg!r}")
- try:
- rows, cols, num = map(int, str(arg))
- except ValueError:
- raise ValueError(
- f"Single argument to subplot must be a three-digit "
- f"integer, not {arg!r}") from None
- elif len(args) == 3:
- rows, cols, num = args
- else:
- raise _api.nargs_error("subplot", takes="1 or 3", given=len(args))
-
- gs = GridSpec._check_gridspec_exists(figure, rows, cols)
- if gs is None:
- gs = GridSpec(rows, cols, figure=figure)
- if isinstance(num, tuple) and len(num) == 2:
- if not all(isinstance(n, Integral) for n in num):
- raise ValueError(
- f"Subplot specifier tuple must contain integers, not {num}"
- )
- i, j = num
- else:
- if not isinstance(num, Integral) or num < 1 or num > rows*cols:
- raise ValueError(
- f"num must be an integer with 1 <= num <= {rows*cols}, "
- f"not {num!r}"
- )
- i = j = num
- return gs[i-1:j]
-
- # num2 is a property only to handle the case where it is None and someone
- # mutates num1.
-
- @property
- def num2(self):
- return self.num1 if self._num2 is None else self._num2
-
- @num2.setter
- def num2(self, value):
- self._num2 = value
-
- def get_gridspec(self):
- return self._gridspec
-
- def get_geometry(self):
- """
- Return the subplot geometry as tuple ``(n_rows, n_cols, start, stop)``.
-
- The indices *start* and *stop* define the range of the subplot within
- the `GridSpec`. *stop* is inclusive (i.e. for a single cell
- ``start == stop``).
- """
- rows, cols = self.get_gridspec().get_geometry()
- return rows, cols, self.num1, self.num2
-
- @property
- def rowspan(self):
- """The rows spanned by this subplot, as a `range` object."""
- ncols = self.get_gridspec().ncols
- return range(self.num1 // ncols, self.num2 // ncols + 1)
-
- @property
- def colspan(self):
- """The columns spanned by this subplot, as a `range` object."""
- ncols = self.get_gridspec().ncols
- # We explicitly support num2 referring to a column on num1's *left*, so
- # we must sort the column indices here so that the range makes sense.
- c1, c2 = sorted([self.num1 % ncols, self.num2 % ncols])
- return range(c1, c2 + 1)
-
- def is_first_row(self):
- return self.rowspan.start == 0
-
- def is_last_row(self):
- return self.rowspan.stop == self.get_gridspec().nrows
-
- def is_first_col(self):
- return self.colspan.start == 0
-
- def is_last_col(self):
- return self.colspan.stop == self.get_gridspec().ncols
-
- def get_position(self, figure):
- """
- Update the subplot position from ``figure.subplotpars``.
- """
- gridspec = self.get_gridspec()
- nrows, ncols = gridspec.get_geometry()
- rows, cols = np.unravel_index([self.num1, self.num2], (nrows, ncols))
- fig_bottoms, fig_tops, fig_lefts, fig_rights = \
- gridspec.get_grid_positions(figure)
-
- fig_bottom = fig_bottoms[rows].min()
- fig_top = fig_tops[rows].max()
- fig_left = fig_lefts[cols].min()
- fig_right = fig_rights[cols].max()
- return Bbox.from_extents(fig_left, fig_bottom, fig_right, fig_top)
-
- def get_topmost_subplotspec(self):
- """
- Return the topmost `SubplotSpec` instance associated with the subplot.
- """
- gridspec = self.get_gridspec()
- if hasattr(gridspec, "get_topmost_subplotspec"):
- return gridspec.get_topmost_subplotspec()
- else:
- return self
-
- def __eq__(self, other):
- """
- Two SubplotSpecs are considered equal if they refer to the same
- position(s) in the same `GridSpec`.
- """
- # other may not even have the attributes we are checking.
- return ((self._gridspec, self.num1, self.num2)
- == (getattr(other, "_gridspec", object()),
- getattr(other, "num1", object()),
- getattr(other, "num2", object())))
-
- def __hash__(self):
- return hash((self._gridspec, self.num1, self.num2))
-
- def subgridspec(self, nrows, ncols, **kwargs):
- """
- Create a GridSpec within this subplot.
-
- The created `.GridSpecFromSubplotSpec` will have this `SubplotSpec` as
- a parent.
-
- Parameters
- ----------
- nrows : int
- Number of rows in grid.
-
- ncols : int
- Number of columns in grid.
-
- Returns
- -------
- `.GridSpecFromSubplotSpec`
-
- Other Parameters
- ----------------
- **kwargs
- All other parameters are passed to `.GridSpecFromSubplotSpec`.
-
- See Also
- --------
- matplotlib.pyplot.subplots
-
- Examples
- --------
- Adding three subplots in the space occupied by a single subplot::
-
- fig = plt.figure()
- gs0 = fig.add_gridspec(3, 1)
- ax1 = fig.add_subplot(gs0[0])
- ax2 = fig.add_subplot(gs0[1])
- gssub = gs0[2].subgridspec(1, 3)
- for i in range(3):
- fig.add_subplot(gssub[0, i])
- """
- return GridSpecFromSubplotSpec(nrows, ncols, self, **kwargs)
diff --git a/contrib/python/matplotlib/py3/matplotlib/gridspec.pyi b/contrib/python/matplotlib/py3/matplotlib/gridspec.pyi
deleted file mode 100644
index 6e2273080b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/gridspec.pyi
+++ /dev/null
@@ -1,134 +0,0 @@
-from typing import Any, Literal, overload
-
-from numpy.typing import ArrayLike
-import numpy as np
-
-from matplotlib.axes import Axes, SubplotBase
-from matplotlib.backend_bases import RendererBase
-from matplotlib.figure import Figure, SubplotParams
-from matplotlib.transforms import Bbox
-
-class GridSpecBase:
- def __init__(
- self,
- nrows: int,
- ncols: int,
- height_ratios: ArrayLike | None = ...,
- width_ratios: ArrayLike | None = ...,
- ) -> None: ...
- @property
- def nrows(self) -> int: ...
- @property
- def ncols(self) -> int: ...
- def get_geometry(self) -> tuple[int, int]: ...
- def get_subplot_params(self, figure: Figure | None = ...) -> SubplotParams: ...
- def new_subplotspec(
- self, loc: tuple[int, int], rowspan: int = ..., colspan: int = ...
- ) -> SubplotSpec: ...
- def set_width_ratios(self, width_ratios: ArrayLike | None) -> None: ...
- def get_width_ratios(self) -> ArrayLike: ...
- def set_height_ratios(self, height_ratios: ArrayLike | None) -> None: ...
- def get_height_ratios(self) -> ArrayLike: ...
- def get_grid_positions(
- self, fig: Figure, raw: bool = ...
- ) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: ...
- @staticmethod
- def _check_gridspec_exists(figure: Figure, nrows: int, ncols: int) -> GridSpec: ...
- def __getitem__(
- self, key: tuple[int | slice, int | slice] | slice | int
- ) -> SubplotSpec: ...
- @overload
- def subplots(
- self,
- *,
- sharex: bool | Literal["all", "row", "col", "none"] = ...,
- sharey: bool | Literal["all", "row", "col", "none"] = ...,
- squeeze: Literal[False],
- subplot_kw: dict[str, Any] | None = ...
- ) -> np.ndarray: ...
- @overload
- def subplots(
- self,
- *,
- sharex: bool | Literal["all", "row", "col", "none"] = ...,
- sharey: bool | Literal["all", "row", "col", "none"] = ...,
- squeeze: Literal[True] = ...,
- subplot_kw: dict[str, Any] | None = ...
- ) -> np.ndarray | SubplotBase | Axes: ...
-
-class GridSpec(GridSpecBase):
- left: float | None
- bottom: float | None
- right: float | None
- top: float | None
- wspace: float | None
- hspace: float | None
- figure: Figure | None
- def __init__(
- self,
- nrows: int,
- ncols: int,
- figure: Figure | None = ...,
- left: float | None = ...,
- bottom: float | None = ...,
- right: float | None = ...,
- top: float | None = ...,
- wspace: float | None = ...,
- hspace: float | None = ...,
- width_ratios: ArrayLike | None = ...,
- height_ratios: ArrayLike | None = ...,
- ) -> None: ...
- def update(self, **kwargs: float | None) -> None: ...
- def locally_modified_subplot_params(self) -> list[str]: ...
- def tight_layout(
- self,
- figure: Figure,
- renderer: RendererBase | None = ...,
- pad: float = ...,
- h_pad: float | None = ...,
- w_pad: float | None = ...,
- rect: tuple[float, float, float, float] | None = ...,
- ) -> None: ...
-
-class GridSpecFromSubplotSpec(GridSpecBase):
- figure: Figure | None
- def __init__(
- self,
- nrows: int,
- ncols: int,
- subplot_spec: SubplotSpec,
- wspace: float | None = ...,
- hspace: float | None = ...,
- height_ratios: ArrayLike | None = ...,
- width_ratios: ArrayLike | None = ...,
- ) -> None: ...
- def get_topmost_subplotspec(self) -> SubplotSpec: ...
-
-class SubplotSpec:
- num1: int
- def __init__(
- self, gridspec: GridSpecBase, num1: int, num2: int | None = ...
- ) -> None: ...
- @staticmethod
- def _from_subplot_args(figure, args): ...
- @property
- def num2(self) -> int: ...
- @num2.setter
- def num2(self, value: int) -> None: ...
- def get_gridspec(self) -> GridSpec: ...
- def get_geometry(self) -> tuple[int, int, int, int]: ...
- @property
- def rowspan(self) -> range: ...
- @property
- def colspan(self) -> range: ...
- def is_first_row(self) -> bool: ...
- def is_last_row(self) -> bool: ...
- def is_first_col(self) -> bool: ...
- def is_last_col(self) -> bool: ...
- def get_position(self, figure: Figure) -> Bbox: ...
- def get_topmost_subplotspec(self) -> SubplotSpec: ...
- def __eq__(self, other: object) -> bool: ...
- def __hash__(self) -> int: ...
- def subgridspec(
- self, nrows: int, ncols: int, **kwargs
- ) -> GridSpecFromSubplotSpec: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/hatch.py b/contrib/python/matplotlib/py3/matplotlib/hatch.py
deleted file mode 100644
index 9ec88776cf..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/hatch.py
+++ /dev/null
@@ -1,225 +0,0 @@
-"""Contains classes for generating hatch patterns."""
-
-import numpy as np
-
-from matplotlib import _api
-from matplotlib.path import Path
-
-
-class HatchPatternBase:
- """The base class for a hatch pattern."""
- pass
-
-
-class HorizontalHatch(HatchPatternBase):
- def __init__(self, hatch, density):
- self.num_lines = int((hatch.count('-') + hatch.count('+')) * density)
- self.num_vertices = self.num_lines * 2
-
- def set_vertices_and_codes(self, vertices, codes):
- steps, stepsize = np.linspace(0.0, 1.0, self.num_lines, False,
- retstep=True)
- steps += stepsize / 2.
- vertices[0::2, 0] = 0.0
- vertices[0::2, 1] = steps
- vertices[1::2, 0] = 1.0
- vertices[1::2, 1] = steps
- codes[0::2] = Path.MOVETO
- codes[1::2] = Path.LINETO
-
-
-class VerticalHatch(HatchPatternBase):
- def __init__(self, hatch, density):
- self.num_lines = int((hatch.count('|') + hatch.count('+')) * density)
- self.num_vertices = self.num_lines * 2
-
- def set_vertices_and_codes(self, vertices, codes):
- steps, stepsize = np.linspace(0.0, 1.0, self.num_lines, False,
- retstep=True)
- steps += stepsize / 2.
- vertices[0::2, 0] = steps
- vertices[0::2, 1] = 0.0
- vertices[1::2, 0] = steps
- vertices[1::2, 1] = 1.0
- codes[0::2] = Path.MOVETO
- codes[1::2] = Path.LINETO
-
-
-class NorthEastHatch(HatchPatternBase):
- def __init__(self, hatch, density):
- self.num_lines = int(
- (hatch.count('/') + hatch.count('x') + hatch.count('X')) * density)
- if self.num_lines:
- self.num_vertices = (self.num_lines + 1) * 2
- else:
- self.num_vertices = 0
-
- def set_vertices_and_codes(self, vertices, codes):
- steps = np.linspace(-0.5, 0.5, self.num_lines + 1)
- vertices[0::2, 0] = 0.0 + steps
- vertices[0::2, 1] = 0.0 - steps
- vertices[1::2, 0] = 1.0 + steps
- vertices[1::2, 1] = 1.0 - steps
- codes[0::2] = Path.MOVETO
- codes[1::2] = Path.LINETO
-
-
-class SouthEastHatch(HatchPatternBase):
- def __init__(self, hatch, density):
- self.num_lines = int(
- (hatch.count('\\') + hatch.count('x') + hatch.count('X'))
- * density)
- if self.num_lines:
- self.num_vertices = (self.num_lines + 1) * 2
- else:
- self.num_vertices = 0
-
- def set_vertices_and_codes(self, vertices, codes):
- steps = np.linspace(-0.5, 0.5, self.num_lines + 1)
- vertices[0::2, 0] = 0.0 + steps
- vertices[0::2, 1] = 1.0 + steps
- vertices[1::2, 0] = 1.0 + steps
- vertices[1::2, 1] = 0.0 + steps
- codes[0::2] = Path.MOVETO
- codes[1::2] = Path.LINETO
-
-
-class Shapes(HatchPatternBase):
- filled = False
-
- def __init__(self, hatch, density):
- if self.num_rows == 0:
- self.num_shapes = 0
- self.num_vertices = 0
- else:
- self.num_shapes = ((self.num_rows // 2 + 1) * (self.num_rows + 1) +
- (self.num_rows // 2) * self.num_rows)
- self.num_vertices = (self.num_shapes *
- len(self.shape_vertices) *
- (1 if self.filled else 2))
-
- def set_vertices_and_codes(self, vertices, codes):
- offset = 1.0 / self.num_rows
- shape_vertices = self.shape_vertices * offset * self.size
- shape_codes = self.shape_codes
- if not self.filled:
- shape_vertices = np.concatenate( # Forward, then backward.
- [shape_vertices, shape_vertices[::-1] * 0.9])
- shape_codes = np.concatenate([shape_codes, shape_codes])
- vertices_parts = []
- codes_parts = []
- for row in range(self.num_rows + 1):
- if row % 2 == 0:
- cols = np.linspace(0, 1, self.num_rows + 1)
- else:
- cols = np.linspace(offset / 2, 1 - offset / 2, self.num_rows)
- row_pos = row * offset
- for col_pos in cols:
- vertices_parts.append(shape_vertices + [col_pos, row_pos])
- codes_parts.append(shape_codes)
- np.concatenate(vertices_parts, out=vertices)
- np.concatenate(codes_parts, out=codes)
-
-
-class Circles(Shapes):
- def __init__(self, hatch, density):
- path = Path.unit_circle()
- self.shape_vertices = path.vertices
- self.shape_codes = path.codes
- super().__init__(hatch, density)
-
-
-class SmallCircles(Circles):
- size = 0.2
-
- def __init__(self, hatch, density):
- self.num_rows = (hatch.count('o')) * density
- super().__init__(hatch, density)
-
-
-class LargeCircles(Circles):
- size = 0.35
-
- def __init__(self, hatch, density):
- self.num_rows = (hatch.count('O')) * density
- super().__init__(hatch, density)
-
-
-class SmallFilledCircles(Circles):
- size = 0.1
- filled = True
-
- def __init__(self, hatch, density):
- self.num_rows = (hatch.count('.')) * density
- super().__init__(hatch, density)
-
-
-class Stars(Shapes):
- size = 1.0 / 3.0
- filled = True
-
- def __init__(self, hatch, density):
- self.num_rows = (hatch.count('*')) * density
- path = Path.unit_regular_star(5)
- self.shape_vertices = path.vertices
- self.shape_codes = np.full(len(self.shape_vertices), Path.LINETO,
- dtype=Path.code_type)
- self.shape_codes[0] = Path.MOVETO
- super().__init__(hatch, density)
-
-_hatch_types = [
- HorizontalHatch,
- VerticalHatch,
- NorthEastHatch,
- SouthEastHatch,
- SmallCircles,
- LargeCircles,
- SmallFilledCircles,
- Stars
- ]
-
-
-def _validate_hatch_pattern(hatch):
- valid_hatch_patterns = set(r'-+|/\xXoO.*')
- if hatch is not None:
- invalids = set(hatch).difference(valid_hatch_patterns)
- if invalids:
- valid = ''.join(sorted(valid_hatch_patterns))
- invalids = ''.join(sorted(invalids))
- _api.warn_deprecated(
- '3.4',
- removal='3.9', # one release after custom hatches (#20690)
- message=f'hatch must consist of a string of "{valid}" or '
- 'None, but found the following invalid values '
- f'"{invalids}". Passing invalid values is deprecated '
- 'since %(since)s and will become an error %(removal)s.'
- )
-
-
-def get_path(hatchpattern, density=6):
- """
- Given a hatch specifier, *hatchpattern*, generates Path to render
- the hatch in a unit square. *density* is the number of lines per
- unit square.
- """
- density = int(density)
-
- patterns = [hatch_type(hatchpattern, density)
- for hatch_type in _hatch_types]
- num_vertices = sum([pattern.num_vertices for pattern in patterns])
-
- if num_vertices == 0:
- return Path(np.empty((0, 2)))
-
- vertices = np.empty((num_vertices, 2))
- codes = np.empty(num_vertices, Path.code_type)
-
- cursor = 0
- for pattern in patterns:
- if pattern.num_vertices != 0:
- vertices_chunk = vertices[cursor:cursor + pattern.num_vertices]
- codes_chunk = codes[cursor:cursor + pattern.num_vertices]
- pattern.set_vertices_and_codes(vertices_chunk, codes_chunk)
- cursor += pattern.num_vertices
-
- return Path(vertices, codes)
diff --git a/contrib/python/matplotlib/py3/matplotlib/hatch.pyi b/contrib/python/matplotlib/py3/matplotlib/hatch.pyi
deleted file mode 100644
index 348cf52149..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/hatch.pyi
+++ /dev/null
@@ -1,68 +0,0 @@
-from matplotlib.path import Path
-
-import numpy as np
-from numpy.typing import ArrayLike
-
-class HatchPatternBase: ...
-
-class HorizontalHatch(HatchPatternBase):
- num_lines: int
- num_vertices: int
- def __init__(self, hatch: str, density: int) -> None: ...
- def set_vertices_and_codes(self, vertices: ArrayLike, codes: ArrayLike) -> None: ...
-
-class VerticalHatch(HatchPatternBase):
- num_lines: int
- num_vertices: int
- def __init__(self, hatch: str, density: int) -> None: ...
- def set_vertices_and_codes(self, vertices: ArrayLike, codes: ArrayLike) -> None: ...
-
-class NorthEastHatch(HatchPatternBase):
- num_lines: int
- num_vertices: int
- def __init__(self, hatch: str, density: int) -> None: ...
- def set_vertices_and_codes(self, vertices: ArrayLike, codes: ArrayLike) -> None: ...
-
-class SouthEastHatch(HatchPatternBase):
- num_lines: int
- num_vertices: int
- def __init__(self, hatch: str, density: int) -> None: ...
- def set_vertices_and_codes(self, vertices: ArrayLike, codes: ArrayLike) -> None: ...
-
-class Shapes(HatchPatternBase):
- filled: bool
- num_shapes: int
- num_vertices: int
- def __init__(self, hatch: str, density: int) -> None: ...
- def set_vertices_and_codes(self, vertices: ArrayLike, codes: ArrayLike) -> None: ...
-
-class Circles(Shapes):
- shape_vertices: np.ndarray
- shape_codes: np.ndarray
- def __init__(self, hatch: str, density: int) -> None: ...
-
-class SmallCircles(Circles):
- size: float
- num_rows: int
- def __init__(self, hatch: str, density: int) -> None: ...
-
-class LargeCircles(Circles):
- size: float
- num_rows: int
- def __init__(self, hatch: str, density: int) -> None: ...
-
-class SmallFilledCircles(Circles):
- size: float
- filled: bool
- num_rows: int
- def __init__(self, hatch: str, density: int) -> None: ...
-
-class Stars(Shapes):
- size: float
- filled: bool
- num_rows: int
- shape_vertices: np.ndarray
- shape_codes: np.ndarray
- def __init__(self, hatch: str, density: int) -> None: ...
-
-def get_path(hatchpattern: str, density: int = ...) -> Path: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/image.py b/contrib/python/matplotlib/py3/matplotlib/image.py
deleted file mode 100644
index 757f0ba347..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/image.py
+++ /dev/null
@@ -1,1785 +0,0 @@
-"""
-The image module supports basic image loading, rescaling and display
-operations.
-"""
-
-import math
-import os
-import logging
-from pathlib import Path
-import warnings
-
-import numpy as np
-import PIL.Image
-import PIL.PngImagePlugin
-
-import matplotlib as mpl
-from matplotlib import _api, cbook, cm
-# For clarity, names from _image are given explicitly in this module
-from matplotlib import _image
-# For user convenience, the names from _image are also imported into
-# the image namespace
-from matplotlib._image import *
-import matplotlib.artist as martist
-from matplotlib.backend_bases import FigureCanvasBase
-import matplotlib.colors as mcolors
-from matplotlib.transforms import (
- Affine2D, BboxBase, Bbox, BboxTransform, BboxTransformTo,
- IdentityTransform, TransformedBbox)
-
-_log = logging.getLogger(__name__)
-
-# map interpolation strings to module constants
-_interpd_ = {
- 'antialiased': _image.NEAREST, # this will use nearest or Hanning...
- 'none': _image.NEAREST, # fall back to nearest when not supported
- 'nearest': _image.NEAREST,
- 'bilinear': _image.BILINEAR,
- 'bicubic': _image.BICUBIC,
- 'spline16': _image.SPLINE16,
- 'spline36': _image.SPLINE36,
- 'hanning': _image.HANNING,
- 'hamming': _image.HAMMING,
- 'hermite': _image.HERMITE,
- 'kaiser': _image.KAISER,
- 'quadric': _image.QUADRIC,
- 'catrom': _image.CATROM,
- 'gaussian': _image.GAUSSIAN,
- 'bessel': _image.BESSEL,
- 'mitchell': _image.MITCHELL,
- 'sinc': _image.SINC,
- 'lanczos': _image.LANCZOS,
- 'blackman': _image.BLACKMAN,
-}
-
-interpolations_names = set(_interpd_)
-
-
-def composite_images(images, renderer, magnification=1.0):
- """
- Composite a number of RGBA images into one. The images are
- composited in the order in which they appear in the *images* list.
-
- Parameters
- ----------
- images : list of Images
- Each must have a `make_image` method. For each image,
- `can_composite` should return `True`, though this is not
- enforced by this function. Each image must have a purely
- affine transformation with no shear.
-
- renderer : `.RendererBase`
-
- magnification : float, default: 1
- The additional magnification to apply for the renderer in use.
-
- Returns
- -------
- image : (M, N, 4) `numpy.uint8` array
- The composited RGBA image.
- offset_x, offset_y : float
- The (left, bottom) offset where the composited image should be placed
- in the output figure.
- """
- if len(images) == 0:
- return np.empty((0, 0, 4), dtype=np.uint8), 0, 0
-
- parts = []
- bboxes = []
- for image in images:
- data, x, y, trans = image.make_image(renderer, magnification)
- if data is not None:
- x *= magnification
- y *= magnification
- parts.append((data, x, y, image._get_scalar_alpha()))
- bboxes.append(
- Bbox([[x, y], [x + data.shape[1], y + data.shape[0]]]))
-
- if len(parts) == 0:
- return np.empty((0, 0, 4), dtype=np.uint8), 0, 0
-
- bbox = Bbox.union(bboxes)
-
- output = np.zeros(
- (int(bbox.height), int(bbox.width), 4), dtype=np.uint8)
-
- for data, x, y, alpha in parts:
- trans = Affine2D().translate(x - bbox.x0, y - bbox.y0)
- _image.resample(data, output, trans, _image.NEAREST,
- resample=False, alpha=alpha)
-
- return output, bbox.x0 / magnification, bbox.y0 / magnification
-
-
-def _draw_list_compositing_images(
- renderer, parent, artists, suppress_composite=None):
- """
- Draw a sorted list of artists, compositing images into a single
- image where possible.
-
- For internal Matplotlib use only: It is here to reduce duplication
- between `Figure.draw` and `Axes.draw`, but otherwise should not be
- generally useful.
- """
- has_images = any(isinstance(x, _ImageBase) for x in artists)
-
- # override the renderer default if suppressComposite is not None
- not_composite = (suppress_composite if suppress_composite is not None
- else renderer.option_image_nocomposite())
-
- if not_composite or not has_images:
- for a in artists:
- a.draw(renderer)
- else:
- # Composite any adjacent images together
- image_group = []
- mag = renderer.get_image_magnification()
-
- def flush_images():
- if len(image_group) == 1:
- image_group[0].draw(renderer)
- elif len(image_group) > 1:
- data, l, b = composite_images(image_group, renderer, mag)
- if data.size != 0:
- gc = renderer.new_gc()
- gc.set_clip_rectangle(parent.bbox)
- gc.set_clip_path(parent.get_clip_path())
- renderer.draw_image(gc, round(l), round(b), data)
- gc.restore()
- del image_group[:]
-
- for a in artists:
- if (isinstance(a, _ImageBase) and a.can_composite() and
- a.get_clip_on() and not a.get_clip_path()):
- image_group.append(a)
- else:
- flush_images()
- a.draw(renderer)
- flush_images()
-
-
-def _resample(
- image_obj, data, out_shape, transform, *, resample=None, alpha=1):
- """
- Convenience wrapper around `._image.resample` to resample *data* to
- *out_shape* (with a third dimension if *data* is RGBA) that takes care of
- allocating the output array and fetching the relevant properties from the
- Image object *image_obj*.
- """
- # AGG can only handle coordinates smaller than 24-bit signed integers,
- # so raise errors if the input data is larger than _image.resample can
- # handle.
- msg = ('Data with more than {n} cannot be accurately displayed. '
- 'Downsampling to less than {n} before displaying. '
- 'To remove this warning, manually downsample your data.')
- if data.shape[1] > 2**23:
- warnings.warn(msg.format(n='2**23 columns'))
- step = int(np.ceil(data.shape[1] / 2**23))
- data = data[:, ::step]
- transform = Affine2D().scale(step, 1) + transform
- if data.shape[0] > 2**24:
- warnings.warn(msg.format(n='2**24 rows'))
- step = int(np.ceil(data.shape[0] / 2**24))
- data = data[::step, :]
- transform = Affine2D().scale(1, step) + transform
- # decide if we need to apply anti-aliasing if the data is upsampled:
- # compare the number of displayed pixels to the number of
- # the data pixels.
- interpolation = image_obj.get_interpolation()
- if interpolation == 'antialiased':
- # don't antialias if upsampling by an integer number or
- # if zooming in more than a factor of 3
- pos = np.array([[0, 0], [data.shape[1], data.shape[0]]])
- disp = transform.transform(pos)
- dispx = np.abs(np.diff(disp[:, 0]))
- dispy = np.abs(np.diff(disp[:, 1]))
- if ((dispx > 3 * data.shape[1] or
- dispx == data.shape[1] or
- dispx == 2 * data.shape[1]) and
- (dispy > 3 * data.shape[0] or
- dispy == data.shape[0] or
- dispy == 2 * data.shape[0])):
- interpolation = 'nearest'
- else:
- interpolation = 'hanning'
- out = np.zeros(out_shape + data.shape[2:], data.dtype) # 2D->2D, 3D->3D.
- if resample is None:
- resample = image_obj.get_resample()
- _image.resample(data, out, transform,
- _interpd_[interpolation],
- resample,
- alpha,
- image_obj.get_filternorm(),
- image_obj.get_filterrad())
- return out
-
-
-def _rgb_to_rgba(A):
- """
- Convert an RGB image to RGBA, as required by the image resample C++
- extension.
- """
- rgba = np.zeros((A.shape[0], A.shape[1], 4), dtype=A.dtype)
- rgba[:, :, :3] = A
- if rgba.dtype == np.uint8:
- rgba[:, :, 3] = 255
- else:
- rgba[:, :, 3] = 1.0
- return rgba
-
-
-class _ImageBase(martist.Artist, cm.ScalarMappable):
- """
- Base class for images.
-
- interpolation and cmap default to their rc settings
-
- cmap is a colors.Colormap instance
- norm is a colors.Normalize instance to map luminance to 0-1
-
- extent is data axes (left, right, bottom, top) for making image plots
- registered with data plots. Default is to label the pixel
- centers with the zero-based row and column indices.
-
- Additional kwargs are matplotlib.artist properties
- """
- zorder = 0
-
- def __init__(self, ax,
- cmap=None,
- norm=None,
- interpolation=None,
- origin=None,
- filternorm=True,
- filterrad=4.0,
- resample=False,
- *,
- interpolation_stage=None,
- **kwargs
- ):
- martist.Artist.__init__(self)
- cm.ScalarMappable.__init__(self, norm, cmap)
- if origin is None:
- origin = mpl.rcParams['image.origin']
- _api.check_in_list(["upper", "lower"], origin=origin)
- self.origin = origin
- self.set_filternorm(filternorm)
- self.set_filterrad(filterrad)
- self.set_interpolation(interpolation)
- self.set_interpolation_stage(interpolation_stage)
- self.set_resample(resample)
- self.axes = ax
-
- self._imcache = None
-
- self._internal_update(kwargs)
-
- def __str__(self):
- try:
- shape = self.get_shape()
- return f"{type(self).__name__}(shape={shape!r})"
- except RuntimeError:
- return type(self).__name__
-
- def __getstate__(self):
- # Save some space on the pickle by not saving the cache.
- return {**super().__getstate__(), "_imcache": None}
-
- def get_size(self):
- """Return the size of the image as tuple (numrows, numcols)."""
- return self.get_shape()[:2]
-
- def get_shape(self):
- """
- Return the shape of the image as tuple (numrows, numcols, channels).
- """
- if self._A is None:
- raise RuntimeError('You must first set the image array')
-
- return self._A.shape
-
- def set_alpha(self, alpha):
- """
- Set the alpha value used for blending - not supported on all backends.
-
- Parameters
- ----------
- alpha : float or 2D array-like or None
- """
- martist.Artist._set_alpha_for_array(self, alpha)
- if np.ndim(alpha) not in (0, 2):
- raise TypeError('alpha must be a float, two-dimensional '
- 'array, or None')
- self._imcache = None
-
- def _get_scalar_alpha(self):
- """
- Get a scalar alpha value to be applied to the artist as a whole.
-
- If the alpha value is a matrix, the method returns 1.0 because pixels
- have individual alpha values (see `~._ImageBase._make_image` for
- details). If the alpha value is a scalar, the method returns said value
- to be applied to the artist as a whole because pixels do not have
- individual alpha values.
- """
- return 1.0 if self._alpha is None or np.ndim(self._alpha) > 0 \
- else self._alpha
-
- def changed(self):
- """
- Call this whenever the mappable is changed so observers can update.
- """
- self._imcache = None
- cm.ScalarMappable.changed(self)
-
- def _make_image(self, A, in_bbox, out_bbox, clip_bbox, magnification=1.0,
- unsampled=False, round_to_pixel_border=True):
- """
- Normalize, rescale, and colormap the image *A* from the given *in_bbox*
- (in data space), to the given *out_bbox* (in pixel space) clipped to
- the given *clip_bbox* (also in pixel space), and magnified by the
- *magnification* factor.
-
- *A* may be a greyscale image (M, N) with a dtype of `~numpy.float32`,
- `~numpy.float64`, `~numpy.float128`, `~numpy.uint16` or `~numpy.uint8`,
- or an (M, N, 4) RGBA image with a dtype of `~numpy.float32`,
- `~numpy.float64`, `~numpy.float128`, or `~numpy.uint8`.
-
- If *unsampled* is True, the image will not be scaled, but an
- appropriate affine transformation will be returned instead.
-
- If *round_to_pixel_border* is True, the output image size will be
- rounded to the nearest pixel boundary. This makes the images align
- correctly with the axes. It should not be used if exact scaling is
- needed, such as for `FigureImage`.
-
- Returns
- -------
- image : (M, N, 4) `numpy.uint8` array
- The RGBA image, resampled unless *unsampled* is True.
- x, y : float
- The upper left corner where the image should be drawn, in pixel
- space.
- trans : `~matplotlib.transforms.Affine2D`
- The affine transformation from image to pixel space.
- """
- if A is None:
- raise RuntimeError('You must first set the image '
- 'array or the image attribute')
- if A.size == 0:
- raise RuntimeError("_make_image must get a non-empty image. "
- "Your Artist's draw method must filter before "
- "this method is called.")
-
- clipped_bbox = Bbox.intersection(out_bbox, clip_bbox)
-
- if clipped_bbox is None:
- return None, 0, 0, None
-
- out_width_base = clipped_bbox.width * magnification
- out_height_base = clipped_bbox.height * magnification
-
- if out_width_base == 0 or out_height_base == 0:
- return None, 0, 0, None
-
- if self.origin == 'upper':
- # Flip the input image using a transform. This avoids the
- # problem with flipping the array, which results in a copy
- # when it is converted to contiguous in the C wrapper
- t0 = Affine2D().translate(0, -A.shape[0]).scale(1, -1)
- else:
- t0 = IdentityTransform()
-
- t0 += (
- Affine2D()
- .scale(
- in_bbox.width / A.shape[1],
- in_bbox.height / A.shape[0])
- .translate(in_bbox.x0, in_bbox.y0)
- + self.get_transform())
-
- t = (t0
- + (Affine2D()
- .translate(-clipped_bbox.x0, -clipped_bbox.y0)
- .scale(magnification)))
-
- # So that the image is aligned with the edge of the axes, we want to
- # round up the output width to the next integer. This also means
- # scaling the transform slightly to account for the extra subpixel.
- if ((not unsampled) and t.is_affine and round_to_pixel_border and
- (out_width_base % 1.0 != 0.0 or out_height_base % 1.0 != 0.0)):
- out_width = math.ceil(out_width_base)
- out_height = math.ceil(out_height_base)
- extra_width = (out_width - out_width_base) / out_width_base
- extra_height = (out_height - out_height_base) / out_height_base
- t += Affine2D().scale(1.0 + extra_width, 1.0 + extra_height)
- else:
- out_width = int(out_width_base)
- out_height = int(out_height_base)
- out_shape = (out_height, out_width)
-
- if not unsampled:
- if not (A.ndim == 2 or A.ndim == 3 and A.shape[-1] in (3, 4)):
- raise ValueError(f"Invalid shape {A.shape} for image data")
- if A.ndim == 2 and self._interpolation_stage != 'rgba':
- # if we are a 2D array, then we are running through the
- # norm + colormap transformation. However, in general the
- # input data is not going to match the size on the screen so we
- # have to resample to the correct number of pixels
-
- # TODO slice input array first
- a_min = A.min()
- a_max = A.max()
- if a_min is np.ma.masked: # All masked; values don't matter.
- a_min, a_max = np.int32(0), np.int32(1)
- if A.dtype.kind == 'f': # Float dtype: scale to same dtype.
- scaled_dtype = np.dtype(
- np.float64 if A.dtype.itemsize > 4 else np.float32)
- if scaled_dtype.itemsize < A.dtype.itemsize:
- _api.warn_external(f"Casting input data from {A.dtype}"
- f" to {scaled_dtype} for imshow.")
- else: # Int dtype, likely.
- # Scale to appropriately sized float: use float32 if the
- # dynamic range is small, to limit the memory footprint.
- da = a_max.astype(np.float64) - a_min.astype(np.float64)
- scaled_dtype = np.float64 if da > 1e8 else np.float32
-
- # Scale the input data to [.1, .9]. The Agg interpolators clip
- # to [0, 1] internally, and we use a smaller input scale to
- # identify the interpolated points that need to be flagged as
- # over/under. This may introduce numeric instabilities in very
- # broadly scaled data.
-
- # Always copy, and don't allow array subtypes.
- A_scaled = np.array(A, dtype=scaled_dtype)
- # Clip scaled data around norm if necessary. This is necessary
- # for big numbers at the edge of float64's ability to represent
- # changes. Applying a norm first would be good, but ruins the
- # interpolation of over numbers.
- self.norm.autoscale_None(A)
- dv = np.float64(self.norm.vmax) - np.float64(self.norm.vmin)
- vmid = np.float64(self.norm.vmin) + dv / 2
- fact = 1e7 if scaled_dtype == np.float64 else 1e4
- newmin = vmid - dv * fact
- if newmin < a_min:
- newmin = None
- else:
- a_min = np.float64(newmin)
- newmax = vmid + dv * fact
- if newmax > a_max:
- newmax = None
- else:
- a_max = np.float64(newmax)
- if newmax is not None or newmin is not None:
- np.clip(A_scaled, newmin, newmax, out=A_scaled)
-
- # Rescale the raw data to [offset, 1-offset] so that the
- # resampling code will run cleanly. Using dyadic numbers here
- # could reduce the error, but would not fully eliminate it and
- # breaks a number of tests (due to the slightly different
- # error bouncing some pixels across a boundary in the (very
- # quantized) colormapping step).
- offset = .1
- frac = .8
- # Run vmin/vmax through the same rescaling as the raw data;
- # otherwise, data values close or equal to the boundaries can
- # end up on the wrong side due to floating point error.
- vmin, vmax = self.norm.vmin, self.norm.vmax
- if vmin is np.ma.masked:
- vmin, vmax = a_min, a_max
- vrange = np.array([vmin, vmax], dtype=scaled_dtype)
-
- A_scaled -= a_min
- vrange -= a_min
- # .item() handles a_min/a_max being ndarray subclasses.
- a_min = a_min.astype(scaled_dtype).item()
- a_max = a_max.astype(scaled_dtype).item()
-
- if a_min != a_max:
- A_scaled /= ((a_max - a_min) / frac)
- vrange /= ((a_max - a_min) / frac)
- A_scaled += offset
- vrange += offset
- # resample the input data to the correct resolution and shape
- A_resampled = _resample(self, A_scaled, out_shape, t)
- del A_scaled # Make sure we don't use A_scaled anymore!
- # Un-scale the resampled data to approximately the original
- # range. Things that interpolated to outside the original range
- # will still be outside, but possibly clipped in the case of
- # higher order interpolation + drastically changing data.
- A_resampled -= offset
- vrange -= offset
- if a_min != a_max:
- A_resampled *= ((a_max - a_min) / frac)
- vrange *= ((a_max - a_min) / frac)
- A_resampled += a_min
- vrange += a_min
- # if using NoNorm, cast back to the original datatype
- if isinstance(self.norm, mcolors.NoNorm):
- A_resampled = A_resampled.astype(A.dtype)
-
- mask = (np.where(A.mask, np.float32(np.nan), np.float32(1))
- if A.mask.shape == A.shape # nontrivial mask
- else np.ones_like(A, np.float32))
- # we always have to interpolate the mask to account for
- # non-affine transformations
- out_alpha = _resample(self, mask, out_shape, t, resample=True)
- del mask # Make sure we don't use mask anymore!
- # Agg updates out_alpha in place. If the pixel has no image
- # data it will not be updated (and still be 0 as we initialized
- # it), if input data that would go into that output pixel than
- # it will be `nan`, if all the input data for a pixel is good
- # it will be 1, and if there is _some_ good data in that output
- # pixel it will be between [0, 1] (such as a rotated image).
- out_mask = np.isnan(out_alpha)
- out_alpha[out_mask] = 1
- # Apply the pixel-by-pixel alpha values if present
- alpha = self.get_alpha()
- if alpha is not None and np.ndim(alpha) > 0:
- out_alpha *= _resample(self, alpha, out_shape,
- t, resample=True)
- # mask and run through the norm
- resampled_masked = np.ma.masked_array(A_resampled, out_mask)
- # we have re-set the vmin/vmax to account for small errors
- # that may have moved input values in/out of range
- s_vmin, s_vmax = vrange
- if isinstance(self.norm, mcolors.LogNorm) and s_vmin <= 0:
- # Don't give 0 or negative values to LogNorm
- s_vmin = np.finfo(scaled_dtype).eps
- # Block the norm from sending an update signal during the
- # temporary vmin/vmax change
- with self.norm.callbacks.blocked(), \
- cbook._setattr_cm(self.norm, vmin=s_vmin, vmax=s_vmax):
- output = self.norm(resampled_masked)
- else:
- if A.ndim == 2: # _interpolation_stage == 'rgba'
- self.norm.autoscale_None(A)
- A = self.to_rgba(A)
- if A.shape[2] == 3:
- A = _rgb_to_rgba(A)
- alpha = self._get_scalar_alpha()
- output_alpha = _resample( # resample alpha channel
- self, A[..., 3], out_shape, t, alpha=alpha)
- output = _resample( # resample rgb channels
- self, _rgb_to_rgba(A[..., :3]), out_shape, t, alpha=alpha)
- output[..., 3] = output_alpha # recombine rgb and alpha
-
- # output is now either a 2D array of normed (int or float) data
- # or an RGBA array of re-sampled input
- output = self.to_rgba(output, bytes=True, norm=False)
- # output is now a correctly sized RGBA array of uint8
-
- # Apply alpha *after* if the input was greyscale without a mask
- if A.ndim == 2:
- alpha = self._get_scalar_alpha()
- alpha_channel = output[:, :, 3]
- alpha_channel[:] = ( # Assignment will cast to uint8.
- alpha_channel.astype(np.float32) * out_alpha * alpha)
-
- else:
- if self._imcache is None:
- self._imcache = self.to_rgba(A, bytes=True, norm=(A.ndim == 2))
- output = self._imcache
-
- # Subset the input image to only the part that will be displayed.
- subset = TransformedBbox(clip_bbox, t0.inverted()).frozen()
- output = output[
- int(max(subset.ymin, 0)):
- int(min(subset.ymax + 1, output.shape[0])),
- int(max(subset.xmin, 0)):
- int(min(subset.xmax + 1, output.shape[1]))]
-
- t = Affine2D().translate(
- int(max(subset.xmin, 0)), int(max(subset.ymin, 0))) + t
-
- return output, clipped_bbox.x0, clipped_bbox.y0, t
-
- def make_image(self, renderer, magnification=1.0, unsampled=False):
- """
- Normalize, rescale, and colormap this image's data for rendering using
- *renderer*, with the given *magnification*.
-
- If *unsampled* is True, the image will not be scaled, but an
- appropriate affine transformation will be returned instead.
-
- Returns
- -------
- image : (M, N, 4) `numpy.uint8` array
- The RGBA image, resampled unless *unsampled* is True.
- x, y : float
- The upper left corner where the image should be drawn, in pixel
- space.
- trans : `~matplotlib.transforms.Affine2D`
- The affine transformation from image to pixel space.
- """
- raise NotImplementedError('The make_image method must be overridden')
-
- def _check_unsampled_image(self):
- """
- Return whether the image is better to be drawn unsampled.
-
- The derived class needs to override it.
- """
- return False
-
- @martist.allow_rasterization
- def draw(self, renderer, *args, **kwargs):
- # if not visible, declare victory and return
- if not self.get_visible():
- self.stale = False
- return
- # for empty images, there is nothing to draw!
- if self.get_array().size == 0:
- self.stale = False
- return
- # actually render the image.
- gc = renderer.new_gc()
- self._set_gc_clip(gc)
- gc.set_alpha(self._get_scalar_alpha())
- gc.set_url(self.get_url())
- gc.set_gid(self.get_gid())
- if (renderer.option_scale_image() # Renderer supports transform kwarg.
- and self._check_unsampled_image()
- and self.get_transform().is_affine):
- im, l, b, trans = self.make_image(renderer, unsampled=True)
- if im is not None:
- trans = Affine2D().scale(im.shape[1], im.shape[0]) + trans
- renderer.draw_image(gc, l, b, im, trans)
- else:
- im, l, b, trans = self.make_image(
- renderer, renderer.get_image_magnification())
- if im is not None:
- renderer.draw_image(gc, l, b, im)
- gc.restore()
- self.stale = False
-
- def contains(self, mouseevent):
- """Test whether the mouse event occurred within the image."""
- if (self._different_canvas(mouseevent)
- # This doesn't work for figimage.
- or not self.axes.contains(mouseevent)[0]):
- return False, {}
- # TODO: make sure this is consistent with patch and patch
- # collection on nonlinear transformed coordinates.
- # TODO: consider returning image coordinates (shouldn't
- # be too difficult given that the image is rectilinear
- trans = self.get_transform().inverted()
- x, y = trans.transform([mouseevent.x, mouseevent.y])
- xmin, xmax, ymin, ymax = self.get_extent()
- # This checks xmin <= x <= xmax *or* xmax <= x <= xmin.
- inside = (x is not None and (x - xmin) * (x - xmax) <= 0
- and y is not None and (y - ymin) * (y - ymax) <= 0)
- return inside, {}
-
- def write_png(self, fname):
- """Write the image to png file *fname*."""
- im = self.to_rgba(self._A[::-1] if self.origin == 'lower' else self._A,
- bytes=True, norm=True)
- PIL.Image.fromarray(im).save(fname, format="png")
-
- @staticmethod
- def _normalize_image_array(A):
- """
- Check validity of image-like input *A* and normalize it to a format suitable for
- Image subclasses.
- """
- A = cbook.safe_masked_invalid(A, copy=True)
- if A.dtype != np.uint8 and not np.can_cast(A.dtype, float, "same_kind"):
- raise TypeError(f"Image data of dtype {A.dtype} cannot be "
- f"converted to float")
- if A.ndim == 3 and A.shape[-1] == 1:
- A = A.squeeze(-1) # If just (M, N, 1), assume scalar and apply colormap.
- if not (A.ndim == 2 or A.ndim == 3 and A.shape[-1] in [3, 4]):
- raise TypeError(f"Invalid shape {A.shape} for image data")
- if A.ndim == 3:
- # If the input data has values outside the valid range (after
- # normalisation), we issue a warning and then clip X to the bounds
- # - otherwise casting wraps extreme values, hiding outliers and
- # making reliable interpretation impossible.
- high = 255 if np.issubdtype(A.dtype, np.integer) else 1
- if A.min() < 0 or high < A.max():
- _log.warning(
- 'Clipping input data to the valid range for imshow with '
- 'RGB data ([0..1] for floats or [0..255] for integers).'
- )
- A = np.clip(A, 0, high)
- # Cast unsupported integer types to uint8
- if A.dtype != np.uint8 and np.issubdtype(A.dtype, np.integer):
- A = A.astype(np.uint8)
- return A
-
- def set_data(self, A):
- """
- Set the image array.
-
- Note that this function does *not* update the normalization used.
-
- Parameters
- ----------
- A : array-like or `PIL.Image.Image`
- """
- if isinstance(A, PIL.Image.Image):
- A = pil_to_array(A) # Needed e.g. to apply png palette.
- self._A = self._normalize_image_array(A)
- self._imcache = None
- self.stale = True
-
- def set_array(self, A):
- """
- Retained for backwards compatibility - use set_data instead.
-
- Parameters
- ----------
- A : array-like
- """
- # This also needs to be here to override the inherited
- # cm.ScalarMappable.set_array method so it is not invoked by mistake.
- self.set_data(A)
-
- def get_interpolation(self):
- """
- Return the interpolation method the image uses when resizing.
-
- One of 'antialiased', 'nearest', 'bilinear', 'bicubic', 'spline16',
- 'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric',
- 'catrom', 'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos',
- or 'none'.
- """
- return self._interpolation
-
- def set_interpolation(self, s):
- """
- Set the interpolation method the image uses when resizing.
-
- If None, use :rc:`image.interpolation`. If 'none', the image is
- shown as is without interpolating. 'none' is only supported in
- agg, ps and pdf backends and will fall back to 'nearest' mode
- for other backends.
-
- Parameters
- ----------
- s : {'antialiased', 'nearest', 'bilinear', 'bicubic', 'spline16', \
-'spline36', 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric', 'catrom', \
-'gaussian', 'bessel', 'mitchell', 'sinc', 'lanczos', 'none'} or None
- """
- s = mpl._val_or_rc(s, 'image.interpolation').lower()
- _api.check_in_list(interpolations_names, interpolation=s)
- self._interpolation = s
- self.stale = True
-
- def set_interpolation_stage(self, s):
- """
- Set when interpolation happens during the transform to RGBA.
-
- Parameters
- ----------
- s : {'data', 'rgba'} or None
- Whether to apply up/downsampling interpolation in data or RGBA
- space.
- """
- if s is None:
- s = "data" # placeholder for maybe having rcParam
- _api.check_in_list(['data', 'rgba'], s=s)
- self._interpolation_stage = s
- self.stale = True
-
- def can_composite(self):
- """Return whether the image can be composited with its neighbors."""
- trans = self.get_transform()
- return (
- self._interpolation != 'none' and
- trans.is_affine and
- trans.is_separable)
-
- def set_resample(self, v):
- """
- Set whether image resampling is used.
-
- Parameters
- ----------
- v : bool or None
- If None, use :rc:`image.resample`.
- """
- v = mpl._val_or_rc(v, 'image.resample')
- self._resample = v
- self.stale = True
-
- def get_resample(self):
- """Return whether image resampling is used."""
- return self._resample
-
- def set_filternorm(self, filternorm):
- """
- Set whether the resize filter normalizes the weights.
-
- See help for `~.Axes.imshow`.
-
- Parameters
- ----------
- filternorm : bool
- """
- self._filternorm = bool(filternorm)
- self.stale = True
-
- def get_filternorm(self):
- """Return whether the resize filter normalizes the weights."""
- return self._filternorm
-
- def set_filterrad(self, filterrad):
- """
- Set the resize filter radius only applicable to some
- interpolation schemes -- see help for imshow
-
- Parameters
- ----------
- filterrad : positive float
- """
- r = float(filterrad)
- if r <= 0:
- raise ValueError("The filter radius must be a positive number")
- self._filterrad = r
- self.stale = True
-
- def get_filterrad(self):
- """Return the filterrad setting."""
- return self._filterrad
-
-
-class AxesImage(_ImageBase):
- """
- An image attached to an Axes.
-
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The axes the image will belong to.
- cmap : str or `~matplotlib.colors.Colormap`, default: :rc:`image.cmap`
- The Colormap instance or registered colormap name used to map scalar
- data to colors.
- norm : str or `~matplotlib.colors.Normalize`
- Maps luminance to 0-1.
- interpolation : str, default: :rc:`image.interpolation`
- Supported values are 'none', 'antialiased', 'nearest', 'bilinear',
- 'bicubic', 'spline16', 'spline36', 'hanning', 'hamming', 'hermite',
- 'kaiser', 'quadric', 'catrom', 'gaussian', 'bessel', 'mitchell',
- 'sinc', 'lanczos', 'blackman'.
- interpolation_stage : {'data', 'rgba'}, default: 'data'
- If 'data', interpolation
- is carried out on the data provided by the user. If 'rgba', the
- interpolation is carried out after the colormapping has been
- applied (visual interpolation).
- origin : {'upper', 'lower'}, default: :rc:`image.origin`
- Place the [0, 0] index of the array in the upper left or lower left
- corner of the axes. The convention 'upper' is typically used for
- matrices and images.
- extent : tuple, optional
- The data axes (left, right, bottom, top) for making image plots
- registered with data plots. Default is to label the pixel
- centers with the zero-based row and column indices.
- filternorm : bool, default: True
- A parameter for the antigrain image resize filter
- (see the antigrain documentation).
- If filternorm is set, the filter normalizes integer values and corrects
- the rounding errors. It doesn't do anything with the source floating
- point values, 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.
- filterrad : float > 0, default: 4
- The filter radius for filters that have a radius parameter, i.e. when
- interpolation is one of: 'sinc', 'lanczos' or 'blackman'.
- resample : bool, default: False
- When True, use a full resampling method. When False, only resample when
- the output image is larger than the input image.
- **kwargs : `~matplotlib.artist.Artist` properties
- """
-
- def __init__(self, ax,
- *,
- cmap=None,
- norm=None,
- interpolation=None,
- origin=None,
- extent=None,
- filternorm=True,
- filterrad=4.0,
- resample=False,
- interpolation_stage=None,
- **kwargs
- ):
-
- self._extent = extent
-
- super().__init__(
- ax,
- cmap=cmap,
- norm=norm,
- interpolation=interpolation,
- origin=origin,
- filternorm=filternorm,
- filterrad=filterrad,
- resample=resample,
- interpolation_stage=interpolation_stage,
- **kwargs
- )
-
- def get_window_extent(self, renderer=None):
- x0, x1, y0, y1 = self._extent
- bbox = Bbox.from_extents([x0, y0, x1, y1])
- return bbox.transformed(self.get_transform())
-
- def make_image(self, renderer, magnification=1.0, unsampled=False):
- # docstring inherited
- trans = self.get_transform()
- # image is created in the canvas coordinate.
- x1, x2, y1, y2 = self.get_extent()
- bbox = Bbox(np.array([[x1, y1], [x2, y2]]))
- transformed_bbox = TransformedBbox(bbox, trans)
- clip = ((self.get_clip_box() or self.axes.bbox) if self.get_clip_on()
- else self.figure.bbox)
- return self._make_image(self._A, bbox, transformed_bbox, clip,
- magnification, unsampled=unsampled)
-
- def _check_unsampled_image(self):
- """Return whether the image would be better drawn unsampled."""
- return self.get_interpolation() == "none"
-
- def set_extent(self, extent, **kwargs):
- """
- Set the image extent.
-
- Parameters
- ----------
- extent : 4-tuple of float
- The position and size of the image as tuple
- ``(left, right, bottom, top)`` in data coordinates.
- **kwargs
- Other parameters from which unit info (i.e., the *xunits*,
- *yunits*, *zunits* (for 3D axes), *runits* and *thetaunits* (for
- polar axes) entries are applied, if present.
-
- Notes
- -----
- This updates ``ax.dataLim``, and, if autoscaling, sets ``ax.viewLim``
- to tightly fit the image, regardless of ``dataLim``. Autoscaling
- state is not changed, so following this with ``ax.autoscale_view()``
- will redo the autoscaling in accord with ``dataLim``.
- """
- (xmin, xmax), (ymin, ymax) = self.axes._process_unit_info(
- [("x", [extent[0], extent[1]]),
- ("y", [extent[2], extent[3]])],
- kwargs)
- if kwargs:
- raise _api.kwarg_error("set_extent", kwargs)
- xmin = self.axes._validate_converted_limits(
- xmin, self.convert_xunits)
- xmax = self.axes._validate_converted_limits(
- xmax, self.convert_xunits)
- ymin = self.axes._validate_converted_limits(
- ymin, self.convert_yunits)
- ymax = self.axes._validate_converted_limits(
- ymax, self.convert_yunits)
- extent = [xmin, xmax, ymin, ymax]
-
- self._extent = extent
- corners = (xmin, ymin), (xmax, ymax)
- self.axes.update_datalim(corners)
- self.sticky_edges.x[:] = [xmin, xmax]
- self.sticky_edges.y[:] = [ymin, ymax]
- if self.axes.get_autoscalex_on():
- self.axes.set_xlim((xmin, xmax), auto=None)
- if self.axes.get_autoscaley_on():
- self.axes.set_ylim((ymin, ymax), auto=None)
- self.stale = True
-
- def get_extent(self):
- """Return the image extent as tuple (left, right, bottom, top)."""
- if self._extent is not None:
- return self._extent
- else:
- sz = self.get_size()
- numrows, numcols = sz
- if self.origin == 'upper':
- return (-0.5, numcols-0.5, numrows-0.5, -0.5)
- else:
- return (-0.5, numcols-0.5, -0.5, numrows-0.5)
-
- def get_cursor_data(self, event):
- """
- Return the image value at the event position or *None* if the event is
- outside the image.
-
- See Also
- --------
- matplotlib.artist.Artist.get_cursor_data
- """
- xmin, xmax, ymin, ymax = self.get_extent()
- if self.origin == 'upper':
- ymin, ymax = ymax, ymin
- arr = self.get_array()
- data_extent = Bbox([[xmin, ymin], [xmax, ymax]])
- array_extent = Bbox([[0, 0], [arr.shape[1], arr.shape[0]]])
- trans = self.get_transform().inverted()
- trans += BboxTransform(boxin=data_extent, boxout=array_extent)
- point = trans.transform([event.x, event.y])
- if any(np.isnan(point)):
- return None
- j, i = point.astype(int)
- # Clip the coordinates at array bounds
- if not (0 <= i < arr.shape[0]) or not (0 <= j < arr.shape[1]):
- return None
- else:
- return arr[i, j]
-
-
-class NonUniformImage(AxesImage):
- mouseover = False # This class still needs its own get_cursor_data impl.
-
- def __init__(self, ax, *, interpolation='nearest', **kwargs):
- """
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The axes the image will belong to.
- interpolation : {'nearest', 'bilinear'}, default: 'nearest'
- The interpolation scheme used in the resampling.
- **kwargs
- All other keyword arguments are identical to those of `.AxesImage`.
- """
- super().__init__(ax, **kwargs)
- self.set_interpolation(interpolation)
-
- def _check_unsampled_image(self):
- """Return False. Do not use unsampled image."""
- return False
-
- def make_image(self, renderer, magnification=1.0, unsampled=False):
- # docstring inherited
- if self._A is None:
- raise RuntimeError('You must first set the image array')
- if unsampled:
- raise ValueError('unsampled not supported on NonUniformImage')
- A = self._A
- if A.ndim == 2:
- if A.dtype != np.uint8:
- A = self.to_rgba(A, bytes=True)
- else:
- A = np.repeat(A[:, :, np.newaxis], 4, 2)
- A[:, :, 3] = 255
- else:
- if A.dtype != np.uint8:
- A = (255*A).astype(np.uint8)
- if A.shape[2] == 3:
- B = np.zeros(tuple([*A.shape[0:2], 4]), np.uint8)
- B[:, :, 0:3] = A
- B[:, :, 3] = 255
- A = B
- vl = self.axes.viewLim
- l, b, r, t = self.axes.bbox.extents
- width = int(((round(r) + 0.5) - (round(l) - 0.5)) * magnification)
- height = int(((round(t) + 0.5) - (round(b) - 0.5)) * magnification)
- x_pix = np.linspace(vl.x0, vl.x1, width)
- y_pix = np.linspace(vl.y0, vl.y1, height)
- if self._interpolation == "nearest":
- x_mid = (self._Ax[:-1] + self._Ax[1:]) / 2
- y_mid = (self._Ay[:-1] + self._Ay[1:]) / 2
- x_int = x_mid.searchsorted(x_pix)
- y_int = y_mid.searchsorted(y_pix)
- # The following is equal to `A[y_int[:, None], x_int[None, :]]`,
- # but many times faster. Both casting to uint32 (to have an
- # effectively 1D array) and manual index flattening matter.
- im = (
- np.ascontiguousarray(A).view(np.uint32).ravel()[
- np.add.outer(y_int * A.shape[1], x_int)]
- .view(np.uint8).reshape((height, width, 4)))
- else: # self._interpolation == "bilinear"
- # Use np.interp to compute x_int/x_float has similar speed.
- x_int = np.clip(
- self._Ax.searchsorted(x_pix) - 1, 0, len(self._Ax) - 2)
- y_int = np.clip(
- self._Ay.searchsorted(y_pix) - 1, 0, len(self._Ay) - 2)
- idx_int = np.add.outer(y_int * A.shape[1], x_int)
- x_frac = np.clip(
- np.divide(x_pix - self._Ax[x_int], np.diff(self._Ax)[x_int],
- dtype=np.float32), # Downcasting helps with speed.
- 0, 1)
- y_frac = np.clip(
- np.divide(y_pix - self._Ay[y_int], np.diff(self._Ay)[y_int],
- dtype=np.float32),
- 0, 1)
- f00 = np.outer(1 - y_frac, 1 - x_frac)
- f10 = np.outer(y_frac, 1 - x_frac)
- f01 = np.outer(1 - y_frac, x_frac)
- f11 = np.outer(y_frac, x_frac)
- im = np.empty((height, width, 4), np.uint8)
- for chan in range(4):
- ac = A[:, :, chan].reshape(-1) # reshape(-1) avoids a copy.
- # Shifting the buffer start (`ac[offset:]`) avoids an array
- # addition (`ac[idx_int + offset]`).
- buf = f00 * ac[idx_int]
- buf += f10 * ac[A.shape[1]:][idx_int]
- buf += f01 * ac[1:][idx_int]
- buf += f11 * ac[A.shape[1] + 1:][idx_int]
- im[:, :, chan] = buf # Implicitly casts to uint8.
- return im, l, b, IdentityTransform()
-
- def set_data(self, x, y, A):
- """
- Set the grid for the pixel centers, and the pixel values.
-
- Parameters
- ----------
- x, y : 1D array-like
- Monotonic arrays of shapes (N,) and (M,), respectively, specifying
- pixel centers.
- A : array-like
- (M, N) `~numpy.ndarray` or masked array of values to be
- colormapped, or (M, N, 3) RGB array, or (M, N, 4) RGBA array.
- """
- A = self._normalize_image_array(A)
- x = np.array(x, np.float32)
- y = np.array(y, np.float32)
- if not (x.ndim == y.ndim == 1 and A.shape[:2] == y.shape + x.shape):
- raise TypeError("Axes don't match array shape")
- self._A = A
- self._Ax = x
- self._Ay = y
- self._imcache = None
- self.stale = True
-
- def set_array(self, *args):
- raise NotImplementedError('Method not supported')
-
- def set_interpolation(self, s):
- """
- Parameters
- ----------
- s : {'nearest', 'bilinear'} or None
- If None, use :rc:`image.interpolation`.
- """
- if s is not None and s not in ('nearest', 'bilinear'):
- raise NotImplementedError('Only nearest neighbor and '
- 'bilinear interpolations are supported')
- super().set_interpolation(s)
-
- def get_extent(self):
- if self._A is None:
- raise RuntimeError('Must set data first')
- return self._Ax[0], self._Ax[-1], self._Ay[0], self._Ay[-1]
-
- @_api.rename_parameter("3.8", "s", "filternorm")
- def set_filternorm(self, filternorm):
- pass
-
- @_api.rename_parameter("3.8", "s", "filterrad")
- def set_filterrad(self, filterrad):
- pass
-
- def set_norm(self, norm):
- if self._A is not None:
- raise RuntimeError('Cannot change colors after loading data')
- super().set_norm(norm)
-
- def set_cmap(self, cmap):
- if self._A is not None:
- raise RuntimeError('Cannot change colors after loading data')
- super().set_cmap(cmap)
-
-
-class PcolorImage(AxesImage):
- """
- Make a pcolor-style plot with an irregular rectangular grid.
-
- This uses a variation of the original irregular image code,
- and it is used by pcolorfast for the corresponding grid type.
- """
-
- def __init__(self, ax,
- x=None,
- y=None,
- A=None,
- *,
- cmap=None,
- norm=None,
- **kwargs
- ):
- """
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The axes the image will belong to.
- x, y : 1D array-like, optional
- Monotonic arrays of length N+1 and M+1, respectively, specifying
- rectangle boundaries. If not given, will default to
- ``range(N + 1)`` and ``range(M + 1)``, respectively.
- A : array-like
- The data to be color-coded. The interpretation depends on the
- shape:
-
- - (M, N) `~numpy.ndarray` or masked array: values to be colormapped
- - (M, N, 3): RGB array
- - (M, N, 4): RGBA array
-
- cmap : str or `~matplotlib.colors.Colormap`, default: :rc:`image.cmap`
- The Colormap instance or registered colormap name used to map
- scalar data to colors.
- norm : str or `~matplotlib.colors.Normalize`
- Maps luminance to 0-1.
- **kwargs : `~matplotlib.artist.Artist` properties
- """
- super().__init__(ax, norm=norm, cmap=cmap)
- self._internal_update(kwargs)
- if A is not None:
- self.set_data(x, y, A)
-
- def make_image(self, renderer, magnification=1.0, unsampled=False):
- # docstring inherited
- if self._A is None:
- raise RuntimeError('You must first set the image array')
- if unsampled:
- raise ValueError('unsampled not supported on PColorImage')
-
- if self._imcache is None:
- A = self.to_rgba(self._A, bytes=True)
- self._imcache = np.pad(A, [(1, 1), (1, 1), (0, 0)], "constant")
- padded_A = self._imcache
- bg = mcolors.to_rgba(self.axes.patch.get_facecolor(), 0)
- bg = (np.array(bg) * 255).astype(np.uint8)
- if (padded_A[0, 0] != bg).all():
- padded_A[[0, -1], :] = padded_A[:, [0, -1]] = bg
-
- l, b, r, t = self.axes.bbox.extents
- width = (round(r) + 0.5) - (round(l) - 0.5)
- height = (round(t) + 0.5) - (round(b) - 0.5)
- width = round(width * magnification)
- height = round(height * magnification)
- vl = self.axes.viewLim
-
- x_pix = np.linspace(vl.x0, vl.x1, width)
- y_pix = np.linspace(vl.y0, vl.y1, height)
- x_int = self._Ax.searchsorted(x_pix)
- y_int = self._Ay.searchsorted(y_pix)
- im = ( # See comment in NonUniformImage.make_image re: performance.
- padded_A.view(np.uint32).ravel()[
- np.add.outer(y_int * padded_A.shape[1], x_int)]
- .view(np.uint8).reshape((height, width, 4)))
- return im, l, b, IdentityTransform()
-
- def _check_unsampled_image(self):
- return False
-
- def set_data(self, x, y, A):
- """
- Set the grid for the rectangle boundaries, and the data values.
-
- Parameters
- ----------
- x, y : 1D array-like, optional
- Monotonic arrays of length N+1 and M+1, respectively, specifying
- rectangle boundaries. If not given, will default to
- ``range(N + 1)`` and ``range(M + 1)``, respectively.
- A : array-like
- The data to be color-coded. The interpretation depends on the
- shape:
-
- - (M, N) `~numpy.ndarray` or masked array: values to be colormapped
- - (M, N, 3): RGB array
- - (M, N, 4): RGBA array
- """
- A = self._normalize_image_array(A)
- x = np.arange(0., A.shape[1] + 1) if x is None else np.array(x, float).ravel()
- y = np.arange(0., A.shape[0] + 1) if y is None else np.array(y, float).ravel()
- if A.shape[:2] != (y.size - 1, x.size - 1):
- raise ValueError(
- "Axes don't match array shape. Got %s, expected %s." %
- (A.shape[:2], (y.size - 1, x.size - 1)))
- # For efficient cursor readout, ensure x and y are increasing.
- if x[-1] < x[0]:
- x = x[::-1]
- A = A[:, ::-1]
- if y[-1] < y[0]:
- y = y[::-1]
- A = A[::-1]
- self._A = A
- self._Ax = x
- self._Ay = y
- self._imcache = None
- self.stale = True
-
- def set_array(self, *args):
- raise NotImplementedError('Method not supported')
-
- def get_cursor_data(self, event):
- # docstring inherited
- x, y = event.xdata, event.ydata
- if (x < self._Ax[0] or x > self._Ax[-1] or
- y < self._Ay[0] or y > self._Ay[-1]):
- return None
- j = np.searchsorted(self._Ax, x) - 1
- i = np.searchsorted(self._Ay, y) - 1
- try:
- return self._A[i, j]
- except IndexError:
- return None
-
-
-class FigureImage(_ImageBase):
- """An image attached to a figure."""
-
- zorder = 0
-
- _interpolation = 'nearest'
-
- def __init__(self, fig,
- *,
- cmap=None,
- norm=None,
- offsetx=0,
- offsety=0,
- origin=None,
- **kwargs
- ):
- """
- cmap is a colors.Colormap instance
- norm is a colors.Normalize instance to map luminance to 0-1
-
- kwargs are an optional list of Artist keyword args
- """
- super().__init__(
- None,
- norm=norm,
- cmap=cmap,
- origin=origin
- )
- self.figure = fig
- self.ox = offsetx
- self.oy = offsety
- self._internal_update(kwargs)
- self.magnification = 1.0
-
- def get_extent(self):
- """Return the image extent as tuple (left, right, bottom, top)."""
- numrows, numcols = self.get_size()
- return (-0.5 + self.ox, numcols-0.5 + self.ox,
- -0.5 + self.oy, numrows-0.5 + self.oy)
-
- def make_image(self, renderer, magnification=1.0, unsampled=False):
- # docstring inherited
- fac = renderer.dpi/self.figure.dpi
- # fac here is to account for pdf, eps, svg backends where
- # figure.dpi is set to 72. This means we need to scale the
- # image (using magnification) and offset it appropriately.
- bbox = Bbox([[self.ox/fac, self.oy/fac],
- [(self.ox/fac + self._A.shape[1]),
- (self.oy/fac + self._A.shape[0])]])
- width, height = self.figure.get_size_inches()
- width *= renderer.dpi
- height *= renderer.dpi
- clip = Bbox([[0, 0], [width, height]])
- return self._make_image(
- self._A, bbox, bbox, clip, magnification=magnification / fac,
- unsampled=unsampled, round_to_pixel_border=False)
-
- def set_data(self, A):
- """Set the image array."""
- cm.ScalarMappable.set_array(self, A)
- self.stale = True
-
-
-class BboxImage(_ImageBase):
- """The Image class whose size is determined by the given bbox."""
-
- def __init__(self, bbox,
- *,
- cmap=None,
- norm=None,
- interpolation=None,
- origin=None,
- filternorm=True,
- filterrad=4.0,
- resample=False,
- **kwargs
- ):
- """
- cmap is a colors.Colormap instance
- norm is a colors.Normalize instance to map luminance to 0-1
-
- kwargs are an optional list of Artist keyword args
- """
- super().__init__(
- None,
- cmap=cmap,
- norm=norm,
- interpolation=interpolation,
- origin=origin,
- filternorm=filternorm,
- filterrad=filterrad,
- resample=resample,
- **kwargs
- )
- self.bbox = bbox
-
- def get_window_extent(self, renderer=None):
- if renderer is None:
- renderer = self.get_figure()._get_renderer()
-
- if isinstance(self.bbox, BboxBase):
- return self.bbox
- elif callable(self.bbox):
- return self.bbox(renderer)
- else:
- raise ValueError("Unknown type of bbox")
-
- def contains(self, mouseevent):
- """Test whether the mouse event occurred within the image."""
- if self._different_canvas(mouseevent) or not self.get_visible():
- return False, {}
- x, y = mouseevent.x, mouseevent.y
- inside = self.get_window_extent().contains(x, y)
- return inside, {}
-
- def make_image(self, renderer, magnification=1.0, unsampled=False):
- # docstring inherited
- width, height = renderer.get_canvas_width_height()
- bbox_in = self.get_window_extent(renderer).frozen()
- bbox_in._points /= [width, height]
- bbox_out = self.get_window_extent(renderer)
- clip = Bbox([[0, 0], [width, height]])
- self._transform = BboxTransformTo(clip)
- return self._make_image(
- self._A,
- bbox_in, bbox_out, clip, magnification, unsampled=unsampled)
-
-
-def imread(fname, format=None):
- """
- Read an image from a file into an array.
-
- .. note::
-
- This function exists for historical reasons. It is recommended to
- use `PIL.Image.open` instead for loading images.
-
- Parameters
- ----------
- fname : str or file-like
- The image file to read: a filename, a URL or a file-like object opened
- in read-binary mode.
-
- Passing a URL is deprecated. Please open the URL
- for reading and pass the result to Pillow, e.g. with
- ``np.array(PIL.Image.open(urllib.request.urlopen(url)))``.
- format : str, optional
- The image file format assumed for reading the data. The image is
- loaded as a PNG file if *format* is set to "png", if *fname* is a path
- or opened file with a ".png" extension, or if it is a URL. In all
- other cases, *format* is ignored and the format is auto-detected by
- `PIL.Image.open`.
-
- Returns
- -------
- `numpy.array`
- The image data. The returned array has shape
-
- - (M, N) for grayscale images.
- - (M, N, 3) for RGB images.
- - (M, N, 4) for RGBA images.
-
- PNG images are returned as float arrays (0-1). All other formats are
- returned as int arrays, with a bit depth determined by the file's
- contents.
- """
- # hide imports to speed initial import on systems with slow linkers
- from urllib import parse
-
- if format is None:
- if isinstance(fname, str):
- parsed = parse.urlparse(fname)
- # If the string is a URL (Windows paths appear as if they have a
- # length-1 scheme), assume png.
- if len(parsed.scheme) > 1:
- ext = 'png'
- else:
- ext = Path(fname).suffix.lower()[1:]
- elif hasattr(fname, 'geturl'): # Returned by urlopen().
- # We could try to parse the url's path and use the extension, but
- # returning png is consistent with the block above. Note that this
- # if clause has to come before checking for fname.name as
- # urlopen("file:///...") also has a name attribute (with the fixed
- # value "<urllib response>").
- ext = 'png'
- elif hasattr(fname, 'name'):
- ext = Path(fname.name).suffix.lower()[1:]
- else:
- ext = 'png'
- else:
- ext = format
- img_open = (
- PIL.PngImagePlugin.PngImageFile if ext == 'png' else PIL.Image.open)
- if isinstance(fname, str) and len(parse.urlparse(fname).scheme) > 1:
- # Pillow doesn't handle URLs directly.
- raise ValueError(
- "Please open the URL for reading and pass the "
- "result to Pillow, e.g. with "
- "``np.array(PIL.Image.open(urllib.request.urlopen(url)))``."
- )
- with img_open(fname) as image:
- return (_pil_png_to_float_array(image)
- if isinstance(image, PIL.PngImagePlugin.PngImageFile) else
- pil_to_array(image))
-
-
-def imsave(fname, arr, vmin=None, vmax=None, cmap=None, format=None,
- origin=None, dpi=100, *, metadata=None, pil_kwargs=None):
- """
- Colormap and save an array as an image file.
-
- RGB(A) images are passed through. Single channel images will be
- colormapped according to *cmap* and *norm*.
-
- .. note::
-
- If you want to save a single channel image as gray scale please use an
- image I/O library (such as pillow, tifffile, or imageio) directly.
-
- Parameters
- ----------
- fname : str or path-like or file-like
- A path or a file-like object to store the image in.
- If *format* is not set, then the output format is inferred from the
- extension of *fname*, if any, and from :rc:`savefig.format` otherwise.
- If *format* is set, it determines the output format.
- arr : array-like
- The image data. The shape can be one of
- MxN (luminance), MxNx3 (RGB) or MxNx4 (RGBA).
- vmin, vmax : float, optional
- *vmin* and *vmax* set the color scaling for the image by fixing the
- values that map to the colormap color limits. If either *vmin*
- or *vmax* is None, that limit is determined from the *arr*
- min/max value.
- cmap : str or `~matplotlib.colors.Colormap`, default: :rc:`image.cmap`
- A Colormap instance or registered colormap name. The colormap
- maps scalar data to colors. It is ignored for RGB(A) data.
- format : str, optional
- The file format, e.g. 'png', 'pdf', 'svg', ... The behavior when this
- is unset is documented under *fname*.
- origin : {'upper', 'lower'}, default: :rc:`image.origin`
- Indicates whether the ``(0, 0)`` index of the array is in the upper
- left or lower left corner of the axes.
- dpi : float
- The DPI to store in the metadata of the file. This does not affect the
- resolution of the output image. Depending on file format, this may be
- rounded to the nearest integer.
- metadata : dict, optional
- Metadata in the image file. The supported keys depend on the output
- format, see the documentation of the respective backends for more
- information.
- Currently only supported for "png", "pdf", "ps", "eps", and "svg".
- pil_kwargs : dict, optional
- Keyword arguments passed to `PIL.Image.Image.save`. If the 'pnginfo'
- key is present, it completely overrides *metadata*, including the
- default 'Software' key.
- """
- from matplotlib.figure import Figure
- if isinstance(fname, os.PathLike):
- fname = os.fspath(fname)
- if format is None:
- format = (Path(fname).suffix[1:] if isinstance(fname, str)
- else mpl.rcParams["savefig.format"]).lower()
- if format in ["pdf", "ps", "eps", "svg"]:
- # Vector formats that are not handled by PIL.
- if pil_kwargs is not None:
- raise ValueError(
- f"Cannot use 'pil_kwargs' when saving to {format}")
- fig = Figure(dpi=dpi, frameon=False)
- fig.figimage(arr, cmap=cmap, vmin=vmin, vmax=vmax, origin=origin,
- resize=True)
- fig.savefig(fname, dpi=dpi, format=format, transparent=True,
- metadata=metadata)
- else:
- # Don't bother creating an image; this avoids rounding errors on the
- # size when dividing and then multiplying by dpi.
- if origin is None:
- origin = mpl.rcParams["image.origin"]
- else:
- _api.check_in_list(('upper', 'lower'), origin=origin)
- if origin == "lower":
- arr = arr[::-1]
- if (isinstance(arr, memoryview) and arr.format == "B"
- and arr.ndim == 3 and arr.shape[-1] == 4):
- # Such an ``arr`` would also be handled fine by sm.to_rgba below
- # (after casting with asarray), but it is useful to special-case it
- # because that's what backend_agg passes, and can be in fact used
- # as is, saving a few operations.
- rgba = arr
- else:
- sm = cm.ScalarMappable(cmap=cmap)
- sm.set_clim(vmin, vmax)
- rgba = sm.to_rgba(arr, bytes=True)
- if pil_kwargs is None:
- pil_kwargs = {}
- else:
- # we modify this below, so make a copy (don't modify caller's dict)
- pil_kwargs = pil_kwargs.copy()
- pil_shape = (rgba.shape[1], rgba.shape[0])
- image = PIL.Image.frombuffer(
- "RGBA", pil_shape, rgba, "raw", "RGBA", 0, 1)
- if format == "png":
- # Only use the metadata kwarg if pnginfo is not set, because the
- # semantics of duplicate keys in pnginfo is unclear.
- if "pnginfo" in pil_kwargs:
- if metadata:
- _api.warn_external("'metadata' is overridden by the "
- "'pnginfo' entry in 'pil_kwargs'.")
- else:
- metadata = {
- "Software": (f"Matplotlib version{mpl.__version__}, "
- f"https://matplotlib.org/"),
- **(metadata if metadata is not None else {}),
- }
- pil_kwargs["pnginfo"] = pnginfo = PIL.PngImagePlugin.PngInfo()
- for k, v in metadata.items():
- if v is not None:
- pnginfo.add_text(k, v)
- elif metadata is not None:
- raise ValueError(f"metadata not supported for format {format!r}")
- if format in ["jpg", "jpeg"]:
- format = "jpeg" # Pillow doesn't recognize "jpg".
- facecolor = mpl.rcParams["savefig.facecolor"]
- if cbook._str_equal(facecolor, "auto"):
- facecolor = mpl.rcParams["figure.facecolor"]
- color = tuple(int(x * 255) for x in mcolors.to_rgb(facecolor))
- background = PIL.Image.new("RGB", pil_shape, color)
- background.paste(image, image)
- image = background
- pil_kwargs.setdefault("format", format)
- pil_kwargs.setdefault("dpi", (dpi, dpi))
- image.save(fname, **pil_kwargs)
-
-
-def pil_to_array(pilImage):
- """
- Load a `PIL image`_ and return it as a numpy int array.
-
- .. _PIL image: https://pillow.readthedocs.io/en/latest/reference/Image.html
-
- Returns
- -------
- numpy.array
-
- The array shape depends on the image type:
-
- - (M, N) for grayscale images.
- - (M, N, 3) for RGB images.
- - (M, N, 4) for RGBA images.
- """
- if pilImage.mode in ['RGBA', 'RGBX', 'RGB', 'L']:
- # return MxNx4 RGBA, MxNx3 RBA, or MxN luminance array
- return np.asarray(pilImage)
- elif pilImage.mode.startswith('I;16'):
- # return MxN luminance array of uint16
- raw = pilImage.tobytes('raw', pilImage.mode)
- if pilImage.mode.endswith('B'):
- x = np.frombuffer(raw, '>u2')
- else:
- x = np.frombuffer(raw, '<u2')
- return x.reshape(pilImage.size[::-1]).astype('=u2')
- else: # try to convert to an rgba image
- try:
- pilImage = pilImage.convert('RGBA')
- except ValueError as err:
- raise RuntimeError('Unknown image mode') from err
- return np.asarray(pilImage) # return MxNx4 RGBA array
-
-
-def _pil_png_to_float_array(pil_png):
- """Convert a PIL `PNGImageFile` to a 0-1 float array."""
- # Unlike pil_to_array this converts to 0-1 float32s for backcompat with the
- # old libpng-based loader.
- # The supported rawmodes are from PIL.PngImagePlugin._MODES. When
- # mode == "RGB(A)", the 16-bit raw data has already been coarsened to 8-bit
- # by Pillow.
- mode = pil_png.mode
- rawmode = pil_png.png.im_rawmode
- if rawmode == "1": # Grayscale.
- return np.asarray(pil_png, np.float32)
- if rawmode == "L;2": # Grayscale.
- return np.divide(pil_png, 2**2 - 1, dtype=np.float32)
- if rawmode == "L;4": # Grayscale.
- return np.divide(pil_png, 2**4 - 1, dtype=np.float32)
- if rawmode == "L": # Grayscale.
- return np.divide(pil_png, 2**8 - 1, dtype=np.float32)
- if rawmode == "I;16B": # Grayscale.
- return np.divide(pil_png, 2**16 - 1, dtype=np.float32)
- if mode == "RGB": # RGB.
- return np.divide(pil_png, 2**8 - 1, dtype=np.float32)
- if mode == "P": # Palette.
- return np.divide(pil_png.convert("RGBA"), 2**8 - 1, dtype=np.float32)
- if mode == "LA": # Grayscale + alpha.
- return np.divide(pil_png.convert("RGBA"), 2**8 - 1, dtype=np.float32)
- if mode == "RGBA": # RGBA.
- return np.divide(pil_png, 2**8 - 1, dtype=np.float32)
- raise ValueError(f"Unknown PIL rawmode: {rawmode}")
-
-
-def thumbnail(infile, thumbfile, scale=0.1, interpolation='bilinear',
- preview=False):
- """
- Make a thumbnail of image in *infile* with output filename *thumbfile*.
-
- See :doc:`/gallery/misc/image_thumbnail_sgskip`.
-
- Parameters
- ----------
- infile : str or file-like
- The image file. Matplotlib relies on Pillow_ for image reading, and
- thus supports a wide range of file formats, including PNG, JPG, TIFF
- and others.
-
- .. _Pillow: https://python-pillow.org/
-
- thumbfile : str or file-like
- The thumbnail filename.
-
- scale : float, default: 0.1
- The scale factor for the thumbnail.
-
- interpolation : str, default: 'bilinear'
- The interpolation scheme used in the resampling. See the
- *interpolation* parameter of `~.Axes.imshow` for possible values.
-
- preview : bool, default: False
- If True, the default backend (presumably a user interface
- backend) will be used which will cause a figure to be raised if
- `~matplotlib.pyplot.show` is called. If it is False, the figure is
- created using `.FigureCanvasBase` and the drawing backend is selected
- as `.Figure.savefig` would normally do.
-
- Returns
- -------
- `.Figure`
- The figure instance containing the thumbnail.
- """
-
- im = imread(infile)
- rows, cols, depth = im.shape
-
- # This doesn't really matter (it cancels in the end) but the API needs it.
- dpi = 100
-
- height = rows / dpi * scale
- width = cols / dpi * scale
-
- if preview:
- # Let the UI backend do everything.
- import matplotlib.pyplot as plt
- fig = plt.figure(figsize=(width, height), dpi=dpi)
- else:
- from matplotlib.figure import Figure
- fig = Figure(figsize=(width, height), dpi=dpi)
- FigureCanvasBase(fig)
-
- ax = fig.add_axes([0, 0, 1, 1], aspect='auto',
- frameon=False, xticks=[], yticks=[])
- ax.imshow(im, aspect='auto', resample=True, interpolation=interpolation)
- fig.savefig(thumbfile, dpi=dpi)
- return fig
diff --git a/contrib/python/matplotlib/py3/matplotlib/image.pyi b/contrib/python/matplotlib/py3/matplotlib/image.pyi
deleted file mode 100644
index 426e34ec83..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/image.pyi
+++ /dev/null
@@ -1,209 +0,0 @@
-from collections.abc import Callable, Sequence
-import os
-import pathlib
-from typing import Any, BinaryIO, Literal
-
-import numpy as np
-from numpy.typing import ArrayLike, NDArray
-import PIL.Image
-
-import matplotlib.artist as martist
-from matplotlib.axes import Axes
-from matplotlib import cm
-from matplotlib.backend_bases import RendererBase, MouseEvent
-from matplotlib.colors import Colormap, Normalize
-from matplotlib.figure import Figure
-from matplotlib.transforms import Affine2D, BboxBase, Bbox, Transform
-
-#
-# These names are re-exported from matplotlib._image.
-#
-
-BESSEL: int
-BICUBIC: int
-BILINEAR: int
-BLACKMAN: int
-CATROM: int
-GAUSSIAN: int
-HAMMING: int
-HANNING: int
-HERMITE: int
-KAISER: int
-LANCZOS: int
-MITCHELL: int
-NEAREST: int
-QUADRIC: int
-SINC: int
-SPLINE16: int
-SPLINE36: int
-
-def resample(
- input_array: NDArray[np.float32] | NDArray[np.float64] | NDArray[np.int8],
- output_array: NDArray[np.float32] | NDArray[np.float64] | NDArray[np.int8],
- transform: Transform,
- interpolation: int = ...,
- resample: bool = ...,
- alpha: float = ...,
- norm: bool = ...,
- radius: float = ...,
-) -> None: ...
-
-#
-# END names re-exported from matplotlib._image.
-#
-
-interpolations_names: set[str]
-
-def composite_images(
- images: Sequence[_ImageBase], renderer: RendererBase, magnification: float = ...
-) -> tuple[np.ndarray, float, float]: ...
-
-class _ImageBase(martist.Artist, cm.ScalarMappable):
- zorder: float
- origin: Literal["upper", "lower"]
- axes: Axes
- def __init__(
- self,
- ax: Axes,
- cmap: str | Colormap | None = ...,
- norm: str | Normalize | None = ...,
- interpolation: str | None = ...,
- origin: Literal["upper", "lower"] | None = ...,
- filternorm: bool = ...,
- filterrad: float = ...,
- resample: bool | None = ...,
- *,
- interpolation_stage: Literal["data", "rgba"] | None = ...,
- **kwargs
- ) -> None: ...
- def get_size(self) -> tuple[int, int]: ...
- def set_alpha(self, alpha: float | ArrayLike | None) -> None: ...
- def changed(self) -> None: ...
- def make_image(
- self, renderer: RendererBase, magnification: float = ..., unsampled: bool = ...
- ) -> tuple[np.ndarray, float, float, Affine2D]: ...
- def draw(self, renderer: RendererBase, *args, **kwargs) -> None: ...
- def write_png(self, fname: str | pathlib.Path | BinaryIO) -> None: ...
- def set_data(self, A: ArrayLike | None) -> None: ...
- def set_array(self, A: ArrayLike | None) -> None: ...
- def get_shape(self) -> tuple[int, int, int]: ...
- def get_interpolation(self) -> str: ...
- def set_interpolation(self, s: str | None) -> None: ...
- def set_interpolation_stage(self, s: Literal["data", "rgba"]) -> None: ...
- def can_composite(self) -> bool: ...
- def set_resample(self, v: bool | None) -> None: ...
- def get_resample(self) -> bool: ...
- def set_filternorm(self, filternorm: bool) -> None: ...
- def get_filternorm(self) -> bool: ...
- def set_filterrad(self, filterrad: float) -> None: ...
- def get_filterrad(self) -> float: ...
-
-class AxesImage(_ImageBase):
- def __init__(
- self,
- ax: Axes,
- *,
- cmap: str | Colormap | None = ...,
- norm: str | Normalize | None = ...,
- interpolation: str | None = ...,
- origin: Literal["upper", "lower"] | None = ...,
- extent: tuple[float, float, float, float] | None = ...,
- filternorm: bool = ...,
- filterrad: float = ...,
- resample: bool = ...,
- interpolation_stage: Literal["data", "rgba"] | None = ...,
- **kwargs
- ) -> None: ...
- def get_window_extent(self, renderer: RendererBase | None = ...) -> Bbox: ...
- def make_image(
- self, renderer: RendererBase, magnification: float = ..., unsampled: bool = ...
- ) -> tuple[np.ndarray, float, float, Affine2D]: ...
- def set_extent(
- self, extent: tuple[float, float, float, float], **kwargs
- ) -> None: ...
- def get_extent(self) -> tuple[float, float, float, float]: ...
- def get_cursor_data(self, event: MouseEvent) -> None | float: ...
-
-class NonUniformImage(AxesImage):
- mouseover: bool
- def __init__(
- self, ax: Axes, *, interpolation: Literal["nearest", "bilinear"] = ..., **kwargs
- ) -> None: ...
- def set_data(self, x: ArrayLike, y: ArrayLike, A: ArrayLike) -> None: ... # type: ignore[override]
- # more limited interpolation available here than base class
- def set_interpolation(self, s: Literal["nearest", "bilinear"]) -> None: ... # type: ignore[override]
-
-class PcolorImage(AxesImage):
- def __init__(
- self,
- ax: Axes,
- x: ArrayLike | None = ...,
- y: ArrayLike | None = ...,
- A: ArrayLike | None = ...,
- *,
- cmap: str | Colormap | None = ...,
- norm: str | Normalize | None = ...,
- **kwargs
- ) -> None: ...
- def set_data(self, x: ArrayLike, y: ArrayLike, A: ArrayLike) -> None: ... # type: ignore[override]
-
-class FigureImage(_ImageBase):
- zorder: float
- figure: Figure
- ox: float
- oy: float
- magnification: float
- def __init__(
- self,
- fig: Figure,
- *,
- cmap: str | Colormap | None = ...,
- norm: str | Normalize | None = ...,
- offsetx: int = ...,
- offsety: int = ...,
- origin: Literal["upper", "lower"] | None = ...,
- **kwargs
- ) -> None: ...
- def get_extent(self) -> tuple[float, float, float, float]: ...
-
-class BboxImage(_ImageBase):
- bbox: BboxBase
- def __init__(
- self,
- bbox: BboxBase | Callable[[RendererBase | None], Bbox],
- *,
- cmap: str | Colormap | None = ...,
- norm: str | Normalize | None = ...,
- interpolation: str | None = ...,
- origin: Literal["upper", "lower"] | None = ...,
- filternorm: bool = ...,
- filterrad: float = ...,
- resample: bool = ...,
- **kwargs
- ) -> None: ...
- def get_window_extent(self, renderer: RendererBase | None = ...) -> Bbox: ...
-
-def imread(
- fname: str | pathlib.Path | BinaryIO, format: str | None = ...
-) -> np.ndarray: ...
-def imsave(
- fname: str | os.PathLike | BinaryIO,
- arr: ArrayLike,
- vmin: float | None = ...,
- vmax: float | None = ...,
- cmap: str | Colormap | None = ...,
- format: str | None = ...,
- origin: Literal["upper", "lower"] | None = ...,
- dpi: float = ...,
- *,
- metadata: dict[str, str] | None = ...,
- pil_kwargs: dict[str, Any] | None = ...
-) -> None: ...
-def pil_to_array(pilImage: PIL.Image.Image) -> np.ndarray: ...
-def thumbnail(
- infile: str | BinaryIO,
- thumbfile: str | BinaryIO,
- scale: float = ...,
- interpolation: str = ...,
- preview: bool = ...,
-) -> Figure: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/layout_engine.py b/contrib/python/matplotlib/py3/matplotlib/layout_engine.py
deleted file mode 100644
index d751059f4e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/layout_engine.py
+++ /dev/null
@@ -1,304 +0,0 @@
-"""
-Classes to layout elements in a `.Figure`.
-
-Figures have a ``layout_engine`` property that holds a subclass of
-`~.LayoutEngine` defined here (or *None* for no layout). At draw time
-``figure.get_layout_engine().execute()`` is called, the goal of which is
-usually to rearrange Axes on the figure to produce a pleasing layout. This is
-like a ``draw`` callback but with two differences. First, when printing we
-disable the layout engine for the final draw. Second, it is useful to know the
-layout engine while the figure is being created. In particular, colorbars are
-made differently with different layout engines (for historical reasons).
-
-Matplotlib supplies two layout engines, `.TightLayoutEngine` and
-`.ConstrainedLayoutEngine`. Third parties can create their own layout engine
-by subclassing `.LayoutEngine`.
-"""
-
-from contextlib import nullcontext
-
-import matplotlib as mpl
-
-from matplotlib._constrained_layout import do_constrained_layout
-from matplotlib._tight_layout import (get_subplotspec_list,
- get_tight_layout_figure)
-
-
-class LayoutEngine:
- """
- Base class for Matplotlib layout engines.
-
- A layout engine can be passed to a figure at instantiation or at any time
- with `~.figure.Figure.set_layout_engine`. Once attached to a figure, the
- layout engine ``execute`` function is called at draw time by
- `~.figure.Figure.draw`, providing a special draw-time hook.
-
- .. note::
-
- However, note that layout engines affect the creation of colorbars, so
- `~.figure.Figure.set_layout_engine` should be called before any
- colorbars are created.
-
- Currently, there are two properties of `LayoutEngine` classes that are
- consulted while manipulating the figure:
-
- - ``engine.colorbar_gridspec`` tells `.Figure.colorbar` whether to make the
- axes using the gridspec method (see `.colorbar.make_axes_gridspec`) or
- not (see `.colorbar.make_axes`);
- - ``engine.adjust_compatible`` stops `.Figure.subplots_adjust` from being
- run if it is not compatible with the layout engine.
-
- To implement a custom `LayoutEngine`:
-
- 1. override ``_adjust_compatible`` and ``_colorbar_gridspec``
- 2. override `LayoutEngine.set` to update *self._params*
- 3. override `LayoutEngine.execute` with your implementation
-
- """
- # override these in subclass
- _adjust_compatible = None
- _colorbar_gridspec = None
-
- def __init__(self, **kwargs):
- super().__init__(**kwargs)
- self._params = {}
-
- def set(self, **kwargs):
- """
- Set the parameters for the layout engine.
- """
- raise NotImplementedError
-
- @property
- def colorbar_gridspec(self):
- """
- Return a boolean if the layout engine creates colorbars using a
- gridspec.
- """
- if self._colorbar_gridspec is None:
- raise NotImplementedError
- return self._colorbar_gridspec
-
- @property
- def adjust_compatible(self):
- """
- Return a boolean if the layout engine is compatible with
- `~.Figure.subplots_adjust`.
- """
- if self._adjust_compatible is None:
- raise NotImplementedError
- return self._adjust_compatible
-
- def get(self):
- """
- Return copy of the parameters for the layout engine.
- """
- return dict(self._params)
-
- def execute(self, fig):
- """
- Execute the layout on the figure given by *fig*.
- """
- # subclasses must implement this.
- raise NotImplementedError
-
-
-class PlaceHolderLayoutEngine(LayoutEngine):
- """
- This layout engine does not adjust the figure layout at all.
-
- The purpose of this `.LayoutEngine` is to act as a placeholder when the user removes
- a layout engine to ensure an incompatible `.LayoutEngine` cannot be set later.
-
- Parameters
- ----------
- adjust_compatible, colorbar_gridspec : bool
- Allow the PlaceHolderLayoutEngine to mirror the behavior of whatever
- layout engine it is replacing.
-
- """
- def __init__(self, adjust_compatible, colorbar_gridspec, **kwargs):
- self._adjust_compatible = adjust_compatible
- self._colorbar_gridspec = colorbar_gridspec
- super().__init__(**kwargs)
-
- def execute(self, fig):
- """
- Do nothing.
- """
- return
-
-
-class TightLayoutEngine(LayoutEngine):
- """
- Implements the ``tight_layout`` geometry management. See
- :ref:`tight_layout_guide` for details.
- """
- _adjust_compatible = True
- _colorbar_gridspec = True
-
- def __init__(self, *, pad=1.08, h_pad=None, w_pad=None,
- rect=(0, 0, 1, 1), **kwargs):
- """
- Initialize tight_layout engine.
-
- Parameters
- ----------
- pad : float, default: 1.08
- Padding between the figure edge and the edges of subplots, as a
- fraction of the font size.
- h_pad, w_pad : float
- Padding (height/width) between edges of adjacent subplots.
- Defaults to *pad*.
- rect : tuple (left, bottom, right, top), default: (0, 0, 1, 1).
- rectangle in normalized figure coordinates that the subplots
- (including labels) will fit into.
- """
- super().__init__(**kwargs)
- for td in ['pad', 'h_pad', 'w_pad', 'rect']:
- # initialize these in case None is passed in above:
- self._params[td] = None
- self.set(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
-
- def execute(self, fig):
- """
- Execute tight_layout.
-
- This decides the subplot parameters given the padding that
- will allow the axes labels to not be covered by other labels
- and axes.
-
- Parameters
- ----------
- fig : `.Figure` to perform layout on.
-
- See Also
- --------
- .figure.Figure.tight_layout
- .pyplot.tight_layout
- """
- info = self._params
- renderer = fig._get_renderer()
- with getattr(renderer, "_draw_disabled", nullcontext)():
- kwargs = get_tight_layout_figure(
- fig, fig.axes, get_subplotspec_list(fig.axes), renderer,
- pad=info['pad'], h_pad=info['h_pad'], w_pad=info['w_pad'],
- rect=info['rect'])
- if kwargs:
- fig.subplots_adjust(**kwargs)
-
- def set(self, *, pad=None, w_pad=None, h_pad=None, rect=None):
- """
- Set the pads for tight_layout.
-
- Parameters
- ----------
- pad : float
- Padding between the figure edge and the edges of subplots, as a
- fraction of the font size.
- w_pad, h_pad : float
- Padding (width/height) between edges of adjacent subplots.
- Defaults to *pad*.
- rect : tuple (left, bottom, right, top)
- rectangle in normalized figure coordinates that the subplots
- (including labels) will fit into.
- """
- for td in self.set.__kwdefaults__:
- if locals()[td] is not None:
- self._params[td] = locals()[td]
-
-
-class ConstrainedLayoutEngine(LayoutEngine):
- """
- Implements the ``constrained_layout`` geometry management. See
- :ref:`constrainedlayout_guide` for details.
- """
-
- _adjust_compatible = False
- _colorbar_gridspec = False
-
- def __init__(self, *, h_pad=None, w_pad=None,
- hspace=None, wspace=None, rect=(0, 0, 1, 1),
- compress=False, **kwargs):
- """
- Initialize ``constrained_layout`` settings.
-
- Parameters
- ----------
- h_pad, w_pad : float
- Padding around the axes elements in inches.
- Default to :rc:`figure.constrained_layout.h_pad` and
- :rc:`figure.constrained_layout.w_pad`.
- hspace, wspace : float
- Fraction of the figure to dedicate to space between the
- axes. These are evenly spread between the gaps between the axes.
- A value of 0.2 for a three-column layout would have a space
- of 0.1 of the figure width between each column.
- If h/wspace < h/w_pad, then the pads are used instead.
- Default to :rc:`figure.constrained_layout.hspace` and
- :rc:`figure.constrained_layout.wspace`.
- rect : tuple of 4 floats
- Rectangle in figure coordinates to perform constrained layout in
- (left, bottom, width, height), each from 0-1.
- compress : bool
- Whether to shift Axes so that white space in between them is
- removed. This is useful for simple grids of fixed-aspect Axes (e.g.
- a grid of images). See :ref:`compressed_layout`.
- """
- super().__init__(**kwargs)
- # set the defaults:
- self.set(w_pad=mpl.rcParams['figure.constrained_layout.w_pad'],
- h_pad=mpl.rcParams['figure.constrained_layout.h_pad'],
- wspace=mpl.rcParams['figure.constrained_layout.wspace'],
- hspace=mpl.rcParams['figure.constrained_layout.hspace'],
- rect=(0, 0, 1, 1))
- # set anything that was passed in (None will be ignored):
- self.set(w_pad=w_pad, h_pad=h_pad, wspace=wspace, hspace=hspace,
- rect=rect)
- self._compress = compress
-
- def execute(self, fig):
- """
- Perform constrained_layout and move and resize axes accordingly.
-
- Parameters
- ----------
- fig : `.Figure` to perform layout on.
- """
- width, height = fig.get_size_inches()
- # pads are relative to the current state of the figure...
- w_pad = self._params['w_pad'] / width
- h_pad = self._params['h_pad'] / height
-
- return do_constrained_layout(fig, w_pad=w_pad, h_pad=h_pad,
- wspace=self._params['wspace'],
- hspace=self._params['hspace'],
- rect=self._params['rect'],
- compress=self._compress)
-
- def set(self, *, h_pad=None, w_pad=None,
- hspace=None, wspace=None, rect=None):
- """
- Set the pads for constrained_layout.
-
- Parameters
- ----------
- h_pad, w_pad : float
- Padding around the axes elements in inches.
- Default to :rc:`figure.constrained_layout.h_pad` and
- :rc:`figure.constrained_layout.w_pad`.
- hspace, wspace : float
- Fraction of the figure to dedicate to space between the
- axes. These are evenly spread between the gaps between the axes.
- A value of 0.2 for a three-column layout would have a space
- of 0.1 of the figure width between each column.
- If h/wspace < h/w_pad, then the pads are used instead.
- Default to :rc:`figure.constrained_layout.hspace` and
- :rc:`figure.constrained_layout.wspace`.
- rect : tuple of 4 floats
- Rectangle in figure coordinates to perform constrained layout in
- (left, bottom, width, height), each from 0-1.
- """
- for td in self.set.__kwdefaults__:
- if locals()[td] is not None:
- self._params[td] = locals()[td]
diff --git a/contrib/python/matplotlib/py3/matplotlib/layout_engine.pyi b/contrib/python/matplotlib/py3/matplotlib/layout_engine.pyi
deleted file mode 100644
index 5b8c812ff4..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/layout_engine.pyi
+++ /dev/null
@@ -1,62 +0,0 @@
-from matplotlib.figure import Figure
-
-from typing import Any
-
-class LayoutEngine:
- def __init__(self, **kwargs: Any) -> None: ...
- def set(self) -> None: ...
- @property
- def colorbar_gridspec(self) -> bool: ...
- @property
- def adjust_compatible(self) -> bool: ...
- def get(self) -> dict[str, Any]: ...
- def execute(self, fig: Figure) -> None: ...
-
-class PlaceHolderLayoutEngine(LayoutEngine):
- def __init__(
- self, adjust_compatible: bool, colorbar_gridspec: bool, **kwargs: Any
- ) -> None: ...
- def execute(self, fig: Figure) -> None: ...
-
-class TightLayoutEngine(LayoutEngine):
- def __init__(
- self,
- *,
- pad: float = ...,
- h_pad: float | None = ...,
- w_pad: float | None = ...,
- rect: tuple[float, float, float, float] = ...,
- **kwargs: Any
- ) -> None: ...
- def execute(self, fig: Figure) -> None: ...
- def set(
- self,
- *,
- pad: float | None = ...,
- w_pad: float | None = ...,
- h_pad: float | None = ...,
- rect: tuple[float, float, float, float] | None = ...
- ) -> None: ...
-
-class ConstrainedLayoutEngine(LayoutEngine):
- def __init__(
- self,
- *,
- h_pad: float | None = ...,
- w_pad: float | None = ...,
- hspace: float | None = ...,
- wspace: float | None = ...,
- rect: tuple[float, float, float, float] = ...,
- compress: bool = ...,
- **kwargs: Any
- ) -> None: ...
- def execute(self, fig: Figure) -> Any: ...
- def set(
- self,
- *,
- h_pad: float | None = ...,
- w_pad: float | None = ...,
- hspace: float | None = ...,
- wspace: float | None = ...,
- rect: tuple[float, float, float, float] | None = ...
- ) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/legend.py b/contrib/python/matplotlib/py3/matplotlib/legend.py
deleted file mode 100644
index c52bdbf01d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/legend.py
+++ /dev/null
@@ -1,1384 +0,0 @@
-"""
-The legend module defines the Legend class, which is responsible for
-drawing legends associated with axes and/or figures.
-
-.. important::
-
- It is unlikely that you would ever create a Legend instance manually.
- Most users would normally create a legend via the `~.Axes.legend`
- function. For more details on legends there is also a :ref:`legend guide
- <legend_guide>`.
-
-The `Legend` class is a container of legend handles and legend texts.
-
-The legend handler map specifies how to create legend handles from artists
-(lines, patches, etc.) in the axes or figures. Default legend handlers are
-defined in the :mod:`~matplotlib.legend_handler` module. While not all artist
-types are covered by the default legend handlers, custom legend handlers can be
-defined to support arbitrary objects.
-
-See the :ref`<legend_guide>` for more
-information.
-"""
-
-import itertools
-import logging
-import numbers
-import time
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, _docstring, colors, offsetbox
-from matplotlib.artist import Artist, allow_rasterization
-from matplotlib.cbook import silent_list
-from matplotlib.font_manager import FontProperties
-from matplotlib.lines import Line2D
-from matplotlib.patches import (Patch, Rectangle, Shadow, FancyBboxPatch,
- StepPatch)
-from matplotlib.collections import (
- Collection, CircleCollection, LineCollection, PathCollection,
- PolyCollection, RegularPolyCollection)
-from matplotlib.text import Text
-from matplotlib.transforms import Bbox, BboxBase, TransformedBbox
-from matplotlib.transforms import BboxTransformTo, BboxTransformFrom
-from matplotlib.offsetbox import (
- AnchoredOffsetbox, DraggableOffsetBox,
- HPacker, VPacker,
- DrawingArea, TextArea,
-)
-from matplotlib.container import ErrorbarContainer, BarContainer, StemContainer
-from . import legend_handler
-
-
-class DraggableLegend(DraggableOffsetBox):
- def __init__(self, legend, use_blit=False, update="loc"):
- """
- Wrapper around a `.Legend` to support mouse dragging.
-
- Parameters
- ----------
- legend : `.Legend`
- The `.Legend` instance to wrap.
- use_blit : bool, optional
- Use blitting for faster image composition. For details see
- :ref:`func-animation`.
- update : {'loc', 'bbox'}, optional
- If "loc", update the *loc* parameter of the legend upon finalizing.
- If "bbox", update the *bbox_to_anchor* parameter.
- """
- self.legend = legend
-
- _api.check_in_list(["loc", "bbox"], update=update)
- self._update = update
-
- super().__init__(legend, legend._legend_box, use_blit=use_blit)
-
- def finalize_offset(self):
- if self._update == "loc":
- self._update_loc(self.get_loc_in_canvas())
- elif self._update == "bbox":
- self._update_bbox_to_anchor(self.get_loc_in_canvas())
-
- def _update_loc(self, loc_in_canvas):
- bbox = self.legend.get_bbox_to_anchor()
- # if bbox has zero width or height, the transformation is
- # ill-defined. Fall back to the default bbox_to_anchor.
- if bbox.width == 0 or bbox.height == 0:
- self.legend.set_bbox_to_anchor(None)
- bbox = self.legend.get_bbox_to_anchor()
- _bbox_transform = BboxTransformFrom(bbox)
- self.legend._loc = tuple(_bbox_transform.transform(loc_in_canvas))
-
- def _update_bbox_to_anchor(self, loc_in_canvas):
- loc_in_bbox = self.legend.axes.transAxes.transform(loc_in_canvas)
- self.legend.set_bbox_to_anchor(loc_in_bbox)
-
-
-_legend_kw_doc_base = """
-bbox_to_anchor : `.BboxBase`, 2-tuple, or 4-tuple of floats
- Box that is used to position the legend in conjunction with *loc*.
- Defaults to `axes.bbox` (if called as a method to `.Axes.legend`) or
- `figure.bbox` (if `.Figure.legend`). This argument allows arbitrary
- placement of the legend.
-
- Bbox coordinates are interpreted in the coordinate system given by
- *bbox_transform*, with the default transform
- Axes or Figure coordinates, depending on which ``legend`` is called.
-
- If a 4-tuple or `.BboxBase` is given, then it specifies the bbox
- ``(x, y, width, height)`` that the legend is placed in.
- To put the legend in the best location in the bottom right
- quadrant of the axes (or figure)::
-
- loc='best', bbox_to_anchor=(0.5, 0., 0.5, 0.5)
-
- A 2-tuple ``(x, y)`` places the corner of the legend specified by *loc* at
- x, y. For example, to put the legend's upper right-hand corner in the
- center of the axes (or figure) the following keywords can be used::
-
- loc='upper right', bbox_to_anchor=(0.5, 0.5)
-
-ncols : int, default: 1
- The number of columns that the legend has.
-
- For backward compatibility, the spelling *ncol* is also supported
- but it is discouraged. If both are given, *ncols* takes precedence.
-
-prop : None or `~matplotlib.font_manager.FontProperties` or dict
- The font properties of the legend. If None (default), the current
- :data:`matplotlib.rcParams` will be used.
-
-fontsize : int or {'xx-small', 'x-small', 'small', 'medium', 'large', \
-'x-large', 'xx-large'}
- The font size of the legend. If the value is numeric the size will be the
- absolute font size in points. String values are relative to the current
- default font size. This argument is only used if *prop* is not specified.
-
-labelcolor : str or list, default: :rc:`legend.labelcolor`
- The color of the text in the legend. Either a valid color string
- (for example, 'red'), or a list of color strings. The labelcolor can
- also be made to match the color of the line or marker using 'linecolor',
- 'markerfacecolor' (or 'mfc'), or 'markeredgecolor' (or 'mec').
-
- Labelcolor can be set globally using :rc:`legend.labelcolor`. If None,
- use :rc:`text.color`.
-
-numpoints : int, default: :rc:`legend.numpoints`
- The number of marker points in the legend when creating a legend
- entry for a `.Line2D` (line).
-
-scatterpoints : int, default: :rc:`legend.scatterpoints`
- The number of marker points in the legend when creating
- a legend entry for a `.PathCollection` (scatter plot).
-
-scatteryoffsets : iterable of floats, default: ``[0.375, 0.5, 0.3125]``
- The vertical offset (relative to the font size) for the markers
- created for a scatter plot legend entry. 0.0 is at the base the
- legend text, and 1.0 is at the top. To draw all markers at the
- same height, set to ``[0.5]``.
-
-markerscale : float, default: :rc:`legend.markerscale`
- The relative size of legend markers compared to the originally drawn ones.
-
-markerfirst : bool, default: True
- If *True*, legend marker is placed to the left of the legend label.
- If *False*, legend marker is placed to the right of the legend label.
-
-reverse : bool, default: False
- If *True*, the legend labels are displayed in reverse order from the input.
- If *False*, the legend labels are displayed in the same order as the input.
-
- .. versionadded:: 3.7
-
-frameon : bool, default: :rc:`legend.frameon`
- Whether the legend should be drawn on a patch (frame).
-
-fancybox : bool, default: :rc:`legend.fancybox`
- Whether round edges should be enabled around the `.FancyBboxPatch` which
- makes up the legend's background.
-
-shadow : None, bool or dict, default: :rc:`legend.shadow`
- Whether to draw a shadow behind the legend.
- The shadow can be configured using `.Patch` keywords.
- Customization via :rc:`legend.shadow` is currently not supported.
-
-framealpha : float, default: :rc:`legend.framealpha`
- The alpha transparency of the legend's background.
- If *shadow* is activated and *framealpha* is ``None``, the default value is
- ignored.
-
-facecolor : "inherit" or color, default: :rc:`legend.facecolor`
- The legend's background color.
- If ``"inherit"``, use :rc:`axes.facecolor`.
-
-edgecolor : "inherit" or color, default: :rc:`legend.edgecolor`
- The legend's background patch edge color.
- If ``"inherit"``, use take :rc:`axes.edgecolor`.
-
-mode : {"expand", None}
- If *mode* is set to ``"expand"`` the legend will be horizontally
- expanded to fill the axes area (or *bbox_to_anchor* if defines
- the legend's size).
-
-bbox_transform : None or `~matplotlib.transforms.Transform`
- The transform for the bounding box (*bbox_to_anchor*). For a value
- of ``None`` (default) the Axes'
- :data:`~matplotlib.axes.Axes.transAxes` transform will be used.
-
-title : str or None
- The legend's title. Default is no title (``None``).
-
-title_fontproperties : None or `~matplotlib.font_manager.FontProperties` or dict
- The font properties of the legend's title. If None (default), the
- *title_fontsize* argument will be used if present; if *title_fontsize* is
- also None, the current :rc:`legend.title_fontsize` will be used.
-
-title_fontsize : int or {'xx-small', 'x-small', 'small', 'medium', 'large', \
-'x-large', 'xx-large'}, default: :rc:`legend.title_fontsize`
- The font size of the legend's title.
- Note: This cannot be combined with *title_fontproperties*. If you want
- to set the fontsize alongside other font properties, use the *size*
- parameter in *title_fontproperties*.
-
-alignment : {'center', 'left', 'right'}, default: 'center'
- The alignment of the legend title and the box of entries. The entries
- are aligned as a single block, so that markers always lined up.
-
-borderpad : float, default: :rc:`legend.borderpad`
- The fractional whitespace inside the legend border, in font-size units.
-
-labelspacing : float, default: :rc:`legend.labelspacing`
- The vertical space between the legend entries, in font-size units.
-
-handlelength : float, default: :rc:`legend.handlelength`
- The length of the legend handles, in font-size units.
-
-handleheight : float, default: :rc:`legend.handleheight`
- The height of the legend handles, in font-size units.
-
-handletextpad : float, default: :rc:`legend.handletextpad`
- The pad between the legend handle and text, in font-size units.
-
-borderaxespad : float, default: :rc:`legend.borderaxespad`
- The pad between the axes and legend border, in font-size units.
-
-columnspacing : float, default: :rc:`legend.columnspacing`
- The spacing between columns, in font-size units.
-
-handler_map : dict or None
- The custom dictionary mapping instances or types to a legend
- handler. This *handler_map* updates the default handler map
- found at `matplotlib.legend.Legend.get_legend_handler_map`.
-
-draggable : bool, default: False
- Whether the legend can be dragged with the mouse.
-"""
-
-_loc_doc_base = """
-loc : str or pair of floats, default: {default}
- The location of the legend.
-
- The strings ``'upper left'``, ``'upper right'``, ``'lower left'``,
- ``'lower right'`` place the legend at the corresponding corner of the
- {parent}.
-
- The strings ``'upper center'``, ``'lower center'``, ``'center left'``,
- ``'center right'`` place the legend at the center of the corresponding edge
- of the {parent}.
-
- The string ``'center'`` places the legend at the center of the {parent}.
-{best}
- The location can also be a 2-tuple giving the coordinates of the lower-left
- corner of the legend in {parent} coordinates (in which case *bbox_to_anchor*
- will be ignored).
-
- For back-compatibility, ``'center right'`` (but no other location) can also
- be spelled ``'right'``, and each "string" location can also be given as a
- numeric value:
-
- ================== =============
- Location String Location Code
- ================== =============
- 'best' (Axes only) 0
- 'upper right' 1
- 'upper left' 2
- 'lower left' 3
- 'lower right' 4
- 'right' 5
- 'center left' 6
- 'center right' 7
- 'lower center' 8
- 'upper center' 9
- 'center' 10
- ================== =============
- {outside}"""
-
-_loc_doc_best = """
- The string ``'best'`` places the legend at the location, among the nine
- locations defined so far, with the minimum overlap with other drawn
- artists. This option can be quite slow for plots with large amounts of
- data; your plotting speed may benefit from providing a specific location.
-"""
-
-_legend_kw_axes_st = (
- _loc_doc_base.format(parent='axes', default=':rc:`legend.loc`',
- best=_loc_doc_best, outside='') +
- _legend_kw_doc_base)
-_docstring.interpd.update(_legend_kw_axes=_legend_kw_axes_st)
-
-_outside_doc = """
- If a figure is using the constrained layout manager, the string codes
- of the *loc* keyword argument can get better layout behaviour using the
- prefix 'outside'. There is ambiguity at the corners, so 'outside
- upper right' will make space for the legend above the rest of the
- axes in the layout, and 'outside right upper' will make space on the
- right side of the layout. In addition to the values of *loc*
- listed above, we have 'outside right upper', 'outside right lower',
- 'outside left upper', and 'outside left lower'. See
- :ref:`legend_guide` for more details.
-"""
-
-_legend_kw_figure_st = (
- _loc_doc_base.format(parent='figure', default="'upper right'",
- best='', outside=_outside_doc) +
- _legend_kw_doc_base)
-_docstring.interpd.update(_legend_kw_figure=_legend_kw_figure_st)
-
-_legend_kw_both_st = (
- _loc_doc_base.format(parent='axes/figure',
- default=":rc:`legend.loc` for Axes, 'upper right' for Figure",
- best=_loc_doc_best, outside=_outside_doc) +
- _legend_kw_doc_base)
-_docstring.interpd.update(_legend_kw_doc=_legend_kw_both_st)
-
-_legend_kw_set_loc_st = (
- _loc_doc_base.format(parent='axes/figure',
- default=":rc:`legend.loc` for Axes, 'upper right' for Figure",
- best=_loc_doc_best, outside=_outside_doc))
-_docstring.interpd.update(_legend_kw_set_loc_doc=_legend_kw_set_loc_st)
-
-
-class Legend(Artist):
- """
- Place a legend on the figure/axes.
- """
-
- # 'best' is only implemented for axes legends
- codes = {'best': 0, **AnchoredOffsetbox.codes}
- zorder = 5
-
- def __str__(self):
- return "Legend"
-
- @_docstring.dedent_interpd
- def __init__(
- self, parent, handles, labels,
- *,
- loc=None,
- numpoints=None, # number of points in the legend line
- markerscale=None, # relative size of legend markers vs. original
- markerfirst=True, # left/right ordering of legend marker and label
- reverse=False, # reverse ordering of legend marker and label
- scatterpoints=None, # number of scatter points
- scatteryoffsets=None,
- prop=None, # properties for the legend texts
- fontsize=None, # keyword to set font size directly
- labelcolor=None, # keyword to set the text color
-
- # spacing & pad defined as a fraction of the font-size
- borderpad=None, # whitespace inside the legend border
- labelspacing=None, # vertical space between the legend entries
- handlelength=None, # length of the legend handles
- handleheight=None, # height of the legend handles
- handletextpad=None, # pad between the legend handle and text
- borderaxespad=None, # pad between the axes and legend border
- columnspacing=None, # spacing between columns
-
- ncols=1, # number of columns
- mode=None, # horizontal distribution of columns: None or "expand"
-
- fancybox=None, # True: fancy box, False: rounded box, None: rcParam
- shadow=None,
- title=None, # legend title
- title_fontsize=None, # legend title font size
- framealpha=None, # set frame alpha
- edgecolor=None, # frame patch edgecolor
- facecolor=None, # frame patch facecolor
-
- bbox_to_anchor=None, # bbox to which the legend will be anchored
- bbox_transform=None, # transform for the bbox
- frameon=None, # draw frame
- handler_map=None,
- title_fontproperties=None, # properties for the legend title
- alignment="center", # control the alignment within the legend box
- ncol=1, # synonym for ncols (backward compatibility)
- draggable=False # whether the legend can be dragged with the mouse
- ):
- """
- Parameters
- ----------
- parent : `~matplotlib.axes.Axes` or `.Figure`
- The artist that contains the legend.
-
- handles : list of (`.Artist` or tuple of `.Artist`)
- A list of Artists (lines, patches) to be added to the legend.
-
- labels : list of str
- A list of labels to show next to the artists. The length of handles
- and labels should be the same. If they are not, they are truncated
- to the length of the shorter list.
-
- Other Parameters
- ----------------
- %(_legend_kw_doc)s
-
- Attributes
- ----------
- legend_handles
- List of `.Artist` objects added as legend entries.
-
- .. versionadded:: 3.7
- """
- # local import only to avoid circularity
- from matplotlib.axes import Axes
- from matplotlib.figure import FigureBase
-
- super().__init__()
-
- if prop is None:
- self.prop = FontProperties(size=mpl._val_or_rc(fontsize, "legend.fontsize"))
- else:
- self.prop = FontProperties._from_any(prop)
- if isinstance(prop, dict) and "size" not in prop:
- self.prop.set_size(mpl.rcParams["legend.fontsize"])
-
- self._fontsize = self.prop.get_size_in_points()
-
- self.texts = []
- self.legend_handles = []
- self._legend_title_box = None
-
- #: A dictionary with the extra handler mappings for this Legend
- #: instance.
- self._custom_handler_map = handler_map
-
- self.numpoints = mpl._val_or_rc(numpoints, 'legend.numpoints')
- self.markerscale = mpl._val_or_rc(markerscale, 'legend.markerscale')
- self.scatterpoints = mpl._val_or_rc(scatterpoints, 'legend.scatterpoints')
- self.borderpad = mpl._val_or_rc(borderpad, 'legend.borderpad')
- self.labelspacing = mpl._val_or_rc(labelspacing, 'legend.labelspacing')
- self.handlelength = mpl._val_or_rc(handlelength, 'legend.handlelength')
- self.handleheight = mpl._val_or_rc(handleheight, 'legend.handleheight')
- self.handletextpad = mpl._val_or_rc(handletextpad, 'legend.handletextpad')
- self.borderaxespad = mpl._val_or_rc(borderaxespad, 'legend.borderaxespad')
- self.columnspacing = mpl._val_or_rc(columnspacing, 'legend.columnspacing')
- self.shadow = mpl._val_or_rc(shadow, 'legend.shadow')
- # trim handles and labels if illegal label...
- _lab, _hand = [], []
- for label, handle in zip(labels, handles):
- if isinstance(label, str) and label.startswith('_'):
- _api.warn_deprecated("3.8", message=(
- "An artist whose label starts with an underscore was passed to "
- "legend(); such artists will no longer be ignored in the future. "
- "To suppress this warning, explicitly filter out such artists, "
- "e.g. with `[art for art in artists if not "
- "art.get_label().startswith('_')]`."))
- else:
- _lab.append(label)
- _hand.append(handle)
- labels, handles = _lab, _hand
-
- if reverse:
- labels.reverse()
- handles.reverse()
-
- if len(handles) < 2:
- ncols = 1
- self._ncols = ncols if ncols != 1 else ncol
-
- if self.numpoints <= 0:
- raise ValueError("numpoints must be > 0; it was %d" % numpoints)
-
- # introduce y-offset for handles of the scatter plot
- if scatteryoffsets is None:
- self._scatteryoffsets = np.array([3. / 8., 4. / 8., 2.5 / 8.])
- else:
- self._scatteryoffsets = np.asarray(scatteryoffsets)
- reps = self.scatterpoints // len(self._scatteryoffsets) + 1
- self._scatteryoffsets = np.tile(self._scatteryoffsets,
- reps)[:self.scatterpoints]
-
- # _legend_box is a VPacker instance that contains all
- # legend items and will be initialized from _init_legend_box()
- # method.
- self._legend_box = None
-
- if isinstance(parent, Axes):
- self.isaxes = True
- self.axes = parent
- self.set_figure(parent.figure)
- elif isinstance(parent, FigureBase):
- self.isaxes = False
- self.set_figure(parent)
- else:
- raise TypeError(
- "Legend needs either Axes or FigureBase as parent"
- )
- self.parent = parent
-
- self._mode = mode
- self.set_bbox_to_anchor(bbox_to_anchor, bbox_transform)
-
- # Figure out if self.shadow is valid
- # If shadow was None, rcParams loads False
- # So it shouldn't be None here
-
- self._shadow_props = {'ox': 2, 'oy': -2} # default location offsets
- if isinstance(self.shadow, dict):
- self._shadow_props.update(self.shadow)
- self.shadow = True
- elif self.shadow in (0, 1, True, False):
- self.shadow = bool(self.shadow)
- else:
- raise ValueError(
- 'Legend shadow must be a dict or bool, not '
- f'{self.shadow!r} of type {type(self.shadow)}.'
- )
-
- # We use FancyBboxPatch to draw a legend frame. The location
- # and size of the box will be updated during the drawing time.
-
- facecolor = mpl._val_or_rc(facecolor, "legend.facecolor")
- if facecolor == 'inherit':
- facecolor = mpl.rcParams["axes.facecolor"]
-
- edgecolor = mpl._val_or_rc(edgecolor, "legend.edgecolor")
- if edgecolor == 'inherit':
- edgecolor = mpl.rcParams["axes.edgecolor"]
-
- fancybox = mpl._val_or_rc(fancybox, "legend.fancybox")
-
- self.legendPatch = FancyBboxPatch(
- xy=(0, 0), width=1, height=1,
- facecolor=facecolor, edgecolor=edgecolor,
- # If shadow is used, default to alpha=1 (#8943).
- alpha=(framealpha if framealpha is not None
- else 1 if shadow
- else mpl.rcParams["legend.framealpha"]),
- # The width and height of the legendPatch will be set (in draw())
- # to the length that includes the padding. Thus we set pad=0 here.
- boxstyle=("round,pad=0,rounding_size=0.2" if fancybox
- else "square,pad=0"),
- mutation_scale=self._fontsize,
- snap=True,
- visible=mpl._val_or_rc(frameon, "legend.frameon")
- )
- self._set_artist_props(self.legendPatch)
-
- _api.check_in_list(["center", "left", "right"], alignment=alignment)
- self._alignment = alignment
-
- # init with null renderer
- self._init_legend_box(handles, labels, markerfirst)
-
- # Set legend location
- self.set_loc(loc)
-
- # figure out title font properties:
- if title_fontsize is not None and title_fontproperties is not None:
- raise ValueError(
- "title_fontsize and title_fontproperties can't be specified "
- "at the same time. Only use one of them. ")
- title_prop_fp = FontProperties._from_any(title_fontproperties)
- if isinstance(title_fontproperties, dict):
- if "size" not in title_fontproperties:
- title_fontsize = mpl.rcParams["legend.title_fontsize"]
- title_prop_fp.set_size(title_fontsize)
- elif title_fontsize is not None:
- title_prop_fp.set_size(title_fontsize)
- elif not isinstance(title_fontproperties, FontProperties):
- title_fontsize = mpl.rcParams["legend.title_fontsize"]
- title_prop_fp.set_size(title_fontsize)
-
- self.set_title(title, prop=title_prop_fp)
-
- self._draggable = None
- self.set_draggable(state=draggable)
-
- # set the text color
-
- color_getters = { # getter function depends on line or patch
- 'linecolor': ['get_color', 'get_facecolor'],
- 'markerfacecolor': ['get_markerfacecolor', 'get_facecolor'],
- 'mfc': ['get_markerfacecolor', 'get_facecolor'],
- 'markeredgecolor': ['get_markeredgecolor', 'get_edgecolor'],
- 'mec': ['get_markeredgecolor', 'get_edgecolor'],
- }
- labelcolor = mpl._val_or_rc(labelcolor, 'legend.labelcolor')
- if labelcolor is None:
- labelcolor = mpl.rcParams['text.color']
- if isinstance(labelcolor, str) and labelcolor in color_getters:
- getter_names = color_getters[labelcolor]
- for handle, text in zip(self.legend_handles, self.texts):
- try:
- if handle.get_array() is not None:
- continue
- except AttributeError:
- pass
- for getter_name in getter_names:
- try:
- color = getattr(handle, getter_name)()
- if isinstance(color, np.ndarray):
- if (
- color.shape[0] == 1
- or np.isclose(color, color[0]).all()
- ):
- text.set_color(color[0])
- else:
- pass
- else:
- text.set_color(color)
- break
- except AttributeError:
- pass
- elif isinstance(labelcolor, str) and labelcolor == 'none':
- for text in self.texts:
- text.set_color(labelcolor)
- elif np.iterable(labelcolor):
- for text, color in zip(self.texts,
- itertools.cycle(
- colors.to_rgba_array(labelcolor))):
- text.set_color(color)
- else:
- raise ValueError(f"Invalid labelcolor: {labelcolor!r}")
-
- legendHandles = _api.deprecated('3.7', alternative="legend_handles")(
- property(lambda self: self.legend_handles))
-
- def _set_artist_props(self, a):
- """
- Set the boilerplate props for artists added to axes.
- """
- a.set_figure(self.figure)
- if self.isaxes:
- a.axes = self.axes
-
- a.set_transform(self.get_transform())
-
- @_docstring.dedent_interpd
- def set_loc(self, loc=None):
- """
- Set the location of the legend.
-
- .. versionadded:: 3.8
-
- Parameters
- ----------
- %(_legend_kw_set_loc_doc)s
- """
- loc0 = loc
- self._loc_used_default = loc is None
- if loc is None:
- loc = mpl.rcParams["legend.loc"]
- if not self.isaxes and loc in [0, 'best']:
- loc = 'upper right'
-
- type_err_message = ("loc must be string, coordinate tuple, or"
- f" an integer 0-10, not {loc!r}")
-
- # handle outside legends:
- self._outside_loc = None
- if isinstance(loc, str):
- if loc.split()[0] == 'outside':
- # strip outside:
- loc = loc.split('outside ')[1]
- # strip "center" at the beginning
- self._outside_loc = loc.replace('center ', '')
- # strip first
- self._outside_loc = self._outside_loc.split()[0]
- locs = loc.split()
- if len(locs) > 1 and locs[0] in ('right', 'left'):
- # locs doesn't accept "left upper", etc, so swap
- if locs[0] != 'center':
- locs = locs[::-1]
- loc = locs[0] + ' ' + locs[1]
- # check that loc is in acceptable strings
- loc = _api.check_getitem(self.codes, loc=loc)
- elif np.iterable(loc):
- # coerce iterable into tuple
- loc = tuple(loc)
- # validate the tuple represents Real coordinates
- if len(loc) != 2 or not all(isinstance(e, numbers.Real) for e in loc):
- raise ValueError(type_err_message)
- elif isinstance(loc, int):
- # validate the integer represents a string numeric value
- if loc < 0 or loc > 10:
- raise ValueError(type_err_message)
- else:
- # all other cases are invalid values of loc
- raise ValueError(type_err_message)
-
- if self.isaxes and self._outside_loc:
- raise ValueError(
- f"'outside' option for loc='{loc0}' keyword argument only "
- "works for figure legends")
-
- if not self.isaxes and loc == 0:
- raise ValueError(
- "Automatic legend placement (loc='best') not implemented for "
- "figure legend")
-
- tmp = self._loc_used_default
- self._set_loc(loc)
- self._loc_used_default = tmp # ignore changes done by _set_loc
-
- def _set_loc(self, loc):
- # find_offset function will be provided to _legend_box and
- # _legend_box will draw itself at the location of the return
- # value of the find_offset.
- self._loc_used_default = False
- self._loc_real = loc
- self.stale = True
- self._legend_box.set_offset(self._findoffset)
-
- def set_ncols(self, ncols):
- """Set the number of columns."""
- self._ncols = ncols
-
- def _get_loc(self):
- return self._loc_real
-
- _loc = property(_get_loc, _set_loc)
-
- def _findoffset(self, width, height, xdescent, ydescent, renderer):
- """Helper function to locate the legend."""
-
- if self._loc == 0: # "best".
- x, y = self._find_best_position(width, height, renderer)
- elif self._loc in Legend.codes.values(): # Fixed location.
- bbox = Bbox.from_bounds(0, 0, width, height)
- x, y = self._get_anchored_bbox(self._loc, bbox,
- self.get_bbox_to_anchor(),
- renderer)
- else: # Axes or figure coordinates.
- fx, fy = self._loc
- bbox = self.get_bbox_to_anchor()
- x, y = bbox.x0 + bbox.width * fx, bbox.y0 + bbox.height * fy
-
- return x + xdescent, y + ydescent
-
- @allow_rasterization
- def draw(self, renderer):
- # docstring inherited
- if not self.get_visible():
- return
-
- renderer.open_group('legend', gid=self.get_gid())
-
- fontsize = renderer.points_to_pixels(self._fontsize)
-
- # if mode == fill, set the width of the legend_box to the
- # width of the parent (minus pads)
- if self._mode in ["expand"]:
- pad = 2 * (self.borderaxespad + self.borderpad) * fontsize
- self._legend_box.set_width(self.get_bbox_to_anchor().width - pad)
-
- # update the location and size of the legend. This needs to
- # be done in any case to clip the figure right.
- bbox = self._legend_box.get_window_extent(renderer)
- self.legendPatch.set_bounds(bbox.bounds)
- self.legendPatch.set_mutation_scale(fontsize)
-
- # self.shadow is validated in __init__
- # So by here it is a bool and self._shadow_props contains any configs
-
- if self.shadow:
- Shadow(self.legendPatch, **self._shadow_props).draw(renderer)
-
- self.legendPatch.draw(renderer)
- self._legend_box.draw(renderer)
-
- renderer.close_group('legend')
- self.stale = False
-
- # _default_handler_map defines the default mapping between plot
- # elements and the legend handlers.
-
- _default_handler_map = {
- StemContainer: legend_handler.HandlerStem(),
- ErrorbarContainer: legend_handler.HandlerErrorbar(),
- Line2D: legend_handler.HandlerLine2D(),
- Patch: legend_handler.HandlerPatch(),
- StepPatch: legend_handler.HandlerStepPatch(),
- LineCollection: legend_handler.HandlerLineCollection(),
- RegularPolyCollection: legend_handler.HandlerRegularPolyCollection(),
- CircleCollection: legend_handler.HandlerCircleCollection(),
- BarContainer: legend_handler.HandlerPatch(
- update_func=legend_handler.update_from_first_child),
- tuple: legend_handler.HandlerTuple(),
- PathCollection: legend_handler.HandlerPathCollection(),
- PolyCollection: legend_handler.HandlerPolyCollection()
- }
-
- # (get|set|update)_default_handler_maps are public interfaces to
- # modify the default handler map.
-
- @classmethod
- def get_default_handler_map(cls):
- """Return the global default handler map, shared by all legends."""
- return cls._default_handler_map
-
- @classmethod
- def set_default_handler_map(cls, handler_map):
- """Set the global default handler map, shared by all legends."""
- cls._default_handler_map = handler_map
-
- @classmethod
- def update_default_handler_map(cls, handler_map):
- """Update the global default handler map, shared by all legends."""
- cls._default_handler_map.update(handler_map)
-
- def get_legend_handler_map(self):
- """Return this legend instance's handler map."""
- default_handler_map = self.get_default_handler_map()
- return ({**default_handler_map, **self._custom_handler_map}
- if self._custom_handler_map else default_handler_map)
-
- @staticmethod
- def get_legend_handler(legend_handler_map, orig_handle):
- """
- Return a legend handler from *legend_handler_map* that
- corresponds to *orig_handler*.
-
- *legend_handler_map* should be a dictionary object (that is
- returned by the get_legend_handler_map method).
-
- It first checks if the *orig_handle* itself is a key in the
- *legend_handler_map* and return the associated value.
- Otherwise, it checks for each of the classes in its
- method-resolution-order. If no matching key is found, it
- returns ``None``.
- """
- try:
- return legend_handler_map[orig_handle]
- except (TypeError, KeyError): # TypeError if unhashable.
- pass
- for handle_type in type(orig_handle).mro():
- try:
- return legend_handler_map[handle_type]
- except KeyError:
- pass
- return None
-
- def _init_legend_box(self, handles, labels, markerfirst=True):
- """
- Initialize the legend_box. The legend_box is an instance of
- the OffsetBox, which is packed with legend handles and
- texts. Once packed, their location is calculated during the
- drawing time.
- """
-
- fontsize = self._fontsize
-
- # legend_box is a HPacker, horizontally packed with columns.
- # Each column is a VPacker, vertically packed with legend items.
- # Each legend item is a HPacker packed with:
- # - handlebox: a DrawingArea which contains the legend handle.
- # - labelbox: a TextArea which contains the legend text.
-
- text_list = [] # the list of text instances
- handle_list = [] # the list of handle instances
- handles_and_labels = []
-
- # The approximate height and descent of text. These values are
- # only used for plotting the legend handle.
- descent = 0.35 * fontsize * (self.handleheight - 0.7) # heuristic.
- height = fontsize * self.handleheight - descent
- # each handle needs to be drawn inside a box of (x, y, w, h) =
- # (0, -descent, width, height). And their coordinates should
- # be given in the display coordinates.
-
- # The transformation of each handle will be automatically set
- # to self.get_transform(). If the artist does not use its
- # default transform (e.g., Collections), you need to
- # manually set their transform to the self.get_transform().
- legend_handler_map = self.get_legend_handler_map()
-
- for orig_handle, label in zip(handles, labels):
- handler = self.get_legend_handler(legend_handler_map, orig_handle)
- if handler is None:
- _api.warn_external(
- "Legend does not support handles for "
- f"{type(orig_handle).__name__} "
- "instances.\nA proxy artist may be used "
- "instead.\nSee: https://matplotlib.org/"
- "stable/users/explain/axes/legend_guide.html"
- "#controlling-the-legend-entries")
- # No handle for this artist, so we just defer to None.
- handle_list.append(None)
- else:
- textbox = TextArea(label, multilinebaseline=True,
- textprops=dict(
- verticalalignment='baseline',
- horizontalalignment='left',
- fontproperties=self.prop))
- handlebox = DrawingArea(width=self.handlelength * fontsize,
- height=height,
- xdescent=0., ydescent=descent)
-
- text_list.append(textbox._text)
- # Create the artist for the legend which represents the
- # original artist/handle.
- handle_list.append(handler.legend_artist(self, orig_handle,
- fontsize, handlebox))
- handles_and_labels.append((handlebox, textbox))
-
- columnbox = []
- # array_split splits n handles_and_labels into ncols columns, with the
- # first n%ncols columns having an extra entry. filter(len, ...)
- # handles the case where n < ncols: the last ncols-n columns are empty
- # and get filtered out.
- for handles_and_labels_column in filter(
- len, np.array_split(handles_and_labels, self._ncols)):
- # pack handlebox and labelbox into itembox
- itemboxes = [HPacker(pad=0,
- sep=self.handletextpad * fontsize,
- children=[h, t] if markerfirst else [t, h],
- align="baseline")
- for h, t in handles_and_labels_column]
- # pack columnbox
- alignment = "baseline" if markerfirst else "right"
- columnbox.append(VPacker(pad=0,
- sep=self.labelspacing * fontsize,
- align=alignment,
- children=itemboxes))
-
- mode = "expand" if self._mode == "expand" else "fixed"
- sep = self.columnspacing * fontsize
- self._legend_handle_box = HPacker(pad=0,
- sep=sep, align="baseline",
- mode=mode,
- children=columnbox)
- self._legend_title_box = TextArea("")
- self._legend_box = VPacker(pad=self.borderpad * fontsize,
- sep=self.labelspacing * fontsize,
- align=self._alignment,
- children=[self._legend_title_box,
- self._legend_handle_box])
- self._legend_box.set_figure(self.figure)
- self._legend_box.axes = self.axes
- self.texts = text_list
- self.legend_handles = handle_list
-
- def _auto_legend_data(self):
- """
- Return display coordinates for hit testing for "best" positioning.
-
- Returns
- -------
- bboxes
- List of bounding boxes of all patches.
- lines
- List of `.Path` corresponding to each line.
- offsets
- List of (x, y) offsets of all collection.
- """
- assert self.isaxes # always holds, as this is only called internally
- bboxes = []
- lines = []
- offsets = []
- for artist in self.parent._children:
- if isinstance(artist, Line2D):
- lines.append(
- artist.get_transform().transform_path(artist.get_path()))
- elif isinstance(artist, Rectangle):
- bboxes.append(
- artist.get_bbox().transformed(artist.get_data_transform()))
- elif isinstance(artist, Patch):
- lines.append(
- artist.get_transform().transform_path(artist.get_path()))
- elif isinstance(artist, Collection):
- transform, transOffset, hoffsets, _ = artist._prepare_points()
- if len(hoffsets):
- for offset in transOffset.transform(hoffsets):
- offsets.append(offset)
-
- return bboxes, lines, offsets
-
- def get_children(self):
- # docstring inherited
- return [self._legend_box, self.get_frame()]
-
- def get_frame(self):
- """Return the `~.patches.Rectangle` used to frame the legend."""
- return self.legendPatch
-
- def get_lines(self):
- r"""Return the list of `~.lines.Line2D`\s in the legend."""
- return [h for h in self.legend_handles if isinstance(h, Line2D)]
-
- def get_patches(self):
- r"""Return the list of `~.patches.Patch`\s in the legend."""
- return silent_list('Patch',
- [h for h in self.legend_handles
- if isinstance(h, Patch)])
-
- def get_texts(self):
- r"""Return the list of `~.text.Text`\s in the legend."""
- return silent_list('Text', self.texts)
-
- def set_alignment(self, alignment):
- """
- Set the alignment of the legend title and the box of entries.
-
- The entries are aligned as a single block, so that markers always
- lined up.
-
- Parameters
- ----------
- alignment : {'center', 'left', 'right'}.
-
- """
- _api.check_in_list(["center", "left", "right"], alignment=alignment)
- self._alignment = alignment
- self._legend_box.align = alignment
-
- def get_alignment(self):
- """Get the alignment value of the legend box"""
- return self._legend_box.align
-
- def set_title(self, title, prop=None):
- """
- Set legend title and title style.
-
- Parameters
- ----------
- title : str
- The legend title.
-
- prop : `.font_manager.FontProperties` or `str` or `pathlib.Path`
- The font properties of the legend title.
- If a `str`, it is interpreted as a fontconfig pattern parsed by
- `.FontProperties`. If a `pathlib.Path`, it is interpreted as the
- absolute path to a font file.
-
- """
- self._legend_title_box._text.set_text(title)
- if title:
- self._legend_title_box._text.set_visible(True)
- self._legend_title_box.set_visible(True)
- else:
- self._legend_title_box._text.set_visible(False)
- self._legend_title_box.set_visible(False)
-
- if prop is not None:
- self._legend_title_box._text.set_fontproperties(prop)
-
- self.stale = True
-
- def get_title(self):
- """Return the `.Text` instance for the legend title."""
- return self._legend_title_box._text
-
- def get_window_extent(self, renderer=None):
- # docstring inherited
- if renderer is None:
- renderer = self.figure._get_renderer()
- return self._legend_box.get_window_extent(renderer=renderer)
-
- def get_tightbbox(self, renderer=None):
- # docstring inherited
- return self._legend_box.get_window_extent(renderer)
-
- def get_frame_on(self):
- """Get whether the legend box patch is drawn."""
- return self.legendPatch.get_visible()
-
- def set_frame_on(self, b):
- """
- Set whether the legend box patch is drawn.
-
- Parameters
- ----------
- b : bool
- """
- self.legendPatch.set_visible(b)
- self.stale = True
-
- draw_frame = set_frame_on # Backcompat alias.
-
- def get_bbox_to_anchor(self):
- """Return the bbox that the legend will be anchored to."""
- if self._bbox_to_anchor is None:
- return self.parent.bbox
- else:
- return self._bbox_to_anchor
-
- def set_bbox_to_anchor(self, bbox, transform=None):
- """
- Set the bbox that the legend will be anchored to.
-
- Parameters
- ----------
- bbox : `~matplotlib.transforms.BboxBase` or tuple
- The bounding box can be specified in the following ways:
-
- - A `.BboxBase` instance
- - A tuple of ``(left, bottom, width, height)`` in the given
- transform (normalized axes coordinate if None)
- - A tuple of ``(left, bottom)`` where the width and height will be
- assumed to be zero.
- - *None*, to remove the bbox anchoring, and use the parent bbox.
-
- transform : `~matplotlib.transforms.Transform`, optional
- A transform to apply to the bounding box. If not specified, this
- will use a transform to the bounding box of the parent.
- """
- if bbox is None:
- self._bbox_to_anchor = None
- return
- elif isinstance(bbox, BboxBase):
- self._bbox_to_anchor = bbox
- else:
- try:
- l = len(bbox)
- except TypeError as err:
- raise ValueError(f"Invalid bbox: {bbox}") from err
-
- if l == 2:
- bbox = [bbox[0], bbox[1], 0, 0]
-
- self._bbox_to_anchor = Bbox.from_bounds(*bbox)
-
- if transform is None:
- transform = BboxTransformTo(self.parent.bbox)
-
- self._bbox_to_anchor = TransformedBbox(self._bbox_to_anchor,
- transform)
- self.stale = True
-
- def _get_anchored_bbox(self, loc, bbox, parentbbox, renderer):
- """
- Place the *bbox* inside the *parentbbox* according to a given
- location code. Return the (x, y) coordinate of the bbox.
-
- Parameters
- ----------
- loc : int
- A location code in range(1, 11). This corresponds to the possible
- values for ``self._loc``, excluding "best".
- bbox : `~matplotlib.transforms.Bbox`
- bbox to be placed, in display coordinates.
- parentbbox : `~matplotlib.transforms.Bbox`
- A parent box which will contain the bbox, in display coordinates.
- """
- return offsetbox._get_anchored_bbox(
- loc, bbox, parentbbox,
- self.borderaxespad * renderer.points_to_pixels(self._fontsize))
-
- def _find_best_position(self, width, height, renderer, consider=None):
- """
- Determine the best location to place the legend.
-
- *consider* is a list of ``(x, y)`` pairs to consider as a potential
- lower-left corner of the legend. All are display coords.
- """
- assert self.isaxes # always holds, as this is only called internally
-
- start_time = time.perf_counter()
-
- bboxes, lines, offsets = self._auto_legend_data()
-
- bbox = Bbox.from_bounds(0, 0, width, height)
- if consider is None:
- consider = [self._get_anchored_bbox(x, bbox,
- self.get_bbox_to_anchor(),
- renderer)
- for x in range(1, len(self.codes))]
-
- candidates = []
- for idx, (l, b) in enumerate(consider):
- legendBox = Bbox.from_bounds(l, b, width, height)
- badness = 0
- # XXX TODO: If markers are present, it would be good to take them
- # into account when checking vertex overlaps in the next line.
- badness = (sum(legendBox.count_contains(line.vertices)
- for line in lines)
- + legendBox.count_contains(offsets)
- + legendBox.count_overlaps(bboxes)
- + sum(line.intersects_bbox(legendBox, filled=False)
- for line in lines))
- if badness == 0:
- return l, b
- # Include the index to favor lower codes in case of a tie.
- candidates.append((badness, idx, (l, b)))
-
- _, _, (l, b) = min(candidates)
-
- if self._loc_used_default and time.perf_counter() - start_time > 1:
- _api.warn_external(
- 'Creating legend with loc="best" can be slow with large '
- 'amounts of data.')
-
- return l, b
-
- @_api.rename_parameter("3.8", "event", "mouseevent")
- def contains(self, mouseevent):
- return self.legendPatch.contains(mouseevent)
-
- def set_draggable(self, state, use_blit=False, update='loc'):
- """
- Enable or disable mouse dragging support of the legend.
-
- Parameters
- ----------
- state : bool
- Whether mouse dragging is enabled.
- use_blit : bool, optional
- Use blitting for faster image composition. For details see
- :ref:`func-animation`.
- update : {'loc', 'bbox'}, optional
- The legend parameter to be changed when dragged:
-
- - 'loc': update the *loc* parameter of the legend
- - 'bbox': update the *bbox_to_anchor* parameter of the legend
-
- Returns
- -------
- `.DraggableLegend` or *None*
- If *state* is ``True`` this returns the `.DraggableLegend` helper
- instance. Otherwise this returns *None*.
- """
- if state:
- if self._draggable is None:
- self._draggable = DraggableLegend(self,
- use_blit,
- update=update)
- else:
- if self._draggable is not None:
- self._draggable.disconnect()
- self._draggable = None
- return self._draggable
-
- def get_draggable(self):
- """Return ``True`` if the legend is draggable, ``False`` otherwise."""
- return self._draggable is not None
-
-
-# Helper functions to parse legend arguments for both `figure.legend` and
-# `axes.legend`:
-def _get_legend_handles(axs, legend_handler_map=None):
- """Yield artists that can be used as handles in a legend."""
- handles_original = []
- for ax in axs:
- handles_original += [
- *(a for a in ax._children
- if isinstance(a, (Line2D, Patch, Collection, Text))),
- *ax.containers]
- # support parasite axes:
- if hasattr(ax, 'parasites'):
- for axx in ax.parasites:
- handles_original += [
- *(a for a in axx._children
- if isinstance(a, (Line2D, Patch, Collection, Text))),
- *axx.containers]
-
- handler_map = {**Legend.get_default_handler_map(),
- **(legend_handler_map or {})}
- has_handler = Legend.get_legend_handler
- for handle in handles_original:
- label = handle.get_label()
- if label != '_nolegend_' and has_handler(handler_map, handle):
- yield handle
- elif (label and not label.startswith('_') and
- not has_handler(handler_map, handle)):
- _api.warn_external(
- "Legend does not support handles for "
- f"{type(handle).__name__} "
- "instances.\nSee: https://matplotlib.org/stable/"
- "tutorials/intermediate/legend_guide.html"
- "#implementing-a-custom-legend-handler")
- continue
-
-
-def _get_legend_handles_labels(axs, legend_handler_map=None):
- """Return handles and labels for legend."""
- handles = []
- labels = []
- for handle in _get_legend_handles(axs, legend_handler_map):
- label = handle.get_label()
- if label and not label.startswith('_'):
- handles.append(handle)
- labels.append(label)
- return handles, labels
-
-
-def _parse_legend_args(axs, *args, handles=None, labels=None, **kwargs):
- """
- Get the handles and labels from the calls to either ``figure.legend``
- or ``axes.legend``.
-
- The parser is a bit involved because we support::
-
- legend()
- legend(labels)
- legend(handles, labels)
- legend(labels=labels)
- legend(handles=handles)
- legend(handles=handles, labels=labels)
-
- The behavior for a mixture of positional and keyword handles and labels
- is undefined and issues a warning.
-
- Parameters
- ----------
- axs : list of `.Axes`
- If handles are not given explicitly, the artists in these Axes are
- used as handles.
- *args : tuple
- Positional parameters passed to ``legend()``.
- handles
- The value of the keyword argument ``legend(handles=...)``, or *None*
- if that keyword argument was not used.
- labels
- The value of the keyword argument ``legend(labels=...)``, or *None*
- if that keyword argument was not used.
- **kwargs
- All other keyword arguments passed to ``legend()``.
-
- Returns
- -------
- handles : list of (`.Artist` or tuple of `.Artist`)
- The legend handles.
- labels : list of str
- The legend labels.
- kwargs : dict
- *kwargs* with keywords handles and labels removed.
-
- """
- log = logging.getLogger(__name__)
-
- handlers = kwargs.get('handler_map')
-
- if (handles is not None or labels is not None) and args:
- _api.warn_external("You have mixed positional and keyword arguments, "
- "some input may be discarded.")
-
- # if got both handles and labels as kwargs, make same length
- if handles and labels:
- handles, labels = zip(*zip(handles, labels))
-
- elif handles is not None and labels is None:
- labels = [handle.get_label() for handle in handles]
-
- elif labels is not None and handles is None:
- # Get as many handles as there are labels.
- handles = [handle for handle, label
- in zip(_get_legend_handles(axs, handlers), labels)]
-
- elif len(args) == 0: # 0 args: automatically detect labels and handles.
- handles, labels = _get_legend_handles_labels(axs, handlers)
- if not handles:
- log.warning(
- "No artists with labels found to put in legend. Note that "
- "artists whose label start with an underscore are ignored "
- "when legend() is called with no argument.")
-
- elif len(args) == 1: # 1 arg: user defined labels, automatic handle detection.
- labels, = args
- if any(isinstance(l, Artist) for l in labels):
- raise TypeError("A single argument passed to legend() must be a "
- "list of labels, but found an Artist in there.")
-
- # Get as many handles as there are labels.
- handles = [handle for handle, label
- in zip(_get_legend_handles(axs, handlers), labels)]
-
- elif len(args) == 2: # 2 args: user defined handles and labels.
- handles, labels = args[:2]
-
- else:
- raise _api.nargs_error('legend', '0-2', len(args))
-
- return handles, labels, kwargs
diff --git a/contrib/python/matplotlib/py3/matplotlib/legend.pyi b/contrib/python/matplotlib/py3/matplotlib/legend.pyi
deleted file mode 100644
index d559b06c5d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/legend.pyi
+++ /dev/null
@@ -1,154 +0,0 @@
-from matplotlib.axes import Axes
-from matplotlib.artist import Artist
-from matplotlib.backend_bases import MouseEvent
-from matplotlib.figure import Figure
-from matplotlib.font_manager import FontProperties
-from matplotlib.legend_handler import HandlerBase
-from matplotlib.lines import Line2D
-from matplotlib.offsetbox import (
- DraggableOffsetBox,
-)
-from matplotlib.patches import FancyBboxPatch, Patch, Rectangle
-from matplotlib.text import Text
-from matplotlib.transforms import (
- BboxBase,
- Transform,
-)
-
-
-import pathlib
-from collections.abc import Iterable
-from typing import Any, Literal, overload
-from .typing import ColorType
-
-class DraggableLegend(DraggableOffsetBox):
- legend: Legend
- def __init__(
- self, legend: Legend, use_blit: bool = ..., update: Literal["loc", "bbox"] = ...
- ) -> None: ...
- def finalize_offset(self) -> None: ...
-
-class Legend(Artist):
- codes: dict[str, int]
- zorder: float
- prop: FontProperties
- texts: list[Text]
- legend_handles: list[Artist | None]
- numpoints: int
- markerscale: float
- scatterpoints: int
- borderpad: float
- labelspacing: float
- handlelength: float
- handleheight: float
- handletextpad: float
- borderaxespad: float
- columnspacing: float
- shadow: bool
- isaxes: bool
- axes: Axes
- parent: Axes | Figure
- legendPatch: FancyBboxPatch
- def __init__(
- self,
- parent: Axes | Figure,
- handles: Iterable[Artist | tuple[Artist, ...]],
- labels: Iterable[str],
- *,
- loc: str | tuple[float, float] | int | None = ...,
- numpoints: int | None = ...,
- markerscale: float | None = ...,
- markerfirst: bool = ...,
- reverse: bool = ...,
- scatterpoints: int | None = ...,
- scatteryoffsets: Iterable[float] | None = ...,
- prop: FontProperties | dict[str, Any] | None = ...,
- fontsize: float | str | None = ...,
- labelcolor: ColorType
- | Iterable[ColorType]
- | Literal["linecolor", "markerfacecolor", "mfc", "markeredgecolor", "mec"]
- | None = ...,
- borderpad: float | None = ...,
- labelspacing: float | None = ...,
- handlelength: float | None = ...,
- handleheight: float | None = ...,
- handletextpad: float | None = ...,
- borderaxespad: float | None = ...,
- columnspacing: float | None = ...,
- ncols: int = ...,
- mode: Literal["expand"] | None = ...,
- fancybox: bool | None = ...,
- shadow: bool | dict[str, Any] | None = ...,
- title: str | None = ...,
- title_fontsize: float | None = ...,
- framealpha: float | None = ...,
- edgecolor: Literal["inherit"] | ColorType | None = ...,
- facecolor: Literal["inherit"] | ColorType | None = ...,
- bbox_to_anchor: BboxBase
- | tuple[float, float]
- | tuple[float, float, float, float]
- | None = ...,
- bbox_transform: Transform | None = ...,
- frameon: bool | None = ...,
- handler_map: dict[Artist | type, HandlerBase] | None = ...,
- title_fontproperties: FontProperties | dict[str, Any] | None = ...,
- alignment: Literal["center", "left", "right"] = ...,
- ncol: int = ...,
- draggable: bool = ...
- ) -> None: ...
- def contains(self, mouseevent: MouseEvent) -> tuple[bool, dict[Any, Any]]: ...
- def set_ncols(self, ncols: int) -> None: ...
- @classmethod
- def get_default_handler_map(cls) -> dict[type, HandlerBase]: ...
- @classmethod
- def set_default_handler_map(cls, handler_map: dict[type, HandlerBase]) -> None: ...
- @classmethod
- def update_default_handler_map(
- cls, handler_map: dict[type, HandlerBase]
- ) -> None: ...
- def get_legend_handler_map(self) -> dict[type, HandlerBase]: ...
- @staticmethod
- def get_legend_handler(
- legend_handler_map: dict[type, HandlerBase], orig_handle: Any
- ) -> HandlerBase | None: ...
- def get_children(self) -> list[Artist]: ...
- def get_frame(self) -> Rectangle: ...
- def get_lines(self) -> list[Line2D]: ...
- def get_patches(self) -> list[Patch]: ...
- def get_texts(self) -> list[Text]: ...
- def set_alignment(self, alignment: Literal["center", "left", "right"]) -> None: ...
- def get_alignment(self) -> Literal["center", "left", "right"]: ...
- def set_loc(self, loc: str | tuple[float, float] | int | None = ...) -> None: ...
- def set_title(
- self, title: str, prop: FontProperties | str | pathlib.Path | None = ...
- ) -> None: ...
- def get_title(self) -> Text: ...
- def get_frame_on(self) -> bool: ...
- def set_frame_on(self, b: bool) -> None: ...
- draw_frame = set_frame_on
- def get_bbox_to_anchor(self) -> BboxBase: ...
- def set_bbox_to_anchor(
- self,
- bbox: BboxBase
- | tuple[float, float]
- | tuple[float, float, float, float]
- | None,
- transform: Transform | None = ...
- ) -> None: ...
- @overload
- def set_draggable(
- self,
- state: Literal[True],
- use_blit: bool = ...,
- update: Literal["loc", "bbox"] = ...,
- ) -> DraggableLegend: ...
- @overload
- def set_draggable(
- self,
- state: Literal[False],
- use_blit: bool = ...,
- update: Literal["loc", "bbox"] = ...,
- ) -> None: ...
- def get_draggable(self) -> bool: ...
- @property
- def legendHandles(self) -> list[Artist | None]: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/legend_handler.py b/contrib/python/matplotlib/py3/matplotlib/legend_handler.py
deleted file mode 100644
index 5a929070e3..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/legend_handler.py
+++ /dev/null
@@ -1,813 +0,0 @@
-"""
-Default legend handlers.
-
-.. important::
-
- This is a low-level legend API, which most end users do not need.
-
- We recommend that you are familiar with the :ref:`legend guide
- <legend_guide>` before reading this documentation.
-
-Legend handlers are expected to be a callable object with a following
-signature::
-
- legend_handler(legend, orig_handle, fontsize, handlebox)
-
-Where *legend* is the legend itself, *orig_handle* is the original
-plot, *fontsize* is the fontsize in pixels, and *handlebox* is an
-`.OffsetBox` instance. Within the call, you should create relevant
-artists (using relevant properties from the *legend* and/or
-*orig_handle*) and add them into the *handlebox*. The artists need to
-be scaled according to the *fontsize* (note that the size is in pixels,
-i.e., this is dpi-scaled value).
-
-This module includes definition of several legend handler classes
-derived from the base class (HandlerBase) with the following method::
-
- def legend_artist(self, legend, orig_handle, fontsize, handlebox)
-"""
-
-from itertools import cycle
-
-import numpy as np
-
-from matplotlib import cbook
-from matplotlib.lines import Line2D
-from matplotlib.patches import Rectangle
-import matplotlib.collections as mcoll
-
-
-def update_from_first_child(tgt, src):
- first_child = next(iter(src.get_children()), None)
- if first_child is not None:
- tgt.update_from(first_child)
-
-
-class HandlerBase:
- """
- A base class for default legend handlers.
-
- The derived classes are meant to override *create_artists* method, which
- has the following signature::
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- trans):
-
- The overridden method needs to create artists of the given
- transform that fits in the given dimension (xdescent, ydescent,
- width, height) that are scaled by fontsize if necessary.
-
- """
- def __init__(self, xpad=0., ypad=0., update_func=None):
- """
- Parameters
- ----------
- xpad : float, optional
- Padding in x-direction.
- ypad : float, optional
- Padding in y-direction.
- update_func : callable, optional
- Function for updating the legend handler properties from another
- legend handler, used by `~HandlerBase.update_prop`.
- """
- self._xpad, self._ypad = xpad, ypad
- self._update_prop_func = update_func
-
- def _update_prop(self, legend_handle, orig_handle):
- if self._update_prop_func is None:
- self._default_update_prop(legend_handle, orig_handle)
- else:
- self._update_prop_func(legend_handle, orig_handle)
-
- def _default_update_prop(self, legend_handle, orig_handle):
- legend_handle.update_from(orig_handle)
-
- def update_prop(self, legend_handle, orig_handle, legend):
-
- self._update_prop(legend_handle, orig_handle)
-
- legend._set_artist_props(legend_handle)
- legend_handle.set_clip_box(None)
- legend_handle.set_clip_path(None)
-
- def adjust_drawing_area(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- ):
- xdescent = xdescent - self._xpad * fontsize
- ydescent = ydescent - self._ypad * fontsize
- width = width - self._xpad * fontsize
- height = height - self._ypad * fontsize
- return xdescent, ydescent, width, height
-
- def legend_artist(self, legend, orig_handle,
- fontsize, handlebox):
- """
- Return the artist that this HandlerBase generates for the given
- original artist/handle.
-
- Parameters
- ----------
- legend : `~matplotlib.legend.Legend`
- The legend for which these legend artists are being created.
- orig_handle : :class:`matplotlib.artist.Artist` or similar
- The object for which these legend artists are being created.
- fontsize : int
- The fontsize in pixels. The artists being created should
- be scaled according to the given fontsize.
- handlebox : `~matplotlib.offsetbox.OffsetBox`
- The box which has been created to hold this legend entry's
- artists. Artists created in the `legend_artist` method must
- be added to this handlebox inside this method.
-
- """
- xdescent, ydescent, width, height = self.adjust_drawing_area(
- legend, orig_handle,
- handlebox.xdescent, handlebox.ydescent,
- handlebox.width, handlebox.height,
- fontsize)
- artists = self.create_artists(legend, orig_handle,
- xdescent, ydescent, width, height,
- fontsize, handlebox.get_transform())
-
- # create_artists will return a list of artists.
- for a in artists:
- handlebox.add_artist(a)
-
- # we only return the first artist
- return artists[0]
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- trans):
- """
- Return the legend artists generated.
-
- Parameters
- ----------
- legend : `~matplotlib.legend.Legend`
- The legend for which these legend artists are being created.
- orig_handle : `~matplotlib.artist.Artist` or similar
- The object for which these legend artists are being created.
- xdescent, ydescent, width, height : int
- The rectangle (*xdescent*, *ydescent*, *width*, *height*) that the
- legend artists being created should fit within.
- fontsize : int
- The fontsize in pixels. The legend artists being created should
- be scaled according to the given fontsize.
- trans : `~matplotlib.transforms.Transform`
- The transform that is applied to the legend artists being created.
- Typically from unit coordinates in the handler box to screen
- coordinates.
- """
- raise NotImplementedError('Derived must override')
-
-
-class HandlerNpoints(HandlerBase):
- """
- A legend handler that shows *numpoints* points in the legend entry.
- """
-
- def __init__(self, marker_pad=0.3, numpoints=None, **kwargs):
- """
- Parameters
- ----------
- marker_pad : float
- Padding between points in legend entry.
- numpoints : int
- Number of points to show in legend entry.
- **kwargs
- Keyword arguments forwarded to `.HandlerBase`.
- """
- super().__init__(**kwargs)
-
- self._numpoints = numpoints
- self._marker_pad = marker_pad
-
- def get_numpoints(self, legend):
- if self._numpoints is None:
- return legend.numpoints
- else:
- return self._numpoints
-
- def get_xdata(self, legend, xdescent, ydescent, width, height, fontsize):
- numpoints = self.get_numpoints(legend)
- if numpoints > 1:
- # we put some pad here to compensate the size of the marker
- pad = self._marker_pad * fontsize
- xdata = np.linspace(-xdescent + pad,
- -xdescent + width - pad,
- numpoints)
- xdata_marker = xdata
- else:
- xdata = [-xdescent, -xdescent + width]
- xdata_marker = [-xdescent + 0.5 * width]
- return xdata, xdata_marker
-
-
-class HandlerNpointsYoffsets(HandlerNpoints):
- """
- A legend handler that shows *numpoints* in the legend, and allows them to
- be individually offset in the y-direction.
- """
-
- def __init__(self, numpoints=None, yoffsets=None, **kwargs):
- """
- Parameters
- ----------
- numpoints : int
- Number of points to show in legend entry.
- yoffsets : array of floats
- Length *numpoints* list of y offsets for each point in
- legend entry.
- **kwargs
- Keyword arguments forwarded to `.HandlerNpoints`.
- """
- super().__init__(numpoints=numpoints, **kwargs)
- self._yoffsets = yoffsets
-
- def get_ydata(self, legend, xdescent, ydescent, width, height, fontsize):
- if self._yoffsets is None:
- ydata = height * legend._scatteryoffsets
- else:
- ydata = height * np.asarray(self._yoffsets)
-
- return ydata
-
-
-class HandlerLine2DCompound(HandlerNpoints):
- """
- Original handler for `.Line2D` instances, that relies on combining
- a line-only with a marker-only artist. May be deprecated in the future.
- """
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- trans):
- # docstring inherited
- xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent,
- width, height, fontsize)
-
- ydata = np.full_like(xdata, ((height - ydescent) / 2))
- legline = Line2D(xdata, ydata)
-
- self.update_prop(legline, orig_handle, legend)
- legline.set_drawstyle('default')
- legline.set_marker("")
-
- legline_marker = Line2D(xdata_marker, ydata[:len(xdata_marker)])
- self.update_prop(legline_marker, orig_handle, legend)
- legline_marker.set_linestyle('None')
- if legend.markerscale != 1:
- newsz = legline_marker.get_markersize() * legend.markerscale
- legline_marker.set_markersize(newsz)
- # we don't want to add this to the return list because
- # the texts and handles are assumed to be in one-to-one
- # correspondence.
- legline._legmarker = legline_marker
-
- legline.set_transform(trans)
- legline_marker.set_transform(trans)
-
- return [legline, legline_marker]
-
-
-class HandlerLine2D(HandlerNpoints):
- """
- Handler for `.Line2D` instances.
-
- See Also
- --------
- HandlerLine2DCompound : An earlier handler implementation, which used one
- artist for the line and another for the marker(s).
- """
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- trans):
- # docstring inherited
- xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent,
- width, height, fontsize)
-
- markevery = None
- if self.get_numpoints(legend) == 1:
- # Special case: one wants a single marker in the center
- # and a line that extends on both sides. One will use a
- # 3 points line, but only mark the #1 (i.e. middle) point.
- xdata = np.linspace(xdata[0], xdata[-1], 3)
- markevery = [1]
-
- ydata = np.full_like(xdata, (height - ydescent) / 2)
- legline = Line2D(xdata, ydata, markevery=markevery)
-
- self.update_prop(legline, orig_handle, legend)
-
- if legend.markerscale != 1:
- newsz = legline.get_markersize() * legend.markerscale
- legline.set_markersize(newsz)
-
- legline.set_transform(trans)
-
- return [legline]
-
-
-class HandlerPatch(HandlerBase):
- """
- Handler for `.Patch` instances.
- """
-
- def __init__(self, patch_func=None, **kwargs):
- """
- Parameters
- ----------
- patch_func : callable, optional
- The function that creates the legend key artist.
- *patch_func* should have the signature::
-
- def patch_func(legend=legend, orig_handle=orig_handle,
- xdescent=xdescent, ydescent=ydescent,
- width=width, height=height, fontsize=fontsize)
-
- Subsequently, the created artist will have its ``update_prop``
- method called and the appropriate transform will be applied.
-
- **kwargs
- Keyword arguments forwarded to `.HandlerBase`.
- """
- super().__init__(**kwargs)
- self._patch_func = patch_func
-
- def _create_patch(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize):
- if self._patch_func is None:
- p = Rectangle(xy=(-xdescent, -ydescent),
- width=width, height=height)
- else:
- p = self._patch_func(legend=legend, orig_handle=orig_handle,
- xdescent=xdescent, ydescent=ydescent,
- width=width, height=height, fontsize=fontsize)
- return p
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize, trans):
- # docstring inherited
- p = self._create_patch(legend, orig_handle,
- xdescent, ydescent, width, height, fontsize)
- self.update_prop(p, orig_handle, legend)
- p.set_transform(trans)
- return [p]
-
-
-class HandlerStepPatch(HandlerBase):
- """
- Handler for `~.matplotlib.patches.StepPatch` instances.
- """
-
- @staticmethod
- def _create_patch(orig_handle, xdescent, ydescent, width, height):
- return Rectangle(xy=(-xdescent, -ydescent), width=width,
- height=height, color=orig_handle.get_facecolor())
-
- @staticmethod
- def _create_line(orig_handle, width, height):
- # Unfilled StepPatch should show as a line
- legline = Line2D([0, width], [height/2, height/2],
- color=orig_handle.get_edgecolor(),
- linestyle=orig_handle.get_linestyle(),
- linewidth=orig_handle.get_linewidth(),
- )
-
- # Overwrite manually because patch and line properties don't mix
- legline.set_drawstyle('default')
- legline.set_marker("")
- return legline
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize, trans):
- # docstring inherited
- if orig_handle.get_fill() or (orig_handle.get_hatch() is not None):
- p = self._create_patch(orig_handle, xdescent, ydescent, width,
- height)
- self.update_prop(p, orig_handle, legend)
- else:
- p = self._create_line(orig_handle, width, height)
- p.set_transform(trans)
- return [p]
-
-
-class HandlerLineCollection(HandlerLine2D):
- """
- Handler for `.LineCollection` instances.
- """
- def get_numpoints(self, legend):
- if self._numpoints is None:
- return legend.scatterpoints
- else:
- return self._numpoints
-
- def _default_update_prop(self, legend_handle, orig_handle):
- lw = orig_handle.get_linewidths()[0]
- dashes = orig_handle._us_linestyles[0]
- color = orig_handle.get_colors()[0]
- legend_handle.set_color(color)
- legend_handle.set_linestyle(dashes)
- legend_handle.set_linewidth(lw)
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize, trans):
- # docstring inherited
- xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent,
- width, height, fontsize)
- ydata = np.full_like(xdata, (height - ydescent) / 2)
- legline = Line2D(xdata, ydata)
-
- self.update_prop(legline, orig_handle, legend)
- legline.set_transform(trans)
-
- return [legline]
-
-
-class HandlerRegularPolyCollection(HandlerNpointsYoffsets):
- r"""Handler for `.RegularPolyCollection`\s."""
-
- def __init__(self, yoffsets=None, sizes=None, **kwargs):
- super().__init__(yoffsets=yoffsets, **kwargs)
-
- self._sizes = sizes
-
- def get_numpoints(self, legend):
- if self._numpoints is None:
- return legend.scatterpoints
- else:
- return self._numpoints
-
- def get_sizes(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize):
- if self._sizes is None:
- handle_sizes = orig_handle.get_sizes()
- if not len(handle_sizes):
- handle_sizes = [1]
- size_max = max(handle_sizes) * legend.markerscale ** 2
- size_min = min(handle_sizes) * legend.markerscale ** 2
-
- numpoints = self.get_numpoints(legend)
- if numpoints < 4:
- sizes = [.5 * (size_max + size_min), size_max,
- size_min][:numpoints]
- else:
- rng = (size_max - size_min)
- sizes = rng * np.linspace(0, 1, numpoints) + size_min
- else:
- sizes = self._sizes
-
- return sizes
-
- def update_prop(self, legend_handle, orig_handle, legend):
-
- self._update_prop(legend_handle, orig_handle)
-
- legend_handle.set_figure(legend.figure)
- # legend._set_artist_props(legend_handle)
- legend_handle.set_clip_box(None)
- legend_handle.set_clip_path(None)
-
- def create_collection(self, orig_handle, sizes, offsets, offset_transform):
- return type(orig_handle)(
- orig_handle.get_numsides(),
- rotation=orig_handle.get_rotation(), sizes=sizes,
- offsets=offsets, offset_transform=offset_transform,
- )
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- trans):
- # docstring inherited
- xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent,
- width, height, fontsize)
-
- ydata = self.get_ydata(legend, xdescent, ydescent,
- width, height, fontsize)
-
- sizes = self.get_sizes(legend, orig_handle, xdescent, ydescent,
- width, height, fontsize)
-
- p = self.create_collection(
- orig_handle, sizes,
- offsets=list(zip(xdata_marker, ydata)), offset_transform=trans)
-
- self.update_prop(p, orig_handle, legend)
- p.set_offset_transform(trans)
- return [p]
-
-
-class HandlerPathCollection(HandlerRegularPolyCollection):
- r"""Handler for `.PathCollection`\s, which are used by `~.Axes.scatter`."""
-
- def create_collection(self, orig_handle, sizes, offsets, offset_transform):
- return type(orig_handle)(
- [orig_handle.get_paths()[0]], sizes=sizes,
- offsets=offsets, offset_transform=offset_transform,
- )
-
-
-class HandlerCircleCollection(HandlerRegularPolyCollection):
- r"""Handler for `.CircleCollection`\s."""
-
- def create_collection(self, orig_handle, sizes, offsets, offset_transform):
- return type(orig_handle)(
- sizes, offsets=offsets, offset_transform=offset_transform)
-
-
-class HandlerErrorbar(HandlerLine2D):
- """Handler for Errorbars."""
-
- def __init__(self, xerr_size=0.5, yerr_size=None,
- marker_pad=0.3, numpoints=None, **kwargs):
-
- self._xerr_size = xerr_size
- self._yerr_size = yerr_size
-
- super().__init__(marker_pad=marker_pad, numpoints=numpoints, **kwargs)
-
- def get_err_size(self, legend, xdescent, ydescent,
- width, height, fontsize):
- xerr_size = self._xerr_size * fontsize
-
- if self._yerr_size is None:
- yerr_size = xerr_size
- else:
- yerr_size = self._yerr_size * fontsize
-
- return xerr_size, yerr_size
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- trans):
- # docstring inherited
- plotlines, caplines, barlinecols = orig_handle
-
- xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent,
- width, height, fontsize)
-
- ydata = np.full_like(xdata, (height - ydescent) / 2)
- legline = Line2D(xdata, ydata)
-
- xdata_marker = np.asarray(xdata_marker)
- ydata_marker = np.asarray(ydata[:len(xdata_marker)])
-
- xerr_size, yerr_size = self.get_err_size(legend, xdescent, ydescent,
- width, height, fontsize)
-
- legline_marker = Line2D(xdata_marker, ydata_marker)
-
- # when plotlines are None (only errorbars are drawn), we just
- # make legline invisible.
- if plotlines is None:
- legline.set_visible(False)
- legline_marker.set_visible(False)
- else:
- self.update_prop(legline, plotlines, legend)
-
- legline.set_drawstyle('default')
- legline.set_marker('none')
-
- self.update_prop(legline_marker, plotlines, legend)
- legline_marker.set_linestyle('None')
-
- if legend.markerscale != 1:
- newsz = legline_marker.get_markersize() * legend.markerscale
- legline_marker.set_markersize(newsz)
-
- handle_barlinecols = []
- handle_caplines = []
-
- if orig_handle.has_xerr:
- verts = [((x - xerr_size, y), (x + xerr_size, y))
- for x, y in zip(xdata_marker, ydata_marker)]
- coll = mcoll.LineCollection(verts)
- self.update_prop(coll, barlinecols[0], legend)
- handle_barlinecols.append(coll)
-
- if caplines:
- capline_left = Line2D(xdata_marker - xerr_size, ydata_marker)
- capline_right = Line2D(xdata_marker + xerr_size, ydata_marker)
- self.update_prop(capline_left, caplines[0], legend)
- self.update_prop(capline_right, caplines[0], legend)
- capline_left.set_marker("|")
- capline_right.set_marker("|")
-
- handle_caplines.append(capline_left)
- handle_caplines.append(capline_right)
-
- if orig_handle.has_yerr:
- verts = [((x, y - yerr_size), (x, y + yerr_size))
- for x, y in zip(xdata_marker, ydata_marker)]
- coll = mcoll.LineCollection(verts)
- self.update_prop(coll, barlinecols[0], legend)
- handle_barlinecols.append(coll)
-
- if caplines:
- capline_left = Line2D(xdata_marker, ydata_marker - yerr_size)
- capline_right = Line2D(xdata_marker, ydata_marker + yerr_size)
- self.update_prop(capline_left, caplines[0], legend)
- self.update_prop(capline_right, caplines[0], legend)
- capline_left.set_marker("_")
- capline_right.set_marker("_")
-
- handle_caplines.append(capline_left)
- handle_caplines.append(capline_right)
-
- artists = [
- *handle_barlinecols, *handle_caplines, legline, legline_marker,
- ]
- for artist in artists:
- artist.set_transform(trans)
- return artists
-
-
-class HandlerStem(HandlerNpointsYoffsets):
- """
- Handler for plots produced by `~.Axes.stem`.
- """
-
- def __init__(self, marker_pad=0.3, numpoints=None,
- bottom=None, yoffsets=None, **kwargs):
- """
- Parameters
- ----------
- marker_pad : float, default: 0.3
- Padding between points in legend entry.
- numpoints : int, optional
- Number of points to show in legend entry.
- bottom : float, optional
-
- yoffsets : array of floats, optional
- Length *numpoints* list of y offsets for each point in
- legend entry.
- **kwargs
- Keyword arguments forwarded to `.HandlerNpointsYoffsets`.
- """
- super().__init__(marker_pad=marker_pad, numpoints=numpoints,
- yoffsets=yoffsets, **kwargs)
- self._bottom = bottom
-
- def get_ydata(self, legend, xdescent, ydescent, width, height, fontsize):
- if self._yoffsets is None:
- ydata = height * (0.5 * legend._scatteryoffsets + 0.5)
- else:
- ydata = height * np.asarray(self._yoffsets)
-
- return ydata
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- trans):
- # docstring inherited
- markerline, stemlines, baseline = orig_handle
- # Check to see if the stemcontainer is storing lines as a list or a
- # LineCollection. Eventually using a list will be removed, and this
- # logic can also be removed.
- using_linecoll = isinstance(stemlines, mcoll.LineCollection)
-
- xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent,
- width, height, fontsize)
-
- ydata = self.get_ydata(legend, xdescent, ydescent,
- width, height, fontsize)
-
- if self._bottom is None:
- bottom = 0.
- else:
- bottom = self._bottom
-
- leg_markerline = Line2D(xdata_marker, ydata[:len(xdata_marker)])
- self.update_prop(leg_markerline, markerline, legend)
-
- leg_stemlines = [Line2D([x, x], [bottom, y])
- for x, y in zip(xdata_marker, ydata)]
-
- if using_linecoll:
- # change the function used by update_prop() from the default
- # to one that handles LineCollection
- with cbook._setattr_cm(
- self, _update_prop_func=self._copy_collection_props):
- for line in leg_stemlines:
- self.update_prop(line, stemlines, legend)
-
- else:
- for lm, m in zip(leg_stemlines, stemlines):
- self.update_prop(lm, m, legend)
-
- leg_baseline = Line2D([np.min(xdata), np.max(xdata)],
- [bottom, bottom])
- self.update_prop(leg_baseline, baseline, legend)
-
- artists = [*leg_stemlines, leg_baseline, leg_markerline]
- for artist in artists:
- artist.set_transform(trans)
- return artists
-
- def _copy_collection_props(self, legend_handle, orig_handle):
- """
- Copy properties from the `.LineCollection` *orig_handle* to the
- `.Line2D` *legend_handle*.
- """
- legend_handle.set_color(orig_handle.get_color()[0])
- legend_handle.set_linestyle(orig_handle.get_linestyle()[0])
-
-
-class HandlerTuple(HandlerBase):
- """
- Handler for Tuple.
- """
-
- def __init__(self, ndivide=1, pad=None, **kwargs):
- """
- Parameters
- ----------
- ndivide : int or None, default: 1
- The number of sections to divide the legend area into. If None,
- use the length of the input tuple.
- pad : float, default: :rc:`legend.borderpad`
- Padding in units of fraction of font size.
- **kwargs
- Keyword arguments forwarded to `.HandlerBase`.
- """
- self._ndivide = ndivide
- self._pad = pad
- super().__init__(**kwargs)
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize,
- trans):
- # docstring inherited
- handler_map = legend.get_legend_handler_map()
-
- if self._ndivide is None:
- ndivide = len(orig_handle)
- else:
- ndivide = self._ndivide
-
- if self._pad is None:
- pad = legend.borderpad * fontsize
- else:
- pad = self._pad * fontsize
-
- if ndivide > 1:
- width = (width - pad * (ndivide - 1)) / ndivide
-
- xds_cycle = cycle(xdescent - (width + pad) * np.arange(ndivide))
-
- a_list = []
- for handle1 in orig_handle:
- handler = legend.get_legend_handler(handler_map, handle1)
- _a_list = handler.create_artists(
- legend, handle1,
- next(xds_cycle), ydescent, width, height, fontsize, trans)
- a_list.extend(_a_list)
-
- return a_list
-
-
-class HandlerPolyCollection(HandlerBase):
- """
- Handler for `.PolyCollection` used in `~.Axes.fill_between` and
- `~.Axes.stackplot`.
- """
- def _update_prop(self, legend_handle, orig_handle):
- def first_color(colors):
- if colors.size == 0:
- return (0, 0, 0, 0)
- return tuple(colors[0])
-
- def get_first(prop_array):
- if len(prop_array):
- return prop_array[0]
- else:
- return None
-
- # orig_handle is a PolyCollection and legend_handle is a Patch.
- # Directly set Patch color attributes (must be RGBA tuples).
- legend_handle._facecolor = first_color(orig_handle.get_facecolor())
- legend_handle._edgecolor = first_color(orig_handle.get_edgecolor())
- legend_handle._original_facecolor = orig_handle._original_facecolor
- legend_handle._original_edgecolor = orig_handle._original_edgecolor
- legend_handle._fill = orig_handle.get_fill()
- legend_handle._hatch = orig_handle.get_hatch()
- # Hatch color is anomalous in having no getters and setters.
- legend_handle._hatch_color = orig_handle._hatch_color
- # Setters are fine for the remaining attributes.
- legend_handle.set_linewidth(get_first(orig_handle.get_linewidths()))
- legend_handle.set_linestyle(get_first(orig_handle.get_linestyles()))
- legend_handle.set_transform(get_first(orig_handle.get_transforms()))
- legend_handle.set_figure(orig_handle.get_figure())
- # Alpha is already taken into account by the color attributes.
-
- def create_artists(self, legend, orig_handle,
- xdescent, ydescent, width, height, fontsize, trans):
- # docstring inherited
- p = Rectangle(xy=(-xdescent, -ydescent),
- width=width, height=height)
- self.update_prop(p, orig_handle, legend)
- p.set_transform(trans)
- return [p]
diff --git a/contrib/python/matplotlib/py3/matplotlib/legend_handler.pyi b/contrib/python/matplotlib/py3/matplotlib/legend_handler.pyi
deleted file mode 100644
index db028a136a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/legend_handler.pyi
+++ /dev/null
@@ -1,294 +0,0 @@
-from collections.abc import Callable, Sequence
-from matplotlib.artist import Artist
-from matplotlib.legend import Legend
-from matplotlib.offsetbox import OffsetBox
-from matplotlib.transforms import Transform
-
-from typing import TypeVar
-
-from numpy.typing import ArrayLike
-
-def update_from_first_child(tgt: Artist, src: Artist) -> None: ...
-
-class HandlerBase:
- def __init__(
- self,
- xpad: float = ...,
- ypad: float = ...,
- update_func: Callable[[Artist, Artist], None] | None = ...,
- ) -> None: ...
- def update_prop(
- self, legend_handle: Artist, orig_handle: Artist, legend: Legend
- ) -> None: ...
- def adjust_drawing_area(
- self,
- legend: Legend,
- orig_handle: Artist,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- ) -> tuple[float, float, float, float]: ...
- def legend_artist(
- self, legend: Legend, orig_handle: Artist, fontsize: float, handlebox: OffsetBox
- ) -> Artist: ...
- def create_artists(
- self,
- legend: Legend,
- orig_handle: Artist,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- trans: Transform,
- ) -> Sequence[Artist]: ...
-
-class HandlerNpoints(HandlerBase):
- def __init__(
- self, marker_pad: float = ..., numpoints: int | None = ..., **kwargs
- ) -> None: ...
- def get_numpoints(self, legend: Legend) -> int | None: ...
- def get_xdata(
- self,
- legend: Legend,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- ) -> tuple[ArrayLike, ArrayLike]: ...
-
-class HandlerNpointsYoffsets(HandlerNpoints):
- def __init__(
- self,
- numpoints: int | None = ...,
- yoffsets: Sequence[float] | None = ...,
- **kwargs
- ) -> None: ...
- def get_ydata(
- self,
- legend: Legend,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- ) -> ArrayLike: ...
-
-class HandlerLine2DCompound(HandlerNpoints):
- def create_artists(
- self,
- legend: Legend,
- orig_handle: Artist,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- trans: Transform,
- ) -> Sequence[Artist]: ...
-
-class HandlerLine2D(HandlerNpoints):
- def create_artists(
- self,
- legend: Legend,
- orig_handle: Artist,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- trans: Transform,
- ) -> Sequence[Artist]: ...
-
-class HandlerPatch(HandlerBase):
- def __init__(self, patch_func: Callable | None = ..., **kwargs) -> None: ...
- def create_artists(
- self,
- legend: Legend,
- orig_handle: Artist,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- trans: Transform,
- ) -> Sequence[Artist]: ...
-
-class HandlerStepPatch(HandlerBase):
- def create_artists(
- self,
- legend: Legend,
- orig_handle: Artist,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- trans: Transform,
- ) -> Sequence[Artist]: ...
-
-class HandlerLineCollection(HandlerLine2D):
- def get_numpoints(self, legend: Legend) -> int: ...
- def create_artists(
- self,
- legend: Legend,
- orig_handle: Artist,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- trans: Transform,
- ) -> Sequence[Artist]: ...
-
-_T = TypeVar("_T", bound=Artist)
-
-class HandlerRegularPolyCollection(HandlerNpointsYoffsets):
- def __init__(
- self,
- yoffsets: Sequence[float] | None = ...,
- sizes: Sequence[float] | None = ...,
- **kwargs
- ) -> None: ...
- def get_numpoints(self, legend: Legend) -> int: ...
- def get_sizes(
- self,
- legend: Legend,
- orig_handle: Artist,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- ) -> Sequence[float]: ...
- def update_prop(
- self, legend_handle, orig_handle: Artist, legend: Legend
- ) -> None: ...
- def create_collection(
- self,
- orig_handle: _T,
- sizes: Sequence[float] | None,
- offsets: Sequence[float] | None,
- offset_transform: Transform,
- ) -> _T: ...
- def create_artists(
- self,
- legend: Legend,
- orig_handle: Artist,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- trans: Transform,
- ) -> Sequence[Artist]: ...
-
-class HandlerPathCollection(HandlerRegularPolyCollection):
- def create_collection(
- self,
- orig_handle: _T,
- sizes: Sequence[float] | None,
- offsets: Sequence[float] | None,
- offset_transform: Transform,
- ) -> _T: ...
-
-class HandlerCircleCollection(HandlerRegularPolyCollection):
- def create_collection(
- self,
- orig_handle: _T,
- sizes: Sequence[float] | None,
- offsets: Sequence[float] | None,
- offset_transform: Transform,
- ) -> _T: ...
-
-class HandlerErrorbar(HandlerLine2D):
- def __init__(
- self,
- xerr_size: float = ...,
- yerr_size: float | None = ...,
- marker_pad: float = ...,
- numpoints: int | None = ...,
- **kwargs
- ) -> None: ...
- def get_err_size(
- self,
- legend: Legend,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- ) -> tuple[float, float]: ...
- def create_artists(
- self,
- legend: Legend,
- orig_handle: Artist,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- trans: Transform,
- ) -> Sequence[Artist]: ...
-
-class HandlerStem(HandlerNpointsYoffsets):
- def __init__(
- self,
- marker_pad: float = ...,
- numpoints: int | None = ...,
- bottom: float | None = ...,
- yoffsets: Sequence[float] | None = ...,
- **kwargs
- ) -> None: ...
- def get_ydata(
- self,
- legend: Legend,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- ) -> ArrayLike: ...
- def create_artists(
- self,
- legend: Legend,
- orig_handle: Artist,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- trans: Transform,
- ) -> Sequence[Artist]: ...
-
-class HandlerTuple(HandlerBase):
- def __init__(
- self, ndivide: int | None = ..., pad: float | None = ..., **kwargs
- ) -> None: ...
- def create_artists(
- self,
- legend: Legend,
- orig_handle: Artist,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- trans: Transform,
- ) -> Sequence[Artist]: ...
-
-class HandlerPolyCollection(HandlerBase):
- def create_artists(
- self,
- legend: Legend,
- orig_handle: Artist,
- xdescent: float,
- ydescent: float,
- width: float,
- height: float,
- fontsize: float,
- trans: Transform,
- ) -> Sequence[Artist]: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/lines.py b/contrib/python/matplotlib/py3/matplotlib/lines.py
deleted file mode 100644
index 92d55a3fe6..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/lines.py
+++ /dev/null
@@ -1,1677 +0,0 @@
-"""
-2D lines with support for a variety of line styles, markers, colors, etc.
-"""
-
-import copy
-
-from numbers import Integral, Number, Real
-import logging
-
-import numpy as np
-
-import matplotlib as mpl
-from . import _api, cbook, colors as mcolors, _docstring
-from .artist import Artist, allow_rasterization
-from .cbook import (
- _to_unmasked_float_array, ls_mapper, ls_mapper_r, STEP_LOOKUP_MAP)
-from .markers import MarkerStyle
-from .path import Path
-from .transforms import Bbox, BboxTransformTo, TransformedPath
-from ._enums import JoinStyle, CapStyle
-
-# Imported here for backward compatibility, even though they don't
-# really belong.
-from . import _path
-from .markers import ( # noqa
- CARETLEFT, CARETRIGHT, CARETUP, CARETDOWN,
- CARETLEFTBASE, CARETRIGHTBASE, CARETUPBASE, CARETDOWNBASE,
- TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN)
-
-_log = logging.getLogger(__name__)
-
-
-def _get_dash_pattern(style):
- """Convert linestyle to dash pattern."""
- # go from short hand -> full strings
- if isinstance(style, str):
- style = ls_mapper.get(style, style)
- # un-dashed styles
- if style in ['solid', 'None']:
- offset = 0
- dashes = None
- # dashed styles
- elif style in ['dashed', 'dashdot', 'dotted']:
- offset = 0
- dashes = tuple(mpl.rcParams[f'lines.{style}_pattern'])
- #
- elif isinstance(style, tuple):
- offset, dashes = style
- if offset is None:
- raise ValueError(f'Unrecognized linestyle: {style!r}')
- else:
- raise ValueError(f'Unrecognized linestyle: {style!r}')
-
- # normalize offset to be positive and shorter than the dash cycle
- if dashes is not None:
- dsum = sum(dashes)
- if dsum:
- offset %= dsum
-
- return offset, dashes
-
-
-def _get_inverse_dash_pattern(offset, dashes):
- """Return the inverse of the given dash pattern, for filling the gaps."""
- # Define the inverse pattern by moving the last gap to the start of the
- # sequence.
- gaps = dashes[-1:] + dashes[:-1]
- # Set the offset so that this new first segment is skipped
- # (see backend_bases.GraphicsContextBase.set_dashes for offset definition).
- offset_gaps = offset + dashes[-1]
-
- return offset_gaps, gaps
-
-
-def _scale_dashes(offset, dashes, lw):
- if not mpl.rcParams['lines.scale_dashes']:
- return offset, dashes
- scaled_offset = offset * lw
- scaled_dashes = ([x * lw if x is not None else None for x in dashes]
- if dashes is not None else None)
- return scaled_offset, scaled_dashes
-
-
-def segment_hits(cx, cy, x, y, radius):
- """
- Return the indices of the segments in the polyline with coordinates (*cx*,
- *cy*) that are within a distance *radius* of the point (*x*, *y*).
- """
- # Process single points specially
- if len(x) <= 1:
- res, = np.nonzero((cx - x) ** 2 + (cy - y) ** 2 <= radius ** 2)
- return res
-
- # We need to lop the last element off a lot.
- xr, yr = x[:-1], y[:-1]
-
- # Only look at line segments whose nearest point to C on the line
- # lies within the segment.
- dx, dy = x[1:] - xr, y[1:] - yr
- Lnorm_sq = dx ** 2 + dy ** 2 # Possibly want to eliminate Lnorm==0
- u = ((cx - xr) * dx + (cy - yr) * dy) / Lnorm_sq
- candidates = (u >= 0) & (u <= 1)
-
- # Note that there is a little area near one side of each point
- # which will be near neither segment, and another which will
- # be near both, depending on the angle of the lines. The
- # following radius test eliminates these ambiguities.
- point_hits = (cx - x) ** 2 + (cy - y) ** 2 <= radius ** 2
- candidates = candidates & ~(point_hits[:-1] | point_hits[1:])
-
- # For those candidates which remain, determine how far they lie away
- # from the line.
- px, py = xr + u * dx, yr + u * dy
- line_hits = (cx - px) ** 2 + (cy - py) ** 2 <= radius ** 2
- line_hits = line_hits & candidates
- points, = point_hits.ravel().nonzero()
- lines, = line_hits.ravel().nonzero()
- return np.concatenate((points, lines))
-
-
-def _mark_every_path(markevery, tpath, affine, ax):
- """
- Helper function that sorts out how to deal the input
- `markevery` and returns the points where markers should be drawn.
-
- Takes in the `markevery` value and the line path and returns the
- sub-sampled path.
- """
- # pull out the two bits of data we want from the path
- codes, verts = tpath.codes, tpath.vertices
-
- def _slice_or_none(in_v, slc):
- """Helper function to cope with `codes` being an ndarray or `None`."""
- if in_v is None:
- return None
- return in_v[slc]
-
- # if just an int, assume starting at 0 and make a tuple
- if isinstance(markevery, Integral):
- markevery = (0, markevery)
- # if just a float, assume starting at 0.0 and make a tuple
- elif isinstance(markevery, Real):
- markevery = (0.0, markevery)
-
- if isinstance(markevery, tuple):
- if len(markevery) != 2:
- raise ValueError('`markevery` is a tuple but its len is not 2; '
- f'markevery={markevery}')
- start, step = markevery
- # if step is an int, old behavior
- if isinstance(step, Integral):
- # tuple of 2 int is for backwards compatibility,
- if not isinstance(start, Integral):
- raise ValueError(
- '`markevery` is a tuple with len 2 and second element is '
- 'an int, but the first element is not an int; '
- f'markevery={markevery}')
- # just return, we are done here
-
- return Path(verts[slice(start, None, step)],
- _slice_or_none(codes, slice(start, None, step)))
-
- elif isinstance(step, Real):
- if not isinstance(start, Real):
- raise ValueError(
- '`markevery` is a tuple with len 2 and second element is '
- 'a float, but the first element is not a float or an int; '
- f'markevery={markevery}')
- if ax is None:
- raise ValueError(
- "markevery is specified relative to the axes size, but "
- "the line does not have a Axes as parent")
-
- # calc cumulative distance along path (in display coords):
- fin = np.isfinite(verts).all(axis=1)
- fverts = verts[fin]
- disp_coords = affine.transform(fverts)
-
- delta = np.empty((len(disp_coords), 2))
- delta[0, :] = 0
- delta[1:, :] = disp_coords[1:, :] - disp_coords[:-1, :]
- delta = np.hypot(*delta.T).cumsum()
- # calc distance between markers along path based on the axes
- # bounding box diagonal being a distance of unity:
- (x0, y0), (x1, y1) = ax.transAxes.transform([[0, 0], [1, 1]])
- scale = np.hypot(x1 - x0, y1 - y0)
- marker_delta = np.arange(start * scale, delta[-1], step * scale)
- # find closest actual data point that is closest to
- # the theoretical distance along the path:
- inds = np.abs(delta[np.newaxis, :] - marker_delta[:, np.newaxis])
- inds = inds.argmin(axis=1)
- inds = np.unique(inds)
- # return, we are done here
- return Path(fverts[inds], _slice_or_none(codes, inds))
- else:
- raise ValueError(
- f"markevery={markevery!r} is a tuple with len 2, but its "
- f"second element is not an int or a float")
-
- elif isinstance(markevery, slice):
- # mazol tov, it's already a slice, just return
- return Path(verts[markevery], _slice_or_none(codes, markevery))
-
- elif np.iterable(markevery):
- # fancy indexing
- try:
- return Path(verts[markevery], _slice_or_none(codes, markevery))
- except (ValueError, IndexError) as err:
- raise ValueError(
- f"markevery={markevery!r} is iterable but not a valid numpy "
- f"fancy index") from err
- else:
- raise ValueError(f"markevery={markevery!r} is not a recognized value")
-
-
-@_docstring.interpd
-@_api.define_aliases({
- "antialiased": ["aa"],
- "color": ["c"],
- "drawstyle": ["ds"],
- "linestyle": ["ls"],
- "linewidth": ["lw"],
- "markeredgecolor": ["mec"],
- "markeredgewidth": ["mew"],
- "markerfacecolor": ["mfc"],
- "markerfacecoloralt": ["mfcalt"],
- "markersize": ["ms"],
-})
-class Line2D(Artist):
- """
- A line - the line can have both a solid linestyle connecting all
- the vertices, and a marker at each vertex. Additionally, the
- drawing of the solid line is influenced by the drawstyle, e.g., one
- can create "stepped" lines in various styles.
- """
-
- lineStyles = _lineStyles = { # hidden names deprecated
- '-': '_draw_solid',
- '--': '_draw_dashed',
- '-.': '_draw_dash_dot',
- ':': '_draw_dotted',
- 'None': '_draw_nothing',
- ' ': '_draw_nothing',
- '': '_draw_nothing',
- }
-
- _drawStyles_l = {
- 'default': '_draw_lines',
- 'steps-mid': '_draw_steps_mid',
- 'steps-pre': '_draw_steps_pre',
- 'steps-post': '_draw_steps_post',
- }
-
- _drawStyles_s = {
- 'steps': '_draw_steps_pre',
- }
-
- # drawStyles should now be deprecated.
- drawStyles = {**_drawStyles_l, **_drawStyles_s}
- # Need a list ordered with long names first:
- drawStyleKeys = [*_drawStyles_l, *_drawStyles_s]
-
- # Referenced here to maintain API. These are defined in
- # MarkerStyle
- markers = MarkerStyle.markers
- filled_markers = MarkerStyle.filled_markers
- fillStyles = MarkerStyle.fillstyles
-
- zorder = 2
-
- _subslice_optim_min_size = 1000
-
- def __str__(self):
- if self._label != "":
- return f"Line2D({self._label})"
- elif self._x is None:
- return "Line2D()"
- elif len(self._x) > 3:
- return "Line2D(({:g},{:g}),({:g},{:g}),...,({:g},{:g}))".format(
- self._x[0], self._y[0],
- self._x[1], self._y[1],
- self._x[-1], self._y[-1])
- else:
- return "Line2D(%s)" % ",".join(
- map("({:g},{:g})".format, self._x, self._y))
-
- def __init__(self, xdata, ydata, *,
- linewidth=None, # all Nones default to rc
- linestyle=None,
- color=None,
- gapcolor=None,
- marker=None,
- markersize=None,
- markeredgewidth=None,
- markeredgecolor=None,
- markerfacecolor=None,
- markerfacecoloralt='none',
- fillstyle=None,
- antialiased=None,
- dash_capstyle=None,
- solid_capstyle=None,
- dash_joinstyle=None,
- solid_joinstyle=None,
- pickradius=5,
- drawstyle=None,
- markevery=None,
- **kwargs
- ):
- """
- Create a `.Line2D` instance with *x* and *y* data in sequences of
- *xdata*, *ydata*.
-
- Additional keyword arguments are `.Line2D` properties:
-
- %(Line2D:kwdoc)s
-
- See :meth:`set_linestyle` for a description of the line styles,
- :meth:`set_marker` for a description of the markers, and
- :meth:`set_drawstyle` for a description of the draw styles.
-
- """
- super().__init__()
-
- # Convert sequences to NumPy arrays.
- if not np.iterable(xdata):
- raise RuntimeError('xdata must be a sequence')
- if not np.iterable(ydata):
- raise RuntimeError('ydata must be a sequence')
-
- if linewidth is None:
- linewidth = mpl.rcParams['lines.linewidth']
-
- if linestyle is None:
- linestyle = mpl.rcParams['lines.linestyle']
- if marker is None:
- marker = mpl.rcParams['lines.marker']
- if color is None:
- color = mpl.rcParams['lines.color']
-
- if markersize is None:
- markersize = mpl.rcParams['lines.markersize']
- if antialiased is None:
- antialiased = mpl.rcParams['lines.antialiased']
- if dash_capstyle is None:
- dash_capstyle = mpl.rcParams['lines.dash_capstyle']
- if dash_joinstyle is None:
- dash_joinstyle = mpl.rcParams['lines.dash_joinstyle']
- if solid_capstyle is None:
- solid_capstyle = mpl.rcParams['lines.solid_capstyle']
- if solid_joinstyle is None:
- solid_joinstyle = mpl.rcParams['lines.solid_joinstyle']
-
- if drawstyle is None:
- drawstyle = 'default'
-
- self._dashcapstyle = None
- self._dashjoinstyle = None
- self._solidjoinstyle = None
- self._solidcapstyle = None
- self.set_dash_capstyle(dash_capstyle)
- self.set_dash_joinstyle(dash_joinstyle)
- self.set_solid_capstyle(solid_capstyle)
- self.set_solid_joinstyle(solid_joinstyle)
-
- self._linestyles = None
- self._drawstyle = None
- self._linewidth = linewidth
- self._unscaled_dash_pattern = (0, None) # offset, dash
- self._dash_pattern = (0, None) # offset, dash (scaled by linewidth)
-
- self.set_linewidth(linewidth)
- self.set_linestyle(linestyle)
- self.set_drawstyle(drawstyle)
-
- self._color = None
- self.set_color(color)
- if marker is None:
- marker = 'none' # Default.
- if not isinstance(marker, MarkerStyle):
- self._marker = MarkerStyle(marker, fillstyle)
- else:
- self._marker = marker
-
- self._gapcolor = None
- self.set_gapcolor(gapcolor)
-
- self._markevery = None
- self._markersize = None
- self._antialiased = None
-
- self.set_markevery(markevery)
- self.set_antialiased(antialiased)
- self.set_markersize(markersize)
-
- self._markeredgecolor = None
- self._markeredgewidth = None
- self._markerfacecolor = None
- self._markerfacecoloralt = None
-
- self.set_markerfacecolor(markerfacecolor) # Normalizes None to rc.
- self.set_markerfacecoloralt(markerfacecoloralt)
- self.set_markeredgecolor(markeredgecolor) # Normalizes None to rc.
- self.set_markeredgewidth(markeredgewidth)
-
- # update kwargs before updating data to give the caller a
- # chance to init axes (and hence unit support)
- self._internal_update(kwargs)
- self.pickradius = pickradius
- self.ind_offset = 0
- if (isinstance(self._picker, Number) and
- not isinstance(self._picker, bool)):
- self._pickradius = self._picker
-
- self._xorig = np.asarray([])
- self._yorig = np.asarray([])
- self._invalidx = True
- self._invalidy = True
- self._x = None
- self._y = None
- self._xy = None
- self._path = None
- self._transformed_path = None
- self._subslice = False
- self._x_filled = None # used in subslicing; only x is needed
-
- self.set_data(xdata, ydata)
-
- def contains(self, mouseevent):
- """
- Test whether *mouseevent* occurred on the line.
-
- An event is deemed to have occurred "on" the line if it is less
- than ``self.pickradius`` (default: 5 points) away from it. Use
- `~.Line2D.get_pickradius` or `~.Line2D.set_pickradius` to get or set
- the pick radius.
-
- Parameters
- ----------
- mouseevent : `~matplotlib.backend_bases.MouseEvent`
-
- Returns
- -------
- contains : bool
- Whether any values are within the radius.
- details : dict
- A dictionary ``{'ind': pointlist}``, where *pointlist* is a
- list of points of the line that are within the pickradius around
- the event position.
-
- TODO: sort returned indices by distance
- """
- if self._different_canvas(mouseevent):
- return False, {}
-
- # Make sure we have data to plot
- if self._invalidy or self._invalidx:
- self.recache()
- if len(self._xy) == 0:
- return False, {}
-
- # Convert points to pixels
- transformed_path = self._get_transformed_path()
- path, affine = transformed_path.get_transformed_path_and_affine()
- path = affine.transform_path(path)
- xy = path.vertices
- xt = xy[:, 0]
- yt = xy[:, 1]
-
- # Convert pick radius from points to pixels
- if self.figure is None:
- _log.warning('no figure set when check if mouse is on line')
- pixels = self._pickradius
- else:
- pixels = self.figure.dpi / 72. * self._pickradius
-
- # The math involved in checking for containment (here and inside of
- # segment_hits) assumes that it is OK to overflow, so temporarily set
- # the error flags accordingly.
- with np.errstate(all='ignore'):
- # Check for collision
- if self._linestyle in ['None', None]:
- # If no line, return the nearby point(s)
- ind, = np.nonzero(
- (xt - mouseevent.x) ** 2 + (yt - mouseevent.y) ** 2
- <= pixels ** 2)
- else:
- # If line, return the nearby segment(s)
- ind = segment_hits(mouseevent.x, mouseevent.y, xt, yt, pixels)
- if self._drawstyle.startswith("steps"):
- ind //= 2
-
- ind += self.ind_offset
-
- # Return the point(s) within radius
- return len(ind) > 0, dict(ind=ind)
-
- def get_pickradius(self):
- """
- Return the pick radius used for containment tests.
-
- See `.contains` for more details.
- """
- return self._pickradius
-
- def set_pickradius(self, pickradius):
- """
- Set the pick radius used for containment tests.
-
- See `.contains` for more details.
-
- Parameters
- ----------
- pickradius : float
- Pick radius, in points.
- """
- if not isinstance(pickradius, Real) or pickradius < 0:
- raise ValueError("pick radius should be a distance")
- self._pickradius = pickradius
-
- pickradius = property(get_pickradius, set_pickradius)
-
- def get_fillstyle(self):
- """
- Return the marker fill style.
-
- See also `~.Line2D.set_fillstyle`.
- """
- return self._marker.get_fillstyle()
-
- def set_fillstyle(self, fs):
- """
- Set the marker fill style.
-
- Parameters
- ----------
- fs : {'full', 'left', 'right', 'bottom', 'top', 'none'}
- Possible values:
-
- - 'full': Fill the whole marker with the *markerfacecolor*.
- - 'left', 'right', 'bottom', 'top': Fill the marker half at
- the given side with the *markerfacecolor*. The other
- half of the marker is filled with *markerfacecoloralt*.
- - 'none': No filling.
-
- For examples see :ref:`marker_fill_styles`.
- """
- self.set_marker(MarkerStyle(self._marker.get_marker(), fs))
- self.stale = True
-
- def set_markevery(self, every):
- """
- Set the markevery property to subsample the plot when using markers.
-
- e.g., if ``every=5``, every 5-th marker will be plotted.
-
- Parameters
- ----------
- every : None or int or (int, int) or slice or list[int] or float or \
-(float, float) or list[bool]
- Which markers to plot.
-
- - ``every=None``: every point will be plotted.
- - ``every=N``: every N-th marker will be plotted starting with
- marker 0.
- - ``every=(start, N)``: every N-th marker, starting at index
- *start*, will be plotted.
- - ``every=slice(start, end, N)``: every N-th marker, starting at
- index *start*, up to but not including index *end*, will be
- plotted.
- - ``every=[i, j, m, ...]``: only markers at the given indices
- will be plotted.
- - ``every=[True, False, True, ...]``: only positions that are True
- will be plotted. The list must have the same length as the data
- points.
- - ``every=0.1``, (i.e. a float): markers will be spaced at
- approximately equal visual distances along the line; the distance
- along the line between markers is determined by multiplying the
- display-coordinate distance of the axes bounding-box diagonal
- by the value of *every*.
- - ``every=(0.5, 0.1)`` (i.e. a length-2 tuple of float): similar
- to ``every=0.1`` but the first marker will be offset along the
- line by 0.5 multiplied by the
- display-coordinate-diagonal-distance along the line.
-
- For examples see
- :doc:`/gallery/lines_bars_and_markers/markevery_demo`.
-
- Notes
- -----
- Setting *markevery* will still only draw markers at actual data points.
- While the float argument form aims for uniform visual spacing, it has
- to coerce from the ideal spacing to the nearest available data point.
- Depending on the number and distribution of data points, the result
- may still not look evenly spaced.
-
- When using a start offset to specify the first marker, the offset will
- be from the first data point which may be different from the first
- the visible data point if the plot is zoomed in.
-
- If zooming in on a plot when using float arguments then the actual
- data points that have markers will change because the distance between
- markers is always determined from the display-coordinates
- axes-bounding-box-diagonal regardless of the actual axes data limits.
-
- """
- self._markevery = every
- self.stale = True
-
- def get_markevery(self):
- """
- Return the markevery setting for marker subsampling.
-
- See also `~.Line2D.set_markevery`.
- """
- return self._markevery
-
- def set_picker(self, p):
- """
- Set the event picker details for the line.
-
- Parameters
- ----------
- p : float or callable[[Artist, Event], tuple[bool, dict]]
- If a float, it is used as the pick radius in points.
- """
- if not callable(p):
- self.set_pickradius(p)
- self._picker = p
-
- def get_bbox(self):
- """Get the bounding box of this line."""
- bbox = Bbox([[0, 0], [0, 0]])
- bbox.update_from_data_xy(self.get_xydata())
- return bbox
-
- def get_window_extent(self, renderer=None):
- bbox = Bbox([[0, 0], [0, 0]])
- trans_data_to_xy = self.get_transform().transform
- bbox.update_from_data_xy(trans_data_to_xy(self.get_xydata()),
- ignore=True)
- # correct for marker size, if any
- if self._marker:
- ms = (self._markersize / 72.0 * self.figure.dpi) * 0.5
- bbox = bbox.padded(ms)
- return bbox
-
- def set_data(self, *args):
- """
- Set the x and y data.
-
- Parameters
- ----------
- *args : (2, N) array or two 1D arrays
- """
- if len(args) == 1:
- (x, y), = args
- else:
- x, y = args
-
- self.set_xdata(x)
- self.set_ydata(y)
-
- def recache_always(self):
- self.recache(always=True)
-
- def recache(self, always=False):
- if always or self._invalidx:
- xconv = self.convert_xunits(self._xorig)
- x = _to_unmasked_float_array(xconv).ravel()
- else:
- x = self._x
- if always or self._invalidy:
- yconv = self.convert_yunits(self._yorig)
- y = _to_unmasked_float_array(yconv).ravel()
- else:
- y = self._y
-
- self._xy = np.column_stack(np.broadcast_arrays(x, y)).astype(float)
- self._x, self._y = self._xy.T # views
-
- self._subslice = False
- if (self.axes
- and len(x) > self._subslice_optim_min_size
- and _path.is_sorted_and_has_non_nan(x)
- and self.axes.name == 'rectilinear'
- and self.axes.get_xscale() == 'linear'
- and self._markevery is None
- and self.get_clip_on()
- and self.get_transform() == self.axes.transData):
- self._subslice = True
- nanmask = np.isnan(x)
- if nanmask.any():
- self._x_filled = self._x.copy()
- indices = np.arange(len(x))
- self._x_filled[nanmask] = np.interp(
- indices[nanmask], indices[~nanmask], self._x[~nanmask])
- else:
- self._x_filled = self._x
-
- if self._path is not None:
- interpolation_steps = self._path._interpolation_steps
- else:
- interpolation_steps = 1
- xy = STEP_LOOKUP_MAP[self._drawstyle](*self._xy.T)
- self._path = Path(np.asarray(xy).T,
- _interpolation_steps=interpolation_steps)
- self._transformed_path = None
- self._invalidx = False
- self._invalidy = False
-
- def _transform_path(self, subslice=None):
- """
- Put a TransformedPath instance at self._transformed_path;
- all invalidation of the transform is then handled by the
- TransformedPath instance.
- """
- # Masked arrays are now handled by the Path class itself
- if subslice is not None:
- xy = STEP_LOOKUP_MAP[self._drawstyle](*self._xy[subslice, :].T)
- _path = Path(np.asarray(xy).T,
- _interpolation_steps=self._path._interpolation_steps)
- else:
- _path = self._path
- self._transformed_path = TransformedPath(_path, self.get_transform())
-
- def _get_transformed_path(self):
- """Return this line's `~matplotlib.transforms.TransformedPath`."""
- if self._transformed_path is None:
- self._transform_path()
- return self._transformed_path
-
- def set_transform(self, t):
- # docstring inherited
- self._invalidx = True
- self._invalidy = True
- super().set_transform(t)
-
- @allow_rasterization
- def draw(self, renderer):
- # docstring inherited
-
- if not self.get_visible():
- return
-
- if self._invalidy or self._invalidx:
- self.recache()
- self.ind_offset = 0 # Needed for contains() method.
- if self._subslice and self.axes:
- x0, x1 = self.axes.get_xbound()
- i0 = self._x_filled.searchsorted(x0, 'left')
- i1 = self._x_filled.searchsorted(x1, 'right')
- subslice = slice(max(i0 - 1, 0), i1 + 1)
- self.ind_offset = subslice.start
- self._transform_path(subslice)
- else:
- subslice = None
-
- if self.get_path_effects():
- from matplotlib.patheffects import PathEffectRenderer
- renderer = PathEffectRenderer(self.get_path_effects(), renderer)
-
- renderer.open_group('line2d', self.get_gid())
- if self._lineStyles[self._linestyle] != '_draw_nothing':
- tpath, affine = (self._get_transformed_path()
- .get_transformed_path_and_affine())
- if len(tpath.vertices):
- gc = renderer.new_gc()
- self._set_gc_clip(gc)
- gc.set_url(self.get_url())
-
- gc.set_antialiased(self._antialiased)
- gc.set_linewidth(self._linewidth)
-
- if self.is_dashed():
- cap = self._dashcapstyle
- join = self._dashjoinstyle
- else:
- cap = self._solidcapstyle
- join = self._solidjoinstyle
- gc.set_joinstyle(join)
- gc.set_capstyle(cap)
- gc.set_snap(self.get_snap())
- if self.get_sketch_params() is not None:
- gc.set_sketch_params(*self.get_sketch_params())
-
- # We first draw a path within the gaps if needed.
- if self.is_dashed() and self._gapcolor is not None:
- lc_rgba = mcolors.to_rgba(self._gapcolor, self._alpha)
- gc.set_foreground(lc_rgba, isRGBA=True)
-
- offset_gaps, gaps = _get_inverse_dash_pattern(
- *self._dash_pattern)
-
- gc.set_dashes(offset_gaps, gaps)
- renderer.draw_path(gc, tpath, affine.frozen())
-
- lc_rgba = mcolors.to_rgba(self._color, self._alpha)
- gc.set_foreground(lc_rgba, isRGBA=True)
-
- gc.set_dashes(*self._dash_pattern)
- renderer.draw_path(gc, tpath, affine.frozen())
- gc.restore()
-
- if self._marker and self._markersize > 0:
- gc = renderer.new_gc()
- self._set_gc_clip(gc)
- gc.set_url(self.get_url())
- gc.set_linewidth(self._markeredgewidth)
- gc.set_antialiased(self._antialiased)
-
- ec_rgba = mcolors.to_rgba(
- self.get_markeredgecolor(), self._alpha)
- fc_rgba = mcolors.to_rgba(
- self._get_markerfacecolor(), self._alpha)
- fcalt_rgba = mcolors.to_rgba(
- self._get_markerfacecolor(alt=True), self._alpha)
- # If the edgecolor is "auto", it is set according to the *line*
- # color but inherits the alpha value of the *face* color, if any.
- if (cbook._str_equal(self._markeredgecolor, "auto")
- and not cbook._str_lower_equal(
- self.get_markerfacecolor(), "none")):
- ec_rgba = ec_rgba[:3] + (fc_rgba[3],)
- gc.set_foreground(ec_rgba, isRGBA=True)
- if self.get_sketch_params() is not None:
- scale, length, randomness = self.get_sketch_params()
- gc.set_sketch_params(scale/2, length/2, 2*randomness)
-
- marker = self._marker
-
- # Markers *must* be drawn ignoring the drawstyle (but don't pay the
- # recaching if drawstyle is already "default").
- if self.get_drawstyle() != "default":
- with cbook._setattr_cm(
- self, _drawstyle="default", _transformed_path=None):
- self.recache()
- self._transform_path(subslice)
- tpath, affine = (self._get_transformed_path()
- .get_transformed_points_and_affine())
- else:
- tpath, affine = (self._get_transformed_path()
- .get_transformed_points_and_affine())
-
- if len(tpath.vertices):
- # subsample the markers if markevery is not None
- markevery = self.get_markevery()
- if markevery is not None:
- subsampled = _mark_every_path(
- markevery, tpath, affine, self.axes)
- else:
- subsampled = tpath
-
- snap = marker.get_snap_threshold()
- if isinstance(snap, Real):
- snap = renderer.points_to_pixels(self._markersize) >= snap
- gc.set_snap(snap)
- gc.set_joinstyle(marker.get_joinstyle())
- gc.set_capstyle(marker.get_capstyle())
- marker_path = marker.get_path()
- marker_trans = marker.get_transform()
- w = renderer.points_to_pixels(self._markersize)
-
- if cbook._str_equal(marker.get_marker(), ","):
- gc.set_linewidth(0)
- else:
- # Don't scale for pixels, and don't stroke them
- marker_trans = marker_trans.scale(w)
- renderer.draw_markers(gc, marker_path, marker_trans,
- subsampled, affine.frozen(),
- fc_rgba)
-
- alt_marker_path = marker.get_alt_path()
- if alt_marker_path:
- alt_marker_trans = marker.get_alt_transform()
- alt_marker_trans = alt_marker_trans.scale(w)
- renderer.draw_markers(
- gc, alt_marker_path, alt_marker_trans, subsampled,
- affine.frozen(), fcalt_rgba)
-
- gc.restore()
-
- renderer.close_group('line2d')
- self.stale = False
-
- def get_antialiased(self):
- """Return whether antialiased rendering is used."""
- return self._antialiased
-
- def get_color(self):
- """
- Return the line color.
-
- See also `~.Line2D.set_color`.
- """
- return self._color
-
- def get_drawstyle(self):
- """
- Return the drawstyle.
-
- See also `~.Line2D.set_drawstyle`.
- """
- return self._drawstyle
-
- def get_gapcolor(self):
- """
- Return the line gapcolor.
-
- See also `~.Line2D.set_gapcolor`.
- """
- return self._gapcolor
-
- def get_linestyle(self):
- """
- Return the linestyle.
-
- See also `~.Line2D.set_linestyle`.
- """
- return self._linestyle
-
- def get_linewidth(self):
- """
- Return the linewidth in points.
-
- See also `~.Line2D.set_linewidth`.
- """
- return self._linewidth
-
- def get_marker(self):
- """
- Return the line marker.
-
- See also `~.Line2D.set_marker`.
- """
- return self._marker.get_marker()
-
- def get_markeredgecolor(self):
- """
- Return the marker edge color.
-
- See also `~.Line2D.set_markeredgecolor`.
- """
- mec = self._markeredgecolor
- if cbook._str_equal(mec, 'auto'):
- if mpl.rcParams['_internal.classic_mode']:
- if self._marker.get_marker() in ('.', ','):
- return self._color
- if (self._marker.is_filled()
- and self._marker.get_fillstyle() != 'none'):
- return 'k' # Bad hard-wired default...
- return self._color
- else:
- return mec
-
- def get_markeredgewidth(self):
- """
- Return the marker edge width in points.
-
- See also `~.Line2D.set_markeredgewidth`.
- """
- return self._markeredgewidth
-
- def _get_markerfacecolor(self, alt=False):
- if self._marker.get_fillstyle() == 'none':
- return 'none'
- fc = self._markerfacecoloralt if alt else self._markerfacecolor
- if cbook._str_lower_equal(fc, 'auto'):
- return self._color
- else:
- return fc
-
- def get_markerfacecolor(self):
- """
- Return the marker face color.
-
- See also `~.Line2D.set_markerfacecolor`.
- """
- return self._get_markerfacecolor(alt=False)
-
- def get_markerfacecoloralt(self):
- """
- Return the alternate marker face color.
-
- See also `~.Line2D.set_markerfacecoloralt`.
- """
- return self._get_markerfacecolor(alt=True)
-
- def get_markersize(self):
- """
- Return the marker size in points.
-
- See also `~.Line2D.set_markersize`.
- """
- return self._markersize
-
- def get_data(self, orig=True):
- """
- Return the line data as an ``(xdata, ydata)`` pair.
-
- If *orig* is *True*, return the original data.
- """
- return self.get_xdata(orig=orig), self.get_ydata(orig=orig)
-
- def get_xdata(self, orig=True):
- """
- Return the xdata.
-
- If *orig* is *True*, return the original data, else the
- processed data.
- """
- if orig:
- return self._xorig
- if self._invalidx:
- self.recache()
- return self._x
-
- def get_ydata(self, orig=True):
- """
- Return the ydata.
-
- If *orig* is *True*, return the original data, else the
- processed data.
- """
- if orig:
- return self._yorig
- if self._invalidy:
- self.recache()
- return self._y
-
- def get_path(self):
- """Return the `~matplotlib.path.Path` associated with this line."""
- if self._invalidy or self._invalidx:
- self.recache()
- return self._path
-
- def get_xydata(self):
- """Return the *xy* data as a (N, 2) array."""
- if self._invalidy or self._invalidx:
- self.recache()
- return self._xy
-
- def set_antialiased(self, b):
- """
- Set whether to use antialiased rendering.
-
- Parameters
- ----------
- b : bool
- """
- if self._antialiased != b:
- self.stale = True
- self._antialiased = b
-
- def set_color(self, color):
- """
- Set the color of the line.
-
- Parameters
- ----------
- color : color
- """
- mcolors._check_color_like(color=color)
- self._color = color
- self.stale = True
-
- def set_drawstyle(self, drawstyle):
- """
- Set the drawstyle of the plot.
-
- The drawstyle determines how the points are connected.
-
- Parameters
- ----------
- drawstyle : {'default', 'steps', 'steps-pre', 'steps-mid', \
-'steps-post'}, default: 'default'
- For 'default', the points are connected with straight lines.
-
- The steps variants connect the points with step-like lines,
- i.e. horizontal lines with vertical steps. They differ in the
- location of the step:
-
- - 'steps-pre': The step is at the beginning of the line segment,
- i.e. the line will be at the y-value of point to the right.
- - 'steps-mid': The step is halfway between the points.
- - 'steps-post: The step is at the end of the line segment,
- i.e. the line will be at the y-value of the point to the left.
- - 'steps' is equal to 'steps-pre' and is maintained for
- backward-compatibility.
-
- For examples see :doc:`/gallery/lines_bars_and_markers/step_demo`.
- """
- if drawstyle is None:
- drawstyle = 'default'
- _api.check_in_list(self.drawStyles, drawstyle=drawstyle)
- if self._drawstyle != drawstyle:
- self.stale = True
- # invalidate to trigger a recache of the path
- self._invalidx = True
- self._drawstyle = drawstyle
-
- def set_gapcolor(self, gapcolor):
- """
- Set a color to fill the gaps in the dashed line style.
-
- .. note::
-
- Striped lines are created by drawing two interleaved dashed lines.
- There can be overlaps between those two, which may result in
- artifacts when using transparency.
-
- This functionality is experimental and may change.
-
- Parameters
- ----------
- gapcolor : color or None
- The color with which to fill the gaps. If None, the gaps are
- unfilled.
- """
- if gapcolor is not None:
- mcolors._check_color_like(color=gapcolor)
- self._gapcolor = gapcolor
- self.stale = True
-
- def set_linewidth(self, w):
- """
- Set the line width in points.
-
- Parameters
- ----------
- w : float
- Line width, in points.
- """
- w = float(w)
- if self._linewidth != w:
- self.stale = True
- self._linewidth = w
- self._dash_pattern = _scale_dashes(*self._unscaled_dash_pattern, w)
-
- def set_linestyle(self, ls):
- """
- Set the linestyle of the line.
-
- Parameters
- ----------
- ls : {'-', '--', '-.', ':', '', (offset, on-off-seq), ...}
- Possible values:
-
- - A string:
-
- ========================================== =================
- linestyle description
- ========================================== =================
- ``'-'`` or ``'solid'`` solid line
- ``'--'`` or ``'dashed'`` dashed line
- ``'-.'`` or ``'dashdot'`` dash-dotted line
- ``':'`` or ``'dotted'`` dotted line
- ``'none'``, ``'None'``, ``' '``, or ``''`` draw nothing
- ========================================== =================
-
- - Alternatively a dash tuple of the following form can be
- provided::
-
- (offset, onoffseq)
-
- where ``onoffseq`` is an even length tuple of on and off ink
- in points. See also :meth:`set_dashes`.
-
- For examples see :doc:`/gallery/lines_bars_and_markers/linestyles`.
- """
- if isinstance(ls, str):
- if ls in [' ', '', 'none']:
- ls = 'None'
- _api.check_in_list([*self._lineStyles, *ls_mapper_r], ls=ls)
- if ls not in self._lineStyles:
- ls = ls_mapper_r[ls]
- self._linestyle = ls
- else:
- self._linestyle = '--'
- self._unscaled_dash_pattern = _get_dash_pattern(ls)
- self._dash_pattern = _scale_dashes(
- *self._unscaled_dash_pattern, self._linewidth)
- self.stale = True
-
- @_docstring.interpd
- def set_marker(self, marker):
- """
- Set the line marker.
-
- Parameters
- ----------
- marker : marker style string, `~.path.Path` or `~.markers.MarkerStyle`
- See `~matplotlib.markers` for full description of possible
- arguments.
- """
- self._marker = MarkerStyle(marker, self._marker.get_fillstyle())
- self.stale = True
-
- def _set_markercolor(self, name, has_rcdefault, val):
- if val is None:
- val = mpl.rcParams[f"lines.{name}"] if has_rcdefault else "auto"
- attr = f"_{name}"
- current = getattr(self, attr)
- if current is None:
- self.stale = True
- else:
- neq = current != val
- # Much faster than `np.any(current != val)` if no arrays are used.
- if neq.any() if isinstance(neq, np.ndarray) else neq:
- self.stale = True
- setattr(self, attr, val)
-
- def set_markeredgecolor(self, ec):
- """
- Set the marker edge color.
-
- Parameters
- ----------
- ec : color
- """
- self._set_markercolor("markeredgecolor", True, ec)
-
- def set_markerfacecolor(self, fc):
- """
- Set the marker face color.
-
- Parameters
- ----------
- fc : color
- """
- self._set_markercolor("markerfacecolor", True, fc)
-
- def set_markerfacecoloralt(self, fc):
- """
- Set the alternate marker face color.
-
- Parameters
- ----------
- fc : color
- """
- self._set_markercolor("markerfacecoloralt", False, fc)
-
- def set_markeredgewidth(self, ew):
- """
- Set the marker edge width in points.
-
- Parameters
- ----------
- ew : float
- Marker edge width, in points.
- """
- if ew is None:
- ew = mpl.rcParams['lines.markeredgewidth']
- if self._markeredgewidth != ew:
- self.stale = True
- self._markeredgewidth = ew
-
- def set_markersize(self, sz):
- """
- Set the marker size in points.
-
- Parameters
- ----------
- sz : float
- Marker size, in points.
- """
- sz = float(sz)
- if self._markersize != sz:
- self.stale = True
- self._markersize = sz
-
- def set_xdata(self, x):
- """
- Set the data array for x.
-
- Parameters
- ----------
- x : 1D array
- """
- if not np.iterable(x):
- # When deprecation cycle is completed
- # raise RuntimeError('x must be a sequence')
- _api.warn_deprecated(
- since="3.7",
- message="Setting data with a non sequence type "
- "is deprecated since %(since)s and will be "
- "remove %(removal)s")
- x = [x, ]
- self._xorig = copy.copy(x)
- self._invalidx = True
- self.stale = True
-
- def set_ydata(self, y):
- """
- Set the data array for y.
-
- Parameters
- ----------
- y : 1D array
- """
- if not np.iterable(y):
- # When deprecation cycle is completed
- # raise RuntimeError('y must be a sequence')
- _api.warn_deprecated(
- since="3.7",
- message="Setting data with a non sequence type "
- "is deprecated since %(since)s and will be "
- "remove %(removal)s")
- y = [y, ]
- self._yorig = copy.copy(y)
- self._invalidy = True
- self.stale = True
-
- def set_dashes(self, seq):
- """
- Set the dash sequence.
-
- The dash sequence is a sequence of floats of even length describing
- the length of dashes and spaces in points.
-
- For example, (5, 2, 1, 2) describes a sequence of 5 point and 1 point
- dashes separated by 2 point spaces.
-
- See also `~.Line2D.set_gapcolor`, which allows those spaces to be
- filled with a color.
-
- Parameters
- ----------
- seq : sequence of floats (on/off ink in points) or (None, None)
- If *seq* is empty or ``(None, None)``, the linestyle will be set
- to solid.
- """
- if seq == (None, None) or len(seq) == 0:
- self.set_linestyle('-')
- else:
- self.set_linestyle((0, seq))
-
- def update_from(self, other):
- """Copy properties from *other* to self."""
- super().update_from(other)
- self._linestyle = other._linestyle
- self._linewidth = other._linewidth
- self._color = other._color
- self._gapcolor = other._gapcolor
- self._markersize = other._markersize
- self._markerfacecolor = other._markerfacecolor
- self._markerfacecoloralt = other._markerfacecoloralt
- self._markeredgecolor = other._markeredgecolor
- self._markeredgewidth = other._markeredgewidth
- self._unscaled_dash_pattern = other._unscaled_dash_pattern
- self._dash_pattern = other._dash_pattern
- self._dashcapstyle = other._dashcapstyle
- self._dashjoinstyle = other._dashjoinstyle
- self._solidcapstyle = other._solidcapstyle
- self._solidjoinstyle = other._solidjoinstyle
-
- self._linestyle = other._linestyle
- self._marker = MarkerStyle(marker=other._marker)
- self._drawstyle = other._drawstyle
-
- @_docstring.interpd
- def set_dash_joinstyle(self, s):
- """
- How to join segments of the line if it `~Line2D.is_dashed`.
-
- The default joinstyle is :rc:`lines.dash_joinstyle`.
-
- Parameters
- ----------
- s : `.JoinStyle` or %(JoinStyle)s
- """
- js = JoinStyle(s)
- if self._dashjoinstyle != js:
- self.stale = True
- self._dashjoinstyle = js
-
- @_docstring.interpd
- def set_solid_joinstyle(self, s):
- """
- How to join segments if the line is solid (not `~Line2D.is_dashed`).
-
- The default joinstyle is :rc:`lines.solid_joinstyle`.
-
- Parameters
- ----------
- s : `.JoinStyle` or %(JoinStyle)s
- """
- js = JoinStyle(s)
- if self._solidjoinstyle != js:
- self.stale = True
- self._solidjoinstyle = js
-
- def get_dash_joinstyle(self):
- """
- Return the `.JoinStyle` for dashed lines.
-
- See also `~.Line2D.set_dash_joinstyle`.
- """
- return self._dashjoinstyle.name
-
- def get_solid_joinstyle(self):
- """
- Return the `.JoinStyle` for solid lines.
-
- See also `~.Line2D.set_solid_joinstyle`.
- """
- return self._solidjoinstyle.name
-
- @_docstring.interpd
- def set_dash_capstyle(self, s):
- """
- How to draw the end caps if the line is `~Line2D.is_dashed`.
-
- The default capstyle is :rc:`lines.dash_capstyle`.
-
- Parameters
- ----------
- s : `.CapStyle` or %(CapStyle)s
- """
- cs = CapStyle(s)
- if self._dashcapstyle != cs:
- self.stale = True
- self._dashcapstyle = cs
-
- @_docstring.interpd
- def set_solid_capstyle(self, s):
- """
- How to draw the end caps if the line is solid (not `~Line2D.is_dashed`)
-
- The default capstyle is :rc:`lines.solid_capstyle`.
-
- Parameters
- ----------
- s : `.CapStyle` or %(CapStyle)s
- """
- cs = CapStyle(s)
- if self._solidcapstyle != cs:
- self.stale = True
- self._solidcapstyle = cs
-
- def get_dash_capstyle(self):
- """
- Return the `.CapStyle` for dashed lines.
-
- See also `~.Line2D.set_dash_capstyle`.
- """
- return self._dashcapstyle.name
-
- def get_solid_capstyle(self):
- """
- Return the `.CapStyle` for solid lines.
-
- See also `~.Line2D.set_solid_capstyle`.
- """
- return self._solidcapstyle.name
-
- def is_dashed(self):
- """
- Return whether line has a dashed linestyle.
-
- A custom linestyle is assumed to be dashed, we do not inspect the
- ``onoffseq`` directly.
-
- See also `~.Line2D.set_linestyle`.
- """
- return self._linestyle in ('--', '-.', ':')
-
-
-class AxLine(Line2D):
- """
- A helper class that implements `~.Axes.axline`, by recomputing the artist
- transform at draw time.
- """
-
- def __init__(self, xy1, xy2, slope, **kwargs):
- """
- Parameters
- ----------
- xy1 : (float, float)
- The first set of (x, y) coordinates for the line to pass through.
- xy2 : (float, float) or None
- The second set of (x, y) coordinates for the line to pass through.
- Either *xy2* or *slope* has to be given.
- slope : float or None
- The slope of the line. Either *xy2* or *slope* has to be given.
- """
- super().__init__([0, 1], [0, 1], **kwargs)
-
- if (xy2 is None and slope is None or
- xy2 is not None and slope is not None):
- raise TypeError(
- "Exactly one of 'xy2' and 'slope' must be given")
-
- self._slope = slope
- self._xy1 = xy1
- self._xy2 = xy2
-
- def get_transform(self):
- ax = self.axes
- points_transform = self._transform - ax.transData + ax.transScale
-
- if self._xy2 is not None:
- # two points were given
- (x1, y1), (x2, y2) = \
- points_transform.transform([self._xy1, self._xy2])
- dx = x2 - x1
- dy = y2 - y1
- if np.allclose(x1, x2):
- if np.allclose(y1, y2):
- raise ValueError(
- f"Cannot draw a line through two identical points "
- f"(x={(x1, x2)}, y={(y1, y2)})")
- slope = np.inf
- else:
- slope = dy / dx
- else:
- # one point and a slope were given
- x1, y1 = points_transform.transform(self._xy1)
- slope = self._slope
- (vxlo, vylo), (vxhi, vyhi) = ax.transScale.transform(ax.viewLim)
- # General case: find intersections with view limits in either
- # direction, and draw between the middle two points.
- if np.isclose(slope, 0):
- start = vxlo, y1
- stop = vxhi, y1
- elif np.isinf(slope):
- start = x1, vylo
- stop = x1, vyhi
- else:
- _, start, stop, _ = sorted([
- (vxlo, y1 + (vxlo - x1) * slope),
- (vxhi, y1 + (vxhi - x1) * slope),
- (x1 + (vylo - y1) / slope, vylo),
- (x1 + (vyhi - y1) / slope, vyhi),
- ])
- return (BboxTransformTo(Bbox([start, stop]))
- + ax.transLimits + ax.transAxes)
-
- def draw(self, renderer):
- self._transformed_path = None # Force regen.
- super().draw(renderer)
-
- def get_xy1(self):
- """
- Return the *xy1* value of the line.
- """
- return self._xy1
-
- def get_xy2(self):
- """
- Return the *xy2* value of the line.
- """
- return self._xy2
-
- def get_slope(self):
- """
- Return the *slope* value of the line.
- """
- return self._slope
-
- def set_xy1(self, x, y):
- """
- Set the *xy1* value of the line.
-
- Parameters
- ----------
- x, y : float
- Points for the line to pass through.
- """
- self._xy1 = x, y
-
- def set_xy2(self, x, y):
- """
- Set the *xy2* value of the line.
-
- Parameters
- ----------
- x, y : float
- Points for the line to pass through.
- """
- if self._slope is None:
- self._xy2 = x, y
- else:
- raise ValueError("Cannot set an 'xy2' value while 'slope' is set;"
- " they differ but their functionalities overlap")
-
- def set_slope(self, slope):
- """
- Set the *slope* value of the line.
-
- Parameters
- ----------
- slope : float
- The slope of the line.
- """
- if self._xy2 is None:
- self._slope = slope
- else:
- raise ValueError("Cannot set a 'slope' value while 'xy2' is set;"
- " they differ but their functionalities overlap")
-
-
-class VertexSelector:
- """
- Manage the callbacks to maintain a list of selected vertices for `.Line2D`.
- Derived classes should override the `process_selected` method to do
- something with the picks.
-
- Here is an example which highlights the selected verts with red circles::
-
- import numpy as np
- import matplotlib.pyplot as plt
- import matplotlib.lines as lines
-
- class HighlightSelected(lines.VertexSelector):
- def __init__(self, line, fmt='ro', **kwargs):
- super().__init__(line)
- self.markers, = self.axes.plot([], [], fmt, **kwargs)
-
- def process_selected(self, ind, xs, ys):
- self.markers.set_data(xs, ys)
- self.canvas.draw()
-
- fig, ax = plt.subplots()
- x, y = np.random.rand(2, 30)
- line, = ax.plot(x, y, 'bs-', picker=5)
-
- selector = HighlightSelected(line)
- plt.show()
- """
-
- def __init__(self, line):
- """
- Parameters
- ----------
- line : `~matplotlib.lines.Line2D`
- The line must already have been added to an `~.axes.Axes` and must
- have its picker property set.
- """
- if line.axes is None:
- raise RuntimeError('You must first add the line to the Axes')
- if line.get_picker() is None:
- raise RuntimeError('You must first set the picker property '
- 'of the line')
- self.axes = line.axes
- self.line = line
- self.cid = self.canvas.callbacks._connect_picklable(
- 'pick_event', self.onpick)
- self.ind = set()
-
- canvas = property(lambda self: self.axes.figure.canvas)
-
- def process_selected(self, ind, xs, ys):
- """
- Default "do nothing" implementation of the `process_selected` method.
-
- Parameters
- ----------
- ind : list of int
- The indices of the selected vertices.
- xs, ys : array-like
- The coordinates of the selected vertices.
- """
- pass
-
- def onpick(self, event):
- """When the line is picked, update the set of selected indices."""
- if event.artist is not self.line:
- return
- self.ind ^= set(event.ind)
- ind = sorted(self.ind)
- xdata, ydata = self.line.get_data()
- self.process_selected(ind, xdata[ind], ydata[ind])
-
-
-lineStyles = Line2D._lineStyles
-lineMarkers = MarkerStyle.markers
-drawStyles = Line2D.drawStyles
-fillStyles = MarkerStyle.fillstyles
diff --git a/contrib/python/matplotlib/py3/matplotlib/lines.pyi b/contrib/python/matplotlib/py3/matplotlib/lines.pyi
deleted file mode 100644
index c91e457e33..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/lines.pyi
+++ /dev/null
@@ -1,153 +0,0 @@
-from .artist import Artist
-from .axes import Axes
-from .backend_bases import MouseEvent, FigureCanvasBase
-from .path import Path
-from .transforms import Bbox, Transform
-
-from collections.abc import Callable, Sequence
-from typing import Any, Literal, overload
-from .typing import (
- ColorType,
- DrawStyleType,
- FillStyleType,
- LineStyleType,
- CapStyleType,
- JoinStyleType,
- MarkEveryType,
- MarkerType,
-)
-from numpy.typing import ArrayLike
-
-def segment_hits(
- cx: ArrayLike, cy: ArrayLike, x: ArrayLike, y: ArrayLike, radius: ArrayLike
-) -> ArrayLike: ...
-
-class Line2D(Artist):
- lineStyles: dict[str, str]
- drawStyles: dict[str, str]
- drawStyleKeys: list[str]
- markers: dict[str | int, str]
- filled_markers: tuple[str, ...]
- fillStyles: tuple[str, ...]
- zorder: float
- ind_offset: float
- def __init__(
- self,
- xdata: ArrayLike,
- ydata: ArrayLike,
- *,
- linewidth: float | None = ...,
- linestyle: LineStyleType | None = ...,
- color: ColorType | None = ...,
- gapcolor: ColorType | None = ...,
- marker: MarkerType | None = ...,
- markersize: float | None = ...,
- markeredgewidth: float | None = ...,
- markeredgecolor: ColorType | None = ...,
- markerfacecolor: ColorType | None = ...,
- markerfacecoloralt: ColorType = ...,
- fillstyle: FillStyleType | None = ...,
- antialiased: bool | None = ...,
- dash_capstyle: CapStyleType | None = ...,
- solid_capstyle: CapStyleType | None = ...,
- dash_joinstyle: JoinStyleType | None = ...,
- solid_joinstyle: JoinStyleType | None = ...,
- pickradius: float = ...,
- drawstyle: DrawStyleType | None = ...,
- markevery: MarkEveryType | None = ...,
- **kwargs
- ) -> None: ...
- def contains(self, mouseevent: MouseEvent) -> tuple[bool, dict]: ...
- def get_pickradius(self) -> float: ...
- def set_pickradius(self, pickradius: float) -> None: ...
- pickradius: float
- def get_fillstyle(self) -> FillStyleType: ...
- stale: bool
- def set_fillstyle(self, fs: FillStyleType) -> None: ...
- def set_markevery(self, every: MarkEveryType) -> None: ...
- def get_markevery(self) -> MarkEveryType: ...
- def set_picker(
- self, p: None | bool | float | Callable[[Artist, MouseEvent], tuple[bool, dict]]
- ) -> None: ...
- def get_bbox(self) -> Bbox: ...
- @overload
- def set_data(self, args: ArrayLike) -> None: ...
- @overload
- def set_data(self, x: ArrayLike, y: ArrayLike) -> None: ...
- def recache_always(self) -> None: ...
- def recache(self, always: bool = ...) -> None: ...
- def get_antialiased(self) -> bool: ...
- def get_color(self) -> ColorType: ...
- def get_drawstyle(self) -> DrawStyleType: ...
- def get_gapcolor(self) -> ColorType: ...
- def get_linestyle(self) -> LineStyleType: ...
- def get_linewidth(self) -> float: ...
- def get_marker(self) -> MarkerType: ...
- def get_markeredgecolor(self) -> ColorType: ...
- def get_markeredgewidth(self) -> float: ...
- def get_markerfacecolor(self) -> ColorType: ...
- def get_markerfacecoloralt(self) -> ColorType: ...
- def get_markersize(self) -> float: ...
- def get_data(self, orig: bool = ...) -> tuple[ArrayLike, ArrayLike]: ...
- def get_xdata(self, orig: bool = ...) -> ArrayLike: ...
- def get_ydata(self, orig: bool = ...) -> ArrayLike: ...
- def get_path(self) -> Path: ...
- def get_xydata(self) -> ArrayLike: ...
- def set_antialiased(self, b: bool) -> None: ...
- def set_color(self, color: ColorType) -> None: ...
- def set_drawstyle(self, drawstyle: DrawStyleType | None) -> None: ...
- def set_gapcolor(self, gapcolor: ColorType | None) -> None: ...
- def set_linewidth(self, w: float) -> None: ...
- def set_linestyle(self, ls: LineStyleType) -> None: ...
- def set_marker(self, marker: MarkerType) -> None: ...
- def set_markeredgecolor(self, ec: ColorType | None) -> None: ...
- def set_markerfacecolor(self, fc: ColorType | None) -> None: ...
- def set_markerfacecoloralt(self, fc: ColorType | None) -> None: ...
- def set_markeredgewidth(self, ew: float | None) -> None: ...
- def set_markersize(self, sz: float) -> None: ...
- def set_xdata(self, x: ArrayLike) -> None: ...
- def set_ydata(self, y: ArrayLike) -> None: ...
- def set_dashes(self, seq: Sequence[float] | tuple[None, None]) -> None: ...
- def update_from(self, other: Artist) -> None: ...
- def set_dash_joinstyle(self, s: JoinStyleType) -> None: ...
- def set_solid_joinstyle(self, s: JoinStyleType) -> None: ...
- def get_dash_joinstyle(self) -> Literal["miter", "round", "bevel"]: ...
- def get_solid_joinstyle(self) -> Literal["miter", "round", "bevel"]: ...
- def set_dash_capstyle(self, s: CapStyleType) -> None: ...
- def set_solid_capstyle(self, s: CapStyleType) -> None: ...
- def get_dash_capstyle(self) -> Literal["butt", "projecting", "round"]: ...
- def get_solid_capstyle(self) -> Literal["butt", "projecting", "round"]: ...
- def is_dashed(self) -> bool: ...
-
-class AxLine(Line2D):
- def __init__(
- self,
- xy1: tuple[float, float],
- xy2: tuple[float, float] | None,
- slope: float | None,
- **kwargs
- ) -> None: ...
- def get_xy1(self) -> tuple[float, float] | None: ...
- def get_xy2(self) -> tuple[float, float] | None: ...
- def get_slope(self) -> float: ...
- def set_xy1(self, x: float, y: float) -> None: ...
- def set_xy2(self, x: float, y: float) -> None: ...
- def set_slope(self, slope: float) -> None: ...
-
-class VertexSelector:
- axes: Axes
- line: Line2D
- cid: int
- ind: set[int]
- def __init__(self, line: Line2D) -> None: ...
- @property
- def canvas(self) -> FigureCanvasBase: ...
- def process_selected(
- self, ind: Sequence[int], xs: ArrayLike, ys: ArrayLike
- ) -> None: ...
- def onpick(self, event: Any) -> None: ...
-
-lineStyles: dict[str, str]
-lineMarkers: dict[str | int, str]
-drawStyles: dict[str, str]
-fillStyles: tuple[FillStyleType, ...]
diff --git a/contrib/python/matplotlib/py3/matplotlib/markers.py b/contrib/python/matplotlib/py3/matplotlib/markers.py
deleted file mode 100644
index e7096e66bc..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/markers.py
+++ /dev/null
@@ -1,917 +0,0 @@
-r"""
-Functions to handle markers; used by the marker functionality of
-`~matplotlib.axes.Axes.plot`, `~matplotlib.axes.Axes.scatter`, and
-`~matplotlib.axes.Axes.errorbar`.
-
-All possible markers are defined here:
-
-============================== ====== =========================================
-marker symbol description
-============================== ====== =========================================
-``"."`` |m00| point
-``","`` |m01| pixel
-``"o"`` |m02| circle
-``"v"`` |m03| triangle_down
-``"^"`` |m04| triangle_up
-``"<"`` |m05| triangle_left
-``">"`` |m06| triangle_right
-``"1"`` |m07| tri_down
-``"2"`` |m08| tri_up
-``"3"`` |m09| tri_left
-``"4"`` |m10| tri_right
-``"8"`` |m11| octagon
-``"s"`` |m12| square
-``"p"`` |m13| pentagon
-``"P"`` |m23| plus (filled)
-``"*"`` |m14| star
-``"h"`` |m15| hexagon1
-``"H"`` |m16| hexagon2
-``"+"`` |m17| plus
-``"x"`` |m18| x
-``"X"`` |m24| x (filled)
-``"D"`` |m19| diamond
-``"d"`` |m20| thin_diamond
-``"|"`` |m21| vline
-``"_"`` |m22| hline
-``0`` (``TICKLEFT``) |m25| tickleft
-``1`` (``TICKRIGHT``) |m26| tickright
-``2`` (``TICKUP``) |m27| tickup
-``3`` (``TICKDOWN``) |m28| tickdown
-``4`` (``CARETLEFT``) |m29| caretleft
-``5`` (``CARETRIGHT``) |m30| caretright
-``6`` (``CARETUP``) |m31| caretup
-``7`` (``CARETDOWN``) |m32| caretdown
-``8`` (``CARETLEFTBASE``) |m33| caretleft (centered at base)
-``9`` (``CARETRIGHTBASE``) |m34| caretright (centered at base)
-``10`` (``CARETUPBASE``) |m35| caretup (centered at base)
-``11`` (``CARETDOWNBASE``) |m36| caretdown (centered at base)
-``"none"`` or ``"None"`` nothing
-``" "`` or ``""`` nothing
-``'$...$'`` |m37| Render the string using mathtext.
- E.g ``"$f$"`` for marker showing the
- letter ``f``.
-``verts`` A list of (x, y) pairs used for Path
- vertices. The center of the marker is
- located at (0, 0) and the size is
- normalized, such that the created path
- is encapsulated inside the unit cell.
-path A `~matplotlib.path.Path` instance.
-``(numsides, 0, angle)`` A regular polygon with ``numsides``
- sides, rotated by ``angle``.
-``(numsides, 1, angle)`` A star-like symbol with ``numsides``
- sides, rotated by ``angle``.
-``(numsides, 2, angle)`` An asterisk with ``numsides`` sides,
- rotated by ``angle``.
-============================== ====== =========================================
-
-As a deprecated feature, ``None`` also means 'nothing' when directly
-constructing a `.MarkerStyle`, but note that there are other contexts where
-``marker=None`` instead means "the default marker" (e.g. :rc:`scatter.marker`
-for `.Axes.scatter`).
-
-Note that special symbols can be defined via the
-:ref:`STIX math font <mathtext>`,
-e.g. ``"$\u266B$"``. For an overview over the STIX font symbols refer to the
-`STIX font table <http://www.stixfonts.org/allGlyphs.html>`_.
-Also see the :doc:`/gallery/text_labels_and_annotations/stix_fonts_demo`.
-
-Integer numbers from ``0`` to ``11`` create lines and triangles. Those are
-equally accessible via capitalized variables, like ``CARETDOWNBASE``.
-Hence the following are equivalent::
-
- plt.plot([1, 2, 3], marker=11)
- plt.plot([1, 2, 3], marker=matplotlib.markers.CARETDOWNBASE)
-
-Markers join and cap styles can be customized by creating a new instance of
-MarkerStyle.
-A MarkerStyle can also have a custom `~matplotlib.transforms.Transform`
-allowing it to be arbitrarily rotated or offset.
-
-Examples showing the use of markers:
-
-* :doc:`/gallery/lines_bars_and_markers/marker_reference`
-* :doc:`/gallery/lines_bars_and_markers/scatter_star_poly`
-* :doc:`/gallery/lines_bars_and_markers/multivariate_marker_plot`
-
-.. |m00| image:: /_static/markers/m00.png
-.. |m01| image:: /_static/markers/m01.png
-.. |m02| image:: /_static/markers/m02.png
-.. |m03| image:: /_static/markers/m03.png
-.. |m04| image:: /_static/markers/m04.png
-.. |m05| image:: /_static/markers/m05.png
-.. |m06| image:: /_static/markers/m06.png
-.. |m07| image:: /_static/markers/m07.png
-.. |m08| image:: /_static/markers/m08.png
-.. |m09| image:: /_static/markers/m09.png
-.. |m10| image:: /_static/markers/m10.png
-.. |m11| image:: /_static/markers/m11.png
-.. |m12| image:: /_static/markers/m12.png
-.. |m13| image:: /_static/markers/m13.png
-.. |m14| image:: /_static/markers/m14.png
-.. |m15| image:: /_static/markers/m15.png
-.. |m16| image:: /_static/markers/m16.png
-.. |m17| image:: /_static/markers/m17.png
-.. |m18| image:: /_static/markers/m18.png
-.. |m19| image:: /_static/markers/m19.png
-.. |m20| image:: /_static/markers/m20.png
-.. |m21| image:: /_static/markers/m21.png
-.. |m22| image:: /_static/markers/m22.png
-.. |m23| image:: /_static/markers/m23.png
-.. |m24| image:: /_static/markers/m24.png
-.. |m25| image:: /_static/markers/m25.png
-.. |m26| image:: /_static/markers/m26.png
-.. |m27| image:: /_static/markers/m27.png
-.. |m28| image:: /_static/markers/m28.png
-.. |m29| image:: /_static/markers/m29.png
-.. |m30| image:: /_static/markers/m30.png
-.. |m31| image:: /_static/markers/m31.png
-.. |m32| image:: /_static/markers/m32.png
-.. |m33| image:: /_static/markers/m33.png
-.. |m34| image:: /_static/markers/m34.png
-.. |m35| image:: /_static/markers/m35.png
-.. |m36| image:: /_static/markers/m36.png
-.. |m37| image:: /_static/markers/m37.png
-"""
-import copy
-
-from collections.abc import Sized
-
-import numpy as np
-
-import matplotlib as mpl
-from . import _api, cbook
-from .path import Path
-from .transforms import IdentityTransform, Affine2D
-from ._enums import JoinStyle, CapStyle
-
-# special-purpose marker identifiers:
-(TICKLEFT, TICKRIGHT, TICKUP, TICKDOWN,
- CARETLEFT, CARETRIGHT, CARETUP, CARETDOWN,
- CARETLEFTBASE, CARETRIGHTBASE, CARETUPBASE, CARETDOWNBASE) = range(12)
-
-_empty_path = Path(np.empty((0, 2)))
-
-
-class MarkerStyle:
- """
- A class representing marker types.
-
- Instances are immutable. If you need to change anything, create a new
- instance.
-
- Attributes
- ----------
- markers : dict
- All known markers.
- filled_markers : tuple
- All known filled markers. This is a subset of *markers*.
- fillstyles : tuple
- The supported fillstyles.
- """
-
- markers = {
- '.': 'point',
- ',': 'pixel',
- 'o': 'circle',
- 'v': 'triangle_down',
- '^': 'triangle_up',
- '<': 'triangle_left',
- '>': 'triangle_right',
- '1': 'tri_down',
- '2': 'tri_up',
- '3': 'tri_left',
- '4': 'tri_right',
- '8': 'octagon',
- 's': 'square',
- 'p': 'pentagon',
- '*': 'star',
- 'h': 'hexagon1',
- 'H': 'hexagon2',
- '+': 'plus',
- 'x': 'x',
- 'D': 'diamond',
- 'd': 'thin_diamond',
- '|': 'vline',
- '_': 'hline',
- 'P': 'plus_filled',
- 'X': 'x_filled',
- TICKLEFT: 'tickleft',
- TICKRIGHT: 'tickright',
- TICKUP: 'tickup',
- TICKDOWN: 'tickdown',
- CARETLEFT: 'caretleft',
- CARETRIGHT: 'caretright',
- CARETUP: 'caretup',
- CARETDOWN: 'caretdown',
- CARETLEFTBASE: 'caretleftbase',
- CARETRIGHTBASE: 'caretrightbase',
- CARETUPBASE: 'caretupbase',
- CARETDOWNBASE: 'caretdownbase',
- "None": 'nothing',
- "none": 'nothing',
- ' ': 'nothing',
- '': 'nothing'
- }
-
- # Just used for informational purposes. is_filled()
- # is calculated in the _set_* functions.
- filled_markers = (
- '.', 'o', 'v', '^', '<', '>', '8', 's', 'p', '*', 'h', 'H', 'D', 'd',
- 'P', 'X')
-
- fillstyles = ('full', 'left', 'right', 'bottom', 'top', 'none')
- _half_fillstyles = ('left', 'right', 'bottom', 'top')
-
- def __init__(self, marker,
- fillstyle=None, transform=None, capstyle=None, joinstyle=None):
- """
- Parameters
- ----------
- marker : str, array-like, Path, MarkerStyle, or None
- - Another instance of *MarkerStyle* copies the details of that
- ``marker``.
- - *None* means no marker. This is the deprecated default.
- - For other possible marker values, see the module docstring
- `matplotlib.markers`.
-
- fillstyle : str, default: :rc:`markers.fillstyle`
- One of 'full', 'left', 'right', 'bottom', 'top', 'none'.
-
- transform : transforms.Transform, default: None
- Transform that will be combined with the native transform of the
- marker.
-
- capstyle : `.CapStyle` or %(CapStyle)s, default: None
- Cap style that will override the default cap style of the marker.
-
- joinstyle : `.JoinStyle` or %(JoinStyle)s, default: None
- Join style that will override the default join style of the marker.
- """
- self._marker_function = None
- self._user_transform = transform
- self._user_capstyle = CapStyle(capstyle) if capstyle is not None else None
- self._user_joinstyle = JoinStyle(joinstyle) if joinstyle is not None else None
- self._set_fillstyle(fillstyle)
- self._set_marker(marker)
-
- def _recache(self):
- if self._marker_function is None:
- return
- self._path = _empty_path
- self._transform = IdentityTransform()
- self._alt_path = None
- self._alt_transform = None
- self._snap_threshold = None
- self._joinstyle = JoinStyle.round
- self._capstyle = self._user_capstyle or CapStyle.butt
- # Initial guess: Assume the marker is filled unless the fillstyle is
- # set to 'none'. The marker function will override this for unfilled
- # markers.
- self._filled = self._fillstyle != 'none'
- self._marker_function()
-
- def __bool__(self):
- return bool(len(self._path.vertices))
-
- def is_filled(self):
- return self._filled
-
- def get_fillstyle(self):
- return self._fillstyle
-
- def _set_fillstyle(self, fillstyle):
- """
- Set the fillstyle.
-
- Parameters
- ----------
- fillstyle : {'full', 'left', 'right', 'bottom', 'top', 'none'}
- The part of the marker surface that is colored with
- markerfacecolor.
- """
- if fillstyle is None:
- fillstyle = mpl.rcParams['markers.fillstyle']
- _api.check_in_list(self.fillstyles, fillstyle=fillstyle)
- self._fillstyle = fillstyle
-
- def get_joinstyle(self):
- return self._joinstyle.name
-
- def get_capstyle(self):
- return self._capstyle.name
-
- def get_marker(self):
- return self._marker
-
- def _set_marker(self, marker):
- """
- Set the marker.
-
- Parameters
- ----------
- marker : str, array-like, Path, MarkerStyle, or None, default: None
- - Another instance of *MarkerStyle* copies the details of that
- ``marker``.
- - *None* means no marker.
- - For other possible marker values see the module docstring
- `matplotlib.markers`.
- """
- if isinstance(marker, str) and cbook.is_math_text(marker):
- self._marker_function = self._set_mathtext_path
- elif isinstance(marker, (int, str)) and marker in self.markers:
- self._marker_function = getattr(self, '_set_' + self.markers[marker])
- elif (isinstance(marker, np.ndarray) and marker.ndim == 2 and
- marker.shape[1] == 2):
- self._marker_function = self._set_vertices
- elif isinstance(marker, Path):
- self._marker_function = self._set_path_marker
- elif (isinstance(marker, Sized) and len(marker) in (2, 3) and
- marker[1] in (0, 1, 2)):
- self._marker_function = self._set_tuple_marker
- elif isinstance(marker, MarkerStyle):
- self.__dict__ = copy.deepcopy(marker.__dict__)
- else:
- try:
- Path(marker)
- self._marker_function = self._set_vertices
- except ValueError as err:
- raise ValueError(
- f'Unrecognized marker style {marker!r}') from err
-
- if not isinstance(marker, MarkerStyle):
- self._marker = marker
- self._recache()
-
- def get_path(self):
- """
- Return a `.Path` for the primary part of the marker.
-
- For unfilled markers this is the whole marker, for filled markers,
- this is the area to be drawn with *markerfacecolor*.
- """
- return self._path
-
- def get_transform(self):
- """
- Return the transform to be applied to the `.Path` from
- `MarkerStyle.get_path()`.
- """
- if self._user_transform is None:
- return self._transform.frozen()
- else:
- return (self._transform + self._user_transform).frozen()
-
- def get_alt_path(self):
- """
- Return a `.Path` for the alternate part of the marker.
-
- For unfilled markers, this is *None*; for filled markers, this is the
- area to be drawn with *markerfacecoloralt*.
- """
- return self._alt_path
-
- def get_alt_transform(self):
- """
- Return the transform to be applied to the `.Path` from
- `MarkerStyle.get_alt_path()`.
- """
- if self._user_transform is None:
- return self._alt_transform.frozen()
- else:
- return (self._alt_transform + self._user_transform).frozen()
-
- def get_snap_threshold(self):
- return self._snap_threshold
-
- def get_user_transform(self):
- """Return user supplied part of marker transform."""
- if self._user_transform is not None:
- return self._user_transform.frozen()
-
- def transformed(self, transform: Affine2D):
- """
- Return a new version of this marker with the transform applied.
-
- Parameters
- ----------
- transform : `~matplotlib.transforms.Affine2D`, default: None
- Transform will be combined with current user supplied transform.
- """
- new_marker = MarkerStyle(self)
- if new_marker._user_transform is not None:
- new_marker._user_transform += transform
- else:
- new_marker._user_transform = transform
- return new_marker
-
- def rotated(self, *, deg=None, rad=None):
- """
- Return a new version of this marker rotated by specified angle.
-
- Parameters
- ----------
- deg : float, default: None
- Rotation angle in degrees.
-
- rad : float, default: None
- Rotation angle in radians.
-
- .. note:: You must specify exactly one of deg or rad.
- """
- if deg is None and rad is None:
- raise ValueError('One of deg or rad is required')
- if deg is not None and rad is not None:
- raise ValueError('Only one of deg and rad can be supplied')
- new_marker = MarkerStyle(self)
- if new_marker._user_transform is None:
- new_marker._user_transform = Affine2D()
-
- if deg is not None:
- new_marker._user_transform.rotate_deg(deg)
- if rad is not None:
- new_marker._user_transform.rotate(rad)
-
- return new_marker
-
- def scaled(self, sx, sy=None):
- """
- Return new marker scaled by specified scale factors.
-
- If *sy* is None, the same scale is applied in both the *x*- and
- *y*-directions.
-
- Parameters
- ----------
- sx : float
- *X*-direction scaling factor.
- sy : float, default: None
- *Y*-direction scaling factor.
- """
- if sy is None:
- sy = sx
-
- new_marker = MarkerStyle(self)
- _transform = new_marker._user_transform or Affine2D()
- new_marker._user_transform = _transform.scale(sx, sy)
- return new_marker
-
- def _set_nothing(self):
- self._filled = False
-
- def _set_custom_marker(self, path):
- rescale = np.max(np.abs(path.vertices)) # max of x's and y's.
- self._transform = Affine2D().scale(0.5 / rescale)
- self._path = path
-
- def _set_path_marker(self):
- self._set_custom_marker(self._marker)
-
- def _set_vertices(self):
- self._set_custom_marker(Path(self._marker))
-
- def _set_tuple_marker(self):
- marker = self._marker
- if len(marker) == 2:
- numsides, rotation = marker[0], 0.0
- elif len(marker) == 3:
- numsides, rotation = marker[0], marker[2]
- symstyle = marker[1]
- if symstyle == 0:
- self._path = Path.unit_regular_polygon(numsides)
- self._joinstyle = self._user_joinstyle or JoinStyle.miter
- elif symstyle == 1:
- self._path = Path.unit_regular_star(numsides)
- self._joinstyle = self._user_joinstyle or JoinStyle.bevel
- elif symstyle == 2:
- self._path = Path.unit_regular_asterisk(numsides)
- self._filled = False
- self._joinstyle = self._user_joinstyle or JoinStyle.bevel
- else:
- raise ValueError(f"Unexpected tuple marker: {marker}")
- self._transform = Affine2D().scale(0.5).rotate_deg(rotation)
-
- def _set_mathtext_path(self):
- """
- Draw mathtext markers '$...$' using `.TextPath` object.
-
- Submitted by tcb
- """
- from matplotlib.text import TextPath
-
- # again, the properties could be initialised just once outside
- # this function
- text = TextPath(xy=(0, 0), s=self.get_marker(),
- usetex=mpl.rcParams['text.usetex'])
- if len(text.vertices) == 0:
- return
-
- bbox = text.get_extents()
- max_dim = max(bbox.width, bbox.height)
- self._transform = (
- Affine2D()
- .translate(-bbox.xmin + 0.5 * -bbox.width, -bbox.ymin + 0.5 * -bbox.height)
- .scale(1.0 / max_dim))
- self._path = text
- self._snap = False
-
- def _half_fill(self):
- return self.get_fillstyle() in self._half_fillstyles
-
- def _set_circle(self, size=1.0):
- self._transform = Affine2D().scale(0.5 * size)
- self._snap_threshold = np.inf
- if not self._half_fill():
- self._path = Path.unit_circle()
- else:
- self._path = self._alt_path = Path.unit_circle_righthalf()
- fs = self.get_fillstyle()
- self._transform.rotate_deg(
- {'right': 0, 'top': 90, 'left': 180, 'bottom': 270}[fs])
- self._alt_transform = self._transform.frozen().rotate_deg(180.)
-
- def _set_point(self):
- self._set_circle(size=0.5)
-
- def _set_pixel(self):
- self._path = Path.unit_rectangle()
- # Ideally, you'd want -0.5, -0.5 here, but then the snapping
- # algorithm in the Agg backend will round this to a 2x2
- # rectangle from (-1, -1) to (1, 1). By offsetting it
- # slightly, we can force it to be (0, 0) to (1, 1), which both
- # makes it only be a single pixel and places it correctly
- # aligned to 1-width stroking (i.e. the ticks). This hack is
- # the best of a number of bad alternatives, mainly because the
- # backends are not aware of what marker is actually being used
- # beyond just its path data.
- self._transform = Affine2D().translate(-0.49999, -0.49999)
- self._snap_threshold = None
-
- _triangle_path = Path._create_closed([[0, 1], [-1, -1], [1, -1]])
- # Going down halfway looks to small. Golden ratio is too far.
- _triangle_path_u = Path._create_closed([[0, 1], [-3/5, -1/5], [3/5, -1/5]])
- _triangle_path_d = Path._create_closed(
- [[-3/5, -1/5], [3/5, -1/5], [1, -1], [-1, -1]])
- _triangle_path_l = Path._create_closed([[0, 1], [0, -1], [-1, -1]])
- _triangle_path_r = Path._create_closed([[0, 1], [0, -1], [1, -1]])
-
- def _set_triangle(self, rot, skip):
- self._transform = Affine2D().scale(0.5).rotate_deg(rot)
- self._snap_threshold = 5.0
-
- if not self._half_fill():
- self._path = self._triangle_path
- else:
- mpaths = [self._triangle_path_u,
- self._triangle_path_l,
- self._triangle_path_d,
- self._triangle_path_r]
-
- fs = self.get_fillstyle()
- if fs == 'top':
- self._path = mpaths[(0 + skip) % 4]
- self._alt_path = mpaths[(2 + skip) % 4]
- elif fs == 'bottom':
- self._path = mpaths[(2 + skip) % 4]
- self._alt_path = mpaths[(0 + skip) % 4]
- elif fs == 'left':
- self._path = mpaths[(1 + skip) % 4]
- self._alt_path = mpaths[(3 + skip) % 4]
- else:
- self._path = mpaths[(3 + skip) % 4]
- self._alt_path = mpaths[(1 + skip) % 4]
-
- self._alt_transform = self._transform
-
- self._joinstyle = self._user_joinstyle or JoinStyle.miter
-
- def _set_triangle_up(self):
- return self._set_triangle(0.0, 0)
-
- def _set_triangle_down(self):
- return self._set_triangle(180.0, 2)
-
- def _set_triangle_left(self):
- return self._set_triangle(90.0, 3)
-
- def _set_triangle_right(self):
- return self._set_triangle(270.0, 1)
-
- def _set_square(self):
- self._transform = Affine2D().translate(-0.5, -0.5)
- self._snap_threshold = 2.0
- if not self._half_fill():
- self._path = Path.unit_rectangle()
- else:
- # Build a bottom filled square out of two rectangles, one filled.
- self._path = Path([[0.0, 0.0], [1.0, 0.0], [1.0, 0.5],
- [0.0, 0.5], [0.0, 0.0]])
- self._alt_path = Path([[0.0, 0.5], [1.0, 0.5], [1.0, 1.0],
- [0.0, 1.0], [0.0, 0.5]])
- fs = self.get_fillstyle()
- rotate = {'bottom': 0, 'right': 90, 'top': 180, 'left': 270}[fs]
- self._transform.rotate_deg(rotate)
- self._alt_transform = self._transform
-
- self._joinstyle = self._user_joinstyle or JoinStyle.miter
-
- def _set_diamond(self):
- self._transform = Affine2D().translate(-0.5, -0.5).rotate_deg(45)
- self._snap_threshold = 5.0
- if not self._half_fill():
- self._path = Path.unit_rectangle()
- else:
- self._path = Path([[0, 0], [1, 0], [1, 1], [0, 0]])
- self._alt_path = Path([[0, 0], [0, 1], [1, 1], [0, 0]])
- fs = self.get_fillstyle()
- rotate = {'right': 0, 'top': 90, 'left': 180, 'bottom': 270}[fs]
- self._transform.rotate_deg(rotate)
- self._alt_transform = self._transform
- self._joinstyle = self._user_joinstyle or JoinStyle.miter
-
- def _set_thin_diamond(self):
- self._set_diamond()
- self._transform.scale(0.6, 1.0)
-
- def _set_pentagon(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = 5.0
-
- polypath = Path.unit_regular_polygon(5)
-
- if not self._half_fill():
- self._path = polypath
- else:
- verts = polypath.vertices
- y = (1 + np.sqrt(5)) / 4.
- top = Path(verts[[0, 1, 4, 0]])
- bottom = Path(verts[[1, 2, 3, 4, 1]])
- left = Path([verts[0], verts[1], verts[2], [0, -y], verts[0]])
- right = Path([verts[0], verts[4], verts[3], [0, -y], verts[0]])
- self._path, self._alt_path = {
- 'top': (top, bottom), 'bottom': (bottom, top),
- 'left': (left, right), 'right': (right, left),
- }[self.get_fillstyle()]
- self._alt_transform = self._transform
-
- self._joinstyle = self._user_joinstyle or JoinStyle.miter
-
- def _set_star(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = 5.0
-
- polypath = Path.unit_regular_star(5, innerCircle=0.381966)
-
- if not self._half_fill():
- self._path = polypath
- else:
- verts = polypath.vertices
- top = Path(np.concatenate([verts[0:4], verts[7:10], verts[0:1]]))
- bottom = Path(np.concatenate([verts[3:8], verts[3:4]]))
- left = Path(np.concatenate([verts[0:6], verts[0:1]]))
- right = Path(np.concatenate([verts[0:1], verts[5:10], verts[0:1]]))
- self._path, self._alt_path = {
- 'top': (top, bottom), 'bottom': (bottom, top),
- 'left': (left, right), 'right': (right, left),
- }[self.get_fillstyle()]
- self._alt_transform = self._transform
-
- self._joinstyle = self._user_joinstyle or JoinStyle.bevel
-
- def _set_hexagon1(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = None
-
- polypath = Path.unit_regular_polygon(6)
-
- if not self._half_fill():
- self._path = polypath
- else:
- verts = polypath.vertices
- # not drawing inside lines
- x = np.abs(np.cos(5 * np.pi / 6.))
- top = Path(np.concatenate([[(-x, 0)], verts[[1, 0, 5]], [(x, 0)]]))
- bottom = Path(np.concatenate([[(-x, 0)], verts[2:5], [(x, 0)]]))
- left = Path(verts[0:4])
- right = Path(verts[[0, 5, 4, 3]])
- self._path, self._alt_path = {
- 'top': (top, bottom), 'bottom': (bottom, top),
- 'left': (left, right), 'right': (right, left),
- }[self.get_fillstyle()]
- self._alt_transform = self._transform
-
- self._joinstyle = self._user_joinstyle or JoinStyle.miter
-
- def _set_hexagon2(self):
- self._transform = Affine2D().scale(0.5).rotate_deg(30)
- self._snap_threshold = None
-
- polypath = Path.unit_regular_polygon(6)
-
- if not self._half_fill():
- self._path = polypath
- else:
- verts = polypath.vertices
- # not drawing inside lines
- x, y = np.sqrt(3) / 4, 3 / 4.
- top = Path(verts[[1, 0, 5, 4, 1]])
- bottom = Path(verts[1:5])
- left = Path(np.concatenate([
- [(x, y)], verts[:3], [(-x, -y), (x, y)]]))
- right = Path(np.concatenate([
- [(x, y)], verts[5:2:-1], [(-x, -y)]]))
- self._path, self._alt_path = {
- 'top': (top, bottom), 'bottom': (bottom, top),
- 'left': (left, right), 'right': (right, left),
- }[self.get_fillstyle()]
- self._alt_transform = self._transform
-
- self._joinstyle = self._user_joinstyle or JoinStyle.miter
-
- def _set_octagon(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = 5.0
-
- polypath = Path.unit_regular_polygon(8)
-
- if not self._half_fill():
- self._transform.rotate_deg(22.5)
- self._path = polypath
- else:
- x = np.sqrt(2.) / 4.
- self._path = self._alt_path = Path(
- [[0, -1], [0, 1], [-x, 1], [-1, x],
- [-1, -x], [-x, -1], [0, -1]])
- fs = self.get_fillstyle()
- self._transform.rotate_deg(
- {'left': 0, 'bottom': 90, 'right': 180, 'top': 270}[fs])
- self._alt_transform = self._transform.frozen().rotate_deg(180.0)
-
- self._joinstyle = self._user_joinstyle or JoinStyle.miter
-
- _line_marker_path = Path([[0.0, -1.0], [0.0, 1.0]])
-
- def _set_vline(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = 1.0
- self._filled = False
- self._path = self._line_marker_path
-
- def _set_hline(self):
- self._set_vline()
- self._transform = self._transform.rotate_deg(90)
-
- _tickhoriz_path = Path([[0.0, 0.0], [1.0, 0.0]])
-
- def _set_tickleft(self):
- self._transform = Affine2D().scale(-1.0, 1.0)
- self._snap_threshold = 1.0
- self._filled = False
- self._path = self._tickhoriz_path
-
- def _set_tickright(self):
- self._transform = Affine2D().scale(1.0, 1.0)
- self._snap_threshold = 1.0
- self._filled = False
- self._path = self._tickhoriz_path
-
- _tickvert_path = Path([[-0.0, 0.0], [-0.0, 1.0]])
-
- def _set_tickup(self):
- self._transform = Affine2D().scale(1.0, 1.0)
- self._snap_threshold = 1.0
- self._filled = False
- self._path = self._tickvert_path
-
- def _set_tickdown(self):
- self._transform = Affine2D().scale(1.0, -1.0)
- self._snap_threshold = 1.0
- self._filled = False
- self._path = self._tickvert_path
-
- _tri_path = Path([[0.0, 0.0], [0.0, -1.0],
- [0.0, 0.0], [0.8, 0.5],
- [0.0, 0.0], [-0.8, 0.5]],
- [Path.MOVETO, Path.LINETO,
- Path.MOVETO, Path.LINETO,
- Path.MOVETO, Path.LINETO])
-
- def _set_tri_down(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = 5.0
- self._filled = False
- self._path = self._tri_path
-
- def _set_tri_up(self):
- self._set_tri_down()
- self._transform = self._transform.rotate_deg(180)
-
- def _set_tri_left(self):
- self._set_tri_down()
- self._transform = self._transform.rotate_deg(270)
-
- def _set_tri_right(self):
- self._set_tri_down()
- self._transform = self._transform.rotate_deg(90)
-
- _caret_path = Path([[-1.0, 1.5], [0.0, 0.0], [1.0, 1.5]])
-
- def _set_caretdown(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = 3.0
- self._filled = False
- self._path = self._caret_path
- self._joinstyle = self._user_joinstyle or JoinStyle.miter
-
- def _set_caretup(self):
- self._set_caretdown()
- self._transform = self._transform.rotate_deg(180)
-
- def _set_caretleft(self):
- self._set_caretdown()
- self._transform = self._transform.rotate_deg(270)
-
- def _set_caretright(self):
- self._set_caretdown()
- self._transform = self._transform.rotate_deg(90)
-
- _caret_path_base = Path([[-1.0, 0.0], [0.0, -1.5], [1.0, 0]])
-
- def _set_caretdownbase(self):
- self._set_caretdown()
- self._path = self._caret_path_base
-
- def _set_caretupbase(self):
- self._set_caretdownbase()
- self._transform = self._transform.rotate_deg(180)
-
- def _set_caretleftbase(self):
- self._set_caretdownbase()
- self._transform = self._transform.rotate_deg(270)
-
- def _set_caretrightbase(self):
- self._set_caretdownbase()
- self._transform = self._transform.rotate_deg(90)
-
- _plus_path = Path([[-1.0, 0.0], [1.0, 0.0],
- [0.0, -1.0], [0.0, 1.0]],
- [Path.MOVETO, Path.LINETO,
- Path.MOVETO, Path.LINETO])
-
- def _set_plus(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = 1.0
- self._filled = False
- self._path = self._plus_path
-
- _x_path = Path([[-1.0, -1.0], [1.0, 1.0],
- [-1.0, 1.0], [1.0, -1.0]],
- [Path.MOVETO, Path.LINETO,
- Path.MOVETO, Path.LINETO])
-
- def _set_x(self):
- self._transform = Affine2D().scale(0.5)
- self._snap_threshold = 3.0
- self._filled = False
- self._path = self._x_path
-
- _plus_filled_path = Path._create_closed(np.array([
- (-1, -3), (+1, -3), (+1, -1), (+3, -1), (+3, +1), (+1, +1),
- (+1, +3), (-1, +3), (-1, +1), (-3, +1), (-3, -1), (-1, -1)]) / 6)
- _plus_filled_path_t = Path._create_closed(np.array([
- (+3, 0), (+3, +1), (+1, +1), (+1, +3),
- (-1, +3), (-1, +1), (-3, +1), (-3, 0)]) / 6)
-
- def _set_plus_filled(self):
- self._transform = Affine2D()
- self._snap_threshold = 5.0
- self._joinstyle = self._user_joinstyle or JoinStyle.miter
- if not self._half_fill():
- self._path = self._plus_filled_path
- else:
- # Rotate top half path to support all partitions
- self._path = self._alt_path = self._plus_filled_path_t
- fs = self.get_fillstyle()
- self._transform.rotate_deg(
- {'top': 0, 'left': 90, 'bottom': 180, 'right': 270}[fs])
- self._alt_transform = self._transform.frozen().rotate_deg(180)
-
- _x_filled_path = Path._create_closed(np.array([
- (-1, -2), (0, -1), (+1, -2), (+2, -1), (+1, 0), (+2, +1),
- (+1, +2), (0, +1), (-1, +2), (-2, +1), (-1, 0), (-2, -1)]) / 4)
- _x_filled_path_t = Path._create_closed(np.array([
- (+1, 0), (+2, +1), (+1, +2), (0, +1),
- (-1, +2), (-2, +1), (-1, 0)]) / 4)
-
- def _set_x_filled(self):
- self._transform = Affine2D()
- self._snap_threshold = 5.0
- self._joinstyle = self._user_joinstyle or JoinStyle.miter
- if not self._half_fill():
- self._path = self._x_filled_path
- else:
- # Rotate top half path to support all partitions
- self._path = self._alt_path = self._x_filled_path_t
- fs = self.get_fillstyle()
- self._transform.rotate_deg(
- {'top': 0, 'left': 90, 'bottom': 180, 'right': 270}[fs])
- self._alt_transform = self._transform.frozen().rotate_deg(180)
diff --git a/contrib/python/matplotlib/py3/matplotlib/markers.pyi b/contrib/python/matplotlib/py3/matplotlib/markers.pyi
deleted file mode 100644
index 3ee5388385..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/markers.pyi
+++ /dev/null
@@ -1,51 +0,0 @@
-from typing import Literal
-
-from .path import Path
-from .transforms import Affine2D, Transform
-
-from numpy.typing import ArrayLike
-from .typing import CapStyleType, FillStyleType, JoinStyleType
-
-TICKLEFT: int
-TICKRIGHT: int
-TICKUP: int
-TICKDOWN: int
-CARETLEFT: int
-CARETRIGHT: int
-CARETUP: int
-CARETDOWN: int
-CARETLEFTBASE: int
-CARETRIGHTBASE: int
-CARETUPBASE: int
-CARETDOWNBASE: int
-
-class MarkerStyle:
- markers: dict[str | int, str]
- filled_markers: tuple[str, ...]
- fillstyles: tuple[FillStyleType, ...]
-
- def __init__(
- self,
- marker: str | ArrayLike | Path | MarkerStyle | None,
- fillstyle: FillStyleType | None = ...,
- transform: Transform | None = ...,
- capstyle: CapStyleType | None = ...,
- joinstyle: JoinStyleType | None = ...,
- ) -> None: ...
- def __bool__(self) -> bool: ...
- def is_filled(self) -> bool: ...
- def get_fillstyle(self) -> FillStyleType: ...
- def get_joinstyle(self) -> Literal["miter", "round", "bevel"]: ...
- def get_capstyle(self) -> Literal["butt", "projecting", "round"]: ...
- def get_marker(self) -> str | ArrayLike | Path | None: ...
- def get_path(self) -> Path: ...
- def get_transform(self) -> Transform: ...
- def get_alt_path(self) -> Path | None: ...
- def get_alt_transform(self) -> Transform: ...
- def get_snap_threshold(self) -> float | None: ...
- def get_user_transform(self) -> Transform | None: ...
- def transformed(self, transform: Affine2D) -> MarkerStyle: ...
- def rotated(
- self, *, deg: float | None = ..., rad: float | None = ...
- ) -> MarkerStyle: ...
- def scaled(self, sx: float, sy: float | None = ...) -> MarkerStyle: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/mathtext.py b/contrib/python/matplotlib/py3/matplotlib/mathtext.py
deleted file mode 100644
index e25b76c403..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mathtext.py
+++ /dev/null
@@ -1,140 +0,0 @@
-r"""
-A module for parsing a subset of the TeX math syntax and rendering it to a
-Matplotlib backend.
-
-For a tutorial of its usage, see :ref:`mathtext`. This
-document is primarily concerned with implementation details.
-
-The module uses pyparsing_ to parse the TeX expression.
-
-.. _pyparsing: https://pypi.org/project/pyparsing/
-
-The Bakoma distribution of the TeX Computer Modern fonts, and STIX
-fonts are supported. There is experimental support for using
-arbitrary fonts, but results may vary without proper tweaking and
-metrics for those fonts.
-"""
-
-import functools
-import logging
-
-import matplotlib as mpl
-from matplotlib import _api, _mathtext
-from matplotlib.ft2font import LOAD_NO_HINTING
-from matplotlib.font_manager import FontProperties
-from ._mathtext import ( # noqa: reexported API
- RasterParse, VectorParse, get_unicode_index)
-
-_log = logging.getLogger(__name__)
-
-
-get_unicode_index.__module__ = __name__
-
-##############################################################################
-# MAIN
-
-
-class MathTextParser:
- _parser = None
- _font_type_mapping = {
- 'cm': _mathtext.BakomaFonts,
- 'dejavuserif': _mathtext.DejaVuSerifFonts,
- 'dejavusans': _mathtext.DejaVuSansFonts,
- 'stix': _mathtext.StixFonts,
- 'stixsans': _mathtext.StixSansFonts,
- 'custom': _mathtext.UnicodeFonts,
- }
-
- def __init__(self, output):
- """
- Create a MathTextParser for the given backend *output*.
-
- Parameters
- ----------
- output : {"path", "agg"}
- Whether to return a `VectorParse` ("path") or a
- `RasterParse` ("agg", or its synonym "macosx").
- """
- self._output_type = _api.check_getitem(
- {"path": "vector", "agg": "raster", "macosx": "raster"},
- output=output.lower())
-
- def parse(self, s, dpi=72, prop=None, *, antialiased=None):
- """
- Parse the given math expression *s* at the given *dpi*. If *prop* is
- provided, it is a `.FontProperties` object specifying the "default"
- font to use in the math expression, used for all non-math text.
-
- The results are cached, so multiple calls to `parse`
- with the same expression should be fast.
-
- Depending on the *output* type, this returns either a `VectorParse` or
- a `RasterParse`.
- """
- # lru_cache can't decorate parse() directly because prop
- # is mutable; key the cache using an internal copy (see
- # text._get_text_metrics_with_cache for a similar case).
- prop = prop.copy() if prop is not None else None
- antialiased = mpl._val_or_rc(antialiased, 'text.antialiased')
- return self._parse_cached(s, dpi, prop, antialiased)
-
- @functools.lru_cache(50)
- def _parse_cached(self, s, dpi, prop, antialiased):
- from matplotlib.backends import backend_agg
-
- if prop is None:
- prop = FontProperties()
- fontset_class = _api.check_getitem(
- self._font_type_mapping, fontset=prop.get_math_fontfamily())
- load_glyph_flags = {
- "vector": LOAD_NO_HINTING,
- "raster": backend_agg.get_hinting_flag(),
- }[self._output_type]
- fontset = fontset_class(prop, load_glyph_flags)
-
- fontsize = prop.get_size_in_points()
-
- if self._parser is None: # Cache the parser globally.
- self.__class__._parser = _mathtext.Parser()
-
- box = self._parser.parse(s, fontset, fontsize, dpi)
- output = _mathtext.ship(box)
- if self._output_type == "vector":
- return output.to_vector()
- elif self._output_type == "raster":
- return output.to_raster(antialiased=antialiased)
-
-
-def math_to_image(s, filename_or_obj, prop=None, dpi=None, format=None,
- *, color=None):
- """
- Given a math expression, renders it in a closely-clipped bounding
- box to an image file.
-
- Parameters
- ----------
- s : str
- A math expression. The math portion must be enclosed in dollar signs.
- filename_or_obj : str or path-like or file-like
- Where to write the image data.
- prop : `.FontProperties`, optional
- The size and style of the text.
- dpi : float, optional
- The output dpi. If not set, the dpi is determined as for
- `.Figure.savefig`.
- format : str, optional
- The output format, e.g., 'svg', 'pdf', 'ps' or 'png'. If not set, the
- format is determined as for `.Figure.savefig`.
- color : str, optional
- Foreground color, defaults to :rc:`text.color`.
- """
- from matplotlib import figure
-
- parser = MathTextParser('path')
- width, height, depth, _, _ = parser.parse(s, dpi=72, prop=prop)
-
- fig = figure.Figure(figsize=(width / 72.0, height / 72.0))
- fig.text(0, depth/height, s, fontproperties=prop, color=color)
- fig.savefig(filename_or_obj, dpi=dpi, format=format)
-
- return depth
diff --git a/contrib/python/matplotlib/py3/matplotlib/mathtext.pyi b/contrib/python/matplotlib/py3/matplotlib/mathtext.pyi
deleted file mode 100644
index 607501a275..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mathtext.pyi
+++ /dev/null
@@ -1,33 +0,0 @@
-import os
-from typing import Generic, IO, Literal, TypeVar, overload
-
-from matplotlib.font_manager import FontProperties
-from matplotlib.typing import ColorType
-
-# Re-exported API from _mathtext.
-from ._mathtext import (
- RasterParse as RasterParse,
- VectorParse as VectorParse,
- get_unicode_index as get_unicode_index,
-)
-
-_ParseType = TypeVar("_ParseType", RasterParse, VectorParse)
-
-class MathTextParser(Generic[_ParseType]):
- @overload
- def __init__(self: MathTextParser[VectorParse], output: Literal["path"]) -> None: ...
- @overload
- def __init__(self: MathTextParser[RasterParse], output: Literal["agg", "raster", "macosx"]) -> None: ...
- def parse(
- self, s: str, dpi: float = ..., prop: FontProperties | None = ..., *, antialiased: bool | None = ...
- ) -> _ParseType: ...
-
-def math_to_image(
- s: str,
- filename_or_obj: str | os.PathLike | IO,
- prop: FontProperties | None = ...,
- dpi: float | None = ...,
- format: str | None = ...,
- *,
- color: ColorType | None = ...
-) -> float: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/mlab.py b/contrib/python/matplotlib/py3/matplotlib/mlab.py
deleted file mode 100644
index 1948e6333e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mlab.py
+++ /dev/null
@@ -1,914 +0,0 @@
-"""
-Numerical Python functions written for compatibility with MATLAB
-commands with the same names. Most numerical Python functions can be found in
-the `NumPy`_ and `SciPy`_ libraries. What remains here is code for performing
-spectral computations and kernel density estimations.
-
-.. _NumPy: https://numpy.org
-.. _SciPy: https://www.scipy.org
-
-Spectral functions
-------------------
-
-`cohere`
- Coherence (normalized cross spectral density)
-
-`csd`
- Cross spectral density using Welch's average periodogram
-
-`detrend`
- Remove the mean or best fit line from an array
-
-`psd`
- Power spectral density using Welch's average periodogram
-
-`specgram`
- Spectrogram (spectrum over segments of time)
-
-`complex_spectrum`
- Return the complex-valued frequency spectrum of a signal
-
-`magnitude_spectrum`
- Return the magnitude of the frequency spectrum of a signal
-
-`angle_spectrum`
- Return the angle (wrapped phase) of the frequency spectrum of a signal
-
-`phase_spectrum`
- Return the phase (unwrapped angle) of the frequency spectrum of a signal
-
-`detrend_mean`
- Remove the mean from a line.
-
-`detrend_linear`
- Remove the best fit line from a line.
-
-`detrend_none`
- Return the original line.
-"""
-
-import functools
-from numbers import Number
-
-import numpy as np
-
-from matplotlib import _api, _docstring, cbook
-
-
-def window_hanning(x):
- """
- Return *x* times the Hanning (or Hann) window of len(*x*).
-
- See Also
- --------
- window_none : Another window algorithm.
- """
- return np.hanning(len(x))*x
-
-
-def window_none(x):
- """
- No window function; simply return *x*.
-
- See Also
- --------
- window_hanning : Another window algorithm.
- """
- return x
-
-
-def detrend(x, key=None, axis=None):
- """
- Return *x* with its trend removed.
-
- Parameters
- ----------
- x : array or sequence
- Array or sequence containing the data.
-
- key : {'default', 'constant', 'mean', 'linear', 'none'} or function
- The detrending algorithm to use. 'default', 'mean', and 'constant' are
- the same as `detrend_mean`. 'linear' is the same as `detrend_linear`.
- 'none' is the same as `detrend_none`. The default is 'mean'. See the
- corresponding functions for more details regarding the algorithms. Can
- also be a function that carries out the detrend operation.
-
- axis : int
- The axis along which to do the detrending.
-
- See Also
- --------
- detrend_mean : Implementation of the 'mean' algorithm.
- detrend_linear : Implementation of the 'linear' algorithm.
- detrend_none : Implementation of the 'none' algorithm.
- """
- if key is None or key in ['constant', 'mean', 'default']:
- return detrend(x, key=detrend_mean, axis=axis)
- elif key == 'linear':
- return detrend(x, key=detrend_linear, axis=axis)
- elif key == 'none':
- return detrend(x, key=detrend_none, axis=axis)
- elif callable(key):
- x = np.asarray(x)
- if axis is not None and axis + 1 > x.ndim:
- raise ValueError(f'axis(={axis}) out of bounds')
- if (axis is None and x.ndim == 0) or (not axis and x.ndim == 1):
- return key(x)
- # try to use the 'axis' argument if the function supports it,
- # otherwise use apply_along_axis to do it
- try:
- return key(x, axis=axis)
- except TypeError:
- return np.apply_along_axis(key, axis=axis, arr=x)
- else:
- raise ValueError(
- f"Unknown value for key: {key!r}, must be one of: 'default', "
- f"'constant', 'mean', 'linear', or a function")
-
-
-def detrend_mean(x, axis=None):
- """
- Return *x* minus the mean(*x*).
-
- Parameters
- ----------
- x : array or sequence
- Array or sequence containing the data
- Can have any dimensionality
-
- axis : int
- The axis along which to take the mean. See `numpy.mean` for a
- description of this argument.
-
- See Also
- --------
- detrend_linear : Another detrend algorithm.
- detrend_none : Another detrend algorithm.
- detrend : A wrapper around all the detrend algorithms.
- """
- x = np.asarray(x)
-
- if axis is not None and axis+1 > x.ndim:
- raise ValueError('axis(=%s) out of bounds' % axis)
-
- return x - x.mean(axis, keepdims=True)
-
-
-def detrend_none(x, axis=None):
- """
- Return *x*: no detrending.
-
- Parameters
- ----------
- x : any object
- An object containing the data
-
- axis : int
- This parameter is ignored.
- It is included for compatibility with detrend_mean
-
- See Also
- --------
- detrend_mean : Another detrend algorithm.
- detrend_linear : Another detrend algorithm.
- detrend : A wrapper around all the detrend algorithms.
- """
- return x
-
-
-def detrend_linear(y):
- """
- Return *x* minus best fit line; 'linear' detrending.
-
- Parameters
- ----------
- y : 0-D or 1-D array or sequence
- Array or sequence containing the data
-
- See Also
- --------
- detrend_mean : Another detrend algorithm.
- detrend_none : Another detrend algorithm.
- detrend : A wrapper around all the detrend algorithms.
- """
- # This is faster than an algorithm based on linalg.lstsq.
- y = np.asarray(y)
-
- if y.ndim > 1:
- raise ValueError('y cannot have ndim > 1')
-
- # short-circuit 0-D array.
- if not y.ndim:
- return np.array(0., dtype=y.dtype)
-
- x = np.arange(y.size, dtype=float)
-
- C = np.cov(x, y, bias=1)
- b = C[0, 1]/C[0, 0]
-
- a = y.mean() - b*x.mean()
- return y - (b*x + a)
-
-
-def _spectral_helper(x, y=None, NFFT=None, Fs=None, detrend_func=None,
- window=None, noverlap=None, pad_to=None,
- sides=None, scale_by_freq=None, mode=None):
- """
- Private helper implementing the common parts between the psd, csd,
- spectrogram and complex, magnitude, angle, and phase spectrums.
- """
- if y is None:
- # if y is None use x for y
- same_data = True
- else:
- # The checks for if y is x are so that we can use the same function to
- # implement the core of psd(), csd(), and spectrogram() without doing
- # extra calculations. We return the unaveraged Pxy, freqs, and t.
- same_data = y is x
-
- if Fs is None:
- Fs = 2
- if noverlap is None:
- noverlap = 0
- if detrend_func is None:
- detrend_func = detrend_none
- if window is None:
- window = window_hanning
-
- # if NFFT is set to None use the whole signal
- if NFFT is None:
- NFFT = 256
-
- if noverlap >= NFFT:
- raise ValueError('noverlap must be less than NFFT')
-
- if mode is None or mode == 'default':
- mode = 'psd'
- _api.check_in_list(
- ['default', 'psd', 'complex', 'magnitude', 'angle', 'phase'],
- mode=mode)
-
- if not same_data and mode != 'psd':
- raise ValueError("x and y must be equal if mode is not 'psd'")
-
- # Make sure we're dealing with a numpy array. If y and x were the same
- # object to start with, keep them that way
- x = np.asarray(x)
- if not same_data:
- y = np.asarray(y)
-
- if sides is None or sides == 'default':
- if np.iscomplexobj(x):
- sides = 'twosided'
- else:
- sides = 'onesided'
- _api.check_in_list(['default', 'onesided', 'twosided'], sides=sides)
-
- # zero pad x and y up to NFFT if they are shorter than NFFT
- if len(x) < NFFT:
- n = len(x)
- x = np.resize(x, NFFT)
- x[n:] = 0
-
- if not same_data and len(y) < NFFT:
- n = len(y)
- y = np.resize(y, NFFT)
- y[n:] = 0
-
- if pad_to is None:
- pad_to = NFFT
-
- if mode != 'psd':
- scale_by_freq = False
- elif scale_by_freq is None:
- scale_by_freq = True
-
- # For real x, ignore the negative frequencies unless told otherwise
- if sides == 'twosided':
- numFreqs = pad_to
- if pad_to % 2:
- freqcenter = (pad_to - 1)//2 + 1
- else:
- freqcenter = pad_to//2
- scaling_factor = 1.
- elif sides == 'onesided':
- if pad_to % 2:
- numFreqs = (pad_to + 1)//2
- else:
- numFreqs = pad_to//2 + 1
- scaling_factor = 2.
-
- if not np.iterable(window):
- window = window(np.ones(NFFT, x.dtype))
- if len(window) != NFFT:
- raise ValueError(
- "The window length must match the data's first dimension")
-
- result = np.lib.stride_tricks.sliding_window_view(
- x, NFFT, axis=0)[::NFFT - noverlap].T
- result = detrend(result, detrend_func, axis=0)
- result = result * window.reshape((-1, 1))
- result = np.fft.fft(result, n=pad_to, axis=0)[:numFreqs, :]
- freqs = np.fft.fftfreq(pad_to, 1/Fs)[:numFreqs]
-
- if not same_data:
- # if same_data is False, mode must be 'psd'
- resultY = np.lib.stride_tricks.sliding_window_view(
- y, NFFT, axis=0)[::NFFT - noverlap].T
- resultY = detrend(resultY, detrend_func, axis=0)
- resultY = resultY * window.reshape((-1, 1))
- resultY = np.fft.fft(resultY, n=pad_to, axis=0)[:numFreqs, :]
- result = np.conj(result) * resultY
- elif mode == 'psd':
- result = np.conj(result) * result
- elif mode == 'magnitude':
- result = np.abs(result) / window.sum()
- elif mode == 'angle' or mode == 'phase':
- # we unwrap the phase later to handle the onesided vs. twosided case
- result = np.angle(result)
- elif mode == 'complex':
- result /= window.sum()
-
- if mode == 'psd':
-
- # Also include scaling factors for one-sided densities and dividing by
- # the sampling frequency, if desired. Scale everything, except the DC
- # component and the NFFT/2 component:
-
- # if we have a even number of frequencies, don't scale NFFT/2
- if not NFFT % 2:
- slc = slice(1, -1, None)
- # if we have an odd number, just don't scale DC
- else:
- slc = slice(1, None, None)
-
- result[slc] *= scaling_factor
-
- # MATLAB divides by the sampling frequency so that density function
- # has units of dB/Hz and can be integrated by the plotted frequency
- # values. Perform the same scaling here.
- if scale_by_freq:
- result /= Fs
- # Scale the spectrum by the norm of the window to compensate for
- # windowing loss; see Bendat & Piersol Sec 11.5.2.
- result /= (window**2).sum()
- else:
- # In this case, preserve power in the segment, not amplitude
- result /= window.sum()**2
-
- t = np.arange(NFFT/2, len(x) - NFFT/2 + 1, NFFT - noverlap)/Fs
-
- if sides == 'twosided':
- # center the frequency range at zero
- freqs = np.roll(freqs, -freqcenter, axis=0)
- result = np.roll(result, -freqcenter, axis=0)
- elif not pad_to % 2:
- # get the last value correctly, it is negative otherwise
- freqs[-1] *= -1
-
- # we unwrap the phase here to handle the onesided vs. twosided case
- if mode == 'phase':
- result = np.unwrap(result, axis=0)
-
- return result, freqs, t
-
-
-def _single_spectrum_helper(
- mode, x, Fs=None, window=None, pad_to=None, sides=None):
- """
- Private helper implementing the commonality between the complex, magnitude,
- angle, and phase spectrums.
- """
- _api.check_in_list(['complex', 'magnitude', 'angle', 'phase'], mode=mode)
-
- if pad_to is None:
- pad_to = len(x)
-
- spec, freqs, _ = _spectral_helper(x=x, y=None, NFFT=len(x), Fs=Fs,
- detrend_func=detrend_none, window=window,
- noverlap=0, pad_to=pad_to,
- sides=sides,
- scale_by_freq=False,
- mode=mode)
- if mode != 'complex':
- spec = spec.real
-
- if spec.ndim == 2 and spec.shape[1] == 1:
- spec = spec[:, 0]
-
- return spec, freqs
-
-
-# Split out these keyword docs so that they can be used elsewhere
-_docstring.interpd.update(
- Spectral="""\
-Fs : float, default: 2
- The sampling frequency (samples per time unit). It is used to calculate
- the Fourier frequencies, *freqs*, in cycles per time unit.
-
-window : callable or ndarray, default: `.window_hanning`
- A function or a vector of length *NFFT*. To create window vectors see
- `.window_hanning`, `.window_none`, `numpy.blackman`, `numpy.hamming`,
- `numpy.bartlett`, `scipy.signal`, `scipy.signal.get_window`, etc. If a
- function is passed as the argument, it must take a data segment as an
- argument and return the windowed version of the segment.
-
-sides : {'default', 'onesided', 'twosided'}, optional
- Which sides of the spectrum to return. 'default' is one-sided for real
- data and two-sided for complex data. 'onesided' forces the return of a
- one-sided spectrum, while 'twosided' forces two-sided.""",
-
- Single_Spectrum="""\
-pad_to : int, optional
- The number of points to which the data segment is padded when performing
- the FFT. While not increasing the actual resolution of the spectrum (the
- minimum distance between resolvable peaks), this can give more points in
- the plot, allowing for more detail. This corresponds to the *n* parameter
- in the call to `~numpy.fft.fft`. The default is None, which sets *pad_to*
- equal to the length of the input signal (i.e. no padding).""",
-
- PSD="""\
-pad_to : int, optional
- The number of points to which the data segment is padded when performing
- the FFT. This can be different from *NFFT*, which specifies the number
- of data points used. While not increasing the actual resolution of the
- spectrum (the minimum distance between resolvable peaks), this can give
- more points in the plot, allowing for more detail. This corresponds to
- the *n* parameter in the call to `~numpy.fft.fft`. The default is None,
- which sets *pad_to* equal to *NFFT*
-
-NFFT : int, default: 256
- The number of data points used in each block for the FFT. A power 2 is
- most efficient. This should *NOT* be used to get zero padding, or the
- scaling of the result will be incorrect; use *pad_to* for this instead.
-
-detrend : {'none', 'mean', 'linear'} or callable, default: 'none'
- The function applied to each segment before fft-ing, designed to remove
- the mean or linear trend. Unlike in MATLAB, where the *detrend* parameter
- is a vector, in Matplotlib it is a function. The :mod:`~matplotlib.mlab`
- module defines `.detrend_none`, `.detrend_mean`, and `.detrend_linear`,
- but you can use a custom function as well. You can also use a string to
- choose one of the functions: 'none' calls `.detrend_none`. 'mean' calls
- `.detrend_mean`. 'linear' calls `.detrend_linear`.
-
-scale_by_freq : bool, default: True
- Whether the resulting density values should be scaled by the scaling
- frequency, which gives density in units of 1/Hz. This allows for
- integration over the returned frequency values. The default is True for
- MATLAB compatibility.""")
-
-
-@_docstring.dedent_interpd
-def psd(x, NFFT=None, Fs=None, detrend=None, window=None,
- noverlap=None, pad_to=None, sides=None, scale_by_freq=None):
- r"""
- Compute the power spectral density.
-
- The power spectral density :math:`P_{xx}` by Welch's average
- periodogram method. The vector *x* is divided into *NFFT* length
- segments. Each segment is detrended by function *detrend* and
- windowed by function *window*. *noverlap* gives the length of
- the overlap between segments. The :math:`|\mathrm{fft}(i)|^2`
- of each segment :math:`i` are averaged to compute :math:`P_{xx}`.
-
- If len(*x*) < *NFFT*, it will be zero padded to *NFFT*.
-
- Parameters
- ----------
- x : 1-D array or sequence
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(PSD)s
-
- noverlap : int, default: 0 (no overlap)
- The number of points of overlap between segments.
-
- Returns
- -------
- Pxx : 1-D array
- The values for the power spectrum :math:`P_{xx}` (real valued)
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *Pxx*
-
- References
- ----------
- Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, John
- Wiley & Sons (1986)
-
- See Also
- --------
- specgram
- `specgram` differs in the default overlap; in not returning the mean of
- the segment periodograms; and in returning the times of the segments.
-
- magnitude_spectrum : returns the magnitude spectrum.
-
- csd : returns the spectral density between two signals.
- """
- Pxx, freqs = csd(x=x, y=None, NFFT=NFFT, Fs=Fs, detrend=detrend,
- window=window, noverlap=noverlap, pad_to=pad_to,
- sides=sides, scale_by_freq=scale_by_freq)
- return Pxx.real, freqs
-
-
-@_docstring.dedent_interpd
-def csd(x, y, NFFT=None, Fs=None, detrend=None, window=None,
- noverlap=None, pad_to=None, sides=None, scale_by_freq=None):
- """
- Compute the cross-spectral density.
-
- The cross spectral density :math:`P_{xy}` by Welch's average
- periodogram method. The vectors *x* and *y* are divided into
- *NFFT* length segments. Each segment is detrended by function
- *detrend* and windowed by function *window*. *noverlap* gives
- the length of the overlap between segments. The product of
- the direct FFTs of *x* and *y* are averaged over each segment
- to compute :math:`P_{xy}`, with a scaling to correct for power
- loss due to windowing.
-
- If len(*x*) < *NFFT* or len(*y*) < *NFFT*, they will be zero
- padded to *NFFT*.
-
- Parameters
- ----------
- x, y : 1-D arrays or sequences
- Arrays or sequences containing the data
-
- %(Spectral)s
-
- %(PSD)s
-
- noverlap : int, default: 0 (no overlap)
- The number of points of overlap between segments.
-
- Returns
- -------
- Pxy : 1-D array
- The values for the cross spectrum :math:`P_{xy}` before scaling (real
- valued)
-
- freqs : 1-D array
- The frequencies corresponding to the elements in *Pxy*
-
- References
- ----------
- Bendat & Piersol -- Random Data: Analysis and Measurement Procedures, John
- Wiley & Sons (1986)
-
- See Also
- --------
- psd : equivalent to setting ``y = x``.
- """
- if NFFT is None:
- NFFT = 256
- Pxy, freqs, _ = _spectral_helper(x=x, y=y, NFFT=NFFT, Fs=Fs,
- detrend_func=detrend, window=window,
- noverlap=noverlap, pad_to=pad_to,
- sides=sides, scale_by_freq=scale_by_freq,
- mode='psd')
-
- if Pxy.ndim == 2:
- if Pxy.shape[1] > 1:
- Pxy = Pxy.mean(axis=1)
- else:
- Pxy = Pxy[:, 0]
- return Pxy, freqs
-
-
-_single_spectrum_docs = """\
-Compute the {quantity} of *x*.
-Data is padded to a length of *pad_to* and the windowing function *window* is
-applied to the signal.
-
-Parameters
-----------
-x : 1-D array or sequence
- Array or sequence containing the data
-
-{Spectral}
-
-{Single_Spectrum}
-
-Returns
--------
-spectrum : 1-D array
- The {quantity}.
-freqs : 1-D array
- The frequencies corresponding to the elements in *spectrum*.
-
-See Also
---------
-psd
- Returns the power spectral density.
-complex_spectrum
- Returns the complex-valued frequency spectrum.
-magnitude_spectrum
- Returns the absolute value of the `complex_spectrum`.
-angle_spectrum
- Returns the angle of the `complex_spectrum`.
-phase_spectrum
- Returns the phase (unwrapped angle) of the `complex_spectrum`.
-specgram
- Can return the complex spectrum of segments within the signal.
-"""
-
-
-complex_spectrum = functools.partial(_single_spectrum_helper, "complex")
-complex_spectrum.__doc__ = _single_spectrum_docs.format(
- quantity="complex-valued frequency spectrum",
- **_docstring.interpd.params)
-magnitude_spectrum = functools.partial(_single_spectrum_helper, "magnitude")
-magnitude_spectrum.__doc__ = _single_spectrum_docs.format(
- quantity="magnitude (absolute value) of the frequency spectrum",
- **_docstring.interpd.params)
-angle_spectrum = functools.partial(_single_spectrum_helper, "angle")
-angle_spectrum.__doc__ = _single_spectrum_docs.format(
- quantity="angle of the frequency spectrum (wrapped phase spectrum)",
- **_docstring.interpd.params)
-phase_spectrum = functools.partial(_single_spectrum_helper, "phase")
-phase_spectrum.__doc__ = _single_spectrum_docs.format(
- quantity="phase of the frequency spectrum (unwrapped phase spectrum)",
- **_docstring.interpd.params)
-
-
-@_docstring.dedent_interpd
-def specgram(x, NFFT=None, Fs=None, detrend=None, window=None,
- noverlap=None, pad_to=None, sides=None, scale_by_freq=None,
- mode=None):
- """
- Compute a spectrogram.
-
- Compute and plot a spectrogram of data in *x*. Data are split into
- *NFFT* length segments and the spectrum of each section is
- computed. The windowing function *window* is applied to each
- segment, and the amount of overlap of each segment is
- specified with *noverlap*.
-
- Parameters
- ----------
- x : array-like
- 1-D array or sequence.
-
- %(Spectral)s
-
- %(PSD)s
-
- noverlap : int, default: 128
- The number of points of overlap between blocks.
- mode : str, default: 'psd'
- What sort of spectrum to use:
- 'psd'
- Returns the power spectral density.
- 'complex'
- Returns the complex-valued frequency spectrum.
- 'magnitude'
- Returns the magnitude spectrum.
- 'angle'
- Returns the phase spectrum without unwrapping.
- 'phase'
- Returns the phase spectrum with unwrapping.
-
- Returns
- -------
- spectrum : array-like
- 2D array, columns are the periodograms of successive segments.
-
- freqs : array-like
- 1-D array, frequencies corresponding to the rows in *spectrum*.
-
- t : array-like
- 1-D array, the times corresponding to midpoints of segments
- (i.e the columns in *spectrum*).
-
- See Also
- --------
- psd : differs in the overlap and in the return values.
- complex_spectrum : similar, but with complex valued frequencies.
- magnitude_spectrum : similar single segment when *mode* is 'magnitude'.
- angle_spectrum : similar to single segment when *mode* is 'angle'.
- phase_spectrum : similar to single segment when *mode* is 'phase'.
-
- Notes
- -----
- *detrend* and *scale_by_freq* only apply when *mode* is set to 'psd'.
-
- """
- if noverlap is None:
- noverlap = 128 # default in _spectral_helper() is noverlap = 0
- if NFFT is None:
- NFFT = 256 # same default as in _spectral_helper()
- if len(x) <= NFFT:
- _api.warn_external("Only one segment is calculated since parameter "
- f"NFFT (={NFFT}) >= signal length (={len(x)}).")
-
- spec, freqs, t = _spectral_helper(x=x, y=None, NFFT=NFFT, Fs=Fs,
- detrend_func=detrend, window=window,
- noverlap=noverlap, pad_to=pad_to,
- sides=sides,
- scale_by_freq=scale_by_freq,
- mode=mode)
-
- if mode != 'complex':
- spec = spec.real # Needed since helper implements generically
-
- return spec, freqs, t
-
-
-@_docstring.dedent_interpd
-def cohere(x, y, NFFT=256, Fs=2, detrend=detrend_none, window=window_hanning,
- noverlap=0, pad_to=None, sides='default', scale_by_freq=None):
- r"""
- The coherence between *x* and *y*. Coherence is the normalized
- cross spectral density:
-
- .. math::
-
- C_{xy} = \frac{|P_{xy}|^2}{P_{xx}P_{yy}}
-
- Parameters
- ----------
- x, y
- Array or sequence containing the data
-
- %(Spectral)s
-
- %(PSD)s
-
- noverlap : int, default: 0 (no overlap)
- The number of points of overlap between segments.
-
- Returns
- -------
- Cxy : 1-D array
- The coherence vector.
- freqs : 1-D array
- The frequencies for the elements in *Cxy*.
-
- See Also
- --------
- :func:`psd`, :func:`csd` :
- For information about the methods used to compute :math:`P_{xy}`,
- :math:`P_{xx}` and :math:`P_{yy}`.
- """
- if len(x) < 2 * NFFT:
- raise ValueError(
- "Coherence is calculated by averaging over *NFFT* length "
- "segments. Your signal is too short for your choice of *NFFT*.")
- Pxx, f = psd(x, NFFT, Fs, detrend, window, noverlap, pad_to, sides,
- scale_by_freq)
- Pyy, f = psd(y, NFFT, Fs, detrend, window, noverlap, pad_to, sides,
- scale_by_freq)
- Pxy, f = csd(x, y, NFFT, Fs, detrend, window, noverlap, pad_to, sides,
- scale_by_freq)
- Cxy = np.abs(Pxy) ** 2 / (Pxx * Pyy)
- return Cxy, f
-
-
-class GaussianKDE:
- """
- Representation of a kernel-density estimate using Gaussian kernels.
-
- Parameters
- ----------
- dataset : array-like
- Datapoints to estimate from. In case of univariate data this is a 1-D
- array, otherwise a 2D array with shape (# of dims, # of data).
- bw_method : str, scalar or callable, optional
- The method used to calculate the estimator bandwidth. This can be
- 'scott', 'silverman', a scalar constant or a callable. If a
- scalar, this will be used directly as `kde.factor`. If a
- callable, it should take a `GaussianKDE` instance as only
- parameter and return a scalar. If None (default), 'scott' is used.
-
- Attributes
- ----------
- dataset : ndarray
- The dataset passed to the constructor.
- dim : int
- Number of dimensions.
- num_dp : int
- Number of datapoints.
- factor : float
- The bandwidth factor, obtained from `kde.covariance_factor`, with which
- the covariance matrix is multiplied.
- covariance : ndarray
- The covariance matrix of *dataset*, scaled by the calculated bandwidth
- (`kde.factor`).
- inv_cov : ndarray
- The inverse of *covariance*.
-
- Methods
- -------
- kde.evaluate(points) : ndarray
- Evaluate the estimated pdf on a provided set of points.
- kde(points) : ndarray
- Same as kde.evaluate(points)
- """
-
- # This implementation with minor modification was too good to pass up.
- # from scipy: https://github.com/scipy/scipy/blob/master/scipy/stats/kde.py
-
- def __init__(self, dataset, bw_method=None):
- self.dataset = np.atleast_2d(dataset)
- if not np.array(self.dataset).size > 1:
- raise ValueError("`dataset` input should have multiple elements.")
-
- self.dim, self.num_dp = np.array(self.dataset).shape
-
- if bw_method is None:
- pass
- elif cbook._str_equal(bw_method, 'scott'):
- self.covariance_factor = self.scotts_factor
- elif cbook._str_equal(bw_method, 'silverman'):
- self.covariance_factor = self.silverman_factor
- elif isinstance(bw_method, Number):
- self._bw_method = 'use constant'
- self.covariance_factor = lambda: bw_method
- elif callable(bw_method):
- self._bw_method = bw_method
- self.covariance_factor = lambda: self._bw_method(self)
- else:
- raise ValueError("`bw_method` should be 'scott', 'silverman', a "
- "scalar or a callable")
-
- # Computes the covariance matrix for each Gaussian kernel using
- # covariance_factor().
-
- self.factor = self.covariance_factor()
- # Cache covariance and inverse covariance of the data
- if not hasattr(self, '_data_inv_cov'):
- self.data_covariance = np.atleast_2d(
- np.cov(
- self.dataset,
- rowvar=1,
- bias=False))
- self.data_inv_cov = np.linalg.inv(self.data_covariance)
-
- self.covariance = self.data_covariance * self.factor ** 2
- self.inv_cov = self.data_inv_cov / self.factor ** 2
- self.norm_factor = (np.sqrt(np.linalg.det(2 * np.pi * self.covariance))
- * self.num_dp)
-
- def scotts_factor(self):
- return np.power(self.num_dp, -1. / (self.dim + 4))
-
- def silverman_factor(self):
- return np.power(
- self.num_dp * (self.dim + 2.0) / 4.0, -1. / (self.dim + 4))
-
- # Default method to calculate bandwidth, can be overwritten by subclass
- covariance_factor = scotts_factor
-
- def evaluate(self, points):
- """
- Evaluate the estimated pdf on a set of points.
-
- Parameters
- ----------
- points : (# of dimensions, # of points)-array
- Alternatively, a (# of dimensions,) vector can be passed in and
- treated as a single point.
-
- Returns
- -------
- (# of points,)-array
- The values at each point.
-
- Raises
- ------
- ValueError : if the dimensionality of the input points is different
- than the dimensionality of the KDE.
-
- """
- points = np.atleast_2d(points)
-
- dim, num_m = np.array(points).shape
- if dim != self.dim:
- raise ValueError(f"points have dimension {dim}, dataset has "
- f"dimension {self.dim}")
-
- result = np.zeros(num_m)
-
- if num_m >= self.num_dp:
- # there are more points than data, so loop over data
- for i in range(self.num_dp):
- diff = self.dataset[:, i, np.newaxis] - points
- tdiff = np.dot(self.inv_cov, diff)
- energy = np.sum(diff * tdiff, axis=0) / 2.0
- result = result + np.exp(-energy)
- else:
- # loop over points
- for i in range(num_m):
- diff = self.dataset - points[:, i, np.newaxis]
- tdiff = np.dot(self.inv_cov, diff)
- energy = np.sum(diff * tdiff, axis=0) / 2.0
- result[i] = np.sum(np.exp(-energy), axis=0)
-
- result = result / self.norm_factor
-
- return result
-
- __call__ = evaluate
diff --git a/contrib/python/matplotlib/py3/matplotlib/mlab.pyi b/contrib/python/matplotlib/py3/matplotlib/mlab.pyi
deleted file mode 100644
index 1f23288dd1..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mlab.pyi
+++ /dev/null
@@ -1,100 +0,0 @@
-from collections.abc import Callable
-import functools
-from typing import Literal
-
-import numpy as np
-from numpy.typing import ArrayLike
-
-def window_hanning(x: ArrayLike) -> ArrayLike: ...
-def window_none(x: ArrayLike) -> ArrayLike: ...
-def detrend(
- x: ArrayLike,
- key: Literal["default", "constant", "mean", "linear", "none"]
- | Callable[[ArrayLike, int | None], ArrayLike]
- | None = ...,
- axis: int | None = ...,
-) -> ArrayLike: ...
-def detrend_mean(x: ArrayLike, axis: int | None = ...) -> ArrayLike: ...
-def detrend_none(x: ArrayLike, axis: int | None = ...) -> ArrayLike: ...
-def detrend_linear(y: ArrayLike) -> ArrayLike: ...
-def psd(
- x: ArrayLike,
- NFFT: int | None = ...,
- Fs: float | None = ...,
- detrend: Literal["none", "mean", "linear"]
- | Callable[[ArrayLike, int | None], ArrayLike]
- | None = ...,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = ...,
- noverlap: int | None = ...,
- pad_to: int | None = ...,
- sides: Literal["default", "onesided", "twosided"] | None = ...,
- scale_by_freq: bool | None = ...,
-) -> tuple[ArrayLike, ArrayLike]: ...
-def csd(
- x: ArrayLike,
- y: ArrayLike | None,
- NFFT: int | None = ...,
- Fs: float | None = ...,
- detrend: Literal["none", "mean", "linear"]
- | Callable[[ArrayLike, int | None], ArrayLike]
- | None = ...,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = ...,
- noverlap: int | None = ...,
- pad_to: int | None = ...,
- sides: Literal["default", "onesided", "twosided"] | None = ...,
- scale_by_freq: bool | None = ...,
-) -> tuple[ArrayLike, ArrayLike]: ...
-
-complex_spectrum = functools.partial(tuple[ArrayLike, ArrayLike])
-magnitude_spectrum = functools.partial(tuple[ArrayLike, ArrayLike])
-angle_spectrum = functools.partial(tuple[ArrayLike, ArrayLike])
-phase_spectrum = functools.partial(tuple[ArrayLike, ArrayLike])
-
-def specgram(
- x: ArrayLike,
- NFFT: int | None = ...,
- Fs: float | None = ...,
- detrend: Literal["none", "mean", "linear"] | Callable[[ArrayLike, int | None], ArrayLike] | None = ...,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = ...,
- noverlap: int | None = ...,
- pad_to: int | None = ...,
- sides: Literal["default", "onesided", "twosided"] | None = ...,
- scale_by_freq: bool | None = ...,
- mode: Literal["psd", "complex", "magnitude", "angle", "phase"] | None = ...,
-) -> tuple[ArrayLike, ArrayLike, ArrayLike]: ...
-def cohere(
- x: ArrayLike,
- y: ArrayLike,
- NFFT: int = ...,
- Fs: float = ...,
- detrend: Literal["none", "mean", "linear"] | Callable[[ArrayLike, int | None], ArrayLike] = ...,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike = ...,
- noverlap: int = ...,
- pad_to: int | None = ...,
- sides: Literal["default", "onesided", "twosided"] = ...,
- scale_by_freq: bool | None = ...,
-) -> tuple[ArrayLike, ArrayLike]: ...
-
-class GaussianKDE:
- dataset: ArrayLike
- dim: int
- num_dp: int
- factor: float
- data_covariance: ArrayLike
- data_inv_cov: ArrayLike
- covariance: ArrayLike
- inv_cov: ArrayLike
- norm_factor: float
- def __init__(
- self,
- dataset: ArrayLike,
- bw_method: Literal["scott", "silverman"]
- | float
- | Callable[[GaussianKDE], float]
- | None = ...,
- ) -> None: ...
- def scotts_factor(self) -> float: ...
- def silverman_factor(self) -> float: ...
- def covariance_factor(self) -> float: ...
- def evaluate(self, points: ArrayLike) -> np.ndarray: ...
- def __call__(self, points: ArrayLike) -> np.ndarray: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmex10.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmex10.afm
deleted file mode 100644
index b9e318ff7f..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmex10.afm
+++ /dev/null
@@ -1,220 +0,0 @@
-StartFontMetrics 2.0
-Comment Creation Date: Thu Jun 21 22:23:20 1990
-Comment UniqueID 5000774
-FontName CMEX10
-EncodingScheme FontSpecific
-FullName CMEX10
-FamilyName Computer Modern
-Weight Medium
-ItalicAngle 0
-IsFixedPitch false
-Version 1.00
-Notice Copyright (c) 1997 American Mathematical Society. All Rights Reserved.
-Comment Computer Modern fonts were designed by Donald E. Knuth
-FontBBox -24 -2960 1454 772
-XHeight 430.556
-Comment CapHeight 0
-Ascender 750
-Comment Descender -1760
-Descender -2960
-Comment FontID CMEX
-Comment DesignSize 10 (pts)
-Comment CharacterCodingScheme TeX math extension
-Comment Space 0 0 0
-Comment ExtraSpace 0
-Comment Quad 1000
-Comment DefaultRuleThickness 40
-Comment BigOpSpacing 111.111 166.667 200 600 100
-Comment Ascendible characters (74) % macro - PS charname
-Comment Ascending 0, 16, 18, 32, 48 % ( - parenleft
-Comment Ascending 1, 17, 19, 33, 49 % ) - parenright
-Comment Ascending 2, 104, 20, 34, 50 % [ - bracketleft
-Comment Ascending 3, 105, 21, 35, 51 % ] - bracketright
-Comment Ascending 4, 106, 22, 36, 52 % lfloor - floorleft
-Comment Ascending 5, 107, 23, 37, 53 % rfloor - floorright
-Comment Ascending 6, 108, 24, 38, 54 % lceil - ceilingleft
-Comment Ascending 7, 109, 25, 39, 55 % rceil - ceilingright
-Comment Ascending 8, 110, 26, 40, 56 % { - braceleft
-Comment Ascending 9, 111, 27, 41, 57 % } - braceright
-Comment Ascending 10, 68, 28, 42 % < - anglebracketleft
-Comment Ascending 11, 69, 29, 43 % > - anglebracketright
-Comment Ascending 14, 46, 30, 44 % / - slash
-Comment Ascending 15, 47, 31, 45 % \ - backslash
-Comment Ascending 70, 71 % bigsqcup - unionsq
-Comment Ascending 72, 73 % oint - contintegral
-Comment Ascending 74, 75 % bigodot - circledot
-Comment Ascending 76, 77 % bigoplus - circleplus
-Comment Ascending 78, 79 % bigotimes - circlemultiply
-Comment Ascending 80, 88 % sum - summation
-Comment Ascending 81, 89 % prod - product
-Comment Ascending 82, 90 % int - integral
-Comment Ascending 83, 91 % bigcup - union
-Comment Ascending 84, 92 % bigcap - intersection
-Comment Ascending 85, 93 % biguplus - unionmulti
-Comment Ascending 86, 94 % bigwedge - logicaland
-Comment Ascending 87, 95 % bigvee - logicalor
-Comment Ascending 96, 97 % coprod - coproduct
-Comment Ascending 98, 99, 100 % widehat - hatwide
-Comment Ascending 101, 102, 103 % widetilde - tildewide
-Comment Ascending 112, 113, 114, 115, 116 % radical - sqrt
-Comment Extensible characters (28)
-Comment Extensible 12 top 0 mid 0 bot 0 rep 12 % vert - thin bar
-Comment Extensible 13 top 0 mid 0 bot 0 rep 13 % Vert - thin double bar
-Comment Extensible 48 top 48 mid 0 bot 64 rep 66 % ( - parenleft
-Comment Extensible 49 top 49 mid 0 bot 65 rep 67 % ) - parenright
-Comment Extensible 50 top 50 mid 0 bot 52 rep 54 % [ - bracketleft
-Comment Extensible 51 top 51 mid 0 bot 53 rep 55 % ] - bracketright
-Comment Extensible 52 top 0 mid 0 bot 52 rep 54 % lfloor - floorleft
-Comment Extensible 53 top 0 mid 0 bot 53 rep 55 % rfloor - floorright
-Comment Extensible 54 top 50 mid 0 bot 0 rep 54 % lceil - ceilingleft
-Comment Extensible 55 top 51 mid 0 bot 0 rep 55 % rceil - ceilingright
-Comment Extensible 56 top 56 mid 60 bot 58 rep 62 % { - braceleft
-Comment Extensible 57 top 57 mid 61 bot 59 rep 62 % } - braceright
-Comment Extensible 58 top 56 mid 0 bot 58 rep 62 % lgroup
-Comment Extensible 59 top 57 mid 0 bot 59 rep 62 % rgroup
-Comment Extensible 60 top 0 mid 0 bot 0 rep 63 % arrowvert
-Comment Extensible 61 top 0 mid 0 bot 0 rep 119 % Arrowvert
-Comment Extensible 62 top 0 mid 0 bot 0 rep 62 % bracevert
-Comment Extensible 63 top 120 mid 0 bot 121 rep 63 % updownarrow
-Comment Extensible 64 top 56 mid 0 bot 59 rep 62 % lmoustache
-Comment Extensible 65 top 57 mid 0 bot 58 rep 62 % rmoustache
-Comment Extensible 66 top 0 mid 0 bot 0 rep 66 % parenleftexten
-Comment Extensible 67 top 0 mid 0 bot 0 rep 67 % parenrightexten
-Comment Extensible 116 top 118 mid 0 bot 116 rep 117 % radical
-Comment Extensible 119 top 126 mid 0 bot 127 rep 119 % Updownarrow
-Comment Extensible 120 top 120 mid 0 bot 0 rep 63 % uparrow
-Comment Extensible 121 top 0 mid 0 bot 121 rep 63 % downarrow
-Comment Extensible 126 top 126 mid 0 bot 0 rep 119 % Uparrow
-Comment Extensible 127 top 0 mid 0 bot 127 rep 119 % Downarrow
-StartCharMetrics 129
-C 0 ; WX 458.333 ; N parenleftbig ; B 152 -1159 413 40 ;
-C 1 ; WX 458.333 ; N parenrightbig ; B 44 -1159 305 40 ;
-C 2 ; WX 416.667 ; N bracketleftbig ; B 202 -1159 394 40 ;
-C 3 ; WX 416.667 ; N bracketrightbig ; B 22 -1159 214 40 ;
-C 4 ; WX 472.222 ; N floorleftbig ; B 202 -1159 449 40 ;
-C 5 ; WX 472.222 ; N floorrightbig ; B 22 -1159 269 40 ;
-C 6 ; WX 472.222 ; N ceilingleftbig ; B 202 -1159 449 40 ;
-C 7 ; WX 472.222 ; N ceilingrightbig ; B 22 -1159 269 40 ;
-C 8 ; WX 583.333 ; N braceleftbig ; B 113 -1159 469 40 ;
-C 9 ; WX 583.333 ; N bracerightbig ; B 113 -1159 469 40 ;
-C 10 ; WX 472.222 ; N angbracketleftbig ; B 98 -1160 393 40 ;
-C 11 ; WX 472.222 ; N angbracketrightbig ; B 78 -1160 373 40 ;
-C 12 ; WX 333.333 ; N vextendsingle ; B 145 -621 188 21 ;
-C 13 ; WX 555.556 ; N vextenddouble ; B 145 -621 410 21 ;
-C 14 ; WX 577.778 ; N slashbig ; B 56 -1159 521 40 ;
-C 15 ; WX 577.778 ; N backslashbig ; B 56 -1159 521 40 ;
-C 16 ; WX 597.222 ; N parenleftBig ; B 180 -1759 560 40 ;
-C 17 ; WX 597.222 ; N parenrightBig ; B 36 -1759 416 40 ;
-C 18 ; WX 736.111 ; N parenleftbigg ; B 208 -2359 700 40 ;
-C 19 ; WX 736.111 ; N parenrightbigg ; B 35 -2359 527 40 ;
-C 20 ; WX 527.778 ; N bracketleftbigg ; B 250 -2359 513 40 ;
-C 21 ; WX 527.778 ; N bracketrightbigg ; B 14 -2359 277 40 ;
-C 22 ; WX 583.333 ; N floorleftbigg ; B 250 -2359 568 40 ;
-C 23 ; WX 583.333 ; N floorrightbigg ; B 14 -2359 332 40 ;
-C 24 ; WX 583.333 ; N ceilingleftbigg ; B 250 -2359 568 40 ;
-C 25 ; WX 583.333 ; N ceilingrightbigg ; B 14 -2359 332 40 ;
-C 26 ; WX 750 ; N braceleftbigg ; B 131 -2359 618 40 ;
-C 27 ; WX 750 ; N bracerightbigg ; B 131 -2359 618 40 ;
-C 28 ; WX 750 ; N angbracketleftbigg ; B 125 -2359 652 40 ;
-C 29 ; WX 750 ; N angbracketrightbigg ; B 97 -2359 624 40 ;
-C 30 ; WX 1044.44 ; N slashbigg ; B 56 -2359 987 40 ;
-C 31 ; WX 1044.44 ; N backslashbigg ; B 56 -2359 987 40 ;
-C 32 ; WX 791.667 ; N parenleftBigg ; B 236 -2959 757 40 ;
-C 33 ; WX 791.667 ; N parenrightBigg ; B 34 -2959 555 40 ;
-C 34 ; WX 583.333 ; N bracketleftBigg ; B 275 -2959 571 40 ;
-C 35 ; WX 583.333 ; N bracketrightBigg ; B 11 -2959 307 40 ;
-C 36 ; WX 638.889 ; N floorleftBigg ; B 275 -2959 627 40 ;
-C 37 ; WX 638.889 ; N floorrightBigg ; B 11 -2959 363 40 ;
-C 38 ; WX 638.889 ; N ceilingleftBigg ; B 275 -2959 627 40 ;
-C 39 ; WX 638.889 ; N ceilingrightBigg ; B 11 -2959 363 40 ;
-C 40 ; WX 805.556 ; N braceleftBigg ; B 144 -2959 661 40 ;
-C 41 ; WX 805.556 ; N bracerightBigg ; B 144 -2959 661 40 ;
-C 42 ; WX 805.556 ; N angbracketleftBigg ; B 139 -2960 697 40 ;
-C 43 ; WX 805.556 ; N angbracketrightBigg ; B 108 -2960 666 40 ;
-C 44 ; WX 1277.78 ; N slashBigg ; B 56 -2959 1221 40 ;
-C 45 ; WX 1277.78 ; N backslashBigg ; B 56 -2959 1221 40 ;
-C 46 ; WX 811.111 ; N slashBig ; B 56 -1759 754 40 ;
-C 47 ; WX 811.111 ; N backslashBig ; B 56 -1759 754 40 ;
-C 48 ; WX 875 ; N parenlefttp ; B 291 -1770 842 39 ;
-C 49 ; WX 875 ; N parenrighttp ; B 32 -1770 583 39 ;
-C 50 ; WX 666.667 ; N bracketlefttp ; B 326 -1760 659 39 ;
-C 51 ; WX 666.667 ; N bracketrighttp ; B 7 -1760 340 39 ;
-C 52 ; WX 666.667 ; N bracketleftbt ; B 326 -1759 659 40 ;
-C 53 ; WX 666.667 ; N bracketrightbt ; B 7 -1759 340 40 ;
-C 54 ; WX 666.667 ; N bracketleftex ; B 326 -601 395 1 ;
-C 55 ; WX 666.667 ; N bracketrightex ; B 271 -601 340 1 ;
-C 56 ; WX 888.889 ; N bracelefttp ; B 384 -910 718 -1 ;
-C 57 ; WX 888.889 ; N bracerighttp ; B 170 -910 504 -1 ;
-C 58 ; WX 888.889 ; N braceleftbt ; B 384 -899 718 10 ;
-C 59 ; WX 888.889 ; N bracerightbt ; B 170 -899 504 10 ;
-C 60 ; WX 888.889 ; N braceleftmid ; B 170 -1810 504 10 ;
-C 61 ; WX 888.889 ; N bracerightmid ; B 384 -1810 718 10 ;
-C 62 ; WX 888.889 ; N braceex ; B 384 -310 504 10 ;
-C 63 ; WX 666.667 ; N arrowvertex ; B 312 -601 355 1 ;
-C 64 ; WX 875 ; N parenleftbt ; B 291 -1759 842 50 ;
-C 65 ; WX 875 ; N parenrightbt ; B 32 -1759 583 50 ;
-C 66 ; WX 875 ; N parenleftex ; B 291 -610 402 10 ;
-C 67 ; WX 875 ; N parenrightex ; B 472 -610 583 10 ;
-C 68 ; WX 611.111 ; N angbracketleftBig ; B 112 -1759 522 40 ;
-C 69 ; WX 611.111 ; N angbracketrightBig ; B 88 -1759 498 40 ;
-C 70 ; WX 833.333 ; N unionsqtext ; B 56 -1000 776 0 ;
-C 71 ; WX 1111.11 ; N unionsqdisplay ; B 56 -1400 1054 0 ;
-C 72 ; WX 472.222 ; N contintegraltext ; B 56 -1111 609 0 ;
-C 73 ; WX 555.556 ; N contintegraldisplay ; B 56 -2222 943 0 ;
-C 74 ; WX 1111.11 ; N circledottext ; B 56 -1000 1054 0 ;
-C 75 ; WX 1511.11 ; N circledotdisplay ; B 56 -1400 1454 0 ;
-C 76 ; WX 1111.11 ; N circleplustext ; B 56 -1000 1054 0 ;
-C 77 ; WX 1511.11 ; N circleplusdisplay ; B 56 -1400 1454 0 ;
-C 78 ; WX 1111.11 ; N circlemultiplytext ; B 56 -1000 1054 0 ;
-C 79 ; WX 1511.11 ; N circlemultiplydisplay ; B 56 -1400 1454 0 ;
-C 80 ; WX 1055.56 ; N summationtext ; B 56 -1000 999 0 ;
-C 81 ; WX 944.444 ; N producttext ; B 56 -1000 887 0 ;
-C 82 ; WX 472.222 ; N integraltext ; B 56 -1111 609 0 ;
-C 83 ; WX 833.333 ; N uniontext ; B 56 -1000 776 0 ;
-C 84 ; WX 833.333 ; N intersectiontext ; B 56 -1000 776 0 ;
-C 85 ; WX 833.333 ; N unionmultitext ; B 56 -1000 776 0 ;
-C 86 ; WX 833.333 ; N logicalandtext ; B 56 -1000 776 0 ;
-C 87 ; WX 833.333 ; N logicalortext ; B 56 -1000 776 0 ;
-C 88 ; WX 1444.44 ; N summationdisplay ; B 56 -1400 1387 0 ;
-C 89 ; WX 1277.78 ; N productdisplay ; B 56 -1400 1221 0 ;
-C 90 ; WX 555.556 ; N integraldisplay ; B 56 -2222 943 0 ;
-C 91 ; WX 1111.11 ; N uniondisplay ; B 56 -1400 1054 0 ;
-C 92 ; WX 1111.11 ; N intersectiondisplay ; B 56 -1400 1054 0 ;
-C 93 ; WX 1111.11 ; N unionmultidisplay ; B 56 -1400 1054 0 ;
-C 94 ; WX 1111.11 ; N logicalanddisplay ; B 56 -1400 1054 0 ;
-C 95 ; WX 1111.11 ; N logicalordisplay ; B 56 -1400 1054 0 ;
-C 96 ; WX 944.444 ; N coproducttext ; B 56 -1000 887 0 ;
-C 97 ; WX 1277.78 ; N coproductdisplay ; B 56 -1400 1221 0 ;
-C 98 ; WX 555.556 ; N hatwide ; B -5 562 561 744 ;
-C 99 ; WX 1000 ; N hatwider ; B -4 575 1003 772 ;
-C 100 ; WX 1444.44 ; N hatwidest ; B -3 575 1446 772 ;
-C 101 ; WX 555.556 ; N tildewide ; B 0 608 555 722 ;
-C 102 ; WX 1000 ; N tildewider ; B 0 624 999 750 ;
-C 103 ; WX 1444.44 ; N tildewidest ; B 0 623 1443 750 ;
-C 104 ; WX 472.222 ; N bracketleftBig ; B 226 -1759 453 40 ;
-C 105 ; WX 472.222 ; N bracketrightBig ; B 18 -1759 245 40 ;
-C 106 ; WX 527.778 ; N floorleftBig ; B 226 -1759 509 40 ;
-C 107 ; WX 527.778 ; N floorrightBig ; B 18 -1759 301 40 ;
-C 108 ; WX 527.778 ; N ceilingleftBig ; B 226 -1759 509 40 ;
-C 109 ; WX 527.778 ; N ceilingrightBig ; B 18 -1759 301 40 ;
-C 110 ; WX 666.667 ; N braceleftBig ; B 119 -1759 547 40 ;
-C 111 ; WX 666.667 ; N bracerightBig ; B 119 -1759 547 40 ;
-C 112 ; WX 1000 ; N radicalbig ; B 110 -1160 1020 40 ;
-C 113 ; WX 1000 ; N radicalBig ; B 110 -1760 1020 40 ;
-C 114 ; WX 1000 ; N radicalbigg ; B 111 -2360 1020 40 ;
-C 115 ; WX 1000 ; N radicalBigg ; B 111 -2960 1020 40 ;
-C 116 ; WX 1055.56 ; N radicalbt ; B 111 -1800 742 20 ;
-C 117 ; WX 1055.56 ; N radicalvertex ; B 702 -620 742 20 ;
-C 118 ; WX 1055.56 ; N radicaltp ; B 702 -580 1076 40 ;
-C 119 ; WX 777.778 ; N arrowvertexdbl ; B 257 -601 521 1 ;
-C 120 ; WX 666.667 ; N arrowtp ; B 111 -600 556 0 ;
-C 121 ; WX 666.667 ; N arrowbt ; B 111 -600 556 0 ;
-C 122 ; WX 450 ; N bracehtipdownleft ; B -24 -214 460 120 ;
-C 123 ; WX 450 ; N bracehtipdownright ; B -10 -214 474 120 ;
-C 124 ; WX 450 ; N bracehtipupleft ; B -24 0 460 334 ;
-C 125 ; WX 450 ; N bracehtipupright ; B -10 0 474 334 ;
-C 126 ; WX 777.778 ; N arrowdbltp ; B 56 -600 722 -1 ;
-C 127 ; WX 777.778 ; N arrowdblbt ; B 56 -599 722 0 ;
-C -1 ; WX 333.333 ; N space ; B 0 0 0 0 ;
-EndCharMetrics
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmmi10.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmmi10.afm
deleted file mode 100644
index f47d6ba04d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmmi10.afm
+++ /dev/null
@@ -1,326 +0,0 @@
-StartFontMetrics 2.0
-Comment Creation Date: Thu Jun 21 22:23:22 1990
-Comment UniqueID 5000785
-FontName CMMI10
-EncodingScheme FontSpecific
-FullName CMMI10
-FamilyName Computer Modern
-Weight Medium
-ItalicAngle -14.04
-IsFixedPitch false
-Version 1.00A
-Notice Copyright (c) 1997 American Mathematical Society. All Rights Reserved.
-Comment Computer Modern fonts were designed by Donald E. Knuth
-FontBBox -32 -250 1048 750
-CapHeight 683.333
-XHeight 430.556
-Ascender 694.444
-Descender -194.444
-Comment FontID CMMI
-Comment DesignSize 10 (pts)
-Comment CharacterCodingScheme TeX math italic
-Comment Space 0 0 0
-Comment Quad 1000
-StartCharMetrics 129
-C 0 ; WX 615.276 ; N Gamma ; B 39 0 723 680 ;
-C 1 ; WX 833.333 ; N Delta ; B 49 0 787 716 ;
-C 2 ; WX 762.774 ; N Theta ; B 50 -22 739 705 ;
-C 3 ; WX 694.444 ; N Lambda ; B 35 0 666 716 ;
-C 4 ; WX 742.361 ; N Xi ; B 53 0 777 677 ;
-C 5 ; WX 831.25 ; N Pi ; B 39 0 880 680 ;
-C 6 ; WX 779.861 ; N Sigma ; B 59 0 807 683 ;
-C 7 ; WX 583.333 ; N Upsilon ; B 29 0 700 705 ;
-C 8 ; WX 666.667 ; N Phi ; B 24 0 642 683 ;
-C 9 ; WX 612.221 ; N Psi ; B 28 0 692 683 ;
-C 10 ; WX 772.396 ; N Omega ; B 80 0 785 705 ;
-C 11 ; WX 639.7 ; N alpha ; B 41 -11 601 442 ;
-C 12 ; WX 565.625 ; N beta ; B 25 -194 590 705 ;
-C 13 ; WX 517.73 ; N gamma ; B 18 -215 542 442 ;
-C 14 ; WX 444.444 ; N delta ; B 41 -12 452 705 ;
-C 15 ; WX 405.902 ; N epsilon1 ; B 47 -11 376 431 ;
-C 16 ; WX 437.5 ; N zeta ; B 47 -205 474 697 ;
-C 17 ; WX 496.53 ; N eta ; B 29 -216 496 442 ;
-C 18 ; WX 469.442 ; N theta ; B 42 -11 455 705 ;
-C 19 ; WX 353.935 ; N iota ; B 56 -11 324 442 ;
-C 20 ; WX 576.159 ; N kappa ; B 55 -11 546 442 ;
-C 21 ; WX 583.333 ; N lambda ; B 53 -13 547 694 ;
-C 22 ; WX 602.548 ; N mu ; B 30 -216 572 442 ;
-C 23 ; WX 493.981 ; N nu ; B 53 0 524 442 ;
-C 24 ; WX 437.5 ; N xi ; B 24 -205 446 697 ;
-C 25 ; WX 570.025 ; N pi ; B 27 -11 567 431 ;
-C 26 ; WX 517.014 ; N rho ; B 30 -216 502 442 ;
-C 27 ; WX 571.429 ; N sigma ; B 38 -11 567 431 ;
-C 28 ; WX 437.153 ; N tau ; B 27 -12 511 431 ;
-C 29 ; WX 540.278 ; N upsilon ; B 29 -11 524 443 ;
-C 30 ; WX 595.833 ; N phi ; B 49 -205 573 694 ;
-C 31 ; WX 625.691 ; N chi ; B 32 -205 594 442 ;
-C 32 ; WX 651.39 ; N psi ; B 29 -205 635 694 ;
-C 33 ; WX 622.453 ; N omega ; B 13 -11 605 443 ;
-C 34 ; WX 466.316 ; N epsilon ; B 27 -22 428 453 ;
-C 35 ; WX 591.438 ; N theta1 ; B 29 -11 561 705 ;
-C 36 ; WX 828.125 ; N pi1 ; B 27 -11 817 431 ;
-C 37 ; WX 517.014 ; N rho1 ; B 74 -194 502 442 ;
-C 38 ; WX 362.846 ; N sigma1 ; B 32 -108 408 442 ;
-C 39 ; WX 654.165 ; N phi1 ; B 50 -218 619 442 ;
-C 40 ; WX 1000 ; N arrowlefttophalf ; B 56 230 943 428 ;
-C 41 ; WX 1000 ; N arrowleftbothalf ; B 56 72 943 270 ;
-C 42 ; WX 1000 ; N arrowrighttophalf ; B 56 230 943 428 ;
-C 43 ; WX 1000 ; N arrowrightbothalf ; B 56 72 943 270 ;
-C 44 ; WX 277.778 ; N arrowhookleft ; B 56 230 221 464 ;
-C 45 ; WX 277.778 ; N arrowhookright ; B 56 230 221 464 ;
-C 46 ; WX 500 ; N triangleright ; B 27 -4 472 504 ;
-C 47 ; WX 500 ; N triangleleft ; B 27 -4 472 504 ;
-C 48 ; WX 500 ; N zerooldstyle ; B 40 -22 459 453 ;
-C 49 ; WX 500 ; N oneoldstyle ; B 92 0 418 453 ;
-C 50 ; WX 500 ; N twooldstyle ; B 44 0 449 453 ;
-C 51 ; WX 500 ; N threeoldstyle ; B 42 -216 457 453 ;
-C 52 ; WX 500 ; N fouroldstyle ; B 28 -194 471 464 ;
-C 53 ; WX 500 ; N fiveoldstyle ; B 50 -216 449 453 ;
-C 54 ; WX 500 ; N sixoldstyle ; B 42 -22 457 666 ;
-C 55 ; WX 500 ; N sevenoldstyle ; B 56 -216 485 463 ;
-C 56 ; WX 500 ; N eightoldstyle ; B 42 -22 457 666 ;
-C 57 ; WX 500 ; N nineoldstyle ; B 42 -216 457 453 ;
-C 58 ; WX 277.778 ; N period ; B 86 0 192 106 ;
-C 59 ; WX 277.778 ; N comma ; B 86 -193 203 106 ;
-C 60 ; WX 777.778 ; N less ; B 83 -39 694 539 ;
-C 61 ; WX 500 ; N slash ; B 56 -250 443 750 ;
-C 62 ; WX 777.778 ; N greater ; B 83 -39 694 539 ;
-C 63 ; WX 500 ; N star ; B 4 16 496 486 ;
-C 64 ; WX 530.902 ; N partialdiff ; B 40 -22 566 716 ;
-C 65 ; WX 750 ; N A ; B 35 0 722 716 ;
-C 66 ; WX 758.508 ; N B ; B 42 0 756 683 ;
-C 67 ; WX 714.72 ; N C ; B 51 -22 759 705 ;
-C 68 ; WX 827.915 ; N D ; B 41 0 803 683 ;
-C 69 ; WX 738.193 ; N E ; B 39 0 765 680 ;
-C 70 ; WX 643.055 ; N F ; B 39 0 751 680 ;
-C 71 ; WX 786.247 ; N G ; B 51 -22 760 705 ;
-C 72 ; WX 831.25 ; N H ; B 39 0 881 683 ;
-C 73 ; WX 439.583 ; N I ; B 34 0 498 683 ;
-C 74 ; WX 554.512 ; N J ; B 73 -22 633 683 ;
-C 75 ; WX 849.305 ; N K ; B 39 0 889 683 ;
-C 76 ; WX 680.556 ; N L ; B 39 0 643 683 ;
-C 77 ; WX 970.138 ; N M ; B 43 0 1044 683 ;
-C 78 ; WX 803.471 ; N N ; B 39 0 881 683 ;
-C 79 ; WX 762.774 ; N O ; B 50 -22 739 705 ;
-C 80 ; WX 642.012 ; N P ; B 41 0 753 683 ;
-C 81 ; WX 790.553 ; N Q ; B 50 -194 739 705 ;
-C 82 ; WX 759.288 ; N R ; B 41 -22 755 683 ;
-C 83 ; WX 613.193 ; N S ; B 53 -22 645 705 ;
-C 84 ; WX 584.375 ; N T ; B 24 0 704 677 ;
-C 85 ; WX 682.776 ; N U ; B 68 -22 760 683 ;
-C 86 ; WX 583.333 ; N V ; B 56 -22 769 683 ;
-C 87 ; WX 944.444 ; N W ; B 55 -22 1048 683 ;
-C 88 ; WX 828.472 ; N X ; B 27 0 851 683 ;
-C 89 ; WX 580.556 ; N Y ; B 34 0 762 683 ;
-C 90 ; WX 682.638 ; N Z ; B 59 0 722 683 ;
-C 91 ; WX 388.889 ; N flat ; B 56 -22 332 750 ;
-C 92 ; WX 388.889 ; N natural ; B 79 -217 309 728 ;
-C 93 ; WX 388.889 ; N sharp ; B 56 -216 332 716 ;
-C 94 ; WX 1000 ; N slurbelow ; B 56 133 943 371 ;
-C 95 ; WX 1000 ; N slurabove ; B 56 130 943 381 ;
-C 96 ; WX 416.667 ; N lscript ; B 11 -12 398 705 ;
-C 97 ; WX 528.588 ; N a ; B 40 -11 498 442 ;
-C 98 ; WX 429.165 ; N b ; B 47 -11 415 694 ;
-C 99 ; WX 432.755 ; N c ; B 41 -11 430 442 ;
-C 100 ; WX 520.486 ; N d ; B 40 -11 517 694 ;
-C 101 ; WX 465.625 ; N e ; B 46 -11 430 442 ;
-C 102 ; WX 489.583 ; N f ; B 53 -205 552 705 ;
-C 103 ; WX 476.967 ; N g ; B 16 -205 474 442 ;
-C 104 ; WX 576.159 ; N h ; B 55 -11 546 694 ;
-C 105 ; WX 344.511 ; N i ; B 29 -11 293 661 ;
-C 106 ; WX 411.805 ; N j ; B -13 -205 397 661 ;
-C 107 ; WX 520.602 ; N k ; B 55 -11 508 694 ;
-C 108 ; WX 298.378 ; N l ; B 46 -11 260 694 ;
-C 109 ; WX 878.012 ; N m ; B 29 -11 848 442 ;
-C 110 ; WX 600.233 ; N n ; B 29 -11 571 442 ;
-C 111 ; WX 484.721 ; N o ; B 41 -11 469 442 ;
-C 112 ; WX 503.125 ; N p ; B -32 -194 490 442 ;
-C 113 ; WX 446.412 ; N q ; B 40 -194 453 442 ;
-C 114 ; WX 451.158 ; N r ; B 29 -11 436 442 ;
-C 115 ; WX 468.75 ; N s ; B 52 -11 419 442 ;
-C 116 ; WX 361.111 ; N t ; B 23 -11 330 626 ;
-C 117 ; WX 572.456 ; N u ; B 29 -11 543 442 ;
-C 118 ; WX 484.722 ; N v ; B 29 -11 468 443 ;
-C 119 ; WX 715.916 ; N w ; B 29 -11 691 443 ;
-C 120 ; WX 571.527 ; N x ; B 29 -11 527 442 ;
-C 121 ; WX 490.28 ; N y ; B 29 -205 490 442 ;
-C 122 ; WX 465.048 ; N z ; B 43 -11 467 442 ;
-C 123 ; WX 322.454 ; N dotlessi ; B 29 -11 293 442 ;
-C 124 ; WX 384.028 ; N dotlessj ; B -13 -205 360 442 ;
-C 125 ; WX 636.457 ; N weierstrass ; B 76 -216 618 453 ;
-C 126 ; WX 500 ; N vector ; B 182 516 625 714 ;
-C 127 ; WX 277.778 ; N tie ; B 264 538 651 665 ;
-C -1 ; WX 333.333 ; N space ; B 0 0 0 0 ;
-EndCharMetrics
-Comment The following are bogus kern pairs for TeX positioning of accents
-StartKernData
-StartKernPairs 166
-KPX Gamma slash -55.556
-KPX Gamma comma -111.111
-KPX Gamma period -111.111
-KPX Gamma tie 83.333
-KPX Delta tie 166.667
-KPX Theta tie 83.333
-KPX Lambda tie 166.667
-KPX Xi tie 83.333
-KPX Pi slash -55.556
-KPX Pi comma -55.556
-KPX Pi period -55.556
-KPX Pi tie 55.556
-KPX Sigma tie 83.333
-KPX Upsilon slash -55.556
-KPX Upsilon comma -111.111
-KPX Upsilon period -111.111
-KPX Upsilon tie 55.556
-KPX Phi tie 83.333
-KPX Psi slash -55.556
-KPX Psi comma -55.556
-KPX Psi period -55.556
-KPX Psi tie 55.556
-KPX Omega tie 83.333
-KPX alpha tie 27.778
-KPX beta tie 83.333
-KPX delta comma -55.556
-KPX delta period -55.556
-KPX delta tie 55.556
-KPX epsilon1 tie 55.556
-KPX zeta tie 83.333
-KPX eta tie 55.556
-KPX theta tie 83.333
-KPX iota tie 55.556
-KPX mu tie 27.778
-KPX nu comma -55.556
-KPX nu period -55.556
-KPX nu tie 27.778
-KPX xi tie 111.111
-KPX rho tie 83.333
-KPX sigma comma -55.556
-KPX sigma period -55.556
-KPX tau comma -55.556
-KPX tau period -55.556
-KPX tau tie 27.778
-KPX upsilon tie 27.778
-KPX phi tie 83.333
-KPX chi tie 55.556
-KPX psi tie 111.111
-KPX epsilon tie 83.333
-KPX theta1 tie 83.333
-KPX rho1 tie 83.333
-KPX sigma1 tie 83.333
-KPX phi1 tie 83.333
-KPX slash Delta -55.556
-KPX slash A -55.556
-KPX slash M -55.556
-KPX slash N -55.556
-KPX slash Y 55.556
-KPX slash Z -55.556
-KPX partialdiff tie 83.333
-KPX A tie 138.889
-KPX B tie 83.333
-KPX C slash -27.778
-KPX C comma -55.556
-KPX C period -55.556
-KPX C tie 83.333
-KPX D tie 55.556
-KPX E tie 83.333
-KPX F slash -55.556
-KPX F comma -111.111
-KPX F period -111.111
-KPX F tie 83.333
-KPX G tie 83.333
-KPX H slash -55.556
-KPX H comma -55.556
-KPX H period -55.556
-KPX H tie 55.556
-KPX I tie 111.111
-KPX J slash -55.556
-KPX J comma -111.111
-KPX J period -111.111
-KPX J tie 166.667
-KPX K slash -55.556
-KPX K comma -55.556
-KPX K period -55.556
-KPX K tie 55.556
-KPX L tie 27.778
-KPX M slash -55.556
-KPX M comma -55.556
-KPX M period -55.556
-KPX M tie 83.333
-KPX N slash -83.333
-KPX N slash -27.778
-KPX N comma -55.556
-KPX N period -55.556
-KPX N tie 83.333
-KPX O tie 83.333
-KPX P slash -55.556
-KPX P comma -111.111
-KPX P period -111.111
-KPX P tie 83.333
-KPX Q tie 83.333
-KPX R tie 83.333
-KPX S slash -55.556
-KPX S comma -55.556
-KPX S period -55.556
-KPX S tie 83.333
-KPX T slash -27.778
-KPX T comma -55.556
-KPX T period -55.556
-KPX T tie 83.333
-KPX U comma -111.111
-KPX U period -111.111
-KPX U slash -55.556
-KPX U tie 27.778
-KPX V comma -166.667
-KPX V period -166.667
-KPX V slash -111.111
-KPX W comma -166.667
-KPX W period -166.667
-KPX W slash -111.111
-KPX X slash -83.333
-KPX X slash -27.778
-KPX X comma -55.556
-KPX X period -55.556
-KPX X tie 83.333
-KPX Y comma -166.667
-KPX Y period -166.667
-KPX Y slash -111.111
-KPX Z slash -55.556
-KPX Z comma -55.556
-KPX Z period -55.556
-KPX Z tie 83.333
-KPX lscript tie 111.111
-KPX c tie 55.556
-KPX d Y 55.556
-KPX d Z -55.556
-KPX d j -111.111
-KPX d f -166.667
-KPX d tie 166.667
-KPX e tie 55.556
-KPX f comma -55.556
-KPX f period -55.556
-KPX f tie 166.667
-KPX g tie 27.778
-KPX h tie -27.778
-KPX j comma -55.556
-KPX j period -55.556
-KPX l tie 83.333
-KPX o tie 55.556
-KPX p tie 83.333
-KPX q tie 83.333
-KPX r comma -55.556
-KPX r period -55.556
-KPX r tie 55.556
-KPX s tie 55.556
-KPX t tie 83.333
-KPX u tie 27.778
-KPX v tie 27.778
-KPX w tie 83.333
-KPX x tie 27.778
-KPX y tie 55.556
-KPX z tie 55.556
-KPX dotlessi tie 27.778
-KPX dotlessj tie 83.333
-KPX weierstrass tie 111.111
-EndKernPairs
-EndKernData
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmr10.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmr10.afm
deleted file mode 100644
index 4d586fe6ff..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmr10.afm
+++ /dev/null
@@ -1,343 +0,0 @@
-StartFontMetrics 2.0
-Comment Creation Date: Thu Jun 21 22:23:28 1990
-Comment UniqueID 5000793
-FontName CMR10
-EncodingScheme FontSpecific
-FullName CMR10
-FamilyName Computer Modern
-Weight Medium
-ItalicAngle 0.0
-IsFixedPitch false
-Version 1.00B
-Notice Copyright (c) 1997 American Mathematical Society. All Rights Reserved.
-Comment Computer Modern fonts were designed by Donald E. Knuth
-FontBBox -40 -250 1009 969
-CapHeight 683.333
-XHeight 430.556
-Ascender 694.444
-Descender -194.444
-Comment FontID CMR
-Comment DesignSize 10 (pts)
-Comment CharacterCodingScheme TeX text
-Comment Space 333.333 166.667 111.111
-Comment ExtraSpace 111.111
-Comment Quad 1000
-StartCharMetrics 129
-C 0 ; WX 625 ; N Gamma ; B 33 0 582 680 ;
-C 1 ; WX 833.333 ; N Delta ; B 47 0 785 716 ;
-C 2 ; WX 777.778 ; N Theta ; B 56 -22 721 705 ;
-C 3 ; WX 694.444 ; N Lambda ; B 32 0 661 716 ;
-C 4 ; WX 666.667 ; N Xi ; B 42 0 624 677 ;
-C 5 ; WX 750 ; N Pi ; B 33 0 716 680 ;
-C 6 ; WX 722.222 ; N Sigma ; B 56 0 665 683 ;
-C 7 ; WX 777.778 ; N Upsilon ; B 56 0 721 705 ;
-C 8 ; WX 722.222 ; N Phi ; B 56 0 665 683 ;
-C 9 ; WX 777.778 ; N Psi ; B 57 0 720 683 ;
-C 10 ; WX 722.222 ; N Omega ; B 44 0 677 705 ;
-C 11 ; WX 583.333 ; N ff ; B 27 0 628 705 ; L i ffi ; L l ffl ;
-C 12 ; WX 555.556 ; N fi ; B 27 0 527 705 ;
-C 13 ; WX 555.556 ; N fl ; B 27 0 527 705 ;
-C 14 ; WX 833.333 ; N ffi ; B 27 0 804 705 ;
-C 15 ; WX 833.333 ; N ffl ; B 27 0 804 705 ;
-C 16 ; WX 277.778 ; N dotlessi ; B 33 0 247 442 ;
-C 17 ; WX 305.556 ; N dotlessj ; B -40 -205 210 442 ;
-C 18 ; WX 500 ; N grave ; B 107 510 293 698 ;
-C 19 ; WX 500 ; N acute ; B 206 510 392 698 ;
-C 20 ; WX 500 ; N caron ; B 118 516 381 638 ;
-C 21 ; WX 500 ; N breve ; B 100 522 399 694 ;
-C 22 ; WX 500 ; N macron ; B 69 559 430 590 ;
-C 23 ; WX 750 ; N ring ; B 279 541 470 716 ;
-C 24 ; WX 444.444 ; N cedilla ; B 131 -203 367 -22 ;
-C 25 ; WX 500 ; N germandbls ; B 28 -11 471 705 ;
-C 26 ; WX 722.222 ; N ae ; B 45 -11 693 448 ;
-C 27 ; WX 777.778 ; N oe ; B 28 -11 749 448 ;
-C 28 ; WX 500 ; N oslash ; B 35 -102 464 534 ;
-C 29 ; WX 902.778 ; N AE ; B 32 0 874 683 ;
-C 30 ; WX 1013.89 ; N OE ; B 70 -22 985 705 ;
-C 31 ; WX 777.778 ; N Oslash ; B 56 -56 721 739 ;
-C 32 ; WX 277.778 ; N suppress ; B 27 280 262 392 ;
-C 33 ; WX 277.778 ; N exclam ; B 86 0 192 716 ; L quoteleft exclamdown ;
-C 34 ; WX 500 ; N quotedblright ; B 33 395 347 694 ;
-C 35 ; WX 833.333 ; N numbersign ; B 56 -194 776 694 ;
-C 36 ; WX 500 ; N dollar ; B 56 -56 443 750 ;
-C 37 ; WX 833.333 ; N percent ; B 56 -56 776 750 ;
-C 38 ; WX 777.778 ; N ampersand ; B 42 -22 727 716 ;
-C 39 ; WX 277.778 ; N quoteright ; B 86 395 206 694 ; L quoteright quotedblright ;
-C 40 ; WX 388.889 ; N parenleft ; B 99 -250 331 750 ;
-C 41 ; WX 388.889 ; N parenright ; B 57 -250 289 750 ;
-C 42 ; WX 500 ; N asterisk ; B 65 319 434 750 ;
-C 43 ; WX 777.778 ; N plus ; B 56 -83 721 583 ;
-C 44 ; WX 277.778 ; N comma ; B 86 -193 203 106 ;
-C 45 ; WX 333.333 ; N hyphen ; B 11 187 276 245 ; L hyphen endash ;
-C 46 ; WX 277.778 ; N period ; B 86 0 192 106 ;
-C 47 ; WX 500 ; N slash ; B 56 -250 443 750 ;
-C 48 ; WX 500 ; N zero ; B 39 -22 460 666 ;
-C 49 ; WX 500 ; N one ; B 89 0 419 666 ;
-C 50 ; WX 500 ; N two ; B 50 0 449 666 ;
-C 51 ; WX 500 ; N three ; B 42 -22 457 666 ;
-C 52 ; WX 500 ; N four ; B 28 0 471 677 ;
-C 53 ; WX 500 ; N five ; B 50 -22 449 666 ;
-C 54 ; WX 500 ; N six ; B 42 -22 457 666 ;
-C 55 ; WX 500 ; N seven ; B 56 -22 485 676 ;
-C 56 ; WX 500 ; N eight ; B 42 -22 457 666 ;
-C 57 ; WX 500 ; N nine ; B 42 -22 457 666 ;
-C 58 ; WX 277.778 ; N colon ; B 86 0 192 431 ;
-C 59 ; WX 277.778 ; N semicolon ; B 86 -193 195 431 ;
-C 60 ; WX 277.778 ; N exclamdown ; B 86 -216 192 500 ;
-C 61 ; WX 777.778 ; N equal ; B 56 133 721 367 ;
-C 62 ; WX 472.222 ; N questiondown ; B 56 -205 415 500 ;
-C 63 ; WX 472.222 ; N question ; B 56 0 415 705 ; L quoteleft questiondown ;
-C 64 ; WX 777.778 ; N at ; B 56 -11 721 705 ;
-C 65 ; WX 750 ; N A ; B 32 0 717 716 ;
-C 66 ; WX 708.333 ; N B ; B 36 0 651 683 ;
-C 67 ; WX 722.222 ; N C ; B 56 -22 665 705 ;
-C 68 ; WX 763.889 ; N D ; B 35 0 707 683 ;
-C 69 ; WX 680.556 ; N E ; B 33 0 652 680 ;
-C 70 ; WX 652.778 ; N F ; B 33 0 610 680 ;
-C 71 ; WX 784.722 ; N G ; B 56 -22 735 705 ;
-C 72 ; WX 750 ; N H ; B 33 0 716 683 ;
-C 73 ; WX 361.111 ; N I ; B 28 0 333 683 ;
-C 74 ; WX 513.889 ; N J ; B 41 -22 465 683 ;
-C 75 ; WX 777.778 ; N K ; B 33 0 736 683 ;
-C 76 ; WX 625 ; N L ; B 33 0 582 683 ;
-C 77 ; WX 916.667 ; N M ; B 37 0 879 683 ;
-C 78 ; WX 750 ; N N ; B 33 0 716 683 ;
-C 79 ; WX 777.778 ; N O ; B 56 -22 721 705 ;
-C 80 ; WX 680.556 ; N P ; B 35 0 624 683 ;
-C 81 ; WX 777.778 ; N Q ; B 56 -194 727 705 ;
-C 82 ; WX 736.111 ; N R ; B 35 -22 732 683 ;
-C 83 ; WX 555.556 ; N S ; B 56 -22 499 705 ;
-C 84 ; WX 722.222 ; N T ; B 36 0 685 677 ;
-C 85 ; WX 750 ; N U ; B 33 -22 716 683 ;
-C 86 ; WX 750 ; N V ; B 19 -22 730 683 ;
-C 87 ; WX 1027.78 ; N W ; B 18 -22 1009 683 ;
-C 88 ; WX 750 ; N X ; B 24 0 726 683 ;
-C 89 ; WX 750 ; N Y ; B 11 0 738 683 ;
-C 90 ; WX 611.111 ; N Z ; B 56 0 560 683 ;
-C 91 ; WX 277.778 ; N bracketleft ; B 118 -250 255 750 ;
-C 92 ; WX 500 ; N quotedblleft ; B 152 394 466 693 ;
-C 93 ; WX 277.778 ; N bracketright ; B 22 -250 159 750 ;
-C 94 ; WX 500 ; N circumflex ; B 116 540 383 694 ;
-C 95 ; WX 277.778 ; N dotaccent ; B 85 563 192 669 ;
-C 96 ; WX 277.778 ; N quoteleft ; B 72 394 192 693 ; L quoteleft quotedblleft ;
-C 97 ; WX 500 ; N a ; B 42 -11 493 448 ;
-C 98 ; WX 555.556 ; N b ; B 28 -11 521 694 ;
-C 99 ; WX 444.444 ; N c ; B 34 -11 415 448 ;
-C 100 ; WX 555.556 ; N d ; B 34 -11 527 694 ;
-C 101 ; WX 444.444 ; N e ; B 28 -11 415 448 ;
-C 102 ; WX 305.556 ; N f ; B 33 0 357 705 ; L i fi ; L f ff ; L l fl ;
-C 103 ; WX 500 ; N g ; B 28 -206 485 453 ;
-C 104 ; WX 555.556 ; N h ; B 32 0 535 694 ;
-C 105 ; WX 277.778 ; N i ; B 33 0 247 669 ;
-C 106 ; WX 305.556 ; N j ; B -40 -205 210 669 ;
-C 107 ; WX 527.778 ; N k ; B 28 0 511 694 ;
-C 108 ; WX 277.778 ; N l ; B 33 0 255 694 ;
-C 109 ; WX 833.333 ; N m ; B 32 0 813 442 ;
-C 110 ; WX 555.556 ; N n ; B 32 0 535 442 ;
-C 111 ; WX 500 ; N o ; B 28 -11 471 448 ;
-C 112 ; WX 555.556 ; N p ; B 28 -194 521 442 ;
-C 113 ; WX 527.778 ; N q ; B 34 -194 527 442 ;
-C 114 ; WX 391.667 ; N r ; B 28 0 364 442 ;
-C 115 ; WX 394.444 ; N s ; B 33 -11 360 448 ;
-C 116 ; WX 388.889 ; N t ; B 19 -11 332 615 ;
-C 117 ; WX 555.556 ; N u ; B 32 -11 535 442 ;
-C 118 ; WX 527.778 ; N v ; B 19 -11 508 431 ;
-C 119 ; WX 722.222 ; N w ; B 18 -11 703 431 ;
-C 120 ; WX 527.778 ; N x ; B 12 0 516 431 ;
-C 121 ; WX 527.778 ; N y ; B 19 -205 508 431 ;
-C 122 ; WX 444.444 ; N z ; B 28 0 401 431 ;
-C 123 ; WX 500 ; N endash ; B 0 255 499 277 ; L hyphen emdash ;
-C 124 ; WX 1000 ; N emdash ; B 0 255 999 277 ;
-C 125 ; WX 500 ; N hungarumlaut ; B 128 513 420 699 ;
-C 126 ; WX 500 ; N tilde ; B 83 575 416 668 ;
-C 127 ; WX 500 ; N dieresis ; B 103 569 396 669 ;
-C -1 ; WX 333.333 ; N space ; B 0 0 0 0 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 183
-KPX ff quoteright 77.778
-KPX ff question 77.778
-KPX ff exclam 77.778
-KPX ff parenright 77.778
-KPX ff bracketright 77.778
-KPX suppress l -277.778
-KPX suppress L -319.444
-KPX quoteright question 111.111
-KPX quoteright exclam 111.111
-KPX A t -27.778
-KPX A C -27.778
-KPX A O -27.778
-KPX A G -27.778
-KPX A U -27.778
-KPX A Q -27.778
-KPX A T -83.333
-KPX A Y -83.333
-KPX A V -111.111
-KPX A W -111.111
-KPX D X -27.778
-KPX D W -27.778
-KPX D A -27.778
-KPX D V -27.778
-KPX D Y -27.778
-KPX F o -83.333
-KPX F e -83.333
-KPX F u -83.333
-KPX F r -83.333
-KPX F a -83.333
-KPX F A -111.111
-KPX F O -27.778
-KPX F C -27.778
-KPX F G -27.778
-KPX F Q -27.778
-KPX I I 27.778
-KPX K O -27.778
-KPX K C -27.778
-KPX K G -27.778
-KPX K Q -27.778
-KPX L T -83.333
-KPX L Y -83.333
-KPX L V -111.111
-KPX L W -111.111
-KPX O X -27.778
-KPX O W -27.778
-KPX O A -27.778
-KPX O V -27.778
-KPX O Y -27.778
-KPX P A -83.333
-KPX P o -27.778
-KPX P e -27.778
-KPX P a -27.778
-KPX P period -83.333
-KPX P comma -83.333
-KPX R t -27.778
-KPX R C -27.778
-KPX R O -27.778
-KPX R G -27.778
-KPX R U -27.778
-KPX R Q -27.778
-KPX R T -83.333
-KPX R Y -83.333
-KPX R V -111.111
-KPX R W -111.111
-KPX T y -27.778
-KPX T e -83.333
-KPX T o -83.333
-KPX T r -83.333
-KPX T a -83.333
-KPX T A -83.333
-KPX T u -83.333
-KPX V o -83.333
-KPX V e -83.333
-KPX V u -83.333
-KPX V r -83.333
-KPX V a -83.333
-KPX V A -111.111
-KPX V O -27.778
-KPX V C -27.778
-KPX V G -27.778
-KPX V Q -27.778
-KPX W o -83.333
-KPX W e -83.333
-KPX W u -83.333
-KPX W r -83.333
-KPX W a -83.333
-KPX W A -111.111
-KPX W O -27.778
-KPX W C -27.778
-KPX W G -27.778
-KPX W Q -27.778
-KPX X O -27.778
-KPX X C -27.778
-KPX X G -27.778
-KPX X Q -27.778
-KPX Y e -83.333
-KPX Y o -83.333
-KPX Y r -83.333
-KPX Y a -83.333
-KPX Y A -83.333
-KPX Y u -83.333
-KPX a v -27.778
-KPX a j 55.556
-KPX a y -27.778
-KPX a w -27.778
-KPX b e 27.778
-KPX b o 27.778
-KPX b x -27.778
-KPX b d 27.778
-KPX b c 27.778
-KPX b q 27.778
-KPX b v -27.778
-KPX b j 55.556
-KPX b y -27.778
-KPX b w -27.778
-KPX c h -27.778
-KPX c k -27.778
-KPX f quoteright 77.778
-KPX f question 77.778
-KPX f exclam 77.778
-KPX f parenright 77.778
-KPX f bracketright 77.778
-KPX g j 27.778
-KPX h t -27.778
-KPX h u -27.778
-KPX h b -27.778
-KPX h y -27.778
-KPX h v -27.778
-KPX h w -27.778
-KPX k a -55.556
-KPX k e -27.778
-KPX k a -27.778
-KPX k o -27.778
-KPX k c -27.778
-KPX m t -27.778
-KPX m u -27.778
-KPX m b -27.778
-KPX m y -27.778
-KPX m v -27.778
-KPX m w -27.778
-KPX n t -27.778
-KPX n u -27.778
-KPX n b -27.778
-KPX n y -27.778
-KPX n v -27.778
-KPX n w -27.778
-KPX o e 27.778
-KPX o o 27.778
-KPX o x -27.778
-KPX o d 27.778
-KPX o c 27.778
-KPX o q 27.778
-KPX o v -27.778
-KPX o j 55.556
-KPX o y -27.778
-KPX o w -27.778
-KPX p e 27.778
-KPX p o 27.778
-KPX p x -27.778
-KPX p d 27.778
-KPX p c 27.778
-KPX p q 27.778
-KPX p v -27.778
-KPX p j 55.556
-KPX p y -27.778
-KPX p w -27.778
-KPX t y -27.778
-KPX t w -27.778
-KPX u w -27.778
-KPX v a -55.556
-KPX v e -27.778
-KPX v a -27.778
-KPX v o -27.778
-KPX v c -27.778
-KPX w e -27.778
-KPX w a -27.778
-KPX w o -27.778
-KPX w c -27.778
-KPX y o -27.778
-KPX y e -27.778
-KPX y a -27.778
-KPX y period -83.333
-KPX y comma -83.333
-EndKernPairs
-EndKernData
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmsy10.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmsy10.afm
deleted file mode 100644
index 09e9487d14..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmsy10.afm
+++ /dev/null
@@ -1,195 +0,0 @@
-StartFontMetrics 2.0
-Comment Creation Date: Thu Jun 21 22:23:44 1990
-Comment UniqueID 5000820
-FontName CMSY10
-EncodingScheme FontSpecific
-FullName CMSY10
-FamilyName Computer Modern
-Weight Medium
-ItalicAngle -14.035
-IsFixedPitch false
-Version 1.00
-Notice Copyright (c) 1997 American Mathematical Society. All Rights Reserved.
-Comment Computer Modern fonts were designed by Donald E. Knuth
-FontBBox -29 -960 1116 775
-CapHeight 683.333
-XHeight 430.556
-Ascender 694.444
-Descender -960
-Comment FontID CMSY
-Comment DesignSize 10 (pts)
-Comment CharacterCodingScheme TeX math symbols
-Comment Space 0 0 0
-Comment ExtraSpace 0
-Comment Quad 1000
-Comment Num 676.508 393.732 443.731
-Comment Denom 685.951 344.841
-Comment Sup 412.892 362.892 288.889
-Comment Sub 150 247.217
-Comment Supdrop 386.108
-Comment Subdrop 50
-Comment Delim 2390 1010
-Comment Axisheight 250
-StartCharMetrics 129
-C 0 ; WX 777.778 ; N minus ; B 83 230 694 270 ;
-C 1 ; WX 277.778 ; N periodcentered ; B 86 197 192 303 ;
-C 2 ; WX 777.778 ; N multiply ; B 147 9 630 491 ;
-C 3 ; WX 500 ; N asteriskmath ; B 65 34 434 465 ;
-C 4 ; WX 777.778 ; N divide ; B 56 -30 722 530 ;
-C 5 ; WX 500 ; N diamondmath ; B 11 11 489 489 ;
-C 6 ; WX 777.778 ; N plusminus ; B 56 0 721 666 ;
-C 7 ; WX 777.778 ; N minusplus ; B 56 -166 721 500 ;
-C 8 ; WX 777.778 ; N circleplus ; B 56 -83 721 583 ;
-C 9 ; WX 777.778 ; N circleminus ; B 56 -83 721 583 ;
-C 10 ; WX 777.778 ; N circlemultiply ; B 56 -83 721 583 ;
-C 11 ; WX 777.778 ; N circledivide ; B 56 -83 721 583 ;
-C 12 ; WX 777.778 ; N circledot ; B 56 -83 721 583 ;
-C 13 ; WX 1000 ; N circlecopyrt ; B 56 -216 943 716 ;
-C 14 ; WX 500 ; N openbullet ; B 56 56 443 444 ;
-C 15 ; WX 500 ; N bullet ; B 56 56 443 444 ;
-C 16 ; WX 777.778 ; N equivasymptotic ; B 56 16 721 484 ;
-C 17 ; WX 777.778 ; N equivalence ; B 56 36 721 464 ;
-C 18 ; WX 777.778 ; N reflexsubset ; B 83 -137 694 636 ;
-C 19 ; WX 777.778 ; N reflexsuperset ; B 83 -137 694 636 ;
-C 20 ; WX 777.778 ; N lessequal ; B 83 -137 694 636 ;
-C 21 ; WX 777.778 ; N greaterequal ; B 83 -137 694 636 ;
-C 22 ; WX 777.778 ; N precedesequal ; B 83 -137 694 636 ;
-C 23 ; WX 777.778 ; N followsequal ; B 83 -137 694 636 ;
-C 24 ; WX 777.778 ; N similar ; B 56 133 721 367 ;
-C 25 ; WX 777.778 ; N approxequal ; B 56 56 721 483 ;
-C 26 ; WX 777.778 ; N propersubset ; B 83 -40 694 540 ;
-C 27 ; WX 777.778 ; N propersuperset ; B 83 -40 694 540 ;
-C 28 ; WX 1000 ; N lessmuch ; B 56 -66 943 566 ;
-C 29 ; WX 1000 ; N greatermuch ; B 56 -66 943 566 ;
-C 30 ; WX 777.778 ; N precedes ; B 83 -40 694 539 ;
-C 31 ; WX 777.778 ; N follows ; B 83 -40 694 539 ;
-C 32 ; WX 1000 ; N arrowleft ; B 57 72 943 428 ;
-C 33 ; WX 1000 ; N arrowright ; B 56 72 942 428 ;
-C 34 ; WX 500 ; N arrowup ; B 72 -194 428 693 ;
-C 35 ; WX 500 ; N arrowdown ; B 72 -193 428 694 ;
-C 36 ; WX 1000 ; N arrowboth ; B 57 72 942 428 ;
-C 37 ; WX 1000 ; N arrownortheast ; B 56 -193 946 697 ;
-C 38 ; WX 1000 ; N arrowsoutheast ; B 56 -197 946 693 ;
-C 39 ; WX 777.778 ; N similarequal ; B 56 36 721 464 ;
-C 40 ; WX 1000 ; N arrowdblleft ; B 57 -25 943 525 ;
-C 41 ; WX 1000 ; N arrowdblright ; B 56 -25 942 525 ;
-C 42 ; WX 611.111 ; N arrowdblup ; B 30 -194 580 694 ;
-C 43 ; WX 611.111 ; N arrowdbldown ; B 30 -194 580 694 ;
-C 44 ; WX 1000 ; N arrowdblboth ; B 35 -25 964 525 ;
-C 45 ; WX 1000 ; N arrownorthwest ; B 53 -193 943 697 ;
-C 46 ; WX 1000 ; N arrowsouthwest ; B 53 -197 943 693 ;
-C 47 ; WX 777.778 ; N proportional ; B 56 -11 722 442 ;
-C 48 ; WX 275 ; N prime ; B 29 45 262 559 ;
-C 49 ; WX 1000 ; N infinity ; B 56 -11 943 442 ;
-C 50 ; WX 666.667 ; N element ; B 83 -40 583 540 ;
-C 51 ; WX 666.667 ; N owner ; B 83 -40 583 540 ;
-C 52 ; WX 888.889 ; N triangle ; B 59 0 829 716 ;
-C 53 ; WX 888.889 ; N triangleinv ; B 59 -216 829 500 ;
-C 54 ; WX 0 ; N negationslash ; B 139 -216 638 716 ;
-C 55 ; WX 0 ; N mapsto ; B 56 64 124 436 ;
-C 56 ; WX 555.556 ; N universal ; B 0 -22 556 694 ;
-C 57 ; WX 555.556 ; N existential ; B 56 0 499 694 ;
-C 58 ; WX 666.667 ; N logicalnot ; B 56 89 610 356 ;
-C 59 ; WX 500 ; N emptyset ; B 47 -78 452 772 ;
-C 60 ; WX 722.222 ; N Rfractur ; B 46 -22 714 716 ;
-C 61 ; WX 722.222 ; N Ifractur ; B 56 -11 693 705 ;
-C 62 ; WX 777.778 ; N latticetop ; B 56 0 722 666 ;
-C 63 ; WX 777.778 ; N perpendicular ; B 56 0 722 666 ;
-C 64 ; WX 611.111 ; N aleph ; B 56 0 554 693 ;
-C 65 ; WX 798.469 ; N A ; B 27 -50 798 722 ;
-C 66 ; WX 656.808 ; N B ; B 30 -22 665 706 ;
-C 67 ; WX 526.527 ; N C ; B 12 -24 534 705 ;
-C 68 ; WX 771.391 ; N D ; B 20 0 766 683 ;
-C 69 ; WX 527.778 ; N E ; B 28 -22 565 705 ;
-C 70 ; WX 718.75 ; N F ; B 17 -33 829 683 ;
-C 71 ; WX 594.864 ; N G ; B 44 -119 601 705 ;
-C 72 ; WX 844.516 ; N H ; B 20 -47 818 683 ;
-C 73 ; WX 544.513 ; N I ; B -24 0 635 683 ;
-C 74 ; WX 677.778 ; N J ; B 47 -119 840 683 ;
-C 75 ; WX 761.949 ; N K ; B 30 -22 733 705 ;
-C 76 ; WX 689.723 ; N L ; B 31 -22 656 705 ;
-C 77 ; WX 1200.9 ; N M ; B 27 -50 1116 705 ;
-C 78 ; WX 820.489 ; N N ; B -29 -50 978 775 ;
-C 79 ; WX 796.112 ; N O ; B 57 -22 777 705 ;
-C 80 ; WX 695.558 ; N P ; B 20 -50 733 683 ;
-C 81 ; WX 816.667 ; N Q ; B 113 -124 788 705 ;
-C 82 ; WX 847.502 ; N R ; B 20 -22 837 683 ;
-C 83 ; WX 605.556 ; N S ; B 18 -22 642 705 ;
-C 84 ; WX 544.643 ; N T ; B 29 0 798 717 ;
-C 85 ; WX 625.83 ; N U ; B -17 -28 688 683 ;
-C 86 ; WX 612.781 ; N V ; B 35 -45 660 683 ;
-C 87 ; WX 987.782 ; N W ; B 35 -45 1036 683 ;
-C 88 ; WX 713.295 ; N X ; B 50 0 808 683 ;
-C 89 ; WX 668.335 ; N Y ; B 31 -135 717 683 ;
-C 90 ; WX 724.724 ; N Z ; B 37 0 767 683 ;
-C 91 ; WX 666.667 ; N union ; B 56 -22 610 598 ;
-C 92 ; WX 666.667 ; N intersection ; B 56 -22 610 598 ;
-C 93 ; WX 666.667 ; N unionmulti ; B 56 -22 610 598 ;
-C 94 ; WX 666.667 ; N logicaland ; B 56 -22 610 598 ;
-C 95 ; WX 666.667 ; N logicalor ; B 56 -22 610 598 ;
-C 96 ; WX 611.111 ; N turnstileleft ; B 56 0 554 694 ;
-C 97 ; WX 611.111 ; N turnstileright ; B 56 0 554 694 ;
-C 98 ; WX 444.444 ; N floorleft ; B 174 -250 422 750 ;
-C 99 ; WX 444.444 ; N floorright ; B 21 -250 269 750 ;
-C 100 ; WX 444.444 ; N ceilingleft ; B 174 -250 422 750 ;
-C 101 ; WX 444.444 ; N ceilingright ; B 21 -250 269 750 ;
-C 102 ; WX 500 ; N braceleft ; B 72 -250 427 750 ;
-C 103 ; WX 500 ; N braceright ; B 72 -250 427 750 ;
-C 104 ; WX 388.889 ; N angbracketleft ; B 110 -250 332 750 ;
-C 105 ; WX 388.889 ; N angbracketright ; B 56 -250 278 750 ;
-C 106 ; WX 277.778 ; N bar ; B 119 -250 159 750 ;
-C 107 ; WX 500 ; N bardbl ; B 132 -250 367 750 ;
-C 108 ; WX 500 ; N arrowbothv ; B 72 -272 428 772 ;
-C 109 ; WX 611.111 ; N arrowdblbothv ; B 30 -272 580 772 ;
-C 110 ; WX 500 ; N backslash ; B 56 -250 443 750 ;
-C 111 ; WX 277.778 ; N wreathproduct ; B 56 -83 221 583 ;
-C 112 ; WX 833.333 ; N radical ; B 73 -960 853 40 ;
-C 113 ; WX 750 ; N coproduct ; B 36 0 713 683 ;
-C 114 ; WX 833.333 ; N nabla ; B 47 -33 785 683 ;
-C 115 ; WX 416.667 ; N integral ; B 56 -216 471 716 ;
-C 116 ; WX 666.667 ; N unionsq ; B 61 0 605 598 ;
-C 117 ; WX 666.667 ; N intersectionsq ; B 61 0 605 598 ;
-C 118 ; WX 777.778 ; N subsetsqequal ; B 83 -137 714 636 ;
-C 119 ; WX 777.778 ; N supersetsqequal ; B 63 -137 694 636 ;
-C 120 ; WX 444.444 ; N section ; B 69 -205 374 705 ;
-C 121 ; WX 444.444 ; N dagger ; B 56 -216 387 705 ;
-C 122 ; WX 444.444 ; N daggerdbl ; B 56 -205 387 705 ;
-C 123 ; WX 611.111 ; N paragraph ; B 56 -194 582 694 ;
-C 124 ; WX 777.778 ; N club ; B 28 -130 750 727 ;
-C 125 ; WX 777.778 ; N diamond ; B 56 -163 722 727 ;
-C 126 ; WX 777.778 ; N heart ; B 56 -33 722 716 ;
-C 127 ; WX 777.778 ; N spade ; B 56 -130 722 727 ;
-C -1 ; WX 333.333 ; N space ; B 0 0 0 0 ;
-EndCharMetrics
-Comment The following are bogus kern pairs for TeX positioning of accents
-StartKernData
-StartKernPairs 26
-KPX A prime 194.444
-KPX B prime 138.889
-KPX C prime 138.889
-KPX D prime 83.333
-KPX E prime 111.111
-KPX F prime 111.111
-KPX G prime 111.111
-KPX H prime 111.111
-KPX I prime 27.778
-KPX J prime 166.667
-KPX K prime 55.556
-KPX L prime 138.889
-KPX M prime 138.889
-KPX N prime 83.333
-KPX O prime 111.111
-KPX P prime 83.333
-KPX Q prime 111.111
-KPX R prime 83.333
-KPX S prime 138.889
-KPX T prime 27.778
-KPX U prime 83.333
-KPX V prime 27.778
-KPX W prime 83.333
-KPX X prime 138.889
-KPX Y prime 83.333
-KPX Z prime 138.889
-EndKernPairs
-EndKernData
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmtt10.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmtt10.afm
deleted file mode 100644
index d6ec19b090..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/cmtt10.afm
+++ /dev/null
@@ -1,156 +0,0 @@
-StartFontMetrics 2.0
-Comment Creation Date: Thu Jun 21 22:23:51 1990
-Comment UniqueID 5000832
-FontName CMTT10
-EncodingScheme FontSpecific
-FullName CMTT10
-FamilyName Computer Modern
-Weight Medium
-ItalicAngle 0.0
-IsFixedPitch true
-Version 1.00B
-Notice Copyright (c) 1997 American Mathematical Society. All Rights Reserved.
-Comment Computer Modern fonts were designed by Donald E. Knuth
-FontBBox -4 -235 731 800
-CapHeight 611.111
-XHeight 430.556
-Ascender 611.111
-Descender -222.222
-Comment FontID CMTT
-Comment DesignSize 10 (pts)
-Comment CharacterCodingScheme TeX typewriter text
-Comment Space 525 0 0
-Comment ExtraSpace 525
-Comment Quad 1050
-StartCharMetrics 129
-C 0 ; WX 525 ; N Gamma ; B 32 0 488 611 ;
-C 1 ; WX 525 ; N Delta ; B 34 0 490 623 ;
-C 2 ; WX 525 ; N Theta ; B 56 -11 468 622 ;
-C 3 ; WX 525 ; N Lambda ; B 29 0 495 623 ;
-C 4 ; WX 525 ; N Xi ; B 33 0 491 611 ;
-C 5 ; WX 525 ; N Pi ; B 22 0 502 611 ;
-C 6 ; WX 525 ; N Sigma ; B 40 0 484 611 ;
-C 7 ; WX 525 ; N Upsilon ; B 38 0 486 622 ;
-C 8 ; WX 525 ; N Phi ; B 40 0 484 611 ;
-C 9 ; WX 525 ; N Psi ; B 38 0 486 611 ;
-C 10 ; WX 525 ; N Omega ; B 32 0 492 622 ;
-C 11 ; WX 525 ; N arrowup ; B 59 0 465 611 ;
-C 12 ; WX 525 ; N arrowdown ; B 59 0 465 611 ;
-C 13 ; WX 525 ; N quotesingle ; B 217 328 309 622 ;
-C 14 ; WX 525 ; N exclamdown ; B 212 -233 312 389 ;
-C 15 ; WX 525 ; N questiondown ; B 62 -228 462 389 ;
-C 16 ; WX 525 ; N dotlessi ; B 78 0 455 431 ;
-C 17 ; WX 525 ; N dotlessj ; B 48 -228 368 431 ;
-C 18 ; WX 525 ; N grave ; B 117 477 329 611 ;
-C 19 ; WX 525 ; N acute ; B 195 477 407 611 ;
-C 20 ; WX 525 ; N caron ; B 101 454 423 572 ;
-C 21 ; WX 525 ; N breve ; B 86 498 438 611 ;
-C 22 ; WX 525 ; N macron ; B 73 514 451 577 ;
-C 23 ; WX 525 ; N ring ; B 181 499 343 619 ;
-C 24 ; WX 525 ; N cedilla ; B 162 -208 428 45 ;
-C 25 ; WX 525 ; N germandbls ; B 17 -6 495 617 ;
-C 26 ; WX 525 ; N ae ; B 33 -6 504 440 ;
-C 27 ; WX 525 ; N oe ; B 19 -6 505 440 ;
-C 28 ; WX 525 ; N oslash ; B 43 -140 481 571 ;
-C 29 ; WX 525 ; N AE ; B 23 0 499 611 ;
-C 30 ; WX 525 ; N OE ; B 29 -11 502 622 ;
-C 31 ; WX 525 ; N Oslash ; B 56 -85 468 696 ;
-C 32 ; WX 525 ; N visiblespace ; B 44 -132 480 240 ;
-C 33 ; WX 525 ; N exclam ; B 212 0 312 622 ; L quoteleft exclamdown ;
-C 34 ; WX 525 ; N quotedbl ; B 126 328 398 622 ;
-C 35 ; WX 525 ; N numbersign ; B 35 0 489 611 ;
-C 36 ; WX 525 ; N dollar ; B 58 -83 466 694 ;
-C 37 ; WX 525 ; N percent ; B 35 -83 489 694 ;
-C 38 ; WX 525 ; N ampersand ; B 28 -11 490 622 ;
-C 39 ; WX 525 ; N quoteright ; B 180 302 341 611 ;
-C 40 ; WX 525 ; N parenleft ; B 173 -82 437 694 ;
-C 41 ; WX 525 ; N parenright ; B 88 -82 352 694 ;
-C 42 ; WX 525 ; N asterisk ; B 68 90 456 521 ;
-C 43 ; WX 525 ; N plus ; B 38 81 486 531 ;
-C 44 ; WX 525 ; N comma ; B 180 -139 346 125 ;
-C 45 ; WX 525 ; N hyphen ; B 56 271 468 341 ;
-C 46 ; WX 525 ; N period ; B 200 0 325 125 ;
-C 47 ; WX 525 ; N slash ; B 58 -83 466 694 ;
-C 48 ; WX 525 ; N zero ; B 50 -11 474 622 ;
-C 49 ; WX 525 ; N one ; B 105 0 442 622 ;
-C 50 ; WX 525 ; N two ; B 52 0 472 622 ;
-C 51 ; WX 525 ; N three ; B 44 -11 480 622 ;
-C 52 ; WX 525 ; N four ; B 29 0 495 623 ;
-C 53 ; WX 525 ; N five ; B 52 -11 472 611 ;
-C 54 ; WX 525 ; N six ; B 53 -11 471 622 ;
-C 55 ; WX 525 ; N seven ; B 44 -11 480 627 ;
-C 56 ; WX 525 ; N eight ; B 44 -11 480 622 ;
-C 57 ; WX 525 ; N nine ; B 53 -11 471 622 ;
-C 58 ; WX 525 ; N colon ; B 200 0 325 431 ;
-C 59 ; WX 525 ; N semicolon ; B 180 -139 330 431 ;
-C 60 ; WX 525 ; N less ; B 56 56 468 556 ;
-C 61 ; WX 525 ; N equal ; B 38 195 486 417 ;
-C 62 ; WX 525 ; N greater ; B 56 56 468 556 ;
-C 63 ; WX 525 ; N question ; B 62 0 462 617 ; L quoteleft questiondown ;
-C 64 ; WX 525 ; N at ; B 44 -6 480 617 ;
-C 65 ; WX 525 ; N A ; B 27 0 497 623 ;
-C 66 ; WX 525 ; N B ; B 23 0 482 611 ;
-C 67 ; WX 525 ; N C ; B 40 -11 484 622 ;
-C 68 ; WX 525 ; N D ; B 19 0 485 611 ;
-C 69 ; WX 525 ; N E ; B 26 0 502 611 ;
-C 70 ; WX 525 ; N F ; B 28 0 490 611 ;
-C 71 ; WX 525 ; N G ; B 38 -11 496 622 ;
-C 72 ; WX 525 ; N H ; B 22 0 502 611 ;
-C 73 ; WX 525 ; N I ; B 79 0 446 611 ;
-C 74 ; WX 525 ; N J ; B 71 -11 478 611 ;
-C 75 ; WX 525 ; N K ; B 26 0 495 611 ;
-C 76 ; WX 525 ; N L ; B 32 0 488 611 ;
-C 77 ; WX 525 ; N M ; B 17 0 507 611 ;
-C 78 ; WX 525 ; N N ; B 28 0 496 611 ;
-C 79 ; WX 525 ; N O ; B 56 -11 468 622 ;
-C 80 ; WX 525 ; N P ; B 26 0 480 611 ;
-C 81 ; WX 525 ; N Q ; B 56 -139 468 622 ;
-C 82 ; WX 525 ; N R ; B 22 -11 522 611 ;
-C 83 ; WX 525 ; N S ; B 52 -11 472 622 ;
-C 84 ; WX 525 ; N T ; B 26 0 498 611 ;
-C 85 ; WX 525 ; N U ; B 4 -11 520 611 ;
-C 86 ; WX 525 ; N V ; B 18 -8 506 611 ;
-C 87 ; WX 525 ; N W ; B 11 -8 513 611 ;
-C 88 ; WX 525 ; N X ; B 27 0 496 611 ;
-C 89 ; WX 525 ; N Y ; B 19 0 505 611 ;
-C 90 ; WX 525 ; N Z ; B 48 0 481 611 ;
-C 91 ; WX 525 ; N bracketleft ; B 222 -83 483 694 ;
-C 92 ; WX 525 ; N backslash ; B 58 -83 466 694 ;
-C 93 ; WX 525 ; N bracketright ; B 41 -83 302 694 ;
-C 94 ; WX 525 ; N asciicircum ; B 100 471 424 611 ;
-C 95 ; WX 525 ; N underscore ; B 56 -95 468 -25 ;
-C 96 ; WX 525 ; N quoteleft ; B 183 372 344 681 ;
-C 97 ; WX 525 ; N a ; B 55 -6 524 440 ;
-C 98 ; WX 525 ; N b ; B 12 -6 488 611 ;
-C 99 ; WX 525 ; N c ; B 73 -6 466 440 ;
-C 100 ; WX 525 ; N d ; B 36 -6 512 611 ;
-C 101 ; WX 525 ; N e ; B 55 -6 464 440 ;
-C 102 ; WX 525 ; N f ; B 42 0 437 617 ;
-C 103 ; WX 525 ; N g ; B 29 -229 509 442 ;
-C 104 ; WX 525 ; N h ; B 12 0 512 611 ;
-C 105 ; WX 525 ; N i ; B 78 0 455 612 ;
-C 106 ; WX 525 ; N j ; B 48 -228 368 612 ;
-C 107 ; WX 525 ; N k ; B 21 0 508 611 ;
-C 108 ; WX 525 ; N l ; B 58 0 467 611 ;
-C 109 ; WX 525 ; N m ; B -4 0 516 437 ;
-C 110 ; WX 525 ; N n ; B 12 0 512 437 ;
-C 111 ; WX 525 ; N o ; B 57 -6 467 440 ;
-C 112 ; WX 525 ; N p ; B 12 -222 488 437 ;
-C 113 ; WX 525 ; N q ; B 40 -222 537 437 ;
-C 114 ; WX 525 ; N r ; B 32 0 487 437 ;
-C 115 ; WX 525 ; N s ; B 72 -6 459 440 ;
-C 116 ; WX 525 ; N t ; B 25 -6 449 554 ;
-C 117 ; WX 525 ; N u ; B 12 -6 512 431 ;
-C 118 ; WX 525 ; N v ; B 24 -4 500 431 ;
-C 119 ; WX 525 ; N w ; B 16 -4 508 431 ;
-C 120 ; WX 525 ; N x ; B 27 0 496 431 ;
-C 121 ; WX 525 ; N y ; B 26 -228 500 431 ;
-C 122 ; WX 525 ; N z ; B 33 0 475 431 ;
-C 123 ; WX 525 ; N braceleft ; B 57 -83 467 694 ;
-C 124 ; WX 525 ; N bar ; B 227 -83 297 694 ;
-C 125 ; WX 525 ; N braceright ; B 57 -83 467 694 ;
-C 126 ; WX 525 ; N asciitilde ; B 87 491 437 611 ;
-C 127 ; WX 525 ; N dieresis ; B 110 512 414 612 ;
-C -1 ; WX 525 ; N space ; B 0 0 0 0 ;
-EndCharMetrics
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pagd8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pagd8a.afm
deleted file mode 100644
index 69eebba18e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pagd8a.afm
+++ /dev/null
@@ -1,576 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Mon Mar 4 13:46:34 1991
-Comment UniqueID 34370
-Comment VMusage 24954 31846
-FontName AvantGarde-Demi
-FullName ITC Avant Garde Gothic Demi
-FamilyName ITC Avant Garde Gothic
-Weight Demi
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -123 -251 1222 1021
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.007
-Notice Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved.ITC Avant Garde Gothic is a registered trademark of International Typeface Corporation.
-EncodingScheme AdobeStandardEncoding
-CapHeight 740
-XHeight 555
-Ascender 740
-Descender -185
-StartCharMetrics 228
-C 32 ; WX 280 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 280 ; N exclam ; B 73 0 206 740 ;
-C 34 ; WX 360 ; N quotedbl ; B 19 444 341 740 ;
-C 35 ; WX 560 ; N numbersign ; B 29 0 525 700 ;
-C 36 ; WX 560 ; N dollar ; B 58 -86 501 857 ;
-C 37 ; WX 860 ; N percent ; B 36 -15 822 755 ;
-C 38 ; WX 680 ; N ampersand ; B 34 -15 665 755 ;
-C 39 ; WX 280 ; N quoteright ; B 72 466 205 740 ;
-C 40 ; WX 380 ; N parenleft ; B 74 -157 350 754 ;
-C 41 ; WX 380 ; N parenright ; B 37 -157 313 754 ;
-C 42 ; WX 440 ; N asterisk ; B 67 457 374 755 ;
-C 43 ; WX 600 ; N plus ; B 48 0 552 506 ;
-C 44 ; WX 280 ; N comma ; B 73 -141 206 133 ;
-C 45 ; WX 420 ; N hyphen ; B 71 230 349 348 ;
-C 46 ; WX 280 ; N period ; B 73 0 206 133 ;
-C 47 ; WX 460 ; N slash ; B 6 -100 454 740 ;
-C 48 ; WX 560 ; N zero ; B 32 -15 529 755 ;
-C 49 ; WX 560 ; N one ; B 137 0 363 740 ;
-C 50 ; WX 560 ; N two ; B 36 0 523 755 ;
-C 51 ; WX 560 ; N three ; B 28 -15 532 755 ;
-C 52 ; WX 560 ; N four ; B 15 0 545 740 ;
-C 53 ; WX 560 ; N five ; B 25 -15 535 740 ;
-C 54 ; WX 560 ; N six ; B 23 -15 536 739 ;
-C 55 ; WX 560 ; N seven ; B 62 0 498 740 ;
-C 56 ; WX 560 ; N eight ; B 33 -15 527 755 ;
-C 57 ; WX 560 ; N nine ; B 24 0 537 754 ;
-C 58 ; WX 280 ; N colon ; B 73 0 206 555 ;
-C 59 ; WX 280 ; N semicolon ; B 73 -141 206 555 ;
-C 60 ; WX 600 ; N less ; B 46 -8 554 514 ;
-C 61 ; WX 600 ; N equal ; B 48 81 552 425 ;
-C 62 ; WX 600 ; N greater ; B 46 -8 554 514 ;
-C 63 ; WX 560 ; N question ; B 38 0 491 755 ;
-C 64 ; WX 740 ; N at ; B 50 -12 750 712 ;
-C 65 ; WX 740 ; N A ; B 7 0 732 740 ;
-C 66 ; WX 580 ; N B ; B 70 0 551 740 ;
-C 67 ; WX 780 ; N C ; B 34 -15 766 755 ;
-C 68 ; WX 700 ; N D ; B 63 0 657 740 ;
-C 69 ; WX 520 ; N E ; B 61 0 459 740 ;
-C 70 ; WX 480 ; N F ; B 61 0 438 740 ;
-C 71 ; WX 840 ; N G ; B 27 -15 817 755 ;
-C 72 ; WX 680 ; N H ; B 71 0 610 740 ;
-C 73 ; WX 280 ; N I ; B 72 0 209 740 ;
-C 74 ; WX 480 ; N J ; B 2 -15 409 740 ;
-C 75 ; WX 620 ; N K ; B 89 0 620 740 ;
-C 76 ; WX 440 ; N L ; B 72 0 435 740 ;
-C 77 ; WX 900 ; N M ; B 63 0 837 740 ;
-C 78 ; WX 740 ; N N ; B 70 0 671 740 ;
-C 79 ; WX 840 ; N O ; B 33 -15 807 755 ;
-C 80 ; WX 560 ; N P ; B 72 0 545 740 ;
-C 81 ; WX 840 ; N Q ; B 32 -15 824 755 ;
-C 82 ; WX 580 ; N R ; B 64 0 565 740 ;
-C 83 ; WX 520 ; N S ; B 12 -15 493 755 ;
-C 84 ; WX 420 ; N T ; B 6 0 418 740 ;
-C 85 ; WX 640 ; N U ; B 55 -15 585 740 ;
-C 86 ; WX 700 ; N V ; B 8 0 695 740 ;
-C 87 ; WX 900 ; N W ; B 7 0 899 740 ;
-C 88 ; WX 680 ; N X ; B 4 0 676 740 ;
-C 89 ; WX 620 ; N Y ; B -2 0 622 740 ;
-C 90 ; WX 500 ; N Z ; B 19 0 481 740 ;
-C 91 ; WX 320 ; N bracketleft ; B 66 -157 284 754 ;
-C 92 ; WX 640 ; N backslash ; B 96 -100 544 740 ;
-C 93 ; WX 320 ; N bracketright ; B 36 -157 254 754 ;
-C 94 ; WX 600 ; N asciicircum ; B 73 375 527 740 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 280 ; N quoteleft ; B 72 466 205 740 ;
-C 97 ; WX 660 ; N a ; B 27 -18 613 574 ;
-C 98 ; WX 660 ; N b ; B 47 -18 632 740 ;
-C 99 ; WX 640 ; N c ; B 37 -18 610 574 ;
-C 100 ; WX 660 ; N d ; B 34 -18 618 740 ;
-C 101 ; WX 640 ; N e ; B 31 -18 610 577 ;
-C 102 ; WX 280 ; N f ; B 15 0 280 755 ; L i fi ; L l fl ;
-C 103 ; WX 660 ; N g ; B 32 -226 623 574 ;
-C 104 ; WX 600 ; N h ; B 54 0 546 740 ;
-C 105 ; WX 240 ; N i ; B 53 0 186 740 ;
-C 106 ; WX 260 ; N j ; B 16 -185 205 740 ;
-C 107 ; WX 580 ; N k ; B 80 0 571 740 ;
-C 108 ; WX 240 ; N l ; B 54 0 187 740 ;
-C 109 ; WX 940 ; N m ; B 54 0 887 574 ;
-C 110 ; WX 600 ; N n ; B 54 0 547 574 ;
-C 111 ; WX 640 ; N o ; B 25 -18 615 574 ;
-C 112 ; WX 660 ; N p ; B 47 -185 629 574 ;
-C 113 ; WX 660 ; N q ; B 31 -185 613 574 ;
-C 114 ; WX 320 ; N r ; B 63 0 317 574 ;
-C 115 ; WX 440 ; N s ; B 19 -18 421 574 ;
-C 116 ; WX 300 ; N t ; B 21 0 299 740 ;
-C 117 ; WX 600 ; N u ; B 50 -18 544 555 ;
-C 118 ; WX 560 ; N v ; B 3 0 556 555 ;
-C 119 ; WX 800 ; N w ; B 11 0 789 555 ;
-C 120 ; WX 560 ; N x ; B 3 0 556 555 ;
-C 121 ; WX 580 ; N y ; B 8 -185 571 555 ;
-C 122 ; WX 460 ; N z ; B 20 0 442 555 ;
-C 123 ; WX 340 ; N braceleft ; B -3 -191 317 747 ;
-C 124 ; WX 600 ; N bar ; B 233 -100 366 740 ;
-C 125 ; WX 340 ; N braceright ; B 23 -191 343 747 ;
-C 126 ; WX 600 ; N asciitilde ; B 67 160 533 347 ;
-C 161 ; WX 280 ; N exclamdown ; B 74 -185 207 555 ;
-C 162 ; WX 560 ; N cent ; B 43 39 517 715 ;
-C 163 ; WX 560 ; N sterling ; B -2 0 562 755 ;
-C 164 ; WX 160 ; N fraction ; B -123 0 282 740 ;
-C 165 ; WX 560 ; N yen ; B -10 0 570 740 ;
-C 166 ; WX 560 ; N florin ; B 0 -151 512 824 ;
-C 167 ; WX 560 ; N section ; B 28 -158 530 755 ;
-C 168 ; WX 560 ; N currency ; B 27 69 534 577 ;
-C 169 ; WX 220 ; N quotesingle ; B 44 444 177 740 ;
-C 170 ; WX 480 ; N quotedblleft ; B 70 466 410 740 ;
-C 171 ; WX 460 ; N guillemotleft ; B 61 108 400 469 ;
-C 172 ; WX 240 ; N guilsinglleft ; B 50 108 190 469 ;
-C 173 ; WX 240 ; N guilsinglright ; B 50 108 190 469 ;
-C 174 ; WX 520 ; N fi ; B 25 0 461 755 ;
-C 175 ; WX 520 ; N fl ; B 25 0 461 755 ;
-C 177 ; WX 500 ; N endash ; B 35 230 465 348 ;
-C 178 ; WX 560 ; N dagger ; B 51 -142 509 740 ;
-C 179 ; WX 560 ; N daggerdbl ; B 51 -142 509 740 ;
-C 180 ; WX 280 ; N periodcentered ; B 73 187 206 320 ;
-C 182 ; WX 600 ; N paragraph ; B -7 -103 607 740 ;
-C 183 ; WX 600 ; N bullet ; B 148 222 453 532 ;
-C 184 ; WX 280 ; N quotesinglbase ; B 72 -141 205 133 ;
-C 185 ; WX 480 ; N quotedblbase ; B 70 -141 410 133 ;
-C 186 ; WX 480 ; N quotedblright ; B 70 466 410 740 ;
-C 187 ; WX 460 ; N guillemotright ; B 61 108 400 469 ;
-C 188 ; WX 1000 ; N ellipsis ; B 100 0 899 133 ;
-C 189 ; WX 1280 ; N perthousand ; B 36 -15 1222 755 ;
-C 191 ; WX 560 ; N questiondown ; B 68 -200 521 555 ;
-C 193 ; WX 420 ; N grave ; B 50 624 329 851 ;
-C 194 ; WX 420 ; N acute ; B 91 624 370 849 ;
-C 195 ; WX 540 ; N circumflex ; B 71 636 470 774 ;
-C 196 ; WX 480 ; N tilde ; B 44 636 437 767 ;
-C 197 ; WX 420 ; N macron ; B 72 648 349 759 ;
-C 198 ; WX 480 ; N breve ; B 42 633 439 770 ;
-C 199 ; WX 280 ; N dotaccent ; B 74 636 207 769 ;
-C 200 ; WX 500 ; N dieresis ; B 78 636 422 769 ;
-C 202 ; WX 360 ; N ring ; B 73 619 288 834 ;
-C 203 ; WX 340 ; N cedilla ; B 98 -251 298 6 ;
-C 205 ; WX 700 ; N hungarumlaut ; B 132 610 609 862 ;
-C 206 ; WX 340 ; N ogonek ; B 79 -195 262 9 ;
-C 207 ; WX 540 ; N caron ; B 71 636 470 774 ;
-C 208 ; WX 1000 ; N emdash ; B 35 230 965 348 ;
-C 225 ; WX 900 ; N AE ; B -5 0 824 740 ;
-C 227 ; WX 360 ; N ordfeminine ; B 19 438 334 755 ;
-C 232 ; WX 480 ; N Lslash ; B 26 0 460 740 ;
-C 233 ; WX 840 ; N Oslash ; B 33 -71 807 814 ;
-C 234 ; WX 1060 ; N OE ; B 37 -15 1007 755 ;
-C 235 ; WX 360 ; N ordmasculine ; B 23 438 338 755 ;
-C 241 ; WX 1080 ; N ae ; B 29 -18 1048 574 ;
-C 245 ; WX 240 ; N dotlessi ; B 53 0 186 555 ;
-C 248 ; WX 320 ; N lslash ; B 34 0 305 740 ;
-C 249 ; WX 660 ; N oslash ; B 35 -50 625 608 ;
-C 250 ; WX 1080 ; N oe ; B 30 -18 1050 574 ;
-C 251 ; WX 600 ; N germandbls ; B 51 -18 585 755 ;
-C -1 ; WX 640 ; N ecircumflex ; B 31 -18 610 774 ;
-C -1 ; WX 640 ; N edieresis ; B 31 -18 610 769 ;
-C -1 ; WX 660 ; N aacute ; B 27 -18 613 849 ;
-C -1 ; WX 740 ; N registered ; B -12 -12 752 752 ;
-C -1 ; WX 240 ; N icircumflex ; B -79 0 320 774 ;
-C -1 ; WX 600 ; N udieresis ; B 50 -18 544 769 ;
-C -1 ; WX 640 ; N ograve ; B 25 -18 615 851 ;
-C -1 ; WX 600 ; N uacute ; B 50 -18 544 849 ;
-C -1 ; WX 600 ; N ucircumflex ; B 50 -18 544 774 ;
-C -1 ; WX 740 ; N Aacute ; B 7 0 732 1019 ;
-C -1 ; WX 240 ; N igrave ; B -65 0 214 851 ;
-C -1 ; WX 280 ; N Icircumflex ; B -59 0 340 944 ;
-C -1 ; WX 640 ; N ccedilla ; B 37 -251 610 574 ;
-C -1 ; WX 660 ; N adieresis ; B 27 -18 613 769 ;
-C -1 ; WX 520 ; N Ecircumflex ; B 61 0 460 944 ;
-C -1 ; WX 440 ; N scaron ; B 19 -18 421 774 ;
-C -1 ; WX 660 ; N thorn ; B 47 -185 629 740 ;
-C -1 ; WX 1000 ; N trademark ; B 9 296 821 740 ;
-C -1 ; WX 640 ; N egrave ; B 31 -18 610 851 ;
-C -1 ; WX 336 ; N threesuperior ; B 8 287 328 749 ;
-C -1 ; WX 460 ; N zcaron ; B 20 0 455 774 ;
-C -1 ; WX 660 ; N atilde ; B 27 -18 613 767 ;
-C -1 ; WX 660 ; N aring ; B 27 -18 613 834 ;
-C -1 ; WX 640 ; N ocircumflex ; B 25 -18 615 774 ;
-C -1 ; WX 520 ; N Edieresis ; B 61 0 459 939 ;
-C -1 ; WX 840 ; N threequarters ; B 18 0 803 749 ;
-C -1 ; WX 580 ; N ydieresis ; B 8 -185 571 769 ;
-C -1 ; WX 580 ; N yacute ; B 8 -185 571 849 ;
-C -1 ; WX 240 ; N iacute ; B 26 0 305 849 ;
-C -1 ; WX 740 ; N Acircumflex ; B 7 0 732 944 ;
-C -1 ; WX 640 ; N Uacute ; B 55 -15 585 1019 ;
-C -1 ; WX 640 ; N eacute ; B 31 -18 610 849 ;
-C -1 ; WX 840 ; N Ograve ; B 33 -15 807 1021 ;
-C -1 ; WX 660 ; N agrave ; B 27 -18 613 851 ;
-C -1 ; WX 640 ; N Udieresis ; B 55 -15 585 939 ;
-C -1 ; WX 660 ; N acircumflex ; B 27 -18 613 774 ;
-C -1 ; WX 280 ; N Igrave ; B -45 0 234 1021 ;
-C -1 ; WX 336 ; N twosuperior ; B 13 296 322 749 ;
-C -1 ; WX 640 ; N Ugrave ; B 55 -15 585 1021 ;
-C -1 ; WX 840 ; N onequarter ; B 92 0 746 740 ;
-C -1 ; WX 640 ; N Ucircumflex ; B 55 -15 585 944 ;
-C -1 ; WX 520 ; N Scaron ; B 12 -15 493 944 ;
-C -1 ; WX 280 ; N Idieresis ; B -32 0 312 939 ;
-C -1 ; WX 240 ; N idieresis ; B -52 0 292 769 ;
-C -1 ; WX 520 ; N Egrave ; B 61 0 459 1021 ;
-C -1 ; WX 840 ; N Oacute ; B 33 -15 807 1019 ;
-C -1 ; WX 600 ; N divide ; B 48 -20 552 526 ;
-C -1 ; WX 740 ; N Atilde ; B 7 0 732 937 ;
-C -1 ; WX 740 ; N Aring ; B 7 0 732 969 ;
-C -1 ; WX 840 ; N Odieresis ; B 33 -15 807 939 ;
-C -1 ; WX 740 ; N Adieresis ; B 7 0 732 939 ;
-C -1 ; WX 740 ; N Ntilde ; B 70 0 671 937 ;
-C -1 ; WX 500 ; N Zcaron ; B 19 0 481 944 ;
-C -1 ; WX 560 ; N Thorn ; B 72 0 545 740 ;
-C -1 ; WX 280 ; N Iacute ; B 46 0 325 1019 ;
-C -1 ; WX 600 ; N plusminus ; B 48 -62 552 556 ;
-C -1 ; WX 600 ; N multiply ; B 59 12 541 494 ;
-C -1 ; WX 520 ; N Eacute ; B 61 0 459 1019 ;
-C -1 ; WX 620 ; N Ydieresis ; B -2 0 622 939 ;
-C -1 ; WX 336 ; N onesuperior ; B 72 296 223 740 ;
-C -1 ; WX 600 ; N ugrave ; B 50 -18 544 851 ;
-C -1 ; WX 600 ; N logicalnot ; B 48 108 552 425 ;
-C -1 ; WX 600 ; N ntilde ; B 54 0 547 767 ;
-C -1 ; WX 840 ; N Otilde ; B 33 -15 807 937 ;
-C -1 ; WX 640 ; N otilde ; B 25 -18 615 767 ;
-C -1 ; WX 780 ; N Ccedilla ; B 34 -251 766 755 ;
-C -1 ; WX 740 ; N Agrave ; B 7 0 732 1021 ;
-C -1 ; WX 840 ; N onehalf ; B 62 0 771 740 ;
-C -1 ; WX 742 ; N Eth ; B 25 0 691 740 ;
-C -1 ; WX 400 ; N degree ; B 57 426 343 712 ;
-C -1 ; WX 620 ; N Yacute ; B -2 0 622 1019 ;
-C -1 ; WX 840 ; N Ocircumflex ; B 33 -15 807 944 ;
-C -1 ; WX 640 ; N oacute ; B 25 -18 615 849 ;
-C -1 ; WX 576 ; N mu ; B 38 -187 539 555 ;
-C -1 ; WX 600 ; N minus ; B 48 193 552 313 ;
-C -1 ; WX 640 ; N eth ; B 27 -18 616 754 ;
-C -1 ; WX 640 ; N odieresis ; B 25 -18 615 769 ;
-C -1 ; WX 740 ; N copyright ; B -12 -12 752 752 ;
-C -1 ; WX 600 ; N brokenbar ; B 233 -100 366 740 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 218
-
-KPX A y -50
-KPX A w -65
-KPX A v -70
-KPX A u -20
-KPX A quoteright -90
-KPX A Y -80
-KPX A W -60
-KPX A V -102
-KPX A U -40
-KPX A T -25
-KPX A Q -50
-KPX A O -50
-KPX A G -40
-KPX A C -40
-
-KPX B A -10
-
-KPX C A -40
-
-KPX D period -20
-KPX D comma -20
-KPX D Y -45
-KPX D W -25
-KPX D V -50
-KPX D A -50
-
-KPX F period -129
-KPX F e -20
-KPX F comma -162
-KPX F a -20
-KPX F A -75
-
-KPX G period -20
-KPX G comma -20
-KPX G Y -15
-
-KPX J period -15
-KPX J a -20
-KPX J A -30
-
-KPX K y -20
-KPX K u -15
-KPX K o -45
-KPX K e -40
-KPX K O -30
-
-KPX L y -23
-KPX L quoteright -30
-KPX L quotedblright -30
-KPX L Y -80
-KPX L W -55
-KPX L V -85
-KPX L T -46
-
-KPX O period -30
-KPX O comma -30
-KPX O Y -30
-KPX O X -30
-KPX O W -20
-KPX O V -45
-KPX O T -15
-KPX O A -60
-
-KPX P period -200
-KPX P o -20
-KPX P e -20
-KPX P comma -220
-KPX P a -20
-KPX P A -100
-
-KPX Q comma 20
-
-KPX R W 25
-KPX R V -10
-KPX R U 25
-KPX R T 40
-KPX R O 25
-
-KPX S comma 20
-
-KPX T y -10
-KPX T w -55
-KPX T u -46
-KPX T semicolon -29
-KPX T r -30
-KPX T period -91
-KPX T o -49
-KPX T hyphen -75
-KPX T e -49
-KPX T comma -82
-KPX T colon -15
-KPX T a -70
-KPX T O -15
-KPX T A -25
-
-KPX U period -20
-KPX U comma -20
-KPX U A -40
-
-KPX V u -55
-KPX V semicolon -33
-KPX V period -145
-KPX V o -101
-KPX V i -15
-KPX V hyphen -75
-KPX V e -101
-KPX V comma -145
-KPX V colon -18
-KPX V a -95
-KPX V O -45
-KPX V G -20
-KPX V A -102
-
-KPX W y -15
-KPX W u -30
-KPX W semicolon -33
-KPX W period -106
-KPX W o -46
-KPX W i -10
-KPX W hyphen -35
-KPX W e -47
-KPX W comma -106
-KPX W colon -15
-KPX W a -50
-KPX W O -20
-KPX W A -58
-
-KPX Y u -52
-KPX Y semicolon -23
-KPX Y period -145
-KPX Y o -89
-KPX Y hyphen -100
-KPX Y e -89
-KPX Y comma -145
-KPX Y colon -10
-KPX Y a -93
-KPX Y O -30
-KPX Y A -80
-
-KPX a t 5
-KPX a p 20
-KPX a b 5
-
-KPX b y -20
-KPX b v -20
-
-KPX c y -20
-KPX c l -15
-KPX c k -15
-
-KPX comma space -50
-KPX comma quoteright -70
-KPX comma quotedblright -70
-
-KPX e y -20
-KPX e x -20
-KPX e w -20
-KPX e v -20
-
-KPX f period -40
-KPX f o -20
-KPX f l -15
-KPX f i -15
-KPX f f -20
-KPX f dotlessi -15
-KPX f comma -40
-KPX f a -15
-
-KPX g i 25
-KPX g a 15
-
-KPX h y -30
-
-KPX k y -5
-KPX k o -30
-KPX k e -40
-
-KPX m y -20
-KPX m u -20
-
-KPX n y -15
-KPX n v -30
-
-KPX o y -20
-KPX o x -30
-KPX o w -20
-KPX o v -30
-
-KPX p y -20
-
-KPX period space -50
-KPX period quoteright -70
-KPX period quotedblright -70
-
-KPX quotedblleft A -50
-
-KPX quotedblright space -50
-
-KPX quoteleft quoteleft -80
-KPX quoteleft A -50
-
-KPX quoteright v -10
-KPX quoteright t 10
-KPX quoteright space -50
-KPX quoteright s -15
-KPX quoteright r -20
-KPX quoteright quoteright -80
-KPX quoteright d -50
-
-KPX r y 40
-KPX r v 40
-KPX r u 20
-KPX r t 20
-KPX r s 20
-KPX r q -8
-KPX r period -73
-KPX r p 20
-KPX r o -15
-KPX r n 21
-KPX r m 15
-KPX r l 20
-KPX r k 5
-KPX r i 20
-KPX r hyphen -60
-KPX r g 1
-KPX r e -4
-KPX r d -6
-KPX r comma -75
-KPX r c -7
-
-KPX s period 20
-KPX s comma 20
-
-KPX space quoteleft -50
-KPX space quotedblleft -50
-KPX space Y -60
-KPX space W -25
-KPX space V -80
-KPX space T -25
-KPX space A -20
-
-KPX v period -90
-KPX v o -20
-KPX v e -20
-KPX v comma -90
-KPX v a -30
-
-KPX w period -90
-KPX w o -30
-KPX w e -20
-KPX w comma -90
-KPX w a -30
-
-KPX x e -20
-
-KPX y period -100
-KPX y o -30
-KPX y e -20
-KPX y comma -100
-KPX y c -35
-KPX y a -30
-EndKernPairs
-EndKernData
-StartComposites 56
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 160 170 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 100 170 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 120 170 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 160 170 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 190 135 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 130 170 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 50 170 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex -10 170 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 10 170 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 50 170 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute -45 170 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -130 170 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -110 170 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave -95 170 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 130 170 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 210 170 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 150 170 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 170 170 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 210 170 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 180 170 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron -10 170 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 145 170 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 50 170 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 70 170 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 75 170 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 135 170 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 60 170 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 5 170 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 120 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 60 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 120 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 150 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 90 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 110 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 50 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 70 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 110 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -65 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -150 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -130 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -115 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 60 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 110 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 50 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 70 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 80 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron -50 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 125 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 30 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 50 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 55 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 115 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 40 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron -15 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pagdo8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pagdo8a.afm
deleted file mode 100644
index c348b11777..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pagdo8a.afm
+++ /dev/null
@@ -1,576 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Mon Mar 4 13:49:44 1991
-Comment UniqueID 34373
-Comment VMusage 6550 39938
-FontName AvantGarde-DemiOblique
-FullName ITC Avant Garde Gothic Demi Oblique
-FamilyName ITC Avant Garde Gothic
-Weight Demi
-ItalicAngle -10.5
-IsFixedPitch false
-FontBBox -123 -251 1256 1021
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.007
-Notice Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved.ITC Avant Garde Gothic is a registered trademark of International Typeface Corporation.
-EncodingScheme AdobeStandardEncoding
-CapHeight 740
-XHeight 555
-Ascender 740
-Descender -185
-StartCharMetrics 228
-C 32 ; WX 280 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 280 ; N exclam ; B 73 0 343 740 ;
-C 34 ; WX 360 ; N quotedbl ; B 127 444 478 740 ;
-C 35 ; WX 560 ; N numbersign ; B 66 0 618 700 ;
-C 36 ; WX 560 ; N dollar ; B 99 -86 582 857 ;
-C 37 ; WX 860 ; N percent ; B 139 -15 856 755 ;
-C 38 ; WX 680 ; N ampersand ; B 71 -15 742 755 ;
-C 39 ; WX 280 ; N quoteright ; B 159 466 342 740 ;
-C 40 ; WX 380 ; N parenleft ; B 120 -157 490 754 ;
-C 41 ; WX 380 ; N parenright ; B 8 -157 378 754 ;
-C 42 ; WX 440 ; N asterisk ; B 174 457 492 755 ;
-C 43 ; WX 600 ; N plus ; B 84 0 610 506 ;
-C 44 ; WX 280 ; N comma ; B 48 -141 231 133 ;
-C 45 ; WX 420 ; N hyphen ; B 114 230 413 348 ;
-C 46 ; WX 280 ; N period ; B 73 0 231 133 ;
-C 47 ; WX 460 ; N slash ; B -13 -100 591 740 ;
-C 48 ; WX 560 ; N zero ; B 70 -15 628 755 ;
-C 49 ; WX 560 ; N one ; B 230 0 500 740 ;
-C 50 ; WX 560 ; N two ; B 44 0 622 755 ;
-C 51 ; WX 560 ; N three ; B 67 -15 585 755 ;
-C 52 ; WX 560 ; N four ; B 36 0 604 740 ;
-C 53 ; WX 560 ; N five ; B 64 -15 600 740 ;
-C 54 ; WX 560 ; N six ; B 64 -15 587 739 ;
-C 55 ; WX 560 ; N seven ; B 83 0 635 740 ;
-C 56 ; WX 560 ; N eight ; B 71 -15 590 755 ;
-C 57 ; WX 560 ; N nine ; B 110 0 633 754 ;
-C 58 ; WX 280 ; N colon ; B 73 0 309 555 ;
-C 59 ; WX 280 ; N semicolon ; B 48 -141 309 555 ;
-C 60 ; WX 600 ; N less ; B 84 -8 649 514 ;
-C 61 ; WX 600 ; N equal ; B 63 81 631 425 ;
-C 62 ; WX 600 ; N greater ; B 45 -8 610 514 ;
-C 63 ; WX 560 ; N question ; B 135 0 593 755 ;
-C 64 ; WX 740 ; N at ; B 109 -12 832 712 ;
-C 65 ; WX 740 ; N A ; B 7 0 732 740 ;
-C 66 ; WX 580 ; N B ; B 70 0 610 740 ;
-C 67 ; WX 780 ; N C ; B 97 -15 864 755 ;
-C 68 ; WX 700 ; N D ; B 63 0 732 740 ;
-C 69 ; WX 520 ; N E ; B 61 0 596 740 ;
-C 70 ; WX 480 ; N F ; B 61 0 575 740 ;
-C 71 ; WX 840 ; N G ; B 89 -15 887 755 ;
-C 72 ; WX 680 ; N H ; B 71 0 747 740 ;
-C 73 ; WX 280 ; N I ; B 72 0 346 740 ;
-C 74 ; WX 480 ; N J ; B 34 -15 546 740 ;
-C 75 ; WX 620 ; N K ; B 89 0 757 740 ;
-C 76 ; WX 440 ; N L ; B 72 0 459 740 ;
-C 77 ; WX 900 ; N M ; B 63 0 974 740 ;
-C 78 ; WX 740 ; N N ; B 70 0 808 740 ;
-C 79 ; WX 840 ; N O ; B 95 -15 882 755 ;
-C 80 ; WX 560 ; N P ; B 72 0 645 740 ;
-C 81 ; WX 840 ; N Q ; B 94 -15 882 755 ;
-C 82 ; WX 580 ; N R ; B 64 0 656 740 ;
-C 83 ; WX 520 ; N S ; B 49 -15 578 755 ;
-C 84 ; WX 420 ; N T ; B 119 0 555 740 ;
-C 85 ; WX 640 ; N U ; B 97 -15 722 740 ;
-C 86 ; WX 700 ; N V ; B 145 0 832 740 ;
-C 87 ; WX 900 ; N W ; B 144 0 1036 740 ;
-C 88 ; WX 680 ; N X ; B 4 0 813 740 ;
-C 89 ; WX 620 ; N Y ; B 135 0 759 740 ;
-C 90 ; WX 500 ; N Z ; B 19 0 599 740 ;
-C 91 ; WX 320 ; N bracketleft ; B 89 -157 424 754 ;
-C 92 ; WX 640 ; N backslash ; B 233 -100 525 740 ;
-C 93 ; WX 320 ; N bracketright ; B 7 -157 342 754 ;
-C 94 ; WX 600 ; N asciicircum ; B 142 375 596 740 ;
-C 95 ; WX 500 ; N underscore ; B -23 -125 486 -75 ;
-C 96 ; WX 280 ; N quoteleft ; B 158 466 341 740 ;
-C 97 ; WX 660 ; N a ; B 73 -18 716 574 ;
-C 98 ; WX 660 ; N b ; B 47 -18 689 740 ;
-C 99 ; WX 640 ; N c ; B 84 -18 679 574 ;
-C 100 ; WX 660 ; N d ; B 80 -18 755 740 ;
-C 101 ; WX 640 ; N e ; B 77 -18 667 577 ;
-C 102 ; WX 280 ; N f ; B 62 0 420 755 ; L i fi ; L l fl ;
-C 103 ; WX 660 ; N g ; B 33 -226 726 574 ;
-C 104 ; WX 600 ; N h ; B 54 0 614 740 ;
-C 105 ; WX 240 ; N i ; B 53 0 323 740 ;
-C 106 ; WX 260 ; N j ; B -18 -185 342 740 ;
-C 107 ; WX 580 ; N k ; B 80 0 648 740 ;
-C 108 ; WX 240 ; N l ; B 54 0 324 740 ;
-C 109 ; WX 940 ; N m ; B 54 0 954 574 ;
-C 110 ; WX 600 ; N n ; B 54 0 613 574 ;
-C 111 ; WX 640 ; N o ; B 71 -18 672 574 ;
-C 112 ; WX 660 ; N p ; B 13 -185 686 574 ;
-C 113 ; WX 660 ; N q ; B 78 -185 716 574 ;
-C 114 ; WX 320 ; N r ; B 63 0 423 574 ;
-C 115 ; WX 440 ; N s ; B 49 -18 483 574 ;
-C 116 ; WX 300 ; N t ; B 86 0 402 740 ;
-C 117 ; WX 600 ; N u ; B 87 -18 647 555 ;
-C 118 ; WX 560 ; N v ; B 106 0 659 555 ;
-C 119 ; WX 800 ; N w ; B 114 0 892 555 ;
-C 120 ; WX 560 ; N x ; B 3 0 632 555 ;
-C 121 ; WX 580 ; N y ; B 75 -185 674 555 ;
-C 122 ; WX 460 ; N z ; B 20 0 528 555 ;
-C 123 ; WX 340 ; N braceleft ; B 40 -191 455 747 ;
-C 124 ; WX 600 ; N bar ; B 214 -100 503 740 ;
-C 125 ; WX 340 ; N braceright ; B -12 -191 405 747 ;
-C 126 ; WX 600 ; N asciitilde ; B 114 160 579 347 ;
-C 161 ; WX 280 ; N exclamdown ; B 40 -185 310 555 ;
-C 162 ; WX 560 ; N cent ; B 110 39 599 715 ;
-C 163 ; WX 560 ; N sterling ; B 38 0 615 755 ;
-C 164 ; WX 160 ; N fraction ; B -123 0 419 740 ;
-C 165 ; WX 560 ; N yen ; B 83 0 707 740 ;
-C 166 ; WX 560 ; N florin ; B -27 -151 664 824 ;
-C 167 ; WX 560 ; N section ; B 65 -158 602 755 ;
-C 168 ; WX 560 ; N currency ; B 53 69 628 577 ;
-C 169 ; WX 220 ; N quotesingle ; B 152 444 314 740 ;
-C 170 ; WX 480 ; N quotedblleft ; B 156 466 546 740 ;
-C 171 ; WX 460 ; N guillemotleft ; B 105 108 487 469 ;
-C 172 ; WX 240 ; N guilsinglleft ; B 94 108 277 469 ;
-C 173 ; WX 240 ; N guilsinglright ; B 70 108 253 469 ;
-C 174 ; WX 520 ; N fi ; B 72 0 598 755 ;
-C 175 ; WX 520 ; N fl ; B 72 0 598 755 ;
-C 177 ; WX 500 ; N endash ; B 78 230 529 348 ;
-C 178 ; WX 560 ; N dagger ; B 133 -142 612 740 ;
-C 179 ; WX 560 ; N daggerdbl ; B 63 -142 618 740 ;
-C 180 ; WX 280 ; N periodcentered ; B 108 187 265 320 ;
-C 182 ; WX 600 ; N paragraph ; B 90 -103 744 740 ;
-C 183 ; WX 600 ; N bullet ; B 215 222 526 532 ;
-C 184 ; WX 280 ; N quotesinglbase ; B 47 -141 230 133 ;
-C 185 ; WX 480 ; N quotedblbase ; B 45 -141 435 133 ;
-C 186 ; WX 480 ; N quotedblright ; B 157 466 547 740 ;
-C 187 ; WX 460 ; N guillemotright ; B 81 108 463 469 ;
-C 188 ; WX 1000 ; N ellipsis ; B 100 0 924 133 ;
-C 189 ; WX 1280 ; N perthousand ; B 139 -15 1256 755 ;
-C 191 ; WX 560 ; N questiondown ; B 69 -200 527 555 ;
-C 193 ; WX 420 ; N grave ; B 189 624 462 851 ;
-C 194 ; WX 420 ; N acute ; B 224 624 508 849 ;
-C 195 ; WX 540 ; N circumflex ; B 189 636 588 774 ;
-C 196 ; WX 480 ; N tilde ; B 178 636 564 767 ;
-C 197 ; WX 420 ; N macron ; B 192 648 490 759 ;
-C 198 ; WX 480 ; N breve ; B 185 633 582 770 ;
-C 199 ; WX 280 ; N dotaccent ; B 192 636 350 769 ;
-C 200 ; WX 500 ; N dieresis ; B 196 636 565 769 ;
-C 202 ; WX 360 ; N ring ; B 206 619 424 834 ;
-C 203 ; WX 340 ; N cedilla ; B 67 -251 272 6 ;
-C 205 ; WX 700 ; N hungarumlaut ; B 258 610 754 862 ;
-C 206 ; WX 340 ; N ogonek ; B 59 -195 243 9 ;
-C 207 ; WX 540 ; N caron ; B 214 636 613 774 ;
-C 208 ; WX 1000 ; N emdash ; B 78 230 1029 348 ;
-C 225 ; WX 900 ; N AE ; B -5 0 961 740 ;
-C 227 ; WX 360 ; N ordfeminine ; B 127 438 472 755 ;
-C 232 ; WX 480 ; N Lslash ; B 68 0 484 740 ;
-C 233 ; WX 840 ; N Oslash ; B 94 -71 891 814 ;
-C 234 ; WX 1060 ; N OE ; B 98 -15 1144 755 ;
-C 235 ; WX 360 ; N ordmasculine ; B 131 438 451 755 ;
-C 241 ; WX 1080 ; N ae ; B 75 -18 1105 574 ;
-C 245 ; WX 240 ; N dotlessi ; B 53 0 289 555 ;
-C 248 ; WX 320 ; N lslash ; B 74 0 404 740 ;
-C 249 ; WX 660 ; N oslash ; B 81 -50 685 608 ;
-C 250 ; WX 1080 ; N oe ; B 76 -18 1108 574 ;
-C 251 ; WX 600 ; N germandbls ; B 51 -18 629 755 ;
-C -1 ; WX 640 ; N ecircumflex ; B 77 -18 667 774 ;
-C -1 ; WX 640 ; N edieresis ; B 77 -18 667 769 ;
-C -1 ; WX 660 ; N aacute ; B 73 -18 716 849 ;
-C -1 ; WX 740 ; N registered ; B 50 -12 827 752 ;
-C -1 ; WX 240 ; N icircumflex ; B 39 0 438 774 ;
-C -1 ; WX 600 ; N udieresis ; B 87 -18 647 769 ;
-C -1 ; WX 640 ; N ograve ; B 71 -18 672 851 ;
-C -1 ; WX 600 ; N uacute ; B 87 -18 647 849 ;
-C -1 ; WX 600 ; N ucircumflex ; B 87 -18 647 774 ;
-C -1 ; WX 740 ; N Aacute ; B 7 0 732 1019 ;
-C -1 ; WX 240 ; N igrave ; B 53 0 347 851 ;
-C -1 ; WX 280 ; N Icircumflex ; B 72 0 489 944 ;
-C -1 ; WX 640 ; N ccedilla ; B 83 -251 679 574 ;
-C -1 ; WX 660 ; N adieresis ; B 73 -18 716 769 ;
-C -1 ; WX 520 ; N Ecircumflex ; B 61 0 609 944 ;
-C -1 ; WX 440 ; N scaron ; B 49 -18 563 774 ;
-C -1 ; WX 660 ; N thorn ; B 13 -185 686 740 ;
-C -1 ; WX 1000 ; N trademark ; B 131 296 958 740 ;
-C -1 ; WX 640 ; N egrave ; B 77 -18 667 851 ;
-C -1 ; WX 336 ; N threesuperior ; B 87 287 413 749 ;
-C -1 ; WX 460 ; N zcaron ; B 20 0 598 774 ;
-C -1 ; WX 660 ; N atilde ; B 73 -18 716 767 ;
-C -1 ; WX 660 ; N aring ; B 73 -18 716 834 ;
-C -1 ; WX 640 ; N ocircumflex ; B 71 -18 672 774 ;
-C -1 ; WX 520 ; N Edieresis ; B 61 0 606 939 ;
-C -1 ; WX 840 ; N threequarters ; B 97 0 836 749 ;
-C -1 ; WX 580 ; N ydieresis ; B 75 -185 674 769 ;
-C -1 ; WX 580 ; N yacute ; B 75 -185 674 849 ;
-C -1 ; WX 240 ; N iacute ; B 53 0 443 849 ;
-C -1 ; WX 740 ; N Acircumflex ; B 7 0 732 944 ;
-C -1 ; WX 640 ; N Uacute ; B 97 -15 722 1019 ;
-C -1 ; WX 640 ; N eacute ; B 77 -18 667 849 ;
-C -1 ; WX 840 ; N Ograve ; B 95 -15 882 1021 ;
-C -1 ; WX 660 ; N agrave ; B 73 -18 716 851 ;
-C -1 ; WX 640 ; N Udieresis ; B 97 -15 722 939 ;
-C -1 ; WX 660 ; N acircumflex ; B 73 -18 716 774 ;
-C -1 ; WX 280 ; N Igrave ; B 72 0 398 1021 ;
-C -1 ; WX 336 ; N twosuperior ; B 73 296 436 749 ;
-C -1 ; WX 640 ; N Ugrave ; B 97 -15 722 1021 ;
-C -1 ; WX 840 ; N onequarter ; B 187 0 779 740 ;
-C -1 ; WX 640 ; N Ucircumflex ; B 97 -15 722 944 ;
-C -1 ; WX 520 ; N Scaron ; B 49 -15 635 944 ;
-C -1 ; WX 280 ; N Idieresis ; B 72 0 486 939 ;
-C -1 ; WX 240 ; N idieresis ; B 53 0 435 769 ;
-C -1 ; WX 520 ; N Egrave ; B 61 0 596 1021 ;
-C -1 ; WX 840 ; N Oacute ; B 95 -15 882 1019 ;
-C -1 ; WX 600 ; N divide ; B 84 -20 610 526 ;
-C -1 ; WX 740 ; N Atilde ; B 7 0 732 937 ;
-C -1 ; WX 740 ; N Aring ; B 7 0 732 969 ;
-C -1 ; WX 840 ; N Odieresis ; B 95 -15 882 939 ;
-C -1 ; WX 740 ; N Adieresis ; B 7 0 732 939 ;
-C -1 ; WX 740 ; N Ntilde ; B 70 0 808 937 ;
-C -1 ; WX 500 ; N Zcaron ; B 19 0 650 944 ;
-C -1 ; WX 560 ; N Thorn ; B 72 0 619 740 ;
-C -1 ; WX 280 ; N Iacute ; B 72 0 494 1019 ;
-C -1 ; WX 600 ; N plusminus ; B 37 -62 626 556 ;
-C -1 ; WX 600 ; N multiply ; B 76 12 617 494 ;
-C -1 ; WX 520 ; N Eacute ; B 61 0 596 1019 ;
-C -1 ; WX 620 ; N Ydieresis ; B 135 0 759 939 ;
-C -1 ; WX 336 ; N onesuperior ; B 182 296 360 740 ;
-C -1 ; WX 600 ; N ugrave ; B 87 -18 647 851 ;
-C -1 ; WX 600 ; N logicalnot ; B 105 108 631 425 ;
-C -1 ; WX 600 ; N ntilde ; B 54 0 624 767 ;
-C -1 ; WX 840 ; N Otilde ; B 95 -15 882 937 ;
-C -1 ; WX 640 ; N otilde ; B 71 -18 672 767 ;
-C -1 ; WX 780 ; N Ccedilla ; B 97 -251 864 755 ;
-C -1 ; WX 740 ; N Agrave ; B 7 0 732 1021 ;
-C -1 ; WX 840 ; N onehalf ; B 157 0 830 740 ;
-C -1 ; WX 742 ; N Eth ; B 83 0 766 740 ;
-C -1 ; WX 400 ; N degree ; B 160 426 451 712 ;
-C -1 ; WX 620 ; N Yacute ; B 135 0 759 1019 ;
-C -1 ; WX 840 ; N Ocircumflex ; B 95 -15 882 944 ;
-C -1 ; WX 640 ; N oacute ; B 71 -18 672 849 ;
-C -1 ; WX 576 ; N mu ; B 3 -187 642 555 ;
-C -1 ; WX 600 ; N minus ; B 84 193 610 313 ;
-C -1 ; WX 640 ; N eth ; B 73 -18 699 754 ;
-C -1 ; WX 640 ; N odieresis ; B 71 -18 672 769 ;
-C -1 ; WX 740 ; N copyright ; B 50 -12 827 752 ;
-C -1 ; WX 600 ; N brokenbar ; B 214 -100 503 740 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 218
-
-KPX A y -50
-KPX A w -65
-KPX A v -70
-KPX A u -20
-KPX A quoteright -90
-KPX A Y -80
-KPX A W -60
-KPX A V -102
-KPX A U -40
-KPX A T -25
-KPX A Q -50
-KPX A O -50
-KPX A G -40
-KPX A C -40
-
-KPX B A -10
-
-KPX C A -40
-
-KPX D period -20
-KPX D comma -20
-KPX D Y -45
-KPX D W -25
-KPX D V -50
-KPX D A -50
-
-KPX F period -129
-KPX F e -20
-KPX F comma -162
-KPX F a -20
-KPX F A -75
-
-KPX G period -20
-KPX G comma -20
-KPX G Y -15
-
-KPX J period -15
-KPX J a -20
-KPX J A -30
-
-KPX K y -20
-KPX K u -15
-KPX K o -45
-KPX K e -40
-KPX K O -30
-
-KPX L y -23
-KPX L quoteright -30
-KPX L quotedblright -30
-KPX L Y -80
-KPX L W -55
-KPX L V -85
-KPX L T -46
-
-KPX O period -30
-KPX O comma -30
-KPX O Y -30
-KPX O X -30
-KPX O W -20
-KPX O V -45
-KPX O T -15
-KPX O A -60
-
-KPX P period -200
-KPX P o -20
-KPX P e -20
-KPX P comma -220
-KPX P a -20
-KPX P A -100
-
-KPX Q comma 20
-
-KPX R W 25
-KPX R V -10
-KPX R U 25
-KPX R T 40
-KPX R O 25
-
-KPX S comma 20
-
-KPX T y -10
-KPX T w -55
-KPX T u -46
-KPX T semicolon -29
-KPX T r -30
-KPX T period -91
-KPX T o -49
-KPX T hyphen -75
-KPX T e -49
-KPX T comma -82
-KPX T colon -15
-KPX T a -70
-KPX T O -15
-KPX T A -25
-
-KPX U period -20
-KPX U comma -20
-KPX U A -40
-
-KPX V u -55
-KPX V semicolon -33
-KPX V period -145
-KPX V o -101
-KPX V i -15
-KPX V hyphen -75
-KPX V e -101
-KPX V comma -145
-KPX V colon -18
-KPX V a -95
-KPX V O -45
-KPX V G -20
-KPX V A -102
-
-KPX W y -15
-KPX W u -30
-KPX W semicolon -33
-KPX W period -106
-KPX W o -46
-KPX W i -10
-KPX W hyphen -35
-KPX W e -47
-KPX W comma -106
-KPX W colon -15
-KPX W a -50
-KPX W O -20
-KPX W A -58
-
-KPX Y u -52
-KPX Y semicolon -23
-KPX Y period -145
-KPX Y o -89
-KPX Y hyphen -100
-KPX Y e -89
-KPX Y comma -145
-KPX Y colon -10
-KPX Y a -93
-KPX Y O -30
-KPX Y A -80
-
-KPX a t 5
-KPX a p 20
-KPX a b 5
-
-KPX b y -20
-KPX b v -20
-
-KPX c y -20
-KPX c l -15
-KPX c k -15
-
-KPX comma space -50
-KPX comma quoteright -70
-KPX comma quotedblright -70
-
-KPX e y -20
-KPX e x -20
-KPX e w -20
-KPX e v -20
-
-KPX f period -40
-KPX f o -20
-KPX f l -15
-KPX f i -15
-KPX f f -20
-KPX f dotlessi -15
-KPX f comma -40
-KPX f a -15
-
-KPX g i 25
-KPX g a 15
-
-KPX h y -30
-
-KPX k y -5
-KPX k o -30
-KPX k e -40
-
-KPX m y -20
-KPX m u -20
-
-KPX n y -15
-KPX n v -30
-
-KPX o y -20
-KPX o x -30
-KPX o w -20
-KPX o v -30
-
-KPX p y -20
-
-KPX period space -50
-KPX period quoteright -70
-KPX period quotedblright -70
-
-KPX quotedblleft A -50
-
-KPX quotedblright space -50
-
-KPX quoteleft quoteleft -80
-KPX quoteleft A -50
-
-KPX quoteright v -10
-KPX quoteright t 10
-KPX quoteright space -50
-KPX quoteright s -15
-KPX quoteright r -20
-KPX quoteright quoteright -80
-KPX quoteright d -50
-
-KPX r y 40
-KPX r v 40
-KPX r u 20
-KPX r t 20
-KPX r s 20
-KPX r q -8
-KPX r period -73
-KPX r p 20
-KPX r o -15
-KPX r n 21
-KPX r m 15
-KPX r l 20
-KPX r k 5
-KPX r i 20
-KPX r hyphen -60
-KPX r g 1
-KPX r e -4
-KPX r d -6
-KPX r comma -75
-KPX r c -7
-
-KPX s period 20
-KPX s comma 20
-
-KPX space quoteleft -50
-KPX space quotedblleft -50
-KPX space Y -60
-KPX space W -25
-KPX space V -80
-KPX space T -25
-KPX space A -20
-
-KPX v period -90
-KPX v o -20
-KPX v e -20
-KPX v comma -90
-KPX v a -30
-
-KPX w period -90
-KPX w o -30
-KPX w e -20
-KPX w comma -90
-KPX w a -30
-
-KPX x e -20
-
-KPX y period -100
-KPX y o -30
-KPX y e -20
-KPX y comma -100
-KPX y c -35
-KPX y a -30
-EndKernPairs
-EndKernData
-StartComposites 56
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 192 170 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 132 170 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 152 170 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 192 170 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 215 135 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 162 170 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 82 170 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 22 170 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 42 170 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 82 170 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute -13 170 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -98 170 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -78 170 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave -63 170 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 162 170 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 242 170 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 182 170 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 202 170 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 242 170 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 212 170 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 22 170 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 177 170 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 82 170 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 102 170 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 107 170 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 167 170 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 92 170 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 37 170 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 120 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 60 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 120 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 150 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 90 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 110 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 50 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 70 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 110 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -65 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -150 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -130 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -115 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 60 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 110 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 50 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 70 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 80 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron -50 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 125 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 30 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 50 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 55 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 115 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 40 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron -15 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pagk8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pagk8a.afm
deleted file mode 100644
index 53b03bbb88..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pagk8a.afm
+++ /dev/null
@@ -1,573 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Mon Mar 4 13:37:31 1991
-Comment UniqueID 34364
-Comment VMusage 24225 31117
-FontName AvantGarde-Book
-FullName ITC Avant Garde Gothic Book
-FamilyName ITC Avant Garde Gothic
-Weight Book
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -113 -222 1148 955
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.006
-Notice Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved.ITC Avant Garde Gothic is a registered trademark of International Typeface Corporation.
-EncodingScheme AdobeStandardEncoding
-CapHeight 740
-XHeight 547
-Ascender 740
-Descender -192
-StartCharMetrics 228
-C 32 ; WX 277 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 295 ; N exclam ; B 111 0 185 740 ;
-C 34 ; WX 309 ; N quotedbl ; B 36 444 273 740 ;
-C 35 ; WX 554 ; N numbersign ; B 33 0 521 740 ;
-C 36 ; WX 554 ; N dollar ; B 70 -70 485 811 ;
-C 37 ; WX 775 ; N percent ; B 21 -13 753 751 ;
-C 38 ; WX 757 ; N ampersand ; B 56 -12 736 753 ;
-C 39 ; WX 351 ; N quoteright ; B 94 546 256 740 ;
-C 40 ; WX 369 ; N parenleft ; B 47 -205 355 757 ;
-C 41 ; WX 369 ; N parenright ; B 14 -205 322 757 ;
-C 42 ; WX 425 ; N asterisk ; B 58 446 367 740 ;
-C 43 ; WX 606 ; N plus ; B 51 0 555 506 ;
-C 44 ; WX 277 ; N comma ; B 14 -67 176 126 ;
-C 45 ; WX 332 ; N hyphen ; B 30 248 302 315 ;
-C 46 ; WX 277 ; N period ; B 102 0 176 126 ;
-C 47 ; WX 437 ; N slash ; B 44 -100 403 740 ;
-C 48 ; WX 554 ; N zero ; B 29 -13 525 753 ;
-C 49 ; WX 554 ; N one ; B 135 0 336 740 ;
-C 50 ; WX 554 ; N two ; B 40 0 514 753 ;
-C 51 ; WX 554 ; N three ; B 34 -13 506 753 ;
-C 52 ; WX 554 ; N four ; B 14 0 528 740 ;
-C 53 ; WX 554 ; N five ; B 26 -13 530 740 ;
-C 54 ; WX 554 ; N six ; B 24 -13 530 739 ;
-C 55 ; WX 554 ; N seven ; B 63 0 491 740 ;
-C 56 ; WX 554 ; N eight ; B 41 -13 513 753 ;
-C 57 ; WX 554 ; N nine ; B 24 0 530 752 ;
-C 58 ; WX 277 ; N colon ; B 102 0 176 548 ;
-C 59 ; WX 277 ; N semicolon ; B 14 -67 176 548 ;
-C 60 ; WX 606 ; N less ; B 46 -8 554 514 ;
-C 61 ; WX 606 ; N equal ; B 51 118 555 388 ;
-C 62 ; WX 606 ; N greater ; B 52 -8 560 514 ;
-C 63 ; WX 591 ; N question ; B 64 0 526 752 ;
-C 64 ; WX 867 ; N at ; B 65 -13 803 753 ;
-C 65 ; WX 740 ; N A ; B 12 0 729 740 ;
-C 66 ; WX 574 ; N B ; B 74 0 544 740 ;
-C 67 ; WX 813 ; N C ; B 43 -13 771 752 ;
-C 68 ; WX 744 ; N D ; B 74 0 699 740 ;
-C 69 ; WX 536 ; N E ; B 70 0 475 740 ;
-C 70 ; WX 485 ; N F ; B 70 0 444 740 ;
-C 71 ; WX 872 ; N G ; B 40 -13 828 753 ;
-C 72 ; WX 683 ; N H ; B 76 0 607 740 ;
-C 73 ; WX 226 ; N I ; B 76 0 150 740 ;
-C 74 ; WX 482 ; N J ; B 6 -13 402 740 ;
-C 75 ; WX 591 ; N K ; B 81 0 591 740 ;
-C 76 ; WX 462 ; N L ; B 82 0 462 740 ;
-C 77 ; WX 919 ; N M ; B 76 0 843 740 ;
-C 78 ; WX 740 ; N N ; B 75 0 664 740 ;
-C 79 ; WX 869 ; N O ; B 43 -13 826 753 ;
-C 80 ; WX 592 ; N P ; B 75 0 564 740 ;
-C 81 ; WX 871 ; N Q ; B 40 -13 837 753 ;
-C 82 ; WX 607 ; N R ; B 70 0 572 740 ;
-C 83 ; WX 498 ; N S ; B 22 -13 473 753 ;
-C 84 ; WX 426 ; N T ; B 6 0 419 740 ;
-C 85 ; WX 655 ; N U ; B 75 -13 579 740 ;
-C 86 ; WX 702 ; N V ; B 8 0 693 740 ;
-C 87 ; WX 960 ; N W ; B 11 0 950 740 ;
-C 88 ; WX 609 ; N X ; B 8 0 602 740 ;
-C 89 ; WX 592 ; N Y ; B 1 0 592 740 ;
-C 90 ; WX 480 ; N Z ; B 12 0 470 740 ;
-C 91 ; WX 351 ; N bracketleft ; B 133 -179 337 753 ;
-C 92 ; WX 605 ; N backslash ; B 118 -100 477 740 ;
-C 93 ; WX 351 ; N bracketright ; B 14 -179 218 753 ;
-C 94 ; WX 606 ; N asciicircum ; B 53 307 553 740 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 351 ; N quoteleft ; B 95 546 257 740 ;
-C 97 ; WX 683 ; N a ; B 42 -13 621 561 ;
-C 98 ; WX 682 ; N b ; B 68 -13 647 740 ;
-C 99 ; WX 647 ; N c ; B 41 -13 607 561 ;
-C 100 ; WX 685 ; N d ; B 39 -13 618 740 ;
-C 101 ; WX 650 ; N e ; B 38 -13 608 561 ;
-C 102 ; WX 314 ; N f ; B 19 0 314 753 ; L i fi ; L l fl ;
-C 103 ; WX 673 ; N g ; B 37 -215 606 561 ;
-C 104 ; WX 610 ; N h ; B 62 0 543 740 ;
-C 105 ; WX 200 ; N i ; B 65 0 135 740 ;
-C 106 ; WX 203 ; N j ; B -44 -192 137 740 ;
-C 107 ; WX 502 ; N k ; B 70 0 498 740 ;
-C 108 ; WX 200 ; N l ; B 65 0 135 740 ;
-C 109 ; WX 938 ; N m ; B 66 0 872 561 ;
-C 110 ; WX 610 ; N n ; B 65 0 546 561 ;
-C 111 ; WX 655 ; N o ; B 42 -13 614 561 ;
-C 112 ; WX 682 ; N p ; B 64 -192 643 561 ;
-C 113 ; WX 682 ; N q ; B 37 -192 616 561 ;
-C 114 ; WX 301 ; N r ; B 65 0 291 561 ;
-C 115 ; WX 388 ; N s ; B 24 -13 364 561 ;
-C 116 ; WX 339 ; N t ; B 14 0 330 740 ;
-C 117 ; WX 608 ; N u ; B 62 -13 541 547 ;
-C 118 ; WX 554 ; N v ; B 7 0 546 547 ;
-C 119 ; WX 831 ; N w ; B 13 0 820 547 ;
-C 120 ; WX 480 ; N x ; B 12 0 468 547 ;
-C 121 ; WX 536 ; N y ; B 15 -192 523 547 ;
-C 122 ; WX 425 ; N z ; B 10 0 415 547 ;
-C 123 ; WX 351 ; N braceleft ; B 70 -189 331 740 ;
-C 124 ; WX 672 ; N bar ; B 299 -100 373 740 ;
-C 125 ; WX 351 ; N braceright ; B 20 -189 281 740 ;
-C 126 ; WX 606 ; N asciitilde ; B 72 179 534 319 ;
-C 161 ; WX 295 ; N exclamdown ; B 110 -192 184 548 ;
-C 162 ; WX 554 ; N cent ; B 48 62 510 707 ;
-C 163 ; WX 554 ; N sterling ; B 4 0 552 753 ;
-C 164 ; WX 166 ; N fraction ; B -113 0 280 740 ;
-C 165 ; WX 554 ; N yen ; B 4 0 550 740 ;
-C 166 ; WX 554 ; N florin ; B -12 -153 518 818 ;
-C 167 ; WX 615 ; N section ; B 85 -141 529 753 ;
-C 168 ; WX 554 ; N currency ; B 8 42 546 580 ;
-C 169 ; WX 198 ; N quotesingle ; B 59 444 140 740 ;
-C 170 ; WX 502 ; N quotedblleft ; B 97 546 406 740 ;
-C 171 ; WX 425 ; N guillemotleft ; B 40 81 386 481 ;
-C 172 ; WX 251 ; N guilsinglleft ; B 40 81 212 481 ;
-C 173 ; WX 251 ; N guilsinglright ; B 39 81 211 481 ;
-C 174 ; WX 487 ; N fi ; B 19 0 422 753 ;
-C 175 ; WX 485 ; N fl ; B 19 0 420 753 ;
-C 177 ; WX 500 ; N endash ; B 35 248 465 315 ;
-C 178 ; WX 553 ; N dagger ; B 59 -133 493 740 ;
-C 179 ; WX 553 ; N daggerdbl ; B 59 -133 493 740 ;
-C 180 ; WX 277 ; N periodcentered ; B 102 190 176 316 ;
-C 182 ; WX 564 ; N paragraph ; B 22 -110 551 740 ;
-C 183 ; WX 606 ; N bullet ; B 150 222 455 532 ;
-C 184 ; WX 354 ; N quotesinglbase ; B 89 -68 251 126 ;
-C 185 ; WX 502 ; N quotedblbase ; B 89 -68 399 126 ;
-C 186 ; WX 484 ; N quotedblright ; B 96 546 405 740 ;
-C 187 ; WX 425 ; N guillemotright ; B 39 81 385 481 ;
-C 188 ; WX 1000 ; N ellipsis ; B 130 0 870 126 ;
-C 189 ; WX 1174 ; N perthousand ; B 25 -13 1148 751 ;
-C 191 ; WX 591 ; N questiondown ; B 65 -205 527 548 ;
-C 193 ; WX 378 ; N grave ; B 69 619 300 786 ;
-C 194 ; WX 375 ; N acute ; B 78 619 309 786 ;
-C 195 ; WX 502 ; N circumflex ; B 74 639 428 764 ;
-C 196 ; WX 439 ; N tilde ; B 47 651 392 754 ;
-C 197 ; WX 485 ; N macron ; B 73 669 411 736 ;
-C 198 ; WX 453 ; N breve ; B 52 651 401 754 ;
-C 199 ; WX 222 ; N dotaccent ; B 74 639 148 765 ;
-C 200 ; WX 369 ; N dieresis ; B 73 639 295 765 ;
-C 202 ; WX 332 ; N ring ; B 62 600 269 807 ;
-C 203 ; WX 324 ; N cedilla ; B 80 -222 254 0 ;
-C 205 ; WX 552 ; N hungarumlaut ; B 119 605 453 800 ;
-C 206 ; WX 302 ; N ogonek ; B 73 -191 228 0 ;
-C 207 ; WX 502 ; N caron ; B 68 639 423 764 ;
-C 208 ; WX 1000 ; N emdash ; B 35 248 965 315 ;
-C 225 ; WX 992 ; N AE ; B -20 0 907 740 ;
-C 227 ; WX 369 ; N ordfeminine ; B -3 407 356 753 ;
-C 232 ; WX 517 ; N Lslash ; B 59 0 517 740 ;
-C 233 ; WX 868 ; N Oslash ; B 43 -83 826 819 ;
-C 234 ; WX 1194 ; N OE ; B 45 -13 1142 753 ;
-C 235 ; WX 369 ; N ordmasculine ; B 12 407 356 753 ;
-C 241 ; WX 1157 ; N ae ; B 34 -13 1113 561 ;
-C 245 ; WX 200 ; N dotlessi ; B 65 0 135 547 ;
-C 248 ; WX 300 ; N lslash ; B 43 0 259 740 ;
-C 249 ; WX 653 ; N oslash ; B 41 -64 613 614 ;
-C 250 ; WX 1137 ; N oe ; B 34 -13 1104 561 ;
-C 251 ; WX 554 ; N germandbls ; B 61 -13 525 753 ;
-C -1 ; WX 650 ; N ecircumflex ; B 38 -13 608 764 ;
-C -1 ; WX 650 ; N edieresis ; B 38 -13 608 765 ;
-C -1 ; WX 683 ; N aacute ; B 42 -13 621 786 ;
-C -1 ; WX 747 ; N registered ; B -9 -12 755 752 ;
-C -1 ; WX 200 ; N icircumflex ; B -77 0 277 764 ;
-C -1 ; WX 608 ; N udieresis ; B 62 -13 541 765 ;
-C -1 ; WX 655 ; N ograve ; B 42 -13 614 786 ;
-C -1 ; WX 608 ; N uacute ; B 62 -13 541 786 ;
-C -1 ; WX 608 ; N ucircumflex ; B 62 -13 541 764 ;
-C -1 ; WX 740 ; N Aacute ; B 12 0 729 949 ;
-C -1 ; WX 200 ; N igrave ; B -60 0 171 786 ;
-C -1 ; WX 226 ; N Icircumflex ; B -64 0 290 927 ;
-C -1 ; WX 647 ; N ccedilla ; B 41 -222 607 561 ;
-C -1 ; WX 683 ; N adieresis ; B 42 -13 621 765 ;
-C -1 ; WX 536 ; N Ecircumflex ; B 70 0 475 927 ;
-C -1 ; WX 388 ; N scaron ; B 11 -13 366 764 ;
-C -1 ; WX 682 ; N thorn ; B 64 -192 643 740 ;
-C -1 ; WX 1000 ; N trademark ; B 9 296 816 740 ;
-C -1 ; WX 650 ; N egrave ; B 38 -13 608 786 ;
-C -1 ; WX 332 ; N threesuperior ; B 18 289 318 747 ;
-C -1 ; WX 425 ; N zcaron ; B 10 0 415 764 ;
-C -1 ; WX 683 ; N atilde ; B 42 -13 621 754 ;
-C -1 ; WX 683 ; N aring ; B 42 -13 621 807 ;
-C -1 ; WX 655 ; N ocircumflex ; B 42 -13 614 764 ;
-C -1 ; WX 536 ; N Edieresis ; B 70 0 475 928 ;
-C -1 ; WX 831 ; N threequarters ; B 46 0 784 747 ;
-C -1 ; WX 536 ; N ydieresis ; B 15 -192 523 765 ;
-C -1 ; WX 536 ; N yacute ; B 15 -192 523 786 ;
-C -1 ; WX 200 ; N iacute ; B 31 0 262 786 ;
-C -1 ; WX 740 ; N Acircumflex ; B 12 0 729 927 ;
-C -1 ; WX 655 ; N Uacute ; B 75 -13 579 949 ;
-C -1 ; WX 650 ; N eacute ; B 38 -13 608 786 ;
-C -1 ; WX 869 ; N Ograve ; B 43 -13 826 949 ;
-C -1 ; WX 683 ; N agrave ; B 42 -13 621 786 ;
-C -1 ; WX 655 ; N Udieresis ; B 75 -13 579 928 ;
-C -1 ; WX 683 ; N acircumflex ; B 42 -13 621 764 ;
-C -1 ; WX 226 ; N Igrave ; B -47 0 184 949 ;
-C -1 ; WX 332 ; N twosuperior ; B 19 296 318 747 ;
-C -1 ; WX 655 ; N Ugrave ; B 75 -13 579 949 ;
-C -1 ; WX 831 ; N onequarter ; B 100 0 729 740 ;
-C -1 ; WX 655 ; N Ucircumflex ; B 75 -13 579 927 ;
-C -1 ; WX 498 ; N Scaron ; B 22 -13 473 927 ;
-C -1 ; WX 226 ; N Idieresis ; B 2 0 224 928 ;
-C -1 ; WX 200 ; N idieresis ; B -11 0 211 765 ;
-C -1 ; WX 536 ; N Egrave ; B 70 0 475 949 ;
-C -1 ; WX 869 ; N Oacute ; B 43 -13 826 949 ;
-C -1 ; WX 606 ; N divide ; B 51 -13 555 519 ;
-C -1 ; WX 740 ; N Atilde ; B 12 0 729 917 ;
-C -1 ; WX 740 ; N Aring ; B 12 0 729 955 ;
-C -1 ; WX 869 ; N Odieresis ; B 43 -13 826 928 ;
-C -1 ; WX 740 ; N Adieresis ; B 12 0 729 928 ;
-C -1 ; WX 740 ; N Ntilde ; B 75 0 664 917 ;
-C -1 ; WX 480 ; N Zcaron ; B 12 0 470 927 ;
-C -1 ; WX 592 ; N Thorn ; B 60 0 549 740 ;
-C -1 ; WX 226 ; N Iacute ; B 44 0 275 949 ;
-C -1 ; WX 606 ; N plusminus ; B 51 -24 555 518 ;
-C -1 ; WX 606 ; N multiply ; B 74 24 533 482 ;
-C -1 ; WX 536 ; N Eacute ; B 70 0 475 949 ;
-C -1 ; WX 592 ; N Ydieresis ; B 1 0 592 928 ;
-C -1 ; WX 332 ; N onesuperior ; B 63 296 198 740 ;
-C -1 ; WX 608 ; N ugrave ; B 62 -13 541 786 ;
-C -1 ; WX 606 ; N logicalnot ; B 51 109 555 388 ;
-C -1 ; WX 610 ; N ntilde ; B 65 0 546 754 ;
-C -1 ; WX 869 ; N Otilde ; B 43 -13 826 917 ;
-C -1 ; WX 655 ; N otilde ; B 42 -13 614 754 ;
-C -1 ; WX 813 ; N Ccedilla ; B 43 -222 771 752 ;
-C -1 ; WX 740 ; N Agrave ; B 12 0 729 949 ;
-C -1 ; WX 831 ; N onehalf ; B 81 0 750 740 ;
-C -1 ; WX 790 ; N Eth ; B 40 0 739 740 ;
-C -1 ; WX 400 ; N degree ; B 56 421 344 709 ;
-C -1 ; WX 592 ; N Yacute ; B 1 0 592 949 ;
-C -1 ; WX 869 ; N Ocircumflex ; B 43 -13 826 927 ;
-C -1 ; WX 655 ; N oacute ; B 42 -13 614 786 ;
-C -1 ; WX 608 ; N mu ; B 80 -184 527 547 ;
-C -1 ; WX 606 ; N minus ; B 51 219 555 287 ;
-C -1 ; WX 655 ; N eth ; B 42 -12 614 753 ;
-C -1 ; WX 655 ; N odieresis ; B 42 -13 614 765 ;
-C -1 ; WX 747 ; N copyright ; B -9 -12 755 752 ;
-C -1 ; WX 672 ; N brokenbar ; B 299 -100 373 740 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 216
-
-KPX A y -62
-KPX A w -65
-KPX A v -70
-KPX A u -20
-KPX A quoteright -100
-KPX A quotedblright -100
-KPX A Y -92
-KPX A W -60
-KPX A V -102
-KPX A U -40
-KPX A T -45
-KPX A Q -40
-KPX A O -50
-KPX A G -40
-KPX A C -40
-
-KPX B A -10
-
-KPX C A -40
-
-KPX D period -20
-KPX D comma -20
-KPX D Y -30
-KPX D W -10
-KPX D V -50
-KPX D A -50
-
-KPX F period -160
-KPX F e -20
-KPX F comma -180
-KPX F a -20
-KPX F A -75
-
-KPX G period -20
-KPX G comma -20
-KPX G Y -20
-
-KPX J period -15
-KPX J a -20
-KPX J A -30
-
-KPX K o -15
-KPX K e -20
-KPX K O -20
-
-KPX L y -23
-KPX L quoteright -130
-KPX L quotedblright -130
-KPX L Y -91
-KPX L W -67
-KPX L V -113
-KPX L T -46
-
-KPX O period -30
-KPX O comma -30
-KPX O Y -30
-KPX O X -30
-KPX O W -20
-KPX O V -60
-KPX O T -30
-KPX O A -60
-
-KPX P period -300
-KPX P o -60
-KPX P e -20
-KPX P comma -280
-KPX P a -20
-KPX P A -114
-
-KPX Q comma 20
-
-KPX R Y -10
-KPX R W 10
-KPX R V -10
-KPX R T 6
-
-KPX S comma 20
-
-KPX T y -50
-KPX T w -55
-KPX T u -46
-KPX T semicolon -29
-KPX T r -30
-KPX T period -91
-KPX T o -70
-KPX T i 10
-KPX T hyphen -75
-KPX T e -49
-KPX T comma -82
-KPX T colon -15
-KPX T a -90
-KPX T O -30
-KPX T A -45
-
-KPX U period -20
-KPX U comma -20
-KPX U A -40
-
-KPX V u -40
-KPX V semicolon -33
-KPX V period -165
-KPX V o -101
-KPX V i -5
-KPX V hyphen -75
-KPX V e -101
-KPX V comma -145
-KPX V colon -18
-KPX V a -104
-KPX V O -60
-KPX V G -20
-KPX V A -102
-
-KPX W y -2
-KPX W u -30
-KPX W semicolon -33
-KPX W period -106
-KPX W o -46
-KPX W i 6
-KPX W hyphen -35
-KPX W e -47
-KPX W comma -106
-KPX W colon -15
-KPX W a -50
-KPX W O -20
-KPX W A -58
-
-KPX Y u -52
-KPX Y semicolon -23
-KPX Y period -175
-KPX Y o -89
-KPX Y hyphen -85
-KPX Y e -89
-KPX Y comma -145
-KPX Y colon -10
-KPX Y a -93
-KPX Y O -30
-KPX Y A -92
-
-KPX a p 20
-KPX a b 20
-
-KPX b y -20
-KPX b v -20
-
-KPX c y -20
-KPX c k -15
-
-KPX comma space -110
-KPX comma quoteright -120
-KPX comma quotedblright -120
-
-KPX e y -20
-KPX e w -20
-KPX e v -20
-
-KPX f period -50
-KPX f o -40
-KPX f l -30
-KPX f i -34
-KPX f f -60
-KPX f e -20
-KPX f dotlessi -34
-KPX f comma -50
-KPX f a -40
-
-KPX g a -15
-
-KPX h y -30
-
-KPX k y -5
-KPX k e -15
-
-KPX m y -20
-KPX m u -20
-KPX m a -20
-
-KPX n y -15
-KPX n v -20
-
-KPX o y -20
-KPX o x -15
-KPX o w -20
-KPX o v -30
-
-KPX p y -20
-
-KPX period space -110
-KPX period quoteright -120
-KPX period quotedblright -120
-
-KPX quotedblleft quoteleft -35
-KPX quotedblleft A -100
-
-KPX quotedblright space -110
-
-KPX quoteleft quoteleft -203
-KPX quoteleft A -100
-
-KPX quoteright v -30
-KPX quoteright t 10
-KPX quoteright space -110
-KPX quoteright s -15
-KPX quoteright r -20
-KPX quoteright quoteright -203
-KPX quoteright quotedblright -35
-KPX quoteright d -110
-
-KPX r y 40
-KPX r v 40
-KPX r u 20
-KPX r t 20
-KPX r s 20
-KPX r q -8
-KPX r period -73
-KPX r p 20
-KPX r o -20
-KPX r n 21
-KPX r m 28
-KPX r l 20
-KPX r k 20
-KPX r i 20
-KPX r hyphen -60
-KPX r g -15
-KPX r e -4
-KPX r d -6
-KPX r comma -75
-KPX r c -20
-KPX r a -20
-
-KPX s period 20
-KPX s comma 20
-
-KPX space quoteleft -110
-KPX space quotedblleft -110
-KPX space Y -60
-KPX space W -25
-KPX space V -50
-KPX space T -25
-KPX space A -20
-
-KPX v period -130
-KPX v o -30
-KPX v e -20
-KPX v comma -100
-KPX v a -30
-
-KPX w period -100
-KPX w o -30
-KPX w h 15
-KPX w e -20
-KPX w comma -90
-KPX w a -30
-
-KPX y period -125
-KPX y o -30
-KPX y e -20
-KPX y comma -110
-KPX y a -30
-EndKernPairs
-EndKernData
-StartComposites 56
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 183 163 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 119 163 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 186 163 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 181 163 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 204 148 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 151 163 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 81 163 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 17 163 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 84 163 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 79 163 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute -34 163 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -138 163 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -71 163 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave -116 163 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 151 163 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 247 163 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 184 163 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 250 163 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 246 163 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 163 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron -2 163 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 160 163 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 77 163 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 143 163 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 119 163 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 129 163 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 112 163 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron -11 163 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 154 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 91 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 157 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 153 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 176 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 122 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 138 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 74 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 141 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 136 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -47 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -151 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -84 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -129 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 86 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 140 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 77 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 143 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 108 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron -57 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 137 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 53 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 120 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 95 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 101 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron -38 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pagko8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pagko8a.afm
deleted file mode 100644
index e0e75f384e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pagko8a.afm
+++ /dev/null
@@ -1,573 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Mon Mar 4 13:41:11 1991
-Comment UniqueID 34367
-Comment VMusage 6555 39267
-FontName AvantGarde-BookOblique
-FullName ITC Avant Garde Gothic Book Oblique
-FamilyName ITC Avant Garde Gothic
-Weight Book
-ItalicAngle -10.5
-IsFixedPitch false
-FontBBox -113 -222 1279 955
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.006
-Notice Copyright (c) 1985, 1987, 1989, 1990, 1991 Adobe Systems Incorporated. All Rights Reserved.ITC Avant Garde Gothic is a registered trademark of International Typeface Corporation.
-EncodingScheme AdobeStandardEncoding
-CapHeight 740
-XHeight 547
-Ascender 740
-Descender -192
-StartCharMetrics 228
-C 32 ; WX 277 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 295 ; N exclam ; B 111 0 322 740 ;
-C 34 ; WX 309 ; N quotedbl ; B 130 444 410 740 ;
-C 35 ; WX 554 ; N numbersign ; B 71 0 620 740 ;
-C 36 ; WX 554 ; N dollar ; B 107 -70 581 811 ;
-C 37 ; WX 775 ; N percent ; B 124 -13 787 751 ;
-C 38 ; WX 757 ; N ampersand ; B 92 -12 775 753 ;
-C 39 ; WX 351 ; N quoteright ; B 195 546 393 740 ;
-C 40 ; WX 369 ; N parenleft ; B 89 -205 495 757 ;
-C 41 ; WX 369 ; N parenright ; B -24 -205 382 757 ;
-C 42 ; WX 425 ; N asterisk ; B 170 446 479 740 ;
-C 43 ; WX 606 ; N plus ; B 92 0 608 506 ;
-C 44 ; WX 277 ; N comma ; B 2 -67 199 126 ;
-C 45 ; WX 332 ; N hyphen ; B 76 248 360 315 ;
-C 46 ; WX 277 ; N period ; B 102 0 199 126 ;
-C 47 ; WX 437 ; N slash ; B 25 -100 540 740 ;
-C 48 ; WX 554 ; N zero ; B 71 -13 622 753 ;
-C 49 ; WX 554 ; N one ; B 260 0 473 740 ;
-C 50 ; WX 554 ; N two ; B 40 0 615 753 ;
-C 51 ; WX 554 ; N three ; B 73 -13 565 753 ;
-C 52 ; WX 554 ; N four ; B 39 0 598 740 ;
-C 53 ; WX 554 ; N five ; B 69 -13 605 740 ;
-C 54 ; WX 554 ; N six ; B 65 -13 580 739 ;
-C 55 ; WX 554 ; N seven ; B 110 0 628 740 ;
-C 56 ; WX 554 ; N eight ; B 77 -13 580 753 ;
-C 57 ; WX 554 ; N nine ; B 111 0 626 752 ;
-C 58 ; WX 277 ; N colon ; B 102 0 278 548 ;
-C 59 ; WX 277 ; N semicolon ; B 2 -67 278 548 ;
-C 60 ; WX 606 ; N less ; B 87 -8 649 514 ;
-C 61 ; WX 606 ; N equal ; B 73 118 627 388 ;
-C 62 ; WX 606 ; N greater ; B 51 -8 613 514 ;
-C 63 ; WX 591 ; N question ; B 158 0 628 752 ;
-C 64 ; WX 867 ; N at ; B 126 -13 888 753 ;
-C 65 ; WX 740 ; N A ; B 12 0 729 740 ;
-C 66 ; WX 574 ; N B ; B 74 0 606 740 ;
-C 67 ; WX 813 ; N C ; B 105 -13 870 752 ;
-C 68 ; WX 744 ; N D ; B 74 0 773 740 ;
-C 69 ; WX 536 ; N E ; B 70 0 612 740 ;
-C 70 ; WX 485 ; N F ; B 70 0 581 740 ;
-C 71 ; WX 872 ; N G ; B 103 -13 891 753 ;
-C 72 ; WX 683 ; N H ; B 76 0 744 740 ;
-C 73 ; WX 226 ; N I ; B 76 0 287 740 ;
-C 74 ; WX 482 ; N J ; B 37 -13 539 740 ;
-C 75 ; WX 591 ; N K ; B 81 0 728 740 ;
-C 76 ; WX 462 ; N L ; B 82 0 474 740 ;
-C 77 ; WX 919 ; N M ; B 76 0 980 740 ;
-C 78 ; WX 740 ; N N ; B 75 0 801 740 ;
-C 79 ; WX 869 ; N O ; B 105 -13 901 753 ;
-C 80 ; WX 592 ; N P ; B 75 0 664 740 ;
-C 81 ; WX 871 ; N Q ; B 102 -13 912 753 ;
-C 82 ; WX 607 ; N R ; B 70 0 669 740 ;
-C 83 ; WX 498 ; N S ; B 57 -13 561 753 ;
-C 84 ; WX 426 ; N T ; B 131 0 556 740 ;
-C 85 ; WX 655 ; N U ; B 118 -13 716 740 ;
-C 86 ; WX 702 ; N V ; B 145 0 830 740 ;
-C 87 ; WX 960 ; N W ; B 148 0 1087 740 ;
-C 88 ; WX 609 ; N X ; B 8 0 724 740 ;
-C 89 ; WX 592 ; N Y ; B 138 0 729 740 ;
-C 90 ; WX 480 ; N Z ; B 12 0 596 740 ;
-C 91 ; WX 351 ; N bracketleft ; B 145 -179 477 753 ;
-C 92 ; WX 605 ; N backslash ; B 255 -100 458 740 ;
-C 93 ; WX 351 ; N bracketright ; B -19 -179 312 753 ;
-C 94 ; WX 606 ; N asciicircum ; B 110 307 610 740 ;
-C 95 ; WX 500 ; N underscore ; B -23 -125 486 -75 ;
-C 96 ; WX 351 ; N quoteleft ; B 232 546 358 740 ;
-C 97 ; WX 683 ; N a ; B 88 -13 722 561 ;
-C 98 ; WX 682 ; N b ; B 68 -13 703 740 ;
-C 99 ; WX 647 ; N c ; B 87 -13 678 561 ;
-C 100 ; WX 685 ; N d ; B 85 -13 755 740 ;
-C 101 ; WX 650 ; N e ; B 84 -13 664 561 ;
-C 102 ; WX 314 ; N f ; B 104 0 454 753 ; L i fi ; L l fl ;
-C 103 ; WX 673 ; N g ; B 56 -215 707 561 ;
-C 104 ; WX 610 ; N h ; B 62 0 606 740 ;
-C 105 ; WX 200 ; N i ; B 65 0 272 740 ;
-C 106 ; WX 203 ; N j ; B -80 -192 274 740 ;
-C 107 ; WX 502 ; N k ; B 70 0 588 740 ;
-C 108 ; WX 200 ; N l ; B 65 0 272 740 ;
-C 109 ; WX 938 ; N m ; B 66 0 938 561 ;
-C 110 ; WX 610 ; N n ; B 65 0 609 561 ;
-C 111 ; WX 655 ; N o ; B 88 -13 669 561 ;
-C 112 ; WX 682 ; N p ; B 28 -192 699 561 ;
-C 113 ; WX 682 ; N q ; B 83 -192 717 561 ;
-C 114 ; WX 301 ; N r ; B 65 0 395 561 ;
-C 115 ; WX 388 ; N s ; B 49 -13 424 561 ;
-C 116 ; WX 339 ; N t ; B 104 0 431 740 ;
-C 117 ; WX 608 ; N u ; B 100 -13 642 547 ;
-C 118 ; WX 554 ; N v ; B 108 0 647 547 ;
-C 119 ; WX 831 ; N w ; B 114 0 921 547 ;
-C 120 ; WX 480 ; N x ; B 12 0 569 547 ;
-C 121 ; WX 536 ; N y ; B 97 -192 624 547 ;
-C 122 ; WX 425 ; N z ; B 10 0 498 547 ;
-C 123 ; WX 351 ; N braceleft ; B 115 -189 468 740 ;
-C 124 ; WX 672 ; N bar ; B 280 -100 510 740 ;
-C 125 ; WX 351 ; N braceright ; B -15 -189 338 740 ;
-C 126 ; WX 606 ; N asciitilde ; B 114 179 584 319 ;
-C 161 ; WX 295 ; N exclamdown ; B 74 -192 286 548 ;
-C 162 ; WX 554 ; N cent ; B 115 62 596 707 ;
-C 163 ; WX 554 ; N sterling ; B 29 0 614 753 ;
-C 164 ; WX 166 ; N fraction ; B -113 0 417 740 ;
-C 165 ; WX 554 ; N yen ; B 75 0 687 740 ;
-C 166 ; WX 554 ; N florin ; B -39 -153 669 818 ;
-C 167 ; WX 615 ; N section ; B 118 -141 597 753 ;
-C 168 ; WX 554 ; N currency ; B 24 42 645 580 ;
-C 169 ; WX 198 ; N quotesingle ; B 153 444 277 740 ;
-C 170 ; WX 502 ; N quotedblleft ; B 234 546 507 740 ;
-C 171 ; WX 425 ; N guillemotleft ; B 92 81 469 481 ;
-C 172 ; WX 251 ; N guilsinglleft ; B 92 81 295 481 ;
-C 173 ; WX 251 ; N guilsinglright ; B 60 81 263 481 ;
-C 174 ; WX 487 ; N fi ; B 104 0 559 753 ;
-C 175 ; WX 485 ; N fl ; B 104 0 557 753 ;
-C 177 ; WX 500 ; N endash ; B 81 248 523 315 ;
-C 178 ; WX 553 ; N dagger ; B 146 -133 593 740 ;
-C 179 ; WX 553 ; N daggerdbl ; B 72 -133 593 740 ;
-C 180 ; WX 277 ; N periodcentered ; B 137 190 235 316 ;
-C 182 ; WX 564 ; N paragraph ; B 119 -110 688 740 ;
-C 183 ; WX 606 ; N bullet ; B 217 222 528 532 ;
-C 184 ; WX 354 ; N quotesinglbase ; B 76 -68 274 126 ;
-C 185 ; WX 502 ; N quotedblbase ; B 76 -68 422 126 ;
-C 186 ; WX 484 ; N quotedblright ; B 197 546 542 740 ;
-C 187 ; WX 425 ; N guillemotright ; B 60 81 437 481 ;
-C 188 ; WX 1000 ; N ellipsis ; B 130 0 893 126 ;
-C 189 ; WX 1174 ; N perthousand ; B 128 -13 1182 751 ;
-C 191 ; WX 591 ; N questiondown ; B 64 -205 534 548 ;
-C 193 ; WX 378 ; N grave ; B 204 619 425 786 ;
-C 194 ; WX 375 ; N acute ; B 203 619 444 786 ;
-C 195 ; WX 502 ; N circumflex ; B 192 639 546 764 ;
-C 196 ; WX 439 ; N tilde ; B 179 651 520 754 ;
-C 197 ; WX 485 ; N macron ; B 197 669 547 736 ;
-C 198 ; WX 453 ; N breve ; B 192 651 541 754 ;
-C 199 ; WX 222 ; N dotaccent ; B 192 639 290 765 ;
-C 200 ; WX 369 ; N dieresis ; B 191 639 437 765 ;
-C 202 ; WX 332 ; N ring ; B 191 600 401 807 ;
-C 203 ; WX 324 ; N cedilla ; B 52 -222 231 0 ;
-C 205 ; WX 552 ; N hungarumlaut ; B 239 605 594 800 ;
-C 206 ; WX 302 ; N ogonek ; B 53 -191 202 0 ;
-C 207 ; WX 502 ; N caron ; B 210 639 565 764 ;
-C 208 ; WX 1000 ; N emdash ; B 81 248 1023 315 ;
-C 225 ; WX 992 ; N AE ; B -20 0 1044 740 ;
-C 227 ; WX 369 ; N ordfeminine ; B 102 407 494 753 ;
-C 232 ; WX 517 ; N Lslash ; B 107 0 529 740 ;
-C 233 ; WX 868 ; N Oslash ; B 76 -83 929 819 ;
-C 234 ; WX 1194 ; N OE ; B 107 -13 1279 753 ;
-C 235 ; WX 369 ; N ordmasculine ; B 116 407 466 753 ;
-C 241 ; WX 1157 ; N ae ; B 80 -13 1169 561 ;
-C 245 ; WX 200 ; N dotlessi ; B 65 0 236 547 ;
-C 248 ; WX 300 ; N lslash ; B 95 0 354 740 ;
-C 249 ; WX 653 ; N oslash ; B 51 -64 703 614 ;
-C 250 ; WX 1137 ; N oe ; B 80 -13 1160 561 ;
-C 251 ; WX 554 ; N germandbls ; B 61 -13 578 753 ;
-C -1 ; WX 650 ; N ecircumflex ; B 84 -13 664 764 ;
-C -1 ; WX 650 ; N edieresis ; B 84 -13 664 765 ;
-C -1 ; WX 683 ; N aacute ; B 88 -13 722 786 ;
-C -1 ; WX 747 ; N registered ; B 53 -12 830 752 ;
-C -1 ; WX 200 ; N icircumflex ; B 41 0 395 764 ;
-C -1 ; WX 608 ; N udieresis ; B 100 -13 642 765 ;
-C -1 ; WX 655 ; N ograve ; B 88 -13 669 786 ;
-C -1 ; WX 608 ; N uacute ; B 100 -13 642 786 ;
-C -1 ; WX 608 ; N ucircumflex ; B 100 -13 642 764 ;
-C -1 ; WX 740 ; N Aacute ; B 12 0 729 949 ;
-C -1 ; WX 200 ; N igrave ; B 65 0 296 786 ;
-C -1 ; WX 226 ; N Icircumflex ; B 76 0 439 927 ;
-C -1 ; WX 647 ; N ccedilla ; B 87 -222 678 561 ;
-C -1 ; WX 683 ; N adieresis ; B 88 -13 722 765 ;
-C -1 ; WX 536 ; N Ecircumflex ; B 70 0 612 927 ;
-C -1 ; WX 388 ; N scaron ; B 49 -13 508 764 ;
-C -1 ; WX 682 ; N thorn ; B 28 -192 699 740 ;
-C -1 ; WX 1000 ; N trademark ; B 137 296 953 740 ;
-C -1 ; WX 650 ; N egrave ; B 84 -13 664 786 ;
-C -1 ; WX 332 ; N threesuperior ; B 98 289 408 747 ;
-C -1 ; WX 425 ; N zcaron ; B 10 0 527 764 ;
-C -1 ; WX 683 ; N atilde ; B 88 -13 722 754 ;
-C -1 ; WX 683 ; N aring ; B 88 -13 722 807 ;
-C -1 ; WX 655 ; N ocircumflex ; B 88 -13 669 764 ;
-C -1 ; WX 536 ; N Edieresis ; B 70 0 612 928 ;
-C -1 ; WX 831 ; N threequarters ; B 126 0 825 747 ;
-C -1 ; WX 536 ; N ydieresis ; B 97 -192 624 765 ;
-C -1 ; WX 536 ; N yacute ; B 97 -192 624 786 ;
-C -1 ; WX 200 ; N iacute ; B 65 0 397 786 ;
-C -1 ; WX 740 ; N Acircumflex ; B 12 0 729 927 ;
-C -1 ; WX 655 ; N Uacute ; B 118 -13 716 949 ;
-C -1 ; WX 650 ; N eacute ; B 84 -13 664 786 ;
-C -1 ; WX 869 ; N Ograve ; B 105 -13 901 949 ;
-C -1 ; WX 683 ; N agrave ; B 88 -13 722 786 ;
-C -1 ; WX 655 ; N Udieresis ; B 118 -13 716 928 ;
-C -1 ; WX 683 ; N acircumflex ; B 88 -13 722 764 ;
-C -1 ; WX 226 ; N Igrave ; B 76 0 340 949 ;
-C -1 ; WX 332 ; N twosuperior ; B 74 296 433 747 ;
-C -1 ; WX 655 ; N Ugrave ; B 118 -13 716 949 ;
-C -1 ; WX 831 ; N onequarter ; B 183 0 770 740 ;
-C -1 ; WX 655 ; N Ucircumflex ; B 118 -13 716 927 ;
-C -1 ; WX 498 ; N Scaron ; B 57 -13 593 927 ;
-C -1 ; WX 226 ; N Idieresis ; B 76 0 396 928 ;
-C -1 ; WX 200 ; N idieresis ; B 65 0 353 765 ;
-C -1 ; WX 536 ; N Egrave ; B 70 0 612 949 ;
-C -1 ; WX 869 ; N Oacute ; B 105 -13 901 949 ;
-C -1 ; WX 606 ; N divide ; B 92 -13 608 519 ;
-C -1 ; WX 740 ; N Atilde ; B 12 0 729 917 ;
-C -1 ; WX 740 ; N Aring ; B 12 0 729 955 ;
-C -1 ; WX 869 ; N Odieresis ; B 105 -13 901 928 ;
-C -1 ; WX 740 ; N Adieresis ; B 12 0 729 928 ;
-C -1 ; WX 740 ; N Ntilde ; B 75 0 801 917 ;
-C -1 ; WX 480 ; N Zcaron ; B 12 0 596 927 ;
-C -1 ; WX 592 ; N Thorn ; B 60 0 621 740 ;
-C -1 ; WX 226 ; N Iacute ; B 76 0 440 949 ;
-C -1 ; WX 606 ; N plusminus ; B 47 -24 618 518 ;
-C -1 ; WX 606 ; N multiply ; B 87 24 612 482 ;
-C -1 ; WX 536 ; N Eacute ; B 70 0 612 949 ;
-C -1 ; WX 592 ; N Ydieresis ; B 138 0 729 928 ;
-C -1 ; WX 332 ; N onesuperior ; B 190 296 335 740 ;
-C -1 ; WX 608 ; N ugrave ; B 100 -13 642 786 ;
-C -1 ; WX 606 ; N logicalnot ; B 110 109 627 388 ;
-C -1 ; WX 610 ; N ntilde ; B 65 0 609 754 ;
-C -1 ; WX 869 ; N Otilde ; B 105 -13 901 917 ;
-C -1 ; WX 655 ; N otilde ; B 88 -13 669 754 ;
-C -1 ; WX 813 ; N Ccedilla ; B 105 -222 870 752 ;
-C -1 ; WX 740 ; N Agrave ; B 12 0 729 949 ;
-C -1 ; WX 831 ; N onehalf ; B 164 0 810 740 ;
-C -1 ; WX 790 ; N Eth ; B 104 0 813 740 ;
-C -1 ; WX 400 ; N degree ; B 158 421 451 709 ;
-C -1 ; WX 592 ; N Yacute ; B 138 0 729 949 ;
-C -1 ; WX 869 ; N Ocircumflex ; B 105 -13 901 927 ;
-C -1 ; WX 655 ; N oacute ; B 88 -13 669 786 ;
-C -1 ; WX 608 ; N mu ; B 46 -184 628 547 ;
-C -1 ; WX 606 ; N minus ; B 92 219 608 287 ;
-C -1 ; WX 655 ; N eth ; B 88 -12 675 753 ;
-C -1 ; WX 655 ; N odieresis ; B 88 -13 669 765 ;
-C -1 ; WX 747 ; N copyright ; B 53 -12 830 752 ;
-C -1 ; WX 672 ; N brokenbar ; B 280 -100 510 740 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 216
-
-KPX A y -62
-KPX A w -65
-KPX A v -70
-KPX A u -20
-KPX A quoteright -100
-KPX A quotedblright -100
-KPX A Y -92
-KPX A W -60
-KPX A V -102
-KPX A U -40
-KPX A T -45
-KPX A Q -40
-KPX A O -50
-KPX A G -40
-KPX A C -40
-
-KPX B A -10
-
-KPX C A -40
-
-KPX D period -20
-KPX D comma -20
-KPX D Y -30
-KPX D W -10
-KPX D V -50
-KPX D A -50
-
-KPX F period -160
-KPX F e -20
-KPX F comma -180
-KPX F a -20
-KPX F A -75
-
-KPX G period -20
-KPX G comma -20
-KPX G Y -20
-
-KPX J period -15
-KPX J a -20
-KPX J A -30
-
-KPX K o -15
-KPX K e -20
-KPX K O -20
-
-KPX L y -23
-KPX L quoteright -130
-KPX L quotedblright -130
-KPX L Y -91
-KPX L W -67
-KPX L V -113
-KPX L T -46
-
-KPX O period -30
-KPX O comma -30
-KPX O Y -30
-KPX O X -30
-KPX O W -20
-KPX O V -60
-KPX O T -30
-KPX O A -60
-
-KPX P period -300
-KPX P o -60
-KPX P e -20
-KPX P comma -280
-KPX P a -20
-KPX P A -114
-
-KPX Q comma 20
-
-KPX R Y -10
-KPX R W 10
-KPX R V -10
-KPX R T 6
-
-KPX S comma 20
-
-KPX T y -50
-KPX T w -55
-KPX T u -46
-KPX T semicolon -29
-KPX T r -30
-KPX T period -91
-KPX T o -70
-KPX T i 10
-KPX T hyphen -75
-KPX T e -49
-KPX T comma -82
-KPX T colon -15
-KPX T a -90
-KPX T O -30
-KPX T A -45
-
-KPX U period -20
-KPX U comma -20
-KPX U A -40
-
-KPX V u -40
-KPX V semicolon -33
-KPX V period -165
-KPX V o -101
-KPX V i -5
-KPX V hyphen -75
-KPX V e -101
-KPX V comma -145
-KPX V colon -18
-KPX V a -104
-KPX V O -60
-KPX V G -20
-KPX V A -102
-
-KPX W y -2
-KPX W u -30
-KPX W semicolon -33
-KPX W period -106
-KPX W o -46
-KPX W i 6
-KPX W hyphen -35
-KPX W e -47
-KPX W comma -106
-KPX W colon -15
-KPX W a -50
-KPX W O -20
-KPX W A -58
-
-KPX Y u -52
-KPX Y semicolon -23
-KPX Y period -175
-KPX Y o -89
-KPX Y hyphen -85
-KPX Y e -89
-KPX Y comma -145
-KPX Y colon -10
-KPX Y a -93
-KPX Y O -30
-KPX Y A -92
-
-KPX a p 20
-KPX a b 20
-
-KPX b y -20
-KPX b v -20
-
-KPX c y -20
-KPX c k -15
-
-KPX comma space -110
-KPX comma quoteright -120
-KPX comma quotedblright -120
-
-KPX e y -20
-KPX e w -20
-KPX e v -20
-
-KPX f period -50
-KPX f o -40
-KPX f l -30
-KPX f i -34
-KPX f f -60
-KPX f e -20
-KPX f dotlessi -34
-KPX f comma -50
-KPX f a -40
-
-KPX g a -15
-
-KPX h y -30
-
-KPX k y -5
-KPX k e -15
-
-KPX m y -20
-KPX m u -20
-KPX m a -20
-
-KPX n y -15
-KPX n v -20
-
-KPX o y -20
-KPX o x -15
-KPX o w -20
-KPX o v -30
-
-KPX p y -20
-
-KPX period space -110
-KPX period quoteright -120
-KPX period quotedblright -120
-
-KPX quotedblleft quoteleft -35
-KPX quotedblleft A -100
-
-KPX quotedblright space -110
-
-KPX quoteleft quoteleft -203
-KPX quoteleft A -100
-
-KPX quoteright v -30
-KPX quoteright t 10
-KPX quoteright space -110
-KPX quoteright s -15
-KPX quoteright r -20
-KPX quoteright quoteright -203
-KPX quoteright quotedblright -35
-KPX quoteright d -110
-
-KPX r y 40
-KPX r v 40
-KPX r u 20
-KPX r t 20
-KPX r s 20
-KPX r q -8
-KPX r period -73
-KPX r p 20
-KPX r o -20
-KPX r n 21
-KPX r m 28
-KPX r l 20
-KPX r k 20
-KPX r i 20
-KPX r hyphen -60
-KPX r g -15
-KPX r e -4
-KPX r d -6
-KPX r comma -75
-KPX r c -20
-KPX r a -20
-
-KPX s period 20
-KPX s comma 20
-
-KPX space quoteleft -110
-KPX space quotedblleft -110
-KPX space Y -60
-KPX space W -25
-KPX space V -50
-KPX space T -25
-KPX space A -20
-
-KPX v period -130
-KPX v o -30
-KPX v e -20
-KPX v comma -100
-KPX v a -30
-
-KPX w period -100
-KPX w o -30
-KPX w h 15
-KPX w e -20
-KPX w comma -90
-KPX w a -30
-
-KPX y period -125
-KPX y o -30
-KPX y e -20
-KPX y comma -110
-KPX y a -30
-EndKernPairs
-EndKernData
-StartComposites 56
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 213 163 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 149 163 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 216 163 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 211 163 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 231 148 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 181 163 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 111 163 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 47 163 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 114 163 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 109 163 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute -4 163 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -108 163 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -41 163 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave -86 163 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 181 163 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 277 163 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 214 163 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 280 163 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 276 163 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 245 163 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 28 163 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 190 163 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 107 163 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 173 163 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 149 163 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 159 163 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 142 163 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 19 163 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 154 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 91 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 157 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 153 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 176 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 122 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 138 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 74 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 141 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 136 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -47 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -151 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -84 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -129 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 86 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 140 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 77 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 143 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 108 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron -57 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 137 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 53 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 120 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 95 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 101 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron -38 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pbkd8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pbkd8a.afm
deleted file mode 100644
index 036be6d8cd..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pbkd8a.afm
+++ /dev/null
@@ -1,415 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Tue Jan 21 16:13:29 1992
-Comment UniqueID 37831
-Comment VMusage 31983 38875
-FontName Bookman-Demi
-FullName ITC Bookman Demi
-FamilyName ITC Bookman
-Weight Demi
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -194 -250 1346 934
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.004
-Notice Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved.ITC Bookman is a registered trademark of International Typeface Corporation.
-EncodingScheme AdobeStandardEncoding
-CapHeight 681
-XHeight 502
-Ascender 725
-Descender -212
-StartCharMetrics 228
-C 32 ; WX 340 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 360 ; N exclam ; B 82 -8 282 698 ;
-C 34 ; WX 420 ; N quotedbl ; B 11 379 369 698 ;
-C 35 ; WX 660 ; N numbersign ; B 84 0 576 681 ;
-C 36 ; WX 660 ; N dollar ; B 48 -119 620 805 ;
-C 37 ; WX 940 ; N percent ; B 12 -8 924 698 ;
-C 38 ; WX 800 ; N ampersand ; B 21 -17 772 698 ;
-C 39 ; WX 320 ; N quoteright ; B 82 440 242 698 ;
-C 40 ; WX 320 ; N parenleft ; B 48 -150 289 749 ;
-C 41 ; WX 320 ; N parenright ; B 20 -150 262 749 ;
-C 42 ; WX 460 ; N asterisk ; B 62 317 405 697 ;
-C 43 ; WX 600 ; N plus ; B 51 9 555 514 ;
-C 44 ; WX 340 ; N comma ; B 78 -124 257 162 ;
-C 45 ; WX 360 ; N hyphen ; B 20 210 340 318 ;
-C 46 ; WX 340 ; N period ; B 76 -8 258 172 ;
-C 47 ; WX 600 ; N slash ; B 50 -149 555 725 ;
-C 48 ; WX 660 ; N zero ; B 30 -17 639 698 ;
-C 49 ; WX 660 ; N one ; B 137 0 568 681 ;
-C 50 ; WX 660 ; N two ; B 41 0 628 698 ;
-C 51 ; WX 660 ; N three ; B 37 -17 631 698 ;
-C 52 ; WX 660 ; N four ; B 19 0 649 681 ;
-C 53 ; WX 660 ; N five ; B 44 -17 623 723 ;
-C 54 ; WX 660 ; N six ; B 34 -17 634 698 ;
-C 55 ; WX 660 ; N seven ; B 36 0 632 681 ;
-C 56 ; WX 660 ; N eight ; B 36 -17 633 698 ;
-C 57 ; WX 660 ; N nine ; B 33 -17 636 698 ;
-C 58 ; WX 340 ; N colon ; B 76 -8 258 515 ;
-C 59 ; WX 340 ; N semicolon ; B 75 -124 259 515 ;
-C 60 ; WX 600 ; N less ; B 49 -9 558 542 ;
-C 61 ; WX 600 ; N equal ; B 51 109 555 421 ;
-C 62 ; WX 600 ; N greater ; B 48 -9 557 542 ;
-C 63 ; WX 660 ; N question ; B 61 -8 608 698 ;
-C 64 ; WX 820 ; N at ; B 60 -17 758 698 ;
-C 65 ; WX 720 ; N A ; B -34 0 763 681 ;
-C 66 ; WX 720 ; N B ; B 20 0 693 681 ;
-C 67 ; WX 740 ; N C ; B 35 -17 724 698 ;
-C 68 ; WX 780 ; N D ; B 20 0 748 681 ;
-C 69 ; WX 720 ; N E ; B 20 0 724 681 ;
-C 70 ; WX 680 ; N F ; B 20 0 686 681 ;
-C 71 ; WX 780 ; N G ; B 35 -17 773 698 ;
-C 72 ; WX 820 ; N H ; B 20 0 800 681 ;
-C 73 ; WX 400 ; N I ; B 20 0 379 681 ;
-C 74 ; WX 640 ; N J ; B -12 -17 622 681 ;
-C 75 ; WX 800 ; N K ; B 20 0 796 681 ;
-C 76 ; WX 640 ; N L ; B 20 0 668 681 ;
-C 77 ; WX 940 ; N M ; B 20 0 924 681 ;
-C 78 ; WX 740 ; N N ; B 20 0 724 681 ;
-C 79 ; WX 800 ; N O ; B 35 -17 769 698 ;
-C 80 ; WX 660 ; N P ; B 20 0 658 681 ;
-C 81 ; WX 800 ; N Q ; B 35 -226 775 698 ;
-C 82 ; WX 780 ; N R ; B 20 0 783 681 ;
-C 83 ; WX 660 ; N S ; B 21 -17 639 698 ;
-C 84 ; WX 700 ; N T ; B -4 0 703 681 ;
-C 85 ; WX 740 ; N U ; B 15 -17 724 681 ;
-C 86 ; WX 720 ; N V ; B -20 0 730 681 ;
-C 87 ; WX 940 ; N W ; B -20 0 963 681 ;
-C 88 ; WX 780 ; N X ; B 1 0 770 681 ;
-C 89 ; WX 700 ; N Y ; B -20 0 718 681 ;
-C 90 ; WX 640 ; N Z ; B 6 0 635 681 ;
-C 91 ; WX 300 ; N bracketleft ; B 75 -138 285 725 ;
-C 92 ; WX 600 ; N backslash ; B 50 0 555 725 ;
-C 93 ; WX 300 ; N bracketright ; B 21 -138 231 725 ;
-C 94 ; WX 600 ; N asciicircum ; B 52 281 554 681 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 320 ; N quoteleft ; B 82 440 242 698 ;
-C 97 ; WX 580 ; N a ; B 28 -8 588 515 ;
-C 98 ; WX 600 ; N b ; B -20 -8 568 725 ;
-C 99 ; WX 580 ; N c ; B 31 -8 550 515 ;
-C 100 ; WX 640 ; N d ; B 31 -8 622 725 ;
-C 101 ; WX 580 ; N e ; B 31 -8 548 515 ;
-C 102 ; WX 380 ; N f ; B 22 0 461 741 ; L i fi ; L l fl ;
-C 103 ; WX 580 ; N g ; B 9 -243 583 595 ;
-C 104 ; WX 680 ; N h ; B 22 0 654 725 ;
-C 105 ; WX 360 ; N i ; B 22 0 335 729 ;
-C 106 ; WX 340 ; N j ; B -94 -221 278 729 ;
-C 107 ; WX 660 ; N k ; B 22 0 643 725 ;
-C 108 ; WX 340 ; N l ; B 9 0 322 725 ;
-C 109 ; WX 1000 ; N m ; B 22 0 980 515 ;
-C 110 ; WX 680 ; N n ; B 22 0 652 515 ;
-C 111 ; WX 620 ; N o ; B 31 -8 585 515 ;
-C 112 ; WX 640 ; N p ; B 22 -212 611 515 ;
-C 113 ; WX 620 ; N q ; B 31 -212 633 515 ;
-C 114 ; WX 460 ; N r ; B 22 0 462 502 ;
-C 115 ; WX 520 ; N s ; B 22 -8 492 515 ;
-C 116 ; WX 460 ; N t ; B 22 -8 445 660 ;
-C 117 ; WX 660 ; N u ; B 22 -8 653 502 ;
-C 118 ; WX 600 ; N v ; B -6 0 593 502 ;
-C 119 ; WX 800 ; N w ; B -6 0 810 502 ;
-C 120 ; WX 600 ; N x ; B 8 0 591 502 ;
-C 121 ; WX 620 ; N y ; B 6 -221 613 502 ;
-C 122 ; WX 560 ; N z ; B 22 0 547 502 ;
-C 123 ; WX 320 ; N braceleft ; B 14 -139 301 726 ;
-C 124 ; WX 600 ; N bar ; B 243 -250 362 750 ;
-C 125 ; WX 320 ; N braceright ; B 15 -140 302 725 ;
-C 126 ; WX 600 ; N asciitilde ; B 51 162 555 368 ;
-C 161 ; WX 360 ; N exclamdown ; B 84 -191 284 515 ;
-C 162 ; WX 660 ; N cent ; B 133 17 535 674 ;
-C 163 ; WX 660 ; N sterling ; B 10 -17 659 698 ;
-C 164 ; WX 120 ; N fraction ; B -194 0 312 681 ;
-C 165 ; WX 660 ; N yen ; B -28 0 696 681 ;
-C 166 ; WX 660 ; N florin ; B -46 -209 674 749 ;
-C 167 ; WX 600 ; N section ; B 36 -153 560 698 ;
-C 168 ; WX 660 ; N currency ; B 77 88 584 593 ;
-C 169 ; WX 240 ; N quotesingle ; B 42 379 178 698 ;
-C 170 ; WX 540 ; N quotedblleft ; B 82 439 449 698 ;
-C 171 ; WX 400 ; N guillemotleft ; B 34 101 360 457 ;
-C 172 ; WX 220 ; N guilsinglleft ; B 34 101 188 457 ;
-C 173 ; WX 220 ; N guilsinglright ; B 34 101 188 457 ;
-C 174 ; WX 740 ; N fi ; B 22 0 710 741 ;
-C 175 ; WX 740 ; N fl ; B 22 0 710 741 ;
-C 177 ; WX 500 ; N endash ; B -25 212 525 318 ;
-C 178 ; WX 440 ; N dagger ; B 33 -156 398 698 ;
-C 179 ; WX 380 ; N daggerdbl ; B 8 -156 380 698 ;
-C 180 ; WX 340 ; N periodcentered ; B 76 175 258 355 ;
-C 182 ; WX 800 ; N paragraph ; B 51 0 698 681 ;
-C 183 ; WX 460 ; N bullet ; B 60 170 404 511 ;
-C 184 ; WX 320 ; N quotesinglbase ; B 82 -114 242 144 ;
-C 185 ; WX 540 ; N quotedblbase ; B 82 -114 450 144 ;
-C 186 ; WX 540 ; N quotedblright ; B 82 440 449 698 ;
-C 187 ; WX 400 ; N guillemotright ; B 34 101 360 457 ;
-C 188 ; WX 1000 ; N ellipsis ; B 76 -8 924 172 ;
-C 189 ; WX 1360 ; N perthousand ; B 12 -8 1346 698 ;
-C 191 ; WX 660 ; N questiondown ; B 62 -191 609 515 ;
-C 193 ; WX 400 ; N grave ; B 68 547 327 730 ;
-C 194 ; WX 400 ; N acute ; B 68 547 327 731 ;
-C 195 ; WX 500 ; N circumflex ; B 68 555 430 731 ;
-C 196 ; WX 480 ; N tilde ; B 69 556 421 691 ;
-C 197 ; WX 460 ; N macron ; B 68 577 383 663 ;
-C 198 ; WX 500 ; N breve ; B 68 553 429 722 ;
-C 199 ; WX 320 ; N dotaccent ; B 68 536 259 730 ;
-C 200 ; WX 500 ; N dieresis ; B 68 560 441 698 ;
-C 202 ; WX 340 ; N ring ; B 68 552 275 755 ;
-C 203 ; WX 360 ; N cedilla ; B 68 -213 284 0 ;
-C 205 ; WX 440 ; N hungarumlaut ; B 68 554 365 741 ;
-C 206 ; WX 320 ; N ogonek ; B 68 -163 246 0 ;
-C 207 ; WX 500 ; N caron ; B 68 541 430 717 ;
-C 208 ; WX 1000 ; N emdash ; B -25 212 1025 318 ;
-C 225 ; WX 1140 ; N AE ; B -34 0 1149 681 ;
-C 227 ; WX 400 ; N ordfeminine ; B 27 383 396 698 ;
-C 232 ; WX 640 ; N Lslash ; B 20 0 668 681 ;
-C 233 ; WX 800 ; N Oslash ; B 35 -110 771 781 ;
-C 234 ; WX 1220 ; N OE ; B 35 -17 1219 698 ;
-C 235 ; WX 400 ; N ordmasculine ; B 17 383 383 698 ;
-C 241 ; WX 880 ; N ae ; B 28 -8 852 515 ;
-C 245 ; WX 360 ; N dotlessi ; B 22 0 335 502 ;
-C 248 ; WX 340 ; N lslash ; B 9 0 322 725 ;
-C 249 ; WX 620 ; N oslash ; B 31 -40 586 551 ;
-C 250 ; WX 940 ; N oe ; B 31 -8 908 515 ;
-C 251 ; WX 660 ; N germandbls ; B -61 -91 644 699 ;
-C -1 ; WX 580 ; N ecircumflex ; B 31 -8 548 731 ;
-C -1 ; WX 580 ; N edieresis ; B 31 -8 548 698 ;
-C -1 ; WX 580 ; N aacute ; B 28 -8 588 731 ;
-C -1 ; WX 740 ; N registered ; B 23 -17 723 698 ;
-C -1 ; WX 360 ; N icircumflex ; B -2 0 360 731 ;
-C -1 ; WX 660 ; N udieresis ; B 22 -8 653 698 ;
-C -1 ; WX 620 ; N ograve ; B 31 -8 585 730 ;
-C -1 ; WX 660 ; N uacute ; B 22 -8 653 731 ;
-C -1 ; WX 660 ; N ucircumflex ; B 22 -8 653 731 ;
-C -1 ; WX 720 ; N Aacute ; B -34 0 763 910 ;
-C -1 ; WX 360 ; N igrave ; B 22 0 335 730 ;
-C -1 ; WX 400 ; N Icircumflex ; B 18 0 380 910 ;
-C -1 ; WX 580 ; N ccedilla ; B 31 -213 550 515 ;
-C -1 ; WX 580 ; N adieresis ; B 28 -8 588 698 ;
-C -1 ; WX 720 ; N Ecircumflex ; B 20 0 724 910 ;
-C -1 ; WX 520 ; N scaron ; B 22 -8 492 717 ;
-C -1 ; WX 640 ; N thorn ; B 22 -212 611 725 ;
-C -1 ; WX 980 ; N trademark ; B 42 277 982 681 ;
-C -1 ; WX 580 ; N egrave ; B 31 -8 548 730 ;
-C -1 ; WX 396 ; N threesuperior ; B 5 269 391 698 ;
-C -1 ; WX 560 ; N zcaron ; B 22 0 547 717 ;
-C -1 ; WX 580 ; N atilde ; B 28 -8 588 691 ;
-C -1 ; WX 580 ; N aring ; B 28 -8 588 755 ;
-C -1 ; WX 620 ; N ocircumflex ; B 31 -8 585 731 ;
-C -1 ; WX 720 ; N Edieresis ; B 20 0 724 877 ;
-C -1 ; WX 990 ; N threequarters ; B 15 0 967 692 ;
-C -1 ; WX 620 ; N ydieresis ; B 6 -221 613 698 ;
-C -1 ; WX 620 ; N yacute ; B 6 -221 613 731 ;
-C -1 ; WX 360 ; N iacute ; B 22 0 335 731 ;
-C -1 ; WX 720 ; N Acircumflex ; B -34 0 763 910 ;
-C -1 ; WX 740 ; N Uacute ; B 15 -17 724 910 ;
-C -1 ; WX 580 ; N eacute ; B 31 -8 548 731 ;
-C -1 ; WX 800 ; N Ograve ; B 35 -17 769 909 ;
-C -1 ; WX 580 ; N agrave ; B 28 -8 588 730 ;
-C -1 ; WX 740 ; N Udieresis ; B 15 -17 724 877 ;
-C -1 ; WX 580 ; N acircumflex ; B 28 -8 588 731 ;
-C -1 ; WX 400 ; N Igrave ; B 20 0 379 909 ;
-C -1 ; WX 396 ; N twosuperior ; B 14 279 396 698 ;
-C -1 ; WX 740 ; N Ugrave ; B 15 -17 724 909 ;
-C -1 ; WX 990 ; N onequarter ; B 65 0 967 681 ;
-C -1 ; WX 740 ; N Ucircumflex ; B 15 -17 724 910 ;
-C -1 ; WX 660 ; N Scaron ; B 21 -17 639 896 ;
-C -1 ; WX 400 ; N Idieresis ; B 18 0 391 877 ;
-C -1 ; WX 360 ; N idieresis ; B -2 0 371 698 ;
-C -1 ; WX 720 ; N Egrave ; B 20 0 724 909 ;
-C -1 ; WX 800 ; N Oacute ; B 35 -17 769 910 ;
-C -1 ; WX 600 ; N divide ; B 51 9 555 521 ;
-C -1 ; WX 720 ; N Atilde ; B -34 0 763 870 ;
-C -1 ; WX 720 ; N Aring ; B -34 0 763 934 ;
-C -1 ; WX 800 ; N Odieresis ; B 35 -17 769 877 ;
-C -1 ; WX 720 ; N Adieresis ; B -34 0 763 877 ;
-C -1 ; WX 740 ; N Ntilde ; B 20 0 724 870 ;
-C -1 ; WX 640 ; N Zcaron ; B 6 0 635 896 ;
-C -1 ; WX 660 ; N Thorn ; B 20 0 658 681 ;
-C -1 ; WX 400 ; N Iacute ; B 20 0 379 910 ;
-C -1 ; WX 600 ; N plusminus ; B 51 0 555 514 ;
-C -1 ; WX 600 ; N multiply ; B 48 10 552 514 ;
-C -1 ; WX 720 ; N Eacute ; B 20 0 724 910 ;
-C -1 ; WX 700 ; N Ydieresis ; B -20 0 718 877 ;
-C -1 ; WX 396 ; N onesuperior ; B 65 279 345 687 ;
-C -1 ; WX 660 ; N ugrave ; B 22 -8 653 730 ;
-C -1 ; WX 600 ; N logicalnot ; B 51 129 555 421 ;
-C -1 ; WX 680 ; N ntilde ; B 22 0 652 691 ;
-C -1 ; WX 800 ; N Otilde ; B 35 -17 769 870 ;
-C -1 ; WX 620 ; N otilde ; B 31 -8 585 691 ;
-C -1 ; WX 740 ; N Ccedilla ; B 35 -213 724 698 ;
-C -1 ; WX 720 ; N Agrave ; B -34 0 763 909 ;
-C -1 ; WX 990 ; N onehalf ; B 65 0 980 681 ;
-C -1 ; WX 780 ; N Eth ; B 20 0 748 681 ;
-C -1 ; WX 400 ; N degree ; B 50 398 350 698 ;
-C -1 ; WX 700 ; N Yacute ; B -20 0 718 910 ;
-C -1 ; WX 800 ; N Ocircumflex ; B 35 -17 769 910 ;
-C -1 ; WX 620 ; N oacute ; B 31 -8 585 731 ;
-C -1 ; WX 660 ; N mu ; B 22 -221 653 502 ;
-C -1 ; WX 600 ; N minus ; B 51 207 555 323 ;
-C -1 ; WX 620 ; N eth ; B 31 -8 585 741 ;
-C -1 ; WX 620 ; N odieresis ; B 31 -8 585 698 ;
-C -1 ; WX 740 ; N copyright ; B 23 -17 723 698 ;
-C -1 ; WX 600 ; N brokenbar ; B 243 -175 362 675 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 90
-
-KPX A y -1
-KPX A w -9
-KPX A v -8
-KPX A Y -52
-KPX A W -20
-KPX A V -68
-KPX A T -40
-
-KPX F period -132
-KPX F comma -130
-KPX F A -59
-
-KPX L y 19
-KPX L Y -35
-KPX L W -41
-KPX L V -50
-KPX L T -4
-
-KPX P period -128
-KPX P comma -129
-KPX P A -46
-
-KPX R y -8
-KPX R Y -20
-KPX R W -24
-KPX R V -29
-KPX R T -4
-
-KPX T semicolon 5
-KPX T s -10
-KPX T r 27
-KPX T period -122
-KPX T o -28
-KPX T i 27
-KPX T hyphen -10
-KPX T e -29
-KPX T comma -122
-KPX T colon 7
-KPX T c -29
-KPX T a -24
-KPX T A -42
-
-KPX V y 12
-KPX V u -11
-KPX V semicolon -38
-KPX V r -15
-KPX V period -105
-KPX V o -79
-KPX V i 15
-KPX V hyphen -10
-KPX V e -80
-KPX V comma -103
-KPX V colon -37
-KPX V a -74
-KPX V A -88
-
-KPX W y 12
-KPX W u -11
-KPX W semicolon -38
-KPX W r -15
-KPX W period -105
-KPX W o -78
-KPX W i 15
-KPX W hyphen -10
-KPX W e -79
-KPX W comma -103
-KPX W colon -37
-KPX W a -73
-KPX W A -60
-
-KPX Y v 24
-KPX Y u -13
-KPX Y semicolon -34
-KPX Y q -66
-KPX Y period -105
-KPX Y p -23
-KPX Y o -66
-KPX Y i 2
-KPX Y hyphen -10
-KPX Y e -67
-KPX Y comma -103
-KPX Y colon -32
-KPX Y a -60
-KPX Y A -56
-
-KPX f f 21
-
-KPX r q -9
-KPX r period -102
-KPX r o -9
-KPX r n 20
-KPX r m 20
-KPX r hyphen -10
-KPX r h -23
-KPX r g -9
-KPX r f 20
-KPX r e -10
-KPX r d -10
-KPX r comma -101
-KPX r c -9
-EndKernPairs
-EndKernData
-StartComposites 56
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 160 179 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 110 179 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 110 179 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 160 179 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 190 179 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 120 179 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 160 179 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 110 179 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 110 179 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 160 179 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 179 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -50 179 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -50 179 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 179 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 130 179 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 200 179 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 150 179 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 150 179 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 200 179 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 160 179 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 80 179 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 170 179 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 120 179 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 120 179 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 170 179 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 150 179 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 100 179 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 70 179 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 90 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 40 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 40 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 90 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 100 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 30 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 90 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 40 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 40 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 90 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -20 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -70 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -70 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -20 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 80 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 110 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 60 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 60 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 50 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 10 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 130 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 80 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 80 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 130 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 110 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 60 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 30 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pbkdi8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pbkdi8a.afm
deleted file mode 100644
index c2da47a2a4..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pbkdi8a.afm
+++ /dev/null
@@ -1,417 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Tue Jan 21 16:12:43 1992
-Comment UniqueID 37832
-Comment VMusage 32139 39031
-FontName Bookman-DemiItalic
-FullName ITC Bookman Demi Italic
-FamilyName ITC Bookman
-Weight Demi
-ItalicAngle -10
-IsFixedPitch false
-FontBBox -231 -250 1333 941
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.004
-Notice Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved.ITC Bookman is a registered trademark of International Typeface Corporation.
-EncodingScheme AdobeStandardEncoding
-CapHeight 681
-XHeight 515
-Ascender 732
-Descender -213
-StartCharMetrics 228
-C 32 ; WX 340 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 320 ; N exclam ; B 86 -8 366 698 ;
-C 34 ; WX 380 ; N quotedbl ; B 140 371 507 697 ;
-C 35 ; WX 680 ; N numbersign ; B 157 0 649 681 ;
-C 36 ; WX 680 ; N dollar ; B 45 -164 697 790 ;
-C 37 ; WX 880 ; N percent ; B 106 -17 899 698 ;
-C 38 ; WX 980 ; N ampersand ; B 48 -17 1016 698 ;
-C 39 ; WX 320 ; N quoteright ; B 171 420 349 698 ;
-C 40 ; WX 260 ; N parenleft ; B 31 -134 388 741 ;
-C 41 ; WX 260 ; N parenright ; B -35 -134 322 741 ;
-C 42 ; WX 460 ; N asterisk ; B 126 346 508 698 ;
-C 43 ; WX 600 ; N plus ; B 91 9 595 514 ;
-C 44 ; WX 340 ; N comma ; B 100 -124 298 185 ;
-C 45 ; WX 280 ; N hyphen ; B 59 218 319 313 ;
-C 46 ; WX 340 ; N period ; B 106 -8 296 177 ;
-C 47 ; WX 360 ; N slash ; B 9 -106 502 742 ;
-C 48 ; WX 680 ; N zero ; B 87 -17 703 698 ;
-C 49 ; WX 680 ; N one ; B 123 0 565 681 ;
-C 50 ; WX 680 ; N two ; B 67 0 674 698 ;
-C 51 ; WX 680 ; N three ; B 72 -17 683 698 ;
-C 52 ; WX 680 ; N four ; B 63 0 708 681 ;
-C 53 ; WX 680 ; N five ; B 78 -17 669 681 ;
-C 54 ; WX 680 ; N six ; B 88 -17 704 698 ;
-C 55 ; WX 680 ; N seven ; B 123 0 739 681 ;
-C 56 ; WX 680 ; N eight ; B 68 -17 686 698 ;
-C 57 ; WX 680 ; N nine ; B 71 -17 712 698 ;
-C 58 ; WX 340 ; N colon ; B 106 -8 356 515 ;
-C 59 ; WX 340 ; N semicolon ; B 100 -124 352 515 ;
-C 60 ; WX 620 ; N less ; B 79 -9 588 540 ;
-C 61 ; WX 600 ; N equal ; B 91 109 595 421 ;
-C 62 ; WX 620 ; N greater ; B 89 -9 598 540 ;
-C 63 ; WX 620 ; N question ; B 145 -8 668 698 ;
-C 64 ; WX 780 ; N at ; B 80 -17 790 698 ;
-C 65 ; WX 720 ; N A ; B -27 0 769 681 ;
-C 66 ; WX 720 ; N B ; B 14 0 762 681 ;
-C 67 ; WX 700 ; N C ; B 78 -17 754 698 ;
-C 68 ; WX 760 ; N D ; B 14 0 805 681 ;
-C 69 ; WX 720 ; N E ; B 14 0 777 681 ;
-C 70 ; WX 660 ; N F ; B 14 0 763 681 ;
-C 71 ; WX 760 ; N G ; B 77 -17 828 698 ;
-C 72 ; WX 800 ; N H ; B 14 0 910 681 ;
-C 73 ; WX 380 ; N I ; B 14 0 485 681 ;
-C 74 ; WX 620 ; N J ; B 8 -17 721 681 ;
-C 75 ; WX 780 ; N K ; B 14 0 879 681 ;
-C 76 ; WX 640 ; N L ; B 14 0 725 681 ;
-C 77 ; WX 860 ; N M ; B 14 0 970 681 ;
-C 78 ; WX 740 ; N N ; B 14 0 845 681 ;
-C 79 ; WX 760 ; N O ; B 78 -17 806 698 ;
-C 80 ; WX 640 ; N P ; B -6 0 724 681 ;
-C 81 ; WX 760 ; N Q ; B 37 -213 805 698 ;
-C 82 ; WX 740 ; N R ; B 14 0 765 681 ;
-C 83 ; WX 700 ; N S ; B 59 -17 731 698 ;
-C 84 ; WX 700 ; N T ; B 70 0 802 681 ;
-C 85 ; WX 740 ; N U ; B 112 -17 855 681 ;
-C 86 ; WX 660 ; N V ; B 72 0 819 681 ;
-C 87 ; WX 1000 ; N W ; B 72 0 1090 681 ;
-C 88 ; WX 740 ; N X ; B -7 0 835 681 ;
-C 89 ; WX 660 ; N Y ; B 72 0 817 681 ;
-C 90 ; WX 680 ; N Z ; B 23 0 740 681 ;
-C 91 ; WX 260 ; N bracketleft ; B 9 -118 374 741 ;
-C 92 ; WX 580 ; N backslash ; B 73 0 575 741 ;
-C 93 ; WX 260 ; N bracketright ; B -18 -118 347 741 ;
-C 94 ; WX 620 ; N asciicircum ; B 92 281 594 681 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 320 ; N quoteleft ; B 155 420 333 698 ;
-C 97 ; WX 680 ; N a ; B 84 -8 735 515 ;
-C 98 ; WX 600 ; N b ; B 57 -8 633 732 ;
-C 99 ; WX 560 ; N c ; B 58 -8 597 515 ;
-C 100 ; WX 680 ; N d ; B 60 -8 714 732 ;
-C 101 ; WX 560 ; N e ; B 59 -8 596 515 ;
-C 102 ; WX 420 ; N f ; B -192 -213 641 741 ; L i fi ; L l fl ;
-C 103 ; WX 620 ; N g ; B 21 -213 669 515 ;
-C 104 ; WX 700 ; N h ; B 93 -8 736 732 ;
-C 105 ; WX 380 ; N i ; B 83 -8 420 755 ;
-C 106 ; WX 320 ; N j ; B -160 -213 392 755 ;
-C 107 ; WX 700 ; N k ; B 97 -8 732 732 ;
-C 108 ; WX 380 ; N l ; B 109 -8 410 732 ;
-C 109 ; WX 960 ; N m ; B 83 -8 996 515 ;
-C 110 ; WX 680 ; N n ; B 83 -8 715 515 ;
-C 111 ; WX 600 ; N o ; B 59 -8 627 515 ;
-C 112 ; WX 660 ; N p ; B -24 -213 682 515 ;
-C 113 ; WX 620 ; N q ; B 60 -213 640 515 ;
-C 114 ; WX 500 ; N r ; B 84 0 582 515 ;
-C 115 ; WX 540 ; N s ; B 32 -8 573 515 ;
-C 116 ; WX 440 ; N t ; B 106 -8 488 658 ;
-C 117 ; WX 680 ; N u ; B 83 -8 720 507 ;
-C 118 ; WX 540 ; N v ; B 56 -8 572 515 ;
-C 119 ; WX 860 ; N w ; B 56 -8 891 515 ;
-C 120 ; WX 620 ; N x ; B 10 -8 654 515 ;
-C 121 ; WX 600 ; N y ; B 25 -213 642 507 ;
-C 122 ; WX 560 ; N z ; B 36 -8 586 515 ;
-C 123 ; WX 300 ; N braceleft ; B 49 -123 413 742 ;
-C 124 ; WX 620 ; N bar ; B 303 -250 422 750 ;
-C 125 ; WX 300 ; N braceright ; B -8 -114 356 751 ;
-C 126 ; WX 620 ; N asciitilde ; B 101 162 605 368 ;
-C 161 ; WX 320 ; N exclamdown ; B 64 -191 344 515 ;
-C 162 ; WX 680 ; N cent ; B 161 25 616 718 ;
-C 163 ; WX 680 ; N sterling ; B 0 -17 787 698 ;
-C 164 ; WX 120 ; N fraction ; B -144 0 382 681 ;
-C 165 ; WX 680 ; N yen ; B 92 0 782 681 ;
-C 166 ; WX 680 ; N florin ; B -28 -199 743 741 ;
-C 167 ; WX 620 ; N section ; B 46 -137 638 698 ;
-C 168 ; WX 680 ; N currency ; B 148 85 637 571 ;
-C 169 ; WX 180 ; N quotesingle ; B 126 370 295 696 ;
-C 170 ; WX 520 ; N quotedblleft ; B 156 420 545 698 ;
-C 171 ; WX 380 ; N guillemotleft ; B 62 84 406 503 ;
-C 172 ; WX 220 ; N guilsinglleft ; B 62 84 249 503 ;
-C 173 ; WX 220 ; N guilsinglright ; B 62 84 249 503 ;
-C 174 ; WX 820 ; N fi ; B -191 -213 850 741 ;
-C 175 ; WX 820 ; N fl ; B -191 -213 850 741 ;
-C 177 ; WX 500 ; N endash ; B 40 219 573 311 ;
-C 178 ; WX 420 ; N dagger ; B 89 -137 466 698 ;
-C 179 ; WX 420 ; N daggerdbl ; B 79 -137 486 698 ;
-C 180 ; WX 340 ; N periodcentered ; B 126 173 316 358 ;
-C 182 ; WX 680 ; N paragraph ; B 137 0 715 681 ;
-C 183 ; WX 360 ; N bullet ; B 60 170 404 511 ;
-C 184 ; WX 300 ; N quotesinglbase ; B 106 -112 284 166 ;
-C 185 ; WX 520 ; N quotedblbase ; B 106 -112 495 166 ;
-C 186 ; WX 520 ; N quotedblright ; B 171 420 560 698 ;
-C 187 ; WX 380 ; N guillemotright ; B 62 84 406 503 ;
-C 188 ; WX 1000 ; N ellipsis ; B 86 -8 942 177 ;
-C 189 ; WX 1360 ; N perthousand ; B 106 -17 1333 698 ;
-C 191 ; WX 620 ; N questiondown ; B 83 -189 606 515 ;
-C 193 ; WX 380 ; N grave ; B 193 566 424 771 ;
-C 194 ; WX 340 ; N acute ; B 176 566 407 771 ;
-C 195 ; WX 480 ; N circumflex ; B 183 582 523 749 ;
-C 196 ; WX 480 ; N tilde ; B 178 587 533 709 ;
-C 197 ; WX 480 ; N macron ; B 177 603 531 691 ;
-C 198 ; WX 460 ; N breve ; B 177 577 516 707 ;
-C 199 ; WX 380 ; N dotaccent ; B 180 570 345 734 ;
-C 200 ; WX 520 ; N dieresis ; B 180 570 569 734 ;
-C 202 ; WX 360 ; N ring ; B 185 558 406 775 ;
-C 203 ; WX 360 ; N cedilla ; B 68 -220 289 -8 ;
-C 205 ; WX 560 ; N hungarumlaut ; B 181 560 616 775 ;
-C 206 ; WX 320 ; N ogonek ; B 68 -182 253 0 ;
-C 207 ; WX 480 ; N caron ; B 183 582 523 749 ;
-C 208 ; WX 1000 ; N emdash ; B 40 219 1073 311 ;
-C 225 ; WX 1140 ; N AE ; B -27 0 1207 681 ;
-C 227 ; WX 440 ; N ordfeminine ; B 118 400 495 685 ;
-C 232 ; WX 640 ; N Lslash ; B 14 0 724 681 ;
-C 233 ; WX 760 ; N Oslash ; B 21 -29 847 725 ;
-C 234 ; WX 1180 ; N OE ; B 94 -17 1245 698 ;
-C 235 ; WX 440 ; N ordmasculine ; B 127 400 455 685 ;
-C 241 ; WX 880 ; N ae ; B 39 -8 913 515 ;
-C 245 ; WX 380 ; N dotlessi ; B 83 -8 420 507 ;
-C 248 ; WX 380 ; N lslash ; B 63 -8 412 732 ;
-C 249 ; WX 600 ; N oslash ; B 17 -54 661 571 ;
-C 250 ; WX 920 ; N oe ; B 48 -8 961 515 ;
-C 251 ; WX 660 ; N germandbls ; B -231 -213 702 741 ;
-C -1 ; WX 560 ; N ecircumflex ; B 59 -8 596 749 ;
-C -1 ; WX 560 ; N edieresis ; B 59 -8 596 734 ;
-C -1 ; WX 680 ; N aacute ; B 84 -8 735 771 ;
-C -1 ; WX 780 ; N registered ; B 83 -17 783 698 ;
-C -1 ; WX 380 ; N icircumflex ; B 83 -8 433 749 ;
-C -1 ; WX 680 ; N udieresis ; B 83 -8 720 734 ;
-C -1 ; WX 600 ; N ograve ; B 59 -8 627 771 ;
-C -1 ; WX 680 ; N uacute ; B 83 -8 720 771 ;
-C -1 ; WX 680 ; N ucircumflex ; B 83 -8 720 749 ;
-C -1 ; WX 720 ; N Aacute ; B -27 0 769 937 ;
-C -1 ; WX 380 ; N igrave ; B 83 -8 424 771 ;
-C -1 ; WX 380 ; N Icircumflex ; B 14 0 493 915 ;
-C -1 ; WX 560 ; N ccedilla ; B 58 -220 597 515 ;
-C -1 ; WX 680 ; N adieresis ; B 84 -8 735 734 ;
-C -1 ; WX 720 ; N Ecircumflex ; B 14 0 777 915 ;
-C -1 ; WX 540 ; N scaron ; B 32 -8 573 749 ;
-C -1 ; WX 660 ; N thorn ; B -24 -213 682 732 ;
-C -1 ; WX 940 ; N trademark ; B 42 277 982 681 ;
-C -1 ; WX 560 ; N egrave ; B 59 -8 596 771 ;
-C -1 ; WX 408 ; N threesuperior ; B 86 269 483 698 ;
-C -1 ; WX 560 ; N zcaron ; B 36 -8 586 749 ;
-C -1 ; WX 680 ; N atilde ; B 84 -8 735 709 ;
-C -1 ; WX 680 ; N aring ; B 84 -8 735 775 ;
-C -1 ; WX 600 ; N ocircumflex ; B 59 -8 627 749 ;
-C -1 ; WX 720 ; N Edieresis ; B 14 0 777 900 ;
-C -1 ; WX 1020 ; N threequarters ; B 86 0 1054 691 ;
-C -1 ; WX 600 ; N ydieresis ; B 25 -213 642 734 ;
-C -1 ; WX 600 ; N yacute ; B 25 -213 642 771 ;
-C -1 ; WX 380 ; N iacute ; B 83 -8 420 771 ;
-C -1 ; WX 720 ; N Acircumflex ; B -27 0 769 915 ;
-C -1 ; WX 740 ; N Uacute ; B 112 -17 855 937 ;
-C -1 ; WX 560 ; N eacute ; B 59 -8 596 771 ;
-C -1 ; WX 760 ; N Ograve ; B 78 -17 806 937 ;
-C -1 ; WX 680 ; N agrave ; B 84 -8 735 771 ;
-C -1 ; WX 740 ; N Udieresis ; B 112 -17 855 900 ;
-C -1 ; WX 680 ; N acircumflex ; B 84 -8 735 749 ;
-C -1 ; WX 380 ; N Igrave ; B 14 0 485 937 ;
-C -1 ; WX 408 ; N twosuperior ; B 91 279 485 698 ;
-C -1 ; WX 740 ; N Ugrave ; B 112 -17 855 937 ;
-C -1 ; WX 1020 ; N onequarter ; B 118 0 1054 681 ;
-C -1 ; WX 740 ; N Ucircumflex ; B 112 -17 855 915 ;
-C -1 ; WX 700 ; N Scaron ; B 59 -17 731 915 ;
-C -1 ; WX 380 ; N Idieresis ; B 14 0 499 900 ;
-C -1 ; WX 380 ; N idieresis ; B 83 -8 479 734 ;
-C -1 ; WX 720 ; N Egrave ; B 14 0 777 937 ;
-C -1 ; WX 760 ; N Oacute ; B 78 -17 806 937 ;
-C -1 ; WX 600 ; N divide ; B 91 9 595 521 ;
-C -1 ; WX 720 ; N Atilde ; B -27 0 769 875 ;
-C -1 ; WX 720 ; N Aring ; B -27 0 769 941 ;
-C -1 ; WX 760 ; N Odieresis ; B 78 -17 806 900 ;
-C -1 ; WX 720 ; N Adieresis ; B -27 0 769 900 ;
-C -1 ; WX 740 ; N Ntilde ; B 14 0 845 875 ;
-C -1 ; WX 680 ; N Zcaron ; B 23 0 740 915 ;
-C -1 ; WX 640 ; N Thorn ; B -6 0 701 681 ;
-C -1 ; WX 380 ; N Iacute ; B 14 0 485 937 ;
-C -1 ; WX 600 ; N plusminus ; B 91 0 595 514 ;
-C -1 ; WX 600 ; N multiply ; B 91 10 595 514 ;
-C -1 ; WX 720 ; N Eacute ; B 14 0 777 937 ;
-C -1 ; WX 660 ; N Ydieresis ; B 72 0 817 900 ;
-C -1 ; WX 408 ; N onesuperior ; B 118 279 406 688 ;
-C -1 ; WX 680 ; N ugrave ; B 83 -8 720 771 ;
-C -1 ; WX 620 ; N logicalnot ; B 81 129 585 421 ;
-C -1 ; WX 680 ; N ntilde ; B 83 -8 715 709 ;
-C -1 ; WX 760 ; N Otilde ; B 78 -17 806 875 ;
-C -1 ; WX 600 ; N otilde ; B 59 -8 627 709 ;
-C -1 ; WX 700 ; N Ccedilla ; B 78 -220 754 698 ;
-C -1 ; WX 720 ; N Agrave ; B -27 0 769 937 ;
-C -1 ; WX 1020 ; N onehalf ; B 118 0 1036 681 ;
-C -1 ; WX 760 ; N Eth ; B 14 0 805 681 ;
-C -1 ; WX 400 ; N degree ; B 130 398 430 698 ;
-C -1 ; WX 660 ; N Yacute ; B 72 0 817 937 ;
-C -1 ; WX 760 ; N Ocircumflex ; B 78 -17 806 915 ;
-C -1 ; WX 600 ; N oacute ; B 59 -8 627 771 ;
-C -1 ; WX 680 ; N mu ; B 54 -213 720 507 ;
-C -1 ; WX 600 ; N minus ; B 91 207 595 323 ;
-C -1 ; WX 600 ; N eth ; B 59 -8 662 741 ;
-C -1 ; WX 600 ; N odieresis ; B 59 -8 627 734 ;
-C -1 ; WX 780 ; N copyright ; B 83 -17 783 698 ;
-C -1 ; WX 620 ; N brokenbar ; B 303 -175 422 675 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 92
-
-KPX A y 20
-KPX A w 20
-KPX A v 20
-KPX A Y -25
-KPX A W -35
-KPX A V -40
-KPX A T -17
-
-KPX F period -105
-KPX F comma -98
-KPX F A -35
-
-KPX L y 62
-KPX L Y -5
-KPX L W -15
-KPX L V -19
-KPX L T -26
-
-KPX P period -105
-KPX P comma -98
-KPX P A -31
-
-KPX R y 27
-KPX R Y 4
-KPX R W -4
-KPX R V -8
-KPX R T -3
-
-KPX T y 56
-KPX T w 69
-KPX T u 42
-KPX T semicolon 31
-KPX T s -1
-KPX T r 41
-KPX T period -107
-KPX T o -5
-KPX T i 42
-KPX T hyphen -20
-KPX T e -10
-KPX T comma -100
-KPX T colon 26
-KPX T c -8
-KPX T a -8
-KPX T A -42
-
-KPX V y 17
-KPX V u -1
-KPX V semicolon -22
-KPX V r 2
-KPX V period -115
-KPX V o -50
-KPX V i 32
-KPX V hyphen -20
-KPX V e -50
-KPX V comma -137
-KPX V colon -28
-KPX V a -50
-KPX V A -50
-
-KPX W y -51
-KPX W u -69
-KPX W semicolon -81
-KPX W r -66
-KPX W period -183
-KPX W o -100
-KPX W i -36
-KPX W hyphen -22
-KPX W e -100
-KPX W comma -201
-KPX W colon -86
-KPX W a -100
-KPX W A -77
-
-KPX Y v 26
-KPX Y u -1
-KPX Y semicolon -4
-KPX Y q -43
-KPX Y period -113
-KPX Y o -41
-KPX Y i 20
-KPX Y hyphen -20
-KPX Y e -46
-KPX Y comma -106
-KPX Y colon -9
-KPX Y a -45
-KPX Y A -30
-
-KPX f f 10
-
-KPX r q -3
-KPX r period -120
-KPX r o -1
-KPX r n 39
-KPX r m 39
-KPX r hyphen -20
-KPX r h -35
-KPX r g -23
-KPX r f 42
-KPX r e -6
-KPX r d -3
-KPX r comma -113
-KPX r c -5
-EndKernPairs
-EndKernData
-StartComposites 56
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 190 166 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 120 166 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 100 166 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 170 166 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 200 166 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 120 166 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 190 166 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 120 166 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 100 166 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 170 166 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 20 166 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -30 166 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -70 166 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 166 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 130 166 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 210 166 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 140 166 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 140 166 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 190 166 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 140 166 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 110 166 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 200 166 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 130 166 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 130 166 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 180 166 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 160 166 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 70 166 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 100 166 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 170 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 100 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 150 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 160 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 100 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 110 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 60 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 20 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 90 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -90 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -90 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 60 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 130 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 60 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 40 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 60 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 30 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 170 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 100 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 80 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 150 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 130 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 40 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 40 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pbkl8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pbkl8a.afm
deleted file mode 100644
index 8b79ea7106..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pbkl8a.afm
+++ /dev/null
@@ -1,407 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Tue Jan 21 16:15:53 1992
-Comment UniqueID 37833
-Comment VMusage 32321 39213
-FontName Bookman-Light
-FullName ITC Bookman Light
-FamilyName ITC Bookman
-Weight Light
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -188 -251 1266 908
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.004
-Notice Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved.ITC Bookman is a registered trademark of International Typeface Corporation.
-EncodingScheme AdobeStandardEncoding
-CapHeight 681
-XHeight 484
-Ascender 717
-Descender -228
-StartCharMetrics 228
-C 32 ; WX 320 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 300 ; N exclam ; B 75 -8 219 698 ;
-C 34 ; WX 380 ; N quotedbl ; B 56 458 323 698 ;
-C 35 ; WX 620 ; N numbersign ; B 65 0 556 681 ;
-C 36 ; WX 620 ; N dollar ; B 34 -109 593 791 ;
-C 37 ; WX 900 ; N percent ; B 22 -8 873 698 ;
-C 38 ; WX 800 ; N ampersand ; B 45 -17 787 698 ;
-C 39 ; WX 220 ; N quoteright ; B 46 480 178 698 ;
-C 40 ; WX 300 ; N parenleft ; B 76 -145 278 727 ;
-C 41 ; WX 300 ; N parenright ; B 17 -146 219 727 ;
-C 42 ; WX 440 ; N asterisk ; B 54 325 391 698 ;
-C 43 ; WX 600 ; N plus ; B 51 8 555 513 ;
-C 44 ; WX 320 ; N comma ; B 90 -114 223 114 ;
-C 45 ; WX 400 ; N hyphen ; B 50 232 350 292 ;
-C 46 ; WX 320 ; N period ; B 92 -8 220 123 ;
-C 47 ; WX 600 ; N slash ; B 74 -149 532 717 ;
-C 48 ; WX 620 ; N zero ; B 40 -17 586 698 ;
-C 49 ; WX 620 ; N one ; B 160 0 501 681 ;
-C 50 ; WX 620 ; N two ; B 42 0 576 698 ;
-C 51 ; WX 620 ; N three ; B 40 -17 576 698 ;
-C 52 ; WX 620 ; N four ; B 25 0 600 681 ;
-C 53 ; WX 620 ; N five ; B 60 -17 584 717 ;
-C 54 ; WX 620 ; N six ; B 45 -17 590 698 ;
-C 55 ; WX 620 ; N seven ; B 60 0 586 681 ;
-C 56 ; WX 620 ; N eight ; B 44 -17 583 698 ;
-C 57 ; WX 620 ; N nine ; B 37 -17 576 698 ;
-C 58 ; WX 320 ; N colon ; B 92 -8 220 494 ;
-C 59 ; WX 320 ; N semicolon ; B 90 -114 223 494 ;
-C 60 ; WX 600 ; N less ; B 49 -2 558 526 ;
-C 61 ; WX 600 ; N equal ; B 51 126 555 398 ;
-C 62 ; WX 600 ; N greater ; B 48 -2 557 526 ;
-C 63 ; WX 540 ; N question ; B 27 -8 514 698 ;
-C 64 ; WX 820 ; N at ; B 55 -17 755 698 ;
-C 65 ; WX 680 ; N A ; B -37 0 714 681 ;
-C 66 ; WX 740 ; N B ; B 31 0 702 681 ;
-C 67 ; WX 740 ; N C ; B 44 -17 702 698 ;
-C 68 ; WX 800 ; N D ; B 31 0 752 681 ;
-C 69 ; WX 720 ; N E ; B 31 0 705 681 ;
-C 70 ; WX 640 ; N F ; B 31 0 654 681 ;
-C 71 ; WX 800 ; N G ; B 44 -17 778 698 ;
-C 72 ; WX 800 ; N H ; B 31 0 769 681 ;
-C 73 ; WX 340 ; N I ; B 31 0 301 681 ;
-C 74 ; WX 600 ; N J ; B -23 -17 567 681 ;
-C 75 ; WX 720 ; N K ; B 31 0 750 681 ;
-C 76 ; WX 600 ; N L ; B 31 0 629 681 ;
-C 77 ; WX 920 ; N M ; B 26 0 894 681 ;
-C 78 ; WX 740 ; N N ; B 26 0 722 681 ;
-C 79 ; WX 800 ; N O ; B 44 -17 758 698 ;
-C 80 ; WX 620 ; N P ; B 31 0 613 681 ;
-C 81 ; WX 820 ; N Q ; B 44 -189 769 698 ;
-C 82 ; WX 720 ; N R ; B 31 0 757 681 ;
-C 83 ; WX 660 ; N S ; B 28 -17 634 698 ;
-C 84 ; WX 620 ; N T ; B -37 0 656 681 ;
-C 85 ; WX 780 ; N U ; B 25 -17 754 681 ;
-C 86 ; WX 700 ; N V ; B -30 0 725 681 ;
-C 87 ; WX 960 ; N W ; B -30 0 984 681 ;
-C 88 ; WX 720 ; N X ; B -30 0 755 681 ;
-C 89 ; WX 640 ; N Y ; B -30 0 666 681 ;
-C 90 ; WX 640 ; N Z ; B 10 0 656 681 ;
-C 91 ; WX 300 ; N bracketleft ; B 92 -136 258 717 ;
-C 92 ; WX 600 ; N backslash ; B 74 0 532 717 ;
-C 93 ; WX 300 ; N bracketright ; B 41 -136 207 717 ;
-C 94 ; WX 600 ; N asciicircum ; B 52 276 554 681 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 220 ; N quoteleft ; B 46 479 178 698 ;
-C 97 ; WX 580 ; N a ; B 35 -8 587 494 ;
-C 98 ; WX 620 ; N b ; B -2 -8 582 717 ;
-C 99 ; WX 520 ; N c ; B 37 -8 498 494 ;
-C 100 ; WX 620 ; N d ; B 37 -8 591 717 ;
-C 101 ; WX 520 ; N e ; B 37 -8 491 494 ;
-C 102 ; WX 320 ; N f ; B 20 0 414 734 ; L i fi ; L l fl ;
-C 103 ; WX 540 ; N g ; B 17 -243 542 567 ;
-C 104 ; WX 660 ; N h ; B 20 0 643 717 ;
-C 105 ; WX 300 ; N i ; B 20 0 288 654 ;
-C 106 ; WX 300 ; N j ; B -109 -251 214 654 ;
-C 107 ; WX 620 ; N k ; B 20 0 628 717 ;
-C 108 ; WX 300 ; N l ; B 20 0 286 717 ;
-C 109 ; WX 940 ; N m ; B 17 0 928 494 ;
-C 110 ; WX 660 ; N n ; B 20 0 649 494 ;
-C 111 ; WX 560 ; N o ; B 37 -8 526 494 ;
-C 112 ; WX 620 ; N p ; B 20 -228 583 494 ;
-C 113 ; WX 580 ; N q ; B 37 -228 589 494 ;
-C 114 ; WX 440 ; N r ; B 20 0 447 494 ;
-C 115 ; WX 520 ; N s ; B 40 -8 487 494 ;
-C 116 ; WX 380 ; N t ; B 20 -8 388 667 ;
-C 117 ; WX 680 ; N u ; B 20 -8 653 484 ;
-C 118 ; WX 520 ; N v ; B -23 0 534 484 ;
-C 119 ; WX 780 ; N w ; B -19 0 804 484 ;
-C 120 ; WX 560 ; N x ; B -16 0 576 484 ;
-C 121 ; WX 540 ; N y ; B -23 -236 549 484 ;
-C 122 ; WX 480 ; N z ; B 7 0 476 484 ;
-C 123 ; WX 280 ; N braceleft ; B 21 -136 260 717 ;
-C 124 ; WX 600 ; N bar ; B 264 -250 342 750 ;
-C 125 ; WX 280 ; N braceright ; B 21 -136 260 717 ;
-C 126 ; WX 600 ; N asciitilde ; B 52 173 556 352 ;
-C 161 ; WX 300 ; N exclamdown ; B 75 -214 219 494 ;
-C 162 ; WX 620 ; N cent ; B 116 20 511 651 ;
-C 163 ; WX 620 ; N sterling ; B 8 -17 631 698 ;
-C 164 ; WX 140 ; N fraction ; B -188 0 335 681 ;
-C 165 ; WX 620 ; N yen ; B -22 0 647 681 ;
-C 166 ; WX 620 ; N florin ; B -29 -155 633 749 ;
-C 167 ; WX 520 ; N section ; B 33 -178 486 698 ;
-C 168 ; WX 620 ; N currency ; B 58 89 563 591 ;
-C 169 ; WX 220 ; N quotesingle ; B 67 458 153 698 ;
-C 170 ; WX 400 ; N quotedblleft ; B 46 479 348 698 ;
-C 171 ; WX 360 ; N guillemotleft ; B 51 89 312 437 ;
-C 172 ; WX 240 ; N guilsinglleft ; B 51 89 189 437 ;
-C 173 ; WX 240 ; N guilsinglright ; B 51 89 189 437 ;
-C 174 ; WX 620 ; N fi ; B 20 0 608 734 ;
-C 175 ; WX 620 ; N fl ; B 20 0 606 734 ;
-C 177 ; WX 500 ; N endash ; B -15 232 515 292 ;
-C 178 ; WX 540 ; N dagger ; B 79 -156 455 698 ;
-C 179 ; WX 540 ; N daggerdbl ; B 79 -156 455 698 ;
-C 180 ; WX 320 ; N periodcentered ; B 92 196 220 327 ;
-C 182 ; WX 600 ; N paragraph ; B 14 0 577 681 ;
-C 183 ; WX 460 ; N bullet ; B 60 170 404 511 ;
-C 184 ; WX 220 ; N quotesinglbase ; B 46 -108 178 110 ;
-C 185 ; WX 400 ; N quotedblbase ; B 46 -108 348 110 ;
-C 186 ; WX 400 ; N quotedblright ; B 46 480 348 698 ;
-C 187 ; WX 360 ; N guillemotright ; B 51 89 312 437 ;
-C 188 ; WX 1000 ; N ellipsis ; B 101 -8 898 123 ;
-C 189 ; WX 1280 ; N perthousand ; B 22 -8 1266 698 ;
-C 191 ; WX 540 ; N questiondown ; B 23 -217 510 494 ;
-C 193 ; WX 340 ; N grave ; B 68 571 274 689 ;
-C 194 ; WX 340 ; N acute ; B 68 571 274 689 ;
-C 195 ; WX 420 ; N circumflex ; B 68 567 352 685 ;
-C 196 ; WX 440 ; N tilde ; B 68 572 375 661 ;
-C 197 ; WX 440 ; N macron ; B 68 587 364 635 ;
-C 198 ; WX 460 ; N breve ; B 68 568 396 687 ;
-C 199 ; WX 260 ; N dotaccent ; B 68 552 186 672 ;
-C 200 ; WX 420 ; N dieresis ; B 68 552 349 674 ;
-C 202 ; WX 320 ; N ring ; B 68 546 252 731 ;
-C 203 ; WX 320 ; N cedilla ; B 68 -200 257 0 ;
-C 205 ; WX 380 ; N hungarumlaut ; B 68 538 311 698 ;
-C 206 ; WX 320 ; N ogonek ; B 68 -145 245 0 ;
-C 207 ; WX 420 ; N caron ; B 68 554 352 672 ;
-C 208 ; WX 1000 ; N emdash ; B -15 232 1015 292 ;
-C 225 ; WX 1260 ; N AE ; B -36 0 1250 681 ;
-C 227 ; WX 420 ; N ordfeminine ; B 49 395 393 698 ;
-C 232 ; WX 600 ; N Lslash ; B 31 0 629 681 ;
-C 233 ; WX 800 ; N Oslash ; B 44 -53 758 733 ;
-C 234 ; WX 1240 ; N OE ; B 44 -17 1214 698 ;
-C 235 ; WX 420 ; N ordmasculine ; B 56 394 361 698 ;
-C 241 ; WX 860 ; N ae ; B 35 -8 832 494 ;
-C 245 ; WX 300 ; N dotlessi ; B 20 0 288 484 ;
-C 248 ; WX 320 ; N lslash ; B 20 0 291 717 ;
-C 249 ; WX 560 ; N oslash ; B 37 -40 526 534 ;
-C 250 ; WX 900 ; N oe ; B 37 -8 876 494 ;
-C 251 ; WX 660 ; N germandbls ; B -109 -110 614 698 ;
-C -1 ; WX 520 ; N ecircumflex ; B 37 -8 491 685 ;
-C -1 ; WX 520 ; N edieresis ; B 37 -8 491 674 ;
-C -1 ; WX 580 ; N aacute ; B 35 -8 587 689 ;
-C -1 ; WX 740 ; N registered ; B 23 -17 723 698 ;
-C -1 ; WX 300 ; N icircumflex ; B 8 0 292 685 ;
-C -1 ; WX 680 ; N udieresis ; B 20 -8 653 674 ;
-C -1 ; WX 560 ; N ograve ; B 37 -8 526 689 ;
-C -1 ; WX 680 ; N uacute ; B 20 -8 653 689 ;
-C -1 ; WX 680 ; N ucircumflex ; B 20 -8 653 685 ;
-C -1 ; WX 680 ; N Aacute ; B -37 0 714 866 ;
-C -1 ; WX 300 ; N igrave ; B 20 0 288 689 ;
-C -1 ; WX 340 ; N Icircumflex ; B 28 0 312 862 ;
-C -1 ; WX 520 ; N ccedilla ; B 37 -200 498 494 ;
-C -1 ; WX 580 ; N adieresis ; B 35 -8 587 674 ;
-C -1 ; WX 720 ; N Ecircumflex ; B 31 0 705 862 ;
-C -1 ; WX 520 ; N scaron ; B 40 -8 487 672 ;
-C -1 ; WX 620 ; N thorn ; B 20 -228 583 717 ;
-C -1 ; WX 980 ; N trademark ; B 34 277 930 681 ;
-C -1 ; WX 520 ; N egrave ; B 37 -8 491 689 ;
-C -1 ; WX 372 ; N threesuperior ; B 12 269 360 698 ;
-C -1 ; WX 480 ; N zcaron ; B 7 0 476 672 ;
-C -1 ; WX 580 ; N atilde ; B 35 -8 587 661 ;
-C -1 ; WX 580 ; N aring ; B 35 -8 587 731 ;
-C -1 ; WX 560 ; N ocircumflex ; B 37 -8 526 685 ;
-C -1 ; WX 720 ; N Edieresis ; B 31 0 705 851 ;
-C -1 ; WX 930 ; N threequarters ; B 52 0 889 691 ;
-C -1 ; WX 540 ; N ydieresis ; B -23 -236 549 674 ;
-C -1 ; WX 540 ; N yacute ; B -23 -236 549 689 ;
-C -1 ; WX 300 ; N iacute ; B 20 0 288 689 ;
-C -1 ; WX 680 ; N Acircumflex ; B -37 0 714 862 ;
-C -1 ; WX 780 ; N Uacute ; B 25 -17 754 866 ;
-C -1 ; WX 520 ; N eacute ; B 37 -8 491 689 ;
-C -1 ; WX 800 ; N Ograve ; B 44 -17 758 866 ;
-C -1 ; WX 580 ; N agrave ; B 35 -8 587 689 ;
-C -1 ; WX 780 ; N Udieresis ; B 25 -17 754 851 ;
-C -1 ; WX 580 ; N acircumflex ; B 35 -8 587 685 ;
-C -1 ; WX 340 ; N Igrave ; B 31 0 301 866 ;
-C -1 ; WX 372 ; N twosuperior ; B 20 279 367 698 ;
-C -1 ; WX 780 ; N Ugrave ; B 25 -17 754 866 ;
-C -1 ; WX 930 ; N onequarter ; B 80 0 869 681 ;
-C -1 ; WX 780 ; N Ucircumflex ; B 25 -17 754 862 ;
-C -1 ; WX 660 ; N Scaron ; B 28 -17 634 849 ;
-C -1 ; WX 340 ; N Idieresis ; B 28 0 309 851 ;
-C -1 ; WX 300 ; N idieresis ; B 8 0 289 674 ;
-C -1 ; WX 720 ; N Egrave ; B 31 0 705 866 ;
-C -1 ; WX 800 ; N Oacute ; B 44 -17 758 866 ;
-C -1 ; WX 600 ; N divide ; B 51 10 555 514 ;
-C -1 ; WX 680 ; N Atilde ; B -37 0 714 838 ;
-C -1 ; WX 680 ; N Aring ; B -37 0 714 908 ;
-C -1 ; WX 800 ; N Odieresis ; B 44 -17 758 851 ;
-C -1 ; WX 680 ; N Adieresis ; B -37 0 714 851 ;
-C -1 ; WX 740 ; N Ntilde ; B 26 0 722 838 ;
-C -1 ; WX 640 ; N Zcaron ; B 10 0 656 849 ;
-C -1 ; WX 620 ; N Thorn ; B 31 0 613 681 ;
-C -1 ; WX 340 ; N Iacute ; B 31 0 301 866 ;
-C -1 ; WX 600 ; N plusminus ; B 51 0 555 513 ;
-C -1 ; WX 600 ; N multiply ; B 51 9 555 513 ;
-C -1 ; WX 720 ; N Eacute ; B 31 0 705 866 ;
-C -1 ; WX 640 ; N Ydieresis ; B -30 0 666 851 ;
-C -1 ; WX 372 ; N onesuperior ; B 80 279 302 688 ;
-C -1 ; WX 680 ; N ugrave ; B 20 -8 653 689 ;
-C -1 ; WX 600 ; N logicalnot ; B 51 128 555 398 ;
-C -1 ; WX 660 ; N ntilde ; B 20 0 649 661 ;
-C -1 ; WX 800 ; N Otilde ; B 44 -17 758 838 ;
-C -1 ; WX 560 ; N otilde ; B 37 -8 526 661 ;
-C -1 ; WX 740 ; N Ccedilla ; B 44 -200 702 698 ;
-C -1 ; WX 680 ; N Agrave ; B -37 0 714 866 ;
-C -1 ; WX 930 ; N onehalf ; B 80 0 885 681 ;
-C -1 ; WX 800 ; N Eth ; B 31 0 752 681 ;
-C -1 ; WX 400 ; N degree ; B 50 398 350 698 ;
-C -1 ; WX 640 ; N Yacute ; B -30 0 666 866 ;
-C -1 ; WX 800 ; N Ocircumflex ; B 44 -17 758 862 ;
-C -1 ; WX 560 ; N oacute ; B 37 -8 526 689 ;
-C -1 ; WX 680 ; N mu ; B 20 -251 653 484 ;
-C -1 ; WX 600 ; N minus ; B 51 224 555 300 ;
-C -1 ; WX 560 ; N eth ; B 37 -8 526 734 ;
-C -1 ; WX 560 ; N odieresis ; B 37 -8 526 674 ;
-C -1 ; WX 740 ; N copyright ; B 24 -17 724 698 ;
-C -1 ; WX 600 ; N brokenbar ; B 264 -175 342 675 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 82
-
-KPX A y 32
-KPX A w 4
-KPX A v 7
-KPX A Y -35
-KPX A W -40
-KPX A V -56
-KPX A T 1
-
-KPX F period -46
-KPX F comma -41
-KPX F A -21
-
-KPX L y 79
-KPX L Y 13
-KPX L W 1
-KPX L V -4
-KPX L T 28
-
-KPX P period -60
-KPX P comma -55
-KPX P A -8
-
-KPX R y 59
-KPX R Y 26
-KPX R W 13
-KPX R V 8
-KPX R T 71
-
-KPX T s 16
-KPX T r 38
-KPX T period -33
-KPX T o 15
-KPX T i 42
-KPX T hyphen 90
-KPX T e 13
-KPX T comma -28
-KPX T c 14
-KPX T a 17
-KPX T A 1
-
-KPX V y 15
-KPX V u -38
-KPX V r -41
-KPX V period -40
-KPX V o -71
-KPX V i -20
-KPX V hyphen 11
-KPX V e -72
-KPX V comma -34
-KPX V a -69
-KPX V A -66
-
-KPX W y 15
-KPX W u -38
-KPX W r -41
-KPX W period -40
-KPX W o -68
-KPX W i -20
-KPX W hyphen 11
-KPX W e -69
-KPX W comma -34
-KPX W a -66
-KPX W A -64
-
-KPX Y v 15
-KPX Y u -38
-KPX Y q -55
-KPX Y period -40
-KPX Y p -31
-KPX Y o -57
-KPX Y i -37
-KPX Y hyphen 11
-KPX Y e -58
-KPX Y comma -34
-KPX Y a -54
-KPX Y A -53
-
-KPX f f 29
-
-KPX r q 9
-KPX r period -64
-KPX r o 8
-KPX r n 31
-KPX r m 31
-KPX r hyphen 70
-KPX r h -21
-KPX r g -4
-KPX r f 33
-KPX r e 7
-KPX r d 7
-KPX r comma -58
-KPX r c 7
-EndKernPairs
-EndKernData
-StartComposites 56
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 200 177 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 130 177 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 130 177 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 140 177 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 180 177 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 120 177 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 220 177 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 150 177 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 150 177 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 160 177 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 20 177 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -40 177 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -40 177 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave -20 177 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 150 177 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 260 177 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 190 177 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 190 177 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 200 177 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 180 177 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 120 177 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 250 177 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 180 177 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 180 177 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 190 177 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 150 177 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 110 177 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 110 177 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 120 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 80 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 120 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 130 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 70 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 90 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 50 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 50 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 90 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -20 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -60 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -60 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -20 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 110 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 110 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 70 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 70 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 110 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 60 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 50 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 170 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 130 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 130 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 170 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 100 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 60 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 30 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pbkli8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pbkli8a.afm
deleted file mode 100644
index 419c319a25..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pbkli8a.afm
+++ /dev/null
@@ -1,410 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Tue Jan 21 16:12:06 1992
-Comment UniqueID 37830
-Comment VMusage 33139 40031
-FontName Bookman-LightItalic
-FullName ITC Bookman Light Italic
-FamilyName ITC Bookman
-Weight Light
-ItalicAngle -10
-IsFixedPitch false
-FontBBox -228 -250 1269 883
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.004
-Notice Copyright (c) 1985, 1987, 1989, 1992 Adobe Systems Incorporated. All Rights Reserved.ITC Bookman is a registered trademark of International Typeface Corporation.
-EncodingScheme AdobeStandardEncoding
-CapHeight 681
-XHeight 494
-Ascender 717
-Descender -212
-StartCharMetrics 228
-C 32 ; WX 300 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 320 ; N exclam ; B 103 -8 342 698 ;
-C 34 ; WX 360 ; N quotedbl ; B 107 468 402 698 ;
-C 35 ; WX 620 ; N numbersign ; B 107 0 598 681 ;
-C 36 ; WX 620 ; N dollar ; B 78 -85 619 762 ;
-C 37 ; WX 800 ; N percent ; B 56 -8 811 691 ;
-C 38 ; WX 820 ; N ampersand ; B 65 -18 848 698 ;
-C 39 ; WX 280 ; N quoteright ; B 148 470 288 698 ;
-C 40 ; WX 280 ; N parenleft ; B 96 -146 383 727 ;
-C 41 ; WX 280 ; N parenright ; B -8 -146 279 727 ;
-C 42 ; WX 440 ; N asterisk ; B 139 324 505 698 ;
-C 43 ; WX 600 ; N plus ; B 91 43 595 548 ;
-C 44 ; WX 300 ; N comma ; B 88 -115 227 112 ;
-C 45 ; WX 320 ; N hyphen ; B 78 269 336 325 ;
-C 46 ; WX 300 ; N period ; B 96 -8 231 127 ;
-C 47 ; WX 600 ; N slash ; B 104 -149 562 717 ;
-C 48 ; WX 620 ; N zero ; B 86 -17 646 698 ;
-C 49 ; WX 620 ; N one ; B 154 0 500 681 ;
-C 50 ; WX 620 ; N two ; B 66 0 636 698 ;
-C 51 ; WX 620 ; N three ; B 55 -17 622 698 ;
-C 52 ; WX 620 ; N four ; B 69 0 634 681 ;
-C 53 ; WX 620 ; N five ; B 70 -17 614 681 ;
-C 54 ; WX 620 ; N six ; B 89 -17 657 698 ;
-C 55 ; WX 620 ; N seven ; B 143 0 672 681 ;
-C 56 ; WX 620 ; N eight ; B 61 -17 655 698 ;
-C 57 ; WX 620 ; N nine ; B 77 -17 649 698 ;
-C 58 ; WX 300 ; N colon ; B 96 -8 292 494 ;
-C 59 ; WX 300 ; N semicolon ; B 88 -114 292 494 ;
-C 60 ; WX 600 ; N less ; B 79 33 588 561 ;
-C 61 ; WX 600 ; N equal ; B 91 161 595 433 ;
-C 62 ; WX 600 ; N greater ; B 93 33 602 561 ;
-C 63 ; WX 540 ; N question ; B 114 -8 604 698 ;
-C 64 ; WX 780 ; N at ; B 102 -17 802 698 ;
-C 65 ; WX 700 ; N A ; B -25 0 720 681 ;
-C 66 ; WX 720 ; N B ; B 21 0 746 681 ;
-C 67 ; WX 720 ; N C ; B 88 -17 746 698 ;
-C 68 ; WX 740 ; N D ; B 21 0 782 681 ;
-C 69 ; WX 680 ; N E ; B 21 0 736 681 ;
-C 70 ; WX 620 ; N F ; B 21 0 743 681 ;
-C 71 ; WX 760 ; N G ; B 88 -17 813 698 ;
-C 72 ; WX 800 ; N H ; B 21 0 888 681 ;
-C 73 ; WX 320 ; N I ; B 21 0 412 681 ;
-C 74 ; WX 560 ; N J ; B -2 -17 666 681 ;
-C 75 ; WX 720 ; N K ; B 21 0 804 681 ;
-C 76 ; WX 580 ; N L ; B 21 0 656 681 ;
-C 77 ; WX 860 ; N M ; B 18 0 956 681 ;
-C 78 ; WX 720 ; N N ; B 18 0 823 681 ;
-C 79 ; WX 760 ; N O ; B 88 -17 799 698 ;
-C 80 ; WX 600 ; N P ; B 21 0 681 681 ;
-C 81 ; WX 780 ; N Q ; B 61 -191 812 698 ;
-C 82 ; WX 700 ; N R ; B 21 0 736 681 ;
-C 83 ; WX 640 ; N S ; B 61 -17 668 698 ;
-C 84 ; WX 600 ; N T ; B 50 0 725 681 ;
-C 85 ; WX 720 ; N U ; B 118 -17 842 681 ;
-C 86 ; WX 680 ; N V ; B 87 0 815 681 ;
-C 87 ; WX 960 ; N W ; B 87 0 1095 681 ;
-C 88 ; WX 700 ; N X ; B -25 0 815 681 ;
-C 89 ; WX 660 ; N Y ; B 87 0 809 681 ;
-C 90 ; WX 580 ; N Z ; B 8 0 695 681 ;
-C 91 ; WX 260 ; N bracketleft ; B 56 -136 351 717 ;
-C 92 ; WX 600 ; N backslash ; B 84 0 542 717 ;
-C 93 ; WX 260 ; N bracketright ; B 15 -136 309 717 ;
-C 94 ; WX 600 ; N asciicircum ; B 97 276 599 681 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 280 ; N quoteleft ; B 191 470 330 698 ;
-C 97 ; WX 620 ; N a ; B 71 -8 686 494 ;
-C 98 ; WX 600 ; N b ; B 88 -8 621 717 ;
-C 99 ; WX 480 ; N c ; B 65 -8 522 494 ;
-C 100 ; WX 640 ; N d ; B 65 -8 695 717 ;
-C 101 ; WX 540 ; N e ; B 65 -8 575 494 ;
-C 102 ; WX 340 ; N f ; B -160 -218 557 725 ; L i fi ; L l fl ;
-C 103 ; WX 560 ; N g ; B 4 -221 581 494 ;
-C 104 ; WX 620 ; N h ; B 88 -8 689 717 ;
-C 105 ; WX 280 ; N i ; B 88 -8 351 663 ;
-C 106 ; WX 280 ; N j ; B -200 -221 308 663 ;
-C 107 ; WX 600 ; N k ; B 88 -8 657 717 ;
-C 108 ; WX 280 ; N l ; B 100 -8 342 717 ;
-C 109 ; WX 880 ; N m ; B 88 -8 952 494 ;
-C 110 ; WX 620 ; N n ; B 88 -8 673 494 ;
-C 111 ; WX 540 ; N o ; B 65 -8 572 494 ;
-C 112 ; WX 600 ; N p ; B -24 -212 620 494 ;
-C 113 ; WX 560 ; N q ; B 65 -212 584 494 ;
-C 114 ; WX 400 ; N r ; B 88 0 481 494 ;
-C 115 ; WX 540 ; N s ; B 65 -8 547 494 ;
-C 116 ; WX 340 ; N t ; B 88 -8 411 664 ;
-C 117 ; WX 620 ; N u ; B 88 -8 686 484 ;
-C 118 ; WX 540 ; N v ; B 88 -8 562 494 ;
-C 119 ; WX 880 ; N w ; B 88 -8 893 494 ;
-C 120 ; WX 540 ; N x ; B 9 -8 626 494 ;
-C 121 ; WX 600 ; N y ; B 60 -221 609 484 ;
-C 122 ; WX 520 ; N z ; B 38 -8 561 494 ;
-C 123 ; WX 360 ; N braceleft ; B 122 -191 442 717 ;
-C 124 ; WX 600 ; N bar ; B 294 -250 372 750 ;
-C 125 ; WX 380 ; N braceright ; B 13 -191 333 717 ;
-C 126 ; WX 600 ; N asciitilde ; B 91 207 595 386 ;
-C 161 ; WX 320 ; N exclamdown ; B 73 -213 301 494 ;
-C 162 ; WX 620 ; N cent ; B 148 -29 596 715 ;
-C 163 ; WX 620 ; N sterling ; B 4 -17 702 698 ;
-C 164 ; WX 20 ; N fraction ; B -228 0 323 681 ;
-C 165 ; WX 620 ; N yen ; B 71 0 735 681 ;
-C 166 ; WX 620 ; N florin ; B -26 -218 692 725 ;
-C 167 ; WX 620 ; N section ; B 38 -178 638 698 ;
-C 168 ; WX 620 ; N currency ; B 100 89 605 591 ;
-C 169 ; WX 200 ; N quotesingle ; B 99 473 247 698 ;
-C 170 ; WX 440 ; N quotedblleft ; B 191 470 493 698 ;
-C 171 ; WX 300 ; N guillemotleft ; B 70 129 313 434 ;
-C 172 ; WX 180 ; N guilsinglleft ; B 75 129 208 434 ;
-C 173 ; WX 180 ; N guilsinglright ; B 70 129 203 434 ;
-C 174 ; WX 640 ; N fi ; B -159 -222 709 725 ;
-C 175 ; WX 660 ; N fl ; B -159 -218 713 725 ;
-C 177 ; WX 500 ; N endash ; B 33 269 561 325 ;
-C 178 ; WX 620 ; N dagger ; B 192 -130 570 698 ;
-C 179 ; WX 620 ; N daggerdbl ; B 144 -122 566 698 ;
-C 180 ; WX 300 ; N periodcentered ; B 137 229 272 364 ;
-C 182 ; WX 620 ; N paragraph ; B 112 0 718 681 ;
-C 183 ; WX 460 ; N bullet ; B 100 170 444 511 ;
-C 184 ; WX 320 ; N quotesinglbase ; B 87 -114 226 113 ;
-C 185 ; WX 480 ; N quotedblbase ; B 87 -114 390 113 ;
-C 186 ; WX 440 ; N quotedblright ; B 148 470 451 698 ;
-C 187 ; WX 300 ; N guillemotright ; B 60 129 303 434 ;
-C 188 ; WX 1000 ; N ellipsis ; B 99 -8 900 127 ;
-C 189 ; WX 1180 ; N perthousand ; B 56 -8 1199 691 ;
-C 191 ; WX 540 ; N questiondown ; B 18 -212 508 494 ;
-C 193 ; WX 340 ; N grave ; B 182 551 377 706 ;
-C 194 ; WX 320 ; N acute ; B 178 551 373 706 ;
-C 195 ; WX 440 ; N circumflex ; B 176 571 479 685 ;
-C 196 ; WX 440 ; N tilde ; B 180 586 488 671 ;
-C 197 ; WX 440 ; N macron ; B 178 599 484 658 ;
-C 198 ; WX 440 ; N breve ; B 191 577 500 680 ;
-C 199 ; WX 260 ; N dotaccent ; B 169 543 290 664 ;
-C 200 ; WX 420 ; N dieresis ; B 185 569 467 688 ;
-C 202 ; WX 300 ; N ring ; B 178 551 334 706 ;
-C 203 ; WX 320 ; N cedilla ; B 45 -178 240 0 ;
-C 205 ; WX 340 ; N hungarumlaut ; B 167 547 402 738 ;
-C 206 ; WX 260 ; N ogonek ; B 51 -173 184 0 ;
-C 207 ; WX 440 ; N caron ; B 178 571 481 684 ;
-C 208 ; WX 1000 ; N emdash ; B 33 269 1061 325 ;
-C 225 ; WX 1220 ; N AE ; B -45 0 1269 681 ;
-C 227 ; WX 440 ; N ordfeminine ; B 130 396 513 698 ;
-C 232 ; WX 580 ; N Lslash ; B 21 0 656 681 ;
-C 233 ; WX 760 ; N Oslash ; B 88 -95 799 777 ;
-C 234 ; WX 1180 ; N OE ; B 88 -17 1237 698 ;
-C 235 ; WX 400 ; N ordmasculine ; B 139 396 455 698 ;
-C 241 ; WX 880 ; N ae ; B 71 -8 918 494 ;
-C 245 ; WX 280 ; N dotlessi ; B 88 -8 351 484 ;
-C 248 ; WX 340 ; N lslash ; B 50 -8 398 717 ;
-C 249 ; WX 540 ; N oslash ; B 65 -49 571 532 ;
-C 250 ; WX 900 ; N oe ; B 65 -8 948 494 ;
-C 251 ; WX 620 ; N germandbls ; B -121 -111 653 698 ;
-C -1 ; WX 540 ; N ecircumflex ; B 65 -8 575 685 ;
-C -1 ; WX 540 ; N edieresis ; B 65 -8 575 688 ;
-C -1 ; WX 620 ; N aacute ; B 71 -8 686 706 ;
-C -1 ; WX 740 ; N registered ; B 84 -17 784 698 ;
-C -1 ; WX 280 ; N icircumflex ; B 76 -8 379 685 ;
-C -1 ; WX 620 ; N udieresis ; B 88 -8 686 688 ;
-C -1 ; WX 540 ; N ograve ; B 65 -8 572 706 ;
-C -1 ; WX 620 ; N uacute ; B 88 -8 686 706 ;
-C -1 ; WX 620 ; N ucircumflex ; B 88 -8 686 685 ;
-C -1 ; WX 700 ; N Aacute ; B -25 0 720 883 ;
-C -1 ; WX 280 ; N igrave ; B 88 -8 351 706 ;
-C -1 ; WX 320 ; N Icircumflex ; B 21 0 449 862 ;
-C -1 ; WX 480 ; N ccedilla ; B 65 -178 522 494 ;
-C -1 ; WX 620 ; N adieresis ; B 71 -8 686 688 ;
-C -1 ; WX 680 ; N Ecircumflex ; B 21 0 736 862 ;
-C -1 ; WX 540 ; N scaron ; B 65 -8 547 684 ;
-C -1 ; WX 600 ; N thorn ; B -24 -212 620 717 ;
-C -1 ; WX 980 ; N trademark ; B 69 277 965 681 ;
-C -1 ; WX 540 ; N egrave ; B 65 -8 575 706 ;
-C -1 ; WX 372 ; N threesuperior ; B 70 269 439 698 ;
-C -1 ; WX 520 ; N zcaron ; B 38 -8 561 684 ;
-C -1 ; WX 620 ; N atilde ; B 71 -8 686 671 ;
-C -1 ; WX 620 ; N aring ; B 71 -8 686 706 ;
-C -1 ; WX 540 ; N ocircumflex ; B 65 -8 572 685 ;
-C -1 ; WX 680 ; N Edieresis ; B 21 0 736 865 ;
-C -1 ; WX 930 ; N threequarters ; B 99 0 913 691 ;
-C -1 ; WX 600 ; N ydieresis ; B 60 -221 609 688 ;
-C -1 ; WX 600 ; N yacute ; B 60 -221 609 706 ;
-C -1 ; WX 280 ; N iacute ; B 88 -8 351 706 ;
-C -1 ; WX 700 ; N Acircumflex ; B -25 0 720 862 ;
-C -1 ; WX 720 ; N Uacute ; B 118 -17 842 883 ;
-C -1 ; WX 540 ; N eacute ; B 65 -8 575 706 ;
-C -1 ; WX 760 ; N Ograve ; B 88 -17 799 883 ;
-C -1 ; WX 620 ; N agrave ; B 71 -8 686 706 ;
-C -1 ; WX 720 ; N Udieresis ; B 118 -17 842 865 ;
-C -1 ; WX 620 ; N acircumflex ; B 71 -8 686 685 ;
-C -1 ; WX 320 ; N Igrave ; B 21 0 412 883 ;
-C -1 ; WX 372 ; N twosuperior ; B 68 279 439 698 ;
-C -1 ; WX 720 ; N Ugrave ; B 118 -17 842 883 ;
-C -1 ; WX 930 ; N onequarter ; B 91 0 913 681 ;
-C -1 ; WX 720 ; N Ucircumflex ; B 118 -17 842 862 ;
-C -1 ; WX 640 ; N Scaron ; B 61 -17 668 861 ;
-C -1 ; WX 320 ; N Idieresis ; B 21 0 447 865 ;
-C -1 ; WX 280 ; N idieresis ; B 88 -8 377 688 ;
-C -1 ; WX 680 ; N Egrave ; B 21 0 736 883 ;
-C -1 ; WX 760 ; N Oacute ; B 88 -17 799 883 ;
-C -1 ; WX 600 ; N divide ; B 91 46 595 548 ;
-C -1 ; WX 700 ; N Atilde ; B -25 0 720 848 ;
-C -1 ; WX 700 ; N Aring ; B -25 0 720 883 ;
-C -1 ; WX 760 ; N Odieresis ; B 88 -17 799 865 ;
-C -1 ; WX 700 ; N Adieresis ; B -25 0 720 865 ;
-C -1 ; WX 720 ; N Ntilde ; B 18 0 823 848 ;
-C -1 ; WX 580 ; N Zcaron ; B 8 0 695 861 ;
-C -1 ; WX 600 ; N Thorn ; B 21 0 656 681 ;
-C -1 ; WX 320 ; N Iacute ; B 21 0 412 883 ;
-C -1 ; WX 600 ; N plusminus ; B 91 0 595 548 ;
-C -1 ; WX 600 ; N multiply ; B 91 44 595 548 ;
-C -1 ; WX 680 ; N Eacute ; B 21 0 736 883 ;
-C -1 ; WX 660 ; N Ydieresis ; B 87 0 809 865 ;
-C -1 ; WX 372 ; N onesuperior ; B 114 279 339 688 ;
-C -1 ; WX 620 ; N ugrave ; B 88 -8 686 706 ;
-C -1 ; WX 600 ; N logicalnot ; B 91 163 595 433 ;
-C -1 ; WX 620 ; N ntilde ; B 88 -8 673 671 ;
-C -1 ; WX 760 ; N Otilde ; B 88 -17 799 848 ;
-C -1 ; WX 540 ; N otilde ; B 65 -8 572 671 ;
-C -1 ; WX 720 ; N Ccedilla ; B 88 -178 746 698 ;
-C -1 ; WX 700 ; N Agrave ; B -25 0 720 883 ;
-C -1 ; WX 930 ; N onehalf ; B 91 0 925 681 ;
-C -1 ; WX 740 ; N Eth ; B 21 0 782 681 ;
-C -1 ; WX 400 ; N degree ; B 120 398 420 698 ;
-C -1 ; WX 660 ; N Yacute ; B 87 0 809 883 ;
-C -1 ; WX 760 ; N Ocircumflex ; B 88 -17 799 862 ;
-C -1 ; WX 540 ; N oacute ; B 65 -8 572 706 ;
-C -1 ; WX 620 ; N mu ; B 53 -221 686 484 ;
-C -1 ; WX 600 ; N minus ; B 91 259 595 335 ;
-C -1 ; WX 540 ; N eth ; B 65 -8 642 725 ;
-C -1 ; WX 540 ; N odieresis ; B 65 -8 572 688 ;
-C -1 ; WX 740 ; N copyright ; B 84 -17 784 698 ;
-C -1 ; WX 600 ; N brokenbar ; B 294 -175 372 675 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 85
-
-KPX A Y -62
-KPX A W -73
-KPX A V -78
-KPX A T -5
-
-KPX F period -97
-KPX F comma -98
-KPX F A -16
-
-KPX L y 20
-KPX L Y 7
-KPX L W 9
-KPX L V 4
-
-KPX P period -105
-KPX P comma -106
-KPX P A -30
-
-KPX R Y 11
-KPX R W 2
-KPX R V 2
-KPX R T 65
-
-KPX T semicolon 48
-KPX T s -7
-KPX T r 67
-KPX T period -78
-KPX T o 14
-KPX T i 71
-KPX T hyphen 20
-KPX T e 10
-KPX T comma -79
-KPX T colon 48
-KPX T c 16
-KPX T a 9
-KPX T A -14
-
-KPX V y -14
-KPX V u -10
-KPX V semicolon -44
-KPX V r -20
-KPX V period -100
-KPX V o -70
-KPX V i 3
-KPX V hyphen 20
-KPX V e -70
-KPX V comma -109
-KPX V colon -35
-KPX V a -70
-KPX V A -70
-
-KPX W y -14
-KPX W u -20
-KPX W semicolon -42
-KPX W r -30
-KPX W period -100
-KPX W o -60
-KPX W i 3
-KPX W hyphen 20
-KPX W e -60
-KPX W comma -109
-KPX W colon -35
-KPX W a -60
-KPX W A -60
-
-KPX Y v -19
-KPX Y u -31
-KPX Y semicolon -40
-KPX Y q -72
-KPX Y period -100
-KPX Y p -37
-KPX Y o -75
-KPX Y i -11
-KPX Y hyphen 20
-KPX Y e -78
-KPX Y comma -109
-KPX Y colon -35
-KPX Y a -79
-KPX Y A -82
-
-KPX f f -19
-
-KPX r q -14
-KPX r period -134
-KPX r o -10
-KPX r n 38
-KPX r m 37
-KPX r hyphen 20
-KPX r h -20
-KPX r g -3
-KPX r f -9
-KPX r e -15
-KPX r d -9
-KPX r comma -143
-KPX r c -8
-EndKernPairs
-EndKernData
-StartComposites 56
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 200 177 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 130 177 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 140 177 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 160 177 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 220 177 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 130 177 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 210 177 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 140 177 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 150 177 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 150 177 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 30 177 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -30 177 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -20 177 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave -30 177 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 130 177 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 250 177 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 190 177 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 200 177 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 210 177 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 190 177 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 100 177 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 230 177 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 170 177 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 180 177 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 170 177 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 200 177 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 140 177 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 70 177 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 120 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 70 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 80 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 110 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 140 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 60 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 90 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 30 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 40 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 80 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -40 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -100 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -90 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -60 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 60 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 80 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 20 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 40 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 80 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 30 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 30 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 120 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 60 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 70 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 110 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 140 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 70 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 20 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pcrb8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pcrb8a.afm
deleted file mode 100644
index baf3a51512..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pcrb8a.afm
+++ /dev/null
@@ -1,344 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1989, 1990, 1991, Adobe Systems Incorporated. All rights reserved.
-Comment Creation Date: Tue Sep 17 14:02:41 1991
-Comment UniqueID 36384
-Comment VMusage 31992 40360
-FontName Courier-Bold
-FullName Courier Bold
-FamilyName Courier
-Weight Bold
-ItalicAngle 0
-IsFixedPitch true
-FontBBox -113 -250 749 801
-UnderlinePosition -100
-UnderlineThickness 50
-Version 002.004
-Notice Copyright (c) 1989, 1990, 1991, Adobe Systems Incorporated. All rights reserved.
-EncodingScheme AdobeStandardEncoding
-CapHeight 562
-XHeight 439
-Ascender 626
-Descender -142
-StartCharMetrics 260
-C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 600 ; N exclam ; B 202 -15 398 572 ;
-C 34 ; WX 600 ; N quotedbl ; B 135 277 465 562 ;
-C 35 ; WX 600 ; N numbersign ; B 56 -45 544 651 ;
-C 36 ; WX 600 ; N dollar ; B 82 -126 519 666 ;
-C 37 ; WX 600 ; N percent ; B 5 -15 595 616 ;
-C 38 ; WX 600 ; N ampersand ; B 36 -15 546 543 ;
-C 39 ; WX 600 ; N quoteright ; B 171 277 423 562 ;
-C 40 ; WX 600 ; N parenleft ; B 219 -102 461 616 ;
-C 41 ; WX 600 ; N parenright ; B 139 -102 381 616 ;
-C 42 ; WX 600 ; N asterisk ; B 91 219 509 601 ;
-C 43 ; WX 600 ; N plus ; B 71 39 529 478 ;
-C 44 ; WX 600 ; N comma ; B 123 -111 393 174 ;
-C 45 ; WX 600 ; N hyphen ; B 100 203 500 313 ;
-C 46 ; WX 600 ; N period ; B 192 -15 408 171 ;
-C 47 ; WX 600 ; N slash ; B 98 -77 502 626 ;
-C 48 ; WX 600 ; N zero ; B 87 -15 513 616 ;
-C 49 ; WX 600 ; N one ; B 81 0 539 616 ;
-C 50 ; WX 600 ; N two ; B 61 0 499 616 ;
-C 51 ; WX 600 ; N three ; B 63 -15 501 616 ;
-C 52 ; WX 600 ; N four ; B 53 0 507 616 ;
-C 53 ; WX 600 ; N five ; B 70 -15 521 601 ;
-C 54 ; WX 600 ; N six ; B 90 -15 521 616 ;
-C 55 ; WX 600 ; N seven ; B 55 0 494 601 ;
-C 56 ; WX 600 ; N eight ; B 83 -15 517 616 ;
-C 57 ; WX 600 ; N nine ; B 79 -15 510 616 ;
-C 58 ; WX 600 ; N colon ; B 191 -15 407 425 ;
-C 59 ; WX 600 ; N semicolon ; B 123 -111 408 425 ;
-C 60 ; WX 600 ; N less ; B 66 15 523 501 ;
-C 61 ; WX 600 ; N equal ; B 71 118 529 398 ;
-C 62 ; WX 600 ; N greater ; B 77 15 534 501 ;
-C 63 ; WX 600 ; N question ; B 98 -14 501 580 ;
-C 64 ; WX 600 ; N at ; B 16 -15 584 616 ;
-C 65 ; WX 600 ; N A ; B -9 0 609 562 ;
-C 66 ; WX 600 ; N B ; B 30 0 573 562 ;
-C 67 ; WX 600 ; N C ; B 22 -18 560 580 ;
-C 68 ; WX 600 ; N D ; B 30 0 594 562 ;
-C 69 ; WX 600 ; N E ; B 25 0 560 562 ;
-C 70 ; WX 600 ; N F ; B 39 0 570 562 ;
-C 71 ; WX 600 ; N G ; B 22 -18 594 580 ;
-C 72 ; WX 600 ; N H ; B 20 0 580 562 ;
-C 73 ; WX 600 ; N I ; B 77 0 523 562 ;
-C 74 ; WX 600 ; N J ; B 37 -18 601 562 ;
-C 75 ; WX 600 ; N K ; B 21 0 599 562 ;
-C 76 ; WX 600 ; N L ; B 39 0 578 562 ;
-C 77 ; WX 600 ; N M ; B -2 0 602 562 ;
-C 78 ; WX 600 ; N N ; B 8 -12 610 562 ;
-C 79 ; WX 600 ; N O ; B 22 -18 578 580 ;
-C 80 ; WX 600 ; N P ; B 48 0 559 562 ;
-C 81 ; WX 600 ; N Q ; B 32 -138 578 580 ;
-C 82 ; WX 600 ; N R ; B 24 0 599 562 ;
-C 83 ; WX 600 ; N S ; B 47 -22 553 582 ;
-C 84 ; WX 600 ; N T ; B 21 0 579 562 ;
-C 85 ; WX 600 ; N U ; B 4 -18 596 562 ;
-C 86 ; WX 600 ; N V ; B -13 0 613 562 ;
-C 87 ; WX 600 ; N W ; B -18 0 618 562 ;
-C 88 ; WX 600 ; N X ; B 12 0 588 562 ;
-C 89 ; WX 600 ; N Y ; B 12 0 589 562 ;
-C 90 ; WX 600 ; N Z ; B 62 0 539 562 ;
-C 91 ; WX 600 ; N bracketleft ; B 245 -102 475 616 ;
-C 92 ; WX 600 ; N backslash ; B 99 -77 503 626 ;
-C 93 ; WX 600 ; N bracketright ; B 125 -102 355 616 ;
-C 94 ; WX 600 ; N asciicircum ; B 108 250 492 616 ;
-C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ;
-C 96 ; WX 600 ; N quoteleft ; B 178 277 428 562 ;
-C 97 ; WX 600 ; N a ; B 35 -15 570 454 ;
-C 98 ; WX 600 ; N b ; B 0 -15 584 626 ;
-C 99 ; WX 600 ; N c ; B 40 -15 545 459 ;
-C 100 ; WX 600 ; N d ; B 20 -15 591 626 ;
-C 101 ; WX 600 ; N e ; B 40 -15 563 454 ;
-C 102 ; WX 600 ; N f ; B 83 0 547 626 ; L i fi ; L l fl ;
-C 103 ; WX 600 ; N g ; B 30 -146 580 454 ;
-C 104 ; WX 600 ; N h ; B 5 0 592 626 ;
-C 105 ; WX 600 ; N i ; B 77 0 523 658 ;
-C 106 ; WX 600 ; N j ; B 63 -146 440 658 ;
-C 107 ; WX 600 ; N k ; B 20 0 585 626 ;
-C 108 ; WX 600 ; N l ; B 77 0 523 626 ;
-C 109 ; WX 600 ; N m ; B -22 0 626 454 ;
-C 110 ; WX 600 ; N n ; B 18 0 592 454 ;
-C 111 ; WX 600 ; N o ; B 30 -15 570 454 ;
-C 112 ; WX 600 ; N p ; B -1 -142 570 454 ;
-C 113 ; WX 600 ; N q ; B 20 -142 591 454 ;
-C 114 ; WX 600 ; N r ; B 47 0 580 454 ;
-C 115 ; WX 600 ; N s ; B 68 -17 535 459 ;
-C 116 ; WX 600 ; N t ; B 47 -15 532 562 ;
-C 117 ; WX 600 ; N u ; B -1 -15 569 439 ;
-C 118 ; WX 600 ; N v ; B -1 0 601 439 ;
-C 119 ; WX 600 ; N w ; B -18 0 618 439 ;
-C 120 ; WX 600 ; N x ; B 6 0 594 439 ;
-C 121 ; WX 600 ; N y ; B -4 -142 601 439 ;
-C 122 ; WX 600 ; N z ; B 81 0 520 439 ;
-C 123 ; WX 600 ; N braceleft ; B 160 -102 464 616 ;
-C 124 ; WX 600 ; N bar ; B 255 -250 345 750 ;
-C 125 ; WX 600 ; N braceright ; B 136 -102 440 616 ;
-C 126 ; WX 600 ; N asciitilde ; B 71 153 530 356 ;
-C 161 ; WX 600 ; N exclamdown ; B 202 -146 398 449 ;
-C 162 ; WX 600 ; N cent ; B 66 -49 518 614 ;
-C 163 ; WX 600 ; N sterling ; B 72 -28 558 611 ;
-C 164 ; WX 600 ; N fraction ; B 25 -60 576 661 ;
-C 165 ; WX 600 ; N yen ; B 10 0 590 562 ;
-C 166 ; WX 600 ; N florin ; B -30 -131 572 616 ;
-C 167 ; WX 600 ; N section ; B 83 -70 517 580 ;
-C 168 ; WX 600 ; N currency ; B 54 49 546 517 ;
-C 169 ; WX 600 ; N quotesingle ; B 227 277 373 562 ;
-C 170 ; WX 600 ; N quotedblleft ; B 71 277 535 562 ;
-C 171 ; WX 600 ; N guillemotleft ; B 8 70 553 446 ;
-C 172 ; WX 600 ; N guilsinglleft ; B 141 70 459 446 ;
-C 173 ; WX 600 ; N guilsinglright ; B 141 70 459 446 ;
-C 174 ; WX 600 ; N fi ; B 12 0 593 626 ;
-C 175 ; WX 600 ; N fl ; B 12 0 593 626 ;
-C 177 ; WX 600 ; N endash ; B 65 203 535 313 ;
-C 178 ; WX 600 ; N dagger ; B 106 -70 494 580 ;
-C 179 ; WX 600 ; N daggerdbl ; B 106 -70 494 580 ;
-C 180 ; WX 600 ; N periodcentered ; B 196 165 404 351 ;
-C 182 ; WX 600 ; N paragraph ; B 6 -70 576 580 ;
-C 183 ; WX 600 ; N bullet ; B 140 132 460 430 ;
-C 184 ; WX 600 ; N quotesinglbase ; B 175 -142 427 143 ;
-C 185 ; WX 600 ; N quotedblbase ; B 65 -142 529 143 ;
-C 186 ; WX 600 ; N quotedblright ; B 61 277 525 562 ;
-C 187 ; WX 600 ; N guillemotright ; B 47 70 592 446 ;
-C 188 ; WX 600 ; N ellipsis ; B 26 -15 574 116 ;
-C 189 ; WX 600 ; N perthousand ; B -113 -15 713 616 ;
-C 191 ; WX 600 ; N questiondown ; B 99 -146 502 449 ;
-C 193 ; WX 600 ; N grave ; B 132 508 395 661 ;
-C 194 ; WX 600 ; N acute ; B 205 508 468 661 ;
-C 195 ; WX 600 ; N circumflex ; B 103 483 497 657 ;
-C 196 ; WX 600 ; N tilde ; B 89 493 512 636 ;
-C 197 ; WX 600 ; N macron ; B 88 505 512 585 ;
-C 198 ; WX 600 ; N breve ; B 83 468 517 631 ;
-C 199 ; WX 600 ; N dotaccent ; B 230 485 370 625 ;
-C 200 ; WX 600 ; N dieresis ; B 128 485 472 625 ;
-C 202 ; WX 600 ; N ring ; B 198 481 402 678 ;
-C 203 ; WX 600 ; N cedilla ; B 205 -206 387 0 ;
-C 205 ; WX 600 ; N hungarumlaut ; B 68 488 588 661 ;
-C 206 ; WX 600 ; N ogonek ; B 169 -199 367 0 ;
-C 207 ; WX 600 ; N caron ; B 103 493 497 667 ;
-C 208 ; WX 600 ; N emdash ; B -10 203 610 313 ;
-C 225 ; WX 600 ; N AE ; B -29 0 602 562 ;
-C 227 ; WX 600 ; N ordfeminine ; B 147 196 453 580 ;
-C 232 ; WX 600 ; N Lslash ; B 39 0 578 562 ;
-C 233 ; WX 600 ; N Oslash ; B 22 -22 578 584 ;
-C 234 ; WX 600 ; N OE ; B -25 0 595 562 ;
-C 235 ; WX 600 ; N ordmasculine ; B 147 196 453 580 ;
-C 241 ; WX 600 ; N ae ; B -4 -15 601 454 ;
-C 245 ; WX 600 ; N dotlessi ; B 77 0 523 439 ;
-C 248 ; WX 600 ; N lslash ; B 77 0 523 626 ;
-C 249 ; WX 600 ; N oslash ; B 30 -24 570 463 ;
-C 250 ; WX 600 ; N oe ; B -18 -15 611 454 ;
-C 251 ; WX 600 ; N germandbls ; B 22 -15 596 626 ;
-C -1 ; WX 600 ; N Odieresis ; B 22 -18 578 748 ;
-C -1 ; WX 600 ; N logicalnot ; B 71 103 529 413 ;
-C -1 ; WX 600 ; N minus ; B 71 203 529 313 ;
-C -1 ; WX 600 ; N merge ; B 137 -15 464 487 ;
-C -1 ; WX 600 ; N degree ; B 86 243 474 616 ;
-C -1 ; WX 600 ; N dectab ; B 8 0 592 320 ;
-C -1 ; WX 600 ; N ll ; B -12 0 600 626 ;
-C -1 ; WX 600 ; N IJ ; B -8 -18 622 562 ;
-C -1 ; WX 600 ; N Eacute ; B 25 0 560 784 ;
-C -1 ; WX 600 ; N Ocircumflex ; B 22 -18 578 780 ;
-C -1 ; WX 600 ; N ucircumflex ; B -1 -15 569 657 ;
-C -1 ; WX 600 ; N left ; B 65 44 535 371 ;
-C -1 ; WX 600 ; N threesuperior ; B 138 222 433 616 ;
-C -1 ; WX 600 ; N up ; B 136 0 463 447 ;
-C -1 ; WX 600 ; N multiply ; B 81 39 520 478 ;
-C -1 ; WX 600 ; N Scaron ; B 47 -22 553 790 ;
-C -1 ; WX 600 ; N tab ; B 19 0 581 562 ;
-C -1 ; WX 600 ; N Ucircumflex ; B 4 -18 596 780 ;
-C -1 ; WX 600 ; N divide ; B 71 16 529 500 ;
-C -1 ; WX 600 ; N Acircumflex ; B -9 0 609 780 ;
-C -1 ; WX 600 ; N eacute ; B 40 -15 563 661 ;
-C -1 ; WX 600 ; N uacute ; B -1 -15 569 661 ;
-C -1 ; WX 600 ; N Aacute ; B -9 0 609 784 ;
-C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ;
-C -1 ; WX 600 ; N twosuperior ; B 143 230 436 616 ;
-C -1 ; WX 600 ; N Ecircumflex ; B 25 0 560 780 ;
-C -1 ; WX 600 ; N ntilde ; B 18 0 592 636 ;
-C -1 ; WX 600 ; N down ; B 137 -15 464 439 ;
-C -1 ; WX 600 ; N center ; B 40 14 560 580 ;
-C -1 ; WX 600 ; N onesuperior ; B 153 230 447 616 ;
-C -1 ; WX 600 ; N ij ; B 6 -146 574 658 ;
-C -1 ; WX 600 ; N edieresis ; B 40 -15 563 625 ;
-C -1 ; WX 600 ; N graybox ; B 76 0 525 599 ;
-C -1 ; WX 600 ; N odieresis ; B 30 -15 570 625 ;
-C -1 ; WX 600 ; N Ograve ; B 22 -18 578 784 ;
-C -1 ; WX 600 ; N threequarters ; B -47 -60 648 661 ;
-C -1 ; WX 600 ; N plusminus ; B 71 24 529 515 ;
-C -1 ; WX 600 ; N prescription ; B 24 -15 599 562 ;
-C -1 ; WX 600 ; N eth ; B 58 -27 543 626 ;
-C -1 ; WX 600 ; N largebullet ; B 248 229 352 333 ;
-C -1 ; WX 600 ; N egrave ; B 40 -15 563 661 ;
-C -1 ; WX 600 ; N ccedilla ; B 40 -206 545 459 ;
-C -1 ; WX 600 ; N notegraphic ; B 77 -15 523 572 ;
-C -1 ; WX 600 ; N Udieresis ; B 4 -18 596 748 ;
-C -1 ; WX 600 ; N Gcaron ; B 22 -18 594 790 ;
-C -1 ; WX 600 ; N arrowdown ; B 144 -15 456 608 ;
-C -1 ; WX 600 ; N format ; B 5 -146 115 601 ;
-C -1 ; WX 600 ; N Otilde ; B 22 -18 578 759 ;
-C -1 ; WX 600 ; N Idieresis ; B 77 0 523 748 ;
-C -1 ; WX 600 ; N adieresis ; B 35 -15 570 625 ;
-C -1 ; WX 600 ; N ecircumflex ; B 40 -15 563 657 ;
-C -1 ; WX 600 ; N Eth ; B 30 0 594 562 ;
-C -1 ; WX 600 ; N onequarter ; B -56 -60 656 661 ;
-C -1 ; WX 600 ; N LL ; B -45 0 645 562 ;
-C -1 ; WX 600 ; N agrave ; B 35 -15 570 661 ;
-C -1 ; WX 600 ; N Zcaron ; B 62 0 539 790 ;
-C -1 ; WX 600 ; N Scedilla ; B 47 -206 553 582 ;
-C -1 ; WX 600 ; N Idot ; B 77 0 523 748 ;
-C -1 ; WX 600 ; N Iacute ; B 77 0 523 784 ;
-C -1 ; WX 600 ; N indent ; B 65 45 535 372 ;
-C -1 ; WX 600 ; N Ugrave ; B 4 -18 596 784 ;
-C -1 ; WX 600 ; N scaron ; B 68 -17 535 667 ;
-C -1 ; WX 600 ; N overscore ; B 0 579 600 629 ;
-C -1 ; WX 600 ; N Aring ; B -9 0 609 801 ;
-C -1 ; WX 600 ; N Ccedilla ; B 22 -206 560 580 ;
-C -1 ; WX 600 ; N Igrave ; B 77 0 523 784 ;
-C -1 ; WX 600 ; N brokenbar ; B 255 -175 345 675 ;
-C -1 ; WX 600 ; N Oacute ; B 22 -18 578 784 ;
-C -1 ; WX 600 ; N otilde ; B 30 -15 570 636 ;
-C -1 ; WX 600 ; N Yacute ; B 12 0 589 784 ;
-C -1 ; WX 600 ; N lira ; B 72 -28 558 611 ;
-C -1 ; WX 600 ; N Icircumflex ; B 77 0 523 780 ;
-C -1 ; WX 600 ; N Atilde ; B -9 0 609 759 ;
-C -1 ; WX 600 ; N Uacute ; B 4 -18 596 784 ;
-C -1 ; WX 600 ; N Ydieresis ; B 12 0 589 748 ;
-C -1 ; WX 600 ; N ydieresis ; B -4 -142 601 625 ;
-C -1 ; WX 600 ; N idieresis ; B 77 0 523 625 ;
-C -1 ; WX 600 ; N Adieresis ; B -9 0 609 748 ;
-C -1 ; WX 600 ; N mu ; B -1 -142 569 439 ;
-C -1 ; WX 600 ; N trademark ; B -9 230 749 562 ;
-C -1 ; WX 600 ; N oacute ; B 30 -15 570 661 ;
-C -1 ; WX 600 ; N acircumflex ; B 35 -15 570 657 ;
-C -1 ; WX 600 ; N Agrave ; B -9 0 609 784 ;
-C -1 ; WX 600 ; N return ; B 19 0 581 562 ;
-C -1 ; WX 600 ; N atilde ; B 35 -15 570 636 ;
-C -1 ; WX 600 ; N square ; B 19 0 581 562 ;
-C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ;
-C -1 ; WX 600 ; N stop ; B 19 0 581 562 ;
-C -1 ; WX 600 ; N udieresis ; B -1 -15 569 625 ;
-C -1 ; WX 600 ; N arrowup ; B 144 3 456 626 ;
-C -1 ; WX 600 ; N igrave ; B 77 0 523 661 ;
-C -1 ; WX 600 ; N Edieresis ; B 25 0 560 748 ;
-C -1 ; WX 600 ; N zcaron ; B 81 0 520 667 ;
-C -1 ; WX 600 ; N arrowboth ; B -24 143 624 455 ;
-C -1 ; WX 600 ; N gcaron ; B 30 -146 580 667 ;
-C -1 ; WX 600 ; N arrowleft ; B -24 143 634 455 ;
-C -1 ; WX 600 ; N aacute ; B 35 -15 570 661 ;
-C -1 ; WX 600 ; N ocircumflex ; B 30 -15 570 657 ;
-C -1 ; WX 600 ; N scedilla ; B 68 -206 535 459 ;
-C -1 ; WX 600 ; N ograve ; B 30 -15 570 661 ;
-C -1 ; WX 600 ; N onehalf ; B -47 -60 648 661 ;
-C -1 ; WX 600 ; N ugrave ; B -1 -15 569 661 ;
-C -1 ; WX 600 ; N Ntilde ; B 8 -12 610 759 ;
-C -1 ; WX 600 ; N iacute ; B 77 0 523 661 ;
-C -1 ; WX 600 ; N arrowright ; B -34 143 624 455 ;
-C -1 ; WX 600 ; N Thorn ; B 48 0 557 562 ;
-C -1 ; WX 600 ; N Egrave ; B 25 0 560 784 ;
-C -1 ; WX 600 ; N thorn ; B -14 -142 570 626 ;
-C -1 ; WX 600 ; N aring ; B 35 -15 570 678 ;
-C -1 ; WX 600 ; N yacute ; B -4 -142 601 661 ;
-C -1 ; WX 600 ; N icircumflex ; B 63 0 523 657 ;
-EndCharMetrics
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 30 123 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -30 123 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis -20 123 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave -50 123 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring -10 123 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde -30 123 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 30 123 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 123 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 123 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 123 ;
-CC Gcaron 2 ; PCC G 0 0 ; PCC caron 10 123 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 123 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 123 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 123 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 123 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 123 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 123 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 123 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 123 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 123 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 123 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 0 123 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 30 123 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 123 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 123 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave -30 123 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 30 123 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 123 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 123 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex -20 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis -10 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave -30 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
-CC gcaron 2 ; PCC g 0 0 ; PCC caron -40 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -40 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -40 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -20 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis -20 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 30 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 10 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pcrbo8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pcrbo8a.afm
deleted file mode 100644
index 6e2c742251..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pcrbo8a.afm
+++ /dev/null
@@ -1,344 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1989, 1990, 1991, Adobe Systems Incorporated. All rights reserved.
-Comment Creation Date: Tue Sep 17 14:13:24 1991
-Comment UniqueID 36389
-Comment VMusage 10055 54684
-FontName Courier-BoldOblique
-FullName Courier Bold Oblique
-FamilyName Courier
-Weight Bold
-ItalicAngle -12
-IsFixedPitch true
-FontBBox -56 -250 868 801
-UnderlinePosition -100
-UnderlineThickness 50
-Version 002.004
-Notice Copyright (c) 1989, 1990, 1991, Adobe Systems Incorporated. All rights reserved.
-EncodingScheme AdobeStandardEncoding
-CapHeight 562
-XHeight 439
-Ascender 626
-Descender -142
-StartCharMetrics 260
-C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 600 ; N exclam ; B 216 -15 495 572 ;
-C 34 ; WX 600 ; N quotedbl ; B 212 277 584 562 ;
-C 35 ; WX 600 ; N numbersign ; B 88 -45 640 651 ;
-C 36 ; WX 600 ; N dollar ; B 87 -126 629 666 ;
-C 37 ; WX 600 ; N percent ; B 102 -15 624 616 ;
-C 38 ; WX 600 ; N ampersand ; B 62 -15 594 543 ;
-C 39 ; WX 600 ; N quoteright ; B 230 277 542 562 ;
-C 40 ; WX 600 ; N parenleft ; B 266 -102 592 616 ;
-C 41 ; WX 600 ; N parenright ; B 117 -102 444 616 ;
-C 42 ; WX 600 ; N asterisk ; B 179 219 597 601 ;
-C 43 ; WX 600 ; N plus ; B 114 39 596 478 ;
-C 44 ; WX 600 ; N comma ; B 99 -111 430 174 ;
-C 45 ; WX 600 ; N hyphen ; B 143 203 567 313 ;
-C 46 ; WX 600 ; N period ; B 207 -15 426 171 ;
-C 47 ; WX 600 ; N slash ; B 91 -77 626 626 ;
-C 48 ; WX 600 ; N zero ; B 136 -15 592 616 ;
-C 49 ; WX 600 ; N one ; B 93 0 561 616 ;
-C 50 ; WX 600 ; N two ; B 61 0 593 616 ;
-C 51 ; WX 600 ; N three ; B 72 -15 571 616 ;
-C 52 ; WX 600 ; N four ; B 82 0 558 616 ;
-C 53 ; WX 600 ; N five ; B 77 -15 621 601 ;
-C 54 ; WX 600 ; N six ; B 136 -15 652 616 ;
-C 55 ; WX 600 ; N seven ; B 147 0 622 601 ;
-C 56 ; WX 600 ; N eight ; B 115 -15 604 616 ;
-C 57 ; WX 600 ; N nine ; B 76 -15 592 616 ;
-C 58 ; WX 600 ; N colon ; B 206 -15 479 425 ;
-C 59 ; WX 600 ; N semicolon ; B 99 -111 480 425 ;
-C 60 ; WX 600 ; N less ; B 121 15 612 501 ;
-C 61 ; WX 600 ; N equal ; B 96 118 614 398 ;
-C 62 ; WX 600 ; N greater ; B 97 15 589 501 ;
-C 63 ; WX 600 ; N question ; B 183 -14 591 580 ;
-C 64 ; WX 600 ; N at ; B 66 -15 641 616 ;
-C 65 ; WX 600 ; N A ; B -9 0 631 562 ;
-C 66 ; WX 600 ; N B ; B 30 0 629 562 ;
-C 67 ; WX 600 ; N C ; B 75 -18 674 580 ;
-C 68 ; WX 600 ; N D ; B 30 0 664 562 ;
-C 69 ; WX 600 ; N E ; B 25 0 669 562 ;
-C 70 ; WX 600 ; N F ; B 39 0 683 562 ;
-C 71 ; WX 600 ; N G ; B 75 -18 674 580 ;
-C 72 ; WX 600 ; N H ; B 20 0 699 562 ;
-C 73 ; WX 600 ; N I ; B 77 0 642 562 ;
-C 74 ; WX 600 ; N J ; B 59 -18 720 562 ;
-C 75 ; WX 600 ; N K ; B 21 0 691 562 ;
-C 76 ; WX 600 ; N L ; B 39 0 635 562 ;
-C 77 ; WX 600 ; N M ; B -2 0 721 562 ;
-C 78 ; WX 600 ; N N ; B 8 -12 729 562 ;
-C 79 ; WX 600 ; N O ; B 74 -18 645 580 ;
-C 80 ; WX 600 ; N P ; B 48 0 642 562 ;
-C 81 ; WX 600 ; N Q ; B 84 -138 636 580 ;
-C 82 ; WX 600 ; N R ; B 24 0 617 562 ;
-C 83 ; WX 600 ; N S ; B 54 -22 672 582 ;
-C 84 ; WX 600 ; N T ; B 86 0 678 562 ;
-C 85 ; WX 600 ; N U ; B 101 -18 715 562 ;
-C 86 ; WX 600 ; N V ; B 84 0 732 562 ;
-C 87 ; WX 600 ; N W ; B 84 0 737 562 ;
-C 88 ; WX 600 ; N X ; B 12 0 689 562 ;
-C 89 ; WX 600 ; N Y ; B 109 0 708 562 ;
-C 90 ; WX 600 ; N Z ; B 62 0 636 562 ;
-C 91 ; WX 600 ; N bracketleft ; B 223 -102 606 616 ;
-C 92 ; WX 600 ; N backslash ; B 223 -77 496 626 ;
-C 93 ; WX 600 ; N bracketright ; B 103 -102 486 616 ;
-C 94 ; WX 600 ; N asciicircum ; B 171 250 555 616 ;
-C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ;
-C 96 ; WX 600 ; N quoteleft ; B 297 277 487 562 ;
-C 97 ; WX 600 ; N a ; B 62 -15 592 454 ;
-C 98 ; WX 600 ; N b ; B 13 -15 636 626 ;
-C 99 ; WX 600 ; N c ; B 81 -15 631 459 ;
-C 100 ; WX 600 ; N d ; B 61 -15 644 626 ;
-C 101 ; WX 600 ; N e ; B 81 -15 604 454 ;
-C 102 ; WX 600 ; N f ; B 83 0 677 626 ; L i fi ; L l fl ;
-C 103 ; WX 600 ; N g ; B 41 -146 673 454 ;
-C 104 ; WX 600 ; N h ; B 18 0 614 626 ;
-C 105 ; WX 600 ; N i ; B 77 0 545 658 ;
-C 106 ; WX 600 ; N j ; B 37 -146 580 658 ;
-C 107 ; WX 600 ; N k ; B 33 0 642 626 ;
-C 108 ; WX 600 ; N l ; B 77 0 545 626 ;
-C 109 ; WX 600 ; N m ; B -22 0 648 454 ;
-C 110 ; WX 600 ; N n ; B 18 0 614 454 ;
-C 111 ; WX 600 ; N o ; B 71 -15 622 454 ;
-C 112 ; WX 600 ; N p ; B -31 -142 622 454 ;
-C 113 ; WX 600 ; N q ; B 61 -142 684 454 ;
-C 114 ; WX 600 ; N r ; B 47 0 654 454 ;
-C 115 ; WX 600 ; N s ; B 67 -17 607 459 ;
-C 116 ; WX 600 ; N t ; B 118 -15 566 562 ;
-C 117 ; WX 600 ; N u ; B 70 -15 591 439 ;
-C 118 ; WX 600 ; N v ; B 70 0 694 439 ;
-C 119 ; WX 600 ; N w ; B 53 0 711 439 ;
-C 120 ; WX 600 ; N x ; B 6 0 670 439 ;
-C 121 ; WX 600 ; N y ; B -20 -142 694 439 ;
-C 122 ; WX 600 ; N z ; B 81 0 613 439 ;
-C 123 ; WX 600 ; N braceleft ; B 204 -102 595 616 ;
-C 124 ; WX 600 ; N bar ; B 202 -250 504 750 ;
-C 125 ; WX 600 ; N braceright ; B 114 -102 506 616 ;
-C 126 ; WX 600 ; N asciitilde ; B 120 153 589 356 ;
-C 161 ; WX 600 ; N exclamdown ; B 197 -146 477 449 ;
-C 162 ; WX 600 ; N cent ; B 121 -49 604 614 ;
-C 163 ; WX 600 ; N sterling ; B 107 -28 650 611 ;
-C 164 ; WX 600 ; N fraction ; B 22 -60 707 661 ;
-C 165 ; WX 600 ; N yen ; B 98 0 709 562 ;
-C 166 ; WX 600 ; N florin ; B -56 -131 701 616 ;
-C 167 ; WX 600 ; N section ; B 74 -70 619 580 ;
-C 168 ; WX 600 ; N currency ; B 77 49 643 517 ;
-C 169 ; WX 600 ; N quotesingle ; B 304 277 492 562 ;
-C 170 ; WX 600 ; N quotedblleft ; B 190 277 594 562 ;
-C 171 ; WX 600 ; N guillemotleft ; B 63 70 638 446 ;
-C 172 ; WX 600 ; N guilsinglleft ; B 196 70 544 446 ;
-C 173 ; WX 600 ; N guilsinglright ; B 166 70 514 446 ;
-C 174 ; WX 600 ; N fi ; B 12 0 643 626 ;
-C 175 ; WX 600 ; N fl ; B 12 0 643 626 ;
-C 177 ; WX 600 ; N endash ; B 108 203 602 313 ;
-C 178 ; WX 600 ; N dagger ; B 176 -70 586 580 ;
-C 179 ; WX 600 ; N daggerdbl ; B 122 -70 586 580 ;
-C 180 ; WX 600 ; N periodcentered ; B 249 165 461 351 ;
-C 182 ; WX 600 ; N paragraph ; B 61 -70 699 580 ;
-C 183 ; WX 600 ; N bullet ; B 197 132 523 430 ;
-C 184 ; WX 600 ; N quotesinglbase ; B 145 -142 457 143 ;
-C 185 ; WX 600 ; N quotedblbase ; B 35 -142 559 143 ;
-C 186 ; WX 600 ; N quotedblright ; B 120 277 644 562 ;
-C 187 ; WX 600 ; N guillemotright ; B 72 70 647 446 ;
-C 188 ; WX 600 ; N ellipsis ; B 35 -15 586 116 ;
-C 189 ; WX 600 ; N perthousand ; B -44 -15 742 616 ;
-C 191 ; WX 600 ; N questiondown ; B 101 -146 509 449 ;
-C 193 ; WX 600 ; N grave ; B 272 508 503 661 ;
-C 194 ; WX 600 ; N acute ; B 313 508 608 661 ;
-C 195 ; WX 600 ; N circumflex ; B 212 483 606 657 ;
-C 196 ; WX 600 ; N tilde ; B 200 493 642 636 ;
-C 197 ; WX 600 ; N macron ; B 195 505 636 585 ;
-C 198 ; WX 600 ; N breve ; B 217 468 651 631 ;
-C 199 ; WX 600 ; N dotaccent ; B 346 485 490 625 ;
-C 200 ; WX 600 ; N dieresis ; B 244 485 592 625 ;
-C 202 ; WX 600 ; N ring ; B 319 481 528 678 ;
-C 203 ; WX 600 ; N cedilla ; B 169 -206 367 0 ;
-C 205 ; WX 600 ; N hungarumlaut ; B 172 488 728 661 ;
-C 206 ; WX 600 ; N ogonek ; B 144 -199 350 0 ;
-C 207 ; WX 600 ; N caron ; B 238 493 632 667 ;
-C 208 ; WX 600 ; N emdash ; B 33 203 677 313 ;
-C 225 ; WX 600 ; N AE ; B -29 0 707 562 ;
-C 227 ; WX 600 ; N ordfeminine ; B 189 196 526 580 ;
-C 232 ; WX 600 ; N Lslash ; B 39 0 635 562 ;
-C 233 ; WX 600 ; N Oslash ; B 48 -22 672 584 ;
-C 234 ; WX 600 ; N OE ; B 26 0 700 562 ;
-C 235 ; WX 600 ; N ordmasculine ; B 189 196 542 580 ;
-C 241 ; WX 600 ; N ae ; B 21 -15 651 454 ;
-C 245 ; WX 600 ; N dotlessi ; B 77 0 545 439 ;
-C 248 ; WX 600 ; N lslash ; B 77 0 578 626 ;
-C 249 ; WX 600 ; N oslash ; B 55 -24 637 463 ;
-C 250 ; WX 600 ; N oe ; B 19 -15 661 454 ;
-C 251 ; WX 600 ; N germandbls ; B 22 -15 628 626 ;
-C -1 ; WX 600 ; N Odieresis ; B 74 -18 645 748 ;
-C -1 ; WX 600 ; N logicalnot ; B 135 103 617 413 ;
-C -1 ; WX 600 ; N minus ; B 114 203 596 313 ;
-C -1 ; WX 600 ; N merge ; B 168 -15 533 487 ;
-C -1 ; WX 600 ; N degree ; B 173 243 569 616 ;
-C -1 ; WX 600 ; N dectab ; B 8 0 615 320 ;
-C -1 ; WX 600 ; N ll ; B 1 0 653 626 ;
-C -1 ; WX 600 ; N IJ ; B -8 -18 741 562 ;
-C -1 ; WX 600 ; N Eacute ; B 25 0 669 784 ;
-C -1 ; WX 600 ; N Ocircumflex ; B 74 -18 645 780 ;
-C -1 ; WX 600 ; N ucircumflex ; B 70 -15 591 657 ;
-C -1 ; WX 600 ; N left ; B 109 44 589 371 ;
-C -1 ; WX 600 ; N threesuperior ; B 193 222 525 616 ;
-C -1 ; WX 600 ; N up ; B 196 0 523 447 ;
-C -1 ; WX 600 ; N multiply ; B 105 39 606 478 ;
-C -1 ; WX 600 ; N Scaron ; B 54 -22 672 790 ;
-C -1 ; WX 600 ; N tab ; B 19 0 641 562 ;
-C -1 ; WX 600 ; N Ucircumflex ; B 101 -18 715 780 ;
-C -1 ; WX 600 ; N divide ; B 114 16 596 500 ;
-C -1 ; WX 600 ; N Acircumflex ; B -9 0 631 780 ;
-C -1 ; WX 600 ; N eacute ; B 81 -15 608 661 ;
-C -1 ; WX 600 ; N uacute ; B 70 -15 608 661 ;
-C -1 ; WX 600 ; N Aacute ; B -9 0 665 784 ;
-C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ;
-C -1 ; WX 600 ; N twosuperior ; B 192 230 541 616 ;
-C -1 ; WX 600 ; N Ecircumflex ; B 25 0 669 780 ;
-C -1 ; WX 600 ; N ntilde ; B 18 0 642 636 ;
-C -1 ; WX 600 ; N down ; B 168 -15 496 439 ;
-C -1 ; WX 600 ; N center ; B 103 14 623 580 ;
-C -1 ; WX 600 ; N onesuperior ; B 213 230 514 616 ;
-C -1 ; WX 600 ; N ij ; B 6 -146 714 658 ;
-C -1 ; WX 600 ; N edieresis ; B 81 -15 604 625 ;
-C -1 ; WX 600 ; N graybox ; B 76 0 652 599 ;
-C -1 ; WX 600 ; N odieresis ; B 71 -15 622 625 ;
-C -1 ; WX 600 ; N Ograve ; B 74 -18 645 784 ;
-C -1 ; WX 600 ; N threequarters ; B 8 -60 698 661 ;
-C -1 ; WX 600 ; N plusminus ; B 76 24 614 515 ;
-C -1 ; WX 600 ; N prescription ; B 24 -15 632 562 ;
-C -1 ; WX 600 ; N eth ; B 93 -27 661 626 ;
-C -1 ; WX 600 ; N largebullet ; B 307 229 413 333 ;
-C -1 ; WX 600 ; N egrave ; B 81 -15 604 661 ;
-C -1 ; WX 600 ; N ccedilla ; B 81 -206 631 459 ;
-C -1 ; WX 600 ; N notegraphic ; B 91 -15 619 572 ;
-C -1 ; WX 600 ; N Udieresis ; B 101 -18 715 748 ;
-C -1 ; WX 600 ; N Gcaron ; B 75 -18 674 790 ;
-C -1 ; WX 600 ; N arrowdown ; B 174 -15 486 608 ;
-C -1 ; WX 600 ; N format ; B -26 -146 243 601 ;
-C -1 ; WX 600 ; N Otilde ; B 74 -18 668 759 ;
-C -1 ; WX 600 ; N Idieresis ; B 77 0 642 748 ;
-C -1 ; WX 600 ; N adieresis ; B 62 -15 592 625 ;
-C -1 ; WX 600 ; N ecircumflex ; B 81 -15 606 657 ;
-C -1 ; WX 600 ; N Eth ; B 30 0 664 562 ;
-C -1 ; WX 600 ; N onequarter ; B 14 -60 706 661 ;
-C -1 ; WX 600 ; N LL ; B -45 0 694 562 ;
-C -1 ; WX 600 ; N agrave ; B 62 -15 592 661 ;
-C -1 ; WX 600 ; N Zcaron ; B 62 0 659 790 ;
-C -1 ; WX 600 ; N Scedilla ; B 54 -206 672 582 ;
-C -1 ; WX 600 ; N Idot ; B 77 0 642 748 ;
-C -1 ; WX 600 ; N Iacute ; B 77 0 642 784 ;
-C -1 ; WX 600 ; N indent ; B 99 45 579 372 ;
-C -1 ; WX 600 ; N Ugrave ; B 101 -18 715 784 ;
-C -1 ; WX 600 ; N scaron ; B 67 -17 632 667 ;
-C -1 ; WX 600 ; N overscore ; B 123 579 734 629 ;
-C -1 ; WX 600 ; N Aring ; B -9 0 631 801 ;
-C -1 ; WX 600 ; N Ccedilla ; B 74 -206 674 580 ;
-C -1 ; WX 600 ; N Igrave ; B 77 0 642 784 ;
-C -1 ; WX 600 ; N brokenbar ; B 218 -175 488 675 ;
-C -1 ; WX 600 ; N Oacute ; B 74 -18 645 784 ;
-C -1 ; WX 600 ; N otilde ; B 71 -15 642 636 ;
-C -1 ; WX 600 ; N Yacute ; B 109 0 708 784 ;
-C -1 ; WX 600 ; N lira ; B 107 -28 650 611 ;
-C -1 ; WX 600 ; N Icircumflex ; B 77 0 642 780 ;
-C -1 ; WX 600 ; N Atilde ; B -9 0 638 759 ;
-C -1 ; WX 600 ; N Uacute ; B 101 -18 715 784 ;
-C -1 ; WX 600 ; N Ydieresis ; B 109 0 708 748 ;
-C -1 ; WX 600 ; N ydieresis ; B -20 -142 694 625 ;
-C -1 ; WX 600 ; N idieresis ; B 77 0 552 625 ;
-C -1 ; WX 600 ; N Adieresis ; B -9 0 631 748 ;
-C -1 ; WX 600 ; N mu ; B 50 -142 591 439 ;
-C -1 ; WX 600 ; N trademark ; B 86 230 868 562 ;
-C -1 ; WX 600 ; N oacute ; B 71 -15 622 661 ;
-C -1 ; WX 600 ; N acircumflex ; B 62 -15 592 657 ;
-C -1 ; WX 600 ; N Agrave ; B -9 0 631 784 ;
-C -1 ; WX 600 ; N return ; B 79 0 700 562 ;
-C -1 ; WX 600 ; N atilde ; B 62 -15 642 636 ;
-C -1 ; WX 600 ; N square ; B 19 0 700 562 ;
-C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ;
-C -1 ; WX 600 ; N stop ; B 19 0 700 562 ;
-C -1 ; WX 600 ; N udieresis ; B 70 -15 591 625 ;
-C -1 ; WX 600 ; N arrowup ; B 244 3 556 626 ;
-C -1 ; WX 600 ; N igrave ; B 77 0 545 661 ;
-C -1 ; WX 600 ; N Edieresis ; B 25 0 669 748 ;
-C -1 ; WX 600 ; N zcaron ; B 81 0 632 667 ;
-C -1 ; WX 600 ; N arrowboth ; B 40 143 688 455 ;
-C -1 ; WX 600 ; N gcaron ; B 41 -146 673 667 ;
-C -1 ; WX 600 ; N arrowleft ; B 40 143 708 455 ;
-C -1 ; WX 600 ; N aacute ; B 62 -15 608 661 ;
-C -1 ; WX 600 ; N ocircumflex ; B 71 -15 622 657 ;
-C -1 ; WX 600 ; N scedilla ; B 67 -206 607 459 ;
-C -1 ; WX 600 ; N ograve ; B 71 -15 622 661 ;
-C -1 ; WX 600 ; N onehalf ; B 23 -60 715 661 ;
-C -1 ; WX 600 ; N ugrave ; B 70 -15 591 661 ;
-C -1 ; WX 600 ; N Ntilde ; B 8 -12 729 759 ;
-C -1 ; WX 600 ; N iacute ; B 77 0 608 661 ;
-C -1 ; WX 600 ; N arrowright ; B 20 143 688 455 ;
-C -1 ; WX 600 ; N Thorn ; B 48 0 619 562 ;
-C -1 ; WX 600 ; N Egrave ; B 25 0 669 784 ;
-C -1 ; WX 600 ; N thorn ; B -31 -142 622 626 ;
-C -1 ; WX 600 ; N aring ; B 62 -15 592 678 ;
-C -1 ; WX 600 ; N yacute ; B -20 -142 694 661 ;
-C -1 ; WX 600 ; N icircumflex ; B 77 0 566 657 ;
-EndCharMetrics
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 56 123 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -4 123 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 6 123 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave -24 123 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 16 123 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde -4 123 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 56 123 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 26 123 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 26 123 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 26 123 ;
-CC Gcaron 2 ; PCC G 0 0 ; PCC caron 36 123 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 26 123 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 26 123 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 26 123 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 26 123 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 26 123 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 26 123 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 26 123 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 26 123 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 26 123 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 26 123 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 26 123 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 56 123 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 26 123 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 26 123 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave -4 123 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 56 123 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 26 123 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 26 123 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex -20 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis -10 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave -30 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
-CC gcaron 2 ; PCC g 0 0 ; PCC caron -40 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -40 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -40 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 0 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -20 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis -20 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 30 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 10 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 0 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pcrr8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pcrr8a.afm
deleted file mode 100644
index f60ec9433e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pcrr8a.afm
+++ /dev/null
@@ -1,344 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1989, 1990, 1991 Adobe Systems Incorporated. All rights reserved.
-Comment Creation Date: Tue Sep 17 07:47:21 1991
-Comment UniqueID 36347
-Comment VMusage 31037 39405
-FontName Courier
-FullName Courier
-FamilyName Courier
-Weight Medium
-ItalicAngle 0
-IsFixedPitch true
-FontBBox -28 -250 628 805
-UnderlinePosition -100
-UnderlineThickness 50
-Version 002.004
-Notice Copyright (c) 1989, 1990, 1991 Adobe Systems Incorporated. All rights reserved.
-EncodingScheme AdobeStandardEncoding
-CapHeight 562
-XHeight 426
-Ascender 629
-Descender -157
-StartCharMetrics 260
-C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 600 ; N exclam ; B 236 -15 364 572 ;
-C 34 ; WX 600 ; N quotedbl ; B 187 328 413 562 ;
-C 35 ; WX 600 ; N numbersign ; B 93 -32 507 639 ;
-C 36 ; WX 600 ; N dollar ; B 105 -126 496 662 ;
-C 37 ; WX 600 ; N percent ; B 81 -15 518 622 ;
-C 38 ; WX 600 ; N ampersand ; B 63 -15 538 543 ;
-C 39 ; WX 600 ; N quoteright ; B 213 328 376 562 ;
-C 40 ; WX 600 ; N parenleft ; B 269 -108 440 622 ;
-C 41 ; WX 600 ; N parenright ; B 160 -108 331 622 ;
-C 42 ; WX 600 ; N asterisk ; B 116 257 484 607 ;
-C 43 ; WX 600 ; N plus ; B 80 44 520 470 ;
-C 44 ; WX 600 ; N comma ; B 181 -112 344 122 ;
-C 45 ; WX 600 ; N hyphen ; B 103 231 497 285 ;
-C 46 ; WX 600 ; N period ; B 229 -15 371 109 ;
-C 47 ; WX 600 ; N slash ; B 125 -80 475 629 ;
-C 48 ; WX 600 ; N zero ; B 106 -15 494 622 ;
-C 49 ; WX 600 ; N one ; B 96 0 505 622 ;
-C 50 ; WX 600 ; N two ; B 70 0 471 622 ;
-C 51 ; WX 600 ; N three ; B 75 -15 466 622 ;
-C 52 ; WX 600 ; N four ; B 78 0 500 622 ;
-C 53 ; WX 600 ; N five ; B 92 -15 497 607 ;
-C 54 ; WX 600 ; N six ; B 111 -15 497 622 ;
-C 55 ; WX 600 ; N seven ; B 82 0 483 607 ;
-C 56 ; WX 600 ; N eight ; B 102 -15 498 622 ;
-C 57 ; WX 600 ; N nine ; B 96 -15 489 622 ;
-C 58 ; WX 600 ; N colon ; B 229 -15 371 385 ;
-C 59 ; WX 600 ; N semicolon ; B 181 -112 371 385 ;
-C 60 ; WX 600 ; N less ; B 41 42 519 472 ;
-C 61 ; WX 600 ; N equal ; B 80 138 520 376 ;
-C 62 ; WX 600 ; N greater ; B 66 42 544 472 ;
-C 63 ; WX 600 ; N question ; B 129 -15 492 572 ;
-C 64 ; WX 600 ; N at ; B 77 -15 533 622 ;
-C 65 ; WX 600 ; N A ; B 3 0 597 562 ;
-C 66 ; WX 600 ; N B ; B 43 0 559 562 ;
-C 67 ; WX 600 ; N C ; B 41 -18 540 580 ;
-C 68 ; WX 600 ; N D ; B 43 0 574 562 ;
-C 69 ; WX 600 ; N E ; B 53 0 550 562 ;
-C 70 ; WX 600 ; N F ; B 53 0 545 562 ;
-C 71 ; WX 600 ; N G ; B 31 -18 575 580 ;
-C 72 ; WX 600 ; N H ; B 32 0 568 562 ;
-C 73 ; WX 600 ; N I ; B 96 0 504 562 ;
-C 74 ; WX 600 ; N J ; B 34 -18 566 562 ;
-C 75 ; WX 600 ; N K ; B 38 0 582 562 ;
-C 76 ; WX 600 ; N L ; B 47 0 554 562 ;
-C 77 ; WX 600 ; N M ; B 4 0 596 562 ;
-C 78 ; WX 600 ; N N ; B 7 -13 593 562 ;
-C 79 ; WX 600 ; N O ; B 43 -18 557 580 ;
-C 80 ; WX 600 ; N P ; B 79 0 558 562 ;
-C 81 ; WX 600 ; N Q ; B 43 -138 557 580 ;
-C 82 ; WX 600 ; N R ; B 38 0 588 562 ;
-C 83 ; WX 600 ; N S ; B 72 -20 529 580 ;
-C 84 ; WX 600 ; N T ; B 38 0 563 562 ;
-C 85 ; WX 600 ; N U ; B 17 -18 583 562 ;
-C 86 ; WX 600 ; N V ; B -4 -13 604 562 ;
-C 87 ; WX 600 ; N W ; B -3 -13 603 562 ;
-C 88 ; WX 600 ; N X ; B 23 0 577 562 ;
-C 89 ; WX 600 ; N Y ; B 24 0 576 562 ;
-C 90 ; WX 600 ; N Z ; B 86 0 514 562 ;
-C 91 ; WX 600 ; N bracketleft ; B 269 -108 442 622 ;
-C 92 ; WX 600 ; N backslash ; B 118 -80 482 629 ;
-C 93 ; WX 600 ; N bracketright ; B 158 -108 331 622 ;
-C 94 ; WX 600 ; N asciicircum ; B 94 354 506 622 ;
-C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ;
-C 96 ; WX 600 ; N quoteleft ; B 224 328 387 562 ;
-C 97 ; WX 600 ; N a ; B 53 -15 559 441 ;
-C 98 ; WX 600 ; N b ; B 14 -15 575 629 ;
-C 99 ; WX 600 ; N c ; B 66 -15 529 441 ;
-C 100 ; WX 600 ; N d ; B 45 -15 591 629 ;
-C 101 ; WX 600 ; N e ; B 66 -15 548 441 ;
-C 102 ; WX 600 ; N f ; B 114 0 531 629 ; L i fi ; L l fl ;
-C 103 ; WX 600 ; N g ; B 45 -157 566 441 ;
-C 104 ; WX 600 ; N h ; B 18 0 582 629 ;
-C 105 ; WX 600 ; N i ; B 95 0 505 657 ;
-C 106 ; WX 600 ; N j ; B 82 -157 410 657 ;
-C 107 ; WX 600 ; N k ; B 43 0 580 629 ;
-C 108 ; WX 600 ; N l ; B 95 0 505 629 ;
-C 109 ; WX 600 ; N m ; B -5 0 605 441 ;
-C 110 ; WX 600 ; N n ; B 26 0 575 441 ;
-C 111 ; WX 600 ; N o ; B 62 -15 538 441 ;
-C 112 ; WX 600 ; N p ; B 9 -157 555 441 ;
-C 113 ; WX 600 ; N q ; B 45 -157 591 441 ;
-C 114 ; WX 600 ; N r ; B 60 0 559 441 ;
-C 115 ; WX 600 ; N s ; B 80 -15 513 441 ;
-C 116 ; WX 600 ; N t ; B 87 -15 530 561 ;
-C 117 ; WX 600 ; N u ; B 21 -15 562 426 ;
-C 118 ; WX 600 ; N v ; B 10 -10 590 426 ;
-C 119 ; WX 600 ; N w ; B -4 -10 604 426 ;
-C 120 ; WX 600 ; N x ; B 20 0 580 426 ;
-C 121 ; WX 600 ; N y ; B 7 -157 592 426 ;
-C 122 ; WX 600 ; N z ; B 99 0 502 426 ;
-C 123 ; WX 600 ; N braceleft ; B 182 -108 437 622 ;
-C 124 ; WX 600 ; N bar ; B 275 -250 326 750 ;
-C 125 ; WX 600 ; N braceright ; B 163 -108 418 622 ;
-C 126 ; WX 600 ; N asciitilde ; B 63 197 540 320 ;
-C 161 ; WX 600 ; N exclamdown ; B 236 -157 364 430 ;
-C 162 ; WX 600 ; N cent ; B 96 -49 500 614 ;
-C 163 ; WX 600 ; N sterling ; B 84 -21 521 611 ;
-C 164 ; WX 600 ; N fraction ; B 92 -57 509 665 ;
-C 165 ; WX 600 ; N yen ; B 26 0 574 562 ;
-C 166 ; WX 600 ; N florin ; B 4 -143 539 622 ;
-C 167 ; WX 600 ; N section ; B 113 -78 488 580 ;
-C 168 ; WX 600 ; N currency ; B 73 58 527 506 ;
-C 169 ; WX 600 ; N quotesingle ; B 259 328 341 562 ;
-C 170 ; WX 600 ; N quotedblleft ; B 143 328 471 562 ;
-C 171 ; WX 600 ; N guillemotleft ; B 37 70 563 446 ;
-C 172 ; WX 600 ; N guilsinglleft ; B 149 70 451 446 ;
-C 173 ; WX 600 ; N guilsinglright ; B 149 70 451 446 ;
-C 174 ; WX 600 ; N fi ; B 3 0 597 629 ;
-C 175 ; WX 600 ; N fl ; B 3 0 597 629 ;
-C 177 ; WX 600 ; N endash ; B 75 231 525 285 ;
-C 178 ; WX 600 ; N dagger ; B 141 -78 459 580 ;
-C 179 ; WX 600 ; N daggerdbl ; B 141 -78 459 580 ;
-C 180 ; WX 600 ; N periodcentered ; B 222 189 378 327 ;
-C 182 ; WX 600 ; N paragraph ; B 50 -78 511 562 ;
-C 183 ; WX 600 ; N bullet ; B 172 130 428 383 ;
-C 184 ; WX 600 ; N quotesinglbase ; B 213 -134 376 100 ;
-C 185 ; WX 600 ; N quotedblbase ; B 143 -134 457 100 ;
-C 186 ; WX 600 ; N quotedblright ; B 143 328 457 562 ;
-C 187 ; WX 600 ; N guillemotright ; B 37 70 563 446 ;
-C 188 ; WX 600 ; N ellipsis ; B 37 -15 563 111 ;
-C 189 ; WX 600 ; N perthousand ; B 3 -15 600 622 ;
-C 191 ; WX 600 ; N questiondown ; B 108 -157 471 430 ;
-C 193 ; WX 600 ; N grave ; B 151 497 378 672 ;
-C 194 ; WX 600 ; N acute ; B 242 497 469 672 ;
-C 195 ; WX 600 ; N circumflex ; B 124 477 476 654 ;
-C 196 ; WX 600 ; N tilde ; B 105 489 503 606 ;
-C 197 ; WX 600 ; N macron ; B 120 525 480 565 ;
-C 198 ; WX 600 ; N breve ; B 153 501 447 609 ;
-C 199 ; WX 600 ; N dotaccent ; B 249 477 352 580 ;
-C 200 ; WX 600 ; N dieresis ; B 148 492 453 595 ;
-C 202 ; WX 600 ; N ring ; B 218 463 382 627 ;
-C 203 ; WX 600 ; N cedilla ; B 224 -151 362 10 ;
-C 205 ; WX 600 ; N hungarumlaut ; B 133 497 540 672 ;
-C 206 ; WX 600 ; N ogonek ; B 227 -151 370 0 ;
-C 207 ; WX 600 ; N caron ; B 124 492 476 669 ;
-C 208 ; WX 600 ; N emdash ; B 0 231 600 285 ;
-C 225 ; WX 600 ; N AE ; B 3 0 550 562 ;
-C 227 ; WX 600 ; N ordfeminine ; B 156 249 442 580 ;
-C 232 ; WX 600 ; N Lslash ; B 47 0 554 562 ;
-C 233 ; WX 600 ; N Oslash ; B 43 -80 557 629 ;
-C 234 ; WX 600 ; N OE ; B 7 0 567 562 ;
-C 235 ; WX 600 ; N ordmasculine ; B 157 249 443 580 ;
-C 241 ; WX 600 ; N ae ; B 19 -15 570 441 ;
-C 245 ; WX 600 ; N dotlessi ; B 95 0 505 426 ;
-C 248 ; WX 600 ; N lslash ; B 95 0 505 629 ;
-C 249 ; WX 600 ; N oslash ; B 62 -80 538 506 ;
-C 250 ; WX 600 ; N oe ; B 19 -15 559 441 ;
-C 251 ; WX 600 ; N germandbls ; B 48 -15 588 629 ;
-C -1 ; WX 600 ; N Odieresis ; B 43 -18 557 731 ;
-C -1 ; WX 600 ; N logicalnot ; B 87 108 513 369 ;
-C -1 ; WX 600 ; N minus ; B 80 232 520 283 ;
-C -1 ; WX 600 ; N merge ; B 160 -15 440 436 ;
-C -1 ; WX 600 ; N degree ; B 123 269 477 622 ;
-C -1 ; WX 600 ; N dectab ; B 18 0 582 227 ;
-C -1 ; WX 600 ; N ll ; B 18 0 567 629 ;
-C -1 ; WX 600 ; N IJ ; B 32 -18 583 562 ;
-C -1 ; WX 600 ; N Eacute ; B 53 0 550 793 ;
-C -1 ; WX 600 ; N Ocircumflex ; B 43 -18 557 775 ;
-C -1 ; WX 600 ; N ucircumflex ; B 21 -15 562 654 ;
-C -1 ; WX 600 ; N left ; B 70 68 530 348 ;
-C -1 ; WX 600 ; N threesuperior ; B 155 240 406 622 ;
-C -1 ; WX 600 ; N up ; B 160 0 440 437 ;
-C -1 ; WX 600 ; N multiply ; B 87 43 515 470 ;
-C -1 ; WX 600 ; N Scaron ; B 72 -20 529 805 ;
-C -1 ; WX 600 ; N tab ; B 19 0 581 562 ;
-C -1 ; WX 600 ; N Ucircumflex ; B 17 -18 583 775 ;
-C -1 ; WX 600 ; N divide ; B 87 48 513 467 ;
-C -1 ; WX 600 ; N Acircumflex ; B 3 0 597 775 ;
-C -1 ; WX 600 ; N eacute ; B 66 -15 548 672 ;
-C -1 ; WX 600 ; N uacute ; B 21 -15 562 672 ;
-C -1 ; WX 600 ; N Aacute ; B 3 0 597 793 ;
-C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ;
-C -1 ; WX 600 ; N twosuperior ; B 177 249 424 622 ;
-C -1 ; WX 600 ; N Ecircumflex ; B 53 0 550 775 ;
-C -1 ; WX 600 ; N ntilde ; B 26 0 575 606 ;
-C -1 ; WX 600 ; N down ; B 160 -15 440 426 ;
-C -1 ; WX 600 ; N center ; B 40 14 560 580 ;
-C -1 ; WX 600 ; N onesuperior ; B 172 249 428 622 ;
-C -1 ; WX 600 ; N ij ; B 37 -157 490 657 ;
-C -1 ; WX 600 ; N edieresis ; B 66 -15 548 595 ;
-C -1 ; WX 600 ; N graybox ; B 76 0 525 599 ;
-C -1 ; WX 600 ; N odieresis ; B 62 -15 538 595 ;
-C -1 ; WX 600 ; N Ograve ; B 43 -18 557 793 ;
-C -1 ; WX 600 ; N threequarters ; B 8 -56 593 666 ;
-C -1 ; WX 600 ; N plusminus ; B 87 44 513 558 ;
-C -1 ; WX 600 ; N prescription ; B 27 -15 577 562 ;
-C -1 ; WX 600 ; N eth ; B 62 -15 538 629 ;
-C -1 ; WX 600 ; N largebullet ; B 261 220 339 297 ;
-C -1 ; WX 600 ; N egrave ; B 66 -15 548 672 ;
-C -1 ; WX 600 ; N ccedilla ; B 66 -151 529 441 ;
-C -1 ; WX 600 ; N notegraphic ; B 136 -15 464 572 ;
-C -1 ; WX 600 ; N Udieresis ; B 17 -18 583 731 ;
-C -1 ; WX 600 ; N Gcaron ; B 31 -18 575 805 ;
-C -1 ; WX 600 ; N arrowdown ; B 116 -15 484 608 ;
-C -1 ; WX 600 ; N format ; B 5 -157 56 607 ;
-C -1 ; WX 600 ; N Otilde ; B 43 -18 557 732 ;
-C -1 ; WX 600 ; N Idieresis ; B 96 0 504 731 ;
-C -1 ; WX 600 ; N adieresis ; B 53 -15 559 595 ;
-C -1 ; WX 600 ; N ecircumflex ; B 66 -15 548 654 ;
-C -1 ; WX 600 ; N Eth ; B 30 0 574 562 ;
-C -1 ; WX 600 ; N onequarter ; B 0 -57 600 665 ;
-C -1 ; WX 600 ; N LL ; B 8 0 592 562 ;
-C -1 ; WX 600 ; N agrave ; B 53 -15 559 672 ;
-C -1 ; WX 600 ; N Zcaron ; B 86 0 514 805 ;
-C -1 ; WX 600 ; N Scedilla ; B 72 -151 529 580 ;
-C -1 ; WX 600 ; N Idot ; B 96 0 504 716 ;
-C -1 ; WX 600 ; N Iacute ; B 96 0 504 793 ;
-C -1 ; WX 600 ; N indent ; B 70 68 530 348 ;
-C -1 ; WX 600 ; N Ugrave ; B 17 -18 583 793 ;
-C -1 ; WX 600 ; N scaron ; B 80 -15 513 669 ;
-C -1 ; WX 600 ; N overscore ; B 0 579 600 629 ;
-C -1 ; WX 600 ; N Aring ; B 3 0 597 753 ;
-C -1 ; WX 600 ; N Ccedilla ; B 41 -151 540 580 ;
-C -1 ; WX 600 ; N Igrave ; B 96 0 504 793 ;
-C -1 ; WX 600 ; N brokenbar ; B 275 -175 326 675 ;
-C -1 ; WX 600 ; N Oacute ; B 43 -18 557 793 ;
-C -1 ; WX 600 ; N otilde ; B 62 -15 538 606 ;
-C -1 ; WX 600 ; N Yacute ; B 24 0 576 793 ;
-C -1 ; WX 600 ; N lira ; B 73 -21 521 611 ;
-C -1 ; WX 600 ; N Icircumflex ; B 96 0 504 775 ;
-C -1 ; WX 600 ; N Atilde ; B 3 0 597 732 ;
-C -1 ; WX 600 ; N Uacute ; B 17 -18 583 793 ;
-C -1 ; WX 600 ; N Ydieresis ; B 24 0 576 731 ;
-C -1 ; WX 600 ; N ydieresis ; B 7 -157 592 595 ;
-C -1 ; WX 600 ; N idieresis ; B 95 0 505 595 ;
-C -1 ; WX 600 ; N Adieresis ; B 3 0 597 731 ;
-C -1 ; WX 600 ; N mu ; B 21 -157 562 426 ;
-C -1 ; WX 600 ; N trademark ; B -23 263 623 562 ;
-C -1 ; WX 600 ; N oacute ; B 62 -15 538 672 ;
-C -1 ; WX 600 ; N acircumflex ; B 53 -15 559 654 ;
-C -1 ; WX 600 ; N Agrave ; B 3 0 597 793 ;
-C -1 ; WX 600 ; N return ; B 19 0 581 562 ;
-C -1 ; WX 600 ; N atilde ; B 53 -15 559 606 ;
-C -1 ; WX 600 ; N square ; B 19 0 581 562 ;
-C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ;
-C -1 ; WX 600 ; N stop ; B 19 0 581 562 ;
-C -1 ; WX 600 ; N udieresis ; B 21 -15 562 595 ;
-C -1 ; WX 600 ; N arrowup ; B 116 0 484 623 ;
-C -1 ; WX 600 ; N igrave ; B 95 0 505 672 ;
-C -1 ; WX 600 ; N Edieresis ; B 53 0 550 731 ;
-C -1 ; WX 600 ; N zcaron ; B 99 0 502 669 ;
-C -1 ; WX 600 ; N arrowboth ; B -28 115 628 483 ;
-C -1 ; WX 600 ; N gcaron ; B 45 -157 566 669 ;
-C -1 ; WX 600 ; N arrowleft ; B -24 115 624 483 ;
-C -1 ; WX 600 ; N aacute ; B 53 -15 559 672 ;
-C -1 ; WX 600 ; N ocircumflex ; B 62 -15 538 654 ;
-C -1 ; WX 600 ; N scedilla ; B 80 -151 513 441 ;
-C -1 ; WX 600 ; N ograve ; B 62 -15 538 672 ;
-C -1 ; WX 600 ; N onehalf ; B 0 -57 611 665 ;
-C -1 ; WX 600 ; N ugrave ; B 21 -15 562 672 ;
-C -1 ; WX 600 ; N Ntilde ; B 7 -13 593 732 ;
-C -1 ; WX 600 ; N iacute ; B 95 0 505 672 ;
-C -1 ; WX 600 ; N arrowright ; B -24 115 624 483 ;
-C -1 ; WX 600 ; N Thorn ; B 79 0 538 562 ;
-C -1 ; WX 600 ; N Egrave ; B 53 0 550 793 ;
-C -1 ; WX 600 ; N thorn ; B -6 -157 555 629 ;
-C -1 ; WX 600 ; N aring ; B 53 -15 559 627 ;
-C -1 ; WX 600 ; N yacute ; B 7 -157 592 672 ;
-C -1 ; WX 600 ; N icircumflex ; B 94 0 505 654 ;
-EndCharMetrics
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 20 121 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -30 121 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis -30 136 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave -30 121 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring -15 126 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 0 126 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 30 121 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 0 121 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 0 136 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 0 121 ;
-CC Gcaron 2 ; PCC G 0 0 ; PCC caron 0 136 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 121 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 121 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 136 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 121 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 0 126 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 0 121 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 0 121 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 0 136 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 0 121 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 0 126 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 30 136 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 30 121 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 0 121 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 0 136 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave -30 121 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 30 121 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 0 136 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 0 136 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
-CC gcaron 2 ; PCC g 0 0 ; PCC caron -30 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -30 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -30 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -30 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute -10 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -10 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute -20 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis -10 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 10 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pcrro8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pcrro8a.afm
deleted file mode 100644
index b053a4ca2d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pcrro8a.afm
+++ /dev/null
@@ -1,344 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1989, 1990, 1991 Adobe Systems Incorporated. All rights reserved.
-Comment Creation Date: Tue Sep 17 09:42:19 1991
-Comment UniqueID 36350
-Comment VMusage 9174 52297
-FontName Courier-Oblique
-FullName Courier Oblique
-FamilyName Courier
-Weight Medium
-ItalicAngle -12
-IsFixedPitch true
-FontBBox -28 -250 742 805
-UnderlinePosition -100
-UnderlineThickness 50
-Version 002.004
-Notice Copyright (c) 1989, 1990, 1991 Adobe Systems Incorporated. All rights reserved.
-EncodingScheme AdobeStandardEncoding
-CapHeight 562
-XHeight 426
-Ascender 629
-Descender -157
-StartCharMetrics 260
-C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 600 ; N exclam ; B 243 -15 464 572 ;
-C 34 ; WX 600 ; N quotedbl ; B 273 328 532 562 ;
-C 35 ; WX 600 ; N numbersign ; B 133 -32 596 639 ;
-C 36 ; WX 600 ; N dollar ; B 108 -126 596 662 ;
-C 37 ; WX 600 ; N percent ; B 134 -15 599 622 ;
-C 38 ; WX 600 ; N ampersand ; B 87 -15 580 543 ;
-C 39 ; WX 600 ; N quoteright ; B 283 328 495 562 ;
-C 40 ; WX 600 ; N parenleft ; B 313 -108 572 622 ;
-C 41 ; WX 600 ; N parenright ; B 137 -108 396 622 ;
-C 42 ; WX 600 ; N asterisk ; B 212 257 580 607 ;
-C 43 ; WX 600 ; N plus ; B 129 44 580 470 ;
-C 44 ; WX 600 ; N comma ; B 157 -112 370 122 ;
-C 45 ; WX 600 ; N hyphen ; B 152 231 558 285 ;
-C 46 ; WX 600 ; N period ; B 238 -15 382 109 ;
-C 47 ; WX 600 ; N slash ; B 112 -80 604 629 ;
-C 48 ; WX 600 ; N zero ; B 154 -15 575 622 ;
-C 49 ; WX 600 ; N one ; B 98 0 515 622 ;
-C 50 ; WX 600 ; N two ; B 70 0 568 622 ;
-C 51 ; WX 600 ; N three ; B 82 -15 538 622 ;
-C 52 ; WX 600 ; N four ; B 108 0 541 622 ;
-C 53 ; WX 600 ; N five ; B 99 -15 589 607 ;
-C 54 ; WX 600 ; N six ; B 155 -15 629 622 ;
-C 55 ; WX 600 ; N seven ; B 182 0 612 607 ;
-C 56 ; WX 600 ; N eight ; B 132 -15 588 622 ;
-C 57 ; WX 600 ; N nine ; B 93 -15 574 622 ;
-C 58 ; WX 600 ; N colon ; B 238 -15 441 385 ;
-C 59 ; WX 600 ; N semicolon ; B 157 -112 441 385 ;
-C 60 ; WX 600 ; N less ; B 96 42 610 472 ;
-C 61 ; WX 600 ; N equal ; B 109 138 600 376 ;
-C 62 ; WX 600 ; N greater ; B 85 42 599 472 ;
-C 63 ; WX 600 ; N question ; B 222 -15 583 572 ;
-C 64 ; WX 600 ; N at ; B 127 -15 582 622 ;
-C 65 ; WX 600 ; N A ; B 3 0 607 562 ;
-C 66 ; WX 600 ; N B ; B 43 0 616 562 ;
-C 67 ; WX 600 ; N C ; B 93 -18 655 580 ;
-C 68 ; WX 600 ; N D ; B 43 0 645 562 ;
-C 69 ; WX 600 ; N E ; B 53 0 660 562 ;
-C 70 ; WX 600 ; N F ; B 53 0 660 562 ;
-C 71 ; WX 600 ; N G ; B 83 -18 645 580 ;
-C 72 ; WX 600 ; N H ; B 32 0 687 562 ;
-C 73 ; WX 600 ; N I ; B 96 0 623 562 ;
-C 74 ; WX 600 ; N J ; B 52 -18 685 562 ;
-C 75 ; WX 600 ; N K ; B 38 0 671 562 ;
-C 76 ; WX 600 ; N L ; B 47 0 607 562 ;
-C 77 ; WX 600 ; N M ; B 4 0 715 562 ;
-C 78 ; WX 600 ; N N ; B 7 -13 712 562 ;
-C 79 ; WX 600 ; N O ; B 94 -18 625 580 ;
-C 80 ; WX 600 ; N P ; B 79 0 644 562 ;
-C 81 ; WX 600 ; N Q ; B 95 -138 625 580 ;
-C 82 ; WX 600 ; N R ; B 38 0 598 562 ;
-C 83 ; WX 600 ; N S ; B 76 -20 650 580 ;
-C 84 ; WX 600 ; N T ; B 108 0 665 562 ;
-C 85 ; WX 600 ; N U ; B 125 -18 702 562 ;
-C 86 ; WX 600 ; N V ; B 105 -13 723 562 ;
-C 87 ; WX 600 ; N W ; B 106 -13 722 562 ;
-C 88 ; WX 600 ; N X ; B 23 0 675 562 ;
-C 89 ; WX 600 ; N Y ; B 133 0 695 562 ;
-C 90 ; WX 600 ; N Z ; B 86 0 610 562 ;
-C 91 ; WX 600 ; N bracketleft ; B 246 -108 574 622 ;
-C 92 ; WX 600 ; N backslash ; B 249 -80 468 629 ;
-C 93 ; WX 600 ; N bracketright ; B 135 -108 463 622 ;
-C 94 ; WX 600 ; N asciicircum ; B 175 354 587 622 ;
-C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ;
-C 96 ; WX 600 ; N quoteleft ; B 343 328 457 562 ;
-C 97 ; WX 600 ; N a ; B 76 -15 569 441 ;
-C 98 ; WX 600 ; N b ; B 29 -15 625 629 ;
-C 99 ; WX 600 ; N c ; B 106 -15 608 441 ;
-C 100 ; WX 600 ; N d ; B 85 -15 640 629 ;
-C 101 ; WX 600 ; N e ; B 106 -15 598 441 ;
-C 102 ; WX 600 ; N f ; B 114 0 662 629 ; L i fi ; L l fl ;
-C 103 ; WX 600 ; N g ; B 61 -157 657 441 ;
-C 104 ; WX 600 ; N h ; B 33 0 592 629 ;
-C 105 ; WX 600 ; N i ; B 95 0 515 657 ;
-C 106 ; WX 600 ; N j ; B 52 -157 550 657 ;
-C 107 ; WX 600 ; N k ; B 58 0 633 629 ;
-C 108 ; WX 600 ; N l ; B 95 0 515 629 ;
-C 109 ; WX 600 ; N m ; B -5 0 615 441 ;
-C 110 ; WX 600 ; N n ; B 26 0 585 441 ;
-C 111 ; WX 600 ; N o ; B 102 -15 588 441 ;
-C 112 ; WX 600 ; N p ; B -24 -157 605 441 ;
-C 113 ; WX 600 ; N q ; B 85 -157 682 441 ;
-C 114 ; WX 600 ; N r ; B 60 0 636 441 ;
-C 115 ; WX 600 ; N s ; B 78 -15 584 441 ;
-C 116 ; WX 600 ; N t ; B 167 -15 561 561 ;
-C 117 ; WX 600 ; N u ; B 101 -15 572 426 ;
-C 118 ; WX 600 ; N v ; B 90 -10 681 426 ;
-C 119 ; WX 600 ; N w ; B 76 -10 695 426 ;
-C 120 ; WX 600 ; N x ; B 20 0 655 426 ;
-C 121 ; WX 600 ; N y ; B -4 -157 683 426 ;
-C 122 ; WX 600 ; N z ; B 99 0 593 426 ;
-C 123 ; WX 600 ; N braceleft ; B 233 -108 569 622 ;
-C 124 ; WX 600 ; N bar ; B 222 -250 485 750 ;
-C 125 ; WX 600 ; N braceright ; B 140 -108 477 622 ;
-C 126 ; WX 600 ; N asciitilde ; B 116 197 600 320 ;
-C 161 ; WX 600 ; N exclamdown ; B 225 -157 445 430 ;
-C 162 ; WX 600 ; N cent ; B 151 -49 588 614 ;
-C 163 ; WX 600 ; N sterling ; B 124 -21 621 611 ;
-C 164 ; WX 600 ; N fraction ; B 84 -57 646 665 ;
-C 165 ; WX 600 ; N yen ; B 120 0 693 562 ;
-C 166 ; WX 600 ; N florin ; B -26 -143 671 622 ;
-C 167 ; WX 600 ; N section ; B 104 -78 590 580 ;
-C 168 ; WX 600 ; N currency ; B 94 58 628 506 ;
-C 169 ; WX 600 ; N quotesingle ; B 345 328 460 562 ;
-C 170 ; WX 600 ; N quotedblleft ; B 262 328 541 562 ;
-C 171 ; WX 600 ; N guillemotleft ; B 92 70 652 446 ;
-C 172 ; WX 600 ; N guilsinglleft ; B 204 70 540 446 ;
-C 173 ; WX 600 ; N guilsinglright ; B 170 70 506 446 ;
-C 174 ; WX 600 ; N fi ; B 3 0 619 629 ;
-C 175 ; WX 600 ; N fl ; B 3 0 619 629 ;
-C 177 ; WX 600 ; N endash ; B 124 231 586 285 ;
-C 178 ; WX 600 ; N dagger ; B 217 -78 546 580 ;
-C 179 ; WX 600 ; N daggerdbl ; B 163 -78 546 580 ;
-C 180 ; WX 600 ; N periodcentered ; B 275 189 434 327 ;
-C 182 ; WX 600 ; N paragraph ; B 100 -78 630 562 ;
-C 183 ; WX 600 ; N bullet ; B 224 130 485 383 ;
-C 184 ; WX 600 ; N quotesinglbase ; B 185 -134 397 100 ;
-C 185 ; WX 600 ; N quotedblbase ; B 115 -134 478 100 ;
-C 186 ; WX 600 ; N quotedblright ; B 213 328 576 562 ;
-C 187 ; WX 600 ; N guillemotright ; B 58 70 618 446 ;
-C 188 ; WX 600 ; N ellipsis ; B 46 -15 575 111 ;
-C 189 ; WX 600 ; N perthousand ; B 59 -15 627 622 ;
-C 191 ; WX 600 ; N questiondown ; B 105 -157 466 430 ;
-C 193 ; WX 600 ; N grave ; B 294 497 484 672 ;
-C 194 ; WX 600 ; N acute ; B 348 497 612 672 ;
-C 195 ; WX 600 ; N circumflex ; B 229 477 581 654 ;
-C 196 ; WX 600 ; N tilde ; B 212 489 629 606 ;
-C 197 ; WX 600 ; N macron ; B 232 525 600 565 ;
-C 198 ; WX 600 ; N breve ; B 279 501 576 609 ;
-C 199 ; WX 600 ; N dotaccent ; B 360 477 466 580 ;
-C 200 ; WX 600 ; N dieresis ; B 262 492 570 595 ;
-C 202 ; WX 600 ; N ring ; B 332 463 500 627 ;
-C 203 ; WX 600 ; N cedilla ; B 197 -151 344 10 ;
-C 205 ; WX 600 ; N hungarumlaut ; B 239 497 683 672 ;
-C 206 ; WX 600 ; N ogonek ; B 207 -151 348 0 ;
-C 207 ; WX 600 ; N caron ; B 262 492 614 669 ;
-C 208 ; WX 600 ; N emdash ; B 49 231 661 285 ;
-C 225 ; WX 600 ; N AE ; B 3 0 655 562 ;
-C 227 ; WX 600 ; N ordfeminine ; B 209 249 512 580 ;
-C 232 ; WX 600 ; N Lslash ; B 47 0 607 562 ;
-C 233 ; WX 600 ; N Oslash ; B 94 -80 625 629 ;
-C 234 ; WX 600 ; N OE ; B 59 0 672 562 ;
-C 235 ; WX 600 ; N ordmasculine ; B 210 249 535 580 ;
-C 241 ; WX 600 ; N ae ; B 41 -15 626 441 ;
-C 245 ; WX 600 ; N dotlessi ; B 95 0 515 426 ;
-C 248 ; WX 600 ; N lslash ; B 95 0 583 629 ;
-C 249 ; WX 600 ; N oslash ; B 102 -80 588 506 ;
-C 250 ; WX 600 ; N oe ; B 54 -15 615 441 ;
-C 251 ; WX 600 ; N germandbls ; B 48 -15 617 629 ;
-C -1 ; WX 600 ; N Odieresis ; B 94 -18 625 731 ;
-C -1 ; WX 600 ; N logicalnot ; B 155 108 591 369 ;
-C -1 ; WX 600 ; N minus ; B 129 232 580 283 ;
-C -1 ; WX 600 ; N merge ; B 187 -15 503 436 ;
-C -1 ; WX 600 ; N degree ; B 214 269 576 622 ;
-C -1 ; WX 600 ; N dectab ; B 18 0 593 227 ;
-C -1 ; WX 600 ; N ll ; B 33 0 616 629 ;
-C -1 ; WX 600 ; N IJ ; B 32 -18 702 562 ;
-C -1 ; WX 600 ; N Eacute ; B 53 0 668 793 ;
-C -1 ; WX 600 ; N Ocircumflex ; B 94 -18 625 775 ;
-C -1 ; WX 600 ; N ucircumflex ; B 101 -15 572 654 ;
-C -1 ; WX 600 ; N left ; B 114 68 580 348 ;
-C -1 ; WX 600 ; N threesuperior ; B 213 240 501 622 ;
-C -1 ; WX 600 ; N up ; B 223 0 503 437 ;
-C -1 ; WX 600 ; N multiply ; B 103 43 607 470 ;
-C -1 ; WX 600 ; N Scaron ; B 76 -20 673 805 ;
-C -1 ; WX 600 ; N tab ; B 19 0 641 562 ;
-C -1 ; WX 600 ; N Ucircumflex ; B 125 -18 702 775 ;
-C -1 ; WX 600 ; N divide ; B 136 48 573 467 ;
-C -1 ; WX 600 ; N Acircumflex ; B 3 0 607 775 ;
-C -1 ; WX 600 ; N eacute ; B 106 -15 612 672 ;
-C -1 ; WX 600 ; N uacute ; B 101 -15 602 672 ;
-C -1 ; WX 600 ; N Aacute ; B 3 0 658 793 ;
-C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ;
-C -1 ; WX 600 ; N twosuperior ; B 230 249 535 622 ;
-C -1 ; WX 600 ; N Ecircumflex ; B 53 0 660 775 ;
-C -1 ; WX 600 ; N ntilde ; B 26 0 629 606 ;
-C -1 ; WX 600 ; N down ; B 187 -15 467 426 ;
-C -1 ; WX 600 ; N center ; B 103 14 623 580 ;
-C -1 ; WX 600 ; N onesuperior ; B 231 249 491 622 ;
-C -1 ; WX 600 ; N ij ; B 37 -157 630 657 ;
-C -1 ; WX 600 ; N edieresis ; B 106 -15 598 595 ;
-C -1 ; WX 600 ; N graybox ; B 76 0 652 599 ;
-C -1 ; WX 600 ; N odieresis ; B 102 -15 588 595 ;
-C -1 ; WX 600 ; N Ograve ; B 94 -18 625 793 ;
-C -1 ; WX 600 ; N threequarters ; B 73 -56 659 666 ;
-C -1 ; WX 600 ; N plusminus ; B 96 44 594 558 ;
-C -1 ; WX 600 ; N prescription ; B 27 -15 617 562 ;
-C -1 ; WX 600 ; N eth ; B 102 -15 639 629 ;
-C -1 ; WX 600 ; N largebullet ; B 315 220 395 297 ;
-C -1 ; WX 600 ; N egrave ; B 106 -15 598 672 ;
-C -1 ; WX 600 ; N ccedilla ; B 106 -151 614 441 ;
-C -1 ; WX 600 ; N notegraphic ; B 143 -15 564 572 ;
-C -1 ; WX 600 ; N Udieresis ; B 125 -18 702 731 ;
-C -1 ; WX 600 ; N Gcaron ; B 83 -18 645 805 ;
-C -1 ; WX 600 ; N arrowdown ; B 152 -15 520 608 ;
-C -1 ; WX 600 ; N format ; B -28 -157 185 607 ;
-C -1 ; WX 600 ; N Otilde ; B 94 -18 656 732 ;
-C -1 ; WX 600 ; N Idieresis ; B 96 0 623 731 ;
-C -1 ; WX 600 ; N adieresis ; B 76 -15 570 595 ;
-C -1 ; WX 600 ; N ecircumflex ; B 106 -15 598 654 ;
-C -1 ; WX 600 ; N Eth ; B 43 0 645 562 ;
-C -1 ; WX 600 ; N onequarter ; B 65 -57 674 665 ;
-C -1 ; WX 600 ; N LL ; B 8 0 647 562 ;
-C -1 ; WX 600 ; N agrave ; B 76 -15 569 672 ;
-C -1 ; WX 600 ; N Zcaron ; B 86 0 643 805 ;
-C -1 ; WX 600 ; N Scedilla ; B 76 -151 650 580 ;
-C -1 ; WX 600 ; N Idot ; B 96 0 623 716 ;
-C -1 ; WX 600 ; N Iacute ; B 96 0 638 793 ;
-C -1 ; WX 600 ; N indent ; B 108 68 574 348 ;
-C -1 ; WX 600 ; N Ugrave ; B 125 -18 702 793 ;
-C -1 ; WX 600 ; N scaron ; B 78 -15 614 669 ;
-C -1 ; WX 600 ; N overscore ; B 123 579 734 629 ;
-C -1 ; WX 600 ; N Aring ; B 3 0 607 753 ;
-C -1 ; WX 600 ; N Ccedilla ; B 93 -151 658 580 ;
-C -1 ; WX 600 ; N Igrave ; B 96 0 623 793 ;
-C -1 ; WX 600 ; N brokenbar ; B 238 -175 469 675 ;
-C -1 ; WX 600 ; N Oacute ; B 94 -18 638 793 ;
-C -1 ; WX 600 ; N otilde ; B 102 -15 629 606 ;
-C -1 ; WX 600 ; N Yacute ; B 133 0 695 793 ;
-C -1 ; WX 600 ; N lira ; B 118 -21 621 611 ;
-C -1 ; WX 600 ; N Icircumflex ; B 96 0 623 775 ;
-C -1 ; WX 600 ; N Atilde ; B 3 0 656 732 ;
-C -1 ; WX 600 ; N Uacute ; B 125 -18 702 793 ;
-C -1 ; WX 600 ; N Ydieresis ; B 133 0 695 731 ;
-C -1 ; WX 600 ; N ydieresis ; B -4 -157 683 595 ;
-C -1 ; WX 600 ; N idieresis ; B 95 0 540 595 ;
-C -1 ; WX 600 ; N Adieresis ; B 3 0 607 731 ;
-C -1 ; WX 600 ; N mu ; B 72 -157 572 426 ;
-C -1 ; WX 600 ; N trademark ; B 75 263 742 562 ;
-C -1 ; WX 600 ; N oacute ; B 102 -15 612 672 ;
-C -1 ; WX 600 ; N acircumflex ; B 76 -15 581 654 ;
-C -1 ; WX 600 ; N Agrave ; B 3 0 607 793 ;
-C -1 ; WX 600 ; N return ; B 79 0 700 562 ;
-C -1 ; WX 600 ; N atilde ; B 76 -15 629 606 ;
-C -1 ; WX 600 ; N square ; B 19 0 700 562 ;
-C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ;
-C -1 ; WX 600 ; N stop ; B 19 0 700 562 ;
-C -1 ; WX 600 ; N udieresis ; B 101 -15 572 595 ;
-C -1 ; WX 600 ; N arrowup ; B 209 0 577 623 ;
-C -1 ; WX 600 ; N igrave ; B 95 0 515 672 ;
-C -1 ; WX 600 ; N Edieresis ; B 53 0 660 731 ;
-C -1 ; WX 600 ; N zcaron ; B 99 0 624 669 ;
-C -1 ; WX 600 ; N arrowboth ; B 36 115 692 483 ;
-C -1 ; WX 600 ; N gcaron ; B 61 -157 657 669 ;
-C -1 ; WX 600 ; N arrowleft ; B 40 115 693 483 ;
-C -1 ; WX 600 ; N aacute ; B 76 -15 612 672 ;
-C -1 ; WX 600 ; N ocircumflex ; B 102 -15 588 654 ;
-C -1 ; WX 600 ; N scedilla ; B 78 -151 584 441 ;
-C -1 ; WX 600 ; N ograve ; B 102 -15 588 672 ;
-C -1 ; WX 600 ; N onehalf ; B 65 -57 669 665 ;
-C -1 ; WX 600 ; N ugrave ; B 101 -15 572 672 ;
-C -1 ; WX 600 ; N Ntilde ; B 7 -13 712 732 ;
-C -1 ; WX 600 ; N iacute ; B 95 0 612 672 ;
-C -1 ; WX 600 ; N arrowright ; B 34 115 688 483 ;
-C -1 ; WX 600 ; N Thorn ; B 79 0 606 562 ;
-C -1 ; WX 600 ; N Egrave ; B 53 0 660 793 ;
-C -1 ; WX 600 ; N thorn ; B -24 -157 605 629 ;
-C -1 ; WX 600 ; N aring ; B 76 -15 569 627 ;
-C -1 ; WX 600 ; N yacute ; B -4 -157 683 672 ;
-C -1 ; WX 600 ; N icircumflex ; B 95 0 551 654 ;
-EndCharMetrics
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 46 121 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex -4 121 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis -1 136 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave -4 121 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 12 126 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 27 126 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 56 121 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 26 121 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 29 136 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 26 121 ;
-CC Gcaron 2 ; PCC G 0 0 ; PCC caron 29 136 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 26 121 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 26 121 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 29 136 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 26 121 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 27 126 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 26 121 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 26 121 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 29 136 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 26 121 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 27 126 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 59 136 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 56 121 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 26 121 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 29 136 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave -4 121 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 56 121 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 29 136 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 29 136 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 0 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 0 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 0 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 0 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 0 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 0 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 0 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 0 0 ;
-CC gcaron 2 ; PCC g 0 0 ; PCC caron -30 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -30 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -30 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -30 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 0 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 0 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 0 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 0 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 0 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 0 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 0 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute -10 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex -10 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 0 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave -30 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute -20 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis -10 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 10 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvb8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvb8a.afm
deleted file mode 100644
index a1e1b33c40..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvb8a.afm
+++ /dev/null
@@ -1,570 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Thu Mar 15 09:43:00 1990
-Comment UniqueID 28357
-Comment VMusage 26878 33770
-FontName Helvetica-Bold
-FullName Helvetica Bold
-FamilyName Helvetica
-Weight Bold
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -170 -228 1003 962
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.007
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 718
-XHeight 532
-Ascender 718
-Descender -207
-StartCharMetrics 228
-C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 90 0 244 718 ;
-C 34 ; WX 474 ; N quotedbl ; B 98 447 376 718 ;
-C 35 ; WX 556 ; N numbersign ; B 18 0 538 698 ;
-C 36 ; WX 556 ; N dollar ; B 30 -115 523 775 ;
-C 37 ; WX 889 ; N percent ; B 28 -19 861 710 ;
-C 38 ; WX 722 ; N ampersand ; B 54 -19 701 718 ;
-C 39 ; WX 278 ; N quoteright ; B 69 445 209 718 ;
-C 40 ; WX 333 ; N parenleft ; B 35 -208 314 734 ;
-C 41 ; WX 333 ; N parenright ; B 19 -208 298 734 ;
-C 42 ; WX 389 ; N asterisk ; B 27 387 362 718 ;
-C 43 ; WX 584 ; N plus ; B 40 0 544 506 ;
-C 44 ; WX 278 ; N comma ; B 64 -168 214 146 ;
-C 45 ; WX 333 ; N hyphen ; B 27 215 306 345 ;
-C 46 ; WX 278 ; N period ; B 64 0 214 146 ;
-C 47 ; WX 278 ; N slash ; B -33 -19 311 737 ;
-C 48 ; WX 556 ; N zero ; B 32 -19 524 710 ;
-C 49 ; WX 556 ; N one ; B 69 0 378 710 ;
-C 50 ; WX 556 ; N two ; B 26 0 511 710 ;
-C 51 ; WX 556 ; N three ; B 27 -19 516 710 ;
-C 52 ; WX 556 ; N four ; B 27 0 526 710 ;
-C 53 ; WX 556 ; N five ; B 27 -19 516 698 ;
-C 54 ; WX 556 ; N six ; B 31 -19 520 710 ;
-C 55 ; WX 556 ; N seven ; B 25 0 528 698 ;
-C 56 ; WX 556 ; N eight ; B 32 -19 524 710 ;
-C 57 ; WX 556 ; N nine ; B 30 -19 522 710 ;
-C 58 ; WX 333 ; N colon ; B 92 0 242 512 ;
-C 59 ; WX 333 ; N semicolon ; B 92 -168 242 512 ;
-C 60 ; WX 584 ; N less ; B 38 -8 546 514 ;
-C 61 ; WX 584 ; N equal ; B 40 87 544 419 ;
-C 62 ; WX 584 ; N greater ; B 38 -8 546 514 ;
-C 63 ; WX 611 ; N question ; B 60 0 556 727 ;
-C 64 ; WX 975 ; N at ; B 118 -19 856 737 ;
-C 65 ; WX 722 ; N A ; B 20 0 702 718 ;
-C 66 ; WX 722 ; N B ; B 76 0 669 718 ;
-C 67 ; WX 722 ; N C ; B 44 -19 684 737 ;
-C 68 ; WX 722 ; N D ; B 76 0 685 718 ;
-C 69 ; WX 667 ; N E ; B 76 0 621 718 ;
-C 70 ; WX 611 ; N F ; B 76 0 587 718 ;
-C 71 ; WX 778 ; N G ; B 44 -19 713 737 ;
-C 72 ; WX 722 ; N H ; B 71 0 651 718 ;
-C 73 ; WX 278 ; N I ; B 64 0 214 718 ;
-C 74 ; WX 556 ; N J ; B 22 -18 484 718 ;
-C 75 ; WX 722 ; N K ; B 87 0 722 718 ;
-C 76 ; WX 611 ; N L ; B 76 0 583 718 ;
-C 77 ; WX 833 ; N M ; B 69 0 765 718 ;
-C 78 ; WX 722 ; N N ; B 69 0 654 718 ;
-C 79 ; WX 778 ; N O ; B 44 -19 734 737 ;
-C 80 ; WX 667 ; N P ; B 76 0 627 718 ;
-C 81 ; WX 778 ; N Q ; B 44 -52 737 737 ;
-C 82 ; WX 722 ; N R ; B 76 0 677 718 ;
-C 83 ; WX 667 ; N S ; B 39 -19 629 737 ;
-C 84 ; WX 611 ; N T ; B 14 0 598 718 ;
-C 85 ; WX 722 ; N U ; B 72 -19 651 718 ;
-C 86 ; WX 667 ; N V ; B 19 0 648 718 ;
-C 87 ; WX 944 ; N W ; B 16 0 929 718 ;
-C 88 ; WX 667 ; N X ; B 14 0 653 718 ;
-C 89 ; WX 667 ; N Y ; B 15 0 653 718 ;
-C 90 ; WX 611 ; N Z ; B 25 0 586 718 ;
-C 91 ; WX 333 ; N bracketleft ; B 63 -196 309 722 ;
-C 92 ; WX 278 ; N backslash ; B -33 -19 311 737 ;
-C 93 ; WX 333 ; N bracketright ; B 24 -196 270 722 ;
-C 94 ; WX 584 ; N asciicircum ; B 62 323 522 698 ;
-C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ;
-C 96 ; WX 278 ; N quoteleft ; B 69 454 209 727 ;
-C 97 ; WX 556 ; N a ; B 29 -14 527 546 ;
-C 98 ; WX 611 ; N b ; B 61 -14 578 718 ;
-C 99 ; WX 556 ; N c ; B 34 -14 524 546 ;
-C 100 ; WX 611 ; N d ; B 34 -14 551 718 ;
-C 101 ; WX 556 ; N e ; B 23 -14 528 546 ;
-C 102 ; WX 333 ; N f ; B 10 0 318 727 ; L i fi ; L l fl ;
-C 103 ; WX 611 ; N g ; B 40 -217 553 546 ;
-C 104 ; WX 611 ; N h ; B 65 0 546 718 ;
-C 105 ; WX 278 ; N i ; B 69 0 209 725 ;
-C 106 ; WX 278 ; N j ; B 3 -214 209 725 ;
-C 107 ; WX 556 ; N k ; B 69 0 562 718 ;
-C 108 ; WX 278 ; N l ; B 69 0 209 718 ;
-C 109 ; WX 889 ; N m ; B 64 0 826 546 ;
-C 110 ; WX 611 ; N n ; B 65 0 546 546 ;
-C 111 ; WX 611 ; N o ; B 34 -14 578 546 ;
-C 112 ; WX 611 ; N p ; B 62 -207 578 546 ;
-C 113 ; WX 611 ; N q ; B 34 -207 552 546 ;
-C 114 ; WX 389 ; N r ; B 64 0 373 546 ;
-C 115 ; WX 556 ; N s ; B 30 -14 519 546 ;
-C 116 ; WX 333 ; N t ; B 10 -6 309 676 ;
-C 117 ; WX 611 ; N u ; B 66 -14 545 532 ;
-C 118 ; WX 556 ; N v ; B 13 0 543 532 ;
-C 119 ; WX 778 ; N w ; B 10 0 769 532 ;
-C 120 ; WX 556 ; N x ; B 15 0 541 532 ;
-C 121 ; WX 556 ; N y ; B 10 -214 539 532 ;
-C 122 ; WX 500 ; N z ; B 20 0 480 532 ;
-C 123 ; WX 389 ; N braceleft ; B 48 -196 365 722 ;
-C 124 ; WX 280 ; N bar ; B 84 -19 196 737 ;
-C 125 ; WX 389 ; N braceright ; B 24 -196 341 722 ;
-C 126 ; WX 584 ; N asciitilde ; B 61 163 523 343 ;
-C 161 ; WX 333 ; N exclamdown ; B 90 -186 244 532 ;
-C 162 ; WX 556 ; N cent ; B 34 -118 524 628 ;
-C 163 ; WX 556 ; N sterling ; B 28 -16 541 718 ;
-C 164 ; WX 167 ; N fraction ; B -170 -19 336 710 ;
-C 165 ; WX 556 ; N yen ; B -9 0 565 698 ;
-C 166 ; WX 556 ; N florin ; B -10 -210 516 737 ;
-C 167 ; WX 556 ; N section ; B 34 -184 522 727 ;
-C 168 ; WX 556 ; N currency ; B -3 76 559 636 ;
-C 169 ; WX 238 ; N quotesingle ; B 70 447 168 718 ;
-C 170 ; WX 500 ; N quotedblleft ; B 64 454 436 727 ;
-C 171 ; WX 556 ; N guillemotleft ; B 88 76 468 484 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 83 76 250 484 ;
-C 173 ; WX 333 ; N guilsinglright ; B 83 76 250 484 ;
-C 174 ; WX 611 ; N fi ; B 10 0 542 727 ;
-C 175 ; WX 611 ; N fl ; B 10 0 542 727 ;
-C 177 ; WX 556 ; N endash ; B 0 227 556 333 ;
-C 178 ; WX 556 ; N dagger ; B 36 -171 520 718 ;
-C 179 ; WX 556 ; N daggerdbl ; B 36 -171 520 718 ;
-C 180 ; WX 278 ; N periodcentered ; B 58 172 220 334 ;
-C 182 ; WX 556 ; N paragraph ; B -8 -191 539 700 ;
-C 183 ; WX 350 ; N bullet ; B 10 194 340 524 ;
-C 184 ; WX 278 ; N quotesinglbase ; B 69 -146 209 127 ;
-C 185 ; WX 500 ; N quotedblbase ; B 64 -146 436 127 ;
-C 186 ; WX 500 ; N quotedblright ; B 64 445 436 718 ;
-C 187 ; WX 556 ; N guillemotright ; B 88 76 468 484 ;
-C 188 ; WX 1000 ; N ellipsis ; B 92 0 908 146 ;
-C 189 ; WX 1000 ; N perthousand ; B -3 -19 1003 710 ;
-C 191 ; WX 611 ; N questiondown ; B 55 -195 551 532 ;
-C 193 ; WX 333 ; N grave ; B -23 604 225 750 ;
-C 194 ; WX 333 ; N acute ; B 108 604 356 750 ;
-C 195 ; WX 333 ; N circumflex ; B -10 604 343 750 ;
-C 196 ; WX 333 ; N tilde ; B -17 610 350 737 ;
-C 197 ; WX 333 ; N macron ; B -6 604 339 678 ;
-C 198 ; WX 333 ; N breve ; B -2 604 335 750 ;
-C 199 ; WX 333 ; N dotaccent ; B 104 614 230 729 ;
-C 200 ; WX 333 ; N dieresis ; B 6 614 327 729 ;
-C 202 ; WX 333 ; N ring ; B 59 568 275 776 ;
-C 203 ; WX 333 ; N cedilla ; B 6 -228 245 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 9 604 486 750 ;
-C 206 ; WX 333 ; N ogonek ; B 71 -228 304 0 ;
-C 207 ; WX 333 ; N caron ; B -10 604 343 750 ;
-C 208 ; WX 1000 ; N emdash ; B 0 227 1000 333 ;
-C 225 ; WX 1000 ; N AE ; B 5 0 954 718 ;
-C 227 ; WX 370 ; N ordfeminine ; B 22 276 347 737 ;
-C 232 ; WX 611 ; N Lslash ; B -20 0 583 718 ;
-C 233 ; WX 778 ; N Oslash ; B 33 -27 744 745 ;
-C 234 ; WX 1000 ; N OE ; B 37 -19 961 737 ;
-C 235 ; WX 365 ; N ordmasculine ; B 6 276 360 737 ;
-C 241 ; WX 889 ; N ae ; B 29 -14 858 546 ;
-C 245 ; WX 278 ; N dotlessi ; B 69 0 209 532 ;
-C 248 ; WX 278 ; N lslash ; B -18 0 296 718 ;
-C 249 ; WX 611 ; N oslash ; B 22 -29 589 560 ;
-C 250 ; WX 944 ; N oe ; B 34 -14 912 546 ;
-C 251 ; WX 611 ; N germandbls ; B 69 -14 579 731 ;
-C -1 ; WX 611 ; N Zcaron ; B 25 0 586 936 ;
-C -1 ; WX 556 ; N ccedilla ; B 34 -228 524 546 ;
-C -1 ; WX 556 ; N ydieresis ; B 10 -214 539 729 ;
-C -1 ; WX 556 ; N atilde ; B 29 -14 527 737 ;
-C -1 ; WX 278 ; N icircumflex ; B -37 0 316 750 ;
-C -1 ; WX 333 ; N threesuperior ; B 8 271 326 710 ;
-C -1 ; WX 556 ; N ecircumflex ; B 23 -14 528 750 ;
-C -1 ; WX 611 ; N thorn ; B 62 -208 578 718 ;
-C -1 ; WX 556 ; N egrave ; B 23 -14 528 750 ;
-C -1 ; WX 333 ; N twosuperior ; B 9 283 324 710 ;
-C -1 ; WX 556 ; N eacute ; B 23 -14 528 750 ;
-C -1 ; WX 611 ; N otilde ; B 34 -14 578 737 ;
-C -1 ; WX 722 ; N Aacute ; B 20 0 702 936 ;
-C -1 ; WX 611 ; N ocircumflex ; B 34 -14 578 750 ;
-C -1 ; WX 556 ; N yacute ; B 10 -214 539 750 ;
-C -1 ; WX 611 ; N udieresis ; B 66 -14 545 729 ;
-C -1 ; WX 834 ; N threequarters ; B 16 -19 799 710 ;
-C -1 ; WX 556 ; N acircumflex ; B 29 -14 527 750 ;
-C -1 ; WX 722 ; N Eth ; B -5 0 685 718 ;
-C -1 ; WX 556 ; N edieresis ; B 23 -14 528 729 ;
-C -1 ; WX 611 ; N ugrave ; B 66 -14 545 750 ;
-C -1 ; WX 1000 ; N trademark ; B 44 306 956 718 ;
-C -1 ; WX 611 ; N ograve ; B 34 -14 578 750 ;
-C -1 ; WX 556 ; N scaron ; B 30 -14 519 750 ;
-C -1 ; WX 278 ; N Idieresis ; B -21 0 300 915 ;
-C -1 ; WX 611 ; N uacute ; B 66 -14 545 750 ;
-C -1 ; WX 556 ; N agrave ; B 29 -14 527 750 ;
-C -1 ; WX 611 ; N ntilde ; B 65 0 546 737 ;
-C -1 ; WX 556 ; N aring ; B 29 -14 527 776 ;
-C -1 ; WX 500 ; N zcaron ; B 20 0 480 750 ;
-C -1 ; WX 278 ; N Icircumflex ; B -37 0 316 936 ;
-C -1 ; WX 722 ; N Ntilde ; B 69 0 654 923 ;
-C -1 ; WX 611 ; N ucircumflex ; B 66 -14 545 750 ;
-C -1 ; WX 667 ; N Ecircumflex ; B 76 0 621 936 ;
-C -1 ; WX 278 ; N Iacute ; B 64 0 329 936 ;
-C -1 ; WX 722 ; N Ccedilla ; B 44 -228 684 737 ;
-C -1 ; WX 778 ; N Odieresis ; B 44 -19 734 915 ;
-C -1 ; WX 667 ; N Scaron ; B 39 -19 629 936 ;
-C -1 ; WX 667 ; N Edieresis ; B 76 0 621 915 ;
-C -1 ; WX 278 ; N Igrave ; B -50 0 214 936 ;
-C -1 ; WX 556 ; N adieresis ; B 29 -14 527 729 ;
-C -1 ; WX 778 ; N Ograve ; B 44 -19 734 936 ;
-C -1 ; WX 667 ; N Egrave ; B 76 0 621 936 ;
-C -1 ; WX 667 ; N Ydieresis ; B 15 0 653 915 ;
-C -1 ; WX 737 ; N registered ; B -11 -19 748 737 ;
-C -1 ; WX 778 ; N Otilde ; B 44 -19 734 923 ;
-C -1 ; WX 834 ; N onequarter ; B 26 -19 766 710 ;
-C -1 ; WX 722 ; N Ugrave ; B 72 -19 651 936 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 72 -19 651 936 ;
-C -1 ; WX 667 ; N Thorn ; B 76 0 627 718 ;
-C -1 ; WX 584 ; N divide ; B 40 -42 544 548 ;
-C -1 ; WX 722 ; N Atilde ; B 20 0 702 923 ;
-C -1 ; WX 722 ; N Uacute ; B 72 -19 651 936 ;
-C -1 ; WX 778 ; N Ocircumflex ; B 44 -19 734 936 ;
-C -1 ; WX 584 ; N logicalnot ; B 40 108 544 419 ;
-C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ;
-C -1 ; WX 278 ; N idieresis ; B -21 0 300 729 ;
-C -1 ; WX 278 ; N iacute ; B 69 0 329 750 ;
-C -1 ; WX 556 ; N aacute ; B 29 -14 527 750 ;
-C -1 ; WX 584 ; N plusminus ; B 40 0 544 506 ;
-C -1 ; WX 584 ; N multiply ; B 40 1 545 505 ;
-C -1 ; WX 722 ; N Udieresis ; B 72 -19 651 915 ;
-C -1 ; WX 584 ; N minus ; B 40 197 544 309 ;
-C -1 ; WX 333 ; N onesuperior ; B 26 283 237 710 ;
-C -1 ; WX 667 ; N Eacute ; B 76 0 621 936 ;
-C -1 ; WX 722 ; N Acircumflex ; B 20 0 702 936 ;
-C -1 ; WX 737 ; N copyright ; B -11 -19 749 737 ;
-C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ;
-C -1 ; WX 611 ; N odieresis ; B 34 -14 578 729 ;
-C -1 ; WX 611 ; N oacute ; B 34 -14 578 750 ;
-C -1 ; WX 400 ; N degree ; B 57 426 343 712 ;
-C -1 ; WX 278 ; N igrave ; B -50 0 209 750 ;
-C -1 ; WX 611 ; N mu ; B 66 -207 545 532 ;
-C -1 ; WX 778 ; N Oacute ; B 44 -19 734 936 ;
-C -1 ; WX 611 ; N eth ; B 34 -14 578 737 ;
-C -1 ; WX 722 ; N Adieresis ; B 20 0 702 915 ;
-C -1 ; WX 667 ; N Yacute ; B 15 0 653 936 ;
-C -1 ; WX 280 ; N brokenbar ; B 84 -19 196 737 ;
-C -1 ; WX 834 ; N onehalf ; B 26 -19 794 710 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 209
-
-KPX A y -30
-KPX A w -30
-KPX A v -40
-KPX A u -30
-KPX A Y -110
-KPX A W -60
-KPX A V -80
-KPX A U -50
-KPX A T -90
-KPX A Q -40
-KPX A O -40
-KPX A G -50
-KPX A C -40
-
-KPX B U -10
-KPX B A -30
-
-KPX D period -30
-KPX D comma -30
-KPX D Y -70
-KPX D W -40
-KPX D V -40
-KPX D A -40
-
-KPX F period -100
-KPX F comma -100
-KPX F a -20
-KPX F A -80
-
-KPX J u -20
-KPX J period -20
-KPX J comma -20
-KPX J A -20
-
-KPX K y -40
-KPX K u -30
-KPX K o -35
-KPX K e -15
-KPX K O -30
-
-KPX L y -30
-KPX L quoteright -140
-KPX L quotedblright -140
-KPX L Y -120
-KPX L W -80
-KPX L V -110
-KPX L T -90
-
-KPX O period -40
-KPX O comma -40
-KPX O Y -70
-KPX O X -50
-KPX O W -50
-KPX O V -50
-KPX O T -40
-KPX O A -50
-
-KPX P period -120
-KPX P o -40
-KPX P e -30
-KPX P comma -120
-KPX P a -30
-KPX P A -100
-
-KPX Q period 20
-KPX Q comma 20
-KPX Q U -10
-
-KPX R Y -50
-KPX R W -40
-KPX R V -50
-KPX R U -20
-KPX R T -20
-KPX R O -20
-
-KPX T y -60
-KPX T w -60
-KPX T u -90
-KPX T semicolon -40
-KPX T r -80
-KPX T period -80
-KPX T o -80
-KPX T hyphen -120
-KPX T e -60
-KPX T comma -80
-KPX T colon -40
-KPX T a -80
-KPX T O -40
-KPX T A -90
-
-KPX U period -30
-KPX U comma -30
-KPX U A -50
-
-KPX V u -60
-KPX V semicolon -40
-KPX V period -120
-KPX V o -90
-KPX V hyphen -80
-KPX V e -50
-KPX V comma -120
-KPX V colon -40
-KPX V a -60
-KPX V O -50
-KPX V G -50
-KPX V A -80
-
-KPX W y -20
-KPX W u -45
-KPX W semicolon -10
-KPX W period -80
-KPX W o -60
-KPX W hyphen -40
-KPX W e -35
-KPX W comma -80
-KPX W colon -10
-KPX W a -40
-KPX W O -20
-KPX W A -60
-
-KPX Y u -100
-KPX Y semicolon -50
-KPX Y period -100
-KPX Y o -100
-KPX Y e -80
-KPX Y comma -100
-KPX Y colon -50
-KPX Y a -90
-KPX Y O -70
-KPX Y A -110
-
-KPX a y -20
-KPX a w -15
-KPX a v -15
-KPX a g -10
-
-KPX b y -20
-KPX b v -20
-KPX b u -20
-KPX b l -10
-
-KPX c y -10
-KPX c l -20
-KPX c k -20
-KPX c h -10
-
-KPX colon space -40
-
-KPX comma space -40
-KPX comma quoteright -120
-KPX comma quotedblright -120
-
-KPX d y -15
-KPX d w -15
-KPX d v -15
-KPX d d -10
-
-KPX e y -15
-KPX e x -15
-KPX e w -15
-KPX e v -15
-KPX e period 20
-KPX e comma 10
-
-KPX f quoteright 30
-KPX f quotedblright 30
-KPX f period -10
-KPX f o -20
-KPX f e -10
-KPX f comma -10
-
-KPX g g -10
-KPX g e 10
-
-KPX h y -20
-
-KPX k o -15
-
-KPX l y -15
-KPX l w -15
-
-KPX m y -30
-KPX m u -20
-
-KPX n y -20
-KPX n v -40
-KPX n u -10
-
-KPX o y -20
-KPX o x -30
-KPX o w -15
-KPX o v -20
-
-KPX p y -15
-
-KPX period space -40
-KPX period quoteright -120
-KPX period quotedblright -120
-
-KPX quotedblright space -80
-
-KPX quoteleft quoteleft -46
-
-KPX quoteright v -20
-KPX quoteright space -80
-KPX quoteright s -60
-KPX quoteright r -40
-KPX quoteright quoteright -46
-KPX quoteright l -20
-KPX quoteright d -80
-
-KPX r y 10
-KPX r v 10
-KPX r t 20
-KPX r s -15
-KPX r q -20
-KPX r period -60
-KPX r o -20
-KPX r hyphen -20
-KPX r g -15
-KPX r d -20
-KPX r comma -60
-KPX r c -20
-
-KPX s w -15
-
-KPX semicolon space -40
-
-KPX space quoteleft -60
-KPX space quotedblleft -80
-KPX space Y -120
-KPX space W -80
-KPX space V -80
-KPX space T -100
-
-KPX v period -80
-KPX v o -30
-KPX v comma -80
-KPX v a -20
-
-KPX w period -40
-KPX w o -20
-KPX w comma -40
-
-KPX x e -10
-
-KPX y period -80
-KPX y o -25
-KPX y e -10
-KPX y comma -80
-KPX y a -30
-
-KPX z e 10
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 186 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 186 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 186 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 186 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 195 186 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 186 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 215 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 167 186 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 167 186 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 167 186 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 186 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 186 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 186 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 186 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 186 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 195 186 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 186 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 186 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 186 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 186 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 186 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 186 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 186 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 195 186 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 195 186 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 195 186 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 167 186 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 186 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 186 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 0 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 132 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 112 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 112 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvb8an.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvb8an.afm
deleted file mode 100644
index b7c69698bb..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvb8an.afm
+++ /dev/null
@@ -1,570 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Thu Mar 15 11:47:27 1990
-Comment UniqueID 28398
-Comment VMusage 7614 43068
-FontName Helvetica-Narrow-Bold
-FullName Helvetica Narrow Bold
-FamilyName Helvetica
-Weight Bold
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -139 -228 822 962
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.007
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 718
-XHeight 532
-Ascender 718
-Descender -207
-StartCharMetrics 228
-C 32 ; WX 228 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 273 ; N exclam ; B 74 0 200 718 ;
-C 34 ; WX 389 ; N quotedbl ; B 80 447 308 718 ;
-C 35 ; WX 456 ; N numbersign ; B 15 0 441 698 ;
-C 36 ; WX 456 ; N dollar ; B 25 -115 429 775 ;
-C 37 ; WX 729 ; N percent ; B 23 -19 706 710 ;
-C 38 ; WX 592 ; N ampersand ; B 44 -19 575 718 ;
-C 39 ; WX 228 ; N quoteright ; B 57 445 171 718 ;
-C 40 ; WX 273 ; N parenleft ; B 29 -208 257 734 ;
-C 41 ; WX 273 ; N parenright ; B 16 -208 244 734 ;
-C 42 ; WX 319 ; N asterisk ; B 22 387 297 718 ;
-C 43 ; WX 479 ; N plus ; B 33 0 446 506 ;
-C 44 ; WX 228 ; N comma ; B 52 -168 175 146 ;
-C 45 ; WX 273 ; N hyphen ; B 22 215 251 345 ;
-C 46 ; WX 228 ; N period ; B 52 0 175 146 ;
-C 47 ; WX 228 ; N slash ; B -27 -19 255 737 ;
-C 48 ; WX 456 ; N zero ; B 26 -19 430 710 ;
-C 49 ; WX 456 ; N one ; B 57 0 310 710 ;
-C 50 ; WX 456 ; N two ; B 21 0 419 710 ;
-C 51 ; WX 456 ; N three ; B 22 -19 423 710 ;
-C 52 ; WX 456 ; N four ; B 22 0 431 710 ;
-C 53 ; WX 456 ; N five ; B 22 -19 423 698 ;
-C 54 ; WX 456 ; N six ; B 25 -19 426 710 ;
-C 55 ; WX 456 ; N seven ; B 20 0 433 698 ;
-C 56 ; WX 456 ; N eight ; B 26 -19 430 710 ;
-C 57 ; WX 456 ; N nine ; B 25 -19 428 710 ;
-C 58 ; WX 273 ; N colon ; B 75 0 198 512 ;
-C 59 ; WX 273 ; N semicolon ; B 75 -168 198 512 ;
-C 60 ; WX 479 ; N less ; B 31 -8 448 514 ;
-C 61 ; WX 479 ; N equal ; B 33 87 446 419 ;
-C 62 ; WX 479 ; N greater ; B 31 -8 448 514 ;
-C 63 ; WX 501 ; N question ; B 49 0 456 727 ;
-C 64 ; WX 800 ; N at ; B 97 -19 702 737 ;
-C 65 ; WX 592 ; N A ; B 16 0 576 718 ;
-C 66 ; WX 592 ; N B ; B 62 0 549 718 ;
-C 67 ; WX 592 ; N C ; B 36 -19 561 737 ;
-C 68 ; WX 592 ; N D ; B 62 0 562 718 ;
-C 69 ; WX 547 ; N E ; B 62 0 509 718 ;
-C 70 ; WX 501 ; N F ; B 62 0 481 718 ;
-C 71 ; WX 638 ; N G ; B 36 -19 585 737 ;
-C 72 ; WX 592 ; N H ; B 58 0 534 718 ;
-C 73 ; WX 228 ; N I ; B 52 0 175 718 ;
-C 74 ; WX 456 ; N J ; B 18 -18 397 718 ;
-C 75 ; WX 592 ; N K ; B 71 0 592 718 ;
-C 76 ; WX 501 ; N L ; B 62 0 478 718 ;
-C 77 ; WX 683 ; N M ; B 57 0 627 718 ;
-C 78 ; WX 592 ; N N ; B 57 0 536 718 ;
-C 79 ; WX 638 ; N O ; B 36 -19 602 737 ;
-C 80 ; WX 547 ; N P ; B 62 0 514 718 ;
-C 81 ; WX 638 ; N Q ; B 36 -52 604 737 ;
-C 82 ; WX 592 ; N R ; B 62 0 555 718 ;
-C 83 ; WX 547 ; N S ; B 32 -19 516 737 ;
-C 84 ; WX 501 ; N T ; B 11 0 490 718 ;
-C 85 ; WX 592 ; N U ; B 59 -19 534 718 ;
-C 86 ; WX 547 ; N V ; B 16 0 531 718 ;
-C 87 ; WX 774 ; N W ; B 13 0 762 718 ;
-C 88 ; WX 547 ; N X ; B 11 0 535 718 ;
-C 89 ; WX 547 ; N Y ; B 12 0 535 718 ;
-C 90 ; WX 501 ; N Z ; B 20 0 481 718 ;
-C 91 ; WX 273 ; N bracketleft ; B 52 -196 253 722 ;
-C 92 ; WX 228 ; N backslash ; B -27 -19 255 737 ;
-C 93 ; WX 273 ; N bracketright ; B 20 -196 221 722 ;
-C 94 ; WX 479 ; N asciicircum ; B 51 323 428 698 ;
-C 95 ; WX 456 ; N underscore ; B 0 -125 456 -75 ;
-C 96 ; WX 228 ; N quoteleft ; B 57 454 171 727 ;
-C 97 ; WX 456 ; N a ; B 24 -14 432 546 ;
-C 98 ; WX 501 ; N b ; B 50 -14 474 718 ;
-C 99 ; WX 456 ; N c ; B 28 -14 430 546 ;
-C 100 ; WX 501 ; N d ; B 28 -14 452 718 ;
-C 101 ; WX 456 ; N e ; B 19 -14 433 546 ;
-C 102 ; WX 273 ; N f ; B 8 0 261 727 ; L i fi ; L l fl ;
-C 103 ; WX 501 ; N g ; B 33 -217 453 546 ;
-C 104 ; WX 501 ; N h ; B 53 0 448 718 ;
-C 105 ; WX 228 ; N i ; B 57 0 171 725 ;
-C 106 ; WX 228 ; N j ; B 2 -214 171 725 ;
-C 107 ; WX 456 ; N k ; B 57 0 461 718 ;
-C 108 ; WX 228 ; N l ; B 57 0 171 718 ;
-C 109 ; WX 729 ; N m ; B 52 0 677 546 ;
-C 110 ; WX 501 ; N n ; B 53 0 448 546 ;
-C 111 ; WX 501 ; N o ; B 28 -14 474 546 ;
-C 112 ; WX 501 ; N p ; B 51 -207 474 546 ;
-C 113 ; WX 501 ; N q ; B 28 -207 453 546 ;
-C 114 ; WX 319 ; N r ; B 52 0 306 546 ;
-C 115 ; WX 456 ; N s ; B 25 -14 426 546 ;
-C 116 ; WX 273 ; N t ; B 8 -6 253 676 ;
-C 117 ; WX 501 ; N u ; B 54 -14 447 532 ;
-C 118 ; WX 456 ; N v ; B 11 0 445 532 ;
-C 119 ; WX 638 ; N w ; B 8 0 631 532 ;
-C 120 ; WX 456 ; N x ; B 12 0 444 532 ;
-C 121 ; WX 456 ; N y ; B 8 -214 442 532 ;
-C 122 ; WX 410 ; N z ; B 16 0 394 532 ;
-C 123 ; WX 319 ; N braceleft ; B 39 -196 299 722 ;
-C 124 ; WX 230 ; N bar ; B 69 -19 161 737 ;
-C 125 ; WX 319 ; N braceright ; B 20 -196 280 722 ;
-C 126 ; WX 479 ; N asciitilde ; B 50 163 429 343 ;
-C 161 ; WX 273 ; N exclamdown ; B 74 -186 200 532 ;
-C 162 ; WX 456 ; N cent ; B 28 -118 430 628 ;
-C 163 ; WX 456 ; N sterling ; B 23 -16 444 718 ;
-C 164 ; WX 137 ; N fraction ; B -139 -19 276 710 ;
-C 165 ; WX 456 ; N yen ; B -7 0 463 698 ;
-C 166 ; WX 456 ; N florin ; B -8 -210 423 737 ;
-C 167 ; WX 456 ; N section ; B 28 -184 428 727 ;
-C 168 ; WX 456 ; N currency ; B -2 76 458 636 ;
-C 169 ; WX 195 ; N quotesingle ; B 57 447 138 718 ;
-C 170 ; WX 410 ; N quotedblleft ; B 52 454 358 727 ;
-C 171 ; WX 456 ; N guillemotleft ; B 72 76 384 484 ;
-C 172 ; WX 273 ; N guilsinglleft ; B 68 76 205 484 ;
-C 173 ; WX 273 ; N guilsinglright ; B 68 76 205 484 ;
-C 174 ; WX 501 ; N fi ; B 8 0 444 727 ;
-C 175 ; WX 501 ; N fl ; B 8 0 444 727 ;
-C 177 ; WX 456 ; N endash ; B 0 227 456 333 ;
-C 178 ; WX 456 ; N dagger ; B 30 -171 426 718 ;
-C 179 ; WX 456 ; N daggerdbl ; B 30 -171 426 718 ;
-C 180 ; WX 228 ; N periodcentered ; B 48 172 180 334 ;
-C 182 ; WX 456 ; N paragraph ; B -7 -191 442 700 ;
-C 183 ; WX 287 ; N bullet ; B 8 194 279 524 ;
-C 184 ; WX 228 ; N quotesinglbase ; B 57 -146 171 127 ;
-C 185 ; WX 410 ; N quotedblbase ; B 52 -146 358 127 ;
-C 186 ; WX 410 ; N quotedblright ; B 52 445 358 718 ;
-C 187 ; WX 456 ; N guillemotright ; B 72 76 384 484 ;
-C 188 ; WX 820 ; N ellipsis ; B 75 0 745 146 ;
-C 189 ; WX 820 ; N perthousand ; B -2 -19 822 710 ;
-C 191 ; WX 501 ; N questiondown ; B 45 -195 452 532 ;
-C 193 ; WX 273 ; N grave ; B -19 604 184 750 ;
-C 194 ; WX 273 ; N acute ; B 89 604 292 750 ;
-C 195 ; WX 273 ; N circumflex ; B -8 604 281 750 ;
-C 196 ; WX 273 ; N tilde ; B -14 610 287 737 ;
-C 197 ; WX 273 ; N macron ; B -5 604 278 678 ;
-C 198 ; WX 273 ; N breve ; B -2 604 275 750 ;
-C 199 ; WX 273 ; N dotaccent ; B 85 614 189 729 ;
-C 200 ; WX 273 ; N dieresis ; B 5 614 268 729 ;
-C 202 ; WX 273 ; N ring ; B 48 568 225 776 ;
-C 203 ; WX 273 ; N cedilla ; B 5 -228 201 0 ;
-C 205 ; WX 273 ; N hungarumlaut ; B 7 604 399 750 ;
-C 206 ; WX 273 ; N ogonek ; B 58 -228 249 0 ;
-C 207 ; WX 273 ; N caron ; B -8 604 281 750 ;
-C 208 ; WX 820 ; N emdash ; B 0 227 820 333 ;
-C 225 ; WX 820 ; N AE ; B 4 0 782 718 ;
-C 227 ; WX 303 ; N ordfeminine ; B 18 276 285 737 ;
-C 232 ; WX 501 ; N Lslash ; B -16 0 478 718 ;
-C 233 ; WX 638 ; N Oslash ; B 27 -27 610 745 ;
-C 234 ; WX 820 ; N OE ; B 30 -19 788 737 ;
-C 235 ; WX 299 ; N ordmasculine ; B 5 276 295 737 ;
-C 241 ; WX 729 ; N ae ; B 24 -14 704 546 ;
-C 245 ; WX 228 ; N dotlessi ; B 57 0 171 532 ;
-C 248 ; WX 228 ; N lslash ; B -15 0 243 718 ;
-C 249 ; WX 501 ; N oslash ; B 18 -29 483 560 ;
-C 250 ; WX 774 ; N oe ; B 28 -14 748 546 ;
-C 251 ; WX 501 ; N germandbls ; B 57 -14 475 731 ;
-C -1 ; WX 501 ; N Zcaron ; B 20 0 481 936 ;
-C -1 ; WX 456 ; N ccedilla ; B 28 -228 430 546 ;
-C -1 ; WX 456 ; N ydieresis ; B 8 -214 442 729 ;
-C -1 ; WX 456 ; N atilde ; B 24 -14 432 737 ;
-C -1 ; WX 228 ; N icircumflex ; B -30 0 259 750 ;
-C -1 ; WX 273 ; N threesuperior ; B 7 271 267 710 ;
-C -1 ; WX 456 ; N ecircumflex ; B 19 -14 433 750 ;
-C -1 ; WX 501 ; N thorn ; B 51 -208 474 718 ;
-C -1 ; WX 456 ; N egrave ; B 19 -14 433 750 ;
-C -1 ; WX 273 ; N twosuperior ; B 7 283 266 710 ;
-C -1 ; WX 456 ; N eacute ; B 19 -14 433 750 ;
-C -1 ; WX 501 ; N otilde ; B 28 -14 474 737 ;
-C -1 ; WX 592 ; N Aacute ; B 16 0 576 936 ;
-C -1 ; WX 501 ; N ocircumflex ; B 28 -14 474 750 ;
-C -1 ; WX 456 ; N yacute ; B 8 -214 442 750 ;
-C -1 ; WX 501 ; N udieresis ; B 54 -14 447 729 ;
-C -1 ; WX 684 ; N threequarters ; B 13 -19 655 710 ;
-C -1 ; WX 456 ; N acircumflex ; B 24 -14 432 750 ;
-C -1 ; WX 592 ; N Eth ; B -4 0 562 718 ;
-C -1 ; WX 456 ; N edieresis ; B 19 -14 433 729 ;
-C -1 ; WX 501 ; N ugrave ; B 54 -14 447 750 ;
-C -1 ; WX 820 ; N trademark ; B 36 306 784 718 ;
-C -1 ; WX 501 ; N ograve ; B 28 -14 474 750 ;
-C -1 ; WX 456 ; N scaron ; B 25 -14 426 750 ;
-C -1 ; WX 228 ; N Idieresis ; B -17 0 246 915 ;
-C -1 ; WX 501 ; N uacute ; B 54 -14 447 750 ;
-C -1 ; WX 456 ; N agrave ; B 24 -14 432 750 ;
-C -1 ; WX 501 ; N ntilde ; B 53 0 448 737 ;
-C -1 ; WX 456 ; N aring ; B 24 -14 432 776 ;
-C -1 ; WX 410 ; N zcaron ; B 16 0 394 750 ;
-C -1 ; WX 228 ; N Icircumflex ; B -30 0 259 936 ;
-C -1 ; WX 592 ; N Ntilde ; B 57 0 536 923 ;
-C -1 ; WX 501 ; N ucircumflex ; B 54 -14 447 750 ;
-C -1 ; WX 547 ; N Ecircumflex ; B 62 0 509 936 ;
-C -1 ; WX 228 ; N Iacute ; B 52 0 270 936 ;
-C -1 ; WX 592 ; N Ccedilla ; B 36 -228 561 737 ;
-C -1 ; WX 638 ; N Odieresis ; B 36 -19 602 915 ;
-C -1 ; WX 547 ; N Scaron ; B 32 -19 516 936 ;
-C -1 ; WX 547 ; N Edieresis ; B 62 0 509 915 ;
-C -1 ; WX 228 ; N Igrave ; B -41 0 175 936 ;
-C -1 ; WX 456 ; N adieresis ; B 24 -14 432 729 ;
-C -1 ; WX 638 ; N Ograve ; B 36 -19 602 936 ;
-C -1 ; WX 547 ; N Egrave ; B 62 0 509 936 ;
-C -1 ; WX 547 ; N Ydieresis ; B 12 0 535 915 ;
-C -1 ; WX 604 ; N registered ; B -9 -19 613 737 ;
-C -1 ; WX 638 ; N Otilde ; B 36 -19 602 923 ;
-C -1 ; WX 684 ; N onequarter ; B 21 -19 628 710 ;
-C -1 ; WX 592 ; N Ugrave ; B 59 -19 534 936 ;
-C -1 ; WX 592 ; N Ucircumflex ; B 59 -19 534 936 ;
-C -1 ; WX 547 ; N Thorn ; B 62 0 514 718 ;
-C -1 ; WX 479 ; N divide ; B 33 -42 446 548 ;
-C -1 ; WX 592 ; N Atilde ; B 16 0 576 923 ;
-C -1 ; WX 592 ; N Uacute ; B 59 -19 534 936 ;
-C -1 ; WX 638 ; N Ocircumflex ; B 36 -19 602 936 ;
-C -1 ; WX 479 ; N logicalnot ; B 33 108 446 419 ;
-C -1 ; WX 592 ; N Aring ; B 16 0 576 962 ;
-C -1 ; WX 228 ; N idieresis ; B -17 0 246 729 ;
-C -1 ; WX 228 ; N iacute ; B 57 0 270 750 ;
-C -1 ; WX 456 ; N aacute ; B 24 -14 432 750 ;
-C -1 ; WX 479 ; N plusminus ; B 33 0 446 506 ;
-C -1 ; WX 479 ; N multiply ; B 33 1 447 505 ;
-C -1 ; WX 592 ; N Udieresis ; B 59 -19 534 915 ;
-C -1 ; WX 479 ; N minus ; B 33 197 446 309 ;
-C -1 ; WX 273 ; N onesuperior ; B 21 283 194 710 ;
-C -1 ; WX 547 ; N Eacute ; B 62 0 509 936 ;
-C -1 ; WX 592 ; N Acircumflex ; B 16 0 576 936 ;
-C -1 ; WX 604 ; N copyright ; B -9 -19 614 737 ;
-C -1 ; WX 592 ; N Agrave ; B 16 0 576 936 ;
-C -1 ; WX 501 ; N odieresis ; B 28 -14 474 729 ;
-C -1 ; WX 501 ; N oacute ; B 28 -14 474 750 ;
-C -1 ; WX 328 ; N degree ; B 47 426 281 712 ;
-C -1 ; WX 228 ; N igrave ; B -41 0 171 750 ;
-C -1 ; WX 501 ; N mu ; B 54 -207 447 532 ;
-C -1 ; WX 638 ; N Oacute ; B 36 -19 602 936 ;
-C -1 ; WX 501 ; N eth ; B 28 -14 474 737 ;
-C -1 ; WX 592 ; N Adieresis ; B 16 0 576 915 ;
-C -1 ; WX 547 ; N Yacute ; B 12 0 535 936 ;
-C -1 ; WX 230 ; N brokenbar ; B 69 -19 161 737 ;
-C -1 ; WX 684 ; N onehalf ; B 21 -19 651 710 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 209
-
-KPX A y -24
-KPX A w -24
-KPX A v -32
-KPX A u -24
-KPX A Y -89
-KPX A W -48
-KPX A V -65
-KPX A U -40
-KPX A T -73
-KPX A Q -32
-KPX A O -32
-KPX A G -40
-KPX A C -32
-
-KPX B U -7
-KPX B A -24
-
-KPX D period -24
-KPX D comma -24
-KPX D Y -56
-KPX D W -32
-KPX D V -32
-KPX D A -32
-
-KPX F period -81
-KPX F comma -81
-KPX F a -15
-KPX F A -65
-
-KPX J u -15
-KPX J period -15
-KPX J comma -15
-KPX J A -15
-
-KPX K y -32
-KPX K u -24
-KPX K o -28
-KPX K e -11
-KPX K O -24
-
-KPX L y -24
-KPX L quoteright -114
-KPX L quotedblright -114
-KPX L Y -97
-KPX L W -65
-KPX L V -89
-KPX L T -73
-
-KPX O period -32
-KPX O comma -32
-KPX O Y -56
-KPX O X -40
-KPX O W -40
-KPX O V -40
-KPX O T -32
-KPX O A -40
-
-KPX P period -97
-KPX P o -32
-KPX P e -24
-KPX P comma -97
-KPX P a -24
-KPX P A -81
-
-KPX Q period 16
-KPX Q comma 16
-KPX Q U -7
-
-KPX R Y -40
-KPX R W -32
-KPX R V -40
-KPX R U -15
-KPX R T -15
-KPX R O -15
-
-KPX T y -48
-KPX T w -48
-KPX T u -73
-KPX T semicolon -32
-KPX T r -65
-KPX T period -65
-KPX T o -65
-KPX T hyphen -97
-KPX T e -48
-KPX T comma -65
-KPX T colon -32
-KPX T a -65
-KPX T O -32
-KPX T A -73
-
-KPX U period -24
-KPX U comma -24
-KPX U A -40
-
-KPX V u -48
-KPX V semicolon -32
-KPX V period -97
-KPX V o -73
-KPX V hyphen -65
-KPX V e -40
-KPX V comma -97
-KPX V colon -32
-KPX V a -48
-KPX V O -40
-KPX V G -40
-KPX V A -65
-
-KPX W y -15
-KPX W u -36
-KPX W semicolon -7
-KPX W period -65
-KPX W o -48
-KPX W hyphen -32
-KPX W e -28
-KPX W comma -65
-KPX W colon -7
-KPX W a -32
-KPX W O -15
-KPX W A -48
-
-KPX Y u -81
-KPX Y semicolon -40
-KPX Y period -81
-KPX Y o -81
-KPX Y e -65
-KPX Y comma -81
-KPX Y colon -40
-KPX Y a -73
-KPX Y O -56
-KPX Y A -89
-
-KPX a y -15
-KPX a w -11
-KPX a v -11
-KPX a g -7
-
-KPX b y -15
-KPX b v -15
-KPX b u -15
-KPX b l -7
-
-KPX c y -7
-KPX c l -15
-KPX c k -15
-KPX c h -7
-
-KPX colon space -32
-
-KPX comma space -32
-KPX comma quoteright -97
-KPX comma quotedblright -97
-
-KPX d y -11
-KPX d w -11
-KPX d v -11
-KPX d d -7
-
-KPX e y -11
-KPX e x -11
-KPX e w -11
-KPX e v -11
-KPX e period 16
-KPX e comma 8
-
-KPX f quoteright 25
-KPX f quotedblright 25
-KPX f period -7
-KPX f o -15
-KPX f e -7
-KPX f comma -7
-
-KPX g g -7
-KPX g e 8
-
-KPX h y -15
-
-KPX k o -11
-
-KPX l y -11
-KPX l w -11
-
-KPX m y -24
-KPX m u -15
-
-KPX n y -15
-KPX n v -32
-KPX n u -7
-
-KPX o y -15
-KPX o x -24
-KPX o w -11
-KPX o v -15
-
-KPX p y -11
-
-KPX period space -32
-KPX period quoteright -97
-KPX period quotedblright -97
-
-KPX quotedblright space -65
-
-KPX quoteleft quoteleft -37
-
-KPX quoteright v -15
-KPX quoteright space -65
-KPX quoteright s -48
-KPX quoteright r -32
-KPX quoteright quoteright -37
-KPX quoteright l -15
-KPX quoteright d -65
-
-KPX r y 8
-KPX r v 8
-KPX r t 16
-KPX r s -11
-KPX r q -15
-KPX r period -48
-KPX r o -15
-KPX r hyphen -15
-KPX r g -11
-KPX r d -15
-KPX r comma -48
-KPX r c -15
-
-KPX s w -11
-
-KPX semicolon space -32
-
-KPX space quoteleft -48
-KPX space quotedblleft -65
-KPX space Y -97
-KPX space W -65
-KPX space V -65
-KPX space T -81
-
-KPX v period -65
-KPX v o -24
-KPX v comma -65
-KPX v a -15
-
-KPX w period -32
-KPX w o -15
-KPX w comma -32
-
-KPX x e -7
-
-KPX y period -65
-KPX y o -20
-KPX y e -7
-KPX y comma -65
-KPX y a -24
-
-KPX z e 8
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 160 186 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 160 186 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 160 186 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 160 186 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 160 186 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 160 186 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 176 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 137 186 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 137 186 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 137 186 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 137 186 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute -22 186 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -22 186 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -22 186 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave -22 186 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 160 186 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 183 186 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 183 186 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 183 186 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 183 186 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 183 186 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 137 186 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 160 186 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 160 186 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 160 186 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 160 186 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 137 186 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 137 186 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 114 186 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 92 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 92 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 92 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 92 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 92 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 92 0 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 108 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 92 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 92 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 92 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -22 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -22 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -22 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -22 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 114 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 114 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 114 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 114 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 114 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 114 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 92 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 114 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 114 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 114 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 114 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 92 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 92 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 69 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvbo8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvbo8a.afm
deleted file mode 100644
index b6cff415fd..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvbo8a.afm
+++ /dev/null
@@ -1,570 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Thu Mar 15 10:44:33 1990
-Comment UniqueID 28371
-Comment VMusage 7614 43068
-FontName Helvetica-BoldOblique
-FullName Helvetica Bold Oblique
-FamilyName Helvetica
-Weight Bold
-ItalicAngle -12
-IsFixedPitch false
-FontBBox -174 -228 1114 962
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.007
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 718
-XHeight 532
-Ascender 718
-Descender -207
-StartCharMetrics 228
-C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 94 0 397 718 ;
-C 34 ; WX 474 ; N quotedbl ; B 193 447 529 718 ;
-C 35 ; WX 556 ; N numbersign ; B 60 0 644 698 ;
-C 36 ; WX 556 ; N dollar ; B 67 -115 622 775 ;
-C 37 ; WX 889 ; N percent ; B 136 -19 901 710 ;
-C 38 ; WX 722 ; N ampersand ; B 89 -19 732 718 ;
-C 39 ; WX 278 ; N quoteright ; B 167 445 362 718 ;
-C 40 ; WX 333 ; N parenleft ; B 76 -208 470 734 ;
-C 41 ; WX 333 ; N parenright ; B -25 -208 369 734 ;
-C 42 ; WX 389 ; N asterisk ; B 146 387 481 718 ;
-C 43 ; WX 584 ; N plus ; B 82 0 610 506 ;
-C 44 ; WX 278 ; N comma ; B 28 -168 245 146 ;
-C 45 ; WX 333 ; N hyphen ; B 73 215 379 345 ;
-C 46 ; WX 278 ; N period ; B 64 0 245 146 ;
-C 47 ; WX 278 ; N slash ; B -37 -19 468 737 ;
-C 48 ; WX 556 ; N zero ; B 86 -19 617 710 ;
-C 49 ; WX 556 ; N one ; B 173 0 529 710 ;
-C 50 ; WX 556 ; N two ; B 26 0 619 710 ;
-C 51 ; WX 556 ; N three ; B 65 -19 608 710 ;
-C 52 ; WX 556 ; N four ; B 60 0 598 710 ;
-C 53 ; WX 556 ; N five ; B 64 -19 636 698 ;
-C 54 ; WX 556 ; N six ; B 85 -19 619 710 ;
-C 55 ; WX 556 ; N seven ; B 125 0 676 698 ;
-C 56 ; WX 556 ; N eight ; B 69 -19 616 710 ;
-C 57 ; WX 556 ; N nine ; B 78 -19 615 710 ;
-C 58 ; WX 333 ; N colon ; B 92 0 351 512 ;
-C 59 ; WX 333 ; N semicolon ; B 56 -168 351 512 ;
-C 60 ; WX 584 ; N less ; B 82 -8 655 514 ;
-C 61 ; WX 584 ; N equal ; B 58 87 633 419 ;
-C 62 ; WX 584 ; N greater ; B 36 -8 609 514 ;
-C 63 ; WX 611 ; N question ; B 165 0 671 727 ;
-C 64 ; WX 975 ; N at ; B 186 -19 954 737 ;
-C 65 ; WX 722 ; N A ; B 20 0 702 718 ;
-C 66 ; WX 722 ; N B ; B 76 0 764 718 ;
-C 67 ; WX 722 ; N C ; B 107 -19 789 737 ;
-C 68 ; WX 722 ; N D ; B 76 0 777 718 ;
-C 69 ; WX 667 ; N E ; B 76 0 757 718 ;
-C 70 ; WX 611 ; N F ; B 76 0 740 718 ;
-C 71 ; WX 778 ; N G ; B 108 -19 817 737 ;
-C 72 ; WX 722 ; N H ; B 71 0 804 718 ;
-C 73 ; WX 278 ; N I ; B 64 0 367 718 ;
-C 74 ; WX 556 ; N J ; B 60 -18 637 718 ;
-C 75 ; WX 722 ; N K ; B 87 0 858 718 ;
-C 76 ; WX 611 ; N L ; B 76 0 611 718 ;
-C 77 ; WX 833 ; N M ; B 69 0 918 718 ;
-C 78 ; WX 722 ; N N ; B 69 0 807 718 ;
-C 79 ; WX 778 ; N O ; B 107 -19 823 737 ;
-C 80 ; WX 667 ; N P ; B 76 0 738 718 ;
-C 81 ; WX 778 ; N Q ; B 107 -52 823 737 ;
-C 82 ; WX 722 ; N R ; B 76 0 778 718 ;
-C 83 ; WX 667 ; N S ; B 81 -19 718 737 ;
-C 84 ; WX 611 ; N T ; B 140 0 751 718 ;
-C 85 ; WX 722 ; N U ; B 116 -19 804 718 ;
-C 86 ; WX 667 ; N V ; B 172 0 801 718 ;
-C 87 ; WX 944 ; N W ; B 169 0 1082 718 ;
-C 88 ; WX 667 ; N X ; B 14 0 791 718 ;
-C 89 ; WX 667 ; N Y ; B 168 0 806 718 ;
-C 90 ; WX 611 ; N Z ; B 25 0 737 718 ;
-C 91 ; WX 333 ; N bracketleft ; B 21 -196 462 722 ;
-C 92 ; WX 278 ; N backslash ; B 124 -19 307 737 ;
-C 93 ; WX 333 ; N bracketright ; B -18 -196 423 722 ;
-C 94 ; WX 584 ; N asciicircum ; B 131 323 591 698 ;
-C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ;
-C 96 ; WX 278 ; N quoteleft ; B 165 454 361 727 ;
-C 97 ; WX 556 ; N a ; B 55 -14 583 546 ;
-C 98 ; WX 611 ; N b ; B 61 -14 645 718 ;
-C 99 ; WX 556 ; N c ; B 79 -14 599 546 ;
-C 100 ; WX 611 ; N d ; B 82 -14 704 718 ;
-C 101 ; WX 556 ; N e ; B 70 -14 593 546 ;
-C 102 ; WX 333 ; N f ; B 87 0 469 727 ; L i fi ; L l fl ;
-C 103 ; WX 611 ; N g ; B 38 -217 666 546 ;
-C 104 ; WX 611 ; N h ; B 65 0 629 718 ;
-C 105 ; WX 278 ; N i ; B 69 0 363 725 ;
-C 106 ; WX 278 ; N j ; B -42 -214 363 725 ;
-C 107 ; WX 556 ; N k ; B 69 0 670 718 ;
-C 108 ; WX 278 ; N l ; B 69 0 362 718 ;
-C 109 ; WX 889 ; N m ; B 64 0 909 546 ;
-C 110 ; WX 611 ; N n ; B 65 0 629 546 ;
-C 111 ; WX 611 ; N o ; B 82 -14 643 546 ;
-C 112 ; WX 611 ; N p ; B 18 -207 645 546 ;
-C 113 ; WX 611 ; N q ; B 80 -207 665 546 ;
-C 114 ; WX 389 ; N r ; B 64 0 489 546 ;
-C 115 ; WX 556 ; N s ; B 63 -14 584 546 ;
-C 116 ; WX 333 ; N t ; B 100 -6 422 676 ;
-C 117 ; WX 611 ; N u ; B 98 -14 658 532 ;
-C 118 ; WX 556 ; N v ; B 126 0 656 532 ;
-C 119 ; WX 778 ; N w ; B 123 0 882 532 ;
-C 120 ; WX 556 ; N x ; B 15 0 648 532 ;
-C 121 ; WX 556 ; N y ; B 42 -214 652 532 ;
-C 122 ; WX 500 ; N z ; B 20 0 583 532 ;
-C 123 ; WX 389 ; N braceleft ; B 94 -196 518 722 ;
-C 124 ; WX 280 ; N bar ; B 80 -19 353 737 ;
-C 125 ; WX 389 ; N braceright ; B -18 -196 407 722 ;
-C 126 ; WX 584 ; N asciitilde ; B 115 163 577 343 ;
-C 161 ; WX 333 ; N exclamdown ; B 50 -186 353 532 ;
-C 162 ; WX 556 ; N cent ; B 79 -118 599 628 ;
-C 163 ; WX 556 ; N sterling ; B 50 -16 635 718 ;
-C 164 ; WX 167 ; N fraction ; B -174 -19 487 710 ;
-C 165 ; WX 556 ; N yen ; B 60 0 713 698 ;
-C 166 ; WX 556 ; N florin ; B -50 -210 669 737 ;
-C 167 ; WX 556 ; N section ; B 61 -184 598 727 ;
-C 168 ; WX 556 ; N currency ; B 27 76 680 636 ;
-C 169 ; WX 238 ; N quotesingle ; B 165 447 321 718 ;
-C 170 ; WX 500 ; N quotedblleft ; B 160 454 588 727 ;
-C 171 ; WX 556 ; N guillemotleft ; B 135 76 571 484 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 130 76 353 484 ;
-C 173 ; WX 333 ; N guilsinglright ; B 99 76 322 484 ;
-C 174 ; WX 611 ; N fi ; B 87 0 696 727 ;
-C 175 ; WX 611 ; N fl ; B 87 0 695 727 ;
-C 177 ; WX 556 ; N endash ; B 48 227 627 333 ;
-C 178 ; WX 556 ; N dagger ; B 118 -171 626 718 ;
-C 179 ; WX 556 ; N daggerdbl ; B 46 -171 628 718 ;
-C 180 ; WX 278 ; N periodcentered ; B 110 172 276 334 ;
-C 182 ; WX 556 ; N paragraph ; B 98 -191 688 700 ;
-C 183 ; WX 350 ; N bullet ; B 83 194 420 524 ;
-C 184 ; WX 278 ; N quotesinglbase ; B 41 -146 236 127 ;
-C 185 ; WX 500 ; N quotedblbase ; B 36 -146 463 127 ;
-C 186 ; WX 500 ; N quotedblright ; B 162 445 589 718 ;
-C 187 ; WX 556 ; N guillemotright ; B 104 76 540 484 ;
-C 188 ; WX 1000 ; N ellipsis ; B 92 0 939 146 ;
-C 189 ; WX 1000 ; N perthousand ; B 76 -19 1038 710 ;
-C 191 ; WX 611 ; N questiondown ; B 53 -195 559 532 ;
-C 193 ; WX 333 ; N grave ; B 136 604 353 750 ;
-C 194 ; WX 333 ; N acute ; B 236 604 515 750 ;
-C 195 ; WX 333 ; N circumflex ; B 118 604 471 750 ;
-C 196 ; WX 333 ; N tilde ; B 113 610 507 737 ;
-C 197 ; WX 333 ; N macron ; B 122 604 483 678 ;
-C 198 ; WX 333 ; N breve ; B 156 604 494 750 ;
-C 199 ; WX 333 ; N dotaccent ; B 235 614 385 729 ;
-C 200 ; WX 333 ; N dieresis ; B 137 614 482 729 ;
-C 202 ; WX 333 ; N ring ; B 200 568 420 776 ;
-C 203 ; WX 333 ; N cedilla ; B -37 -228 220 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 137 604 645 750 ;
-C 206 ; WX 333 ; N ogonek ; B 41 -228 264 0 ;
-C 207 ; WX 333 ; N caron ; B 149 604 502 750 ;
-C 208 ; WX 1000 ; N emdash ; B 48 227 1071 333 ;
-C 225 ; WX 1000 ; N AE ; B 5 0 1100 718 ;
-C 227 ; WX 370 ; N ordfeminine ; B 92 276 465 737 ;
-C 232 ; WX 611 ; N Lslash ; B 34 0 611 718 ;
-C 233 ; WX 778 ; N Oslash ; B 35 -27 894 745 ;
-C 234 ; WX 1000 ; N OE ; B 99 -19 1114 737 ;
-C 235 ; WX 365 ; N ordmasculine ; B 92 276 485 737 ;
-C 241 ; WX 889 ; N ae ; B 56 -14 923 546 ;
-C 245 ; WX 278 ; N dotlessi ; B 69 0 322 532 ;
-C 248 ; WX 278 ; N lslash ; B 40 0 407 718 ;
-C 249 ; WX 611 ; N oslash ; B 22 -29 701 560 ;
-C 250 ; WX 944 ; N oe ; B 82 -14 977 546 ;
-C 251 ; WX 611 ; N germandbls ; B 69 -14 657 731 ;
-C -1 ; WX 611 ; N Zcaron ; B 25 0 737 936 ;
-C -1 ; WX 556 ; N ccedilla ; B 79 -228 599 546 ;
-C -1 ; WX 556 ; N ydieresis ; B 42 -214 652 729 ;
-C -1 ; WX 556 ; N atilde ; B 55 -14 619 737 ;
-C -1 ; WX 278 ; N icircumflex ; B 69 0 444 750 ;
-C -1 ; WX 333 ; N threesuperior ; B 91 271 441 710 ;
-C -1 ; WX 556 ; N ecircumflex ; B 70 -14 593 750 ;
-C -1 ; WX 611 ; N thorn ; B 18 -208 645 718 ;
-C -1 ; WX 556 ; N egrave ; B 70 -14 593 750 ;
-C -1 ; WX 333 ; N twosuperior ; B 69 283 449 710 ;
-C -1 ; WX 556 ; N eacute ; B 70 -14 627 750 ;
-C -1 ; WX 611 ; N otilde ; B 82 -14 646 737 ;
-C -1 ; WX 722 ; N Aacute ; B 20 0 750 936 ;
-C -1 ; WX 611 ; N ocircumflex ; B 82 -14 643 750 ;
-C -1 ; WX 556 ; N yacute ; B 42 -214 652 750 ;
-C -1 ; WX 611 ; N udieresis ; B 98 -14 658 729 ;
-C -1 ; WX 834 ; N threequarters ; B 99 -19 839 710 ;
-C -1 ; WX 556 ; N acircumflex ; B 55 -14 583 750 ;
-C -1 ; WX 722 ; N Eth ; B 62 0 777 718 ;
-C -1 ; WX 556 ; N edieresis ; B 70 -14 594 729 ;
-C -1 ; WX 611 ; N ugrave ; B 98 -14 658 750 ;
-C -1 ; WX 1000 ; N trademark ; B 179 306 1109 718 ;
-C -1 ; WX 611 ; N ograve ; B 82 -14 643 750 ;
-C -1 ; WX 556 ; N scaron ; B 63 -14 614 750 ;
-C -1 ; WX 278 ; N Idieresis ; B 64 0 494 915 ;
-C -1 ; WX 611 ; N uacute ; B 98 -14 658 750 ;
-C -1 ; WX 556 ; N agrave ; B 55 -14 583 750 ;
-C -1 ; WX 611 ; N ntilde ; B 65 0 646 737 ;
-C -1 ; WX 556 ; N aring ; B 55 -14 583 776 ;
-C -1 ; WX 500 ; N zcaron ; B 20 0 586 750 ;
-C -1 ; WX 278 ; N Icircumflex ; B 64 0 484 936 ;
-C -1 ; WX 722 ; N Ntilde ; B 69 0 807 923 ;
-C -1 ; WX 611 ; N ucircumflex ; B 98 -14 658 750 ;
-C -1 ; WX 667 ; N Ecircumflex ; B 76 0 757 936 ;
-C -1 ; WX 278 ; N Iacute ; B 64 0 528 936 ;
-C -1 ; WX 722 ; N Ccedilla ; B 107 -228 789 737 ;
-C -1 ; WX 778 ; N Odieresis ; B 107 -19 823 915 ;
-C -1 ; WX 667 ; N Scaron ; B 81 -19 718 936 ;
-C -1 ; WX 667 ; N Edieresis ; B 76 0 757 915 ;
-C -1 ; WX 278 ; N Igrave ; B 64 0 367 936 ;
-C -1 ; WX 556 ; N adieresis ; B 55 -14 594 729 ;
-C -1 ; WX 778 ; N Ograve ; B 107 -19 823 936 ;
-C -1 ; WX 667 ; N Egrave ; B 76 0 757 936 ;
-C -1 ; WX 667 ; N Ydieresis ; B 168 0 806 915 ;
-C -1 ; WX 737 ; N registered ; B 55 -19 834 737 ;
-C -1 ; WX 778 ; N Otilde ; B 107 -19 823 923 ;
-C -1 ; WX 834 ; N onequarter ; B 132 -19 806 710 ;
-C -1 ; WX 722 ; N Ugrave ; B 116 -19 804 936 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 116 -19 804 936 ;
-C -1 ; WX 667 ; N Thorn ; B 76 0 716 718 ;
-C -1 ; WX 584 ; N divide ; B 82 -42 610 548 ;
-C -1 ; WX 722 ; N Atilde ; B 20 0 741 923 ;
-C -1 ; WX 722 ; N Uacute ; B 116 -19 804 936 ;
-C -1 ; WX 778 ; N Ocircumflex ; B 107 -19 823 936 ;
-C -1 ; WX 584 ; N logicalnot ; B 105 108 633 419 ;
-C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ;
-C -1 ; WX 278 ; N idieresis ; B 69 0 455 729 ;
-C -1 ; WX 278 ; N iacute ; B 69 0 488 750 ;
-C -1 ; WX 556 ; N aacute ; B 55 -14 627 750 ;
-C -1 ; WX 584 ; N plusminus ; B 40 0 625 506 ;
-C -1 ; WX 584 ; N multiply ; B 57 1 635 505 ;
-C -1 ; WX 722 ; N Udieresis ; B 116 -19 804 915 ;
-C -1 ; WX 584 ; N minus ; B 82 197 610 309 ;
-C -1 ; WX 333 ; N onesuperior ; B 148 283 388 710 ;
-C -1 ; WX 667 ; N Eacute ; B 76 0 757 936 ;
-C -1 ; WX 722 ; N Acircumflex ; B 20 0 706 936 ;
-C -1 ; WX 737 ; N copyright ; B 56 -19 835 737 ;
-C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ;
-C -1 ; WX 611 ; N odieresis ; B 82 -14 643 729 ;
-C -1 ; WX 611 ; N oacute ; B 82 -14 654 750 ;
-C -1 ; WX 400 ; N degree ; B 175 426 467 712 ;
-C -1 ; WX 278 ; N igrave ; B 69 0 326 750 ;
-C -1 ; WX 611 ; N mu ; B 22 -207 658 532 ;
-C -1 ; WX 778 ; N Oacute ; B 107 -19 823 936 ;
-C -1 ; WX 611 ; N eth ; B 82 -14 670 737 ;
-C -1 ; WX 722 ; N Adieresis ; B 20 0 716 915 ;
-C -1 ; WX 667 ; N Yacute ; B 168 0 806 936 ;
-C -1 ; WX 280 ; N brokenbar ; B 80 -19 353 737 ;
-C -1 ; WX 834 ; N onehalf ; B 132 -19 858 710 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 209
-
-KPX A y -30
-KPX A w -30
-KPX A v -40
-KPX A u -30
-KPX A Y -110
-KPX A W -60
-KPX A V -80
-KPX A U -50
-KPX A T -90
-KPX A Q -40
-KPX A O -40
-KPX A G -50
-KPX A C -40
-
-KPX B U -10
-KPX B A -30
-
-KPX D period -30
-KPX D comma -30
-KPX D Y -70
-KPX D W -40
-KPX D V -40
-KPX D A -40
-
-KPX F period -100
-KPX F comma -100
-KPX F a -20
-KPX F A -80
-
-KPX J u -20
-KPX J period -20
-KPX J comma -20
-KPX J A -20
-
-KPX K y -40
-KPX K u -30
-KPX K o -35
-KPX K e -15
-KPX K O -30
-
-KPX L y -30
-KPX L quoteright -140
-KPX L quotedblright -140
-KPX L Y -120
-KPX L W -80
-KPX L V -110
-KPX L T -90
-
-KPX O period -40
-KPX O comma -40
-KPX O Y -70
-KPX O X -50
-KPX O W -50
-KPX O V -50
-KPX O T -40
-KPX O A -50
-
-KPX P period -120
-KPX P o -40
-KPX P e -30
-KPX P comma -120
-KPX P a -30
-KPX P A -100
-
-KPX Q period 20
-KPX Q comma 20
-KPX Q U -10
-
-KPX R Y -50
-KPX R W -40
-KPX R V -50
-KPX R U -20
-KPX R T -20
-KPX R O -20
-
-KPX T y -60
-KPX T w -60
-KPX T u -90
-KPX T semicolon -40
-KPX T r -80
-KPX T period -80
-KPX T o -80
-KPX T hyphen -120
-KPX T e -60
-KPX T comma -80
-KPX T colon -40
-KPX T a -80
-KPX T O -40
-KPX T A -90
-
-KPX U period -30
-KPX U comma -30
-KPX U A -50
-
-KPX V u -60
-KPX V semicolon -40
-KPX V period -120
-KPX V o -90
-KPX V hyphen -80
-KPX V e -50
-KPX V comma -120
-KPX V colon -40
-KPX V a -60
-KPX V O -50
-KPX V G -50
-KPX V A -80
-
-KPX W y -20
-KPX W u -45
-KPX W semicolon -10
-KPX W period -80
-KPX W o -60
-KPX W hyphen -40
-KPX W e -35
-KPX W comma -80
-KPX W colon -10
-KPX W a -40
-KPX W O -20
-KPX W A -60
-
-KPX Y u -100
-KPX Y semicolon -50
-KPX Y period -100
-KPX Y o -100
-KPX Y e -80
-KPX Y comma -100
-KPX Y colon -50
-KPX Y a -90
-KPX Y O -70
-KPX Y A -110
-
-KPX a y -20
-KPX a w -15
-KPX a v -15
-KPX a g -10
-
-KPX b y -20
-KPX b v -20
-KPX b u -20
-KPX b l -10
-
-KPX c y -10
-KPX c l -20
-KPX c k -20
-KPX c h -10
-
-KPX colon space -40
-
-KPX comma space -40
-KPX comma quoteright -120
-KPX comma quotedblright -120
-
-KPX d y -15
-KPX d w -15
-KPX d v -15
-KPX d d -10
-
-KPX e y -15
-KPX e x -15
-KPX e w -15
-KPX e v -15
-KPX e period 20
-KPX e comma 10
-
-KPX f quoteright 30
-KPX f quotedblright 30
-KPX f period -10
-KPX f o -20
-KPX f e -10
-KPX f comma -10
-
-KPX g g -10
-KPX g e 10
-
-KPX h y -20
-
-KPX k o -15
-
-KPX l y -15
-KPX l w -15
-
-KPX m y -30
-KPX m u -20
-
-KPX n y -20
-KPX n v -40
-KPX n u -10
-
-KPX o y -20
-KPX o x -30
-KPX o w -15
-KPX o v -20
-
-KPX p y -15
-
-KPX period space -40
-KPX period quoteright -120
-KPX period quotedblright -120
-
-KPX quotedblright space -80
-
-KPX quoteleft quoteleft -46
-
-KPX quoteright v -20
-KPX quoteright space -80
-KPX quoteright s -60
-KPX quoteright r -40
-KPX quoteright quoteright -46
-KPX quoteright l -20
-KPX quoteright d -80
-
-KPX r y 10
-KPX r v 10
-KPX r t 20
-KPX r s -15
-KPX r q -20
-KPX r period -60
-KPX r o -20
-KPX r hyphen -20
-KPX r g -15
-KPX r d -20
-KPX r comma -60
-KPX r c -20
-
-KPX s w -15
-
-KPX semicolon space -40
-
-KPX space quoteleft -60
-KPX space quotedblleft -80
-KPX space Y -120
-KPX space W -80
-KPX space V -80
-KPX space T -100
-
-KPX v period -80
-KPX v o -30
-KPX v comma -80
-KPX v a -20
-
-KPX w period -40
-KPX w o -20
-KPX w comma -40
-
-KPX x e -10
-
-KPX y period -80
-KPX y o -25
-KPX y e -10
-KPX y comma -80
-KPX y a -30
-
-KPX z e 10
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 235 186 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 235 186 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 235 186 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 235 186 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 235 186 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 235 186 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 215 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 207 186 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 207 186 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 207 186 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 207 186 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 13 186 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 13 186 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 13 186 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 13 186 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 235 186 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 263 186 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 263 186 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 263 186 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 263 186 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 263 186 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 207 186 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 235 186 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 235 186 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 235 186 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 235 186 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 207 186 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 207 186 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 179 186 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 0 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 132 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 112 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 112 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvbo8an.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvbo8an.afm
deleted file mode 100644
index 1a3800194d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvbo8an.afm
+++ /dev/null
@@ -1,570 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Thu Mar 15 12:08:57 1990
-Comment UniqueID 28407
-Comment VMusage 7614 43068
-FontName Helvetica-Narrow-BoldOblique
-FullName Helvetica Narrow Bold Oblique
-FamilyName Helvetica
-Weight Bold
-ItalicAngle -12
-IsFixedPitch false
-FontBBox -143 -228 913 962
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.007
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 718
-XHeight 532
-Ascender 718
-Descender -207
-StartCharMetrics 228
-C 32 ; WX 228 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 273 ; N exclam ; B 77 0 325 718 ;
-C 34 ; WX 389 ; N quotedbl ; B 158 447 433 718 ;
-C 35 ; WX 456 ; N numbersign ; B 49 0 528 698 ;
-C 36 ; WX 456 ; N dollar ; B 55 -115 510 775 ;
-C 37 ; WX 729 ; N percent ; B 112 -19 739 710 ;
-C 38 ; WX 592 ; N ampersand ; B 73 -19 600 718 ;
-C 39 ; WX 228 ; N quoteright ; B 137 445 297 718 ;
-C 40 ; WX 273 ; N parenleft ; B 62 -208 385 734 ;
-C 41 ; WX 273 ; N parenright ; B -21 -208 302 734 ;
-C 42 ; WX 319 ; N asterisk ; B 120 387 394 718 ;
-C 43 ; WX 479 ; N plus ; B 67 0 500 506 ;
-C 44 ; WX 228 ; N comma ; B 23 -168 201 146 ;
-C 45 ; WX 273 ; N hyphen ; B 60 215 311 345 ;
-C 46 ; WX 228 ; N period ; B 52 0 201 146 ;
-C 47 ; WX 228 ; N slash ; B -30 -19 383 737 ;
-C 48 ; WX 456 ; N zero ; B 71 -19 506 710 ;
-C 49 ; WX 456 ; N one ; B 142 0 434 710 ;
-C 50 ; WX 456 ; N two ; B 21 0 508 710 ;
-C 51 ; WX 456 ; N three ; B 54 -19 499 710 ;
-C 52 ; WX 456 ; N four ; B 50 0 490 710 ;
-C 53 ; WX 456 ; N five ; B 53 -19 522 698 ;
-C 54 ; WX 456 ; N six ; B 70 -19 507 710 ;
-C 55 ; WX 456 ; N seven ; B 102 0 555 698 ;
-C 56 ; WX 456 ; N eight ; B 57 -19 505 710 ;
-C 57 ; WX 456 ; N nine ; B 64 -19 504 710 ;
-C 58 ; WX 273 ; N colon ; B 75 0 288 512 ;
-C 59 ; WX 273 ; N semicolon ; B 46 -168 288 512 ;
-C 60 ; WX 479 ; N less ; B 67 -8 537 514 ;
-C 61 ; WX 479 ; N equal ; B 48 87 519 419 ;
-C 62 ; WX 479 ; N greater ; B 30 -8 500 514 ;
-C 63 ; WX 501 ; N question ; B 135 0 550 727 ;
-C 64 ; WX 800 ; N at ; B 152 -19 782 737 ;
-C 65 ; WX 592 ; N A ; B 16 0 576 718 ;
-C 66 ; WX 592 ; N B ; B 62 0 626 718 ;
-C 67 ; WX 592 ; N C ; B 88 -19 647 737 ;
-C 68 ; WX 592 ; N D ; B 62 0 637 718 ;
-C 69 ; WX 547 ; N E ; B 62 0 620 718 ;
-C 70 ; WX 501 ; N F ; B 62 0 606 718 ;
-C 71 ; WX 638 ; N G ; B 89 -19 670 737 ;
-C 72 ; WX 592 ; N H ; B 58 0 659 718 ;
-C 73 ; WX 228 ; N I ; B 52 0 301 718 ;
-C 74 ; WX 456 ; N J ; B 49 -18 522 718 ;
-C 75 ; WX 592 ; N K ; B 71 0 703 718 ;
-C 76 ; WX 501 ; N L ; B 62 0 501 718 ;
-C 77 ; WX 683 ; N M ; B 57 0 752 718 ;
-C 78 ; WX 592 ; N N ; B 57 0 661 718 ;
-C 79 ; WX 638 ; N O ; B 88 -19 675 737 ;
-C 80 ; WX 547 ; N P ; B 62 0 605 718 ;
-C 81 ; WX 638 ; N Q ; B 88 -52 675 737 ;
-C 82 ; WX 592 ; N R ; B 62 0 638 718 ;
-C 83 ; WX 547 ; N S ; B 66 -19 588 737 ;
-C 84 ; WX 501 ; N T ; B 114 0 615 718 ;
-C 85 ; WX 592 ; N U ; B 96 -19 659 718 ;
-C 86 ; WX 547 ; N V ; B 141 0 656 718 ;
-C 87 ; WX 774 ; N W ; B 138 0 887 718 ;
-C 88 ; WX 547 ; N X ; B 11 0 648 718 ;
-C 89 ; WX 547 ; N Y ; B 137 0 661 718 ;
-C 90 ; WX 501 ; N Z ; B 20 0 604 718 ;
-C 91 ; WX 273 ; N bracketleft ; B 17 -196 379 722 ;
-C 92 ; WX 228 ; N backslash ; B 101 -19 252 737 ;
-C 93 ; WX 273 ; N bracketright ; B -14 -196 347 722 ;
-C 94 ; WX 479 ; N asciicircum ; B 107 323 484 698 ;
-C 95 ; WX 456 ; N underscore ; B -22 -125 443 -75 ;
-C 96 ; WX 228 ; N quoteleft ; B 136 454 296 727 ;
-C 97 ; WX 456 ; N a ; B 45 -14 478 546 ;
-C 98 ; WX 501 ; N b ; B 50 -14 529 718 ;
-C 99 ; WX 456 ; N c ; B 65 -14 491 546 ;
-C 100 ; WX 501 ; N d ; B 67 -14 577 718 ;
-C 101 ; WX 456 ; N e ; B 58 -14 486 546 ;
-C 102 ; WX 273 ; N f ; B 71 0 385 727 ; L i fi ; L l fl ;
-C 103 ; WX 501 ; N g ; B 31 -217 546 546 ;
-C 104 ; WX 501 ; N h ; B 53 0 516 718 ;
-C 105 ; WX 228 ; N i ; B 57 0 298 725 ;
-C 106 ; WX 228 ; N j ; B -35 -214 298 725 ;
-C 107 ; WX 456 ; N k ; B 57 0 549 718 ;
-C 108 ; WX 228 ; N l ; B 57 0 297 718 ;
-C 109 ; WX 729 ; N m ; B 52 0 746 546 ;
-C 110 ; WX 501 ; N n ; B 53 0 516 546 ;
-C 111 ; WX 501 ; N o ; B 67 -14 527 546 ;
-C 112 ; WX 501 ; N p ; B 15 -207 529 546 ;
-C 113 ; WX 501 ; N q ; B 66 -207 545 546 ;
-C 114 ; WX 319 ; N r ; B 52 0 401 546 ;
-C 115 ; WX 456 ; N s ; B 52 -14 479 546 ;
-C 116 ; WX 273 ; N t ; B 82 -6 346 676 ;
-C 117 ; WX 501 ; N u ; B 80 -14 540 532 ;
-C 118 ; WX 456 ; N v ; B 103 0 538 532 ;
-C 119 ; WX 638 ; N w ; B 101 0 723 532 ;
-C 120 ; WX 456 ; N x ; B 12 0 531 532 ;
-C 121 ; WX 456 ; N y ; B 34 -214 535 532 ;
-C 122 ; WX 410 ; N z ; B 16 0 478 532 ;
-C 123 ; WX 319 ; N braceleft ; B 77 -196 425 722 ;
-C 124 ; WX 230 ; N bar ; B 66 -19 289 737 ;
-C 125 ; WX 319 ; N braceright ; B -14 -196 333 722 ;
-C 126 ; WX 479 ; N asciitilde ; B 94 163 473 343 ;
-C 161 ; WX 273 ; N exclamdown ; B 41 -186 290 532 ;
-C 162 ; WX 456 ; N cent ; B 65 -118 491 628 ;
-C 163 ; WX 456 ; N sterling ; B 41 -16 520 718 ;
-C 164 ; WX 137 ; N fraction ; B -143 -19 399 710 ;
-C 165 ; WX 456 ; N yen ; B 49 0 585 698 ;
-C 166 ; WX 456 ; N florin ; B -41 -210 548 737 ;
-C 167 ; WX 456 ; N section ; B 50 -184 491 727 ;
-C 168 ; WX 456 ; N currency ; B 22 76 558 636 ;
-C 169 ; WX 195 ; N quotesingle ; B 135 447 263 718 ;
-C 170 ; WX 410 ; N quotedblleft ; B 132 454 482 727 ;
-C 171 ; WX 456 ; N guillemotleft ; B 111 76 468 484 ;
-C 172 ; WX 273 ; N guilsinglleft ; B 106 76 289 484 ;
-C 173 ; WX 273 ; N guilsinglright ; B 81 76 264 484 ;
-C 174 ; WX 501 ; N fi ; B 71 0 571 727 ;
-C 175 ; WX 501 ; N fl ; B 71 0 570 727 ;
-C 177 ; WX 456 ; N endash ; B 40 227 514 333 ;
-C 178 ; WX 456 ; N dagger ; B 97 -171 513 718 ;
-C 179 ; WX 456 ; N daggerdbl ; B 38 -171 515 718 ;
-C 180 ; WX 228 ; N periodcentered ; B 90 172 226 334 ;
-C 182 ; WX 456 ; N paragraph ; B 80 -191 564 700 ;
-C 183 ; WX 287 ; N bullet ; B 68 194 345 524 ;
-C 184 ; WX 228 ; N quotesinglbase ; B 34 -146 194 127 ;
-C 185 ; WX 410 ; N quotedblbase ; B 29 -146 380 127 ;
-C 186 ; WX 410 ; N quotedblright ; B 132 445 483 718 ;
-C 187 ; WX 456 ; N guillemotright ; B 85 76 443 484 ;
-C 188 ; WX 820 ; N ellipsis ; B 75 0 770 146 ;
-C 189 ; WX 820 ; N perthousand ; B 62 -19 851 710 ;
-C 191 ; WX 501 ; N questiondown ; B 44 -195 459 532 ;
-C 193 ; WX 273 ; N grave ; B 112 604 290 750 ;
-C 194 ; WX 273 ; N acute ; B 194 604 423 750 ;
-C 195 ; WX 273 ; N circumflex ; B 97 604 387 750 ;
-C 196 ; WX 273 ; N tilde ; B 92 610 415 737 ;
-C 197 ; WX 273 ; N macron ; B 100 604 396 678 ;
-C 198 ; WX 273 ; N breve ; B 128 604 405 750 ;
-C 199 ; WX 273 ; N dotaccent ; B 192 614 316 729 ;
-C 200 ; WX 273 ; N dieresis ; B 112 614 395 729 ;
-C 202 ; WX 273 ; N ring ; B 164 568 344 776 ;
-C 203 ; WX 273 ; N cedilla ; B -30 -228 180 0 ;
-C 205 ; WX 273 ; N hungarumlaut ; B 113 604 529 750 ;
-C 206 ; WX 273 ; N ogonek ; B 33 -228 216 0 ;
-C 207 ; WX 273 ; N caron ; B 123 604 412 750 ;
-C 208 ; WX 820 ; N emdash ; B 40 227 878 333 ;
-C 225 ; WX 820 ; N AE ; B 4 0 902 718 ;
-C 227 ; WX 303 ; N ordfeminine ; B 75 276 381 737 ;
-C 232 ; WX 501 ; N Lslash ; B 28 0 501 718 ;
-C 233 ; WX 638 ; N Oslash ; B 29 -27 733 745 ;
-C 234 ; WX 820 ; N OE ; B 81 -19 913 737 ;
-C 235 ; WX 299 ; N ordmasculine ; B 75 276 398 737 ;
-C 241 ; WX 729 ; N ae ; B 46 -14 757 546 ;
-C 245 ; WX 228 ; N dotlessi ; B 57 0 264 532 ;
-C 248 ; WX 228 ; N lslash ; B 33 0 334 718 ;
-C 249 ; WX 501 ; N oslash ; B 18 -29 575 560 ;
-C 250 ; WX 774 ; N oe ; B 67 -14 801 546 ;
-C 251 ; WX 501 ; N germandbls ; B 57 -14 539 731 ;
-C -1 ; WX 501 ; N Zcaron ; B 20 0 604 936 ;
-C -1 ; WX 456 ; N ccedilla ; B 65 -228 491 546 ;
-C -1 ; WX 456 ; N ydieresis ; B 34 -214 535 729 ;
-C -1 ; WX 456 ; N atilde ; B 45 -14 507 737 ;
-C -1 ; WX 228 ; N icircumflex ; B 57 0 364 750 ;
-C -1 ; WX 273 ; N threesuperior ; B 75 271 361 710 ;
-C -1 ; WX 456 ; N ecircumflex ; B 58 -14 486 750 ;
-C -1 ; WX 501 ; N thorn ; B 15 -208 529 718 ;
-C -1 ; WX 456 ; N egrave ; B 58 -14 486 750 ;
-C -1 ; WX 273 ; N twosuperior ; B 57 283 368 710 ;
-C -1 ; WX 456 ; N eacute ; B 58 -14 514 750 ;
-C -1 ; WX 501 ; N otilde ; B 67 -14 529 737 ;
-C -1 ; WX 592 ; N Aacute ; B 16 0 615 936 ;
-C -1 ; WX 501 ; N ocircumflex ; B 67 -14 527 750 ;
-C -1 ; WX 456 ; N yacute ; B 34 -214 535 750 ;
-C -1 ; WX 501 ; N udieresis ; B 80 -14 540 729 ;
-C -1 ; WX 684 ; N threequarters ; B 82 -19 688 710 ;
-C -1 ; WX 456 ; N acircumflex ; B 45 -14 478 750 ;
-C -1 ; WX 592 ; N Eth ; B 51 0 637 718 ;
-C -1 ; WX 456 ; N edieresis ; B 58 -14 487 729 ;
-C -1 ; WX 501 ; N ugrave ; B 80 -14 540 750 ;
-C -1 ; WX 820 ; N trademark ; B 146 306 909 718 ;
-C -1 ; WX 501 ; N ograve ; B 67 -14 527 750 ;
-C -1 ; WX 456 ; N scaron ; B 52 -14 504 750 ;
-C -1 ; WX 228 ; N Idieresis ; B 52 0 405 915 ;
-C -1 ; WX 501 ; N uacute ; B 80 -14 540 750 ;
-C -1 ; WX 456 ; N agrave ; B 45 -14 478 750 ;
-C -1 ; WX 501 ; N ntilde ; B 53 0 529 737 ;
-C -1 ; WX 456 ; N aring ; B 45 -14 478 776 ;
-C -1 ; WX 410 ; N zcaron ; B 16 0 481 750 ;
-C -1 ; WX 228 ; N Icircumflex ; B 52 0 397 936 ;
-C -1 ; WX 592 ; N Ntilde ; B 57 0 661 923 ;
-C -1 ; WX 501 ; N ucircumflex ; B 80 -14 540 750 ;
-C -1 ; WX 547 ; N Ecircumflex ; B 62 0 620 936 ;
-C -1 ; WX 228 ; N Iacute ; B 52 0 433 936 ;
-C -1 ; WX 592 ; N Ccedilla ; B 88 -228 647 737 ;
-C -1 ; WX 638 ; N Odieresis ; B 88 -19 675 915 ;
-C -1 ; WX 547 ; N Scaron ; B 66 -19 588 936 ;
-C -1 ; WX 547 ; N Edieresis ; B 62 0 620 915 ;
-C -1 ; WX 228 ; N Igrave ; B 52 0 301 936 ;
-C -1 ; WX 456 ; N adieresis ; B 45 -14 487 729 ;
-C -1 ; WX 638 ; N Ograve ; B 88 -19 675 936 ;
-C -1 ; WX 547 ; N Egrave ; B 62 0 620 936 ;
-C -1 ; WX 547 ; N Ydieresis ; B 137 0 661 915 ;
-C -1 ; WX 604 ; N registered ; B 45 -19 684 737 ;
-C -1 ; WX 638 ; N Otilde ; B 88 -19 675 923 ;
-C -1 ; WX 684 ; N onequarter ; B 108 -19 661 710 ;
-C -1 ; WX 592 ; N Ugrave ; B 96 -19 659 936 ;
-C -1 ; WX 592 ; N Ucircumflex ; B 96 -19 659 936 ;
-C -1 ; WX 547 ; N Thorn ; B 62 0 588 718 ;
-C -1 ; WX 479 ; N divide ; B 67 -42 500 548 ;
-C -1 ; WX 592 ; N Atilde ; B 16 0 608 923 ;
-C -1 ; WX 592 ; N Uacute ; B 96 -19 659 936 ;
-C -1 ; WX 638 ; N Ocircumflex ; B 88 -19 675 936 ;
-C -1 ; WX 479 ; N logicalnot ; B 86 108 519 419 ;
-C -1 ; WX 592 ; N Aring ; B 16 0 576 962 ;
-C -1 ; WX 228 ; N idieresis ; B 57 0 373 729 ;
-C -1 ; WX 228 ; N iacute ; B 57 0 400 750 ;
-C -1 ; WX 456 ; N aacute ; B 45 -14 514 750 ;
-C -1 ; WX 479 ; N plusminus ; B 33 0 512 506 ;
-C -1 ; WX 479 ; N multiply ; B 47 1 520 505 ;
-C -1 ; WX 592 ; N Udieresis ; B 96 -19 659 915 ;
-C -1 ; WX 479 ; N minus ; B 67 197 500 309 ;
-C -1 ; WX 273 ; N onesuperior ; B 121 283 318 710 ;
-C -1 ; WX 547 ; N Eacute ; B 62 0 620 936 ;
-C -1 ; WX 592 ; N Acircumflex ; B 16 0 579 936 ;
-C -1 ; WX 604 ; N copyright ; B 46 -19 685 737 ;
-C -1 ; WX 592 ; N Agrave ; B 16 0 576 936 ;
-C -1 ; WX 501 ; N odieresis ; B 67 -14 527 729 ;
-C -1 ; WX 501 ; N oacute ; B 67 -14 537 750 ;
-C -1 ; WX 328 ; N degree ; B 143 426 383 712 ;
-C -1 ; WX 228 ; N igrave ; B 57 0 268 750 ;
-C -1 ; WX 501 ; N mu ; B 18 -207 540 532 ;
-C -1 ; WX 638 ; N Oacute ; B 88 -19 675 936 ;
-C -1 ; WX 501 ; N eth ; B 67 -14 549 737 ;
-C -1 ; WX 592 ; N Adieresis ; B 16 0 588 915 ;
-C -1 ; WX 547 ; N Yacute ; B 137 0 661 936 ;
-C -1 ; WX 230 ; N brokenbar ; B 66 -19 289 737 ;
-C -1 ; WX 684 ; N onehalf ; B 108 -19 704 710 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 209
-
-KPX A y -30
-KPX A w -30
-KPX A v -40
-KPX A u -30
-KPX A Y -110
-KPX A W -60
-KPX A V -80
-KPX A U -50
-KPX A T -90
-KPX A Q -40
-KPX A O -40
-KPX A G -50
-KPX A C -40
-
-KPX B U -10
-KPX B A -30
-
-KPX D period -30
-KPX D comma -30
-KPX D Y -70
-KPX D W -40
-KPX D V -40
-KPX D A -40
-
-KPX F period -100
-KPX F comma -100
-KPX F a -20
-KPX F A -80
-
-KPX J u -20
-KPX J period -20
-KPX J comma -20
-KPX J A -20
-
-KPX K y -40
-KPX K u -30
-KPX K o -35
-KPX K e -15
-KPX K O -30
-
-KPX L y -30
-KPX L quoteright -140
-KPX L quotedblright -140
-KPX L Y -120
-KPX L W -80
-KPX L V -110
-KPX L T -90
-
-KPX O period -40
-KPX O comma -40
-KPX O Y -70
-KPX O X -50
-KPX O W -50
-KPX O V -50
-KPX O T -40
-KPX O A -50
-
-KPX P period -120
-KPX P o -40
-KPX P e -30
-KPX P comma -120
-KPX P a -30
-KPX P A -100
-
-KPX Q period 20
-KPX Q comma 20
-KPX Q U -10
-
-KPX R Y -50
-KPX R W -40
-KPX R V -50
-KPX R U -20
-KPX R T -20
-KPX R O -20
-
-KPX T y -60
-KPX T w -60
-KPX T u -90
-KPX T semicolon -40
-KPX T r -80
-KPX T period -80
-KPX T o -80
-KPX T hyphen -120
-KPX T e -60
-KPX T comma -80
-KPX T colon -40
-KPX T a -80
-KPX T O -40
-KPX T A -90
-
-KPX U period -30
-KPX U comma -30
-KPX U A -50
-
-KPX V u -60
-KPX V semicolon -40
-KPX V period -120
-KPX V o -90
-KPX V hyphen -80
-KPX V e -50
-KPX V comma -120
-KPX V colon -40
-KPX V a -60
-KPX V O -50
-KPX V G -50
-KPX V A -80
-
-KPX W y -20
-KPX W u -45
-KPX W semicolon -10
-KPX W period -80
-KPX W o -60
-KPX W hyphen -40
-KPX W e -35
-KPX W comma -80
-KPX W colon -10
-KPX W a -40
-KPX W O -20
-KPX W A -60
-
-KPX Y u -100
-KPX Y semicolon -50
-KPX Y period -100
-KPX Y o -100
-KPX Y e -80
-KPX Y comma -100
-KPX Y colon -50
-KPX Y a -90
-KPX Y O -70
-KPX Y A -110
-
-KPX a y -20
-KPX a w -15
-KPX a v -15
-KPX a g -10
-
-KPX b y -20
-KPX b v -20
-KPX b u -20
-KPX b l -10
-
-KPX c y -10
-KPX c l -20
-KPX c k -20
-KPX c h -10
-
-KPX colon space -40
-
-KPX comma space -40
-KPX comma quoteright -120
-KPX comma quotedblright -120
-
-KPX d y -15
-KPX d w -15
-KPX d v -15
-KPX d d -10
-
-KPX e y -15
-KPX e x -15
-KPX e w -15
-KPX e v -15
-KPX e period 20
-KPX e comma 10
-
-KPX f quoteright 30
-KPX f quotedblright 30
-KPX f period -10
-KPX f o -20
-KPX f e -10
-KPX f comma -10
-
-KPX g g -10
-KPX g e 10
-
-KPX h y -20
-
-KPX k o -15
-
-KPX l y -15
-KPX l w -15
-
-KPX m y -30
-KPX m u -20
-
-KPX n y -20
-KPX n v -40
-KPX n u -10
-
-KPX o y -20
-KPX o x -30
-KPX o w -15
-KPX o v -20
-
-KPX p y -15
-
-KPX period space -40
-KPX period quoteright -120
-KPX period quotedblright -120
-
-KPX quotedblright space -80
-
-KPX quoteleft quoteleft -46
-
-KPX quoteright v -20
-KPX quoteright space -80
-KPX quoteright s -60
-KPX quoteright r -40
-KPX quoteright quoteright -46
-KPX quoteright l -20
-KPX quoteright d -80
-
-KPX r y 10
-KPX r v 10
-KPX r t 20
-KPX r s -15
-KPX r q -20
-KPX r period -60
-KPX r o -20
-KPX r hyphen -20
-KPX r g -15
-KPX r d -20
-KPX r comma -60
-KPX r c -20
-
-KPX s w -15
-
-KPX semicolon space -40
-
-KPX space quoteleft -60
-KPX space quotedblleft -80
-KPX space Y -120
-KPX space W -80
-KPX space V -80
-KPX space T -100
-
-KPX v period -80
-KPX v o -30
-KPX v comma -80
-KPX v a -20
-
-KPX w period -40
-KPX w o -20
-KPX w comma -40
-
-KPX x e -10
-
-KPX y period -80
-KPX y o -25
-KPX y e -10
-KPX y comma -80
-KPX y a -30
-
-KPX z e 10
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 192 186 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 192 186 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 192 186 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 192 186 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 192 186 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 192 186 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 176 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 169 186 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 169 186 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 169 186 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 169 186 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 10 186 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 10 186 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 10 186 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 10 186 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 192 186 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 215 186 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 215 186 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 215 186 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 215 186 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 186 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 169 186 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 192 186 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 192 186 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 192 186 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 192 186 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 169 186 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 169 186 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 146 186 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 92 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 92 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 92 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 92 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 92 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 92 0 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 108 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 92 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 92 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 92 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -22 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -22 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -22 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -22 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 114 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 114 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 114 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 114 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 114 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 114 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 92 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 114 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 114 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 114 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 114 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 92 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 92 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 69 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvl8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvl8a.afm
deleted file mode 100644
index b02ffacbf9..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvl8a.afm
+++ /dev/null
@@ -1,445 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1988 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date:Mon Jan 11 16:46:06 PST 1988
-FontName Helvetica-Light
-EncodingScheme AdobeStandardEncoding
-FullName Helvetica Light
-FamilyName Helvetica
-Weight Light
-ItalicAngle 0.0
-IsFixedPitch false
-UnderlinePosition -90
-UnderlineThickness 58
-Version 001.002
-Notice Copyright (c) 1985, 1987, 1988 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype Company.
-FontBBox -164 -212 1000 979
-CapHeight 720
-XHeight 518
-Descender -204
-Ascender 720
-StartCharMetrics 228
-C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 130 0 203 720 ;
-C 34 ; WX 278 ; N quotedbl ; B 57 494 220 720 ;
-C 35 ; WX 556 ; N numbersign ; B 27 0 530 698 ;
-C 36 ; WX 556 ; N dollar ; B 37 -95 518 766 ;
-C 37 ; WX 889 ; N percent ; B 67 -14 821 705 ;
-C 38 ; WX 667 ; N ampersand ; B 41 -19 644 720 ;
-C 39 ; WX 222 ; N quoteright ; B 80 495 153 720 ;
-C 40 ; WX 333 ; N parenleft ; B 55 -191 277 739 ;
-C 41 ; WX 333 ; N parenright ; B 56 -191 278 739 ;
-C 42 ; WX 389 ; N asterisk ; B 44 434 344 720 ;
-C 43 ; WX 660 ; N plus ; B 80 0 580 500 ;
-C 44 ; WX 278 ; N comma ; B 102 -137 175 88 ;
-C 45 ; WX 333 ; N hyphen ; B 40 229 293 291 ;
-C 46 ; WX 278 ; N period ; B 102 0 175 88 ;
-C 47 ; WX 278 ; N slash ; B -3 -90 288 739 ;
-C 48 ; WX 556 ; N zero ; B 39 -14 516 705 ;
-C 49 ; WX 556 ; N one ; B 120 0 366 705 ;
-C 50 ; WX 556 ; N two ; B 48 0 515 705 ;
-C 51 ; WX 556 ; N three ; B 34 -14 512 705 ;
-C 52 ; WX 556 ; N four ; B 36 0 520 698 ;
-C 53 ; WX 556 ; N five ; B 35 -14 506 698 ;
-C 54 ; WX 556 ; N six ; B 41 -14 514 705 ;
-C 55 ; WX 556 ; N seven ; B 59 0 508 698 ;
-C 56 ; WX 556 ; N eight ; B 44 -14 512 705 ;
-C 57 ; WX 556 ; N nine ; B 41 -14 515 705 ;
-C 58 ; WX 278 ; N colon ; B 102 0 175 492 ;
-C 59 ; WX 278 ; N semicolon ; B 102 -137 175 492 ;
-C 60 ; WX 660 ; N less ; B 80 -6 580 505 ;
-C 61 ; WX 660 ; N equal ; B 80 124 580 378 ;
-C 62 ; WX 660 ; N greater ; B 80 -6 580 505 ;
-C 63 ; WX 500 ; N question ; B 37 0 472 739 ;
-C 64 ; WX 800 ; N at ; B 40 -19 760 739 ;
-C 65 ; WX 667 ; N A ; B 15 0 651 720 ;
-C 66 ; WX 667 ; N B ; B 81 0 610 720 ;
-C 67 ; WX 722 ; N C ; B 48 -19 670 739 ;
-C 68 ; WX 722 ; N D ; B 81 0 669 720 ;
-C 69 ; WX 611 ; N E ; B 81 0 570 720 ;
-C 70 ; WX 556 ; N F ; B 74 0 538 720 ;
-C 71 ; WX 778 ; N G ; B 53 -19 695 739 ;
-C 72 ; WX 722 ; N H ; B 80 0 642 720 ;
-C 73 ; WX 278 ; N I ; B 105 0 173 720 ;
-C 74 ; WX 500 ; N J ; B 22 -19 415 720 ;
-C 75 ; WX 667 ; N K ; B 85 0 649 720 ;
-C 76 ; WX 556 ; N L ; B 81 0 535 720 ;
-C 77 ; WX 833 ; N M ; B 78 0 755 720 ;
-C 78 ; WX 722 ; N N ; B 79 0 642 720 ;
-C 79 ; WX 778 ; N O ; B 53 -19 724 739 ;
-C 80 ; WX 611 ; N P ; B 78 0 576 720 ;
-C 81 ; WX 778 ; N Q ; B 48 -52 719 739 ;
-C 82 ; WX 667 ; N R ; B 80 0 612 720 ;
-C 83 ; WX 611 ; N S ; B 43 -19 567 739 ;
-C 84 ; WX 556 ; N T ; B 16 0 540 720 ;
-C 85 ; WX 722 ; N U ; B 82 -19 640 720 ;
-C 86 ; WX 611 ; N V ; B 18 0 593 720 ;
-C 87 ; WX 889 ; N W ; B 14 0 875 720 ;
-C 88 ; WX 611 ; N X ; B 18 0 592 720 ;
-C 89 ; WX 611 ; N Y ; B 12 0 598 720 ;
-C 90 ; WX 611 ; N Z ; B 31 0 579 720 ;
-C 91 ; WX 333 ; N bracketleft ; B 91 -191 282 739 ;
-C 92 ; WX 278 ; N backslash ; B -46 0 324 739 ;
-C 93 ; WX 333 ; N bracketright ; B 51 -191 242 739 ;
-C 94 ; WX 660 ; N asciicircum ; B 73 245 586 698 ;
-C 95 ; WX 500 ; N underscore ; B 0 -119 500 -61 ;
-C 96 ; WX 222 ; N quoteleft ; B 69 495 142 720 ;
-C 97 ; WX 556 ; N a ; B 46 -14 534 532 ;
-C 98 ; WX 611 ; N b ; B 79 -14 555 720 ;
-C 99 ; WX 556 ; N c ; B 47 -14 508 532 ;
-C 100 ; WX 611 ; N d ; B 56 -14 532 720 ;
-C 101 ; WX 556 ; N e ; B 45 -14 511 532 ;
-C 102 ; WX 278 ; N f ; B 20 0 257 734 ; L i fi ; L l fl ;
-C 103 ; WX 611 ; N g ; B 56 -212 532 532 ;
-C 104 ; WX 556 ; N h ; B 72 0 483 720 ;
-C 105 ; WX 222 ; N i ; B 78 0 144 720 ;
-C 106 ; WX 222 ; N j ; B 5 -204 151 720 ;
-C 107 ; WX 500 ; N k ; B 68 0 487 720 ;
-C 108 ; WX 222 ; N l ; B 81 0 141 720 ;
-C 109 ; WX 833 ; N m ; B 64 0 768 532 ;
-C 110 ; WX 556 ; N n ; B 72 0 483 532 ;
-C 111 ; WX 556 ; N o ; B 38 -14 518 532 ;
-C 112 ; WX 611 ; N p ; B 79 -204 555 532 ;
-C 113 ; WX 611 ; N q ; B 56 -204 532 532 ;
-C 114 ; WX 333 ; N r ; B 75 0 306 532 ;
-C 115 ; WX 500 ; N s ; B 46 -14 454 532 ;
-C 116 ; WX 278 ; N t ; B 20 -14 254 662 ;
-C 117 ; WX 556 ; N u ; B 72 -14 483 518 ;
-C 118 ; WX 500 ; N v ; B 17 0 483 518 ;
-C 119 ; WX 722 ; N w ; B 15 0 707 518 ;
-C 120 ; WX 500 ; N x ; B 18 0 481 518 ;
-C 121 ; WX 500 ; N y ; B 18 -204 482 518 ;
-C 122 ; WX 500 ; N z ; B 33 0 467 518 ;
-C 123 ; WX 333 ; N braceleft ; B 45 -191 279 739 ;
-C 124 ; WX 222 ; N bar ; B 81 0 141 739 ;
-C 125 ; WX 333 ; N braceright ; B 51 -187 285 743 ;
-C 126 ; WX 660 ; N asciitilde ; B 80 174 580 339 ;
-C 161 ; WX 333 ; N exclamdown ; B 130 -187 203 532 ;
-C 162 ; WX 556 ; N cent ; B 45 -141 506 647 ;
-C 163 ; WX 556 ; N sterling ; B 25 -14 530 705 ;
-C 164 ; WX 167 ; N fraction ; B -164 -14 331 705 ;
-C 165 ; WX 556 ; N yen ; B 4 0 552 720 ;
-C 166 ; WX 556 ; N florin ; B 13 -196 539 734 ;
-C 167 ; WX 556 ; N section ; B 48 -181 508 739 ;
-C 168 ; WX 556 ; N currency ; B 27 50 529 553 ;
-C 169 ; WX 222 ; N quotesingle ; B 85 494 137 720 ;
-C 170 ; WX 389 ; N quotedblleft ; B 86 495 310 720 ;
-C 171 ; WX 556 ; N guillemotleft ; B 113 117 443 404 ;
-C 172 ; WX 389 ; N guilsinglleft ; B 121 117 267 404 ;
-C 173 ; WX 389 ; N guilsinglright ; B 122 117 268 404 ;
-C 174 ; WX 500 ; N fi ; B 13 0 435 734 ;
-C 175 ; WX 500 ; N fl ; B 13 0 432 734 ;
-C 177 ; WX 500 ; N endash ; B 0 238 500 282 ;
-C 178 ; WX 556 ; N dagger ; B 37 -166 519 720 ;
-C 179 ; WX 556 ; N daggerdbl ; B 37 -166 519 720 ;
-C 180 ; WX 278 ; N periodcentered ; B 90 301 187 398 ;
-C 182 ; WX 650 ; N paragraph ; B 66 -146 506 720 ;
-C 183 ; WX 500 ; N bullet ; B 70 180 430 540 ;
-C 184 ; WX 222 ; N quotesinglbase ; B 80 -137 153 88 ;
-C 185 ; WX 389 ; N quotedblbase ; B 79 -137 303 88 ;
-C 186 ; WX 389 ; N quotedblright ; B 79 495 303 720 ;
-C 187 ; WX 556 ; N guillemotright ; B 113 117 443 404 ;
-C 188 ; WX 1000 ; N ellipsis ; B 131 0 870 88 ;
-C 189 ; WX 1000 ; N perthousand ; B 14 -14 985 705 ;
-C 191 ; WX 500 ; N questiondown ; B 28 -207 463 532 ;
-C 193 ; WX 333 ; N grave ; B 45 574 234 713 ;
-C 194 ; WX 333 ; N acute ; B 109 574 297 713 ;
-C 195 ; WX 333 ; N circumflex ; B 24 574 318 713 ;
-C 196 ; WX 333 ; N tilde ; B 16 586 329 688 ;
-C 197 ; WX 333 ; N macron ; B 23 612 319 657 ;
-C 198 ; WX 333 ; N breve ; B 28 580 316 706 ;
-C 199 ; WX 333 ; N dotaccent ; B 134 584 199 686 ;
-C 200 ; WX 333 ; N dieresis ; B 60 584 284 686 ;
-C 202 ; WX 333 ; N ring ; B 67 578 266 777 ;
-C 203 ; WX 333 ; N cedilla ; B 54 -207 257 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 109 574 459 713 ;
-C 206 ; WX 333 ; N ogonek ; B 74 -190 228 0 ;
-C 207 ; WX 333 ; N caron ; B 24 574 318 713 ;
-C 208 ; WX 1000 ; N emdash ; B 0 238 1000 282 ;
-C 225 ; WX 1000 ; N AE ; B 5 0 960 720 ;
-C 227 ; WX 334 ; N ordfeminine ; B 8 307 325 739 ;
-C 232 ; WX 556 ; N Lslash ; B 0 0 535 720 ;
-C 233 ; WX 778 ; N Oslash ; B 42 -37 736 747 ;
-C 234 ; WX 1000 ; N OE ; B 41 -19 967 739 ;
-C 235 ; WX 334 ; N ordmasculine ; B 11 307 323 739 ;
-C 241 ; WX 889 ; N ae ; B 39 -14 847 532 ;
-C 245 ; WX 222 ; N dotlessi ; B 78 0 138 518 ;
-C 248 ; WX 222 ; N lslash ; B 10 0 212 720 ;
-C 249 ; WX 556 ; N oslash ; B 35 -23 521 541 ;
-C 250 ; WX 944 ; N oe ; B 36 -14 904 532 ;
-C 251 ; WX 500 ; N germandbls ; B 52 -14 459 734 ;
-C -1 ; WX 667 ; N Aacute ; B 15 0 651 915 ;
-C -1 ; WX 667 ; N Acircumflex ; B 15 0 651 915 ;
-C -1 ; WX 667 ; N Adieresis ; B 15 0 651 888 ;
-C -1 ; WX 667 ; N Agrave ; B 15 0 651 915 ;
-C -1 ; WX 667 ; N Aring ; B 15 0 651 979 ;
-C -1 ; WX 667 ; N Atilde ; B 15 0 651 890 ;
-C -1 ; WX 722 ; N Ccedilla ; B 48 -207 670 739 ;
-C -1 ; WX 611 ; N Eacute ; B 81 0 570 915 ;
-C -1 ; WX 611 ; N Ecircumflex ; B 81 0 570 915 ;
-C -1 ; WX 611 ; N Edieresis ; B 81 0 570 888 ;
-C -1 ; WX 611 ; N Egrave ; B 81 0 570 915 ;
-C -1 ; WX 722 ; N Eth ; B 10 0 669 720 ;
-C -1 ; WX 278 ; N Iacute ; B 62 0 250 915 ;
-C -1 ; WX 278 ; N Icircumflex ; B -23 0 271 915 ;
-C -1 ; WX 278 ; N Idieresis ; B 13 0 237 888 ;
-C -1 ; WX 278 ; N Igrave ; B 18 0 207 915 ;
-C -1 ; WX 722 ; N Ntilde ; B 79 0 642 890 ;
-C -1 ; WX 778 ; N Oacute ; B 53 -19 724 915 ;
-C -1 ; WX 778 ; N Ocircumflex ; B 53 -19 724 915 ;
-C -1 ; WX 778 ; N Odieresis ; B 53 -19 724 888 ;
-C -1 ; WX 778 ; N Ograve ; B 53 -19 724 915 ;
-C -1 ; WX 778 ; N Otilde ; B 53 -19 724 890 ;
-C -1 ; WX 611 ; N Scaron ; B 43 -19 567 915 ;
-C -1 ; WX 611 ; N Thorn ; B 78 0 576 720 ;
-C -1 ; WX 722 ; N Uacute ; B 82 -19 640 915 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 82 -19 640 915 ;
-C -1 ; WX 722 ; N Udieresis ; B 82 -19 640 888 ;
-C -1 ; WX 722 ; N Ugrave ; B 82 -19 640 915 ;
-C -1 ; WX 611 ; N Yacute ; B 12 0 598 915 ;
-C -1 ; WX 611 ; N Ydieresis ; B 12 0 598 888 ;
-C -1 ; WX 611 ; N Zcaron ; B 31 0 579 915 ;
-C -1 ; WX 556 ; N aacute ; B 46 -14 534 713 ;
-C -1 ; WX 556 ; N acircumflex ; B 46 -14 534 713 ;
-C -1 ; WX 556 ; N adieresis ; B 46 -14 534 686 ;
-C -1 ; WX 556 ; N agrave ; B 46 -14 534 713 ;
-C -1 ; WX 556 ; N aring ; B 46 -14 534 777 ;
-C -1 ; WX 556 ; N atilde ; B 46 -14 534 688 ;
-C -1 ; WX 222 ; N brokenbar ; B 81 0 141 739 ;
-C -1 ; WX 556 ; N ccedilla ; B 47 -207 508 532 ;
-C -1 ; WX 800 ; N copyright ; B 21 -19 779 739 ;
-C -1 ; WX 400 ; N degree ; B 50 405 350 705 ;
-C -1 ; WX 660 ; N divide ; B 80 0 580 500 ;
-C -1 ; WX 556 ; N eacute ; B 45 -14 511 713 ;
-C -1 ; WX 556 ; N ecircumflex ; B 45 -14 511 713 ;
-C -1 ; WX 556 ; N edieresis ; B 45 -14 511 686 ;
-C -1 ; WX 556 ; N egrave ; B 45 -14 511 713 ;
-C -1 ; WX 556 ; N eth ; B 38 -14 518 739 ;
-C -1 ; WX 222 ; N iacute ; B 34 0 222 713 ;
-C -1 ; WX 222 ; N icircumflex ; B -51 0 243 713 ;
-C -1 ; WX 222 ; N idieresis ; B -15 0 209 686 ;
-C -1 ; WX 222 ; N igrave ; B -10 0 179 713 ;
-C -1 ; WX 660 ; N logicalnot ; B 80 112 580 378 ;
-C -1 ; WX 660 ; N minus ; B 80 220 580 280 ;
-C -1 ; WX 556 ; N mu ; B 72 -204 483 518 ;
-C -1 ; WX 660 ; N multiply ; B 83 6 578 500 ;
-C -1 ; WX 556 ; N ntilde ; B 72 0 483 688 ;
-C -1 ; WX 556 ; N oacute ; B 38 -14 518 713 ;
-C -1 ; WX 556 ; N ocircumflex ; B 38 -14 518 713 ;
-C -1 ; WX 556 ; N odieresis ; B 38 -14 518 686 ;
-C -1 ; WX 556 ; N ograve ; B 38 -14 518 713 ;
-C -1 ; WX 834 ; N onehalf ; B 40 -14 794 739 ;
-C -1 ; WX 834 ; N onequarter ; B 40 -14 794 739 ;
-C -1 ; WX 333 ; N onesuperior ; B 87 316 247 739 ;
-C -1 ; WX 556 ; N otilde ; B 38 -14 518 688 ;
-C -1 ; WX 660 ; N plusminus ; B 80 0 580 500 ;
-C -1 ; WX 800 ; N registered ; B 21 -19 779 739 ;
-C -1 ; WX 500 ; N scaron ; B 46 -14 454 713 ;
-C -1 ; WX 611 ; N thorn ; B 79 -204 555 720 ;
-C -1 ; WX 834 ; N threequarters ; B 40 -14 794 739 ;
-C -1 ; WX 333 ; N threesuperior ; B 11 308 322 739 ;
-C -1 ; WX 940 ; N trademark ; B 29 299 859 720 ;
-C -1 ; WX 333 ; N twosuperior ; B 15 316 318 739 ;
-C -1 ; WX 556 ; N uacute ; B 72 -14 483 713 ;
-C -1 ; WX 556 ; N ucircumflex ; B 72 -14 483 713 ;
-C -1 ; WX 556 ; N udieresis ; B 72 -14 483 686 ;
-C -1 ; WX 556 ; N ugrave ; B 72 -14 483 713 ;
-C -1 ; WX 500 ; N yacute ; B 18 -204 482 713 ;
-C -1 ; WX 500 ; N ydieresis ; B 18 -204 482 686 ;
-C -1 ; WX 500 ; N zcaron ; B 33 0 467 713 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 115
-
-KPX A y -18
-KPX A w -18
-KPX A v -18
-KPX A quoteright -74
-KPX A Y -74
-KPX A W -37
-KPX A V -74
-KPX A T -92
-
-KPX F period -129
-KPX F comma -129
-KPX F A -55
-
-KPX L y -37
-KPX L quoteright -74
-KPX L Y -111
-KPX L W -55
-KPX L V -92
-KPX L T -92
-
-KPX P period -129
-KPX P comma -129
-KPX P A -74
-
-KPX R y 0
-KPX R Y -37
-KPX R W -18
-KPX R V -18
-KPX R T -18
-
-KPX T y -84
-KPX T w -84
-KPX T u -92
-KPX T semicolon -111
-KPX T s -111
-KPX T r -92
-KPX T period -111
-KPX T o -111
-KPX T i 0
-KPX T hyphen -129
-KPX T e -111
-KPX T comma -111
-KPX T colon -111
-KPX T c -111
-KPX T a -111
-KPX T A -92
-
-KPX V y -18
-KPX V u -37
-KPX V semicolon -74
-KPX V r -37
-KPX V period -129
-KPX V o -55
-KPX V i -18
-KPX V hyphen -55
-KPX V e -55
-KPX V comma -129
-KPX V colon -74
-KPX V a -55
-KPX V A -74
-
-KPX W y 0
-KPX W u -18
-KPX W semicolon -18
-KPX W r -18
-KPX W period -74
-KPX W o -18
-KPX W i 0
-KPX W hyphen 0
-KPX W e -18
-KPX W comma -74
-KPX W colon -18
-KPX W a -37
-KPX W A -37
-
-KPX Y v -40
-KPX Y u -37
-KPX Y semicolon -92
-KPX Y q -92
-KPX Y period -111
-KPX Y p -37
-KPX Y o -92
-KPX Y i -20
-KPX Y hyphen -111
-KPX Y e -92
-KPX Y comma -111
-KPX Y colon -92
-KPX Y a -92
-KPX Y A -74
-
-KPX f quoteright 18
-KPX f f -18
-
-KPX quoteleft quoteleft -18
-
-KPX quoteright t -18
-KPX quoteright s -74
-KPX quoteright quoteright -18
-
-KPX r z 0
-KPX r y 18
-KPX r x 0
-KPX r w 0
-KPX r v 0
-KPX r u 0
-KPX r t 18
-KPX r r 0
-KPX r quoteright 0
-KPX r q -18
-KPX r period -92
-KPX r o -18
-KPX r n 18
-KPX r m 18
-KPX r hyphen -55
-KPX r h 0
-KPX r g 0
-KPX r f 18
-KPX r e -18
-KPX r d -18
-KPX r comma -92
-KPX r c -18
-
-KPX v period -74
-KPX v comma -74
-
-KPX w period -55
-KPX w comma -55
-
-KPX y period -92
-KPX y comma -92
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 202 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 83 0 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 139 202 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 83 0 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 194 0 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 111 0 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 139 202 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 83 0 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 139 202 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 83 0 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 202 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 202 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 202 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 202 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 111 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 111 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 111 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 111 0 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute -47 202 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -47 202 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -47 202 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 202 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -75 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -75 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -75 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -55 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 202 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 202 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 202 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 202 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 111 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 111 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 111 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 111 0 ;
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 167 202 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 167 202 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 202 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 167 202 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 111 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 111 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 111 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 111 0 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 222 202 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 222 202 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 222 202 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 222 202 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 111 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 111 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 111 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 111 0 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 202 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 111 0 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 194 202 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 111 0 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 222 202 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 111 0 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 187 202 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 111 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvlo8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvlo8a.afm
deleted file mode 100644
index 96612d12ff..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvlo8a.afm
+++ /dev/null
@@ -1,445 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1988 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date:Mon Jan 11 17:38:44 PST 1988
-FontName Helvetica-LightOblique
-EncodingScheme AdobeStandardEncoding
-FullName Helvetica Light Oblique
-FamilyName Helvetica
-Weight Light
-ItalicAngle -12.0
-IsFixedPitch false
-UnderlinePosition -90
-UnderlineThickness 58
-Version 001.002
-Notice Copyright (c) 1985, 1987, 1988 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype Company.
-FontBBox -167 -212 1110 979
-CapHeight 720
-XHeight 518
-Descender -204
-Ascender 720
-StartCharMetrics 228
-C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 130 0 356 720 ;
-C 34 ; WX 278 ; N quotedbl ; B 162 494 373 720 ;
-C 35 ; WX 556 ; N numbersign ; B 75 0 633 698 ;
-C 36 ; WX 556 ; N dollar ; B 75 -95 613 766 ;
-C 37 ; WX 889 ; N percent ; B 176 -14 860 705 ;
-C 38 ; WX 667 ; N ampersand ; B 77 -19 646 720 ;
-C 39 ; WX 222 ; N quoteright ; B 185 495 306 720 ;
-C 40 ; WX 333 ; N parenleft ; B 97 -191 434 739 ;
-C 41 ; WX 333 ; N parenright ; B 15 -191 353 739 ;
-C 42 ; WX 389 ; N asterisk ; B 172 434 472 720 ;
-C 43 ; WX 660 ; N plus ; B 127 0 640 500 ;
-C 44 ; WX 278 ; N comma ; B 73 -137 194 88 ;
-C 45 ; WX 333 ; N hyphen ; B 89 229 355 291 ;
-C 46 ; WX 278 ; N period ; B 102 0 194 88 ;
-C 47 ; WX 278 ; N slash ; B -22 -90 445 739 ;
-C 48 ; WX 556 ; N zero ; B 93 -14 609 705 ;
-C 49 ; WX 556 ; N one ; B 231 0 516 705 ;
-C 50 ; WX 556 ; N two ; B 48 0 628 705 ;
-C 51 ; WX 556 ; N three ; B 74 -14 605 705 ;
-C 52 ; WX 556 ; N four ; B 73 0 570 698 ;
-C 53 ; WX 556 ; N five ; B 71 -14 616 698 ;
-C 54 ; WX 556 ; N six ; B 94 -14 617 705 ;
-C 55 ; WX 556 ; N seven ; B 152 0 656 698 ;
-C 56 ; WX 556 ; N eight ; B 80 -14 601 705 ;
-C 57 ; WX 556 ; N nine ; B 84 -14 607 705 ;
-C 58 ; WX 278 ; N colon ; B 102 0 280 492 ;
-C 59 ; WX 278 ; N semicolon ; B 73 -137 280 492 ;
-C 60 ; WX 660 ; N less ; B 129 -6 687 505 ;
-C 61 ; WX 660 ; N equal ; B 106 124 660 378 ;
-C 62 ; WX 660 ; N greater ; B 79 -6 640 505 ;
-C 63 ; WX 500 ; N question ; B 148 0 594 739 ;
-C 64 ; WX 800 ; N at ; B 108 -19 857 739 ;
-C 65 ; WX 667 ; N A ; B 15 0 651 720 ;
-C 66 ; WX 667 ; N B ; B 81 0 697 720 ;
-C 67 ; WX 722 ; N C ; B 111 -19 771 739 ;
-C 68 ; WX 722 ; N D ; B 81 0 758 720 ;
-C 69 ; WX 611 ; N E ; B 81 0 713 720 ;
-C 70 ; WX 556 ; N F ; B 74 0 691 720 ;
-C 71 ; WX 778 ; N G ; B 116 -19 796 739 ;
-C 72 ; WX 722 ; N H ; B 80 0 795 720 ;
-C 73 ; WX 278 ; N I ; B 105 0 326 720 ;
-C 74 ; WX 500 ; N J ; B 58 -19 568 720 ;
-C 75 ; WX 667 ; N K ; B 85 0 752 720 ;
-C 76 ; WX 556 ; N L ; B 81 0 547 720 ;
-C 77 ; WX 833 ; N M ; B 78 0 908 720 ;
-C 78 ; WX 722 ; N N ; B 79 0 795 720 ;
-C 79 ; WX 778 ; N O ; B 117 -19 812 739 ;
-C 80 ; WX 611 ; N P ; B 78 0 693 720 ;
-C 81 ; WX 778 ; N Q ; B 112 -52 808 739 ;
-C 82 ; WX 667 ; N R ; B 80 0 726 720 ;
-C 83 ; WX 611 ; N S ; B 82 -19 663 739 ;
-C 84 ; WX 556 ; N T ; B 157 0 693 720 ;
-C 85 ; WX 722 ; N U ; B 129 -19 793 720 ;
-C 86 ; WX 611 ; N V ; B 171 0 746 720 ;
-C 87 ; WX 889 ; N W ; B 167 0 1028 720 ;
-C 88 ; WX 611 ; N X ; B 18 0 734 720 ;
-C 89 ; WX 611 ; N Y ; B 165 0 751 720 ;
-C 90 ; WX 611 ; N Z ; B 31 0 729 720 ;
-C 91 ; WX 333 ; N bracketleft ; B 50 -191 439 739 ;
-C 92 ; WX 278 ; N backslash ; B 111 0 324 739 ;
-C 93 ; WX 333 ; N bracketright ; B 10 -191 399 739 ;
-C 94 ; WX 660 ; N asciicircum ; B 125 245 638 698 ;
-C 95 ; WX 500 ; N underscore ; B -25 -119 487 -61 ;
-C 96 ; WX 222 ; N quoteleft ; B 174 495 295 720 ;
-C 97 ; WX 556 ; N a ; B 71 -14 555 532 ;
-C 98 ; WX 611 ; N b ; B 79 -14 619 720 ;
-C 99 ; WX 556 ; N c ; B 92 -14 576 532 ;
-C 100 ; WX 611 ; N d ; B 101 -14 685 720 ;
-C 101 ; WX 556 ; N e ; B 90 -14 575 532 ;
-C 102 ; WX 278 ; N f ; B 97 0 412 734 ; L i fi ; L l fl ;
-C 103 ; WX 611 ; N g ; B 56 -212 642 532 ;
-C 104 ; WX 556 ; N h ; B 72 0 565 720 ;
-C 105 ; WX 222 ; N i ; B 81 0 297 720 ;
-C 106 ; WX 222 ; N j ; B -38 -204 304 720 ;
-C 107 ; WX 500 ; N k ; B 68 0 574 720 ;
-C 108 ; WX 222 ; N l ; B 81 0 294 720 ;
-C 109 ; WX 833 ; N m ; B 64 0 848 532 ;
-C 110 ; WX 556 ; N n ; B 72 0 565 532 ;
-C 111 ; WX 556 ; N o ; B 84 -14 582 532 ;
-C 112 ; WX 611 ; N p ; B 36 -204 620 532 ;
-C 113 ; WX 611 ; N q ; B 102 -204 642 532 ;
-C 114 ; WX 333 ; N r ; B 75 0 419 532 ;
-C 115 ; WX 500 ; N s ; B 78 -14 519 532 ;
-C 116 ; WX 278 ; N t ; B 108 -14 360 662 ;
-C 117 ; WX 556 ; N u ; B 103 -14 593 518 ;
-C 118 ; WX 500 ; N v ; B 127 0 593 518 ;
-C 119 ; WX 722 ; N w ; B 125 0 817 518 ;
-C 120 ; WX 500 ; N x ; B 18 0 584 518 ;
-C 121 ; WX 500 ; N y ; B 26 -204 592 518 ;
-C 122 ; WX 500 ; N z ; B 33 0 564 518 ;
-C 123 ; WX 333 ; N braceleft ; B 103 -191 436 739 ;
-C 124 ; WX 222 ; N bar ; B 81 0 298 739 ;
-C 125 ; WX 333 ; N braceright ; B 12 -187 344 743 ;
-C 126 ; WX 660 ; N asciitilde ; B 127 174 645 339 ;
-C 161 ; WX 333 ; N exclamdown ; B 90 -187 316 532 ;
-C 162 ; WX 556 ; N cent ; B 90 -141 574 647 ;
-C 163 ; WX 556 ; N sterling ; B 51 -14 613 705 ;
-C 164 ; WX 167 ; N fraction ; B -167 -14 481 705 ;
-C 165 ; WX 556 ; N yen ; B 110 0 705 720 ;
-C 166 ; WX 556 ; N florin ; B -26 -196 691 734 ;
-C 167 ; WX 556 ; N section ; B 91 -181 581 739 ;
-C 168 ; WX 556 ; N currency ; B 55 50 629 553 ;
-C 169 ; WX 222 ; N quotesingle ; B 190 494 290 720 ;
-C 170 ; WX 389 ; N quotedblleft ; B 191 495 463 720 ;
-C 171 ; WX 556 ; N guillemotleft ; B 161 117 529 404 ;
-C 172 ; WX 389 ; N guilsinglleft ; B 169 117 353 404 ;
-C 173 ; WX 389 ; N guilsinglright ; B 147 117 330 404 ;
-C 174 ; WX 500 ; N fi ; B 92 0 588 734 ;
-C 175 ; WX 500 ; N fl ; B 92 0 585 734 ;
-C 177 ; WX 500 ; N endash ; B 51 238 560 282 ;
-C 178 ; WX 556 ; N dagger ; B 130 -166 623 720 ;
-C 179 ; WX 556 ; N daggerdbl ; B 49 -166 625 720 ;
-C 180 ; WX 278 ; N periodcentered ; B 163 301 262 398 ;
-C 182 ; WX 650 ; N paragraph ; B 174 -146 659 720 ;
-C 183 ; WX 500 ; N bullet ; B 142 180 510 540 ;
-C 184 ; WX 222 ; N quotesinglbase ; B 51 -137 172 88 ;
-C 185 ; WX 389 ; N quotedblbase ; B 50 -137 322 88 ;
-C 186 ; WX 389 ; N quotedblright ; B 184 495 456 720 ;
-C 187 ; WX 556 ; N guillemotright ; B 138 117 505 404 ;
-C 188 ; WX 1000 ; N ellipsis ; B 131 0 889 88 ;
-C 189 ; WX 1000 ; N perthousand ; B 83 -14 1020 705 ;
-C 191 ; WX 500 ; N questiondown ; B 19 -207 465 532 ;
-C 193 ; WX 333 ; N grave ; B 197 574 356 713 ;
-C 194 ; WX 333 ; N acute ; B 231 574 449 713 ;
-C 195 ; WX 333 ; N circumflex ; B 146 574 440 713 ;
-C 196 ; WX 333 ; N tilde ; B 141 586 475 688 ;
-C 197 ; WX 333 ; N macron ; B 153 612 459 657 ;
-C 198 ; WX 333 ; N breve ; B 177 580 466 706 ;
-C 199 ; WX 333 ; N dotaccent ; B 258 584 345 686 ;
-C 200 ; WX 333 ; N dieresis ; B 184 584 430 686 ;
-C 202 ; WX 333 ; N ring ; B 209 578 412 777 ;
-C 203 ; WX 333 ; N cedilla ; B 14 -207 233 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 231 574 611 713 ;
-C 206 ; WX 333 ; N ogonek ; B 50 -190 199 0 ;
-C 207 ; WX 333 ; N caron ; B 176 574 470 713 ;
-C 208 ; WX 1000 ; N emdash ; B 51 238 1060 282 ;
-C 225 ; WX 1000 ; N AE ; B 5 0 1101 720 ;
-C 227 ; WX 334 ; N ordfeminine ; B 73 307 423 739 ;
-C 232 ; WX 556 ; N Lslash ; B 68 0 547 720 ;
-C 233 ; WX 778 ; N Oslash ; B 41 -37 887 747 ;
-C 234 ; WX 1000 ; N OE ; B 104 -19 1110 739 ;
-C 235 ; WX 334 ; N ordmasculine ; B 76 307 450 739 ;
-C 241 ; WX 889 ; N ae ; B 63 -14 913 532 ;
-C 245 ; WX 222 ; N dotlessi ; B 78 0 248 518 ;
-C 248 ; WX 222 ; N lslash ; B 74 0 316 720 ;
-C 249 ; WX 556 ; N oslash ; B 36 -23 629 541 ;
-C 250 ; WX 944 ; N oe ; B 82 -14 970 532 ;
-C 251 ; WX 500 ; N germandbls ; B 52 -14 554 734 ;
-C -1 ; WX 667 ; N Aacute ; B 15 0 659 915 ;
-C -1 ; WX 667 ; N Acircumflex ; B 15 0 651 915 ;
-C -1 ; WX 667 ; N Adieresis ; B 15 0 651 888 ;
-C -1 ; WX 667 ; N Agrave ; B 15 0 651 915 ;
-C -1 ; WX 667 ; N Aring ; B 15 0 651 979 ;
-C -1 ; WX 667 ; N Atilde ; B 15 0 685 890 ;
-C -1 ; WX 722 ; N Ccedilla ; B 111 -207 771 739 ;
-C -1 ; WX 611 ; N Eacute ; B 81 0 713 915 ;
-C -1 ; WX 611 ; N Ecircumflex ; B 81 0 713 915 ;
-C -1 ; WX 611 ; N Edieresis ; B 81 0 713 888 ;
-C -1 ; WX 611 ; N Egrave ; B 81 0 713 915 ;
-C -1 ; WX 722 ; N Eth ; B 81 0 758 720 ;
-C -1 ; WX 278 ; N Iacute ; B 105 0 445 915 ;
-C -1 ; WX 278 ; N Icircumflex ; B 105 0 436 915 ;
-C -1 ; WX 278 ; N Idieresis ; B 105 0 426 888 ;
-C -1 ; WX 278 ; N Igrave ; B 105 0 372 915 ;
-C -1 ; WX 722 ; N Ntilde ; B 79 0 795 890 ;
-C -1 ; WX 778 ; N Oacute ; B 117 -19 812 915 ;
-C -1 ; WX 778 ; N Ocircumflex ; B 117 -19 812 915 ;
-C -1 ; WX 778 ; N Odieresis ; B 117 -19 812 888 ;
-C -1 ; WX 778 ; N Ograve ; B 117 -19 812 915 ;
-C -1 ; WX 778 ; N Otilde ; B 117 -19 812 890 ;
-C -1 ; WX 611 ; N Scaron ; B 82 -19 663 915 ;
-C -1 ; WX 611 ; N Thorn ; B 78 0 661 720 ;
-C -1 ; WX 722 ; N Uacute ; B 129 -19 793 915 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 129 -19 793 915 ;
-C -1 ; WX 722 ; N Udieresis ; B 129 -19 793 888 ;
-C -1 ; WX 722 ; N Ugrave ; B 129 -19 793 915 ;
-C -1 ; WX 611 ; N Yacute ; B 165 0 751 915 ;
-C -1 ; WX 611 ; N Ydieresis ; B 165 0 751 888 ;
-C -1 ; WX 611 ; N Zcaron ; B 31 0 729 915 ;
-C -1 ; WX 556 ; N aacute ; B 71 -14 561 713 ;
-C -1 ; WX 556 ; N acircumflex ; B 71 -14 555 713 ;
-C -1 ; WX 556 ; N adieresis ; B 71 -14 555 686 ;
-C -1 ; WX 556 ; N agrave ; B 71 -14 555 713 ;
-C -1 ; WX 556 ; N aring ; B 71 -14 555 777 ;
-C -1 ; WX 556 ; N atilde ; B 71 -14 587 688 ;
-C -1 ; WX 222 ; N brokenbar ; B 81 0 298 739 ;
-C -1 ; WX 556 ; N ccedilla ; B 92 -207 576 532 ;
-C -1 ; WX 800 ; N copyright ; B 89 -19 864 739 ;
-C -1 ; WX 400 ; N degree ; B 165 405 471 705 ;
-C -1 ; WX 660 ; N divide ; B 127 0 640 500 ;
-C -1 ; WX 556 ; N eacute ; B 90 -14 575 713 ;
-C -1 ; WX 556 ; N ecircumflex ; B 90 -14 575 713 ;
-C -1 ; WX 556 ; N edieresis ; B 90 -14 575 686 ;
-C -1 ; WX 556 ; N egrave ; B 90 -14 575 713 ;
-C -1 ; WX 556 ; N eth ; B 84 -14 582 739 ;
-C -1 ; WX 222 ; N iacute ; B 78 0 374 713 ;
-C -1 ; WX 222 ; N icircumflex ; B 71 0 365 713 ;
-C -1 ; WX 222 ; N idieresis ; B 78 0 355 686 ;
-C -1 ; WX 222 ; N igrave ; B 78 0 301 713 ;
-C -1 ; WX 660 ; N logicalnot ; B 148 112 660 378 ;
-C -1 ; WX 660 ; N minus ; B 127 220 640 280 ;
-C -1 ; WX 556 ; N mu ; B 29 -204 593 518 ;
-C -1 ; WX 660 ; N multiply ; B 92 6 677 500 ;
-C -1 ; WX 556 ; N ntilde ; B 72 0 587 688 ;
-C -1 ; WX 556 ; N oacute ; B 84 -14 582 713 ;
-C -1 ; WX 556 ; N ocircumflex ; B 84 -14 582 713 ;
-C -1 ; WX 556 ; N odieresis ; B 84 -14 582 686 ;
-C -1 ; WX 556 ; N ograve ; B 84 -14 582 713 ;
-C -1 ; WX 834 ; N onehalf ; B 125 -14 862 739 ;
-C -1 ; WX 834 ; N onequarter ; B 165 -14 823 739 ;
-C -1 ; WX 333 ; N onesuperior ; B 221 316 404 739 ;
-C -1 ; WX 556 ; N otilde ; B 84 -14 587 688 ;
-C -1 ; WX 660 ; N plusminus ; B 80 0 650 500 ;
-C -1 ; WX 800 ; N registered ; B 89 -19 864 739 ;
-C -1 ; WX 500 ; N scaron ; B 78 -14 554 713 ;
-C -1 ; WX 611 ; N thorn ; B 36 -204 620 720 ;
-C -1 ; WX 834 ; N threequarters ; B 131 -14 853 739 ;
-C -1 ; WX 333 ; N threesuperior ; B 102 308 444 739 ;
-C -1 ; WX 940 ; N trademark ; B 174 299 1012 720 ;
-C -1 ; WX 333 ; N twosuperior ; B 82 316 453 739 ;
-C -1 ; WX 556 ; N uacute ; B 103 -14 593 713 ;
-C -1 ; WX 556 ; N ucircumflex ; B 103 -14 593 713 ;
-C -1 ; WX 556 ; N udieresis ; B 103 -14 593 686 ;
-C -1 ; WX 556 ; N ugrave ; B 103 -14 593 713 ;
-C -1 ; WX 500 ; N yacute ; B 26 -204 592 713 ;
-C -1 ; WX 500 ; N ydieresis ; B 26 -204 592 686 ;
-C -1 ; WX 500 ; N zcaron ; B 33 0 564 713 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 115
-
-KPX A y -18
-KPX A w -18
-KPX A v -18
-KPX A quoteright -74
-KPX A Y -74
-KPX A W -37
-KPX A V -74
-KPX A T -92
-
-KPX F period -129
-KPX F comma -129
-KPX F A -55
-
-KPX L y -37
-KPX L quoteright -74
-KPX L Y -111
-KPX L W -55
-KPX L V -92
-KPX L T -92
-
-KPX P period -129
-KPX P comma -129
-KPX P A -74
-
-KPX R y 0
-KPX R Y -37
-KPX R W -18
-KPX R V -18
-KPX R T -18
-
-KPX T y -84
-KPX T w -84
-KPX T u -92
-KPX T semicolon -111
-KPX T s -111
-KPX T r -92
-KPX T period -111
-KPX T o -111
-KPX T i 0
-KPX T hyphen -129
-KPX T e -111
-KPX T comma -111
-KPX T colon -111
-KPX T c -111
-KPX T a -111
-KPX T A -92
-
-KPX V y -18
-KPX V u -37
-KPX V semicolon -74
-KPX V r -37
-KPX V period -129
-KPX V o -55
-KPX V i -18
-KPX V hyphen -55
-KPX V e -55
-KPX V comma -129
-KPX V colon -74
-KPX V a -55
-KPX V A -74
-
-KPX W y 0
-KPX W u -18
-KPX W semicolon -18
-KPX W r -18
-KPX W period -74
-KPX W o -18
-KPX W i 0
-KPX W hyphen 0
-KPX W e -18
-KPX W comma -74
-KPX W colon -18
-KPX W a -37
-KPX W A -37
-
-KPX Y v -40
-KPX Y u -37
-KPX Y semicolon -92
-KPX Y q -92
-KPX Y period -111
-KPX Y p -37
-KPX Y o -92
-KPX Y i -20
-KPX Y hyphen -111
-KPX Y e -92
-KPX Y comma -111
-KPX Y colon -92
-KPX Y a -92
-KPX Y A -74
-
-KPX f quoteright 18
-KPX f f -18
-
-KPX quoteleft quoteleft -18
-
-KPX quoteright t -18
-KPX quoteright s -74
-KPX quoteright quoteright -18
-
-KPX r z 0
-KPX r y 18
-KPX r x 0
-KPX r w 0
-KPX r v 0
-KPX r u 0
-KPX r t 18
-KPX r r 0
-KPX r quoteright 0
-KPX r q -18
-KPX r period -92
-KPX r o -18
-KPX r n 18
-KPX r m 18
-KPX r hyphen -55
-KPX r h 0
-KPX r g 0
-KPX r f 18
-KPX r e -18
-KPX r d -18
-KPX r comma -92
-KPX r c -18
-
-KPX v period -74
-KPX v comma -74
-
-KPX w period -55
-KPX w comma -55
-
-KPX y period -92
-KPX y comma -92
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 202 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 83 0 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 139 202 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 83 0 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 194 0 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 111 0 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 139 202 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 83 0 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 139 202 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 83 0 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 202 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 202 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 202 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 202 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 111 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 111 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 111 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 111 0 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute -47 202 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -47 202 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -47 202 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 202 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -75 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -75 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -75 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -55 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 202 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 202 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 202 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 202 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 111 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 111 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 111 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 111 0 ;
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 167 202 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 167 202 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 202 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 167 202 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 111 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 111 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 111 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 111 0 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 222 202 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 222 202 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 222 202 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 222 202 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 111 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 111 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 111 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 111 0 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 202 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 111 0 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 194 202 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 111 0 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 222 202 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 111 0 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 187 202 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 111 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvr8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvr8a.afm
deleted file mode 100644
index 1eb3b44856..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvr8a.afm
+++ /dev/null
@@ -1,612 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.
-Comment Creation Date: Thu Mar 15 08:58:00 1990
-Comment UniqueID 28352
-Comment VMusage 26389 33281
-FontName Helvetica
-FullName Helvetica
-FamilyName Helvetica
-Weight Medium
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -166 -225 1000 931
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.006
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 718
-XHeight 523
-Ascender 718
-Descender -207
-StartCharMetrics 228
-C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 278 ; N exclam ; B 90 0 187 718 ;
-C 34 ; WX 355 ; N quotedbl ; B 70 463 285 718 ;
-C 35 ; WX 556 ; N numbersign ; B 28 0 529 688 ;
-C 36 ; WX 556 ; N dollar ; B 32 -115 520 775 ;
-C 37 ; WX 889 ; N percent ; B 39 -19 850 703 ;
-C 38 ; WX 667 ; N ampersand ; B 44 -15 645 718 ;
-C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ;
-C 40 ; WX 333 ; N parenleft ; B 68 -207 299 733 ;
-C 41 ; WX 333 ; N parenright ; B 34 -207 265 733 ;
-C 42 ; WX 389 ; N asterisk ; B 39 431 349 718 ;
-C 43 ; WX 584 ; N plus ; B 39 0 545 505 ;
-C 44 ; WX 278 ; N comma ; B 87 -147 191 106 ;
-C 45 ; WX 333 ; N hyphen ; B 44 232 289 322 ;
-C 46 ; WX 278 ; N period ; B 87 0 191 106 ;
-C 47 ; WX 278 ; N slash ; B -17 -19 295 737 ;
-C 48 ; WX 556 ; N zero ; B 37 -19 519 703 ;
-C 49 ; WX 556 ; N one ; B 101 0 359 703 ;
-C 50 ; WX 556 ; N two ; B 26 0 507 703 ;
-C 51 ; WX 556 ; N three ; B 34 -19 522 703 ;
-C 52 ; WX 556 ; N four ; B 25 0 523 703 ;
-C 53 ; WX 556 ; N five ; B 32 -19 514 688 ;
-C 54 ; WX 556 ; N six ; B 38 -19 518 703 ;
-C 55 ; WX 556 ; N seven ; B 37 0 523 688 ;
-C 56 ; WX 556 ; N eight ; B 38 -19 517 703 ;
-C 57 ; WX 556 ; N nine ; B 42 -19 514 703 ;
-C 58 ; WX 278 ; N colon ; B 87 0 191 516 ;
-C 59 ; WX 278 ; N semicolon ; B 87 -147 191 516 ;
-C 60 ; WX 584 ; N less ; B 48 11 536 495 ;
-C 61 ; WX 584 ; N equal ; B 39 115 545 390 ;
-C 62 ; WX 584 ; N greater ; B 48 11 536 495 ;
-C 63 ; WX 556 ; N question ; B 56 0 492 727 ;
-C 64 ; WX 1015 ; N at ; B 147 -19 868 737 ;
-C 65 ; WX 667 ; N A ; B 14 0 654 718 ;
-C 66 ; WX 667 ; N B ; B 74 0 627 718 ;
-C 67 ; WX 722 ; N C ; B 44 -19 681 737 ;
-C 68 ; WX 722 ; N D ; B 81 0 674 718 ;
-C 69 ; WX 667 ; N E ; B 86 0 616 718 ;
-C 70 ; WX 611 ; N F ; B 86 0 583 718 ;
-C 71 ; WX 778 ; N G ; B 48 -19 704 737 ;
-C 72 ; WX 722 ; N H ; B 77 0 646 718 ;
-C 73 ; WX 278 ; N I ; B 91 0 188 718 ;
-C 74 ; WX 500 ; N J ; B 17 -19 428 718 ;
-C 75 ; WX 667 ; N K ; B 76 0 663 718 ;
-C 76 ; WX 556 ; N L ; B 76 0 537 718 ;
-C 77 ; WX 833 ; N M ; B 73 0 761 718 ;
-C 78 ; WX 722 ; N N ; B 76 0 646 718 ;
-C 79 ; WX 778 ; N O ; B 39 -19 739 737 ;
-C 80 ; WX 667 ; N P ; B 86 0 622 718 ;
-C 81 ; WX 778 ; N Q ; B 39 -56 739 737 ;
-C 82 ; WX 722 ; N R ; B 88 0 684 718 ;
-C 83 ; WX 667 ; N S ; B 49 -19 620 737 ;
-C 84 ; WX 611 ; N T ; B 14 0 597 718 ;
-C 85 ; WX 722 ; N U ; B 79 -19 644 718 ;
-C 86 ; WX 667 ; N V ; B 20 0 647 718 ;
-C 87 ; WX 944 ; N W ; B 16 0 928 718 ;
-C 88 ; WX 667 ; N X ; B 19 0 648 718 ;
-C 89 ; WX 667 ; N Y ; B 14 0 653 718 ;
-C 90 ; WX 611 ; N Z ; B 23 0 588 718 ;
-C 91 ; WX 278 ; N bracketleft ; B 63 -196 250 722 ;
-C 92 ; WX 278 ; N backslash ; B -17 -19 295 737 ;
-C 93 ; WX 278 ; N bracketright ; B 28 -196 215 722 ;
-C 94 ; WX 469 ; N asciicircum ; B -14 264 483 688 ;
-C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ;
-C 96 ; WX 222 ; N quoteleft ; B 65 470 169 725 ;
-C 97 ; WX 556 ; N a ; B 36 -15 530 538 ;
-C 98 ; WX 556 ; N b ; B 58 -15 517 718 ;
-C 99 ; WX 500 ; N c ; B 30 -15 477 538 ;
-C 100 ; WX 556 ; N d ; B 35 -15 499 718 ;
-C 101 ; WX 556 ; N e ; B 40 -15 516 538 ;
-C 102 ; WX 278 ; N f ; B 14 0 262 728 ; L i fi ; L l fl ;
-C 103 ; WX 556 ; N g ; B 40 -220 499 538 ;
-C 104 ; WX 556 ; N h ; B 65 0 491 718 ;
-C 105 ; WX 222 ; N i ; B 67 0 155 718 ;
-C 106 ; WX 222 ; N j ; B -16 -210 155 718 ;
-C 107 ; WX 500 ; N k ; B 67 0 501 718 ;
-C 108 ; WX 222 ; N l ; B 67 0 155 718 ;
-C 109 ; WX 833 ; N m ; B 65 0 769 538 ;
-C 110 ; WX 556 ; N n ; B 65 0 491 538 ;
-C 111 ; WX 556 ; N o ; B 35 -14 521 538 ;
-C 112 ; WX 556 ; N p ; B 58 -207 517 538 ;
-C 113 ; WX 556 ; N q ; B 35 -207 494 538 ;
-C 114 ; WX 333 ; N r ; B 77 0 332 538 ;
-C 115 ; WX 500 ; N s ; B 32 -15 464 538 ;
-C 116 ; WX 278 ; N t ; B 14 -7 257 669 ;
-C 117 ; WX 556 ; N u ; B 68 -15 489 523 ;
-C 118 ; WX 500 ; N v ; B 8 0 492 523 ;
-C 119 ; WX 722 ; N w ; B 14 0 709 523 ;
-C 120 ; WX 500 ; N x ; B 11 0 490 523 ;
-C 121 ; WX 500 ; N y ; B 11 -214 489 523 ;
-C 122 ; WX 500 ; N z ; B 31 0 469 523 ;
-C 123 ; WX 334 ; N braceleft ; B 42 -196 292 722 ;
-C 124 ; WX 260 ; N bar ; B 94 -19 167 737 ;
-C 125 ; WX 334 ; N braceright ; B 42 -196 292 722 ;
-C 126 ; WX 584 ; N asciitilde ; B 61 180 523 326 ;
-C 161 ; WX 333 ; N exclamdown ; B 118 -195 215 523 ;
-C 162 ; WX 556 ; N cent ; B 51 -115 513 623 ;
-C 163 ; WX 556 ; N sterling ; B 33 -16 539 718 ;
-C 164 ; WX 167 ; N fraction ; B -166 -19 333 703 ;
-C 165 ; WX 556 ; N yen ; B 3 0 553 688 ;
-C 166 ; WX 556 ; N florin ; B -11 -207 501 737 ;
-C 167 ; WX 556 ; N section ; B 43 -191 512 737 ;
-C 168 ; WX 556 ; N currency ; B 28 99 528 603 ;
-C 169 ; WX 191 ; N quotesingle ; B 59 463 132 718 ;
-C 170 ; WX 333 ; N quotedblleft ; B 38 470 307 725 ;
-C 171 ; WX 556 ; N guillemotleft ; B 97 108 459 446 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 88 108 245 446 ;
-C 173 ; WX 333 ; N guilsinglright ; B 88 108 245 446 ;
-C 174 ; WX 500 ; N fi ; B 14 0 434 728 ;
-C 175 ; WX 500 ; N fl ; B 14 0 432 728 ;
-C 177 ; WX 556 ; N endash ; B 0 240 556 313 ;
-C 178 ; WX 556 ; N dagger ; B 43 -159 514 718 ;
-C 179 ; WX 556 ; N daggerdbl ; B 43 -159 514 718 ;
-C 180 ; WX 278 ; N periodcentered ; B 77 190 202 315 ;
-C 182 ; WX 537 ; N paragraph ; B 18 -173 497 718 ;
-C 183 ; WX 350 ; N bullet ; B 18 202 333 517 ;
-C 184 ; WX 222 ; N quotesinglbase ; B 53 -149 157 106 ;
-C 185 ; WX 333 ; N quotedblbase ; B 26 -149 295 106 ;
-C 186 ; WX 333 ; N quotedblright ; B 26 463 295 718 ;
-C 187 ; WX 556 ; N guillemotright ; B 97 108 459 446 ;
-C 188 ; WX 1000 ; N ellipsis ; B 115 0 885 106 ;
-C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 703 ;
-C 191 ; WX 611 ; N questiondown ; B 91 -201 527 525 ;
-C 193 ; WX 333 ; N grave ; B 14 593 211 734 ;
-C 194 ; WX 333 ; N acute ; B 122 593 319 734 ;
-C 195 ; WX 333 ; N circumflex ; B 21 593 312 734 ;
-C 196 ; WX 333 ; N tilde ; B -4 606 337 722 ;
-C 197 ; WX 333 ; N macron ; B 10 627 323 684 ;
-C 198 ; WX 333 ; N breve ; B 13 595 321 731 ;
-C 199 ; WX 333 ; N dotaccent ; B 121 604 212 706 ;
-C 200 ; WX 333 ; N dieresis ; B 40 604 293 706 ;
-C 202 ; WX 333 ; N ring ; B 75 572 259 756 ;
-C 203 ; WX 333 ; N cedilla ; B 45 -225 259 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 31 593 409 734 ;
-C 206 ; WX 333 ; N ogonek ; B 73 -225 287 0 ;
-C 207 ; WX 333 ; N caron ; B 21 593 312 734 ;
-C 208 ; WX 1000 ; N emdash ; B 0 240 1000 313 ;
-C 225 ; WX 1000 ; N AE ; B 8 0 951 718 ;
-C 227 ; WX 370 ; N ordfeminine ; B 24 304 346 737 ;
-C 232 ; WX 556 ; N Lslash ; B -20 0 537 718 ;
-C 233 ; WX 778 ; N Oslash ; B 39 -19 740 737 ;
-C 234 ; WX 1000 ; N OE ; B 36 -19 965 737 ;
-C 235 ; WX 365 ; N ordmasculine ; B 25 304 341 737 ;
-C 241 ; WX 889 ; N ae ; B 36 -15 847 538 ;
-C 245 ; WX 278 ; N dotlessi ; B 95 0 183 523 ;
-C 248 ; WX 222 ; N lslash ; B -20 0 242 718 ;
-C 249 ; WX 611 ; N oslash ; B 28 -22 537 545 ;
-C 250 ; WX 944 ; N oe ; B 35 -15 902 538 ;
-C 251 ; WX 611 ; N germandbls ; B 67 -15 571 728 ;
-C -1 ; WX 611 ; N Zcaron ; B 23 0 588 929 ;
-C -1 ; WX 500 ; N ccedilla ; B 30 -225 477 538 ;
-C -1 ; WX 500 ; N ydieresis ; B 11 -214 489 706 ;
-C -1 ; WX 556 ; N atilde ; B 36 -15 530 722 ;
-C -1 ; WX 278 ; N icircumflex ; B -6 0 285 734 ;
-C -1 ; WX 333 ; N threesuperior ; B 5 270 325 703 ;
-C -1 ; WX 556 ; N ecircumflex ; B 40 -15 516 734 ;
-C -1 ; WX 556 ; N thorn ; B 58 -207 517 718 ;
-C -1 ; WX 556 ; N egrave ; B 40 -15 516 734 ;
-C -1 ; WX 333 ; N twosuperior ; B 4 281 323 703 ;
-C -1 ; WX 556 ; N eacute ; B 40 -15 516 734 ;
-C -1 ; WX 556 ; N otilde ; B 35 -14 521 722 ;
-C -1 ; WX 667 ; N Aacute ; B 14 0 654 929 ;
-C -1 ; WX 556 ; N ocircumflex ; B 35 -14 521 734 ;
-C -1 ; WX 500 ; N yacute ; B 11 -214 489 734 ;
-C -1 ; WX 556 ; N udieresis ; B 68 -15 489 706 ;
-C -1 ; WX 834 ; N threequarters ; B 45 -19 810 703 ;
-C -1 ; WX 556 ; N acircumflex ; B 36 -15 530 734 ;
-C -1 ; WX 722 ; N Eth ; B 0 0 674 718 ;
-C -1 ; WX 556 ; N edieresis ; B 40 -15 516 706 ;
-C -1 ; WX 556 ; N ugrave ; B 68 -15 489 734 ;
-C -1 ; WX 1000 ; N trademark ; B 46 306 903 718 ;
-C -1 ; WX 556 ; N ograve ; B 35 -14 521 734 ;
-C -1 ; WX 500 ; N scaron ; B 32 -15 464 734 ;
-C -1 ; WX 278 ; N Idieresis ; B 13 0 266 901 ;
-C -1 ; WX 556 ; N uacute ; B 68 -15 489 734 ;
-C -1 ; WX 556 ; N agrave ; B 36 -15 530 734 ;
-C -1 ; WX 556 ; N ntilde ; B 65 0 491 722 ;
-C -1 ; WX 556 ; N aring ; B 36 -15 530 756 ;
-C -1 ; WX 500 ; N zcaron ; B 31 0 469 734 ;
-C -1 ; WX 278 ; N Icircumflex ; B -6 0 285 929 ;
-C -1 ; WX 722 ; N Ntilde ; B 76 0 646 917 ;
-C -1 ; WX 556 ; N ucircumflex ; B 68 -15 489 734 ;
-C -1 ; WX 667 ; N Ecircumflex ; B 86 0 616 929 ;
-C -1 ; WX 278 ; N Iacute ; B 91 0 292 929 ;
-C -1 ; WX 722 ; N Ccedilla ; B 44 -225 681 737 ;
-C -1 ; WX 778 ; N Odieresis ; B 39 -19 739 901 ;
-C -1 ; WX 667 ; N Scaron ; B 49 -19 620 929 ;
-C -1 ; WX 667 ; N Edieresis ; B 86 0 616 901 ;
-C -1 ; WX 278 ; N Igrave ; B -13 0 188 929 ;
-C -1 ; WX 556 ; N adieresis ; B 36 -15 530 706 ;
-C -1 ; WX 778 ; N Ograve ; B 39 -19 739 929 ;
-C -1 ; WX 667 ; N Egrave ; B 86 0 616 929 ;
-C -1 ; WX 667 ; N Ydieresis ; B 14 0 653 901 ;
-C -1 ; WX 737 ; N registered ; B -14 -19 752 737 ;
-C -1 ; WX 778 ; N Otilde ; B 39 -19 739 917 ;
-C -1 ; WX 834 ; N onequarter ; B 73 -19 756 703 ;
-C -1 ; WX 722 ; N Ugrave ; B 79 -19 644 929 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 79 -19 644 929 ;
-C -1 ; WX 667 ; N Thorn ; B 86 0 622 718 ;
-C -1 ; WX 584 ; N divide ; B 39 -19 545 524 ;
-C -1 ; WX 667 ; N Atilde ; B 14 0 654 917 ;
-C -1 ; WX 722 ; N Uacute ; B 79 -19 644 929 ;
-C -1 ; WX 778 ; N Ocircumflex ; B 39 -19 739 929 ;
-C -1 ; WX 584 ; N logicalnot ; B 39 108 545 390 ;
-C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ;
-C -1 ; WX 278 ; N idieresis ; B 13 0 266 706 ;
-C -1 ; WX 278 ; N iacute ; B 95 0 292 734 ;
-C -1 ; WX 556 ; N aacute ; B 36 -15 530 734 ;
-C -1 ; WX 584 ; N plusminus ; B 39 0 545 506 ;
-C -1 ; WX 584 ; N multiply ; B 39 0 545 506 ;
-C -1 ; WX 722 ; N Udieresis ; B 79 -19 644 901 ;
-C -1 ; WX 584 ; N minus ; B 39 216 545 289 ;
-C -1 ; WX 333 ; N onesuperior ; B 43 281 222 703 ;
-C -1 ; WX 667 ; N Eacute ; B 86 0 616 929 ;
-C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ;
-C -1 ; WX 737 ; N copyright ; B -14 -19 752 737 ;
-C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ;
-C -1 ; WX 556 ; N odieresis ; B 35 -14 521 706 ;
-C -1 ; WX 556 ; N oacute ; B 35 -14 521 734 ;
-C -1 ; WX 400 ; N degree ; B 54 411 346 703 ;
-C -1 ; WX 278 ; N igrave ; B -13 0 184 734 ;
-C -1 ; WX 556 ; N mu ; B 68 -207 489 523 ;
-C -1 ; WX 778 ; N Oacute ; B 39 -19 739 929 ;
-C -1 ; WX 556 ; N eth ; B 35 -15 522 737 ;
-C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ;
-C -1 ; WX 667 ; N Yacute ; B 14 0 653 929 ;
-C -1 ; WX 260 ; N brokenbar ; B 94 -19 167 737 ;
-C -1 ; WX 834 ; N onehalf ; B 43 -19 773 703 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 250
-
-KPX A y -40
-KPX A w -40
-KPX A v -40
-KPX A u -30
-KPX A Y -100
-KPX A W -50
-KPX A V -70
-KPX A U -50
-KPX A T -120
-KPX A Q -30
-KPX A O -30
-KPX A G -30
-KPX A C -30
-
-KPX B period -20
-KPX B comma -20
-KPX B U -10
-
-KPX C period -30
-KPX C comma -30
-
-KPX D period -70
-KPX D comma -70
-KPX D Y -90
-KPX D W -40
-KPX D V -70
-KPX D A -40
-
-KPX F r -45
-KPX F period -150
-KPX F o -30
-KPX F e -30
-KPX F comma -150
-KPX F a -50
-KPX F A -80
-
-KPX J u -20
-KPX J period -30
-KPX J comma -30
-KPX J a -20
-KPX J A -20
-
-KPX K y -50
-KPX K u -30
-KPX K o -40
-KPX K e -40
-KPX K O -50
-
-KPX L y -30
-KPX L quoteright -160
-KPX L quotedblright -140
-KPX L Y -140
-KPX L W -70
-KPX L V -110
-KPX L T -110
-
-KPX O period -40
-KPX O comma -40
-KPX O Y -70
-KPX O X -60
-KPX O W -30
-KPX O V -50
-KPX O T -40
-KPX O A -20
-
-KPX P period -180
-KPX P o -50
-KPX P e -50
-KPX P comma -180
-KPX P a -40
-KPX P A -120
-
-KPX Q U -10
-
-KPX R Y -50
-KPX R W -30
-KPX R V -50
-KPX R U -40
-KPX R T -30
-KPX R O -20
-
-KPX S period -20
-KPX S comma -20
-
-KPX T y -120
-KPX T w -120
-KPX T u -120
-KPX T semicolon -20
-KPX T r -120
-KPX T period -120
-KPX T o -120
-KPX T hyphen -140
-KPX T e -120
-KPX T comma -120
-KPX T colon -20
-KPX T a -120
-KPX T O -40
-KPX T A -120
-
-KPX U period -40
-KPX U comma -40
-KPX U A -40
-
-KPX V u -70
-KPX V semicolon -40
-KPX V period -125
-KPX V o -80
-KPX V hyphen -80
-KPX V e -80
-KPX V comma -125
-KPX V colon -40
-KPX V a -70
-KPX V O -40
-KPX V G -40
-KPX V A -80
-
-KPX W y -20
-KPX W u -30
-KPX W period -80
-KPX W o -30
-KPX W hyphen -40
-KPX W e -30
-KPX W comma -80
-KPX W a -40
-KPX W O -20
-KPX W A -50
-
-KPX Y u -110
-KPX Y semicolon -60
-KPX Y period -140
-KPX Y o -140
-KPX Y i -20
-KPX Y hyphen -140
-KPX Y e -140
-KPX Y comma -140
-KPX Y colon -60
-KPX Y a -140
-KPX Y O -85
-KPX Y A -110
-
-KPX a y -30
-KPX a w -20
-KPX a v -20
-
-KPX b y -20
-KPX b v -20
-KPX b u -20
-KPX b period -40
-KPX b l -20
-KPX b comma -40
-KPX b b -10
-
-KPX c k -20
-KPX c comma -15
-
-KPX colon space -50
-
-KPX comma quoteright -100
-KPX comma quotedblright -100
-
-KPX e y -20
-KPX e x -30
-KPX e w -20
-KPX e v -30
-KPX e period -15
-KPX e comma -15
-
-KPX f quoteright 50
-KPX f quotedblright 60
-KPX f period -30
-KPX f o -30
-KPX f e -30
-KPX f dotlessi -28
-KPX f comma -30
-KPX f a -30
-
-KPX g r -10
-
-KPX h y -30
-
-KPX k o -20
-KPX k e -20
-
-KPX m y -15
-KPX m u -10
-
-KPX n y -15
-KPX n v -20
-KPX n u -10
-
-KPX o y -30
-KPX o x -30
-KPX o w -15
-KPX o v -15
-KPX o period -40
-KPX o comma -40
-
-KPX oslash z -55
-KPX oslash y -70
-KPX oslash x -85
-KPX oslash w -70
-KPX oslash v -70
-KPX oslash u -55
-KPX oslash t -55
-KPX oslash s -55
-KPX oslash r -55
-KPX oslash q -55
-KPX oslash period -95
-KPX oslash p -55
-KPX oslash o -55
-KPX oslash n -55
-KPX oslash m -55
-KPX oslash l -55
-KPX oslash k -55
-KPX oslash j -55
-KPX oslash i -55
-KPX oslash h -55
-KPX oslash g -55
-KPX oslash f -55
-KPX oslash e -55
-KPX oslash d -55
-KPX oslash comma -95
-KPX oslash c -55
-KPX oslash b -55
-KPX oslash a -55
-
-KPX p y -30
-KPX p period -35
-KPX p comma -35
-
-KPX period space -60
-KPX period quoteright -100
-KPX period quotedblright -100
-
-KPX quotedblright space -40
-
-KPX quoteleft quoteleft -57
-
-KPX quoteright space -70
-KPX quoteright s -50
-KPX quoteright r -50
-KPX quoteright quoteright -57
-KPX quoteright d -50
-
-KPX r y 30
-KPX r v 30
-KPX r u 15
-KPX r t 40
-KPX r semicolon 30
-KPX r period -50
-KPX r p 30
-KPX r n 25
-KPX r m 25
-KPX r l 15
-KPX r k 15
-KPX r i 15
-KPX r comma -50
-KPX r colon 30
-KPX r a -10
-
-KPX s w -30
-KPX s period -15
-KPX s comma -15
-
-KPX semicolon space -50
-
-KPX space quoteleft -60
-KPX space quotedblleft -30
-KPX space Y -90
-KPX space W -40
-KPX space V -50
-KPX space T -50
-
-KPX v period -80
-KPX v o -25
-KPX v e -25
-KPX v comma -80
-KPX v a -25
-
-KPX w period -60
-KPX w o -10
-KPX w e -10
-KPX w comma -60
-KPX w a -15
-
-KPX x e -30
-
-KPX y period -100
-KPX y o -20
-KPX y e -20
-KPX y comma -100
-KPX y a -20
-
-KPX z o -15
-KPX z e -15
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 167 195 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 167 195 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 195 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 167 195 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 167 175 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 195 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 195 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 167 195 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 167 195 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 167 195 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 195 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute -27 195 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -27 195 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -27 195 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave -27 195 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 205 195 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 195 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 195 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 195 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 195 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 195 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 195 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 195 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 195 195 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 195 195 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 195 195 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 167 195 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 167 195 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 195 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 102 0 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 84 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 102 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 112 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 112 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 112 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 84 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 112 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 112 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvr8an.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvr8an.afm
deleted file mode 100644
index 5a08aa8c99..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvr8an.afm
+++ /dev/null
@@ -1,612 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.
-Comment Creation Date: Thu Mar 15 11:04:57 1990
-Comment UniqueID 28380
-Comment VMusage 7572 42473
-FontName Helvetica-Narrow
-FullName Helvetica Narrow
-FamilyName Helvetica
-Weight Medium
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -136 -225 820 931
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.006
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 718
-XHeight 523
-Ascender 718
-Descender -207
-StartCharMetrics 228
-C 32 ; WX 228 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 228 ; N exclam ; B 74 0 153 718 ;
-C 34 ; WX 291 ; N quotedbl ; B 57 463 234 718 ;
-C 35 ; WX 456 ; N numbersign ; B 23 0 434 688 ;
-C 36 ; WX 456 ; N dollar ; B 26 -115 426 775 ;
-C 37 ; WX 729 ; N percent ; B 32 -19 697 703 ;
-C 38 ; WX 547 ; N ampersand ; B 36 -15 529 718 ;
-C 39 ; WX 182 ; N quoteright ; B 43 463 129 718 ;
-C 40 ; WX 273 ; N parenleft ; B 56 -207 245 733 ;
-C 41 ; WX 273 ; N parenright ; B 28 -207 217 733 ;
-C 42 ; WX 319 ; N asterisk ; B 32 431 286 718 ;
-C 43 ; WX 479 ; N plus ; B 32 0 447 505 ;
-C 44 ; WX 228 ; N comma ; B 71 -147 157 106 ;
-C 45 ; WX 273 ; N hyphen ; B 36 232 237 322 ;
-C 46 ; WX 228 ; N period ; B 71 0 157 106 ;
-C 47 ; WX 228 ; N slash ; B -14 -19 242 737 ;
-C 48 ; WX 456 ; N zero ; B 30 -19 426 703 ;
-C 49 ; WX 456 ; N one ; B 83 0 294 703 ;
-C 50 ; WX 456 ; N two ; B 21 0 416 703 ;
-C 51 ; WX 456 ; N three ; B 28 -19 428 703 ;
-C 52 ; WX 456 ; N four ; B 20 0 429 703 ;
-C 53 ; WX 456 ; N five ; B 26 -19 421 688 ;
-C 54 ; WX 456 ; N six ; B 31 -19 425 703 ;
-C 55 ; WX 456 ; N seven ; B 30 0 429 688 ;
-C 56 ; WX 456 ; N eight ; B 31 -19 424 703 ;
-C 57 ; WX 456 ; N nine ; B 34 -19 421 703 ;
-C 58 ; WX 228 ; N colon ; B 71 0 157 516 ;
-C 59 ; WX 228 ; N semicolon ; B 71 -147 157 516 ;
-C 60 ; WX 479 ; N less ; B 39 11 440 495 ;
-C 61 ; WX 479 ; N equal ; B 32 115 447 390 ;
-C 62 ; WX 479 ; N greater ; B 39 11 440 495 ;
-C 63 ; WX 456 ; N question ; B 46 0 403 727 ;
-C 64 ; WX 832 ; N at ; B 121 -19 712 737 ;
-C 65 ; WX 547 ; N A ; B 11 0 536 718 ;
-C 66 ; WX 547 ; N B ; B 61 0 514 718 ;
-C 67 ; WX 592 ; N C ; B 36 -19 558 737 ;
-C 68 ; WX 592 ; N D ; B 66 0 553 718 ;
-C 69 ; WX 547 ; N E ; B 71 0 505 718 ;
-C 70 ; WX 501 ; N F ; B 71 0 478 718 ;
-C 71 ; WX 638 ; N G ; B 39 -19 577 737 ;
-C 72 ; WX 592 ; N H ; B 63 0 530 718 ;
-C 73 ; WX 228 ; N I ; B 75 0 154 718 ;
-C 74 ; WX 410 ; N J ; B 14 -19 351 718 ;
-C 75 ; WX 547 ; N K ; B 62 0 544 718 ;
-C 76 ; WX 456 ; N L ; B 62 0 440 718 ;
-C 77 ; WX 683 ; N M ; B 60 0 624 718 ;
-C 78 ; WX 592 ; N N ; B 62 0 530 718 ;
-C 79 ; WX 638 ; N O ; B 32 -19 606 737 ;
-C 80 ; WX 547 ; N P ; B 71 0 510 718 ;
-C 81 ; WX 638 ; N Q ; B 32 -56 606 737 ;
-C 82 ; WX 592 ; N R ; B 72 0 561 718 ;
-C 83 ; WX 547 ; N S ; B 40 -19 508 737 ;
-C 84 ; WX 501 ; N T ; B 11 0 490 718 ;
-C 85 ; WX 592 ; N U ; B 65 -19 528 718 ;
-C 86 ; WX 547 ; N V ; B 16 0 531 718 ;
-C 87 ; WX 774 ; N W ; B 13 0 761 718 ;
-C 88 ; WX 547 ; N X ; B 16 0 531 718 ;
-C 89 ; WX 547 ; N Y ; B 11 0 535 718 ;
-C 90 ; WX 501 ; N Z ; B 19 0 482 718 ;
-C 91 ; WX 228 ; N bracketleft ; B 52 -196 205 722 ;
-C 92 ; WX 228 ; N backslash ; B -14 -19 242 737 ;
-C 93 ; WX 228 ; N bracketright ; B 23 -196 176 722 ;
-C 94 ; WX 385 ; N asciicircum ; B -11 264 396 688 ;
-C 95 ; WX 456 ; N underscore ; B 0 -125 456 -75 ;
-C 96 ; WX 182 ; N quoteleft ; B 53 470 139 725 ;
-C 97 ; WX 456 ; N a ; B 30 -15 435 538 ;
-C 98 ; WX 456 ; N b ; B 48 -15 424 718 ;
-C 99 ; WX 410 ; N c ; B 25 -15 391 538 ;
-C 100 ; WX 456 ; N d ; B 29 -15 409 718 ;
-C 101 ; WX 456 ; N e ; B 33 -15 423 538 ;
-C 102 ; WX 228 ; N f ; B 11 0 215 728 ; L i fi ; L l fl ;
-C 103 ; WX 456 ; N g ; B 33 -220 409 538 ;
-C 104 ; WX 456 ; N h ; B 53 0 403 718 ;
-C 105 ; WX 182 ; N i ; B 55 0 127 718 ;
-C 106 ; WX 182 ; N j ; B -13 -210 127 718 ;
-C 107 ; WX 410 ; N k ; B 55 0 411 718 ;
-C 108 ; WX 182 ; N l ; B 55 0 127 718 ;
-C 109 ; WX 683 ; N m ; B 53 0 631 538 ;
-C 110 ; WX 456 ; N n ; B 53 0 403 538 ;
-C 111 ; WX 456 ; N o ; B 29 -14 427 538 ;
-C 112 ; WX 456 ; N p ; B 48 -207 424 538 ;
-C 113 ; WX 456 ; N q ; B 29 -207 405 538 ;
-C 114 ; WX 273 ; N r ; B 63 0 272 538 ;
-C 115 ; WX 410 ; N s ; B 26 -15 380 538 ;
-C 116 ; WX 228 ; N t ; B 11 -7 211 669 ;
-C 117 ; WX 456 ; N u ; B 56 -15 401 523 ;
-C 118 ; WX 410 ; N v ; B 7 0 403 523 ;
-C 119 ; WX 592 ; N w ; B 11 0 581 523 ;
-C 120 ; WX 410 ; N x ; B 9 0 402 523 ;
-C 121 ; WX 410 ; N y ; B 9 -214 401 523 ;
-C 122 ; WX 410 ; N z ; B 25 0 385 523 ;
-C 123 ; WX 274 ; N braceleft ; B 34 -196 239 722 ;
-C 124 ; WX 213 ; N bar ; B 77 -19 137 737 ;
-C 125 ; WX 274 ; N braceright ; B 34 -196 239 722 ;
-C 126 ; WX 479 ; N asciitilde ; B 50 180 429 326 ;
-C 161 ; WX 273 ; N exclamdown ; B 97 -195 176 523 ;
-C 162 ; WX 456 ; N cent ; B 42 -115 421 623 ;
-C 163 ; WX 456 ; N sterling ; B 27 -16 442 718 ;
-C 164 ; WX 137 ; N fraction ; B -136 -19 273 703 ;
-C 165 ; WX 456 ; N yen ; B 2 0 453 688 ;
-C 166 ; WX 456 ; N florin ; B -9 -207 411 737 ;
-C 167 ; WX 456 ; N section ; B 35 -191 420 737 ;
-C 168 ; WX 456 ; N currency ; B 23 99 433 603 ;
-C 169 ; WX 157 ; N quotesingle ; B 48 463 108 718 ;
-C 170 ; WX 273 ; N quotedblleft ; B 31 470 252 725 ;
-C 171 ; WX 456 ; N guillemotleft ; B 80 108 376 446 ;
-C 172 ; WX 273 ; N guilsinglleft ; B 72 108 201 446 ;
-C 173 ; WX 273 ; N guilsinglright ; B 72 108 201 446 ;
-C 174 ; WX 410 ; N fi ; B 11 0 356 728 ;
-C 175 ; WX 410 ; N fl ; B 11 0 354 728 ;
-C 177 ; WX 456 ; N endash ; B 0 240 456 313 ;
-C 178 ; WX 456 ; N dagger ; B 35 -159 421 718 ;
-C 179 ; WX 456 ; N daggerdbl ; B 35 -159 421 718 ;
-C 180 ; WX 228 ; N periodcentered ; B 63 190 166 315 ;
-C 182 ; WX 440 ; N paragraph ; B 15 -173 408 718 ;
-C 183 ; WX 287 ; N bullet ; B 15 202 273 517 ;
-C 184 ; WX 182 ; N quotesinglbase ; B 43 -149 129 106 ;
-C 185 ; WX 273 ; N quotedblbase ; B 21 -149 242 106 ;
-C 186 ; WX 273 ; N quotedblright ; B 21 463 242 718 ;
-C 187 ; WX 456 ; N guillemotright ; B 80 108 376 446 ;
-C 188 ; WX 820 ; N ellipsis ; B 94 0 726 106 ;
-C 189 ; WX 820 ; N perthousand ; B 6 -19 815 703 ;
-C 191 ; WX 501 ; N questiondown ; B 75 -201 432 525 ;
-C 193 ; WX 273 ; N grave ; B 11 593 173 734 ;
-C 194 ; WX 273 ; N acute ; B 100 593 262 734 ;
-C 195 ; WX 273 ; N circumflex ; B 17 593 256 734 ;
-C 196 ; WX 273 ; N tilde ; B -3 606 276 722 ;
-C 197 ; WX 273 ; N macron ; B 8 627 265 684 ;
-C 198 ; WX 273 ; N breve ; B 11 595 263 731 ;
-C 199 ; WX 273 ; N dotaccent ; B 99 604 174 706 ;
-C 200 ; WX 273 ; N dieresis ; B 33 604 240 706 ;
-C 202 ; WX 273 ; N ring ; B 61 572 212 756 ;
-C 203 ; WX 273 ; N cedilla ; B 37 -225 212 0 ;
-C 205 ; WX 273 ; N hungarumlaut ; B 25 593 335 734 ;
-C 206 ; WX 273 ; N ogonek ; B 60 -225 235 0 ;
-C 207 ; WX 273 ; N caron ; B 17 593 256 734 ;
-C 208 ; WX 820 ; N emdash ; B 0 240 820 313 ;
-C 225 ; WX 820 ; N AE ; B 7 0 780 718 ;
-C 227 ; WX 303 ; N ordfeminine ; B 20 304 284 737 ;
-C 232 ; WX 456 ; N Lslash ; B -16 0 440 718 ;
-C 233 ; WX 638 ; N Oslash ; B 32 -19 607 737 ;
-C 234 ; WX 820 ; N OE ; B 30 -19 791 737 ;
-C 235 ; WX 299 ; N ordmasculine ; B 20 304 280 737 ;
-C 241 ; WX 729 ; N ae ; B 30 -15 695 538 ;
-C 245 ; WX 228 ; N dotlessi ; B 78 0 150 523 ;
-C 248 ; WX 182 ; N lslash ; B -16 0 198 718 ;
-C 249 ; WX 501 ; N oslash ; B 23 -22 440 545 ;
-C 250 ; WX 774 ; N oe ; B 29 -15 740 538 ;
-C 251 ; WX 501 ; N germandbls ; B 55 -15 468 728 ;
-C -1 ; WX 501 ; N Zcaron ; B 19 0 482 929 ;
-C -1 ; WX 410 ; N ccedilla ; B 25 -225 391 538 ;
-C -1 ; WX 410 ; N ydieresis ; B 9 -214 401 706 ;
-C -1 ; WX 456 ; N atilde ; B 30 -15 435 722 ;
-C -1 ; WX 228 ; N icircumflex ; B -5 0 234 734 ;
-C -1 ; WX 273 ; N threesuperior ; B 4 270 266 703 ;
-C -1 ; WX 456 ; N ecircumflex ; B 33 -15 423 734 ;
-C -1 ; WX 456 ; N thorn ; B 48 -207 424 718 ;
-C -1 ; WX 456 ; N egrave ; B 33 -15 423 734 ;
-C -1 ; WX 273 ; N twosuperior ; B 3 281 265 703 ;
-C -1 ; WX 456 ; N eacute ; B 33 -15 423 734 ;
-C -1 ; WX 456 ; N otilde ; B 29 -14 427 722 ;
-C -1 ; WX 547 ; N Aacute ; B 11 0 536 929 ;
-C -1 ; WX 456 ; N ocircumflex ; B 29 -14 427 734 ;
-C -1 ; WX 410 ; N yacute ; B 9 -214 401 734 ;
-C -1 ; WX 456 ; N udieresis ; B 56 -15 401 706 ;
-C -1 ; WX 684 ; N threequarters ; B 37 -19 664 703 ;
-C -1 ; WX 456 ; N acircumflex ; B 30 -15 435 734 ;
-C -1 ; WX 592 ; N Eth ; B 0 0 553 718 ;
-C -1 ; WX 456 ; N edieresis ; B 33 -15 423 706 ;
-C -1 ; WX 456 ; N ugrave ; B 56 -15 401 734 ;
-C -1 ; WX 820 ; N trademark ; B 38 306 740 718 ;
-C -1 ; WX 456 ; N ograve ; B 29 -14 427 734 ;
-C -1 ; WX 410 ; N scaron ; B 26 -15 380 734 ;
-C -1 ; WX 228 ; N Idieresis ; B 11 0 218 901 ;
-C -1 ; WX 456 ; N uacute ; B 56 -15 401 734 ;
-C -1 ; WX 456 ; N agrave ; B 30 -15 435 734 ;
-C -1 ; WX 456 ; N ntilde ; B 53 0 403 722 ;
-C -1 ; WX 456 ; N aring ; B 30 -15 435 756 ;
-C -1 ; WX 410 ; N zcaron ; B 25 0 385 734 ;
-C -1 ; WX 228 ; N Icircumflex ; B -5 0 234 929 ;
-C -1 ; WX 592 ; N Ntilde ; B 62 0 530 917 ;
-C -1 ; WX 456 ; N ucircumflex ; B 56 -15 401 734 ;
-C -1 ; WX 547 ; N Ecircumflex ; B 71 0 505 929 ;
-C -1 ; WX 228 ; N Iacute ; B 75 0 239 929 ;
-C -1 ; WX 592 ; N Ccedilla ; B 36 -225 558 737 ;
-C -1 ; WX 638 ; N Odieresis ; B 32 -19 606 901 ;
-C -1 ; WX 547 ; N Scaron ; B 40 -19 508 929 ;
-C -1 ; WX 547 ; N Edieresis ; B 71 0 505 901 ;
-C -1 ; WX 228 ; N Igrave ; B -11 0 154 929 ;
-C -1 ; WX 456 ; N adieresis ; B 30 -15 435 706 ;
-C -1 ; WX 638 ; N Ograve ; B 32 -19 606 929 ;
-C -1 ; WX 547 ; N Egrave ; B 71 0 505 929 ;
-C -1 ; WX 547 ; N Ydieresis ; B 11 0 535 901 ;
-C -1 ; WX 604 ; N registered ; B -11 -19 617 737 ;
-C -1 ; WX 638 ; N Otilde ; B 32 -19 606 917 ;
-C -1 ; WX 684 ; N onequarter ; B 60 -19 620 703 ;
-C -1 ; WX 592 ; N Ugrave ; B 65 -19 528 929 ;
-C -1 ; WX 592 ; N Ucircumflex ; B 65 -19 528 929 ;
-C -1 ; WX 547 ; N Thorn ; B 71 0 510 718 ;
-C -1 ; WX 479 ; N divide ; B 32 -19 447 524 ;
-C -1 ; WX 547 ; N Atilde ; B 11 0 536 917 ;
-C -1 ; WX 592 ; N Uacute ; B 65 -19 528 929 ;
-C -1 ; WX 638 ; N Ocircumflex ; B 32 -19 606 929 ;
-C -1 ; WX 479 ; N logicalnot ; B 32 108 447 390 ;
-C -1 ; WX 547 ; N Aring ; B 11 0 536 931 ;
-C -1 ; WX 228 ; N idieresis ; B 11 0 218 706 ;
-C -1 ; WX 228 ; N iacute ; B 78 0 239 734 ;
-C -1 ; WX 456 ; N aacute ; B 30 -15 435 734 ;
-C -1 ; WX 479 ; N plusminus ; B 32 0 447 506 ;
-C -1 ; WX 479 ; N multiply ; B 32 0 447 506 ;
-C -1 ; WX 592 ; N Udieresis ; B 65 -19 528 901 ;
-C -1 ; WX 479 ; N minus ; B 32 216 447 289 ;
-C -1 ; WX 273 ; N onesuperior ; B 35 281 182 703 ;
-C -1 ; WX 547 ; N Eacute ; B 71 0 505 929 ;
-C -1 ; WX 547 ; N Acircumflex ; B 11 0 536 929 ;
-C -1 ; WX 604 ; N copyright ; B -11 -19 617 737 ;
-C -1 ; WX 547 ; N Agrave ; B 11 0 536 929 ;
-C -1 ; WX 456 ; N odieresis ; B 29 -14 427 706 ;
-C -1 ; WX 456 ; N oacute ; B 29 -14 427 734 ;
-C -1 ; WX 328 ; N degree ; B 44 411 284 703 ;
-C -1 ; WX 228 ; N igrave ; B -11 0 151 734 ;
-C -1 ; WX 456 ; N mu ; B 56 -207 401 523 ;
-C -1 ; WX 638 ; N Oacute ; B 32 -19 606 929 ;
-C -1 ; WX 456 ; N eth ; B 29 -15 428 737 ;
-C -1 ; WX 547 ; N Adieresis ; B 11 0 536 901 ;
-C -1 ; WX 547 ; N Yacute ; B 11 0 535 929 ;
-C -1 ; WX 213 ; N brokenbar ; B 77 -19 137 737 ;
-C -1 ; WX 684 ; N onehalf ; B 35 -19 634 703 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 250
-
-KPX A y -32
-KPX A w -32
-KPX A v -32
-KPX A u -24
-KPX A Y -81
-KPX A W -40
-KPX A V -56
-KPX A U -40
-KPX A T -97
-KPX A Q -24
-KPX A O -24
-KPX A G -24
-KPX A C -24
-
-KPX B period -15
-KPX B comma -15
-KPX B U -7
-
-KPX C period -24
-KPX C comma -24
-
-KPX D period -56
-KPX D comma -56
-KPX D Y -73
-KPX D W -32
-KPX D V -56
-KPX D A -32
-
-KPX F r -36
-KPX F period -122
-KPX F o -24
-KPX F e -24
-KPX F comma -122
-KPX F a -40
-KPX F A -65
-
-KPX J u -15
-KPX J period -24
-KPX J comma -24
-KPX J a -15
-KPX J A -15
-
-KPX K y -40
-KPX K u -24
-KPX K o -32
-KPX K e -32
-KPX K O -40
-
-KPX L y -24
-KPX L quoteright -130
-KPX L quotedblright -114
-KPX L Y -114
-KPX L W -56
-KPX L V -89
-KPX L T -89
-
-KPX O period -32
-KPX O comma -32
-KPX O Y -56
-KPX O X -48
-KPX O W -24
-KPX O V -40
-KPX O T -32
-KPX O A -15
-
-KPX P period -147
-KPX P o -40
-KPX P e -40
-KPX P comma -147
-KPX P a -32
-KPX P A -97
-
-KPX Q U -7
-
-KPX R Y -40
-KPX R W -24
-KPX R V -40
-KPX R U -32
-KPX R T -24
-KPX R O -15
-
-KPX S period -15
-KPX S comma -15
-
-KPX T y -97
-KPX T w -97
-KPX T u -97
-KPX T semicolon -15
-KPX T r -97
-KPX T period -97
-KPX T o -97
-KPX T hyphen -114
-KPX T e -97
-KPX T comma -97
-KPX T colon -15
-KPX T a -97
-KPX T O -32
-KPX T A -97
-
-KPX U period -32
-KPX U comma -32
-KPX U A -32
-
-KPX V u -56
-KPX V semicolon -32
-KPX V period -102
-KPX V o -65
-KPX V hyphen -65
-KPX V e -65
-KPX V comma -102
-KPX V colon -32
-KPX V a -56
-KPX V O -32
-KPX V G -32
-KPX V A -65
-
-KPX W y -15
-KPX W u -24
-KPX W period -65
-KPX W o -24
-KPX W hyphen -32
-KPX W e -24
-KPX W comma -65
-KPX W a -32
-KPX W O -15
-KPX W A -40
-
-KPX Y u -89
-KPX Y semicolon -48
-KPX Y period -114
-KPX Y o -114
-KPX Y i -15
-KPX Y hyphen -114
-KPX Y e -114
-KPX Y comma -114
-KPX Y colon -48
-KPX Y a -114
-KPX Y O -69
-KPX Y A -89
-
-KPX a y -24
-KPX a w -15
-KPX a v -15
-
-KPX b y -15
-KPX b v -15
-KPX b u -15
-KPX b period -32
-KPX b l -15
-KPX b comma -32
-KPX b b -7
-
-KPX c k -15
-KPX c comma -11
-
-KPX colon space -40
-
-KPX comma quoteright -81
-KPX comma quotedblright -81
-
-KPX e y -15
-KPX e x -24
-KPX e w -15
-KPX e v -24
-KPX e period -11
-KPX e comma -11
-
-KPX f quoteright 41
-KPX f quotedblright 49
-KPX f period -24
-KPX f o -24
-KPX f e -24
-KPX f dotlessi -22
-KPX f comma -24
-KPX f a -24
-
-KPX g r -7
-
-KPX h y -24
-
-KPX k o -15
-KPX k e -15
-
-KPX m y -11
-KPX m u -7
-
-KPX n y -11
-KPX n v -15
-KPX n u -7
-
-KPX o y -24
-KPX o x -24
-KPX o w -11
-KPX o v -11
-KPX o period -32
-KPX o comma -32
-
-KPX oslash z -44
-KPX oslash y -56
-KPX oslash x -69
-KPX oslash w -56
-KPX oslash v -56
-KPX oslash u -44
-KPX oslash t -44
-KPX oslash s -44
-KPX oslash r -44
-KPX oslash q -44
-KPX oslash period -77
-KPX oslash p -44
-KPX oslash o -44
-KPX oslash n -44
-KPX oslash m -44
-KPX oslash l -44
-KPX oslash k -44
-KPX oslash j -44
-KPX oslash i -44
-KPX oslash h -44
-KPX oslash g -44
-KPX oslash f -44
-KPX oslash e -44
-KPX oslash d -44
-KPX oslash comma -77
-KPX oslash c -44
-KPX oslash b -44
-KPX oslash a -44
-
-KPX p y -24
-KPX p period -28
-KPX p comma -28
-
-KPX period space -48
-KPX period quoteright -81
-KPX period quotedblright -81
-
-KPX quotedblright space -32
-
-KPX quoteleft quoteleft -46
-
-KPX quoteright space -56
-KPX quoteright s -40
-KPX quoteright r -40
-KPX quoteright quoteright -46
-KPX quoteright d -40
-
-KPX r y 25
-KPX r v 25
-KPX r u 12
-KPX r t 33
-KPX r semicolon 25
-KPX r period -40
-KPX r p 25
-KPX r n 21
-KPX r m 21
-KPX r l 12
-KPX r k 12
-KPX r i 12
-KPX r comma -40
-KPX r colon 25
-KPX r a -7
-
-KPX s w -24
-KPX s period -11
-KPX s comma -11
-
-KPX semicolon space -40
-
-KPX space quoteleft -48
-KPX space quotedblleft -24
-KPX space Y -73
-KPX space W -32
-KPX space V -40
-KPX space T -40
-
-KPX v period -65
-KPX v o -20
-KPX v e -20
-KPX v comma -65
-KPX v a -20
-
-KPX w period -48
-KPX w o -7
-KPX w e -7
-KPX w comma -48
-KPX w a -11
-
-KPX x e -24
-
-KPX y period -81
-KPX y o -15
-KPX y e -15
-KPX y comma -81
-KPX y a -15
-
-KPX z o -11
-KPX z e -11
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 137 195 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 137 195 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 137 195 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 137 195 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 137 175 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 137 195 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 160 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 137 195 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 137 195 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 137 195 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 137 195 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute -22 195 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex -22 195 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis -22 195 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave -22 195 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 168 195 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 183 195 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 183 195 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 183 195 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 183 195 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 183 195 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 137 195 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 160 195 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 160 195 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 160 195 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 160 195 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 137 195 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 137 195 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 114 195 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 92 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 92 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 92 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 92 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 92 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 69 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 92 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 92 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 92 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -22 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -22 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -22 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -22 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 92 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 92 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 92 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 92 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 92 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 69 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 92 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 92 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 92 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 92 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 69 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 69 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 69 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvro8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvro8a.afm
deleted file mode 100644
index 3d69eb7c8e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvro8a.afm
+++ /dev/null
@@ -1,612 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.
-Comment Creation Date: Thu Mar 15 10:24:18 1990
-Comment UniqueID 28362
-Comment VMusage 7572 42473
-FontName Helvetica-Oblique
-FullName Helvetica Oblique
-FamilyName Helvetica
-Weight Medium
-ItalicAngle -12
-IsFixedPitch false
-FontBBox -170 -225 1116 931
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.006
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 718
-XHeight 523
-Ascender 718
-Descender -207
-StartCharMetrics 228
-C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 278 ; N exclam ; B 90 0 340 718 ;
-C 34 ; WX 355 ; N quotedbl ; B 168 463 438 718 ;
-C 35 ; WX 556 ; N numbersign ; B 73 0 631 688 ;
-C 36 ; WX 556 ; N dollar ; B 69 -115 617 775 ;
-C 37 ; WX 889 ; N percent ; B 147 -19 889 703 ;
-C 38 ; WX 667 ; N ampersand ; B 77 -15 647 718 ;
-C 39 ; WX 222 ; N quoteright ; B 151 463 310 718 ;
-C 40 ; WX 333 ; N parenleft ; B 108 -207 454 733 ;
-C 41 ; WX 333 ; N parenright ; B -9 -207 337 733 ;
-C 42 ; WX 389 ; N asterisk ; B 165 431 475 718 ;
-C 43 ; WX 584 ; N plus ; B 85 0 606 505 ;
-C 44 ; WX 278 ; N comma ; B 56 -147 214 106 ;
-C 45 ; WX 333 ; N hyphen ; B 93 232 357 322 ;
-C 46 ; WX 278 ; N period ; B 87 0 214 106 ;
-C 47 ; WX 278 ; N slash ; B -21 -19 452 737 ;
-C 48 ; WX 556 ; N zero ; B 93 -19 608 703 ;
-C 49 ; WX 556 ; N one ; B 207 0 508 703 ;
-C 50 ; WX 556 ; N two ; B 26 0 617 703 ;
-C 51 ; WX 556 ; N three ; B 75 -19 610 703 ;
-C 52 ; WX 556 ; N four ; B 61 0 576 703 ;
-C 53 ; WX 556 ; N five ; B 68 -19 621 688 ;
-C 54 ; WX 556 ; N six ; B 91 -19 615 703 ;
-C 55 ; WX 556 ; N seven ; B 137 0 669 688 ;
-C 56 ; WX 556 ; N eight ; B 74 -19 607 703 ;
-C 57 ; WX 556 ; N nine ; B 82 -19 609 703 ;
-C 58 ; WX 278 ; N colon ; B 87 0 301 516 ;
-C 59 ; WX 278 ; N semicolon ; B 56 -147 301 516 ;
-C 60 ; WX 584 ; N less ; B 94 11 641 495 ;
-C 61 ; WX 584 ; N equal ; B 63 115 628 390 ;
-C 62 ; WX 584 ; N greater ; B 50 11 597 495 ;
-C 63 ; WX 556 ; N question ; B 161 0 610 727 ;
-C 64 ; WX 1015 ; N at ; B 215 -19 965 737 ;
-C 65 ; WX 667 ; N A ; B 14 0 654 718 ;
-C 66 ; WX 667 ; N B ; B 74 0 712 718 ;
-C 67 ; WX 722 ; N C ; B 108 -19 782 737 ;
-C 68 ; WX 722 ; N D ; B 81 0 764 718 ;
-C 69 ; WX 667 ; N E ; B 86 0 762 718 ;
-C 70 ; WX 611 ; N F ; B 86 0 736 718 ;
-C 71 ; WX 778 ; N G ; B 111 -19 799 737 ;
-C 72 ; WX 722 ; N H ; B 77 0 799 718 ;
-C 73 ; WX 278 ; N I ; B 91 0 341 718 ;
-C 74 ; WX 500 ; N J ; B 47 -19 581 718 ;
-C 75 ; WX 667 ; N K ; B 76 0 808 718 ;
-C 76 ; WX 556 ; N L ; B 76 0 555 718 ;
-C 77 ; WX 833 ; N M ; B 73 0 914 718 ;
-C 78 ; WX 722 ; N N ; B 76 0 799 718 ;
-C 79 ; WX 778 ; N O ; B 105 -19 826 737 ;
-C 80 ; WX 667 ; N P ; B 86 0 737 718 ;
-C 81 ; WX 778 ; N Q ; B 105 -56 826 737 ;
-C 82 ; WX 722 ; N R ; B 88 0 773 718 ;
-C 83 ; WX 667 ; N S ; B 90 -19 713 737 ;
-C 84 ; WX 611 ; N T ; B 148 0 750 718 ;
-C 85 ; WX 722 ; N U ; B 123 -19 797 718 ;
-C 86 ; WX 667 ; N V ; B 173 0 800 718 ;
-C 87 ; WX 944 ; N W ; B 169 0 1081 718 ;
-C 88 ; WX 667 ; N X ; B 19 0 790 718 ;
-C 89 ; WX 667 ; N Y ; B 167 0 806 718 ;
-C 90 ; WX 611 ; N Z ; B 23 0 741 718 ;
-C 91 ; WX 278 ; N bracketleft ; B 21 -196 403 722 ;
-C 92 ; WX 278 ; N backslash ; B 140 -19 291 737 ;
-C 93 ; WX 278 ; N bracketright ; B -14 -196 368 722 ;
-C 94 ; WX 469 ; N asciicircum ; B 42 264 539 688 ;
-C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ;
-C 96 ; WX 222 ; N quoteleft ; B 165 470 323 725 ;
-C 97 ; WX 556 ; N a ; B 61 -15 559 538 ;
-C 98 ; WX 556 ; N b ; B 58 -15 584 718 ;
-C 99 ; WX 500 ; N c ; B 74 -15 553 538 ;
-C 100 ; WX 556 ; N d ; B 84 -15 652 718 ;
-C 101 ; WX 556 ; N e ; B 84 -15 578 538 ;
-C 102 ; WX 278 ; N f ; B 86 0 416 728 ; L i fi ; L l fl ;
-C 103 ; WX 556 ; N g ; B 42 -220 610 538 ;
-C 104 ; WX 556 ; N h ; B 65 0 573 718 ;
-C 105 ; WX 222 ; N i ; B 67 0 308 718 ;
-C 106 ; WX 222 ; N j ; B -60 -210 308 718 ;
-C 107 ; WX 500 ; N k ; B 67 0 600 718 ;
-C 108 ; WX 222 ; N l ; B 67 0 308 718 ;
-C 109 ; WX 833 ; N m ; B 65 0 852 538 ;
-C 110 ; WX 556 ; N n ; B 65 0 573 538 ;
-C 111 ; WX 556 ; N o ; B 83 -14 585 538 ;
-C 112 ; WX 556 ; N p ; B 14 -207 584 538 ;
-C 113 ; WX 556 ; N q ; B 84 -207 605 538 ;
-C 114 ; WX 333 ; N r ; B 77 0 446 538 ;
-C 115 ; WX 500 ; N s ; B 63 -15 529 538 ;
-C 116 ; WX 278 ; N t ; B 102 -7 368 669 ;
-C 117 ; WX 556 ; N u ; B 94 -15 600 523 ;
-C 118 ; WX 500 ; N v ; B 119 0 603 523 ;
-C 119 ; WX 722 ; N w ; B 125 0 820 523 ;
-C 120 ; WX 500 ; N x ; B 11 0 594 523 ;
-C 121 ; WX 500 ; N y ; B 15 -214 600 523 ;
-C 122 ; WX 500 ; N z ; B 31 0 571 523 ;
-C 123 ; WX 334 ; N braceleft ; B 92 -196 445 722 ;
-C 124 ; WX 260 ; N bar ; B 90 -19 324 737 ;
-C 125 ; WX 334 ; N braceright ; B 0 -196 354 722 ;
-C 126 ; WX 584 ; N asciitilde ; B 111 180 580 326 ;
-C 161 ; WX 333 ; N exclamdown ; B 77 -195 326 523 ;
-C 162 ; WX 556 ; N cent ; B 95 -115 584 623 ;
-C 163 ; WX 556 ; N sterling ; B 49 -16 634 718 ;
-C 164 ; WX 167 ; N fraction ; B -170 -19 482 703 ;
-C 165 ; WX 556 ; N yen ; B 81 0 699 688 ;
-C 166 ; WX 556 ; N florin ; B -52 -207 654 737 ;
-C 167 ; WX 556 ; N section ; B 76 -191 584 737 ;
-C 168 ; WX 556 ; N currency ; B 60 99 646 603 ;
-C 169 ; WX 191 ; N quotesingle ; B 157 463 285 718 ;
-C 170 ; WX 333 ; N quotedblleft ; B 138 470 461 725 ;
-C 171 ; WX 556 ; N guillemotleft ; B 146 108 554 446 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 137 108 340 446 ;
-C 173 ; WX 333 ; N guilsinglright ; B 111 108 314 446 ;
-C 174 ; WX 500 ; N fi ; B 86 0 587 728 ;
-C 175 ; WX 500 ; N fl ; B 86 0 585 728 ;
-C 177 ; WX 556 ; N endash ; B 51 240 623 313 ;
-C 178 ; WX 556 ; N dagger ; B 135 -159 622 718 ;
-C 179 ; WX 556 ; N daggerdbl ; B 52 -159 623 718 ;
-C 180 ; WX 278 ; N periodcentered ; B 129 190 257 315 ;
-C 182 ; WX 537 ; N paragraph ; B 126 -173 650 718 ;
-C 183 ; WX 350 ; N bullet ; B 91 202 413 517 ;
-C 184 ; WX 222 ; N quotesinglbase ; B 21 -149 180 106 ;
-C 185 ; WX 333 ; N quotedblbase ; B -6 -149 318 106 ;
-C 186 ; WX 333 ; N quotedblright ; B 124 463 448 718 ;
-C 187 ; WX 556 ; N guillemotright ; B 120 108 528 446 ;
-C 188 ; WX 1000 ; N ellipsis ; B 115 0 908 106 ;
-C 189 ; WX 1000 ; N perthousand ; B 88 -19 1029 703 ;
-C 191 ; WX 611 ; N questiondown ; B 85 -201 534 525 ;
-C 193 ; WX 333 ; N grave ; B 170 593 337 734 ;
-C 194 ; WX 333 ; N acute ; B 248 593 475 734 ;
-C 195 ; WX 333 ; N circumflex ; B 147 593 438 734 ;
-C 196 ; WX 333 ; N tilde ; B 125 606 490 722 ;
-C 197 ; WX 333 ; N macron ; B 143 627 468 684 ;
-C 198 ; WX 333 ; N breve ; B 167 595 476 731 ;
-C 199 ; WX 333 ; N dotaccent ; B 249 604 362 706 ;
-C 200 ; WX 333 ; N dieresis ; B 168 604 443 706 ;
-C 202 ; WX 333 ; N ring ; B 214 572 402 756 ;
-C 203 ; WX 333 ; N cedilla ; B 2 -225 232 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 157 593 565 734 ;
-C 206 ; WX 333 ; N ogonek ; B 43 -225 249 0 ;
-C 207 ; WX 333 ; N caron ; B 177 593 468 734 ;
-C 208 ; WX 1000 ; N emdash ; B 51 240 1067 313 ;
-C 225 ; WX 1000 ; N AE ; B 8 0 1097 718 ;
-C 227 ; WX 370 ; N ordfeminine ; B 100 304 449 737 ;
-C 232 ; WX 556 ; N Lslash ; B 41 0 555 718 ;
-C 233 ; WX 778 ; N Oslash ; B 43 -19 890 737 ;
-C 234 ; WX 1000 ; N OE ; B 98 -19 1116 737 ;
-C 235 ; WX 365 ; N ordmasculine ; B 100 304 468 737 ;
-C 241 ; WX 889 ; N ae ; B 61 -15 909 538 ;
-C 245 ; WX 278 ; N dotlessi ; B 95 0 294 523 ;
-C 248 ; WX 222 ; N lslash ; B 41 0 347 718 ;
-C 249 ; WX 611 ; N oslash ; B 29 -22 647 545 ;
-C 250 ; WX 944 ; N oe ; B 83 -15 964 538 ;
-C 251 ; WX 611 ; N germandbls ; B 67 -15 658 728 ;
-C -1 ; WX 611 ; N Zcaron ; B 23 0 741 929 ;
-C -1 ; WX 500 ; N ccedilla ; B 74 -225 553 538 ;
-C -1 ; WX 500 ; N ydieresis ; B 15 -214 600 706 ;
-C -1 ; WX 556 ; N atilde ; B 61 -15 592 722 ;
-C -1 ; WX 278 ; N icircumflex ; B 95 0 411 734 ;
-C -1 ; WX 333 ; N threesuperior ; B 90 270 436 703 ;
-C -1 ; WX 556 ; N ecircumflex ; B 84 -15 578 734 ;
-C -1 ; WX 556 ; N thorn ; B 14 -207 584 718 ;
-C -1 ; WX 556 ; N egrave ; B 84 -15 578 734 ;
-C -1 ; WX 333 ; N twosuperior ; B 64 281 449 703 ;
-C -1 ; WX 556 ; N eacute ; B 84 -15 587 734 ;
-C -1 ; WX 556 ; N otilde ; B 83 -14 602 722 ;
-C -1 ; WX 667 ; N Aacute ; B 14 0 683 929 ;
-C -1 ; WX 556 ; N ocircumflex ; B 83 -14 585 734 ;
-C -1 ; WX 500 ; N yacute ; B 15 -214 600 734 ;
-C -1 ; WX 556 ; N udieresis ; B 94 -15 600 706 ;
-C -1 ; WX 834 ; N threequarters ; B 130 -19 861 703 ;
-C -1 ; WX 556 ; N acircumflex ; B 61 -15 559 734 ;
-C -1 ; WX 722 ; N Eth ; B 69 0 764 718 ;
-C -1 ; WX 556 ; N edieresis ; B 84 -15 578 706 ;
-C -1 ; WX 556 ; N ugrave ; B 94 -15 600 734 ;
-C -1 ; WX 1000 ; N trademark ; B 186 306 1056 718 ;
-C -1 ; WX 556 ; N ograve ; B 83 -14 585 734 ;
-C -1 ; WX 500 ; N scaron ; B 63 -15 552 734 ;
-C -1 ; WX 278 ; N Idieresis ; B 91 0 458 901 ;
-C -1 ; WX 556 ; N uacute ; B 94 -15 600 734 ;
-C -1 ; WX 556 ; N agrave ; B 61 -15 559 734 ;
-C -1 ; WX 556 ; N ntilde ; B 65 0 592 722 ;
-C -1 ; WX 556 ; N aring ; B 61 -15 559 756 ;
-C -1 ; WX 500 ; N zcaron ; B 31 0 571 734 ;
-C -1 ; WX 278 ; N Icircumflex ; B 91 0 452 929 ;
-C -1 ; WX 722 ; N Ntilde ; B 76 0 799 917 ;
-C -1 ; WX 556 ; N ucircumflex ; B 94 -15 600 734 ;
-C -1 ; WX 667 ; N Ecircumflex ; B 86 0 762 929 ;
-C -1 ; WX 278 ; N Iacute ; B 91 0 489 929 ;
-C -1 ; WX 722 ; N Ccedilla ; B 108 -225 782 737 ;
-C -1 ; WX 778 ; N Odieresis ; B 105 -19 826 901 ;
-C -1 ; WX 667 ; N Scaron ; B 90 -19 713 929 ;
-C -1 ; WX 667 ; N Edieresis ; B 86 0 762 901 ;
-C -1 ; WX 278 ; N Igrave ; B 91 0 351 929 ;
-C -1 ; WX 556 ; N adieresis ; B 61 -15 559 706 ;
-C -1 ; WX 778 ; N Ograve ; B 105 -19 826 929 ;
-C -1 ; WX 667 ; N Egrave ; B 86 0 762 929 ;
-C -1 ; WX 667 ; N Ydieresis ; B 167 0 806 901 ;
-C -1 ; WX 737 ; N registered ; B 54 -19 837 737 ;
-C -1 ; WX 778 ; N Otilde ; B 105 -19 826 917 ;
-C -1 ; WX 834 ; N onequarter ; B 150 -19 802 703 ;
-C -1 ; WX 722 ; N Ugrave ; B 123 -19 797 929 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 123 -19 797 929 ;
-C -1 ; WX 667 ; N Thorn ; B 86 0 712 718 ;
-C -1 ; WX 584 ; N divide ; B 85 -19 606 524 ;
-C -1 ; WX 667 ; N Atilde ; B 14 0 699 917 ;
-C -1 ; WX 722 ; N Uacute ; B 123 -19 797 929 ;
-C -1 ; WX 778 ; N Ocircumflex ; B 105 -19 826 929 ;
-C -1 ; WX 584 ; N logicalnot ; B 106 108 628 390 ;
-C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ;
-C -1 ; WX 278 ; N idieresis ; B 95 0 416 706 ;
-C -1 ; WX 278 ; N iacute ; B 95 0 448 734 ;
-C -1 ; WX 556 ; N aacute ; B 61 -15 587 734 ;
-C -1 ; WX 584 ; N plusminus ; B 39 0 618 506 ;
-C -1 ; WX 584 ; N multiply ; B 50 0 642 506 ;
-C -1 ; WX 722 ; N Udieresis ; B 123 -19 797 901 ;
-C -1 ; WX 584 ; N minus ; B 85 216 606 289 ;
-C -1 ; WX 333 ; N onesuperior ; B 166 281 371 703 ;
-C -1 ; WX 667 ; N Eacute ; B 86 0 762 929 ;
-C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ;
-C -1 ; WX 737 ; N copyright ; B 54 -19 837 737 ;
-C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ;
-C -1 ; WX 556 ; N odieresis ; B 83 -14 585 706 ;
-C -1 ; WX 556 ; N oacute ; B 83 -14 587 734 ;
-C -1 ; WX 400 ; N degree ; B 169 411 468 703 ;
-C -1 ; WX 278 ; N igrave ; B 95 0 310 734 ;
-C -1 ; WX 556 ; N mu ; B 24 -207 600 523 ;
-C -1 ; WX 778 ; N Oacute ; B 105 -19 826 929 ;
-C -1 ; WX 556 ; N eth ; B 81 -15 617 737 ;
-C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ;
-C -1 ; WX 667 ; N Yacute ; B 167 0 806 929 ;
-C -1 ; WX 260 ; N brokenbar ; B 90 -19 324 737 ;
-C -1 ; WX 834 ; N onehalf ; B 114 -19 839 703 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 250
-
-KPX A y -40
-KPX A w -40
-KPX A v -40
-KPX A u -30
-KPX A Y -100
-KPX A W -50
-KPX A V -70
-KPX A U -50
-KPX A T -120
-KPX A Q -30
-KPX A O -30
-KPX A G -30
-KPX A C -30
-
-KPX B period -20
-KPX B comma -20
-KPX B U -10
-
-KPX C period -30
-KPX C comma -30
-
-KPX D period -70
-KPX D comma -70
-KPX D Y -90
-KPX D W -40
-KPX D V -70
-KPX D A -40
-
-KPX F r -45
-KPX F period -150
-KPX F o -30
-KPX F e -30
-KPX F comma -150
-KPX F a -50
-KPX F A -80
-
-KPX J u -20
-KPX J period -30
-KPX J comma -30
-KPX J a -20
-KPX J A -20
-
-KPX K y -50
-KPX K u -30
-KPX K o -40
-KPX K e -40
-KPX K O -50
-
-KPX L y -30
-KPX L quoteright -160
-KPX L quotedblright -140
-KPX L Y -140
-KPX L W -70
-KPX L V -110
-KPX L T -110
-
-KPX O period -40
-KPX O comma -40
-KPX O Y -70
-KPX O X -60
-KPX O W -30
-KPX O V -50
-KPX O T -40
-KPX O A -20
-
-KPX P period -180
-KPX P o -50
-KPX P e -50
-KPX P comma -180
-KPX P a -40
-KPX P A -120
-
-KPX Q U -10
-
-KPX R Y -50
-KPX R W -30
-KPX R V -50
-KPX R U -40
-KPX R T -30
-KPX R O -20
-
-KPX S period -20
-KPX S comma -20
-
-KPX T y -120
-KPX T w -120
-KPX T u -120
-KPX T semicolon -20
-KPX T r -120
-KPX T period -120
-KPX T o -120
-KPX T hyphen -140
-KPX T e -120
-KPX T comma -120
-KPX T colon -20
-KPX T a -120
-KPX T O -40
-KPX T A -120
-
-KPX U period -40
-KPX U comma -40
-KPX U A -40
-
-KPX V u -70
-KPX V semicolon -40
-KPX V period -125
-KPX V o -80
-KPX V hyphen -80
-KPX V e -80
-KPX V comma -125
-KPX V colon -40
-KPX V a -70
-KPX V O -40
-KPX V G -40
-KPX V A -80
-
-KPX W y -20
-KPX W u -30
-KPX W period -80
-KPX W o -30
-KPX W hyphen -40
-KPX W e -30
-KPX W comma -80
-KPX W a -40
-KPX W O -20
-KPX W A -50
-
-KPX Y u -110
-KPX Y semicolon -60
-KPX Y period -140
-KPX Y o -140
-KPX Y i -20
-KPX Y hyphen -140
-KPX Y e -140
-KPX Y comma -140
-KPX Y colon -60
-KPX Y a -140
-KPX Y O -85
-KPX Y A -110
-
-KPX a y -30
-KPX a w -20
-KPX a v -20
-
-KPX b y -20
-KPX b v -20
-KPX b u -20
-KPX b period -40
-KPX b l -20
-KPX b comma -40
-KPX b b -10
-
-KPX c k -20
-KPX c comma -15
-
-KPX colon space -50
-
-KPX comma quoteright -100
-KPX comma quotedblright -100
-
-KPX e y -20
-KPX e x -30
-KPX e w -20
-KPX e v -30
-KPX e period -15
-KPX e comma -15
-
-KPX f quoteright 50
-KPX f quotedblright 60
-KPX f period -30
-KPX f o -30
-KPX f e -30
-KPX f dotlessi -28
-KPX f comma -30
-KPX f a -30
-
-KPX g r -10
-
-KPX h y -30
-
-KPX k o -20
-KPX k e -20
-
-KPX m y -15
-KPX m u -10
-
-KPX n y -15
-KPX n v -20
-KPX n u -10
-
-KPX o y -30
-KPX o x -30
-KPX o w -15
-KPX o v -15
-KPX o period -40
-KPX o comma -40
-
-KPX oslash z -55
-KPX oslash y -70
-KPX oslash x -85
-KPX oslash w -70
-KPX oslash v -70
-KPX oslash u -55
-KPX oslash t -55
-KPX oslash s -55
-KPX oslash r -55
-KPX oslash q -55
-KPX oslash period -95
-KPX oslash p -55
-KPX oslash o -55
-KPX oslash n -55
-KPX oslash m -55
-KPX oslash l -55
-KPX oslash k -55
-KPX oslash j -55
-KPX oslash i -55
-KPX oslash h -55
-KPX oslash g -55
-KPX oslash f -55
-KPX oslash e -55
-KPX oslash d -55
-KPX oslash comma -95
-KPX oslash c -55
-KPX oslash b -55
-KPX oslash a -55
-
-KPX p y -30
-KPX p period -35
-KPX p comma -35
-
-KPX period space -60
-KPX period quoteright -100
-KPX period quotedblright -100
-
-KPX quotedblright space -40
-
-KPX quoteleft quoteleft -57
-
-KPX quoteright space -70
-KPX quoteright s -50
-KPX quoteright r -50
-KPX quoteright quoteright -57
-KPX quoteright d -50
-
-KPX r y 30
-KPX r v 30
-KPX r u 15
-KPX r t 40
-KPX r semicolon 30
-KPX r period -50
-KPX r p 30
-KPX r n 25
-KPX r m 25
-KPX r l 15
-KPX r k 15
-KPX r i 15
-KPX r comma -50
-KPX r colon 30
-KPX r a -10
-
-KPX s w -30
-KPX s period -15
-KPX s comma -15
-
-KPX semicolon space -50
-
-KPX space quoteleft -60
-KPX space quotedblleft -30
-KPX space Y -90
-KPX space W -40
-KPX space V -50
-KPX space T -50
-
-KPX v period -80
-KPX v o -25
-KPX v e -25
-KPX v comma -80
-KPX v a -25
-
-KPX w period -60
-KPX w o -10
-KPX w e -10
-KPX w comma -60
-KPX w a -15
-
-KPX x e -30
-
-KPX y period -100
-KPX y o -20
-KPX y e -20
-KPX y comma -100
-KPX y a -20
-
-KPX z o -15
-KPX z e -15
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 208 195 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 208 195 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 208 195 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 208 195 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 204 175 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 208 195 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 195 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 208 195 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 208 195 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 208 195 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 208 195 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 14 195 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 14 195 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 14 195 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 14 195 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 246 195 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 264 195 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 264 195 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 264 195 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 264 195 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 264 195 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 208 195 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 236 195 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 236 195 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 236 195 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 236 195 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 208 195 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 208 195 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 180 195 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 112 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 102 0 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 84 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 112 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 112 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 112 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 112 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 102 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 112 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 112 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 112 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 84 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 112 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 112 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvro8an.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvro8an.afm
deleted file mode 100644
index f757319a4c..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/phvro8an.afm
+++ /dev/null
@@ -1,612 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.
-Comment Creation Date: Thu Mar 15 11:25:48 1990
-Comment UniqueID 28389
-Comment VMusage 7572 42473
-FontName Helvetica-Narrow-Oblique
-FullName Helvetica Narrow Oblique
-FamilyName Helvetica
-Weight Medium
-ItalicAngle -12
-IsFixedPitch false
-FontBBox -139 -225 915 931
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.006
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.Helvetica is a trademark of Linotype AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 718
-XHeight 523
-Ascender 718
-Descender -207
-StartCharMetrics 228
-C 32 ; WX 228 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 228 ; N exclam ; B 74 0 278 718 ;
-C 34 ; WX 291 ; N quotedbl ; B 138 463 359 718 ;
-C 35 ; WX 456 ; N numbersign ; B 60 0 517 688 ;
-C 36 ; WX 456 ; N dollar ; B 57 -115 506 775 ;
-C 37 ; WX 729 ; N percent ; B 120 -19 729 703 ;
-C 38 ; WX 547 ; N ampersand ; B 63 -15 530 718 ;
-C 39 ; WX 182 ; N quoteright ; B 124 463 254 718 ;
-C 40 ; WX 273 ; N parenleft ; B 89 -207 372 733 ;
-C 41 ; WX 273 ; N parenright ; B -7 -207 276 733 ;
-C 42 ; WX 319 ; N asterisk ; B 135 431 389 718 ;
-C 43 ; WX 479 ; N plus ; B 70 0 497 505 ;
-C 44 ; WX 228 ; N comma ; B 46 -147 175 106 ;
-C 45 ; WX 273 ; N hyphen ; B 77 232 293 322 ;
-C 46 ; WX 228 ; N period ; B 71 0 175 106 ;
-C 47 ; WX 228 ; N slash ; B -17 -19 370 737 ;
-C 48 ; WX 456 ; N zero ; B 77 -19 499 703 ;
-C 49 ; WX 456 ; N one ; B 170 0 417 703 ;
-C 50 ; WX 456 ; N two ; B 21 0 506 703 ;
-C 51 ; WX 456 ; N three ; B 61 -19 500 703 ;
-C 52 ; WX 456 ; N four ; B 50 0 472 703 ;
-C 53 ; WX 456 ; N five ; B 55 -19 509 688 ;
-C 54 ; WX 456 ; N six ; B 74 -19 504 703 ;
-C 55 ; WX 456 ; N seven ; B 112 0 549 688 ;
-C 56 ; WX 456 ; N eight ; B 60 -19 497 703 ;
-C 57 ; WX 456 ; N nine ; B 67 -19 499 703 ;
-C 58 ; WX 228 ; N colon ; B 71 0 247 516 ;
-C 59 ; WX 228 ; N semicolon ; B 46 -147 247 516 ;
-C 60 ; WX 479 ; N less ; B 77 11 526 495 ;
-C 61 ; WX 479 ; N equal ; B 52 115 515 390 ;
-C 62 ; WX 479 ; N greater ; B 41 11 490 495 ;
-C 63 ; WX 456 ; N question ; B 132 0 500 727 ;
-C 64 ; WX 832 ; N at ; B 176 -19 791 737 ;
-C 65 ; WX 547 ; N A ; B 11 0 536 718 ;
-C 66 ; WX 547 ; N B ; B 61 0 583 718 ;
-C 67 ; WX 592 ; N C ; B 88 -19 640 737 ;
-C 68 ; WX 592 ; N D ; B 66 0 626 718 ;
-C 69 ; WX 547 ; N E ; B 71 0 625 718 ;
-C 70 ; WX 501 ; N F ; B 71 0 603 718 ;
-C 71 ; WX 638 ; N G ; B 91 -19 655 737 ;
-C 72 ; WX 592 ; N H ; B 63 0 655 718 ;
-C 73 ; WX 228 ; N I ; B 75 0 279 718 ;
-C 74 ; WX 410 ; N J ; B 39 -19 476 718 ;
-C 75 ; WX 547 ; N K ; B 62 0 662 718 ;
-C 76 ; WX 456 ; N L ; B 62 0 455 718 ;
-C 77 ; WX 683 ; N M ; B 60 0 749 718 ;
-C 78 ; WX 592 ; N N ; B 62 0 655 718 ;
-C 79 ; WX 638 ; N O ; B 86 -19 677 737 ;
-C 80 ; WX 547 ; N P ; B 71 0 604 718 ;
-C 81 ; WX 638 ; N Q ; B 86 -56 677 737 ;
-C 82 ; WX 592 ; N R ; B 72 0 634 718 ;
-C 83 ; WX 547 ; N S ; B 74 -19 584 737 ;
-C 84 ; WX 501 ; N T ; B 122 0 615 718 ;
-C 85 ; WX 592 ; N U ; B 101 -19 653 718 ;
-C 86 ; WX 547 ; N V ; B 142 0 656 718 ;
-C 87 ; WX 774 ; N W ; B 138 0 886 718 ;
-C 88 ; WX 547 ; N X ; B 16 0 647 718 ;
-C 89 ; WX 547 ; N Y ; B 137 0 661 718 ;
-C 90 ; WX 501 ; N Z ; B 19 0 607 718 ;
-C 91 ; WX 228 ; N bracketleft ; B 17 -196 331 722 ;
-C 92 ; WX 228 ; N backslash ; B 115 -19 239 737 ;
-C 93 ; WX 228 ; N bracketright ; B -11 -196 302 722 ;
-C 94 ; WX 385 ; N asciicircum ; B 35 264 442 688 ;
-C 95 ; WX 456 ; N underscore ; B -22 -125 443 -75 ;
-C 96 ; WX 182 ; N quoteleft ; B 135 470 265 725 ;
-C 97 ; WX 456 ; N a ; B 50 -15 458 538 ;
-C 98 ; WX 456 ; N b ; B 48 -15 479 718 ;
-C 99 ; WX 410 ; N c ; B 61 -15 454 538 ;
-C 100 ; WX 456 ; N d ; B 69 -15 534 718 ;
-C 101 ; WX 456 ; N e ; B 69 -15 474 538 ;
-C 102 ; WX 228 ; N f ; B 71 0 341 728 ; L i fi ; L l fl ;
-C 103 ; WX 456 ; N g ; B 34 -220 500 538 ;
-C 104 ; WX 456 ; N h ; B 53 0 470 718 ;
-C 105 ; WX 182 ; N i ; B 55 0 252 718 ;
-C 106 ; WX 182 ; N j ; B -49 -210 252 718 ;
-C 107 ; WX 410 ; N k ; B 55 0 492 718 ;
-C 108 ; WX 182 ; N l ; B 55 0 252 718 ;
-C 109 ; WX 683 ; N m ; B 53 0 699 538 ;
-C 110 ; WX 456 ; N n ; B 53 0 470 538 ;
-C 111 ; WX 456 ; N o ; B 68 -14 479 538 ;
-C 112 ; WX 456 ; N p ; B 11 -207 479 538 ;
-C 113 ; WX 456 ; N q ; B 69 -207 496 538 ;
-C 114 ; WX 273 ; N r ; B 63 0 365 538 ;
-C 115 ; WX 410 ; N s ; B 52 -15 434 538 ;
-C 116 ; WX 228 ; N t ; B 84 -7 302 669 ;
-C 117 ; WX 456 ; N u ; B 77 -15 492 523 ;
-C 118 ; WX 410 ; N v ; B 98 0 495 523 ;
-C 119 ; WX 592 ; N w ; B 103 0 673 523 ;
-C 120 ; WX 410 ; N x ; B 9 0 487 523 ;
-C 121 ; WX 410 ; N y ; B 12 -214 492 523 ;
-C 122 ; WX 410 ; N z ; B 25 0 468 523 ;
-C 123 ; WX 274 ; N braceleft ; B 75 -196 365 722 ;
-C 124 ; WX 213 ; N bar ; B 74 -19 265 737 ;
-C 125 ; WX 274 ; N braceright ; B 0 -196 291 722 ;
-C 126 ; WX 479 ; N asciitilde ; B 91 180 476 326 ;
-C 161 ; WX 273 ; N exclamdown ; B 63 -195 267 523 ;
-C 162 ; WX 456 ; N cent ; B 78 -115 479 623 ;
-C 163 ; WX 456 ; N sterling ; B 40 -16 520 718 ;
-C 164 ; WX 137 ; N fraction ; B -139 -19 396 703 ;
-C 165 ; WX 456 ; N yen ; B 67 0 573 688 ;
-C 166 ; WX 456 ; N florin ; B -43 -207 537 737 ;
-C 167 ; WX 456 ; N section ; B 63 -191 479 737 ;
-C 168 ; WX 456 ; N currency ; B 49 99 530 603 ;
-C 169 ; WX 157 ; N quotesingle ; B 129 463 233 718 ;
-C 170 ; WX 273 ; N quotedblleft ; B 113 470 378 725 ;
-C 171 ; WX 456 ; N guillemotleft ; B 120 108 454 446 ;
-C 172 ; WX 273 ; N guilsinglleft ; B 112 108 279 446 ;
-C 173 ; WX 273 ; N guilsinglright ; B 91 108 257 446 ;
-C 174 ; WX 410 ; N fi ; B 71 0 481 728 ;
-C 175 ; WX 410 ; N fl ; B 71 0 479 728 ;
-C 177 ; WX 456 ; N endash ; B 42 240 510 313 ;
-C 178 ; WX 456 ; N dagger ; B 110 -159 510 718 ;
-C 179 ; WX 456 ; N daggerdbl ; B 43 -159 511 718 ;
-C 180 ; WX 228 ; N periodcentered ; B 106 190 211 315 ;
-C 182 ; WX 440 ; N paragraph ; B 103 -173 533 718 ;
-C 183 ; WX 287 ; N bullet ; B 74 202 339 517 ;
-C 184 ; WX 182 ; N quotesinglbase ; B 17 -149 147 106 ;
-C 185 ; WX 273 ; N quotedblbase ; B -5 -149 260 106 ;
-C 186 ; WX 273 ; N quotedblright ; B 102 463 367 718 ;
-C 187 ; WX 456 ; N guillemotright ; B 98 108 433 446 ;
-C 188 ; WX 820 ; N ellipsis ; B 94 0 744 106 ;
-C 189 ; WX 820 ; N perthousand ; B 72 -19 844 703 ;
-C 191 ; WX 501 ; N questiondown ; B 70 -201 438 525 ;
-C 193 ; WX 273 ; N grave ; B 139 593 276 734 ;
-C 194 ; WX 273 ; N acute ; B 203 593 390 734 ;
-C 195 ; WX 273 ; N circumflex ; B 121 593 359 734 ;
-C 196 ; WX 273 ; N tilde ; B 102 606 402 722 ;
-C 197 ; WX 273 ; N macron ; B 117 627 384 684 ;
-C 198 ; WX 273 ; N breve ; B 137 595 391 731 ;
-C 199 ; WX 273 ; N dotaccent ; B 204 604 297 706 ;
-C 200 ; WX 273 ; N dieresis ; B 138 604 363 706 ;
-C 202 ; WX 273 ; N ring ; B 175 572 330 756 ;
-C 203 ; WX 273 ; N cedilla ; B 2 -225 191 0 ;
-C 205 ; WX 273 ; N hungarumlaut ; B 129 593 463 734 ;
-C 206 ; WX 273 ; N ogonek ; B 35 -225 204 0 ;
-C 207 ; WX 273 ; N caron ; B 145 593 384 734 ;
-C 208 ; WX 820 ; N emdash ; B 42 240 875 313 ;
-C 225 ; WX 820 ; N AE ; B 7 0 899 718 ;
-C 227 ; WX 303 ; N ordfeminine ; B 82 304 368 737 ;
-C 232 ; WX 456 ; N Lslash ; B 34 0 455 718 ;
-C 233 ; WX 638 ; N Oslash ; B 35 -19 730 737 ;
-C 234 ; WX 820 ; N OE ; B 80 -19 915 737 ;
-C 235 ; WX 299 ; N ordmasculine ; B 82 304 384 737 ;
-C 241 ; WX 729 ; N ae ; B 50 -15 746 538 ;
-C 245 ; WX 228 ; N dotlessi ; B 78 0 241 523 ;
-C 248 ; WX 182 ; N lslash ; B 34 0 284 718 ;
-C 249 ; WX 501 ; N oslash ; B 24 -22 531 545 ;
-C 250 ; WX 774 ; N oe ; B 68 -15 791 538 ;
-C 251 ; WX 501 ; N germandbls ; B 55 -15 539 728 ;
-C -1 ; WX 501 ; N Zcaron ; B 19 0 607 929 ;
-C -1 ; WX 410 ; N ccedilla ; B 61 -225 454 538 ;
-C -1 ; WX 410 ; N ydieresis ; B 12 -214 492 706 ;
-C -1 ; WX 456 ; N atilde ; B 50 -15 486 722 ;
-C -1 ; WX 228 ; N icircumflex ; B 78 0 337 734 ;
-C -1 ; WX 273 ; N threesuperior ; B 74 270 358 703 ;
-C -1 ; WX 456 ; N ecircumflex ; B 69 -15 474 734 ;
-C -1 ; WX 456 ; N thorn ; B 11 -207 479 718 ;
-C -1 ; WX 456 ; N egrave ; B 69 -15 474 734 ;
-C -1 ; WX 273 ; N twosuperior ; B 52 281 368 703 ;
-C -1 ; WX 456 ; N eacute ; B 69 -15 481 734 ;
-C -1 ; WX 456 ; N otilde ; B 68 -14 494 722 ;
-C -1 ; WX 547 ; N Aacute ; B 11 0 560 929 ;
-C -1 ; WX 456 ; N ocircumflex ; B 68 -14 479 734 ;
-C -1 ; WX 410 ; N yacute ; B 12 -214 492 734 ;
-C -1 ; WX 456 ; N udieresis ; B 77 -15 492 706 ;
-C -1 ; WX 684 ; N threequarters ; B 106 -19 706 703 ;
-C -1 ; WX 456 ; N acircumflex ; B 50 -15 458 734 ;
-C -1 ; WX 592 ; N Eth ; B 57 0 626 718 ;
-C -1 ; WX 456 ; N edieresis ; B 69 -15 474 706 ;
-C -1 ; WX 456 ; N ugrave ; B 77 -15 492 734 ;
-C -1 ; WX 820 ; N trademark ; B 152 306 866 718 ;
-C -1 ; WX 456 ; N ograve ; B 68 -14 479 734 ;
-C -1 ; WX 410 ; N scaron ; B 52 -15 453 734 ;
-C -1 ; WX 228 ; N Idieresis ; B 75 0 375 901 ;
-C -1 ; WX 456 ; N uacute ; B 77 -15 492 734 ;
-C -1 ; WX 456 ; N agrave ; B 50 -15 458 734 ;
-C -1 ; WX 456 ; N ntilde ; B 53 0 486 722 ;
-C -1 ; WX 456 ; N aring ; B 50 -15 458 756 ;
-C -1 ; WX 410 ; N zcaron ; B 25 0 468 734 ;
-C -1 ; WX 228 ; N Icircumflex ; B 75 0 371 929 ;
-C -1 ; WX 592 ; N Ntilde ; B 62 0 655 917 ;
-C -1 ; WX 456 ; N ucircumflex ; B 77 -15 492 734 ;
-C -1 ; WX 547 ; N Ecircumflex ; B 71 0 625 929 ;
-C -1 ; WX 228 ; N Iacute ; B 75 0 401 929 ;
-C -1 ; WX 592 ; N Ccedilla ; B 88 -225 640 737 ;
-C -1 ; WX 638 ; N Odieresis ; B 86 -19 677 901 ;
-C -1 ; WX 547 ; N Scaron ; B 74 -19 584 929 ;
-C -1 ; WX 547 ; N Edieresis ; B 71 0 625 901 ;
-C -1 ; WX 228 ; N Igrave ; B 75 0 288 929 ;
-C -1 ; WX 456 ; N adieresis ; B 50 -15 458 706 ;
-C -1 ; WX 638 ; N Ograve ; B 86 -19 677 929 ;
-C -1 ; WX 547 ; N Egrave ; B 71 0 625 929 ;
-C -1 ; WX 547 ; N Ydieresis ; B 137 0 661 901 ;
-C -1 ; WX 604 ; N registered ; B 44 -19 687 737 ;
-C -1 ; WX 638 ; N Otilde ; B 86 -19 677 917 ;
-C -1 ; WX 684 ; N onequarter ; B 123 -19 658 703 ;
-C -1 ; WX 592 ; N Ugrave ; B 101 -19 653 929 ;
-C -1 ; WX 592 ; N Ucircumflex ; B 101 -19 653 929 ;
-C -1 ; WX 547 ; N Thorn ; B 71 0 584 718 ;
-C -1 ; WX 479 ; N divide ; B 70 -19 497 524 ;
-C -1 ; WX 547 ; N Atilde ; B 11 0 573 917 ;
-C -1 ; WX 592 ; N Uacute ; B 101 -19 653 929 ;
-C -1 ; WX 638 ; N Ocircumflex ; B 86 -19 677 929 ;
-C -1 ; WX 479 ; N logicalnot ; B 87 108 515 390 ;
-C -1 ; WX 547 ; N Aring ; B 11 0 536 931 ;
-C -1 ; WX 228 ; N idieresis ; B 78 0 341 706 ;
-C -1 ; WX 228 ; N iacute ; B 78 0 367 734 ;
-C -1 ; WX 456 ; N aacute ; B 50 -15 481 734 ;
-C -1 ; WX 479 ; N plusminus ; B 32 0 507 506 ;
-C -1 ; WX 479 ; N multiply ; B 41 0 526 506 ;
-C -1 ; WX 592 ; N Udieresis ; B 101 -19 653 901 ;
-C -1 ; WX 479 ; N minus ; B 70 216 497 289 ;
-C -1 ; WX 273 ; N onesuperior ; B 136 281 305 703 ;
-C -1 ; WX 547 ; N Eacute ; B 71 0 625 929 ;
-C -1 ; WX 547 ; N Acircumflex ; B 11 0 536 929 ;
-C -1 ; WX 604 ; N copyright ; B 44 -19 687 737 ;
-C -1 ; WX 547 ; N Agrave ; B 11 0 536 929 ;
-C -1 ; WX 456 ; N odieresis ; B 68 -14 479 706 ;
-C -1 ; WX 456 ; N oacute ; B 68 -14 481 734 ;
-C -1 ; WX 328 ; N degree ; B 138 411 384 703 ;
-C -1 ; WX 228 ; N igrave ; B 78 0 254 734 ;
-C -1 ; WX 456 ; N mu ; B 20 -207 492 523 ;
-C -1 ; WX 638 ; N Oacute ; B 86 -19 677 929 ;
-C -1 ; WX 456 ; N eth ; B 67 -15 506 737 ;
-C -1 ; WX 547 ; N Adieresis ; B 11 0 536 901 ;
-C -1 ; WX 547 ; N Yacute ; B 137 0 661 929 ;
-C -1 ; WX 213 ; N brokenbar ; B 74 -19 265 737 ;
-C -1 ; WX 684 ; N onehalf ; B 93 -19 688 703 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 250
-
-KPX A y -40
-KPX A w -40
-KPX A v -40
-KPX A u -30
-KPX A Y -100
-KPX A W -50
-KPX A V -70
-KPX A U -50
-KPX A T -120
-KPX A Q -30
-KPX A O -30
-KPX A G -30
-KPX A C -30
-
-KPX B period -20
-KPX B comma -20
-KPX B U -10
-
-KPX C period -30
-KPX C comma -30
-
-KPX D period -70
-KPX D comma -70
-KPX D Y -90
-KPX D W -40
-KPX D V -70
-KPX D A -40
-
-KPX F r -45
-KPX F period -150
-KPX F o -30
-KPX F e -30
-KPX F comma -150
-KPX F a -50
-KPX F A -80
-
-KPX J u -20
-KPX J period -30
-KPX J comma -30
-KPX J a -20
-KPX J A -20
-
-KPX K y -50
-KPX K u -30
-KPX K o -40
-KPX K e -40
-KPX K O -50
-
-KPX L y -30
-KPX L quoteright -160
-KPX L quotedblright -140
-KPX L Y -140
-KPX L W -70
-KPX L V -110
-KPX L T -110
-
-KPX O period -40
-KPX O comma -40
-KPX O Y -70
-KPX O X -60
-KPX O W -30
-KPX O V -50
-KPX O T -40
-KPX O A -20
-
-KPX P period -180
-KPX P o -50
-KPX P e -50
-KPX P comma -180
-KPX P a -40
-KPX P A -120
-
-KPX Q U -10
-
-KPX R Y -50
-KPX R W -30
-KPX R V -50
-KPX R U -40
-KPX R T -30
-KPX R O -20
-
-KPX S period -20
-KPX S comma -20
-
-KPX T y -120
-KPX T w -120
-KPX T u -120
-KPX T semicolon -20
-KPX T r -120
-KPX T period -120
-KPX T o -120
-KPX T hyphen -140
-KPX T e -120
-KPX T comma -120
-KPX T colon -20
-KPX T a -120
-KPX T O -40
-KPX T A -120
-
-KPX U period -40
-KPX U comma -40
-KPX U A -40
-
-KPX V u -70
-KPX V semicolon -40
-KPX V period -125
-KPX V o -80
-KPX V hyphen -80
-KPX V e -80
-KPX V comma -125
-KPX V colon -40
-KPX V a -70
-KPX V O -40
-KPX V G -40
-KPX V A -80
-
-KPX W y -20
-KPX W u -30
-KPX W period -80
-KPX W o -30
-KPX W hyphen -40
-KPX W e -30
-KPX W comma -80
-KPX W a -40
-KPX W O -20
-KPX W A -50
-
-KPX Y u -110
-KPX Y semicolon -60
-KPX Y period -140
-KPX Y o -140
-KPX Y i -20
-KPX Y hyphen -140
-KPX Y e -140
-KPX Y comma -140
-KPX Y colon -60
-KPX Y a -140
-KPX Y O -85
-KPX Y A -110
-
-KPX a y -30
-KPX a w -20
-KPX a v -20
-
-KPX b y -20
-KPX b v -20
-KPX b u -20
-KPX b period -40
-KPX b l -20
-KPX b comma -40
-KPX b b -10
-
-KPX c k -20
-KPX c comma -15
-
-KPX colon space -50
-
-KPX comma quoteright -100
-KPX comma quotedblright -100
-
-KPX e y -20
-KPX e x -30
-KPX e w -20
-KPX e v -30
-KPX e period -15
-KPX e comma -15
-
-KPX f quoteright 50
-KPX f quotedblright 60
-KPX f period -30
-KPX f o -30
-KPX f e -30
-KPX f dotlessi -28
-KPX f comma -30
-KPX f a -30
-
-KPX g r -10
-
-KPX h y -30
-
-KPX k o -20
-KPX k e -20
-
-KPX m y -15
-KPX m u -10
-
-KPX n y -15
-KPX n v -20
-KPX n u -10
-
-KPX o y -30
-KPX o x -30
-KPX o w -15
-KPX o v -15
-KPX o period -40
-KPX o comma -40
-
-KPX oslash z -55
-KPX oslash y -70
-KPX oslash x -85
-KPX oslash w -70
-KPX oslash v -70
-KPX oslash u -55
-KPX oslash t -55
-KPX oslash s -55
-KPX oslash r -55
-KPX oslash q -55
-KPX oslash period -95
-KPX oslash p -55
-KPX oslash o -55
-KPX oslash n -55
-KPX oslash m -55
-KPX oslash l -55
-KPX oslash k -55
-KPX oslash j -55
-KPX oslash i -55
-KPX oslash h -55
-KPX oslash g -55
-KPX oslash f -55
-KPX oslash e -55
-KPX oslash d -55
-KPX oslash comma -95
-KPX oslash c -55
-KPX oslash b -55
-KPX oslash a -55
-
-KPX p y -30
-KPX p period -35
-KPX p comma -35
-
-KPX period space -60
-KPX period quoteright -100
-KPX period quotedblright -100
-
-KPX quotedblright space -40
-
-KPX quoteleft quoteleft -57
-
-KPX quoteright space -70
-KPX quoteright s -50
-KPX quoteright r -50
-KPX quoteright quoteright -57
-KPX quoteright d -50
-
-KPX r y 30
-KPX r v 30
-KPX r u 15
-KPX r t 40
-KPX r semicolon 30
-KPX r period -50
-KPX r p 30
-KPX r n 25
-KPX r m 25
-KPX r l 15
-KPX r k 15
-KPX r i 15
-KPX r comma -50
-KPX r colon 30
-KPX r a -10
-
-KPX s w -30
-KPX s period -15
-KPX s comma -15
-
-KPX semicolon space -50
-
-KPX space quoteleft -60
-KPX space quotedblleft -30
-KPX space Y -90
-KPX space W -40
-KPX space V -50
-KPX space T -50
-
-KPX v period -80
-KPX v o -25
-KPX v e -25
-KPX v comma -80
-KPX v a -25
-
-KPX w period -60
-KPX w o -10
-KPX w e -10
-KPX w comma -60
-KPX w a -15
-
-KPX x e -30
-
-KPX y period -100
-KPX y o -20
-KPX y e -20
-KPX y comma -100
-KPX y a -20
-
-KPX z o -15
-KPX z e -15
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 171 195 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 171 195 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 171 195 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 171 195 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 167 175 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 171 195 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 160 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 171 195 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 171 195 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 171 195 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 171 195 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 12 195 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 12 195 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 12 195 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 12 195 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 202 195 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 217 195 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 217 195 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 217 195 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 217 195 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 217 195 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 171 195 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 194 195 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 194 195 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 194 195 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 194 195 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 171 195 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 171 195 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 148 195 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 92 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 92 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 92 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 92 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 92 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 69 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 92 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 92 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 92 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -22 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -22 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -22 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -22 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 92 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 92 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 92 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 92 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 92 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 69 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 92 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 92 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 92 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 92 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 69 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 69 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 69 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pncb8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pncb8a.afm
deleted file mode 100644
index ba1fed6d9a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pncb8a.afm
+++ /dev/null
@@ -1,472 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1988, 1991 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Tue May 28 16:48:12 1991
-Comment UniqueID 35031
-Comment VMusage 30773 37665
-FontName NewCenturySchlbk-Bold
-FullName New Century Schoolbook Bold
-FamilyName New Century Schoolbook
-Weight Bold
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -165 -250 1000 988
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.009
-Notice Copyright (c) 1985, 1987, 1988, 1991 Adobe Systems Incorporated. All Rights Reserved.
-EncodingScheme AdobeStandardEncoding
-CapHeight 722
-XHeight 475
-Ascender 737
-Descender -205
-StartCharMetrics 228
-C 32 ; WX 287 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 296 ; N exclam ; B 53 -15 243 737 ;
-C 34 ; WX 333 ; N quotedbl ; B 0 378 333 737 ;
-C 35 ; WX 574 ; N numbersign ; B 36 0 538 690 ;
-C 36 ; WX 574 ; N dollar ; B 25 -141 549 810 ;
-C 37 ; WX 833 ; N percent ; B 14 -15 819 705 ;
-C 38 ; WX 852 ; N ampersand ; B 34 -15 818 737 ;
-C 39 ; WX 241 ; N quoteright ; B 22 378 220 737 ;
-C 40 ; WX 389 ; N parenleft ; B 77 -117 345 745 ;
-C 41 ; WX 389 ; N parenright ; B 44 -117 312 745 ;
-C 42 ; WX 500 ; N asterisk ; B 54 302 446 737 ;
-C 43 ; WX 606 ; N plus ; B 50 0 556 506 ;
-C 44 ; WX 278 ; N comma ; B 40 -184 238 175 ;
-C 45 ; WX 333 ; N hyphen ; B 42 174 291 302 ;
-C 46 ; WX 278 ; N period ; B 44 -15 234 175 ;
-C 47 ; WX 278 ; N slash ; B -42 -15 320 737 ;
-C 48 ; WX 574 ; N zero ; B 27 -15 547 705 ;
-C 49 ; WX 574 ; N one ; B 83 0 491 705 ;
-C 50 ; WX 574 ; N two ; B 19 0 531 705 ;
-C 51 ; WX 574 ; N three ; B 23 -15 531 705 ;
-C 52 ; WX 574 ; N four ; B 19 0 547 705 ;
-C 53 ; WX 574 ; N five ; B 32 -15 534 705 ;
-C 54 ; WX 574 ; N six ; B 27 -15 547 705 ;
-C 55 ; WX 574 ; N seven ; B 45 -15 547 705 ;
-C 56 ; WX 574 ; N eight ; B 27 -15 548 705 ;
-C 57 ; WX 574 ; N nine ; B 27 -15 547 705 ;
-C 58 ; WX 278 ; N colon ; B 44 -15 234 485 ;
-C 59 ; WX 278 ; N semicolon ; B 40 -184 238 485 ;
-C 60 ; WX 606 ; N less ; B 50 -9 556 515 ;
-C 61 ; WX 606 ; N equal ; B 50 103 556 403 ;
-C 62 ; WX 606 ; N greater ; B 50 -9 556 515 ;
-C 63 ; WX 500 ; N question ; B 23 -15 477 737 ;
-C 64 ; WX 747 ; N at ; B -2 -15 750 737 ;
-C 65 ; WX 759 ; N A ; B -19 0 778 737 ;
-C 66 ; WX 778 ; N B ; B 19 0 739 722 ;
-C 67 ; WX 778 ; N C ; B 39 -15 723 737 ;
-C 68 ; WX 833 ; N D ; B 19 0 794 722 ;
-C 69 ; WX 759 ; N E ; B 19 0 708 722 ;
-C 70 ; WX 722 ; N F ; B 19 0 697 722 ;
-C 71 ; WX 833 ; N G ; B 39 -15 818 737 ;
-C 72 ; WX 870 ; N H ; B 19 0 851 722 ;
-C 73 ; WX 444 ; N I ; B 29 0 415 722 ;
-C 74 ; WX 648 ; N J ; B 6 -15 642 722 ;
-C 75 ; WX 815 ; N K ; B 19 0 822 722 ;
-C 76 ; WX 722 ; N L ; B 19 0 703 722 ;
-C 77 ; WX 981 ; N M ; B 10 0 971 722 ;
-C 78 ; WX 833 ; N N ; B 5 -10 828 722 ;
-C 79 ; WX 833 ; N O ; B 39 -15 794 737 ;
-C 80 ; WX 759 ; N P ; B 24 0 735 722 ;
-C 81 ; WX 833 ; N Q ; B 39 -189 808 737 ;
-C 82 ; WX 815 ; N R ; B 19 -15 815 722 ;
-C 83 ; WX 667 ; N S ; B 51 -15 634 737 ;
-C 84 ; WX 722 ; N T ; B 16 0 706 722 ;
-C 85 ; WX 833 ; N U ; B 14 -15 825 722 ;
-C 86 ; WX 759 ; N V ; B -19 -10 778 722 ;
-C 87 ; WX 981 ; N W ; B 7 -10 974 722 ;
-C 88 ; WX 722 ; N X ; B -12 0 734 722 ;
-C 89 ; WX 722 ; N Y ; B -12 0 734 722 ;
-C 90 ; WX 667 ; N Z ; B 28 0 639 722 ;
-C 91 ; WX 389 ; N bracketleft ; B 84 -109 339 737 ;
-C 92 ; WX 606 ; N backslash ; B 122 -15 484 737 ;
-C 93 ; WX 389 ; N bracketright ; B 50 -109 305 737 ;
-C 94 ; WX 606 ; N asciicircum ; B 66 325 540 690 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 241 ; N quoteleft ; B 22 378 220 737 ;
-C 97 ; WX 611 ; N a ; B 40 -15 601 485 ;
-C 98 ; WX 648 ; N b ; B 4 -15 616 737 ;
-C 99 ; WX 556 ; N c ; B 32 -15 524 485 ;
-C 100 ; WX 667 ; N d ; B 32 -15 644 737 ;
-C 101 ; WX 574 ; N e ; B 32 -15 542 485 ;
-C 102 ; WX 389 ; N f ; B 11 0 461 737 ; L i fi ; L l fl ;
-C 103 ; WX 611 ; N g ; B 30 -205 623 535 ;
-C 104 ; WX 685 ; N h ; B 17 0 662 737 ;
-C 105 ; WX 370 ; N i ; B 26 0 338 737 ;
-C 106 ; WX 352 ; N j ; B -86 -205 271 737 ;
-C 107 ; WX 667 ; N k ; B 17 0 662 737 ;
-C 108 ; WX 352 ; N l ; B 17 0 329 737 ;
-C 109 ; WX 963 ; N m ; B 17 0 940 485 ;
-C 110 ; WX 685 ; N n ; B 17 0 662 485 ;
-C 111 ; WX 611 ; N o ; B 32 -15 579 485 ;
-C 112 ; WX 667 ; N p ; B 17 -205 629 485 ;
-C 113 ; WX 648 ; N q ; B 32 -205 638 485 ;
-C 114 ; WX 519 ; N r ; B 17 0 516 485 ;
-C 115 ; WX 500 ; N s ; B 48 -15 476 485 ;
-C 116 ; WX 426 ; N t ; B 21 -15 405 675 ;
-C 117 ; WX 685 ; N u ; B 17 -15 668 475 ;
-C 118 ; WX 611 ; N v ; B 12 -10 599 475 ;
-C 119 ; WX 889 ; N w ; B 16 -10 873 475 ;
-C 120 ; WX 611 ; N x ; B 12 0 599 475 ;
-C 121 ; WX 611 ; N y ; B 12 -205 599 475 ;
-C 122 ; WX 537 ; N z ; B 38 0 499 475 ;
-C 123 ; WX 389 ; N braceleft ; B 36 -109 313 737 ;
-C 124 ; WX 606 ; N bar ; B 249 -250 357 750 ;
-C 125 ; WX 389 ; N braceright ; B 76 -109 353 737 ;
-C 126 ; WX 606 ; N asciitilde ; B 72 160 534 346 ;
-C 161 ; WX 296 ; N exclamdown ; B 53 -205 243 547 ;
-C 162 ; WX 574 ; N cent ; B 32 -102 528 572 ;
-C 163 ; WX 574 ; N sterling ; B 16 -15 558 705 ;
-C 164 ; WX 167 ; N fraction ; B -165 -15 332 705 ;
-C 165 ; WX 574 ; N yen ; B -10 0 584 690 ;
-C 166 ; WX 574 ; N florin ; B 14 -205 548 737 ;
-C 167 ; WX 500 ; N section ; B 62 -86 438 737 ;
-C 168 ; WX 574 ; N currency ; B 27 84 547 605 ;
-C 169 ; WX 241 ; N quotesingle ; B 53 378 189 737 ;
-C 170 ; WX 481 ; N quotedblleft ; B 22 378 459 737 ;
-C 171 ; WX 500 ; N guillemotleft ; B 46 79 454 397 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 62 79 271 397 ;
-C 173 ; WX 333 ; N guilsinglright ; B 62 79 271 397 ;
-C 174 ; WX 685 ; N fi ; B 11 0 666 737 ;
-C 175 ; WX 685 ; N fl ; B 11 0 666 737 ;
-C 177 ; WX 500 ; N endash ; B 0 184 500 292 ;
-C 178 ; WX 500 ; N dagger ; B 39 -101 461 737 ;
-C 179 ; WX 500 ; N daggerdbl ; B 39 -89 461 737 ;
-C 180 ; WX 278 ; N periodcentered ; B 53 200 225 372 ;
-C 182 ; WX 747 ; N paragraph ; B 96 -71 631 722 ;
-C 183 ; WX 606 ; N bullet ; B 122 180 484 542 ;
-C 184 ; WX 241 ; N quotesinglbase ; B 22 -184 220 175 ;
-C 185 ; WX 481 ; N quotedblbase ; B 22 -184 459 175 ;
-C 186 ; WX 481 ; N quotedblright ; B 22 378 459 737 ;
-C 187 ; WX 500 ; N guillemotright ; B 46 79 454 397 ;
-C 188 ; WX 1000 ; N ellipsis ; B 72 -15 928 175 ;
-C 189 ; WX 1000 ; N perthousand ; B 7 -15 993 705 ;
-C 191 ; WX 500 ; N questiondown ; B 23 -205 477 547 ;
-C 193 ; WX 333 ; N grave ; B 2 547 249 737 ;
-C 194 ; WX 333 ; N acute ; B 84 547 331 737 ;
-C 195 ; WX 333 ; N circumflex ; B -10 547 344 725 ;
-C 196 ; WX 333 ; N tilde ; B -24 563 357 705 ;
-C 197 ; WX 333 ; N macron ; B -6 582 339 664 ;
-C 198 ; WX 333 ; N breve ; B 9 547 324 714 ;
-C 199 ; WX 333 ; N dotaccent ; B 95 552 237 694 ;
-C 200 ; WX 333 ; N dieresis ; B -12 552 345 694 ;
-C 202 ; WX 333 ; N ring ; B 58 545 274 761 ;
-C 203 ; WX 333 ; N cedilla ; B 17 -224 248 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B -16 547 431 737 ;
-C 206 ; WX 333 ; N ogonek ; B 168 -163 346 3 ;
-C 207 ; WX 333 ; N caron ; B -10 547 344 725 ;
-C 208 ; WX 1000 ; N emdash ; B 0 184 1000 292 ;
-C 225 ; WX 981 ; N AE ; B -29 0 963 722 ;
-C 227 ; WX 367 ; N ordfeminine ; B 1 407 393 705 ;
-C 232 ; WX 722 ; N Lslash ; B 19 0 703 722 ;
-C 233 ; WX 833 ; N Oslash ; B 39 -53 794 775 ;
-C 234 ; WX 1000 ; N OE ; B 0 0 982 722 ;
-C 235 ; WX 367 ; N ordmasculine ; B 1 407 366 705 ;
-C 241 ; WX 870 ; N ae ; B 32 -15 838 485 ;
-C 245 ; WX 370 ; N dotlessi ; B 26 0 338 475 ;
-C 248 ; WX 352 ; N lslash ; B 17 0 329 737 ;
-C 249 ; WX 611 ; N oslash ; B 32 -103 579 573 ;
-C 250 ; WX 907 ; N oe ; B 32 -15 875 485 ;
-C 251 ; WX 611 ; N germandbls ; B -2 -15 580 737 ;
-C -1 ; WX 574 ; N ecircumflex ; B 32 -15 542 725 ;
-C -1 ; WX 574 ; N edieresis ; B 32 -15 542 694 ;
-C -1 ; WX 611 ; N aacute ; B 40 -15 601 737 ;
-C -1 ; WX 747 ; N registered ; B -2 -15 750 737 ;
-C -1 ; WX 370 ; N icircumflex ; B 9 0 363 725 ;
-C -1 ; WX 685 ; N udieresis ; B 17 -15 668 694 ;
-C -1 ; WX 611 ; N ograve ; B 32 -15 579 737 ;
-C -1 ; WX 685 ; N uacute ; B 17 -15 668 737 ;
-C -1 ; WX 685 ; N ucircumflex ; B 17 -15 668 725 ;
-C -1 ; WX 759 ; N Aacute ; B -19 0 778 964 ;
-C -1 ; WX 370 ; N igrave ; B 21 0 338 737 ;
-C -1 ; WX 444 ; N Icircumflex ; B 29 0 415 952 ;
-C -1 ; WX 556 ; N ccedilla ; B 32 -224 524 485 ;
-C -1 ; WX 611 ; N adieresis ; B 40 -15 601 694 ;
-C -1 ; WX 759 ; N Ecircumflex ; B 19 0 708 952 ;
-C -1 ; WX 500 ; N scaron ; B 48 -15 476 725 ;
-C -1 ; WX 667 ; N thorn ; B 17 -205 629 737 ;
-C -1 ; WX 1000 ; N trademark ; B 6 317 982 722 ;
-C -1 ; WX 574 ; N egrave ; B 32 -15 542 737 ;
-C -1 ; WX 344 ; N threesuperior ; B -3 273 355 705 ;
-C -1 ; WX 537 ; N zcaron ; B 38 0 499 725 ;
-C -1 ; WX 611 ; N atilde ; B 40 -15 601 705 ;
-C -1 ; WX 611 ; N aring ; B 40 -15 601 761 ;
-C -1 ; WX 611 ; N ocircumflex ; B 32 -15 579 725 ;
-C -1 ; WX 759 ; N Edieresis ; B 19 0 708 921 ;
-C -1 ; WX 861 ; N threequarters ; B 15 -15 838 705 ;
-C -1 ; WX 611 ; N ydieresis ; B 12 -205 599 694 ;
-C -1 ; WX 611 ; N yacute ; B 12 -205 599 737 ;
-C -1 ; WX 370 ; N iacute ; B 26 0 350 737 ;
-C -1 ; WX 759 ; N Acircumflex ; B -19 0 778 952 ;
-C -1 ; WX 833 ; N Uacute ; B 14 -15 825 964 ;
-C -1 ; WX 574 ; N eacute ; B 32 -15 542 737 ;
-C -1 ; WX 833 ; N Ograve ; B 39 -15 794 964 ;
-C -1 ; WX 611 ; N agrave ; B 40 -15 601 737 ;
-C -1 ; WX 833 ; N Udieresis ; B 14 -15 825 921 ;
-C -1 ; WX 611 ; N acircumflex ; B 40 -15 601 725 ;
-C -1 ; WX 444 ; N Igrave ; B 29 0 415 964 ;
-C -1 ; WX 344 ; N twosuperior ; B -3 282 350 705 ;
-C -1 ; WX 833 ; N Ugrave ; B 14 -15 825 964 ;
-C -1 ; WX 861 ; N onequarter ; B 31 -15 838 705 ;
-C -1 ; WX 833 ; N Ucircumflex ; B 14 -15 825 952 ;
-C -1 ; WX 667 ; N Scaron ; B 51 -15 634 952 ;
-C -1 ; WX 444 ; N Idieresis ; B 29 0 415 921 ;
-C -1 ; WX 370 ; N idieresis ; B 7 0 364 694 ;
-C -1 ; WX 759 ; N Egrave ; B 19 0 708 964 ;
-C -1 ; WX 833 ; N Oacute ; B 39 -15 794 964 ;
-C -1 ; WX 606 ; N divide ; B 50 -40 556 546 ;
-C -1 ; WX 759 ; N Atilde ; B -19 0 778 932 ;
-C -1 ; WX 759 ; N Aring ; B -19 0 778 988 ;
-C -1 ; WX 833 ; N Odieresis ; B 39 -15 794 921 ;
-C -1 ; WX 759 ; N Adieresis ; B -19 0 778 921 ;
-C -1 ; WX 833 ; N Ntilde ; B 5 -10 828 932 ;
-C -1 ; WX 667 ; N Zcaron ; B 28 0 639 952 ;
-C -1 ; WX 759 ; N Thorn ; B 24 0 735 722 ;
-C -1 ; WX 444 ; N Iacute ; B 29 0 415 964 ;
-C -1 ; WX 606 ; N plusminus ; B 50 0 556 506 ;
-C -1 ; WX 606 ; N multiply ; B 65 15 541 491 ;
-C -1 ; WX 759 ; N Eacute ; B 19 0 708 964 ;
-C -1 ; WX 722 ; N Ydieresis ; B -12 0 734 921 ;
-C -1 ; WX 344 ; N onesuperior ; B 31 282 309 705 ;
-C -1 ; WX 685 ; N ugrave ; B 17 -15 668 737 ;
-C -1 ; WX 606 ; N logicalnot ; B 50 103 556 403 ;
-C -1 ; WX 685 ; N ntilde ; B 17 0 662 705 ;
-C -1 ; WX 833 ; N Otilde ; B 39 -15 794 932 ;
-C -1 ; WX 611 ; N otilde ; B 32 -15 579 705 ;
-C -1 ; WX 778 ; N Ccedilla ; B 39 -224 723 737 ;
-C -1 ; WX 759 ; N Agrave ; B -19 0 778 964 ;
-C -1 ; WX 861 ; N onehalf ; B 31 -15 838 705 ;
-C -1 ; WX 833 ; N Eth ; B 19 0 794 722 ;
-C -1 ; WX 400 ; N degree ; B 57 419 343 705 ;
-C -1 ; WX 722 ; N Yacute ; B -12 0 734 964 ;
-C -1 ; WX 833 ; N Ocircumflex ; B 39 -15 794 952 ;
-C -1 ; WX 611 ; N oacute ; B 32 -15 579 737 ;
-C -1 ; WX 685 ; N mu ; B 17 -205 668 475 ;
-C -1 ; WX 606 ; N minus ; B 50 199 556 307 ;
-C -1 ; WX 611 ; N eth ; B 32 -15 579 737 ;
-C -1 ; WX 611 ; N odieresis ; B 32 -15 579 694 ;
-C -1 ; WX 747 ; N copyright ; B -2 -15 750 737 ;
-C -1 ; WX 606 ; N brokenbar ; B 249 -175 357 675 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 128
-
-KPX A y -18
-KPX A w -18
-KPX A v -18
-KPX A quoteright -74
-KPX A quotedblright -74
-KPX A Y -91
-KPX A W -74
-KPX A V -74
-KPX A U -18
-KPX A T -55
-
-KPX C period -18
-KPX C comma -18
-
-KPX D period -25
-KPX D comma -25
-
-KPX F r -18
-KPX F period -125
-KPX F o -55
-KPX F i -18
-KPX F e -55
-KPX F comma -125
-KPX F a -74
-
-KPX J u -18
-KPX J period -55
-KPX J o -18
-KPX J e -18
-KPX J comma -55
-KPX J a -18
-KPX J A -18
-
-KPX K y -25
-KPX K u -18
-
-KPX L y -25
-KPX L quoteright -100
-KPX L quotedblright -100
-KPX L Y -74
-KPX L W -74
-KPX L V -100
-KPX L T -100
-
-KPX N period -18
-KPX N comma -18
-
-KPX O period -25
-KPX O comma -25
-KPX O T 10
-
-KPX P period -150
-KPX P o -55
-KPX P e -55
-KPX P comma -150
-KPX P a -55
-KPX P A -74
-
-KPX S period -18
-KPX S comma -18
-
-KPX T u -18
-KPX T r -18
-KPX T period -100
-KPX T o -74
-KPX T i -18
-KPX T hyphen -125
-KPX T e -74
-KPX T comma -100
-KPX T a -74
-KPX T O 10
-KPX T A -55
-
-KPX U period -25
-KPX U comma -25
-KPX U A -18
-
-KPX V u -55
-KPX V semicolon -37
-KPX V period -125
-KPX V o -74
-KPX V i -18
-KPX V hyphen -100
-KPX V e -74
-KPX V comma -125
-KPX V colon -37
-KPX V a -74
-KPX V A -74
-
-KPX W y -25
-KPX W u -37
-KPX W semicolon -55
-KPX W period -100
-KPX W o -74
-KPX W i -18
-KPX W hyphen -100
-KPX W e -74
-KPX W comma -100
-KPX W colon -55
-KPX W a -74
-KPX W A -74
-
-KPX Y u -55
-KPX Y semicolon -25
-KPX Y period -100
-KPX Y o -100
-KPX Y i -18
-KPX Y hyphen -125
-KPX Y e -100
-KPX Y comma -100
-KPX Y colon -25
-KPX Y a -100
-KPX Y A -91
-
-KPX colon space -18
-
-KPX comma space -18
-KPX comma quoteright -18
-KPX comma quotedblright -18
-
-KPX f quoteright 75
-KPX f quotedblright 75
-
-KPX period space -18
-KPX period quoteright -18
-KPX period quotedblright -18
-
-KPX quotedblleft A -74
-
-KPX quotedblright space -18
-
-KPX quoteleft A -74
-
-KPX quoteright s -25
-KPX quoteright d -25
-
-KPX r period -74
-KPX r comma -74
-
-KPX semicolon space -18
-
-KPX space quoteleft -18
-KPX space quotedblleft -18
-KPX space Y -18
-KPX space W -18
-KPX space V -18
-KPX space T -18
-KPX space A -18
-
-KPX v period -100
-KPX v comma -100
-
-KPX w period -100
-KPX w comma -100
-
-KPX y period -100
-KPX y comma -100
-EndKernPairs
-EndKernData
-StartComposites 56
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 213 227 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 213 227 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 213 227 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 213 227 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 213 227 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 213 227 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 213 227 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 213 227 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 213 227 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 213 227 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 56 227 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 56 227 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 56 227 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 56 227 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 250 227 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 250 227 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 250 227 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 250 227 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 250 227 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 250 227 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 167 227 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 250 227 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 250 227 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 250 227 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 250 227 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 195 227 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 195 227 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 227 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 139 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 139 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 139 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 139 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 139 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 139 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 121 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 121 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 121 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 121 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 19 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 19 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 19 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 19 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 176 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 139 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 139 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 139 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 139 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 139 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 84 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 176 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 176 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 176 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 176 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 139 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 139 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 102 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pncbi8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pncbi8a.afm
deleted file mode 100644
index 7871147e0f..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pncbi8a.afm
+++ /dev/null
@@ -1,602 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Tue May 28 16:56:07 1991
-Comment UniqueID 35034
-Comment VMusage 31030 37922
-FontName NewCenturySchlbk-BoldItalic
-FullName New Century Schoolbook Bold Italic
-FamilyName New Century Schoolbook
-Weight Bold
-ItalicAngle -16
-IsFixedPitch false
-FontBBox -205 -250 1147 991
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.007
-Notice Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.
-EncodingScheme AdobeStandardEncoding
-CapHeight 722
-XHeight 477
-Ascender 737
-Descender -205
-StartCharMetrics 228
-C 32 ; WX 287 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 0 -15 333 737 ;
-C 34 ; WX 400 ; N quotedbl ; B 66 388 428 737 ;
-C 35 ; WX 574 ; N numbersign ; B 30 0 544 690 ;
-C 36 ; WX 574 ; N dollar ; B 9 -120 565 810 ;
-C 37 ; WX 889 ; N percent ; B 54 -28 835 727 ;
-C 38 ; WX 889 ; N ampersand ; B 32 -15 823 737 ;
-C 39 ; WX 259 ; N quoteright ; B 48 388 275 737 ;
-C 40 ; WX 407 ; N parenleft ; B 72 -117 454 745 ;
-C 41 ; WX 407 ; N parenright ; B -70 -117 310 745 ;
-C 42 ; WX 500 ; N asterisk ; B 58 301 498 737 ;
-C 43 ; WX 606 ; N plus ; B 50 0 556 506 ;
-C 44 ; WX 287 ; N comma ; B -57 -192 170 157 ;
-C 45 ; WX 333 ; N hyphen ; B 2 177 263 299 ;
-C 46 ; WX 287 ; N period ; B -20 -15 152 157 ;
-C 47 ; WX 278 ; N slash ; B -41 -15 320 737 ;
-C 48 ; WX 574 ; N zero ; B 21 -15 553 705 ;
-C 49 ; WX 574 ; N one ; B 25 0 489 705 ;
-C 50 ; WX 574 ; N two ; B -38 -3 538 705 ;
-C 51 ; WX 574 ; N three ; B -7 -15 536 705 ;
-C 52 ; WX 574 ; N four ; B -13 0 544 705 ;
-C 53 ; WX 574 ; N five ; B 0 -15 574 705 ;
-C 54 ; WX 574 ; N six ; B 31 -15 574 705 ;
-C 55 ; WX 574 ; N seven ; B 64 -15 593 705 ;
-C 56 ; WX 574 ; N eight ; B 0 -15 552 705 ;
-C 57 ; WX 574 ; N nine ; B 0 -15 543 705 ;
-C 58 ; WX 287 ; N colon ; B -20 -15 237 477 ;
-C 59 ; WX 287 ; N semicolon ; B -57 -192 237 477 ;
-C 60 ; WX 606 ; N less ; B 50 -9 556 515 ;
-C 61 ; WX 606 ; N equal ; B 50 103 556 403 ;
-C 62 ; WX 606 ; N greater ; B 50 -8 556 514 ;
-C 63 ; WX 481 ; N question ; B 79 -15 451 737 ;
-C 64 ; WX 747 ; N at ; B -4 -15 751 737 ;
-C 65 ; WX 741 ; N A ; B -75 0 716 737 ;
-C 66 ; WX 759 ; N B ; B -50 0 721 722 ;
-C 67 ; WX 759 ; N C ; B 37 -15 759 737 ;
-C 68 ; WX 833 ; N D ; B -47 0 796 722 ;
-C 69 ; WX 741 ; N E ; B -41 0 730 722 ;
-C 70 ; WX 704 ; N F ; B -41 0 730 722 ;
-C 71 ; WX 815 ; N G ; B 37 -15 805 737 ;
-C 72 ; WX 870 ; N H ; B -41 0 911 722 ;
-C 73 ; WX 444 ; N I ; B -41 0 485 722 ;
-C 74 ; WX 667 ; N J ; B -20 -15 708 722 ;
-C 75 ; WX 778 ; N K ; B -41 0 832 722 ;
-C 76 ; WX 704 ; N L ; B -41 0 670 722 ;
-C 77 ; WX 944 ; N M ; B -44 0 988 722 ;
-C 78 ; WX 852 ; N N ; B -61 -10 913 722 ;
-C 79 ; WX 833 ; N O ; B 37 -15 796 737 ;
-C 80 ; WX 741 ; N P ; B -41 0 730 722 ;
-C 81 ; WX 833 ; N Q ; B 37 -189 796 737 ;
-C 82 ; WX 796 ; N R ; B -41 -15 749 722 ;
-C 83 ; WX 685 ; N S ; B 1 -15 666 737 ;
-C 84 ; WX 722 ; N T ; B 41 0 759 722 ;
-C 85 ; WX 833 ; N U ; B 88 -15 900 722 ;
-C 86 ; WX 741 ; N V ; B 32 -10 802 722 ;
-C 87 ; WX 944 ; N W ; B 40 -10 1000 722 ;
-C 88 ; WX 741 ; N X ; B -82 0 801 722 ;
-C 89 ; WX 704 ; N Y ; B 13 0 775 722 ;
-C 90 ; WX 704 ; N Z ; B -33 0 711 722 ;
-C 91 ; WX 407 ; N bracketleft ; B 1 -109 464 737 ;
-C 92 ; WX 606 ; N backslash ; B 161 -15 445 737 ;
-C 93 ; WX 407 ; N bracketright ; B -101 -109 362 737 ;
-C 94 ; WX 606 ; N asciicircum ; B 66 325 540 690 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 259 ; N quoteleft ; B 47 388 274 737 ;
-C 97 ; WX 667 ; N a ; B 6 -15 636 477 ;
-C 98 ; WX 611 ; N b ; B 29 -15 557 737 ;
-C 99 ; WX 537 ; N c ; B 0 -15 482 477 ;
-C 100 ; WX 667 ; N d ; B 0 -15 660 737 ;
-C 101 ; WX 519 ; N e ; B 0 -15 479 477 ;
-C 102 ; WX 389 ; N f ; B -48 -205 550 737 ; L i fi ; L l fl ;
-C 103 ; WX 611 ; N g ; B -63 -205 604 528 ;
-C 104 ; WX 685 ; N h ; B 0 -15 639 737 ;
-C 105 ; WX 389 ; N i ; B 32 -15 345 737 ;
-C 106 ; WX 370 ; N j ; B -205 -205 347 737 ;
-C 107 ; WX 648 ; N k ; B -11 -15 578 737 ;
-C 108 ; WX 389 ; N l ; B 32 -15 375 737 ;
-C 109 ; WX 944 ; N m ; B 0 -15 909 477 ;
-C 110 ; WX 685 ; N n ; B 0 -15 639 477 ;
-C 111 ; WX 574 ; N o ; B 0 -15 530 477 ;
-C 112 ; WX 648 ; N p ; B -119 -205 590 477 ;
-C 113 ; WX 630 ; N q ; B 0 -205 587 477 ;
-C 114 ; WX 519 ; N r ; B 0 0 527 486 ;
-C 115 ; WX 481 ; N s ; B 0 -15 435 477 ;
-C 116 ; WX 407 ; N t ; B 24 -15 403 650 ;
-C 117 ; WX 685 ; N u ; B 30 -15 635 477 ;
-C 118 ; WX 556 ; N v ; B 30 -15 496 477 ;
-C 119 ; WX 833 ; N w ; B 30 -15 773 477 ;
-C 120 ; WX 574 ; N x ; B -46 -15 574 477 ;
-C 121 ; WX 519 ; N y ; B -66 -205 493 477 ;
-C 122 ; WX 519 ; N z ; B -19 -15 473 477 ;
-C 123 ; WX 407 ; N braceleft ; B 52 -109 408 737 ;
-C 124 ; WX 606 ; N bar ; B 249 -250 357 750 ;
-C 125 ; WX 407 ; N braceright ; B -25 -109 331 737 ;
-C 126 ; WX 606 ; N asciitilde ; B 72 160 534 346 ;
-C 161 ; WX 333 ; N exclamdown ; B -44 -205 289 547 ;
-C 162 ; WX 574 ; N cent ; B 30 -144 512 578 ;
-C 163 ; WX 574 ; N sterling ; B -18 -15 566 705 ;
-C 164 ; WX 167 ; N fraction ; B -166 -15 333 705 ;
-C 165 ; WX 574 ; N yen ; B 17 0 629 690 ;
-C 166 ; WX 574 ; N florin ; B -43 -205 575 737 ;
-C 167 ; WX 500 ; N section ; B -30 -146 515 737 ;
-C 168 ; WX 574 ; N currency ; B 27 84 547 605 ;
-C 169 ; WX 287 ; N quotesingle ; B 112 388 250 737 ;
-C 170 ; WX 481 ; N quotedblleft ; B 54 388 521 737 ;
-C 171 ; WX 481 ; N guillemotleft ; B -35 69 449 407 ;
-C 172 ; WX 278 ; N guilsinglleft ; B -25 69 244 407 ;
-C 173 ; WX 278 ; N guilsinglright ; B -26 69 243 407 ;
-C 174 ; WX 685 ; N fi ; B -70 -205 641 737 ;
-C 175 ; WX 685 ; N fl ; B -70 -205 671 737 ;
-C 177 ; WX 500 ; N endash ; B -47 189 479 287 ;
-C 178 ; WX 500 ; N dagger ; B 48 -146 508 737 ;
-C 179 ; WX 500 ; N daggerdbl ; B -60 -150 508 737 ;
-C 180 ; WX 287 ; N periodcentered ; B 57 200 229 372 ;
-C 182 ; WX 650 ; N paragraph ; B 25 -131 681 722 ;
-C 183 ; WX 606 ; N bullet ; B 122 180 484 542 ;
-C 184 ; WX 259 ; N quotesinglbase ; B -57 -192 170 157 ;
-C 185 ; WX 481 ; N quotedblbase ; B -57 -192 412 157 ;
-C 186 ; WX 481 ; N quotedblright ; B 43 388 510 737 ;
-C 187 ; WX 481 ; N guillemotright ; B -31 69 453 407 ;
-C 188 ; WX 1000 ; N ellipsis ; B 81 -15 919 157 ;
-C 189 ; WX 1167 ; N perthousand ; B 20 -28 1147 727 ;
-C 191 ; WX 481 ; N questiondown ; B 0 -205 372 547 ;
-C 193 ; WX 333 ; N grave ; B 74 538 294 722 ;
-C 194 ; WX 333 ; N acute ; B 123 538 372 722 ;
-C 195 ; WX 333 ; N circumflex ; B 23 533 365 705 ;
-C 196 ; WX 333 ; N tilde ; B 28 561 398 690 ;
-C 197 ; WX 333 ; N macron ; B 47 573 404 649 ;
-C 198 ; WX 333 ; N breve ; B 67 535 390 698 ;
-C 199 ; WX 333 ; N dotaccent ; B 145 546 289 690 ;
-C 200 ; WX 333 ; N dieresis ; B 33 546 393 690 ;
-C 202 ; WX 333 ; N ring ; B 111 522 335 746 ;
-C 203 ; WX 333 ; N cedilla ; B -21 -220 225 3 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 15 538 480 722 ;
-C 206 ; WX 333 ; N ogonek ; B 68 -155 246 -10 ;
-C 207 ; WX 333 ; N caron ; B 60 531 403 705 ;
-C 208 ; WX 1000 ; N emdash ; B -47 189 979 287 ;
-C 225 ; WX 889 ; N AE ; B -86 0 915 722 ;
-C 227 ; WX 412 ; N ordfeminine ; B 47 407 460 705 ;
-C 232 ; WX 704 ; N Lslash ; B -41 0 670 722 ;
-C 233 ; WX 833 ; N Oslash ; B 35 -68 798 790 ;
-C 234 ; WX 963 ; N OE ; B 29 0 989 722 ;
-C 235 ; WX 356 ; N ordmasculine ; B 42 407 394 705 ;
-C 241 ; WX 815 ; N ae ; B -18 -15 775 477 ;
-C 245 ; WX 389 ; N dotlessi ; B 32 -15 345 477 ;
-C 248 ; WX 389 ; N lslash ; B 5 -15 390 737 ;
-C 249 ; WX 574 ; N oslash ; B 0 -121 530 583 ;
-C 250 ; WX 852 ; N oe ; B -6 -15 812 477 ;
-C 251 ; WX 574 ; N germandbls ; B -91 -205 540 737 ;
-C -1 ; WX 519 ; N ecircumflex ; B 0 -15 479 705 ;
-C -1 ; WX 519 ; N edieresis ; B 0 -15 486 690 ;
-C -1 ; WX 667 ; N aacute ; B 6 -15 636 722 ;
-C -1 ; WX 747 ; N registered ; B -2 -15 750 737 ;
-C -1 ; WX 389 ; N icircumflex ; B 21 -15 363 698 ;
-C -1 ; WX 685 ; N udieresis ; B 30 -15 635 690 ;
-C -1 ; WX 574 ; N ograve ; B 0 -15 530 722 ;
-C -1 ; WX 685 ; N uacute ; B 30 -15 635 722 ;
-C -1 ; WX 685 ; N ucircumflex ; B 30 -15 635 705 ;
-C -1 ; WX 741 ; N Aacute ; B -75 0 716 947 ;
-C -1 ; WX 389 ; N igrave ; B 32 -15 345 715 ;
-C -1 ; WX 444 ; N Icircumflex ; B -41 0 485 930 ;
-C -1 ; WX 537 ; N ccedilla ; B 0 -220 482 477 ;
-C -1 ; WX 667 ; N adieresis ; B 6 -15 636 690 ;
-C -1 ; WX 741 ; N Ecircumflex ; B -41 0 730 930 ;
-C -1 ; WX 481 ; N scaron ; B 0 -15 477 705 ;
-C -1 ; WX 648 ; N thorn ; B -119 -205 590 737 ;
-C -1 ; WX 950 ; N trademark ; B 42 317 1017 722 ;
-C -1 ; WX 519 ; N egrave ; B 0 -15 479 722 ;
-C -1 ; WX 344 ; N threesuperior ; B 3 273 361 705 ;
-C -1 ; WX 519 ; N zcaron ; B -19 -15 473 695 ;
-C -1 ; WX 667 ; N atilde ; B 6 -15 636 690 ;
-C -1 ; WX 667 ; N aring ; B 6 -15 636 746 ;
-C -1 ; WX 574 ; N ocircumflex ; B 0 -15 530 705 ;
-C -1 ; WX 741 ; N Edieresis ; B -41 0 730 915 ;
-C -1 ; WX 861 ; N threequarters ; B 35 -15 789 705 ;
-C -1 ; WX 519 ; N ydieresis ; B -66 -205 493 690 ;
-C -1 ; WX 519 ; N yacute ; B -66 -205 493 722 ;
-C -1 ; WX 389 ; N iacute ; B 32 -15 370 715 ;
-C -1 ; WX 741 ; N Acircumflex ; B -75 0 716 930 ;
-C -1 ; WX 833 ; N Uacute ; B 88 -15 900 947 ;
-C -1 ; WX 519 ; N eacute ; B 0 -15 479 722 ;
-C -1 ; WX 833 ; N Ograve ; B 37 -15 796 947 ;
-C -1 ; WX 667 ; N agrave ; B 6 -15 636 722 ;
-C -1 ; WX 833 ; N Udieresis ; B 88 -15 900 915 ;
-C -1 ; WX 667 ; N acircumflex ; B 6 -15 636 705 ;
-C -1 ; WX 444 ; N Igrave ; B -41 0 485 947 ;
-C -1 ; WX 344 ; N twosuperior ; B -17 280 362 705 ;
-C -1 ; WX 833 ; N Ugrave ; B 88 -15 900 947 ;
-C -1 ; WX 861 ; N onequarter ; B 17 -15 789 705 ;
-C -1 ; WX 833 ; N Ucircumflex ; B 88 -15 900 930 ;
-C -1 ; WX 685 ; N Scaron ; B 1 -15 666 930 ;
-C -1 ; WX 444 ; N Idieresis ; B -41 0 509 915 ;
-C -1 ; WX 389 ; N idieresis ; B 31 -15 391 683 ;
-C -1 ; WX 741 ; N Egrave ; B -41 0 730 947 ;
-C -1 ; WX 833 ; N Oacute ; B 37 -15 796 947 ;
-C -1 ; WX 606 ; N divide ; B 50 -40 556 546 ;
-C -1 ; WX 741 ; N Atilde ; B -75 0 716 915 ;
-C -1 ; WX 741 ; N Aring ; B -75 0 716 991 ;
-C -1 ; WX 833 ; N Odieresis ; B 37 -15 796 915 ;
-C -1 ; WX 741 ; N Adieresis ; B -75 0 716 915 ;
-C -1 ; WX 852 ; N Ntilde ; B -61 -10 913 915 ;
-C -1 ; WX 704 ; N Zcaron ; B -33 0 711 930 ;
-C -1 ; WX 741 ; N Thorn ; B -41 0 690 722 ;
-C -1 ; WX 444 ; N Iacute ; B -41 0 488 947 ;
-C -1 ; WX 606 ; N plusminus ; B 50 0 556 506 ;
-C -1 ; WX 606 ; N multiply ; B 65 15 541 491 ;
-C -1 ; WX 741 ; N Eacute ; B -41 0 730 947 ;
-C -1 ; WX 704 ; N Ydieresis ; B 13 0 775 915 ;
-C -1 ; WX 344 ; N onesuperior ; B 19 282 326 705 ;
-C -1 ; WX 685 ; N ugrave ; B 30 -15 635 722 ;
-C -1 ; WX 606 ; N logicalnot ; B 50 103 556 403 ;
-C -1 ; WX 685 ; N ntilde ; B 0 -15 639 690 ;
-C -1 ; WX 833 ; N Otilde ; B 37 -15 796 915 ;
-C -1 ; WX 574 ; N otilde ; B 0 -15 530 690 ;
-C -1 ; WX 759 ; N Ccedilla ; B 37 -220 759 737 ;
-C -1 ; WX 741 ; N Agrave ; B -75 0 716 947 ;
-C -1 ; WX 861 ; N onehalf ; B 17 -15 798 705 ;
-C -1 ; WX 833 ; N Eth ; B -47 0 796 722 ;
-C -1 ; WX 400 ; N degree ; B 86 419 372 705 ;
-C -1 ; WX 704 ; N Yacute ; B 13 0 775 947 ;
-C -1 ; WX 833 ; N Ocircumflex ; B 37 -15 796 930 ;
-C -1 ; WX 574 ; N oacute ; B 0 -15 530 722 ;
-C -1 ; WX 685 ; N mu ; B -89 -205 635 477 ;
-C -1 ; WX 606 ; N minus ; B 50 199 556 307 ;
-C -1 ; WX 574 ; N eth ; B 0 -15 530 752 ;
-C -1 ; WX 574 ; N odieresis ; B 0 -15 530 690 ;
-C -1 ; WX 747 ; N copyright ; B -2 -15 750 737 ;
-C -1 ; WX 606 ; N brokenbar ; B 249 -175 357 675 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 239
-
-KPX A y -33
-KPX A w -25
-KPX A v -10
-KPX A u -15
-KPX A quoteright -95
-KPX A quotedblright -95
-KPX A Y -70
-KPX A W -84
-KPX A V -100
-KPX A U -32
-KPX A T 5
-KPX A Q 5
-KPX A O 5
-KPX A G 5
-KPX A C 5
-
-KPX B period 15
-KPX B comma 15
-KPX B U 15
-KPX B A -11
-
-KPX C A -5
-
-KPX D period -11
-KPX D comma -11
-KPX D Y 6
-KPX D W -11
-KPX D V -18
-
-KPX F r -27
-KPX F period -91
-KPX F o -47
-KPX F i -41
-KPX F e -41
-KPX F comma -91
-KPX F a -47
-KPX F A -79
-
-KPX J u -39
-KPX J period -74
-KPX J o -40
-KPX J e -33
-KPX J comma -74
-KPX J a -40
-KPX J A -30
-
-KPX K y -48
-KPX K u -4
-KPX K o -4
-KPX K e 18
-
-KPX L y -30
-KPX L quoteright -100
-KPX L quotedblright -100
-KPX L Y -55
-KPX L W -69
-KPX L V -97
-KPX L T -75
-
-KPX N period -49
-KPX N comma -49
-
-KPX O period -18
-KPX O comma -18
-KPX O X -18
-KPX O W -15
-KPX O V -24
-KPX O A -5
-
-KPX P period -100
-KPX P o -40
-KPX P e -33
-KPX P comma -100
-KPX P a -40
-KPX P A -80
-
-KPX R W -14
-KPX R V -24
-
-KPX S period -18
-KPX S comma -18
-
-KPX T y -30
-KPX T w -30
-KPX T u -22
-KPX T r -9
-KPX T period -55
-KPX T o -40
-KPX T i -22
-KPX T hyphen -75
-KPX T h -9
-KPX T e -33
-KPX T comma -55
-KPX T a -40
-KPX T O 11
-KPX T A -60
-
-KPX U period -25
-KPX U comma -25
-KPX U A -42
-
-KPX V u -70
-KPX V semicolon 6
-KPX V period -94
-KPX V o -71
-KPX V i -35
-KPX V hyphen -94
-KPX V e -66
-KPX V comma -94
-KPX V colon -49
-KPX V a -55
-KPX V O -19
-KPX V G -12
-KPX V A -100
-
-KPX W y -41
-KPX W u -25
-KPX W semicolon -22
-KPX W period -86
-KPX W o -33
-KPX W i -27
-KPX W hyphen -61
-KPX W h 5
-KPX W e -39
-KPX W comma -86
-KPX W colon -22
-KPX W a -33
-KPX W O -11
-KPX W A -66
-
-KPX Y u -58
-KPX Y semicolon -55
-KPX Y period -91
-KPX Y o -77
-KPX Y i -22
-KPX Y hyphen -91
-KPX Y e -71
-KPX Y comma -91
-KPX Y colon -55
-KPX Y a -77
-KPX Y A -79
-
-KPX a y -8
-KPX a w -8
-KPX a v 6
-
-KPX b y -6
-KPX b v 8
-KPX b period 6
-KPX b comma 6
-
-KPX c y -20
-KPX c period -8
-KPX c l -13
-KPX c k -8
-KPX c h -18
-KPX c comma -8
-
-KPX colon space -18
-
-KPX comma space -18
-KPX comma quoteright -18
-KPX comma quotedblright -18
-
-KPX d y -15
-KPX d w -15
-
-KPX e y -15
-KPX e x -5
-KPX e w -15
-KPX e p -11
-KPX e g -4
-KPX e b -8
-
-KPX f quoteright 105
-KPX f quotedblright 105
-KPX f period -28
-KPX f o 7
-KPX f l 7
-KPX f i 7
-KPX f e 14
-KPX f dotlessi 7
-KPX f comma -28
-KPX f a 8
-
-KPX g y -11
-KPX g r 11
-KPX g period -5
-KPX g comma -5
-
-KPX h y -20
-
-KPX i v 7
-
-KPX k y -15
-KPX k o -22
-KPX k e -16
-
-KPX l y -7
-KPX l w -7
-
-KPX m y -20
-KPX m u -11
-
-KPX n y -20
-KPX n v -7
-KPX n u -11
-
-KPX o y -11
-KPX o w -8
-KPX o v 6
-
-KPX p y -4
-KPX p period 8
-KPX p comma 8
-
-KPX period space -18
-KPX period quoteright -18
-KPX period quotedblright -18
-
-KPX quotedblleft quoteleft 20
-KPX quotedblleft A -60
-
-KPX quotedblright space -18
-
-KPX quoteleft A -80
-
-KPX quoteright v -16
-KPX quoteright t -22
-KPX quoteright s -46
-KPX quoteright r -9
-KPX quoteright l -22
-KPX quoteright d -41
-
-KPX r y -20
-KPX r v -7
-KPX r u -11
-KPX r t -11
-KPX r semicolon 9
-KPX r s -20
-KPX r quoteright 9
-KPX r period -90
-KPX r p -17
-KPX r o -11
-KPX r l -14
-KPX r k 9
-KPX r i -14
-KPX r hyphen -16
-KPX r g -11
-KPX r e -7
-KPX r d -7
-KPX r comma -90
-KPX r colon 9
-KPX r a -11
-
-KPX s period 11
-KPX s comma 11
-
-KPX semicolon space -18
-
-KPX space quotedblleft -18
-KPX space Y -18
-KPX space W -33
-KPX space V -24
-KPX space T -18
-KPX space A -22
-
-KPX v period -11
-KPX v o -6
-KPX v comma -11
-KPX v a -6
-
-KPX w period -17
-KPX w o -14
-KPX w e -8
-KPX w comma -17
-KPX w a -14
-
-KPX x e 5
-
-KPX y period -25
-KPX y o 8
-KPX y e 15
-KPX y comma -25
-KPX y a 8
-
-KPX z e 4
-EndKernPairs
-EndKernData
-StartComposites 56
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 259 225 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 259 225 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 259 225 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 259 225 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 229 245 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 259 225 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 296 225 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 296 225 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 296 225 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 296 225 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 116 225 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 116 225 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 116 225 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 116 225 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 326 225 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 315 225 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 315 225 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 315 225 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 315 225 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 315 225 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 206 225 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 340 225 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 340 225 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 340 225 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 340 225 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 246 225 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 236 225 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 226 225 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 167 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 167 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 167 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 167 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 167 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 167 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 93 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 93 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 93 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 93 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -2 -7 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -2 -7 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -2 -7 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -2 -7 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 176 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 121 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 121 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 121 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 121 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 121 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 74 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 176 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 176 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 176 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 176 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 93 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 93 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 63 -10 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pncr8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pncr8a.afm
deleted file mode 100644
index b9f616cb5a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pncr8a.afm
+++ /dev/null
@@ -1,524 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Tue May 28 16:31:51 1991
-Comment UniqueID 35025
-Comment VMusage 30420 37312
-FontName NewCenturySchlbk-Roman
-FullName New Century Schoolbook Roman
-FamilyName New Century Schoolbook
-Weight Roman
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -195 -250 1000 965
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.007
-Notice Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.
-EncodingScheme AdobeStandardEncoding
-CapHeight 722
-XHeight 464
-Ascender 737
-Descender -205
-StartCharMetrics 228
-C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 296 ; N exclam ; B 86 -15 210 737 ;
-C 34 ; WX 389 ; N quotedbl ; B 61 443 328 737 ;
-C 35 ; WX 556 ; N numbersign ; B 28 0 528 690 ;
-C 36 ; WX 556 ; N dollar ; B 45 -138 511 813 ;
-C 37 ; WX 833 ; N percent ; B 43 -15 790 705 ;
-C 38 ; WX 815 ; N ampersand ; B 51 -15 775 737 ;
-C 39 ; WX 204 ; N quoteright ; B 25 443 179 737 ;
-C 40 ; WX 333 ; N parenleft ; B 40 -117 279 745 ;
-C 41 ; WX 333 ; N parenright ; B 54 -117 293 745 ;
-C 42 ; WX 500 ; N asterisk ; B 57 306 443 737 ;
-C 43 ; WX 606 ; N plus ; B 50 0 556 506 ;
-C 44 ; WX 278 ; N comma ; B 62 -185 216 109 ;
-C 45 ; WX 333 ; N hyphen ; B 42 199 291 277 ;
-C 46 ; WX 278 ; N period ; B 77 -15 201 109 ;
-C 47 ; WX 278 ; N slash ; B -32 -15 310 737 ;
-C 48 ; WX 556 ; N zero ; B 42 -15 514 705 ;
-C 49 ; WX 556 ; N one ; B 100 0 496 705 ;
-C 50 ; WX 556 ; N two ; B 35 0 505 705 ;
-C 51 ; WX 556 ; N three ; B 42 -15 498 705 ;
-C 52 ; WX 556 ; N four ; B 28 0 528 705 ;
-C 53 ; WX 556 ; N five ; B 46 -15 502 705 ;
-C 54 ; WX 556 ; N six ; B 41 -15 515 705 ;
-C 55 ; WX 556 ; N seven ; B 59 -15 508 705 ;
-C 56 ; WX 556 ; N eight ; B 42 -15 514 705 ;
-C 57 ; WX 556 ; N nine ; B 41 -15 515 705 ;
-C 58 ; WX 278 ; N colon ; B 77 -15 201 474 ;
-C 59 ; WX 278 ; N semicolon ; B 62 -185 216 474 ;
-C 60 ; WX 606 ; N less ; B 50 -8 556 514 ;
-C 61 ; WX 606 ; N equal ; B 50 117 556 389 ;
-C 62 ; WX 606 ; N greater ; B 50 -8 556 514 ;
-C 63 ; WX 444 ; N question ; B 29 -15 415 737 ;
-C 64 ; WX 737 ; N at ; B -8 -15 744 737 ;
-C 65 ; WX 722 ; N A ; B -8 0 730 737 ;
-C 66 ; WX 722 ; N B ; B 29 0 669 722 ;
-C 67 ; WX 722 ; N C ; B 45 -15 668 737 ;
-C 68 ; WX 778 ; N D ; B 29 0 733 722 ;
-C 69 ; WX 722 ; N E ; B 29 0 663 722 ;
-C 70 ; WX 667 ; N F ; B 29 0 638 722 ;
-C 71 ; WX 778 ; N G ; B 45 -15 775 737 ;
-C 72 ; WX 833 ; N H ; B 29 0 804 722 ;
-C 73 ; WX 407 ; N I ; B 38 0 369 722 ;
-C 74 ; WX 556 ; N J ; B 5 -15 540 722 ;
-C 75 ; WX 778 ; N K ; B 29 0 803 722 ;
-C 76 ; WX 667 ; N L ; B 29 0 644 722 ;
-C 77 ; WX 944 ; N M ; B 29 0 915 722 ;
-C 78 ; WX 815 ; N N ; B 24 -15 791 722 ;
-C 79 ; WX 778 ; N O ; B 45 -15 733 737 ;
-C 80 ; WX 667 ; N P ; B 29 0 650 722 ;
-C 81 ; WX 778 ; N Q ; B 45 -190 748 737 ;
-C 82 ; WX 722 ; N R ; B 29 -15 713 722 ;
-C 83 ; WX 630 ; N S ; B 47 -15 583 737 ;
-C 84 ; WX 667 ; N T ; B 19 0 648 722 ;
-C 85 ; WX 815 ; N U ; B 16 -15 799 722 ;
-C 86 ; WX 722 ; N V ; B -8 -10 730 722 ;
-C 87 ; WX 981 ; N W ; B 5 -10 976 722 ;
-C 88 ; WX 704 ; N X ; B -8 0 712 722 ;
-C 89 ; WX 704 ; N Y ; B -11 0 715 722 ;
-C 90 ; WX 611 ; N Z ; B 24 0 576 722 ;
-C 91 ; WX 333 ; N bracketleft ; B 126 -109 315 737 ;
-C 92 ; WX 606 ; N backslash ; B 132 -15 474 737 ;
-C 93 ; WX 333 ; N bracketright ; B 18 -109 207 737 ;
-C 94 ; WX 606 ; N asciicircum ; B 89 325 517 690 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 204 ; N quoteleft ; B 25 443 179 737 ;
-C 97 ; WX 556 ; N a ; B 44 -15 542 479 ;
-C 98 ; WX 556 ; N b ; B 10 -15 522 737 ;
-C 99 ; WX 444 ; N c ; B 34 -15 426 479 ;
-C 100 ; WX 574 ; N d ; B 34 -15 552 737 ;
-C 101 ; WX 500 ; N e ; B 34 -15 466 479 ;
-C 102 ; WX 333 ; N f ; B 18 0 437 737 ; L i fi ; L l fl ;
-C 103 ; WX 537 ; N g ; B 23 -205 542 494 ;
-C 104 ; WX 611 ; N h ; B 7 0 592 737 ;
-C 105 ; WX 315 ; N i ; B 18 0 286 722 ;
-C 106 ; WX 296 ; N j ; B -86 -205 216 722 ;
-C 107 ; WX 593 ; N k ; B 10 0 589 737 ;
-C 108 ; WX 315 ; N l ; B 18 0 286 737 ;
-C 109 ; WX 889 ; N m ; B 26 0 863 479 ;
-C 110 ; WX 611 ; N n ; B 22 0 589 479 ;
-C 111 ; WX 500 ; N o ; B 34 -15 466 479 ;
-C 112 ; WX 574 ; N p ; B 22 -205 540 479 ;
-C 113 ; WX 556 ; N q ; B 34 -205 552 479 ;
-C 114 ; WX 444 ; N r ; B 18 0 434 479 ;
-C 115 ; WX 463 ; N s ; B 46 -15 417 479 ;
-C 116 ; WX 389 ; N t ; B 18 -15 371 666 ;
-C 117 ; WX 611 ; N u ; B 22 -15 589 464 ;
-C 118 ; WX 537 ; N v ; B -6 -10 515 464 ;
-C 119 ; WX 778 ; N w ; B 1 -10 749 464 ;
-C 120 ; WX 537 ; N x ; B 8 0 529 464 ;
-C 121 ; WX 537 ; N y ; B 4 -205 533 464 ;
-C 122 ; WX 481 ; N z ; B 42 0 439 464 ;
-C 123 ; WX 333 ; N braceleft ; B 54 -109 279 737 ;
-C 124 ; WX 606 ; N bar ; B 267 -250 339 750 ;
-C 125 ; WX 333 ; N braceright ; B 54 -109 279 737 ;
-C 126 ; WX 606 ; N asciitilde ; B 72 184 534 322 ;
-C 161 ; WX 296 ; N exclamdown ; B 86 -205 210 547 ;
-C 162 ; WX 556 ; N cent ; B 74 -141 482 584 ;
-C 163 ; WX 556 ; N sterling ; B 18 -15 538 705 ;
-C 164 ; WX 167 ; N fraction ; B -195 -15 362 705 ;
-C 165 ; WX 556 ; N yen ; B -1 0 557 690 ;
-C 166 ; WX 556 ; N florin ; B 0 -205 538 737 ;
-C 167 ; WX 500 ; N section ; B 55 -147 445 737 ;
-C 168 ; WX 556 ; N currency ; B 26 93 530 597 ;
-C 169 ; WX 204 ; N quotesingle ; B 59 443 145 737 ;
-C 170 ; WX 389 ; N quotedblleft ; B 25 443 364 737 ;
-C 171 ; WX 426 ; N guillemotleft ; B 39 78 387 398 ;
-C 172 ; WX 259 ; N guilsinglleft ; B 39 78 220 398 ;
-C 173 ; WX 259 ; N guilsinglright ; B 39 78 220 398 ;
-C 174 ; WX 611 ; N fi ; B 18 0 582 737 ;
-C 175 ; WX 611 ; N fl ; B 18 0 582 737 ;
-C 177 ; WX 556 ; N endash ; B 0 208 556 268 ;
-C 178 ; WX 500 ; N dagger ; B 42 -147 458 737 ;
-C 179 ; WX 500 ; N daggerdbl ; B 42 -149 458 737 ;
-C 180 ; WX 278 ; N periodcentered ; B 71 238 207 374 ;
-C 182 ; WX 606 ; N paragraph ; B 60 -132 546 722 ;
-C 183 ; WX 606 ; N bullet ; B 122 180 484 542 ;
-C 184 ; WX 204 ; N quotesinglbase ; B 25 -185 179 109 ;
-C 185 ; WX 389 ; N quotedblbase ; B 25 -185 364 109 ;
-C 186 ; WX 389 ; N quotedblright ; B 25 443 364 737 ;
-C 187 ; WX 426 ; N guillemotright ; B 39 78 387 398 ;
-C 188 ; WX 1000 ; N ellipsis ; B 105 -15 895 109 ;
-C 189 ; WX 1000 ; N perthousand ; B 6 -15 994 705 ;
-C 191 ; WX 444 ; N questiondown ; B 29 -205 415 547 ;
-C 193 ; WX 333 ; N grave ; B 17 528 242 699 ;
-C 194 ; WX 333 ; N acute ; B 91 528 316 699 ;
-C 195 ; WX 333 ; N circumflex ; B 10 528 323 695 ;
-C 196 ; WX 333 ; N tilde ; B 1 553 332 655 ;
-C 197 ; WX 333 ; N macron ; B 10 568 323 623 ;
-C 198 ; WX 333 ; N breve ; B 25 528 308 685 ;
-C 199 ; WX 333 ; N dotaccent ; B 116 543 218 645 ;
-C 200 ; WX 333 ; N dieresis ; B 16 543 317 645 ;
-C 202 ; WX 333 ; N ring ; B 66 522 266 722 ;
-C 203 ; WX 333 ; N cedilla ; B 29 -215 237 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B -9 528 416 699 ;
-C 206 ; WX 333 ; N ogonek ; B 68 -215 254 0 ;
-C 207 ; WX 333 ; N caron ; B 10 528 323 695 ;
-C 208 ; WX 1000 ; N emdash ; B 0 208 1000 268 ;
-C 225 ; WX 1000 ; N AE ; B 0 0 962 722 ;
-C 227 ; WX 334 ; N ordfeminine ; B -4 407 338 705 ;
-C 232 ; WX 667 ; N Lslash ; B 29 0 644 722 ;
-C 233 ; WX 778 ; N Oslash ; B 45 -56 733 778 ;
-C 234 ; WX 1000 ; N OE ; B 21 0 979 722 ;
-C 235 ; WX 300 ; N ordmasculine ; B 4 407 296 705 ;
-C 241 ; WX 796 ; N ae ; B 34 -15 762 479 ;
-C 245 ; WX 315 ; N dotlessi ; B 18 0 286 464 ;
-C 248 ; WX 315 ; N lslash ; B 18 0 286 737 ;
-C 249 ; WX 500 ; N oslash ; B 34 -97 466 561 ;
-C 250 ; WX 833 ; N oe ; B 34 -15 799 479 ;
-C 251 ; WX 574 ; N germandbls ; B 30 -15 537 737 ;
-C -1 ; WX 500 ; N ecircumflex ; B 34 -15 466 695 ;
-C -1 ; WX 500 ; N edieresis ; B 34 -15 466 645 ;
-C -1 ; WX 556 ; N aacute ; B 44 -15 542 699 ;
-C -1 ; WX 737 ; N registered ; B -8 -15 744 737 ;
-C -1 ; WX 315 ; N icircumflex ; B 1 0 314 695 ;
-C -1 ; WX 611 ; N udieresis ; B 22 -15 589 645 ;
-C -1 ; WX 500 ; N ograve ; B 34 -15 466 699 ;
-C -1 ; WX 611 ; N uacute ; B 22 -15 589 699 ;
-C -1 ; WX 611 ; N ucircumflex ; B 22 -15 589 695 ;
-C -1 ; WX 722 ; N Aacute ; B -8 0 730 937 ;
-C -1 ; WX 315 ; N igrave ; B 8 0 286 699 ;
-C -1 ; WX 407 ; N Icircumflex ; B 38 0 369 933 ;
-C -1 ; WX 444 ; N ccedilla ; B 34 -215 426 479 ;
-C -1 ; WX 556 ; N adieresis ; B 44 -15 542 645 ;
-C -1 ; WX 722 ; N Ecircumflex ; B 29 0 663 933 ;
-C -1 ; WX 463 ; N scaron ; B 46 -15 417 695 ;
-C -1 ; WX 574 ; N thorn ; B 22 -205 540 737 ;
-C -1 ; WX 1000 ; N trademark ; B 32 318 968 722 ;
-C -1 ; WX 500 ; N egrave ; B 34 -15 466 699 ;
-C -1 ; WX 333 ; N threesuperior ; B 18 273 315 705 ;
-C -1 ; WX 481 ; N zcaron ; B 42 0 439 695 ;
-C -1 ; WX 556 ; N atilde ; B 44 -15 542 655 ;
-C -1 ; WX 556 ; N aring ; B 44 -15 542 732 ;
-C -1 ; WX 500 ; N ocircumflex ; B 34 -15 466 695 ;
-C -1 ; WX 722 ; N Edieresis ; B 29 0 663 883 ;
-C -1 ; WX 834 ; N threequarters ; B 28 -15 795 705 ;
-C -1 ; WX 537 ; N ydieresis ; B 4 -205 533 645 ;
-C -1 ; WX 537 ; N yacute ; B 4 -205 533 699 ;
-C -1 ; WX 315 ; N iacute ; B 18 0 307 699 ;
-C -1 ; WX 722 ; N Acircumflex ; B -8 0 730 933 ;
-C -1 ; WX 815 ; N Uacute ; B 16 -15 799 937 ;
-C -1 ; WX 500 ; N eacute ; B 34 -15 466 699 ;
-C -1 ; WX 778 ; N Ograve ; B 45 -15 733 937 ;
-C -1 ; WX 556 ; N agrave ; B 44 -15 542 699 ;
-C -1 ; WX 815 ; N Udieresis ; B 16 -15 799 883 ;
-C -1 ; WX 556 ; N acircumflex ; B 44 -15 542 695 ;
-C -1 ; WX 407 ; N Igrave ; B 38 0 369 937 ;
-C -1 ; WX 333 ; N twosuperior ; B 14 282 319 705 ;
-C -1 ; WX 815 ; N Ugrave ; B 16 -15 799 937 ;
-C -1 ; WX 834 ; N onequarter ; B 39 -15 795 705 ;
-C -1 ; WX 815 ; N Ucircumflex ; B 16 -15 799 933 ;
-C -1 ; WX 630 ; N Scaron ; B 47 -15 583 933 ;
-C -1 ; WX 407 ; N Idieresis ; B 38 0 369 883 ;
-C -1 ; WX 315 ; N idieresis ; B 7 0 308 645 ;
-C -1 ; WX 722 ; N Egrave ; B 29 0 663 937 ;
-C -1 ; WX 778 ; N Oacute ; B 45 -15 733 937 ;
-C -1 ; WX 606 ; N divide ; B 50 -22 556 528 ;
-C -1 ; WX 722 ; N Atilde ; B -8 0 730 893 ;
-C -1 ; WX 722 ; N Aring ; B -8 0 730 965 ;
-C -1 ; WX 778 ; N Odieresis ; B 45 -15 733 883 ;
-C -1 ; WX 722 ; N Adieresis ; B -8 0 730 883 ;
-C -1 ; WX 815 ; N Ntilde ; B 24 -15 791 893 ;
-C -1 ; WX 611 ; N Zcaron ; B 24 0 576 933 ;
-C -1 ; WX 667 ; N Thorn ; B 29 0 650 722 ;
-C -1 ; WX 407 ; N Iacute ; B 38 0 369 937 ;
-C -1 ; WX 606 ; N plusminus ; B 50 0 556 506 ;
-C -1 ; WX 606 ; N multiply ; B 74 24 532 482 ;
-C -1 ; WX 722 ; N Eacute ; B 29 0 663 937 ;
-C -1 ; WX 704 ; N Ydieresis ; B -11 0 715 883 ;
-C -1 ; WX 333 ; N onesuperior ; B 39 282 294 705 ;
-C -1 ; WX 611 ; N ugrave ; B 22 -15 589 699 ;
-C -1 ; WX 606 ; N logicalnot ; B 50 108 556 389 ;
-C -1 ; WX 611 ; N ntilde ; B 22 0 589 655 ;
-C -1 ; WX 778 ; N Otilde ; B 45 -15 733 893 ;
-C -1 ; WX 500 ; N otilde ; B 34 -15 466 655 ;
-C -1 ; WX 722 ; N Ccedilla ; B 45 -215 668 737 ;
-C -1 ; WX 722 ; N Agrave ; B -8 0 730 937 ;
-C -1 ; WX 834 ; N onehalf ; B 39 -15 820 705 ;
-C -1 ; WX 778 ; N Eth ; B 29 0 733 722 ;
-C -1 ; WX 400 ; N degree ; B 57 419 343 705 ;
-C -1 ; WX 704 ; N Yacute ; B -11 0 715 937 ;
-C -1 ; WX 778 ; N Ocircumflex ; B 45 -15 733 933 ;
-C -1 ; WX 500 ; N oacute ; B 34 -15 466 699 ;
-C -1 ; WX 611 ; N mu ; B 22 -205 589 464 ;
-C -1 ; WX 606 ; N minus ; B 50 217 556 289 ;
-C -1 ; WX 500 ; N eth ; B 34 -15 466 752 ;
-C -1 ; WX 500 ; N odieresis ; B 34 -15 466 645 ;
-C -1 ; WX 737 ; N copyright ; B -8 -15 744 737 ;
-C -1 ; WX 606 ; N brokenbar ; B 267 -175 339 675 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 169
-
-KPX A y -37
-KPX A w -25
-KPX A v -37
-KPX A quoteright -74
-KPX A quotedblright -74
-KPX A Y -75
-KPX A W -50
-KPX A V -75
-KPX A U -30
-KPX A T -18
-
-KPX B period -37
-KPX B comma -37
-KPX B A -18
-
-KPX C period -37
-KPX C comma -37
-KPX C A -18
-
-KPX D period -37
-KPX D comma -37
-KPX D Y -18
-KPX D V -18
-
-KPX F r -10
-KPX F period -125
-KPX F o -55
-KPX F i -10
-KPX F e -55
-KPX F comma -125
-KPX F a -65
-KPX F A -50
-
-KPX G period -37
-KPX G comma -37
-
-KPX J u -25
-KPX J period -74
-KPX J o -25
-KPX J e -25
-KPX J comma -74
-KPX J a -25
-KPX J A -18
-
-KPX K y -25
-KPX K o 10
-KPX K e 10
-
-KPX L y -25
-KPX L quoteright -100
-KPX L quotedblright -100
-KPX L Y -74
-KPX L W -74
-KPX L V -91
-KPX L T -75
-
-KPX N period -55
-KPX N comma -55
-
-KPX O period -37
-KPX O comma -37
-KPX O Y -18
-KPX O V -18
-KPX O T 10
-
-KPX P period -125
-KPX P o -37
-KPX P e -37
-KPX P comma -125
-KPX P a -37
-KPX P A -55
-
-KPX Q period -25
-KPX Q comma -25
-
-KPX S period -37
-KPX S comma -37
-
-KPX T semicolon -37
-KPX T period -125
-KPX T o -55
-KPX T hyphen -100
-KPX T e -55
-KPX T comma -125
-KPX T colon -37
-KPX T a -55
-KPX T O 10
-KPX T A -18
-
-KPX U period -100
-KPX U comma -100
-KPX U A -30
-
-KPX V u -75
-KPX V semicolon -75
-KPX V period -125
-KPX V o -75
-KPX V i -18
-KPX V hyphen -100
-KPX V e -75
-KPX V comma -125
-KPX V colon -75
-KPX V a -85
-KPX V O -18
-KPX V A -74
-
-KPX W y -55
-KPX W u -55
-KPX W semicolon -100
-KPX W period -125
-KPX W o -60
-KPX W i -18
-KPX W hyphen -100
-KPX W e -60
-KPX W comma -125
-KPX W colon -100
-KPX W a -75
-KPX W A -50
-
-KPX Y u -91
-KPX Y semicolon -75
-KPX Y period -100
-KPX Y o -100
-KPX Y i -18
-KPX Y hyphen -125
-KPX Y e -100
-KPX Y comma -100
-KPX Y colon -75
-KPX Y a -100
-KPX Y O -18
-KPX Y A -75
-
-KPX a y -10
-KPX a w -10
-KPX a v -10
-
-KPX b period -18
-KPX b comma -18
-
-KPX c period -18
-KPX c l -7
-KPX c k -7
-KPX c h -7
-KPX c comma -18
-
-KPX colon space -37
-
-KPX comma space -37
-KPX comma quoteright -37
-KPX comma quotedblright -37
-
-KPX e period -18
-KPX e comma -18
-
-KPX f quoteright 100
-KPX f quotedblright 100
-KPX f period -37
-KPX f comma -37
-
-KPX g period -25
-KPX g comma -25
-
-KPX o period -18
-KPX o comma -18
-
-KPX p period -18
-KPX p comma -18
-
-KPX period space -37
-KPX period quoteright -37
-KPX period quotedblright -37
-
-KPX quotedblleft A -74
-
-KPX quotedblright space -37
-
-KPX quoteleft quoteleft -25
-KPX quoteleft A -74
-
-KPX quoteright s -25
-KPX quoteright quoteright -25
-KPX quoteright d -37
-
-KPX r period -100
-KPX r hyphen -37
-KPX r comma -100
-
-KPX s period -25
-KPX s comma -25
-
-KPX semicolon space -37
-
-KPX space quoteleft -37
-KPX space quotedblleft -37
-KPX space Y -37
-KPX space W -37
-KPX space V -37
-KPX space T -37
-KPX space A -37
-
-KPX v period -125
-KPX v comma -125
-
-KPX w period -125
-KPX w comma -125
-KPX w a -18
-
-KPX y period -125
-KPX y comma -125
-EndKernPairs
-EndKernData
-StartComposites 56
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 238 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 238 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 238 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 238 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 195 243 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 238 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 195 238 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 195 238 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 195 238 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 195 238 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 37 238 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 37 238 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 37 238 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 37 238 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 241 238 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 238 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 238 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 238 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 238 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 238 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 149 238 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 241 238 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 241 238 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 241 238 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 241 238 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 216 238 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 186 238 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 238 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 112 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 112 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 112 10 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 84 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 84 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 84 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 84 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -9 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -9 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -9 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -9 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 65 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 102 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 102 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 74 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pncri8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pncri8a.afm
deleted file mode 100644
index 6dfd6a254d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pncri8a.afm
+++ /dev/null
@@ -1,536 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Tue May 28 16:40:04 1991
-Comment UniqueID 35028
-Comment VMusage 31423 38315
-FontName NewCenturySchlbk-Italic
-FullName New Century Schoolbook Italic
-FamilyName New Century Schoolbook
-Weight Medium
-ItalicAngle -16
-IsFixedPitch false
-FontBBox -166 -250 994 958
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.006
-Notice Copyright (c) 1985, 1987, 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.
-EncodingScheme AdobeStandardEncoding
-CapHeight 722
-XHeight 466
-Ascender 737
-Descender -205
-StartCharMetrics 228
-C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 17 -15 303 737 ;
-C 34 ; WX 400 ; N quotedbl ; B 127 463 363 737 ;
-C 35 ; WX 556 ; N numbersign ; B 28 0 528 690 ;
-C 36 ; WX 556 ; N dollar ; B 4 -142 536 808 ;
-C 37 ; WX 833 ; N percent ; B 43 -15 790 705 ;
-C 38 ; WX 852 ; N ampersand ; B 24 -15 773 737 ;
-C 39 ; WX 204 ; N quoteright ; B 39 463 229 737 ;
-C 40 ; WX 333 ; N parenleft ; B 53 -117 411 745 ;
-C 41 ; WX 333 ; N parenright ; B -93 -117 265 745 ;
-C 42 ; WX 500 ; N asterisk ; B 80 318 500 737 ;
-C 43 ; WX 606 ; N plus ; B 50 0 556 506 ;
-C 44 ; WX 278 ; N comma ; B -39 -165 151 109 ;
-C 45 ; WX 333 ; N hyphen ; B 32 202 259 274 ;
-C 46 ; WX 278 ; N period ; B 17 -15 141 109 ;
-C 47 ; WX 606 ; N slash ; B 132 -15 474 737 ;
-C 48 ; WX 556 ; N zero ; B 30 -15 526 705 ;
-C 49 ; WX 556 ; N one ; B 50 0 459 705 ;
-C 50 ; WX 556 ; N two ; B -37 0 506 705 ;
-C 51 ; WX 556 ; N three ; B -2 -15 506 705 ;
-C 52 ; WX 556 ; N four ; B -8 0 512 705 ;
-C 53 ; WX 556 ; N five ; B 4 -15 540 705 ;
-C 54 ; WX 556 ; N six ; B 36 -15 548 705 ;
-C 55 ; WX 556 ; N seven ; B 69 -15 561 705 ;
-C 56 ; WX 556 ; N eight ; B 6 -15 526 705 ;
-C 57 ; WX 556 ; N nine ; B 8 -15 520 705 ;
-C 58 ; WX 278 ; N colon ; B 17 -15 229 466 ;
-C 59 ; WX 278 ; N semicolon ; B -39 -165 229 466 ;
-C 60 ; WX 606 ; N less ; B 36 -8 542 514 ;
-C 61 ; WX 606 ; N equal ; B 50 117 556 389 ;
-C 62 ; WX 606 ; N greater ; B 64 -8 570 514 ;
-C 63 ; WX 444 ; N question ; B 102 -15 417 737 ;
-C 64 ; WX 747 ; N at ; B -2 -15 750 737 ;
-C 65 ; WX 704 ; N A ; B -87 0 668 737 ;
-C 66 ; WX 722 ; N B ; B -33 0 670 722 ;
-C 67 ; WX 722 ; N C ; B 40 -15 712 737 ;
-C 68 ; WX 778 ; N D ; B -33 0 738 722 ;
-C 69 ; WX 722 ; N E ; B -33 0 700 722 ;
-C 70 ; WX 667 ; N F ; B -33 0 700 722 ;
-C 71 ; WX 778 ; N G ; B 40 -15 763 737 ;
-C 72 ; WX 833 ; N H ; B -33 0 866 722 ;
-C 73 ; WX 407 ; N I ; B -33 0 435 722 ;
-C 74 ; WX 611 ; N J ; B -14 -15 651 722 ;
-C 75 ; WX 741 ; N K ; B -33 0 816 722 ;
-C 76 ; WX 667 ; N L ; B -33 0 627 722 ;
-C 77 ; WX 944 ; N M ; B -33 0 977 722 ;
-C 78 ; WX 815 ; N N ; B -51 -15 866 722 ;
-C 79 ; WX 778 ; N O ; B 40 -15 738 737 ;
-C 80 ; WX 667 ; N P ; B -33 0 667 722 ;
-C 81 ; WX 778 ; N Q ; B 40 -190 738 737 ;
-C 82 ; WX 741 ; N R ; B -45 -15 692 722 ;
-C 83 ; WX 667 ; N S ; B -6 -15 638 737 ;
-C 84 ; WX 685 ; N T ; B 40 0 725 722 ;
-C 85 ; WX 815 ; N U ; B 93 -15 867 722 ;
-C 86 ; WX 704 ; N V ; B 36 -10 779 722 ;
-C 87 ; WX 926 ; N W ; B 53 -10 978 722 ;
-C 88 ; WX 704 ; N X ; B -75 0 779 722 ;
-C 89 ; WX 685 ; N Y ; B 31 0 760 722 ;
-C 90 ; WX 667 ; N Z ; B -25 0 667 722 ;
-C 91 ; WX 333 ; N bracketleft ; B -55 -109 388 737 ;
-C 92 ; WX 606 ; N backslash ; B 132 -15 474 737 ;
-C 93 ; WX 333 ; N bracketright ; B -77 -109 366 737 ;
-C 94 ; WX 606 ; N asciicircum ; B 89 325 517 690 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 204 ; N quoteleft ; B 39 463 229 737 ;
-C 97 ; WX 574 ; N a ; B 2 -15 524 466 ;
-C 98 ; WX 556 ; N b ; B 32 -15 488 737 ;
-C 99 ; WX 444 ; N c ; B 2 -15 394 466 ;
-C 100 ; WX 611 ; N d ; B 2 -15 585 737 ;
-C 101 ; WX 444 ; N e ; B -6 -15 388 466 ;
-C 102 ; WX 333 ; N f ; B -68 -205 470 737 ; L i fi ; L l fl ;
-C 103 ; WX 537 ; N g ; B -79 -205 523 497 ;
-C 104 ; WX 611 ; N h ; B 14 -15 562 737 ;
-C 105 ; WX 333 ; N i ; B 29 -15 282 715 ;
-C 106 ; WX 315 ; N j ; B -166 -205 318 715 ;
-C 107 ; WX 556 ; N k ; B 0 -15 497 737 ;
-C 108 ; WX 333 ; N l ; B 14 -15 292 737 ;
-C 109 ; WX 889 ; N m ; B 14 -15 840 466 ;
-C 110 ; WX 611 ; N n ; B 14 -15 562 466 ;
-C 111 ; WX 500 ; N o ; B 2 -15 450 466 ;
-C 112 ; WX 574 ; N p ; B -101 -205 506 466 ;
-C 113 ; WX 556 ; N q ; B 2 -205 500 466 ;
-C 114 ; WX 444 ; N r ; B 10 0 434 466 ;
-C 115 ; WX 444 ; N s ; B 2 -15 394 466 ;
-C 116 ; WX 352 ; N t ; B 24 -15 328 619 ;
-C 117 ; WX 611 ; N u ; B 44 -15 556 466 ;
-C 118 ; WX 519 ; N v ; B 31 -15 447 466 ;
-C 119 ; WX 778 ; N w ; B 31 -15 706 466 ;
-C 120 ; WX 500 ; N x ; B -33 -15 471 466 ;
-C 121 ; WX 500 ; N y ; B -83 -205 450 466 ;
-C 122 ; WX 463 ; N z ; B -33 -15 416 466 ;
-C 123 ; WX 333 ; N braceleft ; B 38 -109 394 737 ;
-C 124 ; WX 606 ; N bar ; B 267 -250 339 750 ;
-C 125 ; WX 333 ; N braceright ; B -87 -109 269 737 ;
-C 126 ; WX 606 ; N asciitilde ; B 72 184 534 322 ;
-C 161 ; WX 333 ; N exclamdown ; B -22 -205 264 547 ;
-C 162 ; WX 556 ; N cent ; B 62 -144 486 580 ;
-C 163 ; WX 556 ; N sterling ; B -13 -15 544 705 ;
-C 164 ; WX 167 ; N fraction ; B -134 -15 301 705 ;
-C 165 ; WX 556 ; N yen ; B 40 0 624 690 ;
-C 166 ; WX 556 ; N florin ; B -58 -205 569 737 ;
-C 167 ; WX 500 ; N section ; B -10 -147 480 737 ;
-C 168 ; WX 556 ; N currency ; B 26 93 530 597 ;
-C 169 ; WX 278 ; N quotesingle ; B 151 463 237 737 ;
-C 170 ; WX 389 ; N quotedblleft ; B 39 463 406 737 ;
-C 171 ; WX 426 ; N guillemotleft ; B -15 74 402 402 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 40 74 259 402 ;
-C 173 ; WX 333 ; N guilsinglright ; B 40 74 259 402 ;
-C 174 ; WX 611 ; N fi ; B -68 -205 555 737 ;
-C 175 ; WX 611 ; N fl ; B -68 -205 587 737 ;
-C 177 ; WX 500 ; N endash ; B -27 208 487 268 ;
-C 178 ; WX 500 ; N dagger ; B 51 -147 506 737 ;
-C 179 ; WX 500 ; N daggerdbl ; B -54 -147 506 737 ;
-C 180 ; WX 278 ; N periodcentered ; B 71 238 207 374 ;
-C 182 ; WX 650 ; N paragraph ; B 48 -132 665 722 ;
-C 183 ; WX 606 ; N bullet ; B 122 180 484 542 ;
-C 184 ; WX 204 ; N quotesinglbase ; B -78 -165 112 109 ;
-C 185 ; WX 389 ; N quotedblbase ; B -78 -165 289 109 ;
-C 186 ; WX 389 ; N quotedblright ; B 39 463 406 737 ;
-C 187 ; WX 426 ; N guillemotright ; B -15 74 402 402 ;
-C 188 ; WX 1000 ; N ellipsis ; B 59 -15 849 109 ;
-C 189 ; WX 1000 ; N perthousand ; B 6 -15 994 705 ;
-C 191 ; WX 444 ; N questiondown ; B -3 -205 312 547 ;
-C 193 ; WX 333 ; N grave ; B 71 518 262 690 ;
-C 194 ; WX 333 ; N acute ; B 132 518 355 690 ;
-C 195 ; WX 333 ; N circumflex ; B 37 518 331 690 ;
-C 196 ; WX 333 ; N tilde ; B 52 547 383 649 ;
-C 197 ; WX 333 ; N macron ; B 52 560 363 610 ;
-C 198 ; WX 333 ; N breve ; B 69 518 370 677 ;
-C 199 ; WX 333 ; N dotaccent ; B 146 544 248 646 ;
-C 200 ; WX 333 ; N dieresis ; B 59 544 359 646 ;
-C 202 ; WX 333 ; N ring ; B 114 512 314 712 ;
-C 203 ; WX 333 ; N cedilla ; B 3 -215 215 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 32 518 455 690 ;
-C 206 ; WX 333 ; N ogonek ; B 68 -215 254 0 ;
-C 207 ; WX 333 ; N caron ; B 73 518 378 690 ;
-C 208 ; WX 1000 ; N emdash ; B -27 208 987 268 ;
-C 225 ; WX 870 ; N AE ; B -87 0 888 722 ;
-C 227 ; WX 422 ; N ordfeminine ; B 72 416 420 705 ;
-C 232 ; WX 667 ; N Lslash ; B -33 0 627 722 ;
-C 233 ; WX 778 ; N Oslash ; B 16 -68 748 780 ;
-C 234 ; WX 981 ; N OE ; B 40 0 975 722 ;
-C 235 ; WX 372 ; N ordmasculine ; B 66 416 370 705 ;
-C 241 ; WX 722 ; N ae ; B -18 -15 666 466 ;
-C 245 ; WX 333 ; N dotlessi ; B 29 -15 282 466 ;
-C 248 ; WX 333 ; N lslash ; B -25 -15 340 737 ;
-C 249 ; WX 500 ; N oslash ; B 2 -121 450 549 ;
-C 250 ; WX 778 ; N oe ; B 2 -15 722 466 ;
-C 251 ; WX 556 ; N germandbls ; B -76 -205 525 737 ;
-C -1 ; WX 444 ; N ecircumflex ; B -6 -15 388 690 ;
-C -1 ; WX 444 ; N edieresis ; B -6 -15 415 646 ;
-C -1 ; WX 574 ; N aacute ; B 2 -15 524 690 ;
-C -1 ; WX 747 ; N registered ; B -2 -15 750 737 ;
-C -1 ; WX 333 ; N icircumflex ; B 29 -15 331 690 ;
-C -1 ; WX 611 ; N udieresis ; B 44 -15 556 646 ;
-C -1 ; WX 500 ; N ograve ; B 2 -15 450 690 ;
-C -1 ; WX 611 ; N uacute ; B 44 -15 556 690 ;
-C -1 ; WX 611 ; N ucircumflex ; B 44 -15 556 690 ;
-C -1 ; WX 704 ; N Aacute ; B -87 0 668 946 ;
-C -1 ; WX 333 ; N igrave ; B 29 -15 282 690 ;
-C -1 ; WX 407 ; N Icircumflex ; B -33 0 435 946 ;
-C -1 ; WX 444 ; N ccedilla ; B 2 -215 394 466 ;
-C -1 ; WX 574 ; N adieresis ; B 2 -15 524 646 ;
-C -1 ; WX 722 ; N Ecircumflex ; B -33 0 700 946 ;
-C -1 ; WX 444 ; N scaron ; B 2 -15 434 690 ;
-C -1 ; WX 574 ; N thorn ; B -101 -205 506 737 ;
-C -1 ; WX 950 ; N trademark ; B 32 318 968 722 ;
-C -1 ; WX 444 ; N egrave ; B -6 -15 388 690 ;
-C -1 ; WX 333 ; N threesuperior ; B 22 273 359 705 ;
-C -1 ; WX 463 ; N zcaron ; B -33 -15 443 690 ;
-C -1 ; WX 574 ; N atilde ; B 2 -15 524 649 ;
-C -1 ; WX 574 ; N aring ; B 2 -15 524 712 ;
-C -1 ; WX 500 ; N ocircumflex ; B 2 -15 450 690 ;
-C -1 ; WX 722 ; N Edieresis ; B -33 0 700 902 ;
-C -1 ; WX 834 ; N threequarters ; B 22 -15 782 705 ;
-C -1 ; WX 500 ; N ydieresis ; B -83 -205 450 646 ;
-C -1 ; WX 500 ; N yacute ; B -83 -205 450 690 ;
-C -1 ; WX 333 ; N iacute ; B 29 -15 355 690 ;
-C -1 ; WX 704 ; N Acircumflex ; B -87 0 668 946 ;
-C -1 ; WX 815 ; N Uacute ; B 93 -15 867 946 ;
-C -1 ; WX 444 ; N eacute ; B -6 -15 411 690 ;
-C -1 ; WX 778 ; N Ograve ; B 40 -15 738 946 ;
-C -1 ; WX 574 ; N agrave ; B 2 -15 524 690 ;
-C -1 ; WX 815 ; N Udieresis ; B 93 -15 867 902 ;
-C -1 ; WX 574 ; N acircumflex ; B 2 -15 524 690 ;
-C -1 ; WX 407 ; N Igrave ; B -33 0 435 946 ;
-C -1 ; WX 333 ; N twosuperior ; B 0 282 359 705 ;
-C -1 ; WX 815 ; N Ugrave ; B 93 -15 867 946 ;
-C -1 ; WX 834 ; N onequarter ; B 34 -15 782 705 ;
-C -1 ; WX 815 ; N Ucircumflex ; B 93 -15 867 946 ;
-C -1 ; WX 667 ; N Scaron ; B -6 -15 638 946 ;
-C -1 ; WX 407 ; N Idieresis ; B -33 0 456 902 ;
-C -1 ; WX 333 ; N idieresis ; B 29 -15 359 646 ;
-C -1 ; WX 722 ; N Egrave ; B -33 0 700 946 ;
-C -1 ; WX 778 ; N Oacute ; B 40 -15 738 946 ;
-C -1 ; WX 606 ; N divide ; B 50 -22 556 528 ;
-C -1 ; WX 704 ; N Atilde ; B -87 0 668 905 ;
-C -1 ; WX 704 ; N Aring ; B -87 0 668 958 ;
-C -1 ; WX 778 ; N Odieresis ; B 40 -15 738 902 ;
-C -1 ; WX 704 ; N Adieresis ; B -87 0 668 902 ;
-C -1 ; WX 815 ; N Ntilde ; B -51 -15 866 905 ;
-C -1 ; WX 667 ; N Zcaron ; B -25 0 667 946 ;
-C -1 ; WX 667 ; N Thorn ; B -33 0 627 722 ;
-C -1 ; WX 407 ; N Iacute ; B -33 0 452 946 ;
-C -1 ; WX 606 ; N plusminus ; B 50 0 556 506 ;
-C -1 ; WX 606 ; N multiply ; B 74 24 532 482 ;
-C -1 ; WX 722 ; N Eacute ; B -33 0 700 946 ;
-C -1 ; WX 685 ; N Ydieresis ; B 31 0 760 902 ;
-C -1 ; WX 333 ; N onesuperior ; B 34 282 311 705 ;
-C -1 ; WX 611 ; N ugrave ; B 44 -15 556 690 ;
-C -1 ; WX 606 ; N logicalnot ; B 50 108 556 389 ;
-C -1 ; WX 611 ; N ntilde ; B 14 -15 562 649 ;
-C -1 ; WX 778 ; N Otilde ; B 40 -15 738 905 ;
-C -1 ; WX 500 ; N otilde ; B 2 -15 467 649 ;
-C -1 ; WX 722 ; N Ccedilla ; B 40 -215 712 737 ;
-C -1 ; WX 704 ; N Agrave ; B -87 0 668 946 ;
-C -1 ; WX 834 ; N onehalf ; B 34 -15 776 705 ;
-C -1 ; WX 778 ; N Eth ; B -33 0 738 722 ;
-C -1 ; WX 400 ; N degree ; B 86 419 372 705 ;
-C -1 ; WX 685 ; N Yacute ; B 31 0 760 946 ;
-C -1 ; WX 778 ; N Ocircumflex ; B 40 -15 738 946 ;
-C -1 ; WX 500 ; N oacute ; B 2 -15 450 690 ;
-C -1 ; WX 611 ; N mu ; B -60 -205 556 466 ;
-C -1 ; WX 606 ; N minus ; B 50 217 556 289 ;
-C -1 ; WX 500 ; N eth ; B 2 -15 450 737 ;
-C -1 ; WX 500 ; N odieresis ; B 2 -15 450 646 ;
-C -1 ; WX 747 ; N copyright ; B -2 -15 750 737 ;
-C -1 ; WX 606 ; N brokenbar ; B 267 -175 339 675 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 181
-
-KPX A y -55
-KPX A w -18
-KPX A v -18
-KPX A u -18
-KPX A quoteright -125
-KPX A quotedblright -125
-KPX A Y -55
-KPX A W -74
-KPX A V -74
-KPX A U -37
-KPX A T -30
-KPX A Q -18
-KPX A O -18
-KPX A G -18
-KPX A C -18
-
-KPX B period -50
-KPX B comma -50
-
-KPX C period -50
-KPX C comma -50
-
-KPX D period -50
-KPX D comma -50
-KPX D Y -18
-KPX D W -18
-KPX D V -18
-
-KPX F r -55
-KPX F period -125
-KPX F o -55
-KPX F i -10
-KPX F e -55
-KPX F comma -125
-KPX F a -55
-KPX F A -35
-
-KPX G period -50
-KPX G comma -50
-
-KPX J u -18
-KPX J period -100
-KPX J o -37
-KPX J e -37
-KPX J comma -100
-KPX J a -37
-KPX J A -18
-
-KPX L y -50
-KPX L quoteright -125
-KPX L quotedblright -125
-KPX L Y -100
-KPX L W -100
-KPX L V -100
-KPX L T -100
-
-KPX N period -60
-KPX N comma -60
-
-KPX O period -50
-KPX O comma -50
-KPX O Y -18
-KPX O X -18
-KPX O V -18
-KPX O T 18
-
-KPX P period -125
-KPX P o -55
-KPX P e -55
-KPX P comma -125
-KPX P a -55
-KPX P A -50
-
-KPX Q period -20
-KPX Q comma -20
-
-KPX R Y -18
-KPX R W -18
-KPX R V -18
-KPX R U -18
-
-KPX S period -50
-KPX S comma -50
-
-KPX T y -50
-KPX T w -50
-KPX T u -50
-KPX T semicolon -50
-KPX T r -50
-KPX T period -100
-KPX T o -74
-KPX T i -18
-KPX T hyphen -100
-KPX T h -25
-KPX T e -74
-KPX T comma -100
-KPX T colon -50
-KPX T a -74
-KPX T O 18
-
-KPX U period -100
-KPX U comma -100
-KPX U A -18
-
-KPX V u -75
-KPX V semicolon -75
-KPX V period -100
-KPX V o -75
-KPX V i -50
-KPX V hyphen -100
-KPX V e -75
-KPX V comma -100
-KPX V colon -75
-KPX V a -75
-KPX V A -37
-
-KPX W y -55
-KPX W u -55
-KPX W semicolon -75
-KPX W period -100
-KPX W o -55
-KPX W i -20
-KPX W hyphen -75
-KPX W h -20
-KPX W e -55
-KPX W comma -100
-KPX W colon -75
-KPX W a -55
-KPX W A -55
-
-KPX Y u -100
-KPX Y semicolon -75
-KPX Y period -100
-KPX Y o -100
-KPX Y i -25
-KPX Y hyphen -100
-KPX Y e -100
-KPX Y comma -100
-KPX Y colon -75
-KPX Y a -100
-KPX Y A -55
-
-KPX b period -50
-KPX b comma -50
-KPX b b -10
-
-KPX c period -50
-KPX c k -18
-KPX c h -18
-KPX c comma -50
-
-KPX colon space -37
-
-KPX comma space -37
-KPX comma quoteright -37
-KPX comma quotedblright -37
-
-KPX e period -37
-KPX e comma -37
-
-KPX f quoteright 75
-KPX f quotedblright 75
-KPX f period -75
-KPX f o -10
-KPX f comma -75
-
-KPX g period -50
-KPX g comma -50
-
-KPX l y -10
-
-KPX o period -50
-KPX o comma -50
-
-KPX p period -50
-KPX p comma -50
-
-KPX period space -37
-KPX period quoteright -37
-KPX period quotedblright -37
-
-KPX quotedblleft A -75
-
-KPX quotedblright space -37
-
-KPX quoteleft quoteleft -37
-KPX quoteleft A -75
-
-KPX quoteright s -25
-KPX quoteright quoteright -37
-KPX quoteright d -37
-
-KPX r semicolon -25
-KPX r s -10
-KPX r period -125
-KPX r k -18
-KPX r hyphen -75
-KPX r comma -125
-KPX r colon -25
-
-KPX s period -50
-KPX s comma -50
-
-KPX semicolon space -37
-
-KPX space quoteleft -37
-KPX space quotedblleft -37
-KPX space Y -37
-KPX space W -37
-KPX space V -37
-KPX space T -37
-KPX space A -37
-
-KPX v period -75
-KPX v comma -75
-
-KPX w period -75
-KPX w comma -75
-
-KPX y period -75
-KPX y comma -75
-EndKernPairs
-EndKernData
-StartComposites 56
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 246 256 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 246 256 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 231 256 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 246 256 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 216 246 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 231 256 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 255 256 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 255 256 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 255 256 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 255 256 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 97 256 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 97 256 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 97 256 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 97 256 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 301 256 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 283 256 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 283 256 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 283 256 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 283 256 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 283 256 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 227 256 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 301 256 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 301 256 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 301 256 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 301 256 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 256 256 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 236 256 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 227 256 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 121 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 121 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 121 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 121 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 121 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 121 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 0 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 56 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 139 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 139 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 65 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pplb8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pplb8a.afm
deleted file mode 100644
index de7698d29d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pplb8a.afm
+++ /dev/null
@@ -1,434 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Mon Jul 2 22:26:30 1990
-Comment UniqueID 31793
-Comment VMusage 36031 46923
-FontName Palatino-Bold
-FullName Palatino Bold
-FamilyName Palatino
-Weight Bold
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -152 -266 1000 924
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.005
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Palatino is a trademark of Linotype AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 681
-XHeight 471
-Ascender 720
-Descender -258
-StartCharMetrics 228
-C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 278 ; N exclam ; B 63 -12 219 688 ;
-C 34 ; WX 402 ; N quotedbl ; B 22 376 380 695 ;
-C 35 ; WX 500 ; N numbersign ; B 4 0 496 673 ;
-C 36 ; WX 500 ; N dollar ; B 28 -114 472 721 ;
-C 37 ; WX 889 ; N percent ; B 61 -9 828 714 ;
-C 38 ; WX 833 ; N ampersand ; B 52 -17 813 684 ;
-C 39 ; WX 278 ; N quoteright ; B 29 405 249 695 ;
-C 40 ; WX 333 ; N parenleft ; B 65 -104 305 723 ;
-C 41 ; WX 333 ; N parenright ; B 28 -104 268 723 ;
-C 42 ; WX 444 ; N asterisk ; B 44 332 399 695 ;
-C 43 ; WX 606 ; N plus ; B 51 0 555 505 ;
-C 44 ; WX 250 ; N comma ; B -6 -166 227 141 ;
-C 45 ; WX 333 ; N hyphen ; B 16 195 317 305 ;
-C 46 ; WX 250 ; N period ; B 47 -12 203 144 ;
-C 47 ; WX 296 ; N slash ; B -9 -17 305 720 ;
-C 48 ; WX 500 ; N zero ; B 33 -17 468 660 ;
-C 49 ; WX 500 ; N one ; B 35 -3 455 670 ;
-C 50 ; WX 500 ; N two ; B 25 -3 472 660 ;
-C 51 ; WX 500 ; N three ; B 22 -17 458 660 ;
-C 52 ; WX 500 ; N four ; B 12 -3 473 672 ;
-C 53 ; WX 500 ; N five ; B 42 -17 472 656 ;
-C 54 ; WX 500 ; N six ; B 37 -17 469 660 ;
-C 55 ; WX 500 ; N seven ; B 46 -3 493 656 ;
-C 56 ; WX 500 ; N eight ; B 34 -17 467 660 ;
-C 57 ; WX 500 ; N nine ; B 31 -17 463 660 ;
-C 58 ; WX 250 ; N colon ; B 47 -12 203 454 ;
-C 59 ; WX 250 ; N semicolon ; B -6 -166 227 454 ;
-C 60 ; WX 606 ; N less ; B 49 -15 558 519 ;
-C 61 ; WX 606 ; N equal ; B 51 114 555 396 ;
-C 62 ; WX 606 ; N greater ; B 49 -15 558 519 ;
-C 63 ; WX 444 ; N question ; B 43 -12 411 687 ;
-C 64 ; WX 747 ; N at ; B 42 -12 704 681 ;
-C 65 ; WX 778 ; N A ; B 24 -3 757 686 ;
-C 66 ; WX 667 ; N B ; B 39 -3 611 681 ;
-C 67 ; WX 722 ; N C ; B 44 -17 695 695 ;
-C 68 ; WX 833 ; N D ; B 35 -3 786 681 ;
-C 69 ; WX 611 ; N E ; B 39 -4 577 681 ;
-C 70 ; WX 556 ; N F ; B 28 -3 539 681 ;
-C 71 ; WX 833 ; N G ; B 47 -17 776 695 ;
-C 72 ; WX 833 ; N H ; B 36 -3 796 681 ;
-C 73 ; WX 389 ; N I ; B 39 -3 350 681 ;
-C 74 ; WX 389 ; N J ; B -11 -213 350 681 ;
-C 75 ; WX 778 ; N K ; B 39 -3 763 681 ;
-C 76 ; WX 611 ; N L ; B 39 -4 577 681 ;
-C 77 ; WX 1000 ; N M ; B 32 -10 968 681 ;
-C 78 ; WX 833 ; N N ; B 35 -16 798 681 ;
-C 79 ; WX 833 ; N O ; B 47 -17 787 695 ;
-C 80 ; WX 611 ; N P ; B 39 -3 594 681 ;
-C 81 ; WX 833 ; N Q ; B 47 -184 787 695 ;
-C 82 ; WX 722 ; N R ; B 39 -3 708 681 ;
-C 83 ; WX 611 ; N S ; B 57 -17 559 695 ;
-C 84 ; WX 667 ; N T ; B 17 -3 650 681 ;
-C 85 ; WX 778 ; N U ; B 26 -17 760 681 ;
-C 86 ; WX 778 ; N V ; B 20 -3 763 681 ;
-C 87 ; WX 1000 ; N W ; B 17 -3 988 686 ;
-C 88 ; WX 667 ; N X ; B 17 -3 650 695 ;
-C 89 ; WX 667 ; N Y ; B 15 -3 660 695 ;
-C 90 ; WX 667 ; N Z ; B 24 -3 627 681 ;
-C 91 ; WX 333 ; N bracketleft ; B 73 -104 291 720 ;
-C 92 ; WX 606 ; N backslash ; B 72 0 534 720 ;
-C 93 ; WX 333 ; N bracketright ; B 42 -104 260 720 ;
-C 94 ; WX 606 ; N asciicircum ; B 52 275 554 678 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 278 ; N quoteleft ; B 29 405 249 695 ;
-C 97 ; WX 500 ; N a ; B 40 -17 478 471 ;
-C 98 ; WX 611 ; N b ; B 10 -17 556 720 ;
-C 99 ; WX 444 ; N c ; B 37 -17 414 471 ;
-C 100 ; WX 611 ; N d ; B 42 -17 577 720 ;
-C 101 ; WX 500 ; N e ; B 42 -17 461 471 ;
-C 102 ; WX 389 ; N f ; B 34 -3 381 720 ; L i fi ; L l fl ;
-C 103 ; WX 556 ; N g ; B 26 -266 535 471 ;
-C 104 ; WX 611 ; N h ; B 24 -3 587 720 ;
-C 105 ; WX 333 ; N i ; B 34 -3 298 706 ;
-C 106 ; WX 333 ; N j ; B 3 -266 241 706 ;
-C 107 ; WX 611 ; N k ; B 21 -3 597 720 ;
-C 108 ; WX 333 ; N l ; B 24 -3 296 720 ;
-C 109 ; WX 889 ; N m ; B 24 -3 864 471 ;
-C 110 ; WX 611 ; N n ; B 24 -3 587 471 ;
-C 111 ; WX 556 ; N o ; B 40 -17 517 471 ;
-C 112 ; WX 611 ; N p ; B 29 -258 567 471 ;
-C 113 ; WX 611 ; N q ; B 52 -258 589 471 ;
-C 114 ; WX 389 ; N r ; B 30 -3 389 471 ;
-C 115 ; WX 444 ; N s ; B 39 -17 405 471 ;
-C 116 ; WX 333 ; N t ; B 22 -17 324 632 ;
-C 117 ; WX 611 ; N u ; B 25 -17 583 471 ;
-C 118 ; WX 556 ; N v ; B 11 -3 545 459 ;
-C 119 ; WX 833 ; N w ; B 13 -3 820 471 ;
-C 120 ; WX 500 ; N x ; B 20 -3 483 471 ;
-C 121 ; WX 556 ; N y ; B 10 -266 546 459 ;
-C 122 ; WX 500 ; N z ; B 16 -3 464 459 ;
-C 123 ; WX 310 ; N braceleft ; B 5 -117 288 725 ;
-C 124 ; WX 606 ; N bar ; B 260 0 346 720 ;
-C 125 ; WX 310 ; N braceright ; B 22 -117 305 725 ;
-C 126 ; WX 606 ; N asciitilde ; B 51 155 555 342 ;
-C 161 ; WX 278 ; N exclamdown ; B 59 -227 215 471 ;
-C 162 ; WX 500 ; N cent ; B 73 -106 450 554 ;
-C 163 ; WX 500 ; N sterling ; B -2 -19 501 676 ;
-C 164 ; WX 167 ; N fraction ; B -152 0 320 660 ;
-C 165 ; WX 500 ; N yen ; B 17 -3 483 695 ;
-C 166 ; WX 500 ; N florin ; B 11 -242 490 703 ;
-C 167 ; WX 500 ; N section ; B 30 -217 471 695 ;
-C 168 ; WX 500 ; N currency ; B 32 96 468 533 ;
-C 169 ; WX 227 ; N quotesingle ; B 45 376 181 695 ;
-C 170 ; WX 500 ; N quotedblleft ; B 34 405 466 695 ;
-C 171 ; WX 500 ; N guillemotleft ; B 36 44 463 438 ;
-C 172 ; WX 389 ; N guilsinglleft ; B 82 44 307 438 ;
-C 173 ; WX 389 ; N guilsinglright ; B 82 44 307 438 ;
-C 174 ; WX 611 ; N fi ; B 10 -3 595 720 ;
-C 175 ; WX 611 ; N fl ; B 17 -3 593 720 ;
-C 177 ; WX 500 ; N endash ; B 0 208 500 291 ;
-C 178 ; WX 500 ; N dagger ; B 29 -6 472 682 ;
-C 179 ; WX 500 ; N daggerdbl ; B 32 -245 468 682 ;
-C 180 ; WX 250 ; N periodcentered ; B 47 179 203 335 ;
-C 182 ; WX 641 ; N paragraph ; B 19 -161 599 683 ;
-C 183 ; WX 606 ; N bullet ; B 131 172 475 516 ;
-C 184 ; WX 333 ; N quotesinglbase ; B 56 -160 276 130 ;
-C 185 ; WX 500 ; N quotedblbase ; B 34 -160 466 130 ;
-C 186 ; WX 500 ; N quotedblright ; B 34 405 466 695 ;
-C 187 ; WX 500 ; N guillemotright ; B 37 44 464 438 ;
-C 188 ; WX 1000 ; N ellipsis ; B 89 -12 911 144 ;
-C 189 ; WX 1000 ; N perthousand ; B 33 -9 982 724 ;
-C 191 ; WX 444 ; N questiondown ; B 33 -231 401 471 ;
-C 193 ; WX 333 ; N grave ; B 18 506 256 691 ;
-C 194 ; WX 333 ; N acute ; B 78 506 316 691 ;
-C 195 ; WX 333 ; N circumflex ; B -2 506 335 681 ;
-C 196 ; WX 333 ; N tilde ; B -16 535 349 661 ;
-C 197 ; WX 333 ; N macron ; B 1 538 332 609 ;
-C 198 ; WX 333 ; N breve ; B 15 506 318 669 ;
-C 199 ; WX 333 ; N dotaccent ; B 100 537 234 671 ;
-C 200 ; WX 333 ; N dieresis ; B -8 537 341 671 ;
-C 202 ; WX 333 ; N ring ; B 67 500 267 700 ;
-C 203 ; WX 333 ; N cedilla ; B 73 -225 300 -7 ;
-C 205 ; WX 333 ; N hungarumlaut ; B -56 506 390 691 ;
-C 206 ; WX 333 ; N ogonek ; B 60 -246 274 -17 ;
-C 207 ; WX 333 ; N caron ; B -2 510 335 685 ;
-C 208 ; WX 1000 ; N emdash ; B 0 208 1000 291 ;
-C 225 ; WX 1000 ; N AE ; B 12 -4 954 681 ;
-C 227 ; WX 438 ; N ordfeminine ; B 77 367 361 660 ;
-C 232 ; WX 611 ; N Lslash ; B 16 -4 577 681 ;
-C 233 ; WX 833 ; N Oslash ; B 32 -20 808 698 ;
-C 234 ; WX 1000 ; N OE ; B 43 -17 985 695 ;
-C 235 ; WX 488 ; N ordmasculine ; B 89 367 399 660 ;
-C 241 ; WX 778 ; N ae ; B 46 -17 731 471 ;
-C 245 ; WX 333 ; N dotlessi ; B 34 -3 298 471 ;
-C 248 ; WX 333 ; N lslash ; B -4 -3 334 720 ;
-C 249 ; WX 556 ; N oslash ; B 23 -18 534 471 ;
-C 250 ; WX 833 ; N oe ; B 48 -17 799 471 ;
-C 251 ; WX 611 ; N germandbls ; B 30 -17 565 720 ;
-C -1 ; WX 667 ; N Zcaron ; B 24 -3 627 909 ;
-C -1 ; WX 444 ; N ccedilla ; B 37 -225 414 471 ;
-C -1 ; WX 556 ; N ydieresis ; B 10 -266 546 691 ;
-C -1 ; WX 500 ; N atilde ; B 40 -17 478 673 ;
-C -1 ; WX 333 ; N icircumflex ; B -2 -3 335 701 ;
-C -1 ; WX 300 ; N threesuperior ; B 9 261 292 667 ;
-C -1 ; WX 500 ; N ecircumflex ; B 42 -17 461 701 ;
-C -1 ; WX 611 ; N thorn ; B 17 -258 563 720 ;
-C -1 ; WX 500 ; N egrave ; B 42 -17 461 711 ;
-C -1 ; WX 300 ; N twosuperior ; B 5 261 295 660 ;
-C -1 ; WX 500 ; N eacute ; B 42 -17 461 711 ;
-C -1 ; WX 556 ; N otilde ; B 40 -17 517 673 ;
-C -1 ; WX 778 ; N Aacute ; B 24 -3 757 915 ;
-C -1 ; WX 556 ; N ocircumflex ; B 40 -17 517 701 ;
-C -1 ; WX 556 ; N yacute ; B 10 -266 546 711 ;
-C -1 ; WX 611 ; N udieresis ; B 25 -17 583 691 ;
-C -1 ; WX 750 ; N threequarters ; B 15 -2 735 667 ;
-C -1 ; WX 500 ; N acircumflex ; B 40 -17 478 701 ;
-C -1 ; WX 833 ; N Eth ; B 10 -3 786 681 ;
-C -1 ; WX 500 ; N edieresis ; B 42 -17 461 691 ;
-C -1 ; WX 611 ; N ugrave ; B 25 -17 583 711 ;
-C -1 ; WX 998 ; N trademark ; B 38 274 961 678 ;
-C -1 ; WX 556 ; N ograve ; B 40 -17 517 711 ;
-C -1 ; WX 444 ; N scaron ; B 39 -17 405 693 ;
-C -1 ; WX 389 ; N Idieresis ; B 20 -3 369 895 ;
-C -1 ; WX 611 ; N uacute ; B 25 -17 583 711 ;
-C -1 ; WX 500 ; N agrave ; B 40 -17 478 711 ;
-C -1 ; WX 611 ; N ntilde ; B 24 -3 587 673 ;
-C -1 ; WX 500 ; N aring ; B 40 -17 478 700 ;
-C -1 ; WX 500 ; N zcaron ; B 16 -3 464 693 ;
-C -1 ; WX 389 ; N Icircumflex ; B 26 -3 363 905 ;
-C -1 ; WX 833 ; N Ntilde ; B 35 -16 798 885 ;
-C -1 ; WX 611 ; N ucircumflex ; B 25 -17 583 701 ;
-C -1 ; WX 611 ; N Ecircumflex ; B 39 -4 577 905 ;
-C -1 ; WX 389 ; N Iacute ; B 39 -3 350 915 ;
-C -1 ; WX 722 ; N Ccedilla ; B 44 -225 695 695 ;
-C -1 ; WX 833 ; N Odieresis ; B 47 -17 787 895 ;
-C -1 ; WX 611 ; N Scaron ; B 57 -17 559 909 ;
-C -1 ; WX 611 ; N Edieresis ; B 39 -4 577 895 ;
-C -1 ; WX 389 ; N Igrave ; B 39 -3 350 915 ;
-C -1 ; WX 500 ; N adieresis ; B 40 -17 478 691 ;
-C -1 ; WX 833 ; N Ograve ; B 47 -17 787 915 ;
-C -1 ; WX 611 ; N Egrave ; B 39 -4 577 915 ;
-C -1 ; WX 667 ; N Ydieresis ; B 15 -3 660 895 ;
-C -1 ; WX 747 ; N registered ; B 26 -17 720 695 ;
-C -1 ; WX 833 ; N Otilde ; B 47 -17 787 885 ;
-C -1 ; WX 750 ; N onequarter ; B 19 -2 735 665 ;
-C -1 ; WX 778 ; N Ugrave ; B 26 -17 760 915 ;
-C -1 ; WX 778 ; N Ucircumflex ; B 26 -17 760 905 ;
-C -1 ; WX 611 ; N Thorn ; B 39 -3 574 681 ;
-C -1 ; WX 606 ; N divide ; B 51 0 555 510 ;
-C -1 ; WX 778 ; N Atilde ; B 24 -3 757 885 ;
-C -1 ; WX 778 ; N Uacute ; B 26 -17 760 915 ;
-C -1 ; WX 833 ; N Ocircumflex ; B 47 -17 787 905 ;
-C -1 ; WX 606 ; N logicalnot ; B 51 114 555 396 ;
-C -1 ; WX 778 ; N Aring ; B 24 -3 757 924 ;
-C -1 ; WX 333 ; N idieresis ; B -8 -3 341 691 ;
-C -1 ; WX 333 ; N iacute ; B 34 -3 316 711 ;
-C -1 ; WX 500 ; N aacute ; B 40 -17 478 711 ;
-C -1 ; WX 606 ; N plusminus ; B 51 0 555 505 ;
-C -1 ; WX 606 ; N multiply ; B 72 21 534 483 ;
-C -1 ; WX 778 ; N Udieresis ; B 26 -17 760 895 ;
-C -1 ; WX 606 ; N minus ; B 51 212 555 298 ;
-C -1 ; WX 300 ; N onesuperior ; B 14 261 287 665 ;
-C -1 ; WX 611 ; N Eacute ; B 39 -4 577 915 ;
-C -1 ; WX 778 ; N Acircumflex ; B 24 -3 757 905 ;
-C -1 ; WX 747 ; N copyright ; B 26 -17 720 695 ;
-C -1 ; WX 778 ; N Agrave ; B 24 -3 757 915 ;
-C -1 ; WX 556 ; N odieresis ; B 40 -17 517 691 ;
-C -1 ; WX 556 ; N oacute ; B 40 -17 517 711 ;
-C -1 ; WX 400 ; N degree ; B 50 360 350 660 ;
-C -1 ; WX 333 ; N igrave ; B 18 -3 298 711 ;
-C -1 ; WX 611 ; N mu ; B 25 -225 583 471 ;
-C -1 ; WX 833 ; N Oacute ; B 47 -17 787 915 ;
-C -1 ; WX 556 ; N eth ; B 40 -17 517 720 ;
-C -1 ; WX 778 ; N Adieresis ; B 24 -3 757 895 ;
-C -1 ; WX 667 ; N Yacute ; B 15 -3 660 915 ;
-C -1 ; WX 606 ; N brokenbar ; B 260 0 346 720 ;
-C -1 ; WX 750 ; N onehalf ; B 9 -2 745 665 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 101
-
-KPX A y -70
-KPX A w -70
-KPX A v -70
-KPX A space -18
-KPX A quoteright -92
-KPX A Y -111
-KPX A W -90
-KPX A V -129
-KPX A T -92
-
-KPX F period -111
-KPX F comma -111
-KPX F A -55
-
-KPX L y -74
-KPX L space -18
-KPX L quoteright -74
-KPX L Y -92
-KPX L W -92
-KPX L V -92
-KPX L T -74
-
-KPX P period -129
-KPX P comma -129
-KPX P A -74
-
-KPX R y -30
-KPX R Y -55
-KPX R W -37
-KPX R V -74
-KPX R T -55
-
-KPX T y -90
-KPX T w -90
-KPX T u -129
-KPX T semicolon -74
-KPX T s -111
-KPX T r -111
-KPX T period -92
-KPX T o -111
-KPX T i -55
-KPX T hyphen -92
-KPX T e -111
-KPX T comma -92
-KPX T colon -74
-KPX T c -129
-KPX T a -111
-KPX T A -92
-
-KPX V y -90
-KPX V u -92
-KPX V semicolon -74
-KPX V r -111
-KPX V period -129
-KPX V o -111
-KPX V i -55
-KPX V hyphen -92
-KPX V e -111
-KPX V comma -129
-KPX V colon -74
-KPX V a -111
-KPX V A -129
-
-KPX W y -74
-KPX W u -74
-KPX W semicolon -37
-KPX W r -74
-KPX W period -37
-KPX W o -74
-KPX W i -37
-KPX W hyphen -37
-KPX W e -74
-KPX W comma -92
-KPX W colon -37
-KPX W a -74
-KPX W A -90
-
-KPX Y v -74
-KPX Y u -74
-KPX Y semicolon -55
-KPX Y q -92
-KPX Y period -74
-KPX Y p -74
-KPX Y o -74
-KPX Y i -55
-KPX Y hyphen -74
-KPX Y e -74
-KPX Y comma -74
-KPX Y colon -55
-KPX Y a -74
-KPX Y A -55
-
-KPX f quoteright 37
-KPX f f -18
-
-KPX one one -37
-
-KPX quoteleft quoteleft -55
-
-KPX quoteright t -18
-KPX quoteright space -55
-KPX quoteright s -55
-KPX quoteright quoteright -55
-
-KPX r quoteright 55
-KPX r period -55
-KPX r hyphen -18
-KPX r comma -55
-
-KPX v period -111
-KPX v comma -111
-
-KPX w period -92
-KPX w comma -92
-
-KPX y period -92
-KPX y comma -92
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 223 224 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 211 224 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 223 224 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 215 224 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 223 224 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 223 224 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 195 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 224 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 224 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 224 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 224 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 224 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 224 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 224 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 224 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 250 224 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 250 224 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 250 224 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 250 224 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 250 224 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 250 224 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 139 224 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 235 224 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 235 224 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 235 224 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 223 224 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 211 224 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 199 224 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 224 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 84 20 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 84 20 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 84 20 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 84 20 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 84 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 12 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 84 20 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 96 20 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 92 20 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 84 20 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 20 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex 0 20 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 20 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 20 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 139 12 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 112 20 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 112 20 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 20 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 112 20 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 12 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 56 8 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 151 20 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 139 20 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 139 20 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 131 20 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 144 20 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 124 20 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 8 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pplbi8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pplbi8a.afm
deleted file mode 100644
index e161d04909..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pplbi8a.afm
+++ /dev/null
@@ -1,441 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Mon Jul 2 22:48:39 1990
-Comment UniqueID 31799
-Comment VMusage 37656 48548
-FontName Palatino-BoldItalic
-FullName Palatino Bold Italic
-FamilyName Palatino
-Weight Bold
-ItalicAngle -10
-IsFixedPitch false
-FontBBox -170 -271 1073 926
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.005
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Palatino is a trademark of Linotype AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 681
-XHeight 469
-Ascender 726
-Descender -271
-StartCharMetrics 228
-C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 58 -17 322 695 ;
-C 34 ; WX 500 ; N quotedbl ; B 137 467 493 720 ;
-C 35 ; WX 500 ; N numbersign ; B 4 0 496 673 ;
-C 36 ; WX 500 ; N dollar ; B 20 -108 477 737 ;
-C 37 ; WX 889 ; N percent ; B 56 -17 790 697 ;
-C 38 ; WX 833 ; N ampersand ; B 74 -17 811 695 ;
-C 39 ; WX 278 ; N quoteright ; B 76 431 302 720 ;
-C 40 ; WX 333 ; N parenleft ; B 58 -129 368 723 ;
-C 41 ; WX 333 ; N parenright ; B -12 -129 298 723 ;
-C 42 ; WX 444 ; N asterisk ; B 84 332 439 695 ;
-C 43 ; WX 606 ; N plus ; B 50 -5 556 501 ;
-C 44 ; WX 250 ; N comma ; B -33 -164 208 147 ;
-C 45 ; WX 389 ; N hyphen ; B 37 198 362 300 ;
-C 46 ; WX 250 ; N period ; B 48 -17 187 135 ;
-C 47 ; WX 315 ; N slash ; B 1 -17 315 720 ;
-C 48 ; WX 500 ; N zero ; B 42 -17 490 683 ;
-C 49 ; WX 500 ; N one ; B 41 -3 434 678 ;
-C 50 ; WX 500 ; N two ; B 1 -3 454 683 ;
-C 51 ; WX 500 ; N three ; B 8 -17 450 683 ;
-C 52 ; WX 500 ; N four ; B 3 -3 487 683 ;
-C 53 ; WX 500 ; N five ; B 14 -17 481 675 ;
-C 54 ; WX 500 ; N six ; B 39 -17 488 683 ;
-C 55 ; WX 500 ; N seven ; B 69 -3 544 674 ;
-C 56 ; WX 500 ; N eight ; B 26 -17 484 683 ;
-C 57 ; WX 500 ; N nine ; B 27 -17 491 683 ;
-C 58 ; WX 250 ; N colon ; B 38 -17 236 452 ;
-C 59 ; WX 250 ; N semicolon ; B -33 -164 247 452 ;
-C 60 ; WX 606 ; N less ; B 49 -21 558 517 ;
-C 61 ; WX 606 ; N equal ; B 51 106 555 390 ;
-C 62 ; WX 606 ; N greater ; B 48 -21 557 517 ;
-C 63 ; WX 444 ; N question ; B 91 -17 450 695 ;
-C 64 ; WX 833 ; N at ; B 82 -12 744 681 ;
-C 65 ; WX 722 ; N A ; B -35 -3 685 683 ;
-C 66 ; WX 667 ; N B ; B 8 -3 629 681 ;
-C 67 ; WX 685 ; N C ; B 69 -17 695 695 ;
-C 68 ; WX 778 ; N D ; B 0 -3 747 682 ;
-C 69 ; WX 611 ; N E ; B 11 -3 606 681 ;
-C 70 ; WX 556 ; N F ; B -6 -3 593 681 ;
-C 71 ; WX 778 ; N G ; B 72 -17 750 695 ;
-C 72 ; WX 778 ; N H ; B -12 -3 826 681 ;
-C 73 ; WX 389 ; N I ; B -1 -3 412 681 ;
-C 74 ; WX 389 ; N J ; B -29 -207 417 681 ;
-C 75 ; WX 722 ; N K ; B -10 -3 746 681 ;
-C 76 ; WX 611 ; N L ; B 26 -3 578 681 ;
-C 77 ; WX 944 ; N M ; B -23 -17 985 681 ;
-C 78 ; WX 778 ; N N ; B -2 -3 829 681 ;
-C 79 ; WX 833 ; N O ; B 76 -17 794 695 ;
-C 80 ; WX 667 ; N P ; B 11 -3 673 681 ;
-C 81 ; WX 833 ; N Q ; B 76 -222 794 695 ;
-C 82 ; WX 722 ; N R ; B 4 -3 697 681 ;
-C 83 ; WX 556 ; N S ; B 50 -17 517 695 ;
-C 84 ; WX 611 ; N T ; B 56 -3 674 681 ;
-C 85 ; WX 778 ; N U ; B 83 -17 825 681 ;
-C 86 ; WX 667 ; N V ; B 67 -3 745 681 ;
-C 87 ; WX 1000 ; N W ; B 67 -3 1073 689 ;
-C 88 ; WX 722 ; N X ; B -9 -3 772 681 ;
-C 89 ; WX 611 ; N Y ; B 54 -3 675 695 ;
-C 90 ; WX 667 ; N Z ; B 1 -3 676 681 ;
-C 91 ; WX 333 ; N bracketleft ; B 45 -102 381 723 ;
-C 92 ; WX 606 ; N backslash ; B 72 0 534 720 ;
-C 93 ; WX 333 ; N bracketright ; B -21 -102 315 723 ;
-C 94 ; WX 606 ; N asciicircum ; B 63 275 543 678 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 278 ; N quoteleft ; B 65 431 291 720 ;
-C 97 ; WX 556 ; N a ; B 44 -17 519 470 ;
-C 98 ; WX 537 ; N b ; B 44 -17 494 726 ;
-C 99 ; WX 444 ; N c ; B 32 -17 436 469 ;
-C 100 ; WX 556 ; N d ; B 38 -17 550 726 ;
-C 101 ; WX 444 ; N e ; B 28 -17 418 469 ;
-C 102 ; WX 333 ; N f ; B -130 -271 449 726 ; L i fi ; L l fl ;
-C 103 ; WX 500 ; N g ; B -50 -271 529 469 ;
-C 104 ; WX 556 ; N h ; B 22 -17 522 726 ;
-C 105 ; WX 333 ; N i ; B 26 -17 312 695 ;
-C 106 ; WX 333 ; N j ; B -64 -271 323 695 ;
-C 107 ; WX 556 ; N k ; B 34 -17 528 726 ;
-C 108 ; WX 333 ; N l ; B 64 -17 318 726 ;
-C 109 ; WX 833 ; N m ; B 19 -17 803 469 ;
-C 110 ; WX 556 ; N n ; B 17 -17 521 469 ;
-C 111 ; WX 556 ; N o ; B 48 -17 502 469 ;
-C 112 ; WX 556 ; N p ; B -21 -271 516 469 ;
-C 113 ; WX 537 ; N q ; B 32 -271 513 469 ;
-C 114 ; WX 389 ; N r ; B 20 -17 411 469 ;
-C 115 ; WX 444 ; N s ; B 25 -17 406 469 ;
-C 116 ; WX 389 ; N t ; B 42 -17 409 636 ;
-C 117 ; WX 556 ; N u ; B 22 -17 521 469 ;
-C 118 ; WX 556 ; N v ; B 19 -17 513 469 ;
-C 119 ; WX 833 ; N w ; B 27 -17 802 469 ;
-C 120 ; WX 500 ; N x ; B -8 -17 500 469 ;
-C 121 ; WX 556 ; N y ; B 13 -271 541 469 ;
-C 122 ; WX 500 ; N z ; B 31 -17 470 469 ;
-C 123 ; WX 333 ; N braceleft ; B 18 -105 334 720 ;
-C 124 ; WX 606 ; N bar ; B 259 0 347 720 ;
-C 125 ; WX 333 ; N braceright ; B -1 -105 315 720 ;
-C 126 ; WX 606 ; N asciitilde ; B 51 151 555 346 ;
-C 161 ; WX 333 ; N exclamdown ; B 2 -225 259 479 ;
-C 162 ; WX 500 ; N cent ; B 52 -105 456 547 ;
-C 163 ; WX 500 ; N sterling ; B 21 -5 501 683 ;
-C 164 ; WX 167 ; N fraction ; B -170 0 338 683 ;
-C 165 ; WX 500 ; N yen ; B 11 -3 538 695 ;
-C 166 ; WX 500 ; N florin ; B 8 -242 479 690 ;
-C 167 ; WX 556 ; N section ; B 47 -151 497 695 ;
-C 168 ; WX 500 ; N currency ; B 32 96 468 533 ;
-C 169 ; WX 250 ; N quotesingle ; B 127 467 293 720 ;
-C 170 ; WX 500 ; N quotedblleft ; B 65 431 511 720 ;
-C 171 ; WX 500 ; N guillemotleft ; B 35 43 458 446 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 60 43 292 446 ;
-C 173 ; WX 333 ; N guilsinglright ; B 35 40 267 443 ;
-C 174 ; WX 611 ; N fi ; B -130 -271 588 726 ;
-C 175 ; WX 611 ; N fl ; B -130 -271 631 726 ;
-C 177 ; WX 500 ; N endash ; B -12 214 512 282 ;
-C 178 ; WX 556 ; N dagger ; B 67 -3 499 685 ;
-C 179 ; WX 556 ; N daggerdbl ; B 33 -153 537 693 ;
-C 180 ; WX 250 ; N periodcentered ; B 67 172 206 324 ;
-C 182 ; WX 556 ; N paragraph ; B 14 -204 629 681 ;
-C 183 ; WX 606 ; N bullet ; B 131 172 475 516 ;
-C 184 ; WX 250 ; N quotesinglbase ; B -3 -144 220 145 ;
-C 185 ; WX 500 ; N quotedblbase ; B -18 -144 424 145 ;
-C 186 ; WX 500 ; N quotedblright ; B 73 431 519 720 ;
-C 187 ; WX 500 ; N guillemotright ; B 35 40 458 443 ;
-C 188 ; WX 1000 ; N ellipsis ; B 91 -17 896 135 ;
-C 189 ; WX 1000 ; N perthousand ; B 65 -17 912 691 ;
-C 191 ; WX 444 ; N questiondown ; B -12 -226 347 479 ;
-C 193 ; WX 333 ; N grave ; B 110 518 322 699 ;
-C 194 ; WX 333 ; N acute ; B 153 518 392 699 ;
-C 195 ; WX 333 ; N circumflex ; B 88 510 415 684 ;
-C 196 ; WX 333 ; N tilde ; B 82 535 441 654 ;
-C 197 ; WX 333 ; N macron ; B 76 538 418 608 ;
-C 198 ; WX 333 ; N breve ; B 96 518 412 680 ;
-C 199 ; WX 333 ; N dotaccent ; B 202 537 325 668 ;
-C 200 ; WX 333 ; N dieresis ; B 90 537 426 668 ;
-C 202 ; WX 556 ; N ring ; B 277 514 477 714 ;
-C 203 ; WX 333 ; N cedilla ; B 12 -218 248 5 ;
-C 205 ; WX 333 ; N hungarumlaut ; B -28 518 409 699 ;
-C 206 ; WX 333 ; N ogonek ; B 32 -206 238 -17 ;
-C 207 ; WX 333 ; N caron ; B 113 510 445 684 ;
-C 208 ; WX 1000 ; N emdash ; B -12 214 1012 282 ;
-C 225 ; WX 944 ; N AE ; B -29 -3 927 681 ;
-C 227 ; WX 333 ; N ordfeminine ; B 47 391 355 684 ;
-C 232 ; WX 611 ; N Lslash ; B 6 -3 578 681 ;
-C 233 ; WX 833 ; N Oslash ; B 57 -54 797 730 ;
-C 234 ; WX 944 ; N OE ; B 39 -17 961 695 ;
-C 235 ; WX 333 ; N ordmasculine ; B 51 391 346 683 ;
-C 241 ; WX 738 ; N ae ; B 44 -17 711 469 ;
-C 245 ; WX 333 ; N dotlessi ; B 26 -17 293 469 ;
-C 248 ; WX 333 ; N lslash ; B 13 -17 365 726 ;
-C 249 ; WX 556 ; N oslash ; B 14 -50 522 506 ;
-C 250 ; WX 778 ; N oe ; B 48 -17 755 469 ;
-C 251 ; WX 556 ; N germandbls ; B -131 -271 549 726 ;
-C -1 ; WX 667 ; N Zcaron ; B 1 -3 676 896 ;
-C -1 ; WX 444 ; N ccedilla ; B 32 -218 436 469 ;
-C -1 ; WX 556 ; N ydieresis ; B 13 -271 541 688 ;
-C -1 ; WX 556 ; N atilde ; B 44 -17 553 666 ;
-C -1 ; WX 333 ; N icircumflex ; B 26 -17 403 704 ;
-C -1 ; WX 300 ; N threesuperior ; B 23 263 310 683 ;
-C -1 ; WX 444 ; N ecircumflex ; B 28 -17 471 704 ;
-C -1 ; WX 556 ; N thorn ; B -21 -271 516 726 ;
-C -1 ; WX 444 ; N egrave ; B 28 -17 418 719 ;
-C -1 ; WX 300 ; N twosuperior ; B 26 271 321 683 ;
-C -1 ; WX 444 ; N eacute ; B 28 -17 448 719 ;
-C -1 ; WX 556 ; N otilde ; B 48 -17 553 666 ;
-C -1 ; WX 722 ; N Aacute ; B -35 -3 685 911 ;
-C -1 ; WX 556 ; N ocircumflex ; B 48 -17 515 704 ;
-C -1 ; WX 556 ; N yacute ; B 13 -271 541 719 ;
-C -1 ; WX 556 ; N udieresis ; B 22 -17 538 688 ;
-C -1 ; WX 750 ; N threequarters ; B 18 -2 732 683 ;
-C -1 ; WX 556 ; N acircumflex ; B 44 -17 527 704 ;
-C -1 ; WX 778 ; N Eth ; B 0 -3 747 682 ;
-C -1 ; WX 444 ; N edieresis ; B 28 -17 482 688 ;
-C -1 ; WX 556 ; N ugrave ; B 22 -17 521 719 ;
-C -1 ; WX 1000 ; N trademark ; B 38 274 961 678 ;
-C -1 ; WX 556 ; N ograve ; B 48 -17 502 719 ;
-C -1 ; WX 444 ; N scaron ; B 25 -17 489 692 ;
-C -1 ; WX 389 ; N Idieresis ; B -1 -3 454 880 ;
-C -1 ; WX 556 ; N uacute ; B 22 -17 521 719 ;
-C -1 ; WX 556 ; N agrave ; B 44 -17 519 719 ;
-C -1 ; WX 556 ; N ntilde ; B 17 -17 553 666 ;
-C -1 ; WX 556 ; N aring ; B 44 -17 519 714 ;
-C -1 ; WX 500 ; N zcaron ; B 31 -17 517 692 ;
-C -1 ; WX 389 ; N Icircumflex ; B -1 -3 443 896 ;
-C -1 ; WX 778 ; N Ntilde ; B -2 -3 829 866 ;
-C -1 ; WX 556 ; N ucircumflex ; B 22 -17 521 704 ;
-C -1 ; WX 611 ; N Ecircumflex ; B 11 -3 606 896 ;
-C -1 ; WX 389 ; N Iacute ; B -1 -3 420 911 ;
-C -1 ; WX 685 ; N Ccedilla ; B 69 -218 695 695 ;
-C -1 ; WX 833 ; N Odieresis ; B 76 -17 794 880 ;
-C -1 ; WX 556 ; N Scaron ; B 50 -17 557 896 ;
-C -1 ; WX 611 ; N Edieresis ; B 11 -3 606 880 ;
-C -1 ; WX 389 ; N Igrave ; B -1 -3 412 911 ;
-C -1 ; WX 556 ; N adieresis ; B 44 -17 538 688 ;
-C -1 ; WX 833 ; N Ograve ; B 76 -17 794 911 ;
-C -1 ; WX 611 ; N Egrave ; B 11 -3 606 911 ;
-C -1 ; WX 611 ; N Ydieresis ; B 54 -3 675 880 ;
-C -1 ; WX 747 ; N registered ; B 26 -17 720 695 ;
-C -1 ; WX 833 ; N Otilde ; B 76 -17 794 866 ;
-C -1 ; WX 750 ; N onequarter ; B 18 -2 732 683 ;
-C -1 ; WX 778 ; N Ugrave ; B 83 -17 825 911 ;
-C -1 ; WX 778 ; N Ucircumflex ; B 83 -17 825 896 ;
-C -1 ; WX 667 ; N Thorn ; B 11 -3 644 681 ;
-C -1 ; WX 606 ; N divide ; B 50 -5 556 501 ;
-C -1 ; WX 722 ; N Atilde ; B -35 -3 685 866 ;
-C -1 ; WX 778 ; N Uacute ; B 83 -17 825 911 ;
-C -1 ; WX 833 ; N Ocircumflex ; B 76 -17 794 896 ;
-C -1 ; WX 606 ; N logicalnot ; B 51 107 555 390 ;
-C -1 ; WX 722 ; N Aring ; B -35 -3 685 926 ;
-C -1 ; WX 333 ; N idieresis ; B 26 -17 426 688 ;
-C -1 ; WX 333 ; N iacute ; B 26 -17 392 719 ;
-C -1 ; WX 556 ; N aacute ; B 44 -17 519 719 ;
-C -1 ; WX 606 ; N plusminus ; B 50 0 556 501 ;
-C -1 ; WX 606 ; N multiply ; B 72 17 534 479 ;
-C -1 ; WX 778 ; N Udieresis ; B 83 -17 825 880 ;
-C -1 ; WX 606 ; N minus ; B 51 204 555 292 ;
-C -1 ; WX 300 ; N onesuperior ; B 41 271 298 680 ;
-C -1 ; WX 611 ; N Eacute ; B 11 -3 606 911 ;
-C -1 ; WX 722 ; N Acircumflex ; B -35 -3 685 896 ;
-C -1 ; WX 747 ; N copyright ; B 26 -17 720 695 ;
-C -1 ; WX 722 ; N Agrave ; B -35 -3 685 911 ;
-C -1 ; WX 556 ; N odieresis ; B 48 -17 538 688 ;
-C -1 ; WX 556 ; N oacute ; B 48 -17 504 719 ;
-C -1 ; WX 400 ; N degree ; B 50 383 350 683 ;
-C -1 ; WX 333 ; N igrave ; B 26 -17 322 719 ;
-C -1 ; WX 556 ; N mu ; B -15 -232 521 469 ;
-C -1 ; WX 833 ; N Oacute ; B 76 -17 794 911 ;
-C -1 ; WX 556 ; N eth ; B 48 -17 546 726 ;
-C -1 ; WX 722 ; N Adieresis ; B -35 -3 685 880 ;
-C -1 ; WX 611 ; N Yacute ; B 54 -3 675 911 ;
-C -1 ; WX 606 ; N brokenbar ; B 259 0 347 720 ;
-C -1 ; WX 750 ; N onehalf ; B 14 -2 736 683 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 108
-
-KPX A y -55
-KPX A w -37
-KPX A v -55
-KPX A space -55
-KPX A quoteright -55
-KPX A Y -74
-KPX A W -74
-KPX A V -74
-KPX A T -55
-
-KPX F space -18
-KPX F period -111
-KPX F comma -111
-KPX F A -74
-
-KPX L y -37
-KPX L space -18
-KPX L quoteright -55
-KPX L Y -74
-KPX L W -74
-KPX L V -74
-KPX L T -74
-
-KPX P space -55
-KPX P period -129
-KPX P comma -129
-KPX P A -92
-
-KPX R y -20
-KPX R Y -37
-KPX R W -55
-KPX R V -55
-KPX R T -37
-
-KPX T y -80
-KPX T w -50
-KPX T u -92
-KPX T semicolon -55
-KPX T s -92
-KPX T r -92
-KPX T period -55
-KPX T o -111
-KPX T i -74
-KPX T hyphen -92
-KPX T e -111
-KPX T comma -55
-KPX T colon -55
-KPX T c -92
-KPX T a -111
-KPX T O -18
-KPX T A -55
-
-KPX V y -50
-KPX V u -50
-KPX V semicolon -37
-KPX V r -74
-KPX V period -111
-KPX V o -74
-KPX V i -50
-KPX V hyphen -37
-KPX V e -74
-KPX V comma -111
-KPX V colon -37
-KPX V a -92
-KPX V A -74
-
-KPX W y -30
-KPX W u -30
-KPX W semicolon -18
-KPX W r -30
-KPX W period -55
-KPX W o -55
-KPX W i -30
-KPX W e -55
-KPX W comma -55
-KPX W colon -28
-KPX W a -74
-KPX W A -74
-
-KPX Y v -30
-KPX Y u -50
-KPX Y semicolon -55
-KPX Y q -92
-KPX Y period -55
-KPX Y p -74
-KPX Y o -111
-KPX Y i -54
-KPX Y hyphen -55
-KPX Y e -92
-KPX Y comma -55
-KPX Y colon -55
-KPX Y a -111
-KPX Y A -55
-
-KPX f quoteright 37
-KPX f f -37
-
-KPX one one -55
-
-KPX quoteleft quoteleft -55
-
-KPX quoteright t -18
-KPX quoteright space -37
-KPX quoteright s -37
-KPX quoteright quoteright -55
-
-KPX r quoteright 55
-KPX r q -18
-KPX r period -55
-KPX r o -18
-KPX r h -18
-KPX r g -18
-KPX r e -18
-KPX r comma -55
-KPX r c -18
-
-KPX v period -55
-KPX v comma -55
-
-KPX w period -55
-KPX w comma -55
-
-KPX y period -37
-KPX y comma -37
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 212 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 212 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 212 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 212 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 83 212 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 212 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 176 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 212 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 212 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 212 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 212 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 212 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 212 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 212 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 212 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 223 212 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 250 212 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 250 212 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 250 212 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 250 212 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 250 212 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 212 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 223 212 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 223 212 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 223 212 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 211 212 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 151 212 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 139 212 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 212 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 112 20 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 112 20 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 112 20 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 112 20 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 0 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 112 12 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 56 20 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 20 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 20 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 56 20 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute 0 20 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -12 20 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis 0 20 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave 0 20 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 112 12 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 112 20 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 100 20 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 112 20 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 112 20 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 112 12 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 44 8 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 112 20 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 100 20 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 20 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 112 20 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 112 20 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 20 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 72 8 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pplr8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pplr8a.afm
deleted file mode 100644
index 6566b16ed7..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pplr8a.afm
+++ /dev/null
@@ -1,445 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Mon Jul 2 22:14:17 1990
-Comment UniqueID 31790
-Comment VMusage 36445 47337
-FontName Palatino-Roman
-FullName Palatino Roman
-FamilyName Palatino
-Weight Roman
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -166 -283 1021 927
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.005
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Palatino is a trademark of Linotype AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 692
-XHeight 469
-Ascender 726
-Descender -281
-StartCharMetrics 228
-C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 278 ; N exclam ; B 81 -5 197 694 ;
-C 34 ; WX 371 ; N quotedbl ; B 52 469 319 709 ;
-C 35 ; WX 500 ; N numbersign ; B 4 0 495 684 ;
-C 36 ; WX 500 ; N dollar ; B 30 -116 471 731 ;
-C 37 ; WX 840 ; N percent ; B 39 -20 802 709 ;
-C 38 ; WX 778 ; N ampersand ; B 43 -20 753 689 ;
-C 39 ; WX 278 ; N quoteright ; B 45 446 233 709 ;
-C 40 ; WX 333 ; N parenleft ; B 60 -215 301 726 ;
-C 41 ; WX 333 ; N parenright ; B 32 -215 273 726 ;
-C 42 ; WX 389 ; N asterisk ; B 32 342 359 689 ;
-C 43 ; WX 606 ; N plus ; B 51 7 555 512 ;
-C 44 ; WX 250 ; N comma ; B 16 -155 218 123 ;
-C 45 ; WX 333 ; N hyphen ; B 17 215 312 287 ;
-C 46 ; WX 250 ; N period ; B 67 -5 183 111 ;
-C 47 ; WX 606 ; N slash ; B 87 -119 519 726 ;
-C 48 ; WX 500 ; N zero ; B 29 -20 465 689 ;
-C 49 ; WX 500 ; N one ; B 60 -3 418 694 ;
-C 50 ; WX 500 ; N two ; B 16 -3 468 689 ;
-C 51 ; WX 500 ; N three ; B 15 -20 462 689 ;
-C 52 ; WX 500 ; N four ; B 2 -3 472 694 ;
-C 53 ; WX 500 ; N five ; B 13 -20 459 689 ;
-C 54 ; WX 500 ; N six ; B 32 -20 468 689 ;
-C 55 ; WX 500 ; N seven ; B 44 -3 497 689 ;
-C 56 ; WX 500 ; N eight ; B 30 -20 464 689 ;
-C 57 ; WX 500 ; N nine ; B 20 -20 457 689 ;
-C 58 ; WX 250 ; N colon ; B 66 -5 182 456 ;
-C 59 ; WX 250 ; N semicolon ; B 16 -153 218 456 ;
-C 60 ; WX 606 ; N less ; B 57 0 558 522 ;
-C 61 ; WX 606 ; N equal ; B 51 136 555 386 ;
-C 62 ; WX 606 ; N greater ; B 48 0 549 522 ;
-C 63 ; WX 444 ; N question ; B 43 -5 395 694 ;
-C 64 ; WX 747 ; N at ; B 24 -20 724 694 ;
-C 65 ; WX 778 ; N A ; B 15 -3 756 700 ;
-C 66 ; WX 611 ; N B ; B 26 -3 576 692 ;
-C 67 ; WX 709 ; N C ; B 22 -20 670 709 ;
-C 68 ; WX 774 ; N D ; B 22 -3 751 692 ;
-C 69 ; WX 611 ; N E ; B 22 -3 572 692 ;
-C 70 ; WX 556 ; N F ; B 22 -3 536 692 ;
-C 71 ; WX 763 ; N G ; B 22 -20 728 709 ;
-C 72 ; WX 832 ; N H ; B 22 -3 810 692 ;
-C 73 ; WX 337 ; N I ; B 22 -3 315 692 ;
-C 74 ; WX 333 ; N J ; B -15 -194 311 692 ;
-C 75 ; WX 726 ; N K ; B 22 -3 719 692 ;
-C 76 ; WX 611 ; N L ; B 22 -3 586 692 ;
-C 77 ; WX 946 ; N M ; B 16 -13 926 692 ;
-C 78 ; WX 831 ; N N ; B 17 -20 813 692 ;
-C 79 ; WX 786 ; N O ; B 22 -20 764 709 ;
-C 80 ; WX 604 ; N P ; B 22 -3 580 692 ;
-C 81 ; WX 786 ; N Q ; B 22 -176 764 709 ;
-C 82 ; WX 668 ; N R ; B 22 -3 669 692 ;
-C 83 ; WX 525 ; N S ; B 24 -20 503 709 ;
-C 84 ; WX 613 ; N T ; B 18 -3 595 692 ;
-C 85 ; WX 778 ; N U ; B 12 -20 759 692 ;
-C 86 ; WX 722 ; N V ; B 8 -9 706 692 ;
-C 87 ; WX 1000 ; N W ; B 8 -9 984 700 ;
-C 88 ; WX 667 ; N X ; B 14 -3 648 700 ;
-C 89 ; WX 667 ; N Y ; B 9 -3 654 704 ;
-C 90 ; WX 667 ; N Z ; B 15 -3 638 692 ;
-C 91 ; WX 333 ; N bracketleft ; B 79 -184 288 726 ;
-C 92 ; WX 606 ; N backslash ; B 81 0 512 726 ;
-C 93 ; WX 333 ; N bracketright ; B 45 -184 254 726 ;
-C 94 ; WX 606 ; N asciicircum ; B 51 283 554 689 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 278 ; N quoteleft ; B 45 446 233 709 ;
-C 97 ; WX 500 ; N a ; B 32 -12 471 469 ;
-C 98 ; WX 553 ; N b ; B -15 -12 508 726 ;
-C 99 ; WX 444 ; N c ; B 26 -20 413 469 ;
-C 100 ; WX 611 ; N d ; B 35 -12 579 726 ;
-C 101 ; WX 479 ; N e ; B 26 -20 448 469 ;
-C 102 ; WX 333 ; N f ; B 23 -3 341 728 ; L i fi ; L l fl ;
-C 103 ; WX 556 ; N g ; B 32 -283 544 469 ;
-C 104 ; WX 582 ; N h ; B 6 -3 572 726 ;
-C 105 ; WX 291 ; N i ; B 21 -3 271 687 ;
-C 106 ; WX 234 ; N j ; B -40 -283 167 688 ;
-C 107 ; WX 556 ; N k ; B 21 -12 549 726 ;
-C 108 ; WX 291 ; N l ; B 21 -3 271 726 ;
-C 109 ; WX 883 ; N m ; B 16 -3 869 469 ;
-C 110 ; WX 582 ; N n ; B 6 -3 572 469 ;
-C 111 ; WX 546 ; N o ; B 32 -20 514 469 ;
-C 112 ; WX 601 ; N p ; B 8 -281 554 469 ;
-C 113 ; WX 560 ; N q ; B 35 -281 560 469 ;
-C 114 ; WX 395 ; N r ; B 21 -3 374 469 ;
-C 115 ; WX 424 ; N s ; B 30 -20 391 469 ;
-C 116 ; WX 326 ; N t ; B 22 -12 319 621 ;
-C 117 ; WX 603 ; N u ; B 18 -12 581 469 ;
-C 118 ; WX 565 ; N v ; B 6 -7 539 459 ;
-C 119 ; WX 834 ; N w ; B 6 -7 808 469 ;
-C 120 ; WX 516 ; N x ; B 20 -3 496 469 ;
-C 121 ; WX 556 ; N y ; B 12 -283 544 459 ;
-C 122 ; WX 500 ; N z ; B 16 -3 466 462 ;
-C 123 ; WX 333 ; N braceleft ; B 58 -175 289 726 ;
-C 124 ; WX 606 ; N bar ; B 275 0 331 726 ;
-C 125 ; WX 333 ; N braceright ; B 44 -175 275 726 ;
-C 126 ; WX 606 ; N asciitilde ; B 51 176 555 347 ;
-C 161 ; WX 278 ; N exclamdown ; B 81 -225 197 469 ;
-C 162 ; WX 500 ; N cent ; B 61 -101 448 562 ;
-C 163 ; WX 500 ; N sterling ; B 12 -13 478 694 ;
-C 164 ; WX 167 ; N fraction ; B -166 0 337 689 ;
-C 165 ; WX 500 ; N yen ; B 5 -3 496 701 ;
-C 166 ; WX 500 ; N florin ; B 0 -262 473 706 ;
-C 167 ; WX 500 ; N section ; B 26 -219 465 709 ;
-C 168 ; WX 500 ; N currency ; B 30 96 470 531 ;
-C 169 ; WX 208 ; N quotesingle ; B 61 469 147 709 ;
-C 170 ; WX 500 ; N quotedblleft ; B 51 446 449 709 ;
-C 171 ; WX 500 ; N guillemotleft ; B 50 71 450 428 ;
-C 172 ; WX 331 ; N guilsinglleft ; B 66 71 265 428 ;
-C 173 ; WX 331 ; N guilsinglright ; B 66 71 265 428 ;
-C 174 ; WX 605 ; N fi ; B 23 -3 587 728 ;
-C 175 ; WX 608 ; N fl ; B 23 -3 590 728 ;
-C 177 ; WX 500 ; N endash ; B 0 219 500 277 ;
-C 178 ; WX 500 ; N dagger ; B 34 -5 466 694 ;
-C 179 ; WX 500 ; N daggerdbl ; B 34 -249 466 694 ;
-C 180 ; WX 250 ; N periodcentered ; B 67 203 183 319 ;
-C 182 ; WX 628 ; N paragraph ; B 39 -150 589 694 ;
-C 183 ; WX 606 ; N bullet ; B 131 172 475 516 ;
-C 184 ; WX 278 ; N quotesinglbase ; B 22 -153 210 110 ;
-C 185 ; WX 500 ; N quotedblbase ; B 51 -153 449 110 ;
-C 186 ; WX 500 ; N quotedblright ; B 51 446 449 709 ;
-C 187 ; WX 500 ; N guillemotright ; B 50 71 450 428 ;
-C 188 ; WX 1000 ; N ellipsis ; B 109 -5 891 111 ;
-C 189 ; WX 1144 ; N perthousand ; B 123 -20 1021 709 ;
-C 191 ; WX 444 ; N questiondown ; B 43 -231 395 469 ;
-C 193 ; WX 333 ; N grave ; B 31 506 255 677 ;
-C 194 ; WX 333 ; N acute ; B 78 506 302 677 ;
-C 195 ; WX 333 ; N circumflex ; B 11 510 323 677 ;
-C 196 ; WX 333 ; N tilde ; B 2 535 332 640 ;
-C 197 ; WX 333 ; N macron ; B 11 538 323 591 ;
-C 198 ; WX 333 ; N breve ; B 26 506 308 664 ;
-C 199 ; WX 250 ; N dotaccent ; B 75 537 175 637 ;
-C 200 ; WX 333 ; N dieresis ; B 17 537 316 637 ;
-C 202 ; WX 333 ; N ring ; B 67 496 267 696 ;
-C 203 ; WX 333 ; N cedilla ; B 96 -225 304 -10 ;
-C 205 ; WX 380 ; N hungarumlaut ; B 3 506 377 687 ;
-C 206 ; WX 313 ; N ogonek ; B 68 -165 245 -20 ;
-C 207 ; WX 333 ; N caron ; B 11 510 323 677 ;
-C 208 ; WX 1000 ; N emdash ; B 0 219 1000 277 ;
-C 225 ; WX 944 ; N AE ; B -10 -3 908 692 ;
-C 227 ; WX 333 ; N ordfeminine ; B 24 422 310 709 ;
-C 232 ; WX 611 ; N Lslash ; B 6 -3 586 692 ;
-C 233 ; WX 833 ; N Oslash ; B 30 -20 797 709 ;
-C 234 ; WX 998 ; N OE ; B 22 -20 962 709 ;
-C 235 ; WX 333 ; N ordmasculine ; B 10 416 323 709 ;
-C 241 ; WX 758 ; N ae ; B 30 -20 732 469 ;
-C 245 ; WX 287 ; N dotlessi ; B 21 -3 271 469 ;
-C 248 ; WX 291 ; N lslash ; B -14 -3 306 726 ;
-C 249 ; WX 556 ; N oslash ; B 16 -23 530 474 ;
-C 250 ; WX 827 ; N oe ; B 32 -20 800 469 ;
-C 251 ; WX 556 ; N germandbls ; B 23 -9 519 731 ;
-C -1 ; WX 667 ; N Zcaron ; B 15 -3 638 908 ;
-C -1 ; WX 444 ; N ccedilla ; B 26 -225 413 469 ;
-C -1 ; WX 556 ; N ydieresis ; B 12 -283 544 657 ;
-C -1 ; WX 500 ; N atilde ; B 32 -12 471 652 ;
-C -1 ; WX 287 ; N icircumflex ; B -12 -3 300 697 ;
-C -1 ; WX 300 ; N threesuperior ; B 1 266 299 689 ;
-C -1 ; WX 479 ; N ecircumflex ; B 26 -20 448 697 ;
-C -1 ; WX 601 ; N thorn ; B -2 -281 544 726 ;
-C -1 ; WX 479 ; N egrave ; B 26 -20 448 697 ;
-C -1 ; WX 300 ; N twosuperior ; B 0 273 301 689 ;
-C -1 ; WX 479 ; N eacute ; B 26 -20 448 697 ;
-C -1 ; WX 546 ; N otilde ; B 32 -20 514 652 ;
-C -1 ; WX 778 ; N Aacute ; B 15 -3 756 908 ;
-C -1 ; WX 546 ; N ocircumflex ; B 32 -20 514 697 ;
-C -1 ; WX 556 ; N yacute ; B 12 -283 544 697 ;
-C -1 ; WX 603 ; N udieresis ; B 18 -12 581 657 ;
-C -1 ; WX 750 ; N threequarters ; B 15 -3 735 689 ;
-C -1 ; WX 500 ; N acircumflex ; B 32 -12 471 697 ;
-C -1 ; WX 774 ; N Eth ; B 14 -3 751 692 ;
-C -1 ; WX 479 ; N edieresis ; B 26 -20 448 657 ;
-C -1 ; WX 603 ; N ugrave ; B 18 -12 581 697 ;
-C -1 ; WX 979 ; N trademark ; B 40 285 939 689 ;
-C -1 ; WX 546 ; N ograve ; B 32 -20 514 697 ;
-C -1 ; WX 424 ; N scaron ; B 30 -20 391 685 ;
-C -1 ; WX 337 ; N Idieresis ; B 19 -3 318 868 ;
-C -1 ; WX 603 ; N uacute ; B 18 -12 581 697 ;
-C -1 ; WX 500 ; N agrave ; B 32 -12 471 697 ;
-C -1 ; WX 582 ; N ntilde ; B 6 -3 572 652 ;
-C -1 ; WX 500 ; N aring ; B 32 -12 471 716 ;
-C -1 ; WX 500 ; N zcaron ; B 16 -3 466 685 ;
-C -1 ; WX 337 ; N Icircumflex ; B 13 -3 325 908 ;
-C -1 ; WX 831 ; N Ntilde ; B 17 -20 813 871 ;
-C -1 ; WX 603 ; N ucircumflex ; B 18 -12 581 697 ;
-C -1 ; WX 611 ; N Ecircumflex ; B 22 -3 572 908 ;
-C -1 ; WX 337 ; N Iacute ; B 22 -3 315 908 ;
-C -1 ; WX 709 ; N Ccedilla ; B 22 -225 670 709 ;
-C -1 ; WX 786 ; N Odieresis ; B 22 -20 764 868 ;
-C -1 ; WX 525 ; N Scaron ; B 24 -20 503 908 ;
-C -1 ; WX 611 ; N Edieresis ; B 22 -3 572 868 ;
-C -1 ; WX 337 ; N Igrave ; B 22 -3 315 908 ;
-C -1 ; WX 500 ; N adieresis ; B 32 -12 471 657 ;
-C -1 ; WX 786 ; N Ograve ; B 22 -20 764 908 ;
-C -1 ; WX 611 ; N Egrave ; B 22 -3 572 908 ;
-C -1 ; WX 667 ; N Ydieresis ; B 9 -3 654 868 ;
-C -1 ; WX 747 ; N registered ; B 11 -18 736 706 ;
-C -1 ; WX 786 ; N Otilde ; B 22 -20 764 883 ;
-C -1 ; WX 750 ; N onequarter ; B 30 -3 727 692 ;
-C -1 ; WX 778 ; N Ugrave ; B 12 -20 759 908 ;
-C -1 ; WX 778 ; N Ucircumflex ; B 12 -20 759 908 ;
-C -1 ; WX 604 ; N Thorn ; B 32 -3 574 692 ;
-C -1 ; WX 606 ; N divide ; B 51 10 555 512 ;
-C -1 ; WX 778 ; N Atilde ; B 15 -3 756 871 ;
-C -1 ; WX 778 ; N Uacute ; B 12 -20 759 908 ;
-C -1 ; WX 786 ; N Ocircumflex ; B 22 -20 764 908 ;
-C -1 ; WX 606 ; N logicalnot ; B 51 120 551 386 ;
-C -1 ; WX 778 ; N Aring ; B 15 -3 756 927 ;
-C -1 ; WX 287 ; N idieresis ; B -6 -3 293 657 ;
-C -1 ; WX 287 ; N iacute ; B 21 -3 279 697 ;
-C -1 ; WX 500 ; N aacute ; B 32 -12 471 697 ;
-C -1 ; WX 606 ; N plusminus ; B 51 0 555 512 ;
-C -1 ; WX 606 ; N multiply ; B 83 36 523 474 ;
-C -1 ; WX 778 ; N Udieresis ; B 12 -20 759 868 ;
-C -1 ; WX 606 ; N minus ; B 51 233 555 289 ;
-C -1 ; WX 300 ; N onesuperior ; B 31 273 269 692 ;
-C -1 ; WX 611 ; N Eacute ; B 22 -3 572 908 ;
-C -1 ; WX 778 ; N Acircumflex ; B 15 -3 756 908 ;
-C -1 ; WX 747 ; N copyright ; B 11 -18 736 706 ;
-C -1 ; WX 778 ; N Agrave ; B 15 -3 756 908 ;
-C -1 ; WX 546 ; N odieresis ; B 32 -20 514 657 ;
-C -1 ; WX 546 ; N oacute ; B 32 -20 514 697 ;
-C -1 ; WX 400 ; N degree ; B 50 389 350 689 ;
-C -1 ; WX 287 ; N igrave ; B 8 -3 271 697 ;
-C -1 ; WX 603 ; N mu ; B 18 -236 581 469 ;
-C -1 ; WX 786 ; N Oacute ; B 22 -20 764 908 ;
-C -1 ; WX 546 ; N eth ; B 32 -20 504 728 ;
-C -1 ; WX 778 ; N Adieresis ; B 15 -3 756 868 ;
-C -1 ; WX 667 ; N Yacute ; B 9 -3 654 908 ;
-C -1 ; WX 606 ; N brokenbar ; B 275 0 331 726 ;
-C -1 ; WX 750 ; N onehalf ; B 15 -3 735 692 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 111
-
-KPX A y -74
-KPX A w -74
-KPX A v -92
-KPX A space -55
-KPX A quoteright -74
-KPX A Y -111
-KPX A W -74
-KPX A V -111
-KPX A T -74
-
-KPX F period -92
-KPX F comma -92
-KPX F A -74
-
-KPX L y -55
-KPX L space -37
-KPX L quoteright -74
-KPX L Y -92
-KPX L W -74
-KPX L V -92
-KPX L T -74
-
-KPX P space -18
-KPX P period -129
-KPX P comma -129
-KPX P A -92
-
-KPX R y -37
-KPX R Y -37
-KPX R W -37
-KPX R V -55
-KPX R T -37
-
-KPX T y -90
-KPX T w -90
-KPX T u -90
-KPX T semicolon -55
-KPX T s -90
-KPX T r -90
-KPX T period -74
-KPX T o -92
-KPX T i -55
-KPX T hyphen -55
-KPX T e -92
-KPX T comma -74
-KPX T colon -55
-KPX T c -111
-KPX T a -92
-KPX T O -18
-KPX T A -74
-
-KPX V y -92
-KPX V u -92
-KPX V semicolon -55
-KPX V r -92
-KPX V period -129
-KPX V o -111
-KPX V i -55
-KPX V hyphen -74
-KPX V e -111
-KPX V comma -129
-KPX V colon -55
-KPX V a -92
-KPX V A -111
-
-KPX W y -50
-KPX W u -50
-KPX W semicolon -18
-KPX W r -74
-KPX W period -92
-KPX W o -92
-KPX W i -55
-KPX W hyphen -55
-KPX W e -92
-KPX W comma -92
-KPX W colon -18
-KPX W a -92
-KPX W A -92
-
-KPX Y v -90
-KPX Y u -90
-KPX Y space -18
-KPX Y semicolon -74
-KPX Y q -90
-KPX Y period -111
-KPX Y p -111
-KPX Y o -92
-KPX Y i -55
-KPX Y hyphen -92
-KPX Y e -92
-KPX Y comma -111
-KPX Y colon -74
-KPX Y a -92
-KPX Y A -92
-
-KPX f quoteright 55
-KPX f f -18
-
-KPX one one -55
-
-KPX quoteleft quoteleft -37
-
-KPX quoteright quoteright -37
-
-KPX r u -8
-KPX r quoteright 74
-KPX r q -18
-KPX r period -74
-KPX r o -18
-KPX r hyphen -18
-KPX r h -18
-KPX r g -18
-KPX r e -18
-KPX r d -18
-KPX r comma -74
-KPX r c -18
-
-KPX space Y -18
-KPX space A -37
-
-KPX v period -111
-KPX v comma -111
-
-KPX w period -92
-KPX w comma -92
-
-KPX y period -111
-KPX y comma -111
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 229 231 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 223 231 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 223 231 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 215 231 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 223 231 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 223 231 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 188 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 231 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 231 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 231 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 231 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 2 231 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 2 231 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 2 231 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 2 231 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 249 231 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 227 231 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 227 231 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 227 231 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 227 231 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 227 243 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 96 231 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 255 231 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 247 231 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 223 231 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 223 231 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 203 231 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 191 231 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 179 231 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 84 20 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 72 20 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 72 20 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 60 20 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 72 20 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 72 12 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 97 20 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 85 20 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 73 20 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 73 20 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -23 20 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -23 20 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -23 20 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -23 20 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 113 12 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 107 20 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 107 20 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 107 20 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 95 20 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 107 12 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 46 8 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 159 20 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 135 20 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 135 20 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 111 20 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 144 20 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 112 20 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 84 8 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pplri8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pplri8a.afm
deleted file mode 100644
index 01bdcf0568..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pplri8a.afm
+++ /dev/null
@@ -1,439 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Mon Jul 2 22:37:33 1990
-Comment UniqueID 31796
-Comment VMusage 37415 48307
-FontName Palatino-Italic
-FullName Palatino Italic
-FamilyName Palatino
-Weight Medium
-ItalicAngle -10
-IsFixedPitch false
-FontBBox -170 -276 1010 918
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.005
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Palatino is a trademark of Linotype AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 692
-XHeight 482
-Ascender 733
-Descender -276
-StartCharMetrics 228
-C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 76 -8 292 733 ;
-C 34 ; WX 500 ; N quotedbl ; B 140 508 455 733 ;
-C 35 ; WX 500 ; N numbersign ; B 4 0 495 692 ;
-C 36 ; WX 500 ; N dollar ; B 15 -113 452 733 ;
-C 37 ; WX 889 ; N percent ; B 74 -7 809 710 ;
-C 38 ; WX 778 ; N ampersand ; B 47 -18 766 692 ;
-C 39 ; WX 278 ; N quoteright ; B 78 488 258 733 ;
-C 40 ; WX 333 ; N parenleft ; B 54 -106 331 733 ;
-C 41 ; WX 333 ; N parenright ; B 2 -106 279 733 ;
-C 42 ; WX 389 ; N asterisk ; B 76 368 400 706 ;
-C 43 ; WX 606 ; N plus ; B 51 0 555 504 ;
-C 44 ; WX 250 ; N comma ; B 8 -143 203 123 ;
-C 45 ; WX 333 ; N hyphen ; B 19 223 304 281 ;
-C 46 ; WX 250 ; N period ; B 53 -5 158 112 ;
-C 47 ; WX 296 ; N slash ; B -40 -119 392 733 ;
-C 48 ; WX 500 ; N zero ; B 36 -11 480 699 ;
-C 49 ; WX 500 ; N one ; B 54 -3 398 699 ;
-C 50 ; WX 500 ; N two ; B 12 -3 437 699 ;
-C 51 ; WX 500 ; N three ; B 22 -11 447 699 ;
-C 52 ; WX 500 ; N four ; B 15 -3 478 699 ;
-C 53 ; WX 500 ; N five ; B 14 -11 491 693 ;
-C 54 ; WX 500 ; N six ; B 49 -11 469 699 ;
-C 55 ; WX 500 ; N seven ; B 53 -3 502 692 ;
-C 56 ; WX 500 ; N eight ; B 36 -11 469 699 ;
-C 57 ; WX 500 ; N nine ; B 32 -11 468 699 ;
-C 58 ; WX 250 ; N colon ; B 44 -5 207 458 ;
-C 59 ; WX 250 ; N semicolon ; B -9 -146 219 456 ;
-C 60 ; WX 606 ; N less ; B 53 -6 554 516 ;
-C 61 ; WX 606 ; N equal ; B 51 126 555 378 ;
-C 62 ; WX 606 ; N greater ; B 53 -6 554 516 ;
-C 63 ; WX 500 ; N question ; B 114 -8 427 706 ;
-C 64 ; WX 747 ; N at ; B 27 -18 718 706 ;
-C 65 ; WX 722 ; N A ; B -19 -3 677 705 ;
-C 66 ; WX 611 ; N B ; B 26 -6 559 692 ;
-C 67 ; WX 667 ; N C ; B 45 -18 651 706 ;
-C 68 ; WX 778 ; N D ; B 28 -3 741 692 ;
-C 69 ; WX 611 ; N E ; B 30 -3 570 692 ;
-C 70 ; WX 556 ; N F ; B 0 -3 548 692 ;
-C 71 ; WX 722 ; N G ; B 50 -18 694 706 ;
-C 72 ; WX 778 ; N H ; B -3 -3 800 692 ;
-C 73 ; WX 333 ; N I ; B 7 -3 354 692 ;
-C 74 ; WX 333 ; N J ; B -35 -206 358 692 ;
-C 75 ; WX 667 ; N K ; B 13 -3 683 692 ;
-C 76 ; WX 556 ; N L ; B 16 -3 523 692 ;
-C 77 ; WX 944 ; N M ; B -19 -18 940 692 ;
-C 78 ; WX 778 ; N N ; B 2 -11 804 692 ;
-C 79 ; WX 778 ; N O ; B 53 -18 748 706 ;
-C 80 ; WX 611 ; N P ; B 9 -3 594 692 ;
-C 81 ; WX 778 ; N Q ; B 53 -201 748 706 ;
-C 82 ; WX 667 ; N R ; B 9 -3 639 692 ;
-C 83 ; WX 556 ; N S ; B 42 -18 506 706 ;
-C 84 ; WX 611 ; N T ; B 53 -3 635 692 ;
-C 85 ; WX 778 ; N U ; B 88 -18 798 692 ;
-C 86 ; WX 722 ; N V ; B 75 -8 754 692 ;
-C 87 ; WX 944 ; N W ; B 71 -8 980 700 ;
-C 88 ; WX 722 ; N X ; B 20 -3 734 692 ;
-C 89 ; WX 667 ; N Y ; B 52 -3 675 705 ;
-C 90 ; WX 667 ; N Z ; B 20 -3 637 692 ;
-C 91 ; WX 333 ; N bracketleft ; B 18 -100 326 733 ;
-C 92 ; WX 606 ; N backslash ; B 81 0 513 733 ;
-C 93 ; WX 333 ; N bracketright ; B 7 -100 315 733 ;
-C 94 ; WX 606 ; N asciicircum ; B 51 283 554 689 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 278 ; N quoteleft ; B 78 488 258 733 ;
-C 97 ; WX 444 ; N a ; B 4 -11 406 482 ;
-C 98 ; WX 463 ; N b ; B 37 -11 433 733 ;
-C 99 ; WX 407 ; N c ; B 25 -11 389 482 ;
-C 100 ; WX 500 ; N d ; B 17 -11 483 733 ;
-C 101 ; WX 389 ; N e ; B 15 -11 374 482 ;
-C 102 ; WX 278 ; N f ; B -162 -276 413 733 ; L i fi ; L l fl ;
-C 103 ; WX 500 ; N g ; B -37 -276 498 482 ;
-C 104 ; WX 500 ; N h ; B 10 -9 471 733 ;
-C 105 ; WX 278 ; N i ; B 34 -9 264 712 ;
-C 106 ; WX 278 ; N j ; B -70 -276 265 712 ;
-C 107 ; WX 444 ; N k ; B 8 -9 449 733 ;
-C 108 ; WX 278 ; N l ; B 36 -9 251 733 ;
-C 109 ; WX 778 ; N m ; B 24 -9 740 482 ;
-C 110 ; WX 556 ; N n ; B 24 -9 514 482 ;
-C 111 ; WX 444 ; N o ; B 17 -11 411 482 ;
-C 112 ; WX 500 ; N p ; B -7 -276 465 482 ;
-C 113 ; WX 463 ; N q ; B 24 -276 432 482 ;
-C 114 ; WX 389 ; N r ; B 26 -9 384 482 ;
-C 115 ; WX 389 ; N s ; B 9 -11 345 482 ;
-C 116 ; WX 333 ; N t ; B 41 -9 310 646 ;
-C 117 ; WX 556 ; N u ; B 32 -11 512 482 ;
-C 118 ; WX 500 ; N v ; B 21 -11 477 482 ;
-C 119 ; WX 722 ; N w ; B 21 -11 699 482 ;
-C 120 ; WX 500 ; N x ; B 9 -11 484 482 ;
-C 121 ; WX 500 ; N y ; B -8 -276 490 482 ;
-C 122 ; WX 444 ; N z ; B -1 -11 416 482 ;
-C 123 ; WX 333 ; N braceleft ; B 15 -100 319 733 ;
-C 124 ; WX 606 ; N bar ; B 275 0 331 733 ;
-C 125 ; WX 333 ; N braceright ; B 14 -100 318 733 ;
-C 126 ; WX 606 ; N asciitilde ; B 51 168 555 339 ;
-C 161 ; WX 333 ; N exclamdown ; B 15 -276 233 467 ;
-C 162 ; WX 500 ; N cent ; B 56 -96 418 551 ;
-C 163 ; WX 500 ; N sterling ; B 2 -18 479 708 ;
-C 164 ; WX 167 ; N fraction ; B -170 0 337 699 ;
-C 165 ; WX 500 ; N yen ; B 35 -3 512 699 ;
-C 166 ; WX 500 ; N florin ; B 5 -276 470 708 ;
-C 167 ; WX 500 ; N section ; B 14 -220 463 706 ;
-C 168 ; WX 500 ; N currency ; B 14 115 486 577 ;
-C 169 ; WX 333 ; N quotesingle ; B 140 508 288 733 ;
-C 170 ; WX 500 ; N quotedblleft ; B 98 488 475 733 ;
-C 171 ; WX 500 ; N guillemotleft ; B 57 70 437 440 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 57 70 270 440 ;
-C 173 ; WX 333 ; N guilsinglright ; B 63 70 276 440 ;
-C 174 ; WX 528 ; N fi ; B -162 -276 502 733 ;
-C 175 ; WX 545 ; N fl ; B -162 -276 520 733 ;
-C 177 ; WX 500 ; N endash ; B -10 228 510 278 ;
-C 178 ; WX 500 ; N dagger ; B 48 0 469 692 ;
-C 179 ; WX 500 ; N daggerdbl ; B 10 -162 494 692 ;
-C 180 ; WX 250 ; N periodcentered ; B 53 195 158 312 ;
-C 182 ; WX 500 ; N paragraph ; B 33 -224 611 692 ;
-C 183 ; WX 500 ; N bullet ; B 86 182 430 526 ;
-C 184 ; WX 278 ; N quotesinglbase ; B 27 -122 211 120 ;
-C 185 ; WX 500 ; N quotedblbase ; B 43 -122 424 120 ;
-C 186 ; WX 500 ; N quotedblright ; B 98 488 475 733 ;
-C 187 ; WX 500 ; N guillemotright ; B 63 70 443 440 ;
-C 188 ; WX 1000 ; N ellipsis ; B 102 -5 873 112 ;
-C 189 ; WX 1000 ; N perthousand ; B 72 -6 929 717 ;
-C 191 ; WX 500 ; N questiondown ; B 57 -246 370 467 ;
-C 193 ; WX 333 ; N grave ; B 86 518 310 687 ;
-C 194 ; WX 333 ; N acute ; B 122 518 346 687 ;
-C 195 ; WX 333 ; N circumflex ; B 56 510 350 679 ;
-C 196 ; WX 333 ; N tilde ; B 63 535 390 638 ;
-C 197 ; WX 333 ; N macron ; B 74 538 386 589 ;
-C 198 ; WX 333 ; N breve ; B 92 518 393 677 ;
-C 199 ; WX 333 ; N dotaccent ; B 175 537 283 645 ;
-C 200 ; WX 333 ; N dieresis ; B 78 537 378 637 ;
-C 202 ; WX 333 ; N ring ; B 159 508 359 708 ;
-C 203 ; WX 333 ; N cedilla ; B -9 -216 202 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 46 518 385 730 ;
-C 206 ; WX 333 ; N ogonek ; B 38 -207 196 -18 ;
-C 207 ; WX 333 ; N caron ; B 104 510 409 679 ;
-C 208 ; WX 1000 ; N emdash ; B -10 228 1010 278 ;
-C 225 ; WX 941 ; N AE ; B -4 -3 902 692 ;
-C 227 ; WX 333 ; N ordfeminine ; B 60 404 321 699 ;
-C 232 ; WX 556 ; N Lslash ; B -16 -3 523 692 ;
-C 233 ; WX 778 ; N Oslash ; B 32 -39 762 721 ;
-C 234 ; WX 1028 ; N OE ; B 56 -18 989 706 ;
-C 235 ; WX 333 ; N ordmasculine ; B 66 404 322 699 ;
-C 241 ; WX 638 ; N ae ; B 1 -11 623 482 ;
-C 245 ; WX 278 ; N dotlessi ; B 34 -9 241 482 ;
-C 248 ; WX 278 ; N lslash ; B -10 -9 302 733 ;
-C 249 ; WX 444 ; N oslash ; B -18 -24 460 510 ;
-C 250 ; WX 669 ; N oe ; B 17 -11 654 482 ;
-C 251 ; WX 500 ; N germandbls ; B -160 -276 488 733 ;
-C -1 ; WX 667 ; N Zcaron ; B 20 -3 637 907 ;
-C -1 ; WX 407 ; N ccedilla ; B 25 -216 389 482 ;
-C -1 ; WX 500 ; N ydieresis ; B -8 -276 490 657 ;
-C -1 ; WX 444 ; N atilde ; B 4 -11 446 650 ;
-C -1 ; WX 278 ; N icircumflex ; B 29 -9 323 699 ;
-C -1 ; WX 300 ; N threesuperior ; B 28 273 304 699 ;
-C -1 ; WX 389 ; N ecircumflex ; B 15 -11 398 699 ;
-C -1 ; WX 500 ; N thorn ; B -39 -276 433 733 ;
-C -1 ; WX 389 ; N egrave ; B 15 -11 374 707 ;
-C -1 ; WX 300 ; N twosuperior ; B 13 278 290 699 ;
-C -1 ; WX 389 ; N eacute ; B 15 -11 394 707 ;
-C -1 ; WX 444 ; N otilde ; B 17 -11 446 650 ;
-C -1 ; WX 722 ; N Aacute ; B -19 -3 677 897 ;
-C -1 ; WX 444 ; N ocircumflex ; B 17 -11 411 699 ;
-C -1 ; WX 500 ; N yacute ; B -8 -276 490 707 ;
-C -1 ; WX 556 ; N udieresis ; B 32 -11 512 657 ;
-C -1 ; WX 750 ; N threequarters ; B 35 -2 715 699 ;
-C -1 ; WX 444 ; N acircumflex ; B 4 -11 406 699 ;
-C -1 ; WX 778 ; N Eth ; B 19 -3 741 692 ;
-C -1 ; WX 389 ; N edieresis ; B 15 -11 406 657 ;
-C -1 ; WX 556 ; N ugrave ; B 32 -11 512 707 ;
-C -1 ; WX 1000 ; N trademark ; B 52 285 951 689 ;
-C -1 ; WX 444 ; N ograve ; B 17 -11 411 707 ;
-C -1 ; WX 389 ; N scaron ; B 9 -11 419 687 ;
-C -1 ; WX 333 ; N Idieresis ; B 7 -3 418 847 ;
-C -1 ; WX 556 ; N uacute ; B 32 -11 512 707 ;
-C -1 ; WX 444 ; N agrave ; B 4 -11 406 707 ;
-C -1 ; WX 556 ; N ntilde ; B 24 -9 514 650 ;
-C -1 ; WX 444 ; N aring ; B 4 -11 406 728 ;
-C -1 ; WX 444 ; N zcaron ; B -1 -11 447 687 ;
-C -1 ; WX 333 ; N Icircumflex ; B 7 -3 390 889 ;
-C -1 ; WX 778 ; N Ntilde ; B 2 -11 804 866 ;
-C -1 ; WX 556 ; N ucircumflex ; B 32 -11 512 699 ;
-C -1 ; WX 611 ; N Ecircumflex ; B 30 -3 570 889 ;
-C -1 ; WX 333 ; N Iacute ; B 7 -3 406 897 ;
-C -1 ; WX 667 ; N Ccedilla ; B 45 -216 651 706 ;
-C -1 ; WX 778 ; N Odieresis ; B 53 -18 748 847 ;
-C -1 ; WX 556 ; N Scaron ; B 42 -18 539 907 ;
-C -1 ; WX 611 ; N Edieresis ; B 30 -3 570 847 ;
-C -1 ; WX 333 ; N Igrave ; B 7 -3 354 897 ;
-C -1 ; WX 444 ; N adieresis ; B 4 -11 434 657 ;
-C -1 ; WX 778 ; N Ograve ; B 53 -18 748 897 ;
-C -1 ; WX 611 ; N Egrave ; B 30 -3 570 897 ;
-C -1 ; WX 667 ; N Ydieresis ; B 52 -3 675 847 ;
-C -1 ; WX 747 ; N registered ; B 11 -18 736 706 ;
-C -1 ; WX 778 ; N Otilde ; B 53 -18 748 866 ;
-C -1 ; WX 750 ; N onequarter ; B 31 -2 715 699 ;
-C -1 ; WX 778 ; N Ugrave ; B 88 -18 798 897 ;
-C -1 ; WX 778 ; N Ucircumflex ; B 88 -18 798 889 ;
-C -1 ; WX 611 ; N Thorn ; B 9 -3 570 692 ;
-C -1 ; WX 606 ; N divide ; B 51 0 555 504 ;
-C -1 ; WX 722 ; N Atilde ; B -19 -3 677 866 ;
-C -1 ; WX 778 ; N Uacute ; B 88 -18 798 897 ;
-C -1 ; WX 778 ; N Ocircumflex ; B 53 -18 748 889 ;
-C -1 ; WX 606 ; N logicalnot ; B 51 118 555 378 ;
-C -1 ; WX 722 ; N Aring ; B -19 -3 677 918 ;
-C -1 ; WX 278 ; N idieresis ; B 34 -9 351 657 ;
-C -1 ; WX 278 ; N iacute ; B 34 -9 331 707 ;
-C -1 ; WX 444 ; N aacute ; B 4 -11 414 707 ;
-C -1 ; WX 606 ; N plusminus ; B 51 0 555 504 ;
-C -1 ; WX 606 ; N multiply ; B 83 36 523 474 ;
-C -1 ; WX 778 ; N Udieresis ; B 88 -18 798 847 ;
-C -1 ; WX 606 ; N minus ; B 51 224 555 280 ;
-C -1 ; WX 300 ; N onesuperior ; B 61 278 285 699 ;
-C -1 ; WX 611 ; N Eacute ; B 30 -3 570 897 ;
-C -1 ; WX 722 ; N Acircumflex ; B -19 -3 677 889 ;
-C -1 ; WX 747 ; N copyright ; B 11 -18 736 706 ;
-C -1 ; WX 722 ; N Agrave ; B -19 -3 677 897 ;
-C -1 ; WX 444 ; N odieresis ; B 17 -11 434 657 ;
-C -1 ; WX 444 ; N oacute ; B 17 -11 414 707 ;
-C -1 ; WX 400 ; N degree ; B 90 389 390 689 ;
-C -1 ; WX 278 ; N igrave ; B 34 -9 271 707 ;
-C -1 ; WX 556 ; N mu ; B 15 -226 512 482 ;
-C -1 ; WX 778 ; N Oacute ; B 53 -18 748 897 ;
-C -1 ; WX 444 ; N eth ; B 17 -11 478 733 ;
-C -1 ; WX 722 ; N Adieresis ; B -19 -3 677 847 ;
-C -1 ; WX 667 ; N Yacute ; B 52 -3 675 897 ;
-C -1 ; WX 606 ; N brokenbar ; B 275 0 331 733 ;
-C -1 ; WX 750 ; N onehalf ; B 31 -2 721 699 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 106
-
-KPX A y -55
-KPX A w -37
-KPX A v -37
-KPX A space -37
-KPX A quoteright -55
-KPX A Y -55
-KPX A W -55
-KPX A V -74
-KPX A T -55
-
-KPX F period -111
-KPX F comma -111
-KPX F A -111
-
-KPX L y -37
-KPX L space -18
-KPX L quoteright -37
-KPX L Y -74
-KPX L W -74
-KPX L V -74
-KPX L T -74
-
-KPX P period -129
-KPX P comma -129
-KPX P A -129
-
-KPX R y -37
-KPX R Y -55
-KPX R W -55
-KPX R V -74
-KPX R T -55
-
-KPX T y -92
-KPX T w -92
-KPX T u -111
-KPX T semicolon -74
-KPX T s -111
-KPX T r -111
-KPX T period -74
-KPX T o -111
-KPX T i -55
-KPX T hyphen -55
-KPX T e -111
-KPX T comma -74
-KPX T colon -74
-KPX T c -111
-KPX T a -111
-KPX T O -18
-KPX T A -92
-
-KPX V y -74
-KPX V u -74
-KPX V semicolon -37
-KPX V r -92
-KPX V period -129
-KPX V o -74
-KPX V i -74
-KPX V hyphen -55
-KPX V e -92
-KPX V comma -129
-KPX V colon -37
-KPX V a -74
-KPX V A -210
-
-KPX W y -20
-KPX W u -20
-KPX W semicolon -18
-KPX W r -20
-KPX W period -55
-KPX W o -20
-KPX W i -20
-KPX W hyphen -18
-KPX W e -20
-KPX W comma -55
-KPX W colon -18
-KPX W a -20
-KPX W A -92
-
-KPX Y v -74
-KPX Y u -92
-KPX Y semicolon -74
-KPX Y q -92
-KPX Y period -92
-KPX Y p -74
-KPX Y o -111
-KPX Y i -55
-KPX Y hyphen -74
-KPX Y e -111
-KPX Y comma -92
-KPX Y colon -74
-KPX Y a -92
-KPX Y A -92
-
-KPX f quoteright 55
-
-KPX one one -55
-
-KPX quoteleft quoteleft -74
-
-KPX quoteright t -37
-KPX quoteright space -55
-KPX quoteright s -55
-KPX quoteright quoteright -74
-
-KPX r quoteright 37
-KPX r q -18
-KPX r period -74
-KPX r o -18
-KPX r h -18
-KPX r g -18
-KPX r e -18
-KPX r comma -74
-KPX r c -18
-
-KPX v period -55
-KPX v comma -55
-
-KPX w period -55
-KPX w comma -55
-
-KPX y period -37
-KPX y comma -37
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 271 210 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 261 210 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 255 210 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 235 210 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 235 210 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 255 228 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 207 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 199 210 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 179 210 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 179 210 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 167 210 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 60 210 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 40 210 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 40 210 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 210 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 263 228 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 283 210 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 263 210 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 255 210 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 251 210 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 263 228 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 130 228 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 277 210 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 255 210 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 235 210 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 235 210 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 227 210 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 187 210 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 179 228 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 68 20 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 56 20 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 56 20 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 44 20 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 36 20 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 56 12 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 37 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 48 20 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 48 20 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 28 20 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 16 20 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -15 20 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 20 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 20 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -39 20 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 112 12 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 68 20 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 56 20 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 56 20 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 36 20 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 56 12 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 10 8 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 124 20 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 20 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 112 20 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 100 20 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 96 20 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 20 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 38 8 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/psyr.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/psyr.afm
deleted file mode 100644
index 1cdbdae695..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/psyr.afm
+++ /dev/null
@@ -1,209 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.
-Comment Creation Date: Wed Jan 17 21:48:26 1990
-Comment UniqueID 27004
-Comment VMusage 28489 37622
-FontName Symbol
-FullName Symbol
-FamilyName Symbol
-Weight Medium
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -180 -293 1090 1010
-UnderlinePosition -98
-UnderlineThickness 54
-Version 001.007
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All rights reserved.
-EncodingScheme FontSpecific
-StartCharMetrics 189
-C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 128 -17 240 672 ;
-C 34 ; WX 713 ; N universal ; B 31 0 681 705 ;
-C 35 ; WX 500 ; N numbersign ; B 20 -16 481 673 ;
-C 36 ; WX 549 ; N existential ; B 25 0 478 707 ;
-C 37 ; WX 833 ; N percent ; B 63 -36 771 655 ;
-C 38 ; WX 778 ; N ampersand ; B 41 -18 750 661 ;
-C 39 ; WX 439 ; N suchthat ; B 48 -17 414 500 ;
-C 40 ; WX 333 ; N parenleft ; B 53 -191 300 673 ;
-C 41 ; WX 333 ; N parenright ; B 30 -191 277 673 ;
-C 42 ; WX 500 ; N asteriskmath ; B 65 134 427 551 ;
-C 43 ; WX 549 ; N plus ; B 10 0 539 533 ;
-C 44 ; WX 250 ; N comma ; B 56 -152 194 104 ;
-C 45 ; WX 549 ; N minus ; B 11 233 535 288 ;
-C 46 ; WX 250 ; N period ; B 69 -17 181 95 ;
-C 47 ; WX 278 ; N slash ; B 0 -18 254 646 ;
-C 48 ; WX 500 ; N zero ; B 23 -17 471 685 ;
-C 49 ; WX 500 ; N one ; B 117 0 390 673 ;
-C 50 ; WX 500 ; N two ; B 25 0 475 686 ;
-C 51 ; WX 500 ; N three ; B 39 -17 435 685 ;
-C 52 ; WX 500 ; N four ; B 16 0 469 685 ;
-C 53 ; WX 500 ; N five ; B 29 -17 443 685 ;
-C 54 ; WX 500 ; N six ; B 36 -17 467 685 ;
-C 55 ; WX 500 ; N seven ; B 24 -16 448 673 ;
-C 56 ; WX 500 ; N eight ; B 54 -18 440 685 ;
-C 57 ; WX 500 ; N nine ; B 31 -18 460 685 ;
-C 58 ; WX 278 ; N colon ; B 81 -17 193 460 ;
-C 59 ; WX 278 ; N semicolon ; B 83 -152 221 460 ;
-C 60 ; WX 549 ; N less ; B 26 0 523 522 ;
-C 61 ; WX 549 ; N equal ; B 11 141 537 390 ;
-C 62 ; WX 549 ; N greater ; B 26 0 523 522 ;
-C 63 ; WX 444 ; N question ; B 70 -17 412 686 ;
-C 64 ; WX 549 ; N congruent ; B 11 0 537 475 ;
-C 65 ; WX 722 ; N Alpha ; B 4 0 684 673 ;
-C 66 ; WX 667 ; N Beta ; B 29 0 592 673 ;
-C 67 ; WX 722 ; N Chi ; B -9 0 704 673 ;
-C 68 ; WX 612 ; N Delta ; B 6 0 608 688 ;
-C 69 ; WX 611 ; N Epsilon ; B 32 0 617 673 ;
-C 70 ; WX 763 ; N Phi ; B 26 0 741 673 ;
-C 71 ; WX 603 ; N Gamma ; B 24 0 609 673 ;
-C 72 ; WX 722 ; N Eta ; B 39 0 729 673 ;
-C 73 ; WX 333 ; N Iota ; B 32 0 316 673 ;
-C 74 ; WX 631 ; N theta1 ; B 18 -18 623 689 ;
-C 75 ; WX 722 ; N Kappa ; B 35 0 722 673 ;
-C 76 ; WX 686 ; N Lambda ; B 6 0 680 688 ;
-C 77 ; WX 889 ; N Mu ; B 28 0 887 673 ;
-C 78 ; WX 722 ; N Nu ; B 29 -8 720 673 ;
-C 79 ; WX 722 ; N Omicron ; B 41 -17 715 685 ;
-C 80 ; WX 768 ; N Pi ; B 25 0 745 673 ;
-C 81 ; WX 741 ; N Theta ; B 41 -17 715 685 ;
-C 82 ; WX 556 ; N Rho ; B 28 0 563 673 ;
-C 83 ; WX 592 ; N Sigma ; B 5 0 589 673 ;
-C 84 ; WX 611 ; N Tau ; B 33 0 607 673 ;
-C 85 ; WX 690 ; N Upsilon ; B -8 0 694 673 ;
-C 86 ; WX 439 ; N sigma1 ; B 40 -233 436 500 ;
-C 87 ; WX 768 ; N Omega ; B 34 0 736 688 ;
-C 88 ; WX 645 ; N Xi ; B 40 0 599 673 ;
-C 89 ; WX 795 ; N Psi ; B 15 0 781 684 ;
-C 90 ; WX 611 ; N Zeta ; B 44 0 636 673 ;
-C 91 ; WX 333 ; N bracketleft ; B 86 -155 299 674 ;
-C 92 ; WX 863 ; N therefore ; B 163 0 701 478 ;
-C 93 ; WX 333 ; N bracketright ; B 33 -155 246 674 ;
-C 94 ; WX 658 ; N perpendicular ; B 15 0 652 674 ;
-C 95 ; WX 500 ; N underscore ; B -2 -252 502 -206 ;
-C 96 ; WX 500 ; N radicalex ; B 480 881 1090 917 ;
-C 97 ; WX 631 ; N alpha ; B 41 -18 622 500 ;
-C 98 ; WX 549 ; N beta ; B 61 -223 515 741 ;
-C 99 ; WX 549 ; N chi ; B 12 -231 522 499 ;
-C 100 ; WX 494 ; N delta ; B 40 -19 481 740 ;
-C 101 ; WX 439 ; N epsilon ; B 22 -19 427 502 ;
-C 102 ; WX 521 ; N phi ; B 27 -224 490 671 ;
-C 103 ; WX 411 ; N gamma ; B 5 -225 484 499 ;
-C 104 ; WX 603 ; N eta ; B 0 -202 527 514 ;
-C 105 ; WX 329 ; N iota ; B 0 -17 301 503 ;
-C 106 ; WX 603 ; N phi1 ; B 36 -224 587 499 ;
-C 107 ; WX 549 ; N kappa ; B 33 0 558 501 ;
-C 108 ; WX 549 ; N lambda ; B 24 -17 548 739 ;
-C 109 ; WX 576 ; N mu ; B 33 -223 567 500 ;
-C 110 ; WX 521 ; N nu ; B -9 -16 475 507 ;
-C 111 ; WX 549 ; N omicron ; B 35 -19 501 499 ;
-C 112 ; WX 549 ; N pi ; B 10 -19 530 487 ;
-C 113 ; WX 521 ; N theta ; B 43 -17 485 690 ;
-C 114 ; WX 549 ; N rho ; B 50 -230 490 499 ;
-C 115 ; WX 603 ; N sigma ; B 30 -21 588 500 ;
-C 116 ; WX 439 ; N tau ; B 10 -19 418 500 ;
-C 117 ; WX 576 ; N upsilon ; B 7 -18 535 507 ;
-C 118 ; WX 713 ; N omega1 ; B 12 -18 671 583 ;
-C 119 ; WX 686 ; N omega ; B 42 -17 684 500 ;
-C 120 ; WX 493 ; N xi ; B 27 -224 469 766 ;
-C 121 ; WX 686 ; N psi ; B 12 -228 701 500 ;
-C 122 ; WX 494 ; N zeta ; B 60 -225 467 756 ;
-C 123 ; WX 480 ; N braceleft ; B 58 -183 397 673 ;
-C 124 ; WX 200 ; N bar ; B 65 -177 135 673 ;
-C 125 ; WX 480 ; N braceright ; B 79 -183 418 673 ;
-C 126 ; WX 549 ; N similar ; B 17 203 529 307 ;
-C 161 ; WX 620 ; N Upsilon1 ; B -2 0 610 685 ;
-C 162 ; WX 247 ; N minute ; B 27 459 228 735 ;
-C 163 ; WX 549 ; N lessequal ; B 29 0 526 639 ;
-C 164 ; WX 167 ; N fraction ; B -180 -12 340 677 ;
-C 165 ; WX 713 ; N infinity ; B 26 124 688 404 ;
-C 166 ; WX 500 ; N florin ; B 2 -193 494 686 ;
-C 167 ; WX 753 ; N club ; B 86 -26 660 533 ;
-C 168 ; WX 753 ; N diamond ; B 142 -36 600 550 ;
-C 169 ; WX 753 ; N heart ; B 117 -33 631 532 ;
-C 170 ; WX 753 ; N spade ; B 113 -36 629 548 ;
-C 171 ; WX 1042 ; N arrowboth ; B 24 -15 1024 511 ;
-C 172 ; WX 987 ; N arrowleft ; B 32 -15 942 511 ;
-C 173 ; WX 603 ; N arrowup ; B 45 0 571 910 ;
-C 174 ; WX 987 ; N arrowright ; B 49 -15 959 511 ;
-C 175 ; WX 603 ; N arrowdown ; B 45 -22 571 888 ;
-C 176 ; WX 400 ; N degree ; B 50 385 350 685 ;
-C 177 ; WX 549 ; N plusminus ; B 10 0 539 645 ;
-C 178 ; WX 411 ; N second ; B 20 459 413 737 ;
-C 179 ; WX 549 ; N greaterequal ; B 29 0 526 639 ;
-C 180 ; WX 549 ; N multiply ; B 17 8 533 524 ;
-C 181 ; WX 713 ; N proportional ; B 27 123 639 404 ;
-C 182 ; WX 494 ; N partialdiff ; B 26 -20 462 746 ;
-C 183 ; WX 460 ; N bullet ; B 50 113 410 473 ;
-C 184 ; WX 549 ; N divide ; B 10 71 536 456 ;
-C 185 ; WX 549 ; N notequal ; B 15 -25 540 549 ;
-C 186 ; WX 549 ; N equivalence ; B 14 82 538 443 ;
-C 187 ; WX 549 ; N approxequal ; B 14 135 527 394 ;
-C 188 ; WX 1000 ; N ellipsis ; B 111 -17 889 95 ;
-C 189 ; WX 603 ; N arrowvertex ; B 280 -120 336 1010 ;
-C 190 ; WX 1000 ; N arrowhorizex ; B -60 220 1050 276 ;
-C 191 ; WX 658 ; N carriagereturn ; B 15 -16 602 629 ;
-C 192 ; WX 823 ; N aleph ; B 175 -18 661 658 ;
-C 193 ; WX 686 ; N Ifraktur ; B 10 -53 578 740 ;
-C 194 ; WX 795 ; N Rfraktur ; B 26 -15 759 734 ;
-C 195 ; WX 987 ; N weierstrass ; B 159 -211 870 573 ;
-C 196 ; WX 768 ; N circlemultiply ; B 43 -17 733 673 ;
-C 197 ; WX 768 ; N circleplus ; B 43 -15 733 675 ;
-C 198 ; WX 823 ; N emptyset ; B 39 -24 781 719 ;
-C 199 ; WX 768 ; N intersection ; B 40 0 732 509 ;
-C 200 ; WX 768 ; N union ; B 40 -17 732 492 ;
-C 201 ; WX 713 ; N propersuperset ; B 20 0 673 470 ;
-C 202 ; WX 713 ; N reflexsuperset ; B 20 -125 673 470 ;
-C 203 ; WX 713 ; N notsubset ; B 36 -70 690 540 ;
-C 204 ; WX 713 ; N propersubset ; B 37 0 690 470 ;
-C 205 ; WX 713 ; N reflexsubset ; B 37 -125 690 470 ;
-C 206 ; WX 713 ; N element ; B 45 0 505 468 ;
-C 207 ; WX 713 ; N notelement ; B 45 -58 505 555 ;
-C 208 ; WX 768 ; N angle ; B 26 0 738 673 ;
-C 209 ; WX 713 ; N gradient ; B 36 -19 681 718 ;
-C 210 ; WX 790 ; N registerserif ; B 50 -17 740 673 ;
-C 211 ; WX 790 ; N copyrightserif ; B 51 -15 741 675 ;
-C 212 ; WX 890 ; N trademarkserif ; B 18 293 855 673 ;
-C 213 ; WX 823 ; N product ; B 25 -101 803 751 ;
-C 214 ; WX 549 ; N radical ; B 10 -38 515 917 ;
-C 215 ; WX 250 ; N dotmath ; B 69 210 169 310 ;
-C 216 ; WX 713 ; N logicalnot ; B 15 0 680 288 ;
-C 217 ; WX 603 ; N logicaland ; B 23 0 583 454 ;
-C 218 ; WX 603 ; N logicalor ; B 30 0 578 477 ;
-C 219 ; WX 1042 ; N arrowdblboth ; B 27 -20 1023 510 ;
-C 220 ; WX 987 ; N arrowdblleft ; B 30 -15 939 513 ;
-C 221 ; WX 603 ; N arrowdblup ; B 39 2 567 911 ;
-C 222 ; WX 987 ; N arrowdblright ; B 45 -20 954 508 ;
-C 223 ; WX 603 ; N arrowdbldown ; B 44 -19 572 890 ;
-C 224 ; WX 494 ; N lozenge ; B 18 0 466 745 ;
-C 225 ; WX 329 ; N angleleft ; B 25 -198 306 746 ;
-C 226 ; WX 790 ; N registersans ; B 50 -20 740 670 ;
-C 227 ; WX 790 ; N copyrightsans ; B 49 -15 739 675 ;
-C 228 ; WX 786 ; N trademarksans ; B 5 293 725 673 ;
-C 229 ; WX 713 ; N summation ; B 14 -108 695 752 ;
-C 230 ; WX 384 ; N parenlefttp ; B 40 -293 436 926 ;
-C 231 ; WX 384 ; N parenleftex ; B 40 -85 92 925 ;
-C 232 ; WX 384 ; N parenleftbt ; B 40 -293 436 926 ;
-C 233 ; WX 384 ; N bracketlefttp ; B 0 -80 341 926 ;
-C 234 ; WX 384 ; N bracketleftex ; B 0 -79 55 925 ;
-C 235 ; WX 384 ; N bracketleftbt ; B 0 -80 340 926 ;
-C 236 ; WX 494 ; N bracelefttp ; B 201 -75 439 926 ;
-C 237 ; WX 494 ; N braceleftmid ; B 14 -85 255 935 ;
-C 238 ; WX 494 ; N braceleftbt ; B 201 -70 439 926 ;
-C 239 ; WX 494 ; N braceex ; B 201 -80 255 935 ;
-C 241 ; WX 329 ; N angleright ; B 21 -198 302 746 ;
-C 242 ; WX 274 ; N integral ; B 2 -107 291 916 ;
-C 243 ; WX 686 ; N integraltp ; B 332 -83 715 921 ;
-C 244 ; WX 686 ; N integralex ; B 332 -88 415 975 ;
-C 245 ; WX 686 ; N integralbt ; B 39 -81 415 921 ;
-C 246 ; WX 384 ; N parenrighttp ; B 54 -293 450 926 ;
-C 247 ; WX 384 ; N parenrightex ; B 398 -85 450 925 ;
-C 248 ; WX 384 ; N parenrightbt ; B 54 -293 450 926 ;
-C 249 ; WX 384 ; N bracketrighttp ; B 22 -80 360 926 ;
-C 250 ; WX 384 ; N bracketrightex ; B 305 -79 360 925 ;
-C 251 ; WX 384 ; N bracketrightbt ; B 20 -80 360 926 ;
-C 252 ; WX 494 ; N bracerighttp ; B 17 -75 255 926 ;
-C 253 ; WX 494 ; N bracerightmid ; B 201 -85 442 935 ;
-C 254 ; WX 494 ; N bracerightbt ; B 17 -70 255 926 ;
-C -1 ; WX 790 ; N apple ; B 56 -3 733 808 ;
-EndCharMetrics
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/ptmb8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/ptmb8a.afm
deleted file mode 100644
index 55207f94d1..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/ptmb8a.afm
+++ /dev/null
@@ -1,648 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Tue Mar 20 12:17:14 1990
-Comment UniqueID 28417
-Comment VMusage 30458 37350
-FontName Times-Bold
-FullName Times Bold
-FamilyName Times
-Weight Bold
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -168 -218 1000 935
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.007
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 676
-XHeight 461
-Ascender 676
-Descender -205
-StartCharMetrics 228
-C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 81 -13 251 691 ;
-C 34 ; WX 555 ; N quotedbl ; B 83 404 472 691 ;
-C 35 ; WX 500 ; N numbersign ; B 4 0 496 700 ;
-C 36 ; WX 500 ; N dollar ; B 29 -99 472 750 ;
-C 37 ; WX 1000 ; N percent ; B 124 -14 877 692 ;
-C 38 ; WX 833 ; N ampersand ; B 62 -16 787 691 ;
-C 39 ; WX 333 ; N quoteright ; B 79 356 263 691 ;
-C 40 ; WX 333 ; N parenleft ; B 46 -168 306 694 ;
-C 41 ; WX 333 ; N parenright ; B 27 -168 287 694 ;
-C 42 ; WX 500 ; N asterisk ; B 56 255 447 691 ;
-C 43 ; WX 570 ; N plus ; B 33 0 537 506 ;
-C 44 ; WX 250 ; N comma ; B 39 -180 223 155 ;
-C 45 ; WX 333 ; N hyphen ; B 44 171 287 287 ;
-C 46 ; WX 250 ; N period ; B 41 -13 210 156 ;
-C 47 ; WX 278 ; N slash ; B -24 -19 302 691 ;
-C 48 ; WX 500 ; N zero ; B 24 -13 476 688 ;
-C 49 ; WX 500 ; N one ; B 65 0 442 688 ;
-C 50 ; WX 500 ; N two ; B 17 0 478 688 ;
-C 51 ; WX 500 ; N three ; B 16 -14 468 688 ;
-C 52 ; WX 500 ; N four ; B 19 0 475 688 ;
-C 53 ; WX 500 ; N five ; B 22 -8 470 676 ;
-C 54 ; WX 500 ; N six ; B 28 -13 475 688 ;
-C 55 ; WX 500 ; N seven ; B 17 0 477 676 ;
-C 56 ; WX 500 ; N eight ; B 28 -13 472 688 ;
-C 57 ; WX 500 ; N nine ; B 26 -13 473 688 ;
-C 58 ; WX 333 ; N colon ; B 82 -13 251 472 ;
-C 59 ; WX 333 ; N semicolon ; B 82 -180 266 472 ;
-C 60 ; WX 570 ; N less ; B 31 -8 539 514 ;
-C 61 ; WX 570 ; N equal ; B 33 107 537 399 ;
-C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ;
-C 63 ; WX 500 ; N question ; B 57 -13 445 689 ;
-C 64 ; WX 930 ; N at ; B 108 -19 822 691 ;
-C 65 ; WX 722 ; N A ; B 9 0 689 690 ;
-C 66 ; WX 667 ; N B ; B 16 0 619 676 ;
-C 67 ; WX 722 ; N C ; B 49 -19 687 691 ;
-C 68 ; WX 722 ; N D ; B 14 0 690 676 ;
-C 69 ; WX 667 ; N E ; B 16 0 641 676 ;
-C 70 ; WX 611 ; N F ; B 16 0 583 676 ;
-C 71 ; WX 778 ; N G ; B 37 -19 755 691 ;
-C 72 ; WX 778 ; N H ; B 21 0 759 676 ;
-C 73 ; WX 389 ; N I ; B 20 0 370 676 ;
-C 74 ; WX 500 ; N J ; B 3 -96 479 676 ;
-C 75 ; WX 778 ; N K ; B 30 0 769 676 ;
-C 76 ; WX 667 ; N L ; B 19 0 638 676 ;
-C 77 ; WX 944 ; N M ; B 14 0 921 676 ;
-C 78 ; WX 722 ; N N ; B 16 -18 701 676 ;
-C 79 ; WX 778 ; N O ; B 35 -19 743 691 ;
-C 80 ; WX 611 ; N P ; B 16 0 600 676 ;
-C 81 ; WX 778 ; N Q ; B 35 -176 743 691 ;
-C 82 ; WX 722 ; N R ; B 26 0 715 676 ;
-C 83 ; WX 556 ; N S ; B 35 -19 513 692 ;
-C 84 ; WX 667 ; N T ; B 31 0 636 676 ;
-C 85 ; WX 722 ; N U ; B 16 -19 701 676 ;
-C 86 ; WX 722 ; N V ; B 16 -18 701 676 ;
-C 87 ; WX 1000 ; N W ; B 19 -15 981 676 ;
-C 88 ; WX 722 ; N X ; B 16 0 699 676 ;
-C 89 ; WX 722 ; N Y ; B 15 0 699 676 ;
-C 90 ; WX 667 ; N Z ; B 28 0 634 676 ;
-C 91 ; WX 333 ; N bracketleft ; B 67 -149 301 678 ;
-C 92 ; WX 278 ; N backslash ; B -25 -19 303 691 ;
-C 93 ; WX 333 ; N bracketright ; B 32 -149 266 678 ;
-C 94 ; WX 581 ; N asciicircum ; B 73 311 509 676 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 333 ; N quoteleft ; B 70 356 254 691 ;
-C 97 ; WX 500 ; N a ; B 25 -14 488 473 ;
-C 98 ; WX 556 ; N b ; B 17 -14 521 676 ;
-C 99 ; WX 444 ; N c ; B 25 -14 430 473 ;
-C 100 ; WX 556 ; N d ; B 25 -14 534 676 ;
-C 101 ; WX 444 ; N e ; B 25 -14 426 473 ;
-C 102 ; WX 333 ; N f ; B 14 0 389 691 ; L i fi ; L l fl ;
-C 103 ; WX 500 ; N g ; B 28 -206 483 473 ;
-C 104 ; WX 556 ; N h ; B 16 0 534 676 ;
-C 105 ; WX 278 ; N i ; B 16 0 255 691 ;
-C 106 ; WX 333 ; N j ; B -57 -203 263 691 ;
-C 107 ; WX 556 ; N k ; B 22 0 543 676 ;
-C 108 ; WX 278 ; N l ; B 16 0 255 676 ;
-C 109 ; WX 833 ; N m ; B 16 0 814 473 ;
-C 110 ; WX 556 ; N n ; B 21 0 539 473 ;
-C 111 ; WX 500 ; N o ; B 25 -14 476 473 ;
-C 112 ; WX 556 ; N p ; B 19 -205 524 473 ;
-C 113 ; WX 556 ; N q ; B 34 -205 536 473 ;
-C 114 ; WX 444 ; N r ; B 29 0 434 473 ;
-C 115 ; WX 389 ; N s ; B 25 -14 361 473 ;
-C 116 ; WX 333 ; N t ; B 20 -12 332 630 ;
-C 117 ; WX 556 ; N u ; B 16 -14 537 461 ;
-C 118 ; WX 500 ; N v ; B 21 -14 485 461 ;
-C 119 ; WX 722 ; N w ; B 23 -14 707 461 ;
-C 120 ; WX 500 ; N x ; B 12 0 484 461 ;
-C 121 ; WX 500 ; N y ; B 16 -205 480 461 ;
-C 122 ; WX 444 ; N z ; B 21 0 420 461 ;
-C 123 ; WX 394 ; N braceleft ; B 22 -175 340 698 ;
-C 124 ; WX 220 ; N bar ; B 66 -19 154 691 ;
-C 125 ; WX 394 ; N braceright ; B 54 -175 372 698 ;
-C 126 ; WX 520 ; N asciitilde ; B 29 173 491 333 ;
-C 161 ; WX 333 ; N exclamdown ; B 82 -203 252 501 ;
-C 162 ; WX 500 ; N cent ; B 53 -140 458 588 ;
-C 163 ; WX 500 ; N sterling ; B 21 -14 477 684 ;
-C 164 ; WX 167 ; N fraction ; B -168 -12 329 688 ;
-C 165 ; WX 500 ; N yen ; B -64 0 547 676 ;
-C 166 ; WX 500 ; N florin ; B 0 -155 498 706 ;
-C 167 ; WX 500 ; N section ; B 57 -132 443 691 ;
-C 168 ; WX 500 ; N currency ; B -26 61 526 613 ;
-C 169 ; WX 278 ; N quotesingle ; B 75 404 204 691 ;
-C 170 ; WX 500 ; N quotedblleft ; B 32 356 486 691 ;
-C 171 ; WX 500 ; N guillemotleft ; B 23 36 473 415 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 51 36 305 415 ;
-C 173 ; WX 333 ; N guilsinglright ; B 28 36 282 415 ;
-C 174 ; WX 556 ; N fi ; B 14 0 536 691 ;
-C 175 ; WX 556 ; N fl ; B 14 0 536 691 ;
-C 177 ; WX 500 ; N endash ; B 0 181 500 271 ;
-C 178 ; WX 500 ; N dagger ; B 47 -134 453 691 ;
-C 179 ; WX 500 ; N daggerdbl ; B 45 -132 456 691 ;
-C 180 ; WX 250 ; N periodcentered ; B 41 248 210 417 ;
-C 182 ; WX 540 ; N paragraph ; B 0 -186 519 676 ;
-C 183 ; WX 350 ; N bullet ; B 35 198 315 478 ;
-C 184 ; WX 333 ; N quotesinglbase ; B 79 -180 263 155 ;
-C 185 ; WX 500 ; N quotedblbase ; B 14 -180 468 155 ;
-C 186 ; WX 500 ; N quotedblright ; B 14 356 468 691 ;
-C 187 ; WX 500 ; N guillemotright ; B 27 36 477 415 ;
-C 188 ; WX 1000 ; N ellipsis ; B 82 -13 917 156 ;
-C 189 ; WX 1000 ; N perthousand ; B 7 -29 995 706 ;
-C 191 ; WX 500 ; N questiondown ; B 55 -201 443 501 ;
-C 193 ; WX 333 ; N grave ; B 8 528 246 713 ;
-C 194 ; WX 333 ; N acute ; B 86 528 324 713 ;
-C 195 ; WX 333 ; N circumflex ; B -2 528 335 704 ;
-C 196 ; WX 333 ; N tilde ; B -16 547 349 674 ;
-C 197 ; WX 333 ; N macron ; B 1 565 331 637 ;
-C 198 ; WX 333 ; N breve ; B 15 528 318 691 ;
-C 199 ; WX 333 ; N dotaccent ; B 103 537 230 667 ;
-C 200 ; WX 333 ; N dieresis ; B -2 537 335 667 ;
-C 202 ; WX 333 ; N ring ; B 60 527 273 740 ;
-C 203 ; WX 333 ; N cedilla ; B 68 -218 294 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B -13 528 425 713 ;
-C 206 ; WX 333 ; N ogonek ; B 90 -173 319 44 ;
-C 207 ; WX 333 ; N caron ; B -2 528 335 704 ;
-C 208 ; WX 1000 ; N emdash ; B 0 181 1000 271 ;
-C 225 ; WX 1000 ; N AE ; B 4 0 951 676 ;
-C 227 ; WX 300 ; N ordfeminine ; B -1 397 301 688 ;
-C 232 ; WX 667 ; N Lslash ; B 19 0 638 676 ;
-C 233 ; WX 778 ; N Oslash ; B 35 -74 743 737 ;
-C 234 ; WX 1000 ; N OE ; B 22 -5 981 684 ;
-C 235 ; WX 330 ; N ordmasculine ; B 18 397 312 688 ;
-C 241 ; WX 722 ; N ae ; B 33 -14 693 473 ;
-C 245 ; WX 278 ; N dotlessi ; B 16 0 255 461 ;
-C 248 ; WX 278 ; N lslash ; B -22 0 303 676 ;
-C 249 ; WX 500 ; N oslash ; B 25 -92 476 549 ;
-C 250 ; WX 722 ; N oe ; B 22 -14 696 473 ;
-C 251 ; WX 556 ; N germandbls ; B 19 -12 517 691 ;
-C -1 ; WX 667 ; N Zcaron ; B 28 0 634 914 ;
-C -1 ; WX 444 ; N ccedilla ; B 25 -218 430 473 ;
-C -1 ; WX 500 ; N ydieresis ; B 16 -205 480 667 ;
-C -1 ; WX 500 ; N atilde ; B 25 -14 488 674 ;
-C -1 ; WX 278 ; N icircumflex ; B -36 0 301 704 ;
-C -1 ; WX 300 ; N threesuperior ; B 3 268 297 688 ;
-C -1 ; WX 444 ; N ecircumflex ; B 25 -14 426 704 ;
-C -1 ; WX 556 ; N thorn ; B 19 -205 524 676 ;
-C -1 ; WX 444 ; N egrave ; B 25 -14 426 713 ;
-C -1 ; WX 300 ; N twosuperior ; B 0 275 300 688 ;
-C -1 ; WX 444 ; N eacute ; B 25 -14 426 713 ;
-C -1 ; WX 500 ; N otilde ; B 25 -14 476 674 ;
-C -1 ; WX 722 ; N Aacute ; B 9 0 689 923 ;
-C -1 ; WX 500 ; N ocircumflex ; B 25 -14 476 704 ;
-C -1 ; WX 500 ; N yacute ; B 16 -205 480 713 ;
-C -1 ; WX 556 ; N udieresis ; B 16 -14 537 667 ;
-C -1 ; WX 750 ; N threequarters ; B 23 -12 733 688 ;
-C -1 ; WX 500 ; N acircumflex ; B 25 -14 488 704 ;
-C -1 ; WX 722 ; N Eth ; B 6 0 690 676 ;
-C -1 ; WX 444 ; N edieresis ; B 25 -14 426 667 ;
-C -1 ; WX 556 ; N ugrave ; B 16 -14 537 713 ;
-C -1 ; WX 1000 ; N trademark ; B 24 271 977 676 ;
-C -1 ; WX 500 ; N ograve ; B 25 -14 476 713 ;
-C -1 ; WX 389 ; N scaron ; B 25 -14 363 704 ;
-C -1 ; WX 389 ; N Idieresis ; B 20 0 370 877 ;
-C -1 ; WX 556 ; N uacute ; B 16 -14 537 713 ;
-C -1 ; WX 500 ; N agrave ; B 25 -14 488 713 ;
-C -1 ; WX 556 ; N ntilde ; B 21 0 539 674 ;
-C -1 ; WX 500 ; N aring ; B 25 -14 488 740 ;
-C -1 ; WX 444 ; N zcaron ; B 21 0 420 704 ;
-C -1 ; WX 389 ; N Icircumflex ; B 20 0 370 914 ;
-C -1 ; WX 722 ; N Ntilde ; B 16 -18 701 884 ;
-C -1 ; WX 556 ; N ucircumflex ; B 16 -14 537 704 ;
-C -1 ; WX 667 ; N Ecircumflex ; B 16 0 641 914 ;
-C -1 ; WX 389 ; N Iacute ; B 20 0 370 923 ;
-C -1 ; WX 722 ; N Ccedilla ; B 49 -218 687 691 ;
-C -1 ; WX 778 ; N Odieresis ; B 35 -19 743 877 ;
-C -1 ; WX 556 ; N Scaron ; B 35 -19 513 914 ;
-C -1 ; WX 667 ; N Edieresis ; B 16 0 641 877 ;
-C -1 ; WX 389 ; N Igrave ; B 20 0 370 923 ;
-C -1 ; WX 500 ; N adieresis ; B 25 -14 488 667 ;
-C -1 ; WX 778 ; N Ograve ; B 35 -19 743 923 ;
-C -1 ; WX 667 ; N Egrave ; B 16 0 641 923 ;
-C -1 ; WX 722 ; N Ydieresis ; B 15 0 699 877 ;
-C -1 ; WX 747 ; N registered ; B 26 -19 721 691 ;
-C -1 ; WX 778 ; N Otilde ; B 35 -19 743 884 ;
-C -1 ; WX 750 ; N onequarter ; B 28 -12 743 688 ;
-C -1 ; WX 722 ; N Ugrave ; B 16 -19 701 923 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 16 -19 701 914 ;
-C -1 ; WX 611 ; N Thorn ; B 16 0 600 676 ;
-C -1 ; WX 570 ; N divide ; B 33 -31 537 537 ;
-C -1 ; WX 722 ; N Atilde ; B 9 0 689 884 ;
-C -1 ; WX 722 ; N Uacute ; B 16 -19 701 923 ;
-C -1 ; WX 778 ; N Ocircumflex ; B 35 -19 743 914 ;
-C -1 ; WX 570 ; N logicalnot ; B 33 108 537 399 ;
-C -1 ; WX 722 ; N Aring ; B 9 0 689 935 ;
-C -1 ; WX 278 ; N idieresis ; B -36 0 301 667 ;
-C -1 ; WX 278 ; N iacute ; B 16 0 290 713 ;
-C -1 ; WX 500 ; N aacute ; B 25 -14 488 713 ;
-C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ;
-C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ;
-C -1 ; WX 722 ; N Udieresis ; B 16 -19 701 877 ;
-C -1 ; WX 570 ; N minus ; B 33 209 537 297 ;
-C -1 ; WX 300 ; N onesuperior ; B 28 275 273 688 ;
-C -1 ; WX 667 ; N Eacute ; B 16 0 641 923 ;
-C -1 ; WX 722 ; N Acircumflex ; B 9 0 689 914 ;
-C -1 ; WX 747 ; N copyright ; B 26 -19 721 691 ;
-C -1 ; WX 722 ; N Agrave ; B 9 0 689 923 ;
-C -1 ; WX 500 ; N odieresis ; B 25 -14 476 667 ;
-C -1 ; WX 500 ; N oacute ; B 25 -14 476 713 ;
-C -1 ; WX 400 ; N degree ; B 57 402 343 688 ;
-C -1 ; WX 278 ; N igrave ; B -26 0 255 713 ;
-C -1 ; WX 556 ; N mu ; B 33 -206 536 461 ;
-C -1 ; WX 778 ; N Oacute ; B 35 -19 743 923 ;
-C -1 ; WX 500 ; N eth ; B 25 -14 476 691 ;
-C -1 ; WX 722 ; N Adieresis ; B 9 0 689 877 ;
-C -1 ; WX 722 ; N Yacute ; B 15 0 699 928 ;
-C -1 ; WX 220 ; N brokenbar ; B 66 -19 154 691 ;
-C -1 ; WX 750 ; N onehalf ; B -7 -12 775 688 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 283
-
-KPX A y -74
-KPX A w -90
-KPX A v -100
-KPX A u -50
-KPX A quoteright -74
-KPX A quotedblright 0
-KPX A p -25
-KPX A Y -100
-KPX A W -130
-KPX A V -145
-KPX A U -50
-KPX A T -95
-KPX A Q -45
-KPX A O -45
-KPX A G -55
-KPX A C -55
-
-KPX B period 0
-KPX B comma 0
-KPX B U -10
-KPX B A -30
-
-KPX D period -20
-KPX D comma 0
-KPX D Y -40
-KPX D W -40
-KPX D V -40
-KPX D A -35
-
-KPX F r 0
-KPX F period -110
-KPX F o -25
-KPX F i 0
-KPX F e -25
-KPX F comma -92
-KPX F a -25
-KPX F A -90
-
-KPX G period 0
-KPX G comma 0
-
-KPX J u -15
-KPX J period -20
-KPX J o -15
-KPX J e -15
-KPX J comma 0
-KPX J a -15
-KPX J A -30
-
-KPX K y -45
-KPX K u -15
-KPX K o -25
-KPX K e -25
-KPX K O -30
-
-KPX L y -55
-KPX L quoteright -110
-KPX L quotedblright -20
-KPX L Y -92
-KPX L W -92
-KPX L V -92
-KPX L T -92
-
-KPX N period 0
-KPX N comma 0
-KPX N A -20
-
-KPX O period 0
-KPX O comma 0
-KPX O Y -50
-KPX O X -40
-KPX O W -50
-KPX O V -50
-KPX O T -40
-KPX O A -40
-
-KPX P period -110
-KPX P o -20
-KPX P e -20
-KPX P comma -92
-KPX P a -10
-KPX P A -74
-
-KPX Q period -20
-KPX Q comma 0
-KPX Q U -10
-
-KPX R Y -35
-KPX R W -35
-KPX R V -55
-KPX R U -30
-KPX R T -40
-KPX R O -30
-
-KPX S period 0
-KPX S comma 0
-
-KPX T y -74
-KPX T w -74
-KPX T u -92
-KPX T semicolon -74
-KPX T r -74
-KPX T period -90
-KPX T o -92
-KPX T i -18
-KPX T hyphen -92
-KPX T h 0
-KPX T e -92
-KPX T comma -74
-KPX T colon -74
-KPX T a -92
-KPX T O -18
-KPX T A -90
-
-KPX U period -50
-KPX U comma -50
-KPX U A -60
-
-KPX V u -92
-KPX V semicolon -92
-KPX V period -145
-KPX V o -100
-KPX V i -37
-KPX V hyphen -74
-KPX V e -100
-KPX V comma -129
-KPX V colon -92
-KPX V a -92
-KPX V O -45
-KPX V G -30
-KPX V A -135
-
-KPX W y -60
-KPX W u -50
-KPX W semicolon -55
-KPX W period -92
-KPX W o -75
-KPX W i -18
-KPX W hyphen -37
-KPX W h 0
-KPX W e -65
-KPX W comma -92
-KPX W colon -55
-KPX W a -65
-KPX W O -10
-KPX W A -120
-
-KPX Y u -92
-KPX Y semicolon -92
-KPX Y period -92
-KPX Y o -111
-KPX Y i -37
-KPX Y hyphen -92
-KPX Y e -111
-KPX Y comma -92
-KPX Y colon -92
-KPX Y a -85
-KPX Y O -35
-KPX Y A -110
-
-KPX a y 0
-KPX a w 0
-KPX a v -25
-KPX a t 0
-KPX a p 0
-KPX a g 0
-KPX a b 0
-
-KPX b y 0
-KPX b v -15
-KPX b u -20
-KPX b period -40
-KPX b l 0
-KPX b comma 0
-KPX b b -10
-
-KPX c y 0
-KPX c period 0
-KPX c l 0
-KPX c k 0
-KPX c h 0
-KPX c comma 0
-
-KPX colon space 0
-
-KPX comma space 0
-KPX comma quoteright -55
-KPX comma quotedblright -45
-
-KPX d y 0
-KPX d w -15
-KPX d v 0
-KPX d period 0
-KPX d d 0
-KPX d comma 0
-
-KPX e y 0
-KPX e x 0
-KPX e w 0
-KPX e v -15
-KPX e period 0
-KPX e p 0
-KPX e g 0
-KPX e comma 0
-KPX e b 0
-
-KPX f quoteright 55
-KPX f quotedblright 50
-KPX f period -15
-KPX f o -25
-KPX f l 0
-KPX f i -25
-KPX f f 0
-KPX f e 0
-KPX f dotlessi -35
-KPX f comma -15
-KPX f a 0
-
-KPX g y 0
-KPX g r 0
-KPX g period -15
-KPX g o 0
-KPX g i 0
-KPX g g 0
-KPX g e 0
-KPX g comma 0
-KPX g a 0
-
-KPX h y -15
-
-KPX i v -10
-
-KPX k y -15
-KPX k o -15
-KPX k e -10
-
-KPX l y 0
-KPX l w 0
-
-KPX m y 0
-KPX m u 0
-
-KPX n y 0
-KPX n v -40
-KPX n u 0
-
-KPX o y 0
-KPX o x 0
-KPX o w -10
-KPX o v -10
-KPX o g 0
-
-KPX p y 0
-
-KPX period quoteright -55
-KPX period quotedblright -55
-
-KPX quotedblleft quoteleft 0
-KPX quotedblleft A -10
-
-KPX quotedblright space 0
-
-KPX quoteleft quoteleft -63
-KPX quoteleft A -10
-
-KPX quoteright v -20
-KPX quoteright t 0
-KPX quoteright space -74
-KPX quoteright s -37
-KPX quoteright r -20
-KPX quoteright quoteright -63
-KPX quoteright quotedblright 0
-KPX quoteright l 0
-KPX quoteright d -20
-
-KPX r y 0
-KPX r v -10
-KPX r u 0
-KPX r t 0
-KPX r s 0
-KPX r r 0
-KPX r q -18
-KPX r period -100
-KPX r p -10
-KPX r o -18
-KPX r n -15
-KPX r m 0
-KPX r l 0
-KPX r k 0
-KPX r i 0
-KPX r hyphen -37
-KPX r g -10
-KPX r e -18
-KPX r d 0
-KPX r comma -92
-KPX r c -18
-KPX r a 0
-
-KPX s w 0
-
-KPX space quoteleft 0
-KPX space quotedblleft 0
-KPX space Y -55
-KPX space W -30
-KPX space V -45
-KPX space T -30
-KPX space A -55
-
-KPX v period -70
-KPX v o -10
-KPX v e -10
-KPX v comma -55
-KPX v a -10
-
-KPX w period -70
-KPX w o -10
-KPX w h 0
-KPX w e 0
-KPX w comma -55
-KPX w a 0
-
-KPX x e 0
-
-KPX y period -70
-KPX y o -25
-KPX y e -10
-KPX y comma -55
-KPX y a 0
-
-KPX z o 0
-KPX z e 0
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 188 210 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 188 210 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 188 210 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 188 210 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 180 195 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 188 210 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 208 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 174 210 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 174 210 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 174 210 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 174 210 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 28 210 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 28 210 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 28 210 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 28 210 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 195 210 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 223 210 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 223 210 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 223 210 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 223 210 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 223 210 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 210 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 222 210 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 222 210 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 222 210 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 222 210 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 210 215 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 215 210 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 167 210 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 77 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 77 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 77 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 77 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 77 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 77 0 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 69 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 62 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 62 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 62 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 62 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -34 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -34 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -34 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -34 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 112 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 105 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 105 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 105 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 105 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 56 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/ptmbi8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/ptmbi8a.afm
deleted file mode 100644
index 25ab54ea81..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/ptmbi8a.afm
+++ /dev/null
@@ -1,648 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Tue Mar 20 13:14:55 1990
-Comment UniqueID 28425
-Comment VMusage 32721 39613
-FontName Times-BoldItalic
-FullName Times Bold Italic
-FamilyName Times
-Weight Bold
-ItalicAngle -15
-IsFixedPitch false
-FontBBox -200 -218 996 921
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.009
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 669
-XHeight 462
-Ascender 699
-Descender -205
-StartCharMetrics 228
-C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 389 ; N exclam ; B 67 -13 370 684 ;
-C 34 ; WX 555 ; N quotedbl ; B 136 398 536 685 ;
-C 35 ; WX 500 ; N numbersign ; B -33 0 533 700 ;
-C 36 ; WX 500 ; N dollar ; B -20 -100 497 733 ;
-C 37 ; WX 833 ; N percent ; B 39 -10 793 692 ;
-C 38 ; WX 778 ; N ampersand ; B 5 -19 699 682 ;
-C 39 ; WX 333 ; N quoteright ; B 98 369 302 685 ;
-C 40 ; WX 333 ; N parenleft ; B 28 -179 344 685 ;
-C 41 ; WX 333 ; N parenright ; B -44 -179 271 685 ;
-C 42 ; WX 500 ; N asterisk ; B 65 249 456 685 ;
-C 43 ; WX 570 ; N plus ; B 33 0 537 506 ;
-C 44 ; WX 250 ; N comma ; B -60 -182 144 134 ;
-C 45 ; WX 333 ; N hyphen ; B 2 166 271 282 ;
-C 46 ; WX 250 ; N period ; B -9 -13 139 135 ;
-C 47 ; WX 278 ; N slash ; B -64 -18 342 685 ;
-C 48 ; WX 500 ; N zero ; B 17 -14 477 683 ;
-C 49 ; WX 500 ; N one ; B 5 0 419 683 ;
-C 50 ; WX 500 ; N two ; B -27 0 446 683 ;
-C 51 ; WX 500 ; N three ; B -15 -13 450 683 ;
-C 52 ; WX 500 ; N four ; B -15 0 503 683 ;
-C 53 ; WX 500 ; N five ; B -11 -13 487 669 ;
-C 54 ; WX 500 ; N six ; B 23 -15 509 679 ;
-C 55 ; WX 500 ; N seven ; B 52 0 525 669 ;
-C 56 ; WX 500 ; N eight ; B 3 -13 476 683 ;
-C 57 ; WX 500 ; N nine ; B -12 -10 475 683 ;
-C 58 ; WX 333 ; N colon ; B 23 -13 264 459 ;
-C 59 ; WX 333 ; N semicolon ; B -25 -183 264 459 ;
-C 60 ; WX 570 ; N less ; B 31 -8 539 514 ;
-C 61 ; WX 570 ; N equal ; B 33 107 537 399 ;
-C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ;
-C 63 ; WX 500 ; N question ; B 79 -13 470 684 ;
-C 64 ; WX 832 ; N at ; B 63 -18 770 685 ;
-C 65 ; WX 667 ; N A ; B -67 0 593 683 ;
-C 66 ; WX 667 ; N B ; B -24 0 624 669 ;
-C 67 ; WX 667 ; N C ; B 32 -18 677 685 ;
-C 68 ; WX 722 ; N D ; B -46 0 685 669 ;
-C 69 ; WX 667 ; N E ; B -27 0 653 669 ;
-C 70 ; WX 667 ; N F ; B -13 0 660 669 ;
-C 71 ; WX 722 ; N G ; B 21 -18 706 685 ;
-C 72 ; WX 778 ; N H ; B -24 0 799 669 ;
-C 73 ; WX 389 ; N I ; B -32 0 406 669 ;
-C 74 ; WX 500 ; N J ; B -46 -99 524 669 ;
-C 75 ; WX 667 ; N K ; B -21 0 702 669 ;
-C 76 ; WX 611 ; N L ; B -22 0 590 669 ;
-C 77 ; WX 889 ; N M ; B -29 -12 917 669 ;
-C 78 ; WX 722 ; N N ; B -27 -15 748 669 ;
-C 79 ; WX 722 ; N O ; B 27 -18 691 685 ;
-C 80 ; WX 611 ; N P ; B -27 0 613 669 ;
-C 81 ; WX 722 ; N Q ; B 27 -208 691 685 ;
-C 82 ; WX 667 ; N R ; B -29 0 623 669 ;
-C 83 ; WX 556 ; N S ; B 2 -18 526 685 ;
-C 84 ; WX 611 ; N T ; B 50 0 650 669 ;
-C 85 ; WX 722 ; N U ; B 67 -18 744 669 ;
-C 86 ; WX 667 ; N V ; B 65 -18 715 669 ;
-C 87 ; WX 889 ; N W ; B 65 -18 940 669 ;
-C 88 ; WX 667 ; N X ; B -24 0 694 669 ;
-C 89 ; WX 611 ; N Y ; B 73 0 659 669 ;
-C 90 ; WX 611 ; N Z ; B -11 0 590 669 ;
-C 91 ; WX 333 ; N bracketleft ; B -37 -159 362 674 ;
-C 92 ; WX 278 ; N backslash ; B -1 -18 279 685 ;
-C 93 ; WX 333 ; N bracketright ; B -56 -157 343 674 ;
-C 94 ; WX 570 ; N asciicircum ; B 67 304 503 669 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 333 ; N quoteleft ; B 128 369 332 685 ;
-C 97 ; WX 500 ; N a ; B -21 -14 455 462 ;
-C 98 ; WX 500 ; N b ; B -14 -13 444 699 ;
-C 99 ; WX 444 ; N c ; B -5 -13 392 462 ;
-C 100 ; WX 500 ; N d ; B -21 -13 517 699 ;
-C 101 ; WX 444 ; N e ; B 5 -13 398 462 ;
-C 102 ; WX 333 ; N f ; B -169 -205 446 698 ; L i fi ; L l fl ;
-C 103 ; WX 500 ; N g ; B -52 -203 478 462 ;
-C 104 ; WX 556 ; N h ; B -13 -9 498 699 ;
-C 105 ; WX 278 ; N i ; B 2 -9 263 684 ;
-C 106 ; WX 278 ; N j ; B -189 -207 279 684 ;
-C 107 ; WX 500 ; N k ; B -23 -8 483 699 ;
-C 108 ; WX 278 ; N l ; B 2 -9 290 699 ;
-C 109 ; WX 778 ; N m ; B -14 -9 722 462 ;
-C 110 ; WX 556 ; N n ; B -6 -9 493 462 ;
-C 111 ; WX 500 ; N o ; B -3 -13 441 462 ;
-C 112 ; WX 500 ; N p ; B -120 -205 446 462 ;
-C 113 ; WX 500 ; N q ; B 1 -205 471 462 ;
-C 114 ; WX 389 ; N r ; B -21 0 389 462 ;
-C 115 ; WX 389 ; N s ; B -19 -13 333 462 ;
-C 116 ; WX 278 ; N t ; B -11 -9 281 594 ;
-C 117 ; WX 556 ; N u ; B 15 -9 492 462 ;
-C 118 ; WX 444 ; N v ; B 16 -13 401 462 ;
-C 119 ; WX 667 ; N w ; B 16 -13 614 462 ;
-C 120 ; WX 500 ; N x ; B -46 -13 469 462 ;
-C 121 ; WX 444 ; N y ; B -94 -205 392 462 ;
-C 122 ; WX 389 ; N z ; B -43 -78 368 449 ;
-C 123 ; WX 348 ; N braceleft ; B 5 -187 436 686 ;
-C 124 ; WX 220 ; N bar ; B 66 -18 154 685 ;
-C 125 ; WX 348 ; N braceright ; B -129 -187 302 686 ;
-C 126 ; WX 570 ; N asciitilde ; B 54 173 516 333 ;
-C 161 ; WX 389 ; N exclamdown ; B 19 -205 322 492 ;
-C 162 ; WX 500 ; N cent ; B 42 -143 439 576 ;
-C 163 ; WX 500 ; N sterling ; B -32 -12 510 683 ;
-C 164 ; WX 167 ; N fraction ; B -169 -14 324 683 ;
-C 165 ; WX 500 ; N yen ; B 33 0 628 669 ;
-C 166 ; WX 500 ; N florin ; B -87 -156 537 707 ;
-C 167 ; WX 500 ; N section ; B 36 -143 459 685 ;
-C 168 ; WX 500 ; N currency ; B -26 34 526 586 ;
-C 169 ; WX 278 ; N quotesingle ; B 128 398 268 685 ;
-C 170 ; WX 500 ; N quotedblleft ; B 53 369 513 685 ;
-C 171 ; WX 500 ; N guillemotleft ; B 12 32 468 415 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 32 32 303 415 ;
-C 173 ; WX 333 ; N guilsinglright ; B 10 32 281 415 ;
-C 174 ; WX 556 ; N fi ; B -188 -205 514 703 ;
-C 175 ; WX 556 ; N fl ; B -186 -205 553 704 ;
-C 177 ; WX 500 ; N endash ; B -40 178 477 269 ;
-C 178 ; WX 500 ; N dagger ; B 91 -145 494 685 ;
-C 179 ; WX 500 ; N daggerdbl ; B 10 -139 493 685 ;
-C 180 ; WX 250 ; N periodcentered ; B 51 257 199 405 ;
-C 182 ; WX 500 ; N paragraph ; B -57 -193 562 669 ;
-C 183 ; WX 350 ; N bullet ; B 0 175 350 525 ;
-C 184 ; WX 333 ; N quotesinglbase ; B -5 -182 199 134 ;
-C 185 ; WX 500 ; N quotedblbase ; B -57 -182 403 134 ;
-C 186 ; WX 500 ; N quotedblright ; B 53 369 513 685 ;
-C 187 ; WX 500 ; N guillemotright ; B 12 32 468 415 ;
-C 188 ; WX 1000 ; N ellipsis ; B 40 -13 852 135 ;
-C 189 ; WX 1000 ; N perthousand ; B 7 -29 996 706 ;
-C 191 ; WX 500 ; N questiondown ; B 30 -205 421 492 ;
-C 193 ; WX 333 ; N grave ; B 85 516 297 697 ;
-C 194 ; WX 333 ; N acute ; B 139 516 379 697 ;
-C 195 ; WX 333 ; N circumflex ; B 40 516 367 690 ;
-C 196 ; WX 333 ; N tilde ; B 48 536 407 655 ;
-C 197 ; WX 333 ; N macron ; B 51 553 393 623 ;
-C 198 ; WX 333 ; N breve ; B 71 516 387 678 ;
-C 199 ; WX 333 ; N dotaccent ; B 163 525 293 655 ;
-C 200 ; WX 333 ; N dieresis ; B 55 525 397 655 ;
-C 202 ; WX 333 ; N ring ; B 127 516 340 729 ;
-C 203 ; WX 333 ; N cedilla ; B -80 -218 156 5 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 69 516 498 697 ;
-C 206 ; WX 333 ; N ogonek ; B -40 -173 189 44 ;
-C 207 ; WX 333 ; N caron ; B 79 516 411 690 ;
-C 208 ; WX 1000 ; N emdash ; B -40 178 977 269 ;
-C 225 ; WX 944 ; N AE ; B -64 0 918 669 ;
-C 227 ; WX 266 ; N ordfeminine ; B 16 399 330 685 ;
-C 232 ; WX 611 ; N Lslash ; B -22 0 590 669 ;
-C 233 ; WX 722 ; N Oslash ; B 27 -125 691 764 ;
-C 234 ; WX 944 ; N OE ; B 23 -8 946 677 ;
-C 235 ; WX 300 ; N ordmasculine ; B 56 400 347 685 ;
-C 241 ; WX 722 ; N ae ; B -5 -13 673 462 ;
-C 245 ; WX 278 ; N dotlessi ; B 2 -9 238 462 ;
-C 248 ; WX 278 ; N lslash ; B -13 -9 301 699 ;
-C 249 ; WX 500 ; N oslash ; B -3 -119 441 560 ;
-C 250 ; WX 722 ; N oe ; B 6 -13 674 462 ;
-C 251 ; WX 500 ; N germandbls ; B -200 -200 473 705 ;
-C -1 ; WX 611 ; N Zcaron ; B -11 0 590 897 ;
-C -1 ; WX 444 ; N ccedilla ; B -24 -218 392 462 ;
-C -1 ; WX 444 ; N ydieresis ; B -94 -205 438 655 ;
-C -1 ; WX 500 ; N atilde ; B -21 -14 491 655 ;
-C -1 ; WX 278 ; N icircumflex ; B -2 -9 325 690 ;
-C -1 ; WX 300 ; N threesuperior ; B 17 265 321 683 ;
-C -1 ; WX 444 ; N ecircumflex ; B 5 -13 423 690 ;
-C -1 ; WX 500 ; N thorn ; B -120 -205 446 699 ;
-C -1 ; WX 444 ; N egrave ; B 5 -13 398 697 ;
-C -1 ; WX 300 ; N twosuperior ; B 2 274 313 683 ;
-C -1 ; WX 444 ; N eacute ; B 5 -13 435 697 ;
-C -1 ; WX 500 ; N otilde ; B -3 -13 491 655 ;
-C -1 ; WX 667 ; N Aacute ; B -67 0 593 904 ;
-C -1 ; WX 500 ; N ocircumflex ; B -3 -13 451 690 ;
-C -1 ; WX 444 ; N yacute ; B -94 -205 435 697 ;
-C -1 ; WX 556 ; N udieresis ; B 15 -9 494 655 ;
-C -1 ; WX 750 ; N threequarters ; B 7 -14 726 683 ;
-C -1 ; WX 500 ; N acircumflex ; B -21 -14 455 690 ;
-C -1 ; WX 722 ; N Eth ; B -31 0 700 669 ;
-C -1 ; WX 444 ; N edieresis ; B 5 -13 443 655 ;
-C -1 ; WX 556 ; N ugrave ; B 15 -9 492 697 ;
-C -1 ; WX 1000 ; N trademark ; B 32 263 968 669 ;
-C -1 ; WX 500 ; N ograve ; B -3 -13 441 697 ;
-C -1 ; WX 389 ; N scaron ; B -19 -13 439 690 ;
-C -1 ; WX 389 ; N Idieresis ; B -32 0 445 862 ;
-C -1 ; WX 556 ; N uacute ; B 15 -9 492 697 ;
-C -1 ; WX 500 ; N agrave ; B -21 -14 455 697 ;
-C -1 ; WX 556 ; N ntilde ; B -6 -9 504 655 ;
-C -1 ; WX 500 ; N aring ; B -21 -14 455 729 ;
-C -1 ; WX 389 ; N zcaron ; B -43 -78 424 690 ;
-C -1 ; WX 389 ; N Icircumflex ; B -32 0 420 897 ;
-C -1 ; WX 722 ; N Ntilde ; B -27 -15 748 862 ;
-C -1 ; WX 556 ; N ucircumflex ; B 15 -9 492 690 ;
-C -1 ; WX 667 ; N Ecircumflex ; B -27 0 653 897 ;
-C -1 ; WX 389 ; N Iacute ; B -32 0 412 904 ;
-C -1 ; WX 667 ; N Ccedilla ; B 32 -218 677 685 ;
-C -1 ; WX 722 ; N Odieresis ; B 27 -18 691 862 ;
-C -1 ; WX 556 ; N Scaron ; B 2 -18 526 897 ;
-C -1 ; WX 667 ; N Edieresis ; B -27 0 653 862 ;
-C -1 ; WX 389 ; N Igrave ; B -32 0 406 904 ;
-C -1 ; WX 500 ; N adieresis ; B -21 -14 471 655 ;
-C -1 ; WX 722 ; N Ograve ; B 27 -18 691 904 ;
-C -1 ; WX 667 ; N Egrave ; B -27 0 653 904 ;
-C -1 ; WX 611 ; N Ydieresis ; B 73 0 659 862 ;
-C -1 ; WX 747 ; N registered ; B 30 -18 718 685 ;
-C -1 ; WX 722 ; N Otilde ; B 27 -18 691 862 ;
-C -1 ; WX 750 ; N onequarter ; B 7 -14 721 683 ;
-C -1 ; WX 722 ; N Ugrave ; B 67 -18 744 904 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 67 -18 744 897 ;
-C -1 ; WX 611 ; N Thorn ; B -27 0 573 669 ;
-C -1 ; WX 570 ; N divide ; B 33 -29 537 535 ;
-C -1 ; WX 667 ; N Atilde ; B -67 0 593 862 ;
-C -1 ; WX 722 ; N Uacute ; B 67 -18 744 904 ;
-C -1 ; WX 722 ; N Ocircumflex ; B 27 -18 691 897 ;
-C -1 ; WX 606 ; N logicalnot ; B 51 108 555 399 ;
-C -1 ; WX 667 ; N Aring ; B -67 0 593 921 ;
-C -1 ; WX 278 ; N idieresis ; B 2 -9 360 655 ;
-C -1 ; WX 278 ; N iacute ; B 2 -9 352 697 ;
-C -1 ; WX 500 ; N aacute ; B -21 -14 463 697 ;
-C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ;
-C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ;
-C -1 ; WX 722 ; N Udieresis ; B 67 -18 744 862 ;
-C -1 ; WX 606 ; N minus ; B 51 209 555 297 ;
-C -1 ; WX 300 ; N onesuperior ; B 30 274 301 683 ;
-C -1 ; WX 667 ; N Eacute ; B -27 0 653 904 ;
-C -1 ; WX 667 ; N Acircumflex ; B -67 0 593 897 ;
-C -1 ; WX 747 ; N copyright ; B 30 -18 718 685 ;
-C -1 ; WX 667 ; N Agrave ; B -67 0 593 904 ;
-C -1 ; WX 500 ; N odieresis ; B -3 -13 466 655 ;
-C -1 ; WX 500 ; N oacute ; B -3 -13 463 697 ;
-C -1 ; WX 400 ; N degree ; B 83 397 369 683 ;
-C -1 ; WX 278 ; N igrave ; B 2 -9 260 697 ;
-C -1 ; WX 576 ; N mu ; B -60 -207 516 449 ;
-C -1 ; WX 722 ; N Oacute ; B 27 -18 691 904 ;
-C -1 ; WX 500 ; N eth ; B -3 -13 454 699 ;
-C -1 ; WX 667 ; N Adieresis ; B -67 0 593 862 ;
-C -1 ; WX 611 ; N Yacute ; B 73 0 659 904 ;
-C -1 ; WX 220 ; N brokenbar ; B 66 -18 154 685 ;
-C -1 ; WX 750 ; N onehalf ; B -9 -14 723 683 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 283
-
-KPX A y -74
-KPX A w -74
-KPX A v -74
-KPX A u -30
-KPX A quoteright -74
-KPX A quotedblright 0
-KPX A p 0
-KPX A Y -70
-KPX A W -100
-KPX A V -95
-KPX A U -50
-KPX A T -55
-KPX A Q -55
-KPX A O -50
-KPX A G -60
-KPX A C -65
-
-KPX B period 0
-KPX B comma 0
-KPX B U -10
-KPX B A -25
-
-KPX D period 0
-KPX D comma 0
-KPX D Y -50
-KPX D W -40
-KPX D V -50
-KPX D A -25
-
-KPX F r -50
-KPX F period -129
-KPX F o -70
-KPX F i -40
-KPX F e -100
-KPX F comma -129
-KPX F a -95
-KPX F A -100
-
-KPX G period 0
-KPX G comma 0
-
-KPX J u -40
-KPX J period -10
-KPX J o -40
-KPX J e -40
-KPX J comma -10
-KPX J a -40
-KPX J A -25
-
-KPX K y -20
-KPX K u -20
-KPX K o -25
-KPX K e -25
-KPX K O -30
-
-KPX L y -37
-KPX L quoteright -55
-KPX L quotedblright 0
-KPX L Y -37
-KPX L W -37
-KPX L V -37
-KPX L T -18
-
-KPX N period 0
-KPX N comma 0
-KPX N A -30
-
-KPX O period 0
-KPX O comma 0
-KPX O Y -50
-KPX O X -40
-KPX O W -50
-KPX O V -50
-KPX O T -40
-KPX O A -40
-
-KPX P period -129
-KPX P o -55
-KPX P e -50
-KPX P comma -129
-KPX P a -40
-KPX P A -85
-
-KPX Q period 0
-KPX Q comma 0
-KPX Q U -10
-
-KPX R Y -18
-KPX R W -18
-KPX R V -18
-KPX R U -40
-KPX R T -30
-KPX R O -40
-
-KPX S period 0
-KPX S comma 0
-
-KPX T y -37
-KPX T w -37
-KPX T u -37
-KPX T semicolon -74
-KPX T r -37
-KPX T period -92
-KPX T o -95
-KPX T i -37
-KPX T hyphen -92
-KPX T h 0
-KPX T e -92
-KPX T comma -92
-KPX T colon -74
-KPX T a -92
-KPX T O -18
-KPX T A -55
-
-KPX U period 0
-KPX U comma 0
-KPX U A -45
-
-KPX V u -55
-KPX V semicolon -74
-KPX V period -129
-KPX V o -111
-KPX V i -55
-KPX V hyphen -70
-KPX V e -111
-KPX V comma -129
-KPX V colon -74
-KPX V a -111
-KPX V O -30
-KPX V G -10
-KPX V A -85
-
-KPX W y -55
-KPX W u -55
-KPX W semicolon -55
-KPX W period -74
-KPX W o -80
-KPX W i -37
-KPX W hyphen -50
-KPX W h 0
-KPX W e -90
-KPX W comma -74
-KPX W colon -55
-KPX W a -85
-KPX W O -15
-KPX W A -74
-
-KPX Y u -92
-KPX Y semicolon -92
-KPX Y period -74
-KPX Y o -111
-KPX Y i -55
-KPX Y hyphen -92
-KPX Y e -111
-KPX Y comma -92
-KPX Y colon -92
-KPX Y a -92
-KPX Y O -25
-KPX Y A -74
-
-KPX a y 0
-KPX a w 0
-KPX a v 0
-KPX a t 0
-KPX a p 0
-KPX a g 0
-KPX a b 0
-
-KPX b y 0
-KPX b v 0
-KPX b u -20
-KPX b period -40
-KPX b l 0
-KPX b comma 0
-KPX b b -10
-
-KPX c y 0
-KPX c period 0
-KPX c l 0
-KPX c k -10
-KPX c h -10
-KPX c comma 0
-
-KPX colon space 0
-
-KPX comma space 0
-KPX comma quoteright -95
-KPX comma quotedblright -95
-
-KPX d y 0
-KPX d w 0
-KPX d v 0
-KPX d period 0
-KPX d d 0
-KPX d comma 0
-
-KPX e y 0
-KPX e x 0
-KPX e w 0
-KPX e v 0
-KPX e period 0
-KPX e p 0
-KPX e g 0
-KPX e comma 0
-KPX e b -10
-
-KPX f quoteright 55
-KPX f quotedblright 0
-KPX f period -10
-KPX f o -10
-KPX f l 0
-KPX f i 0
-KPX f f -18
-KPX f e -10
-KPX f dotlessi -30
-KPX f comma -10
-KPX f a 0
-
-KPX g y 0
-KPX g r 0
-KPX g period 0
-KPX g o 0
-KPX g i 0
-KPX g g 0
-KPX g e 0
-KPX g comma 0
-KPX g a 0
-
-KPX h y 0
-
-KPX i v 0
-
-KPX k y 0
-KPX k o -10
-KPX k e -30
-
-KPX l y 0
-KPX l w 0
-
-KPX m y 0
-KPX m u 0
-
-KPX n y 0
-KPX n v -40
-KPX n u 0
-
-KPX o y -10
-KPX o x -10
-KPX o w -25
-KPX o v -15
-KPX o g 0
-
-KPX p y 0
-
-KPX period quoteright -95
-KPX period quotedblright -95
-
-KPX quotedblleft quoteleft 0
-KPX quotedblleft A 0
-
-KPX quotedblright space 0
-
-KPX quoteleft quoteleft -74
-KPX quoteleft A 0
-
-KPX quoteright v -15
-KPX quoteright t -37
-KPX quoteright space -74
-KPX quoteright s -74
-KPX quoteright r -15
-KPX quoteright quoteright -74
-KPX quoteright quotedblright 0
-KPX quoteright l 0
-KPX quoteright d -15
-
-KPX r y 0
-KPX r v 0
-KPX r u 0
-KPX r t 0
-KPX r s 0
-KPX r r 0
-KPX r q 0
-KPX r period -65
-KPX r p 0
-KPX r o 0
-KPX r n 0
-KPX r m 0
-KPX r l 0
-KPX r k 0
-KPX r i 0
-KPX r hyphen 0
-KPX r g 0
-KPX r e 0
-KPX r d 0
-KPX r comma -65
-KPX r c 0
-KPX r a 0
-
-KPX s w 0
-
-KPX space quoteleft 0
-KPX space quotedblleft 0
-KPX space Y -70
-KPX space W -70
-KPX space V -70
-KPX space T 0
-KPX space A -37
-
-KPX v period -37
-KPX v o -15
-KPX v e -15
-KPX v comma -37
-KPX v a 0
-
-KPX w period -37
-KPX w o -15
-KPX w h 0
-KPX w e -10
-KPX w comma -37
-KPX w a -10
-
-KPX x e -10
-
-KPX y period -37
-KPX y o 0
-KPX y e 0
-KPX y comma -37
-KPX y a 0
-
-KPX z o 0
-KPX z e 0
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 172 207 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 187 207 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 167 207 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 172 207 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 157 192 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 167 207 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 172 207 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 187 207 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 187 207 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 172 207 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 33 207 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 53 207 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 48 207 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 33 207 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 210 207 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 200 207 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 230 207 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 215 207 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 200 207 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 207 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 207 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 210 207 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 230 207 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 230 207 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 200 207 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 154 207 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 169 207 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 207 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 84 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 84 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 74 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 74 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 84 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 46 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 46 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -42 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -37 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -37 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 97 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 69 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 74 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 112 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 112 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 97 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 102 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 41 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 13 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/ptmr8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/ptmr8a.afm
deleted file mode 100644
index e5092b5c85..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/ptmr8a.afm
+++ /dev/null
@@ -1,648 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Tue Mar 20 12:15:44 1990
-Comment UniqueID 28416
-Comment VMusage 30487 37379
-FontName Times-Roman
-FullName Times Roman
-FamilyName Times
-Weight Roman
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -168 -218 1000 898
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.007
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 662
-XHeight 450
-Ascender 683
-Descender -217
-StartCharMetrics 228
-C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 130 -9 238 676 ;
-C 34 ; WX 408 ; N quotedbl ; B 77 431 331 676 ;
-C 35 ; WX 500 ; N numbersign ; B 5 0 496 662 ;
-C 36 ; WX 500 ; N dollar ; B 44 -87 457 727 ;
-C 37 ; WX 833 ; N percent ; B 61 -13 772 676 ;
-C 38 ; WX 778 ; N ampersand ; B 42 -13 750 676 ;
-C 39 ; WX 333 ; N quoteright ; B 79 433 218 676 ;
-C 40 ; WX 333 ; N parenleft ; B 48 -177 304 676 ;
-C 41 ; WX 333 ; N parenright ; B 29 -177 285 676 ;
-C 42 ; WX 500 ; N asterisk ; B 69 265 432 676 ;
-C 43 ; WX 564 ; N plus ; B 30 0 534 506 ;
-C 44 ; WX 250 ; N comma ; B 56 -141 195 102 ;
-C 45 ; WX 333 ; N hyphen ; B 39 194 285 257 ;
-C 46 ; WX 250 ; N period ; B 70 -11 181 100 ;
-C 47 ; WX 278 ; N slash ; B -9 -14 287 676 ;
-C 48 ; WX 500 ; N zero ; B 24 -14 476 676 ;
-C 49 ; WX 500 ; N one ; B 111 0 394 676 ;
-C 50 ; WX 500 ; N two ; B 30 0 475 676 ;
-C 51 ; WX 500 ; N three ; B 43 -14 431 676 ;
-C 52 ; WX 500 ; N four ; B 12 0 472 676 ;
-C 53 ; WX 500 ; N five ; B 32 -14 438 688 ;
-C 54 ; WX 500 ; N six ; B 34 -14 468 684 ;
-C 55 ; WX 500 ; N seven ; B 20 -8 449 662 ;
-C 56 ; WX 500 ; N eight ; B 56 -14 445 676 ;
-C 57 ; WX 500 ; N nine ; B 30 -22 459 676 ;
-C 58 ; WX 278 ; N colon ; B 81 -11 192 459 ;
-C 59 ; WX 278 ; N semicolon ; B 80 -141 219 459 ;
-C 60 ; WX 564 ; N less ; B 28 -8 536 514 ;
-C 61 ; WX 564 ; N equal ; B 30 120 534 386 ;
-C 62 ; WX 564 ; N greater ; B 28 -8 536 514 ;
-C 63 ; WX 444 ; N question ; B 68 -8 414 676 ;
-C 64 ; WX 921 ; N at ; B 116 -14 809 676 ;
-C 65 ; WX 722 ; N A ; B 15 0 706 674 ;
-C 66 ; WX 667 ; N B ; B 17 0 593 662 ;
-C 67 ; WX 667 ; N C ; B 28 -14 633 676 ;
-C 68 ; WX 722 ; N D ; B 16 0 685 662 ;
-C 69 ; WX 611 ; N E ; B 12 0 597 662 ;
-C 70 ; WX 556 ; N F ; B 12 0 546 662 ;
-C 71 ; WX 722 ; N G ; B 32 -14 709 676 ;
-C 72 ; WX 722 ; N H ; B 19 0 702 662 ;
-C 73 ; WX 333 ; N I ; B 18 0 315 662 ;
-C 74 ; WX 389 ; N J ; B 10 -14 370 662 ;
-C 75 ; WX 722 ; N K ; B 34 0 723 662 ;
-C 76 ; WX 611 ; N L ; B 12 0 598 662 ;
-C 77 ; WX 889 ; N M ; B 12 0 863 662 ;
-C 78 ; WX 722 ; N N ; B 12 -11 707 662 ;
-C 79 ; WX 722 ; N O ; B 34 -14 688 676 ;
-C 80 ; WX 556 ; N P ; B 16 0 542 662 ;
-C 81 ; WX 722 ; N Q ; B 34 -178 701 676 ;
-C 82 ; WX 667 ; N R ; B 17 0 659 662 ;
-C 83 ; WX 556 ; N S ; B 42 -14 491 676 ;
-C 84 ; WX 611 ; N T ; B 17 0 593 662 ;
-C 85 ; WX 722 ; N U ; B 14 -14 705 662 ;
-C 86 ; WX 722 ; N V ; B 16 -11 697 662 ;
-C 87 ; WX 944 ; N W ; B 5 -11 932 662 ;
-C 88 ; WX 722 ; N X ; B 10 0 704 662 ;
-C 89 ; WX 722 ; N Y ; B 22 0 703 662 ;
-C 90 ; WX 611 ; N Z ; B 9 0 597 662 ;
-C 91 ; WX 333 ; N bracketleft ; B 88 -156 299 662 ;
-C 92 ; WX 278 ; N backslash ; B -9 -14 287 676 ;
-C 93 ; WX 333 ; N bracketright ; B 34 -156 245 662 ;
-C 94 ; WX 469 ; N asciicircum ; B 24 297 446 662 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 333 ; N quoteleft ; B 115 433 254 676 ;
-C 97 ; WX 444 ; N a ; B 37 -10 442 460 ;
-C 98 ; WX 500 ; N b ; B 3 -10 468 683 ;
-C 99 ; WX 444 ; N c ; B 25 -10 412 460 ;
-C 100 ; WX 500 ; N d ; B 27 -10 491 683 ;
-C 101 ; WX 444 ; N e ; B 25 -10 424 460 ;
-C 102 ; WX 333 ; N f ; B 20 0 383 683 ; L i fi ; L l fl ;
-C 103 ; WX 500 ; N g ; B 28 -218 470 460 ;
-C 104 ; WX 500 ; N h ; B 9 0 487 683 ;
-C 105 ; WX 278 ; N i ; B 16 0 253 683 ;
-C 106 ; WX 278 ; N j ; B -70 -218 194 683 ;
-C 107 ; WX 500 ; N k ; B 7 0 505 683 ;
-C 108 ; WX 278 ; N l ; B 19 0 257 683 ;
-C 109 ; WX 778 ; N m ; B 16 0 775 460 ;
-C 110 ; WX 500 ; N n ; B 16 0 485 460 ;
-C 111 ; WX 500 ; N o ; B 29 -10 470 460 ;
-C 112 ; WX 500 ; N p ; B 5 -217 470 460 ;
-C 113 ; WX 500 ; N q ; B 24 -217 488 460 ;
-C 114 ; WX 333 ; N r ; B 5 0 335 460 ;
-C 115 ; WX 389 ; N s ; B 51 -10 348 460 ;
-C 116 ; WX 278 ; N t ; B 13 -10 279 579 ;
-C 117 ; WX 500 ; N u ; B 9 -10 479 450 ;
-C 118 ; WX 500 ; N v ; B 19 -14 477 450 ;
-C 119 ; WX 722 ; N w ; B 21 -14 694 450 ;
-C 120 ; WX 500 ; N x ; B 17 0 479 450 ;
-C 121 ; WX 500 ; N y ; B 14 -218 475 450 ;
-C 122 ; WX 444 ; N z ; B 27 0 418 450 ;
-C 123 ; WX 480 ; N braceleft ; B 100 -181 350 680 ;
-C 124 ; WX 200 ; N bar ; B 67 -14 133 676 ;
-C 125 ; WX 480 ; N braceright ; B 130 -181 380 680 ;
-C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ;
-C 161 ; WX 333 ; N exclamdown ; B 97 -218 205 467 ;
-C 162 ; WX 500 ; N cent ; B 53 -138 448 579 ;
-C 163 ; WX 500 ; N sterling ; B 12 -8 490 676 ;
-C 164 ; WX 167 ; N fraction ; B -168 -14 331 676 ;
-C 165 ; WX 500 ; N yen ; B -53 0 512 662 ;
-C 166 ; WX 500 ; N florin ; B 7 -189 490 676 ;
-C 167 ; WX 500 ; N section ; B 70 -148 426 676 ;
-C 168 ; WX 500 ; N currency ; B -22 58 522 602 ;
-C 169 ; WX 180 ; N quotesingle ; B 48 431 133 676 ;
-C 170 ; WX 444 ; N quotedblleft ; B 43 433 414 676 ;
-C 171 ; WX 500 ; N guillemotleft ; B 42 33 456 416 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 63 33 285 416 ;
-C 173 ; WX 333 ; N guilsinglright ; B 48 33 270 416 ;
-C 174 ; WX 556 ; N fi ; B 31 0 521 683 ;
-C 175 ; WX 556 ; N fl ; B 32 0 521 683 ;
-C 177 ; WX 500 ; N endash ; B 0 201 500 250 ;
-C 178 ; WX 500 ; N dagger ; B 59 -149 442 676 ;
-C 179 ; WX 500 ; N daggerdbl ; B 58 -153 442 676 ;
-C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ;
-C 182 ; WX 453 ; N paragraph ; B -22 -154 450 662 ;
-C 183 ; WX 350 ; N bullet ; B 40 196 310 466 ;
-C 184 ; WX 333 ; N quotesinglbase ; B 79 -141 218 102 ;
-C 185 ; WX 444 ; N quotedblbase ; B 45 -141 416 102 ;
-C 186 ; WX 444 ; N quotedblright ; B 30 433 401 676 ;
-C 187 ; WX 500 ; N guillemotright ; B 44 33 458 416 ;
-C 188 ; WX 1000 ; N ellipsis ; B 111 -11 888 100 ;
-C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 706 ;
-C 191 ; WX 444 ; N questiondown ; B 30 -218 376 466 ;
-C 193 ; WX 333 ; N grave ; B 19 507 242 678 ;
-C 194 ; WX 333 ; N acute ; B 93 507 317 678 ;
-C 195 ; WX 333 ; N circumflex ; B 11 507 322 674 ;
-C 196 ; WX 333 ; N tilde ; B 1 532 331 638 ;
-C 197 ; WX 333 ; N macron ; B 11 547 322 601 ;
-C 198 ; WX 333 ; N breve ; B 26 507 307 664 ;
-C 199 ; WX 333 ; N dotaccent ; B 118 523 216 623 ;
-C 200 ; WX 333 ; N dieresis ; B 18 523 315 623 ;
-C 202 ; WX 333 ; N ring ; B 67 512 266 711 ;
-C 203 ; WX 333 ; N cedilla ; B 52 -215 261 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B -3 507 377 678 ;
-C 206 ; WX 333 ; N ogonek ; B 64 -165 249 0 ;
-C 207 ; WX 333 ; N caron ; B 11 507 322 674 ;
-C 208 ; WX 1000 ; N emdash ; B 0 201 1000 250 ;
-C 225 ; WX 889 ; N AE ; B 0 0 863 662 ;
-C 227 ; WX 276 ; N ordfeminine ; B 4 394 270 676 ;
-C 232 ; WX 611 ; N Lslash ; B 12 0 598 662 ;
-C 233 ; WX 722 ; N Oslash ; B 34 -80 688 734 ;
-C 234 ; WX 889 ; N OE ; B 30 -6 885 668 ;
-C 235 ; WX 310 ; N ordmasculine ; B 6 394 304 676 ;
-C 241 ; WX 667 ; N ae ; B 38 -10 632 460 ;
-C 245 ; WX 278 ; N dotlessi ; B 16 0 253 460 ;
-C 248 ; WX 278 ; N lslash ; B 19 0 259 683 ;
-C 249 ; WX 500 ; N oslash ; B 29 -112 470 551 ;
-C 250 ; WX 722 ; N oe ; B 30 -10 690 460 ;
-C 251 ; WX 500 ; N germandbls ; B 12 -9 468 683 ;
-C -1 ; WX 611 ; N Zcaron ; B 9 0 597 886 ;
-C -1 ; WX 444 ; N ccedilla ; B 25 -215 412 460 ;
-C -1 ; WX 500 ; N ydieresis ; B 14 -218 475 623 ;
-C -1 ; WX 444 ; N atilde ; B 37 -10 442 638 ;
-C -1 ; WX 278 ; N icircumflex ; B -16 0 295 674 ;
-C -1 ; WX 300 ; N threesuperior ; B 15 262 291 676 ;
-C -1 ; WX 444 ; N ecircumflex ; B 25 -10 424 674 ;
-C -1 ; WX 500 ; N thorn ; B 5 -217 470 683 ;
-C -1 ; WX 444 ; N egrave ; B 25 -10 424 678 ;
-C -1 ; WX 300 ; N twosuperior ; B 1 270 296 676 ;
-C -1 ; WX 444 ; N eacute ; B 25 -10 424 678 ;
-C -1 ; WX 500 ; N otilde ; B 29 -10 470 638 ;
-C -1 ; WX 722 ; N Aacute ; B 15 0 706 890 ;
-C -1 ; WX 500 ; N ocircumflex ; B 29 -10 470 674 ;
-C -1 ; WX 500 ; N yacute ; B 14 -218 475 678 ;
-C -1 ; WX 500 ; N udieresis ; B 9 -10 479 623 ;
-C -1 ; WX 750 ; N threequarters ; B 15 -14 718 676 ;
-C -1 ; WX 444 ; N acircumflex ; B 37 -10 442 674 ;
-C -1 ; WX 722 ; N Eth ; B 16 0 685 662 ;
-C -1 ; WX 444 ; N edieresis ; B 25 -10 424 623 ;
-C -1 ; WX 500 ; N ugrave ; B 9 -10 479 678 ;
-C -1 ; WX 980 ; N trademark ; B 30 256 957 662 ;
-C -1 ; WX 500 ; N ograve ; B 29 -10 470 678 ;
-C -1 ; WX 389 ; N scaron ; B 39 -10 350 674 ;
-C -1 ; WX 333 ; N Idieresis ; B 18 0 315 835 ;
-C -1 ; WX 500 ; N uacute ; B 9 -10 479 678 ;
-C -1 ; WX 444 ; N agrave ; B 37 -10 442 678 ;
-C -1 ; WX 500 ; N ntilde ; B 16 0 485 638 ;
-C -1 ; WX 444 ; N aring ; B 37 -10 442 711 ;
-C -1 ; WX 444 ; N zcaron ; B 27 0 418 674 ;
-C -1 ; WX 333 ; N Icircumflex ; B 11 0 322 886 ;
-C -1 ; WX 722 ; N Ntilde ; B 12 -11 707 850 ;
-C -1 ; WX 500 ; N ucircumflex ; B 9 -10 479 674 ;
-C -1 ; WX 611 ; N Ecircumflex ; B 12 0 597 886 ;
-C -1 ; WX 333 ; N Iacute ; B 18 0 317 890 ;
-C -1 ; WX 667 ; N Ccedilla ; B 28 -215 633 676 ;
-C -1 ; WX 722 ; N Odieresis ; B 34 -14 688 835 ;
-C -1 ; WX 556 ; N Scaron ; B 42 -14 491 886 ;
-C -1 ; WX 611 ; N Edieresis ; B 12 0 597 835 ;
-C -1 ; WX 333 ; N Igrave ; B 18 0 315 890 ;
-C -1 ; WX 444 ; N adieresis ; B 37 -10 442 623 ;
-C -1 ; WX 722 ; N Ograve ; B 34 -14 688 890 ;
-C -1 ; WX 611 ; N Egrave ; B 12 0 597 890 ;
-C -1 ; WX 722 ; N Ydieresis ; B 22 0 703 835 ;
-C -1 ; WX 760 ; N registered ; B 38 -14 722 676 ;
-C -1 ; WX 722 ; N Otilde ; B 34 -14 688 850 ;
-C -1 ; WX 750 ; N onequarter ; B 37 -14 718 676 ;
-C -1 ; WX 722 ; N Ugrave ; B 14 -14 705 890 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 14 -14 705 886 ;
-C -1 ; WX 556 ; N Thorn ; B 16 0 542 662 ;
-C -1 ; WX 564 ; N divide ; B 30 -10 534 516 ;
-C -1 ; WX 722 ; N Atilde ; B 15 0 706 850 ;
-C -1 ; WX 722 ; N Uacute ; B 14 -14 705 890 ;
-C -1 ; WX 722 ; N Ocircumflex ; B 34 -14 688 886 ;
-C -1 ; WX 564 ; N logicalnot ; B 30 108 534 386 ;
-C -1 ; WX 722 ; N Aring ; B 15 0 706 898 ;
-C -1 ; WX 278 ; N idieresis ; B -9 0 288 623 ;
-C -1 ; WX 278 ; N iacute ; B 16 0 290 678 ;
-C -1 ; WX 444 ; N aacute ; B 37 -10 442 678 ;
-C -1 ; WX 564 ; N plusminus ; B 30 0 534 506 ;
-C -1 ; WX 564 ; N multiply ; B 38 8 527 497 ;
-C -1 ; WX 722 ; N Udieresis ; B 14 -14 705 835 ;
-C -1 ; WX 564 ; N minus ; B 30 220 534 286 ;
-C -1 ; WX 300 ; N onesuperior ; B 57 270 248 676 ;
-C -1 ; WX 611 ; N Eacute ; B 12 0 597 890 ;
-C -1 ; WX 722 ; N Acircumflex ; B 15 0 706 886 ;
-C -1 ; WX 760 ; N copyright ; B 38 -14 722 676 ;
-C -1 ; WX 722 ; N Agrave ; B 15 0 706 890 ;
-C -1 ; WX 500 ; N odieresis ; B 29 -10 470 623 ;
-C -1 ; WX 500 ; N oacute ; B 29 -10 470 678 ;
-C -1 ; WX 400 ; N degree ; B 57 390 343 676 ;
-C -1 ; WX 278 ; N igrave ; B -8 0 253 678 ;
-C -1 ; WX 500 ; N mu ; B 36 -218 512 450 ;
-C -1 ; WX 722 ; N Oacute ; B 34 -14 688 890 ;
-C -1 ; WX 500 ; N eth ; B 29 -10 471 686 ;
-C -1 ; WX 722 ; N Adieresis ; B 15 0 706 835 ;
-C -1 ; WX 722 ; N Yacute ; B 22 0 703 890 ;
-C -1 ; WX 200 ; N brokenbar ; B 67 -14 133 676 ;
-C -1 ; WX 750 ; N onehalf ; B 31 -14 746 676 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 283
-
-KPX A y -92
-KPX A w -92
-KPX A v -74
-KPX A u 0
-KPX A quoteright -111
-KPX A quotedblright 0
-KPX A p 0
-KPX A Y -105
-KPX A W -90
-KPX A V -135
-KPX A U -55
-KPX A T -111
-KPX A Q -55
-KPX A O -55
-KPX A G -40
-KPX A C -40
-
-KPX B period 0
-KPX B comma 0
-KPX B U -10
-KPX B A -35
-
-KPX D period 0
-KPX D comma 0
-KPX D Y -55
-KPX D W -30
-KPX D V -40
-KPX D A -40
-
-KPX F r 0
-KPX F period -80
-KPX F o -15
-KPX F i 0
-KPX F e 0
-KPX F comma -80
-KPX F a -15
-KPX F A -74
-
-KPX G period 0
-KPX G comma 0
-
-KPX J u 0
-KPX J period 0
-KPX J o 0
-KPX J e 0
-KPX J comma 0
-KPX J a 0
-KPX J A -60
-
-KPX K y -25
-KPX K u -15
-KPX K o -35
-KPX K e -25
-KPX K O -30
-
-KPX L y -55
-KPX L quoteright -92
-KPX L quotedblright 0
-KPX L Y -100
-KPX L W -74
-KPX L V -100
-KPX L T -92
-
-KPX N period 0
-KPX N comma 0
-KPX N A -35
-
-KPX O period 0
-KPX O comma 0
-KPX O Y -50
-KPX O X -40
-KPX O W -35
-KPX O V -50
-KPX O T -40
-KPX O A -35
-
-KPX P period -111
-KPX P o 0
-KPX P e 0
-KPX P comma -111
-KPX P a -15
-KPX P A -92
-
-KPX Q period 0
-KPX Q comma 0
-KPX Q U -10
-
-KPX R Y -65
-KPX R W -55
-KPX R V -80
-KPX R U -40
-KPX R T -60
-KPX R O -40
-
-KPX S period 0
-KPX S comma 0
-
-KPX T y -80
-KPX T w -80
-KPX T u -45
-KPX T semicolon -55
-KPX T r -35
-KPX T period -74
-KPX T o -80
-KPX T i -35
-KPX T hyphen -92
-KPX T h 0
-KPX T e -70
-KPX T comma -74
-KPX T colon -50
-KPX T a -80
-KPX T O -18
-KPX T A -93
-
-KPX U period 0
-KPX U comma 0
-KPX U A -40
-
-KPX V u -75
-KPX V semicolon -74
-KPX V period -129
-KPX V o -129
-KPX V i -60
-KPX V hyphen -100
-KPX V e -111
-KPX V comma -129
-KPX V colon -74
-KPX V a -111
-KPX V O -40
-KPX V G -15
-KPX V A -135
-
-KPX W y -73
-KPX W u -50
-KPX W semicolon -37
-KPX W period -92
-KPX W o -80
-KPX W i -40
-KPX W hyphen -65
-KPX W h 0
-KPX W e -80
-KPX W comma -92
-KPX W colon -37
-KPX W a -80
-KPX W O -10
-KPX W A -120
-
-KPX Y u -111
-KPX Y semicolon -92
-KPX Y period -129
-KPX Y o -110
-KPX Y i -55
-KPX Y hyphen -111
-KPX Y e -100
-KPX Y comma -129
-KPX Y colon -92
-KPX Y a -100
-KPX Y O -30
-KPX Y A -120
-
-KPX a y 0
-KPX a w -15
-KPX a v -20
-KPX a t 0
-KPX a p 0
-KPX a g 0
-KPX a b 0
-
-KPX b y 0
-KPX b v -15
-KPX b u -20
-KPX b period -40
-KPX b l 0
-KPX b comma 0
-KPX b b 0
-
-KPX c y -15
-KPX c period 0
-KPX c l 0
-KPX c k 0
-KPX c h 0
-KPX c comma 0
-
-KPX colon space 0
-
-KPX comma space 0
-KPX comma quoteright -70
-KPX comma quotedblright -70
-
-KPX d y 0
-KPX d w 0
-KPX d v 0
-KPX d period 0
-KPX d d 0
-KPX d comma 0
-
-KPX e y -15
-KPX e x -15
-KPX e w -25
-KPX e v -25
-KPX e period 0
-KPX e p 0
-KPX e g -15
-KPX e comma 0
-KPX e b 0
-
-KPX f quoteright 55
-KPX f quotedblright 0
-KPX f period 0
-KPX f o 0
-KPX f l 0
-KPX f i -20
-KPX f f -25
-KPX f e 0
-KPX f dotlessi -50
-KPX f comma 0
-KPX f a -10
-
-KPX g y 0
-KPX g r 0
-KPX g period 0
-KPX g o 0
-KPX g i 0
-KPX g g 0
-KPX g e 0
-KPX g comma 0
-KPX g a -5
-
-KPX h y -5
-
-KPX i v -25
-
-KPX k y -15
-KPX k o -10
-KPX k e -10
-
-KPX l y 0
-KPX l w -10
-
-KPX m y 0
-KPX m u 0
-
-KPX n y -15
-KPX n v -40
-KPX n u 0
-
-KPX o y -10
-KPX o x 0
-KPX o w -25
-KPX o v -15
-KPX o g 0
-
-KPX p y -10
-
-KPX period quoteright -70
-KPX period quotedblright -70
-
-KPX quotedblleft quoteleft 0
-KPX quotedblleft A -80
-
-KPX quotedblright space 0
-
-KPX quoteleft quoteleft -74
-KPX quoteleft A -80
-
-KPX quoteright v -50
-KPX quoteright t -18
-KPX quoteright space -74
-KPX quoteright s -55
-KPX quoteright r -50
-KPX quoteright quoteright -74
-KPX quoteright quotedblright 0
-KPX quoteright l -10
-KPX quoteright d -50
-
-KPX r y 0
-KPX r v 0
-KPX r u 0
-KPX r t 0
-KPX r s 0
-KPX r r 0
-KPX r q 0
-KPX r period -55
-KPX r p 0
-KPX r o 0
-KPX r n 0
-KPX r m 0
-KPX r l 0
-KPX r k 0
-KPX r i 0
-KPX r hyphen -20
-KPX r g -18
-KPX r e 0
-KPX r d 0
-KPX r comma -40
-KPX r c 0
-KPX r a 0
-
-KPX s w 0
-
-KPX space quoteleft 0
-KPX space quotedblleft 0
-KPX space Y -90
-KPX space W -30
-KPX space V -50
-KPX space T -18
-KPX space A -55
-
-KPX v period -65
-KPX v o -20
-KPX v e -15
-KPX v comma -65
-KPX v a -25
-
-KPX w period -65
-KPX w o -10
-KPX w h 0
-KPX w e 0
-KPX w comma -65
-KPX w a -10
-
-KPX x e -15
-
-KPX y period -65
-KPX y o 0
-KPX y e 0
-KPX y comma -65
-KPX y a 0
-
-KPX z o 0
-KPX z e 0
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 195 212 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 195 212 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 195 212 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 195 212 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 185 187 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 195 212 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 139 212 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 139 212 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 139 212 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 139 212 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 0 212 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 0 212 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 0 212 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 0 212 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 195 212 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 195 212 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 195 212 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 195 212 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 195 212 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 195 212 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 112 212 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 212 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 195 212 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 195 212 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 195 212 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 195 212 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 195 212 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 139 212 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 56 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 56 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 56 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 56 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 56 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 56 0 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 56 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -27 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -27 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -27 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 84 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 84 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 84 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 84 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 84 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 84 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 84 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 84 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 56 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/ptmri8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/ptmri8a.afm
deleted file mode 100644
index 6d7a003ba8..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/ptmri8a.afm
+++ /dev/null
@@ -1,648 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Tue Mar 20 13:14:56 1990
-Comment UniqueID 28427
-Comment VMusage 32912 39804
-FontName Times-Italic
-FullName Times Italic
-FamilyName Times
-Weight Medium
-ItalicAngle -15.5
-IsFixedPitch false
-FontBBox -169 -217 1010 883
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.007
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 653
-XHeight 441
-Ascender 683
-Descender -205
-StartCharMetrics 228
-C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 39 -11 302 667 ;
-C 34 ; WX 420 ; N quotedbl ; B 144 421 432 666 ;
-C 35 ; WX 500 ; N numbersign ; B 2 0 540 676 ;
-C 36 ; WX 500 ; N dollar ; B 31 -89 497 731 ;
-C 37 ; WX 833 ; N percent ; B 79 -13 790 676 ;
-C 38 ; WX 778 ; N ampersand ; B 76 -18 723 666 ;
-C 39 ; WX 333 ; N quoteright ; B 151 436 290 666 ;
-C 40 ; WX 333 ; N parenleft ; B 42 -181 315 669 ;
-C 41 ; WX 333 ; N parenright ; B 16 -180 289 669 ;
-C 42 ; WX 500 ; N asterisk ; B 128 255 492 666 ;
-C 43 ; WX 675 ; N plus ; B 86 0 590 506 ;
-C 44 ; WX 250 ; N comma ; B -4 -129 135 101 ;
-C 45 ; WX 333 ; N hyphen ; B 49 192 282 255 ;
-C 46 ; WX 250 ; N period ; B 27 -11 138 100 ;
-C 47 ; WX 278 ; N slash ; B -65 -18 386 666 ;
-C 48 ; WX 500 ; N zero ; B 32 -7 497 676 ;
-C 49 ; WX 500 ; N one ; B 49 0 409 676 ;
-C 50 ; WX 500 ; N two ; B 12 0 452 676 ;
-C 51 ; WX 500 ; N three ; B 15 -7 465 676 ;
-C 52 ; WX 500 ; N four ; B 1 0 479 676 ;
-C 53 ; WX 500 ; N five ; B 15 -7 491 666 ;
-C 54 ; WX 500 ; N six ; B 30 -7 521 686 ;
-C 55 ; WX 500 ; N seven ; B 75 -8 537 666 ;
-C 56 ; WX 500 ; N eight ; B 30 -7 493 676 ;
-C 57 ; WX 500 ; N nine ; B 23 -17 492 676 ;
-C 58 ; WX 333 ; N colon ; B 50 -11 261 441 ;
-C 59 ; WX 333 ; N semicolon ; B 27 -129 261 441 ;
-C 60 ; WX 675 ; N less ; B 84 -8 592 514 ;
-C 61 ; WX 675 ; N equal ; B 86 120 590 386 ;
-C 62 ; WX 675 ; N greater ; B 84 -8 592 514 ;
-C 63 ; WX 500 ; N question ; B 132 -12 472 664 ;
-C 64 ; WX 920 ; N at ; B 118 -18 806 666 ;
-C 65 ; WX 611 ; N A ; B -51 0 564 668 ;
-C 66 ; WX 611 ; N B ; B -8 0 588 653 ;
-C 67 ; WX 667 ; N C ; B 66 -18 689 666 ;
-C 68 ; WX 722 ; N D ; B -8 0 700 653 ;
-C 69 ; WX 611 ; N E ; B -1 0 634 653 ;
-C 70 ; WX 611 ; N F ; B 8 0 645 653 ;
-C 71 ; WX 722 ; N G ; B 52 -18 722 666 ;
-C 72 ; WX 722 ; N H ; B -8 0 767 653 ;
-C 73 ; WX 333 ; N I ; B -8 0 384 653 ;
-C 74 ; WX 444 ; N J ; B -6 -18 491 653 ;
-C 75 ; WX 667 ; N K ; B 7 0 722 653 ;
-C 76 ; WX 556 ; N L ; B -8 0 559 653 ;
-C 77 ; WX 833 ; N M ; B -18 0 873 653 ;
-C 78 ; WX 667 ; N N ; B -20 -15 727 653 ;
-C 79 ; WX 722 ; N O ; B 60 -18 699 666 ;
-C 80 ; WX 611 ; N P ; B 0 0 605 653 ;
-C 81 ; WX 722 ; N Q ; B 59 -182 699 666 ;
-C 82 ; WX 611 ; N R ; B -13 0 588 653 ;
-C 83 ; WX 500 ; N S ; B 17 -18 508 667 ;
-C 84 ; WX 556 ; N T ; B 59 0 633 653 ;
-C 85 ; WX 722 ; N U ; B 102 -18 765 653 ;
-C 86 ; WX 611 ; N V ; B 76 -18 688 653 ;
-C 87 ; WX 833 ; N W ; B 71 -18 906 653 ;
-C 88 ; WX 611 ; N X ; B -29 0 655 653 ;
-C 89 ; WX 556 ; N Y ; B 78 0 633 653 ;
-C 90 ; WX 556 ; N Z ; B -6 0 606 653 ;
-C 91 ; WX 389 ; N bracketleft ; B 21 -153 391 663 ;
-C 92 ; WX 278 ; N backslash ; B -41 -18 319 666 ;
-C 93 ; WX 389 ; N bracketright ; B 12 -153 382 663 ;
-C 94 ; WX 422 ; N asciicircum ; B 0 301 422 666 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 333 ; N quoteleft ; B 171 436 310 666 ;
-C 97 ; WX 500 ; N a ; B 17 -11 476 441 ;
-C 98 ; WX 500 ; N b ; B 23 -11 473 683 ;
-C 99 ; WX 444 ; N c ; B 30 -11 425 441 ;
-C 100 ; WX 500 ; N d ; B 15 -13 527 683 ;
-C 101 ; WX 444 ; N e ; B 31 -11 412 441 ;
-C 102 ; WX 278 ; N f ; B -147 -207 424 678 ; L i fi ; L l fl ;
-C 103 ; WX 500 ; N g ; B 8 -206 472 441 ;
-C 104 ; WX 500 ; N h ; B 19 -9 478 683 ;
-C 105 ; WX 278 ; N i ; B 49 -11 264 654 ;
-C 106 ; WX 278 ; N j ; B -124 -207 276 654 ;
-C 107 ; WX 444 ; N k ; B 14 -11 461 683 ;
-C 108 ; WX 278 ; N l ; B 41 -11 279 683 ;
-C 109 ; WX 722 ; N m ; B 12 -9 704 441 ;
-C 110 ; WX 500 ; N n ; B 14 -9 474 441 ;
-C 111 ; WX 500 ; N o ; B 27 -11 468 441 ;
-C 112 ; WX 500 ; N p ; B -75 -205 469 441 ;
-C 113 ; WX 500 ; N q ; B 25 -209 483 441 ;
-C 114 ; WX 389 ; N r ; B 45 0 412 441 ;
-C 115 ; WX 389 ; N s ; B 16 -13 366 442 ;
-C 116 ; WX 278 ; N t ; B 37 -11 296 546 ;
-C 117 ; WX 500 ; N u ; B 42 -11 475 441 ;
-C 118 ; WX 444 ; N v ; B 21 -18 426 441 ;
-C 119 ; WX 667 ; N w ; B 16 -18 648 441 ;
-C 120 ; WX 444 ; N x ; B -27 -11 447 441 ;
-C 121 ; WX 444 ; N y ; B -24 -206 426 441 ;
-C 122 ; WX 389 ; N z ; B -2 -81 380 428 ;
-C 123 ; WX 400 ; N braceleft ; B 51 -177 407 687 ;
-C 124 ; WX 275 ; N bar ; B 105 -18 171 666 ;
-C 125 ; WX 400 ; N braceright ; B -7 -177 349 687 ;
-C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ;
-C 161 ; WX 389 ; N exclamdown ; B 59 -205 322 473 ;
-C 162 ; WX 500 ; N cent ; B 77 -143 472 560 ;
-C 163 ; WX 500 ; N sterling ; B 10 -6 517 670 ;
-C 164 ; WX 167 ; N fraction ; B -169 -10 337 676 ;
-C 165 ; WX 500 ; N yen ; B 27 0 603 653 ;
-C 166 ; WX 500 ; N florin ; B 25 -182 507 682 ;
-C 167 ; WX 500 ; N section ; B 53 -162 461 666 ;
-C 168 ; WX 500 ; N currency ; B -22 53 522 597 ;
-C 169 ; WX 214 ; N quotesingle ; B 132 421 241 666 ;
-C 170 ; WX 556 ; N quotedblleft ; B 166 436 514 666 ;
-C 171 ; WX 500 ; N guillemotleft ; B 53 37 445 403 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 51 37 281 403 ;
-C 173 ; WX 333 ; N guilsinglright ; B 52 37 282 403 ;
-C 174 ; WX 500 ; N fi ; B -141 -207 481 681 ;
-C 175 ; WX 500 ; N fl ; B -141 -204 518 682 ;
-C 177 ; WX 500 ; N endash ; B -6 197 505 243 ;
-C 178 ; WX 500 ; N dagger ; B 101 -159 488 666 ;
-C 179 ; WX 500 ; N daggerdbl ; B 22 -143 491 666 ;
-C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ;
-C 182 ; WX 523 ; N paragraph ; B 55 -123 616 653 ;
-C 183 ; WX 350 ; N bullet ; B 40 191 310 461 ;
-C 184 ; WX 333 ; N quotesinglbase ; B 44 -129 183 101 ;
-C 185 ; WX 556 ; N quotedblbase ; B 57 -129 405 101 ;
-C 186 ; WX 556 ; N quotedblright ; B 151 436 499 666 ;
-C 187 ; WX 500 ; N guillemotright ; B 55 37 447 403 ;
-C 188 ; WX 889 ; N ellipsis ; B 57 -11 762 100 ;
-C 189 ; WX 1000 ; N perthousand ; B 25 -19 1010 706 ;
-C 191 ; WX 500 ; N questiondown ; B 28 -205 368 471 ;
-C 193 ; WX 333 ; N grave ; B 121 492 311 664 ;
-C 194 ; WX 333 ; N acute ; B 180 494 403 664 ;
-C 195 ; WX 333 ; N circumflex ; B 91 492 385 661 ;
-C 196 ; WX 333 ; N tilde ; B 100 517 427 624 ;
-C 197 ; WX 333 ; N macron ; B 99 532 411 583 ;
-C 198 ; WX 333 ; N breve ; B 117 492 418 650 ;
-C 199 ; WX 333 ; N dotaccent ; B 207 508 305 606 ;
-C 200 ; WX 333 ; N dieresis ; B 107 508 405 606 ;
-C 202 ; WX 333 ; N ring ; B 155 492 355 691 ;
-C 203 ; WX 333 ; N cedilla ; B -30 -217 182 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 93 494 486 664 ;
-C 206 ; WX 333 ; N ogonek ; B -20 -169 200 40 ;
-C 207 ; WX 333 ; N caron ; B 121 492 426 661 ;
-C 208 ; WX 889 ; N emdash ; B -6 197 894 243 ;
-C 225 ; WX 889 ; N AE ; B -27 0 911 653 ;
-C 227 ; WX 276 ; N ordfeminine ; B 42 406 352 676 ;
-C 232 ; WX 556 ; N Lslash ; B -8 0 559 653 ;
-C 233 ; WX 722 ; N Oslash ; B 60 -105 699 722 ;
-C 234 ; WX 944 ; N OE ; B 49 -8 964 666 ;
-C 235 ; WX 310 ; N ordmasculine ; B 67 406 362 676 ;
-C 241 ; WX 667 ; N ae ; B 23 -11 640 441 ;
-C 245 ; WX 278 ; N dotlessi ; B 49 -11 235 441 ;
-C 248 ; WX 278 ; N lslash ; B 37 -11 307 683 ;
-C 249 ; WX 500 ; N oslash ; B 28 -135 469 554 ;
-C 250 ; WX 667 ; N oe ; B 20 -12 646 441 ;
-C 251 ; WX 500 ; N germandbls ; B -168 -207 493 679 ;
-C -1 ; WX 556 ; N Zcaron ; B -6 0 606 873 ;
-C -1 ; WX 444 ; N ccedilla ; B 26 -217 425 441 ;
-C -1 ; WX 444 ; N ydieresis ; B -24 -206 441 606 ;
-C -1 ; WX 500 ; N atilde ; B 17 -11 511 624 ;
-C -1 ; WX 278 ; N icircumflex ; B 34 -11 328 661 ;
-C -1 ; WX 300 ; N threesuperior ; B 43 268 339 676 ;
-C -1 ; WX 444 ; N ecircumflex ; B 31 -11 441 661 ;
-C -1 ; WX 500 ; N thorn ; B -75 -205 469 683 ;
-C -1 ; WX 444 ; N egrave ; B 31 -11 412 664 ;
-C -1 ; WX 300 ; N twosuperior ; B 33 271 324 676 ;
-C -1 ; WX 444 ; N eacute ; B 31 -11 459 664 ;
-C -1 ; WX 500 ; N otilde ; B 27 -11 496 624 ;
-C -1 ; WX 611 ; N Aacute ; B -51 0 564 876 ;
-C -1 ; WX 500 ; N ocircumflex ; B 27 -11 468 661 ;
-C -1 ; WX 444 ; N yacute ; B -24 -206 459 664 ;
-C -1 ; WX 500 ; N udieresis ; B 42 -11 479 606 ;
-C -1 ; WX 750 ; N threequarters ; B 23 -10 736 676 ;
-C -1 ; WX 500 ; N acircumflex ; B 17 -11 476 661 ;
-C -1 ; WX 722 ; N Eth ; B -8 0 700 653 ;
-C -1 ; WX 444 ; N edieresis ; B 31 -11 451 606 ;
-C -1 ; WX 500 ; N ugrave ; B 42 -11 475 664 ;
-C -1 ; WX 980 ; N trademark ; B 30 247 957 653 ;
-C -1 ; WX 500 ; N ograve ; B 27 -11 468 664 ;
-C -1 ; WX 389 ; N scaron ; B 16 -13 454 661 ;
-C -1 ; WX 333 ; N Idieresis ; B -8 0 435 818 ;
-C -1 ; WX 500 ; N uacute ; B 42 -11 477 664 ;
-C -1 ; WX 500 ; N agrave ; B 17 -11 476 664 ;
-C -1 ; WX 500 ; N ntilde ; B 14 -9 476 624 ;
-C -1 ; WX 500 ; N aring ; B 17 -11 476 691 ;
-C -1 ; WX 389 ; N zcaron ; B -2 -81 434 661 ;
-C -1 ; WX 333 ; N Icircumflex ; B -8 0 425 873 ;
-C -1 ; WX 667 ; N Ntilde ; B -20 -15 727 836 ;
-C -1 ; WX 500 ; N ucircumflex ; B 42 -11 475 661 ;
-C -1 ; WX 611 ; N Ecircumflex ; B -1 0 634 873 ;
-C -1 ; WX 333 ; N Iacute ; B -8 0 413 876 ;
-C -1 ; WX 667 ; N Ccedilla ; B 66 -217 689 666 ;
-C -1 ; WX 722 ; N Odieresis ; B 60 -18 699 818 ;
-C -1 ; WX 500 ; N Scaron ; B 17 -18 520 873 ;
-C -1 ; WX 611 ; N Edieresis ; B -1 0 634 818 ;
-C -1 ; WX 333 ; N Igrave ; B -8 0 384 876 ;
-C -1 ; WX 500 ; N adieresis ; B 17 -11 489 606 ;
-C -1 ; WX 722 ; N Ograve ; B 60 -18 699 876 ;
-C -1 ; WX 611 ; N Egrave ; B -1 0 634 876 ;
-C -1 ; WX 556 ; N Ydieresis ; B 78 0 633 818 ;
-C -1 ; WX 760 ; N registered ; B 41 -18 719 666 ;
-C -1 ; WX 722 ; N Otilde ; B 60 -18 699 836 ;
-C -1 ; WX 750 ; N onequarter ; B 33 -10 736 676 ;
-C -1 ; WX 722 ; N Ugrave ; B 102 -18 765 876 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 102 -18 765 873 ;
-C -1 ; WX 611 ; N Thorn ; B 0 0 569 653 ;
-C -1 ; WX 675 ; N divide ; B 86 -11 590 517 ;
-C -1 ; WX 611 ; N Atilde ; B -51 0 566 836 ;
-C -1 ; WX 722 ; N Uacute ; B 102 -18 765 876 ;
-C -1 ; WX 722 ; N Ocircumflex ; B 60 -18 699 873 ;
-C -1 ; WX 675 ; N logicalnot ; B 86 108 590 386 ;
-C -1 ; WX 611 ; N Aring ; B -51 0 564 883 ;
-C -1 ; WX 278 ; N idieresis ; B 49 -11 353 606 ;
-C -1 ; WX 278 ; N iacute ; B 49 -11 356 664 ;
-C -1 ; WX 500 ; N aacute ; B 17 -11 487 664 ;
-C -1 ; WX 675 ; N plusminus ; B 86 0 590 506 ;
-C -1 ; WX 675 ; N multiply ; B 93 8 582 497 ;
-C -1 ; WX 722 ; N Udieresis ; B 102 -18 765 818 ;
-C -1 ; WX 675 ; N minus ; B 86 220 590 286 ;
-C -1 ; WX 300 ; N onesuperior ; B 43 271 284 676 ;
-C -1 ; WX 611 ; N Eacute ; B -1 0 634 876 ;
-C -1 ; WX 611 ; N Acircumflex ; B -51 0 564 873 ;
-C -1 ; WX 760 ; N copyright ; B 41 -18 719 666 ;
-C -1 ; WX 611 ; N Agrave ; B -51 0 564 876 ;
-C -1 ; WX 500 ; N odieresis ; B 27 -11 489 606 ;
-C -1 ; WX 500 ; N oacute ; B 27 -11 487 664 ;
-C -1 ; WX 400 ; N degree ; B 101 390 387 676 ;
-C -1 ; WX 278 ; N igrave ; B 49 -11 284 664 ;
-C -1 ; WX 500 ; N mu ; B -30 -209 497 428 ;
-C -1 ; WX 722 ; N Oacute ; B 60 -18 699 876 ;
-C -1 ; WX 500 ; N eth ; B 27 -11 482 683 ;
-C -1 ; WX 611 ; N Adieresis ; B -51 0 564 818 ;
-C -1 ; WX 556 ; N Yacute ; B 78 0 633 876 ;
-C -1 ; WX 275 ; N brokenbar ; B 105 -18 171 666 ;
-C -1 ; WX 750 ; N onehalf ; B 34 -10 749 676 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 283
-
-KPX A y -55
-KPX A w -55
-KPX A v -55
-KPX A u -20
-KPX A quoteright -37
-KPX A quotedblright 0
-KPX A p 0
-KPX A Y -55
-KPX A W -95
-KPX A V -105
-KPX A U -50
-KPX A T -37
-KPX A Q -40
-KPX A O -40
-KPX A G -35
-KPX A C -30
-
-KPX B period 0
-KPX B comma 0
-KPX B U -10
-KPX B A -25
-
-KPX D period 0
-KPX D comma 0
-KPX D Y -40
-KPX D W -40
-KPX D V -40
-KPX D A -35
-
-KPX F r -55
-KPX F period -135
-KPX F o -105
-KPX F i -45
-KPX F e -75
-KPX F comma -135
-KPX F a -75
-KPX F A -115
-
-KPX G period 0
-KPX G comma 0
-
-KPX J u -35
-KPX J period -25
-KPX J o -25
-KPX J e -25
-KPX J comma -25
-KPX J a -35
-KPX J A -40
-
-KPX K y -40
-KPX K u -40
-KPX K o -40
-KPX K e -35
-KPX K O -50
-
-KPX L y -30
-KPX L quoteright -37
-KPX L quotedblright 0
-KPX L Y -20
-KPX L W -55
-KPX L V -55
-KPX L T -20
-
-KPX N period 0
-KPX N comma 0
-KPX N A -27
-
-KPX O period 0
-KPX O comma 0
-KPX O Y -50
-KPX O X -40
-KPX O W -50
-KPX O V -50
-KPX O T -40
-KPX O A -55
-
-KPX P period -135
-KPX P o -80
-KPX P e -80
-KPX P comma -135
-KPX P a -80
-KPX P A -90
-
-KPX Q period 0
-KPX Q comma 0
-KPX Q U -10
-
-KPX R Y -18
-KPX R W -18
-KPX R V -18
-KPX R U -40
-KPX R T 0
-KPX R O -40
-
-KPX S period 0
-KPX S comma 0
-
-KPX T y -74
-KPX T w -74
-KPX T u -55
-KPX T semicolon -65
-KPX T r -55
-KPX T period -74
-KPX T o -92
-KPX T i -55
-KPX T hyphen -74
-KPX T h 0
-KPX T e -92
-KPX T comma -74
-KPX T colon -55
-KPX T a -92
-KPX T O -18
-KPX T A -50
-
-KPX U period -25
-KPX U comma -25
-KPX U A -40
-
-KPX V u -74
-KPX V semicolon -74
-KPX V period -129
-KPX V o -111
-KPX V i -74
-KPX V hyphen -55
-KPX V e -111
-KPX V comma -129
-KPX V colon -65
-KPX V a -111
-KPX V O -30
-KPX V G 0
-KPX V A -60
-
-KPX W y -70
-KPX W u -55
-KPX W semicolon -65
-KPX W period -92
-KPX W o -92
-KPX W i -55
-KPX W hyphen -37
-KPX W h 0
-KPX W e -92
-KPX W comma -92
-KPX W colon -65
-KPX W a -92
-KPX W O -25
-KPX W A -60
-
-KPX Y u -92
-KPX Y semicolon -65
-KPX Y period -92
-KPX Y o -92
-KPX Y i -74
-KPX Y hyphen -74
-KPX Y e -92
-KPX Y comma -92
-KPX Y colon -65
-KPX Y a -92
-KPX Y O -15
-KPX Y A -50
-
-KPX a y 0
-KPX a w 0
-KPX a v 0
-KPX a t 0
-KPX a p 0
-KPX a g -10
-KPX a b 0
-
-KPX b y 0
-KPX b v 0
-KPX b u -20
-KPX b period -40
-KPX b l 0
-KPX b comma 0
-KPX b b 0
-
-KPX c y 0
-KPX c period 0
-KPX c l 0
-KPX c k -20
-KPX c h -15
-KPX c comma 0
-
-KPX colon space 0
-
-KPX comma space 0
-KPX comma quoteright -140
-KPX comma quotedblright -140
-
-KPX d y 0
-KPX d w 0
-KPX d v 0
-KPX d period 0
-KPX d d 0
-KPX d comma 0
-
-KPX e y -30
-KPX e x -20
-KPX e w -15
-KPX e v -15
-KPX e period -15
-KPX e p 0
-KPX e g -40
-KPX e comma -10
-KPX e b 0
-
-KPX f quoteright 92
-KPX f quotedblright 0
-KPX f period -15
-KPX f o 0
-KPX f l 0
-KPX f i -20
-KPX f f -18
-KPX f e 0
-KPX f dotlessi -60
-KPX f comma -10
-KPX f a 0
-
-KPX g y 0
-KPX g r 0
-KPX g period -15
-KPX g o 0
-KPX g i 0
-KPX g g -10
-KPX g e -10
-KPX g comma -10
-KPX g a 0
-
-KPX h y 0
-
-KPX i v 0
-
-KPX k y -10
-KPX k o -10
-KPX k e -10
-
-KPX l y 0
-KPX l w 0
-
-KPX m y 0
-KPX m u 0
-
-KPX n y 0
-KPX n v -40
-KPX n u 0
-
-KPX o y 0
-KPX o x 0
-KPX o w 0
-KPX o v -10
-KPX o g -10
-
-KPX p y 0
-
-KPX period quoteright -140
-KPX period quotedblright -140
-
-KPX quotedblleft quoteleft 0
-KPX quotedblleft A 0
-
-KPX quotedblright space 0
-
-KPX quoteleft quoteleft -111
-KPX quoteleft A 0
-
-KPX quoteright v -10
-KPX quoteright t -30
-KPX quoteright space -111
-KPX quoteright s -40
-KPX quoteright r -25
-KPX quoteright quoteright -111
-KPX quoteright quotedblright 0
-KPX quoteright l 0
-KPX quoteright d -25
-
-KPX r y 0
-KPX r v 0
-KPX r u 0
-KPX r t 0
-KPX r s -10
-KPX r r 0
-KPX r q -37
-KPX r period -111
-KPX r p 0
-KPX r o -45
-KPX r n 0
-KPX r m 0
-KPX r l 0
-KPX r k 0
-KPX r i 0
-KPX r hyphen -20
-KPX r g -37
-KPX r e -37
-KPX r d -37
-KPX r comma -111
-KPX r c -37
-KPX r a -15
-
-KPX s w 0
-
-KPX space quoteleft 0
-KPX space quotedblleft 0
-KPX space Y -75
-KPX space W -40
-KPX space V -35
-KPX space T -18
-KPX space A -18
-
-KPX v period -74
-KPX v o 0
-KPX v e 0
-KPX v comma -74
-KPX v a 0
-
-KPX w period -74
-KPX w o 0
-KPX w h 0
-KPX w e 0
-KPX w comma -74
-KPX w a 0
-
-KPX x e 0
-
-KPX y period -55
-KPX y o 0
-KPX y e 0
-KPX y comma -55
-KPX y a 0
-
-KPX z o 0
-KPX z e 0
-EndKernPairs
-EndKernData
-StartComposites 58
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 139 212 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 144 212 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 139 212 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 149 212 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 129 192 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 139 212 ;
-CC Ccedilla 2 ; PCC C 0 0 ; PCC cedilla 167 0 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 149 212 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 169 212 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 159 212 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 149 212 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 10 212 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 40 212 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 30 212 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 10 212 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 177 212 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 195 212 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 230 212 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 230 212 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 205 212 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 215 212 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 94 212 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 195 212 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 215 212 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 225 212 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 215 212 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 132 212 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 142 212 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 112 212 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 84 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 84 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 84 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 84 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 84 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 84 0 ;
-CC ccedilla 2 ; PCC c 0 0 ; PCC cedilla 56 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 56 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex 56 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis 46 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 56 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -47 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -57 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -52 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -27 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 49 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 84 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 74 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 84 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 84 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde 69 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron 28 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 74 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 74 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 74 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 84 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 56 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 36 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 8 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/putb8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/putb8a.afm
deleted file mode 100644
index 2eaa540d63..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/putb8a.afm
+++ /dev/null
@@ -1,1005 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Fri Jan 17 15:08:52 1992
-Comment UniqueID 37705
-Comment VMusage 33078 39970
-FontName Utopia-Bold
-FullName Utopia Bold
-FamilyName Utopia
-Weight Bold
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -155 -250 1249 916
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.002
-Notice Copyright (c) 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.Utopia is a registered trademark of Adobe Systems Incorporated.
-EncodingScheme AdobeStandardEncoding
-CapHeight 692
-XHeight 490
-Ascender 742
-Descender -230
-StartCharMetrics 228
-C 32 ; WX 210 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 278 ; N exclam ; B 47 -12 231 707 ;
-C 34 ; WX 473 ; N quotedbl ; B 71 407 402 707 ;
-C 35 ; WX 560 ; N numbersign ; B 14 0 547 668 ;
-C 36 ; WX 560 ; N dollar ; B 38 -104 524 748 ;
-C 37 ; WX 887 ; N percent ; B 40 -31 847 701 ;
-C 38 ; WX 748 ; N ampersand ; B 45 -12 734 680 ;
-C 39 ; WX 252 ; N quoteright ; B 40 387 212 707 ;
-C 40 ; WX 365 ; N parenleft ; B 99 -135 344 699 ;
-C 41 ; WX 365 ; N parenright ; B 21 -135 266 699 ;
-C 42 ; WX 442 ; N asterisk ; B 40 315 402 707 ;
-C 43 ; WX 600 ; N plus ; B 58 0 542 490 ;
-C 44 ; WX 280 ; N comma ; B 40 -167 226 180 ;
-C 45 ; WX 392 ; N hyphen ; B 65 203 328 298 ;
-C 46 ; WX 280 ; N period ; B 48 -12 232 174 ;
-C 47 ; WX 378 ; N slash ; B 34 -15 344 707 ;
-C 48 ; WX 560 ; N zero ; B 31 -12 530 680 ;
-C 49 ; WX 560 ; N one ; B 102 0 459 680 ;
-C 50 ; WX 560 ; N two ; B 30 0 539 680 ;
-C 51 ; WX 560 ; N three ; B 27 -12 519 680 ;
-C 52 ; WX 560 ; N four ; B 19 0 533 668 ;
-C 53 ; WX 560 ; N five ; B 43 -12 519 668 ;
-C 54 ; WX 560 ; N six ; B 30 -12 537 680 ;
-C 55 ; WX 560 ; N seven ; B 34 -12 530 668 ;
-C 56 ; WX 560 ; N eight ; B 27 -12 533 680 ;
-C 57 ; WX 560 ; N nine ; B 34 -12 523 680 ;
-C 58 ; WX 280 ; N colon ; B 48 -12 232 490 ;
-C 59 ; WX 280 ; N semicolon ; B 40 -167 232 490 ;
-C 60 ; WX 600 ; N less ; B 61 5 539 493 ;
-C 61 ; WX 600 ; N equal ; B 58 103 542 397 ;
-C 62 ; WX 600 ; N greater ; B 61 5 539 493 ;
-C 63 ; WX 456 ; N question ; B 20 -12 433 707 ;
-C 64 ; WX 833 ; N at ; B 45 -15 797 707 ;
-C 65 ; WX 644 ; N A ; B -28 0 663 692 ;
-C 66 ; WX 683 ; N B ; B 33 0 645 692 ;
-C 67 ; WX 689 ; N C ; B 42 -15 654 707 ;
-C 68 ; WX 777 ; N D ; B 33 0 735 692 ;
-C 69 ; WX 629 ; N E ; B 33 0 604 692 ;
-C 70 ; WX 593 ; N F ; B 37 0 568 692 ;
-C 71 ; WX 726 ; N G ; B 42 -15 709 707 ;
-C 72 ; WX 807 ; N H ; B 33 0 774 692 ;
-C 73 ; WX 384 ; N I ; B 33 0 351 692 ;
-C 74 ; WX 386 ; N J ; B 6 -114 361 692 ;
-C 75 ; WX 707 ; N K ; B 33 -6 719 692 ;
-C 76 ; WX 585 ; N L ; B 33 0 584 692 ;
-C 77 ; WX 918 ; N M ; B 23 0 885 692 ;
-C 78 ; WX 739 ; N N ; B 25 0 719 692 ;
-C 79 ; WX 768 ; N O ; B 42 -15 726 707 ;
-C 80 ; WX 650 ; N P ; B 33 0 623 692 ;
-C 81 ; WX 768 ; N Q ; B 42 -193 726 707 ;
-C 82 ; WX 684 ; N R ; B 33 0 686 692 ;
-C 83 ; WX 561 ; N S ; B 42 -15 533 707 ;
-C 84 ; WX 624 ; N T ; B 15 0 609 692 ;
-C 85 ; WX 786 ; N U ; B 29 -15 757 692 ;
-C 86 ; WX 645 ; N V ; B -16 0 679 692 ;
-C 87 ; WX 933 ; N W ; B -10 0 960 692 ;
-C 88 ; WX 634 ; N X ; B -19 0 671 692 ;
-C 89 ; WX 617 ; N Y ; B -12 0 655 692 ;
-C 90 ; WX 614 ; N Z ; B 0 0 606 692 ;
-C 91 ; WX 335 ; N bracketleft ; B 123 -128 308 692 ;
-C 92 ; WX 379 ; N backslash ; B 34 -15 345 707 ;
-C 93 ; WX 335 ; N bracketright ; B 27 -128 212 692 ;
-C 94 ; WX 600 ; N asciicircum ; B 56 215 544 668 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 252 ; N quoteleft ; B 40 399 212 719 ;
-C 97 ; WX 544 ; N a ; B 41 -12 561 502 ;
-C 98 ; WX 605 ; N b ; B 15 -12 571 742 ;
-C 99 ; WX 494 ; N c ; B 34 -12 484 502 ;
-C 100 ; WX 605 ; N d ; B 34 -12 596 742 ;
-C 101 ; WX 519 ; N e ; B 34 -12 505 502 ;
-C 102 ; WX 342 ; N f ; B 27 0 421 742 ; L i fi ; L l fl ;
-C 103 ; WX 533 ; N g ; B 25 -242 546 512 ;
-C 104 ; WX 631 ; N h ; B 19 0 622 742 ;
-C 105 ; WX 316 ; N i ; B 26 0 307 720 ;
-C 106 ; WX 316 ; N j ; B -12 -232 260 720 ;
-C 107 ; WX 582 ; N k ; B 19 0 595 742 ;
-C 108 ; WX 309 ; N l ; B 19 0 300 742 ;
-C 109 ; WX 948 ; N m ; B 26 0 939 502 ;
-C 110 ; WX 638 ; N n ; B 26 0 629 502 ;
-C 111 ; WX 585 ; N o ; B 34 -12 551 502 ;
-C 112 ; WX 615 ; N p ; B 19 -230 581 502 ;
-C 113 ; WX 597 ; N q ; B 34 -230 596 502 ;
-C 114 ; WX 440 ; N r ; B 26 0 442 502 ;
-C 115 ; WX 446 ; N s ; B 38 -12 425 502 ;
-C 116 ; WX 370 ; N t ; B 32 -12 373 616 ;
-C 117 ; WX 629 ; N u ; B 23 -12 620 502 ;
-C 118 ; WX 520 ; N v ; B -8 0 546 490 ;
-C 119 ; WX 774 ; N w ; B -10 0 802 490 ;
-C 120 ; WX 522 ; N x ; B -15 0 550 490 ;
-C 121 ; WX 524 ; N y ; B -12 -242 557 490 ;
-C 122 ; WX 483 ; N z ; B -1 0 480 490 ;
-C 123 ; WX 365 ; N braceleft ; B 74 -128 325 692 ;
-C 124 ; WX 284 ; N bar ; B 94 -250 190 750 ;
-C 125 ; WX 365 ; N braceright ; B 40 -128 291 692 ;
-C 126 ; WX 600 ; N asciitilde ; B 50 158 551 339 ;
-C 161 ; WX 278 ; N exclamdown ; B 47 -217 231 502 ;
-C 162 ; WX 560 ; N cent ; B 39 -15 546 678 ;
-C 163 ; WX 560 ; N sterling ; B 21 0 555 679 ;
-C 164 ; WX 100 ; N fraction ; B -155 -27 255 695 ;
-C 165 ; WX 560 ; N yen ; B 3 0 562 668 ;
-C 166 ; WX 560 ; N florin ; B -40 -135 562 691 ;
-C 167 ; WX 566 ; N section ; B 35 -115 531 707 ;
-C 168 ; WX 560 ; N currency ; B 21 73 539 596 ;
-C 169 ; WX 252 ; N quotesingle ; B 57 407 196 707 ;
-C 170 ; WX 473 ; N quotedblleft ; B 40 399 433 719 ;
-C 171 ; WX 487 ; N guillemotleft ; B 40 37 452 464 ;
-C 172 ; WX 287 ; N guilsinglleft ; B 40 37 252 464 ;
-C 173 ; WX 287 ; N guilsinglright ; B 35 37 247 464 ;
-C 174 ; WX 639 ; N fi ; B 27 0 630 742 ;
-C 175 ; WX 639 ; N fl ; B 27 0 630 742 ;
-C 177 ; WX 500 ; N endash ; B 0 209 500 292 ;
-C 178 ; WX 510 ; N dagger ; B 35 -125 475 707 ;
-C 179 ; WX 486 ; N daggerdbl ; B 35 -119 451 707 ;
-C 180 ; WX 280 ; N periodcentered ; B 48 156 232 342 ;
-C 182 ; WX 552 ; N paragraph ; B 35 -101 527 692 ;
-C 183 ; WX 455 ; N bullet ; B 50 174 405 529 ;
-C 184 ; WX 252 ; N quotesinglbase ; B 40 -153 212 167 ;
-C 185 ; WX 473 ; N quotedblbase ; B 40 -153 433 167 ;
-C 186 ; WX 473 ; N quotedblright ; B 40 387 433 707 ;
-C 187 ; WX 487 ; N guillemotright ; B 35 37 447 464 ;
-C 188 ; WX 1000 ; N ellipsis ; B 75 -12 925 174 ;
-C 189 ; WX 1289 ; N perthousand ; B 40 -31 1249 701 ;
-C 191 ; WX 456 ; N questiondown ; B 23 -217 436 502 ;
-C 193 ; WX 430 ; N grave ; B 40 511 312 740 ;
-C 194 ; WX 430 ; N acute ; B 119 511 391 740 ;
-C 195 ; WX 430 ; N circumflex ; B 28 520 402 747 ;
-C 196 ; WX 430 ; N tilde ; B 2 553 427 706 ;
-C 197 ; WX 430 ; N macron ; B 60 587 371 674 ;
-C 198 ; WX 430 ; N breve ; B 56 556 375 716 ;
-C 199 ; WX 430 ; N dotaccent ; B 136 561 294 710 ;
-C 200 ; WX 430 ; N dieresis ; B 16 561 414 710 ;
-C 202 ; WX 430 ; N ring ; B 96 540 334 762 ;
-C 203 ; WX 430 ; N cedilla ; B 136 -246 335 0 ;
-C 205 ; WX 430 ; N hungarumlaut ; B 64 521 446 751 ;
-C 206 ; WX 430 ; N ogonek ; B 105 -246 325 0 ;
-C 207 ; WX 430 ; N caron ; B 28 520 402 747 ;
-C 208 ; WX 1000 ; N emdash ; B 0 209 1000 292 ;
-C 225 ; WX 879 ; N AE ; B -77 0 854 692 ;
-C 227 ; WX 405 ; N ordfeminine ; B 28 265 395 590 ;
-C 232 ; WX 591 ; N Lslash ; B 30 0 590 692 ;
-C 233 ; WX 768 ; N Oslash ; B 42 -61 726 747 ;
-C 234 ; WX 1049 ; N OE ; B 42 0 1024 692 ;
-C 235 ; WX 427 ; N ordmasculine ; B 28 265 399 590 ;
-C 241 ; WX 806 ; N ae ; B 41 -12 792 502 ;
-C 245 ; WX 316 ; N dotlessi ; B 26 0 307 502 ;
-C 248 ; WX 321 ; N lslash ; B 16 0 332 742 ;
-C 249 ; WX 585 ; N oslash ; B 34 -51 551 535 ;
-C 250 ; WX 866 ; N oe ; B 34 -12 852 502 ;
-C 251 ; WX 662 ; N germandbls ; B 29 -12 647 742 ;
-C -1 ; WX 402 ; N onesuperior ; B 71 272 324 680 ;
-C -1 ; WX 600 ; N minus ; B 58 210 542 290 ;
-C -1 ; WX 396 ; N degree ; B 35 360 361 680 ;
-C -1 ; WX 585 ; N oacute ; B 34 -12 551 755 ;
-C -1 ; WX 768 ; N Odieresis ; B 42 -15 726 881 ;
-C -1 ; WX 585 ; N odieresis ; B 34 -12 551 710 ;
-C -1 ; WX 629 ; N Eacute ; B 33 0 604 904 ;
-C -1 ; WX 629 ; N ucircumflex ; B 23 -12 620 747 ;
-C -1 ; WX 900 ; N onequarter ; B 73 -27 814 695 ;
-C -1 ; WX 600 ; N logicalnot ; B 58 95 542 397 ;
-C -1 ; WX 629 ; N Ecircumflex ; B 33 0 604 905 ;
-C -1 ; WX 900 ; N onehalf ; B 53 -27 849 695 ;
-C -1 ; WX 768 ; N Otilde ; B 42 -15 726 876 ;
-C -1 ; WX 629 ; N uacute ; B 23 -12 620 740 ;
-C -1 ; WX 519 ; N eacute ; B 34 -12 505 755 ;
-C -1 ; WX 316 ; N iacute ; B 26 0 369 740 ;
-C -1 ; WX 629 ; N Egrave ; B 33 0 604 904 ;
-C -1 ; WX 316 ; N icircumflex ; B -28 0 346 747 ;
-C -1 ; WX 629 ; N mu ; B 23 -242 620 502 ;
-C -1 ; WX 284 ; N brokenbar ; B 94 -175 190 675 ;
-C -1 ; WX 609 ; N thorn ; B 13 -230 575 722 ;
-C -1 ; WX 644 ; N Aring ; B -28 0 663 872 ;
-C -1 ; WX 524 ; N yacute ; B -12 -242 557 740 ;
-C -1 ; WX 617 ; N Ydieresis ; B -12 0 655 881 ;
-C -1 ; WX 1090 ; N trademark ; B 38 277 1028 692 ;
-C -1 ; WX 800 ; N registered ; B 36 -15 764 707 ;
-C -1 ; WX 585 ; N ocircumflex ; B 34 -12 551 747 ;
-C -1 ; WX 644 ; N Agrave ; B -28 0 663 904 ;
-C -1 ; WX 561 ; N Scaron ; B 42 -15 533 916 ;
-C -1 ; WX 786 ; N Ugrave ; B 29 -15 757 904 ;
-C -1 ; WX 629 ; N Edieresis ; B 33 0 604 881 ;
-C -1 ; WX 786 ; N Uacute ; B 29 -15 757 904 ;
-C -1 ; WX 585 ; N otilde ; B 34 -12 551 706 ;
-C -1 ; WX 638 ; N ntilde ; B 26 0 629 706 ;
-C -1 ; WX 524 ; N ydieresis ; B -12 -242 557 710 ;
-C -1 ; WX 644 ; N Aacute ; B -28 0 663 904 ;
-C -1 ; WX 585 ; N eth ; B 34 -12 551 742 ;
-C -1 ; WX 544 ; N acircumflex ; B 41 -12 561 747 ;
-C -1 ; WX 544 ; N aring ; B 41 -12 561 762 ;
-C -1 ; WX 768 ; N Ograve ; B 42 -15 726 904 ;
-C -1 ; WX 494 ; N ccedilla ; B 34 -246 484 502 ;
-C -1 ; WX 600 ; N multiply ; B 75 20 525 476 ;
-C -1 ; WX 600 ; N divide ; B 58 6 542 494 ;
-C -1 ; WX 402 ; N twosuperior ; B 29 272 382 680 ;
-C -1 ; WX 739 ; N Ntilde ; B 25 0 719 876 ;
-C -1 ; WX 629 ; N ugrave ; B 23 -12 620 740 ;
-C -1 ; WX 786 ; N Ucircumflex ; B 29 -15 757 905 ;
-C -1 ; WX 644 ; N Atilde ; B -28 0 663 876 ;
-C -1 ; WX 483 ; N zcaron ; B -1 0 480 747 ;
-C -1 ; WX 316 ; N idieresis ; B -37 0 361 710 ;
-C -1 ; WX 644 ; N Acircumflex ; B -28 0 663 905 ;
-C -1 ; WX 384 ; N Icircumflex ; B 4 0 380 905 ;
-C -1 ; WX 617 ; N Yacute ; B -12 0 655 904 ;
-C -1 ; WX 768 ; N Oacute ; B 42 -15 726 904 ;
-C -1 ; WX 644 ; N Adieresis ; B -28 0 663 881 ;
-C -1 ; WX 614 ; N Zcaron ; B 0 0 606 916 ;
-C -1 ; WX 544 ; N agrave ; B 41 -12 561 755 ;
-C -1 ; WX 402 ; N threesuperior ; B 30 265 368 680 ;
-C -1 ; WX 585 ; N ograve ; B 34 -12 551 755 ;
-C -1 ; WX 900 ; N threequarters ; B 40 -27 842 695 ;
-C -1 ; WX 783 ; N Eth ; B 35 0 741 692 ;
-C -1 ; WX 600 ; N plusminus ; B 58 0 542 549 ;
-C -1 ; WX 629 ; N udieresis ; B 23 -12 620 710 ;
-C -1 ; WX 519 ; N edieresis ; B 34 -12 505 710 ;
-C -1 ; WX 544 ; N aacute ; B 41 -12 561 755 ;
-C -1 ; WX 316 ; N igrave ; B -47 0 307 740 ;
-C -1 ; WX 384 ; N Idieresis ; B -13 0 397 881 ;
-C -1 ; WX 544 ; N adieresis ; B 41 -12 561 710 ;
-C -1 ; WX 384 ; N Iacute ; B 33 0 423 904 ;
-C -1 ; WX 800 ; N copyright ; B 36 -15 764 707 ;
-C -1 ; WX 384 ; N Igrave ; B -31 0 351 904 ;
-C -1 ; WX 689 ; N Ccedilla ; B 42 -246 654 707 ;
-C -1 ; WX 446 ; N scaron ; B 38 -12 425 747 ;
-C -1 ; WX 519 ; N egrave ; B 34 -12 505 755 ;
-C -1 ; WX 768 ; N Ocircumflex ; B 42 -15 726 905 ;
-C -1 ; WX 640 ; N Thorn ; B 33 0 622 692 ;
-C -1 ; WX 544 ; N atilde ; B 41 -12 561 706 ;
-C -1 ; WX 786 ; N Udieresis ; B 29 -15 757 881 ;
-C -1 ; WX 519 ; N ecircumflex ; B 34 -12 505 747 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 685
-
-KPX A z 25
-KPX A y -40
-KPX A w -42
-KPX A v -48
-KPX A u -18
-KPX A t -12
-KPX A s 6
-KPX A quoteright -110
-KPX A quotedblright -80
-KPX A q -6
-KPX A p -18
-KPX A o -12
-KPX A e -6
-KPX A d -12
-KPX A c -12
-KPX A b -12
-KPX A a -6
-KPX A Y -64
-KPX A X -18
-KPX A W -54
-KPX A V -70
-KPX A U -40
-KPX A T -58
-KPX A Q -18
-KPX A O -18
-KPX A G -18
-KPX A C -18
-
-KPX B y -18
-KPX B u -12
-KPX B r -12
-KPX B o -6
-KPX B l -15
-KPX B k -15
-KPX B i -12
-KPX B h -15
-KPX B e -6
-KPX B b -10
-KPX B a -12
-KPX B W -20
-KPX B V -20
-KPX B U -25
-KPX B T -20
-
-KPX C z -5
-KPX C y -24
-KPX C u -18
-KPX C r -6
-KPX C o -12
-KPX C e -12
-KPX C a -16
-KPX C Q -6
-KPX C O -6
-KPX C G -6
-KPX C C -6
-
-KPX D u -12
-KPX D r -12
-KPX D period -40
-KPX D o -5
-KPX D i -12
-KPX D h -18
-KPX D e -5
-KPX D comma -40
-KPX D a -15
-KPX D Y -60
-KPX D W -40
-KPX D V -40
-
-KPX E y -30
-KPX E w -24
-KPX E v -24
-KPX E u -12
-KPX E t -18
-KPX E s -12
-KPX E r -4
-KPX E q -6
-KPX E period 10
-KPX E p -18
-KPX E o -6
-KPX E n -4
-KPX E m -4
-KPX E j -6
-KPX E i -6
-KPX E g -6
-KPX E e -6
-KPX E d -6
-KPX E comma 10
-KPX E c -6
-KPX E b -5
-KPX E a -4
-KPX E Y -6
-KPX E W -6
-KPX E V -6
-
-KPX F y -18
-KPX F u -12
-KPX F r -36
-KPX F quoteright 20
-KPX F quotedblright 20
-KPX F period -150
-KPX F o -36
-KPX F l -12
-KPX F i -22
-KPX F e -36
-KPX F comma -150
-KPX F a -48
-KPX F A -60
-
-KPX G y -12
-KPX G u -12
-KPX G r -18
-KPX G quotedblright -20
-KPX G n -18
-KPX G l -6
-KPX G i -12
-KPX G h -12
-KPX G a -12
-
-KPX H y -24
-KPX H u -26
-KPX H o -30
-KPX H i -18
-KPX H e -30
-KPX H a -25
-
-KPX I z -6
-KPX I y -6
-KPX I x -6
-KPX I w -18
-KPX I v -24
-KPX I u -26
-KPX I t -24
-KPX I s -18
-KPX I r -12
-KPX I p -26
-KPX I o -30
-KPX I n -18
-KPX I m -18
-KPX I l -6
-KPX I k -6
-KPX I h -6
-KPX I g -6
-KPX I f -6
-KPX I e -30
-KPX I d -30
-KPX I c -30
-KPX I b -6
-KPX I a -24
-
-KPX J y -20
-KPX J u -36
-KPX J o -35
-KPX J i -20
-KPX J e -35
-KPX J bracketright 15
-KPX J braceright 15
-KPX J a -36
-
-KPX K y -70
-KPX K w -60
-KPX K v -80
-KPX K u -42
-KPX K o -30
-KPX K l 10
-KPX K i 6
-KPX K h 10
-KPX K e -18
-KPX K a -6
-KPX K Q -36
-KPX K O -36
-KPX K G -36
-KPX K C -36
-KPX K A 20
-
-KPX L y -52
-KPX L w -58
-KPX L u -12
-KPX L quoteright -130
-KPX L quotedblright -130
-KPX L l 6
-KPX L j -6
-KPX L Y -70
-KPX L W -78
-KPX L V -95
-KPX L U -32
-KPX L T -80
-KPX L Q -12
-KPX L O -12
-KPX L G -12
-KPX L C -12
-KPX L A 30
-
-KPX M y -24
-KPX M u -36
-KPX M o -30
-KPX M n -6
-KPX M j -12
-KPX M i -12
-KPX M e -30
-KPX M d -30
-KPX M c -30
-KPX M a -25
-
-KPX N y -24
-KPX N u -30
-KPX N o -30
-KPX N i -24
-KPX N e -30
-KPX N a -30
-
-KPX O z -6
-KPX O u -6
-KPX O t -6
-KPX O s -6
-KPX O r -10
-KPX O q -6
-KPX O period -40
-KPX O p -10
-KPX O o -6
-KPX O n -10
-KPX O m -10
-KPX O l -15
-KPX O k -15
-KPX O i -6
-KPX O h -15
-KPX O g -6
-KPX O e -6
-KPX O d -6
-KPX O comma -40
-KPX O c -6
-KPX O b -15
-KPX O a -12
-KPX O Y -50
-KPX O X -40
-KPX O W -35
-KPX O V -35
-KPX O T -40
-KPX O A -30
-
-KPX P y 10
-KPX P u -18
-KPX P t -6
-KPX P s -30
-KPX P r -12
-KPX P quoteright 20
-KPX P quotedblright 20
-KPX P period -200
-KPX P o -36
-KPX P n -12
-KPX P l -15
-KPX P i -6
-KPX P hyphen -30
-KPX P h -15
-KPX P e -36
-KPX P comma -200
-KPX P a -36
-KPX P I -20
-KPX P H -20
-KPX P E -20
-KPX P A -85
-
-KPX Q u -6
-KPX Q a -18
-KPX Q Y -50
-KPX Q X -40
-KPX Q W -35
-KPX Q V -35
-KPX Q U -25
-KPX Q T -40
-KPX Q A -30
-
-KPX R y -20
-KPX R u -12
-KPX R t -25
-KPX R quoteright -10
-KPX R quotedblright -10
-KPX R o -12
-KPX R e -18
-KPX R a -6
-KPX R Y -32
-KPX R X 20
-KPX R W -18
-KPX R V -26
-KPX R U -30
-KPX R T -20
-KPX R Q -10
-KPX R O -10
-KPX R G -10
-KPX R C -10
-
-KPX S y -35
-KPX S w -30
-KPX S v -40
-KPX S u -24
-KPX S t -24
-KPX S r -10
-KPX S quoteright -15
-KPX S quotedblright -15
-KPX S p -24
-KPX S n -24
-KPX S m -24
-KPX S l -18
-KPX S k -24
-KPX S j -30
-KPX S i -12
-KPX S h -12
-KPX S a -18
-
-KPX T z -64
-KPX T y -74
-KPX T w -72
-KPX T u -74
-KPX T semicolon -50
-KPX T s -82
-KPX T r -74
-KPX T quoteright 24
-KPX T quotedblright 24
-KPX T period -95
-KPX T parenright 40
-KPX T o -90
-KPX T m -72
-KPX T i -28
-KPX T hyphen -110
-KPX T endash -40
-KPX T emdash -60
-KPX T e -80
-KPX T comma -95
-KPX T bracketright 40
-KPX T braceright 30
-KPX T a -90
-KPX T Y 12
-KPX T X 10
-KPX T W 15
-KPX T V 6
-KPX T T 30
-KPX T S -12
-KPX T Q -25
-KPX T O -25
-KPX T G -25
-KPX T C -25
-KPX T A -52
-
-KPX U z -35
-KPX U y -30
-KPX U x -30
-KPX U v -30
-KPX U t -36
-KPX U s -45
-KPX U r -50
-KPX U p -50
-KPX U n -50
-KPX U m -50
-KPX U l -12
-KPX U k -12
-KPX U i -22
-KPX U h -6
-KPX U g -40
-KPX U f -20
-KPX U d -40
-KPX U c -40
-KPX U b -12
-KPX U a -50
-KPX U A -50
-
-KPX V y -36
-KPX V u -50
-KPX V semicolon -45
-KPX V r -75
-KPX V quoteright 50
-KPX V quotedblright 36
-KPX V period -135
-KPX V parenright 80
-KPX V o -70
-KPX V i 20
-KPX V hyphen -90
-KPX V emdash -20
-KPX V e -70
-KPX V comma -135
-KPX V colon -45
-KPX V bracketright 80
-KPX V braceright 80
-KPX V a -70
-KPX V Q -20
-KPX V O -20
-KPX V G -20
-KPX V C -20
-KPX V A -60
-
-KPX W y -50
-KPX W u -46
-KPX W t -30
-KPX W semicolon -40
-KPX W r -50
-KPX W quoteright 40
-KPX W quotedblright 24
-KPX W period -100
-KPX W parenright 80
-KPX W o -60
-KPX W m -50
-KPX W i 5
-KPX W hyphen -70
-KPX W h 20
-KPX W e -60
-KPX W d -60
-KPX W comma -100
-KPX W colon -40
-KPX W bracketright 80
-KPX W braceright 70
-KPX W a -75
-KPX W T 30
-KPX W Q -20
-KPX W O -20
-KPX W G -20
-KPX W C -20
-KPX W A -58
-
-KPX X y -40
-KPX X u -24
-KPX X quoteright 15
-KPX X e -6
-KPX X a -6
-KPX X Q -24
-KPX X O -30
-KPX X G -30
-KPX X C -30
-KPX X A 20
-
-KPX Y v -50
-KPX Y u -65
-KPX Y t -46
-KPX Y semicolon -37
-KPX Y quoteright 50
-KPX Y quotedblright 36
-KPX Y q -100
-KPX Y period -90
-KPX Y parenright 60
-KPX Y o -90
-KPX Y l 25
-KPX Y i 15
-KPX Y hyphen -100
-KPX Y endash -30
-KPX Y emdash -50
-KPX Y e -90
-KPX Y d -90
-KPX Y comma -90
-KPX Y colon -60
-KPX Y bracketright 80
-KPX Y braceright 64
-KPX Y a -80
-KPX Y Y 12
-KPX Y X 12
-KPX Y W 12
-KPX Y V 12
-KPX Y T 30
-KPX Y Q -40
-KPX Y O -40
-KPX Y G -40
-KPX Y C -40
-KPX Y A -55
-
-KPX Z y -36
-KPX Z w -36
-KPX Z u -6
-KPX Z o -12
-KPX Z i -12
-KPX Z e -6
-KPX Z a -6
-KPX Z Q -18
-KPX Z O -18
-KPX Z G -18
-KPX Z C -18
-KPX Z A 25
-
-KPX a quoteright -45
-KPX a quotedblright -40
-
-KPX b y -15
-KPX b w -20
-KPX b v -20
-KPX b quoteright -45
-KPX b quotedblright -40
-KPX b period -10
-KPX b comma -10
-
-KPX braceleft Y 64
-KPX braceleft W 64
-KPX braceleft V 64
-KPX braceleft T 25
-KPX braceleft J 50
-
-KPX bracketleft Y 64
-KPX bracketleft W 64
-KPX bracketleft V 64
-KPX bracketleft T 35
-KPX bracketleft J 60
-
-KPX c quoteright -5
-
-KPX colon space -20
-
-KPX comma space -40
-KPX comma quoteright -100
-KPX comma quotedblright -100
-
-KPX d quoteright -24
-KPX d quotedblright -24
-
-KPX e z -4
-KPX e quoteright -25
-KPX e quotedblright -20
-
-KPX f quotesingle 70
-KPX f quoteright 68
-KPX f quotedblright 68
-KPX f period -10
-KPX f parenright 110
-KPX f comma -20
-KPX f bracketright 100
-KPX f braceright 80
-
-KPX g y 20
-KPX g p 20
-KPX g f 20
-KPX g comma 10
-
-KPX h quoteright -60
-KPX h quotedblright -60
-
-KPX i quoteright -20
-KPX i quotedblright -20
-
-KPX j quoteright -20
-KPX j quotedblright -20
-KPX j period -10
-KPX j comma -10
-
-KPX k quoteright -30
-KPX k quotedblright -30
-
-KPX l quoteright -24
-KPX l quotedblright -24
-
-KPX m quoteright -60
-KPX m quotedblright -60
-
-KPX n quoteright -60
-KPX n quotedblright -60
-
-KPX o z -12
-KPX o y -25
-KPX o x -18
-KPX o w -30
-KPX o v -30
-KPX o quoteright -45
-KPX o quotedblright -40
-KPX o period -10
-KPX o comma -10
-
-KPX p z -10
-KPX p y -15
-KPX p w -15
-KPX p quoteright -45
-KPX p quotedblright -60
-KPX p period -10
-KPX p comma -10
-
-KPX parenleft Y 64
-KPX parenleft W 64
-KPX parenleft V 64
-KPX parenleft T 50
-KPX parenleft J 50
-
-KPX period space -40
-KPX period quoteright -100
-KPX period quotedblright -100
-
-KPX q quoteright -50
-KPX q quotedblright -50
-KPX q period -10
-KPX q comma -10
-
-KPX quotedblleft z -26
-KPX quotedblleft w 10
-KPX quotedblleft u -40
-KPX quotedblleft t -40
-KPX quotedblleft s -32
-KPX quotedblleft r -40
-KPX quotedblleft q -70
-KPX quotedblleft p -40
-KPX quotedblleft o -70
-KPX quotedblleft n -40
-KPX quotedblleft m -40
-KPX quotedblleft g -50
-KPX quotedblleft f -30
-KPX quotedblleft e -70
-KPX quotedblleft d -70
-KPX quotedblleft c -70
-KPX quotedblleft a -60
-KPX quotedblleft Y 30
-KPX quotedblleft X 20
-KPX quotedblleft W 40
-KPX quotedblleft V 40
-KPX quotedblleft T 18
-KPX quotedblleft J -24
-KPX quotedblleft A -122
-
-KPX quotedblright space -40
-KPX quotedblright period -100
-KPX quotedblright comma -100
-
-KPX quoteleft z -26
-KPX quoteleft y -5
-KPX quoteleft x -5
-KPX quoteleft w 5
-KPX quoteleft v -5
-KPX quoteleft u -25
-KPX quoteleft t -25
-KPX quoteleft s -40
-KPX quoteleft r -40
-KPX quoteleft quoteleft -30
-KPX quoteleft q -70
-KPX quoteleft p -40
-KPX quoteleft o -70
-KPX quoteleft n -40
-KPX quoteleft m -40
-KPX quoteleft g -50
-KPX quoteleft f -10
-KPX quoteleft e -70
-KPX quoteleft d -70
-KPX quoteleft c -70
-KPX quoteleft a -60
-KPX quoteleft Y 35
-KPX quoteleft X 30
-KPX quoteleft W 35
-KPX quoteleft V 35
-KPX quoteleft T 35
-KPX quoteleft J -24
-KPX quoteleft A -122
-
-KPX quoteright v -20
-KPX quoteright t -50
-KPX quoteright space -40
-KPX quoteright s -70
-KPX quoteright r -42
-KPX quoteright quoteright -30
-KPX quoteright period -100
-KPX quoteright m -42
-KPX quoteright l -6
-KPX quoteright d -100
-KPX quoteright comma -100
-
-KPX r z 20
-KPX r y 18
-KPX r x 12
-KPX r w 30
-KPX r v 30
-KPX r u 8
-KPX r t 8
-KPX r semicolon 20
-KPX r quoteright -20
-KPX r quotedblright -10
-KPX r q -6
-KPX r period -60
-KPX r o -6
-KPX r n 8
-KPX r m 8
-KPX r l -10
-KPX r k -10
-KPX r i 8
-KPX r hyphen -60
-KPX r h -10
-KPX r g 5
-KPX r f 8
-KPX r emdash -20
-KPX r e -20
-KPX r d -20
-KPX r comma -80
-KPX r colon 20
-KPX r c -20
-
-KPX s quoteright -40
-KPX s quotedblright -40
-
-KPX semicolon space -20
-
-KPX space quotesinglbase -100
-KPX space quoteleft -40
-KPX space quotedblleft -40
-KPX space quotedblbase -100
-KPX space Y -60
-KPX space W -60
-KPX space V -60
-KPX space T -40
-
-KPX t period 15
-KPX t comma 10
-
-KPX u quoteright -60
-KPX u quotedblright -60
-
-KPX v semicolon 20
-KPX v quoteright 5
-KPX v quotedblright 10
-KPX v q -15
-KPX v period -75
-KPX v o -15
-KPX v e -15
-KPX v d -15
-KPX v comma -90
-KPX v colon 20
-KPX v c -15
-KPX v a -15
-
-KPX w semicolon 20
-KPX w quoteright 15
-KPX w quotedblright 20
-KPX w q -10
-KPX w period -60
-KPX w o -10
-KPX w e -10
-KPX w d -10
-KPX w comma -68
-KPX w colon 20
-KPX w c -10
-
-KPX x quoteright -25
-KPX x quotedblright -20
-KPX x q -6
-KPX x o -6
-KPX x e -12
-KPX x d -12
-KPX x c -12
-
-KPX y semicolon 20
-KPX y quoteright 5
-KPX y quotedblright 10
-KPX y period -72
-KPX y hyphen -20
-KPX y comma -72
-KPX y colon 20
-
-KPX z quoteright -20
-KPX z quotedblright -20
-KPX z o -6
-KPX z e -6
-KPX z d -6
-KPX z c -6
-EndKernPairs
-EndKernData
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/putbi8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/putbi8a.afm
deleted file mode 100644
index 5e8384852c..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/putbi8a.afm
+++ /dev/null
@@ -1,1017 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Fri Jan 17 15:47:44 1992
-Comment UniqueID 37716
-Comment VMusage 34427 41319
-FontName Utopia-BoldItalic
-FullName Utopia Bold Italic
-FamilyName Utopia
-Weight Bold
-ItalicAngle -13
-IsFixedPitch false
-FontBBox -176 -250 1262 916
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.002
-Notice Copyright (c) 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.Utopia is a registered trademark of Adobe Systems Incorporated.
-EncodingScheme AdobeStandardEncoding
-CapHeight 692
-XHeight 502
-Ascender 742
-Descender -242
-StartCharMetrics 228
-C 32 ; WX 210 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 285 ; N exclam ; B 35 -12 336 707 ;
-C 34 ; WX 455 ; N quotedbl ; B 142 407 496 707 ;
-C 35 ; WX 560 ; N numbersign ; B 37 0 606 668 ;
-C 36 ; WX 560 ; N dollar ; B 32 -104 588 748 ;
-C 37 ; WX 896 ; N percent ; B 106 -31 861 702 ;
-C 38 ; WX 752 ; N ampersand ; B 62 -12 736 680 ;
-C 39 ; WX 246 ; N quoteright ; B 95 387 294 707 ;
-C 40 ; WX 350 ; N parenleft ; B 87 -135 438 699 ;
-C 41 ; WX 350 ; N parenright ; B -32 -135 319 699 ;
-C 42 ; WX 500 ; N asterisk ; B 121 315 528 707 ;
-C 43 ; WX 600 ; N plus ; B 83 0 567 490 ;
-C 44 ; WX 280 ; N comma ; B -9 -167 207 180 ;
-C 45 ; WX 392 ; N hyphen ; B 71 203 354 298 ;
-C 46 ; WX 280 ; N period ; B 32 -12 212 166 ;
-C 47 ; WX 260 ; N slash ; B -16 -15 370 707 ;
-C 48 ; WX 560 ; N zero ; B 57 -12 583 680 ;
-C 49 ; WX 560 ; N one ; B 72 0 470 680 ;
-C 50 ; WX 560 ; N two ; B 4 0 578 680 ;
-C 51 ; WX 560 ; N three ; B 21 -12 567 680 ;
-C 52 ; WX 560 ; N four ; B 28 0 557 668 ;
-C 53 ; WX 560 ; N five ; B 23 -12 593 668 ;
-C 54 ; WX 560 ; N six ; B 56 -12 586 680 ;
-C 55 ; WX 560 ; N seven ; B 112 -12 632 668 ;
-C 56 ; WX 560 ; N eight ; B 37 -12 584 680 ;
-C 57 ; WX 560 ; N nine ; B 48 -12 570 680 ;
-C 58 ; WX 280 ; N colon ; B 32 -12 280 490 ;
-C 59 ; WX 280 ; N semicolon ; B -9 -167 280 490 ;
-C 60 ; WX 600 ; N less ; B 66 5 544 495 ;
-C 61 ; WX 600 ; N equal ; B 83 103 567 397 ;
-C 62 ; WX 600 ; N greater ; B 86 5 564 495 ;
-C 63 ; WX 454 ; N question ; B 115 -12 515 707 ;
-C 64 ; WX 828 ; N at ; B 90 -15 842 707 ;
-C 65 ; WX 634 ; N A ; B -59 0 639 692 ;
-C 66 ; WX 680 ; N B ; B 5 0 689 692 ;
-C 67 ; WX 672 ; N C ; B 76 -15 742 707 ;
-C 68 ; WX 774 ; N D ; B 5 0 784 692 ;
-C 69 ; WX 622 ; N E ; B 5 0 687 692 ;
-C 70 ; WX 585 ; N F ; B 5 0 683 692 ;
-C 71 ; WX 726 ; N G ; B 76 -15 756 707 ;
-C 72 ; WX 800 ; N H ; B 5 0 880 692 ;
-C 73 ; WX 386 ; N I ; B 5 0 466 692 ;
-C 74 ; WX 388 ; N J ; B -50 -114 477 692 ;
-C 75 ; WX 688 ; N K ; B 5 -6 823 692 ;
-C 76 ; WX 586 ; N L ; B 5 0 591 692 ;
-C 77 ; WX 921 ; N M ; B 0 0 998 692 ;
-C 78 ; WX 741 ; N N ; B -5 0 838 692 ;
-C 79 ; WX 761 ; N O ; B 78 -15 768 707 ;
-C 80 ; WX 660 ; N P ; B 5 0 694 692 ;
-C 81 ; WX 761 ; N Q ; B 78 -193 768 707 ;
-C 82 ; WX 681 ; N R ; B 5 0 696 692 ;
-C 83 ; WX 551 ; N S ; B 31 -15 570 707 ;
-C 84 ; WX 616 ; N T ; B 91 0 722 692 ;
-C 85 ; WX 776 ; N U ; B 115 -15 867 692 ;
-C 86 ; WX 630 ; N V ; B 92 0 783 692 ;
-C 87 ; WX 920 ; N W ; B 80 0 1062 692 ;
-C 88 ; WX 630 ; N X ; B -56 0 744 692 ;
-C 89 ; WX 622 ; N Y ; B 92 0 765 692 ;
-C 90 ; WX 618 ; N Z ; B -30 0 714 692 ;
-C 91 ; WX 350 ; N bracketleft ; B 56 -128 428 692 ;
-C 92 ; WX 460 ; N backslash ; B 114 -15 425 707 ;
-C 93 ; WX 350 ; N bracketright ; B -22 -128 350 692 ;
-C 94 ; WX 600 ; N asciicircum ; B 79 215 567 668 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 246 ; N quoteleft ; B 114 399 313 719 ;
-C 97 ; WX 596 ; N a ; B 26 -12 612 502 ;
-C 98 ; WX 586 ; N b ; B 34 -12 592 742 ;
-C 99 ; WX 456 ; N c ; B 38 -12 498 502 ;
-C 100 ; WX 609 ; N d ; B 29 -12 651 742 ;
-C 101 ; WX 476 ; N e ; B 38 -12 497 502 ;
-C 102 ; WX 348 ; N f ; B -129 -242 553 742 ; L i fi ; L l fl ;
-C 103 ; WX 522 ; N g ; B -14 -242 609 512 ;
-C 104 ; WX 629 ; N h ; B 44 -12 631 742 ;
-C 105 ; WX 339 ; N i ; B 66 -12 357 720 ;
-C 106 ; WX 333 ; N j ; B -120 -242 364 720 ;
-C 107 ; WX 570 ; N k ; B 39 -12 604 742 ;
-C 108 ; WX 327 ; N l ; B 62 -12 360 742 ;
-C 109 ; WX 914 ; N m ; B 46 -12 917 502 ;
-C 110 ; WX 635 ; N n ; B 45 -12 639 502 ;
-C 111 ; WX 562 ; N o ; B 42 -12 556 502 ;
-C 112 ; WX 606 ; N p ; B 0 -242 613 502 ;
-C 113 ; WX 584 ; N q ; B 29 -242 604 513 ;
-C 114 ; WX 440 ; N r ; B 51 -12 497 502 ;
-C 115 ; WX 417 ; N s ; B 10 -12 432 502 ;
-C 116 ; WX 359 ; N t ; B 68 -12 428 641 ;
-C 117 ; WX 634 ; N u ; B 71 -12 643 502 ;
-C 118 ; WX 518 ; N v ; B 68 -12 547 502 ;
-C 119 ; WX 795 ; N w ; B 70 -12 826 502 ;
-C 120 ; WX 516 ; N x ; B -26 -12 546 502 ;
-C 121 ; WX 489 ; N y ; B -49 -242 532 502 ;
-C 122 ; WX 466 ; N z ; B -17 -12 506 490 ;
-C 123 ; WX 340 ; N braceleft ; B 90 -128 439 692 ;
-C 124 ; WX 265 ; N bar ; B 117 -250 221 750 ;
-C 125 ; WX 340 ; N braceright ; B -42 -128 307 692 ;
-C 126 ; WX 600 ; N asciitilde ; B 70 157 571 338 ;
-C 161 ; WX 285 ; N exclamdown ; B -13 -217 288 502 ;
-C 162 ; WX 560 ; N cent ; B 80 -21 611 668 ;
-C 163 ; WX 560 ; N sterling ; B -4 0 583 679 ;
-C 164 ; WX 100 ; N fraction ; B -176 -27 370 695 ;
-C 165 ; WX 560 ; N yen ; B 65 0 676 668 ;
-C 166 ; WX 560 ; N florin ; B -16 -135 635 691 ;
-C 167 ; WX 568 ; N section ; B 64 -115 559 707 ;
-C 168 ; WX 560 ; N currency ; B 60 73 578 596 ;
-C 169 ; WX 246 ; N quotesingle ; B 134 376 285 707 ;
-C 170 ; WX 455 ; N quotedblleft ; B 114 399 522 719 ;
-C 171 ; WX 560 ; N guillemotleft ; B 90 37 533 464 ;
-C 172 ; WX 360 ; N guilsinglleft ; B 90 37 333 464 ;
-C 173 ; WX 360 ; N guilsinglright ; B 58 37 301 464 ;
-C 174 ; WX 651 ; N fi ; B -129 -242 655 742 ;
-C 175 ; WX 652 ; N fl ; B -129 -242 685 742 ;
-C 177 ; WX 500 ; N endash ; B 12 209 531 292 ;
-C 178 ; WX 514 ; N dagger ; B 101 -125 545 707 ;
-C 179 ; WX 490 ; N daggerdbl ; B 32 -119 528 707 ;
-C 180 ; WX 280 ; N periodcentered ; B 67 161 247 339 ;
-C 182 ; WX 580 ; N paragraph ; B 110 -101 653 692 ;
-C 183 ; WX 465 ; N bullet ; B 99 174 454 529 ;
-C 184 ; WX 246 ; N quotesinglbase ; B -17 -153 182 167 ;
-C 185 ; WX 455 ; N quotedblbase ; B -17 -153 391 167 ;
-C 186 ; WX 455 ; N quotedblright ; B 95 387 503 707 ;
-C 187 ; WX 560 ; N guillemotright ; B 58 37 502 464 ;
-C 188 ; WX 1000 ; N ellipsis ; B 85 -12 931 166 ;
-C 189 ; WX 1297 ; N perthousand ; B 106 -31 1262 702 ;
-C 191 ; WX 454 ; N questiondown ; B -10 -217 391 502 ;
-C 193 ; WX 400 ; N grave ; B 109 511 381 740 ;
-C 194 ; WX 400 ; N acute ; B 186 511 458 740 ;
-C 195 ; WX 400 ; N circumflex ; B 93 520 471 747 ;
-C 196 ; WX 400 ; N tilde ; B 94 549 502 697 ;
-C 197 ; WX 400 ; N macron ; B 133 592 459 664 ;
-C 198 ; WX 400 ; N breve ; B 146 556 469 714 ;
-C 199 ; WX 402 ; N dotaccent ; B 220 561 378 710 ;
-C 200 ; WX 400 ; N dieresis ; B 106 561 504 710 ;
-C 202 ; WX 400 ; N ring ; B 166 529 423 762 ;
-C 203 ; WX 400 ; N cedilla ; B 85 -246 292 0 ;
-C 205 ; WX 400 ; N hungarumlaut ; B 158 546 482 750 ;
-C 206 ; WX 350 ; N ogonek ; B 38 -246 253 0 ;
-C 207 ; WX 400 ; N caron ; B 130 520 508 747 ;
-C 208 ; WX 1000 ; N emdash ; B 12 209 1031 292 ;
-C 225 ; WX 890 ; N AE ; B -107 0 958 692 ;
-C 227 ; WX 444 ; N ordfeminine ; B 62 265 482 590 ;
-C 232 ; WX 592 ; N Lslash ; B 11 0 597 692 ;
-C 233 ; WX 761 ; N Oslash ; B 77 -51 769 734 ;
-C 234 ; WX 1016 ; N OE ; B 76 0 1084 692 ;
-C 235 ; WX 412 ; N ordmasculine ; B 86 265 446 590 ;
-C 241 ; WX 789 ; N ae ; B 26 -12 810 509 ;
-C 245 ; WX 339 ; N dotlessi ; B 66 -12 343 502 ;
-C 248 ; WX 339 ; N lslash ; B 18 -12 420 742 ;
-C 249 ; WX 562 ; N oslash ; B 42 -69 556 549 ;
-C 250 ; WX 811 ; N oe ; B 42 -12 832 502 ;
-C 251 ; WX 628 ; N germandbls ; B -129 -242 692 742 ;
-C -1 ; WX 402 ; N onesuperior ; B 84 272 361 680 ;
-C -1 ; WX 600 ; N minus ; B 83 210 567 290 ;
-C -1 ; WX 375 ; N degree ; B 93 360 425 680 ;
-C -1 ; WX 562 ; N oacute ; B 42 -12 572 755 ;
-C -1 ; WX 761 ; N Odieresis ; B 78 -15 768 881 ;
-C -1 ; WX 562 ; N odieresis ; B 42 -12 585 710 ;
-C -1 ; WX 622 ; N Eacute ; B 5 0 687 904 ;
-C -1 ; WX 634 ; N ucircumflex ; B 71 -12 643 747 ;
-C -1 ; WX 940 ; N onequarter ; B 104 -27 849 695 ;
-C -1 ; WX 600 ; N logicalnot ; B 83 95 567 397 ;
-C -1 ; WX 622 ; N Ecircumflex ; B 5 0 687 905 ;
-C -1 ; WX 940 ; N onehalf ; B 90 -27 898 695 ;
-C -1 ; WX 761 ; N Otilde ; B 78 -15 768 876 ;
-C -1 ; WX 634 ; N uacute ; B 71 -12 643 740 ;
-C -1 ; WX 476 ; N eacute ; B 38 -12 545 755 ;
-C -1 ; WX 339 ; N iacute ; B 66 -12 438 740 ;
-C -1 ; WX 622 ; N Egrave ; B 5 0 687 904 ;
-C -1 ; WX 339 ; N icircumflex ; B 38 -12 416 747 ;
-C -1 ; WX 634 ; N mu ; B -3 -230 643 502 ;
-C -1 ; WX 265 ; N brokenbar ; B 117 -175 221 675 ;
-C -1 ; WX 600 ; N thorn ; B -6 -242 607 700 ;
-C -1 ; WX 634 ; N Aring ; B -59 0 639 879 ;
-C -1 ; WX 489 ; N yacute ; B -49 -242 553 740 ;
-C -1 ; WX 622 ; N Ydieresis ; B 92 0 765 881 ;
-C -1 ; WX 1100 ; N trademark ; B 103 277 1093 692 ;
-C -1 ; WX 824 ; N registered ; B 91 -15 819 707 ;
-C -1 ; WX 562 ; N ocircumflex ; B 42 -12 556 747 ;
-C -1 ; WX 634 ; N Agrave ; B -59 0 639 904 ;
-C -1 ; WX 551 ; N Scaron ; B 31 -15 612 916 ;
-C -1 ; WX 776 ; N Ugrave ; B 115 -15 867 904 ;
-C -1 ; WX 622 ; N Edieresis ; B 5 0 687 881 ;
-C -1 ; WX 776 ; N Uacute ; B 115 -15 867 904 ;
-C -1 ; WX 562 ; N otilde ; B 42 -12 583 697 ;
-C -1 ; WX 635 ; N ntilde ; B 45 -12 639 697 ;
-C -1 ; WX 489 ; N ydieresis ; B -49 -242 532 710 ;
-C -1 ; WX 634 ; N Aacute ; B -59 0 678 904 ;
-C -1 ; WX 562 ; N eth ; B 42 -12 558 742 ;
-C -1 ; WX 596 ; N acircumflex ; B 26 -12 612 747 ;
-C -1 ; WX 596 ; N aring ; B 26 -12 612 762 ;
-C -1 ; WX 761 ; N Ograve ; B 78 -15 768 904 ;
-C -1 ; WX 456 ; N ccedilla ; B 38 -246 498 502 ;
-C -1 ; WX 600 ; N multiply ; B 110 22 560 478 ;
-C -1 ; WX 600 ; N divide ; B 63 7 547 493 ;
-C -1 ; WX 402 ; N twosuperior ; B 29 272 423 680 ;
-C -1 ; WX 741 ; N Ntilde ; B -5 0 838 876 ;
-C -1 ; WX 634 ; N ugrave ; B 71 -12 643 740 ;
-C -1 ; WX 776 ; N Ucircumflex ; B 115 -15 867 905 ;
-C -1 ; WX 634 ; N Atilde ; B -59 0 662 876 ;
-C -1 ; WX 466 ; N zcaron ; B -17 -12 526 747 ;
-C -1 ; WX 339 ; N idieresis ; B 46 -12 444 710 ;
-C -1 ; WX 634 ; N Acircumflex ; B -59 0 639 905 ;
-C -1 ; WX 386 ; N Icircumflex ; B 5 0 506 905 ;
-C -1 ; WX 622 ; N Yacute ; B 92 0 765 904 ;
-C -1 ; WX 761 ; N Oacute ; B 78 -15 768 904 ;
-C -1 ; WX 634 ; N Adieresis ; B -59 0 652 881 ;
-C -1 ; WX 618 ; N Zcaron ; B -30 0 714 916 ;
-C -1 ; WX 596 ; N agrave ; B 26 -12 612 755 ;
-C -1 ; WX 402 ; N threesuperior ; B 59 265 421 680 ;
-C -1 ; WX 562 ; N ograve ; B 42 -12 556 755 ;
-C -1 ; WX 940 ; N threequarters ; B 95 -27 876 695 ;
-C -1 ; WX 780 ; N Eth ; B 11 0 790 692 ;
-C -1 ; WX 600 ; N plusminus ; B 83 0 567 549 ;
-C -1 ; WX 634 ; N udieresis ; B 71 -12 643 710 ;
-C -1 ; WX 476 ; N edieresis ; B 38 -12 542 710 ;
-C -1 ; WX 596 ; N aacute ; B 26 -12 621 755 ;
-C -1 ; WX 339 ; N igrave ; B 39 -12 343 740 ;
-C -1 ; WX 386 ; N Idieresis ; B 5 0 533 881 ;
-C -1 ; WX 596 ; N adieresis ; B 26 -12 612 710 ;
-C -1 ; WX 386 ; N Iacute ; B 5 0 549 904 ;
-C -1 ; WX 824 ; N copyright ; B 91 -15 819 707 ;
-C -1 ; WX 386 ; N Igrave ; B 5 0 466 904 ;
-C -1 ; WX 672 ; N Ccedilla ; B 76 -246 742 707 ;
-C -1 ; WX 417 ; N scaron ; B 10 -12 522 747 ;
-C -1 ; WX 476 ; N egrave ; B 38 -12 497 755 ;
-C -1 ; WX 761 ; N Ocircumflex ; B 78 -15 768 905 ;
-C -1 ; WX 629 ; N Thorn ; B 5 0 660 692 ;
-C -1 ; WX 596 ; N atilde ; B 26 -12 612 697 ;
-C -1 ; WX 776 ; N Udieresis ; B 115 -15 867 881 ;
-C -1 ; WX 476 ; N ecircumflex ; B 38 -12 524 747 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 697
-
-KPX A z 18
-KPX A y -40
-KPX A x 16
-KPX A w -30
-KPX A v -30
-KPX A u -18
-KPX A t -6
-KPX A s 6
-KPX A r -6
-KPX A quoteright -92
-KPX A quotedblright -92
-KPX A p -6
-KPX A o -18
-KPX A n -12
-KPX A m -12
-KPX A l -18
-KPX A h -6
-KPX A d 4
-KPX A c -6
-KPX A b -6
-KPX A a 10
-KPX A Y -56
-KPX A X -8
-KPX A W -46
-KPX A V -75
-KPX A U -50
-KPX A T -60
-KPX A Q -30
-KPX A O -30
-KPX A G -30
-KPX A C -30
-
-KPX B y -6
-KPX B u -12
-KPX B r -6
-KPX B quoteright -20
-KPX B quotedblright -32
-KPX B o 6
-KPX B l -20
-KPX B k -10
-KPX B i -12
-KPX B h -15
-KPX B e 4
-KPX B a 10
-KPX B W -30
-KPX B V -45
-KPX B U -30
-KPX B T -20
-
-KPX C z -6
-KPX C y -18
-KPX C u -12
-KPX C r -12
-KPX C quoteright 12
-KPX C quotedblright 20
-KPX C i -6
-KPX C e -6
-KPX C a -6
-KPX C Q -12
-KPX C O -12
-KPX C G -12
-KPX C C -12
-
-KPX D y 18
-KPX D quoteright -20
-KPX D quotedblright -20
-KPX D period -20
-KPX D o 6
-KPX D h -15
-KPX D e 6
-KPX D comma -20
-KPX D a 6
-KPX D Y -80
-KPX D W -40
-KPX D V -65
-
-KPX E z -6
-KPX E y -24
-KPX E x 15
-KPX E w -30
-KPX E v -18
-KPX E u -24
-KPX E t -18
-KPX E s -6
-KPX E r -6
-KPX E quoteright 10
-KPX E q 10
-KPX E period 15
-KPX E p -12
-KPX E n -12
-KPX E m -12
-KPX E l -6
-KPX E j -6
-KPX E i -12
-KPX E g -12
-KPX E d 10
-KPX E comma 15
-KPX E a 10
-
-KPX F y -12
-KPX F u -24
-KPX F r -12
-KPX F quoteright 40
-KPX F quotedblright 35
-KPX F period -120
-KPX F o -24
-KPX F i -6
-KPX F e -24
-KPX F comma -110
-KPX F a -30
-KPX F A -45
-
-KPX G y -25
-KPX G u -22
-KPX G r -22
-KPX G quoteright -30
-KPX G quotedblright -30
-KPX G n -22
-KPX G l -24
-KPX G i -12
-KPX G h -18
-KPX G e 5
-
-KPX H y -18
-KPX H u -30
-KPX H o -25
-KPX H i -25
-KPX H e -25
-KPX H a -25
-
-KPX I z -20
-KPX I y -6
-KPX I x -6
-KPX I w -30
-KPX I v -30
-KPX I u -30
-KPX I t -18
-KPX I s -18
-KPX I r -12
-KPX I p -18
-KPX I o -25
-KPX I n -18
-KPX I m -18
-KPX I l -6
-KPX I k -6
-KPX I j -20
-KPX I i -10
-KPX I g -24
-KPX I f -6
-KPX I e -25
-KPX I d -15
-KPX I c -25
-KPX I b -6
-KPX I a -15
-
-KPX J y -12
-KPX J u -32
-KPX J quoteright 6
-KPX J quotedblright 6
-KPX J o -36
-KPX J i -30
-KPX J e -30
-KPX J braceright 15
-KPX J a -36
-
-KPX K y -70
-KPX K w -36
-KPX K v -30
-KPX K u -30
-KPX K r -24
-KPX K quoteright 36
-KPX K quotedblright 36
-KPX K o -30
-KPX K n -24
-KPX K l 10
-KPX K i -12
-KPX K h 15
-KPX K e -30
-KPX K a -12
-KPX K Q -50
-KPX K O -50
-KPX K G -50
-KPX K C -50
-KPX K A 15
-
-KPX L y -70
-KPX L w -30
-KPX L u -18
-KPX L quoteright -110
-KPX L quotedblright -110
-KPX L l -16
-KPX L j -18
-KPX L i -18
-KPX L Y -80
-KPX L W -78
-KPX L V -110
-KPX L U -42
-KPX L T -100
-KPX L Q -48
-KPX L O -48
-KPX L G -48
-KPX L C -48
-KPX L A 40
-
-KPX M y -18
-KPX M u -24
-KPX M quoteright 6
-KPX M quotedblright 6
-KPX M o -25
-KPX M n -20
-KPX M j -35
-KPX M i -20
-KPX M e -25
-KPX M d -20
-KPX M c -25
-KPX M a -20
-
-KPX N y -18
-KPX N u -24
-KPX N o -18
-KPX N i -12
-KPX N e -16
-KPX N a -22
-
-KPX O z -6
-KPX O y 12
-KPX O u -6
-KPX O t -6
-KPX O s -6
-KPX O r -6
-KPX O quoteright -20
-KPX O quotedblright -20
-KPX O q 6
-KPX O period -10
-KPX O p -6
-KPX O n -6
-KPX O m -6
-KPX O l -15
-KPX O k -10
-KPX O j -6
-KPX O h -10
-KPX O g -6
-KPX O e 6
-KPX O d 6
-KPX O comma -10
-KPX O a 6
-KPX O Y -70
-KPX O X -30
-KPX O W -35
-KPX O V -50
-KPX O T -42
-KPX O A -8
-
-KPX P y 6
-KPX P u -18
-KPX P t -6
-KPX P s -24
-KPX P r -6
-KPX P quoteright -12
-KPX P period -170
-KPX P o -24
-KPX P n -12
-KPX P l -20
-KPX P h -20
-KPX P e -24
-KPX P comma -170
-KPX P a -40
-KPX P I -45
-KPX P H -45
-KPX P E -45
-KPX P A -70
-
-KPX Q u -6
-KPX Q quoteright -20
-KPX Q quotedblright -38
-KPX Q a -6
-KPX Q Y -70
-KPX Q X -12
-KPX Q W -35
-KPX Q V -50
-KPX Q U -30
-KPX Q T -36
-KPX Q A -18
-
-KPX R y -6
-KPX R u -12
-KPX R quoteright -22
-KPX R quotedblright -22
-KPX R o -20
-KPX R e -12
-KPX R Y -45
-KPX R X 15
-KPX R W -25
-KPX R V -35
-KPX R U -40
-KPX R T -18
-KPX R Q -8
-KPX R O -8
-KPX R G -8
-KPX R C -8
-KPX R A 15
-
-KPX S y -30
-KPX S w -30
-KPX S v -20
-KPX S u -18
-KPX S t -18
-KPX S r -20
-KPX S quoteright -38
-KPX S quotedblright -50
-KPX S p -18
-KPX S n -24
-KPX S m -24
-KPX S l -20
-KPX S k -18
-KPX S j -25
-KPX S i -20
-KPX S h -12
-KPX S e -6
-
-KPX T z -48
-KPX T y -52
-KPX T w -54
-KPX T u -54
-KPX T semicolon -6
-KPX T s -60
-KPX T r -54
-KPX T quoteright 36
-KPX T quotedblright 36
-KPX T period -70
-KPX T parenright 25
-KPX T o -78
-KPX T m -54
-KPX T i -22
-KPX T hyphen -100
-KPX T h 6
-KPX T endash -40
-KPX T emdash -40
-KPX T e -78
-KPX T comma -90
-KPX T bracketright 20
-KPX T braceright 30
-KPX T a -78
-KPX T Y 12
-KPX T X 18
-KPX T W 30
-KPX T V 20
-KPX T T 40
-KPX T Q -6
-KPX T O -6
-KPX T G -6
-KPX T C -6
-KPX T A -40
-
-KPX U z -18
-KPX U x -30
-KPX U v -20
-KPX U t -24
-KPX U s -40
-KPX U r -30
-KPX U p -30
-KPX U n -30
-KPX U m -30
-KPX U l -12
-KPX U k -12
-KPX U i -24
-KPX U h -6
-KPX U g -30
-KPX U f -10
-KPX U d -30
-KPX U c -30
-KPX U b -6
-KPX U a -30
-KPX U A -40
-
-KPX V y -34
-KPX V u -42
-KPX V semicolon -45
-KPX V r -55
-KPX V quoteright 46
-KPX V quotedblright 60
-KPX V period -110
-KPX V parenright 64
-KPX V o -55
-KPX V i 15
-KPX V hyphen -60
-KPX V endash -20
-KPX V emdash -20
-KPX V e -55
-KPX V comma -110
-KPX V colon -18
-KPX V bracketright 64
-KPX V braceright 64
-KPX V a -80
-KPX V T 12
-KPX V A -70
-
-KPX W y -36
-KPX W u -30
-KPX W t -10
-KPX W semicolon -12
-KPX W r -30
-KPX W quoteright 42
-KPX W quotedblright 55
-KPX W period -80
-KPX W parenright 55
-KPX W o -55
-KPX W m -30
-KPX W i 5
-KPX W hyphen -40
-KPX W h 16
-KPX W e -55
-KPX W d -60
-KPX W comma -80
-KPX W colon -12
-KPX W bracketright 64
-KPX W braceright 64
-KPX W a -60
-KPX W T 30
-KPX W Q -5
-KPX W O -5
-KPX W G -5
-KPX W C -5
-KPX W A -45
-
-KPX X y -40
-KPX X u -30
-KPX X r -6
-KPX X quoteright 24
-KPX X quotedblright 40
-KPX X i -6
-KPX X e -18
-KPX X a -6
-KPX X Y -6
-KPX X W -6
-KPX X Q -45
-KPX X O -45
-KPX X G -45
-KPX X C -45
-
-KPX Y v -60
-KPX Y u -70
-KPX Y t -32
-KPX Y semicolon -20
-KPX Y quoteright 56
-KPX Y quotedblright 70
-KPX Y q -100
-KPX Y period -80
-KPX Y parenright 5
-KPX Y o -95
-KPX Y l 15
-KPX Y i 15
-KPX Y hyphen -110
-KPX Y endash -40
-KPX Y emdash -40
-KPX Y e -95
-KPX Y d -85
-KPX Y comma -80
-KPX Y colon -20
-KPX Y bracketright 64
-KPX Y braceright 64
-KPX Y a -85
-KPX Y Y 12
-KPX Y X 12
-KPX Y W 12
-KPX Y V 6
-KPX Y T 30
-KPX Y Q -25
-KPX Y O -25
-KPX Y G -25
-KPX Y C -25
-KPX Y A -40
-
-KPX Z y -36
-KPX Z w -36
-KPX Z u -12
-KPX Z quoteright 18
-KPX Z quotedblright 18
-KPX Z o -6
-KPX Z i -12
-KPX Z e -6
-KPX Z a -6
-KPX Z Q -20
-KPX Z O -20
-KPX Z G -20
-KPX Z C -20
-KPX Z A 30
-
-KPX a quoteright -54
-KPX a quotedblright -54
-
-KPX b y -6
-KPX b w -5
-KPX b v -5
-KPX b quoteright -30
-KPX b quotedblright -30
-KPX b period -15
-KPX b comma -15
-
-KPX braceleft Y 64
-KPX braceleft W 64
-KPX braceleft V 64
-KPX braceleft T 40
-KPX braceleft J 60
-
-KPX bracketleft Y 60
-KPX bracketleft W 64
-KPX bracketleft V 64
-KPX bracketleft T 35
-KPX bracketleft J 30
-
-KPX c quoteright 5
-KPX c quotedblright 5
-
-KPX colon space -30
-
-KPX comma space -40
-KPX comma quoteright -100
-KPX comma quotedblright -100
-
-KPX d quoteright -12
-KPX d quotedblright -12
-KPX d period 15
-KPX d comma 15
-
-KPX e y 6
-KPX e x -10
-KPX e w -10
-KPX e v -10
-KPX e quoteright -25
-KPX e quotedblright -25
-
-KPX f quoteright 120
-KPX f quotedblright 120
-KPX f period -30
-KPX f parenright 100
-KPX f comma -30
-KPX f bracketright 110
-KPX f braceright 110
-
-KPX g y 50
-KPX g quotedblright -20
-KPX g p 30
-KPX g f 42
-KPX g comma 20
-
-KPX h quoteright -78
-KPX h quotedblright -78
-
-KPX i quoteright -20
-KPX i quotedblright -20
-
-KPX j quoteright -20
-KPX j quotedblright -20
-KPX j period -20
-KPX j comma -20
-
-KPX k quoteright -38
-KPX k quotedblright -38
-
-KPX l quoteright -12
-KPX l quotedblright -12
-
-KPX m quoteright -78
-KPX m quotedblright -78
-
-KPX n quoteright -88
-KPX n quotedblright -88
-
-KPX o y -12
-KPX o x -20
-KPX o w -25
-KPX o v -25
-KPX o quoteright -50
-KPX o quotedblright -50
-KPX o period -10
-KPX o comma -10
-
-KPX p w -6
-KPX p quoteright -30
-KPX p quotedblright -52
-KPX p period -15
-KPX p comma -15
-
-KPX parenleft Y 64
-KPX parenleft W 64
-KPX parenleft V 64
-KPX parenleft T 30
-KPX parenleft J 50
-
-KPX period space -40
-KPX period quoteright -100
-KPX period quotedblright -100
-
-KPX q quoteright -40
-KPX q quotedblright -40
-KPX q period -10
-KPX q comma -5
-
-KPX quotedblleft z -30
-KPX quotedblleft x -60
-KPX quotedblleft w -12
-KPX quotedblleft v -12
-KPX quotedblleft u -12
-KPX quotedblleft t 5
-KPX quotedblleft s -30
-KPX quotedblleft r -12
-KPX quotedblleft q -50
-KPX quotedblleft p -12
-KPX quotedblleft o -30
-KPX quotedblleft n -12
-KPX quotedblleft m -12
-KPX quotedblleft l 10
-KPX quotedblleft k 10
-KPX quotedblleft h 10
-KPX quotedblleft g -30
-KPX quotedblleft e -30
-KPX quotedblleft d -50
-KPX quotedblleft c -30
-KPX quotedblleft b 24
-KPX quotedblleft a -50
-KPX quotedblleft Y 30
-KPX quotedblleft X 45
-KPX quotedblleft W 55
-KPX quotedblleft V 40
-KPX quotedblleft T 36
-KPX quotedblleft A -100
-
-KPX quotedblright space -50
-KPX quotedblright period -200
-KPX quotedblright comma -200
-
-KPX quoteleft z -30
-KPX quoteleft y 30
-KPX quoteleft x -10
-KPX quoteleft w -12
-KPX quoteleft u -12
-KPX quoteleft t -30
-KPX quoteleft s -30
-KPX quoteleft r -12
-KPX quoteleft q -30
-KPX quoteleft p -12
-KPX quoteleft o -30
-KPX quoteleft n -12
-KPX quoteleft m -12
-KPX quoteleft l 10
-KPX quoteleft k 10
-KPX quoteleft h 10
-KPX quoteleft g -30
-KPX quoteleft e -30
-KPX quoteleft d -30
-KPX quoteleft c -30
-KPX quoteleft b 24
-KPX quoteleft a -30
-KPX quoteleft Y 12
-KPX quoteleft X 46
-KPX quoteleft W 46
-KPX quoteleft V 28
-KPX quoteleft T 36
-KPX quoteleft A -100
-
-KPX quoteright v -20
-KPX quoteright space -50
-KPX quoteright s -45
-KPX quoteright r -12
-KPX quoteright period -140
-KPX quoteright m -12
-KPX quoteright l -12
-KPX quoteright d -65
-KPX quoteright comma -140
-
-KPX r z 20
-KPX r y 18
-KPX r x 12
-KPX r w 6
-KPX r v 6
-KPX r t 8
-KPX r semicolon 20
-KPX r quoteright -6
-KPX r quotedblright -6
-KPX r q -24
-KPX r period -100
-KPX r o -6
-KPX r l -12
-KPX r k -12
-KPX r hyphen -40
-KPX r h -10
-KPX r f 8
-KPX r endash -20
-KPX r e -26
-KPX r d -25
-KPX r comma -100
-KPX r colon 20
-KPX r c -12
-KPX r a -25
-
-KPX s quoteright -25
-KPX s quotedblright -30
-
-KPX semicolon space -30
-
-KPX space quotesinglbase -60
-KPX space quoteleft -60
-KPX space quotedblleft -60
-KPX space quotedblbase -60
-KPX space Y -70
-KPX space W -50
-KPX space V -70
-KPX space T -50
-KPX space A -50
-
-KPX t quoteright 15
-KPX t quotedblright 15
-KPX t period 15
-KPX t comma 15
-
-KPX u quoteright -65
-KPX u quotedblright -78
-KPX u period 20
-KPX u comma 20
-
-KPX v quoteright -10
-KPX v quotedblright -10
-KPX v q -6
-KPX v period -62
-KPX v o -6
-KPX v e -6
-KPX v d -6
-KPX v comma -62
-KPX v c -6
-KPX v a -6
-
-KPX w quoteright -10
-KPX w quotedblright -10
-KPX w period -40
-KPX w comma -50
-
-KPX x y 12
-KPX x w -6
-KPX x quoteright -30
-KPX x quotedblright -30
-KPX x q -6
-KPX x o -6
-KPX x e -6
-KPX x d -6
-KPX x c -6
-
-KPX y quoteright -10
-KPX y quotedblright -10
-KPX y q -10
-KPX y period -56
-KPX y d -10
-KPX y comma -56
-
-KPX z quoteright -40
-KPX z quotedblright -40
-KPX z o -6
-KPX z e -6
-KPX z d -6
-KPX z c -6
-EndKernPairs
-EndKernData
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/putr8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/putr8a.afm
deleted file mode 100644
index be1bb781ad..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/putr8a.afm
+++ /dev/null
@@ -1,1029 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Fri Jan 17 13:38:17 1992
-Comment UniqueID 37674
-Comment VMusage 32991 39883
-FontName Utopia-Regular
-FullName Utopia Regular
-FamilyName Utopia
-Weight Regular
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -158 -250 1158 890
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.002
-Notice Copyright (c) 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.Utopia is a registered trademark of Adobe Systems Incorporated.
-EncodingScheme AdobeStandardEncoding
-CapHeight 692
-XHeight 490
-Ascender 742
-Descender -230
-StartCharMetrics 228
-C 32 ; WX 225 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 242 ; N exclam ; B 58 -12 184 707 ;
-C 34 ; WX 458 ; N quotedbl ; B 101 464 358 742 ;
-C 35 ; WX 530 ; N numbersign ; B 11 0 519 668 ;
-C 36 ; WX 530 ; N dollar ; B 44 -102 487 743 ;
-C 37 ; WX 838 ; N percent ; B 50 -25 788 700 ;
-C 38 ; WX 706 ; N ampersand ; B 46 -12 692 680 ;
-C 39 ; WX 278 ; N quoteright ; B 72 472 207 742 ;
-C 40 ; WX 350 ; N parenleft ; B 105 -128 325 692 ;
-C 41 ; WX 350 ; N parenright ; B 25 -128 245 692 ;
-C 42 ; WX 412 ; N asterisk ; B 50 356 363 707 ;
-C 43 ; WX 570 ; N plus ; B 43 0 527 490 ;
-C 44 ; WX 265 ; N comma ; B 51 -141 193 141 ;
-C 45 ; WX 392 ; N hyphen ; B 74 216 319 286 ;
-C 46 ; WX 265 ; N period ; B 70 -12 196 116 ;
-C 47 ; WX 460 ; N slash ; B 92 -15 369 707 ;
-C 48 ; WX 530 ; N zero ; B 41 -12 489 680 ;
-C 49 ; WX 530 ; N one ; B 109 0 437 680 ;
-C 50 ; WX 530 ; N two ; B 27 0 485 680 ;
-C 51 ; WX 530 ; N three ; B 27 -12 473 680 ;
-C 52 ; WX 530 ; N four ; B 19 0 493 668 ;
-C 53 ; WX 530 ; N five ; B 40 -12 480 668 ;
-C 54 ; WX 530 ; N six ; B 44 -12 499 680 ;
-C 55 ; WX 530 ; N seven ; B 41 -12 497 668 ;
-C 56 ; WX 530 ; N eight ; B 42 -12 488 680 ;
-C 57 ; WX 530 ; N nine ; B 36 -12 477 680 ;
-C 58 ; WX 265 ; N colon ; B 70 -12 196 490 ;
-C 59 ; WX 265 ; N semicolon ; B 51 -141 196 490 ;
-C 60 ; WX 570 ; N less ; B 46 1 524 499 ;
-C 61 ; WX 570 ; N equal ; B 43 111 527 389 ;
-C 62 ; WX 570 ; N greater ; B 46 1 524 499 ;
-C 63 ; WX 389 ; N question ; B 29 -12 359 707 ;
-C 64 ; WX 793 ; N at ; B 46 -15 755 707 ;
-C 65 ; WX 635 ; N A ; B -29 0 650 692 ;
-C 66 ; WX 646 ; N B ; B 35 0 595 692 ;
-C 67 ; WX 684 ; N C ; B 48 -15 649 707 ;
-C 68 ; WX 779 ; N D ; B 35 0 731 692 ;
-C 69 ; WX 606 ; N E ; B 35 0 577 692 ;
-C 70 ; WX 580 ; N F ; B 35 0 543 692 ;
-C 71 ; WX 734 ; N G ; B 48 -15 725 707 ;
-C 72 ; WX 798 ; N H ; B 35 0 763 692 ;
-C 73 ; WX 349 ; N I ; B 35 0 314 692 ;
-C 74 ; WX 350 ; N J ; B 0 -114 323 692 ;
-C 75 ; WX 658 ; N K ; B 35 -5 671 692 ;
-C 76 ; WX 568 ; N L ; B 35 0 566 692 ;
-C 77 ; WX 944 ; N M ; B 33 0 909 692 ;
-C 78 ; WX 780 ; N N ; B 34 0 753 692 ;
-C 79 ; WX 762 ; N O ; B 48 -15 714 707 ;
-C 80 ; WX 600 ; N P ; B 35 0 574 692 ;
-C 81 ; WX 762 ; N Q ; B 48 -193 714 707 ;
-C 82 ; WX 644 ; N R ; B 35 0 638 692 ;
-C 83 ; WX 541 ; N S ; B 50 -15 504 707 ;
-C 84 ; WX 621 ; N T ; B 22 0 599 692 ;
-C 85 ; WX 791 ; N U ; B 29 -15 762 692 ;
-C 86 ; WX 634 ; N V ; B -18 0 678 692 ;
-C 87 ; WX 940 ; N W ; B -13 0 977 692 ;
-C 88 ; WX 624 ; N X ; B -19 0 657 692 ;
-C 89 ; WX 588 ; N Y ; B -12 0 632 692 ;
-C 90 ; WX 610 ; N Z ; B 9 0 594 692 ;
-C 91 ; WX 330 ; N bracketleft ; B 133 -128 292 692 ;
-C 92 ; WX 460 ; N backslash ; B 91 -15 369 707 ;
-C 93 ; WX 330 ; N bracketright ; B 38 -128 197 692 ;
-C 94 ; WX 570 ; N asciicircum ; B 56 228 514 668 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 278 ; N quoteleft ; B 72 478 207 748 ;
-C 97 ; WX 523 ; N a ; B 49 -12 525 502 ;
-C 98 ; WX 598 ; N b ; B 20 -12 549 742 ;
-C 99 ; WX 496 ; N c ; B 49 -12 473 502 ;
-C 100 ; WX 598 ; N d ; B 49 -12 583 742 ;
-C 101 ; WX 514 ; N e ; B 49 -12 481 502 ;
-C 102 ; WX 319 ; N f ; B 30 0 389 742 ; L i fi ; L l fl ;
-C 103 ; WX 520 ; N g ; B 42 -242 525 512 ;
-C 104 ; WX 607 ; N h ; B 21 0 592 742 ;
-C 105 ; WX 291 ; N i ; B 32 0 276 715 ;
-C 106 ; WX 280 ; N j ; B -33 -242 214 715 ;
-C 107 ; WX 524 ; N k ; B 20 -5 538 742 ;
-C 108 ; WX 279 ; N l ; B 20 0 264 742 ;
-C 109 ; WX 923 ; N m ; B 32 0 908 502 ;
-C 110 ; WX 619 ; N n ; B 32 0 604 502 ;
-C 111 ; WX 577 ; N o ; B 49 -12 528 502 ;
-C 112 ; WX 608 ; N p ; B 25 -230 559 502 ;
-C 113 ; WX 591 ; N q ; B 49 -230 583 502 ;
-C 114 ; WX 389 ; N r ; B 32 0 386 502 ;
-C 115 ; WX 436 ; N s ; B 47 -12 400 502 ;
-C 116 ; WX 344 ; N t ; B 31 -12 342 616 ;
-C 117 ; WX 606 ; N u ; B 26 -12 591 502 ;
-C 118 ; WX 504 ; N v ; B 1 0 529 490 ;
-C 119 ; WX 768 ; N w ; B -2 0 792 490 ;
-C 120 ; WX 486 ; N x ; B 1 0 509 490 ;
-C 121 ; WX 506 ; N y ; B -5 -242 528 490 ;
-C 122 ; WX 480 ; N z ; B 19 0 462 490 ;
-C 123 ; WX 340 ; N braceleft ; B 79 -128 298 692 ;
-C 124 ; WX 228 ; N bar ; B 80 -250 148 750 ;
-C 125 ; WX 340 ; N braceright ; B 42 -128 261 692 ;
-C 126 ; WX 570 ; N asciitilde ; B 73 175 497 317 ;
-C 161 ; WX 242 ; N exclamdown ; B 58 -217 184 502 ;
-C 162 ; WX 530 ; N cent ; B 37 -10 487 675 ;
-C 163 ; WX 530 ; N sterling ; B 27 0 510 680 ;
-C 164 ; WX 150 ; N fraction ; B -158 -27 308 695 ;
-C 165 ; WX 530 ; N yen ; B -2 0 525 668 ;
-C 166 ; WX 530 ; N florin ; B -2 -135 522 691 ;
-C 167 ; WX 554 ; N section ; B 46 -115 507 707 ;
-C 168 ; WX 530 ; N currency ; B 25 90 505 578 ;
-C 169 ; WX 278 ; N quotesingle ; B 93 464 185 742 ;
-C 170 ; WX 458 ; N quotedblleft ; B 72 478 387 748 ;
-C 171 ; WX 442 ; N guillemotleft ; B 41 41 401 435 ;
-C 172 ; WX 257 ; N guilsinglleft ; B 41 41 216 435 ;
-C 173 ; WX 257 ; N guilsinglright ; B 41 41 216 435 ;
-C 174 ; WX 610 ; N fi ; B 30 0 595 742 ;
-C 175 ; WX 610 ; N fl ; B 30 0 595 742 ;
-C 177 ; WX 500 ; N endash ; B 0 221 500 279 ;
-C 178 ; WX 504 ; N dagger ; B 45 -125 459 717 ;
-C 179 ; WX 488 ; N daggerdbl ; B 45 -119 443 717 ;
-C 180 ; WX 265 ; N periodcentered ; B 70 188 196 316 ;
-C 182 ; WX 555 ; N paragraph ; B 64 -101 529 692 ;
-C 183 ; WX 409 ; N bullet ; B 45 192 364 512 ;
-C 184 ; WX 278 ; N quotesinglbase ; B 72 -125 207 145 ;
-C 185 ; WX 458 ; N quotedblbase ; B 72 -125 387 145 ;
-C 186 ; WX 458 ; N quotedblright ; B 72 472 387 742 ;
-C 187 ; WX 442 ; N guillemotright ; B 41 41 401 435 ;
-C 188 ; WX 1000 ; N ellipsis ; B 104 -12 896 116 ;
-C 189 ; WX 1208 ; N perthousand ; B 50 -25 1158 700 ;
-C 191 ; WX 389 ; N questiondown ; B 30 -217 360 502 ;
-C 193 ; WX 400 ; N grave ; B 49 542 271 723 ;
-C 194 ; WX 400 ; N acute ; B 129 542 351 723 ;
-C 195 ; WX 400 ; N circumflex ; B 47 541 353 720 ;
-C 196 ; WX 400 ; N tilde ; B 22 563 377 682 ;
-C 197 ; WX 400 ; N macron ; B 56 597 344 656 ;
-C 198 ; WX 400 ; N breve ; B 63 568 337 704 ;
-C 199 ; WX 400 ; N dotaccent ; B 140 570 260 683 ;
-C 200 ; WX 400 ; N dieresis ; B 36 570 364 683 ;
-C 202 ; WX 400 ; N ring ; B 92 550 308 752 ;
-C 203 ; WX 400 ; N cedilla ; B 163 -230 329 0 ;
-C 205 ; WX 400 ; N hungarumlaut ; B 101 546 380 750 ;
-C 206 ; WX 400 ; N ogonek ; B 103 -230 295 0 ;
-C 207 ; WX 400 ; N caron ; B 47 541 353 720 ;
-C 208 ; WX 1000 ; N emdash ; B 0 221 1000 279 ;
-C 225 ; WX 876 ; N AE ; B -63 0 847 692 ;
-C 227 ; WX 390 ; N ordfeminine ; B 40 265 364 590 ;
-C 232 ; WX 574 ; N Lslash ; B 36 0 572 692 ;
-C 233 ; WX 762 ; N Oslash ; B 48 -53 714 739 ;
-C 234 ; WX 1025 ; N OE ; B 48 0 996 692 ;
-C 235 ; WX 398 ; N ordmasculine ; B 35 265 363 590 ;
-C 241 ; WX 797 ; N ae ; B 49 -12 764 502 ;
-C 245 ; WX 291 ; N dotlessi ; B 32 0 276 502 ;
-C 248 ; WX 294 ; N lslash ; B 14 0 293 742 ;
-C 249 ; WX 577 ; N oslash ; B 49 -41 528 532 ;
-C 250 ; WX 882 ; N oe ; B 49 -12 849 502 ;
-C 251 ; WX 601 ; N germandbls ; B 22 -12 573 742 ;
-C -1 ; WX 380 ; N onesuperior ; B 81 272 307 680 ;
-C -1 ; WX 570 ; N minus ; B 43 221 527 279 ;
-C -1 ; WX 350 ; N degree ; B 37 404 313 680 ;
-C -1 ; WX 577 ; N oacute ; B 49 -12 528 723 ;
-C -1 ; WX 762 ; N Odieresis ; B 48 -15 714 841 ;
-C -1 ; WX 577 ; N odieresis ; B 49 -12 528 683 ;
-C -1 ; WX 606 ; N Eacute ; B 35 0 577 890 ;
-C -1 ; WX 606 ; N ucircumflex ; B 26 -12 591 720 ;
-C -1 ; WX 860 ; N onequarter ; B 65 -27 795 695 ;
-C -1 ; WX 570 ; N logicalnot ; B 43 102 527 389 ;
-C -1 ; WX 606 ; N Ecircumflex ; B 35 0 577 876 ;
-C -1 ; WX 860 ; N onehalf ; B 58 -27 807 695 ;
-C -1 ; WX 762 ; N Otilde ; B 48 -15 714 842 ;
-C -1 ; WX 606 ; N uacute ; B 26 -12 591 723 ;
-C -1 ; WX 514 ; N eacute ; B 49 -12 481 723 ;
-C -1 ; WX 291 ; N iacute ; B 32 0 317 723 ;
-C -1 ; WX 606 ; N Egrave ; B 35 0 577 890 ;
-C -1 ; WX 291 ; N icircumflex ; B -3 0 304 720 ;
-C -1 ; WX 606 ; N mu ; B 26 -246 591 502 ;
-C -1 ; WX 228 ; N brokenbar ; B 80 -175 148 675 ;
-C -1 ; WX 606 ; N thorn ; B 23 -230 557 722 ;
-C -1 ; WX 627 ; N Aring ; B -32 0 647 861 ;
-C -1 ; WX 506 ; N yacute ; B -5 -242 528 723 ;
-C -1 ; WX 588 ; N Ydieresis ; B -12 0 632 841 ;
-C -1 ; WX 1100 ; N trademark ; B 45 277 1048 692 ;
-C -1 ; WX 818 ; N registered ; B 45 -15 773 707 ;
-C -1 ; WX 577 ; N ocircumflex ; B 49 -12 528 720 ;
-C -1 ; WX 635 ; N Agrave ; B -29 0 650 890 ;
-C -1 ; WX 541 ; N Scaron ; B 50 -15 504 882 ;
-C -1 ; WX 791 ; N Ugrave ; B 29 -15 762 890 ;
-C -1 ; WX 606 ; N Edieresis ; B 35 0 577 841 ;
-C -1 ; WX 791 ; N Uacute ; B 29 -15 762 890 ;
-C -1 ; WX 577 ; N otilde ; B 49 -12 528 682 ;
-C -1 ; WX 619 ; N ntilde ; B 32 0 604 682 ;
-C -1 ; WX 506 ; N ydieresis ; B -5 -242 528 683 ;
-C -1 ; WX 635 ; N Aacute ; B -29 0 650 890 ;
-C -1 ; WX 577 ; N eth ; B 49 -12 528 742 ;
-C -1 ; WX 523 ; N acircumflex ; B 49 -12 525 720 ;
-C -1 ; WX 523 ; N aring ; B 49 -12 525 752 ;
-C -1 ; WX 762 ; N Ograve ; B 48 -15 714 890 ;
-C -1 ; WX 496 ; N ccedilla ; B 49 -230 473 502 ;
-C -1 ; WX 570 ; N multiply ; B 63 22 507 478 ;
-C -1 ; WX 570 ; N divide ; B 43 26 527 474 ;
-C -1 ; WX 380 ; N twosuperior ; B 32 272 348 680 ;
-C -1 ; WX 780 ; N Ntilde ; B 34 0 753 842 ;
-C -1 ; WX 606 ; N ugrave ; B 26 -12 591 723 ;
-C -1 ; WX 791 ; N Ucircumflex ; B 29 -15 762 876 ;
-C -1 ; WX 635 ; N Atilde ; B -29 0 650 842 ;
-C -1 ; WX 480 ; N zcaron ; B 19 0 462 720 ;
-C -1 ; WX 291 ; N idieresis ; B -19 0 310 683 ;
-C -1 ; WX 635 ; N Acircumflex ; B -29 0 650 876 ;
-C -1 ; WX 349 ; N Icircumflex ; B 22 0 328 876 ;
-C -1 ; WX 588 ; N Yacute ; B -12 0 632 890 ;
-C -1 ; WX 762 ; N Oacute ; B 48 -15 714 890 ;
-C -1 ; WX 635 ; N Adieresis ; B -29 0 650 841 ;
-C -1 ; WX 610 ; N Zcaron ; B 9 0 594 882 ;
-C -1 ; WX 523 ; N agrave ; B 49 -12 525 723 ;
-C -1 ; WX 380 ; N threesuperior ; B 36 265 339 680 ;
-C -1 ; WX 577 ; N ograve ; B 49 -12 528 723 ;
-C -1 ; WX 860 ; N threequarters ; B 50 -27 808 695 ;
-C -1 ; WX 785 ; N Eth ; B 20 0 737 692 ;
-C -1 ; WX 570 ; N plusminus ; B 43 0 527 556 ;
-C -1 ; WX 606 ; N udieresis ; B 26 -12 591 683 ;
-C -1 ; WX 514 ; N edieresis ; B 49 -12 481 683 ;
-C -1 ; WX 523 ; N aacute ; B 49 -12 525 723 ;
-C -1 ; WX 291 ; N igrave ; B -35 0 276 723 ;
-C -1 ; WX 349 ; N Idieresis ; B 13 0 337 841 ;
-C -1 ; WX 523 ; N adieresis ; B 49 -12 525 683 ;
-C -1 ; WX 349 ; N Iacute ; B 35 0 371 890 ;
-C -1 ; WX 818 ; N copyright ; B 45 -15 773 707 ;
-C -1 ; WX 349 ; N Igrave ; B -17 0 314 890 ;
-C -1 ; WX 680 ; N Ccedilla ; B 48 -230 649 707 ;
-C -1 ; WX 436 ; N scaron ; B 47 -12 400 720 ;
-C -1 ; WX 514 ; N egrave ; B 49 -12 481 723 ;
-C -1 ; WX 762 ; N Ocircumflex ; B 48 -15 714 876 ;
-C -1 ; WX 593 ; N Thorn ; B 35 0 556 692 ;
-C -1 ; WX 523 ; N atilde ; B 49 -12 525 682 ;
-C -1 ; WX 791 ; N Udieresis ; B 29 -15 762 841 ;
-C -1 ; WX 514 ; N ecircumflex ; B 49 -12 481 720 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 712
-
-KPX A z 6
-KPX A y -50
-KPX A w -45
-KPX A v -60
-KPX A u -25
-KPX A t -12
-KPX A quoteright -120
-KPX A quotedblright -120
-KPX A q -6
-KPX A p -18
-KPX A o -12
-KPX A e -6
-KPX A d -12
-KPX A c -12
-KPX A b -12
-KPX A Y -70
-KPX A X -6
-KPX A W -58
-KPX A V -72
-KPX A U -50
-KPX A T -70
-KPX A Q -24
-KPX A O -24
-KPX A G -24
-KPX A C -24
-
-KPX B y -18
-KPX B u -12
-KPX B r -12
-KPX B period -30
-KPX B o -6
-KPX B l -12
-KPX B i -12
-KPX B h -12
-KPX B e -6
-KPX B comma -20
-KPX B a -12
-KPX B W -25
-KPX B V -20
-KPX B U -20
-KPX B T -20
-
-KPX C z -18
-KPX C y -24
-KPX C u -18
-KPX C r -6
-KPX C o -12
-KPX C e -12
-KPX C a -12
-KPX C Q -6
-KPX C O -6
-KPX C G -6
-KPX C C -6
-
-KPX D y 6
-KPX D u -12
-KPX D r -12
-KPX D quoteright -20
-KPX D quotedblright -20
-KPX D period -60
-KPX D i -6
-KPX D h -12
-KPX D e -6
-KPX D comma -50
-KPX D a -6
-KPX D Y -45
-KPX D W -35
-KPX D V -35
-
-KPX E z -6
-KPX E y -30
-KPX E x -6
-KPX E w -24
-KPX E v -24
-KPX E u -12
-KPX E t -18
-KPX E r -4
-KPX E q -6
-KPX E p -18
-KPX E o -6
-KPX E n -4
-KPX E m -4
-KPX E l 5
-KPX E k 5
-KPX E j -6
-KPX E i -6
-KPX E g -6
-KPX E f -12
-KPX E e -6
-KPX E d -6
-KPX E c -6
-KPX E b -12
-KPX E Y -6
-KPX E W -6
-KPX E V -6
-
-KPX F y -18
-KPX F u -12
-KPX F r -20
-KPX F period -180
-KPX F o -36
-KPX F l -12
-KPX F i -10
-KPX F endash 20
-KPX F e -36
-KPX F comma -180
-KPX F a -48
-KPX F A -60
-
-KPX G y -18
-KPX G u -12
-KPX G r -5
-KPX G o 5
-KPX G n -5
-KPX G l -6
-KPX G i -12
-KPX G h -12
-KPX G e 5
-KPX G a -12
-
-KPX H y -24
-KPX H u -26
-KPX H o -30
-KPX H i -18
-KPX H e -30
-KPX H a -24
-
-KPX I z -6
-KPX I y -6
-KPX I x -6
-KPX I w -18
-KPX I v -24
-KPX I u -26
-KPX I t -24
-KPX I s -18
-KPX I r -12
-KPX I p -26
-KPX I o -30
-KPX I n -18
-KPX I m -18
-KPX I l -6
-KPX I k -6
-KPX I h -6
-KPX I g -10
-KPX I f -6
-KPX I e -30
-KPX I d -30
-KPX I c -30
-KPX I b -6
-KPX I a -24
-
-KPX J y -12
-KPX J u -36
-KPX J o -30
-KPX J i -20
-KPX J e -30
-KPX J bracketright 20
-KPX J braceright 20
-KPX J a -36
-
-KPX K y -60
-KPX K w -70
-KPX K v -70
-KPX K u -42
-KPX K o -30
-KPX K i 6
-KPX K e -24
-KPX K a -12
-KPX K Q -42
-KPX K O -42
-KPX K G -42
-KPX K C -42
-
-KPX L y -52
-KPX L w -58
-KPX L u -12
-KPX L quoteright -130
-KPX L quotedblright -50
-KPX L l 6
-KPX L j -6
-KPX L Y -70
-KPX L W -90
-KPX L V -100
-KPX L U -24
-KPX L T -100
-KPX L Q -18
-KPX L O -10
-KPX L G -18
-KPX L C -18
-KPX L A 12
-
-KPX M y -24
-KPX M u -36
-KPX M o -30
-KPX M n -6
-KPX M j -12
-KPX M i -12
-KPX M e -30
-KPX M d -30
-KPX M c -30
-KPX M a -12
-
-KPX N y -24
-KPX N u -30
-KPX N o -30
-KPX N i -24
-KPX N e -30
-KPX N a -30
-
-KPX O z -6
-KPX O u -6
-KPX O t -6
-KPX O s -6
-KPX O q -6
-KPX O period -60
-KPX O p -6
-KPX O o -6
-KPX O n -5
-KPX O m -5
-KPX O l -6
-KPX O k -6
-KPX O i -5
-KPX O h -12
-KPX O g -6
-KPX O e -6
-KPX O d -6
-KPX O comma -50
-KPX O c -6
-KPX O a -12
-KPX O Y -55
-KPX O X -24
-KPX O W -30
-KPX O V -18
-KPX O T -30
-KPX O A -18
-
-KPX P u -12
-KPX P t -6
-KPX P s -24
-KPX P r -12
-KPX P period -200
-KPX P o -30
-KPX P n -12
-KPX P l -6
-KPX P hyphen -40
-KPX P h -6
-KPX P e -30
-KPX P comma -200
-KPX P a -36
-KPX P I -6
-KPX P H -12
-KPX P E -6
-KPX P A -55
-
-KPX Q u -6
-KPX Q a -18
-KPX Q Y -30
-KPX Q X -24
-KPX Q W -24
-KPX Q V -18
-KPX Q U -30
-KPX Q T -24
-KPX Q A -18
-
-KPX R y -20
-KPX R u -12
-KPX R quoteright -20
-KPX R quotedblright -20
-KPX R o -20
-KPX R hyphen -30
-KPX R e -20
-KPX R d -20
-KPX R a -12
-KPX R Y -45
-KPX R W -24
-KPX R V -32
-KPX R U -30
-KPX R T -32
-KPX R Q -24
-KPX R O -24
-KPX R G -24
-KPX R C -24
-
-KPX S y -25
-KPX S w -30
-KPX S v -30
-KPX S u -24
-KPX S t -24
-KPX S r -20
-KPX S quoteright -10
-KPX S quotedblright -10
-KPX S q -5
-KPX S p -24
-KPX S o -12
-KPX S n -20
-KPX S m -20
-KPX S l -18
-KPX S k -24
-KPX S j -12
-KPX S i -20
-KPX S h -12
-KPX S e -12
-KPX S a -18
-
-KPX T z -64
-KPX T y -84
-KPX T w -100
-KPX T u -82
-KPX T semicolon -56
-KPX T s -82
-KPX T r -82
-KPX T quoteright 24
-KPX T period -110
-KPX T parenright 54
-KPX T o -100
-KPX T m -82
-KPX T i -34
-KPX T hyphen -100
-KPX T endash -50
-KPX T emdash -50
-KPX T e -100
-KPX T comma -110
-KPX T colon -50
-KPX T bracketright 54
-KPX T braceright 54
-KPX T a -100
-KPX T Y 12
-KPX T X 18
-KPX T W 6
-KPX T V 6
-KPX T T 12
-KPX T S -12
-KPX T Q -18
-KPX T O -18
-KPX T G -18
-KPX T C -18
-KPX T A -65
-
-KPX U z -30
-KPX U y -20
-KPX U x -30
-KPX U v -20
-KPX U t -36
-KPX U s -40
-KPX U r -40
-KPX U p -42
-KPX U n -40
-KPX U m -40
-KPX U l -12
-KPX U k -12
-KPX U i -28
-KPX U h -6
-KPX U g -50
-KPX U f -12
-KPX U d -45
-KPX U c -45
-KPX U b -12
-KPX U a -40
-KPX U A -40
-
-KPX V y -36
-KPX V u -40
-KPX V semicolon -45
-KPX V r -70
-KPX V quoteright 36
-KPX V quotedblright 20
-KPX V period -140
-KPX V parenright 85
-KPX V o -70
-KPX V i 6
-KPX V hyphen -60
-KPX V endash -20
-KPX V emdash -20
-KPX V e -70
-KPX V comma -140
-KPX V colon -45
-KPX V bracketright 64
-KPX V braceright 64
-KPX V a -60
-KPX V T 6
-KPX V Q -12
-KPX V O -12
-KPX V G -12
-KPX V C -12
-KPX V A -60
-
-KPX W y -50
-KPX W u -46
-KPX W semicolon -40
-KPX W r -45
-KPX W quoteright 36
-KPX W quotedblright 20
-KPX W period -110
-KPX W parenright 85
-KPX W o -65
-KPX W m -45
-KPX W i -10
-KPX W hyphen -40
-KPX W e -65
-KPX W d -65
-KPX W comma -100
-KPX W colon -40
-KPX W bracketright 64
-KPX W braceright 64
-KPX W a -60
-KPX W T 18
-KPX W Q -6
-KPX W O -6
-KPX W G -6
-KPX W C -6
-KPX W A -48
-
-KPX X y -18
-KPX X u -24
-KPX X quoteright 15
-KPX X e -6
-KPX X a -6
-KPX X Q -24
-KPX X O -30
-KPX X G -30
-KPX X C -30
-KPX X A 6
-
-KPX Y v -50
-KPX Y u -54
-KPX Y t -46
-KPX Y semicolon -37
-KPX Y quoteright 36
-KPX Y quotedblright 20
-KPX Y q -100
-KPX Y period -90
-KPX Y parenright 60
-KPX Y o -90
-KPX Y l 10
-KPX Y hyphen -50
-KPX Y emdash -20
-KPX Y e -90
-KPX Y d -90
-KPX Y comma -90
-KPX Y colon -50
-KPX Y bracketright 64
-KPX Y braceright 64
-KPX Y a -68
-KPX Y Y 12
-KPX Y X 12
-KPX Y W 12
-KPX Y V 12
-KPX Y T 12
-KPX Y Q -18
-KPX Y O -18
-KPX Y G -18
-KPX Y C -18
-KPX Y A -32
-
-KPX Z y -36
-KPX Z w -36
-KPX Z u -6
-KPX Z o -12
-KPX Z i -12
-KPX Z e -6
-KPX Z a -6
-KPX Z Q -20
-KPX Z O -20
-KPX Z G -30
-KPX Z C -20
-KPX Z A 20
-
-KPX a quoteright -70
-KPX a quotedblright -80
-
-KPX b y -25
-KPX b w -30
-KPX b v -35
-KPX b quoteright -70
-KPX b quotedblright -70
-KPX b period -40
-KPX b comma -40
-
-KPX braceleft Y 64
-KPX braceleft W 64
-KPX braceleft V 64
-KPX braceleft T 54
-KPX braceleft J 80
-
-KPX bracketleft Y 64
-KPX bracketleft W 64
-KPX bracketleft V 64
-KPX bracketleft T 54
-KPX bracketleft J 80
-
-KPX c quoteright -28
-KPX c quotedblright -28
-KPX c period -10
-
-KPX comma quoteright -50
-KPX comma quotedblright -50
-
-KPX d quoteright -24
-KPX d quotedblright -24
-
-KPX e z -4
-KPX e quoteright -60
-KPX e quotedblright -60
-KPX e period -20
-KPX e comma -20
-
-KPX f quotesingle 30
-KPX f quoteright 65
-KPX f quotedblright 56
-KPX f quotedbl 30
-KPX f parenright 100
-KPX f bracketright 100
-KPX f braceright 100
-
-KPX g quoteright -18
-KPX g quotedblright -10
-
-KPX h quoteright -80
-KPX h quotedblright -80
-
-KPX j quoteright -20
-KPX j quotedblright -20
-KPX j period -30
-KPX j comma -30
-
-KPX k quoteright -40
-KPX k quotedblright -40
-
-KPX l quoteright -10
-KPX l quotedblright -10
-
-KPX m quoteright -80
-KPX m quotedblright -80
-
-KPX n quoteright -80
-KPX n quotedblright -80
-
-KPX o z -12
-KPX o y -30
-KPX o x -18
-KPX o w -30
-KPX o v -30
-KPX o quoteright -70
-KPX o quotedblright -70
-KPX o period -40
-KPX o comma -40
-
-KPX p z -20
-KPX p y -25
-KPX p w -30
-KPX p quoteright -70
-KPX p quotedblright -70
-KPX p period -40
-KPX p comma -40
-
-KPX parenleft Y 64
-KPX parenleft W 64
-KPX parenleft V 64
-KPX parenleft T 64
-KPX parenleft J 80
-
-KPX period quoteright -50
-KPX period quotedblright -50
-
-KPX q quoteright -50
-KPX q quotedblright -50
-KPX q period -20
-KPX q comma -10
-
-KPX quotedblleft z -60
-KPX quotedblleft y -30
-KPX quotedblleft x -40
-KPX quotedblleft w -20
-KPX quotedblleft v -20
-KPX quotedblleft u -40
-KPX quotedblleft t -40
-KPX quotedblleft s -50
-KPX quotedblleft r -50
-KPX quotedblleft q -80
-KPX quotedblleft p -50
-KPX quotedblleft o -80
-KPX quotedblleft n -50
-KPX quotedblleft m -50
-KPX quotedblleft g -70
-KPX quotedblleft f -50
-KPX quotedblleft e -80
-KPX quotedblleft d -80
-KPX quotedblleft c -80
-KPX quotedblleft a -70
-KPX quotedblleft Z -20
-KPX quotedblleft Y 12
-KPX quotedblleft W 18
-KPX quotedblleft V 18
-KPX quotedblleft U -20
-KPX quotedblleft T 10
-KPX quotedblleft S -20
-KPX quotedblleft R -20
-KPX quotedblleft Q -20
-KPX quotedblleft P -20
-KPX quotedblleft O -30
-KPX quotedblleft N -20
-KPX quotedblleft M -20
-KPX quotedblleft L -20
-KPX quotedblleft K -20
-KPX quotedblleft J -40
-KPX quotedblleft I -20
-KPX quotedblleft H -20
-KPX quotedblleft G -30
-KPX quotedblleft F -20
-KPX quotedblleft E -20
-KPX quotedblleft D -20
-KPX quotedblleft C -30
-KPX quotedblleft B -20
-KPX quotedblleft A -130
-
-KPX quotedblright period -130
-KPX quotedblright comma -130
-
-KPX quoteleft z -40
-KPX quoteleft y -35
-KPX quoteleft x -30
-KPX quoteleft w -20
-KPX quoteleft v -20
-KPX quoteleft u -50
-KPX quoteleft t -40
-KPX quoteleft s -45
-KPX quoteleft r -50
-KPX quoteleft quoteleft -72
-KPX quoteleft q -70
-KPX quoteleft p -50
-KPX quoteleft o -70
-KPX quoteleft n -50
-KPX quoteleft m -50
-KPX quoteleft g -65
-KPX quoteleft f -40
-KPX quoteleft e -70
-KPX quoteleft d -70
-KPX quoteleft c -70
-KPX quoteleft a -60
-KPX quoteleft Z -20
-KPX quoteleft Y 18
-KPX quoteleft X 12
-KPX quoteleft W 18
-KPX quoteleft V 18
-KPX quoteleft U -20
-KPX quoteleft T 10
-KPX quoteleft R -20
-KPX quoteleft Q -20
-KPX quoteleft P -20
-KPX quoteleft O -30
-KPX quoteleft N -20
-KPX quoteleft M -20
-KPX quoteleft L -20
-KPX quoteleft K -20
-KPX quoteleft J -40
-KPX quoteleft I -20
-KPX quoteleft H -20
-KPX quoteleft G -40
-KPX quoteleft F -20
-KPX quoteleft E -20
-KPX quoteleft D -20
-KPX quoteleft C -30
-KPX quoteleft B -20
-KPX quoteleft A -130
-
-KPX quoteright v -40
-KPX quoteright t -75
-KPX quoteright s -110
-KPX quoteright r -70
-KPX quoteright quoteright -72
-KPX quoteright period -130
-KPX quoteright m -70
-KPX quoteright l -6
-KPX quoteright d -120
-KPX quoteright comma -130
-
-KPX r z 10
-KPX r y 18
-KPX r x 12
-KPX r w 18
-KPX r v 18
-KPX r u 8
-KPX r t 8
-KPX r semicolon 10
-KPX r quoteright -20
-KPX r quotedblright -20
-KPX r q -6
-KPX r period -60
-KPX r o -6
-KPX r n 8
-KPX r m 8
-KPX r k -6
-KPX r i 8
-KPX r hyphen -20
-KPX r h 6
-KPX r g -6
-KPX r f 8
-KPX r e -20
-KPX r d -20
-KPX r comma -60
-KPX r colon 10
-KPX r c -20
-KPX r a -10
-
-KPX s quoteright -40
-KPX s quotedblright -40
-KPX s period -20
-KPX s comma -10
-
-KPX space quotesinglbase -60
-KPX space quoteleft -40
-KPX space quotedblleft -40
-KPX space quotedblbase -60
-KPX space Y -60
-KPX space W -60
-KPX space V -60
-KPX space T -36
-
-KPX t quoteright -18
-KPX t quotedblright -18
-
-KPX u quoteright -30
-KPX u quotedblright -30
-
-KPX v semicolon 10
-KPX v quoteright 20
-KPX v quotedblright 20
-KPX v q -10
-KPX v period -90
-KPX v o -5
-KPX v e -5
-KPX v d -10
-KPX v comma -90
-KPX v colon 10
-KPX v c -6
-KPX v a -6
-
-KPX w semicolon 10
-KPX w quoteright 20
-KPX w quotedblright 20
-KPX w q -6
-KPX w period -80
-KPX w e -6
-KPX w d -6
-KPX w comma -75
-KPX w colon 10
-KPX w c -6
-
-KPX x quoteright -10
-KPX x quotedblright -20
-KPX x q -6
-KPX x o -6
-KPX x d -12
-KPX x c -12
-
-KPX y semicolon 10
-KPX y q -6
-KPX y period -95
-KPX y o -6
-KPX y hyphen -30
-KPX y e -6
-KPX y d -6
-KPX y comma -85
-KPX y colon 10
-KPX y c -6
-
-KPX z quoteright -20
-KPX z quotedblright -30
-KPX z o -6
-KPX z e -6
-KPX z d -6
-KPX z c -6
-EndKernPairs
-EndKernData
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/putri8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/putri8a.afm
deleted file mode 100644
index b3dd45b553..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/putri8a.afm
+++ /dev/null
@@ -1,1008 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Fri Jan 17 13:15:45 1992
-Comment UniqueID 37666
-Comment VMusage 34143 41035
-FontName Utopia-Italic
-FullName Utopia Italic
-FamilyName Utopia
-Weight Regular
-ItalicAngle -13
-IsFixedPitch false
-FontBBox -201 -250 1170 890
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.002
-Notice Copyright (c) 1989, 1991 Adobe Systems Incorporated. All Rights Reserved.Utopia is a registered trademark of Adobe Systems Incorporated.
-EncodingScheme AdobeStandardEncoding
-CapHeight 692
-XHeight 502
-Ascender 742
-Descender -242
-StartCharMetrics 228
-C 32 ; WX 225 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 240 ; N exclam ; B 34 -12 290 707 ;
-C 34 ; WX 402 ; N quotedbl ; B 171 469 454 742 ;
-C 35 ; WX 530 ; N numbersign ; B 54 0 585 668 ;
-C 36 ; WX 530 ; N dollar ; B 31 -109 551 743 ;
-C 37 ; WX 826 ; N percent ; B 98 -25 795 702 ;
-C 38 ; WX 725 ; N ampersand ; B 60 -12 703 680 ;
-C 39 ; WX 216 ; N quoteright ; B 112 482 265 742 ;
-C 40 ; WX 350 ; N parenleft ; B 106 -128 458 692 ;
-C 41 ; WX 350 ; N parenright ; B -46 -128 306 692 ;
-C 42 ; WX 412 ; N asterisk ; B 106 356 458 707 ;
-C 43 ; WX 570 ; N plus ; B 58 0 542 490 ;
-C 44 ; WX 265 ; N comma ; B 11 -134 173 142 ;
-C 45 ; WX 392 ; N hyphen ; B 82 216 341 286 ;
-C 46 ; WX 265 ; N period ; B 47 -12 169 113 ;
-C 47 ; WX 270 ; N slash ; B 0 -15 341 707 ;
-C 48 ; WX 530 ; N zero ; B 60 -12 541 680 ;
-C 49 ; WX 530 ; N one ; B 74 0 429 680 ;
-C 50 ; WX 530 ; N two ; B -2 0 538 680 ;
-C 51 ; WX 530 ; N three ; B 19 -12 524 680 ;
-C 52 ; WX 530 ; N four ; B 32 0 509 668 ;
-C 53 ; WX 530 ; N five ; B 24 -12 550 668 ;
-C 54 ; WX 530 ; N six ; B 56 -12 551 680 ;
-C 55 ; WX 530 ; N seven ; B 130 -12 600 668 ;
-C 56 ; WX 530 ; N eight ; B 46 -12 535 680 ;
-C 57 ; WX 530 ; N nine ; B 51 -12 536 680 ;
-C 58 ; WX 265 ; N colon ; B 47 -12 248 490 ;
-C 59 ; WX 265 ; N semicolon ; B 11 -134 248 490 ;
-C 60 ; WX 570 ; N less ; B 51 1 529 497 ;
-C 61 ; WX 570 ; N equal ; B 58 111 542 389 ;
-C 62 ; WX 570 ; N greater ; B 51 1 529 497 ;
-C 63 ; WX 425 ; N question ; B 115 -12 456 707 ;
-C 64 ; WX 794 ; N at ; B 88 -15 797 707 ;
-C 65 ; WX 624 ; N A ; B -58 0 623 692 ;
-C 66 ; WX 632 ; N B ; B 3 0 636 692 ;
-C 67 ; WX 661 ; N C ; B 79 -15 723 707 ;
-C 68 ; WX 763 ; N D ; B 5 0 767 692 ;
-C 69 ; WX 596 ; N E ; B 3 0 657 692 ;
-C 70 ; WX 571 ; N F ; B 3 0 660 692 ;
-C 71 ; WX 709 ; N G ; B 79 -15 737 707 ;
-C 72 ; WX 775 ; N H ; B 5 0 857 692 ;
-C 73 ; WX 345 ; N I ; B 5 0 428 692 ;
-C 74 ; WX 352 ; N J ; B -78 -119 436 692 ;
-C 75 ; WX 650 ; N K ; B 5 -5 786 692 ;
-C 76 ; WX 565 ; N L ; B 5 0 568 692 ;
-C 77 ; WX 920 ; N M ; B -4 0 1002 692 ;
-C 78 ; WX 763 ; N N ; B -4 0 855 692 ;
-C 79 ; WX 753 ; N O ; B 79 -15 754 707 ;
-C 80 ; WX 614 ; N P ; B 5 0 646 692 ;
-C 81 ; WX 753 ; N Q ; B 79 -203 754 707 ;
-C 82 ; WX 640 ; N R ; B 5 0 642 692 ;
-C 83 ; WX 533 ; N S ; B 34 -15 542 707 ;
-C 84 ; WX 606 ; N T ; B 102 0 708 692 ;
-C 85 ; WX 794 ; N U ; B 131 -15 880 692 ;
-C 86 ; WX 637 ; N V ; B 96 0 786 692 ;
-C 87 ; WX 946 ; N W ; B 86 0 1075 692 ;
-C 88 ; WX 632 ; N X ; B -36 0 735 692 ;
-C 89 ; WX 591 ; N Y ; B 96 0 744 692 ;
-C 90 ; WX 622 ; N Z ; B -20 0 703 692 ;
-C 91 ; WX 330 ; N bracketleft ; B 69 -128 414 692 ;
-C 92 ; WX 390 ; N backslash ; B 89 -15 371 707 ;
-C 93 ; WX 330 ; N bracketright ; B -21 -128 324 692 ;
-C 94 ; WX 570 ; N asciicircum ; B 83 228 547 668 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 216 ; N quoteleft ; B 130 488 283 748 ;
-C 97 ; WX 561 ; N a ; B 31 -12 563 502 ;
-C 98 ; WX 559 ; N b ; B 47 -12 557 742 ;
-C 99 ; WX 441 ; N c ; B 46 -12 465 502 ;
-C 100 ; WX 587 ; N d ; B 37 -12 612 742 ;
-C 101 ; WX 453 ; N e ; B 45 -12 471 502 ;
-C 102 ; WX 315 ; N f ; B -107 -242 504 742 ; L i fi ; L l fl ;
-C 103 ; WX 499 ; N g ; B -5 -242 573 512 ;
-C 104 ; WX 607 ; N h ; B 57 -12 588 742 ;
-C 105 ; WX 317 ; N i ; B 79 -12 328 715 ;
-C 106 ; WX 309 ; N j ; B -95 -242 330 715 ;
-C 107 ; WX 545 ; N k ; B 57 -12 567 742 ;
-C 108 ; WX 306 ; N l ; B 76 -12 331 742 ;
-C 109 ; WX 912 ; N m ; B 63 -12 894 502 ;
-C 110 ; WX 618 ; N n ; B 63 -12 600 502 ;
-C 111 ; WX 537 ; N o ; B 49 -12 522 502 ;
-C 112 ; WX 590 ; N p ; B 22 -242 586 502 ;
-C 113 ; WX 559 ; N q ; B 38 -242 567 525 ;
-C 114 ; WX 402 ; N r ; B 69 -12 448 502 ;
-C 115 ; WX 389 ; N s ; B 19 -12 397 502 ;
-C 116 ; WX 341 ; N t ; B 84 -12 404 616 ;
-C 117 ; WX 618 ; N u ; B 89 -12 609 502 ;
-C 118 ; WX 510 ; N v ; B 84 -12 528 502 ;
-C 119 ; WX 785 ; N w ; B 87 -12 808 502 ;
-C 120 ; WX 516 ; N x ; B -4 -12 531 502 ;
-C 121 ; WX 468 ; N y ; B -40 -242 505 502 ;
-C 122 ; WX 468 ; N z ; B 4 -12 483 490 ;
-C 123 ; WX 340 ; N braceleft ; B 100 -128 423 692 ;
-C 124 ; WX 270 ; N bar ; B 130 -250 198 750 ;
-C 125 ; WX 340 ; N braceright ; B -20 -128 302 692 ;
-C 126 ; WX 570 ; N asciitilde ; B 98 176 522 318 ;
-C 161 ; WX 240 ; N exclamdown ; B -18 -217 238 502 ;
-C 162 ; WX 530 ; N cent ; B 94 -21 563 669 ;
-C 163 ; WX 530 ; N sterling ; B 9 0 549 680 ;
-C 164 ; WX 100 ; N fraction ; B -201 -24 369 698 ;
-C 165 ; WX 530 ; N yen ; B 72 0 645 668 ;
-C 166 ; WX 530 ; N florin ; B 4 -135 588 691 ;
-C 167 ; WX 530 ; N section ; B 55 -115 533 707 ;
-C 168 ; WX 530 ; N currency ; B 56 90 536 578 ;
-C 169 ; WX 216 ; N quotesingle ; B 161 469 274 742 ;
-C 170 ; WX 402 ; N quotedblleft ; B 134 488 473 748 ;
-C 171 ; WX 462 ; N guillemotleft ; B 79 41 470 435 ;
-C 172 ; WX 277 ; N guilsinglleft ; B 71 41 267 435 ;
-C 173 ; WX 277 ; N guilsinglright ; B 44 41 240 435 ;
-C 174 ; WX 607 ; N fi ; B -107 -242 589 742 ;
-C 175 ; WX 603 ; N fl ; B -107 -242 628 742 ;
-C 177 ; WX 500 ; N endash ; B 12 221 524 279 ;
-C 178 ; WX 500 ; N dagger ; B 101 -125 519 717 ;
-C 179 ; WX 490 ; N daggerdbl ; B 39 -119 509 717 ;
-C 180 ; WX 265 ; N periodcentered ; B 89 187 211 312 ;
-C 182 ; WX 560 ; N paragraph ; B 109 -101 637 692 ;
-C 183 ; WX 500 ; N bullet ; B 110 192 429 512 ;
-C 184 ; WX 216 ; N quotesinglbase ; B -7 -109 146 151 ;
-C 185 ; WX 402 ; N quotedblbase ; B -7 -109 332 151 ;
-C 186 ; WX 402 ; N quotedblright ; B 107 484 446 744 ;
-C 187 ; WX 462 ; N guillemotright ; B 29 41 420 435 ;
-C 188 ; WX 1000 ; N ellipsis ; B 85 -12 873 113 ;
-C 189 ; WX 1200 ; N perthousand ; B 98 -25 1170 702 ;
-C 191 ; WX 425 ; N questiondown ; B 3 -217 344 502 ;
-C 193 ; WX 400 ; N grave ; B 146 542 368 723 ;
-C 194 ; WX 400 ; N acute ; B 214 542 436 723 ;
-C 195 ; WX 400 ; N circumflex ; B 187 546 484 720 ;
-C 196 ; WX 400 ; N tilde ; B 137 563 492 682 ;
-C 197 ; WX 400 ; N macron ; B 193 597 489 656 ;
-C 198 ; WX 400 ; N breve ; B 227 568 501 698 ;
-C 199 ; WX 402 ; N dotaccent ; B 252 570 359 680 ;
-C 200 ; WX 400 ; N dieresis ; B 172 572 487 682 ;
-C 202 ; WX 400 ; N ring ; B 186 550 402 752 ;
-C 203 ; WX 400 ; N cedilla ; B 62 -230 241 0 ;
-C 205 ; WX 400 ; N hungarumlaut ; B 176 546 455 750 ;
-C 206 ; WX 350 ; N ogonek ; B 68 -219 248 0 ;
-C 207 ; WX 400 ; N caron ; B 213 557 510 731 ;
-C 208 ; WX 1000 ; N emdash ; B 12 221 1024 279 ;
-C 225 ; WX 880 ; N AE ; B -88 0 941 692 ;
-C 227 ; WX 425 ; N ordfeminine ; B 77 265 460 590 ;
-C 232 ; WX 571 ; N Lslash ; B 11 0 574 692 ;
-C 233 ; WX 753 ; N Oslash ; B 79 -45 754 736 ;
-C 234 ; WX 1020 ; N OE ; B 79 0 1081 692 ;
-C 235 ; WX 389 ; N ordmasculine ; B 86 265 420 590 ;
-C 241 ; WX 779 ; N ae ; B 34 -12 797 514 ;
-C 245 ; WX 317 ; N dotlessi ; B 79 -12 299 502 ;
-C 248 ; WX 318 ; N lslash ; B 45 -12 376 742 ;
-C 249 ; WX 537 ; N oslash ; B 49 -39 522 529 ;
-C 250 ; WX 806 ; N oe ; B 49 -12 824 502 ;
-C 251 ; WX 577 ; N germandbls ; B -107 -242 630 742 ;
-C -1 ; WX 370 ; N onesuperior ; B 90 272 326 680 ;
-C -1 ; WX 570 ; N minus ; B 58 221 542 279 ;
-C -1 ; WX 400 ; N degree ; B 152 404 428 680 ;
-C -1 ; WX 537 ; N oacute ; B 49 -12 530 723 ;
-C -1 ; WX 753 ; N Odieresis ; B 79 -15 754 848 ;
-C -1 ; WX 537 ; N odieresis ; B 49 -12 532 682 ;
-C -1 ; WX 596 ; N Eacute ; B 3 0 657 890 ;
-C -1 ; WX 618 ; N ucircumflex ; B 89 -12 609 720 ;
-C -1 ; WX 890 ; N onequarter ; B 97 -24 805 698 ;
-C -1 ; WX 570 ; N logicalnot ; B 58 102 542 389 ;
-C -1 ; WX 596 ; N Ecircumflex ; B 3 0 657 876 ;
-C -1 ; WX 890 ; N onehalf ; B 71 -24 812 698 ;
-C -1 ; WX 753 ; N Otilde ; B 79 -15 754 842 ;
-C -1 ; WX 618 ; N uacute ; B 89 -12 609 723 ;
-C -1 ; WX 453 ; N eacute ; B 45 -12 508 723 ;
-C -1 ; WX 317 ; N iacute ; B 79 -12 398 723 ;
-C -1 ; WX 596 ; N Egrave ; B 3 0 657 890 ;
-C -1 ; WX 317 ; N icircumflex ; B 79 -12 383 720 ;
-C -1 ; WX 618 ; N mu ; B 11 -232 609 502 ;
-C -1 ; WX 270 ; N brokenbar ; B 130 -175 198 675 ;
-C -1 ; WX 584 ; N thorn ; B 16 -242 580 700 ;
-C -1 ; WX 624 ; N Aring ; B -58 0 623 861 ;
-C -1 ; WX 468 ; N yacute ; B -40 -242 505 723 ;
-C -1 ; WX 591 ; N Ydieresis ; B 96 0 744 848 ;
-C -1 ; WX 1100 ; N trademark ; B 91 277 1094 692 ;
-C -1 ; WX 836 ; N registered ; B 91 -15 819 707 ;
-C -1 ; WX 537 ; N ocircumflex ; B 49 -12 522 720 ;
-C -1 ; WX 624 ; N Agrave ; B -58 0 623 890 ;
-C -1 ; WX 533 ; N Scaron ; B 34 -15 561 888 ;
-C -1 ; WX 794 ; N Ugrave ; B 131 -15 880 890 ;
-C -1 ; WX 596 ; N Edieresis ; B 3 0 657 848 ;
-C -1 ; WX 794 ; N Uacute ; B 131 -15 880 890 ;
-C -1 ; WX 537 ; N otilde ; B 49 -12 525 682 ;
-C -1 ; WX 618 ; N ntilde ; B 63 -12 600 682 ;
-C -1 ; WX 468 ; N ydieresis ; B -40 -242 513 682 ;
-C -1 ; WX 624 ; N Aacute ; B -58 0 642 890 ;
-C -1 ; WX 537 ; N eth ; B 47 -12 521 742 ;
-C -1 ; WX 561 ; N acircumflex ; B 31 -12 563 720 ;
-C -1 ; WX 561 ; N aring ; B 31 -12 563 752 ;
-C -1 ; WX 753 ; N Ograve ; B 79 -15 754 890 ;
-C -1 ; WX 441 ; N ccedilla ; B 46 -230 465 502 ;
-C -1 ; WX 570 ; N multiply ; B 88 22 532 478 ;
-C -1 ; WX 570 ; N divide ; B 58 25 542 475 ;
-C -1 ; WX 370 ; N twosuperior ; B 35 272 399 680 ;
-C -1 ; WX 763 ; N Ntilde ; B -4 0 855 842 ;
-C -1 ; WX 618 ; N ugrave ; B 89 -12 609 723 ;
-C -1 ; WX 794 ; N Ucircumflex ; B 131 -15 880 876 ;
-C -1 ; WX 624 ; N Atilde ; B -58 0 623 842 ;
-C -1 ; WX 468 ; N zcaron ; B 4 -12 484 731 ;
-C -1 ; WX 317 ; N idieresis ; B 79 -12 398 682 ;
-C -1 ; WX 624 ; N Acircumflex ; B -58 0 623 876 ;
-C -1 ; WX 345 ; N Icircumflex ; B 5 0 453 876 ;
-C -1 ; WX 591 ; N Yacute ; B 96 0 744 890 ;
-C -1 ; WX 753 ; N Oacute ; B 79 -15 754 890 ;
-C -1 ; WX 624 ; N Adieresis ; B -58 0 623 848 ;
-C -1 ; WX 622 ; N Zcaron ; B -20 0 703 888 ;
-C -1 ; WX 561 ; N agrave ; B 31 -12 563 723 ;
-C -1 ; WX 370 ; N threesuperior ; B 59 265 389 680 ;
-C -1 ; WX 537 ; N ograve ; B 49 -12 522 723 ;
-C -1 ; WX 890 ; N threequarters ; B 105 -24 816 698 ;
-C -1 ; WX 770 ; N Eth ; B 12 0 774 692 ;
-C -1 ; WX 570 ; N plusminus ; B 58 0 542 556 ;
-C -1 ; WX 618 ; N udieresis ; B 89 -12 609 682 ;
-C -1 ; WX 453 ; N edieresis ; B 45 -12 490 682 ;
-C -1 ; WX 561 ; N aacute ; B 31 -12 571 723 ;
-C -1 ; WX 317 ; N igrave ; B 55 -12 299 723 ;
-C -1 ; WX 345 ; N Idieresis ; B 5 0 461 848 ;
-C -1 ; WX 561 ; N adieresis ; B 31 -12 563 682 ;
-C -1 ; WX 345 ; N Iacute ; B 5 0 506 890 ;
-C -1 ; WX 836 ; N copyright ; B 91 -15 819 707 ;
-C -1 ; WX 345 ; N Igrave ; B 5 0 428 890 ;
-C -1 ; WX 661 ; N Ccedilla ; B 79 -230 723 707 ;
-C -1 ; WX 389 ; N scaron ; B 19 -12 457 731 ;
-C -1 ; WX 453 ; N egrave ; B 45 -12 471 723 ;
-C -1 ; WX 753 ; N Ocircumflex ; B 79 -15 754 876 ;
-C -1 ; WX 604 ; N Thorn ; B 5 0 616 692 ;
-C -1 ; WX 561 ; N atilde ; B 31 -12 563 682 ;
-C -1 ; WX 794 ; N Udieresis ; B 131 -15 880 848 ;
-C -1 ; WX 453 ; N ecircumflex ; B 45 -12 475 720 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 690
-
-KPX A y -20
-KPX A x 10
-KPX A w -30
-KPX A v -30
-KPX A u -10
-KPX A t -6
-KPX A s 15
-KPX A r -12
-KPX A quoteright -110
-KPX A quotedblright -110
-KPX A q 10
-KPX A p -12
-KPX A o -10
-KPX A n -18
-KPX A m -18
-KPX A l -18
-KPX A j 6
-KPX A h -6
-KPX A d 10
-KPX A c -6
-KPX A b -6
-KPX A a 12
-KPX A Y -76
-KPX A X -8
-KPX A W -80
-KPX A V -90
-KPX A U -60
-KPX A T -72
-KPX A Q -30
-KPX A O -30
-KPX A G -30
-KPX A C -30
-
-KPX B y -6
-KPX B u -20
-KPX B r -15
-KPX B quoteright -40
-KPX B quotedblright -30
-KPX B o 6
-KPX B l -20
-KPX B k -15
-KPX B i -12
-KPX B h -15
-KPX B e 6
-KPX B a 12
-KPX B W -20
-KPX B V -50
-KPX B U -50
-KPX B T -20
-
-KPX C z -6
-KPX C y -18
-KPX C u -18
-KPX C quotedblright 20
-KPX C i -5
-KPX C e -6
-KPX C a -6
-
-KPX D y 18
-KPX D u -10
-KPX D quoteright -40
-KPX D quotedblright -50
-KPX D period -30
-KPX D o 6
-KPX D i 6
-KPX D h -25
-KPX D e 6
-KPX D comma -20
-KPX D a 6
-KPX D Y -70
-KPX D W -50
-KPX D V -60
-
-KPX E z -6
-KPX E y -18
-KPX E x 5
-KPX E w -20
-KPX E v -18
-KPX E u -24
-KPX E t -18
-KPX E s 5
-KPX E r -6
-KPX E quoteright 10
-KPX E quotedblright 10
-KPX E q 10
-KPX E period 10
-KPX E p -12
-KPX E o -6
-KPX E n -12
-KPX E m -12
-KPX E l -12
-KPX E k -10
-KPX E j -6
-KPX E i -12
-KPX E g -12
-KPX E e 5
-KPX E d 10
-KPX E comma 10
-KPX E b -6
-
-KPX F y -12
-KPX F u -30
-KPX F r -18
-KPX F quoteright 15
-KPX F quotedblright 35
-KPX F period -180
-KPX F o -30
-KPX F l -6
-KPX F i -12
-KPX F e -30
-KPX F comma -170
-KPX F a -30
-KPX F A -45
-
-KPX G y -16
-KPX G u -22
-KPX G r -22
-KPX G quoteright -20
-KPX G quotedblright -20
-KPX G o 10
-KPX G n -22
-KPX G l -24
-KPX G i -12
-KPX G h -18
-KPX G e 10
-KPX G a 5
-
-KPX H y -18
-KPX H u -30
-KPX H quoteright 10
-KPX H quotedblright 10
-KPX H o -12
-KPX H i -12
-KPX H e -12
-KPX H a -12
-
-KPX I z -20
-KPX I y -6
-KPX I x -6
-KPX I w -30
-KPX I v -30
-KPX I u -30
-KPX I t -18
-KPX I s -18
-KPX I r -12
-KPX I quoteright 10
-KPX I quotedblright 10
-KPX I p -18
-KPX I o -12
-KPX I n -18
-KPX I m -18
-KPX I l -6
-KPX I k -6
-KPX I g -12
-KPX I f -6
-KPX I d -6
-KPX I c -12
-KPX I b -6
-KPX I a -6
-
-KPX J y -12
-KPX J u -36
-KPX J quoteright 6
-KPX J quotedblright 15
-KPX J o -36
-KPX J i -30
-KPX J e -36
-KPX J braceright 10
-KPX J a -36
-
-KPX K y -40
-KPX K w -30
-KPX K v -20
-KPX K u -24
-KPX K r -12
-KPX K quoteright 25
-KPX K quotedblright 40
-KPX K o -24
-KPX K n -18
-KPX K i -6
-KPX K h 6
-KPX K e -12
-KPX K a -6
-KPX K Q -24
-KPX K O -24
-KPX K G -24
-KPX K C -24
-
-KPX L y -55
-KPX L w -30
-KPX L u -18
-KPX L quoteright -110
-KPX L quotedblright -110
-KPX L l -16
-KPX L j -18
-KPX L i -18
-KPX L a 10
-KPX L Y -80
-KPX L W -90
-KPX L V -110
-KPX L U -42
-KPX L T -80
-KPX L Q -48
-KPX L O -48
-KPX L G -48
-KPX L C -48
-KPX L A 30
-
-KPX M y -18
-KPX M u -24
-KPX M quoteright 6
-KPX M quotedblright 15
-KPX M o -25
-KPX M n -12
-KPX M j -18
-KPX M i -12
-KPX M e -20
-KPX M d -10
-KPX M c -20
-KPX M a -6
-
-KPX N y -18
-KPX N u -24
-KPX N quoteright 10
-KPX N quotedblright 10
-KPX N o -25
-KPX N i -12
-KPX N e -20
-KPX N a -22
-
-KPX O z -6
-KPX O y 12
-KPX O w -10
-KPX O v -10
-KPX O u -6
-KPX O t -6
-KPX O s -6
-KPX O r -6
-KPX O quoteright -40
-KPX O quotedblright -40
-KPX O q 5
-KPX O period -20
-KPX O p -6
-KPX O n -6
-KPX O m -6
-KPX O l -20
-KPX O k -10
-KPX O j -6
-KPX O h -10
-KPX O g -6
-KPX O e 5
-KPX O d 6
-KPX O comma -10
-KPX O c 5
-KPX O b -6
-KPX O a 5
-KPX O Y -75
-KPX O X -30
-KPX O W -40
-KPX O V -60
-KPX O T -48
-KPX O A -18
-
-KPX P y 6
-KPX P u -18
-KPX P t -6
-KPX P s -24
-KPX P r -6
-KPX P period -220
-KPX P o -24
-KPX P n -12
-KPX P l -25
-KPX P h -15
-KPX P e -24
-KPX P comma -220
-KPX P a -24
-KPX P I -30
-KPX P H -30
-KPX P E -30
-KPX P A -75
-
-KPX Q u -6
-KPX Q quoteright -40
-KPX Q quotedblright -50
-KPX Q a -6
-KPX Q Y -70
-KPX Q X -12
-KPX Q W -35
-KPX Q V -60
-KPX Q U -35
-KPX Q T -36
-KPX Q A -18
-
-KPX R y -14
-KPX R u -12
-KPX R quoteright -30
-KPX R quotedblright -20
-KPX R o -12
-KPX R hyphen -20
-KPX R e -12
-KPX R Y -50
-KPX R W -30
-KPX R V -40
-KPX R U -40
-KPX R T -30
-KPX R Q -10
-KPX R O -10
-KPX R G -10
-KPX R C -10
-KPX R A -6
-
-KPX S y -30
-KPX S w -30
-KPX S v -30
-KPX S u -18
-KPX S t -30
-KPX S r -20
-KPX S quoteright -38
-KPX S quotedblright -30
-KPX S p -18
-KPX S n -24
-KPX S m -24
-KPX S l -30
-KPX S k -24
-KPX S j -25
-KPX S i -30
-KPX S h -30
-KPX S e -6
-
-KPX T z -70
-KPX T y -60
-KPX T w -64
-KPX T u -74
-KPX T semicolon -36
-KPX T s -72
-KPX T r -64
-KPX T quoteright 45
-KPX T quotedblright 50
-KPX T period -100
-KPX T parenright 54
-KPX T o -90
-KPX T m -64
-KPX T i -34
-KPX T hyphen -100
-KPX T endash -60
-KPX T emdash -60
-KPX T e -90
-KPX T comma -110
-KPX T colon -10
-KPX T bracketright 45
-KPX T braceright 54
-KPX T a -90
-KPX T Y 12
-KPX T X 18
-KPX T W 6
-KPX T T 18
-KPX T Q -12
-KPX T O -12
-KPX T G -12
-KPX T C -12
-KPX T A -56
-
-KPX U z -30
-KPX U x -40
-KPX U t -24
-KPX U s -30
-KPX U r -30
-KPX U quoteright 10
-KPX U quotedblright 10
-KPX U p -40
-KPX U n -45
-KPX U m -45
-KPX U l -12
-KPX U k -12
-KPX U i -24
-KPX U h -6
-KPX U g -30
-KPX U d -40
-KPX U c -35
-KPX U b -6
-KPX U a -40
-KPX U A -45
-
-KPX V y -46
-KPX V u -42
-KPX V semicolon -35
-KPX V r -50
-KPX V quoteright 75
-KPX V quotedblright 70
-KPX V period -130
-KPX V parenright 64
-KPX V o -62
-KPX V i -10
-KPX V hyphen -60
-KPX V endash -20
-KPX V emdash -20
-KPX V e -52
-KPX V comma -120
-KPX V colon -18
-KPX V bracketright 64
-KPX V braceright 64
-KPX V a -60
-KPX V T 6
-KPX V A -70
-
-KPX W y -42
-KPX W u -56
-KPX W t -20
-KPX W semicolon -28
-KPX W r -40
-KPX W quoteright 55
-KPX W quotedblright 60
-KPX W period -108
-KPX W parenright 64
-KPX W o -60
-KPX W m -35
-KPX W i -10
-KPX W hyphen -40
-KPX W endash -2
-KPX W emdash -10
-KPX W e -54
-KPX W d -50
-KPX W comma -108
-KPX W colon -28
-KPX W bracketright 55
-KPX W braceright 64
-KPX W a -60
-KPX W T 12
-KPX W Q -10
-KPX W O -10
-KPX W G -10
-KPX W C -10
-KPX W A -58
-
-KPX X y -35
-KPX X u -30
-KPX X r -6
-KPX X quoteright 35
-KPX X quotedblright 15
-KPX X i -6
-KPX X e -10
-KPX X a 5
-KPX X Y -6
-KPX X W -6
-KPX X Q -30
-KPX X O -30
-KPX X G -30
-KPX X C -30
-KPX X A -18
-
-KPX Y v -50
-KPX Y u -58
-KPX Y t -32
-KPX Y semicolon -36
-KPX Y quoteright 65
-KPX Y quotedblright 70
-KPX Y q -100
-KPX Y period -90
-KPX Y parenright 60
-KPX Y o -72
-KPX Y l 10
-KPX Y hyphen -95
-KPX Y endash -20
-KPX Y emdash -20
-KPX Y e -72
-KPX Y d -80
-KPX Y comma -80
-KPX Y colon -36
-KPX Y bracketright 64
-KPX Y braceright 75
-KPX Y a -82
-KPX Y Y 12
-KPX Y X 12
-KPX Y W 12
-KPX Y V 6
-KPX Y T 25
-KPX Y Q -5
-KPX Y O -5
-KPX Y G -5
-KPX Y C -5
-KPX Y A -36
-
-KPX Z y -36
-KPX Z w -36
-KPX Z u -12
-KPX Z quoteright 10
-KPX Z quotedblright 10
-KPX Z o -6
-KPX Z i -12
-KPX Z e -6
-KPX Z a -6
-KPX Z Q -30
-KPX Z O -30
-KPX Z G -30
-KPX Z C -30
-KPX Z A 12
-
-KPX a quoteright -40
-KPX a quotedblright -40
-
-KPX b y -6
-KPX b w -15
-KPX b v -15
-KPX b quoteright -50
-KPX b quotedblright -50
-KPX b period -40
-KPX b comma -30
-
-KPX braceleft Y 64
-KPX braceleft W 64
-KPX braceleft V 64
-KPX braceleft T 54
-KPX braceleft J 80
-
-KPX bracketleft Y 64
-KPX bracketleft W 64
-KPX bracketleft V 64
-KPX bracketleft T 54
-KPX bracketleft J 80
-
-KPX c quoteright -20
-KPX c quotedblright -20
-
-KPX colon space -30
-
-KPX comma space -40
-KPX comma quoteright -80
-KPX comma quotedblright -80
-
-KPX d quoteright -12
-KPX d quotedblright -12
-
-KPX e x -10
-KPX e w -10
-KPX e quoteright -30
-KPX e quotedblright -30
-
-KPX f quoteright 110
-KPX f quotedblright 110
-KPX f period -20
-KPX f parenright 100
-KPX f comma -20
-KPX f bracketright 90
-KPX f braceright 90
-
-KPX g y 30
-KPX g p 12
-KPX g f 42
-
-KPX h quoteright -80
-KPX h quotedblright -80
-
-KPX j quoteright -20
-KPX j quotedblright -20
-KPX j period -35
-KPX j comma -20
-
-KPX k quoteright -30
-KPX k quotedblright -50
-
-KPX m quoteright -80
-KPX m quotedblright -80
-
-KPX n quoteright -80
-KPX n quotedblright -80
-
-KPX o z -10
-KPX o y -20
-KPX o x -20
-KPX o w -30
-KPX o v -35
-KPX o quoteright -60
-KPX o quotedblright -50
-KPX o period -30
-KPX o comma -20
-
-KPX p z -10
-KPX p w -15
-KPX p quoteright -50
-KPX p quotedblright -70
-KPX p period -30
-KPX p comma -20
-
-KPX parenleft Y 75
-KPX parenleft W 75
-KPX parenleft V 75
-KPX parenleft T 64
-KPX parenleft J 80
-
-KPX period space -40
-KPX period quoteright -80
-KPX period quotedblright -80
-
-KPX q quoteright -20
-KPX q quotedblright -30
-KPX q period -20
-KPX q comma -10
-
-KPX quotedblleft z -30
-KPX quotedblleft x -40
-KPX quotedblleft w -12
-KPX quotedblleft v -12
-KPX quotedblleft u -12
-KPX quotedblleft t -12
-KPX quotedblleft s -30
-KPX quotedblleft r -12
-KPX quotedblleft q -40
-KPX quotedblleft p -12
-KPX quotedblleft o -30
-KPX quotedblleft n -12
-KPX quotedblleft m -12
-KPX quotedblleft l 10
-KPX quotedblleft k 10
-KPX quotedblleft h 10
-KPX quotedblleft g -30
-KPX quotedblleft e -40
-KPX quotedblleft d -40
-KPX quotedblleft c -40
-KPX quotedblleft b 24
-KPX quotedblleft a -60
-KPX quotedblleft Y 12
-KPX quotedblleft X 28
-KPX quotedblleft W 28
-KPX quotedblleft V 28
-KPX quotedblleft T 36
-KPX quotedblleft A -90
-
-KPX quotedblright space -40
-KPX quotedblright period -100
-KPX quotedblright comma -100
-
-KPX quoteleft z -30
-KPX quoteleft y -10
-KPX quoteleft x -40
-KPX quoteleft w -12
-KPX quoteleft v -12
-KPX quoteleft u -12
-KPX quoteleft t -12
-KPX quoteleft s -30
-KPX quoteleft r -12
-KPX quoteleft quoteleft -18
-KPX quoteleft q -30
-KPX quoteleft p -12
-KPX quoteleft o -30
-KPX quoteleft n -12
-KPX quoteleft m -12
-KPX quoteleft l 10
-KPX quoteleft k 10
-KPX quoteleft h 10
-KPX quoteleft g -30
-KPX quoteleft e -30
-KPX quoteleft d -30
-KPX quoteleft c -30
-KPX quoteleft b 24
-KPX quoteleft a -45
-KPX quoteleft Y 12
-KPX quoteleft X 28
-KPX quoteleft W 28
-KPX quoteleft V 28
-KPX quoteleft T 36
-KPX quoteleft A -90
-
-KPX quoteright v -35
-KPX quoteright t -35
-KPX quoteright space -40
-KPX quoteright s -55
-KPX quoteright r -25
-KPX quoteright quoteright -18
-KPX quoteright period -100
-KPX quoteright m -25
-KPX quoteright l -12
-KPX quoteright d -70
-KPX quoteright comma -100
-
-KPX r y 18
-KPX r w 6
-KPX r v 6
-KPX r t 8
-KPX r quotedblright -15
-KPX r q -24
-KPX r period -120
-KPX r o -6
-KPX r l -20
-KPX r k -20
-KPX r hyphen -30
-KPX r h -20
-KPX r f 8
-KPX r emdash -20
-KPX r e -26
-KPX r d -26
-KPX r comma -110
-KPX r c -12
-KPX r a -20
-
-KPX s quoteright -40
-KPX s quotedblright -45
-
-KPX semicolon space -30
-
-KPX space quotesinglbase -30
-KPX space quoteleft -40
-KPX space quotedblleft -40
-KPX space quotedblbase -30
-KPX space Y -70
-KPX space W -70
-KPX space V -70
-
-KPX t quoteright 10
-KPX t quotedblright -10
-
-KPX u quoteright -55
-KPX u quotedblright -50
-
-KPX v quoteright -20
-KPX v quotedblright -30
-KPX v q -6
-KPX v period -70
-KPX v o -6
-KPX v e -6
-KPX v d -6
-KPX v comma -70
-KPX v c -6
-KPX v a -6
-
-KPX w quoteright -20
-KPX w quotedblright -30
-KPX w period -62
-KPX w comma -62
-
-KPX x y 12
-KPX x w -6
-KPX x quoteright -40
-KPX x quotedblright -50
-KPX x q -6
-KPX x o -6
-KPX x e -6
-KPX x d -6
-KPX x c -6
-
-KPX y quoteright -10
-KPX y quotedblright -20
-KPX y period -70
-KPX y emdash 40
-KPX y comma -60
-
-KPX z quoteright -40
-KPX z quotedblright -50
-KPX z o -6
-KPX z e -6
-KPX z d -6
-KPX z c -6
-EndKernPairs
-EndKernData
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pzcmi8a.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pzcmi8a.afm
deleted file mode 100644
index 6efb57ab58..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pzcmi8a.afm
+++ /dev/null
@@ -1,480 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Fri Dec 28 16:35:46 1990
-Comment UniqueID 33936
-Comment VMusage 34559 41451
-FontName ZapfChancery-MediumItalic
-FullName ITC Zapf Chancery Medium Italic
-FamilyName ITC Zapf Chancery
-Weight Medium
-ItalicAngle -14
-IsFixedPitch false
-FontBBox -181 -314 1065 831
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.007
-Notice Copyright (c) 1985, 1987, 1989, 1990 Adobe Systems Incorporated. All Rights Reserved.ITC Zapf Chancery is a registered trademark of International Typeface Corporation.
-EncodingScheme AdobeStandardEncoding
-CapHeight 708
-XHeight 438
-Ascender 714
-Descender -314
-StartCharMetrics 228
-C 32 ; WX 220 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 280 ; N exclam ; B 119 -14 353 610 ;
-C 34 ; WX 220 ; N quotedbl ; B 120 343 333 610 ;
-C 35 ; WX 440 ; N numbersign ; B 83 0 521 594 ;
-C 36 ; WX 440 ; N dollar ; B 60 -144 508 709 ;
-C 37 ; WX 680 ; N percent ; B 132 -160 710 700 ;
-C 38 ; WX 780 ; N ampersand ; B 126 -16 915 610 ;
-C 39 ; WX 240 ; N quoteright ; B 168 343 338 610 ;
-C 40 ; WX 260 ; N parenleft ; B 96 -216 411 664 ;
-C 41 ; WX 220 ; N parenright ; B -13 -216 302 664 ;
-C 42 ; WX 420 ; N asterisk ; B 139 263 479 610 ;
-C 43 ; WX 520 ; N plus ; B 117 0 543 426 ;
-C 44 ; WX 220 ; N comma ; B 25 -140 213 148 ;
-C 45 ; WX 280 ; N hyphen ; B 69 190 334 248 ;
-C 46 ; WX 220 ; N period ; B 102 -14 228 128 ;
-C 47 ; WX 340 ; N slash ; B 74 -16 458 610 ;
-C 48 ; WX 440 ; N zero ; B 79 -16 538 610 ;
-C 49 ; WX 440 ; N one ; B 41 0 428 610 ;
-C 50 ; WX 440 ; N two ; B 17 -16 485 610 ;
-C 51 ; WX 440 ; N three ; B 1 -16 485 610 ;
-C 52 ; WX 440 ; N four ; B 77 -35 499 610 ;
-C 53 ; WX 440 ; N five ; B 60 -16 595 679 ;
-C 54 ; WX 440 ; N six ; B 90 -16 556 610 ;
-C 55 ; WX 440 ; N seven ; B 157 -33 561 645 ;
-C 56 ; WX 440 ; N eight ; B 65 -16 529 610 ;
-C 57 ; WX 440 ; N nine ; B 32 -16 517 610 ;
-C 58 ; WX 260 ; N colon ; B 98 -14 296 438 ;
-C 59 ; WX 240 ; N semicolon ; B 29 -140 299 438 ;
-C 60 ; WX 520 ; N less ; B 139 0 527 468 ;
-C 61 ; WX 520 ; N equal ; B 117 86 543 340 ;
-C 62 ; WX 520 ; N greater ; B 139 0 527 468 ;
-C 63 ; WX 380 ; N question ; B 150 -14 455 610 ;
-C 64 ; WX 700 ; N at ; B 127 -16 753 610 ;
-C 65 ; WX 620 ; N A ; B 13 -16 697 632 ;
-C 66 ; WX 600 ; N B ; B 85 -6 674 640 ;
-C 67 ; WX 520 ; N C ; B 93 -16 631 610 ;
-C 68 ; WX 700 ; N D ; B 86 -6 768 640 ;
-C 69 ; WX 620 ; N E ; B 91 -12 709 618 ;
-C 70 ; WX 580 ; N F ; B 120 -118 793 629 ;
-C 71 ; WX 620 ; N G ; B 148 -242 709 610 ;
-C 72 ; WX 680 ; N H ; B 18 -16 878 708 ;
-C 73 ; WX 380 ; N I ; B 99 0 504 594 ;
-C 74 ; WX 400 ; N J ; B -14 -147 538 594 ;
-C 75 ; WX 660 ; N K ; B 53 -153 844 610 ;
-C 76 ; WX 580 ; N L ; B 53 -16 657 610 ;
-C 77 ; WX 840 ; N M ; B 58 -16 1020 722 ;
-C 78 ; WX 700 ; N N ; B 85 -168 915 708 ;
-C 79 ; WX 600 ; N O ; B 94 -16 660 610 ;
-C 80 ; WX 540 ; N P ; B 42 0 658 628 ;
-C 81 ; WX 600 ; N Q ; B 84 -177 775 610 ;
-C 82 ; WX 600 ; N R ; B 58 -168 805 640 ;
-C 83 ; WX 460 ; N S ; B 45 -81 558 610 ;
-C 84 ; WX 500 ; N T ; B 63 0 744 667 ;
-C 85 ; WX 740 ; N U ; B 126 -16 792 617 ;
-C 86 ; WX 640 ; N V ; B 124 -16 810 714 ;
-C 87 ; WX 880 ; N W ; B 94 -16 1046 723 ;
-C 88 ; WX 560 ; N X ; B -30 -16 699 610 ;
-C 89 ; WX 560 ; N Y ; B 41 -168 774 647 ;
-C 90 ; WX 620 ; N Z ; B 42 -19 669 624 ;
-C 91 ; WX 240 ; N bracketleft ; B -13 -207 405 655 ;
-C 92 ; WX 480 ; N backslash ; B 140 -16 524 610 ;
-C 93 ; WX 320 ; N bracketright ; B -27 -207 391 655 ;
-C 94 ; WX 520 ; N asciicircum ; B 132 239 532 594 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 240 ; N quoteleft ; B 169 343 339 610 ;
-C 97 ; WX 420 ; N a ; B 92 -15 485 438 ;
-C 98 ; WX 420 ; N b ; B 82 -23 492 714 ;
-C 99 ; WX 340 ; N c ; B 87 -14 406 438 ;
-C 100 ; WX 440 ; N d ; B 102 -14 651 714 ;
-C 101 ; WX 340 ; N e ; B 87 -14 403 438 ;
-C 102 ; WX 320 ; N f ; B -119 -314 547 714 ; L i fi ; L l fl ;
-C 103 ; WX 400 ; N g ; B -108 -314 503 438 ;
-C 104 ; WX 440 ; N h ; B 55 -14 524 714 ;
-C 105 ; WX 240 ; N i ; B 100 -14 341 635 ;
-C 106 ; WX 220 ; N j ; B -112 -314 332 635 ;
-C 107 ; WX 440 ; N k ; B 87 -184 628 714 ;
-C 108 ; WX 240 ; N l ; B 102 -14 480 714 ;
-C 109 ; WX 620 ; N m ; B 86 -14 704 438 ;
-C 110 ; WX 460 ; N n ; B 101 -14 544 438 ;
-C 111 ; WX 400 ; N o ; B 87 -14 449 438 ;
-C 112 ; WX 440 ; N p ; B -23 -314 484 432 ;
-C 113 ; WX 400 ; N q ; B 87 -300 490 510 ;
-C 114 ; WX 300 ; N r ; B 101 -14 424 438 ;
-C 115 ; WX 320 ; N s ; B 46 -14 403 438 ;
-C 116 ; WX 320 ; N t ; B 106 -14 426 539 ;
-C 117 ; WX 460 ; N u ; B 102 -14 528 438 ;
-C 118 ; WX 440 ; N v ; B 87 -14 533 488 ;
-C 119 ; WX 680 ; N w ; B 87 -14 782 488 ;
-C 120 ; WX 420 ; N x ; B 70 -195 589 438 ;
-C 121 ; WX 400 ; N y ; B -24 -314 483 438 ;
-C 122 ; WX 440 ; N z ; B 26 -14 508 445 ;
-C 123 ; WX 240 ; N braceleft ; B 55 -207 383 655 ;
-C 124 ; WX 520 ; N bar ; B 320 -16 378 714 ;
-C 125 ; WX 240 ; N braceright ; B -10 -207 318 655 ;
-C 126 ; WX 520 ; N asciitilde ; B 123 186 539 320 ;
-C 161 ; WX 280 ; N exclamdown ; B 72 -186 306 438 ;
-C 162 ; WX 440 ; N cent ; B 122 -134 476 543 ;
-C 163 ; WX 440 ; N sterling ; B -16 -52 506 610 ;
-C 164 ; WX 60 ; N fraction ; B -181 -16 320 610 ;
-C 165 ; WX 440 ; N yen ; B -1 -168 613 647 ;
-C 166 ; WX 440 ; N florin ; B -64 -314 582 610 ;
-C 167 ; WX 420 ; N section ; B 53 -215 514 610 ;
-C 168 ; WX 440 ; N currency ; B 50 85 474 509 ;
-C 169 ; WX 160 ; N quotesingle ; B 145 343 215 610 ;
-C 170 ; WX 340 ; N quotedblleft ; B 169 343 464 610 ;
-C 171 ; WX 340 ; N guillemotleft ; B 98 24 356 414 ;
-C 172 ; WX 240 ; N guilsinglleft ; B 98 24 258 414 ;
-C 173 ; WX 260 ; N guilsinglright ; B 106 24 266 414 ;
-C 174 ; WX 520 ; N fi ; B -124 -314 605 714 ;
-C 175 ; WX 520 ; N fl ; B -124 -314 670 714 ;
-C 177 ; WX 500 ; N endash ; B 51 199 565 239 ;
-C 178 ; WX 460 ; N dagger ; B 138 -37 568 610 ;
-C 179 ; WX 480 ; N daggerdbl ; B 138 -59 533 610 ;
-C 180 ; WX 220 ; N periodcentered ; B 139 208 241 310 ;
-C 182 ; WX 500 ; N paragraph ; B 105 -199 638 594 ;
-C 183 ; WX 600 ; N bullet ; B 228 149 524 445 ;
-C 184 ; WX 180 ; N quotesinglbase ; B 21 -121 191 146 ;
-C 185 ; WX 280 ; N quotedblbase ; B -14 -121 281 146 ;
-C 186 ; WX 360 ; N quotedblright ; B 158 343 453 610 ;
-C 187 ; WX 380 ; N guillemotright ; B 117 24 375 414 ;
-C 188 ; WX 1000 ; N ellipsis ; B 124 -14 916 128 ;
-C 189 ; WX 960 ; N perthousand ; B 112 -160 1005 700 ;
-C 191 ; WX 400 ; N questiondown ; B 82 -186 387 438 ;
-C 193 ; WX 220 ; N grave ; B 193 492 339 659 ;
-C 194 ; WX 300 ; N acute ; B 265 492 422 659 ;
-C 195 ; WX 340 ; N circumflex ; B 223 482 443 649 ;
-C 196 ; WX 440 ; N tilde ; B 243 543 522 619 ;
-C 197 ; WX 440 ; N macron ; B 222 544 465 578 ;
-C 198 ; WX 440 ; N breve ; B 253 522 501 631 ;
-C 199 ; WX 220 ; N dotaccent ; B 236 522 328 610 ;
-C 200 ; WX 360 ; N dieresis ; B 243 522 469 610 ;
-C 202 ; WX 300 ; N ring ; B 240 483 416 659 ;
-C 203 ; WX 300 ; N cedilla ; B 12 -191 184 6 ;
-C 205 ; WX 400 ; N hungarumlaut ; B 208 492 495 659 ;
-C 206 ; WX 280 ; N ogonek ; B 38 -191 233 6 ;
-C 207 ; WX 340 ; N caron ; B 254 492 474 659 ;
-C 208 ; WX 1000 ; N emdash ; B 51 199 1065 239 ;
-C 225 ; WX 740 ; N AE ; B -21 -16 799 594 ;
-C 227 ; WX 260 ; N ordfeminine ; B 111 338 386 610 ;
-C 232 ; WX 580 ; N Lslash ; B 49 -16 657 610 ;
-C 233 ; WX 660 ; N Oslash ; B 83 -78 751 672 ;
-C 234 ; WX 820 ; N OE ; B 63 -16 909 610 ;
-C 235 ; WX 260 ; N ordmasculine ; B 128 339 373 610 ;
-C 241 ; WX 540 ; N ae ; B 67 -14 624 468 ;
-C 245 ; WX 240 ; N dotlessi ; B 100 -14 306 438 ;
-C 248 ; WX 300 ; N lslash ; B 121 -14 515 714 ;
-C 249 ; WX 440 ; N oslash ; B 46 -64 540 488 ;
-C 250 ; WX 560 ; N oe ; B 78 -14 628 438 ;
-C 251 ; WX 420 ; N germandbls ; B -127 -314 542 714 ;
-C -1 ; WX 340 ; N ecircumflex ; B 87 -14 433 649 ;
-C -1 ; WX 340 ; N edieresis ; B 87 -14 449 610 ;
-C -1 ; WX 420 ; N aacute ; B 92 -15 492 659 ;
-C -1 ; WX 740 ; N registered ; B 137 -16 763 610 ;
-C -1 ; WX 240 ; N icircumflex ; B 100 -14 363 649 ;
-C -1 ; WX 460 ; N udieresis ; B 102 -14 528 610 ;
-C -1 ; WX 400 ; N ograve ; B 87 -14 449 659 ;
-C -1 ; WX 460 ; N uacute ; B 102 -14 528 659 ;
-C -1 ; WX 460 ; N ucircumflex ; B 102 -14 528 649 ;
-C -1 ; WX 620 ; N Aacute ; B 13 -16 702 821 ;
-C -1 ; WX 240 ; N igrave ; B 100 -14 306 659 ;
-C -1 ; WX 380 ; N Icircumflex ; B 99 0 504 821 ;
-C -1 ; WX 340 ; N ccedilla ; B 62 -191 406 438 ;
-C -1 ; WX 420 ; N adieresis ; B 92 -15 485 610 ;
-C -1 ; WX 620 ; N Ecircumflex ; B 91 -12 709 821 ;
-C -1 ; WX 320 ; N scaron ; B 46 -14 464 659 ;
-C -1 ; WX 440 ; N thorn ; B -38 -314 505 714 ;
-C -1 ; WX 1000 ; N trademark ; B 127 187 1046 594 ;
-C -1 ; WX 340 ; N egrave ; B 87 -14 403 659 ;
-C -1 ; WX 264 ; N threesuperior ; B 59 234 348 610 ;
-C -1 ; WX 440 ; N zcaron ; B 26 -14 514 659 ;
-C -1 ; WX 420 ; N atilde ; B 92 -15 522 619 ;
-C -1 ; WX 420 ; N aring ; B 92 -15 485 659 ;
-C -1 ; WX 400 ; N ocircumflex ; B 87 -14 453 649 ;
-C -1 ; WX 620 ; N Edieresis ; B 91 -12 709 762 ;
-C -1 ; WX 660 ; N threequarters ; B 39 -16 706 610 ;
-C -1 ; WX 400 ; N ydieresis ; B -24 -314 483 610 ;
-C -1 ; WX 400 ; N yacute ; B -24 -314 483 659 ;
-C -1 ; WX 240 ; N iacute ; B 100 -14 392 659 ;
-C -1 ; WX 620 ; N Acircumflex ; B 13 -16 697 821 ;
-C -1 ; WX 740 ; N Uacute ; B 126 -16 792 821 ;
-C -1 ; WX 340 ; N eacute ; B 87 -14 462 659 ;
-C -1 ; WX 600 ; N Ograve ; B 94 -16 660 821 ;
-C -1 ; WX 420 ; N agrave ; B 92 -15 485 659 ;
-C -1 ; WX 740 ; N Udieresis ; B 126 -16 792 762 ;
-C -1 ; WX 420 ; N acircumflex ; B 92 -15 485 649 ;
-C -1 ; WX 380 ; N Igrave ; B 99 0 504 821 ;
-C -1 ; WX 264 ; N twosuperior ; B 72 234 354 610 ;
-C -1 ; WX 740 ; N Ugrave ; B 126 -16 792 821 ;
-C -1 ; WX 660 ; N onequarter ; B 56 -16 702 610 ;
-C -1 ; WX 740 ; N Ucircumflex ; B 126 -16 792 821 ;
-C -1 ; WX 460 ; N Scaron ; B 45 -81 594 831 ;
-C -1 ; WX 380 ; N Idieresis ; B 99 0 519 762 ;
-C -1 ; WX 240 ; N idieresis ; B 100 -14 369 610 ;
-C -1 ; WX 620 ; N Egrave ; B 91 -12 709 821 ;
-C -1 ; WX 600 ; N Oacute ; B 94 -16 660 821 ;
-C -1 ; WX 520 ; N divide ; B 117 -14 543 440 ;
-C -1 ; WX 620 ; N Atilde ; B 13 -16 702 771 ;
-C -1 ; WX 620 ; N Aring ; B 13 -16 697 831 ;
-C -1 ; WX 600 ; N Odieresis ; B 94 -16 660 762 ;
-C -1 ; WX 620 ; N Adieresis ; B 13 -16 709 762 ;
-C -1 ; WX 700 ; N Ntilde ; B 85 -168 915 761 ;
-C -1 ; WX 620 ; N Zcaron ; B 42 -19 669 831 ;
-C -1 ; WX 540 ; N Thorn ; B 52 0 647 623 ;
-C -1 ; WX 380 ; N Iacute ; B 99 0 532 821 ;
-C -1 ; WX 520 ; N plusminus ; B 117 0 543 436 ;
-C -1 ; WX 520 ; N multiply ; B 133 16 527 410 ;
-C -1 ; WX 620 ; N Eacute ; B 91 -12 709 821 ;
-C -1 ; WX 560 ; N Ydieresis ; B 41 -168 774 762 ;
-C -1 ; WX 264 ; N onesuperior ; B 83 244 311 610 ;
-C -1 ; WX 460 ; N ugrave ; B 102 -14 528 659 ;
-C -1 ; WX 520 ; N logicalnot ; B 117 86 543 340 ;
-C -1 ; WX 460 ; N ntilde ; B 101 -14 544 619 ;
-C -1 ; WX 600 ; N Otilde ; B 94 -16 660 761 ;
-C -1 ; WX 400 ; N otilde ; B 87 -14 502 619 ;
-C -1 ; WX 520 ; N Ccedilla ; B 93 -191 631 610 ;
-C -1 ; WX 620 ; N Agrave ; B 13 -16 697 821 ;
-C -1 ; WX 660 ; N onehalf ; B 56 -16 702 610 ;
-C -1 ; WX 700 ; N Eth ; B 86 -6 768 640 ;
-C -1 ; WX 400 ; N degree ; B 171 324 457 610 ;
-C -1 ; WX 560 ; N Yacute ; B 41 -168 774 821 ;
-C -1 ; WX 600 ; N Ocircumflex ; B 94 -16 660 821 ;
-C -1 ; WX 400 ; N oacute ; B 87 -14 482 659 ;
-C -1 ; WX 460 ; N mu ; B 7 -314 523 438 ;
-C -1 ; WX 520 ; N minus ; B 117 184 543 242 ;
-C -1 ; WX 400 ; N eth ; B 87 -14 522 714 ;
-C -1 ; WX 400 ; N odieresis ; B 87 -14 479 610 ;
-C -1 ; WX 740 ; N copyright ; B 137 -16 763 610 ;
-C -1 ; WX 520 ; N brokenbar ; B 320 -16 378 714 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 131
-
-KPX A quoteright -40
-KPX A quotedblright -40
-KPX A U -10
-KPX A T 10
-KPX A Q 10
-KPX A O 10
-KPX A G -30
-KPX A C 20
-
-KPX D period -30
-KPX D comma -20
-KPX D Y 10
-KPX D A -10
-
-KPX F period -40
-KPX F i 10
-KPX F comma -30
-
-KPX G period -20
-KPX G comma -10
-
-KPX J period -20
-KPX J comma -10
-
-KPX K u -20
-KPX K o -20
-KPX K e -20
-
-KPX L y -10
-KPX L quoteright -25
-KPX L quotedblright -25
-KPX L W -10
-KPX L V -20
-
-KPX O period -20
-KPX O comma -10
-KPX O Y 10
-KPX O T 20
-KPX O A -20
-
-KPX P period -50
-KPX P o -10
-KPX P e -10
-KPX P comma -40
-KPX P a -20
-KPX P A -10
-
-KPX Q U -10
-
-KPX R Y 10
-KPX R W 10
-KPX R T 20
-
-KPX T o -20
-KPX T i 20
-KPX T hyphen -20
-KPX T h 20
-KPX T e -20
-KPX T a -20
-KPX T O 30
-KPX T A 10
-
-KPX V period -100
-KPX V o -20
-KPX V e -20
-KPX V comma -90
-KPX V a -20
-KPX V O 10
-KPX V G -20
-
-KPX W period -50
-KPX W o -20
-KPX W i 10
-KPX W h 10
-KPX W e -20
-KPX W comma -40
-KPX W a -20
-KPX W O 10
-
-KPX Y u -20
-KPX Y period -50
-KPX Y o -50
-KPX Y i 10
-KPX Y e -40
-KPX Y comma -40
-KPX Y a -60
-
-KPX b period -30
-KPX b l -20
-KPX b comma -20
-KPX b b -20
-
-KPX c k -10
-
-KPX comma quoteright -70
-KPX comma quotedblright -70
-
-KPX d w -20
-KPX d v -10
-KPX d d -40
-
-KPX e y 10
-
-KPX f quoteright 30
-KPX f quotedblright 30
-KPX f period -50
-KPX f f -50
-KPX f e -10
-KPX f comma -40
-KPX f a -20
-
-KPX g y 10
-KPX g period -30
-KPX g i 10
-KPX g e 10
-KPX g comma -20
-KPX g a 10
-
-KPX k y 10
-KPX k o -10
-KPX k e -20
-
-KPX m y 10
-KPX m u 10
-
-KPX n y 20
-
-KPX o period -30
-KPX o comma -20
-
-KPX p period -30
-KPX p p -10
-KPX p comma -20
-
-KPX period quoteright -80
-KPX period quotedblright -80
-
-KPX quotedblleft quoteleft 20
-KPX quotedblleft A 10
-
-KPX quoteleft quoteleft -115
-KPX quoteleft A 10
-
-KPX quoteright v 30
-KPX quoteright t 20
-KPX quoteright s -25
-KPX quoteright r 30
-KPX quoteright quoteright -115
-KPX quoteright quotedblright 20
-KPX quoteright l 20
-
-KPX r period -50
-KPX r i 10
-KPX r comma -40
-
-KPX s period -20
-KPX s comma -10
-
-KPX v period -30
-KPX v comma -20
-
-KPX w period -30
-KPX w o 10
-KPX w h 20
-KPX w comma -20
-EndKernPairs
-EndKernData
-StartComposites 56
-CC Aacute 2 ; PCC A 0 0 ; PCC acute 280 162 ;
-CC Acircumflex 2 ; PCC A 0 0 ; PCC circumflex 240 172 ;
-CC Adieresis 2 ; PCC A 0 0 ; PCC dieresis 240 152 ;
-CC Agrave 2 ; PCC A 0 0 ; PCC grave 250 162 ;
-CC Aring 2 ; PCC A 0 0 ; PCC ring 260 172 ;
-CC Atilde 2 ; PCC A 0 0 ; PCC tilde 180 152 ;
-CC Eacute 2 ; PCC E 0 0 ; PCC acute 230 162 ;
-CC Ecircumflex 2 ; PCC E 0 0 ; PCC circumflex 180 172 ;
-CC Edieresis 2 ; PCC E 0 0 ; PCC dieresis 170 152 ;
-CC Egrave 2 ; PCC E 0 0 ; PCC grave 220 162 ;
-CC Iacute 2 ; PCC I 0 0 ; PCC acute 110 162 ;
-CC Icircumflex 2 ; PCC I 0 0 ; PCC circumflex 60 172 ;
-CC Idieresis 2 ; PCC I 0 0 ; PCC dieresis 50 152 ;
-CC Igrave 2 ; PCC I 0 0 ; PCC grave 100 162 ;
-CC Ntilde 2 ; PCC N 0 0 ; PCC tilde 210 142 ;
-CC Oacute 2 ; PCC O 0 0 ; PCC acute 160 162 ;
-CC Ocircumflex 2 ; PCC O 0 0 ; PCC circumflex 130 172 ;
-CC Odieresis 2 ; PCC O 0 0 ; PCC dieresis 120 152 ;
-CC Ograve 2 ; PCC O 0 0 ; PCC grave 150 162 ;
-CC Otilde 2 ; PCC O 0 0 ; PCC tilde 90 142 ;
-CC Scaron 2 ; PCC S 0 0 ; PCC caron 120 172 ;
-CC Uacute 2 ; PCC U 0 0 ; PCC acute 310 162 ;
-CC Ucircumflex 2 ; PCC U 0 0 ; PCC circumflex 260 172 ;
-CC Udieresis 2 ; PCC U 0 0 ; PCC dieresis 260 152 ;
-CC Ugrave 2 ; PCC U 0 0 ; PCC grave 270 162 ;
-CC Yacute 2 ; PCC Y 0 0 ; PCC acute 220 162 ;
-CC Ydieresis 2 ; PCC Y 0 0 ; PCC dieresis 170 152 ;
-CC Zcaron 2 ; PCC Z 0 0 ; PCC caron 130 172 ;
-CC aacute 2 ; PCC a 0 0 ; PCC acute 70 0 ;
-CC acircumflex 2 ; PCC a 0 0 ; PCC circumflex 20 0 ;
-CC adieresis 2 ; PCC a 0 0 ; PCC dieresis 10 0 ;
-CC agrave 2 ; PCC a 0 0 ; PCC grave 80 0 ;
-CC aring 2 ; PCC a 0 0 ; PCC ring 60 0 ;
-CC atilde 2 ; PCC a 0 0 ; PCC tilde 0 0 ;
-CC eacute 2 ; PCC e 0 0 ; PCC acute 40 0 ;
-CC ecircumflex 2 ; PCC e 0 0 ; PCC circumflex -10 0 ;
-CC edieresis 2 ; PCC e 0 0 ; PCC dieresis -20 0 ;
-CC egrave 2 ; PCC e 0 0 ; PCC grave 30 0 ;
-CC iacute 2 ; PCC dotlessi 0 0 ; PCC acute -30 0 ;
-CC icircumflex 2 ; PCC dotlessi 0 0 ; PCC circumflex -80 0 ;
-CC idieresis 2 ; PCC dotlessi 0 0 ; PCC dieresis -100 0 ;
-CC igrave 2 ; PCC dotlessi 0 0 ; PCC grave -40 0 ;
-CC ntilde 2 ; PCC n 0 0 ; PCC tilde 10 0 ;
-CC oacute 2 ; PCC o 0 0 ; PCC acute 60 0 ;
-CC ocircumflex 2 ; PCC o 0 0 ; PCC circumflex 10 0 ;
-CC odieresis 2 ; PCC o 0 0 ; PCC dieresis 10 0 ;
-CC ograve 2 ; PCC o 0 0 ; PCC grave 60 0 ;
-CC otilde 2 ; PCC o 0 0 ; PCC tilde -20 0 ;
-CC scaron 2 ; PCC s 0 0 ; PCC caron -10 0 ;
-CC uacute 2 ; PCC u 0 0 ; PCC acute 70 0 ;
-CC ucircumflex 2 ; PCC u 0 0 ; PCC circumflex 30 0 ;
-CC udieresis 2 ; PCC u 0 0 ; PCC dieresis 20 0 ;
-CC ugrave 2 ; PCC u 0 0 ; PCC grave 50 0 ;
-CC yacute 2 ; PCC y 0 0 ; PCC acute 60 0 ;
-CC ydieresis 2 ; PCC y 0 0 ; PCC dieresis 0 0 ;
-CC zcaron 2 ; PCC z 0 0 ; PCC caron 40 0 ;
-EndComposites
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pzdr.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pzdr.afm
deleted file mode 100644
index 6b98e8d35f..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/afm/pzdr.afm
+++ /dev/null
@@ -1,222 +0,0 @@
-StartFontMetrics 2.0
-Comment Copyright (c) 1985, 1987, 1988, 1989 Adobe Systems Incorporated. All rights reserved.
-Comment Creation Date: Fri Dec 1 12:57:42 1989
-Comment UniqueID 26200
-Comment VMusage 39281 49041
-FontName ZapfDingbats
-FullName ITC Zapf Dingbats
-FamilyName ITC Zapf Dingbats
-Weight Medium
-ItalicAngle 0
-IsFixedPitch false
-FontBBox -1 -143 981 820
-UnderlinePosition -98
-UnderlineThickness 54
-Version 001.004
-Notice Copyright (c) 1985, 1987, 1988, 1989 Adobe Systems Incorporated. All rights reserved.ITC Zapf Dingbats is a registered trademark of International Typeface Corporation.
-EncodingScheme FontSpecific
-StartCharMetrics 202
-C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 974 ; N a1 ; B 35 72 939 621 ;
-C 34 ; WX 961 ; N a2 ; B 35 81 927 611 ;
-C 35 ; WX 974 ; N a202 ; B 35 72 939 621 ;
-C 36 ; WX 980 ; N a3 ; B 35 0 945 692 ;
-C 37 ; WX 719 ; N a4 ; B 34 139 685 566 ;
-C 38 ; WX 789 ; N a5 ; B 35 -14 755 705 ;
-C 39 ; WX 790 ; N a119 ; B 35 -14 755 705 ;
-C 40 ; WX 791 ; N a118 ; B 35 -13 761 705 ;
-C 41 ; WX 690 ; N a117 ; B 35 138 655 553 ;
-C 42 ; WX 960 ; N a11 ; B 35 123 925 568 ;
-C 43 ; WX 939 ; N a12 ; B 35 134 904 559 ;
-C 44 ; WX 549 ; N a13 ; B 29 -11 516 705 ;
-C 45 ; WX 855 ; N a14 ; B 34 59 820 632 ;
-C 46 ; WX 911 ; N a15 ; B 35 50 876 642 ;
-C 47 ; WX 933 ; N a16 ; B 35 139 899 550 ;
-C 48 ; WX 911 ; N a105 ; B 35 50 876 642 ;
-C 49 ; WX 945 ; N a17 ; B 35 139 909 553 ;
-C 50 ; WX 974 ; N a18 ; B 35 104 938 587 ;
-C 51 ; WX 755 ; N a19 ; B 34 -13 721 705 ;
-C 52 ; WX 846 ; N a20 ; B 36 -14 811 705 ;
-C 53 ; WX 762 ; N a21 ; B 35 0 727 692 ;
-C 54 ; WX 761 ; N a22 ; B 35 0 727 692 ;
-C 55 ; WX 571 ; N a23 ; B -1 -68 571 661 ;
-C 56 ; WX 677 ; N a24 ; B 36 -13 642 705 ;
-C 57 ; WX 763 ; N a25 ; B 35 0 728 692 ;
-C 58 ; WX 760 ; N a26 ; B 35 0 726 692 ;
-C 59 ; WX 759 ; N a27 ; B 35 0 725 692 ;
-C 60 ; WX 754 ; N a28 ; B 35 0 720 692 ;
-C 61 ; WX 494 ; N a6 ; B 35 0 460 692 ;
-C 62 ; WX 552 ; N a7 ; B 35 0 517 692 ;
-C 63 ; WX 537 ; N a8 ; B 35 0 503 692 ;
-C 64 ; WX 577 ; N a9 ; B 35 96 542 596 ;
-C 65 ; WX 692 ; N a10 ; B 35 -14 657 705 ;
-C 66 ; WX 786 ; N a29 ; B 35 -14 751 705 ;
-C 67 ; WX 788 ; N a30 ; B 35 -14 752 705 ;
-C 68 ; WX 788 ; N a31 ; B 35 -14 753 705 ;
-C 69 ; WX 790 ; N a32 ; B 35 -14 756 705 ;
-C 70 ; WX 793 ; N a33 ; B 35 -13 759 705 ;
-C 71 ; WX 794 ; N a34 ; B 35 -13 759 705 ;
-C 72 ; WX 816 ; N a35 ; B 35 -14 782 705 ;
-C 73 ; WX 823 ; N a36 ; B 35 -14 787 705 ;
-C 74 ; WX 789 ; N a37 ; B 35 -14 754 705 ;
-C 75 ; WX 841 ; N a38 ; B 35 -14 807 705 ;
-C 76 ; WX 823 ; N a39 ; B 35 -14 789 705 ;
-C 77 ; WX 833 ; N a40 ; B 35 -14 798 705 ;
-C 78 ; WX 816 ; N a41 ; B 35 -13 782 705 ;
-C 79 ; WX 831 ; N a42 ; B 35 -14 796 705 ;
-C 80 ; WX 923 ; N a43 ; B 35 -14 888 705 ;
-C 81 ; WX 744 ; N a44 ; B 35 0 710 692 ;
-C 82 ; WX 723 ; N a45 ; B 35 0 688 692 ;
-C 83 ; WX 749 ; N a46 ; B 35 0 714 692 ;
-C 84 ; WX 790 ; N a47 ; B 34 -14 756 705 ;
-C 85 ; WX 792 ; N a48 ; B 35 -14 758 705 ;
-C 86 ; WX 695 ; N a49 ; B 35 -14 661 706 ;
-C 87 ; WX 776 ; N a50 ; B 35 -6 741 699 ;
-C 88 ; WX 768 ; N a51 ; B 35 -7 734 699 ;
-C 89 ; WX 792 ; N a52 ; B 35 -14 757 705 ;
-C 90 ; WX 759 ; N a53 ; B 35 0 725 692 ;
-C 91 ; WX 707 ; N a54 ; B 35 -13 672 704 ;
-C 92 ; WX 708 ; N a55 ; B 35 -14 672 705 ;
-C 93 ; WX 682 ; N a56 ; B 35 -14 647 705 ;
-C 94 ; WX 701 ; N a57 ; B 35 -14 666 705 ;
-C 95 ; WX 826 ; N a58 ; B 35 -14 791 705 ;
-C 96 ; WX 815 ; N a59 ; B 35 -14 780 705 ;
-C 97 ; WX 789 ; N a60 ; B 35 -14 754 705 ;
-C 98 ; WX 789 ; N a61 ; B 35 -14 754 705 ;
-C 99 ; WX 707 ; N a62 ; B 34 -14 673 705 ;
-C 100 ; WX 687 ; N a63 ; B 36 0 651 692 ;
-C 101 ; WX 696 ; N a64 ; B 35 0 661 691 ;
-C 102 ; WX 689 ; N a65 ; B 35 0 655 692 ;
-C 103 ; WX 786 ; N a66 ; B 34 -14 751 705 ;
-C 104 ; WX 787 ; N a67 ; B 35 -14 752 705 ;
-C 105 ; WX 713 ; N a68 ; B 35 -14 678 705 ;
-C 106 ; WX 791 ; N a69 ; B 35 -14 756 705 ;
-C 107 ; WX 785 ; N a70 ; B 36 -14 751 705 ;
-C 108 ; WX 791 ; N a71 ; B 35 -14 757 705 ;
-C 109 ; WX 873 ; N a72 ; B 35 -14 838 705 ;
-C 110 ; WX 761 ; N a73 ; B 35 0 726 692 ;
-C 111 ; WX 762 ; N a74 ; B 35 0 727 692 ;
-C 112 ; WX 762 ; N a203 ; B 35 0 727 692 ;
-C 113 ; WX 759 ; N a75 ; B 35 0 725 692 ;
-C 114 ; WX 759 ; N a204 ; B 35 0 725 692 ;
-C 115 ; WX 892 ; N a76 ; B 35 0 858 705 ;
-C 116 ; WX 892 ; N a77 ; B 35 -14 858 692 ;
-C 117 ; WX 788 ; N a78 ; B 35 -14 754 705 ;
-C 118 ; WX 784 ; N a79 ; B 35 -14 749 705 ;
-C 119 ; WX 438 ; N a81 ; B 35 -14 403 705 ;
-C 120 ; WX 138 ; N a82 ; B 35 0 104 692 ;
-C 121 ; WX 277 ; N a83 ; B 35 0 242 692 ;
-C 122 ; WX 415 ; N a84 ; B 35 0 380 692 ;
-C 123 ; WX 392 ; N a97 ; B 35 263 357 705 ;
-C 124 ; WX 392 ; N a98 ; B 34 263 357 705 ;
-C 125 ; WX 668 ; N a99 ; B 35 263 633 705 ;
-C 126 ; WX 668 ; N a100 ; B 36 263 634 705 ;
-C 161 ; WX 732 ; N a101 ; B 35 -143 697 806 ;
-C 162 ; WX 544 ; N a102 ; B 56 -14 488 706 ;
-C 163 ; WX 544 ; N a103 ; B 34 -14 508 705 ;
-C 164 ; WX 910 ; N a104 ; B 35 40 875 651 ;
-C 165 ; WX 667 ; N a106 ; B 35 -14 633 705 ;
-C 166 ; WX 760 ; N a107 ; B 35 -14 726 705 ;
-C 167 ; WX 760 ; N a108 ; B 0 121 758 569 ;
-C 168 ; WX 776 ; N a112 ; B 35 0 741 705 ;
-C 169 ; WX 595 ; N a111 ; B 34 -14 560 705 ;
-C 170 ; WX 694 ; N a110 ; B 35 -14 659 705 ;
-C 171 ; WX 626 ; N a109 ; B 34 0 591 705 ;
-C 172 ; WX 788 ; N a120 ; B 35 -14 754 705 ;
-C 173 ; WX 788 ; N a121 ; B 35 -14 754 705 ;
-C 174 ; WX 788 ; N a122 ; B 35 -14 754 705 ;
-C 175 ; WX 788 ; N a123 ; B 35 -14 754 705 ;
-C 176 ; WX 788 ; N a124 ; B 35 -14 754 705 ;
-C 177 ; WX 788 ; N a125 ; B 35 -14 754 705 ;
-C 178 ; WX 788 ; N a126 ; B 35 -14 754 705 ;
-C 179 ; WX 788 ; N a127 ; B 35 -14 754 705 ;
-C 180 ; WX 788 ; N a128 ; B 35 -14 754 705 ;
-C 181 ; WX 788 ; N a129 ; B 35 -14 754 705 ;
-C 182 ; WX 788 ; N a130 ; B 35 -14 754 705 ;
-C 183 ; WX 788 ; N a131 ; B 35 -14 754 705 ;
-C 184 ; WX 788 ; N a132 ; B 35 -14 754 705 ;
-C 185 ; WX 788 ; N a133 ; B 35 -14 754 705 ;
-C 186 ; WX 788 ; N a134 ; B 35 -14 754 705 ;
-C 187 ; WX 788 ; N a135 ; B 35 -14 754 705 ;
-C 188 ; WX 788 ; N a136 ; B 35 -14 754 705 ;
-C 189 ; WX 788 ; N a137 ; B 35 -14 754 705 ;
-C 190 ; WX 788 ; N a138 ; B 35 -14 754 705 ;
-C 191 ; WX 788 ; N a139 ; B 35 -14 754 705 ;
-C 192 ; WX 788 ; N a140 ; B 35 -14 754 705 ;
-C 193 ; WX 788 ; N a141 ; B 35 -14 754 705 ;
-C 194 ; WX 788 ; N a142 ; B 35 -14 754 705 ;
-C 195 ; WX 788 ; N a143 ; B 35 -14 754 705 ;
-C 196 ; WX 788 ; N a144 ; B 35 -14 754 705 ;
-C 197 ; WX 788 ; N a145 ; B 35 -14 754 705 ;
-C 198 ; WX 788 ; N a146 ; B 35 -14 754 705 ;
-C 199 ; WX 788 ; N a147 ; B 35 -14 754 705 ;
-C 200 ; WX 788 ; N a148 ; B 35 -14 754 705 ;
-C 201 ; WX 788 ; N a149 ; B 35 -14 754 705 ;
-C 202 ; WX 788 ; N a150 ; B 35 -14 754 705 ;
-C 203 ; WX 788 ; N a151 ; B 35 -14 754 705 ;
-C 204 ; WX 788 ; N a152 ; B 35 -14 754 705 ;
-C 205 ; WX 788 ; N a153 ; B 35 -14 754 705 ;
-C 206 ; WX 788 ; N a154 ; B 35 -14 754 705 ;
-C 207 ; WX 788 ; N a155 ; B 35 -14 754 705 ;
-C 208 ; WX 788 ; N a156 ; B 35 -14 754 705 ;
-C 209 ; WX 788 ; N a157 ; B 35 -14 754 705 ;
-C 210 ; WX 788 ; N a158 ; B 35 -14 754 705 ;
-C 211 ; WX 788 ; N a159 ; B 35 -14 754 705 ;
-C 212 ; WX 894 ; N a160 ; B 35 58 860 634 ;
-C 213 ; WX 838 ; N a161 ; B 35 152 803 540 ;
-C 214 ; WX 1016 ; N a163 ; B 34 152 981 540 ;
-C 215 ; WX 458 ; N a164 ; B 35 -127 422 820 ;
-C 216 ; WX 748 ; N a196 ; B 35 94 698 597 ;
-C 217 ; WX 924 ; N a165 ; B 35 140 890 552 ;
-C 218 ; WX 748 ; N a192 ; B 35 94 698 597 ;
-C 219 ; WX 918 ; N a166 ; B 35 166 884 526 ;
-C 220 ; WX 927 ; N a167 ; B 35 32 892 660 ;
-C 221 ; WX 928 ; N a168 ; B 35 129 891 562 ;
-C 222 ; WX 928 ; N a169 ; B 35 128 893 563 ;
-C 223 ; WX 834 ; N a170 ; B 35 155 799 537 ;
-C 224 ; WX 873 ; N a171 ; B 35 93 838 599 ;
-C 225 ; WX 828 ; N a172 ; B 35 104 791 588 ;
-C 226 ; WX 924 ; N a173 ; B 35 98 889 594 ;
-C 227 ; WX 924 ; N a162 ; B 35 98 889 594 ;
-C 228 ; WX 917 ; N a174 ; B 35 0 882 692 ;
-C 229 ; WX 930 ; N a175 ; B 35 84 896 608 ;
-C 230 ; WX 931 ; N a176 ; B 35 84 896 608 ;
-C 231 ; WX 463 ; N a177 ; B 35 -99 429 791 ;
-C 232 ; WX 883 ; N a178 ; B 35 71 848 623 ;
-C 233 ; WX 836 ; N a179 ; B 35 44 802 648 ;
-C 234 ; WX 836 ; N a193 ; B 35 44 802 648 ;
-C 235 ; WX 867 ; N a180 ; B 35 101 832 591 ;
-C 236 ; WX 867 ; N a199 ; B 35 101 832 591 ;
-C 237 ; WX 696 ; N a181 ; B 35 44 661 648 ;
-C 238 ; WX 696 ; N a200 ; B 35 44 661 648 ;
-C 239 ; WX 874 ; N a182 ; B 35 77 840 619 ;
-C 241 ; WX 874 ; N a201 ; B 35 73 840 615 ;
-C 242 ; WX 760 ; N a183 ; B 35 0 725 692 ;
-C 243 ; WX 946 ; N a184 ; B 35 160 911 533 ;
-C 244 ; WX 771 ; N a197 ; B 34 37 736 655 ;
-C 245 ; WX 865 ; N a185 ; B 35 207 830 481 ;
-C 246 ; WX 771 ; N a194 ; B 34 37 736 655 ;
-C 247 ; WX 888 ; N a198 ; B 34 -19 853 712 ;
-C 248 ; WX 967 ; N a186 ; B 35 124 932 568 ;
-C 249 ; WX 888 ; N a195 ; B 34 -19 853 712 ;
-C 250 ; WX 831 ; N a187 ; B 35 113 796 579 ;
-C 251 ; WX 873 ; N a188 ; B 36 118 838 578 ;
-C 252 ; WX 927 ; N a189 ; B 35 150 891 542 ;
-C 253 ; WX 970 ; N a190 ; B 35 76 931 616 ;
-C 254 ; WX 918 ; N a191 ; B 34 99 884 593 ;
-C -1 ; WX 410 ; N a86 ; B 35 0 375 692 ;
-C -1 ; WX 509 ; N a85 ; B 35 0 475 692 ;
-C -1 ; WX 334 ; N a95 ; B 35 0 299 692 ;
-C -1 ; WX 509 ; N a205 ; B 35 0 475 692 ;
-C -1 ; WX 390 ; N a89 ; B 35 -14 356 705 ;
-C -1 ; WX 234 ; N a87 ; B 35 -14 199 705 ;
-C -1 ; WX 276 ; N a91 ; B 35 0 242 692 ;
-C -1 ; WX 390 ; N a90 ; B 35 -14 355 705 ;
-C -1 ; WX 410 ; N a206 ; B 35 0 375 692 ;
-C -1 ; WX 317 ; N a94 ; B 35 0 283 692 ;
-C -1 ; WX 317 ; N a93 ; B 35 0 283 692 ;
-C -1 ; WX 276 ; N a92 ; B 35 0 242 692 ;
-C -1 ; WX 334 ; N a96 ; B 35 0 299 692 ;
-C -1 ; WX 234 ; N a88 ; B 35 -14 199 705 ;
-EndCharMetrics
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Bold.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Bold.afm
deleted file mode 100644
index eb80542b11..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Bold.afm
+++ /dev/null
@@ -1,342 +0,0 @@
-StartFontMetrics 4.1
-Comment Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Mon Jun 23 16:28:00 1997
-Comment UniqueID 43048
-Comment VMusage 41139 52164
-FontName Courier-Bold
-FullName Courier Bold
-FamilyName Courier
-Weight Bold
-ItalicAngle 0
-IsFixedPitch true
-CharacterSet ExtendedRoman
-FontBBox -113 -250 749 801
-UnderlinePosition -100
-UnderlineThickness 50
-Version 003.000
-Notice Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
-EncodingScheme AdobeStandardEncoding
-CapHeight 562
-XHeight 439
-Ascender 629
-Descender -157
-StdHW 84
-StdVW 106
-StartCharMetrics 315
-C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 600 ; N exclam ; B 202 -15 398 572 ;
-C 34 ; WX 600 ; N quotedbl ; B 135 277 465 562 ;
-C 35 ; WX 600 ; N numbersign ; B 56 -45 544 651 ;
-C 36 ; WX 600 ; N dollar ; B 82 -126 519 666 ;
-C 37 ; WX 600 ; N percent ; B 5 -15 595 616 ;
-C 38 ; WX 600 ; N ampersand ; B 36 -15 546 543 ;
-C 39 ; WX 600 ; N quoteright ; B 171 277 423 562 ;
-C 40 ; WX 600 ; N parenleft ; B 219 -102 461 616 ;
-C 41 ; WX 600 ; N parenright ; B 139 -102 381 616 ;
-C 42 ; WX 600 ; N asterisk ; B 91 219 509 601 ;
-C 43 ; WX 600 ; N plus ; B 71 39 529 478 ;
-C 44 ; WX 600 ; N comma ; B 123 -111 393 174 ;
-C 45 ; WX 600 ; N hyphen ; B 100 203 500 313 ;
-C 46 ; WX 600 ; N period ; B 192 -15 408 171 ;
-C 47 ; WX 600 ; N slash ; B 98 -77 502 626 ;
-C 48 ; WX 600 ; N zero ; B 87 -15 513 616 ;
-C 49 ; WX 600 ; N one ; B 81 0 539 616 ;
-C 50 ; WX 600 ; N two ; B 61 0 499 616 ;
-C 51 ; WX 600 ; N three ; B 63 -15 501 616 ;
-C 52 ; WX 600 ; N four ; B 53 0 507 616 ;
-C 53 ; WX 600 ; N five ; B 70 -15 521 601 ;
-C 54 ; WX 600 ; N six ; B 90 -15 521 616 ;
-C 55 ; WX 600 ; N seven ; B 55 0 494 601 ;
-C 56 ; WX 600 ; N eight ; B 83 -15 517 616 ;
-C 57 ; WX 600 ; N nine ; B 79 -15 510 616 ;
-C 58 ; WX 600 ; N colon ; B 191 -15 407 425 ;
-C 59 ; WX 600 ; N semicolon ; B 123 -111 408 425 ;
-C 60 ; WX 600 ; N less ; B 66 15 523 501 ;
-C 61 ; WX 600 ; N equal ; B 71 118 529 398 ;
-C 62 ; WX 600 ; N greater ; B 77 15 534 501 ;
-C 63 ; WX 600 ; N question ; B 98 -14 501 580 ;
-C 64 ; WX 600 ; N at ; B 16 -15 584 616 ;
-C 65 ; WX 600 ; N A ; B -9 0 609 562 ;
-C 66 ; WX 600 ; N B ; B 30 0 573 562 ;
-C 67 ; WX 600 ; N C ; B 22 -18 560 580 ;
-C 68 ; WX 600 ; N D ; B 30 0 594 562 ;
-C 69 ; WX 600 ; N E ; B 25 0 560 562 ;
-C 70 ; WX 600 ; N F ; B 39 0 570 562 ;
-C 71 ; WX 600 ; N G ; B 22 -18 594 580 ;
-C 72 ; WX 600 ; N H ; B 20 0 580 562 ;
-C 73 ; WX 600 ; N I ; B 77 0 523 562 ;
-C 74 ; WX 600 ; N J ; B 37 -18 601 562 ;
-C 75 ; WX 600 ; N K ; B 21 0 599 562 ;
-C 76 ; WX 600 ; N L ; B 39 0 578 562 ;
-C 77 ; WX 600 ; N M ; B -2 0 602 562 ;
-C 78 ; WX 600 ; N N ; B 8 -12 610 562 ;
-C 79 ; WX 600 ; N O ; B 22 -18 578 580 ;
-C 80 ; WX 600 ; N P ; B 48 0 559 562 ;
-C 81 ; WX 600 ; N Q ; B 32 -138 578 580 ;
-C 82 ; WX 600 ; N R ; B 24 0 599 562 ;
-C 83 ; WX 600 ; N S ; B 47 -22 553 582 ;
-C 84 ; WX 600 ; N T ; B 21 0 579 562 ;
-C 85 ; WX 600 ; N U ; B 4 -18 596 562 ;
-C 86 ; WX 600 ; N V ; B -13 0 613 562 ;
-C 87 ; WX 600 ; N W ; B -18 0 618 562 ;
-C 88 ; WX 600 ; N X ; B 12 0 588 562 ;
-C 89 ; WX 600 ; N Y ; B 12 0 589 562 ;
-C 90 ; WX 600 ; N Z ; B 62 0 539 562 ;
-C 91 ; WX 600 ; N bracketleft ; B 245 -102 475 616 ;
-C 92 ; WX 600 ; N backslash ; B 99 -77 503 626 ;
-C 93 ; WX 600 ; N bracketright ; B 125 -102 355 616 ;
-C 94 ; WX 600 ; N asciicircum ; B 108 250 492 616 ;
-C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ;
-C 96 ; WX 600 ; N quoteleft ; B 178 277 428 562 ;
-C 97 ; WX 600 ; N a ; B 35 -15 570 454 ;
-C 98 ; WX 600 ; N b ; B 0 -15 584 626 ;
-C 99 ; WX 600 ; N c ; B 40 -15 545 459 ;
-C 100 ; WX 600 ; N d ; B 20 -15 591 626 ;
-C 101 ; WX 600 ; N e ; B 40 -15 563 454 ;
-C 102 ; WX 600 ; N f ; B 83 0 547 626 ; L i fi ; L l fl ;
-C 103 ; WX 600 ; N g ; B 30 -146 580 454 ;
-C 104 ; WX 600 ; N h ; B 5 0 592 626 ;
-C 105 ; WX 600 ; N i ; B 77 0 523 658 ;
-C 106 ; WX 600 ; N j ; B 63 -146 440 658 ;
-C 107 ; WX 600 ; N k ; B 20 0 585 626 ;
-C 108 ; WX 600 ; N l ; B 77 0 523 626 ;
-C 109 ; WX 600 ; N m ; B -22 0 626 454 ;
-C 110 ; WX 600 ; N n ; B 18 0 592 454 ;
-C 111 ; WX 600 ; N o ; B 30 -15 570 454 ;
-C 112 ; WX 600 ; N p ; B -1 -142 570 454 ;
-C 113 ; WX 600 ; N q ; B 20 -142 591 454 ;
-C 114 ; WX 600 ; N r ; B 47 0 580 454 ;
-C 115 ; WX 600 ; N s ; B 68 -17 535 459 ;
-C 116 ; WX 600 ; N t ; B 47 -15 532 562 ;
-C 117 ; WX 600 ; N u ; B -1 -15 569 439 ;
-C 118 ; WX 600 ; N v ; B -1 0 601 439 ;
-C 119 ; WX 600 ; N w ; B -18 0 618 439 ;
-C 120 ; WX 600 ; N x ; B 6 0 594 439 ;
-C 121 ; WX 600 ; N y ; B -4 -142 601 439 ;
-C 122 ; WX 600 ; N z ; B 81 0 520 439 ;
-C 123 ; WX 600 ; N braceleft ; B 160 -102 464 616 ;
-C 124 ; WX 600 ; N bar ; B 255 -250 345 750 ;
-C 125 ; WX 600 ; N braceright ; B 136 -102 440 616 ;
-C 126 ; WX 600 ; N asciitilde ; B 71 153 530 356 ;
-C 161 ; WX 600 ; N exclamdown ; B 202 -146 398 449 ;
-C 162 ; WX 600 ; N cent ; B 66 -49 518 614 ;
-C 163 ; WX 600 ; N sterling ; B 72 -28 558 611 ;
-C 164 ; WX 600 ; N fraction ; B 25 -60 576 661 ;
-C 165 ; WX 600 ; N yen ; B 10 0 590 562 ;
-C 166 ; WX 600 ; N florin ; B -30 -131 572 616 ;
-C 167 ; WX 600 ; N section ; B 83 -70 517 580 ;
-C 168 ; WX 600 ; N currency ; B 54 49 546 517 ;
-C 169 ; WX 600 ; N quotesingle ; B 227 277 373 562 ;
-C 170 ; WX 600 ; N quotedblleft ; B 71 277 535 562 ;
-C 171 ; WX 600 ; N guillemotleft ; B 8 70 553 446 ;
-C 172 ; WX 600 ; N guilsinglleft ; B 141 70 459 446 ;
-C 173 ; WX 600 ; N guilsinglright ; B 141 70 459 446 ;
-C 174 ; WX 600 ; N fi ; B 12 0 593 626 ;
-C 175 ; WX 600 ; N fl ; B 12 0 593 626 ;
-C 177 ; WX 600 ; N endash ; B 65 203 535 313 ;
-C 178 ; WX 600 ; N dagger ; B 106 -70 494 580 ;
-C 179 ; WX 600 ; N daggerdbl ; B 106 -70 494 580 ;
-C 180 ; WX 600 ; N periodcentered ; B 196 165 404 351 ;
-C 182 ; WX 600 ; N paragraph ; B 6 -70 576 580 ;
-C 183 ; WX 600 ; N bullet ; B 140 132 460 430 ;
-C 184 ; WX 600 ; N quotesinglbase ; B 175 -142 427 143 ;
-C 185 ; WX 600 ; N quotedblbase ; B 65 -142 529 143 ;
-C 186 ; WX 600 ; N quotedblright ; B 61 277 525 562 ;
-C 187 ; WX 600 ; N guillemotright ; B 47 70 592 446 ;
-C 188 ; WX 600 ; N ellipsis ; B 26 -15 574 116 ;
-C 189 ; WX 600 ; N perthousand ; B -113 -15 713 616 ;
-C 191 ; WX 600 ; N questiondown ; B 99 -146 502 449 ;
-C 193 ; WX 600 ; N grave ; B 132 508 395 661 ;
-C 194 ; WX 600 ; N acute ; B 205 508 468 661 ;
-C 195 ; WX 600 ; N circumflex ; B 103 483 497 657 ;
-C 196 ; WX 600 ; N tilde ; B 89 493 512 636 ;
-C 197 ; WX 600 ; N macron ; B 88 505 512 585 ;
-C 198 ; WX 600 ; N breve ; B 83 468 517 631 ;
-C 199 ; WX 600 ; N dotaccent ; B 230 498 370 638 ;
-C 200 ; WX 600 ; N dieresis ; B 128 498 472 638 ;
-C 202 ; WX 600 ; N ring ; B 198 481 402 678 ;
-C 203 ; WX 600 ; N cedilla ; B 205 -206 387 0 ;
-C 205 ; WX 600 ; N hungarumlaut ; B 68 488 588 661 ;
-C 206 ; WX 600 ; N ogonek ; B 169 -199 400 0 ;
-C 207 ; WX 600 ; N caron ; B 103 493 497 667 ;
-C 208 ; WX 600 ; N emdash ; B -10 203 610 313 ;
-C 225 ; WX 600 ; N AE ; B -29 0 602 562 ;
-C 227 ; WX 600 ; N ordfeminine ; B 147 196 453 580 ;
-C 232 ; WX 600 ; N Lslash ; B 39 0 578 562 ;
-C 233 ; WX 600 ; N Oslash ; B 22 -22 578 584 ;
-C 234 ; WX 600 ; N OE ; B -25 0 595 562 ;
-C 235 ; WX 600 ; N ordmasculine ; B 147 196 453 580 ;
-C 241 ; WX 600 ; N ae ; B -4 -15 601 454 ;
-C 245 ; WX 600 ; N dotlessi ; B 77 0 523 439 ;
-C 248 ; WX 600 ; N lslash ; B 77 0 523 626 ;
-C 249 ; WX 600 ; N oslash ; B 30 -24 570 463 ;
-C 250 ; WX 600 ; N oe ; B -18 -15 611 454 ;
-C 251 ; WX 600 ; N germandbls ; B 22 -15 596 626 ;
-C -1 ; WX 600 ; N Idieresis ; B 77 0 523 761 ;
-C -1 ; WX 600 ; N eacute ; B 40 -15 563 661 ;
-C -1 ; WX 600 ; N abreve ; B 35 -15 570 661 ;
-C -1 ; WX 600 ; N uhungarumlaut ; B -1 -15 628 661 ;
-C -1 ; WX 600 ; N ecaron ; B 40 -15 563 667 ;
-C -1 ; WX 600 ; N Ydieresis ; B 12 0 589 761 ;
-C -1 ; WX 600 ; N divide ; B 71 16 529 500 ;
-C -1 ; WX 600 ; N Yacute ; B 12 0 589 784 ;
-C -1 ; WX 600 ; N Acircumflex ; B -9 0 609 780 ;
-C -1 ; WX 600 ; N aacute ; B 35 -15 570 661 ;
-C -1 ; WX 600 ; N Ucircumflex ; B 4 -18 596 780 ;
-C -1 ; WX 600 ; N yacute ; B -4 -142 601 661 ;
-C -1 ; WX 600 ; N scommaaccent ; B 68 -250 535 459 ;
-C -1 ; WX 600 ; N ecircumflex ; B 40 -15 563 657 ;
-C -1 ; WX 600 ; N Uring ; B 4 -18 596 801 ;
-C -1 ; WX 600 ; N Udieresis ; B 4 -18 596 761 ;
-C -1 ; WX 600 ; N aogonek ; B 35 -199 586 454 ;
-C -1 ; WX 600 ; N Uacute ; B 4 -18 596 784 ;
-C -1 ; WX 600 ; N uogonek ; B -1 -199 585 439 ;
-C -1 ; WX 600 ; N Edieresis ; B 25 0 560 761 ;
-C -1 ; WX 600 ; N Dcroat ; B 30 0 594 562 ;
-C -1 ; WX 600 ; N commaaccent ; B 205 -250 397 -57 ;
-C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ;
-C -1 ; WX 600 ; N Emacron ; B 25 0 560 708 ;
-C -1 ; WX 600 ; N ccaron ; B 40 -15 545 667 ;
-C -1 ; WX 600 ; N aring ; B 35 -15 570 678 ;
-C -1 ; WX 600 ; N Ncommaaccent ; B 8 -250 610 562 ;
-C -1 ; WX 600 ; N lacute ; B 77 0 523 801 ;
-C -1 ; WX 600 ; N agrave ; B 35 -15 570 661 ;
-C -1 ; WX 600 ; N Tcommaaccent ; B 21 -250 579 562 ;
-C -1 ; WX 600 ; N Cacute ; B 22 -18 560 784 ;
-C -1 ; WX 600 ; N atilde ; B 35 -15 570 636 ;
-C -1 ; WX 600 ; N Edotaccent ; B 25 0 560 761 ;
-C -1 ; WX 600 ; N scaron ; B 68 -17 535 667 ;
-C -1 ; WX 600 ; N scedilla ; B 68 -206 535 459 ;
-C -1 ; WX 600 ; N iacute ; B 77 0 523 661 ;
-C -1 ; WX 600 ; N lozenge ; B 66 0 534 740 ;
-C -1 ; WX 600 ; N Rcaron ; B 24 0 599 790 ;
-C -1 ; WX 600 ; N Gcommaaccent ; B 22 -250 594 580 ;
-C -1 ; WX 600 ; N ucircumflex ; B -1 -15 569 657 ;
-C -1 ; WX 600 ; N acircumflex ; B 35 -15 570 657 ;
-C -1 ; WX 600 ; N Amacron ; B -9 0 609 708 ;
-C -1 ; WX 600 ; N rcaron ; B 47 0 580 667 ;
-C -1 ; WX 600 ; N ccedilla ; B 40 -206 545 459 ;
-C -1 ; WX 600 ; N Zdotaccent ; B 62 0 539 761 ;
-C -1 ; WX 600 ; N Thorn ; B 48 0 557 562 ;
-C -1 ; WX 600 ; N Omacron ; B 22 -18 578 708 ;
-C -1 ; WX 600 ; N Racute ; B 24 0 599 784 ;
-C -1 ; WX 600 ; N Sacute ; B 47 -22 553 784 ;
-C -1 ; WX 600 ; N dcaron ; B 20 -15 727 626 ;
-C -1 ; WX 600 ; N Umacron ; B 4 -18 596 708 ;
-C -1 ; WX 600 ; N uring ; B -1 -15 569 678 ;
-C -1 ; WX 600 ; N threesuperior ; B 138 222 433 616 ;
-C -1 ; WX 600 ; N Ograve ; B 22 -18 578 784 ;
-C -1 ; WX 600 ; N Agrave ; B -9 0 609 784 ;
-C -1 ; WX 600 ; N Abreve ; B -9 0 609 784 ;
-C -1 ; WX 600 ; N multiply ; B 81 39 520 478 ;
-C -1 ; WX 600 ; N uacute ; B -1 -15 569 661 ;
-C -1 ; WX 600 ; N Tcaron ; B 21 0 579 790 ;
-C -1 ; WX 600 ; N partialdiff ; B 63 -38 537 728 ;
-C -1 ; WX 600 ; N ydieresis ; B -4 -142 601 638 ;
-C -1 ; WX 600 ; N Nacute ; B 8 -12 610 784 ;
-C -1 ; WX 600 ; N icircumflex ; B 73 0 523 657 ;
-C -1 ; WX 600 ; N Ecircumflex ; B 25 0 560 780 ;
-C -1 ; WX 600 ; N adieresis ; B 35 -15 570 638 ;
-C -1 ; WX 600 ; N edieresis ; B 40 -15 563 638 ;
-C -1 ; WX 600 ; N cacute ; B 40 -15 545 661 ;
-C -1 ; WX 600 ; N nacute ; B 18 0 592 661 ;
-C -1 ; WX 600 ; N umacron ; B -1 -15 569 585 ;
-C -1 ; WX 600 ; N Ncaron ; B 8 -12 610 790 ;
-C -1 ; WX 600 ; N Iacute ; B 77 0 523 784 ;
-C -1 ; WX 600 ; N plusminus ; B 71 24 529 515 ;
-C -1 ; WX 600 ; N brokenbar ; B 255 -175 345 675 ;
-C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ;
-C -1 ; WX 600 ; N Gbreve ; B 22 -18 594 784 ;
-C -1 ; WX 600 ; N Idotaccent ; B 77 0 523 761 ;
-C -1 ; WX 600 ; N summation ; B 15 -10 586 706 ;
-C -1 ; WX 600 ; N Egrave ; B 25 0 560 784 ;
-C -1 ; WX 600 ; N racute ; B 47 0 580 661 ;
-C -1 ; WX 600 ; N omacron ; B 30 -15 570 585 ;
-C -1 ; WX 600 ; N Zacute ; B 62 0 539 784 ;
-C -1 ; WX 600 ; N Zcaron ; B 62 0 539 790 ;
-C -1 ; WX 600 ; N greaterequal ; B 26 0 523 696 ;
-C -1 ; WX 600 ; N Eth ; B 30 0 594 562 ;
-C -1 ; WX 600 ; N Ccedilla ; B 22 -206 560 580 ;
-C -1 ; WX 600 ; N lcommaaccent ; B 77 -250 523 626 ;
-C -1 ; WX 600 ; N tcaron ; B 47 -15 532 703 ;
-C -1 ; WX 600 ; N eogonek ; B 40 -199 563 454 ;
-C -1 ; WX 600 ; N Uogonek ; B 4 -199 596 562 ;
-C -1 ; WX 600 ; N Aacute ; B -9 0 609 784 ;
-C -1 ; WX 600 ; N Adieresis ; B -9 0 609 761 ;
-C -1 ; WX 600 ; N egrave ; B 40 -15 563 661 ;
-C -1 ; WX 600 ; N zacute ; B 81 0 520 661 ;
-C -1 ; WX 600 ; N iogonek ; B 77 -199 523 658 ;
-C -1 ; WX 600 ; N Oacute ; B 22 -18 578 784 ;
-C -1 ; WX 600 ; N oacute ; B 30 -15 570 661 ;
-C -1 ; WX 600 ; N amacron ; B 35 -15 570 585 ;
-C -1 ; WX 600 ; N sacute ; B 68 -17 535 661 ;
-C -1 ; WX 600 ; N idieresis ; B 77 0 523 618 ;
-C -1 ; WX 600 ; N Ocircumflex ; B 22 -18 578 780 ;
-C -1 ; WX 600 ; N Ugrave ; B 4 -18 596 784 ;
-C -1 ; WX 600 ; N Delta ; B 6 0 594 688 ;
-C -1 ; WX 600 ; N thorn ; B -14 -142 570 626 ;
-C -1 ; WX 600 ; N twosuperior ; B 143 230 436 616 ;
-C -1 ; WX 600 ; N Odieresis ; B 22 -18 578 761 ;
-C -1 ; WX 600 ; N mu ; B -1 -142 569 439 ;
-C -1 ; WX 600 ; N igrave ; B 77 0 523 661 ;
-C -1 ; WX 600 ; N ohungarumlaut ; B 30 -15 668 661 ;
-C -1 ; WX 600 ; N Eogonek ; B 25 -199 576 562 ;
-C -1 ; WX 600 ; N dcroat ; B 20 -15 591 626 ;
-C -1 ; WX 600 ; N threequarters ; B -47 -60 648 661 ;
-C -1 ; WX 600 ; N Scedilla ; B 47 -206 553 582 ;
-C -1 ; WX 600 ; N lcaron ; B 77 0 597 626 ;
-C -1 ; WX 600 ; N Kcommaaccent ; B 21 -250 599 562 ;
-C -1 ; WX 600 ; N Lacute ; B 39 0 578 784 ;
-C -1 ; WX 600 ; N trademark ; B -9 230 749 562 ;
-C -1 ; WX 600 ; N edotaccent ; B 40 -15 563 638 ;
-C -1 ; WX 600 ; N Igrave ; B 77 0 523 784 ;
-C -1 ; WX 600 ; N Imacron ; B 77 0 523 708 ;
-C -1 ; WX 600 ; N Lcaron ; B 39 0 637 562 ;
-C -1 ; WX 600 ; N onehalf ; B -47 -60 648 661 ;
-C -1 ; WX 600 ; N lessequal ; B 26 0 523 696 ;
-C -1 ; WX 600 ; N ocircumflex ; B 30 -15 570 657 ;
-C -1 ; WX 600 ; N ntilde ; B 18 0 592 636 ;
-C -1 ; WX 600 ; N Uhungarumlaut ; B 4 -18 638 784 ;
-C -1 ; WX 600 ; N Eacute ; B 25 0 560 784 ;
-C -1 ; WX 600 ; N emacron ; B 40 -15 563 585 ;
-C -1 ; WX 600 ; N gbreve ; B 30 -146 580 661 ;
-C -1 ; WX 600 ; N onequarter ; B -56 -60 656 661 ;
-C -1 ; WX 600 ; N Scaron ; B 47 -22 553 790 ;
-C -1 ; WX 600 ; N Scommaaccent ; B 47 -250 553 582 ;
-C -1 ; WX 600 ; N Ohungarumlaut ; B 22 -18 628 784 ;
-C -1 ; WX 600 ; N degree ; B 86 243 474 616 ;
-C -1 ; WX 600 ; N ograve ; B 30 -15 570 661 ;
-C -1 ; WX 600 ; N Ccaron ; B 22 -18 560 790 ;
-C -1 ; WX 600 ; N ugrave ; B -1 -15 569 661 ;
-C -1 ; WX 600 ; N radical ; B -19 -104 473 778 ;
-C -1 ; WX 600 ; N Dcaron ; B 30 0 594 790 ;
-C -1 ; WX 600 ; N rcommaaccent ; B 47 -250 580 454 ;
-C -1 ; WX 600 ; N Ntilde ; B 8 -12 610 759 ;
-C -1 ; WX 600 ; N otilde ; B 30 -15 570 636 ;
-C -1 ; WX 600 ; N Rcommaaccent ; B 24 -250 599 562 ;
-C -1 ; WX 600 ; N Lcommaaccent ; B 39 -250 578 562 ;
-C -1 ; WX 600 ; N Atilde ; B -9 0 609 759 ;
-C -1 ; WX 600 ; N Aogonek ; B -9 -199 625 562 ;
-C -1 ; WX 600 ; N Aring ; B -9 0 609 801 ;
-C -1 ; WX 600 ; N Otilde ; B 22 -18 578 759 ;
-C -1 ; WX 600 ; N zdotaccent ; B 81 0 520 638 ;
-C -1 ; WX 600 ; N Ecaron ; B 25 0 560 790 ;
-C -1 ; WX 600 ; N Iogonek ; B 77 -199 523 562 ;
-C -1 ; WX 600 ; N kcommaaccent ; B 20 -250 585 626 ;
-C -1 ; WX 600 ; N minus ; B 71 203 529 313 ;
-C -1 ; WX 600 ; N Icircumflex ; B 77 0 523 780 ;
-C -1 ; WX 600 ; N ncaron ; B 18 0 592 667 ;
-C -1 ; WX 600 ; N tcommaaccent ; B 47 -250 532 562 ;
-C -1 ; WX 600 ; N logicalnot ; B 71 103 529 413 ;
-C -1 ; WX 600 ; N odieresis ; B 30 -15 570 638 ;
-C -1 ; WX 600 ; N udieresis ; B -1 -15 569 638 ;
-C -1 ; WX 600 ; N notequal ; B 12 -47 537 563 ;
-C -1 ; WX 600 ; N gcommaaccent ; B 30 -146 580 714 ;
-C -1 ; WX 600 ; N eth ; B 58 -27 543 626 ;
-C -1 ; WX 600 ; N zcaron ; B 81 0 520 667 ;
-C -1 ; WX 600 ; N ncommaaccent ; B 18 -250 592 454 ;
-C -1 ; WX 600 ; N onesuperior ; B 153 230 447 616 ;
-C -1 ; WX 600 ; N imacron ; B 77 0 523 585 ;
-C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ;
-EndCharMetrics
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-BoldOblique.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-BoldOblique.afm
deleted file mode 100644
index 29d3b8b10e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-BoldOblique.afm
+++ /dev/null
@@ -1,342 +0,0 @@
-StartFontMetrics 4.1
-Comment Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Mon Jun 23 16:28:46 1997
-Comment UniqueID 43049
-Comment VMusage 17529 79244
-FontName Courier-BoldOblique
-FullName Courier Bold Oblique
-FamilyName Courier
-Weight Bold
-ItalicAngle -12
-IsFixedPitch true
-CharacterSet ExtendedRoman
-FontBBox -57 -250 869 801
-UnderlinePosition -100
-UnderlineThickness 50
-Version 003.000
-Notice Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
-EncodingScheme AdobeStandardEncoding
-CapHeight 562
-XHeight 439
-Ascender 629
-Descender -157
-StdHW 84
-StdVW 106
-StartCharMetrics 315
-C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 600 ; N exclam ; B 215 -15 495 572 ;
-C 34 ; WX 600 ; N quotedbl ; B 211 277 585 562 ;
-C 35 ; WX 600 ; N numbersign ; B 88 -45 641 651 ;
-C 36 ; WX 600 ; N dollar ; B 87 -126 630 666 ;
-C 37 ; WX 600 ; N percent ; B 101 -15 625 616 ;
-C 38 ; WX 600 ; N ampersand ; B 61 -15 595 543 ;
-C 39 ; WX 600 ; N quoteright ; B 229 277 543 562 ;
-C 40 ; WX 600 ; N parenleft ; B 265 -102 592 616 ;
-C 41 ; WX 600 ; N parenright ; B 117 -102 444 616 ;
-C 42 ; WX 600 ; N asterisk ; B 179 219 598 601 ;
-C 43 ; WX 600 ; N plus ; B 114 39 596 478 ;
-C 44 ; WX 600 ; N comma ; B 99 -111 430 174 ;
-C 45 ; WX 600 ; N hyphen ; B 143 203 567 313 ;
-C 46 ; WX 600 ; N period ; B 206 -15 427 171 ;
-C 47 ; WX 600 ; N slash ; B 90 -77 626 626 ;
-C 48 ; WX 600 ; N zero ; B 135 -15 593 616 ;
-C 49 ; WX 600 ; N one ; B 93 0 562 616 ;
-C 50 ; WX 600 ; N two ; B 61 0 594 616 ;
-C 51 ; WX 600 ; N three ; B 71 -15 571 616 ;
-C 52 ; WX 600 ; N four ; B 81 0 559 616 ;
-C 53 ; WX 600 ; N five ; B 77 -15 621 601 ;
-C 54 ; WX 600 ; N six ; B 135 -15 652 616 ;
-C 55 ; WX 600 ; N seven ; B 147 0 622 601 ;
-C 56 ; WX 600 ; N eight ; B 115 -15 604 616 ;
-C 57 ; WX 600 ; N nine ; B 75 -15 592 616 ;
-C 58 ; WX 600 ; N colon ; B 205 -15 480 425 ;
-C 59 ; WX 600 ; N semicolon ; B 99 -111 481 425 ;
-C 60 ; WX 600 ; N less ; B 120 15 613 501 ;
-C 61 ; WX 600 ; N equal ; B 96 118 614 398 ;
-C 62 ; WX 600 ; N greater ; B 97 15 589 501 ;
-C 63 ; WX 600 ; N question ; B 183 -14 592 580 ;
-C 64 ; WX 600 ; N at ; B 65 -15 642 616 ;
-C 65 ; WX 600 ; N A ; B -9 0 632 562 ;
-C 66 ; WX 600 ; N B ; B 30 0 630 562 ;
-C 67 ; WX 600 ; N C ; B 74 -18 675 580 ;
-C 68 ; WX 600 ; N D ; B 30 0 664 562 ;
-C 69 ; WX 600 ; N E ; B 25 0 670 562 ;
-C 70 ; WX 600 ; N F ; B 39 0 684 562 ;
-C 71 ; WX 600 ; N G ; B 74 -18 675 580 ;
-C 72 ; WX 600 ; N H ; B 20 0 700 562 ;
-C 73 ; WX 600 ; N I ; B 77 0 643 562 ;
-C 74 ; WX 600 ; N J ; B 58 -18 721 562 ;
-C 75 ; WX 600 ; N K ; B 21 0 692 562 ;
-C 76 ; WX 600 ; N L ; B 39 0 636 562 ;
-C 77 ; WX 600 ; N M ; B -2 0 722 562 ;
-C 78 ; WX 600 ; N N ; B 8 -12 730 562 ;
-C 79 ; WX 600 ; N O ; B 74 -18 645 580 ;
-C 80 ; WX 600 ; N P ; B 48 0 643 562 ;
-C 81 ; WX 600 ; N Q ; B 83 -138 636 580 ;
-C 82 ; WX 600 ; N R ; B 24 0 617 562 ;
-C 83 ; WX 600 ; N S ; B 54 -22 673 582 ;
-C 84 ; WX 600 ; N T ; B 86 0 679 562 ;
-C 85 ; WX 600 ; N U ; B 101 -18 716 562 ;
-C 86 ; WX 600 ; N V ; B 84 0 733 562 ;
-C 87 ; WX 600 ; N W ; B 79 0 738 562 ;
-C 88 ; WX 600 ; N X ; B 12 0 690 562 ;
-C 89 ; WX 600 ; N Y ; B 109 0 709 562 ;
-C 90 ; WX 600 ; N Z ; B 62 0 637 562 ;
-C 91 ; WX 600 ; N bracketleft ; B 223 -102 606 616 ;
-C 92 ; WX 600 ; N backslash ; B 222 -77 496 626 ;
-C 93 ; WX 600 ; N bracketright ; B 103 -102 486 616 ;
-C 94 ; WX 600 ; N asciicircum ; B 171 250 556 616 ;
-C 95 ; WX 600 ; N underscore ; B -27 -125 585 -75 ;
-C 96 ; WX 600 ; N quoteleft ; B 297 277 487 562 ;
-C 97 ; WX 600 ; N a ; B 61 -15 593 454 ;
-C 98 ; WX 600 ; N b ; B 13 -15 636 626 ;
-C 99 ; WX 600 ; N c ; B 81 -15 631 459 ;
-C 100 ; WX 600 ; N d ; B 60 -15 645 626 ;
-C 101 ; WX 600 ; N e ; B 81 -15 605 454 ;
-C 102 ; WX 600 ; N f ; B 83 0 677 626 ; L i fi ; L l fl ;
-C 103 ; WX 600 ; N g ; B 40 -146 674 454 ;
-C 104 ; WX 600 ; N h ; B 18 0 615 626 ;
-C 105 ; WX 600 ; N i ; B 77 0 546 658 ;
-C 106 ; WX 600 ; N j ; B 36 -146 580 658 ;
-C 107 ; WX 600 ; N k ; B 33 0 643 626 ;
-C 108 ; WX 600 ; N l ; B 77 0 546 626 ;
-C 109 ; WX 600 ; N m ; B -22 0 649 454 ;
-C 110 ; WX 600 ; N n ; B 18 0 615 454 ;
-C 111 ; WX 600 ; N o ; B 71 -15 622 454 ;
-C 112 ; WX 600 ; N p ; B -32 -142 622 454 ;
-C 113 ; WX 600 ; N q ; B 60 -142 685 454 ;
-C 114 ; WX 600 ; N r ; B 47 0 655 454 ;
-C 115 ; WX 600 ; N s ; B 66 -17 608 459 ;
-C 116 ; WX 600 ; N t ; B 118 -15 567 562 ;
-C 117 ; WX 600 ; N u ; B 70 -15 592 439 ;
-C 118 ; WX 600 ; N v ; B 70 0 695 439 ;
-C 119 ; WX 600 ; N w ; B 53 0 712 439 ;
-C 120 ; WX 600 ; N x ; B 6 0 671 439 ;
-C 121 ; WX 600 ; N y ; B -21 -142 695 439 ;
-C 122 ; WX 600 ; N z ; B 81 0 614 439 ;
-C 123 ; WX 600 ; N braceleft ; B 203 -102 595 616 ;
-C 124 ; WX 600 ; N bar ; B 201 -250 505 750 ;
-C 125 ; WX 600 ; N braceright ; B 114 -102 506 616 ;
-C 126 ; WX 600 ; N asciitilde ; B 120 153 590 356 ;
-C 161 ; WX 600 ; N exclamdown ; B 196 -146 477 449 ;
-C 162 ; WX 600 ; N cent ; B 121 -49 605 614 ;
-C 163 ; WX 600 ; N sterling ; B 106 -28 650 611 ;
-C 164 ; WX 600 ; N fraction ; B 22 -60 708 661 ;
-C 165 ; WX 600 ; N yen ; B 98 0 710 562 ;
-C 166 ; WX 600 ; N florin ; B -57 -131 702 616 ;
-C 167 ; WX 600 ; N section ; B 74 -70 620 580 ;
-C 168 ; WX 600 ; N currency ; B 77 49 644 517 ;
-C 169 ; WX 600 ; N quotesingle ; B 303 277 493 562 ;
-C 170 ; WX 600 ; N quotedblleft ; B 190 277 594 562 ;
-C 171 ; WX 600 ; N guillemotleft ; B 62 70 639 446 ;
-C 172 ; WX 600 ; N guilsinglleft ; B 195 70 545 446 ;
-C 173 ; WX 600 ; N guilsinglright ; B 165 70 514 446 ;
-C 174 ; WX 600 ; N fi ; B 12 0 644 626 ;
-C 175 ; WX 600 ; N fl ; B 12 0 644 626 ;
-C 177 ; WX 600 ; N endash ; B 108 203 602 313 ;
-C 178 ; WX 600 ; N dagger ; B 175 -70 586 580 ;
-C 179 ; WX 600 ; N daggerdbl ; B 121 -70 587 580 ;
-C 180 ; WX 600 ; N periodcentered ; B 248 165 461 351 ;
-C 182 ; WX 600 ; N paragraph ; B 61 -70 700 580 ;
-C 183 ; WX 600 ; N bullet ; B 196 132 523 430 ;
-C 184 ; WX 600 ; N quotesinglbase ; B 144 -142 458 143 ;
-C 185 ; WX 600 ; N quotedblbase ; B 34 -142 560 143 ;
-C 186 ; WX 600 ; N quotedblright ; B 119 277 645 562 ;
-C 187 ; WX 600 ; N guillemotright ; B 71 70 647 446 ;
-C 188 ; WX 600 ; N ellipsis ; B 35 -15 587 116 ;
-C 189 ; WX 600 ; N perthousand ; B -45 -15 743 616 ;
-C 191 ; WX 600 ; N questiondown ; B 100 -146 509 449 ;
-C 193 ; WX 600 ; N grave ; B 272 508 503 661 ;
-C 194 ; WX 600 ; N acute ; B 312 508 609 661 ;
-C 195 ; WX 600 ; N circumflex ; B 212 483 607 657 ;
-C 196 ; WX 600 ; N tilde ; B 199 493 643 636 ;
-C 197 ; WX 600 ; N macron ; B 195 505 637 585 ;
-C 198 ; WX 600 ; N breve ; B 217 468 652 631 ;
-C 199 ; WX 600 ; N dotaccent ; B 348 498 493 638 ;
-C 200 ; WX 600 ; N dieresis ; B 246 498 595 638 ;
-C 202 ; WX 600 ; N ring ; B 319 481 528 678 ;
-C 203 ; WX 600 ; N cedilla ; B 168 -206 368 0 ;
-C 205 ; WX 600 ; N hungarumlaut ; B 171 488 729 661 ;
-C 206 ; WX 600 ; N ogonek ; B 143 -199 367 0 ;
-C 207 ; WX 600 ; N caron ; B 238 493 633 667 ;
-C 208 ; WX 600 ; N emdash ; B 33 203 677 313 ;
-C 225 ; WX 600 ; N AE ; B -29 0 708 562 ;
-C 227 ; WX 600 ; N ordfeminine ; B 188 196 526 580 ;
-C 232 ; WX 600 ; N Lslash ; B 39 0 636 562 ;
-C 233 ; WX 600 ; N Oslash ; B 48 -22 673 584 ;
-C 234 ; WX 600 ; N OE ; B 26 0 701 562 ;
-C 235 ; WX 600 ; N ordmasculine ; B 188 196 543 580 ;
-C 241 ; WX 600 ; N ae ; B 21 -15 652 454 ;
-C 245 ; WX 600 ; N dotlessi ; B 77 0 546 439 ;
-C 248 ; WX 600 ; N lslash ; B 77 0 587 626 ;
-C 249 ; WX 600 ; N oslash ; B 54 -24 638 463 ;
-C 250 ; WX 600 ; N oe ; B 18 -15 662 454 ;
-C 251 ; WX 600 ; N germandbls ; B 22 -15 629 626 ;
-C -1 ; WX 600 ; N Idieresis ; B 77 0 643 761 ;
-C -1 ; WX 600 ; N eacute ; B 81 -15 609 661 ;
-C -1 ; WX 600 ; N abreve ; B 61 -15 658 661 ;
-C -1 ; WX 600 ; N uhungarumlaut ; B 70 -15 769 661 ;
-C -1 ; WX 600 ; N ecaron ; B 81 -15 633 667 ;
-C -1 ; WX 600 ; N Ydieresis ; B 109 0 709 761 ;
-C -1 ; WX 600 ; N divide ; B 114 16 596 500 ;
-C -1 ; WX 600 ; N Yacute ; B 109 0 709 784 ;
-C -1 ; WX 600 ; N Acircumflex ; B -9 0 632 780 ;
-C -1 ; WX 600 ; N aacute ; B 61 -15 609 661 ;
-C -1 ; WX 600 ; N Ucircumflex ; B 101 -18 716 780 ;
-C -1 ; WX 600 ; N yacute ; B -21 -142 695 661 ;
-C -1 ; WX 600 ; N scommaaccent ; B 66 -250 608 459 ;
-C -1 ; WX 600 ; N ecircumflex ; B 81 -15 607 657 ;
-C -1 ; WX 600 ; N Uring ; B 101 -18 716 801 ;
-C -1 ; WX 600 ; N Udieresis ; B 101 -18 716 761 ;
-C -1 ; WX 600 ; N aogonek ; B 61 -199 593 454 ;
-C -1 ; WX 600 ; N Uacute ; B 101 -18 716 784 ;
-C -1 ; WX 600 ; N uogonek ; B 70 -199 592 439 ;
-C -1 ; WX 600 ; N Edieresis ; B 25 0 670 761 ;
-C -1 ; WX 600 ; N Dcroat ; B 30 0 664 562 ;
-C -1 ; WX 600 ; N commaaccent ; B 151 -250 385 -57 ;
-C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ;
-C -1 ; WX 600 ; N Emacron ; B 25 0 670 708 ;
-C -1 ; WX 600 ; N ccaron ; B 81 -15 633 667 ;
-C -1 ; WX 600 ; N aring ; B 61 -15 593 678 ;
-C -1 ; WX 600 ; N Ncommaaccent ; B 8 -250 730 562 ;
-C -1 ; WX 600 ; N lacute ; B 77 0 639 801 ;
-C -1 ; WX 600 ; N agrave ; B 61 -15 593 661 ;
-C -1 ; WX 600 ; N Tcommaaccent ; B 86 -250 679 562 ;
-C -1 ; WX 600 ; N Cacute ; B 74 -18 675 784 ;
-C -1 ; WX 600 ; N atilde ; B 61 -15 643 636 ;
-C -1 ; WX 600 ; N Edotaccent ; B 25 0 670 761 ;
-C -1 ; WX 600 ; N scaron ; B 66 -17 633 667 ;
-C -1 ; WX 600 ; N scedilla ; B 66 -206 608 459 ;
-C -1 ; WX 600 ; N iacute ; B 77 0 609 661 ;
-C -1 ; WX 600 ; N lozenge ; B 145 0 614 740 ;
-C -1 ; WX 600 ; N Rcaron ; B 24 0 659 790 ;
-C -1 ; WX 600 ; N Gcommaaccent ; B 74 -250 675 580 ;
-C -1 ; WX 600 ; N ucircumflex ; B 70 -15 597 657 ;
-C -1 ; WX 600 ; N acircumflex ; B 61 -15 607 657 ;
-C -1 ; WX 600 ; N Amacron ; B -9 0 633 708 ;
-C -1 ; WX 600 ; N rcaron ; B 47 0 655 667 ;
-C -1 ; WX 600 ; N ccedilla ; B 81 -206 631 459 ;
-C -1 ; WX 600 ; N Zdotaccent ; B 62 0 637 761 ;
-C -1 ; WX 600 ; N Thorn ; B 48 0 620 562 ;
-C -1 ; WX 600 ; N Omacron ; B 74 -18 663 708 ;
-C -1 ; WX 600 ; N Racute ; B 24 0 665 784 ;
-C -1 ; WX 600 ; N Sacute ; B 54 -22 673 784 ;
-C -1 ; WX 600 ; N dcaron ; B 60 -15 861 626 ;
-C -1 ; WX 600 ; N Umacron ; B 101 -18 716 708 ;
-C -1 ; WX 600 ; N uring ; B 70 -15 592 678 ;
-C -1 ; WX 600 ; N threesuperior ; B 193 222 526 616 ;
-C -1 ; WX 600 ; N Ograve ; B 74 -18 645 784 ;
-C -1 ; WX 600 ; N Agrave ; B -9 0 632 784 ;
-C -1 ; WX 600 ; N Abreve ; B -9 0 684 784 ;
-C -1 ; WX 600 ; N multiply ; B 104 39 606 478 ;
-C -1 ; WX 600 ; N uacute ; B 70 -15 599 661 ;
-C -1 ; WX 600 ; N Tcaron ; B 86 0 679 790 ;
-C -1 ; WX 600 ; N partialdiff ; B 91 -38 627 728 ;
-C -1 ; WX 600 ; N ydieresis ; B -21 -142 695 638 ;
-C -1 ; WX 600 ; N Nacute ; B 8 -12 730 784 ;
-C -1 ; WX 600 ; N icircumflex ; B 77 0 577 657 ;
-C -1 ; WX 600 ; N Ecircumflex ; B 25 0 670 780 ;
-C -1 ; WX 600 ; N adieresis ; B 61 -15 595 638 ;
-C -1 ; WX 600 ; N edieresis ; B 81 -15 605 638 ;
-C -1 ; WX 600 ; N cacute ; B 81 -15 649 661 ;
-C -1 ; WX 600 ; N nacute ; B 18 0 639 661 ;
-C -1 ; WX 600 ; N umacron ; B 70 -15 637 585 ;
-C -1 ; WX 600 ; N Ncaron ; B 8 -12 730 790 ;
-C -1 ; WX 600 ; N Iacute ; B 77 0 643 784 ;
-C -1 ; WX 600 ; N plusminus ; B 76 24 614 515 ;
-C -1 ; WX 600 ; N brokenbar ; B 217 -175 489 675 ;
-C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ;
-C -1 ; WX 600 ; N Gbreve ; B 74 -18 684 784 ;
-C -1 ; WX 600 ; N Idotaccent ; B 77 0 643 761 ;
-C -1 ; WX 600 ; N summation ; B 15 -10 672 706 ;
-C -1 ; WX 600 ; N Egrave ; B 25 0 670 784 ;
-C -1 ; WX 600 ; N racute ; B 47 0 655 661 ;
-C -1 ; WX 600 ; N omacron ; B 71 -15 637 585 ;
-C -1 ; WX 600 ; N Zacute ; B 62 0 665 784 ;
-C -1 ; WX 600 ; N Zcaron ; B 62 0 659 790 ;
-C -1 ; WX 600 ; N greaterequal ; B 26 0 627 696 ;
-C -1 ; WX 600 ; N Eth ; B 30 0 664 562 ;
-C -1 ; WX 600 ; N Ccedilla ; B 74 -206 675 580 ;
-C -1 ; WX 600 ; N lcommaaccent ; B 77 -250 546 626 ;
-C -1 ; WX 600 ; N tcaron ; B 118 -15 627 703 ;
-C -1 ; WX 600 ; N eogonek ; B 81 -199 605 454 ;
-C -1 ; WX 600 ; N Uogonek ; B 101 -199 716 562 ;
-C -1 ; WX 600 ; N Aacute ; B -9 0 655 784 ;
-C -1 ; WX 600 ; N Adieresis ; B -9 0 632 761 ;
-C -1 ; WX 600 ; N egrave ; B 81 -15 605 661 ;
-C -1 ; WX 600 ; N zacute ; B 81 0 614 661 ;
-C -1 ; WX 600 ; N iogonek ; B 77 -199 546 658 ;
-C -1 ; WX 600 ; N Oacute ; B 74 -18 645 784 ;
-C -1 ; WX 600 ; N oacute ; B 71 -15 649 661 ;
-C -1 ; WX 600 ; N amacron ; B 61 -15 637 585 ;
-C -1 ; WX 600 ; N sacute ; B 66 -17 609 661 ;
-C -1 ; WX 600 ; N idieresis ; B 77 0 561 618 ;
-C -1 ; WX 600 ; N Ocircumflex ; B 74 -18 645 780 ;
-C -1 ; WX 600 ; N Ugrave ; B 101 -18 716 784 ;
-C -1 ; WX 600 ; N Delta ; B 6 0 594 688 ;
-C -1 ; WX 600 ; N thorn ; B -32 -142 622 626 ;
-C -1 ; WX 600 ; N twosuperior ; B 191 230 542 616 ;
-C -1 ; WX 600 ; N Odieresis ; B 74 -18 645 761 ;
-C -1 ; WX 600 ; N mu ; B 49 -142 592 439 ;
-C -1 ; WX 600 ; N igrave ; B 77 0 546 661 ;
-C -1 ; WX 600 ; N ohungarumlaut ; B 71 -15 809 661 ;
-C -1 ; WX 600 ; N Eogonek ; B 25 -199 670 562 ;
-C -1 ; WX 600 ; N dcroat ; B 60 -15 712 626 ;
-C -1 ; WX 600 ; N threequarters ; B 8 -60 699 661 ;
-C -1 ; WX 600 ; N Scedilla ; B 54 -206 673 582 ;
-C -1 ; WX 600 ; N lcaron ; B 77 0 731 626 ;
-C -1 ; WX 600 ; N Kcommaaccent ; B 21 -250 692 562 ;
-C -1 ; WX 600 ; N Lacute ; B 39 0 636 784 ;
-C -1 ; WX 600 ; N trademark ; B 86 230 869 562 ;
-C -1 ; WX 600 ; N edotaccent ; B 81 -15 605 638 ;
-C -1 ; WX 600 ; N Igrave ; B 77 0 643 784 ;
-C -1 ; WX 600 ; N Imacron ; B 77 0 663 708 ;
-C -1 ; WX 600 ; N Lcaron ; B 39 0 757 562 ;
-C -1 ; WX 600 ; N onehalf ; B 22 -60 716 661 ;
-C -1 ; WX 600 ; N lessequal ; B 26 0 671 696 ;
-C -1 ; WX 600 ; N ocircumflex ; B 71 -15 622 657 ;
-C -1 ; WX 600 ; N ntilde ; B 18 0 643 636 ;
-C -1 ; WX 600 ; N Uhungarumlaut ; B 101 -18 805 784 ;
-C -1 ; WX 600 ; N Eacute ; B 25 0 670 784 ;
-C -1 ; WX 600 ; N emacron ; B 81 -15 637 585 ;
-C -1 ; WX 600 ; N gbreve ; B 40 -146 674 661 ;
-C -1 ; WX 600 ; N onequarter ; B 13 -60 707 661 ;
-C -1 ; WX 600 ; N Scaron ; B 54 -22 689 790 ;
-C -1 ; WX 600 ; N Scommaaccent ; B 54 -250 673 582 ;
-C -1 ; WX 600 ; N Ohungarumlaut ; B 74 -18 795 784 ;
-C -1 ; WX 600 ; N degree ; B 173 243 570 616 ;
-C -1 ; WX 600 ; N ograve ; B 71 -15 622 661 ;
-C -1 ; WX 600 ; N Ccaron ; B 74 -18 689 790 ;
-C -1 ; WX 600 ; N ugrave ; B 70 -15 592 661 ;
-C -1 ; WX 600 ; N radical ; B 67 -104 635 778 ;
-C -1 ; WX 600 ; N Dcaron ; B 30 0 664 790 ;
-C -1 ; WX 600 ; N rcommaaccent ; B 47 -250 655 454 ;
-C -1 ; WX 600 ; N Ntilde ; B 8 -12 730 759 ;
-C -1 ; WX 600 ; N otilde ; B 71 -15 643 636 ;
-C -1 ; WX 600 ; N Rcommaaccent ; B 24 -250 617 562 ;
-C -1 ; WX 600 ; N Lcommaaccent ; B 39 -250 636 562 ;
-C -1 ; WX 600 ; N Atilde ; B -9 0 669 759 ;
-C -1 ; WX 600 ; N Aogonek ; B -9 -199 632 562 ;
-C -1 ; WX 600 ; N Aring ; B -9 0 632 801 ;
-C -1 ; WX 600 ; N Otilde ; B 74 -18 669 759 ;
-C -1 ; WX 600 ; N zdotaccent ; B 81 0 614 638 ;
-C -1 ; WX 600 ; N Ecaron ; B 25 0 670 790 ;
-C -1 ; WX 600 ; N Iogonek ; B 77 -199 643 562 ;
-C -1 ; WX 600 ; N kcommaaccent ; B 33 -250 643 626 ;
-C -1 ; WX 600 ; N minus ; B 114 203 596 313 ;
-C -1 ; WX 600 ; N Icircumflex ; B 77 0 643 780 ;
-C -1 ; WX 600 ; N ncaron ; B 18 0 633 667 ;
-C -1 ; WX 600 ; N tcommaaccent ; B 118 -250 567 562 ;
-C -1 ; WX 600 ; N logicalnot ; B 135 103 617 413 ;
-C -1 ; WX 600 ; N odieresis ; B 71 -15 622 638 ;
-C -1 ; WX 600 ; N udieresis ; B 70 -15 595 638 ;
-C -1 ; WX 600 ; N notequal ; B 30 -47 626 563 ;
-C -1 ; WX 600 ; N gcommaaccent ; B 40 -146 674 714 ;
-C -1 ; WX 600 ; N eth ; B 93 -27 661 626 ;
-C -1 ; WX 600 ; N zcaron ; B 81 0 643 667 ;
-C -1 ; WX 600 ; N ncommaaccent ; B 18 -250 615 454 ;
-C -1 ; WX 600 ; N onesuperior ; B 212 230 514 616 ;
-C -1 ; WX 600 ; N imacron ; B 77 0 575 585 ;
-C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ;
-EndCharMetrics
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Oblique.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Oblique.afm
deleted file mode 100644
index 3dc163f771..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Oblique.afm
+++ /dev/null
@@ -1,342 +0,0 @@
-StartFontMetrics 4.1
-Comment Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Thu May 1 17:37:52 1997
-Comment UniqueID 43051
-Comment VMusage 16248 75829
-FontName Courier-Oblique
-FullName Courier Oblique
-FamilyName Courier
-Weight Medium
-ItalicAngle -12
-IsFixedPitch true
-CharacterSet ExtendedRoman
-FontBBox -27 -250 849 805
-UnderlinePosition -100
-UnderlineThickness 50
-Version 003.000
-Notice Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
-EncodingScheme AdobeStandardEncoding
-CapHeight 562
-XHeight 426
-Ascender 629
-Descender -157
-StdHW 51
-StdVW 51
-StartCharMetrics 315
-C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 600 ; N exclam ; B 243 -15 464 572 ;
-C 34 ; WX 600 ; N quotedbl ; B 273 328 532 562 ;
-C 35 ; WX 600 ; N numbersign ; B 133 -32 596 639 ;
-C 36 ; WX 600 ; N dollar ; B 108 -126 596 662 ;
-C 37 ; WX 600 ; N percent ; B 134 -15 599 622 ;
-C 38 ; WX 600 ; N ampersand ; B 87 -15 580 543 ;
-C 39 ; WX 600 ; N quoteright ; B 283 328 495 562 ;
-C 40 ; WX 600 ; N parenleft ; B 313 -108 572 622 ;
-C 41 ; WX 600 ; N parenright ; B 137 -108 396 622 ;
-C 42 ; WX 600 ; N asterisk ; B 212 257 580 607 ;
-C 43 ; WX 600 ; N plus ; B 129 44 580 470 ;
-C 44 ; WX 600 ; N comma ; B 157 -112 370 122 ;
-C 45 ; WX 600 ; N hyphen ; B 152 231 558 285 ;
-C 46 ; WX 600 ; N period ; B 238 -15 382 109 ;
-C 47 ; WX 600 ; N slash ; B 112 -80 604 629 ;
-C 48 ; WX 600 ; N zero ; B 154 -15 575 622 ;
-C 49 ; WX 600 ; N one ; B 98 0 515 622 ;
-C 50 ; WX 600 ; N two ; B 70 0 568 622 ;
-C 51 ; WX 600 ; N three ; B 82 -15 538 622 ;
-C 52 ; WX 600 ; N four ; B 108 0 541 622 ;
-C 53 ; WX 600 ; N five ; B 99 -15 589 607 ;
-C 54 ; WX 600 ; N six ; B 155 -15 629 622 ;
-C 55 ; WX 600 ; N seven ; B 182 0 612 607 ;
-C 56 ; WX 600 ; N eight ; B 132 -15 588 622 ;
-C 57 ; WX 600 ; N nine ; B 93 -15 574 622 ;
-C 58 ; WX 600 ; N colon ; B 238 -15 441 385 ;
-C 59 ; WX 600 ; N semicolon ; B 157 -112 441 385 ;
-C 60 ; WX 600 ; N less ; B 96 42 610 472 ;
-C 61 ; WX 600 ; N equal ; B 109 138 600 376 ;
-C 62 ; WX 600 ; N greater ; B 85 42 599 472 ;
-C 63 ; WX 600 ; N question ; B 222 -15 583 572 ;
-C 64 ; WX 600 ; N at ; B 127 -15 582 622 ;
-C 65 ; WX 600 ; N A ; B 3 0 607 562 ;
-C 66 ; WX 600 ; N B ; B 43 0 616 562 ;
-C 67 ; WX 600 ; N C ; B 93 -18 655 580 ;
-C 68 ; WX 600 ; N D ; B 43 0 645 562 ;
-C 69 ; WX 600 ; N E ; B 53 0 660 562 ;
-C 70 ; WX 600 ; N F ; B 53 0 660 562 ;
-C 71 ; WX 600 ; N G ; B 83 -18 645 580 ;
-C 72 ; WX 600 ; N H ; B 32 0 687 562 ;
-C 73 ; WX 600 ; N I ; B 96 0 623 562 ;
-C 74 ; WX 600 ; N J ; B 52 -18 685 562 ;
-C 75 ; WX 600 ; N K ; B 38 0 671 562 ;
-C 76 ; WX 600 ; N L ; B 47 0 607 562 ;
-C 77 ; WX 600 ; N M ; B 4 0 715 562 ;
-C 78 ; WX 600 ; N N ; B 7 -13 712 562 ;
-C 79 ; WX 600 ; N O ; B 94 -18 625 580 ;
-C 80 ; WX 600 ; N P ; B 79 0 644 562 ;
-C 81 ; WX 600 ; N Q ; B 95 -138 625 580 ;
-C 82 ; WX 600 ; N R ; B 38 0 598 562 ;
-C 83 ; WX 600 ; N S ; B 76 -20 650 580 ;
-C 84 ; WX 600 ; N T ; B 108 0 665 562 ;
-C 85 ; WX 600 ; N U ; B 125 -18 702 562 ;
-C 86 ; WX 600 ; N V ; B 105 -13 723 562 ;
-C 87 ; WX 600 ; N W ; B 106 -13 722 562 ;
-C 88 ; WX 600 ; N X ; B 23 0 675 562 ;
-C 89 ; WX 600 ; N Y ; B 133 0 695 562 ;
-C 90 ; WX 600 ; N Z ; B 86 0 610 562 ;
-C 91 ; WX 600 ; N bracketleft ; B 246 -108 574 622 ;
-C 92 ; WX 600 ; N backslash ; B 249 -80 468 629 ;
-C 93 ; WX 600 ; N bracketright ; B 135 -108 463 622 ;
-C 94 ; WX 600 ; N asciicircum ; B 175 354 587 622 ;
-C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ;
-C 96 ; WX 600 ; N quoteleft ; B 343 328 457 562 ;
-C 97 ; WX 600 ; N a ; B 76 -15 569 441 ;
-C 98 ; WX 600 ; N b ; B 29 -15 625 629 ;
-C 99 ; WX 600 ; N c ; B 106 -15 608 441 ;
-C 100 ; WX 600 ; N d ; B 85 -15 640 629 ;
-C 101 ; WX 600 ; N e ; B 106 -15 598 441 ;
-C 102 ; WX 600 ; N f ; B 114 0 662 629 ; L i fi ; L l fl ;
-C 103 ; WX 600 ; N g ; B 61 -157 657 441 ;
-C 104 ; WX 600 ; N h ; B 33 0 592 629 ;
-C 105 ; WX 600 ; N i ; B 95 0 515 657 ;
-C 106 ; WX 600 ; N j ; B 52 -157 550 657 ;
-C 107 ; WX 600 ; N k ; B 58 0 633 629 ;
-C 108 ; WX 600 ; N l ; B 95 0 515 629 ;
-C 109 ; WX 600 ; N m ; B -5 0 615 441 ;
-C 110 ; WX 600 ; N n ; B 26 0 585 441 ;
-C 111 ; WX 600 ; N o ; B 102 -15 588 441 ;
-C 112 ; WX 600 ; N p ; B -24 -157 605 441 ;
-C 113 ; WX 600 ; N q ; B 85 -157 682 441 ;
-C 114 ; WX 600 ; N r ; B 60 0 636 441 ;
-C 115 ; WX 600 ; N s ; B 78 -15 584 441 ;
-C 116 ; WX 600 ; N t ; B 167 -15 561 561 ;
-C 117 ; WX 600 ; N u ; B 101 -15 572 426 ;
-C 118 ; WX 600 ; N v ; B 90 -10 681 426 ;
-C 119 ; WX 600 ; N w ; B 76 -10 695 426 ;
-C 120 ; WX 600 ; N x ; B 20 0 655 426 ;
-C 121 ; WX 600 ; N y ; B -4 -157 683 426 ;
-C 122 ; WX 600 ; N z ; B 99 0 593 426 ;
-C 123 ; WX 600 ; N braceleft ; B 233 -108 569 622 ;
-C 124 ; WX 600 ; N bar ; B 222 -250 485 750 ;
-C 125 ; WX 600 ; N braceright ; B 140 -108 477 622 ;
-C 126 ; WX 600 ; N asciitilde ; B 116 197 600 320 ;
-C 161 ; WX 600 ; N exclamdown ; B 225 -157 445 430 ;
-C 162 ; WX 600 ; N cent ; B 151 -49 588 614 ;
-C 163 ; WX 600 ; N sterling ; B 124 -21 621 611 ;
-C 164 ; WX 600 ; N fraction ; B 84 -57 646 665 ;
-C 165 ; WX 600 ; N yen ; B 120 0 693 562 ;
-C 166 ; WX 600 ; N florin ; B -26 -143 671 622 ;
-C 167 ; WX 600 ; N section ; B 104 -78 590 580 ;
-C 168 ; WX 600 ; N currency ; B 94 58 628 506 ;
-C 169 ; WX 600 ; N quotesingle ; B 345 328 460 562 ;
-C 170 ; WX 600 ; N quotedblleft ; B 262 328 541 562 ;
-C 171 ; WX 600 ; N guillemotleft ; B 92 70 652 446 ;
-C 172 ; WX 600 ; N guilsinglleft ; B 204 70 540 446 ;
-C 173 ; WX 600 ; N guilsinglright ; B 170 70 506 446 ;
-C 174 ; WX 600 ; N fi ; B 3 0 619 629 ;
-C 175 ; WX 600 ; N fl ; B 3 0 619 629 ;
-C 177 ; WX 600 ; N endash ; B 124 231 586 285 ;
-C 178 ; WX 600 ; N dagger ; B 217 -78 546 580 ;
-C 179 ; WX 600 ; N daggerdbl ; B 163 -78 546 580 ;
-C 180 ; WX 600 ; N periodcentered ; B 275 189 434 327 ;
-C 182 ; WX 600 ; N paragraph ; B 100 -78 630 562 ;
-C 183 ; WX 600 ; N bullet ; B 224 130 485 383 ;
-C 184 ; WX 600 ; N quotesinglbase ; B 185 -134 397 100 ;
-C 185 ; WX 600 ; N quotedblbase ; B 115 -134 478 100 ;
-C 186 ; WX 600 ; N quotedblright ; B 213 328 576 562 ;
-C 187 ; WX 600 ; N guillemotright ; B 58 70 618 446 ;
-C 188 ; WX 600 ; N ellipsis ; B 46 -15 575 111 ;
-C 189 ; WX 600 ; N perthousand ; B 59 -15 627 622 ;
-C 191 ; WX 600 ; N questiondown ; B 105 -157 466 430 ;
-C 193 ; WX 600 ; N grave ; B 294 497 484 672 ;
-C 194 ; WX 600 ; N acute ; B 348 497 612 672 ;
-C 195 ; WX 600 ; N circumflex ; B 229 477 581 654 ;
-C 196 ; WX 600 ; N tilde ; B 212 489 629 606 ;
-C 197 ; WX 600 ; N macron ; B 232 525 600 565 ;
-C 198 ; WX 600 ; N breve ; B 279 501 576 609 ;
-C 199 ; WX 600 ; N dotaccent ; B 373 537 478 640 ;
-C 200 ; WX 600 ; N dieresis ; B 272 537 579 640 ;
-C 202 ; WX 600 ; N ring ; B 332 463 500 627 ;
-C 203 ; WX 600 ; N cedilla ; B 197 -151 344 10 ;
-C 205 ; WX 600 ; N hungarumlaut ; B 239 497 683 672 ;
-C 206 ; WX 600 ; N ogonek ; B 189 -172 377 4 ;
-C 207 ; WX 600 ; N caron ; B 262 492 614 669 ;
-C 208 ; WX 600 ; N emdash ; B 49 231 661 285 ;
-C 225 ; WX 600 ; N AE ; B 3 0 655 562 ;
-C 227 ; WX 600 ; N ordfeminine ; B 209 249 512 580 ;
-C 232 ; WX 600 ; N Lslash ; B 47 0 607 562 ;
-C 233 ; WX 600 ; N Oslash ; B 94 -80 625 629 ;
-C 234 ; WX 600 ; N OE ; B 59 0 672 562 ;
-C 235 ; WX 600 ; N ordmasculine ; B 210 249 535 580 ;
-C 241 ; WX 600 ; N ae ; B 41 -15 626 441 ;
-C 245 ; WX 600 ; N dotlessi ; B 95 0 515 426 ;
-C 248 ; WX 600 ; N lslash ; B 95 0 587 629 ;
-C 249 ; WX 600 ; N oslash ; B 102 -80 588 506 ;
-C 250 ; WX 600 ; N oe ; B 54 -15 615 441 ;
-C 251 ; WX 600 ; N germandbls ; B 48 -15 617 629 ;
-C -1 ; WX 600 ; N Idieresis ; B 96 0 623 753 ;
-C -1 ; WX 600 ; N eacute ; B 106 -15 612 672 ;
-C -1 ; WX 600 ; N abreve ; B 76 -15 576 609 ;
-C -1 ; WX 600 ; N uhungarumlaut ; B 101 -15 723 672 ;
-C -1 ; WX 600 ; N ecaron ; B 106 -15 614 669 ;
-C -1 ; WX 600 ; N Ydieresis ; B 133 0 695 753 ;
-C -1 ; WX 600 ; N divide ; B 136 48 573 467 ;
-C -1 ; WX 600 ; N Yacute ; B 133 0 695 805 ;
-C -1 ; WX 600 ; N Acircumflex ; B 3 0 607 787 ;
-C -1 ; WX 600 ; N aacute ; B 76 -15 612 672 ;
-C -1 ; WX 600 ; N Ucircumflex ; B 125 -18 702 787 ;
-C -1 ; WX 600 ; N yacute ; B -4 -157 683 672 ;
-C -1 ; WX 600 ; N scommaaccent ; B 78 -250 584 441 ;
-C -1 ; WX 600 ; N ecircumflex ; B 106 -15 598 654 ;
-C -1 ; WX 600 ; N Uring ; B 125 -18 702 760 ;
-C -1 ; WX 600 ; N Udieresis ; B 125 -18 702 753 ;
-C -1 ; WX 600 ; N aogonek ; B 76 -172 569 441 ;
-C -1 ; WX 600 ; N Uacute ; B 125 -18 702 805 ;
-C -1 ; WX 600 ; N uogonek ; B 101 -172 572 426 ;
-C -1 ; WX 600 ; N Edieresis ; B 53 0 660 753 ;
-C -1 ; WX 600 ; N Dcroat ; B 43 0 645 562 ;
-C -1 ; WX 600 ; N commaaccent ; B 145 -250 323 -58 ;
-C -1 ; WX 600 ; N copyright ; B 53 -18 667 580 ;
-C -1 ; WX 600 ; N Emacron ; B 53 0 660 698 ;
-C -1 ; WX 600 ; N ccaron ; B 106 -15 614 669 ;
-C -1 ; WX 600 ; N aring ; B 76 -15 569 627 ;
-C -1 ; WX 600 ; N Ncommaaccent ; B 7 -250 712 562 ;
-C -1 ; WX 600 ; N lacute ; B 95 0 640 805 ;
-C -1 ; WX 600 ; N agrave ; B 76 -15 569 672 ;
-C -1 ; WX 600 ; N Tcommaaccent ; B 108 -250 665 562 ;
-C -1 ; WX 600 ; N Cacute ; B 93 -18 655 805 ;
-C -1 ; WX 600 ; N atilde ; B 76 -15 629 606 ;
-C -1 ; WX 600 ; N Edotaccent ; B 53 0 660 753 ;
-C -1 ; WX 600 ; N scaron ; B 78 -15 614 669 ;
-C -1 ; WX 600 ; N scedilla ; B 78 -151 584 441 ;
-C -1 ; WX 600 ; N iacute ; B 95 0 612 672 ;
-C -1 ; WX 600 ; N lozenge ; B 94 0 519 706 ;
-C -1 ; WX 600 ; N Rcaron ; B 38 0 642 802 ;
-C -1 ; WX 600 ; N Gcommaaccent ; B 83 -250 645 580 ;
-C -1 ; WX 600 ; N ucircumflex ; B 101 -15 572 654 ;
-C -1 ; WX 600 ; N acircumflex ; B 76 -15 581 654 ;
-C -1 ; WX 600 ; N Amacron ; B 3 0 607 698 ;
-C -1 ; WX 600 ; N rcaron ; B 60 0 636 669 ;
-C -1 ; WX 600 ; N ccedilla ; B 106 -151 614 441 ;
-C -1 ; WX 600 ; N Zdotaccent ; B 86 0 610 753 ;
-C -1 ; WX 600 ; N Thorn ; B 79 0 606 562 ;
-C -1 ; WX 600 ; N Omacron ; B 94 -18 628 698 ;
-C -1 ; WX 600 ; N Racute ; B 38 0 670 805 ;
-C -1 ; WX 600 ; N Sacute ; B 76 -20 650 805 ;
-C -1 ; WX 600 ; N dcaron ; B 85 -15 849 629 ;
-C -1 ; WX 600 ; N Umacron ; B 125 -18 702 698 ;
-C -1 ; WX 600 ; N uring ; B 101 -15 572 627 ;
-C -1 ; WX 600 ; N threesuperior ; B 213 240 501 622 ;
-C -1 ; WX 600 ; N Ograve ; B 94 -18 625 805 ;
-C -1 ; WX 600 ; N Agrave ; B 3 0 607 805 ;
-C -1 ; WX 600 ; N Abreve ; B 3 0 607 732 ;
-C -1 ; WX 600 ; N multiply ; B 103 43 607 470 ;
-C -1 ; WX 600 ; N uacute ; B 101 -15 602 672 ;
-C -1 ; WX 600 ; N Tcaron ; B 108 0 665 802 ;
-C -1 ; WX 600 ; N partialdiff ; B 45 -38 546 710 ;
-C -1 ; WX 600 ; N ydieresis ; B -4 -157 683 620 ;
-C -1 ; WX 600 ; N Nacute ; B 7 -13 712 805 ;
-C -1 ; WX 600 ; N icircumflex ; B 95 0 551 654 ;
-C -1 ; WX 600 ; N Ecircumflex ; B 53 0 660 787 ;
-C -1 ; WX 600 ; N adieresis ; B 76 -15 575 620 ;
-C -1 ; WX 600 ; N edieresis ; B 106 -15 598 620 ;
-C -1 ; WX 600 ; N cacute ; B 106 -15 612 672 ;
-C -1 ; WX 600 ; N nacute ; B 26 0 602 672 ;
-C -1 ; WX 600 ; N umacron ; B 101 -15 600 565 ;
-C -1 ; WX 600 ; N Ncaron ; B 7 -13 712 802 ;
-C -1 ; WX 600 ; N Iacute ; B 96 0 640 805 ;
-C -1 ; WX 600 ; N plusminus ; B 96 44 594 558 ;
-C -1 ; WX 600 ; N brokenbar ; B 238 -175 469 675 ;
-C -1 ; WX 600 ; N registered ; B 53 -18 667 580 ;
-C -1 ; WX 600 ; N Gbreve ; B 83 -18 645 732 ;
-C -1 ; WX 600 ; N Idotaccent ; B 96 0 623 753 ;
-C -1 ; WX 600 ; N summation ; B 15 -10 670 706 ;
-C -1 ; WX 600 ; N Egrave ; B 53 0 660 805 ;
-C -1 ; WX 600 ; N racute ; B 60 0 636 672 ;
-C -1 ; WX 600 ; N omacron ; B 102 -15 600 565 ;
-C -1 ; WX 600 ; N Zacute ; B 86 0 670 805 ;
-C -1 ; WX 600 ; N Zcaron ; B 86 0 642 802 ;
-C -1 ; WX 600 ; N greaterequal ; B 98 0 594 710 ;
-C -1 ; WX 600 ; N Eth ; B 43 0 645 562 ;
-C -1 ; WX 600 ; N Ccedilla ; B 93 -151 658 580 ;
-C -1 ; WX 600 ; N lcommaaccent ; B 95 -250 515 629 ;
-C -1 ; WX 600 ; N tcaron ; B 167 -15 587 717 ;
-C -1 ; WX 600 ; N eogonek ; B 106 -172 598 441 ;
-C -1 ; WX 600 ; N Uogonek ; B 124 -172 702 562 ;
-C -1 ; WX 600 ; N Aacute ; B 3 0 660 805 ;
-C -1 ; WX 600 ; N Adieresis ; B 3 0 607 753 ;
-C -1 ; WX 600 ; N egrave ; B 106 -15 598 672 ;
-C -1 ; WX 600 ; N zacute ; B 99 0 612 672 ;
-C -1 ; WX 600 ; N iogonek ; B 95 -172 515 657 ;
-C -1 ; WX 600 ; N Oacute ; B 94 -18 640 805 ;
-C -1 ; WX 600 ; N oacute ; B 102 -15 612 672 ;
-C -1 ; WX 600 ; N amacron ; B 76 -15 600 565 ;
-C -1 ; WX 600 ; N sacute ; B 78 -15 612 672 ;
-C -1 ; WX 600 ; N idieresis ; B 95 0 545 620 ;
-C -1 ; WX 600 ; N Ocircumflex ; B 94 -18 625 787 ;
-C -1 ; WX 600 ; N Ugrave ; B 125 -18 702 805 ;
-C -1 ; WX 600 ; N Delta ; B 6 0 598 688 ;
-C -1 ; WX 600 ; N thorn ; B -24 -157 605 629 ;
-C -1 ; WX 600 ; N twosuperior ; B 230 249 535 622 ;
-C -1 ; WX 600 ; N Odieresis ; B 94 -18 625 753 ;
-C -1 ; WX 600 ; N mu ; B 72 -157 572 426 ;
-C -1 ; WX 600 ; N igrave ; B 95 0 515 672 ;
-C -1 ; WX 600 ; N ohungarumlaut ; B 102 -15 723 672 ;
-C -1 ; WX 600 ; N Eogonek ; B 53 -172 660 562 ;
-C -1 ; WX 600 ; N dcroat ; B 85 -15 704 629 ;
-C -1 ; WX 600 ; N threequarters ; B 73 -56 659 666 ;
-C -1 ; WX 600 ; N Scedilla ; B 76 -151 650 580 ;
-C -1 ; WX 600 ; N lcaron ; B 95 0 667 629 ;
-C -1 ; WX 600 ; N Kcommaaccent ; B 38 -250 671 562 ;
-C -1 ; WX 600 ; N Lacute ; B 47 0 607 805 ;
-C -1 ; WX 600 ; N trademark ; B 75 263 742 562 ;
-C -1 ; WX 600 ; N edotaccent ; B 106 -15 598 620 ;
-C -1 ; WX 600 ; N Igrave ; B 96 0 623 805 ;
-C -1 ; WX 600 ; N Imacron ; B 96 0 628 698 ;
-C -1 ; WX 600 ; N Lcaron ; B 47 0 632 562 ;
-C -1 ; WX 600 ; N onehalf ; B 65 -57 669 665 ;
-C -1 ; WX 600 ; N lessequal ; B 98 0 645 710 ;
-C -1 ; WX 600 ; N ocircumflex ; B 102 -15 588 654 ;
-C -1 ; WX 600 ; N ntilde ; B 26 0 629 606 ;
-C -1 ; WX 600 ; N Uhungarumlaut ; B 125 -18 761 805 ;
-C -1 ; WX 600 ; N Eacute ; B 53 0 670 805 ;
-C -1 ; WX 600 ; N emacron ; B 106 -15 600 565 ;
-C -1 ; WX 600 ; N gbreve ; B 61 -157 657 609 ;
-C -1 ; WX 600 ; N onequarter ; B 65 -57 674 665 ;
-C -1 ; WX 600 ; N Scaron ; B 76 -20 672 802 ;
-C -1 ; WX 600 ; N Scommaaccent ; B 76 -250 650 580 ;
-C -1 ; WX 600 ; N Ohungarumlaut ; B 94 -18 751 805 ;
-C -1 ; WX 600 ; N degree ; B 214 269 576 622 ;
-C -1 ; WX 600 ; N ograve ; B 102 -15 588 672 ;
-C -1 ; WX 600 ; N Ccaron ; B 93 -18 672 802 ;
-C -1 ; WX 600 ; N ugrave ; B 101 -15 572 672 ;
-C -1 ; WX 600 ; N radical ; B 85 -15 765 792 ;
-C -1 ; WX 600 ; N Dcaron ; B 43 0 645 802 ;
-C -1 ; WX 600 ; N rcommaaccent ; B 60 -250 636 441 ;
-C -1 ; WX 600 ; N Ntilde ; B 7 -13 712 729 ;
-C -1 ; WX 600 ; N otilde ; B 102 -15 629 606 ;
-C -1 ; WX 600 ; N Rcommaaccent ; B 38 -250 598 562 ;
-C -1 ; WX 600 ; N Lcommaaccent ; B 47 -250 607 562 ;
-C -1 ; WX 600 ; N Atilde ; B 3 0 655 729 ;
-C -1 ; WX 600 ; N Aogonek ; B 3 -172 607 562 ;
-C -1 ; WX 600 ; N Aring ; B 3 0 607 750 ;
-C -1 ; WX 600 ; N Otilde ; B 94 -18 655 729 ;
-C -1 ; WX 600 ; N zdotaccent ; B 99 0 593 620 ;
-C -1 ; WX 600 ; N Ecaron ; B 53 0 660 802 ;
-C -1 ; WX 600 ; N Iogonek ; B 96 -172 623 562 ;
-C -1 ; WX 600 ; N kcommaaccent ; B 58 -250 633 629 ;
-C -1 ; WX 600 ; N minus ; B 129 232 580 283 ;
-C -1 ; WX 600 ; N Icircumflex ; B 96 0 623 787 ;
-C -1 ; WX 600 ; N ncaron ; B 26 0 614 669 ;
-C -1 ; WX 600 ; N tcommaaccent ; B 165 -250 561 561 ;
-C -1 ; WX 600 ; N logicalnot ; B 155 108 591 369 ;
-C -1 ; WX 600 ; N odieresis ; B 102 -15 588 620 ;
-C -1 ; WX 600 ; N udieresis ; B 101 -15 575 620 ;
-C -1 ; WX 600 ; N notequal ; B 43 -16 621 529 ;
-C -1 ; WX 600 ; N gcommaaccent ; B 61 -157 657 708 ;
-C -1 ; WX 600 ; N eth ; B 102 -15 639 629 ;
-C -1 ; WX 600 ; N zcaron ; B 99 0 624 669 ;
-C -1 ; WX 600 ; N ncommaaccent ; B 26 -250 585 441 ;
-C -1 ; WX 600 ; N onesuperior ; B 231 249 491 622 ;
-C -1 ; WX 600 ; N imacron ; B 95 0 543 565 ;
-C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ;
-EndCharMetrics
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Courier.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Courier.afm
deleted file mode 100644
index 2f7be81d58..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Courier.afm
+++ /dev/null
@@ -1,342 +0,0 @@
-StartFontMetrics 4.1
-Comment Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Thu May 1 17:27:09 1997
-Comment UniqueID 43050
-Comment VMusage 39754 50779
-FontName Courier
-FullName Courier
-FamilyName Courier
-Weight Medium
-ItalicAngle 0
-IsFixedPitch true
-CharacterSet ExtendedRoman
-FontBBox -23 -250 715 805
-UnderlinePosition -100
-UnderlineThickness 50
-Version 003.000
-Notice Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
-EncodingScheme AdobeStandardEncoding
-CapHeight 562
-XHeight 426
-Ascender 629
-Descender -157
-StdHW 51
-StdVW 51
-StartCharMetrics 315
-C 32 ; WX 600 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 600 ; N exclam ; B 236 -15 364 572 ;
-C 34 ; WX 600 ; N quotedbl ; B 187 328 413 562 ;
-C 35 ; WX 600 ; N numbersign ; B 93 -32 507 639 ;
-C 36 ; WX 600 ; N dollar ; B 105 -126 496 662 ;
-C 37 ; WX 600 ; N percent ; B 81 -15 518 622 ;
-C 38 ; WX 600 ; N ampersand ; B 63 -15 538 543 ;
-C 39 ; WX 600 ; N quoteright ; B 213 328 376 562 ;
-C 40 ; WX 600 ; N parenleft ; B 269 -108 440 622 ;
-C 41 ; WX 600 ; N parenright ; B 160 -108 331 622 ;
-C 42 ; WX 600 ; N asterisk ; B 116 257 484 607 ;
-C 43 ; WX 600 ; N plus ; B 80 44 520 470 ;
-C 44 ; WX 600 ; N comma ; B 181 -112 344 122 ;
-C 45 ; WX 600 ; N hyphen ; B 103 231 497 285 ;
-C 46 ; WX 600 ; N period ; B 229 -15 371 109 ;
-C 47 ; WX 600 ; N slash ; B 125 -80 475 629 ;
-C 48 ; WX 600 ; N zero ; B 106 -15 494 622 ;
-C 49 ; WX 600 ; N one ; B 96 0 505 622 ;
-C 50 ; WX 600 ; N two ; B 70 0 471 622 ;
-C 51 ; WX 600 ; N three ; B 75 -15 466 622 ;
-C 52 ; WX 600 ; N four ; B 78 0 500 622 ;
-C 53 ; WX 600 ; N five ; B 92 -15 497 607 ;
-C 54 ; WX 600 ; N six ; B 111 -15 497 622 ;
-C 55 ; WX 600 ; N seven ; B 82 0 483 607 ;
-C 56 ; WX 600 ; N eight ; B 102 -15 498 622 ;
-C 57 ; WX 600 ; N nine ; B 96 -15 489 622 ;
-C 58 ; WX 600 ; N colon ; B 229 -15 371 385 ;
-C 59 ; WX 600 ; N semicolon ; B 181 -112 371 385 ;
-C 60 ; WX 600 ; N less ; B 41 42 519 472 ;
-C 61 ; WX 600 ; N equal ; B 80 138 520 376 ;
-C 62 ; WX 600 ; N greater ; B 66 42 544 472 ;
-C 63 ; WX 600 ; N question ; B 129 -15 492 572 ;
-C 64 ; WX 600 ; N at ; B 77 -15 533 622 ;
-C 65 ; WX 600 ; N A ; B 3 0 597 562 ;
-C 66 ; WX 600 ; N B ; B 43 0 559 562 ;
-C 67 ; WX 600 ; N C ; B 41 -18 540 580 ;
-C 68 ; WX 600 ; N D ; B 43 0 574 562 ;
-C 69 ; WX 600 ; N E ; B 53 0 550 562 ;
-C 70 ; WX 600 ; N F ; B 53 0 545 562 ;
-C 71 ; WX 600 ; N G ; B 31 -18 575 580 ;
-C 72 ; WX 600 ; N H ; B 32 0 568 562 ;
-C 73 ; WX 600 ; N I ; B 96 0 504 562 ;
-C 74 ; WX 600 ; N J ; B 34 -18 566 562 ;
-C 75 ; WX 600 ; N K ; B 38 0 582 562 ;
-C 76 ; WX 600 ; N L ; B 47 0 554 562 ;
-C 77 ; WX 600 ; N M ; B 4 0 596 562 ;
-C 78 ; WX 600 ; N N ; B 7 -13 593 562 ;
-C 79 ; WX 600 ; N O ; B 43 -18 557 580 ;
-C 80 ; WX 600 ; N P ; B 79 0 558 562 ;
-C 81 ; WX 600 ; N Q ; B 43 -138 557 580 ;
-C 82 ; WX 600 ; N R ; B 38 0 588 562 ;
-C 83 ; WX 600 ; N S ; B 72 -20 529 580 ;
-C 84 ; WX 600 ; N T ; B 38 0 563 562 ;
-C 85 ; WX 600 ; N U ; B 17 -18 583 562 ;
-C 86 ; WX 600 ; N V ; B -4 -13 604 562 ;
-C 87 ; WX 600 ; N W ; B -3 -13 603 562 ;
-C 88 ; WX 600 ; N X ; B 23 0 577 562 ;
-C 89 ; WX 600 ; N Y ; B 24 0 576 562 ;
-C 90 ; WX 600 ; N Z ; B 86 0 514 562 ;
-C 91 ; WX 600 ; N bracketleft ; B 269 -108 442 622 ;
-C 92 ; WX 600 ; N backslash ; B 118 -80 482 629 ;
-C 93 ; WX 600 ; N bracketright ; B 158 -108 331 622 ;
-C 94 ; WX 600 ; N asciicircum ; B 94 354 506 622 ;
-C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ;
-C 96 ; WX 600 ; N quoteleft ; B 224 328 387 562 ;
-C 97 ; WX 600 ; N a ; B 53 -15 559 441 ;
-C 98 ; WX 600 ; N b ; B 14 -15 575 629 ;
-C 99 ; WX 600 ; N c ; B 66 -15 529 441 ;
-C 100 ; WX 600 ; N d ; B 45 -15 591 629 ;
-C 101 ; WX 600 ; N e ; B 66 -15 548 441 ;
-C 102 ; WX 600 ; N f ; B 114 0 531 629 ; L i fi ; L l fl ;
-C 103 ; WX 600 ; N g ; B 45 -157 566 441 ;
-C 104 ; WX 600 ; N h ; B 18 0 582 629 ;
-C 105 ; WX 600 ; N i ; B 95 0 505 657 ;
-C 106 ; WX 600 ; N j ; B 82 -157 410 657 ;
-C 107 ; WX 600 ; N k ; B 43 0 580 629 ;
-C 108 ; WX 600 ; N l ; B 95 0 505 629 ;
-C 109 ; WX 600 ; N m ; B -5 0 605 441 ;
-C 110 ; WX 600 ; N n ; B 26 0 575 441 ;
-C 111 ; WX 600 ; N o ; B 62 -15 538 441 ;
-C 112 ; WX 600 ; N p ; B 9 -157 555 441 ;
-C 113 ; WX 600 ; N q ; B 45 -157 591 441 ;
-C 114 ; WX 600 ; N r ; B 60 0 559 441 ;
-C 115 ; WX 600 ; N s ; B 80 -15 513 441 ;
-C 116 ; WX 600 ; N t ; B 87 -15 530 561 ;
-C 117 ; WX 600 ; N u ; B 21 -15 562 426 ;
-C 118 ; WX 600 ; N v ; B 10 -10 590 426 ;
-C 119 ; WX 600 ; N w ; B -4 -10 604 426 ;
-C 120 ; WX 600 ; N x ; B 20 0 580 426 ;
-C 121 ; WX 600 ; N y ; B 7 -157 592 426 ;
-C 122 ; WX 600 ; N z ; B 99 0 502 426 ;
-C 123 ; WX 600 ; N braceleft ; B 182 -108 437 622 ;
-C 124 ; WX 600 ; N bar ; B 275 -250 326 750 ;
-C 125 ; WX 600 ; N braceright ; B 163 -108 418 622 ;
-C 126 ; WX 600 ; N asciitilde ; B 63 197 540 320 ;
-C 161 ; WX 600 ; N exclamdown ; B 236 -157 364 430 ;
-C 162 ; WX 600 ; N cent ; B 96 -49 500 614 ;
-C 163 ; WX 600 ; N sterling ; B 84 -21 521 611 ;
-C 164 ; WX 600 ; N fraction ; B 92 -57 509 665 ;
-C 165 ; WX 600 ; N yen ; B 26 0 574 562 ;
-C 166 ; WX 600 ; N florin ; B 4 -143 539 622 ;
-C 167 ; WX 600 ; N section ; B 113 -78 488 580 ;
-C 168 ; WX 600 ; N currency ; B 73 58 527 506 ;
-C 169 ; WX 600 ; N quotesingle ; B 259 328 341 562 ;
-C 170 ; WX 600 ; N quotedblleft ; B 143 328 471 562 ;
-C 171 ; WX 600 ; N guillemotleft ; B 37 70 563 446 ;
-C 172 ; WX 600 ; N guilsinglleft ; B 149 70 451 446 ;
-C 173 ; WX 600 ; N guilsinglright ; B 149 70 451 446 ;
-C 174 ; WX 600 ; N fi ; B 3 0 597 629 ;
-C 175 ; WX 600 ; N fl ; B 3 0 597 629 ;
-C 177 ; WX 600 ; N endash ; B 75 231 525 285 ;
-C 178 ; WX 600 ; N dagger ; B 141 -78 459 580 ;
-C 179 ; WX 600 ; N daggerdbl ; B 141 -78 459 580 ;
-C 180 ; WX 600 ; N periodcentered ; B 222 189 378 327 ;
-C 182 ; WX 600 ; N paragraph ; B 50 -78 511 562 ;
-C 183 ; WX 600 ; N bullet ; B 172 130 428 383 ;
-C 184 ; WX 600 ; N quotesinglbase ; B 213 -134 376 100 ;
-C 185 ; WX 600 ; N quotedblbase ; B 143 -134 457 100 ;
-C 186 ; WX 600 ; N quotedblright ; B 143 328 457 562 ;
-C 187 ; WX 600 ; N guillemotright ; B 37 70 563 446 ;
-C 188 ; WX 600 ; N ellipsis ; B 37 -15 563 111 ;
-C 189 ; WX 600 ; N perthousand ; B 3 -15 600 622 ;
-C 191 ; WX 600 ; N questiondown ; B 108 -157 471 430 ;
-C 193 ; WX 600 ; N grave ; B 151 497 378 672 ;
-C 194 ; WX 600 ; N acute ; B 242 497 469 672 ;
-C 195 ; WX 600 ; N circumflex ; B 124 477 476 654 ;
-C 196 ; WX 600 ; N tilde ; B 105 489 503 606 ;
-C 197 ; WX 600 ; N macron ; B 120 525 480 565 ;
-C 198 ; WX 600 ; N breve ; B 153 501 447 609 ;
-C 199 ; WX 600 ; N dotaccent ; B 249 537 352 640 ;
-C 200 ; WX 600 ; N dieresis ; B 148 537 453 640 ;
-C 202 ; WX 600 ; N ring ; B 218 463 382 627 ;
-C 203 ; WX 600 ; N cedilla ; B 224 -151 362 10 ;
-C 205 ; WX 600 ; N hungarumlaut ; B 133 497 540 672 ;
-C 206 ; WX 600 ; N ogonek ; B 211 -172 407 4 ;
-C 207 ; WX 600 ; N caron ; B 124 492 476 669 ;
-C 208 ; WX 600 ; N emdash ; B 0 231 600 285 ;
-C 225 ; WX 600 ; N AE ; B 3 0 550 562 ;
-C 227 ; WX 600 ; N ordfeminine ; B 156 249 442 580 ;
-C 232 ; WX 600 ; N Lslash ; B 47 0 554 562 ;
-C 233 ; WX 600 ; N Oslash ; B 43 -80 557 629 ;
-C 234 ; WX 600 ; N OE ; B 7 0 567 562 ;
-C 235 ; WX 600 ; N ordmasculine ; B 157 249 443 580 ;
-C 241 ; WX 600 ; N ae ; B 19 -15 570 441 ;
-C 245 ; WX 600 ; N dotlessi ; B 95 0 505 426 ;
-C 248 ; WX 600 ; N lslash ; B 95 0 505 629 ;
-C 249 ; WX 600 ; N oslash ; B 62 -80 538 506 ;
-C 250 ; WX 600 ; N oe ; B 19 -15 559 441 ;
-C 251 ; WX 600 ; N germandbls ; B 48 -15 588 629 ;
-C -1 ; WX 600 ; N Idieresis ; B 96 0 504 753 ;
-C -1 ; WX 600 ; N eacute ; B 66 -15 548 672 ;
-C -1 ; WX 600 ; N abreve ; B 53 -15 559 609 ;
-C -1 ; WX 600 ; N uhungarumlaut ; B 21 -15 580 672 ;
-C -1 ; WX 600 ; N ecaron ; B 66 -15 548 669 ;
-C -1 ; WX 600 ; N Ydieresis ; B 24 0 576 753 ;
-C -1 ; WX 600 ; N divide ; B 87 48 513 467 ;
-C -1 ; WX 600 ; N Yacute ; B 24 0 576 805 ;
-C -1 ; WX 600 ; N Acircumflex ; B 3 0 597 787 ;
-C -1 ; WX 600 ; N aacute ; B 53 -15 559 672 ;
-C -1 ; WX 600 ; N Ucircumflex ; B 17 -18 583 787 ;
-C -1 ; WX 600 ; N yacute ; B 7 -157 592 672 ;
-C -1 ; WX 600 ; N scommaaccent ; B 80 -250 513 441 ;
-C -1 ; WX 600 ; N ecircumflex ; B 66 -15 548 654 ;
-C -1 ; WX 600 ; N Uring ; B 17 -18 583 760 ;
-C -1 ; WX 600 ; N Udieresis ; B 17 -18 583 753 ;
-C -1 ; WX 600 ; N aogonek ; B 53 -172 587 441 ;
-C -1 ; WX 600 ; N Uacute ; B 17 -18 583 805 ;
-C -1 ; WX 600 ; N uogonek ; B 21 -172 590 426 ;
-C -1 ; WX 600 ; N Edieresis ; B 53 0 550 753 ;
-C -1 ; WX 600 ; N Dcroat ; B 30 0 574 562 ;
-C -1 ; WX 600 ; N commaaccent ; B 198 -250 335 -58 ;
-C -1 ; WX 600 ; N copyright ; B 0 -18 600 580 ;
-C -1 ; WX 600 ; N Emacron ; B 53 0 550 698 ;
-C -1 ; WX 600 ; N ccaron ; B 66 -15 529 669 ;
-C -1 ; WX 600 ; N aring ; B 53 -15 559 627 ;
-C -1 ; WX 600 ; N Ncommaaccent ; B 7 -250 593 562 ;
-C -1 ; WX 600 ; N lacute ; B 95 0 505 805 ;
-C -1 ; WX 600 ; N agrave ; B 53 -15 559 672 ;
-C -1 ; WX 600 ; N Tcommaaccent ; B 38 -250 563 562 ;
-C -1 ; WX 600 ; N Cacute ; B 41 -18 540 805 ;
-C -1 ; WX 600 ; N atilde ; B 53 -15 559 606 ;
-C -1 ; WX 600 ; N Edotaccent ; B 53 0 550 753 ;
-C -1 ; WX 600 ; N scaron ; B 80 -15 513 669 ;
-C -1 ; WX 600 ; N scedilla ; B 80 -151 513 441 ;
-C -1 ; WX 600 ; N iacute ; B 95 0 505 672 ;
-C -1 ; WX 600 ; N lozenge ; B 18 0 443 706 ;
-C -1 ; WX 600 ; N Rcaron ; B 38 0 588 802 ;
-C -1 ; WX 600 ; N Gcommaaccent ; B 31 -250 575 580 ;
-C -1 ; WX 600 ; N ucircumflex ; B 21 -15 562 654 ;
-C -1 ; WX 600 ; N acircumflex ; B 53 -15 559 654 ;
-C -1 ; WX 600 ; N Amacron ; B 3 0 597 698 ;
-C -1 ; WX 600 ; N rcaron ; B 60 0 559 669 ;
-C -1 ; WX 600 ; N ccedilla ; B 66 -151 529 441 ;
-C -1 ; WX 600 ; N Zdotaccent ; B 86 0 514 753 ;
-C -1 ; WX 600 ; N Thorn ; B 79 0 538 562 ;
-C -1 ; WX 600 ; N Omacron ; B 43 -18 557 698 ;
-C -1 ; WX 600 ; N Racute ; B 38 0 588 805 ;
-C -1 ; WX 600 ; N Sacute ; B 72 -20 529 805 ;
-C -1 ; WX 600 ; N dcaron ; B 45 -15 715 629 ;
-C -1 ; WX 600 ; N Umacron ; B 17 -18 583 698 ;
-C -1 ; WX 600 ; N uring ; B 21 -15 562 627 ;
-C -1 ; WX 600 ; N threesuperior ; B 155 240 406 622 ;
-C -1 ; WX 600 ; N Ograve ; B 43 -18 557 805 ;
-C -1 ; WX 600 ; N Agrave ; B 3 0 597 805 ;
-C -1 ; WX 600 ; N Abreve ; B 3 0 597 732 ;
-C -1 ; WX 600 ; N multiply ; B 87 43 515 470 ;
-C -1 ; WX 600 ; N uacute ; B 21 -15 562 672 ;
-C -1 ; WX 600 ; N Tcaron ; B 38 0 563 802 ;
-C -1 ; WX 600 ; N partialdiff ; B 17 -38 459 710 ;
-C -1 ; WX 600 ; N ydieresis ; B 7 -157 592 620 ;
-C -1 ; WX 600 ; N Nacute ; B 7 -13 593 805 ;
-C -1 ; WX 600 ; N icircumflex ; B 94 0 505 654 ;
-C -1 ; WX 600 ; N Ecircumflex ; B 53 0 550 787 ;
-C -1 ; WX 600 ; N adieresis ; B 53 -15 559 620 ;
-C -1 ; WX 600 ; N edieresis ; B 66 -15 548 620 ;
-C -1 ; WX 600 ; N cacute ; B 66 -15 529 672 ;
-C -1 ; WX 600 ; N nacute ; B 26 0 575 672 ;
-C -1 ; WX 600 ; N umacron ; B 21 -15 562 565 ;
-C -1 ; WX 600 ; N Ncaron ; B 7 -13 593 802 ;
-C -1 ; WX 600 ; N Iacute ; B 96 0 504 805 ;
-C -1 ; WX 600 ; N plusminus ; B 87 44 513 558 ;
-C -1 ; WX 600 ; N brokenbar ; B 275 -175 326 675 ;
-C -1 ; WX 600 ; N registered ; B 0 -18 600 580 ;
-C -1 ; WX 600 ; N Gbreve ; B 31 -18 575 732 ;
-C -1 ; WX 600 ; N Idotaccent ; B 96 0 504 753 ;
-C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ;
-C -1 ; WX 600 ; N Egrave ; B 53 0 550 805 ;
-C -1 ; WX 600 ; N racute ; B 60 0 559 672 ;
-C -1 ; WX 600 ; N omacron ; B 62 -15 538 565 ;
-C -1 ; WX 600 ; N Zacute ; B 86 0 514 805 ;
-C -1 ; WX 600 ; N Zcaron ; B 86 0 514 802 ;
-C -1 ; WX 600 ; N greaterequal ; B 98 0 502 710 ;
-C -1 ; WX 600 ; N Eth ; B 30 0 574 562 ;
-C -1 ; WX 600 ; N Ccedilla ; B 41 -151 540 580 ;
-C -1 ; WX 600 ; N lcommaaccent ; B 95 -250 505 629 ;
-C -1 ; WX 600 ; N tcaron ; B 87 -15 530 717 ;
-C -1 ; WX 600 ; N eogonek ; B 66 -172 548 441 ;
-C -1 ; WX 600 ; N Uogonek ; B 17 -172 583 562 ;
-C -1 ; WX 600 ; N Aacute ; B 3 0 597 805 ;
-C -1 ; WX 600 ; N Adieresis ; B 3 0 597 753 ;
-C -1 ; WX 600 ; N egrave ; B 66 -15 548 672 ;
-C -1 ; WX 600 ; N zacute ; B 99 0 502 672 ;
-C -1 ; WX 600 ; N iogonek ; B 95 -172 505 657 ;
-C -1 ; WX 600 ; N Oacute ; B 43 -18 557 805 ;
-C -1 ; WX 600 ; N oacute ; B 62 -15 538 672 ;
-C -1 ; WX 600 ; N amacron ; B 53 -15 559 565 ;
-C -1 ; WX 600 ; N sacute ; B 80 -15 513 672 ;
-C -1 ; WX 600 ; N idieresis ; B 95 0 505 620 ;
-C -1 ; WX 600 ; N Ocircumflex ; B 43 -18 557 787 ;
-C -1 ; WX 600 ; N Ugrave ; B 17 -18 583 805 ;
-C -1 ; WX 600 ; N Delta ; B 6 0 598 688 ;
-C -1 ; WX 600 ; N thorn ; B -6 -157 555 629 ;
-C -1 ; WX 600 ; N twosuperior ; B 177 249 424 622 ;
-C -1 ; WX 600 ; N Odieresis ; B 43 -18 557 753 ;
-C -1 ; WX 600 ; N mu ; B 21 -157 562 426 ;
-C -1 ; WX 600 ; N igrave ; B 95 0 505 672 ;
-C -1 ; WX 600 ; N ohungarumlaut ; B 62 -15 580 672 ;
-C -1 ; WX 600 ; N Eogonek ; B 53 -172 561 562 ;
-C -1 ; WX 600 ; N dcroat ; B 45 -15 591 629 ;
-C -1 ; WX 600 ; N threequarters ; B 8 -56 593 666 ;
-C -1 ; WX 600 ; N Scedilla ; B 72 -151 529 580 ;
-C -1 ; WX 600 ; N lcaron ; B 95 0 533 629 ;
-C -1 ; WX 600 ; N Kcommaaccent ; B 38 -250 582 562 ;
-C -1 ; WX 600 ; N Lacute ; B 47 0 554 805 ;
-C -1 ; WX 600 ; N trademark ; B -23 263 623 562 ;
-C -1 ; WX 600 ; N edotaccent ; B 66 -15 548 620 ;
-C -1 ; WX 600 ; N Igrave ; B 96 0 504 805 ;
-C -1 ; WX 600 ; N Imacron ; B 96 0 504 698 ;
-C -1 ; WX 600 ; N Lcaron ; B 47 0 554 562 ;
-C -1 ; WX 600 ; N onehalf ; B 0 -57 611 665 ;
-C -1 ; WX 600 ; N lessequal ; B 98 0 502 710 ;
-C -1 ; WX 600 ; N ocircumflex ; B 62 -15 538 654 ;
-C -1 ; WX 600 ; N ntilde ; B 26 0 575 606 ;
-C -1 ; WX 600 ; N Uhungarumlaut ; B 17 -18 590 805 ;
-C -1 ; WX 600 ; N Eacute ; B 53 0 550 805 ;
-C -1 ; WX 600 ; N emacron ; B 66 -15 548 565 ;
-C -1 ; WX 600 ; N gbreve ; B 45 -157 566 609 ;
-C -1 ; WX 600 ; N onequarter ; B 0 -57 600 665 ;
-C -1 ; WX 600 ; N Scaron ; B 72 -20 529 802 ;
-C -1 ; WX 600 ; N Scommaaccent ; B 72 -250 529 580 ;
-C -1 ; WX 600 ; N Ohungarumlaut ; B 43 -18 580 805 ;
-C -1 ; WX 600 ; N degree ; B 123 269 477 622 ;
-C -1 ; WX 600 ; N ograve ; B 62 -15 538 672 ;
-C -1 ; WX 600 ; N Ccaron ; B 41 -18 540 802 ;
-C -1 ; WX 600 ; N ugrave ; B 21 -15 562 672 ;
-C -1 ; WX 600 ; N radical ; B 3 -15 597 792 ;
-C -1 ; WX 600 ; N Dcaron ; B 43 0 574 802 ;
-C -1 ; WX 600 ; N rcommaaccent ; B 60 -250 559 441 ;
-C -1 ; WX 600 ; N Ntilde ; B 7 -13 593 729 ;
-C -1 ; WX 600 ; N otilde ; B 62 -15 538 606 ;
-C -1 ; WX 600 ; N Rcommaaccent ; B 38 -250 588 562 ;
-C -1 ; WX 600 ; N Lcommaaccent ; B 47 -250 554 562 ;
-C -1 ; WX 600 ; N Atilde ; B 3 0 597 729 ;
-C -1 ; WX 600 ; N Aogonek ; B 3 -172 608 562 ;
-C -1 ; WX 600 ; N Aring ; B 3 0 597 750 ;
-C -1 ; WX 600 ; N Otilde ; B 43 -18 557 729 ;
-C -1 ; WX 600 ; N zdotaccent ; B 99 0 502 620 ;
-C -1 ; WX 600 ; N Ecaron ; B 53 0 550 802 ;
-C -1 ; WX 600 ; N Iogonek ; B 96 -172 504 562 ;
-C -1 ; WX 600 ; N kcommaaccent ; B 43 -250 580 629 ;
-C -1 ; WX 600 ; N minus ; B 80 232 520 283 ;
-C -1 ; WX 600 ; N Icircumflex ; B 96 0 504 787 ;
-C -1 ; WX 600 ; N ncaron ; B 26 0 575 669 ;
-C -1 ; WX 600 ; N tcommaaccent ; B 87 -250 530 561 ;
-C -1 ; WX 600 ; N logicalnot ; B 87 108 513 369 ;
-C -1 ; WX 600 ; N odieresis ; B 62 -15 538 620 ;
-C -1 ; WX 600 ; N udieresis ; B 21 -15 562 620 ;
-C -1 ; WX 600 ; N notequal ; B 15 -16 540 529 ;
-C -1 ; WX 600 ; N gcommaaccent ; B 45 -157 566 708 ;
-C -1 ; WX 600 ; N eth ; B 62 -15 538 629 ;
-C -1 ; WX 600 ; N zcaron ; B 99 0 502 669 ;
-C -1 ; WX 600 ; N ncommaaccent ; B 26 -250 575 441 ;
-C -1 ; WX 600 ; N onesuperior ; B 172 249 428 622 ;
-C -1 ; WX 600 ; N imacron ; B 95 0 505 565 ;
-C -1 ; WX 600 ; N Euro ; B 0 0 0 0 ;
-EndCharMetrics
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Bold.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Bold.afm
deleted file mode 100644
index 837c594e0e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Bold.afm
+++ /dev/null
@@ -1,2827 +0,0 @@
-StartFontMetrics 4.1
-Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Thu May 1 12:43:52 1997
-Comment UniqueID 43052
-Comment VMusage 37169 48194
-FontName Helvetica-Bold
-FullName Helvetica Bold
-FamilyName Helvetica
-Weight Bold
-ItalicAngle 0
-IsFixedPitch false
-CharacterSet ExtendedRoman
-FontBBox -170 -228 1003 962
-UnderlinePosition -100
-UnderlineThickness 50
-Version 002.000
-Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 718
-XHeight 532
-Ascender 718
-Descender -207
-StdHW 118
-StdVW 140
-StartCharMetrics 315
-C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 90 0 244 718 ;
-C 34 ; WX 474 ; N quotedbl ; B 98 447 376 718 ;
-C 35 ; WX 556 ; N numbersign ; B 18 0 538 698 ;
-C 36 ; WX 556 ; N dollar ; B 30 -115 523 775 ;
-C 37 ; WX 889 ; N percent ; B 28 -19 861 710 ;
-C 38 ; WX 722 ; N ampersand ; B 54 -19 701 718 ;
-C 39 ; WX 278 ; N quoteright ; B 69 445 209 718 ;
-C 40 ; WX 333 ; N parenleft ; B 35 -208 314 734 ;
-C 41 ; WX 333 ; N parenright ; B 19 -208 298 734 ;
-C 42 ; WX 389 ; N asterisk ; B 27 387 362 718 ;
-C 43 ; WX 584 ; N plus ; B 40 0 544 506 ;
-C 44 ; WX 278 ; N comma ; B 64 -168 214 146 ;
-C 45 ; WX 333 ; N hyphen ; B 27 215 306 345 ;
-C 46 ; WX 278 ; N period ; B 64 0 214 146 ;
-C 47 ; WX 278 ; N slash ; B -33 -19 311 737 ;
-C 48 ; WX 556 ; N zero ; B 32 -19 524 710 ;
-C 49 ; WX 556 ; N one ; B 69 0 378 710 ;
-C 50 ; WX 556 ; N two ; B 26 0 511 710 ;
-C 51 ; WX 556 ; N three ; B 27 -19 516 710 ;
-C 52 ; WX 556 ; N four ; B 27 0 526 710 ;
-C 53 ; WX 556 ; N five ; B 27 -19 516 698 ;
-C 54 ; WX 556 ; N six ; B 31 -19 520 710 ;
-C 55 ; WX 556 ; N seven ; B 25 0 528 698 ;
-C 56 ; WX 556 ; N eight ; B 32 -19 524 710 ;
-C 57 ; WX 556 ; N nine ; B 30 -19 522 710 ;
-C 58 ; WX 333 ; N colon ; B 92 0 242 512 ;
-C 59 ; WX 333 ; N semicolon ; B 92 -168 242 512 ;
-C 60 ; WX 584 ; N less ; B 38 -8 546 514 ;
-C 61 ; WX 584 ; N equal ; B 40 87 544 419 ;
-C 62 ; WX 584 ; N greater ; B 38 -8 546 514 ;
-C 63 ; WX 611 ; N question ; B 60 0 556 727 ;
-C 64 ; WX 975 ; N at ; B 118 -19 856 737 ;
-C 65 ; WX 722 ; N A ; B 20 0 702 718 ;
-C 66 ; WX 722 ; N B ; B 76 0 669 718 ;
-C 67 ; WX 722 ; N C ; B 44 -19 684 737 ;
-C 68 ; WX 722 ; N D ; B 76 0 685 718 ;
-C 69 ; WX 667 ; N E ; B 76 0 621 718 ;
-C 70 ; WX 611 ; N F ; B 76 0 587 718 ;
-C 71 ; WX 778 ; N G ; B 44 -19 713 737 ;
-C 72 ; WX 722 ; N H ; B 71 0 651 718 ;
-C 73 ; WX 278 ; N I ; B 64 0 214 718 ;
-C 74 ; WX 556 ; N J ; B 22 -18 484 718 ;
-C 75 ; WX 722 ; N K ; B 87 0 722 718 ;
-C 76 ; WX 611 ; N L ; B 76 0 583 718 ;
-C 77 ; WX 833 ; N M ; B 69 0 765 718 ;
-C 78 ; WX 722 ; N N ; B 69 0 654 718 ;
-C 79 ; WX 778 ; N O ; B 44 -19 734 737 ;
-C 80 ; WX 667 ; N P ; B 76 0 627 718 ;
-C 81 ; WX 778 ; N Q ; B 44 -52 737 737 ;
-C 82 ; WX 722 ; N R ; B 76 0 677 718 ;
-C 83 ; WX 667 ; N S ; B 39 -19 629 737 ;
-C 84 ; WX 611 ; N T ; B 14 0 598 718 ;
-C 85 ; WX 722 ; N U ; B 72 -19 651 718 ;
-C 86 ; WX 667 ; N V ; B 19 0 648 718 ;
-C 87 ; WX 944 ; N W ; B 16 0 929 718 ;
-C 88 ; WX 667 ; N X ; B 14 0 653 718 ;
-C 89 ; WX 667 ; N Y ; B 15 0 653 718 ;
-C 90 ; WX 611 ; N Z ; B 25 0 586 718 ;
-C 91 ; WX 333 ; N bracketleft ; B 63 -196 309 722 ;
-C 92 ; WX 278 ; N backslash ; B -33 -19 311 737 ;
-C 93 ; WX 333 ; N bracketright ; B 24 -196 270 722 ;
-C 94 ; WX 584 ; N asciicircum ; B 62 323 522 698 ;
-C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ;
-C 96 ; WX 278 ; N quoteleft ; B 69 454 209 727 ;
-C 97 ; WX 556 ; N a ; B 29 -14 527 546 ;
-C 98 ; WX 611 ; N b ; B 61 -14 578 718 ;
-C 99 ; WX 556 ; N c ; B 34 -14 524 546 ;
-C 100 ; WX 611 ; N d ; B 34 -14 551 718 ;
-C 101 ; WX 556 ; N e ; B 23 -14 528 546 ;
-C 102 ; WX 333 ; N f ; B 10 0 318 727 ; L i fi ; L l fl ;
-C 103 ; WX 611 ; N g ; B 40 -217 553 546 ;
-C 104 ; WX 611 ; N h ; B 65 0 546 718 ;
-C 105 ; WX 278 ; N i ; B 69 0 209 725 ;
-C 106 ; WX 278 ; N j ; B 3 -214 209 725 ;
-C 107 ; WX 556 ; N k ; B 69 0 562 718 ;
-C 108 ; WX 278 ; N l ; B 69 0 209 718 ;
-C 109 ; WX 889 ; N m ; B 64 0 826 546 ;
-C 110 ; WX 611 ; N n ; B 65 0 546 546 ;
-C 111 ; WX 611 ; N o ; B 34 -14 578 546 ;
-C 112 ; WX 611 ; N p ; B 62 -207 578 546 ;
-C 113 ; WX 611 ; N q ; B 34 -207 552 546 ;
-C 114 ; WX 389 ; N r ; B 64 0 373 546 ;
-C 115 ; WX 556 ; N s ; B 30 -14 519 546 ;
-C 116 ; WX 333 ; N t ; B 10 -6 309 676 ;
-C 117 ; WX 611 ; N u ; B 66 -14 545 532 ;
-C 118 ; WX 556 ; N v ; B 13 0 543 532 ;
-C 119 ; WX 778 ; N w ; B 10 0 769 532 ;
-C 120 ; WX 556 ; N x ; B 15 0 541 532 ;
-C 121 ; WX 556 ; N y ; B 10 -214 539 532 ;
-C 122 ; WX 500 ; N z ; B 20 0 480 532 ;
-C 123 ; WX 389 ; N braceleft ; B 48 -196 365 722 ;
-C 124 ; WX 280 ; N bar ; B 84 -225 196 775 ;
-C 125 ; WX 389 ; N braceright ; B 24 -196 341 722 ;
-C 126 ; WX 584 ; N asciitilde ; B 61 163 523 343 ;
-C 161 ; WX 333 ; N exclamdown ; B 90 -186 244 532 ;
-C 162 ; WX 556 ; N cent ; B 34 -118 524 628 ;
-C 163 ; WX 556 ; N sterling ; B 28 -16 541 718 ;
-C 164 ; WX 167 ; N fraction ; B -170 -19 336 710 ;
-C 165 ; WX 556 ; N yen ; B -9 0 565 698 ;
-C 166 ; WX 556 ; N florin ; B -10 -210 516 737 ;
-C 167 ; WX 556 ; N section ; B 34 -184 522 727 ;
-C 168 ; WX 556 ; N currency ; B -3 76 559 636 ;
-C 169 ; WX 238 ; N quotesingle ; B 70 447 168 718 ;
-C 170 ; WX 500 ; N quotedblleft ; B 64 454 436 727 ;
-C 171 ; WX 556 ; N guillemotleft ; B 88 76 468 484 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 83 76 250 484 ;
-C 173 ; WX 333 ; N guilsinglright ; B 83 76 250 484 ;
-C 174 ; WX 611 ; N fi ; B 10 0 542 727 ;
-C 175 ; WX 611 ; N fl ; B 10 0 542 727 ;
-C 177 ; WX 556 ; N endash ; B 0 227 556 333 ;
-C 178 ; WX 556 ; N dagger ; B 36 -171 520 718 ;
-C 179 ; WX 556 ; N daggerdbl ; B 36 -171 520 718 ;
-C 180 ; WX 278 ; N periodcentered ; B 58 172 220 334 ;
-C 182 ; WX 556 ; N paragraph ; B -8 -191 539 700 ;
-C 183 ; WX 350 ; N bullet ; B 10 194 340 524 ;
-C 184 ; WX 278 ; N quotesinglbase ; B 69 -146 209 127 ;
-C 185 ; WX 500 ; N quotedblbase ; B 64 -146 436 127 ;
-C 186 ; WX 500 ; N quotedblright ; B 64 445 436 718 ;
-C 187 ; WX 556 ; N guillemotright ; B 88 76 468 484 ;
-C 188 ; WX 1000 ; N ellipsis ; B 92 0 908 146 ;
-C 189 ; WX 1000 ; N perthousand ; B -3 -19 1003 710 ;
-C 191 ; WX 611 ; N questiondown ; B 55 -195 551 532 ;
-C 193 ; WX 333 ; N grave ; B -23 604 225 750 ;
-C 194 ; WX 333 ; N acute ; B 108 604 356 750 ;
-C 195 ; WX 333 ; N circumflex ; B -10 604 343 750 ;
-C 196 ; WX 333 ; N tilde ; B -17 610 350 737 ;
-C 197 ; WX 333 ; N macron ; B -6 604 339 678 ;
-C 198 ; WX 333 ; N breve ; B -2 604 335 750 ;
-C 199 ; WX 333 ; N dotaccent ; B 104 614 230 729 ;
-C 200 ; WX 333 ; N dieresis ; B 6 614 327 729 ;
-C 202 ; WX 333 ; N ring ; B 59 568 275 776 ;
-C 203 ; WX 333 ; N cedilla ; B 6 -228 245 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 9 604 486 750 ;
-C 206 ; WX 333 ; N ogonek ; B 71 -228 304 0 ;
-C 207 ; WX 333 ; N caron ; B -10 604 343 750 ;
-C 208 ; WX 1000 ; N emdash ; B 0 227 1000 333 ;
-C 225 ; WX 1000 ; N AE ; B 5 0 954 718 ;
-C 227 ; WX 370 ; N ordfeminine ; B 22 401 347 737 ;
-C 232 ; WX 611 ; N Lslash ; B -20 0 583 718 ;
-C 233 ; WX 778 ; N Oslash ; B 33 -27 744 745 ;
-C 234 ; WX 1000 ; N OE ; B 37 -19 961 737 ;
-C 235 ; WX 365 ; N ordmasculine ; B 6 401 360 737 ;
-C 241 ; WX 889 ; N ae ; B 29 -14 858 546 ;
-C 245 ; WX 278 ; N dotlessi ; B 69 0 209 532 ;
-C 248 ; WX 278 ; N lslash ; B -18 0 296 718 ;
-C 249 ; WX 611 ; N oslash ; B 22 -29 589 560 ;
-C 250 ; WX 944 ; N oe ; B 34 -14 912 546 ;
-C 251 ; WX 611 ; N germandbls ; B 69 -14 579 731 ;
-C -1 ; WX 278 ; N Idieresis ; B -21 0 300 915 ;
-C -1 ; WX 556 ; N eacute ; B 23 -14 528 750 ;
-C -1 ; WX 556 ; N abreve ; B 29 -14 527 750 ;
-C -1 ; WX 611 ; N uhungarumlaut ; B 66 -14 625 750 ;
-C -1 ; WX 556 ; N ecaron ; B 23 -14 528 750 ;
-C -1 ; WX 667 ; N Ydieresis ; B 15 0 653 915 ;
-C -1 ; WX 584 ; N divide ; B 40 -42 544 548 ;
-C -1 ; WX 667 ; N Yacute ; B 15 0 653 936 ;
-C -1 ; WX 722 ; N Acircumflex ; B 20 0 702 936 ;
-C -1 ; WX 556 ; N aacute ; B 29 -14 527 750 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 72 -19 651 936 ;
-C -1 ; WX 556 ; N yacute ; B 10 -214 539 750 ;
-C -1 ; WX 556 ; N scommaaccent ; B 30 -228 519 546 ;
-C -1 ; WX 556 ; N ecircumflex ; B 23 -14 528 750 ;
-C -1 ; WX 722 ; N Uring ; B 72 -19 651 962 ;
-C -1 ; WX 722 ; N Udieresis ; B 72 -19 651 915 ;
-C -1 ; WX 556 ; N aogonek ; B 29 -224 545 546 ;
-C -1 ; WX 722 ; N Uacute ; B 72 -19 651 936 ;
-C -1 ; WX 611 ; N uogonek ; B 66 -228 545 532 ;
-C -1 ; WX 667 ; N Edieresis ; B 76 0 621 915 ;
-C -1 ; WX 722 ; N Dcroat ; B -5 0 685 718 ;
-C -1 ; WX 250 ; N commaaccent ; B 64 -228 199 -50 ;
-C -1 ; WX 737 ; N copyright ; B -11 -19 749 737 ;
-C -1 ; WX 667 ; N Emacron ; B 76 0 621 864 ;
-C -1 ; WX 556 ; N ccaron ; B 34 -14 524 750 ;
-C -1 ; WX 556 ; N aring ; B 29 -14 527 776 ;
-C -1 ; WX 722 ; N Ncommaaccent ; B 69 -228 654 718 ;
-C -1 ; WX 278 ; N lacute ; B 69 0 329 936 ;
-C -1 ; WX 556 ; N agrave ; B 29 -14 527 750 ;
-C -1 ; WX 611 ; N Tcommaaccent ; B 14 -228 598 718 ;
-C -1 ; WX 722 ; N Cacute ; B 44 -19 684 936 ;
-C -1 ; WX 556 ; N atilde ; B 29 -14 527 737 ;
-C -1 ; WX 667 ; N Edotaccent ; B 76 0 621 915 ;
-C -1 ; WX 556 ; N scaron ; B 30 -14 519 750 ;
-C -1 ; WX 556 ; N scedilla ; B 30 -228 519 546 ;
-C -1 ; WX 278 ; N iacute ; B 69 0 329 750 ;
-C -1 ; WX 494 ; N lozenge ; B 10 0 484 745 ;
-C -1 ; WX 722 ; N Rcaron ; B 76 0 677 936 ;
-C -1 ; WX 778 ; N Gcommaaccent ; B 44 -228 713 737 ;
-C -1 ; WX 611 ; N ucircumflex ; B 66 -14 545 750 ;
-C -1 ; WX 556 ; N acircumflex ; B 29 -14 527 750 ;
-C -1 ; WX 722 ; N Amacron ; B 20 0 702 864 ;
-C -1 ; WX 389 ; N rcaron ; B 18 0 373 750 ;
-C -1 ; WX 556 ; N ccedilla ; B 34 -228 524 546 ;
-C -1 ; WX 611 ; N Zdotaccent ; B 25 0 586 915 ;
-C -1 ; WX 667 ; N Thorn ; B 76 0 627 718 ;
-C -1 ; WX 778 ; N Omacron ; B 44 -19 734 864 ;
-C -1 ; WX 722 ; N Racute ; B 76 0 677 936 ;
-C -1 ; WX 667 ; N Sacute ; B 39 -19 629 936 ;
-C -1 ; WX 743 ; N dcaron ; B 34 -14 750 718 ;
-C -1 ; WX 722 ; N Umacron ; B 72 -19 651 864 ;
-C -1 ; WX 611 ; N uring ; B 66 -14 545 776 ;
-C -1 ; WX 333 ; N threesuperior ; B 8 271 326 710 ;
-C -1 ; WX 778 ; N Ograve ; B 44 -19 734 936 ;
-C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ;
-C -1 ; WX 722 ; N Abreve ; B 20 0 702 936 ;
-C -1 ; WX 584 ; N multiply ; B 40 1 545 505 ;
-C -1 ; WX 611 ; N uacute ; B 66 -14 545 750 ;
-C -1 ; WX 611 ; N Tcaron ; B 14 0 598 936 ;
-C -1 ; WX 494 ; N partialdiff ; B 11 -21 494 750 ;
-C -1 ; WX 556 ; N ydieresis ; B 10 -214 539 729 ;
-C -1 ; WX 722 ; N Nacute ; B 69 0 654 936 ;
-C -1 ; WX 278 ; N icircumflex ; B -37 0 316 750 ;
-C -1 ; WX 667 ; N Ecircumflex ; B 76 0 621 936 ;
-C -1 ; WX 556 ; N adieresis ; B 29 -14 527 729 ;
-C -1 ; WX 556 ; N edieresis ; B 23 -14 528 729 ;
-C -1 ; WX 556 ; N cacute ; B 34 -14 524 750 ;
-C -1 ; WX 611 ; N nacute ; B 65 0 546 750 ;
-C -1 ; WX 611 ; N umacron ; B 66 -14 545 678 ;
-C -1 ; WX 722 ; N Ncaron ; B 69 0 654 936 ;
-C -1 ; WX 278 ; N Iacute ; B 64 0 329 936 ;
-C -1 ; WX 584 ; N plusminus ; B 40 0 544 506 ;
-C -1 ; WX 280 ; N brokenbar ; B 84 -150 196 700 ;
-C -1 ; WX 737 ; N registered ; B -11 -19 748 737 ;
-C -1 ; WX 778 ; N Gbreve ; B 44 -19 713 936 ;
-C -1 ; WX 278 ; N Idotaccent ; B 64 0 214 915 ;
-C -1 ; WX 600 ; N summation ; B 14 -10 585 706 ;
-C -1 ; WX 667 ; N Egrave ; B 76 0 621 936 ;
-C -1 ; WX 389 ; N racute ; B 64 0 384 750 ;
-C -1 ; WX 611 ; N omacron ; B 34 -14 578 678 ;
-C -1 ; WX 611 ; N Zacute ; B 25 0 586 936 ;
-C -1 ; WX 611 ; N Zcaron ; B 25 0 586 936 ;
-C -1 ; WX 549 ; N greaterequal ; B 26 0 523 704 ;
-C -1 ; WX 722 ; N Eth ; B -5 0 685 718 ;
-C -1 ; WX 722 ; N Ccedilla ; B 44 -228 684 737 ;
-C -1 ; WX 278 ; N lcommaaccent ; B 69 -228 213 718 ;
-C -1 ; WX 389 ; N tcaron ; B 10 -6 421 878 ;
-C -1 ; WX 556 ; N eogonek ; B 23 -228 528 546 ;
-C -1 ; WX 722 ; N Uogonek ; B 72 -228 651 718 ;
-C -1 ; WX 722 ; N Aacute ; B 20 0 702 936 ;
-C -1 ; WX 722 ; N Adieresis ; B 20 0 702 915 ;
-C -1 ; WX 556 ; N egrave ; B 23 -14 528 750 ;
-C -1 ; WX 500 ; N zacute ; B 20 0 480 750 ;
-C -1 ; WX 278 ; N iogonek ; B 16 -224 249 725 ;
-C -1 ; WX 778 ; N Oacute ; B 44 -19 734 936 ;
-C -1 ; WX 611 ; N oacute ; B 34 -14 578 750 ;
-C -1 ; WX 556 ; N amacron ; B 29 -14 527 678 ;
-C -1 ; WX 556 ; N sacute ; B 30 -14 519 750 ;
-C -1 ; WX 278 ; N idieresis ; B -21 0 300 729 ;
-C -1 ; WX 778 ; N Ocircumflex ; B 44 -19 734 936 ;
-C -1 ; WX 722 ; N Ugrave ; B 72 -19 651 936 ;
-C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ;
-C -1 ; WX 611 ; N thorn ; B 62 -208 578 718 ;
-C -1 ; WX 333 ; N twosuperior ; B 9 283 324 710 ;
-C -1 ; WX 778 ; N Odieresis ; B 44 -19 734 915 ;
-C -1 ; WX 611 ; N mu ; B 66 -207 545 532 ;
-C -1 ; WX 278 ; N igrave ; B -50 0 209 750 ;
-C -1 ; WX 611 ; N ohungarumlaut ; B 34 -14 625 750 ;
-C -1 ; WX 667 ; N Eogonek ; B 76 -224 639 718 ;
-C -1 ; WX 611 ; N dcroat ; B 34 -14 650 718 ;
-C -1 ; WX 834 ; N threequarters ; B 16 -19 799 710 ;
-C -1 ; WX 667 ; N Scedilla ; B 39 -228 629 737 ;
-C -1 ; WX 400 ; N lcaron ; B 69 0 408 718 ;
-C -1 ; WX 722 ; N Kcommaaccent ; B 87 -228 722 718 ;
-C -1 ; WX 611 ; N Lacute ; B 76 0 583 936 ;
-C -1 ; WX 1000 ; N trademark ; B 44 306 956 718 ;
-C -1 ; WX 556 ; N edotaccent ; B 23 -14 528 729 ;
-C -1 ; WX 278 ; N Igrave ; B -50 0 214 936 ;
-C -1 ; WX 278 ; N Imacron ; B -33 0 312 864 ;
-C -1 ; WX 611 ; N Lcaron ; B 76 0 583 718 ;
-C -1 ; WX 834 ; N onehalf ; B 26 -19 794 710 ;
-C -1 ; WX 549 ; N lessequal ; B 29 0 526 704 ;
-C -1 ; WX 611 ; N ocircumflex ; B 34 -14 578 750 ;
-C -1 ; WX 611 ; N ntilde ; B 65 0 546 737 ;
-C -1 ; WX 722 ; N Uhungarumlaut ; B 72 -19 681 936 ;
-C -1 ; WX 667 ; N Eacute ; B 76 0 621 936 ;
-C -1 ; WX 556 ; N emacron ; B 23 -14 528 678 ;
-C -1 ; WX 611 ; N gbreve ; B 40 -217 553 750 ;
-C -1 ; WX 834 ; N onequarter ; B 26 -19 766 710 ;
-C -1 ; WX 667 ; N Scaron ; B 39 -19 629 936 ;
-C -1 ; WX 667 ; N Scommaaccent ; B 39 -228 629 737 ;
-C -1 ; WX 778 ; N Ohungarumlaut ; B 44 -19 734 936 ;
-C -1 ; WX 400 ; N degree ; B 57 426 343 712 ;
-C -1 ; WX 611 ; N ograve ; B 34 -14 578 750 ;
-C -1 ; WX 722 ; N Ccaron ; B 44 -19 684 936 ;
-C -1 ; WX 611 ; N ugrave ; B 66 -14 545 750 ;
-C -1 ; WX 549 ; N radical ; B 10 -46 512 850 ;
-C -1 ; WX 722 ; N Dcaron ; B 76 0 685 936 ;
-C -1 ; WX 389 ; N rcommaaccent ; B 64 -228 373 546 ;
-C -1 ; WX 722 ; N Ntilde ; B 69 0 654 923 ;
-C -1 ; WX 611 ; N otilde ; B 34 -14 578 737 ;
-C -1 ; WX 722 ; N Rcommaaccent ; B 76 -228 677 718 ;
-C -1 ; WX 611 ; N Lcommaaccent ; B 76 -228 583 718 ;
-C -1 ; WX 722 ; N Atilde ; B 20 0 702 923 ;
-C -1 ; WX 722 ; N Aogonek ; B 20 -224 742 718 ;
-C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ;
-C -1 ; WX 778 ; N Otilde ; B 44 -19 734 923 ;
-C -1 ; WX 500 ; N zdotaccent ; B 20 0 480 729 ;
-C -1 ; WX 667 ; N Ecaron ; B 76 0 621 936 ;
-C -1 ; WX 278 ; N Iogonek ; B -11 -228 222 718 ;
-C -1 ; WX 556 ; N kcommaaccent ; B 69 -228 562 718 ;
-C -1 ; WX 584 ; N minus ; B 40 197 544 309 ;
-C -1 ; WX 278 ; N Icircumflex ; B -37 0 316 936 ;
-C -1 ; WX 611 ; N ncaron ; B 65 0 546 750 ;
-C -1 ; WX 333 ; N tcommaaccent ; B 10 -228 309 676 ;
-C -1 ; WX 584 ; N logicalnot ; B 40 108 544 419 ;
-C -1 ; WX 611 ; N odieresis ; B 34 -14 578 729 ;
-C -1 ; WX 611 ; N udieresis ; B 66 -14 545 729 ;
-C -1 ; WX 549 ; N notequal ; B 15 -49 540 570 ;
-C -1 ; WX 611 ; N gcommaaccent ; B 40 -217 553 850 ;
-C -1 ; WX 611 ; N eth ; B 34 -14 578 737 ;
-C -1 ; WX 500 ; N zcaron ; B 20 0 480 750 ;
-C -1 ; WX 611 ; N ncommaaccent ; B 65 -228 546 546 ;
-C -1 ; WX 333 ; N onesuperior ; B 26 283 237 710 ;
-C -1 ; WX 278 ; N imacron ; B -8 0 285 678 ;
-C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 2481
-KPX A C -40
-KPX A Cacute -40
-KPX A Ccaron -40
-KPX A Ccedilla -40
-KPX A G -50
-KPX A Gbreve -50
-KPX A Gcommaaccent -50
-KPX A O -40
-KPX A Oacute -40
-KPX A Ocircumflex -40
-KPX A Odieresis -40
-KPX A Ograve -40
-KPX A Ohungarumlaut -40
-KPX A Omacron -40
-KPX A Oslash -40
-KPX A Otilde -40
-KPX A Q -40
-KPX A T -90
-KPX A Tcaron -90
-KPX A Tcommaaccent -90
-KPX A U -50
-KPX A Uacute -50
-KPX A Ucircumflex -50
-KPX A Udieresis -50
-KPX A Ugrave -50
-KPX A Uhungarumlaut -50
-KPX A Umacron -50
-KPX A Uogonek -50
-KPX A Uring -50
-KPX A V -80
-KPX A W -60
-KPX A Y -110
-KPX A Yacute -110
-KPX A Ydieresis -110
-KPX A u -30
-KPX A uacute -30
-KPX A ucircumflex -30
-KPX A udieresis -30
-KPX A ugrave -30
-KPX A uhungarumlaut -30
-KPX A umacron -30
-KPX A uogonek -30
-KPX A uring -30
-KPX A v -40
-KPX A w -30
-KPX A y -30
-KPX A yacute -30
-KPX A ydieresis -30
-KPX Aacute C -40
-KPX Aacute Cacute -40
-KPX Aacute Ccaron -40
-KPX Aacute Ccedilla -40
-KPX Aacute G -50
-KPX Aacute Gbreve -50
-KPX Aacute Gcommaaccent -50
-KPX Aacute O -40
-KPX Aacute Oacute -40
-KPX Aacute Ocircumflex -40
-KPX Aacute Odieresis -40
-KPX Aacute Ograve -40
-KPX Aacute Ohungarumlaut -40
-KPX Aacute Omacron -40
-KPX Aacute Oslash -40
-KPX Aacute Otilde -40
-KPX Aacute Q -40
-KPX Aacute T -90
-KPX Aacute Tcaron -90
-KPX Aacute Tcommaaccent -90
-KPX Aacute U -50
-KPX Aacute Uacute -50
-KPX Aacute Ucircumflex -50
-KPX Aacute Udieresis -50
-KPX Aacute Ugrave -50
-KPX Aacute Uhungarumlaut -50
-KPX Aacute Umacron -50
-KPX Aacute Uogonek -50
-KPX Aacute Uring -50
-KPX Aacute V -80
-KPX Aacute W -60
-KPX Aacute Y -110
-KPX Aacute Yacute -110
-KPX Aacute Ydieresis -110
-KPX Aacute u -30
-KPX Aacute uacute -30
-KPX Aacute ucircumflex -30
-KPX Aacute udieresis -30
-KPX Aacute ugrave -30
-KPX Aacute uhungarumlaut -30
-KPX Aacute umacron -30
-KPX Aacute uogonek -30
-KPX Aacute uring -30
-KPX Aacute v -40
-KPX Aacute w -30
-KPX Aacute y -30
-KPX Aacute yacute -30
-KPX Aacute ydieresis -30
-KPX Abreve C -40
-KPX Abreve Cacute -40
-KPX Abreve Ccaron -40
-KPX Abreve Ccedilla -40
-KPX Abreve G -50
-KPX Abreve Gbreve -50
-KPX Abreve Gcommaaccent -50
-KPX Abreve O -40
-KPX Abreve Oacute -40
-KPX Abreve Ocircumflex -40
-KPX Abreve Odieresis -40
-KPX Abreve Ograve -40
-KPX Abreve Ohungarumlaut -40
-KPX Abreve Omacron -40
-KPX Abreve Oslash -40
-KPX Abreve Otilde -40
-KPX Abreve Q -40
-KPX Abreve T -90
-KPX Abreve Tcaron -90
-KPX Abreve Tcommaaccent -90
-KPX Abreve U -50
-KPX Abreve Uacute -50
-KPX Abreve Ucircumflex -50
-KPX Abreve Udieresis -50
-KPX Abreve Ugrave -50
-KPX Abreve Uhungarumlaut -50
-KPX Abreve Umacron -50
-KPX Abreve Uogonek -50
-KPX Abreve Uring -50
-KPX Abreve V -80
-KPX Abreve W -60
-KPX Abreve Y -110
-KPX Abreve Yacute -110
-KPX Abreve Ydieresis -110
-KPX Abreve u -30
-KPX Abreve uacute -30
-KPX Abreve ucircumflex -30
-KPX Abreve udieresis -30
-KPX Abreve ugrave -30
-KPX Abreve uhungarumlaut -30
-KPX Abreve umacron -30
-KPX Abreve uogonek -30
-KPX Abreve uring -30
-KPX Abreve v -40
-KPX Abreve w -30
-KPX Abreve y -30
-KPX Abreve yacute -30
-KPX Abreve ydieresis -30
-KPX Acircumflex C -40
-KPX Acircumflex Cacute -40
-KPX Acircumflex Ccaron -40
-KPX Acircumflex Ccedilla -40
-KPX Acircumflex G -50
-KPX Acircumflex Gbreve -50
-KPX Acircumflex Gcommaaccent -50
-KPX Acircumflex O -40
-KPX Acircumflex Oacute -40
-KPX Acircumflex Ocircumflex -40
-KPX Acircumflex Odieresis -40
-KPX Acircumflex Ograve -40
-KPX Acircumflex Ohungarumlaut -40
-KPX Acircumflex Omacron -40
-KPX Acircumflex Oslash -40
-KPX Acircumflex Otilde -40
-KPX Acircumflex Q -40
-KPX Acircumflex T -90
-KPX Acircumflex Tcaron -90
-KPX Acircumflex Tcommaaccent -90
-KPX Acircumflex U -50
-KPX Acircumflex Uacute -50
-KPX Acircumflex Ucircumflex -50
-KPX Acircumflex Udieresis -50
-KPX Acircumflex Ugrave -50
-KPX Acircumflex Uhungarumlaut -50
-KPX Acircumflex Umacron -50
-KPX Acircumflex Uogonek -50
-KPX Acircumflex Uring -50
-KPX Acircumflex V -80
-KPX Acircumflex W -60
-KPX Acircumflex Y -110
-KPX Acircumflex Yacute -110
-KPX Acircumflex Ydieresis -110
-KPX Acircumflex u -30
-KPX Acircumflex uacute -30
-KPX Acircumflex ucircumflex -30
-KPX Acircumflex udieresis -30
-KPX Acircumflex ugrave -30
-KPX Acircumflex uhungarumlaut -30
-KPX Acircumflex umacron -30
-KPX Acircumflex uogonek -30
-KPX Acircumflex uring -30
-KPX Acircumflex v -40
-KPX Acircumflex w -30
-KPX Acircumflex y -30
-KPX Acircumflex yacute -30
-KPX Acircumflex ydieresis -30
-KPX Adieresis C -40
-KPX Adieresis Cacute -40
-KPX Adieresis Ccaron -40
-KPX Adieresis Ccedilla -40
-KPX Adieresis G -50
-KPX Adieresis Gbreve -50
-KPX Adieresis Gcommaaccent -50
-KPX Adieresis O -40
-KPX Adieresis Oacute -40
-KPX Adieresis Ocircumflex -40
-KPX Adieresis Odieresis -40
-KPX Adieresis Ograve -40
-KPX Adieresis Ohungarumlaut -40
-KPX Adieresis Omacron -40
-KPX Adieresis Oslash -40
-KPX Adieresis Otilde -40
-KPX Adieresis Q -40
-KPX Adieresis T -90
-KPX Adieresis Tcaron -90
-KPX Adieresis Tcommaaccent -90
-KPX Adieresis U -50
-KPX Adieresis Uacute -50
-KPX Adieresis Ucircumflex -50
-KPX Adieresis Udieresis -50
-KPX Adieresis Ugrave -50
-KPX Adieresis Uhungarumlaut -50
-KPX Adieresis Umacron -50
-KPX Adieresis Uogonek -50
-KPX Adieresis Uring -50
-KPX Adieresis V -80
-KPX Adieresis W -60
-KPX Adieresis Y -110
-KPX Adieresis Yacute -110
-KPX Adieresis Ydieresis -110
-KPX Adieresis u -30
-KPX Adieresis uacute -30
-KPX Adieresis ucircumflex -30
-KPX Adieresis udieresis -30
-KPX Adieresis ugrave -30
-KPX Adieresis uhungarumlaut -30
-KPX Adieresis umacron -30
-KPX Adieresis uogonek -30
-KPX Adieresis uring -30
-KPX Adieresis v -40
-KPX Adieresis w -30
-KPX Adieresis y -30
-KPX Adieresis yacute -30
-KPX Adieresis ydieresis -30
-KPX Agrave C -40
-KPX Agrave Cacute -40
-KPX Agrave Ccaron -40
-KPX Agrave Ccedilla -40
-KPX Agrave G -50
-KPX Agrave Gbreve -50
-KPX Agrave Gcommaaccent -50
-KPX Agrave O -40
-KPX Agrave Oacute -40
-KPX Agrave Ocircumflex -40
-KPX Agrave Odieresis -40
-KPX Agrave Ograve -40
-KPX Agrave Ohungarumlaut -40
-KPX Agrave Omacron -40
-KPX Agrave Oslash -40
-KPX Agrave Otilde -40
-KPX Agrave Q -40
-KPX Agrave T -90
-KPX Agrave Tcaron -90
-KPX Agrave Tcommaaccent -90
-KPX Agrave U -50
-KPX Agrave Uacute -50
-KPX Agrave Ucircumflex -50
-KPX Agrave Udieresis -50
-KPX Agrave Ugrave -50
-KPX Agrave Uhungarumlaut -50
-KPX Agrave Umacron -50
-KPX Agrave Uogonek -50
-KPX Agrave Uring -50
-KPX Agrave V -80
-KPX Agrave W -60
-KPX Agrave Y -110
-KPX Agrave Yacute -110
-KPX Agrave Ydieresis -110
-KPX Agrave u -30
-KPX Agrave uacute -30
-KPX Agrave ucircumflex -30
-KPX Agrave udieresis -30
-KPX Agrave ugrave -30
-KPX Agrave uhungarumlaut -30
-KPX Agrave umacron -30
-KPX Agrave uogonek -30
-KPX Agrave uring -30
-KPX Agrave v -40
-KPX Agrave w -30
-KPX Agrave y -30
-KPX Agrave yacute -30
-KPX Agrave ydieresis -30
-KPX Amacron C -40
-KPX Amacron Cacute -40
-KPX Amacron Ccaron -40
-KPX Amacron Ccedilla -40
-KPX Amacron G -50
-KPX Amacron Gbreve -50
-KPX Amacron Gcommaaccent -50
-KPX Amacron O -40
-KPX Amacron Oacute -40
-KPX Amacron Ocircumflex -40
-KPX Amacron Odieresis -40
-KPX Amacron Ograve -40
-KPX Amacron Ohungarumlaut -40
-KPX Amacron Omacron -40
-KPX Amacron Oslash -40
-KPX Amacron Otilde -40
-KPX Amacron Q -40
-KPX Amacron T -90
-KPX Amacron Tcaron -90
-KPX Amacron Tcommaaccent -90
-KPX Amacron U -50
-KPX Amacron Uacute -50
-KPX Amacron Ucircumflex -50
-KPX Amacron Udieresis -50
-KPX Amacron Ugrave -50
-KPX Amacron Uhungarumlaut -50
-KPX Amacron Umacron -50
-KPX Amacron Uogonek -50
-KPX Amacron Uring -50
-KPX Amacron V -80
-KPX Amacron W -60
-KPX Amacron Y -110
-KPX Amacron Yacute -110
-KPX Amacron Ydieresis -110
-KPX Amacron u -30
-KPX Amacron uacute -30
-KPX Amacron ucircumflex -30
-KPX Amacron udieresis -30
-KPX Amacron ugrave -30
-KPX Amacron uhungarumlaut -30
-KPX Amacron umacron -30
-KPX Amacron uogonek -30
-KPX Amacron uring -30
-KPX Amacron v -40
-KPX Amacron w -30
-KPX Amacron y -30
-KPX Amacron yacute -30
-KPX Amacron ydieresis -30
-KPX Aogonek C -40
-KPX Aogonek Cacute -40
-KPX Aogonek Ccaron -40
-KPX Aogonek Ccedilla -40
-KPX Aogonek G -50
-KPX Aogonek Gbreve -50
-KPX Aogonek Gcommaaccent -50
-KPX Aogonek O -40
-KPX Aogonek Oacute -40
-KPX Aogonek Ocircumflex -40
-KPX Aogonek Odieresis -40
-KPX Aogonek Ograve -40
-KPX Aogonek Ohungarumlaut -40
-KPX Aogonek Omacron -40
-KPX Aogonek Oslash -40
-KPX Aogonek Otilde -40
-KPX Aogonek Q -40
-KPX Aogonek T -90
-KPX Aogonek Tcaron -90
-KPX Aogonek Tcommaaccent -90
-KPX Aogonek U -50
-KPX Aogonek Uacute -50
-KPX Aogonek Ucircumflex -50
-KPX Aogonek Udieresis -50
-KPX Aogonek Ugrave -50
-KPX Aogonek Uhungarumlaut -50
-KPX Aogonek Umacron -50
-KPX Aogonek Uogonek -50
-KPX Aogonek Uring -50
-KPX Aogonek V -80
-KPX Aogonek W -60
-KPX Aogonek Y -110
-KPX Aogonek Yacute -110
-KPX Aogonek Ydieresis -110
-KPX Aogonek u -30
-KPX Aogonek uacute -30
-KPX Aogonek ucircumflex -30
-KPX Aogonek udieresis -30
-KPX Aogonek ugrave -30
-KPX Aogonek uhungarumlaut -30
-KPX Aogonek umacron -30
-KPX Aogonek uogonek -30
-KPX Aogonek uring -30
-KPX Aogonek v -40
-KPX Aogonek w -30
-KPX Aogonek y -30
-KPX Aogonek yacute -30
-KPX Aogonek ydieresis -30
-KPX Aring C -40
-KPX Aring Cacute -40
-KPX Aring Ccaron -40
-KPX Aring Ccedilla -40
-KPX Aring G -50
-KPX Aring Gbreve -50
-KPX Aring Gcommaaccent -50
-KPX Aring O -40
-KPX Aring Oacute -40
-KPX Aring Ocircumflex -40
-KPX Aring Odieresis -40
-KPX Aring Ograve -40
-KPX Aring Ohungarumlaut -40
-KPX Aring Omacron -40
-KPX Aring Oslash -40
-KPX Aring Otilde -40
-KPX Aring Q -40
-KPX Aring T -90
-KPX Aring Tcaron -90
-KPX Aring Tcommaaccent -90
-KPX Aring U -50
-KPX Aring Uacute -50
-KPX Aring Ucircumflex -50
-KPX Aring Udieresis -50
-KPX Aring Ugrave -50
-KPX Aring Uhungarumlaut -50
-KPX Aring Umacron -50
-KPX Aring Uogonek -50
-KPX Aring Uring -50
-KPX Aring V -80
-KPX Aring W -60
-KPX Aring Y -110
-KPX Aring Yacute -110
-KPX Aring Ydieresis -110
-KPX Aring u -30
-KPX Aring uacute -30
-KPX Aring ucircumflex -30
-KPX Aring udieresis -30
-KPX Aring ugrave -30
-KPX Aring uhungarumlaut -30
-KPX Aring umacron -30
-KPX Aring uogonek -30
-KPX Aring uring -30
-KPX Aring v -40
-KPX Aring w -30
-KPX Aring y -30
-KPX Aring yacute -30
-KPX Aring ydieresis -30
-KPX Atilde C -40
-KPX Atilde Cacute -40
-KPX Atilde Ccaron -40
-KPX Atilde Ccedilla -40
-KPX Atilde G -50
-KPX Atilde Gbreve -50
-KPX Atilde Gcommaaccent -50
-KPX Atilde O -40
-KPX Atilde Oacute -40
-KPX Atilde Ocircumflex -40
-KPX Atilde Odieresis -40
-KPX Atilde Ograve -40
-KPX Atilde Ohungarumlaut -40
-KPX Atilde Omacron -40
-KPX Atilde Oslash -40
-KPX Atilde Otilde -40
-KPX Atilde Q -40
-KPX Atilde T -90
-KPX Atilde Tcaron -90
-KPX Atilde Tcommaaccent -90
-KPX Atilde U -50
-KPX Atilde Uacute -50
-KPX Atilde Ucircumflex -50
-KPX Atilde Udieresis -50
-KPX Atilde Ugrave -50
-KPX Atilde Uhungarumlaut -50
-KPX Atilde Umacron -50
-KPX Atilde Uogonek -50
-KPX Atilde Uring -50
-KPX Atilde V -80
-KPX Atilde W -60
-KPX Atilde Y -110
-KPX Atilde Yacute -110
-KPX Atilde Ydieresis -110
-KPX Atilde u -30
-KPX Atilde uacute -30
-KPX Atilde ucircumflex -30
-KPX Atilde udieresis -30
-KPX Atilde ugrave -30
-KPX Atilde uhungarumlaut -30
-KPX Atilde umacron -30
-KPX Atilde uogonek -30
-KPX Atilde uring -30
-KPX Atilde v -40
-KPX Atilde w -30
-KPX Atilde y -30
-KPX Atilde yacute -30
-KPX Atilde ydieresis -30
-KPX B A -30
-KPX B Aacute -30
-KPX B Abreve -30
-KPX B Acircumflex -30
-KPX B Adieresis -30
-KPX B Agrave -30
-KPX B Amacron -30
-KPX B Aogonek -30
-KPX B Aring -30
-KPX B Atilde -30
-KPX B U -10
-KPX B Uacute -10
-KPX B Ucircumflex -10
-KPX B Udieresis -10
-KPX B Ugrave -10
-KPX B Uhungarumlaut -10
-KPX B Umacron -10
-KPX B Uogonek -10
-KPX B Uring -10
-KPX D A -40
-KPX D Aacute -40
-KPX D Abreve -40
-KPX D Acircumflex -40
-KPX D Adieresis -40
-KPX D Agrave -40
-KPX D Amacron -40
-KPX D Aogonek -40
-KPX D Aring -40
-KPX D Atilde -40
-KPX D V -40
-KPX D W -40
-KPX D Y -70
-KPX D Yacute -70
-KPX D Ydieresis -70
-KPX D comma -30
-KPX D period -30
-KPX Dcaron A -40
-KPX Dcaron Aacute -40
-KPX Dcaron Abreve -40
-KPX Dcaron Acircumflex -40
-KPX Dcaron Adieresis -40
-KPX Dcaron Agrave -40
-KPX Dcaron Amacron -40
-KPX Dcaron Aogonek -40
-KPX Dcaron Aring -40
-KPX Dcaron Atilde -40
-KPX Dcaron V -40
-KPX Dcaron W -40
-KPX Dcaron Y -70
-KPX Dcaron Yacute -70
-KPX Dcaron Ydieresis -70
-KPX Dcaron comma -30
-KPX Dcaron period -30
-KPX Dcroat A -40
-KPX Dcroat Aacute -40
-KPX Dcroat Abreve -40
-KPX Dcroat Acircumflex -40
-KPX Dcroat Adieresis -40
-KPX Dcroat Agrave -40
-KPX Dcroat Amacron -40
-KPX Dcroat Aogonek -40
-KPX Dcroat Aring -40
-KPX Dcroat Atilde -40
-KPX Dcroat V -40
-KPX Dcroat W -40
-KPX Dcroat Y -70
-KPX Dcroat Yacute -70
-KPX Dcroat Ydieresis -70
-KPX Dcroat comma -30
-KPX Dcroat period -30
-KPX F A -80
-KPX F Aacute -80
-KPX F Abreve -80
-KPX F Acircumflex -80
-KPX F Adieresis -80
-KPX F Agrave -80
-KPX F Amacron -80
-KPX F Aogonek -80
-KPX F Aring -80
-KPX F Atilde -80
-KPX F a -20
-KPX F aacute -20
-KPX F abreve -20
-KPX F acircumflex -20
-KPX F adieresis -20
-KPX F agrave -20
-KPX F amacron -20
-KPX F aogonek -20
-KPX F aring -20
-KPX F atilde -20
-KPX F comma -100
-KPX F period -100
-KPX J A -20
-KPX J Aacute -20
-KPX J Abreve -20
-KPX J Acircumflex -20
-KPX J Adieresis -20
-KPX J Agrave -20
-KPX J Amacron -20
-KPX J Aogonek -20
-KPX J Aring -20
-KPX J Atilde -20
-KPX J comma -20
-KPX J period -20
-KPX J u -20
-KPX J uacute -20
-KPX J ucircumflex -20
-KPX J udieresis -20
-KPX J ugrave -20
-KPX J uhungarumlaut -20
-KPX J umacron -20
-KPX J uogonek -20
-KPX J uring -20
-KPX K O -30
-KPX K Oacute -30
-KPX K Ocircumflex -30
-KPX K Odieresis -30
-KPX K Ograve -30
-KPX K Ohungarumlaut -30
-KPX K Omacron -30
-KPX K Oslash -30
-KPX K Otilde -30
-KPX K e -15
-KPX K eacute -15
-KPX K ecaron -15
-KPX K ecircumflex -15
-KPX K edieresis -15
-KPX K edotaccent -15
-KPX K egrave -15
-KPX K emacron -15
-KPX K eogonek -15
-KPX K o -35
-KPX K oacute -35
-KPX K ocircumflex -35
-KPX K odieresis -35
-KPX K ograve -35
-KPX K ohungarumlaut -35
-KPX K omacron -35
-KPX K oslash -35
-KPX K otilde -35
-KPX K u -30
-KPX K uacute -30
-KPX K ucircumflex -30
-KPX K udieresis -30
-KPX K ugrave -30
-KPX K uhungarumlaut -30
-KPX K umacron -30
-KPX K uogonek -30
-KPX K uring -30
-KPX K y -40
-KPX K yacute -40
-KPX K ydieresis -40
-KPX Kcommaaccent O -30
-KPX Kcommaaccent Oacute -30
-KPX Kcommaaccent Ocircumflex -30
-KPX Kcommaaccent Odieresis -30
-KPX Kcommaaccent Ograve -30
-KPX Kcommaaccent Ohungarumlaut -30
-KPX Kcommaaccent Omacron -30
-KPX Kcommaaccent Oslash -30
-KPX Kcommaaccent Otilde -30
-KPX Kcommaaccent e -15
-KPX Kcommaaccent eacute -15
-KPX Kcommaaccent ecaron -15
-KPX Kcommaaccent ecircumflex -15
-KPX Kcommaaccent edieresis -15
-KPX Kcommaaccent edotaccent -15
-KPX Kcommaaccent egrave -15
-KPX Kcommaaccent emacron -15
-KPX Kcommaaccent eogonek -15
-KPX Kcommaaccent o -35
-KPX Kcommaaccent oacute -35
-KPX Kcommaaccent ocircumflex -35
-KPX Kcommaaccent odieresis -35
-KPX Kcommaaccent ograve -35
-KPX Kcommaaccent ohungarumlaut -35
-KPX Kcommaaccent omacron -35
-KPX Kcommaaccent oslash -35
-KPX Kcommaaccent otilde -35
-KPX Kcommaaccent u -30
-KPX Kcommaaccent uacute -30
-KPX Kcommaaccent ucircumflex -30
-KPX Kcommaaccent udieresis -30
-KPX Kcommaaccent ugrave -30
-KPX Kcommaaccent uhungarumlaut -30
-KPX Kcommaaccent umacron -30
-KPX Kcommaaccent uogonek -30
-KPX Kcommaaccent uring -30
-KPX Kcommaaccent y -40
-KPX Kcommaaccent yacute -40
-KPX Kcommaaccent ydieresis -40
-KPX L T -90
-KPX L Tcaron -90
-KPX L Tcommaaccent -90
-KPX L V -110
-KPX L W -80
-KPX L Y -120
-KPX L Yacute -120
-KPX L Ydieresis -120
-KPX L quotedblright -140
-KPX L quoteright -140
-KPX L y -30
-KPX L yacute -30
-KPX L ydieresis -30
-KPX Lacute T -90
-KPX Lacute Tcaron -90
-KPX Lacute Tcommaaccent -90
-KPX Lacute V -110
-KPX Lacute W -80
-KPX Lacute Y -120
-KPX Lacute Yacute -120
-KPX Lacute Ydieresis -120
-KPX Lacute quotedblright -140
-KPX Lacute quoteright -140
-KPX Lacute y -30
-KPX Lacute yacute -30
-KPX Lacute ydieresis -30
-KPX Lcommaaccent T -90
-KPX Lcommaaccent Tcaron -90
-KPX Lcommaaccent Tcommaaccent -90
-KPX Lcommaaccent V -110
-KPX Lcommaaccent W -80
-KPX Lcommaaccent Y -120
-KPX Lcommaaccent Yacute -120
-KPX Lcommaaccent Ydieresis -120
-KPX Lcommaaccent quotedblright -140
-KPX Lcommaaccent quoteright -140
-KPX Lcommaaccent y -30
-KPX Lcommaaccent yacute -30
-KPX Lcommaaccent ydieresis -30
-KPX Lslash T -90
-KPX Lslash Tcaron -90
-KPX Lslash Tcommaaccent -90
-KPX Lslash V -110
-KPX Lslash W -80
-KPX Lslash Y -120
-KPX Lslash Yacute -120
-KPX Lslash Ydieresis -120
-KPX Lslash quotedblright -140
-KPX Lslash quoteright -140
-KPX Lslash y -30
-KPX Lslash yacute -30
-KPX Lslash ydieresis -30
-KPX O A -50
-KPX O Aacute -50
-KPX O Abreve -50
-KPX O Acircumflex -50
-KPX O Adieresis -50
-KPX O Agrave -50
-KPX O Amacron -50
-KPX O Aogonek -50
-KPX O Aring -50
-KPX O Atilde -50
-KPX O T -40
-KPX O Tcaron -40
-KPX O Tcommaaccent -40
-KPX O V -50
-KPX O W -50
-KPX O X -50
-KPX O Y -70
-KPX O Yacute -70
-KPX O Ydieresis -70
-KPX O comma -40
-KPX O period -40
-KPX Oacute A -50
-KPX Oacute Aacute -50
-KPX Oacute Abreve -50
-KPX Oacute Acircumflex -50
-KPX Oacute Adieresis -50
-KPX Oacute Agrave -50
-KPX Oacute Amacron -50
-KPX Oacute Aogonek -50
-KPX Oacute Aring -50
-KPX Oacute Atilde -50
-KPX Oacute T -40
-KPX Oacute Tcaron -40
-KPX Oacute Tcommaaccent -40
-KPX Oacute V -50
-KPX Oacute W -50
-KPX Oacute X -50
-KPX Oacute Y -70
-KPX Oacute Yacute -70
-KPX Oacute Ydieresis -70
-KPX Oacute comma -40
-KPX Oacute period -40
-KPX Ocircumflex A -50
-KPX Ocircumflex Aacute -50
-KPX Ocircumflex Abreve -50
-KPX Ocircumflex Acircumflex -50
-KPX Ocircumflex Adieresis -50
-KPX Ocircumflex Agrave -50
-KPX Ocircumflex Amacron -50
-KPX Ocircumflex Aogonek -50
-KPX Ocircumflex Aring -50
-KPX Ocircumflex Atilde -50
-KPX Ocircumflex T -40
-KPX Ocircumflex Tcaron -40
-KPX Ocircumflex Tcommaaccent -40
-KPX Ocircumflex V -50
-KPX Ocircumflex W -50
-KPX Ocircumflex X -50
-KPX Ocircumflex Y -70
-KPX Ocircumflex Yacute -70
-KPX Ocircumflex Ydieresis -70
-KPX Ocircumflex comma -40
-KPX Ocircumflex period -40
-KPX Odieresis A -50
-KPX Odieresis Aacute -50
-KPX Odieresis Abreve -50
-KPX Odieresis Acircumflex -50
-KPX Odieresis Adieresis -50
-KPX Odieresis Agrave -50
-KPX Odieresis Amacron -50
-KPX Odieresis Aogonek -50
-KPX Odieresis Aring -50
-KPX Odieresis Atilde -50
-KPX Odieresis T -40
-KPX Odieresis Tcaron -40
-KPX Odieresis Tcommaaccent -40
-KPX Odieresis V -50
-KPX Odieresis W -50
-KPX Odieresis X -50
-KPX Odieresis Y -70
-KPX Odieresis Yacute -70
-KPX Odieresis Ydieresis -70
-KPX Odieresis comma -40
-KPX Odieresis period -40
-KPX Ograve A -50
-KPX Ograve Aacute -50
-KPX Ograve Abreve -50
-KPX Ograve Acircumflex -50
-KPX Ograve Adieresis -50
-KPX Ograve Agrave -50
-KPX Ograve Amacron -50
-KPX Ograve Aogonek -50
-KPX Ograve Aring -50
-KPX Ograve Atilde -50
-KPX Ograve T -40
-KPX Ograve Tcaron -40
-KPX Ograve Tcommaaccent -40
-KPX Ograve V -50
-KPX Ograve W -50
-KPX Ograve X -50
-KPX Ograve Y -70
-KPX Ograve Yacute -70
-KPX Ograve Ydieresis -70
-KPX Ograve comma -40
-KPX Ograve period -40
-KPX Ohungarumlaut A -50
-KPX Ohungarumlaut Aacute -50
-KPX Ohungarumlaut Abreve -50
-KPX Ohungarumlaut Acircumflex -50
-KPX Ohungarumlaut Adieresis -50
-KPX Ohungarumlaut Agrave -50
-KPX Ohungarumlaut Amacron -50
-KPX Ohungarumlaut Aogonek -50
-KPX Ohungarumlaut Aring -50
-KPX Ohungarumlaut Atilde -50
-KPX Ohungarumlaut T -40
-KPX Ohungarumlaut Tcaron -40
-KPX Ohungarumlaut Tcommaaccent -40
-KPX Ohungarumlaut V -50
-KPX Ohungarumlaut W -50
-KPX Ohungarumlaut X -50
-KPX Ohungarumlaut Y -70
-KPX Ohungarumlaut Yacute -70
-KPX Ohungarumlaut Ydieresis -70
-KPX Ohungarumlaut comma -40
-KPX Ohungarumlaut period -40
-KPX Omacron A -50
-KPX Omacron Aacute -50
-KPX Omacron Abreve -50
-KPX Omacron Acircumflex -50
-KPX Omacron Adieresis -50
-KPX Omacron Agrave -50
-KPX Omacron Amacron -50
-KPX Omacron Aogonek -50
-KPX Omacron Aring -50
-KPX Omacron Atilde -50
-KPX Omacron T -40
-KPX Omacron Tcaron -40
-KPX Omacron Tcommaaccent -40
-KPX Omacron V -50
-KPX Omacron W -50
-KPX Omacron X -50
-KPX Omacron Y -70
-KPX Omacron Yacute -70
-KPX Omacron Ydieresis -70
-KPX Omacron comma -40
-KPX Omacron period -40
-KPX Oslash A -50
-KPX Oslash Aacute -50
-KPX Oslash Abreve -50
-KPX Oslash Acircumflex -50
-KPX Oslash Adieresis -50
-KPX Oslash Agrave -50
-KPX Oslash Amacron -50
-KPX Oslash Aogonek -50
-KPX Oslash Aring -50
-KPX Oslash Atilde -50
-KPX Oslash T -40
-KPX Oslash Tcaron -40
-KPX Oslash Tcommaaccent -40
-KPX Oslash V -50
-KPX Oslash W -50
-KPX Oslash X -50
-KPX Oslash Y -70
-KPX Oslash Yacute -70
-KPX Oslash Ydieresis -70
-KPX Oslash comma -40
-KPX Oslash period -40
-KPX Otilde A -50
-KPX Otilde Aacute -50
-KPX Otilde Abreve -50
-KPX Otilde Acircumflex -50
-KPX Otilde Adieresis -50
-KPX Otilde Agrave -50
-KPX Otilde Amacron -50
-KPX Otilde Aogonek -50
-KPX Otilde Aring -50
-KPX Otilde Atilde -50
-KPX Otilde T -40
-KPX Otilde Tcaron -40
-KPX Otilde Tcommaaccent -40
-KPX Otilde V -50
-KPX Otilde W -50
-KPX Otilde X -50
-KPX Otilde Y -70
-KPX Otilde Yacute -70
-KPX Otilde Ydieresis -70
-KPX Otilde comma -40
-KPX Otilde period -40
-KPX P A -100
-KPX P Aacute -100
-KPX P Abreve -100
-KPX P Acircumflex -100
-KPX P Adieresis -100
-KPX P Agrave -100
-KPX P Amacron -100
-KPX P Aogonek -100
-KPX P Aring -100
-KPX P Atilde -100
-KPX P a -30
-KPX P aacute -30
-KPX P abreve -30
-KPX P acircumflex -30
-KPX P adieresis -30
-KPX P agrave -30
-KPX P amacron -30
-KPX P aogonek -30
-KPX P aring -30
-KPX P atilde -30
-KPX P comma -120
-KPX P e -30
-KPX P eacute -30
-KPX P ecaron -30
-KPX P ecircumflex -30
-KPX P edieresis -30
-KPX P edotaccent -30
-KPX P egrave -30
-KPX P emacron -30
-KPX P eogonek -30
-KPX P o -40
-KPX P oacute -40
-KPX P ocircumflex -40
-KPX P odieresis -40
-KPX P ograve -40
-KPX P ohungarumlaut -40
-KPX P omacron -40
-KPX P oslash -40
-KPX P otilde -40
-KPX P period -120
-KPX Q U -10
-KPX Q Uacute -10
-KPX Q Ucircumflex -10
-KPX Q Udieresis -10
-KPX Q Ugrave -10
-KPX Q Uhungarumlaut -10
-KPX Q Umacron -10
-KPX Q Uogonek -10
-KPX Q Uring -10
-KPX Q comma 20
-KPX Q period 20
-KPX R O -20
-KPX R Oacute -20
-KPX R Ocircumflex -20
-KPX R Odieresis -20
-KPX R Ograve -20
-KPX R Ohungarumlaut -20
-KPX R Omacron -20
-KPX R Oslash -20
-KPX R Otilde -20
-KPX R T -20
-KPX R Tcaron -20
-KPX R Tcommaaccent -20
-KPX R U -20
-KPX R Uacute -20
-KPX R Ucircumflex -20
-KPX R Udieresis -20
-KPX R Ugrave -20
-KPX R Uhungarumlaut -20
-KPX R Umacron -20
-KPX R Uogonek -20
-KPX R Uring -20
-KPX R V -50
-KPX R W -40
-KPX R Y -50
-KPX R Yacute -50
-KPX R Ydieresis -50
-KPX Racute O -20
-KPX Racute Oacute -20
-KPX Racute Ocircumflex -20
-KPX Racute Odieresis -20
-KPX Racute Ograve -20
-KPX Racute Ohungarumlaut -20
-KPX Racute Omacron -20
-KPX Racute Oslash -20
-KPX Racute Otilde -20
-KPX Racute T -20
-KPX Racute Tcaron -20
-KPX Racute Tcommaaccent -20
-KPX Racute U -20
-KPX Racute Uacute -20
-KPX Racute Ucircumflex -20
-KPX Racute Udieresis -20
-KPX Racute Ugrave -20
-KPX Racute Uhungarumlaut -20
-KPX Racute Umacron -20
-KPX Racute Uogonek -20
-KPX Racute Uring -20
-KPX Racute V -50
-KPX Racute W -40
-KPX Racute Y -50
-KPX Racute Yacute -50
-KPX Racute Ydieresis -50
-KPX Rcaron O -20
-KPX Rcaron Oacute -20
-KPX Rcaron Ocircumflex -20
-KPX Rcaron Odieresis -20
-KPX Rcaron Ograve -20
-KPX Rcaron Ohungarumlaut -20
-KPX Rcaron Omacron -20
-KPX Rcaron Oslash -20
-KPX Rcaron Otilde -20
-KPX Rcaron T -20
-KPX Rcaron Tcaron -20
-KPX Rcaron Tcommaaccent -20
-KPX Rcaron U -20
-KPX Rcaron Uacute -20
-KPX Rcaron Ucircumflex -20
-KPX Rcaron Udieresis -20
-KPX Rcaron Ugrave -20
-KPX Rcaron Uhungarumlaut -20
-KPX Rcaron Umacron -20
-KPX Rcaron Uogonek -20
-KPX Rcaron Uring -20
-KPX Rcaron V -50
-KPX Rcaron W -40
-KPX Rcaron Y -50
-KPX Rcaron Yacute -50
-KPX Rcaron Ydieresis -50
-KPX Rcommaaccent O -20
-KPX Rcommaaccent Oacute -20
-KPX Rcommaaccent Ocircumflex -20
-KPX Rcommaaccent Odieresis -20
-KPX Rcommaaccent Ograve -20
-KPX Rcommaaccent Ohungarumlaut -20
-KPX Rcommaaccent Omacron -20
-KPX Rcommaaccent Oslash -20
-KPX Rcommaaccent Otilde -20
-KPX Rcommaaccent T -20
-KPX Rcommaaccent Tcaron -20
-KPX Rcommaaccent Tcommaaccent -20
-KPX Rcommaaccent U -20
-KPX Rcommaaccent Uacute -20
-KPX Rcommaaccent Ucircumflex -20
-KPX Rcommaaccent Udieresis -20
-KPX Rcommaaccent Ugrave -20
-KPX Rcommaaccent Uhungarumlaut -20
-KPX Rcommaaccent Umacron -20
-KPX Rcommaaccent Uogonek -20
-KPX Rcommaaccent Uring -20
-KPX Rcommaaccent V -50
-KPX Rcommaaccent W -40
-KPX Rcommaaccent Y -50
-KPX Rcommaaccent Yacute -50
-KPX Rcommaaccent Ydieresis -50
-KPX T A -90
-KPX T Aacute -90
-KPX T Abreve -90
-KPX T Acircumflex -90
-KPX T Adieresis -90
-KPX T Agrave -90
-KPX T Amacron -90
-KPX T Aogonek -90
-KPX T Aring -90
-KPX T Atilde -90
-KPX T O -40
-KPX T Oacute -40
-KPX T Ocircumflex -40
-KPX T Odieresis -40
-KPX T Ograve -40
-KPX T Ohungarumlaut -40
-KPX T Omacron -40
-KPX T Oslash -40
-KPX T Otilde -40
-KPX T a -80
-KPX T aacute -80
-KPX T abreve -80
-KPX T acircumflex -80
-KPX T adieresis -80
-KPX T agrave -80
-KPX T amacron -80
-KPX T aogonek -80
-KPX T aring -80
-KPX T atilde -80
-KPX T colon -40
-KPX T comma -80
-KPX T e -60
-KPX T eacute -60
-KPX T ecaron -60
-KPX T ecircumflex -60
-KPX T edieresis -60
-KPX T edotaccent -60
-KPX T egrave -60
-KPX T emacron -60
-KPX T eogonek -60
-KPX T hyphen -120
-KPX T o -80
-KPX T oacute -80
-KPX T ocircumflex -80
-KPX T odieresis -80
-KPX T ograve -80
-KPX T ohungarumlaut -80
-KPX T omacron -80
-KPX T oslash -80
-KPX T otilde -80
-KPX T period -80
-KPX T r -80
-KPX T racute -80
-KPX T rcommaaccent -80
-KPX T semicolon -40
-KPX T u -90
-KPX T uacute -90
-KPX T ucircumflex -90
-KPX T udieresis -90
-KPX T ugrave -90
-KPX T uhungarumlaut -90
-KPX T umacron -90
-KPX T uogonek -90
-KPX T uring -90
-KPX T w -60
-KPX T y -60
-KPX T yacute -60
-KPX T ydieresis -60
-KPX Tcaron A -90
-KPX Tcaron Aacute -90
-KPX Tcaron Abreve -90
-KPX Tcaron Acircumflex -90
-KPX Tcaron Adieresis -90
-KPX Tcaron Agrave -90
-KPX Tcaron Amacron -90
-KPX Tcaron Aogonek -90
-KPX Tcaron Aring -90
-KPX Tcaron Atilde -90
-KPX Tcaron O -40
-KPX Tcaron Oacute -40
-KPX Tcaron Ocircumflex -40
-KPX Tcaron Odieresis -40
-KPX Tcaron Ograve -40
-KPX Tcaron Ohungarumlaut -40
-KPX Tcaron Omacron -40
-KPX Tcaron Oslash -40
-KPX Tcaron Otilde -40
-KPX Tcaron a -80
-KPX Tcaron aacute -80
-KPX Tcaron abreve -80
-KPX Tcaron acircumflex -80
-KPX Tcaron adieresis -80
-KPX Tcaron agrave -80
-KPX Tcaron amacron -80
-KPX Tcaron aogonek -80
-KPX Tcaron aring -80
-KPX Tcaron atilde -80
-KPX Tcaron colon -40
-KPX Tcaron comma -80
-KPX Tcaron e -60
-KPX Tcaron eacute -60
-KPX Tcaron ecaron -60
-KPX Tcaron ecircumflex -60
-KPX Tcaron edieresis -60
-KPX Tcaron edotaccent -60
-KPX Tcaron egrave -60
-KPX Tcaron emacron -60
-KPX Tcaron eogonek -60
-KPX Tcaron hyphen -120
-KPX Tcaron o -80
-KPX Tcaron oacute -80
-KPX Tcaron ocircumflex -80
-KPX Tcaron odieresis -80
-KPX Tcaron ograve -80
-KPX Tcaron ohungarumlaut -80
-KPX Tcaron omacron -80
-KPX Tcaron oslash -80
-KPX Tcaron otilde -80
-KPX Tcaron period -80
-KPX Tcaron r -80
-KPX Tcaron racute -80
-KPX Tcaron rcommaaccent -80
-KPX Tcaron semicolon -40
-KPX Tcaron u -90
-KPX Tcaron uacute -90
-KPX Tcaron ucircumflex -90
-KPX Tcaron udieresis -90
-KPX Tcaron ugrave -90
-KPX Tcaron uhungarumlaut -90
-KPX Tcaron umacron -90
-KPX Tcaron uogonek -90
-KPX Tcaron uring -90
-KPX Tcaron w -60
-KPX Tcaron y -60
-KPX Tcaron yacute -60
-KPX Tcaron ydieresis -60
-KPX Tcommaaccent A -90
-KPX Tcommaaccent Aacute -90
-KPX Tcommaaccent Abreve -90
-KPX Tcommaaccent Acircumflex -90
-KPX Tcommaaccent Adieresis -90
-KPX Tcommaaccent Agrave -90
-KPX Tcommaaccent Amacron -90
-KPX Tcommaaccent Aogonek -90
-KPX Tcommaaccent Aring -90
-KPX Tcommaaccent Atilde -90
-KPX Tcommaaccent O -40
-KPX Tcommaaccent Oacute -40
-KPX Tcommaaccent Ocircumflex -40
-KPX Tcommaaccent Odieresis -40
-KPX Tcommaaccent Ograve -40
-KPX Tcommaaccent Ohungarumlaut -40
-KPX Tcommaaccent Omacron -40
-KPX Tcommaaccent Oslash -40
-KPX Tcommaaccent Otilde -40
-KPX Tcommaaccent a -80
-KPX Tcommaaccent aacute -80
-KPX Tcommaaccent abreve -80
-KPX Tcommaaccent acircumflex -80
-KPX Tcommaaccent adieresis -80
-KPX Tcommaaccent agrave -80
-KPX Tcommaaccent amacron -80
-KPX Tcommaaccent aogonek -80
-KPX Tcommaaccent aring -80
-KPX Tcommaaccent atilde -80
-KPX Tcommaaccent colon -40
-KPX Tcommaaccent comma -80
-KPX Tcommaaccent e -60
-KPX Tcommaaccent eacute -60
-KPX Tcommaaccent ecaron -60
-KPX Tcommaaccent ecircumflex -60
-KPX Tcommaaccent edieresis -60
-KPX Tcommaaccent edotaccent -60
-KPX Tcommaaccent egrave -60
-KPX Tcommaaccent emacron -60
-KPX Tcommaaccent eogonek -60
-KPX Tcommaaccent hyphen -120
-KPX Tcommaaccent o -80
-KPX Tcommaaccent oacute -80
-KPX Tcommaaccent ocircumflex -80
-KPX Tcommaaccent odieresis -80
-KPX Tcommaaccent ograve -80
-KPX Tcommaaccent ohungarumlaut -80
-KPX Tcommaaccent omacron -80
-KPX Tcommaaccent oslash -80
-KPX Tcommaaccent otilde -80
-KPX Tcommaaccent period -80
-KPX Tcommaaccent r -80
-KPX Tcommaaccent racute -80
-KPX Tcommaaccent rcommaaccent -80
-KPX Tcommaaccent semicolon -40
-KPX Tcommaaccent u -90
-KPX Tcommaaccent uacute -90
-KPX Tcommaaccent ucircumflex -90
-KPX Tcommaaccent udieresis -90
-KPX Tcommaaccent ugrave -90
-KPX Tcommaaccent uhungarumlaut -90
-KPX Tcommaaccent umacron -90
-KPX Tcommaaccent uogonek -90
-KPX Tcommaaccent uring -90
-KPX Tcommaaccent w -60
-KPX Tcommaaccent y -60
-KPX Tcommaaccent yacute -60
-KPX Tcommaaccent ydieresis -60
-KPX U A -50
-KPX U Aacute -50
-KPX U Abreve -50
-KPX U Acircumflex -50
-KPX U Adieresis -50
-KPX U Agrave -50
-KPX U Amacron -50
-KPX U Aogonek -50
-KPX U Aring -50
-KPX U Atilde -50
-KPX U comma -30
-KPX U period -30
-KPX Uacute A -50
-KPX Uacute Aacute -50
-KPX Uacute Abreve -50
-KPX Uacute Acircumflex -50
-KPX Uacute Adieresis -50
-KPX Uacute Agrave -50
-KPX Uacute Amacron -50
-KPX Uacute Aogonek -50
-KPX Uacute Aring -50
-KPX Uacute Atilde -50
-KPX Uacute comma -30
-KPX Uacute period -30
-KPX Ucircumflex A -50
-KPX Ucircumflex Aacute -50
-KPX Ucircumflex Abreve -50
-KPX Ucircumflex Acircumflex -50
-KPX Ucircumflex Adieresis -50
-KPX Ucircumflex Agrave -50
-KPX Ucircumflex Amacron -50
-KPX Ucircumflex Aogonek -50
-KPX Ucircumflex Aring -50
-KPX Ucircumflex Atilde -50
-KPX Ucircumflex comma -30
-KPX Ucircumflex period -30
-KPX Udieresis A -50
-KPX Udieresis Aacute -50
-KPX Udieresis Abreve -50
-KPX Udieresis Acircumflex -50
-KPX Udieresis Adieresis -50
-KPX Udieresis Agrave -50
-KPX Udieresis Amacron -50
-KPX Udieresis Aogonek -50
-KPX Udieresis Aring -50
-KPX Udieresis Atilde -50
-KPX Udieresis comma -30
-KPX Udieresis period -30
-KPX Ugrave A -50
-KPX Ugrave Aacute -50
-KPX Ugrave Abreve -50
-KPX Ugrave Acircumflex -50
-KPX Ugrave Adieresis -50
-KPX Ugrave Agrave -50
-KPX Ugrave Amacron -50
-KPX Ugrave Aogonek -50
-KPX Ugrave Aring -50
-KPX Ugrave Atilde -50
-KPX Ugrave comma -30
-KPX Ugrave period -30
-KPX Uhungarumlaut A -50
-KPX Uhungarumlaut Aacute -50
-KPX Uhungarumlaut Abreve -50
-KPX Uhungarumlaut Acircumflex -50
-KPX Uhungarumlaut Adieresis -50
-KPX Uhungarumlaut Agrave -50
-KPX Uhungarumlaut Amacron -50
-KPX Uhungarumlaut Aogonek -50
-KPX Uhungarumlaut Aring -50
-KPX Uhungarumlaut Atilde -50
-KPX Uhungarumlaut comma -30
-KPX Uhungarumlaut period -30
-KPX Umacron A -50
-KPX Umacron Aacute -50
-KPX Umacron Abreve -50
-KPX Umacron Acircumflex -50
-KPX Umacron Adieresis -50
-KPX Umacron Agrave -50
-KPX Umacron Amacron -50
-KPX Umacron Aogonek -50
-KPX Umacron Aring -50
-KPX Umacron Atilde -50
-KPX Umacron comma -30
-KPX Umacron period -30
-KPX Uogonek A -50
-KPX Uogonek Aacute -50
-KPX Uogonek Abreve -50
-KPX Uogonek Acircumflex -50
-KPX Uogonek Adieresis -50
-KPX Uogonek Agrave -50
-KPX Uogonek Amacron -50
-KPX Uogonek Aogonek -50
-KPX Uogonek Aring -50
-KPX Uogonek Atilde -50
-KPX Uogonek comma -30
-KPX Uogonek period -30
-KPX Uring A -50
-KPX Uring Aacute -50
-KPX Uring Abreve -50
-KPX Uring Acircumflex -50
-KPX Uring Adieresis -50
-KPX Uring Agrave -50
-KPX Uring Amacron -50
-KPX Uring Aogonek -50
-KPX Uring Aring -50
-KPX Uring Atilde -50
-KPX Uring comma -30
-KPX Uring period -30
-KPX V A -80
-KPX V Aacute -80
-KPX V Abreve -80
-KPX V Acircumflex -80
-KPX V Adieresis -80
-KPX V Agrave -80
-KPX V Amacron -80
-KPX V Aogonek -80
-KPX V Aring -80
-KPX V Atilde -80
-KPX V G -50
-KPX V Gbreve -50
-KPX V Gcommaaccent -50
-KPX V O -50
-KPX V Oacute -50
-KPX V Ocircumflex -50
-KPX V Odieresis -50
-KPX V Ograve -50
-KPX V Ohungarumlaut -50
-KPX V Omacron -50
-KPX V Oslash -50
-KPX V Otilde -50
-KPX V a -60
-KPX V aacute -60
-KPX V abreve -60
-KPX V acircumflex -60
-KPX V adieresis -60
-KPX V agrave -60
-KPX V amacron -60
-KPX V aogonek -60
-KPX V aring -60
-KPX V atilde -60
-KPX V colon -40
-KPX V comma -120
-KPX V e -50
-KPX V eacute -50
-KPX V ecaron -50
-KPX V ecircumflex -50
-KPX V edieresis -50
-KPX V edotaccent -50
-KPX V egrave -50
-KPX V emacron -50
-KPX V eogonek -50
-KPX V hyphen -80
-KPX V o -90
-KPX V oacute -90
-KPX V ocircumflex -90
-KPX V odieresis -90
-KPX V ograve -90
-KPX V ohungarumlaut -90
-KPX V omacron -90
-KPX V oslash -90
-KPX V otilde -90
-KPX V period -120
-KPX V semicolon -40
-KPX V u -60
-KPX V uacute -60
-KPX V ucircumflex -60
-KPX V udieresis -60
-KPX V ugrave -60
-KPX V uhungarumlaut -60
-KPX V umacron -60
-KPX V uogonek -60
-KPX V uring -60
-KPX W A -60
-KPX W Aacute -60
-KPX W Abreve -60
-KPX W Acircumflex -60
-KPX W Adieresis -60
-KPX W Agrave -60
-KPX W Amacron -60
-KPX W Aogonek -60
-KPX W Aring -60
-KPX W Atilde -60
-KPX W O -20
-KPX W Oacute -20
-KPX W Ocircumflex -20
-KPX W Odieresis -20
-KPX W Ograve -20
-KPX W Ohungarumlaut -20
-KPX W Omacron -20
-KPX W Oslash -20
-KPX W Otilde -20
-KPX W a -40
-KPX W aacute -40
-KPX W abreve -40
-KPX W acircumflex -40
-KPX W adieresis -40
-KPX W agrave -40
-KPX W amacron -40
-KPX W aogonek -40
-KPX W aring -40
-KPX W atilde -40
-KPX W colon -10
-KPX W comma -80
-KPX W e -35
-KPX W eacute -35
-KPX W ecaron -35
-KPX W ecircumflex -35
-KPX W edieresis -35
-KPX W edotaccent -35
-KPX W egrave -35
-KPX W emacron -35
-KPX W eogonek -35
-KPX W hyphen -40
-KPX W o -60
-KPX W oacute -60
-KPX W ocircumflex -60
-KPX W odieresis -60
-KPX W ograve -60
-KPX W ohungarumlaut -60
-KPX W omacron -60
-KPX W oslash -60
-KPX W otilde -60
-KPX W period -80
-KPX W semicolon -10
-KPX W u -45
-KPX W uacute -45
-KPX W ucircumflex -45
-KPX W udieresis -45
-KPX W ugrave -45
-KPX W uhungarumlaut -45
-KPX W umacron -45
-KPX W uogonek -45
-KPX W uring -45
-KPX W y -20
-KPX W yacute -20
-KPX W ydieresis -20
-KPX Y A -110
-KPX Y Aacute -110
-KPX Y Abreve -110
-KPX Y Acircumflex -110
-KPX Y Adieresis -110
-KPX Y Agrave -110
-KPX Y Amacron -110
-KPX Y Aogonek -110
-KPX Y Aring -110
-KPX Y Atilde -110
-KPX Y O -70
-KPX Y Oacute -70
-KPX Y Ocircumflex -70
-KPX Y Odieresis -70
-KPX Y Ograve -70
-KPX Y Ohungarumlaut -70
-KPX Y Omacron -70
-KPX Y Oslash -70
-KPX Y Otilde -70
-KPX Y a -90
-KPX Y aacute -90
-KPX Y abreve -90
-KPX Y acircumflex -90
-KPX Y adieresis -90
-KPX Y agrave -90
-KPX Y amacron -90
-KPX Y aogonek -90
-KPX Y aring -90
-KPX Y atilde -90
-KPX Y colon -50
-KPX Y comma -100
-KPX Y e -80
-KPX Y eacute -80
-KPX Y ecaron -80
-KPX Y ecircumflex -80
-KPX Y edieresis -80
-KPX Y edotaccent -80
-KPX Y egrave -80
-KPX Y emacron -80
-KPX Y eogonek -80
-KPX Y o -100
-KPX Y oacute -100
-KPX Y ocircumflex -100
-KPX Y odieresis -100
-KPX Y ograve -100
-KPX Y ohungarumlaut -100
-KPX Y omacron -100
-KPX Y oslash -100
-KPX Y otilde -100
-KPX Y period -100
-KPX Y semicolon -50
-KPX Y u -100
-KPX Y uacute -100
-KPX Y ucircumflex -100
-KPX Y udieresis -100
-KPX Y ugrave -100
-KPX Y uhungarumlaut -100
-KPX Y umacron -100
-KPX Y uogonek -100
-KPX Y uring -100
-KPX Yacute A -110
-KPX Yacute Aacute -110
-KPX Yacute Abreve -110
-KPX Yacute Acircumflex -110
-KPX Yacute Adieresis -110
-KPX Yacute Agrave -110
-KPX Yacute Amacron -110
-KPX Yacute Aogonek -110
-KPX Yacute Aring -110
-KPX Yacute Atilde -110
-KPX Yacute O -70
-KPX Yacute Oacute -70
-KPX Yacute Ocircumflex -70
-KPX Yacute Odieresis -70
-KPX Yacute Ograve -70
-KPX Yacute Ohungarumlaut -70
-KPX Yacute Omacron -70
-KPX Yacute Oslash -70
-KPX Yacute Otilde -70
-KPX Yacute a -90
-KPX Yacute aacute -90
-KPX Yacute abreve -90
-KPX Yacute acircumflex -90
-KPX Yacute adieresis -90
-KPX Yacute agrave -90
-KPX Yacute amacron -90
-KPX Yacute aogonek -90
-KPX Yacute aring -90
-KPX Yacute atilde -90
-KPX Yacute colon -50
-KPX Yacute comma -100
-KPX Yacute e -80
-KPX Yacute eacute -80
-KPX Yacute ecaron -80
-KPX Yacute ecircumflex -80
-KPX Yacute edieresis -80
-KPX Yacute edotaccent -80
-KPX Yacute egrave -80
-KPX Yacute emacron -80
-KPX Yacute eogonek -80
-KPX Yacute o -100
-KPX Yacute oacute -100
-KPX Yacute ocircumflex -100
-KPX Yacute odieresis -100
-KPX Yacute ograve -100
-KPX Yacute ohungarumlaut -100
-KPX Yacute omacron -100
-KPX Yacute oslash -100
-KPX Yacute otilde -100
-KPX Yacute period -100
-KPX Yacute semicolon -50
-KPX Yacute u -100
-KPX Yacute uacute -100
-KPX Yacute ucircumflex -100
-KPX Yacute udieresis -100
-KPX Yacute ugrave -100
-KPX Yacute uhungarumlaut -100
-KPX Yacute umacron -100
-KPX Yacute uogonek -100
-KPX Yacute uring -100
-KPX Ydieresis A -110
-KPX Ydieresis Aacute -110
-KPX Ydieresis Abreve -110
-KPX Ydieresis Acircumflex -110
-KPX Ydieresis Adieresis -110
-KPX Ydieresis Agrave -110
-KPX Ydieresis Amacron -110
-KPX Ydieresis Aogonek -110
-KPX Ydieresis Aring -110
-KPX Ydieresis Atilde -110
-KPX Ydieresis O -70
-KPX Ydieresis Oacute -70
-KPX Ydieresis Ocircumflex -70
-KPX Ydieresis Odieresis -70
-KPX Ydieresis Ograve -70
-KPX Ydieresis Ohungarumlaut -70
-KPX Ydieresis Omacron -70
-KPX Ydieresis Oslash -70
-KPX Ydieresis Otilde -70
-KPX Ydieresis a -90
-KPX Ydieresis aacute -90
-KPX Ydieresis abreve -90
-KPX Ydieresis acircumflex -90
-KPX Ydieresis adieresis -90
-KPX Ydieresis agrave -90
-KPX Ydieresis amacron -90
-KPX Ydieresis aogonek -90
-KPX Ydieresis aring -90
-KPX Ydieresis atilde -90
-KPX Ydieresis colon -50
-KPX Ydieresis comma -100
-KPX Ydieresis e -80
-KPX Ydieresis eacute -80
-KPX Ydieresis ecaron -80
-KPX Ydieresis ecircumflex -80
-KPX Ydieresis edieresis -80
-KPX Ydieresis edotaccent -80
-KPX Ydieresis egrave -80
-KPX Ydieresis emacron -80
-KPX Ydieresis eogonek -80
-KPX Ydieresis o -100
-KPX Ydieresis oacute -100
-KPX Ydieresis ocircumflex -100
-KPX Ydieresis odieresis -100
-KPX Ydieresis ograve -100
-KPX Ydieresis ohungarumlaut -100
-KPX Ydieresis omacron -100
-KPX Ydieresis oslash -100
-KPX Ydieresis otilde -100
-KPX Ydieresis period -100
-KPX Ydieresis semicolon -50
-KPX Ydieresis u -100
-KPX Ydieresis uacute -100
-KPX Ydieresis ucircumflex -100
-KPX Ydieresis udieresis -100
-KPX Ydieresis ugrave -100
-KPX Ydieresis uhungarumlaut -100
-KPX Ydieresis umacron -100
-KPX Ydieresis uogonek -100
-KPX Ydieresis uring -100
-KPX a g -10
-KPX a gbreve -10
-KPX a gcommaaccent -10
-KPX a v -15
-KPX a w -15
-KPX a y -20
-KPX a yacute -20
-KPX a ydieresis -20
-KPX aacute g -10
-KPX aacute gbreve -10
-KPX aacute gcommaaccent -10
-KPX aacute v -15
-KPX aacute w -15
-KPX aacute y -20
-KPX aacute yacute -20
-KPX aacute ydieresis -20
-KPX abreve g -10
-KPX abreve gbreve -10
-KPX abreve gcommaaccent -10
-KPX abreve v -15
-KPX abreve w -15
-KPX abreve y -20
-KPX abreve yacute -20
-KPX abreve ydieresis -20
-KPX acircumflex g -10
-KPX acircumflex gbreve -10
-KPX acircumflex gcommaaccent -10
-KPX acircumflex v -15
-KPX acircumflex w -15
-KPX acircumflex y -20
-KPX acircumflex yacute -20
-KPX acircumflex ydieresis -20
-KPX adieresis g -10
-KPX adieresis gbreve -10
-KPX adieresis gcommaaccent -10
-KPX adieresis v -15
-KPX adieresis w -15
-KPX adieresis y -20
-KPX adieresis yacute -20
-KPX adieresis ydieresis -20
-KPX agrave g -10
-KPX agrave gbreve -10
-KPX agrave gcommaaccent -10
-KPX agrave v -15
-KPX agrave w -15
-KPX agrave y -20
-KPX agrave yacute -20
-KPX agrave ydieresis -20
-KPX amacron g -10
-KPX amacron gbreve -10
-KPX amacron gcommaaccent -10
-KPX amacron v -15
-KPX amacron w -15
-KPX amacron y -20
-KPX amacron yacute -20
-KPX amacron ydieresis -20
-KPX aogonek g -10
-KPX aogonek gbreve -10
-KPX aogonek gcommaaccent -10
-KPX aogonek v -15
-KPX aogonek w -15
-KPX aogonek y -20
-KPX aogonek yacute -20
-KPX aogonek ydieresis -20
-KPX aring g -10
-KPX aring gbreve -10
-KPX aring gcommaaccent -10
-KPX aring v -15
-KPX aring w -15
-KPX aring y -20
-KPX aring yacute -20
-KPX aring ydieresis -20
-KPX atilde g -10
-KPX atilde gbreve -10
-KPX atilde gcommaaccent -10
-KPX atilde v -15
-KPX atilde w -15
-KPX atilde y -20
-KPX atilde yacute -20
-KPX atilde ydieresis -20
-KPX b l -10
-KPX b lacute -10
-KPX b lcommaaccent -10
-KPX b lslash -10
-KPX b u -20
-KPX b uacute -20
-KPX b ucircumflex -20
-KPX b udieresis -20
-KPX b ugrave -20
-KPX b uhungarumlaut -20
-KPX b umacron -20
-KPX b uogonek -20
-KPX b uring -20
-KPX b v -20
-KPX b y -20
-KPX b yacute -20
-KPX b ydieresis -20
-KPX c h -10
-KPX c k -20
-KPX c kcommaaccent -20
-KPX c l -20
-KPX c lacute -20
-KPX c lcommaaccent -20
-KPX c lslash -20
-KPX c y -10
-KPX c yacute -10
-KPX c ydieresis -10
-KPX cacute h -10
-KPX cacute k -20
-KPX cacute kcommaaccent -20
-KPX cacute l -20
-KPX cacute lacute -20
-KPX cacute lcommaaccent -20
-KPX cacute lslash -20
-KPX cacute y -10
-KPX cacute yacute -10
-KPX cacute ydieresis -10
-KPX ccaron h -10
-KPX ccaron k -20
-KPX ccaron kcommaaccent -20
-KPX ccaron l -20
-KPX ccaron lacute -20
-KPX ccaron lcommaaccent -20
-KPX ccaron lslash -20
-KPX ccaron y -10
-KPX ccaron yacute -10
-KPX ccaron ydieresis -10
-KPX ccedilla h -10
-KPX ccedilla k -20
-KPX ccedilla kcommaaccent -20
-KPX ccedilla l -20
-KPX ccedilla lacute -20
-KPX ccedilla lcommaaccent -20
-KPX ccedilla lslash -20
-KPX ccedilla y -10
-KPX ccedilla yacute -10
-KPX ccedilla ydieresis -10
-KPX colon space -40
-KPX comma quotedblright -120
-KPX comma quoteright -120
-KPX comma space -40
-KPX d d -10
-KPX d dcroat -10
-KPX d v -15
-KPX d w -15
-KPX d y -15
-KPX d yacute -15
-KPX d ydieresis -15
-KPX dcroat d -10
-KPX dcroat dcroat -10
-KPX dcroat v -15
-KPX dcroat w -15
-KPX dcroat y -15
-KPX dcroat yacute -15
-KPX dcroat ydieresis -15
-KPX e comma 10
-KPX e period 20
-KPX e v -15
-KPX e w -15
-KPX e x -15
-KPX e y -15
-KPX e yacute -15
-KPX e ydieresis -15
-KPX eacute comma 10
-KPX eacute period 20
-KPX eacute v -15
-KPX eacute w -15
-KPX eacute x -15
-KPX eacute y -15
-KPX eacute yacute -15
-KPX eacute ydieresis -15
-KPX ecaron comma 10
-KPX ecaron period 20
-KPX ecaron v -15
-KPX ecaron w -15
-KPX ecaron x -15
-KPX ecaron y -15
-KPX ecaron yacute -15
-KPX ecaron ydieresis -15
-KPX ecircumflex comma 10
-KPX ecircumflex period 20
-KPX ecircumflex v -15
-KPX ecircumflex w -15
-KPX ecircumflex x -15
-KPX ecircumflex y -15
-KPX ecircumflex yacute -15
-KPX ecircumflex ydieresis -15
-KPX edieresis comma 10
-KPX edieresis period 20
-KPX edieresis v -15
-KPX edieresis w -15
-KPX edieresis x -15
-KPX edieresis y -15
-KPX edieresis yacute -15
-KPX edieresis ydieresis -15
-KPX edotaccent comma 10
-KPX edotaccent period 20
-KPX edotaccent v -15
-KPX edotaccent w -15
-KPX edotaccent x -15
-KPX edotaccent y -15
-KPX edotaccent yacute -15
-KPX edotaccent ydieresis -15
-KPX egrave comma 10
-KPX egrave period 20
-KPX egrave v -15
-KPX egrave w -15
-KPX egrave x -15
-KPX egrave y -15
-KPX egrave yacute -15
-KPX egrave ydieresis -15
-KPX emacron comma 10
-KPX emacron period 20
-KPX emacron v -15
-KPX emacron w -15
-KPX emacron x -15
-KPX emacron y -15
-KPX emacron yacute -15
-KPX emacron ydieresis -15
-KPX eogonek comma 10
-KPX eogonek period 20
-KPX eogonek v -15
-KPX eogonek w -15
-KPX eogonek x -15
-KPX eogonek y -15
-KPX eogonek yacute -15
-KPX eogonek ydieresis -15
-KPX f comma -10
-KPX f e -10
-KPX f eacute -10
-KPX f ecaron -10
-KPX f ecircumflex -10
-KPX f edieresis -10
-KPX f edotaccent -10
-KPX f egrave -10
-KPX f emacron -10
-KPX f eogonek -10
-KPX f o -20
-KPX f oacute -20
-KPX f ocircumflex -20
-KPX f odieresis -20
-KPX f ograve -20
-KPX f ohungarumlaut -20
-KPX f omacron -20
-KPX f oslash -20
-KPX f otilde -20
-KPX f period -10
-KPX f quotedblright 30
-KPX f quoteright 30
-KPX g e 10
-KPX g eacute 10
-KPX g ecaron 10
-KPX g ecircumflex 10
-KPX g edieresis 10
-KPX g edotaccent 10
-KPX g egrave 10
-KPX g emacron 10
-KPX g eogonek 10
-KPX g g -10
-KPX g gbreve -10
-KPX g gcommaaccent -10
-KPX gbreve e 10
-KPX gbreve eacute 10
-KPX gbreve ecaron 10
-KPX gbreve ecircumflex 10
-KPX gbreve edieresis 10
-KPX gbreve edotaccent 10
-KPX gbreve egrave 10
-KPX gbreve emacron 10
-KPX gbreve eogonek 10
-KPX gbreve g -10
-KPX gbreve gbreve -10
-KPX gbreve gcommaaccent -10
-KPX gcommaaccent e 10
-KPX gcommaaccent eacute 10
-KPX gcommaaccent ecaron 10
-KPX gcommaaccent ecircumflex 10
-KPX gcommaaccent edieresis 10
-KPX gcommaaccent edotaccent 10
-KPX gcommaaccent egrave 10
-KPX gcommaaccent emacron 10
-KPX gcommaaccent eogonek 10
-KPX gcommaaccent g -10
-KPX gcommaaccent gbreve -10
-KPX gcommaaccent gcommaaccent -10
-KPX h y -20
-KPX h yacute -20
-KPX h ydieresis -20
-KPX k o -15
-KPX k oacute -15
-KPX k ocircumflex -15
-KPX k odieresis -15
-KPX k ograve -15
-KPX k ohungarumlaut -15
-KPX k omacron -15
-KPX k oslash -15
-KPX k otilde -15
-KPX kcommaaccent o -15
-KPX kcommaaccent oacute -15
-KPX kcommaaccent ocircumflex -15
-KPX kcommaaccent odieresis -15
-KPX kcommaaccent ograve -15
-KPX kcommaaccent ohungarumlaut -15
-KPX kcommaaccent omacron -15
-KPX kcommaaccent oslash -15
-KPX kcommaaccent otilde -15
-KPX l w -15
-KPX l y -15
-KPX l yacute -15
-KPX l ydieresis -15
-KPX lacute w -15
-KPX lacute y -15
-KPX lacute yacute -15
-KPX lacute ydieresis -15
-KPX lcommaaccent w -15
-KPX lcommaaccent y -15
-KPX lcommaaccent yacute -15
-KPX lcommaaccent ydieresis -15
-KPX lslash w -15
-KPX lslash y -15
-KPX lslash yacute -15
-KPX lslash ydieresis -15
-KPX m u -20
-KPX m uacute -20
-KPX m ucircumflex -20
-KPX m udieresis -20
-KPX m ugrave -20
-KPX m uhungarumlaut -20
-KPX m umacron -20
-KPX m uogonek -20
-KPX m uring -20
-KPX m y -30
-KPX m yacute -30
-KPX m ydieresis -30
-KPX n u -10
-KPX n uacute -10
-KPX n ucircumflex -10
-KPX n udieresis -10
-KPX n ugrave -10
-KPX n uhungarumlaut -10
-KPX n umacron -10
-KPX n uogonek -10
-KPX n uring -10
-KPX n v -40
-KPX n y -20
-KPX n yacute -20
-KPX n ydieresis -20
-KPX nacute u -10
-KPX nacute uacute -10
-KPX nacute ucircumflex -10
-KPX nacute udieresis -10
-KPX nacute ugrave -10
-KPX nacute uhungarumlaut -10
-KPX nacute umacron -10
-KPX nacute uogonek -10
-KPX nacute uring -10
-KPX nacute v -40
-KPX nacute y -20
-KPX nacute yacute -20
-KPX nacute ydieresis -20
-KPX ncaron u -10
-KPX ncaron uacute -10
-KPX ncaron ucircumflex -10
-KPX ncaron udieresis -10
-KPX ncaron ugrave -10
-KPX ncaron uhungarumlaut -10
-KPX ncaron umacron -10
-KPX ncaron uogonek -10
-KPX ncaron uring -10
-KPX ncaron v -40
-KPX ncaron y -20
-KPX ncaron yacute -20
-KPX ncaron ydieresis -20
-KPX ncommaaccent u -10
-KPX ncommaaccent uacute -10
-KPX ncommaaccent ucircumflex -10
-KPX ncommaaccent udieresis -10
-KPX ncommaaccent ugrave -10
-KPX ncommaaccent uhungarumlaut -10
-KPX ncommaaccent umacron -10
-KPX ncommaaccent uogonek -10
-KPX ncommaaccent uring -10
-KPX ncommaaccent v -40
-KPX ncommaaccent y -20
-KPX ncommaaccent yacute -20
-KPX ncommaaccent ydieresis -20
-KPX ntilde u -10
-KPX ntilde uacute -10
-KPX ntilde ucircumflex -10
-KPX ntilde udieresis -10
-KPX ntilde ugrave -10
-KPX ntilde uhungarumlaut -10
-KPX ntilde umacron -10
-KPX ntilde uogonek -10
-KPX ntilde uring -10
-KPX ntilde v -40
-KPX ntilde y -20
-KPX ntilde yacute -20
-KPX ntilde ydieresis -20
-KPX o v -20
-KPX o w -15
-KPX o x -30
-KPX o y -20
-KPX o yacute -20
-KPX o ydieresis -20
-KPX oacute v -20
-KPX oacute w -15
-KPX oacute x -30
-KPX oacute y -20
-KPX oacute yacute -20
-KPX oacute ydieresis -20
-KPX ocircumflex v -20
-KPX ocircumflex w -15
-KPX ocircumflex x -30
-KPX ocircumflex y -20
-KPX ocircumflex yacute -20
-KPX ocircumflex ydieresis -20
-KPX odieresis v -20
-KPX odieresis w -15
-KPX odieresis x -30
-KPX odieresis y -20
-KPX odieresis yacute -20
-KPX odieresis ydieresis -20
-KPX ograve v -20
-KPX ograve w -15
-KPX ograve x -30
-KPX ograve y -20
-KPX ograve yacute -20
-KPX ograve ydieresis -20
-KPX ohungarumlaut v -20
-KPX ohungarumlaut w -15
-KPX ohungarumlaut x -30
-KPX ohungarumlaut y -20
-KPX ohungarumlaut yacute -20
-KPX ohungarumlaut ydieresis -20
-KPX omacron v -20
-KPX omacron w -15
-KPX omacron x -30
-KPX omacron y -20
-KPX omacron yacute -20
-KPX omacron ydieresis -20
-KPX oslash v -20
-KPX oslash w -15
-KPX oslash x -30
-KPX oslash y -20
-KPX oslash yacute -20
-KPX oslash ydieresis -20
-KPX otilde v -20
-KPX otilde w -15
-KPX otilde x -30
-KPX otilde y -20
-KPX otilde yacute -20
-KPX otilde ydieresis -20
-KPX p y -15
-KPX p yacute -15
-KPX p ydieresis -15
-KPX period quotedblright -120
-KPX period quoteright -120
-KPX period space -40
-KPX quotedblright space -80
-KPX quoteleft quoteleft -46
-KPX quoteright d -80
-KPX quoteright dcroat -80
-KPX quoteright l -20
-KPX quoteright lacute -20
-KPX quoteright lcommaaccent -20
-KPX quoteright lslash -20
-KPX quoteright quoteright -46
-KPX quoteright r -40
-KPX quoteright racute -40
-KPX quoteright rcaron -40
-KPX quoteright rcommaaccent -40
-KPX quoteright s -60
-KPX quoteright sacute -60
-KPX quoteright scaron -60
-KPX quoteright scedilla -60
-KPX quoteright scommaaccent -60
-KPX quoteright space -80
-KPX quoteright v -20
-KPX r c -20
-KPX r cacute -20
-KPX r ccaron -20
-KPX r ccedilla -20
-KPX r comma -60
-KPX r d -20
-KPX r dcroat -20
-KPX r g -15
-KPX r gbreve -15
-KPX r gcommaaccent -15
-KPX r hyphen -20
-KPX r o -20
-KPX r oacute -20
-KPX r ocircumflex -20
-KPX r odieresis -20
-KPX r ograve -20
-KPX r ohungarumlaut -20
-KPX r omacron -20
-KPX r oslash -20
-KPX r otilde -20
-KPX r period -60
-KPX r q -20
-KPX r s -15
-KPX r sacute -15
-KPX r scaron -15
-KPX r scedilla -15
-KPX r scommaaccent -15
-KPX r t 20
-KPX r tcommaaccent 20
-KPX r v 10
-KPX r y 10
-KPX r yacute 10
-KPX r ydieresis 10
-KPX racute c -20
-KPX racute cacute -20
-KPX racute ccaron -20
-KPX racute ccedilla -20
-KPX racute comma -60
-KPX racute d -20
-KPX racute dcroat -20
-KPX racute g -15
-KPX racute gbreve -15
-KPX racute gcommaaccent -15
-KPX racute hyphen -20
-KPX racute o -20
-KPX racute oacute -20
-KPX racute ocircumflex -20
-KPX racute odieresis -20
-KPX racute ograve -20
-KPX racute ohungarumlaut -20
-KPX racute omacron -20
-KPX racute oslash -20
-KPX racute otilde -20
-KPX racute period -60
-KPX racute q -20
-KPX racute s -15
-KPX racute sacute -15
-KPX racute scaron -15
-KPX racute scedilla -15
-KPX racute scommaaccent -15
-KPX racute t 20
-KPX racute tcommaaccent 20
-KPX racute v 10
-KPX racute y 10
-KPX racute yacute 10
-KPX racute ydieresis 10
-KPX rcaron c -20
-KPX rcaron cacute -20
-KPX rcaron ccaron -20
-KPX rcaron ccedilla -20
-KPX rcaron comma -60
-KPX rcaron d -20
-KPX rcaron dcroat -20
-KPX rcaron g -15
-KPX rcaron gbreve -15
-KPX rcaron gcommaaccent -15
-KPX rcaron hyphen -20
-KPX rcaron o -20
-KPX rcaron oacute -20
-KPX rcaron ocircumflex -20
-KPX rcaron odieresis -20
-KPX rcaron ograve -20
-KPX rcaron ohungarumlaut -20
-KPX rcaron omacron -20
-KPX rcaron oslash -20
-KPX rcaron otilde -20
-KPX rcaron period -60
-KPX rcaron q -20
-KPX rcaron s -15
-KPX rcaron sacute -15
-KPX rcaron scaron -15
-KPX rcaron scedilla -15
-KPX rcaron scommaaccent -15
-KPX rcaron t 20
-KPX rcaron tcommaaccent 20
-KPX rcaron v 10
-KPX rcaron y 10
-KPX rcaron yacute 10
-KPX rcaron ydieresis 10
-KPX rcommaaccent c -20
-KPX rcommaaccent cacute -20
-KPX rcommaaccent ccaron -20
-KPX rcommaaccent ccedilla -20
-KPX rcommaaccent comma -60
-KPX rcommaaccent d -20
-KPX rcommaaccent dcroat -20
-KPX rcommaaccent g -15
-KPX rcommaaccent gbreve -15
-KPX rcommaaccent gcommaaccent -15
-KPX rcommaaccent hyphen -20
-KPX rcommaaccent o -20
-KPX rcommaaccent oacute -20
-KPX rcommaaccent ocircumflex -20
-KPX rcommaaccent odieresis -20
-KPX rcommaaccent ograve -20
-KPX rcommaaccent ohungarumlaut -20
-KPX rcommaaccent omacron -20
-KPX rcommaaccent oslash -20
-KPX rcommaaccent otilde -20
-KPX rcommaaccent period -60
-KPX rcommaaccent q -20
-KPX rcommaaccent s -15
-KPX rcommaaccent sacute -15
-KPX rcommaaccent scaron -15
-KPX rcommaaccent scedilla -15
-KPX rcommaaccent scommaaccent -15
-KPX rcommaaccent t 20
-KPX rcommaaccent tcommaaccent 20
-KPX rcommaaccent v 10
-KPX rcommaaccent y 10
-KPX rcommaaccent yacute 10
-KPX rcommaaccent ydieresis 10
-KPX s w -15
-KPX sacute w -15
-KPX scaron w -15
-KPX scedilla w -15
-KPX scommaaccent w -15
-KPX semicolon space -40
-KPX space T -100
-KPX space Tcaron -100
-KPX space Tcommaaccent -100
-KPX space V -80
-KPX space W -80
-KPX space Y -120
-KPX space Yacute -120
-KPX space Ydieresis -120
-KPX space quotedblleft -80
-KPX space quoteleft -60
-KPX v a -20
-KPX v aacute -20
-KPX v abreve -20
-KPX v acircumflex -20
-KPX v adieresis -20
-KPX v agrave -20
-KPX v amacron -20
-KPX v aogonek -20
-KPX v aring -20
-KPX v atilde -20
-KPX v comma -80
-KPX v o -30
-KPX v oacute -30
-KPX v ocircumflex -30
-KPX v odieresis -30
-KPX v ograve -30
-KPX v ohungarumlaut -30
-KPX v omacron -30
-KPX v oslash -30
-KPX v otilde -30
-KPX v period -80
-KPX w comma -40
-KPX w o -20
-KPX w oacute -20
-KPX w ocircumflex -20
-KPX w odieresis -20
-KPX w ograve -20
-KPX w ohungarumlaut -20
-KPX w omacron -20
-KPX w oslash -20
-KPX w otilde -20
-KPX w period -40
-KPX x e -10
-KPX x eacute -10
-KPX x ecaron -10
-KPX x ecircumflex -10
-KPX x edieresis -10
-KPX x edotaccent -10
-KPX x egrave -10
-KPX x emacron -10
-KPX x eogonek -10
-KPX y a -30
-KPX y aacute -30
-KPX y abreve -30
-KPX y acircumflex -30
-KPX y adieresis -30
-KPX y agrave -30
-KPX y amacron -30
-KPX y aogonek -30
-KPX y aring -30
-KPX y atilde -30
-KPX y comma -80
-KPX y e -10
-KPX y eacute -10
-KPX y ecaron -10
-KPX y ecircumflex -10
-KPX y edieresis -10
-KPX y edotaccent -10
-KPX y egrave -10
-KPX y emacron -10
-KPX y eogonek -10
-KPX y o -25
-KPX y oacute -25
-KPX y ocircumflex -25
-KPX y odieresis -25
-KPX y ograve -25
-KPX y ohungarumlaut -25
-KPX y omacron -25
-KPX y oslash -25
-KPX y otilde -25
-KPX y period -80
-KPX yacute a -30
-KPX yacute aacute -30
-KPX yacute abreve -30
-KPX yacute acircumflex -30
-KPX yacute adieresis -30
-KPX yacute agrave -30
-KPX yacute amacron -30
-KPX yacute aogonek -30
-KPX yacute aring -30
-KPX yacute atilde -30
-KPX yacute comma -80
-KPX yacute e -10
-KPX yacute eacute -10
-KPX yacute ecaron -10
-KPX yacute ecircumflex -10
-KPX yacute edieresis -10
-KPX yacute edotaccent -10
-KPX yacute egrave -10
-KPX yacute emacron -10
-KPX yacute eogonek -10
-KPX yacute o -25
-KPX yacute oacute -25
-KPX yacute ocircumflex -25
-KPX yacute odieresis -25
-KPX yacute ograve -25
-KPX yacute ohungarumlaut -25
-KPX yacute omacron -25
-KPX yacute oslash -25
-KPX yacute otilde -25
-KPX yacute period -80
-KPX ydieresis a -30
-KPX ydieresis aacute -30
-KPX ydieresis abreve -30
-KPX ydieresis acircumflex -30
-KPX ydieresis adieresis -30
-KPX ydieresis agrave -30
-KPX ydieresis amacron -30
-KPX ydieresis aogonek -30
-KPX ydieresis aring -30
-KPX ydieresis atilde -30
-KPX ydieresis comma -80
-KPX ydieresis e -10
-KPX ydieresis eacute -10
-KPX ydieresis ecaron -10
-KPX ydieresis ecircumflex -10
-KPX ydieresis edieresis -10
-KPX ydieresis edotaccent -10
-KPX ydieresis egrave -10
-KPX ydieresis emacron -10
-KPX ydieresis eogonek -10
-KPX ydieresis o -25
-KPX ydieresis oacute -25
-KPX ydieresis ocircumflex -25
-KPX ydieresis odieresis -25
-KPX ydieresis ograve -25
-KPX ydieresis ohungarumlaut -25
-KPX ydieresis omacron -25
-KPX ydieresis oslash -25
-KPX ydieresis otilde -25
-KPX ydieresis period -80
-KPX z e 10
-KPX z eacute 10
-KPX z ecaron 10
-KPX z ecircumflex 10
-KPX z edieresis 10
-KPX z edotaccent 10
-KPX z egrave 10
-KPX z emacron 10
-KPX z eogonek 10
-KPX zacute e 10
-KPX zacute eacute 10
-KPX zacute ecaron 10
-KPX zacute ecircumflex 10
-KPX zacute edieresis 10
-KPX zacute edotaccent 10
-KPX zacute egrave 10
-KPX zacute emacron 10
-KPX zacute eogonek 10
-KPX zcaron e 10
-KPX zcaron eacute 10
-KPX zcaron ecaron 10
-KPX zcaron ecircumflex 10
-KPX zcaron edieresis 10
-KPX zcaron edotaccent 10
-KPX zcaron egrave 10
-KPX zcaron emacron 10
-KPX zcaron eogonek 10
-KPX zdotaccent e 10
-KPX zdotaccent eacute 10
-KPX zdotaccent ecaron 10
-KPX zdotaccent ecircumflex 10
-KPX zdotaccent edieresis 10
-KPX zdotaccent edotaccent 10
-KPX zdotaccent egrave 10
-KPX zdotaccent emacron 10
-KPX zdotaccent eogonek 10
-EndKernPairs
-EndKernData
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-BoldOblique.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-BoldOblique.afm
deleted file mode 100644
index 1715b21046..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-BoldOblique.afm
+++ /dev/null
@@ -1,2827 +0,0 @@
-StartFontMetrics 4.1
-Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Thu May 1 12:45:12 1997
-Comment UniqueID 43053
-Comment VMusage 14482 68586
-FontName Helvetica-BoldOblique
-FullName Helvetica Bold Oblique
-FamilyName Helvetica
-Weight Bold
-ItalicAngle -12
-IsFixedPitch false
-CharacterSet ExtendedRoman
-FontBBox -174 -228 1114 962
-UnderlinePosition -100
-UnderlineThickness 50
-Version 002.000
-Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 718
-XHeight 532
-Ascender 718
-Descender -207
-StdHW 118
-StdVW 140
-StartCharMetrics 315
-C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 94 0 397 718 ;
-C 34 ; WX 474 ; N quotedbl ; B 193 447 529 718 ;
-C 35 ; WX 556 ; N numbersign ; B 60 0 644 698 ;
-C 36 ; WX 556 ; N dollar ; B 67 -115 622 775 ;
-C 37 ; WX 889 ; N percent ; B 136 -19 901 710 ;
-C 38 ; WX 722 ; N ampersand ; B 89 -19 732 718 ;
-C 39 ; WX 278 ; N quoteright ; B 167 445 362 718 ;
-C 40 ; WX 333 ; N parenleft ; B 76 -208 470 734 ;
-C 41 ; WX 333 ; N parenright ; B -25 -208 369 734 ;
-C 42 ; WX 389 ; N asterisk ; B 146 387 481 718 ;
-C 43 ; WX 584 ; N plus ; B 82 0 610 506 ;
-C 44 ; WX 278 ; N comma ; B 28 -168 245 146 ;
-C 45 ; WX 333 ; N hyphen ; B 73 215 379 345 ;
-C 46 ; WX 278 ; N period ; B 64 0 245 146 ;
-C 47 ; WX 278 ; N slash ; B -37 -19 468 737 ;
-C 48 ; WX 556 ; N zero ; B 86 -19 617 710 ;
-C 49 ; WX 556 ; N one ; B 173 0 529 710 ;
-C 50 ; WX 556 ; N two ; B 26 0 619 710 ;
-C 51 ; WX 556 ; N three ; B 65 -19 608 710 ;
-C 52 ; WX 556 ; N four ; B 60 0 598 710 ;
-C 53 ; WX 556 ; N five ; B 64 -19 636 698 ;
-C 54 ; WX 556 ; N six ; B 85 -19 619 710 ;
-C 55 ; WX 556 ; N seven ; B 125 0 676 698 ;
-C 56 ; WX 556 ; N eight ; B 69 -19 616 710 ;
-C 57 ; WX 556 ; N nine ; B 78 -19 615 710 ;
-C 58 ; WX 333 ; N colon ; B 92 0 351 512 ;
-C 59 ; WX 333 ; N semicolon ; B 56 -168 351 512 ;
-C 60 ; WX 584 ; N less ; B 82 -8 655 514 ;
-C 61 ; WX 584 ; N equal ; B 58 87 633 419 ;
-C 62 ; WX 584 ; N greater ; B 36 -8 609 514 ;
-C 63 ; WX 611 ; N question ; B 165 0 671 727 ;
-C 64 ; WX 975 ; N at ; B 186 -19 954 737 ;
-C 65 ; WX 722 ; N A ; B 20 0 702 718 ;
-C 66 ; WX 722 ; N B ; B 76 0 764 718 ;
-C 67 ; WX 722 ; N C ; B 107 -19 789 737 ;
-C 68 ; WX 722 ; N D ; B 76 0 777 718 ;
-C 69 ; WX 667 ; N E ; B 76 0 757 718 ;
-C 70 ; WX 611 ; N F ; B 76 0 740 718 ;
-C 71 ; WX 778 ; N G ; B 108 -19 817 737 ;
-C 72 ; WX 722 ; N H ; B 71 0 804 718 ;
-C 73 ; WX 278 ; N I ; B 64 0 367 718 ;
-C 74 ; WX 556 ; N J ; B 60 -18 637 718 ;
-C 75 ; WX 722 ; N K ; B 87 0 858 718 ;
-C 76 ; WX 611 ; N L ; B 76 0 611 718 ;
-C 77 ; WX 833 ; N M ; B 69 0 918 718 ;
-C 78 ; WX 722 ; N N ; B 69 0 807 718 ;
-C 79 ; WX 778 ; N O ; B 107 -19 823 737 ;
-C 80 ; WX 667 ; N P ; B 76 0 738 718 ;
-C 81 ; WX 778 ; N Q ; B 107 -52 823 737 ;
-C 82 ; WX 722 ; N R ; B 76 0 778 718 ;
-C 83 ; WX 667 ; N S ; B 81 -19 718 737 ;
-C 84 ; WX 611 ; N T ; B 140 0 751 718 ;
-C 85 ; WX 722 ; N U ; B 116 -19 804 718 ;
-C 86 ; WX 667 ; N V ; B 172 0 801 718 ;
-C 87 ; WX 944 ; N W ; B 169 0 1082 718 ;
-C 88 ; WX 667 ; N X ; B 14 0 791 718 ;
-C 89 ; WX 667 ; N Y ; B 168 0 806 718 ;
-C 90 ; WX 611 ; N Z ; B 25 0 737 718 ;
-C 91 ; WX 333 ; N bracketleft ; B 21 -196 462 722 ;
-C 92 ; WX 278 ; N backslash ; B 124 -19 307 737 ;
-C 93 ; WX 333 ; N bracketright ; B -18 -196 423 722 ;
-C 94 ; WX 584 ; N asciicircum ; B 131 323 591 698 ;
-C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ;
-C 96 ; WX 278 ; N quoteleft ; B 165 454 361 727 ;
-C 97 ; WX 556 ; N a ; B 55 -14 583 546 ;
-C 98 ; WX 611 ; N b ; B 61 -14 645 718 ;
-C 99 ; WX 556 ; N c ; B 79 -14 599 546 ;
-C 100 ; WX 611 ; N d ; B 82 -14 704 718 ;
-C 101 ; WX 556 ; N e ; B 70 -14 593 546 ;
-C 102 ; WX 333 ; N f ; B 87 0 469 727 ; L i fi ; L l fl ;
-C 103 ; WX 611 ; N g ; B 38 -217 666 546 ;
-C 104 ; WX 611 ; N h ; B 65 0 629 718 ;
-C 105 ; WX 278 ; N i ; B 69 0 363 725 ;
-C 106 ; WX 278 ; N j ; B -42 -214 363 725 ;
-C 107 ; WX 556 ; N k ; B 69 0 670 718 ;
-C 108 ; WX 278 ; N l ; B 69 0 362 718 ;
-C 109 ; WX 889 ; N m ; B 64 0 909 546 ;
-C 110 ; WX 611 ; N n ; B 65 0 629 546 ;
-C 111 ; WX 611 ; N o ; B 82 -14 643 546 ;
-C 112 ; WX 611 ; N p ; B 18 -207 645 546 ;
-C 113 ; WX 611 ; N q ; B 80 -207 665 546 ;
-C 114 ; WX 389 ; N r ; B 64 0 489 546 ;
-C 115 ; WX 556 ; N s ; B 63 -14 584 546 ;
-C 116 ; WX 333 ; N t ; B 100 -6 422 676 ;
-C 117 ; WX 611 ; N u ; B 98 -14 658 532 ;
-C 118 ; WX 556 ; N v ; B 126 0 656 532 ;
-C 119 ; WX 778 ; N w ; B 123 0 882 532 ;
-C 120 ; WX 556 ; N x ; B 15 0 648 532 ;
-C 121 ; WX 556 ; N y ; B 42 -214 652 532 ;
-C 122 ; WX 500 ; N z ; B 20 0 583 532 ;
-C 123 ; WX 389 ; N braceleft ; B 94 -196 518 722 ;
-C 124 ; WX 280 ; N bar ; B 36 -225 361 775 ;
-C 125 ; WX 389 ; N braceright ; B -18 -196 407 722 ;
-C 126 ; WX 584 ; N asciitilde ; B 115 163 577 343 ;
-C 161 ; WX 333 ; N exclamdown ; B 50 -186 353 532 ;
-C 162 ; WX 556 ; N cent ; B 79 -118 599 628 ;
-C 163 ; WX 556 ; N sterling ; B 50 -16 635 718 ;
-C 164 ; WX 167 ; N fraction ; B -174 -19 487 710 ;
-C 165 ; WX 556 ; N yen ; B 60 0 713 698 ;
-C 166 ; WX 556 ; N florin ; B -50 -210 669 737 ;
-C 167 ; WX 556 ; N section ; B 61 -184 598 727 ;
-C 168 ; WX 556 ; N currency ; B 27 76 680 636 ;
-C 169 ; WX 238 ; N quotesingle ; B 165 447 321 718 ;
-C 170 ; WX 500 ; N quotedblleft ; B 160 454 588 727 ;
-C 171 ; WX 556 ; N guillemotleft ; B 135 76 571 484 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 130 76 353 484 ;
-C 173 ; WX 333 ; N guilsinglright ; B 99 76 322 484 ;
-C 174 ; WX 611 ; N fi ; B 87 0 696 727 ;
-C 175 ; WX 611 ; N fl ; B 87 0 695 727 ;
-C 177 ; WX 556 ; N endash ; B 48 227 627 333 ;
-C 178 ; WX 556 ; N dagger ; B 118 -171 626 718 ;
-C 179 ; WX 556 ; N daggerdbl ; B 46 -171 628 718 ;
-C 180 ; WX 278 ; N periodcentered ; B 110 172 276 334 ;
-C 182 ; WX 556 ; N paragraph ; B 98 -191 688 700 ;
-C 183 ; WX 350 ; N bullet ; B 83 194 420 524 ;
-C 184 ; WX 278 ; N quotesinglbase ; B 41 -146 236 127 ;
-C 185 ; WX 500 ; N quotedblbase ; B 36 -146 463 127 ;
-C 186 ; WX 500 ; N quotedblright ; B 162 445 589 718 ;
-C 187 ; WX 556 ; N guillemotright ; B 104 76 540 484 ;
-C 188 ; WX 1000 ; N ellipsis ; B 92 0 939 146 ;
-C 189 ; WX 1000 ; N perthousand ; B 76 -19 1038 710 ;
-C 191 ; WX 611 ; N questiondown ; B 53 -195 559 532 ;
-C 193 ; WX 333 ; N grave ; B 136 604 353 750 ;
-C 194 ; WX 333 ; N acute ; B 236 604 515 750 ;
-C 195 ; WX 333 ; N circumflex ; B 118 604 471 750 ;
-C 196 ; WX 333 ; N tilde ; B 113 610 507 737 ;
-C 197 ; WX 333 ; N macron ; B 122 604 483 678 ;
-C 198 ; WX 333 ; N breve ; B 156 604 494 750 ;
-C 199 ; WX 333 ; N dotaccent ; B 235 614 385 729 ;
-C 200 ; WX 333 ; N dieresis ; B 137 614 482 729 ;
-C 202 ; WX 333 ; N ring ; B 200 568 420 776 ;
-C 203 ; WX 333 ; N cedilla ; B -37 -228 220 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 137 604 645 750 ;
-C 206 ; WX 333 ; N ogonek ; B 41 -228 264 0 ;
-C 207 ; WX 333 ; N caron ; B 149 604 502 750 ;
-C 208 ; WX 1000 ; N emdash ; B 48 227 1071 333 ;
-C 225 ; WX 1000 ; N AE ; B 5 0 1100 718 ;
-C 227 ; WX 370 ; N ordfeminine ; B 125 401 465 737 ;
-C 232 ; WX 611 ; N Lslash ; B 34 0 611 718 ;
-C 233 ; WX 778 ; N Oslash ; B 35 -27 894 745 ;
-C 234 ; WX 1000 ; N OE ; B 99 -19 1114 737 ;
-C 235 ; WX 365 ; N ordmasculine ; B 123 401 485 737 ;
-C 241 ; WX 889 ; N ae ; B 56 -14 923 546 ;
-C 245 ; WX 278 ; N dotlessi ; B 69 0 322 532 ;
-C 248 ; WX 278 ; N lslash ; B 40 0 407 718 ;
-C 249 ; WX 611 ; N oslash ; B 22 -29 701 560 ;
-C 250 ; WX 944 ; N oe ; B 82 -14 977 546 ;
-C 251 ; WX 611 ; N germandbls ; B 69 -14 657 731 ;
-C -1 ; WX 278 ; N Idieresis ; B 64 0 494 915 ;
-C -1 ; WX 556 ; N eacute ; B 70 -14 627 750 ;
-C -1 ; WX 556 ; N abreve ; B 55 -14 606 750 ;
-C -1 ; WX 611 ; N uhungarumlaut ; B 98 -14 784 750 ;
-C -1 ; WX 556 ; N ecaron ; B 70 -14 614 750 ;
-C -1 ; WX 667 ; N Ydieresis ; B 168 0 806 915 ;
-C -1 ; WX 584 ; N divide ; B 82 -42 610 548 ;
-C -1 ; WX 667 ; N Yacute ; B 168 0 806 936 ;
-C -1 ; WX 722 ; N Acircumflex ; B 20 0 706 936 ;
-C -1 ; WX 556 ; N aacute ; B 55 -14 627 750 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 116 -19 804 936 ;
-C -1 ; WX 556 ; N yacute ; B 42 -214 652 750 ;
-C -1 ; WX 556 ; N scommaaccent ; B 63 -228 584 546 ;
-C -1 ; WX 556 ; N ecircumflex ; B 70 -14 593 750 ;
-C -1 ; WX 722 ; N Uring ; B 116 -19 804 962 ;
-C -1 ; WX 722 ; N Udieresis ; B 116 -19 804 915 ;
-C -1 ; WX 556 ; N aogonek ; B 55 -224 583 546 ;
-C -1 ; WX 722 ; N Uacute ; B 116 -19 804 936 ;
-C -1 ; WX 611 ; N uogonek ; B 98 -228 658 532 ;
-C -1 ; WX 667 ; N Edieresis ; B 76 0 757 915 ;
-C -1 ; WX 722 ; N Dcroat ; B 62 0 777 718 ;
-C -1 ; WX 250 ; N commaaccent ; B 16 -228 188 -50 ;
-C -1 ; WX 737 ; N copyright ; B 56 -19 835 737 ;
-C -1 ; WX 667 ; N Emacron ; B 76 0 757 864 ;
-C -1 ; WX 556 ; N ccaron ; B 79 -14 614 750 ;
-C -1 ; WX 556 ; N aring ; B 55 -14 583 776 ;
-C -1 ; WX 722 ; N Ncommaaccent ; B 69 -228 807 718 ;
-C -1 ; WX 278 ; N lacute ; B 69 0 528 936 ;
-C -1 ; WX 556 ; N agrave ; B 55 -14 583 750 ;
-C -1 ; WX 611 ; N Tcommaaccent ; B 140 -228 751 718 ;
-C -1 ; WX 722 ; N Cacute ; B 107 -19 789 936 ;
-C -1 ; WX 556 ; N atilde ; B 55 -14 619 737 ;
-C -1 ; WX 667 ; N Edotaccent ; B 76 0 757 915 ;
-C -1 ; WX 556 ; N scaron ; B 63 -14 614 750 ;
-C -1 ; WX 556 ; N scedilla ; B 63 -228 584 546 ;
-C -1 ; WX 278 ; N iacute ; B 69 0 488 750 ;
-C -1 ; WX 494 ; N lozenge ; B 90 0 564 745 ;
-C -1 ; WX 722 ; N Rcaron ; B 76 0 778 936 ;
-C -1 ; WX 778 ; N Gcommaaccent ; B 108 -228 817 737 ;
-C -1 ; WX 611 ; N ucircumflex ; B 98 -14 658 750 ;
-C -1 ; WX 556 ; N acircumflex ; B 55 -14 583 750 ;
-C -1 ; WX 722 ; N Amacron ; B 20 0 718 864 ;
-C -1 ; WX 389 ; N rcaron ; B 64 0 530 750 ;
-C -1 ; WX 556 ; N ccedilla ; B 79 -228 599 546 ;
-C -1 ; WX 611 ; N Zdotaccent ; B 25 0 737 915 ;
-C -1 ; WX 667 ; N Thorn ; B 76 0 716 718 ;
-C -1 ; WX 778 ; N Omacron ; B 107 -19 823 864 ;
-C -1 ; WX 722 ; N Racute ; B 76 0 778 936 ;
-C -1 ; WX 667 ; N Sacute ; B 81 -19 722 936 ;
-C -1 ; WX 743 ; N dcaron ; B 82 -14 903 718 ;
-C -1 ; WX 722 ; N Umacron ; B 116 -19 804 864 ;
-C -1 ; WX 611 ; N uring ; B 98 -14 658 776 ;
-C -1 ; WX 333 ; N threesuperior ; B 91 271 441 710 ;
-C -1 ; WX 778 ; N Ograve ; B 107 -19 823 936 ;
-C -1 ; WX 722 ; N Agrave ; B 20 0 702 936 ;
-C -1 ; WX 722 ; N Abreve ; B 20 0 729 936 ;
-C -1 ; WX 584 ; N multiply ; B 57 1 635 505 ;
-C -1 ; WX 611 ; N uacute ; B 98 -14 658 750 ;
-C -1 ; WX 611 ; N Tcaron ; B 140 0 751 936 ;
-C -1 ; WX 494 ; N partialdiff ; B 43 -21 585 750 ;
-C -1 ; WX 556 ; N ydieresis ; B 42 -214 652 729 ;
-C -1 ; WX 722 ; N Nacute ; B 69 0 807 936 ;
-C -1 ; WX 278 ; N icircumflex ; B 69 0 444 750 ;
-C -1 ; WX 667 ; N Ecircumflex ; B 76 0 757 936 ;
-C -1 ; WX 556 ; N adieresis ; B 55 -14 594 729 ;
-C -1 ; WX 556 ; N edieresis ; B 70 -14 594 729 ;
-C -1 ; WX 556 ; N cacute ; B 79 -14 627 750 ;
-C -1 ; WX 611 ; N nacute ; B 65 0 654 750 ;
-C -1 ; WX 611 ; N umacron ; B 98 -14 658 678 ;
-C -1 ; WX 722 ; N Ncaron ; B 69 0 807 936 ;
-C -1 ; WX 278 ; N Iacute ; B 64 0 528 936 ;
-C -1 ; WX 584 ; N plusminus ; B 40 0 625 506 ;
-C -1 ; WX 280 ; N brokenbar ; B 52 -150 345 700 ;
-C -1 ; WX 737 ; N registered ; B 55 -19 834 737 ;
-C -1 ; WX 778 ; N Gbreve ; B 108 -19 817 936 ;
-C -1 ; WX 278 ; N Idotaccent ; B 64 0 397 915 ;
-C -1 ; WX 600 ; N summation ; B 14 -10 670 706 ;
-C -1 ; WX 667 ; N Egrave ; B 76 0 757 936 ;
-C -1 ; WX 389 ; N racute ; B 64 0 543 750 ;
-C -1 ; WX 611 ; N omacron ; B 82 -14 643 678 ;
-C -1 ; WX 611 ; N Zacute ; B 25 0 737 936 ;
-C -1 ; WX 611 ; N Zcaron ; B 25 0 737 936 ;
-C -1 ; WX 549 ; N greaterequal ; B 26 0 629 704 ;
-C -1 ; WX 722 ; N Eth ; B 62 0 777 718 ;
-C -1 ; WX 722 ; N Ccedilla ; B 107 -228 789 737 ;
-C -1 ; WX 278 ; N lcommaaccent ; B 30 -228 362 718 ;
-C -1 ; WX 389 ; N tcaron ; B 100 -6 608 878 ;
-C -1 ; WX 556 ; N eogonek ; B 70 -228 593 546 ;
-C -1 ; WX 722 ; N Uogonek ; B 116 -228 804 718 ;
-C -1 ; WX 722 ; N Aacute ; B 20 0 750 936 ;
-C -1 ; WX 722 ; N Adieresis ; B 20 0 716 915 ;
-C -1 ; WX 556 ; N egrave ; B 70 -14 593 750 ;
-C -1 ; WX 500 ; N zacute ; B 20 0 599 750 ;
-C -1 ; WX 278 ; N iogonek ; B -14 -224 363 725 ;
-C -1 ; WX 778 ; N Oacute ; B 107 -19 823 936 ;
-C -1 ; WX 611 ; N oacute ; B 82 -14 654 750 ;
-C -1 ; WX 556 ; N amacron ; B 55 -14 595 678 ;
-C -1 ; WX 556 ; N sacute ; B 63 -14 627 750 ;
-C -1 ; WX 278 ; N idieresis ; B 69 0 455 729 ;
-C -1 ; WX 778 ; N Ocircumflex ; B 107 -19 823 936 ;
-C -1 ; WX 722 ; N Ugrave ; B 116 -19 804 936 ;
-C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ;
-C -1 ; WX 611 ; N thorn ; B 18 -208 645 718 ;
-C -1 ; WX 333 ; N twosuperior ; B 69 283 449 710 ;
-C -1 ; WX 778 ; N Odieresis ; B 107 -19 823 915 ;
-C -1 ; WX 611 ; N mu ; B 22 -207 658 532 ;
-C -1 ; WX 278 ; N igrave ; B 69 0 326 750 ;
-C -1 ; WX 611 ; N ohungarumlaut ; B 82 -14 784 750 ;
-C -1 ; WX 667 ; N Eogonek ; B 76 -224 757 718 ;
-C -1 ; WX 611 ; N dcroat ; B 82 -14 789 718 ;
-C -1 ; WX 834 ; N threequarters ; B 99 -19 839 710 ;
-C -1 ; WX 667 ; N Scedilla ; B 81 -228 718 737 ;
-C -1 ; WX 400 ; N lcaron ; B 69 0 561 718 ;
-C -1 ; WX 722 ; N Kcommaaccent ; B 87 -228 858 718 ;
-C -1 ; WX 611 ; N Lacute ; B 76 0 611 936 ;
-C -1 ; WX 1000 ; N trademark ; B 179 306 1109 718 ;
-C -1 ; WX 556 ; N edotaccent ; B 70 -14 593 729 ;
-C -1 ; WX 278 ; N Igrave ; B 64 0 367 936 ;
-C -1 ; WX 278 ; N Imacron ; B 64 0 496 864 ;
-C -1 ; WX 611 ; N Lcaron ; B 76 0 643 718 ;
-C -1 ; WX 834 ; N onehalf ; B 132 -19 858 710 ;
-C -1 ; WX 549 ; N lessequal ; B 29 0 676 704 ;
-C -1 ; WX 611 ; N ocircumflex ; B 82 -14 643 750 ;
-C -1 ; WX 611 ; N ntilde ; B 65 0 646 737 ;
-C -1 ; WX 722 ; N Uhungarumlaut ; B 116 -19 880 936 ;
-C -1 ; WX 667 ; N Eacute ; B 76 0 757 936 ;
-C -1 ; WX 556 ; N emacron ; B 70 -14 595 678 ;
-C -1 ; WX 611 ; N gbreve ; B 38 -217 666 750 ;
-C -1 ; WX 834 ; N onequarter ; B 132 -19 806 710 ;
-C -1 ; WX 667 ; N Scaron ; B 81 -19 718 936 ;
-C -1 ; WX 667 ; N Scommaaccent ; B 81 -228 718 737 ;
-C -1 ; WX 778 ; N Ohungarumlaut ; B 107 -19 908 936 ;
-C -1 ; WX 400 ; N degree ; B 175 426 467 712 ;
-C -1 ; WX 611 ; N ograve ; B 82 -14 643 750 ;
-C -1 ; WX 722 ; N Ccaron ; B 107 -19 789 936 ;
-C -1 ; WX 611 ; N ugrave ; B 98 -14 658 750 ;
-C -1 ; WX 549 ; N radical ; B 112 -46 689 850 ;
-C -1 ; WX 722 ; N Dcaron ; B 76 0 777 936 ;
-C -1 ; WX 389 ; N rcommaaccent ; B 26 -228 489 546 ;
-C -1 ; WX 722 ; N Ntilde ; B 69 0 807 923 ;
-C -1 ; WX 611 ; N otilde ; B 82 -14 646 737 ;
-C -1 ; WX 722 ; N Rcommaaccent ; B 76 -228 778 718 ;
-C -1 ; WX 611 ; N Lcommaaccent ; B 76 -228 611 718 ;
-C -1 ; WX 722 ; N Atilde ; B 20 0 741 923 ;
-C -1 ; WX 722 ; N Aogonek ; B 20 -224 702 718 ;
-C -1 ; WX 722 ; N Aring ; B 20 0 702 962 ;
-C -1 ; WX 778 ; N Otilde ; B 107 -19 823 923 ;
-C -1 ; WX 500 ; N zdotaccent ; B 20 0 583 729 ;
-C -1 ; WX 667 ; N Ecaron ; B 76 0 757 936 ;
-C -1 ; WX 278 ; N Iogonek ; B -41 -228 367 718 ;
-C -1 ; WX 556 ; N kcommaaccent ; B 69 -228 670 718 ;
-C -1 ; WX 584 ; N minus ; B 82 197 610 309 ;
-C -1 ; WX 278 ; N Icircumflex ; B 64 0 484 936 ;
-C -1 ; WX 611 ; N ncaron ; B 65 0 641 750 ;
-C -1 ; WX 333 ; N tcommaaccent ; B 58 -228 422 676 ;
-C -1 ; WX 584 ; N logicalnot ; B 105 108 633 419 ;
-C -1 ; WX 611 ; N odieresis ; B 82 -14 643 729 ;
-C -1 ; WX 611 ; N udieresis ; B 98 -14 658 729 ;
-C -1 ; WX 549 ; N notequal ; B 32 -49 630 570 ;
-C -1 ; WX 611 ; N gcommaaccent ; B 38 -217 666 850 ;
-C -1 ; WX 611 ; N eth ; B 82 -14 670 737 ;
-C -1 ; WX 500 ; N zcaron ; B 20 0 586 750 ;
-C -1 ; WX 611 ; N ncommaaccent ; B 65 -228 629 546 ;
-C -1 ; WX 333 ; N onesuperior ; B 148 283 388 710 ;
-C -1 ; WX 278 ; N imacron ; B 69 0 429 678 ;
-C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 2481
-KPX A C -40
-KPX A Cacute -40
-KPX A Ccaron -40
-KPX A Ccedilla -40
-KPX A G -50
-KPX A Gbreve -50
-KPX A Gcommaaccent -50
-KPX A O -40
-KPX A Oacute -40
-KPX A Ocircumflex -40
-KPX A Odieresis -40
-KPX A Ograve -40
-KPX A Ohungarumlaut -40
-KPX A Omacron -40
-KPX A Oslash -40
-KPX A Otilde -40
-KPX A Q -40
-KPX A T -90
-KPX A Tcaron -90
-KPX A Tcommaaccent -90
-KPX A U -50
-KPX A Uacute -50
-KPX A Ucircumflex -50
-KPX A Udieresis -50
-KPX A Ugrave -50
-KPX A Uhungarumlaut -50
-KPX A Umacron -50
-KPX A Uogonek -50
-KPX A Uring -50
-KPX A V -80
-KPX A W -60
-KPX A Y -110
-KPX A Yacute -110
-KPX A Ydieresis -110
-KPX A u -30
-KPX A uacute -30
-KPX A ucircumflex -30
-KPX A udieresis -30
-KPX A ugrave -30
-KPX A uhungarumlaut -30
-KPX A umacron -30
-KPX A uogonek -30
-KPX A uring -30
-KPX A v -40
-KPX A w -30
-KPX A y -30
-KPX A yacute -30
-KPX A ydieresis -30
-KPX Aacute C -40
-KPX Aacute Cacute -40
-KPX Aacute Ccaron -40
-KPX Aacute Ccedilla -40
-KPX Aacute G -50
-KPX Aacute Gbreve -50
-KPX Aacute Gcommaaccent -50
-KPX Aacute O -40
-KPX Aacute Oacute -40
-KPX Aacute Ocircumflex -40
-KPX Aacute Odieresis -40
-KPX Aacute Ograve -40
-KPX Aacute Ohungarumlaut -40
-KPX Aacute Omacron -40
-KPX Aacute Oslash -40
-KPX Aacute Otilde -40
-KPX Aacute Q -40
-KPX Aacute T -90
-KPX Aacute Tcaron -90
-KPX Aacute Tcommaaccent -90
-KPX Aacute U -50
-KPX Aacute Uacute -50
-KPX Aacute Ucircumflex -50
-KPX Aacute Udieresis -50
-KPX Aacute Ugrave -50
-KPX Aacute Uhungarumlaut -50
-KPX Aacute Umacron -50
-KPX Aacute Uogonek -50
-KPX Aacute Uring -50
-KPX Aacute V -80
-KPX Aacute W -60
-KPX Aacute Y -110
-KPX Aacute Yacute -110
-KPX Aacute Ydieresis -110
-KPX Aacute u -30
-KPX Aacute uacute -30
-KPX Aacute ucircumflex -30
-KPX Aacute udieresis -30
-KPX Aacute ugrave -30
-KPX Aacute uhungarumlaut -30
-KPX Aacute umacron -30
-KPX Aacute uogonek -30
-KPX Aacute uring -30
-KPX Aacute v -40
-KPX Aacute w -30
-KPX Aacute y -30
-KPX Aacute yacute -30
-KPX Aacute ydieresis -30
-KPX Abreve C -40
-KPX Abreve Cacute -40
-KPX Abreve Ccaron -40
-KPX Abreve Ccedilla -40
-KPX Abreve G -50
-KPX Abreve Gbreve -50
-KPX Abreve Gcommaaccent -50
-KPX Abreve O -40
-KPX Abreve Oacute -40
-KPX Abreve Ocircumflex -40
-KPX Abreve Odieresis -40
-KPX Abreve Ograve -40
-KPX Abreve Ohungarumlaut -40
-KPX Abreve Omacron -40
-KPX Abreve Oslash -40
-KPX Abreve Otilde -40
-KPX Abreve Q -40
-KPX Abreve T -90
-KPX Abreve Tcaron -90
-KPX Abreve Tcommaaccent -90
-KPX Abreve U -50
-KPX Abreve Uacute -50
-KPX Abreve Ucircumflex -50
-KPX Abreve Udieresis -50
-KPX Abreve Ugrave -50
-KPX Abreve Uhungarumlaut -50
-KPX Abreve Umacron -50
-KPX Abreve Uogonek -50
-KPX Abreve Uring -50
-KPX Abreve V -80
-KPX Abreve W -60
-KPX Abreve Y -110
-KPX Abreve Yacute -110
-KPX Abreve Ydieresis -110
-KPX Abreve u -30
-KPX Abreve uacute -30
-KPX Abreve ucircumflex -30
-KPX Abreve udieresis -30
-KPX Abreve ugrave -30
-KPX Abreve uhungarumlaut -30
-KPX Abreve umacron -30
-KPX Abreve uogonek -30
-KPX Abreve uring -30
-KPX Abreve v -40
-KPX Abreve w -30
-KPX Abreve y -30
-KPX Abreve yacute -30
-KPX Abreve ydieresis -30
-KPX Acircumflex C -40
-KPX Acircumflex Cacute -40
-KPX Acircumflex Ccaron -40
-KPX Acircumflex Ccedilla -40
-KPX Acircumflex G -50
-KPX Acircumflex Gbreve -50
-KPX Acircumflex Gcommaaccent -50
-KPX Acircumflex O -40
-KPX Acircumflex Oacute -40
-KPX Acircumflex Ocircumflex -40
-KPX Acircumflex Odieresis -40
-KPX Acircumflex Ograve -40
-KPX Acircumflex Ohungarumlaut -40
-KPX Acircumflex Omacron -40
-KPX Acircumflex Oslash -40
-KPX Acircumflex Otilde -40
-KPX Acircumflex Q -40
-KPX Acircumflex T -90
-KPX Acircumflex Tcaron -90
-KPX Acircumflex Tcommaaccent -90
-KPX Acircumflex U -50
-KPX Acircumflex Uacute -50
-KPX Acircumflex Ucircumflex -50
-KPX Acircumflex Udieresis -50
-KPX Acircumflex Ugrave -50
-KPX Acircumflex Uhungarumlaut -50
-KPX Acircumflex Umacron -50
-KPX Acircumflex Uogonek -50
-KPX Acircumflex Uring -50
-KPX Acircumflex V -80
-KPX Acircumflex W -60
-KPX Acircumflex Y -110
-KPX Acircumflex Yacute -110
-KPX Acircumflex Ydieresis -110
-KPX Acircumflex u -30
-KPX Acircumflex uacute -30
-KPX Acircumflex ucircumflex -30
-KPX Acircumflex udieresis -30
-KPX Acircumflex ugrave -30
-KPX Acircumflex uhungarumlaut -30
-KPX Acircumflex umacron -30
-KPX Acircumflex uogonek -30
-KPX Acircumflex uring -30
-KPX Acircumflex v -40
-KPX Acircumflex w -30
-KPX Acircumflex y -30
-KPX Acircumflex yacute -30
-KPX Acircumflex ydieresis -30
-KPX Adieresis C -40
-KPX Adieresis Cacute -40
-KPX Adieresis Ccaron -40
-KPX Adieresis Ccedilla -40
-KPX Adieresis G -50
-KPX Adieresis Gbreve -50
-KPX Adieresis Gcommaaccent -50
-KPX Adieresis O -40
-KPX Adieresis Oacute -40
-KPX Adieresis Ocircumflex -40
-KPX Adieresis Odieresis -40
-KPX Adieresis Ograve -40
-KPX Adieresis Ohungarumlaut -40
-KPX Adieresis Omacron -40
-KPX Adieresis Oslash -40
-KPX Adieresis Otilde -40
-KPX Adieresis Q -40
-KPX Adieresis T -90
-KPX Adieresis Tcaron -90
-KPX Adieresis Tcommaaccent -90
-KPX Adieresis U -50
-KPX Adieresis Uacute -50
-KPX Adieresis Ucircumflex -50
-KPX Adieresis Udieresis -50
-KPX Adieresis Ugrave -50
-KPX Adieresis Uhungarumlaut -50
-KPX Adieresis Umacron -50
-KPX Adieresis Uogonek -50
-KPX Adieresis Uring -50
-KPX Adieresis V -80
-KPX Adieresis W -60
-KPX Adieresis Y -110
-KPX Adieresis Yacute -110
-KPX Adieresis Ydieresis -110
-KPX Adieresis u -30
-KPX Adieresis uacute -30
-KPX Adieresis ucircumflex -30
-KPX Adieresis udieresis -30
-KPX Adieresis ugrave -30
-KPX Adieresis uhungarumlaut -30
-KPX Adieresis umacron -30
-KPX Adieresis uogonek -30
-KPX Adieresis uring -30
-KPX Adieresis v -40
-KPX Adieresis w -30
-KPX Adieresis y -30
-KPX Adieresis yacute -30
-KPX Adieresis ydieresis -30
-KPX Agrave C -40
-KPX Agrave Cacute -40
-KPX Agrave Ccaron -40
-KPX Agrave Ccedilla -40
-KPX Agrave G -50
-KPX Agrave Gbreve -50
-KPX Agrave Gcommaaccent -50
-KPX Agrave O -40
-KPX Agrave Oacute -40
-KPX Agrave Ocircumflex -40
-KPX Agrave Odieresis -40
-KPX Agrave Ograve -40
-KPX Agrave Ohungarumlaut -40
-KPX Agrave Omacron -40
-KPX Agrave Oslash -40
-KPX Agrave Otilde -40
-KPX Agrave Q -40
-KPX Agrave T -90
-KPX Agrave Tcaron -90
-KPX Agrave Tcommaaccent -90
-KPX Agrave U -50
-KPX Agrave Uacute -50
-KPX Agrave Ucircumflex -50
-KPX Agrave Udieresis -50
-KPX Agrave Ugrave -50
-KPX Agrave Uhungarumlaut -50
-KPX Agrave Umacron -50
-KPX Agrave Uogonek -50
-KPX Agrave Uring -50
-KPX Agrave V -80
-KPX Agrave W -60
-KPX Agrave Y -110
-KPX Agrave Yacute -110
-KPX Agrave Ydieresis -110
-KPX Agrave u -30
-KPX Agrave uacute -30
-KPX Agrave ucircumflex -30
-KPX Agrave udieresis -30
-KPX Agrave ugrave -30
-KPX Agrave uhungarumlaut -30
-KPX Agrave umacron -30
-KPX Agrave uogonek -30
-KPX Agrave uring -30
-KPX Agrave v -40
-KPX Agrave w -30
-KPX Agrave y -30
-KPX Agrave yacute -30
-KPX Agrave ydieresis -30
-KPX Amacron C -40
-KPX Amacron Cacute -40
-KPX Amacron Ccaron -40
-KPX Amacron Ccedilla -40
-KPX Amacron G -50
-KPX Amacron Gbreve -50
-KPX Amacron Gcommaaccent -50
-KPX Amacron O -40
-KPX Amacron Oacute -40
-KPX Amacron Ocircumflex -40
-KPX Amacron Odieresis -40
-KPX Amacron Ograve -40
-KPX Amacron Ohungarumlaut -40
-KPX Amacron Omacron -40
-KPX Amacron Oslash -40
-KPX Amacron Otilde -40
-KPX Amacron Q -40
-KPX Amacron T -90
-KPX Amacron Tcaron -90
-KPX Amacron Tcommaaccent -90
-KPX Amacron U -50
-KPX Amacron Uacute -50
-KPX Amacron Ucircumflex -50
-KPX Amacron Udieresis -50
-KPX Amacron Ugrave -50
-KPX Amacron Uhungarumlaut -50
-KPX Amacron Umacron -50
-KPX Amacron Uogonek -50
-KPX Amacron Uring -50
-KPX Amacron V -80
-KPX Amacron W -60
-KPX Amacron Y -110
-KPX Amacron Yacute -110
-KPX Amacron Ydieresis -110
-KPX Amacron u -30
-KPX Amacron uacute -30
-KPX Amacron ucircumflex -30
-KPX Amacron udieresis -30
-KPX Amacron ugrave -30
-KPX Amacron uhungarumlaut -30
-KPX Amacron umacron -30
-KPX Amacron uogonek -30
-KPX Amacron uring -30
-KPX Amacron v -40
-KPX Amacron w -30
-KPX Amacron y -30
-KPX Amacron yacute -30
-KPX Amacron ydieresis -30
-KPX Aogonek C -40
-KPX Aogonek Cacute -40
-KPX Aogonek Ccaron -40
-KPX Aogonek Ccedilla -40
-KPX Aogonek G -50
-KPX Aogonek Gbreve -50
-KPX Aogonek Gcommaaccent -50
-KPX Aogonek O -40
-KPX Aogonek Oacute -40
-KPX Aogonek Ocircumflex -40
-KPX Aogonek Odieresis -40
-KPX Aogonek Ograve -40
-KPX Aogonek Ohungarumlaut -40
-KPX Aogonek Omacron -40
-KPX Aogonek Oslash -40
-KPX Aogonek Otilde -40
-KPX Aogonek Q -40
-KPX Aogonek T -90
-KPX Aogonek Tcaron -90
-KPX Aogonek Tcommaaccent -90
-KPX Aogonek U -50
-KPX Aogonek Uacute -50
-KPX Aogonek Ucircumflex -50
-KPX Aogonek Udieresis -50
-KPX Aogonek Ugrave -50
-KPX Aogonek Uhungarumlaut -50
-KPX Aogonek Umacron -50
-KPX Aogonek Uogonek -50
-KPX Aogonek Uring -50
-KPX Aogonek V -80
-KPX Aogonek W -60
-KPX Aogonek Y -110
-KPX Aogonek Yacute -110
-KPX Aogonek Ydieresis -110
-KPX Aogonek u -30
-KPX Aogonek uacute -30
-KPX Aogonek ucircumflex -30
-KPX Aogonek udieresis -30
-KPX Aogonek ugrave -30
-KPX Aogonek uhungarumlaut -30
-KPX Aogonek umacron -30
-KPX Aogonek uogonek -30
-KPX Aogonek uring -30
-KPX Aogonek v -40
-KPX Aogonek w -30
-KPX Aogonek y -30
-KPX Aogonek yacute -30
-KPX Aogonek ydieresis -30
-KPX Aring C -40
-KPX Aring Cacute -40
-KPX Aring Ccaron -40
-KPX Aring Ccedilla -40
-KPX Aring G -50
-KPX Aring Gbreve -50
-KPX Aring Gcommaaccent -50
-KPX Aring O -40
-KPX Aring Oacute -40
-KPX Aring Ocircumflex -40
-KPX Aring Odieresis -40
-KPX Aring Ograve -40
-KPX Aring Ohungarumlaut -40
-KPX Aring Omacron -40
-KPX Aring Oslash -40
-KPX Aring Otilde -40
-KPX Aring Q -40
-KPX Aring T -90
-KPX Aring Tcaron -90
-KPX Aring Tcommaaccent -90
-KPX Aring U -50
-KPX Aring Uacute -50
-KPX Aring Ucircumflex -50
-KPX Aring Udieresis -50
-KPX Aring Ugrave -50
-KPX Aring Uhungarumlaut -50
-KPX Aring Umacron -50
-KPX Aring Uogonek -50
-KPX Aring Uring -50
-KPX Aring V -80
-KPX Aring W -60
-KPX Aring Y -110
-KPX Aring Yacute -110
-KPX Aring Ydieresis -110
-KPX Aring u -30
-KPX Aring uacute -30
-KPX Aring ucircumflex -30
-KPX Aring udieresis -30
-KPX Aring ugrave -30
-KPX Aring uhungarumlaut -30
-KPX Aring umacron -30
-KPX Aring uogonek -30
-KPX Aring uring -30
-KPX Aring v -40
-KPX Aring w -30
-KPX Aring y -30
-KPX Aring yacute -30
-KPX Aring ydieresis -30
-KPX Atilde C -40
-KPX Atilde Cacute -40
-KPX Atilde Ccaron -40
-KPX Atilde Ccedilla -40
-KPX Atilde G -50
-KPX Atilde Gbreve -50
-KPX Atilde Gcommaaccent -50
-KPX Atilde O -40
-KPX Atilde Oacute -40
-KPX Atilde Ocircumflex -40
-KPX Atilde Odieresis -40
-KPX Atilde Ograve -40
-KPX Atilde Ohungarumlaut -40
-KPX Atilde Omacron -40
-KPX Atilde Oslash -40
-KPX Atilde Otilde -40
-KPX Atilde Q -40
-KPX Atilde T -90
-KPX Atilde Tcaron -90
-KPX Atilde Tcommaaccent -90
-KPX Atilde U -50
-KPX Atilde Uacute -50
-KPX Atilde Ucircumflex -50
-KPX Atilde Udieresis -50
-KPX Atilde Ugrave -50
-KPX Atilde Uhungarumlaut -50
-KPX Atilde Umacron -50
-KPX Atilde Uogonek -50
-KPX Atilde Uring -50
-KPX Atilde V -80
-KPX Atilde W -60
-KPX Atilde Y -110
-KPX Atilde Yacute -110
-KPX Atilde Ydieresis -110
-KPX Atilde u -30
-KPX Atilde uacute -30
-KPX Atilde ucircumflex -30
-KPX Atilde udieresis -30
-KPX Atilde ugrave -30
-KPX Atilde uhungarumlaut -30
-KPX Atilde umacron -30
-KPX Atilde uogonek -30
-KPX Atilde uring -30
-KPX Atilde v -40
-KPX Atilde w -30
-KPX Atilde y -30
-KPX Atilde yacute -30
-KPX Atilde ydieresis -30
-KPX B A -30
-KPX B Aacute -30
-KPX B Abreve -30
-KPX B Acircumflex -30
-KPX B Adieresis -30
-KPX B Agrave -30
-KPX B Amacron -30
-KPX B Aogonek -30
-KPX B Aring -30
-KPX B Atilde -30
-KPX B U -10
-KPX B Uacute -10
-KPX B Ucircumflex -10
-KPX B Udieresis -10
-KPX B Ugrave -10
-KPX B Uhungarumlaut -10
-KPX B Umacron -10
-KPX B Uogonek -10
-KPX B Uring -10
-KPX D A -40
-KPX D Aacute -40
-KPX D Abreve -40
-KPX D Acircumflex -40
-KPX D Adieresis -40
-KPX D Agrave -40
-KPX D Amacron -40
-KPX D Aogonek -40
-KPX D Aring -40
-KPX D Atilde -40
-KPX D V -40
-KPX D W -40
-KPX D Y -70
-KPX D Yacute -70
-KPX D Ydieresis -70
-KPX D comma -30
-KPX D period -30
-KPX Dcaron A -40
-KPX Dcaron Aacute -40
-KPX Dcaron Abreve -40
-KPX Dcaron Acircumflex -40
-KPX Dcaron Adieresis -40
-KPX Dcaron Agrave -40
-KPX Dcaron Amacron -40
-KPX Dcaron Aogonek -40
-KPX Dcaron Aring -40
-KPX Dcaron Atilde -40
-KPX Dcaron V -40
-KPX Dcaron W -40
-KPX Dcaron Y -70
-KPX Dcaron Yacute -70
-KPX Dcaron Ydieresis -70
-KPX Dcaron comma -30
-KPX Dcaron period -30
-KPX Dcroat A -40
-KPX Dcroat Aacute -40
-KPX Dcroat Abreve -40
-KPX Dcroat Acircumflex -40
-KPX Dcroat Adieresis -40
-KPX Dcroat Agrave -40
-KPX Dcroat Amacron -40
-KPX Dcroat Aogonek -40
-KPX Dcroat Aring -40
-KPX Dcroat Atilde -40
-KPX Dcroat V -40
-KPX Dcroat W -40
-KPX Dcroat Y -70
-KPX Dcroat Yacute -70
-KPX Dcroat Ydieresis -70
-KPX Dcroat comma -30
-KPX Dcroat period -30
-KPX F A -80
-KPX F Aacute -80
-KPX F Abreve -80
-KPX F Acircumflex -80
-KPX F Adieresis -80
-KPX F Agrave -80
-KPX F Amacron -80
-KPX F Aogonek -80
-KPX F Aring -80
-KPX F Atilde -80
-KPX F a -20
-KPX F aacute -20
-KPX F abreve -20
-KPX F acircumflex -20
-KPX F adieresis -20
-KPX F agrave -20
-KPX F amacron -20
-KPX F aogonek -20
-KPX F aring -20
-KPX F atilde -20
-KPX F comma -100
-KPX F period -100
-KPX J A -20
-KPX J Aacute -20
-KPX J Abreve -20
-KPX J Acircumflex -20
-KPX J Adieresis -20
-KPX J Agrave -20
-KPX J Amacron -20
-KPX J Aogonek -20
-KPX J Aring -20
-KPX J Atilde -20
-KPX J comma -20
-KPX J period -20
-KPX J u -20
-KPX J uacute -20
-KPX J ucircumflex -20
-KPX J udieresis -20
-KPX J ugrave -20
-KPX J uhungarumlaut -20
-KPX J umacron -20
-KPX J uogonek -20
-KPX J uring -20
-KPX K O -30
-KPX K Oacute -30
-KPX K Ocircumflex -30
-KPX K Odieresis -30
-KPX K Ograve -30
-KPX K Ohungarumlaut -30
-KPX K Omacron -30
-KPX K Oslash -30
-KPX K Otilde -30
-KPX K e -15
-KPX K eacute -15
-KPX K ecaron -15
-KPX K ecircumflex -15
-KPX K edieresis -15
-KPX K edotaccent -15
-KPX K egrave -15
-KPX K emacron -15
-KPX K eogonek -15
-KPX K o -35
-KPX K oacute -35
-KPX K ocircumflex -35
-KPX K odieresis -35
-KPX K ograve -35
-KPX K ohungarumlaut -35
-KPX K omacron -35
-KPX K oslash -35
-KPX K otilde -35
-KPX K u -30
-KPX K uacute -30
-KPX K ucircumflex -30
-KPX K udieresis -30
-KPX K ugrave -30
-KPX K uhungarumlaut -30
-KPX K umacron -30
-KPX K uogonek -30
-KPX K uring -30
-KPX K y -40
-KPX K yacute -40
-KPX K ydieresis -40
-KPX Kcommaaccent O -30
-KPX Kcommaaccent Oacute -30
-KPX Kcommaaccent Ocircumflex -30
-KPX Kcommaaccent Odieresis -30
-KPX Kcommaaccent Ograve -30
-KPX Kcommaaccent Ohungarumlaut -30
-KPX Kcommaaccent Omacron -30
-KPX Kcommaaccent Oslash -30
-KPX Kcommaaccent Otilde -30
-KPX Kcommaaccent e -15
-KPX Kcommaaccent eacute -15
-KPX Kcommaaccent ecaron -15
-KPX Kcommaaccent ecircumflex -15
-KPX Kcommaaccent edieresis -15
-KPX Kcommaaccent edotaccent -15
-KPX Kcommaaccent egrave -15
-KPX Kcommaaccent emacron -15
-KPX Kcommaaccent eogonek -15
-KPX Kcommaaccent o -35
-KPX Kcommaaccent oacute -35
-KPX Kcommaaccent ocircumflex -35
-KPX Kcommaaccent odieresis -35
-KPX Kcommaaccent ograve -35
-KPX Kcommaaccent ohungarumlaut -35
-KPX Kcommaaccent omacron -35
-KPX Kcommaaccent oslash -35
-KPX Kcommaaccent otilde -35
-KPX Kcommaaccent u -30
-KPX Kcommaaccent uacute -30
-KPX Kcommaaccent ucircumflex -30
-KPX Kcommaaccent udieresis -30
-KPX Kcommaaccent ugrave -30
-KPX Kcommaaccent uhungarumlaut -30
-KPX Kcommaaccent umacron -30
-KPX Kcommaaccent uogonek -30
-KPX Kcommaaccent uring -30
-KPX Kcommaaccent y -40
-KPX Kcommaaccent yacute -40
-KPX Kcommaaccent ydieresis -40
-KPX L T -90
-KPX L Tcaron -90
-KPX L Tcommaaccent -90
-KPX L V -110
-KPX L W -80
-KPX L Y -120
-KPX L Yacute -120
-KPX L Ydieresis -120
-KPX L quotedblright -140
-KPX L quoteright -140
-KPX L y -30
-KPX L yacute -30
-KPX L ydieresis -30
-KPX Lacute T -90
-KPX Lacute Tcaron -90
-KPX Lacute Tcommaaccent -90
-KPX Lacute V -110
-KPX Lacute W -80
-KPX Lacute Y -120
-KPX Lacute Yacute -120
-KPX Lacute Ydieresis -120
-KPX Lacute quotedblright -140
-KPX Lacute quoteright -140
-KPX Lacute y -30
-KPX Lacute yacute -30
-KPX Lacute ydieresis -30
-KPX Lcommaaccent T -90
-KPX Lcommaaccent Tcaron -90
-KPX Lcommaaccent Tcommaaccent -90
-KPX Lcommaaccent V -110
-KPX Lcommaaccent W -80
-KPX Lcommaaccent Y -120
-KPX Lcommaaccent Yacute -120
-KPX Lcommaaccent Ydieresis -120
-KPX Lcommaaccent quotedblright -140
-KPX Lcommaaccent quoteright -140
-KPX Lcommaaccent y -30
-KPX Lcommaaccent yacute -30
-KPX Lcommaaccent ydieresis -30
-KPX Lslash T -90
-KPX Lslash Tcaron -90
-KPX Lslash Tcommaaccent -90
-KPX Lslash V -110
-KPX Lslash W -80
-KPX Lslash Y -120
-KPX Lslash Yacute -120
-KPX Lslash Ydieresis -120
-KPX Lslash quotedblright -140
-KPX Lslash quoteright -140
-KPX Lslash y -30
-KPX Lslash yacute -30
-KPX Lslash ydieresis -30
-KPX O A -50
-KPX O Aacute -50
-KPX O Abreve -50
-KPX O Acircumflex -50
-KPX O Adieresis -50
-KPX O Agrave -50
-KPX O Amacron -50
-KPX O Aogonek -50
-KPX O Aring -50
-KPX O Atilde -50
-KPX O T -40
-KPX O Tcaron -40
-KPX O Tcommaaccent -40
-KPX O V -50
-KPX O W -50
-KPX O X -50
-KPX O Y -70
-KPX O Yacute -70
-KPX O Ydieresis -70
-KPX O comma -40
-KPX O period -40
-KPX Oacute A -50
-KPX Oacute Aacute -50
-KPX Oacute Abreve -50
-KPX Oacute Acircumflex -50
-KPX Oacute Adieresis -50
-KPX Oacute Agrave -50
-KPX Oacute Amacron -50
-KPX Oacute Aogonek -50
-KPX Oacute Aring -50
-KPX Oacute Atilde -50
-KPX Oacute T -40
-KPX Oacute Tcaron -40
-KPX Oacute Tcommaaccent -40
-KPX Oacute V -50
-KPX Oacute W -50
-KPX Oacute X -50
-KPX Oacute Y -70
-KPX Oacute Yacute -70
-KPX Oacute Ydieresis -70
-KPX Oacute comma -40
-KPX Oacute period -40
-KPX Ocircumflex A -50
-KPX Ocircumflex Aacute -50
-KPX Ocircumflex Abreve -50
-KPX Ocircumflex Acircumflex -50
-KPX Ocircumflex Adieresis -50
-KPX Ocircumflex Agrave -50
-KPX Ocircumflex Amacron -50
-KPX Ocircumflex Aogonek -50
-KPX Ocircumflex Aring -50
-KPX Ocircumflex Atilde -50
-KPX Ocircumflex T -40
-KPX Ocircumflex Tcaron -40
-KPX Ocircumflex Tcommaaccent -40
-KPX Ocircumflex V -50
-KPX Ocircumflex W -50
-KPX Ocircumflex X -50
-KPX Ocircumflex Y -70
-KPX Ocircumflex Yacute -70
-KPX Ocircumflex Ydieresis -70
-KPX Ocircumflex comma -40
-KPX Ocircumflex period -40
-KPX Odieresis A -50
-KPX Odieresis Aacute -50
-KPX Odieresis Abreve -50
-KPX Odieresis Acircumflex -50
-KPX Odieresis Adieresis -50
-KPX Odieresis Agrave -50
-KPX Odieresis Amacron -50
-KPX Odieresis Aogonek -50
-KPX Odieresis Aring -50
-KPX Odieresis Atilde -50
-KPX Odieresis T -40
-KPX Odieresis Tcaron -40
-KPX Odieresis Tcommaaccent -40
-KPX Odieresis V -50
-KPX Odieresis W -50
-KPX Odieresis X -50
-KPX Odieresis Y -70
-KPX Odieresis Yacute -70
-KPX Odieresis Ydieresis -70
-KPX Odieresis comma -40
-KPX Odieresis period -40
-KPX Ograve A -50
-KPX Ograve Aacute -50
-KPX Ograve Abreve -50
-KPX Ograve Acircumflex -50
-KPX Ograve Adieresis -50
-KPX Ograve Agrave -50
-KPX Ograve Amacron -50
-KPX Ograve Aogonek -50
-KPX Ograve Aring -50
-KPX Ograve Atilde -50
-KPX Ograve T -40
-KPX Ograve Tcaron -40
-KPX Ograve Tcommaaccent -40
-KPX Ograve V -50
-KPX Ograve W -50
-KPX Ograve X -50
-KPX Ograve Y -70
-KPX Ograve Yacute -70
-KPX Ograve Ydieresis -70
-KPX Ograve comma -40
-KPX Ograve period -40
-KPX Ohungarumlaut A -50
-KPX Ohungarumlaut Aacute -50
-KPX Ohungarumlaut Abreve -50
-KPX Ohungarumlaut Acircumflex -50
-KPX Ohungarumlaut Adieresis -50
-KPX Ohungarumlaut Agrave -50
-KPX Ohungarumlaut Amacron -50
-KPX Ohungarumlaut Aogonek -50
-KPX Ohungarumlaut Aring -50
-KPX Ohungarumlaut Atilde -50
-KPX Ohungarumlaut T -40
-KPX Ohungarumlaut Tcaron -40
-KPX Ohungarumlaut Tcommaaccent -40
-KPX Ohungarumlaut V -50
-KPX Ohungarumlaut W -50
-KPX Ohungarumlaut X -50
-KPX Ohungarumlaut Y -70
-KPX Ohungarumlaut Yacute -70
-KPX Ohungarumlaut Ydieresis -70
-KPX Ohungarumlaut comma -40
-KPX Ohungarumlaut period -40
-KPX Omacron A -50
-KPX Omacron Aacute -50
-KPX Omacron Abreve -50
-KPX Omacron Acircumflex -50
-KPX Omacron Adieresis -50
-KPX Omacron Agrave -50
-KPX Omacron Amacron -50
-KPX Omacron Aogonek -50
-KPX Omacron Aring -50
-KPX Omacron Atilde -50
-KPX Omacron T -40
-KPX Omacron Tcaron -40
-KPX Omacron Tcommaaccent -40
-KPX Omacron V -50
-KPX Omacron W -50
-KPX Omacron X -50
-KPX Omacron Y -70
-KPX Omacron Yacute -70
-KPX Omacron Ydieresis -70
-KPX Omacron comma -40
-KPX Omacron period -40
-KPX Oslash A -50
-KPX Oslash Aacute -50
-KPX Oslash Abreve -50
-KPX Oslash Acircumflex -50
-KPX Oslash Adieresis -50
-KPX Oslash Agrave -50
-KPX Oslash Amacron -50
-KPX Oslash Aogonek -50
-KPX Oslash Aring -50
-KPX Oslash Atilde -50
-KPX Oslash T -40
-KPX Oslash Tcaron -40
-KPX Oslash Tcommaaccent -40
-KPX Oslash V -50
-KPX Oslash W -50
-KPX Oslash X -50
-KPX Oslash Y -70
-KPX Oslash Yacute -70
-KPX Oslash Ydieresis -70
-KPX Oslash comma -40
-KPX Oslash period -40
-KPX Otilde A -50
-KPX Otilde Aacute -50
-KPX Otilde Abreve -50
-KPX Otilde Acircumflex -50
-KPX Otilde Adieresis -50
-KPX Otilde Agrave -50
-KPX Otilde Amacron -50
-KPX Otilde Aogonek -50
-KPX Otilde Aring -50
-KPX Otilde Atilde -50
-KPX Otilde T -40
-KPX Otilde Tcaron -40
-KPX Otilde Tcommaaccent -40
-KPX Otilde V -50
-KPX Otilde W -50
-KPX Otilde X -50
-KPX Otilde Y -70
-KPX Otilde Yacute -70
-KPX Otilde Ydieresis -70
-KPX Otilde comma -40
-KPX Otilde period -40
-KPX P A -100
-KPX P Aacute -100
-KPX P Abreve -100
-KPX P Acircumflex -100
-KPX P Adieresis -100
-KPX P Agrave -100
-KPX P Amacron -100
-KPX P Aogonek -100
-KPX P Aring -100
-KPX P Atilde -100
-KPX P a -30
-KPX P aacute -30
-KPX P abreve -30
-KPX P acircumflex -30
-KPX P adieresis -30
-KPX P agrave -30
-KPX P amacron -30
-KPX P aogonek -30
-KPX P aring -30
-KPX P atilde -30
-KPX P comma -120
-KPX P e -30
-KPX P eacute -30
-KPX P ecaron -30
-KPX P ecircumflex -30
-KPX P edieresis -30
-KPX P edotaccent -30
-KPX P egrave -30
-KPX P emacron -30
-KPX P eogonek -30
-KPX P o -40
-KPX P oacute -40
-KPX P ocircumflex -40
-KPX P odieresis -40
-KPX P ograve -40
-KPX P ohungarumlaut -40
-KPX P omacron -40
-KPX P oslash -40
-KPX P otilde -40
-KPX P period -120
-KPX Q U -10
-KPX Q Uacute -10
-KPX Q Ucircumflex -10
-KPX Q Udieresis -10
-KPX Q Ugrave -10
-KPX Q Uhungarumlaut -10
-KPX Q Umacron -10
-KPX Q Uogonek -10
-KPX Q Uring -10
-KPX Q comma 20
-KPX Q period 20
-KPX R O -20
-KPX R Oacute -20
-KPX R Ocircumflex -20
-KPX R Odieresis -20
-KPX R Ograve -20
-KPX R Ohungarumlaut -20
-KPX R Omacron -20
-KPX R Oslash -20
-KPX R Otilde -20
-KPX R T -20
-KPX R Tcaron -20
-KPX R Tcommaaccent -20
-KPX R U -20
-KPX R Uacute -20
-KPX R Ucircumflex -20
-KPX R Udieresis -20
-KPX R Ugrave -20
-KPX R Uhungarumlaut -20
-KPX R Umacron -20
-KPX R Uogonek -20
-KPX R Uring -20
-KPX R V -50
-KPX R W -40
-KPX R Y -50
-KPX R Yacute -50
-KPX R Ydieresis -50
-KPX Racute O -20
-KPX Racute Oacute -20
-KPX Racute Ocircumflex -20
-KPX Racute Odieresis -20
-KPX Racute Ograve -20
-KPX Racute Ohungarumlaut -20
-KPX Racute Omacron -20
-KPX Racute Oslash -20
-KPX Racute Otilde -20
-KPX Racute T -20
-KPX Racute Tcaron -20
-KPX Racute Tcommaaccent -20
-KPX Racute U -20
-KPX Racute Uacute -20
-KPX Racute Ucircumflex -20
-KPX Racute Udieresis -20
-KPX Racute Ugrave -20
-KPX Racute Uhungarumlaut -20
-KPX Racute Umacron -20
-KPX Racute Uogonek -20
-KPX Racute Uring -20
-KPX Racute V -50
-KPX Racute W -40
-KPX Racute Y -50
-KPX Racute Yacute -50
-KPX Racute Ydieresis -50
-KPX Rcaron O -20
-KPX Rcaron Oacute -20
-KPX Rcaron Ocircumflex -20
-KPX Rcaron Odieresis -20
-KPX Rcaron Ograve -20
-KPX Rcaron Ohungarumlaut -20
-KPX Rcaron Omacron -20
-KPX Rcaron Oslash -20
-KPX Rcaron Otilde -20
-KPX Rcaron T -20
-KPX Rcaron Tcaron -20
-KPX Rcaron Tcommaaccent -20
-KPX Rcaron U -20
-KPX Rcaron Uacute -20
-KPX Rcaron Ucircumflex -20
-KPX Rcaron Udieresis -20
-KPX Rcaron Ugrave -20
-KPX Rcaron Uhungarumlaut -20
-KPX Rcaron Umacron -20
-KPX Rcaron Uogonek -20
-KPX Rcaron Uring -20
-KPX Rcaron V -50
-KPX Rcaron W -40
-KPX Rcaron Y -50
-KPX Rcaron Yacute -50
-KPX Rcaron Ydieresis -50
-KPX Rcommaaccent O -20
-KPX Rcommaaccent Oacute -20
-KPX Rcommaaccent Ocircumflex -20
-KPX Rcommaaccent Odieresis -20
-KPX Rcommaaccent Ograve -20
-KPX Rcommaaccent Ohungarumlaut -20
-KPX Rcommaaccent Omacron -20
-KPX Rcommaaccent Oslash -20
-KPX Rcommaaccent Otilde -20
-KPX Rcommaaccent T -20
-KPX Rcommaaccent Tcaron -20
-KPX Rcommaaccent Tcommaaccent -20
-KPX Rcommaaccent U -20
-KPX Rcommaaccent Uacute -20
-KPX Rcommaaccent Ucircumflex -20
-KPX Rcommaaccent Udieresis -20
-KPX Rcommaaccent Ugrave -20
-KPX Rcommaaccent Uhungarumlaut -20
-KPX Rcommaaccent Umacron -20
-KPX Rcommaaccent Uogonek -20
-KPX Rcommaaccent Uring -20
-KPX Rcommaaccent V -50
-KPX Rcommaaccent W -40
-KPX Rcommaaccent Y -50
-KPX Rcommaaccent Yacute -50
-KPX Rcommaaccent Ydieresis -50
-KPX T A -90
-KPX T Aacute -90
-KPX T Abreve -90
-KPX T Acircumflex -90
-KPX T Adieresis -90
-KPX T Agrave -90
-KPX T Amacron -90
-KPX T Aogonek -90
-KPX T Aring -90
-KPX T Atilde -90
-KPX T O -40
-KPX T Oacute -40
-KPX T Ocircumflex -40
-KPX T Odieresis -40
-KPX T Ograve -40
-KPX T Ohungarumlaut -40
-KPX T Omacron -40
-KPX T Oslash -40
-KPX T Otilde -40
-KPX T a -80
-KPX T aacute -80
-KPX T abreve -80
-KPX T acircumflex -80
-KPX T adieresis -80
-KPX T agrave -80
-KPX T amacron -80
-KPX T aogonek -80
-KPX T aring -80
-KPX T atilde -80
-KPX T colon -40
-KPX T comma -80
-KPX T e -60
-KPX T eacute -60
-KPX T ecaron -60
-KPX T ecircumflex -60
-KPX T edieresis -60
-KPX T edotaccent -60
-KPX T egrave -60
-KPX T emacron -60
-KPX T eogonek -60
-KPX T hyphen -120
-KPX T o -80
-KPX T oacute -80
-KPX T ocircumflex -80
-KPX T odieresis -80
-KPX T ograve -80
-KPX T ohungarumlaut -80
-KPX T omacron -80
-KPX T oslash -80
-KPX T otilde -80
-KPX T period -80
-KPX T r -80
-KPX T racute -80
-KPX T rcommaaccent -80
-KPX T semicolon -40
-KPX T u -90
-KPX T uacute -90
-KPX T ucircumflex -90
-KPX T udieresis -90
-KPX T ugrave -90
-KPX T uhungarumlaut -90
-KPX T umacron -90
-KPX T uogonek -90
-KPX T uring -90
-KPX T w -60
-KPX T y -60
-KPX T yacute -60
-KPX T ydieresis -60
-KPX Tcaron A -90
-KPX Tcaron Aacute -90
-KPX Tcaron Abreve -90
-KPX Tcaron Acircumflex -90
-KPX Tcaron Adieresis -90
-KPX Tcaron Agrave -90
-KPX Tcaron Amacron -90
-KPX Tcaron Aogonek -90
-KPX Tcaron Aring -90
-KPX Tcaron Atilde -90
-KPX Tcaron O -40
-KPX Tcaron Oacute -40
-KPX Tcaron Ocircumflex -40
-KPX Tcaron Odieresis -40
-KPX Tcaron Ograve -40
-KPX Tcaron Ohungarumlaut -40
-KPX Tcaron Omacron -40
-KPX Tcaron Oslash -40
-KPX Tcaron Otilde -40
-KPX Tcaron a -80
-KPX Tcaron aacute -80
-KPX Tcaron abreve -80
-KPX Tcaron acircumflex -80
-KPX Tcaron adieresis -80
-KPX Tcaron agrave -80
-KPX Tcaron amacron -80
-KPX Tcaron aogonek -80
-KPX Tcaron aring -80
-KPX Tcaron atilde -80
-KPX Tcaron colon -40
-KPX Tcaron comma -80
-KPX Tcaron e -60
-KPX Tcaron eacute -60
-KPX Tcaron ecaron -60
-KPX Tcaron ecircumflex -60
-KPX Tcaron edieresis -60
-KPX Tcaron edotaccent -60
-KPX Tcaron egrave -60
-KPX Tcaron emacron -60
-KPX Tcaron eogonek -60
-KPX Tcaron hyphen -120
-KPX Tcaron o -80
-KPX Tcaron oacute -80
-KPX Tcaron ocircumflex -80
-KPX Tcaron odieresis -80
-KPX Tcaron ograve -80
-KPX Tcaron ohungarumlaut -80
-KPX Tcaron omacron -80
-KPX Tcaron oslash -80
-KPX Tcaron otilde -80
-KPX Tcaron period -80
-KPX Tcaron r -80
-KPX Tcaron racute -80
-KPX Tcaron rcommaaccent -80
-KPX Tcaron semicolon -40
-KPX Tcaron u -90
-KPX Tcaron uacute -90
-KPX Tcaron ucircumflex -90
-KPX Tcaron udieresis -90
-KPX Tcaron ugrave -90
-KPX Tcaron uhungarumlaut -90
-KPX Tcaron umacron -90
-KPX Tcaron uogonek -90
-KPX Tcaron uring -90
-KPX Tcaron w -60
-KPX Tcaron y -60
-KPX Tcaron yacute -60
-KPX Tcaron ydieresis -60
-KPX Tcommaaccent A -90
-KPX Tcommaaccent Aacute -90
-KPX Tcommaaccent Abreve -90
-KPX Tcommaaccent Acircumflex -90
-KPX Tcommaaccent Adieresis -90
-KPX Tcommaaccent Agrave -90
-KPX Tcommaaccent Amacron -90
-KPX Tcommaaccent Aogonek -90
-KPX Tcommaaccent Aring -90
-KPX Tcommaaccent Atilde -90
-KPX Tcommaaccent O -40
-KPX Tcommaaccent Oacute -40
-KPX Tcommaaccent Ocircumflex -40
-KPX Tcommaaccent Odieresis -40
-KPX Tcommaaccent Ograve -40
-KPX Tcommaaccent Ohungarumlaut -40
-KPX Tcommaaccent Omacron -40
-KPX Tcommaaccent Oslash -40
-KPX Tcommaaccent Otilde -40
-KPX Tcommaaccent a -80
-KPX Tcommaaccent aacute -80
-KPX Tcommaaccent abreve -80
-KPX Tcommaaccent acircumflex -80
-KPX Tcommaaccent adieresis -80
-KPX Tcommaaccent agrave -80
-KPX Tcommaaccent amacron -80
-KPX Tcommaaccent aogonek -80
-KPX Tcommaaccent aring -80
-KPX Tcommaaccent atilde -80
-KPX Tcommaaccent colon -40
-KPX Tcommaaccent comma -80
-KPX Tcommaaccent e -60
-KPX Tcommaaccent eacute -60
-KPX Tcommaaccent ecaron -60
-KPX Tcommaaccent ecircumflex -60
-KPX Tcommaaccent edieresis -60
-KPX Tcommaaccent edotaccent -60
-KPX Tcommaaccent egrave -60
-KPX Tcommaaccent emacron -60
-KPX Tcommaaccent eogonek -60
-KPX Tcommaaccent hyphen -120
-KPX Tcommaaccent o -80
-KPX Tcommaaccent oacute -80
-KPX Tcommaaccent ocircumflex -80
-KPX Tcommaaccent odieresis -80
-KPX Tcommaaccent ograve -80
-KPX Tcommaaccent ohungarumlaut -80
-KPX Tcommaaccent omacron -80
-KPX Tcommaaccent oslash -80
-KPX Tcommaaccent otilde -80
-KPX Tcommaaccent period -80
-KPX Tcommaaccent r -80
-KPX Tcommaaccent racute -80
-KPX Tcommaaccent rcommaaccent -80
-KPX Tcommaaccent semicolon -40
-KPX Tcommaaccent u -90
-KPX Tcommaaccent uacute -90
-KPX Tcommaaccent ucircumflex -90
-KPX Tcommaaccent udieresis -90
-KPX Tcommaaccent ugrave -90
-KPX Tcommaaccent uhungarumlaut -90
-KPX Tcommaaccent umacron -90
-KPX Tcommaaccent uogonek -90
-KPX Tcommaaccent uring -90
-KPX Tcommaaccent w -60
-KPX Tcommaaccent y -60
-KPX Tcommaaccent yacute -60
-KPX Tcommaaccent ydieresis -60
-KPX U A -50
-KPX U Aacute -50
-KPX U Abreve -50
-KPX U Acircumflex -50
-KPX U Adieresis -50
-KPX U Agrave -50
-KPX U Amacron -50
-KPX U Aogonek -50
-KPX U Aring -50
-KPX U Atilde -50
-KPX U comma -30
-KPX U period -30
-KPX Uacute A -50
-KPX Uacute Aacute -50
-KPX Uacute Abreve -50
-KPX Uacute Acircumflex -50
-KPX Uacute Adieresis -50
-KPX Uacute Agrave -50
-KPX Uacute Amacron -50
-KPX Uacute Aogonek -50
-KPX Uacute Aring -50
-KPX Uacute Atilde -50
-KPX Uacute comma -30
-KPX Uacute period -30
-KPX Ucircumflex A -50
-KPX Ucircumflex Aacute -50
-KPX Ucircumflex Abreve -50
-KPX Ucircumflex Acircumflex -50
-KPX Ucircumflex Adieresis -50
-KPX Ucircumflex Agrave -50
-KPX Ucircumflex Amacron -50
-KPX Ucircumflex Aogonek -50
-KPX Ucircumflex Aring -50
-KPX Ucircumflex Atilde -50
-KPX Ucircumflex comma -30
-KPX Ucircumflex period -30
-KPX Udieresis A -50
-KPX Udieresis Aacute -50
-KPX Udieresis Abreve -50
-KPX Udieresis Acircumflex -50
-KPX Udieresis Adieresis -50
-KPX Udieresis Agrave -50
-KPX Udieresis Amacron -50
-KPX Udieresis Aogonek -50
-KPX Udieresis Aring -50
-KPX Udieresis Atilde -50
-KPX Udieresis comma -30
-KPX Udieresis period -30
-KPX Ugrave A -50
-KPX Ugrave Aacute -50
-KPX Ugrave Abreve -50
-KPX Ugrave Acircumflex -50
-KPX Ugrave Adieresis -50
-KPX Ugrave Agrave -50
-KPX Ugrave Amacron -50
-KPX Ugrave Aogonek -50
-KPX Ugrave Aring -50
-KPX Ugrave Atilde -50
-KPX Ugrave comma -30
-KPX Ugrave period -30
-KPX Uhungarumlaut A -50
-KPX Uhungarumlaut Aacute -50
-KPX Uhungarumlaut Abreve -50
-KPX Uhungarumlaut Acircumflex -50
-KPX Uhungarumlaut Adieresis -50
-KPX Uhungarumlaut Agrave -50
-KPX Uhungarumlaut Amacron -50
-KPX Uhungarumlaut Aogonek -50
-KPX Uhungarumlaut Aring -50
-KPX Uhungarumlaut Atilde -50
-KPX Uhungarumlaut comma -30
-KPX Uhungarumlaut period -30
-KPX Umacron A -50
-KPX Umacron Aacute -50
-KPX Umacron Abreve -50
-KPX Umacron Acircumflex -50
-KPX Umacron Adieresis -50
-KPX Umacron Agrave -50
-KPX Umacron Amacron -50
-KPX Umacron Aogonek -50
-KPX Umacron Aring -50
-KPX Umacron Atilde -50
-KPX Umacron comma -30
-KPX Umacron period -30
-KPX Uogonek A -50
-KPX Uogonek Aacute -50
-KPX Uogonek Abreve -50
-KPX Uogonek Acircumflex -50
-KPX Uogonek Adieresis -50
-KPX Uogonek Agrave -50
-KPX Uogonek Amacron -50
-KPX Uogonek Aogonek -50
-KPX Uogonek Aring -50
-KPX Uogonek Atilde -50
-KPX Uogonek comma -30
-KPX Uogonek period -30
-KPX Uring A -50
-KPX Uring Aacute -50
-KPX Uring Abreve -50
-KPX Uring Acircumflex -50
-KPX Uring Adieresis -50
-KPX Uring Agrave -50
-KPX Uring Amacron -50
-KPX Uring Aogonek -50
-KPX Uring Aring -50
-KPX Uring Atilde -50
-KPX Uring comma -30
-KPX Uring period -30
-KPX V A -80
-KPX V Aacute -80
-KPX V Abreve -80
-KPX V Acircumflex -80
-KPX V Adieresis -80
-KPX V Agrave -80
-KPX V Amacron -80
-KPX V Aogonek -80
-KPX V Aring -80
-KPX V Atilde -80
-KPX V G -50
-KPX V Gbreve -50
-KPX V Gcommaaccent -50
-KPX V O -50
-KPX V Oacute -50
-KPX V Ocircumflex -50
-KPX V Odieresis -50
-KPX V Ograve -50
-KPX V Ohungarumlaut -50
-KPX V Omacron -50
-KPX V Oslash -50
-KPX V Otilde -50
-KPX V a -60
-KPX V aacute -60
-KPX V abreve -60
-KPX V acircumflex -60
-KPX V adieresis -60
-KPX V agrave -60
-KPX V amacron -60
-KPX V aogonek -60
-KPX V aring -60
-KPX V atilde -60
-KPX V colon -40
-KPX V comma -120
-KPX V e -50
-KPX V eacute -50
-KPX V ecaron -50
-KPX V ecircumflex -50
-KPX V edieresis -50
-KPX V edotaccent -50
-KPX V egrave -50
-KPX V emacron -50
-KPX V eogonek -50
-KPX V hyphen -80
-KPX V o -90
-KPX V oacute -90
-KPX V ocircumflex -90
-KPX V odieresis -90
-KPX V ograve -90
-KPX V ohungarumlaut -90
-KPX V omacron -90
-KPX V oslash -90
-KPX V otilde -90
-KPX V period -120
-KPX V semicolon -40
-KPX V u -60
-KPX V uacute -60
-KPX V ucircumflex -60
-KPX V udieresis -60
-KPX V ugrave -60
-KPX V uhungarumlaut -60
-KPX V umacron -60
-KPX V uogonek -60
-KPX V uring -60
-KPX W A -60
-KPX W Aacute -60
-KPX W Abreve -60
-KPX W Acircumflex -60
-KPX W Adieresis -60
-KPX W Agrave -60
-KPX W Amacron -60
-KPX W Aogonek -60
-KPX W Aring -60
-KPX W Atilde -60
-KPX W O -20
-KPX W Oacute -20
-KPX W Ocircumflex -20
-KPX W Odieresis -20
-KPX W Ograve -20
-KPX W Ohungarumlaut -20
-KPX W Omacron -20
-KPX W Oslash -20
-KPX W Otilde -20
-KPX W a -40
-KPX W aacute -40
-KPX W abreve -40
-KPX W acircumflex -40
-KPX W adieresis -40
-KPX W agrave -40
-KPX W amacron -40
-KPX W aogonek -40
-KPX W aring -40
-KPX W atilde -40
-KPX W colon -10
-KPX W comma -80
-KPX W e -35
-KPX W eacute -35
-KPX W ecaron -35
-KPX W ecircumflex -35
-KPX W edieresis -35
-KPX W edotaccent -35
-KPX W egrave -35
-KPX W emacron -35
-KPX W eogonek -35
-KPX W hyphen -40
-KPX W o -60
-KPX W oacute -60
-KPX W ocircumflex -60
-KPX W odieresis -60
-KPX W ograve -60
-KPX W ohungarumlaut -60
-KPX W omacron -60
-KPX W oslash -60
-KPX W otilde -60
-KPX W period -80
-KPX W semicolon -10
-KPX W u -45
-KPX W uacute -45
-KPX W ucircumflex -45
-KPX W udieresis -45
-KPX W ugrave -45
-KPX W uhungarumlaut -45
-KPX W umacron -45
-KPX W uogonek -45
-KPX W uring -45
-KPX W y -20
-KPX W yacute -20
-KPX W ydieresis -20
-KPX Y A -110
-KPX Y Aacute -110
-KPX Y Abreve -110
-KPX Y Acircumflex -110
-KPX Y Adieresis -110
-KPX Y Agrave -110
-KPX Y Amacron -110
-KPX Y Aogonek -110
-KPX Y Aring -110
-KPX Y Atilde -110
-KPX Y O -70
-KPX Y Oacute -70
-KPX Y Ocircumflex -70
-KPX Y Odieresis -70
-KPX Y Ograve -70
-KPX Y Ohungarumlaut -70
-KPX Y Omacron -70
-KPX Y Oslash -70
-KPX Y Otilde -70
-KPX Y a -90
-KPX Y aacute -90
-KPX Y abreve -90
-KPX Y acircumflex -90
-KPX Y adieresis -90
-KPX Y agrave -90
-KPX Y amacron -90
-KPX Y aogonek -90
-KPX Y aring -90
-KPX Y atilde -90
-KPX Y colon -50
-KPX Y comma -100
-KPX Y e -80
-KPX Y eacute -80
-KPX Y ecaron -80
-KPX Y ecircumflex -80
-KPX Y edieresis -80
-KPX Y edotaccent -80
-KPX Y egrave -80
-KPX Y emacron -80
-KPX Y eogonek -80
-KPX Y o -100
-KPX Y oacute -100
-KPX Y ocircumflex -100
-KPX Y odieresis -100
-KPX Y ograve -100
-KPX Y ohungarumlaut -100
-KPX Y omacron -100
-KPX Y oslash -100
-KPX Y otilde -100
-KPX Y period -100
-KPX Y semicolon -50
-KPX Y u -100
-KPX Y uacute -100
-KPX Y ucircumflex -100
-KPX Y udieresis -100
-KPX Y ugrave -100
-KPX Y uhungarumlaut -100
-KPX Y umacron -100
-KPX Y uogonek -100
-KPX Y uring -100
-KPX Yacute A -110
-KPX Yacute Aacute -110
-KPX Yacute Abreve -110
-KPX Yacute Acircumflex -110
-KPX Yacute Adieresis -110
-KPX Yacute Agrave -110
-KPX Yacute Amacron -110
-KPX Yacute Aogonek -110
-KPX Yacute Aring -110
-KPX Yacute Atilde -110
-KPX Yacute O -70
-KPX Yacute Oacute -70
-KPX Yacute Ocircumflex -70
-KPX Yacute Odieresis -70
-KPX Yacute Ograve -70
-KPX Yacute Ohungarumlaut -70
-KPX Yacute Omacron -70
-KPX Yacute Oslash -70
-KPX Yacute Otilde -70
-KPX Yacute a -90
-KPX Yacute aacute -90
-KPX Yacute abreve -90
-KPX Yacute acircumflex -90
-KPX Yacute adieresis -90
-KPX Yacute agrave -90
-KPX Yacute amacron -90
-KPX Yacute aogonek -90
-KPX Yacute aring -90
-KPX Yacute atilde -90
-KPX Yacute colon -50
-KPX Yacute comma -100
-KPX Yacute e -80
-KPX Yacute eacute -80
-KPX Yacute ecaron -80
-KPX Yacute ecircumflex -80
-KPX Yacute edieresis -80
-KPX Yacute edotaccent -80
-KPX Yacute egrave -80
-KPX Yacute emacron -80
-KPX Yacute eogonek -80
-KPX Yacute o -100
-KPX Yacute oacute -100
-KPX Yacute ocircumflex -100
-KPX Yacute odieresis -100
-KPX Yacute ograve -100
-KPX Yacute ohungarumlaut -100
-KPX Yacute omacron -100
-KPX Yacute oslash -100
-KPX Yacute otilde -100
-KPX Yacute period -100
-KPX Yacute semicolon -50
-KPX Yacute u -100
-KPX Yacute uacute -100
-KPX Yacute ucircumflex -100
-KPX Yacute udieresis -100
-KPX Yacute ugrave -100
-KPX Yacute uhungarumlaut -100
-KPX Yacute umacron -100
-KPX Yacute uogonek -100
-KPX Yacute uring -100
-KPX Ydieresis A -110
-KPX Ydieresis Aacute -110
-KPX Ydieresis Abreve -110
-KPX Ydieresis Acircumflex -110
-KPX Ydieresis Adieresis -110
-KPX Ydieresis Agrave -110
-KPX Ydieresis Amacron -110
-KPX Ydieresis Aogonek -110
-KPX Ydieresis Aring -110
-KPX Ydieresis Atilde -110
-KPX Ydieresis O -70
-KPX Ydieresis Oacute -70
-KPX Ydieresis Ocircumflex -70
-KPX Ydieresis Odieresis -70
-KPX Ydieresis Ograve -70
-KPX Ydieresis Ohungarumlaut -70
-KPX Ydieresis Omacron -70
-KPX Ydieresis Oslash -70
-KPX Ydieresis Otilde -70
-KPX Ydieresis a -90
-KPX Ydieresis aacute -90
-KPX Ydieresis abreve -90
-KPX Ydieresis acircumflex -90
-KPX Ydieresis adieresis -90
-KPX Ydieresis agrave -90
-KPX Ydieresis amacron -90
-KPX Ydieresis aogonek -90
-KPX Ydieresis aring -90
-KPX Ydieresis atilde -90
-KPX Ydieresis colon -50
-KPX Ydieresis comma -100
-KPX Ydieresis e -80
-KPX Ydieresis eacute -80
-KPX Ydieresis ecaron -80
-KPX Ydieresis ecircumflex -80
-KPX Ydieresis edieresis -80
-KPX Ydieresis edotaccent -80
-KPX Ydieresis egrave -80
-KPX Ydieresis emacron -80
-KPX Ydieresis eogonek -80
-KPX Ydieresis o -100
-KPX Ydieresis oacute -100
-KPX Ydieresis ocircumflex -100
-KPX Ydieresis odieresis -100
-KPX Ydieresis ograve -100
-KPX Ydieresis ohungarumlaut -100
-KPX Ydieresis omacron -100
-KPX Ydieresis oslash -100
-KPX Ydieresis otilde -100
-KPX Ydieresis period -100
-KPX Ydieresis semicolon -50
-KPX Ydieresis u -100
-KPX Ydieresis uacute -100
-KPX Ydieresis ucircumflex -100
-KPX Ydieresis udieresis -100
-KPX Ydieresis ugrave -100
-KPX Ydieresis uhungarumlaut -100
-KPX Ydieresis umacron -100
-KPX Ydieresis uogonek -100
-KPX Ydieresis uring -100
-KPX a g -10
-KPX a gbreve -10
-KPX a gcommaaccent -10
-KPX a v -15
-KPX a w -15
-KPX a y -20
-KPX a yacute -20
-KPX a ydieresis -20
-KPX aacute g -10
-KPX aacute gbreve -10
-KPX aacute gcommaaccent -10
-KPX aacute v -15
-KPX aacute w -15
-KPX aacute y -20
-KPX aacute yacute -20
-KPX aacute ydieresis -20
-KPX abreve g -10
-KPX abreve gbreve -10
-KPX abreve gcommaaccent -10
-KPX abreve v -15
-KPX abreve w -15
-KPX abreve y -20
-KPX abreve yacute -20
-KPX abreve ydieresis -20
-KPX acircumflex g -10
-KPX acircumflex gbreve -10
-KPX acircumflex gcommaaccent -10
-KPX acircumflex v -15
-KPX acircumflex w -15
-KPX acircumflex y -20
-KPX acircumflex yacute -20
-KPX acircumflex ydieresis -20
-KPX adieresis g -10
-KPX adieresis gbreve -10
-KPX adieresis gcommaaccent -10
-KPX adieresis v -15
-KPX adieresis w -15
-KPX adieresis y -20
-KPX adieresis yacute -20
-KPX adieresis ydieresis -20
-KPX agrave g -10
-KPX agrave gbreve -10
-KPX agrave gcommaaccent -10
-KPX agrave v -15
-KPX agrave w -15
-KPX agrave y -20
-KPX agrave yacute -20
-KPX agrave ydieresis -20
-KPX amacron g -10
-KPX amacron gbreve -10
-KPX amacron gcommaaccent -10
-KPX amacron v -15
-KPX amacron w -15
-KPX amacron y -20
-KPX amacron yacute -20
-KPX amacron ydieresis -20
-KPX aogonek g -10
-KPX aogonek gbreve -10
-KPX aogonek gcommaaccent -10
-KPX aogonek v -15
-KPX aogonek w -15
-KPX aogonek y -20
-KPX aogonek yacute -20
-KPX aogonek ydieresis -20
-KPX aring g -10
-KPX aring gbreve -10
-KPX aring gcommaaccent -10
-KPX aring v -15
-KPX aring w -15
-KPX aring y -20
-KPX aring yacute -20
-KPX aring ydieresis -20
-KPX atilde g -10
-KPX atilde gbreve -10
-KPX atilde gcommaaccent -10
-KPX atilde v -15
-KPX atilde w -15
-KPX atilde y -20
-KPX atilde yacute -20
-KPX atilde ydieresis -20
-KPX b l -10
-KPX b lacute -10
-KPX b lcommaaccent -10
-KPX b lslash -10
-KPX b u -20
-KPX b uacute -20
-KPX b ucircumflex -20
-KPX b udieresis -20
-KPX b ugrave -20
-KPX b uhungarumlaut -20
-KPX b umacron -20
-KPX b uogonek -20
-KPX b uring -20
-KPX b v -20
-KPX b y -20
-KPX b yacute -20
-KPX b ydieresis -20
-KPX c h -10
-KPX c k -20
-KPX c kcommaaccent -20
-KPX c l -20
-KPX c lacute -20
-KPX c lcommaaccent -20
-KPX c lslash -20
-KPX c y -10
-KPX c yacute -10
-KPX c ydieresis -10
-KPX cacute h -10
-KPX cacute k -20
-KPX cacute kcommaaccent -20
-KPX cacute l -20
-KPX cacute lacute -20
-KPX cacute lcommaaccent -20
-KPX cacute lslash -20
-KPX cacute y -10
-KPX cacute yacute -10
-KPX cacute ydieresis -10
-KPX ccaron h -10
-KPX ccaron k -20
-KPX ccaron kcommaaccent -20
-KPX ccaron l -20
-KPX ccaron lacute -20
-KPX ccaron lcommaaccent -20
-KPX ccaron lslash -20
-KPX ccaron y -10
-KPX ccaron yacute -10
-KPX ccaron ydieresis -10
-KPX ccedilla h -10
-KPX ccedilla k -20
-KPX ccedilla kcommaaccent -20
-KPX ccedilla l -20
-KPX ccedilla lacute -20
-KPX ccedilla lcommaaccent -20
-KPX ccedilla lslash -20
-KPX ccedilla y -10
-KPX ccedilla yacute -10
-KPX ccedilla ydieresis -10
-KPX colon space -40
-KPX comma quotedblright -120
-KPX comma quoteright -120
-KPX comma space -40
-KPX d d -10
-KPX d dcroat -10
-KPX d v -15
-KPX d w -15
-KPX d y -15
-KPX d yacute -15
-KPX d ydieresis -15
-KPX dcroat d -10
-KPX dcroat dcroat -10
-KPX dcroat v -15
-KPX dcroat w -15
-KPX dcroat y -15
-KPX dcroat yacute -15
-KPX dcroat ydieresis -15
-KPX e comma 10
-KPX e period 20
-KPX e v -15
-KPX e w -15
-KPX e x -15
-KPX e y -15
-KPX e yacute -15
-KPX e ydieresis -15
-KPX eacute comma 10
-KPX eacute period 20
-KPX eacute v -15
-KPX eacute w -15
-KPX eacute x -15
-KPX eacute y -15
-KPX eacute yacute -15
-KPX eacute ydieresis -15
-KPX ecaron comma 10
-KPX ecaron period 20
-KPX ecaron v -15
-KPX ecaron w -15
-KPX ecaron x -15
-KPX ecaron y -15
-KPX ecaron yacute -15
-KPX ecaron ydieresis -15
-KPX ecircumflex comma 10
-KPX ecircumflex period 20
-KPX ecircumflex v -15
-KPX ecircumflex w -15
-KPX ecircumflex x -15
-KPX ecircumflex y -15
-KPX ecircumflex yacute -15
-KPX ecircumflex ydieresis -15
-KPX edieresis comma 10
-KPX edieresis period 20
-KPX edieresis v -15
-KPX edieresis w -15
-KPX edieresis x -15
-KPX edieresis y -15
-KPX edieresis yacute -15
-KPX edieresis ydieresis -15
-KPX edotaccent comma 10
-KPX edotaccent period 20
-KPX edotaccent v -15
-KPX edotaccent w -15
-KPX edotaccent x -15
-KPX edotaccent y -15
-KPX edotaccent yacute -15
-KPX edotaccent ydieresis -15
-KPX egrave comma 10
-KPX egrave period 20
-KPX egrave v -15
-KPX egrave w -15
-KPX egrave x -15
-KPX egrave y -15
-KPX egrave yacute -15
-KPX egrave ydieresis -15
-KPX emacron comma 10
-KPX emacron period 20
-KPX emacron v -15
-KPX emacron w -15
-KPX emacron x -15
-KPX emacron y -15
-KPX emacron yacute -15
-KPX emacron ydieresis -15
-KPX eogonek comma 10
-KPX eogonek period 20
-KPX eogonek v -15
-KPX eogonek w -15
-KPX eogonek x -15
-KPX eogonek y -15
-KPX eogonek yacute -15
-KPX eogonek ydieresis -15
-KPX f comma -10
-KPX f e -10
-KPX f eacute -10
-KPX f ecaron -10
-KPX f ecircumflex -10
-KPX f edieresis -10
-KPX f edotaccent -10
-KPX f egrave -10
-KPX f emacron -10
-KPX f eogonek -10
-KPX f o -20
-KPX f oacute -20
-KPX f ocircumflex -20
-KPX f odieresis -20
-KPX f ograve -20
-KPX f ohungarumlaut -20
-KPX f omacron -20
-KPX f oslash -20
-KPX f otilde -20
-KPX f period -10
-KPX f quotedblright 30
-KPX f quoteright 30
-KPX g e 10
-KPX g eacute 10
-KPX g ecaron 10
-KPX g ecircumflex 10
-KPX g edieresis 10
-KPX g edotaccent 10
-KPX g egrave 10
-KPX g emacron 10
-KPX g eogonek 10
-KPX g g -10
-KPX g gbreve -10
-KPX g gcommaaccent -10
-KPX gbreve e 10
-KPX gbreve eacute 10
-KPX gbreve ecaron 10
-KPX gbreve ecircumflex 10
-KPX gbreve edieresis 10
-KPX gbreve edotaccent 10
-KPX gbreve egrave 10
-KPX gbreve emacron 10
-KPX gbreve eogonek 10
-KPX gbreve g -10
-KPX gbreve gbreve -10
-KPX gbreve gcommaaccent -10
-KPX gcommaaccent e 10
-KPX gcommaaccent eacute 10
-KPX gcommaaccent ecaron 10
-KPX gcommaaccent ecircumflex 10
-KPX gcommaaccent edieresis 10
-KPX gcommaaccent edotaccent 10
-KPX gcommaaccent egrave 10
-KPX gcommaaccent emacron 10
-KPX gcommaaccent eogonek 10
-KPX gcommaaccent g -10
-KPX gcommaaccent gbreve -10
-KPX gcommaaccent gcommaaccent -10
-KPX h y -20
-KPX h yacute -20
-KPX h ydieresis -20
-KPX k o -15
-KPX k oacute -15
-KPX k ocircumflex -15
-KPX k odieresis -15
-KPX k ograve -15
-KPX k ohungarumlaut -15
-KPX k omacron -15
-KPX k oslash -15
-KPX k otilde -15
-KPX kcommaaccent o -15
-KPX kcommaaccent oacute -15
-KPX kcommaaccent ocircumflex -15
-KPX kcommaaccent odieresis -15
-KPX kcommaaccent ograve -15
-KPX kcommaaccent ohungarumlaut -15
-KPX kcommaaccent omacron -15
-KPX kcommaaccent oslash -15
-KPX kcommaaccent otilde -15
-KPX l w -15
-KPX l y -15
-KPX l yacute -15
-KPX l ydieresis -15
-KPX lacute w -15
-KPX lacute y -15
-KPX lacute yacute -15
-KPX lacute ydieresis -15
-KPX lcommaaccent w -15
-KPX lcommaaccent y -15
-KPX lcommaaccent yacute -15
-KPX lcommaaccent ydieresis -15
-KPX lslash w -15
-KPX lslash y -15
-KPX lslash yacute -15
-KPX lslash ydieresis -15
-KPX m u -20
-KPX m uacute -20
-KPX m ucircumflex -20
-KPX m udieresis -20
-KPX m ugrave -20
-KPX m uhungarumlaut -20
-KPX m umacron -20
-KPX m uogonek -20
-KPX m uring -20
-KPX m y -30
-KPX m yacute -30
-KPX m ydieresis -30
-KPX n u -10
-KPX n uacute -10
-KPX n ucircumflex -10
-KPX n udieresis -10
-KPX n ugrave -10
-KPX n uhungarumlaut -10
-KPX n umacron -10
-KPX n uogonek -10
-KPX n uring -10
-KPX n v -40
-KPX n y -20
-KPX n yacute -20
-KPX n ydieresis -20
-KPX nacute u -10
-KPX nacute uacute -10
-KPX nacute ucircumflex -10
-KPX nacute udieresis -10
-KPX nacute ugrave -10
-KPX nacute uhungarumlaut -10
-KPX nacute umacron -10
-KPX nacute uogonek -10
-KPX nacute uring -10
-KPX nacute v -40
-KPX nacute y -20
-KPX nacute yacute -20
-KPX nacute ydieresis -20
-KPX ncaron u -10
-KPX ncaron uacute -10
-KPX ncaron ucircumflex -10
-KPX ncaron udieresis -10
-KPX ncaron ugrave -10
-KPX ncaron uhungarumlaut -10
-KPX ncaron umacron -10
-KPX ncaron uogonek -10
-KPX ncaron uring -10
-KPX ncaron v -40
-KPX ncaron y -20
-KPX ncaron yacute -20
-KPX ncaron ydieresis -20
-KPX ncommaaccent u -10
-KPX ncommaaccent uacute -10
-KPX ncommaaccent ucircumflex -10
-KPX ncommaaccent udieresis -10
-KPX ncommaaccent ugrave -10
-KPX ncommaaccent uhungarumlaut -10
-KPX ncommaaccent umacron -10
-KPX ncommaaccent uogonek -10
-KPX ncommaaccent uring -10
-KPX ncommaaccent v -40
-KPX ncommaaccent y -20
-KPX ncommaaccent yacute -20
-KPX ncommaaccent ydieresis -20
-KPX ntilde u -10
-KPX ntilde uacute -10
-KPX ntilde ucircumflex -10
-KPX ntilde udieresis -10
-KPX ntilde ugrave -10
-KPX ntilde uhungarumlaut -10
-KPX ntilde umacron -10
-KPX ntilde uogonek -10
-KPX ntilde uring -10
-KPX ntilde v -40
-KPX ntilde y -20
-KPX ntilde yacute -20
-KPX ntilde ydieresis -20
-KPX o v -20
-KPX o w -15
-KPX o x -30
-KPX o y -20
-KPX o yacute -20
-KPX o ydieresis -20
-KPX oacute v -20
-KPX oacute w -15
-KPX oacute x -30
-KPX oacute y -20
-KPX oacute yacute -20
-KPX oacute ydieresis -20
-KPX ocircumflex v -20
-KPX ocircumflex w -15
-KPX ocircumflex x -30
-KPX ocircumflex y -20
-KPX ocircumflex yacute -20
-KPX ocircumflex ydieresis -20
-KPX odieresis v -20
-KPX odieresis w -15
-KPX odieresis x -30
-KPX odieresis y -20
-KPX odieresis yacute -20
-KPX odieresis ydieresis -20
-KPX ograve v -20
-KPX ograve w -15
-KPX ograve x -30
-KPX ograve y -20
-KPX ograve yacute -20
-KPX ograve ydieresis -20
-KPX ohungarumlaut v -20
-KPX ohungarumlaut w -15
-KPX ohungarumlaut x -30
-KPX ohungarumlaut y -20
-KPX ohungarumlaut yacute -20
-KPX ohungarumlaut ydieresis -20
-KPX omacron v -20
-KPX omacron w -15
-KPX omacron x -30
-KPX omacron y -20
-KPX omacron yacute -20
-KPX omacron ydieresis -20
-KPX oslash v -20
-KPX oslash w -15
-KPX oslash x -30
-KPX oslash y -20
-KPX oslash yacute -20
-KPX oslash ydieresis -20
-KPX otilde v -20
-KPX otilde w -15
-KPX otilde x -30
-KPX otilde y -20
-KPX otilde yacute -20
-KPX otilde ydieresis -20
-KPX p y -15
-KPX p yacute -15
-KPX p ydieresis -15
-KPX period quotedblright -120
-KPX period quoteright -120
-KPX period space -40
-KPX quotedblright space -80
-KPX quoteleft quoteleft -46
-KPX quoteright d -80
-KPX quoteright dcroat -80
-KPX quoteright l -20
-KPX quoteright lacute -20
-KPX quoteright lcommaaccent -20
-KPX quoteright lslash -20
-KPX quoteright quoteright -46
-KPX quoteright r -40
-KPX quoteright racute -40
-KPX quoteright rcaron -40
-KPX quoteright rcommaaccent -40
-KPX quoteright s -60
-KPX quoteright sacute -60
-KPX quoteright scaron -60
-KPX quoteright scedilla -60
-KPX quoteright scommaaccent -60
-KPX quoteright space -80
-KPX quoteright v -20
-KPX r c -20
-KPX r cacute -20
-KPX r ccaron -20
-KPX r ccedilla -20
-KPX r comma -60
-KPX r d -20
-KPX r dcroat -20
-KPX r g -15
-KPX r gbreve -15
-KPX r gcommaaccent -15
-KPX r hyphen -20
-KPX r o -20
-KPX r oacute -20
-KPX r ocircumflex -20
-KPX r odieresis -20
-KPX r ograve -20
-KPX r ohungarumlaut -20
-KPX r omacron -20
-KPX r oslash -20
-KPX r otilde -20
-KPX r period -60
-KPX r q -20
-KPX r s -15
-KPX r sacute -15
-KPX r scaron -15
-KPX r scedilla -15
-KPX r scommaaccent -15
-KPX r t 20
-KPX r tcommaaccent 20
-KPX r v 10
-KPX r y 10
-KPX r yacute 10
-KPX r ydieresis 10
-KPX racute c -20
-KPX racute cacute -20
-KPX racute ccaron -20
-KPX racute ccedilla -20
-KPX racute comma -60
-KPX racute d -20
-KPX racute dcroat -20
-KPX racute g -15
-KPX racute gbreve -15
-KPX racute gcommaaccent -15
-KPX racute hyphen -20
-KPX racute o -20
-KPX racute oacute -20
-KPX racute ocircumflex -20
-KPX racute odieresis -20
-KPX racute ograve -20
-KPX racute ohungarumlaut -20
-KPX racute omacron -20
-KPX racute oslash -20
-KPX racute otilde -20
-KPX racute period -60
-KPX racute q -20
-KPX racute s -15
-KPX racute sacute -15
-KPX racute scaron -15
-KPX racute scedilla -15
-KPX racute scommaaccent -15
-KPX racute t 20
-KPX racute tcommaaccent 20
-KPX racute v 10
-KPX racute y 10
-KPX racute yacute 10
-KPX racute ydieresis 10
-KPX rcaron c -20
-KPX rcaron cacute -20
-KPX rcaron ccaron -20
-KPX rcaron ccedilla -20
-KPX rcaron comma -60
-KPX rcaron d -20
-KPX rcaron dcroat -20
-KPX rcaron g -15
-KPX rcaron gbreve -15
-KPX rcaron gcommaaccent -15
-KPX rcaron hyphen -20
-KPX rcaron o -20
-KPX rcaron oacute -20
-KPX rcaron ocircumflex -20
-KPX rcaron odieresis -20
-KPX rcaron ograve -20
-KPX rcaron ohungarumlaut -20
-KPX rcaron omacron -20
-KPX rcaron oslash -20
-KPX rcaron otilde -20
-KPX rcaron period -60
-KPX rcaron q -20
-KPX rcaron s -15
-KPX rcaron sacute -15
-KPX rcaron scaron -15
-KPX rcaron scedilla -15
-KPX rcaron scommaaccent -15
-KPX rcaron t 20
-KPX rcaron tcommaaccent 20
-KPX rcaron v 10
-KPX rcaron y 10
-KPX rcaron yacute 10
-KPX rcaron ydieresis 10
-KPX rcommaaccent c -20
-KPX rcommaaccent cacute -20
-KPX rcommaaccent ccaron -20
-KPX rcommaaccent ccedilla -20
-KPX rcommaaccent comma -60
-KPX rcommaaccent d -20
-KPX rcommaaccent dcroat -20
-KPX rcommaaccent g -15
-KPX rcommaaccent gbreve -15
-KPX rcommaaccent gcommaaccent -15
-KPX rcommaaccent hyphen -20
-KPX rcommaaccent o -20
-KPX rcommaaccent oacute -20
-KPX rcommaaccent ocircumflex -20
-KPX rcommaaccent odieresis -20
-KPX rcommaaccent ograve -20
-KPX rcommaaccent ohungarumlaut -20
-KPX rcommaaccent omacron -20
-KPX rcommaaccent oslash -20
-KPX rcommaaccent otilde -20
-KPX rcommaaccent period -60
-KPX rcommaaccent q -20
-KPX rcommaaccent s -15
-KPX rcommaaccent sacute -15
-KPX rcommaaccent scaron -15
-KPX rcommaaccent scedilla -15
-KPX rcommaaccent scommaaccent -15
-KPX rcommaaccent t 20
-KPX rcommaaccent tcommaaccent 20
-KPX rcommaaccent v 10
-KPX rcommaaccent y 10
-KPX rcommaaccent yacute 10
-KPX rcommaaccent ydieresis 10
-KPX s w -15
-KPX sacute w -15
-KPX scaron w -15
-KPX scedilla w -15
-KPX scommaaccent w -15
-KPX semicolon space -40
-KPX space T -100
-KPX space Tcaron -100
-KPX space Tcommaaccent -100
-KPX space V -80
-KPX space W -80
-KPX space Y -120
-KPX space Yacute -120
-KPX space Ydieresis -120
-KPX space quotedblleft -80
-KPX space quoteleft -60
-KPX v a -20
-KPX v aacute -20
-KPX v abreve -20
-KPX v acircumflex -20
-KPX v adieresis -20
-KPX v agrave -20
-KPX v amacron -20
-KPX v aogonek -20
-KPX v aring -20
-KPX v atilde -20
-KPX v comma -80
-KPX v o -30
-KPX v oacute -30
-KPX v ocircumflex -30
-KPX v odieresis -30
-KPX v ograve -30
-KPX v ohungarumlaut -30
-KPX v omacron -30
-KPX v oslash -30
-KPX v otilde -30
-KPX v period -80
-KPX w comma -40
-KPX w o -20
-KPX w oacute -20
-KPX w ocircumflex -20
-KPX w odieresis -20
-KPX w ograve -20
-KPX w ohungarumlaut -20
-KPX w omacron -20
-KPX w oslash -20
-KPX w otilde -20
-KPX w period -40
-KPX x e -10
-KPX x eacute -10
-KPX x ecaron -10
-KPX x ecircumflex -10
-KPX x edieresis -10
-KPX x edotaccent -10
-KPX x egrave -10
-KPX x emacron -10
-KPX x eogonek -10
-KPX y a -30
-KPX y aacute -30
-KPX y abreve -30
-KPX y acircumflex -30
-KPX y adieresis -30
-KPX y agrave -30
-KPX y amacron -30
-KPX y aogonek -30
-KPX y aring -30
-KPX y atilde -30
-KPX y comma -80
-KPX y e -10
-KPX y eacute -10
-KPX y ecaron -10
-KPX y ecircumflex -10
-KPX y edieresis -10
-KPX y edotaccent -10
-KPX y egrave -10
-KPX y emacron -10
-KPX y eogonek -10
-KPX y o -25
-KPX y oacute -25
-KPX y ocircumflex -25
-KPX y odieresis -25
-KPX y ograve -25
-KPX y ohungarumlaut -25
-KPX y omacron -25
-KPX y oslash -25
-KPX y otilde -25
-KPX y period -80
-KPX yacute a -30
-KPX yacute aacute -30
-KPX yacute abreve -30
-KPX yacute acircumflex -30
-KPX yacute adieresis -30
-KPX yacute agrave -30
-KPX yacute amacron -30
-KPX yacute aogonek -30
-KPX yacute aring -30
-KPX yacute atilde -30
-KPX yacute comma -80
-KPX yacute e -10
-KPX yacute eacute -10
-KPX yacute ecaron -10
-KPX yacute ecircumflex -10
-KPX yacute edieresis -10
-KPX yacute edotaccent -10
-KPX yacute egrave -10
-KPX yacute emacron -10
-KPX yacute eogonek -10
-KPX yacute o -25
-KPX yacute oacute -25
-KPX yacute ocircumflex -25
-KPX yacute odieresis -25
-KPX yacute ograve -25
-KPX yacute ohungarumlaut -25
-KPX yacute omacron -25
-KPX yacute oslash -25
-KPX yacute otilde -25
-KPX yacute period -80
-KPX ydieresis a -30
-KPX ydieresis aacute -30
-KPX ydieresis abreve -30
-KPX ydieresis acircumflex -30
-KPX ydieresis adieresis -30
-KPX ydieresis agrave -30
-KPX ydieresis amacron -30
-KPX ydieresis aogonek -30
-KPX ydieresis aring -30
-KPX ydieresis atilde -30
-KPX ydieresis comma -80
-KPX ydieresis e -10
-KPX ydieresis eacute -10
-KPX ydieresis ecaron -10
-KPX ydieresis ecircumflex -10
-KPX ydieresis edieresis -10
-KPX ydieresis edotaccent -10
-KPX ydieresis egrave -10
-KPX ydieresis emacron -10
-KPX ydieresis eogonek -10
-KPX ydieresis o -25
-KPX ydieresis oacute -25
-KPX ydieresis ocircumflex -25
-KPX ydieresis odieresis -25
-KPX ydieresis ograve -25
-KPX ydieresis ohungarumlaut -25
-KPX ydieresis omacron -25
-KPX ydieresis oslash -25
-KPX ydieresis otilde -25
-KPX ydieresis period -80
-KPX z e 10
-KPX z eacute 10
-KPX z ecaron 10
-KPX z ecircumflex 10
-KPX z edieresis 10
-KPX z edotaccent 10
-KPX z egrave 10
-KPX z emacron 10
-KPX z eogonek 10
-KPX zacute e 10
-KPX zacute eacute 10
-KPX zacute ecaron 10
-KPX zacute ecircumflex 10
-KPX zacute edieresis 10
-KPX zacute edotaccent 10
-KPX zacute egrave 10
-KPX zacute emacron 10
-KPX zacute eogonek 10
-KPX zcaron e 10
-KPX zcaron eacute 10
-KPX zcaron ecaron 10
-KPX zcaron ecircumflex 10
-KPX zcaron edieresis 10
-KPX zcaron edotaccent 10
-KPX zcaron egrave 10
-KPX zcaron emacron 10
-KPX zcaron eogonek 10
-KPX zdotaccent e 10
-KPX zdotaccent eacute 10
-KPX zdotaccent ecaron 10
-KPX zdotaccent ecircumflex 10
-KPX zdotaccent edieresis 10
-KPX zdotaccent edotaccent 10
-KPX zdotaccent egrave 10
-KPX zdotaccent emacron 10
-KPX zdotaccent eogonek 10
-EndKernPairs
-EndKernData
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Oblique.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Oblique.afm
deleted file mode 100644
index 7a7af0017f..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Oblique.afm
+++ /dev/null
@@ -1,3051 +0,0 @@
-StartFontMetrics 4.1
-Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Thu May 1 12:44:31 1997
-Comment UniqueID 43055
-Comment VMusage 14960 69346
-FontName Helvetica-Oblique
-FullName Helvetica Oblique
-FamilyName Helvetica
-Weight Medium
-ItalicAngle -12
-IsFixedPitch false
-CharacterSet ExtendedRoman
-FontBBox -170 -225 1116 931
-UnderlinePosition -100
-UnderlineThickness 50
-Version 002.000
-Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 718
-XHeight 523
-Ascender 718
-Descender -207
-StdHW 76
-StdVW 88
-StartCharMetrics 315
-C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 278 ; N exclam ; B 90 0 340 718 ;
-C 34 ; WX 355 ; N quotedbl ; B 168 463 438 718 ;
-C 35 ; WX 556 ; N numbersign ; B 73 0 631 688 ;
-C 36 ; WX 556 ; N dollar ; B 69 -115 617 775 ;
-C 37 ; WX 889 ; N percent ; B 147 -19 889 703 ;
-C 38 ; WX 667 ; N ampersand ; B 77 -15 647 718 ;
-C 39 ; WX 222 ; N quoteright ; B 151 463 310 718 ;
-C 40 ; WX 333 ; N parenleft ; B 108 -207 454 733 ;
-C 41 ; WX 333 ; N parenright ; B -9 -207 337 733 ;
-C 42 ; WX 389 ; N asterisk ; B 165 431 475 718 ;
-C 43 ; WX 584 ; N plus ; B 85 0 606 505 ;
-C 44 ; WX 278 ; N comma ; B 56 -147 214 106 ;
-C 45 ; WX 333 ; N hyphen ; B 93 232 357 322 ;
-C 46 ; WX 278 ; N period ; B 87 0 214 106 ;
-C 47 ; WX 278 ; N slash ; B -21 -19 452 737 ;
-C 48 ; WX 556 ; N zero ; B 93 -19 608 703 ;
-C 49 ; WX 556 ; N one ; B 207 0 508 703 ;
-C 50 ; WX 556 ; N two ; B 26 0 617 703 ;
-C 51 ; WX 556 ; N three ; B 75 -19 610 703 ;
-C 52 ; WX 556 ; N four ; B 61 0 576 703 ;
-C 53 ; WX 556 ; N five ; B 68 -19 621 688 ;
-C 54 ; WX 556 ; N six ; B 91 -19 615 703 ;
-C 55 ; WX 556 ; N seven ; B 137 0 669 688 ;
-C 56 ; WX 556 ; N eight ; B 74 -19 607 703 ;
-C 57 ; WX 556 ; N nine ; B 82 -19 609 703 ;
-C 58 ; WX 278 ; N colon ; B 87 0 301 516 ;
-C 59 ; WX 278 ; N semicolon ; B 56 -147 301 516 ;
-C 60 ; WX 584 ; N less ; B 94 11 641 495 ;
-C 61 ; WX 584 ; N equal ; B 63 115 628 390 ;
-C 62 ; WX 584 ; N greater ; B 50 11 597 495 ;
-C 63 ; WX 556 ; N question ; B 161 0 610 727 ;
-C 64 ; WX 1015 ; N at ; B 215 -19 965 737 ;
-C 65 ; WX 667 ; N A ; B 14 0 654 718 ;
-C 66 ; WX 667 ; N B ; B 74 0 712 718 ;
-C 67 ; WX 722 ; N C ; B 108 -19 782 737 ;
-C 68 ; WX 722 ; N D ; B 81 0 764 718 ;
-C 69 ; WX 667 ; N E ; B 86 0 762 718 ;
-C 70 ; WX 611 ; N F ; B 86 0 736 718 ;
-C 71 ; WX 778 ; N G ; B 111 -19 799 737 ;
-C 72 ; WX 722 ; N H ; B 77 0 799 718 ;
-C 73 ; WX 278 ; N I ; B 91 0 341 718 ;
-C 74 ; WX 500 ; N J ; B 47 -19 581 718 ;
-C 75 ; WX 667 ; N K ; B 76 0 808 718 ;
-C 76 ; WX 556 ; N L ; B 76 0 555 718 ;
-C 77 ; WX 833 ; N M ; B 73 0 914 718 ;
-C 78 ; WX 722 ; N N ; B 76 0 799 718 ;
-C 79 ; WX 778 ; N O ; B 105 -19 826 737 ;
-C 80 ; WX 667 ; N P ; B 86 0 737 718 ;
-C 81 ; WX 778 ; N Q ; B 105 -56 826 737 ;
-C 82 ; WX 722 ; N R ; B 88 0 773 718 ;
-C 83 ; WX 667 ; N S ; B 90 -19 713 737 ;
-C 84 ; WX 611 ; N T ; B 148 0 750 718 ;
-C 85 ; WX 722 ; N U ; B 123 -19 797 718 ;
-C 86 ; WX 667 ; N V ; B 173 0 800 718 ;
-C 87 ; WX 944 ; N W ; B 169 0 1081 718 ;
-C 88 ; WX 667 ; N X ; B 19 0 790 718 ;
-C 89 ; WX 667 ; N Y ; B 167 0 806 718 ;
-C 90 ; WX 611 ; N Z ; B 23 0 741 718 ;
-C 91 ; WX 278 ; N bracketleft ; B 21 -196 403 722 ;
-C 92 ; WX 278 ; N backslash ; B 140 -19 291 737 ;
-C 93 ; WX 278 ; N bracketright ; B -14 -196 368 722 ;
-C 94 ; WX 469 ; N asciicircum ; B 42 264 539 688 ;
-C 95 ; WX 556 ; N underscore ; B -27 -125 540 -75 ;
-C 96 ; WX 222 ; N quoteleft ; B 165 470 323 725 ;
-C 97 ; WX 556 ; N a ; B 61 -15 559 538 ;
-C 98 ; WX 556 ; N b ; B 58 -15 584 718 ;
-C 99 ; WX 500 ; N c ; B 74 -15 553 538 ;
-C 100 ; WX 556 ; N d ; B 84 -15 652 718 ;
-C 101 ; WX 556 ; N e ; B 84 -15 578 538 ;
-C 102 ; WX 278 ; N f ; B 86 0 416 728 ; L i fi ; L l fl ;
-C 103 ; WX 556 ; N g ; B 42 -220 610 538 ;
-C 104 ; WX 556 ; N h ; B 65 0 573 718 ;
-C 105 ; WX 222 ; N i ; B 67 0 308 718 ;
-C 106 ; WX 222 ; N j ; B -60 -210 308 718 ;
-C 107 ; WX 500 ; N k ; B 67 0 600 718 ;
-C 108 ; WX 222 ; N l ; B 67 0 308 718 ;
-C 109 ; WX 833 ; N m ; B 65 0 852 538 ;
-C 110 ; WX 556 ; N n ; B 65 0 573 538 ;
-C 111 ; WX 556 ; N o ; B 83 -14 585 538 ;
-C 112 ; WX 556 ; N p ; B 14 -207 584 538 ;
-C 113 ; WX 556 ; N q ; B 84 -207 605 538 ;
-C 114 ; WX 333 ; N r ; B 77 0 446 538 ;
-C 115 ; WX 500 ; N s ; B 63 -15 529 538 ;
-C 116 ; WX 278 ; N t ; B 102 -7 368 669 ;
-C 117 ; WX 556 ; N u ; B 94 -15 600 523 ;
-C 118 ; WX 500 ; N v ; B 119 0 603 523 ;
-C 119 ; WX 722 ; N w ; B 125 0 820 523 ;
-C 120 ; WX 500 ; N x ; B 11 0 594 523 ;
-C 121 ; WX 500 ; N y ; B 15 -214 600 523 ;
-C 122 ; WX 500 ; N z ; B 31 0 571 523 ;
-C 123 ; WX 334 ; N braceleft ; B 92 -196 445 722 ;
-C 124 ; WX 260 ; N bar ; B 46 -225 332 775 ;
-C 125 ; WX 334 ; N braceright ; B 0 -196 354 722 ;
-C 126 ; WX 584 ; N asciitilde ; B 111 180 580 326 ;
-C 161 ; WX 333 ; N exclamdown ; B 77 -195 326 523 ;
-C 162 ; WX 556 ; N cent ; B 95 -115 584 623 ;
-C 163 ; WX 556 ; N sterling ; B 49 -16 634 718 ;
-C 164 ; WX 167 ; N fraction ; B -170 -19 482 703 ;
-C 165 ; WX 556 ; N yen ; B 81 0 699 688 ;
-C 166 ; WX 556 ; N florin ; B -52 -207 654 737 ;
-C 167 ; WX 556 ; N section ; B 76 -191 584 737 ;
-C 168 ; WX 556 ; N currency ; B 60 99 646 603 ;
-C 169 ; WX 191 ; N quotesingle ; B 157 463 285 718 ;
-C 170 ; WX 333 ; N quotedblleft ; B 138 470 461 725 ;
-C 171 ; WX 556 ; N guillemotleft ; B 146 108 554 446 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 137 108 340 446 ;
-C 173 ; WX 333 ; N guilsinglright ; B 111 108 314 446 ;
-C 174 ; WX 500 ; N fi ; B 86 0 587 728 ;
-C 175 ; WX 500 ; N fl ; B 86 0 585 728 ;
-C 177 ; WX 556 ; N endash ; B 51 240 623 313 ;
-C 178 ; WX 556 ; N dagger ; B 135 -159 622 718 ;
-C 179 ; WX 556 ; N daggerdbl ; B 52 -159 623 718 ;
-C 180 ; WX 278 ; N periodcentered ; B 129 190 257 315 ;
-C 182 ; WX 537 ; N paragraph ; B 126 -173 650 718 ;
-C 183 ; WX 350 ; N bullet ; B 91 202 413 517 ;
-C 184 ; WX 222 ; N quotesinglbase ; B 21 -149 180 106 ;
-C 185 ; WX 333 ; N quotedblbase ; B -6 -149 318 106 ;
-C 186 ; WX 333 ; N quotedblright ; B 124 463 448 718 ;
-C 187 ; WX 556 ; N guillemotright ; B 120 108 528 446 ;
-C 188 ; WX 1000 ; N ellipsis ; B 115 0 908 106 ;
-C 189 ; WX 1000 ; N perthousand ; B 88 -19 1029 703 ;
-C 191 ; WX 611 ; N questiondown ; B 85 -201 534 525 ;
-C 193 ; WX 333 ; N grave ; B 170 593 337 734 ;
-C 194 ; WX 333 ; N acute ; B 248 593 475 734 ;
-C 195 ; WX 333 ; N circumflex ; B 147 593 438 734 ;
-C 196 ; WX 333 ; N tilde ; B 125 606 490 722 ;
-C 197 ; WX 333 ; N macron ; B 143 627 468 684 ;
-C 198 ; WX 333 ; N breve ; B 167 595 476 731 ;
-C 199 ; WX 333 ; N dotaccent ; B 249 604 362 706 ;
-C 200 ; WX 333 ; N dieresis ; B 168 604 443 706 ;
-C 202 ; WX 333 ; N ring ; B 214 572 402 756 ;
-C 203 ; WX 333 ; N cedilla ; B 2 -225 232 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 157 593 565 734 ;
-C 206 ; WX 333 ; N ogonek ; B 43 -225 249 0 ;
-C 207 ; WX 333 ; N caron ; B 177 593 468 734 ;
-C 208 ; WX 1000 ; N emdash ; B 51 240 1067 313 ;
-C 225 ; WX 1000 ; N AE ; B 8 0 1097 718 ;
-C 227 ; WX 370 ; N ordfeminine ; B 127 405 449 737 ;
-C 232 ; WX 556 ; N Lslash ; B 41 0 555 718 ;
-C 233 ; WX 778 ; N Oslash ; B 43 -19 890 737 ;
-C 234 ; WX 1000 ; N OE ; B 98 -19 1116 737 ;
-C 235 ; WX 365 ; N ordmasculine ; B 141 405 468 737 ;
-C 241 ; WX 889 ; N ae ; B 61 -15 909 538 ;
-C 245 ; WX 278 ; N dotlessi ; B 95 0 294 523 ;
-C 248 ; WX 222 ; N lslash ; B 41 0 347 718 ;
-C 249 ; WX 611 ; N oslash ; B 29 -22 647 545 ;
-C 250 ; WX 944 ; N oe ; B 83 -15 964 538 ;
-C 251 ; WX 611 ; N germandbls ; B 67 -15 658 728 ;
-C -1 ; WX 278 ; N Idieresis ; B 91 0 458 901 ;
-C -1 ; WX 556 ; N eacute ; B 84 -15 587 734 ;
-C -1 ; WX 556 ; N abreve ; B 61 -15 578 731 ;
-C -1 ; WX 556 ; N uhungarumlaut ; B 94 -15 677 734 ;
-C -1 ; WX 556 ; N ecaron ; B 84 -15 580 734 ;
-C -1 ; WX 667 ; N Ydieresis ; B 167 0 806 901 ;
-C -1 ; WX 584 ; N divide ; B 85 -19 606 524 ;
-C -1 ; WX 667 ; N Yacute ; B 167 0 806 929 ;
-C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ;
-C -1 ; WX 556 ; N aacute ; B 61 -15 587 734 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 123 -19 797 929 ;
-C -1 ; WX 500 ; N yacute ; B 15 -214 600 734 ;
-C -1 ; WX 500 ; N scommaaccent ; B 63 -225 529 538 ;
-C -1 ; WX 556 ; N ecircumflex ; B 84 -15 578 734 ;
-C -1 ; WX 722 ; N Uring ; B 123 -19 797 931 ;
-C -1 ; WX 722 ; N Udieresis ; B 123 -19 797 901 ;
-C -1 ; WX 556 ; N aogonek ; B 61 -220 559 538 ;
-C -1 ; WX 722 ; N Uacute ; B 123 -19 797 929 ;
-C -1 ; WX 556 ; N uogonek ; B 94 -225 600 523 ;
-C -1 ; WX 667 ; N Edieresis ; B 86 0 762 901 ;
-C -1 ; WX 722 ; N Dcroat ; B 69 0 764 718 ;
-C -1 ; WX 250 ; N commaaccent ; B 39 -225 172 -40 ;
-C -1 ; WX 737 ; N copyright ; B 54 -19 837 737 ;
-C -1 ; WX 667 ; N Emacron ; B 86 0 762 879 ;
-C -1 ; WX 500 ; N ccaron ; B 74 -15 553 734 ;
-C -1 ; WX 556 ; N aring ; B 61 -15 559 756 ;
-C -1 ; WX 722 ; N Ncommaaccent ; B 76 -225 799 718 ;
-C -1 ; WX 222 ; N lacute ; B 67 0 461 929 ;
-C -1 ; WX 556 ; N agrave ; B 61 -15 559 734 ;
-C -1 ; WX 611 ; N Tcommaaccent ; B 148 -225 750 718 ;
-C -1 ; WX 722 ; N Cacute ; B 108 -19 782 929 ;
-C -1 ; WX 556 ; N atilde ; B 61 -15 592 722 ;
-C -1 ; WX 667 ; N Edotaccent ; B 86 0 762 901 ;
-C -1 ; WX 500 ; N scaron ; B 63 -15 552 734 ;
-C -1 ; WX 500 ; N scedilla ; B 63 -225 529 538 ;
-C -1 ; WX 278 ; N iacute ; B 95 0 448 734 ;
-C -1 ; WX 471 ; N lozenge ; B 88 0 540 728 ;
-C -1 ; WX 722 ; N Rcaron ; B 88 0 773 929 ;
-C -1 ; WX 778 ; N Gcommaaccent ; B 111 -225 799 737 ;
-C -1 ; WX 556 ; N ucircumflex ; B 94 -15 600 734 ;
-C -1 ; WX 556 ; N acircumflex ; B 61 -15 559 734 ;
-C -1 ; WX 667 ; N Amacron ; B 14 0 677 879 ;
-C -1 ; WX 333 ; N rcaron ; B 77 0 508 734 ;
-C -1 ; WX 500 ; N ccedilla ; B 74 -225 553 538 ;
-C -1 ; WX 611 ; N Zdotaccent ; B 23 0 741 901 ;
-C -1 ; WX 667 ; N Thorn ; B 86 0 712 718 ;
-C -1 ; WX 778 ; N Omacron ; B 105 -19 826 879 ;
-C -1 ; WX 722 ; N Racute ; B 88 0 773 929 ;
-C -1 ; WX 667 ; N Sacute ; B 90 -19 713 929 ;
-C -1 ; WX 643 ; N dcaron ; B 84 -15 808 718 ;
-C -1 ; WX 722 ; N Umacron ; B 123 -19 797 879 ;
-C -1 ; WX 556 ; N uring ; B 94 -15 600 756 ;
-C -1 ; WX 333 ; N threesuperior ; B 90 270 436 703 ;
-C -1 ; WX 778 ; N Ograve ; B 105 -19 826 929 ;
-C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ;
-C -1 ; WX 667 ; N Abreve ; B 14 0 685 926 ;
-C -1 ; WX 584 ; N multiply ; B 50 0 642 506 ;
-C -1 ; WX 556 ; N uacute ; B 94 -15 600 734 ;
-C -1 ; WX 611 ; N Tcaron ; B 148 0 750 929 ;
-C -1 ; WX 476 ; N partialdiff ; B 41 -38 550 714 ;
-C -1 ; WX 500 ; N ydieresis ; B 15 -214 600 706 ;
-C -1 ; WX 722 ; N Nacute ; B 76 0 799 929 ;
-C -1 ; WX 278 ; N icircumflex ; B 95 0 411 734 ;
-C -1 ; WX 667 ; N Ecircumflex ; B 86 0 762 929 ;
-C -1 ; WX 556 ; N adieresis ; B 61 -15 559 706 ;
-C -1 ; WX 556 ; N edieresis ; B 84 -15 578 706 ;
-C -1 ; WX 500 ; N cacute ; B 74 -15 559 734 ;
-C -1 ; WX 556 ; N nacute ; B 65 0 587 734 ;
-C -1 ; WX 556 ; N umacron ; B 94 -15 600 684 ;
-C -1 ; WX 722 ; N Ncaron ; B 76 0 799 929 ;
-C -1 ; WX 278 ; N Iacute ; B 91 0 489 929 ;
-C -1 ; WX 584 ; N plusminus ; B 39 0 618 506 ;
-C -1 ; WX 260 ; N brokenbar ; B 62 -150 316 700 ;
-C -1 ; WX 737 ; N registered ; B 54 -19 837 737 ;
-C -1 ; WX 778 ; N Gbreve ; B 111 -19 799 926 ;
-C -1 ; WX 278 ; N Idotaccent ; B 91 0 377 901 ;
-C -1 ; WX 600 ; N summation ; B 15 -10 671 706 ;
-C -1 ; WX 667 ; N Egrave ; B 86 0 762 929 ;
-C -1 ; WX 333 ; N racute ; B 77 0 475 734 ;
-C -1 ; WX 556 ; N omacron ; B 83 -14 585 684 ;
-C -1 ; WX 611 ; N Zacute ; B 23 0 741 929 ;
-C -1 ; WX 611 ; N Zcaron ; B 23 0 741 929 ;
-C -1 ; WX 549 ; N greaterequal ; B 26 0 620 674 ;
-C -1 ; WX 722 ; N Eth ; B 69 0 764 718 ;
-C -1 ; WX 722 ; N Ccedilla ; B 108 -225 782 737 ;
-C -1 ; WX 222 ; N lcommaaccent ; B 25 -225 308 718 ;
-C -1 ; WX 317 ; N tcaron ; B 102 -7 501 808 ;
-C -1 ; WX 556 ; N eogonek ; B 84 -225 578 538 ;
-C -1 ; WX 722 ; N Uogonek ; B 123 -225 797 718 ;
-C -1 ; WX 667 ; N Aacute ; B 14 0 683 929 ;
-C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ;
-C -1 ; WX 556 ; N egrave ; B 84 -15 578 734 ;
-C -1 ; WX 500 ; N zacute ; B 31 0 571 734 ;
-C -1 ; WX 222 ; N iogonek ; B -61 -225 308 718 ;
-C -1 ; WX 778 ; N Oacute ; B 105 -19 826 929 ;
-C -1 ; WX 556 ; N oacute ; B 83 -14 587 734 ;
-C -1 ; WX 556 ; N amacron ; B 61 -15 580 684 ;
-C -1 ; WX 500 ; N sacute ; B 63 -15 559 734 ;
-C -1 ; WX 278 ; N idieresis ; B 95 0 416 706 ;
-C -1 ; WX 778 ; N Ocircumflex ; B 105 -19 826 929 ;
-C -1 ; WX 722 ; N Ugrave ; B 123 -19 797 929 ;
-C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ;
-C -1 ; WX 556 ; N thorn ; B 14 -207 584 718 ;
-C -1 ; WX 333 ; N twosuperior ; B 64 281 449 703 ;
-C -1 ; WX 778 ; N Odieresis ; B 105 -19 826 901 ;
-C -1 ; WX 556 ; N mu ; B 24 -207 600 523 ;
-C -1 ; WX 278 ; N igrave ; B 95 0 310 734 ;
-C -1 ; WX 556 ; N ohungarumlaut ; B 83 -14 677 734 ;
-C -1 ; WX 667 ; N Eogonek ; B 86 -220 762 718 ;
-C -1 ; WX 556 ; N dcroat ; B 84 -15 689 718 ;
-C -1 ; WX 834 ; N threequarters ; B 130 -19 861 703 ;
-C -1 ; WX 667 ; N Scedilla ; B 90 -225 713 737 ;
-C -1 ; WX 299 ; N lcaron ; B 67 0 464 718 ;
-C -1 ; WX 667 ; N Kcommaaccent ; B 76 -225 808 718 ;
-C -1 ; WX 556 ; N Lacute ; B 76 0 555 929 ;
-C -1 ; WX 1000 ; N trademark ; B 186 306 1056 718 ;
-C -1 ; WX 556 ; N edotaccent ; B 84 -15 578 706 ;
-C -1 ; WX 278 ; N Igrave ; B 91 0 351 929 ;
-C -1 ; WX 278 ; N Imacron ; B 91 0 483 879 ;
-C -1 ; WX 556 ; N Lcaron ; B 76 0 570 718 ;
-C -1 ; WX 834 ; N onehalf ; B 114 -19 839 703 ;
-C -1 ; WX 549 ; N lessequal ; B 26 0 666 674 ;
-C -1 ; WX 556 ; N ocircumflex ; B 83 -14 585 734 ;
-C -1 ; WX 556 ; N ntilde ; B 65 0 592 722 ;
-C -1 ; WX 722 ; N Uhungarumlaut ; B 123 -19 801 929 ;
-C -1 ; WX 667 ; N Eacute ; B 86 0 762 929 ;
-C -1 ; WX 556 ; N emacron ; B 84 -15 580 684 ;
-C -1 ; WX 556 ; N gbreve ; B 42 -220 610 731 ;
-C -1 ; WX 834 ; N onequarter ; B 150 -19 802 703 ;
-C -1 ; WX 667 ; N Scaron ; B 90 -19 713 929 ;
-C -1 ; WX 667 ; N Scommaaccent ; B 90 -225 713 737 ;
-C -1 ; WX 778 ; N Ohungarumlaut ; B 105 -19 829 929 ;
-C -1 ; WX 400 ; N degree ; B 169 411 468 703 ;
-C -1 ; WX 556 ; N ograve ; B 83 -14 585 734 ;
-C -1 ; WX 722 ; N Ccaron ; B 108 -19 782 929 ;
-C -1 ; WX 556 ; N ugrave ; B 94 -15 600 734 ;
-C -1 ; WX 453 ; N radical ; B 79 -80 617 762 ;
-C -1 ; WX 722 ; N Dcaron ; B 81 0 764 929 ;
-C -1 ; WX 333 ; N rcommaaccent ; B 30 -225 446 538 ;
-C -1 ; WX 722 ; N Ntilde ; B 76 0 799 917 ;
-C -1 ; WX 556 ; N otilde ; B 83 -14 602 722 ;
-C -1 ; WX 722 ; N Rcommaaccent ; B 88 -225 773 718 ;
-C -1 ; WX 556 ; N Lcommaaccent ; B 76 -225 555 718 ;
-C -1 ; WX 667 ; N Atilde ; B 14 0 699 917 ;
-C -1 ; WX 667 ; N Aogonek ; B 14 -225 654 718 ;
-C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ;
-C -1 ; WX 778 ; N Otilde ; B 105 -19 826 917 ;
-C -1 ; WX 500 ; N zdotaccent ; B 31 0 571 706 ;
-C -1 ; WX 667 ; N Ecaron ; B 86 0 762 929 ;
-C -1 ; WX 278 ; N Iogonek ; B -33 -225 341 718 ;
-C -1 ; WX 500 ; N kcommaaccent ; B 67 -225 600 718 ;
-C -1 ; WX 584 ; N minus ; B 85 216 606 289 ;
-C -1 ; WX 278 ; N Icircumflex ; B 91 0 452 929 ;
-C -1 ; WX 556 ; N ncaron ; B 65 0 580 734 ;
-C -1 ; WX 278 ; N tcommaaccent ; B 63 -225 368 669 ;
-C -1 ; WX 584 ; N logicalnot ; B 106 108 628 390 ;
-C -1 ; WX 556 ; N odieresis ; B 83 -14 585 706 ;
-C -1 ; WX 556 ; N udieresis ; B 94 -15 600 706 ;
-C -1 ; WX 549 ; N notequal ; B 34 -35 623 551 ;
-C -1 ; WX 556 ; N gcommaaccent ; B 42 -220 610 822 ;
-C -1 ; WX 556 ; N eth ; B 81 -15 617 737 ;
-C -1 ; WX 500 ; N zcaron ; B 31 0 571 734 ;
-C -1 ; WX 556 ; N ncommaaccent ; B 65 -225 573 538 ;
-C -1 ; WX 333 ; N onesuperior ; B 166 281 371 703 ;
-C -1 ; WX 278 ; N imacron ; B 95 0 417 684 ;
-C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 2705
-KPX A C -30
-KPX A Cacute -30
-KPX A Ccaron -30
-KPX A Ccedilla -30
-KPX A G -30
-KPX A Gbreve -30
-KPX A Gcommaaccent -30
-KPX A O -30
-KPX A Oacute -30
-KPX A Ocircumflex -30
-KPX A Odieresis -30
-KPX A Ograve -30
-KPX A Ohungarumlaut -30
-KPX A Omacron -30
-KPX A Oslash -30
-KPX A Otilde -30
-KPX A Q -30
-KPX A T -120
-KPX A Tcaron -120
-KPX A Tcommaaccent -120
-KPX A U -50
-KPX A Uacute -50
-KPX A Ucircumflex -50
-KPX A Udieresis -50
-KPX A Ugrave -50
-KPX A Uhungarumlaut -50
-KPX A Umacron -50
-KPX A Uogonek -50
-KPX A Uring -50
-KPX A V -70
-KPX A W -50
-KPX A Y -100
-KPX A Yacute -100
-KPX A Ydieresis -100
-KPX A u -30
-KPX A uacute -30
-KPX A ucircumflex -30
-KPX A udieresis -30
-KPX A ugrave -30
-KPX A uhungarumlaut -30
-KPX A umacron -30
-KPX A uogonek -30
-KPX A uring -30
-KPX A v -40
-KPX A w -40
-KPX A y -40
-KPX A yacute -40
-KPX A ydieresis -40
-KPX Aacute C -30
-KPX Aacute Cacute -30
-KPX Aacute Ccaron -30
-KPX Aacute Ccedilla -30
-KPX Aacute G -30
-KPX Aacute Gbreve -30
-KPX Aacute Gcommaaccent -30
-KPX Aacute O -30
-KPX Aacute Oacute -30
-KPX Aacute Ocircumflex -30
-KPX Aacute Odieresis -30
-KPX Aacute Ograve -30
-KPX Aacute Ohungarumlaut -30
-KPX Aacute Omacron -30
-KPX Aacute Oslash -30
-KPX Aacute Otilde -30
-KPX Aacute Q -30
-KPX Aacute T -120
-KPX Aacute Tcaron -120
-KPX Aacute Tcommaaccent -120
-KPX Aacute U -50
-KPX Aacute Uacute -50
-KPX Aacute Ucircumflex -50
-KPX Aacute Udieresis -50
-KPX Aacute Ugrave -50
-KPX Aacute Uhungarumlaut -50
-KPX Aacute Umacron -50
-KPX Aacute Uogonek -50
-KPX Aacute Uring -50
-KPX Aacute V -70
-KPX Aacute W -50
-KPX Aacute Y -100
-KPX Aacute Yacute -100
-KPX Aacute Ydieresis -100
-KPX Aacute u -30
-KPX Aacute uacute -30
-KPX Aacute ucircumflex -30
-KPX Aacute udieresis -30
-KPX Aacute ugrave -30
-KPX Aacute uhungarumlaut -30
-KPX Aacute umacron -30
-KPX Aacute uogonek -30
-KPX Aacute uring -30
-KPX Aacute v -40
-KPX Aacute w -40
-KPX Aacute y -40
-KPX Aacute yacute -40
-KPX Aacute ydieresis -40
-KPX Abreve C -30
-KPX Abreve Cacute -30
-KPX Abreve Ccaron -30
-KPX Abreve Ccedilla -30
-KPX Abreve G -30
-KPX Abreve Gbreve -30
-KPX Abreve Gcommaaccent -30
-KPX Abreve O -30
-KPX Abreve Oacute -30
-KPX Abreve Ocircumflex -30
-KPX Abreve Odieresis -30
-KPX Abreve Ograve -30
-KPX Abreve Ohungarumlaut -30
-KPX Abreve Omacron -30
-KPX Abreve Oslash -30
-KPX Abreve Otilde -30
-KPX Abreve Q -30
-KPX Abreve T -120
-KPX Abreve Tcaron -120
-KPX Abreve Tcommaaccent -120
-KPX Abreve U -50
-KPX Abreve Uacute -50
-KPX Abreve Ucircumflex -50
-KPX Abreve Udieresis -50
-KPX Abreve Ugrave -50
-KPX Abreve Uhungarumlaut -50
-KPX Abreve Umacron -50
-KPX Abreve Uogonek -50
-KPX Abreve Uring -50
-KPX Abreve V -70
-KPX Abreve W -50
-KPX Abreve Y -100
-KPX Abreve Yacute -100
-KPX Abreve Ydieresis -100
-KPX Abreve u -30
-KPX Abreve uacute -30
-KPX Abreve ucircumflex -30
-KPX Abreve udieresis -30
-KPX Abreve ugrave -30
-KPX Abreve uhungarumlaut -30
-KPX Abreve umacron -30
-KPX Abreve uogonek -30
-KPX Abreve uring -30
-KPX Abreve v -40
-KPX Abreve w -40
-KPX Abreve y -40
-KPX Abreve yacute -40
-KPX Abreve ydieresis -40
-KPX Acircumflex C -30
-KPX Acircumflex Cacute -30
-KPX Acircumflex Ccaron -30
-KPX Acircumflex Ccedilla -30
-KPX Acircumflex G -30
-KPX Acircumflex Gbreve -30
-KPX Acircumflex Gcommaaccent -30
-KPX Acircumflex O -30
-KPX Acircumflex Oacute -30
-KPX Acircumflex Ocircumflex -30
-KPX Acircumflex Odieresis -30
-KPX Acircumflex Ograve -30
-KPX Acircumflex Ohungarumlaut -30
-KPX Acircumflex Omacron -30
-KPX Acircumflex Oslash -30
-KPX Acircumflex Otilde -30
-KPX Acircumflex Q -30
-KPX Acircumflex T -120
-KPX Acircumflex Tcaron -120
-KPX Acircumflex Tcommaaccent -120
-KPX Acircumflex U -50
-KPX Acircumflex Uacute -50
-KPX Acircumflex Ucircumflex -50
-KPX Acircumflex Udieresis -50
-KPX Acircumflex Ugrave -50
-KPX Acircumflex Uhungarumlaut -50
-KPX Acircumflex Umacron -50
-KPX Acircumflex Uogonek -50
-KPX Acircumflex Uring -50
-KPX Acircumflex V -70
-KPX Acircumflex W -50
-KPX Acircumflex Y -100
-KPX Acircumflex Yacute -100
-KPX Acircumflex Ydieresis -100
-KPX Acircumflex u -30
-KPX Acircumflex uacute -30
-KPX Acircumflex ucircumflex -30
-KPX Acircumflex udieresis -30
-KPX Acircumflex ugrave -30
-KPX Acircumflex uhungarumlaut -30
-KPX Acircumflex umacron -30
-KPX Acircumflex uogonek -30
-KPX Acircumflex uring -30
-KPX Acircumflex v -40
-KPX Acircumflex w -40
-KPX Acircumflex y -40
-KPX Acircumflex yacute -40
-KPX Acircumflex ydieresis -40
-KPX Adieresis C -30
-KPX Adieresis Cacute -30
-KPX Adieresis Ccaron -30
-KPX Adieresis Ccedilla -30
-KPX Adieresis G -30
-KPX Adieresis Gbreve -30
-KPX Adieresis Gcommaaccent -30
-KPX Adieresis O -30
-KPX Adieresis Oacute -30
-KPX Adieresis Ocircumflex -30
-KPX Adieresis Odieresis -30
-KPX Adieresis Ograve -30
-KPX Adieresis Ohungarumlaut -30
-KPX Adieresis Omacron -30
-KPX Adieresis Oslash -30
-KPX Adieresis Otilde -30
-KPX Adieresis Q -30
-KPX Adieresis T -120
-KPX Adieresis Tcaron -120
-KPX Adieresis Tcommaaccent -120
-KPX Adieresis U -50
-KPX Adieresis Uacute -50
-KPX Adieresis Ucircumflex -50
-KPX Adieresis Udieresis -50
-KPX Adieresis Ugrave -50
-KPX Adieresis Uhungarumlaut -50
-KPX Adieresis Umacron -50
-KPX Adieresis Uogonek -50
-KPX Adieresis Uring -50
-KPX Adieresis V -70
-KPX Adieresis W -50
-KPX Adieresis Y -100
-KPX Adieresis Yacute -100
-KPX Adieresis Ydieresis -100
-KPX Adieresis u -30
-KPX Adieresis uacute -30
-KPX Adieresis ucircumflex -30
-KPX Adieresis udieresis -30
-KPX Adieresis ugrave -30
-KPX Adieresis uhungarumlaut -30
-KPX Adieresis umacron -30
-KPX Adieresis uogonek -30
-KPX Adieresis uring -30
-KPX Adieresis v -40
-KPX Adieresis w -40
-KPX Adieresis y -40
-KPX Adieresis yacute -40
-KPX Adieresis ydieresis -40
-KPX Agrave C -30
-KPX Agrave Cacute -30
-KPX Agrave Ccaron -30
-KPX Agrave Ccedilla -30
-KPX Agrave G -30
-KPX Agrave Gbreve -30
-KPX Agrave Gcommaaccent -30
-KPX Agrave O -30
-KPX Agrave Oacute -30
-KPX Agrave Ocircumflex -30
-KPX Agrave Odieresis -30
-KPX Agrave Ograve -30
-KPX Agrave Ohungarumlaut -30
-KPX Agrave Omacron -30
-KPX Agrave Oslash -30
-KPX Agrave Otilde -30
-KPX Agrave Q -30
-KPX Agrave T -120
-KPX Agrave Tcaron -120
-KPX Agrave Tcommaaccent -120
-KPX Agrave U -50
-KPX Agrave Uacute -50
-KPX Agrave Ucircumflex -50
-KPX Agrave Udieresis -50
-KPX Agrave Ugrave -50
-KPX Agrave Uhungarumlaut -50
-KPX Agrave Umacron -50
-KPX Agrave Uogonek -50
-KPX Agrave Uring -50
-KPX Agrave V -70
-KPX Agrave W -50
-KPX Agrave Y -100
-KPX Agrave Yacute -100
-KPX Agrave Ydieresis -100
-KPX Agrave u -30
-KPX Agrave uacute -30
-KPX Agrave ucircumflex -30
-KPX Agrave udieresis -30
-KPX Agrave ugrave -30
-KPX Agrave uhungarumlaut -30
-KPX Agrave umacron -30
-KPX Agrave uogonek -30
-KPX Agrave uring -30
-KPX Agrave v -40
-KPX Agrave w -40
-KPX Agrave y -40
-KPX Agrave yacute -40
-KPX Agrave ydieresis -40
-KPX Amacron C -30
-KPX Amacron Cacute -30
-KPX Amacron Ccaron -30
-KPX Amacron Ccedilla -30
-KPX Amacron G -30
-KPX Amacron Gbreve -30
-KPX Amacron Gcommaaccent -30
-KPX Amacron O -30
-KPX Amacron Oacute -30
-KPX Amacron Ocircumflex -30
-KPX Amacron Odieresis -30
-KPX Amacron Ograve -30
-KPX Amacron Ohungarumlaut -30
-KPX Amacron Omacron -30
-KPX Amacron Oslash -30
-KPX Amacron Otilde -30
-KPX Amacron Q -30
-KPX Amacron T -120
-KPX Amacron Tcaron -120
-KPX Amacron Tcommaaccent -120
-KPX Amacron U -50
-KPX Amacron Uacute -50
-KPX Amacron Ucircumflex -50
-KPX Amacron Udieresis -50
-KPX Amacron Ugrave -50
-KPX Amacron Uhungarumlaut -50
-KPX Amacron Umacron -50
-KPX Amacron Uogonek -50
-KPX Amacron Uring -50
-KPX Amacron V -70
-KPX Amacron W -50
-KPX Amacron Y -100
-KPX Amacron Yacute -100
-KPX Amacron Ydieresis -100
-KPX Amacron u -30
-KPX Amacron uacute -30
-KPX Amacron ucircumflex -30
-KPX Amacron udieresis -30
-KPX Amacron ugrave -30
-KPX Amacron uhungarumlaut -30
-KPX Amacron umacron -30
-KPX Amacron uogonek -30
-KPX Amacron uring -30
-KPX Amacron v -40
-KPX Amacron w -40
-KPX Amacron y -40
-KPX Amacron yacute -40
-KPX Amacron ydieresis -40
-KPX Aogonek C -30
-KPX Aogonek Cacute -30
-KPX Aogonek Ccaron -30
-KPX Aogonek Ccedilla -30
-KPX Aogonek G -30
-KPX Aogonek Gbreve -30
-KPX Aogonek Gcommaaccent -30
-KPX Aogonek O -30
-KPX Aogonek Oacute -30
-KPX Aogonek Ocircumflex -30
-KPX Aogonek Odieresis -30
-KPX Aogonek Ograve -30
-KPX Aogonek Ohungarumlaut -30
-KPX Aogonek Omacron -30
-KPX Aogonek Oslash -30
-KPX Aogonek Otilde -30
-KPX Aogonek Q -30
-KPX Aogonek T -120
-KPX Aogonek Tcaron -120
-KPX Aogonek Tcommaaccent -120
-KPX Aogonek U -50
-KPX Aogonek Uacute -50
-KPX Aogonek Ucircumflex -50
-KPX Aogonek Udieresis -50
-KPX Aogonek Ugrave -50
-KPX Aogonek Uhungarumlaut -50
-KPX Aogonek Umacron -50
-KPX Aogonek Uogonek -50
-KPX Aogonek Uring -50
-KPX Aogonek V -70
-KPX Aogonek W -50
-KPX Aogonek Y -100
-KPX Aogonek Yacute -100
-KPX Aogonek Ydieresis -100
-KPX Aogonek u -30
-KPX Aogonek uacute -30
-KPX Aogonek ucircumflex -30
-KPX Aogonek udieresis -30
-KPX Aogonek ugrave -30
-KPX Aogonek uhungarumlaut -30
-KPX Aogonek umacron -30
-KPX Aogonek uogonek -30
-KPX Aogonek uring -30
-KPX Aogonek v -40
-KPX Aogonek w -40
-KPX Aogonek y -40
-KPX Aogonek yacute -40
-KPX Aogonek ydieresis -40
-KPX Aring C -30
-KPX Aring Cacute -30
-KPX Aring Ccaron -30
-KPX Aring Ccedilla -30
-KPX Aring G -30
-KPX Aring Gbreve -30
-KPX Aring Gcommaaccent -30
-KPX Aring O -30
-KPX Aring Oacute -30
-KPX Aring Ocircumflex -30
-KPX Aring Odieresis -30
-KPX Aring Ograve -30
-KPX Aring Ohungarumlaut -30
-KPX Aring Omacron -30
-KPX Aring Oslash -30
-KPX Aring Otilde -30
-KPX Aring Q -30
-KPX Aring T -120
-KPX Aring Tcaron -120
-KPX Aring Tcommaaccent -120
-KPX Aring U -50
-KPX Aring Uacute -50
-KPX Aring Ucircumflex -50
-KPX Aring Udieresis -50
-KPX Aring Ugrave -50
-KPX Aring Uhungarumlaut -50
-KPX Aring Umacron -50
-KPX Aring Uogonek -50
-KPX Aring Uring -50
-KPX Aring V -70
-KPX Aring W -50
-KPX Aring Y -100
-KPX Aring Yacute -100
-KPX Aring Ydieresis -100
-KPX Aring u -30
-KPX Aring uacute -30
-KPX Aring ucircumflex -30
-KPX Aring udieresis -30
-KPX Aring ugrave -30
-KPX Aring uhungarumlaut -30
-KPX Aring umacron -30
-KPX Aring uogonek -30
-KPX Aring uring -30
-KPX Aring v -40
-KPX Aring w -40
-KPX Aring y -40
-KPX Aring yacute -40
-KPX Aring ydieresis -40
-KPX Atilde C -30
-KPX Atilde Cacute -30
-KPX Atilde Ccaron -30
-KPX Atilde Ccedilla -30
-KPX Atilde G -30
-KPX Atilde Gbreve -30
-KPX Atilde Gcommaaccent -30
-KPX Atilde O -30
-KPX Atilde Oacute -30
-KPX Atilde Ocircumflex -30
-KPX Atilde Odieresis -30
-KPX Atilde Ograve -30
-KPX Atilde Ohungarumlaut -30
-KPX Atilde Omacron -30
-KPX Atilde Oslash -30
-KPX Atilde Otilde -30
-KPX Atilde Q -30
-KPX Atilde T -120
-KPX Atilde Tcaron -120
-KPX Atilde Tcommaaccent -120
-KPX Atilde U -50
-KPX Atilde Uacute -50
-KPX Atilde Ucircumflex -50
-KPX Atilde Udieresis -50
-KPX Atilde Ugrave -50
-KPX Atilde Uhungarumlaut -50
-KPX Atilde Umacron -50
-KPX Atilde Uogonek -50
-KPX Atilde Uring -50
-KPX Atilde V -70
-KPX Atilde W -50
-KPX Atilde Y -100
-KPX Atilde Yacute -100
-KPX Atilde Ydieresis -100
-KPX Atilde u -30
-KPX Atilde uacute -30
-KPX Atilde ucircumflex -30
-KPX Atilde udieresis -30
-KPX Atilde ugrave -30
-KPX Atilde uhungarumlaut -30
-KPX Atilde umacron -30
-KPX Atilde uogonek -30
-KPX Atilde uring -30
-KPX Atilde v -40
-KPX Atilde w -40
-KPX Atilde y -40
-KPX Atilde yacute -40
-KPX Atilde ydieresis -40
-KPX B U -10
-KPX B Uacute -10
-KPX B Ucircumflex -10
-KPX B Udieresis -10
-KPX B Ugrave -10
-KPX B Uhungarumlaut -10
-KPX B Umacron -10
-KPX B Uogonek -10
-KPX B Uring -10
-KPX B comma -20
-KPX B period -20
-KPX C comma -30
-KPX C period -30
-KPX Cacute comma -30
-KPX Cacute period -30
-KPX Ccaron comma -30
-KPX Ccaron period -30
-KPX Ccedilla comma -30
-KPX Ccedilla period -30
-KPX D A -40
-KPX D Aacute -40
-KPX D Abreve -40
-KPX D Acircumflex -40
-KPX D Adieresis -40
-KPX D Agrave -40
-KPX D Amacron -40
-KPX D Aogonek -40
-KPX D Aring -40
-KPX D Atilde -40
-KPX D V -70
-KPX D W -40
-KPX D Y -90
-KPX D Yacute -90
-KPX D Ydieresis -90
-KPX D comma -70
-KPX D period -70
-KPX Dcaron A -40
-KPX Dcaron Aacute -40
-KPX Dcaron Abreve -40
-KPX Dcaron Acircumflex -40
-KPX Dcaron Adieresis -40
-KPX Dcaron Agrave -40
-KPX Dcaron Amacron -40
-KPX Dcaron Aogonek -40
-KPX Dcaron Aring -40
-KPX Dcaron Atilde -40
-KPX Dcaron V -70
-KPX Dcaron W -40
-KPX Dcaron Y -90
-KPX Dcaron Yacute -90
-KPX Dcaron Ydieresis -90
-KPX Dcaron comma -70
-KPX Dcaron period -70
-KPX Dcroat A -40
-KPX Dcroat Aacute -40
-KPX Dcroat Abreve -40
-KPX Dcroat Acircumflex -40
-KPX Dcroat Adieresis -40
-KPX Dcroat Agrave -40
-KPX Dcroat Amacron -40
-KPX Dcroat Aogonek -40
-KPX Dcroat Aring -40
-KPX Dcroat Atilde -40
-KPX Dcroat V -70
-KPX Dcroat W -40
-KPX Dcroat Y -90
-KPX Dcroat Yacute -90
-KPX Dcroat Ydieresis -90
-KPX Dcroat comma -70
-KPX Dcroat period -70
-KPX F A -80
-KPX F Aacute -80
-KPX F Abreve -80
-KPX F Acircumflex -80
-KPX F Adieresis -80
-KPX F Agrave -80
-KPX F Amacron -80
-KPX F Aogonek -80
-KPX F Aring -80
-KPX F Atilde -80
-KPX F a -50
-KPX F aacute -50
-KPX F abreve -50
-KPX F acircumflex -50
-KPX F adieresis -50
-KPX F agrave -50
-KPX F amacron -50
-KPX F aogonek -50
-KPX F aring -50
-KPX F atilde -50
-KPX F comma -150
-KPX F e -30
-KPX F eacute -30
-KPX F ecaron -30
-KPX F ecircumflex -30
-KPX F edieresis -30
-KPX F edotaccent -30
-KPX F egrave -30
-KPX F emacron -30
-KPX F eogonek -30
-KPX F o -30
-KPX F oacute -30
-KPX F ocircumflex -30
-KPX F odieresis -30
-KPX F ograve -30
-KPX F ohungarumlaut -30
-KPX F omacron -30
-KPX F oslash -30
-KPX F otilde -30
-KPX F period -150
-KPX F r -45
-KPX F racute -45
-KPX F rcaron -45
-KPX F rcommaaccent -45
-KPX J A -20
-KPX J Aacute -20
-KPX J Abreve -20
-KPX J Acircumflex -20
-KPX J Adieresis -20
-KPX J Agrave -20
-KPX J Amacron -20
-KPX J Aogonek -20
-KPX J Aring -20
-KPX J Atilde -20
-KPX J a -20
-KPX J aacute -20
-KPX J abreve -20
-KPX J acircumflex -20
-KPX J adieresis -20
-KPX J agrave -20
-KPX J amacron -20
-KPX J aogonek -20
-KPX J aring -20
-KPX J atilde -20
-KPX J comma -30
-KPX J period -30
-KPX J u -20
-KPX J uacute -20
-KPX J ucircumflex -20
-KPX J udieresis -20
-KPX J ugrave -20
-KPX J uhungarumlaut -20
-KPX J umacron -20
-KPX J uogonek -20
-KPX J uring -20
-KPX K O -50
-KPX K Oacute -50
-KPX K Ocircumflex -50
-KPX K Odieresis -50
-KPX K Ograve -50
-KPX K Ohungarumlaut -50
-KPX K Omacron -50
-KPX K Oslash -50
-KPX K Otilde -50
-KPX K e -40
-KPX K eacute -40
-KPX K ecaron -40
-KPX K ecircumflex -40
-KPX K edieresis -40
-KPX K edotaccent -40
-KPX K egrave -40
-KPX K emacron -40
-KPX K eogonek -40
-KPX K o -40
-KPX K oacute -40
-KPX K ocircumflex -40
-KPX K odieresis -40
-KPX K ograve -40
-KPX K ohungarumlaut -40
-KPX K omacron -40
-KPX K oslash -40
-KPX K otilde -40
-KPX K u -30
-KPX K uacute -30
-KPX K ucircumflex -30
-KPX K udieresis -30
-KPX K ugrave -30
-KPX K uhungarumlaut -30
-KPX K umacron -30
-KPX K uogonek -30
-KPX K uring -30
-KPX K y -50
-KPX K yacute -50
-KPX K ydieresis -50
-KPX Kcommaaccent O -50
-KPX Kcommaaccent Oacute -50
-KPX Kcommaaccent Ocircumflex -50
-KPX Kcommaaccent Odieresis -50
-KPX Kcommaaccent Ograve -50
-KPX Kcommaaccent Ohungarumlaut -50
-KPX Kcommaaccent Omacron -50
-KPX Kcommaaccent Oslash -50
-KPX Kcommaaccent Otilde -50
-KPX Kcommaaccent e -40
-KPX Kcommaaccent eacute -40
-KPX Kcommaaccent ecaron -40
-KPX Kcommaaccent ecircumflex -40
-KPX Kcommaaccent edieresis -40
-KPX Kcommaaccent edotaccent -40
-KPX Kcommaaccent egrave -40
-KPX Kcommaaccent emacron -40
-KPX Kcommaaccent eogonek -40
-KPX Kcommaaccent o -40
-KPX Kcommaaccent oacute -40
-KPX Kcommaaccent ocircumflex -40
-KPX Kcommaaccent odieresis -40
-KPX Kcommaaccent ograve -40
-KPX Kcommaaccent ohungarumlaut -40
-KPX Kcommaaccent omacron -40
-KPX Kcommaaccent oslash -40
-KPX Kcommaaccent otilde -40
-KPX Kcommaaccent u -30
-KPX Kcommaaccent uacute -30
-KPX Kcommaaccent ucircumflex -30
-KPX Kcommaaccent udieresis -30
-KPX Kcommaaccent ugrave -30
-KPX Kcommaaccent uhungarumlaut -30
-KPX Kcommaaccent umacron -30
-KPX Kcommaaccent uogonek -30
-KPX Kcommaaccent uring -30
-KPX Kcommaaccent y -50
-KPX Kcommaaccent yacute -50
-KPX Kcommaaccent ydieresis -50
-KPX L T -110
-KPX L Tcaron -110
-KPX L Tcommaaccent -110
-KPX L V -110
-KPX L W -70
-KPX L Y -140
-KPX L Yacute -140
-KPX L Ydieresis -140
-KPX L quotedblright -140
-KPX L quoteright -160
-KPX L y -30
-KPX L yacute -30
-KPX L ydieresis -30
-KPX Lacute T -110
-KPX Lacute Tcaron -110
-KPX Lacute Tcommaaccent -110
-KPX Lacute V -110
-KPX Lacute W -70
-KPX Lacute Y -140
-KPX Lacute Yacute -140
-KPX Lacute Ydieresis -140
-KPX Lacute quotedblright -140
-KPX Lacute quoteright -160
-KPX Lacute y -30
-KPX Lacute yacute -30
-KPX Lacute ydieresis -30
-KPX Lcaron T -110
-KPX Lcaron Tcaron -110
-KPX Lcaron Tcommaaccent -110
-KPX Lcaron V -110
-KPX Lcaron W -70
-KPX Lcaron Y -140
-KPX Lcaron Yacute -140
-KPX Lcaron Ydieresis -140
-KPX Lcaron quotedblright -140
-KPX Lcaron quoteright -160
-KPX Lcaron y -30
-KPX Lcaron yacute -30
-KPX Lcaron ydieresis -30
-KPX Lcommaaccent T -110
-KPX Lcommaaccent Tcaron -110
-KPX Lcommaaccent Tcommaaccent -110
-KPX Lcommaaccent V -110
-KPX Lcommaaccent W -70
-KPX Lcommaaccent Y -140
-KPX Lcommaaccent Yacute -140
-KPX Lcommaaccent Ydieresis -140
-KPX Lcommaaccent quotedblright -140
-KPX Lcommaaccent quoteright -160
-KPX Lcommaaccent y -30
-KPX Lcommaaccent yacute -30
-KPX Lcommaaccent ydieresis -30
-KPX Lslash T -110
-KPX Lslash Tcaron -110
-KPX Lslash Tcommaaccent -110
-KPX Lslash V -110
-KPX Lslash W -70
-KPX Lslash Y -140
-KPX Lslash Yacute -140
-KPX Lslash Ydieresis -140
-KPX Lslash quotedblright -140
-KPX Lslash quoteright -160
-KPX Lslash y -30
-KPX Lslash yacute -30
-KPX Lslash ydieresis -30
-KPX O A -20
-KPX O Aacute -20
-KPX O Abreve -20
-KPX O Acircumflex -20
-KPX O Adieresis -20
-KPX O Agrave -20
-KPX O Amacron -20
-KPX O Aogonek -20
-KPX O Aring -20
-KPX O Atilde -20
-KPX O T -40
-KPX O Tcaron -40
-KPX O Tcommaaccent -40
-KPX O V -50
-KPX O W -30
-KPX O X -60
-KPX O Y -70
-KPX O Yacute -70
-KPX O Ydieresis -70
-KPX O comma -40
-KPX O period -40
-KPX Oacute A -20
-KPX Oacute Aacute -20
-KPX Oacute Abreve -20
-KPX Oacute Acircumflex -20
-KPX Oacute Adieresis -20
-KPX Oacute Agrave -20
-KPX Oacute Amacron -20
-KPX Oacute Aogonek -20
-KPX Oacute Aring -20
-KPX Oacute Atilde -20
-KPX Oacute T -40
-KPX Oacute Tcaron -40
-KPX Oacute Tcommaaccent -40
-KPX Oacute V -50
-KPX Oacute W -30
-KPX Oacute X -60
-KPX Oacute Y -70
-KPX Oacute Yacute -70
-KPX Oacute Ydieresis -70
-KPX Oacute comma -40
-KPX Oacute period -40
-KPX Ocircumflex A -20
-KPX Ocircumflex Aacute -20
-KPX Ocircumflex Abreve -20
-KPX Ocircumflex Acircumflex -20
-KPX Ocircumflex Adieresis -20
-KPX Ocircumflex Agrave -20
-KPX Ocircumflex Amacron -20
-KPX Ocircumflex Aogonek -20
-KPX Ocircumflex Aring -20
-KPX Ocircumflex Atilde -20
-KPX Ocircumflex T -40
-KPX Ocircumflex Tcaron -40
-KPX Ocircumflex Tcommaaccent -40
-KPX Ocircumflex V -50
-KPX Ocircumflex W -30
-KPX Ocircumflex X -60
-KPX Ocircumflex Y -70
-KPX Ocircumflex Yacute -70
-KPX Ocircumflex Ydieresis -70
-KPX Ocircumflex comma -40
-KPX Ocircumflex period -40
-KPX Odieresis A -20
-KPX Odieresis Aacute -20
-KPX Odieresis Abreve -20
-KPX Odieresis Acircumflex -20
-KPX Odieresis Adieresis -20
-KPX Odieresis Agrave -20
-KPX Odieresis Amacron -20
-KPX Odieresis Aogonek -20
-KPX Odieresis Aring -20
-KPX Odieresis Atilde -20
-KPX Odieresis T -40
-KPX Odieresis Tcaron -40
-KPX Odieresis Tcommaaccent -40
-KPX Odieresis V -50
-KPX Odieresis W -30
-KPX Odieresis X -60
-KPX Odieresis Y -70
-KPX Odieresis Yacute -70
-KPX Odieresis Ydieresis -70
-KPX Odieresis comma -40
-KPX Odieresis period -40
-KPX Ograve A -20
-KPX Ograve Aacute -20
-KPX Ograve Abreve -20
-KPX Ograve Acircumflex -20
-KPX Ograve Adieresis -20
-KPX Ograve Agrave -20
-KPX Ograve Amacron -20
-KPX Ograve Aogonek -20
-KPX Ograve Aring -20
-KPX Ograve Atilde -20
-KPX Ograve T -40
-KPX Ograve Tcaron -40
-KPX Ograve Tcommaaccent -40
-KPX Ograve V -50
-KPX Ograve W -30
-KPX Ograve X -60
-KPX Ograve Y -70
-KPX Ograve Yacute -70
-KPX Ograve Ydieresis -70
-KPX Ograve comma -40
-KPX Ograve period -40
-KPX Ohungarumlaut A -20
-KPX Ohungarumlaut Aacute -20
-KPX Ohungarumlaut Abreve -20
-KPX Ohungarumlaut Acircumflex -20
-KPX Ohungarumlaut Adieresis -20
-KPX Ohungarumlaut Agrave -20
-KPX Ohungarumlaut Amacron -20
-KPX Ohungarumlaut Aogonek -20
-KPX Ohungarumlaut Aring -20
-KPX Ohungarumlaut Atilde -20
-KPX Ohungarumlaut T -40
-KPX Ohungarumlaut Tcaron -40
-KPX Ohungarumlaut Tcommaaccent -40
-KPX Ohungarumlaut V -50
-KPX Ohungarumlaut W -30
-KPX Ohungarumlaut X -60
-KPX Ohungarumlaut Y -70
-KPX Ohungarumlaut Yacute -70
-KPX Ohungarumlaut Ydieresis -70
-KPX Ohungarumlaut comma -40
-KPX Ohungarumlaut period -40
-KPX Omacron A -20
-KPX Omacron Aacute -20
-KPX Omacron Abreve -20
-KPX Omacron Acircumflex -20
-KPX Omacron Adieresis -20
-KPX Omacron Agrave -20
-KPX Omacron Amacron -20
-KPX Omacron Aogonek -20
-KPX Omacron Aring -20
-KPX Omacron Atilde -20
-KPX Omacron T -40
-KPX Omacron Tcaron -40
-KPX Omacron Tcommaaccent -40
-KPX Omacron V -50
-KPX Omacron W -30
-KPX Omacron X -60
-KPX Omacron Y -70
-KPX Omacron Yacute -70
-KPX Omacron Ydieresis -70
-KPX Omacron comma -40
-KPX Omacron period -40
-KPX Oslash A -20
-KPX Oslash Aacute -20
-KPX Oslash Abreve -20
-KPX Oslash Acircumflex -20
-KPX Oslash Adieresis -20
-KPX Oslash Agrave -20
-KPX Oslash Amacron -20
-KPX Oslash Aogonek -20
-KPX Oslash Aring -20
-KPX Oslash Atilde -20
-KPX Oslash T -40
-KPX Oslash Tcaron -40
-KPX Oslash Tcommaaccent -40
-KPX Oslash V -50
-KPX Oslash W -30
-KPX Oslash X -60
-KPX Oslash Y -70
-KPX Oslash Yacute -70
-KPX Oslash Ydieresis -70
-KPX Oslash comma -40
-KPX Oslash period -40
-KPX Otilde A -20
-KPX Otilde Aacute -20
-KPX Otilde Abreve -20
-KPX Otilde Acircumflex -20
-KPX Otilde Adieresis -20
-KPX Otilde Agrave -20
-KPX Otilde Amacron -20
-KPX Otilde Aogonek -20
-KPX Otilde Aring -20
-KPX Otilde Atilde -20
-KPX Otilde T -40
-KPX Otilde Tcaron -40
-KPX Otilde Tcommaaccent -40
-KPX Otilde V -50
-KPX Otilde W -30
-KPX Otilde X -60
-KPX Otilde Y -70
-KPX Otilde Yacute -70
-KPX Otilde Ydieresis -70
-KPX Otilde comma -40
-KPX Otilde period -40
-KPX P A -120
-KPX P Aacute -120
-KPX P Abreve -120
-KPX P Acircumflex -120
-KPX P Adieresis -120
-KPX P Agrave -120
-KPX P Amacron -120
-KPX P Aogonek -120
-KPX P Aring -120
-KPX P Atilde -120
-KPX P a -40
-KPX P aacute -40
-KPX P abreve -40
-KPX P acircumflex -40
-KPX P adieresis -40
-KPX P agrave -40
-KPX P amacron -40
-KPX P aogonek -40
-KPX P aring -40
-KPX P atilde -40
-KPX P comma -180
-KPX P e -50
-KPX P eacute -50
-KPX P ecaron -50
-KPX P ecircumflex -50
-KPX P edieresis -50
-KPX P edotaccent -50
-KPX P egrave -50
-KPX P emacron -50
-KPX P eogonek -50
-KPX P o -50
-KPX P oacute -50
-KPX P ocircumflex -50
-KPX P odieresis -50
-KPX P ograve -50
-KPX P ohungarumlaut -50
-KPX P omacron -50
-KPX P oslash -50
-KPX P otilde -50
-KPX P period -180
-KPX Q U -10
-KPX Q Uacute -10
-KPX Q Ucircumflex -10
-KPX Q Udieresis -10
-KPX Q Ugrave -10
-KPX Q Uhungarumlaut -10
-KPX Q Umacron -10
-KPX Q Uogonek -10
-KPX Q Uring -10
-KPX R O -20
-KPX R Oacute -20
-KPX R Ocircumflex -20
-KPX R Odieresis -20
-KPX R Ograve -20
-KPX R Ohungarumlaut -20
-KPX R Omacron -20
-KPX R Oslash -20
-KPX R Otilde -20
-KPX R T -30
-KPX R Tcaron -30
-KPX R Tcommaaccent -30
-KPX R U -40
-KPX R Uacute -40
-KPX R Ucircumflex -40
-KPX R Udieresis -40
-KPX R Ugrave -40
-KPX R Uhungarumlaut -40
-KPX R Umacron -40
-KPX R Uogonek -40
-KPX R Uring -40
-KPX R V -50
-KPX R W -30
-KPX R Y -50
-KPX R Yacute -50
-KPX R Ydieresis -50
-KPX Racute O -20
-KPX Racute Oacute -20
-KPX Racute Ocircumflex -20
-KPX Racute Odieresis -20
-KPX Racute Ograve -20
-KPX Racute Ohungarumlaut -20
-KPX Racute Omacron -20
-KPX Racute Oslash -20
-KPX Racute Otilde -20
-KPX Racute T -30
-KPX Racute Tcaron -30
-KPX Racute Tcommaaccent -30
-KPX Racute U -40
-KPX Racute Uacute -40
-KPX Racute Ucircumflex -40
-KPX Racute Udieresis -40
-KPX Racute Ugrave -40
-KPX Racute Uhungarumlaut -40
-KPX Racute Umacron -40
-KPX Racute Uogonek -40
-KPX Racute Uring -40
-KPX Racute V -50
-KPX Racute W -30
-KPX Racute Y -50
-KPX Racute Yacute -50
-KPX Racute Ydieresis -50
-KPX Rcaron O -20
-KPX Rcaron Oacute -20
-KPX Rcaron Ocircumflex -20
-KPX Rcaron Odieresis -20
-KPX Rcaron Ograve -20
-KPX Rcaron Ohungarumlaut -20
-KPX Rcaron Omacron -20
-KPX Rcaron Oslash -20
-KPX Rcaron Otilde -20
-KPX Rcaron T -30
-KPX Rcaron Tcaron -30
-KPX Rcaron Tcommaaccent -30
-KPX Rcaron U -40
-KPX Rcaron Uacute -40
-KPX Rcaron Ucircumflex -40
-KPX Rcaron Udieresis -40
-KPX Rcaron Ugrave -40
-KPX Rcaron Uhungarumlaut -40
-KPX Rcaron Umacron -40
-KPX Rcaron Uogonek -40
-KPX Rcaron Uring -40
-KPX Rcaron V -50
-KPX Rcaron W -30
-KPX Rcaron Y -50
-KPX Rcaron Yacute -50
-KPX Rcaron Ydieresis -50
-KPX Rcommaaccent O -20
-KPX Rcommaaccent Oacute -20
-KPX Rcommaaccent Ocircumflex -20
-KPX Rcommaaccent Odieresis -20
-KPX Rcommaaccent Ograve -20
-KPX Rcommaaccent Ohungarumlaut -20
-KPX Rcommaaccent Omacron -20
-KPX Rcommaaccent Oslash -20
-KPX Rcommaaccent Otilde -20
-KPX Rcommaaccent T -30
-KPX Rcommaaccent Tcaron -30
-KPX Rcommaaccent Tcommaaccent -30
-KPX Rcommaaccent U -40
-KPX Rcommaaccent Uacute -40
-KPX Rcommaaccent Ucircumflex -40
-KPX Rcommaaccent Udieresis -40
-KPX Rcommaaccent Ugrave -40
-KPX Rcommaaccent Uhungarumlaut -40
-KPX Rcommaaccent Umacron -40
-KPX Rcommaaccent Uogonek -40
-KPX Rcommaaccent Uring -40
-KPX Rcommaaccent V -50
-KPX Rcommaaccent W -30
-KPX Rcommaaccent Y -50
-KPX Rcommaaccent Yacute -50
-KPX Rcommaaccent Ydieresis -50
-KPX S comma -20
-KPX S period -20
-KPX Sacute comma -20
-KPX Sacute period -20
-KPX Scaron comma -20
-KPX Scaron period -20
-KPX Scedilla comma -20
-KPX Scedilla period -20
-KPX Scommaaccent comma -20
-KPX Scommaaccent period -20
-KPX T A -120
-KPX T Aacute -120
-KPX T Abreve -120
-KPX T Acircumflex -120
-KPX T Adieresis -120
-KPX T Agrave -120
-KPX T Amacron -120
-KPX T Aogonek -120
-KPX T Aring -120
-KPX T Atilde -120
-KPX T O -40
-KPX T Oacute -40
-KPX T Ocircumflex -40
-KPX T Odieresis -40
-KPX T Ograve -40
-KPX T Ohungarumlaut -40
-KPX T Omacron -40
-KPX T Oslash -40
-KPX T Otilde -40
-KPX T a -120
-KPX T aacute -120
-KPX T abreve -60
-KPX T acircumflex -120
-KPX T adieresis -120
-KPX T agrave -120
-KPX T amacron -60
-KPX T aogonek -120
-KPX T aring -120
-KPX T atilde -60
-KPX T colon -20
-KPX T comma -120
-KPX T e -120
-KPX T eacute -120
-KPX T ecaron -120
-KPX T ecircumflex -120
-KPX T edieresis -120
-KPX T edotaccent -120
-KPX T egrave -60
-KPX T emacron -60
-KPX T eogonek -120
-KPX T hyphen -140
-KPX T o -120
-KPX T oacute -120
-KPX T ocircumflex -120
-KPX T odieresis -120
-KPX T ograve -120
-KPX T ohungarumlaut -120
-KPX T omacron -60
-KPX T oslash -120
-KPX T otilde -60
-KPX T period -120
-KPX T r -120
-KPX T racute -120
-KPX T rcaron -120
-KPX T rcommaaccent -120
-KPX T semicolon -20
-KPX T u -120
-KPX T uacute -120
-KPX T ucircumflex -120
-KPX T udieresis -120
-KPX T ugrave -120
-KPX T uhungarumlaut -120
-KPX T umacron -60
-KPX T uogonek -120
-KPX T uring -120
-KPX T w -120
-KPX T y -120
-KPX T yacute -120
-KPX T ydieresis -60
-KPX Tcaron A -120
-KPX Tcaron Aacute -120
-KPX Tcaron Abreve -120
-KPX Tcaron Acircumflex -120
-KPX Tcaron Adieresis -120
-KPX Tcaron Agrave -120
-KPX Tcaron Amacron -120
-KPX Tcaron Aogonek -120
-KPX Tcaron Aring -120
-KPX Tcaron Atilde -120
-KPX Tcaron O -40
-KPX Tcaron Oacute -40
-KPX Tcaron Ocircumflex -40
-KPX Tcaron Odieresis -40
-KPX Tcaron Ograve -40
-KPX Tcaron Ohungarumlaut -40
-KPX Tcaron Omacron -40
-KPX Tcaron Oslash -40
-KPX Tcaron Otilde -40
-KPX Tcaron a -120
-KPX Tcaron aacute -120
-KPX Tcaron abreve -60
-KPX Tcaron acircumflex -120
-KPX Tcaron adieresis -120
-KPX Tcaron agrave -120
-KPX Tcaron amacron -60
-KPX Tcaron aogonek -120
-KPX Tcaron aring -120
-KPX Tcaron atilde -60
-KPX Tcaron colon -20
-KPX Tcaron comma -120
-KPX Tcaron e -120
-KPX Tcaron eacute -120
-KPX Tcaron ecaron -120
-KPX Tcaron ecircumflex -120
-KPX Tcaron edieresis -120
-KPX Tcaron edotaccent -120
-KPX Tcaron egrave -60
-KPX Tcaron emacron -60
-KPX Tcaron eogonek -120
-KPX Tcaron hyphen -140
-KPX Tcaron o -120
-KPX Tcaron oacute -120
-KPX Tcaron ocircumflex -120
-KPX Tcaron odieresis -120
-KPX Tcaron ograve -120
-KPX Tcaron ohungarumlaut -120
-KPX Tcaron omacron -60
-KPX Tcaron oslash -120
-KPX Tcaron otilde -60
-KPX Tcaron period -120
-KPX Tcaron r -120
-KPX Tcaron racute -120
-KPX Tcaron rcaron -120
-KPX Tcaron rcommaaccent -120
-KPX Tcaron semicolon -20
-KPX Tcaron u -120
-KPX Tcaron uacute -120
-KPX Tcaron ucircumflex -120
-KPX Tcaron udieresis -120
-KPX Tcaron ugrave -120
-KPX Tcaron uhungarumlaut -120
-KPX Tcaron umacron -60
-KPX Tcaron uogonek -120
-KPX Tcaron uring -120
-KPX Tcaron w -120
-KPX Tcaron y -120
-KPX Tcaron yacute -120
-KPX Tcaron ydieresis -60
-KPX Tcommaaccent A -120
-KPX Tcommaaccent Aacute -120
-KPX Tcommaaccent Abreve -120
-KPX Tcommaaccent Acircumflex -120
-KPX Tcommaaccent Adieresis -120
-KPX Tcommaaccent Agrave -120
-KPX Tcommaaccent Amacron -120
-KPX Tcommaaccent Aogonek -120
-KPX Tcommaaccent Aring -120
-KPX Tcommaaccent Atilde -120
-KPX Tcommaaccent O -40
-KPX Tcommaaccent Oacute -40
-KPX Tcommaaccent Ocircumflex -40
-KPX Tcommaaccent Odieresis -40
-KPX Tcommaaccent Ograve -40
-KPX Tcommaaccent Ohungarumlaut -40
-KPX Tcommaaccent Omacron -40
-KPX Tcommaaccent Oslash -40
-KPX Tcommaaccent Otilde -40
-KPX Tcommaaccent a -120
-KPX Tcommaaccent aacute -120
-KPX Tcommaaccent abreve -60
-KPX Tcommaaccent acircumflex -120
-KPX Tcommaaccent adieresis -120
-KPX Tcommaaccent agrave -120
-KPX Tcommaaccent amacron -60
-KPX Tcommaaccent aogonek -120
-KPX Tcommaaccent aring -120
-KPX Tcommaaccent atilde -60
-KPX Tcommaaccent colon -20
-KPX Tcommaaccent comma -120
-KPX Tcommaaccent e -120
-KPX Tcommaaccent eacute -120
-KPX Tcommaaccent ecaron -120
-KPX Tcommaaccent ecircumflex -120
-KPX Tcommaaccent edieresis -120
-KPX Tcommaaccent edotaccent -120
-KPX Tcommaaccent egrave -60
-KPX Tcommaaccent emacron -60
-KPX Tcommaaccent eogonek -120
-KPX Tcommaaccent hyphen -140
-KPX Tcommaaccent o -120
-KPX Tcommaaccent oacute -120
-KPX Tcommaaccent ocircumflex -120
-KPX Tcommaaccent odieresis -120
-KPX Tcommaaccent ograve -120
-KPX Tcommaaccent ohungarumlaut -120
-KPX Tcommaaccent omacron -60
-KPX Tcommaaccent oslash -120
-KPX Tcommaaccent otilde -60
-KPX Tcommaaccent period -120
-KPX Tcommaaccent r -120
-KPX Tcommaaccent racute -120
-KPX Tcommaaccent rcaron -120
-KPX Tcommaaccent rcommaaccent -120
-KPX Tcommaaccent semicolon -20
-KPX Tcommaaccent u -120
-KPX Tcommaaccent uacute -120
-KPX Tcommaaccent ucircumflex -120
-KPX Tcommaaccent udieresis -120
-KPX Tcommaaccent ugrave -120
-KPX Tcommaaccent uhungarumlaut -120
-KPX Tcommaaccent umacron -60
-KPX Tcommaaccent uogonek -120
-KPX Tcommaaccent uring -120
-KPX Tcommaaccent w -120
-KPX Tcommaaccent y -120
-KPX Tcommaaccent yacute -120
-KPX Tcommaaccent ydieresis -60
-KPX U A -40
-KPX U Aacute -40
-KPX U Abreve -40
-KPX U Acircumflex -40
-KPX U Adieresis -40
-KPX U Agrave -40
-KPX U Amacron -40
-KPX U Aogonek -40
-KPX U Aring -40
-KPX U Atilde -40
-KPX U comma -40
-KPX U period -40
-KPX Uacute A -40
-KPX Uacute Aacute -40
-KPX Uacute Abreve -40
-KPX Uacute Acircumflex -40
-KPX Uacute Adieresis -40
-KPX Uacute Agrave -40
-KPX Uacute Amacron -40
-KPX Uacute Aogonek -40
-KPX Uacute Aring -40
-KPX Uacute Atilde -40
-KPX Uacute comma -40
-KPX Uacute period -40
-KPX Ucircumflex A -40
-KPX Ucircumflex Aacute -40
-KPX Ucircumflex Abreve -40
-KPX Ucircumflex Acircumflex -40
-KPX Ucircumflex Adieresis -40
-KPX Ucircumflex Agrave -40
-KPX Ucircumflex Amacron -40
-KPX Ucircumflex Aogonek -40
-KPX Ucircumflex Aring -40
-KPX Ucircumflex Atilde -40
-KPX Ucircumflex comma -40
-KPX Ucircumflex period -40
-KPX Udieresis A -40
-KPX Udieresis Aacute -40
-KPX Udieresis Abreve -40
-KPX Udieresis Acircumflex -40
-KPX Udieresis Adieresis -40
-KPX Udieresis Agrave -40
-KPX Udieresis Amacron -40
-KPX Udieresis Aogonek -40
-KPX Udieresis Aring -40
-KPX Udieresis Atilde -40
-KPX Udieresis comma -40
-KPX Udieresis period -40
-KPX Ugrave A -40
-KPX Ugrave Aacute -40
-KPX Ugrave Abreve -40
-KPX Ugrave Acircumflex -40
-KPX Ugrave Adieresis -40
-KPX Ugrave Agrave -40
-KPX Ugrave Amacron -40
-KPX Ugrave Aogonek -40
-KPX Ugrave Aring -40
-KPX Ugrave Atilde -40
-KPX Ugrave comma -40
-KPX Ugrave period -40
-KPX Uhungarumlaut A -40
-KPX Uhungarumlaut Aacute -40
-KPX Uhungarumlaut Abreve -40
-KPX Uhungarumlaut Acircumflex -40
-KPX Uhungarumlaut Adieresis -40
-KPX Uhungarumlaut Agrave -40
-KPX Uhungarumlaut Amacron -40
-KPX Uhungarumlaut Aogonek -40
-KPX Uhungarumlaut Aring -40
-KPX Uhungarumlaut Atilde -40
-KPX Uhungarumlaut comma -40
-KPX Uhungarumlaut period -40
-KPX Umacron A -40
-KPX Umacron Aacute -40
-KPX Umacron Abreve -40
-KPX Umacron Acircumflex -40
-KPX Umacron Adieresis -40
-KPX Umacron Agrave -40
-KPX Umacron Amacron -40
-KPX Umacron Aogonek -40
-KPX Umacron Aring -40
-KPX Umacron Atilde -40
-KPX Umacron comma -40
-KPX Umacron period -40
-KPX Uogonek A -40
-KPX Uogonek Aacute -40
-KPX Uogonek Abreve -40
-KPX Uogonek Acircumflex -40
-KPX Uogonek Adieresis -40
-KPX Uogonek Agrave -40
-KPX Uogonek Amacron -40
-KPX Uogonek Aogonek -40
-KPX Uogonek Aring -40
-KPX Uogonek Atilde -40
-KPX Uogonek comma -40
-KPX Uogonek period -40
-KPX Uring A -40
-KPX Uring Aacute -40
-KPX Uring Abreve -40
-KPX Uring Acircumflex -40
-KPX Uring Adieresis -40
-KPX Uring Agrave -40
-KPX Uring Amacron -40
-KPX Uring Aogonek -40
-KPX Uring Aring -40
-KPX Uring Atilde -40
-KPX Uring comma -40
-KPX Uring period -40
-KPX V A -80
-KPX V Aacute -80
-KPX V Abreve -80
-KPX V Acircumflex -80
-KPX V Adieresis -80
-KPX V Agrave -80
-KPX V Amacron -80
-KPX V Aogonek -80
-KPX V Aring -80
-KPX V Atilde -80
-KPX V G -40
-KPX V Gbreve -40
-KPX V Gcommaaccent -40
-KPX V O -40
-KPX V Oacute -40
-KPX V Ocircumflex -40
-KPX V Odieresis -40
-KPX V Ograve -40
-KPX V Ohungarumlaut -40
-KPX V Omacron -40
-KPX V Oslash -40
-KPX V Otilde -40
-KPX V a -70
-KPX V aacute -70
-KPX V abreve -70
-KPX V acircumflex -70
-KPX V adieresis -70
-KPX V agrave -70
-KPX V amacron -70
-KPX V aogonek -70
-KPX V aring -70
-KPX V atilde -70
-KPX V colon -40
-KPX V comma -125
-KPX V e -80
-KPX V eacute -80
-KPX V ecaron -80
-KPX V ecircumflex -80
-KPX V edieresis -80
-KPX V edotaccent -80
-KPX V egrave -80
-KPX V emacron -80
-KPX V eogonek -80
-KPX V hyphen -80
-KPX V o -80
-KPX V oacute -80
-KPX V ocircumflex -80
-KPX V odieresis -80
-KPX V ograve -80
-KPX V ohungarumlaut -80
-KPX V omacron -80
-KPX V oslash -80
-KPX V otilde -80
-KPX V period -125
-KPX V semicolon -40
-KPX V u -70
-KPX V uacute -70
-KPX V ucircumflex -70
-KPX V udieresis -70
-KPX V ugrave -70
-KPX V uhungarumlaut -70
-KPX V umacron -70
-KPX V uogonek -70
-KPX V uring -70
-KPX W A -50
-KPX W Aacute -50
-KPX W Abreve -50
-KPX W Acircumflex -50
-KPX W Adieresis -50
-KPX W Agrave -50
-KPX W Amacron -50
-KPX W Aogonek -50
-KPX W Aring -50
-KPX W Atilde -50
-KPX W O -20
-KPX W Oacute -20
-KPX W Ocircumflex -20
-KPX W Odieresis -20
-KPX W Ograve -20
-KPX W Ohungarumlaut -20
-KPX W Omacron -20
-KPX W Oslash -20
-KPX W Otilde -20
-KPX W a -40
-KPX W aacute -40
-KPX W abreve -40
-KPX W acircumflex -40
-KPX W adieresis -40
-KPX W agrave -40
-KPX W amacron -40
-KPX W aogonek -40
-KPX W aring -40
-KPX W atilde -40
-KPX W comma -80
-KPX W e -30
-KPX W eacute -30
-KPX W ecaron -30
-KPX W ecircumflex -30
-KPX W edieresis -30
-KPX W edotaccent -30
-KPX W egrave -30
-KPX W emacron -30
-KPX W eogonek -30
-KPX W hyphen -40
-KPX W o -30
-KPX W oacute -30
-KPX W ocircumflex -30
-KPX W odieresis -30
-KPX W ograve -30
-KPX W ohungarumlaut -30
-KPX W omacron -30
-KPX W oslash -30
-KPX W otilde -30
-KPX W period -80
-KPX W u -30
-KPX W uacute -30
-KPX W ucircumflex -30
-KPX W udieresis -30
-KPX W ugrave -30
-KPX W uhungarumlaut -30
-KPX W umacron -30
-KPX W uogonek -30
-KPX W uring -30
-KPX W y -20
-KPX W yacute -20
-KPX W ydieresis -20
-KPX Y A -110
-KPX Y Aacute -110
-KPX Y Abreve -110
-KPX Y Acircumflex -110
-KPX Y Adieresis -110
-KPX Y Agrave -110
-KPX Y Amacron -110
-KPX Y Aogonek -110
-KPX Y Aring -110
-KPX Y Atilde -110
-KPX Y O -85
-KPX Y Oacute -85
-KPX Y Ocircumflex -85
-KPX Y Odieresis -85
-KPX Y Ograve -85
-KPX Y Ohungarumlaut -85
-KPX Y Omacron -85
-KPX Y Oslash -85
-KPX Y Otilde -85
-KPX Y a -140
-KPX Y aacute -140
-KPX Y abreve -70
-KPX Y acircumflex -140
-KPX Y adieresis -140
-KPX Y agrave -140
-KPX Y amacron -70
-KPX Y aogonek -140
-KPX Y aring -140
-KPX Y atilde -140
-KPX Y colon -60
-KPX Y comma -140
-KPX Y e -140
-KPX Y eacute -140
-KPX Y ecaron -140
-KPX Y ecircumflex -140
-KPX Y edieresis -140
-KPX Y edotaccent -140
-KPX Y egrave -140
-KPX Y emacron -70
-KPX Y eogonek -140
-KPX Y hyphen -140
-KPX Y i -20
-KPX Y iacute -20
-KPX Y iogonek -20
-KPX Y o -140
-KPX Y oacute -140
-KPX Y ocircumflex -140
-KPX Y odieresis -140
-KPX Y ograve -140
-KPX Y ohungarumlaut -140
-KPX Y omacron -140
-KPX Y oslash -140
-KPX Y otilde -140
-KPX Y period -140
-KPX Y semicolon -60
-KPX Y u -110
-KPX Y uacute -110
-KPX Y ucircumflex -110
-KPX Y udieresis -110
-KPX Y ugrave -110
-KPX Y uhungarumlaut -110
-KPX Y umacron -110
-KPX Y uogonek -110
-KPX Y uring -110
-KPX Yacute A -110
-KPX Yacute Aacute -110
-KPX Yacute Abreve -110
-KPX Yacute Acircumflex -110
-KPX Yacute Adieresis -110
-KPX Yacute Agrave -110
-KPX Yacute Amacron -110
-KPX Yacute Aogonek -110
-KPX Yacute Aring -110
-KPX Yacute Atilde -110
-KPX Yacute O -85
-KPX Yacute Oacute -85
-KPX Yacute Ocircumflex -85
-KPX Yacute Odieresis -85
-KPX Yacute Ograve -85
-KPX Yacute Ohungarumlaut -85
-KPX Yacute Omacron -85
-KPX Yacute Oslash -85
-KPX Yacute Otilde -85
-KPX Yacute a -140
-KPX Yacute aacute -140
-KPX Yacute abreve -70
-KPX Yacute acircumflex -140
-KPX Yacute adieresis -140
-KPX Yacute agrave -140
-KPX Yacute amacron -70
-KPX Yacute aogonek -140
-KPX Yacute aring -140
-KPX Yacute atilde -70
-KPX Yacute colon -60
-KPX Yacute comma -140
-KPX Yacute e -140
-KPX Yacute eacute -140
-KPX Yacute ecaron -140
-KPX Yacute ecircumflex -140
-KPX Yacute edieresis -140
-KPX Yacute edotaccent -140
-KPX Yacute egrave -140
-KPX Yacute emacron -70
-KPX Yacute eogonek -140
-KPX Yacute hyphen -140
-KPX Yacute i -20
-KPX Yacute iacute -20
-KPX Yacute iogonek -20
-KPX Yacute o -140
-KPX Yacute oacute -140
-KPX Yacute ocircumflex -140
-KPX Yacute odieresis -140
-KPX Yacute ograve -140
-KPX Yacute ohungarumlaut -140
-KPX Yacute omacron -70
-KPX Yacute oslash -140
-KPX Yacute otilde -140
-KPX Yacute period -140
-KPX Yacute semicolon -60
-KPX Yacute u -110
-KPX Yacute uacute -110
-KPX Yacute ucircumflex -110
-KPX Yacute udieresis -110
-KPX Yacute ugrave -110
-KPX Yacute uhungarumlaut -110
-KPX Yacute umacron -110
-KPX Yacute uogonek -110
-KPX Yacute uring -110
-KPX Ydieresis A -110
-KPX Ydieresis Aacute -110
-KPX Ydieresis Abreve -110
-KPX Ydieresis Acircumflex -110
-KPX Ydieresis Adieresis -110
-KPX Ydieresis Agrave -110
-KPX Ydieresis Amacron -110
-KPX Ydieresis Aogonek -110
-KPX Ydieresis Aring -110
-KPX Ydieresis Atilde -110
-KPX Ydieresis O -85
-KPX Ydieresis Oacute -85
-KPX Ydieresis Ocircumflex -85
-KPX Ydieresis Odieresis -85
-KPX Ydieresis Ograve -85
-KPX Ydieresis Ohungarumlaut -85
-KPX Ydieresis Omacron -85
-KPX Ydieresis Oslash -85
-KPX Ydieresis Otilde -85
-KPX Ydieresis a -140
-KPX Ydieresis aacute -140
-KPX Ydieresis abreve -70
-KPX Ydieresis acircumflex -140
-KPX Ydieresis adieresis -140
-KPX Ydieresis agrave -140
-KPX Ydieresis amacron -70
-KPX Ydieresis aogonek -140
-KPX Ydieresis aring -140
-KPX Ydieresis atilde -70
-KPX Ydieresis colon -60
-KPX Ydieresis comma -140
-KPX Ydieresis e -140
-KPX Ydieresis eacute -140
-KPX Ydieresis ecaron -140
-KPX Ydieresis ecircumflex -140
-KPX Ydieresis edieresis -140
-KPX Ydieresis edotaccent -140
-KPX Ydieresis egrave -140
-KPX Ydieresis emacron -70
-KPX Ydieresis eogonek -140
-KPX Ydieresis hyphen -140
-KPX Ydieresis i -20
-KPX Ydieresis iacute -20
-KPX Ydieresis iogonek -20
-KPX Ydieresis o -140
-KPX Ydieresis oacute -140
-KPX Ydieresis ocircumflex -140
-KPX Ydieresis odieresis -140
-KPX Ydieresis ograve -140
-KPX Ydieresis ohungarumlaut -140
-KPX Ydieresis omacron -140
-KPX Ydieresis oslash -140
-KPX Ydieresis otilde -140
-KPX Ydieresis period -140
-KPX Ydieresis semicolon -60
-KPX Ydieresis u -110
-KPX Ydieresis uacute -110
-KPX Ydieresis ucircumflex -110
-KPX Ydieresis udieresis -110
-KPX Ydieresis ugrave -110
-KPX Ydieresis uhungarumlaut -110
-KPX Ydieresis umacron -110
-KPX Ydieresis uogonek -110
-KPX Ydieresis uring -110
-KPX a v -20
-KPX a w -20
-KPX a y -30
-KPX a yacute -30
-KPX a ydieresis -30
-KPX aacute v -20
-KPX aacute w -20
-KPX aacute y -30
-KPX aacute yacute -30
-KPX aacute ydieresis -30
-KPX abreve v -20
-KPX abreve w -20
-KPX abreve y -30
-KPX abreve yacute -30
-KPX abreve ydieresis -30
-KPX acircumflex v -20
-KPX acircumflex w -20
-KPX acircumflex y -30
-KPX acircumflex yacute -30
-KPX acircumflex ydieresis -30
-KPX adieresis v -20
-KPX adieresis w -20
-KPX adieresis y -30
-KPX adieresis yacute -30
-KPX adieresis ydieresis -30
-KPX agrave v -20
-KPX agrave w -20
-KPX agrave y -30
-KPX agrave yacute -30
-KPX agrave ydieresis -30
-KPX amacron v -20
-KPX amacron w -20
-KPX amacron y -30
-KPX amacron yacute -30
-KPX amacron ydieresis -30
-KPX aogonek v -20
-KPX aogonek w -20
-KPX aogonek y -30
-KPX aogonek yacute -30
-KPX aogonek ydieresis -30
-KPX aring v -20
-KPX aring w -20
-KPX aring y -30
-KPX aring yacute -30
-KPX aring ydieresis -30
-KPX atilde v -20
-KPX atilde w -20
-KPX atilde y -30
-KPX atilde yacute -30
-KPX atilde ydieresis -30
-KPX b b -10
-KPX b comma -40
-KPX b l -20
-KPX b lacute -20
-KPX b lcommaaccent -20
-KPX b lslash -20
-KPX b period -40
-KPX b u -20
-KPX b uacute -20
-KPX b ucircumflex -20
-KPX b udieresis -20
-KPX b ugrave -20
-KPX b uhungarumlaut -20
-KPX b umacron -20
-KPX b uogonek -20
-KPX b uring -20
-KPX b v -20
-KPX b y -20
-KPX b yacute -20
-KPX b ydieresis -20
-KPX c comma -15
-KPX c k -20
-KPX c kcommaaccent -20
-KPX cacute comma -15
-KPX cacute k -20
-KPX cacute kcommaaccent -20
-KPX ccaron comma -15
-KPX ccaron k -20
-KPX ccaron kcommaaccent -20
-KPX ccedilla comma -15
-KPX ccedilla k -20
-KPX ccedilla kcommaaccent -20
-KPX colon space -50
-KPX comma quotedblright -100
-KPX comma quoteright -100
-KPX e comma -15
-KPX e period -15
-KPX e v -30
-KPX e w -20
-KPX e x -30
-KPX e y -20
-KPX e yacute -20
-KPX e ydieresis -20
-KPX eacute comma -15
-KPX eacute period -15
-KPX eacute v -30
-KPX eacute w -20
-KPX eacute x -30
-KPX eacute y -20
-KPX eacute yacute -20
-KPX eacute ydieresis -20
-KPX ecaron comma -15
-KPX ecaron period -15
-KPX ecaron v -30
-KPX ecaron w -20
-KPX ecaron x -30
-KPX ecaron y -20
-KPX ecaron yacute -20
-KPX ecaron ydieresis -20
-KPX ecircumflex comma -15
-KPX ecircumflex period -15
-KPX ecircumflex v -30
-KPX ecircumflex w -20
-KPX ecircumflex x -30
-KPX ecircumflex y -20
-KPX ecircumflex yacute -20
-KPX ecircumflex ydieresis -20
-KPX edieresis comma -15
-KPX edieresis period -15
-KPX edieresis v -30
-KPX edieresis w -20
-KPX edieresis x -30
-KPX edieresis y -20
-KPX edieresis yacute -20
-KPX edieresis ydieresis -20
-KPX edotaccent comma -15
-KPX edotaccent period -15
-KPX edotaccent v -30
-KPX edotaccent w -20
-KPX edotaccent x -30
-KPX edotaccent y -20
-KPX edotaccent yacute -20
-KPX edotaccent ydieresis -20
-KPX egrave comma -15
-KPX egrave period -15
-KPX egrave v -30
-KPX egrave w -20
-KPX egrave x -30
-KPX egrave y -20
-KPX egrave yacute -20
-KPX egrave ydieresis -20
-KPX emacron comma -15
-KPX emacron period -15
-KPX emacron v -30
-KPX emacron w -20
-KPX emacron x -30
-KPX emacron y -20
-KPX emacron yacute -20
-KPX emacron ydieresis -20
-KPX eogonek comma -15
-KPX eogonek period -15
-KPX eogonek v -30
-KPX eogonek w -20
-KPX eogonek x -30
-KPX eogonek y -20
-KPX eogonek yacute -20
-KPX eogonek ydieresis -20
-KPX f a -30
-KPX f aacute -30
-KPX f abreve -30
-KPX f acircumflex -30
-KPX f adieresis -30
-KPX f agrave -30
-KPX f amacron -30
-KPX f aogonek -30
-KPX f aring -30
-KPX f atilde -30
-KPX f comma -30
-KPX f dotlessi -28
-KPX f e -30
-KPX f eacute -30
-KPX f ecaron -30
-KPX f ecircumflex -30
-KPX f edieresis -30
-KPX f edotaccent -30
-KPX f egrave -30
-KPX f emacron -30
-KPX f eogonek -30
-KPX f o -30
-KPX f oacute -30
-KPX f ocircumflex -30
-KPX f odieresis -30
-KPX f ograve -30
-KPX f ohungarumlaut -30
-KPX f omacron -30
-KPX f oslash -30
-KPX f otilde -30
-KPX f period -30
-KPX f quotedblright 60
-KPX f quoteright 50
-KPX g r -10
-KPX g racute -10
-KPX g rcaron -10
-KPX g rcommaaccent -10
-KPX gbreve r -10
-KPX gbreve racute -10
-KPX gbreve rcaron -10
-KPX gbreve rcommaaccent -10
-KPX gcommaaccent r -10
-KPX gcommaaccent racute -10
-KPX gcommaaccent rcaron -10
-KPX gcommaaccent rcommaaccent -10
-KPX h y -30
-KPX h yacute -30
-KPX h ydieresis -30
-KPX k e -20
-KPX k eacute -20
-KPX k ecaron -20
-KPX k ecircumflex -20
-KPX k edieresis -20
-KPX k edotaccent -20
-KPX k egrave -20
-KPX k emacron -20
-KPX k eogonek -20
-KPX k o -20
-KPX k oacute -20
-KPX k ocircumflex -20
-KPX k odieresis -20
-KPX k ograve -20
-KPX k ohungarumlaut -20
-KPX k omacron -20
-KPX k oslash -20
-KPX k otilde -20
-KPX kcommaaccent e -20
-KPX kcommaaccent eacute -20
-KPX kcommaaccent ecaron -20
-KPX kcommaaccent ecircumflex -20
-KPX kcommaaccent edieresis -20
-KPX kcommaaccent edotaccent -20
-KPX kcommaaccent egrave -20
-KPX kcommaaccent emacron -20
-KPX kcommaaccent eogonek -20
-KPX kcommaaccent o -20
-KPX kcommaaccent oacute -20
-KPX kcommaaccent ocircumflex -20
-KPX kcommaaccent odieresis -20
-KPX kcommaaccent ograve -20
-KPX kcommaaccent ohungarumlaut -20
-KPX kcommaaccent omacron -20
-KPX kcommaaccent oslash -20
-KPX kcommaaccent otilde -20
-KPX m u -10
-KPX m uacute -10
-KPX m ucircumflex -10
-KPX m udieresis -10
-KPX m ugrave -10
-KPX m uhungarumlaut -10
-KPX m umacron -10
-KPX m uogonek -10
-KPX m uring -10
-KPX m y -15
-KPX m yacute -15
-KPX m ydieresis -15
-KPX n u -10
-KPX n uacute -10
-KPX n ucircumflex -10
-KPX n udieresis -10
-KPX n ugrave -10
-KPX n uhungarumlaut -10
-KPX n umacron -10
-KPX n uogonek -10
-KPX n uring -10
-KPX n v -20
-KPX n y -15
-KPX n yacute -15
-KPX n ydieresis -15
-KPX nacute u -10
-KPX nacute uacute -10
-KPX nacute ucircumflex -10
-KPX nacute udieresis -10
-KPX nacute ugrave -10
-KPX nacute uhungarumlaut -10
-KPX nacute umacron -10
-KPX nacute uogonek -10
-KPX nacute uring -10
-KPX nacute v -20
-KPX nacute y -15
-KPX nacute yacute -15
-KPX nacute ydieresis -15
-KPX ncaron u -10
-KPX ncaron uacute -10
-KPX ncaron ucircumflex -10
-KPX ncaron udieresis -10
-KPX ncaron ugrave -10
-KPX ncaron uhungarumlaut -10
-KPX ncaron umacron -10
-KPX ncaron uogonek -10
-KPX ncaron uring -10
-KPX ncaron v -20
-KPX ncaron y -15
-KPX ncaron yacute -15
-KPX ncaron ydieresis -15
-KPX ncommaaccent u -10
-KPX ncommaaccent uacute -10
-KPX ncommaaccent ucircumflex -10
-KPX ncommaaccent udieresis -10
-KPX ncommaaccent ugrave -10
-KPX ncommaaccent uhungarumlaut -10
-KPX ncommaaccent umacron -10
-KPX ncommaaccent uogonek -10
-KPX ncommaaccent uring -10
-KPX ncommaaccent v -20
-KPX ncommaaccent y -15
-KPX ncommaaccent yacute -15
-KPX ncommaaccent ydieresis -15
-KPX ntilde u -10
-KPX ntilde uacute -10
-KPX ntilde ucircumflex -10
-KPX ntilde udieresis -10
-KPX ntilde ugrave -10
-KPX ntilde uhungarumlaut -10
-KPX ntilde umacron -10
-KPX ntilde uogonek -10
-KPX ntilde uring -10
-KPX ntilde v -20
-KPX ntilde y -15
-KPX ntilde yacute -15
-KPX ntilde ydieresis -15
-KPX o comma -40
-KPX o period -40
-KPX o v -15
-KPX o w -15
-KPX o x -30
-KPX o y -30
-KPX o yacute -30
-KPX o ydieresis -30
-KPX oacute comma -40
-KPX oacute period -40
-KPX oacute v -15
-KPX oacute w -15
-KPX oacute x -30
-KPX oacute y -30
-KPX oacute yacute -30
-KPX oacute ydieresis -30
-KPX ocircumflex comma -40
-KPX ocircumflex period -40
-KPX ocircumflex v -15
-KPX ocircumflex w -15
-KPX ocircumflex x -30
-KPX ocircumflex y -30
-KPX ocircumflex yacute -30
-KPX ocircumflex ydieresis -30
-KPX odieresis comma -40
-KPX odieresis period -40
-KPX odieresis v -15
-KPX odieresis w -15
-KPX odieresis x -30
-KPX odieresis y -30
-KPX odieresis yacute -30
-KPX odieresis ydieresis -30
-KPX ograve comma -40
-KPX ograve period -40
-KPX ograve v -15
-KPX ograve w -15
-KPX ograve x -30
-KPX ograve y -30
-KPX ograve yacute -30
-KPX ograve ydieresis -30
-KPX ohungarumlaut comma -40
-KPX ohungarumlaut period -40
-KPX ohungarumlaut v -15
-KPX ohungarumlaut w -15
-KPX ohungarumlaut x -30
-KPX ohungarumlaut y -30
-KPX ohungarumlaut yacute -30
-KPX ohungarumlaut ydieresis -30
-KPX omacron comma -40
-KPX omacron period -40
-KPX omacron v -15
-KPX omacron w -15
-KPX omacron x -30
-KPX omacron y -30
-KPX omacron yacute -30
-KPX omacron ydieresis -30
-KPX oslash a -55
-KPX oslash aacute -55
-KPX oslash abreve -55
-KPX oslash acircumflex -55
-KPX oslash adieresis -55
-KPX oslash agrave -55
-KPX oslash amacron -55
-KPX oslash aogonek -55
-KPX oslash aring -55
-KPX oslash atilde -55
-KPX oslash b -55
-KPX oslash c -55
-KPX oslash cacute -55
-KPX oslash ccaron -55
-KPX oslash ccedilla -55
-KPX oslash comma -95
-KPX oslash d -55
-KPX oslash dcroat -55
-KPX oslash e -55
-KPX oslash eacute -55
-KPX oslash ecaron -55
-KPX oslash ecircumflex -55
-KPX oslash edieresis -55
-KPX oslash edotaccent -55
-KPX oslash egrave -55
-KPX oslash emacron -55
-KPX oslash eogonek -55
-KPX oslash f -55
-KPX oslash g -55
-KPX oslash gbreve -55
-KPX oslash gcommaaccent -55
-KPX oslash h -55
-KPX oslash i -55
-KPX oslash iacute -55
-KPX oslash icircumflex -55
-KPX oslash idieresis -55
-KPX oslash igrave -55
-KPX oslash imacron -55
-KPX oslash iogonek -55
-KPX oslash j -55
-KPX oslash k -55
-KPX oslash kcommaaccent -55
-KPX oslash l -55
-KPX oslash lacute -55
-KPX oslash lcommaaccent -55
-KPX oslash lslash -55
-KPX oslash m -55
-KPX oslash n -55
-KPX oslash nacute -55
-KPX oslash ncaron -55
-KPX oslash ncommaaccent -55
-KPX oslash ntilde -55
-KPX oslash o -55
-KPX oslash oacute -55
-KPX oslash ocircumflex -55
-KPX oslash odieresis -55
-KPX oslash ograve -55
-KPX oslash ohungarumlaut -55
-KPX oslash omacron -55
-KPX oslash oslash -55
-KPX oslash otilde -55
-KPX oslash p -55
-KPX oslash period -95
-KPX oslash q -55
-KPX oslash r -55
-KPX oslash racute -55
-KPX oslash rcaron -55
-KPX oslash rcommaaccent -55
-KPX oslash s -55
-KPX oslash sacute -55
-KPX oslash scaron -55
-KPX oslash scedilla -55
-KPX oslash scommaaccent -55
-KPX oslash t -55
-KPX oslash tcommaaccent -55
-KPX oslash u -55
-KPX oslash uacute -55
-KPX oslash ucircumflex -55
-KPX oslash udieresis -55
-KPX oslash ugrave -55
-KPX oslash uhungarumlaut -55
-KPX oslash umacron -55
-KPX oslash uogonek -55
-KPX oslash uring -55
-KPX oslash v -70
-KPX oslash w -70
-KPX oslash x -85
-KPX oslash y -70
-KPX oslash yacute -70
-KPX oslash ydieresis -70
-KPX oslash z -55
-KPX oslash zacute -55
-KPX oslash zcaron -55
-KPX oslash zdotaccent -55
-KPX otilde comma -40
-KPX otilde period -40
-KPX otilde v -15
-KPX otilde w -15
-KPX otilde x -30
-KPX otilde y -30
-KPX otilde yacute -30
-KPX otilde ydieresis -30
-KPX p comma -35
-KPX p period -35
-KPX p y -30
-KPX p yacute -30
-KPX p ydieresis -30
-KPX period quotedblright -100
-KPX period quoteright -100
-KPX period space -60
-KPX quotedblright space -40
-KPX quoteleft quoteleft -57
-KPX quoteright d -50
-KPX quoteright dcroat -50
-KPX quoteright quoteright -57
-KPX quoteright r -50
-KPX quoteright racute -50
-KPX quoteright rcaron -50
-KPX quoteright rcommaaccent -50
-KPX quoteright s -50
-KPX quoteright sacute -50
-KPX quoteright scaron -50
-KPX quoteright scedilla -50
-KPX quoteright scommaaccent -50
-KPX quoteright space -70
-KPX r a -10
-KPX r aacute -10
-KPX r abreve -10
-KPX r acircumflex -10
-KPX r adieresis -10
-KPX r agrave -10
-KPX r amacron -10
-KPX r aogonek -10
-KPX r aring -10
-KPX r atilde -10
-KPX r colon 30
-KPX r comma -50
-KPX r i 15
-KPX r iacute 15
-KPX r icircumflex 15
-KPX r idieresis 15
-KPX r igrave 15
-KPX r imacron 15
-KPX r iogonek 15
-KPX r k 15
-KPX r kcommaaccent 15
-KPX r l 15
-KPX r lacute 15
-KPX r lcommaaccent 15
-KPX r lslash 15
-KPX r m 25
-KPX r n 25
-KPX r nacute 25
-KPX r ncaron 25
-KPX r ncommaaccent 25
-KPX r ntilde 25
-KPX r p 30
-KPX r period -50
-KPX r semicolon 30
-KPX r t 40
-KPX r tcommaaccent 40
-KPX r u 15
-KPX r uacute 15
-KPX r ucircumflex 15
-KPX r udieresis 15
-KPX r ugrave 15
-KPX r uhungarumlaut 15
-KPX r umacron 15
-KPX r uogonek 15
-KPX r uring 15
-KPX r v 30
-KPX r y 30
-KPX r yacute 30
-KPX r ydieresis 30
-KPX racute a -10
-KPX racute aacute -10
-KPX racute abreve -10
-KPX racute acircumflex -10
-KPX racute adieresis -10
-KPX racute agrave -10
-KPX racute amacron -10
-KPX racute aogonek -10
-KPX racute aring -10
-KPX racute atilde -10
-KPX racute colon 30
-KPX racute comma -50
-KPX racute i 15
-KPX racute iacute 15
-KPX racute icircumflex 15
-KPX racute idieresis 15
-KPX racute igrave 15
-KPX racute imacron 15
-KPX racute iogonek 15
-KPX racute k 15
-KPX racute kcommaaccent 15
-KPX racute l 15
-KPX racute lacute 15
-KPX racute lcommaaccent 15
-KPX racute lslash 15
-KPX racute m 25
-KPX racute n 25
-KPX racute nacute 25
-KPX racute ncaron 25
-KPX racute ncommaaccent 25
-KPX racute ntilde 25
-KPX racute p 30
-KPX racute period -50
-KPX racute semicolon 30
-KPX racute t 40
-KPX racute tcommaaccent 40
-KPX racute u 15
-KPX racute uacute 15
-KPX racute ucircumflex 15
-KPX racute udieresis 15
-KPX racute ugrave 15
-KPX racute uhungarumlaut 15
-KPX racute umacron 15
-KPX racute uogonek 15
-KPX racute uring 15
-KPX racute v 30
-KPX racute y 30
-KPX racute yacute 30
-KPX racute ydieresis 30
-KPX rcaron a -10
-KPX rcaron aacute -10
-KPX rcaron abreve -10
-KPX rcaron acircumflex -10
-KPX rcaron adieresis -10
-KPX rcaron agrave -10
-KPX rcaron amacron -10
-KPX rcaron aogonek -10
-KPX rcaron aring -10
-KPX rcaron atilde -10
-KPX rcaron colon 30
-KPX rcaron comma -50
-KPX rcaron i 15
-KPX rcaron iacute 15
-KPX rcaron icircumflex 15
-KPX rcaron idieresis 15
-KPX rcaron igrave 15
-KPX rcaron imacron 15
-KPX rcaron iogonek 15
-KPX rcaron k 15
-KPX rcaron kcommaaccent 15
-KPX rcaron l 15
-KPX rcaron lacute 15
-KPX rcaron lcommaaccent 15
-KPX rcaron lslash 15
-KPX rcaron m 25
-KPX rcaron n 25
-KPX rcaron nacute 25
-KPX rcaron ncaron 25
-KPX rcaron ncommaaccent 25
-KPX rcaron ntilde 25
-KPX rcaron p 30
-KPX rcaron period -50
-KPX rcaron semicolon 30
-KPX rcaron t 40
-KPX rcaron tcommaaccent 40
-KPX rcaron u 15
-KPX rcaron uacute 15
-KPX rcaron ucircumflex 15
-KPX rcaron udieresis 15
-KPX rcaron ugrave 15
-KPX rcaron uhungarumlaut 15
-KPX rcaron umacron 15
-KPX rcaron uogonek 15
-KPX rcaron uring 15
-KPX rcaron v 30
-KPX rcaron y 30
-KPX rcaron yacute 30
-KPX rcaron ydieresis 30
-KPX rcommaaccent a -10
-KPX rcommaaccent aacute -10
-KPX rcommaaccent abreve -10
-KPX rcommaaccent acircumflex -10
-KPX rcommaaccent adieresis -10
-KPX rcommaaccent agrave -10
-KPX rcommaaccent amacron -10
-KPX rcommaaccent aogonek -10
-KPX rcommaaccent aring -10
-KPX rcommaaccent atilde -10
-KPX rcommaaccent colon 30
-KPX rcommaaccent comma -50
-KPX rcommaaccent i 15
-KPX rcommaaccent iacute 15
-KPX rcommaaccent icircumflex 15
-KPX rcommaaccent idieresis 15
-KPX rcommaaccent igrave 15
-KPX rcommaaccent imacron 15
-KPX rcommaaccent iogonek 15
-KPX rcommaaccent k 15
-KPX rcommaaccent kcommaaccent 15
-KPX rcommaaccent l 15
-KPX rcommaaccent lacute 15
-KPX rcommaaccent lcommaaccent 15
-KPX rcommaaccent lslash 15
-KPX rcommaaccent m 25
-KPX rcommaaccent n 25
-KPX rcommaaccent nacute 25
-KPX rcommaaccent ncaron 25
-KPX rcommaaccent ncommaaccent 25
-KPX rcommaaccent ntilde 25
-KPX rcommaaccent p 30
-KPX rcommaaccent period -50
-KPX rcommaaccent semicolon 30
-KPX rcommaaccent t 40
-KPX rcommaaccent tcommaaccent 40
-KPX rcommaaccent u 15
-KPX rcommaaccent uacute 15
-KPX rcommaaccent ucircumflex 15
-KPX rcommaaccent udieresis 15
-KPX rcommaaccent ugrave 15
-KPX rcommaaccent uhungarumlaut 15
-KPX rcommaaccent umacron 15
-KPX rcommaaccent uogonek 15
-KPX rcommaaccent uring 15
-KPX rcommaaccent v 30
-KPX rcommaaccent y 30
-KPX rcommaaccent yacute 30
-KPX rcommaaccent ydieresis 30
-KPX s comma -15
-KPX s period -15
-KPX s w -30
-KPX sacute comma -15
-KPX sacute period -15
-KPX sacute w -30
-KPX scaron comma -15
-KPX scaron period -15
-KPX scaron w -30
-KPX scedilla comma -15
-KPX scedilla period -15
-KPX scedilla w -30
-KPX scommaaccent comma -15
-KPX scommaaccent period -15
-KPX scommaaccent w -30
-KPX semicolon space -50
-KPX space T -50
-KPX space Tcaron -50
-KPX space Tcommaaccent -50
-KPX space V -50
-KPX space W -40
-KPX space Y -90
-KPX space Yacute -90
-KPX space Ydieresis -90
-KPX space quotedblleft -30
-KPX space quoteleft -60
-KPX v a -25
-KPX v aacute -25
-KPX v abreve -25
-KPX v acircumflex -25
-KPX v adieresis -25
-KPX v agrave -25
-KPX v amacron -25
-KPX v aogonek -25
-KPX v aring -25
-KPX v atilde -25
-KPX v comma -80
-KPX v e -25
-KPX v eacute -25
-KPX v ecaron -25
-KPX v ecircumflex -25
-KPX v edieresis -25
-KPX v edotaccent -25
-KPX v egrave -25
-KPX v emacron -25
-KPX v eogonek -25
-KPX v o -25
-KPX v oacute -25
-KPX v ocircumflex -25
-KPX v odieresis -25
-KPX v ograve -25
-KPX v ohungarumlaut -25
-KPX v omacron -25
-KPX v oslash -25
-KPX v otilde -25
-KPX v period -80
-KPX w a -15
-KPX w aacute -15
-KPX w abreve -15
-KPX w acircumflex -15
-KPX w adieresis -15
-KPX w agrave -15
-KPX w amacron -15
-KPX w aogonek -15
-KPX w aring -15
-KPX w atilde -15
-KPX w comma -60
-KPX w e -10
-KPX w eacute -10
-KPX w ecaron -10
-KPX w ecircumflex -10
-KPX w edieresis -10
-KPX w edotaccent -10
-KPX w egrave -10
-KPX w emacron -10
-KPX w eogonek -10
-KPX w o -10
-KPX w oacute -10
-KPX w ocircumflex -10
-KPX w odieresis -10
-KPX w ograve -10
-KPX w ohungarumlaut -10
-KPX w omacron -10
-KPX w oslash -10
-KPX w otilde -10
-KPX w period -60
-KPX x e -30
-KPX x eacute -30
-KPX x ecaron -30
-KPX x ecircumflex -30
-KPX x edieresis -30
-KPX x edotaccent -30
-KPX x egrave -30
-KPX x emacron -30
-KPX x eogonek -30
-KPX y a -20
-KPX y aacute -20
-KPX y abreve -20
-KPX y acircumflex -20
-KPX y adieresis -20
-KPX y agrave -20
-KPX y amacron -20
-KPX y aogonek -20
-KPX y aring -20
-KPX y atilde -20
-KPX y comma -100
-KPX y e -20
-KPX y eacute -20
-KPX y ecaron -20
-KPX y ecircumflex -20
-KPX y edieresis -20
-KPX y edotaccent -20
-KPX y egrave -20
-KPX y emacron -20
-KPX y eogonek -20
-KPX y o -20
-KPX y oacute -20
-KPX y ocircumflex -20
-KPX y odieresis -20
-KPX y ograve -20
-KPX y ohungarumlaut -20
-KPX y omacron -20
-KPX y oslash -20
-KPX y otilde -20
-KPX y period -100
-KPX yacute a -20
-KPX yacute aacute -20
-KPX yacute abreve -20
-KPX yacute acircumflex -20
-KPX yacute adieresis -20
-KPX yacute agrave -20
-KPX yacute amacron -20
-KPX yacute aogonek -20
-KPX yacute aring -20
-KPX yacute atilde -20
-KPX yacute comma -100
-KPX yacute e -20
-KPX yacute eacute -20
-KPX yacute ecaron -20
-KPX yacute ecircumflex -20
-KPX yacute edieresis -20
-KPX yacute edotaccent -20
-KPX yacute egrave -20
-KPX yacute emacron -20
-KPX yacute eogonek -20
-KPX yacute o -20
-KPX yacute oacute -20
-KPX yacute ocircumflex -20
-KPX yacute odieresis -20
-KPX yacute ograve -20
-KPX yacute ohungarumlaut -20
-KPX yacute omacron -20
-KPX yacute oslash -20
-KPX yacute otilde -20
-KPX yacute period -100
-KPX ydieresis a -20
-KPX ydieresis aacute -20
-KPX ydieresis abreve -20
-KPX ydieresis acircumflex -20
-KPX ydieresis adieresis -20
-KPX ydieresis agrave -20
-KPX ydieresis amacron -20
-KPX ydieresis aogonek -20
-KPX ydieresis aring -20
-KPX ydieresis atilde -20
-KPX ydieresis comma -100
-KPX ydieresis e -20
-KPX ydieresis eacute -20
-KPX ydieresis ecaron -20
-KPX ydieresis ecircumflex -20
-KPX ydieresis edieresis -20
-KPX ydieresis edotaccent -20
-KPX ydieresis egrave -20
-KPX ydieresis emacron -20
-KPX ydieresis eogonek -20
-KPX ydieresis o -20
-KPX ydieresis oacute -20
-KPX ydieresis ocircumflex -20
-KPX ydieresis odieresis -20
-KPX ydieresis ograve -20
-KPX ydieresis ohungarumlaut -20
-KPX ydieresis omacron -20
-KPX ydieresis oslash -20
-KPX ydieresis otilde -20
-KPX ydieresis period -100
-KPX z e -15
-KPX z eacute -15
-KPX z ecaron -15
-KPX z ecircumflex -15
-KPX z edieresis -15
-KPX z edotaccent -15
-KPX z egrave -15
-KPX z emacron -15
-KPX z eogonek -15
-KPX z o -15
-KPX z oacute -15
-KPX z ocircumflex -15
-KPX z odieresis -15
-KPX z ograve -15
-KPX z ohungarumlaut -15
-KPX z omacron -15
-KPX z oslash -15
-KPX z otilde -15
-KPX zacute e -15
-KPX zacute eacute -15
-KPX zacute ecaron -15
-KPX zacute ecircumflex -15
-KPX zacute edieresis -15
-KPX zacute edotaccent -15
-KPX zacute egrave -15
-KPX zacute emacron -15
-KPX zacute eogonek -15
-KPX zacute o -15
-KPX zacute oacute -15
-KPX zacute ocircumflex -15
-KPX zacute odieresis -15
-KPX zacute ograve -15
-KPX zacute ohungarumlaut -15
-KPX zacute omacron -15
-KPX zacute oslash -15
-KPX zacute otilde -15
-KPX zcaron e -15
-KPX zcaron eacute -15
-KPX zcaron ecaron -15
-KPX zcaron ecircumflex -15
-KPX zcaron edieresis -15
-KPX zcaron edotaccent -15
-KPX zcaron egrave -15
-KPX zcaron emacron -15
-KPX zcaron eogonek -15
-KPX zcaron o -15
-KPX zcaron oacute -15
-KPX zcaron ocircumflex -15
-KPX zcaron odieresis -15
-KPX zcaron ograve -15
-KPX zcaron ohungarumlaut -15
-KPX zcaron omacron -15
-KPX zcaron oslash -15
-KPX zcaron otilde -15
-KPX zdotaccent e -15
-KPX zdotaccent eacute -15
-KPX zdotaccent ecaron -15
-KPX zdotaccent ecircumflex -15
-KPX zdotaccent edieresis -15
-KPX zdotaccent edotaccent -15
-KPX zdotaccent egrave -15
-KPX zdotaccent emacron -15
-KPX zdotaccent eogonek -15
-KPX zdotaccent o -15
-KPX zdotaccent oacute -15
-KPX zdotaccent ocircumflex -15
-KPX zdotaccent odieresis -15
-KPX zdotaccent ograve -15
-KPX zdotaccent ohungarumlaut -15
-KPX zdotaccent omacron -15
-KPX zdotaccent oslash -15
-KPX zdotaccent otilde -15
-EndKernPairs
-EndKernData
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica.afm
deleted file mode 100644
index bd32af54de..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica.afm
+++ /dev/null
@@ -1,3051 +0,0 @@
-StartFontMetrics 4.1
-Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Thu May 1 12:38:23 1997
-Comment UniqueID 43054
-Comment VMusage 37069 48094
-FontName Helvetica
-FullName Helvetica
-FamilyName Helvetica
-Weight Medium
-ItalicAngle 0
-IsFixedPitch false
-CharacterSet ExtendedRoman
-FontBBox -166 -225 1000 931
-UnderlinePosition -100
-UnderlineThickness 50
-Version 002.000
-Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All Rights Reserved.Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 718
-XHeight 523
-Ascender 718
-Descender -207
-StdHW 76
-StdVW 88
-StartCharMetrics 315
-C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 278 ; N exclam ; B 90 0 187 718 ;
-C 34 ; WX 355 ; N quotedbl ; B 70 463 285 718 ;
-C 35 ; WX 556 ; N numbersign ; B 28 0 529 688 ;
-C 36 ; WX 556 ; N dollar ; B 32 -115 520 775 ;
-C 37 ; WX 889 ; N percent ; B 39 -19 850 703 ;
-C 38 ; WX 667 ; N ampersand ; B 44 -15 645 718 ;
-C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ;
-C 40 ; WX 333 ; N parenleft ; B 68 -207 299 733 ;
-C 41 ; WX 333 ; N parenright ; B 34 -207 265 733 ;
-C 42 ; WX 389 ; N asterisk ; B 39 431 349 718 ;
-C 43 ; WX 584 ; N plus ; B 39 0 545 505 ;
-C 44 ; WX 278 ; N comma ; B 87 -147 191 106 ;
-C 45 ; WX 333 ; N hyphen ; B 44 232 289 322 ;
-C 46 ; WX 278 ; N period ; B 87 0 191 106 ;
-C 47 ; WX 278 ; N slash ; B -17 -19 295 737 ;
-C 48 ; WX 556 ; N zero ; B 37 -19 519 703 ;
-C 49 ; WX 556 ; N one ; B 101 0 359 703 ;
-C 50 ; WX 556 ; N two ; B 26 0 507 703 ;
-C 51 ; WX 556 ; N three ; B 34 -19 522 703 ;
-C 52 ; WX 556 ; N four ; B 25 0 523 703 ;
-C 53 ; WX 556 ; N five ; B 32 -19 514 688 ;
-C 54 ; WX 556 ; N six ; B 38 -19 518 703 ;
-C 55 ; WX 556 ; N seven ; B 37 0 523 688 ;
-C 56 ; WX 556 ; N eight ; B 38 -19 517 703 ;
-C 57 ; WX 556 ; N nine ; B 42 -19 514 703 ;
-C 58 ; WX 278 ; N colon ; B 87 0 191 516 ;
-C 59 ; WX 278 ; N semicolon ; B 87 -147 191 516 ;
-C 60 ; WX 584 ; N less ; B 48 11 536 495 ;
-C 61 ; WX 584 ; N equal ; B 39 115 545 390 ;
-C 62 ; WX 584 ; N greater ; B 48 11 536 495 ;
-C 63 ; WX 556 ; N question ; B 56 0 492 727 ;
-C 64 ; WX 1015 ; N at ; B 147 -19 868 737 ;
-C 65 ; WX 667 ; N A ; B 14 0 654 718 ;
-C 66 ; WX 667 ; N B ; B 74 0 627 718 ;
-C 67 ; WX 722 ; N C ; B 44 -19 681 737 ;
-C 68 ; WX 722 ; N D ; B 81 0 674 718 ;
-C 69 ; WX 667 ; N E ; B 86 0 616 718 ;
-C 70 ; WX 611 ; N F ; B 86 0 583 718 ;
-C 71 ; WX 778 ; N G ; B 48 -19 704 737 ;
-C 72 ; WX 722 ; N H ; B 77 0 646 718 ;
-C 73 ; WX 278 ; N I ; B 91 0 188 718 ;
-C 74 ; WX 500 ; N J ; B 17 -19 428 718 ;
-C 75 ; WX 667 ; N K ; B 76 0 663 718 ;
-C 76 ; WX 556 ; N L ; B 76 0 537 718 ;
-C 77 ; WX 833 ; N M ; B 73 0 761 718 ;
-C 78 ; WX 722 ; N N ; B 76 0 646 718 ;
-C 79 ; WX 778 ; N O ; B 39 -19 739 737 ;
-C 80 ; WX 667 ; N P ; B 86 0 622 718 ;
-C 81 ; WX 778 ; N Q ; B 39 -56 739 737 ;
-C 82 ; WX 722 ; N R ; B 88 0 684 718 ;
-C 83 ; WX 667 ; N S ; B 49 -19 620 737 ;
-C 84 ; WX 611 ; N T ; B 14 0 597 718 ;
-C 85 ; WX 722 ; N U ; B 79 -19 644 718 ;
-C 86 ; WX 667 ; N V ; B 20 0 647 718 ;
-C 87 ; WX 944 ; N W ; B 16 0 928 718 ;
-C 88 ; WX 667 ; N X ; B 19 0 648 718 ;
-C 89 ; WX 667 ; N Y ; B 14 0 653 718 ;
-C 90 ; WX 611 ; N Z ; B 23 0 588 718 ;
-C 91 ; WX 278 ; N bracketleft ; B 63 -196 250 722 ;
-C 92 ; WX 278 ; N backslash ; B -17 -19 295 737 ;
-C 93 ; WX 278 ; N bracketright ; B 28 -196 215 722 ;
-C 94 ; WX 469 ; N asciicircum ; B -14 264 483 688 ;
-C 95 ; WX 556 ; N underscore ; B 0 -125 556 -75 ;
-C 96 ; WX 222 ; N quoteleft ; B 65 470 169 725 ;
-C 97 ; WX 556 ; N a ; B 36 -15 530 538 ;
-C 98 ; WX 556 ; N b ; B 58 -15 517 718 ;
-C 99 ; WX 500 ; N c ; B 30 -15 477 538 ;
-C 100 ; WX 556 ; N d ; B 35 -15 499 718 ;
-C 101 ; WX 556 ; N e ; B 40 -15 516 538 ;
-C 102 ; WX 278 ; N f ; B 14 0 262 728 ; L i fi ; L l fl ;
-C 103 ; WX 556 ; N g ; B 40 -220 499 538 ;
-C 104 ; WX 556 ; N h ; B 65 0 491 718 ;
-C 105 ; WX 222 ; N i ; B 67 0 155 718 ;
-C 106 ; WX 222 ; N j ; B -16 -210 155 718 ;
-C 107 ; WX 500 ; N k ; B 67 0 501 718 ;
-C 108 ; WX 222 ; N l ; B 67 0 155 718 ;
-C 109 ; WX 833 ; N m ; B 65 0 769 538 ;
-C 110 ; WX 556 ; N n ; B 65 0 491 538 ;
-C 111 ; WX 556 ; N o ; B 35 -14 521 538 ;
-C 112 ; WX 556 ; N p ; B 58 -207 517 538 ;
-C 113 ; WX 556 ; N q ; B 35 -207 494 538 ;
-C 114 ; WX 333 ; N r ; B 77 0 332 538 ;
-C 115 ; WX 500 ; N s ; B 32 -15 464 538 ;
-C 116 ; WX 278 ; N t ; B 14 -7 257 669 ;
-C 117 ; WX 556 ; N u ; B 68 -15 489 523 ;
-C 118 ; WX 500 ; N v ; B 8 0 492 523 ;
-C 119 ; WX 722 ; N w ; B 14 0 709 523 ;
-C 120 ; WX 500 ; N x ; B 11 0 490 523 ;
-C 121 ; WX 500 ; N y ; B 11 -214 489 523 ;
-C 122 ; WX 500 ; N z ; B 31 0 469 523 ;
-C 123 ; WX 334 ; N braceleft ; B 42 -196 292 722 ;
-C 124 ; WX 260 ; N bar ; B 94 -225 167 775 ;
-C 125 ; WX 334 ; N braceright ; B 42 -196 292 722 ;
-C 126 ; WX 584 ; N asciitilde ; B 61 180 523 326 ;
-C 161 ; WX 333 ; N exclamdown ; B 118 -195 215 523 ;
-C 162 ; WX 556 ; N cent ; B 51 -115 513 623 ;
-C 163 ; WX 556 ; N sterling ; B 33 -16 539 718 ;
-C 164 ; WX 167 ; N fraction ; B -166 -19 333 703 ;
-C 165 ; WX 556 ; N yen ; B 3 0 553 688 ;
-C 166 ; WX 556 ; N florin ; B -11 -207 501 737 ;
-C 167 ; WX 556 ; N section ; B 43 -191 512 737 ;
-C 168 ; WX 556 ; N currency ; B 28 99 528 603 ;
-C 169 ; WX 191 ; N quotesingle ; B 59 463 132 718 ;
-C 170 ; WX 333 ; N quotedblleft ; B 38 470 307 725 ;
-C 171 ; WX 556 ; N guillemotleft ; B 97 108 459 446 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 88 108 245 446 ;
-C 173 ; WX 333 ; N guilsinglright ; B 88 108 245 446 ;
-C 174 ; WX 500 ; N fi ; B 14 0 434 728 ;
-C 175 ; WX 500 ; N fl ; B 14 0 432 728 ;
-C 177 ; WX 556 ; N endash ; B 0 240 556 313 ;
-C 178 ; WX 556 ; N dagger ; B 43 -159 514 718 ;
-C 179 ; WX 556 ; N daggerdbl ; B 43 -159 514 718 ;
-C 180 ; WX 278 ; N periodcentered ; B 77 190 202 315 ;
-C 182 ; WX 537 ; N paragraph ; B 18 -173 497 718 ;
-C 183 ; WX 350 ; N bullet ; B 18 202 333 517 ;
-C 184 ; WX 222 ; N quotesinglbase ; B 53 -149 157 106 ;
-C 185 ; WX 333 ; N quotedblbase ; B 26 -149 295 106 ;
-C 186 ; WX 333 ; N quotedblright ; B 26 463 295 718 ;
-C 187 ; WX 556 ; N guillemotright ; B 97 108 459 446 ;
-C 188 ; WX 1000 ; N ellipsis ; B 115 0 885 106 ;
-C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 703 ;
-C 191 ; WX 611 ; N questiondown ; B 91 -201 527 525 ;
-C 193 ; WX 333 ; N grave ; B 14 593 211 734 ;
-C 194 ; WX 333 ; N acute ; B 122 593 319 734 ;
-C 195 ; WX 333 ; N circumflex ; B 21 593 312 734 ;
-C 196 ; WX 333 ; N tilde ; B -4 606 337 722 ;
-C 197 ; WX 333 ; N macron ; B 10 627 323 684 ;
-C 198 ; WX 333 ; N breve ; B 13 595 321 731 ;
-C 199 ; WX 333 ; N dotaccent ; B 121 604 212 706 ;
-C 200 ; WX 333 ; N dieresis ; B 40 604 293 706 ;
-C 202 ; WX 333 ; N ring ; B 75 572 259 756 ;
-C 203 ; WX 333 ; N cedilla ; B 45 -225 259 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 31 593 409 734 ;
-C 206 ; WX 333 ; N ogonek ; B 73 -225 287 0 ;
-C 207 ; WX 333 ; N caron ; B 21 593 312 734 ;
-C 208 ; WX 1000 ; N emdash ; B 0 240 1000 313 ;
-C 225 ; WX 1000 ; N AE ; B 8 0 951 718 ;
-C 227 ; WX 370 ; N ordfeminine ; B 24 405 346 737 ;
-C 232 ; WX 556 ; N Lslash ; B -20 0 537 718 ;
-C 233 ; WX 778 ; N Oslash ; B 39 -19 740 737 ;
-C 234 ; WX 1000 ; N OE ; B 36 -19 965 737 ;
-C 235 ; WX 365 ; N ordmasculine ; B 25 405 341 737 ;
-C 241 ; WX 889 ; N ae ; B 36 -15 847 538 ;
-C 245 ; WX 278 ; N dotlessi ; B 95 0 183 523 ;
-C 248 ; WX 222 ; N lslash ; B -20 0 242 718 ;
-C 249 ; WX 611 ; N oslash ; B 28 -22 537 545 ;
-C 250 ; WX 944 ; N oe ; B 35 -15 902 538 ;
-C 251 ; WX 611 ; N germandbls ; B 67 -15 571 728 ;
-C -1 ; WX 278 ; N Idieresis ; B 13 0 266 901 ;
-C -1 ; WX 556 ; N eacute ; B 40 -15 516 734 ;
-C -1 ; WX 556 ; N abreve ; B 36 -15 530 731 ;
-C -1 ; WX 556 ; N uhungarumlaut ; B 68 -15 521 734 ;
-C -1 ; WX 556 ; N ecaron ; B 40 -15 516 734 ;
-C -1 ; WX 667 ; N Ydieresis ; B 14 0 653 901 ;
-C -1 ; WX 584 ; N divide ; B 39 -19 545 524 ;
-C -1 ; WX 667 ; N Yacute ; B 14 0 653 929 ;
-C -1 ; WX 667 ; N Acircumflex ; B 14 0 654 929 ;
-C -1 ; WX 556 ; N aacute ; B 36 -15 530 734 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 79 -19 644 929 ;
-C -1 ; WX 500 ; N yacute ; B 11 -214 489 734 ;
-C -1 ; WX 500 ; N scommaaccent ; B 32 -225 464 538 ;
-C -1 ; WX 556 ; N ecircumflex ; B 40 -15 516 734 ;
-C -1 ; WX 722 ; N Uring ; B 79 -19 644 931 ;
-C -1 ; WX 722 ; N Udieresis ; B 79 -19 644 901 ;
-C -1 ; WX 556 ; N aogonek ; B 36 -220 547 538 ;
-C -1 ; WX 722 ; N Uacute ; B 79 -19 644 929 ;
-C -1 ; WX 556 ; N uogonek ; B 68 -225 519 523 ;
-C -1 ; WX 667 ; N Edieresis ; B 86 0 616 901 ;
-C -1 ; WX 722 ; N Dcroat ; B 0 0 674 718 ;
-C -1 ; WX 250 ; N commaaccent ; B 87 -225 181 -40 ;
-C -1 ; WX 737 ; N copyright ; B -14 -19 752 737 ;
-C -1 ; WX 667 ; N Emacron ; B 86 0 616 879 ;
-C -1 ; WX 500 ; N ccaron ; B 30 -15 477 734 ;
-C -1 ; WX 556 ; N aring ; B 36 -15 530 756 ;
-C -1 ; WX 722 ; N Ncommaaccent ; B 76 -225 646 718 ;
-C -1 ; WX 222 ; N lacute ; B 67 0 264 929 ;
-C -1 ; WX 556 ; N agrave ; B 36 -15 530 734 ;
-C -1 ; WX 611 ; N Tcommaaccent ; B 14 -225 597 718 ;
-C -1 ; WX 722 ; N Cacute ; B 44 -19 681 929 ;
-C -1 ; WX 556 ; N atilde ; B 36 -15 530 722 ;
-C -1 ; WX 667 ; N Edotaccent ; B 86 0 616 901 ;
-C -1 ; WX 500 ; N scaron ; B 32 -15 464 734 ;
-C -1 ; WX 500 ; N scedilla ; B 32 -225 464 538 ;
-C -1 ; WX 278 ; N iacute ; B 95 0 292 734 ;
-C -1 ; WX 471 ; N lozenge ; B 10 0 462 728 ;
-C -1 ; WX 722 ; N Rcaron ; B 88 0 684 929 ;
-C -1 ; WX 778 ; N Gcommaaccent ; B 48 -225 704 737 ;
-C -1 ; WX 556 ; N ucircumflex ; B 68 -15 489 734 ;
-C -1 ; WX 556 ; N acircumflex ; B 36 -15 530 734 ;
-C -1 ; WX 667 ; N Amacron ; B 14 0 654 879 ;
-C -1 ; WX 333 ; N rcaron ; B 61 0 352 734 ;
-C -1 ; WX 500 ; N ccedilla ; B 30 -225 477 538 ;
-C -1 ; WX 611 ; N Zdotaccent ; B 23 0 588 901 ;
-C -1 ; WX 667 ; N Thorn ; B 86 0 622 718 ;
-C -1 ; WX 778 ; N Omacron ; B 39 -19 739 879 ;
-C -1 ; WX 722 ; N Racute ; B 88 0 684 929 ;
-C -1 ; WX 667 ; N Sacute ; B 49 -19 620 929 ;
-C -1 ; WX 643 ; N dcaron ; B 35 -15 655 718 ;
-C -1 ; WX 722 ; N Umacron ; B 79 -19 644 879 ;
-C -1 ; WX 556 ; N uring ; B 68 -15 489 756 ;
-C -1 ; WX 333 ; N threesuperior ; B 5 270 325 703 ;
-C -1 ; WX 778 ; N Ograve ; B 39 -19 739 929 ;
-C -1 ; WX 667 ; N Agrave ; B 14 0 654 929 ;
-C -1 ; WX 667 ; N Abreve ; B 14 0 654 926 ;
-C -1 ; WX 584 ; N multiply ; B 39 0 545 506 ;
-C -1 ; WX 556 ; N uacute ; B 68 -15 489 734 ;
-C -1 ; WX 611 ; N Tcaron ; B 14 0 597 929 ;
-C -1 ; WX 476 ; N partialdiff ; B 13 -38 463 714 ;
-C -1 ; WX 500 ; N ydieresis ; B 11 -214 489 706 ;
-C -1 ; WX 722 ; N Nacute ; B 76 0 646 929 ;
-C -1 ; WX 278 ; N icircumflex ; B -6 0 285 734 ;
-C -1 ; WX 667 ; N Ecircumflex ; B 86 0 616 929 ;
-C -1 ; WX 556 ; N adieresis ; B 36 -15 530 706 ;
-C -1 ; WX 556 ; N edieresis ; B 40 -15 516 706 ;
-C -1 ; WX 500 ; N cacute ; B 30 -15 477 734 ;
-C -1 ; WX 556 ; N nacute ; B 65 0 491 734 ;
-C -1 ; WX 556 ; N umacron ; B 68 -15 489 684 ;
-C -1 ; WX 722 ; N Ncaron ; B 76 0 646 929 ;
-C -1 ; WX 278 ; N Iacute ; B 91 0 292 929 ;
-C -1 ; WX 584 ; N plusminus ; B 39 0 545 506 ;
-C -1 ; WX 260 ; N brokenbar ; B 94 -150 167 700 ;
-C -1 ; WX 737 ; N registered ; B -14 -19 752 737 ;
-C -1 ; WX 778 ; N Gbreve ; B 48 -19 704 926 ;
-C -1 ; WX 278 ; N Idotaccent ; B 91 0 188 901 ;
-C -1 ; WX 600 ; N summation ; B 15 -10 586 706 ;
-C -1 ; WX 667 ; N Egrave ; B 86 0 616 929 ;
-C -1 ; WX 333 ; N racute ; B 77 0 332 734 ;
-C -1 ; WX 556 ; N omacron ; B 35 -14 521 684 ;
-C -1 ; WX 611 ; N Zacute ; B 23 0 588 929 ;
-C -1 ; WX 611 ; N Zcaron ; B 23 0 588 929 ;
-C -1 ; WX 549 ; N greaterequal ; B 26 0 523 674 ;
-C -1 ; WX 722 ; N Eth ; B 0 0 674 718 ;
-C -1 ; WX 722 ; N Ccedilla ; B 44 -225 681 737 ;
-C -1 ; WX 222 ; N lcommaaccent ; B 67 -225 167 718 ;
-C -1 ; WX 317 ; N tcaron ; B 14 -7 329 808 ;
-C -1 ; WX 556 ; N eogonek ; B 40 -225 516 538 ;
-C -1 ; WX 722 ; N Uogonek ; B 79 -225 644 718 ;
-C -1 ; WX 667 ; N Aacute ; B 14 0 654 929 ;
-C -1 ; WX 667 ; N Adieresis ; B 14 0 654 901 ;
-C -1 ; WX 556 ; N egrave ; B 40 -15 516 734 ;
-C -1 ; WX 500 ; N zacute ; B 31 0 469 734 ;
-C -1 ; WX 222 ; N iogonek ; B -31 -225 183 718 ;
-C -1 ; WX 778 ; N Oacute ; B 39 -19 739 929 ;
-C -1 ; WX 556 ; N oacute ; B 35 -14 521 734 ;
-C -1 ; WX 556 ; N amacron ; B 36 -15 530 684 ;
-C -1 ; WX 500 ; N sacute ; B 32 -15 464 734 ;
-C -1 ; WX 278 ; N idieresis ; B 13 0 266 706 ;
-C -1 ; WX 778 ; N Ocircumflex ; B 39 -19 739 929 ;
-C -1 ; WX 722 ; N Ugrave ; B 79 -19 644 929 ;
-C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ;
-C -1 ; WX 556 ; N thorn ; B 58 -207 517 718 ;
-C -1 ; WX 333 ; N twosuperior ; B 4 281 323 703 ;
-C -1 ; WX 778 ; N Odieresis ; B 39 -19 739 901 ;
-C -1 ; WX 556 ; N mu ; B 68 -207 489 523 ;
-C -1 ; WX 278 ; N igrave ; B -13 0 184 734 ;
-C -1 ; WX 556 ; N ohungarumlaut ; B 35 -14 521 734 ;
-C -1 ; WX 667 ; N Eogonek ; B 86 -220 633 718 ;
-C -1 ; WX 556 ; N dcroat ; B 35 -15 550 718 ;
-C -1 ; WX 834 ; N threequarters ; B 45 -19 810 703 ;
-C -1 ; WX 667 ; N Scedilla ; B 49 -225 620 737 ;
-C -1 ; WX 299 ; N lcaron ; B 67 0 311 718 ;
-C -1 ; WX 667 ; N Kcommaaccent ; B 76 -225 663 718 ;
-C -1 ; WX 556 ; N Lacute ; B 76 0 537 929 ;
-C -1 ; WX 1000 ; N trademark ; B 46 306 903 718 ;
-C -1 ; WX 556 ; N edotaccent ; B 40 -15 516 706 ;
-C -1 ; WX 278 ; N Igrave ; B -13 0 188 929 ;
-C -1 ; WX 278 ; N Imacron ; B -17 0 296 879 ;
-C -1 ; WX 556 ; N Lcaron ; B 76 0 537 718 ;
-C -1 ; WX 834 ; N onehalf ; B 43 -19 773 703 ;
-C -1 ; WX 549 ; N lessequal ; B 26 0 523 674 ;
-C -1 ; WX 556 ; N ocircumflex ; B 35 -14 521 734 ;
-C -1 ; WX 556 ; N ntilde ; B 65 0 491 722 ;
-C -1 ; WX 722 ; N Uhungarumlaut ; B 79 -19 644 929 ;
-C -1 ; WX 667 ; N Eacute ; B 86 0 616 929 ;
-C -1 ; WX 556 ; N emacron ; B 40 -15 516 684 ;
-C -1 ; WX 556 ; N gbreve ; B 40 -220 499 731 ;
-C -1 ; WX 834 ; N onequarter ; B 73 -19 756 703 ;
-C -1 ; WX 667 ; N Scaron ; B 49 -19 620 929 ;
-C -1 ; WX 667 ; N Scommaaccent ; B 49 -225 620 737 ;
-C -1 ; WX 778 ; N Ohungarumlaut ; B 39 -19 739 929 ;
-C -1 ; WX 400 ; N degree ; B 54 411 346 703 ;
-C -1 ; WX 556 ; N ograve ; B 35 -14 521 734 ;
-C -1 ; WX 722 ; N Ccaron ; B 44 -19 681 929 ;
-C -1 ; WX 556 ; N ugrave ; B 68 -15 489 734 ;
-C -1 ; WX 453 ; N radical ; B -4 -80 458 762 ;
-C -1 ; WX 722 ; N Dcaron ; B 81 0 674 929 ;
-C -1 ; WX 333 ; N rcommaaccent ; B 77 -225 332 538 ;
-C -1 ; WX 722 ; N Ntilde ; B 76 0 646 917 ;
-C -1 ; WX 556 ; N otilde ; B 35 -14 521 722 ;
-C -1 ; WX 722 ; N Rcommaaccent ; B 88 -225 684 718 ;
-C -1 ; WX 556 ; N Lcommaaccent ; B 76 -225 537 718 ;
-C -1 ; WX 667 ; N Atilde ; B 14 0 654 917 ;
-C -1 ; WX 667 ; N Aogonek ; B 14 -225 654 718 ;
-C -1 ; WX 667 ; N Aring ; B 14 0 654 931 ;
-C -1 ; WX 778 ; N Otilde ; B 39 -19 739 917 ;
-C -1 ; WX 500 ; N zdotaccent ; B 31 0 469 706 ;
-C -1 ; WX 667 ; N Ecaron ; B 86 0 616 929 ;
-C -1 ; WX 278 ; N Iogonek ; B -3 -225 211 718 ;
-C -1 ; WX 500 ; N kcommaaccent ; B 67 -225 501 718 ;
-C -1 ; WX 584 ; N minus ; B 39 216 545 289 ;
-C -1 ; WX 278 ; N Icircumflex ; B -6 0 285 929 ;
-C -1 ; WX 556 ; N ncaron ; B 65 0 491 734 ;
-C -1 ; WX 278 ; N tcommaaccent ; B 14 -225 257 669 ;
-C -1 ; WX 584 ; N logicalnot ; B 39 108 545 390 ;
-C -1 ; WX 556 ; N odieresis ; B 35 -14 521 706 ;
-C -1 ; WX 556 ; N udieresis ; B 68 -15 489 706 ;
-C -1 ; WX 549 ; N notequal ; B 12 -35 537 551 ;
-C -1 ; WX 556 ; N gcommaaccent ; B 40 -220 499 822 ;
-C -1 ; WX 556 ; N eth ; B 35 -15 522 737 ;
-C -1 ; WX 500 ; N zcaron ; B 31 0 469 734 ;
-C -1 ; WX 556 ; N ncommaaccent ; B 65 -225 491 538 ;
-C -1 ; WX 333 ; N onesuperior ; B 43 281 222 703 ;
-C -1 ; WX 278 ; N imacron ; B 5 0 272 684 ;
-C -1 ; WX 556 ; N Euro ; B 0 0 0 0 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 2705
-KPX A C -30
-KPX A Cacute -30
-KPX A Ccaron -30
-KPX A Ccedilla -30
-KPX A G -30
-KPX A Gbreve -30
-KPX A Gcommaaccent -30
-KPX A O -30
-KPX A Oacute -30
-KPX A Ocircumflex -30
-KPX A Odieresis -30
-KPX A Ograve -30
-KPX A Ohungarumlaut -30
-KPX A Omacron -30
-KPX A Oslash -30
-KPX A Otilde -30
-KPX A Q -30
-KPX A T -120
-KPX A Tcaron -120
-KPX A Tcommaaccent -120
-KPX A U -50
-KPX A Uacute -50
-KPX A Ucircumflex -50
-KPX A Udieresis -50
-KPX A Ugrave -50
-KPX A Uhungarumlaut -50
-KPX A Umacron -50
-KPX A Uogonek -50
-KPX A Uring -50
-KPX A V -70
-KPX A W -50
-KPX A Y -100
-KPX A Yacute -100
-KPX A Ydieresis -100
-KPX A u -30
-KPX A uacute -30
-KPX A ucircumflex -30
-KPX A udieresis -30
-KPX A ugrave -30
-KPX A uhungarumlaut -30
-KPX A umacron -30
-KPX A uogonek -30
-KPX A uring -30
-KPX A v -40
-KPX A w -40
-KPX A y -40
-KPX A yacute -40
-KPX A ydieresis -40
-KPX Aacute C -30
-KPX Aacute Cacute -30
-KPX Aacute Ccaron -30
-KPX Aacute Ccedilla -30
-KPX Aacute G -30
-KPX Aacute Gbreve -30
-KPX Aacute Gcommaaccent -30
-KPX Aacute O -30
-KPX Aacute Oacute -30
-KPX Aacute Ocircumflex -30
-KPX Aacute Odieresis -30
-KPX Aacute Ograve -30
-KPX Aacute Ohungarumlaut -30
-KPX Aacute Omacron -30
-KPX Aacute Oslash -30
-KPX Aacute Otilde -30
-KPX Aacute Q -30
-KPX Aacute T -120
-KPX Aacute Tcaron -120
-KPX Aacute Tcommaaccent -120
-KPX Aacute U -50
-KPX Aacute Uacute -50
-KPX Aacute Ucircumflex -50
-KPX Aacute Udieresis -50
-KPX Aacute Ugrave -50
-KPX Aacute Uhungarumlaut -50
-KPX Aacute Umacron -50
-KPX Aacute Uogonek -50
-KPX Aacute Uring -50
-KPX Aacute V -70
-KPX Aacute W -50
-KPX Aacute Y -100
-KPX Aacute Yacute -100
-KPX Aacute Ydieresis -100
-KPX Aacute u -30
-KPX Aacute uacute -30
-KPX Aacute ucircumflex -30
-KPX Aacute udieresis -30
-KPX Aacute ugrave -30
-KPX Aacute uhungarumlaut -30
-KPX Aacute umacron -30
-KPX Aacute uogonek -30
-KPX Aacute uring -30
-KPX Aacute v -40
-KPX Aacute w -40
-KPX Aacute y -40
-KPX Aacute yacute -40
-KPX Aacute ydieresis -40
-KPX Abreve C -30
-KPX Abreve Cacute -30
-KPX Abreve Ccaron -30
-KPX Abreve Ccedilla -30
-KPX Abreve G -30
-KPX Abreve Gbreve -30
-KPX Abreve Gcommaaccent -30
-KPX Abreve O -30
-KPX Abreve Oacute -30
-KPX Abreve Ocircumflex -30
-KPX Abreve Odieresis -30
-KPX Abreve Ograve -30
-KPX Abreve Ohungarumlaut -30
-KPX Abreve Omacron -30
-KPX Abreve Oslash -30
-KPX Abreve Otilde -30
-KPX Abreve Q -30
-KPX Abreve T -120
-KPX Abreve Tcaron -120
-KPX Abreve Tcommaaccent -120
-KPX Abreve U -50
-KPX Abreve Uacute -50
-KPX Abreve Ucircumflex -50
-KPX Abreve Udieresis -50
-KPX Abreve Ugrave -50
-KPX Abreve Uhungarumlaut -50
-KPX Abreve Umacron -50
-KPX Abreve Uogonek -50
-KPX Abreve Uring -50
-KPX Abreve V -70
-KPX Abreve W -50
-KPX Abreve Y -100
-KPX Abreve Yacute -100
-KPX Abreve Ydieresis -100
-KPX Abreve u -30
-KPX Abreve uacute -30
-KPX Abreve ucircumflex -30
-KPX Abreve udieresis -30
-KPX Abreve ugrave -30
-KPX Abreve uhungarumlaut -30
-KPX Abreve umacron -30
-KPX Abreve uogonek -30
-KPX Abreve uring -30
-KPX Abreve v -40
-KPX Abreve w -40
-KPX Abreve y -40
-KPX Abreve yacute -40
-KPX Abreve ydieresis -40
-KPX Acircumflex C -30
-KPX Acircumflex Cacute -30
-KPX Acircumflex Ccaron -30
-KPX Acircumflex Ccedilla -30
-KPX Acircumflex G -30
-KPX Acircumflex Gbreve -30
-KPX Acircumflex Gcommaaccent -30
-KPX Acircumflex O -30
-KPX Acircumflex Oacute -30
-KPX Acircumflex Ocircumflex -30
-KPX Acircumflex Odieresis -30
-KPX Acircumflex Ograve -30
-KPX Acircumflex Ohungarumlaut -30
-KPX Acircumflex Omacron -30
-KPX Acircumflex Oslash -30
-KPX Acircumflex Otilde -30
-KPX Acircumflex Q -30
-KPX Acircumflex T -120
-KPX Acircumflex Tcaron -120
-KPX Acircumflex Tcommaaccent -120
-KPX Acircumflex U -50
-KPX Acircumflex Uacute -50
-KPX Acircumflex Ucircumflex -50
-KPX Acircumflex Udieresis -50
-KPX Acircumflex Ugrave -50
-KPX Acircumflex Uhungarumlaut -50
-KPX Acircumflex Umacron -50
-KPX Acircumflex Uogonek -50
-KPX Acircumflex Uring -50
-KPX Acircumflex V -70
-KPX Acircumflex W -50
-KPX Acircumflex Y -100
-KPX Acircumflex Yacute -100
-KPX Acircumflex Ydieresis -100
-KPX Acircumflex u -30
-KPX Acircumflex uacute -30
-KPX Acircumflex ucircumflex -30
-KPX Acircumflex udieresis -30
-KPX Acircumflex ugrave -30
-KPX Acircumflex uhungarumlaut -30
-KPX Acircumflex umacron -30
-KPX Acircumflex uogonek -30
-KPX Acircumflex uring -30
-KPX Acircumflex v -40
-KPX Acircumflex w -40
-KPX Acircumflex y -40
-KPX Acircumflex yacute -40
-KPX Acircumflex ydieresis -40
-KPX Adieresis C -30
-KPX Adieresis Cacute -30
-KPX Adieresis Ccaron -30
-KPX Adieresis Ccedilla -30
-KPX Adieresis G -30
-KPX Adieresis Gbreve -30
-KPX Adieresis Gcommaaccent -30
-KPX Adieresis O -30
-KPX Adieresis Oacute -30
-KPX Adieresis Ocircumflex -30
-KPX Adieresis Odieresis -30
-KPX Adieresis Ograve -30
-KPX Adieresis Ohungarumlaut -30
-KPX Adieresis Omacron -30
-KPX Adieresis Oslash -30
-KPX Adieresis Otilde -30
-KPX Adieresis Q -30
-KPX Adieresis T -120
-KPX Adieresis Tcaron -120
-KPX Adieresis Tcommaaccent -120
-KPX Adieresis U -50
-KPX Adieresis Uacute -50
-KPX Adieresis Ucircumflex -50
-KPX Adieresis Udieresis -50
-KPX Adieresis Ugrave -50
-KPX Adieresis Uhungarumlaut -50
-KPX Adieresis Umacron -50
-KPX Adieresis Uogonek -50
-KPX Adieresis Uring -50
-KPX Adieresis V -70
-KPX Adieresis W -50
-KPX Adieresis Y -100
-KPX Adieresis Yacute -100
-KPX Adieresis Ydieresis -100
-KPX Adieresis u -30
-KPX Adieresis uacute -30
-KPX Adieresis ucircumflex -30
-KPX Adieresis udieresis -30
-KPX Adieresis ugrave -30
-KPX Adieresis uhungarumlaut -30
-KPX Adieresis umacron -30
-KPX Adieresis uogonek -30
-KPX Adieresis uring -30
-KPX Adieresis v -40
-KPX Adieresis w -40
-KPX Adieresis y -40
-KPX Adieresis yacute -40
-KPX Adieresis ydieresis -40
-KPX Agrave C -30
-KPX Agrave Cacute -30
-KPX Agrave Ccaron -30
-KPX Agrave Ccedilla -30
-KPX Agrave G -30
-KPX Agrave Gbreve -30
-KPX Agrave Gcommaaccent -30
-KPX Agrave O -30
-KPX Agrave Oacute -30
-KPX Agrave Ocircumflex -30
-KPX Agrave Odieresis -30
-KPX Agrave Ograve -30
-KPX Agrave Ohungarumlaut -30
-KPX Agrave Omacron -30
-KPX Agrave Oslash -30
-KPX Agrave Otilde -30
-KPX Agrave Q -30
-KPX Agrave T -120
-KPX Agrave Tcaron -120
-KPX Agrave Tcommaaccent -120
-KPX Agrave U -50
-KPX Agrave Uacute -50
-KPX Agrave Ucircumflex -50
-KPX Agrave Udieresis -50
-KPX Agrave Ugrave -50
-KPX Agrave Uhungarumlaut -50
-KPX Agrave Umacron -50
-KPX Agrave Uogonek -50
-KPX Agrave Uring -50
-KPX Agrave V -70
-KPX Agrave W -50
-KPX Agrave Y -100
-KPX Agrave Yacute -100
-KPX Agrave Ydieresis -100
-KPX Agrave u -30
-KPX Agrave uacute -30
-KPX Agrave ucircumflex -30
-KPX Agrave udieresis -30
-KPX Agrave ugrave -30
-KPX Agrave uhungarumlaut -30
-KPX Agrave umacron -30
-KPX Agrave uogonek -30
-KPX Agrave uring -30
-KPX Agrave v -40
-KPX Agrave w -40
-KPX Agrave y -40
-KPX Agrave yacute -40
-KPX Agrave ydieresis -40
-KPX Amacron C -30
-KPX Amacron Cacute -30
-KPX Amacron Ccaron -30
-KPX Amacron Ccedilla -30
-KPX Amacron G -30
-KPX Amacron Gbreve -30
-KPX Amacron Gcommaaccent -30
-KPX Amacron O -30
-KPX Amacron Oacute -30
-KPX Amacron Ocircumflex -30
-KPX Amacron Odieresis -30
-KPX Amacron Ograve -30
-KPX Amacron Ohungarumlaut -30
-KPX Amacron Omacron -30
-KPX Amacron Oslash -30
-KPX Amacron Otilde -30
-KPX Amacron Q -30
-KPX Amacron T -120
-KPX Amacron Tcaron -120
-KPX Amacron Tcommaaccent -120
-KPX Amacron U -50
-KPX Amacron Uacute -50
-KPX Amacron Ucircumflex -50
-KPX Amacron Udieresis -50
-KPX Amacron Ugrave -50
-KPX Amacron Uhungarumlaut -50
-KPX Amacron Umacron -50
-KPX Amacron Uogonek -50
-KPX Amacron Uring -50
-KPX Amacron V -70
-KPX Amacron W -50
-KPX Amacron Y -100
-KPX Amacron Yacute -100
-KPX Amacron Ydieresis -100
-KPX Amacron u -30
-KPX Amacron uacute -30
-KPX Amacron ucircumflex -30
-KPX Amacron udieresis -30
-KPX Amacron ugrave -30
-KPX Amacron uhungarumlaut -30
-KPX Amacron umacron -30
-KPX Amacron uogonek -30
-KPX Amacron uring -30
-KPX Amacron v -40
-KPX Amacron w -40
-KPX Amacron y -40
-KPX Amacron yacute -40
-KPX Amacron ydieresis -40
-KPX Aogonek C -30
-KPX Aogonek Cacute -30
-KPX Aogonek Ccaron -30
-KPX Aogonek Ccedilla -30
-KPX Aogonek G -30
-KPX Aogonek Gbreve -30
-KPX Aogonek Gcommaaccent -30
-KPX Aogonek O -30
-KPX Aogonek Oacute -30
-KPX Aogonek Ocircumflex -30
-KPX Aogonek Odieresis -30
-KPX Aogonek Ograve -30
-KPX Aogonek Ohungarumlaut -30
-KPX Aogonek Omacron -30
-KPX Aogonek Oslash -30
-KPX Aogonek Otilde -30
-KPX Aogonek Q -30
-KPX Aogonek T -120
-KPX Aogonek Tcaron -120
-KPX Aogonek Tcommaaccent -120
-KPX Aogonek U -50
-KPX Aogonek Uacute -50
-KPX Aogonek Ucircumflex -50
-KPX Aogonek Udieresis -50
-KPX Aogonek Ugrave -50
-KPX Aogonek Uhungarumlaut -50
-KPX Aogonek Umacron -50
-KPX Aogonek Uogonek -50
-KPX Aogonek Uring -50
-KPX Aogonek V -70
-KPX Aogonek W -50
-KPX Aogonek Y -100
-KPX Aogonek Yacute -100
-KPX Aogonek Ydieresis -100
-KPX Aogonek u -30
-KPX Aogonek uacute -30
-KPX Aogonek ucircumflex -30
-KPX Aogonek udieresis -30
-KPX Aogonek ugrave -30
-KPX Aogonek uhungarumlaut -30
-KPX Aogonek umacron -30
-KPX Aogonek uogonek -30
-KPX Aogonek uring -30
-KPX Aogonek v -40
-KPX Aogonek w -40
-KPX Aogonek y -40
-KPX Aogonek yacute -40
-KPX Aogonek ydieresis -40
-KPX Aring C -30
-KPX Aring Cacute -30
-KPX Aring Ccaron -30
-KPX Aring Ccedilla -30
-KPX Aring G -30
-KPX Aring Gbreve -30
-KPX Aring Gcommaaccent -30
-KPX Aring O -30
-KPX Aring Oacute -30
-KPX Aring Ocircumflex -30
-KPX Aring Odieresis -30
-KPX Aring Ograve -30
-KPX Aring Ohungarumlaut -30
-KPX Aring Omacron -30
-KPX Aring Oslash -30
-KPX Aring Otilde -30
-KPX Aring Q -30
-KPX Aring T -120
-KPX Aring Tcaron -120
-KPX Aring Tcommaaccent -120
-KPX Aring U -50
-KPX Aring Uacute -50
-KPX Aring Ucircumflex -50
-KPX Aring Udieresis -50
-KPX Aring Ugrave -50
-KPX Aring Uhungarumlaut -50
-KPX Aring Umacron -50
-KPX Aring Uogonek -50
-KPX Aring Uring -50
-KPX Aring V -70
-KPX Aring W -50
-KPX Aring Y -100
-KPX Aring Yacute -100
-KPX Aring Ydieresis -100
-KPX Aring u -30
-KPX Aring uacute -30
-KPX Aring ucircumflex -30
-KPX Aring udieresis -30
-KPX Aring ugrave -30
-KPX Aring uhungarumlaut -30
-KPX Aring umacron -30
-KPX Aring uogonek -30
-KPX Aring uring -30
-KPX Aring v -40
-KPX Aring w -40
-KPX Aring y -40
-KPX Aring yacute -40
-KPX Aring ydieresis -40
-KPX Atilde C -30
-KPX Atilde Cacute -30
-KPX Atilde Ccaron -30
-KPX Atilde Ccedilla -30
-KPX Atilde G -30
-KPX Atilde Gbreve -30
-KPX Atilde Gcommaaccent -30
-KPX Atilde O -30
-KPX Atilde Oacute -30
-KPX Atilde Ocircumflex -30
-KPX Atilde Odieresis -30
-KPX Atilde Ograve -30
-KPX Atilde Ohungarumlaut -30
-KPX Atilde Omacron -30
-KPX Atilde Oslash -30
-KPX Atilde Otilde -30
-KPX Atilde Q -30
-KPX Atilde T -120
-KPX Atilde Tcaron -120
-KPX Atilde Tcommaaccent -120
-KPX Atilde U -50
-KPX Atilde Uacute -50
-KPX Atilde Ucircumflex -50
-KPX Atilde Udieresis -50
-KPX Atilde Ugrave -50
-KPX Atilde Uhungarumlaut -50
-KPX Atilde Umacron -50
-KPX Atilde Uogonek -50
-KPX Atilde Uring -50
-KPX Atilde V -70
-KPX Atilde W -50
-KPX Atilde Y -100
-KPX Atilde Yacute -100
-KPX Atilde Ydieresis -100
-KPX Atilde u -30
-KPX Atilde uacute -30
-KPX Atilde ucircumflex -30
-KPX Atilde udieresis -30
-KPX Atilde ugrave -30
-KPX Atilde uhungarumlaut -30
-KPX Atilde umacron -30
-KPX Atilde uogonek -30
-KPX Atilde uring -30
-KPX Atilde v -40
-KPX Atilde w -40
-KPX Atilde y -40
-KPX Atilde yacute -40
-KPX Atilde ydieresis -40
-KPX B U -10
-KPX B Uacute -10
-KPX B Ucircumflex -10
-KPX B Udieresis -10
-KPX B Ugrave -10
-KPX B Uhungarumlaut -10
-KPX B Umacron -10
-KPX B Uogonek -10
-KPX B Uring -10
-KPX B comma -20
-KPX B period -20
-KPX C comma -30
-KPX C period -30
-KPX Cacute comma -30
-KPX Cacute period -30
-KPX Ccaron comma -30
-KPX Ccaron period -30
-KPX Ccedilla comma -30
-KPX Ccedilla period -30
-KPX D A -40
-KPX D Aacute -40
-KPX D Abreve -40
-KPX D Acircumflex -40
-KPX D Adieresis -40
-KPX D Agrave -40
-KPX D Amacron -40
-KPX D Aogonek -40
-KPX D Aring -40
-KPX D Atilde -40
-KPX D V -70
-KPX D W -40
-KPX D Y -90
-KPX D Yacute -90
-KPX D Ydieresis -90
-KPX D comma -70
-KPX D period -70
-KPX Dcaron A -40
-KPX Dcaron Aacute -40
-KPX Dcaron Abreve -40
-KPX Dcaron Acircumflex -40
-KPX Dcaron Adieresis -40
-KPX Dcaron Agrave -40
-KPX Dcaron Amacron -40
-KPX Dcaron Aogonek -40
-KPX Dcaron Aring -40
-KPX Dcaron Atilde -40
-KPX Dcaron V -70
-KPX Dcaron W -40
-KPX Dcaron Y -90
-KPX Dcaron Yacute -90
-KPX Dcaron Ydieresis -90
-KPX Dcaron comma -70
-KPX Dcaron period -70
-KPX Dcroat A -40
-KPX Dcroat Aacute -40
-KPX Dcroat Abreve -40
-KPX Dcroat Acircumflex -40
-KPX Dcroat Adieresis -40
-KPX Dcroat Agrave -40
-KPX Dcroat Amacron -40
-KPX Dcroat Aogonek -40
-KPX Dcroat Aring -40
-KPX Dcroat Atilde -40
-KPX Dcroat V -70
-KPX Dcroat W -40
-KPX Dcroat Y -90
-KPX Dcroat Yacute -90
-KPX Dcroat Ydieresis -90
-KPX Dcroat comma -70
-KPX Dcroat period -70
-KPX F A -80
-KPX F Aacute -80
-KPX F Abreve -80
-KPX F Acircumflex -80
-KPX F Adieresis -80
-KPX F Agrave -80
-KPX F Amacron -80
-KPX F Aogonek -80
-KPX F Aring -80
-KPX F Atilde -80
-KPX F a -50
-KPX F aacute -50
-KPX F abreve -50
-KPX F acircumflex -50
-KPX F adieresis -50
-KPX F agrave -50
-KPX F amacron -50
-KPX F aogonek -50
-KPX F aring -50
-KPX F atilde -50
-KPX F comma -150
-KPX F e -30
-KPX F eacute -30
-KPX F ecaron -30
-KPX F ecircumflex -30
-KPX F edieresis -30
-KPX F edotaccent -30
-KPX F egrave -30
-KPX F emacron -30
-KPX F eogonek -30
-KPX F o -30
-KPX F oacute -30
-KPX F ocircumflex -30
-KPX F odieresis -30
-KPX F ograve -30
-KPX F ohungarumlaut -30
-KPX F omacron -30
-KPX F oslash -30
-KPX F otilde -30
-KPX F period -150
-KPX F r -45
-KPX F racute -45
-KPX F rcaron -45
-KPX F rcommaaccent -45
-KPX J A -20
-KPX J Aacute -20
-KPX J Abreve -20
-KPX J Acircumflex -20
-KPX J Adieresis -20
-KPX J Agrave -20
-KPX J Amacron -20
-KPX J Aogonek -20
-KPX J Aring -20
-KPX J Atilde -20
-KPX J a -20
-KPX J aacute -20
-KPX J abreve -20
-KPX J acircumflex -20
-KPX J adieresis -20
-KPX J agrave -20
-KPX J amacron -20
-KPX J aogonek -20
-KPX J aring -20
-KPX J atilde -20
-KPX J comma -30
-KPX J period -30
-KPX J u -20
-KPX J uacute -20
-KPX J ucircumflex -20
-KPX J udieresis -20
-KPX J ugrave -20
-KPX J uhungarumlaut -20
-KPX J umacron -20
-KPX J uogonek -20
-KPX J uring -20
-KPX K O -50
-KPX K Oacute -50
-KPX K Ocircumflex -50
-KPX K Odieresis -50
-KPX K Ograve -50
-KPX K Ohungarumlaut -50
-KPX K Omacron -50
-KPX K Oslash -50
-KPX K Otilde -50
-KPX K e -40
-KPX K eacute -40
-KPX K ecaron -40
-KPX K ecircumflex -40
-KPX K edieresis -40
-KPX K edotaccent -40
-KPX K egrave -40
-KPX K emacron -40
-KPX K eogonek -40
-KPX K o -40
-KPX K oacute -40
-KPX K ocircumflex -40
-KPX K odieresis -40
-KPX K ograve -40
-KPX K ohungarumlaut -40
-KPX K omacron -40
-KPX K oslash -40
-KPX K otilde -40
-KPX K u -30
-KPX K uacute -30
-KPX K ucircumflex -30
-KPX K udieresis -30
-KPX K ugrave -30
-KPX K uhungarumlaut -30
-KPX K umacron -30
-KPX K uogonek -30
-KPX K uring -30
-KPX K y -50
-KPX K yacute -50
-KPX K ydieresis -50
-KPX Kcommaaccent O -50
-KPX Kcommaaccent Oacute -50
-KPX Kcommaaccent Ocircumflex -50
-KPX Kcommaaccent Odieresis -50
-KPX Kcommaaccent Ograve -50
-KPX Kcommaaccent Ohungarumlaut -50
-KPX Kcommaaccent Omacron -50
-KPX Kcommaaccent Oslash -50
-KPX Kcommaaccent Otilde -50
-KPX Kcommaaccent e -40
-KPX Kcommaaccent eacute -40
-KPX Kcommaaccent ecaron -40
-KPX Kcommaaccent ecircumflex -40
-KPX Kcommaaccent edieresis -40
-KPX Kcommaaccent edotaccent -40
-KPX Kcommaaccent egrave -40
-KPX Kcommaaccent emacron -40
-KPX Kcommaaccent eogonek -40
-KPX Kcommaaccent o -40
-KPX Kcommaaccent oacute -40
-KPX Kcommaaccent ocircumflex -40
-KPX Kcommaaccent odieresis -40
-KPX Kcommaaccent ograve -40
-KPX Kcommaaccent ohungarumlaut -40
-KPX Kcommaaccent omacron -40
-KPX Kcommaaccent oslash -40
-KPX Kcommaaccent otilde -40
-KPX Kcommaaccent u -30
-KPX Kcommaaccent uacute -30
-KPX Kcommaaccent ucircumflex -30
-KPX Kcommaaccent udieresis -30
-KPX Kcommaaccent ugrave -30
-KPX Kcommaaccent uhungarumlaut -30
-KPX Kcommaaccent umacron -30
-KPX Kcommaaccent uogonek -30
-KPX Kcommaaccent uring -30
-KPX Kcommaaccent y -50
-KPX Kcommaaccent yacute -50
-KPX Kcommaaccent ydieresis -50
-KPX L T -110
-KPX L Tcaron -110
-KPX L Tcommaaccent -110
-KPX L V -110
-KPX L W -70
-KPX L Y -140
-KPX L Yacute -140
-KPX L Ydieresis -140
-KPX L quotedblright -140
-KPX L quoteright -160
-KPX L y -30
-KPX L yacute -30
-KPX L ydieresis -30
-KPX Lacute T -110
-KPX Lacute Tcaron -110
-KPX Lacute Tcommaaccent -110
-KPX Lacute V -110
-KPX Lacute W -70
-KPX Lacute Y -140
-KPX Lacute Yacute -140
-KPX Lacute Ydieresis -140
-KPX Lacute quotedblright -140
-KPX Lacute quoteright -160
-KPX Lacute y -30
-KPX Lacute yacute -30
-KPX Lacute ydieresis -30
-KPX Lcaron T -110
-KPX Lcaron Tcaron -110
-KPX Lcaron Tcommaaccent -110
-KPX Lcaron V -110
-KPX Lcaron W -70
-KPX Lcaron Y -140
-KPX Lcaron Yacute -140
-KPX Lcaron Ydieresis -140
-KPX Lcaron quotedblright -140
-KPX Lcaron quoteright -160
-KPX Lcaron y -30
-KPX Lcaron yacute -30
-KPX Lcaron ydieresis -30
-KPX Lcommaaccent T -110
-KPX Lcommaaccent Tcaron -110
-KPX Lcommaaccent Tcommaaccent -110
-KPX Lcommaaccent V -110
-KPX Lcommaaccent W -70
-KPX Lcommaaccent Y -140
-KPX Lcommaaccent Yacute -140
-KPX Lcommaaccent Ydieresis -140
-KPX Lcommaaccent quotedblright -140
-KPX Lcommaaccent quoteright -160
-KPX Lcommaaccent y -30
-KPX Lcommaaccent yacute -30
-KPX Lcommaaccent ydieresis -30
-KPX Lslash T -110
-KPX Lslash Tcaron -110
-KPX Lslash Tcommaaccent -110
-KPX Lslash V -110
-KPX Lslash W -70
-KPX Lslash Y -140
-KPX Lslash Yacute -140
-KPX Lslash Ydieresis -140
-KPX Lslash quotedblright -140
-KPX Lslash quoteright -160
-KPX Lslash y -30
-KPX Lslash yacute -30
-KPX Lslash ydieresis -30
-KPX O A -20
-KPX O Aacute -20
-KPX O Abreve -20
-KPX O Acircumflex -20
-KPX O Adieresis -20
-KPX O Agrave -20
-KPX O Amacron -20
-KPX O Aogonek -20
-KPX O Aring -20
-KPX O Atilde -20
-KPX O T -40
-KPX O Tcaron -40
-KPX O Tcommaaccent -40
-KPX O V -50
-KPX O W -30
-KPX O X -60
-KPX O Y -70
-KPX O Yacute -70
-KPX O Ydieresis -70
-KPX O comma -40
-KPX O period -40
-KPX Oacute A -20
-KPX Oacute Aacute -20
-KPX Oacute Abreve -20
-KPX Oacute Acircumflex -20
-KPX Oacute Adieresis -20
-KPX Oacute Agrave -20
-KPX Oacute Amacron -20
-KPX Oacute Aogonek -20
-KPX Oacute Aring -20
-KPX Oacute Atilde -20
-KPX Oacute T -40
-KPX Oacute Tcaron -40
-KPX Oacute Tcommaaccent -40
-KPX Oacute V -50
-KPX Oacute W -30
-KPX Oacute X -60
-KPX Oacute Y -70
-KPX Oacute Yacute -70
-KPX Oacute Ydieresis -70
-KPX Oacute comma -40
-KPX Oacute period -40
-KPX Ocircumflex A -20
-KPX Ocircumflex Aacute -20
-KPX Ocircumflex Abreve -20
-KPX Ocircumflex Acircumflex -20
-KPX Ocircumflex Adieresis -20
-KPX Ocircumflex Agrave -20
-KPX Ocircumflex Amacron -20
-KPX Ocircumflex Aogonek -20
-KPX Ocircumflex Aring -20
-KPX Ocircumflex Atilde -20
-KPX Ocircumflex T -40
-KPX Ocircumflex Tcaron -40
-KPX Ocircumflex Tcommaaccent -40
-KPX Ocircumflex V -50
-KPX Ocircumflex W -30
-KPX Ocircumflex X -60
-KPX Ocircumflex Y -70
-KPX Ocircumflex Yacute -70
-KPX Ocircumflex Ydieresis -70
-KPX Ocircumflex comma -40
-KPX Ocircumflex period -40
-KPX Odieresis A -20
-KPX Odieresis Aacute -20
-KPX Odieresis Abreve -20
-KPX Odieresis Acircumflex -20
-KPX Odieresis Adieresis -20
-KPX Odieresis Agrave -20
-KPX Odieresis Amacron -20
-KPX Odieresis Aogonek -20
-KPX Odieresis Aring -20
-KPX Odieresis Atilde -20
-KPX Odieresis T -40
-KPX Odieresis Tcaron -40
-KPX Odieresis Tcommaaccent -40
-KPX Odieresis V -50
-KPX Odieresis W -30
-KPX Odieresis X -60
-KPX Odieresis Y -70
-KPX Odieresis Yacute -70
-KPX Odieresis Ydieresis -70
-KPX Odieresis comma -40
-KPX Odieresis period -40
-KPX Ograve A -20
-KPX Ograve Aacute -20
-KPX Ograve Abreve -20
-KPX Ograve Acircumflex -20
-KPX Ograve Adieresis -20
-KPX Ograve Agrave -20
-KPX Ograve Amacron -20
-KPX Ograve Aogonek -20
-KPX Ograve Aring -20
-KPX Ograve Atilde -20
-KPX Ograve T -40
-KPX Ograve Tcaron -40
-KPX Ograve Tcommaaccent -40
-KPX Ograve V -50
-KPX Ograve W -30
-KPX Ograve X -60
-KPX Ograve Y -70
-KPX Ograve Yacute -70
-KPX Ograve Ydieresis -70
-KPX Ograve comma -40
-KPX Ograve period -40
-KPX Ohungarumlaut A -20
-KPX Ohungarumlaut Aacute -20
-KPX Ohungarumlaut Abreve -20
-KPX Ohungarumlaut Acircumflex -20
-KPX Ohungarumlaut Adieresis -20
-KPX Ohungarumlaut Agrave -20
-KPX Ohungarumlaut Amacron -20
-KPX Ohungarumlaut Aogonek -20
-KPX Ohungarumlaut Aring -20
-KPX Ohungarumlaut Atilde -20
-KPX Ohungarumlaut T -40
-KPX Ohungarumlaut Tcaron -40
-KPX Ohungarumlaut Tcommaaccent -40
-KPX Ohungarumlaut V -50
-KPX Ohungarumlaut W -30
-KPX Ohungarumlaut X -60
-KPX Ohungarumlaut Y -70
-KPX Ohungarumlaut Yacute -70
-KPX Ohungarumlaut Ydieresis -70
-KPX Ohungarumlaut comma -40
-KPX Ohungarumlaut period -40
-KPX Omacron A -20
-KPX Omacron Aacute -20
-KPX Omacron Abreve -20
-KPX Omacron Acircumflex -20
-KPX Omacron Adieresis -20
-KPX Omacron Agrave -20
-KPX Omacron Amacron -20
-KPX Omacron Aogonek -20
-KPX Omacron Aring -20
-KPX Omacron Atilde -20
-KPX Omacron T -40
-KPX Omacron Tcaron -40
-KPX Omacron Tcommaaccent -40
-KPX Omacron V -50
-KPX Omacron W -30
-KPX Omacron X -60
-KPX Omacron Y -70
-KPX Omacron Yacute -70
-KPX Omacron Ydieresis -70
-KPX Omacron comma -40
-KPX Omacron period -40
-KPX Oslash A -20
-KPX Oslash Aacute -20
-KPX Oslash Abreve -20
-KPX Oslash Acircumflex -20
-KPX Oslash Adieresis -20
-KPX Oslash Agrave -20
-KPX Oslash Amacron -20
-KPX Oslash Aogonek -20
-KPX Oslash Aring -20
-KPX Oslash Atilde -20
-KPX Oslash T -40
-KPX Oslash Tcaron -40
-KPX Oslash Tcommaaccent -40
-KPX Oslash V -50
-KPX Oslash W -30
-KPX Oslash X -60
-KPX Oslash Y -70
-KPX Oslash Yacute -70
-KPX Oslash Ydieresis -70
-KPX Oslash comma -40
-KPX Oslash period -40
-KPX Otilde A -20
-KPX Otilde Aacute -20
-KPX Otilde Abreve -20
-KPX Otilde Acircumflex -20
-KPX Otilde Adieresis -20
-KPX Otilde Agrave -20
-KPX Otilde Amacron -20
-KPX Otilde Aogonek -20
-KPX Otilde Aring -20
-KPX Otilde Atilde -20
-KPX Otilde T -40
-KPX Otilde Tcaron -40
-KPX Otilde Tcommaaccent -40
-KPX Otilde V -50
-KPX Otilde W -30
-KPX Otilde X -60
-KPX Otilde Y -70
-KPX Otilde Yacute -70
-KPX Otilde Ydieresis -70
-KPX Otilde comma -40
-KPX Otilde period -40
-KPX P A -120
-KPX P Aacute -120
-KPX P Abreve -120
-KPX P Acircumflex -120
-KPX P Adieresis -120
-KPX P Agrave -120
-KPX P Amacron -120
-KPX P Aogonek -120
-KPX P Aring -120
-KPX P Atilde -120
-KPX P a -40
-KPX P aacute -40
-KPX P abreve -40
-KPX P acircumflex -40
-KPX P adieresis -40
-KPX P agrave -40
-KPX P amacron -40
-KPX P aogonek -40
-KPX P aring -40
-KPX P atilde -40
-KPX P comma -180
-KPX P e -50
-KPX P eacute -50
-KPX P ecaron -50
-KPX P ecircumflex -50
-KPX P edieresis -50
-KPX P edotaccent -50
-KPX P egrave -50
-KPX P emacron -50
-KPX P eogonek -50
-KPX P o -50
-KPX P oacute -50
-KPX P ocircumflex -50
-KPX P odieresis -50
-KPX P ograve -50
-KPX P ohungarumlaut -50
-KPX P omacron -50
-KPX P oslash -50
-KPX P otilde -50
-KPX P period -180
-KPX Q U -10
-KPX Q Uacute -10
-KPX Q Ucircumflex -10
-KPX Q Udieresis -10
-KPX Q Ugrave -10
-KPX Q Uhungarumlaut -10
-KPX Q Umacron -10
-KPX Q Uogonek -10
-KPX Q Uring -10
-KPX R O -20
-KPX R Oacute -20
-KPX R Ocircumflex -20
-KPX R Odieresis -20
-KPX R Ograve -20
-KPX R Ohungarumlaut -20
-KPX R Omacron -20
-KPX R Oslash -20
-KPX R Otilde -20
-KPX R T -30
-KPX R Tcaron -30
-KPX R Tcommaaccent -30
-KPX R U -40
-KPX R Uacute -40
-KPX R Ucircumflex -40
-KPX R Udieresis -40
-KPX R Ugrave -40
-KPX R Uhungarumlaut -40
-KPX R Umacron -40
-KPX R Uogonek -40
-KPX R Uring -40
-KPX R V -50
-KPX R W -30
-KPX R Y -50
-KPX R Yacute -50
-KPX R Ydieresis -50
-KPX Racute O -20
-KPX Racute Oacute -20
-KPX Racute Ocircumflex -20
-KPX Racute Odieresis -20
-KPX Racute Ograve -20
-KPX Racute Ohungarumlaut -20
-KPX Racute Omacron -20
-KPX Racute Oslash -20
-KPX Racute Otilde -20
-KPX Racute T -30
-KPX Racute Tcaron -30
-KPX Racute Tcommaaccent -30
-KPX Racute U -40
-KPX Racute Uacute -40
-KPX Racute Ucircumflex -40
-KPX Racute Udieresis -40
-KPX Racute Ugrave -40
-KPX Racute Uhungarumlaut -40
-KPX Racute Umacron -40
-KPX Racute Uogonek -40
-KPX Racute Uring -40
-KPX Racute V -50
-KPX Racute W -30
-KPX Racute Y -50
-KPX Racute Yacute -50
-KPX Racute Ydieresis -50
-KPX Rcaron O -20
-KPX Rcaron Oacute -20
-KPX Rcaron Ocircumflex -20
-KPX Rcaron Odieresis -20
-KPX Rcaron Ograve -20
-KPX Rcaron Ohungarumlaut -20
-KPX Rcaron Omacron -20
-KPX Rcaron Oslash -20
-KPX Rcaron Otilde -20
-KPX Rcaron T -30
-KPX Rcaron Tcaron -30
-KPX Rcaron Tcommaaccent -30
-KPX Rcaron U -40
-KPX Rcaron Uacute -40
-KPX Rcaron Ucircumflex -40
-KPX Rcaron Udieresis -40
-KPX Rcaron Ugrave -40
-KPX Rcaron Uhungarumlaut -40
-KPX Rcaron Umacron -40
-KPX Rcaron Uogonek -40
-KPX Rcaron Uring -40
-KPX Rcaron V -50
-KPX Rcaron W -30
-KPX Rcaron Y -50
-KPX Rcaron Yacute -50
-KPX Rcaron Ydieresis -50
-KPX Rcommaaccent O -20
-KPX Rcommaaccent Oacute -20
-KPX Rcommaaccent Ocircumflex -20
-KPX Rcommaaccent Odieresis -20
-KPX Rcommaaccent Ograve -20
-KPX Rcommaaccent Ohungarumlaut -20
-KPX Rcommaaccent Omacron -20
-KPX Rcommaaccent Oslash -20
-KPX Rcommaaccent Otilde -20
-KPX Rcommaaccent T -30
-KPX Rcommaaccent Tcaron -30
-KPX Rcommaaccent Tcommaaccent -30
-KPX Rcommaaccent U -40
-KPX Rcommaaccent Uacute -40
-KPX Rcommaaccent Ucircumflex -40
-KPX Rcommaaccent Udieresis -40
-KPX Rcommaaccent Ugrave -40
-KPX Rcommaaccent Uhungarumlaut -40
-KPX Rcommaaccent Umacron -40
-KPX Rcommaaccent Uogonek -40
-KPX Rcommaaccent Uring -40
-KPX Rcommaaccent V -50
-KPX Rcommaaccent W -30
-KPX Rcommaaccent Y -50
-KPX Rcommaaccent Yacute -50
-KPX Rcommaaccent Ydieresis -50
-KPX S comma -20
-KPX S period -20
-KPX Sacute comma -20
-KPX Sacute period -20
-KPX Scaron comma -20
-KPX Scaron period -20
-KPX Scedilla comma -20
-KPX Scedilla period -20
-KPX Scommaaccent comma -20
-KPX Scommaaccent period -20
-KPX T A -120
-KPX T Aacute -120
-KPX T Abreve -120
-KPX T Acircumflex -120
-KPX T Adieresis -120
-KPX T Agrave -120
-KPX T Amacron -120
-KPX T Aogonek -120
-KPX T Aring -120
-KPX T Atilde -120
-KPX T O -40
-KPX T Oacute -40
-KPX T Ocircumflex -40
-KPX T Odieresis -40
-KPX T Ograve -40
-KPX T Ohungarumlaut -40
-KPX T Omacron -40
-KPX T Oslash -40
-KPX T Otilde -40
-KPX T a -120
-KPX T aacute -120
-KPX T abreve -60
-KPX T acircumflex -120
-KPX T adieresis -120
-KPX T agrave -120
-KPX T amacron -60
-KPX T aogonek -120
-KPX T aring -120
-KPX T atilde -60
-KPX T colon -20
-KPX T comma -120
-KPX T e -120
-KPX T eacute -120
-KPX T ecaron -120
-KPX T ecircumflex -120
-KPX T edieresis -120
-KPX T edotaccent -120
-KPX T egrave -60
-KPX T emacron -60
-KPX T eogonek -120
-KPX T hyphen -140
-KPX T o -120
-KPX T oacute -120
-KPX T ocircumflex -120
-KPX T odieresis -120
-KPX T ograve -120
-KPX T ohungarumlaut -120
-KPX T omacron -60
-KPX T oslash -120
-KPX T otilde -60
-KPX T period -120
-KPX T r -120
-KPX T racute -120
-KPX T rcaron -120
-KPX T rcommaaccent -120
-KPX T semicolon -20
-KPX T u -120
-KPX T uacute -120
-KPX T ucircumflex -120
-KPX T udieresis -120
-KPX T ugrave -120
-KPX T uhungarumlaut -120
-KPX T umacron -60
-KPX T uogonek -120
-KPX T uring -120
-KPX T w -120
-KPX T y -120
-KPX T yacute -120
-KPX T ydieresis -60
-KPX Tcaron A -120
-KPX Tcaron Aacute -120
-KPX Tcaron Abreve -120
-KPX Tcaron Acircumflex -120
-KPX Tcaron Adieresis -120
-KPX Tcaron Agrave -120
-KPX Tcaron Amacron -120
-KPX Tcaron Aogonek -120
-KPX Tcaron Aring -120
-KPX Tcaron Atilde -120
-KPX Tcaron O -40
-KPX Tcaron Oacute -40
-KPX Tcaron Ocircumflex -40
-KPX Tcaron Odieresis -40
-KPX Tcaron Ograve -40
-KPX Tcaron Ohungarumlaut -40
-KPX Tcaron Omacron -40
-KPX Tcaron Oslash -40
-KPX Tcaron Otilde -40
-KPX Tcaron a -120
-KPX Tcaron aacute -120
-KPX Tcaron abreve -60
-KPX Tcaron acircumflex -120
-KPX Tcaron adieresis -120
-KPX Tcaron agrave -120
-KPX Tcaron amacron -60
-KPX Tcaron aogonek -120
-KPX Tcaron aring -120
-KPX Tcaron atilde -60
-KPX Tcaron colon -20
-KPX Tcaron comma -120
-KPX Tcaron e -120
-KPX Tcaron eacute -120
-KPX Tcaron ecaron -120
-KPX Tcaron ecircumflex -120
-KPX Tcaron edieresis -120
-KPX Tcaron edotaccent -120
-KPX Tcaron egrave -60
-KPX Tcaron emacron -60
-KPX Tcaron eogonek -120
-KPX Tcaron hyphen -140
-KPX Tcaron o -120
-KPX Tcaron oacute -120
-KPX Tcaron ocircumflex -120
-KPX Tcaron odieresis -120
-KPX Tcaron ograve -120
-KPX Tcaron ohungarumlaut -120
-KPX Tcaron omacron -60
-KPX Tcaron oslash -120
-KPX Tcaron otilde -60
-KPX Tcaron period -120
-KPX Tcaron r -120
-KPX Tcaron racute -120
-KPX Tcaron rcaron -120
-KPX Tcaron rcommaaccent -120
-KPX Tcaron semicolon -20
-KPX Tcaron u -120
-KPX Tcaron uacute -120
-KPX Tcaron ucircumflex -120
-KPX Tcaron udieresis -120
-KPX Tcaron ugrave -120
-KPX Tcaron uhungarumlaut -120
-KPX Tcaron umacron -60
-KPX Tcaron uogonek -120
-KPX Tcaron uring -120
-KPX Tcaron w -120
-KPX Tcaron y -120
-KPX Tcaron yacute -120
-KPX Tcaron ydieresis -60
-KPX Tcommaaccent A -120
-KPX Tcommaaccent Aacute -120
-KPX Tcommaaccent Abreve -120
-KPX Tcommaaccent Acircumflex -120
-KPX Tcommaaccent Adieresis -120
-KPX Tcommaaccent Agrave -120
-KPX Tcommaaccent Amacron -120
-KPX Tcommaaccent Aogonek -120
-KPX Tcommaaccent Aring -120
-KPX Tcommaaccent Atilde -120
-KPX Tcommaaccent O -40
-KPX Tcommaaccent Oacute -40
-KPX Tcommaaccent Ocircumflex -40
-KPX Tcommaaccent Odieresis -40
-KPX Tcommaaccent Ograve -40
-KPX Tcommaaccent Ohungarumlaut -40
-KPX Tcommaaccent Omacron -40
-KPX Tcommaaccent Oslash -40
-KPX Tcommaaccent Otilde -40
-KPX Tcommaaccent a -120
-KPX Tcommaaccent aacute -120
-KPX Tcommaaccent abreve -60
-KPX Tcommaaccent acircumflex -120
-KPX Tcommaaccent adieresis -120
-KPX Tcommaaccent agrave -120
-KPX Tcommaaccent amacron -60
-KPX Tcommaaccent aogonek -120
-KPX Tcommaaccent aring -120
-KPX Tcommaaccent atilde -60
-KPX Tcommaaccent colon -20
-KPX Tcommaaccent comma -120
-KPX Tcommaaccent e -120
-KPX Tcommaaccent eacute -120
-KPX Tcommaaccent ecaron -120
-KPX Tcommaaccent ecircumflex -120
-KPX Tcommaaccent edieresis -120
-KPX Tcommaaccent edotaccent -120
-KPX Tcommaaccent egrave -60
-KPX Tcommaaccent emacron -60
-KPX Tcommaaccent eogonek -120
-KPX Tcommaaccent hyphen -140
-KPX Tcommaaccent o -120
-KPX Tcommaaccent oacute -120
-KPX Tcommaaccent ocircumflex -120
-KPX Tcommaaccent odieresis -120
-KPX Tcommaaccent ograve -120
-KPX Tcommaaccent ohungarumlaut -120
-KPX Tcommaaccent omacron -60
-KPX Tcommaaccent oslash -120
-KPX Tcommaaccent otilde -60
-KPX Tcommaaccent period -120
-KPX Tcommaaccent r -120
-KPX Tcommaaccent racute -120
-KPX Tcommaaccent rcaron -120
-KPX Tcommaaccent rcommaaccent -120
-KPX Tcommaaccent semicolon -20
-KPX Tcommaaccent u -120
-KPX Tcommaaccent uacute -120
-KPX Tcommaaccent ucircumflex -120
-KPX Tcommaaccent udieresis -120
-KPX Tcommaaccent ugrave -120
-KPX Tcommaaccent uhungarumlaut -120
-KPX Tcommaaccent umacron -60
-KPX Tcommaaccent uogonek -120
-KPX Tcommaaccent uring -120
-KPX Tcommaaccent w -120
-KPX Tcommaaccent y -120
-KPX Tcommaaccent yacute -120
-KPX Tcommaaccent ydieresis -60
-KPX U A -40
-KPX U Aacute -40
-KPX U Abreve -40
-KPX U Acircumflex -40
-KPX U Adieresis -40
-KPX U Agrave -40
-KPX U Amacron -40
-KPX U Aogonek -40
-KPX U Aring -40
-KPX U Atilde -40
-KPX U comma -40
-KPX U period -40
-KPX Uacute A -40
-KPX Uacute Aacute -40
-KPX Uacute Abreve -40
-KPX Uacute Acircumflex -40
-KPX Uacute Adieresis -40
-KPX Uacute Agrave -40
-KPX Uacute Amacron -40
-KPX Uacute Aogonek -40
-KPX Uacute Aring -40
-KPX Uacute Atilde -40
-KPX Uacute comma -40
-KPX Uacute period -40
-KPX Ucircumflex A -40
-KPX Ucircumflex Aacute -40
-KPX Ucircumflex Abreve -40
-KPX Ucircumflex Acircumflex -40
-KPX Ucircumflex Adieresis -40
-KPX Ucircumflex Agrave -40
-KPX Ucircumflex Amacron -40
-KPX Ucircumflex Aogonek -40
-KPX Ucircumflex Aring -40
-KPX Ucircumflex Atilde -40
-KPX Ucircumflex comma -40
-KPX Ucircumflex period -40
-KPX Udieresis A -40
-KPX Udieresis Aacute -40
-KPX Udieresis Abreve -40
-KPX Udieresis Acircumflex -40
-KPX Udieresis Adieresis -40
-KPX Udieresis Agrave -40
-KPX Udieresis Amacron -40
-KPX Udieresis Aogonek -40
-KPX Udieresis Aring -40
-KPX Udieresis Atilde -40
-KPX Udieresis comma -40
-KPX Udieresis period -40
-KPX Ugrave A -40
-KPX Ugrave Aacute -40
-KPX Ugrave Abreve -40
-KPX Ugrave Acircumflex -40
-KPX Ugrave Adieresis -40
-KPX Ugrave Agrave -40
-KPX Ugrave Amacron -40
-KPX Ugrave Aogonek -40
-KPX Ugrave Aring -40
-KPX Ugrave Atilde -40
-KPX Ugrave comma -40
-KPX Ugrave period -40
-KPX Uhungarumlaut A -40
-KPX Uhungarumlaut Aacute -40
-KPX Uhungarumlaut Abreve -40
-KPX Uhungarumlaut Acircumflex -40
-KPX Uhungarumlaut Adieresis -40
-KPX Uhungarumlaut Agrave -40
-KPX Uhungarumlaut Amacron -40
-KPX Uhungarumlaut Aogonek -40
-KPX Uhungarumlaut Aring -40
-KPX Uhungarumlaut Atilde -40
-KPX Uhungarumlaut comma -40
-KPX Uhungarumlaut period -40
-KPX Umacron A -40
-KPX Umacron Aacute -40
-KPX Umacron Abreve -40
-KPX Umacron Acircumflex -40
-KPX Umacron Adieresis -40
-KPX Umacron Agrave -40
-KPX Umacron Amacron -40
-KPX Umacron Aogonek -40
-KPX Umacron Aring -40
-KPX Umacron Atilde -40
-KPX Umacron comma -40
-KPX Umacron period -40
-KPX Uogonek A -40
-KPX Uogonek Aacute -40
-KPX Uogonek Abreve -40
-KPX Uogonek Acircumflex -40
-KPX Uogonek Adieresis -40
-KPX Uogonek Agrave -40
-KPX Uogonek Amacron -40
-KPX Uogonek Aogonek -40
-KPX Uogonek Aring -40
-KPX Uogonek Atilde -40
-KPX Uogonek comma -40
-KPX Uogonek period -40
-KPX Uring A -40
-KPX Uring Aacute -40
-KPX Uring Abreve -40
-KPX Uring Acircumflex -40
-KPX Uring Adieresis -40
-KPX Uring Agrave -40
-KPX Uring Amacron -40
-KPX Uring Aogonek -40
-KPX Uring Aring -40
-KPX Uring Atilde -40
-KPX Uring comma -40
-KPX Uring period -40
-KPX V A -80
-KPX V Aacute -80
-KPX V Abreve -80
-KPX V Acircumflex -80
-KPX V Adieresis -80
-KPX V Agrave -80
-KPX V Amacron -80
-KPX V Aogonek -80
-KPX V Aring -80
-KPX V Atilde -80
-KPX V G -40
-KPX V Gbreve -40
-KPX V Gcommaaccent -40
-KPX V O -40
-KPX V Oacute -40
-KPX V Ocircumflex -40
-KPX V Odieresis -40
-KPX V Ograve -40
-KPX V Ohungarumlaut -40
-KPX V Omacron -40
-KPX V Oslash -40
-KPX V Otilde -40
-KPX V a -70
-KPX V aacute -70
-KPX V abreve -70
-KPX V acircumflex -70
-KPX V adieresis -70
-KPX V agrave -70
-KPX V amacron -70
-KPX V aogonek -70
-KPX V aring -70
-KPX V atilde -70
-KPX V colon -40
-KPX V comma -125
-KPX V e -80
-KPX V eacute -80
-KPX V ecaron -80
-KPX V ecircumflex -80
-KPX V edieresis -80
-KPX V edotaccent -80
-KPX V egrave -80
-KPX V emacron -80
-KPX V eogonek -80
-KPX V hyphen -80
-KPX V o -80
-KPX V oacute -80
-KPX V ocircumflex -80
-KPX V odieresis -80
-KPX V ograve -80
-KPX V ohungarumlaut -80
-KPX V omacron -80
-KPX V oslash -80
-KPX V otilde -80
-KPX V period -125
-KPX V semicolon -40
-KPX V u -70
-KPX V uacute -70
-KPX V ucircumflex -70
-KPX V udieresis -70
-KPX V ugrave -70
-KPX V uhungarumlaut -70
-KPX V umacron -70
-KPX V uogonek -70
-KPX V uring -70
-KPX W A -50
-KPX W Aacute -50
-KPX W Abreve -50
-KPX W Acircumflex -50
-KPX W Adieresis -50
-KPX W Agrave -50
-KPX W Amacron -50
-KPX W Aogonek -50
-KPX W Aring -50
-KPX W Atilde -50
-KPX W O -20
-KPX W Oacute -20
-KPX W Ocircumflex -20
-KPX W Odieresis -20
-KPX W Ograve -20
-KPX W Ohungarumlaut -20
-KPX W Omacron -20
-KPX W Oslash -20
-KPX W Otilde -20
-KPX W a -40
-KPX W aacute -40
-KPX W abreve -40
-KPX W acircumflex -40
-KPX W adieresis -40
-KPX W agrave -40
-KPX W amacron -40
-KPX W aogonek -40
-KPX W aring -40
-KPX W atilde -40
-KPX W comma -80
-KPX W e -30
-KPX W eacute -30
-KPX W ecaron -30
-KPX W ecircumflex -30
-KPX W edieresis -30
-KPX W edotaccent -30
-KPX W egrave -30
-KPX W emacron -30
-KPX W eogonek -30
-KPX W hyphen -40
-KPX W o -30
-KPX W oacute -30
-KPX W ocircumflex -30
-KPX W odieresis -30
-KPX W ograve -30
-KPX W ohungarumlaut -30
-KPX W omacron -30
-KPX W oslash -30
-KPX W otilde -30
-KPX W period -80
-KPX W u -30
-KPX W uacute -30
-KPX W ucircumflex -30
-KPX W udieresis -30
-KPX W ugrave -30
-KPX W uhungarumlaut -30
-KPX W umacron -30
-KPX W uogonek -30
-KPX W uring -30
-KPX W y -20
-KPX W yacute -20
-KPX W ydieresis -20
-KPX Y A -110
-KPX Y Aacute -110
-KPX Y Abreve -110
-KPX Y Acircumflex -110
-KPX Y Adieresis -110
-KPX Y Agrave -110
-KPX Y Amacron -110
-KPX Y Aogonek -110
-KPX Y Aring -110
-KPX Y Atilde -110
-KPX Y O -85
-KPX Y Oacute -85
-KPX Y Ocircumflex -85
-KPX Y Odieresis -85
-KPX Y Ograve -85
-KPX Y Ohungarumlaut -85
-KPX Y Omacron -85
-KPX Y Oslash -85
-KPX Y Otilde -85
-KPX Y a -140
-KPX Y aacute -140
-KPX Y abreve -70
-KPX Y acircumflex -140
-KPX Y adieresis -140
-KPX Y agrave -140
-KPX Y amacron -70
-KPX Y aogonek -140
-KPX Y aring -140
-KPX Y atilde -140
-KPX Y colon -60
-KPX Y comma -140
-KPX Y e -140
-KPX Y eacute -140
-KPX Y ecaron -140
-KPX Y ecircumflex -140
-KPX Y edieresis -140
-KPX Y edotaccent -140
-KPX Y egrave -140
-KPX Y emacron -70
-KPX Y eogonek -140
-KPX Y hyphen -140
-KPX Y i -20
-KPX Y iacute -20
-KPX Y iogonek -20
-KPX Y o -140
-KPX Y oacute -140
-KPX Y ocircumflex -140
-KPX Y odieresis -140
-KPX Y ograve -140
-KPX Y ohungarumlaut -140
-KPX Y omacron -140
-KPX Y oslash -140
-KPX Y otilde -140
-KPX Y period -140
-KPX Y semicolon -60
-KPX Y u -110
-KPX Y uacute -110
-KPX Y ucircumflex -110
-KPX Y udieresis -110
-KPX Y ugrave -110
-KPX Y uhungarumlaut -110
-KPX Y umacron -110
-KPX Y uogonek -110
-KPX Y uring -110
-KPX Yacute A -110
-KPX Yacute Aacute -110
-KPX Yacute Abreve -110
-KPX Yacute Acircumflex -110
-KPX Yacute Adieresis -110
-KPX Yacute Agrave -110
-KPX Yacute Amacron -110
-KPX Yacute Aogonek -110
-KPX Yacute Aring -110
-KPX Yacute Atilde -110
-KPX Yacute O -85
-KPX Yacute Oacute -85
-KPX Yacute Ocircumflex -85
-KPX Yacute Odieresis -85
-KPX Yacute Ograve -85
-KPX Yacute Ohungarumlaut -85
-KPX Yacute Omacron -85
-KPX Yacute Oslash -85
-KPX Yacute Otilde -85
-KPX Yacute a -140
-KPX Yacute aacute -140
-KPX Yacute abreve -70
-KPX Yacute acircumflex -140
-KPX Yacute adieresis -140
-KPX Yacute agrave -140
-KPX Yacute amacron -70
-KPX Yacute aogonek -140
-KPX Yacute aring -140
-KPX Yacute atilde -70
-KPX Yacute colon -60
-KPX Yacute comma -140
-KPX Yacute e -140
-KPX Yacute eacute -140
-KPX Yacute ecaron -140
-KPX Yacute ecircumflex -140
-KPX Yacute edieresis -140
-KPX Yacute edotaccent -140
-KPX Yacute egrave -140
-KPX Yacute emacron -70
-KPX Yacute eogonek -140
-KPX Yacute hyphen -140
-KPX Yacute i -20
-KPX Yacute iacute -20
-KPX Yacute iogonek -20
-KPX Yacute o -140
-KPX Yacute oacute -140
-KPX Yacute ocircumflex -140
-KPX Yacute odieresis -140
-KPX Yacute ograve -140
-KPX Yacute ohungarumlaut -140
-KPX Yacute omacron -70
-KPX Yacute oslash -140
-KPX Yacute otilde -140
-KPX Yacute period -140
-KPX Yacute semicolon -60
-KPX Yacute u -110
-KPX Yacute uacute -110
-KPX Yacute ucircumflex -110
-KPX Yacute udieresis -110
-KPX Yacute ugrave -110
-KPX Yacute uhungarumlaut -110
-KPX Yacute umacron -110
-KPX Yacute uogonek -110
-KPX Yacute uring -110
-KPX Ydieresis A -110
-KPX Ydieresis Aacute -110
-KPX Ydieresis Abreve -110
-KPX Ydieresis Acircumflex -110
-KPX Ydieresis Adieresis -110
-KPX Ydieresis Agrave -110
-KPX Ydieresis Amacron -110
-KPX Ydieresis Aogonek -110
-KPX Ydieresis Aring -110
-KPX Ydieresis Atilde -110
-KPX Ydieresis O -85
-KPX Ydieresis Oacute -85
-KPX Ydieresis Ocircumflex -85
-KPX Ydieresis Odieresis -85
-KPX Ydieresis Ograve -85
-KPX Ydieresis Ohungarumlaut -85
-KPX Ydieresis Omacron -85
-KPX Ydieresis Oslash -85
-KPX Ydieresis Otilde -85
-KPX Ydieresis a -140
-KPX Ydieresis aacute -140
-KPX Ydieresis abreve -70
-KPX Ydieresis acircumflex -140
-KPX Ydieresis adieresis -140
-KPX Ydieresis agrave -140
-KPX Ydieresis amacron -70
-KPX Ydieresis aogonek -140
-KPX Ydieresis aring -140
-KPX Ydieresis atilde -70
-KPX Ydieresis colon -60
-KPX Ydieresis comma -140
-KPX Ydieresis e -140
-KPX Ydieresis eacute -140
-KPX Ydieresis ecaron -140
-KPX Ydieresis ecircumflex -140
-KPX Ydieresis edieresis -140
-KPX Ydieresis edotaccent -140
-KPX Ydieresis egrave -140
-KPX Ydieresis emacron -70
-KPX Ydieresis eogonek -140
-KPX Ydieresis hyphen -140
-KPX Ydieresis i -20
-KPX Ydieresis iacute -20
-KPX Ydieresis iogonek -20
-KPX Ydieresis o -140
-KPX Ydieresis oacute -140
-KPX Ydieresis ocircumflex -140
-KPX Ydieresis odieresis -140
-KPX Ydieresis ograve -140
-KPX Ydieresis ohungarumlaut -140
-KPX Ydieresis omacron -140
-KPX Ydieresis oslash -140
-KPX Ydieresis otilde -140
-KPX Ydieresis period -140
-KPX Ydieresis semicolon -60
-KPX Ydieresis u -110
-KPX Ydieresis uacute -110
-KPX Ydieresis ucircumflex -110
-KPX Ydieresis udieresis -110
-KPX Ydieresis ugrave -110
-KPX Ydieresis uhungarumlaut -110
-KPX Ydieresis umacron -110
-KPX Ydieresis uogonek -110
-KPX Ydieresis uring -110
-KPX a v -20
-KPX a w -20
-KPX a y -30
-KPX a yacute -30
-KPX a ydieresis -30
-KPX aacute v -20
-KPX aacute w -20
-KPX aacute y -30
-KPX aacute yacute -30
-KPX aacute ydieresis -30
-KPX abreve v -20
-KPX abreve w -20
-KPX abreve y -30
-KPX abreve yacute -30
-KPX abreve ydieresis -30
-KPX acircumflex v -20
-KPX acircumflex w -20
-KPX acircumflex y -30
-KPX acircumflex yacute -30
-KPX acircumflex ydieresis -30
-KPX adieresis v -20
-KPX adieresis w -20
-KPX adieresis y -30
-KPX adieresis yacute -30
-KPX adieresis ydieresis -30
-KPX agrave v -20
-KPX agrave w -20
-KPX agrave y -30
-KPX agrave yacute -30
-KPX agrave ydieresis -30
-KPX amacron v -20
-KPX amacron w -20
-KPX amacron y -30
-KPX amacron yacute -30
-KPX amacron ydieresis -30
-KPX aogonek v -20
-KPX aogonek w -20
-KPX aogonek y -30
-KPX aogonek yacute -30
-KPX aogonek ydieresis -30
-KPX aring v -20
-KPX aring w -20
-KPX aring y -30
-KPX aring yacute -30
-KPX aring ydieresis -30
-KPX atilde v -20
-KPX atilde w -20
-KPX atilde y -30
-KPX atilde yacute -30
-KPX atilde ydieresis -30
-KPX b b -10
-KPX b comma -40
-KPX b l -20
-KPX b lacute -20
-KPX b lcommaaccent -20
-KPX b lslash -20
-KPX b period -40
-KPX b u -20
-KPX b uacute -20
-KPX b ucircumflex -20
-KPX b udieresis -20
-KPX b ugrave -20
-KPX b uhungarumlaut -20
-KPX b umacron -20
-KPX b uogonek -20
-KPX b uring -20
-KPX b v -20
-KPX b y -20
-KPX b yacute -20
-KPX b ydieresis -20
-KPX c comma -15
-KPX c k -20
-KPX c kcommaaccent -20
-KPX cacute comma -15
-KPX cacute k -20
-KPX cacute kcommaaccent -20
-KPX ccaron comma -15
-KPX ccaron k -20
-KPX ccaron kcommaaccent -20
-KPX ccedilla comma -15
-KPX ccedilla k -20
-KPX ccedilla kcommaaccent -20
-KPX colon space -50
-KPX comma quotedblright -100
-KPX comma quoteright -100
-KPX e comma -15
-KPX e period -15
-KPX e v -30
-KPX e w -20
-KPX e x -30
-KPX e y -20
-KPX e yacute -20
-KPX e ydieresis -20
-KPX eacute comma -15
-KPX eacute period -15
-KPX eacute v -30
-KPX eacute w -20
-KPX eacute x -30
-KPX eacute y -20
-KPX eacute yacute -20
-KPX eacute ydieresis -20
-KPX ecaron comma -15
-KPX ecaron period -15
-KPX ecaron v -30
-KPX ecaron w -20
-KPX ecaron x -30
-KPX ecaron y -20
-KPX ecaron yacute -20
-KPX ecaron ydieresis -20
-KPX ecircumflex comma -15
-KPX ecircumflex period -15
-KPX ecircumflex v -30
-KPX ecircumflex w -20
-KPX ecircumflex x -30
-KPX ecircumflex y -20
-KPX ecircumflex yacute -20
-KPX ecircumflex ydieresis -20
-KPX edieresis comma -15
-KPX edieresis period -15
-KPX edieresis v -30
-KPX edieresis w -20
-KPX edieresis x -30
-KPX edieresis y -20
-KPX edieresis yacute -20
-KPX edieresis ydieresis -20
-KPX edotaccent comma -15
-KPX edotaccent period -15
-KPX edotaccent v -30
-KPX edotaccent w -20
-KPX edotaccent x -30
-KPX edotaccent y -20
-KPX edotaccent yacute -20
-KPX edotaccent ydieresis -20
-KPX egrave comma -15
-KPX egrave period -15
-KPX egrave v -30
-KPX egrave w -20
-KPX egrave x -30
-KPX egrave y -20
-KPX egrave yacute -20
-KPX egrave ydieresis -20
-KPX emacron comma -15
-KPX emacron period -15
-KPX emacron v -30
-KPX emacron w -20
-KPX emacron x -30
-KPX emacron y -20
-KPX emacron yacute -20
-KPX emacron ydieresis -20
-KPX eogonek comma -15
-KPX eogonek period -15
-KPX eogonek v -30
-KPX eogonek w -20
-KPX eogonek x -30
-KPX eogonek y -20
-KPX eogonek yacute -20
-KPX eogonek ydieresis -20
-KPX f a -30
-KPX f aacute -30
-KPX f abreve -30
-KPX f acircumflex -30
-KPX f adieresis -30
-KPX f agrave -30
-KPX f amacron -30
-KPX f aogonek -30
-KPX f aring -30
-KPX f atilde -30
-KPX f comma -30
-KPX f dotlessi -28
-KPX f e -30
-KPX f eacute -30
-KPX f ecaron -30
-KPX f ecircumflex -30
-KPX f edieresis -30
-KPX f edotaccent -30
-KPX f egrave -30
-KPX f emacron -30
-KPX f eogonek -30
-KPX f o -30
-KPX f oacute -30
-KPX f ocircumflex -30
-KPX f odieresis -30
-KPX f ograve -30
-KPX f ohungarumlaut -30
-KPX f omacron -30
-KPX f oslash -30
-KPX f otilde -30
-KPX f period -30
-KPX f quotedblright 60
-KPX f quoteright 50
-KPX g r -10
-KPX g racute -10
-KPX g rcaron -10
-KPX g rcommaaccent -10
-KPX gbreve r -10
-KPX gbreve racute -10
-KPX gbreve rcaron -10
-KPX gbreve rcommaaccent -10
-KPX gcommaaccent r -10
-KPX gcommaaccent racute -10
-KPX gcommaaccent rcaron -10
-KPX gcommaaccent rcommaaccent -10
-KPX h y -30
-KPX h yacute -30
-KPX h ydieresis -30
-KPX k e -20
-KPX k eacute -20
-KPX k ecaron -20
-KPX k ecircumflex -20
-KPX k edieresis -20
-KPX k edotaccent -20
-KPX k egrave -20
-KPX k emacron -20
-KPX k eogonek -20
-KPX k o -20
-KPX k oacute -20
-KPX k ocircumflex -20
-KPX k odieresis -20
-KPX k ograve -20
-KPX k ohungarumlaut -20
-KPX k omacron -20
-KPX k oslash -20
-KPX k otilde -20
-KPX kcommaaccent e -20
-KPX kcommaaccent eacute -20
-KPX kcommaaccent ecaron -20
-KPX kcommaaccent ecircumflex -20
-KPX kcommaaccent edieresis -20
-KPX kcommaaccent edotaccent -20
-KPX kcommaaccent egrave -20
-KPX kcommaaccent emacron -20
-KPX kcommaaccent eogonek -20
-KPX kcommaaccent o -20
-KPX kcommaaccent oacute -20
-KPX kcommaaccent ocircumflex -20
-KPX kcommaaccent odieresis -20
-KPX kcommaaccent ograve -20
-KPX kcommaaccent ohungarumlaut -20
-KPX kcommaaccent omacron -20
-KPX kcommaaccent oslash -20
-KPX kcommaaccent otilde -20
-KPX m u -10
-KPX m uacute -10
-KPX m ucircumflex -10
-KPX m udieresis -10
-KPX m ugrave -10
-KPX m uhungarumlaut -10
-KPX m umacron -10
-KPX m uogonek -10
-KPX m uring -10
-KPX m y -15
-KPX m yacute -15
-KPX m ydieresis -15
-KPX n u -10
-KPX n uacute -10
-KPX n ucircumflex -10
-KPX n udieresis -10
-KPX n ugrave -10
-KPX n uhungarumlaut -10
-KPX n umacron -10
-KPX n uogonek -10
-KPX n uring -10
-KPX n v -20
-KPX n y -15
-KPX n yacute -15
-KPX n ydieresis -15
-KPX nacute u -10
-KPX nacute uacute -10
-KPX nacute ucircumflex -10
-KPX nacute udieresis -10
-KPX nacute ugrave -10
-KPX nacute uhungarumlaut -10
-KPX nacute umacron -10
-KPX nacute uogonek -10
-KPX nacute uring -10
-KPX nacute v -20
-KPX nacute y -15
-KPX nacute yacute -15
-KPX nacute ydieresis -15
-KPX ncaron u -10
-KPX ncaron uacute -10
-KPX ncaron ucircumflex -10
-KPX ncaron udieresis -10
-KPX ncaron ugrave -10
-KPX ncaron uhungarumlaut -10
-KPX ncaron umacron -10
-KPX ncaron uogonek -10
-KPX ncaron uring -10
-KPX ncaron v -20
-KPX ncaron y -15
-KPX ncaron yacute -15
-KPX ncaron ydieresis -15
-KPX ncommaaccent u -10
-KPX ncommaaccent uacute -10
-KPX ncommaaccent ucircumflex -10
-KPX ncommaaccent udieresis -10
-KPX ncommaaccent ugrave -10
-KPX ncommaaccent uhungarumlaut -10
-KPX ncommaaccent umacron -10
-KPX ncommaaccent uogonek -10
-KPX ncommaaccent uring -10
-KPX ncommaaccent v -20
-KPX ncommaaccent y -15
-KPX ncommaaccent yacute -15
-KPX ncommaaccent ydieresis -15
-KPX ntilde u -10
-KPX ntilde uacute -10
-KPX ntilde ucircumflex -10
-KPX ntilde udieresis -10
-KPX ntilde ugrave -10
-KPX ntilde uhungarumlaut -10
-KPX ntilde umacron -10
-KPX ntilde uogonek -10
-KPX ntilde uring -10
-KPX ntilde v -20
-KPX ntilde y -15
-KPX ntilde yacute -15
-KPX ntilde ydieresis -15
-KPX o comma -40
-KPX o period -40
-KPX o v -15
-KPX o w -15
-KPX o x -30
-KPX o y -30
-KPX o yacute -30
-KPX o ydieresis -30
-KPX oacute comma -40
-KPX oacute period -40
-KPX oacute v -15
-KPX oacute w -15
-KPX oacute x -30
-KPX oacute y -30
-KPX oacute yacute -30
-KPX oacute ydieresis -30
-KPX ocircumflex comma -40
-KPX ocircumflex period -40
-KPX ocircumflex v -15
-KPX ocircumflex w -15
-KPX ocircumflex x -30
-KPX ocircumflex y -30
-KPX ocircumflex yacute -30
-KPX ocircumflex ydieresis -30
-KPX odieresis comma -40
-KPX odieresis period -40
-KPX odieresis v -15
-KPX odieresis w -15
-KPX odieresis x -30
-KPX odieresis y -30
-KPX odieresis yacute -30
-KPX odieresis ydieresis -30
-KPX ograve comma -40
-KPX ograve period -40
-KPX ograve v -15
-KPX ograve w -15
-KPX ograve x -30
-KPX ograve y -30
-KPX ograve yacute -30
-KPX ograve ydieresis -30
-KPX ohungarumlaut comma -40
-KPX ohungarumlaut period -40
-KPX ohungarumlaut v -15
-KPX ohungarumlaut w -15
-KPX ohungarumlaut x -30
-KPX ohungarumlaut y -30
-KPX ohungarumlaut yacute -30
-KPX ohungarumlaut ydieresis -30
-KPX omacron comma -40
-KPX omacron period -40
-KPX omacron v -15
-KPX omacron w -15
-KPX omacron x -30
-KPX omacron y -30
-KPX omacron yacute -30
-KPX omacron ydieresis -30
-KPX oslash a -55
-KPX oslash aacute -55
-KPX oslash abreve -55
-KPX oslash acircumflex -55
-KPX oslash adieresis -55
-KPX oslash agrave -55
-KPX oslash amacron -55
-KPX oslash aogonek -55
-KPX oslash aring -55
-KPX oslash atilde -55
-KPX oslash b -55
-KPX oslash c -55
-KPX oslash cacute -55
-KPX oslash ccaron -55
-KPX oslash ccedilla -55
-KPX oslash comma -95
-KPX oslash d -55
-KPX oslash dcroat -55
-KPX oslash e -55
-KPX oslash eacute -55
-KPX oslash ecaron -55
-KPX oslash ecircumflex -55
-KPX oslash edieresis -55
-KPX oslash edotaccent -55
-KPX oslash egrave -55
-KPX oslash emacron -55
-KPX oslash eogonek -55
-KPX oslash f -55
-KPX oslash g -55
-KPX oslash gbreve -55
-KPX oslash gcommaaccent -55
-KPX oslash h -55
-KPX oslash i -55
-KPX oslash iacute -55
-KPX oslash icircumflex -55
-KPX oslash idieresis -55
-KPX oslash igrave -55
-KPX oslash imacron -55
-KPX oslash iogonek -55
-KPX oslash j -55
-KPX oslash k -55
-KPX oslash kcommaaccent -55
-KPX oslash l -55
-KPX oslash lacute -55
-KPX oslash lcommaaccent -55
-KPX oslash lslash -55
-KPX oslash m -55
-KPX oslash n -55
-KPX oslash nacute -55
-KPX oslash ncaron -55
-KPX oslash ncommaaccent -55
-KPX oslash ntilde -55
-KPX oslash o -55
-KPX oslash oacute -55
-KPX oslash ocircumflex -55
-KPX oslash odieresis -55
-KPX oslash ograve -55
-KPX oslash ohungarumlaut -55
-KPX oslash omacron -55
-KPX oslash oslash -55
-KPX oslash otilde -55
-KPX oslash p -55
-KPX oslash period -95
-KPX oslash q -55
-KPX oslash r -55
-KPX oslash racute -55
-KPX oslash rcaron -55
-KPX oslash rcommaaccent -55
-KPX oslash s -55
-KPX oslash sacute -55
-KPX oslash scaron -55
-KPX oslash scedilla -55
-KPX oslash scommaaccent -55
-KPX oslash t -55
-KPX oslash tcommaaccent -55
-KPX oslash u -55
-KPX oslash uacute -55
-KPX oslash ucircumflex -55
-KPX oslash udieresis -55
-KPX oslash ugrave -55
-KPX oslash uhungarumlaut -55
-KPX oslash umacron -55
-KPX oslash uogonek -55
-KPX oslash uring -55
-KPX oslash v -70
-KPX oslash w -70
-KPX oslash x -85
-KPX oslash y -70
-KPX oslash yacute -70
-KPX oslash ydieresis -70
-KPX oslash z -55
-KPX oslash zacute -55
-KPX oslash zcaron -55
-KPX oslash zdotaccent -55
-KPX otilde comma -40
-KPX otilde period -40
-KPX otilde v -15
-KPX otilde w -15
-KPX otilde x -30
-KPX otilde y -30
-KPX otilde yacute -30
-KPX otilde ydieresis -30
-KPX p comma -35
-KPX p period -35
-KPX p y -30
-KPX p yacute -30
-KPX p ydieresis -30
-KPX period quotedblright -100
-KPX period quoteright -100
-KPX period space -60
-KPX quotedblright space -40
-KPX quoteleft quoteleft -57
-KPX quoteright d -50
-KPX quoteright dcroat -50
-KPX quoteright quoteright -57
-KPX quoteright r -50
-KPX quoteright racute -50
-KPX quoteright rcaron -50
-KPX quoteright rcommaaccent -50
-KPX quoteright s -50
-KPX quoteright sacute -50
-KPX quoteright scaron -50
-KPX quoteright scedilla -50
-KPX quoteright scommaaccent -50
-KPX quoteright space -70
-KPX r a -10
-KPX r aacute -10
-KPX r abreve -10
-KPX r acircumflex -10
-KPX r adieresis -10
-KPX r agrave -10
-KPX r amacron -10
-KPX r aogonek -10
-KPX r aring -10
-KPX r atilde -10
-KPX r colon 30
-KPX r comma -50
-KPX r i 15
-KPX r iacute 15
-KPX r icircumflex 15
-KPX r idieresis 15
-KPX r igrave 15
-KPX r imacron 15
-KPX r iogonek 15
-KPX r k 15
-KPX r kcommaaccent 15
-KPX r l 15
-KPX r lacute 15
-KPX r lcommaaccent 15
-KPX r lslash 15
-KPX r m 25
-KPX r n 25
-KPX r nacute 25
-KPX r ncaron 25
-KPX r ncommaaccent 25
-KPX r ntilde 25
-KPX r p 30
-KPX r period -50
-KPX r semicolon 30
-KPX r t 40
-KPX r tcommaaccent 40
-KPX r u 15
-KPX r uacute 15
-KPX r ucircumflex 15
-KPX r udieresis 15
-KPX r ugrave 15
-KPX r uhungarumlaut 15
-KPX r umacron 15
-KPX r uogonek 15
-KPX r uring 15
-KPX r v 30
-KPX r y 30
-KPX r yacute 30
-KPX r ydieresis 30
-KPX racute a -10
-KPX racute aacute -10
-KPX racute abreve -10
-KPX racute acircumflex -10
-KPX racute adieresis -10
-KPX racute agrave -10
-KPX racute amacron -10
-KPX racute aogonek -10
-KPX racute aring -10
-KPX racute atilde -10
-KPX racute colon 30
-KPX racute comma -50
-KPX racute i 15
-KPX racute iacute 15
-KPX racute icircumflex 15
-KPX racute idieresis 15
-KPX racute igrave 15
-KPX racute imacron 15
-KPX racute iogonek 15
-KPX racute k 15
-KPX racute kcommaaccent 15
-KPX racute l 15
-KPX racute lacute 15
-KPX racute lcommaaccent 15
-KPX racute lslash 15
-KPX racute m 25
-KPX racute n 25
-KPX racute nacute 25
-KPX racute ncaron 25
-KPX racute ncommaaccent 25
-KPX racute ntilde 25
-KPX racute p 30
-KPX racute period -50
-KPX racute semicolon 30
-KPX racute t 40
-KPX racute tcommaaccent 40
-KPX racute u 15
-KPX racute uacute 15
-KPX racute ucircumflex 15
-KPX racute udieresis 15
-KPX racute ugrave 15
-KPX racute uhungarumlaut 15
-KPX racute umacron 15
-KPX racute uogonek 15
-KPX racute uring 15
-KPX racute v 30
-KPX racute y 30
-KPX racute yacute 30
-KPX racute ydieresis 30
-KPX rcaron a -10
-KPX rcaron aacute -10
-KPX rcaron abreve -10
-KPX rcaron acircumflex -10
-KPX rcaron adieresis -10
-KPX rcaron agrave -10
-KPX rcaron amacron -10
-KPX rcaron aogonek -10
-KPX rcaron aring -10
-KPX rcaron atilde -10
-KPX rcaron colon 30
-KPX rcaron comma -50
-KPX rcaron i 15
-KPX rcaron iacute 15
-KPX rcaron icircumflex 15
-KPX rcaron idieresis 15
-KPX rcaron igrave 15
-KPX rcaron imacron 15
-KPX rcaron iogonek 15
-KPX rcaron k 15
-KPX rcaron kcommaaccent 15
-KPX rcaron l 15
-KPX rcaron lacute 15
-KPX rcaron lcommaaccent 15
-KPX rcaron lslash 15
-KPX rcaron m 25
-KPX rcaron n 25
-KPX rcaron nacute 25
-KPX rcaron ncaron 25
-KPX rcaron ncommaaccent 25
-KPX rcaron ntilde 25
-KPX rcaron p 30
-KPX rcaron period -50
-KPX rcaron semicolon 30
-KPX rcaron t 40
-KPX rcaron tcommaaccent 40
-KPX rcaron u 15
-KPX rcaron uacute 15
-KPX rcaron ucircumflex 15
-KPX rcaron udieresis 15
-KPX rcaron ugrave 15
-KPX rcaron uhungarumlaut 15
-KPX rcaron umacron 15
-KPX rcaron uogonek 15
-KPX rcaron uring 15
-KPX rcaron v 30
-KPX rcaron y 30
-KPX rcaron yacute 30
-KPX rcaron ydieresis 30
-KPX rcommaaccent a -10
-KPX rcommaaccent aacute -10
-KPX rcommaaccent abreve -10
-KPX rcommaaccent acircumflex -10
-KPX rcommaaccent adieresis -10
-KPX rcommaaccent agrave -10
-KPX rcommaaccent amacron -10
-KPX rcommaaccent aogonek -10
-KPX rcommaaccent aring -10
-KPX rcommaaccent atilde -10
-KPX rcommaaccent colon 30
-KPX rcommaaccent comma -50
-KPX rcommaaccent i 15
-KPX rcommaaccent iacute 15
-KPX rcommaaccent icircumflex 15
-KPX rcommaaccent idieresis 15
-KPX rcommaaccent igrave 15
-KPX rcommaaccent imacron 15
-KPX rcommaaccent iogonek 15
-KPX rcommaaccent k 15
-KPX rcommaaccent kcommaaccent 15
-KPX rcommaaccent l 15
-KPX rcommaaccent lacute 15
-KPX rcommaaccent lcommaaccent 15
-KPX rcommaaccent lslash 15
-KPX rcommaaccent m 25
-KPX rcommaaccent n 25
-KPX rcommaaccent nacute 25
-KPX rcommaaccent ncaron 25
-KPX rcommaaccent ncommaaccent 25
-KPX rcommaaccent ntilde 25
-KPX rcommaaccent p 30
-KPX rcommaaccent period -50
-KPX rcommaaccent semicolon 30
-KPX rcommaaccent t 40
-KPX rcommaaccent tcommaaccent 40
-KPX rcommaaccent u 15
-KPX rcommaaccent uacute 15
-KPX rcommaaccent ucircumflex 15
-KPX rcommaaccent udieresis 15
-KPX rcommaaccent ugrave 15
-KPX rcommaaccent uhungarumlaut 15
-KPX rcommaaccent umacron 15
-KPX rcommaaccent uogonek 15
-KPX rcommaaccent uring 15
-KPX rcommaaccent v 30
-KPX rcommaaccent y 30
-KPX rcommaaccent yacute 30
-KPX rcommaaccent ydieresis 30
-KPX s comma -15
-KPX s period -15
-KPX s w -30
-KPX sacute comma -15
-KPX sacute period -15
-KPX sacute w -30
-KPX scaron comma -15
-KPX scaron period -15
-KPX scaron w -30
-KPX scedilla comma -15
-KPX scedilla period -15
-KPX scedilla w -30
-KPX scommaaccent comma -15
-KPX scommaaccent period -15
-KPX scommaaccent w -30
-KPX semicolon space -50
-KPX space T -50
-KPX space Tcaron -50
-KPX space Tcommaaccent -50
-KPX space V -50
-KPX space W -40
-KPX space Y -90
-KPX space Yacute -90
-KPX space Ydieresis -90
-KPX space quotedblleft -30
-KPX space quoteleft -60
-KPX v a -25
-KPX v aacute -25
-KPX v abreve -25
-KPX v acircumflex -25
-KPX v adieresis -25
-KPX v agrave -25
-KPX v amacron -25
-KPX v aogonek -25
-KPX v aring -25
-KPX v atilde -25
-KPX v comma -80
-KPX v e -25
-KPX v eacute -25
-KPX v ecaron -25
-KPX v ecircumflex -25
-KPX v edieresis -25
-KPX v edotaccent -25
-KPX v egrave -25
-KPX v emacron -25
-KPX v eogonek -25
-KPX v o -25
-KPX v oacute -25
-KPX v ocircumflex -25
-KPX v odieresis -25
-KPX v ograve -25
-KPX v ohungarumlaut -25
-KPX v omacron -25
-KPX v oslash -25
-KPX v otilde -25
-KPX v period -80
-KPX w a -15
-KPX w aacute -15
-KPX w abreve -15
-KPX w acircumflex -15
-KPX w adieresis -15
-KPX w agrave -15
-KPX w amacron -15
-KPX w aogonek -15
-KPX w aring -15
-KPX w atilde -15
-KPX w comma -60
-KPX w e -10
-KPX w eacute -10
-KPX w ecaron -10
-KPX w ecircumflex -10
-KPX w edieresis -10
-KPX w edotaccent -10
-KPX w egrave -10
-KPX w emacron -10
-KPX w eogonek -10
-KPX w o -10
-KPX w oacute -10
-KPX w ocircumflex -10
-KPX w odieresis -10
-KPX w ograve -10
-KPX w ohungarumlaut -10
-KPX w omacron -10
-KPX w oslash -10
-KPX w otilde -10
-KPX w period -60
-KPX x e -30
-KPX x eacute -30
-KPX x ecaron -30
-KPX x ecircumflex -30
-KPX x edieresis -30
-KPX x edotaccent -30
-KPX x egrave -30
-KPX x emacron -30
-KPX x eogonek -30
-KPX y a -20
-KPX y aacute -20
-KPX y abreve -20
-KPX y acircumflex -20
-KPX y adieresis -20
-KPX y agrave -20
-KPX y amacron -20
-KPX y aogonek -20
-KPX y aring -20
-KPX y atilde -20
-KPX y comma -100
-KPX y e -20
-KPX y eacute -20
-KPX y ecaron -20
-KPX y ecircumflex -20
-KPX y edieresis -20
-KPX y edotaccent -20
-KPX y egrave -20
-KPX y emacron -20
-KPX y eogonek -20
-KPX y o -20
-KPX y oacute -20
-KPX y ocircumflex -20
-KPX y odieresis -20
-KPX y ograve -20
-KPX y ohungarumlaut -20
-KPX y omacron -20
-KPX y oslash -20
-KPX y otilde -20
-KPX y period -100
-KPX yacute a -20
-KPX yacute aacute -20
-KPX yacute abreve -20
-KPX yacute acircumflex -20
-KPX yacute adieresis -20
-KPX yacute agrave -20
-KPX yacute amacron -20
-KPX yacute aogonek -20
-KPX yacute aring -20
-KPX yacute atilde -20
-KPX yacute comma -100
-KPX yacute e -20
-KPX yacute eacute -20
-KPX yacute ecaron -20
-KPX yacute ecircumflex -20
-KPX yacute edieresis -20
-KPX yacute edotaccent -20
-KPX yacute egrave -20
-KPX yacute emacron -20
-KPX yacute eogonek -20
-KPX yacute o -20
-KPX yacute oacute -20
-KPX yacute ocircumflex -20
-KPX yacute odieresis -20
-KPX yacute ograve -20
-KPX yacute ohungarumlaut -20
-KPX yacute omacron -20
-KPX yacute oslash -20
-KPX yacute otilde -20
-KPX yacute period -100
-KPX ydieresis a -20
-KPX ydieresis aacute -20
-KPX ydieresis abreve -20
-KPX ydieresis acircumflex -20
-KPX ydieresis adieresis -20
-KPX ydieresis agrave -20
-KPX ydieresis amacron -20
-KPX ydieresis aogonek -20
-KPX ydieresis aring -20
-KPX ydieresis atilde -20
-KPX ydieresis comma -100
-KPX ydieresis e -20
-KPX ydieresis eacute -20
-KPX ydieresis ecaron -20
-KPX ydieresis ecircumflex -20
-KPX ydieresis edieresis -20
-KPX ydieresis edotaccent -20
-KPX ydieresis egrave -20
-KPX ydieresis emacron -20
-KPX ydieresis eogonek -20
-KPX ydieresis o -20
-KPX ydieresis oacute -20
-KPX ydieresis ocircumflex -20
-KPX ydieresis odieresis -20
-KPX ydieresis ograve -20
-KPX ydieresis ohungarumlaut -20
-KPX ydieresis omacron -20
-KPX ydieresis oslash -20
-KPX ydieresis otilde -20
-KPX ydieresis period -100
-KPX z e -15
-KPX z eacute -15
-KPX z ecaron -15
-KPX z ecircumflex -15
-KPX z edieresis -15
-KPX z edotaccent -15
-KPX z egrave -15
-KPX z emacron -15
-KPX z eogonek -15
-KPX z o -15
-KPX z oacute -15
-KPX z ocircumflex -15
-KPX z odieresis -15
-KPX z ograve -15
-KPX z ohungarumlaut -15
-KPX z omacron -15
-KPX z oslash -15
-KPX z otilde -15
-KPX zacute e -15
-KPX zacute eacute -15
-KPX zacute ecaron -15
-KPX zacute ecircumflex -15
-KPX zacute edieresis -15
-KPX zacute edotaccent -15
-KPX zacute egrave -15
-KPX zacute emacron -15
-KPX zacute eogonek -15
-KPX zacute o -15
-KPX zacute oacute -15
-KPX zacute ocircumflex -15
-KPX zacute odieresis -15
-KPX zacute ograve -15
-KPX zacute ohungarumlaut -15
-KPX zacute omacron -15
-KPX zacute oslash -15
-KPX zacute otilde -15
-KPX zcaron e -15
-KPX zcaron eacute -15
-KPX zcaron ecaron -15
-KPX zcaron ecircumflex -15
-KPX zcaron edieresis -15
-KPX zcaron edotaccent -15
-KPX zcaron egrave -15
-KPX zcaron emacron -15
-KPX zcaron eogonek -15
-KPX zcaron o -15
-KPX zcaron oacute -15
-KPX zcaron ocircumflex -15
-KPX zcaron odieresis -15
-KPX zcaron ograve -15
-KPX zcaron ohungarumlaut -15
-KPX zcaron omacron -15
-KPX zcaron oslash -15
-KPX zcaron otilde -15
-KPX zdotaccent e -15
-KPX zdotaccent eacute -15
-KPX zdotaccent ecaron -15
-KPX zdotaccent ecircumflex -15
-KPX zdotaccent edieresis -15
-KPX zdotaccent edotaccent -15
-KPX zdotaccent egrave -15
-KPX zdotaccent emacron -15
-KPX zdotaccent eogonek -15
-KPX zdotaccent o -15
-KPX zdotaccent oacute -15
-KPX zdotaccent ocircumflex -15
-KPX zdotaccent odieresis -15
-KPX zdotaccent ograve -15
-KPX zdotaccent ohungarumlaut -15
-KPX zdotaccent omacron -15
-KPX zdotaccent oslash -15
-KPX zdotaccent otilde -15
-EndKernPairs
-EndKernData
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Symbol.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Symbol.afm
deleted file mode 100644
index 6a5386a919..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Symbol.afm
+++ /dev/null
@@ -1,213 +0,0 @@
-StartFontMetrics 4.1
-Comment Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All rights reserved.
-Comment Creation Date: Thu May 1 15:12:25 1997
-Comment UniqueID 43064
-Comment VMusage 30820 39997
-FontName Symbol
-FullName Symbol
-FamilyName Symbol
-Weight Medium
-ItalicAngle 0
-IsFixedPitch false
-CharacterSet Special
-FontBBox -180 -293 1090 1010
-UnderlinePosition -100
-UnderlineThickness 50
-Version 001.008
-Notice Copyright (c) 1985, 1987, 1989, 1990, 1997 Adobe Systems Incorporated. All rights reserved.
-EncodingScheme FontSpecific
-StdHW 92
-StdVW 85
-StartCharMetrics 190
-C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 128 -17 240 672 ;
-C 34 ; WX 713 ; N universal ; B 31 0 681 705 ;
-C 35 ; WX 500 ; N numbersign ; B 20 -16 481 673 ;
-C 36 ; WX 549 ; N existential ; B 25 0 478 707 ;
-C 37 ; WX 833 ; N percent ; B 63 -36 771 655 ;
-C 38 ; WX 778 ; N ampersand ; B 41 -18 750 661 ;
-C 39 ; WX 439 ; N suchthat ; B 48 -17 414 500 ;
-C 40 ; WX 333 ; N parenleft ; B 53 -191 300 673 ;
-C 41 ; WX 333 ; N parenright ; B 30 -191 277 673 ;
-C 42 ; WX 500 ; N asteriskmath ; B 65 134 427 551 ;
-C 43 ; WX 549 ; N plus ; B 10 0 539 533 ;
-C 44 ; WX 250 ; N comma ; B 56 -152 194 104 ;
-C 45 ; WX 549 ; N minus ; B 11 233 535 288 ;
-C 46 ; WX 250 ; N period ; B 69 -17 181 95 ;
-C 47 ; WX 278 ; N slash ; B 0 -18 254 646 ;
-C 48 ; WX 500 ; N zero ; B 24 -14 476 685 ;
-C 49 ; WX 500 ; N one ; B 117 0 390 673 ;
-C 50 ; WX 500 ; N two ; B 25 0 475 685 ;
-C 51 ; WX 500 ; N three ; B 43 -14 435 685 ;
-C 52 ; WX 500 ; N four ; B 15 0 469 685 ;
-C 53 ; WX 500 ; N five ; B 32 -14 445 690 ;
-C 54 ; WX 500 ; N six ; B 34 -14 468 685 ;
-C 55 ; WX 500 ; N seven ; B 24 -16 448 673 ;
-C 56 ; WX 500 ; N eight ; B 56 -14 445 685 ;
-C 57 ; WX 500 ; N nine ; B 30 -18 459 685 ;
-C 58 ; WX 278 ; N colon ; B 81 -17 193 460 ;
-C 59 ; WX 278 ; N semicolon ; B 83 -152 221 460 ;
-C 60 ; WX 549 ; N less ; B 26 0 523 522 ;
-C 61 ; WX 549 ; N equal ; B 11 141 537 390 ;
-C 62 ; WX 549 ; N greater ; B 26 0 523 522 ;
-C 63 ; WX 444 ; N question ; B 70 -17 412 686 ;
-C 64 ; WX 549 ; N congruent ; B 11 0 537 475 ;
-C 65 ; WX 722 ; N Alpha ; B 4 0 684 673 ;
-C 66 ; WX 667 ; N Beta ; B 29 0 592 673 ;
-C 67 ; WX 722 ; N Chi ; B -9 0 704 673 ;
-C 68 ; WX 612 ; N Delta ; B 6 0 608 688 ;
-C 69 ; WX 611 ; N Epsilon ; B 32 0 617 673 ;
-C 70 ; WX 763 ; N Phi ; B 26 0 741 673 ;
-C 71 ; WX 603 ; N Gamma ; B 24 0 609 673 ;
-C 72 ; WX 722 ; N Eta ; B 39 0 729 673 ;
-C 73 ; WX 333 ; N Iota ; B 32 0 316 673 ;
-C 74 ; WX 631 ; N theta1 ; B 18 -18 623 689 ;
-C 75 ; WX 722 ; N Kappa ; B 35 0 722 673 ;
-C 76 ; WX 686 ; N Lambda ; B 6 0 680 688 ;
-C 77 ; WX 889 ; N Mu ; B 28 0 887 673 ;
-C 78 ; WX 722 ; N Nu ; B 29 -8 720 673 ;
-C 79 ; WX 722 ; N Omicron ; B 41 -17 715 685 ;
-C 80 ; WX 768 ; N Pi ; B 25 0 745 673 ;
-C 81 ; WX 741 ; N Theta ; B 41 -17 715 685 ;
-C 82 ; WX 556 ; N Rho ; B 28 0 563 673 ;
-C 83 ; WX 592 ; N Sigma ; B 5 0 589 673 ;
-C 84 ; WX 611 ; N Tau ; B 33 0 607 673 ;
-C 85 ; WX 690 ; N Upsilon ; B -8 0 694 673 ;
-C 86 ; WX 439 ; N sigma1 ; B 40 -233 436 500 ;
-C 87 ; WX 768 ; N Omega ; B 34 0 736 688 ;
-C 88 ; WX 645 ; N Xi ; B 40 0 599 673 ;
-C 89 ; WX 795 ; N Psi ; B 15 0 781 684 ;
-C 90 ; WX 611 ; N Zeta ; B 44 0 636 673 ;
-C 91 ; WX 333 ; N bracketleft ; B 86 -155 299 674 ;
-C 92 ; WX 863 ; N therefore ; B 163 0 701 487 ;
-C 93 ; WX 333 ; N bracketright ; B 33 -155 246 674 ;
-C 94 ; WX 658 ; N perpendicular ; B 15 0 652 674 ;
-C 95 ; WX 500 ; N underscore ; B -2 -125 502 -75 ;
-C 96 ; WX 500 ; N radicalex ; B 480 881 1090 917 ;
-C 97 ; WX 631 ; N alpha ; B 41 -18 622 500 ;
-C 98 ; WX 549 ; N beta ; B 61 -223 515 741 ;
-C 99 ; WX 549 ; N chi ; B 12 -231 522 499 ;
-C 100 ; WX 494 ; N delta ; B 40 -19 481 740 ;
-C 101 ; WX 439 ; N epsilon ; B 22 -19 427 502 ;
-C 102 ; WX 521 ; N phi ; B 28 -224 492 673 ;
-C 103 ; WX 411 ; N gamma ; B 5 -225 484 499 ;
-C 104 ; WX 603 ; N eta ; B 0 -202 527 514 ;
-C 105 ; WX 329 ; N iota ; B 0 -17 301 503 ;
-C 106 ; WX 603 ; N phi1 ; B 36 -224 587 499 ;
-C 107 ; WX 549 ; N kappa ; B 33 0 558 501 ;
-C 108 ; WX 549 ; N lambda ; B 24 -17 548 739 ;
-C 109 ; WX 576 ; N mu ; B 33 -223 567 500 ;
-C 110 ; WX 521 ; N nu ; B -9 -16 475 507 ;
-C 111 ; WX 549 ; N omicron ; B 35 -19 501 499 ;
-C 112 ; WX 549 ; N pi ; B 10 -19 530 487 ;
-C 113 ; WX 521 ; N theta ; B 43 -17 485 690 ;
-C 114 ; WX 549 ; N rho ; B 50 -230 490 499 ;
-C 115 ; WX 603 ; N sigma ; B 30 -21 588 500 ;
-C 116 ; WX 439 ; N tau ; B 10 -19 418 500 ;
-C 117 ; WX 576 ; N upsilon ; B 7 -18 535 507 ;
-C 118 ; WX 713 ; N omega1 ; B 12 -18 671 583 ;
-C 119 ; WX 686 ; N omega ; B 42 -17 684 500 ;
-C 120 ; WX 493 ; N xi ; B 27 -224 469 766 ;
-C 121 ; WX 686 ; N psi ; B 12 -228 701 500 ;
-C 122 ; WX 494 ; N zeta ; B 60 -225 467 756 ;
-C 123 ; WX 480 ; N braceleft ; B 58 -183 397 673 ;
-C 124 ; WX 200 ; N bar ; B 65 -293 135 707 ;
-C 125 ; WX 480 ; N braceright ; B 79 -183 418 673 ;
-C 126 ; WX 549 ; N similar ; B 17 203 529 307 ;
-C 160 ; WX 750 ; N Euro ; B 20 -12 714 685 ;
-C 161 ; WX 620 ; N Upsilon1 ; B -2 0 610 685 ;
-C 162 ; WX 247 ; N minute ; B 27 459 228 735 ;
-C 163 ; WX 549 ; N lessequal ; B 29 0 526 639 ;
-C 164 ; WX 167 ; N fraction ; B -180 -12 340 677 ;
-C 165 ; WX 713 ; N infinity ; B 26 124 688 404 ;
-C 166 ; WX 500 ; N florin ; B 2 -193 494 686 ;
-C 167 ; WX 753 ; N club ; B 86 -26 660 533 ;
-C 168 ; WX 753 ; N diamond ; B 142 -36 600 550 ;
-C 169 ; WX 753 ; N heart ; B 117 -33 631 532 ;
-C 170 ; WX 753 ; N spade ; B 113 -36 629 548 ;
-C 171 ; WX 1042 ; N arrowboth ; B 24 -15 1024 511 ;
-C 172 ; WX 987 ; N arrowleft ; B 32 -15 942 511 ;
-C 173 ; WX 603 ; N arrowup ; B 45 0 571 910 ;
-C 174 ; WX 987 ; N arrowright ; B 49 -15 959 511 ;
-C 175 ; WX 603 ; N arrowdown ; B 45 -22 571 888 ;
-C 176 ; WX 400 ; N degree ; B 50 385 350 685 ;
-C 177 ; WX 549 ; N plusminus ; B 10 0 539 645 ;
-C 178 ; WX 411 ; N second ; B 20 459 413 737 ;
-C 179 ; WX 549 ; N greaterequal ; B 29 0 526 639 ;
-C 180 ; WX 549 ; N multiply ; B 17 8 533 524 ;
-C 181 ; WX 713 ; N proportional ; B 27 123 639 404 ;
-C 182 ; WX 494 ; N partialdiff ; B 26 -20 462 746 ;
-C 183 ; WX 460 ; N bullet ; B 50 113 410 473 ;
-C 184 ; WX 549 ; N divide ; B 10 71 536 456 ;
-C 185 ; WX 549 ; N notequal ; B 15 -25 540 549 ;
-C 186 ; WX 549 ; N equivalence ; B 14 82 538 443 ;
-C 187 ; WX 549 ; N approxequal ; B 14 135 527 394 ;
-C 188 ; WX 1000 ; N ellipsis ; B 111 -17 889 95 ;
-C 189 ; WX 603 ; N arrowvertex ; B 280 -120 336 1010 ;
-C 190 ; WX 1000 ; N arrowhorizex ; B -60 220 1050 276 ;
-C 191 ; WX 658 ; N carriagereturn ; B 15 -16 602 629 ;
-C 192 ; WX 823 ; N aleph ; B 175 -18 661 658 ;
-C 193 ; WX 686 ; N Ifraktur ; B 10 -53 578 740 ;
-C 194 ; WX 795 ; N Rfraktur ; B 26 -15 759 734 ;
-C 195 ; WX 987 ; N weierstrass ; B 159 -211 870 573 ;
-C 196 ; WX 768 ; N circlemultiply ; B 43 -17 733 673 ;
-C 197 ; WX 768 ; N circleplus ; B 43 -15 733 675 ;
-C 198 ; WX 823 ; N emptyset ; B 39 -24 781 719 ;
-C 199 ; WX 768 ; N intersection ; B 40 0 732 509 ;
-C 200 ; WX 768 ; N union ; B 40 -17 732 492 ;
-C 201 ; WX 713 ; N propersuperset ; B 20 0 673 470 ;
-C 202 ; WX 713 ; N reflexsuperset ; B 20 -125 673 470 ;
-C 203 ; WX 713 ; N notsubset ; B 36 -70 690 540 ;
-C 204 ; WX 713 ; N propersubset ; B 37 0 690 470 ;
-C 205 ; WX 713 ; N reflexsubset ; B 37 -125 690 470 ;
-C 206 ; WX 713 ; N element ; B 45 0 505 468 ;
-C 207 ; WX 713 ; N notelement ; B 45 -58 505 555 ;
-C 208 ; WX 768 ; N angle ; B 26 0 738 673 ;
-C 209 ; WX 713 ; N gradient ; B 36 -19 681 718 ;
-C 210 ; WX 790 ; N registerserif ; B 50 -17 740 673 ;
-C 211 ; WX 790 ; N copyrightserif ; B 51 -15 741 675 ;
-C 212 ; WX 890 ; N trademarkserif ; B 18 293 855 673 ;
-C 213 ; WX 823 ; N product ; B 25 -101 803 751 ;
-C 214 ; WX 549 ; N radical ; B 10 -38 515 917 ;
-C 215 ; WX 250 ; N dotmath ; B 69 210 169 310 ;
-C 216 ; WX 713 ; N logicalnot ; B 15 0 680 288 ;
-C 217 ; WX 603 ; N logicaland ; B 23 0 583 454 ;
-C 218 ; WX 603 ; N logicalor ; B 30 0 578 477 ;
-C 219 ; WX 1042 ; N arrowdblboth ; B 27 -20 1023 510 ;
-C 220 ; WX 987 ; N arrowdblleft ; B 30 -15 939 513 ;
-C 221 ; WX 603 ; N arrowdblup ; B 39 2 567 911 ;
-C 222 ; WX 987 ; N arrowdblright ; B 45 -20 954 508 ;
-C 223 ; WX 603 ; N arrowdbldown ; B 44 -19 572 890 ;
-C 224 ; WX 494 ; N lozenge ; B 18 0 466 745 ;
-C 225 ; WX 329 ; N angleleft ; B 25 -198 306 746 ;
-C 226 ; WX 790 ; N registersans ; B 50 -20 740 670 ;
-C 227 ; WX 790 ; N copyrightsans ; B 49 -15 739 675 ;
-C 228 ; WX 786 ; N trademarksans ; B 5 293 725 673 ;
-C 229 ; WX 713 ; N summation ; B 14 -108 695 752 ;
-C 230 ; WX 384 ; N parenlefttp ; B 24 -293 436 926 ;
-C 231 ; WX 384 ; N parenleftex ; B 24 -85 108 925 ;
-C 232 ; WX 384 ; N parenleftbt ; B 24 -293 436 926 ;
-C 233 ; WX 384 ; N bracketlefttp ; B 0 -80 349 926 ;
-C 234 ; WX 384 ; N bracketleftex ; B 0 -79 77 925 ;
-C 235 ; WX 384 ; N bracketleftbt ; B 0 -80 349 926 ;
-C 236 ; WX 494 ; N bracelefttp ; B 209 -85 445 925 ;
-C 237 ; WX 494 ; N braceleftmid ; B 20 -85 284 935 ;
-C 238 ; WX 494 ; N braceleftbt ; B 209 -75 445 935 ;
-C 239 ; WX 494 ; N braceex ; B 209 -85 284 935 ;
-C 241 ; WX 329 ; N angleright ; B 21 -198 302 746 ;
-C 242 ; WX 274 ; N integral ; B 2 -107 291 916 ;
-C 243 ; WX 686 ; N integraltp ; B 308 -88 675 920 ;
-C 244 ; WX 686 ; N integralex ; B 308 -88 378 975 ;
-C 245 ; WX 686 ; N integralbt ; B 11 -87 378 921 ;
-C 246 ; WX 384 ; N parenrighttp ; B 54 -293 466 926 ;
-C 247 ; WX 384 ; N parenrightex ; B 382 -85 466 925 ;
-C 248 ; WX 384 ; N parenrightbt ; B 54 -293 466 926 ;
-C 249 ; WX 384 ; N bracketrighttp ; B 22 -80 371 926 ;
-C 250 ; WX 384 ; N bracketrightex ; B 294 -79 371 925 ;
-C 251 ; WX 384 ; N bracketrightbt ; B 22 -80 371 926 ;
-C 252 ; WX 494 ; N bracerighttp ; B 48 -85 284 925 ;
-C 253 ; WX 494 ; N bracerightmid ; B 209 -85 473 935 ;
-C 254 ; WX 494 ; N bracerightbt ; B 48 -75 284 935 ;
-C -1 ; WX 790 ; N apple ; B 56 -3 733 808 ;
-EndCharMetrics
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Bold.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Bold.afm
deleted file mode 100644
index 559ebaeb6f..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Bold.afm
+++ /dev/null
@@ -1,2588 +0,0 @@
-StartFontMetrics 4.1
-Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Thu May 1 12:52:56 1997
-Comment UniqueID 43065
-Comment VMusage 41636 52661
-FontName Times-Bold
-FullName Times Bold
-FamilyName Times
-Weight Bold
-ItalicAngle 0
-IsFixedPitch false
-CharacterSet ExtendedRoman
-FontBBox -168 -218 1000 935
-UnderlinePosition -100
-UnderlineThickness 50
-Version 002.000
-Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 676
-XHeight 461
-Ascender 683
-Descender -217
-StdHW 44
-StdVW 139
-StartCharMetrics 315
-C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 81 -13 251 691 ;
-C 34 ; WX 555 ; N quotedbl ; B 83 404 472 691 ;
-C 35 ; WX 500 ; N numbersign ; B 4 0 496 700 ;
-C 36 ; WX 500 ; N dollar ; B 29 -99 472 750 ;
-C 37 ; WX 1000 ; N percent ; B 124 -14 877 692 ;
-C 38 ; WX 833 ; N ampersand ; B 62 -16 787 691 ;
-C 39 ; WX 333 ; N quoteright ; B 79 356 263 691 ;
-C 40 ; WX 333 ; N parenleft ; B 46 -168 306 694 ;
-C 41 ; WX 333 ; N parenright ; B 27 -168 287 694 ;
-C 42 ; WX 500 ; N asterisk ; B 56 255 447 691 ;
-C 43 ; WX 570 ; N plus ; B 33 0 537 506 ;
-C 44 ; WX 250 ; N comma ; B 39 -180 223 155 ;
-C 45 ; WX 333 ; N hyphen ; B 44 171 287 287 ;
-C 46 ; WX 250 ; N period ; B 41 -13 210 156 ;
-C 47 ; WX 278 ; N slash ; B -24 -19 302 691 ;
-C 48 ; WX 500 ; N zero ; B 24 -13 476 688 ;
-C 49 ; WX 500 ; N one ; B 65 0 442 688 ;
-C 50 ; WX 500 ; N two ; B 17 0 478 688 ;
-C 51 ; WX 500 ; N three ; B 16 -14 468 688 ;
-C 52 ; WX 500 ; N four ; B 19 0 475 688 ;
-C 53 ; WX 500 ; N five ; B 22 -8 470 676 ;
-C 54 ; WX 500 ; N six ; B 28 -13 475 688 ;
-C 55 ; WX 500 ; N seven ; B 17 0 477 676 ;
-C 56 ; WX 500 ; N eight ; B 28 -13 472 688 ;
-C 57 ; WX 500 ; N nine ; B 26 -13 473 688 ;
-C 58 ; WX 333 ; N colon ; B 82 -13 251 472 ;
-C 59 ; WX 333 ; N semicolon ; B 82 -180 266 472 ;
-C 60 ; WX 570 ; N less ; B 31 -8 539 514 ;
-C 61 ; WX 570 ; N equal ; B 33 107 537 399 ;
-C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ;
-C 63 ; WX 500 ; N question ; B 57 -13 445 689 ;
-C 64 ; WX 930 ; N at ; B 108 -19 822 691 ;
-C 65 ; WX 722 ; N A ; B 9 0 689 690 ;
-C 66 ; WX 667 ; N B ; B 16 0 619 676 ;
-C 67 ; WX 722 ; N C ; B 49 -19 687 691 ;
-C 68 ; WX 722 ; N D ; B 14 0 690 676 ;
-C 69 ; WX 667 ; N E ; B 16 0 641 676 ;
-C 70 ; WX 611 ; N F ; B 16 0 583 676 ;
-C 71 ; WX 778 ; N G ; B 37 -19 755 691 ;
-C 72 ; WX 778 ; N H ; B 21 0 759 676 ;
-C 73 ; WX 389 ; N I ; B 20 0 370 676 ;
-C 74 ; WX 500 ; N J ; B 3 -96 479 676 ;
-C 75 ; WX 778 ; N K ; B 30 0 769 676 ;
-C 76 ; WX 667 ; N L ; B 19 0 638 676 ;
-C 77 ; WX 944 ; N M ; B 14 0 921 676 ;
-C 78 ; WX 722 ; N N ; B 16 -18 701 676 ;
-C 79 ; WX 778 ; N O ; B 35 -19 743 691 ;
-C 80 ; WX 611 ; N P ; B 16 0 600 676 ;
-C 81 ; WX 778 ; N Q ; B 35 -176 743 691 ;
-C 82 ; WX 722 ; N R ; B 26 0 715 676 ;
-C 83 ; WX 556 ; N S ; B 35 -19 513 692 ;
-C 84 ; WX 667 ; N T ; B 31 0 636 676 ;
-C 85 ; WX 722 ; N U ; B 16 -19 701 676 ;
-C 86 ; WX 722 ; N V ; B 16 -18 701 676 ;
-C 87 ; WX 1000 ; N W ; B 19 -15 981 676 ;
-C 88 ; WX 722 ; N X ; B 16 0 699 676 ;
-C 89 ; WX 722 ; N Y ; B 15 0 699 676 ;
-C 90 ; WX 667 ; N Z ; B 28 0 634 676 ;
-C 91 ; WX 333 ; N bracketleft ; B 67 -149 301 678 ;
-C 92 ; WX 278 ; N backslash ; B -25 -19 303 691 ;
-C 93 ; WX 333 ; N bracketright ; B 32 -149 266 678 ;
-C 94 ; WX 581 ; N asciicircum ; B 73 311 509 676 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 333 ; N quoteleft ; B 70 356 254 691 ;
-C 97 ; WX 500 ; N a ; B 25 -14 488 473 ;
-C 98 ; WX 556 ; N b ; B 17 -14 521 676 ;
-C 99 ; WX 444 ; N c ; B 25 -14 430 473 ;
-C 100 ; WX 556 ; N d ; B 25 -14 534 676 ;
-C 101 ; WX 444 ; N e ; B 25 -14 426 473 ;
-C 102 ; WX 333 ; N f ; B 14 0 389 691 ; L i fi ; L l fl ;
-C 103 ; WX 500 ; N g ; B 28 -206 483 473 ;
-C 104 ; WX 556 ; N h ; B 16 0 534 676 ;
-C 105 ; WX 278 ; N i ; B 16 0 255 691 ;
-C 106 ; WX 333 ; N j ; B -57 -203 263 691 ;
-C 107 ; WX 556 ; N k ; B 22 0 543 676 ;
-C 108 ; WX 278 ; N l ; B 16 0 255 676 ;
-C 109 ; WX 833 ; N m ; B 16 0 814 473 ;
-C 110 ; WX 556 ; N n ; B 21 0 539 473 ;
-C 111 ; WX 500 ; N o ; B 25 -14 476 473 ;
-C 112 ; WX 556 ; N p ; B 19 -205 524 473 ;
-C 113 ; WX 556 ; N q ; B 34 -205 536 473 ;
-C 114 ; WX 444 ; N r ; B 29 0 434 473 ;
-C 115 ; WX 389 ; N s ; B 25 -14 361 473 ;
-C 116 ; WX 333 ; N t ; B 20 -12 332 630 ;
-C 117 ; WX 556 ; N u ; B 16 -14 537 461 ;
-C 118 ; WX 500 ; N v ; B 21 -14 485 461 ;
-C 119 ; WX 722 ; N w ; B 23 -14 707 461 ;
-C 120 ; WX 500 ; N x ; B 12 0 484 461 ;
-C 121 ; WX 500 ; N y ; B 16 -205 480 461 ;
-C 122 ; WX 444 ; N z ; B 21 0 420 461 ;
-C 123 ; WX 394 ; N braceleft ; B 22 -175 340 698 ;
-C 124 ; WX 220 ; N bar ; B 66 -218 154 782 ;
-C 125 ; WX 394 ; N braceright ; B 54 -175 372 698 ;
-C 126 ; WX 520 ; N asciitilde ; B 29 173 491 333 ;
-C 161 ; WX 333 ; N exclamdown ; B 82 -203 252 501 ;
-C 162 ; WX 500 ; N cent ; B 53 -140 458 588 ;
-C 163 ; WX 500 ; N sterling ; B 21 -14 477 684 ;
-C 164 ; WX 167 ; N fraction ; B -168 -12 329 688 ;
-C 165 ; WX 500 ; N yen ; B -64 0 547 676 ;
-C 166 ; WX 500 ; N florin ; B 0 -155 498 706 ;
-C 167 ; WX 500 ; N section ; B 57 -132 443 691 ;
-C 168 ; WX 500 ; N currency ; B -26 61 526 613 ;
-C 169 ; WX 278 ; N quotesingle ; B 75 404 204 691 ;
-C 170 ; WX 500 ; N quotedblleft ; B 32 356 486 691 ;
-C 171 ; WX 500 ; N guillemotleft ; B 23 36 473 415 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 51 36 305 415 ;
-C 173 ; WX 333 ; N guilsinglright ; B 28 36 282 415 ;
-C 174 ; WX 556 ; N fi ; B 14 0 536 691 ;
-C 175 ; WX 556 ; N fl ; B 14 0 536 691 ;
-C 177 ; WX 500 ; N endash ; B 0 181 500 271 ;
-C 178 ; WX 500 ; N dagger ; B 47 -134 453 691 ;
-C 179 ; WX 500 ; N daggerdbl ; B 45 -132 456 691 ;
-C 180 ; WX 250 ; N periodcentered ; B 41 248 210 417 ;
-C 182 ; WX 540 ; N paragraph ; B 0 -186 519 676 ;
-C 183 ; WX 350 ; N bullet ; B 35 198 315 478 ;
-C 184 ; WX 333 ; N quotesinglbase ; B 79 -180 263 155 ;
-C 185 ; WX 500 ; N quotedblbase ; B 14 -180 468 155 ;
-C 186 ; WX 500 ; N quotedblright ; B 14 356 468 691 ;
-C 187 ; WX 500 ; N guillemotright ; B 27 36 477 415 ;
-C 188 ; WX 1000 ; N ellipsis ; B 82 -13 917 156 ;
-C 189 ; WX 1000 ; N perthousand ; B 7 -29 995 706 ;
-C 191 ; WX 500 ; N questiondown ; B 55 -201 443 501 ;
-C 193 ; WX 333 ; N grave ; B 8 528 246 713 ;
-C 194 ; WX 333 ; N acute ; B 86 528 324 713 ;
-C 195 ; WX 333 ; N circumflex ; B -2 528 335 704 ;
-C 196 ; WX 333 ; N tilde ; B -16 547 349 674 ;
-C 197 ; WX 333 ; N macron ; B 1 565 331 637 ;
-C 198 ; WX 333 ; N breve ; B 15 528 318 691 ;
-C 199 ; WX 333 ; N dotaccent ; B 103 536 258 691 ;
-C 200 ; WX 333 ; N dieresis ; B -2 537 335 667 ;
-C 202 ; WX 333 ; N ring ; B 60 527 273 740 ;
-C 203 ; WX 333 ; N cedilla ; B 68 -218 294 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B -13 528 425 713 ;
-C 206 ; WX 333 ; N ogonek ; B 90 -193 319 24 ;
-C 207 ; WX 333 ; N caron ; B -2 528 335 704 ;
-C 208 ; WX 1000 ; N emdash ; B 0 181 1000 271 ;
-C 225 ; WX 1000 ; N AE ; B 4 0 951 676 ;
-C 227 ; WX 300 ; N ordfeminine ; B -1 397 301 688 ;
-C 232 ; WX 667 ; N Lslash ; B 19 0 638 676 ;
-C 233 ; WX 778 ; N Oslash ; B 35 -74 743 737 ;
-C 234 ; WX 1000 ; N OE ; B 22 -5 981 684 ;
-C 235 ; WX 330 ; N ordmasculine ; B 18 397 312 688 ;
-C 241 ; WX 722 ; N ae ; B 33 -14 693 473 ;
-C 245 ; WX 278 ; N dotlessi ; B 16 0 255 461 ;
-C 248 ; WX 278 ; N lslash ; B -22 0 303 676 ;
-C 249 ; WX 500 ; N oslash ; B 25 -92 476 549 ;
-C 250 ; WX 722 ; N oe ; B 22 -14 696 473 ;
-C 251 ; WX 556 ; N germandbls ; B 19 -12 517 691 ;
-C -1 ; WX 389 ; N Idieresis ; B 20 0 370 877 ;
-C -1 ; WX 444 ; N eacute ; B 25 -14 426 713 ;
-C -1 ; WX 500 ; N abreve ; B 25 -14 488 691 ;
-C -1 ; WX 556 ; N uhungarumlaut ; B 16 -14 557 713 ;
-C -1 ; WX 444 ; N ecaron ; B 25 -14 426 704 ;
-C -1 ; WX 722 ; N Ydieresis ; B 15 0 699 877 ;
-C -1 ; WX 570 ; N divide ; B 33 -31 537 537 ;
-C -1 ; WX 722 ; N Yacute ; B 15 0 699 923 ;
-C -1 ; WX 722 ; N Acircumflex ; B 9 0 689 914 ;
-C -1 ; WX 500 ; N aacute ; B 25 -14 488 713 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 16 -19 701 914 ;
-C -1 ; WX 500 ; N yacute ; B 16 -205 480 713 ;
-C -1 ; WX 389 ; N scommaaccent ; B 25 -218 361 473 ;
-C -1 ; WX 444 ; N ecircumflex ; B 25 -14 426 704 ;
-C -1 ; WX 722 ; N Uring ; B 16 -19 701 935 ;
-C -1 ; WX 722 ; N Udieresis ; B 16 -19 701 877 ;
-C -1 ; WX 500 ; N aogonek ; B 25 -193 504 473 ;
-C -1 ; WX 722 ; N Uacute ; B 16 -19 701 923 ;
-C -1 ; WX 556 ; N uogonek ; B 16 -193 539 461 ;
-C -1 ; WX 667 ; N Edieresis ; B 16 0 641 877 ;
-C -1 ; WX 722 ; N Dcroat ; B 6 0 690 676 ;
-C -1 ; WX 250 ; N commaaccent ; B 47 -218 203 -50 ;
-C -1 ; WX 747 ; N copyright ; B 26 -19 721 691 ;
-C -1 ; WX 667 ; N Emacron ; B 16 0 641 847 ;
-C -1 ; WX 444 ; N ccaron ; B 25 -14 430 704 ;
-C -1 ; WX 500 ; N aring ; B 25 -14 488 740 ;
-C -1 ; WX 722 ; N Ncommaaccent ; B 16 -188 701 676 ;
-C -1 ; WX 278 ; N lacute ; B 16 0 297 923 ;
-C -1 ; WX 500 ; N agrave ; B 25 -14 488 713 ;
-C -1 ; WX 667 ; N Tcommaaccent ; B 31 -218 636 676 ;
-C -1 ; WX 722 ; N Cacute ; B 49 -19 687 923 ;
-C -1 ; WX 500 ; N atilde ; B 25 -14 488 674 ;
-C -1 ; WX 667 ; N Edotaccent ; B 16 0 641 901 ;
-C -1 ; WX 389 ; N scaron ; B 25 -14 363 704 ;
-C -1 ; WX 389 ; N scedilla ; B 25 -218 361 473 ;
-C -1 ; WX 278 ; N iacute ; B 16 0 289 713 ;
-C -1 ; WX 494 ; N lozenge ; B 10 0 484 745 ;
-C -1 ; WX 722 ; N Rcaron ; B 26 0 715 914 ;
-C -1 ; WX 778 ; N Gcommaaccent ; B 37 -218 755 691 ;
-C -1 ; WX 556 ; N ucircumflex ; B 16 -14 537 704 ;
-C -1 ; WX 500 ; N acircumflex ; B 25 -14 488 704 ;
-C -1 ; WX 722 ; N Amacron ; B 9 0 689 847 ;
-C -1 ; WX 444 ; N rcaron ; B 29 0 434 704 ;
-C -1 ; WX 444 ; N ccedilla ; B 25 -218 430 473 ;
-C -1 ; WX 667 ; N Zdotaccent ; B 28 0 634 901 ;
-C -1 ; WX 611 ; N Thorn ; B 16 0 600 676 ;
-C -1 ; WX 778 ; N Omacron ; B 35 -19 743 847 ;
-C -1 ; WX 722 ; N Racute ; B 26 0 715 923 ;
-C -1 ; WX 556 ; N Sacute ; B 35 -19 513 923 ;
-C -1 ; WX 672 ; N dcaron ; B 25 -14 681 682 ;
-C -1 ; WX 722 ; N Umacron ; B 16 -19 701 847 ;
-C -1 ; WX 556 ; N uring ; B 16 -14 537 740 ;
-C -1 ; WX 300 ; N threesuperior ; B 3 268 297 688 ;
-C -1 ; WX 778 ; N Ograve ; B 35 -19 743 923 ;
-C -1 ; WX 722 ; N Agrave ; B 9 0 689 923 ;
-C -1 ; WX 722 ; N Abreve ; B 9 0 689 901 ;
-C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ;
-C -1 ; WX 556 ; N uacute ; B 16 -14 537 713 ;
-C -1 ; WX 667 ; N Tcaron ; B 31 0 636 914 ;
-C -1 ; WX 494 ; N partialdiff ; B 11 -21 494 750 ;
-C -1 ; WX 500 ; N ydieresis ; B 16 -205 480 667 ;
-C -1 ; WX 722 ; N Nacute ; B 16 -18 701 923 ;
-C -1 ; WX 278 ; N icircumflex ; B -37 0 300 704 ;
-C -1 ; WX 667 ; N Ecircumflex ; B 16 0 641 914 ;
-C -1 ; WX 500 ; N adieresis ; B 25 -14 488 667 ;
-C -1 ; WX 444 ; N edieresis ; B 25 -14 426 667 ;
-C -1 ; WX 444 ; N cacute ; B 25 -14 430 713 ;
-C -1 ; WX 556 ; N nacute ; B 21 0 539 713 ;
-C -1 ; WX 556 ; N umacron ; B 16 -14 537 637 ;
-C -1 ; WX 722 ; N Ncaron ; B 16 -18 701 914 ;
-C -1 ; WX 389 ; N Iacute ; B 20 0 370 923 ;
-C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ;
-C -1 ; WX 220 ; N brokenbar ; B 66 -143 154 707 ;
-C -1 ; WX 747 ; N registered ; B 26 -19 721 691 ;
-C -1 ; WX 778 ; N Gbreve ; B 37 -19 755 901 ;
-C -1 ; WX 389 ; N Idotaccent ; B 20 0 370 901 ;
-C -1 ; WX 600 ; N summation ; B 14 -10 585 706 ;
-C -1 ; WX 667 ; N Egrave ; B 16 0 641 923 ;
-C -1 ; WX 444 ; N racute ; B 29 0 434 713 ;
-C -1 ; WX 500 ; N omacron ; B 25 -14 476 637 ;
-C -1 ; WX 667 ; N Zacute ; B 28 0 634 923 ;
-C -1 ; WX 667 ; N Zcaron ; B 28 0 634 914 ;
-C -1 ; WX 549 ; N greaterequal ; B 26 0 523 704 ;
-C -1 ; WX 722 ; N Eth ; B 6 0 690 676 ;
-C -1 ; WX 722 ; N Ccedilla ; B 49 -218 687 691 ;
-C -1 ; WX 278 ; N lcommaaccent ; B 16 -218 255 676 ;
-C -1 ; WX 416 ; N tcaron ; B 20 -12 425 815 ;
-C -1 ; WX 444 ; N eogonek ; B 25 -193 426 473 ;
-C -1 ; WX 722 ; N Uogonek ; B 16 -193 701 676 ;
-C -1 ; WX 722 ; N Aacute ; B 9 0 689 923 ;
-C -1 ; WX 722 ; N Adieresis ; B 9 0 689 877 ;
-C -1 ; WX 444 ; N egrave ; B 25 -14 426 713 ;
-C -1 ; WX 444 ; N zacute ; B 21 0 420 713 ;
-C -1 ; WX 278 ; N iogonek ; B 16 -193 274 691 ;
-C -1 ; WX 778 ; N Oacute ; B 35 -19 743 923 ;
-C -1 ; WX 500 ; N oacute ; B 25 -14 476 713 ;
-C -1 ; WX 500 ; N amacron ; B 25 -14 488 637 ;
-C -1 ; WX 389 ; N sacute ; B 25 -14 361 713 ;
-C -1 ; WX 278 ; N idieresis ; B -37 0 300 667 ;
-C -1 ; WX 778 ; N Ocircumflex ; B 35 -19 743 914 ;
-C -1 ; WX 722 ; N Ugrave ; B 16 -19 701 923 ;
-C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ;
-C -1 ; WX 556 ; N thorn ; B 19 -205 524 676 ;
-C -1 ; WX 300 ; N twosuperior ; B 0 275 300 688 ;
-C -1 ; WX 778 ; N Odieresis ; B 35 -19 743 877 ;
-C -1 ; WX 556 ; N mu ; B 33 -206 536 461 ;
-C -1 ; WX 278 ; N igrave ; B -27 0 255 713 ;
-C -1 ; WX 500 ; N ohungarumlaut ; B 25 -14 529 713 ;
-C -1 ; WX 667 ; N Eogonek ; B 16 -193 644 676 ;
-C -1 ; WX 556 ; N dcroat ; B 25 -14 534 676 ;
-C -1 ; WX 750 ; N threequarters ; B 23 -12 733 688 ;
-C -1 ; WX 556 ; N Scedilla ; B 35 -218 513 692 ;
-C -1 ; WX 394 ; N lcaron ; B 16 0 412 682 ;
-C -1 ; WX 778 ; N Kcommaaccent ; B 30 -218 769 676 ;
-C -1 ; WX 667 ; N Lacute ; B 19 0 638 923 ;
-C -1 ; WX 1000 ; N trademark ; B 24 271 977 676 ;
-C -1 ; WX 444 ; N edotaccent ; B 25 -14 426 691 ;
-C -1 ; WX 389 ; N Igrave ; B 20 0 370 923 ;
-C -1 ; WX 389 ; N Imacron ; B 20 0 370 847 ;
-C -1 ; WX 667 ; N Lcaron ; B 19 0 652 682 ;
-C -1 ; WX 750 ; N onehalf ; B -7 -12 775 688 ;
-C -1 ; WX 549 ; N lessequal ; B 29 0 526 704 ;
-C -1 ; WX 500 ; N ocircumflex ; B 25 -14 476 704 ;
-C -1 ; WX 556 ; N ntilde ; B 21 0 539 674 ;
-C -1 ; WX 722 ; N Uhungarumlaut ; B 16 -19 701 923 ;
-C -1 ; WX 667 ; N Eacute ; B 16 0 641 923 ;
-C -1 ; WX 444 ; N emacron ; B 25 -14 426 637 ;
-C -1 ; WX 500 ; N gbreve ; B 28 -206 483 691 ;
-C -1 ; WX 750 ; N onequarter ; B 28 -12 743 688 ;
-C -1 ; WX 556 ; N Scaron ; B 35 -19 513 914 ;
-C -1 ; WX 556 ; N Scommaaccent ; B 35 -218 513 692 ;
-C -1 ; WX 778 ; N Ohungarumlaut ; B 35 -19 743 923 ;
-C -1 ; WX 400 ; N degree ; B 57 402 343 688 ;
-C -1 ; WX 500 ; N ograve ; B 25 -14 476 713 ;
-C -1 ; WX 722 ; N Ccaron ; B 49 -19 687 914 ;
-C -1 ; WX 556 ; N ugrave ; B 16 -14 537 713 ;
-C -1 ; WX 549 ; N radical ; B 10 -46 512 850 ;
-C -1 ; WX 722 ; N Dcaron ; B 14 0 690 914 ;
-C -1 ; WX 444 ; N rcommaaccent ; B 29 -218 434 473 ;
-C -1 ; WX 722 ; N Ntilde ; B 16 -18 701 884 ;
-C -1 ; WX 500 ; N otilde ; B 25 -14 476 674 ;
-C -1 ; WX 722 ; N Rcommaaccent ; B 26 -218 715 676 ;
-C -1 ; WX 667 ; N Lcommaaccent ; B 19 -218 638 676 ;
-C -1 ; WX 722 ; N Atilde ; B 9 0 689 884 ;
-C -1 ; WX 722 ; N Aogonek ; B 9 -193 699 690 ;
-C -1 ; WX 722 ; N Aring ; B 9 0 689 935 ;
-C -1 ; WX 778 ; N Otilde ; B 35 -19 743 884 ;
-C -1 ; WX 444 ; N zdotaccent ; B 21 0 420 691 ;
-C -1 ; WX 667 ; N Ecaron ; B 16 0 641 914 ;
-C -1 ; WX 389 ; N Iogonek ; B 20 -193 370 676 ;
-C -1 ; WX 556 ; N kcommaaccent ; B 22 -218 543 676 ;
-C -1 ; WX 570 ; N minus ; B 33 209 537 297 ;
-C -1 ; WX 389 ; N Icircumflex ; B 20 0 370 914 ;
-C -1 ; WX 556 ; N ncaron ; B 21 0 539 704 ;
-C -1 ; WX 333 ; N tcommaaccent ; B 20 -218 332 630 ;
-C -1 ; WX 570 ; N logicalnot ; B 33 108 537 399 ;
-C -1 ; WX 500 ; N odieresis ; B 25 -14 476 667 ;
-C -1 ; WX 556 ; N udieresis ; B 16 -14 537 667 ;
-C -1 ; WX 549 ; N notequal ; B 15 -49 540 570 ;
-C -1 ; WX 500 ; N gcommaaccent ; B 28 -206 483 829 ;
-C -1 ; WX 500 ; N eth ; B 25 -14 476 691 ;
-C -1 ; WX 444 ; N zcaron ; B 21 0 420 704 ;
-C -1 ; WX 556 ; N ncommaaccent ; B 21 -218 539 473 ;
-C -1 ; WX 300 ; N onesuperior ; B 28 275 273 688 ;
-C -1 ; WX 278 ; N imacron ; B -8 0 272 637 ;
-C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 2242
-KPX A C -55
-KPX A Cacute -55
-KPX A Ccaron -55
-KPX A Ccedilla -55
-KPX A G -55
-KPX A Gbreve -55
-KPX A Gcommaaccent -55
-KPX A O -45
-KPX A Oacute -45
-KPX A Ocircumflex -45
-KPX A Odieresis -45
-KPX A Ograve -45
-KPX A Ohungarumlaut -45
-KPX A Omacron -45
-KPX A Oslash -45
-KPX A Otilde -45
-KPX A Q -45
-KPX A T -95
-KPX A Tcaron -95
-KPX A Tcommaaccent -95
-KPX A U -50
-KPX A Uacute -50
-KPX A Ucircumflex -50
-KPX A Udieresis -50
-KPX A Ugrave -50
-KPX A Uhungarumlaut -50
-KPX A Umacron -50
-KPX A Uogonek -50
-KPX A Uring -50
-KPX A V -145
-KPX A W -130
-KPX A Y -100
-KPX A Yacute -100
-KPX A Ydieresis -100
-KPX A p -25
-KPX A quoteright -74
-KPX A u -50
-KPX A uacute -50
-KPX A ucircumflex -50
-KPX A udieresis -50
-KPX A ugrave -50
-KPX A uhungarumlaut -50
-KPX A umacron -50
-KPX A uogonek -50
-KPX A uring -50
-KPX A v -100
-KPX A w -90
-KPX A y -74
-KPX A yacute -74
-KPX A ydieresis -74
-KPX Aacute C -55
-KPX Aacute Cacute -55
-KPX Aacute Ccaron -55
-KPX Aacute Ccedilla -55
-KPX Aacute G -55
-KPX Aacute Gbreve -55
-KPX Aacute Gcommaaccent -55
-KPX Aacute O -45
-KPX Aacute Oacute -45
-KPX Aacute Ocircumflex -45
-KPX Aacute Odieresis -45
-KPX Aacute Ograve -45
-KPX Aacute Ohungarumlaut -45
-KPX Aacute Omacron -45
-KPX Aacute Oslash -45
-KPX Aacute Otilde -45
-KPX Aacute Q -45
-KPX Aacute T -95
-KPX Aacute Tcaron -95
-KPX Aacute Tcommaaccent -95
-KPX Aacute U -50
-KPX Aacute Uacute -50
-KPX Aacute Ucircumflex -50
-KPX Aacute Udieresis -50
-KPX Aacute Ugrave -50
-KPX Aacute Uhungarumlaut -50
-KPX Aacute Umacron -50
-KPX Aacute Uogonek -50
-KPX Aacute Uring -50
-KPX Aacute V -145
-KPX Aacute W -130
-KPX Aacute Y -100
-KPX Aacute Yacute -100
-KPX Aacute Ydieresis -100
-KPX Aacute p -25
-KPX Aacute quoteright -74
-KPX Aacute u -50
-KPX Aacute uacute -50
-KPX Aacute ucircumflex -50
-KPX Aacute udieresis -50
-KPX Aacute ugrave -50
-KPX Aacute uhungarumlaut -50
-KPX Aacute umacron -50
-KPX Aacute uogonek -50
-KPX Aacute uring -50
-KPX Aacute v -100
-KPX Aacute w -90
-KPX Aacute y -74
-KPX Aacute yacute -74
-KPX Aacute ydieresis -74
-KPX Abreve C -55
-KPX Abreve Cacute -55
-KPX Abreve Ccaron -55
-KPX Abreve Ccedilla -55
-KPX Abreve G -55
-KPX Abreve Gbreve -55
-KPX Abreve Gcommaaccent -55
-KPX Abreve O -45
-KPX Abreve Oacute -45
-KPX Abreve Ocircumflex -45
-KPX Abreve Odieresis -45
-KPX Abreve Ograve -45
-KPX Abreve Ohungarumlaut -45
-KPX Abreve Omacron -45
-KPX Abreve Oslash -45
-KPX Abreve Otilde -45
-KPX Abreve Q -45
-KPX Abreve T -95
-KPX Abreve Tcaron -95
-KPX Abreve Tcommaaccent -95
-KPX Abreve U -50
-KPX Abreve Uacute -50
-KPX Abreve Ucircumflex -50
-KPX Abreve Udieresis -50
-KPX Abreve Ugrave -50
-KPX Abreve Uhungarumlaut -50
-KPX Abreve Umacron -50
-KPX Abreve Uogonek -50
-KPX Abreve Uring -50
-KPX Abreve V -145
-KPX Abreve W -130
-KPX Abreve Y -100
-KPX Abreve Yacute -100
-KPX Abreve Ydieresis -100
-KPX Abreve p -25
-KPX Abreve quoteright -74
-KPX Abreve u -50
-KPX Abreve uacute -50
-KPX Abreve ucircumflex -50
-KPX Abreve udieresis -50
-KPX Abreve ugrave -50
-KPX Abreve uhungarumlaut -50
-KPX Abreve umacron -50
-KPX Abreve uogonek -50
-KPX Abreve uring -50
-KPX Abreve v -100
-KPX Abreve w -90
-KPX Abreve y -74
-KPX Abreve yacute -74
-KPX Abreve ydieresis -74
-KPX Acircumflex C -55
-KPX Acircumflex Cacute -55
-KPX Acircumflex Ccaron -55
-KPX Acircumflex Ccedilla -55
-KPX Acircumflex G -55
-KPX Acircumflex Gbreve -55
-KPX Acircumflex Gcommaaccent -55
-KPX Acircumflex O -45
-KPX Acircumflex Oacute -45
-KPX Acircumflex Ocircumflex -45
-KPX Acircumflex Odieresis -45
-KPX Acircumflex Ograve -45
-KPX Acircumflex Ohungarumlaut -45
-KPX Acircumflex Omacron -45
-KPX Acircumflex Oslash -45
-KPX Acircumflex Otilde -45
-KPX Acircumflex Q -45
-KPX Acircumflex T -95
-KPX Acircumflex Tcaron -95
-KPX Acircumflex Tcommaaccent -95
-KPX Acircumflex U -50
-KPX Acircumflex Uacute -50
-KPX Acircumflex Ucircumflex -50
-KPX Acircumflex Udieresis -50
-KPX Acircumflex Ugrave -50
-KPX Acircumflex Uhungarumlaut -50
-KPX Acircumflex Umacron -50
-KPX Acircumflex Uogonek -50
-KPX Acircumflex Uring -50
-KPX Acircumflex V -145
-KPX Acircumflex W -130
-KPX Acircumflex Y -100
-KPX Acircumflex Yacute -100
-KPX Acircumflex Ydieresis -100
-KPX Acircumflex p -25
-KPX Acircumflex quoteright -74
-KPX Acircumflex u -50
-KPX Acircumflex uacute -50
-KPX Acircumflex ucircumflex -50
-KPX Acircumflex udieresis -50
-KPX Acircumflex ugrave -50
-KPX Acircumflex uhungarumlaut -50
-KPX Acircumflex umacron -50
-KPX Acircumflex uogonek -50
-KPX Acircumflex uring -50
-KPX Acircumflex v -100
-KPX Acircumflex w -90
-KPX Acircumflex y -74
-KPX Acircumflex yacute -74
-KPX Acircumflex ydieresis -74
-KPX Adieresis C -55
-KPX Adieresis Cacute -55
-KPX Adieresis Ccaron -55
-KPX Adieresis Ccedilla -55
-KPX Adieresis G -55
-KPX Adieresis Gbreve -55
-KPX Adieresis Gcommaaccent -55
-KPX Adieresis O -45
-KPX Adieresis Oacute -45
-KPX Adieresis Ocircumflex -45
-KPX Adieresis Odieresis -45
-KPX Adieresis Ograve -45
-KPX Adieresis Ohungarumlaut -45
-KPX Adieresis Omacron -45
-KPX Adieresis Oslash -45
-KPX Adieresis Otilde -45
-KPX Adieresis Q -45
-KPX Adieresis T -95
-KPX Adieresis Tcaron -95
-KPX Adieresis Tcommaaccent -95
-KPX Adieresis U -50
-KPX Adieresis Uacute -50
-KPX Adieresis Ucircumflex -50
-KPX Adieresis Udieresis -50
-KPX Adieresis Ugrave -50
-KPX Adieresis Uhungarumlaut -50
-KPX Adieresis Umacron -50
-KPX Adieresis Uogonek -50
-KPX Adieresis Uring -50
-KPX Adieresis V -145
-KPX Adieresis W -130
-KPX Adieresis Y -100
-KPX Adieresis Yacute -100
-KPX Adieresis Ydieresis -100
-KPX Adieresis p -25
-KPX Adieresis quoteright -74
-KPX Adieresis u -50
-KPX Adieresis uacute -50
-KPX Adieresis ucircumflex -50
-KPX Adieresis udieresis -50
-KPX Adieresis ugrave -50
-KPX Adieresis uhungarumlaut -50
-KPX Adieresis umacron -50
-KPX Adieresis uogonek -50
-KPX Adieresis uring -50
-KPX Adieresis v -100
-KPX Adieresis w -90
-KPX Adieresis y -74
-KPX Adieresis yacute -74
-KPX Adieresis ydieresis -74
-KPX Agrave C -55
-KPX Agrave Cacute -55
-KPX Agrave Ccaron -55
-KPX Agrave Ccedilla -55
-KPX Agrave G -55
-KPX Agrave Gbreve -55
-KPX Agrave Gcommaaccent -55
-KPX Agrave O -45
-KPX Agrave Oacute -45
-KPX Agrave Ocircumflex -45
-KPX Agrave Odieresis -45
-KPX Agrave Ograve -45
-KPX Agrave Ohungarumlaut -45
-KPX Agrave Omacron -45
-KPX Agrave Oslash -45
-KPX Agrave Otilde -45
-KPX Agrave Q -45
-KPX Agrave T -95
-KPX Agrave Tcaron -95
-KPX Agrave Tcommaaccent -95
-KPX Agrave U -50
-KPX Agrave Uacute -50
-KPX Agrave Ucircumflex -50
-KPX Agrave Udieresis -50
-KPX Agrave Ugrave -50
-KPX Agrave Uhungarumlaut -50
-KPX Agrave Umacron -50
-KPX Agrave Uogonek -50
-KPX Agrave Uring -50
-KPX Agrave V -145
-KPX Agrave W -130
-KPX Agrave Y -100
-KPX Agrave Yacute -100
-KPX Agrave Ydieresis -100
-KPX Agrave p -25
-KPX Agrave quoteright -74
-KPX Agrave u -50
-KPX Agrave uacute -50
-KPX Agrave ucircumflex -50
-KPX Agrave udieresis -50
-KPX Agrave ugrave -50
-KPX Agrave uhungarumlaut -50
-KPX Agrave umacron -50
-KPX Agrave uogonek -50
-KPX Agrave uring -50
-KPX Agrave v -100
-KPX Agrave w -90
-KPX Agrave y -74
-KPX Agrave yacute -74
-KPX Agrave ydieresis -74
-KPX Amacron C -55
-KPX Amacron Cacute -55
-KPX Amacron Ccaron -55
-KPX Amacron Ccedilla -55
-KPX Amacron G -55
-KPX Amacron Gbreve -55
-KPX Amacron Gcommaaccent -55
-KPX Amacron O -45
-KPX Amacron Oacute -45
-KPX Amacron Ocircumflex -45
-KPX Amacron Odieresis -45
-KPX Amacron Ograve -45
-KPX Amacron Ohungarumlaut -45
-KPX Amacron Omacron -45
-KPX Amacron Oslash -45
-KPX Amacron Otilde -45
-KPX Amacron Q -45
-KPX Amacron T -95
-KPX Amacron Tcaron -95
-KPX Amacron Tcommaaccent -95
-KPX Amacron U -50
-KPX Amacron Uacute -50
-KPX Amacron Ucircumflex -50
-KPX Amacron Udieresis -50
-KPX Amacron Ugrave -50
-KPX Amacron Uhungarumlaut -50
-KPX Amacron Umacron -50
-KPX Amacron Uogonek -50
-KPX Amacron Uring -50
-KPX Amacron V -145
-KPX Amacron W -130
-KPX Amacron Y -100
-KPX Amacron Yacute -100
-KPX Amacron Ydieresis -100
-KPX Amacron p -25
-KPX Amacron quoteright -74
-KPX Amacron u -50
-KPX Amacron uacute -50
-KPX Amacron ucircumflex -50
-KPX Amacron udieresis -50
-KPX Amacron ugrave -50
-KPX Amacron uhungarumlaut -50
-KPX Amacron umacron -50
-KPX Amacron uogonek -50
-KPX Amacron uring -50
-KPX Amacron v -100
-KPX Amacron w -90
-KPX Amacron y -74
-KPX Amacron yacute -74
-KPX Amacron ydieresis -74
-KPX Aogonek C -55
-KPX Aogonek Cacute -55
-KPX Aogonek Ccaron -55
-KPX Aogonek Ccedilla -55
-KPX Aogonek G -55
-KPX Aogonek Gbreve -55
-KPX Aogonek Gcommaaccent -55
-KPX Aogonek O -45
-KPX Aogonek Oacute -45
-KPX Aogonek Ocircumflex -45
-KPX Aogonek Odieresis -45
-KPX Aogonek Ograve -45
-KPX Aogonek Ohungarumlaut -45
-KPX Aogonek Omacron -45
-KPX Aogonek Oslash -45
-KPX Aogonek Otilde -45
-KPX Aogonek Q -45
-KPX Aogonek T -95
-KPX Aogonek Tcaron -95
-KPX Aogonek Tcommaaccent -95
-KPX Aogonek U -50
-KPX Aogonek Uacute -50
-KPX Aogonek Ucircumflex -50
-KPX Aogonek Udieresis -50
-KPX Aogonek Ugrave -50
-KPX Aogonek Uhungarumlaut -50
-KPX Aogonek Umacron -50
-KPX Aogonek Uogonek -50
-KPX Aogonek Uring -50
-KPX Aogonek V -145
-KPX Aogonek W -130
-KPX Aogonek Y -100
-KPX Aogonek Yacute -100
-KPX Aogonek Ydieresis -100
-KPX Aogonek p -25
-KPX Aogonek quoteright -74
-KPX Aogonek u -50
-KPX Aogonek uacute -50
-KPX Aogonek ucircumflex -50
-KPX Aogonek udieresis -50
-KPX Aogonek ugrave -50
-KPX Aogonek uhungarumlaut -50
-KPX Aogonek umacron -50
-KPX Aogonek uogonek -50
-KPX Aogonek uring -50
-KPX Aogonek v -100
-KPX Aogonek w -90
-KPX Aogonek y -34
-KPX Aogonek yacute -34
-KPX Aogonek ydieresis -34
-KPX Aring C -55
-KPX Aring Cacute -55
-KPX Aring Ccaron -55
-KPX Aring Ccedilla -55
-KPX Aring G -55
-KPX Aring Gbreve -55
-KPX Aring Gcommaaccent -55
-KPX Aring O -45
-KPX Aring Oacute -45
-KPX Aring Ocircumflex -45
-KPX Aring Odieresis -45
-KPX Aring Ograve -45
-KPX Aring Ohungarumlaut -45
-KPX Aring Omacron -45
-KPX Aring Oslash -45
-KPX Aring Otilde -45
-KPX Aring Q -45
-KPX Aring T -95
-KPX Aring Tcaron -95
-KPX Aring Tcommaaccent -95
-KPX Aring U -50
-KPX Aring Uacute -50
-KPX Aring Ucircumflex -50
-KPX Aring Udieresis -50
-KPX Aring Ugrave -50
-KPX Aring Uhungarumlaut -50
-KPX Aring Umacron -50
-KPX Aring Uogonek -50
-KPX Aring Uring -50
-KPX Aring V -145
-KPX Aring W -130
-KPX Aring Y -100
-KPX Aring Yacute -100
-KPX Aring Ydieresis -100
-KPX Aring p -25
-KPX Aring quoteright -74
-KPX Aring u -50
-KPX Aring uacute -50
-KPX Aring ucircumflex -50
-KPX Aring udieresis -50
-KPX Aring ugrave -50
-KPX Aring uhungarumlaut -50
-KPX Aring umacron -50
-KPX Aring uogonek -50
-KPX Aring uring -50
-KPX Aring v -100
-KPX Aring w -90
-KPX Aring y -74
-KPX Aring yacute -74
-KPX Aring ydieresis -74
-KPX Atilde C -55
-KPX Atilde Cacute -55
-KPX Atilde Ccaron -55
-KPX Atilde Ccedilla -55
-KPX Atilde G -55
-KPX Atilde Gbreve -55
-KPX Atilde Gcommaaccent -55
-KPX Atilde O -45
-KPX Atilde Oacute -45
-KPX Atilde Ocircumflex -45
-KPX Atilde Odieresis -45
-KPX Atilde Ograve -45
-KPX Atilde Ohungarumlaut -45
-KPX Atilde Omacron -45
-KPX Atilde Oslash -45
-KPX Atilde Otilde -45
-KPX Atilde Q -45
-KPX Atilde T -95
-KPX Atilde Tcaron -95
-KPX Atilde Tcommaaccent -95
-KPX Atilde U -50
-KPX Atilde Uacute -50
-KPX Atilde Ucircumflex -50
-KPX Atilde Udieresis -50
-KPX Atilde Ugrave -50
-KPX Atilde Uhungarumlaut -50
-KPX Atilde Umacron -50
-KPX Atilde Uogonek -50
-KPX Atilde Uring -50
-KPX Atilde V -145
-KPX Atilde W -130
-KPX Atilde Y -100
-KPX Atilde Yacute -100
-KPX Atilde Ydieresis -100
-KPX Atilde p -25
-KPX Atilde quoteright -74
-KPX Atilde u -50
-KPX Atilde uacute -50
-KPX Atilde ucircumflex -50
-KPX Atilde udieresis -50
-KPX Atilde ugrave -50
-KPX Atilde uhungarumlaut -50
-KPX Atilde umacron -50
-KPX Atilde uogonek -50
-KPX Atilde uring -50
-KPX Atilde v -100
-KPX Atilde w -90
-KPX Atilde y -74
-KPX Atilde yacute -74
-KPX Atilde ydieresis -74
-KPX B A -30
-KPX B Aacute -30
-KPX B Abreve -30
-KPX B Acircumflex -30
-KPX B Adieresis -30
-KPX B Agrave -30
-KPX B Amacron -30
-KPX B Aogonek -30
-KPX B Aring -30
-KPX B Atilde -30
-KPX B U -10
-KPX B Uacute -10
-KPX B Ucircumflex -10
-KPX B Udieresis -10
-KPX B Ugrave -10
-KPX B Uhungarumlaut -10
-KPX B Umacron -10
-KPX B Uogonek -10
-KPX B Uring -10
-KPX D A -35
-KPX D Aacute -35
-KPX D Abreve -35
-KPX D Acircumflex -35
-KPX D Adieresis -35
-KPX D Agrave -35
-KPX D Amacron -35
-KPX D Aogonek -35
-KPX D Aring -35
-KPX D Atilde -35
-KPX D V -40
-KPX D W -40
-KPX D Y -40
-KPX D Yacute -40
-KPX D Ydieresis -40
-KPX D period -20
-KPX Dcaron A -35
-KPX Dcaron Aacute -35
-KPX Dcaron Abreve -35
-KPX Dcaron Acircumflex -35
-KPX Dcaron Adieresis -35
-KPX Dcaron Agrave -35
-KPX Dcaron Amacron -35
-KPX Dcaron Aogonek -35
-KPX Dcaron Aring -35
-KPX Dcaron Atilde -35
-KPX Dcaron V -40
-KPX Dcaron W -40
-KPX Dcaron Y -40
-KPX Dcaron Yacute -40
-KPX Dcaron Ydieresis -40
-KPX Dcaron period -20
-KPX Dcroat A -35
-KPX Dcroat Aacute -35
-KPX Dcroat Abreve -35
-KPX Dcroat Acircumflex -35
-KPX Dcroat Adieresis -35
-KPX Dcroat Agrave -35
-KPX Dcroat Amacron -35
-KPX Dcroat Aogonek -35
-KPX Dcroat Aring -35
-KPX Dcroat Atilde -35
-KPX Dcroat V -40
-KPX Dcroat W -40
-KPX Dcroat Y -40
-KPX Dcroat Yacute -40
-KPX Dcroat Ydieresis -40
-KPX Dcroat period -20
-KPX F A -90
-KPX F Aacute -90
-KPX F Abreve -90
-KPX F Acircumflex -90
-KPX F Adieresis -90
-KPX F Agrave -90
-KPX F Amacron -90
-KPX F Aogonek -90
-KPX F Aring -90
-KPX F Atilde -90
-KPX F a -25
-KPX F aacute -25
-KPX F abreve -25
-KPX F acircumflex -25
-KPX F adieresis -25
-KPX F agrave -25
-KPX F amacron -25
-KPX F aogonek -25
-KPX F aring -25
-KPX F atilde -25
-KPX F comma -92
-KPX F e -25
-KPX F eacute -25
-KPX F ecaron -25
-KPX F ecircumflex -25
-KPX F edieresis -25
-KPX F edotaccent -25
-KPX F egrave -25
-KPX F emacron -25
-KPX F eogonek -25
-KPX F o -25
-KPX F oacute -25
-KPX F ocircumflex -25
-KPX F odieresis -25
-KPX F ograve -25
-KPX F ohungarumlaut -25
-KPX F omacron -25
-KPX F oslash -25
-KPX F otilde -25
-KPX F period -110
-KPX J A -30
-KPX J Aacute -30
-KPX J Abreve -30
-KPX J Acircumflex -30
-KPX J Adieresis -30
-KPX J Agrave -30
-KPX J Amacron -30
-KPX J Aogonek -30
-KPX J Aring -30
-KPX J Atilde -30
-KPX J a -15
-KPX J aacute -15
-KPX J abreve -15
-KPX J acircumflex -15
-KPX J adieresis -15
-KPX J agrave -15
-KPX J amacron -15
-KPX J aogonek -15
-KPX J aring -15
-KPX J atilde -15
-KPX J e -15
-KPX J eacute -15
-KPX J ecaron -15
-KPX J ecircumflex -15
-KPX J edieresis -15
-KPX J edotaccent -15
-KPX J egrave -15
-KPX J emacron -15
-KPX J eogonek -15
-KPX J o -15
-KPX J oacute -15
-KPX J ocircumflex -15
-KPX J odieresis -15
-KPX J ograve -15
-KPX J ohungarumlaut -15
-KPX J omacron -15
-KPX J oslash -15
-KPX J otilde -15
-KPX J period -20
-KPX J u -15
-KPX J uacute -15
-KPX J ucircumflex -15
-KPX J udieresis -15
-KPX J ugrave -15
-KPX J uhungarumlaut -15
-KPX J umacron -15
-KPX J uogonek -15
-KPX J uring -15
-KPX K O -30
-KPX K Oacute -30
-KPX K Ocircumflex -30
-KPX K Odieresis -30
-KPX K Ograve -30
-KPX K Ohungarumlaut -30
-KPX K Omacron -30
-KPX K Oslash -30
-KPX K Otilde -30
-KPX K e -25
-KPX K eacute -25
-KPX K ecaron -25
-KPX K ecircumflex -25
-KPX K edieresis -25
-KPX K edotaccent -25
-KPX K egrave -25
-KPX K emacron -25
-KPX K eogonek -25
-KPX K o -25
-KPX K oacute -25
-KPX K ocircumflex -25
-KPX K odieresis -25
-KPX K ograve -25
-KPX K ohungarumlaut -25
-KPX K omacron -25
-KPX K oslash -25
-KPX K otilde -25
-KPX K u -15
-KPX K uacute -15
-KPX K ucircumflex -15
-KPX K udieresis -15
-KPX K ugrave -15
-KPX K uhungarumlaut -15
-KPX K umacron -15
-KPX K uogonek -15
-KPX K uring -15
-KPX K y -45
-KPX K yacute -45
-KPX K ydieresis -45
-KPX Kcommaaccent O -30
-KPX Kcommaaccent Oacute -30
-KPX Kcommaaccent Ocircumflex -30
-KPX Kcommaaccent Odieresis -30
-KPX Kcommaaccent Ograve -30
-KPX Kcommaaccent Ohungarumlaut -30
-KPX Kcommaaccent Omacron -30
-KPX Kcommaaccent Oslash -30
-KPX Kcommaaccent Otilde -30
-KPX Kcommaaccent e -25
-KPX Kcommaaccent eacute -25
-KPX Kcommaaccent ecaron -25
-KPX Kcommaaccent ecircumflex -25
-KPX Kcommaaccent edieresis -25
-KPX Kcommaaccent edotaccent -25
-KPX Kcommaaccent egrave -25
-KPX Kcommaaccent emacron -25
-KPX Kcommaaccent eogonek -25
-KPX Kcommaaccent o -25
-KPX Kcommaaccent oacute -25
-KPX Kcommaaccent ocircumflex -25
-KPX Kcommaaccent odieresis -25
-KPX Kcommaaccent ograve -25
-KPX Kcommaaccent ohungarumlaut -25
-KPX Kcommaaccent omacron -25
-KPX Kcommaaccent oslash -25
-KPX Kcommaaccent otilde -25
-KPX Kcommaaccent u -15
-KPX Kcommaaccent uacute -15
-KPX Kcommaaccent ucircumflex -15
-KPX Kcommaaccent udieresis -15
-KPX Kcommaaccent ugrave -15
-KPX Kcommaaccent uhungarumlaut -15
-KPX Kcommaaccent umacron -15
-KPX Kcommaaccent uogonek -15
-KPX Kcommaaccent uring -15
-KPX Kcommaaccent y -45
-KPX Kcommaaccent yacute -45
-KPX Kcommaaccent ydieresis -45
-KPX L T -92
-KPX L Tcaron -92
-KPX L Tcommaaccent -92
-KPX L V -92
-KPX L W -92
-KPX L Y -92
-KPX L Yacute -92
-KPX L Ydieresis -92
-KPX L quotedblright -20
-KPX L quoteright -110
-KPX L y -55
-KPX L yacute -55
-KPX L ydieresis -55
-KPX Lacute T -92
-KPX Lacute Tcaron -92
-KPX Lacute Tcommaaccent -92
-KPX Lacute V -92
-KPX Lacute W -92
-KPX Lacute Y -92
-KPX Lacute Yacute -92
-KPX Lacute Ydieresis -92
-KPX Lacute quotedblright -20
-KPX Lacute quoteright -110
-KPX Lacute y -55
-KPX Lacute yacute -55
-KPX Lacute ydieresis -55
-KPX Lcommaaccent T -92
-KPX Lcommaaccent Tcaron -92
-KPX Lcommaaccent Tcommaaccent -92
-KPX Lcommaaccent V -92
-KPX Lcommaaccent W -92
-KPX Lcommaaccent Y -92
-KPX Lcommaaccent Yacute -92
-KPX Lcommaaccent Ydieresis -92
-KPX Lcommaaccent quotedblright -20
-KPX Lcommaaccent quoteright -110
-KPX Lcommaaccent y -55
-KPX Lcommaaccent yacute -55
-KPX Lcommaaccent ydieresis -55
-KPX Lslash T -92
-KPX Lslash Tcaron -92
-KPX Lslash Tcommaaccent -92
-KPX Lslash V -92
-KPX Lslash W -92
-KPX Lslash Y -92
-KPX Lslash Yacute -92
-KPX Lslash Ydieresis -92
-KPX Lslash quotedblright -20
-KPX Lslash quoteright -110
-KPX Lslash y -55
-KPX Lslash yacute -55
-KPX Lslash ydieresis -55
-KPX N A -20
-KPX N Aacute -20
-KPX N Abreve -20
-KPX N Acircumflex -20
-KPX N Adieresis -20
-KPX N Agrave -20
-KPX N Amacron -20
-KPX N Aogonek -20
-KPX N Aring -20
-KPX N Atilde -20
-KPX Nacute A -20
-KPX Nacute Aacute -20
-KPX Nacute Abreve -20
-KPX Nacute Acircumflex -20
-KPX Nacute Adieresis -20
-KPX Nacute Agrave -20
-KPX Nacute Amacron -20
-KPX Nacute Aogonek -20
-KPX Nacute Aring -20
-KPX Nacute Atilde -20
-KPX Ncaron A -20
-KPX Ncaron Aacute -20
-KPX Ncaron Abreve -20
-KPX Ncaron Acircumflex -20
-KPX Ncaron Adieresis -20
-KPX Ncaron Agrave -20
-KPX Ncaron Amacron -20
-KPX Ncaron Aogonek -20
-KPX Ncaron Aring -20
-KPX Ncaron Atilde -20
-KPX Ncommaaccent A -20
-KPX Ncommaaccent Aacute -20
-KPX Ncommaaccent Abreve -20
-KPX Ncommaaccent Acircumflex -20
-KPX Ncommaaccent Adieresis -20
-KPX Ncommaaccent Agrave -20
-KPX Ncommaaccent Amacron -20
-KPX Ncommaaccent Aogonek -20
-KPX Ncommaaccent Aring -20
-KPX Ncommaaccent Atilde -20
-KPX Ntilde A -20
-KPX Ntilde Aacute -20
-KPX Ntilde Abreve -20
-KPX Ntilde Acircumflex -20
-KPX Ntilde Adieresis -20
-KPX Ntilde Agrave -20
-KPX Ntilde Amacron -20
-KPX Ntilde Aogonek -20
-KPX Ntilde Aring -20
-KPX Ntilde Atilde -20
-KPX O A -40
-KPX O Aacute -40
-KPX O Abreve -40
-KPX O Acircumflex -40
-KPX O Adieresis -40
-KPX O Agrave -40
-KPX O Amacron -40
-KPX O Aogonek -40
-KPX O Aring -40
-KPX O Atilde -40
-KPX O T -40
-KPX O Tcaron -40
-KPX O Tcommaaccent -40
-KPX O V -50
-KPX O W -50
-KPX O X -40
-KPX O Y -50
-KPX O Yacute -50
-KPX O Ydieresis -50
-KPX Oacute A -40
-KPX Oacute Aacute -40
-KPX Oacute Abreve -40
-KPX Oacute Acircumflex -40
-KPX Oacute Adieresis -40
-KPX Oacute Agrave -40
-KPX Oacute Amacron -40
-KPX Oacute Aogonek -40
-KPX Oacute Aring -40
-KPX Oacute Atilde -40
-KPX Oacute T -40
-KPX Oacute Tcaron -40
-KPX Oacute Tcommaaccent -40
-KPX Oacute V -50
-KPX Oacute W -50
-KPX Oacute X -40
-KPX Oacute Y -50
-KPX Oacute Yacute -50
-KPX Oacute Ydieresis -50
-KPX Ocircumflex A -40
-KPX Ocircumflex Aacute -40
-KPX Ocircumflex Abreve -40
-KPX Ocircumflex Acircumflex -40
-KPX Ocircumflex Adieresis -40
-KPX Ocircumflex Agrave -40
-KPX Ocircumflex Amacron -40
-KPX Ocircumflex Aogonek -40
-KPX Ocircumflex Aring -40
-KPX Ocircumflex Atilde -40
-KPX Ocircumflex T -40
-KPX Ocircumflex Tcaron -40
-KPX Ocircumflex Tcommaaccent -40
-KPX Ocircumflex V -50
-KPX Ocircumflex W -50
-KPX Ocircumflex X -40
-KPX Ocircumflex Y -50
-KPX Ocircumflex Yacute -50
-KPX Ocircumflex Ydieresis -50
-KPX Odieresis A -40
-KPX Odieresis Aacute -40
-KPX Odieresis Abreve -40
-KPX Odieresis Acircumflex -40
-KPX Odieresis Adieresis -40
-KPX Odieresis Agrave -40
-KPX Odieresis Amacron -40
-KPX Odieresis Aogonek -40
-KPX Odieresis Aring -40
-KPX Odieresis Atilde -40
-KPX Odieresis T -40
-KPX Odieresis Tcaron -40
-KPX Odieresis Tcommaaccent -40
-KPX Odieresis V -50
-KPX Odieresis W -50
-KPX Odieresis X -40
-KPX Odieresis Y -50
-KPX Odieresis Yacute -50
-KPX Odieresis Ydieresis -50
-KPX Ograve A -40
-KPX Ograve Aacute -40
-KPX Ograve Abreve -40
-KPX Ograve Acircumflex -40
-KPX Ograve Adieresis -40
-KPX Ograve Agrave -40
-KPX Ograve Amacron -40
-KPX Ograve Aogonek -40
-KPX Ograve Aring -40
-KPX Ograve Atilde -40
-KPX Ograve T -40
-KPX Ograve Tcaron -40
-KPX Ograve Tcommaaccent -40
-KPX Ograve V -50
-KPX Ograve W -50
-KPX Ograve X -40
-KPX Ograve Y -50
-KPX Ograve Yacute -50
-KPX Ograve Ydieresis -50
-KPX Ohungarumlaut A -40
-KPX Ohungarumlaut Aacute -40
-KPX Ohungarumlaut Abreve -40
-KPX Ohungarumlaut Acircumflex -40
-KPX Ohungarumlaut Adieresis -40
-KPX Ohungarumlaut Agrave -40
-KPX Ohungarumlaut Amacron -40
-KPX Ohungarumlaut Aogonek -40
-KPX Ohungarumlaut Aring -40
-KPX Ohungarumlaut Atilde -40
-KPX Ohungarumlaut T -40
-KPX Ohungarumlaut Tcaron -40
-KPX Ohungarumlaut Tcommaaccent -40
-KPX Ohungarumlaut V -50
-KPX Ohungarumlaut W -50
-KPX Ohungarumlaut X -40
-KPX Ohungarumlaut Y -50
-KPX Ohungarumlaut Yacute -50
-KPX Ohungarumlaut Ydieresis -50
-KPX Omacron A -40
-KPX Omacron Aacute -40
-KPX Omacron Abreve -40
-KPX Omacron Acircumflex -40
-KPX Omacron Adieresis -40
-KPX Omacron Agrave -40
-KPX Omacron Amacron -40
-KPX Omacron Aogonek -40
-KPX Omacron Aring -40
-KPX Omacron Atilde -40
-KPX Omacron T -40
-KPX Omacron Tcaron -40
-KPX Omacron Tcommaaccent -40
-KPX Omacron V -50
-KPX Omacron W -50
-KPX Omacron X -40
-KPX Omacron Y -50
-KPX Omacron Yacute -50
-KPX Omacron Ydieresis -50
-KPX Oslash A -40
-KPX Oslash Aacute -40
-KPX Oslash Abreve -40
-KPX Oslash Acircumflex -40
-KPX Oslash Adieresis -40
-KPX Oslash Agrave -40
-KPX Oslash Amacron -40
-KPX Oslash Aogonek -40
-KPX Oslash Aring -40
-KPX Oslash Atilde -40
-KPX Oslash T -40
-KPX Oslash Tcaron -40
-KPX Oslash Tcommaaccent -40
-KPX Oslash V -50
-KPX Oslash W -50
-KPX Oslash X -40
-KPX Oslash Y -50
-KPX Oslash Yacute -50
-KPX Oslash Ydieresis -50
-KPX Otilde A -40
-KPX Otilde Aacute -40
-KPX Otilde Abreve -40
-KPX Otilde Acircumflex -40
-KPX Otilde Adieresis -40
-KPX Otilde Agrave -40
-KPX Otilde Amacron -40
-KPX Otilde Aogonek -40
-KPX Otilde Aring -40
-KPX Otilde Atilde -40
-KPX Otilde T -40
-KPX Otilde Tcaron -40
-KPX Otilde Tcommaaccent -40
-KPX Otilde V -50
-KPX Otilde W -50
-KPX Otilde X -40
-KPX Otilde Y -50
-KPX Otilde Yacute -50
-KPX Otilde Ydieresis -50
-KPX P A -74
-KPX P Aacute -74
-KPX P Abreve -74
-KPX P Acircumflex -74
-KPX P Adieresis -74
-KPX P Agrave -74
-KPX P Amacron -74
-KPX P Aogonek -74
-KPX P Aring -74
-KPX P Atilde -74
-KPX P a -10
-KPX P aacute -10
-KPX P abreve -10
-KPX P acircumflex -10
-KPX P adieresis -10
-KPX P agrave -10
-KPX P amacron -10
-KPX P aogonek -10
-KPX P aring -10
-KPX P atilde -10
-KPX P comma -92
-KPX P e -20
-KPX P eacute -20
-KPX P ecaron -20
-KPX P ecircumflex -20
-KPX P edieresis -20
-KPX P edotaccent -20
-KPX P egrave -20
-KPX P emacron -20
-KPX P eogonek -20
-KPX P o -20
-KPX P oacute -20
-KPX P ocircumflex -20
-KPX P odieresis -20
-KPX P ograve -20
-KPX P ohungarumlaut -20
-KPX P omacron -20
-KPX P oslash -20
-KPX P otilde -20
-KPX P period -110
-KPX Q U -10
-KPX Q Uacute -10
-KPX Q Ucircumflex -10
-KPX Q Udieresis -10
-KPX Q Ugrave -10
-KPX Q Uhungarumlaut -10
-KPX Q Umacron -10
-KPX Q Uogonek -10
-KPX Q Uring -10
-KPX Q period -20
-KPX R O -30
-KPX R Oacute -30
-KPX R Ocircumflex -30
-KPX R Odieresis -30
-KPX R Ograve -30
-KPX R Ohungarumlaut -30
-KPX R Omacron -30
-KPX R Oslash -30
-KPX R Otilde -30
-KPX R T -40
-KPX R Tcaron -40
-KPX R Tcommaaccent -40
-KPX R U -30
-KPX R Uacute -30
-KPX R Ucircumflex -30
-KPX R Udieresis -30
-KPX R Ugrave -30
-KPX R Uhungarumlaut -30
-KPX R Umacron -30
-KPX R Uogonek -30
-KPX R Uring -30
-KPX R V -55
-KPX R W -35
-KPX R Y -35
-KPX R Yacute -35
-KPX R Ydieresis -35
-KPX Racute O -30
-KPX Racute Oacute -30
-KPX Racute Ocircumflex -30
-KPX Racute Odieresis -30
-KPX Racute Ograve -30
-KPX Racute Ohungarumlaut -30
-KPX Racute Omacron -30
-KPX Racute Oslash -30
-KPX Racute Otilde -30
-KPX Racute T -40
-KPX Racute Tcaron -40
-KPX Racute Tcommaaccent -40
-KPX Racute U -30
-KPX Racute Uacute -30
-KPX Racute Ucircumflex -30
-KPX Racute Udieresis -30
-KPX Racute Ugrave -30
-KPX Racute Uhungarumlaut -30
-KPX Racute Umacron -30
-KPX Racute Uogonek -30
-KPX Racute Uring -30
-KPX Racute V -55
-KPX Racute W -35
-KPX Racute Y -35
-KPX Racute Yacute -35
-KPX Racute Ydieresis -35
-KPX Rcaron O -30
-KPX Rcaron Oacute -30
-KPX Rcaron Ocircumflex -30
-KPX Rcaron Odieresis -30
-KPX Rcaron Ograve -30
-KPX Rcaron Ohungarumlaut -30
-KPX Rcaron Omacron -30
-KPX Rcaron Oslash -30
-KPX Rcaron Otilde -30
-KPX Rcaron T -40
-KPX Rcaron Tcaron -40
-KPX Rcaron Tcommaaccent -40
-KPX Rcaron U -30
-KPX Rcaron Uacute -30
-KPX Rcaron Ucircumflex -30
-KPX Rcaron Udieresis -30
-KPX Rcaron Ugrave -30
-KPX Rcaron Uhungarumlaut -30
-KPX Rcaron Umacron -30
-KPX Rcaron Uogonek -30
-KPX Rcaron Uring -30
-KPX Rcaron V -55
-KPX Rcaron W -35
-KPX Rcaron Y -35
-KPX Rcaron Yacute -35
-KPX Rcaron Ydieresis -35
-KPX Rcommaaccent O -30
-KPX Rcommaaccent Oacute -30
-KPX Rcommaaccent Ocircumflex -30
-KPX Rcommaaccent Odieresis -30
-KPX Rcommaaccent Ograve -30
-KPX Rcommaaccent Ohungarumlaut -30
-KPX Rcommaaccent Omacron -30
-KPX Rcommaaccent Oslash -30
-KPX Rcommaaccent Otilde -30
-KPX Rcommaaccent T -40
-KPX Rcommaaccent Tcaron -40
-KPX Rcommaaccent Tcommaaccent -40
-KPX Rcommaaccent U -30
-KPX Rcommaaccent Uacute -30
-KPX Rcommaaccent Ucircumflex -30
-KPX Rcommaaccent Udieresis -30
-KPX Rcommaaccent Ugrave -30
-KPX Rcommaaccent Uhungarumlaut -30
-KPX Rcommaaccent Umacron -30
-KPX Rcommaaccent Uogonek -30
-KPX Rcommaaccent Uring -30
-KPX Rcommaaccent V -55
-KPX Rcommaaccent W -35
-KPX Rcommaaccent Y -35
-KPX Rcommaaccent Yacute -35
-KPX Rcommaaccent Ydieresis -35
-KPX T A -90
-KPX T Aacute -90
-KPX T Abreve -90
-KPX T Acircumflex -90
-KPX T Adieresis -90
-KPX T Agrave -90
-KPX T Amacron -90
-KPX T Aogonek -90
-KPX T Aring -90
-KPX T Atilde -90
-KPX T O -18
-KPX T Oacute -18
-KPX T Ocircumflex -18
-KPX T Odieresis -18
-KPX T Ograve -18
-KPX T Ohungarumlaut -18
-KPX T Omacron -18
-KPX T Oslash -18
-KPX T Otilde -18
-KPX T a -92
-KPX T aacute -92
-KPX T abreve -52
-KPX T acircumflex -52
-KPX T adieresis -52
-KPX T agrave -52
-KPX T amacron -52
-KPX T aogonek -92
-KPX T aring -92
-KPX T atilde -52
-KPX T colon -74
-KPX T comma -74
-KPX T e -92
-KPX T eacute -92
-KPX T ecaron -92
-KPX T ecircumflex -92
-KPX T edieresis -52
-KPX T edotaccent -92
-KPX T egrave -52
-KPX T emacron -52
-KPX T eogonek -92
-KPX T hyphen -92
-KPX T i -18
-KPX T iacute -18
-KPX T iogonek -18
-KPX T o -92
-KPX T oacute -92
-KPX T ocircumflex -92
-KPX T odieresis -92
-KPX T ograve -92
-KPX T ohungarumlaut -92
-KPX T omacron -92
-KPX T oslash -92
-KPX T otilde -92
-KPX T period -90
-KPX T r -74
-KPX T racute -74
-KPX T rcaron -74
-KPX T rcommaaccent -74
-KPX T semicolon -74
-KPX T u -92
-KPX T uacute -92
-KPX T ucircumflex -92
-KPX T udieresis -92
-KPX T ugrave -92
-KPX T uhungarumlaut -92
-KPX T umacron -92
-KPX T uogonek -92
-KPX T uring -92
-KPX T w -74
-KPX T y -34
-KPX T yacute -34
-KPX T ydieresis -34
-KPX Tcaron A -90
-KPX Tcaron Aacute -90
-KPX Tcaron Abreve -90
-KPX Tcaron Acircumflex -90
-KPX Tcaron Adieresis -90
-KPX Tcaron Agrave -90
-KPX Tcaron Amacron -90
-KPX Tcaron Aogonek -90
-KPX Tcaron Aring -90
-KPX Tcaron Atilde -90
-KPX Tcaron O -18
-KPX Tcaron Oacute -18
-KPX Tcaron Ocircumflex -18
-KPX Tcaron Odieresis -18
-KPX Tcaron Ograve -18
-KPX Tcaron Ohungarumlaut -18
-KPX Tcaron Omacron -18
-KPX Tcaron Oslash -18
-KPX Tcaron Otilde -18
-KPX Tcaron a -92
-KPX Tcaron aacute -92
-KPX Tcaron abreve -52
-KPX Tcaron acircumflex -52
-KPX Tcaron adieresis -52
-KPX Tcaron agrave -52
-KPX Tcaron amacron -52
-KPX Tcaron aogonek -92
-KPX Tcaron aring -92
-KPX Tcaron atilde -52
-KPX Tcaron colon -74
-KPX Tcaron comma -74
-KPX Tcaron e -92
-KPX Tcaron eacute -92
-KPX Tcaron ecaron -92
-KPX Tcaron ecircumflex -92
-KPX Tcaron edieresis -52
-KPX Tcaron edotaccent -92
-KPX Tcaron egrave -52
-KPX Tcaron emacron -52
-KPX Tcaron eogonek -92
-KPX Tcaron hyphen -92
-KPX Tcaron i -18
-KPX Tcaron iacute -18
-KPX Tcaron iogonek -18
-KPX Tcaron o -92
-KPX Tcaron oacute -92
-KPX Tcaron ocircumflex -92
-KPX Tcaron odieresis -92
-KPX Tcaron ograve -92
-KPX Tcaron ohungarumlaut -92
-KPX Tcaron omacron -92
-KPX Tcaron oslash -92
-KPX Tcaron otilde -92
-KPX Tcaron period -90
-KPX Tcaron r -74
-KPX Tcaron racute -74
-KPX Tcaron rcaron -74
-KPX Tcaron rcommaaccent -74
-KPX Tcaron semicolon -74
-KPX Tcaron u -92
-KPX Tcaron uacute -92
-KPX Tcaron ucircumflex -92
-KPX Tcaron udieresis -92
-KPX Tcaron ugrave -92
-KPX Tcaron uhungarumlaut -92
-KPX Tcaron umacron -92
-KPX Tcaron uogonek -92
-KPX Tcaron uring -92
-KPX Tcaron w -74
-KPX Tcaron y -34
-KPX Tcaron yacute -34
-KPX Tcaron ydieresis -34
-KPX Tcommaaccent A -90
-KPX Tcommaaccent Aacute -90
-KPX Tcommaaccent Abreve -90
-KPX Tcommaaccent Acircumflex -90
-KPX Tcommaaccent Adieresis -90
-KPX Tcommaaccent Agrave -90
-KPX Tcommaaccent Amacron -90
-KPX Tcommaaccent Aogonek -90
-KPX Tcommaaccent Aring -90
-KPX Tcommaaccent Atilde -90
-KPX Tcommaaccent O -18
-KPX Tcommaaccent Oacute -18
-KPX Tcommaaccent Ocircumflex -18
-KPX Tcommaaccent Odieresis -18
-KPX Tcommaaccent Ograve -18
-KPX Tcommaaccent Ohungarumlaut -18
-KPX Tcommaaccent Omacron -18
-KPX Tcommaaccent Oslash -18
-KPX Tcommaaccent Otilde -18
-KPX Tcommaaccent a -92
-KPX Tcommaaccent aacute -92
-KPX Tcommaaccent abreve -52
-KPX Tcommaaccent acircumflex -52
-KPX Tcommaaccent adieresis -52
-KPX Tcommaaccent agrave -52
-KPX Tcommaaccent amacron -52
-KPX Tcommaaccent aogonek -92
-KPX Tcommaaccent aring -92
-KPX Tcommaaccent atilde -52
-KPX Tcommaaccent colon -74
-KPX Tcommaaccent comma -74
-KPX Tcommaaccent e -92
-KPX Tcommaaccent eacute -92
-KPX Tcommaaccent ecaron -92
-KPX Tcommaaccent ecircumflex -92
-KPX Tcommaaccent edieresis -52
-KPX Tcommaaccent edotaccent -92
-KPX Tcommaaccent egrave -52
-KPX Tcommaaccent emacron -52
-KPX Tcommaaccent eogonek -92
-KPX Tcommaaccent hyphen -92
-KPX Tcommaaccent i -18
-KPX Tcommaaccent iacute -18
-KPX Tcommaaccent iogonek -18
-KPX Tcommaaccent o -92
-KPX Tcommaaccent oacute -92
-KPX Tcommaaccent ocircumflex -92
-KPX Tcommaaccent odieresis -92
-KPX Tcommaaccent ograve -92
-KPX Tcommaaccent ohungarumlaut -92
-KPX Tcommaaccent omacron -92
-KPX Tcommaaccent oslash -92
-KPX Tcommaaccent otilde -92
-KPX Tcommaaccent period -90
-KPX Tcommaaccent r -74
-KPX Tcommaaccent racute -74
-KPX Tcommaaccent rcaron -74
-KPX Tcommaaccent rcommaaccent -74
-KPX Tcommaaccent semicolon -74
-KPX Tcommaaccent u -92
-KPX Tcommaaccent uacute -92
-KPX Tcommaaccent ucircumflex -92
-KPX Tcommaaccent udieresis -92
-KPX Tcommaaccent ugrave -92
-KPX Tcommaaccent uhungarumlaut -92
-KPX Tcommaaccent umacron -92
-KPX Tcommaaccent uogonek -92
-KPX Tcommaaccent uring -92
-KPX Tcommaaccent w -74
-KPX Tcommaaccent y -34
-KPX Tcommaaccent yacute -34
-KPX Tcommaaccent ydieresis -34
-KPX U A -60
-KPX U Aacute -60
-KPX U Abreve -60
-KPX U Acircumflex -60
-KPX U Adieresis -60
-KPX U Agrave -60
-KPX U Amacron -60
-KPX U Aogonek -60
-KPX U Aring -60
-KPX U Atilde -60
-KPX U comma -50
-KPX U period -50
-KPX Uacute A -60
-KPX Uacute Aacute -60
-KPX Uacute Abreve -60
-KPX Uacute Acircumflex -60
-KPX Uacute Adieresis -60
-KPX Uacute Agrave -60
-KPX Uacute Amacron -60
-KPX Uacute Aogonek -60
-KPX Uacute Aring -60
-KPX Uacute Atilde -60
-KPX Uacute comma -50
-KPX Uacute period -50
-KPX Ucircumflex A -60
-KPX Ucircumflex Aacute -60
-KPX Ucircumflex Abreve -60
-KPX Ucircumflex Acircumflex -60
-KPX Ucircumflex Adieresis -60
-KPX Ucircumflex Agrave -60
-KPX Ucircumflex Amacron -60
-KPX Ucircumflex Aogonek -60
-KPX Ucircumflex Aring -60
-KPX Ucircumflex Atilde -60
-KPX Ucircumflex comma -50
-KPX Ucircumflex period -50
-KPX Udieresis A -60
-KPX Udieresis Aacute -60
-KPX Udieresis Abreve -60
-KPX Udieresis Acircumflex -60
-KPX Udieresis Adieresis -60
-KPX Udieresis Agrave -60
-KPX Udieresis Amacron -60
-KPX Udieresis Aogonek -60
-KPX Udieresis Aring -60
-KPX Udieresis Atilde -60
-KPX Udieresis comma -50
-KPX Udieresis period -50
-KPX Ugrave A -60
-KPX Ugrave Aacute -60
-KPX Ugrave Abreve -60
-KPX Ugrave Acircumflex -60
-KPX Ugrave Adieresis -60
-KPX Ugrave Agrave -60
-KPX Ugrave Amacron -60
-KPX Ugrave Aogonek -60
-KPX Ugrave Aring -60
-KPX Ugrave Atilde -60
-KPX Ugrave comma -50
-KPX Ugrave period -50
-KPX Uhungarumlaut A -60
-KPX Uhungarumlaut Aacute -60
-KPX Uhungarumlaut Abreve -60
-KPX Uhungarumlaut Acircumflex -60
-KPX Uhungarumlaut Adieresis -60
-KPX Uhungarumlaut Agrave -60
-KPX Uhungarumlaut Amacron -60
-KPX Uhungarumlaut Aogonek -60
-KPX Uhungarumlaut Aring -60
-KPX Uhungarumlaut Atilde -60
-KPX Uhungarumlaut comma -50
-KPX Uhungarumlaut period -50
-KPX Umacron A -60
-KPX Umacron Aacute -60
-KPX Umacron Abreve -60
-KPX Umacron Acircumflex -60
-KPX Umacron Adieresis -60
-KPX Umacron Agrave -60
-KPX Umacron Amacron -60
-KPX Umacron Aogonek -60
-KPX Umacron Aring -60
-KPX Umacron Atilde -60
-KPX Umacron comma -50
-KPX Umacron period -50
-KPX Uogonek A -60
-KPX Uogonek Aacute -60
-KPX Uogonek Abreve -60
-KPX Uogonek Acircumflex -60
-KPX Uogonek Adieresis -60
-KPX Uogonek Agrave -60
-KPX Uogonek Amacron -60
-KPX Uogonek Aogonek -60
-KPX Uogonek Aring -60
-KPX Uogonek Atilde -60
-KPX Uogonek comma -50
-KPX Uogonek period -50
-KPX Uring A -60
-KPX Uring Aacute -60
-KPX Uring Abreve -60
-KPX Uring Acircumflex -60
-KPX Uring Adieresis -60
-KPX Uring Agrave -60
-KPX Uring Amacron -60
-KPX Uring Aogonek -60
-KPX Uring Aring -60
-KPX Uring Atilde -60
-KPX Uring comma -50
-KPX Uring period -50
-KPX V A -135
-KPX V Aacute -135
-KPX V Abreve -135
-KPX V Acircumflex -135
-KPX V Adieresis -135
-KPX V Agrave -135
-KPX V Amacron -135
-KPX V Aogonek -135
-KPX V Aring -135
-KPX V Atilde -135
-KPX V G -30
-KPX V Gbreve -30
-KPX V Gcommaaccent -30
-KPX V O -45
-KPX V Oacute -45
-KPX V Ocircumflex -45
-KPX V Odieresis -45
-KPX V Ograve -45
-KPX V Ohungarumlaut -45
-KPX V Omacron -45
-KPX V Oslash -45
-KPX V Otilde -45
-KPX V a -92
-KPX V aacute -92
-KPX V abreve -92
-KPX V acircumflex -92
-KPX V adieresis -92
-KPX V agrave -92
-KPX V amacron -92
-KPX V aogonek -92
-KPX V aring -92
-KPX V atilde -92
-KPX V colon -92
-KPX V comma -129
-KPX V e -100
-KPX V eacute -100
-KPX V ecaron -100
-KPX V ecircumflex -100
-KPX V edieresis -100
-KPX V edotaccent -100
-KPX V egrave -100
-KPX V emacron -100
-KPX V eogonek -100
-KPX V hyphen -74
-KPX V i -37
-KPX V iacute -37
-KPX V icircumflex -37
-KPX V idieresis -37
-KPX V igrave -37
-KPX V imacron -37
-KPX V iogonek -37
-KPX V o -100
-KPX V oacute -100
-KPX V ocircumflex -100
-KPX V odieresis -100
-KPX V ograve -100
-KPX V ohungarumlaut -100
-KPX V omacron -100
-KPX V oslash -100
-KPX V otilde -100
-KPX V period -145
-KPX V semicolon -92
-KPX V u -92
-KPX V uacute -92
-KPX V ucircumflex -92
-KPX V udieresis -92
-KPX V ugrave -92
-KPX V uhungarumlaut -92
-KPX V umacron -92
-KPX V uogonek -92
-KPX V uring -92
-KPX W A -120
-KPX W Aacute -120
-KPX W Abreve -120
-KPX W Acircumflex -120
-KPX W Adieresis -120
-KPX W Agrave -120
-KPX W Amacron -120
-KPX W Aogonek -120
-KPX W Aring -120
-KPX W Atilde -120
-KPX W O -10
-KPX W Oacute -10
-KPX W Ocircumflex -10
-KPX W Odieresis -10
-KPX W Ograve -10
-KPX W Ohungarumlaut -10
-KPX W Omacron -10
-KPX W Oslash -10
-KPX W Otilde -10
-KPX W a -65
-KPX W aacute -65
-KPX W abreve -65
-KPX W acircumflex -65
-KPX W adieresis -65
-KPX W agrave -65
-KPX W amacron -65
-KPX W aogonek -65
-KPX W aring -65
-KPX W atilde -65
-KPX W colon -55
-KPX W comma -92
-KPX W e -65
-KPX W eacute -65
-KPX W ecaron -65
-KPX W ecircumflex -65
-KPX W edieresis -65
-KPX W edotaccent -65
-KPX W egrave -65
-KPX W emacron -65
-KPX W eogonek -65
-KPX W hyphen -37
-KPX W i -18
-KPX W iacute -18
-KPX W iogonek -18
-KPX W o -75
-KPX W oacute -75
-KPX W ocircumflex -75
-KPX W odieresis -75
-KPX W ograve -75
-KPX W ohungarumlaut -75
-KPX W omacron -75
-KPX W oslash -75
-KPX W otilde -75
-KPX W period -92
-KPX W semicolon -55
-KPX W u -50
-KPX W uacute -50
-KPX W ucircumflex -50
-KPX W udieresis -50
-KPX W ugrave -50
-KPX W uhungarumlaut -50
-KPX W umacron -50
-KPX W uogonek -50
-KPX W uring -50
-KPX W y -60
-KPX W yacute -60
-KPX W ydieresis -60
-KPX Y A -110
-KPX Y Aacute -110
-KPX Y Abreve -110
-KPX Y Acircumflex -110
-KPX Y Adieresis -110
-KPX Y Agrave -110
-KPX Y Amacron -110
-KPX Y Aogonek -110
-KPX Y Aring -110
-KPX Y Atilde -110
-KPX Y O -35
-KPX Y Oacute -35
-KPX Y Ocircumflex -35
-KPX Y Odieresis -35
-KPX Y Ograve -35
-KPX Y Ohungarumlaut -35
-KPX Y Omacron -35
-KPX Y Oslash -35
-KPX Y Otilde -35
-KPX Y a -85
-KPX Y aacute -85
-KPX Y abreve -85
-KPX Y acircumflex -85
-KPX Y adieresis -85
-KPX Y agrave -85
-KPX Y amacron -85
-KPX Y aogonek -85
-KPX Y aring -85
-KPX Y atilde -85
-KPX Y colon -92
-KPX Y comma -92
-KPX Y e -111
-KPX Y eacute -111
-KPX Y ecaron -111
-KPX Y ecircumflex -111
-KPX Y edieresis -71
-KPX Y edotaccent -111
-KPX Y egrave -71
-KPX Y emacron -71
-KPX Y eogonek -111
-KPX Y hyphen -92
-KPX Y i -37
-KPX Y iacute -37
-KPX Y iogonek -37
-KPX Y o -111
-KPX Y oacute -111
-KPX Y ocircumflex -111
-KPX Y odieresis -111
-KPX Y ograve -111
-KPX Y ohungarumlaut -111
-KPX Y omacron -111
-KPX Y oslash -111
-KPX Y otilde -111
-KPX Y period -92
-KPX Y semicolon -92
-KPX Y u -92
-KPX Y uacute -92
-KPX Y ucircumflex -92
-KPX Y udieresis -92
-KPX Y ugrave -92
-KPX Y uhungarumlaut -92
-KPX Y umacron -92
-KPX Y uogonek -92
-KPX Y uring -92
-KPX Yacute A -110
-KPX Yacute Aacute -110
-KPX Yacute Abreve -110
-KPX Yacute Acircumflex -110
-KPX Yacute Adieresis -110
-KPX Yacute Agrave -110
-KPX Yacute Amacron -110
-KPX Yacute Aogonek -110
-KPX Yacute Aring -110
-KPX Yacute Atilde -110
-KPX Yacute O -35
-KPX Yacute Oacute -35
-KPX Yacute Ocircumflex -35
-KPX Yacute Odieresis -35
-KPX Yacute Ograve -35
-KPX Yacute Ohungarumlaut -35
-KPX Yacute Omacron -35
-KPX Yacute Oslash -35
-KPX Yacute Otilde -35
-KPX Yacute a -85
-KPX Yacute aacute -85
-KPX Yacute abreve -85
-KPX Yacute acircumflex -85
-KPX Yacute adieresis -85
-KPX Yacute agrave -85
-KPX Yacute amacron -85
-KPX Yacute aogonek -85
-KPX Yacute aring -85
-KPX Yacute atilde -85
-KPX Yacute colon -92
-KPX Yacute comma -92
-KPX Yacute e -111
-KPX Yacute eacute -111
-KPX Yacute ecaron -111
-KPX Yacute ecircumflex -111
-KPX Yacute edieresis -71
-KPX Yacute edotaccent -111
-KPX Yacute egrave -71
-KPX Yacute emacron -71
-KPX Yacute eogonek -111
-KPX Yacute hyphen -92
-KPX Yacute i -37
-KPX Yacute iacute -37
-KPX Yacute iogonek -37
-KPX Yacute o -111
-KPX Yacute oacute -111
-KPX Yacute ocircumflex -111
-KPX Yacute odieresis -111
-KPX Yacute ograve -111
-KPX Yacute ohungarumlaut -111
-KPX Yacute omacron -111
-KPX Yacute oslash -111
-KPX Yacute otilde -111
-KPX Yacute period -92
-KPX Yacute semicolon -92
-KPX Yacute u -92
-KPX Yacute uacute -92
-KPX Yacute ucircumflex -92
-KPX Yacute udieresis -92
-KPX Yacute ugrave -92
-KPX Yacute uhungarumlaut -92
-KPX Yacute umacron -92
-KPX Yacute uogonek -92
-KPX Yacute uring -92
-KPX Ydieresis A -110
-KPX Ydieresis Aacute -110
-KPX Ydieresis Abreve -110
-KPX Ydieresis Acircumflex -110
-KPX Ydieresis Adieresis -110
-KPX Ydieresis Agrave -110
-KPX Ydieresis Amacron -110
-KPX Ydieresis Aogonek -110
-KPX Ydieresis Aring -110
-KPX Ydieresis Atilde -110
-KPX Ydieresis O -35
-KPX Ydieresis Oacute -35
-KPX Ydieresis Ocircumflex -35
-KPX Ydieresis Odieresis -35
-KPX Ydieresis Ograve -35
-KPX Ydieresis Ohungarumlaut -35
-KPX Ydieresis Omacron -35
-KPX Ydieresis Oslash -35
-KPX Ydieresis Otilde -35
-KPX Ydieresis a -85
-KPX Ydieresis aacute -85
-KPX Ydieresis abreve -85
-KPX Ydieresis acircumflex -85
-KPX Ydieresis adieresis -85
-KPX Ydieresis agrave -85
-KPX Ydieresis amacron -85
-KPX Ydieresis aogonek -85
-KPX Ydieresis aring -85
-KPX Ydieresis atilde -85
-KPX Ydieresis colon -92
-KPX Ydieresis comma -92
-KPX Ydieresis e -111
-KPX Ydieresis eacute -111
-KPX Ydieresis ecaron -111
-KPX Ydieresis ecircumflex -111
-KPX Ydieresis edieresis -71
-KPX Ydieresis edotaccent -111
-KPX Ydieresis egrave -71
-KPX Ydieresis emacron -71
-KPX Ydieresis eogonek -111
-KPX Ydieresis hyphen -92
-KPX Ydieresis i -37
-KPX Ydieresis iacute -37
-KPX Ydieresis iogonek -37
-KPX Ydieresis o -111
-KPX Ydieresis oacute -111
-KPX Ydieresis ocircumflex -111
-KPX Ydieresis odieresis -111
-KPX Ydieresis ograve -111
-KPX Ydieresis ohungarumlaut -111
-KPX Ydieresis omacron -111
-KPX Ydieresis oslash -111
-KPX Ydieresis otilde -111
-KPX Ydieresis period -92
-KPX Ydieresis semicolon -92
-KPX Ydieresis u -92
-KPX Ydieresis uacute -92
-KPX Ydieresis ucircumflex -92
-KPX Ydieresis udieresis -92
-KPX Ydieresis ugrave -92
-KPX Ydieresis uhungarumlaut -92
-KPX Ydieresis umacron -92
-KPX Ydieresis uogonek -92
-KPX Ydieresis uring -92
-KPX a v -25
-KPX aacute v -25
-KPX abreve v -25
-KPX acircumflex v -25
-KPX adieresis v -25
-KPX agrave v -25
-KPX amacron v -25
-KPX aogonek v -25
-KPX aring v -25
-KPX atilde v -25
-KPX b b -10
-KPX b period -40
-KPX b u -20
-KPX b uacute -20
-KPX b ucircumflex -20
-KPX b udieresis -20
-KPX b ugrave -20
-KPX b uhungarumlaut -20
-KPX b umacron -20
-KPX b uogonek -20
-KPX b uring -20
-KPX b v -15
-KPX comma quotedblright -45
-KPX comma quoteright -55
-KPX d w -15
-KPX dcroat w -15
-KPX e v -15
-KPX eacute v -15
-KPX ecaron v -15
-KPX ecircumflex v -15
-KPX edieresis v -15
-KPX edotaccent v -15
-KPX egrave v -15
-KPX emacron v -15
-KPX eogonek v -15
-KPX f comma -15
-KPX f dotlessi -35
-KPX f i -25
-KPX f o -25
-KPX f oacute -25
-KPX f ocircumflex -25
-KPX f odieresis -25
-KPX f ograve -25
-KPX f ohungarumlaut -25
-KPX f omacron -25
-KPX f oslash -25
-KPX f otilde -25
-KPX f period -15
-KPX f quotedblright 50
-KPX f quoteright 55
-KPX g period -15
-KPX gbreve period -15
-KPX gcommaaccent period -15
-KPX h y -15
-KPX h yacute -15
-KPX h ydieresis -15
-KPX i v -10
-KPX iacute v -10
-KPX icircumflex v -10
-KPX idieresis v -10
-KPX igrave v -10
-KPX imacron v -10
-KPX iogonek v -10
-KPX k e -10
-KPX k eacute -10
-KPX k ecaron -10
-KPX k ecircumflex -10
-KPX k edieresis -10
-KPX k edotaccent -10
-KPX k egrave -10
-KPX k emacron -10
-KPX k eogonek -10
-KPX k o -15
-KPX k oacute -15
-KPX k ocircumflex -15
-KPX k odieresis -15
-KPX k ograve -15
-KPX k ohungarumlaut -15
-KPX k omacron -15
-KPX k oslash -15
-KPX k otilde -15
-KPX k y -15
-KPX k yacute -15
-KPX k ydieresis -15
-KPX kcommaaccent e -10
-KPX kcommaaccent eacute -10
-KPX kcommaaccent ecaron -10
-KPX kcommaaccent ecircumflex -10
-KPX kcommaaccent edieresis -10
-KPX kcommaaccent edotaccent -10
-KPX kcommaaccent egrave -10
-KPX kcommaaccent emacron -10
-KPX kcommaaccent eogonek -10
-KPX kcommaaccent o -15
-KPX kcommaaccent oacute -15
-KPX kcommaaccent ocircumflex -15
-KPX kcommaaccent odieresis -15
-KPX kcommaaccent ograve -15
-KPX kcommaaccent ohungarumlaut -15
-KPX kcommaaccent omacron -15
-KPX kcommaaccent oslash -15
-KPX kcommaaccent otilde -15
-KPX kcommaaccent y -15
-KPX kcommaaccent yacute -15
-KPX kcommaaccent ydieresis -15
-KPX n v -40
-KPX nacute v -40
-KPX ncaron v -40
-KPX ncommaaccent v -40
-KPX ntilde v -40
-KPX o v -10
-KPX o w -10
-KPX oacute v -10
-KPX oacute w -10
-KPX ocircumflex v -10
-KPX ocircumflex w -10
-KPX odieresis v -10
-KPX odieresis w -10
-KPX ograve v -10
-KPX ograve w -10
-KPX ohungarumlaut v -10
-KPX ohungarumlaut w -10
-KPX omacron v -10
-KPX omacron w -10
-KPX oslash v -10
-KPX oslash w -10
-KPX otilde v -10
-KPX otilde w -10
-KPX period quotedblright -55
-KPX period quoteright -55
-KPX quotedblleft A -10
-KPX quotedblleft Aacute -10
-KPX quotedblleft Abreve -10
-KPX quotedblleft Acircumflex -10
-KPX quotedblleft Adieresis -10
-KPX quotedblleft Agrave -10
-KPX quotedblleft Amacron -10
-KPX quotedblleft Aogonek -10
-KPX quotedblleft Aring -10
-KPX quotedblleft Atilde -10
-KPX quoteleft A -10
-KPX quoteleft Aacute -10
-KPX quoteleft Abreve -10
-KPX quoteleft Acircumflex -10
-KPX quoteleft Adieresis -10
-KPX quoteleft Agrave -10
-KPX quoteleft Amacron -10
-KPX quoteleft Aogonek -10
-KPX quoteleft Aring -10
-KPX quoteleft Atilde -10
-KPX quoteleft quoteleft -63
-KPX quoteright d -20
-KPX quoteright dcroat -20
-KPX quoteright quoteright -63
-KPX quoteright r -20
-KPX quoteright racute -20
-KPX quoteright rcaron -20
-KPX quoteright rcommaaccent -20
-KPX quoteright s -37
-KPX quoteright sacute -37
-KPX quoteright scaron -37
-KPX quoteright scedilla -37
-KPX quoteright scommaaccent -37
-KPX quoteright space -74
-KPX quoteright v -20
-KPX r c -18
-KPX r cacute -18
-KPX r ccaron -18
-KPX r ccedilla -18
-KPX r comma -92
-KPX r e -18
-KPX r eacute -18
-KPX r ecaron -18
-KPX r ecircumflex -18
-KPX r edieresis -18
-KPX r edotaccent -18
-KPX r egrave -18
-KPX r emacron -18
-KPX r eogonek -18
-KPX r g -10
-KPX r gbreve -10
-KPX r gcommaaccent -10
-KPX r hyphen -37
-KPX r n -15
-KPX r nacute -15
-KPX r ncaron -15
-KPX r ncommaaccent -15
-KPX r ntilde -15
-KPX r o -18
-KPX r oacute -18
-KPX r ocircumflex -18
-KPX r odieresis -18
-KPX r ograve -18
-KPX r ohungarumlaut -18
-KPX r omacron -18
-KPX r oslash -18
-KPX r otilde -18
-KPX r p -10
-KPX r period -100
-KPX r q -18
-KPX r v -10
-KPX racute c -18
-KPX racute cacute -18
-KPX racute ccaron -18
-KPX racute ccedilla -18
-KPX racute comma -92
-KPX racute e -18
-KPX racute eacute -18
-KPX racute ecaron -18
-KPX racute ecircumflex -18
-KPX racute edieresis -18
-KPX racute edotaccent -18
-KPX racute egrave -18
-KPX racute emacron -18
-KPX racute eogonek -18
-KPX racute g -10
-KPX racute gbreve -10
-KPX racute gcommaaccent -10
-KPX racute hyphen -37
-KPX racute n -15
-KPX racute nacute -15
-KPX racute ncaron -15
-KPX racute ncommaaccent -15
-KPX racute ntilde -15
-KPX racute o -18
-KPX racute oacute -18
-KPX racute ocircumflex -18
-KPX racute odieresis -18
-KPX racute ograve -18
-KPX racute ohungarumlaut -18
-KPX racute omacron -18
-KPX racute oslash -18
-KPX racute otilde -18
-KPX racute p -10
-KPX racute period -100
-KPX racute q -18
-KPX racute v -10
-KPX rcaron c -18
-KPX rcaron cacute -18
-KPX rcaron ccaron -18
-KPX rcaron ccedilla -18
-KPX rcaron comma -92
-KPX rcaron e -18
-KPX rcaron eacute -18
-KPX rcaron ecaron -18
-KPX rcaron ecircumflex -18
-KPX rcaron edieresis -18
-KPX rcaron edotaccent -18
-KPX rcaron egrave -18
-KPX rcaron emacron -18
-KPX rcaron eogonek -18
-KPX rcaron g -10
-KPX rcaron gbreve -10
-KPX rcaron gcommaaccent -10
-KPX rcaron hyphen -37
-KPX rcaron n -15
-KPX rcaron nacute -15
-KPX rcaron ncaron -15
-KPX rcaron ncommaaccent -15
-KPX rcaron ntilde -15
-KPX rcaron o -18
-KPX rcaron oacute -18
-KPX rcaron ocircumflex -18
-KPX rcaron odieresis -18
-KPX rcaron ograve -18
-KPX rcaron ohungarumlaut -18
-KPX rcaron omacron -18
-KPX rcaron oslash -18
-KPX rcaron otilde -18
-KPX rcaron p -10
-KPX rcaron period -100
-KPX rcaron q -18
-KPX rcaron v -10
-KPX rcommaaccent c -18
-KPX rcommaaccent cacute -18
-KPX rcommaaccent ccaron -18
-KPX rcommaaccent ccedilla -18
-KPX rcommaaccent comma -92
-KPX rcommaaccent e -18
-KPX rcommaaccent eacute -18
-KPX rcommaaccent ecaron -18
-KPX rcommaaccent ecircumflex -18
-KPX rcommaaccent edieresis -18
-KPX rcommaaccent edotaccent -18
-KPX rcommaaccent egrave -18
-KPX rcommaaccent emacron -18
-KPX rcommaaccent eogonek -18
-KPX rcommaaccent g -10
-KPX rcommaaccent gbreve -10
-KPX rcommaaccent gcommaaccent -10
-KPX rcommaaccent hyphen -37
-KPX rcommaaccent n -15
-KPX rcommaaccent nacute -15
-KPX rcommaaccent ncaron -15
-KPX rcommaaccent ncommaaccent -15
-KPX rcommaaccent ntilde -15
-KPX rcommaaccent o -18
-KPX rcommaaccent oacute -18
-KPX rcommaaccent ocircumflex -18
-KPX rcommaaccent odieresis -18
-KPX rcommaaccent ograve -18
-KPX rcommaaccent ohungarumlaut -18
-KPX rcommaaccent omacron -18
-KPX rcommaaccent oslash -18
-KPX rcommaaccent otilde -18
-KPX rcommaaccent p -10
-KPX rcommaaccent period -100
-KPX rcommaaccent q -18
-KPX rcommaaccent v -10
-KPX space A -55
-KPX space Aacute -55
-KPX space Abreve -55
-KPX space Acircumflex -55
-KPX space Adieresis -55
-KPX space Agrave -55
-KPX space Amacron -55
-KPX space Aogonek -55
-KPX space Aring -55
-KPX space Atilde -55
-KPX space T -30
-KPX space Tcaron -30
-KPX space Tcommaaccent -30
-KPX space V -45
-KPX space W -30
-KPX space Y -55
-KPX space Yacute -55
-KPX space Ydieresis -55
-KPX v a -10
-KPX v aacute -10
-KPX v abreve -10
-KPX v acircumflex -10
-KPX v adieresis -10
-KPX v agrave -10
-KPX v amacron -10
-KPX v aogonek -10
-KPX v aring -10
-KPX v atilde -10
-KPX v comma -55
-KPX v e -10
-KPX v eacute -10
-KPX v ecaron -10
-KPX v ecircumflex -10
-KPX v edieresis -10
-KPX v edotaccent -10
-KPX v egrave -10
-KPX v emacron -10
-KPX v eogonek -10
-KPX v o -10
-KPX v oacute -10
-KPX v ocircumflex -10
-KPX v odieresis -10
-KPX v ograve -10
-KPX v ohungarumlaut -10
-KPX v omacron -10
-KPX v oslash -10
-KPX v otilde -10
-KPX v period -70
-KPX w comma -55
-KPX w o -10
-KPX w oacute -10
-KPX w ocircumflex -10
-KPX w odieresis -10
-KPX w ograve -10
-KPX w ohungarumlaut -10
-KPX w omacron -10
-KPX w oslash -10
-KPX w otilde -10
-KPX w period -70
-KPX y comma -55
-KPX y e -10
-KPX y eacute -10
-KPX y ecaron -10
-KPX y ecircumflex -10
-KPX y edieresis -10
-KPX y edotaccent -10
-KPX y egrave -10
-KPX y emacron -10
-KPX y eogonek -10
-KPX y o -25
-KPX y oacute -25
-KPX y ocircumflex -25
-KPX y odieresis -25
-KPX y ograve -25
-KPX y ohungarumlaut -25
-KPX y omacron -25
-KPX y oslash -25
-KPX y otilde -25
-KPX y period -70
-KPX yacute comma -55
-KPX yacute e -10
-KPX yacute eacute -10
-KPX yacute ecaron -10
-KPX yacute ecircumflex -10
-KPX yacute edieresis -10
-KPX yacute edotaccent -10
-KPX yacute egrave -10
-KPX yacute emacron -10
-KPX yacute eogonek -10
-KPX yacute o -25
-KPX yacute oacute -25
-KPX yacute ocircumflex -25
-KPX yacute odieresis -25
-KPX yacute ograve -25
-KPX yacute ohungarumlaut -25
-KPX yacute omacron -25
-KPX yacute oslash -25
-KPX yacute otilde -25
-KPX yacute period -70
-KPX ydieresis comma -55
-KPX ydieresis e -10
-KPX ydieresis eacute -10
-KPX ydieresis ecaron -10
-KPX ydieresis ecircumflex -10
-KPX ydieresis edieresis -10
-KPX ydieresis edotaccent -10
-KPX ydieresis egrave -10
-KPX ydieresis emacron -10
-KPX ydieresis eogonek -10
-KPX ydieresis o -25
-KPX ydieresis oacute -25
-KPX ydieresis ocircumflex -25
-KPX ydieresis odieresis -25
-KPX ydieresis ograve -25
-KPX ydieresis ohungarumlaut -25
-KPX ydieresis omacron -25
-KPX ydieresis oslash -25
-KPX ydieresis otilde -25
-KPX ydieresis period -70
-EndKernPairs
-EndKernData
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Times-BoldItalic.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Times-BoldItalic.afm
deleted file mode 100644
index 2301dfd232..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Times-BoldItalic.afm
+++ /dev/null
@@ -1,2384 +0,0 @@
-StartFontMetrics 4.1
-Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Thu May 1 13:04:06 1997
-Comment UniqueID 43066
-Comment VMusage 45874 56899
-FontName Times-BoldItalic
-FullName Times Bold Italic
-FamilyName Times
-Weight Bold
-ItalicAngle -15
-IsFixedPitch false
-CharacterSet ExtendedRoman
-FontBBox -200 -218 996 921
-UnderlinePosition -100
-UnderlineThickness 50
-Version 002.000
-Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 669
-XHeight 462
-Ascender 683
-Descender -217
-StdHW 42
-StdVW 121
-StartCharMetrics 315
-C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 389 ; N exclam ; B 67 -13 370 684 ;
-C 34 ; WX 555 ; N quotedbl ; B 136 398 536 685 ;
-C 35 ; WX 500 ; N numbersign ; B -33 0 533 700 ;
-C 36 ; WX 500 ; N dollar ; B -20 -100 497 733 ;
-C 37 ; WX 833 ; N percent ; B 39 -10 793 692 ;
-C 38 ; WX 778 ; N ampersand ; B 5 -19 699 682 ;
-C 39 ; WX 333 ; N quoteright ; B 98 369 302 685 ;
-C 40 ; WX 333 ; N parenleft ; B 28 -179 344 685 ;
-C 41 ; WX 333 ; N parenright ; B -44 -179 271 685 ;
-C 42 ; WX 500 ; N asterisk ; B 65 249 456 685 ;
-C 43 ; WX 570 ; N plus ; B 33 0 537 506 ;
-C 44 ; WX 250 ; N comma ; B -60 -182 144 134 ;
-C 45 ; WX 333 ; N hyphen ; B 2 166 271 282 ;
-C 46 ; WX 250 ; N period ; B -9 -13 139 135 ;
-C 47 ; WX 278 ; N slash ; B -64 -18 342 685 ;
-C 48 ; WX 500 ; N zero ; B 17 -14 477 683 ;
-C 49 ; WX 500 ; N one ; B 5 0 419 683 ;
-C 50 ; WX 500 ; N two ; B -27 0 446 683 ;
-C 51 ; WX 500 ; N three ; B -15 -13 450 683 ;
-C 52 ; WX 500 ; N four ; B -15 0 503 683 ;
-C 53 ; WX 500 ; N five ; B -11 -13 487 669 ;
-C 54 ; WX 500 ; N six ; B 23 -15 509 679 ;
-C 55 ; WX 500 ; N seven ; B 52 0 525 669 ;
-C 56 ; WX 500 ; N eight ; B 3 -13 476 683 ;
-C 57 ; WX 500 ; N nine ; B -12 -10 475 683 ;
-C 58 ; WX 333 ; N colon ; B 23 -13 264 459 ;
-C 59 ; WX 333 ; N semicolon ; B -25 -183 264 459 ;
-C 60 ; WX 570 ; N less ; B 31 -8 539 514 ;
-C 61 ; WX 570 ; N equal ; B 33 107 537 399 ;
-C 62 ; WX 570 ; N greater ; B 31 -8 539 514 ;
-C 63 ; WX 500 ; N question ; B 79 -13 470 684 ;
-C 64 ; WX 832 ; N at ; B 63 -18 770 685 ;
-C 65 ; WX 667 ; N A ; B -67 0 593 683 ;
-C 66 ; WX 667 ; N B ; B -24 0 624 669 ;
-C 67 ; WX 667 ; N C ; B 32 -18 677 685 ;
-C 68 ; WX 722 ; N D ; B -46 0 685 669 ;
-C 69 ; WX 667 ; N E ; B -27 0 653 669 ;
-C 70 ; WX 667 ; N F ; B -13 0 660 669 ;
-C 71 ; WX 722 ; N G ; B 21 -18 706 685 ;
-C 72 ; WX 778 ; N H ; B -24 0 799 669 ;
-C 73 ; WX 389 ; N I ; B -32 0 406 669 ;
-C 74 ; WX 500 ; N J ; B -46 -99 524 669 ;
-C 75 ; WX 667 ; N K ; B -21 0 702 669 ;
-C 76 ; WX 611 ; N L ; B -22 0 590 669 ;
-C 77 ; WX 889 ; N M ; B -29 -12 917 669 ;
-C 78 ; WX 722 ; N N ; B -27 -15 748 669 ;
-C 79 ; WX 722 ; N O ; B 27 -18 691 685 ;
-C 80 ; WX 611 ; N P ; B -27 0 613 669 ;
-C 81 ; WX 722 ; N Q ; B 27 -208 691 685 ;
-C 82 ; WX 667 ; N R ; B -29 0 623 669 ;
-C 83 ; WX 556 ; N S ; B 2 -18 526 685 ;
-C 84 ; WX 611 ; N T ; B 50 0 650 669 ;
-C 85 ; WX 722 ; N U ; B 67 -18 744 669 ;
-C 86 ; WX 667 ; N V ; B 65 -18 715 669 ;
-C 87 ; WX 889 ; N W ; B 65 -18 940 669 ;
-C 88 ; WX 667 ; N X ; B -24 0 694 669 ;
-C 89 ; WX 611 ; N Y ; B 73 0 659 669 ;
-C 90 ; WX 611 ; N Z ; B -11 0 590 669 ;
-C 91 ; WX 333 ; N bracketleft ; B -37 -159 362 674 ;
-C 92 ; WX 278 ; N backslash ; B -1 -18 279 685 ;
-C 93 ; WX 333 ; N bracketright ; B -56 -157 343 674 ;
-C 94 ; WX 570 ; N asciicircum ; B 67 304 503 669 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 333 ; N quoteleft ; B 128 369 332 685 ;
-C 97 ; WX 500 ; N a ; B -21 -14 455 462 ;
-C 98 ; WX 500 ; N b ; B -14 -13 444 699 ;
-C 99 ; WX 444 ; N c ; B -5 -13 392 462 ;
-C 100 ; WX 500 ; N d ; B -21 -13 517 699 ;
-C 101 ; WX 444 ; N e ; B 5 -13 398 462 ;
-C 102 ; WX 333 ; N f ; B -169 -205 446 698 ; L i fi ; L l fl ;
-C 103 ; WX 500 ; N g ; B -52 -203 478 462 ;
-C 104 ; WX 556 ; N h ; B -13 -9 498 699 ;
-C 105 ; WX 278 ; N i ; B 2 -9 263 684 ;
-C 106 ; WX 278 ; N j ; B -189 -207 279 684 ;
-C 107 ; WX 500 ; N k ; B -23 -8 483 699 ;
-C 108 ; WX 278 ; N l ; B 2 -9 290 699 ;
-C 109 ; WX 778 ; N m ; B -14 -9 722 462 ;
-C 110 ; WX 556 ; N n ; B -6 -9 493 462 ;
-C 111 ; WX 500 ; N o ; B -3 -13 441 462 ;
-C 112 ; WX 500 ; N p ; B -120 -205 446 462 ;
-C 113 ; WX 500 ; N q ; B 1 -205 471 462 ;
-C 114 ; WX 389 ; N r ; B -21 0 389 462 ;
-C 115 ; WX 389 ; N s ; B -19 -13 333 462 ;
-C 116 ; WX 278 ; N t ; B -11 -9 281 594 ;
-C 117 ; WX 556 ; N u ; B 15 -9 492 462 ;
-C 118 ; WX 444 ; N v ; B 16 -13 401 462 ;
-C 119 ; WX 667 ; N w ; B 16 -13 614 462 ;
-C 120 ; WX 500 ; N x ; B -46 -13 469 462 ;
-C 121 ; WX 444 ; N y ; B -94 -205 392 462 ;
-C 122 ; WX 389 ; N z ; B -43 -78 368 449 ;
-C 123 ; WX 348 ; N braceleft ; B 5 -187 436 686 ;
-C 124 ; WX 220 ; N bar ; B 66 -218 154 782 ;
-C 125 ; WX 348 ; N braceright ; B -129 -187 302 686 ;
-C 126 ; WX 570 ; N asciitilde ; B 54 173 516 333 ;
-C 161 ; WX 389 ; N exclamdown ; B 19 -205 322 492 ;
-C 162 ; WX 500 ; N cent ; B 42 -143 439 576 ;
-C 163 ; WX 500 ; N sterling ; B -32 -12 510 683 ;
-C 164 ; WX 167 ; N fraction ; B -169 -14 324 683 ;
-C 165 ; WX 500 ; N yen ; B 33 0 628 669 ;
-C 166 ; WX 500 ; N florin ; B -87 -156 537 707 ;
-C 167 ; WX 500 ; N section ; B 36 -143 459 685 ;
-C 168 ; WX 500 ; N currency ; B -26 34 526 586 ;
-C 169 ; WX 278 ; N quotesingle ; B 128 398 268 685 ;
-C 170 ; WX 500 ; N quotedblleft ; B 53 369 513 685 ;
-C 171 ; WX 500 ; N guillemotleft ; B 12 32 468 415 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 32 32 303 415 ;
-C 173 ; WX 333 ; N guilsinglright ; B 10 32 281 415 ;
-C 174 ; WX 556 ; N fi ; B -188 -205 514 703 ;
-C 175 ; WX 556 ; N fl ; B -186 -205 553 704 ;
-C 177 ; WX 500 ; N endash ; B -40 178 477 269 ;
-C 178 ; WX 500 ; N dagger ; B 91 -145 494 685 ;
-C 179 ; WX 500 ; N daggerdbl ; B 10 -139 493 685 ;
-C 180 ; WX 250 ; N periodcentered ; B 51 257 199 405 ;
-C 182 ; WX 500 ; N paragraph ; B -57 -193 562 669 ;
-C 183 ; WX 350 ; N bullet ; B 0 175 350 525 ;
-C 184 ; WX 333 ; N quotesinglbase ; B -5 -182 199 134 ;
-C 185 ; WX 500 ; N quotedblbase ; B -57 -182 403 134 ;
-C 186 ; WX 500 ; N quotedblright ; B 53 369 513 685 ;
-C 187 ; WX 500 ; N guillemotright ; B 12 32 468 415 ;
-C 188 ; WX 1000 ; N ellipsis ; B 40 -13 852 135 ;
-C 189 ; WX 1000 ; N perthousand ; B 7 -29 996 706 ;
-C 191 ; WX 500 ; N questiondown ; B 30 -205 421 492 ;
-C 193 ; WX 333 ; N grave ; B 85 516 297 697 ;
-C 194 ; WX 333 ; N acute ; B 139 516 379 697 ;
-C 195 ; WX 333 ; N circumflex ; B 40 516 367 690 ;
-C 196 ; WX 333 ; N tilde ; B 48 536 407 655 ;
-C 197 ; WX 333 ; N macron ; B 51 553 393 623 ;
-C 198 ; WX 333 ; N breve ; B 71 516 387 678 ;
-C 199 ; WX 333 ; N dotaccent ; B 163 550 298 684 ;
-C 200 ; WX 333 ; N dieresis ; B 55 550 402 684 ;
-C 202 ; WX 333 ; N ring ; B 127 516 340 729 ;
-C 203 ; WX 333 ; N cedilla ; B -80 -218 156 5 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 69 516 498 697 ;
-C 206 ; WX 333 ; N ogonek ; B 15 -183 244 34 ;
-C 207 ; WX 333 ; N caron ; B 79 516 411 690 ;
-C 208 ; WX 1000 ; N emdash ; B -40 178 977 269 ;
-C 225 ; WX 944 ; N AE ; B -64 0 918 669 ;
-C 227 ; WX 266 ; N ordfeminine ; B 16 399 330 685 ;
-C 232 ; WX 611 ; N Lslash ; B -22 0 590 669 ;
-C 233 ; WX 722 ; N Oslash ; B 27 -125 691 764 ;
-C 234 ; WX 944 ; N OE ; B 23 -8 946 677 ;
-C 235 ; WX 300 ; N ordmasculine ; B 56 400 347 685 ;
-C 241 ; WX 722 ; N ae ; B -5 -13 673 462 ;
-C 245 ; WX 278 ; N dotlessi ; B 2 -9 238 462 ;
-C 248 ; WX 278 ; N lslash ; B -7 -9 307 699 ;
-C 249 ; WX 500 ; N oslash ; B -3 -119 441 560 ;
-C 250 ; WX 722 ; N oe ; B 6 -13 674 462 ;
-C 251 ; WX 500 ; N germandbls ; B -200 -200 473 705 ;
-C -1 ; WX 389 ; N Idieresis ; B -32 0 450 862 ;
-C -1 ; WX 444 ; N eacute ; B 5 -13 435 697 ;
-C -1 ; WX 500 ; N abreve ; B -21 -14 471 678 ;
-C -1 ; WX 556 ; N uhungarumlaut ; B 15 -9 610 697 ;
-C -1 ; WX 444 ; N ecaron ; B 5 -13 467 690 ;
-C -1 ; WX 611 ; N Ydieresis ; B 73 0 659 862 ;
-C -1 ; WX 570 ; N divide ; B 33 -29 537 535 ;
-C -1 ; WX 611 ; N Yacute ; B 73 0 659 904 ;
-C -1 ; WX 667 ; N Acircumflex ; B -67 0 593 897 ;
-C -1 ; WX 500 ; N aacute ; B -21 -14 463 697 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 67 -18 744 897 ;
-C -1 ; WX 444 ; N yacute ; B -94 -205 435 697 ;
-C -1 ; WX 389 ; N scommaaccent ; B -19 -218 333 462 ;
-C -1 ; WX 444 ; N ecircumflex ; B 5 -13 423 690 ;
-C -1 ; WX 722 ; N Uring ; B 67 -18 744 921 ;
-C -1 ; WX 722 ; N Udieresis ; B 67 -18 744 862 ;
-C -1 ; WX 500 ; N aogonek ; B -21 -183 455 462 ;
-C -1 ; WX 722 ; N Uacute ; B 67 -18 744 904 ;
-C -1 ; WX 556 ; N uogonek ; B 15 -183 492 462 ;
-C -1 ; WX 667 ; N Edieresis ; B -27 0 653 862 ;
-C -1 ; WX 722 ; N Dcroat ; B -31 0 700 669 ;
-C -1 ; WX 250 ; N commaaccent ; B -36 -218 131 -50 ;
-C -1 ; WX 747 ; N copyright ; B 30 -18 718 685 ;
-C -1 ; WX 667 ; N Emacron ; B -27 0 653 830 ;
-C -1 ; WX 444 ; N ccaron ; B -5 -13 467 690 ;
-C -1 ; WX 500 ; N aring ; B -21 -14 455 729 ;
-C -1 ; WX 722 ; N Ncommaaccent ; B -27 -218 748 669 ;
-C -1 ; WX 278 ; N lacute ; B 2 -9 392 904 ;
-C -1 ; WX 500 ; N agrave ; B -21 -14 455 697 ;
-C -1 ; WX 611 ; N Tcommaaccent ; B 50 -218 650 669 ;
-C -1 ; WX 667 ; N Cacute ; B 32 -18 677 904 ;
-C -1 ; WX 500 ; N atilde ; B -21 -14 491 655 ;
-C -1 ; WX 667 ; N Edotaccent ; B -27 0 653 862 ;
-C -1 ; WX 389 ; N scaron ; B -19 -13 424 690 ;
-C -1 ; WX 389 ; N scedilla ; B -19 -218 333 462 ;
-C -1 ; WX 278 ; N iacute ; B 2 -9 352 697 ;
-C -1 ; WX 494 ; N lozenge ; B 10 0 484 745 ;
-C -1 ; WX 667 ; N Rcaron ; B -29 0 623 897 ;
-C -1 ; WX 722 ; N Gcommaaccent ; B 21 -218 706 685 ;
-C -1 ; WX 556 ; N ucircumflex ; B 15 -9 492 690 ;
-C -1 ; WX 500 ; N acircumflex ; B -21 -14 455 690 ;
-C -1 ; WX 667 ; N Amacron ; B -67 0 593 830 ;
-C -1 ; WX 389 ; N rcaron ; B -21 0 424 690 ;
-C -1 ; WX 444 ; N ccedilla ; B -5 -218 392 462 ;
-C -1 ; WX 611 ; N Zdotaccent ; B -11 0 590 862 ;
-C -1 ; WX 611 ; N Thorn ; B -27 0 573 669 ;
-C -1 ; WX 722 ; N Omacron ; B 27 -18 691 830 ;
-C -1 ; WX 667 ; N Racute ; B -29 0 623 904 ;
-C -1 ; WX 556 ; N Sacute ; B 2 -18 531 904 ;
-C -1 ; WX 608 ; N dcaron ; B -21 -13 675 708 ;
-C -1 ; WX 722 ; N Umacron ; B 67 -18 744 830 ;
-C -1 ; WX 556 ; N uring ; B 15 -9 492 729 ;
-C -1 ; WX 300 ; N threesuperior ; B 17 265 321 683 ;
-C -1 ; WX 722 ; N Ograve ; B 27 -18 691 904 ;
-C -1 ; WX 667 ; N Agrave ; B -67 0 593 904 ;
-C -1 ; WX 667 ; N Abreve ; B -67 0 593 885 ;
-C -1 ; WX 570 ; N multiply ; B 48 16 522 490 ;
-C -1 ; WX 556 ; N uacute ; B 15 -9 492 697 ;
-C -1 ; WX 611 ; N Tcaron ; B 50 0 650 897 ;
-C -1 ; WX 494 ; N partialdiff ; B 11 -21 494 750 ;
-C -1 ; WX 444 ; N ydieresis ; B -94 -205 443 655 ;
-C -1 ; WX 722 ; N Nacute ; B -27 -15 748 904 ;
-C -1 ; WX 278 ; N icircumflex ; B -3 -9 324 690 ;
-C -1 ; WX 667 ; N Ecircumflex ; B -27 0 653 897 ;
-C -1 ; WX 500 ; N adieresis ; B -21 -14 476 655 ;
-C -1 ; WX 444 ; N edieresis ; B 5 -13 448 655 ;
-C -1 ; WX 444 ; N cacute ; B -5 -13 435 697 ;
-C -1 ; WX 556 ; N nacute ; B -6 -9 493 697 ;
-C -1 ; WX 556 ; N umacron ; B 15 -9 492 623 ;
-C -1 ; WX 722 ; N Ncaron ; B -27 -15 748 897 ;
-C -1 ; WX 389 ; N Iacute ; B -32 0 432 904 ;
-C -1 ; WX 570 ; N plusminus ; B 33 0 537 506 ;
-C -1 ; WX 220 ; N brokenbar ; B 66 -143 154 707 ;
-C -1 ; WX 747 ; N registered ; B 30 -18 718 685 ;
-C -1 ; WX 722 ; N Gbreve ; B 21 -18 706 885 ;
-C -1 ; WX 389 ; N Idotaccent ; B -32 0 406 862 ;
-C -1 ; WX 600 ; N summation ; B 14 -10 585 706 ;
-C -1 ; WX 667 ; N Egrave ; B -27 0 653 904 ;
-C -1 ; WX 389 ; N racute ; B -21 0 407 697 ;
-C -1 ; WX 500 ; N omacron ; B -3 -13 462 623 ;
-C -1 ; WX 611 ; N Zacute ; B -11 0 590 904 ;
-C -1 ; WX 611 ; N Zcaron ; B -11 0 590 897 ;
-C -1 ; WX 549 ; N greaterequal ; B 26 0 523 704 ;
-C -1 ; WX 722 ; N Eth ; B -31 0 700 669 ;
-C -1 ; WX 667 ; N Ccedilla ; B 32 -218 677 685 ;
-C -1 ; WX 278 ; N lcommaaccent ; B -42 -218 290 699 ;
-C -1 ; WX 366 ; N tcaron ; B -11 -9 434 754 ;
-C -1 ; WX 444 ; N eogonek ; B 5 -183 398 462 ;
-C -1 ; WX 722 ; N Uogonek ; B 67 -183 744 669 ;
-C -1 ; WX 667 ; N Aacute ; B -67 0 593 904 ;
-C -1 ; WX 667 ; N Adieresis ; B -67 0 593 862 ;
-C -1 ; WX 444 ; N egrave ; B 5 -13 398 697 ;
-C -1 ; WX 389 ; N zacute ; B -43 -78 407 697 ;
-C -1 ; WX 278 ; N iogonek ; B -20 -183 263 684 ;
-C -1 ; WX 722 ; N Oacute ; B 27 -18 691 904 ;
-C -1 ; WX 500 ; N oacute ; B -3 -13 463 697 ;
-C -1 ; WX 500 ; N amacron ; B -21 -14 467 623 ;
-C -1 ; WX 389 ; N sacute ; B -19 -13 407 697 ;
-C -1 ; WX 278 ; N idieresis ; B 2 -9 364 655 ;
-C -1 ; WX 722 ; N Ocircumflex ; B 27 -18 691 897 ;
-C -1 ; WX 722 ; N Ugrave ; B 67 -18 744 904 ;
-C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ;
-C -1 ; WX 500 ; N thorn ; B -120 -205 446 699 ;
-C -1 ; WX 300 ; N twosuperior ; B 2 274 313 683 ;
-C -1 ; WX 722 ; N Odieresis ; B 27 -18 691 862 ;
-C -1 ; WX 576 ; N mu ; B -60 -207 516 449 ;
-C -1 ; WX 278 ; N igrave ; B 2 -9 259 697 ;
-C -1 ; WX 500 ; N ohungarumlaut ; B -3 -13 582 697 ;
-C -1 ; WX 667 ; N Eogonek ; B -27 -183 653 669 ;
-C -1 ; WX 500 ; N dcroat ; B -21 -13 552 699 ;
-C -1 ; WX 750 ; N threequarters ; B 7 -14 726 683 ;
-C -1 ; WX 556 ; N Scedilla ; B 2 -218 526 685 ;
-C -1 ; WX 382 ; N lcaron ; B 2 -9 448 708 ;
-C -1 ; WX 667 ; N Kcommaaccent ; B -21 -218 702 669 ;
-C -1 ; WX 611 ; N Lacute ; B -22 0 590 904 ;
-C -1 ; WX 1000 ; N trademark ; B 32 263 968 669 ;
-C -1 ; WX 444 ; N edotaccent ; B 5 -13 398 655 ;
-C -1 ; WX 389 ; N Igrave ; B -32 0 406 904 ;
-C -1 ; WX 389 ; N Imacron ; B -32 0 461 830 ;
-C -1 ; WX 611 ; N Lcaron ; B -22 0 671 718 ;
-C -1 ; WX 750 ; N onehalf ; B -9 -14 723 683 ;
-C -1 ; WX 549 ; N lessequal ; B 29 0 526 704 ;
-C -1 ; WX 500 ; N ocircumflex ; B -3 -13 451 690 ;
-C -1 ; WX 556 ; N ntilde ; B -6 -9 504 655 ;
-C -1 ; WX 722 ; N Uhungarumlaut ; B 67 -18 744 904 ;
-C -1 ; WX 667 ; N Eacute ; B -27 0 653 904 ;
-C -1 ; WX 444 ; N emacron ; B 5 -13 439 623 ;
-C -1 ; WX 500 ; N gbreve ; B -52 -203 478 678 ;
-C -1 ; WX 750 ; N onequarter ; B 7 -14 721 683 ;
-C -1 ; WX 556 ; N Scaron ; B 2 -18 553 897 ;
-C -1 ; WX 556 ; N Scommaaccent ; B 2 -218 526 685 ;
-C -1 ; WX 722 ; N Ohungarumlaut ; B 27 -18 723 904 ;
-C -1 ; WX 400 ; N degree ; B 83 397 369 683 ;
-C -1 ; WX 500 ; N ograve ; B -3 -13 441 697 ;
-C -1 ; WX 667 ; N Ccaron ; B 32 -18 677 897 ;
-C -1 ; WX 556 ; N ugrave ; B 15 -9 492 697 ;
-C -1 ; WX 549 ; N radical ; B 10 -46 512 850 ;
-C -1 ; WX 722 ; N Dcaron ; B -46 0 685 897 ;
-C -1 ; WX 389 ; N rcommaaccent ; B -67 -218 389 462 ;
-C -1 ; WX 722 ; N Ntilde ; B -27 -15 748 862 ;
-C -1 ; WX 500 ; N otilde ; B -3 -13 491 655 ;
-C -1 ; WX 667 ; N Rcommaaccent ; B -29 -218 623 669 ;
-C -1 ; WX 611 ; N Lcommaaccent ; B -22 -218 590 669 ;
-C -1 ; WX 667 ; N Atilde ; B -67 0 593 862 ;
-C -1 ; WX 667 ; N Aogonek ; B -67 -183 604 683 ;
-C -1 ; WX 667 ; N Aring ; B -67 0 593 921 ;
-C -1 ; WX 722 ; N Otilde ; B 27 -18 691 862 ;
-C -1 ; WX 389 ; N zdotaccent ; B -43 -78 368 655 ;
-C -1 ; WX 667 ; N Ecaron ; B -27 0 653 897 ;
-C -1 ; WX 389 ; N Iogonek ; B -32 -183 406 669 ;
-C -1 ; WX 500 ; N kcommaaccent ; B -23 -218 483 699 ;
-C -1 ; WX 606 ; N minus ; B 51 209 555 297 ;
-C -1 ; WX 389 ; N Icircumflex ; B -32 0 450 897 ;
-C -1 ; WX 556 ; N ncaron ; B -6 -9 523 690 ;
-C -1 ; WX 278 ; N tcommaaccent ; B -62 -218 281 594 ;
-C -1 ; WX 606 ; N logicalnot ; B 51 108 555 399 ;
-C -1 ; WX 500 ; N odieresis ; B -3 -13 471 655 ;
-C -1 ; WX 556 ; N udieresis ; B 15 -9 499 655 ;
-C -1 ; WX 549 ; N notequal ; B 15 -49 540 570 ;
-C -1 ; WX 500 ; N gcommaaccent ; B -52 -203 478 767 ;
-C -1 ; WX 500 ; N eth ; B -3 -13 454 699 ;
-C -1 ; WX 389 ; N zcaron ; B -43 -78 424 690 ;
-C -1 ; WX 556 ; N ncommaaccent ; B -6 -218 493 462 ;
-C -1 ; WX 300 ; N onesuperior ; B 30 274 301 683 ;
-C -1 ; WX 278 ; N imacron ; B 2 -9 294 623 ;
-C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 2038
-KPX A C -65
-KPX A Cacute -65
-KPX A Ccaron -65
-KPX A Ccedilla -65
-KPX A G -60
-KPX A Gbreve -60
-KPX A Gcommaaccent -60
-KPX A O -50
-KPX A Oacute -50
-KPX A Ocircumflex -50
-KPX A Odieresis -50
-KPX A Ograve -50
-KPX A Ohungarumlaut -50
-KPX A Omacron -50
-KPX A Oslash -50
-KPX A Otilde -50
-KPX A Q -55
-KPX A T -55
-KPX A Tcaron -55
-KPX A Tcommaaccent -55
-KPX A U -50
-KPX A Uacute -50
-KPX A Ucircumflex -50
-KPX A Udieresis -50
-KPX A Ugrave -50
-KPX A Uhungarumlaut -50
-KPX A Umacron -50
-KPX A Uogonek -50
-KPX A Uring -50
-KPX A V -95
-KPX A W -100
-KPX A Y -70
-KPX A Yacute -70
-KPX A Ydieresis -70
-KPX A quoteright -74
-KPX A u -30
-KPX A uacute -30
-KPX A ucircumflex -30
-KPX A udieresis -30
-KPX A ugrave -30
-KPX A uhungarumlaut -30
-KPX A umacron -30
-KPX A uogonek -30
-KPX A uring -30
-KPX A v -74
-KPX A w -74
-KPX A y -74
-KPX A yacute -74
-KPX A ydieresis -74
-KPX Aacute C -65
-KPX Aacute Cacute -65
-KPX Aacute Ccaron -65
-KPX Aacute Ccedilla -65
-KPX Aacute G -60
-KPX Aacute Gbreve -60
-KPX Aacute Gcommaaccent -60
-KPX Aacute O -50
-KPX Aacute Oacute -50
-KPX Aacute Ocircumflex -50
-KPX Aacute Odieresis -50
-KPX Aacute Ograve -50
-KPX Aacute Ohungarumlaut -50
-KPX Aacute Omacron -50
-KPX Aacute Oslash -50
-KPX Aacute Otilde -50
-KPX Aacute Q -55
-KPX Aacute T -55
-KPX Aacute Tcaron -55
-KPX Aacute Tcommaaccent -55
-KPX Aacute U -50
-KPX Aacute Uacute -50
-KPX Aacute Ucircumflex -50
-KPX Aacute Udieresis -50
-KPX Aacute Ugrave -50
-KPX Aacute Uhungarumlaut -50
-KPX Aacute Umacron -50
-KPX Aacute Uogonek -50
-KPX Aacute Uring -50
-KPX Aacute V -95
-KPX Aacute W -100
-KPX Aacute Y -70
-KPX Aacute Yacute -70
-KPX Aacute Ydieresis -70
-KPX Aacute quoteright -74
-KPX Aacute u -30
-KPX Aacute uacute -30
-KPX Aacute ucircumflex -30
-KPX Aacute udieresis -30
-KPX Aacute ugrave -30
-KPX Aacute uhungarumlaut -30
-KPX Aacute umacron -30
-KPX Aacute uogonek -30
-KPX Aacute uring -30
-KPX Aacute v -74
-KPX Aacute w -74
-KPX Aacute y -74
-KPX Aacute yacute -74
-KPX Aacute ydieresis -74
-KPX Abreve C -65
-KPX Abreve Cacute -65
-KPX Abreve Ccaron -65
-KPX Abreve Ccedilla -65
-KPX Abreve G -60
-KPX Abreve Gbreve -60
-KPX Abreve Gcommaaccent -60
-KPX Abreve O -50
-KPX Abreve Oacute -50
-KPX Abreve Ocircumflex -50
-KPX Abreve Odieresis -50
-KPX Abreve Ograve -50
-KPX Abreve Ohungarumlaut -50
-KPX Abreve Omacron -50
-KPX Abreve Oslash -50
-KPX Abreve Otilde -50
-KPX Abreve Q -55
-KPX Abreve T -55
-KPX Abreve Tcaron -55
-KPX Abreve Tcommaaccent -55
-KPX Abreve U -50
-KPX Abreve Uacute -50
-KPX Abreve Ucircumflex -50
-KPX Abreve Udieresis -50
-KPX Abreve Ugrave -50
-KPX Abreve Uhungarumlaut -50
-KPX Abreve Umacron -50
-KPX Abreve Uogonek -50
-KPX Abreve Uring -50
-KPX Abreve V -95
-KPX Abreve W -100
-KPX Abreve Y -70
-KPX Abreve Yacute -70
-KPX Abreve Ydieresis -70
-KPX Abreve quoteright -74
-KPX Abreve u -30
-KPX Abreve uacute -30
-KPX Abreve ucircumflex -30
-KPX Abreve udieresis -30
-KPX Abreve ugrave -30
-KPX Abreve uhungarumlaut -30
-KPX Abreve umacron -30
-KPX Abreve uogonek -30
-KPX Abreve uring -30
-KPX Abreve v -74
-KPX Abreve w -74
-KPX Abreve y -74
-KPX Abreve yacute -74
-KPX Abreve ydieresis -74
-KPX Acircumflex C -65
-KPX Acircumflex Cacute -65
-KPX Acircumflex Ccaron -65
-KPX Acircumflex Ccedilla -65
-KPX Acircumflex G -60
-KPX Acircumflex Gbreve -60
-KPX Acircumflex Gcommaaccent -60
-KPX Acircumflex O -50
-KPX Acircumflex Oacute -50
-KPX Acircumflex Ocircumflex -50
-KPX Acircumflex Odieresis -50
-KPX Acircumflex Ograve -50
-KPX Acircumflex Ohungarumlaut -50
-KPX Acircumflex Omacron -50
-KPX Acircumflex Oslash -50
-KPX Acircumflex Otilde -50
-KPX Acircumflex Q -55
-KPX Acircumflex T -55
-KPX Acircumflex Tcaron -55
-KPX Acircumflex Tcommaaccent -55
-KPX Acircumflex U -50
-KPX Acircumflex Uacute -50
-KPX Acircumflex Ucircumflex -50
-KPX Acircumflex Udieresis -50
-KPX Acircumflex Ugrave -50
-KPX Acircumflex Uhungarumlaut -50
-KPX Acircumflex Umacron -50
-KPX Acircumflex Uogonek -50
-KPX Acircumflex Uring -50
-KPX Acircumflex V -95
-KPX Acircumflex W -100
-KPX Acircumflex Y -70
-KPX Acircumflex Yacute -70
-KPX Acircumflex Ydieresis -70
-KPX Acircumflex quoteright -74
-KPX Acircumflex u -30
-KPX Acircumflex uacute -30
-KPX Acircumflex ucircumflex -30
-KPX Acircumflex udieresis -30
-KPX Acircumflex ugrave -30
-KPX Acircumflex uhungarumlaut -30
-KPX Acircumflex umacron -30
-KPX Acircumflex uogonek -30
-KPX Acircumflex uring -30
-KPX Acircumflex v -74
-KPX Acircumflex w -74
-KPX Acircumflex y -74
-KPX Acircumflex yacute -74
-KPX Acircumflex ydieresis -74
-KPX Adieresis C -65
-KPX Adieresis Cacute -65
-KPX Adieresis Ccaron -65
-KPX Adieresis Ccedilla -65
-KPX Adieresis G -60
-KPX Adieresis Gbreve -60
-KPX Adieresis Gcommaaccent -60
-KPX Adieresis O -50
-KPX Adieresis Oacute -50
-KPX Adieresis Ocircumflex -50
-KPX Adieresis Odieresis -50
-KPX Adieresis Ograve -50
-KPX Adieresis Ohungarumlaut -50
-KPX Adieresis Omacron -50
-KPX Adieresis Oslash -50
-KPX Adieresis Otilde -50
-KPX Adieresis Q -55
-KPX Adieresis T -55
-KPX Adieresis Tcaron -55
-KPX Adieresis Tcommaaccent -55
-KPX Adieresis U -50
-KPX Adieresis Uacute -50
-KPX Adieresis Ucircumflex -50
-KPX Adieresis Udieresis -50
-KPX Adieresis Ugrave -50
-KPX Adieresis Uhungarumlaut -50
-KPX Adieresis Umacron -50
-KPX Adieresis Uogonek -50
-KPX Adieresis Uring -50
-KPX Adieresis V -95
-KPX Adieresis W -100
-KPX Adieresis Y -70
-KPX Adieresis Yacute -70
-KPX Adieresis Ydieresis -70
-KPX Adieresis quoteright -74
-KPX Adieresis u -30
-KPX Adieresis uacute -30
-KPX Adieresis ucircumflex -30
-KPX Adieresis udieresis -30
-KPX Adieresis ugrave -30
-KPX Adieresis uhungarumlaut -30
-KPX Adieresis umacron -30
-KPX Adieresis uogonek -30
-KPX Adieresis uring -30
-KPX Adieresis v -74
-KPX Adieresis w -74
-KPX Adieresis y -74
-KPX Adieresis yacute -74
-KPX Adieresis ydieresis -74
-KPX Agrave C -65
-KPX Agrave Cacute -65
-KPX Agrave Ccaron -65
-KPX Agrave Ccedilla -65
-KPX Agrave G -60
-KPX Agrave Gbreve -60
-KPX Agrave Gcommaaccent -60
-KPX Agrave O -50
-KPX Agrave Oacute -50
-KPX Agrave Ocircumflex -50
-KPX Agrave Odieresis -50
-KPX Agrave Ograve -50
-KPX Agrave Ohungarumlaut -50
-KPX Agrave Omacron -50
-KPX Agrave Oslash -50
-KPX Agrave Otilde -50
-KPX Agrave Q -55
-KPX Agrave T -55
-KPX Agrave Tcaron -55
-KPX Agrave Tcommaaccent -55
-KPX Agrave U -50
-KPX Agrave Uacute -50
-KPX Agrave Ucircumflex -50
-KPX Agrave Udieresis -50
-KPX Agrave Ugrave -50
-KPX Agrave Uhungarumlaut -50
-KPX Agrave Umacron -50
-KPX Agrave Uogonek -50
-KPX Agrave Uring -50
-KPX Agrave V -95
-KPX Agrave W -100
-KPX Agrave Y -70
-KPX Agrave Yacute -70
-KPX Agrave Ydieresis -70
-KPX Agrave quoteright -74
-KPX Agrave u -30
-KPX Agrave uacute -30
-KPX Agrave ucircumflex -30
-KPX Agrave udieresis -30
-KPX Agrave ugrave -30
-KPX Agrave uhungarumlaut -30
-KPX Agrave umacron -30
-KPX Agrave uogonek -30
-KPX Agrave uring -30
-KPX Agrave v -74
-KPX Agrave w -74
-KPX Agrave y -74
-KPX Agrave yacute -74
-KPX Agrave ydieresis -74
-KPX Amacron C -65
-KPX Amacron Cacute -65
-KPX Amacron Ccaron -65
-KPX Amacron Ccedilla -65
-KPX Amacron G -60
-KPX Amacron Gbreve -60
-KPX Amacron Gcommaaccent -60
-KPX Amacron O -50
-KPX Amacron Oacute -50
-KPX Amacron Ocircumflex -50
-KPX Amacron Odieresis -50
-KPX Amacron Ograve -50
-KPX Amacron Ohungarumlaut -50
-KPX Amacron Omacron -50
-KPX Amacron Oslash -50
-KPX Amacron Otilde -50
-KPX Amacron Q -55
-KPX Amacron T -55
-KPX Amacron Tcaron -55
-KPX Amacron Tcommaaccent -55
-KPX Amacron U -50
-KPX Amacron Uacute -50
-KPX Amacron Ucircumflex -50
-KPX Amacron Udieresis -50
-KPX Amacron Ugrave -50
-KPX Amacron Uhungarumlaut -50
-KPX Amacron Umacron -50
-KPX Amacron Uogonek -50
-KPX Amacron Uring -50
-KPX Amacron V -95
-KPX Amacron W -100
-KPX Amacron Y -70
-KPX Amacron Yacute -70
-KPX Amacron Ydieresis -70
-KPX Amacron quoteright -74
-KPX Amacron u -30
-KPX Amacron uacute -30
-KPX Amacron ucircumflex -30
-KPX Amacron udieresis -30
-KPX Amacron ugrave -30
-KPX Amacron uhungarumlaut -30
-KPX Amacron umacron -30
-KPX Amacron uogonek -30
-KPX Amacron uring -30
-KPX Amacron v -74
-KPX Amacron w -74
-KPX Amacron y -74
-KPX Amacron yacute -74
-KPX Amacron ydieresis -74
-KPX Aogonek C -65
-KPX Aogonek Cacute -65
-KPX Aogonek Ccaron -65
-KPX Aogonek Ccedilla -65
-KPX Aogonek G -60
-KPX Aogonek Gbreve -60
-KPX Aogonek Gcommaaccent -60
-KPX Aogonek O -50
-KPX Aogonek Oacute -50
-KPX Aogonek Ocircumflex -50
-KPX Aogonek Odieresis -50
-KPX Aogonek Ograve -50
-KPX Aogonek Ohungarumlaut -50
-KPX Aogonek Omacron -50
-KPX Aogonek Oslash -50
-KPX Aogonek Otilde -50
-KPX Aogonek Q -55
-KPX Aogonek T -55
-KPX Aogonek Tcaron -55
-KPX Aogonek Tcommaaccent -55
-KPX Aogonek U -50
-KPX Aogonek Uacute -50
-KPX Aogonek Ucircumflex -50
-KPX Aogonek Udieresis -50
-KPX Aogonek Ugrave -50
-KPX Aogonek Uhungarumlaut -50
-KPX Aogonek Umacron -50
-KPX Aogonek Uogonek -50
-KPX Aogonek Uring -50
-KPX Aogonek V -95
-KPX Aogonek W -100
-KPX Aogonek Y -70
-KPX Aogonek Yacute -70
-KPX Aogonek Ydieresis -70
-KPX Aogonek quoteright -74
-KPX Aogonek u -30
-KPX Aogonek uacute -30
-KPX Aogonek ucircumflex -30
-KPX Aogonek udieresis -30
-KPX Aogonek ugrave -30
-KPX Aogonek uhungarumlaut -30
-KPX Aogonek umacron -30
-KPX Aogonek uogonek -30
-KPX Aogonek uring -30
-KPX Aogonek v -74
-KPX Aogonek w -74
-KPX Aogonek y -34
-KPX Aogonek yacute -34
-KPX Aogonek ydieresis -34
-KPX Aring C -65
-KPX Aring Cacute -65
-KPX Aring Ccaron -65
-KPX Aring Ccedilla -65
-KPX Aring G -60
-KPX Aring Gbreve -60
-KPX Aring Gcommaaccent -60
-KPX Aring O -50
-KPX Aring Oacute -50
-KPX Aring Ocircumflex -50
-KPX Aring Odieresis -50
-KPX Aring Ograve -50
-KPX Aring Ohungarumlaut -50
-KPX Aring Omacron -50
-KPX Aring Oslash -50
-KPX Aring Otilde -50
-KPX Aring Q -55
-KPX Aring T -55
-KPX Aring Tcaron -55
-KPX Aring Tcommaaccent -55
-KPX Aring U -50
-KPX Aring Uacute -50
-KPX Aring Ucircumflex -50
-KPX Aring Udieresis -50
-KPX Aring Ugrave -50
-KPX Aring Uhungarumlaut -50
-KPX Aring Umacron -50
-KPX Aring Uogonek -50
-KPX Aring Uring -50
-KPX Aring V -95
-KPX Aring W -100
-KPX Aring Y -70
-KPX Aring Yacute -70
-KPX Aring Ydieresis -70
-KPX Aring quoteright -74
-KPX Aring u -30
-KPX Aring uacute -30
-KPX Aring ucircumflex -30
-KPX Aring udieresis -30
-KPX Aring ugrave -30
-KPX Aring uhungarumlaut -30
-KPX Aring umacron -30
-KPX Aring uogonek -30
-KPX Aring uring -30
-KPX Aring v -74
-KPX Aring w -74
-KPX Aring y -74
-KPX Aring yacute -74
-KPX Aring ydieresis -74
-KPX Atilde C -65
-KPX Atilde Cacute -65
-KPX Atilde Ccaron -65
-KPX Atilde Ccedilla -65
-KPX Atilde G -60
-KPX Atilde Gbreve -60
-KPX Atilde Gcommaaccent -60
-KPX Atilde O -50
-KPX Atilde Oacute -50
-KPX Atilde Ocircumflex -50
-KPX Atilde Odieresis -50
-KPX Atilde Ograve -50
-KPX Atilde Ohungarumlaut -50
-KPX Atilde Omacron -50
-KPX Atilde Oslash -50
-KPX Atilde Otilde -50
-KPX Atilde Q -55
-KPX Atilde T -55
-KPX Atilde Tcaron -55
-KPX Atilde Tcommaaccent -55
-KPX Atilde U -50
-KPX Atilde Uacute -50
-KPX Atilde Ucircumflex -50
-KPX Atilde Udieresis -50
-KPX Atilde Ugrave -50
-KPX Atilde Uhungarumlaut -50
-KPX Atilde Umacron -50
-KPX Atilde Uogonek -50
-KPX Atilde Uring -50
-KPX Atilde V -95
-KPX Atilde W -100
-KPX Atilde Y -70
-KPX Atilde Yacute -70
-KPX Atilde Ydieresis -70
-KPX Atilde quoteright -74
-KPX Atilde u -30
-KPX Atilde uacute -30
-KPX Atilde ucircumflex -30
-KPX Atilde udieresis -30
-KPX Atilde ugrave -30
-KPX Atilde uhungarumlaut -30
-KPX Atilde umacron -30
-KPX Atilde uogonek -30
-KPX Atilde uring -30
-KPX Atilde v -74
-KPX Atilde w -74
-KPX Atilde y -74
-KPX Atilde yacute -74
-KPX Atilde ydieresis -74
-KPX B A -25
-KPX B Aacute -25
-KPX B Abreve -25
-KPX B Acircumflex -25
-KPX B Adieresis -25
-KPX B Agrave -25
-KPX B Amacron -25
-KPX B Aogonek -25
-KPX B Aring -25
-KPX B Atilde -25
-KPX B U -10
-KPX B Uacute -10
-KPX B Ucircumflex -10
-KPX B Udieresis -10
-KPX B Ugrave -10
-KPX B Uhungarumlaut -10
-KPX B Umacron -10
-KPX B Uogonek -10
-KPX B Uring -10
-KPX D A -25
-KPX D Aacute -25
-KPX D Abreve -25
-KPX D Acircumflex -25
-KPX D Adieresis -25
-KPX D Agrave -25
-KPX D Amacron -25
-KPX D Aogonek -25
-KPX D Aring -25
-KPX D Atilde -25
-KPX D V -50
-KPX D W -40
-KPX D Y -50
-KPX D Yacute -50
-KPX D Ydieresis -50
-KPX Dcaron A -25
-KPX Dcaron Aacute -25
-KPX Dcaron Abreve -25
-KPX Dcaron Acircumflex -25
-KPX Dcaron Adieresis -25
-KPX Dcaron Agrave -25
-KPX Dcaron Amacron -25
-KPX Dcaron Aogonek -25
-KPX Dcaron Aring -25
-KPX Dcaron Atilde -25
-KPX Dcaron V -50
-KPX Dcaron W -40
-KPX Dcaron Y -50
-KPX Dcaron Yacute -50
-KPX Dcaron Ydieresis -50
-KPX Dcroat A -25
-KPX Dcroat Aacute -25
-KPX Dcroat Abreve -25
-KPX Dcroat Acircumflex -25
-KPX Dcroat Adieresis -25
-KPX Dcroat Agrave -25
-KPX Dcroat Amacron -25
-KPX Dcroat Aogonek -25
-KPX Dcroat Aring -25
-KPX Dcroat Atilde -25
-KPX Dcroat V -50
-KPX Dcroat W -40
-KPX Dcroat Y -50
-KPX Dcroat Yacute -50
-KPX Dcroat Ydieresis -50
-KPX F A -100
-KPX F Aacute -100
-KPX F Abreve -100
-KPX F Acircumflex -100
-KPX F Adieresis -100
-KPX F Agrave -100
-KPX F Amacron -100
-KPX F Aogonek -100
-KPX F Aring -100
-KPX F Atilde -100
-KPX F a -95
-KPX F aacute -95
-KPX F abreve -95
-KPX F acircumflex -95
-KPX F adieresis -95
-KPX F agrave -95
-KPX F amacron -95
-KPX F aogonek -95
-KPX F aring -95
-KPX F atilde -95
-KPX F comma -129
-KPX F e -100
-KPX F eacute -100
-KPX F ecaron -100
-KPX F ecircumflex -100
-KPX F edieresis -100
-KPX F edotaccent -100
-KPX F egrave -100
-KPX F emacron -100
-KPX F eogonek -100
-KPX F i -40
-KPX F iacute -40
-KPX F icircumflex -40
-KPX F idieresis -40
-KPX F igrave -40
-KPX F imacron -40
-KPX F iogonek -40
-KPX F o -70
-KPX F oacute -70
-KPX F ocircumflex -70
-KPX F odieresis -70
-KPX F ograve -70
-KPX F ohungarumlaut -70
-KPX F omacron -70
-KPX F oslash -70
-KPX F otilde -70
-KPX F period -129
-KPX F r -50
-KPX F racute -50
-KPX F rcaron -50
-KPX F rcommaaccent -50
-KPX J A -25
-KPX J Aacute -25
-KPX J Abreve -25
-KPX J Acircumflex -25
-KPX J Adieresis -25
-KPX J Agrave -25
-KPX J Amacron -25
-KPX J Aogonek -25
-KPX J Aring -25
-KPX J Atilde -25
-KPX J a -40
-KPX J aacute -40
-KPX J abreve -40
-KPX J acircumflex -40
-KPX J adieresis -40
-KPX J agrave -40
-KPX J amacron -40
-KPX J aogonek -40
-KPX J aring -40
-KPX J atilde -40
-KPX J comma -10
-KPX J e -40
-KPX J eacute -40
-KPX J ecaron -40
-KPX J ecircumflex -40
-KPX J edieresis -40
-KPX J edotaccent -40
-KPX J egrave -40
-KPX J emacron -40
-KPX J eogonek -40
-KPX J o -40
-KPX J oacute -40
-KPX J ocircumflex -40
-KPX J odieresis -40
-KPX J ograve -40
-KPX J ohungarumlaut -40
-KPX J omacron -40
-KPX J oslash -40
-KPX J otilde -40
-KPX J period -10
-KPX J u -40
-KPX J uacute -40
-KPX J ucircumflex -40
-KPX J udieresis -40
-KPX J ugrave -40
-KPX J uhungarumlaut -40
-KPX J umacron -40
-KPX J uogonek -40
-KPX J uring -40
-KPX K O -30
-KPX K Oacute -30
-KPX K Ocircumflex -30
-KPX K Odieresis -30
-KPX K Ograve -30
-KPX K Ohungarumlaut -30
-KPX K Omacron -30
-KPX K Oslash -30
-KPX K Otilde -30
-KPX K e -25
-KPX K eacute -25
-KPX K ecaron -25
-KPX K ecircumflex -25
-KPX K edieresis -25
-KPX K edotaccent -25
-KPX K egrave -25
-KPX K emacron -25
-KPX K eogonek -25
-KPX K o -25
-KPX K oacute -25
-KPX K ocircumflex -25
-KPX K odieresis -25
-KPX K ograve -25
-KPX K ohungarumlaut -25
-KPX K omacron -25
-KPX K oslash -25
-KPX K otilde -25
-KPX K u -20
-KPX K uacute -20
-KPX K ucircumflex -20
-KPX K udieresis -20
-KPX K ugrave -20
-KPX K uhungarumlaut -20
-KPX K umacron -20
-KPX K uogonek -20
-KPX K uring -20
-KPX K y -20
-KPX K yacute -20
-KPX K ydieresis -20
-KPX Kcommaaccent O -30
-KPX Kcommaaccent Oacute -30
-KPX Kcommaaccent Ocircumflex -30
-KPX Kcommaaccent Odieresis -30
-KPX Kcommaaccent Ograve -30
-KPX Kcommaaccent Ohungarumlaut -30
-KPX Kcommaaccent Omacron -30
-KPX Kcommaaccent Oslash -30
-KPX Kcommaaccent Otilde -30
-KPX Kcommaaccent e -25
-KPX Kcommaaccent eacute -25
-KPX Kcommaaccent ecaron -25
-KPX Kcommaaccent ecircumflex -25
-KPX Kcommaaccent edieresis -25
-KPX Kcommaaccent edotaccent -25
-KPX Kcommaaccent egrave -25
-KPX Kcommaaccent emacron -25
-KPX Kcommaaccent eogonek -25
-KPX Kcommaaccent o -25
-KPX Kcommaaccent oacute -25
-KPX Kcommaaccent ocircumflex -25
-KPX Kcommaaccent odieresis -25
-KPX Kcommaaccent ograve -25
-KPX Kcommaaccent ohungarumlaut -25
-KPX Kcommaaccent omacron -25
-KPX Kcommaaccent oslash -25
-KPX Kcommaaccent otilde -25
-KPX Kcommaaccent u -20
-KPX Kcommaaccent uacute -20
-KPX Kcommaaccent ucircumflex -20
-KPX Kcommaaccent udieresis -20
-KPX Kcommaaccent ugrave -20
-KPX Kcommaaccent uhungarumlaut -20
-KPX Kcommaaccent umacron -20
-KPX Kcommaaccent uogonek -20
-KPX Kcommaaccent uring -20
-KPX Kcommaaccent y -20
-KPX Kcommaaccent yacute -20
-KPX Kcommaaccent ydieresis -20
-KPX L T -18
-KPX L Tcaron -18
-KPX L Tcommaaccent -18
-KPX L V -37
-KPX L W -37
-KPX L Y -37
-KPX L Yacute -37
-KPX L Ydieresis -37
-KPX L quoteright -55
-KPX L y -37
-KPX L yacute -37
-KPX L ydieresis -37
-KPX Lacute T -18
-KPX Lacute Tcaron -18
-KPX Lacute Tcommaaccent -18
-KPX Lacute V -37
-KPX Lacute W -37
-KPX Lacute Y -37
-KPX Lacute Yacute -37
-KPX Lacute Ydieresis -37
-KPX Lacute quoteright -55
-KPX Lacute y -37
-KPX Lacute yacute -37
-KPX Lacute ydieresis -37
-KPX Lcommaaccent T -18
-KPX Lcommaaccent Tcaron -18
-KPX Lcommaaccent Tcommaaccent -18
-KPX Lcommaaccent V -37
-KPX Lcommaaccent W -37
-KPX Lcommaaccent Y -37
-KPX Lcommaaccent Yacute -37
-KPX Lcommaaccent Ydieresis -37
-KPX Lcommaaccent quoteright -55
-KPX Lcommaaccent y -37
-KPX Lcommaaccent yacute -37
-KPX Lcommaaccent ydieresis -37
-KPX Lslash T -18
-KPX Lslash Tcaron -18
-KPX Lslash Tcommaaccent -18
-KPX Lslash V -37
-KPX Lslash W -37
-KPX Lslash Y -37
-KPX Lslash Yacute -37
-KPX Lslash Ydieresis -37
-KPX Lslash quoteright -55
-KPX Lslash y -37
-KPX Lslash yacute -37
-KPX Lslash ydieresis -37
-KPX N A -30
-KPX N Aacute -30
-KPX N Abreve -30
-KPX N Acircumflex -30
-KPX N Adieresis -30
-KPX N Agrave -30
-KPX N Amacron -30
-KPX N Aogonek -30
-KPX N Aring -30
-KPX N Atilde -30
-KPX Nacute A -30
-KPX Nacute Aacute -30
-KPX Nacute Abreve -30
-KPX Nacute Acircumflex -30
-KPX Nacute Adieresis -30
-KPX Nacute Agrave -30
-KPX Nacute Amacron -30
-KPX Nacute Aogonek -30
-KPX Nacute Aring -30
-KPX Nacute Atilde -30
-KPX Ncaron A -30
-KPX Ncaron Aacute -30
-KPX Ncaron Abreve -30
-KPX Ncaron Acircumflex -30
-KPX Ncaron Adieresis -30
-KPX Ncaron Agrave -30
-KPX Ncaron Amacron -30
-KPX Ncaron Aogonek -30
-KPX Ncaron Aring -30
-KPX Ncaron Atilde -30
-KPX Ncommaaccent A -30
-KPX Ncommaaccent Aacute -30
-KPX Ncommaaccent Abreve -30
-KPX Ncommaaccent Acircumflex -30
-KPX Ncommaaccent Adieresis -30
-KPX Ncommaaccent Agrave -30
-KPX Ncommaaccent Amacron -30
-KPX Ncommaaccent Aogonek -30
-KPX Ncommaaccent Aring -30
-KPX Ncommaaccent Atilde -30
-KPX Ntilde A -30
-KPX Ntilde Aacute -30
-KPX Ntilde Abreve -30
-KPX Ntilde Acircumflex -30
-KPX Ntilde Adieresis -30
-KPX Ntilde Agrave -30
-KPX Ntilde Amacron -30
-KPX Ntilde Aogonek -30
-KPX Ntilde Aring -30
-KPX Ntilde Atilde -30
-KPX O A -40
-KPX O Aacute -40
-KPX O Abreve -40
-KPX O Acircumflex -40
-KPX O Adieresis -40
-KPX O Agrave -40
-KPX O Amacron -40
-KPX O Aogonek -40
-KPX O Aring -40
-KPX O Atilde -40
-KPX O T -40
-KPX O Tcaron -40
-KPX O Tcommaaccent -40
-KPX O V -50
-KPX O W -50
-KPX O X -40
-KPX O Y -50
-KPX O Yacute -50
-KPX O Ydieresis -50
-KPX Oacute A -40
-KPX Oacute Aacute -40
-KPX Oacute Abreve -40
-KPX Oacute Acircumflex -40
-KPX Oacute Adieresis -40
-KPX Oacute Agrave -40
-KPX Oacute Amacron -40
-KPX Oacute Aogonek -40
-KPX Oacute Aring -40
-KPX Oacute Atilde -40
-KPX Oacute T -40
-KPX Oacute Tcaron -40
-KPX Oacute Tcommaaccent -40
-KPX Oacute V -50
-KPX Oacute W -50
-KPX Oacute X -40
-KPX Oacute Y -50
-KPX Oacute Yacute -50
-KPX Oacute Ydieresis -50
-KPX Ocircumflex A -40
-KPX Ocircumflex Aacute -40
-KPX Ocircumflex Abreve -40
-KPX Ocircumflex Acircumflex -40
-KPX Ocircumflex Adieresis -40
-KPX Ocircumflex Agrave -40
-KPX Ocircumflex Amacron -40
-KPX Ocircumflex Aogonek -40
-KPX Ocircumflex Aring -40
-KPX Ocircumflex Atilde -40
-KPX Ocircumflex T -40
-KPX Ocircumflex Tcaron -40
-KPX Ocircumflex Tcommaaccent -40
-KPX Ocircumflex V -50
-KPX Ocircumflex W -50
-KPX Ocircumflex X -40
-KPX Ocircumflex Y -50
-KPX Ocircumflex Yacute -50
-KPX Ocircumflex Ydieresis -50
-KPX Odieresis A -40
-KPX Odieresis Aacute -40
-KPX Odieresis Abreve -40
-KPX Odieresis Acircumflex -40
-KPX Odieresis Adieresis -40
-KPX Odieresis Agrave -40
-KPX Odieresis Amacron -40
-KPX Odieresis Aogonek -40
-KPX Odieresis Aring -40
-KPX Odieresis Atilde -40
-KPX Odieresis T -40
-KPX Odieresis Tcaron -40
-KPX Odieresis Tcommaaccent -40
-KPX Odieresis V -50
-KPX Odieresis W -50
-KPX Odieresis X -40
-KPX Odieresis Y -50
-KPX Odieresis Yacute -50
-KPX Odieresis Ydieresis -50
-KPX Ograve A -40
-KPX Ograve Aacute -40
-KPX Ograve Abreve -40
-KPX Ograve Acircumflex -40
-KPX Ograve Adieresis -40
-KPX Ograve Agrave -40
-KPX Ograve Amacron -40
-KPX Ograve Aogonek -40
-KPX Ograve Aring -40
-KPX Ograve Atilde -40
-KPX Ograve T -40
-KPX Ograve Tcaron -40
-KPX Ograve Tcommaaccent -40
-KPX Ograve V -50
-KPX Ograve W -50
-KPX Ograve X -40
-KPX Ograve Y -50
-KPX Ograve Yacute -50
-KPX Ograve Ydieresis -50
-KPX Ohungarumlaut A -40
-KPX Ohungarumlaut Aacute -40
-KPX Ohungarumlaut Abreve -40
-KPX Ohungarumlaut Acircumflex -40
-KPX Ohungarumlaut Adieresis -40
-KPX Ohungarumlaut Agrave -40
-KPX Ohungarumlaut Amacron -40
-KPX Ohungarumlaut Aogonek -40
-KPX Ohungarumlaut Aring -40
-KPX Ohungarumlaut Atilde -40
-KPX Ohungarumlaut T -40
-KPX Ohungarumlaut Tcaron -40
-KPX Ohungarumlaut Tcommaaccent -40
-KPX Ohungarumlaut V -50
-KPX Ohungarumlaut W -50
-KPX Ohungarumlaut X -40
-KPX Ohungarumlaut Y -50
-KPX Ohungarumlaut Yacute -50
-KPX Ohungarumlaut Ydieresis -50
-KPX Omacron A -40
-KPX Omacron Aacute -40
-KPX Omacron Abreve -40
-KPX Omacron Acircumflex -40
-KPX Omacron Adieresis -40
-KPX Omacron Agrave -40
-KPX Omacron Amacron -40
-KPX Omacron Aogonek -40
-KPX Omacron Aring -40
-KPX Omacron Atilde -40
-KPX Omacron T -40
-KPX Omacron Tcaron -40
-KPX Omacron Tcommaaccent -40
-KPX Omacron V -50
-KPX Omacron W -50
-KPX Omacron X -40
-KPX Omacron Y -50
-KPX Omacron Yacute -50
-KPX Omacron Ydieresis -50
-KPX Oslash A -40
-KPX Oslash Aacute -40
-KPX Oslash Abreve -40
-KPX Oslash Acircumflex -40
-KPX Oslash Adieresis -40
-KPX Oslash Agrave -40
-KPX Oslash Amacron -40
-KPX Oslash Aogonek -40
-KPX Oslash Aring -40
-KPX Oslash Atilde -40
-KPX Oslash T -40
-KPX Oslash Tcaron -40
-KPX Oslash Tcommaaccent -40
-KPX Oslash V -50
-KPX Oslash W -50
-KPX Oslash X -40
-KPX Oslash Y -50
-KPX Oslash Yacute -50
-KPX Oslash Ydieresis -50
-KPX Otilde A -40
-KPX Otilde Aacute -40
-KPX Otilde Abreve -40
-KPX Otilde Acircumflex -40
-KPX Otilde Adieresis -40
-KPX Otilde Agrave -40
-KPX Otilde Amacron -40
-KPX Otilde Aogonek -40
-KPX Otilde Aring -40
-KPX Otilde Atilde -40
-KPX Otilde T -40
-KPX Otilde Tcaron -40
-KPX Otilde Tcommaaccent -40
-KPX Otilde V -50
-KPX Otilde W -50
-KPX Otilde X -40
-KPX Otilde Y -50
-KPX Otilde Yacute -50
-KPX Otilde Ydieresis -50
-KPX P A -85
-KPX P Aacute -85
-KPX P Abreve -85
-KPX P Acircumflex -85
-KPX P Adieresis -85
-KPX P Agrave -85
-KPX P Amacron -85
-KPX P Aogonek -85
-KPX P Aring -85
-KPX P Atilde -85
-KPX P a -40
-KPX P aacute -40
-KPX P abreve -40
-KPX P acircumflex -40
-KPX P adieresis -40
-KPX P agrave -40
-KPX P amacron -40
-KPX P aogonek -40
-KPX P aring -40
-KPX P atilde -40
-KPX P comma -129
-KPX P e -50
-KPX P eacute -50
-KPX P ecaron -50
-KPX P ecircumflex -50
-KPX P edieresis -50
-KPX P edotaccent -50
-KPX P egrave -50
-KPX P emacron -50
-KPX P eogonek -50
-KPX P o -55
-KPX P oacute -55
-KPX P ocircumflex -55
-KPX P odieresis -55
-KPX P ograve -55
-KPX P ohungarumlaut -55
-KPX P omacron -55
-KPX P oslash -55
-KPX P otilde -55
-KPX P period -129
-KPX Q U -10
-KPX Q Uacute -10
-KPX Q Ucircumflex -10
-KPX Q Udieresis -10
-KPX Q Ugrave -10
-KPX Q Uhungarumlaut -10
-KPX Q Umacron -10
-KPX Q Uogonek -10
-KPX Q Uring -10
-KPX R O -40
-KPX R Oacute -40
-KPX R Ocircumflex -40
-KPX R Odieresis -40
-KPX R Ograve -40
-KPX R Ohungarumlaut -40
-KPX R Omacron -40
-KPX R Oslash -40
-KPX R Otilde -40
-KPX R T -30
-KPX R Tcaron -30
-KPX R Tcommaaccent -30
-KPX R U -40
-KPX R Uacute -40
-KPX R Ucircumflex -40
-KPX R Udieresis -40
-KPX R Ugrave -40
-KPX R Uhungarumlaut -40
-KPX R Umacron -40
-KPX R Uogonek -40
-KPX R Uring -40
-KPX R V -18
-KPX R W -18
-KPX R Y -18
-KPX R Yacute -18
-KPX R Ydieresis -18
-KPX Racute O -40
-KPX Racute Oacute -40
-KPX Racute Ocircumflex -40
-KPX Racute Odieresis -40
-KPX Racute Ograve -40
-KPX Racute Ohungarumlaut -40
-KPX Racute Omacron -40
-KPX Racute Oslash -40
-KPX Racute Otilde -40
-KPX Racute T -30
-KPX Racute Tcaron -30
-KPX Racute Tcommaaccent -30
-KPX Racute U -40
-KPX Racute Uacute -40
-KPX Racute Ucircumflex -40
-KPX Racute Udieresis -40
-KPX Racute Ugrave -40
-KPX Racute Uhungarumlaut -40
-KPX Racute Umacron -40
-KPX Racute Uogonek -40
-KPX Racute Uring -40
-KPX Racute V -18
-KPX Racute W -18
-KPX Racute Y -18
-KPX Racute Yacute -18
-KPX Racute Ydieresis -18
-KPX Rcaron O -40
-KPX Rcaron Oacute -40
-KPX Rcaron Ocircumflex -40
-KPX Rcaron Odieresis -40
-KPX Rcaron Ograve -40
-KPX Rcaron Ohungarumlaut -40
-KPX Rcaron Omacron -40
-KPX Rcaron Oslash -40
-KPX Rcaron Otilde -40
-KPX Rcaron T -30
-KPX Rcaron Tcaron -30
-KPX Rcaron Tcommaaccent -30
-KPX Rcaron U -40
-KPX Rcaron Uacute -40
-KPX Rcaron Ucircumflex -40
-KPX Rcaron Udieresis -40
-KPX Rcaron Ugrave -40
-KPX Rcaron Uhungarumlaut -40
-KPX Rcaron Umacron -40
-KPX Rcaron Uogonek -40
-KPX Rcaron Uring -40
-KPX Rcaron V -18
-KPX Rcaron W -18
-KPX Rcaron Y -18
-KPX Rcaron Yacute -18
-KPX Rcaron Ydieresis -18
-KPX Rcommaaccent O -40
-KPX Rcommaaccent Oacute -40
-KPX Rcommaaccent Ocircumflex -40
-KPX Rcommaaccent Odieresis -40
-KPX Rcommaaccent Ograve -40
-KPX Rcommaaccent Ohungarumlaut -40
-KPX Rcommaaccent Omacron -40
-KPX Rcommaaccent Oslash -40
-KPX Rcommaaccent Otilde -40
-KPX Rcommaaccent T -30
-KPX Rcommaaccent Tcaron -30
-KPX Rcommaaccent Tcommaaccent -30
-KPX Rcommaaccent U -40
-KPX Rcommaaccent Uacute -40
-KPX Rcommaaccent Ucircumflex -40
-KPX Rcommaaccent Udieresis -40
-KPX Rcommaaccent Ugrave -40
-KPX Rcommaaccent Uhungarumlaut -40
-KPX Rcommaaccent Umacron -40
-KPX Rcommaaccent Uogonek -40
-KPX Rcommaaccent Uring -40
-KPX Rcommaaccent V -18
-KPX Rcommaaccent W -18
-KPX Rcommaaccent Y -18
-KPX Rcommaaccent Yacute -18
-KPX Rcommaaccent Ydieresis -18
-KPX T A -55
-KPX T Aacute -55
-KPX T Abreve -55
-KPX T Acircumflex -55
-KPX T Adieresis -55
-KPX T Agrave -55
-KPX T Amacron -55
-KPX T Aogonek -55
-KPX T Aring -55
-KPX T Atilde -55
-KPX T O -18
-KPX T Oacute -18
-KPX T Ocircumflex -18
-KPX T Odieresis -18
-KPX T Ograve -18
-KPX T Ohungarumlaut -18
-KPX T Omacron -18
-KPX T Oslash -18
-KPX T Otilde -18
-KPX T a -92
-KPX T aacute -92
-KPX T abreve -92
-KPX T acircumflex -92
-KPX T adieresis -92
-KPX T agrave -92
-KPX T amacron -92
-KPX T aogonek -92
-KPX T aring -92
-KPX T atilde -92
-KPX T colon -74
-KPX T comma -92
-KPX T e -92
-KPX T eacute -92
-KPX T ecaron -92
-KPX T ecircumflex -92
-KPX T edieresis -52
-KPX T edotaccent -92
-KPX T egrave -52
-KPX T emacron -52
-KPX T eogonek -92
-KPX T hyphen -92
-KPX T i -37
-KPX T iacute -37
-KPX T iogonek -37
-KPX T o -95
-KPX T oacute -95
-KPX T ocircumflex -95
-KPX T odieresis -95
-KPX T ograve -95
-KPX T ohungarumlaut -95
-KPX T omacron -95
-KPX T oslash -95
-KPX T otilde -95
-KPX T period -92
-KPX T r -37
-KPX T racute -37
-KPX T rcaron -37
-KPX T rcommaaccent -37
-KPX T semicolon -74
-KPX T u -37
-KPX T uacute -37
-KPX T ucircumflex -37
-KPX T udieresis -37
-KPX T ugrave -37
-KPX T uhungarumlaut -37
-KPX T umacron -37
-KPX T uogonek -37
-KPX T uring -37
-KPX T w -37
-KPX T y -37
-KPX T yacute -37
-KPX T ydieresis -37
-KPX Tcaron A -55
-KPX Tcaron Aacute -55
-KPX Tcaron Abreve -55
-KPX Tcaron Acircumflex -55
-KPX Tcaron Adieresis -55
-KPX Tcaron Agrave -55
-KPX Tcaron Amacron -55
-KPX Tcaron Aogonek -55
-KPX Tcaron Aring -55
-KPX Tcaron Atilde -55
-KPX Tcaron O -18
-KPX Tcaron Oacute -18
-KPX Tcaron Ocircumflex -18
-KPX Tcaron Odieresis -18
-KPX Tcaron Ograve -18
-KPX Tcaron Ohungarumlaut -18
-KPX Tcaron Omacron -18
-KPX Tcaron Oslash -18
-KPX Tcaron Otilde -18
-KPX Tcaron a -92
-KPX Tcaron aacute -92
-KPX Tcaron abreve -92
-KPX Tcaron acircumflex -92
-KPX Tcaron adieresis -92
-KPX Tcaron agrave -92
-KPX Tcaron amacron -92
-KPX Tcaron aogonek -92
-KPX Tcaron aring -92
-KPX Tcaron atilde -92
-KPX Tcaron colon -74
-KPX Tcaron comma -92
-KPX Tcaron e -92
-KPX Tcaron eacute -92
-KPX Tcaron ecaron -92
-KPX Tcaron ecircumflex -92
-KPX Tcaron edieresis -52
-KPX Tcaron edotaccent -92
-KPX Tcaron egrave -52
-KPX Tcaron emacron -52
-KPX Tcaron eogonek -92
-KPX Tcaron hyphen -92
-KPX Tcaron i -37
-KPX Tcaron iacute -37
-KPX Tcaron iogonek -37
-KPX Tcaron o -95
-KPX Tcaron oacute -95
-KPX Tcaron ocircumflex -95
-KPX Tcaron odieresis -95
-KPX Tcaron ograve -95
-KPX Tcaron ohungarumlaut -95
-KPX Tcaron omacron -95
-KPX Tcaron oslash -95
-KPX Tcaron otilde -95
-KPX Tcaron period -92
-KPX Tcaron r -37
-KPX Tcaron racute -37
-KPX Tcaron rcaron -37
-KPX Tcaron rcommaaccent -37
-KPX Tcaron semicolon -74
-KPX Tcaron u -37
-KPX Tcaron uacute -37
-KPX Tcaron ucircumflex -37
-KPX Tcaron udieresis -37
-KPX Tcaron ugrave -37
-KPX Tcaron uhungarumlaut -37
-KPX Tcaron umacron -37
-KPX Tcaron uogonek -37
-KPX Tcaron uring -37
-KPX Tcaron w -37
-KPX Tcaron y -37
-KPX Tcaron yacute -37
-KPX Tcaron ydieresis -37
-KPX Tcommaaccent A -55
-KPX Tcommaaccent Aacute -55
-KPX Tcommaaccent Abreve -55
-KPX Tcommaaccent Acircumflex -55
-KPX Tcommaaccent Adieresis -55
-KPX Tcommaaccent Agrave -55
-KPX Tcommaaccent Amacron -55
-KPX Tcommaaccent Aogonek -55
-KPX Tcommaaccent Aring -55
-KPX Tcommaaccent Atilde -55
-KPX Tcommaaccent O -18
-KPX Tcommaaccent Oacute -18
-KPX Tcommaaccent Ocircumflex -18
-KPX Tcommaaccent Odieresis -18
-KPX Tcommaaccent Ograve -18
-KPX Tcommaaccent Ohungarumlaut -18
-KPX Tcommaaccent Omacron -18
-KPX Tcommaaccent Oslash -18
-KPX Tcommaaccent Otilde -18
-KPX Tcommaaccent a -92
-KPX Tcommaaccent aacute -92
-KPX Tcommaaccent abreve -92
-KPX Tcommaaccent acircumflex -92
-KPX Tcommaaccent adieresis -92
-KPX Tcommaaccent agrave -92
-KPX Tcommaaccent amacron -92
-KPX Tcommaaccent aogonek -92
-KPX Tcommaaccent aring -92
-KPX Tcommaaccent atilde -92
-KPX Tcommaaccent colon -74
-KPX Tcommaaccent comma -92
-KPX Tcommaaccent e -92
-KPX Tcommaaccent eacute -92
-KPX Tcommaaccent ecaron -92
-KPX Tcommaaccent ecircumflex -92
-KPX Tcommaaccent edieresis -52
-KPX Tcommaaccent edotaccent -92
-KPX Tcommaaccent egrave -52
-KPX Tcommaaccent emacron -52
-KPX Tcommaaccent eogonek -92
-KPX Tcommaaccent hyphen -92
-KPX Tcommaaccent i -37
-KPX Tcommaaccent iacute -37
-KPX Tcommaaccent iogonek -37
-KPX Tcommaaccent o -95
-KPX Tcommaaccent oacute -95
-KPX Tcommaaccent ocircumflex -95
-KPX Tcommaaccent odieresis -95
-KPX Tcommaaccent ograve -95
-KPX Tcommaaccent ohungarumlaut -95
-KPX Tcommaaccent omacron -95
-KPX Tcommaaccent oslash -95
-KPX Tcommaaccent otilde -95
-KPX Tcommaaccent period -92
-KPX Tcommaaccent r -37
-KPX Tcommaaccent racute -37
-KPX Tcommaaccent rcaron -37
-KPX Tcommaaccent rcommaaccent -37
-KPX Tcommaaccent semicolon -74
-KPX Tcommaaccent u -37
-KPX Tcommaaccent uacute -37
-KPX Tcommaaccent ucircumflex -37
-KPX Tcommaaccent udieresis -37
-KPX Tcommaaccent ugrave -37
-KPX Tcommaaccent uhungarumlaut -37
-KPX Tcommaaccent umacron -37
-KPX Tcommaaccent uogonek -37
-KPX Tcommaaccent uring -37
-KPX Tcommaaccent w -37
-KPX Tcommaaccent y -37
-KPX Tcommaaccent yacute -37
-KPX Tcommaaccent ydieresis -37
-KPX U A -45
-KPX U Aacute -45
-KPX U Abreve -45
-KPX U Acircumflex -45
-KPX U Adieresis -45
-KPX U Agrave -45
-KPX U Amacron -45
-KPX U Aogonek -45
-KPX U Aring -45
-KPX U Atilde -45
-KPX Uacute A -45
-KPX Uacute Aacute -45
-KPX Uacute Abreve -45
-KPX Uacute Acircumflex -45
-KPX Uacute Adieresis -45
-KPX Uacute Agrave -45
-KPX Uacute Amacron -45
-KPX Uacute Aogonek -45
-KPX Uacute Aring -45
-KPX Uacute Atilde -45
-KPX Ucircumflex A -45
-KPX Ucircumflex Aacute -45
-KPX Ucircumflex Abreve -45
-KPX Ucircumflex Acircumflex -45
-KPX Ucircumflex Adieresis -45
-KPX Ucircumflex Agrave -45
-KPX Ucircumflex Amacron -45
-KPX Ucircumflex Aogonek -45
-KPX Ucircumflex Aring -45
-KPX Ucircumflex Atilde -45
-KPX Udieresis A -45
-KPX Udieresis Aacute -45
-KPX Udieresis Abreve -45
-KPX Udieresis Acircumflex -45
-KPX Udieresis Adieresis -45
-KPX Udieresis Agrave -45
-KPX Udieresis Amacron -45
-KPX Udieresis Aogonek -45
-KPX Udieresis Aring -45
-KPX Udieresis Atilde -45
-KPX Ugrave A -45
-KPX Ugrave Aacute -45
-KPX Ugrave Abreve -45
-KPX Ugrave Acircumflex -45
-KPX Ugrave Adieresis -45
-KPX Ugrave Agrave -45
-KPX Ugrave Amacron -45
-KPX Ugrave Aogonek -45
-KPX Ugrave Aring -45
-KPX Ugrave Atilde -45
-KPX Uhungarumlaut A -45
-KPX Uhungarumlaut Aacute -45
-KPX Uhungarumlaut Abreve -45
-KPX Uhungarumlaut Acircumflex -45
-KPX Uhungarumlaut Adieresis -45
-KPX Uhungarumlaut Agrave -45
-KPX Uhungarumlaut Amacron -45
-KPX Uhungarumlaut Aogonek -45
-KPX Uhungarumlaut Aring -45
-KPX Uhungarumlaut Atilde -45
-KPX Umacron A -45
-KPX Umacron Aacute -45
-KPX Umacron Abreve -45
-KPX Umacron Acircumflex -45
-KPX Umacron Adieresis -45
-KPX Umacron Agrave -45
-KPX Umacron Amacron -45
-KPX Umacron Aogonek -45
-KPX Umacron Aring -45
-KPX Umacron Atilde -45
-KPX Uogonek A -45
-KPX Uogonek Aacute -45
-KPX Uogonek Abreve -45
-KPX Uogonek Acircumflex -45
-KPX Uogonek Adieresis -45
-KPX Uogonek Agrave -45
-KPX Uogonek Amacron -45
-KPX Uogonek Aogonek -45
-KPX Uogonek Aring -45
-KPX Uogonek Atilde -45
-KPX Uring A -45
-KPX Uring Aacute -45
-KPX Uring Abreve -45
-KPX Uring Acircumflex -45
-KPX Uring Adieresis -45
-KPX Uring Agrave -45
-KPX Uring Amacron -45
-KPX Uring Aogonek -45
-KPX Uring Aring -45
-KPX Uring Atilde -45
-KPX V A -85
-KPX V Aacute -85
-KPX V Abreve -85
-KPX V Acircumflex -85
-KPX V Adieresis -85
-KPX V Agrave -85
-KPX V Amacron -85
-KPX V Aogonek -85
-KPX V Aring -85
-KPX V Atilde -85
-KPX V G -10
-KPX V Gbreve -10
-KPX V Gcommaaccent -10
-KPX V O -30
-KPX V Oacute -30
-KPX V Ocircumflex -30
-KPX V Odieresis -30
-KPX V Ograve -30
-KPX V Ohungarumlaut -30
-KPX V Omacron -30
-KPX V Oslash -30
-KPX V Otilde -30
-KPX V a -111
-KPX V aacute -111
-KPX V abreve -111
-KPX V acircumflex -111
-KPX V adieresis -111
-KPX V agrave -111
-KPX V amacron -111
-KPX V aogonek -111
-KPX V aring -111
-KPX V atilde -111
-KPX V colon -74
-KPX V comma -129
-KPX V e -111
-KPX V eacute -111
-KPX V ecaron -111
-KPX V ecircumflex -111
-KPX V edieresis -71
-KPX V edotaccent -111
-KPX V egrave -71
-KPX V emacron -71
-KPX V eogonek -111
-KPX V hyphen -70
-KPX V i -55
-KPX V iacute -55
-KPX V iogonek -55
-KPX V o -111
-KPX V oacute -111
-KPX V ocircumflex -111
-KPX V odieresis -111
-KPX V ograve -111
-KPX V ohungarumlaut -111
-KPX V omacron -111
-KPX V oslash -111
-KPX V otilde -111
-KPX V period -129
-KPX V semicolon -74
-KPX V u -55
-KPX V uacute -55
-KPX V ucircumflex -55
-KPX V udieresis -55
-KPX V ugrave -55
-KPX V uhungarumlaut -55
-KPX V umacron -55
-KPX V uogonek -55
-KPX V uring -55
-KPX W A -74
-KPX W Aacute -74
-KPX W Abreve -74
-KPX W Acircumflex -74
-KPX W Adieresis -74
-KPX W Agrave -74
-KPX W Amacron -74
-KPX W Aogonek -74
-KPX W Aring -74
-KPX W Atilde -74
-KPX W O -15
-KPX W Oacute -15
-KPX W Ocircumflex -15
-KPX W Odieresis -15
-KPX W Ograve -15
-KPX W Ohungarumlaut -15
-KPX W Omacron -15
-KPX W Oslash -15
-KPX W Otilde -15
-KPX W a -85
-KPX W aacute -85
-KPX W abreve -85
-KPX W acircumflex -85
-KPX W adieresis -85
-KPX W agrave -85
-KPX W amacron -85
-KPX W aogonek -85
-KPX W aring -85
-KPX W atilde -85
-KPX W colon -55
-KPX W comma -74
-KPX W e -90
-KPX W eacute -90
-KPX W ecaron -90
-KPX W ecircumflex -90
-KPX W edieresis -50
-KPX W edotaccent -90
-KPX W egrave -50
-KPX W emacron -50
-KPX W eogonek -90
-KPX W hyphen -50
-KPX W i -37
-KPX W iacute -37
-KPX W iogonek -37
-KPX W o -80
-KPX W oacute -80
-KPX W ocircumflex -80
-KPX W odieresis -80
-KPX W ograve -80
-KPX W ohungarumlaut -80
-KPX W omacron -80
-KPX W oslash -80
-KPX W otilde -80
-KPX W period -74
-KPX W semicolon -55
-KPX W u -55
-KPX W uacute -55
-KPX W ucircumflex -55
-KPX W udieresis -55
-KPX W ugrave -55
-KPX W uhungarumlaut -55
-KPX W umacron -55
-KPX W uogonek -55
-KPX W uring -55
-KPX W y -55
-KPX W yacute -55
-KPX W ydieresis -55
-KPX Y A -74
-KPX Y Aacute -74
-KPX Y Abreve -74
-KPX Y Acircumflex -74
-KPX Y Adieresis -74
-KPX Y Agrave -74
-KPX Y Amacron -74
-KPX Y Aogonek -74
-KPX Y Aring -74
-KPX Y Atilde -74
-KPX Y O -25
-KPX Y Oacute -25
-KPX Y Ocircumflex -25
-KPX Y Odieresis -25
-KPX Y Ograve -25
-KPX Y Ohungarumlaut -25
-KPX Y Omacron -25
-KPX Y Oslash -25
-KPX Y Otilde -25
-KPX Y a -92
-KPX Y aacute -92
-KPX Y abreve -92
-KPX Y acircumflex -92
-KPX Y adieresis -92
-KPX Y agrave -92
-KPX Y amacron -92
-KPX Y aogonek -92
-KPX Y aring -92
-KPX Y atilde -92
-KPX Y colon -92
-KPX Y comma -92
-KPX Y e -111
-KPX Y eacute -111
-KPX Y ecaron -111
-KPX Y ecircumflex -71
-KPX Y edieresis -71
-KPX Y edotaccent -111
-KPX Y egrave -71
-KPX Y emacron -71
-KPX Y eogonek -111
-KPX Y hyphen -92
-KPX Y i -55
-KPX Y iacute -55
-KPX Y iogonek -55
-KPX Y o -111
-KPX Y oacute -111
-KPX Y ocircumflex -111
-KPX Y odieresis -111
-KPX Y ograve -111
-KPX Y ohungarumlaut -111
-KPX Y omacron -111
-KPX Y oslash -111
-KPX Y otilde -111
-KPX Y period -74
-KPX Y semicolon -92
-KPX Y u -92
-KPX Y uacute -92
-KPX Y ucircumflex -92
-KPX Y udieresis -92
-KPX Y ugrave -92
-KPX Y uhungarumlaut -92
-KPX Y umacron -92
-KPX Y uogonek -92
-KPX Y uring -92
-KPX Yacute A -74
-KPX Yacute Aacute -74
-KPX Yacute Abreve -74
-KPX Yacute Acircumflex -74
-KPX Yacute Adieresis -74
-KPX Yacute Agrave -74
-KPX Yacute Amacron -74
-KPX Yacute Aogonek -74
-KPX Yacute Aring -74
-KPX Yacute Atilde -74
-KPX Yacute O -25
-KPX Yacute Oacute -25
-KPX Yacute Ocircumflex -25
-KPX Yacute Odieresis -25
-KPX Yacute Ograve -25
-KPX Yacute Ohungarumlaut -25
-KPX Yacute Omacron -25
-KPX Yacute Oslash -25
-KPX Yacute Otilde -25
-KPX Yacute a -92
-KPX Yacute aacute -92
-KPX Yacute abreve -92
-KPX Yacute acircumflex -92
-KPX Yacute adieresis -92
-KPX Yacute agrave -92
-KPX Yacute amacron -92
-KPX Yacute aogonek -92
-KPX Yacute aring -92
-KPX Yacute atilde -92
-KPX Yacute colon -92
-KPX Yacute comma -92
-KPX Yacute e -111
-KPX Yacute eacute -111
-KPX Yacute ecaron -111
-KPX Yacute ecircumflex -71
-KPX Yacute edieresis -71
-KPX Yacute edotaccent -111
-KPX Yacute egrave -71
-KPX Yacute emacron -71
-KPX Yacute eogonek -111
-KPX Yacute hyphen -92
-KPX Yacute i -55
-KPX Yacute iacute -55
-KPX Yacute iogonek -55
-KPX Yacute o -111
-KPX Yacute oacute -111
-KPX Yacute ocircumflex -111
-KPX Yacute odieresis -111
-KPX Yacute ograve -111
-KPX Yacute ohungarumlaut -111
-KPX Yacute omacron -111
-KPX Yacute oslash -111
-KPX Yacute otilde -111
-KPX Yacute period -74
-KPX Yacute semicolon -92
-KPX Yacute u -92
-KPX Yacute uacute -92
-KPX Yacute ucircumflex -92
-KPX Yacute udieresis -92
-KPX Yacute ugrave -92
-KPX Yacute uhungarumlaut -92
-KPX Yacute umacron -92
-KPX Yacute uogonek -92
-KPX Yacute uring -92
-KPX Ydieresis A -74
-KPX Ydieresis Aacute -74
-KPX Ydieresis Abreve -74
-KPX Ydieresis Acircumflex -74
-KPX Ydieresis Adieresis -74
-KPX Ydieresis Agrave -74
-KPX Ydieresis Amacron -74
-KPX Ydieresis Aogonek -74
-KPX Ydieresis Aring -74
-KPX Ydieresis Atilde -74
-KPX Ydieresis O -25
-KPX Ydieresis Oacute -25
-KPX Ydieresis Ocircumflex -25
-KPX Ydieresis Odieresis -25
-KPX Ydieresis Ograve -25
-KPX Ydieresis Ohungarumlaut -25
-KPX Ydieresis Omacron -25
-KPX Ydieresis Oslash -25
-KPX Ydieresis Otilde -25
-KPX Ydieresis a -92
-KPX Ydieresis aacute -92
-KPX Ydieresis abreve -92
-KPX Ydieresis acircumflex -92
-KPX Ydieresis adieresis -92
-KPX Ydieresis agrave -92
-KPX Ydieresis amacron -92
-KPX Ydieresis aogonek -92
-KPX Ydieresis aring -92
-KPX Ydieresis atilde -92
-KPX Ydieresis colon -92
-KPX Ydieresis comma -92
-KPX Ydieresis e -111
-KPX Ydieresis eacute -111
-KPX Ydieresis ecaron -111
-KPX Ydieresis ecircumflex -71
-KPX Ydieresis edieresis -71
-KPX Ydieresis edotaccent -111
-KPX Ydieresis egrave -71
-KPX Ydieresis emacron -71
-KPX Ydieresis eogonek -111
-KPX Ydieresis hyphen -92
-KPX Ydieresis i -55
-KPX Ydieresis iacute -55
-KPX Ydieresis iogonek -55
-KPX Ydieresis o -111
-KPX Ydieresis oacute -111
-KPX Ydieresis ocircumflex -111
-KPX Ydieresis odieresis -111
-KPX Ydieresis ograve -111
-KPX Ydieresis ohungarumlaut -111
-KPX Ydieresis omacron -111
-KPX Ydieresis oslash -111
-KPX Ydieresis otilde -111
-KPX Ydieresis period -74
-KPX Ydieresis semicolon -92
-KPX Ydieresis u -92
-KPX Ydieresis uacute -92
-KPX Ydieresis ucircumflex -92
-KPX Ydieresis udieresis -92
-KPX Ydieresis ugrave -92
-KPX Ydieresis uhungarumlaut -92
-KPX Ydieresis umacron -92
-KPX Ydieresis uogonek -92
-KPX Ydieresis uring -92
-KPX b b -10
-KPX b period -40
-KPX b u -20
-KPX b uacute -20
-KPX b ucircumflex -20
-KPX b udieresis -20
-KPX b ugrave -20
-KPX b uhungarumlaut -20
-KPX b umacron -20
-KPX b uogonek -20
-KPX b uring -20
-KPX c h -10
-KPX c k -10
-KPX c kcommaaccent -10
-KPX cacute h -10
-KPX cacute k -10
-KPX cacute kcommaaccent -10
-KPX ccaron h -10
-KPX ccaron k -10
-KPX ccaron kcommaaccent -10
-KPX ccedilla h -10
-KPX ccedilla k -10
-KPX ccedilla kcommaaccent -10
-KPX comma quotedblright -95
-KPX comma quoteright -95
-KPX e b -10
-KPX eacute b -10
-KPX ecaron b -10
-KPX ecircumflex b -10
-KPX edieresis b -10
-KPX edotaccent b -10
-KPX egrave b -10
-KPX emacron b -10
-KPX eogonek b -10
-KPX f comma -10
-KPX f dotlessi -30
-KPX f e -10
-KPX f eacute -10
-KPX f edotaccent -10
-KPX f eogonek -10
-KPX f f -18
-KPX f o -10
-KPX f oacute -10
-KPX f ocircumflex -10
-KPX f ograve -10
-KPX f ohungarumlaut -10
-KPX f oslash -10
-KPX f otilde -10
-KPX f period -10
-KPX f quoteright 55
-KPX k e -30
-KPX k eacute -30
-KPX k ecaron -30
-KPX k ecircumflex -30
-KPX k edieresis -30
-KPX k edotaccent -30
-KPX k egrave -30
-KPX k emacron -30
-KPX k eogonek -30
-KPX k o -10
-KPX k oacute -10
-KPX k ocircumflex -10
-KPX k odieresis -10
-KPX k ograve -10
-KPX k ohungarumlaut -10
-KPX k omacron -10
-KPX k oslash -10
-KPX k otilde -10
-KPX kcommaaccent e -30
-KPX kcommaaccent eacute -30
-KPX kcommaaccent ecaron -30
-KPX kcommaaccent ecircumflex -30
-KPX kcommaaccent edieresis -30
-KPX kcommaaccent edotaccent -30
-KPX kcommaaccent egrave -30
-KPX kcommaaccent emacron -30
-KPX kcommaaccent eogonek -30
-KPX kcommaaccent o -10
-KPX kcommaaccent oacute -10
-KPX kcommaaccent ocircumflex -10
-KPX kcommaaccent odieresis -10
-KPX kcommaaccent ograve -10
-KPX kcommaaccent ohungarumlaut -10
-KPX kcommaaccent omacron -10
-KPX kcommaaccent oslash -10
-KPX kcommaaccent otilde -10
-KPX n v -40
-KPX nacute v -40
-KPX ncaron v -40
-KPX ncommaaccent v -40
-KPX ntilde v -40
-KPX o v -15
-KPX o w -25
-KPX o x -10
-KPX o y -10
-KPX o yacute -10
-KPX o ydieresis -10
-KPX oacute v -15
-KPX oacute w -25
-KPX oacute x -10
-KPX oacute y -10
-KPX oacute yacute -10
-KPX oacute ydieresis -10
-KPX ocircumflex v -15
-KPX ocircumflex w -25
-KPX ocircumflex x -10
-KPX ocircumflex y -10
-KPX ocircumflex yacute -10
-KPX ocircumflex ydieresis -10
-KPX odieresis v -15
-KPX odieresis w -25
-KPX odieresis x -10
-KPX odieresis y -10
-KPX odieresis yacute -10
-KPX odieresis ydieresis -10
-KPX ograve v -15
-KPX ograve w -25
-KPX ograve x -10
-KPX ograve y -10
-KPX ograve yacute -10
-KPX ograve ydieresis -10
-KPX ohungarumlaut v -15
-KPX ohungarumlaut w -25
-KPX ohungarumlaut x -10
-KPX ohungarumlaut y -10
-KPX ohungarumlaut yacute -10
-KPX ohungarumlaut ydieresis -10
-KPX omacron v -15
-KPX omacron w -25
-KPX omacron x -10
-KPX omacron y -10
-KPX omacron yacute -10
-KPX omacron ydieresis -10
-KPX oslash v -15
-KPX oslash w -25
-KPX oslash x -10
-KPX oslash y -10
-KPX oslash yacute -10
-KPX oslash ydieresis -10
-KPX otilde v -15
-KPX otilde w -25
-KPX otilde x -10
-KPX otilde y -10
-KPX otilde yacute -10
-KPX otilde ydieresis -10
-KPX period quotedblright -95
-KPX period quoteright -95
-KPX quoteleft quoteleft -74
-KPX quoteright d -15
-KPX quoteright dcroat -15
-KPX quoteright quoteright -74
-KPX quoteright r -15
-KPX quoteright racute -15
-KPX quoteright rcaron -15
-KPX quoteright rcommaaccent -15
-KPX quoteright s -74
-KPX quoteright sacute -74
-KPX quoteright scaron -74
-KPX quoteright scedilla -74
-KPX quoteright scommaaccent -74
-KPX quoteright space -74
-KPX quoteright t -37
-KPX quoteright tcommaaccent -37
-KPX quoteright v -15
-KPX r comma -65
-KPX r period -65
-KPX racute comma -65
-KPX racute period -65
-KPX rcaron comma -65
-KPX rcaron period -65
-KPX rcommaaccent comma -65
-KPX rcommaaccent period -65
-KPX space A -37
-KPX space Aacute -37
-KPX space Abreve -37
-KPX space Acircumflex -37
-KPX space Adieresis -37
-KPX space Agrave -37
-KPX space Amacron -37
-KPX space Aogonek -37
-KPX space Aring -37
-KPX space Atilde -37
-KPX space V -70
-KPX space W -70
-KPX space Y -70
-KPX space Yacute -70
-KPX space Ydieresis -70
-KPX v comma -37
-KPX v e -15
-KPX v eacute -15
-KPX v ecaron -15
-KPX v ecircumflex -15
-KPX v edieresis -15
-KPX v edotaccent -15
-KPX v egrave -15
-KPX v emacron -15
-KPX v eogonek -15
-KPX v o -15
-KPX v oacute -15
-KPX v ocircumflex -15
-KPX v odieresis -15
-KPX v ograve -15
-KPX v ohungarumlaut -15
-KPX v omacron -15
-KPX v oslash -15
-KPX v otilde -15
-KPX v period -37
-KPX w a -10
-KPX w aacute -10
-KPX w abreve -10
-KPX w acircumflex -10
-KPX w adieresis -10
-KPX w agrave -10
-KPX w amacron -10
-KPX w aogonek -10
-KPX w aring -10
-KPX w atilde -10
-KPX w comma -37
-KPX w e -10
-KPX w eacute -10
-KPX w ecaron -10
-KPX w ecircumflex -10
-KPX w edieresis -10
-KPX w edotaccent -10
-KPX w egrave -10
-KPX w emacron -10
-KPX w eogonek -10
-KPX w o -15
-KPX w oacute -15
-KPX w ocircumflex -15
-KPX w odieresis -15
-KPX w ograve -15
-KPX w ohungarumlaut -15
-KPX w omacron -15
-KPX w oslash -15
-KPX w otilde -15
-KPX w period -37
-KPX x e -10
-KPX x eacute -10
-KPX x ecaron -10
-KPX x ecircumflex -10
-KPX x edieresis -10
-KPX x edotaccent -10
-KPX x egrave -10
-KPX x emacron -10
-KPX x eogonek -10
-KPX y comma -37
-KPX y period -37
-KPX yacute comma -37
-KPX yacute period -37
-KPX ydieresis comma -37
-KPX ydieresis period -37
-EndKernPairs
-EndKernData
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Italic.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Italic.afm
deleted file mode 100644
index b0eaee40fc..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Italic.afm
+++ /dev/null
@@ -1,2667 +0,0 @@
-StartFontMetrics 4.1
-Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Thu May 1 12:56:55 1997
-Comment UniqueID 43067
-Comment VMusage 47727 58752
-FontName Times-Italic
-FullName Times Italic
-FamilyName Times
-Weight Medium
-ItalicAngle -15.5
-IsFixedPitch false
-CharacterSet ExtendedRoman
-FontBBox -169 -217 1010 883
-UnderlinePosition -100
-UnderlineThickness 50
-Version 002.000
-Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 653
-XHeight 441
-Ascender 683
-Descender -217
-StdHW 32
-StdVW 76
-StartCharMetrics 315
-C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 39 -11 302 667 ;
-C 34 ; WX 420 ; N quotedbl ; B 144 421 432 666 ;
-C 35 ; WX 500 ; N numbersign ; B 2 0 540 676 ;
-C 36 ; WX 500 ; N dollar ; B 31 -89 497 731 ;
-C 37 ; WX 833 ; N percent ; B 79 -13 790 676 ;
-C 38 ; WX 778 ; N ampersand ; B 76 -18 723 666 ;
-C 39 ; WX 333 ; N quoteright ; B 151 436 290 666 ;
-C 40 ; WX 333 ; N parenleft ; B 42 -181 315 669 ;
-C 41 ; WX 333 ; N parenright ; B 16 -180 289 669 ;
-C 42 ; WX 500 ; N asterisk ; B 128 255 492 666 ;
-C 43 ; WX 675 ; N plus ; B 86 0 590 506 ;
-C 44 ; WX 250 ; N comma ; B -4 -129 135 101 ;
-C 45 ; WX 333 ; N hyphen ; B 49 192 282 255 ;
-C 46 ; WX 250 ; N period ; B 27 -11 138 100 ;
-C 47 ; WX 278 ; N slash ; B -65 -18 386 666 ;
-C 48 ; WX 500 ; N zero ; B 32 -7 497 676 ;
-C 49 ; WX 500 ; N one ; B 49 0 409 676 ;
-C 50 ; WX 500 ; N two ; B 12 0 452 676 ;
-C 51 ; WX 500 ; N three ; B 15 -7 465 676 ;
-C 52 ; WX 500 ; N four ; B 1 0 479 676 ;
-C 53 ; WX 500 ; N five ; B 15 -7 491 666 ;
-C 54 ; WX 500 ; N six ; B 30 -7 521 686 ;
-C 55 ; WX 500 ; N seven ; B 75 -8 537 666 ;
-C 56 ; WX 500 ; N eight ; B 30 -7 493 676 ;
-C 57 ; WX 500 ; N nine ; B 23 -17 492 676 ;
-C 58 ; WX 333 ; N colon ; B 50 -11 261 441 ;
-C 59 ; WX 333 ; N semicolon ; B 27 -129 261 441 ;
-C 60 ; WX 675 ; N less ; B 84 -8 592 514 ;
-C 61 ; WX 675 ; N equal ; B 86 120 590 386 ;
-C 62 ; WX 675 ; N greater ; B 84 -8 592 514 ;
-C 63 ; WX 500 ; N question ; B 132 -12 472 664 ;
-C 64 ; WX 920 ; N at ; B 118 -18 806 666 ;
-C 65 ; WX 611 ; N A ; B -51 0 564 668 ;
-C 66 ; WX 611 ; N B ; B -8 0 588 653 ;
-C 67 ; WX 667 ; N C ; B 66 -18 689 666 ;
-C 68 ; WX 722 ; N D ; B -8 0 700 653 ;
-C 69 ; WX 611 ; N E ; B -1 0 634 653 ;
-C 70 ; WX 611 ; N F ; B 8 0 645 653 ;
-C 71 ; WX 722 ; N G ; B 52 -18 722 666 ;
-C 72 ; WX 722 ; N H ; B -8 0 767 653 ;
-C 73 ; WX 333 ; N I ; B -8 0 384 653 ;
-C 74 ; WX 444 ; N J ; B -6 -18 491 653 ;
-C 75 ; WX 667 ; N K ; B 7 0 722 653 ;
-C 76 ; WX 556 ; N L ; B -8 0 559 653 ;
-C 77 ; WX 833 ; N M ; B -18 0 873 653 ;
-C 78 ; WX 667 ; N N ; B -20 -15 727 653 ;
-C 79 ; WX 722 ; N O ; B 60 -18 699 666 ;
-C 80 ; WX 611 ; N P ; B 0 0 605 653 ;
-C 81 ; WX 722 ; N Q ; B 59 -182 699 666 ;
-C 82 ; WX 611 ; N R ; B -13 0 588 653 ;
-C 83 ; WX 500 ; N S ; B 17 -18 508 667 ;
-C 84 ; WX 556 ; N T ; B 59 0 633 653 ;
-C 85 ; WX 722 ; N U ; B 102 -18 765 653 ;
-C 86 ; WX 611 ; N V ; B 76 -18 688 653 ;
-C 87 ; WX 833 ; N W ; B 71 -18 906 653 ;
-C 88 ; WX 611 ; N X ; B -29 0 655 653 ;
-C 89 ; WX 556 ; N Y ; B 78 0 633 653 ;
-C 90 ; WX 556 ; N Z ; B -6 0 606 653 ;
-C 91 ; WX 389 ; N bracketleft ; B 21 -153 391 663 ;
-C 92 ; WX 278 ; N backslash ; B -41 -18 319 666 ;
-C 93 ; WX 389 ; N bracketright ; B 12 -153 382 663 ;
-C 94 ; WX 422 ; N asciicircum ; B 0 301 422 666 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 333 ; N quoteleft ; B 171 436 310 666 ;
-C 97 ; WX 500 ; N a ; B 17 -11 476 441 ;
-C 98 ; WX 500 ; N b ; B 23 -11 473 683 ;
-C 99 ; WX 444 ; N c ; B 30 -11 425 441 ;
-C 100 ; WX 500 ; N d ; B 15 -13 527 683 ;
-C 101 ; WX 444 ; N e ; B 31 -11 412 441 ;
-C 102 ; WX 278 ; N f ; B -147 -207 424 678 ; L i fi ; L l fl ;
-C 103 ; WX 500 ; N g ; B 8 -206 472 441 ;
-C 104 ; WX 500 ; N h ; B 19 -9 478 683 ;
-C 105 ; WX 278 ; N i ; B 49 -11 264 654 ;
-C 106 ; WX 278 ; N j ; B -124 -207 276 654 ;
-C 107 ; WX 444 ; N k ; B 14 -11 461 683 ;
-C 108 ; WX 278 ; N l ; B 41 -11 279 683 ;
-C 109 ; WX 722 ; N m ; B 12 -9 704 441 ;
-C 110 ; WX 500 ; N n ; B 14 -9 474 441 ;
-C 111 ; WX 500 ; N o ; B 27 -11 468 441 ;
-C 112 ; WX 500 ; N p ; B -75 -205 469 441 ;
-C 113 ; WX 500 ; N q ; B 25 -209 483 441 ;
-C 114 ; WX 389 ; N r ; B 45 0 412 441 ;
-C 115 ; WX 389 ; N s ; B 16 -13 366 442 ;
-C 116 ; WX 278 ; N t ; B 37 -11 296 546 ;
-C 117 ; WX 500 ; N u ; B 42 -11 475 441 ;
-C 118 ; WX 444 ; N v ; B 21 -18 426 441 ;
-C 119 ; WX 667 ; N w ; B 16 -18 648 441 ;
-C 120 ; WX 444 ; N x ; B -27 -11 447 441 ;
-C 121 ; WX 444 ; N y ; B -24 -206 426 441 ;
-C 122 ; WX 389 ; N z ; B -2 -81 380 428 ;
-C 123 ; WX 400 ; N braceleft ; B 51 -177 407 687 ;
-C 124 ; WX 275 ; N bar ; B 105 -217 171 783 ;
-C 125 ; WX 400 ; N braceright ; B -7 -177 349 687 ;
-C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ;
-C 161 ; WX 389 ; N exclamdown ; B 59 -205 322 473 ;
-C 162 ; WX 500 ; N cent ; B 77 -143 472 560 ;
-C 163 ; WX 500 ; N sterling ; B 10 -6 517 670 ;
-C 164 ; WX 167 ; N fraction ; B -169 -10 337 676 ;
-C 165 ; WX 500 ; N yen ; B 27 0 603 653 ;
-C 166 ; WX 500 ; N florin ; B 25 -182 507 682 ;
-C 167 ; WX 500 ; N section ; B 53 -162 461 666 ;
-C 168 ; WX 500 ; N currency ; B -22 53 522 597 ;
-C 169 ; WX 214 ; N quotesingle ; B 132 421 241 666 ;
-C 170 ; WX 556 ; N quotedblleft ; B 166 436 514 666 ;
-C 171 ; WX 500 ; N guillemotleft ; B 53 37 445 403 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 51 37 281 403 ;
-C 173 ; WX 333 ; N guilsinglright ; B 52 37 282 403 ;
-C 174 ; WX 500 ; N fi ; B -141 -207 481 681 ;
-C 175 ; WX 500 ; N fl ; B -141 -204 518 682 ;
-C 177 ; WX 500 ; N endash ; B -6 197 505 243 ;
-C 178 ; WX 500 ; N dagger ; B 101 -159 488 666 ;
-C 179 ; WX 500 ; N daggerdbl ; B 22 -143 491 666 ;
-C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ;
-C 182 ; WX 523 ; N paragraph ; B 55 -123 616 653 ;
-C 183 ; WX 350 ; N bullet ; B 40 191 310 461 ;
-C 184 ; WX 333 ; N quotesinglbase ; B 44 -129 183 101 ;
-C 185 ; WX 556 ; N quotedblbase ; B 57 -129 405 101 ;
-C 186 ; WX 556 ; N quotedblright ; B 151 436 499 666 ;
-C 187 ; WX 500 ; N guillemotright ; B 55 37 447 403 ;
-C 188 ; WX 889 ; N ellipsis ; B 57 -11 762 100 ;
-C 189 ; WX 1000 ; N perthousand ; B 25 -19 1010 706 ;
-C 191 ; WX 500 ; N questiondown ; B 28 -205 368 471 ;
-C 193 ; WX 333 ; N grave ; B 121 492 311 664 ;
-C 194 ; WX 333 ; N acute ; B 180 494 403 664 ;
-C 195 ; WX 333 ; N circumflex ; B 91 492 385 661 ;
-C 196 ; WX 333 ; N tilde ; B 100 517 427 624 ;
-C 197 ; WX 333 ; N macron ; B 99 532 411 583 ;
-C 198 ; WX 333 ; N breve ; B 117 492 418 650 ;
-C 199 ; WX 333 ; N dotaccent ; B 207 548 305 646 ;
-C 200 ; WX 333 ; N dieresis ; B 107 548 405 646 ;
-C 202 ; WX 333 ; N ring ; B 155 492 355 691 ;
-C 203 ; WX 333 ; N cedilla ; B -30 -217 182 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B 93 494 486 664 ;
-C 206 ; WX 333 ; N ogonek ; B 20 -169 203 40 ;
-C 207 ; WX 333 ; N caron ; B 121 492 426 661 ;
-C 208 ; WX 889 ; N emdash ; B -6 197 894 243 ;
-C 225 ; WX 889 ; N AE ; B -27 0 911 653 ;
-C 227 ; WX 276 ; N ordfeminine ; B 42 406 352 676 ;
-C 232 ; WX 556 ; N Lslash ; B -8 0 559 653 ;
-C 233 ; WX 722 ; N Oslash ; B 60 -105 699 722 ;
-C 234 ; WX 944 ; N OE ; B 49 -8 964 666 ;
-C 235 ; WX 310 ; N ordmasculine ; B 67 406 362 676 ;
-C 241 ; WX 667 ; N ae ; B 23 -11 640 441 ;
-C 245 ; WX 278 ; N dotlessi ; B 49 -11 235 441 ;
-C 248 ; WX 278 ; N lslash ; B 41 -11 312 683 ;
-C 249 ; WX 500 ; N oslash ; B 28 -135 469 554 ;
-C 250 ; WX 667 ; N oe ; B 20 -12 646 441 ;
-C 251 ; WX 500 ; N germandbls ; B -168 -207 493 679 ;
-C -1 ; WX 333 ; N Idieresis ; B -8 0 435 818 ;
-C -1 ; WX 444 ; N eacute ; B 31 -11 459 664 ;
-C -1 ; WX 500 ; N abreve ; B 17 -11 502 650 ;
-C -1 ; WX 500 ; N uhungarumlaut ; B 42 -11 580 664 ;
-C -1 ; WX 444 ; N ecaron ; B 31 -11 482 661 ;
-C -1 ; WX 556 ; N Ydieresis ; B 78 0 633 818 ;
-C -1 ; WX 675 ; N divide ; B 86 -11 590 517 ;
-C -1 ; WX 556 ; N Yacute ; B 78 0 633 876 ;
-C -1 ; WX 611 ; N Acircumflex ; B -51 0 564 873 ;
-C -1 ; WX 500 ; N aacute ; B 17 -11 487 664 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 102 -18 765 873 ;
-C -1 ; WX 444 ; N yacute ; B -24 -206 459 664 ;
-C -1 ; WX 389 ; N scommaaccent ; B 16 -217 366 442 ;
-C -1 ; WX 444 ; N ecircumflex ; B 31 -11 441 661 ;
-C -1 ; WX 722 ; N Uring ; B 102 -18 765 883 ;
-C -1 ; WX 722 ; N Udieresis ; B 102 -18 765 818 ;
-C -1 ; WX 500 ; N aogonek ; B 17 -169 476 441 ;
-C -1 ; WX 722 ; N Uacute ; B 102 -18 765 876 ;
-C -1 ; WX 500 ; N uogonek ; B 42 -169 477 441 ;
-C -1 ; WX 611 ; N Edieresis ; B -1 0 634 818 ;
-C -1 ; WX 722 ; N Dcroat ; B -8 0 700 653 ;
-C -1 ; WX 250 ; N commaaccent ; B 8 -217 133 -50 ;
-C -1 ; WX 760 ; N copyright ; B 41 -18 719 666 ;
-C -1 ; WX 611 ; N Emacron ; B -1 0 634 795 ;
-C -1 ; WX 444 ; N ccaron ; B 30 -11 482 661 ;
-C -1 ; WX 500 ; N aring ; B 17 -11 476 691 ;
-C -1 ; WX 667 ; N Ncommaaccent ; B -20 -187 727 653 ;
-C -1 ; WX 278 ; N lacute ; B 41 -11 395 876 ;
-C -1 ; WX 500 ; N agrave ; B 17 -11 476 664 ;
-C -1 ; WX 556 ; N Tcommaaccent ; B 59 -217 633 653 ;
-C -1 ; WX 667 ; N Cacute ; B 66 -18 690 876 ;
-C -1 ; WX 500 ; N atilde ; B 17 -11 511 624 ;
-C -1 ; WX 611 ; N Edotaccent ; B -1 0 634 818 ;
-C -1 ; WX 389 ; N scaron ; B 16 -13 454 661 ;
-C -1 ; WX 389 ; N scedilla ; B 16 -217 366 442 ;
-C -1 ; WX 278 ; N iacute ; B 49 -11 355 664 ;
-C -1 ; WX 471 ; N lozenge ; B 13 0 459 724 ;
-C -1 ; WX 611 ; N Rcaron ; B -13 0 588 873 ;
-C -1 ; WX 722 ; N Gcommaaccent ; B 52 -217 722 666 ;
-C -1 ; WX 500 ; N ucircumflex ; B 42 -11 475 661 ;
-C -1 ; WX 500 ; N acircumflex ; B 17 -11 476 661 ;
-C -1 ; WX 611 ; N Amacron ; B -51 0 564 795 ;
-C -1 ; WX 389 ; N rcaron ; B 45 0 434 661 ;
-C -1 ; WX 444 ; N ccedilla ; B 30 -217 425 441 ;
-C -1 ; WX 556 ; N Zdotaccent ; B -6 0 606 818 ;
-C -1 ; WX 611 ; N Thorn ; B 0 0 569 653 ;
-C -1 ; WX 722 ; N Omacron ; B 60 -18 699 795 ;
-C -1 ; WX 611 ; N Racute ; B -13 0 588 876 ;
-C -1 ; WX 500 ; N Sacute ; B 17 -18 508 876 ;
-C -1 ; WX 544 ; N dcaron ; B 15 -13 658 683 ;
-C -1 ; WX 722 ; N Umacron ; B 102 -18 765 795 ;
-C -1 ; WX 500 ; N uring ; B 42 -11 475 691 ;
-C -1 ; WX 300 ; N threesuperior ; B 43 268 339 676 ;
-C -1 ; WX 722 ; N Ograve ; B 60 -18 699 876 ;
-C -1 ; WX 611 ; N Agrave ; B -51 0 564 876 ;
-C -1 ; WX 611 ; N Abreve ; B -51 0 564 862 ;
-C -1 ; WX 675 ; N multiply ; B 93 8 582 497 ;
-C -1 ; WX 500 ; N uacute ; B 42 -11 477 664 ;
-C -1 ; WX 556 ; N Tcaron ; B 59 0 633 873 ;
-C -1 ; WX 476 ; N partialdiff ; B 17 -38 459 710 ;
-C -1 ; WX 444 ; N ydieresis ; B -24 -206 441 606 ;
-C -1 ; WX 667 ; N Nacute ; B -20 -15 727 876 ;
-C -1 ; WX 278 ; N icircumflex ; B 33 -11 327 661 ;
-C -1 ; WX 611 ; N Ecircumflex ; B -1 0 634 873 ;
-C -1 ; WX 500 ; N adieresis ; B 17 -11 489 606 ;
-C -1 ; WX 444 ; N edieresis ; B 31 -11 451 606 ;
-C -1 ; WX 444 ; N cacute ; B 30 -11 459 664 ;
-C -1 ; WX 500 ; N nacute ; B 14 -9 477 664 ;
-C -1 ; WX 500 ; N umacron ; B 42 -11 485 583 ;
-C -1 ; WX 667 ; N Ncaron ; B -20 -15 727 873 ;
-C -1 ; WX 333 ; N Iacute ; B -8 0 433 876 ;
-C -1 ; WX 675 ; N plusminus ; B 86 0 590 506 ;
-C -1 ; WX 275 ; N brokenbar ; B 105 -142 171 708 ;
-C -1 ; WX 760 ; N registered ; B 41 -18 719 666 ;
-C -1 ; WX 722 ; N Gbreve ; B 52 -18 722 862 ;
-C -1 ; WX 333 ; N Idotaccent ; B -8 0 384 818 ;
-C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ;
-C -1 ; WX 611 ; N Egrave ; B -1 0 634 876 ;
-C -1 ; WX 389 ; N racute ; B 45 0 431 664 ;
-C -1 ; WX 500 ; N omacron ; B 27 -11 495 583 ;
-C -1 ; WX 556 ; N Zacute ; B -6 0 606 876 ;
-C -1 ; WX 556 ; N Zcaron ; B -6 0 606 873 ;
-C -1 ; WX 549 ; N greaterequal ; B 26 0 523 658 ;
-C -1 ; WX 722 ; N Eth ; B -8 0 700 653 ;
-C -1 ; WX 667 ; N Ccedilla ; B 66 -217 689 666 ;
-C -1 ; WX 278 ; N lcommaaccent ; B 22 -217 279 683 ;
-C -1 ; WX 300 ; N tcaron ; B 37 -11 407 681 ;
-C -1 ; WX 444 ; N eogonek ; B 31 -169 412 441 ;
-C -1 ; WX 722 ; N Uogonek ; B 102 -184 765 653 ;
-C -1 ; WX 611 ; N Aacute ; B -51 0 564 876 ;
-C -1 ; WX 611 ; N Adieresis ; B -51 0 564 818 ;
-C -1 ; WX 444 ; N egrave ; B 31 -11 412 664 ;
-C -1 ; WX 389 ; N zacute ; B -2 -81 431 664 ;
-C -1 ; WX 278 ; N iogonek ; B 49 -169 264 654 ;
-C -1 ; WX 722 ; N Oacute ; B 60 -18 699 876 ;
-C -1 ; WX 500 ; N oacute ; B 27 -11 487 664 ;
-C -1 ; WX 500 ; N amacron ; B 17 -11 495 583 ;
-C -1 ; WX 389 ; N sacute ; B 16 -13 431 664 ;
-C -1 ; WX 278 ; N idieresis ; B 49 -11 352 606 ;
-C -1 ; WX 722 ; N Ocircumflex ; B 60 -18 699 873 ;
-C -1 ; WX 722 ; N Ugrave ; B 102 -18 765 876 ;
-C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ;
-C -1 ; WX 500 ; N thorn ; B -75 -205 469 683 ;
-C -1 ; WX 300 ; N twosuperior ; B 33 271 324 676 ;
-C -1 ; WX 722 ; N Odieresis ; B 60 -18 699 818 ;
-C -1 ; WX 500 ; N mu ; B -30 -209 497 428 ;
-C -1 ; WX 278 ; N igrave ; B 49 -11 284 664 ;
-C -1 ; WX 500 ; N ohungarumlaut ; B 27 -11 590 664 ;
-C -1 ; WX 611 ; N Eogonek ; B -1 -169 634 653 ;
-C -1 ; WX 500 ; N dcroat ; B 15 -13 572 683 ;
-C -1 ; WX 750 ; N threequarters ; B 23 -10 736 676 ;
-C -1 ; WX 500 ; N Scedilla ; B 17 -217 508 667 ;
-C -1 ; WX 300 ; N lcaron ; B 41 -11 407 683 ;
-C -1 ; WX 667 ; N Kcommaaccent ; B 7 -217 722 653 ;
-C -1 ; WX 556 ; N Lacute ; B -8 0 559 876 ;
-C -1 ; WX 980 ; N trademark ; B 30 247 957 653 ;
-C -1 ; WX 444 ; N edotaccent ; B 31 -11 412 606 ;
-C -1 ; WX 333 ; N Igrave ; B -8 0 384 876 ;
-C -1 ; WX 333 ; N Imacron ; B -8 0 441 795 ;
-C -1 ; WX 611 ; N Lcaron ; B -8 0 586 653 ;
-C -1 ; WX 750 ; N onehalf ; B 34 -10 749 676 ;
-C -1 ; WX 549 ; N lessequal ; B 26 0 523 658 ;
-C -1 ; WX 500 ; N ocircumflex ; B 27 -11 468 661 ;
-C -1 ; WX 500 ; N ntilde ; B 14 -9 476 624 ;
-C -1 ; WX 722 ; N Uhungarumlaut ; B 102 -18 765 876 ;
-C -1 ; WX 611 ; N Eacute ; B -1 0 634 876 ;
-C -1 ; WX 444 ; N emacron ; B 31 -11 457 583 ;
-C -1 ; WX 500 ; N gbreve ; B 8 -206 487 650 ;
-C -1 ; WX 750 ; N onequarter ; B 33 -10 736 676 ;
-C -1 ; WX 500 ; N Scaron ; B 17 -18 520 873 ;
-C -1 ; WX 500 ; N Scommaaccent ; B 17 -217 508 667 ;
-C -1 ; WX 722 ; N Ohungarumlaut ; B 60 -18 699 876 ;
-C -1 ; WX 400 ; N degree ; B 101 390 387 676 ;
-C -1 ; WX 500 ; N ograve ; B 27 -11 468 664 ;
-C -1 ; WX 667 ; N Ccaron ; B 66 -18 689 873 ;
-C -1 ; WX 500 ; N ugrave ; B 42 -11 475 664 ;
-C -1 ; WX 453 ; N radical ; B 2 -60 452 768 ;
-C -1 ; WX 722 ; N Dcaron ; B -8 0 700 873 ;
-C -1 ; WX 389 ; N rcommaaccent ; B -3 -217 412 441 ;
-C -1 ; WX 667 ; N Ntilde ; B -20 -15 727 836 ;
-C -1 ; WX 500 ; N otilde ; B 27 -11 496 624 ;
-C -1 ; WX 611 ; N Rcommaaccent ; B -13 -187 588 653 ;
-C -1 ; WX 556 ; N Lcommaaccent ; B -8 -217 559 653 ;
-C -1 ; WX 611 ; N Atilde ; B -51 0 566 836 ;
-C -1 ; WX 611 ; N Aogonek ; B -51 -169 566 668 ;
-C -1 ; WX 611 ; N Aring ; B -51 0 564 883 ;
-C -1 ; WX 722 ; N Otilde ; B 60 -18 699 836 ;
-C -1 ; WX 389 ; N zdotaccent ; B -2 -81 380 606 ;
-C -1 ; WX 611 ; N Ecaron ; B -1 0 634 873 ;
-C -1 ; WX 333 ; N Iogonek ; B -8 -169 384 653 ;
-C -1 ; WX 444 ; N kcommaaccent ; B 14 -187 461 683 ;
-C -1 ; WX 675 ; N minus ; B 86 220 590 286 ;
-C -1 ; WX 333 ; N Icircumflex ; B -8 0 425 873 ;
-C -1 ; WX 500 ; N ncaron ; B 14 -9 510 661 ;
-C -1 ; WX 278 ; N tcommaaccent ; B 2 -217 296 546 ;
-C -1 ; WX 675 ; N logicalnot ; B 86 108 590 386 ;
-C -1 ; WX 500 ; N odieresis ; B 27 -11 489 606 ;
-C -1 ; WX 500 ; N udieresis ; B 42 -11 479 606 ;
-C -1 ; WX 549 ; N notequal ; B 12 -29 537 541 ;
-C -1 ; WX 500 ; N gcommaaccent ; B 8 -206 472 706 ;
-C -1 ; WX 500 ; N eth ; B 27 -11 482 683 ;
-C -1 ; WX 389 ; N zcaron ; B -2 -81 434 661 ;
-C -1 ; WX 500 ; N ncommaaccent ; B 14 -187 474 441 ;
-C -1 ; WX 300 ; N onesuperior ; B 43 271 284 676 ;
-C -1 ; WX 278 ; N imacron ; B 46 -11 311 583 ;
-C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 2321
-KPX A C -30
-KPX A Cacute -30
-KPX A Ccaron -30
-KPX A Ccedilla -30
-KPX A G -35
-KPX A Gbreve -35
-KPX A Gcommaaccent -35
-KPX A O -40
-KPX A Oacute -40
-KPX A Ocircumflex -40
-KPX A Odieresis -40
-KPX A Ograve -40
-KPX A Ohungarumlaut -40
-KPX A Omacron -40
-KPX A Oslash -40
-KPX A Otilde -40
-KPX A Q -40
-KPX A T -37
-KPX A Tcaron -37
-KPX A Tcommaaccent -37
-KPX A U -50
-KPX A Uacute -50
-KPX A Ucircumflex -50
-KPX A Udieresis -50
-KPX A Ugrave -50
-KPX A Uhungarumlaut -50
-KPX A Umacron -50
-KPX A Uogonek -50
-KPX A Uring -50
-KPX A V -105
-KPX A W -95
-KPX A Y -55
-KPX A Yacute -55
-KPX A Ydieresis -55
-KPX A quoteright -37
-KPX A u -20
-KPX A uacute -20
-KPX A ucircumflex -20
-KPX A udieresis -20
-KPX A ugrave -20
-KPX A uhungarumlaut -20
-KPX A umacron -20
-KPX A uogonek -20
-KPX A uring -20
-KPX A v -55
-KPX A w -55
-KPX A y -55
-KPX A yacute -55
-KPX A ydieresis -55
-KPX Aacute C -30
-KPX Aacute Cacute -30
-KPX Aacute Ccaron -30
-KPX Aacute Ccedilla -30
-KPX Aacute G -35
-KPX Aacute Gbreve -35
-KPX Aacute Gcommaaccent -35
-KPX Aacute O -40
-KPX Aacute Oacute -40
-KPX Aacute Ocircumflex -40
-KPX Aacute Odieresis -40
-KPX Aacute Ograve -40
-KPX Aacute Ohungarumlaut -40
-KPX Aacute Omacron -40
-KPX Aacute Oslash -40
-KPX Aacute Otilde -40
-KPX Aacute Q -40
-KPX Aacute T -37
-KPX Aacute Tcaron -37
-KPX Aacute Tcommaaccent -37
-KPX Aacute U -50
-KPX Aacute Uacute -50
-KPX Aacute Ucircumflex -50
-KPX Aacute Udieresis -50
-KPX Aacute Ugrave -50
-KPX Aacute Uhungarumlaut -50
-KPX Aacute Umacron -50
-KPX Aacute Uogonek -50
-KPX Aacute Uring -50
-KPX Aacute V -105
-KPX Aacute W -95
-KPX Aacute Y -55
-KPX Aacute Yacute -55
-KPX Aacute Ydieresis -55
-KPX Aacute quoteright -37
-KPX Aacute u -20
-KPX Aacute uacute -20
-KPX Aacute ucircumflex -20
-KPX Aacute udieresis -20
-KPX Aacute ugrave -20
-KPX Aacute uhungarumlaut -20
-KPX Aacute umacron -20
-KPX Aacute uogonek -20
-KPX Aacute uring -20
-KPX Aacute v -55
-KPX Aacute w -55
-KPX Aacute y -55
-KPX Aacute yacute -55
-KPX Aacute ydieresis -55
-KPX Abreve C -30
-KPX Abreve Cacute -30
-KPX Abreve Ccaron -30
-KPX Abreve Ccedilla -30
-KPX Abreve G -35
-KPX Abreve Gbreve -35
-KPX Abreve Gcommaaccent -35
-KPX Abreve O -40
-KPX Abreve Oacute -40
-KPX Abreve Ocircumflex -40
-KPX Abreve Odieresis -40
-KPX Abreve Ograve -40
-KPX Abreve Ohungarumlaut -40
-KPX Abreve Omacron -40
-KPX Abreve Oslash -40
-KPX Abreve Otilde -40
-KPX Abreve Q -40
-KPX Abreve T -37
-KPX Abreve Tcaron -37
-KPX Abreve Tcommaaccent -37
-KPX Abreve U -50
-KPX Abreve Uacute -50
-KPX Abreve Ucircumflex -50
-KPX Abreve Udieresis -50
-KPX Abreve Ugrave -50
-KPX Abreve Uhungarumlaut -50
-KPX Abreve Umacron -50
-KPX Abreve Uogonek -50
-KPX Abreve Uring -50
-KPX Abreve V -105
-KPX Abreve W -95
-KPX Abreve Y -55
-KPX Abreve Yacute -55
-KPX Abreve Ydieresis -55
-KPX Abreve quoteright -37
-KPX Abreve u -20
-KPX Abreve uacute -20
-KPX Abreve ucircumflex -20
-KPX Abreve udieresis -20
-KPX Abreve ugrave -20
-KPX Abreve uhungarumlaut -20
-KPX Abreve umacron -20
-KPX Abreve uogonek -20
-KPX Abreve uring -20
-KPX Abreve v -55
-KPX Abreve w -55
-KPX Abreve y -55
-KPX Abreve yacute -55
-KPX Abreve ydieresis -55
-KPX Acircumflex C -30
-KPX Acircumflex Cacute -30
-KPX Acircumflex Ccaron -30
-KPX Acircumflex Ccedilla -30
-KPX Acircumflex G -35
-KPX Acircumflex Gbreve -35
-KPX Acircumflex Gcommaaccent -35
-KPX Acircumflex O -40
-KPX Acircumflex Oacute -40
-KPX Acircumflex Ocircumflex -40
-KPX Acircumflex Odieresis -40
-KPX Acircumflex Ograve -40
-KPX Acircumflex Ohungarumlaut -40
-KPX Acircumflex Omacron -40
-KPX Acircumflex Oslash -40
-KPX Acircumflex Otilde -40
-KPX Acircumflex Q -40
-KPX Acircumflex T -37
-KPX Acircumflex Tcaron -37
-KPX Acircumflex Tcommaaccent -37
-KPX Acircumflex U -50
-KPX Acircumflex Uacute -50
-KPX Acircumflex Ucircumflex -50
-KPX Acircumflex Udieresis -50
-KPX Acircumflex Ugrave -50
-KPX Acircumflex Uhungarumlaut -50
-KPX Acircumflex Umacron -50
-KPX Acircumflex Uogonek -50
-KPX Acircumflex Uring -50
-KPX Acircumflex V -105
-KPX Acircumflex W -95
-KPX Acircumflex Y -55
-KPX Acircumflex Yacute -55
-KPX Acircumflex Ydieresis -55
-KPX Acircumflex quoteright -37
-KPX Acircumflex u -20
-KPX Acircumflex uacute -20
-KPX Acircumflex ucircumflex -20
-KPX Acircumflex udieresis -20
-KPX Acircumflex ugrave -20
-KPX Acircumflex uhungarumlaut -20
-KPX Acircumflex umacron -20
-KPX Acircumflex uogonek -20
-KPX Acircumflex uring -20
-KPX Acircumflex v -55
-KPX Acircumflex w -55
-KPX Acircumflex y -55
-KPX Acircumflex yacute -55
-KPX Acircumflex ydieresis -55
-KPX Adieresis C -30
-KPX Adieresis Cacute -30
-KPX Adieresis Ccaron -30
-KPX Adieresis Ccedilla -30
-KPX Adieresis G -35
-KPX Adieresis Gbreve -35
-KPX Adieresis Gcommaaccent -35
-KPX Adieresis O -40
-KPX Adieresis Oacute -40
-KPX Adieresis Ocircumflex -40
-KPX Adieresis Odieresis -40
-KPX Adieresis Ograve -40
-KPX Adieresis Ohungarumlaut -40
-KPX Adieresis Omacron -40
-KPX Adieresis Oslash -40
-KPX Adieresis Otilde -40
-KPX Adieresis Q -40
-KPX Adieresis T -37
-KPX Adieresis Tcaron -37
-KPX Adieresis Tcommaaccent -37
-KPX Adieresis U -50
-KPX Adieresis Uacute -50
-KPX Adieresis Ucircumflex -50
-KPX Adieresis Udieresis -50
-KPX Adieresis Ugrave -50
-KPX Adieresis Uhungarumlaut -50
-KPX Adieresis Umacron -50
-KPX Adieresis Uogonek -50
-KPX Adieresis Uring -50
-KPX Adieresis V -105
-KPX Adieresis W -95
-KPX Adieresis Y -55
-KPX Adieresis Yacute -55
-KPX Adieresis Ydieresis -55
-KPX Adieresis quoteright -37
-KPX Adieresis u -20
-KPX Adieresis uacute -20
-KPX Adieresis ucircumflex -20
-KPX Adieresis udieresis -20
-KPX Adieresis ugrave -20
-KPX Adieresis uhungarumlaut -20
-KPX Adieresis umacron -20
-KPX Adieresis uogonek -20
-KPX Adieresis uring -20
-KPX Adieresis v -55
-KPX Adieresis w -55
-KPX Adieresis y -55
-KPX Adieresis yacute -55
-KPX Adieresis ydieresis -55
-KPX Agrave C -30
-KPX Agrave Cacute -30
-KPX Agrave Ccaron -30
-KPX Agrave Ccedilla -30
-KPX Agrave G -35
-KPX Agrave Gbreve -35
-KPX Agrave Gcommaaccent -35
-KPX Agrave O -40
-KPX Agrave Oacute -40
-KPX Agrave Ocircumflex -40
-KPX Agrave Odieresis -40
-KPX Agrave Ograve -40
-KPX Agrave Ohungarumlaut -40
-KPX Agrave Omacron -40
-KPX Agrave Oslash -40
-KPX Agrave Otilde -40
-KPX Agrave Q -40
-KPX Agrave T -37
-KPX Agrave Tcaron -37
-KPX Agrave Tcommaaccent -37
-KPX Agrave U -50
-KPX Agrave Uacute -50
-KPX Agrave Ucircumflex -50
-KPX Agrave Udieresis -50
-KPX Agrave Ugrave -50
-KPX Agrave Uhungarumlaut -50
-KPX Agrave Umacron -50
-KPX Agrave Uogonek -50
-KPX Agrave Uring -50
-KPX Agrave V -105
-KPX Agrave W -95
-KPX Agrave Y -55
-KPX Agrave Yacute -55
-KPX Agrave Ydieresis -55
-KPX Agrave quoteright -37
-KPX Agrave u -20
-KPX Agrave uacute -20
-KPX Agrave ucircumflex -20
-KPX Agrave udieresis -20
-KPX Agrave ugrave -20
-KPX Agrave uhungarumlaut -20
-KPX Agrave umacron -20
-KPX Agrave uogonek -20
-KPX Agrave uring -20
-KPX Agrave v -55
-KPX Agrave w -55
-KPX Agrave y -55
-KPX Agrave yacute -55
-KPX Agrave ydieresis -55
-KPX Amacron C -30
-KPX Amacron Cacute -30
-KPX Amacron Ccaron -30
-KPX Amacron Ccedilla -30
-KPX Amacron G -35
-KPX Amacron Gbreve -35
-KPX Amacron Gcommaaccent -35
-KPX Amacron O -40
-KPX Amacron Oacute -40
-KPX Amacron Ocircumflex -40
-KPX Amacron Odieresis -40
-KPX Amacron Ograve -40
-KPX Amacron Ohungarumlaut -40
-KPX Amacron Omacron -40
-KPX Amacron Oslash -40
-KPX Amacron Otilde -40
-KPX Amacron Q -40
-KPX Amacron T -37
-KPX Amacron Tcaron -37
-KPX Amacron Tcommaaccent -37
-KPX Amacron U -50
-KPX Amacron Uacute -50
-KPX Amacron Ucircumflex -50
-KPX Amacron Udieresis -50
-KPX Amacron Ugrave -50
-KPX Amacron Uhungarumlaut -50
-KPX Amacron Umacron -50
-KPX Amacron Uogonek -50
-KPX Amacron Uring -50
-KPX Amacron V -105
-KPX Amacron W -95
-KPX Amacron Y -55
-KPX Amacron Yacute -55
-KPX Amacron Ydieresis -55
-KPX Amacron quoteright -37
-KPX Amacron u -20
-KPX Amacron uacute -20
-KPX Amacron ucircumflex -20
-KPX Amacron udieresis -20
-KPX Amacron ugrave -20
-KPX Amacron uhungarumlaut -20
-KPX Amacron umacron -20
-KPX Amacron uogonek -20
-KPX Amacron uring -20
-KPX Amacron v -55
-KPX Amacron w -55
-KPX Amacron y -55
-KPX Amacron yacute -55
-KPX Amacron ydieresis -55
-KPX Aogonek C -30
-KPX Aogonek Cacute -30
-KPX Aogonek Ccaron -30
-KPX Aogonek Ccedilla -30
-KPX Aogonek G -35
-KPX Aogonek Gbreve -35
-KPX Aogonek Gcommaaccent -35
-KPX Aogonek O -40
-KPX Aogonek Oacute -40
-KPX Aogonek Ocircumflex -40
-KPX Aogonek Odieresis -40
-KPX Aogonek Ograve -40
-KPX Aogonek Ohungarumlaut -40
-KPX Aogonek Omacron -40
-KPX Aogonek Oslash -40
-KPX Aogonek Otilde -40
-KPX Aogonek Q -40
-KPX Aogonek T -37
-KPX Aogonek Tcaron -37
-KPX Aogonek Tcommaaccent -37
-KPX Aogonek U -50
-KPX Aogonek Uacute -50
-KPX Aogonek Ucircumflex -50
-KPX Aogonek Udieresis -50
-KPX Aogonek Ugrave -50
-KPX Aogonek Uhungarumlaut -50
-KPX Aogonek Umacron -50
-KPX Aogonek Uogonek -50
-KPX Aogonek Uring -50
-KPX Aogonek V -105
-KPX Aogonek W -95
-KPX Aogonek Y -55
-KPX Aogonek Yacute -55
-KPX Aogonek Ydieresis -55
-KPX Aogonek quoteright -37
-KPX Aogonek u -20
-KPX Aogonek uacute -20
-KPX Aogonek ucircumflex -20
-KPX Aogonek udieresis -20
-KPX Aogonek ugrave -20
-KPX Aogonek uhungarumlaut -20
-KPX Aogonek umacron -20
-KPX Aogonek uogonek -20
-KPX Aogonek uring -20
-KPX Aogonek v -55
-KPX Aogonek w -55
-KPX Aogonek y -55
-KPX Aogonek yacute -55
-KPX Aogonek ydieresis -55
-KPX Aring C -30
-KPX Aring Cacute -30
-KPX Aring Ccaron -30
-KPX Aring Ccedilla -30
-KPX Aring G -35
-KPX Aring Gbreve -35
-KPX Aring Gcommaaccent -35
-KPX Aring O -40
-KPX Aring Oacute -40
-KPX Aring Ocircumflex -40
-KPX Aring Odieresis -40
-KPX Aring Ograve -40
-KPX Aring Ohungarumlaut -40
-KPX Aring Omacron -40
-KPX Aring Oslash -40
-KPX Aring Otilde -40
-KPX Aring Q -40
-KPX Aring T -37
-KPX Aring Tcaron -37
-KPX Aring Tcommaaccent -37
-KPX Aring U -50
-KPX Aring Uacute -50
-KPX Aring Ucircumflex -50
-KPX Aring Udieresis -50
-KPX Aring Ugrave -50
-KPX Aring Uhungarumlaut -50
-KPX Aring Umacron -50
-KPX Aring Uogonek -50
-KPX Aring Uring -50
-KPX Aring V -105
-KPX Aring W -95
-KPX Aring Y -55
-KPX Aring Yacute -55
-KPX Aring Ydieresis -55
-KPX Aring quoteright -37
-KPX Aring u -20
-KPX Aring uacute -20
-KPX Aring ucircumflex -20
-KPX Aring udieresis -20
-KPX Aring ugrave -20
-KPX Aring uhungarumlaut -20
-KPX Aring umacron -20
-KPX Aring uogonek -20
-KPX Aring uring -20
-KPX Aring v -55
-KPX Aring w -55
-KPX Aring y -55
-KPX Aring yacute -55
-KPX Aring ydieresis -55
-KPX Atilde C -30
-KPX Atilde Cacute -30
-KPX Atilde Ccaron -30
-KPX Atilde Ccedilla -30
-KPX Atilde G -35
-KPX Atilde Gbreve -35
-KPX Atilde Gcommaaccent -35
-KPX Atilde O -40
-KPX Atilde Oacute -40
-KPX Atilde Ocircumflex -40
-KPX Atilde Odieresis -40
-KPX Atilde Ograve -40
-KPX Atilde Ohungarumlaut -40
-KPX Atilde Omacron -40
-KPX Atilde Oslash -40
-KPX Atilde Otilde -40
-KPX Atilde Q -40
-KPX Atilde T -37
-KPX Atilde Tcaron -37
-KPX Atilde Tcommaaccent -37
-KPX Atilde U -50
-KPX Atilde Uacute -50
-KPX Atilde Ucircumflex -50
-KPX Atilde Udieresis -50
-KPX Atilde Ugrave -50
-KPX Atilde Uhungarumlaut -50
-KPX Atilde Umacron -50
-KPX Atilde Uogonek -50
-KPX Atilde Uring -50
-KPX Atilde V -105
-KPX Atilde W -95
-KPX Atilde Y -55
-KPX Atilde Yacute -55
-KPX Atilde Ydieresis -55
-KPX Atilde quoteright -37
-KPX Atilde u -20
-KPX Atilde uacute -20
-KPX Atilde ucircumflex -20
-KPX Atilde udieresis -20
-KPX Atilde ugrave -20
-KPX Atilde uhungarumlaut -20
-KPX Atilde umacron -20
-KPX Atilde uogonek -20
-KPX Atilde uring -20
-KPX Atilde v -55
-KPX Atilde w -55
-KPX Atilde y -55
-KPX Atilde yacute -55
-KPX Atilde ydieresis -55
-KPX B A -25
-KPX B Aacute -25
-KPX B Abreve -25
-KPX B Acircumflex -25
-KPX B Adieresis -25
-KPX B Agrave -25
-KPX B Amacron -25
-KPX B Aogonek -25
-KPX B Aring -25
-KPX B Atilde -25
-KPX B U -10
-KPX B Uacute -10
-KPX B Ucircumflex -10
-KPX B Udieresis -10
-KPX B Ugrave -10
-KPX B Uhungarumlaut -10
-KPX B Umacron -10
-KPX B Uogonek -10
-KPX B Uring -10
-KPX D A -35
-KPX D Aacute -35
-KPX D Abreve -35
-KPX D Acircumflex -35
-KPX D Adieresis -35
-KPX D Agrave -35
-KPX D Amacron -35
-KPX D Aogonek -35
-KPX D Aring -35
-KPX D Atilde -35
-KPX D V -40
-KPX D W -40
-KPX D Y -40
-KPX D Yacute -40
-KPX D Ydieresis -40
-KPX Dcaron A -35
-KPX Dcaron Aacute -35
-KPX Dcaron Abreve -35
-KPX Dcaron Acircumflex -35
-KPX Dcaron Adieresis -35
-KPX Dcaron Agrave -35
-KPX Dcaron Amacron -35
-KPX Dcaron Aogonek -35
-KPX Dcaron Aring -35
-KPX Dcaron Atilde -35
-KPX Dcaron V -40
-KPX Dcaron W -40
-KPX Dcaron Y -40
-KPX Dcaron Yacute -40
-KPX Dcaron Ydieresis -40
-KPX Dcroat A -35
-KPX Dcroat Aacute -35
-KPX Dcroat Abreve -35
-KPX Dcroat Acircumflex -35
-KPX Dcroat Adieresis -35
-KPX Dcroat Agrave -35
-KPX Dcroat Amacron -35
-KPX Dcroat Aogonek -35
-KPX Dcroat Aring -35
-KPX Dcroat Atilde -35
-KPX Dcroat V -40
-KPX Dcroat W -40
-KPX Dcroat Y -40
-KPX Dcroat Yacute -40
-KPX Dcroat Ydieresis -40
-KPX F A -115
-KPX F Aacute -115
-KPX F Abreve -115
-KPX F Acircumflex -115
-KPX F Adieresis -115
-KPX F Agrave -115
-KPX F Amacron -115
-KPX F Aogonek -115
-KPX F Aring -115
-KPX F Atilde -115
-KPX F a -75
-KPX F aacute -75
-KPX F abreve -75
-KPX F acircumflex -75
-KPX F adieresis -75
-KPX F agrave -75
-KPX F amacron -75
-KPX F aogonek -75
-KPX F aring -75
-KPX F atilde -75
-KPX F comma -135
-KPX F e -75
-KPX F eacute -75
-KPX F ecaron -75
-KPX F ecircumflex -75
-KPX F edieresis -75
-KPX F edotaccent -75
-KPX F egrave -75
-KPX F emacron -75
-KPX F eogonek -75
-KPX F i -45
-KPX F iacute -45
-KPX F icircumflex -45
-KPX F idieresis -45
-KPX F igrave -45
-KPX F imacron -45
-KPX F iogonek -45
-KPX F o -105
-KPX F oacute -105
-KPX F ocircumflex -105
-KPX F odieresis -105
-KPX F ograve -105
-KPX F ohungarumlaut -105
-KPX F omacron -105
-KPX F oslash -105
-KPX F otilde -105
-KPX F period -135
-KPX F r -55
-KPX F racute -55
-KPX F rcaron -55
-KPX F rcommaaccent -55
-KPX J A -40
-KPX J Aacute -40
-KPX J Abreve -40
-KPX J Acircumflex -40
-KPX J Adieresis -40
-KPX J Agrave -40
-KPX J Amacron -40
-KPX J Aogonek -40
-KPX J Aring -40
-KPX J Atilde -40
-KPX J a -35
-KPX J aacute -35
-KPX J abreve -35
-KPX J acircumflex -35
-KPX J adieresis -35
-KPX J agrave -35
-KPX J amacron -35
-KPX J aogonek -35
-KPX J aring -35
-KPX J atilde -35
-KPX J comma -25
-KPX J e -25
-KPX J eacute -25
-KPX J ecaron -25
-KPX J ecircumflex -25
-KPX J edieresis -25
-KPX J edotaccent -25
-KPX J egrave -25
-KPX J emacron -25
-KPX J eogonek -25
-KPX J o -25
-KPX J oacute -25
-KPX J ocircumflex -25
-KPX J odieresis -25
-KPX J ograve -25
-KPX J ohungarumlaut -25
-KPX J omacron -25
-KPX J oslash -25
-KPX J otilde -25
-KPX J period -25
-KPX J u -35
-KPX J uacute -35
-KPX J ucircumflex -35
-KPX J udieresis -35
-KPX J ugrave -35
-KPX J uhungarumlaut -35
-KPX J umacron -35
-KPX J uogonek -35
-KPX J uring -35
-KPX K O -50
-KPX K Oacute -50
-KPX K Ocircumflex -50
-KPX K Odieresis -50
-KPX K Ograve -50
-KPX K Ohungarumlaut -50
-KPX K Omacron -50
-KPX K Oslash -50
-KPX K Otilde -50
-KPX K e -35
-KPX K eacute -35
-KPX K ecaron -35
-KPX K ecircumflex -35
-KPX K edieresis -35
-KPX K edotaccent -35
-KPX K egrave -35
-KPX K emacron -35
-KPX K eogonek -35
-KPX K o -40
-KPX K oacute -40
-KPX K ocircumflex -40
-KPX K odieresis -40
-KPX K ograve -40
-KPX K ohungarumlaut -40
-KPX K omacron -40
-KPX K oslash -40
-KPX K otilde -40
-KPX K u -40
-KPX K uacute -40
-KPX K ucircumflex -40
-KPX K udieresis -40
-KPX K ugrave -40
-KPX K uhungarumlaut -40
-KPX K umacron -40
-KPX K uogonek -40
-KPX K uring -40
-KPX K y -40
-KPX K yacute -40
-KPX K ydieresis -40
-KPX Kcommaaccent O -50
-KPX Kcommaaccent Oacute -50
-KPX Kcommaaccent Ocircumflex -50
-KPX Kcommaaccent Odieresis -50
-KPX Kcommaaccent Ograve -50
-KPX Kcommaaccent Ohungarumlaut -50
-KPX Kcommaaccent Omacron -50
-KPX Kcommaaccent Oslash -50
-KPX Kcommaaccent Otilde -50
-KPX Kcommaaccent e -35
-KPX Kcommaaccent eacute -35
-KPX Kcommaaccent ecaron -35
-KPX Kcommaaccent ecircumflex -35
-KPX Kcommaaccent edieresis -35
-KPX Kcommaaccent edotaccent -35
-KPX Kcommaaccent egrave -35
-KPX Kcommaaccent emacron -35
-KPX Kcommaaccent eogonek -35
-KPX Kcommaaccent o -40
-KPX Kcommaaccent oacute -40
-KPX Kcommaaccent ocircumflex -40
-KPX Kcommaaccent odieresis -40
-KPX Kcommaaccent ograve -40
-KPX Kcommaaccent ohungarumlaut -40
-KPX Kcommaaccent omacron -40
-KPX Kcommaaccent oslash -40
-KPX Kcommaaccent otilde -40
-KPX Kcommaaccent u -40
-KPX Kcommaaccent uacute -40
-KPX Kcommaaccent ucircumflex -40
-KPX Kcommaaccent udieresis -40
-KPX Kcommaaccent ugrave -40
-KPX Kcommaaccent uhungarumlaut -40
-KPX Kcommaaccent umacron -40
-KPX Kcommaaccent uogonek -40
-KPX Kcommaaccent uring -40
-KPX Kcommaaccent y -40
-KPX Kcommaaccent yacute -40
-KPX Kcommaaccent ydieresis -40
-KPX L T -20
-KPX L Tcaron -20
-KPX L Tcommaaccent -20
-KPX L V -55
-KPX L W -55
-KPX L Y -20
-KPX L Yacute -20
-KPX L Ydieresis -20
-KPX L quoteright -37
-KPX L y -30
-KPX L yacute -30
-KPX L ydieresis -30
-KPX Lacute T -20
-KPX Lacute Tcaron -20
-KPX Lacute Tcommaaccent -20
-KPX Lacute V -55
-KPX Lacute W -55
-KPX Lacute Y -20
-KPX Lacute Yacute -20
-KPX Lacute Ydieresis -20
-KPX Lacute quoteright -37
-KPX Lacute y -30
-KPX Lacute yacute -30
-KPX Lacute ydieresis -30
-KPX Lcommaaccent T -20
-KPX Lcommaaccent Tcaron -20
-KPX Lcommaaccent Tcommaaccent -20
-KPX Lcommaaccent V -55
-KPX Lcommaaccent W -55
-KPX Lcommaaccent Y -20
-KPX Lcommaaccent Yacute -20
-KPX Lcommaaccent Ydieresis -20
-KPX Lcommaaccent quoteright -37
-KPX Lcommaaccent y -30
-KPX Lcommaaccent yacute -30
-KPX Lcommaaccent ydieresis -30
-KPX Lslash T -20
-KPX Lslash Tcaron -20
-KPX Lslash Tcommaaccent -20
-KPX Lslash V -55
-KPX Lslash W -55
-KPX Lslash Y -20
-KPX Lslash Yacute -20
-KPX Lslash Ydieresis -20
-KPX Lslash quoteright -37
-KPX Lslash y -30
-KPX Lslash yacute -30
-KPX Lslash ydieresis -30
-KPX N A -27
-KPX N Aacute -27
-KPX N Abreve -27
-KPX N Acircumflex -27
-KPX N Adieresis -27
-KPX N Agrave -27
-KPX N Amacron -27
-KPX N Aogonek -27
-KPX N Aring -27
-KPX N Atilde -27
-KPX Nacute A -27
-KPX Nacute Aacute -27
-KPX Nacute Abreve -27
-KPX Nacute Acircumflex -27
-KPX Nacute Adieresis -27
-KPX Nacute Agrave -27
-KPX Nacute Amacron -27
-KPX Nacute Aogonek -27
-KPX Nacute Aring -27
-KPX Nacute Atilde -27
-KPX Ncaron A -27
-KPX Ncaron Aacute -27
-KPX Ncaron Abreve -27
-KPX Ncaron Acircumflex -27
-KPX Ncaron Adieresis -27
-KPX Ncaron Agrave -27
-KPX Ncaron Amacron -27
-KPX Ncaron Aogonek -27
-KPX Ncaron Aring -27
-KPX Ncaron Atilde -27
-KPX Ncommaaccent A -27
-KPX Ncommaaccent Aacute -27
-KPX Ncommaaccent Abreve -27
-KPX Ncommaaccent Acircumflex -27
-KPX Ncommaaccent Adieresis -27
-KPX Ncommaaccent Agrave -27
-KPX Ncommaaccent Amacron -27
-KPX Ncommaaccent Aogonek -27
-KPX Ncommaaccent Aring -27
-KPX Ncommaaccent Atilde -27
-KPX Ntilde A -27
-KPX Ntilde Aacute -27
-KPX Ntilde Abreve -27
-KPX Ntilde Acircumflex -27
-KPX Ntilde Adieresis -27
-KPX Ntilde Agrave -27
-KPX Ntilde Amacron -27
-KPX Ntilde Aogonek -27
-KPX Ntilde Aring -27
-KPX Ntilde Atilde -27
-KPX O A -55
-KPX O Aacute -55
-KPX O Abreve -55
-KPX O Acircumflex -55
-KPX O Adieresis -55
-KPX O Agrave -55
-KPX O Amacron -55
-KPX O Aogonek -55
-KPX O Aring -55
-KPX O Atilde -55
-KPX O T -40
-KPX O Tcaron -40
-KPX O Tcommaaccent -40
-KPX O V -50
-KPX O W -50
-KPX O X -40
-KPX O Y -50
-KPX O Yacute -50
-KPX O Ydieresis -50
-KPX Oacute A -55
-KPX Oacute Aacute -55
-KPX Oacute Abreve -55
-KPX Oacute Acircumflex -55
-KPX Oacute Adieresis -55
-KPX Oacute Agrave -55
-KPX Oacute Amacron -55
-KPX Oacute Aogonek -55
-KPX Oacute Aring -55
-KPX Oacute Atilde -55
-KPX Oacute T -40
-KPX Oacute Tcaron -40
-KPX Oacute Tcommaaccent -40
-KPX Oacute V -50
-KPX Oacute W -50
-KPX Oacute X -40
-KPX Oacute Y -50
-KPX Oacute Yacute -50
-KPX Oacute Ydieresis -50
-KPX Ocircumflex A -55
-KPX Ocircumflex Aacute -55
-KPX Ocircumflex Abreve -55
-KPX Ocircumflex Acircumflex -55
-KPX Ocircumflex Adieresis -55
-KPX Ocircumflex Agrave -55
-KPX Ocircumflex Amacron -55
-KPX Ocircumflex Aogonek -55
-KPX Ocircumflex Aring -55
-KPX Ocircumflex Atilde -55
-KPX Ocircumflex T -40
-KPX Ocircumflex Tcaron -40
-KPX Ocircumflex Tcommaaccent -40
-KPX Ocircumflex V -50
-KPX Ocircumflex W -50
-KPX Ocircumflex X -40
-KPX Ocircumflex Y -50
-KPX Ocircumflex Yacute -50
-KPX Ocircumflex Ydieresis -50
-KPX Odieresis A -55
-KPX Odieresis Aacute -55
-KPX Odieresis Abreve -55
-KPX Odieresis Acircumflex -55
-KPX Odieresis Adieresis -55
-KPX Odieresis Agrave -55
-KPX Odieresis Amacron -55
-KPX Odieresis Aogonek -55
-KPX Odieresis Aring -55
-KPX Odieresis Atilde -55
-KPX Odieresis T -40
-KPX Odieresis Tcaron -40
-KPX Odieresis Tcommaaccent -40
-KPX Odieresis V -50
-KPX Odieresis W -50
-KPX Odieresis X -40
-KPX Odieresis Y -50
-KPX Odieresis Yacute -50
-KPX Odieresis Ydieresis -50
-KPX Ograve A -55
-KPX Ograve Aacute -55
-KPX Ograve Abreve -55
-KPX Ograve Acircumflex -55
-KPX Ograve Adieresis -55
-KPX Ograve Agrave -55
-KPX Ograve Amacron -55
-KPX Ograve Aogonek -55
-KPX Ograve Aring -55
-KPX Ograve Atilde -55
-KPX Ograve T -40
-KPX Ograve Tcaron -40
-KPX Ograve Tcommaaccent -40
-KPX Ograve V -50
-KPX Ograve W -50
-KPX Ograve X -40
-KPX Ograve Y -50
-KPX Ograve Yacute -50
-KPX Ograve Ydieresis -50
-KPX Ohungarumlaut A -55
-KPX Ohungarumlaut Aacute -55
-KPX Ohungarumlaut Abreve -55
-KPX Ohungarumlaut Acircumflex -55
-KPX Ohungarumlaut Adieresis -55
-KPX Ohungarumlaut Agrave -55
-KPX Ohungarumlaut Amacron -55
-KPX Ohungarumlaut Aogonek -55
-KPX Ohungarumlaut Aring -55
-KPX Ohungarumlaut Atilde -55
-KPX Ohungarumlaut T -40
-KPX Ohungarumlaut Tcaron -40
-KPX Ohungarumlaut Tcommaaccent -40
-KPX Ohungarumlaut V -50
-KPX Ohungarumlaut W -50
-KPX Ohungarumlaut X -40
-KPX Ohungarumlaut Y -50
-KPX Ohungarumlaut Yacute -50
-KPX Ohungarumlaut Ydieresis -50
-KPX Omacron A -55
-KPX Omacron Aacute -55
-KPX Omacron Abreve -55
-KPX Omacron Acircumflex -55
-KPX Omacron Adieresis -55
-KPX Omacron Agrave -55
-KPX Omacron Amacron -55
-KPX Omacron Aogonek -55
-KPX Omacron Aring -55
-KPX Omacron Atilde -55
-KPX Omacron T -40
-KPX Omacron Tcaron -40
-KPX Omacron Tcommaaccent -40
-KPX Omacron V -50
-KPX Omacron W -50
-KPX Omacron X -40
-KPX Omacron Y -50
-KPX Omacron Yacute -50
-KPX Omacron Ydieresis -50
-KPX Oslash A -55
-KPX Oslash Aacute -55
-KPX Oslash Abreve -55
-KPX Oslash Acircumflex -55
-KPX Oslash Adieresis -55
-KPX Oslash Agrave -55
-KPX Oslash Amacron -55
-KPX Oslash Aogonek -55
-KPX Oslash Aring -55
-KPX Oslash Atilde -55
-KPX Oslash T -40
-KPX Oslash Tcaron -40
-KPX Oslash Tcommaaccent -40
-KPX Oslash V -50
-KPX Oslash W -50
-KPX Oslash X -40
-KPX Oslash Y -50
-KPX Oslash Yacute -50
-KPX Oslash Ydieresis -50
-KPX Otilde A -55
-KPX Otilde Aacute -55
-KPX Otilde Abreve -55
-KPX Otilde Acircumflex -55
-KPX Otilde Adieresis -55
-KPX Otilde Agrave -55
-KPX Otilde Amacron -55
-KPX Otilde Aogonek -55
-KPX Otilde Aring -55
-KPX Otilde Atilde -55
-KPX Otilde T -40
-KPX Otilde Tcaron -40
-KPX Otilde Tcommaaccent -40
-KPX Otilde V -50
-KPX Otilde W -50
-KPX Otilde X -40
-KPX Otilde Y -50
-KPX Otilde Yacute -50
-KPX Otilde Ydieresis -50
-KPX P A -90
-KPX P Aacute -90
-KPX P Abreve -90
-KPX P Acircumflex -90
-KPX P Adieresis -90
-KPX P Agrave -90
-KPX P Amacron -90
-KPX P Aogonek -90
-KPX P Aring -90
-KPX P Atilde -90
-KPX P a -80
-KPX P aacute -80
-KPX P abreve -80
-KPX P acircumflex -80
-KPX P adieresis -80
-KPX P agrave -80
-KPX P amacron -80
-KPX P aogonek -80
-KPX P aring -80
-KPX P atilde -80
-KPX P comma -135
-KPX P e -80
-KPX P eacute -80
-KPX P ecaron -80
-KPX P ecircumflex -80
-KPX P edieresis -80
-KPX P edotaccent -80
-KPX P egrave -80
-KPX P emacron -80
-KPX P eogonek -80
-KPX P o -80
-KPX P oacute -80
-KPX P ocircumflex -80
-KPX P odieresis -80
-KPX P ograve -80
-KPX P ohungarumlaut -80
-KPX P omacron -80
-KPX P oslash -80
-KPX P otilde -80
-KPX P period -135
-KPX Q U -10
-KPX Q Uacute -10
-KPX Q Ucircumflex -10
-KPX Q Udieresis -10
-KPX Q Ugrave -10
-KPX Q Uhungarumlaut -10
-KPX Q Umacron -10
-KPX Q Uogonek -10
-KPX Q Uring -10
-KPX R O -40
-KPX R Oacute -40
-KPX R Ocircumflex -40
-KPX R Odieresis -40
-KPX R Ograve -40
-KPX R Ohungarumlaut -40
-KPX R Omacron -40
-KPX R Oslash -40
-KPX R Otilde -40
-KPX R U -40
-KPX R Uacute -40
-KPX R Ucircumflex -40
-KPX R Udieresis -40
-KPX R Ugrave -40
-KPX R Uhungarumlaut -40
-KPX R Umacron -40
-KPX R Uogonek -40
-KPX R Uring -40
-KPX R V -18
-KPX R W -18
-KPX R Y -18
-KPX R Yacute -18
-KPX R Ydieresis -18
-KPX Racute O -40
-KPX Racute Oacute -40
-KPX Racute Ocircumflex -40
-KPX Racute Odieresis -40
-KPX Racute Ograve -40
-KPX Racute Ohungarumlaut -40
-KPX Racute Omacron -40
-KPX Racute Oslash -40
-KPX Racute Otilde -40
-KPX Racute U -40
-KPX Racute Uacute -40
-KPX Racute Ucircumflex -40
-KPX Racute Udieresis -40
-KPX Racute Ugrave -40
-KPX Racute Uhungarumlaut -40
-KPX Racute Umacron -40
-KPX Racute Uogonek -40
-KPX Racute Uring -40
-KPX Racute V -18
-KPX Racute W -18
-KPX Racute Y -18
-KPX Racute Yacute -18
-KPX Racute Ydieresis -18
-KPX Rcaron O -40
-KPX Rcaron Oacute -40
-KPX Rcaron Ocircumflex -40
-KPX Rcaron Odieresis -40
-KPX Rcaron Ograve -40
-KPX Rcaron Ohungarumlaut -40
-KPX Rcaron Omacron -40
-KPX Rcaron Oslash -40
-KPX Rcaron Otilde -40
-KPX Rcaron U -40
-KPX Rcaron Uacute -40
-KPX Rcaron Ucircumflex -40
-KPX Rcaron Udieresis -40
-KPX Rcaron Ugrave -40
-KPX Rcaron Uhungarumlaut -40
-KPX Rcaron Umacron -40
-KPX Rcaron Uogonek -40
-KPX Rcaron Uring -40
-KPX Rcaron V -18
-KPX Rcaron W -18
-KPX Rcaron Y -18
-KPX Rcaron Yacute -18
-KPX Rcaron Ydieresis -18
-KPX Rcommaaccent O -40
-KPX Rcommaaccent Oacute -40
-KPX Rcommaaccent Ocircumflex -40
-KPX Rcommaaccent Odieresis -40
-KPX Rcommaaccent Ograve -40
-KPX Rcommaaccent Ohungarumlaut -40
-KPX Rcommaaccent Omacron -40
-KPX Rcommaaccent Oslash -40
-KPX Rcommaaccent Otilde -40
-KPX Rcommaaccent U -40
-KPX Rcommaaccent Uacute -40
-KPX Rcommaaccent Ucircumflex -40
-KPX Rcommaaccent Udieresis -40
-KPX Rcommaaccent Ugrave -40
-KPX Rcommaaccent Uhungarumlaut -40
-KPX Rcommaaccent Umacron -40
-KPX Rcommaaccent Uogonek -40
-KPX Rcommaaccent Uring -40
-KPX Rcommaaccent V -18
-KPX Rcommaaccent W -18
-KPX Rcommaaccent Y -18
-KPX Rcommaaccent Yacute -18
-KPX Rcommaaccent Ydieresis -18
-KPX T A -50
-KPX T Aacute -50
-KPX T Abreve -50
-KPX T Acircumflex -50
-KPX T Adieresis -50
-KPX T Agrave -50
-KPX T Amacron -50
-KPX T Aogonek -50
-KPX T Aring -50
-KPX T Atilde -50
-KPX T O -18
-KPX T Oacute -18
-KPX T Ocircumflex -18
-KPX T Odieresis -18
-KPX T Ograve -18
-KPX T Ohungarumlaut -18
-KPX T Omacron -18
-KPX T Oslash -18
-KPX T Otilde -18
-KPX T a -92
-KPX T aacute -92
-KPX T abreve -92
-KPX T acircumflex -92
-KPX T adieresis -92
-KPX T agrave -92
-KPX T amacron -92
-KPX T aogonek -92
-KPX T aring -92
-KPX T atilde -92
-KPX T colon -55
-KPX T comma -74
-KPX T e -92
-KPX T eacute -92
-KPX T ecaron -92
-KPX T ecircumflex -52
-KPX T edieresis -52
-KPX T edotaccent -92
-KPX T egrave -52
-KPX T emacron -52
-KPX T eogonek -92
-KPX T hyphen -74
-KPX T i -55
-KPX T iacute -55
-KPX T iogonek -55
-KPX T o -92
-KPX T oacute -92
-KPX T ocircumflex -92
-KPX T odieresis -92
-KPX T ograve -92
-KPX T ohungarumlaut -92
-KPX T omacron -92
-KPX T oslash -92
-KPX T otilde -92
-KPX T period -74
-KPX T r -55
-KPX T racute -55
-KPX T rcaron -55
-KPX T rcommaaccent -55
-KPX T semicolon -65
-KPX T u -55
-KPX T uacute -55
-KPX T ucircumflex -55
-KPX T udieresis -55
-KPX T ugrave -55
-KPX T uhungarumlaut -55
-KPX T umacron -55
-KPX T uogonek -55
-KPX T uring -55
-KPX T w -74
-KPX T y -74
-KPX T yacute -74
-KPX T ydieresis -34
-KPX Tcaron A -50
-KPX Tcaron Aacute -50
-KPX Tcaron Abreve -50
-KPX Tcaron Acircumflex -50
-KPX Tcaron Adieresis -50
-KPX Tcaron Agrave -50
-KPX Tcaron Amacron -50
-KPX Tcaron Aogonek -50
-KPX Tcaron Aring -50
-KPX Tcaron Atilde -50
-KPX Tcaron O -18
-KPX Tcaron Oacute -18
-KPX Tcaron Ocircumflex -18
-KPX Tcaron Odieresis -18
-KPX Tcaron Ograve -18
-KPX Tcaron Ohungarumlaut -18
-KPX Tcaron Omacron -18
-KPX Tcaron Oslash -18
-KPX Tcaron Otilde -18
-KPX Tcaron a -92
-KPX Tcaron aacute -92
-KPX Tcaron abreve -92
-KPX Tcaron acircumflex -92
-KPX Tcaron adieresis -92
-KPX Tcaron agrave -92
-KPX Tcaron amacron -92
-KPX Tcaron aogonek -92
-KPX Tcaron aring -92
-KPX Tcaron atilde -92
-KPX Tcaron colon -55
-KPX Tcaron comma -74
-KPX Tcaron e -92
-KPX Tcaron eacute -92
-KPX Tcaron ecaron -92
-KPX Tcaron ecircumflex -52
-KPX Tcaron edieresis -52
-KPX Tcaron edotaccent -92
-KPX Tcaron egrave -52
-KPX Tcaron emacron -52
-KPX Tcaron eogonek -92
-KPX Tcaron hyphen -74
-KPX Tcaron i -55
-KPX Tcaron iacute -55
-KPX Tcaron iogonek -55
-KPX Tcaron o -92
-KPX Tcaron oacute -92
-KPX Tcaron ocircumflex -92
-KPX Tcaron odieresis -92
-KPX Tcaron ograve -92
-KPX Tcaron ohungarumlaut -92
-KPX Tcaron omacron -92
-KPX Tcaron oslash -92
-KPX Tcaron otilde -92
-KPX Tcaron period -74
-KPX Tcaron r -55
-KPX Tcaron racute -55
-KPX Tcaron rcaron -55
-KPX Tcaron rcommaaccent -55
-KPX Tcaron semicolon -65
-KPX Tcaron u -55
-KPX Tcaron uacute -55
-KPX Tcaron ucircumflex -55
-KPX Tcaron udieresis -55
-KPX Tcaron ugrave -55
-KPX Tcaron uhungarumlaut -55
-KPX Tcaron umacron -55
-KPX Tcaron uogonek -55
-KPX Tcaron uring -55
-KPX Tcaron w -74
-KPX Tcaron y -74
-KPX Tcaron yacute -74
-KPX Tcaron ydieresis -34
-KPX Tcommaaccent A -50
-KPX Tcommaaccent Aacute -50
-KPX Tcommaaccent Abreve -50
-KPX Tcommaaccent Acircumflex -50
-KPX Tcommaaccent Adieresis -50
-KPX Tcommaaccent Agrave -50
-KPX Tcommaaccent Amacron -50
-KPX Tcommaaccent Aogonek -50
-KPX Tcommaaccent Aring -50
-KPX Tcommaaccent Atilde -50
-KPX Tcommaaccent O -18
-KPX Tcommaaccent Oacute -18
-KPX Tcommaaccent Ocircumflex -18
-KPX Tcommaaccent Odieresis -18
-KPX Tcommaaccent Ograve -18
-KPX Tcommaaccent Ohungarumlaut -18
-KPX Tcommaaccent Omacron -18
-KPX Tcommaaccent Oslash -18
-KPX Tcommaaccent Otilde -18
-KPX Tcommaaccent a -92
-KPX Tcommaaccent aacute -92
-KPX Tcommaaccent abreve -92
-KPX Tcommaaccent acircumflex -92
-KPX Tcommaaccent adieresis -92
-KPX Tcommaaccent agrave -92
-KPX Tcommaaccent amacron -92
-KPX Tcommaaccent aogonek -92
-KPX Tcommaaccent aring -92
-KPX Tcommaaccent atilde -92
-KPX Tcommaaccent colon -55
-KPX Tcommaaccent comma -74
-KPX Tcommaaccent e -92
-KPX Tcommaaccent eacute -92
-KPX Tcommaaccent ecaron -92
-KPX Tcommaaccent ecircumflex -52
-KPX Tcommaaccent edieresis -52
-KPX Tcommaaccent edotaccent -92
-KPX Tcommaaccent egrave -52
-KPX Tcommaaccent emacron -52
-KPX Tcommaaccent eogonek -92
-KPX Tcommaaccent hyphen -74
-KPX Tcommaaccent i -55
-KPX Tcommaaccent iacute -55
-KPX Tcommaaccent iogonek -55
-KPX Tcommaaccent o -92
-KPX Tcommaaccent oacute -92
-KPX Tcommaaccent ocircumflex -92
-KPX Tcommaaccent odieresis -92
-KPX Tcommaaccent ograve -92
-KPX Tcommaaccent ohungarumlaut -92
-KPX Tcommaaccent omacron -92
-KPX Tcommaaccent oslash -92
-KPX Tcommaaccent otilde -92
-KPX Tcommaaccent period -74
-KPX Tcommaaccent r -55
-KPX Tcommaaccent racute -55
-KPX Tcommaaccent rcaron -55
-KPX Tcommaaccent rcommaaccent -55
-KPX Tcommaaccent semicolon -65
-KPX Tcommaaccent u -55
-KPX Tcommaaccent uacute -55
-KPX Tcommaaccent ucircumflex -55
-KPX Tcommaaccent udieresis -55
-KPX Tcommaaccent ugrave -55
-KPX Tcommaaccent uhungarumlaut -55
-KPX Tcommaaccent umacron -55
-KPX Tcommaaccent uogonek -55
-KPX Tcommaaccent uring -55
-KPX Tcommaaccent w -74
-KPX Tcommaaccent y -74
-KPX Tcommaaccent yacute -74
-KPX Tcommaaccent ydieresis -34
-KPX U A -40
-KPX U Aacute -40
-KPX U Abreve -40
-KPX U Acircumflex -40
-KPX U Adieresis -40
-KPX U Agrave -40
-KPX U Amacron -40
-KPX U Aogonek -40
-KPX U Aring -40
-KPX U Atilde -40
-KPX U comma -25
-KPX U period -25
-KPX Uacute A -40
-KPX Uacute Aacute -40
-KPX Uacute Abreve -40
-KPX Uacute Acircumflex -40
-KPX Uacute Adieresis -40
-KPX Uacute Agrave -40
-KPX Uacute Amacron -40
-KPX Uacute Aogonek -40
-KPX Uacute Aring -40
-KPX Uacute Atilde -40
-KPX Uacute comma -25
-KPX Uacute period -25
-KPX Ucircumflex A -40
-KPX Ucircumflex Aacute -40
-KPX Ucircumflex Abreve -40
-KPX Ucircumflex Acircumflex -40
-KPX Ucircumflex Adieresis -40
-KPX Ucircumflex Agrave -40
-KPX Ucircumflex Amacron -40
-KPX Ucircumflex Aogonek -40
-KPX Ucircumflex Aring -40
-KPX Ucircumflex Atilde -40
-KPX Ucircumflex comma -25
-KPX Ucircumflex period -25
-KPX Udieresis A -40
-KPX Udieresis Aacute -40
-KPX Udieresis Abreve -40
-KPX Udieresis Acircumflex -40
-KPX Udieresis Adieresis -40
-KPX Udieresis Agrave -40
-KPX Udieresis Amacron -40
-KPX Udieresis Aogonek -40
-KPX Udieresis Aring -40
-KPX Udieresis Atilde -40
-KPX Udieresis comma -25
-KPX Udieresis period -25
-KPX Ugrave A -40
-KPX Ugrave Aacute -40
-KPX Ugrave Abreve -40
-KPX Ugrave Acircumflex -40
-KPX Ugrave Adieresis -40
-KPX Ugrave Agrave -40
-KPX Ugrave Amacron -40
-KPX Ugrave Aogonek -40
-KPX Ugrave Aring -40
-KPX Ugrave Atilde -40
-KPX Ugrave comma -25
-KPX Ugrave period -25
-KPX Uhungarumlaut A -40
-KPX Uhungarumlaut Aacute -40
-KPX Uhungarumlaut Abreve -40
-KPX Uhungarumlaut Acircumflex -40
-KPX Uhungarumlaut Adieresis -40
-KPX Uhungarumlaut Agrave -40
-KPX Uhungarumlaut Amacron -40
-KPX Uhungarumlaut Aogonek -40
-KPX Uhungarumlaut Aring -40
-KPX Uhungarumlaut Atilde -40
-KPX Uhungarumlaut comma -25
-KPX Uhungarumlaut period -25
-KPX Umacron A -40
-KPX Umacron Aacute -40
-KPX Umacron Abreve -40
-KPX Umacron Acircumflex -40
-KPX Umacron Adieresis -40
-KPX Umacron Agrave -40
-KPX Umacron Amacron -40
-KPX Umacron Aogonek -40
-KPX Umacron Aring -40
-KPX Umacron Atilde -40
-KPX Umacron comma -25
-KPX Umacron period -25
-KPX Uogonek A -40
-KPX Uogonek Aacute -40
-KPX Uogonek Abreve -40
-KPX Uogonek Acircumflex -40
-KPX Uogonek Adieresis -40
-KPX Uogonek Agrave -40
-KPX Uogonek Amacron -40
-KPX Uogonek Aogonek -40
-KPX Uogonek Aring -40
-KPX Uogonek Atilde -40
-KPX Uogonek comma -25
-KPX Uogonek period -25
-KPX Uring A -40
-KPX Uring Aacute -40
-KPX Uring Abreve -40
-KPX Uring Acircumflex -40
-KPX Uring Adieresis -40
-KPX Uring Agrave -40
-KPX Uring Amacron -40
-KPX Uring Aogonek -40
-KPX Uring Aring -40
-KPX Uring Atilde -40
-KPX Uring comma -25
-KPX Uring period -25
-KPX V A -60
-KPX V Aacute -60
-KPX V Abreve -60
-KPX V Acircumflex -60
-KPX V Adieresis -60
-KPX V Agrave -60
-KPX V Amacron -60
-KPX V Aogonek -60
-KPX V Aring -60
-KPX V Atilde -60
-KPX V O -30
-KPX V Oacute -30
-KPX V Ocircumflex -30
-KPX V Odieresis -30
-KPX V Ograve -30
-KPX V Ohungarumlaut -30
-KPX V Omacron -30
-KPX V Oslash -30
-KPX V Otilde -30
-KPX V a -111
-KPX V aacute -111
-KPX V abreve -111
-KPX V acircumflex -111
-KPX V adieresis -111
-KPX V agrave -111
-KPX V amacron -111
-KPX V aogonek -111
-KPX V aring -111
-KPX V atilde -111
-KPX V colon -65
-KPX V comma -129
-KPX V e -111
-KPX V eacute -111
-KPX V ecaron -111
-KPX V ecircumflex -111
-KPX V edieresis -71
-KPX V edotaccent -111
-KPX V egrave -71
-KPX V emacron -71
-KPX V eogonek -111
-KPX V hyphen -55
-KPX V i -74
-KPX V iacute -74
-KPX V icircumflex -34
-KPX V idieresis -34
-KPX V igrave -34
-KPX V imacron -34
-KPX V iogonek -74
-KPX V o -111
-KPX V oacute -111
-KPX V ocircumflex -111
-KPX V odieresis -111
-KPX V ograve -111
-KPX V ohungarumlaut -111
-KPX V omacron -111
-KPX V oslash -111
-KPX V otilde -111
-KPX V period -129
-KPX V semicolon -74
-KPX V u -74
-KPX V uacute -74
-KPX V ucircumflex -74
-KPX V udieresis -74
-KPX V ugrave -74
-KPX V uhungarumlaut -74
-KPX V umacron -74
-KPX V uogonek -74
-KPX V uring -74
-KPX W A -60
-KPX W Aacute -60
-KPX W Abreve -60
-KPX W Acircumflex -60
-KPX W Adieresis -60
-KPX W Agrave -60
-KPX W Amacron -60
-KPX W Aogonek -60
-KPX W Aring -60
-KPX W Atilde -60
-KPX W O -25
-KPX W Oacute -25
-KPX W Ocircumflex -25
-KPX W Odieresis -25
-KPX W Ograve -25
-KPX W Ohungarumlaut -25
-KPX W Omacron -25
-KPX W Oslash -25
-KPX W Otilde -25
-KPX W a -92
-KPX W aacute -92
-KPX W abreve -92
-KPX W acircumflex -92
-KPX W adieresis -92
-KPX W agrave -92
-KPX W amacron -92
-KPX W aogonek -92
-KPX W aring -92
-KPX W atilde -92
-KPX W colon -65
-KPX W comma -92
-KPX W e -92
-KPX W eacute -92
-KPX W ecaron -92
-KPX W ecircumflex -92
-KPX W edieresis -52
-KPX W edotaccent -92
-KPX W egrave -52
-KPX W emacron -52
-KPX W eogonek -92
-KPX W hyphen -37
-KPX W i -55
-KPX W iacute -55
-KPX W iogonek -55
-KPX W o -92
-KPX W oacute -92
-KPX W ocircumflex -92
-KPX W odieresis -92
-KPX W ograve -92
-KPX W ohungarumlaut -92
-KPX W omacron -92
-KPX W oslash -92
-KPX W otilde -92
-KPX W period -92
-KPX W semicolon -65
-KPX W u -55
-KPX W uacute -55
-KPX W ucircumflex -55
-KPX W udieresis -55
-KPX W ugrave -55
-KPX W uhungarumlaut -55
-KPX W umacron -55
-KPX W uogonek -55
-KPX W uring -55
-KPX W y -70
-KPX W yacute -70
-KPX W ydieresis -70
-KPX Y A -50
-KPX Y Aacute -50
-KPX Y Abreve -50
-KPX Y Acircumflex -50
-KPX Y Adieresis -50
-KPX Y Agrave -50
-KPX Y Amacron -50
-KPX Y Aogonek -50
-KPX Y Aring -50
-KPX Y Atilde -50
-KPX Y O -15
-KPX Y Oacute -15
-KPX Y Ocircumflex -15
-KPX Y Odieresis -15
-KPX Y Ograve -15
-KPX Y Ohungarumlaut -15
-KPX Y Omacron -15
-KPX Y Oslash -15
-KPX Y Otilde -15
-KPX Y a -92
-KPX Y aacute -92
-KPX Y abreve -92
-KPX Y acircumflex -92
-KPX Y adieresis -92
-KPX Y agrave -92
-KPX Y amacron -92
-KPX Y aogonek -92
-KPX Y aring -92
-KPX Y atilde -92
-KPX Y colon -65
-KPX Y comma -92
-KPX Y e -92
-KPX Y eacute -92
-KPX Y ecaron -92
-KPX Y ecircumflex -92
-KPX Y edieresis -52
-KPX Y edotaccent -92
-KPX Y egrave -52
-KPX Y emacron -52
-KPX Y eogonek -92
-KPX Y hyphen -74
-KPX Y i -74
-KPX Y iacute -74
-KPX Y icircumflex -34
-KPX Y idieresis -34
-KPX Y igrave -34
-KPX Y imacron -34
-KPX Y iogonek -74
-KPX Y o -92
-KPX Y oacute -92
-KPX Y ocircumflex -92
-KPX Y odieresis -92
-KPX Y ograve -92
-KPX Y ohungarumlaut -92
-KPX Y omacron -92
-KPX Y oslash -92
-KPX Y otilde -92
-KPX Y period -92
-KPX Y semicolon -65
-KPX Y u -92
-KPX Y uacute -92
-KPX Y ucircumflex -92
-KPX Y udieresis -92
-KPX Y ugrave -92
-KPX Y uhungarumlaut -92
-KPX Y umacron -92
-KPX Y uogonek -92
-KPX Y uring -92
-KPX Yacute A -50
-KPX Yacute Aacute -50
-KPX Yacute Abreve -50
-KPX Yacute Acircumflex -50
-KPX Yacute Adieresis -50
-KPX Yacute Agrave -50
-KPX Yacute Amacron -50
-KPX Yacute Aogonek -50
-KPX Yacute Aring -50
-KPX Yacute Atilde -50
-KPX Yacute O -15
-KPX Yacute Oacute -15
-KPX Yacute Ocircumflex -15
-KPX Yacute Odieresis -15
-KPX Yacute Ograve -15
-KPX Yacute Ohungarumlaut -15
-KPX Yacute Omacron -15
-KPX Yacute Oslash -15
-KPX Yacute Otilde -15
-KPX Yacute a -92
-KPX Yacute aacute -92
-KPX Yacute abreve -92
-KPX Yacute acircumflex -92
-KPX Yacute adieresis -92
-KPX Yacute agrave -92
-KPX Yacute amacron -92
-KPX Yacute aogonek -92
-KPX Yacute aring -92
-KPX Yacute atilde -92
-KPX Yacute colon -65
-KPX Yacute comma -92
-KPX Yacute e -92
-KPX Yacute eacute -92
-KPX Yacute ecaron -92
-KPX Yacute ecircumflex -92
-KPX Yacute edieresis -52
-KPX Yacute edotaccent -92
-KPX Yacute egrave -52
-KPX Yacute emacron -52
-KPX Yacute eogonek -92
-KPX Yacute hyphen -74
-KPX Yacute i -74
-KPX Yacute iacute -74
-KPX Yacute icircumflex -34
-KPX Yacute idieresis -34
-KPX Yacute igrave -34
-KPX Yacute imacron -34
-KPX Yacute iogonek -74
-KPX Yacute o -92
-KPX Yacute oacute -92
-KPX Yacute ocircumflex -92
-KPX Yacute odieresis -92
-KPX Yacute ograve -92
-KPX Yacute ohungarumlaut -92
-KPX Yacute omacron -92
-KPX Yacute oslash -92
-KPX Yacute otilde -92
-KPX Yacute period -92
-KPX Yacute semicolon -65
-KPX Yacute u -92
-KPX Yacute uacute -92
-KPX Yacute ucircumflex -92
-KPX Yacute udieresis -92
-KPX Yacute ugrave -92
-KPX Yacute uhungarumlaut -92
-KPX Yacute umacron -92
-KPX Yacute uogonek -92
-KPX Yacute uring -92
-KPX Ydieresis A -50
-KPX Ydieresis Aacute -50
-KPX Ydieresis Abreve -50
-KPX Ydieresis Acircumflex -50
-KPX Ydieresis Adieresis -50
-KPX Ydieresis Agrave -50
-KPX Ydieresis Amacron -50
-KPX Ydieresis Aogonek -50
-KPX Ydieresis Aring -50
-KPX Ydieresis Atilde -50
-KPX Ydieresis O -15
-KPX Ydieresis Oacute -15
-KPX Ydieresis Ocircumflex -15
-KPX Ydieresis Odieresis -15
-KPX Ydieresis Ograve -15
-KPX Ydieresis Ohungarumlaut -15
-KPX Ydieresis Omacron -15
-KPX Ydieresis Oslash -15
-KPX Ydieresis Otilde -15
-KPX Ydieresis a -92
-KPX Ydieresis aacute -92
-KPX Ydieresis abreve -92
-KPX Ydieresis acircumflex -92
-KPX Ydieresis adieresis -92
-KPX Ydieresis agrave -92
-KPX Ydieresis amacron -92
-KPX Ydieresis aogonek -92
-KPX Ydieresis aring -92
-KPX Ydieresis atilde -92
-KPX Ydieresis colon -65
-KPX Ydieresis comma -92
-KPX Ydieresis e -92
-KPX Ydieresis eacute -92
-KPX Ydieresis ecaron -92
-KPX Ydieresis ecircumflex -92
-KPX Ydieresis edieresis -52
-KPX Ydieresis edotaccent -92
-KPX Ydieresis egrave -52
-KPX Ydieresis emacron -52
-KPX Ydieresis eogonek -92
-KPX Ydieresis hyphen -74
-KPX Ydieresis i -74
-KPX Ydieresis iacute -74
-KPX Ydieresis icircumflex -34
-KPX Ydieresis idieresis -34
-KPX Ydieresis igrave -34
-KPX Ydieresis imacron -34
-KPX Ydieresis iogonek -74
-KPX Ydieresis o -92
-KPX Ydieresis oacute -92
-KPX Ydieresis ocircumflex -92
-KPX Ydieresis odieresis -92
-KPX Ydieresis ograve -92
-KPX Ydieresis ohungarumlaut -92
-KPX Ydieresis omacron -92
-KPX Ydieresis oslash -92
-KPX Ydieresis otilde -92
-KPX Ydieresis period -92
-KPX Ydieresis semicolon -65
-KPX Ydieresis u -92
-KPX Ydieresis uacute -92
-KPX Ydieresis ucircumflex -92
-KPX Ydieresis udieresis -92
-KPX Ydieresis ugrave -92
-KPX Ydieresis uhungarumlaut -92
-KPX Ydieresis umacron -92
-KPX Ydieresis uogonek -92
-KPX Ydieresis uring -92
-KPX a g -10
-KPX a gbreve -10
-KPX a gcommaaccent -10
-KPX aacute g -10
-KPX aacute gbreve -10
-KPX aacute gcommaaccent -10
-KPX abreve g -10
-KPX abreve gbreve -10
-KPX abreve gcommaaccent -10
-KPX acircumflex g -10
-KPX acircumflex gbreve -10
-KPX acircumflex gcommaaccent -10
-KPX adieresis g -10
-KPX adieresis gbreve -10
-KPX adieresis gcommaaccent -10
-KPX agrave g -10
-KPX agrave gbreve -10
-KPX agrave gcommaaccent -10
-KPX amacron g -10
-KPX amacron gbreve -10
-KPX amacron gcommaaccent -10
-KPX aogonek g -10
-KPX aogonek gbreve -10
-KPX aogonek gcommaaccent -10
-KPX aring g -10
-KPX aring gbreve -10
-KPX aring gcommaaccent -10
-KPX atilde g -10
-KPX atilde gbreve -10
-KPX atilde gcommaaccent -10
-KPX b period -40
-KPX b u -20
-KPX b uacute -20
-KPX b ucircumflex -20
-KPX b udieresis -20
-KPX b ugrave -20
-KPX b uhungarumlaut -20
-KPX b umacron -20
-KPX b uogonek -20
-KPX b uring -20
-KPX c h -15
-KPX c k -20
-KPX c kcommaaccent -20
-KPX cacute h -15
-KPX cacute k -20
-KPX cacute kcommaaccent -20
-KPX ccaron h -15
-KPX ccaron k -20
-KPX ccaron kcommaaccent -20
-KPX ccedilla h -15
-KPX ccedilla k -20
-KPX ccedilla kcommaaccent -20
-KPX comma quotedblright -140
-KPX comma quoteright -140
-KPX e comma -10
-KPX e g -40
-KPX e gbreve -40
-KPX e gcommaaccent -40
-KPX e period -15
-KPX e v -15
-KPX e w -15
-KPX e x -20
-KPX e y -30
-KPX e yacute -30
-KPX e ydieresis -30
-KPX eacute comma -10
-KPX eacute g -40
-KPX eacute gbreve -40
-KPX eacute gcommaaccent -40
-KPX eacute period -15
-KPX eacute v -15
-KPX eacute w -15
-KPX eacute x -20
-KPX eacute y -30
-KPX eacute yacute -30
-KPX eacute ydieresis -30
-KPX ecaron comma -10
-KPX ecaron g -40
-KPX ecaron gbreve -40
-KPX ecaron gcommaaccent -40
-KPX ecaron period -15
-KPX ecaron v -15
-KPX ecaron w -15
-KPX ecaron x -20
-KPX ecaron y -30
-KPX ecaron yacute -30
-KPX ecaron ydieresis -30
-KPX ecircumflex comma -10
-KPX ecircumflex g -40
-KPX ecircumflex gbreve -40
-KPX ecircumflex gcommaaccent -40
-KPX ecircumflex period -15
-KPX ecircumflex v -15
-KPX ecircumflex w -15
-KPX ecircumflex x -20
-KPX ecircumflex y -30
-KPX ecircumflex yacute -30
-KPX ecircumflex ydieresis -30
-KPX edieresis comma -10
-KPX edieresis g -40
-KPX edieresis gbreve -40
-KPX edieresis gcommaaccent -40
-KPX edieresis period -15
-KPX edieresis v -15
-KPX edieresis w -15
-KPX edieresis x -20
-KPX edieresis y -30
-KPX edieresis yacute -30
-KPX edieresis ydieresis -30
-KPX edotaccent comma -10
-KPX edotaccent g -40
-KPX edotaccent gbreve -40
-KPX edotaccent gcommaaccent -40
-KPX edotaccent period -15
-KPX edotaccent v -15
-KPX edotaccent w -15
-KPX edotaccent x -20
-KPX edotaccent y -30
-KPX edotaccent yacute -30
-KPX edotaccent ydieresis -30
-KPX egrave comma -10
-KPX egrave g -40
-KPX egrave gbreve -40
-KPX egrave gcommaaccent -40
-KPX egrave period -15
-KPX egrave v -15
-KPX egrave w -15
-KPX egrave x -20
-KPX egrave y -30
-KPX egrave yacute -30
-KPX egrave ydieresis -30
-KPX emacron comma -10
-KPX emacron g -40
-KPX emacron gbreve -40
-KPX emacron gcommaaccent -40
-KPX emacron period -15
-KPX emacron v -15
-KPX emacron w -15
-KPX emacron x -20
-KPX emacron y -30
-KPX emacron yacute -30
-KPX emacron ydieresis -30
-KPX eogonek comma -10
-KPX eogonek g -40
-KPX eogonek gbreve -40
-KPX eogonek gcommaaccent -40
-KPX eogonek period -15
-KPX eogonek v -15
-KPX eogonek w -15
-KPX eogonek x -20
-KPX eogonek y -30
-KPX eogonek yacute -30
-KPX eogonek ydieresis -30
-KPX f comma -10
-KPX f dotlessi -60
-KPX f f -18
-KPX f i -20
-KPX f iogonek -20
-KPX f period -15
-KPX f quoteright 92
-KPX g comma -10
-KPX g e -10
-KPX g eacute -10
-KPX g ecaron -10
-KPX g ecircumflex -10
-KPX g edieresis -10
-KPX g edotaccent -10
-KPX g egrave -10
-KPX g emacron -10
-KPX g eogonek -10
-KPX g g -10
-KPX g gbreve -10
-KPX g gcommaaccent -10
-KPX g period -15
-KPX gbreve comma -10
-KPX gbreve e -10
-KPX gbreve eacute -10
-KPX gbreve ecaron -10
-KPX gbreve ecircumflex -10
-KPX gbreve edieresis -10
-KPX gbreve edotaccent -10
-KPX gbreve egrave -10
-KPX gbreve emacron -10
-KPX gbreve eogonek -10
-KPX gbreve g -10
-KPX gbreve gbreve -10
-KPX gbreve gcommaaccent -10
-KPX gbreve period -15
-KPX gcommaaccent comma -10
-KPX gcommaaccent e -10
-KPX gcommaaccent eacute -10
-KPX gcommaaccent ecaron -10
-KPX gcommaaccent ecircumflex -10
-KPX gcommaaccent edieresis -10
-KPX gcommaaccent edotaccent -10
-KPX gcommaaccent egrave -10
-KPX gcommaaccent emacron -10
-KPX gcommaaccent eogonek -10
-KPX gcommaaccent g -10
-KPX gcommaaccent gbreve -10
-KPX gcommaaccent gcommaaccent -10
-KPX gcommaaccent period -15
-KPX k e -10
-KPX k eacute -10
-KPX k ecaron -10
-KPX k ecircumflex -10
-KPX k edieresis -10
-KPX k edotaccent -10
-KPX k egrave -10
-KPX k emacron -10
-KPX k eogonek -10
-KPX k o -10
-KPX k oacute -10
-KPX k ocircumflex -10
-KPX k odieresis -10
-KPX k ograve -10
-KPX k ohungarumlaut -10
-KPX k omacron -10
-KPX k oslash -10
-KPX k otilde -10
-KPX k y -10
-KPX k yacute -10
-KPX k ydieresis -10
-KPX kcommaaccent e -10
-KPX kcommaaccent eacute -10
-KPX kcommaaccent ecaron -10
-KPX kcommaaccent ecircumflex -10
-KPX kcommaaccent edieresis -10
-KPX kcommaaccent edotaccent -10
-KPX kcommaaccent egrave -10
-KPX kcommaaccent emacron -10
-KPX kcommaaccent eogonek -10
-KPX kcommaaccent o -10
-KPX kcommaaccent oacute -10
-KPX kcommaaccent ocircumflex -10
-KPX kcommaaccent odieresis -10
-KPX kcommaaccent ograve -10
-KPX kcommaaccent ohungarumlaut -10
-KPX kcommaaccent omacron -10
-KPX kcommaaccent oslash -10
-KPX kcommaaccent otilde -10
-KPX kcommaaccent y -10
-KPX kcommaaccent yacute -10
-KPX kcommaaccent ydieresis -10
-KPX n v -40
-KPX nacute v -40
-KPX ncaron v -40
-KPX ncommaaccent v -40
-KPX ntilde v -40
-KPX o g -10
-KPX o gbreve -10
-KPX o gcommaaccent -10
-KPX o v -10
-KPX oacute g -10
-KPX oacute gbreve -10
-KPX oacute gcommaaccent -10
-KPX oacute v -10
-KPX ocircumflex g -10
-KPX ocircumflex gbreve -10
-KPX ocircumflex gcommaaccent -10
-KPX ocircumflex v -10
-KPX odieresis g -10
-KPX odieresis gbreve -10
-KPX odieresis gcommaaccent -10
-KPX odieresis v -10
-KPX ograve g -10
-KPX ograve gbreve -10
-KPX ograve gcommaaccent -10
-KPX ograve v -10
-KPX ohungarumlaut g -10
-KPX ohungarumlaut gbreve -10
-KPX ohungarumlaut gcommaaccent -10
-KPX ohungarumlaut v -10
-KPX omacron g -10
-KPX omacron gbreve -10
-KPX omacron gcommaaccent -10
-KPX omacron v -10
-KPX oslash g -10
-KPX oslash gbreve -10
-KPX oslash gcommaaccent -10
-KPX oslash v -10
-KPX otilde g -10
-KPX otilde gbreve -10
-KPX otilde gcommaaccent -10
-KPX otilde v -10
-KPX period quotedblright -140
-KPX period quoteright -140
-KPX quoteleft quoteleft -111
-KPX quoteright d -25
-KPX quoteright dcroat -25
-KPX quoteright quoteright -111
-KPX quoteright r -25
-KPX quoteright racute -25
-KPX quoteright rcaron -25
-KPX quoteright rcommaaccent -25
-KPX quoteright s -40
-KPX quoteright sacute -40
-KPX quoteright scaron -40
-KPX quoteright scedilla -40
-KPX quoteright scommaaccent -40
-KPX quoteright space -111
-KPX quoteright t -30
-KPX quoteright tcommaaccent -30
-KPX quoteright v -10
-KPX r a -15
-KPX r aacute -15
-KPX r abreve -15
-KPX r acircumflex -15
-KPX r adieresis -15
-KPX r agrave -15
-KPX r amacron -15
-KPX r aogonek -15
-KPX r aring -15
-KPX r atilde -15
-KPX r c -37
-KPX r cacute -37
-KPX r ccaron -37
-KPX r ccedilla -37
-KPX r comma -111
-KPX r d -37
-KPX r dcroat -37
-KPX r e -37
-KPX r eacute -37
-KPX r ecaron -37
-KPX r ecircumflex -37
-KPX r edieresis -37
-KPX r edotaccent -37
-KPX r egrave -37
-KPX r emacron -37
-KPX r eogonek -37
-KPX r g -37
-KPX r gbreve -37
-KPX r gcommaaccent -37
-KPX r hyphen -20
-KPX r o -45
-KPX r oacute -45
-KPX r ocircumflex -45
-KPX r odieresis -45
-KPX r ograve -45
-KPX r ohungarumlaut -45
-KPX r omacron -45
-KPX r oslash -45
-KPX r otilde -45
-KPX r period -111
-KPX r q -37
-KPX r s -10
-KPX r sacute -10
-KPX r scaron -10
-KPX r scedilla -10
-KPX r scommaaccent -10
-KPX racute a -15
-KPX racute aacute -15
-KPX racute abreve -15
-KPX racute acircumflex -15
-KPX racute adieresis -15
-KPX racute agrave -15
-KPX racute amacron -15
-KPX racute aogonek -15
-KPX racute aring -15
-KPX racute atilde -15
-KPX racute c -37
-KPX racute cacute -37
-KPX racute ccaron -37
-KPX racute ccedilla -37
-KPX racute comma -111
-KPX racute d -37
-KPX racute dcroat -37
-KPX racute e -37
-KPX racute eacute -37
-KPX racute ecaron -37
-KPX racute ecircumflex -37
-KPX racute edieresis -37
-KPX racute edotaccent -37
-KPX racute egrave -37
-KPX racute emacron -37
-KPX racute eogonek -37
-KPX racute g -37
-KPX racute gbreve -37
-KPX racute gcommaaccent -37
-KPX racute hyphen -20
-KPX racute o -45
-KPX racute oacute -45
-KPX racute ocircumflex -45
-KPX racute odieresis -45
-KPX racute ograve -45
-KPX racute ohungarumlaut -45
-KPX racute omacron -45
-KPX racute oslash -45
-KPX racute otilde -45
-KPX racute period -111
-KPX racute q -37
-KPX racute s -10
-KPX racute sacute -10
-KPX racute scaron -10
-KPX racute scedilla -10
-KPX racute scommaaccent -10
-KPX rcaron a -15
-KPX rcaron aacute -15
-KPX rcaron abreve -15
-KPX rcaron acircumflex -15
-KPX rcaron adieresis -15
-KPX rcaron agrave -15
-KPX rcaron amacron -15
-KPX rcaron aogonek -15
-KPX rcaron aring -15
-KPX rcaron atilde -15
-KPX rcaron c -37
-KPX rcaron cacute -37
-KPX rcaron ccaron -37
-KPX rcaron ccedilla -37
-KPX rcaron comma -111
-KPX rcaron d -37
-KPX rcaron dcroat -37
-KPX rcaron e -37
-KPX rcaron eacute -37
-KPX rcaron ecaron -37
-KPX rcaron ecircumflex -37
-KPX rcaron edieresis -37
-KPX rcaron edotaccent -37
-KPX rcaron egrave -37
-KPX rcaron emacron -37
-KPX rcaron eogonek -37
-KPX rcaron g -37
-KPX rcaron gbreve -37
-KPX rcaron gcommaaccent -37
-KPX rcaron hyphen -20
-KPX rcaron o -45
-KPX rcaron oacute -45
-KPX rcaron ocircumflex -45
-KPX rcaron odieresis -45
-KPX rcaron ograve -45
-KPX rcaron ohungarumlaut -45
-KPX rcaron omacron -45
-KPX rcaron oslash -45
-KPX rcaron otilde -45
-KPX rcaron period -111
-KPX rcaron q -37
-KPX rcaron s -10
-KPX rcaron sacute -10
-KPX rcaron scaron -10
-KPX rcaron scedilla -10
-KPX rcaron scommaaccent -10
-KPX rcommaaccent a -15
-KPX rcommaaccent aacute -15
-KPX rcommaaccent abreve -15
-KPX rcommaaccent acircumflex -15
-KPX rcommaaccent adieresis -15
-KPX rcommaaccent agrave -15
-KPX rcommaaccent amacron -15
-KPX rcommaaccent aogonek -15
-KPX rcommaaccent aring -15
-KPX rcommaaccent atilde -15
-KPX rcommaaccent c -37
-KPX rcommaaccent cacute -37
-KPX rcommaaccent ccaron -37
-KPX rcommaaccent ccedilla -37
-KPX rcommaaccent comma -111
-KPX rcommaaccent d -37
-KPX rcommaaccent dcroat -37
-KPX rcommaaccent e -37
-KPX rcommaaccent eacute -37
-KPX rcommaaccent ecaron -37
-KPX rcommaaccent ecircumflex -37
-KPX rcommaaccent edieresis -37
-KPX rcommaaccent edotaccent -37
-KPX rcommaaccent egrave -37
-KPX rcommaaccent emacron -37
-KPX rcommaaccent eogonek -37
-KPX rcommaaccent g -37
-KPX rcommaaccent gbreve -37
-KPX rcommaaccent gcommaaccent -37
-KPX rcommaaccent hyphen -20
-KPX rcommaaccent o -45
-KPX rcommaaccent oacute -45
-KPX rcommaaccent ocircumflex -45
-KPX rcommaaccent odieresis -45
-KPX rcommaaccent ograve -45
-KPX rcommaaccent ohungarumlaut -45
-KPX rcommaaccent omacron -45
-KPX rcommaaccent oslash -45
-KPX rcommaaccent otilde -45
-KPX rcommaaccent period -111
-KPX rcommaaccent q -37
-KPX rcommaaccent s -10
-KPX rcommaaccent sacute -10
-KPX rcommaaccent scaron -10
-KPX rcommaaccent scedilla -10
-KPX rcommaaccent scommaaccent -10
-KPX space A -18
-KPX space Aacute -18
-KPX space Abreve -18
-KPX space Acircumflex -18
-KPX space Adieresis -18
-KPX space Agrave -18
-KPX space Amacron -18
-KPX space Aogonek -18
-KPX space Aring -18
-KPX space Atilde -18
-KPX space T -18
-KPX space Tcaron -18
-KPX space Tcommaaccent -18
-KPX space V -35
-KPX space W -40
-KPX space Y -75
-KPX space Yacute -75
-KPX space Ydieresis -75
-KPX v comma -74
-KPX v period -74
-KPX w comma -74
-KPX w period -74
-KPX y comma -55
-KPX y period -55
-KPX yacute comma -55
-KPX yacute period -55
-KPX ydieresis comma -55
-KPX ydieresis period -55
-EndKernPairs
-EndKernData
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Roman.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Roman.afm
deleted file mode 100644
index a0953f2802..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/Times-Roman.afm
+++ /dev/null
@@ -1,2419 +0,0 @@
-StartFontMetrics 4.1
-Comment Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Thu May 1 12:49:17 1997
-Comment UniqueID 43068
-Comment VMusage 43909 54934
-FontName Times-Roman
-FullName Times Roman
-FamilyName Times
-Weight Roman
-ItalicAngle 0
-IsFixedPitch false
-CharacterSet ExtendedRoman
-FontBBox -168 -218 1000 898
-UnderlinePosition -100
-UnderlineThickness 50
-Version 002.000
-Notice Copyright (c) 1985, 1987, 1989, 1990, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved.Times is a trademark of Linotype-Hell AG and/or its subsidiaries.
-EncodingScheme AdobeStandardEncoding
-CapHeight 662
-XHeight 450
-Ascender 683
-Descender -217
-StdHW 28
-StdVW 84
-StartCharMetrics 315
-C 32 ; WX 250 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 333 ; N exclam ; B 130 -9 238 676 ;
-C 34 ; WX 408 ; N quotedbl ; B 77 431 331 676 ;
-C 35 ; WX 500 ; N numbersign ; B 5 0 496 662 ;
-C 36 ; WX 500 ; N dollar ; B 44 -87 457 727 ;
-C 37 ; WX 833 ; N percent ; B 61 -13 772 676 ;
-C 38 ; WX 778 ; N ampersand ; B 42 -13 750 676 ;
-C 39 ; WX 333 ; N quoteright ; B 79 433 218 676 ;
-C 40 ; WX 333 ; N parenleft ; B 48 -177 304 676 ;
-C 41 ; WX 333 ; N parenright ; B 29 -177 285 676 ;
-C 42 ; WX 500 ; N asterisk ; B 69 265 432 676 ;
-C 43 ; WX 564 ; N plus ; B 30 0 534 506 ;
-C 44 ; WX 250 ; N comma ; B 56 -141 195 102 ;
-C 45 ; WX 333 ; N hyphen ; B 39 194 285 257 ;
-C 46 ; WX 250 ; N period ; B 70 -11 181 100 ;
-C 47 ; WX 278 ; N slash ; B -9 -14 287 676 ;
-C 48 ; WX 500 ; N zero ; B 24 -14 476 676 ;
-C 49 ; WX 500 ; N one ; B 111 0 394 676 ;
-C 50 ; WX 500 ; N two ; B 30 0 475 676 ;
-C 51 ; WX 500 ; N three ; B 43 -14 431 676 ;
-C 52 ; WX 500 ; N four ; B 12 0 472 676 ;
-C 53 ; WX 500 ; N five ; B 32 -14 438 688 ;
-C 54 ; WX 500 ; N six ; B 34 -14 468 684 ;
-C 55 ; WX 500 ; N seven ; B 20 -8 449 662 ;
-C 56 ; WX 500 ; N eight ; B 56 -14 445 676 ;
-C 57 ; WX 500 ; N nine ; B 30 -22 459 676 ;
-C 58 ; WX 278 ; N colon ; B 81 -11 192 459 ;
-C 59 ; WX 278 ; N semicolon ; B 80 -141 219 459 ;
-C 60 ; WX 564 ; N less ; B 28 -8 536 514 ;
-C 61 ; WX 564 ; N equal ; B 30 120 534 386 ;
-C 62 ; WX 564 ; N greater ; B 28 -8 536 514 ;
-C 63 ; WX 444 ; N question ; B 68 -8 414 676 ;
-C 64 ; WX 921 ; N at ; B 116 -14 809 676 ;
-C 65 ; WX 722 ; N A ; B 15 0 706 674 ;
-C 66 ; WX 667 ; N B ; B 17 0 593 662 ;
-C 67 ; WX 667 ; N C ; B 28 -14 633 676 ;
-C 68 ; WX 722 ; N D ; B 16 0 685 662 ;
-C 69 ; WX 611 ; N E ; B 12 0 597 662 ;
-C 70 ; WX 556 ; N F ; B 12 0 546 662 ;
-C 71 ; WX 722 ; N G ; B 32 -14 709 676 ;
-C 72 ; WX 722 ; N H ; B 19 0 702 662 ;
-C 73 ; WX 333 ; N I ; B 18 0 315 662 ;
-C 74 ; WX 389 ; N J ; B 10 -14 370 662 ;
-C 75 ; WX 722 ; N K ; B 34 0 723 662 ;
-C 76 ; WX 611 ; N L ; B 12 0 598 662 ;
-C 77 ; WX 889 ; N M ; B 12 0 863 662 ;
-C 78 ; WX 722 ; N N ; B 12 -11 707 662 ;
-C 79 ; WX 722 ; N O ; B 34 -14 688 676 ;
-C 80 ; WX 556 ; N P ; B 16 0 542 662 ;
-C 81 ; WX 722 ; N Q ; B 34 -178 701 676 ;
-C 82 ; WX 667 ; N R ; B 17 0 659 662 ;
-C 83 ; WX 556 ; N S ; B 42 -14 491 676 ;
-C 84 ; WX 611 ; N T ; B 17 0 593 662 ;
-C 85 ; WX 722 ; N U ; B 14 -14 705 662 ;
-C 86 ; WX 722 ; N V ; B 16 -11 697 662 ;
-C 87 ; WX 944 ; N W ; B 5 -11 932 662 ;
-C 88 ; WX 722 ; N X ; B 10 0 704 662 ;
-C 89 ; WX 722 ; N Y ; B 22 0 703 662 ;
-C 90 ; WX 611 ; N Z ; B 9 0 597 662 ;
-C 91 ; WX 333 ; N bracketleft ; B 88 -156 299 662 ;
-C 92 ; WX 278 ; N backslash ; B -9 -14 287 676 ;
-C 93 ; WX 333 ; N bracketright ; B 34 -156 245 662 ;
-C 94 ; WX 469 ; N asciicircum ; B 24 297 446 662 ;
-C 95 ; WX 500 ; N underscore ; B 0 -125 500 -75 ;
-C 96 ; WX 333 ; N quoteleft ; B 115 433 254 676 ;
-C 97 ; WX 444 ; N a ; B 37 -10 442 460 ;
-C 98 ; WX 500 ; N b ; B 3 -10 468 683 ;
-C 99 ; WX 444 ; N c ; B 25 -10 412 460 ;
-C 100 ; WX 500 ; N d ; B 27 -10 491 683 ;
-C 101 ; WX 444 ; N e ; B 25 -10 424 460 ;
-C 102 ; WX 333 ; N f ; B 20 0 383 683 ; L i fi ; L l fl ;
-C 103 ; WX 500 ; N g ; B 28 -218 470 460 ;
-C 104 ; WX 500 ; N h ; B 9 0 487 683 ;
-C 105 ; WX 278 ; N i ; B 16 0 253 683 ;
-C 106 ; WX 278 ; N j ; B -70 -218 194 683 ;
-C 107 ; WX 500 ; N k ; B 7 0 505 683 ;
-C 108 ; WX 278 ; N l ; B 19 0 257 683 ;
-C 109 ; WX 778 ; N m ; B 16 0 775 460 ;
-C 110 ; WX 500 ; N n ; B 16 0 485 460 ;
-C 111 ; WX 500 ; N o ; B 29 -10 470 460 ;
-C 112 ; WX 500 ; N p ; B 5 -217 470 460 ;
-C 113 ; WX 500 ; N q ; B 24 -217 488 460 ;
-C 114 ; WX 333 ; N r ; B 5 0 335 460 ;
-C 115 ; WX 389 ; N s ; B 51 -10 348 460 ;
-C 116 ; WX 278 ; N t ; B 13 -10 279 579 ;
-C 117 ; WX 500 ; N u ; B 9 -10 479 450 ;
-C 118 ; WX 500 ; N v ; B 19 -14 477 450 ;
-C 119 ; WX 722 ; N w ; B 21 -14 694 450 ;
-C 120 ; WX 500 ; N x ; B 17 0 479 450 ;
-C 121 ; WX 500 ; N y ; B 14 -218 475 450 ;
-C 122 ; WX 444 ; N z ; B 27 0 418 450 ;
-C 123 ; WX 480 ; N braceleft ; B 100 -181 350 680 ;
-C 124 ; WX 200 ; N bar ; B 67 -218 133 782 ;
-C 125 ; WX 480 ; N braceright ; B 130 -181 380 680 ;
-C 126 ; WX 541 ; N asciitilde ; B 40 183 502 323 ;
-C 161 ; WX 333 ; N exclamdown ; B 97 -218 205 467 ;
-C 162 ; WX 500 ; N cent ; B 53 -138 448 579 ;
-C 163 ; WX 500 ; N sterling ; B 12 -8 490 676 ;
-C 164 ; WX 167 ; N fraction ; B -168 -14 331 676 ;
-C 165 ; WX 500 ; N yen ; B -53 0 512 662 ;
-C 166 ; WX 500 ; N florin ; B 7 -189 490 676 ;
-C 167 ; WX 500 ; N section ; B 70 -148 426 676 ;
-C 168 ; WX 500 ; N currency ; B -22 58 522 602 ;
-C 169 ; WX 180 ; N quotesingle ; B 48 431 133 676 ;
-C 170 ; WX 444 ; N quotedblleft ; B 43 433 414 676 ;
-C 171 ; WX 500 ; N guillemotleft ; B 42 33 456 416 ;
-C 172 ; WX 333 ; N guilsinglleft ; B 63 33 285 416 ;
-C 173 ; WX 333 ; N guilsinglright ; B 48 33 270 416 ;
-C 174 ; WX 556 ; N fi ; B 31 0 521 683 ;
-C 175 ; WX 556 ; N fl ; B 32 0 521 683 ;
-C 177 ; WX 500 ; N endash ; B 0 201 500 250 ;
-C 178 ; WX 500 ; N dagger ; B 59 -149 442 676 ;
-C 179 ; WX 500 ; N daggerdbl ; B 58 -153 442 676 ;
-C 180 ; WX 250 ; N periodcentered ; B 70 199 181 310 ;
-C 182 ; WX 453 ; N paragraph ; B -22 -154 450 662 ;
-C 183 ; WX 350 ; N bullet ; B 40 196 310 466 ;
-C 184 ; WX 333 ; N quotesinglbase ; B 79 -141 218 102 ;
-C 185 ; WX 444 ; N quotedblbase ; B 45 -141 416 102 ;
-C 186 ; WX 444 ; N quotedblright ; B 30 433 401 676 ;
-C 187 ; WX 500 ; N guillemotright ; B 44 33 458 416 ;
-C 188 ; WX 1000 ; N ellipsis ; B 111 -11 888 100 ;
-C 189 ; WX 1000 ; N perthousand ; B 7 -19 994 706 ;
-C 191 ; WX 444 ; N questiondown ; B 30 -218 376 466 ;
-C 193 ; WX 333 ; N grave ; B 19 507 242 678 ;
-C 194 ; WX 333 ; N acute ; B 93 507 317 678 ;
-C 195 ; WX 333 ; N circumflex ; B 11 507 322 674 ;
-C 196 ; WX 333 ; N tilde ; B 1 532 331 638 ;
-C 197 ; WX 333 ; N macron ; B 11 547 322 601 ;
-C 198 ; WX 333 ; N breve ; B 26 507 307 664 ;
-C 199 ; WX 333 ; N dotaccent ; B 118 581 216 681 ;
-C 200 ; WX 333 ; N dieresis ; B 18 581 315 681 ;
-C 202 ; WX 333 ; N ring ; B 67 512 266 711 ;
-C 203 ; WX 333 ; N cedilla ; B 52 -215 261 0 ;
-C 205 ; WX 333 ; N hungarumlaut ; B -3 507 377 678 ;
-C 206 ; WX 333 ; N ogonek ; B 62 -165 243 0 ;
-C 207 ; WX 333 ; N caron ; B 11 507 322 674 ;
-C 208 ; WX 1000 ; N emdash ; B 0 201 1000 250 ;
-C 225 ; WX 889 ; N AE ; B 0 0 863 662 ;
-C 227 ; WX 276 ; N ordfeminine ; B 4 394 270 676 ;
-C 232 ; WX 611 ; N Lslash ; B 12 0 598 662 ;
-C 233 ; WX 722 ; N Oslash ; B 34 -80 688 734 ;
-C 234 ; WX 889 ; N OE ; B 30 -6 885 668 ;
-C 235 ; WX 310 ; N ordmasculine ; B 6 394 304 676 ;
-C 241 ; WX 667 ; N ae ; B 38 -10 632 460 ;
-C 245 ; WX 278 ; N dotlessi ; B 16 0 253 460 ;
-C 248 ; WX 278 ; N lslash ; B 19 0 259 683 ;
-C 249 ; WX 500 ; N oslash ; B 29 -112 470 551 ;
-C 250 ; WX 722 ; N oe ; B 30 -10 690 460 ;
-C 251 ; WX 500 ; N germandbls ; B 12 -9 468 683 ;
-C -1 ; WX 333 ; N Idieresis ; B 18 0 315 835 ;
-C -1 ; WX 444 ; N eacute ; B 25 -10 424 678 ;
-C -1 ; WX 444 ; N abreve ; B 37 -10 442 664 ;
-C -1 ; WX 500 ; N uhungarumlaut ; B 9 -10 501 678 ;
-C -1 ; WX 444 ; N ecaron ; B 25 -10 424 674 ;
-C -1 ; WX 722 ; N Ydieresis ; B 22 0 703 835 ;
-C -1 ; WX 564 ; N divide ; B 30 -10 534 516 ;
-C -1 ; WX 722 ; N Yacute ; B 22 0 703 890 ;
-C -1 ; WX 722 ; N Acircumflex ; B 15 0 706 886 ;
-C -1 ; WX 444 ; N aacute ; B 37 -10 442 678 ;
-C -1 ; WX 722 ; N Ucircumflex ; B 14 -14 705 886 ;
-C -1 ; WX 500 ; N yacute ; B 14 -218 475 678 ;
-C -1 ; WX 389 ; N scommaaccent ; B 51 -218 348 460 ;
-C -1 ; WX 444 ; N ecircumflex ; B 25 -10 424 674 ;
-C -1 ; WX 722 ; N Uring ; B 14 -14 705 898 ;
-C -1 ; WX 722 ; N Udieresis ; B 14 -14 705 835 ;
-C -1 ; WX 444 ; N aogonek ; B 37 -165 469 460 ;
-C -1 ; WX 722 ; N Uacute ; B 14 -14 705 890 ;
-C -1 ; WX 500 ; N uogonek ; B 9 -155 487 450 ;
-C -1 ; WX 611 ; N Edieresis ; B 12 0 597 835 ;
-C -1 ; WX 722 ; N Dcroat ; B 16 0 685 662 ;
-C -1 ; WX 250 ; N commaaccent ; B 59 -218 184 -50 ;
-C -1 ; WX 760 ; N copyright ; B 38 -14 722 676 ;
-C -1 ; WX 611 ; N Emacron ; B 12 0 597 813 ;
-C -1 ; WX 444 ; N ccaron ; B 25 -10 412 674 ;
-C -1 ; WX 444 ; N aring ; B 37 -10 442 711 ;
-C -1 ; WX 722 ; N Ncommaaccent ; B 12 -198 707 662 ;
-C -1 ; WX 278 ; N lacute ; B 19 0 290 890 ;
-C -1 ; WX 444 ; N agrave ; B 37 -10 442 678 ;
-C -1 ; WX 611 ; N Tcommaaccent ; B 17 -218 593 662 ;
-C -1 ; WX 667 ; N Cacute ; B 28 -14 633 890 ;
-C -1 ; WX 444 ; N atilde ; B 37 -10 442 638 ;
-C -1 ; WX 611 ; N Edotaccent ; B 12 0 597 835 ;
-C -1 ; WX 389 ; N scaron ; B 39 -10 350 674 ;
-C -1 ; WX 389 ; N scedilla ; B 51 -215 348 460 ;
-C -1 ; WX 278 ; N iacute ; B 16 0 290 678 ;
-C -1 ; WX 471 ; N lozenge ; B 13 0 459 724 ;
-C -1 ; WX 667 ; N Rcaron ; B 17 0 659 886 ;
-C -1 ; WX 722 ; N Gcommaaccent ; B 32 -218 709 676 ;
-C -1 ; WX 500 ; N ucircumflex ; B 9 -10 479 674 ;
-C -1 ; WX 444 ; N acircumflex ; B 37 -10 442 674 ;
-C -1 ; WX 722 ; N Amacron ; B 15 0 706 813 ;
-C -1 ; WX 333 ; N rcaron ; B 5 0 335 674 ;
-C -1 ; WX 444 ; N ccedilla ; B 25 -215 412 460 ;
-C -1 ; WX 611 ; N Zdotaccent ; B 9 0 597 835 ;
-C -1 ; WX 556 ; N Thorn ; B 16 0 542 662 ;
-C -1 ; WX 722 ; N Omacron ; B 34 -14 688 813 ;
-C -1 ; WX 667 ; N Racute ; B 17 0 659 890 ;
-C -1 ; WX 556 ; N Sacute ; B 42 -14 491 890 ;
-C -1 ; WX 588 ; N dcaron ; B 27 -10 589 695 ;
-C -1 ; WX 722 ; N Umacron ; B 14 -14 705 813 ;
-C -1 ; WX 500 ; N uring ; B 9 -10 479 711 ;
-C -1 ; WX 300 ; N threesuperior ; B 15 262 291 676 ;
-C -1 ; WX 722 ; N Ograve ; B 34 -14 688 890 ;
-C -1 ; WX 722 ; N Agrave ; B 15 0 706 890 ;
-C -1 ; WX 722 ; N Abreve ; B 15 0 706 876 ;
-C -1 ; WX 564 ; N multiply ; B 38 8 527 497 ;
-C -1 ; WX 500 ; N uacute ; B 9 -10 479 678 ;
-C -1 ; WX 611 ; N Tcaron ; B 17 0 593 886 ;
-C -1 ; WX 476 ; N partialdiff ; B 17 -38 459 710 ;
-C -1 ; WX 500 ; N ydieresis ; B 14 -218 475 623 ;
-C -1 ; WX 722 ; N Nacute ; B 12 -11 707 890 ;
-C -1 ; WX 278 ; N icircumflex ; B -16 0 295 674 ;
-C -1 ; WX 611 ; N Ecircumflex ; B 12 0 597 886 ;
-C -1 ; WX 444 ; N adieresis ; B 37 -10 442 623 ;
-C -1 ; WX 444 ; N edieresis ; B 25 -10 424 623 ;
-C -1 ; WX 444 ; N cacute ; B 25 -10 413 678 ;
-C -1 ; WX 500 ; N nacute ; B 16 0 485 678 ;
-C -1 ; WX 500 ; N umacron ; B 9 -10 479 601 ;
-C -1 ; WX 722 ; N Ncaron ; B 12 -11 707 886 ;
-C -1 ; WX 333 ; N Iacute ; B 18 0 317 890 ;
-C -1 ; WX 564 ; N plusminus ; B 30 0 534 506 ;
-C -1 ; WX 200 ; N brokenbar ; B 67 -143 133 707 ;
-C -1 ; WX 760 ; N registered ; B 38 -14 722 676 ;
-C -1 ; WX 722 ; N Gbreve ; B 32 -14 709 876 ;
-C -1 ; WX 333 ; N Idotaccent ; B 18 0 315 835 ;
-C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ;
-C -1 ; WX 611 ; N Egrave ; B 12 0 597 890 ;
-C -1 ; WX 333 ; N racute ; B 5 0 335 678 ;
-C -1 ; WX 500 ; N omacron ; B 29 -10 470 601 ;
-C -1 ; WX 611 ; N Zacute ; B 9 0 597 890 ;
-C -1 ; WX 611 ; N Zcaron ; B 9 0 597 886 ;
-C -1 ; WX 549 ; N greaterequal ; B 26 0 523 666 ;
-C -1 ; WX 722 ; N Eth ; B 16 0 685 662 ;
-C -1 ; WX 667 ; N Ccedilla ; B 28 -215 633 676 ;
-C -1 ; WX 278 ; N lcommaaccent ; B 19 -218 257 683 ;
-C -1 ; WX 326 ; N tcaron ; B 13 -10 318 722 ;
-C -1 ; WX 444 ; N eogonek ; B 25 -165 424 460 ;
-C -1 ; WX 722 ; N Uogonek ; B 14 -165 705 662 ;
-C -1 ; WX 722 ; N Aacute ; B 15 0 706 890 ;
-C -1 ; WX 722 ; N Adieresis ; B 15 0 706 835 ;
-C -1 ; WX 444 ; N egrave ; B 25 -10 424 678 ;
-C -1 ; WX 444 ; N zacute ; B 27 0 418 678 ;
-C -1 ; WX 278 ; N iogonek ; B 16 -165 265 683 ;
-C -1 ; WX 722 ; N Oacute ; B 34 -14 688 890 ;
-C -1 ; WX 500 ; N oacute ; B 29 -10 470 678 ;
-C -1 ; WX 444 ; N amacron ; B 37 -10 442 601 ;
-C -1 ; WX 389 ; N sacute ; B 51 -10 348 678 ;
-C -1 ; WX 278 ; N idieresis ; B -9 0 288 623 ;
-C -1 ; WX 722 ; N Ocircumflex ; B 34 -14 688 886 ;
-C -1 ; WX 722 ; N Ugrave ; B 14 -14 705 890 ;
-C -1 ; WX 612 ; N Delta ; B 6 0 608 688 ;
-C -1 ; WX 500 ; N thorn ; B 5 -217 470 683 ;
-C -1 ; WX 300 ; N twosuperior ; B 1 270 296 676 ;
-C -1 ; WX 722 ; N Odieresis ; B 34 -14 688 835 ;
-C -1 ; WX 500 ; N mu ; B 36 -218 512 450 ;
-C -1 ; WX 278 ; N igrave ; B -8 0 253 678 ;
-C -1 ; WX 500 ; N ohungarumlaut ; B 29 -10 491 678 ;
-C -1 ; WX 611 ; N Eogonek ; B 12 -165 597 662 ;
-C -1 ; WX 500 ; N dcroat ; B 27 -10 500 683 ;
-C -1 ; WX 750 ; N threequarters ; B 15 -14 718 676 ;
-C -1 ; WX 556 ; N Scedilla ; B 42 -215 491 676 ;
-C -1 ; WX 344 ; N lcaron ; B 19 0 347 695 ;
-C -1 ; WX 722 ; N Kcommaaccent ; B 34 -198 723 662 ;
-C -1 ; WX 611 ; N Lacute ; B 12 0 598 890 ;
-C -1 ; WX 980 ; N trademark ; B 30 256 957 662 ;
-C -1 ; WX 444 ; N edotaccent ; B 25 -10 424 623 ;
-C -1 ; WX 333 ; N Igrave ; B 18 0 315 890 ;
-C -1 ; WX 333 ; N Imacron ; B 11 0 322 813 ;
-C -1 ; WX 611 ; N Lcaron ; B 12 0 598 676 ;
-C -1 ; WX 750 ; N onehalf ; B 31 -14 746 676 ;
-C -1 ; WX 549 ; N lessequal ; B 26 0 523 666 ;
-C -1 ; WX 500 ; N ocircumflex ; B 29 -10 470 674 ;
-C -1 ; WX 500 ; N ntilde ; B 16 0 485 638 ;
-C -1 ; WX 722 ; N Uhungarumlaut ; B 14 -14 705 890 ;
-C -1 ; WX 611 ; N Eacute ; B 12 0 597 890 ;
-C -1 ; WX 444 ; N emacron ; B 25 -10 424 601 ;
-C -1 ; WX 500 ; N gbreve ; B 28 -218 470 664 ;
-C -1 ; WX 750 ; N onequarter ; B 37 -14 718 676 ;
-C -1 ; WX 556 ; N Scaron ; B 42 -14 491 886 ;
-C -1 ; WX 556 ; N Scommaaccent ; B 42 -218 491 676 ;
-C -1 ; WX 722 ; N Ohungarumlaut ; B 34 -14 688 890 ;
-C -1 ; WX 400 ; N degree ; B 57 390 343 676 ;
-C -1 ; WX 500 ; N ograve ; B 29 -10 470 678 ;
-C -1 ; WX 667 ; N Ccaron ; B 28 -14 633 886 ;
-C -1 ; WX 500 ; N ugrave ; B 9 -10 479 678 ;
-C -1 ; WX 453 ; N radical ; B 2 -60 452 768 ;
-C -1 ; WX 722 ; N Dcaron ; B 16 0 685 886 ;
-C -1 ; WX 333 ; N rcommaaccent ; B 5 -218 335 460 ;
-C -1 ; WX 722 ; N Ntilde ; B 12 -11 707 850 ;
-C -1 ; WX 500 ; N otilde ; B 29 -10 470 638 ;
-C -1 ; WX 667 ; N Rcommaaccent ; B 17 -198 659 662 ;
-C -1 ; WX 611 ; N Lcommaaccent ; B 12 -218 598 662 ;
-C -1 ; WX 722 ; N Atilde ; B 15 0 706 850 ;
-C -1 ; WX 722 ; N Aogonek ; B 15 -165 738 674 ;
-C -1 ; WX 722 ; N Aring ; B 15 0 706 898 ;
-C -1 ; WX 722 ; N Otilde ; B 34 -14 688 850 ;
-C -1 ; WX 444 ; N zdotaccent ; B 27 0 418 623 ;
-C -1 ; WX 611 ; N Ecaron ; B 12 0 597 886 ;
-C -1 ; WX 333 ; N Iogonek ; B 18 -165 315 662 ;
-C -1 ; WX 500 ; N kcommaaccent ; B 7 -218 505 683 ;
-C -1 ; WX 564 ; N minus ; B 30 220 534 286 ;
-C -1 ; WX 333 ; N Icircumflex ; B 11 0 322 886 ;
-C -1 ; WX 500 ; N ncaron ; B 16 0 485 674 ;
-C -1 ; WX 278 ; N tcommaaccent ; B 13 -218 279 579 ;
-C -1 ; WX 564 ; N logicalnot ; B 30 108 534 386 ;
-C -1 ; WX 500 ; N odieresis ; B 29 -10 470 623 ;
-C -1 ; WX 500 ; N udieresis ; B 9 -10 479 623 ;
-C -1 ; WX 549 ; N notequal ; B 12 -31 537 547 ;
-C -1 ; WX 500 ; N gcommaaccent ; B 28 -218 470 749 ;
-C -1 ; WX 500 ; N eth ; B 29 -10 471 686 ;
-C -1 ; WX 444 ; N zcaron ; B 27 0 418 674 ;
-C -1 ; WX 500 ; N ncommaaccent ; B 16 -218 485 460 ;
-C -1 ; WX 300 ; N onesuperior ; B 57 270 248 676 ;
-C -1 ; WX 278 ; N imacron ; B 6 0 271 601 ;
-C -1 ; WX 500 ; N Euro ; B 0 0 0 0 ;
-EndCharMetrics
-StartKernData
-StartKernPairs 2073
-KPX A C -40
-KPX A Cacute -40
-KPX A Ccaron -40
-KPX A Ccedilla -40
-KPX A G -40
-KPX A Gbreve -40
-KPX A Gcommaaccent -40
-KPX A O -55
-KPX A Oacute -55
-KPX A Ocircumflex -55
-KPX A Odieresis -55
-KPX A Ograve -55
-KPX A Ohungarumlaut -55
-KPX A Omacron -55
-KPX A Oslash -55
-KPX A Otilde -55
-KPX A Q -55
-KPX A T -111
-KPX A Tcaron -111
-KPX A Tcommaaccent -111
-KPX A U -55
-KPX A Uacute -55
-KPX A Ucircumflex -55
-KPX A Udieresis -55
-KPX A Ugrave -55
-KPX A Uhungarumlaut -55
-KPX A Umacron -55
-KPX A Uogonek -55
-KPX A Uring -55
-KPX A V -135
-KPX A W -90
-KPX A Y -105
-KPX A Yacute -105
-KPX A Ydieresis -105
-KPX A quoteright -111
-KPX A v -74
-KPX A w -92
-KPX A y -92
-KPX A yacute -92
-KPX A ydieresis -92
-KPX Aacute C -40
-KPX Aacute Cacute -40
-KPX Aacute Ccaron -40
-KPX Aacute Ccedilla -40
-KPX Aacute G -40
-KPX Aacute Gbreve -40
-KPX Aacute Gcommaaccent -40
-KPX Aacute O -55
-KPX Aacute Oacute -55
-KPX Aacute Ocircumflex -55
-KPX Aacute Odieresis -55
-KPX Aacute Ograve -55
-KPX Aacute Ohungarumlaut -55
-KPX Aacute Omacron -55
-KPX Aacute Oslash -55
-KPX Aacute Otilde -55
-KPX Aacute Q -55
-KPX Aacute T -111
-KPX Aacute Tcaron -111
-KPX Aacute Tcommaaccent -111
-KPX Aacute U -55
-KPX Aacute Uacute -55
-KPX Aacute Ucircumflex -55
-KPX Aacute Udieresis -55
-KPX Aacute Ugrave -55
-KPX Aacute Uhungarumlaut -55
-KPX Aacute Umacron -55
-KPX Aacute Uogonek -55
-KPX Aacute Uring -55
-KPX Aacute V -135
-KPX Aacute W -90
-KPX Aacute Y -105
-KPX Aacute Yacute -105
-KPX Aacute Ydieresis -105
-KPX Aacute quoteright -111
-KPX Aacute v -74
-KPX Aacute w -92
-KPX Aacute y -92
-KPX Aacute yacute -92
-KPX Aacute ydieresis -92
-KPX Abreve C -40
-KPX Abreve Cacute -40
-KPX Abreve Ccaron -40
-KPX Abreve Ccedilla -40
-KPX Abreve G -40
-KPX Abreve Gbreve -40
-KPX Abreve Gcommaaccent -40
-KPX Abreve O -55
-KPX Abreve Oacute -55
-KPX Abreve Ocircumflex -55
-KPX Abreve Odieresis -55
-KPX Abreve Ograve -55
-KPX Abreve Ohungarumlaut -55
-KPX Abreve Omacron -55
-KPX Abreve Oslash -55
-KPX Abreve Otilde -55
-KPX Abreve Q -55
-KPX Abreve T -111
-KPX Abreve Tcaron -111
-KPX Abreve Tcommaaccent -111
-KPX Abreve U -55
-KPX Abreve Uacute -55
-KPX Abreve Ucircumflex -55
-KPX Abreve Udieresis -55
-KPX Abreve Ugrave -55
-KPX Abreve Uhungarumlaut -55
-KPX Abreve Umacron -55
-KPX Abreve Uogonek -55
-KPX Abreve Uring -55
-KPX Abreve V -135
-KPX Abreve W -90
-KPX Abreve Y -105
-KPX Abreve Yacute -105
-KPX Abreve Ydieresis -105
-KPX Abreve quoteright -111
-KPX Abreve v -74
-KPX Abreve w -92
-KPX Abreve y -92
-KPX Abreve yacute -92
-KPX Abreve ydieresis -92
-KPX Acircumflex C -40
-KPX Acircumflex Cacute -40
-KPX Acircumflex Ccaron -40
-KPX Acircumflex Ccedilla -40
-KPX Acircumflex G -40
-KPX Acircumflex Gbreve -40
-KPX Acircumflex Gcommaaccent -40
-KPX Acircumflex O -55
-KPX Acircumflex Oacute -55
-KPX Acircumflex Ocircumflex -55
-KPX Acircumflex Odieresis -55
-KPX Acircumflex Ograve -55
-KPX Acircumflex Ohungarumlaut -55
-KPX Acircumflex Omacron -55
-KPX Acircumflex Oslash -55
-KPX Acircumflex Otilde -55
-KPX Acircumflex Q -55
-KPX Acircumflex T -111
-KPX Acircumflex Tcaron -111
-KPX Acircumflex Tcommaaccent -111
-KPX Acircumflex U -55
-KPX Acircumflex Uacute -55
-KPX Acircumflex Ucircumflex -55
-KPX Acircumflex Udieresis -55
-KPX Acircumflex Ugrave -55
-KPX Acircumflex Uhungarumlaut -55
-KPX Acircumflex Umacron -55
-KPX Acircumflex Uogonek -55
-KPX Acircumflex Uring -55
-KPX Acircumflex V -135
-KPX Acircumflex W -90
-KPX Acircumflex Y -105
-KPX Acircumflex Yacute -105
-KPX Acircumflex Ydieresis -105
-KPX Acircumflex quoteright -111
-KPX Acircumflex v -74
-KPX Acircumflex w -92
-KPX Acircumflex y -92
-KPX Acircumflex yacute -92
-KPX Acircumflex ydieresis -92
-KPX Adieresis C -40
-KPX Adieresis Cacute -40
-KPX Adieresis Ccaron -40
-KPX Adieresis Ccedilla -40
-KPX Adieresis G -40
-KPX Adieresis Gbreve -40
-KPX Adieresis Gcommaaccent -40
-KPX Adieresis O -55
-KPX Adieresis Oacute -55
-KPX Adieresis Ocircumflex -55
-KPX Adieresis Odieresis -55
-KPX Adieresis Ograve -55
-KPX Adieresis Ohungarumlaut -55
-KPX Adieresis Omacron -55
-KPX Adieresis Oslash -55
-KPX Adieresis Otilde -55
-KPX Adieresis Q -55
-KPX Adieresis T -111
-KPX Adieresis Tcaron -111
-KPX Adieresis Tcommaaccent -111
-KPX Adieresis U -55
-KPX Adieresis Uacute -55
-KPX Adieresis Ucircumflex -55
-KPX Adieresis Udieresis -55
-KPX Adieresis Ugrave -55
-KPX Adieresis Uhungarumlaut -55
-KPX Adieresis Umacron -55
-KPX Adieresis Uogonek -55
-KPX Adieresis Uring -55
-KPX Adieresis V -135
-KPX Adieresis W -90
-KPX Adieresis Y -105
-KPX Adieresis Yacute -105
-KPX Adieresis Ydieresis -105
-KPX Adieresis quoteright -111
-KPX Adieresis v -74
-KPX Adieresis w -92
-KPX Adieresis y -92
-KPX Adieresis yacute -92
-KPX Adieresis ydieresis -92
-KPX Agrave C -40
-KPX Agrave Cacute -40
-KPX Agrave Ccaron -40
-KPX Agrave Ccedilla -40
-KPX Agrave G -40
-KPX Agrave Gbreve -40
-KPX Agrave Gcommaaccent -40
-KPX Agrave O -55
-KPX Agrave Oacute -55
-KPX Agrave Ocircumflex -55
-KPX Agrave Odieresis -55
-KPX Agrave Ograve -55
-KPX Agrave Ohungarumlaut -55
-KPX Agrave Omacron -55
-KPX Agrave Oslash -55
-KPX Agrave Otilde -55
-KPX Agrave Q -55
-KPX Agrave T -111
-KPX Agrave Tcaron -111
-KPX Agrave Tcommaaccent -111
-KPX Agrave U -55
-KPX Agrave Uacute -55
-KPX Agrave Ucircumflex -55
-KPX Agrave Udieresis -55
-KPX Agrave Ugrave -55
-KPX Agrave Uhungarumlaut -55
-KPX Agrave Umacron -55
-KPX Agrave Uogonek -55
-KPX Agrave Uring -55
-KPX Agrave V -135
-KPX Agrave W -90
-KPX Agrave Y -105
-KPX Agrave Yacute -105
-KPX Agrave Ydieresis -105
-KPX Agrave quoteright -111
-KPX Agrave v -74
-KPX Agrave w -92
-KPX Agrave y -92
-KPX Agrave yacute -92
-KPX Agrave ydieresis -92
-KPX Amacron C -40
-KPX Amacron Cacute -40
-KPX Amacron Ccaron -40
-KPX Amacron Ccedilla -40
-KPX Amacron G -40
-KPX Amacron Gbreve -40
-KPX Amacron Gcommaaccent -40
-KPX Amacron O -55
-KPX Amacron Oacute -55
-KPX Amacron Ocircumflex -55
-KPX Amacron Odieresis -55
-KPX Amacron Ograve -55
-KPX Amacron Ohungarumlaut -55
-KPX Amacron Omacron -55
-KPX Amacron Oslash -55
-KPX Amacron Otilde -55
-KPX Amacron Q -55
-KPX Amacron T -111
-KPX Amacron Tcaron -111
-KPX Amacron Tcommaaccent -111
-KPX Amacron U -55
-KPX Amacron Uacute -55
-KPX Amacron Ucircumflex -55
-KPX Amacron Udieresis -55
-KPX Amacron Ugrave -55
-KPX Amacron Uhungarumlaut -55
-KPX Amacron Umacron -55
-KPX Amacron Uogonek -55
-KPX Amacron Uring -55
-KPX Amacron V -135
-KPX Amacron W -90
-KPX Amacron Y -105
-KPX Amacron Yacute -105
-KPX Amacron Ydieresis -105
-KPX Amacron quoteright -111
-KPX Amacron v -74
-KPX Amacron w -92
-KPX Amacron y -92
-KPX Amacron yacute -92
-KPX Amacron ydieresis -92
-KPX Aogonek C -40
-KPX Aogonek Cacute -40
-KPX Aogonek Ccaron -40
-KPX Aogonek Ccedilla -40
-KPX Aogonek G -40
-KPX Aogonek Gbreve -40
-KPX Aogonek Gcommaaccent -40
-KPX Aogonek O -55
-KPX Aogonek Oacute -55
-KPX Aogonek Ocircumflex -55
-KPX Aogonek Odieresis -55
-KPX Aogonek Ograve -55
-KPX Aogonek Ohungarumlaut -55
-KPX Aogonek Omacron -55
-KPX Aogonek Oslash -55
-KPX Aogonek Otilde -55
-KPX Aogonek Q -55
-KPX Aogonek T -111
-KPX Aogonek Tcaron -111
-KPX Aogonek Tcommaaccent -111
-KPX Aogonek U -55
-KPX Aogonek Uacute -55
-KPX Aogonek Ucircumflex -55
-KPX Aogonek Udieresis -55
-KPX Aogonek Ugrave -55
-KPX Aogonek Uhungarumlaut -55
-KPX Aogonek Umacron -55
-KPX Aogonek Uogonek -55
-KPX Aogonek Uring -55
-KPX Aogonek V -135
-KPX Aogonek W -90
-KPX Aogonek Y -105
-KPX Aogonek Yacute -105
-KPX Aogonek Ydieresis -105
-KPX Aogonek quoteright -111
-KPX Aogonek v -74
-KPX Aogonek w -52
-KPX Aogonek y -52
-KPX Aogonek yacute -52
-KPX Aogonek ydieresis -52
-KPX Aring C -40
-KPX Aring Cacute -40
-KPX Aring Ccaron -40
-KPX Aring Ccedilla -40
-KPX Aring G -40
-KPX Aring Gbreve -40
-KPX Aring Gcommaaccent -40
-KPX Aring O -55
-KPX Aring Oacute -55
-KPX Aring Ocircumflex -55
-KPX Aring Odieresis -55
-KPX Aring Ograve -55
-KPX Aring Ohungarumlaut -55
-KPX Aring Omacron -55
-KPX Aring Oslash -55
-KPX Aring Otilde -55
-KPX Aring Q -55
-KPX Aring T -111
-KPX Aring Tcaron -111
-KPX Aring Tcommaaccent -111
-KPX Aring U -55
-KPX Aring Uacute -55
-KPX Aring Ucircumflex -55
-KPX Aring Udieresis -55
-KPX Aring Ugrave -55
-KPX Aring Uhungarumlaut -55
-KPX Aring Umacron -55
-KPX Aring Uogonek -55
-KPX Aring Uring -55
-KPX Aring V -135
-KPX Aring W -90
-KPX Aring Y -105
-KPX Aring Yacute -105
-KPX Aring Ydieresis -105
-KPX Aring quoteright -111
-KPX Aring v -74
-KPX Aring w -92
-KPX Aring y -92
-KPX Aring yacute -92
-KPX Aring ydieresis -92
-KPX Atilde C -40
-KPX Atilde Cacute -40
-KPX Atilde Ccaron -40
-KPX Atilde Ccedilla -40
-KPX Atilde G -40
-KPX Atilde Gbreve -40
-KPX Atilde Gcommaaccent -40
-KPX Atilde O -55
-KPX Atilde Oacute -55
-KPX Atilde Ocircumflex -55
-KPX Atilde Odieresis -55
-KPX Atilde Ograve -55
-KPX Atilde Ohungarumlaut -55
-KPX Atilde Omacron -55
-KPX Atilde Oslash -55
-KPX Atilde Otilde -55
-KPX Atilde Q -55
-KPX Atilde T -111
-KPX Atilde Tcaron -111
-KPX Atilde Tcommaaccent -111
-KPX Atilde U -55
-KPX Atilde Uacute -55
-KPX Atilde Ucircumflex -55
-KPX Atilde Udieresis -55
-KPX Atilde Ugrave -55
-KPX Atilde Uhungarumlaut -55
-KPX Atilde Umacron -55
-KPX Atilde Uogonek -55
-KPX Atilde Uring -55
-KPX Atilde V -135
-KPX Atilde W -90
-KPX Atilde Y -105
-KPX Atilde Yacute -105
-KPX Atilde Ydieresis -105
-KPX Atilde quoteright -111
-KPX Atilde v -74
-KPX Atilde w -92
-KPX Atilde y -92
-KPX Atilde yacute -92
-KPX Atilde ydieresis -92
-KPX B A -35
-KPX B Aacute -35
-KPX B Abreve -35
-KPX B Acircumflex -35
-KPX B Adieresis -35
-KPX B Agrave -35
-KPX B Amacron -35
-KPX B Aogonek -35
-KPX B Aring -35
-KPX B Atilde -35
-KPX B U -10
-KPX B Uacute -10
-KPX B Ucircumflex -10
-KPX B Udieresis -10
-KPX B Ugrave -10
-KPX B Uhungarumlaut -10
-KPX B Umacron -10
-KPX B Uogonek -10
-KPX B Uring -10
-KPX D A -40
-KPX D Aacute -40
-KPX D Abreve -40
-KPX D Acircumflex -40
-KPX D Adieresis -40
-KPX D Agrave -40
-KPX D Amacron -40
-KPX D Aogonek -40
-KPX D Aring -40
-KPX D Atilde -40
-KPX D V -40
-KPX D W -30
-KPX D Y -55
-KPX D Yacute -55
-KPX D Ydieresis -55
-KPX Dcaron A -40
-KPX Dcaron Aacute -40
-KPX Dcaron Abreve -40
-KPX Dcaron Acircumflex -40
-KPX Dcaron Adieresis -40
-KPX Dcaron Agrave -40
-KPX Dcaron Amacron -40
-KPX Dcaron Aogonek -40
-KPX Dcaron Aring -40
-KPX Dcaron Atilde -40
-KPX Dcaron V -40
-KPX Dcaron W -30
-KPX Dcaron Y -55
-KPX Dcaron Yacute -55
-KPX Dcaron Ydieresis -55
-KPX Dcroat A -40
-KPX Dcroat Aacute -40
-KPX Dcroat Abreve -40
-KPX Dcroat Acircumflex -40
-KPX Dcroat Adieresis -40
-KPX Dcroat Agrave -40
-KPX Dcroat Amacron -40
-KPX Dcroat Aogonek -40
-KPX Dcroat Aring -40
-KPX Dcroat Atilde -40
-KPX Dcroat V -40
-KPX Dcroat W -30
-KPX Dcroat Y -55
-KPX Dcroat Yacute -55
-KPX Dcroat Ydieresis -55
-KPX F A -74
-KPX F Aacute -74
-KPX F Abreve -74
-KPX F Acircumflex -74
-KPX F Adieresis -74
-KPX F Agrave -74
-KPX F Amacron -74
-KPX F Aogonek -74
-KPX F Aring -74
-KPX F Atilde -74
-KPX F a -15
-KPX F aacute -15
-KPX F abreve -15
-KPX F acircumflex -15
-KPX F adieresis -15
-KPX F agrave -15
-KPX F amacron -15
-KPX F aogonek -15
-KPX F aring -15
-KPX F atilde -15
-KPX F comma -80
-KPX F o -15
-KPX F oacute -15
-KPX F ocircumflex -15
-KPX F odieresis -15
-KPX F ograve -15
-KPX F ohungarumlaut -15
-KPX F omacron -15
-KPX F oslash -15
-KPX F otilde -15
-KPX F period -80
-KPX J A -60
-KPX J Aacute -60
-KPX J Abreve -60
-KPX J Acircumflex -60
-KPX J Adieresis -60
-KPX J Agrave -60
-KPX J Amacron -60
-KPX J Aogonek -60
-KPX J Aring -60
-KPX J Atilde -60
-KPX K O -30
-KPX K Oacute -30
-KPX K Ocircumflex -30
-KPX K Odieresis -30
-KPX K Ograve -30
-KPX K Ohungarumlaut -30
-KPX K Omacron -30
-KPX K Oslash -30
-KPX K Otilde -30
-KPX K e -25
-KPX K eacute -25
-KPX K ecaron -25
-KPX K ecircumflex -25
-KPX K edieresis -25
-KPX K edotaccent -25
-KPX K egrave -25
-KPX K emacron -25
-KPX K eogonek -25
-KPX K o -35
-KPX K oacute -35
-KPX K ocircumflex -35
-KPX K odieresis -35
-KPX K ograve -35
-KPX K ohungarumlaut -35
-KPX K omacron -35
-KPX K oslash -35
-KPX K otilde -35
-KPX K u -15
-KPX K uacute -15
-KPX K ucircumflex -15
-KPX K udieresis -15
-KPX K ugrave -15
-KPX K uhungarumlaut -15
-KPX K umacron -15
-KPX K uogonek -15
-KPX K uring -15
-KPX K y -25
-KPX K yacute -25
-KPX K ydieresis -25
-KPX Kcommaaccent O -30
-KPX Kcommaaccent Oacute -30
-KPX Kcommaaccent Ocircumflex -30
-KPX Kcommaaccent Odieresis -30
-KPX Kcommaaccent Ograve -30
-KPX Kcommaaccent Ohungarumlaut -30
-KPX Kcommaaccent Omacron -30
-KPX Kcommaaccent Oslash -30
-KPX Kcommaaccent Otilde -30
-KPX Kcommaaccent e -25
-KPX Kcommaaccent eacute -25
-KPX Kcommaaccent ecaron -25
-KPX Kcommaaccent ecircumflex -25
-KPX Kcommaaccent edieresis -25
-KPX Kcommaaccent edotaccent -25
-KPX Kcommaaccent egrave -25
-KPX Kcommaaccent emacron -25
-KPX Kcommaaccent eogonek -25
-KPX Kcommaaccent o -35
-KPX Kcommaaccent oacute -35
-KPX Kcommaaccent ocircumflex -35
-KPX Kcommaaccent odieresis -35
-KPX Kcommaaccent ograve -35
-KPX Kcommaaccent ohungarumlaut -35
-KPX Kcommaaccent omacron -35
-KPX Kcommaaccent oslash -35
-KPX Kcommaaccent otilde -35
-KPX Kcommaaccent u -15
-KPX Kcommaaccent uacute -15
-KPX Kcommaaccent ucircumflex -15
-KPX Kcommaaccent udieresis -15
-KPX Kcommaaccent ugrave -15
-KPX Kcommaaccent uhungarumlaut -15
-KPX Kcommaaccent umacron -15
-KPX Kcommaaccent uogonek -15
-KPX Kcommaaccent uring -15
-KPX Kcommaaccent y -25
-KPX Kcommaaccent yacute -25
-KPX Kcommaaccent ydieresis -25
-KPX L T -92
-KPX L Tcaron -92
-KPX L Tcommaaccent -92
-KPX L V -100
-KPX L W -74
-KPX L Y -100
-KPX L Yacute -100
-KPX L Ydieresis -100
-KPX L quoteright -92
-KPX L y -55
-KPX L yacute -55
-KPX L ydieresis -55
-KPX Lacute T -92
-KPX Lacute Tcaron -92
-KPX Lacute Tcommaaccent -92
-KPX Lacute V -100
-KPX Lacute W -74
-KPX Lacute Y -100
-KPX Lacute Yacute -100
-KPX Lacute Ydieresis -100
-KPX Lacute quoteright -92
-KPX Lacute y -55
-KPX Lacute yacute -55
-KPX Lacute ydieresis -55
-KPX Lcaron quoteright -92
-KPX Lcaron y -55
-KPX Lcaron yacute -55
-KPX Lcaron ydieresis -55
-KPX Lcommaaccent T -92
-KPX Lcommaaccent Tcaron -92
-KPX Lcommaaccent Tcommaaccent -92
-KPX Lcommaaccent V -100
-KPX Lcommaaccent W -74
-KPX Lcommaaccent Y -100
-KPX Lcommaaccent Yacute -100
-KPX Lcommaaccent Ydieresis -100
-KPX Lcommaaccent quoteright -92
-KPX Lcommaaccent y -55
-KPX Lcommaaccent yacute -55
-KPX Lcommaaccent ydieresis -55
-KPX Lslash T -92
-KPX Lslash Tcaron -92
-KPX Lslash Tcommaaccent -92
-KPX Lslash V -100
-KPX Lslash W -74
-KPX Lslash Y -100
-KPX Lslash Yacute -100
-KPX Lslash Ydieresis -100
-KPX Lslash quoteright -92
-KPX Lslash y -55
-KPX Lslash yacute -55
-KPX Lslash ydieresis -55
-KPX N A -35
-KPX N Aacute -35
-KPX N Abreve -35
-KPX N Acircumflex -35
-KPX N Adieresis -35
-KPX N Agrave -35
-KPX N Amacron -35
-KPX N Aogonek -35
-KPX N Aring -35
-KPX N Atilde -35
-KPX Nacute A -35
-KPX Nacute Aacute -35
-KPX Nacute Abreve -35
-KPX Nacute Acircumflex -35
-KPX Nacute Adieresis -35
-KPX Nacute Agrave -35
-KPX Nacute Amacron -35
-KPX Nacute Aogonek -35
-KPX Nacute Aring -35
-KPX Nacute Atilde -35
-KPX Ncaron A -35
-KPX Ncaron Aacute -35
-KPX Ncaron Abreve -35
-KPX Ncaron Acircumflex -35
-KPX Ncaron Adieresis -35
-KPX Ncaron Agrave -35
-KPX Ncaron Amacron -35
-KPX Ncaron Aogonek -35
-KPX Ncaron Aring -35
-KPX Ncaron Atilde -35
-KPX Ncommaaccent A -35
-KPX Ncommaaccent Aacute -35
-KPX Ncommaaccent Abreve -35
-KPX Ncommaaccent Acircumflex -35
-KPX Ncommaaccent Adieresis -35
-KPX Ncommaaccent Agrave -35
-KPX Ncommaaccent Amacron -35
-KPX Ncommaaccent Aogonek -35
-KPX Ncommaaccent Aring -35
-KPX Ncommaaccent Atilde -35
-KPX Ntilde A -35
-KPX Ntilde Aacute -35
-KPX Ntilde Abreve -35
-KPX Ntilde Acircumflex -35
-KPX Ntilde Adieresis -35
-KPX Ntilde Agrave -35
-KPX Ntilde Amacron -35
-KPX Ntilde Aogonek -35
-KPX Ntilde Aring -35
-KPX Ntilde Atilde -35
-KPX O A -35
-KPX O Aacute -35
-KPX O Abreve -35
-KPX O Acircumflex -35
-KPX O Adieresis -35
-KPX O Agrave -35
-KPX O Amacron -35
-KPX O Aogonek -35
-KPX O Aring -35
-KPX O Atilde -35
-KPX O T -40
-KPX O Tcaron -40
-KPX O Tcommaaccent -40
-KPX O V -50
-KPX O W -35
-KPX O X -40
-KPX O Y -50
-KPX O Yacute -50
-KPX O Ydieresis -50
-KPX Oacute A -35
-KPX Oacute Aacute -35
-KPX Oacute Abreve -35
-KPX Oacute Acircumflex -35
-KPX Oacute Adieresis -35
-KPX Oacute Agrave -35
-KPX Oacute Amacron -35
-KPX Oacute Aogonek -35
-KPX Oacute Aring -35
-KPX Oacute Atilde -35
-KPX Oacute T -40
-KPX Oacute Tcaron -40
-KPX Oacute Tcommaaccent -40
-KPX Oacute V -50
-KPX Oacute W -35
-KPX Oacute X -40
-KPX Oacute Y -50
-KPX Oacute Yacute -50
-KPX Oacute Ydieresis -50
-KPX Ocircumflex A -35
-KPX Ocircumflex Aacute -35
-KPX Ocircumflex Abreve -35
-KPX Ocircumflex Acircumflex -35
-KPX Ocircumflex Adieresis -35
-KPX Ocircumflex Agrave -35
-KPX Ocircumflex Amacron -35
-KPX Ocircumflex Aogonek -35
-KPX Ocircumflex Aring -35
-KPX Ocircumflex Atilde -35
-KPX Ocircumflex T -40
-KPX Ocircumflex Tcaron -40
-KPX Ocircumflex Tcommaaccent -40
-KPX Ocircumflex V -50
-KPX Ocircumflex W -35
-KPX Ocircumflex X -40
-KPX Ocircumflex Y -50
-KPX Ocircumflex Yacute -50
-KPX Ocircumflex Ydieresis -50
-KPX Odieresis A -35
-KPX Odieresis Aacute -35
-KPX Odieresis Abreve -35
-KPX Odieresis Acircumflex -35
-KPX Odieresis Adieresis -35
-KPX Odieresis Agrave -35
-KPX Odieresis Amacron -35
-KPX Odieresis Aogonek -35
-KPX Odieresis Aring -35
-KPX Odieresis Atilde -35
-KPX Odieresis T -40
-KPX Odieresis Tcaron -40
-KPX Odieresis Tcommaaccent -40
-KPX Odieresis V -50
-KPX Odieresis W -35
-KPX Odieresis X -40
-KPX Odieresis Y -50
-KPX Odieresis Yacute -50
-KPX Odieresis Ydieresis -50
-KPX Ograve A -35
-KPX Ograve Aacute -35
-KPX Ograve Abreve -35
-KPX Ograve Acircumflex -35
-KPX Ograve Adieresis -35
-KPX Ograve Agrave -35
-KPX Ograve Amacron -35
-KPX Ograve Aogonek -35
-KPX Ograve Aring -35
-KPX Ograve Atilde -35
-KPX Ograve T -40
-KPX Ograve Tcaron -40
-KPX Ograve Tcommaaccent -40
-KPX Ograve V -50
-KPX Ograve W -35
-KPX Ograve X -40
-KPX Ograve Y -50
-KPX Ograve Yacute -50
-KPX Ograve Ydieresis -50
-KPX Ohungarumlaut A -35
-KPX Ohungarumlaut Aacute -35
-KPX Ohungarumlaut Abreve -35
-KPX Ohungarumlaut Acircumflex -35
-KPX Ohungarumlaut Adieresis -35
-KPX Ohungarumlaut Agrave -35
-KPX Ohungarumlaut Amacron -35
-KPX Ohungarumlaut Aogonek -35
-KPX Ohungarumlaut Aring -35
-KPX Ohungarumlaut Atilde -35
-KPX Ohungarumlaut T -40
-KPX Ohungarumlaut Tcaron -40
-KPX Ohungarumlaut Tcommaaccent -40
-KPX Ohungarumlaut V -50
-KPX Ohungarumlaut W -35
-KPX Ohungarumlaut X -40
-KPX Ohungarumlaut Y -50
-KPX Ohungarumlaut Yacute -50
-KPX Ohungarumlaut Ydieresis -50
-KPX Omacron A -35
-KPX Omacron Aacute -35
-KPX Omacron Abreve -35
-KPX Omacron Acircumflex -35
-KPX Omacron Adieresis -35
-KPX Omacron Agrave -35
-KPX Omacron Amacron -35
-KPX Omacron Aogonek -35
-KPX Omacron Aring -35
-KPX Omacron Atilde -35
-KPX Omacron T -40
-KPX Omacron Tcaron -40
-KPX Omacron Tcommaaccent -40
-KPX Omacron V -50
-KPX Omacron W -35
-KPX Omacron X -40
-KPX Omacron Y -50
-KPX Omacron Yacute -50
-KPX Omacron Ydieresis -50
-KPX Oslash A -35
-KPX Oslash Aacute -35
-KPX Oslash Abreve -35
-KPX Oslash Acircumflex -35
-KPX Oslash Adieresis -35
-KPX Oslash Agrave -35
-KPX Oslash Amacron -35
-KPX Oslash Aogonek -35
-KPX Oslash Aring -35
-KPX Oslash Atilde -35
-KPX Oslash T -40
-KPX Oslash Tcaron -40
-KPX Oslash Tcommaaccent -40
-KPX Oslash V -50
-KPX Oslash W -35
-KPX Oslash X -40
-KPX Oslash Y -50
-KPX Oslash Yacute -50
-KPX Oslash Ydieresis -50
-KPX Otilde A -35
-KPX Otilde Aacute -35
-KPX Otilde Abreve -35
-KPX Otilde Acircumflex -35
-KPX Otilde Adieresis -35
-KPX Otilde Agrave -35
-KPX Otilde Amacron -35
-KPX Otilde Aogonek -35
-KPX Otilde Aring -35
-KPX Otilde Atilde -35
-KPX Otilde T -40
-KPX Otilde Tcaron -40
-KPX Otilde Tcommaaccent -40
-KPX Otilde V -50
-KPX Otilde W -35
-KPX Otilde X -40
-KPX Otilde Y -50
-KPX Otilde Yacute -50
-KPX Otilde Ydieresis -50
-KPX P A -92
-KPX P Aacute -92
-KPX P Abreve -92
-KPX P Acircumflex -92
-KPX P Adieresis -92
-KPX P Agrave -92
-KPX P Amacron -92
-KPX P Aogonek -92
-KPX P Aring -92
-KPX P Atilde -92
-KPX P a -15
-KPX P aacute -15
-KPX P abreve -15
-KPX P acircumflex -15
-KPX P adieresis -15
-KPX P agrave -15
-KPX P amacron -15
-KPX P aogonek -15
-KPX P aring -15
-KPX P atilde -15
-KPX P comma -111
-KPX P period -111
-KPX Q U -10
-KPX Q Uacute -10
-KPX Q Ucircumflex -10
-KPX Q Udieresis -10
-KPX Q Ugrave -10
-KPX Q Uhungarumlaut -10
-KPX Q Umacron -10
-KPX Q Uogonek -10
-KPX Q Uring -10
-KPX R O -40
-KPX R Oacute -40
-KPX R Ocircumflex -40
-KPX R Odieresis -40
-KPX R Ograve -40
-KPX R Ohungarumlaut -40
-KPX R Omacron -40
-KPX R Oslash -40
-KPX R Otilde -40
-KPX R T -60
-KPX R Tcaron -60
-KPX R Tcommaaccent -60
-KPX R U -40
-KPX R Uacute -40
-KPX R Ucircumflex -40
-KPX R Udieresis -40
-KPX R Ugrave -40
-KPX R Uhungarumlaut -40
-KPX R Umacron -40
-KPX R Uogonek -40
-KPX R Uring -40
-KPX R V -80
-KPX R W -55
-KPX R Y -65
-KPX R Yacute -65
-KPX R Ydieresis -65
-KPX Racute O -40
-KPX Racute Oacute -40
-KPX Racute Ocircumflex -40
-KPX Racute Odieresis -40
-KPX Racute Ograve -40
-KPX Racute Ohungarumlaut -40
-KPX Racute Omacron -40
-KPX Racute Oslash -40
-KPX Racute Otilde -40
-KPX Racute T -60
-KPX Racute Tcaron -60
-KPX Racute Tcommaaccent -60
-KPX Racute U -40
-KPX Racute Uacute -40
-KPX Racute Ucircumflex -40
-KPX Racute Udieresis -40
-KPX Racute Ugrave -40
-KPX Racute Uhungarumlaut -40
-KPX Racute Umacron -40
-KPX Racute Uogonek -40
-KPX Racute Uring -40
-KPX Racute V -80
-KPX Racute W -55
-KPX Racute Y -65
-KPX Racute Yacute -65
-KPX Racute Ydieresis -65
-KPX Rcaron O -40
-KPX Rcaron Oacute -40
-KPX Rcaron Ocircumflex -40
-KPX Rcaron Odieresis -40
-KPX Rcaron Ograve -40
-KPX Rcaron Ohungarumlaut -40
-KPX Rcaron Omacron -40
-KPX Rcaron Oslash -40
-KPX Rcaron Otilde -40
-KPX Rcaron T -60
-KPX Rcaron Tcaron -60
-KPX Rcaron Tcommaaccent -60
-KPX Rcaron U -40
-KPX Rcaron Uacute -40
-KPX Rcaron Ucircumflex -40
-KPX Rcaron Udieresis -40
-KPX Rcaron Ugrave -40
-KPX Rcaron Uhungarumlaut -40
-KPX Rcaron Umacron -40
-KPX Rcaron Uogonek -40
-KPX Rcaron Uring -40
-KPX Rcaron V -80
-KPX Rcaron W -55
-KPX Rcaron Y -65
-KPX Rcaron Yacute -65
-KPX Rcaron Ydieresis -65
-KPX Rcommaaccent O -40
-KPX Rcommaaccent Oacute -40
-KPX Rcommaaccent Ocircumflex -40
-KPX Rcommaaccent Odieresis -40
-KPX Rcommaaccent Ograve -40
-KPX Rcommaaccent Ohungarumlaut -40
-KPX Rcommaaccent Omacron -40
-KPX Rcommaaccent Oslash -40
-KPX Rcommaaccent Otilde -40
-KPX Rcommaaccent T -60
-KPX Rcommaaccent Tcaron -60
-KPX Rcommaaccent Tcommaaccent -60
-KPX Rcommaaccent U -40
-KPX Rcommaaccent Uacute -40
-KPX Rcommaaccent Ucircumflex -40
-KPX Rcommaaccent Udieresis -40
-KPX Rcommaaccent Ugrave -40
-KPX Rcommaaccent Uhungarumlaut -40
-KPX Rcommaaccent Umacron -40
-KPX Rcommaaccent Uogonek -40
-KPX Rcommaaccent Uring -40
-KPX Rcommaaccent V -80
-KPX Rcommaaccent W -55
-KPX Rcommaaccent Y -65
-KPX Rcommaaccent Yacute -65
-KPX Rcommaaccent Ydieresis -65
-KPX T A -93
-KPX T Aacute -93
-KPX T Abreve -93
-KPX T Acircumflex -93
-KPX T Adieresis -93
-KPX T Agrave -93
-KPX T Amacron -93
-KPX T Aogonek -93
-KPX T Aring -93
-KPX T Atilde -93
-KPX T O -18
-KPX T Oacute -18
-KPX T Ocircumflex -18
-KPX T Odieresis -18
-KPX T Ograve -18
-KPX T Ohungarumlaut -18
-KPX T Omacron -18
-KPX T Oslash -18
-KPX T Otilde -18
-KPX T a -80
-KPX T aacute -80
-KPX T abreve -80
-KPX T acircumflex -80
-KPX T adieresis -40
-KPX T agrave -40
-KPX T amacron -40
-KPX T aogonek -80
-KPX T aring -80
-KPX T atilde -40
-KPX T colon -50
-KPX T comma -74
-KPX T e -70
-KPX T eacute -70
-KPX T ecaron -70
-KPX T ecircumflex -70
-KPX T edieresis -30
-KPX T edotaccent -70
-KPX T egrave -70
-KPX T emacron -30
-KPX T eogonek -70
-KPX T hyphen -92
-KPX T i -35
-KPX T iacute -35
-KPX T iogonek -35
-KPX T o -80
-KPX T oacute -80
-KPX T ocircumflex -80
-KPX T odieresis -80
-KPX T ograve -80
-KPX T ohungarumlaut -80
-KPX T omacron -80
-KPX T oslash -80
-KPX T otilde -80
-KPX T period -74
-KPX T r -35
-KPX T racute -35
-KPX T rcaron -35
-KPX T rcommaaccent -35
-KPX T semicolon -55
-KPX T u -45
-KPX T uacute -45
-KPX T ucircumflex -45
-KPX T udieresis -45
-KPX T ugrave -45
-KPX T uhungarumlaut -45
-KPX T umacron -45
-KPX T uogonek -45
-KPX T uring -45
-KPX T w -80
-KPX T y -80
-KPX T yacute -80
-KPX T ydieresis -80
-KPX Tcaron A -93
-KPX Tcaron Aacute -93
-KPX Tcaron Abreve -93
-KPX Tcaron Acircumflex -93
-KPX Tcaron Adieresis -93
-KPX Tcaron Agrave -93
-KPX Tcaron Amacron -93
-KPX Tcaron Aogonek -93
-KPX Tcaron Aring -93
-KPX Tcaron Atilde -93
-KPX Tcaron O -18
-KPX Tcaron Oacute -18
-KPX Tcaron Ocircumflex -18
-KPX Tcaron Odieresis -18
-KPX Tcaron Ograve -18
-KPX Tcaron Ohungarumlaut -18
-KPX Tcaron Omacron -18
-KPX Tcaron Oslash -18
-KPX Tcaron Otilde -18
-KPX Tcaron a -80
-KPX Tcaron aacute -80
-KPX Tcaron abreve -80
-KPX Tcaron acircumflex -80
-KPX Tcaron adieresis -40
-KPX Tcaron agrave -40
-KPX Tcaron amacron -40
-KPX Tcaron aogonek -80
-KPX Tcaron aring -80
-KPX Tcaron atilde -40
-KPX Tcaron colon -50
-KPX Tcaron comma -74
-KPX Tcaron e -70
-KPX Tcaron eacute -70
-KPX Tcaron ecaron -70
-KPX Tcaron ecircumflex -30
-KPX Tcaron edieresis -30
-KPX Tcaron edotaccent -70
-KPX Tcaron egrave -70
-KPX Tcaron emacron -30
-KPX Tcaron eogonek -70
-KPX Tcaron hyphen -92
-KPX Tcaron i -35
-KPX Tcaron iacute -35
-KPX Tcaron iogonek -35
-KPX Tcaron o -80
-KPX Tcaron oacute -80
-KPX Tcaron ocircumflex -80
-KPX Tcaron odieresis -80
-KPX Tcaron ograve -80
-KPX Tcaron ohungarumlaut -80
-KPX Tcaron omacron -80
-KPX Tcaron oslash -80
-KPX Tcaron otilde -80
-KPX Tcaron period -74
-KPX Tcaron r -35
-KPX Tcaron racute -35
-KPX Tcaron rcaron -35
-KPX Tcaron rcommaaccent -35
-KPX Tcaron semicolon -55
-KPX Tcaron u -45
-KPX Tcaron uacute -45
-KPX Tcaron ucircumflex -45
-KPX Tcaron udieresis -45
-KPX Tcaron ugrave -45
-KPX Tcaron uhungarumlaut -45
-KPX Tcaron umacron -45
-KPX Tcaron uogonek -45
-KPX Tcaron uring -45
-KPX Tcaron w -80
-KPX Tcaron y -80
-KPX Tcaron yacute -80
-KPX Tcaron ydieresis -80
-KPX Tcommaaccent A -93
-KPX Tcommaaccent Aacute -93
-KPX Tcommaaccent Abreve -93
-KPX Tcommaaccent Acircumflex -93
-KPX Tcommaaccent Adieresis -93
-KPX Tcommaaccent Agrave -93
-KPX Tcommaaccent Amacron -93
-KPX Tcommaaccent Aogonek -93
-KPX Tcommaaccent Aring -93
-KPX Tcommaaccent Atilde -93
-KPX Tcommaaccent O -18
-KPX Tcommaaccent Oacute -18
-KPX Tcommaaccent Ocircumflex -18
-KPX Tcommaaccent Odieresis -18
-KPX Tcommaaccent Ograve -18
-KPX Tcommaaccent Ohungarumlaut -18
-KPX Tcommaaccent Omacron -18
-KPX Tcommaaccent Oslash -18
-KPX Tcommaaccent Otilde -18
-KPX Tcommaaccent a -80
-KPX Tcommaaccent aacute -80
-KPX Tcommaaccent abreve -80
-KPX Tcommaaccent acircumflex -80
-KPX Tcommaaccent adieresis -40
-KPX Tcommaaccent agrave -40
-KPX Tcommaaccent amacron -40
-KPX Tcommaaccent aogonek -80
-KPX Tcommaaccent aring -80
-KPX Tcommaaccent atilde -40
-KPX Tcommaaccent colon -50
-KPX Tcommaaccent comma -74
-KPX Tcommaaccent e -70
-KPX Tcommaaccent eacute -70
-KPX Tcommaaccent ecaron -70
-KPX Tcommaaccent ecircumflex -30
-KPX Tcommaaccent edieresis -30
-KPX Tcommaaccent edotaccent -70
-KPX Tcommaaccent egrave -30
-KPX Tcommaaccent emacron -70
-KPX Tcommaaccent eogonek -70
-KPX Tcommaaccent hyphen -92
-KPX Tcommaaccent i -35
-KPX Tcommaaccent iacute -35
-KPX Tcommaaccent iogonek -35
-KPX Tcommaaccent o -80
-KPX Tcommaaccent oacute -80
-KPX Tcommaaccent ocircumflex -80
-KPX Tcommaaccent odieresis -80
-KPX Tcommaaccent ograve -80
-KPX Tcommaaccent ohungarumlaut -80
-KPX Tcommaaccent omacron -80
-KPX Tcommaaccent oslash -80
-KPX Tcommaaccent otilde -80
-KPX Tcommaaccent period -74
-KPX Tcommaaccent r -35
-KPX Tcommaaccent racute -35
-KPX Tcommaaccent rcaron -35
-KPX Tcommaaccent rcommaaccent -35
-KPX Tcommaaccent semicolon -55
-KPX Tcommaaccent u -45
-KPX Tcommaaccent uacute -45
-KPX Tcommaaccent ucircumflex -45
-KPX Tcommaaccent udieresis -45
-KPX Tcommaaccent ugrave -45
-KPX Tcommaaccent uhungarumlaut -45
-KPX Tcommaaccent umacron -45
-KPX Tcommaaccent uogonek -45
-KPX Tcommaaccent uring -45
-KPX Tcommaaccent w -80
-KPX Tcommaaccent y -80
-KPX Tcommaaccent yacute -80
-KPX Tcommaaccent ydieresis -80
-KPX U A -40
-KPX U Aacute -40
-KPX U Abreve -40
-KPX U Acircumflex -40
-KPX U Adieresis -40
-KPX U Agrave -40
-KPX U Amacron -40
-KPX U Aogonek -40
-KPX U Aring -40
-KPX U Atilde -40
-KPX Uacute A -40
-KPX Uacute Aacute -40
-KPX Uacute Abreve -40
-KPX Uacute Acircumflex -40
-KPX Uacute Adieresis -40
-KPX Uacute Agrave -40
-KPX Uacute Amacron -40
-KPX Uacute Aogonek -40
-KPX Uacute Aring -40
-KPX Uacute Atilde -40
-KPX Ucircumflex A -40
-KPX Ucircumflex Aacute -40
-KPX Ucircumflex Abreve -40
-KPX Ucircumflex Acircumflex -40
-KPX Ucircumflex Adieresis -40
-KPX Ucircumflex Agrave -40
-KPX Ucircumflex Amacron -40
-KPX Ucircumflex Aogonek -40
-KPX Ucircumflex Aring -40
-KPX Ucircumflex Atilde -40
-KPX Udieresis A -40
-KPX Udieresis Aacute -40
-KPX Udieresis Abreve -40
-KPX Udieresis Acircumflex -40
-KPX Udieresis Adieresis -40
-KPX Udieresis Agrave -40
-KPX Udieresis Amacron -40
-KPX Udieresis Aogonek -40
-KPX Udieresis Aring -40
-KPX Udieresis Atilde -40
-KPX Ugrave A -40
-KPX Ugrave Aacute -40
-KPX Ugrave Abreve -40
-KPX Ugrave Acircumflex -40
-KPX Ugrave Adieresis -40
-KPX Ugrave Agrave -40
-KPX Ugrave Amacron -40
-KPX Ugrave Aogonek -40
-KPX Ugrave Aring -40
-KPX Ugrave Atilde -40
-KPX Uhungarumlaut A -40
-KPX Uhungarumlaut Aacute -40
-KPX Uhungarumlaut Abreve -40
-KPX Uhungarumlaut Acircumflex -40
-KPX Uhungarumlaut Adieresis -40
-KPX Uhungarumlaut Agrave -40
-KPX Uhungarumlaut Amacron -40
-KPX Uhungarumlaut Aogonek -40
-KPX Uhungarumlaut Aring -40
-KPX Uhungarumlaut Atilde -40
-KPX Umacron A -40
-KPX Umacron Aacute -40
-KPX Umacron Abreve -40
-KPX Umacron Acircumflex -40
-KPX Umacron Adieresis -40
-KPX Umacron Agrave -40
-KPX Umacron Amacron -40
-KPX Umacron Aogonek -40
-KPX Umacron Aring -40
-KPX Umacron Atilde -40
-KPX Uogonek A -40
-KPX Uogonek Aacute -40
-KPX Uogonek Abreve -40
-KPX Uogonek Acircumflex -40
-KPX Uogonek Adieresis -40
-KPX Uogonek Agrave -40
-KPX Uogonek Amacron -40
-KPX Uogonek Aogonek -40
-KPX Uogonek Aring -40
-KPX Uogonek Atilde -40
-KPX Uring A -40
-KPX Uring Aacute -40
-KPX Uring Abreve -40
-KPX Uring Acircumflex -40
-KPX Uring Adieresis -40
-KPX Uring Agrave -40
-KPX Uring Amacron -40
-KPX Uring Aogonek -40
-KPX Uring Aring -40
-KPX Uring Atilde -40
-KPX V A -135
-KPX V Aacute -135
-KPX V Abreve -135
-KPX V Acircumflex -135
-KPX V Adieresis -135
-KPX V Agrave -135
-KPX V Amacron -135
-KPX V Aogonek -135
-KPX V Aring -135
-KPX V Atilde -135
-KPX V G -15
-KPX V Gbreve -15
-KPX V Gcommaaccent -15
-KPX V O -40
-KPX V Oacute -40
-KPX V Ocircumflex -40
-KPX V Odieresis -40
-KPX V Ograve -40
-KPX V Ohungarumlaut -40
-KPX V Omacron -40
-KPX V Oslash -40
-KPX V Otilde -40
-KPX V a -111
-KPX V aacute -111
-KPX V abreve -111
-KPX V acircumflex -71
-KPX V adieresis -71
-KPX V agrave -71
-KPX V amacron -71
-KPX V aogonek -111
-KPX V aring -111
-KPX V atilde -71
-KPX V colon -74
-KPX V comma -129
-KPX V e -111
-KPX V eacute -111
-KPX V ecaron -71
-KPX V ecircumflex -71
-KPX V edieresis -71
-KPX V edotaccent -111
-KPX V egrave -71
-KPX V emacron -71
-KPX V eogonek -111
-KPX V hyphen -100
-KPX V i -60
-KPX V iacute -60
-KPX V icircumflex -20
-KPX V idieresis -20
-KPX V igrave -20
-KPX V imacron -20
-KPX V iogonek -60
-KPX V o -129
-KPX V oacute -129
-KPX V ocircumflex -129
-KPX V odieresis -89
-KPX V ograve -89
-KPX V ohungarumlaut -129
-KPX V omacron -89
-KPX V oslash -129
-KPX V otilde -89
-KPX V period -129
-KPX V semicolon -74
-KPX V u -75
-KPX V uacute -75
-KPX V ucircumflex -75
-KPX V udieresis -75
-KPX V ugrave -75
-KPX V uhungarumlaut -75
-KPX V umacron -75
-KPX V uogonek -75
-KPX V uring -75
-KPX W A -120
-KPX W Aacute -120
-KPX W Abreve -120
-KPX W Acircumflex -120
-KPX W Adieresis -120
-KPX W Agrave -120
-KPX W Amacron -120
-KPX W Aogonek -120
-KPX W Aring -120
-KPX W Atilde -120
-KPX W O -10
-KPX W Oacute -10
-KPX W Ocircumflex -10
-KPX W Odieresis -10
-KPX W Ograve -10
-KPX W Ohungarumlaut -10
-KPX W Omacron -10
-KPX W Oslash -10
-KPX W Otilde -10
-KPX W a -80
-KPX W aacute -80
-KPX W abreve -80
-KPX W acircumflex -80
-KPX W adieresis -80
-KPX W agrave -80
-KPX W amacron -80
-KPX W aogonek -80
-KPX W aring -80
-KPX W atilde -80
-KPX W colon -37
-KPX W comma -92
-KPX W e -80
-KPX W eacute -80
-KPX W ecaron -80
-KPX W ecircumflex -80
-KPX W edieresis -40
-KPX W edotaccent -80
-KPX W egrave -40
-KPX W emacron -40
-KPX W eogonek -80
-KPX W hyphen -65
-KPX W i -40
-KPX W iacute -40
-KPX W iogonek -40
-KPX W o -80
-KPX W oacute -80
-KPX W ocircumflex -80
-KPX W odieresis -80
-KPX W ograve -80
-KPX W ohungarumlaut -80
-KPX W omacron -80
-KPX W oslash -80
-KPX W otilde -80
-KPX W period -92
-KPX W semicolon -37
-KPX W u -50
-KPX W uacute -50
-KPX W ucircumflex -50
-KPX W udieresis -50
-KPX W ugrave -50
-KPX W uhungarumlaut -50
-KPX W umacron -50
-KPX W uogonek -50
-KPX W uring -50
-KPX W y -73
-KPX W yacute -73
-KPX W ydieresis -73
-KPX Y A -120
-KPX Y Aacute -120
-KPX Y Abreve -120
-KPX Y Acircumflex -120
-KPX Y Adieresis -120
-KPX Y Agrave -120
-KPX Y Amacron -120
-KPX Y Aogonek -120
-KPX Y Aring -120
-KPX Y Atilde -120
-KPX Y O -30
-KPX Y Oacute -30
-KPX Y Ocircumflex -30
-KPX Y Odieresis -30
-KPX Y Ograve -30
-KPX Y Ohungarumlaut -30
-KPX Y Omacron -30
-KPX Y Oslash -30
-KPX Y Otilde -30
-KPX Y a -100
-KPX Y aacute -100
-KPX Y abreve -100
-KPX Y acircumflex -100
-KPX Y adieresis -60
-KPX Y agrave -60
-KPX Y amacron -60
-KPX Y aogonek -100
-KPX Y aring -100
-KPX Y atilde -60
-KPX Y colon -92
-KPX Y comma -129
-KPX Y e -100
-KPX Y eacute -100
-KPX Y ecaron -100
-KPX Y ecircumflex -100
-KPX Y edieresis -60
-KPX Y edotaccent -100
-KPX Y egrave -60
-KPX Y emacron -60
-KPX Y eogonek -100
-KPX Y hyphen -111
-KPX Y i -55
-KPX Y iacute -55
-KPX Y iogonek -55
-KPX Y o -110
-KPX Y oacute -110
-KPX Y ocircumflex -110
-KPX Y odieresis -70
-KPX Y ograve -70
-KPX Y ohungarumlaut -110
-KPX Y omacron -70
-KPX Y oslash -110
-KPX Y otilde -70
-KPX Y period -129
-KPX Y semicolon -92
-KPX Y u -111
-KPX Y uacute -111
-KPX Y ucircumflex -111
-KPX Y udieresis -71
-KPX Y ugrave -71
-KPX Y uhungarumlaut -111
-KPX Y umacron -71
-KPX Y uogonek -111
-KPX Y uring -111
-KPX Yacute A -120
-KPX Yacute Aacute -120
-KPX Yacute Abreve -120
-KPX Yacute Acircumflex -120
-KPX Yacute Adieresis -120
-KPX Yacute Agrave -120
-KPX Yacute Amacron -120
-KPX Yacute Aogonek -120
-KPX Yacute Aring -120
-KPX Yacute Atilde -120
-KPX Yacute O -30
-KPX Yacute Oacute -30
-KPX Yacute Ocircumflex -30
-KPX Yacute Odieresis -30
-KPX Yacute Ograve -30
-KPX Yacute Ohungarumlaut -30
-KPX Yacute Omacron -30
-KPX Yacute Oslash -30
-KPX Yacute Otilde -30
-KPX Yacute a -100
-KPX Yacute aacute -100
-KPX Yacute abreve -100
-KPX Yacute acircumflex -100
-KPX Yacute adieresis -60
-KPX Yacute agrave -60
-KPX Yacute amacron -60
-KPX Yacute aogonek -100
-KPX Yacute aring -100
-KPX Yacute atilde -60
-KPX Yacute colon -92
-KPX Yacute comma -129
-KPX Yacute e -100
-KPX Yacute eacute -100
-KPX Yacute ecaron -100
-KPX Yacute ecircumflex -100
-KPX Yacute edieresis -60
-KPX Yacute edotaccent -100
-KPX Yacute egrave -60
-KPX Yacute emacron -60
-KPX Yacute eogonek -100
-KPX Yacute hyphen -111
-KPX Yacute i -55
-KPX Yacute iacute -55
-KPX Yacute iogonek -55
-KPX Yacute o -110
-KPX Yacute oacute -110
-KPX Yacute ocircumflex -110
-KPX Yacute odieresis -70
-KPX Yacute ograve -70
-KPX Yacute ohungarumlaut -110
-KPX Yacute omacron -70
-KPX Yacute oslash -110
-KPX Yacute otilde -70
-KPX Yacute period -129
-KPX Yacute semicolon -92
-KPX Yacute u -111
-KPX Yacute uacute -111
-KPX Yacute ucircumflex -111
-KPX Yacute udieresis -71
-KPX Yacute ugrave -71
-KPX Yacute uhungarumlaut -111
-KPX Yacute umacron -71
-KPX Yacute uogonek -111
-KPX Yacute uring -111
-KPX Ydieresis A -120
-KPX Ydieresis Aacute -120
-KPX Ydieresis Abreve -120
-KPX Ydieresis Acircumflex -120
-KPX Ydieresis Adieresis -120
-KPX Ydieresis Agrave -120
-KPX Ydieresis Amacron -120
-KPX Ydieresis Aogonek -120
-KPX Ydieresis Aring -120
-KPX Ydieresis Atilde -120
-KPX Ydieresis O -30
-KPX Ydieresis Oacute -30
-KPX Ydieresis Ocircumflex -30
-KPX Ydieresis Odieresis -30
-KPX Ydieresis Ograve -30
-KPX Ydieresis Ohungarumlaut -30
-KPX Ydieresis Omacron -30
-KPX Ydieresis Oslash -30
-KPX Ydieresis Otilde -30
-KPX Ydieresis a -100
-KPX Ydieresis aacute -100
-KPX Ydieresis abreve -100
-KPX Ydieresis acircumflex -100
-KPX Ydieresis adieresis -60
-KPX Ydieresis agrave -60
-KPX Ydieresis amacron -60
-KPX Ydieresis aogonek -100
-KPX Ydieresis aring -100
-KPX Ydieresis atilde -100
-KPX Ydieresis colon -92
-KPX Ydieresis comma -129
-KPX Ydieresis e -100
-KPX Ydieresis eacute -100
-KPX Ydieresis ecaron -100
-KPX Ydieresis ecircumflex -100
-KPX Ydieresis edieresis -60
-KPX Ydieresis edotaccent -100
-KPX Ydieresis egrave -60
-KPX Ydieresis emacron -60
-KPX Ydieresis eogonek -100
-KPX Ydieresis hyphen -111
-KPX Ydieresis i -55
-KPX Ydieresis iacute -55
-KPX Ydieresis iogonek -55
-KPX Ydieresis o -110
-KPX Ydieresis oacute -110
-KPX Ydieresis ocircumflex -110
-KPX Ydieresis odieresis -70
-KPX Ydieresis ograve -70
-KPX Ydieresis ohungarumlaut -110
-KPX Ydieresis omacron -70
-KPX Ydieresis oslash -110
-KPX Ydieresis otilde -70
-KPX Ydieresis period -129
-KPX Ydieresis semicolon -92
-KPX Ydieresis u -111
-KPX Ydieresis uacute -111
-KPX Ydieresis ucircumflex -111
-KPX Ydieresis udieresis -71
-KPX Ydieresis ugrave -71
-KPX Ydieresis uhungarumlaut -111
-KPX Ydieresis umacron -71
-KPX Ydieresis uogonek -111
-KPX Ydieresis uring -111
-KPX a v -20
-KPX a w -15
-KPX aacute v -20
-KPX aacute w -15
-KPX abreve v -20
-KPX abreve w -15
-KPX acircumflex v -20
-KPX acircumflex w -15
-KPX adieresis v -20
-KPX adieresis w -15
-KPX agrave v -20
-KPX agrave w -15
-KPX amacron v -20
-KPX amacron w -15
-KPX aogonek v -20
-KPX aogonek w -15
-KPX aring v -20
-KPX aring w -15
-KPX atilde v -20
-KPX atilde w -15
-KPX b period -40
-KPX b u -20
-KPX b uacute -20
-KPX b ucircumflex -20
-KPX b udieresis -20
-KPX b ugrave -20
-KPX b uhungarumlaut -20
-KPX b umacron -20
-KPX b uogonek -20
-KPX b uring -20
-KPX b v -15
-KPX c y -15
-KPX c yacute -15
-KPX c ydieresis -15
-KPX cacute y -15
-KPX cacute yacute -15
-KPX cacute ydieresis -15
-KPX ccaron y -15
-KPX ccaron yacute -15
-KPX ccaron ydieresis -15
-KPX ccedilla y -15
-KPX ccedilla yacute -15
-KPX ccedilla ydieresis -15
-KPX comma quotedblright -70
-KPX comma quoteright -70
-KPX e g -15
-KPX e gbreve -15
-KPX e gcommaaccent -15
-KPX e v -25
-KPX e w -25
-KPX e x -15
-KPX e y -15
-KPX e yacute -15
-KPX e ydieresis -15
-KPX eacute g -15
-KPX eacute gbreve -15
-KPX eacute gcommaaccent -15
-KPX eacute v -25
-KPX eacute w -25
-KPX eacute x -15
-KPX eacute y -15
-KPX eacute yacute -15
-KPX eacute ydieresis -15
-KPX ecaron g -15
-KPX ecaron gbreve -15
-KPX ecaron gcommaaccent -15
-KPX ecaron v -25
-KPX ecaron w -25
-KPX ecaron x -15
-KPX ecaron y -15
-KPX ecaron yacute -15
-KPX ecaron ydieresis -15
-KPX ecircumflex g -15
-KPX ecircumflex gbreve -15
-KPX ecircumflex gcommaaccent -15
-KPX ecircumflex v -25
-KPX ecircumflex w -25
-KPX ecircumflex x -15
-KPX ecircumflex y -15
-KPX ecircumflex yacute -15
-KPX ecircumflex ydieresis -15
-KPX edieresis g -15
-KPX edieresis gbreve -15
-KPX edieresis gcommaaccent -15
-KPX edieresis v -25
-KPX edieresis w -25
-KPX edieresis x -15
-KPX edieresis y -15
-KPX edieresis yacute -15
-KPX edieresis ydieresis -15
-KPX edotaccent g -15
-KPX edotaccent gbreve -15
-KPX edotaccent gcommaaccent -15
-KPX edotaccent v -25
-KPX edotaccent w -25
-KPX edotaccent x -15
-KPX edotaccent y -15
-KPX edotaccent yacute -15
-KPX edotaccent ydieresis -15
-KPX egrave g -15
-KPX egrave gbreve -15
-KPX egrave gcommaaccent -15
-KPX egrave v -25
-KPX egrave w -25
-KPX egrave x -15
-KPX egrave y -15
-KPX egrave yacute -15
-KPX egrave ydieresis -15
-KPX emacron g -15
-KPX emacron gbreve -15
-KPX emacron gcommaaccent -15
-KPX emacron v -25
-KPX emacron w -25
-KPX emacron x -15
-KPX emacron y -15
-KPX emacron yacute -15
-KPX emacron ydieresis -15
-KPX eogonek g -15
-KPX eogonek gbreve -15
-KPX eogonek gcommaaccent -15
-KPX eogonek v -25
-KPX eogonek w -25
-KPX eogonek x -15
-KPX eogonek y -15
-KPX eogonek yacute -15
-KPX eogonek ydieresis -15
-KPX f a -10
-KPX f aacute -10
-KPX f abreve -10
-KPX f acircumflex -10
-KPX f adieresis -10
-KPX f agrave -10
-KPX f amacron -10
-KPX f aogonek -10
-KPX f aring -10
-KPX f atilde -10
-KPX f dotlessi -50
-KPX f f -25
-KPX f i -20
-KPX f iacute -20
-KPX f quoteright 55
-KPX g a -5
-KPX g aacute -5
-KPX g abreve -5
-KPX g acircumflex -5
-KPX g adieresis -5
-KPX g agrave -5
-KPX g amacron -5
-KPX g aogonek -5
-KPX g aring -5
-KPX g atilde -5
-KPX gbreve a -5
-KPX gbreve aacute -5
-KPX gbreve abreve -5
-KPX gbreve acircumflex -5
-KPX gbreve adieresis -5
-KPX gbreve agrave -5
-KPX gbreve amacron -5
-KPX gbreve aogonek -5
-KPX gbreve aring -5
-KPX gbreve atilde -5
-KPX gcommaaccent a -5
-KPX gcommaaccent aacute -5
-KPX gcommaaccent abreve -5
-KPX gcommaaccent acircumflex -5
-KPX gcommaaccent adieresis -5
-KPX gcommaaccent agrave -5
-KPX gcommaaccent amacron -5
-KPX gcommaaccent aogonek -5
-KPX gcommaaccent aring -5
-KPX gcommaaccent atilde -5
-KPX h y -5
-KPX h yacute -5
-KPX h ydieresis -5
-KPX i v -25
-KPX iacute v -25
-KPX icircumflex v -25
-KPX idieresis v -25
-KPX igrave v -25
-KPX imacron v -25
-KPX iogonek v -25
-KPX k e -10
-KPX k eacute -10
-KPX k ecaron -10
-KPX k ecircumflex -10
-KPX k edieresis -10
-KPX k edotaccent -10
-KPX k egrave -10
-KPX k emacron -10
-KPX k eogonek -10
-KPX k o -10
-KPX k oacute -10
-KPX k ocircumflex -10
-KPX k odieresis -10
-KPX k ograve -10
-KPX k ohungarumlaut -10
-KPX k omacron -10
-KPX k oslash -10
-KPX k otilde -10
-KPX k y -15
-KPX k yacute -15
-KPX k ydieresis -15
-KPX kcommaaccent e -10
-KPX kcommaaccent eacute -10
-KPX kcommaaccent ecaron -10
-KPX kcommaaccent ecircumflex -10
-KPX kcommaaccent edieresis -10
-KPX kcommaaccent edotaccent -10
-KPX kcommaaccent egrave -10
-KPX kcommaaccent emacron -10
-KPX kcommaaccent eogonek -10
-KPX kcommaaccent o -10
-KPX kcommaaccent oacute -10
-KPX kcommaaccent ocircumflex -10
-KPX kcommaaccent odieresis -10
-KPX kcommaaccent ograve -10
-KPX kcommaaccent ohungarumlaut -10
-KPX kcommaaccent omacron -10
-KPX kcommaaccent oslash -10
-KPX kcommaaccent otilde -10
-KPX kcommaaccent y -15
-KPX kcommaaccent yacute -15
-KPX kcommaaccent ydieresis -15
-KPX l w -10
-KPX lacute w -10
-KPX lcommaaccent w -10
-KPX lslash w -10
-KPX n v -40
-KPX n y -15
-KPX n yacute -15
-KPX n ydieresis -15
-KPX nacute v -40
-KPX nacute y -15
-KPX nacute yacute -15
-KPX nacute ydieresis -15
-KPX ncaron v -40
-KPX ncaron y -15
-KPX ncaron yacute -15
-KPX ncaron ydieresis -15
-KPX ncommaaccent v -40
-KPX ncommaaccent y -15
-KPX ncommaaccent yacute -15
-KPX ncommaaccent ydieresis -15
-KPX ntilde v -40
-KPX ntilde y -15
-KPX ntilde yacute -15
-KPX ntilde ydieresis -15
-KPX o v -15
-KPX o w -25
-KPX o y -10
-KPX o yacute -10
-KPX o ydieresis -10
-KPX oacute v -15
-KPX oacute w -25
-KPX oacute y -10
-KPX oacute yacute -10
-KPX oacute ydieresis -10
-KPX ocircumflex v -15
-KPX ocircumflex w -25
-KPX ocircumflex y -10
-KPX ocircumflex yacute -10
-KPX ocircumflex ydieresis -10
-KPX odieresis v -15
-KPX odieresis w -25
-KPX odieresis y -10
-KPX odieresis yacute -10
-KPX odieresis ydieresis -10
-KPX ograve v -15
-KPX ograve w -25
-KPX ograve y -10
-KPX ograve yacute -10
-KPX ograve ydieresis -10
-KPX ohungarumlaut v -15
-KPX ohungarumlaut w -25
-KPX ohungarumlaut y -10
-KPX ohungarumlaut yacute -10
-KPX ohungarumlaut ydieresis -10
-KPX omacron v -15
-KPX omacron w -25
-KPX omacron y -10
-KPX omacron yacute -10
-KPX omacron ydieresis -10
-KPX oslash v -15
-KPX oslash w -25
-KPX oslash y -10
-KPX oslash yacute -10
-KPX oslash ydieresis -10
-KPX otilde v -15
-KPX otilde w -25
-KPX otilde y -10
-KPX otilde yacute -10
-KPX otilde ydieresis -10
-KPX p y -10
-KPX p yacute -10
-KPX p ydieresis -10
-KPX period quotedblright -70
-KPX period quoteright -70
-KPX quotedblleft A -80
-KPX quotedblleft Aacute -80
-KPX quotedblleft Abreve -80
-KPX quotedblleft Acircumflex -80
-KPX quotedblleft Adieresis -80
-KPX quotedblleft Agrave -80
-KPX quotedblleft Amacron -80
-KPX quotedblleft Aogonek -80
-KPX quotedblleft Aring -80
-KPX quotedblleft Atilde -80
-KPX quoteleft A -80
-KPX quoteleft Aacute -80
-KPX quoteleft Abreve -80
-KPX quoteleft Acircumflex -80
-KPX quoteleft Adieresis -80
-KPX quoteleft Agrave -80
-KPX quoteleft Amacron -80
-KPX quoteleft Aogonek -80
-KPX quoteleft Aring -80
-KPX quoteleft Atilde -80
-KPX quoteleft quoteleft -74
-KPX quoteright d -50
-KPX quoteright dcroat -50
-KPX quoteright l -10
-KPX quoteright lacute -10
-KPX quoteright lcommaaccent -10
-KPX quoteright lslash -10
-KPX quoteright quoteright -74
-KPX quoteright r -50
-KPX quoteright racute -50
-KPX quoteright rcaron -50
-KPX quoteright rcommaaccent -50
-KPX quoteright s -55
-KPX quoteright sacute -55
-KPX quoteright scaron -55
-KPX quoteright scedilla -55
-KPX quoteright scommaaccent -55
-KPX quoteright space -74
-KPX quoteright t -18
-KPX quoteright tcommaaccent -18
-KPX quoteright v -50
-KPX r comma -40
-KPX r g -18
-KPX r gbreve -18
-KPX r gcommaaccent -18
-KPX r hyphen -20
-KPX r period -55
-KPX racute comma -40
-KPX racute g -18
-KPX racute gbreve -18
-KPX racute gcommaaccent -18
-KPX racute hyphen -20
-KPX racute period -55
-KPX rcaron comma -40
-KPX rcaron g -18
-KPX rcaron gbreve -18
-KPX rcaron gcommaaccent -18
-KPX rcaron hyphen -20
-KPX rcaron period -55
-KPX rcommaaccent comma -40
-KPX rcommaaccent g -18
-KPX rcommaaccent gbreve -18
-KPX rcommaaccent gcommaaccent -18
-KPX rcommaaccent hyphen -20
-KPX rcommaaccent period -55
-KPX space A -55
-KPX space Aacute -55
-KPX space Abreve -55
-KPX space Acircumflex -55
-KPX space Adieresis -55
-KPX space Agrave -55
-KPX space Amacron -55
-KPX space Aogonek -55
-KPX space Aring -55
-KPX space Atilde -55
-KPX space T -18
-KPX space Tcaron -18
-KPX space Tcommaaccent -18
-KPX space V -50
-KPX space W -30
-KPX space Y -90
-KPX space Yacute -90
-KPX space Ydieresis -90
-KPX v a -25
-KPX v aacute -25
-KPX v abreve -25
-KPX v acircumflex -25
-KPX v adieresis -25
-KPX v agrave -25
-KPX v amacron -25
-KPX v aogonek -25
-KPX v aring -25
-KPX v atilde -25
-KPX v comma -65
-KPX v e -15
-KPX v eacute -15
-KPX v ecaron -15
-KPX v ecircumflex -15
-KPX v edieresis -15
-KPX v edotaccent -15
-KPX v egrave -15
-KPX v emacron -15
-KPX v eogonek -15
-KPX v o -20
-KPX v oacute -20
-KPX v ocircumflex -20
-KPX v odieresis -20
-KPX v ograve -20
-KPX v ohungarumlaut -20
-KPX v omacron -20
-KPX v oslash -20
-KPX v otilde -20
-KPX v period -65
-KPX w a -10
-KPX w aacute -10
-KPX w abreve -10
-KPX w acircumflex -10
-KPX w adieresis -10
-KPX w agrave -10
-KPX w amacron -10
-KPX w aogonek -10
-KPX w aring -10
-KPX w atilde -10
-KPX w comma -65
-KPX w o -10
-KPX w oacute -10
-KPX w ocircumflex -10
-KPX w odieresis -10
-KPX w ograve -10
-KPX w ohungarumlaut -10
-KPX w omacron -10
-KPX w oslash -10
-KPX w otilde -10
-KPX w period -65
-KPX x e -15
-KPX x eacute -15
-KPX x ecaron -15
-KPX x ecircumflex -15
-KPX x edieresis -15
-KPX x edotaccent -15
-KPX x egrave -15
-KPX x emacron -15
-KPX x eogonek -15
-KPX y comma -65
-KPX y period -65
-KPX yacute comma -65
-KPX yacute period -65
-KPX ydieresis comma -65
-KPX ydieresis period -65
-EndKernPairs
-EndKernData
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/ZapfDingbats.afm b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/ZapfDingbats.afm
deleted file mode 100644
index b2745053e4..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/ZapfDingbats.afm
+++ /dev/null
@@ -1,225 +0,0 @@
-StartFontMetrics 4.1
-Comment Copyright (c) 1985, 1987, 1988, 1989, 1997 Adobe Systems Incorporated. All Rights Reserved.
-Comment Creation Date: Thu May 1 15:14:13 1997
-Comment UniqueID 43082
-Comment VMusage 45775 55535
-FontName ZapfDingbats
-FullName ITC Zapf Dingbats
-FamilyName ZapfDingbats
-Weight Medium
-ItalicAngle 0
-IsFixedPitch false
-CharacterSet Special
-FontBBox -1 -143 981 820
-UnderlinePosition -100
-UnderlineThickness 50
-Version 002.000
-Notice Copyright (c) 1985, 1987, 1988, 1989, 1997 Adobe Systems Incorporated. All Rights Reserved.ITC Zapf Dingbats is a registered trademark of International Typeface Corporation.
-EncodingScheme FontSpecific
-StdHW 28
-StdVW 90
-StartCharMetrics 202
-C 32 ; WX 278 ; N space ; B 0 0 0 0 ;
-C 33 ; WX 974 ; N a1 ; B 35 72 939 621 ;
-C 34 ; WX 961 ; N a2 ; B 35 81 927 611 ;
-C 35 ; WX 974 ; N a202 ; B 35 72 939 621 ;
-C 36 ; WX 980 ; N a3 ; B 35 0 945 692 ;
-C 37 ; WX 719 ; N a4 ; B 34 139 685 566 ;
-C 38 ; WX 789 ; N a5 ; B 35 -14 755 705 ;
-C 39 ; WX 790 ; N a119 ; B 35 -14 755 705 ;
-C 40 ; WX 791 ; N a118 ; B 35 -13 761 705 ;
-C 41 ; WX 690 ; N a117 ; B 34 138 655 553 ;
-C 42 ; WX 960 ; N a11 ; B 35 123 925 568 ;
-C 43 ; WX 939 ; N a12 ; B 35 134 904 559 ;
-C 44 ; WX 549 ; N a13 ; B 29 -11 516 705 ;
-C 45 ; WX 855 ; N a14 ; B 34 59 820 632 ;
-C 46 ; WX 911 ; N a15 ; B 35 50 876 642 ;
-C 47 ; WX 933 ; N a16 ; B 35 139 899 550 ;
-C 48 ; WX 911 ; N a105 ; B 35 50 876 642 ;
-C 49 ; WX 945 ; N a17 ; B 35 139 909 553 ;
-C 50 ; WX 974 ; N a18 ; B 35 104 938 587 ;
-C 51 ; WX 755 ; N a19 ; B 34 -13 721 705 ;
-C 52 ; WX 846 ; N a20 ; B 36 -14 811 705 ;
-C 53 ; WX 762 ; N a21 ; B 35 0 727 692 ;
-C 54 ; WX 761 ; N a22 ; B 35 0 727 692 ;
-C 55 ; WX 571 ; N a23 ; B -1 -68 571 661 ;
-C 56 ; WX 677 ; N a24 ; B 36 -13 642 705 ;
-C 57 ; WX 763 ; N a25 ; B 35 0 728 692 ;
-C 58 ; WX 760 ; N a26 ; B 35 0 726 692 ;
-C 59 ; WX 759 ; N a27 ; B 35 0 725 692 ;
-C 60 ; WX 754 ; N a28 ; B 35 0 720 692 ;
-C 61 ; WX 494 ; N a6 ; B 35 0 460 692 ;
-C 62 ; WX 552 ; N a7 ; B 35 0 517 692 ;
-C 63 ; WX 537 ; N a8 ; B 35 0 503 692 ;
-C 64 ; WX 577 ; N a9 ; B 35 96 542 596 ;
-C 65 ; WX 692 ; N a10 ; B 35 -14 657 705 ;
-C 66 ; WX 786 ; N a29 ; B 35 -14 751 705 ;
-C 67 ; WX 788 ; N a30 ; B 35 -14 752 705 ;
-C 68 ; WX 788 ; N a31 ; B 35 -14 753 705 ;
-C 69 ; WX 790 ; N a32 ; B 35 -14 756 705 ;
-C 70 ; WX 793 ; N a33 ; B 35 -13 759 705 ;
-C 71 ; WX 794 ; N a34 ; B 35 -13 759 705 ;
-C 72 ; WX 816 ; N a35 ; B 35 -14 782 705 ;
-C 73 ; WX 823 ; N a36 ; B 35 -14 787 705 ;
-C 74 ; WX 789 ; N a37 ; B 35 -14 754 705 ;
-C 75 ; WX 841 ; N a38 ; B 35 -14 807 705 ;
-C 76 ; WX 823 ; N a39 ; B 35 -14 789 705 ;
-C 77 ; WX 833 ; N a40 ; B 35 -14 798 705 ;
-C 78 ; WX 816 ; N a41 ; B 35 -13 782 705 ;
-C 79 ; WX 831 ; N a42 ; B 35 -14 796 705 ;
-C 80 ; WX 923 ; N a43 ; B 35 -14 888 705 ;
-C 81 ; WX 744 ; N a44 ; B 35 0 710 692 ;
-C 82 ; WX 723 ; N a45 ; B 35 0 688 692 ;
-C 83 ; WX 749 ; N a46 ; B 35 0 714 692 ;
-C 84 ; WX 790 ; N a47 ; B 34 -14 756 705 ;
-C 85 ; WX 792 ; N a48 ; B 35 -14 758 705 ;
-C 86 ; WX 695 ; N a49 ; B 35 -14 661 706 ;
-C 87 ; WX 776 ; N a50 ; B 35 -6 741 699 ;
-C 88 ; WX 768 ; N a51 ; B 35 -7 734 699 ;
-C 89 ; WX 792 ; N a52 ; B 35 -14 757 705 ;
-C 90 ; WX 759 ; N a53 ; B 35 0 725 692 ;
-C 91 ; WX 707 ; N a54 ; B 35 -13 672 704 ;
-C 92 ; WX 708 ; N a55 ; B 35 -14 672 705 ;
-C 93 ; WX 682 ; N a56 ; B 35 -14 647 705 ;
-C 94 ; WX 701 ; N a57 ; B 35 -14 666 705 ;
-C 95 ; WX 826 ; N a58 ; B 35 -14 791 705 ;
-C 96 ; WX 815 ; N a59 ; B 35 -14 780 705 ;
-C 97 ; WX 789 ; N a60 ; B 35 -14 754 705 ;
-C 98 ; WX 789 ; N a61 ; B 35 -14 754 705 ;
-C 99 ; WX 707 ; N a62 ; B 34 -14 673 705 ;
-C 100 ; WX 687 ; N a63 ; B 36 0 651 692 ;
-C 101 ; WX 696 ; N a64 ; B 35 0 661 691 ;
-C 102 ; WX 689 ; N a65 ; B 35 0 655 692 ;
-C 103 ; WX 786 ; N a66 ; B 34 -14 751 705 ;
-C 104 ; WX 787 ; N a67 ; B 35 -14 752 705 ;
-C 105 ; WX 713 ; N a68 ; B 35 -14 678 705 ;
-C 106 ; WX 791 ; N a69 ; B 35 -14 756 705 ;
-C 107 ; WX 785 ; N a70 ; B 36 -14 751 705 ;
-C 108 ; WX 791 ; N a71 ; B 35 -14 757 705 ;
-C 109 ; WX 873 ; N a72 ; B 35 -14 838 705 ;
-C 110 ; WX 761 ; N a73 ; B 35 0 726 692 ;
-C 111 ; WX 762 ; N a74 ; B 35 0 727 692 ;
-C 112 ; WX 762 ; N a203 ; B 35 0 727 692 ;
-C 113 ; WX 759 ; N a75 ; B 35 0 725 692 ;
-C 114 ; WX 759 ; N a204 ; B 35 0 725 692 ;
-C 115 ; WX 892 ; N a76 ; B 35 0 858 705 ;
-C 116 ; WX 892 ; N a77 ; B 35 -14 858 692 ;
-C 117 ; WX 788 ; N a78 ; B 35 -14 754 705 ;
-C 118 ; WX 784 ; N a79 ; B 35 -14 749 705 ;
-C 119 ; WX 438 ; N a81 ; B 35 -14 403 705 ;
-C 120 ; WX 138 ; N a82 ; B 35 0 104 692 ;
-C 121 ; WX 277 ; N a83 ; B 35 0 242 692 ;
-C 122 ; WX 415 ; N a84 ; B 35 0 380 692 ;
-C 123 ; WX 392 ; N a97 ; B 35 263 357 705 ;
-C 124 ; WX 392 ; N a98 ; B 34 263 357 705 ;
-C 125 ; WX 668 ; N a99 ; B 35 263 633 705 ;
-C 126 ; WX 668 ; N a100 ; B 36 263 634 705 ;
-C 128 ; WX 390 ; N a89 ; B 35 -14 356 705 ;
-C 129 ; WX 390 ; N a90 ; B 35 -14 355 705 ;
-C 130 ; WX 317 ; N a93 ; B 35 0 283 692 ;
-C 131 ; WX 317 ; N a94 ; B 35 0 283 692 ;
-C 132 ; WX 276 ; N a91 ; B 35 0 242 692 ;
-C 133 ; WX 276 ; N a92 ; B 35 0 242 692 ;
-C 134 ; WX 509 ; N a205 ; B 35 0 475 692 ;
-C 135 ; WX 509 ; N a85 ; B 35 0 475 692 ;
-C 136 ; WX 410 ; N a206 ; B 35 0 375 692 ;
-C 137 ; WX 410 ; N a86 ; B 35 0 375 692 ;
-C 138 ; WX 234 ; N a87 ; B 35 -14 199 705 ;
-C 139 ; WX 234 ; N a88 ; B 35 -14 199 705 ;
-C 140 ; WX 334 ; N a95 ; B 35 0 299 692 ;
-C 141 ; WX 334 ; N a96 ; B 35 0 299 692 ;
-C 161 ; WX 732 ; N a101 ; B 35 -143 697 806 ;
-C 162 ; WX 544 ; N a102 ; B 56 -14 488 706 ;
-C 163 ; WX 544 ; N a103 ; B 34 -14 508 705 ;
-C 164 ; WX 910 ; N a104 ; B 35 40 875 651 ;
-C 165 ; WX 667 ; N a106 ; B 35 -14 633 705 ;
-C 166 ; WX 760 ; N a107 ; B 35 -14 726 705 ;
-C 167 ; WX 760 ; N a108 ; B 0 121 758 569 ;
-C 168 ; WX 776 ; N a112 ; B 35 0 741 705 ;
-C 169 ; WX 595 ; N a111 ; B 34 -14 560 705 ;
-C 170 ; WX 694 ; N a110 ; B 35 -14 659 705 ;
-C 171 ; WX 626 ; N a109 ; B 34 0 591 705 ;
-C 172 ; WX 788 ; N a120 ; B 35 -14 754 705 ;
-C 173 ; WX 788 ; N a121 ; B 35 -14 754 705 ;
-C 174 ; WX 788 ; N a122 ; B 35 -14 754 705 ;
-C 175 ; WX 788 ; N a123 ; B 35 -14 754 705 ;
-C 176 ; WX 788 ; N a124 ; B 35 -14 754 705 ;
-C 177 ; WX 788 ; N a125 ; B 35 -14 754 705 ;
-C 178 ; WX 788 ; N a126 ; B 35 -14 754 705 ;
-C 179 ; WX 788 ; N a127 ; B 35 -14 754 705 ;
-C 180 ; WX 788 ; N a128 ; B 35 -14 754 705 ;
-C 181 ; WX 788 ; N a129 ; B 35 -14 754 705 ;
-C 182 ; WX 788 ; N a130 ; B 35 -14 754 705 ;
-C 183 ; WX 788 ; N a131 ; B 35 -14 754 705 ;
-C 184 ; WX 788 ; N a132 ; B 35 -14 754 705 ;
-C 185 ; WX 788 ; N a133 ; B 35 -14 754 705 ;
-C 186 ; WX 788 ; N a134 ; B 35 -14 754 705 ;
-C 187 ; WX 788 ; N a135 ; B 35 -14 754 705 ;
-C 188 ; WX 788 ; N a136 ; B 35 -14 754 705 ;
-C 189 ; WX 788 ; N a137 ; B 35 -14 754 705 ;
-C 190 ; WX 788 ; N a138 ; B 35 -14 754 705 ;
-C 191 ; WX 788 ; N a139 ; B 35 -14 754 705 ;
-C 192 ; WX 788 ; N a140 ; B 35 -14 754 705 ;
-C 193 ; WX 788 ; N a141 ; B 35 -14 754 705 ;
-C 194 ; WX 788 ; N a142 ; B 35 -14 754 705 ;
-C 195 ; WX 788 ; N a143 ; B 35 -14 754 705 ;
-C 196 ; WX 788 ; N a144 ; B 35 -14 754 705 ;
-C 197 ; WX 788 ; N a145 ; B 35 -14 754 705 ;
-C 198 ; WX 788 ; N a146 ; B 35 -14 754 705 ;
-C 199 ; WX 788 ; N a147 ; B 35 -14 754 705 ;
-C 200 ; WX 788 ; N a148 ; B 35 -14 754 705 ;
-C 201 ; WX 788 ; N a149 ; B 35 -14 754 705 ;
-C 202 ; WX 788 ; N a150 ; B 35 -14 754 705 ;
-C 203 ; WX 788 ; N a151 ; B 35 -14 754 705 ;
-C 204 ; WX 788 ; N a152 ; B 35 -14 754 705 ;
-C 205 ; WX 788 ; N a153 ; B 35 -14 754 705 ;
-C 206 ; WX 788 ; N a154 ; B 35 -14 754 705 ;
-C 207 ; WX 788 ; N a155 ; B 35 -14 754 705 ;
-C 208 ; WX 788 ; N a156 ; B 35 -14 754 705 ;
-C 209 ; WX 788 ; N a157 ; B 35 -14 754 705 ;
-C 210 ; WX 788 ; N a158 ; B 35 -14 754 705 ;
-C 211 ; WX 788 ; N a159 ; B 35 -14 754 705 ;
-C 212 ; WX 894 ; N a160 ; B 35 58 860 634 ;
-C 213 ; WX 838 ; N a161 ; B 35 152 803 540 ;
-C 214 ; WX 1016 ; N a163 ; B 34 152 981 540 ;
-C 215 ; WX 458 ; N a164 ; B 35 -127 422 820 ;
-C 216 ; WX 748 ; N a196 ; B 35 94 698 597 ;
-C 217 ; WX 924 ; N a165 ; B 35 140 890 552 ;
-C 218 ; WX 748 ; N a192 ; B 35 94 698 597 ;
-C 219 ; WX 918 ; N a166 ; B 35 166 884 526 ;
-C 220 ; WX 927 ; N a167 ; B 35 32 892 660 ;
-C 221 ; WX 928 ; N a168 ; B 35 129 891 562 ;
-C 222 ; WX 928 ; N a169 ; B 35 128 893 563 ;
-C 223 ; WX 834 ; N a170 ; B 35 155 799 537 ;
-C 224 ; WX 873 ; N a171 ; B 35 93 838 599 ;
-C 225 ; WX 828 ; N a172 ; B 35 104 791 588 ;
-C 226 ; WX 924 ; N a173 ; B 35 98 889 594 ;
-C 227 ; WX 924 ; N a162 ; B 35 98 889 594 ;
-C 228 ; WX 917 ; N a174 ; B 35 0 882 692 ;
-C 229 ; WX 930 ; N a175 ; B 35 84 896 608 ;
-C 230 ; WX 931 ; N a176 ; B 35 84 896 608 ;
-C 231 ; WX 463 ; N a177 ; B 35 -99 429 791 ;
-C 232 ; WX 883 ; N a178 ; B 35 71 848 623 ;
-C 233 ; WX 836 ; N a179 ; B 35 44 802 648 ;
-C 234 ; WX 836 ; N a193 ; B 35 44 802 648 ;
-C 235 ; WX 867 ; N a180 ; B 35 101 832 591 ;
-C 236 ; WX 867 ; N a199 ; B 35 101 832 591 ;
-C 237 ; WX 696 ; N a181 ; B 35 44 661 648 ;
-C 238 ; WX 696 ; N a200 ; B 35 44 661 648 ;
-C 239 ; WX 874 ; N a182 ; B 35 77 840 619 ;
-C 241 ; WX 874 ; N a201 ; B 35 73 840 615 ;
-C 242 ; WX 760 ; N a183 ; B 35 0 725 692 ;
-C 243 ; WX 946 ; N a184 ; B 35 160 911 533 ;
-C 244 ; WX 771 ; N a197 ; B 34 37 736 655 ;
-C 245 ; WX 865 ; N a185 ; B 35 207 830 481 ;
-C 246 ; WX 771 ; N a194 ; B 34 37 736 655 ;
-C 247 ; WX 888 ; N a198 ; B 34 -19 853 712 ;
-C 248 ; WX 967 ; N a186 ; B 35 124 932 568 ;
-C 249 ; WX 888 ; N a195 ; B 34 -19 853 712 ;
-C 250 ; WX 831 ; N a187 ; B 35 113 796 579 ;
-C 251 ; WX 873 ; N a188 ; B 36 118 838 578 ;
-C 252 ; WX 927 ; N a189 ; B 35 150 891 542 ;
-C 253 ; WX 970 ; N a190 ; B 35 76 931 616 ;
-C 254 ; WX 918 ; N a191 ; B 34 99 884 593 ;
-EndCharMetrics
-EndFontMetrics
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/readme.txt b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/readme.txt
deleted file mode 100644
index 047ae70a17..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/pdfcorefonts/readme.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-Font Metrics for the 14 PDF Core Fonts
-======================================
-
-This directory contains font metrics for the 14 PDF Core Fonts,
-downloaded from Adobe. The title and this paragraph were added by
-Matplotlib developers. The download URL was
-<http://partners.adobe.com/public/developer/font/index.html>.
-
-This file and the 14 PostScript(R) AFM files it accompanies may be used, copied,
-and distributed for any purpose and without charge, with or without modification,
-provided that all copyright notices are retained; that the AFM files are not
-distributed without this file; that all modifications to this file or any of
-the AFM files are prominently noted in the modified file(s); and that this
-paragraph is not modified. Adobe Systems has no responsibility or obligation
-to support the use of the AFM files.
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Bold.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Bold.ttf
deleted file mode 100644
index 1f22f07c99..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Bold.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSans-BoldOblique.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSans-BoldOblique.ttf
deleted file mode 100644
index b8886cb5e0..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSans-BoldOblique.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Oblique.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Oblique.ttf
deleted file mode 100644
index 300ea68b6c..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSans-Oblique.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf
deleted file mode 100644
index 5267218852..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansDisplay.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansDisplay.ttf
deleted file mode 100644
index 36758a2e70..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansDisplay.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Bold.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Bold.ttf
deleted file mode 100644
index cbcdd31d60..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Bold.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-BoldOblique.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-BoldOblique.ttf
deleted file mode 100644
index da513440a2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-BoldOblique.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Oblique.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Oblique.ttf
deleted file mode 100644
index 0185ce95a5..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Oblique.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono.ttf
deleted file mode 100644
index 278cd78139..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSansMono.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Bold.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Bold.ttf
deleted file mode 100644
index d683eb282b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Bold.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-BoldItalic.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-BoldItalic.ttf
deleted file mode 100644
index b4831f7654..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-BoldItalic.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Italic.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Italic.ttf
deleted file mode 100644
index 45b508b829..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Italic.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerif.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerif.ttf
deleted file mode 100644
index 39dd3946d3..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerif.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerifDisplay.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerifDisplay.ttf
deleted file mode 100644
index 1623714d22..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/DejaVuSerifDisplay.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/LICENSE_DEJAVU b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/LICENSE_DEJAVU
deleted file mode 100644
index 254e2cc42a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/LICENSE_DEJAVU
+++ /dev/null
@@ -1,99 +0,0 @@
-Fonts are (c) Bitstream (see below). DejaVu changes are in public domain.
-Glyphs imported from Arev fonts are (c) Tavmjong Bah (see below)
-
-Bitstream Vera Fonts Copyright
-------------------------------
-
-Copyright (c) 2003 by Bitstream, Inc. All Rights Reserved. Bitstream Vera is
-a trademark of Bitstream, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of the fonts accompanying this license ("Fonts") and associated
-documentation files (the "Font Software"), to reproduce and distribute the
-Font Software, including without limitation the rights to use, copy, merge,
-publish, distribute, and/or sell copies of the Font Software, and to permit
-persons to whom the Font Software is furnished to do so, subject to the
-following conditions:
-
-The above copyright and trademark notices and this permission notice shall
-be included in all copies of one or more of the Font Software typefaces.
-
-The Font Software may be modified, altered, or added to, and in particular
-the designs of glyphs or characters in the Fonts may be modified and
-additional glyphs or characters may be added to the Fonts, only if the fonts
-are renamed to names not containing either the words "Bitstream" or the word
-"Vera".
-
-This License becomes null and void to the extent applicable to Fonts or Font
-Software that has been modified and is distributed under the "Bitstream
-Vera" names.
-
-The Font Software may be sold as part of a larger software package but no
-copy of one or more of the Font Software typefaces may be sold by itself.
-
-THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF COPYRIGHT, PATENT,
-TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL BITSTREAM OR THE GNOME
-FOUNDATION BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING
-ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
-THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM OTHER DEALINGS IN THE
-FONT SOFTWARE.
-
-Except as contained in this notice, the names of Gnome, the Gnome
-Foundation, and Bitstream Inc., shall not be used in advertising or
-otherwise to promote the sale, use or other dealings in this Font Software
-without prior written authorization from the Gnome Foundation or Bitstream
-Inc., respectively. For further information, contact: fonts at gnome dot
-org.
-
-Arev Fonts Copyright
-------------------------------
-
-Copyright (c) 2006 by Tavmjong Bah. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of the fonts accompanying this license ("Fonts") and
-associated documentation files (the "Font Software"), to reproduce
-and distribute the modifications to the Bitstream Vera Font Software,
-including without limitation the rights to use, copy, merge, publish,
-distribute, and/or sell copies of the Font Software, and to permit
-persons to whom the Font Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright and trademark notices and this permission notice
-shall be included in all copies of one or more of the Font Software
-typefaces.
-
-The Font Software may be modified, altered, or added to, and in
-particular the designs of glyphs or characters in the Fonts may be
-modified and additional glyphs or characters may be added to the
-Fonts, only if the fonts are renamed to names not containing either
-the words "Tavmjong Bah" or the word "Arev".
-
-This License becomes null and void to the extent applicable to Fonts
-or Font Software that has been modified and is distributed under the
-"Tavmjong Bah Arev" names.
-
-The Font Software may be sold as part of a larger software package but
-no copy of one or more of the Font Software typefaces may be sold by
-itself.
-
-THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL
-TAVMJONG BAH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
-DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
-OTHER DEALINGS IN THE FONT SOFTWARE.
-
-Except as contained in this notice, the name of Tavmjong Bah shall not
-be used in advertising or otherwise to promote the sale, use or other
-dealings in this Font Software without prior written authorization
-from Tavmjong Bah. For further information, contact: tavmjong @ free
-. fr.
-
-$Id: LICENSE 2133 2007-11-28 02:46:28Z lechimp $
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/LICENSE_STIX b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/LICENSE_STIX
deleted file mode 100644
index 6034d94748..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/LICENSE_STIX
+++ /dev/null
@@ -1,124 +0,0 @@
-The STIX fonts distributed with matplotlib have been modified from
-their canonical form. They have been converted from OTF to TTF format
-using Fontforge and this script:
-
- #!/usr/bin/env fontforge
- i=1
- while ( i<$argc )
- Open($argv[i])
- Generate($argv[i]:r + ".ttf")
- i = i+1
- endloop
-
-The original STIX Font License begins below.
-
------------------------------------------------------------
-
-STIX Font License
-
-24 May 2010
-
-Copyright (c) 2001-2010 by the STI Pub Companies, consisting of the American
-Institute of Physics, the American Chemical Society, the American Mathematical
-Society, the American Physical Society, Elsevier, Inc., and The Institute of
-Electrical and Electronic Engineers, Inc. (www.stixfonts.org), with Reserved
-Font Name STIX Fonts, STIX Fonts (TM) is a trademark of The Institute of
-Electrical and Electronics Engineers, Inc.
-
-Portions copyright (c) 1998-2003 by MicroPress, Inc. (www.micropress-inc.com),
-with Reserved Font Name TM Math. To obtain additional mathematical fonts, please
-contact MicroPress, Inc., 68-30 Harrow Street, Forest Hills, NY 11375, USA,
-Phone: (718) 575-1816.
-
-Portions copyright (c) 1990 by Elsevier, Inc.
-
-This Font Software is licensed under the SIL Open Font License, Version 1.1.
-This license is copied below, and is also available with a FAQ at:
-https://scripts.sil.org/OFL
-
------------------------------------------------------------
-SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
------------------------------------------------------------
-
-PREAMBLE
-The goals of the Open Font License (OFL) are to stimulate worldwide
-development of collaborative font projects, to support the font creation
-efforts of academic and linguistic communities, and to provide a free and
-open framework in which fonts may be shared and improved in partnership
-with others.
-
-The OFL allows the licensed fonts to be used, studied, modified and
-redistributed freely as long as they are not sold by themselves. The
-fonts, including any derivative works, can be bundled, embedded,
-redistributed and/or sold with any software provided that any reserved
-names are not used by derivative works. The fonts and derivatives,
-however, cannot be released under any other type of license. The
-requirement for fonts to remain under this license does not apply
-to any document created using the fonts or their derivatives.
-
-DEFINITIONS
-"Font Software" refers to the set of files released by the Copyright
-Holder(s) under this license and clearly marked as such. This may
-include source files, build scripts and documentation.
-
-"Reserved Font Name" refers to any names specified as such after the
-copyright statement(s).
-
-"Original Version" refers to the collection of Font Software components as
-distributed by the Copyright Holder(s).
-
-"Modified Version" refers to any derivative made by adding to, deleting,
-or substituting -- in part or in whole -- any of the components of the
-Original Version, by changing formats or by porting the Font Software to a
-new environment.
-
-"Author" refers to any designer, engineer, programmer, technical
-writer or other person who contributed to the Font Software.
-
-PERMISSION & CONDITIONS
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of the Font Software, to use, study, copy, merge, embed, modify,
-redistribute, and sell modified and unmodified copies of the Font
-Software, subject to the following conditions:
-
-1) Neither the Font Software nor any of its individual components,
-in Original or Modified Versions, may be sold by itself.
-
-2) Original or Modified Versions of the Font Software may be bundled,
-redistributed and/or sold with any software, provided that each copy
-contains the above copyright notice and this license. These can be
-included either as stand-alone text files, human-readable headers or
-in the appropriate machine-readable metadata fields within text or
-binary files as long as those fields can be easily viewed by the user.
-
-3) No Modified Version of the Font Software may use the Reserved Font
-Name(s) unless explicit written permission is granted by the corresponding
-Copyright Holder. This restriction only applies to the primary font name as
-presented to the users.
-
-4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
-Software shall not be used to promote, endorse or advertise any
-Modified Version, except to acknowledge the contribution(s) of the
-Copyright Holder(s) and the Author(s) or with their explicit written
-permission.
-
-5) The Font Software, modified or unmodified, in part or in whole,
-must be distributed entirely under this license, and must not be
-distributed under any other license. The requirement for fonts to
-remain under this license does not apply to any document created
-using the Font Software.
-
-TERMINATION
-This license becomes null and void if any of the above conditions are
-not met.
-
-DISCLAIMER
-THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
-OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
-COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
-DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
-OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXGeneral.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXGeneral.ttf
deleted file mode 100644
index 8699400037..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXGeneral.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXGeneralBol.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXGeneralBol.ttf
deleted file mode 100644
index ba80b537eb..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXGeneralBol.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXGeneralBolIta.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXGeneralBolIta.ttf
deleted file mode 100644
index 5957dabb14..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXGeneralBolIta.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXGeneralItalic.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXGeneralItalic.ttf
deleted file mode 100644
index 2830b6b9a2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXGeneralItalic.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXNonUni.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXNonUni.ttf
deleted file mode 100644
index a70c797d09..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXNonUni.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXNonUniBol.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXNonUniBol.ttf
deleted file mode 100644
index ccbd9a6011..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXNonUniBol.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXNonUniBolIta.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXNonUniBolIta.ttf
deleted file mode 100644
index e75e09e6c0..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXNonUniBolIta.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXNonUniIta.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXNonUniIta.ttf
deleted file mode 100644
index c27d42fb25..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXNonUniIta.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizFiveSymReg.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizFiveSymReg.ttf
deleted file mode 100644
index f81717ec1d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizFiveSymReg.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizFourSymBol.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizFourSymBol.ttf
deleted file mode 100644
index 855dec9823..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizFourSymBol.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizFourSymReg.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizFourSymReg.ttf
deleted file mode 100644
index f955ca2ad1..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizFourSymReg.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymBol.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymBol.ttf
deleted file mode 100644
index 6ffd35778f..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymBol.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymReg.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymReg.ttf
deleted file mode 100644
index 01ed101cd4..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizOneSymReg.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymBol.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymBol.ttf
deleted file mode 100644
index 1ccf365e8f..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymBol.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymReg.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymReg.ttf
deleted file mode 100644
index bf2b66af76..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymReg.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymBol.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymBol.ttf
deleted file mode 100644
index bd5f93f0e4..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymBol.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymReg.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymReg.ttf
deleted file mode 100644
index 73b9930f6c..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymReg.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmb10.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmb10.ttf
deleted file mode 100644
index 189bdf0f0a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmb10.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmex10.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmex10.ttf
deleted file mode 100644
index e4b468dcd3..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmex10.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmmi10.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmmi10.ttf
deleted file mode 100644
index 8d32661041..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmmi10.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmr10.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmr10.ttf
deleted file mode 100644
index 8bc44966a8..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmr10.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmss10.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmss10.ttf
deleted file mode 100644
index ef70532c71..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmss10.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmsy10.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmsy10.ttf
deleted file mode 100644
index 45d8421a5b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmsy10.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmtt10.ttf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmtt10.ttf
deleted file mode 100644
index 15bdb68b3f..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/fonts/ttf/cmtt10.ttf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back-symbolic.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back-symbolic.svg
deleted file mode 100644
index a933ef8cdf..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back-symbolic.svg
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 65.144375 35.006875
-C 65.144375 32.425 63.43375 30.15125 60.703125 30.15125
-L 33.991875 30.15125
-L 45.105625 19.0375
-C 46.019375 18.12375 46.550625 16.87 46.550625 15.584375
-C 46.550625 14.288125 46.019375 13.034375 45.105625 12.13125
-L 42.258125 9.315625
-C 41.344375 8.4125 40.133125 7.88125 38.8475 7.88125
-C 37.55125 7.88125 36.2975 8.4125 35.394375 9.315625
-L 10.69125 33.986875
-C 9.82 34.900625 9.28875 36.14375 9.28875 37.44
-C 9.28875 38.725625 9.82 39.979375 10.69125 40.850625
-L 35.394375 65.59625
-C 36.2975 66.4675 37.55125 66.99875 38.8475 66.99875
-C 40.133125 66.99875 41.386875 66.4675 42.258125 65.59625
-L 45.105625 62.70625
-C 46.019375 61.835 46.550625 60.58125 46.550625 59.295625
-C 46.550625 58.01 46.019375 56.75625 45.105625 55.885
-L 33.991875 44.72875
-L 60.703125 44.72875
-C 63.43375 44.72875 65.144375 42.444375 65.144375 39.8625
-z
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back.pdf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back.pdf
deleted file mode 100644
index 79709d8f43..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back.pdf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back.png
deleted file mode 100644
index e3c4b58154..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back.svg
deleted file mode 100644
index a933ef8cdf..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back.svg
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 65.144375 35.006875
-C 65.144375 32.425 63.43375 30.15125 60.703125 30.15125
-L 33.991875 30.15125
-L 45.105625 19.0375
-C 46.019375 18.12375 46.550625 16.87 46.550625 15.584375
-C 46.550625 14.288125 46.019375 13.034375 45.105625 12.13125
-L 42.258125 9.315625
-C 41.344375 8.4125 40.133125 7.88125 38.8475 7.88125
-C 37.55125 7.88125 36.2975 8.4125 35.394375 9.315625
-L 10.69125 33.986875
-C 9.82 34.900625 9.28875 36.14375 9.28875 37.44
-C 9.28875 38.725625 9.82 39.979375 10.69125 40.850625
-L 35.394375 65.59625
-C 36.2975 66.4675 37.55125 66.99875 38.8475 66.99875
-C 40.133125 66.99875 41.386875 66.4675 42.258125 65.59625
-L 45.105625 62.70625
-C 46.019375 61.835 46.550625 60.58125 46.550625 59.295625
-C 46.550625 58.01 46.019375 56.75625 45.105625 55.885
-L 33.991875 44.72875
-L 60.703125 44.72875
-C 63.43375 44.72875 65.144375 42.444375 65.144375 39.8625
-z
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back_large.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back_large.png
deleted file mode 100644
index e44a70a9cd..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/back_large.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave-symbolic.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave-symbolic.svg
deleted file mode 100644
index ad8372d295..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave-symbolic.svg
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 21.4225 61.72875
-L 21.4225 47.161875
-L 50.566875 47.161875
-L 50.566875 61.72875
-z
-M 55.4225 61.72875
-L 55.4225 45.94
-C 55.4225 43.931875 53.796875 42.295625 51.78875 42.295625
-L 20.21125 42.295625
-C 18.203125 42.295625 16.566875 43.931875 16.566875 45.94
-L 16.566875 61.72875
-L 11.71125 61.72875
-L 11.71125 13.161875
-L 16.566875 13.161875
-L 16.566875 28.94
-C 16.566875 30.95875 18.203125 32.584375 20.21125 32.584375
-L 42.066875 32.584375
-C 44.085625 32.584375 45.71125 30.95875 45.71125 28.94
-L 45.71125 13.161875
-C 46.47625 13.161875 47.953125 13.7675 48.484375 14.29875
-L 59.14125 24.955625
-C 59.640625 25.455 60.28875 27.00625 60.28875 27.72875
-L 60.28875 61.72875
-z
-M 40.855625 26.5175
-C 40.855625 27.155 40.281875 27.72875 39.644375 27.72875
-L 32.355625 27.72875
-C 31.7075 27.72875 31.144375 27.155 31.144375 26.5175
-L 31.144375 14.373125
-C 31.144375 13.725 31.7075 13.161875 32.355625 13.161875
-L 39.644375 13.161875
-C 40.281875 13.161875 40.855625 13.725 40.855625 14.373125
-z
-M 65.144375 27.72875
-C 65.144375 25.720625 64.0075 22.9475 62.5625 21.5025
-L 51.9375 10.8775
-C 50.4925 9.443125 47.719375 8.295625 45.71125 8.295625
-L 10.5 8.295625
-C 8.491875 8.295625 6.855625 9.931875 6.855625 11.94
-L 6.855625 62.94
-C 6.855625 64.95875 8.491875 66.584375 10.5 66.584375
-L 61.5 66.584375
-C 63.508125 66.584375 65.144375 64.95875 65.144375 62.94
-z
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave.pdf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave.pdf
deleted file mode 100644
index 794a1152f6..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave.pdf
+++ /dev/null
@@ -1,70 +0,0 @@
-%PDF-1.4
-%
-1 0 obj
-<< /Pages 2 0 R /Type /Catalog >>
-endobj
-8 0 obj
-<< /ExtGState 4 0 R /Font 3 0 R /Pattern 5 0 R
-/ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /Shading 6 0 R
-/XObject 7 0 R >>
-endobj
-10 0 obj
-<< /Annots [ ] /Contents 9 0 R
-/Group << /CS /DeviceRGB /S /Transparency /Type /Group >>
-/MediaBox [ 0 0 72 72 ] /Parent 2 0 R /Resources 8 0 R /Type /Page >>
-endobj
-9 0 obj
-<< /Filter /FlateDecode /Length 11 0 R >>
-stream
-xuKn1 D:N@2A
- lj@|֧ob"y:wa<q<}|Ǜq?Mx ߍ^]U$>zȧ2y,ZN4_:b;P&ʮ)k2r#3ybc,ͫ+c*aT1&'޴
-Z-p"=\-X azݫDITb%\5QrZuz(T?PTRJw@f4JlWA|Z-AfHEm 6Lft"VS+Ȯ\,iv!Rf#F2ov#`:l%NvLEڵз]J=Hыa,5c `f=i0W`5E?u!7x2vkt ֱӂBa1Hwgս!H3͘?\
-endstream
-endobj
-11 0 obj
-500
-endobj
-3 0 obj
-<< >>
-endobj
-4 0 obj
-<< /A1 << /CA 0 /Type /ExtGState /ca 0 >>
-/A2 << /CA 1 /Type /ExtGState /ca 1 >> >>
-endobj
-5 0 obj
-<< >>
-endobj
-6 0 obj
-<< >>
-endobj
-7 0 obj
-<< >>
-endobj
-2 0 obj
-<< /Count 1 /Kids [ 10 0 R ] /Type /Pages >>
-endobj
-12 0 obj
-<< /CreationDate (D:20160601123507-04'00')
-/Creator (matplotlib 1.5.2rc2.post1933.dev0+gb775a26, http://matplotlib.org)
-/Producer (matplotlib pdf backend) >>
-endobj
-xref
-0 13
-0000000000 65535 f
-0000000016 00000 n
-0000001161 00000 n
-0000000978 00000 n
-0000000999 00000 n
-0000001098 00000 n
-0000001119 00000 n
-0000001140 00000 n
-0000000065 00000 n
-0000000383 00000 n
-0000000208 00000 n
-0000000958 00000 n
-0000001221 00000 n
-trailer
-<< /Info 12 0 R /Root 1 0 R /Size 13 >>
-startxref
-1395
-%%EOF
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave.png
deleted file mode 100644
index 919e40bf58..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave.svg
deleted file mode 100644
index ad8372d295..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave.svg
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 21.4225 61.72875
-L 21.4225 47.161875
-L 50.566875 47.161875
-L 50.566875 61.72875
-z
-M 55.4225 61.72875
-L 55.4225 45.94
-C 55.4225 43.931875 53.796875 42.295625 51.78875 42.295625
-L 20.21125 42.295625
-C 18.203125 42.295625 16.566875 43.931875 16.566875 45.94
-L 16.566875 61.72875
-L 11.71125 61.72875
-L 11.71125 13.161875
-L 16.566875 13.161875
-L 16.566875 28.94
-C 16.566875 30.95875 18.203125 32.584375 20.21125 32.584375
-L 42.066875 32.584375
-C 44.085625 32.584375 45.71125 30.95875 45.71125 28.94
-L 45.71125 13.161875
-C 46.47625 13.161875 47.953125 13.7675 48.484375 14.29875
-L 59.14125 24.955625
-C 59.640625 25.455 60.28875 27.00625 60.28875 27.72875
-L 60.28875 61.72875
-z
-M 40.855625 26.5175
-C 40.855625 27.155 40.281875 27.72875 39.644375 27.72875
-L 32.355625 27.72875
-C 31.7075 27.72875 31.144375 27.155 31.144375 26.5175
-L 31.144375 14.373125
-C 31.144375 13.725 31.7075 13.161875 32.355625 13.161875
-L 39.644375 13.161875
-C 40.281875 13.161875 40.855625 13.725 40.855625 14.373125
-z
-M 65.144375 27.72875
-C 65.144375 25.720625 64.0075 22.9475 62.5625 21.5025
-L 51.9375 10.8775
-C 50.4925 9.443125 47.719375 8.295625 45.71125 8.295625
-L 10.5 8.295625
-C 8.491875 8.295625 6.855625 9.931875 6.855625 11.94
-L 6.855625 62.94
-C 6.855625 64.95875 8.491875 66.584375 10.5 66.584375
-L 61.5 66.584375
-C 63.508125 66.584375 65.144375 64.95875 65.144375 62.94
-z
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave_large.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave_large.png
deleted file mode 100644
index a39b55a616..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/filesave_large.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward-symbolic.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward-symbolic.svg
deleted file mode 100644
index 1f40713606..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward-symbolic.svg
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 62.71125 37.44
-C 62.71125 36.14375 62.2225 34.900625 61.30875 34.01875
-L 36.605625 9.315625
-C 35.691875 8.4125 34.438125 7.88125 33.1525 7.88125
-C 31.866875 7.88125 30.645 8.4125 29.741875 9.315625
-L 26.894375 12.163125
-C 25.980625 13.034375 25.449375 14.288125 25.449375 15.584375
-C 25.449375 16.87 25.980625 18.12375 26.894375 18.995
-L 38.008125 30.15125
-L 11.296875 30.15125
-C 8.56625 30.15125 6.855625 32.425 6.855625 35.006875
-L 6.855625 39.8625
-C 6.855625 42.444375 8.56625 44.72875 11.296875 44.72875
-L 38.008125 44.72875
-L 26.894375 55.8425
-C 25.980625 56.75625 25.449375 58.01 25.449375 59.295625
-C 25.449375 60.58125 25.980625 61.835 26.894375 62.74875
-L 29.741875 65.59625
-C 30.645 66.4675 31.866875 66.99875 33.1525 66.99875
-C 34.438125 66.99875 35.691875 66.4675 36.605625 65.59625
-L 61.30875 40.893125
-C 62.2225 39.979375 62.71125 38.725625 62.71125 37.44
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward.pdf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward.pdf
deleted file mode 100644
index ce4a1bcb13..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward.pdf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward.png
deleted file mode 100644
index 59400feb49..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward.svg
deleted file mode 100644
index 1f40713606..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward.svg
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 62.71125 37.44
-C 62.71125 36.14375 62.2225 34.900625 61.30875 34.01875
-L 36.605625 9.315625
-C 35.691875 8.4125 34.438125 7.88125 33.1525 7.88125
-C 31.866875 7.88125 30.645 8.4125 29.741875 9.315625
-L 26.894375 12.163125
-C 25.980625 13.034375 25.449375 14.288125 25.449375 15.584375
-C 25.449375 16.87 25.980625 18.12375 26.894375 18.995
-L 38.008125 30.15125
-L 11.296875 30.15125
-C 8.56625 30.15125 6.855625 32.425 6.855625 35.006875
-L 6.855625 39.8625
-C 6.855625 42.444375 8.56625 44.72875 11.296875 44.72875
-L 38.008125 44.72875
-L 26.894375 55.8425
-C 25.980625 56.75625 25.449375 58.01 25.449375 59.295625
-C 25.449375 60.58125 25.980625 61.835 26.894375 62.74875
-L 29.741875 65.59625
-C 30.645 66.4675 31.866875 66.99875 33.1525 66.99875
-C 34.438125 66.99875 35.691875 66.4675 36.605625 65.59625
-L 61.30875 40.893125
-C 62.2225 39.979375 62.71125 38.725625 62.71125 37.44
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward_large.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward_large.png
deleted file mode 100644
index de65815bba..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/forward_large.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/hand.pdf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/hand.pdf
deleted file mode 100644
index 13088169ee..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/hand.pdf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/hand.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/hand.png
deleted file mode 100644
index d956c5fd72..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/hand.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/hand.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/hand.svg
deleted file mode 100644
index f246f51e57..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/hand.svg
+++ /dev/null
@@ -1,130 +0,0 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
-"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"
-[
- <!ATTLIST svg
- xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink">
-]>
-<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
-<svg
- xml:space="preserve"
- width="128pt"
- height="128pt"
- viewBox="0 0 507.946 507.946"
- id="svg49"
- sodipodi:version="0.27"
- sodipodi:docname="/mnt/windows/themes/Work/Blue-Sphere/edit_add.svg"
- sodipodi:docbase="/mnt/windows/themes/Work/Blue-Sphere/"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs
- id="defs62">
- <radialGradient
- id="radialGradient93"
- cx="218.9404"
- cy="219.7715"
- r="150.7063"
- fx="218.9404"
- fy="219.7715"
- gradientUnits="userSpaceOnUse"
- style="stroke:#000000;stroke-opacity:0.986014;stroke-width:0.981612;">
- <stop
- offset="0.000000"
- style="stop-color:#25a6ca;stop-opacity:1;"
- id="stop94" />
- <stop
- offset="1.000000"
- style="stop-color:#2ea6b9;stop-opacity:0.843137;"
- id="stop95" />
- </radialGradient>
- <radialGradient
- id="aigrd1"
- cx="218.9404"
- cy="219.7715"
- r="150.7063"
- fx="218.9404"
- fy="219.7715"
- gradientUnits="userSpaceOnUse"
- style="stroke:#000000;stroke-opacity:0.986014;stroke-width:0.981612;">
- <stop
- offset="0"
- style="stop-color:#73ffff;stroke:#000000;stroke-opacity:0.986014;stroke-width:0.981612;"
- id="stop53" />
- <stop
- offset="0.2809"
- style="stop-color:#2EA6B9;stroke:#000000;stroke-opacity:0.986014;stroke-width:0.981612;"
- id="stop54" />
- <stop
- offset="1"
- style="stop-color:#006b8b;stroke:#000000;stroke-opacity:0.986014;stroke-width:0.981612;"
- id="stop55" />
- </radialGradient>
- <linearGradient
- xlink:href="#aigrd1"
- id="linearGradient91"
- x1="-0.295723"
- y1="-0.264591"
- x2="0.622574"
- y2="0.365762"
- gradientUnits="objectBoundingBox"
- gradientTransform="matrix(0.996114,0,0,1.0039,0.496124,0.492186)"
- spreadMethod="pad" />
- <radialGradient
- xlink:href="#aigrd1"
- id="radialGradient92"
- cx="-8.09344e-05"
- cy="-7.68867e-05"
- fx="-8.09344e-05"
- fy="-7.68867e-05"
- r="0.789127"
- gradientUnits="objectBoundingBox"
- gradientTransform="matrix(1.06784,0,0,0.936469,0.342219,0.344712)"
- spreadMethod="pad" />
- <radialGradient
- xlink:href="#aigrd1"
- id="radialGradient1594"
- cx="1.37157e-25"
- cy="4.82783e-26"
- fx="1.37157e-25"
- fy="4.82783e-26"
- r="0.766358"
- gradientUnits="objectBoundingBox"
- gradientTransform="matrix(0.920679,-0.0285824,0.0336168,1.08511,0.373436,0.384854)"
- spreadMethod="pad" />
- </defs>
- <sodipodi:namedview
- id="base">
- <sodipodi:guide
- orientation="vertical"
- position="73.690849"
- id="sodipodi:guide127" />
- <sodipodi:guide
- orientation="vertical"
- position="101.148262"
- id="sodipodi:guide22" />
- <sodipodi:guide
- orientation="vertical"
- position="57.943218"
- id="sodipodi:guide23" />
- <sodipodi:guide
- orientation="vertical"
- position="30.889589"
- id="sodipodi:guide1593" />
- <sodipodi:guide
- orientation="horizontal"
- position="61.981071"
- id="sodipodi:guide1662" />
- </sodipodi:namedview>
- <path
- style="font-size:12;stroke:none;stroke-width:0.979268;stroke-opacity:0.986014;fill:#a4c9ee;fill-opacity:0.7;"
- d="M134.757,263.776c0,66.739,54.298,121.04,121.039,121.04c66.739,0,121.039-54.301,121.039-121.04c0-66.741-54.3-121.039-121.039-121.039c-66.741,0-121.039,54.298-121.039,121.039z"
- id="path51"
- transform="matrix(1.89511,0,0,1.91236,-231.458,-247.971)" />
- <path
- style="font-size:12;opacity:0.7;fill:url(#radialGradient1594);stroke:#1c6772;stroke-width:3.86972;stroke-opacity:0.988235;"
- d="M 246.07 280.233 L 164.809 283.331 C 151.201 283.417 145.222 268.094 145.5 257.812 C 144.854 249.607 148.852 232.142 164.429 230.994 L 244.216 229.011 L 241.953 153.421 C 241.796 138.289 257.675 128.71 267.404 129.607 C 278.285 128.656 290.708 137.925 291.688 150.233 L 293.169 229.483 L 373.02 227.669 C 386.182 226.629 395.032 239.215 395.06 249.825 C 395.088 260.706 394.781 274.802 375.372 275.169 L 295.928 277.056 L 298.139 360.561 C 298.225 371.398 285.104 379.184 276.67 378.906 C 268.465 379.552 248.69 376.94 247.542 361.363 L 246.07 280.233 z "
- id="path124"
- sodipodi:nodetypes="ccccccccccccccccc"
- transform="matrix(1.2536,0.0388772,-0.0388772,1.2536,-66.3537,-65.4059)" />
-</svg> \ No newline at end of file
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help-symbolic.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help-symbolic.svg
deleted file mode 100644
index 484bdbcbf6..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help-symbolic.svg
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 43.283438 55.959375
-C 43.283438 55.12 42.603437 54.44 41.764063 54.44
-L 32.658437 54.44
-C 31.829687 54.44 31.139063 55.12 31.139063 55.959375
-L 31.139063 65.065
-C 31.139063 65.904375 31.829687 66.584375 32.658437 66.584375
-L 41.764063 66.584375
-C 42.603437 66.584375 43.283438 65.904375 43.283438 65.065
-z
-M 55.279063 33.19
-C 55.279063 24.49875 46.173438 18.0175 38.045313 18.0175
-C 30.310312 18.0175 24.540937 21.31125 20.439687 28.11125
-C 20.025312 28.79125 20.174062 29.62 20.822187 30.119375
-L 27.048437 34.858125
-C 27.345937 35.049375 27.654062 35.16625 27.994062 35.16625
-C 28.408437 35.16625 28.865313 34.9325 29.173437 34.560625
-C 31.404688 31.745 32.318438 30.841875 33.232187 30.19375
-C 34.060937 29.62 35.622812 29.08875 37.333438 29.08875
-C 40.404062 29.08875 43.177188 30.990625 43.177188 33.115625
-C 43.177188 35.54875 41.955313 36.791875 39.033438 38.12
-C 35.697187 39.639375 31.139063 43.591875 31.139063 48.181875
-L 31.139063 49.8925
-C 31.139063 50.72125 31.670313 52.0175 32.509687 52.0175
-L 41.615313 52.0175
-C 42.486563 52.0175 43.134687 51.029375 43.134687 50.19
-C 43.134687 49.095625 44.537188 46.47125 46.779063 45.185625
-C 50.380938 43.166875 55.279063 40.404375 55.279063 33.19
-z
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help.pdf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help.pdf
deleted file mode 100644
index 38178d05b2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help.pdf
+++ /dev/null
@@ -1,68 +0,0 @@
-%PDF-1.4
-%
-1 0 obj
-<< /Pages 2 0 R /Type /Catalog >>
-endobj
-8 0 obj
-<< /ExtGState 4 0 R /Font 3 0 R /Pattern 5 0 R
-/ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /Shading 6 0 R
-/XObject 7 0 R >>
-endobj
-10 0 obj
-<< /Annots [ ] /Contents 9 0 R
-/Group << /CS /DeviceRGB /S /Transparency /Type /Group >>
-/MediaBox [ 0 0 72 72 ] /Parent 2 0 R /Resources 8 0 R /Type /Page >>
-endobj
-9 0 obj
-<< /Filter /FlateDecode /Length 11 0 R >>
-stream
-xm͎S1 yΏ!͞-bUf$x}^*8>>yoyg}my{2|nqH /|R*Jb\n(5sXZ;GL j;ݻ%e2z@ '\A {;cRv);Co(n{G4\`r$=,(8#JÚTLPՑ]\6d9lD Xxev@&Y=vrX:4צTOzsxZE5"c3B\i!runzͲ]xK&6ꠙCX(0i/V+5蜣F0 -<U9eYMQ"}Bmp꽶Vγ!Xbf9/0T"$b͎b^Cz*!3^?}YpWRKb\]Ԙm^~1չ9_=b
-endstream
-endobj
-11 0 obj
-549
-endobj
-3 0 obj
-<< >>
-endobj
-4 0 obj
-<< /A1 << /CA 0 /Type /ExtGState /ca 0 >>
-/A2 << /CA 1 /Type /ExtGState /ca 1 >> >>
-endobj
-5 0 obj
-<< >>
-endobj
-6 0 obj
-<< >>
-endobj
-7 0 obj
-<< >>
-endobj
-2 0 obj
-<< /Count 1 /Kids [ 10 0 R ] /Type /Pages >>
-endobj
-12 0 obj
-<< /CreationDate (D:20170812144045-04'00')
-/Creator (matplotlib 2.0.2.post4623.dev0+gcb3aea0db, http://matplotlib.org)
-/Producer (matplotlib pdf backend 2.0.2.post4623.dev0+gcb3aea0db) >>
-endobj
-xref
-0 13
-0000000000 65535 f
-0000000016 00000 n
-0000001210 00000 n
-0000001027 00000 n
-0000001048 00000 n
-0000001147 00000 n
-0000001168 00000 n
-0000001189 00000 n
-0000000065 00000 n
-0000000383 00000 n
-0000000208 00000 n
-0000001007 00000 n
-0000001270 00000 n
-trailer
-<< /Info 12 0 R /Root 1 0 R /Size 13 >>
-startxref
-1474
-%%EOF
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help.png
deleted file mode 100644
index a52fbbe819..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help.svg
deleted file mode 100644
index 484bdbcbf6..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help.svg
+++ /dev/null
@@ -1,52 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 43.283438 55.959375
-C 43.283438 55.12 42.603437 54.44 41.764063 54.44
-L 32.658437 54.44
-C 31.829687 54.44 31.139063 55.12 31.139063 55.959375
-L 31.139063 65.065
-C 31.139063 65.904375 31.829687 66.584375 32.658437 66.584375
-L 41.764063 66.584375
-C 42.603437 66.584375 43.283438 65.904375 43.283438 65.065
-z
-M 55.279063 33.19
-C 55.279063 24.49875 46.173438 18.0175 38.045313 18.0175
-C 30.310312 18.0175 24.540937 21.31125 20.439687 28.11125
-C 20.025312 28.79125 20.174062 29.62 20.822187 30.119375
-L 27.048437 34.858125
-C 27.345937 35.049375 27.654062 35.16625 27.994062 35.16625
-C 28.408437 35.16625 28.865313 34.9325 29.173437 34.560625
-C 31.404688 31.745 32.318438 30.841875 33.232187 30.19375
-C 34.060937 29.62 35.622812 29.08875 37.333438 29.08875
-C 40.404062 29.08875 43.177188 30.990625 43.177188 33.115625
-C 43.177188 35.54875 41.955313 36.791875 39.033438 38.12
-C 35.697187 39.639375 31.139063 43.591875 31.139063 48.181875
-L 31.139063 49.8925
-C 31.139063 50.72125 31.670313 52.0175 32.509687 52.0175
-L 41.615313 52.0175
-C 42.486563 52.0175 43.134687 51.029375 43.134687 50.19
-C 43.134687 49.095625 44.537188 46.47125 46.779063 45.185625
-C 50.380938 43.166875 55.279063 40.404375 55.279063 33.19
-z
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help_large.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help_large.png
deleted file mode 100644
index 3f3d4dfed7..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/help_large.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home-symbolic.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home-symbolic.svg
deleted file mode 100644
index 3c4ccce3ed..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home-symbolic.svg
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 57.860938 45.94
-C 57.860938 45.865625 57.860938 45.79125 57.818438 45.716875
-L 35.994687 27.72875
-L 14.181562 45.716875
-C 14.181562 45.79125 14.139062 45.865625 14.139062 45.94
-L 14.139062 64.15125
-C 14.139062 65.479375 15.244062 66.584375 16.572187 66.584375
-L 31.139063 66.584375
-L 31.139063 52.0175
-L 40.860938 52.0175
-L 40.860938 66.584375
-L 55.427813 66.584375
-C 56.755938 66.584375 57.860938 65.479375 57.860938 64.15125
-z
-M 66.318438 43.32625
-C 66.732813 42.826875 66.658438 42.03 66.169688 41.615625
-L 57.860938 34.709375
-L 57.860938 19.22875
-C 57.860938 18.54875 57.329688 18.0175 56.639063 18.0175
-L 49.360938 18.0175
-C 48.670312 18.0175 48.139062 18.54875 48.139062 19.22875
-L 48.139062 26.62375
-L 38.884687 18.88875
-C 37.290937 17.560625 34.709063 17.560625 33.115313 18.88875
-L 5.830312 41.615625
-C 5.341562 42.03 5.267187 42.826875 5.681562 43.32625
-L 8.029687 46.13125
-C 8.220937 46.354375 8.529062 46.51375 8.826562 46.545625
-C 9.166562 46.588125 9.474687 46.47125 9.740312 46.28
-L 35.994687 24.3925
-L 62.259687 46.28
-C 62.482813 46.47125 62.748438 46.545625 63.056562 46.545625
-C 63.088437 46.545625 63.130938 46.545625 63.173438 46.545625
-C 63.470938 46.51375 63.779063 46.354375 63.970313 46.13125
-z
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home.pdf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home.pdf
deleted file mode 100644
index f9c6439b9b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home.pdf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home.png
deleted file mode 100644
index 6e5fdebb35..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home.svg
deleted file mode 100644
index 3c4ccce3ed..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home.svg
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 57.860938 45.94
-C 57.860938 45.865625 57.860938 45.79125 57.818438 45.716875
-L 35.994687 27.72875
-L 14.181562 45.716875
-C 14.181562 45.79125 14.139062 45.865625 14.139062 45.94
-L 14.139062 64.15125
-C 14.139062 65.479375 15.244062 66.584375 16.572187 66.584375
-L 31.139063 66.584375
-L 31.139063 52.0175
-L 40.860938 52.0175
-L 40.860938 66.584375
-L 55.427813 66.584375
-C 56.755938 66.584375 57.860938 65.479375 57.860938 64.15125
-z
-M 66.318438 43.32625
-C 66.732813 42.826875 66.658438 42.03 66.169688 41.615625
-L 57.860938 34.709375
-L 57.860938 19.22875
-C 57.860938 18.54875 57.329688 18.0175 56.639063 18.0175
-L 49.360938 18.0175
-C 48.670312 18.0175 48.139062 18.54875 48.139062 19.22875
-L 48.139062 26.62375
-L 38.884687 18.88875
-C 37.290937 17.560625 34.709063 17.560625 33.115313 18.88875
-L 5.830312 41.615625
-C 5.341562 42.03 5.267187 42.826875 5.681562 43.32625
-L 8.029687 46.13125
-C 8.220937 46.354375 8.529062 46.51375 8.826562 46.545625
-C 9.166562 46.588125 9.474687 46.47125 9.740312 46.28
-L 35.994687 24.3925
-L 62.259687 46.28
-C 62.482813 46.47125 62.748438 46.545625 63.056562 46.545625
-C 63.088437 46.545625 63.130938 46.545625 63.173438 46.545625
-C 63.470938 46.51375 63.779063 46.354375 63.970313 46.13125
-z
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home_large.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home_large.png
deleted file mode 100644
index 3357bfeb90..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/home_large.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/matplotlib.pdf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/matplotlib.pdf
deleted file mode 100644
index 6c44566ad8..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/matplotlib.pdf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/matplotlib.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/matplotlib.png
deleted file mode 100644
index 8eedfa7cc8..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/matplotlib.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/matplotlib.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/matplotlib.svg
deleted file mode 100644
index 95d1b61203..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/matplotlib.svg
+++ /dev/null
@@ -1,3171 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="axes_1">
- <g id="patch_2">
- <path d="M 36 70.2
-C 45.069946 70.2 53.769632 66.596472 60.183052 60.183052
-C 66.596472 53.769632 70.2 45.069946 70.2 36
-C 70.2 26.930054 66.596472 18.230368 60.183052 11.816948
-C 53.769632 5.403528 45.069946 1.8 36 1.8
-C 26.930054 1.8 18.230368 5.403528 11.816948 11.816948
-C 5.403528 18.230368 1.8 26.930054 1.8 36
-C 1.8 45.069946 5.403528 53.769632 11.816948 60.183052
-C 18.230368 66.596472 26.930054 70.2 36 70.2
-z
-" style="fill:#ffffff;"/>
- </g>
- <g id="matplotlib.axis_1">
- <g id="xtick_1">
- <g id="line2d_1">
- <path clip-path="url(#p2b9aa5bb59)" d="M 36 36
-L 70.2 36
-" style="fill:none;"/>
- </g>
- </g>
- <g id="xtick_2">
- <g id="line2d_2">
- <path clip-path="url(#p2b9aa5bb59)" d="M 36 36
-L 60.183052 11.816948
-" style="fill:none;"/>
- </g>
- </g>
- <g id="xtick_3">
- <g id="line2d_3">
- <path clip-path="url(#p2b9aa5bb59)" d="M 36 36
-L 36 1.8
-" style="fill:none;"/>
- </g>
- </g>
- <g id="xtick_4">
- <g id="line2d_4">
- <path clip-path="url(#p2b9aa5bb59)" d="M 36 36
-L 11.816948 11.816948
-" style="fill:none;"/>
- </g>
- </g>
- <g id="xtick_5">
- <g id="line2d_5">
- <path clip-path="url(#p2b9aa5bb59)" d="M 36 36
-L 1.8 36
-" style="fill:none;"/>
- </g>
- </g>
- <g id="xtick_6">
- <g id="line2d_6">
- <path clip-path="url(#p2b9aa5bb59)" d="M 36 36
-L 11.816948 60.183052
-" style="fill:none;"/>
- </g>
- </g>
- <g id="xtick_7">
- <g id="line2d_7">
- <path clip-path="url(#p2b9aa5bb59)" d="M 36 36
-L 36 70.2
-" style="fill:none;"/>
- </g>
- </g>
- <g id="xtick_8">
- <g id="line2d_8">
- <path clip-path="url(#p2b9aa5bb59)" d="M 36 36
-L 60.183052 60.183052
-" style="fill:none;"/>
- </g>
- </g>
- </g>
- <g id="matplotlib.axis_2">
- <g id="ytick_1">
- <g id="line2d_9">
- <path clip-path="url(#p2b9aa5bb59)" d="M 39.8 36
-L 39.687124 35.080697
-L 39.355201 34.216008
-L 38.82395 33.457304
-L 38.124933 32.849657
-L 37.299677 32.429168
-L 36.397208 32.220817
-L 35.471142 32.236981
-L 34.576495 32.476701
-L 33.766416 32.925735
-L 33.089031 33.557407
-L 32.584583 34.33419
-L 32.283039 35.209936
-L 32.202315 36.132618
-L 32.347206 37.047422
-L 32.709103 37.9
-L 33.266509 38.639702
-L 33.986307 39.222583
-L 34.825735 39.614015
-L 35.734925 39.790743
-L 36.659863 39.742269
-L 37.545599 39.471473
-L 38.339514 38.994441
-L 38.994441 38.339514
-L 39.471473 37.545599
-L 39.742269 36.659863
-L 39.8 36
-L 39.8 36
-" style="fill:none;"/>
- </g>
- </g>
- <g id="ytick_2">
- <g id="line2d_10">
- <path clip-path="url(#p2b9aa5bb59)" d="M 47.4 36
-L 47.289056 34.413427
-L 46.958383 32.857734
-L 46.414418 31.363202
-L 45.667748 29.95892
-L 44.732907 28.672221
-L 43.628089 27.528149
-L 42.374799 26.548972
-L 40.997431 25.753748
-L 39.522794 25.157956
-L 37.979589 24.773192
-L 36.397854 24.606945
-L 34.808376 24.66245
-L 33.24209 24.938629
-L 31.729485 25.430104
-L 30.3 26.12731
-L 28.981459 27.016677
-L 27.799526 28.080895
-L 26.777206 29.299248
-L 25.934397 30.648024
-L 25.287504 32.10097
-L 24.849117 33.629807
-L 24.62777 35.204776
-L 24.62777 36.795224
-L 24.849117 38.370193
-L 25.287504 39.89903
-L 25.934397 41.351976
-L 26.777206 42.700752
-L 27.799526 43.919105
-L 28.981459 44.983323
-L 30.3 45.87269
-L 31.729485 46.569896
-L 33.24209 47.061371
-L 34.808376 47.33755
-L 36.397854 47.393055
-L 37.979589 47.226808
-L 39.522794 46.842044
-L 40.997431 46.246252
-L 42.374799 45.451028
-L 43.628089 44.471851
-L 44.732907 43.327779
-L 45.667748 42.04108
-L 46.414418 40.636798
-L 46.958383 39.142266
-L 47.289056 37.586573
-L 47.4 36
-L 47.4 36
-" style="fill:none;"/>
- </g>
- </g>
- <g id="ytick_3">
- <g id="line2d_11">
- <path clip-path="url(#p2b9aa5bb59)" d="M 55 36
-L 54.895916 34.013959
-L 54.584804 32.049678
-L 54.070074 30.128677
-L 53.357364 28.272004
-L 52.454483 26.5
-L 51.371323 24.83208
-L 50.119752 23.286518
-L 48.713482 21.880248
-L 47.16792 20.628677
-L 45.5 19.545517
-L 43.727996 18.642636
-L 41.871323 17.929926
-L 39.950322 17.415196
-L 37.986041 17.104084
-L 36 17
-L 34.013959 17.104084
-L 32.049678 17.415196
-L 30.128677 17.929926
-L 28.272004 18.642636
-L 26.5 19.545517
-L 24.83208 20.628677
-L 23.286518 21.880248
-L 21.880248 23.286518
-L 20.628677 24.83208
-L 19.545517 26.5
-L 18.642636 28.272004
-L 17.929926 30.128677
-L 17.415196 32.049678
-L 17.104084 34.013959
-L 17 36
-L 17.104084 37.986041
-L 17.415196 39.950322
-L 17.929926 41.871323
-L 18.642636 43.727996
-L 19.545517 45.5
-L 20.628677 47.16792
-L 21.880248 48.713482
-L 23.286518 50.119752
-L 24.83208 51.371323
-L 26.5 52.454483
-L 28.272004 53.357364
-L 30.128677 54.070074
-L 32.049678 54.584804
-L 34.013959 54.895916
-L 36 55
-L 37.986041 54.895916
-L 39.950322 54.584804
-L 41.871323 54.070074
-L 43.727996 53.357364
-L 45.5 52.454483
-L 47.16792 51.371323
-L 48.713482 50.119752
-L 50.119752 48.713482
-L 51.371323 47.16792
-L 52.454483 45.5
-L 53.357364 43.727996
-L 54.070074 41.871323
-L 54.584804 39.950322
-L 54.895916 37.986041
-L 55 36
-L 55 36
-" style="fill:none;"/>
- </g>
- </g>
- <g id="ytick_4">
- <g id="line2d_12">
- <path clip-path="url(#p2b9aa5bb59)" d="M 62.6 36
-L 62.454282 33.219543
-L 62.018726 30.469549
-L 61.298103 27.780148
-L 60.300309 25.180805
-L 59.036276 22.7
-L 57.519852 20.364912
-L 55.767652 18.201126
-L 53.798874 16.232348
-L 51.635088 14.480148
-L 49.3 12.963724
-L 46.819195 11.699691
-L 44.219852 10.701897
-L 41.530451 9.981274
-L 38.780457 9.545718
-L 36 9.4
-L 33.219543 9.545718
-L 30.469549 9.981274
-L 27.780148 10.701897
-L 25.180805 11.699691
-L 22.7 12.963724
-L 20.364912 14.480148
-L 18.201126 16.232348
-L 16.232348 18.201126
-L 14.480148 20.364912
-L 12.963724 22.7
-L 11.699691 25.180805
-L 10.701897 27.780148
-L 9.981274 30.469549
-L 9.545718 33.219543
-L 9.4 36
-L 9.545718 38.780457
-L 9.981274 41.530451
-L 10.701897 44.219852
-L 11.699691 46.819195
-L 12.963724 49.3
-L 14.480148 51.635088
-L 16.232348 53.798874
-L 18.201126 55.767652
-L 20.364912 57.519852
-L 22.7 59.036276
-L 25.180805 60.300309
-L 27.780148 61.298103
-L 30.469549 62.018726
-L 33.219543 62.454282
-L 36 62.6
-L 38.780457 62.454282
-L 41.530451 62.018726
-L 44.219852 61.298103
-L 46.819195 60.300309
-L 49.3 59.036276
-L 51.635088 57.519852
-L 53.798874 55.767652
-L 55.767652 53.798874
-L 57.519852 51.635088
-L 59.036276 49.3
-L 60.300309 46.819195
-L 61.298103 44.219852
-L 62.018726 41.530451
-L 62.454282 38.780457
-L 62.6 36
-L 62.6 36
-" style="fill:none;"/>
- </g>
- </g>
- </g>
- <g id="patch_3">
- <path clip-path="url(#p2b9aa5bb59)" d="M 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36.07228 35.976515
-L 36.144561 35.953029
-L 36.216841 35.929544
-L 36.289121 35.906059
-L 36.361401 35.882574
-L 36.433682 35.859088
-L 36.505962 35.835603
-L 36.578242 35.812118
-L 36.650523 35.788632
-L 36.722803 35.765147
-L 36.795083 35.741662
-L 36.867364 35.718177
-L 36.939644 35.694691
-L 37.011924 35.671206
-L 37.084204 35.647721
-L 37.156485 35.624235
-L 37.228765 35.60075
-L 37.301045 35.577265
-L 37.373326 35.553779
-L 37.445606 35.530294
-L 37.517886 35.506809
-L 37.590166 35.483324
-L 37.662447 35.459838
-L 37.734727 35.436353
-L 37.807007 35.412868
-L 37.879288 35.389382
-L 37.951568 35.365897
-L 38.023848 35.342412
-L 38.096129 35.318927
-L 38.168409 35.295441
-L 38.240689 35.271956
-L 38.312969 35.248471
-L 38.38525 35.224985
-L 38.45753 35.2015
-L 38.52981 35.178015
-L 38.602091 35.15453
-L 38.674371 35.131044
-L 38.746651 35.107559
-L 38.818932 35.084074
-L 38.891212 35.060588
-L 38.963492 35.037103
-L 39.035772 35.013618
-L 39.108053 34.990132
-L 39.180333 34.966647
-L 39.252613 34.943162
-L 39.324894 34.919677
-L 39.397174 34.896191
-L 39.469454 34.872706
-L 39.541734 34.849221
-L 39.614015 34.825735
-L 39.686295 34.80225
-L 39.758575 34.778765
-L 39.830856 34.75528
-L 39.903136 34.731794
-L 39.975416 34.708309
-L 40.047697 34.684824
-L 40.119977 34.661338
-L 40.192257 34.637853
-L 40.264537 34.614368
-L 40.336818 34.590883
-L 40.409098 34.567397
-L 40.481378 34.543912
-L 40.553659 34.520427
-L 40.625939 34.496941
-L 40.698219 34.473456
-L 40.770499 34.449971
-L 40.84278 34.426485
-L 40.91506 34.403
-L 40.98734 34.379515
-L 41.059621 34.35603
-L 41.131901 34.332544
-L 41.204181 34.309059
-L 41.276462 34.285574
-L 41.348742 34.262088
-L 41.421022 34.238603
-L 41.493302 34.215118
-L 41.565583 34.191633
-L 41.637863 34.168147
-L 41.710143 34.144662
-L 41.782424 34.121177
-L 41.854704 34.097691
-L 41.926984 34.074206
-L 41.999265 34.050721
-L 42.071545 34.027236
-L 42.143825 34.00375
-L 42.216105 33.980265
-L 42.288386 33.95678
-L 42.360666 33.933294
-L 42.432946 33.909809
-L 42.505227 33.886324
-L 42.577507 33.862838
-L 42.649787 33.839353
-L 42.722067 33.815868
-L 42.794348 33.792383
-L 42.866628 33.768897
-L 42.938908 33.745412
-L 43.011189 33.721927
-L 43.083469 33.698441
-L 43.155749 33.674956
-L 43.22803 33.651471
-L 43.235372 33.67419
-L 43.242643 33.696932
-L 43.249843 33.719697
-L 43.256971 33.742484
-L 43.264027 33.765294
-L 43.271012 33.788125
-L 43.277925 33.810979
-L 43.284766 33.833854
-L 43.291535 33.85675
-L 43.298232 33.879668
-L 43.304857 33.902606
-L 43.31141 33.925565
-L 43.317891 33.948545
-L 43.3243 33.971545
-L 43.330636 33.994565
-L 43.3369 34.017605
-L 43.343092 34.040664
-L 43.349211 34.063742
-L 43.355258 34.08684
-L 43.361232 34.109957
-L 43.367133 34.133092
-L 43.372962 34.156246
-L 43.378718 34.179418
-L 43.384401 34.202608
-L 43.390011 34.225815
-L 43.395549 34.24904
-L 43.401013 34.272283
-L 43.406404 34.295542
-L 43.411722 34.318818
-L 43.416967 34.342111
-L 43.422139 34.365421
-L 43.427238 34.388746
-L 43.432263 34.412087
-L 43.437215 34.435444
-L 43.442093 34.458817
-L 43.446898 34.482204
-L 43.45163 34.505607
-L 43.456288 34.529024
-L 43.460872 34.552456
-L 43.465383 34.575902
-L 43.46982 34.599362
-L 43.474184 34.622836
-L 43.478473 34.646324
-L 43.482689 34.669825
-L 43.486831 34.693339
-L 43.490899 34.716866
-L 43.494893 34.740405
-L 43.498813 34.763958
-L 43.502659 34.787522
-L 43.506431 34.811098
-L 43.510129 34.834686
-L 43.513753 34.858286
-L 43.517303 34.881896
-L 43.520779 34.905518
-L 43.52418 34.929151
-L 43.527507 34.952794
-L 43.53076 34.976447
-L 43.533938 35.000111
-L 43.537042 35.023784
-L 43.540072 35.047467
-L 43.543027 35.07116
-L 43.545908 35.094862
-L 43.548714 35.118572
-L 43.551446 35.142291
-L 43.554103 35.166019
-L 43.556686 35.189755
-L 43.559194 35.213499
-L 43.561628 35.237251
-L 43.563987 35.26101
-L 43.566271 35.284777
-L 43.568481 35.30855
-L 43.570615 35.332331
-L 43.572676 35.356118
-L 43.574661 35.379911
-L 43.576572 35.403711
-L 43.578408 35.427516
-L 43.580169 35.451327
-L 43.581855 35.475144
-L 43.583467 35.498965
-L 43.585003 35.522792
-L 43.586465 35.546623
-L 43.587852 35.570459
-L 43.589164 35.594299
-L 43.590401 35.618143
-L 43.591563 35.641991
-L 43.59265 35.665842
-L 43.593663 35.689697
-L 43.5946 35.713555
-L 43.595462 35.737415
-L 43.59625 35.761278
-L 43.596962 35.785144
-L 43.5976 35.809011
-L 43.598162 35.832881
-L 43.59865 35.856752
-L 43.599062 35.880624
-L 43.5994 35.904498
-L 43.599662 35.928373
-L 43.59985 35.952248
-L 43.599962 35.976124
-L 43.6 36
-L 43.524 36
-L 43.448 36
-L 43.372 36
-L 43.296 36
-L 43.22 36
-L 43.144 36
-L 43.068 36
-L 42.992 36
-L 42.916 36
-L 42.84 36
-L 42.764 36
-L 42.688 36
-L 42.612 36
-L 42.536 36
-L 42.46 36
-L 42.384 36
-L 42.308 36
-L 42.232 36
-L 42.156 36
-L 42.08 36
-L 42.004 36
-L 41.928 36
-L 41.852 36
-L 41.776 36
-L 41.7 36
-L 41.624 36
-L 41.548 36
-L 41.472 36
-L 41.396 36
-L 41.32 36
-L 41.244 36
-L 41.168 36
-L 41.092 36
-L 41.016 36
-L 40.94 36
-L 40.864 36
-L 40.788 36
-L 40.712 36
-L 40.636 36
-L 40.56 36
-L 40.484 36
-L 40.408 36
-L 40.332 36
-L 40.256 36
-L 40.18 36
-L 40.104 36
-L 40.028 36
-L 39.952 36
-L 39.876 36
-L 39.8 36
-L 39.724 36
-L 39.648 36
-L 39.572 36
-L 39.496 36
-L 39.42 36
-L 39.344 36
-L 39.268 36
-L 39.192 36
-L 39.116 36
-L 39.04 36
-L 38.964 36
-L 38.888 36
-L 38.812 36
-L 38.736 36
-L 38.66 36
-L 38.584 36
-L 38.508 36
-L 38.432 36
-L 38.356 36
-L 38.28 36
-L 38.204 36
-L 38.128 36
-L 38.052 36
-L 37.976 36
-L 37.9 36
-L 37.824 36
-L 37.748 36
-L 37.672 36
-L 37.596 36
-L 37.52 36
-L 37.444 36
-L 37.368 36
-L 37.292 36
-L 37.216 36
-L 37.14 36
-L 37.064 36
-L 36.988 36
-L 36.912 36
-L 36.836 36
-L 36.76 36
-L 36.684 36
-L 36.608 36
-L 36.532 36
-L 36.456 36
-L 36.38 36
-L 36.304 36
-L 36.228 36
-L 36.152 36
-L 36.076 36
-z
-" style="fill:#004cff;stroke:#000000;stroke-linejoin:miter;"/>
- </g>
- <g id="patch_4">
- <path clip-path="url(#p2b9aa5bb59)" d="M 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36.080113 35.786538
-L 36.160227 35.573077
-L 36.24034 35.359615
-L 36.320454 35.146154
-L 36.400567 34.932692
-L 36.480681 34.719231
-L 36.560794 34.505769
-L 36.640908 34.292308
-L 36.721021 34.078846
-L 36.801135 33.865384
-L 36.881248 33.651923
-L 36.961362 33.438461
-L 37.041475 33.225
-L 37.121588 33.011538
-L 37.201702 32.798077
-L 37.281815 32.584615
-L 37.361929 32.371154
-L 37.442042 32.157692
-L 37.522156 31.944231
-L 37.602269 31.730769
-L 37.682383 31.517307
-L 37.762496 31.303846
-L 37.84261 31.090384
-L 37.922723 30.876923
-L 38.002836 30.663461
-L 38.08295 30.45
-L 38.163063 30.236538
-L 38.243177 30.023077
-L 38.32329 29.809615
-L 38.403404 29.596153
-L 38.483517 29.382692
-L 38.563631 29.16923
-L 38.643744 28.955769
-L 38.723858 28.742307
-L 38.803971 28.528846
-L 38.884085 28.315384
-L 38.964198 28.101923
-L 39.044311 27.888461
-L 39.124425 27.675
-L 39.204538 27.461538
-L 39.284652 27.248076
-L 39.364765 27.034615
-L 39.444879 26.821153
-L 39.524992 26.607692
-L 39.605106 26.39423
-L 39.685219 26.180769
-L 39.765333 25.967307
-L 39.845446 25.753846
-L 39.92556 25.540384
-L 40.005673 25.326922
-L 40.085786 25.113461
-L 40.1659 24.899999
-L 40.246013 24.686538
-L 40.326127 24.473076
-L 40.40624 24.259615
-L 40.486354 24.046153
-L 40.566467 23.832692
-L 40.646581 23.61923
-L 40.726694 23.405769
-L 40.806808 23.192307
-L 40.886921 22.978845
-L 40.967035 22.765384
-L 41.047148 22.551922
-L 41.127261 22.338461
-L 41.207375 22.124999
-L 41.287488 21.911538
-L 41.367602 21.698076
-L 41.447715 21.484615
-L 41.527829 21.271153
-L 41.607942 21.057691
-L 41.688056 20.84423
-L 41.768169 20.630768
-L 41.848283 20.417307
-L 41.928396 20.203845
-L 42.008509 19.990384
-L 42.088623 19.776922
-L 42.168736 19.563461
-L 42.24885 19.349999
-L 42.328963 19.136538
-L 42.409077 18.923076
-L 42.48919 18.709614
-L 42.569304 18.496153
-L 42.649417 18.282691
-L 42.729531 18.06923
-L 42.809644 17.855768
-L 42.889758 17.642307
-L 42.969871 17.428845
-L 43.049984 17.215384
-L 43.130098 17.001922
-L 43.210211 16.78846
-L 43.290325 16.574999
-L 43.370438 16.361537
-L 43.450552 16.148076
-L 43.530665 15.934614
-L 43.610779 15.721153
-L 43.690892 15.507691
-L 43.771006 15.29423
-L 43.851119 15.080768
-L 43.931233 14.867306
-L 44.011346 14.653845
-L 44.078367 14.679119
-L 44.145309 14.704603
-L 44.21217 14.730297
-L 44.27895 14.756201
-L 44.345648 14.782315
-L 44.412265 14.808638
-L 44.478798 14.835171
-L 44.545247 14.861912
-L 44.611612 14.888862
-L 44.677892 14.91602
-L 44.744086 14.943387
-L 44.810194 14.970961
-L 44.876215 14.998743
-L 44.942149 15.026732
-L 45.007994 15.054928
-L 45.07375 15.083331
-L 45.139417 15.11194
-L 45.204994 15.140755
-L 45.270479 15.169776
-L 45.335874 15.199003
-L 45.401176 15.228435
-L 45.466385 15.258073
-L 45.531501 15.287914
-L 45.596523 15.317961
-L 45.66145 15.348211
-L 45.726281 15.378665
-L 45.791017 15.409323
-L 45.855656 15.440184
-L 45.920198 15.471248
-L 45.984642 15.502514
-L 46.048987 15.533983
-L 46.113234 15.565654
-L 46.17738 15.597526
-L 46.241426 15.6296
-L 46.305371 15.661875
-L 46.369214 15.69435
-L 46.432955 15.727026
-L 46.496593 15.759903
-L 46.560127 15.792978
-L 46.623557 15.826254
-L 46.686882 15.859728
-L 46.750102 15.893401
-L 46.813215 15.927273
-L 46.876222 15.961343
-L 46.939122 15.99561
-L 47.001913 16.030075
-L 47.064596 16.064737
-L 47.12717 16.099596
-L 47.189634 16.134651
-L 47.251987 16.169902
-L 47.31423 16.205349
-L 47.376361 16.240991
-L 47.438379 16.276829
-L 47.500285 16.312861
-L 47.562077 16.349087
-L 47.623755 16.385507
-L 47.685318 16.422121
-L 47.746766 16.458928
-L 47.808098 16.495928
-L 47.869314 16.533121
-L 47.930412 16.570505
-L 47.991393 16.608081
-L 48.052255 16.645849
-L 48.112998 16.683808
-L 48.173622 16.721957
-L 48.234125 16.760297
-L 48.294508 16.798826
-L 48.35477 16.837545
-L 48.414909 16.876454
-L 48.474926 16.91555
-L 48.53482 16.954836
-L 48.59459 16.994309
-L 48.654236 17.03397
-L 48.713757 17.073818
-L 48.773153 17.113852
-L 48.832422 17.154074
-L 48.891565 17.194481
-L 48.950581 17.235074
-L 49.009468 17.275852
-L 49.068228 17.316814
-L 49.126858 17.357962
-L 49.185359 17.399293
-L 49.24373 17.440807
-L 49.30197 17.482505
-L 49.360078 17.524386
-L 49.418055 17.566449
-L 49.475899 17.608694
-L 49.533611 17.651121
-L 49.591189 17.693728
-L 49.648632 17.736516
-L 49.705941 17.779485
-L 49.763115 17.822633
-L 49.820153 17.865961
-L 49.877054 17.909468
-L 49.933819 17.953153
-L 49.990446 17.997016
-L 50.046935 18.041057
-L 50.103285 18.085276
-L 50.159496 18.129671
-L 50.215567 18.174242
-L 50.073412 18.3525
-L 49.931256 18.530757
-L 49.7891 18.709015
-L 49.646945 18.887273
-L 49.504789 19.06553
-L 49.362633 19.243788
-L 49.220478 19.422045
-L 49.078322 19.600303
-L 48.936166 19.77856
-L 48.794011 19.956818
-L 48.651855 20.135076
-L 48.509699 20.313333
-L 48.367544 20.491591
-L 48.225388 20.669848
-L 48.083232 20.848106
-L 47.941077 21.026363
-L 47.798921 21.204621
-L 47.656765 21.382879
-L 47.51461 21.561136
-L 47.372454 21.739394
-L 47.230298 21.917651
-L 47.088143 22.095909
-L 46.945987 22.274166
-L 46.803831 22.452424
-L 46.661676 22.630682
-L 46.51952 22.808939
-L 46.377364 22.987197
-L 46.235209 23.165454
-L 46.093053 23.343712
-L 45.950897 23.52197
-L 45.808742 23.700227
-L 45.666586 23.878485
-L 45.52443 24.056742
-L 45.382275 24.235
-L 45.240119 24.413257
-L 45.097963 24.591515
-L 44.955808 24.769773
-L 44.813652 24.94803
-L 44.671496 25.126288
-L 44.52934 25.304545
-L 44.387185 25.482803
-L 44.245029 25.66106
-L 44.102873 25.839318
-L 43.960718 26.017576
-L 43.818562 26.195833
-L 43.676406 26.374091
-L 43.534251 26.552348
-L 43.392095 26.730606
-L 43.249939 26.908864
-L 43.107784 27.087121
-L 42.965628 27.265379
-L 42.823472 27.443636
-L 42.681317 27.621894
-L 42.539161 27.800151
-L 42.397005 27.978409
-L 42.25485 28.156667
-L 42.112694 28.334924
-L 41.970538 28.513182
-L 41.828383 28.691439
-L 41.686227 28.869697
-L 41.544071 29.047954
-L 41.401916 29.226212
-L 41.25976 29.40447
-L 41.117604 29.582727
-L 40.975449 29.760985
-L 40.833293 29.939242
-L 40.691137 30.1175
-L 40.548982 30.295758
-L 40.406826 30.474015
-L 40.26467 30.652273
-L 40.122515 30.83053
-L 39.980359 31.008788
-L 39.838203 31.187045
-L 39.696048 31.365303
-L 39.553892 31.543561
-L 39.411736 31.721818
-L 39.269581 31.900076
-L 39.127425 32.078333
-L 38.985269 32.256591
-L 38.843113 32.434848
-L 38.700958 32.613106
-L 38.558802 32.791364
-L 38.416646 32.969621
-L 38.274491 33.147879
-L 38.132335 33.326136
-L 37.990179 33.504394
-L 37.848024 33.682651
-L 37.705868 33.860909
-L 37.563712 34.039167
-L 37.421557 34.217424
-L 37.279401 34.395682
-L 37.137245 34.573939
-L 36.99509 34.752197
-L 36.852934 34.930455
-L 36.710778 35.108712
-L 36.568623 35.28697
-L 36.426467 35.465227
-L 36.284311 35.643485
-L 36.142156 35.821742
-z
-" style="fill:#ceff29;stroke:#000000;stroke-linejoin:miter;"/>
- </g>
- <g id="patch_5">
- <path clip-path="url(#p2b9aa5bb59)" d="M 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 35.805174 35.766636
-L 35.610348 35.533272
-L 35.415521 35.299908
-L 35.220695 35.066544
-L 35.025869 34.83318
-L 34.831043 34.599816
-L 34.636217 34.366452
-L 34.441391 34.133088
-L 34.246564 33.899724
-L 34.051738 33.66636
-L 33.856912 33.432996
-L 33.662086 33.199632
-L 33.46726 32.966268
-L 33.272433 32.732904
-L 33.077607 32.49954
-L 32.882781 32.266176
-L 32.687955 32.032812
-L 32.493129 31.799448
-L 32.298302 31.566084
-L 32.103476 31.33272
-L 31.90865 31.099356
-L 31.713824 30.865992
-L 31.518998 30.632628
-L 31.324172 30.399264
-L 31.129345 30.1659
-L 30.934519 29.932536
-L 30.739693 29.699172
-L 30.544867 29.465808
-L 30.350041 29.232444
-L 30.155214 28.99908
-L 29.960388 28.765716
-L 29.765562 28.532352
-L 29.570736 28.298988
-L 29.37591 28.065624
-L 29.181083 27.83226
-L 28.986257 27.598896
-L 28.791431 27.365532
-L 28.596605 27.132168
-L 28.401779 26.898804
-L 28.206953 26.66544
-L 28.012126 26.432076
-L 27.8173 26.198712
-L 27.622474 25.965348
-L 27.427648 25.731984
-L 27.232822 25.49862
-L 27.037995 25.265256
-L 26.843169 25.031892
-L 26.648343 24.798528
-L 26.453517 24.565164
-L 26.258691 24.3318
-L 26.063864 24.098436
-L 25.869038 23.865072
-L 25.674212 23.631708
-L 25.479386 23.398344
-L 25.28456 23.16498
-L 25.089734 22.931616
-L 24.894907 22.698252
-L 24.700081 22.464888
-L 24.505255 22.231524
-L 24.310429 21.99816
-L 24.115603 21.764796
-L 23.920776 21.531432
-L 23.72595 21.298068
-L 23.531124 21.064704
-L 23.336298 20.83134
-L 23.141472 20.597976
-L 22.946645 20.364612
-L 22.751819 20.131248
-L 22.556993 19.897884
-L 22.362167 19.66452
-L 22.167341 19.431156
-L 21.972515 19.197792
-L 21.777688 18.964428
-L 21.582862 18.731064
-L 21.388036 18.4977
-L 21.19321 18.264336
-L 20.998384 18.030972
-L 20.803557 17.797608
-L 20.608731 17.564244
-L 20.413905 17.33088
-L 20.219079 17.097516
-L 20.024253 16.864152
-L 19.829427 16.630788
-L 19.6346 16.397424
-L 19.439774 16.16406
-L 19.244948 15.930696
-L 19.050122 15.697332
-L 18.855296 15.463968
-L 18.660469 15.230604
-L 18.465643 14.99724
-L 18.270817 14.763876
-L 18.075991 14.530512
-L 17.881165 14.297148
-L 17.686338 14.063784
-L 17.491512 13.83042
-L 17.296686 13.597056
-L 17.10186 13.363692
-L 16.907034 13.130328
-L 16.712208 12.896964
-L 16.517381 12.6636
-L 16.627567 12.57205
-L 16.738184 12.48102
-L 16.849228 12.390512
-L 16.960697 12.300529
-L 17.072589 12.211071
-L 17.184902 12.122143
-L 17.297632 12.033744
-L 17.410777 11.945878
-L 17.524336 11.858545
-L 17.638304 11.771749
-L 17.752681 11.685491
-L 17.867462 11.599773
-L 17.982647 11.514597
-L 18.098231 11.429964
-L 18.214213 11.345877
-L 18.33059 11.262338
-L 18.447359 11.179347
-L 18.564518 11.096908
-L 18.682064 11.015022
-L 18.799995 10.933691
-L 18.918308 10.852917
-L 19.037 10.772701
-L 19.156069 10.693045
-L 19.275511 10.613951
-L 19.395326 10.535421
-L 19.515509 10.457456
-L 19.636058 10.380059
-L 19.75697 10.30323
-L 19.878243 10.226972
-L 19.999874 10.151287
-L 20.121861 10.076175
-L 20.2442 10.001639
-L 20.366888 9.927681
-L 20.489924 9.854301
-L 20.613305 9.781502
-L 20.737027 9.709286
-L 20.861088 9.637653
-L 20.985485 9.566605
-L 21.110216 9.496145
-L 21.235277 9.426273
-L 21.360667 9.356991
-L 21.486381 9.288301
-L 21.612418 9.220204
-L 21.738774 9.152702
-L 21.865446 9.085796
-L 21.992433 9.019487
-L 22.119731 8.953778
-L 22.247337 8.888669
-L 22.375248 8.824163
-L 22.503462 8.760259
-L 22.631976 8.696961
-L 22.760786 8.634269
-L 22.889891 8.572185
-L 23.019286 8.51071
-L 23.14897 8.449845
-L 23.278939 8.389592
-L 23.409191 8.329952
-L 23.539723 8.270927
-L 23.670531 8.212518
-L 23.801612 8.154725
-L 23.932965 8.097551
-L 24.064586 8.040996
-L 24.196472 7.985063
-L 24.328619 7.929751
-L 24.461026 7.875063
-L 24.59369 7.820999
-L 24.726606 7.767561
-L 24.859773 7.71475
-L 24.993187 7.662568
-L 25.126846 7.611014
-L 25.260746 7.560091
-L 25.394885 7.509799
-L 25.529259 7.46014
-L 25.663866 7.411115
-L 25.798702 7.362725
-L 25.933765 7.314971
-L 26.069051 7.267853
-L 26.204558 7.221374
-L 26.340282 7.175534
-L 26.476221 7.130334
-L 26.612371 7.085775
-L 26.74873 7.041858
-L 26.885295 6.998584
-L 27.022061 6.955954
-L 27.159027 6.913969
-L 27.29619 6.87263
-L 27.433545 6.831938
-L 27.571091 6.791893
-L 27.708824 6.752498
-L 27.846741 6.713751
-L 27.984839 6.675655
-L 28.123116 6.63821
-L 28.261567 6.601418
-L 28.40019 6.565278
-L 28.538981 6.529791
-L 28.677939 6.494959
-L 28.817059 6.460783
-L 28.956338 6.427262
-L 29.095774 6.394398
-L 29.235364 6.362191
-L 29.30301 6.65857
-L 29.370656 6.954948
-L 29.438303 7.251326
-L 29.505949 7.547704
-L 29.573595 7.844082
-L 29.641242 8.14046
-L 29.708888 8.436838
-L 29.776535 8.733216
-L 29.844181 9.029594
-L 29.911827 9.325972
-L 29.979474 9.62235
-L 30.04712 9.918728
-L 30.114766 10.215107
-L 30.182413 10.511485
-L 30.250059 10.807863
-L 30.317705 11.104241
-L 30.385352 11.400619
-L 30.452998 11.696997
-L 30.520645 11.993375
-L 30.588291 12.289753
-L 30.655937 12.586131
-L 30.723584 12.882509
-L 30.79123 13.178887
-L 30.858876 13.475266
-L 30.926523 13.771644
-L 30.994169 14.068022
-L 31.061815 14.3644
-L 31.129462 14.660778
-L 31.197108 14.957156
-L 31.264755 15.253534
-L 31.332401 15.549912
-L 31.400047 15.84629
-L 31.467694 16.142668
-L 31.53534 16.439046
-L 31.602986 16.735424
-L 31.670633 17.031803
-L 31.738279 17.328181
-L 31.805925 17.624559
-L 31.873572 17.920937
-L 31.941218 18.217315
-L 32.008865 18.513693
-L 32.076511 18.810071
-L 32.144157 19.106449
-L 32.211804 19.402827
-L 32.27945 19.699205
-L 32.347096 19.995583
-L 32.414743 20.291961
-L 32.482389 20.58834
-L 32.550035 20.884718
-L 32.617682 21.181096
-L 32.685328 21.477474
-L 32.752975 21.773852
-L 32.820621 22.07023
-L 32.888267 22.366608
-L 32.955914 22.662986
-L 33.02356 22.959364
-L 33.091206 23.255742
-L 33.158853 23.55212
-L 33.226499 23.848499
-L 33.294145 24.144877
-L 33.361792 24.441255
-L 33.429438 24.737633
-L 33.497085 25.034011
-L 33.564731 25.330389
-L 33.632377 25.626767
-L 33.700024 25.923145
-L 33.76767 26.219523
-L 33.835316 26.515901
-L 33.902963 26.812279
-L 33.970609 27.108657
-L 34.038255 27.405036
-L 34.105902 27.701414
-L 34.173548 27.997792
-L 34.241195 28.29417
-L 34.308841 28.590548
-L 34.376487 28.886926
-L 34.444134 29.183304
-L 34.51178 29.479682
-L 34.579426 29.77606
-L 34.647073 30.072438
-L 34.714719 30.368816
-L 34.782365 30.665194
-L 34.850012 30.961573
-L 34.917658 31.257951
-L 34.985305 31.554329
-L 35.052951 31.850707
-L 35.120597 32.147085
-L 35.188244 32.443463
-L 35.25589 32.739841
-L 35.323536 33.036219
-L 35.391183 33.332597
-L 35.458829 33.628975
-L 35.526475 33.925353
-L 35.594122 34.221731
-L 35.661768 34.51811
-L 35.729415 34.814488
-L 35.797061 35.110866
-L 35.864707 35.407244
-L 35.932354 35.703622
-z
-" style="fill:#ff6800;stroke:#000000;stroke-linejoin:miter;"/>
- </g>
- <g id="patch_6">
- <path clip-path="url(#p2b9aa5bb59)" d="M 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 35.738275 36.047496
-L 35.476549 36.094992
-L 35.214824 36.142488
-L 34.953099 36.189985
-L 34.691374 36.237481
-L 34.429648 36.284977
-L 34.167923 36.332473
-L 33.906198 36.379969
-L 33.644473 36.427465
-L 33.382747 36.474961
-L 33.121022 36.522457
-L 32.859297 36.569954
-L 32.597571 36.61745
-L 32.335846 36.664946
-L 32.074121 36.712442
-L 31.812396 36.759938
-L 31.55067 36.807434
-L 31.288945 36.85493
-L 31.02722 36.902427
-L 30.765495 36.949923
-L 30.503769 36.997419
-L 30.242044 37.044915
-L 29.980319 37.092411
-L 29.718594 37.139907
-L 29.456868 37.187403
-L 29.195143 37.234899
-L 28.933418 37.282396
-L 28.671692 37.329892
-L 28.409967 37.377388
-L 28.148242 37.424884
-L 27.886517 37.47238
-L 27.624791 37.519876
-L 27.363066 37.567372
-L 27.101341 37.614869
-L 26.839616 37.662365
-L 26.57789 37.709861
-L 26.316165 37.757357
-L 26.05444 37.804853
-L 25.792714 37.852349
-L 25.530989 37.899845
-L 25.269264 37.947341
-L 25.007539 37.994838
-L 24.745813 38.042334
-L 24.484088 38.08983
-L 24.222363 38.137326
-L 23.960638 38.184822
-L 23.698912 38.232318
-L 23.437187 38.279814
-L 23.175462 38.327311
-L 22.913736 38.374807
-L 22.652011 38.422303
-L 22.390286 38.469799
-L 22.128561 38.517295
-L 21.866835 38.564791
-L 21.60511 38.612287
-L 21.343385 38.659784
-L 21.08166 38.70728
-L 20.819934 38.754776
-L 20.558209 38.802272
-L 20.296484 38.849768
-L 20.034758 38.897264
-L 19.773033 38.94476
-L 19.511308 38.992256
-L 19.249583 39.039753
-L 18.987857 39.087249
-L 18.726132 39.134745
-L 18.464407 39.182241
-L 18.202682 39.229737
-L 17.940956 39.277233
-L 17.679231 39.324729
-L 17.417506 39.372226
-L 17.155781 39.419722
-L 16.894055 39.467218
-L 16.63233 39.514714
-L 16.370605 39.56221
-L 16.108879 39.609706
-L 15.847154 39.657202
-L 15.585429 39.704698
-L 15.323704 39.752195
-L 15.061978 39.799691
-L 14.800253 39.847187
-L 14.538528 39.894683
-L 14.276803 39.942179
-L 14.015077 39.989675
-L 13.753352 40.037171
-L 13.491627 40.084668
-L 13.229901 40.132164
-L 12.968176 40.17966
-L 12.706451 40.227156
-L 12.444726 40.274652
-L 12.183 40.322148
-L 11.921275 40.369644
-L 11.65955 40.41714
-L 11.397825 40.464637
-L 11.136099 40.512133
-L 10.874374 40.559629
-L 10.612649 40.607125
-L 10.350923 40.654621
-L 10.089198 40.702117
-L 9.827473 40.749613
-L 9.798147 40.585074
-L 9.769856 40.420353
-L 9.7426 40.255458
-L 9.71638 40.090395
-L 9.691199 39.925171
-L 9.667055 39.759791
-L 9.643952 39.594263
-L 9.621889 39.428594
-L 9.600867 39.262789
-L 9.580888 39.096855
-L 9.561951 38.930798
-L 9.544058 38.764626
-L 9.52721 38.598345
-L 9.511407 38.431962
-L 9.496649 38.265482
-L 9.482938 38.098913
-L 9.470274 37.932261
-L 9.458657 37.765533
-L 9.448088 37.598735
-L 9.438567 37.431874
-L 9.430094 37.264956
-L 9.422671 37.097989
-L 9.416297 36.930978
-L 9.410972 36.76393
-L 9.406697 36.596853
-L 9.403472 36.429751
-L 9.401297 36.262633
-L 9.400171 36.095504
-L 9.400096 35.928372
-L 9.401072 35.761242
-L 9.403097 35.594122
-L 9.406172 35.427018
-L 9.410297 35.259936
-L 9.415472 35.092884
-L 9.421696 34.925867
-L 9.42897 34.758893
-L 9.437292 34.591968
-L 9.446663 34.425099
-L 9.457083 34.258291
-L 9.46855 34.091553
-L 9.481065 33.92489
-L 9.494627 33.758308
-L 9.509235 33.591815
-L 9.524889 33.425418
-L 9.541588 33.259121
-L 9.559331 33.092934
-L 9.578119 32.92686
-L 9.597949 32.760909
-L 9.618822 32.595085
-L 9.640736 32.429395
-L 9.663691 32.263847
-L 9.687686 32.098445
-L 9.712719 31.933198
-L 9.738791 31.768112
-L 9.765898 31.603193
-L 9.794042 31.438447
-L 9.82322 31.273881
-L 9.853432 31.109502
-L 9.884676 30.945316
-L 9.91695 30.781329
-L 9.950255 30.617548
-L 9.984588 30.45398
-L 10.019948 30.290631
-L 10.056333 30.127508
-L 10.093743 29.964616
-L 10.132176 29.801962
-L 10.17163 29.639553
-L 10.212103 29.477395
-L 10.253595 29.315495
-L 10.296102 29.153859
-L 10.339625 28.992493
-L 10.384161 28.831403
-L 10.429708 28.670597
-L 10.476264 28.510079
-L 10.523828 28.349858
-L 10.572398 28.189938
-L 10.621972 28.030327
-L 10.672547 27.871031
-L 10.724123 27.712055
-L 10.776696 27.553407
-L 10.830265 27.395092
-L 10.884828 27.237117
-L 10.940382 27.079487
-L 10.996925 26.92221
-L 11.054456 26.765292
-L 11.112971 26.608737
-L 11.172469 26.452554
-L 11.232947 26.296748
-L 11.294403 26.141324
-L 11.356834 25.98629
-L 11.420238 25.831651
-L 11.484613 25.677414
-L 11.549955 25.523584
-L 11.616262 25.370167
-L 11.683533 25.217171
-L 11.751763 25.0646
-L 11.82095 24.91246
-L 11.891092 24.760759
-L 11.962185 24.609501
-L 12.034228 24.458693
-L 12.273886 24.574106
-L 12.513544 24.689519
-L 12.753201 24.804932
-L 12.992859 24.920345
-L 13.232517 25.035758
-L 13.472174 25.151171
-L 13.711832 25.266584
-L 13.95149 25.381997
-L 14.191148 25.49741
-L 14.430805 25.612823
-L 14.670463 25.728236
-L 14.910121 25.843649
-L 15.149778 25.959063
-L 15.389436 26.074476
-L 15.629094 26.189889
-L 15.868752 26.305302
-L 16.108409 26.420715
-L 16.348067 26.536128
-L 16.587725 26.651541
-L 16.827382 26.766954
-L 17.06704 26.882367
-L 17.306698 26.99778
-L 17.546356 27.113193
-L 17.786013 27.228606
-L 18.025671 27.344019
-L 18.265329 27.459432
-L 18.504987 27.574846
-L 18.744644 27.690259
-L 18.984302 27.805672
-L 19.22396 27.921085
-L 19.463617 28.036498
-L 19.703275 28.151911
-L 19.942933 28.267324
-L 20.182591 28.382737
-L 20.422248 28.49815
-L 20.661906 28.613563
-L 20.901564 28.728976
-L 21.141221 28.844389
-L 21.380879 28.959802
-L 21.620537 29.075216
-L 21.860195 29.190629
-L 22.099852 29.306042
-L 22.33951 29.421455
-L 22.579168 29.536868
-L 22.818825 29.652281
-L 23.058483 29.767694
-L 23.298141 29.883107
-L 23.537799 29.99852
-L 23.777456 30.113933
-L 24.017114 30.229346
-L 24.256772 30.344759
-L 24.496429 30.460172
-L 24.736087 30.575585
-L 24.975745 30.690999
-L 25.215403 30.806412
-L 25.45506 30.921825
-L 25.694718 31.037238
-L 25.934376 31.152651
-L 26.174034 31.268064
-L 26.413691 31.383477
-L 26.653349 31.49889
-L 26.893007 31.614303
-L 27.132664 31.729716
-L 27.372322 31.845129
-L 27.61198 31.960542
-L 27.851638 32.075955
-L 28.091295 32.191369
-L 28.330953 32.306782
-L 28.570611 32.422195
-L 28.810268 32.537608
-L 29.049926 32.653021
-L 29.289584 32.768434
-L 29.529242 32.883847
-L 29.768899 32.99926
-L 30.008557 33.114673
-L 30.248215 33.230086
-L 30.487872 33.345499
-L 30.72753 33.460912
-L 30.967188 33.576325
-L 31.206846 33.691739
-L 31.446503 33.807152
-L 31.686161 33.922565
-L 31.925819 34.037978
-L 32.165476 34.153391
-L 32.405134 34.268804
-L 32.644792 34.384217
-L 32.88445 34.49963
-L 33.124107 34.615043
-L 33.363765 34.730456
-L 33.603423 34.845869
-L 33.843081 34.961282
-L 34.082738 35.076695
-L 34.322396 35.192108
-L 34.562054 35.307522
-L 34.801711 35.422935
-L 35.041369 35.538348
-L 35.281027 35.653761
-L 35.520685 35.769174
-L 35.760342 35.884587
-z
-" style="fill:#ffc400;stroke:#000000;stroke-linejoin:miter;"/>
- </g>
- <g id="patch_7">
- <path clip-path="url(#p2b9aa5bb59)" d="M 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 35.875056 36.086562
-L 35.750111 36.173123
-L 35.625167 36.259685
-L 35.500223 36.346247
-L 35.375278 36.432808
-L 35.250334 36.51937
-L 35.12539 36.605932
-L 35.000445 36.692493
-L 34.875501 36.779055
-L 34.750557 36.865616
-L 34.625613 36.952178
-L 34.500668 37.03874
-L 34.375724 37.125301
-L 34.25078 37.211863
-L 34.125835 37.298425
-L 34.000891 37.384986
-L 33.875947 37.471548
-L 33.751002 37.55811
-L 33.626058 37.644671
-L 33.501114 37.731233
-L 33.376169 37.817795
-L 33.251225 37.904356
-L 33.126281 37.990918
-L 33.001336 38.077479
-L 32.876392 38.164041
-L 32.751448 38.250603
-L 32.626503 38.337164
-L 32.501559 38.423726
-L 32.376615 38.510288
-L 32.251671 38.596849
-L 32.126726 38.683411
-L 32.001782 38.769973
-L 31.876838 38.856534
-L 31.751893 38.943096
-L 31.626949 39.029658
-L 31.502005 39.116219
-L 31.37706 39.202781
-L 31.252116 39.289342
-L 31.127172 39.375904
-L 31.002227 39.462466
-L 30.877283 39.549027
-L 30.752339 39.635589
-L 30.627394 39.722151
-L 30.50245 39.808712
-L 30.377506 39.895274
-L 30.252561 39.981836
-L 30.127617 40.068397
-L 30.002673 40.154959
-L 29.877729 40.241521
-L 29.752784 40.328082
-L 29.62784 40.414644
-L 29.502896 40.501205
-L 29.377951 40.587767
-L 29.253007 40.674329
-L 29.128063 40.76089
-L 29.003118 40.847452
-L 28.878174 40.934014
-L 28.75323 41.020575
-L 28.628285 41.107137
-L 28.503341 41.193699
-L 28.378397 41.28026
-L 28.253452 41.366822
-L 28.128508 41.453384
-L 28.003564 41.539945
-L 27.878619 41.626507
-L 27.753675 41.713068
-L 27.628731 41.79963
-L 27.503787 41.886192
-L 27.378842 41.972753
-L 27.253898 42.059315
-L 27.128954 42.145877
-L 27.004009 42.232438
-L 26.879065 42.319
-L 26.754121 42.405562
-L 26.629176 42.492123
-L 26.504232 42.578685
-L 26.379288 42.665247
-L 26.254343 42.751808
-L 26.129399 42.83837
-L 26.004455 42.924931
-L 25.87951 43.011493
-L 25.754566 43.098055
-L 25.629622 43.184616
-L 25.504678 43.271178
-L 25.379733 43.35774
-L 25.254789 43.444301
-L 25.129845 43.530863
-L 25.0049 43.617425
-L 24.879956 43.703986
-L 24.755012 43.790548
-L 24.630067 43.87711
-L 24.505123 43.963671
-L 24.380179 44.050233
-L 24.255234 44.136794
-L 24.13029 44.223356
-L 24.005346 44.309918
-L 23.880401 44.396479
-L 23.755457 44.483041
-L 23.630513 44.569603
-L 23.505568 44.656164
-L 23.491987 44.636527
-L 23.478436 44.616869
-L 23.464916 44.59719
-L 23.451427 44.577489
-L 23.437969 44.557767
-L 23.424542 44.538024
-L 23.411146 44.51826
-L 23.397781 44.498475
-L 23.384447 44.478669
-L 23.371145 44.458842
-L 23.357873 44.438995
-L 23.344633 44.419126
-L 23.331424 44.399237
-L 23.318246 44.379327
-L 23.305099 44.359396
-L 23.291984 44.339444
-L 23.2789 44.319472
-L 23.265848 44.29948
-L 23.252827 44.279467
-L 23.239837 44.259433
-L 23.226879 44.23938
-L 23.213952 44.219305
-L 23.201057 44.199211
-L 23.188194 44.179096
-L 23.175362 44.158962
-L 23.162562 44.138807
-L 23.149793 44.118632
-L 23.137056 44.098437
-L 23.124351 44.078222
-L 23.111678 44.057987
-L 23.099036 44.037732
-L 23.086426 44.017457
-L 23.073849 43.997163
-L 23.061303 43.976848
-L 23.048789 43.956514
-L 23.036306 43.936161
-L 23.023856 43.915788
-L 23.011438 43.895395
-L 22.999052 43.874983
-L 22.986698 43.854551
-L 22.974376 43.834101
-L 22.962087 43.81363
-L 22.949829 43.793141
-L 22.937604 43.772632
-L 22.925411 43.752104
-L 22.91325 43.731557
-L 22.901121 43.710991
-L 22.889025 43.690406
-L 22.876961 43.669802
-L 22.86493 43.649178
-L 22.852931 43.628536
-L 22.840964 43.607876
-L 22.82903 43.587196
-L 22.817128 43.566498
-L 22.805259 43.545781
-L 22.793422 43.525045
-L 22.781618 43.504291
-L 22.769847 43.483519
-L 22.758108 43.462728
-L 22.746402 43.441918
-L 22.734729 43.42109
-L 22.723088 43.400244
-L 22.71148 43.37938
-L 22.699905 43.358497
-L 22.688363 43.337596
-L 22.676853 43.316677
-L 22.665377 43.29574
-L 22.653933 43.274785
-L 22.642522 43.253812
-L 22.631145 43.232821
-L 22.6198 43.211813
-L 22.608488 43.190786
-L 22.597209 43.169742
-L 22.585964 43.14868
-L 22.574751 43.127601
-L 22.563572 43.106504
-L 22.552425 43.085389
-L 22.541312 43.064257
-L 22.530232 43.043107
-L 22.519186 43.02194
-L 22.508172 43.000756
-L 22.497192 42.979555
-L 22.486245 42.958336
-L 22.475332 42.9371
-L 22.464452 42.915847
-L 22.453605 42.894577
-L 22.442792 42.87329
-L 22.432012 42.851985
-L 22.421266 42.830664
-L 22.410553 42.809327
-L 22.399874 42.787972
-L 22.389228 42.766601
-L 22.378616 42.745213
-L 22.368037 42.723808
-L 22.357492 42.702386
-L 22.346981 42.680949
-L 22.336504 42.659494
-L 22.32606 42.638023
-L 22.31565 42.616536
-L 22.305273 42.595033
-L 22.44222 42.529083
-L 22.579168 42.463132
-L 22.716115 42.397182
-L 22.853062 42.331232
-L 22.99001 42.265281
-L 23.126957 42.199331
-L 23.263904 42.133381
-L 23.400851 42.06743
-L 23.537799 42.00148
-L 23.674746 41.93553
-L 23.811693 41.869579
-L 23.94864 41.803629
-L 24.085588 41.737679
-L 24.222535 41.671728
-L 24.359482 41.605778
-L 24.496429 41.539828
-L 24.633377 41.473877
-L 24.770324 41.407927
-L 24.907271 41.341977
-L 25.044219 41.276026
-L 25.181166 41.210076
-L 25.318113 41.144126
-L 25.45506 41.078175
-L 25.592008 41.012225
-L 25.728955 40.946275
-L 25.865902 40.880324
-L 26.002849 40.814374
-L 26.139797 40.748424
-L 26.276744 40.682473
-L 26.413691 40.616523
-L 26.550639 40.550573
-L 26.687586 40.484622
-L 26.824533 40.418672
-L 26.96148 40.352722
-L 27.098428 40.286771
-L 27.235375 40.220821
-L 27.372322 40.154871
-L 27.509269 40.08892
-L 27.646217 40.02297
-L 27.783164 39.95702
-L 27.920111 39.891069
-L 28.057058 39.825119
-L 28.194006 39.759169
-L 28.330953 39.693218
-L 28.4679 39.627268
-L 28.604848 39.561318
-L 28.741795 39.495367
-L 28.878742 39.429417
-L 29.015689 39.363467
-L 29.152637 39.297516
-L 29.289584 39.231566
-L 29.426531 39.165616
-L 29.563478 39.099665
-L 29.700426 39.033715
-L 29.837373 38.967765
-L 29.97432 38.901814
-L 30.111267 38.835864
-L 30.248215 38.769914
-L 30.385162 38.703963
-L 30.522109 38.638013
-L 30.659057 38.572063
-L 30.796004 38.506112
-L 30.932951 38.440162
-L 31.069898 38.374212
-L 31.206846 38.308261
-L 31.343793 38.242311
-L 31.48074 38.176361
-L 31.617687 38.110411
-L 31.754635 38.04446
-L 31.891582 37.97851
-L 32.028529 37.91256
-L 32.165476 37.846609
-L 32.302424 37.780659
-L 32.439371 37.714709
-L 32.576318 37.648758
-L 32.713266 37.582808
-L 32.850213 37.516858
-L 32.98716 37.450907
-L 33.124107 37.384957
-L 33.261055 37.319007
-L 33.398002 37.253056
-L 33.534949 37.187106
-L 33.671896 37.121156
-L 33.808844 37.055205
-L 33.945791 36.989255
-L 34.082738 36.923305
-L 34.219686 36.857354
-L 34.356633 36.791404
-L 34.49358 36.725454
-L 34.630527 36.659503
-L 34.767475 36.593553
-L 34.904422 36.527603
-L 35.041369 36.461652
-L 35.178316 36.395702
-L 35.315264 36.329752
-L 35.452211 36.263801
-L 35.589158 36.197851
-L 35.726105 36.131901
-L 35.863053 36.06595
-z
-" style="fill:#29ffce;stroke:#000000;stroke-linejoin:miter;"/>
- </g>
- <g id="patch_8">
- <path clip-path="url(#p2b9aa5bb59)" d="M 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36.031826 36.187315
-L 36.063652 36.374631
-L 36.095479 36.561946
-L 36.127305 36.749262
-L 36.159131 36.936577
-L 36.190957 37.123893
-L 36.222783 37.311208
-L 36.254609 37.498524
-L 36.286436 37.685839
-L 36.318262 37.873155
-L 36.350088 38.06047
-L 36.381914 38.247786
-L 36.41374 38.435101
-L 36.445567 38.622417
-L 36.477393 38.809732
-L 36.509219 38.997048
-L 36.541045 39.184363
-L 36.572871 39.371679
-L 36.604697 39.558994
-L 36.636524 39.74631
-L 36.66835 39.933625
-L 36.700176 40.120941
-L 36.732002 40.308256
-L 36.763828 40.495572
-L 36.795655 40.682887
-L 36.827481 40.870203
-L 36.859307 41.057518
-L 36.891133 41.244834
-L 36.922959 41.432149
-L 36.954785 41.619465
-L 36.986612 41.80678
-L 37.018438 41.994096
-L 37.050264 42.181411
-L 37.08209 42.368727
-L 37.113916 42.556042
-L 37.145743 42.743358
-L 37.177569 42.930673
-L 37.209395 43.117989
-L 37.241221 43.305304
-L 37.273047 43.49262
-L 37.304873 43.679935
-L 37.3367 43.867251
-L 37.368526 44.054566
-L 37.400352 44.241882
-L 37.432178 44.429197
-L 37.464004 44.616513
-L 37.495831 44.803828
-L 37.527657 44.991144
-L 37.559483 45.178459
-L 37.591309 45.365775
-L 37.623135 45.55309
-L 37.654961 45.740406
-L 37.686788 45.927721
-L 37.718614 46.115037
-L 37.75044 46.302352
-L 37.782266 46.489668
-L 37.814092 46.676983
-L 37.845919 46.864299
-L 37.877745 47.051614
-L 37.909571 47.23893
-L 37.941397 47.426245
-L 37.973223 47.613561
-L 38.005049 47.800876
-L 38.036876 47.988192
-L 38.068702 48.175507
-L 38.100528 48.362823
-L 38.132354 48.550138
-L 38.16418 48.737454
-L 38.196007 48.924769
-L 38.227833 49.112085
-L 38.259659 49.2994
-L 38.291485 49.486716
-L 38.323311 49.674031
-L 38.355137 49.861347
-L 38.386964 50.048662
-L 38.41879 50.235978
-L 38.450616 50.423293
-L 38.482442 50.610608
-L 38.514268 50.797924
-L 38.546095 50.985239
-L 38.577921 51.172555
-L 38.609747 51.35987
-L 38.641573 51.547186
-L 38.673399 51.734501
-L 38.705226 51.921817
-L 38.737052 52.109132
-L 38.768878 52.296448
-L 38.800704 52.483763
-L 38.83253 52.671079
-L 38.864356 52.858394
-L 38.896183 53.04571
-L 38.928009 53.233025
-L 38.959835 53.420341
-L 38.991661 53.607656
-L 39.023487 53.794972
-L 39.055314 53.982287
-L 39.08714 54.169603
-L 39.118966 54.356918
-L 39.150792 54.544234
-L 39.182618 54.731549
-L 39.109035 54.743903
-L 39.035404 54.755968
-L 38.961727 54.767743
-L 38.888003 54.779229
-L 38.814235 54.790425
-L 38.740424 54.801332
-L 38.66657 54.811948
-L 38.592676 54.822275
-L 38.518741 54.832311
-L 38.444767 54.842057
-L 38.370756 54.851512
-L 38.296708 54.860677
-L 38.222625 54.869551
-L 38.148508 54.878133
-L 38.074357 54.886425
-L 38.000174 54.894425
-L 37.925961 54.902134
-L 37.851718 54.909552
-L 37.777446 54.916677
-L 37.703147 54.923512
-L 37.628821 54.930054
-L 37.554471 54.936304
-L 37.480096 54.942263
-L 37.405699 54.947929
-L 37.33128 54.953303
-L 37.256841 54.958385
-L 37.182382 54.963174
-L 37.107905 54.967671
-L 37.03341 54.971876
-L 36.9589 54.975787
-L 36.884375 54.979407
-L 36.809837 54.982733
-L 36.735286 54.985767
-L 36.660723 54.988508
-L 36.586151 54.990956
-L 36.511569 54.993112
-L 36.436979 54.994974
-L 36.362383 54.996544
-L 36.287781 54.99782
-L 36.213175 54.998804
-L 36.138565 54.999495
-L 36.063954 54.999892
-L 35.989341 54.999997
-L 35.914728 54.999809
-L 35.840117 54.999327
-L 35.765509 54.998553
-L 35.690903 54.997486
-L 35.616303 54.996125
-L 35.541709 54.994472
-L 35.467121 54.992526
-L 35.392542 54.990287
-L 35.317972 54.987755
-L 35.243413 54.98493
-L 35.168865 54.981813
-L 35.09433 54.978403
-L 35.01981 54.9747
-L 34.945304 54.970704
-L 34.870814 54.966416
-L 34.796342 54.961836
-L 34.721889 54.956963
-L 34.647455 54.951797
-L 34.573042 54.94634
-L 34.498651 54.94059
-L 34.424284 54.934548
-L 34.34994 54.928214
-L 34.275622 54.921589
-L 34.201331 54.914671
-L 34.127067 54.907462
-L 34.052832 54.899961
-L 33.978627 54.892169
-L 33.904454 54.884086
-L 33.830313 54.875711
-L 33.756205 54.867045
-L 33.682131 54.858088
-L 33.608094 54.84884
-L 33.534093 54.839302
-L 33.460131 54.829473
-L 33.386207 54.819354
-L 33.312324 54.808945
-L 33.238483 54.798245
-L 33.164684 54.787256
-L 33.090928 54.775977
-L 33.017218 54.764408
-L 32.943553 54.75255
-L 32.869936 54.740403
-L 32.796367 54.727967
-L 32.722847 54.715242
-L 32.649378 54.702228
-L 32.575961 54.688926
-L 32.502596 54.675336
-L 32.429285 54.661458
-L 32.35603 54.647292
-L 32.28283 54.632838
-L 32.209688 54.618097
-L 32.136604 54.603069
-L 32.06358 54.587754
-L 31.990617 54.572152
-L 31.917715 54.556265
-L 31.844877 54.54009
-L 31.772102 54.52363
-L 31.814381 54.338394
-L 31.85666 54.153158
-L 31.898939 53.967921
-L 31.941218 53.782685
-L 31.983497 53.597449
-L 32.025776 53.412213
-L 32.068055 53.226976
-L 32.110334 53.04174
-L 32.152613 52.856504
-L 32.194892 52.671267
-L 32.237171 52.486031
-L 32.27945 52.300795
-L 32.321729 52.115558
-L 32.364008 51.930322
-L 32.406287 51.745086
-L 32.448566 51.559849
-L 32.490845 51.374613
-L 32.533124 51.189377
-L 32.575403 51.004141
-L 32.617682 50.818904
-L 32.659961 50.633668
-L 32.70224 50.448432
-L 32.744519 50.263195
-L 32.786798 50.077959
-L 32.829077 49.892723
-L 32.871356 49.707486
-L 32.913635 49.52225
-L 32.955914 49.337014
-L 32.998193 49.151778
-L 33.040472 48.966541
-L 33.082751 48.781305
-L 33.12503 48.596069
-L 33.167309 48.410832
-L 33.209587 48.225596
-L 33.251866 48.04036
-L 33.294145 47.855123
-L 33.336424 47.669887
-L 33.378703 47.484651
-L 33.420982 47.299415
-L 33.463261 47.114178
-L 33.50554 46.928942
-L 33.547819 46.743706
-L 33.590098 46.558469
-L 33.632377 46.373233
-L 33.674656 46.187997
-L 33.716935 46.00276
-L 33.759214 45.817524
-L 33.801493 45.632288
-L 33.843772 45.447051
-L 33.886051 45.261815
-L 33.92833 45.076579
-L 33.970609 44.891343
-L 34.012888 44.706106
-L 34.055167 44.52087
-L 34.097446 44.335634
-L 34.139725 44.150397
-L 34.182004 43.965161
-L 34.224283 43.779925
-L 34.266562 43.594688
-L 34.308841 43.409452
-L 34.35112 43.224216
-L 34.393399 43.03898
-L 34.435678 42.853743
-L 34.477957 42.668507
-L 34.520236 42.483271
-L 34.562515 42.298034
-L 34.604794 42.112798
-L 34.647073 41.927562
-L 34.689352 41.742325
-L 34.731631 41.557089
-L 34.77391 41.371853
-L 34.816189 41.186616
-L 34.858468 41.00138
-L 34.900747 40.816144
-L 34.943026 40.630908
-L 34.985305 40.445671
-L 35.027584 40.260435
-L 35.069862 40.075199
-L 35.112141 39.889962
-L 35.15442 39.704726
-L 35.196699 39.51949
-L 35.238978 39.334253
-L 35.281257 39.149017
-L 35.323536 38.963781
-L 35.365815 38.778545
-L 35.408094 38.593308
-L 35.450373 38.408072
-L 35.492652 38.222836
-L 35.534931 38.037599
-L 35.57721 37.852363
-L 35.619489 37.667127
-L 35.661768 37.48189
-L 35.704047 37.296654
-L 35.746326 37.111418
-L 35.788605 36.926182
-L 35.830884 36.740945
-L 35.873163 36.555709
-L 35.915442 36.370473
-L 35.957721 36.185236
-z
-" style="fill:#7dff7a;stroke:#000000;stroke-linejoin:miter;"/>
- </g>
- <g id="patch_9">
- <path clip-path="url(#p2b9aa5bb59)" d="M 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36 36
-L 36.239788 36.186862
-L 36.479577 36.373725
-L 36.719365 36.560587
-L 36.959154 36.747449
-L 37.198942 36.934311
-L 37.43873 37.121174
-L 37.678519 37.308036
-L 37.918307 37.494898
-L 38.158096 37.681761
-L 38.397884 37.868623
-L 38.637673 38.055485
-L 38.877461 38.242348
-L 39.117249 38.42921
-L 39.357038 38.616072
-L 39.596826 38.802934
-L 39.836615 38.989797
-L 40.076403 39.176659
-L 40.316191 39.363521
-L 40.55598 39.550384
-L 40.795768 39.737246
-L 41.035557 39.924108
-L 41.275345 40.110971
-L 41.515133 40.297833
-L 41.754922 40.484695
-L 41.99471 40.671557
-L 42.234499 40.85842
-L 42.474287 41.045282
-L 42.714075 41.232144
-L 42.953864 41.419007
-L 43.193652 41.605869
-L 43.433441 41.792731
-L 43.673229 41.979594
-L 43.913018 42.166456
-L 44.152806 42.353318
-L 44.392594 42.54018
-L 44.632383 42.727043
-L 44.872171 42.913905
-L 45.11196 43.100767
-L 45.351748 43.28763
-L 45.591536 43.474492
-L 45.831325 43.661354
-L 46.071113 43.848217
-L 46.310902 44.035079
-L 46.55069 44.221941
-L 46.790478 44.408803
-L 47.030267 44.595666
-L 47.270055 44.782528
-L 47.509844 44.96939
-L 47.749632 45.156253
-L 47.98942 45.343115
-L 48.229209 45.529977
-L 48.468997 45.71684
-L 48.708786 45.903702
-L 48.948574 46.090564
-L 49.188363 46.277426
-L 49.428151 46.464289
-L 49.667939 46.651151
-L 49.907728 46.838013
-L 50.147516 47.024876
-L 50.387305 47.211738
-L 50.627093 47.3986
-L 50.866881 47.585462
-L 51.10667 47.772325
-L 51.346458 47.959187
-L 51.586247 48.146049
-L 51.826035 48.332912
-L 52.065823 48.519774
-L 52.305612 48.706636
-L 52.5454 48.893499
-L 52.785189 49.080361
-L 53.024977 49.267223
-L 53.264766 49.454085
-L 53.504554 49.640948
-L 53.744342 49.82781
-L 53.984131 50.014672
-L 54.223919 50.201535
-L 54.463708 50.388397
-L 54.703496 50.575259
-L 54.943284 50.762122
-L 55.183073 50.948984
-L 55.422861 51.135846
-L 55.66265 51.322708
-L 55.902438 51.509571
-L 56.142226 51.696433
-L 56.382015 51.883295
-L 56.621803 52.070158
-L 56.861592 52.25702
-L 57.10138 52.443882
-L 57.341168 52.630745
-L 57.580957 52.817607
-L 57.820745 53.004469
-L 58.060534 53.191331
-L 58.300322 53.378194
-L 58.540111 53.565056
-L 58.779899 53.751918
-L 59.019687 53.938781
-L 59.259476 54.125643
-L 59.499264 54.312505
-L 59.739053 54.499368
-L 59.978841 54.68623
-L 59.934746 54.742677
-L 59.890518 54.79902
-L 59.846158 54.855258
-L 59.801665 54.911392
-L 59.75704 54.967421
-L 59.712283 55.023344
-L 59.667395 55.079162
-L 59.622375 55.134874
-L 59.577224 55.19048
-L 59.531942 55.245979
-L 59.486529 55.301371
-L 59.440987 55.356657
-L 59.395313 55.411834
-L 59.34951 55.466904
-L 59.303578 55.521866
-L 59.257516 55.57672
-L 59.211325 55.631464
-L 59.165005 55.6861
-L 59.118556 55.740627
-L 59.07198 55.795044
-L 59.025275 55.849351
-L 58.978442 55.903548
-L 58.931481 55.957634
-L 58.884394 56.01161
-L 58.837179 56.065474
-L 58.789837 56.119227
-L 58.742369 56.172869
-L 58.694775 56.226398
-L 58.647055 56.279815
-L 58.599209 56.33312
-L 58.551237 56.386311
-L 58.503141 56.43939
-L 58.454919 56.492355
-L 58.406573 56.545206
-L 58.358102 56.597943
-L 58.309507 56.650566
-L 58.260789 56.703074
-L 58.211947 56.755467
-L 58.162981 56.807745
-L 58.113892 56.859908
-L 58.064681 56.911955
-L 58.015347 56.963885
-L 57.965891 57.015699
-L 57.916313 57.067397
-L 57.866614 57.118978
-L 57.816792 57.170441
-L 57.76685 57.221787
-L 57.716787 57.273015
-L 57.666604 57.324124
-L 57.6163 57.375116
-L 57.565876 57.425989
-L 57.515332 57.476743
-L 57.464669 57.527377
-L 57.413887 57.577892
-L 57.362986 57.628288
-L 57.311966 57.678563
-L 57.260828 57.728718
-L 57.209572 57.778752
-L 57.158198 57.828666
-L 57.106707 57.878458
-L 57.055099 57.928129
-L 57.003373 57.977678
-L 56.951531 58.027105
-L 56.899573 58.076409
-L 56.847499 58.125591
-L 56.795309 58.174651
-L 56.743003 58.223587
-L 56.690583 58.2724
-L 56.638047 58.321089
-L 56.585397 58.369654
-L 56.532633 58.418095
-L 56.479754 58.466412
-L 56.426762 58.514604
-L 56.373657 58.562671
-L 56.320438 58.610612
-L 56.267107 58.658428
-L 56.213663 58.706119
-L 56.160107 58.753683
-L 56.106439 58.801121
-L 56.052659 58.848432
-L 55.998769 58.895617
-L 55.944767 58.942674
-L 55.890654 58.989604
-L 55.836431 59.036406
-L 55.782097 59.083081
-L 55.727654 59.129627
-L 55.673102 59.176045
-L 55.61844 59.222334
-L 55.563669 59.268495
-L 55.50879 59.314526
-L 55.453802 59.360428
-L 55.398706 59.4062
-L 55.343503 59.451842
-L 55.288192 59.497354
-L 55.232775 59.542735
-L 55.17725 59.587986
-L 55.121619 59.633106
-L 55.065882 59.678094
-L 55.010039 59.722952
-L 54.95409 59.767677
-L 54.764549 59.53
-L 54.575008 59.292324
-L 54.385467 59.054647
-L 54.195926 58.81697
-L 54.006385 58.579293
-L 53.816845 58.341616
-L 53.627304 58.10394
-L 53.437763 57.866263
-L 53.248222 57.628586
-L 53.058681 57.390909
-L 52.86914 57.153233
-L 52.679599 56.915556
-L 52.490058 56.677879
-L 52.300517 56.440202
-L 52.110976 56.202526
-L 51.921436 55.964849
-L 51.731895 55.727172
-L 51.542354 55.489495
-L 51.352813 55.251818
-L 51.163272 55.014142
-L 50.973731 54.776465
-L 50.78419 54.538788
-L 50.594649 54.301111
-L 50.405108 54.063435
-L 50.215567 53.825758
-L 50.026027 53.588081
-L 49.836486 53.350404
-L 49.646945 53.112727
-L 49.457404 52.875051
-L 49.267863 52.637374
-L 49.078322 52.399697
-L 48.888781 52.16202
-L 48.69924 51.924344
-L 48.509699 51.686667
-L 48.320158 51.44899
-L 48.130618 51.211313
-L 47.941077 50.973637
-L 47.751536 50.73596
-L 47.561995 50.498283
-L 47.372454 50.260606
-L 47.182913 50.022929
-L 46.993372 49.785253
-L 46.803831 49.547576
-L 46.61429 49.309899
-L 46.424749 49.072222
-L 46.235209 48.834546
-L 46.045668 48.596869
-L 45.856127 48.359192
-L 45.666586 48.121515
-L 45.477045 47.883839
-L 45.287504 47.646162
-L 45.097963 47.408485
-L 44.908422 47.170808
-L 44.718881 46.933131
-L 44.52934 46.695455
-L 44.3398 46.457778
-L 44.150259 46.220101
-L 43.960718 45.982424
-L 43.771177 45.744748
-L 43.581636 45.507071
-L 43.392095 45.269394
-L 43.202554 45.031717
-L 43.013013 44.794041
-L 42.823472 44.556364
-L 42.633931 44.318687
-L 42.444391 44.08101
-L 42.25485 43.843333
-L 42.065309 43.605657
-L 41.875768 43.36798
-L 41.686227 43.130303
-L 41.496686 42.892626
-L 41.307145 42.65495
-L 41.117604 42.417273
-L 40.928063 42.179596
-L 40.738522 41.941919
-L 40.548982 41.704242
-L 40.359441 41.466566
-L 40.1699 41.228889
-L 39.980359 40.991212
-L 39.790818 40.753535
-L 39.601277 40.515859
-L 39.411736 40.278182
-L 39.222195 40.040505
-L 39.032654 39.802828
-L 38.843113 39.565152
-L 38.653573 39.327475
-L 38.464032 39.089798
-L 38.274491 38.852121
-L 38.08495 38.614444
-L 37.895409 38.376768
-L 37.705868 38.139091
-L 37.516327 37.901414
-L 37.326786 37.663737
-L 37.137245 37.426061
-L 36.947704 37.188384
-L 36.758164 36.950707
-L 36.568623 36.71303
-L 36.379082 36.475354
-L 36.189541 36.237677
-z
-" style="fill:#ff6800;stroke:#000000;stroke-linejoin:miter;"/>
- </g>
- <g id="patch_10">
- <path d="M 36 70.2
-C 45.069946 70.2 53.769632 66.596472 60.183052 60.183052
-C 66.596472 53.769632 70.2 45.069946 70.2 36
-C 70.2 26.930054 66.596472 18.230368 60.183052 11.816948
-C 53.769632 5.403528 45.069946 1.8 36 1.8
-C 26.930054 1.8 18.230368 5.403528 11.816948 11.816948
-C 5.403528 18.230368 1.8 26.930054 1.8 36
-C 1.8 45.069946 5.403528 53.769632 11.816948 60.183052
-C 18.230368 66.596472 26.930054 70.2 36 70.2
-z
-" style="fill:none;stroke:#000000;stroke-linecap:square;stroke-linejoin:miter;stroke-width:0.8;"/>
- </g>
- </g>
- </g>
- <defs>
- <clipPath id="p2b9aa5bb59">
- <path d="M 36 70.2
-C 45.069946 70.2 53.769632 66.596472 60.183052 60.183052
-C 66.596472 53.769632 70.2 45.069946 70.2 36
-C 70.2 26.930054 66.596472 18.230368 60.183052 11.816948
-C 53.769632 5.403528 45.069946 1.8 36 1.8
-C 26.930054 1.8 18.230368 5.403528 11.816948 11.816948
-C 5.403528 18.230368 1.8 26.930054 1.8 36
-C 1.8 45.069946 5.403528 53.769632 11.816948 60.183052
-C 18.230368 66.596472 26.930054 70.2 36 70.2
-z
-"/>
- </clipPath>
- </defs>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/matplotlib_large.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/matplotlib_large.png
deleted file mode 100644
index c7dcfe6cb8..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/matplotlib_large.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move-symbolic.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move-symbolic.svg
deleted file mode 100644
index aa7198cf72..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move-symbolic.svg
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 70 37.44
-C 70 36.8025 69.734375 36.18625 69.2775 35.74
-L 59.56625 26.018125
-C 59.109375 25.56125 58.50375 25.295625 57.855625 25.295625
-C 56.5275 25.295625 55.433125 26.400625 55.433125 27.72875
-L 55.433125 32.584375
-L 40.855625 32.584375
-L 40.855625 18.0175
-L 45.71125 18.0175
-C 47.039375 18.0175 48.144375 16.9125 48.144375 15.584375
-C 48.144375 14.93625 47.87875 14.330625 47.421875 13.87375
-L 37.710625 4.1625
-C 37.25375 3.705625 36.648125 3.44 36 3.44
-C 35.351875 3.44 34.74625 3.705625 34.289375 4.1625
-L 24.578125 13.87375
-C 24.12125 14.330625 23.855625 14.93625 23.855625 15.584375
-C 23.855625 16.9125 24.960625 18.0175 26.28875 18.0175
-L 31.144375 18.0175
-L 31.144375 32.584375
-L 16.566875 32.584375
-L 16.566875 27.72875
-C 16.566875 26.400625 15.4725 25.295625 14.144375 25.295625
-C 13.49625 25.295625 12.890625 25.56125 12.43375 26.018125
-L 2.7225 35.74
-C 2.265625 36.18625 2 36.8025 2 37.44
-C 2 38.088125 2.265625 38.69375 2.7225 39.150625
-L 12.43375 48.861875
-C 12.890625 49.31875 13.49625 49.584375 14.144375 49.584375
-C 15.4725 49.584375 16.566875 48.49 16.566875 47.161875
-L 16.566875 42.295625
-L 31.144375 42.295625
-L 31.144375 56.873125
-L 26.28875 56.873125
-C 24.960625 56.873125 23.855625 57.9675 23.855625 59.295625
-C 23.855625 59.94375 24.12125 60.549375 24.578125 61.00625
-L 34.289375 70.7175
-C 34.74625 71.174375 35.351875 71.44 36 71.44
-C 36.648125 71.44 37.25375 71.174375 37.710625 70.7175
-L 47.421875 61.00625
-C 47.87875 60.549375 48.144375 59.94375 48.144375 59.295625
-C 48.144375 57.9675 47.039375 56.873125 45.71125 56.873125
-L 40.855625 56.873125
-L 40.855625 42.295625
-L 55.433125 42.295625
-L 55.433125 47.161875
-C 55.433125 48.49 56.5275 49.584375 57.855625 49.584375
-C 58.50375 49.584375 59.109375 49.31875 59.56625 48.861875
-L 69.2775 39.150625
-C 69.734375 38.69375 70 38.088125 70 37.44
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move.pdf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move.pdf
deleted file mode 100644
index d883d9224a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move.pdf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move.png
deleted file mode 100644
index 4fbbaef41b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move.svg
deleted file mode 100644
index aa7198cf72..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move.svg
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 70 37.44
-C 70 36.8025 69.734375 36.18625 69.2775 35.74
-L 59.56625 26.018125
-C 59.109375 25.56125 58.50375 25.295625 57.855625 25.295625
-C 56.5275 25.295625 55.433125 26.400625 55.433125 27.72875
-L 55.433125 32.584375
-L 40.855625 32.584375
-L 40.855625 18.0175
-L 45.71125 18.0175
-C 47.039375 18.0175 48.144375 16.9125 48.144375 15.584375
-C 48.144375 14.93625 47.87875 14.330625 47.421875 13.87375
-L 37.710625 4.1625
-C 37.25375 3.705625 36.648125 3.44 36 3.44
-C 35.351875 3.44 34.74625 3.705625 34.289375 4.1625
-L 24.578125 13.87375
-C 24.12125 14.330625 23.855625 14.93625 23.855625 15.584375
-C 23.855625 16.9125 24.960625 18.0175 26.28875 18.0175
-L 31.144375 18.0175
-L 31.144375 32.584375
-L 16.566875 32.584375
-L 16.566875 27.72875
-C 16.566875 26.400625 15.4725 25.295625 14.144375 25.295625
-C 13.49625 25.295625 12.890625 25.56125 12.43375 26.018125
-L 2.7225 35.74
-C 2.265625 36.18625 2 36.8025 2 37.44
-C 2 38.088125 2.265625 38.69375 2.7225 39.150625
-L 12.43375 48.861875
-C 12.890625 49.31875 13.49625 49.584375 14.144375 49.584375
-C 15.4725 49.584375 16.566875 48.49 16.566875 47.161875
-L 16.566875 42.295625
-L 31.144375 42.295625
-L 31.144375 56.873125
-L 26.28875 56.873125
-C 24.960625 56.873125 23.855625 57.9675 23.855625 59.295625
-C 23.855625 59.94375 24.12125 60.549375 24.578125 61.00625
-L 34.289375 70.7175
-C 34.74625 71.174375 35.351875 71.44 36 71.44
-C 36.648125 71.44 37.25375 71.174375 37.710625 70.7175
-L 47.421875 61.00625
-C 47.87875 60.549375 48.144375 59.94375 48.144375 59.295625
-C 48.144375 57.9675 47.039375 56.873125 45.71125 56.873125
-L 40.855625 56.873125
-L 40.855625 42.295625
-L 55.433125 42.295625
-L 55.433125 47.161875
-C 55.433125 48.49 56.5275 49.584375 57.855625 49.584375
-C 58.50375 49.584375 59.109375 49.31875 59.56625 48.861875
-L 69.2775 39.150625
-C 69.734375 38.69375 70 38.088125 70 37.44
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move_large.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move_large.png
deleted file mode 100644
index 96351c115f..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/move_large.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/qt4_editor_options.pdf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/qt4_editor_options.pdf
deleted file mode 100644
index a92f2cc3aa..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/qt4_editor_options.pdf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/qt4_editor_options.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/qt4_editor_options.png
deleted file mode 100644
index 792ec81244..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/qt4_editor_options.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/qt4_editor_options.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/qt4_editor_options.svg
deleted file mode 100644
index 0b46bf8092..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/qt4_editor_options.svg
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 74.855625 61.72875
-L 2 61.72875
-L 2 8.295625
-L -2.855625 8.295625
-L -2.855625 66.584375
-L 74.855625 66.584375
-z
-M 70 14.373125
-C 70 13.693125 69.46875 13.161875 68.78875 13.161875
-L 52.2775 13.161875
-C 51.215 13.161875 50.651875 14.4475 51.44875 15.244375
-L 56.03875 19.834375
-L 38.433125 37.44
-L 29.593125 28.6
-C 29.09375 28.11125 28.339375 28.11125 27.84 28.6
-L 5.644375 50.795625
-L 12.933125 58.084375
-L 28.71125 42.295625
-L 37.561875 51.14625
-C 38.050625 51.635 38.805 51.635 39.304375 51.14625
-L 63.3275 27.123125
-L 67.9175 31.713125
-C 68.714375 32.51 70 31.93625 70 30.87375
-z
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/qt4_editor_options_large.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/qt4_editor_options_large.png
deleted file mode 100644
index 46d52c91c9..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/qt4_editor_options_large.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots-symbolic.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots-symbolic.svg
deleted file mode 100644
index e87d2c9b1b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots-symbolic.svg
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 20.21125 56.873125
-L 6.855625 56.873125
-L 6.855625 61.72875
-L 20.21125 61.72875
-z
-M 33.566875 52.0175
-L 23.855625 52.0175
-C 22.5275 52.0175 21.4225 53.111875 21.4225 54.44
-L 21.4225 64.161875
-C 21.4225 65.49 22.5275 66.584375 23.855625 66.584375
-L 33.566875 66.584375
-C 34.895 66.584375 36 65.49 36 64.161875
-L 36 54.44
-C 36 53.111875 34.895 52.0175 33.566875 52.0175
-M 39.644375 37.44
-L 6.855625 37.44
-L 6.855625 42.295625
-L 39.644375 42.295625
-z
-M 15.355625 18.0175
-L 6.855625 18.0175
-L 6.855625 22.873125
-L 15.355625 22.873125
-z
-M 65.144375 56.873125
-L 37.21125 56.873125
-L 37.21125 61.72875
-L 65.144375 61.72875
-z
-M 28.71125 13.161875
-L 19 13.161875
-C 17.671875 13.161875 16.566875 14.25625 16.566875 15.584375
-L 16.566875 25.295625
-C 16.566875 26.62375 17.671875 27.72875 19 27.72875
-L 28.71125 27.72875
-C 30.039375 27.72875 31.144375 26.62375 31.144375 25.295625
-L 31.144375 15.584375
-C 31.144375 14.25625 30.039375 13.161875 28.71125 13.161875
-M 53 32.584375
-L 43.28875 32.584375
-C 41.960625 32.584375 40.855625 33.689375 40.855625 35.0175
-L 40.855625 44.72875
-C 40.855625 46.056875 41.960625 47.161875 43.28875 47.161875
-L 53 47.161875
-C 54.328125 47.161875 55.4225 46.056875 55.4225 44.72875
-L 55.4225 35.0175
-C 55.4225 33.689375 54.328125 32.584375 53 32.584375
-M 65.144375 37.44
-L 56.644375 37.44
-L 56.644375 42.295625
-L 65.144375 42.295625
-z
-M 65.144375 18.0175
-L 32.355625 18.0175
-L 32.355625 22.873125
-L 65.144375 22.873125
-z
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots.pdf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots.pdf
deleted file mode 100644
index f404665579..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots.pdf
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots.png
deleted file mode 100644
index bb0318c40e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots.svg
deleted file mode 100644
index e87d2c9b1b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots.svg
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 20.21125 56.873125
-L 6.855625 56.873125
-L 6.855625 61.72875
-L 20.21125 61.72875
-z
-M 33.566875 52.0175
-L 23.855625 52.0175
-C 22.5275 52.0175 21.4225 53.111875 21.4225 54.44
-L 21.4225 64.161875
-C 21.4225 65.49 22.5275 66.584375 23.855625 66.584375
-L 33.566875 66.584375
-C 34.895 66.584375 36 65.49 36 64.161875
-L 36 54.44
-C 36 53.111875 34.895 52.0175 33.566875 52.0175
-M 39.644375 37.44
-L 6.855625 37.44
-L 6.855625 42.295625
-L 39.644375 42.295625
-z
-M 15.355625 18.0175
-L 6.855625 18.0175
-L 6.855625 22.873125
-L 15.355625 22.873125
-z
-M 65.144375 56.873125
-L 37.21125 56.873125
-L 37.21125 61.72875
-L 65.144375 61.72875
-z
-M 28.71125 13.161875
-L 19 13.161875
-C 17.671875 13.161875 16.566875 14.25625 16.566875 15.584375
-L 16.566875 25.295625
-C 16.566875 26.62375 17.671875 27.72875 19 27.72875
-L 28.71125 27.72875
-C 30.039375 27.72875 31.144375 26.62375 31.144375 25.295625
-L 31.144375 15.584375
-C 31.144375 14.25625 30.039375 13.161875 28.71125 13.161875
-M 53 32.584375
-L 43.28875 32.584375
-C 41.960625 32.584375 40.855625 33.689375 40.855625 35.0175
-L 40.855625 44.72875
-C 40.855625 46.056875 41.960625 47.161875 43.28875 47.161875
-L 53 47.161875
-C 54.328125 47.161875 55.4225 46.056875 55.4225 44.72875
-L 55.4225 35.0175
-C 55.4225 33.689375 54.328125 32.584375 53 32.584375
-M 65.144375 37.44
-L 56.644375 37.44
-L 56.644375 42.295625
-L 65.144375 42.295625
-z
-M 65.144375 18.0175
-L 32.355625 18.0175
-L 32.355625 22.873125
-L 65.144375 22.873125
-z
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots_large.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots_large.png
deleted file mode 100644
index 4440af1759..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/subplots_large.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect-symbolic.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect-symbolic.svg
deleted file mode 100644
index f4b69b23c5..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect-symbolic.svg
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 48.139062 32.589687
-C 48.139062 41.960938 40.510312 49.589687 31.139063 49.589687
-C 21.767812 49.589687 14.139062 41.960938 14.139062 32.589687
-C 14.139062 23.218437 21.767812 15.589687 31.139063 15.589687
-C 40.510312 15.589687 48.139062 23.218437 48.139062 32.589687
-M 67.572187 64.156562
-C 67.572187 62.870937 67.040937 61.617188 66.169688 60.745937
-L 53.154062 47.730312
-C 56.224688 43.289062 57.860938 37.976562 57.860938 32.589687
-C 57.860938 17.820937 45.907813 5.867812 31.139063 5.867812
-C 16.380937 5.867812 4.427812 17.820937 4.427812 32.589687
-C 4.427812 47.347812 16.380937 59.300937 31.139063 59.300937
-C 36.525937 59.300937 41.838437 57.664687 46.279687 54.594062
-L 59.295313 67.577812
-C 60.166562 68.480937 61.420313 69.012187 62.716563 69.012187
-C 65.372813 69.012187 67.572187 66.812812 67.572187 64.156562
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect.pdf b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect.pdf
deleted file mode 100644
index 22add33bb8..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect.pdf
+++ /dev/null
@@ -1,68 +0,0 @@
-%PDF-1.4
-%
-1 0 obj
-<< /Pages 2 0 R /Type /Catalog >>
-endobj
-8 0 obj
-<< /ExtGState 4 0 R /Font 3 0 R /Pattern 5 0 R
-/ProcSet [ /PDF /Text /ImageB /ImageC /ImageI ] /Shading 6 0 R
-/XObject 7 0 R >>
-endobj
-10 0 obj
-<< /Annots [ ] /Contents 9 0 R
-/Group << /CS /DeviceRGB /S /Transparency /Type /Group >>
-/MediaBox [ 0 0 72 72 ] /Parent 2 0 R /Resources 8 0 R /Type /Page >>
-endobj
-9 0 obj
-<< /Filter /FlateDecode /Length 11 0 R >>
-stream
-xmRKn1 >b},޾W$in/mHؠ$,鍞Hz}O9$ӷ??﷯x Uq;y ] ,q'[M٥Gk 7<sU&+5pT/XX.7ٌ}PT.s`܊61 cŦs@$O*%,2{pV#~'xSp T SҜhNa4}'17QgY|!|@WD3ٓNk[xcYp:loԅvspX!]FMw^Ǡa¦"ĒZzWA@NfV;]OABh
-endstream
-endobj
-11 0 obj
-375
-endobj
-3 0 obj
-<< >>
-endobj
-4 0 obj
-<< /A1 << /CA 0 /Type /ExtGState /ca 0 >>
-/A2 << /CA 1 /Type /ExtGState /ca 1 >> >>
-endobj
-5 0 obj
-<< >>
-endobj
-6 0 obj
-<< >>
-endobj
-7 0 obj
-<< >>
-endobj
-2 0 obj
-<< /Count 1 /Kids [ 10 0 R ] /Type /Pages >>
-endobj
-12 0 obj
-<< /CreationDate (D:20160601123507-04'00')
-/Creator (matplotlib 1.5.2rc2.post1933.dev0+gb775a26, http://matplotlib.org)
-/Producer (matplotlib pdf backend) >>
-endobj
-xref
-0 13
-0000000000 65535 f
-0000000016 00000 n
-0000001036 00000 n
-0000000853 00000 n
-0000000874 00000 n
-0000000973 00000 n
-0000000994 00000 n
-0000001015 00000 n
-0000000065 00000 n
-0000000383 00000 n
-0000000208 00000 n
-0000000833 00000 n
-0000001096 00000 n
-trailer
-<< /Info 12 0 R /Root 1 0 R /Size 13 >>
-startxref
-1270
-%%EOF
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect.png
deleted file mode 100644
index 12afa25248..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect.svg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect.svg
deleted file mode 100644
index f4b69b23c5..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect.svg
+++ /dev/null
@@ -1,40 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!-- Created with matplotlib (http://matplotlib.org/) -->
-<svg height="72pt" version="1.1" viewBox="0 0 72 72" width="72pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <defs>
- <style type="text/css">
-*{stroke-linecap:butt;stroke-linejoin:round;}
- </style>
- </defs>
- <g id="figure_1">
- <g id="patch_1">
- <path d="M 0 72
-L 72 72
-L 72 0
-L 0 0
-z
-" style="fill:none;opacity:0;"/>
- </g>
- <g id="text_1">
- <path d="M 48.139062 32.589687
-C 48.139062 41.960938 40.510312 49.589687 31.139063 49.589687
-C 21.767812 49.589687 14.139062 41.960938 14.139062 32.589687
-C 14.139062 23.218437 21.767812 15.589687 31.139063 15.589687
-C 40.510312 15.589687 48.139062 23.218437 48.139062 32.589687
-M 67.572187 64.156562
-C 67.572187 62.870937 67.040937 61.617188 66.169688 60.745937
-L 53.154062 47.730312
-C 56.224688 43.289062 57.860938 37.976562 57.860938 32.589687
-C 57.860938 17.820937 45.907813 5.867812 31.139063 5.867812
-C 16.380937 5.867812 4.427812 17.820937 4.427812 32.589687
-C 4.427812 47.347812 16.380937 59.300937 31.139063 59.300937
-C 36.525937 59.300937 41.838437 57.664687 46.279687 54.594062
-L 59.295313 67.577812
-C 60.166562 68.480937 61.420313 69.012187 62.716563 69.012187
-C 65.372813 69.012187 67.572187 66.812812 67.572187 64.156562
-"/>
- </g>
- </g>
-</svg>
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect_large.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect_large.png
deleted file mode 100644
index 5963603bb6..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/images/zoom_to_rect_large.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/kpsewhich.lua b/contrib/python/matplotlib/py3/matplotlib/mpl-data/kpsewhich.lua
deleted file mode 100644
index 8e9172a450..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/kpsewhich.lua
+++ /dev/null
@@ -1,3 +0,0 @@
--- see dviread._LuatexKpsewhich
-kpse.set_program_name("latex")
-while true do print(kpse.lookup(io.read():gsub("\r", ""))); io.flush(); end
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/matplotlibrc b/contrib/python/matplotlib/py3/matplotlib/mpl-data/matplotlibrc
deleted file mode 100644
index 5014aa4489..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/matplotlibrc
+++ /dev/null
@@ -1,798 +0,0 @@
-#### MATPLOTLIBRC FORMAT
-
-## NOTE FOR END USERS: DO NOT EDIT THIS FILE!
-##
-## This is a sample Matplotlib configuration file - you can find a copy
-## of it on your system in site-packages/matplotlib/mpl-data/matplotlibrc
-## (relative to your Python installation location).
-## DO NOT EDIT IT!
-##
-## If you wish to change your default style, copy this file to one of the
-## following locations:
-## Unix/Linux:
-## $HOME/.config/matplotlib/matplotlibrc OR
-## $XDG_CONFIG_HOME/matplotlib/matplotlibrc (if $XDG_CONFIG_HOME is set)
-## Other platforms:
-## $HOME/.matplotlib/matplotlibrc
-## and edit that copy.
-##
-## See https://matplotlib.org/stable/users/explain/customizing.html#customizing-with-matplotlibrc-files
-## for more details on the paths which are checked for the configuration file.
-##
-## Blank lines, or lines starting with a comment symbol, are ignored, as are
-## trailing comments. Other lines must have the format:
-## key: val # optional comment
-##
-## Formatting: Use PEP8-like style (as enforced in the rest of the codebase).
-## All lines start with an additional '#', so that removing all leading '#'s
-## yields a valid style file.
-##
-## Colors: for the color values below, you can either use
-## - a Matplotlib color string, such as r, k, or b
-## - an RGB tuple, such as (1.0, 0.5, 0.0)
-## - a double-quoted hex string, such as "#ff00ff".
-## The unquoted string ff00ff is also supported for backward
-## compatibility, but is discouraged.
-## - a scalar grayscale intensity such as 0.75
-## - a legal html color name, e.g., red, blue, darkslategray
-##
-## String values may optionally be enclosed in double quotes, which allows
-## using the comment character # in the string.
-##
-## This file (and other style files) must be encoded as utf-8.
-##
-## Matplotlib configuration are currently divided into following parts:
-## - BACKENDS
-## - LINES
-## - PATCHES
-## - HATCHES
-## - BOXPLOT
-## - FONT
-## - TEXT
-## - LaTeX
-## - AXES
-## - DATES
-## - TICKS
-## - GRIDS
-## - LEGEND
-## - FIGURE
-## - IMAGES
-## - CONTOUR PLOTS
-## - ERRORBAR PLOTS
-## - HISTOGRAM PLOTS
-## - SCATTER PLOTS
-## - AGG RENDERING
-## - PATHS
-## - SAVING FIGURES
-## - INTERACTIVE KEYMAPS
-## - ANIMATION
-
-##### CONFIGURATION BEGINS HERE
-
-
-## ***************************************************************************
-## * BACKENDS *
-## ***************************************************************************
-## The default backend. If you omit this parameter, the first working
-## backend from the following list is used:
-## MacOSX QtAgg Gtk4Agg Gtk3Agg TkAgg WxAgg Agg
-## Other choices include:
-## QtCairo GTK4Cairo GTK3Cairo TkCairo WxCairo Cairo
-## Qt5Agg Qt5Cairo Wx # deprecated.
-## PS PDF SVG Template
-## You can also deploy your own backend outside of Matplotlib by referring to
-## the module name (which must be in the PYTHONPATH) as 'module://my_backend'.
-##backend: Agg
-
-## The port to use for the web server in the WebAgg backend.
-#webagg.port: 8988
-
-## The address on which the WebAgg web server should be reachable
-#webagg.address: 127.0.0.1
-
-## If webagg.port is unavailable, a number of other random ports will
-## be tried until one that is available is found.
-#webagg.port_retries: 50
-
-## When True, open the web browser to the plot that is shown
-#webagg.open_in_browser: True
-
-## If you are running pyplot inside a GUI and your backend choice
-## conflicts, we will automatically try to find a compatible one for
-## you if backend_fallback is True
-#backend_fallback: True
-
-#interactive: False
-#figure.hooks: # list of dotted.module.name:dotted.callable.name
-#toolbar: toolbar2 # {None, toolbar2, toolmanager}
-#timezone: UTC # a pytz timezone string, e.g., US/Central or Europe/Paris
-
-
-## ***************************************************************************
-## * LINES *
-## ***************************************************************************
-## See https://matplotlib.org/stable/api/artist_api.html#module-matplotlib.lines
-## for more information on line properties.
-#lines.linewidth: 1.5 # line width in points
-#lines.linestyle: - # solid line
-#lines.color: C0 # has no affect on plot(); see axes.prop_cycle
-#lines.marker: None # the default marker
-#lines.markerfacecolor: auto # the default marker face color
-#lines.markeredgecolor: auto # the default marker edge color
-#lines.markeredgewidth: 1.0 # the line width around the marker symbol
-#lines.markersize: 6 # marker size, in points
-#lines.dash_joinstyle: round # {miter, round, bevel}
-#lines.dash_capstyle: butt # {butt, round, projecting}
-#lines.solid_joinstyle: round # {miter, round, bevel}
-#lines.solid_capstyle: projecting # {butt, round, projecting}
-#lines.antialiased: True # render lines in antialiased (no jaggies)
-
-## The three standard dash patterns. These are scaled by the linewidth.
-#lines.dashed_pattern: 3.7, 1.6
-#lines.dashdot_pattern: 6.4, 1.6, 1, 1.6
-#lines.dotted_pattern: 1, 1.65
-#lines.scale_dashes: True
-
-#markers.fillstyle: full # {full, left, right, bottom, top, none}
-
-#pcolor.shading: auto
-#pcolormesh.snap: True # Whether to snap the mesh to pixel boundaries. This is
- # provided solely to allow old test images to remain
- # unchanged. Set to False to obtain the previous behavior.
-
-## ***************************************************************************
-## * PATCHES *
-## ***************************************************************************
-## Patches are graphical objects that fill 2D space, like polygons or circles.
-## See https://matplotlib.org/stable/api/artist_api.html#module-matplotlib.patches
-## for more information on patch properties.
-#patch.linewidth: 1.0 # edge width in points.
-#patch.facecolor: C0
-#patch.edgecolor: black # if forced, or patch is not filled
-#patch.force_edgecolor: False # True to always use edgecolor
-#patch.antialiased: True # render patches in antialiased (no jaggies)
-
-
-## ***************************************************************************
-## * HATCHES *
-## ***************************************************************************
-#hatch.color: black
-#hatch.linewidth: 1.0
-
-
-## ***************************************************************************
-## * BOXPLOT *
-## ***************************************************************************
-#boxplot.notch: False
-#boxplot.vertical: True
-#boxplot.whiskers: 1.5
-#boxplot.bootstrap: None
-#boxplot.patchartist: False
-#boxplot.showmeans: False
-#boxplot.showcaps: True
-#boxplot.showbox: True
-#boxplot.showfliers: True
-#boxplot.meanline: False
-
-#boxplot.flierprops.color: black
-#boxplot.flierprops.marker: o
-#boxplot.flierprops.markerfacecolor: none
-#boxplot.flierprops.markeredgecolor: black
-#boxplot.flierprops.markeredgewidth: 1.0
-#boxplot.flierprops.markersize: 6
-#boxplot.flierprops.linestyle: none
-#boxplot.flierprops.linewidth: 1.0
-
-#boxplot.boxprops.color: black
-#boxplot.boxprops.linewidth: 1.0
-#boxplot.boxprops.linestyle: -
-
-#boxplot.whiskerprops.color: black
-#boxplot.whiskerprops.linewidth: 1.0
-#boxplot.whiskerprops.linestyle: -
-
-#boxplot.capprops.color: black
-#boxplot.capprops.linewidth: 1.0
-#boxplot.capprops.linestyle: -
-
-#boxplot.medianprops.color: C1
-#boxplot.medianprops.linewidth: 1.0
-#boxplot.medianprops.linestyle: -
-
-#boxplot.meanprops.color: C2
-#boxplot.meanprops.marker: ^
-#boxplot.meanprops.markerfacecolor: C2
-#boxplot.meanprops.markeredgecolor: C2
-#boxplot.meanprops.markersize: 6
-#boxplot.meanprops.linestyle: --
-#boxplot.meanprops.linewidth: 1.0
-
-
-## ***************************************************************************
-## * FONT *
-## ***************************************************************************
-## The font properties used by `text.Text`.
-## See https://matplotlib.org/stable/api/font_manager_api.html for more information
-## on font properties. The 6 font properties used for font matching are
-## given below with their default values.
-##
-## The font.family property can take either a single or multiple entries of any
-## combination of concrete font names (not supported when rendering text with
-## usetex) or the following five generic values:
-## - 'serif' (e.g., Times),
-## - 'sans-serif' (e.g., Helvetica),
-## - 'cursive' (e.g., Zapf-Chancery),
-## - 'fantasy' (e.g., Western), and
-## - 'monospace' (e.g., Courier).
-## Each of these values has a corresponding default list of font names
-## (font.serif, etc.); the first available font in the list is used. Note that
-## for font.serif, font.sans-serif, and font.monospace, the first element of
-## the list (a DejaVu font) will always be used because DejaVu is shipped with
-## Matplotlib and is thus guaranteed to be available; the other entries are
-## left as examples of other possible values.
-##
-## The font.style property has three values: normal (or roman), italic
-## or oblique. The oblique style will be used for italic, if it is not
-## present.
-##
-## The font.variant property has two values: normal or small-caps. For
-## TrueType fonts, which are scalable fonts, small-caps is equivalent
-## to using a font size of 'smaller', or about 83 % of the current font
-## size.
-##
-## The font.weight property has effectively 13 values: normal, bold,
-## bolder, lighter, 100, 200, 300, ..., 900. Normal is the same as
-## 400, and bold is 700. bolder and lighter are relative values with
-## respect to the current weight.
-##
-## The font.stretch property has 11 values: ultra-condensed,
-## extra-condensed, condensed, semi-condensed, normal, semi-expanded,
-## expanded, extra-expanded, ultra-expanded, wider, and narrower. This
-## property is not currently implemented.
-##
-## The font.size property is the default font size for text, given in points.
-## 10 pt is the standard value.
-##
-## Note that font.size controls default text sizes. To configure
-## special text sizes tick labels, axes, labels, title, etc., see the rc
-## settings for axes and ticks. Special text sizes can be defined
-## relative to font.size, using the following values: xx-small, x-small,
-## small, medium, large, x-large, xx-large, larger, or smaller
-
-#font.family: sans-serif
-#font.style: normal
-#font.variant: normal
-#font.weight: normal
-#font.stretch: normal
-#font.size: 10.0
-
-#font.serif: DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif
-#font.sans-serif: DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
-#font.cursive: Apple Chancery, Textile, Zapf Chancery, Sand, Script MT, Felipa, Comic Neue, Comic Sans MS, cursive
-#font.fantasy: Chicago, Charcoal, Impact, Western, xkcd script, fantasy
-#font.monospace: DejaVu Sans Mono, Bitstream Vera Sans Mono, Computer Modern Typewriter, Andale Mono, Nimbus Mono L, Courier New, Courier, Fixed, Terminal, monospace
-
-
-## ***************************************************************************
-## * TEXT *
-## ***************************************************************************
-## The text properties used by `text.Text`.
-## See https://matplotlib.org/stable/api/artist_api.html#module-matplotlib.text
-## for more information on text properties
-#text.color: black
-
-## FreeType hinting flag ("foo" corresponds to FT_LOAD_FOO); may be one of the
-## following (Proprietary Matplotlib-specific synonyms are given in parentheses,
-## but their use is discouraged):
-## - default: Use the font's native hinter if possible, else FreeType's auto-hinter.
-## ("either" is a synonym).
-## - no_autohint: Use the font's native hinter if possible, else don't hint.
-## ("native" is a synonym.)
-## - force_autohint: Use FreeType's auto-hinter. ("auto" is a synonym.)
-## - no_hinting: Disable hinting. ("none" is a synonym.)
-#text.hinting: force_autohint
-
-#text.hinting_factor: 8 # Specifies the amount of softness for hinting in the
- # horizontal direction. A value of 1 will hint to full
- # pixels. A value of 2 will hint to half pixels etc.
-#text.kerning_factor: 0 # Specifies the scaling factor for kerning values. This
- # is provided solely to allow old test images to remain
- # unchanged. Set to 6 to obtain previous behavior.
- # Values other than 0 or 6 have no defined meaning.
-#text.antialiased: True # If True (default), the text will be antialiased.
- # This only affects raster outputs.
-#text.parse_math: True # Use mathtext if there is an even number of unescaped
- # dollar signs.
-
-
-## ***************************************************************************
-## * LaTeX *
-## ***************************************************************************
-## For more information on LaTeX properties, see
-## https://matplotlib.org/stable/users/explain/text/usetex.html
-#text.usetex: False # use latex for all text handling. The following fonts
- # are supported through the usual rc parameter settings:
- # new century schoolbook, bookman, times, palatino,
- # zapf chancery, charter, serif, sans-serif, helvetica,
- # avant garde, courier, monospace, computer modern roman,
- # computer modern sans serif, computer modern typewriter
-#text.latex.preamble: # IMPROPER USE OF THIS FEATURE WILL LEAD TO LATEX FAILURES
- # AND IS THEREFORE UNSUPPORTED. PLEASE DO NOT ASK FOR HELP
- # IF THIS FEATURE DOES NOT DO WHAT YOU EXPECT IT TO.
- # text.latex.preamble is a single line of LaTeX code that
- # will be passed on to the LaTeX system. It may contain
- # any code that is valid for the LaTeX "preamble", i.e.
- # between the "\documentclass" and "\begin{document}"
- # statements.
- # Note that it has to be put on a single line, which may
- # become quite long.
- # The following packages are always loaded with usetex,
- # so beware of package collisions:
- # geometry, inputenc, type1cm.
- # PostScript (PSNFSS) font packages may also be
- # loaded, depending on your font settings.
-
-## The following settings allow you to select the fonts in math mode.
-#mathtext.fontset: dejavusans # Should be 'dejavusans' (default),
- # 'dejavuserif', 'cm' (Computer Modern), 'stix',
- # 'stixsans' or 'custom'
-## "mathtext.fontset: custom" is defined by the mathtext.bf, .cal, .it, ...
-## settings which map a TeX font name to a fontconfig font pattern. (These
-## settings are not used for other font sets.)
-#mathtext.bf: sans:bold
-#mathtext.bfit: sans:italic:bold
-#mathtext.cal: cursive
-#mathtext.it: sans:italic
-#mathtext.rm: sans
-#mathtext.sf: sans
-#mathtext.tt: monospace
-#mathtext.fallback: cm # Select fallback font from ['cm' (Computer Modern), 'stix'
- # 'stixsans'] when a symbol cannot be found in one of the
- # custom math fonts. Select 'None' to not perform fallback
- # and replace the missing character by a dummy symbol.
-#mathtext.default: it # The default font to use for math.
- # Can be any of the LaTeX font names, including
- # the special name "regular" for the same font
- # used in regular text.
-
-
-## ***************************************************************************
-## * AXES *
-## ***************************************************************************
-## Following are default face and edge colors, default tick sizes,
-## default font sizes for tick labels, and so on. See
-## https://matplotlib.org/stable/api/axes_api.html#module-matplotlib.axes
-#axes.facecolor: white # axes background color
-#axes.edgecolor: black # axes edge color
-#axes.linewidth: 0.8 # edge line width
-#axes.grid: False # display grid or not
-#axes.grid.axis: both # which axis the grid should apply to
-#axes.grid.which: major # grid lines at {major, minor, both} ticks
-#axes.titlelocation: center # alignment of the title: {left, right, center}
-#axes.titlesize: large # font size of the axes title
-#axes.titleweight: normal # font weight of title
-#axes.titlecolor: auto # color of the axes title, auto falls back to
- # text.color as default value
-#axes.titley: None # position title (axes relative units). None implies auto
-#axes.titlepad: 6.0 # pad between axes and title in points
-#axes.labelsize: medium # font size of the x and y labels
-#axes.labelpad: 4.0 # space between label and axis
-#axes.labelweight: normal # weight of the x and y labels
-#axes.labelcolor: black
-#axes.axisbelow: line # draw axis gridlines and ticks:
- # - below patches (True)
- # - above patches but below lines ('line')
- # - above all (False)
-
-#axes.formatter.limits: -5, 6 # use scientific notation if log10
- # of the axis range is smaller than the
- # first or larger than the second
-#axes.formatter.use_locale: False # When True, format tick labels
- # according to the user's locale.
- # For example, use ',' as a decimal
- # separator in the fr_FR locale.
-#axes.formatter.use_mathtext: False # When True, use mathtext for scientific
- # notation.
-#axes.formatter.min_exponent: 0 # minimum exponent to format in scientific notation
-#axes.formatter.useoffset: True # If True, the tick label formatter
- # will default to labeling ticks relative
- # to an offset when the data range is
- # small compared to the minimum absolute
- # value of the data.
-#axes.formatter.offset_threshold: 4 # When useoffset is True, the offset
- # will be used when it can remove
- # at least this number of significant
- # digits from tick labels.
-
-#axes.spines.left: True # display axis spines
-#axes.spines.bottom: True
-#axes.spines.top: True
-#axes.spines.right: True
-
-#axes.unicode_minus: True # use Unicode for the minus symbol rather than hyphen. See
- # https://en.wikipedia.org/wiki/Plus_and_minus_signs#Character_codes
-#axes.prop_cycle: cycler('color', ['1f77b4', 'ff7f0e', '2ca02c', 'd62728', '9467bd', '8c564b', 'e377c2', '7f7f7f', 'bcbd22', '17becf'])
- # color cycle for plot lines as list of string color specs:
- # single letter, long name, or web-style hex
- # As opposed to all other parameters in this file, the color
- # values must be enclosed in quotes for this parameter,
- # e.g. '1f77b4', instead of 1f77b4.
- # See also https://matplotlib.org/stable/users/explain/artists/color_cycle.html
- # for more details on prop_cycle usage.
-#axes.xmargin: .05 # x margin. See `axes.Axes.margins`
-#axes.ymargin: .05 # y margin. See `axes.Axes.margins`
-#axes.zmargin: .05 # z margin. See `axes.Axes.margins`
-#axes.autolimit_mode: data # If "data", use axes.xmargin and axes.ymargin as is.
- # If "round_numbers", after application of margins, axis
- # limits are further expanded to the nearest "round" number.
-#polaraxes.grid: True # display grid on polar axes
-#axes3d.grid: True # display grid on 3D axes
-
-#axes3d.xaxis.panecolor: (0.95, 0.95, 0.95, 0.5) # background pane on 3D axes
-#axes3d.yaxis.panecolor: (0.90, 0.90, 0.90, 0.5) # background pane on 3D axes
-#axes3d.zaxis.panecolor: (0.925, 0.925, 0.925, 0.5) # background pane on 3D axes
-
-## ***************************************************************************
-## * AXIS *
-## ***************************************************************************
-#xaxis.labellocation: center # alignment of the xaxis label: {left, right, center}
-#yaxis.labellocation: center # alignment of the yaxis label: {bottom, top, center}
-
-
-## ***************************************************************************
-## * DATES *
-## ***************************************************************************
-## These control the default format strings used in AutoDateFormatter.
-## Any valid format datetime format string can be used (see the python
-## `datetime` for details). For example, by using:
-## - '%x' will use the locale date representation
-## - '%X' will use the locale time representation
-## - '%c' will use the full locale datetime representation
-## These values map to the scales:
-## {'year': 365, 'month': 30, 'day': 1, 'hour': 1/24, 'minute': 1 / (24 * 60)}
-
-#date.autoformatter.year: %Y
-#date.autoformatter.month: %Y-%m
-#date.autoformatter.day: %Y-%m-%d
-#date.autoformatter.hour: %m-%d %H
-#date.autoformatter.minute: %d %H:%M
-#date.autoformatter.second: %H:%M:%S
-#date.autoformatter.microsecond: %M:%S.%f
-## The reference date for Matplotlib's internal date representation
-## See https://matplotlib.org/stable/gallery/ticks/date_precision_and_epochs.html
-#date.epoch: 1970-01-01T00:00:00
-## 'auto', 'concise':
-#date.converter: auto
-## For auto converter whether to use interval_multiples:
-#date.interval_multiples: True
-
-## ***************************************************************************
-## * TICKS *
-## ***************************************************************************
-## See https://matplotlib.org/stable/api/axis_api.html#matplotlib.axis.Tick
-#xtick.top: False # draw ticks on the top side
-#xtick.bottom: True # draw ticks on the bottom side
-#xtick.labeltop: False # draw label on the top
-#xtick.labelbottom: True # draw label on the bottom
-#xtick.major.size: 3.5 # major tick size in points
-#xtick.minor.size: 2 # minor tick size in points
-#xtick.major.width: 0.8 # major tick width in points
-#xtick.minor.width: 0.6 # minor tick width in points
-#xtick.major.pad: 3.5 # distance to major tick label in points
-#xtick.minor.pad: 3.4 # distance to the minor tick label in points
-#xtick.color: black # color of the ticks
-#xtick.labelcolor: inherit # color of the tick labels or inherit from xtick.color
-#xtick.labelsize: medium # font size of the tick labels
-#xtick.direction: out # direction: {in, out, inout}
-#xtick.minor.visible: False # visibility of minor ticks on x-axis
-#xtick.major.top: True # draw x axis top major ticks
-#xtick.major.bottom: True # draw x axis bottom major ticks
-#xtick.minor.top: True # draw x axis top minor ticks
-#xtick.minor.bottom: True # draw x axis bottom minor ticks
-#xtick.minor.ndivs: auto # number of minor ticks between the major ticks on x-axis
-#xtick.alignment: center # alignment of xticks
-
-#ytick.left: True # draw ticks on the left side
-#ytick.right: False # draw ticks on the right side
-#ytick.labelleft: True # draw tick labels on the left side
-#ytick.labelright: False # draw tick labels on the right side
-#ytick.major.size: 3.5 # major tick size in points
-#ytick.minor.size: 2 # minor tick size in points
-#ytick.major.width: 0.8 # major tick width in points
-#ytick.minor.width: 0.6 # minor tick width in points
-#ytick.major.pad: 3.5 # distance to major tick label in points
-#ytick.minor.pad: 3.4 # distance to the minor tick label in points
-#ytick.color: black # color of the ticks
-#ytick.labelcolor: inherit # color of the tick labels or inherit from ytick.color
-#ytick.labelsize: medium # font size of the tick labels
-#ytick.direction: out # direction: {in, out, inout}
-#ytick.minor.visible: False # visibility of minor ticks on y-axis
-#ytick.major.left: True # draw y axis left major ticks
-#ytick.major.right: True # draw y axis right major ticks
-#ytick.minor.left: True # draw y axis left minor ticks
-#ytick.minor.right: True # draw y axis right minor ticks
-#ytick.minor.ndivs: auto # number of minor ticks between the major ticks on y-axis
-#ytick.alignment: center_baseline # alignment of yticks
-
-
-## ***************************************************************************
-## * GRIDS *
-## ***************************************************************************
-#grid.color: "#b0b0b0" # grid color
-#grid.linestyle: - # solid
-#grid.linewidth: 0.8 # in points
-#grid.alpha: 1.0 # transparency, between 0.0 and 1.0
-
-
-## ***************************************************************************
-## * LEGEND *
-## ***************************************************************************
-#legend.loc: best
-#legend.frameon: True # if True, draw the legend on a background patch
-#legend.framealpha: 0.8 # legend patch transparency
-#legend.facecolor: inherit # inherit from axes.facecolor; or color spec
-#legend.edgecolor: 0.8 # background patch boundary color
-#legend.fancybox: True # if True, use a rounded box for the
- # legend background, else a rectangle
-#legend.shadow: False # if True, give background a shadow effect
-#legend.numpoints: 1 # the number of marker points in the legend line
-#legend.scatterpoints: 1 # number of scatter points
-#legend.markerscale: 1.0 # the relative size of legend markers vs. original
-#legend.fontsize: medium
-#legend.labelcolor: None
-#legend.title_fontsize: None # None sets to the same as the default axes.
-
-## Dimensions as fraction of font size:
-#legend.borderpad: 0.4 # border whitespace
-#legend.labelspacing: 0.5 # the vertical space between the legend entries
-#legend.handlelength: 2.0 # the length of the legend lines
-#legend.handleheight: 0.7 # the height of the legend handle
-#legend.handletextpad: 0.8 # the space between the legend line and legend text
-#legend.borderaxespad: 0.5 # the border between the axes and legend edge
-#legend.columnspacing: 2.0 # column separation
-
-
-## ***************************************************************************
-## * FIGURE *
-## ***************************************************************************
-## See https://matplotlib.org/stable/api/figure_api.html#matplotlib.figure.Figure
-#figure.titlesize: large # size of the figure title (``Figure.suptitle()``)
-#figure.titleweight: normal # weight of the figure title
-#figure.labelsize: large # size of the figure label (``Figure.sup[x|y]label()``)
-#figure.labelweight: normal # weight of the figure label
-#figure.figsize: 6.4, 4.8 # figure size in inches
-#figure.dpi: 100 # figure dots per inch
-#figure.facecolor: white # figure face color
-#figure.edgecolor: white # figure edge color
-#figure.frameon: True # enable figure frame
-#figure.max_open_warning: 20 # The maximum number of figures to open through
- # the pyplot interface before emitting a warning.
- # If less than one this feature is disabled.
-#figure.raise_window : True # Raise the GUI window to front when show() is called.
-
-## The figure subplot parameters. All dimensions are a fraction of the figure width and height.
-#figure.subplot.left: 0.125 # the left side of the subplots of the figure
-#figure.subplot.right: 0.9 # the right side of the subplots of the figure
-#figure.subplot.bottom: 0.11 # the bottom of the subplots of the figure
-#figure.subplot.top: 0.88 # the top of the subplots of the figure
-#figure.subplot.wspace: 0.2 # the amount of width reserved for space between subplots,
- # expressed as a fraction of the average axis width
-#figure.subplot.hspace: 0.2 # the amount of height reserved for space between subplots,
- # expressed as a fraction of the average axis height
-
-## Figure layout
-#figure.autolayout: False # When True, automatically adjust subplot
- # parameters to make the plot fit the figure
- # using `tight_layout`
-#figure.constrained_layout.use: False # When True, automatically make plot
- # elements fit on the figure. (Not
- # compatible with `autolayout`, above).
-## Padding (in inches) around axes; defaults to 3/72 inches, i.e. 3 points.
-#figure.constrained_layout.h_pad: 0.04167
-#figure.constrained_layout.w_pad: 0.04167
-## Spacing between subplots, relative to the subplot sizes. Much smaller than for
-## tight_layout (figure.subplot.hspace, figure.subplot.wspace) as constrained_layout
-## already takes surrounding texts (titles, labels, # ticklabels) into account.
-#figure.constrained_layout.hspace: 0.02
-#figure.constrained_layout.wspace: 0.02
-
-
-## ***************************************************************************
-## * IMAGES *
-## ***************************************************************************
-#image.aspect: equal # {equal, auto} or a number
-#image.interpolation: antialiased # see help(imshow) for options
-#image.cmap: viridis # A colormap name (plasma, magma, etc.)
-#image.lut: 256 # the size of the colormap lookup table
-#image.origin: upper # {lower, upper}
-#image.resample: True
-#image.composite_image: True # When True, all the images on a set of axes are
- # combined into a single composite image before
- # saving a figure as a vector graphics file,
- # such as a PDF.
-
-
-## ***************************************************************************
-## * CONTOUR PLOTS *
-## ***************************************************************************
-#contour.negative_linestyle: dashed # string or on-off ink sequence
-#contour.corner_mask: True # {True, False}
-#contour.linewidth: None # {float, None} Size of the contour line
- # widths. If set to None, it falls back to
- # `line.linewidth`.
-#contour.algorithm: mpl2014 # {mpl2005, mpl2014, serial, threaded}
-
-
-## ***************************************************************************
-## * ERRORBAR PLOTS *
-## ***************************************************************************
-#errorbar.capsize: 0 # length of end cap on error bars in pixels
-
-
-## ***************************************************************************
-## * HISTOGRAM PLOTS *
-## ***************************************************************************
-#hist.bins: 10 # The default number of histogram bins or 'auto'.
-
-
-## ***************************************************************************
-## * SCATTER PLOTS *
-## ***************************************************************************
-#scatter.marker: o # The default marker type for scatter plots.
-#scatter.edgecolors: face # The default edge colors for scatter plots.
-
-
-## ***************************************************************************
-## * AGG RENDERING *
-## ***************************************************************************
-## Warning: experimental, 2008/10/10
-#agg.path.chunksize: 0 # 0 to disable; values in the range
- # 10000 to 100000 can improve speed slightly
- # and prevent an Agg rendering failure
- # when plotting very large data sets,
- # especially if they are very gappy.
- # It may cause minor artifacts, though.
- # A value of 20000 is probably a good
- # starting point.
-
-
-## ***************************************************************************
-## * PATHS *
-## ***************************************************************************
-#path.simplify: True # When True, simplify paths by removing "invisible"
- # points to reduce file size and increase rendering
- # speed
-#path.simplify_threshold: 0.111111111111 # The threshold of similarity below
- # which vertices will be removed in
- # the simplification process.
-#path.snap: True # When True, rectilinear axis-aligned paths will be snapped
- # to the nearest pixel when certain criteria are met.
- # When False, paths will never be snapped.
-#path.sketch: None # May be None, or a 3-tuple of the form:
- # (scale, length, randomness).
- # - *scale* is the amplitude of the wiggle
- # perpendicular to the line (in pixels).
- # - *length* is the length of the wiggle along the
- # line (in pixels).
- # - *randomness* is the factor by which the length is
- # randomly scaled.
-#path.effects:
-
-
-## ***************************************************************************
-## * SAVING FIGURES *
-## ***************************************************************************
-## The default savefig parameters can be different from the display parameters
-## e.g., you may want a higher resolution, or to make the figure
-## background white
-#savefig.dpi: figure # figure dots per inch or 'figure'
-#savefig.facecolor: auto # figure face color when saving
-#savefig.edgecolor: auto # figure edge color when saving
-#savefig.format: png # {png, ps, pdf, svg}
-#savefig.bbox: standard # {tight, standard}
- # 'tight' is incompatible with generating frames
- # for animation
-#savefig.pad_inches: 0.1 # padding to be used, when bbox is set to 'tight'
-#savefig.directory: ~ # default directory in savefig dialog, gets updated after
- # interactive saves, unless set to the empty string (i.e.
- # the current directory); use '.' to start at the current
- # directory but update after interactive saves
-#savefig.transparent: False # whether figures are saved with a transparent
- # background by default
-#savefig.orientation: portrait # orientation of saved figure, for PostScript output only
-
-### macosx backend params
-#macosx.window_mode : system # How to open new figures (system, tab, window)
- # system uses the MacOS system preferences
-
-### tk backend params
-#tk.window_focus: False # Maintain shell focus for TkAgg
-
-### ps backend params
-#ps.papersize: letter # {figure, letter, legal, ledger, A0-A10, B0-B10}
-#ps.useafm: False # use AFM fonts, results in small files
-#ps.usedistiller: False # {ghostscript, xpdf, None}
- # Experimental: may produce smaller files.
- # xpdf intended for production of publication quality files,
- # but requires ghostscript, xpdf and ps2eps
-#ps.distiller.res: 6000 # dpi
-#ps.fonttype: 3 # Output Type 3 (Type3) or Type 42 (TrueType)
-
-### PDF backend params
-#pdf.compression: 6 # integer from 0 to 9
- # 0 disables compression (good for debugging)
-#pdf.fonttype: 3 # Output Type 3 (Type3) or Type 42 (TrueType)
-#pdf.use14corefonts: False
-#pdf.inheritcolor: False
-
-### SVG backend params
-#svg.image_inline: True # Write raster image data directly into the SVG file
-#svg.fonttype: path # How to handle SVG fonts:
- # path: Embed characters as paths -- supported
- # by most SVG renderers
- # None: Assume fonts are installed on the
- # machine where the SVG will be viewed.
-#svg.hashsalt: None # If not None, use this string as hash salt instead of uuid4
-
-### pgf parameter
-## See https://matplotlib.org/stable/tutorials/text/pgf.html for more information.
-#pgf.rcfonts: True
-#pgf.preamble: # See text.latex.preamble for documentation
-#pgf.texsystem: xelatex
-
-### docstring params
-#docstring.hardcopy: False # set this when you want to generate hardcopy docstring
-
-
-## ***************************************************************************
-## * INTERACTIVE KEYMAPS *
-## ***************************************************************************
-## Event keys to interact with figures/plots via keyboard.
-## See https://matplotlib.org/stable/users/explain/interactive.html for more
-## details on interactive navigation. Customize these settings according to
-## your needs. Leave the field(s) empty if you don't need a key-map. (i.e.,
-## fullscreen : '')
-#keymap.fullscreen: f, ctrl+f # toggling
-#keymap.home: h, r, home # home or reset mnemonic
-#keymap.back: left, c, backspace, MouseButton.BACK # forward / backward keys
-#keymap.forward: right, v, MouseButton.FORWARD # for quick navigation
-#keymap.pan: p # pan mnemonic
-#keymap.zoom: o # zoom mnemonic
-#keymap.save: s, ctrl+s # saving current figure
-#keymap.help: f1 # display help about active tools
-#keymap.quit: ctrl+w, cmd+w, q # close the current figure
-#keymap.quit_all: # close all figures
-#keymap.grid: g # switching on/off major grids in current axes
-#keymap.grid_minor: G # switching on/off minor grids in current axes
-#keymap.yscale: l # toggle scaling of y-axes ('log'/'linear')
-#keymap.xscale: k, L # toggle scaling of x-axes ('log'/'linear')
-#keymap.copy: ctrl+c, cmd+c # copy figure to clipboard
-
-
-## ***************************************************************************
-## * ANIMATION *
-## ***************************************************************************
-#animation.html: none # How to display the animation as HTML in
- # the IPython notebook:
- # - 'html5' uses HTML5 video tag
- # - 'jshtml' creates a JavaScript animation
-#animation.writer: ffmpeg # MovieWriter 'backend' to use
-#animation.codec: h264 # Codec to use for writing movie
-#animation.bitrate: -1 # Controls size/quality trade-off for movie.
- # -1 implies let utility auto-determine
-#animation.frame_format: png # Controls frame format used by temp files
-
-## Path to ffmpeg binary. Unqualified paths are resolved by subprocess.Popen.
-#animation.ffmpeg_path: ffmpeg
-## Additional arguments to pass to ffmpeg.
-#animation.ffmpeg_args:
-
-## Path to ImageMagick's convert binary. Unqualified paths are resolved by
-## subprocess.Popen, except that on Windows, we look up an install of
-## ImageMagick in the registry (as convert is also the name of a system tool).
-#animation.convert_path: convert
-## Additional arguments to pass to convert.
-#animation.convert_args: -layers, OptimizePlus
-#
-#animation.embed_limit: 20.0 # Limit, in MB, of size of base64 encoded
- # animation in HTML (i.e. IPython notebook)
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/plot_directive/plot_directive.css b/contrib/python/matplotlib/py3/matplotlib/mpl-data/plot_directive/plot_directive.css
deleted file mode 100644
index d45593c93c..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/plot_directive/plot_directive.css
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * plot_directive.css
- * ~~~~~~~~~~~~
- *
- * Stylesheet controlling images created using the `plot` directive within
- * Sphinx.
- *
- * :copyright: Copyright 2020-* by the Matplotlib development team.
- * :license: Matplotlib, see LICENSE for details.
- *
- */
-
-img.plot-directive {
- border: 0;
- max-width: 100%;
-}
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/Minduka_Present_Blue_Pack.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/Minduka_Present_Blue_Pack.png
deleted file mode 100644
index 2b1aff4e3c..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/Minduka_Present_Blue_Pack.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/README.txt b/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/README.txt
deleted file mode 100644
index 75a534951d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/README.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-This is the sample data needed for some of matplotlib's examples and
-docs. See matplotlib.cbook.get_sample_data for more info.
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/Stocks.csv b/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/Stocks.csv
deleted file mode 100644
index 575d353dff..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/Stocks.csv
+++ /dev/null
@@ -1,526 +0,0 @@
-# Data source: https://finance.yahoo.com
-Date,IBM,AAPL,MSFT,XRX,AMZN,DELL,GOOGL,ADBE,^GSPC,^IXIC
-1990-01-01,10.970438003540039,0.24251236021518707,0.40375930070877075,11.202081680297852,,,,1.379060983657837,329.0799865722656,415.79998779296875
-1990-02-01,11.554415702819824,0.24251236021518707,0.43104037642478943,10.39472484588623,,,,1.7790844440460205,331.8900146484375,425.79998779296875
-1990-02-05,,,,,,,,,,
-1990-03-01,11.951693534851074,0.28801724314689636,0.4834197461605072,11.394058227539062,,,,2.2348830699920654,339.94000244140625,435.5
-1990-04-01,12.275476455688477,0.2817564308643341,0.5063362717628479,10.139430046081543,,,,2.2531447410583496,330.79998779296875,420.1000061035156
-1990-05-01,13.514284133911133,0.295173317193985,0.6372847557067871,9.704153060913086,,,,2.0985164642333984,361.2300109863281,459.0
-1990-05-04,,,,,,,,,,
-1990-06-01,13.380948066711426,0.3211067020893097,0.6634747385978699,9.749448776245117,,,,2.164785146713257,358.0199890136719,462.29998779296875
-1990-07-01,12.697657585144043,0.3013734817504883,0.5805402994155884,9.489465713500977,,,,2.069063901901245,356.1499938964844,438.20001220703125
-1990-08-01,11.601561546325684,0.26549553871154785,0.5368908047676086,8.553519248962402,,,,1.4750508069992065,322.55999755859375,381.20001220703125
-1990-08-06,,,,,,,,,,
-1990-09-01,12.251119613647461,0.20872052013874054,0.5499854683876038,7.255113124847412,,,,1.1210384368896484,306.04998779296875,344.5
-1990-10-01,12.15034294128418,0.22131578624248505,0.5565334558486938,6.248927116394043,,,,1.416249394416809,304.0,329.79998779296875
-1990-11-01,13.08609390258789,0.26449888944625854,0.6307373642921448,7.361023426055908,,,,1.4900128841400146,322.2200012207031,359.1000061035156
-1990-11-05,,,,,,,,,,
-1990-12-01,13.161062240600586,0.31051647663116455,0.6569272875785828,7.519896507263184,,,,1.7186784744262695,330.2200012207031,373.79998779296875
-1991-01-01,14.762505531311035,0.40078282356262207,0.8566243648529053,10.554410934448242,,,,2.242394208908081,343.92999267578125,414.20001220703125
-1991-02-01,14.995450973510742,0.4134202301502228,0.9057300686836243,12.286416053771973,,,,2.8402483463287354,367.07000732421875,453.1000061035156
-1991-02-04,,,,,,,,,,
-1991-03-01,13.39067268371582,0.49208223819732666,0.92646324634552,12.511940002441406,,,,3.1869795322418213,375.2200012207031,482.29998779296875
-1991-04-01,12.111870765686035,0.39800751209259033,0.8642628788948059,12.511940002441406,,,,3.0589873790740967,375.3399963378906,484.7200012207031
-1991-05-01,12.479341506958008,0.34011581540107727,0.9581103920936584,12.73144817352295,,,,2.9850986003875732,389.8299865722656,506.1099853515625
-1991-05-06,,,,,,,,,,
-1991-06-01,11.555957794189453,0.30108359456062317,0.89208984375,11.853414535522461,,,,2.5565452575683594,371.1600036621094,475.9200134277344
-1991-07-01,12.04675579071045,0.33554431796073914,0.9624748229980469,12.397871017456055,,,,3.1678967475891113,387.80999755859375,502.0400085449219
-1991-08-01,11.526222229003906,0.3845158815383911,1.1163398027420044,13.037229537963867,,,,3.012463331222534,395.42999267578125,525.6799926757812
-1991-08-06,,,,,,,,,,
-1991-09-01,12.478833198547363,0.3599340617656708,1.1654454469680786,13.740047454833984,,,,3.0346662998199463,387.8599853515625,526.8800048828125
-1991-10-01,11.83155345916748,0.37447676062583923,1.2292828559875488,14.41578483581543,,,,3.1431360244750977,392.45001220703125,542.97998046875
-1991-11-01,11.139124870300293,0.36902356147766113,1.2734787464141846,13.965290069580078,,,,2.846613883972168,375.2200012207031,523.9000244140625
-1991-11-04,,,,,,,,,,
-1991-12-01,10.851117134094238,0.4109107553958893,1.4568067789077759,15.42939281463623,,,,3.8844411373138428,417.0899963378906,586.3400268554688
-1992-01-01,10.973037719726562,0.4719553291797638,1.5746610164642334,17.584869384765625,,,,3.639812469482422,408.7799987792969,620.2100219726562
-1992-02-01,10.592026710510254,0.49199995398521423,1.61721932888031,18.04088020324707,,,,3.3547844886779785,412.70001220703125,633.469970703125
-1992-02-06,,,,,,,,,,
-1992-03-01,10.317353248596191,0.4253714978694916,1.5517452955245972,16.302349090576172,,,,3.043056011199951,403.69000244140625,603.77001953125
-1992-04-01,11.213163375854492,0.43906375765800476,1.4437123537063599,17.062589645385742,,,,2.631263494491577,414.95001220703125,578.6799926757812
-1992-05-01,11.213163375854492,0.4363253116607666,1.5844820737838745,17.263996124267578,,,,2.705594062805176,415.3500061035156,585.3099975585938
-1992-05-07,,,,,,,,,,
-1992-06-01,12.25231647491455,0.3505205810070038,1.3749638795852661,16.055517196655273,,,,2.705594062805176,408.1400146484375,563.5999755859375
-1992-07-01,11.861115455627441,0.34207984805107117,1.4289811849594116,17.38025665283203,,,,2.263554334640503,424.2099914550781,580.8300170898438
-1992-08-01,10.84400749206543,0.33659130334854126,1.4633547067642212,17.525571823120117,,,,1.9359338283538818,414.0299987792969,563.1199951171875
-1992-08-06,,,,,,,,,,
-1992-09-01,10.243829727172852,0.3310767114162445,1.58120858669281,18.464359283447266,,,,1.6753284931182861,417.79998779296875,583.27001953125
-1992-10-01,8.483662605285645,0.38518592715263367,1.7432584762573242,17.436922073364258,,,,2.12785267829895,418.67999267578125,605.1699829101562
-1992-11-01,8.658098220825195,0.42187052965164185,1.8291932344436646,18.493711471557617,,,,2.030792474746704,431.3500061035156,652.72998046875
-1992-11-05,,,,,,,,,,
-1992-12-01,6.505843639373779,0.43931084871292114,1.6769649982452393,18.788379669189453,,,,1.8814688920974731,435.7099914550781,676.9500122070312
-1993-01-01,6.651134490966797,0.43747296929359436,1.6990629434585571,20.329378128051758,,,,2.4787611961364746,438.7799987792969,696.3400268554688
-1993-02-01,7.022435188293457,0.38968151807785034,1.6376806497573853,19.618152618408203,,,,2.670894145965576,443.3800048828125,670.77001953125
-1993-02-04,,,,,,,,,,
-1993-03-01,6.6405534744262695,0.37947842478752136,1.8169171810150146,19.766319274902344,,,,2.573633909225464,451.6700134277344,690.1300048828125
-1993-04-01,6.346868991851807,0.3776364326477051,1.6794201135635376,18.451818466186523,,,,3.434307336807251,440.19000244140625,661.4199829101562
-1993-05-01,6.885295867919922,0.4172421991825104,1.8193715810775757,18.12286949157715,,,,3.959200859069824,450.19000244140625,700.530029296875
-1993-05-06,,,,,,,,,,
-1993-06-01,6.51603364944458,0.29166528582572937,1.7285257577896118,19.299583435058594,,,,3.7042527198791504,450.5299987792969,703.9500122070312
-1993-07-01,5.872671604156494,0.2049039751291275,1.453533411026001,17.638439178466797,,,,2.9742372035980225,448.1300048828125,704.7000122070312
-1993-08-01,6.037637233734131,0.19567380845546722,1.4756313562393188,17.759246826171875,,,,2.5536391735076904,463.55999755859375,742.8400268554688
-1993-08-05,,,,,,,,,,
-1993-09-01,5.574150562286377,0.1733584851026535,1.620492935180664,17.849544525146484,,,,2.1931254863739014,458.92999267578125,762.780029296875
-1993-10-01,6.105024337768555,0.22805523872375488,1.5738422870635986,19.34462547302246,,,,2.6137242317199707,467.8299865722656,779.260009765625
-1993-11-01,7.150176048278809,0.2336171418428421,1.5713871717453003,20.107433319091797,,,,2.786593437194824,461.7900085449219,754.3900146484375
-1993-11-04,,,,,,,,,,
-1993-12-01,7.535686016082764,0.21771006286144257,1.5836634635925293,22.01595687866211,,,,2.68115496635437,466.45001220703125,776.7999877929688
-1994-01-01,7.535686016082764,0.24376071989536285,1.672054648399353,24.171361923217773,,,,3.64516544342041,481.6099853515625,800.469970703125
-1994-02-01,7.052198886871338,0.27167221903800964,1.620492935180664,23.894229888916016,,,,3.5310842990875244,467.1400146484375,792.5
-1994-02-04,,,,,,,,,,
-1994-03-01,7.31842041015625,0.24837146699428558,1.6646885871887207,23.706161499023438,,,,2.9274797439575195,445.7699890136719,743.4600219726562
-1994-04-01,7.703606128692627,0.22409436106681824,1.8169171810150146,24.543949127197266,,,,3.2354440689086914,450.9100036621094,733.8400268554688
-1994-05-01,8.440468788146973,0.21849241852760315,2.1115520000457764,24.947307586669922,,,,3.4773480892181396,456.5,735.1900024414062
-1994-05-05,,,,,,,,,,
-1994-06-01,7.905290126800537,0.19873161613941193,2.028071165084839,24.444643020629883,,,,3.2959203720092773,444.2699890136719,705.9600219726562
-1994-07-01,8.325791358947754,0.2526327669620514,2.023160934448242,25.569963455200195,,,,3.756444215774536,458.260009765625,722.1599731445312
-1994-08-01,9.217235565185547,0.27138155698776245,2.2834222316741943,26.789077758789062,,,,3.847325563430786,475.489990234375,765.6199951171875
-1994-08-04,,,,,,,,,,
-1994-09-01,9.405942916870117,0.25350791215896606,2.2048532962799072,26.88198471069336,,,,3.9382081031799316,462.7099914550781,764.2899780273438
-1994-10-01,10.064526557922363,0.324998676776886,2.474935293197632,25.811735153198242,,,,4.368794918060303,472.3500061035156,777.489990234375
-1994-11-01,9.557921409606934,0.28031668066978455,2.470024824142456,24.741479873657227,,,,4.004726409912109,453.69000244140625,750.3200073242188
-1994-11-04,,,,,,,,,,
-1994-12-01,9.9633207321167,0.2943686842918396,2.401276111602783,25.12115478515625,,,,3.6103241443634033,459.2699890136719,751.9600219726562
-1995-01-01,9.77692985534668,0.3047473132610321,2.332528591156006,27.753808975219727,,,,3.5117223262786865,470.4200134277344,755.2000122070312
-1995-02-01,10.200541496276855,0.29814332723617554,2.474935293197632,28.13443946838379,,,,4.345465660095215,487.3900146484375,793.72998046875
-1995-02-06,,,,,,,,,,
-1995-03-01,11.169903755187988,0.2667955756187439,2.7941226959228516,29.989917755126953,,,,6.016797065734863,500.7099914550781,817.2100219726562
-1995-04-01,12.870043754577637,0.2895018756389618,3.2115228176116943,31.52293586730957,,,,7.08742618560791,514.7100219726562,843.97998046875
-1995-05-01,12.649023056030273,0.31457316875457764,3.326920747756958,28.96788215637207,,,,6.326970100402832,533.4000244140625,864.5800170898438
-1995-05-04,,,,,,,,,,
-1995-06-01,13.091790199279785,0.3524453043937683,3.5503528118133545,30.15083122253418,,,,7.057007789611816,544.75,933.4500122070312
-1995-07-01,14.847586631774902,0.3415350615978241,3.5552642345428467,30.697277069091797,,,,7.513277530670166,562.0599975585938,1001.2100219726562
-1995-08-01,14.09753131866455,0.32635587453842163,3.6338343620300293,31.08300018310547,,,,6.210629463195801,561.8800048828125,1020.1099853515625
-1995-08-08,,,,,,,,,,
-1995-09-01,12.916881561279297,0.28348639607429504,3.5552642345428467,34.767181396484375,,,,6.301961898803711,584.4099731445312,1043.5400390625
-1995-10-01,13.292764663696289,0.27635207772254944,3.92846941947937,33.5381965637207,,,,6.941293239593506,581.5,1036.06005859375
-1995-11-01,13.207347869873047,0.2901458144187927,3.4226772785186768,35.478694915771484,,,,8.243063926696777,605.3699951171875,1059.199951171875
-1995-11-08,,,,,,,,,,
-1995-12-01,12.52143669128418,0.24333631992340088,3.447230815887451,35.68303298950195,,,,7.557409763336182,615.9299926757812,1052.1300048828125
-1996-01-01,14.868143081665039,0.21089188754558563,3.6338343620300293,32.199371337890625,,,,4.14438533782959,636.02001953125,1059.7900390625
-1996-02-01,16.80373764038086,0.2099376916885376,3.876908779144287,33.924922943115234,,,,4.089058876037598,640.4299926757812,1100.050048828125
-1996-02-07,,,,,,,,,,
-1996-03-01,15.278267860412598,0.1875123232603073,4.051232814788818,32.900360107421875,,,,3.936483860015869,645.5,1101.4000244140625
-1996-04-01,14.797598838806152,0.1860809624195099,4.448990821838379,38.40559768676758,,,,5.248644828796387,654.1699829101562,1190.52001953125
-1996-05-01,14.660264015197754,0.1994406133890152,4.6650567054748535,41.25652313232422,,,,4.538435459136963,669.1199951171875,1243.4300537109375
-1996-05-08,,,,,,,,,,
-1996-06-01,13.641029357910156,0.1603158563375473,4.719073295593262,42.07575225830078,,,,4.385625839233398,670.6300048828125,1185.02001953125
-1996-07-01,14.812233924865723,0.1679503321647644,4.630680561065674,39.836021423339844,,,,3.7132644653320312,639.9500122070312,1080.5899658203125
-1996-08-01,15.759532928466797,0.18512675166130066,4.812370777130127,43.394588470458984,,,,4.269299030303955,651.989990234375,1141.5
-1996-08-07,,,,,,,,,,
-1996-09-01,17.209583282470703,0.16938161849975586,5.180670261383057,42.40607833862305,,,,4.5600385665893555,687.3300170898438,1226.9200439453125
-1996-10-01,17.831613540649414,0.17558389902114868,5.391822814941406,36.86507034301758,,,,4.244296073913574,705.27001953125,1221.510009765625
-1996-11-01,22.03032875061035,0.184172585606575,6.162785530090332,38.95176315307617,,,,4.841867923736572,757.02001953125,1292.6099853515625
-1996-11-06,,,,,,,,,,
-1996-12-01,20.998197555541992,0.15936164557933807,6.491794109344482,41.83340072631836,,,,4.581387996673584,740.739990234375,1291.030029296875
-1997-01-01,21.743183135986328,0.12691716849803925,8.01407527923584,46.8797492980957,,,,4.642676830291748,786.1599731445312,1379.8499755859375
-1997-02-01,19.924028396606445,0.1240537017583847,7.660515785217285,49.97840881347656,,,,4.47982120513916,790.8200073242188,1309.0
-1997-02-06,,,,,,,,,,
-1997-03-01,19.067983627319336,0.13932174444198608,7.203826904296875,45.4803581237793,,,,4.924733638763428,757.1199951171875,1221.699951171875
-1997-04-01,22.298084259033203,0.12977975606918335,9.546177864074707,49.431339263916016,,,,4.807621955871582,801.3400268554688,1260.760009765625
-1997-05-01,24.034704208374023,0.12691716849803925,9.742606163024902,54.45485305786133,,,,5.483453750610352,848.280029296875,1400.3199462890625
-1997-05-07,,,,,,,,,,
-1997-05-28,,,,,,,,,,
-1997-06-01,25.13742446899414,0.10878564417362213,9.929201126098633,63.396705627441406,0.07708299905061722,,,4.3084282875061035,885.1400146484375,1442.0699462890625
-1997-07-01,29.45465660095215,0.1335965245962143,11.107746124267578,66.42845916748047,0.11979199945926666,,,4.592585563659668,954.3099975585938,1593.81005859375
-1997-08-01,28.23609161376953,0.1660410314798355,10.385887145996094,60.97687911987305,0.11692699790000916,,,4.851738929748535,899.469970703125,1587.3199462890625
-1997-08-07,,,,,,,,,,
-1997-09-01,29.579116821289062,0.16556398570537567,10.395710945129395,67.9932632446289,0.21692700684070587,,,6.2071452140808105,947.280029296875,1685.68994140625
-1997-10-01,27.48627281188965,0.13001829385757446,10.214018821716309,64.32245635986328,0.25416699051856995,,,5.889601707458496,914.6199951171875,1593.6099853515625
-1997-11-01,30.555805206298828,0.13550494611263275,11.117568969726562,63.00460433959961,0.20624999701976776,,,5.180382251739502,955.4000244140625,1600.550048828125
-1997-11-06,,,,,,,,,,
-1997-12-01,29.25237274169922,0.10019782930612564,10.155089378356934,59.91267013549805,0.2510420083999634,,,5.087874889373779,970.4299926757812,1570.3499755859375
-1998-01-01,27.609769821166992,0.1397988647222519,11.721570014953613,65.44635009765625,0.24583299458026886,,,4.750911235809326,980.280029296875,1619.3599853515625
-1998-02-01,29.19993782043457,0.1803557574748993,13.317505836486816,72.36756134033203,0.3208329975605011,,,5.452751159667969,1049.3399658203125,1770.510009765625
-1998-02-06,,,,,,,,,,
-1998-03-01,29.10112953186035,0.2099376916885376,14.06391716003418,86.66805267333984,0.35637998580932617,,,5.576151371002197,1101.75,1835.6800537109375
-1998-04-01,32.4630012512207,0.20898354053497314,14.162128448486328,92.79229736328125,0.3822920024394989,,,6.177727699279785,1111.75,1868.4100341796875
-1998-05-01,32.918251037597656,0.2032574564218521,13.327329635620117,84.10579681396484,0.3671880066394806,,,4.930263519287109,1090.8199462890625,1778.8699951171875
-1998-05-06,,,,,,,,,,
-1998-06-01,32.225502014160156,0.2190026193857193,17.029911041259766,83.08383178710938,0.831250011920929,,,5.238887786865234,1133.8399658203125,1894.739990234375
-1998-07-01,37.19002914428711,0.26433059573173523,17.27544403076172,86.6082992553711,0.9239580035209656,,,3.988961935043335,1120.6700439453125,1872.3900146484375
-1998-08-01,31.611520767211914,0.23808826506137848,15.075493812561035,72.04536437988281,0.6979169845581055,,,3.2419238090515137,957.280029296875,1499.25
-1998-08-06,,,,,,,,,,
-1998-09-01,36.12905502319336,0.2910497486591339,17.295076370239258,69.53275299072266,0.9302080273628235,,,4.283971786499023,1017.010009765625,1693.8399658203125
-1998-10-01,41.75224685668945,0.2834153473377228,16.637067794799805,80.36154174804688,1.0536459684371948,,,4.59221076965332,1098.6700439453125,1771.3900146484375
-1998-11-01,46.4265251159668,0.2438134402036667,19.170928955078125,88.54693603515625,1.600000023841858,,,5.535391330718994,1163.6300048828125,1949.5400390625
-1998-11-06,,,,,,,,,,
-1998-12-01,51.91548538208008,0.3125200569629669,21.793180465698242,97.19573974609375,2.6770830154418945,,,5.782783031463623,1229.22998046875,2192.68994140625
-1999-01-01,51.59874725341797,0.3144294023513794,27.499271392822266,102.47120666503906,2.92343807220459,,,5.912916660308838,1279.6400146484375,2505.889892578125
-1999-02-01,47.797481536865234,0.2657618522644043,23.5904541015625,91.21175384521484,3.203125,,,4.984185218811035,1238.3299560546875,2288.030029296875
-1999-02-08,,,,,,,,,,
-1999-03-01,49.97552490234375,0.27435049414634705,28.16712188720703,88.21611785888672,4.304687976837158,,,7.027392387390137,1286.3699951171875,2461.39990234375
-1999-04-01,58.98025894165039,0.35116779804229736,25.554689407348633,97.44929504394531,4.301562786102295,,,7.854666709899902,1335.1800537109375,2542.860107421875
-1999-05-01,65.41220092773438,0.3363769054412842,25.35825538635254,93.19886779785156,2.96875,,,9.187017440795898,1301.8399658203125,2470.52001953125
-1999-05-06,,,,,,,,,,
-1999-05-27,,,,,,,,,,
-1999-06-01,72.96644592285156,0.35355332493782043,28.343910217285156,97.96764373779297,3.128124952316284,,,10.182408332824707,1372.7099609375,2686.1201171875
-1999-07-01,70.95524597167969,0.4251234233379364,26.96893310546875,81.35432434082031,2.50156307220459,,,10.634023666381836,1328.719970703125,2638.489990234375
-1999-08-01,70.32015991210938,0.49812400341033936,29.090301513671875,79.7938461303711,3.109375,,,12.354691505432129,1320.4100341796875,2739.35009765625
-1999-08-06,,,,,,,,,,
-1999-09-01,68.37564849853516,0.48333317041397095,28.46175193786621,69.8066177368164,3.996875047683716,,,14.07535457611084,1282.7099609375,2746.159912109375
-1999-10-01,55.519859313964844,0.6116815209388733,29.090301513671875,47.42917251586914,3.53125,,,17.35419464111328,1362.9300537109375,2966.429931640625
-1999-11-01,58.239349365234375,0.747186541557312,28.613975524902344,45.75767135620117,4.253125190734863,,,17.044021606445312,1388.9100341796875,3336.159912109375
-1999-11-08,,,,,,,,,,
-1999-12-01,61.04003143310547,0.7848799824714661,36.6919059753418,37.92245101928711,3.8062500953674316,,,16.687326431274414,1469.25,4069.31005859375
-2000-01-01,63.515560150146484,0.7920366525650024,30.75990104675293,35.14961242675781,3.2281250953674316,,,13.668244361877441,1394.4599609375,3940.35009765625
-2000-02-01,58.14006042480469,0.8750578165054321,28.088550567626953,36.62297058105469,3.4437499046325684,,,25.31960105895996,1366.4200439453125,4696.68994140625
-2000-02-08,,,,,,,,,,
-2000-03-01,67.05181884765625,1.0368047952651978,33.39197540283203,43.779178619384766,3.3499999046325684,,,27.631258010864258,1498.5799560546875,4572.830078125
-2000-04-01,63.157623291015625,0.947104275226593,21.920852661132812,45.03520965576172,2.7593750953674316,,,30.027847290039062,1452.4300537109375,3860.659912109375
-2000-05-01,60.785640716552734,0.6412634253501892,19.661985397338867,46.097347259521484,2.4156250953674316,,,27.948402404785156,1420.5999755859375,3400.909912109375
-2000-05-08,,,,,,,,,,
-2000-06-01,62.13500213623047,0.7996708750724792,25.142194747924805,35.529056549072266,1.8156249523162842,,,32.277984619140625,1454.5999755859375,3966.110107421875
-2000-07-01,63.65913009643555,0.7758141756057739,21.940492630004883,25.79067039489746,1.506250023841858,,,28.43518829345703,1430.8299560546875,3766.989990234375
-2000-08-01,74.86860656738281,0.9304049015045166,21.940492630004883,27.82395362854004,2.075000047683716,,,32.28449630737305,1517.6800537109375,4206.35009765625
-2000-08-08,,,,,,,,,,
-2000-09-01,63.94328689575195,0.3931553065776825,18.95485496520996,25.980575561523438,1.921875,,,38.555137634277344,1436.510009765625,3672.820068359375
-2000-10-01,55.92375183105469,0.29868337512016296,21.645862579345703,14.6140718460083,1.8312499523162842,,,37.785430908203125,1429.4000244140625,3369.6298828125
-2000-11-01,53.08496856689453,0.2519250810146332,18.03167152404785,12.016016960144043,1.234375,,,31.482683181762695,1314.949951171875,2597.929931640625
-2000-11-08,,,,,,,,,,
-2000-12-01,48.32046127319336,0.22711420059204102,13.631781578063965,8.067792892456055,0.778124988079071,,,28.90570068359375,1320.280029296875,2470.52001953125
-2001-01-01,63.6693229675293,0.33017459511756897,19.190568923950195,14.251648902893066,0.8656250238418579,,,21.702556610107422,1366.010009765625,2772.72998046875
-2001-02-01,56.790767669677734,0.2786443829536438,18.54237174987793,10.536102294921875,0.5093749761581421,,,14.440549850463867,1239.93994140625,2151.830078125
-2001-02-07,,,,,,,,,,
-2001-03-01,54.73835754394531,0.3369686007499695,17.18704605102539,10.535667419433594,0.5115000009536743,,,17.375865936279297,1160.3299560546875,1840.260009765625
-2001-04-01,65.52893829345703,0.38918623328208923,21.292295455932617,15.900238990783691,0.7889999747276306,,,22.32872772216797,1249.4599609375,2116.239990234375
-2001-05-01,63.62804412841797,0.3046000301837921,21.741714477539062,17.430465698242188,0.8345000147819519,,,19.768779754638672,1255.8199462890625,2110.489990234375
-2001-05-08,,,,,,,,,,
-2001-06-01,64.6737060546875,0.35498547554016113,22.942251205444336,16.83243751525879,0.7074999809265137,,,23.362648010253906,1224.3800048828125,2160.5400390625
-2001-07-01,59.949947357177734,0.28688937425613403,20.80202293395996,14.035829544067383,0.6244999766349792,,,18.640790939331055,1211.22998046875,2027.1300048828125
-2001-08-01,56.952762603759766,0.2832247018814087,17.929533004760742,16.18165397644043,0.44699999690055847,,,16.711578369140625,1133.5799560546875,1805.4300537109375
-2001-08-08,,,,,,,,,,
-2001-09-01,52.33213424682617,0.23680917918682098,16.081575393676758,13.6312894821167,0.2985000014305115,,,11.92334270477295,1040.93994140625,1498.800048828125
-2001-10-01,61.660858154296875,0.26810887455940247,18.275238037109375,12.312134742736816,0.3490000069141388,,,13.133195877075195,1059.780029296875,1690.199951171875
-2001-11-01,65.95150756835938,0.3252120614051819,20.17975616455078,14.774558067321777,0.5659999847412109,,,15.958827018737793,1139.449951171875,1930.5799560546875
-2001-11-07,,,,,,,,,,
-2001-12-01,69.1006088256836,0.3343726694583893,20.820878982543945,18.32748794555664,0.5410000085830688,,,15.446427345275879,1148.0799560546875,1950.4000244140625
-2002-01-01,61.63407897949219,0.37742963433265686,20.022619247436523,19.928070068359375,0.7095000147819519,,,16.771486282348633,1130.199951171875,1934.030029296875
-2002-02-01,56.052799224853516,0.3313194811344147,18.334945678710938,17.07868194580078,0.7049999833106995,,,18.105239868164062,1106.72998046875,1731.489990234375
-2002-02-06,,,,,,,,,,
-2002-03-01,59.49020767211914,0.3613981306552887,18.95407485961914,18.907917022705078,0.7149999737739563,,,20.051130294799805,1147.3900146484375,1845.3499755859375
-2002-04-01,47.912540435791016,0.3705587685108185,16.424144744873047,15.56605339050293,0.8345000147819519,,,19.893611907958984,1076.9200439453125,1688.22998046875
-2002-05-01,46.01911926269531,0.35574817657470703,15.999865531921387,15.777122497558594,0.9114999771118164,,,17.971961975097656,1067.1400146484375,1615.72998046875
-2002-05-08,,,,,,,,,,
-2002-06-01,41.26642990112305,0.2705524265766144,17.190977096557617,10.55325984954834,0.8125,,,14.188389778137207,989.8200073242188,1463.2099609375
-2002-07-01,40.349422454833984,0.23299239575862885,15.079033851623535,12.224191665649414,0.7225000262260437,,,11.933782577514648,911.6199951171875,1328.260009765625
-2002-08-01,43.203697204589844,0.22520573437213898,15.424735069274902,12.329721450805664,0.746999979019165,,,10.01123046875,916.0700073242188,1314.8499755859375
-2002-08-07,,,,,,,,,,
-2002-09-01,33.49409484863281,0.22138899564743042,13.746496200561523,8.706437110900879,0.796500027179718,,,9.513158798217773,815.280029296875,1172.06005859375
-2002-10-01,45.344242095947266,0.24535933136940002,16.804426193237305,11.678934097290039,0.9679999947547913,,,11.782204627990723,885.760009765625,1329.75
-2002-11-01,49.92806625366211,0.23665708303451538,18.127525329589844,15.337401390075684,1.1675000190734863,,,14.71778678894043,936.3099975585938,1478.780029296875
-2002-11-06,,,,,,,,,,
-2002-12-01,44.5990104675293,0.2187930941581726,16.248149871826172,14.15894889831543,0.9445000290870667,,,12.360349655151367,879.8200073242188,1335.510009765625
-2003-01-01,45.00184631347656,0.21925139427185059,14.91561222076416,15.56605339050293,1.0924999713897705,,,13.167760848999023,855.7000122070312,1320.9100341796875
-2003-02-01,44.85797119140625,0.22917553782463074,14.896756172180176,15.829883575439453,1.1004999876022339,,,13.712512969970703,841.1500244140625,1337.52001953125
-2003-02-06,,,,,,,,,,
-2003-03-01,45.22197723388672,0.2158920168876648,15.266251564025879,15.302220344543457,1.3014999628067017,,,15.372973442077637,848.1799926757812,1341.1700439453125
-2003-04-01,48.95253372192383,0.21711383759975433,16.123830795288086,17.342517852783203,1.434499979019165,,,17.22471046447754,916.9199829101562,1464.31005859375
-2003-05-01,50.76301956176758,0.2740640342235565,15.518482208251953,19.224523544311523,1.7944999933242798,,,17.618791580200195,963.5900268554688,1595.9100341796875
-2003-05-07,,,,,,,,,,
-2003-06-01,47.655845642089844,0.29101142287254333,16.16796875,18.626508712768555,1.815999984741211,,,15.997578620910645,974.5,1622.800048828125
-2003-07-01,46.933773040771484,0.32185351848602295,16.653514862060547,18.995861053466797,2.0820000171661377,,,16.333431243896484,990.3099975585938,1735.02001953125
-2003-08-01,47.37279510498047,0.34521347284317017,16.722881317138672,18.960683822631836,2.315999984741211,,,19.37755012512207,1008.010009765625,1810.449951171875
-2003-08-06,,,,,,,,,,
-2003-09-01,51.1259651184082,0.3163566291332245,17.530014038085938,18.046072006225586,2.4214999675750732,,,19.657007217407227,995.969970703125,1786.93994140625
-2003-10-01,51.79159927368164,0.3494885563850403,16.48325538635254,18.468202590942383,2.7214999198913574,,,21.84463119506836,1050.7099609375,1932.2099609375
-2003-11-01,52.405128479003906,0.3192576766014099,16.303056716918945,21.423110961914062,2.698499917984009,,,20.621614456176758,1058.199951171875,1960.260009765625
-2003-11-06,,,,,,,,,,
-2003-12-01,53.74093246459961,0.32628077268600464,17.35569190979004,24.272485733032227,2.63100004196167,,,19.5084171295166,1111.9200439453125,2003.3699951171875
-2004-01-01,57.53900146484375,0.3444499373435974,17.533241271972656,25.74994659423828,2.5199999809265137,,,19.119047164916992,1131.1300048828125,2066.14990234375
-2004-02-01,55.95598602294922,0.36521488428115845,16.82303810119629,24.87051010131836,2.1505000591278076,,,18.600963592529297,1144.93994140625,2029.8199462890625
-2004-02-06,,,,,,,,,,
-2004-03-01,53.3401985168457,0.4128514230251312,15.808448791503906,25.6268310546875,2.1640000343322754,,,19.62464141845703,1126.2099609375,1994.219970703125
-2004-04-01,51.208683013916016,0.39361342787742615,16.56939125061035,23.6217041015625,2.180000066757202,,,20.729951858520508,1107.300048828125,1920.1500244140625
-2004-05-01,51.45262145996094,0.4284247159957886,16.632802963256836,23.815183639526367,2.424999952316284,,,22.293439865112305,1120.6800537109375,1986.739990234375
-2004-05-06,,,,,,,,,,
-2004-06-01,51.300846099853516,0.4968261420726776,18.110280990600586,25.503700256347656,2.7200000286102295,,,23.227535247802734,1140.8399658203125,2047.7900390625
-2004-07-01,50.672325134277344,0.4937727451324463,18.065902709960938,24.378023147583008,1.9459999799728394,,,21.075881958007812,1101.719970703125,1887.3599853515625
-2004-08-01,49.28722381591797,0.5265995860099792,17.31130027770996,23.6217041015625,1.906999945640564,,,22.91964340209961,1104.239990234375,1838.0999755859375
-2004-08-06,,,,,,,,,,
-2004-09-01,50.00397872924805,0.5916416049003601,17.5849609375,24.764976501464844,2.0429999828338623,,64.8648681640625,24.718441009521484,1114.5799560546875,1896.8399658203125
-2004-10-01,52.34260559082031,0.800052285194397,17.788476943969727,25.978591918945312,1.7065000534057617,,95.41541290283203,28.003637313842773,1130.199951171875,1974.989990234375
-2004-11-01,54.96117401123047,1.0237311124801636,17.050731658935547,26.945974349975586,1.9839999675750732,,91.0810775756836,30.26772117614746,1173.8199462890625,2096.81005859375
-2004-11-08,,,,,,,,,,
-2004-12-01,57.60344696044922,0.9832708239555359,18.939943313598633,29.918479919433594,2.2144999504089355,,96.49149322509766,31.357276916503906,1211.9200439453125,2175.43994140625
-2005-01-01,54.58831024169922,1.1741228103637695,18.628063201904297,27.930959701538086,2.1610000133514404,,97.90790557861328,28.444419860839844,1181.27001953125,2062.409912109375
-2005-02-01,54.09749221801758,1.3698610067367554,17.83417510986328,27.438472747802734,1.7589999437332153,,94.0890884399414,30.86894416809082,1203.5999755859375,2051.719970703125
-2005-02-08,,,,,,,,,,
-2005-03-01,53.49815368652344,1.2724499702453613,17.18527603149414,26.6469669342041,1.7135000228881836,,90.34534454345703,33.57841110229492,1180.5899658203125,1999.22998046875
-2005-04-01,44.7164421081543,1.1011403799057007,17.988739013671875,23.305103302001953,1.6180000305175781,,110.110107421875,29.735000610351562,1156.8499755859375,1921.6500244140625
-2005-05-01,44.23051071166992,1.2141252756118774,18.3442440032959,23.867952346801758,1.7755000591278076,,138.77377319335938,33.119998931884766,1191.5,2068.219970703125
-2005-05-06,,,,,,,,,,
-2005-06-01,43.555538177490234,1.124043345451355,17.71768569946289,24.254899978637695,1.6545000076293945,,147.22222900390625,28.610000610351562,1191.3299560546875,2056.9599609375
-2005-07-01,48.991188049316406,1.3023751974105835,18.26690673828125,23.234752655029297,2.257499933242798,,144.02401733398438,29.639999389648438,1234.1800537109375,2184.830078125
-2005-08-01,47.3240966796875,1.431849479675293,19.529403686523438,23.58652687072754,2.134999990463257,,143.1431427001953,27.040000915527344,1220.3299560546875,2152.090087890625
-2005-08-08,,,,,,,,,,
-2005-09-01,47.202552795410156,1.6370543241500854,18.40694236755371,24.00865936279297,2.265000104904175,,158.3883819580078,29.850000381469727,1228.81005859375,2151.68994140625
-2005-10-01,48.1793098449707,1.7585887908935547,18.385473251342773,23.867952346801758,1.9930000305175781,,186.25625610351562,32.25,1207.010009765625,2120.300048828125
-2005-11-01,52.309974670410156,2.0709757804870605,19.80194664001465,24.976051330566406,2.4230000972747803,,202.65765380859375,32.61000061035156,1249.47998046875,2232.820068359375
-2005-11-08,,,,,,,,,,
-2005-12-01,48.483585357666016,2.1952593326568604,18.762245178222656,25.76755142211914,2.3575000762939453,,207.63763427734375,36.959999084472656,1248.2900390625,2205.320068359375
-2006-01-01,47.95273208618164,2.305800437927246,20.19721794128418,25.169517517089844,2.240999937057495,,216.5465545654297,39.72999954223633,1280.0799560546875,2305.820068359375
-2006-02-01,47.32752227783203,2.0914342403411865,19.27882957458496,26.207246780395508,1.871999979019165,,181.49148559570312,38.54999923706055,1280.6600341796875,2281.389892578125
-2006-02-08,,,,,,,,,,
-2006-03-01,48.76497268676758,1.9152405261993408,19.588937759399414,26.734920501708984,1.8265000581741333,,195.1951904296875,34.95000076293945,1294.8699951171875,2339.7900390625
-2006-04-01,48.6880989074707,2.149454355239868,17.385986328125,24.694625854492188,1.7604999542236328,,209.17918395996094,39.20000076293945,1310.6099853515625,2322.570068359375
-2006-05-01,47.24531936645508,1.8251585960388184,16.306108474731445,24.149375915527344,1.7304999828338623,,186.09609985351562,28.6299991607666,1270.0899658203125,2178.8798828125
-2006-05-08,,,,,,,,,,
-2006-06-01,45.58832931518555,1.7488168478012085,16.83946990966797,24.465961456298828,1.934000015258789,,209.8748779296875,30.360000610351562,1270.199951171875,2172.090087890625
-2006-07-01,45.938453674316406,2.075251340866089,17.388734817504883,24.78256607055664,1.344499945640564,,193.49349975585938,28.510000228881836,1276.6600341796875,2091.469970703125
-2006-08-01,48.051090240478516,2.0718915462493896,18.574007034301758,26.048952102661133,1.5414999723434448,,189.45445251464844,32.439998626708984,1303.8199462890625,2183.75
-2006-08-08,,,,,,,,,,
-2006-09-01,48.820682525634766,2.350689172744751,19.839282989501953,27.368104934692383,1.6059999465942383,,201.15115356445312,37.459999084472656,1335.8499755859375,2258.429931640625
-2006-10-01,55.01115798950195,2.475886821746826,20.82581329345703,29.90088653564453,1.9045000076293945,,238.4334259033203,38.25,1377.93994140625,2366.7099609375
-2006-11-01,54.766883850097656,2.798962354660034,21.29731559753418,29.021446228027344,2.0169999599456787,,242.64764404296875,40.15999984741211,1400.6300048828125,2431.77001953125
-2006-11-08,,,,,,,,,,
-2006-12-01,58.07079315185547,2.5907039642333984,21.73406219482422,29.812957763671875,1.9730000495910645,,230.47047424316406,41.119998931884766,1418.300048828125,2415.2900390625
-2007-01-01,59.266300201416016,2.617882013320923,22.461923599243164,30.252676010131836,1.8834999799728394,,251.00100708007812,38.869998931884766,1438.239990234375,2463.929931640625
-2007-02-01,55.55428695678711,2.583681344985962,20.50397491455078,30.37578582763672,1.9570000171661377,,224.949951171875,39.25,1406.8199462890625,2416.14990234375
-2007-02-07,,,,,,,,,,
-2007-03-01,56.51309585571289,2.8371317386627197,20.3559513092041,29.707414627075195,1.9895000457763672,,229.30931091308594,41.70000076293945,1420.8599853515625,2421.639892578125
-2007-04-01,61.27952575683594,3.0475287437438965,21.867843627929688,32.539215087890625,3.066499948501587,,235.92591857910156,41.560001373291016,1482.3699951171875,2525.090087890625
-2007-05-01,63.91150665283203,3.700700044631958,22.415639877319336,33.18999099731445,3.4570000171661377,,249.20420837402344,44.060001373291016,1530.6199951171875,2604.52001953125
-2007-05-08,,,,,,,,,,
-2007-06-01,63.347747802734375,3.7266552448272705,21.59428596496582,32.5040397644043,3.4205000400543213,,261.6116027832031,40.150001525878906,1503.3499755859375,2603.22998046875
-2007-07-01,66.59786987304688,4.023471355438232,21.242568969726562,30.70998764038086,3.927000045776367,,255.2552490234375,40.290000915527344,1455.27001953125,2546.27001953125
-2007-08-01,70.23324584960938,4.228675365447998,21.052053451538086,30.12954330444336,3.995500087738037,,257.88287353515625,42.75,1473.989990234375,2596.360107421875
-2007-08-08,,,,,,,,,,
-2007-09-01,71.1520004272461,4.68641471862793,21.662628173828125,30.49891471862793,4.65749979019165,,283.9189147949219,43.65999984741211,1526.75,2701.5
-2007-10-01,70.13726806640625,5.800380706787109,27.067256927490234,30.674802780151367,4.457499980926514,,353.8538513183594,47.900001525878906,1549.3800048828125,2859.1201171875
-2007-11-01,63.529457092285156,5.564334392547607,24.70686912536621,29.6898193359375,4.5279998779296875,,346.8468322753906,42.13999938964844,1481.1400146484375,2660.9599609375
-2007-11-07,,,,,,,,,,
-2007-12-01,65.52474212646484,6.048642158508301,26.26405906677246,28.4762020111084,4.631999969482422,,346.0860900878906,42.72999954223633,1468.3599853515625,2652.280029296875
-2008-01-01,64.92465209960938,4.133399963378906,24.050800323486328,27.21040916442871,3.884999990463257,,282.43243408203125,34.93000030517578,1378.550048828125,2389.860107421875
-2008-02-01,69.0161361694336,3.8176541328430176,20.066930770874023,25.923078536987305,3.2235000133514404,,235.82582092285156,33.650001525878906,1330.6300048828125,2271.47998046875
-2008-02-06,,,,,,,,,,
-2008-03-01,70.05885314941406,4.381966590881348,21.01883316040039,26.399211883544922,3.565000057220459,,220.45545959472656,35.59000015258789,1322.699951171875,2279.10009765625
-2008-04-01,73.44194030761719,5.311798572540283,21.122520446777344,24.706567764282227,3.93149995803833,,287.43243408203125,37.290000915527344,1385.5899658203125,2412.800048828125
-2008-05-01,78.75386810302734,5.763737201690674,20.974388122558594,24.016834259033203,4.080999851226807,,293.1932067871094,44.060001373291016,1400.3800048828125,2522.659912109375
-2008-05-07,,,,,,,,,,
-2008-06-01,72.41636657714844,5.11300802230835,20.449499130249023,23.981456756591797,3.6665000915527344,,263.4734802246094,39.38999938964844,1280.0,2292.97998046875
-2008-07-01,78.18988800048828,4.853753566741943,19.118900299072266,24.197914123535156,3.816999912261963,,237.1121063232422,41.349998474121094,1267.3800048828125,2325.550048828125
-2008-08-01,74.37141418457031,5.176827907562256,20.285959243774414,24.712379455566406,4.040500164031982,,231.8768768310547,42.83000183105469,1282.8299560546875,2367.52001953125
-2008-08-06,,,,,,,,,,
-2008-09-01,71.73551177978516,3.470762014389038,19.91908073425293,20.454687118530273,3.638000011444092,,200.46046447753906,39.470001220703125,1166.3599853515625,2091.8798828125
-2008-10-01,57.02163314819336,3.2854056358337402,16.66515350341797,14.2785062789917,2.861999988555908,,179.85986328125,26.639999389648438,968.75,1720.949951171875
-2008-11-01,50.04803466796875,2.8298041820526123,15.090431213378906,12.444729804992676,2.134999990463257,,146.6266326904297,23.15999984741211,896.239990234375,1535.5699462890625
-2008-11-06,,,,,,,,,,
-2008-12-01,51.90673828125,2.6062774658203125,14.606595039367676,14.189484596252441,2.563999891281128,,153.97897338867188,21.290000915527344,903.25,1577.030029296875
-2009-01-01,56.52627944946289,2.7522425651550293,12.848398208618164,11.888165473937988,2.940999984741211,,169.43443298339844,19.309999465942383,825.8800048828125,1476.4200439453125
-2009-02-01,56.76066589355469,2.7272019386291504,12.13459587097168,9.274202346801758,3.239500045776367,,169.16416931152344,16.700000762939453,735.0900268554688,1377.8399658203125
-2009-02-06,,,,,,,,,,
-2009-03-01,60.08320999145508,3.209982395172119,13.897279739379883,8.146258354187012,3.671999931335449,,174.20420837402344,21.389999389648438,797.8699951171875,1528.5899658203125
-2009-04-01,64.00231170654297,3.8423893451690674,15.3270902633667,11.028571128845215,4.026000022888184,,198.1831817626953,27.350000381469727,872.8099975585938,1717.300048828125
-2009-05-01,65.90607452392578,4.147140979766846,15.803704261779785,12.274019241333008,3.8994998931884766,,208.82382202148438,28.18000030517578,919.1400146484375,1774.3299560546875
-2009-05-06,,,,,,,,,,
-2009-06-01,65.09091186523438,4.349293231964111,18.0966796875,11.69642448425293,4.183000087738037,,211.00601196289062,28.299999237060547,919.3200073242188,1835.0400390625
-2009-07-01,73.51245880126953,4.989336013793945,17.906352996826172,14.879191398620605,4.288000106811523,,221.7467498779297,32.41999816894531,987.47998046875,1978.5
-2009-08-01,73.58724975585938,5.1365203857421875,18.766645431518555,15.714898109436035,4.059500217437744,,231.06607055664062,31.420000076293945,1020.6199951171875,2009.06005859375
-2009-08-06,,,,,,,,,,
-2009-09-01,74.90744018554688,5.659914016723633,19.69136619567871,14.061647415161133,4.668000221252441,,248.1731719970703,33.040000915527344,1057.0799560546875,2122.419921875
-2009-10-01,75.53370666503906,5.756102561950684,21.230228424072266,13.72740650177002,5.940499782562256,,268.3283386230469,32.939998626708984,1036.18994140625,2045.1099853515625
-2009-11-01,79.12847900390625,6.1045241355896,22.51645278930664,14.055986404418945,6.795499801635742,,291.7917785644531,35.08000183105469,1095.6300048828125,2144.60009765625
-2009-11-06,,,,,,,,,,
-2009-12-01,82.34589385986328,6.434925556182861,23.438796997070312,15.443329811096191,6.72599983215332,,310.30029296875,36.779998779296875,1115.0999755859375,2269.14990234375
-2010-01-01,76.99246215820312,5.86481237411499,21.670120239257812,15.999075889587402,6.270500183105469,,265.2352294921875,32.29999923706055,1073.8699951171875,2147.35009765625
-2010-02-01,79.99315643310547,6.248349666595459,22.04693031311035,17.19167137145996,5.920000076293945,,263.6636657714844,34.650001525878906,1104.489990234375,2238.260009765625
-2010-02-08,,,,,,,,,,
-2010-03-01,81.0396728515625,7.176041126251221,22.629026412963867,17.88887596130371,6.78849983215332,,283.8438415527344,35.369998931884766,1169.4300537109375,2397.9599609375
-2010-04-01,81.51359558105469,7.972740650177002,23.594758987426758,20.0878963470459,6.855000019073486,,263.11309814453125,33.599998474121094,1186.68994140625,2461.18994140625
-2010-05-01,79.1503677368164,7.84417724609375,19.932706832885742,17.157638549804688,6.2729997634887695,,243.0580596923828,32.08000183105469,1089.4100341796875,2257.0400390625
-2010-05-06,,,,,,,,,,
-2010-06-01,78.42550659179688,7.680809020996094,17.857412338256836,14.817129135131836,5.4629998207092285,,222.69769287109375,26.43000030517578,1030.7099609375,2109.239990234375
-2010-07-01,81.55033874511719,7.855478763580322,20.03040885925293,18.038850784301758,5.894499778747559,,242.66766357421875,28.719999313354492,1101.5999755859375,2254.699951171875
-2010-08-01,78.20323944091797,7.4233856201171875,18.214401245117188,15.64971923828125,6.241499900817871,,225.2352294921875,27.700000762939453,1049.3299560546875,2114.030029296875
-2010-08-06,,,,,,,,,,
-2010-09-01,85.6181411743164,8.664690971374512,19.10737419128418,19.168588638305664,7.853000164031982,,263.1581726074219,26.149999618530273,1141.199951171875,2368.6201171875
-2010-10-01,91.65619659423828,9.190831184387207,20.808244705200195,21.757949829101562,8.261500358581543,,307.15716552734375,28.149999618530273,1183.260009765625,2507.409912109375
-2010-11-01,90.290283203125,9.501388549804688,19.70814323425293,21.311634063720703,8.770000457763672,,278.1331481933594,27.799999237060547,1180.550048828125,2498.22998046875
-2010-11-08,,,,,,,,,,
-2010-12-01,94.08943176269531,9.84980583190918,21.909496307373047,21.423206329345703,9.0,,297.28228759765625,30.780000686645508,1257.6400146484375,2652.8701171875
-2011-01-01,103.8599853515625,10.361597061157227,21.76820182800293,19.823131561279297,8.482000350952148,,300.48046875,33.04999923706055,1286.1199951171875,2700.080078125
-2011-02-01,103.78302001953125,10.785745620727539,20.865453720092773,20.065792083740234,8.66450023651123,,307.00701904296875,34.5,1327.219970703125,2782.27001953125
-2011-02-08,,,,,,,,,,
-2011-03-01,104.95984649658203,10.64222526550293,20.04909324645996,19.879127502441406,9.006500244140625,,293.6736755371094,33.15999984741211,1325.8299560546875,2781.070068359375
-2011-04-01,109.79368591308594,10.691693305969238,20.467607498168945,18.910266876220703,9.790499687194824,,272.32232666015625,33.54999923706055,1363.6099853515625,2873.5400390625
-2011-05-01,108.73165130615234,10.621461868286133,19.7490291595459,19.135168075561523,9.834500312805176,,264.7747802734375,34.630001068115234,1345.199951171875,2835.300048828125
-2011-05-06,,,,,,,,,,
-2011-06-01,110.91179656982422,10.25013542175293,20.665348052978516,19.510000228881836,10.224499702453613,,253.4434356689453,31.450000762939453,1320.6400146484375,2773.52001953125
-2011-07-01,117.571044921875,11.923834800720215,21.778095245361328,17.562105178833008,11.12600040435791,,302.14715576171875,27.709999084472656,1292.280029296875,2756.3798828125
-2011-08-01,111.14454650878906,11.75130844116211,21.142244338989258,15.623312950134277,10.761500358581543,,270.7507629394531,25.239999771118164,1218.8900146484375,2579.4599609375
-2011-08-08,,,,,,,,,,
-2011-09-01,113.55061340332031,11.644124984741211,19.90796661376953,13.119815826416016,10.81149959564209,,257.77777099609375,24.170000076293945,1131.4200439453125,2415.39990234375
-2011-10-01,119.88819122314453,12.360504150390625,21.299680709838867,15.485393524169922,10.67549991607666,,296.6166076660156,29.40999984741211,1253.300048828125,2684.409912109375
-2011-11-01,122.07645416259766,11.670994758605957,20.459848403930664,15.42860221862793,9.614500045776367,,299.9949951171875,27.420000076293945,1246.9599609375,2620.340087890625
-2011-11-08,,,,,,,,,,
-2011-12-01,119.88117218017578,12.367225646972656,20.92014503479004,15.068914413452148,8.654999732971191,,323.2732849121094,28.270000457763672,1257.5999755859375,2605.14990234375
-2012-01-01,125.56623077392578,13.939234733581543,23.79706382751465,14.749091148376465,9.722000122070312,,290.3453369140625,30.950000762939453,1312.4100341796875,2813.840087890625
-2012-02-01,128.25875854492188,16.564136505126953,25.57801628112793,15.662582397460938,8.98449993133545,,309.4344482421875,32.88999938964844,1365.6800537109375,2966.889892578125
-2012-02-08,,,,,,,,,,
-2012-03-01,136.5597381591797,18.308074951171875,26.1682071685791,15.377117156982422,10.125499725341797,,320.9409484863281,34.310001373291016,1408.469970703125,3091.570068359375
-2012-04-01,135.53221130371094,17.83262062072754,25.97353172302246,14.882647514343262,11.595000267028809,,302.72772216796875,33.54999923706055,1397.9100341796875,3046.360107421875
-2012-05-01,126.25150299072266,17.64176368713379,23.677928924560547,13.811394691467285,10.645500183105469,,290.7207336425781,31.049999237060547,1310.3299560546875,2827.340087890625
-2012-05-08,,,,,,,,,,
-2012-06-01,128.5418243408203,17.83323097229004,24.976381301879883,15.054808616638184,11.417499542236328,,290.3253173828125,32.369998931884766,1362.1600341796875,2935.050048828125
-2012-07-01,128.80467224121094,18.650381088256836,24.06191635131836,13.332178115844727,11.664999961853027,,316.8017883300781,30.8799991607666,1379.3199462890625,2939.52001953125
-2012-08-01,128.06199645996094,20.314008712768555,25.1641845703125,14.178669929504395,12.41349983215332,,342.88787841796875,31.270000457763672,1406.5799560546875,3066.9599609375
-2012-08-08,,,,,,,,,,
-2012-09-01,136.92532348632812,20.458269119262695,24.459667205810547,14.120949745178223,12.715999603271484,,377.62762451171875,32.439998626708984,1440.6700439453125,3116.22998046875
-2012-10-01,128.39756774902344,18.256948471069336,23.456958770751953,12.4627103805542,11.644499778747559,,340.490478515625,34.029998779296875,1412.1600341796875,2977.22998046875
-2012-11-01,125.45381927490234,17.94904899597168,21.878910064697266,13.178736686706543,12.602499961853027,,349.5345458984375,34.61000061035156,1416.1800537109375,3010.239990234375
-2012-11-07,,,,,,,,,,
-2012-12-01,126.98394775390625,16.39484405517578,22.13326644897461,13.19808578491211,12.543499946594238,,354.0440368652344,37.68000030517578,1426.18994140625,3019.510009765625
-2013-01-01,134.6208953857422,14.03252124786377,22.746475219726562,15.598185539245605,13.274999618530273,,378.2232360839844,37.83000183105469,1498.1099853515625,3142.1298828125
-2013-02-01,133.1359405517578,13.598445892333984,23.036500930786133,15.79291820526123,13.213500022888184,,401.0010070800781,39.310001373291016,1514.6800537109375,3160.18994140625
-2013-02-06,,,,,,,,,,
-2013-03-01,141.99786376953125,13.716739654541016,23.903995513916016,16.74711036682129,13.32450008392334,,397.49249267578125,43.52000045776367,1569.18994140625,3267.52001953125
-2013-04-01,134.8347625732422,13.720457077026367,27.655447006225586,16.822824478149414,12.690500259399414,,412.69769287109375,45.08000183105469,1597.5699462890625,3328.7900390625
-2013-05-01,138.48284912109375,13.935823440551758,29.15936851501465,17.234567642211914,13.460000038146973,,436.0460510253906,42.90999984741211,1630.739990234375,3455.909912109375
-2013-05-08,,,,,,,,,,
-2013-06-01,127.82191467285156,12.368638038635254,29.060949325561523,17.783567428588867,13.884499549865723,,440.6256408691406,45.560001373291016,1606.280029296875,3403.25
-2013-07-01,130.45040893554688,14.115401268005371,26.789243698120117,19.142587661743164,15.060999870300293,,444.3193054199219,47.279998779296875,1685.72998046875,3626.3701171875
-2013-08-01,121.90938568115234,15.19745922088623,28.101774215698242,19.695158004760742,14.048999786376953,,423.8738708496094,45.75,1632.969970703125,3589.8701171875
-2013-08-07,,,,,,,,,,
-2013-09-01,124.47478485107422,14.96906566619873,28.19812774658203,20.306934356689453,15.631999969482422,,438.3934020996094,51.939998626708984,1681.550048828125,3771.47998046875
-2013-10-01,120.46192169189453,16.41180992126465,30.002870559692383,19.72601890563965,18.201499938964844,,515.8057861328125,54.220001220703125,1756.5400390625,3919.7099609375
-2013-11-01,120.77778625488281,17.45956802368164,32.30753707885742,22.58371353149414,19.680999755859375,,530.3253173828125,56.779998779296875,1805.81005859375,4059.889892578125
-2013-11-06,,,,,,,,,,
-2013-12-01,126.7584228515625,17.71782684326172,31.937856674194336,24.151473999023438,19.93950080871582,,560.9158935546875,59.880001068115234,1848.3599853515625,4176.58984375
-2014-01-01,119.39906311035156,15.80967903137207,32.304969787597656,21.634523391723633,17.934499740600586,,591.0760498046875,59.189998626708984,1782.5899658203125,4103.8798828125
-2014-02-01,125.13655090332031,16.61942481994629,32.70622634887695,21.913677215576172,18.104999542236328,,608.4334106445312,68.62999725341797,1859.449951171875,4308.1201171875
-2014-02-06,,,,,,,,,,
-2014-03-01,130.79644775390625,17.052499771118164,35.256614685058594,22.53180694580078,16.818500518798828,,557.8128051757812,65.73999786376953,1872.3399658203125,4198.990234375
-2014-04-01,133.50091552734375,18.747455596923828,34.7491340637207,24.246538162231445,15.206500053405762,,534.8800048828125,61.689998626708984,1883.949951171875,4114.56005859375
-2014-05-01,125.27215576171875,20.11072540283203,35.21359634399414,24.767969131469727,15.6274995803833,,571.6500244140625,64.54000091552734,1923.5699462890625,4242.6201171875
-2014-05-07,,,,,,,,,,
-2014-06-01,123.88963317871094,20.782461166381836,36.12032699584961,24.94846534729004,16.23900032043457,,584.6699829101562,72.36000061035156,1960.22998046875,4408.18017578125
-2014-07-01,130.99761962890625,21.37957000732422,37.38497543334961,26.72607421875,15.649499893188477,,579.5499877929688,69.25,1930.6700439453125,4369.77001953125
-2014-08-01,131.4281463623047,22.922651290893555,39.35124206542969,27.834640502929688,16.95199966430664,,582.3599853515625,71.9000015258789,2003.3699951171875,4580.27001953125
-2014-08-06,,,,,,,,,,
-2014-09-01,130.50729370117188,22.643360137939453,40.40761947631836,26.66560935974121,16.121999740600586,,588.4099731445312,69.19000244140625,1972.2900390625,4493.39013671875
-2014-10-01,113.0242691040039,24.27278709411621,40.92185974121094,26.89417266845703,15.27299976348877,,567.8699951171875,70.12000274658203,2018.050048828125,4630.740234375
-2014-11-01,111.49117279052734,26.729284286499023,41.67144012451172,28.27128028869629,16.93199920654297,,549.0800170898438,73.68000030517578,2067.56005859375,4791.6298828125
-2014-11-06,,,,,,,,,,
-2014-12-01,111.05672454833984,24.915250778198242,40.74142074584961,28.068769454956055,15.517499923706055,,530.6599731445312,72.69999694824219,2058.89990234375,4736.0498046875
-2015-01-01,106.12132263183594,26.445661544799805,35.434940338134766,26.79075813293457,17.726499557495117,,537.5499877929688,70.12999725341797,1994.989990234375,4635.240234375
-2015-02-01,112.09505462646484,28.996322631835938,38.460933685302734,27.767194747924805,19.007999420166016,,562.6300048828125,79.0999984741211,2104.5,4963.52978515625
-2015-02-06,,,,,,,,,,
-2015-03-01,111.87759399414062,28.197509765625,35.91679000854492,26.139816284179688,18.604999542236328,,554.7000122070312,73.94000244140625,2067.889892578125,4900.8798828125
-2015-04-01,119.3988265991211,28.360668182373047,42.96587371826172,23.521541595458984,21.089000701904297,,548.77001953125,76.05999755859375,2085.510009765625,4941.419921875
-2015-05-01,118.25563049316406,29.523195266723633,41.39352035522461,23.3579158782959,21.46150016784668,,545.3200073242188,79.08999633789062,2107.389892578125,5070.02978515625
-2015-05-06,,,,,,,,,,
-2015-06-01,114.24130249023438,28.542850494384766,39.253108978271484,21.762542724609375,21.704500198364258,,540.0399780273438,81.01000213623047,2063.110107421875,4986.8701171875
-2015-07-01,113.77072143554688,27.60302734375,41.520286560058594,22.683992385864258,26.8075008392334,,657.5,81.98999786376953,2103.840087890625,5128.27978515625
-2015-08-01,103.86784362792969,25.65966796875,38.692989349365234,20.93431854248047,25.644500732421875,,647.8200073242188,78.56999969482422,1972.1800537109375,4776.509765625
-2015-08-06,,,,,,,,,,
-2015-09-01,102.66226959228516,25.21347999572754,39.61040496826172,20.028608322143555,25.594499588012695,,638.3699951171875,82.22000122070312,1920.030029296875,4620.16015625
-2015-10-01,99.1993637084961,27.31651496887207,47.11008071899414,19.46390151977539,31.295000076293945,,737.3900146484375,88.66000366210938,2079.360107421875,5053.75
-2015-11-01,98.7319564819336,27.042200088500977,48.64043045043945,21.868392944335938,33.2400016784668,,762.8499755859375,91.45999908447266,2080.409912109375,5108.669921875
-2015-11-06,,,,,,,,,,
-2015-12-01,98.37144470214844,24.16438102722168,49.98638916015625,22.03421974182129,33.794498443603516,,778.010009765625,93.94000244140625,2043.93994140625,5007.41015625
-2016-01-01,89.20050811767578,22.3461971282959,49.63501739501953,20.343839645385742,29.350000381469727,,761.3499755859375,89.12999725341797,1940.239990234375,4613.9501953125
-2016-02-01,93.6608657836914,22.196985244750977,45.841888427734375,20.051719665527344,27.625999450683594,,717.219970703125,85.1500015258789,1932.22998046875,4557.9501953125
-2016-02-08,,,,,,,,,,
-2016-03-01,109.36297607421875,25.15644073486328,50.11842727661133,23.285871505737305,29.68199920654297,,762.9000244140625,93.80000305175781,2059.739990234375,4869.85009765625
-2016-04-01,105.3841552734375,21.636524200439453,45.25450134277344,20.178363800048828,32.97949981689453,,707.8800048828125,94.22000122070312,2065.300048828125,4775.35986328125
-2016-05-01,111.01663208007812,23.049110412597656,48.094825744628906,20.956079483032227,36.13949966430664,,748.8499755859375,99.47000122070312,2096.949951171875,4948.0498046875
-2016-05-06,,,,,,,,,,
-2016-06-01,110.65898895263672,22.20018196105957,46.75897216796875,19.947153091430664,35.78099822998047,,703.530029296875,95.79000091552734,2098.860107421875,4842.669921875
-2016-07-01,117.10401916503906,24.199600219726562,51.79398727416992,21.839828491210938,37.94049835205078,,791.3400268554688,97.86000061035156,2173.60009765625,5162.1298828125
-2016-08-01,115.83541107177734,24.638490676879883,52.506752014160156,20.885658264160156,38.45800018310547,,789.8499755859375,102.30999755859375,2170.949951171875,5213.22021484375
-2016-08-08,,,,,,,,,,
-2016-09-01,116.81381225585938,26.394628524780273,52.96271896362305,21.479366302490234,41.865501403808594,13.321450233459473,804.0599975585938,108.54000091552734,2168.27001953125,5312.0
-2016-10-01,113.019287109375,26.509033203125,55.095947265625,20.878395080566406,39.49100112915039,13.680961608886719,809.9000244140625,107.51000213623047,2126.14990234375,5189.14013671875
-2016-11-01,119.29200744628906,25.803936004638672,55.40858840942383,19.980859756469727,37.528499603271484,14.926712036132812,775.8800048828125,102.80999755859375,2198.81005859375,5323.68017578125
-2016-11-08,,,,,,,,,,
-2016-12-01,123.1717300415039,27.180198669433594,57.52321243286133,18.655929565429688,37.493499755859375,15.31966781616211,792.4500122070312,102.94999694824219,2238.830078125,5383.1201171875
-2017-01-01,129.5013427734375,28.47795867919922,59.84672927856445,22.670724868774414,41.17399978637695,17.554771423339844,820.1900024414062,113.37999725341797,2278.8701171875,5614.7900390625
-2017-02-01,133.43417358398438,32.148292541503906,59.22650909423828,24.339130401611328,42.25199890136719,17.69411849975586,844.9299926757812,118.33999633789062,2363.639892578125,5825.43994140625
-2017-02-08,,,,,,,,,,
-2017-03-01,130.24111938476562,33.85976028442383,61.33644485473633,24.011991500854492,44.32699966430664,17.858545303344727,847.7999877929688,130.1300048828125,2362.719970703125,5911.740234375
-2017-04-01,119.88253784179688,33.85739517211914,63.75787353515625,23.72492027282715,46.2495002746582,18.70298194885254,924.52001953125,133.74000549316406,2384.199951171875,6047.60986328125
-2017-05-01,114.1535415649414,36.00456237792969,65.0430908203125,23.328956604003906,49.73099899291992,19.338397979736328,987.0900268554688,141.86000061035156,2411.800048828125,6198.52001953125
-2017-05-08,,,,,,,,,,
-2017-06-01,116.17494201660156,34.084716796875,64.56354522705078,23.700172424316406,48.400001525878906,17.030832290649414,929.6799926757812,141.44000244140625,2423.409912109375,6140.419921875
-2017-07-01,109.25714874267578,35.19940948486328,68.0947265625,25.520694732666016,49.388999938964844,17.911497116088867,945.5,146.49000549316406,2470.300048828125,6348.1201171875
-2017-08-01,108.01860809326172,38.81330490112305,70.03360748291016,26.852062225341797,49.029998779296875,20.882347106933594,955.239990234375,155.16000366210938,2471.64990234375,6428.66015625
-2017-08-08,,,,,,,,,,
-2017-09-01,110.72441864013672,36.6182861328125,70.14307403564453,27.700807571411133,48.067501068115234,21.517763137817383,973.719970703125,149.17999267578125,2519.360107421875,6495.9599609375
-2017-10-01,117.57792663574219,40.163211822509766,78.32596588134766,25.408233642578125,55.263999938964844,23.067289352416992,1033.0400390625,175.16000366210938,2575.260009765625,6727.669921875
-2017-11-01,117.50923919677734,40.83085632324219,79.2582015991211,24.86334991455078,58.837501525878906,21.80481719970703,1036.1700439453125,181.47000122070312,2647.580078125,6873.97021484375
-2017-11-09,,,,,,,,,,
-2017-12-01,118.25981140136719,40.3528938293457,80.95279693603516,24.43583106994629,58.4734992980957,22.65203857421875,1053.4000244140625,175.24000549316406,2673.610107421875,6903.39013671875
-2018-01-01,126.18390655517578,39.9236946105957,89.91493225097656,28.855159759521484,72.54450225830078,19.982173919677734,1182.219970703125,199.75999450683594,2823.81005859375,7411.47998046875
-2018-02-01,120.11751556396484,42.472713470458984,88.74141693115234,25.634004592895508,75.62249755859375,20.7039852142334,1103.9200439453125,209.1300048828125,2713.830078125,7273.009765625
-2018-02-08,,,,,,,,,,
-2018-03-01,119.43197631835938,40.170265197753906,86.7812271118164,24.33201026916504,72.36699676513672,20.402997970581055,1037.1400146484375,216.0800018310547,2640.8701171875,7063.4501953125
-2018-04-01,112.83880615234375,39.566917419433594,88.92057037353516,26.82056999206543,78.30650329589844,20.00168228149414,1018.5800170898438,221.60000610351562,2648.050048828125,7066.27001953125
-2018-05-01,109.99760437011719,44.7408332824707,93.97891998291016,23.179109573364258,81.48100280761719,22.479249954223633,1100.0,249.27999877929688,2705.27001953125,7442.1201171875
-2018-05-09,,,,,,,,,,
-2018-06-01,109.95153045654297,44.4903450012207,94.16664123535156,20.467208862304688,84.98999786376953,23.571720123291016,1129.18994140625,243.80999755859375,2718.3701171875,7510.2998046875
-2018-07-01,114.06781768798828,45.73533630371094,101.30004119873047,22.375450134277344,88.87200164794922,25.784528732299805,1227.219970703125,244.67999267578125,2816.2900390625,7671.7900390625
-2018-08-01,115.2877197265625,54.709842681884766,107.2684097290039,24.00385284423828,100.635498046875,26.8017520904541,1231.800048828125,263.510009765625,2901.52001953125,8109.5400390625
-2018-08-09,,,,,,,,,,
-2018-09-01,120.2962646484375,54.445865631103516,109.63678741455078,23.24565315246582,100.1500015258789,27.066509246826172,1207.0799560546875,269.95001220703125,2913.97998046875,8046.35009765625
-2018-10-01,91.83122253417969,52.78649139404297,102.38966369628906,24.236047744750977,79.90049743652344,25.190916061401367,1090.5799560546875,245.75999450683594,2711.739990234375,7305.89990234375
-2018-11-01,98.86396026611328,43.07142639160156,106.3008041381836,23.4099178314209,84.50849914550781,29.396371841430664,1109.6500244140625,250.88999938964844,2760.169921875,7330.5400390625
-2018-11-08,,,,,,,,,,
-2018-12-01,91.58279418945312,38.17780685424805,97.78714752197266,17.18350601196289,75.09850311279297,24.59708595275879,1044.9599609375,226.24000549316406,2506.85009765625,6635.27978515625
-2019-01-01,108.30086517333984,40.28346252441406,100.5406265258789,24.84735679626465,85.9365005493164,24.456159591674805,1125.8900146484375,247.82000732421875,2704.10009765625,7281.740234375
-2019-02-01,111.28997039794922,41.90748596191406,107.85758972167969,27.216707229614258,81.99150085449219,28.095136642456055,1126.550048828125,262.5,2784.489990234375,7532.52978515625
-2019-02-07,,,,,,,,,,
-2019-03-01,115.00740814208984,46.17075729370117,114.03240966796875,28.167972564697266,89.0374984741211,29.539655685424805,1176.8900146484375,266.489990234375,2834.39990234375,7729.31982421875
-2019-04-01,114.33090209960938,48.77644348144531,126.27296447753906,29.61660385131836,96.32599639892578,33.9285774230957,1198.9599609375,289.25,2945.830078125,8095.39013671875
-2019-05-01,103.50668334960938,42.55390930175781,119.58222198486328,27.175188064575195,88.75350189208984,29.972509384155273,1106.5,270.8999938964844,2752.06005859375,7453.14990234375
-2019-05-09,,,,,,,,,,
-2019-06-01,113.73433685302734,48.293270111083984,130.00108337402344,31.43656349182129,94.68150329589844,25.56848907470703,1082.800048828125,294.6499938964844,2941.760009765625,8006.240234375
-2019-07-01,122.26231384277344,51.98261260986328,132.24281311035156,28.701255798339844,93.33899688720703,29.061506271362305,1218.199951171875,298.8599853515625,2980.3798828125,8175.419921875
-2019-08-01,111.7796401977539,50.93339920043945,133.78579711914062,25.92054557800293,88.81449890136719,25.9359073638916,1190.530029296875,284.510009765625,2926.4599609375,7962.8798828125
-2019-08-08,,,,,,,,,,
-2019-09-01,121.34967803955078,54.85721969604492,135.37051391601562,26.743131637573242,86.79550170898438,26.10200309753418,1221.1400146484375,276.25,2976.739990234375,7999.33984375
-2019-10-01,111.59463500976562,60.929054260253906,139.59625244140625,30.58913803100586,88.83300018310547,26.620418548583984,1258.800048828125,277.92999267578125,3037.56005859375,8292.3603515625
-2019-11-01,112.19547271728516,65.45783996582031,147.39544677734375,35.09682083129883,90.04000091552734,24.40582847595215,1304.0899658203125,309.5299987792969,3140.97998046875,8665.4697265625
-2019-11-07,,,,,,,,,,
-2019-12-01,113.17443084716797,72.13994598388672,154.07154846191406,33.23965072631836,92.39199829101562,25.86544418334961,1339.3900146484375,329.80999755859375,3230.780029296875,8972.599609375
-2020-01-01,121.35601806640625,76.03622436523438,166.31326293945312,32.28398132324219,100.43599700927734,24.546754837036133,1432.780029296875,351.1400146484375,3225.52001953125,9150.9404296875
-2020-02-01,109.88997650146484,67.1553726196289,158.28240966796875,29.225305557250977,94.1875,20.364192962646484,1339.25,345.1199951171875,2954.219970703125,8567.3701171875
-2020-02-07,,,,,,,,,,
-2020-03-01,94.6399154663086,62.61878204345703,154.502197265625,17.190288543701172,97.48600006103516,19.90617561340332,1161.949951171875,318.239990234375,2584.590087890625,7700.10009765625
-2020-04-01,107.12150573730469,72.34808349609375,175.5648956298828,16.6003360748291,123.69999694824219,21.486589431762695,1346.699951171875,353.6400146484375,2912.429931640625,8889.5498046875
-2020-05-01,106.55841827392578,78.29256439208984,179.52272033691406,14.412978172302246,122.11849975585938,24.98464012145996,1433.52001953125,386.6000061035156,3044.31005859375,9489.8701171875
-2020-05-07,,,,,,,,,,
-2020-06-01,104.41674041748047,90.0749740600586,199.92588806152344,13.877481460571289,137.9409942626953,27.652219772338867,1418.050048828125,435.30999755859375,3100.2900390625,10058.76953125
-2020-07-01,106.29290008544922,104.9491958618164,201.3994598388672,15.366937637329102,158.23399353027344,30.11343765258789,1487.949951171875,444.32000732421875,3271.1201171875,10745.26953125
-2020-08-01,106.61280059814453,127.44819641113281,221.55807495117188,17.406635284423828,172.54800415039062,33.25917053222656,1629.530029296875,513.3900146484375,3500.31005859375,11775.4599609375
-2020-08-07,,,,,,,,,,
-2020-09-01,106.57222747802734,114.5876235961914,207.12527465820312,17.323570251464844,157.43649291992188,34.06950759887695,1465.5999755859375,490.42999267578125,3363.0,11167.509765625
-2020-10-01,97.80435180664062,107.71099090576172,199.38504028320312,16.259458541870117,151.8074951171875,30.329862594604492,1616.1099853515625,447.1000061035156,3269.9599609375,10911.58984375
-2020-11-01,108.19266510009766,117.79344177246094,210.8082733154297,20.478687286376953,158.40199279785156,34.74394989013672,1754.4000244140625,478.4700012207031,3621.6298828125,12198.740234375
-2020-11-09,,,,,,,,,,
-2020-12-01,111.85865020751953,131.51597595214844,219.60447692871094,21.694869995117188,162.84649658203125,36.88808059692383,1752.6400146484375,500.1199951171875,3756.070068359375,12888.2802734375
-2021-01-01,105.84272766113281,130.7924346923828,229.0237274169922,19.891191482543945,160.30999755859375,36.6867561340332,1827.3599853515625,458.7699890136719,3714.239990234375,13070.6904296875
-2021-02-01,105.68277740478516,120.18710327148438,229.4384002685547,24.100215911865234,154.64649963378906,40.80388259887695,2021.9100341796875,459.6700134277344,3811.14990234375,13192.349609375
-2021-02-09,,,,,,,,,,
-2021-03-01,119.9990005493164,121.25013732910156,233.32164001464844,22.955739974975586,154.70399475097656,44.367366790771484,2062.52001953125,475.3699951171875,3972.889892578125,13246.8701171875
-2021-04-01,127.76121520996094,130.49156188964844,249.56121826171875,23.070621490478516,173.37100219726562,49.49113082885742,2353.5,508.3399963378906,4181.169921875,13962.6796875
-2021-05-01,129.4361114501953,123.6920166015625,247.08718872070312,22.41118812561035,161.15350341796875,49.64715576171875,2356.85009765625,504.5799865722656,4204.10986328125,13748.740234375
-2021-05-07,,,,,,,,,,
-2021-06-01,133.47738647460938,136.1819610595703,268.70587158203125,22.44941520690918,172.00799560546875,50.16557312011719,2441.7900390625,585.6400146484375,4297.5,14503.9501953125
-2021-07-01,128.35101318359375,145.03138732910156,282.6023864746094,23.305561065673828,166.37950134277344,48.63045883178711,2694.530029296875,621.6300048828125,4395.259765625,14672.6796875
-2021-08-01,127.78646087646484,150.96749877929688,299.4349365234375,21.74091148376465,173.5395050048828,49.053245544433594,2893.949951171875,663.7000122070312,4522.68017578125,15259.240234375
-2021-08-09,,,,,,,,,,
-2021-09-01,127.95899963378906,140.906982421875,280.1719665527344,19.48086166381836,164.2519989013672,52.36507034301758,2673.52001953125,575.719970703125,4307.5400390625,14448.580078125
-2021-10-01,115.22111511230469,149.1721954345703,329.56378173828125,17.397972106933594,168.6215057373047,55.35980224609375,2960.919921875,650.3599853515625,4605.3798828125,15498.3896484375
-2021-11-01,112.8140869140625,164.60723876953125,328.5401611328125,18.003969192504883,175.35350036621094,56.077186584472656,2837.949951171875,669.8499755859375,4567.0,15537.6904296875
-2021-11-04,,,,,,,,,,
-2021-11-09,,,,,,,,,,
-2021-12-01,130.48629760742188,177.08387756347656,334.8461608886719,22.1286563873291,166.7169952392578,55.77927017211914,2897.0400390625,567.0599975585938,4766.18017578125,15644.9697265625
-2022-01-01,130.3984375,174.30149841308594,309.6171875,20.856517791748047,149.57350158691406,56.41482162475586,2706.070068359375,534.2999877929688,4515.5498046875,14239.8798828125
-2022-02-01,119.60104370117188,164.66795349121094,297.4805908203125,19.47332763671875,153.56300354003906,50.60551452636719,2701.139892578125,467.67999267578125,4373.93994140625,13751.400390625
-2022-02-10,,,,,,,,,,
-2022-03-01,128.46168518066406,174.3538360595703,307.59356689453125,19.927804946899414,162.99749755859375,49.84086990356445,2781.35009765625,455.6199951171875,4530.41015625,14220.51953125
-2022-04-01,130.6254425048828,157.418701171875,276.8751220703125,17.399999618530273,124.28150177001953,46.68299102783203,2282.18994140625,395.95001220703125,4131.93017578125,12334.6396484375
-2022-05-01,137.1759796142578,148.6216278076172,271.2382507324219,18.81999969482422,120.20950317382812,49.939998626708984,2275.239990234375,416.4800109863281,4132.14990234375,12081.3896484375
-2022-05-09,,,,,,,,,,
-2022-06-01,141.86000061035156,137.44000244140625,256.4800109863281,15.819999694824219,107.4000015258789,48.939998626708984,2240.14990234375,365.6300048828125,3821.550048828125,11181.5400390625
-2022-06-28,141.86000061035156,137.44000244140625,256.4800109863281,15.819999694824219,107.4000015258789,48.939998626708984,2240.14990234375,365.6300048828125,3821.550048828125,11181.5400390625
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/axes_grid/bivariate_normal.npy b/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/axes_grid/bivariate_normal.npy
deleted file mode 100644
index b6b8dacdd0..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/axes_grid/bivariate_normal.npy
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/data_x_x2_x3.csv b/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/data_x_x2_x3.csv
deleted file mode 100644
index 521da14532..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/data_x_x2_x3.csv
+++ /dev/null
@@ -1,11 +0,0 @@
- 0 0 0
- 1 1 1
- 2 4 8
- 3 9 27
- 4 16 64
- 5 25 125
- 6 36 216
- 7 49 343
- 8 64 512
- 9 81 729
-10 100 1000
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/eeg.dat b/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/eeg.dat
deleted file mode 100644
index c666c65053..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/eeg.dat
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/embedding_in_wx3.xrc b/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/embedding_in_wx3.xrc
deleted file mode 100644
index 220656d735..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/embedding_in_wx3.xrc
+++ /dev/null
@@ -1,65 +0,0 @@
-<?xml version="1.0" ?>
-<resource>
- <object class="wxFrame" name="MainFrame">
- <title>embedding_in_wx3</title>
- <object class="wxPanel" name="MainPanel">
- <object class="wxBoxSizer">
- <orient>wxVERTICAL</orient>
- <object class="sizeritem">
- <object class="wxStaticText">
- <label>Check out this whizz-bang stuff!</label>
- <style>wxALIGN_CENTRE</style>
- </object>
- <option>0</option>
- <flag>wxALL|wxEXPAND</flag>
- <border>5</border>
- </object>
- <object class="sizeritem">
- <object class="wxBoxSizer">
- <orient>wxHORIZONTAL</orient>
- <object class="sizeritem">
- <object class="wxButton" name="whiz_button">
- <label>whiz</label>
- </object>
- <option>0</option>
- <flag>wxALL|wxEXPAND</flag>
- <border>2</border>
- </object>
- <object class="sizeritem">
- <object class="wxButton" name="bang_button">
- <label>bang</label>
- </object>
- <option>0</option>
- <flag>wxALL|wxEXPAND</flag>
- <border>2</border>
- </object>
- <object class="sizeritem">
- <object class="wxStaticText" name="">
- <label>bang count:</label>
- <style>wxALIGN_RIGHT</style>
- </object>
- <option>1</option>
- <flag>wxALL|wxEXPAND</flag>
- <border>2</border>
- </object>
- <object class="sizeritem">
- <object class="wxTextCtrl" name="bang_count">
- <value>0</value>
- </object>
- <option>0</option>
- <flag>wxEXPAND</flag>
- </object>
- </object>
- <option>0</option>
- <flag>wxLEFT|wxRIGHT|wxEXPAND</flag>
- <border>5</border>
- </object>
- <object class="sizeritem">
- <object class="wxPanel" name="plot_container_panel"/>
- <option>1</option>
- <flag>wxEXPAND</flag>
- </object>
- </object>
- </object>
- </object>
-</resource> \ No newline at end of file
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/goog.npz b/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/goog.npz
deleted file mode 100644
index 6cbfd68ba9..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/goog.npz
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/grace_hopper.jpg b/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/grace_hopper.jpg
deleted file mode 100644
index 478720d669..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/grace_hopper.jpg
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/jacksboro_fault_dem.npz b/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/jacksboro_fault_dem.npz
deleted file mode 100644
index d25028648b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/jacksboro_fault_dem.npz
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/logo2.png b/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/logo2.png
deleted file mode 100644
index 72843ab1fe..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/logo2.png
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/membrane.dat b/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/membrane.dat
deleted file mode 100644
index 68f5e6b219..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/membrane.dat
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/msft.csv b/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/msft.csv
deleted file mode 100644
index 727b1befe3..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/msft.csv
+++ /dev/null
@@ -1,66 +0,0 @@
-Date,Open,High,Low,Close,Volume,Adj. Close*
-19-Sep-03,29.76,29.97,29.52,29.96,92433800,29.79
-18-Sep-03,28.49,29.51,28.42,29.50,67268096,29.34
-17-Sep-03,28.76,28.95,28.47,28.50,47221600,28.34
-16-Sep-03,28.41,28.95,28.32,28.90,52060600,28.74
-15-Sep-03,28.37,28.61,28.33,28.36,41432300,28.20
-12-Sep-03,27.48,28.40,27.45,28.34,55777200,28.18
-11-Sep-03,27.66,28.11,27.59,27.84,37813300,27.68
-10-Sep-03,28.03,28.18,27.48,27.55,54763500,27.40
-9-Sep-03,28.65,28.71,28.31,28.37,44315200,28.21
-8-Sep-03,28.39,28.92,28.34,28.84,46105300,28.68
-5-Sep-03,28.23,28.75,28.17,28.38,64024500,28.22
-4-Sep-03,28.10,28.47,27.99,28.43,59840800,28.27
-3-Sep-03,27.42,28.40,27.38,28.30,109437800,28.14
-2-Sep-03,26.70,27.30,26.47,27.26,74168896,27.11
-29-Aug-03,26.46,26.55,26.35,26.52,34503000,26.37
-28-Aug-03,26.50,26.58,26.24,26.51,46211200,26.36
-27-Aug-03,26.51,26.58,26.30,26.42,30633900,26.27
-26-Aug-03,26.31,26.67,25.96,26.57,47546000,26.42
-25-Aug-03,26.31,26.54,26.23,26.50,36132900,26.35
-22-Aug-03,26.78,26.95,26.21,26.22,65846300,26.07
-21-Aug-03,26.65,26.73,26.13,26.24,63802700,26.09
-20-Aug-03,26.30,26.53,26.00,26.45,56739300,26.30
-19-Aug-03,25.85,26.65,25.77,26.62,72952896,26.47
-18-Aug-03,25.56,25.83,25.46,25.70,45817400,25.56
-15-Aug-03,25.61,25.66,25.43,25.54,27607900,25.40
-14-Aug-03,25.66,25.71,25.52,25.63,37338300,25.49
-13-Aug-03,25.79,25.89,25.50,25.60,39636900,25.46
-12-Aug-03,25.71,25.77,25.45,25.73,38208400,25.59
-11-Aug-03,25.61,25.99,25.54,25.61,36433900,25.47
-8-Aug-03,25.88,25.98,25.50,25.58,33241400,25.44
-7-Aug-03,25.72,25.81,25.45,25.71,44258500,25.57
-6-Aug-03,25.54,26.19,25.43,25.65,56294900,25.51
-5-Aug-03,26.31,26.54,25.60,25.66,58825800,25.52
-4-Aug-03,26.15,26.41,25.75,26.18,51825600,26.03
-1-Aug-03,26.33,26.51,26.12,26.17,42649700,26.02
-31-Jul-03,26.60,26.99,26.31,26.41,64504800,26.26
-30-Jul-03,26.46,26.57,26.17,26.23,41240300,26.08
-29-Jul-03,26.88,26.90,26.24,26.47,62391100,26.32
-28-Jul-03,26.94,27.00,26.49,26.61,52658300,26.46
-25-Jul-03,26.28,26.95,26.07,26.89,54173000,26.74
-24-Jul-03,26.78,26.92,25.98,26.00,53556600,25.85
-23-Jul-03,26.42,26.65,26.14,26.45,49828200,26.30
-22-Jul-03,26.28,26.56,26.13,26.38,51791000,26.23
-21-Jul-03,26.87,26.91,26.00,26.04,48480800,25.89
-18-Jul-03,27.11,27.23,26.75,26.89,63388400,26.74
-17-Jul-03,27.14,27.27,26.54,26.69,72805000,26.54
-16-Jul-03,27.56,27.62,27.20,27.52,49838900,27.37
-15-Jul-03,27.47,27.53,27.10,27.27,53567600,27.12
-14-Jul-03,27.63,27.81,27.05,27.40,60464400,27.25
-11-Jul-03,26.95,27.45,26.89,27.31,50377300,27.16
-10-Jul-03,27.25,27.42,26.59,26.91,55350800,26.76
-9-Jul-03,27.56,27.70,27.25,27.47,62300700,27.32
-8-Jul-03,27.26,27.80,27.25,27.70,61896800,27.55
-7-Jul-03,27.02,27.55,26.95,27.42,88960800,27.27
-3-Jul-03,26.69,26.95,26.41,26.50,39440900,26.35
-2-Jul-03,26.50,26.93,26.45,26.88,94069296,26.73
-1-Jul-03,25.59,26.20,25.39,26.15,60926000,26.00
-30-Jun-03,25.94,26.12,25.50,25.64,48073100,25.50
-27-Jun-03,25.95,26.34,25.53,25.63,76040304,25.49
-26-Jun-03,25.39,26.51,25.21,25.75,51758100,25.61
-25-Jun-03,25.64,25.99,25.14,25.26,60483500,25.12
-24-Jun-03,25.65,26.04,25.52,25.70,51820300,25.56
-23-Jun-03,26.14,26.24,25.49,25.78,52584500,25.64
-20-Jun-03,26.34,26.38,26.01,26.33,86048896,26.18
-19-Jun-03,26.09,26.39,26.01,26.07,63626900,25.92 \ No newline at end of file
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/s1045.ima.gz b/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/s1045.ima.gz
deleted file mode 100644
index 347db4c069..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/s1045.ima.gz
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/topobathy.npz b/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/topobathy.npz
deleted file mode 100644
index 9f9b085fa2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/sample_data/topobathy.npz
+++ /dev/null
Binary files differ
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/Solarize_Light2.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/Solarize_Light2.mplstyle
deleted file mode 100644
index 4187213143..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/Solarize_Light2.mplstyle
+++ /dev/null
@@ -1,53 +0,0 @@
-# Solarized color palette taken from https://ethanschoonover.com/solarized/
-# Inspired by, and copied from ggthemes https://github.com/jrnold/ggthemes
-
-#TODO:
-# 1. Padding to title from face
-# 2. Remove top & right ticks
-# 3. Give Title a Magenta Color(?)
-
-#base00 ='#657b83'
-#base01 ='#93a1a1'
-#base2 ='#eee8d5'
-#base3 ='#fdf6e3'
-#base01 ='#586e75'
-#Magenta ='#d33682'
-#Blue ='#268bd2'
-#cyan ='#2aa198'
-#violet ='#6c71c4'
-#green ='#859900'
-#orange ='#cb4b16'
-
-figure.facecolor : FDF6E3
-
-patch.antialiased : True
-
-lines.linewidth : 2.0
-lines.solid_capstyle: butt
-
-axes.titlesize : 16
-axes.labelsize : 12
-axes.labelcolor : 657b83
-axes.facecolor : eee8d5
-axes.edgecolor : eee8d5
-axes.axisbelow : True
-axes.prop_cycle : cycler('color', ['268BD2', '2AA198', '859900', 'B58900', 'CB4B16', 'DC322F', 'D33682', '6C71C4'])
-# Blue
-# Cyan
-# Green
-# Yellow
-# Orange
-# Red
-# Magenta
-# Violet
-axes.grid : True
-grid.color : fdf6e3 # grid color
-grid.linestyle : - # line
-grid.linewidth : 1 # in points
-
-### TICKS
-xtick.color : 657b83
-xtick.direction : out
-
-ytick.color : 657b83
-ytick.direction : out
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/_classic_test_patch.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/_classic_test_patch.mplstyle
deleted file mode 100644
index 96f62f4ba5..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/_classic_test_patch.mplstyle
+++ /dev/null
@@ -1,6 +0,0 @@
-# This patch should go on top of the "classic" style and exists solely to avoid
-# changing baseline images.
-
-text.kerning_factor : 6
-
-ytick.alignment: center_baseline
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/_mpl-gallery-nogrid.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/_mpl-gallery-nogrid.mplstyle
deleted file mode 100644
index 911658fe88..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/_mpl-gallery-nogrid.mplstyle
+++ /dev/null
@@ -1,19 +0,0 @@
-# This style is used for the plot_types gallery. It is considered private.
-
-axes.grid: False
-axes.axisbelow: True
-
-figure.figsize: 2, 2
-# make it so the axes labels don't show up. Obviously
-# not good style for any quantitative analysis:
-figure.subplot.left: 0.01
-figure.subplot.right: 0.99
-figure.subplot.bottom: 0.01
-figure.subplot.top: 0.99
-
-xtick.major.size: 0.0
-ytick.major.size: 0.0
-
-# colors:
-image.cmap : Blues
-axes.prop_cycle: cycler('color', ['1f77b4', '82bbdb', 'ccdff1'])
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/_mpl-gallery.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/_mpl-gallery.mplstyle
deleted file mode 100644
index 75c95bf16a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/_mpl-gallery.mplstyle
+++ /dev/null
@@ -1,19 +0,0 @@
-# This style is used for the plot_types gallery. It is considered part of the private API.
-
-axes.grid: True
-axes.axisbelow: True
-
-figure.figsize: 2, 2
-# make it so the axes labels don't show up. Obviously
-# not good style for any quantitative analysis:
-figure.subplot.left: 0.01
-figure.subplot.right: 0.99
-figure.subplot.bottom: 0.01
-figure.subplot.top: 0.99
-
-xtick.major.size: 0.0
-ytick.major.size: 0.0
-
-# colors:
-image.cmap : Blues
-axes.prop_cycle: cycler('color', ['1f77b4', '58a1cf', 'abd0e6'])
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/bmh.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/bmh.mplstyle
deleted file mode 100644
index 1b449cc09f..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/bmh.mplstyle
+++ /dev/null
@@ -1,29 +0,0 @@
-#Author: Cameron Davidson-Pilon, original styles from Bayesian Methods for Hackers
-# https://github.com/CamDavidsonPilon/Probabilistic-Programming-and-Bayesian-Methods-for-Hackers/
-
-lines.linewidth : 2.0
-
-patch.linewidth: 0.5
-patch.facecolor: blue
-patch.edgecolor: eeeeee
-patch.antialiased: True
-
-text.hinting_factor : 8
-
-mathtext.fontset : cm
-
-axes.facecolor: eeeeee
-axes.edgecolor: bcbcbc
-axes.grid : True
-axes.titlesize: x-large
-axes.labelsize: large
-axes.prop_cycle: cycler('color', ['348ABD', 'A60628', '7A68A6', '467821', 'D55E00', 'CC79A7', '56B4E9', '009E73', 'F0E442', '0072B2'])
-
-grid.color: b2b2b2
-grid.linestyle: --
-grid.linewidth: 0.5
-
-legend.fancybox: True
-
-xtick.direction: in
-ytick.direction: in
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/classic.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/classic.mplstyle
deleted file mode 100644
index e1768e5a61..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/classic.mplstyle
+++ /dev/null
@@ -1,492 +0,0 @@
-### Classic matplotlib plotting style as of v1.5
-
-
-### LINES
-# See https://matplotlib.org/api/artist_api.html#module-matplotlib.lines for more
-# information on line properties.
-lines.linewidth : 1.0 # line width in points
-lines.linestyle : - # solid line
-lines.color : b # has no affect on plot(); see axes.prop_cycle
-lines.marker : None # the default marker
-lines.markerfacecolor : auto # the default markerfacecolor
-lines.markeredgecolor : auto # the default markeredgecolor
-lines.markeredgewidth : 0.5 # the line width around the marker symbol
-lines.markersize : 6 # markersize, in points
-lines.dash_joinstyle : round # miter|round|bevel
-lines.dash_capstyle : butt # butt|round|projecting
-lines.solid_joinstyle : round # miter|round|bevel
-lines.solid_capstyle : projecting # butt|round|projecting
-lines.antialiased : True # render lines in antialiased (no jaggies)
-lines.dashed_pattern : 6, 6
-lines.dashdot_pattern : 3, 5, 1, 5
-lines.dotted_pattern : 1, 3
-lines.scale_dashes: False
-
-### Marker props
-markers.fillstyle: full
-
-### PATCHES
-# Patches are graphical objects that fill 2D space, like polygons or
-# circles. See
-# https://matplotlib.org/api/artist_api.html#module-matplotlib.patches
-# information on patch properties
-patch.linewidth : 1.0 # edge width in points
-patch.facecolor : b
-patch.force_edgecolor : True
-patch.edgecolor : k
-patch.antialiased : True # render patches in antialiased (no jaggies)
-
-hatch.color : k
-hatch.linewidth : 1.0
-
-hist.bins : 10
-
-### FONT
-#
-# font properties used by text.Text. See
-# https://matplotlib.org/api/font_manager_api.html for more
-# information on font properties. The 6 font properties used for font
-# matching are given below with their default values.
-#
-# The font.family property has five values: 'serif' (e.g., Times),
-# 'sans-serif' (e.g., Helvetica), 'cursive' (e.g., Zapf-Chancery),
-# 'fantasy' (e.g., Western), and 'monospace' (e.g., Courier). Each of
-# these font families has a default list of font names in decreasing
-# order of priority associated with them. When text.usetex is False,
-# font.family may also be one or more concrete font names.
-#
-# The font.style property has three values: normal (or roman), italic
-# or oblique. The oblique style will be used for italic, if it is not
-# present.
-#
-# The font.variant property has two values: normal or small-caps. For
-# TrueType fonts, which are scalable fonts, small-caps is equivalent
-# to using a font size of 'smaller', or about 83% of the current font
-# size.
-#
-# The font.weight property has effectively 13 values: normal, bold,
-# bolder, lighter, 100, 200, 300, ..., 900. Normal is the same as
-# 400, and bold is 700. bolder and lighter are relative values with
-# respect to the current weight.
-#
-# The font.stretch property has 11 values: ultra-condensed,
-# extra-condensed, condensed, semi-condensed, normal, semi-expanded,
-# expanded, extra-expanded, ultra-expanded, wider, and narrower. This
-# property is not currently implemented.
-#
-# The font.size property is the default font size for text, given in pts.
-# 12pt is the standard value.
-#
-font.family : sans-serif
-font.style : normal
-font.variant : normal
-font.weight : normal
-font.stretch : normal
-# note that font.size controls default text sizes. To configure
-# special text sizes tick labels, axes, labels, title, etc, see the rc
-# settings for axes and ticks. Special text sizes can be defined
-# relative to font.size, using the following values: xx-small, x-small,
-# small, medium, large, x-large, xx-large, larger, or smaller
-font.size : 12.0
-font.serif : DejaVu Serif, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif
-font.sans-serif: DejaVu Sans, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
-font.cursive : Apple Chancery, Textile, Zapf Chancery, Sand, Script MT, Felipa, cursive
-font.fantasy : Comic Sans MS, Chicago, Charcoal, ImpactWestern, xkcd script, fantasy
-font.monospace : DejaVu Sans Mono, Andale Mono, Nimbus Mono L, Courier New, Courier, Fixed, Terminal, monospace
-
-### TEXT
-# text properties used by text.Text. See
-# https://matplotlib.org/api/artist_api.html#module-matplotlib.text for more
-# information on text properties
-
-text.color : k
-
-### LaTeX customizations. See http://www.scipy.org/Wiki/Cookbook/Matplotlib/UsingTex
-text.usetex : False # use latex for all text handling. The following fonts
- # are supported through the usual rc parameter settings:
- # new century schoolbook, bookman, times, palatino,
- # zapf chancery, charter, serif, sans-serif, helvetica,
- # avant garde, courier, monospace, computer modern roman,
- # computer modern sans serif, computer modern typewriter
- # If another font is desired which can loaded using the
- # LaTeX \usepackage command, please inquire at the
- # matplotlib mailing list
-text.latex.preamble : # IMPROPER USE OF THIS FEATURE WILL LEAD TO LATEX FAILURES
- # AND IS THEREFORE UNSUPPORTED. PLEASE DO NOT ASK FOR HELP
- # IF THIS FEATURE DOES NOT DO WHAT YOU EXPECT IT TO.
- # text.latex.preamble is a single line of LaTeX code that
- # will be passed on to the LaTeX system. It may contain
- # any code that is valid for the LaTeX "preamble", i.e.
- # between the "\documentclass" and "\begin{document}"
- # statements.
- # Note that it has to be put on a single line, which may
- # become quite long.
- # The following packages are always loaded with usetex, so
- # beware of package collisions: color, geometry, graphicx,
- # type1cm, textcomp.
- # Adobe Postscript (PSSNFS) font packages may also be
- # loaded, depending on your font settings.
-
-text.hinting : auto # May be one of the following:
- # 'none': Perform no hinting
- # 'auto': Use freetype's autohinter
- # 'native': Use the hinting information in the
- # font file, if available, and if your
- # freetype library supports it
- # 'either': Use the native hinting information,
- # or the autohinter if none is available.
- # For backward compatibility, this value may also be
- # True === 'auto' or False === 'none'.
-text.hinting_factor : 8 # Specifies the amount of softness for hinting in the
- # horizontal direction. A value of 1 will hint to full
- # pixels. A value of 2 will hint to half pixels etc.
-
-text.antialiased : True # If True (default), the text will be antialiased.
- # This only affects the Agg backend.
-
-# The following settings allow you to select the fonts in math mode.
-# They map from a TeX font name to a fontconfig font pattern.
-# These settings are only used if mathtext.fontset is 'custom'.
-# Note that this "custom" mode is unsupported and may go away in the
-# future.
-mathtext.cal : cursive
-mathtext.rm : serif
-mathtext.tt : monospace
-mathtext.it : serif:italic
-mathtext.bf : serif:bold
-mathtext.sf : sans\-serif
-mathtext.fontset : cm # Should be 'cm' (Computer Modern), 'stix',
- # 'stixsans' or 'custom'
-mathtext.fallback: cm # Select fallback font from ['cm' (Computer Modern), 'stix'
- # 'stixsans'] when a symbol cannot be found in one of the
- # custom math fonts. Select 'None' to not perform fallback
- # and replace the missing character by a dummy.
-
-mathtext.default : it # The default font to use for math.
- # Can be any of the LaTeX font names, including
- # the special name "regular" for the same font
- # used in regular text.
-
-### AXES
-# default face and edge color, default tick sizes,
-# default fontsizes for ticklabels, and so on. See
-# https://matplotlib.org/api/axes_api.html#module-matplotlib.axes
-axes.facecolor : w # axes background color
-axes.edgecolor : k # axes edge color
-axes.linewidth : 1.0 # edge linewidth
-axes.grid : False # display grid or not
-axes.grid.which : major
-axes.grid.axis : both
-axes.titlesize : large # fontsize of the axes title
-axes.titley : 1.0 # at the top, no autopositioning.
-axes.titlepad : 5.0 # pad between axes and title in points
-axes.titleweight : normal # font weight for axes title
-axes.labelsize : medium # fontsize of the x any y labels
-axes.labelpad : 5.0 # space between label and axis
-axes.labelweight : normal # weight of the x and y labels
-axes.labelcolor : k
-axes.axisbelow : False # whether axis gridlines and ticks are below
- # the axes elements (lines, text, etc)
-
-axes.formatter.limits : -7, 7 # use scientific notation if log10
- # of the axis range is smaller than the
- # first or larger than the second
-axes.formatter.use_locale : False # When True, format tick labels
- # according to the user's locale.
- # For example, use ',' as a decimal
- # separator in the fr_FR locale.
-axes.formatter.use_mathtext : False # When True, use mathtext for scientific
- # notation.
-axes.formatter.useoffset : True # If True, the tick label formatter
- # will default to labeling ticks relative
- # to an offset when the data range is very
- # small compared to the minimum absolute
- # value of the data.
-axes.formatter.offset_threshold : 2 # When useoffset is True, the offset
- # will be used when it can remove
- # at least this number of significant
- # digits from tick labels.
-
-axes.unicode_minus : True # use Unicode for the minus symbol
- # rather than hyphen. See
- # https://en.wikipedia.org/wiki/Plus_and_minus_signs#Character_codes
-axes.prop_cycle : cycler('color', 'bgrcmyk')
- # color cycle for plot lines
- # as list of string colorspecs:
- # single letter, long name, or
- # web-style hex
-axes.autolimit_mode : round_numbers
-axes.xmargin : 0 # x margin. See `axes.Axes.margins`
-axes.ymargin : 0 # y margin See `axes.Axes.margins`
-axes.spines.bottom : True
-axes.spines.left : True
-axes.spines.right : True
-axes.spines.top : True
-polaraxes.grid : True # display grid on polar axes
-axes3d.grid : True # display grid on 3d axes
-
-date.autoformatter.year : %Y
-date.autoformatter.month : %b %Y
-date.autoformatter.day : %b %d %Y
-date.autoformatter.hour : %H:%M:%S
-date.autoformatter.minute : %H:%M:%S.%f
-date.autoformatter.second : %H:%M:%S.%f
-date.autoformatter.microsecond : %H:%M:%S.%f
-date.converter: auto # 'auto', 'concise'
-
-### TICKS
-# see https://matplotlib.org/api/axis_api.html#matplotlib.axis.Tick
-
-xtick.top : True # draw ticks on the top side
-xtick.bottom : True # draw ticks on the bottom side
-xtick.major.size : 4 # major tick size in points
-xtick.minor.size : 2 # minor tick size in points
-xtick.minor.visible : False
-xtick.major.width : 0.5 # major tick width in points
-xtick.minor.width : 0.5 # minor tick width in points
-xtick.major.pad : 4 # distance to major tick label in points
-xtick.minor.pad : 4 # distance to the minor tick label in points
-xtick.color : k # color of the tick labels
-xtick.labelsize : medium # fontsize of the tick labels
-xtick.direction : in # direction: in, out, or inout
-xtick.major.top : True # draw x axis top major ticks
-xtick.major.bottom : True # draw x axis bottom major ticks
-xtick.minor.top : True # draw x axis top minor ticks
-xtick.minor.bottom : True # draw x axis bottom minor ticks
-xtick.alignment : center
-
-ytick.left : True # draw ticks on the left side
-ytick.right : True # draw ticks on the right side
-ytick.major.size : 4 # major tick size in points
-ytick.minor.size : 2 # minor tick size in points
-ytick.minor.visible : False
-ytick.major.width : 0.5 # major tick width in points
-ytick.minor.width : 0.5 # minor tick width in points
-ytick.major.pad : 4 # distance to major tick label in points
-ytick.minor.pad : 4 # distance to the minor tick label in points
-ytick.color : k # color of the tick labels
-ytick.labelsize : medium # fontsize of the tick labels
-ytick.direction : in # direction: in, out, or inout
-ytick.major.left : True # draw y axis left major ticks
-ytick.major.right : True # draw y axis right major ticks
-ytick.minor.left : True # draw y axis left minor ticks
-ytick.minor.right : True # draw y axis right minor ticks
-ytick.alignment : center
-
-### GRIDS
-grid.color : k # grid color
-grid.linestyle : : # dotted
-grid.linewidth : 0.5 # in points
-grid.alpha : 1.0 # transparency, between 0.0 and 1.0
-
-### Legend
-legend.fancybox : False # if True, use a rounded box for the
- # legend, else a rectangle
-legend.loc : upper right
-legend.numpoints : 2 # the number of points in the legend line
-legend.fontsize : large
-legend.borderpad : 0.4 # border whitespace in fontsize units
-legend.markerscale : 1.0 # the relative size of legend markers vs. original
-# the following dimensions are in axes coords
-legend.labelspacing : 0.5 # the vertical space between the legend entries in fraction of fontsize
-legend.handlelength : 2. # the length of the legend lines in fraction of fontsize
-legend.handleheight : 0.7 # the height of the legend handle in fraction of fontsize
-legend.handletextpad : 0.8 # the space between the legend line and legend text in fraction of fontsize
-legend.borderaxespad : 0.5 # the border between the axes and legend edge in fraction of fontsize
-legend.columnspacing : 2. # the border between the axes and legend edge in fraction of fontsize
-legend.shadow : False
-legend.frameon : True # whether or not to draw a frame around legend
-legend.framealpha : None # opacity of legend frame
-legend.scatterpoints : 3 # number of scatter points
-legend.facecolor : inherit # legend background color (when 'inherit' uses axes.facecolor)
-legend.edgecolor : inherit # legend edge color (when 'inherit' uses axes.edgecolor)
-
-
-
-### FIGURE
-# See https://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure
-figure.titlesize : medium # size of the figure title
-figure.titleweight : normal # weight of the figure title
-figure.labelsize: medium # size of the figure label
-figure.labelweight: normal # weight of the figure label
-figure.figsize : 8, 6 # figure size in inches
-figure.dpi : 80 # figure dots per inch
-figure.facecolor : 0.75 # figure facecolor; 0.75 is scalar gray
-figure.edgecolor : w # figure edgecolor
-figure.autolayout : False # When True, automatically adjust subplot
- # parameters to make the plot fit the figure
-figure.frameon : True
-
-# The figure subplot parameters. All dimensions are a fraction of the
-# figure width or height
-figure.subplot.left : 0.125 # the left side of the subplots of the figure
-figure.subplot.right : 0.9 # the right side of the subplots of the figure
-figure.subplot.bottom : 0.1 # the bottom of the subplots of the figure
-figure.subplot.top : 0.9 # the top of the subplots of the figure
-figure.subplot.wspace : 0.2 # the amount of width reserved for space between subplots,
- # expressed as a fraction of the average axis width
-figure.subplot.hspace : 0.2 # the amount of height reserved for space between subplots,
- # expressed as a fraction of the average axis height
-
-### IMAGES
-image.aspect : equal # equal | auto | a number
-image.interpolation : bilinear # see help(imshow) for options
-image.cmap : jet # gray | jet | ...
-image.lut : 256 # the size of the colormap lookup table
-image.origin : upper # lower | upper
-image.resample : False
-image.composite_image : True
-
-### CONTOUR PLOTS
-contour.negative_linestyle : dashed # dashed | solid
-contour.corner_mask : True
-
-# errorbar props
-errorbar.capsize: 3
-
-# scatter props
-scatter.marker: o
-
-### Boxplots
-boxplot.bootstrap: None
-boxplot.boxprops.color: b
-boxplot.boxprops.linestyle: -
-boxplot.boxprops.linewidth: 1.0
-boxplot.capprops.color: k
-boxplot.capprops.linestyle: -
-boxplot.capprops.linewidth: 1.0
-boxplot.flierprops.color: b
-boxplot.flierprops.linestyle: none
-boxplot.flierprops.linewidth: 1.0
-boxplot.flierprops.marker: +
-boxplot.flierprops.markeredgecolor: k
-boxplot.flierprops.markerfacecolor: auto
-boxplot.flierprops.markersize: 6.0
-boxplot.meanline: False
-boxplot.meanprops.color: r
-boxplot.meanprops.linestyle: -
-boxplot.meanprops.linewidth: 1.0
-boxplot.medianprops.color: r
-boxplot.meanprops.marker: s
-boxplot.meanprops.markerfacecolor: r
-boxplot.meanprops.markeredgecolor: k
-boxplot.meanprops.markersize: 6.0
-boxplot.medianprops.linestyle: -
-boxplot.medianprops.linewidth: 1.0
-boxplot.notch: False
-boxplot.patchartist: False
-boxplot.showbox: True
-boxplot.showcaps: True
-boxplot.showfliers: True
-boxplot.showmeans: False
-boxplot.vertical: True
-boxplot.whiskerprops.color: b
-boxplot.whiskerprops.linestyle: --
-boxplot.whiskerprops.linewidth: 1.0
-boxplot.whiskers: 1.5
-
-### Agg rendering
-### Warning: experimental, 2008/10/10
-agg.path.chunksize : 0 # 0 to disable; values in the range
- # 10000 to 100000 can improve speed slightly
- # and prevent an Agg rendering failure
- # when plotting very large data sets,
- # especially if they are very gappy.
- # It may cause minor artifacts, though.
- # A value of 20000 is probably a good
- # starting point.
-### SAVING FIGURES
-path.simplify : True # When True, simplify paths by removing "invisible"
- # points to reduce file size and increase rendering
- # speed
-path.simplify_threshold : 0.1111111111111111
- # The threshold of similarity below which
- # vertices will be removed in the simplification
- # process
-path.snap : True # When True, rectilinear axis-aligned paths will be snapped to
- # the nearest pixel when certain criteria are met. When False,
- # paths will never be snapped.
-path.sketch : None # May be none, or a 3-tuple of the form (scale, length,
- # randomness).
- # *scale* is the amplitude of the wiggle
- # perpendicular to the line (in pixels). *length*
- # is the length of the wiggle along the line (in
- # pixels). *randomness* is the factor by which
- # the length is randomly scaled.
-
-# the default savefig params can be different from the display params
-# e.g., you may want a higher resolution, or to make the figure
-# background white
-savefig.dpi : 100 # figure dots per inch
-savefig.facecolor : w # figure facecolor when saving
-savefig.edgecolor : w # figure edgecolor when saving
-savefig.format : png # png, ps, pdf, svg
-savefig.bbox : standard # 'tight' or 'standard'.
- # 'tight' is incompatible with pipe-based animation
- # backends (e.g. 'ffmpeg') but will work with those
- # based on temporary files (e.g. 'ffmpeg_file')
-savefig.pad_inches : 0.1 # Padding to be used when bbox is set to 'tight'
-savefig.transparent : False # setting that controls whether figures are saved with a
- # transparent background by default
-savefig.orientation : portrait
-
-# ps backend params
-ps.papersize : letter # auto, letter, legal, ledger, A0-A10, B0-B10
-ps.useafm : False # use of afm fonts, results in small files
-ps.usedistiller : False # can be: None, ghostscript or xpdf
- # Experimental: may produce smaller files.
- # xpdf intended for production of publication quality files,
- # but requires ghostscript, xpdf and ps2eps
-ps.distiller.res : 6000 # dpi
-ps.fonttype : 3 # Output Type 3 (Type3) or Type 42 (TrueType)
-
-# pdf backend params
-pdf.compression : 6 # integer from 0 to 9
- # 0 disables compression (good for debugging)
-pdf.fonttype : 3 # Output Type 3 (Type3) or Type 42 (TrueType)
-pdf.inheritcolor : False
-pdf.use14corefonts : False
-
-# pgf backend params
-pgf.texsystem : xelatex
-pgf.rcfonts : True
-pgf.preamble :
-
-# svg backend params
-svg.image_inline : True # write raster image data directly into the svg file
-svg.fonttype : path # How to handle SVG fonts:
-# 'none': Assume fonts are installed on the machine where the SVG will be viewed.
-# 'path': Embed characters as paths -- supported by most SVG renderers
-
-# Event keys to interact with figures/plots via keyboard.
-# Customize these settings according to your needs.
-# Leave the field(s) empty if you don't need a key-map. (i.e., fullscreen : '')
-
-keymap.fullscreen : f, ctrl+f # toggling
-keymap.home : h, r, home # home or reset mnemonic
-keymap.back : left, c, backspace # forward / backward keys to enable
-keymap.forward : right, v # left handed quick navigation
-keymap.pan : p # pan mnemonic
-keymap.zoom : o # zoom mnemonic
-keymap.save : s, ctrl+s # saving current figure
-keymap.quit : ctrl+w, cmd+w # close the current figure
-keymap.grid : g # switching on/off a grid in current axes
-keymap.yscale : l # toggle scaling of y-axes ('log'/'linear')
-keymap.xscale : k, L # toggle scaling of x-axes ('log'/'linear')
-
-###ANIMATION settings
-animation.writer : ffmpeg # MovieWriter 'backend' to use
-animation.codec : mpeg4 # Codec to use for writing movie
-animation.bitrate: -1 # Controls size/quality tradeoff for movie.
- # -1 implies let utility auto-determine
-animation.frame_format: png # Controls frame format used by temp files
-animation.ffmpeg_path: ffmpeg # Path to ffmpeg binary. Without full path
- # $PATH is searched
-animation.ffmpeg_args: # Additional arguments to pass to ffmpeg
-animation.convert_path: convert # Path to ImageMagick's convert binary.
- # On Windows use the full path since convert
- # is also the name of a system tool.
-animation.convert_args:
-animation.html: none
-
-_internal.classic_mode: True
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/dark_background.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/dark_background.mplstyle
deleted file mode 100644
index c4b7741ae4..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/dark_background.mplstyle
+++ /dev/null
@@ -1,29 +0,0 @@
-# Set black background default line colors to white.
-
-lines.color: white
-patch.edgecolor: white
-
-text.color: white
-
-axes.facecolor: black
-axes.edgecolor: white
-axes.labelcolor: white
-axes.prop_cycle: cycler('color', ['8dd3c7', 'feffb3', 'bfbbd9', 'fa8174', '81b1d2', 'fdb462', 'b3de69', 'bc82bd', 'ccebc4', 'ffed6f'])
-
-xtick.color: white
-ytick.color: white
-
-grid.color: white
-
-figure.facecolor: black
-figure.edgecolor: black
-
-savefig.facecolor: black
-savefig.edgecolor: black
-
-### Boxplots
-boxplot.boxprops.color: white
-boxplot.capprops.color: white
-boxplot.flierprops.color: white
-boxplot.flierprops.markeredgecolor: white
-boxplot.whiskerprops.color: white
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/fast.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/fast.mplstyle
deleted file mode 100644
index 1f7be7d463..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/fast.mplstyle
+++ /dev/null
@@ -1,11 +0,0 @@
-# a small set of changes that will make your plotting FAST (1).
-#
-# (1) in some cases
-
-# Maximally simplify lines.
-path.simplify: True
-path.simplify_threshold: 1.0
-
-# chunk up large lines into smaller lines!
-# simple trick to avoid those pesky O(>n) algorithms!
-agg.path.chunksize: 10000
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/fivethirtyeight.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/fivethirtyeight.mplstyle
deleted file mode 100644
index 738db39f5f..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/fivethirtyeight.mplstyle
+++ /dev/null
@@ -1,40 +0,0 @@
-#Author: Cameron Davidson-Pilon, replicated styles from FiveThirtyEight.com
-# See https://www.dataorigami.net/blogs/fivethirtyeight-mpl
-
-lines.linewidth: 4
-lines.solid_capstyle: butt
-
-legend.fancybox: true
-
-axes.prop_cycle: cycler('color', ['008fd5', 'fc4f30', 'e5ae38', '6d904f', '8b8b8b', '810f7c'])
-axes.facecolor: f0f0f0
-axes.labelsize: large
-axes.axisbelow: true
-axes.grid: true
-axes.edgecolor: f0f0f0
-axes.linewidth: 3.0
-axes.titlesize: x-large
-
-patch.edgecolor: f0f0f0
-patch.linewidth: 0.5
-
-svg.fonttype: path
-
-grid.linestyle: -
-grid.linewidth: 1.0
-grid.color: cbcbcb
-
-xtick.major.size: 0
-xtick.minor.size: 0
-ytick.major.size: 0
-ytick.minor.size: 0
-
-font.size:14.0
-
-savefig.edgecolor: f0f0f0
-savefig.facecolor: f0f0f0
-
-figure.subplot.left: 0.08
-figure.subplot.right: 0.95
-figure.subplot.bottom: 0.07
-figure.facecolor: f0f0f0
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/ggplot.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/ggplot.mplstyle
deleted file mode 100644
index d1b3ba2e33..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/ggplot.mplstyle
+++ /dev/null
@@ -1,39 +0,0 @@
-# from https://everyhue.me/posts/sane-color-scheme-for-matplotlib/
-
-patch.linewidth: 0.5
-patch.facecolor: 348ABD # blue
-patch.edgecolor: EEEEEE
-patch.antialiased: True
-
-font.size: 10.0
-
-axes.facecolor: E5E5E5
-axes.edgecolor: white
-axes.linewidth: 1
-axes.grid: True
-axes.titlesize: x-large
-axes.labelsize: large
-axes.labelcolor: 555555
-axes.axisbelow: True # grid/ticks are below elements (e.g., lines, text)
-
-axes.prop_cycle: cycler('color', ['E24A33', '348ABD', '988ED5', '777777', 'FBC15E', '8EBA42', 'FFB5B8'])
- # E24A33 : red
- # 348ABD : blue
- # 988ED5 : purple
- # 777777 : gray
- # FBC15E : yellow
- # 8EBA42 : green
- # FFB5B8 : pink
-
-xtick.color: 555555
-xtick.direction: out
-
-ytick.color: 555555
-ytick.direction: out
-
-grid.color: white
-grid.linestyle: - # solid line
-
-figure.facecolor: white
-figure.edgecolor: 0.50
-
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/grayscale.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/grayscale.mplstyle
deleted file mode 100644
index 6a1114e406..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/grayscale.mplstyle
+++ /dev/null
@@ -1,29 +0,0 @@
-# Set all colors to grayscale
-# Note: strings of float values are interpreted by matplotlib as gray values.
-
-
-lines.color: black
-patch.facecolor: gray
-patch.edgecolor: black
-
-text.color: black
-
-axes.facecolor: white
-axes.edgecolor: black
-axes.labelcolor: black
-# black to light gray
-axes.prop_cycle: cycler('color', ['0.00', '0.40', '0.60', '0.70'])
-
-xtick.color: black
-ytick.color: black
-
-grid.color: black
-
-figure.facecolor: 0.75
-figure.edgecolor: white
-
-image.cmap: gray
-
-savefig.facecolor: white
-savefig.edgecolor: white
-
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-bright.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-bright.mplstyle
deleted file mode 100644
index 5e9e949378..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-bright.mplstyle
+++ /dev/null
@@ -1,3 +0,0 @@
-# Seaborn bright palette
-axes.prop_cycle: cycler('color', ['003FFF', '03ED3A', 'E8000B', '8A2BE2', 'FFC400', '00D7FF'])
-patch.facecolor: 003FFF
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-colorblind.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-colorblind.mplstyle
deleted file mode 100644
index e13b7aade3..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-colorblind.mplstyle
+++ /dev/null
@@ -1,3 +0,0 @@
-# Seaborn colorblind palette
-axes.prop_cycle: cycler('color', ['0072B2', '009E73', 'D55E00', 'CC79A7', 'F0E442', '56B4E9'])
-patch.facecolor: 0072B2
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-dark-palette.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-dark-palette.mplstyle
deleted file mode 100644
index 30160ae250..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-dark-palette.mplstyle
+++ /dev/null
@@ -1,3 +0,0 @@
-# Seaborn dark palette
-axes.prop_cycle: cycler('color', ['001C7F', '017517', '8C0900', '7600A1', 'B8860B', '006374'])
-patch.facecolor: 001C7F
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-dark.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-dark.mplstyle
deleted file mode 100644
index 55b50b5bdd..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-dark.mplstyle
+++ /dev/null
@@ -1,30 +0,0 @@
-# Seaborn common parameters
-# .15 = dark_gray
-# .8 = light_gray
-figure.facecolor: white
-text.color: .15
-axes.labelcolor: .15
-legend.frameon: False
-legend.numpoints: 1
-legend.scatterpoints: 1
-xtick.direction: out
-ytick.direction: out
-xtick.color: .15
-ytick.color: .15
-axes.axisbelow: True
-image.cmap: Greys
-font.family: sans-serif
-font.sans-serif: Arial, Liberation Sans, DejaVu Sans, Bitstream Vera Sans, sans-serif
-grid.linestyle: -
-lines.solid_capstyle: round
-
-# Seaborn dark parameters
-axes.grid: False
-axes.facecolor: EAEAF2
-axes.edgecolor: white
-axes.linewidth: 0
-grid.color: white
-xtick.major.size: 0
-ytick.major.size: 0
-xtick.minor.size: 0
-ytick.minor.size: 0
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-darkgrid.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-darkgrid.mplstyle
deleted file mode 100644
index 0f5d955d7d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-darkgrid.mplstyle
+++ /dev/null
@@ -1,30 +0,0 @@
-# Seaborn common parameters
-# .15 = dark_gray
-# .8 = light_gray
-figure.facecolor: white
-text.color: .15
-axes.labelcolor: .15
-legend.frameon: False
-legend.numpoints: 1
-legend.scatterpoints: 1
-xtick.direction: out
-ytick.direction: out
-xtick.color: .15
-ytick.color: .15
-axes.axisbelow: True
-image.cmap: Greys
-font.family: sans-serif
-font.sans-serif: Arial, Liberation Sans, DejaVu Sans, Bitstream Vera Sans, sans-serif
-grid.linestyle: -
-lines.solid_capstyle: round
-
-# Seaborn darkgrid parameters
-axes.grid: True
-axes.facecolor: EAEAF2
-axes.edgecolor: white
-axes.linewidth: 0
-grid.color: white
-xtick.major.size: 0
-ytick.major.size: 0
-xtick.minor.size: 0
-ytick.minor.size: 0
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-deep.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-deep.mplstyle
deleted file mode 100644
index 5d6b7c5600..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-deep.mplstyle
+++ /dev/null
@@ -1,3 +0,0 @@
-# Seaborn deep palette
-axes.prop_cycle: cycler('color', ['4C72B0', '55A868', 'C44E52', '8172B2', 'CCB974', '64B5CD'])
-patch.facecolor: 4C72B0
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-muted.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-muted.mplstyle
deleted file mode 100644
index 4a71646ce9..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-muted.mplstyle
+++ /dev/null
@@ -1,3 +0,0 @@
-# Seaborn muted palette
-axes.prop_cycle: cycler('color', ['4878CF', '6ACC65', 'D65F5F', 'B47CC7', 'C4AD66', '77BEDB'])
-patch.facecolor: 4878CF
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-notebook.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-notebook.mplstyle
deleted file mode 100644
index 18bcf3e120..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-notebook.mplstyle
+++ /dev/null
@@ -1,21 +0,0 @@
-# Seaborn notebook context
-figure.figsize: 8.0, 5.5
-axes.labelsize: 11
-axes.titlesize: 12
-xtick.labelsize: 10
-ytick.labelsize: 10
-legend.fontsize: 10
-
-grid.linewidth: 1
-lines.linewidth: 1.75
-patch.linewidth: .3
-lines.markersize: 7
-lines.markeredgewidth: 0
-
-xtick.major.width: 1
-ytick.major.width: 1
-xtick.minor.width: .5
-ytick.minor.width: .5
-
-xtick.major.pad: 7
-ytick.major.pad: 7
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-paper.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-paper.mplstyle
deleted file mode 100644
index 3326be4333..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-paper.mplstyle
+++ /dev/null
@@ -1,21 +0,0 @@
-# Seaborn paper context
-figure.figsize: 6.4, 4.4
-axes.labelsize: 8.8
-axes.titlesize: 9.6
-xtick.labelsize: 8
-ytick.labelsize: 8
-legend.fontsize: 8
-
-grid.linewidth: 0.8
-lines.linewidth: 1.4
-patch.linewidth: 0.24
-lines.markersize: 5.6
-lines.markeredgewidth: 0
-
-xtick.major.width: 0.8
-ytick.major.width: 0.8
-xtick.minor.width: 0.4
-ytick.minor.width: 0.4
-
-xtick.major.pad: 5.6
-ytick.major.pad: 5.6
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-pastel.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-pastel.mplstyle
deleted file mode 100644
index dff67482c0..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-pastel.mplstyle
+++ /dev/null
@@ -1,3 +0,0 @@
-# Seaborn pastel palette
-axes.prop_cycle: cycler('color', ['92C6FF', '97F0AA', 'FF9F9A', 'D0BBFF', 'FFFEA3', 'B0E0E6'])
-patch.facecolor: 92C6FF
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-poster.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-poster.mplstyle
deleted file mode 100644
index 47f237006c..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-poster.mplstyle
+++ /dev/null
@@ -1,21 +0,0 @@
-# Seaborn poster context
-figure.figsize: 12.8, 8.8
-axes.labelsize: 17.6
-axes.titlesize: 19.2
-xtick.labelsize: 16
-ytick.labelsize: 16
-legend.fontsize: 16
-
-grid.linewidth: 1.6
-lines.linewidth: 2.8
-patch.linewidth: 0.48
-lines.markersize: 11.2
-lines.markeredgewidth: 0
-
-xtick.major.width: 1.6
-ytick.major.width: 1.6
-xtick.minor.width: 0.8
-ytick.minor.width: 0.8
-
-xtick.major.pad: 11.2
-ytick.major.pad: 11.2
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-talk.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-talk.mplstyle
deleted file mode 100644
index 29a77c53c4..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-talk.mplstyle
+++ /dev/null
@@ -1,21 +0,0 @@
-# Seaborn talk context
-figure.figsize: 10.4, 7.15
-axes.labelsize: 14.3
-axes.titlesize: 15.6
-xtick.labelsize: 13
-ytick.labelsize: 13
-legend.fontsize: 13
-
-grid.linewidth: 1.3
-lines.linewidth: 2.275
-patch.linewidth: 0.39
-lines.markersize: 9.1
-lines.markeredgewidth: 0
-
-xtick.major.width: 1.3
-ytick.major.width: 1.3
-xtick.minor.width: 0.65
-ytick.minor.width: 0.65
-
-xtick.major.pad: 9.1
-ytick.major.pad: 9.1
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-ticks.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-ticks.mplstyle
deleted file mode 100644
index c2a1cab9a5..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-ticks.mplstyle
+++ /dev/null
@@ -1,30 +0,0 @@
-# Seaborn common parameters
-# .15 = dark_gray
-# .8 = light_gray
-figure.facecolor: white
-text.color: .15
-axes.labelcolor: .15
-legend.frameon: False
-legend.numpoints: 1
-legend.scatterpoints: 1
-xtick.direction: out
-ytick.direction: out
-xtick.color: .15
-ytick.color: .15
-axes.axisbelow: True
-image.cmap: Greys
-font.family: sans-serif
-font.sans-serif: Arial, Liberation Sans, DejaVu Sans, Bitstream Vera Sans, sans-serif
-grid.linestyle: -
-lines.solid_capstyle: round
-
-# Seaborn white parameters
-axes.grid: False
-axes.facecolor: white
-axes.edgecolor: .15
-axes.linewidth: 1.25
-grid.color: .8
-xtick.major.size: 6
-ytick.major.size: 6
-xtick.minor.size: 3
-ytick.minor.size: 3
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-white.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-white.mplstyle
deleted file mode 100644
index dcbe3acf31..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-white.mplstyle
+++ /dev/null
@@ -1,30 +0,0 @@
-# Seaborn common parameters
-# .15 = dark_gray
-# .8 = light_gray
-figure.facecolor: white
-text.color: .15
-axes.labelcolor: .15
-legend.frameon: False
-legend.numpoints: 1
-legend.scatterpoints: 1
-xtick.direction: out
-ytick.direction: out
-xtick.color: .15
-ytick.color: .15
-axes.axisbelow: True
-image.cmap: Greys
-font.family: sans-serif
-font.sans-serif: Arial, Liberation Sans, DejaVu Sans, Bitstream Vera Sans, sans-serif
-grid.linestyle: -
-lines.solid_capstyle: round
-
-# Seaborn white parameters
-axes.grid: False
-axes.facecolor: white
-axes.edgecolor: .15
-axes.linewidth: 1.25
-grid.color: .8
-xtick.major.size: 0
-ytick.major.size: 0
-xtick.minor.size: 0
-ytick.minor.size: 0
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-whitegrid.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-whitegrid.mplstyle
deleted file mode 100644
index 612e21813e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8-whitegrid.mplstyle
+++ /dev/null
@@ -1,30 +0,0 @@
-# Seaborn common parameters
-# .15 = dark_gray
-# .8 = light_gray
-figure.facecolor: white
-text.color: .15
-axes.labelcolor: .15
-legend.frameon: False
-legend.numpoints: 1
-legend.scatterpoints: 1
-xtick.direction: out
-ytick.direction: out
-xtick.color: .15
-ytick.color: .15
-axes.axisbelow: True
-image.cmap: Greys
-font.family: sans-serif
-font.sans-serif: Arial, Liberation Sans, DejaVu Sans, Bitstream Vera Sans, sans-serif
-grid.linestyle: -
-lines.solid_capstyle: round
-
-# Seaborn whitegrid parameters
-axes.grid: True
-axes.facecolor: white
-axes.edgecolor: .8
-axes.linewidth: 1
-grid.color: .8
-xtick.major.size: 0
-ytick.major.size: 0
-xtick.minor.size: 0
-ytick.minor.size: 0
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8.mplstyle
deleted file mode 100644
index 94b1bc837a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/seaborn-v0_8.mplstyle
+++ /dev/null
@@ -1,57 +0,0 @@
-# default seaborn aesthetic
-# darkgrid + deep palette + notebook context
-
-axes.axisbelow: True
-axes.edgecolor: white
-axes.facecolor: EAEAF2
-axes.grid: True
-axes.labelcolor: .15
-axes.labelsize: 11
-axes.linewidth: 0
-axes.prop_cycle: cycler('color', ['4C72B0', '55A868', 'C44E52', '8172B2', 'CCB974', '64B5CD'])
-axes.titlesize: 12
-
-figure.facecolor: white
-figure.figsize: 8.0, 5.5
-
-font.family: sans-serif
-font.sans-serif: Arial, Liberation Sans, DejaVu Sans, Bitstream Vera Sans, sans-serif
-
-grid.color: white
-grid.linestyle: -
-grid.linewidth: 1
-
-image.cmap: Greys
-
-legend.fontsize: 10
-legend.frameon: False
-legend.numpoints: 1
-legend.scatterpoints: 1
-
-lines.linewidth: 1.75
-lines.markeredgewidth: 0
-lines.markersize: 7
-lines.solid_capstyle: round
-
-patch.facecolor: 4C72B0
-patch.linewidth: .3
-
-text.color: .15
-
-xtick.color: .15
-xtick.direction: out
-xtick.labelsize: 10
-xtick.major.pad: 7
-xtick.major.size: 0
-xtick.major.width: 1
-xtick.minor.size: 0
-xtick.minor.width: .5
-
-ytick.color: .15
-ytick.direction: out
-ytick.labelsize: 10
-ytick.major.pad: 7
-ytick.major.size: 0
-ytick.major.width: 1
-ytick.minor.size: 0
-ytick.minor.width: .5
diff --git a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/tableau-colorblind10.mplstyle b/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/tableau-colorblind10.mplstyle
deleted file mode 100644
index 2d8cb0208d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/mpl-data/stylelib/tableau-colorblind10.mplstyle
+++ /dev/null
@@ -1,3 +0,0 @@
-# Tableau colorblind 10 palette
-axes.prop_cycle: cycler('color', ['006BA4', 'FF800E', 'ABABAB', '595959', '5F9ED1', 'C85200', '898989', 'A2C8EC', 'FFBC79', 'CFCFCF'])
-patch.facecolor: 006BA4 \ No newline at end of file
diff --git a/contrib/python/matplotlib/py3/matplotlib/offsetbox.py b/contrib/python/matplotlib/py3/matplotlib/offsetbox.py
deleted file mode 100644
index bb117c38ce..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/offsetbox.py
+++ /dev/null
@@ -1,1604 +0,0 @@
-r"""
-Container classes for `.Artist`\s.
-
-`OffsetBox`
- The base of all container artists defined in this module.
-
-`AnchoredOffsetbox`, `AnchoredText`
- Anchor and align an arbitrary `.Artist` or a text relative to the parent
- axes or a specific anchor point.
-
-`DrawingArea`
- A container with fixed width and height. Children have a fixed position
- inside the container and may be clipped.
-
-`HPacker`, `VPacker`
- Containers for layouting their children vertically or horizontally.
-
-`PaddedBox`
- A container to add a padding around an `.Artist`.
-
-`TextArea`
- Contains a single `.Text` instance.
-"""
-
-import functools
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, _docstring
-import matplotlib.artist as martist
-import matplotlib.path as mpath
-import matplotlib.text as mtext
-import matplotlib.transforms as mtransforms
-from matplotlib.font_manager import FontProperties
-from matplotlib.image import BboxImage
-from matplotlib.patches import (
- FancyBboxPatch, FancyArrowPatch, bbox_artist as mbbox_artist)
-from matplotlib.transforms import Bbox, BboxBase, TransformedBbox
-
-
-DEBUG = False
-
-
-def _compat_get_offset(meth):
- """
- Decorator for the get_offset method of OffsetBox and subclasses, that
- allows supporting both the new signature (self, bbox, renderer) and the old
- signature (self, width, height, xdescent, ydescent, renderer).
- """
- sigs = [lambda self, width, height, xdescent, ydescent, renderer: locals(),
- lambda self, bbox, renderer: locals()]
-
- @functools.wraps(meth)
- def get_offset(self, *args, **kwargs):
- params = _api.select_matching_signature(sigs, self, *args, **kwargs)
- bbox = (params["bbox"] if "bbox" in params else
- Bbox.from_bounds(-params["xdescent"], -params["ydescent"],
- params["width"], params["height"]))
- return meth(params["self"], bbox, params["renderer"])
- return get_offset
-
-
-@_api.deprecated("3.7", alternative='patches.bbox_artist')
-def bbox_artist(*args, **kwargs):
- if DEBUG:
- mbbox_artist(*args, **kwargs)
-
-
-# for debugging use
-def _bbox_artist(*args, **kwargs):
- if DEBUG:
- mbbox_artist(*args, **kwargs)
-
-
-def _get_packed_offsets(widths, total, sep, mode="fixed"):
- r"""
- Pack boxes specified by their *widths*.
-
- For simplicity of the description, the terminology used here assumes a
- horizontal layout, but the function works equally for a vertical layout.
-
- There are three packing *mode*\s:
-
- - 'fixed': The elements are packed tight to the left with a spacing of
- *sep* in between. If *total* is *None* the returned total will be the
- right edge of the last box. A non-*None* total will be passed unchecked
- to the output. In particular this means that right edge of the last
- box may be further to the right than the returned total.
-
- - 'expand': Distribute the boxes with equal spacing so that the left edge
- of the first box is at 0, and the right edge of the last box is at
- *total*. The parameter *sep* is ignored in this mode. A total of *None*
- is accepted and considered equal to 1. The total is returned unchanged
- (except for the conversion *None* to 1). If the total is smaller than
- the sum of the widths, the laid out boxes will overlap.
-
- - 'equal': If *total* is given, the total space is divided in N equal
- ranges and each box is left-aligned within its subspace.
- Otherwise (*total* is *None*), *sep* must be provided and each box is
- left-aligned in its subspace of width ``(max(widths) + sep)``. The
- total width is then calculated to be ``N * (max(widths) + sep)``.
-
- Parameters
- ----------
- widths : list of float
- Widths of boxes to be packed.
- total : float or None
- Intended total length. *None* if not used.
- sep : float or None
- Spacing between boxes.
- mode : {'fixed', 'expand', 'equal'}
- The packing mode.
-
- Returns
- -------
- total : float
- The total width needed to accommodate the laid out boxes.
- offsets : array of float
- The left offsets of the boxes.
- """
- _api.check_in_list(["fixed", "expand", "equal"], mode=mode)
-
- if mode == "fixed":
- offsets_ = np.cumsum([0] + [w + sep for w in widths])
- offsets = offsets_[:-1]
- if total is None:
- total = offsets_[-1] - sep
- return total, offsets
-
- elif mode == "expand":
- # This is a bit of a hack to avoid a TypeError when *total*
- # is None and used in conjugation with tight layout.
- if total is None:
- total = 1
- if len(widths) > 1:
- sep = (total - sum(widths)) / (len(widths) - 1)
- else:
- sep = 0
- offsets_ = np.cumsum([0] + [w + sep for w in widths])
- offsets = offsets_[:-1]
- return total, offsets
-
- elif mode == "equal":
- maxh = max(widths)
- if total is None:
- if sep is None:
- raise ValueError("total and sep cannot both be None when "
- "using layout mode 'equal'")
- total = (maxh + sep) * len(widths)
- else:
- sep = total / len(widths) - maxh
- offsets = (maxh + sep) * np.arange(len(widths))
- return total, offsets
-
-
-def _get_aligned_offsets(yspans, height, align="baseline"):
- """
- Align boxes each specified by their ``(y0, y1)`` spans.
-
- For simplicity of the description, the terminology used here assumes a
- horizontal layout (i.e., vertical alignment), but the function works
- equally for a vertical layout.
-
- Parameters
- ----------
- yspans
- List of (y0, y1) spans of boxes to be aligned.
- height : float or None
- Intended total height. If None, the maximum of the heights
- (``y1 - y0``) in *yspans* is used.
- align : {'baseline', 'left', 'top', 'right', 'bottom', 'center'}
- The alignment anchor of the boxes.
-
- Returns
- -------
- (y0, y1)
- y range spanned by the packing. If a *height* was originally passed
- in, then for all alignments other than "baseline", a span of ``(0,
- height)`` is used without checking that it is actually large enough).
- descent
- The descent of the packing.
- offsets
- The bottom offsets of the boxes.
- """
-
- _api.check_in_list(
- ["baseline", "left", "top", "right", "bottom", "center"], align=align)
- if height is None:
- height = max(y1 - y0 for y0, y1 in yspans)
-
- if align == "baseline":
- yspan = (min(y0 for y0, y1 in yspans), max(y1 for y0, y1 in yspans))
- offsets = [0] * len(yspans)
- elif align in ["left", "bottom"]:
- yspan = (0, height)
- offsets = [-y0 for y0, y1 in yspans]
- elif align in ["right", "top"]:
- yspan = (0, height)
- offsets = [height - y1 for y0, y1 in yspans]
- elif align == "center":
- yspan = (0, height)
- offsets = [(height - (y1 - y0)) * .5 - y0 for y0, y1 in yspans]
-
- return yspan, offsets
-
-
-class OffsetBox(martist.Artist):
- """
- The OffsetBox is a simple container artist.
-
- The child artists are meant to be drawn at a relative position to its
- parent.
-
- Being an artist itself, all parameters are passed on to `.Artist`.
- """
- def __init__(self, *args, **kwargs):
- super().__init__(*args)
- self._internal_update(kwargs)
- # Clipping has not been implemented in the OffsetBox family, so
- # disable the clip flag for consistency. It can always be turned back
- # on to zero effect.
- self.set_clip_on(False)
- self._children = []
- self._offset = (0, 0)
-
- def set_figure(self, fig):
- """
- Set the `.Figure` for the `.OffsetBox` and all its children.
-
- Parameters
- ----------
- fig : `~matplotlib.figure.Figure`
- """
- super().set_figure(fig)
- for c in self.get_children():
- c.set_figure(fig)
-
- @martist.Artist.axes.setter
- def axes(self, ax):
- # TODO deal with this better
- martist.Artist.axes.fset(self, ax)
- for c in self.get_children():
- if c is not None:
- c.axes = ax
-
- def contains(self, mouseevent):
- """
- Delegate the mouse event contains-check to the children.
-
- As a container, the `.OffsetBox` does not respond itself to
- mouseevents.
-
- Parameters
- ----------
- mouseevent : `~matplotlib.backend_bases.MouseEvent`
-
- Returns
- -------
- contains : bool
- Whether any values are within the radius.
- details : dict
- An artist-specific dictionary of details of the event context,
- such as which points are contained in the pick radius. See the
- individual Artist subclasses for details.
-
- See Also
- --------
- .Artist.contains
- """
- if self._different_canvas(mouseevent):
- return False, {}
- for c in self.get_children():
- a, b = c.contains(mouseevent)
- if a:
- return a, b
- return False, {}
-
- def set_offset(self, xy):
- """
- Set the offset.
-
- Parameters
- ----------
- xy : (float, float) or callable
- The (x, y) coordinates of the offset in display units. These can
- either be given explicitly as a tuple (x, y), or by providing a
- function that converts the extent into the offset. This function
- must have the signature::
-
- def offset(width, height, xdescent, ydescent, renderer) \
--> (float, float)
- """
- self._offset = xy
- self.stale = True
-
- @_compat_get_offset
- def get_offset(self, bbox, renderer):
- """
- Return the offset as a tuple (x, y).
-
- The extent parameters have to be provided to handle the case where the
- offset is dynamically determined by a callable (see
- `~.OffsetBox.set_offset`).
-
- Parameters
- ----------
- bbox : `.Bbox`
- renderer : `.RendererBase` subclass
- """
- return (
- self._offset(bbox.width, bbox.height, -bbox.x0, -bbox.y0, renderer)
- if callable(self._offset)
- else self._offset)
-
- def set_width(self, width):
- """
- Set the width of the box.
-
- Parameters
- ----------
- width : float
- """
- self.width = width
- self.stale = True
-
- def set_height(self, height):
- """
- Set the height of the box.
-
- Parameters
- ----------
- height : float
- """
- self.height = height
- self.stale = True
-
- def get_visible_children(self):
- r"""Return a list of the visible child `.Artist`\s."""
- return [c for c in self._children if c.get_visible()]
-
- def get_children(self):
- r"""Return a list of the child `.Artist`\s."""
- return self._children
-
- def _get_bbox_and_child_offsets(self, renderer):
- """
- Return the bbox of the offsetbox and the child offsets.
-
- The bbox should satisfy ``x0 <= x1 and y0 <= y1``.
-
- Parameters
- ----------
- renderer : `.RendererBase` subclass
-
- Returns
- -------
- bbox
- list of (xoffset, yoffset) pairs
- """
- raise NotImplementedError(
- "get_bbox_and_offsets must be overridden in derived classes")
-
- def get_bbox(self, renderer):
- """Return the bbox of the offsetbox, ignoring parent offsets."""
- bbox, offsets = self._get_bbox_and_child_offsets(renderer)
- return bbox
-
- @_api.deprecated("3.7", alternative="get_bbox and child.get_offset")
- def get_extent_offsets(self, renderer):
- """
- Update offset of the children and return the extent of the box.
-
- Parameters
- ----------
- renderer : `.RendererBase` subclass
-
- Returns
- -------
- width
- height
- xdescent
- ydescent
- list of (xoffset, yoffset) pairs
- """
- bbox, offsets = self._get_bbox_and_child_offsets(renderer)
- return bbox.width, bbox.height, -bbox.x0, -bbox.y0, offsets
-
- @_api.deprecated("3.7", alternative="get_bbox")
- def get_extent(self, renderer):
- """Return a tuple ``width, height, xdescent, ydescent`` of the box."""
- bbox = self.get_bbox(renderer)
- return bbox.width, bbox.height, -bbox.x0, -bbox.y0
-
- def get_window_extent(self, renderer=None):
- # docstring inherited
- if renderer is None:
- renderer = self.figure._get_renderer()
- bbox = self.get_bbox(renderer)
- try: # Some subclasses redefine get_offset to take no args.
- px, py = self.get_offset(bbox, renderer)
- except TypeError:
- px, py = self.get_offset()
- return bbox.translated(px, py)
-
- def draw(self, renderer):
- """
- Update the location of children if necessary and draw them
- to the given *renderer*.
- """
- bbox, offsets = self._get_bbox_and_child_offsets(renderer)
- px, py = self.get_offset(bbox, renderer)
- for c, (ox, oy) in zip(self.get_visible_children(), offsets):
- c.set_offset((px + ox, py + oy))
- c.draw(renderer)
- _bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
- self.stale = False
-
-
-class PackerBase(OffsetBox):
- def __init__(self, pad=0., sep=0., width=None, height=None,
- align="baseline", mode="fixed", children=None):
- """
- Parameters
- ----------
- pad : float, default: 0.0
- The boundary padding in points.
-
- sep : float, default: 0.0
- The spacing between items in points.
-
- width, height : float, optional
- Width and height of the container box in pixels, calculated if
- *None*.
-
- align : {'top', 'bottom', 'left', 'right', 'center', 'baseline'}, \
-default: 'baseline'
- Alignment of boxes.
-
- mode : {'fixed', 'expand', 'equal'}, default: 'fixed'
- The packing mode.
-
- - 'fixed' packs the given `.Artist`\\s tight with *sep* spacing.
- - 'expand' uses the maximal available space to distribute the
- artists with equal spacing in between.
- - 'equal': Each artist an equal fraction of the available space
- and is left-aligned (or top-aligned) therein.
-
- children : list of `.Artist`
- The artists to pack.
-
- Notes
- -----
- *pad* and *sep* are in points and will be scaled with the renderer
- dpi, while *width* and *height* are in pixels.
- """
- super().__init__()
- self.height = height
- self.width = width
- self.sep = sep
- self.pad = pad
- self.mode = mode
- self.align = align
- self._children = children
-
-
-class VPacker(PackerBase):
- """
- VPacker packs its children vertically, automatically adjusting their
- relative positions at draw time.
- """
-
- def _get_bbox_and_child_offsets(self, renderer):
- # docstring inherited
- dpicor = renderer.points_to_pixels(1.)
- pad = self.pad * dpicor
- sep = self.sep * dpicor
-
- if self.width is not None:
- for c in self.get_visible_children():
- if isinstance(c, PackerBase) and c.mode == "expand":
- c.set_width(self.width)
-
- bboxes = [c.get_bbox(renderer) for c in self.get_visible_children()]
- (x0, x1), xoffsets = _get_aligned_offsets(
- [bbox.intervalx for bbox in bboxes], self.width, self.align)
- height, yoffsets = _get_packed_offsets(
- [bbox.height for bbox in bboxes], self.height, sep, self.mode)
-
- yoffsets = height - (yoffsets + [bbox.y1 for bbox in bboxes])
- ydescent = yoffsets[0]
- yoffsets = yoffsets - ydescent
-
- return (
- Bbox.from_bounds(x0, -ydescent, x1 - x0, height).padded(pad),
- [*zip(xoffsets, yoffsets)])
-
-
-class HPacker(PackerBase):
- """
- HPacker packs its children horizontally, automatically adjusting their
- relative positions at draw time.
- """
-
- def _get_bbox_and_child_offsets(self, renderer):
- # docstring inherited
- dpicor = renderer.points_to_pixels(1.)
- pad = self.pad * dpicor
- sep = self.sep * dpicor
-
- bboxes = [c.get_bbox(renderer) for c in self.get_visible_children()]
- if not bboxes:
- return Bbox.from_bounds(0, 0, 0, 0).padded(pad), []
-
- (y0, y1), yoffsets = _get_aligned_offsets(
- [bbox.intervaly for bbox in bboxes], self.height, self.align)
- width, xoffsets = _get_packed_offsets(
- [bbox.width for bbox in bboxes], self.width, sep, self.mode)
-
- x0 = bboxes[0].x0
- xoffsets -= ([bbox.x0 for bbox in bboxes] - x0)
-
- return (Bbox.from_bounds(x0, y0, width, y1 - y0).padded(pad),
- [*zip(xoffsets, yoffsets)])
-
-
-class PaddedBox(OffsetBox):
- """
- A container to add a padding around an `.Artist`.
-
- The `.PaddedBox` contains a `.FancyBboxPatch` that is used to visualize
- it when rendering.
- """
-
- def __init__(self, child, pad=0., *, draw_frame=False, patch_attrs=None):
- """
- Parameters
- ----------
- child : `~matplotlib.artist.Artist`
- The contained `.Artist`.
- pad : float, default: 0.0
- The padding in points. This will be scaled with the renderer dpi.
- In contrast, *width* and *height* are in *pixels* and thus not
- scaled.
- draw_frame : bool
- Whether to draw the contained `.FancyBboxPatch`.
- patch_attrs : dict or None
- Additional parameters passed to the contained `.FancyBboxPatch`.
- """
- super().__init__()
- self.pad = pad
- self._children = [child]
- self.patch = FancyBboxPatch(
- xy=(0.0, 0.0), width=1., height=1.,
- facecolor='w', edgecolor='k',
- mutation_scale=1, # self.prop.get_size_in_points(),
- snap=True,
- visible=draw_frame,
- boxstyle="square,pad=0",
- )
- if patch_attrs is not None:
- self.patch.update(patch_attrs)
-
- def _get_bbox_and_child_offsets(self, renderer):
- # docstring inherited.
- pad = self.pad * renderer.points_to_pixels(1.)
- return (self._children[0].get_bbox(renderer).padded(pad), [(0, 0)])
-
- def draw(self, renderer):
- # docstring inherited
- bbox, offsets = self._get_bbox_and_child_offsets(renderer)
- px, py = self.get_offset(bbox, renderer)
- for c, (ox, oy) in zip(self.get_visible_children(), offsets):
- c.set_offset((px + ox, py + oy))
-
- self.draw_frame(renderer)
-
- for c in self.get_visible_children():
- c.draw(renderer)
-
- self.stale = False
-
- def update_frame(self, bbox, fontsize=None):
- self.patch.set_bounds(bbox.bounds)
- if fontsize:
- self.patch.set_mutation_scale(fontsize)
- self.stale = True
-
- def draw_frame(self, renderer):
- # update the location and size of the legend
- self.update_frame(self.get_window_extent(renderer))
- self.patch.draw(renderer)
-
-
-class DrawingArea(OffsetBox):
- """
- The DrawingArea can contain any Artist as a child. The DrawingArea
- has a fixed width and height. The position of children relative to
- the parent is fixed. The children can be clipped at the
- boundaries of the parent.
- """
-
- def __init__(self, width, height, xdescent=0., ydescent=0., clip=False):
- """
- Parameters
- ----------
- width, height : float
- Width and height of the container box.
- xdescent, ydescent : float
- Descent of the box in x- and y-direction.
- clip : bool
- Whether to clip the children to the box.
- """
- super().__init__()
- self.width = width
- self.height = height
- self.xdescent = xdescent
- self.ydescent = ydescent
- self._clip_children = clip
- self.offset_transform = mtransforms.Affine2D()
- self.dpi_transform = mtransforms.Affine2D()
-
- @property
- def clip_children(self):
- """
- If the children of this DrawingArea should be clipped
- by DrawingArea bounding box.
- """
- return self._clip_children
-
- @clip_children.setter
- def clip_children(self, val):
- self._clip_children = bool(val)
- self.stale = True
-
- def get_transform(self):
- """
- Return the `~matplotlib.transforms.Transform` applied to the children.
- """
- return self.dpi_transform + self.offset_transform
-
- def set_transform(self, t):
- """
- set_transform is ignored.
- """
-
- def set_offset(self, xy):
- """
- Set the offset of the container.
-
- Parameters
- ----------
- xy : (float, float)
- The (x, y) coordinates of the offset in display units.
- """
- self._offset = xy
- self.offset_transform.clear()
- self.offset_transform.translate(xy[0], xy[1])
- self.stale = True
-
- def get_offset(self):
- """Return offset of the container."""
- return self._offset
-
- def get_bbox(self, renderer):
- # docstring inherited
- dpi_cor = renderer.points_to_pixels(1.)
- return Bbox.from_bounds(
- -self.xdescent * dpi_cor, -self.ydescent * dpi_cor,
- self.width * dpi_cor, self.height * dpi_cor)
-
- def add_artist(self, a):
- """Add an `.Artist` to the container box."""
- self._children.append(a)
- if not a.is_transform_set():
- a.set_transform(self.get_transform())
- if self.axes is not None:
- a.axes = self.axes
- fig = self.figure
- if fig is not None:
- a.set_figure(fig)
-
- def draw(self, renderer):
- # docstring inherited
-
- dpi_cor = renderer.points_to_pixels(1.)
- self.dpi_transform.clear()
- self.dpi_transform.scale(dpi_cor)
-
- # At this point the DrawingArea has a transform
- # to the display space so the path created is
- # good for clipping children
- tpath = mtransforms.TransformedPath(
- mpath.Path([[0, 0], [0, self.height],
- [self.width, self.height],
- [self.width, 0]]),
- self.get_transform())
- for c in self._children:
- if self._clip_children and not (c.clipbox or c._clippath):
- c.set_clip_path(tpath)
- c.draw(renderer)
-
- _bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
- self.stale = False
-
-
-class TextArea(OffsetBox):
- """
- The TextArea is a container artist for a single Text instance.
-
- The text is placed at (0, 0) with baseline+left alignment, by default. The
- width and height of the TextArea instance is the width and height of its
- child text.
- """
-
- def __init__(self, s,
- *,
- textprops=None,
- multilinebaseline=False,
- ):
- """
- Parameters
- ----------
- s : str
- The text to be displayed.
- textprops : dict, default: {}
- Dictionary of keyword parameters to be passed to the `.Text`
- instance in the TextArea.
- multilinebaseline : bool, default: False
- Whether the baseline for multiline text is adjusted so that it
- is (approximately) center-aligned with single-line text.
- """
- if textprops is None:
- textprops = {}
- self._text = mtext.Text(0, 0, s, **textprops)
- super().__init__()
- self._children = [self._text]
- self.offset_transform = mtransforms.Affine2D()
- self._baseline_transform = mtransforms.Affine2D()
- self._text.set_transform(self.offset_transform +
- self._baseline_transform)
- self._multilinebaseline = multilinebaseline
-
- def set_text(self, s):
- """Set the text of this area as a string."""
- self._text.set_text(s)
- self.stale = True
-
- def get_text(self):
- """Return the string representation of this area's text."""
- return self._text.get_text()
-
- def set_multilinebaseline(self, t):
- """
- Set multilinebaseline.
-
- If True, the baseline for multiline text is adjusted so that it is
- (approximately) center-aligned with single-line text. This is used
- e.g. by the legend implementation so that single-line labels are
- baseline-aligned, but multiline labels are "center"-aligned with them.
- """
- self._multilinebaseline = t
- self.stale = True
-
- def get_multilinebaseline(self):
- """
- Get multilinebaseline.
- """
- return self._multilinebaseline
-
- def set_transform(self, t):
- """
- set_transform is ignored.
- """
-
- def set_offset(self, xy):
- """
- Set the offset of the container.
-
- Parameters
- ----------
- xy : (float, float)
- The (x, y) coordinates of the offset in display units.
- """
- self._offset = xy
- self.offset_transform.clear()
- self.offset_transform.translate(xy[0], xy[1])
- self.stale = True
-
- def get_offset(self):
- """Return offset of the container."""
- return self._offset
-
- def get_bbox(self, renderer):
- _, h_, d_ = renderer.get_text_width_height_descent(
- "lp", self._text._fontproperties,
- ismath="TeX" if self._text.get_usetex() else False)
-
- bbox, info, yd = self._text._get_layout(renderer)
- w, h = bbox.size
-
- self._baseline_transform.clear()
-
- if len(info) > 1 and self._multilinebaseline:
- yd_new = 0.5 * h - 0.5 * (h_ - d_)
- self._baseline_transform.translate(0, yd - yd_new)
- yd = yd_new
- else: # single line
- h_d = max(h_ - d_, h - yd)
- h = h_d + yd
-
- ha = self._text.get_horizontalalignment()
- x0 = {"left": 0, "center": -w / 2, "right": -w}[ha]
-
- return Bbox.from_bounds(x0, -yd, w, h)
-
- def draw(self, renderer):
- # docstring inherited
- self._text.draw(renderer)
- _bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
- self.stale = False
-
-
-class AuxTransformBox(OffsetBox):
- """
- Offset Box with the aux_transform. Its children will be
- transformed with the aux_transform first then will be
- offsetted. The absolute coordinate of the aux_transform is meaning
- as it will be automatically adjust so that the left-lower corner
- of the bounding box of children will be set to (0, 0) before the
- offset transform.
-
- It is similar to drawing area, except that the extent of the box
- is not predetermined but calculated from the window extent of its
- children. Furthermore, the extent of the children will be
- calculated in the transformed coordinate.
- """
- def __init__(self, aux_transform):
- self.aux_transform = aux_transform
- super().__init__()
- self.offset_transform = mtransforms.Affine2D()
- # ref_offset_transform makes offset_transform always relative to the
- # lower-left corner of the bbox of its children.
- self.ref_offset_transform = mtransforms.Affine2D()
-
- def add_artist(self, a):
- """Add an `.Artist` to the container box."""
- self._children.append(a)
- a.set_transform(self.get_transform())
- self.stale = True
-
- def get_transform(self):
- """
- Return the :class:`~matplotlib.transforms.Transform` applied
- to the children
- """
- return (self.aux_transform
- + self.ref_offset_transform
- + self.offset_transform)
-
- def set_transform(self, t):
- """
- set_transform is ignored.
- """
-
- def set_offset(self, xy):
- """
- Set the offset of the container.
-
- Parameters
- ----------
- xy : (float, float)
- The (x, y) coordinates of the offset in display units.
- """
- self._offset = xy
- self.offset_transform.clear()
- self.offset_transform.translate(xy[0], xy[1])
- self.stale = True
-
- def get_offset(self):
- """Return offset of the container."""
- return self._offset
-
- def get_bbox(self, renderer):
- # clear the offset transforms
- _off = self.offset_transform.get_matrix() # to be restored later
- self.ref_offset_transform.clear()
- self.offset_transform.clear()
- # calculate the extent
- bboxes = [c.get_window_extent(renderer) for c in self._children]
- ub = Bbox.union(bboxes)
- # adjust ref_offset_transform
- self.ref_offset_transform.translate(-ub.x0, -ub.y0)
- # restore offset transform
- self.offset_transform.set_matrix(_off)
- return Bbox.from_bounds(0, 0, ub.width, ub.height)
-
- def draw(self, renderer):
- # docstring inherited
- for c in self._children:
- c.draw(renderer)
- _bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
- self.stale = False
-
-
-class AnchoredOffsetbox(OffsetBox):
- """
- An offset box placed according to location *loc*.
-
- AnchoredOffsetbox has a single child. When multiple children are needed,
- use an extra OffsetBox to enclose them. By default, the offset box is
- anchored against its parent axes. You may explicitly specify the
- *bbox_to_anchor*.
- """
- zorder = 5 # zorder of the legend
-
- # Location codes
- codes = {'upper right': 1,
- 'upper left': 2,
- 'lower left': 3,
- 'lower right': 4,
- 'right': 5,
- 'center left': 6,
- 'center right': 7,
- 'lower center': 8,
- 'upper center': 9,
- 'center': 10,
- }
-
- def __init__(self, loc, *,
- pad=0.4, borderpad=0.5,
- child=None, prop=None, frameon=True,
- bbox_to_anchor=None,
- bbox_transform=None,
- **kwargs):
- """
- Parameters
- ----------
- loc : str
- The box location. Valid locations are
- 'upper left', 'upper center', 'upper right',
- 'center left', 'center', 'center right',
- 'lower left', 'lower center', 'lower right'.
- For backward compatibility, numeric values are accepted as well.
- See the parameter *loc* of `.Legend` for details.
- pad : float, default: 0.4
- Padding around the child as fraction of the fontsize.
- borderpad : float, default: 0.5
- Padding between the offsetbox frame and the *bbox_to_anchor*.
- child : `.OffsetBox`
- The box that will be anchored.
- prop : `.FontProperties`
- This is only used as a reference for paddings. If not given,
- :rc:`legend.fontsize` is used.
- frameon : bool
- Whether to draw a frame around the box.
- bbox_to_anchor : `.BboxBase`, 2-tuple, or 4-tuple of floats
- Box that is used to position the legend in conjunction with *loc*.
- bbox_transform : None or :class:`matplotlib.transforms.Transform`
- The transform for the bounding box (*bbox_to_anchor*).
- **kwargs
- All other parameters are passed on to `.OffsetBox`.
-
- Notes
- -----
- See `.Legend` for a detailed description of the anchoring mechanism.
- """
- super().__init__(**kwargs)
-
- self.set_bbox_to_anchor(bbox_to_anchor, bbox_transform)
- self.set_child(child)
-
- if isinstance(loc, str):
- loc = _api.check_getitem(self.codes, loc=loc)
-
- self.loc = loc
- self.borderpad = borderpad
- self.pad = pad
-
- if prop is None:
- self.prop = FontProperties(size=mpl.rcParams["legend.fontsize"])
- else:
- self.prop = FontProperties._from_any(prop)
- if isinstance(prop, dict) and "size" not in prop:
- self.prop.set_size(mpl.rcParams["legend.fontsize"])
-
- self.patch = FancyBboxPatch(
- xy=(0.0, 0.0), width=1., height=1.,
- facecolor='w', edgecolor='k',
- mutation_scale=self.prop.get_size_in_points(),
- snap=True,
- visible=frameon,
- boxstyle="square,pad=0",
- )
-
- def set_child(self, child):
- """Set the child to be anchored."""
- self._child = child
- if child is not None:
- child.axes = self.axes
- self.stale = True
-
- def get_child(self):
- """Return the child."""
- return self._child
-
- def get_children(self):
- """Return the list of children."""
- return [self._child]
-
- def get_bbox(self, renderer):
- # docstring inherited
- fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
- pad = self.pad * fontsize
- return self.get_child().get_bbox(renderer).padded(pad)
-
- def get_bbox_to_anchor(self):
- """Return the bbox that the box is anchored to."""
- if self._bbox_to_anchor is None:
- return self.axes.bbox
- else:
- transform = self._bbox_to_anchor_transform
- if transform is None:
- return self._bbox_to_anchor
- else:
- return TransformedBbox(self._bbox_to_anchor, transform)
-
- def set_bbox_to_anchor(self, bbox, transform=None):
- """
- Set the bbox that the box is anchored to.
-
- *bbox* can be a Bbox instance, a list of [left, bottom, width,
- height], or a list of [left, bottom] where the width and
- height will be assumed to be zero. The bbox will be
- transformed to display coordinate by the given transform.
- """
- if bbox is None or isinstance(bbox, BboxBase):
- self._bbox_to_anchor = bbox
- else:
- try:
- l = len(bbox)
- except TypeError as err:
- raise ValueError(f"Invalid bbox: {bbox}") from err
-
- if l == 2:
- bbox = [bbox[0], bbox[1], 0, 0]
-
- self._bbox_to_anchor = Bbox.from_bounds(*bbox)
-
- self._bbox_to_anchor_transform = transform
- self.stale = True
-
- @_compat_get_offset
- def get_offset(self, bbox, renderer):
- # docstring inherited
- pad = (self.borderpad
- * renderer.points_to_pixels(self.prop.get_size_in_points()))
- bbox_to_anchor = self.get_bbox_to_anchor()
- x0, y0 = _get_anchored_bbox(
- self.loc, Bbox.from_bounds(0, 0, bbox.width, bbox.height),
- bbox_to_anchor, pad)
- return x0 - bbox.x0, y0 - bbox.y0
-
- def update_frame(self, bbox, fontsize=None):
- self.patch.set_bounds(bbox.bounds)
- if fontsize:
- self.patch.set_mutation_scale(fontsize)
-
- def draw(self, renderer):
- # docstring inherited
- if not self.get_visible():
- return
-
- # update the location and size of the legend
- bbox = self.get_window_extent(renderer)
- fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
- self.update_frame(bbox, fontsize)
- self.patch.draw(renderer)
-
- px, py = self.get_offset(self.get_bbox(renderer), renderer)
- self.get_child().set_offset((px, py))
- self.get_child().draw(renderer)
- self.stale = False
-
-
-def _get_anchored_bbox(loc, bbox, parentbbox, borderpad):
- """
- Return the (x, y) position of the *bbox* anchored at the *parentbbox* with
- the *loc* code with the *borderpad*.
- """
- # This is only called internally and *loc* should already have been
- # validated. If 0 (None), we just let ``bbox.anchored`` raise.
- c = [None, "NE", "NW", "SW", "SE", "E", "W", "E", "S", "N", "C"][loc]
- container = parentbbox.padded(-borderpad)
- return bbox.anchored(c, container=container).p0
-
-
-class AnchoredText(AnchoredOffsetbox):
- """
- AnchoredOffsetbox with Text.
- """
-
- def __init__(self, s, loc, *, pad=0.4, borderpad=0.5, prop=None, **kwargs):
- """
- Parameters
- ----------
- s : str
- Text.
-
- loc : str
- Location code. See `AnchoredOffsetbox`.
-
- pad : float, default: 0.4
- Padding around the text as fraction of the fontsize.
-
- borderpad : float, default: 0.5
- Spacing between the offsetbox frame and the *bbox_to_anchor*.
-
- prop : dict, optional
- Dictionary of keyword parameters to be passed to the
- `~matplotlib.text.Text` instance contained inside AnchoredText.
-
- **kwargs
- All other parameters are passed to `AnchoredOffsetbox`.
- """
-
- if prop is None:
- prop = {}
- badkwargs = {'va', 'verticalalignment'}
- if badkwargs & set(prop):
- raise ValueError(
- 'Mixing verticalalignment with AnchoredText is not supported.')
-
- self.txt = TextArea(s, textprops=prop)
- fp = self.txt._text.get_fontproperties()
- super().__init__(
- loc, pad=pad, borderpad=borderpad, child=self.txt, prop=fp,
- **kwargs)
-
-
-class OffsetImage(OffsetBox):
-
- def __init__(self, arr, *,
- zoom=1,
- cmap=None,
- norm=None,
- interpolation=None,
- origin=None,
- filternorm=True,
- filterrad=4.0,
- resample=False,
- dpi_cor=True,
- **kwargs
- ):
-
- super().__init__()
- self._dpi_cor = dpi_cor
-
- self.image = BboxImage(bbox=self.get_window_extent,
- cmap=cmap,
- norm=norm,
- interpolation=interpolation,
- origin=origin,
- filternorm=filternorm,
- filterrad=filterrad,
- resample=resample,
- **kwargs
- )
-
- self._children = [self.image]
-
- self.set_zoom(zoom)
- self.set_data(arr)
-
- def set_data(self, arr):
- self._data = np.asarray(arr)
- self.image.set_data(self._data)
- self.stale = True
-
- def get_data(self):
- return self._data
-
- def set_zoom(self, zoom):
- self._zoom = zoom
- self.stale = True
-
- def get_zoom(self):
- return self._zoom
-
- def get_offset(self):
- """Return offset of the container."""
- return self._offset
-
- def get_children(self):
- return [self.image]
-
- def get_bbox(self, renderer):
- dpi_cor = renderer.points_to_pixels(1.) if self._dpi_cor else 1.
- zoom = self.get_zoom()
- data = self.get_data()
- ny, nx = data.shape[:2]
- w, h = dpi_cor * nx * zoom, dpi_cor * ny * zoom
- return Bbox.from_bounds(0, 0, w, h)
-
- def draw(self, renderer):
- # docstring inherited
- self.image.draw(renderer)
- # bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
- self.stale = False
-
-
-class AnnotationBbox(martist.Artist, mtext._AnnotationBase):
- """
- Container for an `OffsetBox` referring to a specific position *xy*.
-
- Optionally an arrow pointing from the offsetbox to *xy* can be drawn.
-
- This is like `.Annotation`, but with `OffsetBox` instead of `.Text`.
- """
-
- zorder = 3
-
- def __str__(self):
- return f"AnnotationBbox({self.xy[0]:g},{self.xy[1]:g})"
-
- @_docstring.dedent_interpd
- def __init__(self, offsetbox, xy, xybox=None, xycoords='data', boxcoords=None, *,
- frameon=True, pad=0.4, # FancyBboxPatch boxstyle.
- annotation_clip=None,
- box_alignment=(0.5, 0.5),
- bboxprops=None,
- arrowprops=None,
- fontsize=None,
- **kwargs):
- """
- Parameters
- ----------
- offsetbox : `OffsetBox`
-
- xy : (float, float)
- The point *(x, y)* to annotate. The coordinate system is determined
- by *xycoords*.
-
- xybox : (float, float), default: *xy*
- The position *(x, y)* to place the text at. The coordinate system
- is determined by *boxcoords*.
-
- xycoords : single or two-tuple of str or `.Artist` or `.Transform` or \
-callable, default: 'data'
- The coordinate system that *xy* is given in. See the parameter
- *xycoords* in `.Annotation` for a detailed description.
-
- boxcoords : single or two-tuple of str or `.Artist` or `.Transform` \
-or callable, default: value of *xycoords*
- The coordinate system that *xybox* is given in. See the parameter
- *textcoords* in `.Annotation` for a detailed description.
-
- frameon : bool, default: True
- By default, the text is surrounded by a white `.FancyBboxPatch`
- (accessible as the ``patch`` attribute of the `.AnnotationBbox`).
- If *frameon* is set to False, this patch is made invisible.
-
- annotation_clip: bool or None, default: None
- Whether to clip (i.e. not draw) the annotation when the annotation
- point *xy* is outside the axes area.
-
- - If *True*, the annotation will be clipped when *xy* is outside
- the axes.
- - If *False*, the annotation will always be drawn.
- - If *None*, the annotation will be clipped when *xy* is outside
- the axes and *xycoords* is 'data'.
-
- pad : float, default: 0.4
- Padding around the offsetbox.
-
- box_alignment : (float, float)
- A tuple of two floats for a vertical and horizontal alignment of
- the offset box w.r.t. the *boxcoords*.
- The lower-left corner is (0, 0) and upper-right corner is (1, 1).
-
- bboxprops : dict, optional
- A dictionary of properties to set for the annotation bounding box,
- for example *boxstyle* and *alpha*. See `.FancyBboxPatch` for
- details.
-
- arrowprops: dict, optional
- Arrow properties, see `.Annotation` for description.
-
- fontsize: float or str, optional
- Translated to points and passed as *mutation_scale* into
- `.FancyBboxPatch` to scale attributes of the box style (e.g. pad
- or rounding_size). The name is chosen in analogy to `.Text` where
- *fontsize* defines the mutation scale as well. If not given,
- :rc:`legend.fontsize` is used. See `.Text.set_fontsize` for valid
- values.
-
- **kwargs
- Other `AnnotationBbox` properties. See `.AnnotationBbox.set` for
- a list.
- """
-
- martist.Artist.__init__(self)
- mtext._AnnotationBase.__init__(
- self, xy, xycoords=xycoords, annotation_clip=annotation_clip)
-
- self.offsetbox = offsetbox
- self.arrowprops = arrowprops.copy() if arrowprops is not None else None
- self.set_fontsize(fontsize)
- self.xybox = xybox if xybox is not None else xy
- self.boxcoords = boxcoords if boxcoords is not None else xycoords
- self._box_alignment = box_alignment
-
- if arrowprops is not None:
- self._arrow_relpos = self.arrowprops.pop("relpos", (0.5, 0.5))
- self.arrow_patch = FancyArrowPatch((0, 0), (1, 1),
- **self.arrowprops)
- else:
- self._arrow_relpos = None
- self.arrow_patch = None
-
- self.patch = FancyBboxPatch( # frame
- xy=(0.0, 0.0), width=1., height=1.,
- facecolor='w', edgecolor='k',
- mutation_scale=self.prop.get_size_in_points(),
- snap=True,
- visible=frameon,
- )
- self.patch.set_boxstyle("square", pad=pad)
- if bboxprops:
- self.patch.set(**bboxprops)
-
- self._internal_update(kwargs)
-
- @property
- def xyann(self):
- return self.xybox
-
- @xyann.setter
- def xyann(self, xyann):
- self.xybox = xyann
- self.stale = True
-
- @property
- def anncoords(self):
- return self.boxcoords
-
- @anncoords.setter
- def anncoords(self, coords):
- self.boxcoords = coords
- self.stale = True
-
- def contains(self, mouseevent):
- if self._different_canvas(mouseevent):
- return False, {}
- if not self._check_xy(None):
- return False, {}
- return self.offsetbox.contains(mouseevent)
- # self.arrow_patch is currently not checked as this can be a line - JJ
-
- def get_children(self):
- children = [self.offsetbox, self.patch]
- if self.arrow_patch:
- children.append(self.arrow_patch)
- return children
-
- def set_figure(self, fig):
- if self.arrow_patch is not None:
- self.arrow_patch.set_figure(fig)
- self.offsetbox.set_figure(fig)
- martist.Artist.set_figure(self, fig)
-
- def set_fontsize(self, s=None):
- """
- Set the fontsize in points.
-
- If *s* is not given, reset to :rc:`legend.fontsize`.
- """
- if s is None:
- s = mpl.rcParams["legend.fontsize"]
-
- self.prop = FontProperties(size=s)
- self.stale = True
-
- def get_fontsize(self):
- """Return the fontsize in points."""
- return self.prop.get_size_in_points()
-
- def get_window_extent(self, renderer=None):
- # docstring inherited
- if renderer is None:
- renderer = self.figure._get_renderer()
- self.update_positions(renderer)
- return Bbox.union([child.get_window_extent(renderer)
- for child in self.get_children()])
-
- def get_tightbbox(self, renderer=None):
- # docstring inherited
- if renderer is None:
- renderer = self.figure._get_renderer()
- self.update_positions(renderer)
- return Bbox.union([child.get_tightbbox(renderer)
- for child in self.get_children()])
-
- def update_positions(self, renderer):
- """Update pixel positions for the annotated point, the text, and the arrow."""
-
- ox0, oy0 = self._get_xy(renderer, self.xybox, self.boxcoords)
- bbox = self.offsetbox.get_bbox(renderer)
- fw, fh = self._box_alignment
- self.offsetbox.set_offset(
- (ox0 - fw*bbox.width - bbox.x0, oy0 - fh*bbox.height - bbox.y0))
-
- bbox = self.offsetbox.get_window_extent(renderer)
- self.patch.set_bounds(bbox.bounds)
-
- mutation_scale = renderer.points_to_pixels(self.get_fontsize())
- self.patch.set_mutation_scale(mutation_scale)
-
- if self.arrowprops:
- # Use FancyArrowPatch if self.arrowprops has "arrowstyle" key.
-
- # Adjust the starting point of the arrow relative to the textbox.
- # TODO: Rotation needs to be accounted.
- arrow_begin = bbox.p0 + bbox.size * self._arrow_relpos
- arrow_end = self._get_position_xy(renderer)
- # The arrow (from arrow_begin to arrow_end) will be first clipped
- # by patchA and patchB, then shrunk by shrinkA and shrinkB (in
- # points). If patch A is not set, self.bbox_patch is used.
- self.arrow_patch.set_positions(arrow_begin, arrow_end)
-
- if "mutation_scale" in self.arrowprops:
- mutation_scale = renderer.points_to_pixels(
- self.arrowprops["mutation_scale"])
- # Else, use fontsize-based mutation_scale defined above.
- self.arrow_patch.set_mutation_scale(mutation_scale)
-
- patchA = self.arrowprops.get("patchA", self.patch)
- self.arrow_patch.set_patchA(patchA)
-
- def draw(self, renderer):
- # docstring inherited
- if renderer is not None:
- self._renderer = renderer
- if not self.get_visible() or not self._check_xy(renderer):
- return
- renderer.open_group(self.__class__.__name__, gid=self.get_gid())
- self.update_positions(renderer)
- if self.arrow_patch is not None:
- if self.arrow_patch.figure is None and self.figure is not None:
- self.arrow_patch.figure = self.figure
- self.arrow_patch.draw(renderer)
- self.patch.draw(renderer)
- self.offsetbox.draw(renderer)
- renderer.close_group(self.__class__.__name__)
- self.stale = False
-
-
-class DraggableBase:
- """
- Helper base class for a draggable artist (legend, offsetbox).
-
- Derived classes must override the following methods::
-
- def save_offset(self):
- '''
- Called when the object is picked for dragging; should save the
- reference position of the artist.
- '''
-
- def update_offset(self, dx, dy):
- '''
- Called during the dragging; (*dx*, *dy*) is the pixel offset from
- the point where the mouse drag started.
- '''
-
- Optionally, you may override the following method::
-
- def finalize_offset(self):
- '''Called when the mouse is released.'''
-
- In the current implementation of `.DraggableLegend` and
- `DraggableAnnotation`, `update_offset` places the artists in display
- coordinates, and `finalize_offset` recalculates their position in axes
- coordinate and set a relevant attribute.
- """
-
- def __init__(self, ref_artist, use_blit=False):
- self.ref_artist = ref_artist
- if not ref_artist.pickable():
- ref_artist.set_picker(True)
- self.got_artist = False
- self._use_blit = use_blit and self.canvas.supports_blit
- callbacks = ref_artist.figure._canvas_callbacks
- self._disconnectors = [
- functools.partial(
- callbacks.disconnect, callbacks._connect_picklable(name, func))
- for name, func in [
- ("pick_event", self.on_pick),
- ("button_release_event", self.on_release),
- ("motion_notify_event", self.on_motion),
- ]
- ]
-
- # A property, not an attribute, to maintain picklability.
- canvas = property(lambda self: self.ref_artist.figure.canvas)
-
- cids = property(lambda self: [
- disconnect.args[0] for disconnect in self._disconnectors[:2]])
-
- def on_motion(self, evt):
- if self._check_still_parented() and self.got_artist:
- dx = evt.x - self.mouse_x
- dy = evt.y - self.mouse_y
- self.update_offset(dx, dy)
- if self._use_blit:
- self.canvas.restore_region(self.background)
- self.ref_artist.draw(
- self.ref_artist.figure._get_renderer())
- self.canvas.blit()
- else:
- self.canvas.draw()
-
- def on_pick(self, evt):
- if self._check_still_parented() and evt.artist == self.ref_artist:
- self.mouse_x = evt.mouseevent.x
- self.mouse_y = evt.mouseevent.y
- self.got_artist = True
- if self._use_blit:
- self.ref_artist.set_animated(True)
- self.canvas.draw()
- self.background = \
- self.canvas.copy_from_bbox(self.ref_artist.figure.bbox)
- self.ref_artist.draw(
- self.ref_artist.figure._get_renderer())
- self.canvas.blit()
- self.save_offset()
-
- def on_release(self, event):
- if self._check_still_parented() and self.got_artist:
- self.finalize_offset()
- self.got_artist = False
- if self._use_blit:
- self.ref_artist.set_animated(False)
-
- def _check_still_parented(self):
- if self.ref_artist.figure is None:
- self.disconnect()
- return False
- else:
- return True
-
- def disconnect(self):
- """Disconnect the callbacks."""
- for disconnector in self._disconnectors:
- disconnector()
-
- def save_offset(self):
- pass
-
- def update_offset(self, dx, dy):
- pass
-
- def finalize_offset(self):
- pass
-
-
-class DraggableOffsetBox(DraggableBase):
- def __init__(self, ref_artist, offsetbox, use_blit=False):
- super().__init__(ref_artist, use_blit=use_blit)
- self.offsetbox = offsetbox
-
- def save_offset(self):
- offsetbox = self.offsetbox
- renderer = offsetbox.figure._get_renderer()
- offset = offsetbox.get_offset(offsetbox.get_bbox(renderer), renderer)
- self.offsetbox_x, self.offsetbox_y = offset
- self.offsetbox.set_offset(offset)
-
- def update_offset(self, dx, dy):
- loc_in_canvas = self.offsetbox_x + dx, self.offsetbox_y + dy
- self.offsetbox.set_offset(loc_in_canvas)
-
- def get_loc_in_canvas(self):
- offsetbox = self.offsetbox
- renderer = offsetbox.figure._get_renderer()
- bbox = offsetbox.get_bbox(renderer)
- ox, oy = offsetbox._offset
- loc_in_canvas = (ox + bbox.x0, oy + bbox.y0)
- return loc_in_canvas
-
-
-class DraggableAnnotation(DraggableBase):
- def __init__(self, annotation, use_blit=False):
- super().__init__(annotation, use_blit=use_blit)
- self.annotation = annotation
-
- def save_offset(self):
- ann = self.annotation
- self.ox, self.oy = ann.get_transform().transform(ann.xyann)
-
- def update_offset(self, dx, dy):
- ann = self.annotation
- ann.xyann = ann.get_transform().inverted().transform(
- (self.ox + dx, self.oy + dy))
diff --git a/contrib/python/matplotlib/py3/matplotlib/offsetbox.pyi b/contrib/python/matplotlib/py3/matplotlib/offsetbox.pyi
deleted file mode 100644
index fdd6ce287f..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/offsetbox.pyi
+++ /dev/null
@@ -1,321 +0,0 @@
-import matplotlib.artist as martist
-from matplotlib.backend_bases import RendererBase, Event, FigureCanvasBase
-from matplotlib.colors import Colormap, Normalize
-import matplotlib.text as mtext
-from matplotlib.figure import Figure
-from matplotlib.font_manager import FontProperties
-from matplotlib.image import BboxImage
-from matplotlib.patches import FancyArrowPatch, FancyBboxPatch
-from matplotlib.transforms import Bbox, BboxBase, Transform
-
-import numpy as np
-from numpy.typing import ArrayLike
-from collections.abc import Callable, Sequence
-from typing import Any, Literal, overload
-
-DEBUG: bool
-
-def bbox_artist(*args, **kwargs) -> None: ...
-def _get_packed_offsets(
- widths: Sequence[float],
- total: float | None,
- sep: float | None,
- mode: Literal["fixed", "expand", "equal"] = ...,
-) -> tuple[float, np.ndarray]: ...
-
-class OffsetBox(martist.Artist):
- width: float | None
- height: float | None
- def __init__(self, *args, **kwargs) -> None: ...
- def set_figure(self, fig: Figure) -> None: ...
- def set_offset(
- self,
- xy: tuple[float, float]
- | Callable[[float, float, float, float, RendererBase], tuple[float, float]],
- ) -> None: ...
-
- @overload
- def get_offset(self, bbox: Bbox, renderer: RendererBase) -> tuple[float, float]: ...
- @overload
- def get_offset(
- self,
- width: float,
- height: float,
- xdescent: float,
- ydescent: float,
- renderer: RendererBase
- ) -> tuple[float, float]: ...
-
- def set_width(self, width: float) -> None: ...
- def set_height(self, height: float) -> None: ...
- def get_visible_children(self) -> list[martist.Artist]: ...
- def get_children(self) -> list[martist.Artist]: ...
- def get_bbox(self, renderer: RendererBase) -> Bbox: ...
- def get_extent_offsets(
- self, renderer: RendererBase
- ) -> tuple[float, float, float, float, list[tuple[float, float]]]: ...
- def get_extent(
- self, renderer: RendererBase
- ) -> tuple[float, float, float, float]: ...
- def get_window_extent(self, renderer: RendererBase | None = ...) -> Bbox: ...
-
-class PackerBase(OffsetBox):
- height: float | None
- width: float | None
- sep: float | None
- pad: float | None
- mode: Literal["fixed", "expand", "equal"]
- align: Literal["top", "bottom", "left", "right", "center", "baseline"]
- def __init__(
- self,
- pad: float | None = ...,
- sep: float | None = ...,
- width: float | None = ...,
- height: float | None = ...,
- align: Literal["top", "bottom", "left", "right", "center", "baseline"] = ...,
- mode: Literal["fixed", "expand", "equal"] = ...,
- children: list[martist.Artist] | None = ...,
- ) -> None: ...
-
-class VPacker(PackerBase): ...
-class HPacker(PackerBase): ...
-
-class PaddedBox(OffsetBox):
- pad: float | None
- patch: FancyBboxPatch
- def __init__(
- self,
- child: martist.Artist,
- pad: float | None = ...,
- *,
- draw_frame: bool = ...,
- patch_attrs: dict[str, Any] | None = ...,
- ) -> None: ...
- def update_frame(self, bbox: Bbox, fontsize: float | None = ...) -> None: ...
- def draw_frame(self, renderer: RendererBase) -> None: ...
-
-class DrawingArea(OffsetBox):
- width: float
- height: float
- xdescent: float
- ydescent: float
- offset_transform: Transform
- dpi_transform: Transform
- def __init__(
- self,
- width: float,
- height: float,
- xdescent: float = ...,
- ydescent: float = ...,
- clip: bool = ...,
- ) -> None: ...
- @property
- def clip_children(self) -> bool: ...
- @clip_children.setter
- def clip_children(self, val: bool) -> None: ...
- def get_transform(self) -> Transform: ...
-
- # does not accept all options of superclass
- def set_offset(self, xy: tuple[float, float]) -> None: ... # type: ignore[override]
- def get_offset(self) -> tuple[float, float]: ... # type: ignore[override]
- def add_artist(self, a: martist.Artist) -> None: ...
-
-class TextArea(OffsetBox):
- offset_transform: Transform
- def __init__(
- self,
- s: str,
- *,
- textprops: dict[str, Any] | None = ...,
- multilinebaseline: bool = ...,
- ) -> None: ...
- def set_text(self, s: str) -> None: ...
- def get_text(self) -> str: ...
- def set_multilinebaseline(self, t: bool) -> None: ...
- def get_multilinebaseline(self) -> bool: ...
-
- # does not accept all options of superclass
- def set_offset(self, xy: tuple[float, float]) -> None: ... # type: ignore[override]
- def get_offset(self) -> tuple[float, float]: ... # type: ignore[override]
-
-class AuxTransformBox(OffsetBox):
- aux_transform: Transform
- offset_transform: Transform
- ref_offset_transform: Transform
- def __init__(self, aux_transform: Transform) -> None: ...
- def add_artist(self, a: martist.Artist) -> None: ...
- def get_transform(self) -> Transform: ...
-
- # does not accept all options of superclass
- def set_offset(self, xy: tuple[float, float]) -> None: ... # type: ignore[override]
- def get_offset(self) -> tuple[float, float]: ... # type: ignore[override]
-
-class AnchoredOffsetbox(OffsetBox):
- zorder: float
- codes: dict[str, int]
- loc: int
- borderpad: float
- pad: float
- prop: FontProperties
- patch: FancyBboxPatch
- def __init__(
- self,
- loc: str,
- *,
- pad: float = ...,
- borderpad: float = ...,
- child: OffsetBox | None = ...,
- prop: FontProperties | None = ...,
- frameon: bool = ...,
- bbox_to_anchor: BboxBase
- | tuple[float, float]
- | tuple[float, float, float, float]
- | None = ...,
- bbox_transform: Transform | None = ...,
- **kwargs
- ) -> None: ...
- def set_child(self, child: OffsetBox | None) -> None: ...
- def get_child(self) -> OffsetBox | None: ...
- def get_children(self) -> list[martist.Artist]: ...
- def get_bbox_to_anchor(self) -> Bbox: ...
- def set_bbox_to_anchor(
- self, bbox: BboxBase, transform: Transform | None = ...
- ) -> None: ...
- def update_frame(self, bbox: Bbox, fontsize: float | None = ...) -> None: ...
-
-class AnchoredText(AnchoredOffsetbox):
- txt: TextArea
- def __init__(
- self,
- s: str,
- loc: str,
- *,
- pad: float = ...,
- borderpad: float = ...,
- prop: dict[str, Any] | None = ...,
- **kwargs
- ) -> None: ...
-
-class OffsetImage(OffsetBox):
- image: BboxImage
- def __init__(
- self,
- arr: ArrayLike,
- *,
- zoom: float = ...,
- cmap: Colormap | str | None = ...,
- norm: Normalize | str | None = ...,
- interpolation: str | None = ...,
- origin: Literal["upper", "lower"] | None = ...,
- filternorm: bool = ...,
- filterrad: float = ...,
- resample: bool = ...,
- dpi_cor: bool = ...,
- **kwargs
- ) -> None: ...
- stale: bool
- def set_data(self, arr: ArrayLike | None) -> None: ...
- def get_data(self) -> ArrayLike | None: ...
- def set_zoom(self, zoom: float) -> None: ...
- def get_zoom(self) -> float: ...
- def get_children(self) -> list[martist.Artist]: ...
- def get_offset(self) -> tuple[float, float]: ... # type: ignore[override]
-
-class AnnotationBbox(martist.Artist, mtext._AnnotationBase):
- zorder: float
- offsetbox: OffsetBox
- arrowprops: dict[str, Any] | None
- xybox: tuple[float, float]
- boxcoords: str | tuple[str, str] | martist.Artist | Transform | Callable[
- [RendererBase], Bbox | Transform
- ]
- arrow_patch: FancyArrowPatch | None
- patch: FancyBboxPatch
- prop: FontProperties
- def __init__(
- self,
- offsetbox: OffsetBox,
- xy: tuple[float, float],
- xybox: tuple[float, float] | None = ...,
- xycoords: str
- | tuple[str, str]
- | martist.Artist
- | Transform
- | Callable[[RendererBase], Bbox | Transform] = ...,
- boxcoords: str
- | tuple[str, str]
- | martist.Artist
- | Transform
- | Callable[[RendererBase], Bbox | Transform]
- | None = ...,
- *,
- frameon: bool = ...,
- pad: float = ...,
- annotation_clip: bool | None = ...,
- box_alignment: tuple[float, float] = ...,
- bboxprops: dict[str, Any] | None = ...,
- arrowprops: dict[str, Any] | None = ...,
- fontsize: float | str | None = ...,
- **kwargs
- ) -> None: ...
- @property
- def xyann(self) -> tuple[float, float]: ...
- @xyann.setter
- def xyann(self, xyann: tuple[float, float]) -> None: ...
- @property
- def anncoords(
- self,
- ) -> str | tuple[str, str] | martist.Artist | Transform | Callable[
- [RendererBase], Bbox | Transform
- ]: ...
- @anncoords.setter
- def anncoords(
- self,
- coords: str
- | tuple[str, str]
- | martist.Artist
- | Transform
- | Callable[[RendererBase], Bbox | Transform],
- ) -> None: ...
- def get_children(self) -> list[martist.Artist]: ...
- def set_figure(self, fig: Figure) -> None: ...
- def set_fontsize(self, s: str | float | None = ...) -> None: ...
- def get_fontsize(self) -> float: ...
- def get_tightbbox(self, renderer: RendererBase | None = ...) -> Bbox: ...
- def update_positions(self, renderer: RendererBase) -> None: ...
-
-class DraggableBase:
- ref_artist: martist.Artist
- got_artist: bool
- mouse_x: int
- mouse_y: int
- background: Any
-
- @property
- def canvas(self) -> FigureCanvasBase: ...
- @property
- def cids(self) -> list[int]: ...
-
- def __init__(self, ref_artist: martist.Artist, use_blit: bool = ...) -> None: ...
- def on_motion(self, evt: Event) -> None: ...
- def on_pick(self, evt: Event) -> None: ...
- def on_release(self, event: Event) -> None: ...
- def disconnect(self) -> None: ...
- def save_offset(self) -> None: ...
- def update_offset(self, dx: float, dy: float) -> None: ...
- def finalize_offset(self) -> None: ...
-
-class DraggableOffsetBox(DraggableBase):
- offsetbox: OffsetBox
- def __init__(
- self, ref_artist: martist.Artist, offsetbox: OffsetBox, use_blit: bool = ...
- ) -> None: ...
- def save_offset(self) -> None: ...
- def update_offset(self, dx: float, dy: float) -> None: ...
- def get_loc_in_canvas(self) -> tuple[float, float]: ...
-
-class DraggableAnnotation(DraggableBase):
- annotation: mtext.Annotation
- def __init__(self, annotation: mtext.Annotation, use_blit: bool = ...) -> None: ...
- def save_offset(self) -> None: ...
- def update_offset(self, dx: float, dy: float) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/patches.py b/contrib/python/matplotlib/py3/matplotlib/patches.py
deleted file mode 100644
index f80df92c62..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/patches.py
+++ /dev/null
@@ -1,4634 +0,0 @@
-r"""
-Patches are `.Artist`\s with a face color and an edge color.
-"""
-
-import functools
-import inspect
-import math
-from numbers import Number, Real
-import textwrap
-from types import SimpleNamespace
-from collections import namedtuple
-from matplotlib.transforms import Affine2D
-
-import numpy as np
-
-import matplotlib as mpl
-from . import (_api, artist, cbook, colors, _docstring, hatch as mhatch,
- lines as mlines, transforms)
-from .bezier import (
- NonIntersectingPathException, get_cos_sin, get_intersection,
- get_parallels, inside_circle, make_wedged_bezier2,
- split_bezier_intersecting_with_closedpath, split_path_inout)
-from .path import Path
-from ._enums import JoinStyle, CapStyle
-
-
-@_docstring.interpd
-@_api.define_aliases({
- "antialiased": ["aa"],
- "edgecolor": ["ec"],
- "facecolor": ["fc"],
- "linestyle": ["ls"],
- "linewidth": ["lw"],
-})
-class Patch(artist.Artist):
- """
- A patch is a 2D artist with a face color and an edge color.
-
- If any of *edgecolor*, *facecolor*, *linewidth*, or *antialiased*
- are *None*, they default to their rc params setting.
- """
- zorder = 1
-
- # Whether to draw an edge by default. Set on a
- # subclass-by-subclass basis.
- _edge_default = False
-
- def __init__(self, *,
- edgecolor=None,
- facecolor=None,
- color=None,
- linewidth=None,
- linestyle=None,
- antialiased=None,
- hatch=None,
- fill=True,
- capstyle=None,
- joinstyle=None,
- **kwargs):
- """
- The following kwarg properties are supported
-
- %(Patch:kwdoc)s
- """
- super().__init__()
-
- if linestyle is None:
- linestyle = "solid"
- if capstyle is None:
- capstyle = CapStyle.butt
- if joinstyle is None:
- joinstyle = JoinStyle.miter
-
- self._hatch_color = colors.to_rgba(mpl.rcParams['hatch.color'])
- self._fill = bool(fill) # needed for set_facecolor call
- if color is not None:
- if edgecolor is not None or facecolor is not None:
- _api.warn_external(
- "Setting the 'color' property will override "
- "the edgecolor or facecolor properties.")
- self.set_color(color)
- else:
- self.set_edgecolor(edgecolor)
- self.set_facecolor(facecolor)
-
- self._linewidth = 0
- self._unscaled_dash_pattern = (0, None) # offset, dash
- self._dash_pattern = (0, None) # offset, dash (scaled by linewidth)
-
- self.set_linestyle(linestyle)
- self.set_linewidth(linewidth)
- self.set_antialiased(antialiased)
- self.set_hatch(hatch)
- self.set_capstyle(capstyle)
- self.set_joinstyle(joinstyle)
-
- if len(kwargs):
- self._internal_update(kwargs)
-
- def get_verts(self):
- """
- Return a copy of the vertices used in this patch.
-
- If the patch contains Bézier curves, the curves will be interpolated by
- line segments. To access the curves as curves, use `get_path`.
- """
- trans = self.get_transform()
- path = self.get_path()
- polygons = path.to_polygons(trans)
- if len(polygons):
- return polygons[0]
- return []
-
- def _process_radius(self, radius):
- if radius is not None:
- return radius
- if isinstance(self._picker, Number):
- _radius = self._picker
- else:
- if self.get_edgecolor()[3] == 0:
- _radius = 0
- else:
- _radius = self.get_linewidth()
- return _radius
-
- def contains(self, mouseevent, radius=None):
- """
- Test whether the mouse event occurred in the patch.
-
- Returns
- -------
- (bool, empty dict)
- """
- if self._different_canvas(mouseevent):
- return False, {}
- radius = self._process_radius(radius)
- codes = self.get_path().codes
- if codes is not None:
- vertices = self.get_path().vertices
- # if the current path is concatenated by multiple sub paths.
- # get the indexes of the starting code(MOVETO) of all sub paths
- idxs, = np.where(codes == Path.MOVETO)
- # Don't split before the first MOVETO.
- idxs = idxs[1:]
- subpaths = map(
- Path, np.split(vertices, idxs), np.split(codes, idxs))
- else:
- subpaths = [self.get_path()]
- inside = any(
- subpath.contains_point(
- (mouseevent.x, mouseevent.y), self.get_transform(), radius)
- for subpath in subpaths)
- return inside, {}
-
- def contains_point(self, point, radius=None):
- """
- Return whether the given point is inside the patch.
-
- Parameters
- ----------
- point : (float, float)
- The point (x, y) to check, in target coordinates of
- ``self.get_transform()``. These are display coordinates for patches
- that are added to a figure or axes.
- radius : float, optional
- Additional margin on the patch in target coordinates of
- ``self.get_transform()``. See `.Path.contains_point` for further
- details.
-
- Returns
- -------
- bool
-
- Notes
- -----
- The proper use of this method depends on the transform of the patch.
- Isolated patches do not have a transform. In this case, the patch
- creation coordinates and the point coordinates match. The following
- example checks that the center of a circle is within the circle
-
- >>> center = 0, 0
- >>> c = Circle(center, radius=1)
- >>> c.contains_point(center)
- True
-
- The convention of checking against the transformed patch stems from
- the fact that this method is predominantly used to check if display
- coordinates (e.g. from mouse events) are within the patch. If you want
- to do the above check with data coordinates, you have to properly
- transform them first:
-
- >>> center = 0, 0
- >>> c = Circle(center, radius=1)
- >>> plt.gca().add_patch(c)
- >>> transformed_center = c.get_transform().transform(center)
- >>> c.contains_point(transformed_center)
- True
-
- """
- radius = self._process_radius(radius)
- return self.get_path().contains_point(point,
- self.get_transform(),
- radius)
-
- def contains_points(self, points, radius=None):
- """
- Return whether the given points are inside the patch.
-
- Parameters
- ----------
- points : (N, 2) array
- The points to check, in target coordinates of
- ``self.get_transform()``. These are display coordinates for patches
- that are added to a figure or axes. Columns contain x and y values.
- radius : float, optional
- Additional margin on the patch in target coordinates of
- ``self.get_transform()``. See `.Path.contains_point` for further
- details.
-
- Returns
- -------
- length-N bool array
-
- Notes
- -----
- The proper use of this method depends on the transform of the patch.
- See the notes on `.Patch.contains_point`.
- """
- radius = self._process_radius(radius)
- return self.get_path().contains_points(points,
- self.get_transform(),
- radius)
-
- def update_from(self, other):
- # docstring inherited.
- super().update_from(other)
- # For some properties we don't need or don't want to go through the
- # getters/setters, so we just copy them directly.
- self._edgecolor = other._edgecolor
- self._facecolor = other._facecolor
- self._original_edgecolor = other._original_edgecolor
- self._original_facecolor = other._original_facecolor
- self._fill = other._fill
- self._hatch = other._hatch
- self._hatch_color = other._hatch_color
- self._unscaled_dash_pattern = other._unscaled_dash_pattern
- self.set_linewidth(other._linewidth) # also sets scaled dashes
- self.set_transform(other.get_data_transform())
- # If the transform of other needs further initialization, then it will
- # be the case for this artist too.
- self._transformSet = other.is_transform_set()
-
- def get_extents(self):
- """
- Return the `Patch`'s axis-aligned extents as a `~.transforms.Bbox`.
- """
- return self.get_path().get_extents(self.get_transform())
-
- def get_transform(self):
- """Return the `~.transforms.Transform` applied to the `Patch`."""
- return self.get_patch_transform() + artist.Artist.get_transform(self)
-
- def get_data_transform(self):
- """
- Return the `~.transforms.Transform` mapping data coordinates to
- physical coordinates.
- """
- return artist.Artist.get_transform(self)
-
- def get_patch_transform(self):
- """
- Return the `~.transforms.Transform` instance mapping patch coordinates
- to data coordinates.
-
- For example, one may define a patch of a circle which represents a
- radius of 5 by providing coordinates for a unit circle, and a
- transform which scales the coordinates (the patch coordinate) by 5.
- """
- return transforms.IdentityTransform()
-
- def get_antialiased(self):
- """Return whether antialiasing is used for drawing."""
- return self._antialiased
-
- def get_edgecolor(self):
- """Return the edge color."""
- return self._edgecolor
-
- def get_facecolor(self):
- """Return the face color."""
- return self._facecolor
-
- def get_linewidth(self):
- """Return the line width in points."""
- return self._linewidth
-
- def get_linestyle(self):
- """Return the linestyle."""
- return self._linestyle
-
- def set_antialiased(self, aa):
- """
- Set whether to use antialiased rendering.
-
- Parameters
- ----------
- aa : bool or None
- """
- if aa is None:
- aa = mpl.rcParams['patch.antialiased']
- self._antialiased = aa
- self.stale = True
-
- def _set_edgecolor(self, color):
- set_hatch_color = True
- if color is None:
- if (mpl.rcParams['patch.force_edgecolor'] or
- not self._fill or self._edge_default):
- color = mpl.rcParams['patch.edgecolor']
- else:
- color = 'none'
- set_hatch_color = False
-
- self._edgecolor = colors.to_rgba(color, self._alpha)
- if set_hatch_color:
- self._hatch_color = self._edgecolor
- self.stale = True
-
- def set_edgecolor(self, color):
- """
- Set the patch edge color.
-
- Parameters
- ----------
- color : color or None
- """
- self._original_edgecolor = color
- self._set_edgecolor(color)
-
- def _set_facecolor(self, color):
- if color is None:
- color = mpl.rcParams['patch.facecolor']
- alpha = self._alpha if self._fill else 0
- self._facecolor = colors.to_rgba(color, alpha)
- self.stale = True
-
- def set_facecolor(self, color):
- """
- Set the patch face color.
-
- Parameters
- ----------
- color : color or None
- """
- self._original_facecolor = color
- self._set_facecolor(color)
-
- def set_color(self, c):
- """
- Set both the edgecolor and the facecolor.
-
- Parameters
- ----------
- c : color
-
- See Also
- --------
- Patch.set_facecolor, Patch.set_edgecolor
- For setting the edge or face color individually.
- """
- self.set_facecolor(c)
- self.set_edgecolor(c)
-
- def set_alpha(self, alpha):
- # docstring inherited
- super().set_alpha(alpha)
- self._set_facecolor(self._original_facecolor)
- self._set_edgecolor(self._original_edgecolor)
- # stale is already True
-
- def set_linewidth(self, w):
- """
- Set the patch linewidth in points.
-
- Parameters
- ----------
- w : float or None
- """
- if w is None:
- w = mpl.rcParams['patch.linewidth']
- self._linewidth = float(w)
- self._dash_pattern = mlines._scale_dashes(
- *self._unscaled_dash_pattern, w)
- self.stale = True
-
- def set_linestyle(self, ls):
- """
- Set the patch linestyle.
-
- ========================================== =================
- linestyle description
- ========================================== =================
- ``'-'`` or ``'solid'`` solid line
- ``'--'`` or ``'dashed'`` dashed line
- ``'-.'`` or ``'dashdot'`` dash-dotted line
- ``':'`` or ``'dotted'`` dotted line
- ``'none'``, ``'None'``, ``' '``, or ``''`` draw nothing
- ========================================== =================
-
- Alternatively a dash tuple of the following form can be provided::
-
- (offset, onoffseq)
-
- where ``onoffseq`` is an even length tuple of on and off ink in points.
-
- Parameters
- ----------
- ls : {'-', '--', '-.', ':', '', (offset, on-off-seq), ...}
- The line style.
- """
- if ls is None:
- ls = "solid"
- if ls in [' ', '', 'none']:
- ls = 'None'
- self._linestyle = ls
- self._unscaled_dash_pattern = mlines._get_dash_pattern(ls)
- self._dash_pattern = mlines._scale_dashes(
- *self._unscaled_dash_pattern, self._linewidth)
- self.stale = True
-
- def set_fill(self, b):
- """
- Set whether to fill the patch.
-
- Parameters
- ----------
- b : bool
- """
- self._fill = bool(b)
- self._set_facecolor(self._original_facecolor)
- self._set_edgecolor(self._original_edgecolor)
- self.stale = True
-
- def get_fill(self):
- """Return whether the patch is filled."""
- return self._fill
-
- # Make fill a property so as to preserve the long-standing
- # but somewhat inconsistent behavior in which fill was an
- # attribute.
- fill = property(get_fill, set_fill)
-
- @_docstring.interpd
- def set_capstyle(self, s):
- """
- Set the `.CapStyle`.
-
- The default capstyle is 'round' for `.FancyArrowPatch` and 'butt' for
- all other patches.
-
- Parameters
- ----------
- s : `.CapStyle` or %(CapStyle)s
- """
- cs = CapStyle(s)
- self._capstyle = cs
- self.stale = True
-
- def get_capstyle(self):
- """Return the capstyle."""
- return self._capstyle.name
-
- @_docstring.interpd
- def set_joinstyle(self, s):
- """
- Set the `.JoinStyle`.
-
- The default joinstyle is 'round' for `.FancyArrowPatch` and 'miter' for
- all other patches.
-
- Parameters
- ----------
- s : `.JoinStyle` or %(JoinStyle)s
- """
- js = JoinStyle(s)
- self._joinstyle = js
- self.stale = True
-
- def get_joinstyle(self):
- """Return the joinstyle."""
- return self._joinstyle.name
-
- def set_hatch(self, hatch):
- r"""
- Set the hatching pattern.
-
- *hatch* can be one of::
-
- / - diagonal hatching
- \ - back diagonal
- | - vertical
- - - horizontal
- + - crossed
- x - crossed diagonal
- o - small circle
- O - large circle
- . - dots
- * - stars
-
- Letters can be combined, in which case all the specified
- hatchings are done. If same letter repeats, it increases the
- density of hatching of that pattern.
-
- Hatching is supported in the PostScript, PDF, SVG and Agg
- backends only.
-
- Parameters
- ----------
- hatch : {'/', '\\', '|', '-', '+', 'x', 'o', 'O', '.', '*'}
- """
- # Use validate_hatch(list) after deprecation.
- mhatch._validate_hatch_pattern(hatch)
- self._hatch = hatch
- self.stale = True
-
- def get_hatch(self):
- """Return the hatching pattern."""
- return self._hatch
-
- def _draw_paths_with_artist_properties(
- self, renderer, draw_path_args_list):
- """
- ``draw()`` helper factored out for sharing with `FancyArrowPatch`.
-
- Configure *renderer* and the associated graphics context *gc*
- from the artist properties, then repeatedly call
- ``renderer.draw_path(gc, *draw_path_args)`` for each tuple
- *draw_path_args* in *draw_path_args_list*.
- """
-
- renderer.open_group('patch', self.get_gid())
- gc = renderer.new_gc()
-
- gc.set_foreground(self._edgecolor, isRGBA=True)
-
- lw = self._linewidth
- if self._edgecolor[3] == 0 or self._linestyle == 'None':
- lw = 0
- gc.set_linewidth(lw)
- gc.set_dashes(*self._dash_pattern)
- gc.set_capstyle(self._capstyle)
- gc.set_joinstyle(self._joinstyle)
-
- gc.set_antialiased(self._antialiased)
- self._set_gc_clip(gc)
- gc.set_url(self._url)
- gc.set_snap(self.get_snap())
-
- gc.set_alpha(self._alpha)
-
- if self._hatch:
- gc.set_hatch(self._hatch)
- gc.set_hatch_color(self._hatch_color)
-
- if self.get_sketch_params() is not None:
- gc.set_sketch_params(*self.get_sketch_params())
-
- if self.get_path_effects():
- from matplotlib.patheffects import PathEffectRenderer
- renderer = PathEffectRenderer(self.get_path_effects(), renderer)
-
- for draw_path_args in draw_path_args_list:
- renderer.draw_path(gc, *draw_path_args)
-
- gc.restore()
- renderer.close_group('patch')
- self.stale = False
-
- @artist.allow_rasterization
- def draw(self, renderer):
- # docstring inherited
- if not self.get_visible():
- return
- path = self.get_path()
- transform = self.get_transform()
- tpath = transform.transform_path_non_affine(path)
- affine = transform.get_affine()
- self._draw_paths_with_artist_properties(
- renderer,
- [(tpath, affine,
- # Work around a bug in the PDF and SVG renderers, which
- # do not draw the hatches if the facecolor is fully
- # transparent, but do if it is None.
- self._facecolor if self._facecolor[3] else None)])
-
- def get_path(self):
- """Return the path of this patch."""
- raise NotImplementedError('Derived must override')
-
- def get_window_extent(self, renderer=None):
- return self.get_path().get_extents(self.get_transform())
-
- def _convert_xy_units(self, xy):
- """Convert x and y units for a tuple (x, y)."""
- x = self.convert_xunits(xy[0])
- y = self.convert_yunits(xy[1])
- return x, y
-
-
-class Shadow(Patch):
- def __str__(self):
- return f"Shadow({self.patch})"
-
- @_docstring.dedent_interpd
- def __init__(self, patch, ox, oy, *, shade=0.7, **kwargs):
- """
- Create a shadow of the given *patch*.
-
- By default, the shadow will have the same face color as the *patch*,
- but darkened. The darkness can be controlled by *shade*.
-
- Parameters
- ----------
- patch : `~matplotlib.patches.Patch`
- The patch to create the shadow for.
- ox, oy : float
- The shift of the shadow in data coordinates, scaled by a factor
- of dpi/72.
- shade : float, default: 0.7
- How the darkness of the shadow relates to the original color. If 1, the
- shadow is black, if 0, the shadow has the same color as the *patch*.
-
- .. versionadded:: 3.8
-
- **kwargs
- Properties of the shadow patch. Supported keys are:
-
- %(Patch:kwdoc)s
- """
- super().__init__()
- self.patch = patch
- self._ox, self._oy = ox, oy
- self._shadow_transform = transforms.Affine2D()
-
- self.update_from(self.patch)
- if not 0 <= shade <= 1:
- raise ValueError("shade must be between 0 and 1.")
- color = (1 - shade) * np.asarray(colors.to_rgb(self.patch.get_facecolor()))
- self.update({'facecolor': color, 'edgecolor': color, 'alpha': 0.5,
- # Place shadow patch directly behind the inherited patch.
- 'zorder': np.nextafter(self.patch.zorder, -np.inf),
- **kwargs})
-
- def _update_transform(self, renderer):
- ox = renderer.points_to_pixels(self._ox)
- oy = renderer.points_to_pixels(self._oy)
- self._shadow_transform.clear().translate(ox, oy)
-
- def get_path(self):
- return self.patch.get_path()
-
- def get_patch_transform(self):
- return self.patch.get_patch_transform() + self._shadow_transform
-
- def draw(self, renderer):
- self._update_transform(renderer)
- super().draw(renderer)
-
-
-class Rectangle(Patch):
- """
- A rectangle defined via an anchor point *xy* and its *width* and *height*.
-
- The rectangle extends from ``xy[0]`` to ``xy[0] + width`` in x-direction
- and from ``xy[1]`` to ``xy[1] + height`` in y-direction. ::
-
- : +------------------+
- : | |
- : height |
- : | |
- : (xy)---- width -----+
-
- One may picture *xy* as the bottom left corner, but which corner *xy* is
- actually depends on the direction of the axis and the sign of *width*
- and *height*; e.g. *xy* would be the bottom right corner if the x-axis
- was inverted or if *width* was negative.
- """
-
- def __str__(self):
- pars = self._x0, self._y0, self._width, self._height, self.angle
- fmt = "Rectangle(xy=(%g, %g), width=%g, height=%g, angle=%g)"
- return fmt % pars
-
- @_docstring.dedent_interpd
- def __init__(self, xy, width, height, *,
- angle=0.0, rotation_point='xy', **kwargs):
- """
- Parameters
- ----------
- xy : (float, float)
- The anchor point.
- width : float
- Rectangle width.
- height : float
- Rectangle height.
- angle : float, default: 0
- Rotation in degrees anti-clockwise about the rotation point.
- rotation_point : {'xy', 'center', (number, number)}, default: 'xy'
- If ``'xy'``, rotate around the anchor point. If ``'center'`` rotate
- around the center. If 2-tuple of number, rotate around this
- coordinate.
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.patches.Patch` properties
- %(Patch:kwdoc)s
- """
- super().__init__(**kwargs)
- self._x0 = xy[0]
- self._y0 = xy[1]
- self._width = width
- self._height = height
- self.angle = float(angle)
- self.rotation_point = rotation_point
- # Required for RectangleSelector with axes aspect ratio != 1
- # The patch is defined in data coordinates and when changing the
- # selector with square modifier and not in data coordinates, we need
- # to correct for the aspect ratio difference between the data and
- # display coordinate systems. Its value is typically provide by
- # Axes._get_aspect_ratio()
- self._aspect_ratio_correction = 1.0
- self._convert_units() # Validate the inputs.
-
- def get_path(self):
- """Return the vertices of the rectangle."""
- return Path.unit_rectangle()
-
- def _convert_units(self):
- """Convert bounds of the rectangle."""
- x0 = self.convert_xunits(self._x0)
- y0 = self.convert_yunits(self._y0)
- x1 = self.convert_xunits(self._x0 + self._width)
- y1 = self.convert_yunits(self._y0 + self._height)
- return x0, y0, x1, y1
-
- def get_patch_transform(self):
- # Note: This cannot be called until after this has been added to
- # an Axes, otherwise unit conversion will fail. This makes it very
- # important to call the accessor method and not directly access the
- # transformation member variable.
- bbox = self.get_bbox()
- if self.rotation_point == 'center':
- width, height = bbox.x1 - bbox.x0, bbox.y1 - bbox.y0
- rotation_point = bbox.x0 + width / 2., bbox.y0 + height / 2.
- elif self.rotation_point == 'xy':
- rotation_point = bbox.x0, bbox.y0
- else:
- rotation_point = self.rotation_point
- return transforms.BboxTransformTo(bbox) \
- + transforms.Affine2D() \
- .translate(-rotation_point[0], -rotation_point[1]) \
- .scale(1, self._aspect_ratio_correction) \
- .rotate_deg(self.angle) \
- .scale(1, 1 / self._aspect_ratio_correction) \
- .translate(*rotation_point)
-
- @property
- def rotation_point(self):
- """The rotation point of the patch."""
- return self._rotation_point
-
- @rotation_point.setter
- def rotation_point(self, value):
- if value in ['center', 'xy'] or (
- isinstance(value, tuple) and len(value) == 2 and
- isinstance(value[0], Real) and isinstance(value[1], Real)
- ):
- self._rotation_point = value
- else:
- raise ValueError("`rotation_point` must be one of "
- "{'xy', 'center', (number, number)}.")
-
- def get_x(self):
- """Return the left coordinate of the rectangle."""
- return self._x0
-
- def get_y(self):
- """Return the bottom coordinate of the rectangle."""
- return self._y0
-
- def get_xy(self):
- """Return the left and bottom coords of the rectangle as a tuple."""
- return self._x0, self._y0
-
- def get_corners(self):
- """
- Return the corners of the rectangle, moving anti-clockwise from
- (x0, y0).
- """
- return self.get_patch_transform().transform(
- [(0, 0), (1, 0), (1, 1), (0, 1)])
-
- def get_center(self):
- """Return the centre of the rectangle."""
- return self.get_patch_transform().transform((0.5, 0.5))
-
- def get_width(self):
- """Return the width of the rectangle."""
- return self._width
-
- def get_height(self):
- """Return the height of the rectangle."""
- return self._height
-
- def get_angle(self):
- """Get the rotation angle in degrees."""
- return self.angle
-
- def set_x(self, x):
- """Set the left coordinate of the rectangle."""
- self._x0 = x
- self.stale = True
-
- def set_y(self, y):
- """Set the bottom coordinate of the rectangle."""
- self._y0 = y
- self.stale = True
-
- def set_angle(self, angle):
- """
- Set the rotation angle in degrees.
-
- The rotation is performed anti-clockwise around *xy*.
- """
- self.angle = angle
- self.stale = True
-
- def set_xy(self, xy):
- """
- Set the left and bottom coordinates of the rectangle.
-
- Parameters
- ----------
- xy : (float, float)
- """
- self._x0, self._y0 = xy
- self.stale = True
-
- def set_width(self, w):
- """Set the width of the rectangle."""
- self._width = w
- self.stale = True
-
- def set_height(self, h):
- """Set the height of the rectangle."""
- self._height = h
- self.stale = True
-
- def set_bounds(self, *args):
- """
- Set the bounds of the rectangle as *left*, *bottom*, *width*, *height*.
-
- The values may be passed as separate parameters or as a tuple::
-
- set_bounds(left, bottom, width, height)
- set_bounds((left, bottom, width, height))
-
- .. ACCEPTS: (left, bottom, width, height)
- """
- if len(args) == 1:
- l, b, w, h = args[0]
- else:
- l, b, w, h = args
- self._x0 = l
- self._y0 = b
- self._width = w
- self._height = h
- self.stale = True
-
- def get_bbox(self):
- """Return the `.Bbox`."""
- return transforms.Bbox.from_extents(*self._convert_units())
-
- xy = property(get_xy, set_xy)
-
-
-class RegularPolygon(Patch):
- """A regular polygon patch."""
-
- def __str__(self):
- s = "RegularPolygon((%g, %g), %d, radius=%g, orientation=%g)"
- return s % (self.xy[0], self.xy[1], self.numvertices, self.radius,
- self.orientation)
-
- @_docstring.dedent_interpd
- def __init__(self, xy, numVertices, *,
- radius=5, orientation=0, **kwargs):
- """
- Parameters
- ----------
- xy : (float, float)
- The center position.
-
- numVertices : int
- The number of vertices.
-
- radius : float
- The distance from the center to each of the vertices.
-
- orientation : float
- The polygon rotation angle (in radians).
-
- **kwargs
- `Patch` properties:
-
- %(Patch:kwdoc)s
- """
- self.xy = xy
- self.numvertices = numVertices
- self.orientation = orientation
- self.radius = radius
- self._path = Path.unit_regular_polygon(numVertices)
- self._patch_transform = transforms.Affine2D()
- super().__init__(**kwargs)
-
- def get_path(self):
- return self._path
-
- def get_patch_transform(self):
- return self._patch_transform.clear() \
- .scale(self.radius) \
- .rotate(self.orientation) \
- .translate(*self.xy)
-
-
-class PathPatch(Patch):
- """A general polycurve path patch."""
-
- _edge_default = True
-
- def __str__(self):
- s = "PathPatch%d((%g, %g) ...)"
- return s % (len(self._path.vertices), *tuple(self._path.vertices[0]))
-
- @_docstring.dedent_interpd
- def __init__(self, path, **kwargs):
- """
- *path* is a `.Path` object.
-
- Valid keyword arguments are:
-
- %(Patch:kwdoc)s
- """
- super().__init__(**kwargs)
- self._path = path
-
- def get_path(self):
- return self._path
-
- def set_path(self, path):
- self._path = path
-
-
-class StepPatch(PathPatch):
- """
- A path patch describing a stepwise constant function.
-
- By default, the path is not closed and starts and stops at
- baseline value.
- """
-
- _edge_default = False
-
- @_docstring.dedent_interpd
- def __init__(self, values, edges, *,
- orientation='vertical', baseline=0, **kwargs):
- """
- Parameters
- ----------
- values : array-like
- The step heights.
-
- edges : array-like
- The edge positions, with ``len(edges) == len(vals) + 1``,
- between which the curve takes on vals values.
-
- orientation : {'vertical', 'horizontal'}, default: 'vertical'
- The direction of the steps. Vertical means that *values* are
- along the y-axis, and edges are along the x-axis.
-
- baseline : float, array-like or None, default: 0
- The bottom value of the bounding edges or when
- ``fill=True``, position of lower edge. If *fill* is
- True or an array is passed to *baseline*, a closed
- path is drawn.
-
- **kwargs
- `Patch` properties:
-
- %(Patch:kwdoc)s
- """
- self.orientation = orientation
- self._edges = np.asarray(edges)
- self._values = np.asarray(values)
- self._baseline = np.asarray(baseline) if baseline is not None else None
- self._update_path()
- super().__init__(self._path, **kwargs)
-
- def _update_path(self):
- if np.isnan(np.sum(self._edges)):
- raise ValueError('Nan values in "edges" are disallowed')
- if self._edges.size - 1 != self._values.size:
- raise ValueError('Size mismatch between "values" and "edges". '
- "Expected `len(values) + 1 == len(edges)`, but "
- f"`len(values) = {self._values.size}` and "
- f"`len(edges) = {self._edges.size}`.")
- # Initializing with empty arrays allows supporting empty stairs.
- verts, codes = [np.empty((0, 2))], [np.empty(0, dtype=Path.code_type)]
-
- _nan_mask = np.isnan(self._values)
- if self._baseline is not None:
- _nan_mask |= np.isnan(self._baseline)
- for idx0, idx1 in cbook.contiguous_regions(~_nan_mask):
- x = np.repeat(self._edges[idx0:idx1+1], 2)
- y = np.repeat(self._values[idx0:idx1], 2)
- if self._baseline is None:
- y = np.concatenate([y[:1], y, y[-1:]])
- elif self._baseline.ndim == 0: # single baseline value
- y = np.concatenate([[self._baseline], y, [self._baseline]])
- elif self._baseline.ndim == 1: # baseline array
- base = np.repeat(self._baseline[idx0:idx1], 2)[::-1]
- x = np.concatenate([x, x[::-1]])
- y = np.concatenate([base[-1:], y, base[:1],
- base[:1], base, base[-1:]])
- else: # no baseline
- raise ValueError('Invalid `baseline` specified')
- if self.orientation == 'vertical':
- xy = np.column_stack([x, y])
- else:
- xy = np.column_stack([y, x])
- verts.append(xy)
- codes.append([Path.MOVETO] + [Path.LINETO]*(len(xy)-1))
- self._path = Path(np.concatenate(verts), np.concatenate(codes))
-
- def get_data(self):
- """Get `.StepPatch` values, edges and baseline as namedtuple."""
- StairData = namedtuple('StairData', 'values edges baseline')
- return StairData(self._values, self._edges, self._baseline)
-
- def set_data(self, values=None, edges=None, baseline=None):
- """
- Set `.StepPatch` values, edges and baseline.
-
- Parameters
- ----------
- values : 1D array-like or None
- Will not update values, if passing None
- edges : 1D array-like, optional
- baseline : float, 1D array-like or None
- """
- if values is None and edges is None and baseline is None:
- raise ValueError("Must set *values*, *edges* or *baseline*.")
- if values is not None:
- self._values = np.asarray(values)
- if edges is not None:
- self._edges = np.asarray(edges)
- if baseline is not None:
- self._baseline = np.asarray(baseline)
- self._update_path()
- self.stale = True
-
-
-class Polygon(Patch):
- """A general polygon patch."""
-
- def __str__(self):
- if len(self._path.vertices):
- s = "Polygon%d((%g, %g) ...)"
- return s % (len(self._path.vertices), *self._path.vertices[0])
- else:
- return "Polygon0()"
-
- @_docstring.dedent_interpd
- def __init__(self, xy, *, closed=True, **kwargs):
- """
- Parameters
- ----------
- xy : (N, 2) array
-
- closed : bool, default: True
- Whether the polygon is closed (i.e., has identical start and end
- points).
-
- **kwargs
- %(Patch:kwdoc)s
- """
- super().__init__(**kwargs)
- self._closed = closed
- self.set_xy(xy)
-
- def get_path(self):
- """Get the `.Path` of the polygon."""
- return self._path
-
- def get_closed(self):
- """Return whether the polygon is closed."""
- return self._closed
-
- def set_closed(self, closed):
- """
- Set whether the polygon is closed.
-
- Parameters
- ----------
- closed : bool
- True if the polygon is closed
- """
- if self._closed == bool(closed):
- return
- self._closed = bool(closed)
- self.set_xy(self.get_xy())
- self.stale = True
-
- def get_xy(self):
- """
- Get the vertices of the path.
-
- Returns
- -------
- (N, 2) array
- The coordinates of the vertices.
- """
- return self._path.vertices
-
- def set_xy(self, xy):
- """
- Set the vertices of the polygon.
-
- Parameters
- ----------
- xy : (N, 2) array-like
- The coordinates of the vertices.
-
- Notes
- -----
- Unlike `.Path`, we do not ignore the last input vertex. If the
- polygon is meant to be closed, and the last point of the polygon is not
- equal to the first, we assume that the user has not explicitly passed a
- ``CLOSEPOLY`` vertex, and add it ourselves.
- """
- xy = np.asarray(xy)
- nverts, _ = xy.shape
- if self._closed:
- # if the first and last vertex are the "same", then we assume that
- # the user explicitly passed the CLOSEPOLY vertex. Otherwise, we
- # have to append one since the last vertex will be "ignored" by
- # Path
- if nverts == 1 or nverts > 1 and (xy[0] != xy[-1]).any():
- xy = np.concatenate([xy, [xy[0]]])
- else:
- # if we aren't closed, and the last vertex matches the first, then
- # we assume we have an unnecessary CLOSEPOLY vertex and remove it
- if nverts > 2 and (xy[0] == xy[-1]).all():
- xy = xy[:-1]
- self._path = Path(xy, closed=self._closed)
- self.stale = True
-
- xy = property(get_xy, set_xy,
- doc='The vertices of the path as a (N, 2) array.')
-
-
-class Wedge(Patch):
- """Wedge shaped patch."""
-
- def __str__(self):
- pars = (self.center[0], self.center[1], self.r,
- self.theta1, self.theta2, self.width)
- fmt = "Wedge(center=(%g, %g), r=%g, theta1=%g, theta2=%g, width=%s)"
- return fmt % pars
-
- @_docstring.dedent_interpd
- def __init__(self, center, r, theta1, theta2, *, width=None, **kwargs):
- """
- A wedge centered at *x*, *y* center with radius *r* that
- sweeps *theta1* to *theta2* (in degrees). If *width* is given,
- then a partial wedge is drawn from inner radius *r* - *width*
- to outer radius *r*.
-
- Valid keyword arguments are:
-
- %(Patch:kwdoc)s
- """
- super().__init__(**kwargs)
- self.center = center
- self.r, self.width = r, width
- self.theta1, self.theta2 = theta1, theta2
- self._patch_transform = transforms.IdentityTransform()
- self._recompute_path()
-
- def _recompute_path(self):
- # Inner and outer rings are connected unless the annulus is complete
- if abs((self.theta2 - self.theta1) - 360) <= 1e-12:
- theta1, theta2 = 0, 360
- connector = Path.MOVETO
- else:
- theta1, theta2 = self.theta1, self.theta2
- connector = Path.LINETO
-
- # Form the outer ring
- arc = Path.arc(theta1, theta2)
-
- if self.width is not None:
- # Partial annulus needs to draw the outer ring
- # followed by a reversed and scaled inner ring
- v1 = arc.vertices
- v2 = arc.vertices[::-1] * (self.r - self.width) / self.r
- v = np.concatenate([v1, v2, [(0, 0)]])
- c = [*arc.codes, connector, *arc.codes[1:], Path.CLOSEPOLY]
- else:
- # Wedge doesn't need an inner ring
- v = np.concatenate([arc.vertices, [(0, 0), (0, 0)]])
- c = [*arc.codes, connector, Path.CLOSEPOLY]
-
- # Shift and scale the wedge to the final location.
- self._path = Path(v * self.r + self.center, c)
-
- def set_center(self, center):
- self._path = None
- self.center = center
- self.stale = True
-
- def set_radius(self, radius):
- self._path = None
- self.r = radius
- self.stale = True
-
- def set_theta1(self, theta1):
- self._path = None
- self.theta1 = theta1
- self.stale = True
-
- def set_theta2(self, theta2):
- self._path = None
- self.theta2 = theta2
- self.stale = True
-
- def set_width(self, width):
- self._path = None
- self.width = width
- self.stale = True
-
- def get_path(self):
- if self._path is None:
- self._recompute_path()
- return self._path
-
-
-# COVERAGE NOTE: Not used internally or from examples
-class Arrow(Patch):
- """An arrow patch."""
-
- def __str__(self):
- return "Arrow()"
-
- _path = Path._create_closed([
- [0.0, 0.1], [0.0, -0.1], [0.8, -0.1], [0.8, -0.3], [1.0, 0.0],
- [0.8, 0.3], [0.8, 0.1]])
-
- @_docstring.dedent_interpd
- def __init__(self, x, y, dx, dy, *, width=1.0, **kwargs):
- """
- Draws an arrow from (*x*, *y*) to (*x* + *dx*, *y* + *dy*).
- The width of the arrow is scaled by *width*.
-
- Parameters
- ----------
- x : float
- x coordinate of the arrow tail.
- y : float
- y coordinate of the arrow tail.
- dx : float
- Arrow length in the x direction.
- dy : float
- Arrow length in the y direction.
- width : float, default: 1
- Scale factor for the width of the arrow. With a default value of 1,
- the tail width is 0.2 and head width is 0.6.
- **kwargs
- Keyword arguments control the `Patch` properties:
-
- %(Patch:kwdoc)s
-
- See Also
- --------
- FancyArrow
- Patch that allows independent control of the head and tail
- properties.
- """
- super().__init__(**kwargs)
- self._patch_transform = (
- transforms.Affine2D()
- .scale(np.hypot(dx, dy), width)
- .rotate(np.arctan2(dy, dx))
- .translate(x, y)
- .frozen())
-
- def get_path(self):
- return self._path
-
- def get_patch_transform(self):
- return self._patch_transform
-
-
-class FancyArrow(Polygon):
- """
- Like Arrow, but lets you set head width and head height independently.
- """
-
- _edge_default = True
-
- def __str__(self):
- return "FancyArrow()"
-
- @_docstring.dedent_interpd
- def __init__(self, x, y, dx, dy, *,
- width=0.001, length_includes_head=False, head_width=None,
- head_length=None, shape='full', overhang=0,
- head_starts_at_zero=False, **kwargs):
- """
- Parameters
- ----------
- x, y : float
- The x and y coordinates of the arrow base.
-
- dx, dy : float
- The length of the arrow along x and y direction.
-
- width : float, default: 0.001
- Width of full arrow tail.
-
- length_includes_head : bool, default: False
- True if head is to be counted in calculating the length.
-
- head_width : float or None, default: 3*width
- Total width of the full arrow head.
-
- head_length : float or None, default: 1.5*head_width
- Length of arrow head.
-
- shape : {'full', 'left', 'right'}, default: 'full'
- Draw the left-half, right-half, or full arrow.
-
- overhang : float, default: 0
- Fraction that the arrow is swept back (0 overhang means
- triangular shape). Can be negative or greater than one.
-
- head_starts_at_zero : bool, default: False
- If True, the head starts being drawn at coordinate 0
- instead of ending at coordinate 0.
-
- **kwargs
- `.Patch` properties:
-
- %(Patch:kwdoc)s
- """
- self._x = x
- self._y = y
- self._dx = dx
- self._dy = dy
- self._width = width
- self._length_includes_head = length_includes_head
- self._head_width = head_width
- self._head_length = head_length
- self._shape = shape
- self._overhang = overhang
- self._head_starts_at_zero = head_starts_at_zero
- self._make_verts()
- super().__init__(self.verts, closed=True, **kwargs)
-
- def set_data(self, *, x=None, y=None, dx=None, dy=None, width=None,
- head_width=None, head_length=None):
- """
- Set `.FancyArrow` x, y, dx, dy, width, head_with, and head_length.
- Values left as None will not be updated.
-
- Parameters
- ----------
- x, y : float or None, default: None
- The x and y coordinates of the arrow base.
-
- dx, dy : float or None, default: None
- The length of the arrow along x and y direction.
-
- width : float or None, default: None
- Width of full arrow tail.
-
- head_width : float or None, default: None
- Total width of the full arrow head.
-
- head_length : float or None, default: None
- Length of arrow head.
- """
- if x is not None:
- self._x = x
- if y is not None:
- self._y = y
- if dx is not None:
- self._dx = dx
- if dy is not None:
- self._dy = dy
- if width is not None:
- self._width = width
- if head_width is not None:
- self._head_width = head_width
- if head_length is not None:
- self._head_length = head_length
- self._make_verts()
- self.set_xy(self.verts)
-
- def _make_verts(self):
- if self._head_width is None:
- head_width = 3 * self._width
- else:
- head_width = self._head_width
- if self._head_length is None:
- head_length = 1.5 * head_width
- else:
- head_length = self._head_length
-
- distance = np.hypot(self._dx, self._dy)
-
- if self._length_includes_head:
- length = distance
- else:
- length = distance + head_length
- if not length:
- self.verts = np.empty([0, 2]) # display nothing if empty
- else:
- # start by drawing horizontal arrow, point at (0, 0)
- hw, hl = head_width, head_length
- hs, lw = self._overhang, self._width
- left_half_arrow = np.array([
- [0.0, 0.0], # tip
- [-hl, -hw / 2], # leftmost
- [-hl * (1 - hs), -lw / 2], # meets stem
- [-length, -lw / 2], # bottom left
- [-length, 0],
- ])
- # if we're not including the head, shift up by head length
- if not self._length_includes_head:
- left_half_arrow += [head_length, 0]
- # if the head starts at 0, shift up by another head length
- if self._head_starts_at_zero:
- left_half_arrow += [head_length / 2, 0]
- # figure out the shape, and complete accordingly
- if self._shape == 'left':
- coords = left_half_arrow
- else:
- right_half_arrow = left_half_arrow * [1, -1]
- if self._shape == 'right':
- coords = right_half_arrow
- elif self._shape == 'full':
- # The half-arrows contain the midpoint of the stem,
- # which we can omit from the full arrow. Including it
- # twice caused a problem with xpdf.
- coords = np.concatenate([left_half_arrow[:-1],
- right_half_arrow[-2::-1]])
- else:
- raise ValueError(f"Got unknown shape: {self._shape!r}")
- if distance != 0:
- cx = self._dx / distance
- sx = self._dy / distance
- else:
- # Account for division by zero
- cx, sx = 0, 1
- M = [[cx, sx], [-sx, cx]]
- self.verts = np.dot(coords, M) + [
- self._x + self._dx,
- self._y + self._dy,
- ]
-
-
-_docstring.interpd.update(
- FancyArrow="\n".join(
- (inspect.getdoc(FancyArrow.__init__) or "").splitlines()[2:]))
-
-
-class CirclePolygon(RegularPolygon):
- """A polygon-approximation of a circle patch."""
-
- def __str__(self):
- s = "CirclePolygon((%g, %g), radius=%g, resolution=%d)"
- return s % (self.xy[0], self.xy[1], self.radius, self.numvertices)
-
- @_docstring.dedent_interpd
- def __init__(self, xy, radius=5, *,
- resolution=20, # the number of vertices
- ** kwargs):
- """
- Create a circle at *xy* = (*x*, *y*) with given *radius*.
-
- This circle is approximated by a regular polygon with *resolution*
- sides. For a smoother circle drawn with splines, see `Circle`.
-
- Valid keyword arguments are:
-
- %(Patch:kwdoc)s
- """
- super().__init__(
- xy, resolution, radius=radius, orientation=0, **kwargs)
-
-
-class Ellipse(Patch):
- """A scale-free ellipse."""
-
- def __str__(self):
- pars = (self._center[0], self._center[1],
- self.width, self.height, self.angle)
- fmt = "Ellipse(xy=(%s, %s), width=%s, height=%s, angle=%s)"
- return fmt % pars
-
- @_docstring.dedent_interpd
- def __init__(self, xy, width, height, *, angle=0, **kwargs):
- """
- Parameters
- ----------
- xy : (float, float)
- xy coordinates of ellipse centre.
- width : float
- Total length (diameter) of horizontal axis.
- height : float
- Total length (diameter) of vertical axis.
- angle : float, default: 0
- Rotation in degrees anti-clockwise.
-
- Notes
- -----
- Valid keyword arguments are:
-
- %(Patch:kwdoc)s
- """
- super().__init__(**kwargs)
-
- self._center = xy
- self._width, self._height = width, height
- self._angle = angle
- self._path = Path.unit_circle()
- # Required for EllipseSelector with axes aspect ratio != 1
- # The patch is defined in data coordinates and when changing the
- # selector with square modifier and not in data coordinates, we need
- # to correct for the aspect ratio difference between the data and
- # display coordinate systems.
- self._aspect_ratio_correction = 1.0
- # Note: This cannot be calculated until this is added to an Axes
- self._patch_transform = transforms.IdentityTransform()
-
- def _recompute_transform(self):
- """
- Notes
- -----
- This cannot be called until after this has been added to an Axes,
- otherwise unit conversion will fail. This makes it very important to
- call the accessor method and not directly access the transformation
- member variable.
- """
- center = (self.convert_xunits(self._center[0]),
- self.convert_yunits(self._center[1]))
- width = self.convert_xunits(self._width)
- height = self.convert_yunits(self._height)
- self._patch_transform = transforms.Affine2D() \
- .scale(width * 0.5, height * 0.5 * self._aspect_ratio_correction) \
- .rotate_deg(self.angle) \
- .scale(1, 1 / self._aspect_ratio_correction) \
- .translate(*center)
-
- def get_path(self):
- """Return the path of the ellipse."""
- return self._path
-
- def get_patch_transform(self):
- self._recompute_transform()
- return self._patch_transform
-
- def set_center(self, xy):
- """
- Set the center of the ellipse.
-
- Parameters
- ----------
- xy : (float, float)
- """
- self._center = xy
- self.stale = True
-
- def get_center(self):
- """Return the center of the ellipse."""
- return self._center
-
- center = property(get_center, set_center)
-
- def set_width(self, width):
- """
- Set the width of the ellipse.
-
- Parameters
- ----------
- width : float
- """
- self._width = width
- self.stale = True
-
- def get_width(self):
- """
- Return the width of the ellipse.
- """
- return self._width
-
- width = property(get_width, set_width)
-
- def set_height(self, height):
- """
- Set the height of the ellipse.
-
- Parameters
- ----------
- height : float
- """
- self._height = height
- self.stale = True
-
- def get_height(self):
- """Return the height of the ellipse."""
- return self._height
-
- height = property(get_height, set_height)
-
- def set_angle(self, angle):
- """
- Set the angle of the ellipse.
-
- Parameters
- ----------
- angle : float
- """
- self._angle = angle
- self.stale = True
-
- def get_angle(self):
- """Return the angle of the ellipse."""
- return self._angle
-
- angle = property(get_angle, set_angle)
-
- def get_corners(self):
- """
- Return the corners of the ellipse bounding box.
-
- The bounding box orientation is moving anti-clockwise from the
- lower left corner defined before rotation.
- """
- return self.get_patch_transform().transform(
- [(-1, -1), (1, -1), (1, 1), (-1, 1)])
-
- def get_vertices(self):
- """
- Return the vertices coordinates of the ellipse.
-
- The definition can be found `here <https://en.wikipedia.org/wiki/Ellipse>`_
-
- .. versionadded:: 3.8
- """
- if self.width < self.height:
- ret = self.get_patch_transform().transform([(0, 1), (0, -1)])
- else:
- ret = self.get_patch_transform().transform([(1, 0), (-1, 0)])
- return [tuple(x) for x in ret]
-
- def get_co_vertices(self):
- """
- Return the co-vertices coordinates of the ellipse.
-
- The definition can be found `here <https://en.wikipedia.org/wiki/Ellipse>`_
-
- .. versionadded:: 3.8
- """
- if self.width < self.height:
- ret = self.get_patch_transform().transform([(1, 0), (-1, 0)])
- else:
- ret = self.get_patch_transform().transform([(0, 1), (0, -1)])
- return [tuple(x) for x in ret]
-
-
-class Annulus(Patch):
- """
- An elliptical annulus.
- """
-
- @_docstring.dedent_interpd
- def __init__(self, xy, r, width, angle=0.0, **kwargs):
- """
- Parameters
- ----------
- xy : (float, float)
- xy coordinates of annulus centre.
- r : float or (float, float)
- The radius, or semi-axes:
-
- - If float: radius of the outer circle.
- - If two floats: semi-major and -minor axes of outer ellipse.
- width : float
- Width (thickness) of the annular ring. The width is measured inward
- from the outer ellipse so that for the inner ellipse the semi-axes
- are given by ``r - width``. *width* must be less than or equal to
- the semi-minor axis.
- angle : float, default: 0
- Rotation angle in degrees (anti-clockwise from the positive
- x-axis). Ignored for circular annuli (i.e., if *r* is a scalar).
- **kwargs
- Keyword arguments control the `Patch` properties:
-
- %(Patch:kwdoc)s
- """
- super().__init__(**kwargs)
-
- self.set_radii(r)
- self.center = xy
- self.width = width
- self.angle = angle
- self._path = None
-
- def __str__(self):
- if self.a == self.b:
- r = self.a
- else:
- r = (self.a, self.b)
-
- return "Annulus(xy=(%s, %s), r=%s, width=%s, angle=%s)" % \
- (*self.center, r, self.width, self.angle)
-
- def set_center(self, xy):
- """
- Set the center of the annulus.
-
- Parameters
- ----------
- xy : (float, float)
- """
- self._center = xy
- self._path = None
- self.stale = True
-
- def get_center(self):
- """Return the center of the annulus."""
- return self._center
-
- center = property(get_center, set_center)
-
- def set_width(self, width):
- """
- Set the width (thickness) of the annulus ring.
-
- The width is measured inwards from the outer ellipse.
-
- Parameters
- ----------
- width : float
- """
- if min(self.a, self.b) <= width:
- raise ValueError(
- 'Width of annulus must be less than or equal semi-minor axis')
-
- self._width = width
- self._path = None
- self.stale = True
-
- def get_width(self):
- """Return the width (thickness) of the annulus ring."""
- return self._width
-
- width = property(get_width, set_width)
-
- def set_angle(self, angle):
- """
- Set the tilt angle of the annulus.
-
- Parameters
- ----------
- angle : float
- """
- self._angle = angle
- self._path = None
- self.stale = True
-
- def get_angle(self):
- """Return the angle of the annulus."""
- return self._angle
-
- angle = property(get_angle, set_angle)
-
- def set_semimajor(self, a):
- """
- Set the semi-major axis *a* of the annulus.
-
- Parameters
- ----------
- a : float
- """
- self.a = float(a)
- self._path = None
- self.stale = True
-
- def set_semiminor(self, b):
- """
- Set the semi-minor axis *b* of the annulus.
-
- Parameters
- ----------
- b : float
- """
- self.b = float(b)
- self._path = None
- self.stale = True
-
- def set_radii(self, r):
- """
- Set the semi-major (*a*) and semi-minor radii (*b*) of the annulus.
-
- Parameters
- ----------
- r : float or (float, float)
- The radius, or semi-axes:
-
- - If float: radius of the outer circle.
- - If two floats: semi-major and -minor axes of outer ellipse.
- """
- if np.shape(r) == (2,):
- self.a, self.b = r
- elif np.shape(r) == ():
- self.a = self.b = float(r)
- else:
- raise ValueError("Parameter 'r' must be one or two floats.")
-
- self._path = None
- self.stale = True
-
- def get_radii(self):
- """Return the semi-major and semi-minor radii of the annulus."""
- return self.a, self.b
-
- radii = property(get_radii, set_radii)
-
- def _transform_verts(self, verts, a, b):
- return transforms.Affine2D() \
- .scale(*self._convert_xy_units((a, b))) \
- .rotate_deg(self.angle) \
- .translate(*self._convert_xy_units(self.center)) \
- .transform(verts)
-
- def _recompute_path(self):
- # circular arc
- arc = Path.arc(0, 360)
-
- # annulus needs to draw an outer ring
- # followed by a reversed and scaled inner ring
- a, b, w = self.a, self.b, self.width
- v1 = self._transform_verts(arc.vertices, a, b)
- v2 = self._transform_verts(arc.vertices[::-1], a - w, b - w)
- v = np.vstack([v1, v2, v1[0, :], (0, 0)])
- c = np.hstack([arc.codes, Path.MOVETO,
- arc.codes[1:], Path.MOVETO,
- Path.CLOSEPOLY])
- self._path = Path(v, c)
-
- def get_path(self):
- if self._path is None:
- self._recompute_path()
- return self._path
-
-
-class Circle(Ellipse):
- """
- A circle patch.
- """
- def __str__(self):
- pars = self.center[0], self.center[1], self.radius
- fmt = "Circle(xy=(%g, %g), radius=%g)"
- return fmt % pars
-
- @_docstring.dedent_interpd
- def __init__(self, xy, radius=5, **kwargs):
- """
- Create a true circle at center *xy* = (*x*, *y*) with given *radius*.
-
- Unlike `CirclePolygon` which is a polygonal approximation, this uses
- Bezier splines and is much closer to a scale-free circle.
-
- Valid keyword arguments are:
-
- %(Patch:kwdoc)s
- """
- super().__init__(xy, radius * 2, radius * 2, **kwargs)
- self.radius = radius
-
- def set_radius(self, radius):
- """
- Set the radius of the circle.
-
- Parameters
- ----------
- radius : float
- """
- self.width = self.height = 2 * radius
- self.stale = True
-
- def get_radius(self):
- """Return the radius of the circle."""
- return self.width / 2.
-
- radius = property(get_radius, set_radius)
-
-
-class Arc(Ellipse):
- """
- An elliptical arc, i.e. a segment of an ellipse.
-
- Due to internal optimizations, the arc cannot be filled.
- """
-
- def __str__(self):
- pars = (self.center[0], self.center[1], self.width,
- self.height, self.angle, self.theta1, self.theta2)
- fmt = ("Arc(xy=(%g, %g), width=%g, "
- "height=%g, angle=%g, theta1=%g, theta2=%g)")
- return fmt % pars
-
- @_docstring.dedent_interpd
- def __init__(self, xy, width, height, *,
- angle=0.0, theta1=0.0, theta2=360.0, **kwargs):
- """
- Parameters
- ----------
- xy : (float, float)
- The center of the ellipse.
-
- width : float
- The length of the horizontal axis.
-
- height : float
- The length of the vertical axis.
-
- angle : float
- Rotation of the ellipse in degrees (counterclockwise).
-
- theta1, theta2 : float, default: 0, 360
- Starting and ending angles of the arc in degrees. These values
- are relative to *angle*, e.g. if *angle* = 45 and *theta1* = 90
- the absolute starting angle is 135.
- Default *theta1* = 0, *theta2* = 360, i.e. a complete ellipse.
- The arc is drawn in the counterclockwise direction.
- Angles greater than or equal to 360, or smaller than 0, are
- represented by an equivalent angle in the range [0, 360), by
- taking the input value mod 360.
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.patches.Patch` properties
- Most `.Patch` properties are supported as keyword arguments,
- except *fill* and *facecolor* because filling is not supported.
-
- %(Patch:kwdoc)s
- """
- fill = kwargs.setdefault('fill', False)
- if fill:
- raise ValueError("Arc objects cannot be filled")
-
- super().__init__(xy, width, height, angle=angle, **kwargs)
-
- self.theta1 = theta1
- self.theta2 = theta2
- (self._theta1, self._theta2, self._stretched_width,
- self._stretched_height) = self._theta_stretch()
- self._path = Path.arc(self._theta1, self._theta2)
-
- @artist.allow_rasterization
- def draw(self, renderer):
- """
- Draw the arc to the given *renderer*.
-
- Notes
- -----
- Ellipses are normally drawn using an approximation that uses
- eight cubic Bezier splines. The error of this approximation
- is 1.89818e-6, according to this unverified source:
-
- Lancaster, Don. *Approximating a Circle or an Ellipse Using
- Four Bezier Cubic Splines.*
-
- https://www.tinaja.com/glib/ellipse4.pdf
-
- There is a use case where very large ellipses must be drawn
- with very high accuracy, and it is too expensive to render the
- entire ellipse with enough segments (either splines or line
- segments). Therefore, in the case where either radius of the
- ellipse is large enough that the error of the spline
- approximation will be visible (greater than one pixel offset
- from the ideal), a different technique is used.
-
- In that case, only the visible parts of the ellipse are drawn,
- with each visible arc using a fixed number of spline segments
- (8). The algorithm proceeds as follows:
-
- 1. The points where the ellipse intersects the axes (or figure)
- bounding box are located. (This is done by performing an inverse
- transformation on the bbox such that it is relative to the unit
- circle -- this makes the intersection calculation much easier than
- doing rotated ellipse intersection directly.)
-
- This uses the "line intersecting a circle" algorithm from:
-
- Vince, John. *Geometry for Computer Graphics: Formulae,
- Examples & Proofs.* London: Springer-Verlag, 2005.
-
- 2. The angles of each of the intersection points are calculated.
-
- 3. Proceeding counterclockwise starting in the positive
- x-direction, each of the visible arc-segments between the
- pairs of vertices are drawn using the Bezier arc
- approximation technique implemented in `.Path.arc`.
- """
- if not self.get_visible():
- return
-
- self._recompute_transform()
-
- self._update_path()
- # Get width and height in pixels we need to use
- # `self.get_data_transform` rather than `self.get_transform`
- # because we want the transform from dataspace to the
- # screen space to estimate how big the arc will be in physical
- # units when rendered (the transform that we get via
- # `self.get_transform()` goes from an idealized unit-radius
- # space to screen space).
- data_to_screen_trans = self.get_data_transform()
- pwidth, pheight = (
- data_to_screen_trans.transform((self._stretched_width,
- self._stretched_height)) -
- data_to_screen_trans.transform((0, 0)))
- inv_error = (1.0 / 1.89818e-6) * 0.5
-
- if pwidth < inv_error and pheight < inv_error:
- return Patch.draw(self, renderer)
-
- def line_circle_intersect(x0, y0, x1, y1):
- dx = x1 - x0
- dy = y1 - y0
- dr2 = dx * dx + dy * dy
- D = x0 * y1 - x1 * y0
- D2 = D * D
- discrim = dr2 - D2
- if discrim >= 0.0:
- sign_dy = np.copysign(1, dy) # +/-1, never 0.
- sqrt_discrim = np.sqrt(discrim)
- return np.array(
- [[(D * dy + sign_dy * dx * sqrt_discrim) / dr2,
- (-D * dx + abs(dy) * sqrt_discrim) / dr2],
- [(D * dy - sign_dy * dx * sqrt_discrim) / dr2,
- (-D * dx - abs(dy) * sqrt_discrim) / dr2]])
- else:
- return np.empty((0, 2))
-
- def segment_circle_intersect(x0, y0, x1, y1):
- epsilon = 1e-9
- if x1 < x0:
- x0e, x1e = x1, x0
- else:
- x0e, x1e = x0, x1
- if y1 < y0:
- y0e, y1e = y1, y0
- else:
- y0e, y1e = y0, y1
- xys = line_circle_intersect(x0, y0, x1, y1)
- xs, ys = xys.T
- return xys[
- (x0e - epsilon < xs) & (xs < x1e + epsilon)
- & (y0e - epsilon < ys) & (ys < y1e + epsilon)
- ]
-
- # Transform the axes (or figure) box_path so that it is relative to
- # the unit circle in the same way that it is relative to the desired
- # ellipse.
- box_path_transform = (
- transforms.BboxTransformTo((self.axes or self.figure).bbox)
- - self.get_transform())
- box_path = Path.unit_rectangle().transformed(box_path_transform)
-
- thetas = set()
- # For each of the point pairs, there is a line segment
- for p0, p1 in zip(box_path.vertices[:-1], box_path.vertices[1:]):
- xy = segment_circle_intersect(*p0, *p1)
- x, y = xy.T
- # arctan2 return [-pi, pi), the rest of our angles are in
- # [0, 360], adjust as needed.
- theta = (np.rad2deg(np.arctan2(y, x)) + 360) % 360
- thetas.update(
- theta[(self._theta1 < theta) & (theta < self._theta2)])
- thetas = sorted(thetas) + [self._theta2]
- last_theta = self._theta1
- theta1_rad = np.deg2rad(self._theta1)
- inside = box_path.contains_point(
- (np.cos(theta1_rad), np.sin(theta1_rad))
- )
-
- # save original path
- path_original = self._path
- for theta in thetas:
- if inside:
- self._path = Path.arc(last_theta, theta, 8)
- Patch.draw(self, renderer)
- inside = False
- else:
- inside = True
- last_theta = theta
-
- # restore original path
- self._path = path_original
-
- def _update_path(self):
- # Compute new values and update and set new _path if any value changed
- stretched = self._theta_stretch()
- if any(a != b for a, b in zip(
- stretched, (self._theta1, self._theta2, self._stretched_width,
- self._stretched_height))):
- (self._theta1, self._theta2, self._stretched_width,
- self._stretched_height) = stretched
- self._path = Path.arc(self._theta1, self._theta2)
-
- def _theta_stretch(self):
- # If the width and height of ellipse are not equal, take into account
- # stretching when calculating angles to draw between
- def theta_stretch(theta, scale):
- theta = np.deg2rad(theta)
- x = np.cos(theta)
- y = np.sin(theta)
- stheta = np.rad2deg(np.arctan2(scale * y, x))
- # arctan2 has the range [-pi, pi], we expect [0, 2*pi]
- return (stheta + 360) % 360
-
- width = self.convert_xunits(self.width)
- height = self.convert_yunits(self.height)
- if (
- # if we need to stretch the angles because we are distorted
- width != height
- # and we are not doing a full circle.
- #
- # 0 and 360 do not exactly round-trip through the angle
- # stretching (due to both float precision limitations and
- # the difference between the range of arctan2 [-pi, pi] and
- # this method [0, 360]) so avoid doing it if we don't have to.
- and not (self.theta1 != self.theta2 and
- self.theta1 % 360 == self.theta2 % 360)
- ):
- theta1 = theta_stretch(self.theta1, width / height)
- theta2 = theta_stretch(self.theta2, width / height)
- return theta1, theta2, width, height
- return self.theta1, self.theta2, width, height
-
-
-def bbox_artist(artist, renderer, props=None, fill=True):
- """
- A debug function to draw a rectangle around the bounding
- box returned by an artist's `.Artist.get_window_extent`
- to test whether the artist is returning the correct bbox.
-
- *props* is a dict of rectangle props with the additional property
- 'pad' that sets the padding around the bbox in points.
- """
- if props is None:
- props = {}
- props = props.copy() # don't want to alter the pad externally
- pad = props.pop('pad', 4)
- pad = renderer.points_to_pixels(pad)
- bbox = artist.get_window_extent(renderer)
- r = Rectangle(
- xy=(bbox.x0 - pad / 2, bbox.y0 - pad / 2),
- width=bbox.width + pad, height=bbox.height + pad,
- fill=fill, transform=transforms.IdentityTransform(), clip_on=False)
- r.update(props)
- r.draw(renderer)
-
-
-def draw_bbox(bbox, renderer, color='k', trans=None):
- """
- A debug function to draw a rectangle around the bounding
- box returned by an artist's `.Artist.get_window_extent`
- to test whether the artist is returning the correct bbox.
- """
- r = Rectangle(xy=bbox.p0, width=bbox.width, height=bbox.height,
- edgecolor=color, fill=False, clip_on=False)
- if trans is not None:
- r.set_transform(trans)
- r.draw(renderer)
-
-
-class _Style:
- """
- A base class for the Styles. It is meant to be a container class,
- where actual styles are declared as subclass of it, and it
- provides some helper functions.
- """
-
- def __init_subclass__(cls):
- # Automatically perform docstring interpolation on the subclasses:
- # This allows listing the supported styles via
- # - %(BoxStyle:table)s
- # - %(ConnectionStyle:table)s
- # - %(ArrowStyle:table)s
- # and additionally adding .. ACCEPTS: blocks via
- # - %(BoxStyle:table_and_accepts)s
- # - %(ConnectionStyle:table_and_accepts)s
- # - %(ArrowStyle:table_and_accepts)s
- _docstring.interpd.update({
- f"{cls.__name__}:table": cls.pprint_styles(),
- f"{cls.__name__}:table_and_accepts": (
- cls.pprint_styles()
- + "\n\n .. ACCEPTS: ["
- + "|".join(map(" '{}' ".format, cls._style_list))
- + "]")
- })
-
- def __new__(cls, stylename, **kwargs):
- """Return the instance of the subclass with the given style name."""
- # The "class" should have the _style_list attribute, which is a mapping
- # of style names to style classes.
- _list = stylename.replace(" ", "").split(",")
- _name = _list[0].lower()
- try:
- _cls = cls._style_list[_name]
- except KeyError as err:
- raise ValueError(f"Unknown style: {stylename!r}") from err
- try:
- _args_pair = [cs.split("=") for cs in _list[1:]]
- _args = {k: float(v) for k, v in _args_pair}
- except ValueError as err:
- raise ValueError(
- f"Incorrect style argument: {stylename!r}") from err
- return _cls(**{**_args, **kwargs})
-
- @classmethod
- def get_styles(cls):
- """Return a dictionary of available styles."""
- return cls._style_list
-
- @classmethod
- def pprint_styles(cls):
- """Return the available styles as pretty-printed string."""
- table = [('Class', 'Name', 'Attrs'),
- *[(cls.__name__,
- # Add backquotes, as - and | have special meaning in reST.
- f'``{name}``',
- # [1:-1] drops the surrounding parentheses.
- str(inspect.signature(cls))[1:-1] or 'None')
- for name, cls in cls._style_list.items()]]
- # Convert to rst table.
- col_len = [max(len(cell) for cell in column) for column in zip(*table)]
- table_formatstr = ' '.join('=' * cl for cl in col_len)
- rst_table = '\n'.join([
- '',
- table_formatstr,
- ' '.join(cell.ljust(cl) for cell, cl in zip(table[0], col_len)),
- table_formatstr,
- *[' '.join(cell.ljust(cl) for cell, cl in zip(row, col_len))
- for row in table[1:]],
- table_formatstr,
- ])
- return textwrap.indent(rst_table, prefix=' ' * 4)
-
- @classmethod
- def register(cls, name, style):
- """Register a new style."""
- if not issubclass(style, cls._Base):
- raise ValueError(f"{style} must be a subclass of {cls._Base}")
- cls._style_list[name] = style
-
-
-def _register_style(style_list, cls=None, *, name=None):
- """Class decorator that stashes a class in a (style) dictionary."""
- if cls is None:
- return functools.partial(_register_style, style_list, name=name)
- style_list[name or cls.__name__.lower()] = cls
- return cls
-
-
-@_docstring.dedent_interpd
-class BoxStyle(_Style):
- """
- `BoxStyle` is a container class which defines several
- boxstyle classes, which are used for `FancyBboxPatch`.
-
- A style object can be created as::
-
- BoxStyle.Round(pad=0.2)
-
- or::
-
- BoxStyle("Round", pad=0.2)
-
- or::
-
- BoxStyle("Round, pad=0.2")
-
- The following boxstyle classes are defined.
-
- %(BoxStyle:table)s
-
- An instance of a boxstyle class is a callable object, with the signature ::
-
- __call__(self, x0, y0, width, height, mutation_size) -> Path
-
- *x0*, *y0*, *width* and *height* specify the location and size of the box
- to be drawn; *mutation_size* scales the outline properties such as padding.
- """
-
- _style_list = {}
-
- @_register_style(_style_list)
- class Square:
- """A square box."""
-
- def __init__(self, pad=0.3):
- """
- Parameters
- ----------
- pad : float, default: 0.3
- The amount of padding around the original box.
- """
- self.pad = pad
-
- def __call__(self, x0, y0, width, height, mutation_size):
- pad = mutation_size * self.pad
- # width and height with padding added.
- width, height = width + 2 * pad, height + 2 * pad
- # boundary of the padded box
- x0, y0 = x0 - pad, y0 - pad
- x1, y1 = x0 + width, y0 + height
- return Path._create_closed(
- [(x0, y0), (x1, y0), (x1, y1), (x0, y1)])
-
- @_register_style(_style_list)
- class Circle:
- """A circular box."""
-
- def __init__(self, pad=0.3):
- """
- Parameters
- ----------
- pad : float, default: 0.3
- The amount of padding around the original box.
- """
- self.pad = pad
-
- def __call__(self, x0, y0, width, height, mutation_size):
- pad = mutation_size * self.pad
- width, height = width + 2 * pad, height + 2 * pad
- # boundary of the padded box
- x0, y0 = x0 - pad, y0 - pad
- return Path.circle((x0 + width / 2, y0 + height / 2),
- max(width, height) / 2)
-
- @_register_style(_style_list)
- class Ellipse:
- """
- An elliptical box.
-
- .. versionadded:: 3.7
- """
-
- def __init__(self, pad=0.3):
- """
- Parameters
- ----------
- pad : float, default: 0.3
- The amount of padding around the original box.
- """
- self.pad = pad
-
- def __call__(self, x0, y0, width, height, mutation_size):
- pad = mutation_size * self.pad
- width, height = width + 2 * pad, height + 2 * pad
- # boundary of the padded box
- x0, y0 = x0 - pad, y0 - pad
- a = width / math.sqrt(2)
- b = height / math.sqrt(2)
- trans = Affine2D().scale(a, b).translate(x0 + width / 2,
- y0 + height / 2)
- return trans.transform_path(Path.unit_circle())
-
- @_register_style(_style_list)
- class LArrow:
- """A box in the shape of a left-pointing arrow."""
-
- def __init__(self, pad=0.3):
- """
- Parameters
- ----------
- pad : float, default: 0.3
- The amount of padding around the original box.
- """
- self.pad = pad
-
- def __call__(self, x0, y0, width, height, mutation_size):
- # padding
- pad = mutation_size * self.pad
- # width and height with padding added.
- width, height = width + 2 * pad, height + 2 * pad
- # boundary of the padded box
- x0, y0 = x0 - pad, y0 - pad,
- x1, y1 = x0 + width, y0 + height
-
- dx = (y1 - y0) / 2
- dxx = dx / 2
- x0 = x0 + pad / 1.4 # adjust by ~sqrt(2)
-
- return Path._create_closed(
- [(x0 + dxx, y0), (x1, y0), (x1, y1), (x0 + dxx, y1),
- (x0 + dxx, y1 + dxx), (x0 - dx, y0 + dx),
- (x0 + dxx, y0 - dxx), # arrow
- (x0 + dxx, y0)])
-
- @_register_style(_style_list)
- class RArrow(LArrow):
- """A box in the shape of a right-pointing arrow."""
-
- def __call__(self, x0, y0, width, height, mutation_size):
- p = BoxStyle.LArrow.__call__(
- self, x0, y0, width, height, mutation_size)
- p.vertices[:, 0] = 2 * x0 + width - p.vertices[:, 0]
- return p
-
- @_register_style(_style_list)
- class DArrow:
- """A box in the shape of a two-way arrow."""
- # Modified from LArrow to add a right arrow to the bbox.
-
- def __init__(self, pad=0.3):
- """
- Parameters
- ----------
- pad : float, default: 0.3
- The amount of padding around the original box.
- """
- self.pad = pad
-
- def __call__(self, x0, y0, width, height, mutation_size):
- # padding
- pad = mutation_size * self.pad
- # width and height with padding added.
- # The width is padded by the arrows, so we don't need to pad it.
- height = height + 2 * pad
- # boundary of the padded box
- x0, y0 = x0 - pad, y0 - pad
- x1, y1 = x0 + width, y0 + height
-
- dx = (y1 - y0) / 2
- dxx = dx / 2
- x0 = x0 + pad / 1.4 # adjust by ~sqrt(2)
-
- return Path._create_closed([
- (x0 + dxx, y0), (x1, y0), # bot-segment
- (x1, y0 - dxx), (x1 + dx + dxx, y0 + dx),
- (x1, y1 + dxx), # right-arrow
- (x1, y1), (x0 + dxx, y1), # top-segment
- (x0 + dxx, y1 + dxx), (x0 - dx, y0 + dx),
- (x0 + dxx, y0 - dxx), # left-arrow
- (x0 + dxx, y0)])
-
- @_register_style(_style_list)
- class Round:
- """A box with round corners."""
-
- def __init__(self, pad=0.3, rounding_size=None):
- """
- Parameters
- ----------
- pad : float, default: 0.3
- The amount of padding around the original box.
- rounding_size : float, default: *pad*
- Radius of the corners.
- """
- self.pad = pad
- self.rounding_size = rounding_size
-
- def __call__(self, x0, y0, width, height, mutation_size):
-
- # padding
- pad = mutation_size * self.pad
-
- # size of the rounding corner
- if self.rounding_size:
- dr = mutation_size * self.rounding_size
- else:
- dr = pad
-
- width, height = width + 2 * pad, height + 2 * pad
-
- x0, y0 = x0 - pad, y0 - pad,
- x1, y1 = x0 + width, y0 + height
-
- # Round corners are implemented as quadratic Bezier, e.g.,
- # [(x0, y0-dr), (x0, y0), (x0+dr, y0)] for lower left corner.
- cp = [(x0 + dr, y0),
- (x1 - dr, y0),
- (x1, y0), (x1, y0 + dr),
- (x1, y1 - dr),
- (x1, y1), (x1 - dr, y1),
- (x0 + dr, y1),
- (x0, y1), (x0, y1 - dr),
- (x0, y0 + dr),
- (x0, y0), (x0 + dr, y0),
- (x0 + dr, y0)]
-
- com = [Path.MOVETO,
- Path.LINETO,
- Path.CURVE3, Path.CURVE3,
- Path.LINETO,
- Path.CURVE3, Path.CURVE3,
- Path.LINETO,
- Path.CURVE3, Path.CURVE3,
- Path.LINETO,
- Path.CURVE3, Path.CURVE3,
- Path.CLOSEPOLY]
-
- return Path(cp, com)
-
- @_register_style(_style_list)
- class Round4:
- """A box with rounded edges."""
-
- def __init__(self, pad=0.3, rounding_size=None):
- """
- Parameters
- ----------
- pad : float, default: 0.3
- The amount of padding around the original box.
- rounding_size : float, default: *pad*/2
- Rounding of edges.
- """
- self.pad = pad
- self.rounding_size = rounding_size
-
- def __call__(self, x0, y0, width, height, mutation_size):
-
- # padding
- pad = mutation_size * self.pad
-
- # Rounding size; defaults to half of the padding.
- if self.rounding_size:
- dr = mutation_size * self.rounding_size
- else:
- dr = pad / 2.
-
- width = width + 2 * pad - 2 * dr
- height = height + 2 * pad - 2 * dr
-
- x0, y0 = x0 - pad + dr, y0 - pad + dr,
- x1, y1 = x0 + width, y0 + height
-
- cp = [(x0, y0),
- (x0 + dr, y0 - dr), (x1 - dr, y0 - dr), (x1, y0),
- (x1 + dr, y0 + dr), (x1 + dr, y1 - dr), (x1, y1),
- (x1 - dr, y1 + dr), (x0 + dr, y1 + dr), (x0, y1),
- (x0 - dr, y1 - dr), (x0 - dr, y0 + dr), (x0, y0),
- (x0, y0)]
-
- com = [Path.MOVETO,
- Path.CURVE4, Path.CURVE4, Path.CURVE4,
- Path.CURVE4, Path.CURVE4, Path.CURVE4,
- Path.CURVE4, Path.CURVE4, Path.CURVE4,
- Path.CURVE4, Path.CURVE4, Path.CURVE4,
- Path.CLOSEPOLY]
-
- return Path(cp, com)
-
- @_register_style(_style_list)
- class Sawtooth:
- """A box with a sawtooth outline."""
-
- def __init__(self, pad=0.3, tooth_size=None):
- """
- Parameters
- ----------
- pad : float, default: 0.3
- The amount of padding around the original box.
- tooth_size : float, default: *pad*/2
- Size of the sawtooth.
- """
- self.pad = pad
- self.tooth_size = tooth_size
-
- def _get_sawtooth_vertices(self, x0, y0, width, height, mutation_size):
-
- # padding
- pad = mutation_size * self.pad
-
- # size of sawtooth
- if self.tooth_size is None:
- tooth_size = self.pad * .5 * mutation_size
- else:
- tooth_size = self.tooth_size * mutation_size
-
- hsz = tooth_size / 2
- width = width + 2 * pad - tooth_size
- height = height + 2 * pad - tooth_size
-
- # the sizes of the vertical and horizontal sawtooth are
- # separately adjusted to fit the given box size.
- dsx_n = round((width - tooth_size) / (tooth_size * 2)) * 2
- dsy_n = round((height - tooth_size) / (tooth_size * 2)) * 2
-
- x0, y0 = x0 - pad + hsz, y0 - pad + hsz
- x1, y1 = x0 + width, y0 + height
-
- xs = [
- x0, *np.linspace(x0 + hsz, x1 - hsz, 2 * dsx_n + 1), # bottom
- *([x1, x1 + hsz, x1, x1 - hsz] * dsy_n)[:2*dsy_n+2], # right
- x1, *np.linspace(x1 - hsz, x0 + hsz, 2 * dsx_n + 1), # top
- *([x0, x0 - hsz, x0, x0 + hsz] * dsy_n)[:2*dsy_n+2], # left
- ]
- ys = [
- *([y0, y0 - hsz, y0, y0 + hsz] * dsx_n)[:2*dsx_n+2], # bottom
- y0, *np.linspace(y0 + hsz, y1 - hsz, 2 * dsy_n + 1), # right
- *([y1, y1 + hsz, y1, y1 - hsz] * dsx_n)[:2*dsx_n+2], # top
- y1, *np.linspace(y1 - hsz, y0 + hsz, 2 * dsy_n + 1), # left
- ]
-
- return [*zip(xs, ys), (xs[0], ys[0])]
-
- def __call__(self, x0, y0, width, height, mutation_size):
- saw_vertices = self._get_sawtooth_vertices(x0, y0, width,
- height, mutation_size)
- return Path(saw_vertices, closed=True)
-
- @_register_style(_style_list)
- class Roundtooth(Sawtooth):
- """A box with a rounded sawtooth outline."""
-
- def __call__(self, x0, y0, width, height, mutation_size):
- saw_vertices = self._get_sawtooth_vertices(x0, y0,
- width, height,
- mutation_size)
- # Add a trailing vertex to allow us to close the polygon correctly
- saw_vertices = np.concatenate([saw_vertices, [saw_vertices[0]]])
- codes = ([Path.MOVETO] +
- [Path.CURVE3, Path.CURVE3] * ((len(saw_vertices)-1)//2) +
- [Path.CLOSEPOLY])
- return Path(saw_vertices, codes)
-
-
-@_docstring.dedent_interpd
-class ConnectionStyle(_Style):
- """
- `ConnectionStyle` is a container class which defines
- several connectionstyle classes, which is used to create a path
- between two points. These are mainly used with `FancyArrowPatch`.
-
- A connectionstyle object can be either created as::
-
- ConnectionStyle.Arc3(rad=0.2)
-
- or::
-
- ConnectionStyle("Arc3", rad=0.2)
-
- or::
-
- ConnectionStyle("Arc3, rad=0.2")
-
- The following classes are defined
-
- %(ConnectionStyle:table)s
-
- An instance of any connection style class is a callable object,
- whose call signature is::
-
- __call__(self, posA, posB,
- patchA=None, patchB=None,
- shrinkA=2., shrinkB=2.)
-
- and it returns a `.Path` instance. *posA* and *posB* are
- tuples of (x, y) coordinates of the two points to be
- connected. *patchA* (or *patchB*) is given, the returned path is
- clipped so that it start (or end) from the boundary of the
- patch. The path is further shrunk by *shrinkA* (or *shrinkB*)
- which is given in points.
- """
-
- _style_list = {}
-
- class _Base:
- """
- A base class for connectionstyle classes. The subclass needs
- to implement a *connect* method whose call signature is::
-
- connect(posA, posB)
-
- where posA and posB are tuples of x, y coordinates to be
- connected. The method needs to return a path connecting two
- points. This base class defines a __call__ method, and a few
- helper methods.
- """
-
- @_api.deprecated("3.7")
- class SimpleEvent:
- def __init__(self, xy):
- self.x, self.y = xy
-
- def _in_patch(self, patch):
- """
- Return a predicate function testing whether a point *xy* is
- contained in *patch*.
- """
- return lambda xy: patch.contains(
- SimpleNamespace(x=xy[0], y=xy[1]))[0]
-
- def _clip(self, path, in_start, in_stop):
- """
- Clip *path* at its start by the region where *in_start* returns
- True, and at its stop by the region where *in_stop* returns True.
-
- The original path is assumed to start in the *in_start* region and
- to stop in the *in_stop* region.
- """
- if in_start:
- try:
- _, path = split_path_inout(path, in_start)
- except ValueError:
- pass
- if in_stop:
- try:
- path, _ = split_path_inout(path, in_stop)
- except ValueError:
- pass
- return path
-
- def __call__(self, posA, posB,
- shrinkA=2., shrinkB=2., patchA=None, patchB=None):
- """
- Call the *connect* method to create a path between *posA* and
- *posB*; then clip and shrink the path.
- """
- path = self.connect(posA, posB)
- path = self._clip(
- path,
- self._in_patch(patchA) if patchA else None,
- self._in_patch(patchB) if patchB else None,
- )
- path = self._clip(
- path,
- inside_circle(*path.vertices[0], shrinkA) if shrinkA else None,
- inside_circle(*path.vertices[-1], shrinkB) if shrinkB else None
- )
- return path
-
- @_register_style(_style_list)
- class Arc3(_Base):
- """
- Creates a simple quadratic Bézier curve between two
- points. The curve is created so that the middle control point
- (C1) is located at the same distance from the start (C0) and
- end points(C2) and the distance of the C1 to the line
- connecting C0-C2 is *rad* times the distance of C0-C2.
- """
-
- def __init__(self, rad=0.):
- """
- Parameters
- ----------
- rad : float
- Curvature of the curve.
- """
- self.rad = rad
-
- def connect(self, posA, posB):
- x1, y1 = posA
- x2, y2 = posB
- x12, y12 = (x1 + x2) / 2., (y1 + y2) / 2.
- dx, dy = x2 - x1, y2 - y1
-
- f = self.rad
-
- cx, cy = x12 + f * dy, y12 - f * dx
-
- vertices = [(x1, y1),
- (cx, cy),
- (x2, y2)]
- codes = [Path.MOVETO,
- Path.CURVE3,
- Path.CURVE3]
-
- return Path(vertices, codes)
-
- @_register_style(_style_list)
- class Angle3(_Base):
- """
- Creates a simple quadratic Bézier curve between two points. The middle
- control point is placed at the intersecting point of two lines which
- cross the start and end point, and have a slope of *angleA* and
- *angleB*, respectively.
- """
-
- def __init__(self, angleA=90, angleB=0):
- """
- Parameters
- ----------
- angleA : float
- Starting angle of the path.
-
- angleB : float
- Ending angle of the path.
- """
-
- self.angleA = angleA
- self.angleB = angleB
-
- def connect(self, posA, posB):
- x1, y1 = posA
- x2, y2 = posB
-
- cosA = math.cos(math.radians(self.angleA))
- sinA = math.sin(math.radians(self.angleA))
- cosB = math.cos(math.radians(self.angleB))
- sinB = math.sin(math.radians(self.angleB))
-
- cx, cy = get_intersection(x1, y1, cosA, sinA,
- x2, y2, cosB, sinB)
-
- vertices = [(x1, y1), (cx, cy), (x2, y2)]
- codes = [Path.MOVETO, Path.CURVE3, Path.CURVE3]
-
- return Path(vertices, codes)
-
- @_register_style(_style_list)
- class Angle(_Base):
- """
- Creates a piecewise continuous quadratic Bézier path between two
- points. The path has a one passing-through point placed at the
- intersecting point of two lines which cross the start and end point,
- and have a slope of *angleA* and *angleB*, respectively.
- The connecting edges are rounded with *rad*.
- """
-
- def __init__(self, angleA=90, angleB=0, rad=0.):
- """
- Parameters
- ----------
- angleA : float
- Starting angle of the path.
-
- angleB : float
- Ending angle of the path.
-
- rad : float
- Rounding radius of the edge.
- """
-
- self.angleA = angleA
- self.angleB = angleB
-
- self.rad = rad
-
- def connect(self, posA, posB):
- x1, y1 = posA
- x2, y2 = posB
-
- cosA = math.cos(math.radians(self.angleA))
- sinA = math.sin(math.radians(self.angleA))
- cosB = math.cos(math.radians(self.angleB))
- sinB = math.sin(math.radians(self.angleB))
-
- cx, cy = get_intersection(x1, y1, cosA, sinA,
- x2, y2, cosB, sinB)
-
- vertices = [(x1, y1)]
- codes = [Path.MOVETO]
-
- if self.rad == 0.:
- vertices.append((cx, cy))
- codes.append(Path.LINETO)
- else:
- dx1, dy1 = x1 - cx, y1 - cy
- d1 = np.hypot(dx1, dy1)
- f1 = self.rad / d1
- dx2, dy2 = x2 - cx, y2 - cy
- d2 = np.hypot(dx2, dy2)
- f2 = self.rad / d2
- vertices.extend([(cx + dx1 * f1, cy + dy1 * f1),
- (cx, cy),
- (cx + dx2 * f2, cy + dy2 * f2)])
- codes.extend([Path.LINETO, Path.CURVE3, Path.CURVE3])
-
- vertices.append((x2, y2))
- codes.append(Path.LINETO)
-
- return Path(vertices, codes)
-
- @_register_style(_style_list)
- class Arc(_Base):
- """
- Creates a piecewise continuous quadratic Bézier path between two
- points. The path can have two passing-through points, a
- point placed at the distance of *armA* and angle of *angleA* from
- point A, another point with respect to point B. The edges are
- rounded with *rad*.
- """
-
- def __init__(self, angleA=0, angleB=0, armA=None, armB=None, rad=0.):
- """
- Parameters
- ----------
- angleA : float
- Starting angle of the path.
-
- angleB : float
- Ending angle of the path.
-
- armA : float or None
- Length of the starting arm.
-
- armB : float or None
- Length of the ending arm.
-
- rad : float
- Rounding radius of the edges.
- """
-
- self.angleA = angleA
- self.angleB = angleB
- self.armA = armA
- self.armB = armB
-
- self.rad = rad
-
- def connect(self, posA, posB):
- x1, y1 = posA
- x2, y2 = posB
-
- vertices = [(x1, y1)]
- rounded = []
- codes = [Path.MOVETO]
-
- if self.armA:
- cosA = math.cos(math.radians(self.angleA))
- sinA = math.sin(math.radians(self.angleA))
- # x_armA, y_armB
- d = self.armA - self.rad
- rounded.append((x1 + d * cosA, y1 + d * sinA))
- d = self.armA
- rounded.append((x1 + d * cosA, y1 + d * sinA))
-
- if self.armB:
- cosB = math.cos(math.radians(self.angleB))
- sinB = math.sin(math.radians(self.angleB))
- x_armB, y_armB = x2 + self.armB * cosB, y2 + self.armB * sinB
-
- if rounded:
- xp, yp = rounded[-1]
- dx, dy = x_armB - xp, y_armB - yp
- dd = (dx * dx + dy * dy) ** .5
-
- rounded.append((xp + self.rad * dx / dd,
- yp + self.rad * dy / dd))
- vertices.extend(rounded)
- codes.extend([Path.LINETO,
- Path.CURVE3,
- Path.CURVE3])
- else:
- xp, yp = vertices[-1]
- dx, dy = x_armB - xp, y_armB - yp
- dd = (dx * dx + dy * dy) ** .5
-
- d = dd - self.rad
- rounded = [(xp + d * dx / dd, yp + d * dy / dd),
- (x_armB, y_armB)]
-
- if rounded:
- xp, yp = rounded[-1]
- dx, dy = x2 - xp, y2 - yp
- dd = (dx * dx + dy * dy) ** .5
-
- rounded.append((xp + self.rad * dx / dd,
- yp + self.rad * dy / dd))
- vertices.extend(rounded)
- codes.extend([Path.LINETO,
- Path.CURVE3,
- Path.CURVE3])
-
- vertices.append((x2, y2))
- codes.append(Path.LINETO)
-
- return Path(vertices, codes)
-
- @_register_style(_style_list)
- class Bar(_Base):
- """
- A line with *angle* between A and B with *armA* and *armB*. One of the
- arms is extended so that they are connected in a right angle. The
- length of *armA* is determined by (*armA* + *fraction* x AB distance).
- Same for *armB*.
- """
-
- def __init__(self, armA=0., armB=0., fraction=0.3, angle=None):
- """
- Parameters
- ----------
- armA : float
- Minimum length of armA.
-
- armB : float
- Minimum length of armB.
-
- fraction : float
- A fraction of the distance between two points that will be
- added to armA and armB.
-
- angle : float or None
- Angle of the connecting line (if None, parallel to A and B).
- """
- self.armA = armA
- self.armB = armB
- self.fraction = fraction
- self.angle = angle
-
- def connect(self, posA, posB):
- x1, y1 = posA
- x20, y20 = x2, y2 = posB
-
- theta1 = math.atan2(y2 - y1, x2 - x1)
- dx, dy = x2 - x1, y2 - y1
- dd = (dx * dx + dy * dy) ** .5
- ddx, ddy = dx / dd, dy / dd
-
- armA, armB = self.armA, self.armB
-
- if self.angle is not None:
- theta0 = np.deg2rad(self.angle)
- dtheta = theta1 - theta0
- dl = dd * math.sin(dtheta)
- dL = dd * math.cos(dtheta)
- x2, y2 = x1 + dL * math.cos(theta0), y1 + dL * math.sin(theta0)
- armB = armB - dl
-
- # update
- dx, dy = x2 - x1, y2 - y1
- dd2 = (dx * dx + dy * dy) ** .5
- ddx, ddy = dx / dd2, dy / dd2
-
- arm = max(armA, armB)
- f = self.fraction * dd + arm
-
- cx1, cy1 = x1 + f * ddy, y1 - f * ddx
- cx2, cy2 = x2 + f * ddy, y2 - f * ddx
-
- vertices = [(x1, y1),
- (cx1, cy1),
- (cx2, cy2),
- (x20, y20)]
- codes = [Path.MOVETO,
- Path.LINETO,
- Path.LINETO,
- Path.LINETO]
-
- return Path(vertices, codes)
-
-
-def _point_along_a_line(x0, y0, x1, y1, d):
- """
- Return the point on the line connecting (*x0*, *y0*) -- (*x1*, *y1*) whose
- distance from (*x0*, *y0*) is *d*.
- """
- dx, dy = x0 - x1, y0 - y1
- ff = d / (dx * dx + dy * dy) ** .5
- x2, y2 = x0 - ff * dx, y0 - ff * dy
-
- return x2, y2
-
-
-@_docstring.dedent_interpd
-class ArrowStyle(_Style):
- """
- `ArrowStyle` is a container class which defines several
- arrowstyle classes, which is used to create an arrow path along a
- given path. These are mainly used with `FancyArrowPatch`.
-
- An arrowstyle object can be either created as::
-
- ArrowStyle.Fancy(head_length=.4, head_width=.4, tail_width=.4)
-
- or::
-
- ArrowStyle("Fancy", head_length=.4, head_width=.4, tail_width=.4)
-
- or::
-
- ArrowStyle("Fancy, head_length=.4, head_width=.4, tail_width=.4")
-
- The following classes are defined
-
- %(ArrowStyle:table)s
-
- For an overview of the visual appearance, see
- :doc:`/gallery/text_labels_and_annotations/fancyarrow_demo`.
-
- An instance of any arrow style class is a callable object,
- whose call signature is::
-
- __call__(self, path, mutation_size, linewidth, aspect_ratio=1.)
-
- and it returns a tuple of a `.Path` instance and a boolean
- value. *path* is a `.Path` instance along which the arrow
- will be drawn. *mutation_size* and *aspect_ratio* have the same
- meaning as in `BoxStyle`. *linewidth* is a line width to be
- stroked. This is meant to be used to correct the location of the
- head so that it does not overshoot the destination point, but not all
- classes support it.
-
- Notes
- -----
- *angleA* and *angleB* specify the orientation of the bracket, as either a
- clockwise or counterclockwise angle depending on the arrow type. 0 degrees
- means perpendicular to the line connecting the arrow's head and tail.
-
- .. plot:: gallery/text_labels_and_annotations/angles_on_bracket_arrows.py
- """
-
- _style_list = {}
-
- class _Base:
- """
- Arrow Transmuter Base class
-
- ArrowTransmuterBase and its derivatives are used to make a fancy
- arrow around a given path. The __call__ method returns a path
- (which will be used to create a PathPatch instance) and a boolean
- value indicating the path is open therefore is not fillable. This
- class is not an artist and actual drawing of the fancy arrow is
- done by the FancyArrowPatch class.
- """
-
- # The derived classes are required to be able to be initialized
- # w/o arguments, i.e., all its argument (except self) must have
- # the default values.
-
- @staticmethod
- def ensure_quadratic_bezier(path):
- """
- Some ArrowStyle classes only works with a simple quadratic
- Bézier curve (created with `.ConnectionStyle.Arc3` or
- `.ConnectionStyle.Angle3`). This static method checks if the
- provided path is a simple quadratic Bézier curve and returns its
- control points if true.
- """
- segments = list(path.iter_segments())
- if (len(segments) != 2 or segments[0][1] != Path.MOVETO or
- segments[1][1] != Path.CURVE3):
- raise ValueError(
- "'path' is not a valid quadratic Bezier curve")
- return [*segments[0][0], *segments[1][0]]
-
- def transmute(self, path, mutation_size, linewidth):
- """
- The transmute method is the very core of the ArrowStyle class and
- must be overridden in the subclasses. It receives the *path*
- object along which the arrow will be drawn, and the
- *mutation_size*, with which the arrow head etc. will be scaled.
- The *linewidth* may be used to adjust the path so that it does not
- pass beyond the given points. It returns a tuple of a `.Path`
- instance and a boolean. The boolean value indicate whether the
- path can be filled or not. The return value can also be a list of
- paths and list of booleans of the same length.
- """
- raise NotImplementedError('Derived must override')
-
- def __call__(self, path, mutation_size, linewidth,
- aspect_ratio=1.):
- """
- The __call__ method is a thin wrapper around the transmute method
- and takes care of the aspect ratio.
- """
-
- if aspect_ratio is not None:
- # Squeeze the given height by the aspect_ratio
- vertices = path.vertices / [1, aspect_ratio]
- path_shrunk = Path(vertices, path.codes)
- # call transmute method with squeezed height.
- path_mutated, fillable = self.transmute(path_shrunk,
- mutation_size,
- linewidth)
- if np.iterable(fillable):
- # Restore the height
- path_list = [Path(p.vertices * [1, aspect_ratio], p.codes)
- for p in path_mutated]
- return path_list, fillable
- else:
- return path_mutated, fillable
- else:
- return self.transmute(path, mutation_size, linewidth)
-
- class _Curve(_Base):
- """
- A simple arrow which will work with any path instance. The
- returned path is the concatenation of the original path, and at
- most two paths representing the arrow head or bracket at the start
- point and at the end point. The arrow heads can be either open
- or closed.
- """
-
- arrow = "-"
- fillbegin = fillend = False # Whether arrows are filled.
-
- def __init__(self, head_length=.4, head_width=.2, widthA=1., widthB=1.,
- lengthA=0.2, lengthB=0.2, angleA=0, angleB=0, scaleA=None,
- scaleB=None):
- """
- Parameters
- ----------
- head_length : float, default: 0.4
- Length of the arrow head, relative to *mutation_size*.
- head_width : float, default: 0.2
- Width of the arrow head, relative to *mutation_size*.
- widthA, widthB : float, default: 1.0
- Width of the bracket.
- lengthA, lengthB : float, default: 0.2
- Length of the bracket.
- angleA, angleB : float, default: 0
- Orientation of the bracket, as a counterclockwise angle.
- 0 degrees means perpendicular to the line.
- scaleA, scaleB : float, default: *mutation_size*
- The scale of the brackets.
- """
-
- self.head_length, self.head_width = head_length, head_width
- self.widthA, self.widthB = widthA, widthB
- self.lengthA, self.lengthB = lengthA, lengthB
- self.angleA, self.angleB = angleA, angleB
- self.scaleA, self.scaleB = scaleA, scaleB
-
- self._beginarrow_head = False
- self._beginarrow_bracket = False
- self._endarrow_head = False
- self._endarrow_bracket = False
-
- if "-" not in self.arrow:
- raise ValueError("arrow must have the '-' between "
- "the two heads")
-
- beginarrow, endarrow = self.arrow.split("-", 1)
-
- if beginarrow == "<":
- self._beginarrow_head = True
- self._beginarrow_bracket = False
- elif beginarrow == "<|":
- self._beginarrow_head = True
- self._beginarrow_bracket = False
- self.fillbegin = True
- elif beginarrow in ("]", "|"):
- self._beginarrow_head = False
- self._beginarrow_bracket = True
-
- if endarrow == ">":
- self._endarrow_head = True
- self._endarrow_bracket = False
- elif endarrow == "|>":
- self._endarrow_head = True
- self._endarrow_bracket = False
- self.fillend = True
- elif endarrow in ("[", "|"):
- self._endarrow_head = False
- self._endarrow_bracket = True
-
- super().__init__()
-
- def _get_arrow_wedge(self, x0, y0, x1, y1,
- head_dist, cos_t, sin_t, linewidth):
- """
- Return the paths for arrow heads. Since arrow lines are
- drawn with capstyle=projected, The arrow goes beyond the
- desired point. This method also returns the amount of the path
- to be shrunken so that it does not overshoot.
- """
-
- # arrow from x0, y0 to x1, y1
- dx, dy = x0 - x1, y0 - y1
-
- cp_distance = np.hypot(dx, dy)
-
- # pad_projected : amount of pad to account the
- # overshooting of the projection of the wedge
- pad_projected = (.5 * linewidth / sin_t)
-
- # Account for division by zero
- if cp_distance == 0:
- cp_distance = 1
-
- # apply pad for projected edge
- ddx = pad_projected * dx / cp_distance
- ddy = pad_projected * dy / cp_distance
-
- # offset for arrow wedge
- dx = dx / cp_distance * head_dist
- dy = dy / cp_distance * head_dist
-
- dx1, dy1 = cos_t * dx + sin_t * dy, -sin_t * dx + cos_t * dy
- dx2, dy2 = cos_t * dx - sin_t * dy, sin_t * dx + cos_t * dy
-
- vertices_arrow = [(x1 + ddx + dx1, y1 + ddy + dy1),
- (x1 + ddx, y1 + ddy),
- (x1 + ddx + dx2, y1 + ddy + dy2)]
- codes_arrow = [Path.MOVETO,
- Path.LINETO,
- Path.LINETO]
-
- return vertices_arrow, codes_arrow, ddx, ddy
-
- def _get_bracket(self, x0, y0,
- x1, y1, width, length, angle):
-
- cos_t, sin_t = get_cos_sin(x1, y1, x0, y0)
-
- # arrow from x0, y0 to x1, y1
- from matplotlib.bezier import get_normal_points
- x1, y1, x2, y2 = get_normal_points(x0, y0, cos_t, sin_t, width)
-
- dx, dy = length * cos_t, length * sin_t
-
- vertices_arrow = [(x1 + dx, y1 + dy),
- (x1, y1),
- (x2, y2),
- (x2 + dx, y2 + dy)]
- codes_arrow = [Path.MOVETO,
- Path.LINETO,
- Path.LINETO,
- Path.LINETO]
-
- if angle:
- trans = transforms.Affine2D().rotate_deg_around(x0, y0, angle)
- vertices_arrow = trans.transform(vertices_arrow)
-
- return vertices_arrow, codes_arrow
-
- def transmute(self, path, mutation_size, linewidth):
- # docstring inherited
- if self._beginarrow_head or self._endarrow_head:
- head_length = self.head_length * mutation_size
- head_width = self.head_width * mutation_size
- head_dist = np.hypot(head_length, head_width)
- cos_t, sin_t = head_length / head_dist, head_width / head_dist
-
- scaleA = mutation_size if self.scaleA is None else self.scaleA
- scaleB = mutation_size if self.scaleB is None else self.scaleB
-
- # begin arrow
- x0, y0 = path.vertices[0]
- x1, y1 = path.vertices[1]
-
- # If there is no room for an arrow and a line, then skip the arrow
- has_begin_arrow = self._beginarrow_head and (x0, y0) != (x1, y1)
- verticesA, codesA, ddxA, ddyA = (
- self._get_arrow_wedge(x1, y1, x0, y0,
- head_dist, cos_t, sin_t, linewidth)
- if has_begin_arrow
- else ([], [], 0, 0)
- )
-
- # end arrow
- x2, y2 = path.vertices[-2]
- x3, y3 = path.vertices[-1]
-
- # If there is no room for an arrow and a line, then skip the arrow
- has_end_arrow = self._endarrow_head and (x2, y2) != (x3, y3)
- verticesB, codesB, ddxB, ddyB = (
- self._get_arrow_wedge(x2, y2, x3, y3,
- head_dist, cos_t, sin_t, linewidth)
- if has_end_arrow
- else ([], [], 0, 0)
- )
-
- # This simple code will not work if ddx, ddy is greater than the
- # separation between vertices.
- paths = [Path(np.concatenate([[(x0 + ddxA, y0 + ddyA)],
- path.vertices[1:-1],
- [(x3 + ddxB, y3 + ddyB)]]),
- path.codes)]
- fills = [False]
-
- if has_begin_arrow:
- if self.fillbegin:
- paths.append(
- Path([*verticesA, (0, 0)], [*codesA, Path.CLOSEPOLY]))
- fills.append(True)
- else:
- paths.append(Path(verticesA, codesA))
- fills.append(False)
- elif self._beginarrow_bracket:
- x0, y0 = path.vertices[0]
- x1, y1 = path.vertices[1]
- verticesA, codesA = self._get_bracket(x0, y0, x1, y1,
- self.widthA * scaleA,
- self.lengthA * scaleA,
- self.angleA)
-
- paths.append(Path(verticesA, codesA))
- fills.append(False)
-
- if has_end_arrow:
- if self.fillend:
- fills.append(True)
- paths.append(
- Path([*verticesB, (0, 0)], [*codesB, Path.CLOSEPOLY]))
- else:
- fills.append(False)
- paths.append(Path(verticesB, codesB))
- elif self._endarrow_bracket:
- x0, y0 = path.vertices[-1]
- x1, y1 = path.vertices[-2]
- verticesB, codesB = self._get_bracket(x0, y0, x1, y1,
- self.widthB * scaleB,
- self.lengthB * scaleB,
- self.angleB)
-
- paths.append(Path(verticesB, codesB))
- fills.append(False)
-
- return paths, fills
-
- @_register_style(_style_list, name="-")
- class Curve(_Curve):
- """A simple curve without any arrow head."""
-
- def __init__(self): # hide head_length, head_width
- # These attributes (whose values come from backcompat) only matter
- # if someone modifies beginarrow/etc. on an ArrowStyle instance.
- super().__init__(head_length=.2, head_width=.1)
-
- @_register_style(_style_list, name="<-")
- class CurveA(_Curve):
- """An arrow with a head at its start point."""
- arrow = "<-"
-
- @_register_style(_style_list, name="->")
- class CurveB(_Curve):
- """An arrow with a head at its end point."""
- arrow = "->"
-
- @_register_style(_style_list, name="<->")
- class CurveAB(_Curve):
- """An arrow with heads both at the start and the end point."""
- arrow = "<->"
-
- @_register_style(_style_list, name="<|-")
- class CurveFilledA(_Curve):
- """An arrow with filled triangle head at the start."""
- arrow = "<|-"
-
- @_register_style(_style_list, name="-|>")
- class CurveFilledB(_Curve):
- """An arrow with filled triangle head at the end."""
- arrow = "-|>"
-
- @_register_style(_style_list, name="<|-|>")
- class CurveFilledAB(_Curve):
- """An arrow with filled triangle heads at both ends."""
- arrow = "<|-|>"
-
- @_register_style(_style_list, name="]-")
- class BracketA(_Curve):
- """An arrow with an outward square bracket at its start."""
- arrow = "]-"
-
- def __init__(self, widthA=1., lengthA=0.2, angleA=0):
- """
- Parameters
- ----------
- widthA : float, default: 1.0
- Width of the bracket.
- lengthA : float, default: 0.2
- Length of the bracket.
- angleA : float, default: 0 degrees
- Orientation of the bracket, as a counterclockwise angle.
- 0 degrees means perpendicular to the line.
- """
- super().__init__(widthA=widthA, lengthA=lengthA, angleA=angleA)
-
- @_register_style(_style_list, name="-[")
- class BracketB(_Curve):
- """An arrow with an outward square bracket at its end."""
- arrow = "-["
-
- def __init__(self, widthB=1., lengthB=0.2, angleB=0):
- """
- Parameters
- ----------
- widthB : float, default: 1.0
- Width of the bracket.
- lengthB : float, default: 0.2
- Length of the bracket.
- angleB : float, default: 0 degrees
- Orientation of the bracket, as a counterclockwise angle.
- 0 degrees means perpendicular to the line.
- """
- super().__init__(widthB=widthB, lengthB=lengthB, angleB=angleB)
-
- @_register_style(_style_list, name="]-[")
- class BracketAB(_Curve):
- """An arrow with outward square brackets at both ends."""
- arrow = "]-["
-
- def __init__(self,
- widthA=1., lengthA=0.2, angleA=0,
- widthB=1., lengthB=0.2, angleB=0):
- """
- Parameters
- ----------
- widthA, widthB : float, default: 1.0
- Width of the bracket.
- lengthA, lengthB : float, default: 0.2
- Length of the bracket.
- angleA, angleB : float, default: 0 degrees
- Orientation of the bracket, as a counterclockwise angle.
- 0 degrees means perpendicular to the line.
- """
- super().__init__(widthA=widthA, lengthA=lengthA, angleA=angleA,
- widthB=widthB, lengthB=lengthB, angleB=angleB)
-
- @_register_style(_style_list, name="|-|")
- class BarAB(_Curve):
- """An arrow with vertical bars ``|`` at both ends."""
- arrow = "|-|"
-
- def __init__(self, widthA=1., angleA=0, widthB=1., angleB=0):
- """
- Parameters
- ----------
- widthA, widthB : float, default: 1.0
- Width of the bracket.
- angleA, angleB : float, default: 0 degrees
- Orientation of the bracket, as a counterclockwise angle.
- 0 degrees means perpendicular to the line.
- """
- super().__init__(widthA=widthA, lengthA=0, angleA=angleA,
- widthB=widthB, lengthB=0, angleB=angleB)
-
- @_register_style(_style_list, name=']->')
- class BracketCurve(_Curve):
- """
- An arrow with an outward square bracket at its start and a head at
- the end.
- """
- arrow = "]->"
-
- def __init__(self, widthA=1., lengthA=0.2, angleA=None):
- """
- Parameters
- ----------
- widthA : float, default: 1.0
- Width of the bracket.
- lengthA : float, default: 0.2
- Length of the bracket.
- angleA : float, default: 0 degrees
- Orientation of the bracket, as a counterclockwise angle.
- 0 degrees means perpendicular to the line.
- """
- super().__init__(widthA=widthA, lengthA=lengthA, angleA=angleA)
-
- @_register_style(_style_list, name='<-[')
- class CurveBracket(_Curve):
- """
- An arrow with an outward square bracket at its end and a head at
- the start.
- """
- arrow = "<-["
-
- def __init__(self, widthB=1., lengthB=0.2, angleB=None):
- """
- Parameters
- ----------
- widthB : float, default: 1.0
- Width of the bracket.
- lengthB : float, default: 0.2
- Length of the bracket.
- angleB : float, default: 0 degrees
- Orientation of the bracket, as a counterclockwise angle.
- 0 degrees means perpendicular to the line.
- """
- super().__init__(widthB=widthB, lengthB=lengthB, angleB=angleB)
-
- @_register_style(_style_list)
- class Simple(_Base):
- """A simple arrow. Only works with a quadratic Bézier curve."""
-
- def __init__(self, head_length=.5, head_width=.5, tail_width=.2):
- """
- Parameters
- ----------
- head_length : float, default: 0.5
- Length of the arrow head.
-
- head_width : float, default: 0.5
- Width of the arrow head.
-
- tail_width : float, default: 0.2
- Width of the arrow tail.
- """
- self.head_length, self.head_width, self.tail_width = \
- head_length, head_width, tail_width
- super().__init__()
-
- def transmute(self, path, mutation_size, linewidth):
- # docstring inherited
- x0, y0, x1, y1, x2, y2 = self.ensure_quadratic_bezier(path)
-
- # divide the path into a head and a tail
- head_length = self.head_length * mutation_size
- in_f = inside_circle(x2, y2, head_length)
- arrow_path = [(x0, y0), (x1, y1), (x2, y2)]
-
- try:
- arrow_out, arrow_in = \
- split_bezier_intersecting_with_closedpath(arrow_path, in_f)
- except NonIntersectingPathException:
- # if this happens, make a straight line of the head_length
- # long.
- x0, y0 = _point_along_a_line(x2, y2, x1, y1, head_length)
- x1n, y1n = 0.5 * (x0 + x2), 0.5 * (y0 + y2)
- arrow_in = [(x0, y0), (x1n, y1n), (x2, y2)]
- arrow_out = None
-
- # head
- head_width = self.head_width * mutation_size
- head_left, head_right = make_wedged_bezier2(arrow_in,
- head_width / 2., wm=.5)
-
- # tail
- if arrow_out is not None:
- tail_width = self.tail_width * mutation_size
- tail_left, tail_right = get_parallels(arrow_out,
- tail_width / 2.)
-
- patch_path = [(Path.MOVETO, tail_right[0]),
- (Path.CURVE3, tail_right[1]),
- (Path.CURVE3, tail_right[2]),
- (Path.LINETO, head_right[0]),
- (Path.CURVE3, head_right[1]),
- (Path.CURVE3, head_right[2]),
- (Path.CURVE3, head_left[1]),
- (Path.CURVE3, head_left[0]),
- (Path.LINETO, tail_left[2]),
- (Path.CURVE3, tail_left[1]),
- (Path.CURVE3, tail_left[0]),
- (Path.LINETO, tail_right[0]),
- (Path.CLOSEPOLY, tail_right[0]),
- ]
- else:
- patch_path = [(Path.MOVETO, head_right[0]),
- (Path.CURVE3, head_right[1]),
- (Path.CURVE3, head_right[2]),
- (Path.CURVE3, head_left[1]),
- (Path.CURVE3, head_left[0]),
- (Path.CLOSEPOLY, head_left[0]),
- ]
-
- path = Path([p for c, p in patch_path], [c for c, p in patch_path])
-
- return path, True
-
- @_register_style(_style_list)
- class Fancy(_Base):
- """A fancy arrow. Only works with a quadratic Bézier curve."""
-
- def __init__(self, head_length=.4, head_width=.4, tail_width=.4):
- """
- Parameters
- ----------
- head_length : float, default: 0.4
- Length of the arrow head.
-
- head_width : float, default: 0.4
- Width of the arrow head.
-
- tail_width : float, default: 0.4
- Width of the arrow tail.
- """
- self.head_length, self.head_width, self.tail_width = \
- head_length, head_width, tail_width
- super().__init__()
-
- def transmute(self, path, mutation_size, linewidth):
- # docstring inherited
- x0, y0, x1, y1, x2, y2 = self.ensure_quadratic_bezier(path)
-
- # divide the path into a head and a tail
- head_length = self.head_length * mutation_size
- arrow_path = [(x0, y0), (x1, y1), (x2, y2)]
-
- # path for head
- in_f = inside_circle(x2, y2, head_length)
- try:
- path_out, path_in = split_bezier_intersecting_with_closedpath(
- arrow_path, in_f)
- except NonIntersectingPathException:
- # if this happens, make a straight line of the head_length
- # long.
- x0, y0 = _point_along_a_line(x2, y2, x1, y1, head_length)
- x1n, y1n = 0.5 * (x0 + x2), 0.5 * (y0 + y2)
- arrow_path = [(x0, y0), (x1n, y1n), (x2, y2)]
- path_head = arrow_path
- else:
- path_head = path_in
-
- # path for head
- in_f = inside_circle(x2, y2, head_length * .8)
- path_out, path_in = split_bezier_intersecting_with_closedpath(
- arrow_path, in_f)
- path_tail = path_out
-
- # head
- head_width = self.head_width * mutation_size
- head_l, head_r = make_wedged_bezier2(path_head,
- head_width / 2.,
- wm=.6)
-
- # tail
- tail_width = self.tail_width * mutation_size
- tail_left, tail_right = make_wedged_bezier2(path_tail,
- tail_width * .5,
- w1=1., wm=0.6, w2=0.3)
-
- # path for head
- in_f = inside_circle(x0, y0, tail_width * .3)
- path_in, path_out = split_bezier_intersecting_with_closedpath(
- arrow_path, in_f)
- tail_start = path_in[-1]
-
- head_right, head_left = head_r, head_l
- patch_path = [(Path.MOVETO, tail_start),
- (Path.LINETO, tail_right[0]),
- (Path.CURVE3, tail_right[1]),
- (Path.CURVE3, tail_right[2]),
- (Path.LINETO, head_right[0]),
- (Path.CURVE3, head_right[1]),
- (Path.CURVE3, head_right[2]),
- (Path.CURVE3, head_left[1]),
- (Path.CURVE3, head_left[0]),
- (Path.LINETO, tail_left[2]),
- (Path.CURVE3, tail_left[1]),
- (Path.CURVE3, tail_left[0]),
- (Path.LINETO, tail_start),
- (Path.CLOSEPOLY, tail_start),
- ]
- path = Path([p for c, p in patch_path], [c for c, p in patch_path])
-
- return path, True
-
- @_register_style(_style_list)
- class Wedge(_Base):
- """
- Wedge(?) shape. Only works with a quadratic Bézier curve. The
- start point has a width of the *tail_width* and the end point has a
- width of 0. At the middle, the width is *shrink_factor*x*tail_width*.
- """
-
- def __init__(self, tail_width=.3, shrink_factor=0.5):
- """
- Parameters
- ----------
- tail_width : float, default: 0.3
- Width of the tail.
-
- shrink_factor : float, default: 0.5
- Fraction of the arrow width at the middle point.
- """
- self.tail_width = tail_width
- self.shrink_factor = shrink_factor
- super().__init__()
-
- def transmute(self, path, mutation_size, linewidth):
- # docstring inherited
- x0, y0, x1, y1, x2, y2 = self.ensure_quadratic_bezier(path)
-
- arrow_path = [(x0, y0), (x1, y1), (x2, y2)]
- b_plus, b_minus = make_wedged_bezier2(
- arrow_path,
- self.tail_width * mutation_size / 2.,
- wm=self.shrink_factor)
-
- patch_path = [(Path.MOVETO, b_plus[0]),
- (Path.CURVE3, b_plus[1]),
- (Path.CURVE3, b_plus[2]),
- (Path.LINETO, b_minus[2]),
- (Path.CURVE3, b_minus[1]),
- (Path.CURVE3, b_minus[0]),
- (Path.CLOSEPOLY, b_minus[0]),
- ]
- path = Path([p for c, p in patch_path], [c for c, p in patch_path])
-
- return path, True
-
-
-class FancyBboxPatch(Patch):
- """
- A fancy box around a rectangle with lower left at *xy* = (*x*, *y*)
- with specified width and height.
-
- `.FancyBboxPatch` is similar to `.Rectangle`, but it draws a fancy box
- around the rectangle. The transformation of the rectangle box to the
- fancy box is delegated to the style classes defined in `.BoxStyle`.
- """
-
- _edge_default = True
-
- def __str__(self):
- s = self.__class__.__name__ + "((%g, %g), width=%g, height=%g)"
- return s % (self._x, self._y, self._width, self._height)
-
- @_docstring.dedent_interpd
- def __init__(self, xy, width, height, boxstyle="round", *,
- mutation_scale=1, mutation_aspect=1, **kwargs):
- """
- Parameters
- ----------
- xy : (float, float)
- The lower left corner of the box.
-
- width : float
- The width of the box.
-
- height : float
- The height of the box.
-
- boxstyle : str or `~matplotlib.patches.BoxStyle`
- The style of the fancy box. This can either be a `.BoxStyle`
- instance or a string of the style name and optionally comma
- separated attributes (e.g. "Round, pad=0.2"). This string is
- passed to `.BoxStyle` to construct a `.BoxStyle` object. See
- there for a full documentation.
-
- The following box styles are available:
-
- %(BoxStyle:table)s
-
- mutation_scale : float, default: 1
- Scaling factor applied to the attributes of the box style
- (e.g. pad or rounding_size).
-
- mutation_aspect : float, default: 1
- The height of the rectangle will be squeezed by this value before
- the mutation and the mutated box will be stretched by the inverse
- of it. For example, this allows different horizontal and vertical
- padding.
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.patches.Patch` properties
-
- %(Patch:kwdoc)s
- """
-
- super().__init__(**kwargs)
- self._x, self._y = xy
- self._width = width
- self._height = height
- self.set_boxstyle(boxstyle)
- self._mutation_scale = mutation_scale
- self._mutation_aspect = mutation_aspect
- self.stale = True
-
- @_docstring.dedent_interpd
- def set_boxstyle(self, boxstyle=None, **kwargs):
- """
- Set the box style, possibly with further attributes.
-
- Attributes from the previous box style are not reused.
-
- Without argument (or with ``boxstyle=None``), the available box styles
- are returned as a human-readable string.
-
- Parameters
- ----------
- boxstyle : str or `~matplotlib.patches.BoxStyle`
- The style of the box: either a `.BoxStyle` instance, or a string,
- which is the style name and optionally comma separated attributes
- (e.g. "Round,pad=0.2"). Such a string is used to construct a
- `.BoxStyle` object, as documented in that class.
-
- The following box styles are available:
-
- %(BoxStyle:table_and_accepts)s
-
- **kwargs
- Additional attributes for the box style. See the table above for
- supported parameters.
-
- Examples
- --------
- ::
-
- set_boxstyle("Round,pad=0.2")
- set_boxstyle("round", pad=0.2)
- """
- if boxstyle is None:
- return BoxStyle.pprint_styles()
- self._bbox_transmuter = (
- BoxStyle(boxstyle, **kwargs)
- if isinstance(boxstyle, str) else boxstyle)
- self.stale = True
-
- def get_boxstyle(self):
- """Return the boxstyle object."""
- return self._bbox_transmuter
-
- def set_mutation_scale(self, scale):
- """
- Set the mutation scale.
-
- Parameters
- ----------
- scale : float
- """
- self._mutation_scale = scale
- self.stale = True
-
- def get_mutation_scale(self):
- """Return the mutation scale."""
- return self._mutation_scale
-
- def set_mutation_aspect(self, aspect):
- """
- Set the aspect ratio of the bbox mutation.
-
- Parameters
- ----------
- aspect : float
- """
- self._mutation_aspect = aspect
- self.stale = True
-
- def get_mutation_aspect(self):
- """Return the aspect ratio of the bbox mutation."""
- return (self._mutation_aspect if self._mutation_aspect is not None
- else 1) # backcompat.
-
- def get_path(self):
- """Return the mutated path of the rectangle."""
- boxstyle = self.get_boxstyle()
- m_aspect = self.get_mutation_aspect()
- # Call boxstyle with y, height squeezed by aspect_ratio.
- path = boxstyle(self._x, self._y / m_aspect,
- self._width, self._height / m_aspect,
- self.get_mutation_scale())
- return Path(path.vertices * [1, m_aspect], path.codes) # Unsqueeze y.
-
- # Following methods are borrowed from the Rectangle class.
-
- def get_x(self):
- """Return the left coord of the rectangle."""
- return self._x
-
- def get_y(self):
- """Return the bottom coord of the rectangle."""
- return self._y
-
- def get_width(self):
- """Return the width of the rectangle."""
- return self._width
-
- def get_height(self):
- """Return the height of the rectangle."""
- return self._height
-
- def set_x(self, x):
- """
- Set the left coord of the rectangle.
-
- Parameters
- ----------
- x : float
- """
- self._x = x
- self.stale = True
-
- def set_y(self, y):
- """
- Set the bottom coord of the rectangle.
-
- Parameters
- ----------
- y : float
- """
- self._y = y
- self.stale = True
-
- def set_width(self, w):
- """
- Set the rectangle width.
-
- Parameters
- ----------
- w : float
- """
- self._width = w
- self.stale = True
-
- def set_height(self, h):
- """
- Set the rectangle height.
-
- Parameters
- ----------
- h : float
- """
- self._height = h
- self.stale = True
-
- def set_bounds(self, *args):
- """
- Set the bounds of the rectangle.
-
- Call signatures::
-
- set_bounds(left, bottom, width, height)
- set_bounds((left, bottom, width, height))
-
- Parameters
- ----------
- left, bottom : float
- The coordinates of the bottom left corner of the rectangle.
- width, height : float
- The width/height of the rectangle.
- """
- if len(args) == 1:
- l, b, w, h = args[0]
- else:
- l, b, w, h = args
- self._x = l
- self._y = b
- self._width = w
- self._height = h
- self.stale = True
-
- def get_bbox(self):
- """Return the `.Bbox`."""
- return transforms.Bbox.from_bounds(self._x, self._y,
- self._width, self._height)
-
-
-class FancyArrowPatch(Patch):
- """
- A fancy arrow patch.
-
- It draws an arrow using the `ArrowStyle`. It is primarily used by the
- `~.axes.Axes.annotate` method. For most purposes, use the annotate method for
- drawing arrows.
-
- The head and tail positions are fixed at the specified start and end points
- of the arrow, but the size and shape (in display coordinates) of the arrow
- does not change when the axis is moved or zoomed.
- """
- _edge_default = True
-
- def __str__(self):
- if self._posA_posB is not None:
- (x1, y1), (x2, y2) = self._posA_posB
- return f"{type(self).__name__}(({x1:g}, {y1:g})->({x2:g}, {y2:g}))"
- else:
- return f"{type(self).__name__}({self._path_original})"
-
- @_docstring.dedent_interpd
- def __init__(self, posA=None, posB=None, *,
- path=None, arrowstyle="simple", connectionstyle="arc3",
- patchA=None, patchB=None, shrinkA=2, shrinkB=2,
- mutation_scale=1, mutation_aspect=1, **kwargs):
- """
- There are two ways for defining an arrow:
-
- - If *posA* and *posB* are given, a path connecting two points is
- created according to *connectionstyle*. The path will be
- clipped with *patchA* and *patchB* and further shrunken by
- *shrinkA* and *shrinkB*. An arrow is drawn along this
- resulting path using the *arrowstyle* parameter.
-
- - Alternatively if *path* is provided, an arrow is drawn along this
- path and *patchA*, *patchB*, *shrinkA*, and *shrinkB* are ignored.
-
- Parameters
- ----------
- posA, posB : (float, float), default: None
- (x, y) coordinates of arrow tail and arrow head respectively.
-
- path : `~matplotlib.path.Path`, default: None
- If provided, an arrow is drawn along this path and *patchA*,
- *patchB*, *shrinkA*, and *shrinkB* are ignored.
-
- arrowstyle : str or `.ArrowStyle`, default: 'simple'
- The `.ArrowStyle` with which the fancy arrow is drawn. If a
- string, it should be one of the available arrowstyle names, with
- optional comma-separated attributes. The optional attributes are
- meant to be scaled with the *mutation_scale*. The following arrow
- styles are available:
-
- %(ArrowStyle:table)s
-
- connectionstyle : str or `.ConnectionStyle` or None, optional, \
-default: 'arc3'
- The `.ConnectionStyle` with which *posA* and *posB* are connected.
- If a string, it should be one of the available connectionstyle
- names, with optional comma-separated attributes. The following
- connection styles are available:
-
- %(ConnectionStyle:table)s
-
- patchA, patchB : `~matplotlib.patches.Patch`, default: None
- Head and tail patches, respectively.
-
- shrinkA, shrinkB : float, default: 2
- Shrinking factor of the tail and head of the arrow respectively.
-
- mutation_scale : float, default: 1
- Value with which attributes of *arrowstyle* (e.g., *head_length*)
- will be scaled.
-
- mutation_aspect : None or float, default: None
- The height of the rectangle will be squeezed by this value before
- the mutation and the mutated box will be stretched by the inverse
- of it.
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.patches.Patch` properties, optional
- Here is a list of available `.Patch` properties:
-
- %(Patch:kwdoc)s
-
- In contrast to other patches, the default ``capstyle`` and
- ``joinstyle`` for `FancyArrowPatch` are set to ``"round"``.
- """
- # Traditionally, the cap- and joinstyle for FancyArrowPatch are round
- kwargs.setdefault("joinstyle", JoinStyle.round)
- kwargs.setdefault("capstyle", CapStyle.round)
-
- super().__init__(**kwargs)
-
- if posA is not None and posB is not None and path is None:
- self._posA_posB = [posA, posB]
-
- if connectionstyle is None:
- connectionstyle = "arc3"
- self.set_connectionstyle(connectionstyle)
-
- elif posA is None and posB is None and path is not None:
- self._posA_posB = None
- else:
- raise ValueError("Either posA and posB, or path need to provided")
-
- self.patchA = patchA
- self.patchB = patchB
- self.shrinkA = shrinkA
- self.shrinkB = shrinkB
-
- self._path_original = path
-
- self.set_arrowstyle(arrowstyle)
-
- self._mutation_scale = mutation_scale
- self._mutation_aspect = mutation_aspect
-
- self._dpi_cor = 1.0
-
- def set_positions(self, posA, posB):
- """
- Set the start and end positions of the connecting path.
-
- Parameters
- ----------
- posA, posB : None, tuple
- (x, y) coordinates of arrow tail and arrow head respectively. If
- `None` use current value.
- """
- if posA is not None:
- self._posA_posB[0] = posA
- if posB is not None:
- self._posA_posB[1] = posB
- self.stale = True
-
- def set_patchA(self, patchA):
- """
- Set the tail patch.
-
- Parameters
- ----------
- patchA : `.patches.Patch`
- """
- self.patchA = patchA
- self.stale = True
-
- def set_patchB(self, patchB):
- """
- Set the head patch.
-
- Parameters
- ----------
- patchB : `.patches.Patch`
- """
- self.patchB = patchB
- self.stale = True
-
- @_docstring.dedent_interpd
- def set_connectionstyle(self, connectionstyle=None, **kwargs):
- """
- Set the connection style, possibly with further attributes.
-
- Attributes from the previous connection style are not reused.
-
- Without argument (or with ``connectionstyle=None``), the available box
- styles are returned as a human-readable string.
-
- Parameters
- ----------
- connectionstyle : str or `~matplotlib.patches.ConnectionStyle`
- The style of the connection: either a `.ConnectionStyle` instance,
- or a string, which is the style name and optionally comma separated
- attributes (e.g. "Arc,armA=30,rad=10"). Such a string is used to
- construct a `.ConnectionStyle` object, as documented in that class.
-
- The following connection styles are available:
-
- %(ConnectionStyle:table_and_accepts)s
-
- **kwargs
- Additional attributes for the connection style. See the table above
- for supported parameters.
-
- Examples
- --------
- ::
-
- set_connectionstyle("Arc,armA=30,rad=10")
- set_connectionstyle("arc", armA=30, rad=10)
- """
- if connectionstyle is None:
- return ConnectionStyle.pprint_styles()
- self._connector = (
- ConnectionStyle(connectionstyle, **kwargs)
- if isinstance(connectionstyle, str) else connectionstyle)
- self.stale = True
-
- def get_connectionstyle(self):
- """Return the `ConnectionStyle` used."""
- return self._connector
-
- def set_arrowstyle(self, arrowstyle=None, **kwargs):
- """
- Set the arrow style, possibly with further attributes.
-
- Attributes from the previous arrow style are not reused.
-
- Without argument (or with ``arrowstyle=None``), the available box
- styles are returned as a human-readable string.
-
- Parameters
- ----------
- arrowstyle : str or `~matplotlib.patches.ArrowStyle`
- The style of the arrow: either a `.ArrowStyle` instance, or a
- string, which is the style name and optionally comma separated
- attributes (e.g. "Fancy,head_length=0.2"). Such a string is used to
- construct a `.ArrowStyle` object, as documented in that class.
-
- The following arrow styles are available:
-
- %(ArrowStyle:table_and_accepts)s
-
- **kwargs
- Additional attributes for the arrow style. See the table above for
- supported parameters.
-
- Examples
- --------
- ::
-
- set_arrowstyle("Fancy,head_length=0.2")
- set_arrowstyle("fancy", head_length=0.2)
- """
- if arrowstyle is None:
- return ArrowStyle.pprint_styles()
- self._arrow_transmuter = (
- ArrowStyle(arrowstyle, **kwargs)
- if isinstance(arrowstyle, str) else arrowstyle)
- self.stale = True
-
- def get_arrowstyle(self):
- """Return the arrowstyle object."""
- return self._arrow_transmuter
-
- def set_mutation_scale(self, scale):
- """
- Set the mutation scale.
-
- Parameters
- ----------
- scale : float
- """
- self._mutation_scale = scale
- self.stale = True
-
- def get_mutation_scale(self):
- """
- Return the mutation scale.
-
- Returns
- -------
- scalar
- """
- return self._mutation_scale
-
- def set_mutation_aspect(self, aspect):
- """
- Set the aspect ratio of the bbox mutation.
-
- Parameters
- ----------
- aspect : float
- """
- self._mutation_aspect = aspect
- self.stale = True
-
- def get_mutation_aspect(self):
- """Return the aspect ratio of the bbox mutation."""
- return (self._mutation_aspect if self._mutation_aspect is not None
- else 1) # backcompat.
-
- def get_path(self):
- """Return the path of the arrow in the data coordinates."""
- # The path is generated in display coordinates, then converted back to
- # data coordinates.
- _path, fillable = self._get_path_in_displaycoord()
- if np.iterable(fillable):
- _path = Path.make_compound_path(*_path)
- return self.get_transform().inverted().transform_path(_path)
-
- def _get_path_in_displaycoord(self):
- """Return the mutated path of the arrow in display coordinates."""
- dpi_cor = self._dpi_cor
-
- if self._posA_posB is not None:
- posA = self._convert_xy_units(self._posA_posB[0])
- posB = self._convert_xy_units(self._posA_posB[1])
- (posA, posB) = self.get_transform().transform((posA, posB))
- _path = self.get_connectionstyle()(posA, posB,
- patchA=self.patchA,
- patchB=self.patchB,
- shrinkA=self.shrinkA * dpi_cor,
- shrinkB=self.shrinkB * dpi_cor
- )
- else:
- _path = self.get_transform().transform_path(self._path_original)
-
- _path, fillable = self.get_arrowstyle()(
- _path,
- self.get_mutation_scale() * dpi_cor,
- self.get_linewidth() * dpi_cor,
- self.get_mutation_aspect())
-
- return _path, fillable
-
- def draw(self, renderer):
- if not self.get_visible():
- return
-
- # FIXME: dpi_cor is for the dpi-dependency of the linewidth. There
- # could be room for improvement. Maybe _get_path_in_displaycoord could
- # take a renderer argument, but get_path should be adapted too.
- self._dpi_cor = renderer.points_to_pixels(1.)
- path, fillable = self._get_path_in_displaycoord()
-
- if not np.iterable(fillable):
- path = [path]
- fillable = [fillable]
-
- affine = transforms.IdentityTransform()
-
- self._draw_paths_with_artist_properties(
- renderer,
- [(p, affine, self._facecolor if f and self._facecolor[3] else None)
- for p, f in zip(path, fillable)])
-
-
-class ConnectionPatch(FancyArrowPatch):
- """A patch that connects two points (possibly in different axes)."""
-
- def __str__(self):
- return "ConnectionPatch((%g, %g), (%g, %g))" % \
- (self.xy1[0], self.xy1[1], self.xy2[0], self.xy2[1])
-
- @_docstring.dedent_interpd
- def __init__(self, xyA, xyB, coordsA, coordsB=None, *,
- axesA=None, axesB=None,
- arrowstyle="-",
- connectionstyle="arc3",
- patchA=None,
- patchB=None,
- shrinkA=0.,
- shrinkB=0.,
- mutation_scale=10.,
- mutation_aspect=None,
- clip_on=False,
- **kwargs):
- """
- Connect point *xyA* in *coordsA* with point *xyB* in *coordsB*.
-
- Valid keys are
-
- =============== ======================================================
- Key Description
- =============== ======================================================
- arrowstyle the arrow style
- connectionstyle the connection style
- relpos default is (0.5, 0.5)
- patchA default is bounding box of the text
- patchB default is None
- shrinkA default is 2 points
- shrinkB default is 2 points
- mutation_scale default is text size (in points)
- mutation_aspect default is 1.
- ? any key for `matplotlib.patches.PathPatch`
- =============== ======================================================
-
- *coordsA* and *coordsB* are strings that indicate the
- coordinates of *xyA* and *xyB*.
-
- ==================== ==================================================
- Property Description
- ==================== ==================================================
- 'figure points' points from the lower left corner of the figure
- 'figure pixels' pixels from the lower left corner of the figure
- 'figure fraction' 0, 0 is lower left of figure and 1, 1 is upper
- right
- 'subfigure points' points from the lower left corner of the subfigure
- 'subfigure pixels' pixels from the lower left corner of the subfigure
- 'subfigure fraction' fraction of the subfigure, 0, 0 is lower left.
- 'axes points' points from lower left corner of axes
- 'axes pixels' pixels from lower left corner of axes
- 'axes fraction' 0, 0 is lower left of axes and 1, 1 is upper right
- 'data' use the coordinate system of the object being
- annotated (default)
- 'offset points' offset (in points) from the *xy* value
- 'polar' you can specify *theta*, *r* for the annotation,
- even in cartesian plots. Note that if you are
- using a polar axes, you do not need to specify
- polar for the coordinate system since that is the
- native "data" coordinate system.
- ==================== ==================================================
-
- Alternatively they can be set to any valid
- `~matplotlib.transforms.Transform`.
-
- Note that 'subfigure pixels' and 'figure pixels' are the same
- for the parent figure, so users who want code that is usable in
- a subfigure can use 'subfigure pixels'.
-
- .. note::
-
- Using `ConnectionPatch` across two `~.axes.Axes` instances
- is not directly compatible with :ref:`constrained layout
- <constrainedlayout_guide>`. Add the artist
- directly to the `.Figure` instead of adding it to a specific Axes,
- or exclude it from the layout using ``con.set_in_layout(False)``.
-
- .. code-block:: default
-
- fig, ax = plt.subplots(1, 2, constrained_layout=True)
- con = ConnectionPatch(..., axesA=ax[0], axesB=ax[1])
- fig.add_artist(con)
-
- """
- if coordsB is None:
- coordsB = coordsA
- # we'll draw ourself after the artist we annotate by default
- self.xy1 = xyA
- self.xy2 = xyB
- self.coords1 = coordsA
- self.coords2 = coordsB
-
- self.axesA = axesA
- self.axesB = axesB
-
- super().__init__(posA=(0, 0), posB=(1, 1),
- arrowstyle=arrowstyle,
- connectionstyle=connectionstyle,
- patchA=patchA, patchB=patchB,
- shrinkA=shrinkA, shrinkB=shrinkB,
- mutation_scale=mutation_scale,
- mutation_aspect=mutation_aspect,
- clip_on=clip_on,
- **kwargs)
- # if True, draw annotation only if self.xy is inside the axes
- self._annotation_clip = None
-
- def _get_xy(self, xy, s, axes=None):
- """Calculate the pixel position of given point."""
- s0 = s # For the error message, if needed.
- if axes is None:
- axes = self.axes
- xy = np.array(xy)
- if s in ["figure points", "axes points"]:
- xy *= self.figure.dpi / 72
- s = s.replace("points", "pixels")
- elif s == "figure fraction":
- s = self.figure.transFigure
- elif s == "subfigure fraction":
- s = self.figure.transSubfigure
- elif s == "axes fraction":
- s = axes.transAxes
- x, y = xy
-
- if s == 'data':
- trans = axes.transData
- x = float(self.convert_xunits(x))
- y = float(self.convert_yunits(y))
- return trans.transform((x, y))
- elif s == 'offset points':
- if self.xycoords == 'offset points': # prevent recursion
- return self._get_xy(self.xy, 'data')
- return (
- self._get_xy(self.xy, self.xycoords) # converted data point
- + xy * self.figure.dpi / 72) # converted offset
- elif s == 'polar':
- theta, r = x, y
- x = r * np.cos(theta)
- y = r * np.sin(theta)
- trans = axes.transData
- return trans.transform((x, y))
- elif s == 'figure pixels':
- # pixels from the lower left corner of the figure
- bb = self.figure.figbbox
- x = bb.x0 + x if x >= 0 else bb.x1 + x
- y = bb.y0 + y if y >= 0 else bb.y1 + y
- return x, y
- elif s == 'subfigure pixels':
- # pixels from the lower left corner of the figure
- bb = self.figure.bbox
- x = bb.x0 + x if x >= 0 else bb.x1 + x
- y = bb.y0 + y if y >= 0 else bb.y1 + y
- return x, y
- elif s == 'axes pixels':
- # pixels from the lower left corner of the axes
- bb = axes.bbox
- x = bb.x0 + x if x >= 0 else bb.x1 + x
- y = bb.y0 + y if y >= 0 else bb.y1 + y
- return x, y
- elif isinstance(s, transforms.Transform):
- return s.transform(xy)
- else:
- raise ValueError(f"{s0} is not a valid coordinate transformation")
-
- def set_annotation_clip(self, b):
- """
- Set the annotation's clipping behavior.
-
- Parameters
- ----------
- b : bool or None
- - True: The annotation will be clipped when ``self.xy`` is
- outside the axes.
- - False: The annotation will always be drawn.
- - None: The annotation will be clipped when ``self.xy`` is
- outside the axes and ``self.xycoords == "data"``.
- """
- self._annotation_clip = b
- self.stale = True
-
- def get_annotation_clip(self):
- """
- Return the clipping behavior.
-
- See `.set_annotation_clip` for the meaning of the return value.
- """
- return self._annotation_clip
-
- def _get_path_in_displaycoord(self):
- """Return the mutated path of the arrow in display coordinates."""
- dpi_cor = self._dpi_cor
- posA = self._get_xy(self.xy1, self.coords1, self.axesA)
- posB = self._get_xy(self.xy2, self.coords2, self.axesB)
- path = self.get_connectionstyle()(
- posA, posB,
- patchA=self.patchA, patchB=self.patchB,
- shrinkA=self.shrinkA * dpi_cor, shrinkB=self.shrinkB * dpi_cor,
- )
- path, fillable = self.get_arrowstyle()(
- path,
- self.get_mutation_scale() * dpi_cor,
- self.get_linewidth() * dpi_cor,
- self.get_mutation_aspect()
- )
- return path, fillable
-
- def _check_xy(self, renderer):
- """Check whether the annotation needs to be drawn."""
-
- b = self.get_annotation_clip()
-
- if b or (b is None and self.coords1 == "data"):
- xy_pixel = self._get_xy(self.xy1, self.coords1, self.axesA)
- if self.axesA is None:
- axes = self.axes
- else:
- axes = self.axesA
- if not axes.contains_point(xy_pixel):
- return False
-
- if b or (b is None and self.coords2 == "data"):
- xy_pixel = self._get_xy(self.xy2, self.coords2, self.axesB)
- if self.axesB is None:
- axes = self.axes
- else:
- axes = self.axesB
- if not axes.contains_point(xy_pixel):
- return False
-
- return True
-
- def draw(self, renderer):
- if renderer is not None:
- self._renderer = renderer
- if not self.get_visible() or not self._check_xy(renderer):
- return
- super().draw(renderer)
diff --git a/contrib/python/matplotlib/py3/matplotlib/patches.pyi b/contrib/python/matplotlib/py3/matplotlib/patches.pyi
deleted file mode 100644
index 29fe36aa6c..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/patches.pyi
+++ /dev/null
@@ -1,751 +0,0 @@
-from . import artist
-from .axes import Axes
-from .backend_bases import RendererBase, MouseEvent
-from .path import Path
-from .transforms import Transform, Bbox
-
-from typing import Any, Literal, overload
-
-import numpy as np
-from numpy.typing import ArrayLike
-from .typing import ColorType, LineStyleType, CapStyleType, JoinStyleType
-
-class Patch(artist.Artist):
- zorder: float
- def __init__(
- self,
- *,
- edgecolor: ColorType | None = ...,
- facecolor: ColorType | None = ...,
- color: ColorType | None = ...,
- linewidth: float | None = ...,
- linestyle: LineStyleType | None = ...,
- antialiased: bool | None = ...,
- hatch: str | None = ...,
- fill: bool = ...,
- capstyle: CapStyleType | None = ...,
- joinstyle: JoinStyleType | None = ...,
- **kwargs,
- ) -> None: ...
- def get_verts(self) -> ArrayLike: ...
- def contains(self, mouseevent: MouseEvent, radius: float | None = None) -> tuple[bool, dict[Any, Any]]: ...
- def contains_point(
- self, point: tuple[float, float], radius: float | None = ...
- ) -> bool: ...
- def contains_points(
- self, points: ArrayLike, radius: float | None = ...
- ) -> np.ndarray: ...
- def get_extents(self) -> Bbox: ...
- def get_transform(self) -> Transform: ...
- def get_data_transform(self) -> Transform: ...
- def get_patch_transform(self) -> Transform: ...
- def get_antialiased(self) -> bool: ...
- def get_edgecolor(self) -> ColorType: ...
- def get_facecolor(self) -> ColorType: ...
- def get_linewidth(self) -> float: ...
- def get_linestyle(self) -> LineStyleType: ...
- def set_antialiased(self, aa: bool | None) -> None: ...
- def set_edgecolor(self, color: ColorType | None) -> None: ...
- def set_facecolor(self, color: ColorType | None) -> None: ...
- def set_color(self, c: ColorType | None) -> None: ...
- def set_alpha(self, alpha: float | None) -> None: ...
- def set_linewidth(self, w: float | None) -> None: ...
- def set_linestyle(self, ls: LineStyleType | None) -> None: ...
- def set_fill(self, b: bool) -> None: ...
- def get_fill(self) -> bool: ...
- fill = property(get_fill, set_fill)
- def set_capstyle(self, s: CapStyleType) -> None: ...
- def get_capstyle(self) -> Literal["butt", "projecting", "round"]: ...
- def set_joinstyle(self, s: JoinStyleType) -> None: ...
- def get_joinstyle(self) -> Literal["miter", "round", "bevel"]: ...
- def set_hatch(self, hatch: str) -> None: ...
- def get_hatch(self) -> str: ...
- def get_path(self) -> Path: ...
-
-class Shadow(Patch):
- patch: Patch
- def __init__(self, patch: Patch, ox: float, oy: float, *, shade: float = ..., **kwargs) -> None: ...
-
-class Rectangle(Patch):
- angle: float
- def __init__(
- self,
- xy: tuple[float, float],
- width: float,
- height: float,
- *,
- angle: float = ...,
- rotation_point: Literal["xy", "center"] | tuple[float, float] = ...,
- **kwargs,
- ) -> None: ...
- @property
- def rotation_point(self) -> Literal["xy", "center"] | tuple[float, float]: ...
- @rotation_point.setter
- def rotation_point(
- self, value: Literal["xy", "center"] | tuple[float, float]
- ) -> None: ...
- def get_x(self) -> float: ...
- def get_y(self) -> float: ...
- def get_xy(self) -> tuple[float, float]: ...
- def get_corners(self) -> np.ndarray: ...
- def get_center(self) -> np.ndarray: ...
- def get_width(self) -> float: ...
- def get_height(self) -> float: ...
- def get_angle(self) -> float: ...
- def set_x(self, x: float) -> None: ...
- def set_y(self, y: float) -> None: ...
- def set_angle(self, angle: float) -> None: ...
- def set_xy(self, xy: tuple[float, float]) -> None: ...
- def set_width(self, w: float) -> None: ...
- def set_height(self, h: float) -> None: ...
- @overload
- def set_bounds(self, args: tuple[float, float, float, float], /) -> None: ...
- @overload
- def set_bounds(
- self, left: float, bottom: float, width: float, height: float, /
- ) -> None: ...
- def get_bbox(self) -> Bbox: ...
- xy = property(get_xy, set_xy)
-
-class RegularPolygon(Patch):
- xy: tuple[float, float]
- numvertices: int
- orientation: float
- radius: float
- def __init__(
- self,
- xy: tuple[float, float],
- numVertices: int,
- *,
- radius: float = ...,
- orientation: float = ...,
- **kwargs,
- ) -> None: ...
-
-class PathPatch(Patch):
- def __init__(self, path: Path, **kwargs) -> None: ...
- def set_path(self, path: Path) -> None: ...
-
-class StepPatch(PathPatch):
- orientation: Literal["vertical", "horizontal"]
- def __init__(
- self,
- values: ArrayLike,
- edges: ArrayLike,
- *,
- orientation: Literal["vertical", "horizontal"] = ...,
- baseline: float = ...,
- **kwargs,
- ) -> None: ...
-
- # NamedTuple StairData, defined in body of method
- def get_data(self) -> tuple[np.ndarray, np.ndarray, float]: ...
- def set_data(
- self,
- values: ArrayLike | None = ...,
- edges: ArrayLike | None = ...,
- baseline: float | None = ...,
- ) -> None: ...
-
-class Polygon(Patch):
- def __init__(self, xy: ArrayLike, *, closed: bool = ..., **kwargs) -> None: ...
- def get_closed(self) -> bool: ...
- def set_closed(self, closed: bool) -> None: ...
- def get_xy(self) -> np.ndarray: ...
- def set_xy(self, xy: ArrayLike) -> None: ...
- xy = property(get_xy, set_xy)
-
-class Wedge(Patch):
- center: tuple[float, float]
- r: float
- theta1: float
- theta2: float
- width: float | None
- def __init__(
- self,
- center: tuple[float, float],
- r: float,
- theta1: float,
- theta2: float,
- *,
- width: float | None = ...,
- **kwargs,
- ) -> None: ...
- def set_center(self, center: tuple[float, float]) -> None: ...
- def set_radius(self, radius: float) -> None: ...
- def set_theta1(self, theta1: float) -> None: ...
- def set_theta2(self, theta2: float) -> None: ...
- def set_width(self, width: float | None) -> None: ...
-
-class Arrow(Patch):
- def __init__(
- self, x: float, y: float, dx: float, dy: float, *, width: float = ..., **kwargs
- ) -> None: ...
-
-class FancyArrow(Polygon):
- def __init__(
- self,
- x: float,
- y: float,
- dx: float,
- dy: float,
- *,
- width: float = ...,
- length_includes_head: bool = ...,
- head_width: float | None = ...,
- head_length: float | None = ...,
- shape: Literal["full", "left", "right"] = ...,
- overhang: float = ...,
- head_starts_at_zero: bool = ...,
- **kwargs,
- ) -> None: ...
- def set_data(
- self,
- *,
- x: float | None = ...,
- y: float | None = ...,
- dx: float | None = ...,
- dy: float | None = ...,
- width: float | None = ...,
- head_width: float | None = ...,
- head_length: float | None = ...,
- ) -> None: ...
-
-class CirclePolygon(RegularPolygon):
- def __init__(
- self,
- xy: tuple[float, float],
- radius: float = ...,
- *,
- resolution: int = ...,
- **kwargs,
- ) -> None: ...
-
-class Ellipse(Patch):
- def __init__(
- self,
- xy: tuple[float, float],
- width: float,
- height: float,
- *,
- angle: float = ...,
- **kwargs,
- ) -> None: ...
- def set_center(self, xy: tuple[float, float]) -> None: ...
- def get_center(self) -> float: ...
- center = property(get_center, set_center)
-
- def set_width(self, width: float) -> None: ...
- def get_width(self) -> float: ...
- width = property(get_width, set_width)
-
- def set_height(self, height: float) -> None: ...
- def get_height(self) -> float: ...
- height = property(get_height, set_height)
-
- def set_angle(self, angle: float) -> None: ...
- def get_angle(self) -> float: ...
- angle = property(get_angle, set_angle)
-
- def get_corners(self) -> np.ndarray: ...
-
- def get_vertices(self) -> list[tuple[float, float]]: ...
- def get_co_vertices(self) -> list[tuple[float, float]]: ...
-
-
-class Annulus(Patch):
- a: float
- b: float
- def __init__(
- self,
- xy: tuple[float, float],
- r: float | tuple[float, float],
- width: float,
- angle: float = ...,
- **kwargs,
- ) -> None: ...
- def set_center(self, xy: tuple[float, float]) -> None: ...
- def get_center(self) -> tuple[float, float]: ...
- center = property(get_center, set_center)
-
- def set_width(self, width: float) -> None: ...
- def get_width(self) -> float: ...
- width = property(get_width, set_width)
-
- def set_angle(self, angle: float) -> None: ...
- def get_angle(self) -> float: ...
- angle = property(get_angle, set_angle)
-
- def set_semimajor(self, a: float) -> None: ...
- def set_semiminor(self, b: float) -> None: ...
- def set_radii(self, r: float | tuple[float, float]) -> None: ...
- def get_radii(self) -> tuple[float, float]: ...
- radii = property(get_radii, set_radii)
-
-class Circle(Ellipse):
- def __init__(
- self, xy: tuple[float, float], radius: float = ..., **kwargs
- ) -> None: ...
- def set_radius(self, radius: float) -> None: ...
- def get_radius(self) -> float: ...
- radius = property(get_radius, set_radius)
-
-class Arc(Ellipse):
- theta1: float
- theta2: float
- def __init__(
- self,
- xy: tuple[float, float],
- width: float,
- height: float,
- *,
- angle: float = ...,
- theta1: float = ...,
- theta2: float = ...,
- **kwargs,
- ) -> None: ...
-
-def bbox_artist(
- artist: artist.Artist,
- renderer: RendererBase,
- props: dict[str, Any] | None = ...,
- fill: bool = ...,
-) -> None: ...
-def draw_bbox(
- bbox: Bbox,
- renderer: RendererBase,
- color: ColorType = ...,
- trans: Transform | None = ...,
-) -> None: ...
-
-class _Style:
- def __new__(cls, stylename, **kwargs): ...
- @classmethod
- def get_styles(cls) -> dict[str, type]: ...
- @classmethod
- def pprint_styles(cls) -> str: ...
- @classmethod
- def register(cls, name: str, style: type) -> None: ...
-
-class BoxStyle(_Style):
- class Square(BoxStyle):
- pad: float
- def __init__(self, pad: float = ...) -> None: ...
- def __call__(
- self,
- x0: float,
- y0: float,
- width: float,
- height: float,
- mutation_size: float,
- ) -> Path: ...
-
- class Circle(BoxStyle):
- pad: float
- def __init__(self, pad: float = ...) -> None: ...
- def __call__(
- self,
- x0: float,
- y0: float,
- width: float,
- height: float,
- mutation_size: float,
- ) -> Path: ...
-
- class Ellipse(BoxStyle):
- pad: float
- def __init__(self, pad: float = ...) -> None: ...
- def __call__(
- self,
- x0: float,
- y0: float,
- width: float,
- height: float,
- mutation_size: float,
- ) -> Path: ...
-
- class LArrow(BoxStyle):
- pad: float
- def __init__(self, pad: float = ...) -> None: ...
- def __call__(
- self,
- x0: float,
- y0: float,
- width: float,
- height: float,
- mutation_size: float,
- ) -> Path: ...
-
- class RArrow(LArrow):
- def __call__(
- self,
- x0: float,
- y0: float,
- width: float,
- height: float,
- mutation_size: float,
- ) -> Path: ...
-
- class DArrow(BoxStyle):
- pad: float
- def __init__(self, pad: float = ...) -> None: ...
- def __call__(
- self,
- x0: float,
- y0: float,
- width: float,
- height: float,
- mutation_size: float,
- ) -> Path: ...
-
- class Round(BoxStyle):
- pad: float
- rounding_size: float | None
- def __init__(
- self, pad: float = ..., rounding_size: float | None = ...
- ) -> None: ...
- def __call__(
- self,
- x0: float,
- y0: float,
- width: float,
- height: float,
- mutation_size: float,
- ) -> Path: ...
-
- class Round4(BoxStyle):
- pad: float
- rounding_size: float | None
- def __init__(
- self, pad: float = ..., rounding_size: float | None = ...
- ) -> None: ...
- def __call__(
- self,
- x0: float,
- y0: float,
- width: float,
- height: float,
- mutation_size: float,
- ) -> Path: ...
-
- class Sawtooth(BoxStyle):
- pad: float
- tooth_size: float | None
- def __init__(
- self, pad: float = ..., tooth_size: float | None = ...
- ) -> None: ...
- def __call__(
- self,
- x0: float,
- y0: float,
- width: float,
- height: float,
- mutation_size: float,
- ) -> Path: ...
-
- class Roundtooth(Sawtooth):
- def __call__(
- self,
- x0: float,
- y0: float,
- width: float,
- height: float,
- mutation_size: float,
- ) -> Path: ...
-
-class ConnectionStyle(_Style):
- class _Base(ConnectionStyle):
- class SimpleEvent:
- def __init__(self, xy: tuple[float, float]) -> None: ...
-
- def __call__(
- self,
- posA: tuple[float, float],
- posB: tuple[float, float],
- shrinkA: float = ...,
- shrinkB: float = ...,
- patchA: Patch | None = ...,
- patchB: Patch | None = ...,
- ) -> Path: ...
-
- class Arc3(_Base):
- rad: float
- def __init__(self, rad: float = ...) -> None: ...
- def connect(
- self, posA: tuple[float, float], posB: tuple[float, float]
- ) -> Path: ...
-
- class Angle3(_Base):
- angleA: float
- angleB: float
- def __init__(self, angleA: float = ..., angleB: float = ...) -> None: ...
- def connect(
- self, posA: tuple[float, float], posB: tuple[float, float]
- ) -> Path: ...
-
- class Angle(_Base):
- angleA: float
- angleB: float
- rad: float
- def __init__(
- self, angleA: float = ..., angleB: float = ..., rad: float = ...
- ) -> None: ...
- def connect(
- self, posA: tuple[float, float], posB: tuple[float, float]
- ) -> Path: ...
-
- class Arc(_Base):
- angleA: float
- angleB: float
- armA: float | None
- armB: float | None
- rad: float
- def __init__(
- self,
- angleA: float = ...,
- angleB: float = ...,
- armA: float | None = ...,
- armB: float | None = ...,
- rad: float = ...,
- ) -> None: ...
- def connect(
- self, posA: tuple[float, float], posB: tuple[float, float]
- ) -> Path: ...
-
- class Bar(_Base):
- armA: float
- armB: float
- fraction: float
- angle: float | None
- def __init__(
- self,
- armA: float = ...,
- armB: float = ...,
- fraction: float = ...,
- angle: float | None = ...,
- ) -> None: ...
- def connect(
- self, posA: tuple[float, float], posB: tuple[float, float]
- ) -> Path: ...
-
-class ArrowStyle(_Style):
- class _Base(ArrowStyle):
- @staticmethod
- def ensure_quadratic_bezier(path: Path) -> list[float]: ...
- def transmute(
- self, path: Path, mutation_size: float, linewidth: float
- ) -> tuple[Path, bool]: ...
- def __call__(
- self,
- path: Path,
- mutation_size: float,
- linewidth: float,
- aspect_ratio: float = ...,
- ) -> tuple[Path, bool]: ...
-
- class _Curve(_Base):
- arrow: str
- fillbegin: bool
- fillend: bool
- def __init__(
- self,
- head_length: float = ...,
- head_width: float = ...,
- widthA: float = ...,
- widthB: float = ...,
- lengthA: float = ...,
- lengthB: float = ...,
- angleA: float | None = ...,
- angleB: float | None = ...,
- scaleA: float | None = ...,
- scaleB: float | None = ...,
- ) -> None: ...
-
- class Curve(_Curve):
- def __init__(self) -> None: ...
-
- class CurveA(_Curve):
- arrow: str
-
- class CurveB(_Curve):
- arrow: str
-
- class CurveAB(_Curve):
- arrow: str
-
- class CurveFilledA(_Curve):
- arrow: str
-
- class CurveFilledB(_Curve):
- arrow: str
-
- class CurveFilledAB(_Curve):
- arrow: str
-
- class BracketA(_Curve):
- arrow: str
- def __init__(
- self, widthA: float = ..., lengthA: float = ..., angleA: float = ...
- ) -> None: ...
-
- class BracketB(_Curve):
- arrow: str
- def __init__(
- self, widthB: float = ..., lengthB: float = ..., angleB: float = ...
- ) -> None: ...
-
- class BracketAB(_Curve):
- arrow: str
- def __init__(
- self,
- widthA: float = ...,
- lengthA: float = ...,
- angleA: float = ...,
- widthB: float = ...,
- lengthB: float = ...,
- angleB: float = ...,
- ) -> None: ...
-
- class BarAB(_Curve):
- arrow: str
- def __init__(
- self,
- widthA: float = ...,
- angleA: float = ...,
- widthB: float = ...,
- angleB: float = ...,
- ) -> None: ...
-
- class BracketCurve(_Curve):
- arrow: str
- def __init__(
- self, widthA: float = ..., lengthA: float = ..., angleA: float | None = ...
- ) -> None: ...
-
- class CurveBracket(_Curve):
- arrow: str
- def __init__(
- self, widthB: float = ..., lengthB: float = ..., angleB: float | None = ...
- ) -> None: ...
-
- class Simple(_Base):
- def __init__(
- self,
- head_length: float = ...,
- head_width: float = ...,
- tail_width: float = ...,
- ) -> None: ...
-
- class Fancy(_Base):
- def __init__(
- self,
- head_length: float = ...,
- head_width: float = ...,
- tail_width: float = ...,
- ) -> None: ...
-
- class Wedge(_Base):
- tail_width: float
- shrink_factor: float
- def __init__(
- self, tail_width: float = ..., shrink_factor: float = ...
- ) -> None: ...
-
-class FancyBboxPatch(Patch):
- def __init__(
- self,
- xy: tuple[float, float],
- width: float,
- height: float,
- boxstyle: str | BoxStyle = ...,
- *,
- mutation_scale: float = ...,
- mutation_aspect: float = ...,
- **kwargs,
- ) -> None: ...
- def set_boxstyle(self, boxstyle: str | BoxStyle | None = ..., **kwargs) -> None: ...
- def get_boxstyle(self) -> BoxStyle: ...
- def set_mutation_scale(self, scale: float) -> None: ...
- def get_mutation_scale(self) -> float: ...
- def set_mutation_aspect(self, aspect: float) -> None: ...
- def get_mutation_aspect(self) -> float: ...
- def get_x(self) -> float: ...
- def get_y(self) -> float: ...
- def get_width(self) -> float: ...
- def get_height(self) -> float: ...
- def set_x(self, x: float) -> None: ...
- def set_y(self, y: float) -> None: ...
- def set_width(self, w: float) -> None: ...
- def set_height(self, h: float) -> None: ...
- @overload
- def set_bounds(self, args: tuple[float, float, float, float], /) -> None: ...
- @overload
- def set_bounds(
- self, left: float, bottom: float, width: float, height: float, /
- ) -> None: ...
- def get_bbox(self) -> Bbox: ...
-
-class FancyArrowPatch(Patch):
- patchA: Patch
- patchB: Patch
- shrinkA: float
- shrinkB: float
- def __init__(
- self,
- posA: tuple[float, float] | None = ...,
- posB: tuple[float, float] | None = ...,
- *,
- path: Path | None = ...,
- arrowstyle: str | ArrowStyle = ...,
- connectionstyle: str | ConnectionStyle = ...,
- patchA: Patch | None = ...,
- patchB: Patch | None = ...,
- shrinkA: float = ...,
- shrinkB: float = ...,
- mutation_scale: float = ...,
- mutation_aspect: float | None = ...,
- **kwargs,
- ) -> None: ...
- def set_positions(
- self, posA: tuple[float, float], posB: tuple[float, float]
- ) -> None: ...
- def set_patchA(self, patchA: Patch) -> None: ...
- def set_patchB(self, patchB: Patch) -> None: ...
- def set_connectionstyle(self, connectionstyle: str | ConnectionStyle | None = ..., **kwargs) -> None: ...
- def get_connectionstyle(self) -> ConnectionStyle: ...
- def set_arrowstyle(self, arrowstyle: str | ArrowStyle | None = ..., **kwargs) -> None: ...
- def get_arrowstyle(self) -> ArrowStyle: ...
- def set_mutation_scale(self, scale: float) -> None: ...
- def get_mutation_scale(self) -> float: ...
- def set_mutation_aspect(self, aspect: float | None) -> None: ...
- def get_mutation_aspect(self) -> float: ...
-
-class ConnectionPatch(FancyArrowPatch):
- xy1: tuple[float, float]
- xy2: tuple[float, float]
- coords1: str | Transform
- coords2: str | Transform | None
- axesA: Axes | None
- axesB: Axes | None
- def __init__(
- self,
- xyA: tuple[float, float],
- xyB: tuple[float, float],
- coordsA: str | Transform,
- coordsB: str | Transform | None = ...,
- *,
- axesA: Axes | None = ...,
- axesB: Axes | None = ...,
- arrowstyle: str | ArrowStyle = ...,
- connectionstyle: str | ConnectionStyle = ...,
- patchA: Patch | None = ...,
- patchB: Patch | None = ...,
- shrinkA: float = ...,
- shrinkB: float = ...,
- mutation_scale: float = ...,
- mutation_aspect: float | None = ...,
- clip_on: bool = ...,
- **kwargs,
- ) -> None: ...
- def set_annotation_clip(self, b: bool | None) -> None: ...
- def get_annotation_clip(self) -> bool | None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/path.py b/contrib/python/matplotlib/py3/matplotlib/path.py
deleted file mode 100644
index e72eb1a9ca..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/path.py
+++ /dev/null
@@ -1,1093 +0,0 @@
-r"""
-A module for dealing with the polylines used throughout Matplotlib.
-
-The primary class for polyline handling in Matplotlib is `Path`. Almost all
-vector drawing makes use of `Path`\s somewhere in the drawing pipeline.
-
-Whilst a `Path` instance itself cannot be drawn, some `.Artist` subclasses,
-such as `.PathPatch` and `.PathCollection`, can be used for convenient `Path`
-visualisation.
-"""
-
-import copy
-from functools import lru_cache
-from weakref import WeakValueDictionary
-
-import numpy as np
-
-import matplotlib as mpl
-from . import _api, _path
-from .cbook import _to_unmasked_float_array, simple_linear_interpolation
-from .bezier import BezierSegment
-
-
-class Path:
- """
- A series of possibly disconnected, possibly closed, line and curve
- segments.
-
- The underlying storage is made up of two parallel numpy arrays:
-
- - *vertices*: an (N, 2) float array of vertices
- - *codes*: an N-length `numpy.uint8` array of path codes, or None
-
- These two arrays always have the same length in the first
- dimension. For example, to represent a cubic curve, you must
- provide three vertices and three `CURVE4` codes.
-
- The code types are:
-
- - `STOP` : 1 vertex (ignored)
- A marker for the end of the entire path (currently not required and
- ignored)
-
- - `MOVETO` : 1 vertex
- Pick up the pen and move to the given vertex.
-
- - `LINETO` : 1 vertex
- Draw a line from the current position to the given vertex.
-
- - `CURVE3` : 1 control point, 1 endpoint
- Draw a quadratic Bézier curve from the current position, with the given
- control point, to the given end point.
-
- - `CURVE4` : 2 control points, 1 endpoint
- Draw a cubic Bézier curve from the current position, with the given
- control points, to the given end point.
-
- - `CLOSEPOLY` : 1 vertex (ignored)
- Draw a line segment to the start point of the current polyline.
-
- If *codes* is None, it is interpreted as a `MOVETO` followed by a series
- of `LINETO`.
-
- Users of Path objects should not access the vertices and codes arrays
- directly. Instead, they should use `iter_segments` or `cleaned` to get the
- vertex/code pairs. This helps, in particular, to consistently handle the
- case of *codes* being None.
-
- Some behavior of Path objects can be controlled by rcParams. See the
- rcParams whose keys start with 'path.'.
-
- .. note::
-
- The vertices and codes arrays should be treated as
- immutable -- there are a number of optimizations and assumptions
- made up front in the constructor that will not change when the
- data changes.
- """
-
- code_type = np.uint8
-
- # Path codes
- STOP = code_type(0) # 1 vertex
- MOVETO = code_type(1) # 1 vertex
- LINETO = code_type(2) # 1 vertex
- CURVE3 = code_type(3) # 2 vertices
- CURVE4 = code_type(4) # 3 vertices
- CLOSEPOLY = code_type(79) # 1 vertex
-
- #: A dictionary mapping Path codes to the number of vertices that the
- #: code expects.
- NUM_VERTICES_FOR_CODE = {STOP: 1,
- MOVETO: 1,
- LINETO: 1,
- CURVE3: 2,
- CURVE4: 3,
- CLOSEPOLY: 1}
-
- def __init__(self, vertices, codes=None, _interpolation_steps=1,
- closed=False, readonly=False):
- """
- Create a new path with the given vertices and codes.
-
- Parameters
- ----------
- vertices : (N, 2) array-like
- The path vertices, as an array, masked array or sequence of pairs.
- Masked values, if any, will be converted to NaNs, which are then
- handled correctly by the Agg PathIterator and other consumers of
- path data, such as :meth:`iter_segments`.
- codes : array-like or None, optional
- N-length array of integers representing the codes of the path.
- If not None, codes must be the same length as vertices.
- If None, *vertices* will be treated as a series of line segments.
- _interpolation_steps : int, optional
- Used as a hint to certain projections, such as Polar, that this
- path should be linearly interpolated immediately before drawing.
- This attribute is primarily an implementation detail and is not
- intended for public use.
- closed : bool, optional
- If *codes* is None and closed is True, vertices will be treated as
- line segments of a closed polygon. Note that the last vertex will
- then be ignored (as the corresponding code will be set to
- `CLOSEPOLY`).
- readonly : bool, optional
- Makes the path behave in an immutable way and sets the vertices
- and codes as read-only arrays.
- """
- vertices = _to_unmasked_float_array(vertices)
- _api.check_shape((None, 2), vertices=vertices)
-
- if codes is not None:
- codes = np.asarray(codes, self.code_type)
- if codes.ndim != 1 or len(codes) != len(vertices):
- raise ValueError("'codes' must be a 1D list or array with the "
- "same length of 'vertices'. "
- f"Your vertices have shape {vertices.shape} "
- f"but your codes have shape {codes.shape}")
- if len(codes) and codes[0] != self.MOVETO:
- raise ValueError("The first element of 'code' must be equal "
- f"to 'MOVETO' ({self.MOVETO}). "
- f"Your first code is {codes[0]}")
- elif closed and len(vertices):
- codes = np.empty(len(vertices), dtype=self.code_type)
- codes[0] = self.MOVETO
- codes[1:-1] = self.LINETO
- codes[-1] = self.CLOSEPOLY
-
- self._vertices = vertices
- self._codes = codes
- self._interpolation_steps = _interpolation_steps
- self._update_values()
-
- if readonly:
- self._vertices.flags.writeable = False
- if self._codes is not None:
- self._codes.flags.writeable = False
- self._readonly = True
- else:
- self._readonly = False
-
- @classmethod
- def _fast_from_codes_and_verts(cls, verts, codes, internals_from=None):
- """
- Create a Path instance without the expense of calling the constructor.
-
- Parameters
- ----------
- verts : array-like
- codes : array
- internals_from : Path or None
- If not None, another `Path` from which the attributes
- ``should_simplify``, ``simplify_threshold``, and
- ``interpolation_steps`` will be copied. Note that ``readonly`` is
- never copied, and always set to ``False`` by this constructor.
- """
- pth = cls.__new__(cls)
- pth._vertices = _to_unmasked_float_array(verts)
- pth._codes = codes
- pth._readonly = False
- if internals_from is not None:
- pth._should_simplify = internals_from._should_simplify
- pth._simplify_threshold = internals_from._simplify_threshold
- pth._interpolation_steps = internals_from._interpolation_steps
- else:
- pth._should_simplify = True
- pth._simplify_threshold = mpl.rcParams['path.simplify_threshold']
- pth._interpolation_steps = 1
- return pth
-
- @classmethod
- def _create_closed(cls, vertices):
- """
- Create a closed polygonal path going through *vertices*.
-
- Unlike ``Path(..., closed=True)``, *vertices* should **not** end with
- an entry for the CLOSEPATH; this entry is added by `._create_closed`.
- """
- v = _to_unmasked_float_array(vertices)
- return cls(np.concatenate([v, v[:1]]), closed=True)
-
- def _update_values(self):
- self._simplify_threshold = mpl.rcParams['path.simplify_threshold']
- self._should_simplify = (
- self._simplify_threshold > 0 and
- mpl.rcParams['path.simplify'] and
- len(self._vertices) >= 128 and
- (self._codes is None or np.all(self._codes <= Path.LINETO))
- )
-
- @property
- def vertices(self):
- """The vertices of the `Path` as an (N, 2) array."""
- return self._vertices
-
- @vertices.setter
- def vertices(self, vertices):
- if self._readonly:
- raise AttributeError("Can't set vertices on a readonly Path")
- self._vertices = vertices
- self._update_values()
-
- @property
- def codes(self):
- """
- The list of codes in the `Path` as a 1D array.
-
- Each code is one of `STOP`, `MOVETO`, `LINETO`, `CURVE3`, `CURVE4` or
- `CLOSEPOLY`. For codes that correspond to more than one vertex
- (`CURVE3` and `CURVE4`), that code will be repeated so that the length
- of `vertices` and `codes` is always the same.
- """
- return self._codes
-
- @codes.setter
- def codes(self, codes):
- if self._readonly:
- raise AttributeError("Can't set codes on a readonly Path")
- self._codes = codes
- self._update_values()
-
- @property
- def simplify_threshold(self):
- """
- The fraction of a pixel difference below which vertices will
- be simplified out.
- """
- return self._simplify_threshold
-
- @simplify_threshold.setter
- def simplify_threshold(self, threshold):
- self._simplify_threshold = threshold
-
- @property
- def should_simplify(self):
- """
- `True` if the vertices array should be simplified.
- """
- return self._should_simplify
-
- @should_simplify.setter
- def should_simplify(self, should_simplify):
- self._should_simplify = should_simplify
-
- @property
- def readonly(self):
- """
- `True` if the `Path` is read-only.
- """
- return self._readonly
-
- def copy(self):
- """
- Return a shallow copy of the `Path`, which will share the
- vertices and codes with the source `Path`.
- """
- return copy.copy(self)
-
- def __deepcopy__(self, memo=None):
- """
- Return a deepcopy of the `Path`. The `Path` will not be
- readonly, even if the source `Path` is.
- """
- # Deepcopying arrays (vertices, codes) strips the writeable=False flag.
- p = copy.deepcopy(super(), memo)
- p._readonly = False
- return p
-
- deepcopy = __deepcopy__
-
- @classmethod
- def make_compound_path_from_polys(cls, XY):
- """
- Make a compound `Path` object to draw a number of polygons with equal
- numbers of sides.
-
- .. plot:: gallery/misc/histogram_path.py
-
- Parameters
- ----------
- XY : (numpolys, numsides, 2) array
- """
- # for each poly: 1 for the MOVETO, (numsides-1) for the LINETO, 1 for
- # the CLOSEPOLY; the vert for the closepoly is ignored but we still
- # need it to keep the codes aligned with the vertices
- numpolys, numsides, two = XY.shape
- if two != 2:
- raise ValueError("The third dimension of 'XY' must be 2")
- stride = numsides + 1
- nverts = numpolys * stride
- verts = np.zeros((nverts, 2))
- codes = np.full(nverts, cls.LINETO, dtype=cls.code_type)
- codes[0::stride] = cls.MOVETO
- codes[numsides::stride] = cls.CLOSEPOLY
- for i in range(numsides):
- verts[i::stride] = XY[:, i]
- return cls(verts, codes)
-
- @classmethod
- def make_compound_path(cls, *args):
- r"""
- Concatenate a list of `Path`\s into a single `Path`, removing all `STOP`\s.
- """
- if not args:
- return Path(np.empty([0, 2], dtype=np.float32))
- vertices = np.concatenate([path.vertices for path in args])
- codes = np.empty(len(vertices), dtype=cls.code_type)
- i = 0
- for path in args:
- size = len(path.vertices)
- if path.codes is None:
- if size:
- codes[i] = cls.MOVETO
- codes[i+1:i+size] = cls.LINETO
- else:
- codes[i:i+size] = path.codes
- i += size
- not_stop_mask = codes != cls.STOP # Remove STOPs, as internal STOPs are a bug.
- return cls(vertices[not_stop_mask], codes[not_stop_mask])
-
- def __repr__(self):
- return f"Path({self.vertices!r}, {self.codes!r})"
-
- def __len__(self):
- return len(self.vertices)
-
- def iter_segments(self, transform=None, remove_nans=True, clip=None,
- snap=False, stroke_width=1.0, simplify=None,
- curves=True, sketch=None):
- """
- Iterate over all curve segments in the path.
-
- Each iteration returns a pair ``(vertices, code)``, where ``vertices``
- is a sequence of 1-3 coordinate pairs, and ``code`` is a `Path` code.
-
- Additionally, this method can provide a number of standard cleanups and
- conversions to the path.
-
- Parameters
- ----------
- transform : None or :class:`~matplotlib.transforms.Transform`
- If not None, the given affine transformation will be applied to the
- path.
- remove_nans : bool, optional
- Whether to remove all NaNs from the path and skip over them using
- MOVETO commands.
- clip : None or (float, float, float, float), optional
- If not None, must be a four-tuple (x1, y1, x2, y2)
- defining a rectangle in which to clip the path.
- snap : None or bool, optional
- If True, snap all nodes to pixels; if False, don't snap them.
- If None, snap if the path contains only segments
- parallel to the x or y axes, and no more than 1024 of them.
- stroke_width : float, optional
- The width of the stroke being drawn (used for path snapping).
- simplify : None or bool, optional
- Whether to simplify the path by removing vertices
- that do not affect its appearance. If None, use the
- :attr:`should_simplify` attribute. See also :rc:`path.simplify`
- and :rc:`path.simplify_threshold`.
- curves : bool, optional
- If True, curve segments will be returned as curve segments.
- If False, all curves will be converted to line segments.
- sketch : None or sequence, optional
- If not None, must be a 3-tuple of the form
- (scale, length, randomness), representing the sketch parameters.
- """
- if not len(self):
- return
-
- cleaned = self.cleaned(transform=transform,
- remove_nans=remove_nans, clip=clip,
- snap=snap, stroke_width=stroke_width,
- simplify=simplify, curves=curves,
- sketch=sketch)
-
- # Cache these object lookups for performance in the loop.
- NUM_VERTICES_FOR_CODE = self.NUM_VERTICES_FOR_CODE
- STOP = self.STOP
-
- vertices = iter(cleaned.vertices)
- codes = iter(cleaned.codes)
- for curr_vertices, code in zip(vertices, codes):
- if code == STOP:
- break
- extra_vertices = NUM_VERTICES_FOR_CODE[code] - 1
- if extra_vertices:
- for i in range(extra_vertices):
- next(codes)
- curr_vertices = np.append(curr_vertices, next(vertices))
- yield curr_vertices, code
-
- def iter_bezier(self, **kwargs):
- """
- Iterate over each Bézier curve (lines included) in a `Path`.
-
- Parameters
- ----------
- **kwargs
- Forwarded to `.iter_segments`.
-
- Yields
- ------
- B : `~matplotlib.bezier.BezierSegment`
- The Bézier curves that make up the current path. Note in particular
- that freestanding points are Bézier curves of order 0, and lines
- are Bézier curves of order 1 (with two control points).
- code : `~matplotlib.path.Path.code_type`
- The code describing what kind of curve is being returned.
- `MOVETO`, `LINETO`, `CURVE3`, and `CURVE4` correspond to
- Bézier curves with 1, 2, 3, and 4 control points (respectively).
- `CLOSEPOLY` is a `LINETO` with the control points correctly
- chosen based on the start/end points of the current stroke.
- """
- first_vert = None
- prev_vert = None
- for verts, code in self.iter_segments(**kwargs):
- if first_vert is None:
- if code != Path.MOVETO:
- raise ValueError("Malformed path, must start with MOVETO.")
- if code == Path.MOVETO: # a point is like "CURVE1"
- first_vert = verts
- yield BezierSegment(np.array([first_vert])), code
- elif code == Path.LINETO: # "CURVE2"
- yield BezierSegment(np.array([prev_vert, verts])), code
- elif code == Path.CURVE3:
- yield BezierSegment(np.array([prev_vert, verts[:2],
- verts[2:]])), code
- elif code == Path.CURVE4:
- yield BezierSegment(np.array([prev_vert, verts[:2],
- verts[2:4], verts[4:]])), code
- elif code == Path.CLOSEPOLY:
- yield BezierSegment(np.array([prev_vert, first_vert])), code
- elif code == Path.STOP:
- return
- else:
- raise ValueError(f"Invalid Path.code_type: {code}")
- prev_vert = verts[-2:]
-
- def _iter_connected_components(self):
- """Return subpaths split at MOVETOs."""
- if self.codes is None:
- yield self
- else:
- idxs = np.append((self.codes == Path.MOVETO).nonzero()[0], len(self.codes))
- for sl in map(slice, idxs, idxs[1:]):
- yield Path._fast_from_codes_and_verts(
- self.vertices[sl], self.codes[sl], self)
-
- def cleaned(self, transform=None, remove_nans=False, clip=None,
- *, simplify=False, curves=False,
- stroke_width=1.0, snap=False, sketch=None):
- """
- Return a new `Path` with vertices and codes cleaned according to the
- parameters.
-
- See Also
- --------
- Path.iter_segments : for details of the keyword arguments.
- """
- vertices, codes = _path.cleanup_path(
- self, transform, remove_nans, clip, snap, stroke_width, simplify,
- curves, sketch)
- pth = Path._fast_from_codes_and_verts(vertices, codes, self)
- if not simplify:
- pth._should_simplify = False
- return pth
-
- def transformed(self, transform):
- """
- Return a transformed copy of the path.
-
- See Also
- --------
- matplotlib.transforms.TransformedPath
- A specialized path class that will cache the transformed result and
- automatically update when the transform changes.
- """
- return Path(transform.transform(self.vertices), self.codes,
- self._interpolation_steps)
-
- def contains_point(self, point, transform=None, radius=0.0):
- """
- Return whether the area enclosed by the path contains the given point.
-
- The path is always treated as closed; i.e. if the last code is not
- `CLOSEPOLY` an implicit segment connecting the last vertex to the first
- vertex is assumed.
-
- Parameters
- ----------
- point : (float, float)
- The point (x, y) to check.
- transform : `~matplotlib.transforms.Transform`, optional
- If not ``None``, *point* will be compared to ``self`` transformed
- by *transform*; i.e. for a correct check, *transform* should
- transform the path into the coordinate system of *point*.
- radius : float, default: 0
- Additional margin on the path in coordinates of *point*.
- The path is extended tangentially by *radius/2*; i.e. if you would
- draw the path with a linewidth of *radius*, all points on the line
- would still be considered to be contained in the area. Conversely,
- negative values shrink the area: Points on the imaginary line
- will be considered outside the area.
-
- Returns
- -------
- bool
-
- Notes
- -----
- The current algorithm has some limitations:
-
- - The result is undefined for points exactly at the boundary
- (i.e. at the path shifted by *radius/2*).
- - The result is undefined if there is no enclosed area, i.e. all
- vertices are on a straight line.
- - If bounding lines start to cross each other due to *radius* shift,
- the result is not guaranteed to be correct.
- """
- if transform is not None:
- transform = transform.frozen()
- # `point_in_path` does not handle nonlinear transforms, so we
- # transform the path ourselves. If *transform* is affine, letting
- # `point_in_path` handle the transform avoids allocating an extra
- # buffer.
- if transform and not transform.is_affine:
- self = transform.transform_path(self)
- transform = None
- return _path.point_in_path(point[0], point[1], radius, self, transform)
-
- def contains_points(self, points, transform=None, radius=0.0):
- """
- Return whether the area enclosed by the path contains the given points.
-
- The path is always treated as closed; i.e. if the last code is not
- `CLOSEPOLY` an implicit segment connecting the last vertex to the first
- vertex is assumed.
-
- Parameters
- ----------
- points : (N, 2) array
- The points to check. Columns contain x and y values.
- transform : `~matplotlib.transforms.Transform`, optional
- If not ``None``, *points* will be compared to ``self`` transformed
- by *transform*; i.e. for a correct check, *transform* should
- transform the path into the coordinate system of *points*.
- radius : float, default: 0
- Additional margin on the path in coordinates of *points*.
- The path is extended tangentially by *radius/2*; i.e. if you would
- draw the path with a linewidth of *radius*, all points on the line
- would still be considered to be contained in the area. Conversely,
- negative values shrink the area: Points on the imaginary line
- will be considered outside the area.
-
- Returns
- -------
- length-N bool array
-
- Notes
- -----
- The current algorithm has some limitations:
-
- - The result is undefined for points exactly at the boundary
- (i.e. at the path shifted by *radius/2*).
- - The result is undefined if there is no enclosed area, i.e. all
- vertices are on a straight line.
- - If bounding lines start to cross each other due to *radius* shift,
- the result is not guaranteed to be correct.
- """
- if transform is not None:
- transform = transform.frozen()
- result = _path.points_in_path(points, radius, self, transform)
- return result.astype('bool')
-
- def contains_path(self, path, transform=None):
- """
- Return whether this (closed) path completely contains the given path.
-
- If *transform* is not ``None``, the path will be transformed before
- checking for containment.
- """
- if transform is not None:
- transform = transform.frozen()
- return _path.path_in_path(self, None, path, transform)
-
- def get_extents(self, transform=None, **kwargs):
- """
- Get Bbox of the path.
-
- Parameters
- ----------
- transform : `~matplotlib.transforms.Transform`, optional
- Transform to apply to path before computing extents, if any.
- **kwargs
- Forwarded to `.iter_bezier`.
-
- Returns
- -------
- matplotlib.transforms.Bbox
- The extents of the path Bbox([[xmin, ymin], [xmax, ymax]])
- """
- from .transforms import Bbox
- if transform is not None:
- self = transform.transform_path(self)
- if self.codes is None:
- xys = self.vertices
- elif len(np.intersect1d(self.codes, [Path.CURVE3, Path.CURVE4])) == 0:
- # Optimization for the straight line case.
- # Instead of iterating through each curve, consider
- # each line segment's end-points
- # (recall that STOP and CLOSEPOLY vertices are ignored)
- xys = self.vertices[np.isin(self.codes,
- [Path.MOVETO, Path.LINETO])]
- else:
- xys = []
- for curve, code in self.iter_bezier(**kwargs):
- # places where the derivative is zero can be extrema
- _, dzeros = curve.axis_aligned_extrema()
- # as can the ends of the curve
- xys.append(curve([0, *dzeros, 1]))
- xys = np.concatenate(xys)
- if len(xys):
- return Bbox([xys.min(axis=0), xys.max(axis=0)])
- else:
- return Bbox.null()
-
- def intersects_path(self, other, filled=True):
- """
- Return whether if this path intersects another given path.
-
- If *filled* is True, then this also returns True if one path completely
- encloses the other (i.e., the paths are treated as filled).
- """
- return _path.path_intersects_path(self, other, filled)
-
- def intersects_bbox(self, bbox, filled=True):
- """
- Return whether this path intersects a given `~.transforms.Bbox`.
-
- If *filled* is True, then this also returns True if the path completely
- encloses the `.Bbox` (i.e., the path is treated as filled).
-
- The bounding box is always considered filled.
- """
- return _path.path_intersects_rectangle(
- self, bbox.x0, bbox.y0, bbox.x1, bbox.y1, filled)
-
- def interpolated(self, steps):
- """
- Return a new path resampled to length N x *steps*.
-
- Codes other than `LINETO` are not handled correctly.
- """
- if steps == 1:
- return self
-
- vertices = simple_linear_interpolation(self.vertices, steps)
- codes = self.codes
- if codes is not None:
- new_codes = np.full((len(codes) - 1) * steps + 1, Path.LINETO,
- dtype=self.code_type)
- new_codes[0::steps] = codes
- else:
- new_codes = None
- return Path(vertices, new_codes)
-
- def to_polygons(self, transform=None, width=0, height=0, closed_only=True):
- """
- Convert this path to a list of polygons or polylines. Each
- polygon/polyline is an (N, 2) array of vertices. In other words,
- each polygon has no `MOVETO` instructions or curves. This
- is useful for displaying in backends that do not support
- compound paths or Bézier curves.
-
- If *width* and *height* are both non-zero then the lines will
- be simplified so that vertices outside of (0, 0), (width,
- height) will be clipped.
-
- If *closed_only* is `True` (default), only closed polygons,
- with the last point being the same as the first point, will be
- returned. Any unclosed polylines in the path will be
- explicitly closed. If *closed_only* is `False`, any unclosed
- polygons in the path will be returned as unclosed polygons,
- and the closed polygons will be returned explicitly closed by
- setting the last point to the same as the first point.
- """
- if len(self.vertices) == 0:
- return []
-
- if transform is not None:
- transform = transform.frozen()
-
- if self.codes is None and (width == 0 or height == 0):
- vertices = self.vertices
- if closed_only:
- if len(vertices) < 3:
- return []
- elif np.any(vertices[0] != vertices[-1]):
- vertices = [*vertices, vertices[0]]
-
- if transform is None:
- return [vertices]
- else:
- return [transform.transform(vertices)]
-
- # Deal with the case where there are curves and/or multiple
- # subpaths (using extension code)
- return _path.convert_path_to_polygons(
- self, transform, width, height, closed_only)
-
- _unit_rectangle = None
-
- @classmethod
- def unit_rectangle(cls):
- """
- Return a `Path` instance of the unit rectangle from (0, 0) to (1, 1).
- """
- if cls._unit_rectangle is None:
- cls._unit_rectangle = cls([[0, 0], [1, 0], [1, 1], [0, 1], [0, 0]],
- closed=True, readonly=True)
- return cls._unit_rectangle
-
- _unit_regular_polygons = WeakValueDictionary()
-
- @classmethod
- def unit_regular_polygon(cls, numVertices):
- """
- Return a :class:`Path` instance for a unit regular polygon with the
- given *numVertices* such that the circumscribing circle has radius 1.0,
- centered at (0, 0).
- """
- if numVertices <= 16:
- path = cls._unit_regular_polygons.get(numVertices)
- else:
- path = None
- if path is None:
- theta = ((2 * np.pi / numVertices) * np.arange(numVertices + 1)
- # This initial rotation is to make sure the polygon always
- # "points-up".
- + np.pi / 2)
- verts = np.column_stack((np.cos(theta), np.sin(theta)))
- path = cls(verts, closed=True, readonly=True)
- if numVertices <= 16:
- cls._unit_regular_polygons[numVertices] = path
- return path
-
- _unit_regular_stars = WeakValueDictionary()
-
- @classmethod
- def unit_regular_star(cls, numVertices, innerCircle=0.5):
- """
- Return a :class:`Path` for a unit regular star with the given
- numVertices and radius of 1.0, centered at (0, 0).
- """
- if numVertices <= 16:
- path = cls._unit_regular_stars.get((numVertices, innerCircle))
- else:
- path = None
- if path is None:
- ns2 = numVertices * 2
- theta = (2*np.pi/ns2 * np.arange(ns2 + 1))
- # This initial rotation is to make sure the polygon always
- # "points-up"
- theta += np.pi / 2.0
- r = np.ones(ns2 + 1)
- r[1::2] = innerCircle
- verts = (r * np.vstack((np.cos(theta), np.sin(theta)))).T
- path = cls(verts, closed=True, readonly=True)
- if numVertices <= 16:
- cls._unit_regular_stars[(numVertices, innerCircle)] = path
- return path
-
- @classmethod
- def unit_regular_asterisk(cls, numVertices):
- """
- Return a :class:`Path` for a unit regular asterisk with the given
- numVertices and radius of 1.0, centered at (0, 0).
- """
- return cls.unit_regular_star(numVertices, 0.0)
-
- _unit_circle = None
-
- @classmethod
- def unit_circle(cls):
- """
- Return the readonly :class:`Path` of the unit circle.
-
- For most cases, :func:`Path.circle` will be what you want.
- """
- if cls._unit_circle is None:
- cls._unit_circle = cls.circle(center=(0, 0), radius=1,
- readonly=True)
- return cls._unit_circle
-
- @classmethod
- def circle(cls, center=(0., 0.), radius=1., readonly=False):
- """
- Return a `Path` representing a circle of a given radius and center.
-
- Parameters
- ----------
- center : (float, float), default: (0, 0)
- The center of the circle.
- radius : float, default: 1
- The radius of the circle.
- readonly : bool
- Whether the created path should have the "readonly" argument
- set when creating the Path instance.
-
- Notes
- -----
- The circle is approximated using 8 cubic Bézier curves, as described in
-
- Lancaster, Don. `Approximating a Circle or an Ellipse Using Four
- Bezier Cubic Splines <https://www.tinaja.com/glib/ellipse4.pdf>`_.
- """
- MAGIC = 0.2652031
- SQRTHALF = np.sqrt(0.5)
- MAGIC45 = SQRTHALF * MAGIC
-
- vertices = np.array([[0.0, -1.0],
-
- [MAGIC, -1.0],
- [SQRTHALF-MAGIC45, -SQRTHALF-MAGIC45],
- [SQRTHALF, -SQRTHALF],
-
- [SQRTHALF+MAGIC45, -SQRTHALF+MAGIC45],
- [1.0, -MAGIC],
- [1.0, 0.0],
-
- [1.0, MAGIC],
- [SQRTHALF+MAGIC45, SQRTHALF-MAGIC45],
- [SQRTHALF, SQRTHALF],
-
- [SQRTHALF-MAGIC45, SQRTHALF+MAGIC45],
- [MAGIC, 1.0],
- [0.0, 1.0],
-
- [-MAGIC, 1.0],
- [-SQRTHALF+MAGIC45, SQRTHALF+MAGIC45],
- [-SQRTHALF, SQRTHALF],
-
- [-SQRTHALF-MAGIC45, SQRTHALF-MAGIC45],
- [-1.0, MAGIC],
- [-1.0, 0.0],
-
- [-1.0, -MAGIC],
- [-SQRTHALF-MAGIC45, -SQRTHALF+MAGIC45],
- [-SQRTHALF, -SQRTHALF],
-
- [-SQRTHALF+MAGIC45, -SQRTHALF-MAGIC45],
- [-MAGIC, -1.0],
- [0.0, -1.0],
-
- [0.0, -1.0]],
- dtype=float)
-
- codes = [cls.CURVE4] * 26
- codes[0] = cls.MOVETO
- codes[-1] = cls.CLOSEPOLY
- return Path(vertices * radius + center, codes, readonly=readonly)
-
- _unit_circle_righthalf = None
-
- @classmethod
- def unit_circle_righthalf(cls):
- """
- Return a `Path` of the right half of a unit circle.
-
- See `Path.circle` for the reference on the approximation used.
- """
- if cls._unit_circle_righthalf is None:
- MAGIC = 0.2652031
- SQRTHALF = np.sqrt(0.5)
- MAGIC45 = SQRTHALF * MAGIC
-
- vertices = np.array(
- [[0.0, -1.0],
-
- [MAGIC, -1.0],
- [SQRTHALF-MAGIC45, -SQRTHALF-MAGIC45],
- [SQRTHALF, -SQRTHALF],
-
- [SQRTHALF+MAGIC45, -SQRTHALF+MAGIC45],
- [1.0, -MAGIC],
- [1.0, 0.0],
-
- [1.0, MAGIC],
- [SQRTHALF+MAGIC45, SQRTHALF-MAGIC45],
- [SQRTHALF, SQRTHALF],
-
- [SQRTHALF-MAGIC45, SQRTHALF+MAGIC45],
- [MAGIC, 1.0],
- [0.0, 1.0],
-
- [0.0, -1.0]],
-
- float)
-
- codes = np.full(14, cls.CURVE4, dtype=cls.code_type)
- codes[0] = cls.MOVETO
- codes[-1] = cls.CLOSEPOLY
-
- cls._unit_circle_righthalf = cls(vertices, codes, readonly=True)
- return cls._unit_circle_righthalf
-
- @classmethod
- def arc(cls, theta1, theta2, n=None, is_wedge=False):
- """
- Return a `Path` for the unit circle arc from angles *theta1* to
- *theta2* (in degrees).
-
- *theta2* is unwrapped to produce the shortest arc within 360 degrees.
- That is, if *theta2* > *theta1* + 360, the arc will be from *theta1* to
- *theta2* - 360 and not a full circle plus some extra overlap.
-
- If *n* is provided, it is the number of spline segments to make.
- If *n* is not provided, the number of spline segments is
- determined based on the delta between *theta1* and *theta2*.
-
- Masionobe, L. 2003. `Drawing an elliptical arc using
- polylines, quadratic or cubic Bezier curves
- <https://web.archive.org/web/20190318044212/http://www.spaceroots.org/documents/ellipse/index.html>`_.
- """
- halfpi = np.pi * 0.5
-
- eta1 = theta1
- eta2 = theta2 - 360 * np.floor((theta2 - theta1) / 360)
- # Ensure 2pi range is not flattened to 0 due to floating-point errors,
- # but don't try to expand existing 0 range.
- if theta2 != theta1 and eta2 <= eta1:
- eta2 += 360
- eta1, eta2 = np.deg2rad([eta1, eta2])
-
- # number of curve segments to make
- if n is None:
- n = int(2 ** np.ceil((eta2 - eta1) / halfpi))
- if n < 1:
- raise ValueError("n must be >= 1 or None")
-
- deta = (eta2 - eta1) / n
- t = np.tan(0.5 * deta)
- alpha = np.sin(deta) * (np.sqrt(4.0 + 3.0 * t * t) - 1) / 3.0
-
- steps = np.linspace(eta1, eta2, n + 1, True)
- cos_eta = np.cos(steps)
- sin_eta = np.sin(steps)
-
- xA = cos_eta[:-1]
- yA = sin_eta[:-1]
- xA_dot = -yA
- yA_dot = xA
-
- xB = cos_eta[1:]
- yB = sin_eta[1:]
- xB_dot = -yB
- yB_dot = xB
-
- if is_wedge:
- length = n * 3 + 4
- vertices = np.zeros((length, 2), float)
- codes = np.full(length, cls.CURVE4, dtype=cls.code_type)
- vertices[1] = [xA[0], yA[0]]
- codes[0:2] = [cls.MOVETO, cls.LINETO]
- codes[-2:] = [cls.LINETO, cls.CLOSEPOLY]
- vertex_offset = 2
- end = length - 2
- else:
- length = n * 3 + 1
- vertices = np.empty((length, 2), float)
- codes = np.full(length, cls.CURVE4, dtype=cls.code_type)
- vertices[0] = [xA[0], yA[0]]
- codes[0] = cls.MOVETO
- vertex_offset = 1
- end = length
-
- vertices[vertex_offset:end:3, 0] = xA + alpha * xA_dot
- vertices[vertex_offset:end:3, 1] = yA + alpha * yA_dot
- vertices[vertex_offset+1:end:3, 0] = xB - alpha * xB_dot
- vertices[vertex_offset+1:end:3, 1] = yB - alpha * yB_dot
- vertices[vertex_offset+2:end:3, 0] = xB
- vertices[vertex_offset+2:end:3, 1] = yB
-
- return cls(vertices, codes, readonly=True)
-
- @classmethod
- def wedge(cls, theta1, theta2, n=None):
- """
- Return a `Path` for the unit circle wedge from angles *theta1* to
- *theta2* (in degrees).
-
- *theta2* is unwrapped to produce the shortest wedge within 360 degrees.
- That is, if *theta2* > *theta1* + 360, the wedge will be from *theta1*
- to *theta2* - 360 and not a full circle plus some extra overlap.
-
- If *n* is provided, it is the number of spline segments to make.
- If *n* is not provided, the number of spline segments is
- determined based on the delta between *theta1* and *theta2*.
-
- See `Path.arc` for the reference on the approximation used.
- """
- return cls.arc(theta1, theta2, n, True)
-
- @staticmethod
- @lru_cache(8)
- def hatch(hatchpattern, density=6):
- """
- Given a hatch specifier, *hatchpattern*, generates a `Path` that
- can be used in a repeated hatching pattern. *density* is the
- number of lines per unit square.
- """
- from matplotlib.hatch import get_path
- return (get_path(hatchpattern, density)
- if hatchpattern is not None else None)
-
- def clip_to_bbox(self, bbox, inside=True):
- """
- Clip the path to the given bounding box.
-
- The path must be made up of one or more closed polygons. This
- algorithm will not behave correctly for unclosed paths.
-
- If *inside* is `True`, clip to the inside of the box, otherwise
- to the outside of the box.
- """
- verts = _path.clip_path_to_rect(self, bbox, inside)
- paths = [Path(poly) for poly in verts]
- return self.make_compound_path(*paths)
-
-
-def get_path_collection_extents(
- master_transform, paths, transforms, offsets, offset_transform):
- r"""
- Get bounding box of a `.PathCollection`\s internal objects.
-
- That is, given a sequence of `Path`\s, `.Transform`\s objects, and offsets, as found
- in a `.PathCollection`, return the bounding box that encapsulates all of them.
-
- Parameters
- ----------
- master_transform : `~matplotlib.transforms.Transform`
- Global transformation applied to all paths.
- paths : list of `Path`
- transforms : list of `~matplotlib.transforms.Affine2DBase`
- If non-empty, this overrides *master_transform*.
- offsets : (N, 2) array-like
- offset_transform : `~matplotlib.transforms.Affine2DBase`
- Transform applied to the offsets before offsetting the path.
-
- Notes
- -----
- The way that *paths*, *transforms* and *offsets* are combined follows the same
- method as for collections: each is iterated over independently, so if you have 3
- paths (A, B, C), 2 transforms (α, β) and 1 offset (O), their combinations are as
- follows:
-
- - (A, α, O)
- - (B, β, O)
- - (C, α, O)
- """
- from .transforms import Bbox
- if len(paths) == 0:
- raise ValueError("No paths provided")
- if len(offsets) == 0:
- _api.warn_deprecated(
- "3.8", message="Calling get_path_collection_extents() with an"
- " empty offsets list is deprecated since %(since)s. Support will"
- " be removed %(removal)s.")
- extents, minpos = _path.get_path_collection_extents(
- master_transform, paths, np.atleast_3d(transforms),
- offsets, offset_transform)
- return Bbox.from_extents(*extents, minpos=minpos)
diff --git a/contrib/python/matplotlib/py3/matplotlib/path.pyi b/contrib/python/matplotlib/py3/matplotlib/path.pyi
deleted file mode 100644
index 464fc6d9a9..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/path.pyi
+++ /dev/null
@@ -1,140 +0,0 @@
-from .bezier import BezierSegment
-from .transforms import Affine2D, Transform, Bbox
-from collections.abc import Generator, Iterable, Sequence
-
-import numpy as np
-from numpy.typing import ArrayLike
-
-from typing import Any, overload
-
-class Path:
- code_type: type[np.uint8]
- STOP: np.uint8
- MOVETO: np.uint8
- LINETO: np.uint8
- CURVE3: np.uint8
- CURVE4: np.uint8
- CLOSEPOLY: np.uint8
- NUM_VERTICES_FOR_CODE: dict[np.uint8, int]
-
- def __init__(
- self,
- vertices: ArrayLike,
- codes: ArrayLike | None = ...,
- _interpolation_steps: int = ...,
- closed: bool = ...,
- readonly: bool = ...,
- ) -> None: ...
- @property
- def vertices(self) -> ArrayLike: ...
- @vertices.setter
- def vertices(self, vertices: ArrayLike) -> None: ...
- @property
- def codes(self) -> ArrayLike | None: ...
- @codes.setter
- def codes(self, codes: ArrayLike) -> None: ...
- @property
- def simplify_threshold(self) -> float: ...
- @simplify_threshold.setter
- def simplify_threshold(self, threshold: float) -> None: ...
- @property
- def should_simplify(self) -> bool: ...
- @should_simplify.setter
- def should_simplify(self, should_simplify: bool) -> None: ...
- @property
- def readonly(self) -> bool: ...
- def copy(self) -> Path: ...
- def __deepcopy__(self, memo: dict[int, Any] | None = ...) -> Path: ...
- deepcopy = __deepcopy__
-
- @classmethod
- def make_compound_path_from_polys(cls, XY: ArrayLike) -> Path: ...
- @classmethod
- def make_compound_path(cls, *args: Path) -> Path: ...
- def __len__(self) -> int: ...
- def iter_segments(
- self,
- transform: Transform | None = ...,
- remove_nans: bool = ...,
- clip: tuple[float, float, float, float] | None = ...,
- snap: bool | None = ...,
- stroke_width: float = ...,
- simplify: bool | None = ...,
- curves: bool = ...,
- sketch: tuple[float, float, float] | None = ...,
- ) -> Generator[tuple[np.ndarray, np.uint8], None, None]: ...
- def iter_bezier(self, **kwargs) -> Generator[BezierSegment, None, None]: ...
- def cleaned(
- self,
- transform: Transform | None = ...,
- remove_nans: bool = ...,
- clip: tuple[float, float, float, float] | None = ...,
- *,
- simplify: bool | None = ...,
- curves: bool = ...,
- stroke_width: float = ...,
- snap: bool | None = ...,
- sketch: tuple[float, float, float] | None = ...
- ) -> Path: ...
- def transformed(self, transform: Transform) -> Path: ...
- def contains_point(
- self,
- point: tuple[float, float],
- transform: Transform | None = ...,
- radius: float = ...,
- ) -> bool: ...
- def contains_points(
- self, points: ArrayLike, transform: Transform | None = ..., radius: float = ...
- ) -> np.ndarray: ...
- def contains_path(self, path: Path, transform: Transform | None = ...) -> bool: ...
- def get_extents(self, transform: Transform | None = ..., **kwargs) -> Bbox: ...
- def intersects_path(self, other: Path, filled: bool = ...) -> bool: ...
- def intersects_bbox(self, bbox: Bbox, filled: bool = ...) -> bool: ...
- def interpolated(self, steps: int) -> Path: ...
- def to_polygons(
- self,
- transform: Transform | None = ...,
- width: float = ...,
- height: float = ...,
- closed_only: bool = ...,
- ) -> list[ArrayLike]: ...
- @classmethod
- def unit_rectangle(cls) -> Path: ...
- @classmethod
- def unit_regular_polygon(cls, numVertices: int) -> Path: ...
- @classmethod
- def unit_regular_star(cls, numVertices: int, innerCircle: float = ...) -> Path: ...
- @classmethod
- def unit_regular_asterisk(cls, numVertices: int) -> Path: ...
- @classmethod
- def unit_circle(cls) -> Path: ...
- @classmethod
- def circle(
- cls,
- center: tuple[float, float] = ...,
- radius: float = ...,
- readonly: bool = ...,
- ) -> Path: ...
- @classmethod
- def unit_circle_righthalf(cls) -> Path: ...
- @classmethod
- def arc(
- cls, theta1: float, theta2: float, n: int | None = ..., is_wedge: bool = ...
- ) -> Path: ...
- @classmethod
- def wedge(cls, theta1: float, theta2: float, n: int | None = ...) -> Path: ...
- @overload
- @staticmethod
- def hatch(hatchpattern: str, density: float = ...) -> Path: ...
- @overload
- @staticmethod
- def hatch(hatchpattern: None, density: float = ...) -> None: ...
- def clip_to_bbox(self, bbox: Bbox, inside: bool = ...) -> Path: ...
-
-def get_path_collection_extents(
- master_transform: Transform,
- paths: Sequence[Path],
- transforms: Iterable[Affine2D],
- offsets: ArrayLike,
- offset_transform: Affine2D,
-) -> Bbox: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/patheffects.py b/contrib/python/matplotlib/py3/matplotlib/patheffects.py
deleted file mode 100644
index 5bb4c8e2a5..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/patheffects.py
+++ /dev/null
@@ -1,513 +0,0 @@
-"""
-Defines classes for path effects. The path effects are supported in `.Text`,
-`.Line2D` and `.Patch`.
-
-.. seealso::
- :ref:`patheffects_guide`
-"""
-
-from matplotlib.backend_bases import RendererBase
-from matplotlib import colors as mcolors
-from matplotlib import patches as mpatches
-from matplotlib import transforms as mtransforms
-from matplotlib.path import Path
-import numpy as np
-
-
-class AbstractPathEffect:
- """
- A base class for path effects.
-
- Subclasses should override the ``draw_path`` method to add effect
- functionality.
- """
-
- def __init__(self, offset=(0., 0.)):
- """
- Parameters
- ----------
- offset : (float, float), default: (0, 0)
- The (x, y) offset to apply to the path, measured in points.
- """
- self._offset = offset
-
- def _offset_transform(self, renderer):
- """Apply the offset to the given transform."""
- return mtransforms.Affine2D().translate(
- *map(renderer.points_to_pixels, self._offset))
-
- def _update_gc(self, gc, new_gc_dict):
- """
- Update the given GraphicsContext with the given dict of properties.
-
- The keys in the dictionary are used to identify the appropriate
- ``set_`` method on the *gc*.
- """
- new_gc_dict = new_gc_dict.copy()
-
- dashes = new_gc_dict.pop("dashes", None)
- if dashes:
- gc.set_dashes(**dashes)
-
- for k, v in new_gc_dict.items():
- set_method = getattr(gc, 'set_' + k, None)
- if not callable(set_method):
- raise AttributeError(f'Unknown property {k}')
- set_method(v)
- return gc
-
- def draw_path(self, renderer, gc, tpath, affine, rgbFace=None):
- """
- Derived should override this method. The arguments are the same
- as :meth:`matplotlib.backend_bases.RendererBase.draw_path`
- except the first argument is a renderer.
- """
- # Get the real renderer, not a PathEffectRenderer.
- if isinstance(renderer, PathEffectRenderer):
- renderer = renderer._renderer
- return renderer.draw_path(gc, tpath, affine, rgbFace)
-
-
-class PathEffectRenderer(RendererBase):
- """
- Implements a Renderer which contains another renderer.
-
- This proxy then intercepts draw calls, calling the appropriate
- :class:`AbstractPathEffect` draw method.
-
- .. note::
- Not all methods have been overridden on this RendererBase subclass.
- It may be necessary to add further methods to extend the PathEffects
- capabilities further.
- """
-
- def __init__(self, path_effects, renderer):
- """
- Parameters
- ----------
- path_effects : iterable of :class:`AbstractPathEffect`
- The path effects which this renderer represents.
- renderer : `~matplotlib.backend_bases.RendererBase` subclass
-
- """
- self._path_effects = path_effects
- self._renderer = renderer
-
- def copy_with_path_effect(self, path_effects):
- return self.__class__(path_effects, self._renderer)
-
- def draw_path(self, gc, tpath, affine, rgbFace=None):
- for path_effect in self._path_effects:
- path_effect.draw_path(self._renderer, gc, tpath, affine,
- rgbFace)
-
- def draw_markers(
- self, gc, marker_path, marker_trans, path, *args, **kwargs):
- # We do a little shimmy so that all markers are drawn for each path
- # effect in turn. Essentially, we induce recursion (depth 1) which is
- # terminated once we have just a single path effect to work with.
- if len(self._path_effects) == 1:
- # Call the base path effect function - this uses the unoptimised
- # approach of calling "draw_path" multiple times.
- return super().draw_markers(gc, marker_path, marker_trans, path,
- *args, **kwargs)
-
- for path_effect in self._path_effects:
- renderer = self.copy_with_path_effect([path_effect])
- # Recursively call this method, only next time we will only have
- # one path effect.
- renderer.draw_markers(gc, marker_path, marker_trans, path,
- *args, **kwargs)
-
- def draw_path_collection(self, gc, master_transform, paths, *args,
- **kwargs):
- # We do a little shimmy so that all paths are drawn for each path
- # effect in turn. Essentially, we induce recursion (depth 1) which is
- # terminated once we have just a single path effect to work with.
- if len(self._path_effects) == 1:
- # Call the base path effect function - this uses the unoptimised
- # approach of calling "draw_path" multiple times.
- return super().draw_path_collection(gc, master_transform, paths,
- *args, **kwargs)
-
- for path_effect in self._path_effects:
- renderer = self.copy_with_path_effect([path_effect])
- # Recursively call this method, only next time we will only have
- # one path effect.
- renderer.draw_path_collection(gc, master_transform, paths,
- *args, **kwargs)
-
- def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath):
- # Implements the naive text drawing as is found in RendererBase.
- path, transform = self._get_text_path_transform(x, y, s, prop,
- angle, ismath)
- color = gc.get_rgb()
- gc.set_linewidth(0.0)
- self.draw_path(gc, path, transform, rgbFace=color)
-
- def __getattribute__(self, name):
- if name in ['flipy', 'get_canvas_width_height', 'new_gc',
- 'points_to_pixels', '_text2path', 'height', 'width']:
- return getattr(self._renderer, name)
- else:
- return object.__getattribute__(self, name)
-
-
-class Normal(AbstractPathEffect):
- """
- The "identity" PathEffect.
-
- The Normal PathEffect's sole purpose is to draw the original artist with
- no special path effect.
- """
-
-
-def _subclass_with_normal(effect_class):
- """
- Create a PathEffect class combining *effect_class* and a normal draw.
- """
-
- class withEffect(effect_class):
- def draw_path(self, renderer, gc, tpath, affine, rgbFace):
- super().draw_path(renderer, gc, tpath, affine, rgbFace)
- renderer.draw_path(gc, tpath, affine, rgbFace)
-
- withEffect.__name__ = f"with{effect_class.__name__}"
- withEffect.__qualname__ = f"with{effect_class.__name__}"
- withEffect.__doc__ = f"""
- A shortcut PathEffect for applying `.{effect_class.__name__}` and then
- drawing the original Artist.
-
- With this class you can use ::
-
- artist.set_path_effects([patheffects.with{effect_class.__name__}()])
-
- as a shortcut for ::
-
- artist.set_path_effects([patheffects.{effect_class.__name__}(),
- patheffects.Normal()])
- """
- # Docstring inheritance doesn't work for locally-defined subclasses.
- withEffect.draw_path.__doc__ = effect_class.draw_path.__doc__
- return withEffect
-
-
-class Stroke(AbstractPathEffect):
- """A line based PathEffect which re-draws a stroke."""
-
- def __init__(self, offset=(0, 0), **kwargs):
- """
- The path will be stroked with its gc updated with the given
- keyword arguments, i.e., the keyword arguments should be valid
- gc parameter values.
- """
- super().__init__(offset)
- self._gc = kwargs
-
- def draw_path(self, renderer, gc, tpath, affine, rgbFace):
- """Draw the path with updated gc."""
- gc0 = renderer.new_gc() # Don't modify gc, but a copy!
- gc0.copy_properties(gc)
- gc0 = self._update_gc(gc0, self._gc)
- renderer.draw_path(
- gc0, tpath, affine + self._offset_transform(renderer), rgbFace)
- gc0.restore()
-
-
-withStroke = _subclass_with_normal(effect_class=Stroke)
-
-
-class SimplePatchShadow(AbstractPathEffect):
- """A simple shadow via a filled patch."""
-
- def __init__(self, offset=(2, -2),
- shadow_rgbFace=None, alpha=None,
- rho=0.3, **kwargs):
- """
- Parameters
- ----------
- offset : (float, float), default: (2, -2)
- The (x, y) offset of the shadow in points.
- shadow_rgbFace : color
- The shadow color.
- alpha : float, default: 0.3
- The alpha transparency of the created shadow patch.
- rho : float, default: 0.3
- A scale factor to apply to the rgbFace color if *shadow_rgbFace*
- is not specified.
- **kwargs
- Extra keywords are stored and passed through to
- :meth:`AbstractPathEffect._update_gc`.
-
- """
- super().__init__(offset)
-
- if shadow_rgbFace is None:
- self._shadow_rgbFace = shadow_rgbFace
- else:
- self._shadow_rgbFace = mcolors.to_rgba(shadow_rgbFace)
-
- if alpha is None:
- alpha = 0.3
-
- self._alpha = alpha
- self._rho = rho
-
- #: The dictionary of keywords to update the graphics collection with.
- self._gc = kwargs
-
- def draw_path(self, renderer, gc, tpath, affine, rgbFace):
- """
- Overrides the standard draw_path to add the shadow offset and
- necessary color changes for the shadow.
- """
- gc0 = renderer.new_gc() # Don't modify gc, but a copy!
- gc0.copy_properties(gc)
-
- if self._shadow_rgbFace is None:
- r, g, b = (rgbFace or (1., 1., 1.))[:3]
- # Scale the colors by a factor to improve the shadow effect.
- shadow_rgbFace = (r * self._rho, g * self._rho, b * self._rho)
- else:
- shadow_rgbFace = self._shadow_rgbFace
-
- gc0.set_foreground("none")
- gc0.set_alpha(self._alpha)
- gc0.set_linewidth(0)
-
- gc0 = self._update_gc(gc0, self._gc)
- renderer.draw_path(
- gc0, tpath, affine + self._offset_transform(renderer),
- shadow_rgbFace)
- gc0.restore()
-
-
-withSimplePatchShadow = _subclass_with_normal(effect_class=SimplePatchShadow)
-
-
-class SimpleLineShadow(AbstractPathEffect):
- """A simple shadow via a line."""
-
- def __init__(self, offset=(2, -2),
- shadow_color='k', alpha=0.3, rho=0.3, **kwargs):
- """
- Parameters
- ----------
- offset : (float, float), default: (2, -2)
- The (x, y) offset to apply to the path, in points.
- shadow_color : color, default: 'black'
- The shadow color.
- A value of ``None`` takes the original artist's color
- with a scale factor of *rho*.
- alpha : float, default: 0.3
- The alpha transparency of the created shadow patch.
- rho : float, default: 0.3
- A scale factor to apply to the rgbFace color if *shadow_color*
- is ``None``.
- **kwargs
- Extra keywords are stored and passed through to
- :meth:`AbstractPathEffect._update_gc`.
- """
- super().__init__(offset)
- if shadow_color is None:
- self._shadow_color = shadow_color
- else:
- self._shadow_color = mcolors.to_rgba(shadow_color)
- self._alpha = alpha
- self._rho = rho
- #: The dictionary of keywords to update the graphics collection with.
- self._gc = kwargs
-
- def draw_path(self, renderer, gc, tpath, affine, rgbFace):
- """
- Overrides the standard draw_path to add the shadow offset and
- necessary color changes for the shadow.
- """
- gc0 = renderer.new_gc() # Don't modify gc, but a copy!
- gc0.copy_properties(gc)
-
- if self._shadow_color is None:
- r, g, b = (gc0.get_foreground() or (1., 1., 1.))[:3]
- # Scale the colors by a factor to improve the shadow effect.
- shadow_rgbFace = (r * self._rho, g * self._rho, b * self._rho)
- else:
- shadow_rgbFace = self._shadow_color
-
- gc0.set_foreground(shadow_rgbFace)
- gc0.set_alpha(self._alpha)
-
- gc0 = self._update_gc(gc0, self._gc)
- renderer.draw_path(
- gc0, tpath, affine + self._offset_transform(renderer))
- gc0.restore()
-
-
-class PathPatchEffect(AbstractPathEffect):
- """
- Draws a `.PathPatch` instance whose Path comes from the original
- PathEffect artist.
- """
-
- def __init__(self, offset=(0, 0), **kwargs):
- """
- Parameters
- ----------
- offset : (float, float), default: (0, 0)
- The (x, y) offset to apply to the path, in points.
- **kwargs
- All keyword arguments are passed through to the
- :class:`~matplotlib.patches.PathPatch` constructor. The
- properties which cannot be overridden are "path", "clip_box"
- "transform" and "clip_path".
- """
- super().__init__(offset=offset)
- self.patch = mpatches.PathPatch([], **kwargs)
-
- def draw_path(self, renderer, gc, tpath, affine, rgbFace):
- self.patch._path = tpath
- self.patch.set_transform(affine + self._offset_transform(renderer))
- self.patch.set_clip_box(gc.get_clip_rectangle())
- clip_path = gc.get_clip_path()
- if clip_path and self.patch.get_clip_path() is None:
- self.patch.set_clip_path(*clip_path)
- self.patch.draw(renderer)
-
-
-class TickedStroke(AbstractPathEffect):
- """
- A line-based PathEffect which draws a path with a ticked style.
-
- This line style is frequently used to represent constraints in
- optimization. The ticks may be used to indicate that one side
- of the line is invalid or to represent a closed boundary of a
- domain (i.e. a wall or the edge of a pipe).
-
- The spacing, length, and angle of ticks can be controlled.
-
- This line style is sometimes referred to as a hatched line.
-
- See also the :doc:`/gallery/misc/tickedstroke_demo` example.
- """
-
- def __init__(self, offset=(0, 0),
- spacing=10.0, angle=45.0, length=np.sqrt(2),
- **kwargs):
- """
- Parameters
- ----------
- offset : (float, float), default: (0, 0)
- The (x, y) offset to apply to the path, in points.
- spacing : float, default: 10.0
- The spacing between ticks in points.
- angle : float, default: 45.0
- The angle between the path and the tick in degrees. The angle
- is measured as if you were an ant walking along the curve, with
- zero degrees pointing directly ahead, 90 to your left, -90
- to your right, and 180 behind you. To change side of the ticks,
- change sign of the angle.
- length : float, default: 1.414
- The length of the tick relative to spacing.
- Recommended length = 1.414 (sqrt(2)) when angle=45, length=1.0
- when angle=90 and length=2.0 when angle=60.
- **kwargs
- Extra keywords are stored and passed through to
- :meth:`AbstractPathEffect._update_gc`.
-
- Examples
- --------
- See :doc:`/gallery/misc/tickedstroke_demo`.
- """
- super().__init__(offset)
-
- self._spacing = spacing
- self._angle = angle
- self._length = length
- self._gc = kwargs
-
- def draw_path(self, renderer, gc, tpath, affine, rgbFace):
- """Draw the path with updated gc."""
- # Do not modify the input! Use copy instead.
- gc0 = renderer.new_gc()
- gc0.copy_properties(gc)
-
- gc0 = self._update_gc(gc0, self._gc)
- trans = affine + self._offset_transform(renderer)
-
- theta = -np.radians(self._angle)
- trans_matrix = np.array([[np.cos(theta), -np.sin(theta)],
- [np.sin(theta), np.cos(theta)]])
-
- # Convert spacing parameter to pixels.
- spacing_px = renderer.points_to_pixels(self._spacing)
-
- # Transform before evaluation because to_polygons works at resolution
- # of one -- assuming it is working in pixel space.
- transpath = affine.transform_path(tpath)
-
- # Evaluate path to straight line segments that can be used to
- # construct line ticks.
- polys = transpath.to_polygons(closed_only=False)
-
- for p in polys:
- x = p[:, 0]
- y = p[:, 1]
-
- # Can not interpolate points or draw line if only one point in
- # polyline.
- if x.size < 2:
- continue
-
- # Find distance between points on the line
- ds = np.hypot(x[1:] - x[:-1], y[1:] - y[:-1])
-
- # Build parametric coordinate along curve
- s = np.concatenate(([0.0], np.cumsum(ds)))
- s_total = s[-1]
-
- num = int(np.ceil(s_total / spacing_px)) - 1
- # Pick parameter values for ticks.
- s_tick = np.linspace(spacing_px/2, s_total - spacing_px/2, num)
-
- # Find points along the parameterized curve
- x_tick = np.interp(s_tick, s, x)
- y_tick = np.interp(s_tick, s, y)
-
- # Find unit vectors in local direction of curve
- delta_s = self._spacing * .001
- u = (np.interp(s_tick + delta_s, s, x) - x_tick) / delta_s
- v = (np.interp(s_tick + delta_s, s, y) - y_tick) / delta_s
-
- # Normalize slope into unit slope vector.
- n = np.hypot(u, v)
- mask = n == 0
- n[mask] = 1.0
-
- uv = np.array([u / n, v / n]).T
- uv[mask] = np.array([0, 0]).T
-
- # Rotate and scale unit vector into tick vector
- dxy = np.dot(uv, trans_matrix) * self._length * spacing_px
-
- # Build tick endpoints
- x_end = x_tick + dxy[:, 0]
- y_end = y_tick + dxy[:, 1]
-
- # Interleave ticks to form Path vertices
- xyt = np.empty((2 * num, 2), dtype=x_tick.dtype)
- xyt[0::2, 0] = x_tick
- xyt[1::2, 0] = x_end
- xyt[0::2, 1] = y_tick
- xyt[1::2, 1] = y_end
-
- # Build up vector of Path codes
- codes = np.tile([Path.MOVETO, Path.LINETO], num)
-
- # Construct and draw resulting path
- h = Path(xyt, codes)
- # Transform back to data space during render
- renderer.draw_path(gc0, h, affine.inverted() + trans, rgbFace)
-
- gc0.restore()
-
-
-withTickedStroke = _subclass_with_normal(effect_class=TickedStroke)
diff --git a/contrib/python/matplotlib/py3/matplotlib/patheffects.pyi b/contrib/python/matplotlib/py3/matplotlib/patheffects.pyi
deleted file mode 100644
index 5d8dcfeab6..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/patheffects.pyi
+++ /dev/null
@@ -1,106 +0,0 @@
-from collections.abc import Iterable, Sequence
-from typing import Any
-
-from matplotlib.backend_bases import RendererBase, GraphicsContextBase
-from matplotlib.path import Path
-from matplotlib.patches import Patch
-from matplotlib.transforms import Transform
-
-from matplotlib.typing import ColorType
-
-class AbstractPathEffect:
- def __init__(self, offset: tuple[float, float] = ...) -> None: ...
- def draw_path(
- self,
- renderer: RendererBase,
- gc: GraphicsContextBase,
- tpath: Path,
- affine: Transform,
- rgbFace: ColorType | None = ...,
- ) -> None: ...
-
-class PathEffectRenderer(RendererBase):
- def __init__(
- self, path_effects: Iterable[AbstractPathEffect], renderer: RendererBase
- ) -> None: ...
- def copy_with_path_effect(self, path_effects: Iterable[AbstractPathEffect]) -> PathEffectRenderer: ...
- def draw_path(
- self,
- gc: GraphicsContextBase,
- tpath: Path,
- affine: Transform,
- rgbFace: ColorType | None = ...,
- ) -> None: ...
- def draw_markers(
- self,
- gc: GraphicsContextBase,
- marker_path: Path,
- marker_trans: Transform,
- path: Path,
- *args,
- **kwargs
- ) -> None: ...
- def draw_path_collection(
- self,
- gc: GraphicsContextBase,
- master_transform: Transform,
- paths: Sequence[Path],
- *args,
- **kwargs
- ) -> None: ...
- def __getattribute__(self, name: str) -> Any: ...
-
-class Normal(AbstractPathEffect): ...
-
-class Stroke(AbstractPathEffect):
- def __init__(self, offset: tuple[float, float] = ..., **kwargs) -> None: ...
- # rgbFace becomes non-optional
- def draw_path(self, renderer: RendererBase, gc: GraphicsContextBase, tpath: Path, affine: Transform, rgbFace: ColorType) -> None: ... # type: ignore
-
-class withStroke(Stroke): ...
-
-class SimplePatchShadow(AbstractPathEffect):
- def __init__(
- self,
- offset: tuple[float, float] = ...,
- shadow_rgbFace: ColorType | None = ...,
- alpha: float | None = ...,
- rho: float = ...,
- **kwargs
- ) -> None: ...
- # rgbFace becomes non-optional
- def draw_path(self, renderer: RendererBase, gc: GraphicsContextBase, tpath: Path, affine: Transform, rgbFace: ColorType) -> None: ... # type: ignore
-
-class withSimplePatchShadow(SimplePatchShadow): ...
-
-class SimpleLineShadow(AbstractPathEffect):
- def __init__(
- self,
- offset: tuple[float, float] = ...,
- shadow_color: ColorType = ...,
- alpha: float = ...,
- rho: float = ...,
- **kwargs
- ) -> None: ...
- # rgbFace becomes non-optional
- def draw_path(self, renderer: RendererBase, gc: GraphicsContextBase, tpath: Path, affine: Transform, rgbFace: ColorType) -> None: ... # type: ignore
-
-class PathPatchEffect(AbstractPathEffect):
- patch: Patch
- def __init__(self, offset: tuple[float, float] = ..., **kwargs) -> None: ...
- # rgbFace becomes non-optional
- def draw_path(self, renderer: RendererBase, gc: GraphicsContextBase, tpath: Path, affine: Transform, rgbFace: ColorType) -> None: ... # type: ignore
-
-class TickedStroke(AbstractPathEffect):
- def __init__(
- self,
- offset: tuple[float, float] = ...,
- spacing: float = ...,
- angle: float = ...,
- length: float = ...,
- **kwargs
- ) -> None: ...
- # rgbFace becomes non-optional
- def draw_path(self, renderer: RendererBase, gc: GraphicsContextBase, tpath: Path, affine: Transform, rgbFace: ColorType) -> None: ... # type: ignore
-
-class withTickedStroke(TickedStroke): ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/projections/__init__.py b/contrib/python/matplotlib/py3/matplotlib/projections/__init__.py
deleted file mode 100644
index 4c5ef8e250..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/projections/__init__.py
+++ /dev/null
@@ -1,126 +0,0 @@
-"""
-Non-separable transforms that map from data space to screen space.
-
-Projections are defined as `~.axes.Axes` subclasses. They include the
-following elements:
-
-- A transformation from data coordinates into display coordinates.
-
-- An inverse of that transformation. This is used, for example, to convert
- mouse positions from screen space back into data space.
-
-- Transformations for the gridlines, ticks and ticklabels. Custom projections
- will often need to place these elements in special locations, and Matplotlib
- has a facility to help with doing so.
-
-- Setting up default values (overriding `~.axes.Axes.cla`), since the defaults
- for a rectilinear axes may not be appropriate.
-
-- Defining the shape of the axes, for example, an elliptical axes, that will be
- used to draw the background of the plot and for clipping any data elements.
-
-- Defining custom locators and formatters for the projection. For example, in
- a geographic projection, it may be more convenient to display the grid in
- degrees, even if the data is in radians.
-
-- Set up interactive panning and zooming. This is left as an "advanced"
- feature left to the reader, but there is an example of this for polar plots
- in `matplotlib.projections.polar`.
-
-- Any additional methods for additional convenience or features.
-
-Once the projection axes is defined, it can be used in one of two ways:
-
-- By defining the class attribute ``name``, the projection axes can be
- registered with `matplotlib.projections.register_projection` and subsequently
- simply invoked by name::
-
- fig.add_subplot(projection="my_proj_name")
-
-- For more complex, parameterisable projections, a generic "projection" object
- may be defined which includes the method ``_as_mpl_axes``. ``_as_mpl_axes``
- should take no arguments and return the projection's axes subclass and a
- dictionary of additional arguments to pass to the subclass' ``__init__``
- method. Subsequently a parameterised projection can be initialised with::
-
- fig.add_subplot(projection=MyProjection(param1=param1_value))
-
- where MyProjection is an object which implements a ``_as_mpl_axes`` method.
-
-A full-fledged and heavily annotated example is in
-:doc:`/gallery/misc/custom_projection`. The polar plot functionality in
-`matplotlib.projections.polar` may also be of interest.
-"""
-
-from .. import axes, _docstring
-from .geo import AitoffAxes, HammerAxes, LambertAxes, MollweideAxes
-from .polar import PolarAxes
-
-try:
- from mpl_toolkits.mplot3d import Axes3D
-except Exception:
- import warnings
- warnings.warn("Unable to import Axes3D. This may be due to multiple versions of "
- "Matplotlib being installed (e.g. as a system package and as a pip "
- "package). As a result, the 3D projection is not available.")
- Axes3D = None
-
-
-class ProjectionRegistry:
- """A mapping of registered projection names to projection classes."""
-
- def __init__(self):
- self._all_projection_types = {}
-
- def register(self, *projections):
- """Register a new set of projections."""
- for projection in projections:
- name = projection.name
- self._all_projection_types[name] = projection
-
- def get_projection_class(self, name):
- """Get a projection class from its *name*."""
- return self._all_projection_types[name]
-
- def get_projection_names(self):
- """Return the names of all projections currently registered."""
- return sorted(self._all_projection_types)
-
-
-projection_registry = ProjectionRegistry()
-projection_registry.register(
- axes.Axes,
- PolarAxes,
- AitoffAxes,
- HammerAxes,
- LambertAxes,
- MollweideAxes,
-)
-if Axes3D is not None:
- projection_registry.register(Axes3D)
-else:
- # remove from namespace if not importable
- del Axes3D
-
-
-def register_projection(cls):
- projection_registry.register(cls)
-
-
-def get_projection_class(projection=None):
- """
- Get a projection class from its name.
-
- If *projection* is None, a standard rectilinear projection is returned.
- """
- if projection is None:
- projection = 'rectilinear'
-
- try:
- return projection_registry.get_projection_class(projection)
- except KeyError as err:
- raise ValueError("Unknown projection %r" % projection) from err
-
-
-get_projection_names = projection_registry.get_projection_names
-_docstring.interpd.update(projection_names=get_projection_names())
diff --git a/contrib/python/matplotlib/py3/matplotlib/projections/__init__.pyi b/contrib/python/matplotlib/py3/matplotlib/projections/__init__.pyi
deleted file mode 100644
index 0f8b6c0980..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/projections/__init__.pyi
+++ /dev/null
@@ -1,15 +0,0 @@
-from .geo import AitoffAxes, HammerAxes, LambertAxes, MollweideAxes
-from .polar import PolarAxes
-from ..axes import Axes
-
-class ProjectionRegistry:
- def __init__(self) -> None: ...
- def register(self, *projections: type[Axes]) -> None: ...
- def get_projection_class(self, name: str) -> type[Axes]: ...
- def get_projection_names(self) -> list[str]: ...
-
-projection_registry: ProjectionRegistry
-
-def register_projection(cls: type[Axes]) -> None: ...
-def get_projection_class(projection: str | None = ...) -> type[Axes]: ...
-def get_projection_names() -> list[str]: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/projections/geo.py b/contrib/python/matplotlib/py3/matplotlib/projections/geo.py
deleted file mode 100644
index 498b2f72eb..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/projections/geo.py
+++ /dev/null
@@ -1,510 +0,0 @@
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api
-from matplotlib.axes import Axes
-import matplotlib.axis as maxis
-from matplotlib.patches import Circle
-from matplotlib.path import Path
-import matplotlib.spines as mspines
-from matplotlib.ticker import (
- Formatter, NullLocator, FixedLocator, NullFormatter)
-from matplotlib.transforms import Affine2D, BboxTransformTo, Transform
-
-
-class GeoAxes(Axes):
- """An abstract base class for geographic projections."""
-
- class ThetaFormatter(Formatter):
- """
- Used to format the theta tick labels. Converts the native
- unit of radians into degrees and adds a degree symbol.
- """
- def __init__(self, round_to=1.0):
- self._round_to = round_to
-
- def __call__(self, x, pos=None):
- degrees = round(np.rad2deg(x) / self._round_to) * self._round_to
- return f"{degrees:0.0f}\N{DEGREE SIGN}"
-
- RESOLUTION = 75
-
- def _init_axis(self):
- self.xaxis = maxis.XAxis(self, clear=False)
- self.yaxis = maxis.YAxis(self, clear=False)
- self.spines['geo'].register_axis(self.yaxis)
-
- def clear(self):
- # docstring inherited
- super().clear()
-
- self.set_longitude_grid(30)
- self.set_latitude_grid(15)
- self.set_longitude_grid_ends(75)
- self.xaxis.set_minor_locator(NullLocator())
- self.yaxis.set_minor_locator(NullLocator())
- self.xaxis.set_ticks_position('none')
- self.yaxis.set_ticks_position('none')
- self.yaxis.set_tick_params(label1On=True)
- # Why do we need to turn on yaxis tick labels, but
- # xaxis tick labels are already on?
-
- self.grid(mpl.rcParams['axes.grid'])
-
- Axes.set_xlim(self, -np.pi, np.pi)
- Axes.set_ylim(self, -np.pi / 2.0, np.pi / 2.0)
-
- def _set_lim_and_transforms(self):
- # A (possibly non-linear) projection on the (already scaled) data
- self.transProjection = self._get_core_transform(self.RESOLUTION)
-
- self.transAffine = self._get_affine_transform()
-
- self.transAxes = BboxTransformTo(self.bbox)
-
- # The complete data transformation stack -- from data all the
- # way to display coordinates
- self.transData = \
- self.transProjection + \
- self.transAffine + \
- self.transAxes
-
- # This is the transform for longitude ticks.
- self._xaxis_pretransform = \
- Affine2D() \
- .scale(1, self._longitude_cap * 2) \
- .translate(0, -self._longitude_cap)
- self._xaxis_transform = \
- self._xaxis_pretransform + \
- self.transData
- self._xaxis_text1_transform = \
- Affine2D().scale(1, 0) + \
- self.transData + \
- Affine2D().translate(0, 4)
- self._xaxis_text2_transform = \
- Affine2D().scale(1, 0) + \
- self.transData + \
- Affine2D().translate(0, -4)
-
- # This is the transform for latitude ticks.
- yaxis_stretch = Affine2D().scale(np.pi * 2, 1).translate(-np.pi, 0)
- yaxis_space = Affine2D().scale(1, 1.1)
- self._yaxis_transform = \
- yaxis_stretch + \
- self.transData
- yaxis_text_base = \
- yaxis_stretch + \
- self.transProjection + \
- (yaxis_space +
- self.transAffine +
- self.transAxes)
- self._yaxis_text1_transform = \
- yaxis_text_base + \
- Affine2D().translate(-8, 0)
- self._yaxis_text2_transform = \
- yaxis_text_base + \
- Affine2D().translate(8, 0)
-
- def _get_affine_transform(self):
- transform = self._get_core_transform(1)
- xscale, _ = transform.transform((np.pi, 0))
- _, yscale = transform.transform((0, np.pi/2))
- return Affine2D() \
- .scale(0.5 / xscale, 0.5 / yscale) \
- .translate(0.5, 0.5)
-
- def get_xaxis_transform(self, which='grid'):
- _api.check_in_list(['tick1', 'tick2', 'grid'], which=which)
- return self._xaxis_transform
-
- def get_xaxis_text1_transform(self, pad):
- return self._xaxis_text1_transform, 'bottom', 'center'
-
- def get_xaxis_text2_transform(self, pad):
- return self._xaxis_text2_transform, 'top', 'center'
-
- def get_yaxis_transform(self, which='grid'):
- _api.check_in_list(['tick1', 'tick2', 'grid'], which=which)
- return self._yaxis_transform
-
- def get_yaxis_text1_transform(self, pad):
- return self._yaxis_text1_transform, 'center', 'right'
-
- def get_yaxis_text2_transform(self, pad):
- return self._yaxis_text2_transform, 'center', 'left'
-
- def _gen_axes_patch(self):
- return Circle((0.5, 0.5), 0.5)
-
- def _gen_axes_spines(self):
- return {'geo': mspines.Spine.circular_spine(self, (0.5, 0.5), 0.5)}
-
- def set_yscale(self, *args, **kwargs):
- if args[0] != 'linear':
- raise NotImplementedError
-
- set_xscale = set_yscale
-
- def set_xlim(self, *args, **kwargs):
- """Not supported. Please consider using Cartopy."""
- raise TypeError("Changing axes limits of a geographic projection is "
- "not supported. Please consider using Cartopy.")
-
- set_ylim = set_xlim
-
- def format_coord(self, lon, lat):
- """Return a format string formatting the coordinate."""
- lon, lat = np.rad2deg([lon, lat])
- ns = 'N' if lat >= 0.0 else 'S'
- ew = 'E' if lon >= 0.0 else 'W'
- return ('%f\N{DEGREE SIGN}%s, %f\N{DEGREE SIGN}%s'
- % (abs(lat), ns, abs(lon), ew))
-
- def set_longitude_grid(self, degrees):
- """
- Set the number of degrees between each longitude grid.
- """
- # Skip -180 and 180, which are the fixed limits.
- grid = np.arange(-180 + degrees, 180, degrees)
- self.xaxis.set_major_locator(FixedLocator(np.deg2rad(grid)))
- self.xaxis.set_major_formatter(self.ThetaFormatter(degrees))
-
- def set_latitude_grid(self, degrees):
- """
- Set the number of degrees between each latitude grid.
- """
- # Skip -90 and 90, which are the fixed limits.
- grid = np.arange(-90 + degrees, 90, degrees)
- self.yaxis.set_major_locator(FixedLocator(np.deg2rad(grid)))
- self.yaxis.set_major_formatter(self.ThetaFormatter(degrees))
-
- def set_longitude_grid_ends(self, degrees):
- """
- Set the latitude(s) at which to stop drawing the longitude grids.
- """
- self._longitude_cap = np.deg2rad(degrees)
- self._xaxis_pretransform \
- .clear() \
- .scale(1.0, self._longitude_cap * 2.0) \
- .translate(0.0, -self._longitude_cap)
-
- def get_data_ratio(self):
- """Return the aspect ratio of the data itself."""
- return 1.0
-
- ### Interactive panning
-
- def can_zoom(self):
- """
- Return whether this Axes supports the zoom box button functionality.
-
- This Axes object does not support interactive zoom box.
- """
- return False
-
- def can_pan(self):
- """
- Return whether this Axes supports the pan/zoom button functionality.
-
- This Axes object does not support interactive pan/zoom.
- """
- return False
-
- def start_pan(self, x, y, button):
- pass
-
- def end_pan(self):
- pass
-
- def drag_pan(self, button, key, x, y):
- pass
-
-
-class _GeoTransform(Transform):
- # Factoring out some common functionality.
- input_dims = output_dims = 2
-
- def __init__(self, resolution):
- """
- Create a new geographical transform.
-
- Resolution is the number of steps to interpolate between each input
- line segment to approximate its path in curved space.
- """
- super().__init__()
- self._resolution = resolution
-
- def __str__(self):
- return f"{type(self).__name__}({self._resolution})"
-
- def transform_path_non_affine(self, path):
- # docstring inherited
- ipath = path.interpolated(self._resolution)
- return Path(self.transform(ipath.vertices), ipath.codes)
-
-
-class AitoffAxes(GeoAxes):
- name = 'aitoff'
-
- class AitoffTransform(_GeoTransform):
- """The base Aitoff transform."""
-
- @_api.rename_parameter("3.8", "ll", "values")
- def transform_non_affine(self, values):
- # docstring inherited
- longitude, latitude = values.T
-
- # Pre-compute some values
- half_long = longitude / 2.0
- cos_latitude = np.cos(latitude)
-
- alpha = np.arccos(cos_latitude * np.cos(half_long))
- sinc_alpha = np.sinc(alpha / np.pi) # np.sinc is sin(pi*x)/(pi*x).
-
- x = (cos_latitude * np.sin(half_long)) / sinc_alpha
- y = np.sin(latitude) / sinc_alpha
- return np.column_stack([x, y])
-
- def inverted(self):
- # docstring inherited
- return AitoffAxes.InvertedAitoffTransform(self._resolution)
-
- class InvertedAitoffTransform(_GeoTransform):
-
- @_api.rename_parameter("3.8", "xy", "values")
- def transform_non_affine(self, values):
- # docstring inherited
- # MGDTODO: Math is hard ;(
- return np.full_like(values, np.nan)
-
- def inverted(self):
- # docstring inherited
- return AitoffAxes.AitoffTransform(self._resolution)
-
- def __init__(self, *args, **kwargs):
- self._longitude_cap = np.pi / 2.0
- super().__init__(*args, **kwargs)
- self.set_aspect(0.5, adjustable='box', anchor='C')
- self.clear()
-
- def _get_core_transform(self, resolution):
- return self.AitoffTransform(resolution)
-
-
-class HammerAxes(GeoAxes):
- name = 'hammer'
-
- class HammerTransform(_GeoTransform):
- """The base Hammer transform."""
-
- @_api.rename_parameter("3.8", "ll", "values")
- def transform_non_affine(self, values):
- # docstring inherited
- longitude, latitude = values.T
- half_long = longitude / 2.0
- cos_latitude = np.cos(latitude)
- sqrt2 = np.sqrt(2.0)
- alpha = np.sqrt(1.0 + cos_latitude * np.cos(half_long))
- x = (2.0 * sqrt2) * (cos_latitude * np.sin(half_long)) / alpha
- y = (sqrt2 * np.sin(latitude)) / alpha
- return np.column_stack([x, y])
-
- def inverted(self):
- # docstring inherited
- return HammerAxes.InvertedHammerTransform(self._resolution)
-
- class InvertedHammerTransform(_GeoTransform):
-
- @_api.rename_parameter("3.8", "xy", "values")
- def transform_non_affine(self, values):
- # docstring inherited
- x, y = values.T
- z = np.sqrt(1 - (x / 4) ** 2 - (y / 2) ** 2)
- longitude = 2 * np.arctan((z * x) / (2 * (2 * z ** 2 - 1)))
- latitude = np.arcsin(y*z)
- return np.column_stack([longitude, latitude])
-
- def inverted(self):
- # docstring inherited
- return HammerAxes.HammerTransform(self._resolution)
-
- def __init__(self, *args, **kwargs):
- self._longitude_cap = np.pi / 2.0
- super().__init__(*args, **kwargs)
- self.set_aspect(0.5, adjustable='box', anchor='C')
- self.clear()
-
- def _get_core_transform(self, resolution):
- return self.HammerTransform(resolution)
-
-
-class MollweideAxes(GeoAxes):
- name = 'mollweide'
-
- class MollweideTransform(_GeoTransform):
- """The base Mollweide transform."""
-
- @_api.rename_parameter("3.8", "ll", "values")
- def transform_non_affine(self, values):
- # docstring inherited
- def d(theta):
- delta = (-(theta + np.sin(theta) - pi_sin_l)
- / (1 + np.cos(theta)))
- return delta, np.abs(delta) > 0.001
-
- longitude, latitude = values.T
-
- clat = np.pi/2 - np.abs(latitude)
- ihigh = clat < 0.087 # within 5 degrees of the poles
- ilow = ~ihigh
- aux = np.empty(latitude.shape, dtype=float)
-
- if ilow.any(): # Newton-Raphson iteration
- pi_sin_l = np.pi * np.sin(latitude[ilow])
- theta = 2.0 * latitude[ilow]
- delta, large_delta = d(theta)
- while np.any(large_delta):
- theta[large_delta] += delta[large_delta]
- delta, large_delta = d(theta)
- aux[ilow] = theta / 2
-
- if ihigh.any(): # Taylor series-based approx. solution
- e = clat[ihigh]
- d = 0.5 * (3 * np.pi * e**2) ** (1.0/3)
- aux[ihigh] = (np.pi/2 - d) * np.sign(latitude[ihigh])
-
- xy = np.empty(values.shape, dtype=float)
- xy[:, 0] = (2.0 * np.sqrt(2.0) / np.pi) * longitude * np.cos(aux)
- xy[:, 1] = np.sqrt(2.0) * np.sin(aux)
-
- return xy
-
- def inverted(self):
- # docstring inherited
- return MollweideAxes.InvertedMollweideTransform(self._resolution)
-
- class InvertedMollweideTransform(_GeoTransform):
-
- @_api.rename_parameter("3.8", "xy", "values")
- def transform_non_affine(self, values):
- # docstring inherited
- x, y = values.T
- # from Equations (7, 8) of
- # https://mathworld.wolfram.com/MollweideProjection.html
- theta = np.arcsin(y / np.sqrt(2))
- longitude = (np.pi / (2 * np.sqrt(2))) * x / np.cos(theta)
- latitude = np.arcsin((2 * theta + np.sin(2 * theta)) / np.pi)
- return np.column_stack([longitude, latitude])
-
- def inverted(self):
- # docstring inherited
- return MollweideAxes.MollweideTransform(self._resolution)
-
- def __init__(self, *args, **kwargs):
- self._longitude_cap = np.pi / 2.0
- super().__init__(*args, **kwargs)
- self.set_aspect(0.5, adjustable='box', anchor='C')
- self.clear()
-
- def _get_core_transform(self, resolution):
- return self.MollweideTransform(resolution)
-
-
-class LambertAxes(GeoAxes):
- name = 'lambert'
-
- class LambertTransform(_GeoTransform):
- """The base Lambert transform."""
-
- def __init__(self, center_longitude, center_latitude, resolution):
- """
- Create a new Lambert transform. Resolution is the number of steps
- to interpolate between each input line segment to approximate its
- path in curved Lambert space.
- """
- _GeoTransform.__init__(self, resolution)
- self._center_longitude = center_longitude
- self._center_latitude = center_latitude
-
- @_api.rename_parameter("3.8", "ll", "values")
- def transform_non_affine(self, values):
- # docstring inherited
- longitude, latitude = values.T
- clong = self._center_longitude
- clat = self._center_latitude
- cos_lat = np.cos(latitude)
- sin_lat = np.sin(latitude)
- diff_long = longitude - clong
- cos_diff_long = np.cos(diff_long)
-
- inner_k = np.maximum( # Prevent divide-by-zero problems
- 1 + np.sin(clat)*sin_lat + np.cos(clat)*cos_lat*cos_diff_long,
- 1e-15)
- k = np.sqrt(2 / inner_k)
- x = k * cos_lat*np.sin(diff_long)
- y = k * (np.cos(clat)*sin_lat - np.sin(clat)*cos_lat*cos_diff_long)
-
- return np.column_stack([x, y])
-
- def inverted(self):
- # docstring inherited
- return LambertAxes.InvertedLambertTransform(
- self._center_longitude,
- self._center_latitude,
- self._resolution)
-
- class InvertedLambertTransform(_GeoTransform):
-
- def __init__(self, center_longitude, center_latitude, resolution):
- _GeoTransform.__init__(self, resolution)
- self._center_longitude = center_longitude
- self._center_latitude = center_latitude
-
- @_api.rename_parameter("3.8", "xy", "values")
- def transform_non_affine(self, values):
- # docstring inherited
- x, y = values.T
- clong = self._center_longitude
- clat = self._center_latitude
- p = np.maximum(np.hypot(x, y), 1e-9)
- c = 2 * np.arcsin(0.5 * p)
- sin_c = np.sin(c)
- cos_c = np.cos(c)
-
- latitude = np.arcsin(cos_c*np.sin(clat) +
- ((y*sin_c*np.cos(clat)) / p))
- longitude = clong + np.arctan(
- (x*sin_c) / (p*np.cos(clat)*cos_c - y*np.sin(clat)*sin_c))
-
- return np.column_stack([longitude, latitude])
-
- def inverted(self):
- # docstring inherited
- return LambertAxes.LambertTransform(
- self._center_longitude,
- self._center_latitude,
- self._resolution)
-
- def __init__(self, *args, center_longitude=0, center_latitude=0, **kwargs):
- self._longitude_cap = np.pi / 2
- self._center_longitude = center_longitude
- self._center_latitude = center_latitude
- super().__init__(*args, **kwargs)
- self.set_aspect('equal', adjustable='box', anchor='C')
- self.clear()
-
- def clear(self):
- # docstring inherited
- super().clear()
- self.yaxis.set_major_formatter(NullFormatter())
-
- def _get_core_transform(self, resolution):
- return self.LambertTransform(
- self._center_longitude,
- self._center_latitude,
- resolution)
-
- def _get_affine_transform(self):
- return Affine2D() \
- .scale(0.25) \
- .translate(0.5, 0.5)
diff --git a/contrib/python/matplotlib/py3/matplotlib/projections/geo.pyi b/contrib/python/matplotlib/py3/matplotlib/projections/geo.pyi
deleted file mode 100644
index 93220f8cbc..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/projections/geo.pyi
+++ /dev/null
@@ -1,112 +0,0 @@
-from matplotlib.axes import Axes
-from matplotlib.ticker import Formatter
-from matplotlib.transforms import Transform
-
-from typing import Any, Literal
-
-class GeoAxes(Axes):
- class ThetaFormatter(Formatter):
- def __init__(self, round_to: float = ...) -> None: ...
- def __call__(self, x: float, pos: Any | None = ...): ...
- RESOLUTION: float
- def get_xaxis_transform(
- self, which: Literal["tick1", "tick2", "grid"] = ...
- ) -> Transform: ...
- def get_xaxis_text1_transform(
- self, pad: float
- ) -> tuple[
- Transform,
- Literal["center", "top", "bottom", "baseline", "center_baseline"],
- Literal["center", "left", "right"],
- ]: ...
- def get_xaxis_text2_transform(
- self, pad: float
- ) -> tuple[
- Transform,
- Literal["center", "top", "bottom", "baseline", "center_baseline"],
- Literal["center", "left", "right"],
- ]: ...
- def get_yaxis_transform(
- self, which: Literal["tick1", "tick2", "grid"] = ...
- ) -> Transform: ...
- def get_yaxis_text1_transform(
- self, pad: float
- ) -> tuple[
- Transform,
- Literal["center", "top", "bottom", "baseline", "center_baseline"],
- Literal["center", "left", "right"],
- ]: ...
- def get_yaxis_text2_transform(
- self, pad: float
- ) -> tuple[
- Transform,
- Literal["center", "top", "bottom", "baseline", "center_baseline"],
- Literal["center", "left", "right"],
- ]: ...
- def set_xlim(self, *args, **kwargs) -> tuple[float, float]: ...
- def set_ylim(self, *args, **kwargs) -> tuple[float, float]: ...
- def format_coord(self, lon: float, lat: float) -> str: ...
- def set_longitude_grid(self, degrees: float) -> None: ...
- def set_latitude_grid(self, degrees: float) -> None: ...
- def set_longitude_grid_ends(self, degrees: float) -> None: ...
- def get_data_ratio(self) -> float: ...
- def can_zoom(self) -> bool: ...
- def can_pan(self) -> bool: ...
- def start_pan(self, x, y, button) -> None: ...
- def end_pan(self) -> None: ...
- def drag_pan(self, button, key, x, y) -> None: ...
-
-class _GeoTransform(Transform):
- input_dims: int
- output_dims: int
- def __init__(self, resolution: int) -> None: ...
-
-class AitoffAxes(GeoAxes):
- name: str
-
- class AitoffTransform(_GeoTransform):
- def inverted(self) -> AitoffAxes.InvertedAitoffTransform: ...
-
- class InvertedAitoffTransform(_GeoTransform):
- def inverted(self) -> AitoffAxes.AitoffTransform: ...
-
-class HammerAxes(GeoAxes):
- name: str
-
- class HammerTransform(_GeoTransform):
- def inverted(self) -> HammerAxes.InvertedHammerTransform: ...
-
- class InvertedHammerTransform(_GeoTransform):
- def inverted(self) -> HammerAxes.HammerTransform: ...
-
-class MollweideAxes(GeoAxes):
- name: str
-
- class MollweideTransform(_GeoTransform):
- def inverted(self) -> MollweideAxes.InvertedMollweideTransform: ...
-
- class InvertedMollweideTransform(_GeoTransform):
- def inverted(self) -> MollweideAxes.MollweideTransform: ...
-
-class LambertAxes(GeoAxes):
- name: str
-
- class LambertTransform(_GeoTransform):
- def __init__(
- self, center_longitude: float, center_latitude: float, resolution: int
- ) -> None: ...
- def inverted(self) -> LambertAxes.InvertedLambertTransform: ...
-
- class InvertedLambertTransform(_GeoTransform):
- def __init__(
- self, center_longitude: float, center_latitude: float, resolution: int
- ) -> None: ...
- def inverted(self) -> LambertAxes.LambertTransform: ...
-
- def __init__(
- self,
- *args,
- center_longitude: float = ...,
- center_latitude: float = ...,
- **kwargs
- ) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/projections/polar.py b/contrib/python/matplotlib/py3/matplotlib/projections/polar.py
deleted file mode 100644
index 0bff320e57..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/projections/polar.py
+++ /dev/null
@@ -1,1536 +0,0 @@
-import math
-import types
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, cbook
-from matplotlib.axes import Axes
-import matplotlib.axis as maxis
-import matplotlib.markers as mmarkers
-import matplotlib.patches as mpatches
-from matplotlib.path import Path
-import matplotlib.ticker as mticker
-import matplotlib.transforms as mtransforms
-from matplotlib.spines import Spine
-
-
-class PolarTransform(mtransforms.Transform):
- r"""
- The base polar transform.
-
- This transform maps polar coordinates :math:`\theta, r` into Cartesian
- coordinates :math:`x, y = r \cos(\theta), r \sin(\theta)`
- (but does not fully transform into Axes coordinates or
- handle positioning in screen space).
-
- This transformation is designed to be applied to data after any scaling
- along the radial axis (e.g. log-scaling) has been applied to the input
- data.
-
- Path segments at a fixed radius are automatically transformed to circular
- arcs as long as ``path._interpolation_steps > 1``.
- """
-
- input_dims = output_dims = 2
-
- def __init__(self, axis=None, use_rmin=True,
- _apply_theta_transforms=True, *, scale_transform=None):
- """
- Parameters
- ----------
- axis : `~matplotlib.axis.Axis`, optional
- Axis associated with this transform. This is used to get the
- minimum radial limit.
- use_rmin : `bool`, optional
- If ``True``, subtract the minimum radial axis limit before
- transforming to Cartesian coordinates. *axis* must also be
- specified for this to take effect.
- """
- super().__init__()
- self._axis = axis
- self._use_rmin = use_rmin
- self._apply_theta_transforms = _apply_theta_transforms
- self._scale_transform = scale_transform
-
- __str__ = mtransforms._make_str_method(
- "_axis",
- use_rmin="_use_rmin",
- _apply_theta_transforms="_apply_theta_transforms")
-
- def _get_rorigin(self):
- # Get lower r limit after being scaled by the radial scale transform
- return self._scale_transform.transform(
- (0, self._axis.get_rorigin()))[1]
-
- @_api.rename_parameter("3.8", "tr", "values")
- def transform_non_affine(self, values):
- # docstring inherited
- theta, r = np.transpose(values)
- # PolarAxes does not use the theta transforms here, but apply them for
- # backwards-compatibility if not being used by it.
- if self._apply_theta_transforms and self._axis is not None:
- theta *= self._axis.get_theta_direction()
- theta += self._axis.get_theta_offset()
- if self._use_rmin and self._axis is not None:
- r = (r - self._get_rorigin()) * self._axis.get_rsign()
- r = np.where(r >= 0, r, np.nan)
- return np.column_stack([r * np.cos(theta), r * np.sin(theta)])
-
- def transform_path_non_affine(self, path):
- # docstring inherited
- if not len(path) or path._interpolation_steps == 1:
- return Path(self.transform_non_affine(path.vertices), path.codes)
- xys = []
- codes = []
- last_t = last_r = None
- for trs, c in path.iter_segments():
- trs = trs.reshape((-1, 2))
- if c == Path.LINETO:
- (t, r), = trs
- if t == last_t: # Same angle: draw a straight line.
- xys.extend(self.transform_non_affine(trs))
- codes.append(Path.LINETO)
- elif r == last_r: # Same radius: draw an arc.
- # The following is complicated by Path.arc() being
- # "helpful" and unwrapping the angles, but we don't want
- # that behavior here.
- last_td, td = np.rad2deg([last_t, t])
- if self._use_rmin and self._axis is not None:
- r = ((r - self._get_rorigin())
- * self._axis.get_rsign())
- if last_td <= td:
- while td - last_td > 360:
- arc = Path.arc(last_td, last_td + 360)
- xys.extend(arc.vertices[1:] * r)
- codes.extend(arc.codes[1:])
- last_td += 360
- arc = Path.arc(last_td, td)
- xys.extend(arc.vertices[1:] * r)
- codes.extend(arc.codes[1:])
- else:
- # The reverse version also relies on the fact that all
- # codes but the first one are the same.
- while last_td - td > 360:
- arc = Path.arc(last_td - 360, last_td)
- xys.extend(arc.vertices[::-1][1:] * r)
- codes.extend(arc.codes[1:])
- last_td -= 360
- arc = Path.arc(td, last_td)
- xys.extend(arc.vertices[::-1][1:] * r)
- codes.extend(arc.codes[1:])
- else: # Interpolate.
- trs = cbook.simple_linear_interpolation(
- np.vstack([(last_t, last_r), trs]),
- path._interpolation_steps)[1:]
- xys.extend(self.transform_non_affine(trs))
- codes.extend([Path.LINETO] * len(trs))
- else: # Not a straight line.
- xys.extend(self.transform_non_affine(trs))
- codes.extend([c] * len(trs))
- last_t, last_r = trs[-1]
- return Path(xys, codes)
-
- def inverted(self):
- # docstring inherited
- return PolarAxes.InvertedPolarTransform(self._axis, self._use_rmin,
- self._apply_theta_transforms)
-
-
-class PolarAffine(mtransforms.Affine2DBase):
- r"""
- The affine part of the polar projection.
-
- Scales the output so that maximum radius rests on the edge of the axes
- circle and the origin is mapped to (0.5, 0.5). The transform applied is
- the same to x and y components and given by:
-
- .. math::
-
- x_{1} = 0.5 \left [ \frac{x_{0}}{(r_{\max} - r_{\min})} + 1 \right ]
-
- :math:`r_{\min}, r_{\max}` are the minimum and maximum radial limits after
- any scaling (e.g. log scaling) has been removed.
- """
- def __init__(self, scale_transform, limits):
- """
- Parameters
- ----------
- scale_transform : `~matplotlib.transforms.Transform`
- Scaling transform for the data. This is used to remove any scaling
- from the radial view limits.
- limits : `~matplotlib.transforms.BboxBase`
- View limits of the data. The only part of its bounds that is used
- is the y limits (for the radius limits).
- """
- super().__init__()
- self._scale_transform = scale_transform
- self._limits = limits
- self.set_children(scale_transform, limits)
- self._mtx = None
-
- __str__ = mtransforms._make_str_method("_scale_transform", "_limits")
-
- def get_matrix(self):
- # docstring inherited
- if self._invalid:
- limits_scaled = self._limits.transformed(self._scale_transform)
- yscale = limits_scaled.ymax - limits_scaled.ymin
- affine = mtransforms.Affine2D() \
- .scale(0.5 / yscale) \
- .translate(0.5, 0.5)
- self._mtx = affine.get_matrix()
- self._inverted = None
- self._invalid = 0
- return self._mtx
-
-
-class InvertedPolarTransform(mtransforms.Transform):
- """
- The inverse of the polar transform, mapping Cartesian
- coordinate space *x* and *y* back to *theta* and *r*.
- """
- input_dims = output_dims = 2
-
- def __init__(self, axis=None, use_rmin=True,
- _apply_theta_transforms=True):
- """
- Parameters
- ----------
- axis : `~matplotlib.axis.Axis`, optional
- Axis associated with this transform. This is used to get the
- minimum radial limit.
- use_rmin : `bool`, optional
- If ``True`` add the minimum radial axis limit after
- transforming from Cartesian coordinates. *axis* must also be
- specified for this to take effect.
- """
- super().__init__()
- self._axis = axis
- self._use_rmin = use_rmin
- self._apply_theta_transforms = _apply_theta_transforms
-
- __str__ = mtransforms._make_str_method(
- "_axis",
- use_rmin="_use_rmin",
- _apply_theta_transforms="_apply_theta_transforms")
-
- @_api.rename_parameter("3.8", "xy", "values")
- def transform_non_affine(self, values):
- # docstring inherited
- x, y = values.T
- r = np.hypot(x, y)
- theta = (np.arctan2(y, x) + 2 * np.pi) % (2 * np.pi)
- # PolarAxes does not use the theta transforms here, but apply them for
- # backwards-compatibility if not being used by it.
- if self._apply_theta_transforms and self._axis is not None:
- theta -= self._axis.get_theta_offset()
- theta *= self._axis.get_theta_direction()
- theta %= 2 * np.pi
- if self._use_rmin and self._axis is not None:
- r += self._axis.get_rorigin()
- r *= self._axis.get_rsign()
- return np.column_stack([theta, r])
-
- def inverted(self):
- # docstring inherited
- return PolarAxes.PolarTransform(self._axis, self._use_rmin,
- self._apply_theta_transforms)
-
-
-class ThetaFormatter(mticker.Formatter):
- """
- Used to format the *theta* tick labels. Converts the native
- unit of radians into degrees and adds a degree symbol.
- """
-
- def __call__(self, x, pos=None):
- vmin, vmax = self.axis.get_view_interval()
- d = np.rad2deg(abs(vmax - vmin))
- digits = max(-int(np.log10(d) - 1.5), 0)
- # Use Unicode rather than mathtext with \circ, so that it will work
- # correctly with any arbitrary font (assuming it has a degree sign),
- # whereas $5\circ$ will only work correctly with one of the supported
- # math fonts (Computer Modern and STIX).
- return f"{np.rad2deg(x):0.{digits:d}f}\N{DEGREE SIGN}"
-
-
-class _AxisWrapper:
- def __init__(self, axis):
- self._axis = axis
-
- def get_view_interval(self):
- return np.rad2deg(self._axis.get_view_interval())
-
- def set_view_interval(self, vmin, vmax):
- self._axis.set_view_interval(*np.deg2rad((vmin, vmax)))
-
- def get_minpos(self):
- return np.rad2deg(self._axis.get_minpos())
-
- def get_data_interval(self):
- return np.rad2deg(self._axis.get_data_interval())
-
- def set_data_interval(self, vmin, vmax):
- self._axis.set_data_interval(*np.deg2rad((vmin, vmax)))
-
- def get_tick_space(self):
- return self._axis.get_tick_space()
-
-
-class ThetaLocator(mticker.Locator):
- """
- Used to locate theta ticks.
-
- This will work the same as the base locator except in the case that the
- view spans the entire circle. In such cases, the previously used default
- locations of every 45 degrees are returned.
- """
-
- def __init__(self, base):
- self.base = base
- self.axis = self.base.axis = _AxisWrapper(self.base.axis)
-
- def set_axis(self, axis):
- self.axis = _AxisWrapper(axis)
- self.base.set_axis(self.axis)
-
- def __call__(self):
- lim = self.axis.get_view_interval()
- if _is_full_circle_deg(lim[0], lim[1]):
- return np.arange(8) * 2 * np.pi / 8
- else:
- return np.deg2rad(self.base())
-
- def view_limits(self, vmin, vmax):
- vmin, vmax = np.rad2deg((vmin, vmax))
- return np.deg2rad(self.base.view_limits(vmin, vmax))
-
-
-class ThetaTick(maxis.XTick):
- """
- A theta-axis tick.
-
- This subclass of `.XTick` provides angular ticks with some small
- modification to their re-positioning such that ticks are rotated based on
- tick location. This results in ticks that are correctly perpendicular to
- the arc spine.
-
- When 'auto' rotation is enabled, labels are also rotated to be parallel to
- the spine. The label padding is also applied here since it's not possible
- to use a generic axes transform to produce tick-specific padding.
- """
-
- def __init__(self, axes, *args, **kwargs):
- self._text1_translate = mtransforms.ScaledTranslation(
- 0, 0, axes.figure.dpi_scale_trans)
- self._text2_translate = mtransforms.ScaledTranslation(
- 0, 0, axes.figure.dpi_scale_trans)
- super().__init__(axes, *args, **kwargs)
- self.label1.set(
- rotation_mode='anchor',
- transform=self.label1.get_transform() + self._text1_translate)
- self.label2.set(
- rotation_mode='anchor',
- transform=self.label2.get_transform() + self._text2_translate)
-
- def _apply_params(self, **kwargs):
- super()._apply_params(**kwargs)
- # Ensure transform is correct; sometimes this gets reset.
- trans = self.label1.get_transform()
- if not trans.contains_branch(self._text1_translate):
- self.label1.set_transform(trans + self._text1_translate)
- trans = self.label2.get_transform()
- if not trans.contains_branch(self._text2_translate):
- self.label2.set_transform(trans + self._text2_translate)
-
- def _update_padding(self, pad, angle):
- padx = pad * np.cos(angle) / 72
- pady = pad * np.sin(angle) / 72
- self._text1_translate._t = (padx, pady)
- self._text1_translate.invalidate()
- self._text2_translate._t = (-padx, -pady)
- self._text2_translate.invalidate()
-
- def update_position(self, loc):
- super().update_position(loc)
- axes = self.axes
- angle = loc * axes.get_theta_direction() + axes.get_theta_offset()
- text_angle = np.rad2deg(angle) % 360 - 90
- angle -= np.pi / 2
-
- marker = self.tick1line.get_marker()
- if marker in (mmarkers.TICKUP, '|'):
- trans = mtransforms.Affine2D().scale(1, 1).rotate(angle)
- elif marker == mmarkers.TICKDOWN:
- trans = mtransforms.Affine2D().scale(1, -1).rotate(angle)
- else:
- # Don't modify custom tick line markers.
- trans = self.tick1line._marker._transform
- self.tick1line._marker._transform = trans
-
- marker = self.tick2line.get_marker()
- if marker in (mmarkers.TICKUP, '|'):
- trans = mtransforms.Affine2D().scale(1, 1).rotate(angle)
- elif marker == mmarkers.TICKDOWN:
- trans = mtransforms.Affine2D().scale(1, -1).rotate(angle)
- else:
- # Don't modify custom tick line markers.
- trans = self.tick2line._marker._transform
- self.tick2line._marker._transform = trans
-
- mode, user_angle = self._labelrotation
- if mode == 'default':
- text_angle = user_angle
- else:
- if text_angle > 90:
- text_angle -= 180
- elif text_angle < -90:
- text_angle += 180
- text_angle += user_angle
- self.label1.set_rotation(text_angle)
- self.label2.set_rotation(text_angle)
-
- # This extra padding helps preserve the look from previous releases but
- # is also needed because labels are anchored to their center.
- pad = self._pad + 7
- self._update_padding(pad,
- self._loc * axes.get_theta_direction() +
- axes.get_theta_offset())
-
-
-class ThetaAxis(maxis.XAxis):
- """
- A theta Axis.
-
- This overrides certain properties of an `.XAxis` to provide special-casing
- for an angular axis.
- """
- __name__ = 'thetaaxis'
- axis_name = 'theta' #: Read-only name identifying the axis.
- _tick_class = ThetaTick
-
- def _wrap_locator_formatter(self):
- self.set_major_locator(ThetaLocator(self.get_major_locator()))
- self.set_major_formatter(ThetaFormatter())
- self.isDefault_majloc = True
- self.isDefault_majfmt = True
-
- def clear(self):
- # docstring inherited
- super().clear()
- self.set_ticks_position('none')
- self._wrap_locator_formatter()
-
- def _set_scale(self, value, **kwargs):
- if value != 'linear':
- raise NotImplementedError(
- "The xscale cannot be set on a polar plot")
- super()._set_scale(value, **kwargs)
- # LinearScale.set_default_locators_and_formatters just set the major
- # locator to be an AutoLocator, so we customize it here to have ticks
- # at sensible degree multiples.
- self.get_major_locator().set_params(steps=[1, 1.5, 3, 4.5, 9, 10])
- self._wrap_locator_formatter()
-
- def _copy_tick_props(self, src, dest):
- """Copy the props from src tick to dest tick."""
- if src is None or dest is None:
- return
- super()._copy_tick_props(src, dest)
-
- # Ensure that tick transforms are independent so that padding works.
- trans = dest._get_text1_transform()[0]
- dest.label1.set_transform(trans + dest._text1_translate)
- trans = dest._get_text2_transform()[0]
- dest.label2.set_transform(trans + dest._text2_translate)
-
-
-class RadialLocator(mticker.Locator):
- """
- Used to locate radius ticks.
-
- Ensures that all ticks are strictly positive. For all other tasks, it
- delegates to the base `.Locator` (which may be different depending on the
- scale of the *r*-axis).
- """
-
- def __init__(self, base, axes=None):
- self.base = base
- self._axes = axes
-
- def set_axis(self, axis):
- self.base.set_axis(axis)
-
- def __call__(self):
- # Ensure previous behaviour with full circle non-annular views.
- if self._axes:
- if _is_full_circle_rad(*self._axes.viewLim.intervalx):
- rorigin = self._axes.get_rorigin() * self._axes.get_rsign()
- if self._axes.get_rmin() <= rorigin:
- return [tick for tick in self.base() if tick > rorigin]
- return self.base()
-
- def _zero_in_bounds(self):
- """
- Return True if zero is within the valid values for the
- scale of the radial axis.
- """
- vmin, vmax = self._axes.yaxis._scale.limit_range_for_scale(0, 1, 1e-5)
- return vmin == 0
-
- def nonsingular(self, vmin, vmax):
- # docstring inherited
- if self._zero_in_bounds() and (vmin, vmax) == (-np.inf, np.inf):
- # Initial view limits
- return (0, 1)
- else:
- return self.base.nonsingular(vmin, vmax)
-
- def view_limits(self, vmin, vmax):
- vmin, vmax = self.base.view_limits(vmin, vmax)
- if self._zero_in_bounds() and vmax > vmin:
- # this allows inverted r/y-lims
- vmin = min(0, vmin)
- return mtransforms.nonsingular(vmin, vmax)
-
-
-class _ThetaShift(mtransforms.ScaledTranslation):
- """
- Apply a padding shift based on axes theta limits.
-
- This is used to create padding for radial ticks.
-
- Parameters
- ----------
- axes : `~matplotlib.axes.Axes`
- The owning axes; used to determine limits.
- pad : float
- The padding to apply, in points.
- mode : {'min', 'max', 'rlabel'}
- Whether to shift away from the start (``'min'``) or the end (``'max'``)
- of the axes, or using the rlabel position (``'rlabel'``).
- """
- def __init__(self, axes, pad, mode):
- super().__init__(pad, pad, axes.figure.dpi_scale_trans)
- self.set_children(axes._realViewLim)
- self.axes = axes
- self.mode = mode
- self.pad = pad
-
- __str__ = mtransforms._make_str_method("axes", "pad", "mode")
-
- def get_matrix(self):
- if self._invalid:
- if self.mode == 'rlabel':
- angle = (
- np.deg2rad(self.axes.get_rlabel_position()) *
- self.axes.get_theta_direction() +
- self.axes.get_theta_offset()
- )
- else:
- if self.mode == 'min':
- angle = self.axes._realViewLim.xmin
- elif self.mode == 'max':
- angle = self.axes._realViewLim.xmax
-
- if self.mode in ('rlabel', 'min'):
- padx = np.cos(angle - np.pi / 2)
- pady = np.sin(angle - np.pi / 2)
- else:
- padx = np.cos(angle + np.pi / 2)
- pady = np.sin(angle + np.pi / 2)
-
- self._t = (self.pad * padx / 72, self.pad * pady / 72)
- return super().get_matrix()
-
-
-class RadialTick(maxis.YTick):
- """
- A radial-axis tick.
-
- This subclass of `.YTick` provides radial ticks with some small
- modification to their re-positioning such that ticks are rotated based on
- axes limits. This results in ticks that are correctly perpendicular to
- the spine. Labels are also rotated to be perpendicular to the spine, when
- 'auto' rotation is enabled.
- """
-
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- self.label1.set_rotation_mode('anchor')
- self.label2.set_rotation_mode('anchor')
-
- def _determine_anchor(self, mode, angle, start):
- # Note: angle is the (spine angle - 90) because it's used for the tick
- # & text setup, so all numbers below are -90 from (normed) spine angle.
- if mode == 'auto':
- if start:
- if -90 <= angle <= 90:
- return 'left', 'center'
- else:
- return 'right', 'center'
- else:
- if -90 <= angle <= 90:
- return 'right', 'center'
- else:
- return 'left', 'center'
- else:
- if start:
- if angle < -68.5:
- return 'center', 'top'
- elif angle < -23.5:
- return 'left', 'top'
- elif angle < 22.5:
- return 'left', 'center'
- elif angle < 67.5:
- return 'left', 'bottom'
- elif angle < 112.5:
- return 'center', 'bottom'
- elif angle < 157.5:
- return 'right', 'bottom'
- elif angle < 202.5:
- return 'right', 'center'
- elif angle < 247.5:
- return 'right', 'top'
- else:
- return 'center', 'top'
- else:
- if angle < -68.5:
- return 'center', 'bottom'
- elif angle < -23.5:
- return 'right', 'bottom'
- elif angle < 22.5:
- return 'right', 'center'
- elif angle < 67.5:
- return 'right', 'top'
- elif angle < 112.5:
- return 'center', 'top'
- elif angle < 157.5:
- return 'left', 'top'
- elif angle < 202.5:
- return 'left', 'center'
- elif angle < 247.5:
- return 'left', 'bottom'
- else:
- return 'center', 'bottom'
-
- def update_position(self, loc):
- super().update_position(loc)
- axes = self.axes
- thetamin = axes.get_thetamin()
- thetamax = axes.get_thetamax()
- direction = axes.get_theta_direction()
- offset_rad = axes.get_theta_offset()
- offset = np.rad2deg(offset_rad)
- full = _is_full_circle_deg(thetamin, thetamax)
-
- if full:
- angle = (axes.get_rlabel_position() * direction +
- offset) % 360 - 90
- tick_angle = 0
- else:
- angle = (thetamin * direction + offset) % 360 - 90
- if direction > 0:
- tick_angle = np.deg2rad(angle)
- else:
- tick_angle = np.deg2rad(angle + 180)
- text_angle = (angle + 90) % 180 - 90 # between -90 and +90.
- mode, user_angle = self._labelrotation
- if mode == 'auto':
- text_angle += user_angle
- else:
- text_angle = user_angle
-
- if full:
- ha = self.label1.get_horizontalalignment()
- va = self.label1.get_verticalalignment()
- else:
- ha, va = self._determine_anchor(mode, angle, direction > 0)
- self.label1.set_horizontalalignment(ha)
- self.label1.set_verticalalignment(va)
- self.label1.set_rotation(text_angle)
-
- marker = self.tick1line.get_marker()
- if marker == mmarkers.TICKLEFT:
- trans = mtransforms.Affine2D().rotate(tick_angle)
- elif marker == '_':
- trans = mtransforms.Affine2D().rotate(tick_angle + np.pi / 2)
- elif marker == mmarkers.TICKRIGHT:
- trans = mtransforms.Affine2D().scale(-1, 1).rotate(tick_angle)
- else:
- # Don't modify custom tick line markers.
- trans = self.tick1line._marker._transform
- self.tick1line._marker._transform = trans
-
- if full:
- self.label2.set_visible(False)
- self.tick2line.set_visible(False)
- angle = (thetamax * direction + offset) % 360 - 90
- if direction > 0:
- tick_angle = np.deg2rad(angle)
- else:
- tick_angle = np.deg2rad(angle + 180)
- text_angle = (angle + 90) % 180 - 90 # between -90 and +90.
- mode, user_angle = self._labelrotation
- if mode == 'auto':
- text_angle += user_angle
- else:
- text_angle = user_angle
-
- ha, va = self._determine_anchor(mode, angle, direction < 0)
- self.label2.set_ha(ha)
- self.label2.set_va(va)
- self.label2.set_rotation(text_angle)
-
- marker = self.tick2line.get_marker()
- if marker == mmarkers.TICKLEFT:
- trans = mtransforms.Affine2D().rotate(tick_angle)
- elif marker == '_':
- trans = mtransforms.Affine2D().rotate(tick_angle + np.pi / 2)
- elif marker == mmarkers.TICKRIGHT:
- trans = mtransforms.Affine2D().scale(-1, 1).rotate(tick_angle)
- else:
- # Don't modify custom tick line markers.
- trans = self.tick2line._marker._transform
- self.tick2line._marker._transform = trans
-
-
-class RadialAxis(maxis.YAxis):
- """
- A radial Axis.
-
- This overrides certain properties of a `.YAxis` to provide special-casing
- for a radial axis.
- """
- __name__ = 'radialaxis'
- axis_name = 'radius' #: Read-only name identifying the axis.
- _tick_class = RadialTick
-
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- self.sticky_edges.y.append(0)
-
- def _wrap_locator_formatter(self):
- self.set_major_locator(RadialLocator(self.get_major_locator(),
- self.axes))
- self.isDefault_majloc = True
-
- def clear(self):
- # docstring inherited
- super().clear()
- self.set_ticks_position('none')
- self._wrap_locator_formatter()
-
- def _set_scale(self, value, **kwargs):
- super()._set_scale(value, **kwargs)
- self._wrap_locator_formatter()
-
-
-def _is_full_circle_deg(thetamin, thetamax):
- """
- Determine if a wedge (in degrees) spans the full circle.
-
- The condition is derived from :class:`~matplotlib.patches.Wedge`.
- """
- return abs(abs(thetamax - thetamin) - 360.0) < 1e-12
-
-
-def _is_full_circle_rad(thetamin, thetamax):
- """
- Determine if a wedge (in radians) spans the full circle.
-
- The condition is derived from :class:`~matplotlib.patches.Wedge`.
- """
- return abs(abs(thetamax - thetamin) - 2 * np.pi) < 1.74e-14
-
-
-class _WedgeBbox(mtransforms.Bbox):
- """
- Transform (theta, r) wedge Bbox into axes bounding box.
-
- Parameters
- ----------
- center : (float, float)
- Center of the wedge
- viewLim : `~matplotlib.transforms.Bbox`
- Bbox determining the boundaries of the wedge
- originLim : `~matplotlib.transforms.Bbox`
- Bbox determining the origin for the wedge, if different from *viewLim*
- """
- def __init__(self, center, viewLim, originLim, **kwargs):
- super().__init__([[0, 0], [1, 1]], **kwargs)
- self._center = center
- self._viewLim = viewLim
- self._originLim = originLim
- self.set_children(viewLim, originLim)
-
- __str__ = mtransforms._make_str_method("_center", "_viewLim", "_originLim")
-
- def get_points(self):
- # docstring inherited
- if self._invalid:
- points = self._viewLim.get_points().copy()
- # Scale angular limits to work with Wedge.
- points[:, 0] *= 180 / np.pi
- if points[0, 0] > points[1, 0]:
- points[:, 0] = points[::-1, 0]
-
- # Scale radial limits based on origin radius.
- points[:, 1] -= self._originLim.y0
-
- # Scale radial limits to match axes limits.
- rscale = 0.5 / points[1, 1]
- points[:, 1] *= rscale
- width = min(points[1, 1] - points[0, 1], 0.5)
-
- # Generate bounding box for wedge.
- wedge = mpatches.Wedge(self._center, points[1, 1],
- points[0, 0], points[1, 0],
- width=width)
- self.update_from_path(wedge.get_path())
-
- # Ensure equal aspect ratio.
- w, h = self._points[1] - self._points[0]
- deltah = max(w - h, 0) / 2
- deltaw = max(h - w, 0) / 2
- self._points += np.array([[-deltaw, -deltah], [deltaw, deltah]])
-
- self._invalid = 0
-
- return self._points
-
-
-class PolarAxes(Axes):
- """
- A polar graph projection, where the input dimensions are *theta*, *r*.
-
- Theta starts pointing east and goes anti-clockwise.
- """
- name = 'polar'
-
- def __init__(self, *args,
- theta_offset=0, theta_direction=1, rlabel_position=22.5,
- **kwargs):
- # docstring inherited
- self._default_theta_offset = theta_offset
- self._default_theta_direction = theta_direction
- self._default_rlabel_position = np.deg2rad(rlabel_position)
- super().__init__(*args, **kwargs)
- self.use_sticky_edges = True
- self.set_aspect('equal', adjustable='box', anchor='C')
- self.clear()
-
- def clear(self):
- # docstring inherited
- super().clear()
-
- self.title.set_y(1.05)
-
- start = self.spines.get('start', None)
- if start:
- start.set_visible(False)
- end = self.spines.get('end', None)
- if end:
- end.set_visible(False)
- self.set_xlim(0.0, 2 * np.pi)
-
- self.grid(mpl.rcParams['polaraxes.grid'])
- inner = self.spines.get('inner', None)
- if inner:
- inner.set_visible(False)
-
- self.set_rorigin(None)
- self.set_theta_offset(self._default_theta_offset)
- self.set_theta_direction(self._default_theta_direction)
-
- def _init_axis(self):
- # This is moved out of __init__ because non-separable axes don't use it
- self.xaxis = ThetaAxis(self, clear=False)
- self.yaxis = RadialAxis(self, clear=False)
- self.spines['polar'].register_axis(self.yaxis)
-
- def _set_lim_and_transforms(self):
- # A view limit where the minimum radius can be locked if the user
- # specifies an alternate origin.
- self._originViewLim = mtransforms.LockableBbox(self.viewLim)
-
- # Handle angular offset and direction.
- self._direction = mtransforms.Affine2D() \
- .scale(self._default_theta_direction, 1.0)
- self._theta_offset = mtransforms.Affine2D() \
- .translate(self._default_theta_offset, 0.0)
- self.transShift = self._direction + self._theta_offset
- # A view limit shifted to the correct location after accounting for
- # orientation and offset.
- self._realViewLim = mtransforms.TransformedBbox(self.viewLim,
- self.transShift)
-
- # Transforms the x and y axis separately by a scale factor
- # It is assumed that this part will have non-linear components
- self.transScale = mtransforms.TransformWrapper(
- mtransforms.IdentityTransform())
-
- # Scale view limit into a bbox around the selected wedge. This may be
- # smaller than the usual unit axes rectangle if not plotting the full
- # circle.
- self.axesLim = _WedgeBbox((0.5, 0.5),
- self._realViewLim, self._originViewLim)
-
- # Scale the wedge to fill the axes.
- self.transWedge = mtransforms.BboxTransformFrom(self.axesLim)
-
- # Scale the axes to fill the figure.
- self.transAxes = mtransforms.BboxTransformTo(self.bbox)
-
- # A (possibly non-linear) projection on the (already scaled)
- # data. This one is aware of rmin
- self.transProjection = self.PolarTransform(
- self,
- _apply_theta_transforms=False,
- scale_transform=self.transScale
- )
- # Add dependency on rorigin.
- self.transProjection.set_children(self._originViewLim)
-
- # An affine transformation on the data, generally to limit the
- # range of the axes
- self.transProjectionAffine = self.PolarAffine(self.transScale,
- self._originViewLim)
-
- # The complete data transformation stack -- from data all the
- # way to display coordinates
- #
- # 1. Remove any radial axis scaling (e.g. log scaling)
- # 2. Shift data in the theta direction
- # 3. Project the data from polar to cartesian values
- # (with the origin in the same place)
- # 4. Scale and translate the cartesian values to Axes coordinates
- # (here the origin is moved to the lower left of the Axes)
- # 5. Move and scale to fill the Axes
- # 6. Convert from Axes coordinates to Figure coordinates
- self.transData = (
- self.transScale +
- self.transShift +
- self.transProjection +
- (
- self.transProjectionAffine +
- self.transWedge +
- self.transAxes
- )
- )
-
- # This is the transform for theta-axis ticks. It is
- # equivalent to transData, except it always puts r == 0.0 and r == 1.0
- # at the edge of the axis circles.
- self._xaxis_transform = (
- mtransforms.blended_transform_factory(
- mtransforms.IdentityTransform(),
- mtransforms.BboxTransformTo(self.viewLim)) +
- self.transData)
- # The theta labels are flipped along the radius, so that text 1 is on
- # the outside by default. This should work the same as before.
- flipr_transform = mtransforms.Affine2D() \
- .translate(0.0, -0.5) \
- .scale(1.0, -1.0) \
- .translate(0.0, 0.5)
- self._xaxis_text_transform = flipr_transform + self._xaxis_transform
-
- # This is the transform for r-axis ticks. It scales the theta
- # axis so the gridlines from 0.0 to 1.0, now go from thetamin to
- # thetamax.
- self._yaxis_transform = (
- mtransforms.blended_transform_factory(
- mtransforms.BboxTransformTo(self.viewLim),
- mtransforms.IdentityTransform()) +
- self.transData)
- # The r-axis labels are put at an angle and padded in the r-direction
- self._r_label_position = mtransforms.Affine2D() \
- .translate(self._default_rlabel_position, 0.0)
- self._yaxis_text_transform = mtransforms.TransformWrapper(
- self._r_label_position + self.transData)
-
- def get_xaxis_transform(self, which='grid'):
- _api.check_in_list(['tick1', 'tick2', 'grid'], which=which)
- return self._xaxis_transform
-
- def get_xaxis_text1_transform(self, pad):
- return self._xaxis_text_transform, 'center', 'center'
-
- def get_xaxis_text2_transform(self, pad):
- return self._xaxis_text_transform, 'center', 'center'
-
- def get_yaxis_transform(self, which='grid'):
- if which in ('tick1', 'tick2'):
- return self._yaxis_text_transform
- elif which == 'grid':
- return self._yaxis_transform
- else:
- _api.check_in_list(['tick1', 'tick2', 'grid'], which=which)
-
- def get_yaxis_text1_transform(self, pad):
- thetamin, thetamax = self._realViewLim.intervalx
- if _is_full_circle_rad(thetamin, thetamax):
- return self._yaxis_text_transform, 'bottom', 'left'
- elif self.get_theta_direction() > 0:
- halign = 'left'
- pad_shift = _ThetaShift(self, pad, 'min')
- else:
- halign = 'right'
- pad_shift = _ThetaShift(self, pad, 'max')
- return self._yaxis_text_transform + pad_shift, 'center', halign
-
- def get_yaxis_text2_transform(self, pad):
- if self.get_theta_direction() > 0:
- halign = 'right'
- pad_shift = _ThetaShift(self, pad, 'max')
- else:
- halign = 'left'
- pad_shift = _ThetaShift(self, pad, 'min')
- return self._yaxis_text_transform + pad_shift, 'center', halign
-
- def draw(self, renderer):
- self._unstale_viewLim()
- thetamin, thetamax = np.rad2deg(self._realViewLim.intervalx)
- if thetamin > thetamax:
- thetamin, thetamax = thetamax, thetamin
- rmin, rmax = ((self._realViewLim.intervaly - self.get_rorigin()) *
- self.get_rsign())
- if isinstance(self.patch, mpatches.Wedge):
- # Backwards-compatibility: Any subclassed Axes might override the
- # patch to not be the Wedge that PolarAxes uses.
- center = self.transWedge.transform((0.5, 0.5))
- self.patch.set_center(center)
- self.patch.set_theta1(thetamin)
- self.patch.set_theta2(thetamax)
-
- edge, _ = self.transWedge.transform((1, 0))
- radius = edge - center[0]
- width = min(radius * (rmax - rmin) / rmax, radius)
- self.patch.set_radius(radius)
- self.patch.set_width(width)
-
- inner_width = radius - width
- inner = self.spines.get('inner', None)
- if inner:
- inner.set_visible(inner_width != 0.0)
-
- visible = not _is_full_circle_deg(thetamin, thetamax)
- # For backwards compatibility, any subclassed Axes might override the
- # spines to not include start/end that PolarAxes uses.
- start = self.spines.get('start', None)
- end = self.spines.get('end', None)
- if start:
- start.set_visible(visible)
- if end:
- end.set_visible(visible)
- if visible:
- yaxis_text_transform = self._yaxis_transform
- else:
- yaxis_text_transform = self._r_label_position + self.transData
- if self._yaxis_text_transform != yaxis_text_transform:
- self._yaxis_text_transform.set(yaxis_text_transform)
- self.yaxis.reset_ticks()
- self.yaxis.set_clip_path(self.patch)
-
- super().draw(renderer)
-
- def _gen_axes_patch(self):
- return mpatches.Wedge((0.5, 0.5), 0.5, 0.0, 360.0)
-
- def _gen_axes_spines(self):
- spines = {
- 'polar': Spine.arc_spine(self, 'top', (0.5, 0.5), 0.5, 0, 360),
- 'start': Spine.linear_spine(self, 'left'),
- 'end': Spine.linear_spine(self, 'right'),
- 'inner': Spine.arc_spine(self, 'bottom', (0.5, 0.5), 0.0, 0, 360),
- }
- spines['polar'].set_transform(self.transWedge + self.transAxes)
- spines['inner'].set_transform(self.transWedge + self.transAxes)
- spines['start'].set_transform(self._yaxis_transform)
- spines['end'].set_transform(self._yaxis_transform)
- return spines
-
- def set_thetamax(self, thetamax):
- """Set the maximum theta limit in degrees."""
- self.viewLim.x1 = np.deg2rad(thetamax)
-
- def get_thetamax(self):
- """Return the maximum theta limit in degrees."""
- return np.rad2deg(self.viewLim.xmax)
-
- def set_thetamin(self, thetamin):
- """Set the minimum theta limit in degrees."""
- self.viewLim.x0 = np.deg2rad(thetamin)
-
- def get_thetamin(self):
- """Get the minimum theta limit in degrees."""
- return np.rad2deg(self.viewLim.xmin)
-
- def set_thetalim(self, *args, **kwargs):
- r"""
- Set the minimum and maximum theta values.
-
- Can take the following signatures:
-
- - ``set_thetalim(minval, maxval)``: Set the limits in radians.
- - ``set_thetalim(thetamin=minval, thetamax=maxval)``: Set the limits
- in degrees.
-
- where minval and maxval are the minimum and maximum limits. Values are
- wrapped in to the range :math:`[0, 2\pi]` (in radians), so for example
- it is possible to do ``set_thetalim(-np.pi / 2, np.pi / 2)`` to have
- an axis symmetric around 0. A ValueError is raised if the absolute
- angle difference is larger than a full circle.
- """
- orig_lim = self.get_xlim() # in radians
- if 'thetamin' in kwargs:
- kwargs['xmin'] = np.deg2rad(kwargs.pop('thetamin'))
- if 'thetamax' in kwargs:
- kwargs['xmax'] = np.deg2rad(kwargs.pop('thetamax'))
- new_min, new_max = self.set_xlim(*args, **kwargs)
- # Parsing all permutations of *args, **kwargs is tricky; it is simpler
- # to let set_xlim() do it and then validate the limits.
- if abs(new_max - new_min) > 2 * np.pi:
- self.set_xlim(orig_lim) # un-accept the change
- raise ValueError("The angle range must be less than a full circle")
- return tuple(np.rad2deg((new_min, new_max)))
-
- def set_theta_offset(self, offset):
- """
- Set the offset for the location of 0 in radians.
- """
- mtx = self._theta_offset.get_matrix()
- mtx[0, 2] = offset
- self._theta_offset.invalidate()
-
- def get_theta_offset(self):
- """
- Get the offset for the location of 0 in radians.
- """
- return self._theta_offset.get_matrix()[0, 2]
-
- def set_theta_zero_location(self, loc, offset=0.0):
- """
- Set the location of theta's zero.
-
- This simply calls `set_theta_offset` with the correct value in radians.
-
- Parameters
- ----------
- loc : str
- May be one of "N", "NW", "W", "SW", "S", "SE", "E", or "NE".
- offset : float, default: 0
- An offset in degrees to apply from the specified *loc*. **Note:**
- this offset is *always* applied counter-clockwise regardless of
- the direction setting.
- """
- mapping = {
- 'N': np.pi * 0.5,
- 'NW': np.pi * 0.75,
- 'W': np.pi,
- 'SW': np.pi * 1.25,
- 'S': np.pi * 1.5,
- 'SE': np.pi * 1.75,
- 'E': 0,
- 'NE': np.pi * 0.25}
- return self.set_theta_offset(mapping[loc] + np.deg2rad(offset))
-
- def set_theta_direction(self, direction):
- """
- Set the direction in which theta increases.
-
- clockwise, -1:
- Theta increases in the clockwise direction
-
- counterclockwise, anticlockwise, 1:
- Theta increases in the counterclockwise direction
- """
- mtx = self._direction.get_matrix()
- if direction in ('clockwise', -1):
- mtx[0, 0] = -1
- elif direction in ('counterclockwise', 'anticlockwise', 1):
- mtx[0, 0] = 1
- else:
- _api.check_in_list(
- [-1, 1, 'clockwise', 'counterclockwise', 'anticlockwise'],
- direction=direction)
- self._direction.invalidate()
-
- def get_theta_direction(self):
- """
- Get the direction in which theta increases.
-
- -1:
- Theta increases in the clockwise direction
-
- 1:
- Theta increases in the counterclockwise direction
- """
- return self._direction.get_matrix()[0, 0]
-
- def set_rmax(self, rmax):
- """
- Set the outer radial limit.
-
- Parameters
- ----------
- rmax : float
- """
- self.viewLim.y1 = rmax
-
- def get_rmax(self):
- """
- Returns
- -------
- float
- Outer radial limit.
- """
- return self.viewLim.ymax
-
- def set_rmin(self, rmin):
- """
- Set the inner radial limit.
-
- Parameters
- ----------
- rmin : float
- """
- self.viewLim.y0 = rmin
-
- def get_rmin(self):
- """
- Returns
- -------
- float
- The inner radial limit.
- """
- return self.viewLim.ymin
-
- def set_rorigin(self, rorigin):
- """
- Update the radial origin.
-
- Parameters
- ----------
- rorigin : float
- """
- self._originViewLim.locked_y0 = rorigin
-
- def get_rorigin(self):
- """
- Returns
- -------
- float
- """
- return self._originViewLim.y0
-
- def get_rsign(self):
- return np.sign(self._originViewLim.y1 - self._originViewLim.y0)
-
- def set_rlim(self, bottom=None, top=None, *,
- emit=True, auto=False, **kwargs):
- """
- Set the radial axis view limits.
-
- This function behaves like `.Axes.set_ylim`, but additionally supports
- *rmin* and *rmax* as aliases for *bottom* and *top*.
-
- See Also
- --------
- .Axes.set_ylim
- """
- if 'rmin' in kwargs:
- if bottom is None:
- bottom = kwargs.pop('rmin')
- else:
- raise ValueError('Cannot supply both positional "bottom"'
- 'argument and kwarg "rmin"')
- if 'rmax' in kwargs:
- if top is None:
- top = kwargs.pop('rmax')
- else:
- raise ValueError('Cannot supply both positional "top"'
- 'argument and kwarg "rmax"')
- return self.set_ylim(bottom=bottom, top=top, emit=emit, auto=auto,
- **kwargs)
-
- def get_rlabel_position(self):
- """
- Returns
- -------
- float
- The theta position of the radius labels in degrees.
- """
- return np.rad2deg(self._r_label_position.get_matrix()[0, 2])
-
- def set_rlabel_position(self, value):
- """
- Update the theta position of the radius labels.
-
- Parameters
- ----------
- value : number
- The angular position of the radius labels in degrees.
- """
- self._r_label_position.clear().translate(np.deg2rad(value), 0.0)
-
- def set_yscale(self, *args, **kwargs):
- super().set_yscale(*args, **kwargs)
- self.yaxis.set_major_locator(
- self.RadialLocator(self.yaxis.get_major_locator(), self))
-
- def set_rscale(self, *args, **kwargs):
- return Axes.set_yscale(self, *args, **kwargs)
-
- def set_rticks(self, *args, **kwargs):
- return Axes.set_yticks(self, *args, **kwargs)
-
- def set_thetagrids(self, angles, labels=None, fmt=None, **kwargs):
- """
- Set the theta gridlines in a polar plot.
-
- Parameters
- ----------
- angles : tuple with floats, degrees
- The angles of the theta gridlines.
-
- labels : tuple with strings or None
- The labels to use at each theta gridline. The
- `.projections.polar.ThetaFormatter` will be used if None.
-
- fmt : str or None
- Format string used in `matplotlib.ticker.FormatStrFormatter`.
- For example '%f'. Note that the angle that is used is in
- radians.
-
- Returns
- -------
- lines : list of `.lines.Line2D`
- The theta gridlines.
-
- labels : list of `.text.Text`
- The tick labels.
-
- Other Parameters
- ----------------
- **kwargs
- *kwargs* are optional `.Text` properties for the labels.
-
- .. warning::
-
- This only sets the properties of the current ticks.
- Ticks are not guaranteed to be persistent. Various operations
- can create, delete and modify the Tick instances. There is an
- imminent risk that these settings can get lost if you work on
- the figure further (including also panning/zooming on a
- displayed figure).
-
- Use `.set_tick_params` instead if possible.
-
- See Also
- --------
- .PolarAxes.set_rgrids
- .Axis.get_gridlines
- .Axis.get_ticklabels
- """
-
- # Make sure we take into account unitized data
- angles = self.convert_yunits(angles)
- angles = np.deg2rad(angles)
- self.set_xticks(angles)
- if labels is not None:
- self.set_xticklabels(labels)
- elif fmt is not None:
- self.xaxis.set_major_formatter(mticker.FormatStrFormatter(fmt))
- for t in self.xaxis.get_ticklabels():
- t._internal_update(kwargs)
- return self.xaxis.get_ticklines(), self.xaxis.get_ticklabels()
-
- def set_rgrids(self, radii, labels=None, angle=None, fmt=None, **kwargs):
- """
- Set the radial gridlines on a polar plot.
-
- Parameters
- ----------
- radii : tuple with floats
- The radii for the radial gridlines
-
- labels : tuple with strings or None
- The labels to use at each radial gridline. The
- `matplotlib.ticker.ScalarFormatter` will be used if None.
-
- angle : float
- The angular position of the radius labels in degrees.
-
- fmt : str or None
- Format string used in `matplotlib.ticker.FormatStrFormatter`.
- For example '%f'.
-
- Returns
- -------
- lines : list of `.lines.Line2D`
- The radial gridlines.
-
- labels : list of `.text.Text`
- The tick labels.
-
- Other Parameters
- ----------------
- **kwargs
- *kwargs* are optional `.Text` properties for the labels.
-
- .. warning::
-
- This only sets the properties of the current ticks.
- Ticks are not guaranteed to be persistent. Various operations
- can create, delete and modify the Tick instances. There is an
- imminent risk that these settings can get lost if you work on
- the figure further (including also panning/zooming on a
- displayed figure).
-
- Use `.set_tick_params` instead if possible.
-
- See Also
- --------
- .PolarAxes.set_thetagrids
- .Axis.get_gridlines
- .Axis.get_ticklabels
- """
- # Make sure we take into account unitized data
- radii = self.convert_xunits(radii)
- radii = np.asarray(radii)
-
- self.set_yticks(radii)
- if labels is not None:
- self.set_yticklabels(labels)
- elif fmt is not None:
- self.yaxis.set_major_formatter(mticker.FormatStrFormatter(fmt))
- if angle is None:
- angle = self.get_rlabel_position()
- self.set_rlabel_position(angle)
- for t in self.yaxis.get_ticklabels():
- t._internal_update(kwargs)
- return self.yaxis.get_gridlines(), self.yaxis.get_ticklabels()
-
- def format_coord(self, theta, r):
- # docstring inherited
- screen_xy = self.transData.transform((theta, r))
- screen_xys = screen_xy + np.stack(
- np.meshgrid([-1, 0, 1], [-1, 0, 1])).reshape((2, -1)).T
- ts, rs = self.transData.inverted().transform(screen_xys).T
- delta_t = abs((ts - theta + np.pi) % (2 * np.pi) - np.pi).max()
- delta_t_halfturns = delta_t / np.pi
- delta_t_degrees = delta_t_halfturns * 180
- delta_r = abs(rs - r).max()
- if theta < 0:
- theta += 2 * np.pi
- theta_halfturns = theta / np.pi
- theta_degrees = theta_halfturns * 180
-
- # See ScalarFormatter.format_data_short. For r, use #g-formatting
- # (as for linear axes), but for theta, use f-formatting as scientific
- # notation doesn't make sense and the trailing dot is ugly.
- def format_sig(value, delta, opt, fmt):
- # For "f", only count digits after decimal point.
- prec = (max(0, -math.floor(math.log10(delta))) if fmt == "f" else
- cbook._g_sig_digits(value, delta))
- return f"{value:-{opt}.{prec}{fmt}}"
-
- return ('\N{GREEK SMALL LETTER THETA}={}\N{GREEK SMALL LETTER PI} '
- '({}\N{DEGREE SIGN}), r={}').format(
- format_sig(theta_halfturns, delta_t_halfturns, "", "f"),
- format_sig(theta_degrees, delta_t_degrees, "", "f"),
- format_sig(r, delta_r, "#", "g"),
- )
-
- def get_data_ratio(self):
- """
- Return the aspect ratio of the data itself. For a polar plot,
- this should always be 1.0
- """
- return 1.0
-
- # # # Interactive panning
-
- def can_zoom(self):
- """
- Return whether this Axes supports the zoom box button functionality.
-
- A polar Axes does not support zoom boxes.
- """
- return False
-
- def can_pan(self):
- """
- Return whether this Axes supports the pan/zoom button functionality.
-
- For a polar Axes, this is slightly misleading. Both panning and
- zooming are performed by the same button. Panning is performed
- in azimuth while zooming is done along the radial.
- """
- return True
-
- def start_pan(self, x, y, button):
- angle = np.deg2rad(self.get_rlabel_position())
- mode = ''
- if button == 1:
- epsilon = np.pi / 45.0
- t, r = self.transData.inverted().transform((x, y))
- if angle - epsilon <= t <= angle + epsilon:
- mode = 'drag_r_labels'
- elif button == 3:
- mode = 'zoom'
-
- self._pan_start = types.SimpleNamespace(
- rmax=self.get_rmax(),
- trans=self.transData.frozen(),
- trans_inverse=self.transData.inverted().frozen(),
- r_label_angle=self.get_rlabel_position(),
- x=x,
- y=y,
- mode=mode)
-
- def end_pan(self):
- del self._pan_start
-
- def drag_pan(self, button, key, x, y):
- p = self._pan_start
-
- if p.mode == 'drag_r_labels':
- (startt, startr), (t, r) = p.trans_inverse.transform(
- [(p.x, p.y), (x, y)])
-
- # Deal with theta
- dt = np.rad2deg(startt - t)
- self.set_rlabel_position(p.r_label_angle - dt)
-
- trans, vert1, horiz1 = self.get_yaxis_text1_transform(0.0)
- trans, vert2, horiz2 = self.get_yaxis_text2_transform(0.0)
- for t in self.yaxis.majorTicks + self.yaxis.minorTicks:
- t.label1.set_va(vert1)
- t.label1.set_ha(horiz1)
- t.label2.set_va(vert2)
- t.label2.set_ha(horiz2)
-
- elif p.mode == 'zoom':
- (startt, startr), (t, r) = p.trans_inverse.transform(
- [(p.x, p.y), (x, y)])
-
- # Deal with r
- scale = r / startr
- self.set_rmax(p.rmax / scale)
-
-
-# To keep things all self-contained, we can put aliases to the Polar classes
-# defined above. This isn't strictly necessary, but it makes some of the
-# code more readable, and provides a backwards compatible Polar API. In
-# particular, this is used by the :doc:`/gallery/specialty_plots/radar_chart`
-# example to override PolarTransform on a PolarAxes subclass, so make sure that
-# that example is unaffected before changing this.
-PolarAxes.PolarTransform = PolarTransform
-PolarAxes.PolarAffine = PolarAffine
-PolarAxes.InvertedPolarTransform = InvertedPolarTransform
-PolarAxes.ThetaFormatter = ThetaFormatter
-PolarAxes.RadialLocator = RadialLocator
-PolarAxes.ThetaLocator = ThetaLocator
diff --git a/contrib/python/matplotlib/py3/matplotlib/projections/polar.pyi b/contrib/python/matplotlib/py3/matplotlib/projections/polar.pyi
deleted file mode 100644
index 2592d49471..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/projections/polar.pyi
+++ /dev/null
@@ -1,196 +0,0 @@
-import matplotlib.axis as maxis
-import matplotlib.ticker as mticker
-import matplotlib.transforms as mtransforms
-from matplotlib.axes import Axes
-from matplotlib.lines import Line2D
-from matplotlib.text import Text
-
-import numpy as np
-from numpy.typing import ArrayLike
-from collections.abc import Sequence
-from typing import Any, ClassVar, Literal, overload
-
-class PolarTransform(mtransforms.Transform):
- input_dims: int
- output_dims: int
- def __init__(
- self,
- axis: PolarAxes | None = ...,
- use_rmin: bool = ...,
- _apply_theta_transforms: bool = ...,
- *,
- scale_transform: mtransforms.Transform | None = ...,
- ) -> None: ...
- def inverted(self) -> InvertedPolarTransform: ...
-
-class PolarAffine(mtransforms.Affine2DBase):
- def __init__(
- self, scale_transform: mtransforms.Transform, limits: mtransforms.BboxBase
- ) -> None: ...
-
-class InvertedPolarTransform(mtransforms.Transform):
- input_dims: int
- output_dims: int
- def __init__(
- self,
- axis: PolarAxes | None = ...,
- use_rmin: bool = ...,
- _apply_theta_transforms: bool = ...,
- ) -> None: ...
- def inverted(self) -> PolarTransform: ...
-
-class ThetaFormatter(mticker.Formatter): ...
-
-class _AxisWrapper:
- def __init__(self, axis: maxis.Axis) -> None: ...
- def get_view_interval(self) -> np.ndarray: ...
- def set_view_interval(self, vmin: float, vmax: float) -> None: ...
- def get_minpos(self) -> float: ...
- def get_data_interval(self) -> np.ndarray: ...
- def set_data_interval(self, vmin: float, vmax: float) -> None: ...
- def get_tick_space(self) -> int: ...
-
-class ThetaLocator(mticker.Locator):
- base: mticker.Locator
- axis: _AxisWrapper | None
- def __init__(self, base: mticker.Locator) -> None: ...
-
-class ThetaTick(maxis.XTick):
- def __init__(self, axes: PolarAxes, *args, **kwargs) -> None: ...
-
-class ThetaAxis(maxis.XAxis):
- axis_name: str
-
-class RadialLocator(mticker.Locator):
- base: mticker.Locator
- def __init__(self, base, axes: PolarAxes | None = ...) -> None: ...
-
-class RadialTick(maxis.YTick): ...
-
-class RadialAxis(maxis.YAxis):
- axis_name: str
-
-class _WedgeBbox(mtransforms.Bbox):
- def __init__(
- self,
- center: tuple[float, float],
- viewLim: mtransforms.Bbox,
- originLim: mtransforms.Bbox,
- **kwargs,
- ) -> None: ...
-
-class PolarAxes(Axes):
-
- PolarTransform: ClassVar[type] = PolarTransform
- PolarAffine: ClassVar[type] = PolarAffine
- InvertedPolarTransform: ClassVar[type] = InvertedPolarTransform
- ThetaFormatter: ClassVar[type] = ThetaFormatter
- RadialLocator: ClassVar[type] = RadialLocator
- ThetaLocator: ClassVar[type] = ThetaLocator
-
- name: str
- use_sticky_edges: bool
- def __init__(
- self,
- *args,
- theta_offset: float = ...,
- theta_direction: float = ...,
- rlabel_position: float = ...,
- **kwargs,
- ) -> None: ...
- def get_xaxis_transform(
- self, which: Literal["tick1", "tick2", "grid"] = ...
- ) -> mtransforms.Transform: ...
- def get_xaxis_text1_transform(
- self, pad: float
- ) -> tuple[
- mtransforms.Transform,
- Literal["center", "top", "bottom", "baseline", "center_baseline"],
- Literal["center", "left", "right"],
- ]: ...
- def get_xaxis_text2_transform(
- self, pad: float
- ) -> tuple[
- mtransforms.Transform,
- Literal["center", "top", "bottom", "baseline", "center_baseline"],
- Literal["center", "left", "right"],
- ]: ...
- def get_yaxis_transform(
- self, which: Literal["tick1", "tick2", "grid"] = ...
- ) -> mtransforms.Transform: ...
- def get_yaxis_text1_transform(
- self, pad: float
- ) -> tuple[
- mtransforms.Transform,
- Literal["center", "top", "bottom", "baseline", "center_baseline"],
- Literal["center", "left", "right"],
- ]: ...
- def get_yaxis_text2_transform(
- self, pad: float
- ) -> tuple[
- mtransforms.Transform,
- Literal["center", "top", "bottom", "baseline", "center_baseline"],
- Literal["center", "left", "right"],
- ]: ...
- def set_thetamax(self, thetamax: float) -> None: ...
- def get_thetamax(self) -> float: ...
- def set_thetamin(self, thetamin: float) -> None: ...
- def get_thetamin(self) -> float: ...
- @overload
- def set_thetalim(self, minval: float, maxval: float, /) -> tuple[float, float]: ...
- @overload
- def set_thetalim(self, *, thetamin: float, thetamax: float) -> tuple[float, float]: ...
- def set_theta_offset(self, offset: float) -> None: ...
- def get_theta_offset(self) -> float: ...
- def set_theta_zero_location(
- self,
- loc: Literal["N", "NW", "W", "SW", "S", "SE", "E", "NE"],
- offset: float = ...,
- ) -> None: ...
- def set_theta_direction(
- self,
- direction: Literal[-1, 1, "clockwise", "counterclockwise", "anticlockwise"],
- ) -> None: ...
- def get_theta_direction(self) -> Literal[-1, 1]: ...
- def set_rmax(self, rmax: float) -> None: ...
- def get_rmax(self) -> float: ...
- def set_rmin(self, rmin: float) -> None: ...
- def get_rmin(self) -> float: ...
- def set_rorigin(self, rorigin: float | None) -> None: ...
- def get_rorigin(self) -> float: ...
- def get_rsign(self) -> float: ...
- def set_rlim(
- self,
- bottom: float | tuple[float, float] | None = ...,
- top: float | None = ...,
- *,
- emit: bool = ...,
- auto: bool = ...,
- **kwargs,
- ) -> tuple[float, float]: ...
- def get_rlabel_position(self) -> float: ...
- def set_rlabel_position(self, value: float) -> None: ...
- def set_rscale(self, *args, **kwargs) -> None: ...
- def set_rticks(self, *args, **kwargs) -> None: ...
- def set_thetagrids(
- self,
- angles: ArrayLike,
- labels: Sequence[str | Text] | None = ...,
- fmt: str | None = ...,
- **kwargs,
- ) -> tuple[list[Line2D], list[Text]]: ...
- def set_rgrids(
- self,
- radii: ArrayLike,
- labels: Sequence[str | Text] | None = ...,
- angle: float | None = ...,
- fmt: str | None = ...,
- **kwargs,
- ) -> tuple[list[Line2D], list[Text]]: ...
- def format_coord(self, theta: float, r: float) -> str: ...
- def get_data_ratio(self) -> float: ...
- def can_zoom(self) -> bool: ...
- def can_pan(self) -> bool: ...
- def start_pan(self, x: float, y: float, button: int) -> None: ...
- def end_pan(self) -> None: ...
- def drag_pan(self, button: Any, key: Any, x: float, y: float) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/py.typed b/contrib/python/matplotlib/py3/matplotlib/py.typed
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/py.typed
+++ /dev/null
diff --git a/contrib/python/matplotlib/py3/matplotlib/pylab.py b/contrib/python/matplotlib/py3/matplotlib/pylab.py
deleted file mode 100644
index 77eb6506d8..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/pylab.py
+++ /dev/null
@@ -1,65 +0,0 @@
-"""
-`pylab` is a historic interface and its use is strongly discouraged. The equivalent
-replacement is `matplotlib.pyplot`. See :ref:`api_interfaces` for a full overview
-of Matplotlib interfaces.
-
-`pylab` was designed to support a MATLAB-like way of working with all plotting related
-functions directly available in the global namespace. This was achieved through a
-wildcard import (``from pylab import *``).
-
-.. warning::
- The use of `pylab` is discouraged for the following reasons:
-
- ``from pylab import *`` imports all the functions from `matplotlib.pyplot`, `numpy`,
- `numpy.fft`, `numpy.linalg`, and `numpy.random`, and some additional functions into
- the global namespace.
-
- Such a pattern is considered bad practice in modern python, as it clutters the global
- namespace. Even more severely, in the case of `pylab`, this will overwrite some
- builtin functions (e.g. the builtin `sum` will be replaced by `numpy.sum`), which
- can lead to unexpected behavior.
-
-"""
-
-from matplotlib.cbook import flatten, silent_list
-
-import matplotlib as mpl
-
-from matplotlib.dates import (
- date2num, num2date, datestr2num, drange, DateFormatter, DateLocator,
- RRuleLocator, YearLocator, MonthLocator, WeekdayLocator, DayLocator,
- HourLocator, MinuteLocator, SecondLocator, rrule, MO, TU, WE, TH, FR,
- SA, SU, YEARLY, MONTHLY, WEEKLY, DAILY, HOURLY, MINUTELY, SECONDLY,
- relativedelta)
-
-# bring all the symbols in so folks can import them from
-# pylab in one fell swoop
-
-## We are still importing too many things from mlab; more cleanup is needed.
-
-from matplotlib.mlab import (
- detrend, detrend_linear, detrend_mean, detrend_none, window_hanning,
- window_none)
-
-from matplotlib import cbook, mlab, pyplot as plt
-from matplotlib.pyplot import *
-
-from numpy import *
-from numpy.fft import *
-from numpy.random import *
-from numpy.linalg import *
-
-import numpy as np
-import numpy.ma as ma
-
-# don't let numpy's datetime hide stdlib
-import datetime
-
-# This is needed, or bytes will be numpy.random.bytes from
-# "from numpy.random import *" above
-bytes = __import__("builtins").bytes
-# We also don't want the numpy version of these functions
-abs = __import__("builtins").abs
-max = __import__("builtins").max
-min = __import__("builtins").min
-round = __import__("builtins").round
diff --git a/contrib/python/matplotlib/py3/matplotlib/pyplot.py b/contrib/python/matplotlib/py3/matplotlib/pyplot.py
deleted file mode 100644
index 62f7eba74e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/pyplot.py
+++ /dev/null
@@ -1,4373 +0,0 @@
-# Note: The first part of this file can be modified in place, but the latter
-# part is autogenerated by the boilerplate.py script.
-
-"""
-`matplotlib.pyplot` is a state-based interface to matplotlib. It provides
-an implicit, MATLAB-like, way of plotting. It also opens figures on your
-screen, and acts as the figure GUI manager.
-
-pyplot is mainly intended for interactive plots and simple cases of
-programmatic plot generation::
-
- import numpy as np
- import matplotlib.pyplot as plt
-
- x = np.arange(0, 5, 0.1)
- y = np.sin(x)
- plt.plot(x, y)
-
-The explicit object-oriented API is recommended for complex plots, though
-pyplot is still usually used to create the figure and often the axes in the
-figure. See `.pyplot.figure`, `.pyplot.subplots`, and
-`.pyplot.subplot_mosaic` to create figures, and
-:doc:`Axes API </api/axes_api>` for the plotting methods on an Axes::
-
- import numpy as np
- import matplotlib.pyplot as plt
-
- x = np.arange(0, 5, 0.1)
- y = np.sin(x)
- fig, ax = plt.subplots()
- ax.plot(x, y)
-
-
-See :ref:`api_interfaces` for an explanation of the tradeoffs between the
-implicit and explicit interfaces.
-"""
-
-# fmt: off
-
-from __future__ import annotations
-
-from contextlib import AbstractContextManager, ExitStack
-from enum import Enum
-import functools
-import importlib
-import inspect
-import logging
-import re
-import sys
-import threading
-import time
-from typing import cast, overload
-
-from cycler import cycler
-import matplotlib
-import matplotlib.colorbar
-import matplotlib.image
-from matplotlib import _api
-from matplotlib import ( # Re-exported for typing.
- cm as cm, get_backend as get_backend, rcParams as rcParams, style as style)
-from matplotlib import _pylab_helpers, interactive
-from matplotlib import cbook
-from matplotlib import _docstring
-from matplotlib.backend_bases import (
- FigureCanvasBase, FigureManagerBase, MouseButton)
-from matplotlib.figure import Figure, FigureBase, figaspect
-from matplotlib.gridspec import GridSpec, SubplotSpec
-from matplotlib import rcsetup, rcParamsDefault, rcParamsOrig
-from matplotlib.artist import Artist
-from matplotlib.axes import Axes, Subplot # type: ignore
-from matplotlib.projections import PolarAxes # type: ignore
-from matplotlib import mlab # for detrend_none, window_hanning
-from matplotlib.scale import get_scale_names
-
-from matplotlib.cm import _colormaps
-from matplotlib.cm import register_cmap # type: ignore
-from matplotlib.colors import _color_sequences
-
-import numpy as np
-
-from typing import TYPE_CHECKING, cast
-
-if TYPE_CHECKING:
- from collections.abc import Callable, Hashable, Iterable, Sequence
- import datetime
- import pathlib
- import os
- from typing import Any, BinaryIO, Literal, TypeVar
- from typing_extensions import ParamSpec
-
- import PIL.Image
- from numpy.typing import ArrayLike
-
- from matplotlib.axis import Tick
- from matplotlib.axes._base import _AxesBase
- from matplotlib.backend_bases import RendererBase, Event
- from matplotlib.cm import ScalarMappable
- from matplotlib.contour import ContourSet, QuadContourSet
- from matplotlib.collections import (
- Collection,
- LineCollection,
- BrokenBarHCollection,
- PolyCollection,
- PathCollection,
- EventCollection,
- QuadMesh,
- )
- from matplotlib.colorbar import Colorbar
- from matplotlib.colors import Colormap
- from matplotlib.container import (
- BarContainer,
- ErrorbarContainer,
- StemContainer,
- )
- from matplotlib.figure import SubFigure
- from matplotlib.legend import Legend
- from matplotlib.mlab import GaussianKDE
- from matplotlib.image import AxesImage, FigureImage
- from matplotlib.patches import FancyArrow, StepPatch, Wedge
- from matplotlib.quiver import Barbs, Quiver, QuiverKey
- from matplotlib.scale import ScaleBase
- from matplotlib.transforms import Transform, Bbox
- from matplotlib.typing import ColorType, LineStyleType, MarkerType, HashableList
- from matplotlib.widgets import SubplotTool
-
- _P = ParamSpec('_P')
- _R = TypeVar('_R')
- _T = TypeVar('_T')
-
-
-# We may not need the following imports here:
-from matplotlib.colors import Normalize
-from matplotlib.lines import Line2D
-from matplotlib.text import Text, Annotation
-from matplotlib.patches import Polygon, Rectangle, Circle, Arrow
-from matplotlib.widgets import Button, Slider, Widget
-
-from .ticker import (
- TickHelper, Formatter, FixedFormatter, NullFormatter, FuncFormatter,
- FormatStrFormatter, ScalarFormatter, LogFormatter, LogFormatterExponent,
- LogFormatterMathtext, Locator, IndexLocator, FixedLocator, NullLocator,
- LinearLocator, LogLocator, AutoLocator, MultipleLocator, MaxNLocator)
-
-_log = logging.getLogger(__name__)
-
-
-# Explicit rename instead of import-as for typing's sake.
-colormaps = _colormaps
-color_sequences = _color_sequences
-
-
-@overload
-def _copy_docstring_and_deprecators(
- method: Any,
- func: Literal[None] = None
-) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ...
-
-
-@overload
-def _copy_docstring_and_deprecators(
- method: Any, func: Callable[_P, _R]) -> Callable[_P, _R]: ...
-
-
-def _copy_docstring_and_deprecators(
- method: Any,
- func: Callable[_P, _R] | None = None
-) -> Callable[[Callable[_P, _R]], Callable[_P, _R]] | Callable[_P, _R]:
- if func is None:
- return cast('Callable[[Callable[_P, _R]], Callable[_P, _R]]',
- functools.partial(_copy_docstring_and_deprecators, method))
- decorators: list[Callable[[Callable[_P, _R]], Callable[_P, _R]]] = [
- _docstring.copy(method)
- ]
- # Check whether the definition of *method* includes @_api.rename_parameter
- # or @_api.make_keyword_only decorators; if so, propagate them to the
- # pyplot wrapper as well.
- while hasattr(method, "__wrapped__"):
- potential_decorator = _api.deprecation.DECORATORS.get(method)
- if potential_decorator:
- decorators.append(potential_decorator)
- method = method.__wrapped__
- for decorator in decorators[::-1]:
- func = decorator(func)
- return func
-
-
-## Global ##
-
-
-# The state controlled by {,un}install_repl_displayhook().
-_ReplDisplayHook = Enum("_ReplDisplayHook", ["NONE", "PLAIN", "IPYTHON"])
-_REPL_DISPLAYHOOK = _ReplDisplayHook.NONE
-
-
-def _draw_all_if_interactive() -> None:
- if matplotlib.is_interactive():
- draw_all()
-
-
-def install_repl_displayhook() -> None:
- """
- Connect to the display hook of the current shell.
-
- The display hook gets called when the read-evaluate-print-loop (REPL) of
- the shell has finished the execution of a command. We use this callback
- to be able to automatically update a figure in interactive mode.
-
- This works both with IPython and with vanilla python shells.
- """
- global _REPL_DISPLAYHOOK
-
- if _REPL_DISPLAYHOOK is _ReplDisplayHook.IPYTHON:
- return
-
- # See if we have IPython hooks around, if so use them.
- # Use ``sys.modules.get(name)`` rather than ``name in sys.modules`` as
- # entries can also have been explicitly set to None.
- mod_ipython = sys.modules.get("IPython")
- if not mod_ipython:
- _REPL_DISPLAYHOOK = _ReplDisplayHook.PLAIN
- return
- ip = mod_ipython.get_ipython()
- if not ip:
- _REPL_DISPLAYHOOK = _ReplDisplayHook.PLAIN
- return
-
- ip.events.register("post_execute", _draw_all_if_interactive)
- _REPL_DISPLAYHOOK = _ReplDisplayHook.IPYTHON
-
- from IPython.core.pylabtools import backend2gui # type: ignore
- # trigger IPython's eventloop integration, if available
- ipython_gui_name = backend2gui.get(get_backend())
- if ipython_gui_name:
- ip.enable_gui(ipython_gui_name)
-
-
-def uninstall_repl_displayhook() -> None:
- """Disconnect from the display hook of the current shell."""
- global _REPL_DISPLAYHOOK
- if _REPL_DISPLAYHOOK is _ReplDisplayHook.IPYTHON:
- from IPython import get_ipython # type: ignore
- ip = get_ipython()
- ip.events.unregister("post_execute", _draw_all_if_interactive)
- _REPL_DISPLAYHOOK = _ReplDisplayHook.NONE
-
-
-draw_all = _pylab_helpers.Gcf.draw_all
-
-
-# Ensure this appears in the pyplot docs.
-@_copy_docstring_and_deprecators(matplotlib.set_loglevel)
-def set_loglevel(*args, **kwargs) -> None:
- return matplotlib.set_loglevel(*args, **kwargs)
-
-
-@_copy_docstring_and_deprecators(Artist.findobj)
-def findobj(
- o: Artist | None = None,
- match: Callable[[Artist], bool] | type[Artist] | None = None,
- include_self: bool = True
-) -> list[Artist]:
- if o is None:
- o = gcf()
- return o.findobj(match, include_self=include_self)
-
-
-_backend_mod: type[matplotlib.backend_bases._Backend] | None = None
-
-
-def _get_backend_mod() -> type[matplotlib.backend_bases._Backend]:
- """
- Ensure that a backend is selected and return it.
-
- This is currently private, but may be made public in the future.
- """
- if _backend_mod is None:
- # Use rcParams._get("backend") to avoid going through the fallback
- # logic (which will (re)import pyplot and then call switch_backend if
- # we need to resolve the auto sentinel)
- switch_backend(rcParams._get("backend")) # type: ignore[attr-defined]
- return cast(type[matplotlib.backend_bases._Backend], _backend_mod)
-
-
-def switch_backend(newbackend: str) -> None:
- """
- Set the pyplot backend.
-
- Switching to an interactive backend is possible only if no event loop for
- another interactive backend has started. Switching to and from
- non-interactive backends is always possible.
-
- If the new backend is different than the current backend then all open
- Figures will be closed via ``plt.close('all')``.
-
- Parameters
- ----------
- newbackend : str
- The case-insensitive name of the backend to use.
-
- """
- global _backend_mod
- # make sure the init is pulled up so we can assign to it later
- import matplotlib.backends
-
- if newbackend is rcsetup._auto_backend_sentinel:
- current_framework = cbook._get_running_interactive_framework()
- mapping = {'qt': 'qtagg',
- 'gtk3': 'gtk3agg',
- 'gtk4': 'gtk4agg',
- 'wx': 'wxagg',
- 'tk': 'tkagg',
- 'macosx': 'macosx',
- 'headless': 'agg'}
-
- if current_framework in mapping:
- candidates = [mapping[current_framework]]
- else:
- candidates = []
- candidates += [
- "macosx", "qtagg", "gtk4agg", "gtk3agg", "tkagg", "wxagg"]
-
- # Don't try to fallback on the cairo-based backends as they each have
- # an additional dependency (pycairo) over the agg-based backend, and
- # are of worse quality.
- for candidate in candidates:
- try:
- switch_backend(candidate)
- except ImportError:
- continue
- else:
- rcParamsOrig['backend'] = candidate
- return
- else:
- # Switching to Agg should always succeed; if it doesn't, let the
- # exception propagate out.
- switch_backend("agg")
- rcParamsOrig["backend"] = "agg"
- return
- # have to escape the switch on access logic
- old_backend = dict.__getitem__(rcParams, 'backend')
-
- module = importlib.import_module(cbook._backend_module_name(newbackend))
- canvas_class = module.FigureCanvas
-
- required_framework = canvas_class.required_interactive_framework
- if required_framework is not None:
- current_framework = cbook._get_running_interactive_framework()
- if (current_framework and required_framework
- and current_framework != required_framework):
- raise ImportError(
- "Cannot load backend {!r} which requires the {!r} interactive "
- "framework, as {!r} is currently running".format(
- newbackend, required_framework, current_framework))
-
- # Load the new_figure_manager() and show() functions from the backend.
-
- # Classically, backends can directly export these functions. This should
- # keep working for backcompat.
- new_figure_manager = getattr(module, "new_figure_manager", None)
- show = getattr(module, "show", None)
-
- # In that classical approach, backends are implemented as modules, but
- # "inherit" default method implementations from backend_bases._Backend.
- # This is achieved by creating a "class" that inherits from
- # backend_bases._Backend and whose body is filled with the module globals.
- class backend_mod(matplotlib.backend_bases._Backend):
- locals().update(vars(module))
-
- # However, the newer approach for defining new_figure_manager and
- # show is to derive them from canvas methods. In that case, also
- # update backend_mod accordingly; also, per-backend customization of
- # draw_if_interactive is disabled.
- if new_figure_manager is None:
-
- def new_figure_manager_given_figure(num, figure):
- return canvas_class.new_manager(figure, num)
-
- def new_figure_manager(num, *args, FigureClass=Figure, **kwargs):
- fig = FigureClass(*args, **kwargs)
- return new_figure_manager_given_figure(num, fig)
-
- def draw_if_interactive() -> None:
- if matplotlib.is_interactive():
- manager = _pylab_helpers.Gcf.get_active()
- if manager:
- manager.canvas.draw_idle()
-
- backend_mod.new_figure_manager_given_figure = ( # type: ignore[method-assign]
- new_figure_manager_given_figure)
- backend_mod.new_figure_manager = ( # type: ignore[method-assign]
- new_figure_manager)
- backend_mod.draw_if_interactive = ( # type: ignore[method-assign]
- draw_if_interactive)
-
- # If the manager explicitly overrides pyplot_show, use it even if a global
- # show is already present, as the latter may be here for backcompat.
- manager_class = getattr(canvas_class, "manager_class", None)
- # We can't compare directly manager_class.pyplot_show and FMB.pyplot_show because
- # pyplot_show is a classmethod so the above constructs are bound classmethods, and
- # thus always different (being bound to different classes). We also have to use
- # getattr_static instead of vars as manager_class could have no __dict__.
- manager_pyplot_show = inspect.getattr_static(manager_class, "pyplot_show", None)
- base_pyplot_show = inspect.getattr_static(FigureManagerBase, "pyplot_show", None)
- if (show is None
- or (manager_pyplot_show is not None
- and manager_pyplot_show != base_pyplot_show)):
- if not manager_pyplot_show:
- raise ValueError(
- f"Backend {newbackend} defines neither FigureCanvas.manager_class nor "
- f"a toplevel show function")
- _pyplot_show = cast('Any', manager_class).pyplot_show
- backend_mod.show = _pyplot_show # type: ignore[method-assign]
-
- _log.debug("Loaded backend %s version %s.",
- newbackend, backend_mod.backend_version)
-
- rcParams['backend'] = rcParamsDefault['backend'] = newbackend
- _backend_mod = backend_mod
- for func_name in ["new_figure_manager", "draw_if_interactive", "show"]:
- globals()[func_name].__signature__ = inspect.signature(
- getattr(backend_mod, func_name))
-
- # Need to keep a global reference to the backend for compatibility reasons.
- # See https://github.com/matplotlib/matplotlib/issues/6092
- matplotlib.backends.backend = newbackend # type: ignore[attr-defined]
-
- if not cbook._str_equal(old_backend, newbackend):
- if get_fignums():
- _api.warn_deprecated("3.8", message=(
- "Auto-close()ing of figures upon backend switching is deprecated since "
- "%(since)s and will be removed %(removal)s. To suppress this warning, "
- "explicitly call plt.close('all') first."))
- close("all")
-
- # Make sure the repl display hook is installed in case we become interactive.
- install_repl_displayhook()
-
-
-def _warn_if_gui_out_of_main_thread() -> None:
- warn = False
- canvas_class = cast(type[FigureCanvasBase], _get_backend_mod().FigureCanvas)
- if canvas_class.required_interactive_framework:
- if hasattr(threading, 'get_native_id'):
- # This compares native thread ids because even if Python-level
- # Thread objects match, the underlying OS thread (which is what
- # really matters) may be different on Python implementations with
- # green threads.
- if threading.get_native_id() != threading.main_thread().native_id:
- warn = True
- else:
- # Fall back to Python-level Thread if native IDs are unavailable,
- # mainly for PyPy.
- if threading.current_thread() is not threading.main_thread():
- warn = True
- if warn:
- _api.warn_external(
- "Starting a Matplotlib GUI outside of the main thread will likely "
- "fail.")
-
-
-# This function's signature is rewritten upon backend-load by switch_backend.
-def new_figure_manager(*args, **kwargs):
- """Create a new figure manager instance."""
- _warn_if_gui_out_of_main_thread()
- return _get_backend_mod().new_figure_manager(*args, **kwargs)
-
-
-# This function's signature is rewritten upon backend-load by switch_backend.
-def draw_if_interactive(*args, **kwargs):
- """
- Redraw the current figure if in interactive mode.
-
- .. warning::
-
- End users will typically not have to call this function because the
- the interactive mode takes care of this.
- """
- return _get_backend_mod().draw_if_interactive(*args, **kwargs)
-
-
-# This function's signature is rewritten upon backend-load by switch_backend.
-def show(*args, **kwargs) -> None:
- """
- Display all open figures.
-
- Parameters
- ----------
- block : bool, optional
- Whether to wait for all figures to be closed before returning.
-
- If `True` block and run the GUI main loop until all figure windows
- are closed.
-
- If `False` ensure that all figure windows are displayed and return
- immediately. In this case, you are responsible for ensuring
- that the event loop is running to have responsive figures.
-
- Defaults to True in non-interactive mode and to False in interactive
- mode (see `.pyplot.isinteractive`).
-
- See Also
- --------
- ion : Enable interactive mode, which shows / updates the figure after
- every plotting command, so that calling ``show()`` is not necessary.
- ioff : Disable interactive mode.
- savefig : Save the figure to an image file instead of showing it on screen.
-
- Notes
- -----
- **Saving figures to file and showing a window at the same time**
-
- If you want an image file as well as a user interface window, use
- `.pyplot.savefig` before `.pyplot.show`. At the end of (a blocking)
- ``show()`` the figure is closed and thus unregistered from pyplot. Calling
- `.pyplot.savefig` afterwards would save a new and thus empty figure. This
- limitation of command order does not apply if the show is non-blocking or
- if you keep a reference to the figure and use `.Figure.savefig`.
-
- **Auto-show in jupyter notebooks**
-
- The jupyter backends (activated via ``%matplotlib inline``,
- ``%matplotlib notebook``, or ``%matplotlib widget``), call ``show()`` at
- the end of every cell by default. Thus, you usually don't have to call it
- explicitly there.
- """
- _warn_if_gui_out_of_main_thread()
- return _get_backend_mod().show(*args, **kwargs)
-
-
-def isinteractive() -> bool:
- """
- Return whether plots are updated after every plotting command.
-
- The interactive mode is mainly useful if you build plots from the command
- line and want to see the effect of each command while you are building the
- figure.
-
- In interactive mode:
-
- - newly created figures will be shown immediately;
- - figures will automatically redraw on change;
- - `.pyplot.show` will not block by default.
-
- In non-interactive mode:
-
- - newly created figures and changes to figures will not be reflected until
- explicitly asked to be;
- - `.pyplot.show` will block by default.
-
- See Also
- --------
- ion : Enable interactive mode.
- ioff : Disable interactive mode.
- show : Show all figures (and maybe block).
- pause : Show all figures, and block for a time.
- """
- return matplotlib.is_interactive()
-
-
-def ioff() -> ExitStack:
- """
- Disable interactive mode.
-
- See `.pyplot.isinteractive` for more details.
-
- See Also
- --------
- ion : Enable interactive mode.
- isinteractive : Whether interactive mode is enabled.
- show : Show all figures (and maybe block).
- pause : Show all figures, and block for a time.
-
- Notes
- -----
- For a temporary change, this can be used as a context manager::
-
- # if interactive mode is on
- # then figures will be shown on creation
- plt.ion()
- # This figure will be shown immediately
- fig = plt.figure()
-
- with plt.ioff():
- # interactive mode will be off
- # figures will not automatically be shown
- fig2 = plt.figure()
- # ...
-
- To enable optional usage as a context manager, this function returns a
- `~contextlib.ExitStack` object, which is not intended to be stored or
- accessed by the user.
- """
- stack = ExitStack()
- stack.callback(ion if isinteractive() else ioff)
- matplotlib.interactive(False)
- uninstall_repl_displayhook()
- return stack
-
-
-def ion() -> ExitStack:
- """
- Enable interactive mode.
-
- See `.pyplot.isinteractive` for more details.
-
- See Also
- --------
- ioff : Disable interactive mode.
- isinteractive : Whether interactive mode is enabled.
- show : Show all figures (and maybe block).
- pause : Show all figures, and block for a time.
-
- Notes
- -----
- For a temporary change, this can be used as a context manager::
-
- # if interactive mode is off
- # then figures will not be shown on creation
- plt.ioff()
- # This figure will not be shown immediately
- fig = plt.figure()
-
- with plt.ion():
- # interactive mode will be on
- # figures will automatically be shown
- fig2 = plt.figure()
- # ...
-
- To enable optional usage as a context manager, this function returns a
- `~contextlib.ExitStack` object, which is not intended to be stored or
- accessed by the user.
- """
- stack = ExitStack()
- stack.callback(ion if isinteractive() else ioff)
- matplotlib.interactive(True)
- install_repl_displayhook()
- return stack
-
-
-def pause(interval: float) -> None:
- """
- Run the GUI event loop for *interval* seconds.
-
- If there is an active figure, it will be updated and displayed before the
- pause, and the GUI event loop (if any) will run during the pause.
-
- This can be used for crude animation. For more complex animation use
- :mod:`matplotlib.animation`.
-
- If there is no active figure, sleep for *interval* seconds instead.
-
- See Also
- --------
- matplotlib.animation : Proper animations
- show : Show all figures and optional block until all figures are closed.
- """
- manager = _pylab_helpers.Gcf.get_active()
- if manager is not None:
- canvas = manager.canvas
- if canvas.figure.stale:
- canvas.draw_idle()
- show(block=False)
- canvas.start_event_loop(interval)
- else:
- time.sleep(interval)
-
-
-@_copy_docstring_and_deprecators(matplotlib.rc)
-def rc(group: str, **kwargs) -> None:
- matplotlib.rc(group, **kwargs)
-
-
-@_copy_docstring_and_deprecators(matplotlib.rc_context)
-def rc_context(
- rc: dict[str, Any] | None = None,
- fname: str | pathlib.Path | os.PathLike | None = None,
-) -> AbstractContextManager[None]:
- return matplotlib.rc_context(rc, fname)
-
-
-@_copy_docstring_and_deprecators(matplotlib.rcdefaults)
-def rcdefaults() -> None:
- matplotlib.rcdefaults()
- if matplotlib.is_interactive():
- draw_all()
-
-
-# getp/get/setp are explicitly reexported so that they show up in pyplot docs.
-
-
-@_copy_docstring_and_deprecators(matplotlib.artist.getp)
-def getp(obj, *args, **kwargs):
- return matplotlib.artist.getp(obj, *args, **kwargs)
-
-
-@_copy_docstring_and_deprecators(matplotlib.artist.get)
-def get(obj, *args, **kwargs):
- return matplotlib.artist.get(obj, *args, **kwargs)
-
-
-@_copy_docstring_and_deprecators(matplotlib.artist.setp)
-def setp(obj, *args, **kwargs):
- return matplotlib.artist.setp(obj, *args, **kwargs)
-
-
-def xkcd(
- scale: float = 1, length: float = 100, randomness: float = 2
-) -> ExitStack:
- """
- Turn on `xkcd <https://xkcd.com/>`_ sketch-style drawing mode.
-
- This will only have an effect on things drawn after this function is called.
-
- For best results, install the `xkcd script <https://github.com/ipython/xkcd-font/>`_
- font; xkcd fonts are not packaged with Matplotlib.
-
- Parameters
- ----------
- scale : float, optional
- The amplitude of the wiggle perpendicular to the source line.
- length : float, optional
- The length of the wiggle along the line.
- randomness : float, optional
- The scale factor by which the length is shrunken or expanded.
-
- Notes
- -----
- This function works by a number of rcParams, so it will probably
- override others you have set before.
-
- If you want the effects of this function to be temporary, it can
- be used as a context manager, for example::
-
- with plt.xkcd():
- # This figure will be in XKCD-style
- fig1 = plt.figure()
- # ...
-
- # This figure will be in regular style
- fig2 = plt.figure()
- """
- # This cannot be implemented in terms of contextmanager() or rc_context()
- # because this needs to work as a non-contextmanager too.
-
- if rcParams['text.usetex']:
- raise RuntimeError(
- "xkcd mode is not compatible with text.usetex = True")
-
- stack = ExitStack()
- stack.callback(dict.update, rcParams, rcParams.copy()) # type: ignore
-
- from matplotlib import patheffects
- rcParams.update({
- 'font.family': ['xkcd', 'xkcd Script', 'Comic Neue', 'Comic Sans MS'],
- 'font.size': 14.0,
- 'path.sketch': (scale, length, randomness),
- 'path.effects': [
- patheffects.withStroke(linewidth=4, foreground="w")],
- 'axes.linewidth': 1.5,
- 'lines.linewidth': 2.0,
- 'figure.facecolor': 'white',
- 'grid.linewidth': 0.0,
- 'axes.grid': False,
- 'axes.unicode_minus': False,
- 'axes.edgecolor': 'black',
- 'xtick.major.size': 8,
- 'xtick.major.width': 3,
- 'ytick.major.size': 8,
- 'ytick.major.width': 3,
- })
-
- return stack
-
-
-## Figures ##
-
-def figure(
- # autoincrement if None, else integer from 1-N
- num: int | str | Figure | SubFigure | None = None,
- # defaults to rc figure.figsize
- figsize: tuple[float, float] | None = None,
- # defaults to rc figure.dpi
- dpi: float | None = None,
- *,
- # defaults to rc figure.facecolor
- facecolor: ColorType | None = None,
- # defaults to rc figure.edgecolor
- edgecolor: ColorType | None = None,
- frameon: bool = True,
- FigureClass: type[Figure] = Figure,
- clear: bool = False,
- **kwargs
-) -> Figure:
- """
- Create a new figure, or activate an existing figure.
-
- Parameters
- ----------
- num : int or str or `.Figure` or `.SubFigure`, optional
- A unique identifier for the figure.
-
- If a figure with that identifier already exists, this figure is made
- active and returned. An integer refers to the ``Figure.number``
- attribute, a string refers to the figure label.
-
- If there is no figure with the identifier or *num* is not given, a new
- figure is created, made active and returned. If *num* is an int, it
- will be used for the ``Figure.number`` attribute, otherwise, an
- auto-generated integer value is used (starting at 1 and incremented
- for each new figure). If *num* is a string, the figure label and the
- window title is set to this value. If num is a ``SubFigure``, its
- parent ``Figure`` is activated.
-
- figsize : (float, float), default: :rc:`figure.figsize`
- Width, height in inches.
-
- dpi : float, default: :rc:`figure.dpi`
- The resolution of the figure in dots-per-inch.
-
- facecolor : color, default: :rc:`figure.facecolor`
- The background color.
-
- edgecolor : color, default: :rc:`figure.edgecolor`
- The border color.
-
- frameon : bool, default: True
- If False, suppress drawing the figure frame.
-
- FigureClass : subclass of `~matplotlib.figure.Figure`
- If set, an instance of this subclass will be created, rather than a
- plain `.Figure`.
-
- clear : bool, default: False
- If True and the figure already exists, then it is cleared.
-
- layout : {'constrained', 'compressed', 'tight', 'none', `.LayoutEngine`, None}, \
-default: None
- The layout mechanism for positioning of plot elements to avoid
- overlapping Axes decorations (labels, ticks, etc). Note that layout
- managers can measurably slow down figure display.
-
- - 'constrained': The constrained layout solver adjusts axes sizes
- to avoid overlapping axes decorations. Can handle complex plot
- layouts and colorbars, and is thus recommended.
-
- See :ref:`constrainedlayout_guide`
- for examples.
-
- - 'compressed': uses the same algorithm as 'constrained', but
- removes extra space between fixed-aspect-ratio Axes. Best for
- simple grids of axes.
-
- - 'tight': Use the tight layout mechanism. This is a relatively
- simple algorithm that adjusts the subplot parameters so that
- decorations do not overlap. See `.Figure.set_tight_layout` for
- further details.
-
- - 'none': Do not use a layout engine.
-
- - A `.LayoutEngine` instance. Builtin layout classes are
- `.ConstrainedLayoutEngine` and `.TightLayoutEngine`, more easily
- accessible by 'constrained' and 'tight'. Passing an instance
- allows third parties to provide their own layout engine.
-
- If not given, fall back to using the parameters *tight_layout* and
- *constrained_layout*, including their config defaults
- :rc:`figure.autolayout` and :rc:`figure.constrained_layout.use`.
-
- **kwargs
- Additional keyword arguments are passed to the `.Figure` constructor.
-
- Returns
- -------
- `~matplotlib.figure.Figure`
-
- Notes
- -----
- A newly created figure is passed to the `~.FigureCanvasBase.new_manager`
- method or the `new_figure_manager` function provided by the current
- backend, which install a canvas and a manager on the figure.
-
- Once this is done, :rc:`figure.hooks` are called, one at a time, on the
- figure; these hooks allow arbitrary customization of the figure (e.g.,
- attaching callbacks) or of associated elements (e.g., modifying the
- toolbar). See :doc:`/gallery/user_interfaces/mplcvd` for an example of
- toolbar customization.
-
- If you are creating many figures, make sure you explicitly call
- `.pyplot.close` on the figures you are not using, because this will
- enable pyplot to properly clean up the memory.
-
- `~matplotlib.rcParams` defines the default values, which can be modified
- in the matplotlibrc file.
- """
- if isinstance(num, FigureBase):
- # type narrowed to `Figure | SubFigure` by combination of input and isinstance
- if num.canvas.manager is None:
- raise ValueError("The passed figure is not managed by pyplot")
- _pylab_helpers.Gcf.set_active(num.canvas.manager)
- return num.figure
-
- allnums = get_fignums()
- next_num = max(allnums) + 1 if allnums else 1
- fig_label = ''
- if num is None:
- num = next_num
- elif isinstance(num, str):
- fig_label = num
- all_labels = get_figlabels()
- if fig_label not in all_labels:
- if fig_label == 'all':
- _api.warn_external("close('all') closes all existing figures.")
- num = next_num
- else:
- inum = all_labels.index(fig_label)
- num = allnums[inum]
- else:
- num = int(num) # crude validation of num argument
-
- # Type of "num" has narrowed to int, but mypy can't quite see it
- manager = _pylab_helpers.Gcf.get_fig_manager(num) # type: ignore[arg-type]
- if manager is None:
- max_open_warning = rcParams['figure.max_open_warning']
- if len(allnums) == max_open_warning >= 1:
- _api.warn_external(
- f"More than {max_open_warning} figures have been opened. "
- f"Figures created through the pyplot interface "
- f"(`matplotlib.pyplot.figure`) are retained until explicitly "
- f"closed and may consume too much memory. (To control this "
- f"warning, see the rcParam `figure.max_open_warning`). "
- f"Consider using `matplotlib.pyplot.close()`.",
- RuntimeWarning)
-
- manager = new_figure_manager(
- num, figsize=figsize, dpi=dpi,
- facecolor=facecolor, edgecolor=edgecolor, frameon=frameon,
- FigureClass=FigureClass, **kwargs)
- fig = manager.canvas.figure
- if fig_label:
- fig.set_label(fig_label)
-
- for hookspecs in rcParams["figure.hooks"]:
- module_name, dotted_name = hookspecs.split(":")
- obj: Any = importlib.import_module(module_name)
- for part in dotted_name.split("."):
- obj = getattr(obj, part)
- obj(fig)
-
- _pylab_helpers.Gcf._set_new_active_manager(manager)
-
- # make sure backends (inline) that we don't ship that expect this
- # to be called in plotting commands to make the figure call show
- # still work. There is probably a better way to do this in the
- # FigureManager base class.
- draw_if_interactive()
-
- if _REPL_DISPLAYHOOK is _ReplDisplayHook.PLAIN:
- fig.stale_callback = _auto_draw_if_interactive
-
- if clear:
- manager.canvas.figure.clear()
-
- return manager.canvas.figure
-
-
-def _auto_draw_if_interactive(fig, val):
- """
- An internal helper function for making sure that auto-redrawing
- works as intended in the plain python repl.
-
- Parameters
- ----------
- fig : Figure
- A figure object which is assumed to be associated with a canvas
- """
- if (val and matplotlib.is_interactive()
- and not fig.canvas.is_saving()
- and not fig.canvas._is_idle_drawing):
- # Some artists can mark themselves as stale in the middle of drawing
- # (e.g. axes position & tick labels being computed at draw time), but
- # this shouldn't trigger a redraw because the current redraw will
- # already take them into account.
- with fig.canvas._idle_draw_cntx():
- fig.canvas.draw_idle()
-
-
-def gcf() -> Figure:
- """
- Get the current figure.
-
- If there is currently no figure on the pyplot figure stack, a new one is
- created using `~.pyplot.figure()`. (To test whether there is currently a
- figure on the pyplot figure stack, check whether `~.pyplot.get_fignums()`
- is empty.)
- """
- manager = _pylab_helpers.Gcf.get_active()
- if manager is not None:
- return manager.canvas.figure
- else:
- return figure()
-
-
-def fignum_exists(num: int) -> bool:
- """Return whether the figure with the given id exists."""
- return _pylab_helpers.Gcf.has_fignum(num) or num in get_figlabels()
-
-
-def get_fignums() -> list[int]:
- """Return a list of existing figure numbers."""
- return sorted(_pylab_helpers.Gcf.figs)
-
-
-def get_figlabels() -> list[Any]:
- """Return a list of existing figure labels."""
- managers = _pylab_helpers.Gcf.get_all_fig_managers()
- managers.sort(key=lambda m: m.num)
- return [m.canvas.figure.get_label() for m in managers]
-
-
-def get_current_fig_manager() -> FigureManagerBase | None:
- """
- Return the figure manager of the current figure.
-
- The figure manager is a container for the actual backend-depended window
- that displays the figure on screen.
-
- If no current figure exists, a new one is created, and its figure
- manager is returned.
-
- Returns
- -------
- `.FigureManagerBase` or backend-dependent subclass thereof
- """
- return gcf().canvas.manager
-
-
-@_copy_docstring_and_deprecators(FigureCanvasBase.mpl_connect)
-def connect(s: str, func: Callable[[Event], Any]) -> int:
- return gcf().canvas.mpl_connect(s, func)
-
-
-@_copy_docstring_and_deprecators(FigureCanvasBase.mpl_disconnect)
-def disconnect(cid: int) -> None:
- gcf().canvas.mpl_disconnect(cid)
-
-
-def close(fig: None | int | str | Figure | Literal["all"] = None) -> None:
- """
- Close a figure window.
-
- Parameters
- ----------
- fig : None or int or str or `.Figure`
- The figure to close. There are a number of ways to specify this:
-
- - *None*: the current figure
- - `.Figure`: the given `.Figure` instance
- - ``int``: a figure number
- - ``str``: a figure name
- - 'all': all figures
-
- """
- if fig is None:
- manager = _pylab_helpers.Gcf.get_active()
- if manager is None:
- return
- else:
- _pylab_helpers.Gcf.destroy(manager)
- elif fig == 'all':
- _pylab_helpers.Gcf.destroy_all()
- elif isinstance(fig, int):
- _pylab_helpers.Gcf.destroy(fig)
- elif hasattr(fig, 'int'):
- # if we are dealing with a type UUID, we
- # can use its integer representation
- _pylab_helpers.Gcf.destroy(fig.int)
- elif isinstance(fig, str):
- all_labels = get_figlabels()
- if fig in all_labels:
- num = get_fignums()[all_labels.index(fig)]
- _pylab_helpers.Gcf.destroy(num)
- elif isinstance(fig, Figure):
- _pylab_helpers.Gcf.destroy_fig(fig)
- else:
- raise TypeError("close() argument must be a Figure, an int, a string, "
- "or None, not %s" % type(fig))
-
-
-def clf() -> None:
- """Clear the current figure."""
- gcf().clear()
-
-
-def draw() -> None:
- """
- Redraw the current figure.
-
- This is used to update a figure that has been altered, but not
- automatically re-drawn. If interactive mode is on (via `.ion()`), this
- should be only rarely needed, but there may be ways to modify the state of
- a figure without marking it as "stale". Please report these cases as bugs.
-
- This is equivalent to calling ``fig.canvas.draw_idle()``, where ``fig`` is
- the current figure.
-
- See Also
- --------
- .FigureCanvasBase.draw_idle
- .FigureCanvasBase.draw
- """
- gcf().canvas.draw_idle()
-
-
-@_copy_docstring_and_deprecators(Figure.savefig)
-def savefig(*args, **kwargs) -> None:
- fig = gcf()
- # savefig default implementation has no return, so mypy is unhappy
- # presumably this is here because subclasses can return?
- res = fig.savefig(*args, **kwargs) # type: ignore[func-returns-value]
- fig.canvas.draw_idle() # Need this if 'transparent=True', to reset colors.
- return res
-
-
-## Putting things in figures ##
-
-
-def figlegend(*args, **kwargs) -> Legend:
- return gcf().legend(*args, **kwargs)
-if Figure.legend.__doc__:
- figlegend.__doc__ = Figure.legend.__doc__ \
- .replace(" legend(", " figlegend(") \
- .replace("fig.legend(", "plt.figlegend(") \
- .replace("ax.plot(", "plt.plot(")
-
-
-## Axes ##
-
-@_docstring.dedent_interpd
-def axes(
- arg: None | tuple[float, float, float, float] = None,
- **kwargs
-) -> matplotlib.axes.Axes:
- """
- Add an Axes to the current figure and make it the current Axes.
-
- Call signatures::
-
- plt.axes()
- plt.axes(rect, projection=None, polar=False, **kwargs)
- plt.axes(ax)
-
- Parameters
- ----------
- arg : None or 4-tuple
- The exact behavior of this function depends on the type:
-
- - *None*: A new full window Axes is added using
- ``subplot(**kwargs)``.
- - 4-tuple of floats *rect* = ``(left, bottom, width, height)``.
- A new Axes is added with dimensions *rect* in normalized
- (0, 1) units using `~.Figure.add_axes` on the current figure.
-
- projection : {None, 'aitoff', 'hammer', 'lambert', 'mollweide', \
-'polar', 'rectilinear', str}, optional
- The projection type of the `~.axes.Axes`. *str* is the name of
- a custom projection, see `~matplotlib.projections`. The default
- None results in a 'rectilinear' projection.
-
- polar : bool, default: False
- If True, equivalent to projection='polar'.
-
- sharex, sharey : `~matplotlib.axes.Axes`, optional
- Share the x or y `~matplotlib.axis` with sharex and/or sharey.
- The axis will have the same limits, ticks, and scale as the axis
- of the shared Axes.
-
- label : str
- A label for the returned Axes.
-
- Returns
- -------
- `~.axes.Axes`, or a subclass of `~.axes.Axes`
- The returned axes class depends on the projection used. It is
- `~.axes.Axes` if rectilinear projection is used and
- `.projections.polar.PolarAxes` if polar projection is used.
-
- Other Parameters
- ----------------
- **kwargs
- This method also takes the keyword arguments for
- the returned Axes class. The keyword arguments for the
- rectilinear Axes class `~.axes.Axes` can be found in
- the following table but there might also be other keyword
- arguments if another projection is used, see the actual Axes
- class.
-
- %(Axes:kwdoc)s
-
- See Also
- --------
- .Figure.add_axes
- .pyplot.subplot
- .Figure.add_subplot
- .Figure.subplots
- .pyplot.subplots
-
- Examples
- --------
- ::
-
- # Creating a new full window Axes
- plt.axes()
-
- # Creating a new Axes with specified dimensions and a grey background
- plt.axes((left, bottom, width, height), facecolor='grey')
- """
- fig = gcf()
- pos = kwargs.pop('position', None)
- if arg is None:
- if pos is None:
- return fig.add_subplot(**kwargs)
- else:
- return fig.add_axes(pos, **kwargs)
- else:
- return fig.add_axes(arg, **kwargs)
-
-
-def delaxes(ax: matplotlib.axes.Axes | None = None) -> None:
- """
- Remove an `~.axes.Axes` (defaulting to the current axes) from its figure.
- """
- if ax is None:
- ax = gca()
- ax.remove()
-
-
-def sca(ax: Axes) -> None:
- """
- Set the current Axes to *ax* and the current Figure to the parent of *ax*.
- """
- # Mypy sees ax.figure as potentially None,
- # but if you are calling this, it won't be None
- # Additionally the slight difference between `Figure` and `FigureBase` mypy catches
- figure(ax.figure) # type: ignore[arg-type]
- ax.figure.sca(ax) # type: ignore[union-attr]
-
-
-def cla() -> None:
- """Clear the current axes."""
- # Not generated via boilerplate.py to allow a different docstring.
- return gca().cla()
-
-
-## More ways of creating axes ##
-
-@_docstring.dedent_interpd
-def subplot(*args, **kwargs) -> Axes:
- """
- Add an Axes to the current figure or retrieve an existing Axes.
-
- This is a wrapper of `.Figure.add_subplot` which provides additional
- behavior when working with the implicit API (see the notes section).
-
- Call signatures::
-
- subplot(nrows, ncols, index, **kwargs)
- subplot(pos, **kwargs)
- subplot(**kwargs)
- subplot(ax)
-
- Parameters
- ----------
- *args : int, (int, int, *index*), or `.SubplotSpec`, default: (1, 1, 1)
- The position of the subplot described by one of
-
- - Three integers (*nrows*, *ncols*, *index*). The subplot will take the
- *index* position on a grid with *nrows* rows and *ncols* columns.
- *index* starts at 1 in the upper left corner and increases to the
- right. *index* can also be a two-tuple specifying the (*first*,
- *last*) indices (1-based, and including *last*) of the subplot, e.g.,
- ``fig.add_subplot(3, 1, (1, 2))`` makes a subplot that spans the
- upper 2/3 of the figure.
- - A 3-digit integer. The digits are interpreted as if given separately
- as three single-digit integers, i.e. ``fig.add_subplot(235)`` is the
- same as ``fig.add_subplot(2, 3, 5)``. Note that this can only be used
- if there are no more than 9 subplots.
- - A `.SubplotSpec`.
-
- projection : {None, 'aitoff', 'hammer', 'lambert', 'mollweide', \
-'polar', 'rectilinear', str}, optional
- The projection type of the subplot (`~.axes.Axes`). *str* is the name
- of a custom projection, see `~matplotlib.projections`. The default
- None results in a 'rectilinear' projection.
-
- polar : bool, default: False
- If True, equivalent to projection='polar'.
-
- sharex, sharey : `~matplotlib.axes.Axes`, optional
- Share the x or y `~matplotlib.axis` with sharex and/or sharey. The
- axis will have the same limits, ticks, and scale as the axis of the
- shared axes.
-
- label : str
- A label for the returned axes.
-
- Returns
- -------
- `~.axes.Axes`
-
- The Axes of the subplot. The returned Axes can actually be an instance
- of a subclass, such as `.projections.polar.PolarAxes` for polar
- projections.
-
- Other Parameters
- ----------------
- **kwargs
- This method also takes the keyword arguments for the returned axes
- base class; except for the *figure* argument. The keyword arguments
- for the rectilinear base class `~.axes.Axes` can be found in
- the following table but there might also be other keyword
- arguments if another projection is used.
-
- %(Axes:kwdoc)s
-
- Notes
- -----
- Creating a new Axes will delete any preexisting Axes that
- overlaps with it beyond sharing a boundary::
-
- import matplotlib.pyplot as plt
- # plot a line, implicitly creating a subplot(111)
- plt.plot([1, 2, 3])
- # now create a subplot which represents the top plot of a grid
- # with 2 rows and 1 column. Since this subplot will overlap the
- # first, the plot (and its axes) previously created, will be removed
- plt.subplot(211)
-
- If you do not want this behavior, use the `.Figure.add_subplot` method
- or the `.pyplot.axes` function instead.
-
- If no *kwargs* are passed and there exists an Axes in the location
- specified by *args* then that Axes will be returned rather than a new
- Axes being created.
-
- If *kwargs* are passed and there exists an Axes in the location
- specified by *args*, the projection type is the same, and the
- *kwargs* match with the existing Axes, then the existing Axes is
- returned. Otherwise a new Axes is created with the specified
- parameters. We save a reference to the *kwargs* which we use
- for this comparison. If any of the values in *kwargs* are
- mutable we will not detect the case where they are mutated.
- In these cases we suggest using `.Figure.add_subplot` and the
- explicit Axes API rather than the implicit pyplot API.
-
- See Also
- --------
- .Figure.add_subplot
- .pyplot.subplots
- .pyplot.axes
- .Figure.subplots
-
- Examples
- --------
- ::
-
- plt.subplot(221)
-
- # equivalent but more general
- ax1 = plt.subplot(2, 2, 1)
-
- # add a subplot with no frame
- ax2 = plt.subplot(222, frameon=False)
-
- # add a polar subplot
- plt.subplot(223, projection='polar')
-
- # add a red subplot that shares the x-axis with ax1
- plt.subplot(224, sharex=ax1, facecolor='red')
-
- # delete ax2 from the figure
- plt.delaxes(ax2)
-
- # add ax2 to the figure again
- plt.subplot(ax2)
-
- # make the first axes "current" again
- plt.subplot(221)
-
- """
- # Here we will only normalize `polar=True` vs `projection='polar'` and let
- # downstream code deal with the rest.
- unset = object()
- projection = kwargs.get('projection', unset)
- polar = kwargs.pop('polar', unset)
- if polar is not unset and polar:
- # if we got mixed messages from the user, raise
- if projection is not unset and projection != 'polar':
- raise ValueError(
- f"polar={polar}, yet projection={projection!r}. "
- "Only one of these arguments should be supplied."
- )
- kwargs['projection'] = projection = 'polar'
-
- # if subplot called without arguments, create subplot(1, 1, 1)
- if len(args) == 0:
- args = (1, 1, 1)
-
- # This check was added because it is very easy to type subplot(1, 2, False)
- # when subplots(1, 2, False) was intended (sharex=False, that is). In most
- # cases, no error will ever occur, but mysterious behavior can result
- # because what was intended to be the sharex argument is instead treated as
- # a subplot index for subplot()
- if len(args) >= 3 and isinstance(args[2], bool):
- _api.warn_external("The subplot index argument to subplot() appears "
- "to be a boolean. Did you intend to use "
- "subplots()?")
- # Check for nrows and ncols, which are not valid subplot args:
- if 'nrows' in kwargs or 'ncols' in kwargs:
- raise TypeError("subplot() got an unexpected keyword argument 'ncols' "
- "and/or 'nrows'. Did you intend to call subplots()?")
-
- fig = gcf()
-
- # First, search for an existing subplot with a matching spec.
- key = SubplotSpec._from_subplot_args(fig, args)
-
- for ax in fig.axes:
- # If we found an Axes at the position, we can re-use it if the user passed no
- # kwargs or if the axes class and kwargs are identical.
- if (ax.get_subplotspec() == key
- and (kwargs == {}
- or (ax._projection_init
- == fig._process_projection_requirements(**kwargs)))):
- break
- else:
- # we have exhausted the known Axes and none match, make a new one!
- ax = fig.add_subplot(*args, **kwargs)
-
- fig.sca(ax)
-
- return ax
-
-
-def subplots(
- nrows: int = 1, ncols: int = 1, *,
- sharex: bool | Literal["none", "all", "row", "col"] = False,
- sharey: bool | Literal["none", "all", "row", "col"] = False,
- squeeze: bool = True,
- width_ratios: Sequence[float] | None = None,
- height_ratios: Sequence[float] | None = None,
- subplot_kw: dict[str, Any] | None = None,
- gridspec_kw: dict[str, Any] | None = None,
- **fig_kw
-) -> tuple[Figure, Any]:
- """
- Create a figure and a set of subplots.
-
- This utility wrapper makes it convenient to create common layouts of
- subplots, including the enclosing figure object, in a single call.
-
- Parameters
- ----------
- nrows, ncols : int, default: 1
- Number of rows/columns of the subplot grid.
-
- sharex, sharey : bool or {'none', 'all', 'row', 'col'}, default: False
- Controls sharing of properties among x (*sharex*) or y (*sharey*)
- axes:
-
- - True or 'all': x- or y-axis will be shared among all subplots.
- - False or 'none': each subplot x- or y-axis will be independent.
- - 'row': each subplot row will share an x- or y-axis.
- - 'col': each subplot column will share an x- or y-axis.
-
- When subplots have a shared x-axis along a column, only the x tick
- labels of the bottom subplot are created. Similarly, when subplots
- have a shared y-axis along a row, only the y tick labels of the first
- column subplot are created. To later turn other subplots' ticklabels
- on, use `~matplotlib.axes.Axes.tick_params`.
-
- When subplots have a shared axis that has units, calling
- `~matplotlib.axis.Axis.set_units` will update each axis with the
- new units.
-
- squeeze : bool, default: True
- - If True, extra dimensions are squeezed out from the returned
- array of `~matplotlib.axes.Axes`:
-
- - if only one subplot is constructed (nrows=ncols=1), the
- resulting single Axes object is returned as a scalar.
- - for Nx1 or 1xM subplots, the returned object is a 1D numpy
- object array of Axes objects.
- - for NxM, subplots with N>1 and M>1 are returned as a 2D array.
-
- - If False, no squeezing at all is done: the returned Axes object is
- always a 2D array containing Axes instances, even if it ends up
- being 1x1.
-
- width_ratios : array-like of length *ncols*, optional
- Defines the relative widths of the columns. Each column gets a
- relative width of ``width_ratios[i] / sum(width_ratios)``.
- If not given, all columns will have the same width. Equivalent
- to ``gridspec_kw={'width_ratios': [...]}``.
-
- height_ratios : array-like of length *nrows*, optional
- Defines the relative heights of the rows. Each row gets a
- relative height of ``height_ratios[i] / sum(height_ratios)``.
- If not given, all rows will have the same height. Convenience
- for ``gridspec_kw={'height_ratios': [...]}``.
-
- subplot_kw : dict, optional
- Dict with keywords passed to the
- `~matplotlib.figure.Figure.add_subplot` call used to create each
- subplot.
-
- gridspec_kw : dict, optional
- Dict with keywords passed to the `~matplotlib.gridspec.GridSpec`
- constructor used to create the grid the subplots are placed on.
-
- **fig_kw
- All additional keyword arguments are passed to the
- `.pyplot.figure` call.
-
- Returns
- -------
- fig : `.Figure`
-
- ax : `~matplotlib.axes.Axes` or array of Axes
- *ax* can be either a single `~.axes.Axes` object, or an array of Axes
- objects if more than one subplot was created. The dimensions of the
- resulting array can be controlled with the squeeze keyword, see above.
-
- Typical idioms for handling the return value are::
-
- # using the variable ax for single a Axes
- fig, ax = plt.subplots()
-
- # using the variable axs for multiple Axes
- fig, axs = plt.subplots(2, 2)
-
- # using tuple unpacking for multiple Axes
- fig, (ax1, ax2) = plt.subplots(1, 2)
- fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
-
- The names ``ax`` and pluralized ``axs`` are preferred over ``axes``
- because for the latter it's not clear if it refers to a single
- `~.axes.Axes` instance or a collection of these.
-
- See Also
- --------
- .pyplot.figure
- .pyplot.subplot
- .pyplot.axes
- .Figure.subplots
- .Figure.add_subplot
-
- Examples
- --------
- ::
-
- # First create some toy data:
- x = np.linspace(0, 2*np.pi, 400)
- y = np.sin(x**2)
-
- # Create just a figure and only one subplot
- fig, ax = plt.subplots()
- ax.plot(x, y)
- ax.set_title('Simple plot')
-
- # Create two subplots and unpack the output array immediately
- f, (ax1, ax2) = plt.subplots(1, 2, sharey=True)
- ax1.plot(x, y)
- ax1.set_title('Sharing Y axis')
- ax2.scatter(x, y)
-
- # Create four polar axes and access them through the returned array
- fig, axs = plt.subplots(2, 2, subplot_kw=dict(projection="polar"))
- axs[0, 0].plot(x, y)
- axs[1, 1].scatter(x, y)
-
- # Share a X axis with each column of subplots
- plt.subplots(2, 2, sharex='col')
-
- # Share a Y axis with each row of subplots
- plt.subplots(2, 2, sharey='row')
-
- # Share both X and Y axes with all subplots
- plt.subplots(2, 2, sharex='all', sharey='all')
-
- # Note that this is the same as
- plt.subplots(2, 2, sharex=True, sharey=True)
-
- # Create figure number 10 with a single subplot
- # and clears it if it already exists.
- fig, ax = plt.subplots(num=10, clear=True)
-
- """
- fig = figure(**fig_kw)
- axs = fig.subplots(nrows=nrows, ncols=ncols, sharex=sharex, sharey=sharey,
- squeeze=squeeze, subplot_kw=subplot_kw,
- gridspec_kw=gridspec_kw, height_ratios=height_ratios,
- width_ratios=width_ratios)
- return fig, axs
-
-
-@overload
-def subplot_mosaic(
- mosaic: str,
- *,
- sharex: bool = ...,
- sharey: bool = ...,
- width_ratios: ArrayLike | None = ...,
- height_ratios: ArrayLike | None = ...,
- empty_sentinel: str = ...,
- subplot_kw: dict[str, Any] | None = ...,
- gridspec_kw: dict[str, Any] | None = ...,
- per_subplot_kw: dict[str | tuple[str, ...], dict[str, Any]] | None = ...,
- **fig_kw: Any
-) -> tuple[Figure, dict[str, matplotlib.axes.Axes]]: ...
-
-
-@overload
-def subplot_mosaic(
- mosaic: list[HashableList[_T]],
- *,
- sharex: bool = ...,
- sharey: bool = ...,
- width_ratios: ArrayLike | None = ...,
- height_ratios: ArrayLike | None = ...,
- empty_sentinel: _T = ...,
- subplot_kw: dict[str, Any] | None = ...,
- gridspec_kw: dict[str, Any] | None = ...,
- per_subplot_kw: dict[_T | tuple[_T, ...], dict[str, Any]] | None = ...,
- **fig_kw: Any
-) -> tuple[Figure, dict[_T, matplotlib.axes.Axes]]: ...
-
-
-@overload
-def subplot_mosaic(
- mosaic: list[HashableList[Hashable]],
- *,
- sharex: bool = ...,
- sharey: bool = ...,
- width_ratios: ArrayLike | None = ...,
- height_ratios: ArrayLike | None = ...,
- empty_sentinel: Any = ...,
- subplot_kw: dict[str, Any] | None = ...,
- gridspec_kw: dict[str, Any] | None = ...,
- per_subplot_kw: dict[Hashable | tuple[Hashable, ...], dict[str, Any]] | None = ...,
- **fig_kw: Any
-) -> tuple[Figure, dict[Hashable, matplotlib.axes.Axes]]: ...
-
-
-def subplot_mosaic(
- mosaic: str | list[HashableList[_T]] | list[HashableList[Hashable]],
- *,
- sharex: bool = False,
- sharey: bool = False,
- width_ratios: ArrayLike | None = None,
- height_ratios: ArrayLike | None = None,
- empty_sentinel: Any = '.',
- subplot_kw: dict[str, Any] | None = None,
- gridspec_kw: dict[str, Any] | None = None,
- per_subplot_kw: dict[str | tuple[str, ...], dict[str, Any]] |
- dict[_T | tuple[_T, ...], dict[str, Any]] |
- dict[Hashable | tuple[Hashable, ...], dict[str, Any]] | None = None,
- **fig_kw: Any
-) -> tuple[Figure, dict[str, matplotlib.axes.Axes]] | \
- tuple[Figure, dict[_T, matplotlib.axes.Axes]] | \
- tuple[Figure, dict[Hashable, matplotlib.axes.Axes]]:
- """
- Build a layout of Axes based on ASCII art or nested lists.
-
- This is a helper function to build complex GridSpec layouts visually.
-
- See :ref:`mosaic`
- for an example and full API documentation
-
- Parameters
- ----------
- mosaic : list of list of {hashable or nested} or str
-
- A visual layout of how you want your Axes to be arranged
- labeled as strings. For example ::
-
- x = [['A panel', 'A panel', 'edge'],
- ['C panel', '.', 'edge']]
-
- produces 4 axes:
-
- - 'A panel' which is 1 row high and spans the first two columns
- - 'edge' which is 2 rows high and is on the right edge
- - 'C panel' which in 1 row and 1 column wide in the bottom left
- - a blank space 1 row and 1 column wide in the bottom center
-
- Any of the entries in the layout can be a list of lists
- of the same form to create nested layouts.
-
- If input is a str, then it must be of the form ::
-
- '''
- AAE
- C.E
- '''
-
- where each character is a column and each line is a row.
- This only allows only single character Axes labels and does
- not allow nesting but is very terse.
-
- sharex, sharey : bool, default: False
- If True, the x-axis (*sharex*) or y-axis (*sharey*) will be shared
- among all subplots. In that case, tick label visibility and axis units
- behave as for `subplots`. If False, each subplot's x- or y-axis will
- be independent.
-
- width_ratios : array-like of length *ncols*, optional
- Defines the relative widths of the columns. Each column gets a
- relative width of ``width_ratios[i] / sum(width_ratios)``.
- If not given, all columns will have the same width. Convenience
- for ``gridspec_kw={'width_ratios': [...]}``.
-
- height_ratios : array-like of length *nrows*, optional
- Defines the relative heights of the rows. Each row gets a
- relative height of ``height_ratios[i] / sum(height_ratios)``.
- If not given, all rows will have the same height. Convenience
- for ``gridspec_kw={'height_ratios': [...]}``.
-
- empty_sentinel : object, optional
- Entry in the layout to mean "leave this space empty". Defaults
- to ``'.'``. Note, if *layout* is a string, it is processed via
- `inspect.cleandoc` to remove leading white space, which may
- interfere with using white-space as the empty sentinel.
-
- subplot_kw : dict, optional
- Dictionary with keywords passed to the `.Figure.add_subplot` call
- used to create each subplot. These values may be overridden by
- values in *per_subplot_kw*.
-
- per_subplot_kw : dict, optional
- A dictionary mapping the Axes identifiers or tuples of identifiers
- to a dictionary of keyword arguments to be passed to the
- `.Figure.add_subplot` call used to create each subplot. The values
- in these dictionaries have precedence over the values in
- *subplot_kw*.
-
- If *mosaic* is a string, and thus all keys are single characters,
- it is possible to use a single string instead of a tuple as keys;
- i.e. ``"AB"`` is equivalent to ``("A", "B")``.
-
- .. versionadded:: 3.7
-
- gridspec_kw : dict, optional
- Dictionary with keywords passed to the `.GridSpec` constructor used
- to create the grid the subplots are placed on.
-
- **fig_kw
- All additional keyword arguments are passed to the
- `.pyplot.figure` call.
-
- Returns
- -------
- fig : `.Figure`
- The new figure
-
- dict[label, Axes]
- A dictionary mapping the labels to the Axes objects. The order of
- the axes is left-to-right and top-to-bottom of their position in the
- total layout.
-
- """
- fig = figure(**fig_kw)
- ax_dict = fig.subplot_mosaic( # type: ignore[misc]
- mosaic, # type: ignore[arg-type]
- sharex=sharex, sharey=sharey,
- height_ratios=height_ratios, width_ratios=width_ratios,
- subplot_kw=subplot_kw, gridspec_kw=gridspec_kw,
- empty_sentinel=empty_sentinel,
- per_subplot_kw=per_subplot_kw, # type: ignore[arg-type]
- )
- return fig, ax_dict
-
-
-def subplot2grid(
- shape: tuple[int, int], loc: tuple[int, int],
- rowspan: int = 1, colspan: int = 1,
- fig: Figure | None = None,
- **kwargs
-) -> matplotlib.axes.Axes:
- """
- Create a subplot at a specific location inside a regular grid.
-
- Parameters
- ----------
- shape : (int, int)
- Number of rows and of columns of the grid in which to place axis.
- loc : (int, int)
- Row number and column number of the axis location within the grid.
- rowspan : int, default: 1
- Number of rows for the axis to span downwards.
- colspan : int, default: 1
- Number of columns for the axis to span to the right.
- fig : `.Figure`, optional
- Figure to place the subplot in. Defaults to the current figure.
- **kwargs
- Additional keyword arguments are handed to `~.Figure.add_subplot`.
-
- Returns
- -------
- `~.axes.Axes`
-
- The Axes of the subplot. The returned Axes can actually be an instance
- of a subclass, such as `.projections.polar.PolarAxes` for polar
- projections.
-
- Notes
- -----
- The following call ::
-
- ax = subplot2grid((nrows, ncols), (row, col), rowspan, colspan)
-
- is identical to ::
-
- fig = gcf()
- gs = fig.add_gridspec(nrows, ncols)
- ax = fig.add_subplot(gs[row:row+rowspan, col:col+colspan])
- """
- if fig is None:
- fig = gcf()
- rows, cols = shape
- gs = GridSpec._check_gridspec_exists(fig, rows, cols)
- subplotspec = gs.new_subplotspec(loc, rowspan=rowspan, colspan=colspan)
- return fig.add_subplot(subplotspec, **kwargs)
-
-
-def twinx(ax: matplotlib.axes.Axes | None = None) -> _AxesBase:
- """
- Make and return a second axes that shares the *x*-axis. The new axes will
- overlay *ax* (or the current axes if *ax* is *None*), and its ticks will be
- on the right.
-
- Examples
- --------
- :doc:`/gallery/subplots_axes_and_figures/two_scales`
- """
- if ax is None:
- ax = gca()
- ax1 = ax.twinx()
- return ax1
-
-
-def twiny(ax: matplotlib.axes.Axes | None = None) -> _AxesBase:
- """
- Make and return a second axes that shares the *y*-axis. The new axes will
- overlay *ax* (or the current axes if *ax* is *None*), and its ticks will be
- on the top.
-
- Examples
- --------
- :doc:`/gallery/subplots_axes_and_figures/two_scales`
- """
- if ax is None:
- ax = gca()
- ax1 = ax.twiny()
- return ax1
-
-
-def subplot_tool(targetfig: Figure | None = None) -> SubplotTool | None:
- """
- Launch a subplot tool window for a figure.
-
- Returns
- -------
- `matplotlib.widgets.SubplotTool`
- """
- if targetfig is None:
- targetfig = gcf()
- tb = targetfig.canvas.manager.toolbar # type: ignore[union-attr]
- if hasattr(tb, "configure_subplots"): # toolbar2
- from matplotlib.backend_bases import NavigationToolbar2
- return cast(NavigationToolbar2, tb).configure_subplots()
- elif hasattr(tb, "trigger_tool"): # toolmanager
- from matplotlib.backend_bases import ToolContainerBase
- cast(ToolContainerBase, tb).trigger_tool("subplots")
- return None
- else:
- raise ValueError("subplot_tool can only be launched for figures with "
- "an associated toolbar")
-
-
-def box(on: bool | None = None) -> None:
- """
- Turn the axes box on or off on the current axes.
-
- Parameters
- ----------
- on : bool or None
- The new `~matplotlib.axes.Axes` box state. If ``None``, toggle
- the state.
-
- See Also
- --------
- :meth:`matplotlib.axes.Axes.set_frame_on`
- :meth:`matplotlib.axes.Axes.get_frame_on`
- """
- ax = gca()
- if on is None:
- on = not ax.get_frame_on()
- ax.set_frame_on(on)
-
-## Axis ##
-
-
-def xlim(*args, **kwargs) -> tuple[float, float]:
- """
- Get or set the x limits of the current axes.
-
- Call signatures::
-
- left, right = xlim() # return the current xlim
- xlim((left, right)) # set the xlim to left, right
- xlim(left, right) # set the xlim to left, right
-
- If you do not specify args, you can pass *left* or *right* as kwargs,
- i.e.::
-
- xlim(right=3) # adjust the right leaving left unchanged
- xlim(left=1) # adjust the left leaving right unchanged
-
- Setting limits turns autoscaling off for the x-axis.
-
- Returns
- -------
- left, right
- A tuple of the new x-axis limits.
-
- Notes
- -----
- Calling this function with no arguments (e.g. ``xlim()``) is the pyplot
- equivalent of calling `~.Axes.get_xlim` on the current axes.
- Calling this function with arguments is the pyplot equivalent of calling
- `~.Axes.set_xlim` on the current axes. All arguments are passed though.
- """
- ax = gca()
- if not args and not kwargs:
- return ax.get_xlim()
- ret = ax.set_xlim(*args, **kwargs)
- return ret
-
-
-def ylim(*args, **kwargs) -> tuple[float, float]:
- """
- Get or set the y-limits of the current axes.
-
- Call signatures::
-
- bottom, top = ylim() # return the current ylim
- ylim((bottom, top)) # set the ylim to bottom, top
- ylim(bottom, top) # set the ylim to bottom, top
-
- If you do not specify args, you can alternatively pass *bottom* or
- *top* as kwargs, i.e.::
-
- ylim(top=3) # adjust the top leaving bottom unchanged
- ylim(bottom=1) # adjust the bottom leaving top unchanged
-
- Setting limits turns autoscaling off for the y-axis.
-
- Returns
- -------
- bottom, top
- A tuple of the new y-axis limits.
-
- Notes
- -----
- Calling this function with no arguments (e.g. ``ylim()``) is the pyplot
- equivalent of calling `~.Axes.get_ylim` on the current axes.
- Calling this function with arguments is the pyplot equivalent of calling
- `~.Axes.set_ylim` on the current axes. All arguments are passed though.
- """
- ax = gca()
- if not args and not kwargs:
- return ax.get_ylim()
- ret = ax.set_ylim(*args, **kwargs)
- return ret
-
-
-def xticks(
- ticks: ArrayLike | None = None,
- labels: Sequence[str] | None = None,
- *,
- minor: bool = False,
- **kwargs
-) -> tuple[list[Tick] | np.ndarray, list[Text]]:
- """
- Get or set the current tick locations and labels of the x-axis.
-
- Pass no arguments to return the current values without modifying them.
-
- Parameters
- ----------
- ticks : array-like, optional
- The list of xtick locations. Passing an empty list removes all xticks.
- labels : array-like, optional
- The labels to place at the given *ticks* locations. This argument can
- only be passed if *ticks* is passed as well.
- minor : bool, default: False
- If ``False``, get/set the major ticks/labels; if ``True``, the minor
- ticks/labels.
- **kwargs
- `.Text` properties can be used to control the appearance of the labels.
-
- Returns
- -------
- locs
- The list of xtick locations.
- labels
- The list of xlabel `.Text` objects.
-
- Notes
- -----
- Calling this function with no arguments (e.g. ``xticks()``) is the pyplot
- equivalent of calling `~.Axes.get_xticks` and `~.Axes.get_xticklabels` on
- the current axes.
- Calling this function with arguments is the pyplot equivalent of calling
- `~.Axes.set_xticks` and `~.Axes.set_xticklabels` on the current axes.
-
- Examples
- --------
- >>> locs, labels = xticks() # Get the current locations and labels.
- >>> xticks(np.arange(0, 1, step=0.2)) # Set label locations.
- >>> xticks(np.arange(3), ['Tom', 'Dick', 'Sue']) # Set text labels.
- >>> xticks([0, 1, 2], ['January', 'February', 'March'],
- ... rotation=20) # Set text labels and properties.
- >>> xticks([]) # Disable xticks.
- """
- ax = gca()
-
- locs: list[Tick] | np.ndarray
- if ticks is None:
- locs = ax.get_xticks(minor=minor)
- if labels is not None:
- raise TypeError("xticks(): Parameter 'labels' can't be set "
- "without setting 'ticks'")
- else:
- locs = ax.set_xticks(ticks, minor=minor)
-
- labels_out: list[Text] = []
- if labels is None:
- labels_out = ax.get_xticklabels(minor=minor)
- for l in labels_out:
- l._internal_update(kwargs)
- else:
- labels_out = ax.set_xticklabels(labels, minor=minor, **kwargs)
-
- return locs, labels_out
-
-
-def yticks(
- ticks: ArrayLike | None = None,
- labels: Sequence[str] | None = None,
- *,
- minor: bool = False,
- **kwargs
-) -> tuple[list[Tick] | np.ndarray, list[Text]]:
- """
- Get or set the current tick locations and labels of the y-axis.
-
- Pass no arguments to return the current values without modifying them.
-
- Parameters
- ----------
- ticks : array-like, optional
- The list of ytick locations. Passing an empty list removes all yticks.
- labels : array-like, optional
- The labels to place at the given *ticks* locations. This argument can
- only be passed if *ticks* is passed as well.
- minor : bool, default: False
- If ``False``, get/set the major ticks/labels; if ``True``, the minor
- ticks/labels.
- **kwargs
- `.Text` properties can be used to control the appearance of the labels.
-
- Returns
- -------
- locs
- The list of ytick locations.
- labels
- The list of ylabel `.Text` objects.
-
- Notes
- -----
- Calling this function with no arguments (e.g. ``yticks()``) is the pyplot
- equivalent of calling `~.Axes.get_yticks` and `~.Axes.get_yticklabels` on
- the current axes.
- Calling this function with arguments is the pyplot equivalent of calling
- `~.Axes.set_yticks` and `~.Axes.set_yticklabels` on the current axes.
-
- Examples
- --------
- >>> locs, labels = yticks() # Get the current locations and labels.
- >>> yticks(np.arange(0, 1, step=0.2)) # Set label locations.
- >>> yticks(np.arange(3), ['Tom', 'Dick', 'Sue']) # Set text labels.
- >>> yticks([0, 1, 2], ['January', 'February', 'March'],
- ... rotation=45) # Set text labels and properties.
- >>> yticks([]) # Disable yticks.
- """
- ax = gca()
-
- locs: list[Tick] | np.ndarray
- if ticks is None:
- locs = ax.get_yticks(minor=minor)
- if labels is not None:
- raise TypeError("yticks(): Parameter 'labels' can't be set "
- "without setting 'ticks'")
- else:
- locs = ax.set_yticks(ticks, minor=minor)
-
- labels_out: list[Text] = []
- if labels is None:
- labels_out = ax.get_yticklabels(minor=minor)
- for l in labels_out:
- l._internal_update(kwargs)
- else:
- labels_out = ax.set_yticklabels(labels, minor=minor, **kwargs)
-
- return locs, labels_out
-
-
-def rgrids(
- radii: ArrayLike | None = None,
- labels: Sequence[str | Text] | None = None,
- angle: float | None = None,
- fmt: str | None = None,
- **kwargs
-) -> tuple[list[Line2D], list[Text]]:
- """
- Get or set the radial gridlines on the current polar plot.
-
- Call signatures::
-
- lines, labels = rgrids()
- lines, labels = rgrids(radii, labels=None, angle=22.5, fmt=None, **kwargs)
-
- When called with no arguments, `.rgrids` simply returns the tuple
- (*lines*, *labels*). When called with arguments, the labels will
- appear at the specified radial distances and angle.
-
- Parameters
- ----------
- radii : tuple with floats
- The radii for the radial gridlines
-
- labels : tuple with strings or None
- The labels to use at each radial gridline. The
- `matplotlib.ticker.ScalarFormatter` will be used if None.
-
- angle : float
- The angular position of the radius labels in degrees.
-
- fmt : str or None
- Format string used in `matplotlib.ticker.FormatStrFormatter`.
- For example '%f'.
-
- Returns
- -------
- lines : list of `.lines.Line2D`
- The radial gridlines.
-
- labels : list of `.text.Text`
- The tick labels.
-
- Other Parameters
- ----------------
- **kwargs
- *kwargs* are optional `.Text` properties for the labels.
-
- See Also
- --------
- .pyplot.thetagrids
- .projections.polar.PolarAxes.set_rgrids
- .Axis.get_gridlines
- .Axis.get_ticklabels
-
- Examples
- --------
- ::
-
- # set the locations of the radial gridlines
- lines, labels = rgrids( (0.25, 0.5, 1.0) )
-
- # set the locations and labels of the radial gridlines
- lines, labels = rgrids( (0.25, 0.5, 1.0), ('Tom', 'Dick', 'Harry' ))
- """
- ax = gca()
- if not isinstance(ax, PolarAxes):
- raise RuntimeError('rgrids only defined for polar axes')
- if all(p is None for p in [radii, labels, angle, fmt]) and not kwargs:
- lines_out: list[Line2D] = ax.yaxis.get_gridlines()
- labels_out: list[Text] = ax.yaxis.get_ticklabels()
- elif radii is None:
- raise TypeError("'radii' cannot be None when other parameters are passed")
- else:
- lines_out, labels_out = ax.set_rgrids(
- radii, labels=labels, angle=angle, fmt=fmt, **kwargs)
- return lines_out, labels_out
-
-
-def thetagrids(
- angles: ArrayLike | None = None,
- labels: Sequence[str | Text] | None = None,
- fmt: str | None = None,
- **kwargs
-) -> tuple[list[Line2D], list[Text]]:
- """
- Get or set the theta gridlines on the current polar plot.
-
- Call signatures::
-
- lines, labels = thetagrids()
- lines, labels = thetagrids(angles, labels=None, fmt=None, **kwargs)
-
- When called with no arguments, `.thetagrids` simply returns the tuple
- (*lines*, *labels*). When called with arguments, the labels will
- appear at the specified angles.
-
- Parameters
- ----------
- angles : tuple with floats, degrees
- The angles of the theta gridlines.
-
- labels : tuple with strings or None
- The labels to use at each radial gridline. The
- `.projections.polar.ThetaFormatter` will be used if None.
-
- fmt : str or None
- Format string used in `matplotlib.ticker.FormatStrFormatter`.
- For example '%f'. Note that the angle in radians will be used.
-
- Returns
- -------
- lines : list of `.lines.Line2D`
- The theta gridlines.
-
- labels : list of `.text.Text`
- The tick labels.
-
- Other Parameters
- ----------------
- **kwargs
- *kwargs* are optional `.Text` properties for the labels.
-
- See Also
- --------
- .pyplot.rgrids
- .projections.polar.PolarAxes.set_thetagrids
- .Axis.get_gridlines
- .Axis.get_ticklabels
-
- Examples
- --------
- ::
-
- # set the locations of the angular gridlines
- lines, labels = thetagrids(range(45, 360, 90))
-
- # set the locations and labels of the angular gridlines
- lines, labels = thetagrids(range(45, 360, 90), ('NE', 'NW', 'SW', 'SE'))
- """
- ax = gca()
- if not isinstance(ax, PolarAxes):
- raise RuntimeError('thetagrids only defined for polar axes')
- if all(param is None for param in [angles, labels, fmt]) and not kwargs:
- lines_out: list[Line2D] = ax.xaxis.get_ticklines()
- labels_out: list[Text] = ax.xaxis.get_ticklabels()
- elif angles is None:
- raise TypeError("'angles' cannot be None when other parameters are passed")
- else:
- lines_out, labels_out = ax.set_thetagrids(angles,
- labels=labels, fmt=fmt,
- **kwargs)
- return lines_out, labels_out
-
-
-@_api.deprecated("3.7", pending=True)
-def get_plot_commands() -> list[str]:
- """
- Get a sorted list of all of the plotting commands.
- """
- NON_PLOT_COMMANDS = {
- 'connect', 'disconnect', 'get_current_fig_manager', 'ginput',
- 'new_figure_manager', 'waitforbuttonpress'}
- return [name for name in _get_pyplot_commands()
- if name not in NON_PLOT_COMMANDS]
-
-
-def _get_pyplot_commands() -> list[str]:
- # This works by searching for all functions in this module and removing
- # a few hard-coded exclusions, as well as all of the colormap-setting
- # functions, and anything marked as private with a preceding underscore.
- exclude = {'colormaps', 'colors', 'get_plot_commands', *colormaps}
- this_module = inspect.getmodule(get_plot_commands)
- return sorted(
- name for name, obj in globals().items()
- if not name.startswith('_') and name not in exclude
- and inspect.isfunction(obj)
- and inspect.getmodule(obj) is this_module)
-
-
-## Plotting part 1: manually generated functions and wrappers ##
-
-
-@_copy_docstring_and_deprecators(Figure.colorbar)
-def colorbar(
- mappable: ScalarMappable | None = None,
- cax: matplotlib.axes.Axes | None = None,
- ax: matplotlib.axes.Axes | Iterable[matplotlib.axes.Axes] | None = None,
- **kwargs
-) -> Colorbar:
- if mappable is None:
- mappable = gci()
- if mappable is None:
- raise RuntimeError('No mappable was found to use for colorbar '
- 'creation. First define a mappable such as '
- 'an image (with imshow) or a contour set ('
- 'with contourf).')
- ret = gcf().colorbar(mappable, cax=cax, ax=ax, **kwargs)
- return ret
-
-
-def clim(vmin: float | None = None, vmax: float | None = None) -> None:
- """
- Set the color limits of the current image.
-
- If either *vmin* or *vmax* is None, the image min/max respectively
- will be used for color scaling.
-
- If you want to set the clim of multiple images, use
- `~.ScalarMappable.set_clim` on every image, for example::
-
- for im in gca().get_images():
- im.set_clim(0, 0.5)
-
- """
- im = gci()
- if im is None:
- raise RuntimeError('You must first define an image, e.g., with imshow')
-
- im.set_clim(vmin, vmax)
-
-
-# eventually this implementation should move here, use indirection for now to
-# avoid having two copies of the code floating around.
-def get_cmap(
- name: Colormap | str | None = None,
- lut: int | None = None
-) -> Colormap:
- return cm._get_cmap(name=name, lut=lut) # type: ignore
-get_cmap.__doc__ = cm._get_cmap.__doc__ # type: ignore
-
-
-def set_cmap(cmap: Colormap | str) -> None:
- """
- Set the default colormap, and applies it to the current image if any.
-
- Parameters
- ----------
- cmap : `~matplotlib.colors.Colormap` or str
- A colormap instance or the name of a registered colormap.
-
- See Also
- --------
- colormaps
- matplotlib.cm.register_cmap
- matplotlib.cm.get_cmap
- """
- cmap = get_cmap(cmap)
-
- rc('image', cmap=cmap.name)
- im = gci()
-
- if im is not None:
- im.set_cmap(cmap)
-
-
-@_copy_docstring_and_deprecators(matplotlib.image.imread)
-def imread(
- fname: str | pathlib.Path | BinaryIO, format: str | None = None
-) -> np.ndarray:
- return matplotlib.image.imread(fname, format)
-
-
-@_copy_docstring_and_deprecators(matplotlib.image.imsave)
-def imsave(
- fname: str | os.PathLike | BinaryIO, arr: ArrayLike, **kwargs
-) -> None:
- matplotlib.image.imsave(fname, arr, **kwargs)
-
-
-def matshow(A: ArrayLike, fignum: None | int = None, **kwargs) -> AxesImage:
- """
- Display an array as a matrix in a new figure window.
-
- The origin is set at the upper left hand corner and rows (first
- dimension of the array) are displayed horizontally. The aspect
- ratio of the figure window is that of the array, unless this would
- make an excessively short or narrow figure.
-
- Tick labels for the xaxis are placed on top.
-
- Parameters
- ----------
- A : 2D array-like
- The matrix to be displayed.
-
- fignum : None or int
- If *None*, create a new, appropriately sized figure window.
-
- If 0, use the current Axes (creating one if there is none, without ever
- adjusting the figure size).
-
- Otherwise, create a new Axes on the figure with the given number
- (creating it at the appropriate size if it does not exist, but not
- adjusting the figure size otherwise). Note that this will be drawn on
- top of any preexisting Axes on the figure.
-
- Returns
- -------
- `~matplotlib.image.AxesImage`
-
- Other Parameters
- ----------------
- **kwargs : `~matplotlib.axes.Axes.imshow` arguments
-
- """
- A = np.asanyarray(A)
- if fignum == 0:
- ax = gca()
- else:
- # Extract actual aspect ratio of array and make appropriately sized
- # figure.
- fig = figure(fignum, figsize=figaspect(A))
- ax = fig.add_axes((0.15, 0.09, 0.775, 0.775))
- im = ax.matshow(A, **kwargs)
- sci(im)
- return im
-
-
-def polar(*args, **kwargs) -> list[Line2D]:
- """
- Make a polar plot.
-
- call signature::
-
- polar(theta, r, **kwargs)
-
- Multiple *theta*, *r* arguments are supported, with format strings, as in
- `plot`.
- """
- # If an axis already exists, check if it has a polar projection
- if gcf().get_axes():
- ax = gca()
- if not isinstance(ax, PolarAxes):
- _api.warn_external('Trying to create polar plot on an Axes '
- 'that does not have a polar projection.')
- else:
- ax = axes(projection="polar")
- return ax.plot(*args, **kwargs)
-
-
-# If rcParams['backend_fallback'] is true, and an interactive backend is
-# requested, ignore rcParams['backend'] and force selection of a backend that
-# is compatible with the current running interactive framework.
-if (rcParams["backend_fallback"]
- and rcParams._get_backend_or_none() in ( # type: ignore
- set(rcsetup.interactive_bk) - {'WebAgg', 'nbAgg'})
- and cbook._get_running_interactive_framework()): # type: ignore
- rcParams._set("backend", rcsetup._auto_backend_sentinel) # type: ignore
-
-# fmt: on
-
-################# REMAINING CONTENT GENERATED BY boilerplate.py ##############
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Figure.figimage)
-def figimage(
- X: ArrayLike,
- xo: int = 0,
- yo: int = 0,
- alpha: float | None = None,
- norm: str | Normalize | None = None,
- cmap: str | Colormap | None = None,
- vmin: float | None = None,
- vmax: float | None = None,
- origin: Literal["upper", "lower"] | None = None,
- resize: bool = False,
- **kwargs,
-) -> FigureImage:
- return gcf().figimage(
- X,
- xo=xo,
- yo=yo,
- alpha=alpha,
- norm=norm,
- cmap=cmap,
- vmin=vmin,
- vmax=vmax,
- origin=origin,
- resize=resize,
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Figure.text)
-def figtext(
- x: float, y: float, s: str, fontdict: dict[str, Any] | None = None, **kwargs
-) -> Text:
- return gcf().text(x, y, s, fontdict=fontdict, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Figure.gca)
-def gca() -> Axes:
- return gcf().gca()
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Figure._gci)
-def gci() -> ScalarMappable | None:
- return gcf()._gci()
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Figure.ginput)
-def ginput(
- n: int = 1,
- timeout: float = 30,
- show_clicks: bool = True,
- mouse_add: MouseButton = MouseButton.LEFT,
- mouse_pop: MouseButton = MouseButton.RIGHT,
- mouse_stop: MouseButton = MouseButton.MIDDLE,
-) -> list[tuple[int, int]]:
- return gcf().ginput(
- n=n,
- timeout=timeout,
- show_clicks=show_clicks,
- mouse_add=mouse_add,
- mouse_pop=mouse_pop,
- mouse_stop=mouse_stop,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Figure.subplots_adjust)
-def subplots_adjust(
- left: float | None = None,
- bottom: float | None = None,
- right: float | None = None,
- top: float | None = None,
- wspace: float | None = None,
- hspace: float | None = None,
-) -> None:
- gcf().subplots_adjust(
- left=left, bottom=bottom, right=right, top=top, wspace=wspace, hspace=hspace
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Figure.suptitle)
-def suptitle(t: str, **kwargs) -> Text:
- return gcf().suptitle(t, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Figure.tight_layout)
-def tight_layout(
- *,
- pad: float = 1.08,
- h_pad: float | None = None,
- w_pad: float | None = None,
- rect: tuple[float, float, float, float] | None = None,
-) -> None:
- gcf().tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Figure.waitforbuttonpress)
-def waitforbuttonpress(timeout: float = -1) -> None | bool:
- return gcf().waitforbuttonpress(timeout=timeout)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.acorr)
-def acorr(
- x: ArrayLike, *, data=None, **kwargs
-) -> tuple[np.ndarray, np.ndarray, LineCollection | Line2D, Line2D | None]:
- return gca().acorr(x, **({"data": data} if data is not None else {}), **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.angle_spectrum)
-def angle_spectrum(
- x: ArrayLike,
- Fs: float | None = None,
- Fc: int | None = None,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = None,
- pad_to: int | None = None,
- sides: Literal["default", "onesided", "twosided"] | None = None,
- *,
- data=None,
- **kwargs,
-) -> tuple[np.ndarray, np.ndarray, Line2D]:
- return gca().angle_spectrum(
- x,
- Fs=Fs,
- Fc=Fc,
- window=window,
- pad_to=pad_to,
- sides=sides,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.annotate)
-def annotate(
- text: str,
- xy: tuple[float, float],
- xytext: tuple[float, float] | None = None,
- xycoords: str
- | Artist
- | Transform
- | Callable[[RendererBase], Bbox | Transform]
- | tuple[float, float] = "data",
- textcoords: str
- | Artist
- | Transform
- | Callable[[RendererBase], Bbox | Transform]
- | tuple[float, float]
- | None = None,
- arrowprops: dict[str, Any] | None = None,
- annotation_clip: bool | None = None,
- **kwargs,
-) -> Annotation:
- return gca().annotate(
- text,
- xy,
- xytext=xytext,
- xycoords=xycoords,
- textcoords=textcoords,
- arrowprops=arrowprops,
- annotation_clip=annotation_clip,
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.arrow)
-def arrow(x: float, y: float, dx: float, dy: float, **kwargs) -> FancyArrow:
- return gca().arrow(x, y, dx, dy, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.autoscale)
-def autoscale(
- enable: bool = True,
- axis: Literal["both", "x", "y"] = "both",
- tight: bool | None = None,
-) -> None:
- gca().autoscale(enable=enable, axis=axis, tight=tight)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.axhline)
-def axhline(y: float = 0, xmin: float = 0, xmax: float = 1, **kwargs) -> Line2D:
- return gca().axhline(y=y, xmin=xmin, xmax=xmax, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.axhspan)
-def axhspan(
- ymin: float, ymax: float, xmin: float = 0, xmax: float = 1, **kwargs
-) -> Polygon:
- return gca().axhspan(ymin, ymax, xmin=xmin, xmax=xmax, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.axis)
-def axis(
- arg: tuple[float, float, float, float] | bool | str | None = None,
- /,
- *,
- emit: bool = True,
- **kwargs,
-) -> tuple[float, float, float, float]:
- return gca().axis(arg, emit=emit, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.axline)
-def axline(
- xy1: tuple[float, float],
- xy2: tuple[float, float] | None = None,
- *,
- slope: float | None = None,
- **kwargs,
-) -> Line2D:
- return gca().axline(xy1, xy2=xy2, slope=slope, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.axvline)
-def axvline(x: float = 0, ymin: float = 0, ymax: float = 1, **kwargs) -> Line2D:
- return gca().axvline(x=x, ymin=ymin, ymax=ymax, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.axvspan)
-def axvspan(
- xmin: float, xmax: float, ymin: float = 0, ymax: float = 1, **kwargs
-) -> Polygon:
- return gca().axvspan(xmin, xmax, ymin=ymin, ymax=ymax, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.bar)
-def bar(
- x: float | ArrayLike,
- height: float | ArrayLike,
- width: float | ArrayLike = 0.8,
- bottom: float | ArrayLike | None = None,
- *,
- align: Literal["center", "edge"] = "center",
- data=None,
- **kwargs,
-) -> BarContainer:
- return gca().bar(
- x,
- height,
- width=width,
- bottom=bottom,
- align=align,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.barbs)
-def barbs(*args, data=None, **kwargs) -> Barbs:
- return gca().barbs(*args, **({"data": data} if data is not None else {}), **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.barh)
-def barh(
- y: float | ArrayLike,
- width: float | ArrayLike,
- height: float | ArrayLike = 0.8,
- left: float | ArrayLike | None = None,
- *,
- align: Literal["center", "edge"] = "center",
- data=None,
- **kwargs,
-) -> BarContainer:
- return gca().barh(
- y,
- width,
- height=height,
- left=left,
- align=align,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.bar_label)
-def bar_label(
- container: BarContainer,
- labels: ArrayLike | None = None,
- *,
- fmt: str | Callable[[float], str] = "%g",
- label_type: Literal["center", "edge"] = "edge",
- padding: float = 0,
- **kwargs,
-) -> list[Annotation]:
- return gca().bar_label(
- container,
- labels=labels,
- fmt=fmt,
- label_type=label_type,
- padding=padding,
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.boxplot)
-def boxplot(
- x: ArrayLike | Sequence[ArrayLike],
- notch: bool | None = None,
- sym: str | None = None,
- vert: bool | None = None,
- whis: float | tuple[float, float] | None = None,
- positions: ArrayLike | None = None,
- widths: float | ArrayLike | None = None,
- patch_artist: bool | None = None,
- bootstrap: int | None = None,
- usermedians: ArrayLike | None = None,
- conf_intervals: ArrayLike | None = None,
- meanline: bool | None = None,
- showmeans: bool | None = None,
- showcaps: bool | None = None,
- showbox: bool | None = None,
- showfliers: bool | None = None,
- boxprops: dict[str, Any] | None = None,
- labels: Sequence[str] | None = None,
- flierprops: dict[str, Any] | None = None,
- medianprops: dict[str, Any] | None = None,
- meanprops: dict[str, Any] | None = None,
- capprops: dict[str, Any] | None = None,
- whiskerprops: dict[str, Any] | None = None,
- manage_ticks: bool = True,
- autorange: bool = False,
- zorder: float | None = None,
- capwidths: float | ArrayLike | None = None,
- *,
- data=None,
-) -> dict[str, Any]:
- return gca().boxplot(
- x,
- notch=notch,
- sym=sym,
- vert=vert,
- whis=whis,
- positions=positions,
- widths=widths,
- patch_artist=patch_artist,
- bootstrap=bootstrap,
- usermedians=usermedians,
- conf_intervals=conf_intervals,
- meanline=meanline,
- showmeans=showmeans,
- showcaps=showcaps,
- showbox=showbox,
- showfliers=showfliers,
- boxprops=boxprops,
- labels=labels,
- flierprops=flierprops,
- medianprops=medianprops,
- meanprops=meanprops,
- capprops=capprops,
- whiskerprops=whiskerprops,
- manage_ticks=manage_ticks,
- autorange=autorange,
- zorder=zorder,
- capwidths=capwidths,
- **({"data": data} if data is not None else {}),
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.broken_barh)
-def broken_barh(
- xranges: Sequence[tuple[float, float]],
- yrange: tuple[float, float],
- *,
- data=None,
- **kwargs,
-) -> BrokenBarHCollection:
- return gca().broken_barh(
- xranges, yrange, **({"data": data} if data is not None else {}), **kwargs
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.clabel)
-def clabel(CS: ContourSet, levels: ArrayLike | None = None, **kwargs) -> list[Text]:
- return gca().clabel(CS, levels=levels, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.cohere)
-def cohere(
- x: ArrayLike,
- y: ArrayLike,
- NFFT: int = 256,
- Fs: float = 2,
- Fc: int = 0,
- detrend: Literal["none", "mean", "linear"]
- | Callable[[ArrayLike], ArrayLike] = mlab.detrend_none,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike = mlab.window_hanning,
- noverlap: int = 0,
- pad_to: int | None = None,
- sides: Literal["default", "onesided", "twosided"] = "default",
- scale_by_freq: bool | None = None,
- *,
- data=None,
- **kwargs,
-) -> tuple[np.ndarray, np.ndarray]:
- return gca().cohere(
- x,
- y,
- NFFT=NFFT,
- Fs=Fs,
- Fc=Fc,
- detrend=detrend,
- window=window,
- noverlap=noverlap,
- pad_to=pad_to,
- sides=sides,
- scale_by_freq=scale_by_freq,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.contour)
-def contour(*args, data=None, **kwargs) -> QuadContourSet:
- __ret = gca().contour(
- *args, **({"data": data} if data is not None else {}), **kwargs
- )
- if __ret._A is not None: # type: ignore[attr-defined]
- sci(__ret)
- return __ret
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.contourf)
-def contourf(*args, data=None, **kwargs) -> QuadContourSet:
- __ret = gca().contourf(
- *args, **({"data": data} if data is not None else {}), **kwargs
- )
- if __ret._A is not None: # type: ignore[attr-defined]
- sci(__ret)
- return __ret
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.csd)
-def csd(
- x: ArrayLike,
- y: ArrayLike,
- NFFT: int | None = None,
- Fs: float | None = None,
- Fc: int | None = None,
- detrend: Literal["none", "mean", "linear"]
- | Callable[[ArrayLike], ArrayLike]
- | None = None,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = None,
- noverlap: int | None = None,
- pad_to: int | None = None,
- sides: Literal["default", "onesided", "twosided"] | None = None,
- scale_by_freq: bool | None = None,
- return_line: bool | None = None,
- *,
- data=None,
- **kwargs,
-) -> tuple[np.ndarray, np.ndarray] | tuple[np.ndarray, np.ndarray, Line2D]:
- return gca().csd(
- x,
- y,
- NFFT=NFFT,
- Fs=Fs,
- Fc=Fc,
- detrend=detrend,
- window=window,
- noverlap=noverlap,
- pad_to=pad_to,
- sides=sides,
- scale_by_freq=scale_by_freq,
- return_line=return_line,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.ecdf)
-def ecdf(
- x: ArrayLike,
- weights: ArrayLike | None = None,
- *,
- complementary: bool = False,
- orientation: Literal["vertical", "horizonatal"] = "vertical",
- compress: bool = False,
- data=None,
- **kwargs,
-) -> Line2D:
- return gca().ecdf(
- x,
- weights=weights,
- complementary=complementary,
- orientation=orientation,
- compress=compress,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.errorbar)
-def errorbar(
- x: float | ArrayLike,
- y: float | ArrayLike,
- yerr: float | ArrayLike | None = None,
- xerr: float | ArrayLike | None = None,
- fmt: str = "",
- ecolor: ColorType | None = None,
- elinewidth: float | None = None,
- capsize: float | None = None,
- barsabove: bool = False,
- lolims: bool | ArrayLike = False,
- uplims: bool | ArrayLike = False,
- xlolims: bool | ArrayLike = False,
- xuplims: bool | ArrayLike = False,
- errorevery: int | tuple[int, int] = 1,
- capthick: float | None = None,
- *,
- data=None,
- **kwargs,
-) -> ErrorbarContainer:
- return gca().errorbar(
- x,
- y,
- yerr=yerr,
- xerr=xerr,
- fmt=fmt,
- ecolor=ecolor,
- elinewidth=elinewidth,
- capsize=capsize,
- barsabove=barsabove,
- lolims=lolims,
- uplims=uplims,
- xlolims=xlolims,
- xuplims=xuplims,
- errorevery=errorevery,
- capthick=capthick,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.eventplot)
-def eventplot(
- positions: ArrayLike | Sequence[ArrayLike],
- orientation: Literal["horizontal", "vertical"] = "horizontal",
- lineoffsets: float | Sequence[float] = 1,
- linelengths: float | Sequence[float] = 1,
- linewidths: float | Sequence[float] | None = None,
- colors: ColorType | Sequence[ColorType] | None = None,
- alpha: float | Sequence[float] | None = None,
- linestyles: LineStyleType | Sequence[LineStyleType] = "solid",
- *,
- data=None,
- **kwargs,
-) -> EventCollection:
- return gca().eventplot(
- positions,
- orientation=orientation,
- lineoffsets=lineoffsets,
- linelengths=linelengths,
- linewidths=linewidths,
- colors=colors,
- alpha=alpha,
- linestyles=linestyles,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.fill)
-def fill(*args, data=None, **kwargs) -> list[Polygon]:
- return gca().fill(*args, **({"data": data} if data is not None else {}), **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.fill_between)
-def fill_between(
- x: ArrayLike,
- y1: ArrayLike | float,
- y2: ArrayLike | float = 0,
- where: Sequence[bool] | None = None,
- interpolate: bool = False,
- step: Literal["pre", "post", "mid"] | None = None,
- *,
- data=None,
- **kwargs,
-) -> PolyCollection:
- return gca().fill_between(
- x,
- y1,
- y2=y2,
- where=where,
- interpolate=interpolate,
- step=step,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.fill_betweenx)
-def fill_betweenx(
- y: ArrayLike,
- x1: ArrayLike | float,
- x2: ArrayLike | float = 0,
- where: Sequence[bool] | None = None,
- step: Literal["pre", "post", "mid"] | None = None,
- interpolate: bool = False,
- *,
- data=None,
- **kwargs,
-) -> PolyCollection:
- return gca().fill_betweenx(
- y,
- x1,
- x2=x2,
- where=where,
- step=step,
- interpolate=interpolate,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.grid)
-def grid(
- visible: bool | None = None,
- which: Literal["major", "minor", "both"] = "major",
- axis: Literal["both", "x", "y"] = "both",
- **kwargs,
-) -> None:
- gca().grid(visible=visible, which=which, axis=axis, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.hexbin)
-def hexbin(
- x: ArrayLike,
- y: ArrayLike,
- C: ArrayLike | None = None,
- gridsize: int | tuple[int, int] = 100,
- bins: Literal["log"] | int | Sequence[float] | None = None,
- xscale: Literal["linear", "log"] = "linear",
- yscale: Literal["linear", "log"] = "linear",
- extent: tuple[float, float, float, float] | None = None,
- cmap: str | Colormap | None = None,
- norm: str | Normalize | None = None,
- vmin: float | None = None,
- vmax: float | None = None,
- alpha: float | None = None,
- linewidths: float | None = None,
- edgecolors: Literal["face", "none"] | ColorType = "face",
- reduce_C_function: Callable[[np.ndarray | list[float]], float] = np.mean,
- mincnt: int | None = None,
- marginals: bool = False,
- *,
- data=None,
- **kwargs,
-) -> PolyCollection:
- __ret = gca().hexbin(
- x,
- y,
- C=C,
- gridsize=gridsize,
- bins=bins,
- xscale=xscale,
- yscale=yscale,
- extent=extent,
- cmap=cmap,
- norm=norm,
- vmin=vmin,
- vmax=vmax,
- alpha=alpha,
- linewidths=linewidths,
- edgecolors=edgecolors,
- reduce_C_function=reduce_C_function,
- mincnt=mincnt,
- marginals=marginals,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
- sci(__ret)
- return __ret
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.hist)
-def hist(
- x: ArrayLike | Sequence[ArrayLike],
- bins: int | Sequence[float] | str | None = None,
- range: tuple[float, float] | None = None,
- density: bool = False,
- weights: ArrayLike | None = None,
- cumulative: bool | float = False,
- bottom: ArrayLike | float | None = None,
- histtype: Literal["bar", "barstacked", "step", "stepfilled"] = "bar",
- align: Literal["left", "mid", "right"] = "mid",
- orientation: Literal["vertical", "horizontal"] = "vertical",
- rwidth: float | None = None,
- log: bool = False,
- color: ColorType | Sequence[ColorType] | None = None,
- label: str | Sequence[str] | None = None,
- stacked: bool = False,
- *,
- data=None,
- **kwargs,
-) -> tuple[
- np.ndarray | list[np.ndarray],
- np.ndarray,
- BarContainer | Polygon | list[BarContainer | Polygon],
-]:
- return gca().hist(
- x,
- bins=bins,
- range=range,
- density=density,
- weights=weights,
- cumulative=cumulative,
- bottom=bottom,
- histtype=histtype,
- align=align,
- orientation=orientation,
- rwidth=rwidth,
- log=log,
- color=color,
- label=label,
- stacked=stacked,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.stairs)
-def stairs(
- values: ArrayLike,
- edges: ArrayLike | None = None,
- *,
- orientation: Literal["vertical", "horizontal"] = "vertical",
- baseline: float | ArrayLike | None = 0,
- fill: bool = False,
- data=None,
- **kwargs,
-) -> StepPatch:
- return gca().stairs(
- values,
- edges=edges,
- orientation=orientation,
- baseline=baseline,
- fill=fill,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.hist2d)
-def hist2d(
- x: ArrayLike,
- y: ArrayLike,
- bins: None | int | tuple[int, int] | ArrayLike | tuple[ArrayLike, ArrayLike] = 10,
- range: ArrayLike | None = None,
- density: bool = False,
- weights: ArrayLike | None = None,
- cmin: float | None = None,
- cmax: float | None = None,
- *,
- data=None,
- **kwargs,
-) -> tuple[np.ndarray, np.ndarray, np.ndarray, QuadMesh]:
- __ret = gca().hist2d(
- x,
- y,
- bins=bins,
- range=range,
- density=density,
- weights=weights,
- cmin=cmin,
- cmax=cmax,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
- sci(__ret[-1])
- return __ret
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.hlines)
-def hlines(
- y: float | ArrayLike,
- xmin: float | ArrayLike,
- xmax: float | ArrayLike,
- colors: ColorType | Sequence[ColorType] | None = None,
- linestyles: LineStyleType = "solid",
- label: str = "",
- *,
- data=None,
- **kwargs,
-) -> LineCollection:
- return gca().hlines(
- y,
- xmin,
- xmax,
- colors=colors,
- linestyles=linestyles,
- label=label,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.imshow)
-def imshow(
- X: ArrayLike | PIL.Image.Image,
- cmap: str | Colormap | None = None,
- norm: str | Normalize | None = None,
- *,
- aspect: Literal["equal", "auto"] | float | None = None,
- interpolation: str | None = None,
- alpha: float | ArrayLike | None = None,
- vmin: float | None = None,
- vmax: float | None = None,
- origin: Literal["upper", "lower"] | None = None,
- extent: tuple[float, float, float, float] | None = None,
- interpolation_stage: Literal["data", "rgba"] | None = None,
- filternorm: bool = True,
- filterrad: float = 4.0,
- resample: bool | None = None,
- url: str | None = None,
- data=None,
- **kwargs,
-) -> AxesImage:
- __ret = gca().imshow(
- X,
- cmap=cmap,
- norm=norm,
- aspect=aspect,
- interpolation=interpolation,
- alpha=alpha,
- vmin=vmin,
- vmax=vmax,
- origin=origin,
- extent=extent,
- interpolation_stage=interpolation_stage,
- filternorm=filternorm,
- filterrad=filterrad,
- resample=resample,
- url=url,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
- sci(__ret)
- return __ret
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.legend)
-def legend(*args, **kwargs) -> Legend:
- return gca().legend(*args, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.locator_params)
-def locator_params(
- axis: Literal["both", "x", "y"] = "both", tight: bool | None = None, **kwargs
-) -> None:
- gca().locator_params(axis=axis, tight=tight, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.loglog)
-def loglog(*args, **kwargs) -> list[Line2D]:
- return gca().loglog(*args, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.magnitude_spectrum)
-def magnitude_spectrum(
- x: ArrayLike,
- Fs: float | None = None,
- Fc: int | None = None,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = None,
- pad_to: int | None = None,
- sides: Literal["default", "onesided", "twosided"] | None = None,
- scale: Literal["default", "linear", "dB"] | None = None,
- *,
- data=None,
- **kwargs,
-) -> tuple[np.ndarray, np.ndarray, Line2D]:
- return gca().magnitude_spectrum(
- x,
- Fs=Fs,
- Fc=Fc,
- window=window,
- pad_to=pad_to,
- sides=sides,
- scale=scale,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.margins)
-def margins(
- *margins: float,
- x: float | None = None,
- y: float | None = None,
- tight: bool | None = True,
-) -> tuple[float, float] | None:
- return gca().margins(*margins, x=x, y=y, tight=tight)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.minorticks_off)
-def minorticks_off() -> None:
- gca().minorticks_off()
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.minorticks_on)
-def minorticks_on() -> None:
- gca().minorticks_on()
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.pcolor)
-def pcolor(
- *args: ArrayLike,
- shading: Literal["flat", "nearest", "auto"] | None = None,
- alpha: float | None = None,
- norm: str | Normalize | None = None,
- cmap: str | Colormap | None = None,
- vmin: float | None = None,
- vmax: float | None = None,
- data=None,
- **kwargs,
-) -> Collection:
- __ret = gca().pcolor(
- *args,
- shading=shading,
- alpha=alpha,
- norm=norm,
- cmap=cmap,
- vmin=vmin,
- vmax=vmax,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
- sci(__ret)
- return __ret
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.pcolormesh)
-def pcolormesh(
- *args: ArrayLike,
- alpha: float | None = None,
- norm: str | Normalize | None = None,
- cmap: str | Colormap | None = None,
- vmin: float | None = None,
- vmax: float | None = None,
- shading: Literal["flat", "nearest", "gouraud", "auto"] | None = None,
- antialiased: bool = False,
- data=None,
- **kwargs,
-) -> QuadMesh:
- __ret = gca().pcolormesh(
- *args,
- alpha=alpha,
- norm=norm,
- cmap=cmap,
- vmin=vmin,
- vmax=vmax,
- shading=shading,
- antialiased=antialiased,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
- sci(__ret)
- return __ret
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.phase_spectrum)
-def phase_spectrum(
- x: ArrayLike,
- Fs: float | None = None,
- Fc: int | None = None,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = None,
- pad_to: int | None = None,
- sides: Literal["default", "onesided", "twosided"] | None = None,
- *,
- data=None,
- **kwargs,
-) -> tuple[np.ndarray, np.ndarray, Line2D]:
- return gca().phase_spectrum(
- x,
- Fs=Fs,
- Fc=Fc,
- window=window,
- pad_to=pad_to,
- sides=sides,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.pie)
-def pie(
- x: ArrayLike,
- explode: ArrayLike | None = None,
- labels: Sequence[str] | None = None,
- colors: ColorType | Sequence[ColorType] | None = None,
- autopct: str | Callable[[float], str] | None = None,
- pctdistance: float = 0.6,
- shadow: bool = False,
- labeldistance: float | None = 1.1,
- startangle: float = 0,
- radius: float = 1,
- counterclock: bool = True,
- wedgeprops: dict[str, Any] | None = None,
- textprops: dict[str, Any] | None = None,
- center: tuple[float, float] = (0, 0),
- frame: bool = False,
- rotatelabels: bool = False,
- *,
- normalize: bool = True,
- hatch: str | Sequence[str] | None = None,
- data=None,
-) -> tuple[list[Wedge], list[Text]] | tuple[list[Wedge], list[Text], list[Text]]:
- return gca().pie(
- x,
- explode=explode,
- labels=labels,
- colors=colors,
- autopct=autopct,
- pctdistance=pctdistance,
- shadow=shadow,
- labeldistance=labeldistance,
- startangle=startangle,
- radius=radius,
- counterclock=counterclock,
- wedgeprops=wedgeprops,
- textprops=textprops,
- center=center,
- frame=frame,
- rotatelabels=rotatelabels,
- normalize=normalize,
- hatch=hatch,
- **({"data": data} if data is not None else {}),
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.plot)
-def plot(
- *args: float | ArrayLike | str,
- scalex: bool = True,
- scaley: bool = True,
- data=None,
- **kwargs,
-) -> list[Line2D]:
- return gca().plot(
- *args,
- scalex=scalex,
- scaley=scaley,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.plot_date)
-def plot_date(
- x: ArrayLike,
- y: ArrayLike,
- fmt: str = "o",
- tz: str | datetime.tzinfo | None = None,
- xdate: bool = True,
- ydate: bool = False,
- *,
- data=None,
- **kwargs,
-) -> list[Line2D]:
- return gca().plot_date(
- x,
- y,
- fmt=fmt,
- tz=tz,
- xdate=xdate,
- ydate=ydate,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.psd)
-def psd(
- x: ArrayLike,
- NFFT: int | None = None,
- Fs: float | None = None,
- Fc: int | None = None,
- detrend: Literal["none", "mean", "linear"]
- | Callable[[ArrayLike], ArrayLike]
- | None = None,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = None,
- noverlap: int | None = None,
- pad_to: int | None = None,
- sides: Literal["default", "onesided", "twosided"] | None = None,
- scale_by_freq: bool | None = None,
- return_line: bool | None = None,
- *,
- data=None,
- **kwargs,
-) -> tuple[np.ndarray, np.ndarray] | tuple[np.ndarray, np.ndarray, Line2D]:
- return gca().psd(
- x,
- NFFT=NFFT,
- Fs=Fs,
- Fc=Fc,
- detrend=detrend,
- window=window,
- noverlap=noverlap,
- pad_to=pad_to,
- sides=sides,
- scale_by_freq=scale_by_freq,
- return_line=return_line,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.quiver)
-def quiver(*args, data=None, **kwargs) -> Quiver:
- __ret = gca().quiver(
- *args, **({"data": data} if data is not None else {}), **kwargs
- )
- sci(__ret)
- return __ret
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.quiverkey)
-def quiverkey(
- Q: Quiver, X: float, Y: float, U: float, label: str, **kwargs
-) -> QuiverKey:
- return gca().quiverkey(Q, X, Y, U, label, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.scatter)
-def scatter(
- x: float | ArrayLike,
- y: float | ArrayLike,
- s: float | ArrayLike | None = None,
- c: ArrayLike | Sequence[ColorType] | ColorType | None = None,
- marker: MarkerType | None = None,
- cmap: str | Colormap | None = None,
- norm: str | Normalize | None = None,
- vmin: float | None = None,
- vmax: float | None = None,
- alpha: float | None = None,
- linewidths: float | Sequence[float] | None = None,
- *,
- edgecolors: Literal["face", "none"] | ColorType | Sequence[ColorType] | None = None,
- plotnonfinite: bool = False,
- data=None,
- **kwargs,
-) -> PathCollection:
- __ret = gca().scatter(
- x,
- y,
- s=s,
- c=c,
- marker=marker,
- cmap=cmap,
- norm=norm,
- vmin=vmin,
- vmax=vmax,
- alpha=alpha,
- linewidths=linewidths,
- edgecolors=edgecolors,
- plotnonfinite=plotnonfinite,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
- sci(__ret)
- return __ret
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.semilogx)
-def semilogx(*args, **kwargs) -> list[Line2D]:
- return gca().semilogx(*args, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.semilogy)
-def semilogy(*args, **kwargs) -> list[Line2D]:
- return gca().semilogy(*args, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.specgram)
-def specgram(
- x: ArrayLike,
- NFFT: int | None = None,
- Fs: float | None = None,
- Fc: int | None = None,
- detrend: Literal["none", "mean", "linear"]
- | Callable[[ArrayLike], ArrayLike]
- | None = None,
- window: Callable[[ArrayLike], ArrayLike] | ArrayLike | None = None,
- noverlap: int | None = None,
- cmap: str | Colormap | None = None,
- xextent: tuple[float, float] | None = None,
- pad_to: int | None = None,
- sides: Literal["default", "onesided", "twosided"] | None = None,
- scale_by_freq: bool | None = None,
- mode: Literal["default", "psd", "magnitude", "angle", "phase"] | None = None,
- scale: Literal["default", "linear", "dB"] | None = None,
- vmin: float | None = None,
- vmax: float | None = None,
- *,
- data=None,
- **kwargs,
-) -> tuple[np.ndarray, np.ndarray, np.ndarray, AxesImage]:
- __ret = gca().specgram(
- x,
- NFFT=NFFT,
- Fs=Fs,
- Fc=Fc,
- detrend=detrend,
- window=window,
- noverlap=noverlap,
- cmap=cmap,
- xextent=xextent,
- pad_to=pad_to,
- sides=sides,
- scale_by_freq=scale_by_freq,
- mode=mode,
- scale=scale,
- vmin=vmin,
- vmax=vmax,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
- sci(__ret[-1])
- return __ret
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.spy)
-def spy(
- Z: ArrayLike,
- precision: float | Literal["present"] = 0,
- marker: str | None = None,
- markersize: float | None = None,
- aspect: Literal["equal", "auto"] | float | None = "equal",
- origin: Literal["upper", "lower"] = "upper",
- **kwargs,
-) -> AxesImage:
- __ret = gca().spy(
- Z,
- precision=precision,
- marker=marker,
- markersize=markersize,
- aspect=aspect,
- origin=origin,
- **kwargs,
- )
- if isinstance(__ret, cm.ScalarMappable):
- sci(__ret) # noqa
- return __ret
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.stackplot)
-def stackplot(x, *args, labels=(), colors=None, baseline="zero", data=None, **kwargs):
- return gca().stackplot(
- x,
- *args,
- labels=labels,
- colors=colors,
- baseline=baseline,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.stem)
-def stem(
- *args: ArrayLike | str,
- linefmt: str | None = None,
- markerfmt: str | None = None,
- basefmt: str | None = None,
- bottom: float = 0,
- label: str | None = None,
- orientation: Literal["vertical", "horizontal"] = "vertical",
- data=None,
-) -> StemContainer:
- return gca().stem(
- *args,
- linefmt=linefmt,
- markerfmt=markerfmt,
- basefmt=basefmt,
- bottom=bottom,
- label=label,
- orientation=orientation,
- **({"data": data} if data is not None else {}),
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.step)
-def step(
- x: ArrayLike,
- y: ArrayLike,
- *args,
- where: Literal["pre", "post", "mid"] = "pre",
- data=None,
- **kwargs,
-) -> list[Line2D]:
- return gca().step(
- x,
- y,
- *args,
- where=where,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.streamplot)
-def streamplot(
- x,
- y,
- u,
- v,
- density=1,
- linewidth=None,
- color=None,
- cmap=None,
- norm=None,
- arrowsize=1,
- arrowstyle="-|>",
- minlength=0.1,
- transform=None,
- zorder=None,
- start_points=None,
- maxlength=4.0,
- integration_direction="both",
- broken_streamlines=True,
- *,
- data=None,
-):
- __ret = gca().streamplot(
- x,
- y,
- u,
- v,
- density=density,
- linewidth=linewidth,
- color=color,
- cmap=cmap,
- norm=norm,
- arrowsize=arrowsize,
- arrowstyle=arrowstyle,
- minlength=minlength,
- transform=transform,
- zorder=zorder,
- start_points=start_points,
- maxlength=maxlength,
- integration_direction=integration_direction,
- broken_streamlines=broken_streamlines,
- **({"data": data} if data is not None else {}),
- )
- sci(__ret.lines)
- return __ret
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.table)
-def table(
- cellText=None,
- cellColours=None,
- cellLoc="right",
- colWidths=None,
- rowLabels=None,
- rowColours=None,
- rowLoc="left",
- colLabels=None,
- colColours=None,
- colLoc="center",
- loc="bottom",
- bbox=None,
- edges="closed",
- **kwargs,
-):
- return gca().table(
- cellText=cellText,
- cellColours=cellColours,
- cellLoc=cellLoc,
- colWidths=colWidths,
- rowLabels=rowLabels,
- rowColours=rowColours,
- rowLoc=rowLoc,
- colLabels=colLabels,
- colColours=colColours,
- colLoc=colLoc,
- loc=loc,
- bbox=bbox,
- edges=edges,
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.text)
-def text(
- x: float, y: float, s: str, fontdict: dict[str, Any] | None = None, **kwargs
-) -> Text:
- return gca().text(x, y, s, fontdict=fontdict, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.tick_params)
-def tick_params(axis: Literal["both", "x", "y"] = "both", **kwargs) -> None:
- gca().tick_params(axis=axis, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.ticklabel_format)
-def ticklabel_format(
- *,
- axis: Literal["both", "x", "y"] = "both",
- style: Literal["", "sci", "scientific", "plain"] = "",
- scilimits: tuple[int, int] | None = None,
- useOffset: bool | float | None = None,
- useLocale: bool | None = None,
- useMathText: bool | None = None,
-) -> None:
- gca().ticklabel_format(
- axis=axis,
- style=style,
- scilimits=scilimits,
- useOffset=useOffset,
- useLocale=useLocale,
- useMathText=useMathText,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.tricontour)
-def tricontour(*args, **kwargs):
- __ret = gca().tricontour(*args, **kwargs)
- if __ret._A is not None: # type: ignore[attr-defined]
- sci(__ret)
- return __ret
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.tricontourf)
-def tricontourf(*args, **kwargs):
- __ret = gca().tricontourf(*args, **kwargs)
- if __ret._A is not None: # type: ignore[attr-defined]
- sci(__ret)
- return __ret
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.tripcolor)
-def tripcolor(
- *args,
- alpha=1.0,
- norm=None,
- cmap=None,
- vmin=None,
- vmax=None,
- shading="flat",
- facecolors=None,
- **kwargs,
-):
- __ret = gca().tripcolor(
- *args,
- alpha=alpha,
- norm=norm,
- cmap=cmap,
- vmin=vmin,
- vmax=vmax,
- shading=shading,
- facecolors=facecolors,
- **kwargs,
- )
- sci(__ret)
- return __ret
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.triplot)
-def triplot(*args, **kwargs):
- return gca().triplot(*args, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.violinplot)
-def violinplot(
- dataset: ArrayLike | Sequence[ArrayLike],
- positions: ArrayLike | None = None,
- vert: bool = True,
- widths: float | ArrayLike = 0.5,
- showmeans: bool = False,
- showextrema: bool = True,
- showmedians: bool = False,
- quantiles: Sequence[float | Sequence[float]] | None = None,
- points: int = 100,
- bw_method: Literal["scott", "silverman"]
- | float
- | Callable[[GaussianKDE], float]
- | None = None,
- *,
- data=None,
-) -> dict[str, Collection]:
- return gca().violinplot(
- dataset,
- positions=positions,
- vert=vert,
- widths=widths,
- showmeans=showmeans,
- showextrema=showextrema,
- showmedians=showmedians,
- quantiles=quantiles,
- points=points,
- bw_method=bw_method,
- **({"data": data} if data is not None else {}),
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.vlines)
-def vlines(
- x: float | ArrayLike,
- ymin: float | ArrayLike,
- ymax: float | ArrayLike,
- colors: ColorType | Sequence[ColorType] | None = None,
- linestyles: LineStyleType = "solid",
- label: str = "",
- *,
- data=None,
- **kwargs,
-) -> LineCollection:
- return gca().vlines(
- x,
- ymin,
- ymax,
- colors=colors,
- linestyles=linestyles,
- label=label,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.xcorr)
-def xcorr(
- x: ArrayLike,
- y: ArrayLike,
- normed: bool = True,
- detrend: Callable[[ArrayLike], ArrayLike] = mlab.detrend_none,
- usevlines: bool = True,
- maxlags: int = 10,
- *,
- data=None,
- **kwargs,
-) -> tuple[np.ndarray, np.ndarray, LineCollection | Line2D, Line2D | None]:
- return gca().xcorr(
- x,
- y,
- normed=normed,
- detrend=detrend,
- usevlines=usevlines,
- maxlags=maxlags,
- **({"data": data} if data is not None else {}),
- **kwargs,
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes._sci)
-def sci(im: ScalarMappable) -> None:
- gca()._sci(im)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.set_title)
-def title(
- label: str,
- fontdict: dict[str, Any] | None = None,
- loc: Literal["left", "center", "right"] | None = None,
- pad: float | None = None,
- *,
- y: float | None = None,
- **kwargs,
-) -> Text:
- return gca().set_title(label, fontdict=fontdict, loc=loc, pad=pad, y=y, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.set_xlabel)
-def xlabel(
- xlabel: str,
- fontdict: dict[str, Any] | None = None,
- labelpad: float | None = None,
- *,
- loc: Literal["left", "center", "right"] | None = None,
- **kwargs,
-) -> Text:
- return gca().set_xlabel(
- xlabel, fontdict=fontdict, labelpad=labelpad, loc=loc, **kwargs
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.set_ylabel)
-def ylabel(
- ylabel: str,
- fontdict: dict[str, Any] | None = None,
- labelpad: float | None = None,
- *,
- loc: Literal["bottom", "center", "top"] | None = None,
- **kwargs,
-) -> Text:
- return gca().set_ylabel(
- ylabel, fontdict=fontdict, labelpad=labelpad, loc=loc, **kwargs
- )
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.set_xscale)
-def xscale(value: str | ScaleBase, **kwargs) -> None:
- gca().set_xscale(value, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-@_copy_docstring_and_deprecators(Axes.set_yscale)
-def yscale(value: str | ScaleBase, **kwargs) -> None:
- gca().set_yscale(value, **kwargs)
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def autumn() -> None:
- """
- Set the colormap to 'autumn'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("autumn")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def bone() -> None:
- """
- Set the colormap to 'bone'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("bone")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def cool() -> None:
- """
- Set the colormap to 'cool'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("cool")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def copper() -> None:
- """
- Set the colormap to 'copper'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("copper")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def flag() -> None:
- """
- Set the colormap to 'flag'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("flag")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def gray() -> None:
- """
- Set the colormap to 'gray'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("gray")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def hot() -> None:
- """
- Set the colormap to 'hot'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("hot")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def hsv() -> None:
- """
- Set the colormap to 'hsv'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("hsv")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def jet() -> None:
- """
- Set the colormap to 'jet'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("jet")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def pink() -> None:
- """
- Set the colormap to 'pink'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("pink")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def prism() -> None:
- """
- Set the colormap to 'prism'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("prism")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def spring() -> None:
- """
- Set the colormap to 'spring'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("spring")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def summer() -> None:
- """
- Set the colormap to 'summer'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("summer")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def winter() -> None:
- """
- Set the colormap to 'winter'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("winter")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def magma() -> None:
- """
- Set the colormap to 'magma'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("magma")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def inferno() -> None:
- """
- Set the colormap to 'inferno'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("inferno")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def plasma() -> None:
- """
- Set the colormap to 'plasma'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("plasma")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def viridis() -> None:
- """
- Set the colormap to 'viridis'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("viridis")
-
-
-# Autogenerated by boilerplate.py. Do not edit as changes will be lost.
-def nipy_spectral() -> None:
- """
- Set the colormap to 'nipy_spectral'.
-
- This changes the default colormap as well as the colormap of the current
- image if there is one. See ``help(colormaps)`` for more information.
- """
- set_cmap("nipy_spectral")
diff --git a/contrib/python/matplotlib/py3/matplotlib/quiver.py b/contrib/python/matplotlib/py3/matplotlib/quiver.py
deleted file mode 100644
index c8f8ba5661..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/quiver.py
+++ /dev/null
@@ -1,1181 +0,0 @@
-"""
-Support for plotting vector fields.
-
-Presently this contains Quiver and Barb. Quiver plots an arrow in the
-direction of the vector, with the size of the arrow related to the
-magnitude of the vector.
-
-Barbs are like quiver in that they point along a vector, but
-the magnitude of the vector is given schematically by the presence of barbs
-or flags on the barb.
-
-This will also become a home for things such as standard
-deviation ellipses, which can and will be derived very easily from
-the Quiver code.
-"""
-
-import math
-
-import numpy as np
-from numpy import ma
-
-from matplotlib import _api, cbook, _docstring
-import matplotlib.artist as martist
-import matplotlib.collections as mcollections
-from matplotlib.patches import CirclePolygon
-import matplotlib.text as mtext
-import matplotlib.transforms as transforms
-
-
-_quiver_doc = """
-Plot a 2D field of arrows.
-
-Call signature::
-
- quiver([X, Y], U, V, [C], **kwargs)
-
-*X*, *Y* define the arrow locations, *U*, *V* define the arrow directions, and
-*C* optionally sets the color.
-
-**Arrow length**
-
-The default settings auto-scales the length of the arrows to a reasonable size.
-To change this behavior see the *scale* and *scale_units* parameters.
-
-**Arrow shape**
-
-The arrow shape is determined by *width*, *headwidth*, *headlength* and
-*headaxislength*. See the notes below.
-
-**Arrow styling**
-
-Each arrow is internally represented by a filled polygon with a default edge
-linewidth of 0. As a result, an arrow is rather a filled area, not a line with
-a head, and `.PolyCollection` properties like *linewidth*, *edgecolor*,
-*facecolor*, etc. act accordingly.
-
-
-Parameters
-----------
-X, Y : 1D or 2D array-like, optional
- The x and y coordinates of the arrow locations.
-
- If not given, they will be generated as a uniform integer meshgrid based
- on the dimensions of *U* and *V*.
-
- If *X* and *Y* are 1D but *U*, *V* are 2D, *X*, *Y* are expanded to 2D
- using ``X, Y = np.meshgrid(X, Y)``. In this case ``len(X)`` and ``len(Y)``
- must match the column and row dimensions of *U* and *V*.
-
-U, V : 1D or 2D array-like
- The x and y direction components of the arrow vectors. The interpretation
- of these components (in data or in screen space) depends on *angles*.
-
- *U* and *V* must have the same number of elements, matching the number of
- arrow locations in *X*, *Y*. *U* and *V* may be masked. Locations masked
- in any of *U*, *V*, and *C* will not be drawn.
-
-C : 1D or 2D array-like, optional
- Numeric data that defines the arrow colors by colormapping via *norm* and
- *cmap*.
-
- This does not support explicit colors. If you want to set colors directly,
- use *color* instead. The size of *C* must match the number of arrow
- locations.
-
-angles : {'uv', 'xy'} or array-like, default: 'uv'
- Method for determining the angle of the arrows.
-
- - 'uv': Arrow direction in screen coordinates. Use this if the arrows
- symbolize a quantity that is not based on *X*, *Y* data coordinates.
-
- If *U* == *V* the orientation of the arrow on the plot is 45 degrees
- counter-clockwise from the horizontal axis (positive to the right).
-
- - 'xy': Arrow direction in data coordinates, i.e. the arrows point from
- (x, y) to (x+u, y+v). Use this e.g. for plotting a gradient field.
-
- - Arbitrary angles may be specified explicitly as an array of values
- in degrees, counter-clockwise from the horizontal axis.
-
- In this case *U*, *V* is only used to determine the length of the
- arrows.
-
- Note: inverting a data axis will correspondingly invert the
- arrows only with ``angles='xy'``.
-
-pivot : {'tail', 'mid', 'middle', 'tip'}, default: 'tail'
- The part of the arrow that is anchored to the *X*, *Y* grid. The arrow
- rotates about this point.
-
- 'mid' is a synonym for 'middle'.
-
-scale : float, optional
- Scales the length of the arrow inversely.
-
- Number of data units per arrow length unit, e.g., m/s per plot width; a
- smaller scale parameter makes the arrow longer. Default is *None*.
-
- If *None*, a simple autoscaling algorithm is used, based on the average
- vector length and the number of vectors. The arrow length unit is given by
- the *scale_units* parameter.
-
-scale_units : {'width', 'height', 'dots', 'inches', 'x', 'y', 'xy'}, optional
- If the *scale* kwarg is *None*, the arrow length unit. Default is *None*.
-
- e.g. *scale_units* is 'inches', *scale* is 2.0, and ``(u, v) = (1, 0)``,
- then the vector will be 0.5 inches long.
-
- If *scale_units* is 'width' or 'height', then the vector will be half the
- width/height of the axes.
-
- If *scale_units* is 'x' then the vector will be 0.5 x-axis
- units. To plot vectors in the x-y plane, with u and v having
- the same units as x and y, use
- ``angles='xy', scale_units='xy', scale=1``.
-
-units : {'width', 'height', 'dots', 'inches', 'x', 'y', 'xy'}, default: 'width'
- Affects the arrow size (except for the length). In particular, the shaft
- *width* is measured in multiples of this unit.
-
- Supported values are:
-
- - 'width', 'height': The width or height of the Axes.
- - 'dots', 'inches': Pixels or inches based on the figure dpi.
- - 'x', 'y', 'xy': *X*, *Y* or :math:`\\sqrt{X^2 + Y^2}` in data units.
-
- The following table summarizes how these values affect the visible arrow
- size under zooming and figure size changes:
-
- ================= ================= ==================
- units zoom figure size change
- ================= ================= ==================
- 'x', 'y', 'xy' arrow size scales —
- 'width', 'height' — arrow size scales
- 'dots', 'inches' — —
- ================= ================= ==================
-
-width : float, optional
- Shaft width in arrow units. All head parameters are relative to *width*.
-
- The default depends on choice of *units* above, and number of vectors;
- a typical starting value is about 0.005 times the width of the plot.
-
-headwidth : float, default: 3
- Head width as multiple of shaft *width*. See the notes below.
-
-headlength : float, default: 5
- Head length as multiple of shaft *width*. See the notes below.
-
-headaxislength : float, default: 4.5
- Head length at shaft intersection as multiple of shaft *width*.
- See the notes below.
-
-minshaft : float, default: 1
- Length below which arrow scales, in units of head length. Do not
- set this to less than 1, or small arrows will look terrible!
-
-minlength : float, default: 1
- Minimum length as a multiple of shaft width; if an arrow length
- is less than this, plot a dot (hexagon) of this diameter instead.
-
-color : color or color sequence, optional
- Explicit color(s) for the arrows. If *C* has been set, *color* has no
- effect.
-
- This is a synonym for the `.PolyCollection` *facecolor* parameter.
-
-Other Parameters
-----------------
-data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
-**kwargs : `~matplotlib.collections.PolyCollection` properties, optional
- All other keyword arguments are passed on to `.PolyCollection`:
-
- %(PolyCollection:kwdoc)s
-
-Returns
--------
-`~matplotlib.quiver.Quiver`
-
-See Also
---------
-.Axes.quiverkey : Add a key to a quiver plot.
-
-Notes
------
-
-**Arrow shape**
-
-The arrow is drawn as a polygon using the nodes as shown below. The values
-*headwidth*, *headlength*, and *headaxislength* are in units of *width*.
-
-.. image:: /_static/quiver_sizes.svg
- :width: 500px
-
-The defaults give a slightly swept-back arrow. Here are some guidelines how to
-get other head shapes:
-
-- To make the head a triangle, make *headaxislength* the same as *headlength*.
-- To make the arrow more pointed, reduce *headwidth* or increase *headlength*
- and *headaxislength*.
-- To make the head smaller relative to the shaft, scale down all the head
- parameters proportionally.
-- To remove the head completely, set all *head* parameters to 0.
-- To get a diamond-shaped head, make *headaxislength* larger than *headlength*.
-- Warning: For *headaxislength* < (*headlength* / *headwidth*), the "headaxis"
- nodes (i.e. the ones connecting the head with the shaft) will protrude out
- of the head in forward direction so that the arrow head looks broken.
-""" % _docstring.interpd.params
-
-_docstring.interpd.update(quiver_doc=_quiver_doc)
-
-
-class QuiverKey(martist.Artist):
- """Labelled arrow for use as a quiver plot scale key."""
- halign = {'N': 'center', 'S': 'center', 'E': 'left', 'W': 'right'}
- valign = {'N': 'bottom', 'S': 'top', 'E': 'center', 'W': 'center'}
- pivot = {'N': 'middle', 'S': 'middle', 'E': 'tip', 'W': 'tail'}
-
- def __init__(self, Q, X, Y, U, label,
- *, angle=0, coordinates='axes', color=None, labelsep=0.1,
- labelpos='N', labelcolor=None, fontproperties=None, **kwargs):
- """
- Add a key to a quiver plot.
-
- The positioning of the key depends on *X*, *Y*, *coordinates*, and
- *labelpos*. If *labelpos* is 'N' or 'S', *X*, *Y* give the position of
- the middle of the key arrow. If *labelpos* is 'E', *X*, *Y* positions
- the head, and if *labelpos* is 'W', *X*, *Y* positions the tail; in
- either of these two cases, *X*, *Y* is somewhere in the middle of the
- arrow+label key object.
-
- Parameters
- ----------
- Q : `~matplotlib.quiver.Quiver`
- A `.Quiver` object as returned by a call to `~.Axes.quiver()`.
- X, Y : float
- The location of the key.
- U : float
- The length of the key.
- label : str
- The key label (e.g., length and units of the key).
- angle : float, default: 0
- The angle of the key arrow, in degrees anti-clockwise from the
- x-axis.
- coordinates : {'axes', 'figure', 'data', 'inches'}, default: 'axes'
- Coordinate system and units for *X*, *Y*: 'axes' and 'figure' are
- normalized coordinate systems with (0, 0) in the lower left and
- (1, 1) in the upper right; 'data' are the axes data coordinates
- (used for the locations of the vectors in the quiver plot itself);
- 'inches' is position in the figure in inches, with (0, 0) at the
- lower left corner.
- color : color
- Overrides face and edge colors from *Q*.
- labelpos : {'N', 'S', 'E', 'W'}
- Position the label above, below, to the right, to the left of the
- arrow, respectively.
- labelsep : float, default: 0.1
- Distance in inches between the arrow and the label.
- labelcolor : color, default: :rc:`text.color`
- Label color.
- fontproperties : dict, optional
- A dictionary with keyword arguments accepted by the
- `~matplotlib.font_manager.FontProperties` initializer:
- *family*, *style*, *variant*, *size*, *weight*.
- **kwargs
- Any additional keyword arguments are used to override vector
- properties taken from *Q*.
- """
- super().__init__()
- self.Q = Q
- self.X = X
- self.Y = Y
- self.U = U
- self.angle = angle
- self.coord = coordinates
- self.color = color
- self.label = label
- self._labelsep_inches = labelsep
-
- self.labelpos = labelpos
- self.labelcolor = labelcolor
- self.fontproperties = fontproperties or dict()
- self.kw = kwargs
- self.text = mtext.Text(
- text=label,
- horizontalalignment=self.halign[self.labelpos],
- verticalalignment=self.valign[self.labelpos],
- fontproperties=self.fontproperties)
- if self.labelcolor is not None:
- self.text.set_color(self.labelcolor)
- self._dpi_at_last_init = None
- self.zorder = Q.zorder + 0.1
-
- @property
- def labelsep(self):
- return self._labelsep_inches * self.Q.axes.figure.dpi
-
- def _init(self):
- if True: # self._dpi_at_last_init != self.axes.figure.dpi
- if self.Q._dpi_at_last_init != self.Q.axes.figure.dpi:
- self.Q._init()
- self._set_transform()
- with cbook._setattr_cm(self.Q, pivot=self.pivot[self.labelpos],
- # Hack: save and restore the Umask
- Umask=ma.nomask):
- u = self.U * np.cos(np.radians(self.angle))
- v = self.U * np.sin(np.radians(self.angle))
- angle = (self.Q.angles if isinstance(self.Q.angles, str)
- else 'uv')
- self.verts = self.Q._make_verts(
- np.array([u]), np.array([v]), angle)
- kwargs = self.Q.polykw
- kwargs.update(self.kw)
- self.vector = mcollections.PolyCollection(
- self.verts,
- offsets=[(self.X, self.Y)],
- offset_transform=self.get_transform(),
- **kwargs)
- if self.color is not None:
- self.vector.set_color(self.color)
- self.vector.set_transform(self.Q.get_transform())
- self.vector.set_figure(self.get_figure())
- self._dpi_at_last_init = self.Q.axes.figure.dpi
-
- def _text_shift(self):
- return {
- "N": (0, +self.labelsep),
- "S": (0, -self.labelsep),
- "E": (+self.labelsep, 0),
- "W": (-self.labelsep, 0),
- }[self.labelpos]
-
- @martist.allow_rasterization
- def draw(self, renderer):
- self._init()
- self.vector.draw(renderer)
- pos = self.get_transform().transform((self.X, self.Y))
- self.text.set_position(pos + self._text_shift())
- self.text.draw(renderer)
- self.stale = False
-
- def _set_transform(self):
- self.set_transform(_api.check_getitem({
- "data": self.Q.axes.transData,
- "axes": self.Q.axes.transAxes,
- "figure": self.Q.axes.figure.transFigure,
- "inches": self.Q.axes.figure.dpi_scale_trans,
- }, coordinates=self.coord))
-
- def set_figure(self, fig):
- super().set_figure(fig)
- self.text.set_figure(fig)
-
- def contains(self, mouseevent):
- if self._different_canvas(mouseevent):
- return False, {}
- # Maybe the dictionary should allow one to
- # distinguish between a text hit and a vector hit.
- if (self.text.contains(mouseevent)[0] or
- self.vector.contains(mouseevent)[0]):
- return True, {}
- return False, {}
-
-
-def _parse_args(*args, caller_name='function'):
- """
- Helper function to parse positional parameters for colored vector plots.
-
- This is currently used for Quiver and Barbs.
-
- Parameters
- ----------
- *args : list
- list of 2-5 arguments. Depending on their number they are parsed to::
-
- U, V
- U, V, C
- X, Y, U, V
- X, Y, U, V, C
-
- caller_name : str
- Name of the calling method (used in error messages).
- """
- X = Y = C = None
-
- nargs = len(args)
- if nargs == 2:
- # The use of atleast_1d allows for handling scalar arguments while also
- # keeping masked arrays
- U, V = np.atleast_1d(*args)
- elif nargs == 3:
- U, V, C = np.atleast_1d(*args)
- elif nargs == 4:
- X, Y, U, V = np.atleast_1d(*args)
- elif nargs == 5:
- X, Y, U, V, C = np.atleast_1d(*args)
- else:
- raise _api.nargs_error(caller_name, takes="from 2 to 5", given=nargs)
-
- nr, nc = (1, U.shape[0]) if U.ndim == 1 else U.shape
-
- if X is not None:
- X = X.ravel()
- Y = Y.ravel()
- if len(X) == nc and len(Y) == nr:
- X, Y = [a.ravel() for a in np.meshgrid(X, Y)]
- elif len(X) != len(Y):
- raise ValueError('X and Y must be the same size, but '
- f'X.size is {X.size} and Y.size is {Y.size}.')
- else:
- indexgrid = np.meshgrid(np.arange(nc), np.arange(nr))
- X, Y = [np.ravel(a) for a in indexgrid]
- # Size validation for U, V, C is left to the set_UVC method.
- return X, Y, U, V, C
-
-
-def _check_consistent_shapes(*arrays):
- all_shapes = {a.shape for a in arrays}
- if len(all_shapes) != 1:
- raise ValueError('The shapes of the passed in arrays do not match')
-
-
-class Quiver(mcollections.PolyCollection):
- """
- Specialized PolyCollection for arrows.
-
- The only API method is set_UVC(), which can be used
- to change the size, orientation, and color of the
- arrows; their locations are fixed when the class is
- instantiated. Possibly this method will be useful
- in animations.
-
- Much of the work in this class is done in the draw()
- method so that as much information as possible is available
- about the plot. In subsequent draw() calls, recalculation
- is limited to things that might have changed, so there
- should be no performance penalty from putting the calculations
- in the draw() method.
- """
-
- _PIVOT_VALS = ('tail', 'middle', 'tip')
-
- @_docstring.Substitution(_quiver_doc)
- def __init__(self, ax, *args,
- scale=None, headwidth=3, headlength=5, headaxislength=4.5,
- minshaft=1, minlength=1, units='width', scale_units=None,
- angles='uv', width=None, color='k', pivot='tail', **kwargs):
- """
- The constructor takes one required argument, an Axes
- instance, followed by the args and kwargs described
- by the following pyplot interface documentation:
- %s
- """
- self._axes = ax # The attr actually set by the Artist.axes property.
- X, Y, U, V, C = _parse_args(*args, caller_name='quiver')
- self.X = X
- self.Y = Y
- self.XY = np.column_stack((X, Y))
- self.N = len(X)
- self.scale = scale
- self.headwidth = headwidth
- self.headlength = float(headlength)
- self.headaxislength = headaxislength
- self.minshaft = minshaft
- self.minlength = minlength
- self.units = units
- self.scale_units = scale_units
- self.angles = angles
- self.width = width
-
- if pivot.lower() == 'mid':
- pivot = 'middle'
- self.pivot = pivot.lower()
- _api.check_in_list(self._PIVOT_VALS, pivot=self.pivot)
-
- self.transform = kwargs.pop('transform', ax.transData)
- kwargs.setdefault('facecolors', color)
- kwargs.setdefault('linewidths', (0,))
- super().__init__([], offsets=self.XY, offset_transform=self.transform,
- closed=False, **kwargs)
- self.polykw = kwargs
- self.set_UVC(U, V, C)
- self._dpi_at_last_init = None
-
- def _init(self):
- """
- Initialization delayed until first draw;
- allow time for axes setup.
- """
- # It seems that there are not enough event notifications
- # available to have this work on an as-needed basis at present.
- if True: # self._dpi_at_last_init != self.axes.figure.dpi
- trans = self._set_transform()
- self.span = trans.inverted().transform_bbox(self.axes.bbox).width
- if self.width is None:
- sn = np.clip(math.sqrt(self.N), 8, 25)
- self.width = 0.06 * self.span / sn
-
- # _make_verts sets self.scale if not already specified
- if (self._dpi_at_last_init != self.axes.figure.dpi
- and self.scale is None):
- self._make_verts(self.U, self.V, self.angles)
-
- self._dpi_at_last_init = self.axes.figure.dpi
-
- def get_datalim(self, transData):
- trans = self.get_transform()
- offset_trf = self.get_offset_transform()
- full_transform = (trans - transData) + (offset_trf - transData)
- XY = full_transform.transform(self.XY)
- bbox = transforms.Bbox.null()
- bbox.update_from_data_xy(XY, ignore=True)
- return bbox
-
- @martist.allow_rasterization
- def draw(self, renderer):
- self._init()
- verts = self._make_verts(self.U, self.V, self.angles)
- self.set_verts(verts, closed=False)
- super().draw(renderer)
- self.stale = False
-
- def set_UVC(self, U, V, C=None):
- # We need to ensure we have a copy, not a reference
- # to an array that might change before draw().
- U = ma.masked_invalid(U, copy=True).ravel()
- V = ma.masked_invalid(V, copy=True).ravel()
- if C is not None:
- C = ma.masked_invalid(C, copy=True).ravel()
- for name, var in zip(('U', 'V', 'C'), (U, V, C)):
- if not (var is None or var.size == self.N or var.size == 1):
- raise ValueError(f'Argument {name} has a size {var.size}'
- f' which does not match {self.N},'
- ' the number of arrow positions')
-
- mask = ma.mask_or(U.mask, V.mask, copy=False, shrink=True)
- if C is not None:
- mask = ma.mask_or(mask, C.mask, copy=False, shrink=True)
- if mask is ma.nomask:
- C = C.filled()
- else:
- C = ma.array(C, mask=mask, copy=False)
- self.U = U.filled(1)
- self.V = V.filled(1)
- self.Umask = mask
- if C is not None:
- self.set_array(C)
- self.stale = True
-
- def _dots_per_unit(self, units):
- """Return a scale factor for converting from units to pixels."""
- bb = self.axes.bbox
- vl = self.axes.viewLim
- return _api.check_getitem({
- 'x': bb.width / vl.width,
- 'y': bb.height / vl.height,
- 'xy': np.hypot(*bb.size) / np.hypot(*vl.size),
- 'width': bb.width,
- 'height': bb.height,
- 'dots': 1.,
- 'inches': self.axes.figure.dpi,
- }, units=units)
-
- def _set_transform(self):
- """
- Set the PolyCollection transform to go
- from arrow width units to pixels.
- """
- dx = self._dots_per_unit(self.units)
- self._trans_scale = dx # pixels per arrow width unit
- trans = transforms.Affine2D().scale(dx)
- self.set_transform(trans)
- return trans
-
- def _angles_lengths(self, U, V, eps=1):
- xy = self.axes.transData.transform(self.XY)
- uv = np.column_stack((U, V))
- xyp = self.axes.transData.transform(self.XY + eps * uv)
- dxy = xyp - xy
- angles = np.arctan2(dxy[:, 1], dxy[:, 0])
- lengths = np.hypot(*dxy.T) / eps
- return angles, lengths
-
- def _make_verts(self, U, V, angles):
- uv = (U + V * 1j)
- str_angles = angles if isinstance(angles, str) else ''
- if str_angles == 'xy' and self.scale_units == 'xy':
- # Here eps is 1 so that if we get U, V by diffing
- # the X, Y arrays, the vectors will connect the
- # points, regardless of the axis scaling (including log).
- angles, lengths = self._angles_lengths(U, V, eps=1)
- elif str_angles == 'xy' or self.scale_units == 'xy':
- # Calculate eps based on the extents of the plot
- # so that we don't end up with roundoff error from
- # adding a small number to a large.
- eps = np.abs(self.axes.dataLim.extents).max() * 0.001
- angles, lengths = self._angles_lengths(U, V, eps=eps)
- if str_angles and self.scale_units == 'xy':
- a = lengths
- else:
- a = np.abs(uv)
- if self.scale is None:
- sn = max(10, math.sqrt(self.N))
- if self.Umask is not ma.nomask:
- amean = a[~self.Umask].mean()
- else:
- amean = a.mean()
- # crude auto-scaling
- # scale is typical arrow length as a multiple of the arrow width
- scale = 1.8 * amean * sn / self.span
- if self.scale_units is None:
- if self.scale is None:
- self.scale = scale
- widthu_per_lenu = 1.0
- else:
- if self.scale_units == 'xy':
- dx = 1
- else:
- dx = self._dots_per_unit(self.scale_units)
- widthu_per_lenu = dx / self._trans_scale
- if self.scale is None:
- self.scale = scale * widthu_per_lenu
- length = a * (widthu_per_lenu / (self.scale * self.width))
- X, Y = self._h_arrows(length)
- if str_angles == 'xy':
- theta = angles
- elif str_angles == 'uv':
- theta = np.angle(uv)
- else:
- theta = ma.masked_invalid(np.deg2rad(angles)).filled(0)
- theta = theta.reshape((-1, 1)) # for broadcasting
- xy = (X + Y * 1j) * np.exp(1j * theta) * self.width
- XY = np.stack((xy.real, xy.imag), axis=2)
- if self.Umask is not ma.nomask:
- XY = ma.array(XY)
- XY[self.Umask] = ma.masked
- # This might be handled more efficiently with nans, given
- # that nans will end up in the paths anyway.
-
- return XY
-
- def _h_arrows(self, length):
- """Length is in arrow width units."""
- # It might be possible to streamline the code
- # and speed it up a bit by using complex (x, y)
- # instead of separate arrays; but any gain would be slight.
- minsh = self.minshaft * self.headlength
- N = len(length)
- length = length.reshape(N, 1)
- # This number is chosen based on when pixel values overflow in Agg
- # causing rendering errors
- # length = np.minimum(length, 2 ** 16)
- np.clip(length, 0, 2 ** 16, out=length)
- # x, y: normal horizontal arrow
- x = np.array([0, -self.headaxislength,
- -self.headlength, 0],
- np.float64)
- x = x + np.array([0, 1, 1, 1]) * length
- y = 0.5 * np.array([1, 1, self.headwidth, 0], np.float64)
- y = np.repeat(y[np.newaxis, :], N, axis=0)
- # x0, y0: arrow without shaft, for short vectors
- x0 = np.array([0, minsh - self.headaxislength,
- minsh - self.headlength, minsh], np.float64)
- y0 = 0.5 * np.array([1, 1, self.headwidth, 0], np.float64)
- ii = [0, 1, 2, 3, 2, 1, 0, 0]
- X = x[:, ii]
- Y = y[:, ii]
- Y[:, 3:-1] *= -1
- X0 = x0[ii]
- Y0 = y0[ii]
- Y0[3:-1] *= -1
- shrink = length / minsh if minsh != 0. else 0.
- X0 = shrink * X0[np.newaxis, :]
- Y0 = shrink * Y0[np.newaxis, :]
- short = np.repeat(length < minsh, 8, axis=1)
- # Now select X0, Y0 if short, otherwise X, Y
- np.copyto(X, X0, where=short)
- np.copyto(Y, Y0, where=short)
- if self.pivot == 'middle':
- X -= 0.5 * X[:, 3, np.newaxis]
- elif self.pivot == 'tip':
- # numpy bug? using -= does not work here unless we multiply by a
- # float first, as with 'mid'.
- X = X - X[:, 3, np.newaxis]
- elif self.pivot != 'tail':
- _api.check_in_list(["middle", "tip", "tail"], pivot=self.pivot)
-
- tooshort = length < self.minlength
- if tooshort.any():
- # Use a heptagonal dot:
- th = np.arange(0, 8, 1, np.float64) * (np.pi / 3.0)
- x1 = np.cos(th) * self.minlength * 0.5
- y1 = np.sin(th) * self.minlength * 0.5
- X1 = np.repeat(x1[np.newaxis, :], N, axis=0)
- Y1 = np.repeat(y1[np.newaxis, :], N, axis=0)
- tooshort = np.repeat(tooshort, 8, 1)
- np.copyto(X, X1, where=tooshort)
- np.copyto(Y, Y1, where=tooshort)
- # Mask handling is deferred to the caller, _make_verts.
- return X, Y
-
- quiver_doc = _api.deprecated("3.7")(property(lambda self: _quiver_doc))
-
-
-_barbs_doc = r"""
-Plot a 2D field of barbs.
-
-Call signature::
-
- barbs([X, Y], U, V, [C], **kwargs)
-
-Where *X*, *Y* define the barb locations, *U*, *V* define the barb
-directions, and *C* optionally sets the color.
-
-All arguments may be 1D or 2D. *U*, *V*, *C* may be masked arrays, but masked
-*X*, *Y* are not supported at present.
-
-Barbs are traditionally used in meteorology as a way to plot the speed
-and direction of wind observations, but can technically be used to
-plot any two dimensional vector quantity. As opposed to arrows, which
-give vector magnitude by the length of the arrow, the barbs give more
-quantitative information about the vector magnitude by putting slanted
-lines or a triangle for various increments in magnitude, as show
-schematically below::
-
- : /\ \
- : / \ \
- : / \ \ \
- : / \ \ \
- : ------------------------------
-
-The largest increment is given by a triangle (or "flag"). After those
-come full lines (barbs). The smallest increment is a half line. There
-is only, of course, ever at most 1 half line. If the magnitude is
-small and only needs a single half-line and no full lines or
-triangles, the half-line is offset from the end of the barb so that it
-can be easily distinguished from barbs with a single full line. The
-magnitude for the barb shown above would nominally be 65, using the
-standard increments of 50, 10, and 5.
-
-See also https://en.wikipedia.org/wiki/Wind_barb.
-
-Parameters
-----------
-X, Y : 1D or 2D array-like, optional
- The x and y coordinates of the barb locations. See *pivot* for how the
- barbs are drawn to the x, y positions.
-
- If not given, they will be generated as a uniform integer meshgrid based
- on the dimensions of *U* and *V*.
-
- If *X* and *Y* are 1D but *U*, *V* are 2D, *X*, *Y* are expanded to 2D
- using ``X, Y = np.meshgrid(X, Y)``. In this case ``len(X)`` and ``len(Y)``
- must match the column and row dimensions of *U* and *V*.
-
-U, V : 1D or 2D array-like
- The x and y components of the barb shaft.
-
-C : 1D or 2D array-like, optional
- Numeric data that defines the barb colors by colormapping via *norm* and
- *cmap*.
-
- This does not support explicit colors. If you want to set colors directly,
- use *barbcolor* instead.
-
-length : float, default: 7
- Length of the barb in points; the other parts of the barb
- are scaled against this.
-
-pivot : {'tip', 'middle'} or float, default: 'tip'
- The part of the arrow that is anchored to the *X*, *Y* grid. The barb
- rotates about this point. This can also be a number, which shifts the
- start of the barb that many points away from grid point.
-
-barbcolor : color or color sequence
- The color of all parts of the barb except for the flags. This parameter
- is analogous to the *edgecolor* parameter for polygons, which can be used
- instead. However this parameter will override facecolor.
-
-flagcolor : color or color sequence
- The color of any flags on the barb. This parameter is analogous to the
- *facecolor* parameter for polygons, which can be used instead. However,
- this parameter will override facecolor. If this is not set (and *C* has
- not either) then *flagcolor* will be set to match *barbcolor* so that the
- barb has a uniform color. If *C* has been set, *flagcolor* has no effect.
-
-sizes : dict, optional
- A dictionary of coefficients specifying the ratio of a given
- feature to the length of the barb. Only those values one wishes to
- override need to be included. These features include:
-
- - 'spacing' - space between features (flags, full/half barbs)
- - 'height' - height (distance from shaft to top) of a flag or full barb
- - 'width' - width of a flag, twice the width of a full barb
- - 'emptybarb' - radius of the circle used for low magnitudes
-
-fill_empty : bool, default: False
- Whether the empty barbs (circles) that are drawn should be filled with
- the flag color. If they are not filled, the center is transparent.
-
-rounding : bool, default: True
- Whether the vector magnitude should be rounded when allocating barb
- components. If True, the magnitude is rounded to the nearest multiple
- of the half-barb increment. If False, the magnitude is simply truncated
- to the next lowest multiple.
-
-barb_increments : dict, optional
- A dictionary of increments specifying values to associate with
- different parts of the barb. Only those values one wishes to
- override need to be included.
-
- - 'half' - half barbs (Default is 5)
- - 'full' - full barbs (Default is 10)
- - 'flag' - flags (default is 50)
-
-flip_barb : bool or array-like of bool, default: False
- Whether the lines and flags should point opposite to normal.
- Normal behavior is for the barbs and lines to point right (comes from wind
- barbs having these features point towards low pressure in the Northern
- Hemisphere).
-
- A single value is applied to all barbs. Individual barbs can be flipped by
- passing a bool array of the same size as *U* and *V*.
-
-Returns
--------
-barbs : `~matplotlib.quiver.Barbs`
-
-Other Parameters
-----------------
-data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
-**kwargs
- The barbs can further be customized using `.PolyCollection` keyword
- arguments:
-
- %(PolyCollection:kwdoc)s
-""" % _docstring.interpd.params
-
-_docstring.interpd.update(barbs_doc=_barbs_doc)
-
-
-class Barbs(mcollections.PolyCollection):
- """
- Specialized PolyCollection for barbs.
-
- The only API method is :meth:`set_UVC`, which can be used to
- change the size, orientation, and color of the arrows. Locations
- are changed using the :meth:`set_offsets` collection method.
- Possibly this method will be useful in animations.
-
- There is one internal function :meth:`_find_tails` which finds
- exactly what should be put on the barb given the vector magnitude.
- From there :meth:`_make_barbs` is used to find the vertices of the
- polygon to represent the barb based on this information.
- """
-
- # This may be an abuse of polygons here to render what is essentially maybe
- # 1 triangle and a series of lines. It works fine as far as I can tell
- # however.
-
- @_docstring.interpd
- def __init__(self, ax, *args,
- pivot='tip', length=7, barbcolor=None, flagcolor=None,
- sizes=None, fill_empty=False, barb_increments=None,
- rounding=True, flip_barb=False, **kwargs):
- """
- The constructor takes one required argument, an Axes
- instance, followed by the args and kwargs described
- by the following pyplot interface documentation:
- %(barbs_doc)s
- """
- self.sizes = sizes or dict()
- self.fill_empty = fill_empty
- self.barb_increments = barb_increments or dict()
- self.rounding = rounding
- self.flip = np.atleast_1d(flip_barb)
- transform = kwargs.pop('transform', ax.transData)
- self._pivot = pivot
- self._length = length
-
- # Flagcolor and barbcolor provide convenience parameters for
- # setting the facecolor and edgecolor, respectively, of the barb
- # polygon. We also work here to make the flag the same color as the
- # rest of the barb by default
-
- if None in (barbcolor, flagcolor):
- kwargs['edgecolors'] = 'face'
- if flagcolor:
- kwargs['facecolors'] = flagcolor
- elif barbcolor:
- kwargs['facecolors'] = barbcolor
- else:
- # Set to facecolor passed in or default to black
- kwargs.setdefault('facecolors', 'k')
- else:
- kwargs['edgecolors'] = barbcolor
- kwargs['facecolors'] = flagcolor
-
- # Explicitly set a line width if we're not given one, otherwise
- # polygons are not outlined and we get no barbs
- if 'linewidth' not in kwargs and 'lw' not in kwargs:
- kwargs['linewidth'] = 1
-
- # Parse out the data arrays from the various configurations supported
- x, y, u, v, c = _parse_args(*args, caller_name='barbs')
- self.x = x
- self.y = y
- xy = np.column_stack((x, y))
-
- # Make a collection
- barb_size = self._length ** 2 / 4 # Empirically determined
- super().__init__(
- [], (barb_size,), offsets=xy, offset_transform=transform, **kwargs)
- self.set_transform(transforms.IdentityTransform())
-
- self.set_UVC(u, v, c)
-
- def _find_tails(self, mag, rounding=True, half=5, full=10, flag=50):
- """
- Find how many of each of the tail pieces is necessary.
-
- Parameters
- ----------
- mag : `~numpy.ndarray`
- Vector magnitudes; must be non-negative (and an actual ndarray).
- rounding : bool, default: True
- Whether to round or to truncate to the nearest half-barb.
- half, full, flag : float, defaults: 5, 10, 50
- Increments for a half-barb, a barb, and a flag.
-
- Returns
- -------
- n_flags, n_barbs : int array
- For each entry in *mag*, the number of flags and barbs.
- half_flag : bool array
- For each entry in *mag*, whether a half-barb is needed.
- empty_flag : bool array
- For each entry in *mag*, whether nothing is drawn.
- """
- # If rounding, round to the nearest multiple of half, the smallest
- # increment
- if rounding:
- mag = half * np.around(mag / half)
- n_flags, mag = divmod(mag, flag)
- n_barb, mag = divmod(mag, full)
- half_flag = mag >= half
- empty_flag = ~(half_flag | (n_flags > 0) | (n_barb > 0))
- return n_flags.astype(int), n_barb.astype(int), half_flag, empty_flag
-
- def _make_barbs(self, u, v, nflags, nbarbs, half_barb, empty_flag, length,
- pivot, sizes, fill_empty, flip):
- """
- Create the wind barbs.
-
- Parameters
- ----------
- u, v
- Components of the vector in the x and y directions, respectively.
-
- nflags, nbarbs, half_barb, empty_flag
- Respectively, the number of flags, number of barbs, flag for
- half a barb, and flag for empty barb, ostensibly obtained from
- :meth:`_find_tails`.
-
- length
- The length of the barb staff in points.
-
- pivot : {"tip", "middle"} or number
- The point on the barb around which the entire barb should be
- rotated. If a number, the start of the barb is shifted by that
- many points from the origin.
-
- sizes : dict
- Coefficients specifying the ratio of a given feature to the length
- of the barb. These features include:
-
- - *spacing*: space between features (flags, full/half barbs).
- - *height*: distance from shaft of top of a flag or full barb.
- - *width*: width of a flag, twice the width of a full barb.
- - *emptybarb*: radius of the circle used for low magnitudes.
-
- fill_empty : bool
- Whether the circle representing an empty barb should be filled or
- not (this changes the drawing of the polygon).
-
- flip : list of bool
- Whether the features should be flipped to the other side of the
- barb (useful for winds in the southern hemisphere).
-
- Returns
- -------
- list of arrays of vertices
- Polygon vertices for each of the wind barbs. These polygons have
- been rotated to properly align with the vector direction.
- """
-
- # These control the spacing and size of barb elements relative to the
- # length of the shaft
- spacing = length * sizes.get('spacing', 0.125)
- full_height = length * sizes.get('height', 0.4)
- full_width = length * sizes.get('width', 0.25)
- empty_rad = length * sizes.get('emptybarb', 0.15)
-
- # Controls y point where to pivot the barb.
- pivot_points = dict(tip=0.0, middle=-length / 2.)
-
- endx = 0.0
- try:
- endy = float(pivot)
- except ValueError:
- endy = pivot_points[pivot.lower()]
-
- # Get the appropriate angle for the vector components. The offset is
- # due to the way the barb is initially drawn, going down the y-axis.
- # This makes sense in a meteorological mode of thinking since there 0
- # degrees corresponds to north (the y-axis traditionally)
- angles = -(ma.arctan2(v, u) + np.pi / 2)
-
- # Used for low magnitude. We just get the vertices, so if we make it
- # out here, it can be reused. The center set here should put the
- # center of the circle at the location(offset), rather than at the
- # same point as the barb pivot; this seems more sensible.
- circ = CirclePolygon((0, 0), radius=empty_rad).get_verts()
- if fill_empty:
- empty_barb = circ
- else:
- # If we don't want the empty one filled, we make a degenerate
- # polygon that wraps back over itself
- empty_barb = np.concatenate((circ, circ[::-1]))
-
- barb_list = []
- for index, angle in np.ndenumerate(angles):
- # If the vector magnitude is too weak to draw anything, plot an
- # empty circle instead
- if empty_flag[index]:
- # We can skip the transform since the circle has no preferred
- # orientation
- barb_list.append(empty_barb)
- continue
-
- poly_verts = [(endx, endy)]
- offset = length
-
- # Handle if this barb should be flipped
- barb_height = -full_height if flip[index] else full_height
-
- # Add vertices for each flag
- for i in range(nflags[index]):
- # The spacing that works for the barbs is a little to much for
- # the flags, but this only occurs when we have more than 1
- # flag.
- if offset != length:
- offset += spacing / 2.
- poly_verts.extend(
- [[endx, endy + offset],
- [endx + barb_height, endy - full_width / 2 + offset],
- [endx, endy - full_width + offset]])
-
- offset -= full_width + spacing
-
- # Add vertices for each barb. These really are lines, but works
- # great adding 3 vertices that basically pull the polygon out and
- # back down the line
- for i in range(nbarbs[index]):
- poly_verts.extend(
- [(endx, endy + offset),
- (endx + barb_height, endy + offset + full_width / 2),
- (endx, endy + offset)])
-
- offset -= spacing
-
- # Add the vertices for half a barb, if needed
- if half_barb[index]:
- # If the half barb is the first on the staff, traditionally it
- # is offset from the end to make it easy to distinguish from a
- # barb with a full one
- if offset == length:
- poly_verts.append((endx, endy + offset))
- offset -= 1.5 * spacing
- poly_verts.extend(
- [(endx, endy + offset),
- (endx + barb_height / 2, endy + offset + full_width / 4),
- (endx, endy + offset)])
-
- # Rotate the barb according the angle. Making the barb first and
- # then rotating it made the math for drawing the barb really easy.
- # Also, the transform framework makes doing the rotation simple.
- poly_verts = transforms.Affine2D().rotate(-angle).transform(
- poly_verts)
- barb_list.append(poly_verts)
-
- return barb_list
-
- def set_UVC(self, U, V, C=None):
- # We need to ensure we have a copy, not a reference to an array that
- # might change before draw().
- self.u = ma.masked_invalid(U, copy=True).ravel()
- self.v = ma.masked_invalid(V, copy=True).ravel()
-
- # Flip needs to have the same number of entries as everything else.
- # Use broadcast_to to avoid a bloated array of identical values.
- # (can't rely on actual broadcasting)
- if len(self.flip) == 1:
- flip = np.broadcast_to(self.flip, self.u.shape)
- else:
- flip = self.flip
-
- if C is not None:
- c = ma.masked_invalid(C, copy=True).ravel()
- x, y, u, v, c, flip = cbook.delete_masked_points(
- self.x.ravel(), self.y.ravel(), self.u, self.v, c,
- flip.ravel())
- _check_consistent_shapes(x, y, u, v, c, flip)
- else:
- x, y, u, v, flip = cbook.delete_masked_points(
- self.x.ravel(), self.y.ravel(), self.u, self.v, flip.ravel())
- _check_consistent_shapes(x, y, u, v, flip)
-
- magnitude = np.hypot(u, v)
- flags, barbs, halves, empty = self._find_tails(
- magnitude, self.rounding, **self.barb_increments)
-
- # Get the vertices for each of the barbs
-
- plot_barbs = self._make_barbs(u, v, flags, barbs, halves, empty,
- self._length, self._pivot, self.sizes,
- self.fill_empty, flip)
- self.set_verts(plot_barbs)
-
- # Set the color array
- if C is not None:
- self.set_array(c)
-
- # Update the offsets in case the masked data changed
- xy = np.column_stack((x, y))
- self._offsets = xy
- self.stale = True
-
- def set_offsets(self, xy):
- """
- Set the offsets for the barb polygons. This saves the offsets passed
- in and masks them as appropriate for the existing U/V data.
-
- Parameters
- ----------
- xy : sequence of pairs of floats
- """
- self.x = xy[:, 0]
- self.y = xy[:, 1]
- x, y, u, v = cbook.delete_masked_points(
- self.x.ravel(), self.y.ravel(), self.u, self.v)
- _check_consistent_shapes(x, y, u, v)
- xy = np.column_stack((x, y))
- super().set_offsets(xy)
- self.stale = True
-
- barbs_doc = _api.deprecated("3.7")(property(lambda self: _barbs_doc))
diff --git a/contrib/python/matplotlib/py3/matplotlib/quiver.pyi b/contrib/python/matplotlib/py3/matplotlib/quiver.pyi
deleted file mode 100644
index c673c5dd3a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/quiver.pyi
+++ /dev/null
@@ -1,187 +0,0 @@
-import matplotlib.artist as martist
-import matplotlib.collections as mcollections
-from matplotlib.axes import Axes
-from matplotlib.figure import Figure
-from matplotlib.text import Text
-from matplotlib.transforms import Transform, Bbox
-
-
-import numpy as np
-from numpy.typing import ArrayLike
-from collections.abc import Sequence
-from typing import Any, Literal, overload
-from matplotlib.typing import ColorType
-
-class QuiverKey(martist.Artist):
- halign: dict[Literal["N", "S", "E", "W"], Literal["left", "center", "right"]]
- valign: dict[Literal["N", "S", "E", "W"], Literal["top", "center", "bottom"]]
- pivot: dict[Literal["N", "S", "E", "W"], Literal["middle", "tip", "tail"]]
- Q: Quiver
- X: float
- Y: float
- U: float
- angle: float
- coord: Literal["axes", "figure", "data", "inches"]
- color: ColorType | None
- label: str
- labelpos: Literal["N", "S", "E", "W"]
- labelcolor: ColorType | None
- fontproperties: dict[str, Any]
- kw: dict[str, Any]
- text: Text
- zorder: float
- def __init__(
- self,
- Q: Quiver,
- X: float,
- Y: float,
- U: float,
- label: str,
- *,
- angle: float = ...,
- coordinates: Literal["axes", "figure", "data", "inches"] = ...,
- color: ColorType | None = ...,
- labelsep: float = ...,
- labelpos: Literal["N", "S", "E", "W"] = ...,
- labelcolor: ColorType | None = ...,
- fontproperties: dict[str, Any] | None = ...,
- **kwargs
- ) -> None: ...
- @property
- def labelsep(self) -> float: ...
- def set_figure(self, fig: Figure) -> None: ...
-
-class Quiver(mcollections.PolyCollection):
- X: ArrayLike
- Y: ArrayLike
- XY: ArrayLike
- U: ArrayLike
- V: ArrayLike
- Umask: ArrayLike
- N: int
- scale: float | None
- headwidth: float
- headlength: float
- headaxislength: float
- minshaft: float
- minlength: float
- units: Literal["width", "height", "dots", "inches", "x", "y", "xy"]
- scale_units: Literal["width", "height", "dots", "inches", "x", "y", "xy"] | None
- angles: Literal["uv", "xy"] | ArrayLike
- width: float | None
- pivot: Literal["tail", "middle", "tip"]
- transform: Transform
- polykw: dict[str, Any]
-
- @overload
- def __init__(
- self,
- ax: Axes,
- U: ArrayLike,
- V: ArrayLike,
- C: ArrayLike = ...,
- *,
- scale: float | None = ...,
- headwidth: float = ...,
- headlength: float = ...,
- headaxislength: float = ...,
- minshaft: float = ...,
- minlength: float = ...,
- units: Literal["width", "height", "dots", "inches", "x", "y", "xy"] = ...,
- scale_units: Literal["width", "height", "dots", "inches", "x", "y", "xy"]
- | None = ...,
- angles: Literal["uv", "xy"] | ArrayLike = ...,
- width: float | None = ...,
- color: ColorType | Sequence[ColorType] = ...,
- pivot: Literal["tail", "mid", "middle", "tip"] = ...,
- **kwargs
- ) -> None: ...
- @overload
- def __init__(
- self,
- ax: Axes,
- X: ArrayLike,
- Y: ArrayLike,
- U: ArrayLike,
- V: ArrayLike,
- C: ArrayLike = ...,
- *,
- scale: float | None = ...,
- headwidth: float = ...,
- headlength: float = ...,
- headaxislength: float = ...,
- minshaft: float = ...,
- minlength: float = ...,
- units: Literal["width", "height", "dots", "inches", "x", "y", "xy"] = ...,
- scale_units: Literal["width", "height", "dots", "inches", "x", "y", "xy"]
- | None = ...,
- angles: Literal["uv", "xy"] | ArrayLike = ...,
- width: float | None = ...,
- color: ColorType | Sequence[ColorType] = ...,
- pivot: Literal["tail", "mid", "middle", "tip"] = ...,
- **kwargs
- ) -> None: ...
- def get_datalim(self, transData: Transform) -> Bbox: ...
- def set_UVC(
- self, U: ArrayLike, V: ArrayLike, C: ArrayLike | None = ...
- ) -> None: ...
- @property
- def quiver_doc(self) -> str: ...
-
-class Barbs(mcollections.PolyCollection):
- sizes: dict[str, float]
- fill_empty: bool
- barb_increments: dict[str, float]
- rounding: bool
- flip: np.ndarray
- x: ArrayLike
- y: ArrayLike
- u: ArrayLike
- v: ArrayLike
-
- @overload
- def __init__(
- self,
- ax: Axes,
- U: ArrayLike,
- V: ArrayLike,
- C: ArrayLike = ...,
- *,
- pivot: str = ...,
- length: int = ...,
- barbcolor: ColorType | Sequence[ColorType] | None = ...,
- flagcolor: ColorType | Sequence[ColorType] | None = ...,
- sizes: dict[str, float] | None = ...,
- fill_empty: bool = ...,
- barb_increments: dict[str, float] | None = ...,
- rounding: bool = ...,
- flip_barb: bool | ArrayLike = ...,
- **kwargs
- ) -> None: ...
- @overload
- def __init__(
- self,
- ax: Axes,
- X: ArrayLike,
- Y: ArrayLike,
- U: ArrayLike,
- V: ArrayLike,
- C: ArrayLike = ...,
- *,
- pivot: str = ...,
- length: int = ...,
- barbcolor: ColorType | Sequence[ColorType] | None = ...,
- flagcolor: ColorType | Sequence[ColorType] | None = ...,
- sizes: dict[str, float] | None = ...,
- fill_empty: bool = ...,
- barb_increments: dict[str, float] | None = ...,
- rounding: bool = ...,
- flip_barb: bool | ArrayLike = ...,
- **kwargs
- ) -> None: ...
- def set_UVC(
- self, U: ArrayLike, V: ArrayLike, C: ArrayLike | None = ...
- ) -> None: ...
- def set_offsets(self, xy: ArrayLike) -> None: ...
- @property
- def barbs_doc(self) -> str: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/rcsetup.py b/contrib/python/matplotlib/py3/matplotlib/rcsetup.py
deleted file mode 100644
index 276bb9f812..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/rcsetup.py
+++ /dev/null
@@ -1,1346 +0,0 @@
-"""
-The rcsetup module contains the validation code for customization using
-Matplotlib's rc settings.
-
-Each rc setting is assigned a function used to validate any attempted changes
-to that setting. The validation functions are defined in the rcsetup module,
-and are used to construct the rcParams global object which stores the settings
-and is referenced throughout Matplotlib.
-
-The default values of the rc settings are set in the default matplotlibrc file.
-Any additions or deletions to the parameter set listed here should also be
-propagated to the :file:`lib/matplotlib/mpl-data/matplotlibrc` in Matplotlib's
-root source directory.
-"""
-
-import ast
-from functools import lru_cache, reduce
-from numbers import Real
-import operator
-import os
-import re
-
-import numpy as np
-
-from matplotlib import _api, cbook
-from matplotlib.cbook import ls_mapper
-from matplotlib.colors import Colormap, is_color_like
-from matplotlib._fontconfig_pattern import parse_fontconfig_pattern
-from matplotlib._enums import JoinStyle, CapStyle
-
-# Don't let the original cycler collide with our validating cycler
-from cycler import Cycler, cycler as ccycler
-
-
-# The capitalized forms are needed for ipython at present; this may
-# change for later versions.
-interactive_bk = [
- 'GTK3Agg', 'GTK3Cairo', 'GTK4Agg', 'GTK4Cairo',
- 'MacOSX',
- 'nbAgg',
- 'QtAgg', 'QtCairo', 'Qt5Agg', 'Qt5Cairo',
- 'TkAgg', 'TkCairo',
- 'WebAgg',
- 'WX', 'WXAgg', 'WXCairo',
-]
-non_interactive_bk = ['agg', 'cairo',
- 'pdf', 'pgf', 'ps', 'svg', 'template']
-all_backends = interactive_bk + non_interactive_bk
-
-
-class ValidateInStrings:
- def __init__(self, key, valid, ignorecase=False, *,
- _deprecated_since=None):
- """*valid* is a list of legal strings."""
- self.key = key
- self.ignorecase = ignorecase
- self._deprecated_since = _deprecated_since
-
- def func(s):
- if ignorecase:
- return s.lower()
- else:
- return s
- self.valid = {func(k): k for k in valid}
-
- def __call__(self, s):
- if self._deprecated_since:
- name, = (k for k, v in globals().items() if v is self)
- _api.warn_deprecated(
- self._deprecated_since, name=name, obj_type="function")
- if self.ignorecase and isinstance(s, str):
- s = s.lower()
- if s in self.valid:
- return self.valid[s]
- msg = (f"{s!r} is not a valid value for {self.key}; supported values "
- f"are {[*self.valid.values()]}")
- if (isinstance(s, str)
- and (s.startswith('"') and s.endswith('"')
- or s.startswith("'") and s.endswith("'"))
- and s[1:-1] in self.valid):
- msg += "; remove quotes surrounding your string"
- raise ValueError(msg)
-
-
-@lru_cache
-def _listify_validator(scalar_validator, allow_stringlist=False, *,
- n=None, doc=None):
- def f(s):
- if isinstance(s, str):
- try:
- val = [scalar_validator(v.strip()) for v in s.split(',')
- if v.strip()]
- except Exception:
- if allow_stringlist:
- # Sometimes, a list of colors might be a single string
- # of single-letter colornames. So give that a shot.
- val = [scalar_validator(v.strip()) for v in s if v.strip()]
- else:
- raise
- # Allow any ordered sequence type -- generators, np.ndarray, pd.Series
- # -- but not sets, whose iteration order is non-deterministic.
- elif np.iterable(s) and not isinstance(s, (set, frozenset)):
- # The condition on this list comprehension will preserve the
- # behavior of filtering out any empty strings (behavior was
- # from the original validate_stringlist()), while allowing
- # any non-string/text scalar values such as numbers and arrays.
- val = [scalar_validator(v) for v in s
- if not isinstance(v, str) or v]
- else:
- raise ValueError(
- f"Expected str or other non-set iterable, but got {s}")
- if n is not None and len(val) != n:
- raise ValueError(
- f"Expected {n} values, but there are {len(val)} values in {s}")
- return val
-
- try:
- f.__name__ = f"{scalar_validator.__name__}list"
- except AttributeError: # class instance.
- f.__name__ = f"{type(scalar_validator).__name__}List"
- f.__qualname__ = f.__qualname__.rsplit(".", 1)[0] + "." + f.__name__
- f.__doc__ = doc if doc is not None else scalar_validator.__doc__
- return f
-
-
-def validate_any(s):
- return s
-validate_anylist = _listify_validator(validate_any)
-
-
-def _validate_date(s):
- try:
- np.datetime64(s)
- return s
- except ValueError:
- raise ValueError(
- f'{s!r} should be a string that can be parsed by numpy.datetime64')
-
-
-def validate_bool(b):
- """Convert b to ``bool`` or raise."""
- if isinstance(b, str):
- b = b.lower()
- if b in ('t', 'y', 'yes', 'on', 'true', '1', 1, True):
- return True
- elif b in ('f', 'n', 'no', 'off', 'false', '0', 0, False):
- return False
- else:
- raise ValueError(f'Cannot convert {b!r} to bool')
-
-
-def validate_axisbelow(s):
- try:
- return validate_bool(s)
- except ValueError:
- if isinstance(s, str):
- if s == 'line':
- return 'line'
- raise ValueError(f'{s!r} cannot be interpreted as'
- ' True, False, or "line"')
-
-
-def validate_dpi(s):
- """Confirm s is string 'figure' or convert s to float or raise."""
- if s == 'figure':
- return s
- try:
- return float(s)
- except ValueError as e:
- raise ValueError(f'{s!r} is not string "figure" and '
- f'could not convert {s!r} to float') from e
-
-
-def _make_type_validator(cls, *, allow_none=False):
- """
- Return a validator that converts inputs to *cls* or raises (and possibly
- allows ``None`` as well).
- """
-
- def validator(s):
- if (allow_none and
- (s is None or isinstance(s, str) and s.lower() == "none")):
- return None
- if cls is str and not isinstance(s, str):
- raise ValueError(f'Could not convert {s!r} to str')
- try:
- return cls(s)
- except (TypeError, ValueError) as e:
- raise ValueError(
- f'Could not convert {s!r} to {cls.__name__}') from e
-
- validator.__name__ = f"validate_{cls.__name__}"
- if allow_none:
- validator.__name__ += "_or_None"
- validator.__qualname__ = (
- validator.__qualname__.rsplit(".", 1)[0] + "." + validator.__name__)
- return validator
-
-
-validate_string = _make_type_validator(str)
-validate_string_or_None = _make_type_validator(str, allow_none=True)
-validate_stringlist = _listify_validator(
- validate_string, doc='return a list of strings')
-validate_int = _make_type_validator(int)
-validate_int_or_None = _make_type_validator(int, allow_none=True)
-validate_float = _make_type_validator(float)
-validate_float_or_None = _make_type_validator(float, allow_none=True)
-validate_floatlist = _listify_validator(
- validate_float, doc='return a list of floats')
-
-
-def _validate_pathlike(s):
- if isinstance(s, (str, os.PathLike)):
- # Store value as str because savefig.directory needs to distinguish
- # between "" (cwd) and "." (cwd, but gets updated by user selections).
- return os.fsdecode(s)
- else:
- return validate_string(s)
-
-
-def validate_fonttype(s):
- """
- Confirm that this is a Postscript or PDF font type that we know how to
- convert to.
- """
- fonttypes = {'type3': 3,
- 'truetype': 42}
- try:
- fonttype = validate_int(s)
- except ValueError:
- try:
- return fonttypes[s.lower()]
- except KeyError as e:
- raise ValueError('Supported Postscript/PDF font types are %s'
- % list(fonttypes)) from e
- else:
- if fonttype not in fonttypes.values():
- raise ValueError(
- 'Supported Postscript/PDF font types are %s' %
- list(fonttypes.values()))
- return fonttype
-
-
-_validate_standard_backends = ValidateInStrings(
- 'backend', all_backends, ignorecase=True)
-_auto_backend_sentinel = object()
-
-
-def validate_backend(s):
- backend = (
- s if s is _auto_backend_sentinel or s.startswith("module://")
- else _validate_standard_backends(s))
- return backend
-
-
-def _validate_toolbar(s):
- s = ValidateInStrings(
- 'toolbar', ['None', 'toolbar2', 'toolmanager'], ignorecase=True)(s)
- if s == 'toolmanager':
- _api.warn_external(
- "Treat the new Tool classes introduced in v1.5 as experimental "
- "for now; the API and rcParam may change in future versions.")
- return s
-
-
-def validate_color_or_inherit(s):
- """Return a valid color arg."""
- if cbook._str_equal(s, 'inherit'):
- return s
- return validate_color(s)
-
-
-def validate_color_or_auto(s):
- if cbook._str_equal(s, 'auto'):
- return s
- return validate_color(s)
-
-
-def validate_color_for_prop_cycle(s):
- # N-th color cycle syntax can't go into the color cycle.
- if isinstance(s, str) and re.match("^C[0-9]$", s):
- raise ValueError(f"Cannot put cycle reference ({s!r}) in prop_cycler")
- return validate_color(s)
-
-
-def _validate_color_or_linecolor(s):
- if cbook._str_equal(s, 'linecolor'):
- return s
- elif cbook._str_equal(s, 'mfc') or cbook._str_equal(s, 'markerfacecolor'):
- return 'markerfacecolor'
- elif cbook._str_equal(s, 'mec') or cbook._str_equal(s, 'markeredgecolor'):
- return 'markeredgecolor'
- elif s is None:
- return None
- elif isinstance(s, str) and len(s) == 6 or len(s) == 8:
- stmp = '#' + s
- if is_color_like(stmp):
- return stmp
- if s.lower() == 'none':
- return None
- elif is_color_like(s):
- return s
-
- raise ValueError(f'{s!r} does not look like a color arg')
-
-
-def validate_color(s):
- """Return a valid color arg."""
- if isinstance(s, str):
- if s.lower() == 'none':
- return 'none'
- if len(s) == 6 or len(s) == 8:
- stmp = '#' + s
- if is_color_like(stmp):
- return stmp
-
- if is_color_like(s):
- return s
-
- # If it is still valid, it must be a tuple (as a string from matplotlibrc).
- try:
- color = ast.literal_eval(s)
- except (SyntaxError, ValueError):
- pass
- else:
- if is_color_like(color):
- return color
-
- raise ValueError(f'{s!r} does not look like a color arg')
-
-
-validate_colorlist = _listify_validator(
- validate_color, allow_stringlist=True, doc='return a list of colorspecs')
-
-
-def _validate_cmap(s):
- _api.check_isinstance((str, Colormap), cmap=s)
- return s
-
-
-def validate_aspect(s):
- if s in ('auto', 'equal'):
- return s
- try:
- return float(s)
- except ValueError as e:
- raise ValueError('not a valid aspect specification') from e
-
-
-def validate_fontsize_None(s):
- if s is None or s == 'None':
- return None
- else:
- return validate_fontsize(s)
-
-
-def validate_fontsize(s):
- fontsizes = ['xx-small', 'x-small', 'small', 'medium', 'large',
- 'x-large', 'xx-large', 'smaller', 'larger']
- if isinstance(s, str):
- s = s.lower()
- if s in fontsizes:
- return s
- try:
- return float(s)
- except ValueError as e:
- raise ValueError("%s is not a valid font size. Valid font sizes "
- "are %s." % (s, ", ".join(fontsizes))) from e
-
-
-validate_fontsizelist = _listify_validator(validate_fontsize)
-
-
-def validate_fontweight(s):
- weights = [
- 'ultralight', 'light', 'normal', 'regular', 'book', 'medium', 'roman',
- 'semibold', 'demibold', 'demi', 'bold', 'heavy', 'extra bold', 'black']
- # Note: Historically, weights have been case-sensitive in Matplotlib
- if s in weights:
- return s
- try:
- return int(s)
- except (ValueError, TypeError) as e:
- raise ValueError(f'{s} is not a valid font weight.') from e
-
-
-def validate_fontstretch(s):
- stretchvalues = [
- 'ultra-condensed', 'extra-condensed', 'condensed', 'semi-condensed',
- 'normal', 'semi-expanded', 'expanded', 'extra-expanded',
- 'ultra-expanded']
- # Note: Historically, stretchvalues have been case-sensitive in Matplotlib
- if s in stretchvalues:
- return s
- try:
- return int(s)
- except (ValueError, TypeError) as e:
- raise ValueError(f'{s} is not a valid font stretch.') from e
-
-
-def validate_font_properties(s):
- parse_fontconfig_pattern(s)
- return s
-
-
-def _validate_mathtext_fallback(s):
- _fallback_fonts = ['cm', 'stix', 'stixsans']
- if isinstance(s, str):
- s = s.lower()
- if s is None or s == 'none':
- return None
- elif s.lower() in _fallback_fonts:
- return s
- else:
- raise ValueError(
- f"{s} is not a valid fallback font name. Valid fallback font "
- f"names are {','.join(_fallback_fonts)}. Passing 'None' will turn "
- "fallback off.")
-
-
-def validate_whiskers(s):
- try:
- return _listify_validator(validate_float, n=2)(s)
- except (TypeError, ValueError):
- try:
- return float(s)
- except ValueError as e:
- raise ValueError("Not a valid whisker value [float, "
- "(float, float)]") from e
-
-
-def validate_ps_distiller(s):
- if isinstance(s, str):
- s = s.lower()
- if s in ('none', None, 'false', False):
- return None
- else:
- return ValidateInStrings('ps.usedistiller', ['ghostscript', 'xpdf'])(s)
-
-
-def _validate_papersize(s):
- # Re-inline this validator when the 'auto' deprecation expires.
- s = ValidateInStrings("ps.papersize",
- ["figure", "auto", "letter", "legal", "ledger",
- *[f"{ab}{i}" for ab in "ab" for i in range(11)]],
- ignorecase=True)(s)
- if s == "auto":
- _api.warn_deprecated("3.8", name="ps.papersize='auto'",
- addendum="Pass an explicit paper type, figure, or omit "
- "the *ps.papersize* rcParam entirely.")
- return s
-
-
-# A validator dedicated to the named line styles, based on the items in
-# ls_mapper, and a list of possible strings read from Line2D.set_linestyle
-_validate_named_linestyle = ValidateInStrings(
- 'linestyle',
- [*ls_mapper.keys(), *ls_mapper.values(), 'None', 'none', ' ', ''],
- ignorecase=True)
-
-
-def _validate_linestyle(ls):
- """
- A validator for all possible line styles, the named ones *and*
- the on-off ink sequences.
- """
- if isinstance(ls, str):
- try: # Look first for a valid named line style, like '--' or 'solid'.
- return _validate_named_linestyle(ls)
- except ValueError:
- pass
- try:
- ls = ast.literal_eval(ls) # Parsing matplotlibrc.
- except (SyntaxError, ValueError):
- pass # Will error with the ValueError at the end.
-
- def _is_iterable_not_string_like(x):
- # Explicitly exclude bytes/bytearrays so that they are not
- # nonsensically interpreted as sequences of numbers (codepoints).
- return np.iterable(x) and not isinstance(x, (str, bytes, bytearray))
-
- if _is_iterable_not_string_like(ls):
- if len(ls) == 2 and _is_iterable_not_string_like(ls[1]):
- # (offset, (on, off, on, off, ...))
- offset, onoff = ls
- else:
- # For backcompat: (on, off, on, off, ...); the offset is implicit.
- offset = 0
- onoff = ls
-
- if (isinstance(offset, Real)
- and len(onoff) % 2 == 0
- and all(isinstance(elem, Real) for elem in onoff)):
- return (offset, onoff)
-
- raise ValueError(f"linestyle {ls!r} is not a valid on-off ink sequence.")
-
-
-validate_fillstyle = ValidateInStrings(
- 'markers.fillstyle', ['full', 'left', 'right', 'bottom', 'top', 'none'])
-
-
-validate_fillstylelist = _listify_validator(validate_fillstyle)
-
-
-def validate_markevery(s):
- """
- Validate the markevery property of a Line2D object.
-
- Parameters
- ----------
- s : None, int, (int, int), slice, float, (float, float), or list[int]
-
- Returns
- -------
- None, int, (int, int), slice, float, (float, float), or list[int]
- """
- # Validate s against type slice float int and None
- if isinstance(s, (slice, float, int, type(None))):
- return s
- # Validate s against type tuple
- if isinstance(s, tuple):
- if (len(s) == 2
- and (all(isinstance(e, int) for e in s)
- or all(isinstance(e, float) for e in s))):
- return s
- else:
- raise TypeError(
- "'markevery' tuple must be pair of ints or of floats")
- # Validate s against type list
- if isinstance(s, list):
- if all(isinstance(e, int) for e in s):
- return s
- else:
- raise TypeError(
- "'markevery' list must have all elements of type int")
- raise TypeError("'markevery' is of an invalid type")
-
-
-validate_markeverylist = _listify_validator(validate_markevery)
-
-
-def validate_bbox(s):
- if isinstance(s, str):
- s = s.lower()
- if s == 'tight':
- return s
- if s == 'standard':
- return None
- raise ValueError("bbox should be 'tight' or 'standard'")
- elif s is not None:
- # Backwards compatibility. None is equivalent to 'standard'.
- raise ValueError("bbox should be 'tight' or 'standard'")
- return s
-
-
-def validate_sketch(s):
- if isinstance(s, str):
- s = s.lower()
- if s == 'none' or s is None:
- return None
- try:
- return tuple(_listify_validator(validate_float, n=3)(s))
- except ValueError:
- raise ValueError("Expected a (scale, length, randomness) triplet")
-
-
-def _validate_greaterthan_minushalf(s):
- s = validate_float(s)
- if s > -0.5:
- return s
- else:
- raise RuntimeError(f'Value must be >-0.5; got {s}')
-
-
-def _validate_greaterequal0_lessequal1(s):
- s = validate_float(s)
- if 0 <= s <= 1:
- return s
- else:
- raise RuntimeError(f'Value must be >=0 and <=1; got {s}')
-
-
-def _validate_int_greaterequal0(s):
- s = validate_int(s)
- if s >= 0:
- return s
- else:
- raise RuntimeError(f'Value must be >=0; got {s}')
-
-
-def validate_hatch(s):
- r"""
- Validate a hatch pattern.
- A hatch pattern string can have any sequence of the following
- characters: ``\ / | - + * . x o O``.
- """
- if not isinstance(s, str):
- raise ValueError("Hatch pattern must be a string")
- _api.check_isinstance(str, hatch_pattern=s)
- unknown = set(s) - {'\\', '/', '|', '-', '+', '*', '.', 'x', 'o', 'O'}
- if unknown:
- raise ValueError("Unknown hatch symbol(s): %s" % list(unknown))
- return s
-
-
-validate_hatchlist = _listify_validator(validate_hatch)
-validate_dashlist = _listify_validator(validate_floatlist)
-
-
-def _validate_minor_tick_ndivs(n):
- """
- Validate ndiv parameter related to the minor ticks.
- It controls the number of minor ticks to be placed between
- two major ticks.
- """
-
- if isinstance(n, str) and n.lower() == 'auto':
- return n
- try:
- n = _validate_int_greaterequal0(n)
- return n
- except (RuntimeError, ValueError):
- pass
-
- raise ValueError("'tick.minor.ndivs' must be 'auto' or non-negative int")
-
-
-_prop_validators = {
- 'color': _listify_validator(validate_color_for_prop_cycle,
- allow_stringlist=True),
- 'linewidth': validate_floatlist,
- 'linestyle': _listify_validator(_validate_linestyle),
- 'facecolor': validate_colorlist,
- 'edgecolor': validate_colorlist,
- 'joinstyle': _listify_validator(JoinStyle),
- 'capstyle': _listify_validator(CapStyle),
- 'fillstyle': validate_fillstylelist,
- 'markerfacecolor': validate_colorlist,
- 'markersize': validate_floatlist,
- 'markeredgewidth': validate_floatlist,
- 'markeredgecolor': validate_colorlist,
- 'markevery': validate_markeverylist,
- 'alpha': validate_floatlist,
- 'marker': validate_stringlist,
- 'hatch': validate_hatchlist,
- 'dashes': validate_dashlist,
- }
-_prop_aliases = {
- 'c': 'color',
- 'lw': 'linewidth',
- 'ls': 'linestyle',
- 'fc': 'facecolor',
- 'ec': 'edgecolor',
- 'mfc': 'markerfacecolor',
- 'mec': 'markeredgecolor',
- 'mew': 'markeredgewidth',
- 'ms': 'markersize',
- }
-
-
-def cycler(*args, **kwargs):
- """
- Create a `~cycler.Cycler` object much like :func:`cycler.cycler`,
- but includes input validation.
-
- Call signatures::
-
- cycler(cycler)
- cycler(label=values[, label2=values2[, ...]])
- cycler(label, values)
-
- Form 1 copies a given `~cycler.Cycler` object.
-
- Form 2 creates a `~cycler.Cycler` which cycles over one or more
- properties simultaneously. If multiple properties are given, their
- value lists must have the same length.
-
- Form 3 creates a `~cycler.Cycler` for a single property. This form
- exists for compatibility with the original cycler. Its use is
- discouraged in favor of the kwarg form, i.e. ``cycler(label=values)``.
-
- Parameters
- ----------
- cycler : Cycler
- Copy constructor for Cycler.
-
- label : str
- The property key. Must be a valid `.Artist` property.
- For example, 'color' or 'linestyle'. Aliases are allowed,
- such as 'c' for 'color' and 'lw' for 'linewidth'.
-
- values : iterable
- Finite-length iterable of the property values. These values
- are validated and will raise a ValueError if invalid.
-
- Returns
- -------
- Cycler
- A new :class:`~cycler.Cycler` for the given properties.
-
- Examples
- --------
- Creating a cycler for a single property:
-
- >>> c = cycler(color=['red', 'green', 'blue'])
-
- Creating a cycler for simultaneously cycling over multiple properties
- (e.g. red circle, green plus, blue cross):
-
- >>> c = cycler(color=['red', 'green', 'blue'],
- ... marker=['o', '+', 'x'])
-
- """
- if args and kwargs:
- raise TypeError("cycler() can only accept positional OR keyword "
- "arguments -- not both.")
- elif not args and not kwargs:
- raise TypeError("cycler() must have positional OR keyword arguments")
-
- if len(args) == 1:
- if not isinstance(args[0], Cycler):
- raise TypeError("If only one positional argument given, it must "
- "be a Cycler instance.")
- return validate_cycler(args[0])
- elif len(args) == 2:
- pairs = [(args[0], args[1])]
- elif len(args) > 2:
- raise _api.nargs_error('cycler', '0-2', len(args))
- else:
- pairs = kwargs.items()
-
- validated = []
- for prop, vals in pairs:
- norm_prop = _prop_aliases.get(prop, prop)
- validator = _prop_validators.get(norm_prop, None)
- if validator is None:
- raise TypeError("Unknown artist property: %s" % prop)
- vals = validator(vals)
- # We will normalize the property names as well to reduce
- # the amount of alias handling code elsewhere.
- validated.append((norm_prop, vals))
-
- return reduce(operator.add, (ccycler(k, v) for k, v in validated))
-
-
-class _DunderChecker(ast.NodeVisitor):
- def visit_Attribute(self, node):
- if node.attr.startswith("__") and node.attr.endswith("__"):
- raise ValueError("cycler strings with dunders are forbidden")
- self.generic_visit(node)
-
-
-# A validator dedicated to the named legend loc
-_validate_named_legend_loc = ValidateInStrings(
- 'legend.loc',
- [
- "best",
- "upper right", "upper left", "lower left", "lower right", "right",
- "center left", "center right", "lower center", "upper center",
- "center"],
- ignorecase=True)
-
-
-def _validate_legend_loc(loc):
- """
- Confirm that loc is a type which rc.Params["legend.loc"] supports.
-
- .. versionadded:: 3.8
-
- Parameters
- ----------
- loc : str | int | (float, float) | str((float, float))
- The location of the legend.
-
- Returns
- -------
- loc : str | int | (float, float) or raise ValueError exception
- The location of the legend.
- """
- if isinstance(loc, str):
- try:
- return _validate_named_legend_loc(loc)
- except ValueError:
- pass
- try:
- loc = ast.literal_eval(loc)
- except (SyntaxError, ValueError):
- pass
- if isinstance(loc, int):
- if 0 <= loc <= 10:
- return loc
- if isinstance(loc, tuple):
- if len(loc) == 2 and all(isinstance(e, Real) for e in loc):
- return loc
- raise ValueError(f"{loc} is not a valid legend location.")
-
-
-def validate_cycler(s):
- """Return a Cycler object from a string repr or the object itself."""
- if isinstance(s, str):
- # TODO: We might want to rethink this...
- # While I think I have it quite locked down, it is execution of
- # arbitrary code without sanitation.
- # Combine this with the possibility that rcparams might come from the
- # internet (future plans), this could be downright dangerous.
- # I locked it down by only having the 'cycler()' function available.
- # UPDATE: Partly plugging a security hole.
- # I really should have read this:
- # https://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html
- # We should replace this eval with a combo of PyParsing and
- # ast.literal_eval()
- try:
- _DunderChecker().visit(ast.parse(s))
- s = eval(s, {'cycler': cycler, '__builtins__': {}})
- except BaseException as e:
- raise ValueError(f"{s!r} is not a valid cycler construction: {e}"
- ) from e
- # Should make sure what comes from the above eval()
- # is a Cycler object.
- if isinstance(s, Cycler):
- cycler_inst = s
- else:
- raise ValueError(f"Object is not a string or Cycler instance: {s!r}")
-
- unknowns = cycler_inst.keys - (set(_prop_validators) | set(_prop_aliases))
- if unknowns:
- raise ValueError("Unknown artist properties: %s" % unknowns)
-
- # Not a full validation, but it'll at least normalize property names
- # A fuller validation would require v0.10 of cycler.
- checker = set()
- for prop in cycler_inst.keys:
- norm_prop = _prop_aliases.get(prop, prop)
- if norm_prop != prop and norm_prop in cycler_inst.keys:
- raise ValueError(f"Cannot specify both {norm_prop!r} and alias "
- f"{prop!r} in the same prop_cycle")
- if norm_prop in checker:
- raise ValueError(f"Another property was already aliased to "
- f"{norm_prop!r}. Collision normalizing {prop!r}.")
- checker.update([norm_prop])
-
- # This is just an extra-careful check, just in case there is some
- # edge-case I haven't thought of.
- assert len(checker) == len(cycler_inst.keys)
-
- # Now, it should be safe to mutate this cycler
- for prop in cycler_inst.keys:
- norm_prop = _prop_aliases.get(prop, prop)
- cycler_inst.change_key(prop, norm_prop)
-
- for key, vals in cycler_inst.by_key().items():
- _prop_validators[key](vals)
-
- return cycler_inst
-
-
-def validate_hist_bins(s):
- valid_strs = ["auto", "sturges", "fd", "doane", "scott", "rice", "sqrt"]
- if isinstance(s, str) and s in valid_strs:
- return s
- try:
- return int(s)
- except (TypeError, ValueError):
- pass
- try:
- return validate_floatlist(s)
- except ValueError:
- pass
- raise ValueError(f"'hist.bins' must be one of {valid_strs}, an int or"
- " a sequence of floats")
-
-
-class _ignorecase(list):
- """A marker class indicating that a list-of-str is case-insensitive."""
-
-
-def _convert_validator_spec(key, conv):
- if isinstance(conv, list):
- ignorecase = isinstance(conv, _ignorecase)
- return ValidateInStrings(key, conv, ignorecase=ignorecase)
- else:
- return conv
-
-
-# Mapping of rcParams to validators.
-# Converters given as lists or _ignorecase are converted to ValidateInStrings
-# immediately below.
-# The rcParams defaults are defined in lib/matplotlib/mpl-data/matplotlibrc, which
-# gets copied to matplotlib/mpl-data/matplotlibrc by the setup script.
-_validators = {
- "backend": validate_backend,
- "backend_fallback": validate_bool,
- "figure.hooks": validate_stringlist,
- "toolbar": _validate_toolbar,
- "interactive": validate_bool,
- "timezone": validate_string,
-
- "webagg.port": validate_int,
- "webagg.address": validate_string,
- "webagg.open_in_browser": validate_bool,
- "webagg.port_retries": validate_int,
-
- # line props
- "lines.linewidth": validate_float, # line width in points
- "lines.linestyle": _validate_linestyle, # solid line
- "lines.color": validate_color, # first color in color cycle
- "lines.marker": validate_string, # marker name
- "lines.markerfacecolor": validate_color_or_auto, # default color
- "lines.markeredgecolor": validate_color_or_auto, # default color
- "lines.markeredgewidth": validate_float,
- "lines.markersize": validate_float, # markersize, in points
- "lines.antialiased": validate_bool, # antialiased (no jaggies)
- "lines.dash_joinstyle": JoinStyle,
- "lines.solid_joinstyle": JoinStyle,
- "lines.dash_capstyle": CapStyle,
- "lines.solid_capstyle": CapStyle,
- "lines.dashed_pattern": validate_floatlist,
- "lines.dashdot_pattern": validate_floatlist,
- "lines.dotted_pattern": validate_floatlist,
- "lines.scale_dashes": validate_bool,
-
- # marker props
- "markers.fillstyle": validate_fillstyle,
-
- ## pcolor(mesh) props:
- "pcolor.shading": ["auto", "flat", "nearest", "gouraud"],
- "pcolormesh.snap": validate_bool,
-
- ## patch props
- "patch.linewidth": validate_float, # line width in points
- "patch.edgecolor": validate_color,
- "patch.force_edgecolor": validate_bool,
- "patch.facecolor": validate_color, # first color in cycle
- "patch.antialiased": validate_bool, # antialiased (no jaggies)
-
- ## hatch props
- "hatch.color": validate_color,
- "hatch.linewidth": validate_float,
-
- ## Histogram properties
- "hist.bins": validate_hist_bins,
-
- ## Boxplot properties
- "boxplot.notch": validate_bool,
- "boxplot.vertical": validate_bool,
- "boxplot.whiskers": validate_whiskers,
- "boxplot.bootstrap": validate_int_or_None,
- "boxplot.patchartist": validate_bool,
- "boxplot.showmeans": validate_bool,
- "boxplot.showcaps": validate_bool,
- "boxplot.showbox": validate_bool,
- "boxplot.showfliers": validate_bool,
- "boxplot.meanline": validate_bool,
-
- "boxplot.flierprops.color": validate_color,
- "boxplot.flierprops.marker": validate_string,
- "boxplot.flierprops.markerfacecolor": validate_color_or_auto,
- "boxplot.flierprops.markeredgecolor": validate_color,
- "boxplot.flierprops.markeredgewidth": validate_float,
- "boxplot.flierprops.markersize": validate_float,
- "boxplot.flierprops.linestyle": _validate_linestyle,
- "boxplot.flierprops.linewidth": validate_float,
-
- "boxplot.boxprops.color": validate_color,
- "boxplot.boxprops.linewidth": validate_float,
- "boxplot.boxprops.linestyle": _validate_linestyle,
-
- "boxplot.whiskerprops.color": validate_color,
- "boxplot.whiskerprops.linewidth": validate_float,
- "boxplot.whiskerprops.linestyle": _validate_linestyle,
-
- "boxplot.capprops.color": validate_color,
- "boxplot.capprops.linewidth": validate_float,
- "boxplot.capprops.linestyle": _validate_linestyle,
-
- "boxplot.medianprops.color": validate_color,
- "boxplot.medianprops.linewidth": validate_float,
- "boxplot.medianprops.linestyle": _validate_linestyle,
-
- "boxplot.meanprops.color": validate_color,
- "boxplot.meanprops.marker": validate_string,
- "boxplot.meanprops.markerfacecolor": validate_color,
- "boxplot.meanprops.markeredgecolor": validate_color,
- "boxplot.meanprops.markersize": validate_float,
- "boxplot.meanprops.linestyle": _validate_linestyle,
- "boxplot.meanprops.linewidth": validate_float,
-
- ## font props
- "font.family": validate_stringlist, # used by text object
- "font.style": validate_string,
- "font.variant": validate_string,
- "font.stretch": validate_fontstretch,
- "font.weight": validate_fontweight,
- "font.size": validate_float, # Base font size in points
- "font.serif": validate_stringlist,
- "font.sans-serif": validate_stringlist,
- "font.cursive": validate_stringlist,
- "font.fantasy": validate_stringlist,
- "font.monospace": validate_stringlist,
-
- # text props
- "text.color": validate_color,
- "text.usetex": validate_bool,
- "text.latex.preamble": validate_string,
- "text.hinting": ["default", "no_autohint", "force_autohint",
- "no_hinting", "auto", "native", "either", "none"],
- "text.hinting_factor": validate_int,
- "text.kerning_factor": validate_int,
- "text.antialiased": validate_bool,
- "text.parse_math": validate_bool,
-
- "mathtext.cal": validate_font_properties,
- "mathtext.rm": validate_font_properties,
- "mathtext.tt": validate_font_properties,
- "mathtext.it": validate_font_properties,
- "mathtext.bf": validate_font_properties,
- "mathtext.bfit": validate_font_properties,
- "mathtext.sf": validate_font_properties,
- "mathtext.fontset": ["dejavusans", "dejavuserif", "cm", "stix",
- "stixsans", "custom"],
- "mathtext.default": ["rm", "cal", "bfit", "it", "tt", "sf", "bf", "default",
- "bb", "frak", "scr", "regular"],
- "mathtext.fallback": _validate_mathtext_fallback,
-
- "image.aspect": validate_aspect, # equal, auto, a number
- "image.interpolation": validate_string,
- "image.cmap": _validate_cmap, # gray, jet, etc.
- "image.lut": validate_int, # lookup table
- "image.origin": ["upper", "lower"],
- "image.resample": validate_bool,
- # Specify whether vector graphics backends will combine all images on a
- # set of axes into a single composite image
- "image.composite_image": validate_bool,
-
- # contour props
- "contour.negative_linestyle": _validate_linestyle,
- "contour.corner_mask": validate_bool,
- "contour.linewidth": validate_float_or_None,
- "contour.algorithm": ["mpl2005", "mpl2014", "serial", "threaded"],
-
- # errorbar props
- "errorbar.capsize": validate_float,
-
- # axis props
- # alignment of x/y axis title
- "xaxis.labellocation": ["left", "center", "right"],
- "yaxis.labellocation": ["bottom", "center", "top"],
-
- # axes props
- "axes.axisbelow": validate_axisbelow,
- "axes.facecolor": validate_color, # background color
- "axes.edgecolor": validate_color, # edge color
- "axes.linewidth": validate_float, # edge linewidth
-
- "axes.spines.left": validate_bool, # Set visibility of axes spines,
- "axes.spines.right": validate_bool, # i.e., the lines around the chart
- "axes.spines.bottom": validate_bool, # denoting data boundary.
- "axes.spines.top": validate_bool,
-
- "axes.titlesize": validate_fontsize, # axes title fontsize
- "axes.titlelocation": ["left", "center", "right"], # axes title alignment
- "axes.titleweight": validate_fontweight, # axes title font weight
- "axes.titlecolor": validate_color_or_auto, # axes title font color
- # title location, axes units, None means auto
- "axes.titley": validate_float_or_None,
- # pad from axes top decoration to title in points
- "axes.titlepad": validate_float,
- "axes.grid": validate_bool, # display grid or not
- "axes.grid.which": ["minor", "both", "major"], # which grids are drawn
- "axes.grid.axis": ["x", "y", "both"], # grid type
- "axes.labelsize": validate_fontsize, # fontsize of x & y labels
- "axes.labelpad": validate_float, # space between label and axis
- "axes.labelweight": validate_fontweight, # fontsize of x & y labels
- "axes.labelcolor": validate_color, # color of axis label
- # use scientific notation if log10 of the axis range is smaller than the
- # first or larger than the second
- "axes.formatter.limits": _listify_validator(validate_int, n=2),
- # use current locale to format ticks
- "axes.formatter.use_locale": validate_bool,
- "axes.formatter.use_mathtext": validate_bool,
- # minimum exponent to format in scientific notation
- "axes.formatter.min_exponent": validate_int,
- "axes.formatter.useoffset": validate_bool,
- "axes.formatter.offset_threshold": validate_int,
- "axes.unicode_minus": validate_bool,
- # This entry can be either a cycler object or a string repr of a
- # cycler-object, which gets eval()'ed to create the object.
- "axes.prop_cycle": validate_cycler,
- # If "data", axes limits are set close to the data.
- # If "round_numbers" axes limits are set to the nearest round numbers.
- "axes.autolimit_mode": ["data", "round_numbers"],
- "axes.xmargin": _validate_greaterthan_minushalf, # margin added to xaxis
- "axes.ymargin": _validate_greaterthan_minushalf, # margin added to yaxis
- "axes.zmargin": _validate_greaterthan_minushalf, # margin added to zaxis
-
- "polaraxes.grid": validate_bool, # display polar grid or not
- "axes3d.grid": validate_bool, # display 3d grid
-
- "axes3d.xaxis.panecolor": validate_color, # 3d background pane
- "axes3d.yaxis.panecolor": validate_color, # 3d background pane
- "axes3d.zaxis.panecolor": validate_color, # 3d background pane
-
- # scatter props
- "scatter.marker": validate_string,
- "scatter.edgecolors": validate_string,
-
- "date.epoch": _validate_date,
- "date.autoformatter.year": validate_string,
- "date.autoformatter.month": validate_string,
- "date.autoformatter.day": validate_string,
- "date.autoformatter.hour": validate_string,
- "date.autoformatter.minute": validate_string,
- "date.autoformatter.second": validate_string,
- "date.autoformatter.microsecond": validate_string,
-
- 'date.converter': ['auto', 'concise'],
- # for auto date locator, choose interval_multiples
- 'date.interval_multiples': validate_bool,
-
- # legend properties
- "legend.fancybox": validate_bool,
- "legend.loc": _validate_legend_loc,
-
- # the number of points in the legend line
- "legend.numpoints": validate_int,
- # the number of points in the legend line for scatter
- "legend.scatterpoints": validate_int,
- "legend.fontsize": validate_fontsize,
- "legend.title_fontsize": validate_fontsize_None,
- # color of the legend
- "legend.labelcolor": _validate_color_or_linecolor,
- # the relative size of legend markers vs. original
- "legend.markerscale": validate_float,
- # using dict in rcParams not yet supported, so make sure it is bool
- "legend.shadow": validate_bool,
- # whether or not to draw a frame around legend
- "legend.frameon": validate_bool,
- # alpha value of the legend frame
- "legend.framealpha": validate_float_or_None,
-
- ## the following dimensions are in fraction of the font size
- "legend.borderpad": validate_float, # units are fontsize
- # the vertical space between the legend entries
- "legend.labelspacing": validate_float,
- # the length of the legend lines
- "legend.handlelength": validate_float,
- # the length of the legend lines
- "legend.handleheight": validate_float,
- # the space between the legend line and legend text
- "legend.handletextpad": validate_float,
- # the border between the axes and legend edge
- "legend.borderaxespad": validate_float,
- # the border between the axes and legend edge
- "legend.columnspacing": validate_float,
- "legend.facecolor": validate_color_or_inherit,
- "legend.edgecolor": validate_color_or_inherit,
-
- # tick properties
- "xtick.top": validate_bool, # draw ticks on top side
- "xtick.bottom": validate_bool, # draw ticks on bottom side
- "xtick.labeltop": validate_bool, # draw label on top
- "xtick.labelbottom": validate_bool, # draw label on bottom
- "xtick.major.size": validate_float, # major xtick size in points
- "xtick.minor.size": validate_float, # minor xtick size in points
- "xtick.major.width": validate_float, # major xtick width in points
- "xtick.minor.width": validate_float, # minor xtick width in points
- "xtick.major.pad": validate_float, # distance to label in points
- "xtick.minor.pad": validate_float, # distance to label in points
- "xtick.color": validate_color, # color of xticks
- "xtick.labelcolor": validate_color_or_inherit, # color of xtick labels
- "xtick.minor.visible": validate_bool, # visibility of minor xticks
- "xtick.minor.top": validate_bool, # draw top minor xticks
- "xtick.minor.bottom": validate_bool, # draw bottom minor xticks
- "xtick.major.top": validate_bool, # draw top major xticks
- "xtick.major.bottom": validate_bool, # draw bottom major xticks
- # number of minor xticks
- "xtick.minor.ndivs": _validate_minor_tick_ndivs,
- "xtick.labelsize": validate_fontsize, # fontsize of xtick labels
- "xtick.direction": ["out", "in", "inout"], # direction of xticks
- "xtick.alignment": ["center", "right", "left"],
-
- "ytick.left": validate_bool, # draw ticks on left side
- "ytick.right": validate_bool, # draw ticks on right side
- "ytick.labelleft": validate_bool, # draw tick labels on left side
- "ytick.labelright": validate_bool, # draw tick labels on right side
- "ytick.major.size": validate_float, # major ytick size in points
- "ytick.minor.size": validate_float, # minor ytick size in points
- "ytick.major.width": validate_float, # major ytick width in points
- "ytick.minor.width": validate_float, # minor ytick width in points
- "ytick.major.pad": validate_float, # distance to label in points
- "ytick.minor.pad": validate_float, # distance to label in points
- "ytick.color": validate_color, # color of yticks
- "ytick.labelcolor": validate_color_or_inherit, # color of ytick labels
- "ytick.minor.visible": validate_bool, # visibility of minor yticks
- "ytick.minor.left": validate_bool, # draw left minor yticks
- "ytick.minor.right": validate_bool, # draw right minor yticks
- "ytick.major.left": validate_bool, # draw left major yticks
- "ytick.major.right": validate_bool, # draw right major yticks
- # number of minor yticks
- "ytick.minor.ndivs": _validate_minor_tick_ndivs,
- "ytick.labelsize": validate_fontsize, # fontsize of ytick labels
- "ytick.direction": ["out", "in", "inout"], # direction of yticks
- "ytick.alignment": [
- "center", "top", "bottom", "baseline", "center_baseline"],
-
- "grid.color": validate_color, # grid color
- "grid.linestyle": _validate_linestyle, # solid
- "grid.linewidth": validate_float, # in points
- "grid.alpha": validate_float,
-
- ## figure props
- # figure title
- "figure.titlesize": validate_fontsize,
- "figure.titleweight": validate_fontweight,
-
- # figure labels
- "figure.labelsize": validate_fontsize,
- "figure.labelweight": validate_fontweight,
-
- # figure size in inches: width by height
- "figure.figsize": _listify_validator(validate_float, n=2),
- "figure.dpi": validate_float,
- "figure.facecolor": validate_color,
- "figure.edgecolor": validate_color,
- "figure.frameon": validate_bool,
- "figure.autolayout": validate_bool,
- "figure.max_open_warning": validate_int,
- "figure.raise_window": validate_bool,
- "macosx.window_mode": ["system", "tab", "window"],
-
- "figure.subplot.left": validate_float,
- "figure.subplot.right": validate_float,
- "figure.subplot.bottom": validate_float,
- "figure.subplot.top": validate_float,
- "figure.subplot.wspace": validate_float,
- "figure.subplot.hspace": validate_float,
-
- "figure.constrained_layout.use": validate_bool, # run constrained_layout?
- # wspace and hspace are fraction of adjacent subplots to use for space.
- # Much smaller than above because we don't need room for the text.
- "figure.constrained_layout.hspace": validate_float,
- "figure.constrained_layout.wspace": validate_float,
- # buffer around the axes, in inches.
- "figure.constrained_layout.h_pad": validate_float,
- "figure.constrained_layout.w_pad": validate_float,
-
- ## Saving figure's properties
- 'savefig.dpi': validate_dpi,
- 'savefig.facecolor': validate_color_or_auto,
- 'savefig.edgecolor': validate_color_or_auto,
- 'savefig.orientation': ['landscape', 'portrait'],
- "savefig.format": validate_string,
- "savefig.bbox": validate_bbox, # "tight", or "standard" (= None)
- "savefig.pad_inches": validate_float,
- # default directory in savefig dialog box
- "savefig.directory": _validate_pathlike,
- "savefig.transparent": validate_bool,
-
- "tk.window_focus": validate_bool, # Maintain shell focus for TkAgg
-
- # Set the papersize/type
- "ps.papersize": _validate_papersize,
- "ps.useafm": validate_bool,
- # use ghostscript or xpdf to distill ps output
- "ps.usedistiller": validate_ps_distiller,
- "ps.distiller.res": validate_int, # dpi
- "ps.fonttype": validate_fonttype, # 3 (Type3) or 42 (Truetype)
- "pdf.compression": validate_int, # 0-9 compression level; 0 to disable
- "pdf.inheritcolor": validate_bool, # skip color setting commands
- # use only the 14 PDF core fonts embedded in every PDF viewing application
- "pdf.use14corefonts": validate_bool,
- "pdf.fonttype": validate_fonttype, # 3 (Type3) or 42 (Truetype)
-
- "pgf.texsystem": ["xelatex", "lualatex", "pdflatex"], # latex variant used
- "pgf.rcfonts": validate_bool, # use mpl's rc settings for font config
- "pgf.preamble": validate_string, # custom LaTeX preamble
-
- # write raster image data into the svg file
- "svg.image_inline": validate_bool,
- "svg.fonttype": ["none", "path"], # save text as text ("none") or "paths"
- "svg.hashsalt": validate_string_or_None,
-
- # set this when you want to generate hardcopy docstring
- "docstring.hardcopy": validate_bool,
-
- "path.simplify": validate_bool,
- "path.simplify_threshold": _validate_greaterequal0_lessequal1,
- "path.snap": validate_bool,
- "path.sketch": validate_sketch,
- "path.effects": validate_anylist,
- "agg.path.chunksize": validate_int, # 0 to disable chunking
-
- # key-mappings (multi-character mappings should be a list/tuple)
- "keymap.fullscreen": validate_stringlist,
- "keymap.home": validate_stringlist,
- "keymap.back": validate_stringlist,
- "keymap.forward": validate_stringlist,
- "keymap.pan": validate_stringlist,
- "keymap.zoom": validate_stringlist,
- "keymap.save": validate_stringlist,
- "keymap.quit": validate_stringlist,
- "keymap.quit_all": validate_stringlist, # e.g.: "W", "cmd+W", "Q"
- "keymap.grid": validate_stringlist,
- "keymap.grid_minor": validate_stringlist,
- "keymap.yscale": validate_stringlist,
- "keymap.xscale": validate_stringlist,
- "keymap.help": validate_stringlist,
- "keymap.copy": validate_stringlist,
-
- # Animation settings
- "animation.html": ["html5", "jshtml", "none"],
- # Limit, in MB, of size of base64 encoded animation in HTML
- # (i.e. IPython notebook)
- "animation.embed_limit": validate_float,
- "animation.writer": validate_string,
- "animation.codec": validate_string,
- "animation.bitrate": validate_int,
- # Controls image format when frames are written to disk
- "animation.frame_format": ["png", "jpeg", "tiff", "raw", "rgba", "ppm",
- "sgi", "bmp", "pbm", "svg"],
- # Path to ffmpeg binary. If just binary name, subprocess uses $PATH.
- "animation.ffmpeg_path": _validate_pathlike,
- # Additional arguments for ffmpeg movie writer (using pipes)
- "animation.ffmpeg_args": validate_stringlist,
- # Path to convert binary. If just binary name, subprocess uses $PATH.
- "animation.convert_path": _validate_pathlike,
- # Additional arguments for convert movie writer (using pipes)
- "animation.convert_args": validate_stringlist,
-
- # Classic (pre 2.0) compatibility mode
- # This is used for things that are hard to make backward compatible
- # with a sane rcParam alone. This does *not* turn on classic mode
- # altogether. For that use `matplotlib.style.use("classic")`.
- "_internal.classic_mode": validate_bool
-}
-_hardcoded_defaults = { # Defaults not inferred from
- # lib/matplotlib/mpl-data/matplotlibrc...
- # ... because they are private:
- "_internal.classic_mode": False,
- # ... because they are deprecated:
- # No current deprecations.
- # backend is handled separately when constructing rcParamsDefault.
-}
-_validators = {k: _convert_validator_spec(k, conv)
- for k, conv in _validators.items()}
diff --git a/contrib/python/matplotlib/py3/matplotlib/rcsetup.pyi b/contrib/python/matplotlib/py3/matplotlib/rcsetup.pyi
deleted file mode 100644
index 70e94a7694..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/rcsetup.pyi
+++ /dev/null
@@ -1,157 +0,0 @@
-from cycler import Cycler
-
-from collections.abc import Callable, Iterable
-from typing import Any, Literal, TypeVar
-from matplotlib.typing import ColorType, LineStyleType, MarkEveryType
-
-interactive_bk: list[str]
-non_interactive_bk: list[str]
-all_backends: list[str]
-
-_T = TypeVar("_T")
-
-def _listify_validator(s: Callable[[Any], _T]) -> Callable[[Any], list[_T]]: ...
-
-class ValidateInStrings:
- key: str
- ignorecase: bool
- valid: dict[str, str]
- def __init__(
- self,
- key: str,
- valid: Iterable[str],
- ignorecase: bool = ...,
- *,
- _deprecated_since: str | None = ...
- ) -> None: ...
- def __call__(self, s: Any) -> str: ...
-
-def validate_any(s: Any) -> Any: ...
-def validate_anylist(s: Any) -> list[Any]: ...
-def validate_bool(b: Any) -> bool: ...
-def validate_axisbelow(s: Any) -> bool | Literal["line"]: ...
-def validate_dpi(s: Any) -> Literal["figure"] | float: ...
-def validate_string(s: Any) -> str: ...
-def validate_string_or_None(s: Any) -> str | None: ...
-def validate_stringlist(s: Any) -> list[str]: ...
-def validate_int(s: Any) -> int: ...
-def validate_int_or_None(s: Any) -> int | None: ...
-def validate_float(s: Any) -> float: ...
-def validate_float_or_None(s: Any) -> float | None: ...
-def validate_floatlist(s: Any) -> list[float]: ...
-def validate_fonttype(s: Any) -> int: ...
-
-_auto_backend_sentinel: object
-
-def validate_backend(s: Any) -> str: ...
-def validate_color_or_inherit(s: Any) -> Literal["inherit"] | ColorType: ...
-def validate_color_or_auto(s: Any) -> ColorType | Literal["auto"]: ...
-def validate_color_for_prop_cycle(s: Any) -> ColorType: ...
-def validate_color(s: Any) -> ColorType: ...
-def validate_colorlist(s: Any) -> list[ColorType]: ...
-def _validate_color_or_linecolor(
- s: Any,
-) -> ColorType | Literal["linecolor", "markerfacecolor", "markeredgecolor"] | None: ...
-def validate_aspect(s: Any) -> Literal["auto", "equal"] | float: ...
-def validate_fontsize_None(
- s: Any,
-) -> Literal[
- "xx-small",
- "x-small",
- "small",
- "medium",
- "large",
- "x-large",
- "xx-large",
- "smaller",
- "larger",
-] | float | None: ...
-def validate_fontsize(
- s: Any,
-) -> Literal[
- "xx-small",
- "x-small",
- "small",
- "medium",
- "large",
- "x-large",
- "xx-large",
- "smaller",
- "larger",
-] | float: ...
-def validate_fontsizelist(
- s: Any,
-) -> list[
- Literal[
- "xx-small",
- "x-small",
- "small",
- "medium",
- "large",
- "x-large",
- "xx-large",
- "smaller",
- "larger",
- ]
- | float
-]: ...
-def validate_fontweight(
- s: Any,
-) -> Literal[
- "ultralight",
- "light",
- "normal",
- "regular",
- "book",
- "medium",
- "roman",
- "semibold",
- "demibold",
- "demi",
- "bold",
- "heavy",
- "extra bold",
- "black",
-] | int: ...
-def validate_fontstretch(
- s: Any,
-) -> Literal[
- "ultra-condensed",
- "extra-condensed",
- "condensed",
- "semi-condensed",
- "normal",
- "semi-expanded",
- "expanded",
- "extra-expanded",
- "ultra-expanded",
-] | int: ...
-def validate_font_properties(s: Any) -> dict[str, Any]: ...
-def validate_whiskers(s: Any) -> list[float] | float: ...
-def validate_ps_distiller(s: Any) -> None | Literal["ghostscript", "xpdf"]: ...
-
-validate_fillstyle: ValidateInStrings
-
-def validate_fillstylelist(
- s: Any,
-) -> list[Literal["full", "left", "right", "bottom", "top", "none"]]: ...
-def validate_markevery(s: Any) -> MarkEveryType: ...
-def _validate_linestyle(s: Any) -> LineStyleType: ...
-def validate_markeverylist(s: Any) -> list[MarkEveryType]: ...
-def validate_bbox(s: Any) -> Literal["tight", "standard"] | None: ...
-def validate_sketch(s: Any) -> None | tuple[float, float, float]: ...
-def validate_hatch(s: Any) -> str: ...
-def validate_hatchlist(s: Any) -> list[str]: ...
-def validate_dashlist(s: Any) -> list[list[float]]: ...
-
-# TODO: copy cycler overloads?
-def cycler(*args, **kwargs) -> Cycler: ...
-def validate_cycler(s: Any) -> Cycler: ...
-def validate_hist_bins(
- s: Any,
-) -> Literal["auto", "sturges", "fd", "doane", "scott", "rice", "sqrt"] | int | list[
- float
-]: ...
-
-# At runtime is added in __init__.py
-defaultParams: dict[str, Any]
diff --git a/contrib/python/matplotlib/py3/matplotlib/sankey.py b/contrib/python/matplotlib/py3/matplotlib/sankey.py
deleted file mode 100644
index b626abe307..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/sankey.py
+++ /dev/null
@@ -1,814 +0,0 @@
-"""
-Module for creating Sankey diagrams using Matplotlib.
-"""
-
-import logging
-from types import SimpleNamespace
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib.path import Path
-from matplotlib.patches import PathPatch
-from matplotlib.transforms import Affine2D
-from matplotlib import _docstring
-
-_log = logging.getLogger(__name__)
-
-__author__ = "Kevin L. Davies"
-__credits__ = ["Yannick Copin"]
-__license__ = "BSD"
-__version__ = "2011/09/16"
-
-# Angles [deg/90]
-RIGHT = 0
-UP = 1
-# LEFT = 2
-DOWN = 3
-
-
-class Sankey:
- """
- Sankey diagram.
-
- Sankey diagrams are a specific type of flow diagram, in which
- the width of the arrows is shown proportionally to the flow
- quantity. They are typically used to visualize energy or
- material or cost transfers between processes.
- `Wikipedia (6/1/2011) <https://en.wikipedia.org/wiki/Sankey_diagram>`_
-
- """
-
- def __init__(self, ax=None, scale=1.0, unit='', format='%G', gap=0.25,
- radius=0.1, shoulder=0.03, offset=0.15, head_angle=100,
- margin=0.4, tolerance=1e-6, **kwargs):
- """
- Create a new Sankey instance.
-
- The optional arguments listed below are applied to all subdiagrams so
- that there is consistent alignment and formatting.
-
- In order to draw a complex Sankey diagram, create an instance of
- `Sankey` by calling it without any kwargs::
-
- sankey = Sankey()
-
- Then add simple Sankey sub-diagrams::
-
- sankey.add() # 1
- sankey.add() # 2
- #...
- sankey.add() # n
-
- Finally, create the full diagram::
-
- sankey.finish()
-
- Or, instead, simply daisy-chain those calls::
-
- Sankey().add().add... .add().finish()
-
- Other Parameters
- ----------------
- ax : `~matplotlib.axes.Axes`
- Axes onto which the data should be plotted. If *ax* isn't
- provided, new Axes will be created.
- scale : float
- Scaling factor for the flows. *scale* sizes the width of the paths
- in order to maintain proper layout. The same scale is applied to
- all subdiagrams. The value should be chosen such that the product
- of the scale and the sum of the inputs is approximately 1.0 (and
- the product of the scale and the sum of the outputs is
- approximately -1.0).
- unit : str
- The physical unit associated with the flow quantities. If *unit*
- is None, then none of the quantities are labeled.
- format : str or callable
- A Python number formatting string or callable used to label the
- flows with their quantities (i.e., a number times a unit, where the
- unit is given). If a format string is given, the label will be
- ``format % quantity``. If a callable is given, it will be called
- with ``quantity`` as an argument.
- gap : float
- Space between paths that break in/break away to/from the top or
- bottom.
- radius : float
- Inner radius of the vertical paths.
- shoulder : float
- Size of the shoulders of output arrows.
- offset : float
- Text offset (from the dip or tip of the arrow).
- head_angle : float
- Angle, in degrees, of the arrow heads (and negative of the angle of
- the tails).
- margin : float
- Minimum space between Sankey outlines and the edge of the plot
- area.
- tolerance : float
- Acceptable maximum of the magnitude of the sum of flows. The
- magnitude of the sum of connected flows cannot be greater than
- *tolerance*.
- **kwargs
- Any additional keyword arguments will be passed to `add`, which
- will create the first subdiagram.
-
- See Also
- --------
- Sankey.add
- Sankey.finish
-
- Examples
- --------
- .. plot:: gallery/specialty_plots/sankey_basics.py
- """
- # Check the arguments.
- if gap < 0:
- raise ValueError(
- "'gap' is negative, which is not allowed because it would "
- "cause the paths to overlap")
- if radius > gap:
- raise ValueError(
- "'radius' is greater than 'gap', which is not allowed because "
- "it would cause the paths to overlap")
- if head_angle < 0:
- raise ValueError(
- "'head_angle' is negative, which is not allowed because it "
- "would cause inputs to look like outputs and vice versa")
- if tolerance < 0:
- raise ValueError(
- "'tolerance' is negative, but it must be a magnitude")
-
- # Create axes if necessary.
- if ax is None:
- import matplotlib.pyplot as plt
- fig = plt.figure()
- ax = fig.add_subplot(1, 1, 1, xticks=[], yticks=[])
-
- self.diagrams = []
-
- # Store the inputs.
- self.ax = ax
- self.unit = unit
- self.format = format
- self.scale = scale
- self.gap = gap
- self.radius = radius
- self.shoulder = shoulder
- self.offset = offset
- self.margin = margin
- self.pitch = np.tan(np.pi * (1 - head_angle / 180.0) / 2.0)
- self.tolerance = tolerance
-
- # Initialize the vertices of tight box around the diagram(s).
- self.extent = np.array((np.inf, -np.inf, np.inf, -np.inf))
-
- # If there are any kwargs, create the first subdiagram.
- if len(kwargs):
- self.add(**kwargs)
-
- def _arc(self, quadrant=0, cw=True, radius=1, center=(0, 0)):
- """
- Return the codes and vertices for a rotated, scaled, and translated
- 90 degree arc.
-
- Other Parameters
- ----------------
- quadrant : {0, 1, 2, 3}, default: 0
- Uses 0-based indexing (0, 1, 2, or 3).
- cw : bool, default: True
- If True, the arc vertices are produced clockwise; counter-clockwise
- otherwise.
- radius : float, default: 1
- The radius of the arc.
- center : (float, float), default: (0, 0)
- (x, y) tuple of the arc's center.
- """
- # Note: It would be possible to use matplotlib's transforms to rotate,
- # scale, and translate the arc, but since the angles are discrete,
- # it's just as easy and maybe more efficient to do it here.
- ARC_CODES = [Path.LINETO,
- Path.CURVE4,
- Path.CURVE4,
- Path.CURVE4,
- Path.CURVE4,
- Path.CURVE4,
- Path.CURVE4]
- # Vertices of a cubic Bezier curve approximating a 90 deg arc
- # These can be determined by Path.arc(0, 90).
- ARC_VERTICES = np.array([[1.00000000e+00, 0.00000000e+00],
- [1.00000000e+00, 2.65114773e-01],
- [8.94571235e-01, 5.19642327e-01],
- [7.07106781e-01, 7.07106781e-01],
- [5.19642327e-01, 8.94571235e-01],
- [2.65114773e-01, 1.00000000e+00],
- # Insignificant
- # [6.12303177e-17, 1.00000000e+00]])
- [0.00000000e+00, 1.00000000e+00]])
- if quadrant in (0, 2):
- if cw:
- vertices = ARC_VERTICES
- else:
- vertices = ARC_VERTICES[:, ::-1] # Swap x and y.
- else: # 1, 3
- # Negate x.
- if cw:
- # Swap x and y.
- vertices = np.column_stack((-ARC_VERTICES[:, 1],
- ARC_VERTICES[:, 0]))
- else:
- vertices = np.column_stack((-ARC_VERTICES[:, 0],
- ARC_VERTICES[:, 1]))
- if quadrant > 1:
- radius = -radius # Rotate 180 deg.
- return list(zip(ARC_CODES, radius * vertices +
- np.tile(center, (ARC_VERTICES.shape[0], 1))))
-
- def _add_input(self, path, angle, flow, length):
- """
- Add an input to a path and return its tip and label locations.
- """
- if angle is None:
- return [0, 0], [0, 0]
- else:
- x, y = path[-1][1] # Use the last point as a reference.
- dipdepth = (flow / 2) * self.pitch
- if angle == RIGHT:
- x -= length
- dip = [x + dipdepth, y + flow / 2.0]
- path.extend([(Path.LINETO, [x, y]),
- (Path.LINETO, dip),
- (Path.LINETO, [x, y + flow]),
- (Path.LINETO, [x + self.gap, y + flow])])
- label_location = [dip[0] - self.offset, dip[1]]
- else: # Vertical
- x -= self.gap
- if angle == UP:
- sign = 1
- else:
- sign = -1
-
- dip = [x - flow / 2, y - sign * (length - dipdepth)]
- if angle == DOWN:
- quadrant = 2
- else:
- quadrant = 1
-
- # Inner arc isn't needed if inner radius is zero
- if self.radius:
- path.extend(self._arc(quadrant=quadrant,
- cw=angle == UP,
- radius=self.radius,
- center=(x + self.radius,
- y - sign * self.radius)))
- else:
- path.append((Path.LINETO, [x, y]))
- path.extend([(Path.LINETO, [x, y - sign * length]),
- (Path.LINETO, dip),
- (Path.LINETO, [x - flow, y - sign * length])])
- path.extend(self._arc(quadrant=quadrant,
- cw=angle == DOWN,
- radius=flow + self.radius,
- center=(x + self.radius,
- y - sign * self.radius)))
- path.append((Path.LINETO, [x - flow, y + sign * flow]))
- label_location = [dip[0], dip[1] - sign * self.offset]
-
- return dip, label_location
-
- def _add_output(self, path, angle, flow, length):
- """
- Append an output to a path and return its tip and label locations.
-
- .. note:: *flow* is negative for an output.
- """
- if angle is None:
- return [0, 0], [0, 0]
- else:
- x, y = path[-1][1] # Use the last point as a reference.
- tipheight = (self.shoulder - flow / 2) * self.pitch
- if angle == RIGHT:
- x += length
- tip = [x + tipheight, y + flow / 2.0]
- path.extend([(Path.LINETO, [x, y]),
- (Path.LINETO, [x, y + self.shoulder]),
- (Path.LINETO, tip),
- (Path.LINETO, [x, y - self.shoulder + flow]),
- (Path.LINETO, [x, y + flow]),
- (Path.LINETO, [x - self.gap, y + flow])])
- label_location = [tip[0] + self.offset, tip[1]]
- else: # Vertical
- x += self.gap
- if angle == UP:
- sign, quadrant = 1, 3
- else:
- sign, quadrant = -1, 0
-
- tip = [x - flow / 2.0, y + sign * (length + tipheight)]
- # Inner arc isn't needed if inner radius is zero
- if self.radius:
- path.extend(self._arc(quadrant=quadrant,
- cw=angle == UP,
- radius=self.radius,
- center=(x - self.radius,
- y + sign * self.radius)))
- else:
- path.append((Path.LINETO, [x, y]))
- path.extend([(Path.LINETO, [x, y + sign * length]),
- (Path.LINETO, [x - self.shoulder,
- y + sign * length]),
- (Path.LINETO, tip),
- (Path.LINETO, [x + self.shoulder - flow,
- y + sign * length]),
- (Path.LINETO, [x - flow, y + sign * length])])
- path.extend(self._arc(quadrant=quadrant,
- cw=angle == DOWN,
- radius=self.radius - flow,
- center=(x - self.radius,
- y + sign * self.radius)))
- path.append((Path.LINETO, [x - flow, y + sign * flow]))
- label_location = [tip[0], tip[1] + sign * self.offset]
- return tip, label_location
-
- def _revert(self, path, first_action=Path.LINETO):
- """
- A path is not simply reversible by path[::-1] since the code
- specifies an action to take from the **previous** point.
- """
- reverse_path = []
- next_code = first_action
- for code, position in path[::-1]:
- reverse_path.append((next_code, position))
- next_code = code
- return reverse_path
- # This might be more efficient, but it fails because 'tuple' object
- # doesn't support item assignment:
- # path[1] = path[1][-1:0:-1]
- # path[1][0] = first_action
- # path[2] = path[2][::-1]
- # return path
-
- @_docstring.dedent_interpd
- def add(self, patchlabel='', flows=None, orientations=None, labels='',
- trunklength=1.0, pathlengths=0.25, prior=None, connect=(0, 0),
- rotation=0, **kwargs):
- """
- Add a simple Sankey diagram with flows at the same hierarchical level.
-
- Parameters
- ----------
- patchlabel : str
- Label to be placed at the center of the diagram.
- Note that *label* (not *patchlabel*) can be passed as keyword
- argument to create an entry in the legend.
-
- flows : list of float
- Array of flow values. By convention, inputs are positive and
- outputs are negative.
-
- Flows are placed along the top of the diagram from the inside out
- in order of their index within *flows*. They are placed along the
- sides of the diagram from the top down and along the bottom from
- the outside in.
-
- If the sum of the inputs and outputs is
- nonzero, the discrepancy will appear as a cubic Bézier curve along
- the top and bottom edges of the trunk.
-
- orientations : list of {-1, 0, 1}
- List of orientations of the flows (or a single orientation to be
- used for all flows). Valid values are 0 (inputs from
- the left, outputs to the right), 1 (from and to the top) or -1
- (from and to the bottom).
-
- labels : list of (str or None)
- List of labels for the flows (or a single label to be used for all
- flows). Each label may be *None* (no label), or a labeling string.
- If an entry is a (possibly empty) string, then the quantity for the
- corresponding flow will be shown below the string. However, if
- the *unit* of the main diagram is None, then quantities are never
- shown, regardless of the value of this argument.
-
- trunklength : float
- Length between the bases of the input and output groups (in
- data-space units).
-
- pathlengths : list of float
- List of lengths of the vertical arrows before break-in or after
- break-away. If a single value is given, then it will be applied to
- the first (inside) paths on the top and bottom, and the length of
- all other arrows will be justified accordingly. The *pathlengths*
- are not applied to the horizontal inputs and outputs.
-
- prior : int
- Index of the prior diagram to which this diagram should be
- connected.
-
- connect : (int, int)
- A (prior, this) tuple indexing the flow of the prior diagram and
- the flow of this diagram which should be connected. If this is the
- first diagram or *prior* is *None*, *connect* will be ignored.
-
- rotation : float
- Angle of rotation of the diagram in degrees. The interpretation of
- the *orientations* argument will be rotated accordingly (e.g., if
- *rotation* == 90, an *orientations* entry of 1 means to/from the
- left). *rotation* is ignored if this diagram is connected to an
- existing one (using *prior* and *connect*).
-
- Returns
- -------
- Sankey
- The current `.Sankey` instance.
-
- Other Parameters
- ----------------
- **kwargs
- Additional keyword arguments set `matplotlib.patches.PathPatch`
- properties, listed below. For example, one may want to use
- ``fill=False`` or ``label="A legend entry"``.
-
- %(Patch:kwdoc)s
-
- See Also
- --------
- Sankey.finish
- """
- # Check and preprocess the arguments.
- flows = np.array([1.0, -1.0]) if flows is None else np.array(flows)
- n = flows.shape[0] # Number of flows
- if rotation is None:
- rotation = 0
- else:
- # In the code below, angles are expressed in deg/90.
- rotation /= 90.0
- if orientations is None:
- orientations = 0
- try:
- orientations = np.broadcast_to(orientations, n)
- except ValueError:
- raise ValueError(
- f"The shapes of 'flows' {np.shape(flows)} and 'orientations' "
- f"{np.shape(orientations)} are incompatible"
- ) from None
- try:
- labels = np.broadcast_to(labels, n)
- except ValueError:
- raise ValueError(
- f"The shapes of 'flows' {np.shape(flows)} and 'labels' "
- f"{np.shape(labels)} are incompatible"
- ) from None
- if trunklength < 0:
- raise ValueError(
- "'trunklength' is negative, which is not allowed because it "
- "would cause poor layout")
- if abs(np.sum(flows)) > self.tolerance:
- _log.info("The sum of the flows is nonzero (%f; patchlabel=%r); "
- "is the system not at steady state?",
- np.sum(flows), patchlabel)
- scaled_flows = self.scale * flows
- gain = sum(max(flow, 0) for flow in scaled_flows)
- loss = sum(min(flow, 0) for flow in scaled_flows)
- if prior is not None:
- if prior < 0:
- raise ValueError("The index of the prior diagram is negative")
- if min(connect) < 0:
- raise ValueError(
- "At least one of the connection indices is negative")
- if prior >= len(self.diagrams):
- raise ValueError(
- f"The index of the prior diagram is {prior}, but there "
- f"are only {len(self.diagrams)} other diagrams")
- if connect[0] >= len(self.diagrams[prior].flows):
- raise ValueError(
- "The connection index to the source diagram is {}, but "
- "that diagram has only {} flows".format(
- connect[0], len(self.diagrams[prior].flows)))
- if connect[1] >= n:
- raise ValueError(
- f"The connection index to this diagram is {connect[1]}, "
- f"but this diagram has only {n} flows")
- if self.diagrams[prior].angles[connect[0]] is None:
- raise ValueError(
- f"The connection cannot be made, which may occur if the "
- f"magnitude of flow {connect[0]} of diagram {prior} is "
- f"less than the specified tolerance")
- flow_error = (self.diagrams[prior].flows[connect[0]] +
- flows[connect[1]])
- if abs(flow_error) >= self.tolerance:
- raise ValueError(
- f"The scaled sum of the connected flows is {flow_error}, "
- f"which is not within the tolerance ({self.tolerance})")
-
- # Determine if the flows are inputs.
- are_inputs = [None] * n
- for i, flow in enumerate(flows):
- if flow >= self.tolerance:
- are_inputs[i] = True
- elif flow <= -self.tolerance:
- are_inputs[i] = False
- else:
- _log.info(
- "The magnitude of flow %d (%f) is below the tolerance "
- "(%f).\nIt will not be shown, and it cannot be used in a "
- "connection.", i, flow, self.tolerance)
-
- # Determine the angles of the arrows (before rotation).
- angles = [None] * n
- for i, (orient, is_input) in enumerate(zip(orientations, are_inputs)):
- if orient == 1:
- if is_input:
- angles[i] = DOWN
- elif is_input is False:
- # Be specific since is_input can be None.
- angles[i] = UP
- elif orient == 0:
- if is_input is not None:
- angles[i] = RIGHT
- else:
- if orient != -1:
- raise ValueError(
- f"The value of orientations[{i}] is {orient}, "
- f"but it must be -1, 0, or 1")
- if is_input:
- angles[i] = UP
- elif is_input is False:
- angles[i] = DOWN
-
- # Justify the lengths of the paths.
- if np.iterable(pathlengths):
- if len(pathlengths) != n:
- raise ValueError(
- f"The lengths of 'flows' ({n}) and 'pathlengths' "
- f"({len(pathlengths)}) are incompatible")
- else: # Make pathlengths into a list.
- urlength = pathlengths
- ullength = pathlengths
- lrlength = pathlengths
- lllength = pathlengths
- d = dict(RIGHT=pathlengths)
- pathlengths = [d.get(angle, 0) for angle in angles]
- # Determine the lengths of the top-side arrows
- # from the middle outwards.
- for i, (angle, is_input, flow) in enumerate(zip(angles, are_inputs,
- scaled_flows)):
- if angle == DOWN and is_input:
- pathlengths[i] = ullength
- ullength += flow
- elif angle == UP and is_input is False:
- pathlengths[i] = urlength
- urlength -= flow # Flow is negative for outputs.
- # Determine the lengths of the bottom-side arrows
- # from the middle outwards.
- for i, (angle, is_input, flow) in enumerate(reversed(list(zip(
- angles, are_inputs, scaled_flows)))):
- if angle == UP and is_input:
- pathlengths[n - i - 1] = lllength
- lllength += flow
- elif angle == DOWN and is_input is False:
- pathlengths[n - i - 1] = lrlength
- lrlength -= flow
- # Determine the lengths of the left-side arrows
- # from the bottom upwards.
- has_left_input = False
- for i, (angle, is_input, spec) in enumerate(reversed(list(zip(
- angles, are_inputs, zip(scaled_flows, pathlengths))))):
- if angle == RIGHT:
- if is_input:
- if has_left_input:
- pathlengths[n - i - 1] = 0
- else:
- has_left_input = True
- # Determine the lengths of the right-side arrows
- # from the top downwards.
- has_right_output = False
- for i, (angle, is_input, spec) in enumerate(zip(
- angles, are_inputs, list(zip(scaled_flows, pathlengths)))):
- if angle == RIGHT:
- if is_input is False:
- if has_right_output:
- pathlengths[i] = 0
- else:
- has_right_output = True
-
- # Begin the subpaths, and smooth the transition if the sum of the flows
- # is nonzero.
- urpath = [(Path.MOVETO, [(self.gap - trunklength / 2.0), # Upper right
- gain / 2.0]),
- (Path.LINETO, [(self.gap - trunklength / 2.0) / 2.0,
- gain / 2.0]),
- (Path.CURVE4, [(self.gap - trunklength / 2.0) / 8.0,
- gain / 2.0]),
- (Path.CURVE4, [(trunklength / 2.0 - self.gap) / 8.0,
- -loss / 2.0]),
- (Path.LINETO, [(trunklength / 2.0 - self.gap) / 2.0,
- -loss / 2.0]),
- (Path.LINETO, [(trunklength / 2.0 - self.gap),
- -loss / 2.0])]
- llpath = [(Path.LINETO, [(trunklength / 2.0 - self.gap), # Lower left
- loss / 2.0]),
- (Path.LINETO, [(trunklength / 2.0 - self.gap) / 2.0,
- loss / 2.0]),
- (Path.CURVE4, [(trunklength / 2.0 - self.gap) / 8.0,
- loss / 2.0]),
- (Path.CURVE4, [(self.gap - trunklength / 2.0) / 8.0,
- -gain / 2.0]),
- (Path.LINETO, [(self.gap - trunklength / 2.0) / 2.0,
- -gain / 2.0]),
- (Path.LINETO, [(self.gap - trunklength / 2.0),
- -gain / 2.0])]
- lrpath = [(Path.LINETO, [(trunklength / 2.0 - self.gap), # Lower right
- loss / 2.0])]
- ulpath = [(Path.LINETO, [self.gap - trunklength / 2.0, # Upper left
- gain / 2.0])]
-
- # Add the subpaths and assign the locations of the tips and labels.
- tips = np.zeros((n, 2))
- label_locations = np.zeros((n, 2))
- # Add the top-side inputs and outputs from the middle outwards.
- for i, (angle, is_input, spec) in enumerate(zip(
- angles, are_inputs, list(zip(scaled_flows, pathlengths)))):
- if angle == DOWN and is_input:
- tips[i, :], label_locations[i, :] = self._add_input(
- ulpath, angle, *spec)
- elif angle == UP and is_input is False:
- tips[i, :], label_locations[i, :] = self._add_output(
- urpath, angle, *spec)
- # Add the bottom-side inputs and outputs from the middle outwards.
- for i, (angle, is_input, spec) in enumerate(reversed(list(zip(
- angles, are_inputs, list(zip(scaled_flows, pathlengths)))))):
- if angle == UP and is_input:
- tip, label_location = self._add_input(llpath, angle, *spec)
- tips[n - i - 1, :] = tip
- label_locations[n - i - 1, :] = label_location
- elif angle == DOWN and is_input is False:
- tip, label_location = self._add_output(lrpath, angle, *spec)
- tips[n - i - 1, :] = tip
- label_locations[n - i - 1, :] = label_location
- # Add the left-side inputs from the bottom upwards.
- has_left_input = False
- for i, (angle, is_input, spec) in enumerate(reversed(list(zip(
- angles, are_inputs, list(zip(scaled_flows, pathlengths)))))):
- if angle == RIGHT and is_input:
- if not has_left_input:
- # Make sure the lower path extends
- # at least as far as the upper one.
- if llpath[-1][1][0] > ulpath[-1][1][0]:
- llpath.append((Path.LINETO, [ulpath[-1][1][0],
- llpath[-1][1][1]]))
- has_left_input = True
- tip, label_location = self._add_input(llpath, angle, *spec)
- tips[n - i - 1, :] = tip
- label_locations[n - i - 1, :] = label_location
- # Add the right-side outputs from the top downwards.
- has_right_output = False
- for i, (angle, is_input, spec) in enumerate(zip(
- angles, are_inputs, list(zip(scaled_flows, pathlengths)))):
- if angle == RIGHT and is_input is False:
- if not has_right_output:
- # Make sure the upper path extends
- # at least as far as the lower one.
- if urpath[-1][1][0] < lrpath[-1][1][0]:
- urpath.append((Path.LINETO, [lrpath[-1][1][0],
- urpath[-1][1][1]]))
- has_right_output = True
- tips[i, :], label_locations[i, :] = self._add_output(
- urpath, angle, *spec)
- # Trim any hanging vertices.
- if not has_left_input:
- ulpath.pop()
- llpath.pop()
- if not has_right_output:
- lrpath.pop()
- urpath.pop()
-
- # Concatenate the subpaths in the correct order (clockwise from top).
- path = (urpath + self._revert(lrpath) + llpath + self._revert(ulpath) +
- [(Path.CLOSEPOLY, urpath[0][1])])
-
- # Create a patch with the Sankey outline.
- codes, vertices = zip(*path)
- vertices = np.array(vertices)
-
- def _get_angle(a, r):
- if a is None:
- return None
- else:
- return a + r
-
- if prior is None:
- if rotation != 0: # By default, none of this is needed.
- angles = [_get_angle(angle, rotation) for angle in angles]
- rotate = Affine2D().rotate_deg(rotation * 90).transform_affine
- tips = rotate(tips)
- label_locations = rotate(label_locations)
- vertices = rotate(vertices)
- text = self.ax.text(0, 0, s=patchlabel, ha='center', va='center')
- else:
- rotation = (self.diagrams[prior].angles[connect[0]] -
- angles[connect[1]])
- angles = [_get_angle(angle, rotation) for angle in angles]
- rotate = Affine2D().rotate_deg(rotation * 90).transform_affine
- tips = rotate(tips)
- offset = self.diagrams[prior].tips[connect[0]] - tips[connect[1]]
- translate = Affine2D().translate(*offset).transform_affine
- tips = translate(tips)
- label_locations = translate(rotate(label_locations))
- vertices = translate(rotate(vertices))
- kwds = dict(s=patchlabel, ha='center', va='center')
- text = self.ax.text(*offset, **kwds)
- if mpl.rcParams['_internal.classic_mode']:
- fc = kwargs.pop('fc', kwargs.pop('facecolor', '#bfd1d4'))
- lw = kwargs.pop('lw', kwargs.pop('linewidth', 0.5))
- else:
- fc = kwargs.pop('fc', kwargs.pop('facecolor', None))
- lw = kwargs.pop('lw', kwargs.pop('linewidth', None))
- if fc is None:
- fc = self.ax._get_patches_for_fill.get_next_color()
- patch = PathPatch(Path(vertices, codes), fc=fc, lw=lw, **kwargs)
- self.ax.add_patch(patch)
-
- # Add the path labels.
- texts = []
- for number, angle, label, location in zip(flows, angles, labels,
- label_locations):
- if label is None or angle is None:
- label = ''
- elif self.unit is not None:
- if isinstance(self.format, str):
- quantity = self.format % abs(number) + self.unit
- elif callable(self.format):
- quantity = self.format(number)
- else:
- raise TypeError(
- 'format must be callable or a format string')
- if label != '':
- label += "\n"
- label += quantity
- texts.append(self.ax.text(x=location[0], y=location[1],
- s=label,
- ha='center', va='center'))
- # Text objects are placed even they are empty (as long as the magnitude
- # of the corresponding flow is larger than the tolerance) in case the
- # user wants to provide labels later.
-
- # Expand the size of the diagram if necessary.
- self.extent = (min(np.min(vertices[:, 0]),
- np.min(label_locations[:, 0]),
- self.extent[0]),
- max(np.max(vertices[:, 0]),
- np.max(label_locations[:, 0]),
- self.extent[1]),
- min(np.min(vertices[:, 1]),
- np.min(label_locations[:, 1]),
- self.extent[2]),
- max(np.max(vertices[:, 1]),
- np.max(label_locations[:, 1]),
- self.extent[3]))
- # Include both vertices _and_ label locations in the extents; there are
- # where either could determine the margins (e.g., arrow shoulders).
-
- # Add this diagram as a subdiagram.
- self.diagrams.append(
- SimpleNamespace(patch=patch, flows=flows, angles=angles, tips=tips,
- text=text, texts=texts))
-
- # Allow a daisy-chained call structure (see docstring for the class).
- return self
-
- def finish(self):
- """
- Adjust the axes and return a list of information about the Sankey
- subdiagram(s).
-
- Returns a list of subdiagrams with the following fields:
-
- ======== =============================================================
- Field Description
- ======== =============================================================
- *patch* Sankey outline (a `~matplotlib.patches.PathPatch`).
- *flows* Flow values (positive for input, negative for output).
- *angles* List of angles of the arrows [deg/90].
- For example, if the diagram has not been rotated,
- an input to the top side has an angle of 3 (DOWN),
- and an output from the top side has an angle of 1 (UP).
- If a flow has been skipped (because its magnitude is less
- than *tolerance*), then its angle will be *None*.
- *tips* (N, 2)-array of the (x, y) positions of the tips (or "dips")
- of the flow paths.
- If the magnitude of a flow is less the *tolerance* of this
- `Sankey` instance, the flow is skipped and its tip will be at
- the center of the diagram.
- *text* `.Text` instance for the diagram label.
- *texts* List of `.Text` instances for the flow labels.
- ======== =============================================================
-
- See Also
- --------
- Sankey.add
- """
- self.ax.axis([self.extent[0] - self.margin,
- self.extent[1] + self.margin,
- self.extent[2] - self.margin,
- self.extent[3] + self.margin])
- self.ax.set_aspect('equal', adjustable='datalim')
- return self.diagrams
diff --git a/contrib/python/matplotlib/py3/matplotlib/sankey.pyi b/contrib/python/matplotlib/py3/matplotlib/sankey.pyi
deleted file mode 100644
index 4a40c31e3c..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/sankey.pyi
+++ /dev/null
@@ -1,61 +0,0 @@
-from matplotlib.axes import Axes
-
-from collections.abc import Callable, Iterable
-from typing import Any
-
-import numpy as np
-
-__license__: str
-__credits__: list[str]
-__author__: str
-__version__: str
-
-RIGHT: int
-UP: int
-DOWN: int
-
-# TODO typing units
-class Sankey:
- diagrams: list[Any]
- ax: Axes
- unit: Any
- format: str | Callable[[float], str]
- scale: float
- gap: float
- radius: float
- shoulder: float
- offset: float
- margin: float
- pitch: float
- tolerance: float
- extent: np.ndarray
- def __init__(
- self,
- ax: Axes | None = ...,
- scale: float = ...,
- unit: Any = ...,
- format: str | Callable[[float], str] = ...,
- gap: float = ...,
- radius: float = ...,
- shoulder: float = ...,
- offset: float = ...,
- head_angle: float = ...,
- margin: float = ...,
- tolerance: float = ...,
- **kwargs
- ) -> None: ...
- def add(
- self,
- patchlabel: str = ...,
- flows: Iterable[float] | None = ...,
- orientations: Iterable[int] | None = ...,
- labels: str | Iterable[str | None] = ...,
- trunklength: float = ...,
- pathlengths: float | Iterable[float] = ...,
- prior: int | None = ...,
- connect: tuple[int, int] = ...,
- rotation: float = ...,
- **kwargs
- # Replace return with Self when py3.9 is dropped
- ) -> Sankey: ...
- def finish(self) -> list[Any]: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/scale.py b/contrib/python/matplotlib/py3/matplotlib/scale.py
deleted file mode 100644
index d86de461ef..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/scale.py
+++ /dev/null
@@ -1,756 +0,0 @@
-"""
-Scales define the distribution of data values on an axis, e.g. a log scaling.
-They are defined as subclasses of `ScaleBase`.
-
-See also `.axes.Axes.set_xscale` and the scales examples in the documentation.
-
-See :doc:`/gallery/scales/custom_scale` for a full example of defining a custom
-scale.
-
-Matplotlib also supports non-separable transformations that operate on both
-`~.axis.Axis` at the same time. They are known as projections, and defined in
-`matplotlib.projections`.
-"""
-
-import inspect
-import textwrap
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, _docstring
-from matplotlib.ticker import (
- NullFormatter, ScalarFormatter, LogFormatterSciNotation, LogitFormatter,
- NullLocator, LogLocator, AutoLocator, AutoMinorLocator,
- SymmetricalLogLocator, AsinhLocator, LogitLocator)
-from matplotlib.transforms import Transform, IdentityTransform
-
-
-class ScaleBase:
- """
- The base class for all scales.
-
- Scales are separable transformations, working on a single dimension.
-
- Subclasses should override
-
- :attr:`name`
- The scale's name.
- :meth:`get_transform`
- A method returning a `.Transform`, which converts data coordinates to
- scaled coordinates. This transform should be invertible, so that e.g.
- mouse positions can be converted back to data coordinates.
- :meth:`set_default_locators_and_formatters`
- A method that sets default locators and formatters for an `~.axis.Axis`
- that uses this scale.
- :meth:`limit_range_for_scale`
- An optional method that "fixes" the axis range to acceptable values,
- e.g. restricting log-scaled axes to positive values.
- """
-
- def __init__(self, axis):
- r"""
- Construct a new scale.
-
- Notes
- -----
- The following note is for scale implementors.
-
- For back-compatibility reasons, scales take an `~matplotlib.axis.Axis`
- object as first argument. However, this argument should not
- be used: a single scale object should be usable by multiple
- `~matplotlib.axis.Axis`\es at the same time.
- """
-
- def get_transform(self):
- """
- Return the `.Transform` object associated with this scale.
- """
- raise NotImplementedError()
-
- def set_default_locators_and_formatters(self, axis):
- """
- Set the locators and formatters of *axis* to instances suitable for
- this scale.
- """
- raise NotImplementedError()
-
- def limit_range_for_scale(self, vmin, vmax, minpos):
- """
- Return the range *vmin*, *vmax*, restricted to the
- domain supported by this scale (if any).
-
- *minpos* should be the minimum positive value in the data.
- This is used by log scales to determine a minimum value.
- """
- return vmin, vmax
-
-
-class LinearScale(ScaleBase):
- """
- The default linear scale.
- """
-
- name = 'linear'
-
- def __init__(self, axis):
- # This method is present only to prevent inheritance of the base class'
- # constructor docstring, which would otherwise end up interpolated into
- # the docstring of Axis.set_scale.
- """
- """ # noqa: D419
-
- def set_default_locators_and_formatters(self, axis):
- # docstring inherited
- axis.set_major_locator(AutoLocator())
- axis.set_major_formatter(ScalarFormatter())
- axis.set_minor_formatter(NullFormatter())
- # update the minor locator for x and y axis based on rcParams
- if (axis.axis_name == 'x' and mpl.rcParams['xtick.minor.visible'] or
- axis.axis_name == 'y' and mpl.rcParams['ytick.minor.visible']):
- axis.set_minor_locator(AutoMinorLocator())
- else:
- axis.set_minor_locator(NullLocator())
-
- def get_transform(self):
- """
- Return the transform for linear scaling, which is just the
- `~matplotlib.transforms.IdentityTransform`.
- """
- return IdentityTransform()
-
-
-class FuncTransform(Transform):
- """
- A simple transform that takes and arbitrary function for the
- forward and inverse transform.
- """
-
- input_dims = output_dims = 1
-
- def __init__(self, forward, inverse):
- """
- Parameters
- ----------
- forward : callable
- The forward function for the transform. This function must have
- an inverse and, for best behavior, be monotonic.
- It must have the signature::
-
- def forward(values: array-like) -> array-like
-
- inverse : callable
- The inverse of the forward function. Signature as ``forward``.
- """
- super().__init__()
- if callable(forward) and callable(inverse):
- self._forward = forward
- self._inverse = inverse
- else:
- raise ValueError('arguments to FuncTransform must be functions')
-
- def transform_non_affine(self, values):
- return self._forward(values)
-
- def inverted(self):
- return FuncTransform(self._inverse, self._forward)
-
-
-class FuncScale(ScaleBase):
- """
- Provide an arbitrary scale with user-supplied function for the axis.
- """
-
- name = 'function'
-
- def __init__(self, axis, functions):
- """
- Parameters
- ----------
- axis : `~matplotlib.axis.Axis`
- The axis for the scale.
- functions : (callable, callable)
- two-tuple of the forward and inverse functions for the scale.
- The forward function must be monotonic.
-
- Both functions must have the signature::
-
- def forward(values: array-like) -> array-like
- """
- forward, inverse = functions
- transform = FuncTransform(forward, inverse)
- self._transform = transform
-
- def get_transform(self):
- """Return the `.FuncTransform` associated with this scale."""
- return self._transform
-
- def set_default_locators_and_formatters(self, axis):
- # docstring inherited
- axis.set_major_locator(AutoLocator())
- axis.set_major_formatter(ScalarFormatter())
- axis.set_minor_formatter(NullFormatter())
- # update the minor locator for x and y axis based on rcParams
- if (axis.axis_name == 'x' and mpl.rcParams['xtick.minor.visible'] or
- axis.axis_name == 'y' and mpl.rcParams['ytick.minor.visible']):
- axis.set_minor_locator(AutoMinorLocator())
- else:
- axis.set_minor_locator(NullLocator())
-
-
-class LogTransform(Transform):
- input_dims = output_dims = 1
-
- def __init__(self, base, nonpositive='clip'):
- super().__init__()
- if base <= 0 or base == 1:
- raise ValueError('The log base cannot be <= 0 or == 1')
- self.base = base
- self._clip = _api.check_getitem(
- {"clip": True, "mask": False}, nonpositive=nonpositive)
-
- def __str__(self):
- return "{}(base={}, nonpositive={!r})".format(
- type(self).__name__, self.base, "clip" if self._clip else "mask")
-
- @_api.rename_parameter("3.8", "a", "values")
- def transform_non_affine(self, values):
- # Ignore invalid values due to nans being passed to the transform.
- with np.errstate(divide="ignore", invalid="ignore"):
- log = {np.e: np.log, 2: np.log2, 10: np.log10}.get(self.base)
- if log: # If possible, do everything in a single call to NumPy.
- out = log(values)
- else:
- out = np.log(values)
- out /= np.log(self.base)
- if self._clip:
- # SVG spec says that conforming viewers must support values up
- # to 3.4e38 (C float); however experiments suggest that
- # Inkscape (which uses cairo for rendering) runs into cairo's
- # 24-bit limit (which is apparently shared by Agg).
- # Ghostscript (used for pdf rendering appears to overflow even
- # earlier, with the max value around 2 ** 15 for the tests to
- # pass. On the other hand, in practice, we want to clip beyond
- # np.log10(np.nextafter(0, 1)) ~ -323
- # so 1000 seems safe.
- out[values <= 0] = -1000
- return out
-
- def inverted(self):
- return InvertedLogTransform(self.base)
-
-
-class InvertedLogTransform(Transform):
- input_dims = output_dims = 1
-
- def __init__(self, base):
- super().__init__()
- self.base = base
-
- def __str__(self):
- return f"{type(self).__name__}(base={self.base})"
-
- @_api.rename_parameter("3.8", "a", "values")
- def transform_non_affine(self, values):
- return np.power(self.base, values)
-
- def inverted(self):
- return LogTransform(self.base)
-
-
-class LogScale(ScaleBase):
- """
- A standard logarithmic scale. Care is taken to only plot positive values.
- """
- name = 'log'
-
- def __init__(self, axis, *, base=10, subs=None, nonpositive="clip"):
- """
- Parameters
- ----------
- axis : `~matplotlib.axis.Axis`
- The axis for the scale.
- base : float, default: 10
- The base of the logarithm.
- nonpositive : {'clip', 'mask'}, default: 'clip'
- Determines the behavior for non-positive values. They can either
- be masked as invalid, or clipped to a very small positive number.
- subs : sequence of int, default: None
- Where to place the subticks between each major tick. For example,
- in a log10 scale, ``[2, 3, 4, 5, 6, 7, 8, 9]`` will place 8
- logarithmically spaced minor ticks between each major tick.
- """
- self._transform = LogTransform(base, nonpositive)
- self.subs = subs
-
- base = property(lambda self: self._transform.base)
-
- def set_default_locators_and_formatters(self, axis):
- # docstring inherited
- axis.set_major_locator(LogLocator(self.base))
- axis.set_major_formatter(LogFormatterSciNotation(self.base))
- axis.set_minor_locator(LogLocator(self.base, self.subs))
- axis.set_minor_formatter(
- LogFormatterSciNotation(self.base,
- labelOnlyBase=(self.subs is not None)))
-
- def get_transform(self):
- """Return the `.LogTransform` associated with this scale."""
- return self._transform
-
- def limit_range_for_scale(self, vmin, vmax, minpos):
- """Limit the domain to positive values."""
- if not np.isfinite(minpos):
- minpos = 1e-300 # Should rarely (if ever) have a visible effect.
-
- return (minpos if vmin <= 0 else vmin,
- minpos if vmax <= 0 else vmax)
-
-
-class FuncScaleLog(LogScale):
- """
- Provide an arbitrary scale with user-supplied function for the axis and
- then put on a logarithmic axes.
- """
-
- name = 'functionlog'
-
- def __init__(self, axis, functions, base=10):
- """
- Parameters
- ----------
- axis : `~matplotlib.axis.Axis`
- The axis for the scale.
- functions : (callable, callable)
- two-tuple of the forward and inverse functions for the scale.
- The forward function must be monotonic.
-
- Both functions must have the signature::
-
- def forward(values: array-like) -> array-like
-
- base : float, default: 10
- Logarithmic base of the scale.
- """
- forward, inverse = functions
- self.subs = None
- self._transform = FuncTransform(forward, inverse) + LogTransform(base)
-
- @property
- def base(self):
- return self._transform._b.base # Base of the LogTransform.
-
- def get_transform(self):
- """Return the `.Transform` associated with this scale."""
- return self._transform
-
-
-class SymmetricalLogTransform(Transform):
- input_dims = output_dims = 1
-
- def __init__(self, base, linthresh, linscale):
- super().__init__()
- if base <= 1.0:
- raise ValueError("'base' must be larger than 1")
- if linthresh <= 0.0:
- raise ValueError("'linthresh' must be positive")
- if linscale <= 0.0:
- raise ValueError("'linscale' must be positive")
- self.base = base
- self.linthresh = linthresh
- self.linscale = linscale
- self._linscale_adj = (linscale / (1.0 - self.base ** -1))
- self._log_base = np.log(base)
-
- @_api.rename_parameter("3.8", "a", "values")
- def transform_non_affine(self, values):
- abs_a = np.abs(values)
- with np.errstate(divide="ignore", invalid="ignore"):
- out = np.sign(values) * self.linthresh * (
- self._linscale_adj +
- np.log(abs_a / self.linthresh) / self._log_base)
- inside = abs_a <= self.linthresh
- out[inside] = values[inside] * self._linscale_adj
- return out
-
- def inverted(self):
- return InvertedSymmetricalLogTransform(self.base, self.linthresh,
- self.linscale)
-
-
-class InvertedSymmetricalLogTransform(Transform):
- input_dims = output_dims = 1
-
- def __init__(self, base, linthresh, linscale):
- super().__init__()
- symlog = SymmetricalLogTransform(base, linthresh, linscale)
- self.base = base
- self.linthresh = linthresh
- self.invlinthresh = symlog.transform(linthresh)
- self.linscale = linscale
- self._linscale_adj = (linscale / (1.0 - self.base ** -1))
-
- @_api.rename_parameter("3.8", "a", "values")
- def transform_non_affine(self, values):
- abs_a = np.abs(values)
- with np.errstate(divide="ignore", invalid="ignore"):
- out = np.sign(values) * self.linthresh * (
- np.power(self.base,
- abs_a / self.linthresh - self._linscale_adj))
- inside = abs_a <= self.invlinthresh
- out[inside] = values[inside] / self._linscale_adj
- return out
-
- def inverted(self):
- return SymmetricalLogTransform(self.base,
- self.linthresh, self.linscale)
-
-
-class SymmetricalLogScale(ScaleBase):
- """
- The symmetrical logarithmic scale is logarithmic in both the
- positive and negative directions from the origin.
-
- Since the values close to zero tend toward infinity, there is a
- need to have a range around zero that is linear. The parameter
- *linthresh* allows the user to specify the size of this range
- (-*linthresh*, *linthresh*).
-
- Parameters
- ----------
- base : float, default: 10
- The base of the logarithm.
-
- linthresh : float, default: 2
- Defines the range ``(-x, x)``, within which the plot is linear.
- This avoids having the plot go to infinity around zero.
-
- subs : sequence of int
- Where to place the subticks between each major tick.
- For example, in a log10 scale: ``[2, 3, 4, 5, 6, 7, 8, 9]`` will place
- 8 logarithmically spaced minor ticks between each major tick.
-
- linscale : float, optional
- This allows the linear range ``(-linthresh, linthresh)`` to be
- stretched relative to the logarithmic range. Its value is the number of
- decades to use for each half of the linear range. For example, when
- *linscale* == 1.0 (the default), the space used for the positive and
- negative halves of the linear range will be equal to one decade in
- the logarithmic range.
- """
- name = 'symlog'
-
- def __init__(self, axis, *, base=10, linthresh=2, subs=None, linscale=1):
- self._transform = SymmetricalLogTransform(base, linthresh, linscale)
- self.subs = subs
-
- base = property(lambda self: self._transform.base)
- linthresh = property(lambda self: self._transform.linthresh)
- linscale = property(lambda self: self._transform.linscale)
-
- def set_default_locators_and_formatters(self, axis):
- # docstring inherited
- axis.set_major_locator(SymmetricalLogLocator(self.get_transform()))
- axis.set_major_formatter(LogFormatterSciNotation(self.base))
- axis.set_minor_locator(SymmetricalLogLocator(self.get_transform(),
- self.subs))
- axis.set_minor_formatter(NullFormatter())
-
- def get_transform(self):
- """Return the `.SymmetricalLogTransform` associated with this scale."""
- return self._transform
-
-
-class AsinhTransform(Transform):
- """Inverse hyperbolic-sine transformation used by `.AsinhScale`"""
- input_dims = output_dims = 1
-
- def __init__(self, linear_width):
- super().__init__()
- if linear_width <= 0.0:
- raise ValueError("Scale parameter 'linear_width' " +
- "must be strictly positive")
- self.linear_width = linear_width
-
- @_api.rename_parameter("3.8", "a", "values")
- def transform_non_affine(self, values):
- return self.linear_width * np.arcsinh(values / self.linear_width)
-
- def inverted(self):
- return InvertedAsinhTransform(self.linear_width)
-
-
-class InvertedAsinhTransform(Transform):
- """Hyperbolic sine transformation used by `.AsinhScale`"""
- input_dims = output_dims = 1
-
- def __init__(self, linear_width):
- super().__init__()
- self.linear_width = linear_width
-
- @_api.rename_parameter("3.8", "a", "values")
- def transform_non_affine(self, values):
- return self.linear_width * np.sinh(values / self.linear_width)
-
- def inverted(self):
- return AsinhTransform(self.linear_width)
-
-
-class AsinhScale(ScaleBase):
- """
- A quasi-logarithmic scale based on the inverse hyperbolic sine (asinh)
-
- For values close to zero, this is essentially a linear scale,
- but for large magnitude values (either positive or negative)
- it is asymptotically logarithmic. The transition between these
- linear and logarithmic regimes is smooth, and has no discontinuities
- in the function gradient in contrast to
- the `.SymmetricalLogScale` ("symlog") scale.
-
- Specifically, the transformation of an axis coordinate :math:`a` is
- :math:`a \\rightarrow a_0 \\sinh^{-1} (a / a_0)` where :math:`a_0`
- is the effective width of the linear region of the transformation.
- In that region, the transformation is
- :math:`a \\rightarrow a + \\mathcal{O}(a^3)`.
- For large values of :math:`a` the transformation behaves as
- :math:`a \\rightarrow a_0 \\, \\mathrm{sgn}(a) \\ln |a| + \\mathcal{O}(1)`.
-
- .. note::
-
- This API is provisional and may be revised in the future
- based on early user feedback.
- """
-
- name = 'asinh'
-
- auto_tick_multipliers = {
- 3: (2, ),
- 4: (2, ),
- 5: (2, ),
- 8: (2, 4),
- 10: (2, 5),
- 16: (2, 4, 8),
- 64: (4, 16),
- 1024: (256, 512)
- }
-
- def __init__(self, axis, *, linear_width=1.0,
- base=10, subs='auto', **kwargs):
- """
- Parameters
- ----------
- linear_width : float, default: 1
- The scale parameter (elsewhere referred to as :math:`a_0`)
- defining the extent of the quasi-linear region,
- and the coordinate values beyond which the transformation
- becomes asymptotically logarithmic.
- base : int, default: 10
- The number base used for rounding tick locations
- on a logarithmic scale. If this is less than one,
- then rounding is to the nearest integer multiple
- of powers of ten.
- subs : sequence of int
- Multiples of the number base used for minor ticks.
- If set to 'auto', this will use built-in defaults,
- e.g. (2, 5) for base=10.
- """
- super().__init__(axis)
- self._transform = AsinhTransform(linear_width)
- self._base = int(base)
- if subs == 'auto':
- self._subs = self.auto_tick_multipliers.get(self._base)
- else:
- self._subs = subs
-
- linear_width = property(lambda self: self._transform.linear_width)
-
- def get_transform(self):
- return self._transform
-
- def set_default_locators_and_formatters(self, axis):
- axis.set(major_locator=AsinhLocator(self.linear_width,
- base=self._base),
- minor_locator=AsinhLocator(self.linear_width,
- base=self._base,
- subs=self._subs),
- minor_formatter=NullFormatter())
- if self._base > 1:
- axis.set_major_formatter(LogFormatterSciNotation(self._base))
- else:
- axis.set_major_formatter('{x:.3g}')
-
-
-class LogitTransform(Transform):
- input_dims = output_dims = 1
-
- def __init__(self, nonpositive='mask'):
- super().__init__()
- _api.check_in_list(['mask', 'clip'], nonpositive=nonpositive)
- self._nonpositive = nonpositive
- self._clip = {"clip": True, "mask": False}[nonpositive]
-
- @_api.rename_parameter("3.8", "a", "values")
- def transform_non_affine(self, values):
- """logit transform (base 10), masked or clipped"""
- with np.errstate(divide="ignore", invalid="ignore"):
- out = np.log10(values / (1 - values))
- if self._clip: # See LogTransform for choice of clip value.
- out[values <= 0] = -1000
- out[1 <= values] = 1000
- return out
-
- def inverted(self):
- return LogisticTransform(self._nonpositive)
-
- def __str__(self):
- return f"{type(self).__name__}({self._nonpositive!r})"
-
-
-class LogisticTransform(Transform):
- input_dims = output_dims = 1
-
- def __init__(self, nonpositive='mask'):
- super().__init__()
- self._nonpositive = nonpositive
-
- @_api.rename_parameter("3.8", "a", "values")
- def transform_non_affine(self, values):
- """logistic transform (base 10)"""
- return 1.0 / (1 + 10**(-values))
-
- def inverted(self):
- return LogitTransform(self._nonpositive)
-
- def __str__(self):
- return f"{type(self).__name__}({self._nonpositive!r})"
-
-
-class LogitScale(ScaleBase):
- """
- Logit scale for data between zero and one, both excluded.
-
- This scale is similar to a log scale close to zero and to one, and almost
- linear around 0.5. It maps the interval ]0, 1[ onto ]-infty, +infty[.
- """
- name = 'logit'
-
- def __init__(self, axis, nonpositive='mask', *,
- one_half=r"\frac{1}{2}", use_overline=False):
- r"""
- Parameters
- ----------
- axis : `~matplotlib.axis.Axis`
- Currently unused.
- nonpositive : {'mask', 'clip'}
- Determines the behavior for values beyond the open interval ]0, 1[.
- They can either be masked as invalid, or clipped to a number very
- close to 0 or 1.
- use_overline : bool, default: False
- Indicate the usage of survival notation (\overline{x}) in place of
- standard notation (1-x) for probability close to one.
- one_half : str, default: r"\frac{1}{2}"
- The string used for ticks formatter to represent 1/2.
- """
- self._transform = LogitTransform(nonpositive)
- self._use_overline = use_overline
- self._one_half = one_half
-
- def get_transform(self):
- """Return the `.LogitTransform` associated with this scale."""
- return self._transform
-
- def set_default_locators_and_formatters(self, axis):
- # docstring inherited
- # ..., 0.01, 0.1, 0.5, 0.9, 0.99, ...
- axis.set_major_locator(LogitLocator())
- axis.set_major_formatter(
- LogitFormatter(
- one_half=self._one_half,
- use_overline=self._use_overline
- )
- )
- axis.set_minor_locator(LogitLocator(minor=True))
- axis.set_minor_formatter(
- LogitFormatter(
- minor=True,
- one_half=self._one_half,
- use_overline=self._use_overline
- )
- )
-
- def limit_range_for_scale(self, vmin, vmax, minpos):
- """
- Limit the domain to values between 0 and 1 (excluded).
- """
- if not np.isfinite(minpos):
- minpos = 1e-7 # Should rarely (if ever) have a visible effect.
- return (minpos if vmin <= 0 else vmin,
- 1 - minpos if vmax >= 1 else vmax)
-
-
-_scale_mapping = {
- 'linear': LinearScale,
- 'log': LogScale,
- 'symlog': SymmetricalLogScale,
- 'asinh': AsinhScale,
- 'logit': LogitScale,
- 'function': FuncScale,
- 'functionlog': FuncScaleLog,
- }
-
-
-def get_scale_names():
- """Return the names of the available scales."""
- return sorted(_scale_mapping)
-
-
-def scale_factory(scale, axis, **kwargs):
- """
- Return a scale class by name.
-
- Parameters
- ----------
- scale : {%(names)s}
- axis : `~matplotlib.axis.Axis`
- """
- scale_cls = _api.check_getitem(_scale_mapping, scale=scale)
- return scale_cls(axis, **kwargs)
-
-
-if scale_factory.__doc__:
- scale_factory.__doc__ = scale_factory.__doc__ % {
- "names": ", ".join(map(repr, get_scale_names()))}
-
-
-def register_scale(scale_class):
- """
- Register a new kind of scale.
-
- Parameters
- ----------
- scale_class : subclass of `ScaleBase`
- The scale to register.
- """
- _scale_mapping[scale_class.name] = scale_class
-
-
-def _get_scale_docs():
- """
- Helper function for generating docstrings related to scales.
- """
- docs = []
- for name, scale_class in _scale_mapping.items():
- docstring = inspect.getdoc(scale_class.__init__) or ""
- docs.extend([
- f" {name!r}",
- "",
- textwrap.indent(docstring, " " * 8),
- ""
- ])
- return "\n".join(docs)
-
-
-_docstring.interpd.update(
- scale_type='{%s}' % ', '.join([repr(x) for x in get_scale_names()]),
- scale_docs=_get_scale_docs().rstrip(),
- )
diff --git a/contrib/python/matplotlib/py3/matplotlib/scale.pyi b/contrib/python/matplotlib/py3/matplotlib/scale.pyi
deleted file mode 100644
index 7fec8e68cc..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/scale.pyi
+++ /dev/null
@@ -1,178 +0,0 @@
-from matplotlib.axis import Axis
-from matplotlib.transforms import Transform
-
-from collections.abc import Callable, Iterable
-from typing import Literal
-from numpy.typing import ArrayLike
-
-class ScaleBase:
- def __init__(self, axis: Axis | None) -> None: ...
- def get_transform(self) -> Transform: ...
- def set_default_locators_and_formatters(self, axis: Axis) -> None: ...
- def limit_range_for_scale(
- self, vmin: float, vmax: float, minpos: float
- ) -> tuple[float, float]: ...
-
-class LinearScale(ScaleBase):
- name: str
-
-class FuncTransform(Transform):
- input_dims: int
- output_dims: int
- def __init__(
- self,
- forward: Callable[[ArrayLike], ArrayLike],
- inverse: Callable[[ArrayLike], ArrayLike],
- ) -> None: ...
- def inverted(self) -> FuncTransform: ...
-
-class FuncScale(ScaleBase):
- name: str
- def __init__(
- self,
- axis: Axis | None,
- functions: tuple[
- Callable[[ArrayLike], ArrayLike], Callable[[ArrayLike], ArrayLike]
- ],
- ) -> None: ...
-
-class LogTransform(Transform):
- input_dims: int
- output_dims: int
- base: float
- def __init__(
- self, base: float, nonpositive: Literal["clip", "mask"] = ...
- ) -> None: ...
- def inverted(self) -> InvertedLogTransform: ...
-
-class InvertedLogTransform(Transform):
- input_dims: int
- output_dims: int
- base: float
- def __init__(self, base: float) -> None: ...
- def inverted(self) -> LogTransform: ...
-
-class LogScale(ScaleBase):
- name: str
- subs: Iterable[int] | None
- def __init__(
- self,
- axis: Axis | None,
- *,
- base: float = ...,
- subs: Iterable[int] | None = ...,
- nonpositive: Literal["clip", "mask"] = ...
- ) -> None: ...
- @property
- def base(self) -> float: ...
- def get_transform(self) -> Transform: ...
-
-class FuncScaleLog(LogScale):
- def __init__(
- self,
- axis: Axis | None,
- functions: tuple[
- Callable[[ArrayLike], ArrayLike], Callable[[ArrayLike], ArrayLike]
- ],
- base: float = ...,
- ) -> None: ...
- @property
- def base(self) -> float: ...
- def get_transform(self) -> Transform: ...
-
-class SymmetricalLogTransform(Transform):
- input_dims: int
- output_dims: int
- base: float
- linthresh: float
- linscale: float
- def __init__(self, base: float, linthresh: float, linscale: float) -> None: ...
- def inverted(self) -> InvertedSymmetricalLogTransform: ...
-
-class InvertedSymmetricalLogTransform(Transform):
- input_dims: int
- output_dims: int
- base: float
- linthresh: float
- invlinthresh: float
- linscale: float
- def __init__(self, base: float, linthresh: float, linscale: float) -> None: ...
- def inverted(self) -> SymmetricalLogTransform: ...
-
-class SymmetricalLogScale(ScaleBase):
- name: str
- subs: Iterable[int] | None
- def __init__(
- self,
- axis: Axis | None,
- *,
- base: float = ...,
- linthresh: float = ...,
- subs: Iterable[int] | None = ...,
- linscale: float = ...
- ) -> None: ...
- @property
- def base(self) -> float: ...
- @property
- def linthresh(self) -> float: ...
- @property
- def linscale(self) -> float: ...
- def get_transform(self) -> SymmetricalLogTransform: ...
-
-class AsinhTransform(Transform):
- input_dims: int
- output_dims: int
- linear_width: float
- def __init__(self, linear_width: float) -> None: ...
- def inverted(self) -> InvertedAsinhTransform: ...
-
-class InvertedAsinhTransform(Transform):
- input_dims: int
- output_dims: int
- linear_width: float
- def __init__(self, linear_width: float) -> None: ...
- def inverted(self) -> AsinhTransform: ...
-
-class AsinhScale(ScaleBase):
- name: str
- auto_tick_multipliers: dict[int, tuple[int, ...]]
- def __init__(
- self,
- axis: Axis | None,
- *,
- linear_width: float = ...,
- base: float = ...,
- subs: Iterable[int] | Literal["auto"] | None = ...,
- **kwargs
- ) -> None: ...
- @property
- def linear_width(self) -> float: ...
- def get_transform(self) -> AsinhTransform: ...
-
-class LogitTransform(Transform):
- input_dims: int
- output_dims: int
- def __init__(self, nonpositive: Literal["mask", "clip"] = ...) -> None: ...
- def inverted(self) -> LogisticTransform: ...
-
-class LogisticTransform(Transform):
- input_dims: int
- output_dims: int
- def __init__(self, nonpositive: Literal["mask", "clip"] = ...) -> None: ...
- def inverted(self) -> LogitTransform: ...
-
-class LogitScale(ScaleBase):
- name: str
- def __init__(
- self,
- axis: Axis | None,
- nonpositive: Literal["mask", "clip"] = ...,
- *,
- one_half: str = ...,
- use_overline: bool = ...
- ) -> None: ...
- def get_transform(self) -> LogitTransform: ...
-
-def get_scale_names() -> list[str]: ...
-def scale_factory(scale: str, axis: Axis, **kwargs) -> ScaleBase: ...
-def register_scale(scale_class: type[ScaleBase]) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/sphinxext/__init__.py b/contrib/python/matplotlib/py3/matplotlib/sphinxext/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/sphinxext/__init__.py
+++ /dev/null
diff --git a/contrib/python/matplotlib/py3/matplotlib/sphinxext/figmpl_directive.py b/contrib/python/matplotlib/py3/matplotlib/sphinxext/figmpl_directive.py
deleted file mode 100644
index 5ef34f4dd0..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/sphinxext/figmpl_directive.py
+++ /dev/null
@@ -1,288 +0,0 @@
-"""
-Add a ``figure-mpl`` directive that is a responsive version of ``figure``.
-
-This implementation is very similar to ``.. figure::``, except it also allows a
-``srcset=`` argument to be passed to the image tag, hence allowing responsive
-resolution images.
-
-There is no particular reason this could not be used standalone, but is meant
-to be used with :doc:`/api/sphinxext_plot_directive_api`.
-
-Note that the directory organization is a bit different than ``.. figure::``.
-See the *FigureMpl* documentation below.
-
-"""
-from docutils import nodes
-
-from docutils.parsers.rst import directives
-from docutils.parsers.rst.directives.images import Figure, Image
-
-import os
-from os.path import relpath
-from pathlib import PurePath, Path
-import shutil
-
-from sphinx.errors import ExtensionError
-
-import matplotlib
-
-
-class figmplnode(nodes.General, nodes.Element):
- pass
-
-
-class FigureMpl(Figure):
- """
- Implements a directive to allow an optional hidpi image.
-
- Meant to be used with the *plot_srcset* configuration option in conf.py,
- and gets set in the TEMPLATE of plot_directive.py
-
- e.g.::
-
- .. figure-mpl:: plot_directive/some_plots-1.png
- :alt: bar
- :srcset: plot_directive/some_plots-1.png,
- plot_directive/some_plots-1.2x.png 2.00x
- :class: plot-directive
-
- The resulting html (at ``some_plots.html``) is::
-
- <img src="sphx_glr_bar_001_hidpi.png"
- srcset="_images/some_plot-1.png,
- _images/some_plots-1.2x.png 2.00x",
- alt="bar"
- class="plot_directive" />
-
- Note that the handling of subdirectories is different than that used by the sphinx
- figure directive::
-
- .. figure-mpl:: plot_directive/nestedpage/index-1.png
- :alt: bar
- :srcset: plot_directive/nestedpage/index-1.png
- plot_directive/nestedpage/index-1.2x.png 2.00x
- :class: plot_directive
-
- The resulting html (at ``nestedpage/index.html``)::
-
- <img src="../_images/nestedpage-index-1.png"
- srcset="../_images/nestedpage-index-1.png,
- ../_images/_images/nestedpage-index-1.2x.png 2.00x",
- alt="bar"
- class="sphx-glr-single-img" />
-
- where the subdirectory is included in the image name for uniqueness.
- """
-
- has_content = False
- required_arguments = 1
- optional_arguments = 2
- final_argument_whitespace = False
- option_spec = {
- 'alt': directives.unchanged,
- 'height': directives.length_or_unitless,
- 'width': directives.length_or_percentage_or_unitless,
- 'scale': directives.nonnegative_int,
- 'align': Image.align,
- 'class': directives.class_option,
- 'caption': directives.unchanged,
- 'srcset': directives.unchanged,
- }
-
- def run(self):
-
- image_node = figmplnode()
-
- imagenm = self.arguments[0]
- image_node['alt'] = self.options.get('alt', '')
- image_node['align'] = self.options.get('align', None)
- image_node['class'] = self.options.get('class', None)
- image_node['width'] = self.options.get('width', None)
- image_node['height'] = self.options.get('height', None)
- image_node['scale'] = self.options.get('scale', None)
- image_node['caption'] = self.options.get('caption', None)
-
- # we would like uri to be the highest dpi version so that
- # latex etc will use that. But for now, lets just make
- # imagenm... maybe pdf one day?
-
- image_node['uri'] = imagenm
- image_node['srcset'] = self.options.get('srcset', None)
-
- return [image_node]
-
-
-def _parse_srcsetNodes(st):
- """
- parse srcset...
- """
- entries = st.split(',')
- srcset = {}
- for entry in entries:
- spl = entry.strip().split(' ')
- if len(spl) == 1:
- srcset[0] = spl[0]
- elif len(spl) == 2:
- mult = spl[1][:-1]
- srcset[float(mult)] = spl[0]
- else:
- raise ExtensionError(f'srcset argument "{entry}" is invalid.')
- return srcset
-
-
-def _copy_images_figmpl(self, node):
-
- # these will be the temporary place the plot-directive put the images eg:
- # ../../../build/html/plot_directive/users/explain/artists/index-1.png
- if node['srcset']:
- srcset = _parse_srcsetNodes(node['srcset'])
- else:
- srcset = None
-
- # the rst file's location: eg /Users/username/matplotlib/doc/users/explain/artists
- docsource = PurePath(self.document['source']).parent
-
- # get the relpath relative to root:
- srctop = self.builder.srcdir
- rel = relpath(docsource, srctop).replace('.', '').replace(os.sep, '-')
- if len(rel):
- rel += '-'
- # eg: users/explain/artists
-
- imagedir = PurePath(self.builder.outdir, self.builder.imagedir)
- # eg: /Users/username/matplotlib/doc/build/html/_images/users/explain/artists
-
- Path(imagedir).mkdir(parents=True, exist_ok=True)
-
- # copy all the sources to the imagedir:
- if srcset:
- for src in srcset.values():
- # the entries in srcset are relative to docsource's directory
- abspath = PurePath(docsource, src)
- name = rel + abspath.name
- shutil.copyfile(abspath, imagedir / name)
- else:
- abspath = PurePath(docsource, node['uri'])
- name = rel + abspath.name
- shutil.copyfile(abspath, imagedir / name)
-
- return imagedir, srcset, rel
-
-
-def visit_figmpl_html(self, node):
-
- imagedir, srcset, rel = _copy_images_figmpl(self, node)
-
- # /doc/examples/subd/plot_1.rst
- docsource = PurePath(self.document['source'])
- # /doc/
- # make sure to add the trailing slash:
- srctop = PurePath(self.builder.srcdir, '')
- # examples/subd/plot_1.rst
- relsource = relpath(docsource, srctop)
- # /doc/build/html
- desttop = PurePath(self.builder.outdir, '')
- # /doc/build/html/examples/subd
- dest = desttop / relsource
-
- # ../../_images/ for dirhtml and ../_images/ for html
- imagerel = PurePath(relpath(imagedir, dest.parent)).as_posix()
- if self.builder.name == "dirhtml":
- imagerel = f'..{imagerel}'
-
- # make uri also be relative...
- nm = PurePath(node['uri'][1:]).name
- uri = f'{imagerel}/{rel}{nm}'
-
- # make srcset str. Need to change all the prefixes!
- maxsrc = uri
- srcsetst = ''
- if srcset:
- maxmult = -1
- for mult, src in srcset.items():
- nm = PurePath(src[1:]).name
- # ../../_images/plot_1_2_0x.png
- path = f'{imagerel}/{rel}{nm}'
- srcsetst += path
- if mult == 0:
- srcsetst += ', '
- else:
- srcsetst += f' {mult:1.2f}x, '
-
- if mult > maxmult:
- maxmult = mult
- maxsrc = path
-
- # trim trailing comma and space...
- srcsetst = srcsetst[:-2]
-
- alt = node['alt']
- if node['class'] is not None:
- classst = ' '.join(node['class'])
- classst = f'class="{classst}"'
-
- else:
- classst = ''
-
- stylers = ['width', 'height', 'scale']
- stylest = ''
- for style in stylers:
- if node[style]:
- stylest += f'{style}: {node[style]};'
-
- figalign = node['align'] if node['align'] else 'center'
-
-# <figure class="align-default" id="id1">
-# <a class="reference internal image-reference" href="_images/index-1.2x.png">
-# <img alt="_images/index-1.2x.png" src="_images/index-1.2x.png" style="width: 53%;" />
-# </a>
-# <figcaption>
-# <p><span class="caption-text">Figure caption is here....</span>
-# <a class="headerlink" href="#id1" title="Permalink to this image">#</a></p>
-# </figcaption>
-# </figure>
- img_block = (f'<img src="{uri}" style="{stylest}" srcset="{srcsetst}" '
- f'alt="{alt}" {classst}/>')
- html_block = f'<figure class="align-{figalign}">\n'
- html_block += f' <a class="reference internal image-reference" href="{maxsrc}">\n'
- html_block += f' {img_block}\n </a>\n'
- if node['caption']:
- html_block += ' <figcaption>\n'
- html_block += f' <p><span class="caption-text">{node["caption"]}</span></p>\n'
- html_block += ' </figcaption>\n'
- html_block += '</figure>\n'
- self.body.append(html_block)
-
-
-def visit_figmpl_latex(self, node):
-
- if node['srcset'] is not None:
- imagedir, srcset = _copy_images_figmpl(self, node)
- maxmult = -1
- # choose the highest res version for latex:
- maxmult = max(srcset, default=-1)
- node['uri'] = PurePath(srcset[maxmult]).name
-
- self.visit_figure(node)
-
-
-def depart_figmpl_html(self, node):
- pass
-
-
-def depart_figmpl_latex(self, node):
- self.depart_figure(node)
-
-
-def figurempl_addnode(app):
- app.add_node(figmplnode,
- html=(visit_figmpl_html, depart_figmpl_html),
- latex=(visit_figmpl_latex, depart_figmpl_latex))
-
-
-def setup(app):
- app.add_directive("figure-mpl", FigureMpl)
- figurempl_addnode(app)
- metadata = {'parallel_read_safe': True, 'parallel_write_safe': True,
- 'version': matplotlib.__version__}
- return metadata
diff --git a/contrib/python/matplotlib/py3/matplotlib/sphinxext/mathmpl.py b/contrib/python/matplotlib/py3/matplotlib/sphinxext/mathmpl.py
deleted file mode 100644
index 3e0d562e2d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/sphinxext/mathmpl.py
+++ /dev/null
@@ -1,239 +0,0 @@
-r"""
-A role and directive to display mathtext in Sphinx
-==================================================
-
-The ``mathmpl`` Sphinx extension creates a mathtext image in Matplotlib and
-shows it in html output. Thus, it is a true and faithful representation of what
-you will see if you pass a given LaTeX string to Matplotlib (see
-:ref:`mathtext`).
-
-.. warning::
- In most cases, you will likely want to use one of `Sphinx's builtin Math
- extensions
- <https://www.sphinx-doc.org/en/master/usage/extensions/math.html>`__
- instead of this one. The builtin Sphinx math directive uses MathJax to
- render mathematical expressions, and addresses accessibility concerns that
- ``mathmpl`` doesn't address.
-
-Mathtext may be included in two ways:
-
-1. Inline, using the role::
-
- This text uses inline math: :mathmpl:`\alpha > \beta`.
-
- which produces:
-
- This text uses inline math: :mathmpl:`\alpha > \beta`.
-
-2. Standalone, using the directive::
-
- Here is some standalone math:
-
- .. mathmpl::
-
- \alpha > \beta
-
- which produces:
-
- Here is some standalone math:
-
- .. mathmpl::
-
- \alpha > \beta
-
-Options
--------
-
-The ``mathmpl`` role and directive both support the following options:
-
-fontset : str, default: 'cm'
- The font set to use when displaying math. See :rc:`mathtext.fontset`.
-
-fontsize : float
- The font size, in points. Defaults to the value from the extension
- configuration option defined below.
-
-Configuration options
----------------------
-
-The mathtext extension has the following configuration options:
-
-mathmpl_fontsize : float, default: 10.0
- Default font size, in points.
-
-mathmpl_srcset : list of str, default: []
- Additional image sizes to generate when embedding in HTML, to support
- `responsive resolution images
- <https://developer.mozilla.org/en-US/docs/Learn/HTML/Multimedia_and_embedding/Responsive_images>`__.
- The list should contain additional x-descriptors (``'1.5x'``, ``'2x'``,
- etc.) to generate (1x is the default and always included.)
-
-"""
-
-import hashlib
-from pathlib import Path
-
-from docutils import nodes
-from docutils.parsers.rst import Directive, directives
-import sphinx
-from sphinx.errors import ConfigError, ExtensionError
-
-import matplotlib as mpl
-from matplotlib import _api, mathtext
-from matplotlib.rcsetup import validate_float_or_None
-
-
-# Define LaTeX math node:
-class latex_math(nodes.General, nodes.Element):
- pass
-
-
-def fontset_choice(arg):
- return directives.choice(arg, mathtext.MathTextParser._font_type_mapping)
-
-
-def math_role(role, rawtext, text, lineno, inliner,
- options={}, content=[]):
- i = rawtext.find('`')
- latex = rawtext[i+1:-1]
- node = latex_math(rawtext)
- node['latex'] = latex
- node['fontset'] = options.get('fontset', 'cm')
- node['fontsize'] = options.get('fontsize',
- setup.app.config.mathmpl_fontsize)
- return [node], []
-math_role.options = {'fontset': fontset_choice,
- 'fontsize': validate_float_or_None}
-
-
-class MathDirective(Directive):
- """
- The ``.. mathmpl::`` directive, as documented in the module's docstring.
- """
- has_content = True
- required_arguments = 0
- optional_arguments = 0
- final_argument_whitespace = False
- option_spec = {'fontset': fontset_choice,
- 'fontsize': validate_float_or_None}
-
- def run(self):
- latex = ''.join(self.content)
- node = latex_math(self.block_text)
- node['latex'] = latex
- node['fontset'] = self.options.get('fontset', 'cm')
- node['fontsize'] = self.options.get('fontsize',
- setup.app.config.mathmpl_fontsize)
- return [node]
-
-
-# This uses mathtext to render the expression
-def latex2png(latex, filename, fontset='cm', fontsize=10, dpi=100):
- with mpl.rc_context({'mathtext.fontset': fontset, 'font.size': fontsize}):
- try:
- depth = mathtext.math_to_image(
- f"${latex}$", filename, dpi=dpi, format="png")
- except Exception:
- _api.warn_external(f"Could not render math expression {latex}")
- depth = 0
- return depth
-
-
-# LaTeX to HTML translation stuff:
-def latex2html(node, source):
- inline = isinstance(node.parent, nodes.TextElement)
- latex = node['latex']
- fontset = node['fontset']
- fontsize = node['fontsize']
- name = 'math-{}'.format(
- hashlib.md5(f'{latex}{fontset}{fontsize}'.encode()).hexdigest()[-10:])
-
- destdir = Path(setup.app.builder.outdir, '_images', 'mathmpl')
- destdir.mkdir(parents=True, exist_ok=True)
-
- dest = destdir / f'{name}.png'
- depth = latex2png(latex, dest, fontset, fontsize=fontsize)
-
- srcset = []
- for size in setup.app.config.mathmpl_srcset:
- filename = f'{name}-{size.replace(".", "_")}.png'
- latex2png(latex, destdir / filename, fontset, fontsize=fontsize,
- dpi=100 * float(size[:-1]))
- srcset.append(
- f'{setup.app.builder.imgpath}/mathmpl/{filename} {size}')
- if srcset:
- srcset = (f'srcset="{setup.app.builder.imgpath}/mathmpl/{name}.png, ' +
- ', '.join(srcset) + '" ')
-
- if inline:
- cls = ''
- else:
- cls = 'class="center" '
- if inline and depth != 0:
- style = 'style="position: relative; bottom: -%dpx"' % (depth + 1)
- else:
- style = ''
-
- return (f'<img src="{setup.app.builder.imgpath}/mathmpl/{name}.png"'
- f' {srcset}{cls}{style}/>')
-
-
-def _config_inited(app, config):
- # Check for srcset hidpi images
- for i, size in enumerate(app.config.mathmpl_srcset):
- if size[-1] == 'x': # "2x" = "2.0"
- try:
- float(size[:-1])
- except ValueError:
- raise ConfigError(
- f'Invalid value for mathmpl_srcset parameter: {size!r}. '
- 'Must be a list of strings with the multiplicative '
- 'factor followed by an "x". e.g. ["2.0x", "1.5x"]')
- else:
- raise ConfigError(
- f'Invalid value for mathmpl_srcset parameter: {size!r}. '
- 'Must be a list of strings with the multiplicative '
- 'factor followed by an "x". e.g. ["2.0x", "1.5x"]')
-
-
-def setup(app):
- setup.app = app
- app.add_config_value('mathmpl_fontsize', 10.0, True)
- app.add_config_value('mathmpl_srcset', [], True)
- try:
- app.connect('config-inited', _config_inited) # Sphinx 1.8+
- except ExtensionError:
- app.connect('env-updated', lambda app, env: _config_inited(app, None))
-
- # Add visit/depart methods to HTML-Translator:
- def visit_latex_math_html(self, node):
- source = self.document.attributes['source']
- self.body.append(latex2html(node, source))
-
- def depart_latex_math_html(self, node):
- pass
-
- # Add visit/depart methods to LaTeX-Translator:
- def visit_latex_math_latex(self, node):
- inline = isinstance(node.parent, nodes.TextElement)
- if inline:
- self.body.append('$%s$' % node['latex'])
- else:
- self.body.extend(['\\begin{equation}',
- node['latex'],
- '\\end{equation}'])
-
- def depart_latex_math_latex(self, node):
- pass
-
- app.add_node(latex_math,
- html=(visit_latex_math_html, depart_latex_math_html),
- latex=(visit_latex_math_latex, depart_latex_math_latex))
- app.add_role('mathmpl', math_role)
- app.add_directive('mathmpl', MathDirective)
- if sphinx.version_info < (1, 8):
- app.add_role('math', math_role)
- app.add_directive('math', MathDirective)
-
- metadata = {'parallel_read_safe': True, 'parallel_write_safe': True}
- return metadata
diff --git a/contrib/python/matplotlib/py3/matplotlib/sphinxext/plot_directive.py b/contrib/python/matplotlib/py3/matplotlib/sphinxext/plot_directive.py
deleted file mode 100644
index 65b25fb913..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/sphinxext/plot_directive.py
+++ /dev/null
@@ -1,933 +0,0 @@
-"""
-A directive for including a Matplotlib plot in a Sphinx document
-================================================================
-
-This is a Sphinx extension providing a reStructuredText directive
-``.. plot::`` for including a plot in a Sphinx document.
-
-In HTML output, ``.. plot::`` will include a .png file with a link
-to a high-res .png and .pdf. In LaTeX output, it will include a .pdf.
-
-The plot content may be defined in one of three ways:
-
-1. **A path to a source file** as the argument to the directive::
-
- .. plot:: path/to/plot.py
-
- When a path to a source file is given, the content of the
- directive may optionally contain a caption for the plot::
-
- .. plot:: path/to/plot.py
-
- The plot caption.
-
- Additionally, one may specify the name of a function to call (with
- no arguments) immediately after importing the module::
-
- .. plot:: path/to/plot.py plot_function1
-
-2. Included as **inline content** to the directive::
-
- .. plot::
-
- import matplotlib.pyplot as plt
- plt.plot([1, 2, 3], [4, 5, 6])
- plt.title("A plotting exammple")
-
-3. Using **doctest** syntax::
-
- .. plot::
-
- A plotting example:
- >>> import matplotlib.pyplot as plt
- >>> plt.plot([1, 2, 3], [4, 5, 6])
-
-Options
--------
-
-The ``.. plot::`` directive supports the following options:
-
-``:format:`` : {'python', 'doctest'}
- The format of the input. If unset, the format is auto-detected.
-
-``:include-source:`` : bool
- Whether to display the source code. The default can be changed using
- the ``plot_include_source`` variable in :file:`conf.py` (which itself
- defaults to False).
-
-``:show-source-link:`` : bool
- Whether to show a link to the source in HTML. The default can be
- changed using the ``plot_html_show_source_link`` variable in
- :file:`conf.py` (which itself defaults to True).
-
-``:context:`` : bool or str
- If provided, the code will be run in the context of all previous plot
- directives for which the ``:context:`` option was specified. This only
- applies to inline code plot directives, not those run from files. If
- the ``:context: reset`` option is specified, the context is reset
- for this and future plots, and previous figures are closed prior to
- running the code. ``:context: close-figs`` keeps the context but closes
- previous figures before running the code.
-
-``:nofigs:`` : bool
- If specified, the code block will be run, but no figures will be
- inserted. This is usually useful with the ``:context:`` option.
-
-``:caption:`` : str
- If specified, the option's argument will be used as a caption for the
- figure. This overwrites the caption given in the content, when the plot
- is generated from a file.
-
-Additionally, this directive supports all the options of the `image directive
-<https://docutils.sourceforge.io/docs/ref/rst/directives.html#image>`_,
-except for ``:target:`` (since plot will add its own target). These include
-``:alt:``, ``:height:``, ``:width:``, ``:scale:``, ``:align:`` and ``:class:``.
-
-Configuration options
----------------------
-
-The plot directive has the following configuration options:
-
-plot_include_source
- Default value for the include-source option (default: False).
-
-plot_html_show_source_link
- Whether to show a link to the source in HTML (default: True).
-
-plot_pre_code
- Code that should be executed before each plot. If None (the default),
- it will default to a string containing::
-
- import numpy as np
- from matplotlib import pyplot as plt
-
-plot_basedir
- Base directory, to which ``plot::`` file names are relative to.
- If None or empty (the default), file names are relative to the
- directory where the file containing the directive is.
-
-plot_formats
- File formats to generate (default: ['png', 'hires.png', 'pdf']).
- List of tuples or strings::
-
- [(suffix, dpi), suffix, ...]
-
- that determine the file format and the DPI. For entries whose
- DPI was omitted, sensible defaults are chosen. When passing from
- the command line through sphinx_build the list should be passed as
- suffix:dpi,suffix:dpi, ...
-
-plot_html_show_formats
- Whether to show links to the files in HTML (default: True).
-
-plot_rcparams
- A dictionary containing any non-standard rcParams that should
- be applied before each plot (default: {}).
-
-plot_apply_rcparams
- By default, rcParams are applied when ``:context:`` option is not used
- in a plot directive. If set, this configuration option overrides this
- behavior and applies rcParams before each plot.
-
-plot_working_directory
- By default, the working directory will be changed to the directory of
- the example, so the code can get at its data files, if any. Also its
- path will be added to `sys.path` so it can import any helper modules
- sitting beside it. This configuration option can be used to specify
- a central directory (also added to `sys.path`) where data files and
- helper modules for all code are located.
-
-plot_template
- Provide a customized template for preparing restructured text.
-
-plot_srcset
- Allow the srcset image option for responsive image resolutions. List of
- strings with the multiplicative factors followed by an "x".
- e.g. ["2.0x", "1.5x"]. "2.0x" will create a png with the default "png"
- resolution from plot_formats, multiplied by 2. If plot_srcset is
- specified, the plot directive uses the
- :doc:`/api/sphinxext_figmpl_directive_api` (instead of the usual figure
- directive) in the intermediary rst file that is generated.
- The plot_srcset option is incompatible with *singlehtml* builds, and an
- error will be raised.
-
-Notes on how it works
----------------------
-
-The plot directive runs the code it is given, either in the source file or the
-code under the directive. The figure created (if any) is saved in the sphinx
-build directory under a subdirectory named ``plot_directive``. It then creates
-an intermediate rst file that calls a ``.. figure:`` directive (or
-``.. figmpl::`` directive if ``plot_srcset`` is being used) and has links to
-the ``*.png`` files in the ``plot_directive`` directory. These translations can
-be customized by changing the *plot_template*. See the source of
-:doc:`/api/sphinxext_plot_directive_api` for the templates defined in *TEMPLATE*
-and *TEMPLATE_SRCSET*.
-"""
-
-import contextlib
-import doctest
-from io import StringIO
-import itertools
-import os
-from os.path import relpath
-from pathlib import Path
-import re
-import shutil
-import sys
-import textwrap
-import traceback
-
-from docutils.parsers.rst import directives, Directive
-from docutils.parsers.rst.directives.images import Image
-import jinja2 # Sphinx dependency.
-
-from sphinx.errors import ExtensionError
-
-import matplotlib
-from matplotlib.backend_bases import FigureManagerBase
-import matplotlib.pyplot as plt
-from matplotlib import _pylab_helpers, cbook
-
-matplotlib.use("agg")
-
-__version__ = 2
-
-
-# -----------------------------------------------------------------------------
-# Registration hook
-# -----------------------------------------------------------------------------
-
-
-def _option_boolean(arg):
- if not arg or not arg.strip():
- # no argument given, assume used as a flag
- return True
- elif arg.strip().lower() in ('no', '0', 'false'):
- return False
- elif arg.strip().lower() in ('yes', '1', 'true'):
- return True
- else:
- raise ValueError(f'{arg!r} unknown boolean')
-
-
-def _option_context(arg):
- if arg in [None, 'reset', 'close-figs']:
- return arg
- raise ValueError("Argument should be None or 'reset' or 'close-figs'")
-
-
-def _option_format(arg):
- return directives.choice(arg, ('python', 'doctest'))
-
-
-def mark_plot_labels(app, document):
- """
- To make plots referenceable, we need to move the reference from the
- "htmlonly" (or "latexonly") node to the actual figure node itself.
- """
- for name, explicit in document.nametypes.items():
- if not explicit:
- continue
- labelid = document.nameids[name]
- if labelid is None:
- continue
- node = document.ids[labelid]
- if node.tagname in ('html_only', 'latex_only'):
- for n in node:
- if n.tagname == 'figure':
- sectname = name
- for c in n:
- if c.tagname == 'caption':
- sectname = c.astext()
- break
-
- node['ids'].remove(labelid)
- node['names'].remove(name)
- n['ids'].append(labelid)
- n['names'].append(name)
- document.settings.env.labels[name] = \
- document.settings.env.docname, labelid, sectname
- break
-
-
-class PlotDirective(Directive):
- """The ``.. plot::`` directive, as documented in the module's docstring."""
-
- has_content = True
- required_arguments = 0
- optional_arguments = 2
- final_argument_whitespace = False
- option_spec = {
- 'alt': directives.unchanged,
- 'height': directives.length_or_unitless,
- 'width': directives.length_or_percentage_or_unitless,
- 'scale': directives.nonnegative_int,
- 'align': Image.align,
- 'class': directives.class_option,
- 'include-source': _option_boolean,
- 'show-source-link': _option_boolean,
- 'format': _option_format,
- 'context': _option_context,
- 'nofigs': directives.flag,
- 'caption': directives.unchanged,
- }
-
- def run(self):
- """Run the plot directive."""
- try:
- return run(self.arguments, self.content, self.options,
- self.state_machine, self.state, self.lineno)
- except Exception as e:
- raise self.error(str(e))
-
-
-def _copy_css_file(app, exc):
- if exc is None and app.builder.format == 'html':
- src = cbook._get_data_path('plot_directive/plot_directive.css')
- dst = app.outdir / Path('_static')
- dst.mkdir(exist_ok=True)
- # Use copyfile because we do not want to copy src's permissions.
- shutil.copyfile(src, dst / Path('plot_directive.css'))
-
-
-def setup(app):
- setup.app = app
- setup.config = app.config
- setup.confdir = app.confdir
- app.add_directive('plot', PlotDirective)
- app.add_config_value('plot_pre_code', None, True)
- app.add_config_value('plot_include_source', False, True)
- app.add_config_value('plot_html_show_source_link', True, True)
- app.add_config_value('plot_formats', ['png', 'hires.png', 'pdf'], True)
- app.add_config_value('plot_basedir', None, True)
- app.add_config_value('plot_html_show_formats', True, True)
- app.add_config_value('plot_rcparams', {}, True)
- app.add_config_value('plot_apply_rcparams', False, True)
- app.add_config_value('plot_working_directory', None, True)
- app.add_config_value('plot_template', None, True)
- app.add_config_value('plot_srcset', [], True)
- app.connect('doctree-read', mark_plot_labels)
- app.add_css_file('plot_directive.css')
- app.connect('build-finished', _copy_css_file)
- metadata = {'parallel_read_safe': True, 'parallel_write_safe': True,
- 'version': matplotlib.__version__}
- return metadata
-
-
-# -----------------------------------------------------------------------------
-# Doctest handling
-# -----------------------------------------------------------------------------
-
-
-def contains_doctest(text):
- try:
- # check if it's valid Python as-is
- compile(text, '<string>', 'exec')
- return False
- except SyntaxError:
- pass
- r = re.compile(r'^\s*>>>', re.M)
- m = r.search(text)
- return bool(m)
-
-
-def _split_code_at_show(text, function_name):
- """Split code at plt.show()."""
-
- is_doctest = contains_doctest(text)
- if function_name is None:
- parts = []
- part = []
- for line in text.split("\n"):
- if ((not is_doctest and line.startswith('plt.show(')) or
- (is_doctest and line.strip() == '>>> plt.show()')):
- part.append(line)
- parts.append("\n".join(part))
- part = []
- else:
- part.append(line)
- if "\n".join(part).strip():
- parts.append("\n".join(part))
- else:
- parts = [text]
- return is_doctest, parts
-
-
-# -----------------------------------------------------------------------------
-# Template
-# -----------------------------------------------------------------------------
-
-_SOURCECODE = """
-{{ source_code }}
-
-.. only:: html
-
- {% if src_name or (html_show_formats and not multi_image) %}
- (
- {%- if src_name -%}
- :download:`Source code <{{ build_dir }}/{{ src_name }}>`
- {%- endif -%}
- {%- if html_show_formats and not multi_image -%}
- {%- for img in images -%}
- {%- for fmt in img.formats -%}
- {%- if src_name or not loop.first -%}, {% endif -%}
- :download:`{{ fmt }} <{{ build_dir }}/{{ img.basename }}.{{ fmt }}>`
- {%- endfor -%}
- {%- endfor -%}
- {%- endif -%}
- )
- {% endif %}
-"""
-
-TEMPLATE_SRCSET = _SOURCECODE + """
- {% for img in images %}
- .. figure-mpl:: {{ build_dir }}/{{ img.basename }}.{{ default_fmt }}
- {% for option in options -%}
- {{ option }}
- {% endfor %}
- {%- if caption -%}
- {{ caption }} {# appropriate leading whitespace added beforehand #}
- {% endif -%}
- {%- if srcset -%}
- :srcset: {{ build_dir }}/{{ img.basename }}.{{ default_fmt }}
- {%- for sr in srcset -%}
- , {{ build_dir }}/{{ img.basename }}.{{ sr }}.{{ default_fmt }} {{sr}}
- {%- endfor -%}
- {% endif %}
-
- {% if html_show_formats and multi_image %}
- (
- {%- for fmt in img.formats -%}
- {%- if not loop.first -%}, {% endif -%}
- :download:`{{ fmt }} <{{ build_dir }}/{{ img.basename }}.{{ fmt }}>`
- {%- endfor -%}
- )
- {% endif %}
-
-
- {% endfor %}
-
-.. only:: not html
-
- {% for img in images %}
- .. figure-mpl:: {{ build_dir }}/{{ img.basename }}.*
- {% for option in options -%}
- {{ option }}
- {% endfor -%}
-
- {{ caption }} {# appropriate leading whitespace added beforehand #}
- {% endfor %}
-
-"""
-
-TEMPLATE = _SOURCECODE + """
-
- {% for img in images %}
- .. figure:: {{ build_dir }}/{{ img.basename }}.{{ default_fmt }}
- {% for option in options -%}
- {{ option }}
- {% endfor %}
-
- {% if html_show_formats and multi_image -%}
- (
- {%- for fmt in img.formats -%}
- {%- if not loop.first -%}, {% endif -%}
- :download:`{{ fmt }} <{{ build_dir }}/{{ img.basename }}.{{ fmt }}>`
- {%- endfor -%}
- )
- {%- endif -%}
-
- {{ caption }} {# appropriate leading whitespace added beforehand #}
- {% endfor %}
-
-.. only:: not html
-
- {% for img in images %}
- .. figure:: {{ build_dir }}/{{ img.basename }}.*
- {% for option in options -%}
- {{ option }}
- {% endfor -%}
-
- {{ caption }} {# appropriate leading whitespace added beforehand #}
- {% endfor %}
-
-"""
-
-exception_template = """
-.. only:: html
-
- [`source code <%(linkdir)s/%(basename)s.py>`__]
-
-Exception occurred rendering plot.
-
-"""
-
-# the context of the plot for all directives specified with the
-# :context: option
-plot_context = dict()
-
-
-class ImageFile:
- def __init__(self, basename, dirname):
- self.basename = basename
- self.dirname = dirname
- self.formats = []
-
- def filename(self, format):
- return os.path.join(self.dirname, f"{self.basename}.{format}")
-
- def filenames(self):
- return [self.filename(fmt) for fmt in self.formats]
-
-
-def out_of_date(original, derived, includes=None):
- """
- Return whether *derived* is out-of-date relative to *original* or any of
- the RST files included in it using the RST include directive (*includes*).
- *derived* and *original* are full paths, and *includes* is optionally a
- list of full paths which may have been included in the *original*.
- """
- if not os.path.exists(derived):
- return True
-
- if includes is None:
- includes = []
- files_to_check = [original, *includes]
-
- def out_of_date_one(original, derived_mtime):
- return (os.path.exists(original) and
- derived_mtime < os.stat(original).st_mtime)
-
- derived_mtime = os.stat(derived).st_mtime
- return any(out_of_date_one(f, derived_mtime) for f in files_to_check)
-
-
-class PlotError(RuntimeError):
- pass
-
-
-def _run_code(code, code_path, ns=None, function_name=None):
- """
- Import a Python module from a path, and run the function given by
- name, if function_name is not None.
- """
-
- # Change the working directory to the directory of the example, so
- # it can get at its data files, if any. Add its path to sys.path
- # so it can import any helper modules sitting beside it.
- pwd = os.getcwd()
- if setup.config.plot_working_directory is not None:
- try:
- os.chdir(setup.config.plot_working_directory)
- except OSError as err:
- raise OSError(f'{err}\n`plot_working_directory` option in '
- f'Sphinx configuration file must be a valid '
- f'directory path') from err
- except TypeError as err:
- raise TypeError(f'{err}\n`plot_working_directory` option in '
- f'Sphinx configuration file must be a string or '
- f'None') from err
- elif code_path is not None:
- dirname = os.path.abspath(os.path.dirname(code_path))
- os.chdir(dirname)
-
- with cbook._setattr_cm(
- sys, argv=[code_path], path=[os.getcwd(), *sys.path]), \
- contextlib.redirect_stdout(StringIO()):
- try:
- if ns is None:
- ns = {}
- if not ns:
- if setup.config.plot_pre_code is None:
- exec('import numpy as np\n'
- 'from matplotlib import pyplot as plt\n', ns)
- else:
- exec(str(setup.config.plot_pre_code), ns)
- if "__main__" in code:
- ns['__name__'] = '__main__'
-
- # Patch out non-interactive show() to avoid triggering a warning.
- with cbook._setattr_cm(FigureManagerBase, show=lambda self: None):
- exec(code, ns)
- if function_name is not None:
- exec(function_name + "()", ns)
-
- except (Exception, SystemExit) as err:
- raise PlotError(traceback.format_exc()) from err
- finally:
- os.chdir(pwd)
- return ns
-
-
-def clear_state(plot_rcparams, close=True):
- if close:
- plt.close('all')
- matplotlib.rc_file_defaults()
- matplotlib.rcParams.update(plot_rcparams)
-
-
-def get_plot_formats(config):
- default_dpi = {'png': 80, 'hires.png': 200, 'pdf': 200}
- formats = []
- plot_formats = config.plot_formats
- for fmt in plot_formats:
- if isinstance(fmt, str):
- if ':' in fmt:
- suffix, dpi = fmt.split(':')
- formats.append((str(suffix), int(dpi)))
- else:
- formats.append((fmt, default_dpi.get(fmt, 80)))
- elif isinstance(fmt, (tuple, list)) and len(fmt) == 2:
- formats.append((str(fmt[0]), int(fmt[1])))
- else:
- raise PlotError('invalid image format "%r" in plot_formats' % fmt)
- return formats
-
-
-def _parse_srcset(entries):
- """
- Parse srcset for multiples...
- """
- srcset = {}
- for entry in entries:
- entry = entry.strip()
- if len(entry) >= 2:
- mult = entry[:-1]
- srcset[float(mult)] = entry
- else:
- raise ExtensionError(f'srcset argument {entry!r} is invalid.')
- return srcset
-
-
-def render_figures(code, code_path, output_dir, output_base, context,
- function_name, config, context_reset=False,
- close_figs=False,
- code_includes=None):
- """
- Run a pyplot script and save the images in *output_dir*.
-
- Save the images under *output_dir* with file names derived from
- *output_base*
- """
-
- if function_name is not None:
- output_base = f'{output_base}_{function_name}'
- formats = get_plot_formats(config)
-
- # Try to determine if all images already exist
-
- is_doctest, code_pieces = _split_code_at_show(code, function_name)
- # Look for single-figure output files first
- img = ImageFile(output_base, output_dir)
- for format, dpi in formats:
- if context or out_of_date(code_path, img.filename(format),
- includes=code_includes):
- all_exists = False
- break
- img.formats.append(format)
- else:
- all_exists = True
-
- if all_exists:
- return [(code, [img])]
-
- # Then look for multi-figure output files
- results = []
- for i, code_piece in enumerate(code_pieces):
- images = []
- for j in itertools.count():
- if len(code_pieces) > 1:
- img = ImageFile('%s_%02d_%02d' % (output_base, i, j),
- output_dir)
- else:
- img = ImageFile('%s_%02d' % (output_base, j), output_dir)
- for fmt, dpi in formats:
- if context or out_of_date(code_path, img.filename(fmt),
- includes=code_includes):
- all_exists = False
- break
- img.formats.append(fmt)
-
- # assume that if we have one, we have them all
- if not all_exists:
- all_exists = (j > 0)
- break
- images.append(img)
- if not all_exists:
- break
- results.append((code_piece, images))
- else:
- all_exists = True
-
- if all_exists:
- return results
-
- # We didn't find the files, so build them
-
- results = []
- ns = plot_context if context else {}
-
- if context_reset:
- clear_state(config.plot_rcparams)
- plot_context.clear()
-
- close_figs = not context or close_figs
-
- for i, code_piece in enumerate(code_pieces):
-
- if not context or config.plot_apply_rcparams:
- clear_state(config.plot_rcparams, close_figs)
- elif close_figs:
- plt.close('all')
-
- _run_code(doctest.script_from_examples(code_piece) if is_doctest
- else code_piece,
- code_path, ns, function_name)
-
- images = []
- fig_managers = _pylab_helpers.Gcf.get_all_fig_managers()
- for j, figman in enumerate(fig_managers):
- if len(fig_managers) == 1 and len(code_pieces) == 1:
- img = ImageFile(output_base, output_dir)
- elif len(code_pieces) == 1:
- img = ImageFile("%s_%02d" % (output_base, j), output_dir)
- else:
- img = ImageFile("%s_%02d_%02d" % (output_base, i, j),
- output_dir)
- images.append(img)
-
- for fmt, dpi in formats:
- try:
- figman.canvas.figure.savefig(img.filename(fmt), dpi=dpi)
- if fmt == formats[0][0] and config.plot_srcset:
- # save a 2x, 3x etc version of the default...
- srcset = _parse_srcset(config.plot_srcset)
- for mult, suffix in srcset.items():
- fm = f'{suffix}.{fmt}'
- img.formats.append(fm)
- figman.canvas.figure.savefig(img.filename(fm),
- dpi=int(dpi * mult))
- except Exception as err:
- raise PlotError(traceback.format_exc()) from err
- img.formats.append(fmt)
-
- results.append((code_piece, images))
-
- if not context or config.plot_apply_rcparams:
- clear_state(config.plot_rcparams, close=not context)
-
- return results
-
-
-def run(arguments, content, options, state_machine, state, lineno):
- document = state_machine.document
- config = document.settings.env.config
- nofigs = 'nofigs' in options
-
- if config.plot_srcset and setup.app.builder.name == 'singlehtml':
- raise ExtensionError(
- 'plot_srcset option not compatible with single HTML writer')
-
- formats = get_plot_formats(config)
- default_fmt = formats[0][0]
-
- options.setdefault('include-source', config.plot_include_source)
- options.setdefault('show-source-link', config.plot_html_show_source_link)
-
- if 'class' in options:
- # classes are parsed into a list of string, and output by simply
- # printing the list, abusing the fact that RST guarantees to strip
- # non-conforming characters
- options['class'] = ['plot-directive'] + options['class']
- else:
- options.setdefault('class', ['plot-directive'])
- keep_context = 'context' in options
- context_opt = None if not keep_context else options['context']
-
- rst_file = document.attributes['source']
- rst_dir = os.path.dirname(rst_file)
-
- if len(arguments):
- if not config.plot_basedir:
- source_file_name = os.path.join(setup.app.builder.srcdir,
- directives.uri(arguments[0]))
- else:
- source_file_name = os.path.join(setup.confdir, config.plot_basedir,
- directives.uri(arguments[0]))
- # If there is content, it will be passed as a caption.
- caption = '\n'.join(content)
-
- # Enforce unambiguous use of captions.
- if "caption" in options:
- if caption:
- raise ValueError(
- 'Caption specified in both content and options.'
- ' Please remove ambiguity.'
- )
- # Use caption option
- caption = options["caption"]
-
- # If the optional function name is provided, use it
- if len(arguments) == 2:
- function_name = arguments[1]
- else:
- function_name = None
-
- code = Path(source_file_name).read_text(encoding='utf-8')
- output_base = os.path.basename(source_file_name)
- else:
- source_file_name = rst_file
- code = textwrap.dedent("\n".join(map(str, content)))
- counter = document.attributes.get('_plot_counter', 0) + 1
- document.attributes['_plot_counter'] = counter
- base, ext = os.path.splitext(os.path.basename(source_file_name))
- output_base = '%s-%d.py' % (base, counter)
- function_name = None
- caption = options.get('caption', '')
-
- base, source_ext = os.path.splitext(output_base)
- if source_ext in ('.py', '.rst', '.txt'):
- output_base = base
- else:
- source_ext = ''
-
- # ensure that LaTeX includegraphics doesn't choke in foo.bar.pdf filenames
- output_base = output_base.replace('.', '-')
-
- # is it in doctest format?
- is_doctest = contains_doctest(code)
- if 'format' in options:
- if options['format'] == 'python':
- is_doctest = False
- else:
- is_doctest = True
-
- # determine output directory name fragment
- source_rel_name = relpath(source_file_name, setup.confdir)
- source_rel_dir = os.path.dirname(source_rel_name).lstrip(os.path.sep)
-
- # build_dir: where to place output files (temporarily)
- build_dir = os.path.join(os.path.dirname(setup.app.doctreedir),
- 'plot_directive',
- source_rel_dir)
- # get rid of .. in paths, also changes pathsep
- # see note in Python docs for warning about symbolic links on Windows.
- # need to compare source and dest paths at end
- build_dir = os.path.normpath(build_dir)
- os.makedirs(build_dir, exist_ok=True)
-
- # how to link to files from the RST file
- try:
- build_dir_link = relpath(build_dir, rst_dir).replace(os.path.sep, '/')
- except ValueError:
- # on Windows, relpath raises ValueError when path and start are on
- # different mounts/drives
- build_dir_link = build_dir
-
- # get list of included rst files so that the output is updated when any
- # plots in the included files change. These attributes are modified by the
- # include directive (see the docutils.parsers.rst.directives.misc module).
- try:
- source_file_includes = [os.path.join(os.getcwd(), t[0])
- for t in state.document.include_log]
- except AttributeError:
- # the document.include_log attribute only exists in docutils >=0.17,
- # before that we need to inspect the state machine
- possible_sources = {os.path.join(setup.confdir, t[0])
- for t in state_machine.input_lines.items}
- source_file_includes = [f for f in possible_sources
- if os.path.isfile(f)]
- # remove the source file itself from the includes
- try:
- source_file_includes.remove(source_file_name)
- except ValueError:
- pass
-
- # save script (if necessary)
- if options['show-source-link']:
- Path(build_dir, output_base + source_ext).write_text(
- doctest.script_from_examples(code)
- if source_file_name == rst_file and is_doctest
- else code,
- encoding='utf-8')
-
- # make figures
- try:
- results = render_figures(code=code,
- code_path=source_file_name,
- output_dir=build_dir,
- output_base=output_base,
- context=keep_context,
- function_name=function_name,
- config=config,
- context_reset=context_opt == 'reset',
- close_figs=context_opt == 'close-figs',
- code_includes=source_file_includes)
- errors = []
- except PlotError as err:
- reporter = state.memo.reporter
- sm = reporter.system_message(
- 2, "Exception occurred in plotting {}\n from {}:\n{}".format(
- output_base, source_file_name, err),
- line=lineno)
- results = [(code, [])]
- errors = [sm]
-
- # Properly indent the caption
- if caption and config.plot_srcset:
- caption = f':caption: {caption}'
- elif caption:
- caption = '\n' + '\n'.join(' ' + line.strip()
- for line in caption.split('\n'))
- # generate output restructuredtext
- total_lines = []
- for j, (code_piece, images) in enumerate(results):
- if options['include-source']:
- if is_doctest:
- lines = ['', *code_piece.splitlines()]
- else:
- lines = ['.. code-block:: python', '',
- *textwrap.indent(code_piece, ' ').splitlines()]
- source_code = "\n".join(lines)
- else:
- source_code = ""
-
- if nofigs:
- images = []
-
- opts = [
- f':{key}: {val}' for key, val in options.items()
- if key in ('alt', 'height', 'width', 'scale', 'align', 'class')]
-
- # Not-None src_name signals the need for a source download in the
- # generated html
- if j == 0 and options['show-source-link']:
- src_name = output_base + source_ext
- else:
- src_name = None
- if config.plot_srcset:
- srcset = [*_parse_srcset(config.plot_srcset).values()]
- template = TEMPLATE_SRCSET
- else:
- srcset = None
- template = TEMPLATE
-
- result = jinja2.Template(config.plot_template or template).render(
- default_fmt=default_fmt,
- build_dir=build_dir_link,
- src_name=src_name,
- multi_image=len(images) > 1,
- options=opts,
- srcset=srcset,
- images=images,
- source_code=source_code,
- html_show_formats=config.plot_html_show_formats and len(images),
- caption=caption)
- total_lines.extend(result.split("\n"))
- total_lines.extend("\n")
-
- if total_lines:
- state_machine.insert_input(total_lines, source=source_file_name)
-
- return errors
diff --git a/contrib/python/matplotlib/py3/matplotlib/spines.py b/contrib/python/matplotlib/py3/matplotlib/spines.py
deleted file mode 100644
index 9077ae478d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/spines.py
+++ /dev/null
@@ -1,595 +0,0 @@
-from collections.abc import MutableMapping
-import functools
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, _docstring
-from matplotlib.artist import allow_rasterization
-import matplotlib.transforms as mtransforms
-import matplotlib.patches as mpatches
-import matplotlib.path as mpath
-
-
-class Spine(mpatches.Patch):
- """
- An axis spine -- the line noting the data area boundaries.
-
- Spines are the lines connecting the axis tick marks and noting the
- boundaries of the data area. They can be placed at arbitrary
- positions. See `~.Spine.set_position` for more information.
-
- The default position is ``('outward', 0)``.
-
- Spines are subclasses of `.Patch`, and inherit much of their behavior.
-
- Spines draw a line, a circle, or an arc depending on if
- `~.Spine.set_patch_line`, `~.Spine.set_patch_circle`, or
- `~.Spine.set_patch_arc` has been called. Line-like is the default.
-
- For examples see :ref:`spines_examples`.
- """
- def __str__(self):
- return "Spine"
-
- @_docstring.dedent_interpd
- def __init__(self, axes, spine_type, path, **kwargs):
- """
- Parameters
- ----------
- axes : `~matplotlib.axes.Axes`
- The `~.axes.Axes` instance containing the spine.
- spine_type : str
- The spine type.
- path : `~matplotlib.path.Path`
- The `.Path` instance used to draw the spine.
-
- Other Parameters
- ----------------
- **kwargs
- Valid keyword arguments are:
-
- %(Patch:kwdoc)s
- """
- super().__init__(**kwargs)
- self.axes = axes
- self.set_figure(self.axes.figure)
- self.spine_type = spine_type
- self.set_facecolor('none')
- self.set_edgecolor(mpl.rcParams['axes.edgecolor'])
- self.set_linewidth(mpl.rcParams['axes.linewidth'])
- self.set_capstyle('projecting')
- self.axis = None
-
- self.set_zorder(2.5)
- self.set_transform(self.axes.transData) # default transform
-
- self._bounds = None # default bounds
-
- # Defer initial position determination. (Not much support for
- # non-rectangular axes is currently implemented, and this lets
- # them pass through the spines machinery without errors.)
- self._position = None
- _api.check_isinstance(mpath.Path, path=path)
- self._path = path
-
- # To support drawing both linear and circular spines, this
- # class implements Patch behavior three ways. If
- # self._patch_type == 'line', behave like a mpatches.PathPatch
- # instance. If self._patch_type == 'circle', behave like a
- # mpatches.Ellipse instance. If self._patch_type == 'arc', behave like
- # a mpatches.Arc instance.
- self._patch_type = 'line'
-
- # Behavior copied from mpatches.Ellipse:
- # Note: This cannot be calculated until this is added to an Axes
- self._patch_transform = mtransforms.IdentityTransform()
-
- def set_patch_arc(self, center, radius, theta1, theta2):
- """Set the spine to be arc-like."""
- self._patch_type = 'arc'
- self._center = center
- self._width = radius * 2
- self._height = radius * 2
- self._theta1 = theta1
- self._theta2 = theta2
- self._path = mpath.Path.arc(theta1, theta2)
- # arc drawn on axes transform
- self.set_transform(self.axes.transAxes)
- self.stale = True
-
- def set_patch_circle(self, center, radius):
- """Set the spine to be circular."""
- self._patch_type = 'circle'
- self._center = center
- self._width = radius * 2
- self._height = radius * 2
- # circle drawn on axes transform
- self.set_transform(self.axes.transAxes)
- self.stale = True
-
- def set_patch_line(self):
- """Set the spine to be linear."""
- self._patch_type = 'line'
- self.stale = True
-
- # Behavior copied from mpatches.Ellipse:
- def _recompute_transform(self):
- """
- Notes
- -----
- This cannot be called until after this has been added to an Axes,
- otherwise unit conversion will fail. This makes it very important to
- call the accessor method and not directly access the transformation
- member variable.
- """
- assert self._patch_type in ('arc', 'circle')
- center = (self.convert_xunits(self._center[0]),
- self.convert_yunits(self._center[1]))
- width = self.convert_xunits(self._width)
- height = self.convert_yunits(self._height)
- self._patch_transform = mtransforms.Affine2D() \
- .scale(width * 0.5, height * 0.5) \
- .translate(*center)
-
- def get_patch_transform(self):
- if self._patch_type in ('arc', 'circle'):
- self._recompute_transform()
- return self._patch_transform
- else:
- return super().get_patch_transform()
-
- def get_window_extent(self, renderer=None):
- """
- Return the window extent of the spines in display space, including
- padding for ticks (but not their labels)
-
- See Also
- --------
- matplotlib.axes.Axes.get_tightbbox
- matplotlib.axes.Axes.get_window_extent
- """
- # make sure the location is updated so that transforms etc are correct:
- self._adjust_location()
- bb = super().get_window_extent(renderer=renderer)
- if self.axis is None or not self.axis.get_visible():
- return bb
- bboxes = [bb]
- drawn_ticks = self.axis._update_ticks()
-
- major_tick = next(iter({*drawn_ticks} & {*self.axis.majorTicks}), None)
- minor_tick = next(iter({*drawn_ticks} & {*self.axis.minorTicks}), None)
- for tick in [major_tick, minor_tick]:
- if tick is None:
- continue
- bb0 = bb.frozen()
- tickl = tick._size
- tickdir = tick._tickdir
- if tickdir == 'out':
- padout = 1
- padin = 0
- elif tickdir == 'in':
- padout = 0
- padin = 1
- else:
- padout = 0.5
- padin = 0.5
- padout = padout * tickl / 72 * self.figure.dpi
- padin = padin * tickl / 72 * self.figure.dpi
-
- if tick.tick1line.get_visible():
- if self.spine_type == 'left':
- bb0.x0 = bb0.x0 - padout
- bb0.x1 = bb0.x1 + padin
- elif self.spine_type == 'bottom':
- bb0.y0 = bb0.y0 - padout
- bb0.y1 = bb0.y1 + padin
-
- if tick.tick2line.get_visible():
- if self.spine_type == 'right':
- bb0.x1 = bb0.x1 + padout
- bb0.x0 = bb0.x0 - padin
- elif self.spine_type == 'top':
- bb0.y1 = bb0.y1 + padout
- bb0.y0 = bb0.y0 - padout
- bboxes.append(bb0)
-
- return mtransforms.Bbox.union(bboxes)
-
- def get_path(self):
- return self._path
-
- def _ensure_position_is_set(self):
- if self._position is None:
- # default position
- self._position = ('outward', 0.0) # in points
- self.set_position(self._position)
-
- def register_axis(self, axis):
- """
- Register an axis.
-
- An axis should be registered with its corresponding spine from
- the Axes instance. This allows the spine to clear any axis
- properties when needed.
- """
- self.axis = axis
- self.stale = True
-
- def clear(self):
- """Clear the current spine."""
- self._clear()
- if self.axis is not None:
- self.axis.clear()
-
- def _clear(self):
- """
- Clear things directly related to the spine.
-
- In this way it is possible to avoid clearing the Axis as well when calling
- from library code where it is known that the Axis is cleared separately.
- """
- self._position = None # clear position
-
- def _adjust_location(self):
- """Automatically set spine bounds to the view interval."""
-
- if self.spine_type == 'circle':
- return
-
- if self._bounds is not None:
- low, high = self._bounds
- elif self.spine_type in ('left', 'right'):
- low, high = self.axes.viewLim.intervaly
- elif self.spine_type in ('top', 'bottom'):
- low, high = self.axes.viewLim.intervalx
- else:
- raise ValueError(f'unknown spine spine_type: {self.spine_type}')
-
- if self._patch_type == 'arc':
- if self.spine_type in ('bottom', 'top'):
- try:
- direction = self.axes.get_theta_direction()
- except AttributeError:
- direction = 1
- try:
- offset = self.axes.get_theta_offset()
- except AttributeError:
- offset = 0
- low = low * direction + offset
- high = high * direction + offset
- if low > high:
- low, high = high, low
-
- self._path = mpath.Path.arc(np.rad2deg(low), np.rad2deg(high))
-
- if self.spine_type == 'bottom':
- rmin, rmax = self.axes.viewLim.intervaly
- try:
- rorigin = self.axes.get_rorigin()
- except AttributeError:
- rorigin = rmin
- scaled_diameter = (rmin - rorigin) / (rmax - rorigin)
- self._height = scaled_diameter
- self._width = scaled_diameter
-
- else:
- raise ValueError('unable to set bounds for spine "%s"' %
- self.spine_type)
- else:
- v1 = self._path.vertices
- assert v1.shape == (2, 2), 'unexpected vertices shape'
- if self.spine_type in ['left', 'right']:
- v1[0, 1] = low
- v1[1, 1] = high
- elif self.spine_type in ['bottom', 'top']:
- v1[0, 0] = low
- v1[1, 0] = high
- else:
- raise ValueError('unable to set bounds for spine "%s"' %
- self.spine_type)
-
- @allow_rasterization
- def draw(self, renderer):
- self._adjust_location()
- ret = super().draw(renderer)
- self.stale = False
- return ret
-
- def set_position(self, position):
- """
- Set the position of the spine.
-
- Spine position is specified by a 2 tuple of (position type,
- amount). The position types are:
-
- * 'outward': place the spine out from the data area by the specified
- number of points. (Negative values place the spine inwards.)
- * 'axes': place the spine at the specified Axes coordinate (0 to 1).
- * 'data': place the spine at the specified data coordinate.
-
- Additionally, shorthand notations define a special positions:
-
- * 'center' -> ``('axes', 0.5)``
- * 'zero' -> ``('data', 0.0)``
-
- Examples
- --------
- :doc:`/gallery/spines/spine_placement_demo`
- """
- if position in ('center', 'zero'): # special positions
- pass
- else:
- if len(position) != 2:
- raise ValueError("position should be 'center' or 2-tuple")
- if position[0] not in ['outward', 'axes', 'data']:
- raise ValueError("position[0] should be one of 'outward', "
- "'axes', or 'data' ")
- self._position = position
- self.set_transform(self.get_spine_transform())
- if self.axis is not None:
- self.axis.reset_ticks()
- self.stale = True
-
- def get_position(self):
- """Return the spine position."""
- self._ensure_position_is_set()
- return self._position
-
- def get_spine_transform(self):
- """Return the spine transform."""
- self._ensure_position_is_set()
-
- position = self._position
- if isinstance(position, str):
- if position == 'center':
- position = ('axes', 0.5)
- elif position == 'zero':
- position = ('data', 0)
- assert len(position) == 2, 'position should be 2-tuple'
- position_type, amount = position
- _api.check_in_list(['axes', 'outward', 'data'],
- position_type=position_type)
- if self.spine_type in ['left', 'right']:
- base_transform = self.axes.get_yaxis_transform(which='grid')
- elif self.spine_type in ['top', 'bottom']:
- base_transform = self.axes.get_xaxis_transform(which='grid')
- else:
- raise ValueError(f'unknown spine spine_type: {self.spine_type!r}')
-
- if position_type == 'outward':
- if amount == 0: # short circuit commonest case
- return base_transform
- else:
- offset_vec = {'left': (-1, 0), 'right': (1, 0),
- 'bottom': (0, -1), 'top': (0, 1),
- }[self.spine_type]
- # calculate x and y offset in dots
- offset_dots = amount * np.array(offset_vec) / 72
- return (base_transform
- + mtransforms.ScaledTranslation(
- *offset_dots, self.figure.dpi_scale_trans))
- elif position_type == 'axes':
- if self.spine_type in ['left', 'right']:
- # keep y unchanged, fix x at amount
- return (mtransforms.Affine2D.from_values(0, 0, 0, 1, amount, 0)
- + base_transform)
- elif self.spine_type in ['bottom', 'top']:
- # keep x unchanged, fix y at amount
- return (mtransforms.Affine2D.from_values(1, 0, 0, 0, 0, amount)
- + base_transform)
- elif position_type == 'data':
- if self.spine_type in ('right', 'top'):
- # The right and top spines have a default position of 1 in
- # axes coordinates. When specifying the position in data
- # coordinates, we need to calculate the position relative to 0.
- amount -= 1
- if self.spine_type in ('left', 'right'):
- return mtransforms.blended_transform_factory(
- mtransforms.Affine2D().translate(amount, 0)
- + self.axes.transData,
- self.axes.transData)
- elif self.spine_type in ('bottom', 'top'):
- return mtransforms.blended_transform_factory(
- self.axes.transData,
- mtransforms.Affine2D().translate(0, amount)
- + self.axes.transData)
-
- def set_bounds(self, low=None, high=None):
- """
- Set the spine bounds.
-
- Parameters
- ----------
- low : float or None, optional
- The lower spine bound. Passing *None* leaves the limit unchanged.
-
- The bounds may also be passed as the tuple (*low*, *high*) as the
- first positional argument.
-
- .. ACCEPTS: (low: float, high: float)
-
- high : float or None, optional
- The higher spine bound. Passing *None* leaves the limit unchanged.
- """
- if self.spine_type == 'circle':
- raise ValueError(
- 'set_bounds() method incompatible with circular spines')
- if high is None and np.iterable(low):
- low, high = low
- old_low, old_high = self.get_bounds() or (None, None)
- if low is None:
- low = old_low
- if high is None:
- high = old_high
- self._bounds = (low, high)
- self.stale = True
-
- def get_bounds(self):
- """Get the bounds of the spine."""
- return self._bounds
-
- @classmethod
- def linear_spine(cls, axes, spine_type, **kwargs):
- """Create and return a linear `Spine`."""
- # all values of 0.999 get replaced upon call to set_bounds()
- if spine_type == 'left':
- path = mpath.Path([(0.0, 0.999), (0.0, 0.999)])
- elif spine_type == 'right':
- path = mpath.Path([(1.0, 0.999), (1.0, 0.999)])
- elif spine_type == 'bottom':
- path = mpath.Path([(0.999, 0.0), (0.999, 0.0)])
- elif spine_type == 'top':
- path = mpath.Path([(0.999, 1.0), (0.999, 1.0)])
- else:
- raise ValueError('unable to make path for spine "%s"' % spine_type)
- result = cls(axes, spine_type, path, **kwargs)
- result.set_visible(mpl.rcParams[f'axes.spines.{spine_type}'])
-
- return result
-
- @classmethod
- def arc_spine(cls, axes, spine_type, center, radius, theta1, theta2,
- **kwargs):
- """Create and return an arc `Spine`."""
- path = mpath.Path.arc(theta1, theta2)
- result = cls(axes, spine_type, path, **kwargs)
- result.set_patch_arc(center, radius, theta1, theta2)
- return result
-
- @classmethod
- def circular_spine(cls, axes, center, radius, **kwargs):
- """Create and return a circular `Spine`."""
- path = mpath.Path.unit_circle()
- spine_type = 'circle'
- result = cls(axes, spine_type, path, **kwargs)
- result.set_patch_circle(center, radius)
- return result
-
- def set_color(self, c):
- """
- Set the edgecolor.
-
- Parameters
- ----------
- c : color
-
- Notes
- -----
- This method does not modify the facecolor (which defaults to "none"),
- unlike the `.Patch.set_color` method defined in the parent class. Use
- `.Patch.set_facecolor` to set the facecolor.
- """
- self.set_edgecolor(c)
- self.stale = True
-
-
-class SpinesProxy:
- """
- A proxy to broadcast ``set_*()`` and ``set()`` method calls to contained `.Spines`.
-
- The proxy cannot be used for any other operations on its members.
-
- The supported methods are determined dynamically based on the contained
- spines. If not all spines support a given method, it's executed only on
- the subset of spines that support it.
- """
- def __init__(self, spine_dict):
- self._spine_dict = spine_dict
-
- def __getattr__(self, name):
- broadcast_targets = [spine for spine in self._spine_dict.values()
- if hasattr(spine, name)]
- if (name != 'set' and not name.startswith('set_')) or not broadcast_targets:
- raise AttributeError(
- f"'SpinesProxy' object has no attribute '{name}'")
-
- def x(_targets, _funcname, *args, **kwargs):
- for spine in _targets:
- getattr(spine, _funcname)(*args, **kwargs)
- x = functools.partial(x, broadcast_targets, name)
- x.__doc__ = broadcast_targets[0].__doc__
- return x
-
- def __dir__(self):
- names = []
- for spine in self._spine_dict.values():
- names.extend(name
- for name in dir(spine) if name.startswith('set_'))
- return list(sorted(set(names)))
-
-
-class Spines(MutableMapping):
- r"""
- The container of all `.Spine`\s in an Axes.
-
- The interface is dict-like mapping names (e.g. 'left') to `.Spine` objects.
- Additionally, it implements some pandas.Series-like features like accessing
- elements by attribute::
-
- spines['top'].set_visible(False)
- spines.top.set_visible(False)
-
- Multiple spines can be addressed simultaneously by passing a list::
-
- spines[['top', 'right']].set_visible(False)
-
- Use an open slice to address all spines::
-
- spines[:].set_visible(False)
-
- The latter two indexing methods will return a `SpinesProxy` that broadcasts all
- ``set_*()`` and ``set()`` calls to its members, but cannot be used for any other
- operation.
- """
- def __init__(self, **kwargs):
- self._dict = kwargs
-
- @classmethod
- def from_dict(cls, d):
- return cls(**d)
-
- def __getstate__(self):
- return self._dict
-
- def __setstate__(self, state):
- self.__init__(**state)
-
- def __getattr__(self, name):
- try:
- return self._dict[name]
- except KeyError:
- raise AttributeError(
- f"'Spines' object does not contain a '{name}' spine")
-
- def __getitem__(self, key):
- if isinstance(key, list):
- unknown_keys = [k for k in key if k not in self._dict]
- if unknown_keys:
- raise KeyError(', '.join(unknown_keys))
- return SpinesProxy({k: v for k, v in self._dict.items()
- if k in key})
- if isinstance(key, tuple):
- raise ValueError('Multiple spines must be passed as a single list')
- if isinstance(key, slice):
- if key.start is None and key.stop is None and key.step is None:
- return SpinesProxy(self._dict)
- else:
- raise ValueError(
- 'Spines does not support slicing except for the fully '
- 'open slice [:] to access all spines.')
- return self._dict[key]
-
- def __setitem__(self, key, value):
- # TODO: Do we want to deprecate adding spines?
- self._dict[key] = value
-
- def __delitem__(self, key):
- # TODO: Do we want to deprecate deleting spines?
- del self._dict[key]
-
- def __iter__(self):
- return iter(self._dict)
-
- def __len__(self):
- return len(self._dict)
diff --git a/contrib/python/matplotlib/py3/matplotlib/spines.pyi b/contrib/python/matplotlib/py3/matplotlib/spines.pyi
deleted file mode 100644
index 0f06a6d1ce..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/spines.pyi
+++ /dev/null
@@ -1,83 +0,0 @@
-from collections.abc import Callable, Iterator, MutableMapping
-from typing import Any, Literal, TypeVar, overload
-
-import matplotlib.patches as mpatches
-from matplotlib.axes import Axes
-from matplotlib.axis import Axis
-from matplotlib.path import Path
-from matplotlib.transforms import Transform
-from matplotlib.typing import ColorType
-
-class Spine(mpatches.Patch):
- axes: Axes
- spine_type: str
- axis: Axis | None
- def __init__(self, axes: Axes, spine_type: str, path: Path, **kwargs) -> None: ...
- def set_patch_arc(
- self, center: tuple[float, float], radius: float, theta1: float, theta2: float
- ) -> None: ...
- def set_patch_circle(self, center: tuple[float, float], radius: float) -> None: ...
- def set_patch_line(self) -> None: ...
- def get_patch_transform(self) -> Transform: ...
- def get_path(self) -> Path: ...
- def register_axis(self, axis: Axis) -> None: ...
- def clear(self) -> None: ...
- def set_position(
- self,
- position: Literal["center", "zero"]
- | tuple[Literal["outward", "axes", "data"], float],
- ) -> None: ...
- def get_position(
- self,
- ) -> Literal["center", "zero"] | tuple[
- Literal["outward", "axes", "data"], float
- ]: ...
- def get_spine_transform(self) -> Transform: ...
- def set_bounds(self, low: float | None = ..., high: float | None = ...) -> None: ...
- def get_bounds(self) -> tuple[float, float]: ...
-
- _T = TypeVar("_T", bound=Spine)
- @classmethod
- def linear_spine(
- cls: type[_T],
- axes: Axes,
- spine_type: Literal["left", "right", "bottom", "top"],
- **kwargs
- ) -> _T: ...
- @classmethod
- def arc_spine(
- cls: type[_T],
- axes: Axes,
- spine_type: Literal["left", "right", "bottom", "top"],
- center: tuple[float, float],
- radius: float,
- theta1: float,
- theta2: float,
- **kwargs
- ) -> _T: ...
- @classmethod
- def circular_spine(
- cls: type[_T], axes: Axes, center: tuple[float, float], radius: float, **kwargs
- ) -> _T: ...
- def set_color(self, c: ColorType | None) -> None: ...
-
-class SpinesProxy:
- def __init__(self, spine_dict: dict[str, Spine]) -> None: ...
- def __getattr__(self, name: str) -> Callable[..., None]: ...
- def __dir__(self) -> list[str]: ...
-
-class Spines(MutableMapping[str, Spine]):
- def __init__(self, **kwargs: Spine) -> None: ...
- @classmethod
- def from_dict(cls, d: dict[str, Spine]) -> Spines: ...
- def __getattr__(self, name: str) -> Spine: ...
- @overload
- def __getitem__(self, key: str) -> Spine: ...
- @overload
- def __getitem__(self, key: list[str]) -> SpinesProxy: ...
- @overload
- def __getitem__(self, key: slice) -> SpinesProxy: ...
- def __setitem__(self, key: str, value: Spine) -> None: ...
- def __delitem__(self, key: str) -> None: ...
- def __iter__(self) -> Iterator[str]: ...
- def __len__(self) -> int: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/stackplot.py b/contrib/python/matplotlib/py3/matplotlib/stackplot.py
deleted file mode 100644
index 2629593683..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/stackplot.py
+++ /dev/null
@@ -1,127 +0,0 @@
-"""
-Stacked area plot for 1D arrays inspired by Douglas Y'barbo's stackoverflow
-answer:
-https://stackoverflow.com/q/2225995/
-
-(https://stackoverflow.com/users/66549/doug)
-"""
-
-import itertools
-
-import numpy as np
-
-from matplotlib import _api
-
-__all__ = ['stackplot']
-
-
-def stackplot(axes, x, *args,
- labels=(), colors=None, baseline='zero',
- **kwargs):
- """
- Draw a stacked area plot.
-
- Parameters
- ----------
- x : (N,) array-like
-
- y : (M, N) array-like
- The data is assumed to be unstacked. Each of the following
- calls is legal::
-
- stackplot(x, y) # where y has shape (M, N)
- stackplot(x, y1, y2, y3) # where y1, y2, y3, y4 have length N
-
- baseline : {'zero', 'sym', 'wiggle', 'weighted_wiggle'}
- Method used to calculate the baseline:
-
- - ``'zero'``: Constant zero baseline, i.e. a simple stacked plot.
- - ``'sym'``: Symmetric around zero and is sometimes called
- 'ThemeRiver'.
- - ``'wiggle'``: Minimizes the sum of the squared slopes.
- - ``'weighted_wiggle'``: Does the same but weights to account for
- size of each layer. It is also called 'Streamgraph'-layout. More
- details can be found at http://leebyron.com/streamgraph/.
-
- labels : list of str, optional
- A sequence of labels to assign to each data series. If unspecified,
- then no labels will be applied to artists.
-
- colors : list of color, optional
- A sequence of colors to be cycled through and used to color the stacked
- areas. The sequence need not be exactly the same length as the number
- of provided *y*, in which case the colors will repeat from the
- beginning.
-
- If not specified, the colors from the Axes property cycle will be used.
-
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- All other keyword arguments are passed to `.Axes.fill_between`.
-
- Returns
- -------
- list of `.PolyCollection`
- A list of `.PolyCollection` instances, one for each element in the
- stacked area plot.
- """
-
- y = np.vstack(args)
-
- labels = iter(labels)
- if colors is not None:
- colors = itertools.cycle(colors)
- else:
- colors = (axes._get_lines.get_next_color() for _ in y)
-
- # Assume data passed has not been 'stacked', so stack it here.
- # We'll need a float buffer for the upcoming calculations.
- stack = np.cumsum(y, axis=0, dtype=np.promote_types(y.dtype, np.float32))
-
- _api.check_in_list(['zero', 'sym', 'wiggle', 'weighted_wiggle'],
- baseline=baseline)
- if baseline == 'zero':
- first_line = 0.
-
- elif baseline == 'sym':
- first_line = -np.sum(y, 0) * 0.5
- stack += first_line[None, :]
-
- elif baseline == 'wiggle':
- m = y.shape[0]
- first_line = (y * (m - 0.5 - np.arange(m)[:, None])).sum(0)
- first_line /= -m
- stack += first_line
-
- elif baseline == 'weighted_wiggle':
- total = np.sum(y, 0)
- # multiply by 1/total (or zero) to avoid infinities in the division:
- inv_total = np.zeros_like(total)
- mask = total > 0
- inv_total[mask] = 1.0 / total[mask]
- increase = np.hstack((y[:, 0:1], np.diff(y)))
- below_size = total - stack
- below_size += 0.5 * y
- move_up = below_size * inv_total
- move_up[:, 0] = 0.5
- center = (move_up - 0.5) * increase
- center = np.cumsum(center.sum(0))
- first_line = center - 0.5 * total
- stack += first_line
-
- # Color between x = 0 and the first array.
- coll = axes.fill_between(x, first_line, stack[0, :],
- facecolor=next(colors), label=next(labels, None),
- **kwargs)
- coll.sticky_edges.y[:] = [0]
- r = [coll]
-
- # Color between array i-1 and array i
- for i in range(len(y) - 1):
- r.append(axes.fill_between(x, stack[i, :], stack[i + 1, :],
- facecolor=next(colors),
- label=next(labels, None),
- **kwargs))
- return r
diff --git a/contrib/python/matplotlib/py3/matplotlib/stackplot.pyi b/contrib/python/matplotlib/py3/matplotlib/stackplot.pyi
deleted file mode 100644
index 503e282665..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/stackplot.pyi
+++ /dev/null
@@ -1,17 +0,0 @@
-from matplotlib.axes import Axes
-from matplotlib.collections import PolyCollection
-
-from collections.abc import Iterable
-from typing import Literal
-from numpy.typing import ArrayLike
-from matplotlib.typing import ColorType
-
-def stackplot(
- axes: Axes,
- x: ArrayLike,
- *args: ArrayLike,
- labels: Iterable[str] = ...,
- colors: Iterable[ColorType] | None = ...,
- baseline: Literal["zero", "sym", "wiggle", "weighted_wiggle"] = ...,
- **kwargs
-) -> list[PolyCollection]: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/streamplot.py b/contrib/python/matplotlib/py3/matplotlib/streamplot.py
deleted file mode 100644
index daae8fc5b3..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/streamplot.py
+++ /dev/null
@@ -1,712 +0,0 @@
-"""
-Streamline plotting for 2D vector fields.
-
-"""
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, cm, patches
-import matplotlib.colors as mcolors
-import matplotlib.collections as mcollections
-import matplotlib.lines as mlines
-
-
-__all__ = ['streamplot']
-
-
-def streamplot(axes, x, y, u, v, density=1, linewidth=None, color=None,
- cmap=None, norm=None, arrowsize=1, arrowstyle='-|>',
- minlength=0.1, transform=None, zorder=None, start_points=None,
- maxlength=4.0, integration_direction='both',
- broken_streamlines=True):
- """
- Draw streamlines of a vector flow.
-
- Parameters
- ----------
- x, y : 1D/2D arrays
- Evenly spaced strictly increasing arrays to make a grid. If 2D, all
- rows of *x* must be equal and all columns of *y* must be equal; i.e.,
- they must be as if generated by ``np.meshgrid(x_1d, y_1d)``.
- u, v : 2D arrays
- *x* and *y*-velocities. The number of rows and columns must match
- the length of *y* and *x*, respectively.
- density : float or (float, float)
- Controls the closeness of streamlines. When ``density = 1``, the domain
- is divided into a 30x30 grid. *density* linearly scales this grid.
- Each cell in the grid can have, at most, one traversing streamline.
- For different densities in each direction, use a tuple
- (density_x, density_y).
- linewidth : float or 2D array
- The width of the streamlines. With a 2D array the line width can be
- varied across the grid. The array must have the same shape as *u*
- and *v*.
- color : color or 2D array
- The streamline color. If given an array, its values are converted to
- colors using *cmap* and *norm*. The array must have the same shape
- as *u* and *v*.
- cmap, norm
- Data normalization and colormapping parameters for *color*; only used
- if *color* is an array of floats. See `~.Axes.imshow` for a detailed
- description.
- arrowsize : float
- Scaling factor for the arrow size.
- arrowstyle : str
- Arrow style specification.
- See `~matplotlib.patches.FancyArrowPatch`.
- minlength : float
- Minimum length of streamline in axes coordinates.
- start_points : (N, 2) array
- Coordinates of starting points for the streamlines in data coordinates
- (the same coordinates as the *x* and *y* arrays).
- zorder : float
- The zorder of the streamlines and arrows.
- Artists with lower zorder values are drawn first.
- maxlength : float
- Maximum length of streamline in axes coordinates.
- integration_direction : {'forward', 'backward', 'both'}, default: 'both'
- Integrate the streamline in forward, backward or both directions.
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
- broken_streamlines : boolean, default: True
- If False, forces streamlines to continue until they
- leave the plot domain. If True, they may be terminated if they
- come too close to another streamline.
-
- Returns
- -------
- StreamplotSet
- Container object with attributes
-
- - ``lines``: `.LineCollection` of streamlines
-
- - ``arrows``: `.PatchCollection` containing `.FancyArrowPatch`
- objects representing the arrows half-way along streamlines.
-
- This container will probably change in the future to allow changes
- to the colormap, alpha, etc. for both lines and arrows, but these
- changes should be backward compatible.
- """
- grid = Grid(x, y)
- mask = StreamMask(density)
- dmap = DomainMap(grid, mask)
-
- if zorder is None:
- zorder = mlines.Line2D.zorder
-
- # default to data coordinates
- if transform is None:
- transform = axes.transData
-
- if color is None:
- color = axes._get_lines.get_next_color()
-
- if linewidth is None:
- linewidth = mpl.rcParams['lines.linewidth']
-
- line_kw = {}
- arrow_kw = dict(arrowstyle=arrowstyle, mutation_scale=10 * arrowsize)
-
- _api.check_in_list(['both', 'forward', 'backward'],
- integration_direction=integration_direction)
-
- if integration_direction == 'both':
- maxlength /= 2.
-
- use_multicolor_lines = isinstance(color, np.ndarray)
- if use_multicolor_lines:
- if color.shape != grid.shape:
- raise ValueError("If 'color' is given, it must match the shape of "
- "the (x, y) grid")
- line_colors = [[]] # Empty entry allows concatenation of zero arrays.
- color = np.ma.masked_invalid(color)
- else:
- line_kw['color'] = color
- arrow_kw['color'] = color
-
- if isinstance(linewidth, np.ndarray):
- if linewidth.shape != grid.shape:
- raise ValueError("If 'linewidth' is given, it must match the "
- "shape of the (x, y) grid")
- line_kw['linewidth'] = []
- else:
- line_kw['linewidth'] = linewidth
- arrow_kw['linewidth'] = linewidth
-
- line_kw['zorder'] = zorder
- arrow_kw['zorder'] = zorder
-
- # Sanity checks.
- if u.shape != grid.shape or v.shape != grid.shape:
- raise ValueError("'u' and 'v' must match the shape of the (x, y) grid")
-
- u = np.ma.masked_invalid(u)
- v = np.ma.masked_invalid(v)
-
- integrate = _get_integrator(u, v, dmap, minlength, maxlength,
- integration_direction)
-
- trajectories = []
- if start_points is None:
- for xm, ym in _gen_starting_points(mask.shape):
- if mask[ym, xm] == 0:
- xg, yg = dmap.mask2grid(xm, ym)
- t = integrate(xg, yg, broken_streamlines)
- if t is not None:
- trajectories.append(t)
- else:
- sp2 = np.asanyarray(start_points, dtype=float).copy()
-
- # Check if start_points are outside the data boundaries
- for xs, ys in sp2:
- if not (grid.x_origin <= xs <= grid.x_origin + grid.width and
- grid.y_origin <= ys <= grid.y_origin + grid.height):
- raise ValueError(f"Starting point ({xs}, {ys}) outside of "
- "data boundaries")
-
- # Convert start_points from data to array coords
- # Shift the seed points from the bottom left of the data so that
- # data2grid works properly.
- sp2[:, 0] -= grid.x_origin
- sp2[:, 1] -= grid.y_origin
-
- for xs, ys in sp2:
- xg, yg = dmap.data2grid(xs, ys)
- # Floating point issues can cause xg, yg to be slightly out of
- # bounds for xs, ys on the upper boundaries. Because we have
- # already checked that the starting points are within the original
- # grid, clip the xg, yg to the grid to work around this issue
- xg = np.clip(xg, 0, grid.nx - 1)
- yg = np.clip(yg, 0, grid.ny - 1)
-
- t = integrate(xg, yg, broken_streamlines)
- if t is not None:
- trajectories.append(t)
-
- if use_multicolor_lines:
- if norm is None:
- norm = mcolors.Normalize(color.min(), color.max())
- cmap = cm._ensure_cmap(cmap)
-
- streamlines = []
- arrows = []
- for t in trajectories:
- tgx, tgy = t.T
- # Rescale from grid-coordinates to data-coordinates.
- tx, ty = dmap.grid2data(tgx, tgy)
- tx += grid.x_origin
- ty += grid.y_origin
-
- # Create multiple tiny segments if varying width or color is given
- if isinstance(linewidth, np.ndarray) or use_multicolor_lines:
- points = np.transpose([tx, ty]).reshape(-1, 1, 2)
- streamlines.extend(np.hstack([points[:-1], points[1:]]))
- else:
- points = np.transpose([tx, ty])
- streamlines.append(points)
-
- # Add arrows halfway along each trajectory.
- s = np.cumsum(np.hypot(np.diff(tx), np.diff(ty)))
- n = np.searchsorted(s, s[-1] / 2.)
- arrow_tail = (tx[n], ty[n])
- arrow_head = (np.mean(tx[n:n + 2]), np.mean(ty[n:n + 2]))
-
- if isinstance(linewidth, np.ndarray):
- line_widths = interpgrid(linewidth, tgx, tgy)[:-1]
- line_kw['linewidth'].extend(line_widths)
- arrow_kw['linewidth'] = line_widths[n]
-
- if use_multicolor_lines:
- color_values = interpgrid(color, tgx, tgy)[:-1]
- line_colors.append(color_values)
- arrow_kw['color'] = cmap(norm(color_values[n]))
-
- p = patches.FancyArrowPatch(
- arrow_tail, arrow_head, transform=transform, **arrow_kw)
- arrows.append(p)
-
- lc = mcollections.LineCollection(
- streamlines, transform=transform, **line_kw)
- lc.sticky_edges.x[:] = [grid.x_origin, grid.x_origin + grid.width]
- lc.sticky_edges.y[:] = [grid.y_origin, grid.y_origin + grid.height]
- if use_multicolor_lines:
- lc.set_array(np.ma.hstack(line_colors))
- lc.set_cmap(cmap)
- lc.set_norm(norm)
- axes.add_collection(lc)
-
- ac = mcollections.PatchCollection(arrows)
- # Adding the collection itself is broken; see #2341.
- for p in arrows:
- axes.add_patch(p)
-
- axes.autoscale_view()
- stream_container = StreamplotSet(lc, ac)
- return stream_container
-
-
-class StreamplotSet:
-
- def __init__(self, lines, arrows):
- self.lines = lines
- self.arrows = arrows
-
-
-# Coordinate definitions
-# ========================
-
-class DomainMap:
- """
- Map representing different coordinate systems.
-
- Coordinate definitions:
-
- * axes-coordinates goes from 0 to 1 in the domain.
- * data-coordinates are specified by the input x-y coordinates.
- * grid-coordinates goes from 0 to N and 0 to M for an N x M grid,
- where N and M match the shape of the input data.
- * mask-coordinates goes from 0 to N and 0 to M for an N x M mask,
- where N and M are user-specified to control the density of streamlines.
-
- This class also has methods for adding trajectories to the StreamMask.
- Before adding a trajectory, run `start_trajectory` to keep track of regions
- crossed by a given trajectory. Later, if you decide the trajectory is bad
- (e.g., if the trajectory is very short) just call `undo_trajectory`.
- """
-
- def __init__(self, grid, mask):
- self.grid = grid
- self.mask = mask
- # Constants for conversion between grid- and mask-coordinates
- self.x_grid2mask = (mask.nx - 1) / (grid.nx - 1)
- self.y_grid2mask = (mask.ny - 1) / (grid.ny - 1)
-
- self.x_mask2grid = 1. / self.x_grid2mask
- self.y_mask2grid = 1. / self.y_grid2mask
-
- self.x_data2grid = 1. / grid.dx
- self.y_data2grid = 1. / grid.dy
-
- def grid2mask(self, xi, yi):
- """Return nearest space in mask-coords from given grid-coords."""
- return round(xi * self.x_grid2mask), round(yi * self.y_grid2mask)
-
- def mask2grid(self, xm, ym):
- return xm * self.x_mask2grid, ym * self.y_mask2grid
-
- def data2grid(self, xd, yd):
- return xd * self.x_data2grid, yd * self.y_data2grid
-
- def grid2data(self, xg, yg):
- return xg / self.x_data2grid, yg / self.y_data2grid
-
- def start_trajectory(self, xg, yg, broken_streamlines=True):
- xm, ym = self.grid2mask(xg, yg)
- self.mask._start_trajectory(xm, ym, broken_streamlines)
-
- def reset_start_point(self, xg, yg):
- xm, ym = self.grid2mask(xg, yg)
- self.mask._current_xy = (xm, ym)
-
- def update_trajectory(self, xg, yg, broken_streamlines=True):
- if not self.grid.within_grid(xg, yg):
- raise InvalidIndexError
- xm, ym = self.grid2mask(xg, yg)
- self.mask._update_trajectory(xm, ym, broken_streamlines)
-
- def undo_trajectory(self):
- self.mask._undo_trajectory()
-
-
-class Grid:
- """Grid of data."""
- def __init__(self, x, y):
-
- if np.ndim(x) == 1:
- pass
- elif np.ndim(x) == 2:
- x_row = x[0]
- if not np.allclose(x_row, x):
- raise ValueError("The rows of 'x' must be equal")
- x = x_row
- else:
- raise ValueError("'x' can have at maximum 2 dimensions")
-
- if np.ndim(y) == 1:
- pass
- elif np.ndim(y) == 2:
- yt = np.transpose(y) # Also works for nested lists.
- y_col = yt[0]
- if not np.allclose(y_col, yt):
- raise ValueError("The columns of 'y' must be equal")
- y = y_col
- else:
- raise ValueError("'y' can have at maximum 2 dimensions")
-
- if not (np.diff(x) > 0).all():
- raise ValueError("'x' must be strictly increasing")
- if not (np.diff(y) > 0).all():
- raise ValueError("'y' must be strictly increasing")
-
- self.nx = len(x)
- self.ny = len(y)
-
- self.dx = x[1] - x[0]
- self.dy = y[1] - y[0]
-
- self.x_origin = x[0]
- self.y_origin = y[0]
-
- self.width = x[-1] - x[0]
- self.height = y[-1] - y[0]
-
- if not np.allclose(np.diff(x), self.width / (self.nx - 1)):
- raise ValueError("'x' values must be equally spaced")
- if not np.allclose(np.diff(y), self.height / (self.ny - 1)):
- raise ValueError("'y' values must be equally spaced")
-
- @property
- def shape(self):
- return self.ny, self.nx
-
- def within_grid(self, xi, yi):
- """Return whether (*xi*, *yi*) is a valid index of the grid."""
- # Note that xi/yi can be floats; so, for example, we can't simply check
- # `xi < self.nx` since *xi* can be `self.nx - 1 < xi < self.nx`
- return 0 <= xi <= self.nx - 1 and 0 <= yi <= self.ny - 1
-
-
-class StreamMask:
- """
- Mask to keep track of discrete regions crossed by streamlines.
-
- The resolution of this grid determines the approximate spacing between
- trajectories. Streamlines are only allowed to pass through zeroed cells:
- When a streamline enters a cell, that cell is set to 1, and no new
- streamlines are allowed to enter.
- """
-
- def __init__(self, density):
- try:
- self.nx, self.ny = (30 * np.broadcast_to(density, 2)).astype(int)
- except ValueError as err:
- raise ValueError("'density' must be a scalar or be of length "
- "2") from err
- if self.nx < 0 or self.ny < 0:
- raise ValueError("'density' must be positive")
- self._mask = np.zeros((self.ny, self.nx))
- self.shape = self._mask.shape
-
- self._current_xy = None
-
- def __getitem__(self, args):
- return self._mask[args]
-
- def _start_trajectory(self, xm, ym, broken_streamlines=True):
- """Start recording streamline trajectory"""
- self._traj = []
- self._update_trajectory(xm, ym, broken_streamlines)
-
- def _undo_trajectory(self):
- """Remove current trajectory from mask"""
- for t in self._traj:
- self._mask[t] = 0
-
- def _update_trajectory(self, xm, ym, broken_streamlines=True):
- """
- Update current trajectory position in mask.
-
- If the new position has already been filled, raise `InvalidIndexError`.
- """
- if self._current_xy != (xm, ym):
- if self[ym, xm] == 0:
- self._traj.append((ym, xm))
- self._mask[ym, xm] = 1
- self._current_xy = (xm, ym)
- else:
- if broken_streamlines:
- raise InvalidIndexError
- else:
- pass
-
-
-class InvalidIndexError(Exception):
- pass
-
-
-class TerminateTrajectory(Exception):
- pass
-
-
-# Integrator definitions
-# =======================
-
-def _get_integrator(u, v, dmap, minlength, maxlength, integration_direction):
-
- # rescale velocity onto grid-coordinates for integrations.
- u, v = dmap.data2grid(u, v)
-
- # speed (path length) will be in axes-coordinates
- u_ax = u / (dmap.grid.nx - 1)
- v_ax = v / (dmap.grid.ny - 1)
- speed = np.ma.sqrt(u_ax ** 2 + v_ax ** 2)
-
- def forward_time(xi, yi):
- if not dmap.grid.within_grid(xi, yi):
- raise OutOfBounds
- ds_dt = interpgrid(speed, xi, yi)
- if ds_dt == 0:
- raise TerminateTrajectory()
- dt_ds = 1. / ds_dt
- ui = interpgrid(u, xi, yi)
- vi = interpgrid(v, xi, yi)
- return ui * dt_ds, vi * dt_ds
-
- def backward_time(xi, yi):
- dxi, dyi = forward_time(xi, yi)
- return -dxi, -dyi
-
- def integrate(x0, y0, broken_streamlines=True):
- """
- Return x, y grid-coordinates of trajectory based on starting point.
-
- Integrate both forward and backward in time from starting point in
- grid coordinates.
-
- Integration is terminated when a trajectory reaches a domain boundary
- or when it crosses into an already occupied cell in the StreamMask. The
- resulting trajectory is None if it is shorter than `minlength`.
- """
-
- stotal, xy_traj = 0., []
-
- try:
- dmap.start_trajectory(x0, y0, broken_streamlines)
- except InvalidIndexError:
- return None
- if integration_direction in ['both', 'backward']:
- s, xyt = _integrate_rk12(x0, y0, dmap, backward_time, maxlength,
- broken_streamlines)
- stotal += s
- xy_traj += xyt[::-1]
-
- if integration_direction in ['both', 'forward']:
- dmap.reset_start_point(x0, y0)
- s, xyt = _integrate_rk12(x0, y0, dmap, forward_time, maxlength,
- broken_streamlines)
- stotal += s
- xy_traj += xyt[1:]
-
- if stotal > minlength:
- return np.broadcast_arrays(xy_traj, np.empty((1, 2)))[0]
- else: # reject short trajectories
- dmap.undo_trajectory()
- return None
-
- return integrate
-
-
-class OutOfBounds(IndexError):
- pass
-
-
-def _integrate_rk12(x0, y0, dmap, f, maxlength, broken_streamlines=True):
- """
- 2nd-order Runge-Kutta algorithm with adaptive step size.
-
- This method is also referred to as the improved Euler's method, or Heun's
- method. This method is favored over higher-order methods because:
-
- 1. To get decent looking trajectories and to sample every mask cell
- on the trajectory we need a small timestep, so a lower order
- solver doesn't hurt us unless the data is *very* high resolution.
- In fact, for cases where the user inputs
- data smaller or of similar grid size to the mask grid, the higher
- order corrections are negligible because of the very fast linear
- interpolation used in `interpgrid`.
-
- 2. For high resolution input data (i.e. beyond the mask
- resolution), we must reduce the timestep. Therefore, an adaptive
- timestep is more suited to the problem as this would be very hard
- to judge automatically otherwise.
-
- This integrator is about 1.5 - 2x as fast as RK4 and RK45 solvers (using
- similar Python implementations) in most setups.
- """
- # This error is below that needed to match the RK4 integrator. It
- # is set for visual reasons -- too low and corners start
- # appearing ugly and jagged. Can be tuned.
- maxerror = 0.003
-
- # This limit is important (for all integrators) to avoid the
- # trajectory skipping some mask cells. We could relax this
- # condition if we use the code which is commented out below to
- # increment the location gradually. However, due to the efficient
- # nature of the interpolation, this doesn't boost speed by much
- # for quite a bit of complexity.
- maxds = min(1. / dmap.mask.nx, 1. / dmap.mask.ny, 0.1)
-
- ds = maxds
- stotal = 0
- xi = x0
- yi = y0
- xyf_traj = []
-
- while True:
- try:
- if dmap.grid.within_grid(xi, yi):
- xyf_traj.append((xi, yi))
- else:
- raise OutOfBounds
-
- # Compute the two intermediate gradients.
- # f should raise OutOfBounds if the locations given are
- # outside the grid.
- k1x, k1y = f(xi, yi)
- k2x, k2y = f(xi + ds * k1x, yi + ds * k1y)
-
- except OutOfBounds:
- # Out of the domain during this step.
- # Take an Euler step to the boundary to improve neatness
- # unless the trajectory is currently empty.
- if xyf_traj:
- ds, xyf_traj = _euler_step(xyf_traj, dmap, f)
- stotal += ds
- break
- except TerminateTrajectory:
- break
-
- dx1 = ds * k1x
- dy1 = ds * k1y
- dx2 = ds * 0.5 * (k1x + k2x)
- dy2 = ds * 0.5 * (k1y + k2y)
-
- ny, nx = dmap.grid.shape
- # Error is normalized to the axes coordinates
- error = np.hypot((dx2 - dx1) / (nx - 1), (dy2 - dy1) / (ny - 1))
-
- # Only save step if within error tolerance
- if error < maxerror:
- xi += dx2
- yi += dy2
- try:
- dmap.update_trajectory(xi, yi, broken_streamlines)
- except InvalidIndexError:
- break
- if stotal + ds > maxlength:
- break
- stotal += ds
-
- # recalculate stepsize based on step error
- if error == 0:
- ds = maxds
- else:
- ds = min(maxds, 0.85 * ds * (maxerror / error) ** 0.5)
-
- return stotal, xyf_traj
-
-
-def _euler_step(xyf_traj, dmap, f):
- """Simple Euler integration step that extends streamline to boundary."""
- ny, nx = dmap.grid.shape
- xi, yi = xyf_traj[-1]
- cx, cy = f(xi, yi)
- if cx == 0:
- dsx = np.inf
- elif cx < 0:
- dsx = xi / -cx
- else:
- dsx = (nx - 1 - xi) / cx
- if cy == 0:
- dsy = np.inf
- elif cy < 0:
- dsy = yi / -cy
- else:
- dsy = (ny - 1 - yi) / cy
- ds = min(dsx, dsy)
- xyf_traj.append((xi + cx * ds, yi + cy * ds))
- return ds, xyf_traj
-
-
-# Utility functions
-# ========================
-
-def interpgrid(a, xi, yi):
- """Fast 2D, linear interpolation on an integer grid"""
-
- Ny, Nx = np.shape(a)
- if isinstance(xi, np.ndarray):
- x = xi.astype(int)
- y = yi.astype(int)
- # Check that xn, yn don't exceed max index
- xn = np.clip(x + 1, 0, Nx - 1)
- yn = np.clip(y + 1, 0, Ny - 1)
- else:
- x = int(xi)
- y = int(yi)
- # conditional is faster than clipping for integers
- if x == (Nx - 1):
- xn = x
- else:
- xn = x + 1
- if y == (Ny - 1):
- yn = y
- else:
- yn = y + 1
-
- a00 = a[y, x]
- a01 = a[y, xn]
- a10 = a[yn, x]
- a11 = a[yn, xn]
- xt = xi - x
- yt = yi - y
- a0 = a00 * (1 - xt) + a01 * xt
- a1 = a10 * (1 - xt) + a11 * xt
- ai = a0 * (1 - yt) + a1 * yt
-
- if not isinstance(xi, np.ndarray):
- if np.ma.is_masked(ai):
- raise TerminateTrajectory
-
- return ai
-
-
-def _gen_starting_points(shape):
- """
- Yield starting points for streamlines.
-
- Trying points on the boundary first gives higher quality streamlines.
- This algorithm starts with a point on the mask corner and spirals inward.
- This algorithm is inefficient, but fast compared to rest of streamplot.
- """
- ny, nx = shape
- xfirst = 0
- yfirst = 1
- xlast = nx - 1
- ylast = ny - 1
- x, y = 0, 0
- direction = 'right'
- for i in range(nx * ny):
- yield x, y
-
- if direction == 'right':
- x += 1
- if x >= xlast:
- xlast -= 1
- direction = 'up'
- elif direction == 'up':
- y += 1
- if y >= ylast:
- ylast -= 1
- direction = 'left'
- elif direction == 'left':
- x -= 1
- if x <= xfirst:
- xfirst += 1
- direction = 'down'
- elif direction == 'down':
- y -= 1
- if y <= yfirst:
- yfirst += 1
- direction = 'right'
diff --git a/contrib/python/matplotlib/py3/matplotlib/streamplot.pyi b/contrib/python/matplotlib/py3/matplotlib/streamplot.pyi
deleted file mode 100644
index 9da83096e5..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/streamplot.pyi
+++ /dev/null
@@ -1,82 +0,0 @@
-from matplotlib.axes import Axes
-from matplotlib.colors import Normalize, Colormap
-from matplotlib.collections import LineCollection, PatchCollection
-from matplotlib.patches import ArrowStyle
-from matplotlib.transforms import Transform
-
-from typing import Literal
-from numpy.typing import ArrayLike
-from .typing import ColorType
-
-def streamplot(
- axes: Axes,
- x: ArrayLike,
- y: ArrayLike,
- u: ArrayLike,
- v: ArrayLike,
- density: float | tuple[float, float] = ...,
- linewidth: float | ArrayLike | None = ...,
- color: ColorType | ArrayLike | None = ...,
- cmap: str | Colormap | None = ...,
- norm: str | Normalize | None = ...,
- arrowsize: float = ...,
- arrowstyle: str | ArrowStyle = ...,
- minlength: float = ...,
- transform: Transform | None = ...,
- zorder: float | None = ...,
- start_points: ArrayLike | None = ...,
- maxlength: float = ...,
- integration_direction: Literal["forward", "backward", "both"] = ...,
- broken_streamlines: bool = ...,
-) -> StreamplotSet: ...
-
-class StreamplotSet:
- lines: LineCollection
- arrows: PatchCollection
- def __init__(self, lines: LineCollection, arrows: PatchCollection) -> None: ...
-
-class DomainMap:
- grid: Grid
- mask: StreamMask
- x_grid2mask: float
- y_grid2mask: float
- x_mask2grid: float
- y_mask2grid: float
- x_data2grid: float
- y_data2grid: float
- def __init__(self, grid: Grid, mask: StreamMask) -> None: ...
- def grid2mask(self, xi: float, yi: float) -> tuple[int, int]: ...
- def mask2grid(self, xm: float, ym: float) -> tuple[float, float]: ...
- def data2grid(self, xd: float, yd: float) -> tuple[float, float]: ...
- def grid2data(self, xg: float, yg: float) -> tuple[float, float]: ...
- def start_trajectory(
- self, xg: float, yg: float, broken_streamlines: bool = ...
- ) -> None: ...
- def reset_start_point(self, xg: float, yg: float) -> None: ...
- def update_trajectory(self, xg, yg, broken_streamlines: bool = ...) -> None: ...
- def undo_trajectory(self) -> None: ...
-
-class Grid:
- nx: int
- ny: int
- dx: float
- dy: float
- x_origin: float
- y_origin: float
- width: float
- height: float
- def __init__(self, x: ArrayLike, y: ArrayLike) -> None: ...
- @property
- def shape(self) -> tuple[int, int]: ...
- def within_grid(self, xi: float, yi: float) -> bool: ...
-
-class StreamMask:
- nx: int
- ny: int
- shape: tuple[int, int]
- def __init__(self, density: float | tuple[float, float]) -> None: ...
- def __getitem__(self, args): ...
-
-class InvalidIndexError(Exception): ...
-class TerminateTrajectory(Exception): ...
-class OutOfBounds(IndexError): ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/style/__init__.py b/contrib/python/matplotlib/py3/matplotlib/style/__init__.py
deleted file mode 100644
index 488c6d6ae1..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/style/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-from .core import available, context, library, reload_library, use
-
-
-__all__ = ["available", "context", "library", "reload_library", "use"]
diff --git a/contrib/python/matplotlib/py3/matplotlib/style/core.py b/contrib/python/matplotlib/py3/matplotlib/style/core.py
deleted file mode 100644
index 7e9008c561..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/style/core.py
+++ /dev/null
@@ -1,245 +0,0 @@
-"""
-Core functions and attributes for the matplotlib style library:
-
-``use``
- Select style sheet to override the current matplotlib settings.
-``context``
- Context manager to use a style sheet temporarily.
-``available``
- List available style sheets.
-``library``
- A dictionary of style names and matplotlib settings.
-"""
-
-import contextlib
-import logging
-import os
-from pathlib import Path
-import sys
-import warnings
-
-if sys.version_info >= (3, 10):
- import importlib.resources as importlib_resources
-else:
- # Even though Py3.9 has importlib.resources, it doesn't properly handle
- # modules added in sys.path.
- import importlib_resources
-
-import matplotlib as mpl
-from matplotlib import _api, _docstring, _rc_params_in_file, rcParamsDefault
-
-_log = logging.getLogger(__name__)
-
-__all__ = ['use', 'context', 'available', 'library', 'reload_library']
-
-
-BASE_LIBRARY_PATH = os.path.join(mpl.get_data_path(), 'stylelib')
-# Users may want multiple library paths, so store a list of paths.
-USER_LIBRARY_PATHS = [os.path.join(mpl.get_configdir(), 'stylelib')]
-STYLE_EXTENSION = 'mplstyle'
-# A list of rcParams that should not be applied from styles
-STYLE_BLACKLIST = {
- 'interactive', 'backend', 'webagg.port', 'webagg.address',
- 'webagg.port_retries', 'webagg.open_in_browser', 'backend_fallback',
- 'toolbar', 'timezone', 'figure.max_open_warning',
- 'figure.raise_window', 'savefig.directory', 'tk.window_focus',
- 'docstring.hardcopy', 'date.epoch'}
-
-
-@_docstring.Substitution(
- "\n".join(map("- {}".format, sorted(STYLE_BLACKLIST, key=str.lower)))
-)
-def use(style):
- """
- Use Matplotlib style settings from a style specification.
-
- The style name of 'default' is reserved for reverting back to
- the default style settings.
-
- .. note::
-
- This updates the `.rcParams` with the settings from the style.
- `.rcParams` not defined in the style are kept.
-
- Parameters
- ----------
- style : str, dict, Path or list
-
- A style specification. Valid options are:
-
- str
- - One of the style names in `.style.available` (a builtin style or
- a style installed in the user library path).
-
- - A dotted name of the form "package.style_name"; in that case,
- "package" should be an importable Python package name, e.g. at
- ``/path/to/package/__init__.py``; the loaded style file is
- ``/path/to/package/style_name.mplstyle``. (Style files in
- subpackages are likewise supported.)
-
- - The path or URL to a style file, which gets loaded by
- `.rc_params_from_file`.
-
- dict
- A mapping of key/value pairs for `matplotlib.rcParams`.
-
- Path
- The path to a style file, which gets loaded by
- `.rc_params_from_file`.
-
- list
- A list of style specifiers (str, Path or dict), which are applied
- from first to last in the list.
-
- Notes
- -----
- The following `.rcParams` are not related to style and will be ignored if
- found in a style specification:
-
- %s
- """
- if isinstance(style, (str, Path)) or hasattr(style, 'keys'):
- # If name is a single str, Path or dict, make it a single element list.
- styles = [style]
- else:
- styles = style
-
- style_alias = {'mpl20': 'default', 'mpl15': 'classic'}
-
- for style in styles:
- if isinstance(style, str):
- style = style_alias.get(style, style)
- if style == "default":
- # Deprecation warnings were already handled when creating
- # rcParamsDefault, no need to reemit them here.
- with _api.suppress_matplotlib_deprecation_warning():
- # don't trigger RcParams.__getitem__('backend')
- style = {k: rcParamsDefault[k] for k in rcParamsDefault
- if k not in STYLE_BLACKLIST}
- elif style in library:
- style = library[style]
- elif "." in style:
- pkg, _, name = style.rpartition(".")
- try:
- path = (importlib_resources.files(pkg)
- / f"{name}.{STYLE_EXTENSION}")
- style = _rc_params_in_file(path)
- except (ModuleNotFoundError, OSError, TypeError) as exc:
- # There is an ambiguity whether a dotted name refers to a
- # package.style_name or to a dotted file path. Currently,
- # we silently try the first form and then the second one;
- # in the future, we may consider forcing file paths to
- # either use Path objects or be prepended with "./" and use
- # the slash as marker for file paths.
- pass
- if isinstance(style, (str, Path)):
- try:
- style = _rc_params_in_file(style)
- except OSError as err:
- raise OSError(
- f"{style!r} is not a valid package style, path of style "
- f"file, URL of style file, or library style name (library "
- f"styles are listed in `style.available`)") from err
- filtered = {}
- for k in style: # don't trigger RcParams.__getitem__('backend')
- if k in STYLE_BLACKLIST:
- _api.warn_external(
- f"Style includes a parameter, {k!r}, that is not "
- f"related to style. Ignoring this parameter.")
- else:
- filtered[k] = style[k]
- mpl.rcParams.update(filtered)
-
-
-@contextlib.contextmanager
-def context(style, after_reset=False):
- """
- Context manager for using style settings temporarily.
-
- Parameters
- ----------
- style : str, dict, Path or list
- A style specification. Valid options are:
-
- str
- - One of the style names in `.style.available` (a builtin style or
- a style installed in the user library path).
-
- - A dotted name of the form "package.style_name"; in that case,
- "package" should be an importable Python package name, e.g. at
- ``/path/to/package/__init__.py``; the loaded style file is
- ``/path/to/package/style_name.mplstyle``. (Style files in
- subpackages are likewise supported.)
-
- - The path or URL to a style file, which gets loaded by
- `.rc_params_from_file`.
- dict
- A mapping of key/value pairs for `matplotlib.rcParams`.
-
- Path
- The path to a style file, which gets loaded by
- `.rc_params_from_file`.
-
- list
- A list of style specifiers (str, Path or dict), which are applied
- from first to last in the list.
-
- after_reset : bool
- If True, apply style after resetting settings to their defaults;
- otherwise, apply style on top of the current settings.
- """
- with mpl.rc_context():
- if after_reset:
- mpl.rcdefaults()
- use(style)
- yield
-
-
-def update_user_library(library):
- """Update style library with user-defined rc files."""
- for stylelib_path in map(os.path.expanduser, USER_LIBRARY_PATHS):
- styles = read_style_directory(stylelib_path)
- update_nested_dict(library, styles)
- return library
-
-
-def read_style_directory(style_dir):
- """Return dictionary of styles defined in *style_dir*."""
- styles = dict()
- for path in Path(style_dir).glob(f"*.{STYLE_EXTENSION}"):
- with warnings.catch_warnings(record=True) as warns:
- styles[path.stem] = _rc_params_in_file(path)
- for w in warns:
- _log.warning('In %s: %s', path, w.message)
- return styles
-
-
-def update_nested_dict(main_dict, new_dict):
- """
- Update nested dict (only level of nesting) with new values.
-
- Unlike `dict.update`, this assumes that the values of the parent dict are
- dicts (or dict-like), so you shouldn't replace the nested dict if it
- already exists. Instead you should update the sub-dict.
- """
- # update named styles specified by user
- for name, rc_dict in new_dict.items():
- main_dict.setdefault(name, {}).update(rc_dict)
- return main_dict
-
-
-# Load style library
-# ==================
-_base_library = read_style_directory(BASE_LIBRARY_PATH)
-library = {}
-available = []
-
-
-def reload_library():
- """Reload the style library."""
- library.clear()
- library.update(update_user_library(_base_library))
- available[:] = sorted(library.keys())
-
-
-reload_library()
diff --git a/contrib/python/matplotlib/py3/matplotlib/style/core.pyi b/contrib/python/matplotlib/py3/matplotlib/style/core.pyi
deleted file mode 100644
index 7340049214..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/style/core.pyi
+++ /dev/null
@@ -1,19 +0,0 @@
-from collections.abc import Generator
-import contextlib
-
-from matplotlib import RcParams
-from matplotlib.typing import RcStyleType
-
-USER_LIBRARY_PATHS: list[str] = ...
-STYLE_EXTENSION: str = ...
-
-def use(style: RcStyleType) -> None: ...
-@contextlib.contextmanager
-def context(
- style: RcStyleType, after_reset: bool = ...
-) -> Generator[None, None, None]: ...
-
-library: dict[str, RcParams]
-available: list[str]
-
-def reload_library() -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/table.py b/contrib/python/matplotlib/py3/matplotlib/table.py
deleted file mode 100644
index d42cdf878d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/table.py
+++ /dev/null
@@ -1,831 +0,0 @@
-# Original code by:
-# John Gill <jng@europe.renre.com>
-# Copyright 2004 John Gill and John Hunter
-#
-# Subsequent changes:
-# The Matplotlib development team
-# Copyright The Matplotlib development team
-
-"""
-Tables drawing.
-
-.. note::
- The table implementation in Matplotlib is lightly maintained. For a more
- featureful table implementation, you may wish to try `blume
- <https://github.com/swfiua/blume>`_.
-
-Use the factory function `~matplotlib.table.table` to create a ready-made
-table from texts. If you need more control, use the `.Table` class and its
-methods.
-
-The table consists of a grid of cells, which are indexed by (row, column).
-The cell (0, 0) is positioned at the top left.
-
-Thanks to John Gill for providing the class and table.
-"""
-
-import numpy as np
-
-from . import _api, _docstring
-from .artist import Artist, allow_rasterization
-from .patches import Rectangle
-from .text import Text
-from .transforms import Bbox
-from .path import Path
-
-
-class Cell(Rectangle):
- """
- A cell is a `.Rectangle` with some associated `.Text`.
-
- As a user, you'll most likely not creates cells yourself. Instead, you
- should use either the `~matplotlib.table.table` factory function or
- `.Table.add_cell`.
- """
-
- PAD = 0.1
- """Padding between text and rectangle."""
-
- _edges = 'BRTL'
- _edge_aliases = {'open': '',
- 'closed': _edges, # default
- 'horizontal': 'BT',
- 'vertical': 'RL'
- }
-
- def __init__(self, xy, width, height, *,
- edgecolor='k', facecolor='w',
- fill=True,
- text='',
- loc=None,
- fontproperties=None,
- visible_edges='closed',
- ):
- """
- Parameters
- ----------
- xy : 2-tuple
- The position of the bottom left corner of the cell.
- width : float
- The cell width.
- height : float
- The cell height.
- edgecolor : color
- The color of the cell border.
- facecolor : color
- The cell facecolor.
- fill : bool
- Whether the cell background is filled.
- text : str
- The cell text.
- loc : {'left', 'center', 'right'}, default: 'right'
- The alignment of the text within the cell.
- fontproperties : dict
- A dict defining the font properties of the text. Supported keys and
- values are the keyword arguments accepted by `.FontProperties`.
- visible_edges : str, default: 'closed'
- The cell edges to be drawn with a line: a substring of 'BRTL'
- (bottom, right, top, left), or one of 'open' (no edges drawn),
- 'closed' (all edges drawn), 'horizontal' (bottom and top),
- 'vertical' (right and left).
- """
-
- # Call base
- super().__init__(xy, width=width, height=height, fill=fill,
- edgecolor=edgecolor, facecolor=facecolor)
- self.set_clip_on(False)
- self.visible_edges = visible_edges
-
- # Create text object
- if loc is None:
- loc = 'right'
- self._loc = loc
- self._text = Text(x=xy[0], y=xy[1], clip_on=False,
- text=text, fontproperties=fontproperties,
- horizontalalignment=loc, verticalalignment='center')
-
- @_api.rename_parameter("3.8", "trans", "t")
- def set_transform(self, t):
- super().set_transform(t)
- # the text does not get the transform!
- self.stale = True
-
- def set_figure(self, fig):
- super().set_figure(fig)
- self._text.set_figure(fig)
-
- def get_text(self):
- """Return the cell `.Text` instance."""
- return self._text
-
- def set_fontsize(self, size):
- """Set the text fontsize."""
- self._text.set_fontsize(size)
- self.stale = True
-
- def get_fontsize(self):
- """Return the cell fontsize."""
- return self._text.get_fontsize()
-
- def auto_set_font_size(self, renderer):
- """Shrink font size until the text fits into the cell width."""
- fontsize = self.get_fontsize()
- required = self.get_required_width(renderer)
- while fontsize > 1 and required > self.get_width():
- fontsize -= 1
- self.set_fontsize(fontsize)
- required = self.get_required_width(renderer)
-
- return fontsize
-
- @allow_rasterization
- def draw(self, renderer):
- if not self.get_visible():
- return
- # draw the rectangle
- super().draw(renderer)
- # position the text
- self._set_text_position(renderer)
- self._text.draw(renderer)
- self.stale = False
-
- def _set_text_position(self, renderer):
- """Set text up so it is drawn in the right place."""
- bbox = self.get_window_extent(renderer)
- # center vertically
- y = bbox.y0 + bbox.height / 2
- # position horizontally
- loc = self._text.get_horizontalalignment()
- if loc == 'center':
- x = bbox.x0 + bbox.width / 2
- elif loc == 'left':
- x = bbox.x0 + bbox.width * self.PAD
- else: # right.
- x = bbox.x0 + bbox.width * (1 - self.PAD)
- self._text.set_position((x, y))
-
- def get_text_bounds(self, renderer):
- """
- Return the text bounds as *(x, y, width, height)* in table coordinates.
- """
- return (self._text.get_window_extent(renderer)
- .transformed(self.get_data_transform().inverted())
- .bounds)
-
- def get_required_width(self, renderer):
- """Return the minimal required width for the cell."""
- l, b, w, h = self.get_text_bounds(renderer)
- return w * (1.0 + (2.0 * self.PAD))
-
- @_docstring.dedent_interpd
- def set_text_props(self, **kwargs):
- """
- Update the text properties.
-
- Valid keyword arguments are:
-
- %(Text:kwdoc)s
- """
- self._text._internal_update(kwargs)
- self.stale = True
-
- @property
- def visible_edges(self):
- """
- The cell edges to be drawn with a line.
-
- Reading this property returns a substring of 'BRTL' (bottom, right,
- top, left').
-
- When setting this property, you can use a substring of 'BRTL' or one
- of {'open', 'closed', 'horizontal', 'vertical'}.
- """
- return self._visible_edges
-
- @visible_edges.setter
- def visible_edges(self, value):
- if value is None:
- self._visible_edges = self._edges
- elif value in self._edge_aliases:
- self._visible_edges = self._edge_aliases[value]
- else:
- if any(edge not in self._edges for edge in value):
- raise ValueError('Invalid edge param {}, must only be one of '
- '{} or string of {}'.format(
- value,
- ", ".join(self._edge_aliases),
- ", ".join(self._edges)))
- self._visible_edges = value
- self.stale = True
-
- def get_path(self):
- """Return a `.Path` for the `.visible_edges`."""
- codes = [Path.MOVETO]
- codes.extend(
- Path.LINETO if edge in self._visible_edges else Path.MOVETO
- for edge in self._edges)
- if Path.MOVETO not in codes[1:]: # All sides are visible
- codes[-1] = Path.CLOSEPOLY
- return Path(
- [[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0], [0.0, 0.0]],
- codes,
- readonly=True
- )
-
-
-CustomCell = Cell # Backcompat. alias.
-
-
-class Table(Artist):
- """
- A table of cells.
-
- The table consists of a grid of cells, which are indexed by (row, column).
-
- For a simple table, you'll have a full grid of cells with indices from
- (0, 0) to (num_rows-1, num_cols-1), in which the cell (0, 0) is positioned
- at the top left. However, you can also add cells with negative indices.
- You don't have to add a cell to every grid position, so you can create
- tables that have holes.
-
- *Note*: You'll usually not create an empty table from scratch. Instead use
- `~matplotlib.table.table` to create a table from data.
- """
- codes = {'best': 0,
- 'upper right': 1, # default
- 'upper left': 2,
- 'lower left': 3,
- 'lower right': 4,
- 'center left': 5,
- 'center right': 6,
- 'lower center': 7,
- 'upper center': 8,
- 'center': 9,
- 'top right': 10,
- 'top left': 11,
- 'bottom left': 12,
- 'bottom right': 13,
- 'right': 14,
- 'left': 15,
- 'top': 16,
- 'bottom': 17,
- }
- """Possible values where to place the table relative to the Axes."""
-
- FONTSIZE = 10
-
- AXESPAD = 0.02
- """The border between the Axes and the table edge in Axes units."""
-
- def __init__(self, ax, loc=None, bbox=None, **kwargs):
- """
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The `~.axes.Axes` to plot the table into.
- loc : str
- The position of the cell with respect to *ax*. This must be one of
- the `~.Table.codes`.
- bbox : `.Bbox` or [xmin, ymin, width, height], optional
- A bounding box to draw the table into. If this is not *None*, this
- overrides *loc*.
-
- Other Parameters
- ----------------
- **kwargs
- `.Artist` properties.
- """
-
- super().__init__()
-
- if isinstance(loc, str):
- if loc not in self.codes:
- raise ValueError(
- "Unrecognized location {!r}. Valid locations are\n\t{}"
- .format(loc, '\n\t'.join(self.codes)))
- loc = self.codes[loc]
- self.set_figure(ax.figure)
- self._axes = ax
- self._loc = loc
- self._bbox = bbox
-
- # use axes coords
- ax._unstale_viewLim()
- self.set_transform(ax.transAxes)
-
- self._cells = {}
- self._edges = None
- self._autoColumns = []
- self._autoFontsize = True
- self._internal_update(kwargs)
-
- self.set_clip_on(False)
-
- def add_cell(self, row, col, *args, **kwargs):
- """
- Create a cell and add it to the table.
-
- Parameters
- ----------
- row : int
- Row index.
- col : int
- Column index.
- *args, **kwargs
- All other parameters are passed on to `Cell`.
-
- Returns
- -------
- `.Cell`
- The created cell.
-
- """
- xy = (0, 0)
- cell = Cell(xy, visible_edges=self.edges, *args, **kwargs)
- self[row, col] = cell
- return cell
-
- def __setitem__(self, position, cell):
- """
- Set a custom cell in a given position.
- """
- _api.check_isinstance(Cell, cell=cell)
- try:
- row, col = position[0], position[1]
- except Exception as err:
- raise KeyError('Only tuples length 2 are accepted as '
- 'coordinates') from err
- cell.set_figure(self.figure)
- cell.set_transform(self.get_transform())
- cell.set_clip_on(False)
- self._cells[row, col] = cell
- self.stale = True
-
- def __getitem__(self, position):
- """Retrieve a custom cell from a given position."""
- return self._cells[position]
-
- @property
- def edges(self):
- """
- The default value of `~.Cell.visible_edges` for newly added
- cells using `.add_cell`.
-
- Notes
- -----
- This setting does currently only affect newly created cells using
- `.add_cell`.
-
- To change existing cells, you have to set their edges explicitly::
-
- for c in tab.get_celld().values():
- c.visible_edges = 'horizontal'
-
- """
- return self._edges
-
- @edges.setter
- def edges(self, value):
- self._edges = value
- self.stale = True
-
- def _approx_text_height(self):
- return (self.FONTSIZE / 72.0 * self.figure.dpi /
- self._axes.bbox.height * 1.2)
-
- @allow_rasterization
- def draw(self, renderer):
- # docstring inherited
-
- # Need a renderer to do hit tests on mouseevent; assume the last one
- # will do
- if renderer is None:
- renderer = self.figure._get_renderer()
- if renderer is None:
- raise RuntimeError('No renderer defined')
-
- if not self.get_visible():
- return
- renderer.open_group('table', gid=self.get_gid())
- self._update_positions(renderer)
-
- for key in sorted(self._cells):
- self._cells[key].draw(renderer)
-
- renderer.close_group('table')
- self.stale = False
-
- def _get_grid_bbox(self, renderer):
- """
- Get a bbox, in axes coordinates for the cells.
-
- Only include those in the range (0, 0) to (maxRow, maxCol).
- """
- boxes = [cell.get_window_extent(renderer)
- for (row, col), cell in self._cells.items()
- if row >= 0 and col >= 0]
- bbox = Bbox.union(boxes)
- return bbox.transformed(self.get_transform().inverted())
-
- def contains(self, mouseevent):
- # docstring inherited
- if self._different_canvas(mouseevent):
- return False, {}
- # TODO: Return index of the cell containing the cursor so that the user
- # doesn't have to bind to each one individually.
- renderer = self.figure._get_renderer()
- if renderer is not None:
- boxes = [cell.get_window_extent(renderer)
- for (row, col), cell in self._cells.items()
- if row >= 0 and col >= 0]
- bbox = Bbox.union(boxes)
- return bbox.contains(mouseevent.x, mouseevent.y), {}
- else:
- return False, {}
-
- def get_children(self):
- """Return the Artists contained by the table."""
- return list(self._cells.values())
-
- def get_window_extent(self, renderer=None):
- # docstring inherited
- if renderer is None:
- renderer = self.figure._get_renderer()
- self._update_positions(renderer)
- boxes = [cell.get_window_extent(renderer)
- for cell in self._cells.values()]
- return Bbox.union(boxes)
-
- def _do_cell_alignment(self):
- """
- Calculate row heights and column widths; position cells accordingly.
- """
- # Calculate row/column widths
- widths = {}
- heights = {}
- for (row, col), cell in self._cells.items():
- height = heights.setdefault(row, 0.0)
- heights[row] = max(height, cell.get_height())
- width = widths.setdefault(col, 0.0)
- widths[col] = max(width, cell.get_width())
-
- # work out left position for each column
- xpos = 0
- lefts = {}
- for col in sorted(widths):
- lefts[col] = xpos
- xpos += widths[col]
-
- ypos = 0
- bottoms = {}
- for row in sorted(heights, reverse=True):
- bottoms[row] = ypos
- ypos += heights[row]
-
- # set cell positions
- for (row, col), cell in self._cells.items():
- cell.set_x(lefts[col])
- cell.set_y(bottoms[row])
-
- def auto_set_column_width(self, col):
- """
- Automatically set the widths of given columns to optimal sizes.
-
- Parameters
- ----------
- col : int or sequence of ints
- The indices of the columns to auto-scale.
- """
- col1d = np.atleast_1d(col)
- if not np.issubdtype(col1d.dtype, np.integer):
- _api.warn_deprecated("3.8", name="col",
- message="%(name)r must be an int or sequence of ints. "
- "Passing other types is deprecated since %(since)s "
- "and will be removed %(removal)s.")
- return
- for cell in col1d:
- self._autoColumns.append(cell)
-
- self.stale = True
-
- def _auto_set_column_width(self, col, renderer):
- """Automatically set width for column."""
- cells = [cell for key, cell in self._cells.items() if key[1] == col]
- max_width = max((cell.get_required_width(renderer) for cell in cells),
- default=0)
- for cell in cells:
- cell.set_width(max_width)
-
- def auto_set_font_size(self, value=True):
- """Automatically set font size."""
- self._autoFontsize = value
- self.stale = True
-
- def _auto_set_font_size(self, renderer):
-
- if len(self._cells) == 0:
- return
- fontsize = next(iter(self._cells.values())).get_fontsize()
- cells = []
- for key, cell in self._cells.items():
- # ignore auto-sized columns
- if key[1] in self._autoColumns:
- continue
- size = cell.auto_set_font_size(renderer)
- fontsize = min(fontsize, size)
- cells.append(cell)
-
- # now set all fontsizes equal
- for cell in self._cells.values():
- cell.set_fontsize(fontsize)
-
- def scale(self, xscale, yscale):
- """Scale column widths by *xscale* and row heights by *yscale*."""
- for c in self._cells.values():
- c.set_width(c.get_width() * xscale)
- c.set_height(c.get_height() * yscale)
-
- def set_fontsize(self, size):
- """
- Set the font size, in points, of the cell text.
-
- Parameters
- ----------
- size : float
-
- Notes
- -----
- As long as auto font size has not been disabled, the value will be
- clipped such that the text fits horizontally into the cell.
-
- You can disable this behavior using `.auto_set_font_size`.
-
- >>> the_table.auto_set_font_size(False)
- >>> the_table.set_fontsize(20)
-
- However, there is no automatic scaling of the row height so that the
- text may exceed the cell boundary.
- """
- for cell in self._cells.values():
- cell.set_fontsize(size)
- self.stale = True
-
- def _offset(self, ox, oy):
- """Move all the artists by ox, oy (axes coords)."""
- for c in self._cells.values():
- x, y = c.get_x(), c.get_y()
- c.set_x(x + ox)
- c.set_y(y + oy)
-
- def _update_positions(self, renderer):
- # called from renderer to allow more precise estimates of
- # widths and heights with get_window_extent
-
- # Do any auto width setting
- for col in self._autoColumns:
- self._auto_set_column_width(col, renderer)
-
- if self._autoFontsize:
- self._auto_set_font_size(renderer)
-
- # Align all the cells
- self._do_cell_alignment()
-
- bbox = self._get_grid_bbox(renderer)
- l, b, w, h = bbox.bounds
-
- if self._bbox is not None:
- # Position according to bbox
- if isinstance(self._bbox, Bbox):
- rl, rb, rw, rh = self._bbox.bounds
- else:
- rl, rb, rw, rh = self._bbox
- self.scale(rw / w, rh / h)
- ox = rl - l
- oy = rb - b
- self._do_cell_alignment()
- else:
- # Position using loc
- (BEST, UR, UL, LL, LR, CL, CR, LC, UC, C,
- TR, TL, BL, BR, R, L, T, B) = range(len(self.codes))
- # defaults for center
- ox = (0.5 - w / 2) - l
- oy = (0.5 - h / 2) - b
- if self._loc in (UL, LL, CL): # left
- ox = self.AXESPAD - l
- if self._loc in (BEST, UR, LR, R, CR): # right
- ox = 1 - (l + w + self.AXESPAD)
- if self._loc in (BEST, UR, UL, UC): # upper
- oy = 1 - (b + h + self.AXESPAD)
- if self._loc in (LL, LR, LC): # lower
- oy = self.AXESPAD - b
- if self._loc in (LC, UC, C): # center x
- ox = (0.5 - w / 2) - l
- if self._loc in (CL, CR, C): # center y
- oy = (0.5 - h / 2) - b
-
- if self._loc in (TL, BL, L): # out left
- ox = - (l + w)
- if self._loc in (TR, BR, R): # out right
- ox = 1.0 - l
- if self._loc in (TR, TL, T): # out top
- oy = 1.0 - b
- if self._loc in (BL, BR, B): # out bottom
- oy = - (b + h)
-
- self._offset(ox, oy)
-
- def get_celld(self):
- r"""
- Return a dict of cells in the table mapping *(row, column)* to
- `.Cell`\s.
-
- Notes
- -----
- You can also directly index into the Table object to access individual
- cells::
-
- cell = table[row, col]
-
- """
- return self._cells
-
-
-@_docstring.dedent_interpd
-def table(ax,
- cellText=None, cellColours=None,
- cellLoc='right', colWidths=None,
- rowLabels=None, rowColours=None, rowLoc='left',
- colLabels=None, colColours=None, colLoc='center',
- loc='bottom', bbox=None, edges='closed',
- **kwargs):
- """
- Add a table to an `~.axes.Axes`.
-
- At least one of *cellText* or *cellColours* must be specified. These
- parameters must be 2D lists, in which the outer lists define the rows and
- the inner list define the column values per row. Each row must have the
- same number of elements.
-
- The table can optionally have row and column headers, which are configured
- using *rowLabels*, *rowColours*, *rowLoc* and *colLabels*, *colColours*,
- *colLoc* respectively.
-
- For finer grained control over tables, use the `.Table` class and add it to
- the axes with `.Axes.add_table`.
-
- Parameters
- ----------
- cellText : 2D list of str, optional
- The texts to place into the table cells.
-
- *Note*: Line breaks in the strings are currently not accounted for and
- will result in the text exceeding the cell boundaries.
-
- cellColours : 2D list of colors, optional
- The background colors of the cells.
-
- cellLoc : {'left', 'center', 'right'}, default: 'right'
- The alignment of the text within the cells.
-
- colWidths : list of float, optional
- The column widths in units of the axes. If not given, all columns will
- have a width of *1 / ncols*.
-
- rowLabels : list of str, optional
- The text of the row header cells.
-
- rowColours : list of colors, optional
- The colors of the row header cells.
-
- rowLoc : {'left', 'center', 'right'}, default: 'left'
- The text alignment of the row header cells.
-
- colLabels : list of str, optional
- The text of the column header cells.
-
- colColours : list of colors, optional
- The colors of the column header cells.
-
- colLoc : {'left', 'center', 'right'}, default: 'left'
- The text alignment of the column header cells.
-
- loc : str, optional
- The position of the cell with respect to *ax*. This must be one of
- the `~.Table.codes`.
-
- bbox : `.Bbox` or [xmin, ymin, width, height], optional
- A bounding box to draw the table into. If this is not *None*, this
- overrides *loc*.
-
- edges : substring of 'BRTL' or {'open', 'closed', 'horizontal', 'vertical'}
- The cell edges to be drawn with a line. See also
- `~.Cell.visible_edges`.
-
- Returns
- -------
- `~matplotlib.table.Table`
- The created table.
-
- Other Parameters
- ----------------
- **kwargs
- `.Table` properties.
-
- %(Table:kwdoc)s
- """
-
- if cellColours is None and cellText is None:
- raise ValueError('At least one argument from "cellColours" or '
- '"cellText" must be provided to create a table.')
-
- # Check we have some cellText
- if cellText is None:
- # assume just colours are needed
- rows = len(cellColours)
- cols = len(cellColours[0])
- cellText = [[''] * cols] * rows
-
- rows = len(cellText)
- cols = len(cellText[0])
- for row in cellText:
- if len(row) != cols:
- raise ValueError(f"Each row in 'cellText' must have {cols} "
- "columns")
-
- if cellColours is not None:
- if len(cellColours) != rows:
- raise ValueError(f"'cellColours' must have {rows} rows")
- for row in cellColours:
- if len(row) != cols:
- raise ValueError("Each row in 'cellColours' must have "
- f"{cols} columns")
- else:
- cellColours = ['w' * cols] * rows
-
- # Set colwidths if not given
- if colWidths is None:
- colWidths = [1.0 / cols] * cols
-
- # Fill in missing information for column
- # and row labels
- rowLabelWidth = 0
- if rowLabels is None:
- if rowColours is not None:
- rowLabels = [''] * rows
- rowLabelWidth = colWidths[0]
- elif rowColours is None:
- rowColours = 'w' * rows
-
- if rowLabels is not None:
- if len(rowLabels) != rows:
- raise ValueError(f"'rowLabels' must be of length {rows}")
-
- # If we have column labels, need to shift
- # the text and colour arrays down 1 row
- offset = 1
- if colLabels is None:
- if colColours is not None:
- colLabels = [''] * cols
- else:
- offset = 0
- elif colColours is None:
- colColours = 'w' * cols
-
- # Set up cell colours if not given
- if cellColours is None:
- cellColours = ['w' * cols] * rows
-
- # Now create the table
- table = Table(ax, loc, bbox, **kwargs)
- table.edges = edges
- height = table._approx_text_height()
-
- # Add the cells
- for row in range(rows):
- for col in range(cols):
- table.add_cell(row + offset, col,
- width=colWidths[col], height=height,
- text=cellText[row][col],
- facecolor=cellColours[row][col],
- loc=cellLoc)
- # Do column labels
- if colLabels is not None:
- for col in range(cols):
- table.add_cell(0, col,
- width=colWidths[col], height=height,
- text=colLabels[col], facecolor=colColours[col],
- loc=colLoc)
-
- # Do row labels
- if rowLabels is not None:
- for row in range(rows):
- table.add_cell(row + offset, -1,
- width=rowLabelWidth or 1e-15, height=height,
- text=rowLabels[row], facecolor=rowColours[row],
- loc=rowLoc)
- if rowLabelWidth == 0:
- table.auto_set_column_width(-1)
-
- ax.add_table(table)
- return table
diff --git a/contrib/python/matplotlib/py3/matplotlib/table.pyi b/contrib/python/matplotlib/py3/matplotlib/table.pyi
deleted file mode 100644
index 842c55edb5..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/table.pyi
+++ /dev/null
@@ -1,85 +0,0 @@
-from .artist import Artist
-from .axes import Axes
-from .backend_bases import RendererBase
-from .patches import Rectangle
-from .path import Path
-from .text import Text
-from .transforms import Bbox
-from .typing import ColorType
-
-from collections.abc import Sequence
-from typing import Any, Literal
-
-class Cell(Rectangle):
- PAD: float
- def __init__(
- self,
- xy: tuple[float, float],
- width: float,
- height: float,
- *,
- edgecolor: ColorType = ...,
- facecolor: ColorType = ...,
- fill: bool = ...,
- text: str = ...,
- loc: Literal["left", "center", "right"] | None = ...,
- fontproperties: dict[str, Any] | None = ...,
- visible_edges: str | None = ...
- ) -> None: ...
- def get_text(self) -> Text: ...
- def set_fontsize(self, size: float) -> None: ...
- def get_fontsize(self) -> float: ...
- def auto_set_font_size(self, renderer: RendererBase) -> float: ...
- def get_text_bounds(
- self, renderer: RendererBase
- ) -> tuple[float, float, float, float]: ...
- def get_required_width(self, renderer: RendererBase) -> float: ...
- def set_text_props(self, **kwargs) -> None: ...
- @property
- def visible_edges(self) -> str: ...
- @visible_edges.setter
- def visible_edges(self, value: str | None) -> None: ...
- def get_path(self) -> Path: ...
-
-CustomCell = Cell
-
-class Table(Artist):
- codes: dict[str, int]
- FONTSIZE: float
- AXESPAD: float
- def __init__(
- self, ax: Axes, loc: str | None = ..., bbox: Bbox | None = ..., **kwargs
- ) -> None: ...
- def add_cell(self, row: int, col: int, *args, **kwargs) -> Cell: ...
- def __setitem__(self, position: tuple[int, int], cell: Cell) -> None: ...
- def __getitem__(self, position: tuple[int, int]) -> Cell: ...
- @property
- def edges(self) -> str | None: ...
- @edges.setter
- def edges(self, value: str | None) -> None: ...
- def draw(self, renderer) -> None: ...
- def get_children(self) -> list[Artist]: ...
- def get_window_extent(self, renderer: RendererBase | None = ...) -> Bbox: ...
- def auto_set_column_width(self, col: int | Sequence[int]) -> None: ...
- def auto_set_font_size(self, value: bool = ...) -> None: ...
- def scale(self, xscale: float, yscale: float) -> None: ...
- def set_fontsize(self, size: float) -> None: ...
- def get_celld(self) -> dict[tuple[int, int], Cell]: ...
-
-def table(
- ax: Axes,
- cellText: Sequence[Sequence[str]] | None = ...,
- cellColours: Sequence[Sequence[ColorType]] | None = ...,
- cellLoc: Literal["left", "center", "right"] = ...,
- colWidths: Sequence[float] | None = ...,
- rowLabels: Sequence[str] | None = ...,
- rowColours: Sequence[ColorType] | None = ...,
- rowLoc: Literal["left", "center", "right"] = ...,
- colLabels: Sequence[str] | None = ...,
- colColours: Sequence[ColorType] | None = ...,
- colLoc: Literal["left", "center", "right"] = ...,
- loc: str = ...,
- bbox: Bbox | None = ...,
- edges: str = ...,
- **kwargs
-) -> Table: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/__init__.py b/contrib/python/matplotlib/py3/matplotlib/testing/__init__.py
deleted file mode 100644
index da21eb42c5..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/__init__.py
+++ /dev/null
@@ -1,174 +0,0 @@
-"""
-Helper functions for testing.
-"""
-from pathlib import Path
-from tempfile import TemporaryDirectory
-import locale
-import logging
-import os
-import subprocess
-import sys
-
-import matplotlib as mpl
-from matplotlib import _api
-
-_log = logging.getLogger(__name__)
-
-
-def set_font_settings_for_testing():
- mpl.rcParams['font.family'] = 'DejaVu Sans'
- mpl.rcParams['text.hinting'] = 'none'
- mpl.rcParams['text.hinting_factor'] = 8
-
-
-def set_reproducibility_for_testing():
- mpl.rcParams['svg.hashsalt'] = 'matplotlib'
-
-
-def setup():
- # The baseline images are created in this locale, so we should use
- # it during all of the tests.
-
- try:
- locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
- except locale.Error:
- try:
- locale.setlocale(locale.LC_ALL, 'English_United States.1252')
- except locale.Error:
- _log.warning(
- "Could not set locale to English/United States. "
- "Some date-related tests may fail.")
-
- mpl.use('Agg')
-
- with _api.suppress_matplotlib_deprecation_warning():
- mpl.rcdefaults() # Start with all defaults
-
- # These settings *must* be hardcoded for running the comparison tests and
- # are not necessarily the default values as specified in rcsetup.py.
- set_font_settings_for_testing()
- set_reproducibility_for_testing()
-
-
-def subprocess_run_for_testing(command, env=None, timeout=None, stdout=None,
- stderr=None, check=False, text=True,
- capture_output=False):
- """
- Create and run a subprocess.
-
- Thin wrapper around `subprocess.run`, intended for testing. Will
- mark fork() failures on Cygwin as expected failures: not a
- success, but not indicating a problem with the code either.
-
- Parameters
- ----------
- args : list of str
- env : dict[str, str]
- timeout : float
- stdout, stderr
- check : bool
- text : bool
- Also called ``universal_newlines`` in subprocess. I chose this
- name since the main effect is returning bytes (`False`) vs. str
- (`True`), though it also tries to normalize newlines across
- platforms.
- capture_output : bool
- Set stdout and stderr to subprocess.PIPE
-
- Returns
- -------
- proc : subprocess.Popen
-
- See Also
- --------
- subprocess.run
-
- Raises
- ------
- pytest.xfail
- If platform is Cygwin and subprocess reports a fork() failure.
- """
- if capture_output:
- stdout = stderr = subprocess.PIPE
- try:
- proc = subprocess.run(
- command, env=env,
- timeout=timeout, check=check,
- stdout=stdout, stderr=stderr,
- text=text
- )
- except BlockingIOError:
- if sys.platform == "cygwin":
- # Might want to make this more specific
- import pytest
- pytest.xfail("Fork failure")
- raise
- return proc
-
-
-def subprocess_run_helper(func, *args, timeout, extra_env=None):
- """
- Run a function in a sub-process.
-
- Parameters
- ----------
- func : function
- The function to be run. It must be in a module that is importable.
- *args : str
- Any additional command line arguments to be passed in
- the first argument to ``subprocess.run``.
- extra_env : dict[str, str]
- Any additional environment variables to be set for the subprocess.
- """
- target = func.__name__
- module = func.__module__
- proc = subprocess_run_for_testing(
- [
- sys.executable,
- "-c",
- f"from {module} import {target}; {target}()",
- *args
- ],
- env={**os.environ, "SOURCE_DATE_EPOCH": "0", **(extra_env or {})},
- timeout=timeout, check=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- text=True
- )
- return proc
-
-
-def _check_for_pgf(texsystem):
- """
- Check if a given TeX system + pgf is available
-
- Parameters
- ----------
- texsystem : str
- The executable name to check
- """
- with TemporaryDirectory() as tmpdir:
- tex_path = Path(tmpdir, "test.tex")
- tex_path.write_text(r"""
- \documentclass{article}
- \usepackage{pgf}
- \begin{document}
- \typeout{pgfversion=\pgfversion}
- \makeatletter
- \@@end
- """, encoding="utf-8")
- try:
- subprocess.check_call(
- [texsystem, "-halt-on-error", str(tex_path)], cwd=tmpdir,
- stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
- except (OSError, subprocess.CalledProcessError):
- return False
- return True
-
-
-def _has_tex_package(package):
- try:
- mpl.dviread.find_tex_file(f"{package}.sty")
- return True
- except FileNotFoundError:
- return False
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/__init__.pyi b/contrib/python/matplotlib/py3/matplotlib/testing/__init__.pyi
deleted file mode 100644
index 30cfd9a9ed..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/__init__.pyi
+++ /dev/null
@@ -1,49 +0,0 @@
-from collections.abc import Callable
-import subprocess
-from typing import Any, IO, Literal, overload
-
-def set_font_settings_for_testing() -> None: ...
-def set_reproducibility_for_testing() -> None: ...
-def setup() -> None: ...
-@overload
-def subprocess_run_for_testing(
- command: list[str],
- env: dict[str, str] | None = ...,
- timeout: float | None = ...,
- stdout: int | IO[Any] | None = ...,
- stderr: int | IO[Any] | None = ...,
- check: bool = ...,
- *,
- text: Literal[True],
- capture_output: bool = ...,
-) -> subprocess.CompletedProcess[str]: ...
-@overload
-def subprocess_run_for_testing(
- command: list[str],
- env: dict[str, str] | None = ...,
- timeout: float | None = ...,
- stdout: int | IO[Any] | None = ...,
- stderr: int | IO[Any] | None = ...,
- check: bool = ...,
- text: Literal[False] = ...,
- capture_output: bool = ...,
-) -> subprocess.CompletedProcess[bytes]: ...
-@overload
-def subprocess_run_for_testing(
- command: list[str],
- env: dict[str, str] | None = ...,
- timeout: float | None = ...,
- stdout: int | IO[Any] | None = ...,
- stderr: int | IO[Any] | None = ...,
- check: bool = ...,
- text: bool = ...,
- capture_output: bool = ...,
-) -> subprocess.CompletedProcess[bytes] | subprocess.CompletedProcess[str]: ...
-def subprocess_run_helper(
- func: Callable[[], None],
- *args: Any,
- timeout: float,
- extra_env: dict[str, str] | None = ...,
-) -> subprocess.CompletedProcess[str]: ...
-def _check_for_pgf(texsystem: str) -> bool: ...
-def _has_tex_package(package: str) -> bool: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/_markers.py b/contrib/python/matplotlib/py3/matplotlib/testing/_markers.py
deleted file mode 100644
index c7ef8687a8..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/_markers.py
+++ /dev/null
@@ -1,49 +0,0 @@
-"""
-pytest markers for the internal Matplotlib test suite.
-"""
-
-import logging
-import shutil
-
-import pytest
-
-import matplotlib.testing
-import matplotlib.testing.compare
-from matplotlib import _get_executable_info, ExecutableNotFoundError
-
-
-_log = logging.getLogger(__name__)
-
-
-def _checkdep_usetex() -> bool:
- if not shutil.which("tex"):
- _log.warning("usetex mode requires TeX.")
- return False
- try:
- _get_executable_info("dvipng")
- except ExecutableNotFoundError:
- _log.warning("usetex mode requires dvipng.")
- return False
- try:
- _get_executable_info("gs")
- except ExecutableNotFoundError:
- _log.warning("usetex mode requires ghostscript.")
- return False
- return True
-
-
-needs_ghostscript = pytest.mark.skipif(
- "eps" not in matplotlib.testing.compare.converter,
- reason="This test needs a ghostscript installation")
-needs_pgf_lualatex = pytest.mark.skipif(
- not matplotlib.testing._check_for_pgf('lualatex'),
- reason='lualatex + pgf is required')
-needs_pgf_pdflatex = pytest.mark.skipif(
- not matplotlib.testing._check_for_pgf('pdflatex'),
- reason='pdflatex + pgf is required')
-needs_pgf_xelatex = pytest.mark.skipif(
- not matplotlib.testing._check_for_pgf('xelatex'),
- reason='xelatex + pgf is required')
-needs_usetex = pytest.mark.skipif(
- not _checkdep_usetex(),
- reason="This test needs a TeX installation")
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/compare.py b/contrib/python/matplotlib/py3/matplotlib/testing/compare.py
deleted file mode 100644
index 655765b3ac..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/compare.py
+++ /dev/null
@@ -1,515 +0,0 @@
-"""
-Utilities for comparing image results.
-"""
-
-import atexit
-import functools
-import hashlib
-import logging
-import os
-from pathlib import Path
-import shutil
-import subprocess
-import sys
-from tempfile import TemporaryDirectory, TemporaryFile
-import weakref
-
-import numpy as np
-from PIL import Image
-
-import matplotlib as mpl
-from matplotlib import cbook
-from matplotlib.testing.exceptions import ImageComparisonFailure
-
-_log = logging.getLogger(__name__)
-
-__all__ = ['calculate_rms', 'comparable_formats', 'compare_images']
-
-
-def make_test_filename(fname, purpose):
- """
- Make a new filename by inserting *purpose* before the file's extension.
- """
- base, ext = os.path.splitext(fname)
- return f'{base}-{purpose}{ext}'
-
-
-def _get_cache_path():
- cache_dir = Path(mpl.get_cachedir(), 'test_cache')
- cache_dir.mkdir(parents=True, exist_ok=True)
- return cache_dir
-
-
-def get_cache_dir():
- return str(_get_cache_path())
-
-
-def get_file_hash(path, block_size=2 ** 20):
- md5 = hashlib.md5()
- with open(path, 'rb') as fd:
- while True:
- data = fd.read(block_size)
- if not data:
- break
- md5.update(data)
-
- if Path(path).suffix == '.pdf':
- md5.update(str(mpl._get_executable_info("gs").version)
- .encode('utf-8'))
- elif Path(path).suffix == '.svg':
- md5.update(str(mpl._get_executable_info("inkscape").version)
- .encode('utf-8'))
-
- return md5.hexdigest()
-
-
-class _ConverterError(Exception):
- pass
-
-
-class _Converter:
- def __init__(self):
- self._proc = None
- # Explicitly register deletion from an atexit handler because if we
- # wait until the object is GC'd (which occurs later), then some module
- # globals (e.g. signal.SIGKILL) has already been set to None, and
- # kill() doesn't work anymore...
- atexit.register(self.__del__)
-
- def __del__(self):
- if self._proc:
- self._proc.kill()
- self._proc.wait()
- for stream in filter(None, [self._proc.stdin,
- self._proc.stdout,
- self._proc.stderr]):
- stream.close()
- self._proc = None
-
- def _read_until(self, terminator):
- """Read until the prompt is reached."""
- buf = bytearray()
- while True:
- c = self._proc.stdout.read(1)
- if not c:
- raise _ConverterError(os.fsdecode(bytes(buf)))
- buf.extend(c)
- if buf.endswith(terminator):
- return bytes(buf)
-
-
-class _GSConverter(_Converter):
- def __call__(self, orig, dest):
- if not self._proc:
- self._proc = subprocess.Popen(
- [mpl._get_executable_info("gs").executable,
- "-dNOSAFER", "-dNOPAUSE", "-dEPSCrop", "-sDEVICE=png16m"],
- # As far as I can see, ghostscript never outputs to stderr.
- stdin=subprocess.PIPE, stdout=subprocess.PIPE)
- try:
- self._read_until(b"\nGS")
- except _ConverterError as e:
- raise OSError(f"Failed to start Ghostscript:\n\n{e.args[0]}") from None
-
- def encode_and_escape(name):
- return (os.fsencode(name)
- .replace(b"\\", b"\\\\")
- .replace(b"(", br"\(")
- .replace(b")", br"\)"))
-
- self._proc.stdin.write(
- b"<< /OutputFile ("
- + encode_and_escape(dest)
- + b") >> setpagedevice ("
- + encode_and_escape(orig)
- + b") run flush\n")
- self._proc.stdin.flush()
- # GS> if nothing left on the stack; GS<n> if n items left on the stack.
- err = self._read_until((b"GS<", b"GS>"))
- stack = self._read_until(b">") if err.endswith(b"GS<") else b""
- if stack or not os.path.exists(dest):
- stack_size = int(stack[:-1]) if stack else 0
- self._proc.stdin.write(b"pop\n" * stack_size)
- # Using the systemencoding should at least get the filenames right.
- raise ImageComparisonFailure(
- (err + stack).decode(sys.getfilesystemencoding(), "replace"))
-
-
-class _SVGConverter(_Converter):
- def __call__(self, orig, dest):
- old_inkscape = mpl._get_executable_info("inkscape").version.major < 1
- terminator = b"\n>" if old_inkscape else b"> "
- if not hasattr(self, "_tmpdir"):
- self._tmpdir = TemporaryDirectory()
- # On Windows, we must make sure that self._proc has terminated
- # (which __del__ does) before clearing _tmpdir.
- weakref.finalize(self._tmpdir, self.__del__)
- if (not self._proc # First run.
- or self._proc.poll() is not None): # Inkscape terminated.
- if self._proc is not None and self._proc.poll() is not None:
- for stream in filter(None, [self._proc.stdin,
- self._proc.stdout,
- self._proc.stderr]):
- stream.close()
- env = {
- **os.environ,
- # If one passes e.g. a png file to Inkscape, it will try to
- # query the user for conversion options via a GUI (even with
- # `--without-gui`). Unsetting `DISPLAY` prevents this (and
- # causes GTK to crash and Inkscape to terminate, but that'll
- # just be reported as a regular exception below).
- "DISPLAY": "",
- # Do not load any user options.
- "INKSCAPE_PROFILE_DIR": self._tmpdir.name,
- }
- # Old versions of Inkscape (e.g. 0.48.3.1) seem to sometimes
- # deadlock when stderr is redirected to a pipe, so we redirect it
- # to a temporary file instead. This is not necessary anymore as of
- # Inkscape 0.92.1.
- stderr = TemporaryFile()
- self._proc = subprocess.Popen(
- ["inkscape", "--without-gui", "--shell"] if old_inkscape else
- ["inkscape", "--shell"],
- stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=stderr,
- env=env, cwd=self._tmpdir.name)
- # Slight abuse, but makes shutdown handling easier.
- self._proc.stderr = stderr
- try:
- self._read_until(terminator)
- except _ConverterError as err:
- raise OSError(
- "Failed to start Inkscape in interactive mode:\n\n"
- + err.args[0]) from err
-
- # Inkscape's shell mode does not support escaping metacharacters in the
- # filename ("\n", and ":;" for inkscape>=1). Avoid any problems by
- # running from a temporary directory and using fixed filenames.
- inkscape_orig = Path(self._tmpdir.name, os.fsdecode(b"f.svg"))
- inkscape_dest = Path(self._tmpdir.name, os.fsdecode(b"f.png"))
- try:
- inkscape_orig.symlink_to(Path(orig).resolve())
- except OSError:
- shutil.copyfile(orig, inkscape_orig)
- self._proc.stdin.write(
- b"f.svg --export-png=f.png\n" if old_inkscape else
- b"file-open:f.svg;export-filename:f.png;export-do;file-close\n")
- self._proc.stdin.flush()
- try:
- self._read_until(terminator)
- except _ConverterError as err:
- # Inkscape's output is not localized but gtk's is, so the output
- # stream probably has a mixed encoding. Using the filesystem
- # encoding should at least get the filenames right...
- self._proc.stderr.seek(0)
- raise ImageComparisonFailure(
- self._proc.stderr.read().decode(
- sys.getfilesystemencoding(), "replace")) from err
- os.remove(inkscape_orig)
- shutil.move(inkscape_dest, dest)
-
- def __del__(self):
- super().__del__()
- if hasattr(self, "_tmpdir"):
- self._tmpdir.cleanup()
-
-
-class _SVGWithMatplotlibFontsConverter(_SVGConverter):
- """
- A SVG converter which explicitly adds the fonts shipped by Matplotlib to
- Inkspace's font search path, to better support `svg.fonttype = "none"`
- (which is in particular used by certain mathtext tests).
- """
-
- def __call__(self, orig, dest):
- if not hasattr(self, "_tmpdir"):
- self._tmpdir = TemporaryDirectory()
- shutil.copytree(cbook._get_data_path("fonts/ttf"),
- Path(self._tmpdir.name, "fonts"))
- return super().__call__(orig, dest)
-
-
-def _update_converter():
- try:
- mpl._get_executable_info("gs")
- except mpl.ExecutableNotFoundError:
- pass
- else:
- converter['pdf'] = converter['eps'] = _GSConverter()
- try:
- mpl._get_executable_info("inkscape")
- except mpl.ExecutableNotFoundError:
- pass
- else:
- converter['svg'] = _SVGConverter()
-
-
-#: A dictionary that maps filename extensions to functions which themselves
-#: convert between arguments `old` and `new` (filenames).
-converter = {}
-_update_converter()
-_svg_with_matplotlib_fonts_converter = _SVGWithMatplotlibFontsConverter()
-
-
-def comparable_formats():
- """
- Return the list of file formats that `.compare_images` can compare
- on this system.
-
- Returns
- -------
- list of str
- E.g. ``['png', 'pdf', 'svg', 'eps']``.
-
- """
- return ['png', *converter]
-
-
-def convert(filename, cache):
- """
- Convert the named file to png; return the name of the created file.
-
- If *cache* is True, the result of the conversion is cached in
- `matplotlib.get_cachedir() + '/test_cache/'`. The caching is based on a
- hash of the exact contents of the input file. Old cache entries are
- automatically deleted as needed to keep the size of the cache capped to
- twice the size of all baseline images.
- """
- path = Path(filename)
- if not path.exists():
- raise OSError(f"{path} does not exist")
- if path.suffix[1:] not in converter:
- import pytest
- pytest.skip(f"Don't know how to convert {path.suffix} files to png")
- newpath = path.parent / f"{path.stem}_{path.suffix[1:]}.png"
-
- # Only convert the file if the destination doesn't already exist or
- # is out of date.
- if not newpath.exists() or newpath.stat().st_mtime < path.stat().st_mtime:
- cache_dir = _get_cache_path() if cache else None
-
- if cache_dir is not None:
- _register_conversion_cache_cleaner_once()
- hash_value = get_file_hash(path)
- cached_path = cache_dir / (hash_value + newpath.suffix)
- if cached_path.exists():
- _log.debug("For %s: reusing cached conversion.", filename)
- shutil.copyfile(cached_path, newpath)
- return str(newpath)
-
- _log.debug("For %s: converting to png.", filename)
- convert = converter[path.suffix[1:]]
- if path.suffix == ".svg":
- contents = path.read_text()
- if 'style="font:' in contents:
- # for svg.fonttype = none, we explicitly patch the font search
- # path so that fonts shipped by Matplotlib are found.
- convert = _svg_with_matplotlib_fonts_converter
- convert(path, newpath)
-
- if cache_dir is not None:
- _log.debug("For %s: caching conversion result.", filename)
- shutil.copyfile(newpath, cached_path)
-
- return str(newpath)
-
-
-def _clean_conversion_cache():
- # This will actually ignore mpl_toolkits baseline images, but they're
- # relatively small.
- baseline_images_size = sum(
- path.stat().st_size
- for path in Path(mpl.__file__).parent.glob("**/baseline_images/**/*"))
- # 2x: one full copy of baselines, and one full copy of test results
- # (actually an overestimate: we don't convert png baselines and results).
- max_cache_size = 2 * baseline_images_size
- # Reduce cache until it fits.
- with cbook._lock_path(_get_cache_path()):
- cache_stat = {
- path: path.stat() for path in _get_cache_path().glob("*")}
- cache_size = sum(stat.st_size for stat in cache_stat.values())
- paths_by_atime = sorted( # Oldest at the end.
- cache_stat, key=lambda path: cache_stat[path].st_atime,
- reverse=True)
- while cache_size > max_cache_size:
- path = paths_by_atime.pop()
- cache_size -= cache_stat[path].st_size
- path.unlink()
-
-
-@functools.cache # Ensure this is only registered once.
-def _register_conversion_cache_cleaner_once():
- atexit.register(_clean_conversion_cache)
-
-
-def crop_to_same(actual_path, actual_image, expected_path, expected_image):
- # clip the images to the same size -- this is useful only when
- # comparing eps to pdf
- if actual_path[-7:-4] == 'eps' and expected_path[-7:-4] == 'pdf':
- aw, ah, ad = actual_image.shape
- ew, eh, ed = expected_image.shape
- actual_image = actual_image[int(aw / 2 - ew / 2):int(
- aw / 2 + ew / 2), int(ah / 2 - eh / 2):int(ah / 2 + eh / 2)]
- return actual_image, expected_image
-
-
-def calculate_rms(expected_image, actual_image):
- """
- Calculate the per-pixel errors, then compute the root mean square error.
- """
- if expected_image.shape != actual_image.shape:
- raise ImageComparisonFailure(
- f"Image sizes do not match expected size: {expected_image.shape} "
- f"actual size {actual_image.shape}")
- # Convert to float to avoid overflowing finite integer types.
- return np.sqrt(((expected_image - actual_image).astype(float) ** 2).mean())
-
-
-# NOTE: compare_image and save_diff_image assume that the image does not have
-# 16-bit depth, as Pillow converts these to RGB incorrectly.
-
-
-def _load_image(path):
- img = Image.open(path)
- # In an RGBA image, if the smallest value in the alpha channel is 255, all
- # values in it must be 255, meaning that the image is opaque. If so,
- # discard the alpha channel so that it may compare equal to an RGB image.
- if img.mode != "RGBA" or img.getextrema()[3][0] == 255:
- img = img.convert("RGB")
- return np.asarray(img)
-
-
-def compare_images(expected, actual, tol, in_decorator=False):
- """
- Compare two "image" files checking differences within a tolerance.
-
- The two given filenames may point to files which are convertible to
- PNG via the `.converter` dictionary. The underlying RMS is calculated
- with the `.calculate_rms` function.
-
- Parameters
- ----------
- expected : str
- The filename of the expected image.
- actual : str
- The filename of the actual image.
- tol : float
- The tolerance (a color value difference, where 255 is the
- maximal difference). The test fails if the average pixel
- difference is greater than this value.
- in_decorator : bool
- Determines the output format. If called from image_comparison
- decorator, this should be True. (default=False)
-
- Returns
- -------
- None or dict or str
- Return *None* if the images are equal within the given tolerance.
-
- If the images differ, the return value depends on *in_decorator*.
- If *in_decorator* is true, a dict with the following entries is
- returned:
-
- - *rms*: The RMS of the image difference.
- - *expected*: The filename of the expected image.
- - *actual*: The filename of the actual image.
- - *diff_image*: The filename of the difference image.
- - *tol*: The comparison tolerance.
-
- Otherwise, a human-readable multi-line string representation of this
- information is returned.
-
- Examples
- --------
- ::
-
- img1 = "./baseline/plot.png"
- img2 = "./output/plot.png"
- compare_images(img1, img2, 0.001)
-
- """
- actual = os.fspath(actual)
- if not os.path.exists(actual):
- raise Exception(f"Output image {actual} does not exist.")
- if os.stat(actual).st_size == 0:
- raise Exception(f"Output image file {actual} is empty.")
-
- # Convert the image to png
- expected = os.fspath(expected)
- if not os.path.exists(expected):
- raise OSError(f'Baseline image {expected!r} does not exist.')
- extension = expected.split('.')[-1]
- if extension != 'png':
- actual = convert(actual, cache=True)
- expected = convert(expected, cache=True)
-
- # open the image files
- expected_image = _load_image(expected)
- actual_image = _load_image(actual)
-
- actual_image, expected_image = crop_to_same(
- actual, actual_image, expected, expected_image)
-
- diff_image = make_test_filename(actual, 'failed-diff')
-
- if tol <= 0:
- if np.array_equal(expected_image, actual_image):
- return None
-
- # convert to signed integers, so that the images can be subtracted without
- # overflow
- expected_image = expected_image.astype(np.int16)
- actual_image = actual_image.astype(np.int16)
-
- rms = calculate_rms(expected_image, actual_image)
-
- if rms <= tol:
- return None
-
- save_diff_image(expected, actual, diff_image)
-
- results = dict(rms=rms, expected=str(expected),
- actual=str(actual), diff=str(diff_image), tol=tol)
-
- if not in_decorator:
- # Then the results should be a string suitable for stdout.
- template = ['Error: Image files did not match.',
- 'RMS Value: {rms}',
- 'Expected: \n {expected}',
- 'Actual: \n {actual}',
- 'Difference:\n {diff}',
- 'Tolerance: \n {tol}', ]
- results = '\n '.join([line.format(**results) for line in template])
- return results
-
-
-def save_diff_image(expected, actual, output):
- """
- Parameters
- ----------
- expected : str
- File path of expected image.
- actual : str
- File path of actual image.
- output : str
- File path to save difference image to.
- """
- expected_image = _load_image(expected)
- actual_image = _load_image(actual)
- actual_image, expected_image = crop_to_same(
- actual, actual_image, expected, expected_image)
- expected_image = np.array(expected_image, float)
- actual_image = np.array(actual_image, float)
- if expected_image.shape != actual_image.shape:
- raise ImageComparisonFailure(
- f"Image sizes do not match expected size: {expected_image.shape} "
- f"actual size {actual_image.shape}")
- abs_diff = np.abs(expected_image - actual_image)
-
- # expand differences in luminance domain
- abs_diff *= 10
- abs_diff = np.clip(abs_diff, 0, 255).astype(np.uint8)
-
- if abs_diff.shape[2] == 4: # Hard-code the alpha channel to fully solid
- abs_diff[:, :, 3] = 255
-
- Image.fromarray(abs_diff).save(output, format="png")
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/compare.pyi b/contrib/python/matplotlib/py3/matplotlib/testing/compare.pyi
deleted file mode 100644
index 8f11b3bebc..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/compare.pyi
+++ /dev/null
@@ -1,32 +0,0 @@
-from collections.abc import Callable
-from typing import Literal, overload
-
-from numpy.typing import NDArray
-
-__all__ = ["calculate_rms", "comparable_formats", "compare_images"]
-
-def make_test_filename(fname: str, purpose: str) -> str: ...
-def get_cache_dir() -> str: ...
-def get_file_hash(path: str, block_size: int = ...) -> str: ...
-
-converter: dict[str, Callable[[str, str], None]] = {}
-
-def comparable_formats() -> list[str]: ...
-def convert(filename: str, cache: bool) -> str: ...
-def crop_to_same(
- actual_path: str, actual_image: NDArray, expected_path: str, expected_image: NDArray
-) -> tuple[NDArray, NDArray]: ...
-def calculate_rms(expected_image: NDArray, actual_image: NDArray) -> float: ...
-@overload
-def compare_images(
- expected: str, actual: str, tol: float, in_decorator: Literal[True]
-) -> None | dict[str, float | str]: ...
-@overload
-def compare_images(
- expected: str, actual: str, tol: float, in_decorator: Literal[False]
-) -> None | str: ...
-@overload
-def compare_images(
- expected: str, actual: str, tol: float, in_decorator: bool = ...
-) -> None | str | dict[str, float | str]: ...
-def save_diff_image(expected: str, actual: str, output: str) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/conftest.py b/contrib/python/matplotlib/py3/matplotlib/testing/conftest.py
deleted file mode 100644
index c285c247e7..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/conftest.py
+++ /dev/null
@@ -1,100 +0,0 @@
-import pytest
-import sys
-import matplotlib
-from matplotlib import _api
-
-
-def pytest_configure(config):
- # config is initialized here rather than in pytest.ini so that `pytest
- # --pyargs matplotlib` (which would not find pytest.ini) works. The only
- # entries in pytest.ini set minversion (which is checked earlier),
- # testpaths/python_files, as they are required to properly find the tests
- for key, value in [
- ("markers", "flaky: (Provided by pytest-rerunfailures.)"),
- ("markers", "timeout: (Provided by pytest-timeout.)"),
- ("markers", "backend: Set alternate Matplotlib backend temporarily."),
- ("markers", "baseline_images: Compare output against references."),
- ("markers", "pytz: Tests that require pytz to be installed."),
- ("filterwarnings", "error"),
- ("filterwarnings",
- "ignore:.*The py23 module has been deprecated:DeprecationWarning"),
- ("filterwarnings",
- r"ignore:DynamicImporter.find_spec\(\) not found; "
- r"falling back to find_module\(\):ImportWarning"),
- ]:
- config.addinivalue_line(key, value)
-
- matplotlib.use('agg', force=True)
- matplotlib._called_from_pytest = True
- matplotlib._init_tests()
-
-
-def pytest_unconfigure(config):
- matplotlib._called_from_pytest = False
-
-
-@pytest.fixture(autouse=True)
-def mpl_test_settings(request):
- from matplotlib.testing.decorators import _cleanup_cm
-
- with _cleanup_cm():
-
- backend = None
- backend_marker = request.node.get_closest_marker('backend')
- prev_backend = matplotlib.get_backend()
- if backend_marker is not None:
- assert len(backend_marker.args) == 1, \
- "Marker 'backend' must specify 1 backend."
- backend, = backend_marker.args
- skip_on_importerror = backend_marker.kwargs.get(
- 'skip_on_importerror', False)
-
- # special case Qt backend importing to avoid conflicts
- if backend.lower().startswith('qt5'):
- if any(sys.modules.get(k) for k in ('PyQt4', 'PySide')):
- pytest.skip('Qt4 binding already imported')
-
- matplotlib.testing.setup()
- with _api.suppress_matplotlib_deprecation_warning():
- if backend is not None:
- # This import must come after setup() so it doesn't load the
- # default backend prematurely.
- import matplotlib.pyplot as plt
- try:
- plt.switch_backend(backend)
- except ImportError as exc:
- # Should only occur for the cairo backend tests, if neither
- # pycairo nor cairocffi are installed.
- if 'cairo' in backend.lower() or skip_on_importerror:
- pytest.skip("Failed to switch to backend "
- f"{backend} ({exc}).")
- else:
- raise
- # Default of cleanup and image_comparison too.
- matplotlib.style.use(["classic", "_classic_test_patch"])
- try:
- yield
- finally:
- if backend is not None:
- plt.close("all")
- matplotlib.use(prev_backend)
-
-
-@pytest.fixture
-def pd():
- """Fixture to import and configure pandas."""
- pd = pytest.importorskip('pandas')
- try:
- from pandas.plotting import (
- deregister_matplotlib_converters as deregister)
- deregister()
- except ImportError:
- pass
- return pd
-
-
-@pytest.fixture
-def xr():
- """Fixture to import xarray."""
- xr = pytest.importorskip('xarray')
- return xr
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/conftest.pyi b/contrib/python/matplotlib/py3/matplotlib/testing/conftest.pyi
deleted file mode 100644
index 2af0eb93cc..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/conftest.pyi
+++ /dev/null
@@ -1,12 +0,0 @@
-from types import ModuleType
-
-import pytest
-
-def pytest_configure(config: pytest.Config) -> None: ...
-def pytest_unconfigure(config: pytest.Config) -> None: ...
-@pytest.fixture
-def mpl_test_settings(request: pytest.FixtureRequest) -> None: ...
-@pytest.fixture
-def pd() -> ModuleType: ...
-@pytest.fixture
-def xr() -> ModuleType: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/decorators.py b/contrib/python/matplotlib/py3/matplotlib/testing/decorators.py
deleted file mode 100644
index 49ac4a1506..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/decorators.py
+++ /dev/null
@@ -1,464 +0,0 @@
-import contextlib
-import functools
-import inspect
-import os
-from platform import uname
-from pathlib import Path
-import shutil
-import string
-import sys
-import warnings
-
-from packaging.version import parse as parse_version
-
-import matplotlib.style
-import matplotlib.units
-import matplotlib.testing
-from matplotlib import _pylab_helpers, cbook, ft2font, pyplot as plt, ticker
-from .compare import comparable_formats, compare_images, make_test_filename
-from .exceptions import ImageComparisonFailure
-
-
-@contextlib.contextmanager
-def _cleanup_cm():
- orig_units_registry = matplotlib.units.registry.copy()
- try:
- with warnings.catch_warnings(), matplotlib.rc_context():
- yield
- finally:
- matplotlib.units.registry.clear()
- matplotlib.units.registry.update(orig_units_registry)
- plt.close("all")
-
-
-def _check_freetype_version(ver):
- if ver is None:
- return True
-
- if isinstance(ver, str):
- ver = (ver, ver)
- ver = [parse_version(x) for x in ver]
- found = parse_version(ft2font.__freetype_version__)
-
- return ver[0] <= found <= ver[1]
-
-
-def _checked_on_freetype_version(required_freetype_version):
- import pytest
- return pytest.mark.xfail(
- not _check_freetype_version(required_freetype_version),
- reason=f"Mismatched version of freetype. "
- f"Test requires '{required_freetype_version}', "
- f"you have '{ft2font.__freetype_version__}'",
- raises=ImageComparisonFailure, strict=False)
-
-
-def remove_ticks_and_titles(figure):
- figure.suptitle("")
- null_formatter = ticker.NullFormatter()
- def remove_ticks(ax):
- """Remove ticks in *ax* and all its child Axes."""
- ax.set_title("")
- ax.xaxis.set_major_formatter(null_formatter)
- ax.xaxis.set_minor_formatter(null_formatter)
- ax.yaxis.set_major_formatter(null_formatter)
- ax.yaxis.set_minor_formatter(null_formatter)
- try:
- ax.zaxis.set_major_formatter(null_formatter)
- ax.zaxis.set_minor_formatter(null_formatter)
- except AttributeError:
- pass
- for child in ax.child_axes:
- remove_ticks(child)
- for ax in figure.get_axes():
- remove_ticks(ax)
-
-
-@contextlib.contextmanager
-def _collect_new_figures():
- """
- After::
-
- with _collect_new_figures() as figs:
- some_code()
-
- the list *figs* contains the figures that have been created during the
- execution of ``some_code``, sorted by figure number.
- """
- managers = _pylab_helpers.Gcf.figs
- preexisting = [manager for manager in managers.values()]
- new_figs = []
- try:
- yield new_figs
- finally:
- new_managers = sorted([manager for manager in managers.values()
- if manager not in preexisting],
- key=lambda manager: manager.num)
- new_figs[:] = [manager.canvas.figure for manager in new_managers]
-
-
-def _raise_on_image_difference(expected, actual, tol):
- __tracebackhide__ = True
-
- err = compare_images(expected, actual, tol, in_decorator=True)
- if err:
- for key in ["actual", "expected", "diff"]:
- err[key] = os.path.relpath(err[key])
- raise ImageComparisonFailure(
- ('images not close (RMS %(rms).3f):'
- '\n\t%(actual)s\n\t%(expected)s\n\t%(diff)s') % err)
-
-
-class _ImageComparisonBase:
- """
- Image comparison base class
-
- This class provides *just* the comparison-related functionality and avoids
- any code that would be specific to any testing framework.
- """
-
- def __init__(self, func, tol, remove_text, savefig_kwargs):
- self.func = func
- self.baseline_dir, self.result_dir = _image_directories(func)
- self.tol = tol
- self.remove_text = remove_text
- self.savefig_kwargs = savefig_kwargs
-
- def copy_baseline(self, baseline, extension):
- baseline_path = self.baseline_dir / baseline
- orig_expected_path = baseline_path.with_suffix(f'.{extension}')
- if extension == 'eps' and not orig_expected_path.exists():
- orig_expected_path = orig_expected_path.with_suffix('.pdf')
- expected_fname = make_test_filename(
- self.result_dir / orig_expected_path.name, 'expected')
- try:
- # os.symlink errors if the target already exists.
- with contextlib.suppress(OSError):
- os.remove(expected_fname)
- try:
- if 'microsoft' in uname().release.lower():
- raise OSError # On WSL, symlink breaks silently
- os.symlink(orig_expected_path, expected_fname)
- except OSError: # On Windows, symlink *may* be unavailable.
- shutil.copyfile(orig_expected_path, expected_fname)
- except OSError as err:
- raise ImageComparisonFailure(
- f"Missing baseline image {expected_fname} because the "
- f"following file cannot be accessed: "
- f"{orig_expected_path}") from err
- return expected_fname
-
- def compare(self, fig, baseline, extension, *, _lock=False):
- __tracebackhide__ = True
-
- if self.remove_text:
- remove_ticks_and_titles(fig)
-
- actual_path = (self.result_dir / baseline).with_suffix(f'.{extension}')
- kwargs = self.savefig_kwargs.copy()
- if extension == 'pdf':
- kwargs.setdefault('metadata',
- {'Creator': None, 'Producer': None,
- 'CreationDate': None})
-
- lock = (cbook._lock_path(actual_path)
- if _lock else contextlib.nullcontext())
- with lock:
- try:
- fig.savefig(actual_path, **kwargs)
- finally:
- # Matplotlib has an autouse fixture to close figures, but this
- # makes things more convenient for third-party users.
- plt.close(fig)
- expected_path = self.copy_baseline(baseline, extension)
- _raise_on_image_difference(expected_path, actual_path, self.tol)
-
-
-def _pytest_image_comparison(baseline_images, extensions, tol,
- freetype_version, remove_text, savefig_kwargs,
- style):
- """
- Decorate function with image comparison for pytest.
-
- This function creates a decorator that wraps a figure-generating function
- with image comparison code.
- """
- import pytest
-
- KEYWORD_ONLY = inspect.Parameter.KEYWORD_ONLY
-
- def decorator(func):
- old_sig = inspect.signature(func)
-
- @functools.wraps(func)
- @pytest.mark.parametrize('extension', extensions)
- @matplotlib.style.context(style)
- @_checked_on_freetype_version(freetype_version)
- @functools.wraps(func)
- def wrapper(*args, extension, request, **kwargs):
- __tracebackhide__ = True
- if 'extension' in old_sig.parameters:
- kwargs['extension'] = extension
- if 'request' in old_sig.parameters:
- kwargs['request'] = request
-
- if extension not in comparable_formats():
- reason = {
- 'pdf': 'because Ghostscript is not installed',
- 'eps': 'because Ghostscript is not installed',
- 'svg': 'because Inkscape is not installed',
- }.get(extension, 'on this system')
- pytest.skip(f"Cannot compare {extension} files {reason}")
-
- img = _ImageComparisonBase(func, tol=tol, remove_text=remove_text,
- savefig_kwargs=savefig_kwargs)
- matplotlib.testing.set_font_settings_for_testing()
-
- with _collect_new_figures() as figs:
- func(*args, **kwargs)
-
- # If the test is parametrized in any way other than applied via
- # this decorator, then we need to use a lock to prevent two
- # processes from touching the same output file.
- needs_lock = any(
- marker.args[0] != 'extension'
- for marker in request.node.iter_markers('parametrize'))
-
- if baseline_images is not None:
- our_baseline_images = baseline_images
- else:
- # Allow baseline image list to be produced on the fly based on
- # current parametrization.
- our_baseline_images = request.getfixturevalue(
- 'baseline_images')
-
- assert len(figs) == len(our_baseline_images), (
- f"Test generated {len(figs)} images but there are "
- f"{len(our_baseline_images)} baseline images")
- for fig, baseline in zip(figs, our_baseline_images):
- img.compare(fig, baseline, extension, _lock=needs_lock)
-
- parameters = list(old_sig.parameters.values())
- if 'extension' not in old_sig.parameters:
- parameters += [inspect.Parameter('extension', KEYWORD_ONLY)]
- if 'request' not in old_sig.parameters:
- parameters += [inspect.Parameter("request", KEYWORD_ONLY)]
- new_sig = old_sig.replace(parameters=parameters)
- wrapper.__signature__ = new_sig
-
- # Reach a bit into pytest internals to hoist the marks from our wrapped
- # function.
- new_marks = getattr(func, 'pytestmark', []) + wrapper.pytestmark
- wrapper.pytestmark = new_marks
-
- return wrapper
-
- return decorator
-
-
-def image_comparison(baseline_images, extensions=None, tol=0,
- freetype_version=None, remove_text=False,
- savefig_kwarg=None,
- # Default of mpl_test_settings fixture and cleanup too.
- style=("classic", "_classic_test_patch")):
- """
- Compare images generated by the test with those specified in
- *baseline_images*, which must correspond, else an `ImageComparisonFailure`
- exception will be raised.
-
- Parameters
- ----------
- baseline_images : list or None
- A list of strings specifying the names of the images generated by
- calls to `.Figure.savefig`.
-
- If *None*, the test function must use the ``baseline_images`` fixture,
- either as a parameter or with `pytest.mark.usefixtures`. This value is
- only allowed when using pytest.
-
- extensions : None or list of str
- The list of extensions to test, e.g. ``['png', 'pdf']``.
-
- If *None*, defaults to all supported extensions: png, pdf, and svg.
-
- When testing a single extension, it can be directly included in the
- names passed to *baseline_images*. In that case, *extensions* must not
- be set.
-
- In order to keep the size of the test suite from ballooning, we only
- include the ``svg`` or ``pdf`` outputs if the test is explicitly
- exercising a feature dependent on that backend (see also the
- `check_figures_equal` decorator for that purpose).
-
- tol : float, default: 0
- The RMS threshold above which the test is considered failed.
-
- Due to expected small differences in floating-point calculations, on
- 32-bit systems an additional 0.06 is added to this threshold.
-
- freetype_version : str or tuple
- The expected freetype version or range of versions for this test to
- pass.
-
- remove_text : bool
- Remove the title and tick text from the figure before comparison. This
- is useful to make the baseline images independent of variations in text
- rendering between different versions of FreeType.
-
- This does not remove other, more deliberate, text, such as legends and
- annotations.
-
- savefig_kwarg : dict
- Optional arguments that are passed to the savefig method.
-
- style : str, dict, or list
- The optional style(s) to apply to the image test. The test itself
- can also apply additional styles if desired. Defaults to ``["classic",
- "_classic_test_patch"]``.
- """
-
- if baseline_images is not None:
- # List of non-empty filename extensions.
- baseline_exts = [*filter(None, {Path(baseline).suffix[1:]
- for baseline in baseline_images})]
- if baseline_exts:
- if extensions is not None:
- raise ValueError(
- "When including extensions directly in 'baseline_images', "
- "'extensions' cannot be set as well")
- if len(baseline_exts) > 1:
- raise ValueError(
- "When including extensions directly in 'baseline_images', "
- "all baselines must share the same suffix")
- extensions = baseline_exts
- baseline_images = [ # Chop suffix out from baseline_images.
- Path(baseline).stem for baseline in baseline_images]
- if extensions is None:
- # Default extensions to test, if not set via baseline_images.
- extensions = ['png', 'pdf', 'svg']
- if savefig_kwarg is None:
- savefig_kwarg = dict() # default no kwargs to savefig
- if sys.maxsize <= 2**32:
- tol += 0.06
- return _pytest_image_comparison(
- baseline_images=baseline_images, extensions=extensions, tol=tol,
- freetype_version=freetype_version, remove_text=remove_text,
- savefig_kwargs=savefig_kwarg, style=style)
-
-
-def check_figures_equal(*, extensions=("png", "pdf", "svg"), tol=0):
- """
- Decorator for test cases that generate and compare two figures.
-
- The decorated function must take two keyword arguments, *fig_test*
- and *fig_ref*, and draw the test and reference images on them.
- After the function returns, the figures are saved and compared.
-
- This decorator should be preferred over `image_comparison` when possible in
- order to keep the size of the test suite from ballooning.
-
- Parameters
- ----------
- extensions : list, default: ["png", "pdf", "svg"]
- The extensions to test.
- tol : float
- The RMS threshold above which the test is considered failed.
-
- Raises
- ------
- RuntimeError
- If any new figures are created (and not subsequently closed) inside
- the test function.
-
- Examples
- --------
- Check that calling `.Axes.plot` with a single argument plots it against
- ``[0, 1, 2, ...]``::
-
- @check_figures_equal()
- def test_plot(fig_test, fig_ref):
- fig_test.subplots().plot([1, 3, 5])
- fig_ref.subplots().plot([0, 1, 2], [1, 3, 5])
-
- """
- ALLOWED_CHARS = set(string.digits + string.ascii_letters + '_-[]()')
- KEYWORD_ONLY = inspect.Parameter.KEYWORD_ONLY
-
- def decorator(func):
- import pytest
-
- _, result_dir = _image_directories(func)
- old_sig = inspect.signature(func)
-
- if not {"fig_test", "fig_ref"}.issubset(old_sig.parameters):
- raise ValueError("The decorated function must have at least the "
- "parameters 'fig_test' and 'fig_ref', but your "
- f"function has the signature {old_sig}")
-
- @pytest.mark.parametrize("ext", extensions)
- def wrapper(*args, ext, request, **kwargs):
- if 'ext' in old_sig.parameters:
- kwargs['ext'] = ext
- if 'request' in old_sig.parameters:
- kwargs['request'] = request
-
- file_name = "".join(c for c in request.node.name
- if c in ALLOWED_CHARS)
- try:
- fig_test = plt.figure("test")
- fig_ref = plt.figure("reference")
- with _collect_new_figures() as figs:
- func(*args, fig_test=fig_test, fig_ref=fig_ref, **kwargs)
- if figs:
- raise RuntimeError('Number of open figures changed during '
- 'test. Make sure you are plotting to '
- 'fig_test or fig_ref, or if this is '
- 'deliberate explicitly close the '
- 'new figure(s) inside the test.')
- test_image_path = result_dir / (file_name + "." + ext)
- ref_image_path = result_dir / (file_name + "-expected." + ext)
- fig_test.savefig(test_image_path)
- fig_ref.savefig(ref_image_path)
- _raise_on_image_difference(
- ref_image_path, test_image_path, tol=tol
- )
- finally:
- plt.close(fig_test)
- plt.close(fig_ref)
-
- parameters = [
- param
- for param in old_sig.parameters.values()
- if param.name not in {"fig_test", "fig_ref"}
- ]
- if 'ext' not in old_sig.parameters:
- parameters += [inspect.Parameter("ext", KEYWORD_ONLY)]
- if 'request' not in old_sig.parameters:
- parameters += [inspect.Parameter("request", KEYWORD_ONLY)]
- new_sig = old_sig.replace(parameters=parameters)
- wrapper.__signature__ = new_sig
-
- # reach a bit into pytest internals to hoist the marks from
- # our wrapped function
- new_marks = getattr(func, "pytestmark", []) + wrapper.pytestmark
- wrapper.pytestmark = new_marks
-
- return wrapper
-
- return decorator
-
-
-def _image_directories(func):
- """
- Compute the baseline and result image directories for testing *func*.
-
- For test module ``foo.bar.test_baz``, the baseline directory is at
- ``foo/bar/baseline_images/test_baz`` and the result directory at
- ``$(pwd)/result_images/test_baz``. The result directory is created if it
- doesn't exist.
- """
- module_path = Path(inspect.getfile(func))
- baseline_dir = module_path.parent / "baseline_images" / module_path.stem
- result_dir = Path().resolve() / "result_images" / module_path.stem
- result_dir.mkdir(parents=True, exist_ok=True)
- return baseline_dir, result_dir
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/decorators.pyi b/contrib/python/matplotlib/py3/matplotlib/testing/decorators.pyi
deleted file mode 100644
index f1b6c5e595..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/decorators.pyi
+++ /dev/null
@@ -1,25 +0,0 @@
-from collections.abc import Callable, Sequence
-from pathlib import Path
-from typing import Any, TypeVar
-from typing_extensions import ParamSpec
-
-from matplotlib.figure import Figure
-from matplotlib.typing import RcStyleType
-
-_P = ParamSpec("_P")
-_R = TypeVar("_R")
-
-def remove_ticks_and_titles(figure: Figure) -> None: ...
-def image_comparison(
- baseline_images: list[str] | None,
- extensions: list[str] | None = ...,
- tol: float = ...,
- freetype_version: tuple[str, str] | str | None = ...,
- remove_text: bool = ...,
- savefig_kwarg: dict[str, Any] | None = ...,
- style: RcStyleType = ...,
-) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ...
-def check_figures_equal(
- *, extensions: Sequence[str] = ..., tol: float = ...
-) -> Callable[[Callable[_P, _R]], Callable[_P, _R]]: ...
-def _image_directories(func: Callable) -> tuple[Path, Path]: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/exceptions.py b/contrib/python/matplotlib/py3/matplotlib/testing/exceptions.py
deleted file mode 100644
index c39a392077..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/exceptions.py
+++ /dev/null
@@ -1,4 +0,0 @@
-class ImageComparisonFailure(AssertionError):
- """
- Raise this exception to mark a test as a comparison between two images.
- """
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/Duration.py b/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/Duration.py
deleted file mode 100644
index 052c5a47c0..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/Duration.py
+++ /dev/null
@@ -1,138 +0,0 @@
-"""Duration module."""
-
-import functools
-import operator
-
-from matplotlib import _api
-
-
-class Duration:
- """Class Duration in development."""
-
- allowed = ["ET", "UTC"]
-
- def __init__(self, frame, seconds):
- """
- Create a new Duration object.
-
- = ERROR CONDITIONS
- - If the input frame is not in the allowed list, an error is thrown.
-
- = INPUT VARIABLES
- - frame The frame of the duration. Must be 'ET' or 'UTC'
- - seconds The number of seconds in the Duration.
- """
- _api.check_in_list(self.allowed, frame=frame)
- self._frame = frame
- self._seconds = seconds
-
- def frame(self):
- """Return the frame the duration is in."""
- return self._frame
-
- def __abs__(self):
- """Return the absolute value of the duration."""
- return Duration(self._frame, abs(self._seconds))
-
- def __neg__(self):
- """Return the negative value of this Duration."""
- return Duration(self._frame, -self._seconds)
-
- def seconds(self):
- """Return the number of seconds in the Duration."""
- return self._seconds
-
- def __bool__(self):
- return self._seconds != 0
-
- def _cmp(self, op, rhs):
- """
- Check that *self* and *rhs* share frames; compare them using *op*.
- """
- self.checkSameFrame(rhs, "compare")
- return op(self._seconds, rhs._seconds)
-
- __eq__ = functools.partialmethod(_cmp, operator.eq)
- __ne__ = functools.partialmethod(_cmp, operator.ne)
- __lt__ = functools.partialmethod(_cmp, operator.lt)
- __le__ = functools.partialmethod(_cmp, operator.le)
- __gt__ = functools.partialmethod(_cmp, operator.gt)
- __ge__ = functools.partialmethod(_cmp, operator.ge)
-
- def __add__(self, rhs):
- """
- Add two Durations.
-
- = ERROR CONDITIONS
- - If the input rhs is not in the same frame, an error is thrown.
-
- = INPUT VARIABLES
- - rhs The Duration to add.
-
- = RETURN VALUE
- - Returns the sum of ourselves and the input Duration.
- """
- # Delay-load due to circular dependencies.
- import matplotlib.testing.jpl_units as U
-
- if isinstance(rhs, U.Epoch):
- return rhs + self
-
- self.checkSameFrame(rhs, "add")
- return Duration(self._frame, self._seconds + rhs._seconds)
-
- def __sub__(self, rhs):
- """
- Subtract two Durations.
-
- = ERROR CONDITIONS
- - If the input rhs is not in the same frame, an error is thrown.
-
- = INPUT VARIABLES
- - rhs The Duration to subtract.
-
- = RETURN VALUE
- - Returns the difference of ourselves and the input Duration.
- """
- self.checkSameFrame(rhs, "sub")
- return Duration(self._frame, self._seconds - rhs._seconds)
-
- def __mul__(self, rhs):
- """
- Scale a UnitDbl by a value.
-
- = INPUT VARIABLES
- - rhs The scalar to multiply by.
-
- = RETURN VALUE
- - Returns the scaled Duration.
- """
- return Duration(self._frame, self._seconds * float(rhs))
-
- __rmul__ = __mul__
-
- def __str__(self):
- """Print the Duration."""
- return f"{self._seconds:g} {self._frame}"
-
- def __repr__(self):
- """Print the Duration."""
- return f"Duration('{self._frame}', {self._seconds:g})"
-
- def checkSameFrame(self, rhs, func):
- """
- Check to see if frames are the same.
-
- = ERROR CONDITIONS
- - If the frame of the rhs Duration is not the same as our frame,
- an error is thrown.
-
- = INPUT VARIABLES
- - rhs The Duration to check for the same frame
- - func The name of the function doing the check.
- """
- if self._frame != rhs._frame:
- raise ValueError(
- f"Cannot {func} Durations with different frames.\n"
- f"LHS: {self._frame}\n"
- f"RHS: {rhs._frame}")
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/Epoch.py b/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/Epoch.py
deleted file mode 100644
index 501b7fa38c..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/Epoch.py
+++ /dev/null
@@ -1,211 +0,0 @@
-"""Epoch module."""
-
-import functools
-import operator
-import math
-import datetime as DT
-
-from matplotlib import _api
-from matplotlib.dates import date2num
-
-
-class Epoch:
- # Frame conversion offsets in seconds
- # t(TO) = t(FROM) + allowed[ FROM ][ TO ]
- allowed = {
- "ET": {
- "UTC": +64.1839,
- },
- "UTC": {
- "ET": -64.1839,
- },
- }
-
- def __init__(self, frame, sec=None, jd=None, daynum=None, dt=None):
- """
- Create a new Epoch object.
-
- Build an epoch 1 of 2 ways:
-
- Using seconds past a Julian date:
- # Epoch('ET', sec=1e8, jd=2451545)
-
- or using a matplotlib day number
- # Epoch('ET', daynum=730119.5)
-
- = ERROR CONDITIONS
- - If the input units are not in the allowed list, an error is thrown.
-
- = INPUT VARIABLES
- - frame The frame of the epoch. Must be 'ET' or 'UTC'
- - sec The number of seconds past the input JD.
- - jd The Julian date of the epoch.
- - daynum The matplotlib day number of the epoch.
- - dt A python datetime instance.
- """
- if ((sec is None and jd is not None) or
- (sec is not None and jd is None) or
- (daynum is not None and
- (sec is not None or jd is not None)) or
- (daynum is None and dt is None and
- (sec is None or jd is None)) or
- (daynum is not None and dt is not None) or
- (dt is not None and (sec is not None or jd is not None)) or
- ((dt is not None) and not isinstance(dt, DT.datetime))):
- raise ValueError(
- "Invalid inputs. Must enter sec and jd together, "
- "daynum by itself, or dt (must be a python datetime).\n"
- "Sec = %s\n"
- "JD = %s\n"
- "dnum= %s\n"
- "dt = %s" % (sec, jd, daynum, dt))
-
- _api.check_in_list(self.allowed, frame=frame)
- self._frame = frame
-
- if dt is not None:
- daynum = date2num(dt)
-
- if daynum is not None:
- # 1-JAN-0001 in JD = 1721425.5
- jd = float(daynum) + 1721425.5
- self._jd = math.floor(jd)
- self._seconds = (jd - self._jd) * 86400.0
-
- else:
- self._seconds = float(sec)
- self._jd = float(jd)
-
- # Resolve seconds down to [ 0, 86400)
- deltaDays = math.floor(self._seconds / 86400)
- self._jd += deltaDays
- self._seconds -= deltaDays * 86400.0
-
- def convert(self, frame):
- if self._frame == frame:
- return self
-
- offset = self.allowed[self._frame][frame]
-
- return Epoch(frame, self._seconds + offset, self._jd)
-
- def frame(self):
- return self._frame
-
- def julianDate(self, frame):
- t = self
- if frame != self._frame:
- t = self.convert(frame)
-
- return t._jd + t._seconds / 86400.0
-
- def secondsPast(self, frame, jd):
- t = self
- if frame != self._frame:
- t = self.convert(frame)
-
- delta = t._jd - jd
- return t._seconds + delta * 86400
-
- def _cmp(self, op, rhs):
- """Compare Epochs *self* and *rhs* using operator *op*."""
- t = self
- if self._frame != rhs._frame:
- t = self.convert(rhs._frame)
- if t._jd != rhs._jd:
- return op(t._jd, rhs._jd)
- return op(t._seconds, rhs._seconds)
-
- __eq__ = functools.partialmethod(_cmp, operator.eq)
- __ne__ = functools.partialmethod(_cmp, operator.ne)
- __lt__ = functools.partialmethod(_cmp, operator.lt)
- __le__ = functools.partialmethod(_cmp, operator.le)
- __gt__ = functools.partialmethod(_cmp, operator.gt)
- __ge__ = functools.partialmethod(_cmp, operator.ge)
-
- def __add__(self, rhs):
- """
- Add a duration to an Epoch.
-
- = INPUT VARIABLES
- - rhs The Epoch to subtract.
-
- = RETURN VALUE
- - Returns the difference of ourselves and the input Epoch.
- """
- t = self
- if self._frame != rhs.frame():
- t = self.convert(rhs._frame)
-
- sec = t._seconds + rhs.seconds()
-
- return Epoch(t._frame, sec, t._jd)
-
- def __sub__(self, rhs):
- """
- Subtract two Epoch's or a Duration from an Epoch.
-
- Valid:
- Duration = Epoch - Epoch
- Epoch = Epoch - Duration
-
- = INPUT VARIABLES
- - rhs The Epoch to subtract.
-
- = RETURN VALUE
- - Returns either the duration between to Epoch's or the a new
- Epoch that is the result of subtracting a duration from an epoch.
- """
- # Delay-load due to circular dependencies.
- import matplotlib.testing.jpl_units as U
-
- # Handle Epoch - Duration
- if isinstance(rhs, U.Duration):
- return self + -rhs
-
- t = self
- if self._frame != rhs._frame:
- t = self.convert(rhs._frame)
-
- days = t._jd - rhs._jd
- sec = t._seconds - rhs._seconds
-
- return U.Duration(rhs._frame, days*86400 + sec)
-
- def __str__(self):
- """Print the Epoch."""
- return f"{self.julianDate(self._frame):22.15e} {self._frame}"
-
- def __repr__(self):
- """Print the Epoch."""
- return str(self)
-
- @staticmethod
- def range(start, stop, step):
- """
- Generate a range of Epoch objects.
-
- Similar to the Python range() method. Returns the range [
- start, stop) at the requested step. Each element will be a
- Epoch object.
-
- = INPUT VARIABLES
- - start The starting value of the range.
- - stop The stop value of the range.
- - step Step to use.
-
- = RETURN VALUE
- - Returns a list containing the requested Epoch values.
- """
- elems = []
-
- i = 0
- while True:
- d = start + i * step
- if d >= stop:
- break
-
- elems.append(d)
- i += 1
-
- return elems
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/EpochConverter.py b/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/EpochConverter.py
deleted file mode 100644
index f42d7b71d0..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/EpochConverter.py
+++ /dev/null
@@ -1,96 +0,0 @@
-"""EpochConverter module containing class EpochConverter."""
-
-from matplotlib import cbook, units
-import matplotlib.dates as date_ticker
-
-__all__ = ['EpochConverter']
-
-
-class EpochConverter(units.ConversionInterface):
- """
- Provides Matplotlib conversion functionality for Monte Epoch and Duration
- classes.
- """
-
- # julian date reference for "Jan 1, 0001" minus 1 day because
- # Matplotlib really wants "Jan 0, 0001"
- jdRef = 1721425.5 - 1
-
- @staticmethod
- def axisinfo(unit, axis):
- # docstring inherited
- majloc = date_ticker.AutoDateLocator()
- majfmt = date_ticker.AutoDateFormatter(majloc)
- return units.AxisInfo(majloc=majloc, majfmt=majfmt, label=unit)
-
- @staticmethod
- def float2epoch(value, unit):
- """
- Convert a Matplotlib floating-point date into an Epoch of the specified
- units.
-
- = INPUT VARIABLES
- - value The Matplotlib floating-point date.
- - unit The unit system to use for the Epoch.
-
- = RETURN VALUE
- - Returns the value converted to an Epoch in the specified time system.
- """
- # Delay-load due to circular dependencies.
- import matplotlib.testing.jpl_units as U
-
- secPastRef = value * 86400.0 * U.UnitDbl(1.0, 'sec')
- return U.Epoch(unit, secPastRef, EpochConverter.jdRef)
-
- @staticmethod
- def epoch2float(value, unit):
- """
- Convert an Epoch value to a float suitable for plotting as a python
- datetime object.
-
- = INPUT VARIABLES
- - value An Epoch or list of Epochs that need to be converted.
- - unit The units to use for an axis with Epoch data.
-
- = RETURN VALUE
- - Returns the value parameter converted to floats.
- """
- return value.julianDate(unit) - EpochConverter.jdRef
-
- @staticmethod
- def duration2float(value):
- """
- Convert a Duration value to a float suitable for plotting as a python
- datetime object.
-
- = INPUT VARIABLES
- - value A Duration or list of Durations that need to be converted.
-
- = RETURN VALUE
- - Returns the value parameter converted to floats.
- """
- return value.seconds() / 86400.0
-
- @staticmethod
- def convert(value, unit, axis):
- # docstring inherited
-
- # Delay-load due to circular dependencies.
- import matplotlib.testing.jpl_units as U
-
- if not cbook.is_scalar_or_string(value):
- return [EpochConverter.convert(x, unit, axis) for x in value]
- if unit is None:
- unit = EpochConverter.default_units(value, axis)
- if isinstance(value, U.Duration):
- return EpochConverter.duration2float(value)
- else:
- return EpochConverter.epoch2float(value, unit)
-
- @staticmethod
- def default_units(value, axis):
- # docstring inherited
- if cbook.is_scalar_or_string(value):
- return value.frame()
- else:
- return EpochConverter.default_units(value[0], axis)
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/StrConverter.py b/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/StrConverter.py
deleted file mode 100644
index a62d4981dc..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/StrConverter.py
+++ /dev/null
@@ -1,97 +0,0 @@
-"""StrConverter module containing class StrConverter."""
-
-import numpy as np
-
-import matplotlib.units as units
-
-__all__ = ['StrConverter']
-
-
-class StrConverter(units.ConversionInterface):
- """
- A Matplotlib converter class for string data values.
-
- Valid units for string are:
- - 'indexed' : Values are indexed as they are specified for plotting.
- - 'sorted' : Values are sorted alphanumerically.
- - 'inverted' : Values are inverted so that the first value is on top.
- - 'sorted-inverted' : A combination of 'sorted' and 'inverted'
- """
-
- @staticmethod
- def axisinfo(unit, axis):
- # docstring inherited
- return None
-
- @staticmethod
- def convert(value, unit, axis):
- # docstring inherited
-
- if value == []:
- return []
-
- # we delay loading to make matplotlib happy
- ax = axis.axes
- if axis is ax.xaxis:
- isXAxis = True
- else:
- isXAxis = False
-
- axis.get_major_ticks()
- ticks = axis.get_ticklocs()
- labels = axis.get_ticklabels()
-
- labels = [l.get_text() for l in labels if l.get_text()]
-
- if not labels:
- ticks = []
- labels = []
-
- if not np.iterable(value):
- value = [value]
-
- newValues = []
- for v in value:
- if v not in labels and v not in newValues:
- newValues.append(v)
-
- labels.extend(newValues)
-
- # DISABLED: This is disabled because matplotlib bar plots do not
- # DISABLED: recalculate the unit conversion of the data values
- # DISABLED: this is due to design and is not really a bug.
- # DISABLED: If this gets changed, then we can activate the following
- # DISABLED: block of code. Note that this works for line plots.
- # DISABLED if unit:
- # DISABLED if unit.find("sorted") > -1:
- # DISABLED labels.sort()
- # DISABLED if unit.find("inverted") > -1:
- # DISABLED labels = labels[::-1]
-
- # add padding (so they do not appear on the axes themselves)
- labels = [''] + labels + ['']
- ticks = list(range(len(labels)))
- ticks[0] = 0.5
- ticks[-1] = ticks[-1] - 0.5
-
- axis.set_ticks(ticks)
- axis.set_ticklabels(labels)
- # we have to do the following lines to make ax.autoscale_view work
- loc = axis.get_major_locator()
- loc.set_bounds(ticks[0], ticks[-1])
-
- if isXAxis:
- ax.set_xlim(ticks[0], ticks[-1])
- else:
- ax.set_ylim(ticks[0], ticks[-1])
-
- result = [ticks[labels.index(v)] for v in value]
-
- ax.viewLim.ignore(-1)
- return result
-
- @staticmethod
- def default_units(value, axis):
- # docstring inherited
- # The default behavior for string indexing.
- return "indexed"
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/UnitDbl.py b/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/UnitDbl.py
deleted file mode 100644
index 5226c06ad5..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/UnitDbl.py
+++ /dev/null
@@ -1,180 +0,0 @@
-"""UnitDbl module."""
-
-import functools
-import operator
-
-from matplotlib import _api
-
-
-class UnitDbl:
- """Class UnitDbl in development."""
-
- # Unit conversion table. Small subset of the full one but enough
- # to test the required functions. First field is a scale factor to
- # convert the input units to the units of the second field. Only
- # units in this table are allowed.
- allowed = {
- "m": (0.001, "km"),
- "km": (1, "km"),
- "mile": (1.609344, "km"),
-
- "rad": (1, "rad"),
- "deg": (1.745329251994330e-02, "rad"),
-
- "sec": (1, "sec"),
- "min": (60.0, "sec"),
- "hour": (3600, "sec"),
- }
-
- _types = {
- "km": "distance",
- "rad": "angle",
- "sec": "time",
- }
-
- def __init__(self, value, units):
- """
- Create a new UnitDbl object.
-
- Units are internally converted to km, rad, and sec. The only
- valid inputs for units are [m, km, mile, rad, deg, sec, min, hour].
-
- The field UnitDbl.value will contain the converted value. Use
- the convert() method to get a specific type of units back.
-
- = ERROR CONDITIONS
- - If the input units are not in the allowed list, an error is thrown.
-
- = INPUT VARIABLES
- - value The numeric value of the UnitDbl.
- - units The string name of the units the value is in.
- """
- data = _api.check_getitem(self.allowed, units=units)
- self._value = float(value * data[0])
- self._units = data[1]
-
- def convert(self, units):
- """
- Convert the UnitDbl to a specific set of units.
-
- = ERROR CONDITIONS
- - If the input units are not in the allowed list, an error is thrown.
-
- = INPUT VARIABLES
- - units The string name of the units to convert to.
-
- = RETURN VALUE
- - Returns the value of the UnitDbl in the requested units as a floating
- point number.
- """
- if self._units == units:
- return self._value
- data = _api.check_getitem(self.allowed, units=units)
- if self._units != data[1]:
- raise ValueError(f"Error trying to convert to different units.\n"
- f" Invalid conversion requested.\n"
- f" UnitDbl: {self}\n"
- f" Units: {units}\n")
- return self._value / data[0]
-
- def __abs__(self):
- """Return the absolute value of this UnitDbl."""
- return UnitDbl(abs(self._value), self._units)
-
- def __neg__(self):
- """Return the negative value of this UnitDbl."""
- return UnitDbl(-self._value, self._units)
-
- def __bool__(self):
- """Return the truth value of a UnitDbl."""
- return bool(self._value)
-
- def _cmp(self, op, rhs):
- """Check that *self* and *rhs* share units; compare them using *op*."""
- self.checkSameUnits(rhs, "compare")
- return op(self._value, rhs._value)
-
- __eq__ = functools.partialmethod(_cmp, operator.eq)
- __ne__ = functools.partialmethod(_cmp, operator.ne)
- __lt__ = functools.partialmethod(_cmp, operator.lt)
- __le__ = functools.partialmethod(_cmp, operator.le)
- __gt__ = functools.partialmethod(_cmp, operator.gt)
- __ge__ = functools.partialmethod(_cmp, operator.ge)
-
- def _binop_unit_unit(self, op, rhs):
- """Check that *self* and *rhs* share units; combine them using *op*."""
- self.checkSameUnits(rhs, op.__name__)
- return UnitDbl(op(self._value, rhs._value), self._units)
-
- __add__ = functools.partialmethod(_binop_unit_unit, operator.add)
- __sub__ = functools.partialmethod(_binop_unit_unit, operator.sub)
-
- def _binop_unit_scalar(self, op, scalar):
- """Combine *self* and *scalar* using *op*."""
- return UnitDbl(op(self._value, scalar), self._units)
-
- __mul__ = functools.partialmethod(_binop_unit_scalar, operator.mul)
- __rmul__ = functools.partialmethod(_binop_unit_scalar, operator.mul)
-
- def __str__(self):
- """Print the UnitDbl."""
- return f"{self._value:g} *{self._units}"
-
- def __repr__(self):
- """Print the UnitDbl."""
- return f"UnitDbl({self._value:g}, '{self._units}')"
-
- def type(self):
- """Return the type of UnitDbl data."""
- return self._types[self._units]
-
- @staticmethod
- def range(start, stop, step=None):
- """
- Generate a range of UnitDbl objects.
-
- Similar to the Python range() method. Returns the range [
- start, stop) at the requested step. Each element will be a
- UnitDbl object.
-
- = INPUT VARIABLES
- - start The starting value of the range.
- - stop The stop value of the range.
- - step Optional step to use. If set to None, then a UnitDbl of
- value 1 w/ the units of the start is used.
-
- = RETURN VALUE
- - Returns a list containing the requested UnitDbl values.
- """
- if step is None:
- step = UnitDbl(1, start._units)
-
- elems = []
-
- i = 0
- while True:
- d = start + i * step
- if d >= stop:
- break
-
- elems.append(d)
- i += 1
-
- return elems
-
- def checkSameUnits(self, rhs, func):
- """
- Check to see if units are the same.
-
- = ERROR CONDITIONS
- - If the units of the rhs UnitDbl are not the same as our units,
- an error is thrown.
-
- = INPUT VARIABLES
- - rhs The UnitDbl to check for the same units
- - func The name of the function doing the check.
- """
- if self._units != rhs._units:
- raise ValueError(f"Cannot {func} units of different types.\n"
- f"LHS: {self._units}\n"
- f"RHS: {rhs._units}")
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/UnitDblConverter.py b/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/UnitDblConverter.py
deleted file mode 100644
index 23065379f5..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/UnitDblConverter.py
+++ /dev/null
@@ -1,85 +0,0 @@
-"""UnitDblConverter module containing class UnitDblConverter."""
-
-import numpy as np
-
-from matplotlib import cbook, units
-import matplotlib.projections.polar as polar
-
-__all__ = ['UnitDblConverter']
-
-
-# A special function for use with the matplotlib FuncFormatter class
-# for formatting axes with radian units.
-# This was copied from matplotlib example code.
-def rad_fn(x, pos=None):
- """Radian function formatter."""
- n = int((x / np.pi) * 2.0 + 0.25)
- if n == 0:
- return str(x)
- elif n == 1:
- return r'$\pi/2$'
- elif n == 2:
- return r'$\pi$'
- elif n % 2 == 0:
- return fr'${n//2}\pi$'
- else:
- return fr'${n}\pi/2$'
-
-
-class UnitDblConverter(units.ConversionInterface):
- """
- Provides Matplotlib conversion functionality for the Monte UnitDbl class.
- """
- # default for plotting
- defaults = {
- "distance": 'km',
- "angle": 'deg',
- "time": 'sec',
- }
-
- @staticmethod
- def axisinfo(unit, axis):
- # docstring inherited
-
- # Delay-load due to circular dependencies.
- import matplotlib.testing.jpl_units as U
-
- # Check to see if the value used for units is a string unit value
- # or an actual instance of a UnitDbl so that we can use the unit
- # value for the default axis label value.
- if unit:
- label = unit if isinstance(unit, str) else unit.label()
- else:
- label = None
-
- if label == "deg" and isinstance(axis.axes, polar.PolarAxes):
- # If we want degrees for a polar plot, use the PolarPlotFormatter
- majfmt = polar.PolarAxes.ThetaFormatter()
- else:
- majfmt = U.UnitDblFormatter(useOffset=False)
-
- return units.AxisInfo(majfmt=majfmt, label=label)
-
- @staticmethod
- def convert(value, unit, axis):
- # docstring inherited
- if not cbook.is_scalar_or_string(value):
- return [UnitDblConverter.convert(x, unit, axis) for x in value]
- # If no units were specified, then get the default units to use.
- if unit is None:
- unit = UnitDblConverter.default_units(value, axis)
- # Convert the incoming UnitDbl value/values to float/floats
- if isinstance(axis.axes, polar.PolarAxes) and value.type() == "angle":
- # Guarantee that units are radians for polar plots.
- return value.convert("rad")
- return value.convert(unit)
-
- @staticmethod
- def default_units(value, axis):
- # docstring inherited
- # Determine the default units based on the user preferences set for
- # default units when printing a UnitDbl.
- if cbook.is_scalar_or_string(value):
- return UnitDblConverter.defaults[value.type()]
- else:
- return UnitDblConverter.default_units(value[0], axis)
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/UnitDblFormatter.py b/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/UnitDblFormatter.py
deleted file mode 100644
index 30a9914015..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/UnitDblFormatter.py
+++ /dev/null
@@ -1,28 +0,0 @@
-"""UnitDblFormatter module containing class UnitDblFormatter."""
-
-import matplotlib.ticker as ticker
-
-__all__ = ['UnitDblFormatter']
-
-
-class UnitDblFormatter(ticker.ScalarFormatter):
- """
- The formatter for UnitDbl data types.
-
- This allows for formatting with the unit string.
- """
-
- def __call__(self, x, pos=None):
- # docstring inherited
- if len(self.locs) == 0:
- return ''
- else:
- return f'{x:.12}'
-
- def format_data_short(self, value):
- # docstring inherited
- return f'{value:.12}'
-
- def format_data(self, value):
- # docstring inherited
- return f'{value:.12}'
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/__init__.py b/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/__init__.py
deleted file mode 100644
index b8caa9a895..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/jpl_units/__init__.py
+++ /dev/null
@@ -1,76 +0,0 @@
-"""
-A sample set of units for use with testing unit conversion
-of Matplotlib routines. These are used because they use very strict
-enforcement of unitized data which will test the entire spectrum of how
-unitized data might be used (it is not always meaningful to convert to
-a float without specific units given).
-
-UnitDbl is essentially a unitized floating point number. It has a
-minimal set of supported units (enough for testing purposes). All
-of the mathematical operation are provided to fully test any behaviour
-that might occur with unitized data. Remember that unitized data has
-rules as to how it can be applied to one another (a value of distance
-cannot be added to a value of time). Thus we need to guard against any
-accidental "default" conversion that will strip away the meaning of the
-data and render it neutered.
-
-Epoch is different than a UnitDbl of time. Time is something that can be
-measured where an Epoch is a specific moment in time. Epochs are typically
-referenced as an offset from some predetermined epoch.
-
-A difference of two epochs is a Duration. The distinction between a Duration
-and a UnitDbl of time is made because an Epoch can have different frames (or
-units). In the case of our test Epoch class the two allowed frames are 'UTC'
-and 'ET' (Note that these are rough estimates provided for testing purposes
-and should not be used in production code where accuracy of time frames is
-desired). As such a Duration also has a frame of reference and therefore needs
-to be called out as different that a simple measurement of time since a delta-t
-in one frame may not be the same in another.
-"""
-
-from .Duration import Duration
-from .Epoch import Epoch
-from .UnitDbl import UnitDbl
-
-from .StrConverter import StrConverter
-from .EpochConverter import EpochConverter
-from .UnitDblConverter import UnitDblConverter
-
-from .UnitDblFormatter import UnitDblFormatter
-
-
-__version__ = "1.0"
-
-__all__ = [
- 'register',
- 'Duration',
- 'Epoch',
- 'UnitDbl',
- 'UnitDblFormatter',
- ]
-
-
-def register():
- """Register the unit conversion classes with matplotlib."""
- import matplotlib.units as mplU
-
- mplU.registry[str] = StrConverter()
- mplU.registry[Epoch] = EpochConverter()
- mplU.registry[Duration] = EpochConverter()
- mplU.registry[UnitDbl] = UnitDblConverter()
-
-
-# Some default unit instances
-# Distances
-m = UnitDbl(1.0, "m")
-km = UnitDbl(1.0, "km")
-mile = UnitDbl(1.0, "mile")
-# Angles
-deg = UnitDbl(1.0, "deg")
-rad = UnitDbl(1.0, "rad")
-# Time
-sec = UnitDbl(1.0, "sec")
-min = UnitDbl(1.0, "min")
-hr = UnitDbl(1.0, "hour")
-day = UnitDbl(24.0, "hour")
-sec = UnitDbl(1.0, "sec")
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/widgets.py b/contrib/python/matplotlib/py3/matplotlib/testing/widgets.py
deleted file mode 100644
index eb75518536..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/widgets.py
+++ /dev/null
@@ -1,119 +0,0 @@
-"""
-========================
-Widget testing utilities
-========================
-
-See also :mod:`matplotlib.tests.test_widgets`.
-"""
-
-from unittest import mock
-
-import matplotlib.pyplot as plt
-
-
-def get_ax():
- """Create a plot and return its axes."""
- fig, ax = plt.subplots(1, 1)
- ax.plot([0, 200], [0, 200])
- ax.set_aspect(1.0)
- ax.figure.canvas.draw()
- return ax
-
-
-def noop(*args, **kwargs):
- pass
-
-
-def mock_event(ax, button=1, xdata=0, ydata=0, key=None, step=1):
- r"""
- Create a mock event that can stand in for `.Event` and its subclasses.
-
- This event is intended to be used in tests where it can be passed into
- event handling functions.
-
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The axes the event will be in.
- xdata : float
- x coord of mouse in data coords.
- ydata : float
- y coord of mouse in data coords.
- button : None or `MouseButton` or {'up', 'down'}
- The mouse button pressed in this event (see also `.MouseEvent`).
- key : None or str
- The key pressed when the mouse event triggered (see also `.KeyEvent`).
- step : int
- Number of scroll steps (positive for 'up', negative for 'down').
-
- Returns
- -------
- event
- A `.Event`\-like Mock instance.
- """
- event = mock.Mock()
- event.button = button
- event.x, event.y = ax.transData.transform([(xdata, ydata),
- (xdata, ydata)])[0]
- event.xdata, event.ydata = xdata, ydata
- event.inaxes = ax
- event.canvas = ax.figure.canvas
- event.key = key
- event.step = step
- event.guiEvent = None
- event.name = 'Custom'
- return event
-
-
-def do_event(tool, etype, button=1, xdata=0, ydata=0, key=None, step=1):
- """
- Trigger an event on the given tool.
-
- Parameters
- ----------
- tool : matplotlib.widgets.AxesWidget
- etype : str
- The event to trigger.
- xdata : float
- x coord of mouse in data coords.
- ydata : float
- y coord of mouse in data coords.
- button : None or `MouseButton` or {'up', 'down'}
- The mouse button pressed in this event (see also `.MouseEvent`).
- key : None or str
- The key pressed when the mouse event triggered (see also `.KeyEvent`).
- step : int
- Number of scroll steps (positive for 'up', negative for 'down').
- """
- event = mock_event(tool.ax, button, xdata, ydata, key, step)
- func = getattr(tool, etype)
- func(event)
-
-
-def click_and_drag(tool, start, end, key=None):
- """
- Helper to simulate a mouse drag operation.
-
- Parameters
- ----------
- tool : `~matplotlib.widgets.Widget`
- start : [float, float]
- Starting point in data coordinates.
- end : [float, float]
- End point in data coordinates.
- key : None or str
- An optional key that is pressed during the whole operation
- (see also `.KeyEvent`).
- """
- if key is not None:
- # Press key
- do_event(tool, 'on_key_press', xdata=start[0], ydata=start[1],
- button=1, key=key)
- # Click, move, and release mouse
- do_event(tool, 'press', xdata=start[0], ydata=start[1], button=1)
- do_event(tool, 'onmove', xdata=end[0], ydata=end[1], button=1)
- do_event(tool, 'release', xdata=end[0], ydata=end[1], button=1)
- if key is not None:
- # Release key
- do_event(tool, 'on_key_release', xdata=end[0], ydata=end[1],
- button=1, key=key)
diff --git a/contrib/python/matplotlib/py3/matplotlib/testing/widgets.pyi b/contrib/python/matplotlib/py3/matplotlib/testing/widgets.pyi
deleted file mode 100644
index 858ff45715..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/testing/widgets.pyi
+++ /dev/null
@@ -1,31 +0,0 @@
-from typing import Any, Literal
-
-from matplotlib.axes import Axes
-from matplotlib.backend_bases import Event, MouseButton
-from matplotlib.widgets import AxesWidget, Widget
-
-def get_ax() -> Axes: ...
-def noop(*args: Any, **kwargs: Any) -> None: ...
-def mock_event(
- ax: Axes,
- button: MouseButton | int | Literal["up", "down"] | None = ...,
- xdata: float = ...,
- ydata: float = ...,
- key: str | None = ...,
- step: int = ...,
-) -> Event: ...
-def do_event(
- tool: AxesWidget,
- etype: str,
- button: MouseButton | int | Literal["up", "down"] | None = ...,
- xdata: float = ...,
- ydata: float = ...,
- key: str | None = ...,
- step: int = ...,
-) -> None: ...
-def click_and_drag(
- tool: Widget,
- start: tuple[float, float],
- end: tuple[float, float],
- key: str | None = ...,
-) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/texmanager.py b/contrib/python/matplotlib/py3/matplotlib/texmanager.py
deleted file mode 100644
index 812eab58b8..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/texmanager.py
+++ /dev/null
@@ -1,368 +0,0 @@
-r"""
-Support for embedded TeX expressions in Matplotlib.
-
-Requirements:
-
-* LaTeX.
-* \*Agg backends: dvipng>=1.6.
-* PS backend: PSfrag, dvips, and Ghostscript>=9.0.
-* PDF and SVG backends: if LuaTeX is present, it will be used to speed up some
- post-processing steps, but note that it is not used to parse the TeX string
- itself (only LaTeX is supported).
-
-To enable TeX rendering of all text in your Matplotlib figure, set
-:rc:`text.usetex` to True.
-
-TeX and dvipng/dvips processing results are cached
-in ~/.matplotlib/tex.cache for reuse between sessions.
-
-`TexManager.get_rgba` can also be used to directly obtain raster output as RGBA
-NumPy arrays.
-"""
-
-import functools
-import hashlib
-import logging
-import os
-from pathlib import Path
-import subprocess
-from tempfile import TemporaryDirectory
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, cbook, dviread
-
-_log = logging.getLogger(__name__)
-
-
-def _usepackage_if_not_loaded(package, *, option=None):
- """
- Output LaTeX code that loads a package (possibly with an option) if it
- hasn't been loaded yet.
-
- LaTeX cannot load twice a package with different options, so this helper
- can be used to protect against users loading arbitrary packages/options in
- their custom preamble.
- """
- option = f"[{option}]" if option is not None else ""
- return (
- r"\makeatletter"
- r"\@ifpackageloaded{%(package)s}{}{\usepackage%(option)s{%(package)s}}"
- r"\makeatother"
- ) % {"package": package, "option": option}
-
-
-class TexManager:
- """
- Convert strings to dvi files using TeX, caching the results to a directory.
-
- The cache directory is called ``tex.cache`` and is located in the directory
- returned by `.get_cachedir`.
-
- Repeated calls to this constructor always return the same instance.
- """
-
- texcache = _api.deprecate_privatize_attribute("3.8")
- _texcache = os.path.join(mpl.get_cachedir(), 'tex.cache')
- _grey_arrayd = {}
-
- _font_families = ('serif', 'sans-serif', 'cursive', 'monospace')
- _font_preambles = {
- 'new century schoolbook': r'\renewcommand{\rmdefault}{pnc}',
- 'bookman': r'\renewcommand{\rmdefault}{pbk}',
- 'times': r'\usepackage{mathptmx}',
- 'palatino': r'\usepackage{mathpazo}',
- 'zapf chancery': r'\usepackage{chancery}',
- 'cursive': r'\usepackage{chancery}',
- 'charter': r'\usepackage{charter}',
- 'serif': '',
- 'sans-serif': '',
- 'helvetica': r'\usepackage{helvet}',
- 'avant garde': r'\usepackage{avant}',
- 'courier': r'\usepackage{courier}',
- # Loading the type1ec package ensures that cm-super is installed, which
- # is necessary for Unicode computer modern. (It also allows the use of
- # computer modern at arbitrary sizes, but that's just a side effect.)
- 'monospace': r'\usepackage{type1ec}',
- 'computer modern roman': r'\usepackage{type1ec}',
- 'computer modern sans serif': r'\usepackage{type1ec}',
- 'computer modern typewriter': r'\usepackage{type1ec}',
- }
- _font_types = {
- 'new century schoolbook': 'serif',
- 'bookman': 'serif',
- 'times': 'serif',
- 'palatino': 'serif',
- 'zapf chancery': 'cursive',
- 'charter': 'serif',
- 'helvetica': 'sans-serif',
- 'avant garde': 'sans-serif',
- 'courier': 'monospace',
- 'computer modern roman': 'serif',
- 'computer modern sans serif': 'sans-serif',
- 'computer modern typewriter': 'monospace',
- }
-
- @functools.lru_cache # Always return the same instance.
- def __new__(cls):
- Path(cls._texcache).mkdir(parents=True, exist_ok=True)
- return object.__new__(cls)
-
- @classmethod
- def _get_font_family_and_reduced(cls):
- """Return the font family name and whether the font is reduced."""
- ff = mpl.rcParams['font.family']
- ff_val = ff[0].lower() if len(ff) == 1 else None
- if len(ff) == 1 and ff_val in cls._font_families:
- return ff_val, False
- elif len(ff) == 1 and ff_val in cls._font_preambles:
- return cls._font_types[ff_val], True
- else:
- _log.info('font.family must be one of (%s) when text.usetex is '
- 'True. serif will be used by default.',
- ', '.join(cls._font_families))
- return 'serif', False
-
- @classmethod
- def _get_font_preamble_and_command(cls):
- requested_family, is_reduced_font = cls._get_font_family_and_reduced()
-
- preambles = {}
- for font_family in cls._font_families:
- if is_reduced_font and font_family == requested_family:
- preambles[font_family] = cls._font_preambles[
- mpl.rcParams['font.family'][0].lower()]
- else:
- for font in mpl.rcParams['font.' + font_family]:
- if font.lower() in cls._font_preambles:
- preambles[font_family] = \
- cls._font_preambles[font.lower()]
- _log.debug(
- 'family: %s, font: %s, info: %s',
- font_family, font,
- cls._font_preambles[font.lower()])
- break
- else:
- _log.debug('%s font is not compatible with usetex.',
- font)
- else:
- _log.info('No LaTeX-compatible font found for the %s font'
- 'family in rcParams. Using default.',
- font_family)
- preambles[font_family] = cls._font_preambles[font_family]
-
- # The following packages and commands need to be included in the latex
- # file's preamble:
- cmd = {preambles[family]
- for family in ['serif', 'sans-serif', 'monospace']}
- if requested_family == 'cursive':
- cmd.add(preambles['cursive'])
- cmd.add(r'\usepackage{type1cm}')
- preamble = '\n'.join(sorted(cmd))
- fontcmd = (r'\sffamily' if requested_family == 'sans-serif' else
- r'\ttfamily' if requested_family == 'monospace' else
- r'\rmfamily')
- return preamble, fontcmd
-
- @classmethod
- def get_basefile(cls, tex, fontsize, dpi=None):
- """
- Return a filename based on a hash of the string, fontsize, and dpi.
- """
- src = cls._get_tex_source(tex, fontsize) + str(dpi)
- filehash = hashlib.md5(src.encode('utf-8')).hexdigest()
- filepath = Path(cls._texcache)
-
- num_letters, num_levels = 2, 2
- for i in range(0, num_letters*num_levels, num_letters):
- filepath = filepath / Path(filehash[i:i+2])
-
- filepath.mkdir(parents=True, exist_ok=True)
- return os.path.join(filepath, filehash)
-
- @classmethod
- def get_font_preamble(cls):
- """
- Return a string containing font configuration for the tex preamble.
- """
- font_preamble, command = cls._get_font_preamble_and_command()
- return font_preamble
-
- @classmethod
- def get_custom_preamble(cls):
- """Return a string containing user additions to the tex preamble."""
- return mpl.rcParams['text.latex.preamble']
-
- @classmethod
- def _get_tex_source(cls, tex, fontsize):
- """Return the complete TeX source for processing a TeX string."""
- font_preamble, fontcmd = cls._get_font_preamble_and_command()
- baselineskip = 1.25 * fontsize
- return "\n".join([
- r"\documentclass{article}",
- r"% Pass-through \mathdefault, which is used in non-usetex mode",
- r"% to use the default text font but was historically suppressed",
- r"% in usetex mode.",
- r"\newcommand{\mathdefault}[1]{#1}",
- font_preamble,
- r"\usepackage[utf8]{inputenc}",
- r"\DeclareUnicodeCharacter{2212}{\ensuremath{-}}",
- r"% geometry is loaded before the custom preamble as ",
- r"% convert_psfrags relies on a custom preamble to change the ",
- r"% geometry.",
- r"\usepackage[papersize=72in, margin=1in]{geometry}",
- cls.get_custom_preamble(),
- r"% Use `underscore` package to take care of underscores in text.",
- r"% The [strings] option allows to use underscores in file names.",
- _usepackage_if_not_loaded("underscore", option="strings"),
- r"% Custom packages (e.g. newtxtext) may already have loaded ",
- r"% textcomp with different options.",
- _usepackage_if_not_loaded("textcomp"),
- r"\pagestyle{empty}",
- r"\begin{document}",
- r"% The empty hbox ensures that a page is printed even for empty",
- r"% inputs, except when using psfrag which gets confused by it.",
- r"% matplotlibbaselinemarker is used by dviread to detect the",
- r"% last line's baseline.",
- rf"\fontsize{{{fontsize}}}{{{baselineskip}}}%",
- r"\ifdefined\psfrag\else\hbox{}\fi%",
- rf"{{{fontcmd} {tex}}}%",
- r"\end{document}",
- ])
-
- @classmethod
- def make_tex(cls, tex, fontsize):
- """
- Generate a tex file to render the tex string at a specific font size.
-
- Return the file name.
- """
- texfile = cls.get_basefile(tex, fontsize) + ".tex"
- Path(texfile).write_text(cls._get_tex_source(tex, fontsize),
- encoding='utf-8')
- return texfile
-
- @classmethod
- def _run_checked_subprocess(cls, command, tex, *, cwd=None):
- _log.debug(cbook._pformat_subprocess(command))
- try:
- report = subprocess.check_output(
- command, cwd=cwd if cwd is not None else cls._texcache,
- stderr=subprocess.STDOUT)
- except FileNotFoundError as exc:
- raise RuntimeError(
- f'Failed to process string with tex because {command[0]} '
- 'could not be found') from exc
- except subprocess.CalledProcessError as exc:
- raise RuntimeError(
- '{prog} was not able to process the following string:\n'
- '{tex!r}\n\n'
- 'Here is the full command invocation and its output:\n\n'
- '{format_command}\n\n'
- '{exc}\n\n'.format(
- prog=command[0],
- format_command=cbook._pformat_subprocess(command),
- tex=tex.encode('unicode_escape'),
- exc=exc.output.decode('utf-8', 'backslashreplace'))
- ) from None
- _log.debug(report)
- return report
-
- @classmethod
- def make_dvi(cls, tex, fontsize):
- """
- Generate a dvi file containing latex's layout of tex string.
-
- Return the file name.
- """
- basefile = cls.get_basefile(tex, fontsize)
- dvifile = '%s.dvi' % basefile
- if not os.path.exists(dvifile):
- texfile = Path(cls.make_tex(tex, fontsize))
- # Generate the dvi in a temporary directory to avoid race
- # conditions e.g. if multiple processes try to process the same tex
- # string at the same time. Having tmpdir be a subdirectory of the
- # final output dir ensures that they are on the same filesystem,
- # and thus replace() works atomically. It also allows referring to
- # the texfile with a relative path (for pathological MPLCONFIGDIRs,
- # the absolute path may contain characters (e.g. ~) that TeX does
- # not support; n.b. relative paths cannot traverse parents, or it
- # will be blocked when `openin_any = p` in texmf.cnf).
- cwd = Path(dvifile).parent
- with TemporaryDirectory(dir=cwd) as tmpdir:
- tmppath = Path(tmpdir)
- cls._run_checked_subprocess(
- ["latex", "-interaction=nonstopmode", "--halt-on-error",
- f"--output-directory={tmppath.name}",
- f"{texfile.name}"], tex, cwd=cwd)
- (tmppath / Path(dvifile).name).replace(dvifile)
- return dvifile
-
- @classmethod
- def make_png(cls, tex, fontsize, dpi):
- """
- Generate a png file containing latex's rendering of tex string.
-
- Return the file name.
- """
- basefile = cls.get_basefile(tex, fontsize, dpi)
- pngfile = '%s.png' % basefile
- # see get_rgba for a discussion of the background
- if not os.path.exists(pngfile):
- dvifile = cls.make_dvi(tex, fontsize)
- cmd = ["dvipng", "-bg", "Transparent", "-D", str(dpi),
- "-T", "tight", "-o", pngfile, dvifile]
- # When testing, disable FreeType rendering for reproducibility; but
- # dvipng 1.16 has a bug (fixed in f3ff241) that breaks --freetype0
- # mode, so for it we keep FreeType enabled; the image will be
- # slightly off.
- if (getattr(mpl, "_called_from_pytest", False) and
- mpl._get_executable_info("dvipng").raw_version != "1.16"):
- cmd.insert(1, "--freetype0")
- cls._run_checked_subprocess(cmd, tex)
- return pngfile
-
- @classmethod
- def get_grey(cls, tex, fontsize=None, dpi=None):
- """Return the alpha channel."""
- if not fontsize:
- fontsize = mpl.rcParams['font.size']
- if not dpi:
- dpi = mpl.rcParams['savefig.dpi']
- key = cls._get_tex_source(tex, fontsize), dpi
- alpha = cls._grey_arrayd.get(key)
- if alpha is None:
- pngfile = cls.make_png(tex, fontsize, dpi)
- rgba = mpl.image.imread(os.path.join(cls._texcache, pngfile))
- cls._grey_arrayd[key] = alpha = rgba[:, :, -1]
- return alpha
-
- @classmethod
- def get_rgba(cls, tex, fontsize=None, dpi=None, rgb=(0, 0, 0)):
- r"""
- Return latex's rendering of the tex string as an RGBA array.
-
- Examples
- --------
- >>> texmanager = TexManager()
- >>> s = r"\TeX\ is $\displaystyle\sum_n\frac{-e^{i\pi}}{2^n}$!"
- >>> Z = texmanager.get_rgba(s, fontsize=12, dpi=80, rgb=(1, 0, 0))
- """
- alpha = cls.get_grey(tex, fontsize, dpi)
- rgba = np.empty((*alpha.shape, 4))
- rgba[..., :3] = mpl.colors.to_rgb(rgb)
- rgba[..., -1] = alpha
- return rgba
-
- @classmethod
- def get_text_width_height_descent(cls, tex, fontsize, renderer=None):
- """Return width, height and descent of the text."""
- if tex.strip() == '':
- return 0, 0, 0
- dvifile = cls.make_dvi(tex, fontsize)
- dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1
- with dviread.Dvi(dvifile, 72 * dpi_fraction) as dvi:
- page, = dvi
- # A total height (including the descent) needs to be returned.
- return page.width, page.height + page.descent, page.descent
diff --git a/contrib/python/matplotlib/py3/matplotlib/texmanager.pyi b/contrib/python/matplotlib/py3/matplotlib/texmanager.pyi
deleted file mode 100644
index 94f0d76fa8..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/texmanager.pyi
+++ /dev/null
@@ -1,38 +0,0 @@
-from .backend_bases import RendererBase
-
-from matplotlib.typing import ColorType
-
-import numpy as np
-
-class TexManager:
- texcache: str
- @classmethod
- def get_basefile(
- cls, tex: str, fontsize: float, dpi: float | None = ...
- ) -> str: ...
- @classmethod
- def get_font_preamble(cls) -> str: ...
- @classmethod
- def get_custom_preamble(cls) -> str: ...
- @classmethod
- def make_tex(cls, tex: str, fontsize: float) -> str: ...
- @classmethod
- def make_dvi(cls, tex: str, fontsize: float) -> str: ...
- @classmethod
- def make_png(cls, tex: str, fontsize: float, dpi: float) -> str: ...
- @classmethod
- def get_grey(
- cls, tex: str, fontsize: float | None = ..., dpi: float | None = ...
- ) -> np.ndarray: ...
- @classmethod
- def get_rgba(
- cls,
- tex: str,
- fontsize: float | None = ...,
- dpi: float | None = ...,
- rgb: ColorType = ...,
- ) -> np.ndarray: ...
- @classmethod
- def get_text_width_height_descent(
- cls, tex: str, fontsize, renderer: RendererBase | None = ...
- ) -> tuple[int, int, int]: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/text.py b/contrib/python/matplotlib/py3/matplotlib/text.py
deleted file mode 100644
index 7a58ce7172..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/text.py
+++ /dev/null
@@ -1,2023 +0,0 @@
-"""
-Classes for including text in a figure.
-"""
-
-import functools
-import logging
-import math
-from numbers import Real
-import weakref
-
-import numpy as np
-
-import matplotlib as mpl
-from . import _api, artist, cbook, _docstring
-from .artist import Artist
-from .font_manager import FontProperties
-from .patches import FancyArrowPatch, FancyBboxPatch, Rectangle
-from .textpath import TextPath, TextToPath # noqa # Logically located here
-from .transforms import (
- Affine2D, Bbox, BboxBase, BboxTransformTo, IdentityTransform, Transform)
-
-
-_log = logging.getLogger(__name__)
-
-
-def _get_textbox(text, renderer):
- """
- Calculate the bounding box of the text.
-
- The bbox position takes text rotation into account, but the width and
- height are those of the unrotated box (unlike `.Text.get_window_extent`).
- """
- # TODO : This function may move into the Text class as a method. As a
- # matter of fact, the information from the _get_textbox function
- # should be available during the Text._get_layout() call, which is
- # called within the _get_textbox. So, it would better to move this
- # function as a method with some refactoring of _get_layout method.
-
- projected_xs = []
- projected_ys = []
-
- theta = np.deg2rad(text.get_rotation())
- tr = Affine2D().rotate(-theta)
-
- _, parts, d = text._get_layout(renderer)
-
- for t, wh, x, y in parts:
- w, h = wh
-
- xt1, yt1 = tr.transform((x, y))
- yt1 -= d
- xt2, yt2 = xt1 + w, yt1 + h
-
- projected_xs.extend([xt1, xt2])
- projected_ys.extend([yt1, yt2])
-
- xt_box, yt_box = min(projected_xs), min(projected_ys)
- w_box, h_box = max(projected_xs) - xt_box, max(projected_ys) - yt_box
-
- x_box, y_box = Affine2D().rotate(theta).transform((xt_box, yt_box))
-
- return x_box, y_box, w_box, h_box
-
-
-def _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi):
- """Call ``renderer.get_text_width_height_descent``, caching the results."""
- # Cached based on a copy of fontprop so that later in-place mutations of
- # the passed-in argument do not mess up the cache.
- return _get_text_metrics_with_cache_impl(
- weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)
-
-
-@functools.lru_cache(4096)
-def _get_text_metrics_with_cache_impl(
- renderer_ref, text, fontprop, ismath, dpi):
- # dpi is unused, but participates in cache invalidation (via the renderer).
- return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)
-
-
-@_docstring.interpd
-@_api.define_aliases({
- "color": ["c"],
- "fontfamily": ["family"],
- "fontproperties": ["font", "font_properties"],
- "horizontalalignment": ["ha"],
- "multialignment": ["ma"],
- "fontname": ["name"],
- "fontsize": ["size"],
- "fontstretch": ["stretch"],
- "fontstyle": ["style"],
- "fontvariant": ["variant"],
- "verticalalignment": ["va"],
- "fontweight": ["weight"],
-})
-class Text(Artist):
- """Handle storing and drawing of text in window or data coordinates."""
-
- zorder = 3
- _charsize_cache = dict()
-
- def __repr__(self):
- return f"Text({self._x}, {self._y}, {self._text!r})"
-
- def __init__(self,
- x=0, y=0, text='', *,
- color=None, # defaults to rc params
- verticalalignment='baseline',
- horizontalalignment='left',
- multialignment=None,
- fontproperties=None, # defaults to FontProperties()
- rotation=None,
- linespacing=None,
- rotation_mode=None,
- usetex=None, # defaults to rcParams['text.usetex']
- wrap=False,
- transform_rotates_text=False,
- parse_math=None, # defaults to rcParams['text.parse_math']
- antialiased=None, # defaults to rcParams['text.antialiased']
- **kwargs
- ):
- """
- Create a `.Text` instance at *x*, *y* with string *text*.
-
- The text is aligned relative to the anchor point (*x*, *y*) according
- to ``horizontalalignment`` (default: 'left') and ``verticalalignment``
- (default: 'bottom'). See also
- :doc:`/gallery/text_labels_and_annotations/text_alignment`.
-
- While Text accepts the 'label' keyword argument, by default it is not
- added to the handles of a legend.
-
- Valid keyword arguments are:
-
- %(Text:kwdoc)s
- """
- super().__init__()
- self._x, self._y = x, y
- self._text = ''
- self._reset_visual_defaults(
- text=text,
- color=color,
- fontproperties=fontproperties,
- usetex=usetex,
- parse_math=parse_math,
- wrap=wrap,
- verticalalignment=verticalalignment,
- horizontalalignment=horizontalalignment,
- multialignment=multialignment,
- rotation=rotation,
- transform_rotates_text=transform_rotates_text,
- linespacing=linespacing,
- rotation_mode=rotation_mode,
- antialiased=antialiased
- )
- self.update(kwargs)
-
- def _reset_visual_defaults(
- self,
- text='',
- color=None,
- fontproperties=None,
- usetex=None,
- parse_math=None,
- wrap=False,
- verticalalignment='baseline',
- horizontalalignment='left',
- multialignment=None,
- rotation=None,
- transform_rotates_text=False,
- linespacing=None,
- rotation_mode=None,
- antialiased=None
- ):
- self.set_text(text)
- self.set_color(mpl._val_or_rc(color, "text.color"))
- self.set_fontproperties(fontproperties)
- self.set_usetex(usetex)
- self.set_parse_math(mpl._val_or_rc(parse_math, 'text.parse_math'))
- self.set_wrap(wrap)
- self.set_verticalalignment(verticalalignment)
- self.set_horizontalalignment(horizontalalignment)
- self._multialignment = multialignment
- self.set_rotation(rotation)
- self._transform_rotates_text = transform_rotates_text
- self._bbox_patch = None # a FancyBboxPatch instance
- self._renderer = None
- if linespacing is None:
- linespacing = 1.2 # Maybe use rcParam later.
- self.set_linespacing(linespacing)
- self.set_rotation_mode(rotation_mode)
- self.set_antialiased(antialiased if antialiased is not None else
- mpl.rcParams['text.antialiased'])
-
- def update(self, kwargs):
- # docstring inherited
- ret = []
- kwargs = cbook.normalize_kwargs(kwargs, Text)
- sentinel = object() # bbox can be None, so use another sentinel.
- # Update fontproperties first, as it has lowest priority.
- fontproperties = kwargs.pop("fontproperties", sentinel)
- if fontproperties is not sentinel:
- ret.append(self.set_fontproperties(fontproperties))
- # Update bbox last, as it depends on font properties.
- bbox = kwargs.pop("bbox", sentinel)
- ret.extend(super().update(kwargs))
- if bbox is not sentinel:
- ret.append(self.set_bbox(bbox))
- return ret
-
- def __getstate__(self):
- d = super().__getstate__()
- # remove the cached _renderer (if it exists)
- d['_renderer'] = None
- return d
-
- def contains(self, mouseevent):
- """
- Return whether the mouse event occurred inside the axis-aligned
- bounding-box of the text.
- """
- if (self._different_canvas(mouseevent) or not self.get_visible()
- or self._renderer is None):
- return False, {}
- # Explicitly use Text.get_window_extent(self) and not
- # self.get_window_extent() so that Annotation.contains does not
- # accidentally cover the entire annotation bounding box.
- bbox = Text.get_window_extent(self)
- inside = (bbox.x0 <= mouseevent.x <= bbox.x1
- and bbox.y0 <= mouseevent.y <= bbox.y1)
- cattr = {}
- # if the text has a surrounding patch, also check containment for it,
- # and merge the results with the results for the text.
- if self._bbox_patch:
- patch_inside, patch_cattr = self._bbox_patch.contains(mouseevent)
- inside = inside or patch_inside
- cattr["bbox_patch"] = patch_cattr
- return inside, cattr
-
- def _get_xy_display(self):
- """
- Get the (possibly unit converted) transformed x, y in display coords.
- """
- x, y = self.get_unitless_position()
- return self.get_transform().transform((x, y))
-
- def _get_multialignment(self):
- if self._multialignment is not None:
- return self._multialignment
- else:
- return self._horizontalalignment
-
- def _char_index_at(self, x):
- """
- Calculate the index closest to the coordinate x in display space.
-
- The position of text[index] is assumed to be the sum of the widths
- of all preceding characters text[:index].
-
- This works only on single line texts.
- """
- if not self._text:
- return 0
-
- text = self._text
-
- fontproperties = str(self._fontproperties)
- if fontproperties not in Text._charsize_cache:
- Text._charsize_cache[fontproperties] = dict()
-
- charsize_cache = Text._charsize_cache[fontproperties]
- for char in set(text):
- if char not in charsize_cache:
- self.set_text(char)
- bb = self.get_window_extent()
- charsize_cache[char] = bb.x1 - bb.x0
-
- self.set_text(text)
- bb = self.get_window_extent()
-
- size_accum = np.cumsum([0] + [charsize_cache[x] for x in text])
- std_x = x - bb.x0
- return (np.abs(size_accum - std_x)).argmin()
-
- def get_rotation(self):
- """Return the text angle in degrees between 0 and 360."""
- if self.get_transform_rotates_text():
- return self.get_transform().transform_angles(
- [self._rotation], [self.get_unitless_position()]).item(0)
- else:
- return self._rotation
-
- def get_transform_rotates_text(self):
- """
- Return whether rotations of the transform affect the text direction.
- """
- return self._transform_rotates_text
-
- def set_rotation_mode(self, m):
- """
- Set text rotation mode.
-
- Parameters
- ----------
- m : {None, 'default', 'anchor'}
- If ``"default"``, the text will be first rotated, then aligned according
- to their horizontal and vertical alignments. If ``"anchor"``, then
- alignment occurs before rotation. Passing ``None`` will set the rotation
- mode to ``"default"``.
- """
- if m is None:
- m = "default"
- else:
- _api.check_in_list(("anchor", "default"), rotation_mode=m)
- self._rotation_mode = m
- self.stale = True
-
- def get_rotation_mode(self):
- """Return the text rotation mode."""
- return self._rotation_mode
-
- def set_antialiased(self, antialiased):
- """
- Set whether to use antialiased rendering.
-
- Parameters
- ----------
- antialiased : bool
-
- Notes
- -----
- Antialiasing will be determined by :rc:`text.antialiased`
- and the parameter *antialiased* will have no effect if the text contains
- math expressions.
- """
- self._antialiased = antialiased
- self.stale = True
-
- def get_antialiased(self):
- """Return whether antialiased rendering is used."""
- return self._antialiased
-
- def update_from(self, other):
- # docstring inherited
- super().update_from(other)
- self._color = other._color
- self._multialignment = other._multialignment
- self._verticalalignment = other._verticalalignment
- self._horizontalalignment = other._horizontalalignment
- self._fontproperties = other._fontproperties.copy()
- self._usetex = other._usetex
- self._rotation = other._rotation
- self._transform_rotates_text = other._transform_rotates_text
- self._picker = other._picker
- self._linespacing = other._linespacing
- self._antialiased = other._antialiased
- self.stale = True
-
- def _get_layout(self, renderer):
- """
- Return the extent (bbox) of the text together with
- multiple-alignment information. Note that it returns an extent
- of a rotated text when necessary.
- """
- thisx, thisy = 0.0, 0.0
- lines = self._get_wrapped_text().split("\n") # Ensures lines is not empty.
-
- ws = []
- hs = []
- xs = []
- ys = []
-
- # Full vertical extent of font, including ascenders and descenders:
- _, lp_h, lp_d = _get_text_metrics_with_cache(
- renderer, "lp", self._fontproperties,
- ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
- min_dy = (lp_h - lp_d) * self._linespacing
-
- for i, line in enumerate(lines):
- clean_line, ismath = self._preprocess_math(line)
- if clean_line:
- w, h, d = _get_text_metrics_with_cache(
- renderer, clean_line, self._fontproperties,
- ismath=ismath, dpi=self.figure.dpi)
- else:
- w = h = d = 0
-
- # For multiline text, increase the line spacing when the text
- # net-height (excluding baseline) is larger than that of a "l"
- # (e.g., use of superscripts), which seems what TeX does.
- h = max(h, lp_h)
- d = max(d, lp_d)
-
- ws.append(w)
- hs.append(h)
-
- # Metrics of the last line that are needed later:
- baseline = (h - d) - thisy
-
- if i == 0:
- # position at baseline
- thisy = -(h - d)
- else:
- # put baseline a good distance from bottom of previous line
- thisy -= max(min_dy, (h - d) * self._linespacing)
-
- xs.append(thisx) # == 0.
- ys.append(thisy)
-
- thisy -= d
-
- # Metrics of the last line that are needed later:
- descent = d
-
- # Bounding box definition:
- width = max(ws)
- xmin = 0
- xmax = width
- ymax = 0
- ymin = ys[-1] - descent # baseline of last line minus its descent
-
- # get the rotation matrix
- M = Affine2D().rotate_deg(self.get_rotation())
-
- # now offset the individual text lines within the box
- malign = self._get_multialignment()
- if malign == 'left':
- offset_layout = [(x, y) for x, y in zip(xs, ys)]
- elif malign == 'center':
- offset_layout = [(x + width / 2 - w / 2, y)
- for x, y, w in zip(xs, ys, ws)]
- elif malign == 'right':
- offset_layout = [(x + width - w, y)
- for x, y, w in zip(xs, ys, ws)]
-
- # the corners of the unrotated bounding box
- corners_horiz = np.array(
- [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)])
-
- # now rotate the bbox
- corners_rotated = M.transform(corners_horiz)
- # compute the bounds of the rotated box
- xmin = corners_rotated[:, 0].min()
- xmax = corners_rotated[:, 0].max()
- ymin = corners_rotated[:, 1].min()
- ymax = corners_rotated[:, 1].max()
- width = xmax - xmin
- height = ymax - ymin
-
- # Now move the box to the target position offset the display
- # bbox by alignment
- halign = self._horizontalalignment
- valign = self._verticalalignment
-
- rotation_mode = self.get_rotation_mode()
- if rotation_mode != "anchor":
- # compute the text location in display coords and the offsets
- # necessary to align the bbox with that location
- if halign == 'center':
- offsetx = (xmin + xmax) / 2
- elif halign == 'right':
- offsetx = xmax
- else:
- offsetx = xmin
-
- if valign == 'center':
- offsety = (ymin + ymax) / 2
- elif valign == 'top':
- offsety = ymax
- elif valign == 'baseline':
- offsety = ymin + descent
- elif valign == 'center_baseline':
- offsety = ymin + height - baseline / 2.0
- else:
- offsety = ymin
- else:
- xmin1, ymin1 = corners_horiz[0]
- xmax1, ymax1 = corners_horiz[2]
-
- if halign == 'center':
- offsetx = (xmin1 + xmax1) / 2.0
- elif halign == 'right':
- offsetx = xmax1
- else:
- offsetx = xmin1
-
- if valign == 'center':
- offsety = (ymin1 + ymax1) / 2.0
- elif valign == 'top':
- offsety = ymax1
- elif valign == 'baseline':
- offsety = ymax1 - baseline
- elif valign == 'center_baseline':
- offsety = ymax1 - baseline / 2.0
- else:
- offsety = ymin1
-
- offsetx, offsety = M.transform((offsetx, offsety))
-
- xmin -= offsetx
- ymin -= offsety
-
- bbox = Bbox.from_bounds(xmin, ymin, width, height)
-
- # now rotate the positions around the first (x, y) position
- xys = M.transform(offset_layout) - (offsetx, offsety)
-
- return bbox, list(zip(lines, zip(ws, hs), *xys.T)), descent
-
- def set_bbox(self, rectprops):
- """
- Draw a bounding box around self.
-
- Parameters
- ----------
- rectprops : dict with properties for `.patches.FancyBboxPatch`
- The default boxstyle is 'square'. The mutation
- scale of the `.patches.FancyBboxPatch` is set to the fontsize.
-
- Examples
- --------
- ::
-
- t.set_bbox(dict(facecolor='red', alpha=0.5))
- """
-
- if rectprops is not None:
- props = rectprops.copy()
- boxstyle = props.pop("boxstyle", None)
- pad = props.pop("pad", None)
- if boxstyle is None:
- boxstyle = "square"
- if pad is None:
- pad = 4 # points
- pad /= self.get_size() # to fraction of font size
- else:
- if pad is None:
- pad = 0.3
- # boxstyle could be a callable or a string
- if isinstance(boxstyle, str) and "pad" not in boxstyle:
- boxstyle += ",pad=%0.2f" % pad
- self._bbox_patch = FancyBboxPatch(
- (0, 0), 1, 1,
- boxstyle=boxstyle, transform=IdentityTransform(), **props)
- else:
- self._bbox_patch = None
-
- self._update_clip_properties()
-
- def get_bbox_patch(self):
- """
- Return the bbox Patch, or None if the `.patches.FancyBboxPatch`
- is not made.
- """
- return self._bbox_patch
-
- def update_bbox_position_size(self, renderer):
- """
- Update the location and the size of the bbox.
-
- This method should be used when the position and size of the bbox needs
- to be updated before actually drawing the bbox.
- """
- if self._bbox_patch:
- # don't use self.get_unitless_position here, which refers to text
- # position in Text:
- posx = float(self.convert_xunits(self._x))
- posy = float(self.convert_yunits(self._y))
- posx, posy = self.get_transform().transform((posx, posy))
-
- x_box, y_box, w_box, h_box = _get_textbox(self, renderer)
- self._bbox_patch.set_bounds(0., 0., w_box, h_box)
- self._bbox_patch.set_transform(
- Affine2D()
- .rotate_deg(self.get_rotation())
- .translate(posx + x_box, posy + y_box))
- fontsize_in_pixel = renderer.points_to_pixels(self.get_size())
- self._bbox_patch.set_mutation_scale(fontsize_in_pixel)
-
- def _update_clip_properties(self):
- if self._bbox_patch:
- clipprops = dict(clip_box=self.clipbox,
- clip_path=self._clippath,
- clip_on=self._clipon)
- self._bbox_patch.update(clipprops)
-
- def set_clip_box(self, clipbox):
- # docstring inherited.
- super().set_clip_box(clipbox)
- self._update_clip_properties()
-
- def set_clip_path(self, path, transform=None):
- # docstring inherited.
- super().set_clip_path(path, transform)
- self._update_clip_properties()
-
- def set_clip_on(self, b):
- # docstring inherited.
- super().set_clip_on(b)
- self._update_clip_properties()
-
- def get_wrap(self):
- """Return whether the text can be wrapped."""
- return self._wrap
-
- def set_wrap(self, wrap):
- """
- Set whether the text can be wrapped.
-
- Parameters
- ----------
- wrap : bool
-
- Notes
- -----
- Wrapping does not work together with
- ``savefig(..., bbox_inches='tight')`` (which is also used internally
- by ``%matplotlib inline`` in IPython/Jupyter). The 'tight' setting
- rescales the canvas to accommodate all content and happens before
- wrapping.
- """
- self._wrap = wrap
-
- def _get_wrap_line_width(self):
- """
- Return the maximum line width for wrapping text based on the current
- orientation.
- """
- x0, y0 = self.get_transform().transform(self.get_position())
- figure_box = self.get_figure().get_window_extent()
-
- # Calculate available width based on text alignment
- alignment = self.get_horizontalalignment()
- self.set_rotation_mode('anchor')
- rotation = self.get_rotation()
-
- left = self._get_dist_to_box(rotation, x0, y0, figure_box)
- right = self._get_dist_to_box(
- (180 + rotation) % 360, x0, y0, figure_box)
-
- if alignment == 'left':
- line_width = left
- elif alignment == 'right':
- line_width = right
- else:
- line_width = 2 * min(left, right)
-
- return line_width
-
- def _get_dist_to_box(self, rotation, x0, y0, figure_box):
- """
- Return the distance from the given points to the boundaries of a
- rotated box, in pixels.
- """
- if rotation > 270:
- quad = rotation - 270
- h1 = y0 / math.cos(math.radians(quad))
- h2 = (figure_box.x1 - x0) / math.cos(math.radians(90 - quad))
- elif rotation > 180:
- quad = rotation - 180
- h1 = x0 / math.cos(math.radians(quad))
- h2 = y0 / math.cos(math.radians(90 - quad))
- elif rotation > 90:
- quad = rotation - 90
- h1 = (figure_box.y1 - y0) / math.cos(math.radians(quad))
- h2 = x0 / math.cos(math.radians(90 - quad))
- else:
- h1 = (figure_box.x1 - x0) / math.cos(math.radians(rotation))
- h2 = (figure_box.y1 - y0) / math.cos(math.radians(90 - rotation))
-
- return min(h1, h2)
-
- def _get_rendered_text_width(self, text):
- """
- Return the width of a given text string, in pixels.
- """
-
- w, h, d = self._renderer.get_text_width_height_descent(
- text,
- self.get_fontproperties(),
- cbook.is_math_text(text))
- return math.ceil(w)
-
- def _get_wrapped_text(self):
- """
- Return a copy of the text string with new lines added so that the text
- is wrapped relative to the parent figure (if `get_wrap` is True).
- """
- if not self.get_wrap():
- return self.get_text()
-
- # Not fit to handle breaking up latex syntax correctly, so
- # ignore latex for now.
- if self.get_usetex():
- return self.get_text()
-
- # Build the line incrementally, for a more accurate measure of length
- line_width = self._get_wrap_line_width()
- wrapped_lines = []
-
- # New lines in the user's text force a split
- unwrapped_lines = self.get_text().split('\n')
-
- # Now wrap each individual unwrapped line
- for unwrapped_line in unwrapped_lines:
-
- sub_words = unwrapped_line.split(' ')
- # Remove items from sub_words as we go, so stop when empty
- while len(sub_words) > 0:
- if len(sub_words) == 1:
- # Only one word, so just add it to the end
- wrapped_lines.append(sub_words.pop(0))
- continue
-
- for i in range(2, len(sub_words) + 1):
- # Get width of all words up to and including here
- line = ' '.join(sub_words[:i])
- current_width = self._get_rendered_text_width(line)
-
- # If all these words are too wide, append all not including
- # last word
- if current_width > line_width:
- wrapped_lines.append(' '.join(sub_words[:i - 1]))
- sub_words = sub_words[i - 1:]
- break
-
- # Otherwise if all words fit in the width, append them all
- elif i == len(sub_words):
- wrapped_lines.append(' '.join(sub_words[:i]))
- sub_words = []
- break
-
- return '\n'.join(wrapped_lines)
-
- @artist.allow_rasterization
- def draw(self, renderer):
- # docstring inherited
-
- if renderer is not None:
- self._renderer = renderer
- if not self.get_visible():
- return
- if self.get_text() == '':
- return
-
- renderer.open_group('text', self.get_gid())
-
- with self._cm_set(text=self._get_wrapped_text()):
- bbox, info, descent = self._get_layout(renderer)
- trans = self.get_transform()
-
- # don't use self.get_position here, which refers to text
- # position in Text:
- posx = float(self.convert_xunits(self._x))
- posy = float(self.convert_yunits(self._y))
- posx, posy = trans.transform((posx, posy))
- if not np.isfinite(posx) or not np.isfinite(posy):
- _log.warning("posx and posy should be finite values")
- return
- canvasw, canvash = renderer.get_canvas_width_height()
-
- # Update the location and size of the bbox
- # (`.patches.FancyBboxPatch`), and draw it.
- if self._bbox_patch:
- self.update_bbox_position_size(renderer)
- self._bbox_patch.draw(renderer)
-
- gc = renderer.new_gc()
- gc.set_foreground(self.get_color())
- gc.set_alpha(self.get_alpha())
- gc.set_url(self._url)
- gc.set_antialiased(self._antialiased)
- self._set_gc_clip(gc)
-
- angle = self.get_rotation()
-
- for line, wh, x, y in info:
-
- mtext = self if len(info) == 1 else None
- x = x + posx
- y = y + posy
- if renderer.flipy():
- y = canvash - y
- clean_line, ismath = self._preprocess_math(line)
-
- if self.get_path_effects():
- from matplotlib.patheffects import PathEffectRenderer
- textrenderer = PathEffectRenderer(
- self.get_path_effects(), renderer)
- else:
- textrenderer = renderer
-
- if self.get_usetex():
- textrenderer.draw_tex(gc, x, y, clean_line,
- self._fontproperties, angle,
- mtext=mtext)
- else:
- textrenderer.draw_text(gc, x, y, clean_line,
- self._fontproperties, angle,
- ismath=ismath, mtext=mtext)
-
- gc.restore()
- renderer.close_group('text')
- self.stale = False
-
- def get_color(self):
- """Return the color of the text."""
- return self._color
-
- def get_fontproperties(self):
- """Return the `.font_manager.FontProperties`."""
- return self._fontproperties
-
- def get_fontfamily(self):
- """
- Return the list of font families used for font lookup.
-
- See Also
- --------
- .font_manager.FontProperties.get_family
- """
- return self._fontproperties.get_family()
-
- def get_fontname(self):
- """
- Return the font name as a string.
-
- See Also
- --------
- .font_manager.FontProperties.get_name
- """
- return self._fontproperties.get_name()
-
- def get_fontstyle(self):
- """
- Return the font style as a string.
-
- See Also
- --------
- .font_manager.FontProperties.get_style
- """
- return self._fontproperties.get_style()
-
- def get_fontsize(self):
- """
- Return the font size as an integer.
-
- See Also
- --------
- .font_manager.FontProperties.get_size_in_points
- """
- return self._fontproperties.get_size_in_points()
-
- def get_fontvariant(self):
- """
- Return the font variant as a string.
-
- See Also
- --------
- .font_manager.FontProperties.get_variant
- """
- return self._fontproperties.get_variant()
-
- def get_fontweight(self):
- """
- Return the font weight as a string or a number.
-
- See Also
- --------
- .font_manager.FontProperties.get_weight
- """
- return self._fontproperties.get_weight()
-
- def get_stretch(self):
- """
- Return the font stretch as a string or a number.
-
- See Also
- --------
- .font_manager.FontProperties.get_stretch
- """
- return self._fontproperties.get_stretch()
-
- def get_horizontalalignment(self):
- """
- Return the horizontal alignment as a string. Will be one of
- 'left', 'center' or 'right'.
- """
- return self._horizontalalignment
-
- def get_unitless_position(self):
- """Return the (x, y) unitless position of the text."""
- # This will get the position with all unit information stripped away.
- # This is here for convenience since it is done in several locations.
- x = float(self.convert_xunits(self._x))
- y = float(self.convert_yunits(self._y))
- return x, y
-
- def get_position(self):
- """Return the (x, y) position of the text."""
- # This should return the same data (possible unitized) as was
- # specified with 'set_x' and 'set_y'.
- return self._x, self._y
-
- def get_text(self):
- """Return the text string."""
- return self._text
-
- def get_verticalalignment(self):
- """
- Return the vertical alignment as a string. Will be one of
- 'top', 'center', 'bottom', 'baseline' or 'center_baseline'.
- """
- return self._verticalalignment
-
- def get_window_extent(self, renderer=None, dpi=None):
- """
- Return the `.Bbox` bounding the text, in display units.
-
- In addition to being used internally, this is useful for specifying
- clickable regions in a png file on a web page.
-
- Parameters
- ----------
- renderer : Renderer, optional
- A renderer is needed to compute the bounding box. If the artist
- has already been drawn, the renderer is cached; thus, it is only
- necessary to pass this argument when calling `get_window_extent`
- before the first draw. In practice, it is usually easier to
- trigger a draw first, e.g. by calling
- `~.Figure.draw_without_rendering` or ``plt.show()``.
-
- dpi : float, optional
- The dpi value for computing the bbox, defaults to
- ``self.figure.dpi`` (*not* the renderer dpi); should be set e.g. if
- to match regions with a figure saved with a custom dpi value.
- """
- if not self.get_visible():
- return Bbox.unit()
- if dpi is None:
- dpi = self.figure.dpi
- if self.get_text() == '':
- with cbook._setattr_cm(self.figure, dpi=dpi):
- tx, ty = self._get_xy_display()
- return Bbox.from_bounds(tx, ty, 0, 0)
-
- if renderer is not None:
- self._renderer = renderer
- if self._renderer is None:
- self._renderer = self.figure._get_renderer()
- if self._renderer is None:
- raise RuntimeError(
- "Cannot get window extent of text w/o renderer. You likely "
- "want to call 'figure.draw_without_rendering()' first.")
-
- with cbook._setattr_cm(self.figure, dpi=dpi):
- bbox, info, descent = self._get_layout(self._renderer)
- x, y = self.get_unitless_position()
- x, y = self.get_transform().transform((x, y))
- bbox = bbox.translated(x, y)
- return bbox
-
- def set_backgroundcolor(self, color):
- """
- Set the background color of the text by updating the bbox.
-
- Parameters
- ----------
- color : color
-
- See Also
- --------
- .set_bbox : To change the position of the bounding box
- """
- if self._bbox_patch is None:
- self.set_bbox(dict(facecolor=color, edgecolor=color))
- else:
- self._bbox_patch.update(dict(facecolor=color))
-
- self._update_clip_properties()
- self.stale = True
-
- def set_color(self, color):
- """
- Set the foreground color of the text
-
- Parameters
- ----------
- color : color
- """
- # "auto" is only supported by axisartist, but we can just let it error
- # out at draw time for simplicity.
- if not cbook._str_equal(color, "auto"):
- mpl.colors._check_color_like(color=color)
- self._color = color
- self.stale = True
-
- def set_horizontalalignment(self, align):
- """
- Set the horizontal alignment relative to the anchor point.
-
- See also :doc:`/gallery/text_labels_and_annotations/text_alignment`.
-
- Parameters
- ----------
- align : {'left', 'center', 'right'}
- """
- _api.check_in_list(['center', 'right', 'left'], align=align)
- self._horizontalalignment = align
- self.stale = True
-
- def set_multialignment(self, align):
- """
- Set the text alignment for multiline texts.
-
- The layout of the bounding box of all the lines is determined by the
- horizontalalignment and verticalalignment properties. This property
- controls the alignment of the text lines within that box.
-
- Parameters
- ----------
- align : {'left', 'right', 'center'}
- """
- _api.check_in_list(['center', 'right', 'left'], align=align)
- self._multialignment = align
- self.stale = True
-
- def set_linespacing(self, spacing):
- """
- Set the line spacing as a multiple of the font size.
-
- The default line spacing is 1.2.
-
- Parameters
- ----------
- spacing : float (multiple of font size)
- """
- _api.check_isinstance(Real, spacing=spacing)
- self._linespacing = spacing
- self.stale = True
-
- def set_fontfamily(self, fontname):
- """
- Set the font family. Can be either a single string, or a list of
- strings in decreasing priority. Each string may be either a real font
- name or a generic font class name. If the latter, the specific font
- names will be looked up in the corresponding rcParams.
-
- If a `Text` instance is constructed with ``fontfamily=None``, then the
- font is set to :rc:`font.family`, and the
- same is done when `set_fontfamily()` is called on an existing
- `Text` instance.
-
- Parameters
- ----------
- fontname : {FONTNAME, 'serif', 'sans-serif', 'cursive', 'fantasy', \
-'monospace'}
-
- See Also
- --------
- .font_manager.FontProperties.set_family
- """
- self._fontproperties.set_family(fontname)
- self.stale = True
-
- def set_fontvariant(self, variant):
- """
- Set the font variant.
-
- Parameters
- ----------
- variant : {'normal', 'small-caps'}
-
- See Also
- --------
- .font_manager.FontProperties.set_variant
- """
- self._fontproperties.set_variant(variant)
- self.stale = True
-
- def set_fontstyle(self, fontstyle):
- """
- Set the font style.
-
- Parameters
- ----------
- fontstyle : {'normal', 'italic', 'oblique'}
-
- See Also
- --------
- .font_manager.FontProperties.set_style
- """
- self._fontproperties.set_style(fontstyle)
- self.stale = True
-
- def set_fontsize(self, fontsize):
- """
- Set the font size.
-
- Parameters
- ----------
- fontsize : float or {'xx-small', 'x-small', 'small', 'medium', \
-'large', 'x-large', 'xx-large'}
- If a float, the fontsize in points. The string values denote sizes
- relative to the default font size.
-
- See Also
- --------
- .font_manager.FontProperties.set_size
- """
- self._fontproperties.set_size(fontsize)
- self.stale = True
-
- def get_math_fontfamily(self):
- """
- Return the font family name for math text rendered by Matplotlib.
-
- The default value is :rc:`mathtext.fontset`.
-
- See Also
- --------
- set_math_fontfamily
- """
- return self._fontproperties.get_math_fontfamily()
-
- def set_math_fontfamily(self, fontfamily):
- """
- Set the font family for math text rendered by Matplotlib.
-
- This does only affect Matplotlib's own math renderer. It has no effect
- when rendering with TeX (``usetex=True``).
-
- Parameters
- ----------
- fontfamily : str
- The name of the font family.
-
- Available font families are defined in the
- :ref:`default matplotlibrc file
- <customizing-with-matplotlibrc-files>`.
-
- See Also
- --------
- get_math_fontfamily
- """
- self._fontproperties.set_math_fontfamily(fontfamily)
-
- def set_fontweight(self, weight):
- """
- Set the font weight.
-
- Parameters
- ----------
- weight : {a numeric value in range 0-1000, 'ultralight', 'light', \
-'normal', 'regular', 'book', 'medium', 'roman', 'semibold', 'demibold', \
-'demi', 'bold', 'heavy', 'extra bold', 'black'}
-
- See Also
- --------
- .font_manager.FontProperties.set_weight
- """
- self._fontproperties.set_weight(weight)
- self.stale = True
-
- def set_fontstretch(self, stretch):
- """
- Set the font stretch (horizontal condensation or expansion).
-
- Parameters
- ----------
- stretch : {a numeric value in range 0-1000, 'ultra-condensed', \
-'extra-condensed', 'condensed', 'semi-condensed', 'normal', 'semi-expanded', \
-'expanded', 'extra-expanded', 'ultra-expanded'}
-
- See Also
- --------
- .font_manager.FontProperties.set_stretch
- """
- self._fontproperties.set_stretch(stretch)
- self.stale = True
-
- def set_position(self, xy):
- """
- Set the (*x*, *y*) position of the text.
-
- Parameters
- ----------
- xy : (float, float)
- """
- self.set_x(xy[0])
- self.set_y(xy[1])
-
- def set_x(self, x):
- """
- Set the *x* position of the text.
-
- Parameters
- ----------
- x : float
- """
- self._x = x
- self.stale = True
-
- def set_y(self, y):
- """
- Set the *y* position of the text.
-
- Parameters
- ----------
- y : float
- """
- self._y = y
- self.stale = True
-
- def set_rotation(self, s):
- """
- Set the rotation of the text.
-
- Parameters
- ----------
- s : float or {'vertical', 'horizontal'}
- The rotation angle in degrees in mathematically positive direction
- (counterclockwise). 'horizontal' equals 0, 'vertical' equals 90.
- """
- if isinstance(s, Real):
- self._rotation = float(s) % 360
- elif cbook._str_equal(s, 'horizontal') or s is None:
- self._rotation = 0.
- elif cbook._str_equal(s, 'vertical'):
- self._rotation = 90.
- else:
- raise ValueError("rotation must be 'vertical', 'horizontal' or "
- f"a number, not {s}")
- self.stale = True
-
- def set_transform_rotates_text(self, t):
- """
- Whether rotations of the transform affect the text direction.
-
- Parameters
- ----------
- t : bool
- """
- self._transform_rotates_text = t
- self.stale = True
-
- def set_verticalalignment(self, align):
- """
- Set the vertical alignment relative to the anchor point.
-
- See also :doc:`/gallery/text_labels_and_annotations/text_alignment`.
-
- Parameters
- ----------
- align : {'bottom', 'baseline', 'center', 'center_baseline', 'top'}
- """
- _api.check_in_list(
- ['top', 'bottom', 'center', 'baseline', 'center_baseline'],
- align=align)
- self._verticalalignment = align
- self.stale = True
-
- def set_text(self, s):
- r"""
- Set the text string *s*.
-
- It may contain newlines (``\n``) or math in LaTeX syntax.
-
- Parameters
- ----------
- s : object
- Any object gets converted to its `str` representation, except for
- ``None`` which is converted to an empty string.
- """
- s = '' if s is None else str(s)
- if s != self._text:
- self._text = s
- self.stale = True
-
- def _preprocess_math(self, s):
- """
- Return the string *s* after mathtext preprocessing, and the kind of
- mathtext support needed.
-
- - If *self* is configured to use TeX, return *s* unchanged except that
- a single space gets escaped, and the flag "TeX".
- - Otherwise, if *s* is mathtext (has an even number of unescaped dollar
- signs) and ``parse_math`` is not set to False, return *s* and the
- flag True.
- - Otherwise, return *s* with dollar signs unescaped, and the flag
- False.
- """
- if self.get_usetex():
- if s == " ":
- s = r"\ "
- return s, "TeX"
- elif not self.get_parse_math():
- return s, False
- elif cbook.is_math_text(s):
- return s, True
- else:
- return s.replace(r"\$", "$"), False
-
- def set_fontproperties(self, fp):
- """
- Set the font properties that control the text.
-
- Parameters
- ----------
- fp : `.font_manager.FontProperties` or `str` or `pathlib.Path`
- If a `str`, it is interpreted as a fontconfig pattern parsed by
- `.FontProperties`. If a `pathlib.Path`, it is interpreted as the
- absolute path to a font file.
- """
- self._fontproperties = FontProperties._from_any(fp).copy()
- self.stale = True
-
- def set_usetex(self, usetex):
- """
- Parameters
- ----------
- usetex : bool or None
- Whether to render using TeX, ``None`` means to use
- :rc:`text.usetex`.
- """
- if usetex is None:
- self._usetex = mpl.rcParams['text.usetex']
- else:
- self._usetex = bool(usetex)
- self.stale = True
-
- def get_usetex(self):
- """Return whether this `Text` object uses TeX for rendering."""
- return self._usetex
-
- def set_parse_math(self, parse_math):
- """
- Override switch to disable any mathtext parsing for this `Text`.
-
- Parameters
- ----------
- parse_math : bool
- If False, this `Text` will never use mathtext. If True, mathtext
- will be used if there is an even number of unescaped dollar signs.
- """
- self._parse_math = bool(parse_math)
-
- def get_parse_math(self):
- """Return whether mathtext parsing is considered for this `Text`."""
- return self._parse_math
-
- def set_fontname(self, fontname):
- """
- Alias for `set_fontfamily`.
-
- One-way alias only: the getter differs.
-
- Parameters
- ----------
- fontname : {FONTNAME, 'serif', 'sans-serif', 'cursive', 'fantasy', \
-'monospace'}
-
- See Also
- --------
- .font_manager.FontProperties.set_family
-
- """
- self.set_fontfamily(fontname)
-
-
-class OffsetFrom:
- """Callable helper class for working with `Annotation`."""
-
- def __init__(self, artist, ref_coord, unit="points"):
- """
- Parameters
- ----------
- artist : `~matplotlib.artist.Artist` or `.BboxBase` or `.Transform`
- The object to compute the offset from.
-
- ref_coord : (float, float)
- If *artist* is an `.Artist` or `.BboxBase`, this values is
- the location to of the offset origin in fractions of the
- *artist* bounding box.
-
- If *artist* is a transform, the offset origin is the
- transform applied to this value.
-
- unit : {'points, 'pixels'}, default: 'points'
- The screen units to use (pixels or points) for the offset input.
- """
- self._artist = artist
- x, y = ref_coord # Make copy when ref_coord is an array (and check the shape).
- self._ref_coord = x, y
- self.set_unit(unit)
-
- def set_unit(self, unit):
- """
- Set the unit for input to the transform used by ``__call__``.
-
- Parameters
- ----------
- unit : {'points', 'pixels'}
- """
- _api.check_in_list(["points", "pixels"], unit=unit)
- self._unit = unit
-
- def get_unit(self):
- """Return the unit for input to the transform used by ``__call__``."""
- return self._unit
-
- def __call__(self, renderer):
- """
- Return the offset transform.
-
- Parameters
- ----------
- renderer : `RendererBase`
- The renderer to use to compute the offset
-
- Returns
- -------
- `Transform`
- Maps (x, y) in pixel or point units to screen units
- relative to the given artist.
- """
- if isinstance(self._artist, Artist):
- bbox = self._artist.get_window_extent(renderer)
- xf, yf = self._ref_coord
- x = bbox.x0 + bbox.width * xf
- y = bbox.y0 + bbox.height * yf
- elif isinstance(self._artist, BboxBase):
- bbox = self._artist
- xf, yf = self._ref_coord
- x = bbox.x0 + bbox.width * xf
- y = bbox.y0 + bbox.height * yf
- elif isinstance(self._artist, Transform):
- x, y = self._artist.transform(self._ref_coord)
- else:
- _api.check_isinstance((Artist, BboxBase, Transform), artist=self._artist)
- scale = 1 if self._unit == "pixels" else renderer.points_to_pixels(1)
- return Affine2D().scale(scale).translate(x, y)
-
-
-class _AnnotationBase:
- def __init__(self,
- xy,
- xycoords='data',
- annotation_clip=None):
-
- x, y = xy # Make copy when xy is an array (and check the shape).
- self.xy = x, y
- self.xycoords = xycoords
- self.set_annotation_clip(annotation_clip)
-
- self._draggable = None
-
- def _get_xy(self, renderer, xy, coords):
- x, y = xy
- xcoord, ycoord = coords if isinstance(coords, tuple) else (coords, coords)
- if xcoord == 'data':
- x = float(self.convert_xunits(x))
- if ycoord == 'data':
- y = float(self.convert_yunits(y))
- return self._get_xy_transform(renderer, coords).transform((x, y))
-
- def _get_xy_transform(self, renderer, coords):
-
- if isinstance(coords, tuple):
- xcoord, ycoord = coords
- from matplotlib.transforms import blended_transform_factory
- tr1 = self._get_xy_transform(renderer, xcoord)
- tr2 = self._get_xy_transform(renderer, ycoord)
- return blended_transform_factory(tr1, tr2)
- elif callable(coords):
- tr = coords(renderer)
- if isinstance(tr, BboxBase):
- return BboxTransformTo(tr)
- elif isinstance(tr, Transform):
- return tr
- else:
- raise TypeError(
- f"xycoords callable must return a BboxBase or Transform, not a "
- f"{type(tr).__name__}")
- elif isinstance(coords, Artist):
- bbox = coords.get_window_extent(renderer)
- return BboxTransformTo(bbox)
- elif isinstance(coords, BboxBase):
- return BboxTransformTo(coords)
- elif isinstance(coords, Transform):
- return coords
- elif not isinstance(coords, str):
- raise TypeError(
- f"'xycoords' must be an instance of str, tuple[str, str], Artist, "
- f"Transform, or Callable, not a {type(coords).__name__}")
-
- if coords == 'data':
- return self.axes.transData
- elif coords == 'polar':
- from matplotlib.projections import PolarAxes
- tr = PolarAxes.PolarTransform()
- trans = tr + self.axes.transData
- return trans
-
- try:
- bbox_name, unit = coords.split()
- except ValueError: # i.e. len(coords.split()) != 2.
- raise ValueError(f"{coords!r} is not a valid coordinate") from None
-
- bbox0, xy0 = None, None
-
- # if unit is offset-like
- if bbox_name == "figure":
- bbox0 = self.figure.figbbox
- elif bbox_name == "subfigure":
- bbox0 = self.figure.bbox
- elif bbox_name == "axes":
- bbox0 = self.axes.bbox
-
- # reference x, y in display coordinate
- if bbox0 is not None:
- xy0 = bbox0.p0
- elif bbox_name == "offset":
- xy0 = self._get_position_xy(renderer)
- else:
- raise ValueError(f"{coords!r} is not a valid coordinate")
-
- if unit == "points":
- tr = Affine2D().scale(self.figure.dpi / 72) # dpi/72 dots per point
- elif unit == "pixels":
- tr = Affine2D()
- elif unit == "fontsize":
- tr = Affine2D().scale(self.get_size() * self.figure.dpi / 72)
- elif unit == "fraction":
- tr = Affine2D().scale(*bbox0.size)
- else:
- raise ValueError(f"{unit!r} is not a recognized unit")
-
- return tr.translate(*xy0)
-
- def set_annotation_clip(self, b):
- """
- Set the annotation's clipping behavior.
-
- Parameters
- ----------
- b : bool or None
- - True: The annotation will be clipped when ``self.xy`` is
- outside the axes.
- - False: The annotation will always be drawn.
- - None: The annotation will be clipped when ``self.xy`` is
- outside the axes and ``self.xycoords == "data"``.
- """
- self._annotation_clip = b
-
- def get_annotation_clip(self):
- """
- Return the annotation's clipping behavior.
-
- See `set_annotation_clip` for the meaning of return values.
- """
- return self._annotation_clip
-
- def _get_position_xy(self, renderer):
- """Return the pixel position of the annotated point."""
- return self._get_xy(renderer, self.xy, self.xycoords)
-
- def _check_xy(self, renderer=None):
- """Check whether the annotation at *xy_pixel* should be drawn."""
- if renderer is None:
- renderer = self.figure._get_renderer()
- b = self.get_annotation_clip()
- if b or (b is None and self.xycoords == "data"):
- # check if self.xy is inside the axes.
- xy_pixel = self._get_position_xy(renderer)
- return self.axes.contains_point(xy_pixel)
- return True
-
- def draggable(self, state=None, use_blit=False):
- """
- Set whether the annotation is draggable with the mouse.
-
- Parameters
- ----------
- state : bool or None
- - True or False: set the draggability.
- - None: toggle the draggability.
- use_blit : bool, default: False
- Use blitting for faster image composition. For details see
- :ref:`func-animation`.
-
- Returns
- -------
- DraggableAnnotation or None
- If the annotation is draggable, the corresponding
- `.DraggableAnnotation` helper is returned.
- """
- from matplotlib.offsetbox import DraggableAnnotation
- is_draggable = self._draggable is not None
-
- # if state is None we'll toggle
- if state is None:
- state = not is_draggable
-
- if state:
- if self._draggable is None:
- self._draggable = DraggableAnnotation(self, use_blit)
- else:
- if self._draggable is not None:
- self._draggable.disconnect()
- self._draggable = None
-
- return self._draggable
-
-
-class Annotation(Text, _AnnotationBase):
- """
- An `.Annotation` is a `.Text` that can refer to a specific position *xy*.
- Optionally an arrow pointing from the text to *xy* can be drawn.
-
- Attributes
- ----------
- xy
- The annotated position.
- xycoords
- The coordinate system for *xy*.
- arrow_patch
- A `.FancyArrowPatch` to point from *xytext* to *xy*.
- """
-
- def __str__(self):
- return f"Annotation({self.xy[0]:g}, {self.xy[1]:g}, {self._text!r})"
-
- def __init__(self, text, xy,
- xytext=None,
- xycoords='data',
- textcoords=None,
- arrowprops=None,
- annotation_clip=None,
- **kwargs):
- """
- Annotate the point *xy* with text *text*.
-
- In the simplest form, the text is placed at *xy*.
-
- Optionally, the text can be displayed in another position *xytext*.
- An arrow pointing from the text to the annotated point *xy* can then
- be added by defining *arrowprops*.
-
- Parameters
- ----------
- text : str
- The text of the annotation.
-
- xy : (float, float)
- The point *(x, y)* to annotate. The coordinate system is determined
- by *xycoords*.
-
- xytext : (float, float), default: *xy*
- The position *(x, y)* to place the text at. The coordinate system
- is determined by *textcoords*.
-
- xycoords : single or two-tuple of str or `.Artist` or `.Transform` or \
-callable, default: 'data'
-
- The coordinate system that *xy* is given in. The following types
- of values are supported:
-
- - One of the following strings:
-
- ==================== ============================================
- Value Description
- ==================== ============================================
- 'figure points' Points from the lower left of the figure
- 'figure pixels' Pixels from the lower left of the figure
- 'figure fraction' Fraction of figure from lower left
- 'subfigure points' Points from the lower left of the subfigure
- 'subfigure pixels' Pixels from the lower left of the subfigure
- 'subfigure fraction' Fraction of subfigure from lower left
- 'axes points' Points from lower left corner of axes
- 'axes pixels' Pixels from lower left corner of axes
- 'axes fraction' Fraction of axes from lower left
- 'data' Use the coordinate system of the object
- being annotated (default)
- 'polar' *(theta, r)* if not native 'data'
- coordinates
- ==================== ============================================
-
- Note that 'subfigure pixels' and 'figure pixels' are the same
- for the parent figure, so users who want code that is usable in
- a subfigure can use 'subfigure pixels'.
-
- - An `.Artist`: *xy* is interpreted as a fraction of the artist's
- `~matplotlib.transforms.Bbox`. E.g. *(0, 0)* would be the lower
- left corner of the bounding box and *(0.5, 1)* would be the
- center top of the bounding box.
-
- - A `.Transform` to transform *xy* to screen coordinates.
-
- - A function with one of the following signatures::
-
- def transform(renderer) -> Bbox
- def transform(renderer) -> Transform
-
- where *renderer* is a `.RendererBase` subclass.
-
- The result of the function is interpreted like the `.Artist` and
- `.Transform` cases above.
-
- - A tuple *(xcoords, ycoords)* specifying separate coordinate
- systems for *x* and *y*. *xcoords* and *ycoords* must each be
- of one of the above described types.
-
- See :ref:`plotting-guide-annotation` for more details.
-
- textcoords : single or two-tuple of str or `.Artist` or `.Transform` \
-or callable, default: value of *xycoords*
- The coordinate system that *xytext* is given in.
-
- All *xycoords* values are valid as well as the following strings:
-
- ================= =================================================
- Value Description
- ================= =================================================
- 'offset points' Offset, in points, from the *xy* value
- 'offset pixels' Offset, in pixels, from the *xy* value
- 'offset fontsize' Offset, relative to fontsize, from the *xy* value
- ================= =================================================
-
- arrowprops : dict, optional
- The properties used to draw a `.FancyArrowPatch` arrow between the
- positions *xy* and *xytext*. Defaults to None, i.e. no arrow is
- drawn.
-
- For historical reasons there are two different ways to specify
- arrows, "simple" and "fancy":
-
- **Simple arrow:**
-
- If *arrowprops* does not contain the key 'arrowstyle' the
- allowed keys are:
-
- ========== =================================================
- Key Description
- ========== =================================================
- width The width of the arrow in points
- headwidth The width of the base of the arrow head in points
- headlength The length of the arrow head in points
- shrink Fraction of total length to shrink from both ends
- ? Any `.FancyArrowPatch` property
- ========== =================================================
-
- The arrow is attached to the edge of the text box, the exact
- position (corners or centers) depending on where it's pointing to.
-
- **Fancy arrow:**
-
- This is used if 'arrowstyle' is provided in the *arrowprops*.
-
- Valid keys are the following `.FancyArrowPatch` parameters:
-
- =============== ===================================
- Key Description
- =============== ===================================
- arrowstyle The arrow style
- connectionstyle The connection style
- relpos See below; default is (0.5, 0.5)
- patchA Default is bounding box of the text
- patchB Default is None
- shrinkA Default is 2 points
- shrinkB Default is 2 points
- mutation_scale Default is text size (in points)
- mutation_aspect Default is 1
- ? Any `.FancyArrowPatch` property
- =============== ===================================
-
- The exact starting point position of the arrow is defined by
- *relpos*. It's a tuple of relative coordinates of the text box,
- where (0, 0) is the lower left corner and (1, 1) is the upper
- right corner. Values <0 and >1 are supported and specify points
- outside the text box. By default (0.5, 0.5), so the starting point
- is centered in the text box.
-
- annotation_clip : bool or None, default: None
- Whether to clip (i.e. not draw) the annotation when the annotation
- point *xy* is outside the axes area.
-
- - If *True*, the annotation will be clipped when *xy* is outside
- the axes.
- - If *False*, the annotation will always be drawn.
- - If *None*, the annotation will be clipped when *xy* is outside
- the axes and *xycoords* is 'data'.
-
- **kwargs
- Additional kwargs are passed to `.Text`.
-
- Returns
- -------
- `.Annotation`
-
- See Also
- --------
- :ref:`plotting-guide-annotation`
-
- """
- _AnnotationBase.__init__(self,
- xy,
- xycoords=xycoords,
- annotation_clip=annotation_clip)
- # warn about wonky input data
- if (xytext is None and
- textcoords is not None and
- textcoords != xycoords):
- _api.warn_external("You have used the `textcoords` kwarg, but "
- "not the `xytext` kwarg. This can lead to "
- "surprising results.")
-
- # clean up textcoords and assign default
- if textcoords is None:
- textcoords = self.xycoords
- self._textcoords = textcoords
-
- # cleanup xytext defaults
- if xytext is None:
- xytext = self.xy
- x, y = xytext
-
- self.arrowprops = arrowprops
- if arrowprops is not None:
- arrowprops = arrowprops.copy()
- if "arrowstyle" in arrowprops:
- self._arrow_relpos = arrowprops.pop("relpos", (0.5, 0.5))
- else:
- # modified YAArrow API to be used with FancyArrowPatch
- for key in ['width', 'headwidth', 'headlength', 'shrink']:
- arrowprops.pop(key, None)
- if 'frac' in arrowprops:
- _api.warn_deprecated(
- "3.8", name="the (unused) 'frac' key in 'arrowprops'")
- arrowprops.pop("frac")
- self.arrow_patch = FancyArrowPatch((0, 0), (1, 1), **arrowprops)
- else:
- self.arrow_patch = None
-
- # Must come last, as some kwargs may be propagated to arrow_patch.
- Text.__init__(self, x, y, text, **kwargs)
-
- @_api.rename_parameter("3.8", "event", "mouseevent")
- def contains(self, mouseevent):
- if self._different_canvas(mouseevent):
- return False, {}
- contains, tinfo = Text.contains(self, mouseevent)
- if self.arrow_patch is not None:
- in_patch, _ = self.arrow_patch.contains(mouseevent)
- contains = contains or in_patch
- return contains, tinfo
-
- @property
- def xycoords(self):
- return self._xycoords
-
- @xycoords.setter
- def xycoords(self, xycoords):
- def is_offset(s):
- return isinstance(s, str) and s.startswith("offset")
-
- if (isinstance(xycoords, tuple) and any(map(is_offset, xycoords))
- or is_offset(xycoords)):
- raise ValueError("xycoords cannot be an offset coordinate")
- self._xycoords = xycoords
-
- @property
- def xyann(self):
- """
- The text position.
-
- See also *xytext* in `.Annotation`.
- """
- return self.get_position()
-
- @xyann.setter
- def xyann(self, xytext):
- self.set_position(xytext)
-
- def get_anncoords(self):
- """
- Return the coordinate system to use for `.Annotation.xyann`.
-
- See also *xycoords* in `.Annotation`.
- """
- return self._textcoords
-
- def set_anncoords(self, coords):
- """
- Set the coordinate system to use for `.Annotation.xyann`.
-
- See also *xycoords* in `.Annotation`.
- """
- self._textcoords = coords
-
- anncoords = property(get_anncoords, set_anncoords, doc="""
- The coordinate system to use for `.Annotation.xyann`.""")
-
- def set_figure(self, fig):
- # docstring inherited
- if self.arrow_patch is not None:
- self.arrow_patch.set_figure(fig)
- Artist.set_figure(self, fig)
-
- def update_positions(self, renderer):
- """
- Update the pixel positions of the annotation text and the arrow patch.
- """
- # generate transformation
- self.set_transform(self._get_xy_transform(renderer, self.anncoords))
-
- arrowprops = self.arrowprops
- if arrowprops is None:
- return
-
- bbox = Text.get_window_extent(self, renderer)
-
- arrow_end = x1, y1 = self._get_position_xy(renderer) # Annotated pos.
-
- ms = arrowprops.get("mutation_scale", self.get_size())
- self.arrow_patch.set_mutation_scale(ms)
-
- if "arrowstyle" not in arrowprops:
- # Approximately simulate the YAArrow.
- shrink = arrowprops.get('shrink', 0.0)
- width = arrowprops.get('width', 4)
- headwidth = arrowprops.get('headwidth', 12)
- headlength = arrowprops.get('headlength', 12)
-
- # NB: ms is in pts
- stylekw = dict(head_length=headlength / ms,
- head_width=headwidth / ms,
- tail_width=width / ms)
-
- self.arrow_patch.set_arrowstyle('simple', **stylekw)
-
- # using YAArrow style:
- # pick the corner of the text bbox closest to annotated point.
- xpos = [(bbox.x0, 0), ((bbox.x0 + bbox.x1) / 2, 0.5), (bbox.x1, 1)]
- ypos = [(bbox.y0, 0), ((bbox.y0 + bbox.y1) / 2, 0.5), (bbox.y1, 1)]
- x, relposx = min(xpos, key=lambda v: abs(v[0] - x1))
- y, relposy = min(ypos, key=lambda v: abs(v[0] - y1))
- self._arrow_relpos = (relposx, relposy)
- r = np.hypot(y - y1, x - x1)
- shrink_pts = shrink * r / renderer.points_to_pixels(1)
- self.arrow_patch.shrinkA = self.arrow_patch.shrinkB = shrink_pts
-
- # adjust the starting point of the arrow relative to the textbox.
- # TODO : Rotation needs to be accounted.
- arrow_begin = bbox.p0 + bbox.size * self._arrow_relpos
- # The arrow is drawn from arrow_begin to arrow_end. It will be first
- # clipped by patchA and patchB. Then it will be shrunk by shrinkA and
- # shrinkB (in points). If patchA is not set, self.bbox_patch is used.
- self.arrow_patch.set_positions(arrow_begin, arrow_end)
-
- if "patchA" in arrowprops:
- patchA = arrowprops["patchA"]
- elif self._bbox_patch:
- patchA = self._bbox_patch
- elif self.get_text() == "":
- patchA = None
- else:
- pad = renderer.points_to_pixels(4)
- patchA = Rectangle(
- xy=(bbox.x0 - pad / 2, bbox.y0 - pad / 2),
- width=bbox.width + pad, height=bbox.height + pad,
- transform=IdentityTransform(), clip_on=False)
- self.arrow_patch.set_patchA(patchA)
-
- @artist.allow_rasterization
- def draw(self, renderer):
- # docstring inherited
- if renderer is not None:
- self._renderer = renderer
- if not self.get_visible() or not self._check_xy(renderer):
- return
- # Update text positions before `Text.draw` would, so that the
- # FancyArrowPatch is correctly positioned.
- self.update_positions(renderer)
- self.update_bbox_position_size(renderer)
- if self.arrow_patch is not None: # FancyArrowPatch
- if self.arrow_patch.figure is None and self.figure is not None:
- self.arrow_patch.figure = self.figure
- self.arrow_patch.draw(renderer)
- # Draw text, including FancyBboxPatch, after FancyArrowPatch.
- # Otherwise, a wedge arrowstyle can land partly on top of the Bbox.
- Text.draw(self, renderer)
-
- def get_window_extent(self, renderer=None):
- # docstring inherited
- # This block is the same as in Text.get_window_extent, but we need to
- # set the renderer before calling update_positions().
- if not self.get_visible() or not self._check_xy(renderer):
- return Bbox.unit()
- if renderer is not None:
- self._renderer = renderer
- if self._renderer is None:
- self._renderer = self.figure._get_renderer()
- if self._renderer is None:
- raise RuntimeError('Cannot get window extent without renderer')
-
- self.update_positions(self._renderer)
-
- text_bbox = Text.get_window_extent(self)
- bboxes = [text_bbox]
-
- if self.arrow_patch is not None:
- bboxes.append(self.arrow_patch.get_window_extent())
-
- return Bbox.union(bboxes)
-
- def get_tightbbox(self, renderer=None):
- # docstring inherited
- if not self._check_xy(renderer):
- return Bbox.null()
- return super().get_tightbbox(renderer)
-
-
-_docstring.interpd.update(Annotation=Annotation.__init__.__doc__)
diff --git a/contrib/python/matplotlib/py3/matplotlib/text.pyi b/contrib/python/matplotlib/py3/matplotlib/text.pyi
deleted file mode 100644
index 6a83b1bbbe..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/text.pyi
+++ /dev/null
@@ -1,214 +0,0 @@
-from .artist import Artist
-from .backend_bases import RendererBase
-from .font_manager import FontProperties
-from .offsetbox import DraggableAnnotation
-from .path import Path
-from .patches import FancyArrowPatch, FancyBboxPatch
-from .textpath import ( # noqa: reexported API
- TextPath as TextPath,
- TextToPath as TextToPath,
-)
-from .transforms import (
- Bbox,
- BboxBase,
- Transform,
-)
-
-from collections.abc import Callable, Iterable
-from typing import Any, Literal
-from .typing import ColorType
-
-class Text(Artist):
- zorder: float
- def __init__(
- self,
- x: float = ...,
- y: float = ...,
- text: Any = ...,
- *,
- color: ColorType | None = ...,
- verticalalignment: Literal[
- "bottom", "baseline", "center", "center_baseline", "top"
- ] = ...,
- horizontalalignment: Literal["left", "center", "right"] = ...,
- multialignment: Literal["left", "center", "right"] | None = ...,
- fontproperties: str | Path | FontProperties | None = ...,
- rotation: float | Literal["vertical", "horizontal"] | None = ...,
- linespacing: float | None = ...,
- rotation_mode: Literal["default", "anchor"] | None = ...,
- usetex: bool | None = ...,
- wrap: bool = ...,
- transform_rotates_text: bool = ...,
- parse_math: bool | None = ...,
- antialiased: bool | None = ...,
- **kwargs
- ) -> None: ...
- def update(self, kwargs: dict[str, Any]) -> list[Any]: ...
- def get_rotation(self) -> float: ...
- def get_transform_rotates_text(self) -> bool: ...
- def set_rotation_mode(self, m: None | Literal["default", "anchor"]) -> None: ...
- def get_rotation_mode(self) -> Literal["default", "anchor"]: ...
- def set_bbox(self, rectprops: dict[str, Any]) -> None: ...
- def get_bbox_patch(self) -> None | FancyBboxPatch: ...
- def update_bbox_position_size(self, renderer: RendererBase) -> None: ...
- def get_wrap(self) -> bool: ...
- def set_wrap(self, wrap: bool) -> None: ...
- def get_color(self) -> ColorType: ...
- def get_fontproperties(self) -> FontProperties: ...
- def get_fontfamily(self) -> list[str]: ...
- def get_fontname(self) -> str: ...
- def get_fontstyle(self) -> Literal["normal", "italic", "oblique"]: ...
- def get_fontsize(self) -> float | str: ...
- def get_fontvariant(self) -> Literal["normal", "small-caps"]: ...
- def get_fontweight(self) -> int | str: ...
- def get_stretch(self) -> int | str: ...
- def get_horizontalalignment(self) -> Literal["left", "center", "right"]: ...
- def get_unitless_position(self) -> tuple[float, float]: ...
- def get_position(self) -> tuple[float, float]: ...
- def get_text(self) -> str: ...
- def get_verticalalignment(
- self,
- ) -> Literal["bottom", "baseline", "center", "center_baseline", "top"]: ...
- def get_window_extent(
- self, renderer: RendererBase | None = ..., dpi: float | None = ...
- ) -> Bbox: ...
- def set_backgroundcolor(self, color: ColorType) -> None: ...
- def set_color(self, color: ColorType) -> None: ...
- def set_horizontalalignment(
- self, align: Literal["left", "center", "right"]
- ) -> None: ...
- def set_multialignment(self, align: Literal["left", "center", "right"]) -> None: ...
- def set_linespacing(self, spacing: float) -> None: ...
- def set_fontfamily(self, fontname: str | Iterable[str]) -> None: ...
- def set_fontvariant(self, variant: Literal["normal", "small-caps"]) -> None: ...
- def set_fontstyle(
- self, fontstyle: Literal["normal", "italic", "oblique"]
- ) -> None: ...
- def set_fontsize(self, fontsize: float | str) -> None: ...
- def get_math_fontfamily(self) -> str: ...
- def set_math_fontfamily(self, fontfamily: str) -> None: ...
- def set_fontweight(self, weight: int | str) -> None: ...
- def set_fontstretch(self, stretch: int | str) -> None: ...
- def set_position(self, xy: tuple[float, float]) -> None: ...
- def set_x(self, x: float) -> None: ...
- def set_y(self, y: float) -> None: ...
- def set_rotation(self, s: float) -> None: ...
- def set_transform_rotates_text(self, t: bool) -> None: ...
- def set_verticalalignment(
- self, align: Literal["bottom", "baseline", "center", "center_baseline", "top"]
- ) -> None: ...
- def set_text(self, s: Any) -> None: ...
- def set_fontproperties(self, fp: FontProperties | str | Path | None) -> None: ...
- def set_usetex(self, usetex: bool | None) -> None: ...
- def get_usetex(self) -> bool: ...
- def set_parse_math(self, parse_math: bool) -> None: ...
- def get_parse_math(self) -> bool: ...
- def set_fontname(self, fontname: str | Iterable[str]) -> None: ...
- def get_antialiased(self) -> bool: ...
- def set_antialiased(self, antialiased: bool) -> None: ...
-
-class OffsetFrom:
- def __init__(
- self,
- artist: Artist | BboxBase | Transform,
- ref_coord: tuple[float, float],
- unit: Literal["points", "pixels"] = ...,
- ) -> None: ...
- def set_unit(self, unit: Literal["points", "pixels"]) -> None: ...
- def get_unit(self) -> Literal["points", "pixels"]: ...
- def __call__(self, renderer: RendererBase) -> Transform: ...
-
-class _AnnotationBase:
- xy: tuple[float, float]
- xycoords: str | tuple[str, str] | Artist | Transform | Callable[
- [RendererBase], Bbox | Transform
- ]
- def __init__(
- self,
- xy,
- xycoords: str
- | tuple[str, str]
- | Artist
- | Transform
- | Callable[[RendererBase], Bbox | Transform] = ...,
- annotation_clip: bool | None = ...,
- ) -> None: ...
- def set_annotation_clip(self, b: bool | None) -> None: ...
- def get_annotation_clip(self) -> bool | None: ...
- def draggable(
- self, state: bool | None = ..., use_blit: bool = ...
- ) -> DraggableAnnotation | None: ...
-
-class Annotation(Text, _AnnotationBase):
- arrowprops: dict[str, Any] | None
- arrow_patch: FancyArrowPatch | None
- def __init__(
- self,
- text: str,
- xy: tuple[float, float],
- xytext: tuple[float, float] | None = ...,
- xycoords: str
- | tuple[str, str]
- | Artist
- | Transform
- | Callable[[RendererBase], Bbox | Transform] = ...,
- textcoords: str
- | tuple[str, str]
- | Artist
- | Transform
- | Callable[[RendererBase], Bbox | Transform]
- | None = ...,
- arrowprops: dict[str, Any] | None = ...,
- annotation_clip: bool | None = ...,
- **kwargs
- ) -> None: ...
- @property
- def xycoords(
- self,
- ) -> str | tuple[str, str] | Artist | Transform | Callable[
- [RendererBase], Bbox | Transform
- ]: ...
- @xycoords.setter
- def xycoords(
- self,
- xycoords: str
- | tuple[str, str]
- | Artist
- | Transform
- | Callable[[RendererBase], Bbox | Transform],
- ) -> None: ...
- @property
- def xyann(self) -> tuple[float, float]: ...
- @xyann.setter
- def xyann(self, xytext: tuple[float, float]) -> None: ...
- def get_anncoords(
- self,
- ) -> str | tuple[str, str] | Artist | Transform | Callable[
- [RendererBase], Bbox | Transform
- ]: ...
- def set_anncoords(
- self,
- coords: str
- | tuple[str, str]
- | Artist
- | Transform
- | Callable[[RendererBase], Bbox | Transform],
- ) -> None: ...
- @property
- def anncoords(
- self,
- ) -> str | tuple[str, str] | Artist | Transform | Callable[
- [RendererBase], Bbox | Transform
- ]: ...
- @anncoords.setter
- def anncoords(
- self,
- coords: str
- | tuple[str, str]
- | Artist
- | Transform
- | Callable[[RendererBase], Bbox | Transform],
- ) -> None: ...
- def update_positions(self, renderer: RendererBase) -> None: ...
- # Drops `dpi` parameter from superclass
- def get_window_extent(self, renderer: RendererBase | None = ...) -> Bbox: ... # type: ignore[override]
diff --git a/contrib/python/matplotlib/py3/matplotlib/textpath.py b/contrib/python/matplotlib/py3/matplotlib/textpath.py
deleted file mode 100644
index c00966d6e6..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/textpath.py
+++ /dev/null
@@ -1,397 +0,0 @@
-from collections import OrderedDict
-import logging
-import urllib.parse
-
-import numpy as np
-
-from matplotlib import _text_helpers, dviread
-from matplotlib.font_manager import (
- FontProperties, get_font, fontManager as _fontManager
-)
-from matplotlib.ft2font import LOAD_NO_HINTING, LOAD_TARGET_LIGHT
-from matplotlib.mathtext import MathTextParser
-from matplotlib.path import Path
-from matplotlib.texmanager import TexManager
-from matplotlib.transforms import Affine2D
-
-_log = logging.getLogger(__name__)
-
-
-class TextToPath:
- """A class that converts strings to paths."""
-
- FONT_SCALE = 100.
- DPI = 72
-
- def __init__(self):
- self.mathtext_parser = MathTextParser('path')
- self._texmanager = None
-
- def _get_font(self, prop):
- """
- Find the `FT2Font` matching font properties *prop*, with its size set.
- """
- filenames = _fontManager._find_fonts_by_props(prop)
- font = get_font(filenames)
- font.set_size(self.FONT_SCALE, self.DPI)
- return font
-
- def _get_hinting_flag(self):
- return LOAD_NO_HINTING
-
- def _get_char_id(self, font, ccode):
- """
- Return a unique id for the given font and character-code set.
- """
- return urllib.parse.quote(f"{font.postscript_name}-{ccode:x}")
-
- def get_text_width_height_descent(self, s, prop, ismath):
- fontsize = prop.get_size_in_points()
-
- if ismath == "TeX":
- return TexManager().get_text_width_height_descent(s, fontsize)
-
- scale = fontsize / self.FONT_SCALE
-
- if ismath:
- prop = prop.copy()
- prop.set_size(self.FONT_SCALE)
- width, height, descent, *_ = \
- self.mathtext_parser.parse(s, 72, prop)
- return width * scale, height * scale, descent * scale
-
- font = self._get_font(prop)
- font.set_text(s, 0.0, flags=LOAD_NO_HINTING)
- w, h = font.get_width_height()
- w /= 64.0 # convert from subpixels
- h /= 64.0
- d = font.get_descent()
- d /= 64.0
- return w * scale, h * scale, d * scale
-
- def get_text_path(self, prop, s, ismath=False):
- """
- Convert text *s* to path (a tuple of vertices and codes for
- matplotlib.path.Path).
-
- Parameters
- ----------
- prop : `~matplotlib.font_manager.FontProperties`
- The font properties for the text.
- s : str
- The text to be converted.
- ismath : {False, True, "TeX"}
- If True, use mathtext parser. If "TeX", use tex for rendering.
-
- Returns
- -------
- verts : list
- A list of arrays containing the (x, y) coordinates of the vertices.
- codes : list
- A list of path codes.
-
- Examples
- --------
- Create a list of vertices and codes from a text, and create a `.Path`
- from those::
-
- from matplotlib.path import Path
- from matplotlib.text import TextToPath
- from matplotlib.font_manager import FontProperties
-
- fp = FontProperties(family="Comic Neue", style="italic")
- verts, codes = TextToPath().get_text_path(fp, "ABC")
- path = Path(verts, codes, closed=False)
-
- Also see `TextPath` for a more direct way to create a path from a text.
- """
- if ismath == "TeX":
- glyph_info, glyph_map, rects = self.get_glyphs_tex(prop, s)
- elif not ismath:
- font = self._get_font(prop)
- glyph_info, glyph_map, rects = self.get_glyphs_with_font(font, s)
- else:
- glyph_info, glyph_map, rects = self.get_glyphs_mathtext(prop, s)
-
- verts, codes = [], []
- for glyph_id, xposition, yposition, scale in glyph_info:
- verts1, codes1 = glyph_map[glyph_id]
- verts.extend(verts1 * scale + [xposition, yposition])
- codes.extend(codes1)
- for verts1, codes1 in rects:
- verts.extend(verts1)
- codes.extend(codes1)
-
- # Make sure an empty string or one with nothing to print
- # (e.g. only spaces & newlines) will be valid/empty path
- if not verts:
- verts = np.empty((0, 2))
-
- return verts, codes
-
- def get_glyphs_with_font(self, font, s, glyph_map=None,
- return_new_glyphs_only=False):
- """
- Convert string *s* to vertices and codes using the provided ttf font.
- """
-
- if glyph_map is None:
- glyph_map = OrderedDict()
-
- if return_new_glyphs_only:
- glyph_map_new = OrderedDict()
- else:
- glyph_map_new = glyph_map
-
- xpositions = []
- glyph_ids = []
- for item in _text_helpers.layout(s, font):
- char_id = self._get_char_id(item.ft_object, ord(item.char))
- glyph_ids.append(char_id)
- xpositions.append(item.x)
- if char_id not in glyph_map:
- glyph_map_new[char_id] = item.ft_object.get_path()
-
- ypositions = [0] * len(xpositions)
- sizes = [1.] * len(xpositions)
-
- rects = []
-
- return (list(zip(glyph_ids, xpositions, ypositions, sizes)),
- glyph_map_new, rects)
-
- def get_glyphs_mathtext(self, prop, s, glyph_map=None,
- return_new_glyphs_only=False):
- """
- Parse mathtext string *s* and convert it to a (vertices, codes) pair.
- """
-
- prop = prop.copy()
- prop.set_size(self.FONT_SCALE)
-
- width, height, descent, glyphs, rects = self.mathtext_parser.parse(
- s, self.DPI, prop)
-
- if not glyph_map:
- glyph_map = OrderedDict()
-
- if return_new_glyphs_only:
- glyph_map_new = OrderedDict()
- else:
- glyph_map_new = glyph_map
-
- xpositions = []
- ypositions = []
- glyph_ids = []
- sizes = []
-
- for font, fontsize, ccode, ox, oy in glyphs:
- char_id = self._get_char_id(font, ccode)
- if char_id not in glyph_map:
- font.clear()
- font.set_size(self.FONT_SCALE, self.DPI)
- font.load_char(ccode, flags=LOAD_NO_HINTING)
- glyph_map_new[char_id] = font.get_path()
-
- xpositions.append(ox)
- ypositions.append(oy)
- glyph_ids.append(char_id)
- size = fontsize / self.FONT_SCALE
- sizes.append(size)
-
- myrects = []
- for ox, oy, w, h in rects:
- vert1 = [(ox, oy), (ox, oy + h), (ox + w, oy + h),
- (ox + w, oy), (ox, oy), (0, 0)]
- code1 = [Path.MOVETO,
- Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO,
- Path.CLOSEPOLY]
- myrects.append((vert1, code1))
-
- return (list(zip(glyph_ids, xpositions, ypositions, sizes)),
- glyph_map_new, myrects)
-
- def get_glyphs_tex(self, prop, s, glyph_map=None,
- return_new_glyphs_only=False):
- """Convert the string *s* to vertices and codes using usetex mode."""
- # Mostly borrowed from pdf backend.
-
- dvifile = TexManager().make_dvi(s, self.FONT_SCALE)
- with dviread.Dvi(dvifile, self.DPI) as dvi:
- page, = dvi
-
- if glyph_map is None:
- glyph_map = OrderedDict()
-
- if return_new_glyphs_only:
- glyph_map_new = OrderedDict()
- else:
- glyph_map_new = glyph_map
-
- glyph_ids, xpositions, ypositions, sizes = [], [], [], []
-
- # Gather font information and do some setup for combining
- # characters into strings.
- for text in page.text:
- font = get_font(text.font_path)
- char_id = self._get_char_id(font, text.glyph)
- if char_id not in glyph_map:
- font.clear()
- font.set_size(self.FONT_SCALE, self.DPI)
- glyph_name_or_index = text.glyph_name_or_index
- if isinstance(glyph_name_or_index, str):
- index = font.get_name_index(glyph_name_or_index)
- font.load_glyph(index, flags=LOAD_TARGET_LIGHT)
- elif isinstance(glyph_name_or_index, int):
- self._select_native_charmap(font)
- font.load_char(
- glyph_name_or_index, flags=LOAD_TARGET_LIGHT)
- else: # Should not occur.
- raise TypeError(f"Glyph spec of unexpected type: "
- f"{glyph_name_or_index!r}")
- glyph_map_new[char_id] = font.get_path()
-
- glyph_ids.append(char_id)
- xpositions.append(text.x)
- ypositions.append(text.y)
- sizes.append(text.font_size / self.FONT_SCALE)
-
- myrects = []
-
- for ox, oy, h, w in page.boxes:
- vert1 = [(ox, oy), (ox + w, oy), (ox + w, oy + h),
- (ox, oy + h), (ox, oy), (0, 0)]
- code1 = [Path.MOVETO,
- Path.LINETO, Path.LINETO, Path.LINETO, Path.LINETO,
- Path.CLOSEPOLY]
- myrects.append((vert1, code1))
-
- return (list(zip(glyph_ids, xpositions, ypositions, sizes)),
- glyph_map_new, myrects)
-
- @staticmethod
- def _select_native_charmap(font):
- # Select the native charmap. (we can't directly identify it but it's
- # typically an Adobe charmap).
- for charmap_code in [
- 1094992451, # ADOBE_CUSTOM.
- 1094995778, # ADOBE_STANDARD.
- ]:
- try:
- font.select_charmap(charmap_code)
- except (ValueError, RuntimeError):
- pass
- else:
- break
- else:
- _log.warning("No supported encoding in font (%s).", font.fname)
-
-
-text_to_path = TextToPath()
-
-
-class TextPath(Path):
- """
- Create a path from the text.
- """
-
- def __init__(self, xy, s, size=None, prop=None,
- _interpolation_steps=1, usetex=False):
- r"""
- Create a path from the text. Note that it simply is a path,
- not an artist. You need to use the `.PathPatch` (or other artists)
- to draw this path onto the canvas.
-
- Parameters
- ----------
- xy : tuple or array of two float values
- Position of the text. For no offset, use ``xy=(0, 0)``.
-
- s : str
- The text to convert to a path.
-
- size : float, optional
- Font size in points. Defaults to the size specified via the font
- properties *prop*.
-
- prop : `~matplotlib.font_manager.FontProperties`, optional
- Font property. If not provided, will use a default
- `.FontProperties` with parameters from the
- :ref:`rcParams<customizing-with-dynamic-rc-settings>`.
-
- _interpolation_steps : int, optional
- (Currently ignored)
-
- usetex : bool, default: False
- Whether to use tex rendering.
-
- Examples
- --------
- The following creates a path from the string "ABC" with Helvetica
- font face; and another path from the latex fraction 1/2::
-
- from matplotlib.text import TextPath
- from matplotlib.font_manager import FontProperties
-
- fp = FontProperties(family="Helvetica", style="italic")
- path1 = TextPath((12, 12), "ABC", size=12, prop=fp)
- path2 = TextPath((0, 0), r"$\frac{1}{2}$", size=12, usetex=True)
-
- Also see :doc:`/gallery/text_labels_and_annotations/demo_text_path`.
- """
- # Circular import.
- from matplotlib.text import Text
-
- prop = FontProperties._from_any(prop)
- if size is None:
- size = prop.get_size_in_points()
-
- self._xy = xy
- self.set_size(size)
-
- self._cached_vertices = None
- s, ismath = Text(usetex=usetex)._preprocess_math(s)
- super().__init__(
- *text_to_path.get_text_path(prop, s, ismath=ismath),
- _interpolation_steps=_interpolation_steps,
- readonly=True)
- self._should_simplify = False
-
- def set_size(self, size):
- """Set the text size."""
- self._size = size
- self._invalid = True
-
- def get_size(self):
- """Get the text size."""
- return self._size
-
- @property
- def vertices(self):
- """
- Return the cached path after updating it if necessary.
- """
- self._revalidate_path()
- return self._cached_vertices
-
- @property
- def codes(self):
- """
- Return the codes
- """
- return self._codes
-
- def _revalidate_path(self):
- """
- Update the path if necessary.
-
- The path for the text is initially create with the font size of
- `.FONT_SCALE`, and this path is rescaled to other size when necessary.
- """
- if self._invalid or self._cached_vertices is None:
- tr = (Affine2D()
- .scale(self._size / text_to_path.FONT_SCALE)
- .translate(*self._xy))
- self._cached_vertices = tr.transform(self._vertices)
- self._cached_vertices.flags.writeable = False
- self._invalid = False
diff --git a/contrib/python/matplotlib/py3/matplotlib/textpath.pyi b/contrib/python/matplotlib/py3/matplotlib/textpath.pyi
deleted file mode 100644
index 34d4e92ac4..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/textpath.pyi
+++ /dev/null
@@ -1,74 +0,0 @@
-from matplotlib.font_manager import FontProperties
-from matplotlib.ft2font import FT2Font
-from matplotlib.mathtext import MathTextParser, VectorParse
-from matplotlib.path import Path
-
-import numpy as np
-
-from typing import Literal
-
-class TextToPath:
- FONT_SCALE: float
- DPI: float
- mathtext_parser: MathTextParser[VectorParse]
- def __init__(self) -> None: ...
- def get_text_width_height_descent(
- self, s: str, prop: FontProperties, ismath: bool | Literal["TeX"]
- ) -> tuple[float, float, float]: ...
- def get_text_path(
- self, prop: FontProperties, s: str, ismath: bool | Literal["TeX"] = ...
- ) -> list[np.ndarray]: ...
- def get_glyphs_with_font(
- self,
- font: FT2Font,
- s: str,
- glyph_map: dict[str, tuple[np.ndarray, np.ndarray]] | None = ...,
- return_new_glyphs_only: bool = ...,
- ) -> tuple[
- list[tuple[str, float, float, float]],
- dict[str, tuple[np.ndarray, np.ndarray]],
- list[tuple[list[tuple[float, float]], list[int]]],
- ]: ...
- def get_glyphs_mathtext(
- self,
- prop: FontProperties,
- s: str,
- glyph_map: dict[str, tuple[np.ndarray, np.ndarray]] | None = ...,
- return_new_glyphs_only: bool = ...,
- ) -> tuple[
- list[tuple[str, float, float, float]],
- dict[str, tuple[np.ndarray, np.ndarray]],
- list[tuple[list[tuple[float, float]], list[int]]],
- ]: ...
- def get_glyphs_tex(
- self,
- prop: FontProperties,
- s: str,
- glyph_map: dict[str, tuple[np.ndarray, np.ndarray]] | None = ...,
- return_new_glyphs_only: bool = ...,
- ) -> tuple[
- list[tuple[str, float, float, float]],
- dict[str, tuple[np.ndarray, np.ndarray]],
- list[tuple[list[tuple[float, float]], list[int]]],
- ]: ...
-
-text_to_path: TextToPath
-
-class TextPath(Path):
- def __init__(
- self,
- xy: tuple[float, float],
- s: str,
- size: float | None = ...,
- prop: FontProperties | None = ...,
- _interpolation_steps: int = ...,
- usetex: bool = ...,
- ) -> None: ...
- def set_size(self, size: float | None) -> None: ...
- def get_size(self) -> float | None: ...
-
- # These are read only... there actually are protections in the base class, so probably can be deleted...
- @property # type: ignore[misc]
- def vertices(self) -> np.ndarray: ... # type: ignore[override]
- @property # type: ignore[misc]
- def codes(self) -> np.ndarray: ... # type: ignore[override]
diff --git a/contrib/python/matplotlib/py3/matplotlib/ticker.py b/contrib/python/matplotlib/py3/matplotlib/ticker.py
deleted file mode 100644
index 5b1b7e1140..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/ticker.py
+++ /dev/null
@@ -1,2942 +0,0 @@
-"""
-Tick locating and formatting
-============================
-
-This module contains classes for configuring tick locating and formatting.
-Generic tick locators and formatters are provided, as well as domain specific
-custom ones.
-
-Although the locators know nothing about major or minor ticks, they are used
-by the Axis class to support major and minor tick locating and formatting.
-
-.. _tick_locating:
-.. _locators:
-
-Tick locating
--------------
-
-The Locator class is the base class for all tick locators. The locators
-handle autoscaling of the view limits based on the data limits, and the
-choosing of tick locations. A useful semi-automatic tick locator is
-`MultipleLocator`. It is initialized with a base, e.g., 10, and it picks
-axis limits and ticks that are multiples of that base.
-
-The Locator subclasses defined here are:
-
-======================= =======================================================
-`AutoLocator` `MaxNLocator` with simple defaults. This is the default
- tick locator for most plotting.
-`MaxNLocator` Finds up to a max number of intervals with ticks at
- nice locations.
-`LinearLocator` Space ticks evenly from min to max.
-`LogLocator` Space ticks logarithmically from min to max.
-`MultipleLocator` Ticks and range are a multiple of base; either integer
- or float.
-`FixedLocator` Tick locations are fixed.
-`IndexLocator` Locator for index plots (e.g., where
- ``x = range(len(y))``).
-`NullLocator` No ticks.
-`SymmetricalLogLocator` Locator for use with the symlog norm; works like
- `LogLocator` for the part outside of the threshold and
- adds 0 if inside the limits.
-`AsinhLocator` Locator for use with the asinh norm, attempting to
- space ticks approximately uniformly.
-`LogitLocator` Locator for logit scaling.
-`AutoMinorLocator` Locator for minor ticks when the axis is linear and the
- major ticks are uniformly spaced. Subdivides the major
- tick interval into a specified number of minor
- intervals, defaulting to 4 or 5 depending on the major
- interval.
-======================= =======================================================
-
-There are a number of locators specialized for date locations - see
-the :mod:`.dates` module.
-
-You can define your own locator by deriving from Locator. You must
-override the ``__call__`` method, which returns a sequence of locations,
-and you will probably want to override the autoscale method to set the
-view limits from the data limits.
-
-If you want to override the default locator, use one of the above or a custom
-locator and pass it to the x- or y-axis instance. The relevant methods are::
-
- ax.xaxis.set_major_locator(xmajor_locator)
- ax.xaxis.set_minor_locator(xminor_locator)
- ax.yaxis.set_major_locator(ymajor_locator)
- ax.yaxis.set_minor_locator(yminor_locator)
-
-The default minor locator is `NullLocator`, i.e., no minor ticks on by default.
-
-.. note::
- `Locator` instances should not be used with more than one
- `~matplotlib.axis.Axis` or `~matplotlib.axes.Axes`. So instead of::
-
- locator = MultipleLocator(5)
- ax.xaxis.set_major_locator(locator)
- ax2.xaxis.set_major_locator(locator)
-
- do the following instead::
-
- ax.xaxis.set_major_locator(MultipleLocator(5))
- ax2.xaxis.set_major_locator(MultipleLocator(5))
-
-.. _formatters:
-
-Tick formatting
----------------
-
-Tick formatting is controlled by classes derived from Formatter. The formatter
-operates on a single tick value and returns a string to the axis.
-
-========================= =====================================================
-`NullFormatter` No labels on the ticks.
-`FixedFormatter` Set the strings manually for the labels.
-`FuncFormatter` User defined function sets the labels.
-`StrMethodFormatter` Use string `format` method.
-`FormatStrFormatter` Use an old-style sprintf format string.
-`ScalarFormatter` Default formatter for scalars: autopick the format
- string.
-`LogFormatter` Formatter for log axes.
-`LogFormatterExponent` Format values for log axis using
- ``exponent = log_base(value)``.
-`LogFormatterMathtext` Format values for log axis using
- ``exponent = log_base(value)`` using Math text.
-`LogFormatterSciNotation` Format values for log axis using scientific notation.
-`LogitFormatter` Probability formatter.
-`EngFormatter` Format labels in engineering notation.
-`PercentFormatter` Format labels as a percentage.
-========================= =====================================================
-
-You can derive your own formatter from the Formatter base class by
-simply overriding the ``__call__`` method. The formatter class has
-access to the axis view and data limits.
-
-To control the major and minor tick label formats, use one of the
-following methods::
-
- ax.xaxis.set_major_formatter(xmajor_formatter)
- ax.xaxis.set_minor_formatter(xminor_formatter)
- ax.yaxis.set_major_formatter(ymajor_formatter)
- ax.yaxis.set_minor_formatter(yminor_formatter)
-
-In addition to a `.Formatter` instance, `~.Axis.set_major_formatter` and
-`~.Axis.set_minor_formatter` also accept a ``str`` or function. ``str`` input
-will be internally replaced with an autogenerated `.StrMethodFormatter` with
-the input ``str``. For function input, a `.FuncFormatter` with the input
-function will be generated and used.
-
-See :doc:`/gallery/ticks/major_minor_demo` for an example of setting major
-and minor ticks. See the :mod:`matplotlib.dates` module for more information
-and examples of using date locators and formatters.
-"""
-
-import itertools
-import logging
-import locale
-import math
-from numbers import Integral
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, cbook
-from matplotlib import transforms as mtransforms
-
-_log = logging.getLogger(__name__)
-
-__all__ = ('TickHelper', 'Formatter', 'FixedFormatter',
- 'NullFormatter', 'FuncFormatter', 'FormatStrFormatter',
- 'StrMethodFormatter', 'ScalarFormatter', 'LogFormatter',
- 'LogFormatterExponent', 'LogFormatterMathtext',
- 'LogFormatterSciNotation',
- 'LogitFormatter', 'EngFormatter', 'PercentFormatter',
- 'Locator', 'IndexLocator', 'FixedLocator', 'NullLocator',
- 'LinearLocator', 'LogLocator', 'AutoLocator',
- 'MultipleLocator', 'MaxNLocator', 'AutoMinorLocator',
- 'SymmetricalLogLocator', 'AsinhLocator', 'LogitLocator')
-
-
-class _DummyAxis:
- __name__ = "dummy"
-
- def __init__(self, minpos=0):
- self._data_interval = (0, 1)
- self._view_interval = (0, 1)
- self._minpos = minpos
-
- def get_view_interval(self):
- return self._view_interval
-
- def set_view_interval(self, vmin, vmax):
- self._view_interval = (vmin, vmax)
-
- def get_minpos(self):
- return self._minpos
-
- def get_data_interval(self):
- return self._data_interval
-
- def set_data_interval(self, vmin, vmax):
- self._data_interval = (vmin, vmax)
-
- def get_tick_space(self):
- # Just use the long-standing default of nbins==9
- return 9
-
-
-class TickHelper:
- axis = None
-
- def set_axis(self, axis):
- self.axis = axis
-
- def create_dummy_axis(self, **kwargs):
- if self.axis is None:
- self.axis = _DummyAxis(**kwargs)
-
-
-class Formatter(TickHelper):
- """
- Create a string based on a tick value and location.
- """
- # some classes want to see all the locs to help format
- # individual ones
- locs = []
-
- def __call__(self, x, pos=None):
- """
- Return the format for tick value *x* at position pos.
- ``pos=None`` indicates an unspecified location.
- """
- raise NotImplementedError('Derived must override')
-
- def format_ticks(self, values):
- """Return the tick labels for all the ticks at once."""
- self.set_locs(values)
- return [self(value, i) for i, value in enumerate(values)]
-
- def format_data(self, value):
- """
- Return the full string representation of the value with the
- position unspecified.
- """
- return self.__call__(value)
-
- def format_data_short(self, value):
- """
- Return a short string version of the tick value.
-
- Defaults to the position-independent long value.
- """
- return self.format_data(value)
-
- def get_offset(self):
- return ''
-
- def set_locs(self, locs):
- """
- Set the locations of the ticks.
-
- This method is called before computing the tick labels because some
- formatters need to know all tick locations to do so.
- """
- self.locs = locs
-
- @staticmethod
- def fix_minus(s):
- """
- Some classes may want to replace a hyphen for minus with the proper
- Unicode symbol (U+2212) for typographical correctness. This is a
- helper method to perform such a replacement when it is enabled via
- :rc:`axes.unicode_minus`.
- """
- return (s.replace('-', '\N{MINUS SIGN}')
- if mpl.rcParams['axes.unicode_minus']
- else s)
-
- def _set_locator(self, locator):
- """Subclasses may want to override this to set a locator."""
- pass
-
-
-class NullFormatter(Formatter):
- """Always return the empty string."""
-
- def __call__(self, x, pos=None):
- # docstring inherited
- return ''
-
-
-class FixedFormatter(Formatter):
- """
- Return fixed strings for tick labels based only on position, not value.
-
- .. note::
- `.FixedFormatter` should only be used together with `.FixedLocator`.
- Otherwise, the labels may end up in unexpected positions.
- """
-
- def __init__(self, seq):
- """Set the sequence *seq* of strings that will be used for labels."""
- self.seq = seq
- self.offset_string = ''
-
- def __call__(self, x, pos=None):
- """
- Return the label that matches the position, regardless of the value.
-
- For positions ``pos < len(seq)``, return ``seq[i]`` regardless of
- *x*. Otherwise return empty string. ``seq`` is the sequence of
- strings that this object was initialized with.
- """
- if pos is None or pos >= len(self.seq):
- return ''
- else:
- return self.seq[pos]
-
- def get_offset(self):
- return self.offset_string
-
- def set_offset_string(self, ofs):
- self.offset_string = ofs
-
-
-class FuncFormatter(Formatter):
- """
- Use a user-defined function for formatting.
-
- The function should take in two inputs (a tick value ``x`` and a
- position ``pos``), and return a string containing the corresponding
- tick label.
- """
-
- def __init__(self, func):
- self.func = func
- self.offset_string = ""
-
- def __call__(self, x, pos=None):
- """
- Return the value of the user defined function.
-
- *x* and *pos* are passed through as-is.
- """
- return self.func(x, pos)
-
- def get_offset(self):
- return self.offset_string
-
- def set_offset_string(self, ofs):
- self.offset_string = ofs
-
-
-class FormatStrFormatter(Formatter):
- """
- Use an old-style ('%' operator) format string to format the tick.
-
- The format string should have a single variable format (%) in it.
- It will be applied to the value (not the position) of the tick.
-
- Negative numeric values will use a dash, not a Unicode minus; use mathtext
- to get a Unicode minus by wrapping the format specifier with $ (e.g.
- "$%g$").
- """
- def __init__(self, fmt):
- self.fmt = fmt
-
- def __call__(self, x, pos=None):
- """
- Return the formatted label string.
-
- Only the value *x* is formatted. The position is ignored.
- """
- return self.fmt % x
-
-
-class StrMethodFormatter(Formatter):
- """
- Use a new-style format string (as used by `str.format`) to format the tick.
-
- The field used for the tick value must be labeled *x* and the field used
- for the tick position must be labeled *pos*.
- """
- def __init__(self, fmt):
- self.fmt = fmt
-
- def __call__(self, x, pos=None):
- """
- Return the formatted label string.
-
- *x* and *pos* are passed to `str.format` as keyword arguments
- with those exact names.
- """
- return self.fmt.format(x=x, pos=pos)
-
-
-class ScalarFormatter(Formatter):
- """
- Format tick values as a number.
-
- Parameters
- ----------
- useOffset : bool or float, default: :rc:`axes.formatter.useoffset`
- Whether to use offset notation. See `.set_useOffset`.
- useMathText : bool, default: :rc:`axes.formatter.use_mathtext`
- Whether to use fancy math formatting. See `.set_useMathText`.
- useLocale : bool, default: :rc:`axes.formatter.use_locale`.
- Whether to use locale settings for decimal sign and positive sign.
- See `.set_useLocale`.
-
- Notes
- -----
- In addition to the parameters above, the formatting of scientific vs.
- floating point representation can be configured via `.set_scientific`
- and `.set_powerlimits`).
-
- **Offset notation and scientific notation**
-
- Offset notation and scientific notation look quite similar at first sight.
- Both split some information from the formatted tick values and display it
- at the end of the axis.
-
- - The scientific notation splits up the order of magnitude, i.e. a
- multiplicative scaling factor, e.g. ``1e6``.
-
- - The offset notation separates an additive constant, e.g. ``+1e6``. The
- offset notation label is always prefixed with a ``+`` or ``-`` sign
- and is thus distinguishable from the order of magnitude label.
-
- The following plot with x limits ``1_000_000`` to ``1_000_010`` illustrates
- the different formatting. Note the labels at the right edge of the x axis.
-
- .. plot::
-
- lim = (1_000_000, 1_000_010)
-
- fig, (ax1, ax2, ax3) = plt.subplots(3, 1, gridspec_kw={'hspace': 2})
- ax1.set(title='offset_notation', xlim=lim)
- ax2.set(title='scientific notation', xlim=lim)
- ax2.xaxis.get_major_formatter().set_useOffset(False)
- ax3.set(title='floating point notation', xlim=lim)
- ax3.xaxis.get_major_formatter().set_useOffset(False)
- ax3.xaxis.get_major_formatter().set_scientific(False)
-
- """
-
- def __init__(self, useOffset=None, useMathText=None, useLocale=None):
- if useOffset is None:
- useOffset = mpl.rcParams['axes.formatter.useoffset']
- self._offset_threshold = \
- mpl.rcParams['axes.formatter.offset_threshold']
- self.set_useOffset(useOffset)
- self._usetex = mpl.rcParams['text.usetex']
- self.set_useMathText(useMathText)
- self.orderOfMagnitude = 0
- self.format = ''
- self._scientific = True
- self._powerlimits = mpl.rcParams['axes.formatter.limits']
- self.set_useLocale(useLocale)
-
- def get_useOffset(self):
- """
- Return whether automatic mode for offset notation is active.
-
- This returns True if ``set_useOffset(True)``; it returns False if an
- explicit offset was set, e.g. ``set_useOffset(1000)``.
-
- See Also
- --------
- ScalarFormatter.set_useOffset
- """
- return self._useOffset
-
- def set_useOffset(self, val):
- """
- Set whether to use offset notation.
-
- When formatting a set numbers whose value is large compared to their
- range, the formatter can separate an additive constant. This can
- shorten the formatted numbers so that they are less likely to overlap
- when drawn on an axis.
-
- Parameters
- ----------
- val : bool or float
- - If False, do not use offset notation.
- - If True (=automatic mode), use offset notation if it can make
- the residual numbers significantly shorter. The exact behavior
- is controlled by :rc:`axes.formatter.offset_threshold`.
- - If a number, force an offset of the given value.
-
- Examples
- --------
- With active offset notation, the values
-
- ``100_000, 100_002, 100_004, 100_006, 100_008``
-
- will be formatted as ``0, 2, 4, 6, 8`` plus an offset ``+1e5``, which
- is written to the edge of the axis.
- """
- if val in [True, False]:
- self.offset = 0
- self._useOffset = val
- else:
- self._useOffset = False
- self.offset = val
-
- useOffset = property(fget=get_useOffset, fset=set_useOffset)
-
- def get_useLocale(self):
- """
- Return whether locale settings are used for formatting.
-
- See Also
- --------
- ScalarFormatter.set_useLocale
- """
- return self._useLocale
-
- def set_useLocale(self, val):
- """
- Set whether to use locale settings for decimal sign and positive sign.
-
- Parameters
- ----------
- val : bool or None
- *None* resets to :rc:`axes.formatter.use_locale`.
- """
- if val is None:
- self._useLocale = mpl.rcParams['axes.formatter.use_locale']
- else:
- self._useLocale = val
-
- useLocale = property(fget=get_useLocale, fset=set_useLocale)
-
- def _format_maybe_minus_and_locale(self, fmt, arg):
- """
- Format *arg* with *fmt*, applying Unicode minus and locale if desired.
- """
- return self.fix_minus(
- # Escape commas introduced by locale.format_string if using math text,
- # but not those present from the beginning in fmt.
- (",".join(locale.format_string(part, (arg,), True).replace(",", "{,}")
- for part in fmt.split(",")) if self._useMathText
- else locale.format_string(fmt, (arg,), True))
- if self._useLocale
- else fmt % arg)
-
- def get_useMathText(self):
- """
- Return whether to use fancy math formatting.
-
- See Also
- --------
- ScalarFormatter.set_useMathText
- """
- return self._useMathText
-
- def set_useMathText(self, val):
- r"""
- Set whether to use fancy math formatting.
-
- If active, scientific notation is formatted as :math:`1.2 \times 10^3`.
-
- Parameters
- ----------
- val : bool or None
- *None* resets to :rc:`axes.formatter.use_mathtext`.
- """
- if val is None:
- self._useMathText = mpl.rcParams['axes.formatter.use_mathtext']
- if self._useMathText is False:
- try:
- from matplotlib import font_manager
- ufont = font_manager.findfont(
- font_manager.FontProperties(
- mpl.rcParams["font.family"]
- ),
- fallback_to_default=False,
- )
- except ValueError:
- ufont = None
-
- if ufont == str(cbook._get_data_path("fonts/ttf/cmr10.ttf")):
- _api.warn_external(
- "cmr10 font should ideally be used with "
- "mathtext, set axes.formatter.use_mathtext to True"
- )
- else:
- self._useMathText = val
-
- useMathText = property(fget=get_useMathText, fset=set_useMathText)
-
- def __call__(self, x, pos=None):
- """
- Return the format for tick value *x* at position *pos*.
- """
- if len(self.locs) == 0:
- return ''
- else:
- xp = (x - self.offset) / (10. ** self.orderOfMagnitude)
- if abs(xp) < 1e-8:
- xp = 0
- return self._format_maybe_minus_and_locale(self.format, xp)
-
- def set_scientific(self, b):
- """
- Turn scientific notation on or off.
-
- See Also
- --------
- ScalarFormatter.set_powerlimits
- """
- self._scientific = bool(b)
-
- def set_powerlimits(self, lims):
- r"""
- Set size thresholds for scientific notation.
-
- Parameters
- ----------
- lims : (int, int)
- A tuple *(min_exp, max_exp)* containing the powers of 10 that
- determine the switchover threshold. For a number representable as
- :math:`a \times 10^\mathrm{exp}` with :math:`1 <= |a| < 10`,
- scientific notation will be used if ``exp <= min_exp`` or
- ``exp >= max_exp``.
-
- The default limits are controlled by :rc:`axes.formatter.limits`.
-
- In particular numbers with *exp* equal to the thresholds are
- written in scientific notation.
-
- Typically, *min_exp* will be negative and *max_exp* will be
- positive.
-
- For example, ``formatter.set_powerlimits((-3, 4))`` will provide
- the following formatting:
- :math:`1 \times 10^{-3}, 9.9 \times 10^{-3}, 0.01,`
- :math:`9999, 1 \times 10^4`.
-
- See Also
- --------
- ScalarFormatter.set_scientific
- """
- if len(lims) != 2:
- raise ValueError("'lims' must be a sequence of length 2")
- self._powerlimits = lims
-
- def format_data_short(self, value):
- # docstring inherited
- if value is np.ma.masked:
- return ""
- if isinstance(value, Integral):
- fmt = "%d"
- else:
- if getattr(self.axis, "__name__", "") in ["xaxis", "yaxis"]:
- if self.axis.__name__ == "xaxis":
- axis_trf = self.axis.axes.get_xaxis_transform()
- axis_inv_trf = axis_trf.inverted()
- screen_xy = axis_trf.transform((value, 0))
- neighbor_values = axis_inv_trf.transform(
- screen_xy + [[-1, 0], [+1, 0]])[:, 0]
- else: # yaxis:
- axis_trf = self.axis.axes.get_yaxis_transform()
- axis_inv_trf = axis_trf.inverted()
- screen_xy = axis_trf.transform((0, value))
- neighbor_values = axis_inv_trf.transform(
- screen_xy + [[0, -1], [0, +1]])[:, 1]
- delta = abs(neighbor_values - value).max()
- else:
- # Rough approximation: no more than 1e4 divisions.
- a, b = self.axis.get_view_interval()
- delta = (b - a) / 1e4
- fmt = f"%-#.{cbook._g_sig_digits(value, delta)}g"
- return self._format_maybe_minus_and_locale(fmt, value)
-
- def format_data(self, value):
- # docstring inherited
- e = math.floor(math.log10(abs(value)))
- s = round(value / 10**e, 10)
- significand = self._format_maybe_minus_and_locale(
- "%d" if s % 1 == 0 else "%1.10g", s)
- if e == 0:
- return significand
- exponent = self._format_maybe_minus_and_locale("%d", e)
- if self._useMathText or self._usetex:
- exponent = "10^{%s}" % exponent
- return (exponent if s == 1 # reformat 1x10^y as 10^y
- else rf"{significand} \times {exponent}")
- else:
- return f"{significand}e{exponent}"
-
- def get_offset(self):
- """
- Return scientific notation, plus offset.
- """
- if len(self.locs) == 0:
- return ''
- if self.orderOfMagnitude or self.offset:
- offsetStr = ''
- sciNotStr = ''
- if self.offset:
- offsetStr = self.format_data(self.offset)
- if self.offset > 0:
- offsetStr = '+' + offsetStr
- if self.orderOfMagnitude:
- if self._usetex or self._useMathText:
- sciNotStr = self.format_data(10 ** self.orderOfMagnitude)
- else:
- sciNotStr = '1e%d' % self.orderOfMagnitude
- if self._useMathText or self._usetex:
- if sciNotStr != '':
- sciNotStr = r'\times\mathdefault{%s}' % sciNotStr
- s = fr'${sciNotStr}\mathdefault{{{offsetStr}}}$'
- else:
- s = ''.join((sciNotStr, offsetStr))
- return self.fix_minus(s)
- return ''
-
- def set_locs(self, locs):
- # docstring inherited
- self.locs = locs
- if len(self.locs) > 0:
- if self._useOffset:
- self._compute_offset()
- self._set_order_of_magnitude()
- self._set_format()
-
- def _compute_offset(self):
- locs = self.locs
- # Restrict to visible ticks.
- vmin, vmax = sorted(self.axis.get_view_interval())
- locs = np.asarray(locs)
- locs = locs[(vmin <= locs) & (locs <= vmax)]
- if not len(locs):
- self.offset = 0
- return
- lmin, lmax = locs.min(), locs.max()
- # Only use offset if there are at least two ticks and every tick has
- # the same sign.
- if lmin == lmax or lmin <= 0 <= lmax:
- self.offset = 0
- return
- # min, max comparing absolute values (we want division to round towards
- # zero so we work on absolute values).
- abs_min, abs_max = sorted([abs(float(lmin)), abs(float(lmax))])
- sign = math.copysign(1, lmin)
- # What is the smallest power of ten such that abs_min and abs_max are
- # equal up to that precision?
- # Note: Internally using oom instead of 10 ** oom avoids some numerical
- # accuracy issues.
- oom_max = np.ceil(math.log10(abs_max))
- oom = 1 + next(oom for oom in itertools.count(oom_max, -1)
- if abs_min // 10 ** oom != abs_max // 10 ** oom)
- if (abs_max - abs_min) / 10 ** oom <= 1e-2:
- # Handle the case of straddling a multiple of a large power of ten
- # (relative to the span).
- # What is the smallest power of ten such that abs_min and abs_max
- # are no more than 1 apart at that precision?
- oom = 1 + next(oom for oom in itertools.count(oom_max, -1)
- if abs_max // 10 ** oom - abs_min // 10 ** oom > 1)
- # Only use offset if it saves at least _offset_threshold digits.
- n = self._offset_threshold - 1
- self.offset = (sign * (abs_max // 10 ** oom) * 10 ** oom
- if abs_max // 10 ** oom >= 10**n
- else 0)
-
- def _set_order_of_magnitude(self):
- # if scientific notation is to be used, find the appropriate exponent
- # if using a numerical offset, find the exponent after applying the
- # offset. When lower power limit = upper <> 0, use provided exponent.
- if not self._scientific:
- self.orderOfMagnitude = 0
- return
- if self._powerlimits[0] == self._powerlimits[1] != 0:
- # fixed scaling when lower power limit = upper <> 0.
- self.orderOfMagnitude = self._powerlimits[0]
- return
- # restrict to visible ticks
- vmin, vmax = sorted(self.axis.get_view_interval())
- locs = np.asarray(self.locs)
- locs = locs[(vmin <= locs) & (locs <= vmax)]
- locs = np.abs(locs)
- if not len(locs):
- self.orderOfMagnitude = 0
- return
- if self.offset:
- oom = math.floor(math.log10(vmax - vmin))
- else:
- val = locs.max()
- if val == 0:
- oom = 0
- else:
- oom = math.floor(math.log10(val))
- if oom <= self._powerlimits[0]:
- self.orderOfMagnitude = oom
- elif oom >= self._powerlimits[1]:
- self.orderOfMagnitude = oom
- else:
- self.orderOfMagnitude = 0
-
- def _set_format(self):
- # set the format string to format all the ticklabels
- if len(self.locs) < 2:
- # Temporarily augment the locations with the axis end points.
- _locs = [*self.locs, *self.axis.get_view_interval()]
- else:
- _locs = self.locs
- locs = (np.asarray(_locs) - self.offset) / 10. ** self.orderOfMagnitude
- loc_range = np.ptp(locs)
- # Curvilinear coordinates can yield two identical points.
- if loc_range == 0:
- loc_range = np.max(np.abs(locs))
- # Both points might be zero.
- if loc_range == 0:
- loc_range = 1
- if len(self.locs) < 2:
- # We needed the end points only for the loc_range calculation.
- locs = locs[:-2]
- loc_range_oom = int(math.floor(math.log10(loc_range)))
- # first estimate:
- sigfigs = max(0, 3 - loc_range_oom)
- # refined estimate:
- thresh = 1e-3 * 10 ** loc_range_oom
- while sigfigs >= 0:
- if np.abs(locs - np.round(locs, decimals=sigfigs)).max() < thresh:
- sigfigs -= 1
- else:
- break
- sigfigs += 1
- self.format = f'%1.{sigfigs}f'
- if self._usetex or self._useMathText:
- self.format = r'$\mathdefault{%s}$' % self.format
-
-
-class LogFormatter(Formatter):
- """
- Base class for formatting ticks on a log or symlog scale.
-
- It may be instantiated directly, or subclassed.
-
- Parameters
- ----------
- base : float, default: 10.
- Base of the logarithm used in all calculations.
-
- labelOnlyBase : bool, default: False
- If True, label ticks only at integer powers of base.
- This is normally True for major ticks and False for
- minor ticks.
-
- minor_thresholds : (subset, all), default: (1, 0.4)
- If labelOnlyBase is False, these two numbers control
- the labeling of ticks that are not at integer powers of
- base; normally these are the minor ticks. The controlling
- parameter is the log of the axis data range. In the typical
- case where base is 10 it is the number of decades spanned
- by the axis, so we can call it 'numdec'. If ``numdec <= all``,
- all minor ticks will be labeled. If ``all < numdec <= subset``,
- then only a subset of minor ticks will be labeled, so as to
- avoid crowding. If ``numdec > subset`` then no minor ticks will
- be labeled.
-
- linthresh : None or float, default: None
- If a symmetric log scale is in use, its ``linthresh``
- parameter must be supplied here.
-
- Notes
- -----
- The `set_locs` method must be called to enable the subsetting
- logic controlled by the ``minor_thresholds`` parameter.
-
- In some cases such as the colorbar, there is no distinction between
- major and minor ticks; the tick locations might be set manually,
- or by a locator that puts ticks at integer powers of base and
- at intermediate locations. For this situation, disable the
- minor_thresholds logic by using ``minor_thresholds=(np.inf, np.inf)``,
- so that all ticks will be labeled.
-
- To disable labeling of minor ticks when 'labelOnlyBase' is False,
- use ``minor_thresholds=(0, 0)``. This is the default for the
- "classic" style.
-
- Examples
- --------
- To label a subset of minor ticks when the view limits span up
- to 2 decades, and all of the ticks when zoomed in to 0.5 decades
- or less, use ``minor_thresholds=(2, 0.5)``.
-
- To label all minor ticks when the view limits span up to 1.5
- decades, use ``minor_thresholds=(1.5, 1.5)``.
- """
-
- def __init__(self, base=10.0, labelOnlyBase=False,
- minor_thresholds=None,
- linthresh=None):
-
- self.set_base(base)
- self.set_label_minor(labelOnlyBase)
- if minor_thresholds is None:
- if mpl.rcParams['_internal.classic_mode']:
- minor_thresholds = (0, 0)
- else:
- minor_thresholds = (1, 0.4)
- self.minor_thresholds = minor_thresholds
- self._sublabels = None
- self._linthresh = linthresh
-
- def set_base(self, base):
- """
- Change the *base* for labeling.
-
- .. warning::
- Should always match the base used for :class:`LogLocator`
- """
- self._base = float(base)
-
- def set_label_minor(self, labelOnlyBase):
- """
- Switch minor tick labeling on or off.
-
- Parameters
- ----------
- labelOnlyBase : bool
- If True, label ticks only at integer powers of base.
- """
- self.labelOnlyBase = labelOnlyBase
-
- def set_locs(self, locs=None):
- """
- Use axis view limits to control which ticks are labeled.
-
- The *locs* parameter is ignored in the present algorithm.
- """
- if np.isinf(self.minor_thresholds[0]):
- self._sublabels = None
- return
-
- # Handle symlog case:
- linthresh = self._linthresh
- if linthresh is None:
- try:
- linthresh = self.axis.get_transform().linthresh
- except AttributeError:
- pass
-
- vmin, vmax = self.axis.get_view_interval()
- if vmin > vmax:
- vmin, vmax = vmax, vmin
-
- if linthresh is None and vmin <= 0:
- # It's probably a colorbar with
- # a format kwarg setting a LogFormatter in the manner
- # that worked with 1.5.x, but that doesn't work now.
- self._sublabels = {1} # label powers of base
- return
-
- b = self._base
- if linthresh is not None: # symlog
- # Only compute the number of decades in the logarithmic part of the
- # axis
- numdec = 0
- if vmin < -linthresh:
- rhs = min(vmax, -linthresh)
- numdec += math.log(vmin / rhs) / math.log(b)
- if vmax > linthresh:
- lhs = max(vmin, linthresh)
- numdec += math.log(vmax / lhs) / math.log(b)
- else:
- vmin = math.log(vmin) / math.log(b)
- vmax = math.log(vmax) / math.log(b)
- numdec = abs(vmax - vmin)
-
- if numdec > self.minor_thresholds[0]:
- # Label only bases
- self._sublabels = {1}
- elif numdec > self.minor_thresholds[1]:
- # Add labels between bases at log-spaced coefficients;
- # include base powers in case the locations include
- # "major" and "minor" points, as in colorbar.
- c = np.geomspace(1, b, int(b)//2 + 1)
- self._sublabels = set(np.round(c))
- # For base 10, this yields (1, 2, 3, 4, 6, 10).
- else:
- # Label all integer multiples of base**n.
- self._sublabels = set(np.arange(1, b + 1))
-
- def _num_to_string(self, x, vmin, vmax):
- if x > 10000:
- s = '%1.0e' % x
- elif x < 1:
- s = '%1.0e' % x
- else:
- s = self._pprint_val(x, vmax - vmin)
- return s
-
- def __call__(self, x, pos=None):
- # docstring inherited
- if x == 0.0: # Symlog
- return '0'
-
- x = abs(x)
- b = self._base
- # only label the decades
- fx = math.log(x) / math.log(b)
- is_x_decade = _is_close_to_int(fx)
- exponent = round(fx) if is_x_decade else np.floor(fx)
- coeff = round(b ** (fx - exponent))
-
- if self.labelOnlyBase and not is_x_decade:
- return ''
- if self._sublabels is not None and coeff not in self._sublabels:
- return ''
-
- vmin, vmax = self.axis.get_view_interval()
- vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05)
- s = self._num_to_string(x, vmin, vmax)
- return self.fix_minus(s)
-
- def format_data(self, value):
- with cbook._setattr_cm(self, labelOnlyBase=False):
- return cbook.strip_math(self.__call__(value))
-
- def format_data_short(self, value):
- # docstring inherited
- return '%-12g' % value
-
- def _pprint_val(self, x, d):
- # If the number is not too big and it's an int, format it as an int.
- if abs(x) < 1e4 and x == int(x):
- return '%d' % x
- fmt = ('%1.3e' if d < 1e-2 else
- '%1.3f' if d <= 1 else
- '%1.2f' if d <= 10 else
- '%1.1f' if d <= 1e5 else
- '%1.1e')
- s = fmt % x
- tup = s.split('e')
- if len(tup) == 2:
- mantissa = tup[0].rstrip('0').rstrip('.')
- exponent = int(tup[1])
- if exponent:
- s = '%se%d' % (mantissa, exponent)
- else:
- s = mantissa
- else:
- s = s.rstrip('0').rstrip('.')
- return s
-
-
-class LogFormatterExponent(LogFormatter):
- """
- Format values for log axis using ``exponent = log_base(value)``.
- """
- def _num_to_string(self, x, vmin, vmax):
- fx = math.log(x) / math.log(self._base)
- if abs(fx) > 10000:
- s = '%1.0g' % fx
- elif abs(fx) < 1:
- s = '%1.0g' % fx
- else:
- fd = math.log(vmax - vmin) / math.log(self._base)
- s = self._pprint_val(fx, fd)
- return s
-
-
-class LogFormatterMathtext(LogFormatter):
- """
- Format values for log axis using ``exponent = log_base(value)``.
- """
-
- def _non_decade_format(self, sign_string, base, fx, usetex):
- """Return string for non-decade locations."""
- return r'$\mathdefault{%s%s^{%.2f}}$' % (sign_string, base, fx)
-
- def __call__(self, x, pos=None):
- # docstring inherited
- if x == 0: # Symlog
- return r'$\mathdefault{0}$'
-
- sign_string = '-' if x < 0 else ''
- x = abs(x)
- b = self._base
-
- # only label the decades
- fx = math.log(x) / math.log(b)
- is_x_decade = _is_close_to_int(fx)
- exponent = round(fx) if is_x_decade else np.floor(fx)
- coeff = round(b ** (fx - exponent))
-
- if self.labelOnlyBase and not is_x_decade:
- return ''
- if self._sublabels is not None and coeff not in self._sublabels:
- return ''
-
- if is_x_decade:
- fx = round(fx)
-
- # use string formatting of the base if it is not an integer
- if b % 1 == 0.0:
- base = '%d' % b
- else:
- base = '%s' % b
-
- if abs(fx) < mpl.rcParams['axes.formatter.min_exponent']:
- return r'$\mathdefault{%s%g}$' % (sign_string, x)
- elif not is_x_decade:
- usetex = mpl.rcParams['text.usetex']
- return self._non_decade_format(sign_string, base, fx, usetex)
- else:
- return r'$\mathdefault{%s%s^{%d}}$' % (sign_string, base, fx)
-
-
-class LogFormatterSciNotation(LogFormatterMathtext):
- """
- Format values following scientific notation in a logarithmic axis.
- """
-
- def _non_decade_format(self, sign_string, base, fx, usetex):
- """Return string for non-decade locations."""
- b = float(base)
- exponent = math.floor(fx)
- coeff = b ** (fx - exponent)
- if _is_close_to_int(coeff):
- coeff = round(coeff)
- return r'$\mathdefault{%s%g\times%s^{%d}}$' \
- % (sign_string, coeff, base, exponent)
-
-
-class LogitFormatter(Formatter):
- """
- Probability formatter (using Math text).
- """
-
- def __init__(
- self,
- *,
- use_overline=False,
- one_half=r"\frac{1}{2}",
- minor=False,
- minor_threshold=25,
- minor_number=6,
- ):
- r"""
- Parameters
- ----------
- use_overline : bool, default: False
- If x > 1/2, with x = 1-v, indicate if x should be displayed as
- $\overline{v}$. The default is to display $1-v$.
-
- one_half : str, default: r"\frac{1}{2}"
- The string used to represent 1/2.
-
- minor : bool, default: False
- Indicate if the formatter is formatting minor ticks or not.
- Basically minor ticks are not labelled, except when only few ticks
- are provided, ticks with most space with neighbor ticks are
- labelled. See other parameters to change the default behavior.
-
- minor_threshold : int, default: 25
- Maximum number of locs for labelling some minor ticks. This
- parameter have no effect if minor is False.
-
- minor_number : int, default: 6
- Number of ticks which are labelled when the number of ticks is
- below the threshold.
- """
- self._use_overline = use_overline
- self._one_half = one_half
- self._minor = minor
- self._labelled = set()
- self._minor_threshold = minor_threshold
- self._minor_number = minor_number
-
- def use_overline(self, use_overline):
- r"""
- Switch display mode with overline for labelling p>1/2.
-
- Parameters
- ----------
- use_overline : bool, default: False
- If x > 1/2, with x = 1-v, indicate if x should be displayed as
- $\overline{v}$. The default is to display $1-v$.
- """
- self._use_overline = use_overline
-
- def set_one_half(self, one_half):
- r"""
- Set the way one half is displayed.
-
- one_half : str, default: r"\frac{1}{2}"
- The string used to represent 1/2.
- """
- self._one_half = one_half
-
- def set_minor_threshold(self, minor_threshold):
- """
- Set the threshold for labelling minors ticks.
-
- Parameters
- ----------
- minor_threshold : int
- Maximum number of locations for labelling some minor ticks. This
- parameter have no effect if minor is False.
- """
- self._minor_threshold = minor_threshold
-
- def set_minor_number(self, minor_number):
- """
- Set the number of minor ticks to label when some minor ticks are
- labelled.
-
- Parameters
- ----------
- minor_number : int
- Number of ticks which are labelled when the number of ticks is
- below the threshold.
- """
- self._minor_number = minor_number
-
- def set_locs(self, locs):
- self.locs = np.array(locs)
- self._labelled.clear()
-
- if not self._minor:
- return None
- if all(
- _is_decade(x, rtol=1e-7)
- or _is_decade(1 - x, rtol=1e-7)
- or (_is_close_to_int(2 * x) and
- int(np.round(2 * x)) == 1)
- for x in locs
- ):
- # minor ticks are subsample from ideal, so no label
- return None
- if len(locs) < self._minor_threshold:
- if len(locs) < self._minor_number:
- self._labelled.update(locs)
- else:
- # we do not have a lot of minor ticks, so only few decades are
- # displayed, then we choose some (spaced) minor ticks to label.
- # Only minor ticks are known, we assume it is sufficient to
- # choice which ticks are displayed.
- # For each ticks we compute the distance between the ticks and
- # the previous, and between the ticks and the next one. Ticks
- # with smallest minimum are chosen. As tiebreak, the ticks
- # with smallest sum is chosen.
- diff = np.diff(-np.log(1 / self.locs - 1))
- space_pessimistic = np.minimum(
- np.concatenate(((np.inf,), diff)),
- np.concatenate((diff, (np.inf,))),
- )
- space_sum = (
- np.concatenate(((0,), diff))
- + np.concatenate((diff, (0,)))
- )
- good_minor = sorted(
- range(len(self.locs)),
- key=lambda i: (space_pessimistic[i], space_sum[i]),
- )[-self._minor_number:]
- self._labelled.update(locs[i] for i in good_minor)
-
- def _format_value(self, x, locs, sci_notation=True):
- if sci_notation:
- exponent = math.floor(np.log10(x))
- min_precision = 0
- else:
- exponent = 0
- min_precision = 1
- value = x * 10 ** (-exponent)
- if len(locs) < 2:
- precision = min_precision
- else:
- diff = np.sort(np.abs(locs - x))[1]
- precision = -np.log10(diff) + exponent
- precision = (
- int(np.round(precision))
- if _is_close_to_int(precision)
- else math.ceil(precision)
- )
- if precision < min_precision:
- precision = min_precision
- mantissa = r"%.*f" % (precision, value)
- if not sci_notation:
- return mantissa
- s = r"%s\cdot10^{%d}" % (mantissa, exponent)
- return s
-
- def _one_minus(self, s):
- if self._use_overline:
- return r"\overline{%s}" % s
- else:
- return f"1-{s}"
-
- def __call__(self, x, pos=None):
- if self._minor and x not in self._labelled:
- return ""
- if x <= 0 or x >= 1:
- return ""
- if _is_close_to_int(2 * x) and round(2 * x) == 1:
- s = self._one_half
- elif x < 0.5 and _is_decade(x, rtol=1e-7):
- exponent = round(math.log10(x))
- s = "10^{%d}" % exponent
- elif x > 0.5 and _is_decade(1 - x, rtol=1e-7):
- exponent = round(math.log10(1 - x))
- s = self._one_minus("10^{%d}" % exponent)
- elif x < 0.1:
- s = self._format_value(x, self.locs)
- elif x > 0.9:
- s = self._one_minus(self._format_value(1-x, 1-self.locs))
- else:
- s = self._format_value(x, self.locs, sci_notation=False)
- return r"$\mathdefault{%s}$" % s
-
- def format_data_short(self, value):
- # docstring inherited
- # Thresholds chosen to use scientific notation iff exponent <= -2.
- if value < 0.1:
- return f"{value:e}"
- if value < 0.9:
- return f"{value:f}"
- return f"1-{1 - value:e}"
-
-
-class EngFormatter(Formatter):
- """
- Format axis values using engineering prefixes to represent powers
- of 1000, plus a specified unit, e.g., 10 MHz instead of 1e7.
- """
-
- # The SI engineering prefixes
- ENG_PREFIXES = {
- -30: "q",
- -27: "r",
- -24: "y",
- -21: "z",
- -18: "a",
- -15: "f",
- -12: "p",
- -9: "n",
- -6: "\N{MICRO SIGN}",
- -3: "m",
- 0: "",
- 3: "k",
- 6: "M",
- 9: "G",
- 12: "T",
- 15: "P",
- 18: "E",
- 21: "Z",
- 24: "Y",
- 27: "R",
- 30: "Q"
- }
-
- def __init__(self, unit="", places=None, sep=" ", *, usetex=None,
- useMathText=None):
- r"""
- Parameters
- ----------
- unit : str, default: ""
- Unit symbol to use, suitable for use with single-letter
- representations of powers of 1000. For example, 'Hz' or 'm'.
-
- places : int, default: None
- Precision with which to display the number, specified in
- digits after the decimal point (there will be between one
- and three digits before the decimal point). If it is None,
- the formatting falls back to the floating point format '%g',
- which displays up to 6 *significant* digits, i.e. the equivalent
- value for *places* varies between 0 and 5 (inclusive).
-
- sep : str, default: " "
- Separator used between the value and the prefix/unit. For
- example, one get '3.14 mV' if ``sep`` is " " (default) and
- '3.14mV' if ``sep`` is "". Besides the default behavior, some
- other useful options may be:
-
- * ``sep=""`` to append directly the prefix/unit to the value;
- * ``sep="\N{THIN SPACE}"`` (``U+2009``);
- * ``sep="\N{NARROW NO-BREAK SPACE}"`` (``U+202F``);
- * ``sep="\N{NO-BREAK SPACE}"`` (``U+00A0``).
-
- usetex : bool, default: :rc:`text.usetex`
- To enable/disable the use of TeX's math mode for rendering the
- numbers in the formatter.
-
- useMathText : bool, default: :rc:`axes.formatter.use_mathtext`
- To enable/disable the use mathtext for rendering the numbers in
- the formatter.
- """
- self.unit = unit
- self.places = places
- self.sep = sep
- self.set_usetex(usetex)
- self.set_useMathText(useMathText)
-
- def get_usetex(self):
- return self._usetex
-
- def set_usetex(self, val):
- if val is None:
- self._usetex = mpl.rcParams['text.usetex']
- else:
- self._usetex = val
-
- usetex = property(fget=get_usetex, fset=set_usetex)
-
- def get_useMathText(self):
- return self._useMathText
-
- def set_useMathText(self, val):
- if val is None:
- self._useMathText = mpl.rcParams['axes.formatter.use_mathtext']
- else:
- self._useMathText = val
-
- useMathText = property(fget=get_useMathText, fset=set_useMathText)
-
- def __call__(self, x, pos=None):
- s = f"{self.format_eng(x)}{self.unit}"
- # Remove the trailing separator when there is neither prefix nor unit
- if self.sep and s.endswith(self.sep):
- s = s[:-len(self.sep)]
- return self.fix_minus(s)
-
- def format_eng(self, num):
- """
- Format a number in engineering notation, appending a letter
- representing the power of 1000 of the original number.
- Some examples:
-
- >>> format_eng(0) # for self.places = 0
- '0'
-
- >>> format_eng(1000000) # for self.places = 1
- '1.0 M'
-
- >>> format_eng(-1e-6) # for self.places = 2
- '-1.00 \N{MICRO SIGN}'
- """
- sign = 1
- fmt = "g" if self.places is None else f".{self.places:d}f"
-
- if num < 0:
- sign = -1
- num = -num
-
- if num != 0:
- pow10 = int(math.floor(math.log10(num) / 3) * 3)
- else:
- pow10 = 0
- # Force num to zero, to avoid inconsistencies like
- # format_eng(-0) = "0" and format_eng(0.0) = "0"
- # but format_eng(-0.0) = "-0.0"
- num = 0.0
-
- pow10 = np.clip(pow10, min(self.ENG_PREFIXES), max(self.ENG_PREFIXES))
-
- mant = sign * num / (10.0 ** pow10)
- # Taking care of the cases like 999.9..., which may be rounded to 1000
- # instead of 1 k. Beware of the corner case of values that are beyond
- # the range of SI prefixes (i.e. > 'Y').
- if (abs(float(format(mant, fmt))) >= 1000
- and pow10 < max(self.ENG_PREFIXES)):
- mant /= 1000
- pow10 += 3
-
- prefix = self.ENG_PREFIXES[int(pow10)]
- if self._usetex or self._useMathText:
- formatted = f"${mant:{fmt}}${self.sep}{prefix}"
- else:
- formatted = f"{mant:{fmt}}{self.sep}{prefix}"
-
- return formatted
-
-
-class PercentFormatter(Formatter):
- """
- Format numbers as a percentage.
-
- Parameters
- ----------
- xmax : float
- Determines how the number is converted into a percentage.
- *xmax* is the data value that corresponds to 100%.
- Percentages are computed as ``x / xmax * 100``. So if the data is
- already scaled to be percentages, *xmax* will be 100. Another common
- situation is where *xmax* is 1.0.
-
- decimals : None or int
- The number of decimal places to place after the point.
- If *None* (the default), the number will be computed automatically.
-
- symbol : str or None
- A string that will be appended to the label. It may be
- *None* or empty to indicate that no symbol should be used. LaTeX
- special characters are escaped in *symbol* whenever latex mode is
- enabled, unless *is_latex* is *True*.
-
- is_latex : bool
- If *False*, reserved LaTeX characters in *symbol* will be escaped.
- """
- def __init__(self, xmax=100, decimals=None, symbol='%', is_latex=False):
- self.xmax = xmax + 0.0
- self.decimals = decimals
- self._symbol = symbol
- self._is_latex = is_latex
-
- def __call__(self, x, pos=None):
- """Format the tick as a percentage with the appropriate scaling."""
- ax_min, ax_max = self.axis.get_view_interval()
- display_range = abs(ax_max - ax_min)
- return self.fix_minus(self.format_pct(x, display_range))
-
- def format_pct(self, x, display_range):
- """
- Format the number as a percentage number with the correct
- number of decimals and adds the percent symbol, if any.
-
- If ``self.decimals`` is `None`, the number of digits after the
- decimal point is set based on the *display_range* of the axis
- as follows:
-
- ============= ======== =======================
- display_range decimals sample
- ============= ======== =======================
- >50 0 ``x = 34.5`` => 35%
- >5 1 ``x = 34.5`` => 34.5%
- >0.5 2 ``x = 34.5`` => 34.50%
- ... ... ...
- ============= ======== =======================
-
- This method will not be very good for tiny axis ranges or
- extremely large ones. It assumes that the values on the chart
- are percentages displayed on a reasonable scale.
- """
- x = self.convert_to_pct(x)
- if self.decimals is None:
- # conversion works because display_range is a difference
- scaled_range = self.convert_to_pct(display_range)
- if scaled_range <= 0:
- decimals = 0
- else:
- # Luckily Python's built-in ceil rounds to +inf, not away from
- # zero. This is very important since the equation for decimals
- # starts out as `scaled_range > 0.5 * 10**(2 - decimals)`
- # and ends up with `decimals > 2 - log10(2 * scaled_range)`.
- decimals = math.ceil(2.0 - math.log10(2.0 * scaled_range))
- if decimals > 5:
- decimals = 5
- elif decimals < 0:
- decimals = 0
- else:
- decimals = self.decimals
- s = f'{x:0.{int(decimals)}f}'
-
- return s + self.symbol
-
- def convert_to_pct(self, x):
- return 100.0 * (x / self.xmax)
-
- @property
- def symbol(self):
- r"""
- The configured percent symbol as a string.
-
- If LaTeX is enabled via :rc:`text.usetex`, the special characters
- ``{'#', '$', '%', '&', '~', '_', '^', '\', '{', '}'}`` are
- automatically escaped in the string.
- """
- symbol = self._symbol
- if not symbol:
- symbol = ''
- elif not self._is_latex and mpl.rcParams['text.usetex']:
- # Source: http://www.personal.ceu.hu/tex/specchar.htm
- # Backslash must be first for this to work correctly since
- # it keeps getting added in
- for spec in r'\#$%&~_^{}':
- symbol = symbol.replace(spec, '\\' + spec)
- return symbol
-
- @symbol.setter
- def symbol(self, symbol):
- self._symbol = symbol
-
-
-class Locator(TickHelper):
- """
- Determine the tick locations;
-
- Note that the same locator should not be used across multiple
- `~matplotlib.axis.Axis` because the locator stores references to the Axis
- data and view limits.
- """
-
- # Some automatic tick locators can generate so many ticks they
- # kill the machine when you try and render them.
- # This parameter is set to cause locators to raise an error if too
- # many ticks are generated.
- MAXTICKS = 1000
-
- def tick_values(self, vmin, vmax):
- """
- Return the values of the located ticks given **vmin** and **vmax**.
-
- .. note::
- To get tick locations with the vmin and vmax values defined
- automatically for the associated ``axis`` simply call
- the Locator instance::
-
- >>> print(type(loc))
- <type 'Locator'>
- >>> print(loc())
- [1, 2, 3, 4]
-
- """
- raise NotImplementedError('Derived must override')
-
- def set_params(self, **kwargs):
- """
- Do nothing, and raise a warning. Any locator class not supporting the
- set_params() function will call this.
- """
- _api.warn_external(
- "'set_params()' not defined for locator of type " +
- str(type(self)))
-
- def __call__(self):
- """Return the locations of the ticks."""
- # note: some locators return data limits, other return view limits,
- # hence there is no *one* interface to call self.tick_values.
- raise NotImplementedError('Derived must override')
-
- def raise_if_exceeds(self, locs):
- """
- Log at WARNING level if *locs* is longer than `Locator.MAXTICKS`.
-
- This is intended to be called immediately before returning *locs* from
- ``__call__`` to inform users in case their Locator returns a huge
- number of ticks, causing Matplotlib to run out of memory.
-
- The "strange" name of this method dates back to when it would raise an
- exception instead of emitting a log.
- """
- if len(locs) >= self.MAXTICKS:
- _log.warning(
- "Locator attempting to generate %s ticks ([%s, ..., %s]), "
- "which exceeds Locator.MAXTICKS (%s).",
- len(locs), locs[0], locs[-1], self.MAXTICKS)
- return locs
-
- def nonsingular(self, v0, v1):
- """
- Adjust a range as needed to avoid singularities.
-
- This method gets called during autoscaling, with ``(v0, v1)`` set to
- the data limits on the axes if the axes contains any data, or
- ``(-inf, +inf)`` if not.
-
- - If ``v0 == v1`` (possibly up to some floating point slop), this
- method returns an expanded interval around this value.
- - If ``(v0, v1) == (-inf, +inf)``, this method returns appropriate
- default view limits.
- - Otherwise, ``(v0, v1)`` is returned without modification.
- """
- return mtransforms.nonsingular(v0, v1, expander=.05)
-
- def view_limits(self, vmin, vmax):
- """
- Select a scale for the range from vmin to vmax.
-
- Subclasses should override this method to change locator behaviour.
- """
- return mtransforms.nonsingular(vmin, vmax)
-
-
-class IndexLocator(Locator):
- """
- Place a tick on every multiple of some base number of points
- plotted, e.g., on every 5th point. It is assumed that you are doing
- index plotting; i.e., the axis is 0, len(data). This is mainly
- useful for x ticks.
- """
- def __init__(self, base, offset):
- """Place ticks every *base* data point, starting at *offset*."""
- self._base = base
- self.offset = offset
-
- def set_params(self, base=None, offset=None):
- """Set parameters within this locator"""
- if base is not None:
- self._base = base
- if offset is not None:
- self.offset = offset
-
- def __call__(self):
- """Return the locations of the ticks"""
- dmin, dmax = self.axis.get_data_interval()
- return self.tick_values(dmin, dmax)
-
- def tick_values(self, vmin, vmax):
- return self.raise_if_exceeds(
- np.arange(vmin + self.offset, vmax + 1, self._base))
-
-
-class FixedLocator(Locator):
- """
- Tick locations are fixed at *locs*. If *nbins* is not None,
- the *locs* array of possible positions will be subsampled to
- keep the number of ticks <= *nbins* +1.
- The subsampling will be done to include the smallest
- absolute value; for example, if zero is included in the
- array of possibilities, then it is guaranteed to be one of
- the chosen ticks.
- """
-
- def __init__(self, locs, nbins=None):
- self.locs = np.asarray(locs)
- _api.check_shape((None,), locs=self.locs)
- self.nbins = max(nbins, 2) if nbins is not None else None
-
- def set_params(self, nbins=None):
- """Set parameters within this locator."""
- if nbins is not None:
- self.nbins = nbins
-
- def __call__(self):
- return self.tick_values(None, None)
-
- def tick_values(self, vmin, vmax):
- """
- Return the locations of the ticks.
-
- .. note::
-
- Because the values are fixed, vmin and vmax are not used in this
- method.
-
- """
- if self.nbins is None:
- return self.locs
- step = max(int(np.ceil(len(self.locs) / self.nbins)), 1)
- ticks = self.locs[::step]
- for i in range(1, step):
- ticks1 = self.locs[i::step]
- if np.abs(ticks1).min() < np.abs(ticks).min():
- ticks = ticks1
- return self.raise_if_exceeds(ticks)
-
-
-class NullLocator(Locator):
- """
- No ticks
- """
-
- def __call__(self):
- return self.tick_values(None, None)
-
- def tick_values(self, vmin, vmax):
- """
- Return the locations of the ticks.
-
- .. note::
-
- Because the values are Null, vmin and vmax are not used in this
- method.
- """
- return []
-
-
-class LinearLocator(Locator):
- """
- Determine the tick locations
-
- The first time this function is called it will try to set the
- number of ticks to make a nice tick partitioning. Thereafter, the
- number of ticks will be fixed so that interactive navigation will
- be nice
-
- """
- def __init__(self, numticks=None, presets=None):
- """
- Parameters
- ----------
- numticks : int or None, default None
- Number of ticks. If None, *numticks* = 11.
- presets : dict or None, default: None
- Dictionary mapping ``(vmin, vmax)`` to an array of locations.
- Overrides *numticks* if there is an entry for the current
- ``(vmin, vmax)``.
- """
- self.numticks = numticks
- if presets is None:
- self.presets = {}
- else:
- self.presets = presets
-
- @property
- def numticks(self):
- # Old hard-coded default.
- return self._numticks if self._numticks is not None else 11
-
- @numticks.setter
- def numticks(self, numticks):
- self._numticks = numticks
-
- def set_params(self, numticks=None, presets=None):
- """Set parameters within this locator."""
- if presets is not None:
- self.presets = presets
- if numticks is not None:
- self.numticks = numticks
-
- def __call__(self):
- """Return the locations of the ticks."""
- vmin, vmax = self.axis.get_view_interval()
- return self.tick_values(vmin, vmax)
-
- def tick_values(self, vmin, vmax):
- vmin, vmax = mtransforms.nonsingular(vmin, vmax, expander=0.05)
-
- if (vmin, vmax) in self.presets:
- return self.presets[(vmin, vmax)]
-
- if self.numticks == 0:
- return []
- ticklocs = np.linspace(vmin, vmax, self.numticks)
-
- return self.raise_if_exceeds(ticklocs)
-
- def view_limits(self, vmin, vmax):
- """Try to choose the view limits intelligently."""
-
- if vmax < vmin:
- vmin, vmax = vmax, vmin
-
- if vmin == vmax:
- vmin -= 1
- vmax += 1
-
- if mpl.rcParams['axes.autolimit_mode'] == 'round_numbers':
- exponent, remainder = divmod(
- math.log10(vmax - vmin), math.log10(max(self.numticks - 1, 1)))
- exponent -= (remainder < .5)
- scale = max(self.numticks - 1, 1) ** (-exponent)
- vmin = math.floor(scale * vmin) / scale
- vmax = math.ceil(scale * vmax) / scale
-
- return mtransforms.nonsingular(vmin, vmax)
-
-
-class MultipleLocator(Locator):
- """
- Set a tick on each integer multiple of the *base* plus an *offset* within
- the view interval.
- """
-
- def __init__(self, base=1.0, offset=0.0):
- """
- Parameters
- ----------
- base : float > 0
- Interval between ticks.
- offset : float
- Value added to each multiple of *base*.
-
- .. versionadded:: 3.8
- """
- self._edge = _Edge_integer(base, 0)
- self._offset = offset
-
- def set_params(self, base=None, offset=None):
- """
- Set parameters within this locator.
-
- Parameters
- ----------
- base : float > 0
- Interval between ticks.
- offset : float
- Value added to each multiple of *base*.
-
- .. versionadded:: 3.8
- """
- if base is not None:
- self._edge = _Edge_integer(base, 0)
- if offset is not None:
- self._offset = offset
-
- def __call__(self):
- """Return the locations of the ticks."""
- vmin, vmax = self.axis.get_view_interval()
- return self.tick_values(vmin, vmax)
-
- def tick_values(self, vmin, vmax):
- if vmax < vmin:
- vmin, vmax = vmax, vmin
- step = self._edge.step
- vmin -= self._offset
- vmax -= self._offset
- vmin = self._edge.ge(vmin) * step
- n = (vmax - vmin + 0.001 * step) // step
- locs = vmin - step + np.arange(n + 3) * step + self._offset
- return self.raise_if_exceeds(locs)
-
- def view_limits(self, dmin, dmax):
- """
- Set the view limits to the nearest tick values that contain the data.
- """
- if mpl.rcParams['axes.autolimit_mode'] == 'round_numbers':
- vmin = self._edge.le(dmin - self._offset) * self._edge.step + self._offset
- vmax = self._edge.ge(dmax - self._offset) * self._edge.step + self._offset
- if vmin == vmax:
- vmin -= 1
- vmax += 1
- else:
- vmin = dmin
- vmax = dmax
-
- return mtransforms.nonsingular(vmin, vmax)
-
-
-def scale_range(vmin, vmax, n=1, threshold=100):
- dv = abs(vmax - vmin) # > 0 as nonsingular is called before.
- meanv = (vmax + vmin) / 2
- if abs(meanv) / dv < threshold:
- offset = 0
- else:
- offset = math.copysign(10 ** (math.log10(abs(meanv)) // 1), meanv)
- scale = 10 ** (math.log10(dv / n) // 1)
- return scale, offset
-
-
-class _Edge_integer:
- """
- Helper for `.MaxNLocator`, `.MultipleLocator`, etc.
-
- Take floating-point precision limitations into account when calculating
- tick locations as integer multiples of a step.
- """
- def __init__(self, step, offset):
- """
- Parameters
- ----------
- step : float > 0
- Interval between ticks.
- offset : float
- Offset subtracted from the data limits prior to calculating tick
- locations.
- """
- if step <= 0:
- raise ValueError("'step' must be positive")
- self.step = step
- self._offset = abs(offset)
-
- def closeto(self, ms, edge):
- # Allow more slop when the offset is large compared to the step.
- if self._offset > 0:
- digits = np.log10(self._offset / self.step)
- tol = max(1e-10, 10 ** (digits - 12))
- tol = min(0.4999, tol)
- else:
- tol = 1e-10
- return abs(ms - edge) < tol
-
- def le(self, x):
- """Return the largest n: n*step <= x."""
- d, m = divmod(x, self.step)
- if self.closeto(m / self.step, 1):
- return d + 1
- return d
-
- def ge(self, x):
- """Return the smallest n: n*step >= x."""
- d, m = divmod(x, self.step)
- if self.closeto(m / self.step, 0):
- return d
- return d + 1
-
-
-class MaxNLocator(Locator):
- """
- Find nice tick locations with no more than *nbins* + 1 being within the
- view limits. Locations beyond the limits are added to support autoscaling.
- """
- default_params = dict(nbins=10,
- steps=None,
- integer=False,
- symmetric=False,
- prune=None,
- min_n_ticks=2)
-
- def __init__(self, nbins=None, **kwargs):
- """
- Parameters
- ----------
- nbins : int or 'auto', default: 10
- Maximum number of intervals; one less than max number of
- ticks. If the string 'auto', the number of bins will be
- automatically determined based on the length of the axis.
-
- steps : array-like, optional
- Sequence of acceptable tick multiples, starting with 1 and
- ending with 10. For example, if ``steps=[1, 2, 4, 5, 10]``,
- ``20, 40, 60`` or ``0.4, 0.6, 0.8`` would be possible
- sets of ticks because they are multiples of 2.
- ``30, 60, 90`` would not be generated because 3 does not
- appear in this example list of steps.
-
- integer : bool, default: False
- If True, ticks will take only integer values, provided at least
- *min_n_ticks* integers are found within the view limits.
-
- symmetric : bool, default: False
- If True, autoscaling will result in a range symmetric about zero.
-
- prune : {'lower', 'upper', 'both', None}, default: None
- Remove the 'lower' tick, the 'upper' tick, or ticks on 'both' sides
- *if they fall exactly on an axis' edge* (this typically occurs when
- :rc:`axes.autolimit_mode` is 'round_numbers'). Removing such ticks
- is mostly useful for stacked or ganged plots, where the upper tick
- of an axes overlaps with the lower tick of the axes above it.
-
- min_n_ticks : int, default: 2
- Relax *nbins* and *integer* constraints if necessary to obtain
- this minimum number of ticks.
- """
- if nbins is not None:
- kwargs['nbins'] = nbins
- self.set_params(**{**self.default_params, **kwargs})
-
- @staticmethod
- def _validate_steps(steps):
- if not np.iterable(steps):
- raise ValueError('steps argument must be an increasing sequence '
- 'of numbers between 1 and 10 inclusive')
- steps = np.asarray(steps)
- if np.any(np.diff(steps) <= 0) or steps[-1] > 10 or steps[0] < 1:
- raise ValueError('steps argument must be an increasing sequence '
- 'of numbers between 1 and 10 inclusive')
- if steps[0] != 1:
- steps = np.concatenate([[1], steps])
- if steps[-1] != 10:
- steps = np.concatenate([steps, [10]])
- return steps
-
- @staticmethod
- def _staircase(steps):
- # Make an extended staircase within which the needed step will be
- # found. This is probably much larger than necessary.
- return np.concatenate([0.1 * steps[:-1], steps, [10 * steps[1]]])
-
- def set_params(self, **kwargs):
- """
- Set parameters for this locator.
-
- Parameters
- ----------
- nbins : int or 'auto', optional
- see `.MaxNLocator`
- steps : array-like, optional
- see `.MaxNLocator`
- integer : bool, optional
- see `.MaxNLocator`
- symmetric : bool, optional
- see `.MaxNLocator`
- prune : {'lower', 'upper', 'both', None}, optional
- see `.MaxNLocator`
- min_n_ticks : int, optional
- see `.MaxNLocator`
- """
- if 'nbins' in kwargs:
- self._nbins = kwargs.pop('nbins')
- if self._nbins != 'auto':
- self._nbins = int(self._nbins)
- if 'symmetric' in kwargs:
- self._symmetric = kwargs.pop('symmetric')
- if 'prune' in kwargs:
- prune = kwargs.pop('prune')
- _api.check_in_list(['upper', 'lower', 'both', None], prune=prune)
- self._prune = prune
- if 'min_n_ticks' in kwargs:
- self._min_n_ticks = max(1, kwargs.pop('min_n_ticks'))
- if 'steps' in kwargs:
- steps = kwargs.pop('steps')
- if steps is None:
- self._steps = np.array([1, 1.5, 2, 2.5, 3, 4, 5, 6, 8, 10])
- else:
- self._steps = self._validate_steps(steps)
- self._extended_steps = self._staircase(self._steps)
- if 'integer' in kwargs:
- self._integer = kwargs.pop('integer')
- if kwargs:
- raise _api.kwarg_error("set_params", kwargs)
-
- def _raw_ticks(self, vmin, vmax):
- """
- Generate a list of tick locations including the range *vmin* to
- *vmax*. In some applications, one or both of the end locations
- will not be needed, in which case they are trimmed off
- elsewhere.
- """
- if self._nbins == 'auto':
- if self.axis is not None:
- nbins = np.clip(self.axis.get_tick_space(),
- max(1, self._min_n_ticks - 1), 9)
- else:
- nbins = 9
- else:
- nbins = self._nbins
-
- scale, offset = scale_range(vmin, vmax, nbins)
- _vmin = vmin - offset
- _vmax = vmax - offset
- steps = self._extended_steps * scale
- if self._integer:
- # For steps > 1, keep only integer values.
- igood = (steps < 1) | (np.abs(steps - np.round(steps)) < 0.001)
- steps = steps[igood]
-
- raw_step = ((_vmax - _vmin) / nbins)
- large_steps = steps >= raw_step
- if mpl.rcParams['axes.autolimit_mode'] == 'round_numbers':
- # Classic round_numbers mode may require a larger step.
- # Get first multiple of steps that are <= _vmin
- floored_vmins = (_vmin // steps) * steps
- floored_vmaxs = floored_vmins + steps * nbins
- large_steps = large_steps & (floored_vmaxs >= _vmax)
-
- # Find index of smallest large step
- istep = np.nonzero(large_steps)[0][0]
-
- # Start at smallest of the steps greater than the raw step, and check
- # if it provides enough ticks. If not, work backwards through
- # smaller steps until one is found that provides enough ticks.
- for step in steps[:istep+1][::-1]:
-
- if (self._integer and
- np.floor(_vmax) - np.ceil(_vmin) >= self._min_n_ticks - 1):
- step = max(1, step)
- best_vmin = (_vmin // step) * step
-
- # Find tick locations spanning the vmin-vmax range, taking into
- # account degradation of precision when there is a large offset.
- # The edge ticks beyond vmin and/or vmax are needed for the
- # "round_numbers" autolimit mode.
- edge = _Edge_integer(step, offset)
- low = edge.le(_vmin - best_vmin)
- high = edge.ge(_vmax - best_vmin)
- ticks = np.arange(low, high + 1) * step + best_vmin
- # Count only the ticks that will be displayed.
- nticks = ((ticks <= _vmax) & (ticks >= _vmin)).sum()
- if nticks >= self._min_n_ticks:
- break
- return ticks + offset
-
- def __call__(self):
- vmin, vmax = self.axis.get_view_interval()
- return self.tick_values(vmin, vmax)
-
- def tick_values(self, vmin, vmax):
- if self._symmetric:
- vmax = max(abs(vmin), abs(vmax))
- vmin = -vmax
- vmin, vmax = mtransforms.nonsingular(
- vmin, vmax, expander=1e-13, tiny=1e-14)
- locs = self._raw_ticks(vmin, vmax)
-
- prune = self._prune
- if prune == 'lower':
- locs = locs[1:]
- elif prune == 'upper':
- locs = locs[:-1]
- elif prune == 'both':
- locs = locs[1:-1]
- return self.raise_if_exceeds(locs)
-
- def view_limits(self, dmin, dmax):
- if self._symmetric:
- dmax = max(abs(dmin), abs(dmax))
- dmin = -dmax
-
- dmin, dmax = mtransforms.nonsingular(
- dmin, dmax, expander=1e-12, tiny=1e-13)
-
- if mpl.rcParams['axes.autolimit_mode'] == 'round_numbers':
- return self._raw_ticks(dmin, dmax)[[0, -1]]
- else:
- return dmin, dmax
-
-
-def _is_decade(x, *, base=10, rtol=None):
- """Return True if *x* is an integer power of *base*."""
- if not np.isfinite(x):
- return False
- if x == 0.0:
- return True
- lx = np.log(abs(x)) / np.log(base)
- if rtol is None:
- return np.isclose(lx, np.round(lx))
- else:
- return np.isclose(lx, np.round(lx), rtol=rtol)
-
-
-def _decade_less_equal(x, base):
- """
- Return the largest integer power of *base* that's less or equal to *x*.
-
- If *x* is negative, the exponent will be *greater*.
- """
- return (x if x == 0 else
- -_decade_greater_equal(-x, base) if x < 0 else
- base ** np.floor(np.log(x) / np.log(base)))
-
-
-def _decade_greater_equal(x, base):
- """
- Return the smallest integer power of *base* that's greater or equal to *x*.
-
- If *x* is negative, the exponent will be *smaller*.
- """
- return (x if x == 0 else
- -_decade_less_equal(-x, base) if x < 0 else
- base ** np.ceil(np.log(x) / np.log(base)))
-
-
-def _decade_less(x, base):
- """
- Return the largest integer power of *base* that's less than *x*.
-
- If *x* is negative, the exponent will be *greater*.
- """
- if x < 0:
- return -_decade_greater(-x, base)
- less = _decade_less_equal(x, base)
- if less == x:
- less /= base
- return less
-
-
-def _decade_greater(x, base):
- """
- Return the smallest integer power of *base* that's greater than *x*.
-
- If *x* is negative, the exponent will be *smaller*.
- """
- if x < 0:
- return -_decade_less(-x, base)
- greater = _decade_greater_equal(x, base)
- if greater == x:
- greater *= base
- return greater
-
-
-def _is_close_to_int(x):
- return math.isclose(x, round(x))
-
-
-class LogLocator(Locator):
- """
-
- Determine the tick locations for log axes.
-
- Place ticks on the locations : ``subs[j] * base**i``
-
- Parameters
- ----------
- base : float, default: 10.0
- The base of the log used, so major ticks are placed at
- ``base**n``, where ``n`` is an integer.
- subs : None or {'auto', 'all'} or sequence of float, default: (1.0,)
- Gives the multiples of integer powers of the base at which
- to place ticks. The default of ``(1.0, )`` places ticks only at
- integer powers of the base.
- Permitted string values are ``'auto'`` and ``'all'``.
- Both of these use an algorithm based on the axis view
- limits to determine whether and how to put ticks between
- integer powers of the base. With ``'auto'``, ticks are
- placed only between integer powers; with ``'all'``, the
- integer powers are included. A value of None is
- equivalent to ``'auto'``.
- numticks : None or int, default: None
- The maximum number of ticks to allow on a given axis. The default
- of ``None`` will try to choose intelligently as long as this
- Locator has already been assigned to an axis using
- `~.axis.Axis.get_tick_space`, but otherwise falls back to 9.
-
- """
-
- @_api.delete_parameter("3.8", "numdecs")
- def __init__(self, base=10.0, subs=(1.0,), numdecs=4, numticks=None):
- """Place ticks on the locations : subs[j] * base**i."""
- if numticks is None:
- if mpl.rcParams['_internal.classic_mode']:
- numticks = 15
- else:
- numticks = 'auto'
- self._base = float(base)
- self._set_subs(subs)
- self._numdecs = numdecs
- self.numticks = numticks
-
- @_api.delete_parameter("3.8", "numdecs")
- def set_params(self, base=None, subs=None, numdecs=None, numticks=None):
- """Set parameters within this locator."""
- if base is not None:
- self._base = float(base)
- if subs is not None:
- self._set_subs(subs)
- if numdecs is not None:
- self._numdecs = numdecs
- if numticks is not None:
- self.numticks = numticks
-
- numdecs = _api.deprecate_privatize_attribute(
- "3.8", addendum="This attribute has no effect.")
-
- def _set_subs(self, subs):
- """
- Set the minor ticks for the log scaling every ``base**i*subs[j]``.
- """
- if subs is None: # consistency with previous bad API
- self._subs = 'auto'
- elif isinstance(subs, str):
- _api.check_in_list(('all', 'auto'), subs=subs)
- self._subs = subs
- else:
- try:
- self._subs = np.asarray(subs, dtype=float)
- except ValueError as e:
- raise ValueError("subs must be None, 'all', 'auto' or "
- "a sequence of floats, not "
- f"{subs}.") from e
- if self._subs.ndim != 1:
- raise ValueError("A sequence passed to subs must be "
- "1-dimensional, not "
- f"{self._subs.ndim}-dimensional.")
-
- def __call__(self):
- """Return the locations of the ticks."""
- vmin, vmax = self.axis.get_view_interval()
- return self.tick_values(vmin, vmax)
-
- def tick_values(self, vmin, vmax):
- if self.numticks == 'auto':
- if self.axis is not None:
- numticks = np.clip(self.axis.get_tick_space(), 2, 9)
- else:
- numticks = 9
- else:
- numticks = self.numticks
-
- b = self._base
- if vmin <= 0.0:
- if self.axis is not None:
- vmin = self.axis.get_minpos()
-
- if vmin <= 0.0 or not np.isfinite(vmin):
- raise ValueError(
- "Data has no positive values, and therefore cannot be log-scaled.")
-
- _log.debug('vmin %s vmax %s', vmin, vmax)
-
- if vmax < vmin:
- vmin, vmax = vmax, vmin
- log_vmin = math.log(vmin) / math.log(b)
- log_vmax = math.log(vmax) / math.log(b)
-
- numdec = math.floor(log_vmax) - math.ceil(log_vmin)
-
- if isinstance(self._subs, str):
- if numdec > 10 or b < 3:
- if self._subs == 'auto':
- return np.array([]) # no minor or major ticks
- else:
- subs = np.array([1.0]) # major ticks
- else:
- _first = 2.0 if self._subs == 'auto' else 1.0
- subs = np.arange(_first, b)
- else:
- subs = self._subs
-
- # Get decades between major ticks.
- stride = (max(math.ceil(numdec / (numticks - 1)), 1)
- if mpl.rcParams['_internal.classic_mode'] else
- numdec // numticks + 1)
-
- # if we have decided that the stride is as big or bigger than
- # the range, clip the stride back to the available range - 1
- # with a floor of 1. This prevents getting axis with only 1 tick
- # visible.
- if stride >= numdec:
- stride = max(1, numdec - 1)
-
- # Does subs include anything other than 1? Essentially a hack to know
- # whether we're a major or a minor locator.
- have_subs = len(subs) > 1 or (len(subs) == 1 and subs[0] != 1.0)
-
- decades = np.arange(math.floor(log_vmin) - stride,
- math.ceil(log_vmax) + 2 * stride, stride)
-
- if have_subs:
- if stride == 1:
- ticklocs = np.concatenate(
- [subs * decade_start for decade_start in b ** decades])
- else:
- ticklocs = np.array([])
- else:
- ticklocs = b ** decades
-
- _log.debug('ticklocs %r', ticklocs)
- if (len(subs) > 1
- and stride == 1
- and ((vmin <= ticklocs) & (ticklocs <= vmax)).sum() <= 1):
- # If we're a minor locator *that expects at least two ticks per
- # decade* and the major locator stride is 1 and there's no more
- # than one minor tick, switch to AutoLocator.
- return AutoLocator().tick_values(vmin, vmax)
- else:
- return self.raise_if_exceeds(ticklocs)
-
- def view_limits(self, vmin, vmax):
- """Try to choose the view limits intelligently."""
- b = self._base
-
- vmin, vmax = self.nonsingular(vmin, vmax)
-
- if mpl.rcParams['axes.autolimit_mode'] == 'round_numbers':
- vmin = _decade_less_equal(vmin, b)
- vmax = _decade_greater_equal(vmax, b)
-
- return vmin, vmax
-
- def nonsingular(self, vmin, vmax):
- if vmin > vmax:
- vmin, vmax = vmax, vmin
- if not np.isfinite(vmin) or not np.isfinite(vmax):
- vmin, vmax = 1, 10 # Initial range, no data plotted yet.
- elif vmax <= 0:
- _api.warn_external(
- "Data has no positive values, and therefore cannot be "
- "log-scaled.")
- vmin, vmax = 1, 10
- else:
- # Consider shared axises
- minpos = min(axis.get_minpos() for axis in self.axis._get_shared_axis())
- if not np.isfinite(minpos):
- minpos = 1e-300 # This should never take effect.
- if vmin <= 0:
- vmin = minpos
- if vmin == vmax:
- vmin = _decade_less(vmin, self._base)
- vmax = _decade_greater(vmax, self._base)
- return vmin, vmax
-
-
-class SymmetricalLogLocator(Locator):
- """
- Determine the tick locations for symmetric log axes.
- """
-
- def __init__(self, transform=None, subs=None, linthresh=None, base=None):
- """
- Parameters
- ----------
- transform : `~.scale.SymmetricalLogTransform`, optional
- If set, defines the *base* and *linthresh* of the symlog transform.
- base, linthresh : float, optional
- The *base* and *linthresh* of the symlog transform, as documented
- for `.SymmetricalLogScale`. These parameters are only used if
- *transform* is not set.
- subs : sequence of float, default: [1]
- The multiples of integer powers of the base where ticks are placed,
- i.e., ticks are placed at
- ``[sub * base**i for i in ... for sub in subs]``.
-
- Notes
- -----
- Either *transform*, or both *base* and *linthresh*, must be given.
- """
- if transform is not None:
- self._base = transform.base
- self._linthresh = transform.linthresh
- elif linthresh is not None and base is not None:
- self._base = base
- self._linthresh = linthresh
- else:
- raise ValueError("Either transform, or both linthresh "
- "and base, must be provided.")
- if subs is None:
- self._subs = [1.0]
- else:
- self._subs = subs
- self.numticks = 15
-
- def set_params(self, subs=None, numticks=None):
- """Set parameters within this locator."""
- if numticks is not None:
- self.numticks = numticks
- if subs is not None:
- self._subs = subs
-
- def __call__(self):
- """Return the locations of the ticks."""
- # Note, these are untransformed coordinates
- vmin, vmax = self.axis.get_view_interval()
- return self.tick_values(vmin, vmax)
-
- def tick_values(self, vmin, vmax):
- linthresh = self._linthresh
-
- if vmax < vmin:
- vmin, vmax = vmax, vmin
-
- # The domain is divided into three sections, only some of
- # which may actually be present.
- #
- # <======== -t ==0== t ========>
- # aaaaaaaaa bbbbb ccccccccc
- #
- # a) and c) will have ticks at integral log positions. The
- # number of ticks needs to be reduced if there are more
- # than self.numticks of them.
- #
- # b) has a tick at 0 and only 0 (we assume t is a small
- # number, and the linear segment is just an implementation
- # detail and not interesting.)
- #
- # We could also add ticks at t, but that seems to usually be
- # uninteresting.
- #
- # "simple" mode is when the range falls entirely within [-t, t]
- # -- it should just display (vmin, 0, vmax)
- if -linthresh <= vmin < vmax <= linthresh:
- # only the linear range is present
- return sorted({vmin, 0, vmax})
-
- # Lower log range is present
- has_a = (vmin < -linthresh)
- # Upper log range is present
- has_c = (vmax > linthresh)
-
- # Check if linear range is present
- has_b = (has_a and vmax > -linthresh) or (has_c and vmin < linthresh)
-
- base = self._base
-
- def get_log_range(lo, hi):
- lo = np.floor(np.log(lo) / np.log(base))
- hi = np.ceil(np.log(hi) / np.log(base))
- return lo, hi
-
- # Calculate all the ranges, so we can determine striding
- a_lo, a_hi = (0, 0)
- if has_a:
- a_upper_lim = min(-linthresh, vmax)
- a_lo, a_hi = get_log_range(abs(a_upper_lim), abs(vmin) + 1)
-
- c_lo, c_hi = (0, 0)
- if has_c:
- c_lower_lim = max(linthresh, vmin)
- c_lo, c_hi = get_log_range(c_lower_lim, vmax + 1)
-
- # Calculate the total number of integer exponents in a and c ranges
- total_ticks = (a_hi - a_lo) + (c_hi - c_lo)
- if has_b:
- total_ticks += 1
- stride = max(total_ticks // (self.numticks - 1), 1)
-
- decades = []
- if has_a:
- decades.extend(-1 * (base ** (np.arange(a_lo, a_hi,
- stride)[::-1])))
-
- if has_b:
- decades.append(0.0)
-
- if has_c:
- decades.extend(base ** (np.arange(c_lo, c_hi, stride)))
-
- subs = np.asarray(self._subs)
-
- if len(subs) > 1 or subs[0] != 1.0:
- ticklocs = []
- for decade in decades:
- if decade == 0:
- ticklocs.append(decade)
- else:
- ticklocs.extend(subs * decade)
- else:
- ticklocs = decades
-
- return self.raise_if_exceeds(np.array(ticklocs))
-
- def view_limits(self, vmin, vmax):
- """Try to choose the view limits intelligently."""
- b = self._base
- if vmax < vmin:
- vmin, vmax = vmax, vmin
-
- if mpl.rcParams['axes.autolimit_mode'] == 'round_numbers':
- vmin = _decade_less_equal(vmin, b)
- vmax = _decade_greater_equal(vmax, b)
- if vmin == vmax:
- vmin = _decade_less(vmin, b)
- vmax = _decade_greater(vmax, b)
-
- return mtransforms.nonsingular(vmin, vmax)
-
-
-class AsinhLocator(Locator):
- """
- An axis tick locator specialized for the inverse-sinh scale
-
- This is very unlikely to have any use beyond
- the `~.scale.AsinhScale` class.
-
- .. note::
-
- This API is provisional and may be revised in the future
- based on early user feedback.
- """
- def __init__(self, linear_width, numticks=11, symthresh=0.2,
- base=10, subs=None):
- """
- Parameters
- ----------
- linear_width : float
- The scale parameter defining the extent
- of the quasi-linear region.
- numticks : int, default: 11
- The approximate number of major ticks that will fit
- along the entire axis
- symthresh : float, default: 0.2
- The fractional threshold beneath which data which covers
- a range that is approximately symmetric about zero
- will have ticks that are exactly symmetric.
- base : int, default: 10
- The number base used for rounding tick locations
- on a logarithmic scale. If this is less than one,
- then rounding is to the nearest integer multiple
- of powers of ten.
- subs : tuple, default: None
- Multiples of the number base, typically used
- for the minor ticks, e.g. (2, 5) when base=10.
- """
- super().__init__()
- self.linear_width = linear_width
- self.numticks = numticks
- self.symthresh = symthresh
- self.base = base
- self.subs = subs
-
- def set_params(self, numticks=None, symthresh=None,
- base=None, subs=None):
- """Set parameters within this locator."""
- if numticks is not None:
- self.numticks = numticks
- if symthresh is not None:
- self.symthresh = symthresh
- if base is not None:
- self.base = base
- if subs is not None:
- self.subs = subs if len(subs) > 0 else None
-
- def __call__(self):
- vmin, vmax = self.axis.get_view_interval()
- if (vmin * vmax) < 0 and abs(1 + vmax / vmin) < self.symthresh:
- # Data-range appears to be almost symmetric, so round up:
- bound = max(abs(vmin), abs(vmax))
- return self.tick_values(-bound, bound)
- else:
- return self.tick_values(vmin, vmax)
-
- def tick_values(self, vmin, vmax):
- # Construct a set of "on-screen" locations
- # that are uniformly spaced:
- ymin, ymax = self.linear_width * np.arcsinh(np.array([vmin, vmax])
- / self.linear_width)
- ys = np.linspace(ymin, ymax, self.numticks)
- zero_dev = np.abs(ys / (ymax - ymin))
- if (ymin * ymax) < 0:
- # Ensure that the zero tick-mark is included,
- # if the axis straddles zero
- ys = np.hstack([ys[(zero_dev > 0.5 / self.numticks)], 0.0])
-
- # Transform the "on-screen" grid to the data space:
- xs = self.linear_width * np.sinh(ys / self.linear_width)
- zero_xs = (ys == 0)
-
- # Round the data-space values to be intuitive base-n numbers,
- # keeping track of positive and negative values separately,
- # but giving careful treatment to the zero value:
- if self.base > 1:
- log_base = math.log(self.base)
- powers = (
- np.where(zero_xs, 0, np.sign(xs)) *
- np.power(self.base,
- np.where(zero_xs, 0.0,
- np.floor(np.log(np.abs(xs) + zero_xs*1e-6)
- / log_base)))
- )
- if self.subs:
- qs = np.outer(powers, self.subs).flatten()
- else:
- qs = powers
- else:
- powers = (
- np.where(xs >= 0, 1, -1) *
- np.power(10, np.where(zero_xs, 0.0,
- np.floor(np.log10(np.abs(xs)
- + zero_xs*1e-6))))
- )
- qs = powers * np.round(xs / powers)
- ticks = np.array(sorted(set(qs)))
-
- if len(ticks) >= 2:
- return ticks
- else:
- return np.linspace(vmin, vmax, self.numticks)
-
-
-class LogitLocator(MaxNLocator):
- """
- Determine the tick locations for logit axes
- """
-
- def __init__(self, minor=False, *, nbins="auto"):
- """
- Place ticks on the logit locations
-
- Parameters
- ----------
- nbins : int or 'auto', optional
- Number of ticks. Only used if minor is False.
- minor : bool, default: False
- Indicate if this locator is for minor ticks or not.
- """
-
- self._minor = minor
- super().__init__(nbins=nbins, steps=[1, 2, 5, 10])
-
- def set_params(self, minor=None, **kwargs):
- """Set parameters within this locator."""
- if minor is not None:
- self._minor = minor
- super().set_params(**kwargs)
-
- @property
- def minor(self):
- return self._minor
-
- @minor.setter
- def minor(self, value):
- self.set_params(minor=value)
-
- def tick_values(self, vmin, vmax):
- # dummy axis has no axes attribute
- if hasattr(self.axis, "axes") and self.axis.axes.name == "polar":
- raise NotImplementedError("Polar axis cannot be logit scaled yet")
-
- if self._nbins == "auto":
- if self.axis is not None:
- nbins = self.axis.get_tick_space()
- if nbins < 2:
- nbins = 2
- else:
- nbins = 9
- else:
- nbins = self._nbins
-
- # We define ideal ticks with their index:
- # linscale: ... 1e-3 1e-2 1e-1 1/2 1-1e-1 1-1e-2 1-1e-3 ...
- # b-scale : ... -3 -2 -1 0 1 2 3 ...
- def ideal_ticks(x):
- return 10 ** x if x < 0 else 1 - (10 ** (-x)) if x > 0 else 0.5
-
- vmin, vmax = self.nonsingular(vmin, vmax)
- binf = int(
- np.floor(np.log10(vmin))
- if vmin < 0.5
- else 0
- if vmin < 0.9
- else -np.ceil(np.log10(1 - vmin))
- )
- bsup = int(
- np.ceil(np.log10(vmax))
- if vmax <= 0.5
- else 1
- if vmax <= 0.9
- else -np.floor(np.log10(1 - vmax))
- )
- numideal = bsup - binf - 1
- if numideal >= 2:
- # have 2 or more wanted ideal ticks, so use them as major ticks
- if numideal > nbins:
- # to many ideal ticks, subsampling ideals for major ticks, and
- # take others for minor ticks
- subsampling_factor = math.ceil(numideal / nbins)
- if self._minor:
- ticklocs = [
- ideal_ticks(b)
- for b in range(binf, bsup + 1)
- if (b % subsampling_factor) != 0
- ]
- else:
- ticklocs = [
- ideal_ticks(b)
- for b in range(binf, bsup + 1)
- if (b % subsampling_factor) == 0
- ]
- return self.raise_if_exceeds(np.array(ticklocs))
- if self._minor:
- ticklocs = []
- for b in range(binf, bsup):
- if b < -1:
- ticklocs.extend(np.arange(2, 10) * 10 ** b)
- elif b == -1:
- ticklocs.extend(np.arange(2, 5) / 10)
- elif b == 0:
- ticklocs.extend(np.arange(6, 9) / 10)
- else:
- ticklocs.extend(
- 1 - np.arange(2, 10)[::-1] * 10 ** (-b - 1)
- )
- return self.raise_if_exceeds(np.array(ticklocs))
- ticklocs = [ideal_ticks(b) for b in range(binf, bsup + 1)]
- return self.raise_if_exceeds(np.array(ticklocs))
- # the scale is zoomed so same ticks as linear scale can be used
- if self._minor:
- return []
- return super().tick_values(vmin, vmax)
-
- def nonsingular(self, vmin, vmax):
- standard_minpos = 1e-7
- initial_range = (standard_minpos, 1 - standard_minpos)
- if vmin > vmax:
- vmin, vmax = vmax, vmin
- if not np.isfinite(vmin) or not np.isfinite(vmax):
- vmin, vmax = initial_range # Initial range, no data plotted yet.
- elif vmax <= 0 or vmin >= 1:
- # vmax <= 0 occurs when all values are negative
- # vmin >= 1 occurs when all values are greater than one
- _api.warn_external(
- "Data has no values between 0 and 1, and therefore cannot be "
- "logit-scaled."
- )
- vmin, vmax = initial_range
- else:
- minpos = (
- self.axis.get_minpos()
- if self.axis is not None
- else standard_minpos
- )
- if not np.isfinite(minpos):
- minpos = standard_minpos # This should never take effect.
- if vmin <= 0:
- vmin = minpos
- # NOTE: for vmax, we should query a property similar to get_minpos,
- # but related to the maximal, less-than-one data point.
- # Unfortunately, Bbox._minpos is defined very deep in the BBox and
- # updated with data, so for now we use 1 - minpos as a substitute.
- if vmax >= 1:
- vmax = 1 - minpos
- if vmin == vmax:
- vmin, vmax = 0.1 * vmin, 1 - 0.1 * vmin
-
- return vmin, vmax
-
-
-class AutoLocator(MaxNLocator):
- """
- Dynamically find major tick positions. This is actually a subclass
- of `~matplotlib.ticker.MaxNLocator`, with parameters *nbins = 'auto'*
- and *steps = [1, 2, 2.5, 5, 10]*.
- """
- def __init__(self):
- """
- To know the values of the non-public parameters, please have a
- look to the defaults of `~matplotlib.ticker.MaxNLocator`.
- """
- if mpl.rcParams['_internal.classic_mode']:
- nbins = 9
- steps = [1, 2, 5, 10]
- else:
- nbins = 'auto'
- steps = [1, 2, 2.5, 5, 10]
- super().__init__(nbins=nbins, steps=steps)
-
-
-class AutoMinorLocator(Locator):
- """
- Dynamically find minor tick positions based on the positions of
- major ticks. The scale must be linear with major ticks evenly spaced.
- """
- def __init__(self, n=None):
- """
- *n* is the number of subdivisions of the interval between
- major ticks; e.g., n=2 will place a single minor tick midway
- between major ticks.
-
- If *n* is omitted or None, the value stored in rcParams will be used.
- In case *n* is set to 'auto', it will be set to 4 or 5. If the distance
- between the major ticks equals 1, 2.5, 5 or 10 it can be perfectly
- divided in 5 equidistant sub-intervals with a length multiple of
- 0.05. Otherwise it is divided in 4 sub-intervals.
- """
- self.ndivs = n
-
- def __call__(self):
- """Return the locations of the ticks."""
- if self.axis.get_scale() == 'log':
- _api.warn_external('AutoMinorLocator does not work with '
- 'logarithmic scale')
- return []
-
- majorlocs = self.axis.get_majorticklocs()
- try:
- majorstep = majorlocs[1] - majorlocs[0]
- except IndexError:
- # Need at least two major ticks to find minor tick locations
- # TODO: Figure out a way to still be able to display minor
- # ticks without two major ticks visible. For now, just display
- # no ticks at all.
- return []
-
- if self.ndivs is None:
-
- if self.axis.axis_name == 'y':
- self.ndivs = mpl.rcParams['ytick.minor.ndivs']
- else:
- # for x and z axis
- self.ndivs = mpl.rcParams['xtick.minor.ndivs']
-
- if self.ndivs == 'auto':
-
- majorstep_no_exponent = 10 ** (np.log10(majorstep) % 1)
-
- if np.isclose(majorstep_no_exponent, [1.0, 2.5, 5.0, 10.0]).any():
- ndivs = 5
- else:
- ndivs = 4
- else:
- ndivs = self.ndivs
-
- minorstep = majorstep / ndivs
-
- vmin, vmax = self.axis.get_view_interval()
- if vmin > vmax:
- vmin, vmax = vmax, vmin
-
- t0 = majorlocs[0]
- tmin = round((vmin - t0) / minorstep)
- tmax = round((vmax - t0) / minorstep) + 1
- locs = (np.arange(tmin, tmax) * minorstep) + t0
-
- return self.raise_if_exceeds(locs)
-
- def tick_values(self, vmin, vmax):
- raise NotImplementedError('Cannot get tick locations for a '
- '%s type.' % type(self))
diff --git a/contrib/python/matplotlib/py3/matplotlib/ticker.pyi b/contrib/python/matplotlib/py3/matplotlib/ticker.pyi
deleted file mode 100644
index f026b4943c..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/ticker.pyi
+++ /dev/null
@@ -1,301 +0,0 @@
-from collections.abc import Callable, Sequence
-from typing import Any, Literal
-
-from matplotlib.axis import Axis
-from matplotlib.transforms import Transform
-from matplotlib.projections.polar import _AxisWrapper
-
-import numpy as np
-
-class _DummyAxis:
- __name__: str
- def __init__(self, minpos: float = ...) -> None: ...
- def get_view_interval(self) -> tuple[float, float]: ...
- def set_view_interval(self, vmin: float, vmax: float) -> None: ...
- def get_minpos(self) -> float: ...
- def get_data_interval(self) -> tuple[float, float]: ...
- def set_data_interval(self, vmin: float, vmax: float) -> None: ...
- def get_tick_space(self) -> int: ...
-
-class TickHelper:
- axis: None | Axis | _DummyAxis | _AxisWrapper
- def set_axis(self, axis: Axis | _DummyAxis | _AxisWrapper | None) -> None: ...
- def create_dummy_axis(self, **kwargs) -> None: ...
-
-class Formatter(TickHelper):
- locs: list[float]
- def __call__(self, x: float, pos: int | None = ...) -> str: ...
- def format_ticks(self, values: list[float]) -> list[str]: ...
- def format_data(self, value: float) -> str: ...
- def format_data_short(self, value: float) -> str: ...
- def get_offset(self) -> str: ...
- def set_locs(self, locs: list[float]) -> None: ...
- @staticmethod
- def fix_minus(s: str) -> str: ...
-
-class NullFormatter(Formatter): ...
-
-class FixedFormatter(Formatter):
- seq: Sequence[str]
- offset_string: str
- def __init__(self, seq: Sequence[str]) -> None: ...
- def set_offset_string(self, ofs: str) -> None: ...
-
-class FuncFormatter(Formatter):
- func: Callable[[float, int | None], str]
- offset_string: str
- # Callable[[float, int | None], str] | Callable[[float], str]
- def __init__(self, func: Callable[..., str]) -> None: ...
- def set_offset_string(self, ofs: str) -> None: ...
-
-class FormatStrFormatter(Formatter):
- fmt: str
- def __init__(self, fmt: str) -> None: ...
-
-class StrMethodFormatter(Formatter):
- fmt: str
- def __init__(self, fmt: str) -> None: ...
-
-class ScalarFormatter(Formatter):
- orderOfMagnitude: int
- format: str
- def __init__(
- self,
- useOffset: bool | float | None = ...,
- useMathText: bool | None = ...,
- useLocale: bool | None = ...,
- ) -> None: ...
- offset: float
- def get_useOffset(self) -> bool: ...
- def set_useOffset(self, val: bool | float) -> None: ...
- @property
- def useOffset(self) -> bool: ...
- @useOffset.setter
- def useOffset(self, val: bool | float) -> None: ...
- def get_useLocale(self) -> bool: ...
- def set_useLocale(self, val: bool | None) -> None: ...
- @property
- def useLocale(self) -> bool: ...
- @useLocale.setter
- def useLocale(self, val: bool | None) -> None: ...
- def get_useMathText(self) -> bool: ...
- def set_useMathText(self, val: bool | None) -> None: ...
- @property
- def useMathText(self) -> bool: ...
- @useMathText.setter
- def useMathText(self, val: bool | None) -> None: ...
- def set_scientific(self, b: bool) -> None: ...
- def set_powerlimits(self, lims: tuple[int, int]) -> None: ...
- def format_data_short(self, value: float | np.ma.MaskedArray) -> str: ...
- def format_data(self, value: float) -> str: ...
-
-class LogFormatter(Formatter):
- minor_thresholds: tuple[float, float]
- def __init__(
- self,
- base: float = ...,
- labelOnlyBase: bool = ...,
- minor_thresholds: tuple[float, float] | None = ...,
- linthresh: float | None = ...,
- ) -> None: ...
- def set_base(self, base: float) -> None: ...
- labelOnlyBase: bool
- def set_label_minor(self, labelOnlyBase: bool) -> None: ...
- def set_locs(self, locs: Any | None = ...) -> None: ...
- def format_data(self, value: float) -> str: ...
- def format_data_short(self, value: float) -> str: ...
-
-class LogFormatterExponent(LogFormatter): ...
-class LogFormatterMathtext(LogFormatter): ...
-class LogFormatterSciNotation(LogFormatterMathtext): ...
-
-class LogitFormatter(Formatter):
- def __init__(
- self,
- *,
- use_overline: bool = ...,
- one_half: str = ...,
- minor: bool = ...,
- minor_threshold: int = ...,
- minor_number: int = ...
- ) -> None: ...
- def use_overline(self, use_overline: bool) -> None: ...
- def set_one_half(self, one_half: str) -> None: ...
- def set_minor_threshold(self, minor_threshold: int) -> None: ...
- def set_minor_number(self, minor_number: int) -> None: ...
- def format_data_short(self, value: float) -> str: ...
-
-class EngFormatter(Formatter):
- ENG_PREFIXES: dict[int, str]
- unit: str
- places: int | None
- sep: str
- def __init__(
- self,
- unit: str = ...,
- places: int | None = ...,
- sep: str = ...,
- *,
- usetex: bool | None = ...,
- useMathText: bool | None = ...
- ) -> None: ...
- def get_usetex(self) -> bool: ...
- def set_usetex(self, val: bool | None) -> None: ...
- @property
- def usetex(self) -> bool: ...
- @usetex.setter
- def usetex(self, val: bool | None) -> None: ...
- def get_useMathText(self) -> bool: ...
- def set_useMathText(self, val: bool | None) -> None: ...
- @property
- def useMathText(self) -> bool: ...
- @useMathText.setter
- def useMathText(self, val: bool | None) -> None: ...
- def format_eng(self, num: float) -> str: ...
-
-class PercentFormatter(Formatter):
- xmax: float
- decimals: int | None
- def __init__(
- self,
- xmax: float = ...,
- decimals: int | None = ...,
- symbol: str | None = ...,
- is_latex: bool = ...,
- ) -> None: ...
- def format_pct(self, x: float, display_range: float) -> str: ...
- def convert_to_pct(self, x: float) -> float: ...
- @property
- def symbol(self) -> str: ...
- @symbol.setter
- def symbol(self, symbol: str) -> None: ...
-
-class Locator(TickHelper):
- MAXTICKS: int
- def tick_values(self, vmin: float, vmax: float) -> Sequence[float]: ...
- # Implementation accepts **kwargs, but is a no-op other than a warning
- # Typing as **kwargs would require each subclass to accept **kwargs for mypy
- def set_params(self) -> None: ...
- def __call__(self) -> Sequence[float]: ...
- def raise_if_exceeds(self, locs: Sequence[float]) -> Sequence[float]: ...
- def nonsingular(self, v0: float, v1: float) -> tuple[float, float]: ...
- def view_limits(self, vmin: float, vmax: float) -> tuple[float, float]: ...
-
-class IndexLocator(Locator):
- offset: float
- def __init__(self, base: float, offset: float) -> None: ...
- def set_params(
- self, base: float | None = ..., offset: float | None = ...
- ) -> None: ...
-
-class FixedLocator(Locator):
- nbins: int | None
- def __init__(self, locs: Sequence[float], nbins: int | None = ...) -> None: ...
- def set_params(self, nbins: int | None = ...) -> None: ...
-
-class NullLocator(Locator): ...
-
-class LinearLocator(Locator):
- presets: dict[tuple[float, float], Sequence[float]]
- def __init__(
- self,
- numticks: int | None = ...,
- presets: dict[tuple[float, float], Sequence[float]] | None = ...,
- ) -> None: ...
- @property
- def numticks(self) -> int: ...
- @numticks.setter
- def numticks(self, numticks: int | None) -> None: ...
- def set_params(
- self,
- numticks: int | None = ...,
- presets: dict[tuple[float, float], Sequence[float]] | None = ...,
- ) -> None: ...
-
-class MultipleLocator(Locator):
- def __init__(self, base: float = ..., offset: float = ...) -> None: ...
- def set_params(self, base: float | None = ..., offset: float | None = ...) -> None: ...
- def view_limits(self, dmin: float, dmax: float) -> tuple[float, float]: ...
-
-class _Edge_integer:
- step: float
- def __init__(self, step: float, offset: float) -> None: ...
- def closeto(self, ms: float, edge: float) -> bool: ...
- def le(self, x: float) -> float: ...
- def ge(self, x: float) -> float: ...
-
-class MaxNLocator(Locator):
- default_params: dict[str, Any]
- def __init__(self, nbins: int | Literal["auto"] | None = ..., **kwargs) -> None: ...
- def set_params(self, **kwargs) -> None: ...
- def view_limits(self, dmin: float, dmax: float) -> tuple[float, float]: ...
-
-class LogLocator(Locator):
- numdecs: float
- numticks: int | None
- def __init__(
- self,
- base: float = ...,
- subs: None | Literal["auto", "all"] | Sequence[float] = ...,
- numdecs: float = ...,
- numticks: int | None = ...,
- ) -> None: ...
- def set_params(
- self,
- base: float | None = ...,
- subs: Literal["auto", "all"] | Sequence[float] | None = ...,
- numdecs: float | None = ...,
- numticks: int | None = ...,
- ) -> None: ...
-
-class SymmetricalLogLocator(Locator):
- numticks: int
- def __init__(
- self,
- transform: Transform | None = ...,
- subs: Sequence[float] | None = ...,
- linthresh: float | None = ...,
- base: float | None = ...,
- ) -> None: ...
- def set_params(
- self, subs: Sequence[float] | None = ..., numticks: int | None = ...
- ) -> None: ...
-
-class AsinhLocator(Locator):
- linear_width: float
- numticks: int
- symthresh: float
- base: int
- subs: Sequence[float] | None
- def __init__(
- self,
- linear_width: float,
- numticks: int = ...,
- symthresh: float = ...,
- base: int = ...,
- subs: Sequence[float] | None = ...,
- ) -> None: ...
- def set_params(
- self,
- numticks: int | None = ...,
- symthresh: float | None = ...,
- base: int | None = ...,
- subs: Sequence[float] | None = ...,
- ) -> None: ...
-
-class LogitLocator(MaxNLocator):
- def __init__(
- self, minor: bool = ..., *, nbins: Literal["auto"] | int = ...
- ) -> None: ...
- def set_params(self, minor: bool | None = ..., **kwargs) -> None: ...
- @property
- def minor(self) -> bool: ...
- @minor.setter
- def minor(self, value: bool) -> None: ...
-
-class AutoLocator(MaxNLocator):
- def __init__(self) -> None: ...
-
-class AutoMinorLocator(Locator):
- ndivs: int
- def __init__(self, n: int | None = ...) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/transforms.py b/contrib/python/matplotlib/py3/matplotlib/transforms.py
deleted file mode 100644
index d04b59afa9..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/transforms.py
+++ /dev/null
@@ -1,2975 +0,0 @@
-"""
-Matplotlib includes a framework for arbitrary geometric
-transformations that is used determine the final position of all
-elements drawn on the canvas.
-
-Transforms are composed into trees of `TransformNode` objects
-whose actual value depends on their children. When the contents of
-children change, their parents are automatically invalidated. The
-next time an invalidated transform is accessed, it is recomputed to
-reflect those changes. This invalidation/caching approach prevents
-unnecessary recomputations of transforms, and contributes to better
-interactive performance.
-
-For example, here is a graph of the transform tree used to plot data
-to the graph:
-
-.. image:: ../_static/transforms.png
-
-The framework can be used for both affine and non-affine
-transformations. However, for speed, we want to use the backend
-renderers to perform affine transformations whenever possible.
-Therefore, it is possible to perform just the affine or non-affine
-part of a transformation on a set of data. The affine is always
-assumed to occur after the non-affine. For any transform::
-
- full transform == non-affine part + affine part
-
-The backends are not expected to handle non-affine transformations
-themselves.
-
-See the tutorial :ref:`transforms_tutorial` for examples
-of how to use transforms.
-"""
-
-# Note: There are a number of places in the code where we use `np.min` or
-# `np.minimum` instead of the builtin `min`, and likewise for `max`. This is
-# done so that `nan`s are propagated, instead of being silently dropped.
-
-import copy
-import functools
-import textwrap
-import weakref
-import math
-
-import numpy as np
-from numpy.linalg import inv
-
-from matplotlib import _api
-from matplotlib._path import (
- affine_transform, count_bboxes_overlapping_bbox, update_path_extents)
-from .path import Path
-
-DEBUG = False
-
-
-def _make_str_method(*args, **kwargs):
- """
- Generate a ``__str__`` method for a `.Transform` subclass.
-
- After ::
-
- class T:
- __str__ = _make_str_method("attr", key="other")
-
- ``str(T(...))`` will be
-
- .. code-block:: text
-
- {type(T).__name__}(
- {self.attr},
- key={self.other})
- """
- indent = functools.partial(textwrap.indent, prefix=" " * 4)
- def strrepr(x): return repr(x) if isinstance(x, str) else str(x)
- return lambda self: (
- type(self).__name__ + "("
- + ",".join([*(indent("\n" + strrepr(getattr(self, arg)))
- for arg in args),
- *(indent("\n" + k + "=" + strrepr(getattr(self, arg)))
- for k, arg in kwargs.items())])
- + ")")
-
-
-class TransformNode:
- """
- The base class for anything that participates in the transform tree
- and needs to invalidate its parents or be invalidated. This includes
- classes that are not really transforms, such as bounding boxes, since some
- transforms depend on bounding boxes to compute their values.
- """
-
- # Invalidation may affect only the affine part. If the
- # invalidation was "affine-only", the _invalid member is set to
- # INVALID_AFFINE_ONLY
- INVALID_NON_AFFINE = _api.deprecated("3.8")(_api.classproperty(lambda cls: 1))
- INVALID_AFFINE = _api.deprecated("3.8")(_api.classproperty(lambda cls: 2))
- INVALID = _api.deprecated("3.8")(_api.classproperty(lambda cls: 3))
-
- # Possible values for the _invalid attribute.
- _VALID, _INVALID_AFFINE_ONLY, _INVALID_FULL = range(3)
-
- # Some metadata about the transform, used to determine whether an
- # invalidation is affine-only
- is_affine = False
- is_bbox = False
-
- pass_through = False
- """
- If pass_through is True, all ancestors will always be
- invalidated, even if 'self' is already invalid.
- """
-
- def __init__(self, shorthand_name=None):
- """
- Parameters
- ----------
- shorthand_name : str
- A string representing the "name" of the transform. The name carries
- no significance other than to improve the readability of
- ``str(transform)`` when DEBUG=True.
- """
- self._parents = {}
- # Initially invalid, until first computation.
- self._invalid = self._INVALID_FULL
- self._shorthand_name = shorthand_name or ''
-
- if DEBUG:
- def __str__(self):
- # either just return the name of this TransformNode, or its repr
- return self._shorthand_name or repr(self)
-
- def __getstate__(self):
- # turn the dictionary with weak values into a normal dictionary
- return {**self.__dict__,
- '_parents': {k: v() for k, v in self._parents.items()}}
-
- def __setstate__(self, data_dict):
- self.__dict__ = data_dict
- # turn the normal dictionary back into a dictionary with weak values
- # The extra lambda is to provide a callback to remove dead
- # weakrefs from the dictionary when garbage collection is done.
- self._parents = {
- k: weakref.ref(v, lambda _, pop=self._parents.pop, k=k: pop(k))
- for k, v in self._parents.items() if v is not None}
-
- def __copy__(self):
- other = copy.copy(super())
- # If `c = a + b; a1 = copy(a)`, then modifications to `a1` do not
- # propagate back to `c`, i.e. we need to clear the parents of `a1`.
- other._parents = {}
- # If `c = a + b; c1 = copy(c)`, then modifications to `a` also need to
- # be propagated to `c1`.
- for key, val in vars(self).items():
- if isinstance(val, TransformNode) and id(self) in val._parents:
- other.set_children(val) # val == getattr(other, key)
- return other
-
- def invalidate(self):
- """
- Invalidate this `TransformNode` and triggers an invalidation of its
- ancestors. Should be called any time the transform changes.
- """
- return self._invalidate_internal(
- level=self._INVALID_AFFINE_ONLY if self.is_affine else self._INVALID_FULL,
- invalidating_node=self)
-
- def _invalidate_internal(self, level, invalidating_node):
- """
- Called by :meth:`invalidate` and subsequently ascends the transform
- stack calling each TransformNode's _invalidate_internal method.
- """
- # If we are already more invalid than the currently propagated invalidation,
- # then we don't need to do anything.
- if level <= self._invalid and not self.pass_through:
- return
- self._invalid = level
- for parent in list(self._parents.values()):
- parent = parent() # Dereference the weak reference.
- if parent is not None:
- parent._invalidate_internal(level=level, invalidating_node=self)
-
- def set_children(self, *children):
- """
- Set the children of the transform, to let the invalidation
- system know which transforms can invalidate this transform.
- Should be called from the constructor of any transforms that
- depend on other transforms.
- """
- # Parents are stored as weak references, so that if the
- # parents are destroyed, references from the children won't
- # keep them alive.
- id_self = id(self)
- for child in children:
- # Use weak references so this dictionary won't keep obsolete nodes
- # alive; the callback deletes the dictionary entry. This is a
- # performance improvement over using WeakValueDictionary.
- ref = weakref.ref(
- self, lambda _, pop=child._parents.pop, k=id_self: pop(k))
- child._parents[id_self] = ref
-
- def frozen(self):
- """
- Return a frozen copy of this transform node. The frozen copy will not
- be updated when its children change. Useful for storing a previously
- known state of a transform where ``copy.deepcopy()`` might normally be
- used.
- """
- return self
-
-
-class BboxBase(TransformNode):
- """
- The base class of all bounding boxes.
-
- This class is immutable; `Bbox` is a mutable subclass.
-
- The canonical representation is as two points, with no
- restrictions on their ordering. Convenience properties are
- provided to get the left, bottom, right and top edges and width
- and height, but these are not stored explicitly.
- """
-
- is_bbox = True
- is_affine = True
-
- if DEBUG:
- @staticmethod
- def _check(points):
- if isinstance(points, np.ma.MaskedArray):
- _api.warn_external("Bbox bounds are a masked array.")
- points = np.asarray(points)
- if any((points[1, :] - points[0, :]) == 0):
- _api.warn_external("Singular Bbox.")
-
- def frozen(self):
- return Bbox(self.get_points().copy())
- frozen.__doc__ = TransformNode.__doc__
-
- def __array__(self, *args, **kwargs):
- return self.get_points()
-
- @property
- def x0(self):
- """
- The first of the pair of *x* coordinates that define the bounding box.
-
- This is not guaranteed to be less than :attr:`x1` (for that, use
- :attr:`xmin`).
- """
- return self.get_points()[0, 0]
-
- @property
- def y0(self):
- """
- The first of the pair of *y* coordinates that define the bounding box.
-
- This is not guaranteed to be less than :attr:`y1` (for that, use
- :attr:`ymin`).
- """
- return self.get_points()[0, 1]
-
- @property
- def x1(self):
- """
- The second of the pair of *x* coordinates that define the bounding box.
-
- This is not guaranteed to be greater than :attr:`x0` (for that, use
- :attr:`xmax`).
- """
- return self.get_points()[1, 0]
-
- @property
- def y1(self):
- """
- The second of the pair of *y* coordinates that define the bounding box.
-
- This is not guaranteed to be greater than :attr:`y0` (for that, use
- :attr:`ymax`).
- """
- return self.get_points()[1, 1]
-
- @property
- def p0(self):
- """
- The first pair of (*x*, *y*) coordinates that define the bounding box.
-
- This is not guaranteed to be the bottom-left corner (for that, use
- :attr:`min`).
- """
- return self.get_points()[0]
-
- @property
- def p1(self):
- """
- The second pair of (*x*, *y*) coordinates that define the bounding box.
-
- This is not guaranteed to be the top-right corner (for that, use
- :attr:`max`).
- """
- return self.get_points()[1]
-
- @property
- def xmin(self):
- """The left edge of the bounding box."""
- return np.min(self.get_points()[:, 0])
-
- @property
- def ymin(self):
- """The bottom edge of the bounding box."""
- return np.min(self.get_points()[:, 1])
-
- @property
- def xmax(self):
- """The right edge of the bounding box."""
- return np.max(self.get_points()[:, 0])
-
- @property
- def ymax(self):
- """The top edge of the bounding box."""
- return np.max(self.get_points()[:, 1])
-
- @property
- def min(self):
- """The bottom-left corner of the bounding box."""
- return np.min(self.get_points(), axis=0)
-
- @property
- def max(self):
- """The top-right corner of the bounding box."""
- return np.max(self.get_points(), axis=0)
-
- @property
- def intervalx(self):
- """
- The pair of *x* coordinates that define the bounding box.
-
- This is not guaranteed to be sorted from left to right.
- """
- return self.get_points()[:, 0]
-
- @property
- def intervaly(self):
- """
- The pair of *y* coordinates that define the bounding box.
-
- This is not guaranteed to be sorted from bottom to top.
- """
- return self.get_points()[:, 1]
-
- @property
- def width(self):
- """The (signed) width of the bounding box."""
- points = self.get_points()
- return points[1, 0] - points[0, 0]
-
- @property
- def height(self):
- """The (signed) height of the bounding box."""
- points = self.get_points()
- return points[1, 1] - points[0, 1]
-
- @property
- def size(self):
- """The (signed) width and height of the bounding box."""
- points = self.get_points()
- return points[1] - points[0]
-
- @property
- def bounds(self):
- """Return (:attr:`x0`, :attr:`y0`, :attr:`width`, :attr:`height`)."""
- (x0, y0), (x1, y1) = self.get_points()
- return (x0, y0, x1 - x0, y1 - y0)
-
- @property
- def extents(self):
- """Return (:attr:`x0`, :attr:`y0`, :attr:`x1`, :attr:`y1`)."""
- return self.get_points().flatten() # flatten returns a copy.
-
- def get_points(self):
- raise NotImplementedError
-
- def containsx(self, x):
- """
- Return whether *x* is in the closed (:attr:`x0`, :attr:`x1`) interval.
- """
- x0, x1 = self.intervalx
- return x0 <= x <= x1 or x0 >= x >= x1
-
- def containsy(self, y):
- """
- Return whether *y* is in the closed (:attr:`y0`, :attr:`y1`) interval.
- """
- y0, y1 = self.intervaly
- return y0 <= y <= y1 or y0 >= y >= y1
-
- def contains(self, x, y):
- """
- Return whether ``(x, y)`` is in the bounding box or on its edge.
- """
- return self.containsx(x) and self.containsy(y)
-
- def overlaps(self, other):
- """
- Return whether this bounding box overlaps with the other bounding box.
-
- Parameters
- ----------
- other : `.BboxBase`
- """
- ax1, ay1, ax2, ay2 = self.extents
- bx1, by1, bx2, by2 = other.extents
- if ax2 < ax1:
- ax2, ax1 = ax1, ax2
- if ay2 < ay1:
- ay2, ay1 = ay1, ay2
- if bx2 < bx1:
- bx2, bx1 = bx1, bx2
- if by2 < by1:
- by2, by1 = by1, by2
- return ax1 <= bx2 and bx1 <= ax2 and ay1 <= by2 and by1 <= ay2
-
- def fully_containsx(self, x):
- """
- Return whether *x* is in the open (:attr:`x0`, :attr:`x1`) interval.
- """
- x0, x1 = self.intervalx
- return x0 < x < x1 or x0 > x > x1
-
- def fully_containsy(self, y):
- """
- Return whether *y* is in the open (:attr:`y0`, :attr:`y1`) interval.
- """
- y0, y1 = self.intervaly
- return y0 < y < y1 or y0 > y > y1
-
- def fully_contains(self, x, y):
- """
- Return whether ``x, y`` is in the bounding box, but not on its edge.
- """
- return self.fully_containsx(x) and self.fully_containsy(y)
-
- def fully_overlaps(self, other):
- """
- Return whether this bounding box overlaps with the other bounding box,
- not including the edges.
-
- Parameters
- ----------
- other : `.BboxBase`
- """
- ax1, ay1, ax2, ay2 = self.extents
- bx1, by1, bx2, by2 = other.extents
- if ax2 < ax1:
- ax2, ax1 = ax1, ax2
- if ay2 < ay1:
- ay2, ay1 = ay1, ay2
- if bx2 < bx1:
- bx2, bx1 = bx1, bx2
- if by2 < by1:
- by2, by1 = by1, by2
- return ax1 < bx2 and bx1 < ax2 and ay1 < by2 and by1 < ay2
-
- def transformed(self, transform):
- """
- Construct a `Bbox` by statically transforming this one by *transform*.
- """
- pts = self.get_points()
- ll, ul, lr = transform.transform(np.array(
- [pts[0], [pts[0, 0], pts[1, 1]], [pts[1, 0], pts[0, 1]]]))
- return Bbox([ll, [lr[0], ul[1]]])
-
- coefs = {'C': (0.5, 0.5),
- 'SW': (0, 0),
- 'S': (0.5, 0),
- 'SE': (1.0, 0),
- 'E': (1.0, 0.5),
- 'NE': (1.0, 1.0),
- 'N': (0.5, 1.0),
- 'NW': (0, 1.0),
- 'W': (0, 0.5)}
-
- def anchored(self, c, container=None):
- """
- Return a copy of the `Bbox` anchored to *c* within *container*.
-
- Parameters
- ----------
- c : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', ...}
- Either an (*x*, *y*) pair of relative coordinates (0 is left or
- bottom, 1 is right or top), 'C' (center), or a cardinal direction
- ('SW', southwest, is bottom left, etc.).
- container : `Bbox`, optional
- The box within which the `Bbox` is positioned.
-
- See Also
- --------
- .Axes.set_anchor
- """
- if container is None:
- _api.warn_deprecated(
- "3.8", message="Calling anchored() with no container bbox "
- "returns a frozen copy of the original bbox and is deprecated "
- "since %(since)s.")
- container = self
- l, b, w, h = container.bounds
- L, B, W, H = self.bounds
- cx, cy = self.coefs[c] if isinstance(c, str) else c
- return Bbox(self._points +
- [(l + cx * (w - W)) - L,
- (b + cy * (h - H)) - B])
-
- def shrunk(self, mx, my):
- """
- Return a copy of the `Bbox`, shrunk by the factor *mx*
- in the *x* direction and the factor *my* in the *y* direction.
- The lower left corner of the box remains unchanged. Normally
- *mx* and *my* will be less than 1, but this is not enforced.
- """
- w, h = self.size
- return Bbox([self._points[0],
- self._points[0] + [mx * w, my * h]])
-
- def shrunk_to_aspect(self, box_aspect, container=None, fig_aspect=1.0):
- """
- Return a copy of the `Bbox`, shrunk so that it is as
- large as it can be while having the desired aspect ratio,
- *box_aspect*. If the box coordinates are relative (i.e.
- fractions of a larger box such as a figure) then the
- physical aspect ratio of that figure is specified with
- *fig_aspect*, so that *box_aspect* can also be given as a
- ratio of the absolute dimensions, not the relative dimensions.
- """
- if box_aspect <= 0 or fig_aspect <= 0:
- raise ValueError("'box_aspect' and 'fig_aspect' must be positive")
- if container is None:
- container = self
- w, h = container.size
- H = w * box_aspect / fig_aspect
- if H <= h:
- W = w
- else:
- W = h * fig_aspect / box_aspect
- H = h
- return Bbox([self._points[0],
- self._points[0] + (W, H)])
-
- def splitx(self, *args):
- """
- Return a list of new `Bbox` objects formed by splitting the original
- one with vertical lines at fractional positions given by *args*.
- """
- xf = [0, *args, 1]
- x0, y0, x1, y1 = self.extents
- w = x1 - x0
- return [Bbox([[x0 + xf0 * w, y0], [x0 + xf1 * w, y1]])
- for xf0, xf1 in zip(xf[:-1], xf[1:])]
-
- def splity(self, *args):
- """
- Return a list of new `Bbox` objects formed by splitting the original
- one with horizontal lines at fractional positions given by *args*.
- """
- yf = [0, *args, 1]
- x0, y0, x1, y1 = self.extents
- h = y1 - y0
- return [Bbox([[x0, y0 + yf0 * h], [x1, y0 + yf1 * h]])
- for yf0, yf1 in zip(yf[:-1], yf[1:])]
-
- def count_contains(self, vertices):
- """
- Count the number of vertices contained in the `Bbox`.
- Any vertices with a non-finite x or y value are ignored.
-
- Parameters
- ----------
- vertices : (N, 2) array
- """
- if len(vertices) == 0:
- return 0
- vertices = np.asarray(vertices)
- with np.errstate(invalid='ignore'):
- return (((self.min < vertices) &
- (vertices < self.max)).all(axis=1).sum())
-
- def count_overlaps(self, bboxes):
- """
- Count the number of bounding boxes that overlap this one.
-
- Parameters
- ----------
- bboxes : sequence of `.BboxBase`
- """
- return count_bboxes_overlapping_bbox(
- self, np.atleast_3d([np.array(x) for x in bboxes]))
-
- def expanded(self, sw, sh):
- """
- Construct a `Bbox` by expanding this one around its center by the
- factors *sw* and *sh*.
- """
- width = self.width
- height = self.height
- deltaw = (sw * width - width) / 2.0
- deltah = (sh * height - height) / 2.0
- a = np.array([[-deltaw, -deltah], [deltaw, deltah]])
- return Bbox(self._points + a)
-
- @_api.rename_parameter("3.8", "p", "w_pad")
- def padded(self, w_pad, h_pad=None):
- """
- Construct a `Bbox` by padding this one on all four sides.
-
- Parameters
- ----------
- w_pad : float
- Width pad
- h_pad : float, optional
- Height pad. Defaults to *w_pad*.
-
- """
- points = self.get_points()
- if h_pad is None:
- h_pad = w_pad
- return Bbox(points + [[-w_pad, -h_pad], [w_pad, h_pad]])
-
- def translated(self, tx, ty):
- """Construct a `Bbox` by translating this one by *tx* and *ty*."""
- return Bbox(self._points + (tx, ty))
-
- def corners(self):
- """
- Return the corners of this rectangle as an array of points.
-
- Specifically, this returns the array
- ``[[x0, y0], [x0, y1], [x1, y0], [x1, y1]]``.
- """
- (x0, y0), (x1, y1) = self.get_points()
- return np.array([[x0, y0], [x0, y1], [x1, y0], [x1, y1]])
-
- def rotated(self, radians):
- """
- Return the axes-aligned bounding box that bounds the result of rotating
- this `Bbox` by an angle of *radians*.
- """
- corners = self.corners()
- corners_rotated = Affine2D().rotate(radians).transform(corners)
- bbox = Bbox.unit()
- bbox.update_from_data_xy(corners_rotated, ignore=True)
- return bbox
-
- @staticmethod
- def union(bboxes):
- """Return a `Bbox` that contains all of the given *bboxes*."""
- if not len(bboxes):
- raise ValueError("'bboxes' cannot be empty")
- x0 = np.min([bbox.xmin for bbox in bboxes])
- x1 = np.max([bbox.xmax for bbox in bboxes])
- y0 = np.min([bbox.ymin for bbox in bboxes])
- y1 = np.max([bbox.ymax for bbox in bboxes])
- return Bbox([[x0, y0], [x1, y1]])
-
- @staticmethod
- def intersection(bbox1, bbox2):
- """
- Return the intersection of *bbox1* and *bbox2* if they intersect, or
- None if they don't.
- """
- x0 = np.maximum(bbox1.xmin, bbox2.xmin)
- x1 = np.minimum(bbox1.xmax, bbox2.xmax)
- y0 = np.maximum(bbox1.ymin, bbox2.ymin)
- y1 = np.minimum(bbox1.ymax, bbox2.ymax)
- return Bbox([[x0, y0], [x1, y1]]) if x0 <= x1 and y0 <= y1 else None
-
-_default_minpos = np.array([np.inf, np.inf])
-
-
-class Bbox(BboxBase):
- """
- A mutable bounding box.
-
- Examples
- --------
- **Create from known bounds**
-
- The default constructor takes the boundary "points" ``[[xmin, ymin],
- [xmax, ymax]]``.
-
- >>> Bbox([[1, 1], [3, 7]])
- Bbox([[1.0, 1.0], [3.0, 7.0]])
-
- Alternatively, a Bbox can be created from the flattened points array, the
- so-called "extents" ``(xmin, ymin, xmax, ymax)``
-
- >>> Bbox.from_extents(1, 1, 3, 7)
- Bbox([[1.0, 1.0], [3.0, 7.0]])
-
- or from the "bounds" ``(xmin, ymin, width, height)``.
-
- >>> Bbox.from_bounds(1, 1, 2, 6)
- Bbox([[1.0, 1.0], [3.0, 7.0]])
-
- **Create from collections of points**
-
- The "empty" object for accumulating Bboxs is the null bbox, which is a
- stand-in for the empty set.
-
- >>> Bbox.null()
- Bbox([[inf, inf], [-inf, -inf]])
-
- Adding points to the null bbox will give you the bbox of those points.
-
- >>> box = Bbox.null()
- >>> box.update_from_data_xy([[1, 1]])
- >>> box
- Bbox([[1.0, 1.0], [1.0, 1.0]])
- >>> box.update_from_data_xy([[2, 3], [3, 2]], ignore=False)
- >>> box
- Bbox([[1.0, 1.0], [3.0, 3.0]])
-
- Setting ``ignore=True`` is equivalent to starting over from a null bbox.
-
- >>> box.update_from_data_xy([[1, 1]], ignore=True)
- >>> box
- Bbox([[1.0, 1.0], [1.0, 1.0]])
-
- .. warning::
-
- It is recommended to always specify ``ignore`` explicitly. If not, the
- default value of ``ignore`` can be changed at any time by code with
- access to your Bbox, for example using the method `~.Bbox.ignore`.
-
- **Properties of the ``null`` bbox**
-
- .. note::
-
- The current behavior of `Bbox.null()` may be surprising as it does
- not have all of the properties of the "empty set", and as such does
- not behave like a "zero" object in the mathematical sense. We may
- change that in the future (with a deprecation period).
-
- The null bbox is the identity for intersections
-
- >>> Bbox.intersection(Bbox([[1, 1], [3, 7]]), Bbox.null())
- Bbox([[1.0, 1.0], [3.0, 7.0]])
-
- except with itself, where it returns the full space.
-
- >>> Bbox.intersection(Bbox.null(), Bbox.null())
- Bbox([[-inf, -inf], [inf, inf]])
-
- A union containing null will always return the full space (not the other
- set!)
-
- >>> Bbox.union([Bbox([[0, 0], [0, 0]]), Bbox.null()])
- Bbox([[-inf, -inf], [inf, inf]])
- """
-
- def __init__(self, points, **kwargs):
- """
- Parameters
- ----------
- points : `~numpy.ndarray`
- A (2, 2) array of the form ``[[x0, y0], [x1, y1]]``.
- """
- super().__init__(**kwargs)
- points = np.asarray(points, float)
- if points.shape != (2, 2):
- raise ValueError('Bbox points must be of the form '
- '"[[x0, y0], [x1, y1]]".')
- self._points = points
- self._minpos = _default_minpos.copy()
- self._ignore = True
- # it is helpful in some contexts to know if the bbox is a
- # default or has been mutated; we store the orig points to
- # support the mutated methods
- self._points_orig = self._points.copy()
- if DEBUG:
- ___init__ = __init__
-
- def __init__(self, points, **kwargs):
- self._check(points)
- self.___init__(points, **kwargs)
-
- def invalidate(self):
- self._check(self._points)
- super().invalidate()
-
- def frozen(self):
- # docstring inherited
- frozen_bbox = super().frozen()
- frozen_bbox._minpos = self.minpos.copy()
- return frozen_bbox
-
- @staticmethod
- def unit():
- """Create a new unit `Bbox` from (0, 0) to (1, 1)."""
- return Bbox([[0, 0], [1, 1]])
-
- @staticmethod
- def null():
- """Create a new null `Bbox` from (inf, inf) to (-inf, -inf)."""
- return Bbox([[np.inf, np.inf], [-np.inf, -np.inf]])
-
- @staticmethod
- def from_bounds(x0, y0, width, height):
- """
- Create a new `Bbox` from *x0*, *y0*, *width* and *height*.
-
- *width* and *height* may be negative.
- """
- return Bbox.from_extents(x0, y0, x0 + width, y0 + height)
-
- @staticmethod
- def from_extents(*args, minpos=None):
- """
- Create a new Bbox from *left*, *bottom*, *right* and *top*.
-
- The *y*-axis increases upwards.
-
- Parameters
- ----------
- left, bottom, right, top : float
- The four extents of the bounding box.
- minpos : float or None
- If this is supplied, the Bbox will have a minimum positive value
- set. This is useful when dealing with logarithmic scales and other
- scales where negative bounds result in floating point errors.
- """
- bbox = Bbox(np.reshape(args, (2, 2)))
- if minpos is not None:
- bbox._minpos[:] = minpos
- return bbox
-
- def __format__(self, fmt):
- return (
- 'Bbox(x0={0.x0:{1}}, y0={0.y0:{1}}, x1={0.x1:{1}}, y1={0.y1:{1}})'.
- format(self, fmt))
-
- def __str__(self):
- return format(self, '')
-
- def __repr__(self):
- return 'Bbox([[{0.x0}, {0.y0}], [{0.x1}, {0.y1}]])'.format(self)
-
- def ignore(self, value):
- """
- Set whether the existing bounds of the box should be ignored
- by subsequent calls to :meth:`update_from_data_xy`.
-
- value : bool
- - When ``True``, subsequent calls to `update_from_data_xy` will
- ignore the existing bounds of the `Bbox`.
- - When ``False``, subsequent calls to `update_from_data_xy` will
- include the existing bounds of the `Bbox`.
- """
- self._ignore = value
-
- def update_from_path(self, path, ignore=None, updatex=True, updatey=True):
- """
- Update the bounds of the `Bbox` to contain the vertices of the
- provided path. After updating, the bounds will have positive *width*
- and *height*; *x0* and *y0* will be the minimal values.
-
- Parameters
- ----------
- path : `~matplotlib.path.Path`
- ignore : bool, optional
- - When ``True``, ignore the existing bounds of the `Bbox`.
- - When ``False``, include the existing bounds of the `Bbox`.
- - When ``None``, use the last value passed to :meth:`ignore`.
- updatex, updatey : bool, default: True
- When ``True``, update the x/y values.
- """
- if ignore is None:
- ignore = self._ignore
-
- if path.vertices.size == 0:
- return
-
- points, minpos, changed = update_path_extents(
- path, None, self._points, self._minpos, ignore)
-
- if changed:
- self.invalidate()
- if updatex:
- self._points[:, 0] = points[:, 0]
- self._minpos[0] = minpos[0]
- if updatey:
- self._points[:, 1] = points[:, 1]
- self._minpos[1] = minpos[1]
-
- def update_from_data_x(self, x, ignore=None):
- """
- Update the x-bounds of the `Bbox` based on the passed in data. After
- updating, the bounds will have positive *width*, and *x0* will be the
- minimal value.
-
- Parameters
- ----------
- x : `~numpy.ndarray`
- Array of x-values.
- ignore : bool, optional
- - When ``True``, ignore the existing bounds of the `Bbox`.
- - When ``False``, include the existing bounds of the `Bbox`.
- - When ``None``, use the last value passed to :meth:`ignore`.
- """
- x = np.ravel(x)
- self.update_from_data_xy(np.column_stack([x, np.ones(x.size)]),
- ignore=ignore, updatey=False)
-
- def update_from_data_y(self, y, ignore=None):
- """
- Update the y-bounds of the `Bbox` based on the passed in data. After
- updating, the bounds will have positive *height*, and *y0* will be the
- minimal value.
-
- Parameters
- ----------
- y : `~numpy.ndarray`
- Array of y-values.
- ignore : bool, optional
- - When ``True``, ignore the existing bounds of the `Bbox`.
- - When ``False``, include the existing bounds of the `Bbox`.
- - When ``None``, use the last value passed to :meth:`ignore`.
- """
- y = np.ravel(y)
- self.update_from_data_xy(np.column_stack([np.ones(y.size), y]),
- ignore=ignore, updatex=False)
-
- def update_from_data_xy(self, xy, ignore=None, updatex=True, updatey=True):
- """
- Update the `Bbox` bounds based on the passed in *xy* coordinates.
-
- After updating, the bounds will have positive *width* and *height*;
- *x0* and *y0* will be the minimal values.
-
- Parameters
- ----------
- xy : (N, 2) array-like
- The (x, y) coordinates.
- ignore : bool, optional
- - When ``True``, ignore the existing bounds of the `Bbox`.
- - When ``False``, include the existing bounds of the `Bbox`.
- - When ``None``, use the last value passed to :meth:`ignore`.
- updatex, updatey : bool, default: True
- When ``True``, update the x/y values.
- """
- if len(xy) == 0:
- return
-
- path = Path(xy)
- self.update_from_path(path, ignore=ignore,
- updatex=updatex, updatey=updatey)
-
- @BboxBase.x0.setter
- def x0(self, val):
- self._points[0, 0] = val
- self.invalidate()
-
- @BboxBase.y0.setter
- def y0(self, val):
- self._points[0, 1] = val
- self.invalidate()
-
- @BboxBase.x1.setter
- def x1(self, val):
- self._points[1, 0] = val
- self.invalidate()
-
- @BboxBase.y1.setter
- def y1(self, val):
- self._points[1, 1] = val
- self.invalidate()
-
- @BboxBase.p0.setter
- def p0(self, val):
- self._points[0] = val
- self.invalidate()
-
- @BboxBase.p1.setter
- def p1(self, val):
- self._points[1] = val
- self.invalidate()
-
- @BboxBase.intervalx.setter
- def intervalx(self, interval):
- self._points[:, 0] = interval
- self.invalidate()
-
- @BboxBase.intervaly.setter
- def intervaly(self, interval):
- self._points[:, 1] = interval
- self.invalidate()
-
- @BboxBase.bounds.setter
- def bounds(self, bounds):
- l, b, w, h = bounds
- points = np.array([[l, b], [l + w, b + h]], float)
- if np.any(self._points != points):
- self._points = points
- self.invalidate()
-
- @property
- def minpos(self):
- """
- The minimum positive value in both directions within the Bbox.
-
- This is useful when dealing with logarithmic scales and other scales
- where negative bounds result in floating point errors, and will be used
- as the minimum extent instead of *p0*.
- """
- return self._minpos
-
- @property
- def minposx(self):
- """
- The minimum positive value in the *x*-direction within the Bbox.
-
- This is useful when dealing with logarithmic scales and other scales
- where negative bounds result in floating point errors, and will be used
- as the minimum *x*-extent instead of *x0*.
- """
- return self._minpos[0]
-
- @property
- def minposy(self):
- """
- The minimum positive value in the *y*-direction within the Bbox.
-
- This is useful when dealing with logarithmic scales and other scales
- where negative bounds result in floating point errors, and will be used
- as the minimum *y*-extent instead of *y0*.
- """
- return self._minpos[1]
-
- def get_points(self):
- """
- Get the points of the bounding box as an array of the form
- ``[[x0, y0], [x1, y1]]``.
- """
- self._invalid = 0
- return self._points
-
- def set_points(self, points):
- """
- Set the points of the bounding box directly from an array of the form
- ``[[x0, y0], [x1, y1]]``. No error checking is performed, as this
- method is mainly for internal use.
- """
- if np.any(self._points != points):
- self._points = points
- self.invalidate()
-
- def set(self, other):
- """
- Set this bounding box from the "frozen" bounds of another `Bbox`.
- """
- if np.any(self._points != other.get_points()):
- self._points = other.get_points()
- self.invalidate()
-
- def mutated(self):
- """Return whether the bbox has changed since init."""
- return self.mutatedx() or self.mutatedy()
-
- def mutatedx(self):
- """Return whether the x-limits have changed since init."""
- return (self._points[0, 0] != self._points_orig[0, 0] or
- self._points[1, 0] != self._points_orig[1, 0])
-
- def mutatedy(self):
- """Return whether the y-limits have changed since init."""
- return (self._points[0, 1] != self._points_orig[0, 1] or
- self._points[1, 1] != self._points_orig[1, 1])
-
-
-class TransformedBbox(BboxBase):
- """
- A `Bbox` that is automatically transformed by a given
- transform. When either the child bounding box or transform
- changes, the bounds of this bbox will update accordingly.
- """
-
- def __init__(self, bbox, transform, **kwargs):
- """
- Parameters
- ----------
- bbox : `Bbox`
- transform : `Transform`
- """
- if not bbox.is_bbox:
- raise ValueError("'bbox' is not a bbox")
- _api.check_isinstance(Transform, transform=transform)
- if transform.input_dims != 2 or transform.output_dims != 2:
- raise ValueError(
- "The input and output dimensions of 'transform' must be 2")
-
- super().__init__(**kwargs)
- self._bbox = bbox
- self._transform = transform
- self.set_children(bbox, transform)
- self._points = None
-
- __str__ = _make_str_method("_bbox", "_transform")
-
- def get_points(self):
- # docstring inherited
- if self._invalid:
- p = self._bbox.get_points()
- # Transform all four points, then make a new bounding box
- # from the result, taking care to make the orientation the
- # same.
- points = self._transform.transform(
- [[p[0, 0], p[0, 1]],
- [p[1, 0], p[0, 1]],
- [p[0, 0], p[1, 1]],
- [p[1, 0], p[1, 1]]])
- points = np.ma.filled(points, 0.0)
-
- xs = min(points[:, 0]), max(points[:, 0])
- if p[0, 0] > p[1, 0]:
- xs = xs[::-1]
-
- ys = min(points[:, 1]), max(points[:, 1])
- if p[0, 1] > p[1, 1]:
- ys = ys[::-1]
-
- self._points = np.array([
- [xs[0], ys[0]],
- [xs[1], ys[1]]
- ])
-
- self._invalid = 0
- return self._points
-
- if DEBUG:
- _get_points = get_points
-
- def get_points(self):
- points = self._get_points()
- self._check(points)
- return points
-
- def contains(self, x, y):
- # Docstring inherited.
- return self._bbox.contains(*self._transform.inverted().transform((x, y)))
-
- def fully_contains(self, x, y):
- # Docstring inherited.
- return self._bbox.fully_contains(*self._transform.inverted().transform((x, y)))
-
-
-class LockableBbox(BboxBase):
- """
- A `Bbox` where some elements may be locked at certain values.
-
- When the child bounding box changes, the bounds of this bbox will update
- accordingly with the exception of the locked elements.
- """
- def __init__(self, bbox, x0=None, y0=None, x1=None, y1=None, **kwargs):
- """
- Parameters
- ----------
- bbox : `Bbox`
- The child bounding box to wrap.
-
- x0 : float or None
- The locked value for x0, or None to leave unlocked.
-
- y0 : float or None
- The locked value for y0, or None to leave unlocked.
-
- x1 : float or None
- The locked value for x1, or None to leave unlocked.
-
- y1 : float or None
- The locked value for y1, or None to leave unlocked.
-
- """
- if not bbox.is_bbox:
- raise ValueError("'bbox' is not a bbox")
-
- super().__init__(**kwargs)
- self._bbox = bbox
- self.set_children(bbox)
- self._points = None
- fp = [x0, y0, x1, y1]
- mask = [val is None for val in fp]
- self._locked_points = np.ma.array(fp, float, mask=mask).reshape((2, 2))
-
- __str__ = _make_str_method("_bbox", "_locked_points")
-
- def get_points(self):
- # docstring inherited
- if self._invalid:
- points = self._bbox.get_points()
- self._points = np.where(self._locked_points.mask,
- points,
- self._locked_points)
- self._invalid = 0
- return self._points
-
- if DEBUG:
- _get_points = get_points
-
- def get_points(self):
- points = self._get_points()
- self._check(points)
- return points
-
- @property
- def locked_x0(self):
- """
- float or None: The value used for the locked x0.
- """
- if self._locked_points.mask[0, 0]:
- return None
- else:
- return self._locked_points[0, 0]
-
- @locked_x0.setter
- def locked_x0(self, x0):
- self._locked_points.mask[0, 0] = x0 is None
- self._locked_points.data[0, 0] = x0
- self.invalidate()
-
- @property
- def locked_y0(self):
- """
- float or None: The value used for the locked y0.
- """
- if self._locked_points.mask[0, 1]:
- return None
- else:
- return self._locked_points[0, 1]
-
- @locked_y0.setter
- def locked_y0(self, y0):
- self._locked_points.mask[0, 1] = y0 is None
- self._locked_points.data[0, 1] = y0
- self.invalidate()
-
- @property
- def locked_x1(self):
- """
- float or None: The value used for the locked x1.
- """
- if self._locked_points.mask[1, 0]:
- return None
- else:
- return self._locked_points[1, 0]
-
- @locked_x1.setter
- def locked_x1(self, x1):
- self._locked_points.mask[1, 0] = x1 is None
- self._locked_points.data[1, 0] = x1
- self.invalidate()
-
- @property
- def locked_y1(self):
- """
- float or None: The value used for the locked y1.
- """
- if self._locked_points.mask[1, 1]:
- return None
- else:
- return self._locked_points[1, 1]
-
- @locked_y1.setter
- def locked_y1(self, y1):
- self._locked_points.mask[1, 1] = y1 is None
- self._locked_points.data[1, 1] = y1
- self.invalidate()
-
-
-class Transform(TransformNode):
- """
- The base class of all `TransformNode` instances that
- actually perform a transformation.
-
- All non-affine transformations should be subclasses of this class.
- New affine transformations should be subclasses of `Affine2D`.
-
- Subclasses of this class should override the following members (at
- minimum):
-
- - :attr:`input_dims`
- - :attr:`output_dims`
- - :meth:`transform`
- - :meth:`inverted` (if an inverse exists)
-
- The following attributes may be overridden if the default is unsuitable:
-
- - :attr:`is_separable` (defaults to True for 1D -> 1D transforms, False
- otherwise)
- - :attr:`has_inverse` (defaults to True if :meth:`inverted` is overridden,
- False otherwise)
-
- If the transform needs to do something non-standard with
- `matplotlib.path.Path` objects, such as adding curves
- where there were once line segments, it should override:
-
- - :meth:`transform_path`
- """
-
- input_dims = None
- """
- The number of input dimensions of this transform.
- Must be overridden (with integers) in the subclass.
- """
-
- output_dims = None
- """
- The number of output dimensions of this transform.
- Must be overridden (with integers) in the subclass.
- """
-
- is_separable = False
- """True if this transform is separable in the x- and y- dimensions."""
-
- has_inverse = False
- """True if this transform has a corresponding inverse transform."""
-
- def __init_subclass__(cls):
- # 1d transforms are always separable; we assume higher-dimensional ones
- # are not but subclasses can also directly set is_separable -- this is
- # verified by checking whether "is_separable" appears more than once in
- # the class's MRO (it appears once in Transform).
- if (sum("is_separable" in vars(parent) for parent in cls.__mro__) == 1
- and cls.input_dims == cls.output_dims == 1):
- cls.is_separable = True
- # Transform.inverted raises NotImplementedError; we assume that if this
- # is overridden then the transform is invertible but subclass can also
- # directly set has_inverse.
- if (sum("has_inverse" in vars(parent) for parent in cls.__mro__) == 1
- and hasattr(cls, "inverted")
- and cls.inverted is not Transform.inverted):
- cls.has_inverse = True
-
- def __add__(self, other):
- """
- Compose two transforms together so that *self* is followed by *other*.
-
- ``A + B`` returns a transform ``C`` so that
- ``C.transform(x) == B.transform(A.transform(x))``.
- """
- return (composite_transform_factory(self, other)
- if isinstance(other, Transform) else
- NotImplemented)
-
- # Equality is based on object identity for `Transform`s (so we don't
- # override `__eq__`), but some subclasses, such as TransformWrapper &
- # AffineBase, override this behavior.
-
- def _iter_break_from_left_to_right(self):
- """
- Return an iterator breaking down this transform stack from left to
- right recursively. If self == ((A, N), A) then the result will be an
- iterator which yields I : ((A, N), A), followed by A : (N, A),
- followed by (A, N) : (A), but not ((A, N), A) : I.
-
- This is equivalent to flattening the stack then yielding
- ``flat_stack[:i], flat_stack[i:]`` where i=0..(n-1).
- """
- yield IdentityTransform(), self
-
- @property
- def depth(self):
- """
- Return the number of transforms which have been chained
- together to form this Transform instance.
-
- .. note::
-
- For the special case of a Composite transform, the maximum depth
- of the two is returned.
-
- """
- return 1
-
- def contains_branch(self, other):
- """
- Return whether the given transform is a sub-tree of this transform.
-
- This routine uses transform equality to identify sub-trees, therefore
- in many situations it is object id which will be used.
-
- For the case where the given transform represents the whole
- of this transform, returns True.
- """
- if self.depth < other.depth:
- return False
-
- # check that a subtree is equal to other (starting from self)
- for _, sub_tree in self._iter_break_from_left_to_right():
- if sub_tree == other:
- return True
- return False
-
- def contains_branch_seperately(self, other_transform):
- """
- Return whether the given branch is a sub-tree of this transform on
- each separate dimension.
-
- A common use for this method is to identify if a transform is a blended
- transform containing an Axes' data transform. e.g.::
-
- x_isdata, y_isdata = trans.contains_branch_seperately(ax.transData)
-
- """
- if self.output_dims != 2:
- raise ValueError('contains_branch_seperately only supports '
- 'transforms with 2 output dimensions')
- # for a non-blended transform each separate dimension is the same, so
- # just return the appropriate shape.
- return [self.contains_branch(other_transform)] * 2
-
- def __sub__(self, other):
- """
- Compose *self* with the inverse of *other*, cancelling identical terms
- if any::
-
- # In general:
- A - B == A + B.inverted()
- # (but see note regarding frozen transforms below).
-
- # If A "ends with" B (i.e. A == A' + B for some A') we can cancel
- # out B:
- (A' + B) - B == A'
-
- # Likewise, if B "starts with" A (B = A + B'), we can cancel out A:
- A - (A + B') == B'.inverted() == B'^-1
-
- Cancellation (rather than naively returning ``A + B.inverted()``) is
- important for multiple reasons:
-
- - It avoids floating-point inaccuracies when computing the inverse of
- B: ``B - B`` is guaranteed to cancel out exactly (resulting in the
- identity transform), whereas ``B + B.inverted()`` may differ by a
- small epsilon.
- - ``B.inverted()`` always returns a frozen transform: if one computes
- ``A + B + B.inverted()`` and later mutates ``B``, then
- ``B.inverted()`` won't be updated and the last two terms won't cancel
- out anymore; on the other hand, ``A + B - B`` will always be equal to
- ``A`` even if ``B`` is mutated.
- """
- # we only know how to do this operation if other is a Transform.
- if not isinstance(other, Transform):
- return NotImplemented
- for remainder, sub_tree in self._iter_break_from_left_to_right():
- if sub_tree == other:
- return remainder
- for remainder, sub_tree in other._iter_break_from_left_to_right():
- if sub_tree == self:
- if not remainder.has_inverse:
- raise ValueError(
- "The shortcut cannot be computed since 'other' "
- "includes a non-invertible component")
- return remainder.inverted()
- # if we have got this far, then there was no shortcut possible
- if other.has_inverse:
- return self + other.inverted()
- else:
- raise ValueError('It is not possible to compute transA - transB '
- 'since transB cannot be inverted and there is no '
- 'shortcut possible.')
-
- def __array__(self, *args, **kwargs):
- """Array interface to get at this Transform's affine matrix."""
- return self.get_affine().get_matrix()
-
- def transform(self, values):
- """
- Apply this transformation on the given array of *values*.
-
- Parameters
- ----------
- values : array-like
- The input values as an array of length :attr:`input_dims` or
- shape (N, :attr:`input_dims`).
-
- Returns
- -------
- array
- The output values as an array of length :attr:`output_dims` or
- shape (N, :attr:`output_dims`), depending on the input.
- """
- # Ensure that values is a 2d array (but remember whether
- # we started with a 1d or 2d array).
- values = np.asanyarray(values)
- ndim = values.ndim
- values = values.reshape((-1, self.input_dims))
-
- # Transform the values
- res = self.transform_affine(self.transform_non_affine(values))
-
- # Convert the result back to the shape of the input values.
- if ndim == 0:
- assert not np.ma.is_masked(res) # just to be on the safe side
- return res[0, 0]
- if ndim == 1:
- return res.reshape(-1)
- elif ndim == 2:
- return res
- raise ValueError(
- "Input values must have shape (N, {dims}) or ({dims},)"
- .format(dims=self.input_dims))
-
- def transform_affine(self, values):
- """
- Apply only the affine part of this transformation on the
- given array of values.
-
- ``transform(values)`` is always equivalent to
- ``transform_affine(transform_non_affine(values))``.
-
- In non-affine transformations, this is generally a no-op. In
- affine transformations, this is equivalent to
- ``transform(values)``.
-
- Parameters
- ----------
- values : array
- The input values as an array of length :attr:`input_dims` or
- shape (N, :attr:`input_dims`).
-
- Returns
- -------
- array
- The output values as an array of length :attr:`output_dims` or
- shape (N, :attr:`output_dims`), depending on the input.
- """
- return self.get_affine().transform(values)
-
- def transform_non_affine(self, values):
- """
- Apply only the non-affine part of this transformation.
-
- ``transform(values)`` is always equivalent to
- ``transform_affine(transform_non_affine(values))``.
-
- In non-affine transformations, this is generally equivalent to
- ``transform(values)``. In affine transformations, this is
- always a no-op.
-
- Parameters
- ----------
- values : array
- The input values as an array of length :attr:`input_dims` or
- shape (N, :attr:`input_dims`).
-
- Returns
- -------
- array
- The output values as an array of length :attr:`output_dims` or
- shape (N, :attr:`output_dims`), depending on the input.
- """
- return values
-
- def transform_bbox(self, bbox):
- """
- Transform the given bounding box.
-
- For smarter transforms including caching (a common requirement in
- Matplotlib), see `TransformedBbox`.
- """
- return Bbox(self.transform(bbox.get_points()))
-
- def get_affine(self):
- """Get the affine part of this transform."""
- return IdentityTransform()
-
- def get_matrix(self):
- """Get the matrix for the affine part of this transform."""
- return self.get_affine().get_matrix()
-
- def transform_point(self, point):
- """
- Return a transformed point.
-
- This function is only kept for backcompatibility; the more general
- `.transform` method is capable of transforming both a list of points
- and a single point.
-
- The point is given as a sequence of length :attr:`input_dims`.
- The transformed point is returned as a sequence of length
- :attr:`output_dims`.
- """
- if len(point) != self.input_dims:
- raise ValueError("The length of 'point' must be 'self.input_dims'")
- return self.transform(point)
-
- def transform_path(self, path):
- """
- Apply the transform to `.Path` *path*, returning a new `.Path`.
-
- In some cases, this transform may insert curves into the path
- that began as line segments.
- """
- return self.transform_path_affine(self.transform_path_non_affine(path))
-
- def transform_path_affine(self, path):
- """
- Apply the affine part of this transform to `.Path` *path*, returning a
- new `.Path`.
-
- ``transform_path(path)`` is equivalent to
- ``transform_path_affine(transform_path_non_affine(values))``.
- """
- return self.get_affine().transform_path_affine(path)
-
- def transform_path_non_affine(self, path):
- """
- Apply the non-affine part of this transform to `.Path` *path*,
- returning a new `.Path`.
-
- ``transform_path(path)`` is equivalent to
- ``transform_path_affine(transform_path_non_affine(values))``.
- """
- x = self.transform_non_affine(path.vertices)
- return Path._fast_from_codes_and_verts(x, path.codes, path)
-
- def transform_angles(self, angles, pts, radians=False, pushoff=1e-5):
- """
- Transform a set of angles anchored at specific locations.
-
- Parameters
- ----------
- angles : (N,) array-like
- The angles to transform.
- pts : (N, 2) array-like
- The points where the angles are anchored.
- radians : bool, default: False
- Whether *angles* are radians or degrees.
- pushoff : float
- For each point in *pts* and angle in *angles*, the transformed
- angle is computed by transforming a segment of length *pushoff*
- starting at that point and making that angle relative to the
- horizontal axis, and measuring the angle between the horizontal
- axis and the transformed segment.
-
- Returns
- -------
- (N,) array
- """
- # Must be 2D
- if self.input_dims != 2 or self.output_dims != 2:
- raise NotImplementedError('Only defined in 2D')
- angles = np.asarray(angles)
- pts = np.asarray(pts)
- _api.check_shape((None, 2), pts=pts)
- _api.check_shape((None,), angles=angles)
- if len(angles) != len(pts):
- raise ValueError("There must be as many 'angles' as 'pts'")
- # Convert to radians if desired
- if not radians:
- angles = np.deg2rad(angles)
- # Move a short distance away
- pts2 = pts + pushoff * np.column_stack([np.cos(angles),
- np.sin(angles)])
- # Transform both sets of points
- tpts = self.transform(pts)
- tpts2 = self.transform(pts2)
- # Calculate transformed angles
- d = tpts2 - tpts
- a = np.arctan2(d[:, 1], d[:, 0])
- # Convert back to degrees if desired
- if not radians:
- a = np.rad2deg(a)
- return a
-
- def inverted(self):
- """
- Return the corresponding inverse transformation.
-
- It holds ``x == self.inverted().transform(self.transform(x))``.
-
- The return value of this method should be treated as
- temporary. An update to *self* does not cause a corresponding
- update to its inverted copy.
- """
- raise NotImplementedError()
-
-
-class TransformWrapper(Transform):
- """
- A helper class that holds a single child transform and acts
- equivalently to it.
-
- This is useful if a node of the transform tree must be replaced at
- run time with a transform of a different type. This class allows
- that replacement to correctly trigger invalidation.
-
- `TransformWrapper` instances must have the same input and output dimensions
- during their entire lifetime, so the child transform may only be replaced
- with another child transform of the same dimensions.
- """
-
- pass_through = True
-
- def __init__(self, child):
- """
- *child*: A `Transform` instance. This child may later
- be replaced with :meth:`set`.
- """
- _api.check_isinstance(Transform, child=child)
- super().__init__()
- self.set(child)
-
- def __eq__(self, other):
- return self._child.__eq__(other)
-
- __str__ = _make_str_method("_child")
-
- def frozen(self):
- # docstring inherited
- return self._child.frozen()
-
- def set(self, child):
- """
- Replace the current child of this transform with another one.
-
- The new child must have the same number of input and output
- dimensions as the current child.
- """
- if hasattr(self, "_child"): # Absent during init.
- self.invalidate()
- new_dims = (child.input_dims, child.output_dims)
- old_dims = (self._child.input_dims, self._child.output_dims)
- if new_dims != old_dims:
- raise ValueError(
- f"The input and output dims of the new child {new_dims} "
- f"do not match those of current child {old_dims}")
- self._child._parents.pop(id(self), None)
-
- self._child = child
- self.set_children(child)
-
- self.transform = child.transform
- self.transform_affine = child.transform_affine
- self.transform_non_affine = child.transform_non_affine
- self.transform_path = child.transform_path
- self.transform_path_affine = child.transform_path_affine
- self.transform_path_non_affine = child.transform_path_non_affine
- self.get_affine = child.get_affine
- self.inverted = child.inverted
- self.get_matrix = child.get_matrix
- # note we do not wrap other properties here since the transform's
- # child can be changed with WrappedTransform.set and so checking
- # is_affine and other such properties may be dangerous.
-
- self._invalid = 0
- self.invalidate()
- self._invalid = 0
-
- input_dims = property(lambda self: self._child.input_dims)
- output_dims = property(lambda self: self._child.output_dims)
- is_affine = property(lambda self: self._child.is_affine)
- is_separable = property(lambda self: self._child.is_separable)
- has_inverse = property(lambda self: self._child.has_inverse)
-
-
-class AffineBase(Transform):
- """
- The base class of all affine transformations of any number of dimensions.
- """
- is_affine = True
-
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
- self._inverted = None
-
- def __array__(self, *args, **kwargs):
- # optimises the access of the transform matrix vs. the superclass
- return self.get_matrix()
-
- def __eq__(self, other):
- if getattr(other, "is_affine", False) and hasattr(other, "get_matrix"):
- return (self.get_matrix() == other.get_matrix()).all()
- return NotImplemented
-
- def transform(self, values):
- # docstring inherited
- return self.transform_affine(values)
-
- def transform_affine(self, values):
- # docstring inherited
- raise NotImplementedError('Affine subclasses should override this '
- 'method.')
-
- @_api.rename_parameter("3.8", "points", "values")
- def transform_non_affine(self, values):
- # docstring inherited
- return values
-
- def transform_path(self, path):
- # docstring inherited
- return self.transform_path_affine(path)
-
- def transform_path_affine(self, path):
- # docstring inherited
- return Path(self.transform_affine(path.vertices),
- path.codes, path._interpolation_steps)
-
- def transform_path_non_affine(self, path):
- # docstring inherited
- return path
-
- def get_affine(self):
- # docstring inherited
- return self
-
-
-class Affine2DBase(AffineBase):
- """
- The base class of all 2D affine transformations.
-
- 2D affine transformations are performed using a 3x3 numpy array::
-
- a c e
- b d f
- 0 0 1
-
- This class provides the read-only interface. For a mutable 2D
- affine transformation, use `Affine2D`.
-
- Subclasses of this class will generally only need to override a
- constructor and `~.Transform.get_matrix` that generates a custom 3x3 matrix.
- """
- input_dims = 2
- output_dims = 2
-
- def frozen(self):
- # docstring inherited
- return Affine2D(self.get_matrix().copy())
-
- @property
- def is_separable(self):
- mtx = self.get_matrix()
- return mtx[0, 1] == mtx[1, 0] == 0.0
-
- def to_values(self):
- """
- Return the values of the matrix as an ``(a, b, c, d, e, f)`` tuple.
- """
- mtx = self.get_matrix()
- return tuple(mtx[:2].swapaxes(0, 1).flat)
-
- @_api.rename_parameter("3.8", "points", "values")
- def transform_affine(self, values):
- mtx = self.get_matrix()
- if isinstance(values, np.ma.MaskedArray):
- tpoints = affine_transform(values.data, mtx)
- return np.ma.MaskedArray(tpoints, mask=np.ma.getmask(values))
- return affine_transform(values, mtx)
-
- if DEBUG:
- _transform_affine = transform_affine
-
- @_api.rename_parameter("3.8", "points", "values")
- def transform_affine(self, values):
- # docstring inherited
- # The major speed trap here is just converting to the
- # points to an array in the first place. If we can use
- # more arrays upstream, that should help here.
- if not isinstance(values, np.ndarray):
- _api.warn_external(
- f'A non-numpy array of type {type(values)} was passed in '
- f'for transformation, which results in poor performance.')
- return self._transform_affine(values)
-
- def inverted(self):
- # docstring inherited
- if self._inverted is None or self._invalid:
- mtx = self.get_matrix()
- shorthand_name = None
- if self._shorthand_name:
- shorthand_name = '(%s)-1' % self._shorthand_name
- self._inverted = Affine2D(inv(mtx), shorthand_name=shorthand_name)
- self._invalid = 0
- return self._inverted
-
-
-class Affine2D(Affine2DBase):
- """
- A mutable 2D affine transformation.
- """
-
- def __init__(self, matrix=None, **kwargs):
- """
- Initialize an Affine transform from a 3x3 numpy float array::
-
- a c e
- b d f
- 0 0 1
-
- If *matrix* is None, initialize with the identity transform.
- """
- super().__init__(**kwargs)
- if matrix is None:
- # A bit faster than np.identity(3).
- matrix = IdentityTransform._mtx
- self._mtx = matrix.copy()
- self._invalid = 0
-
- _base_str = _make_str_method("_mtx")
-
- def __str__(self):
- return (self._base_str()
- if (self._mtx != np.diag(np.diag(self._mtx))).any()
- else f"Affine2D().scale({self._mtx[0, 0]}, {self._mtx[1, 1]})"
- if self._mtx[0, 0] != self._mtx[1, 1]
- else f"Affine2D().scale({self._mtx[0, 0]})")
-
- @staticmethod
- def from_values(a, b, c, d, e, f):
- """
- Create a new Affine2D instance from the given values::
-
- a c e
- b d f
- 0 0 1
-
- .
- """
- return Affine2D(
- np.array([a, c, e, b, d, f, 0.0, 0.0, 1.0], float).reshape((3, 3)))
-
- def get_matrix(self):
- """
- Get the underlying transformation matrix as a 3x3 array::
-
- a c e
- b d f
- 0 0 1
-
- .
- """
- if self._invalid:
- self._inverted = None
- self._invalid = 0
- return self._mtx
-
- def set_matrix(self, mtx):
- """
- Set the underlying transformation matrix from a 3x3 array::
-
- a c e
- b d f
- 0 0 1
-
- .
- """
- self._mtx = mtx
- self.invalidate()
-
- def set(self, other):
- """
- Set this transformation from the frozen copy of another
- `Affine2DBase` object.
- """
- _api.check_isinstance(Affine2DBase, other=other)
- self._mtx = other.get_matrix()
- self.invalidate()
-
- def clear(self):
- """
- Reset the underlying matrix to the identity transform.
- """
- # A bit faster than np.identity(3).
- self._mtx = IdentityTransform._mtx.copy()
- self.invalidate()
- return self
-
- def rotate(self, theta):
- """
- Add a rotation (in radians) to this transform in place.
-
- Returns *self*, so this method can easily be chained with more
- calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
- and :meth:`scale`.
- """
- a = math.cos(theta)
- b = math.sin(theta)
- mtx = self._mtx
- # Operating and assigning one scalar at a time is much faster.
- (xx, xy, x0), (yx, yy, y0), _ = mtx.tolist()
- # mtx = [[a -b 0], [b a 0], [0 0 1]] * mtx
- mtx[0, 0] = a * xx - b * yx
- mtx[0, 1] = a * xy - b * yy
- mtx[0, 2] = a * x0 - b * y0
- mtx[1, 0] = b * xx + a * yx
- mtx[1, 1] = b * xy + a * yy
- mtx[1, 2] = b * x0 + a * y0
- self.invalidate()
- return self
-
- def rotate_deg(self, degrees):
- """
- Add a rotation (in degrees) to this transform in place.
-
- Returns *self*, so this method can easily be chained with more
- calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
- and :meth:`scale`.
- """
- return self.rotate(math.radians(degrees))
-
- def rotate_around(self, x, y, theta):
- """
- Add a rotation (in radians) around the point (x, y) in place.
-
- Returns *self*, so this method can easily be chained with more
- calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
- and :meth:`scale`.
- """
- return self.translate(-x, -y).rotate(theta).translate(x, y)
-
- def rotate_deg_around(self, x, y, degrees):
- """
- Add a rotation (in degrees) around the point (x, y) in place.
-
- Returns *self*, so this method can easily be chained with more
- calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
- and :meth:`scale`.
- """
- # Cast to float to avoid wraparound issues with uint8's
- x, y = float(x), float(y)
- return self.translate(-x, -y).rotate_deg(degrees).translate(x, y)
-
- def translate(self, tx, ty):
- """
- Add a translation in place.
-
- Returns *self*, so this method can easily be chained with more
- calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
- and :meth:`scale`.
- """
- self._mtx[0, 2] += tx
- self._mtx[1, 2] += ty
- self.invalidate()
- return self
-
- def scale(self, sx, sy=None):
- """
- Add a scale in place.
-
- If *sy* is None, the same scale is applied in both the *x*- and
- *y*-directions.
-
- Returns *self*, so this method can easily be chained with more
- calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
- and :meth:`scale`.
- """
- if sy is None:
- sy = sx
- # explicit element-wise scaling is fastest
- self._mtx[0, 0] *= sx
- self._mtx[0, 1] *= sx
- self._mtx[0, 2] *= sx
- self._mtx[1, 0] *= sy
- self._mtx[1, 1] *= sy
- self._mtx[1, 2] *= sy
- self.invalidate()
- return self
-
- def skew(self, xShear, yShear):
- """
- Add a skew in place.
-
- *xShear* and *yShear* are the shear angles along the *x*- and
- *y*-axes, respectively, in radians.
-
- Returns *self*, so this method can easily be chained with more
- calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
- and :meth:`scale`.
- """
- rx = math.tan(xShear)
- ry = math.tan(yShear)
- mtx = self._mtx
- # Operating and assigning one scalar at a time is much faster.
- (xx, xy, x0), (yx, yy, y0), _ = mtx.tolist()
- # mtx = [[1 rx 0], [ry 1 0], [0 0 1]] * mtx
- mtx[0, 0] += rx * yx
- mtx[0, 1] += rx * yy
- mtx[0, 2] += rx * y0
- mtx[1, 0] += ry * xx
- mtx[1, 1] += ry * xy
- mtx[1, 2] += ry * x0
- self.invalidate()
- return self
-
- def skew_deg(self, xShear, yShear):
- """
- Add a skew in place.
-
- *xShear* and *yShear* are the shear angles along the *x*- and
- *y*-axes, respectively, in degrees.
-
- Returns *self*, so this method can easily be chained with more
- calls to :meth:`rotate`, :meth:`rotate_deg`, :meth:`translate`
- and :meth:`scale`.
- """
- return self.skew(math.radians(xShear), math.radians(yShear))
-
-
-class IdentityTransform(Affine2DBase):
- """
- A special class that does one thing, the identity transform, in a
- fast way.
- """
- _mtx = np.identity(3)
-
- def frozen(self):
- # docstring inherited
- return self
-
- __str__ = _make_str_method()
-
- def get_matrix(self):
- # docstring inherited
- return self._mtx
-
- @_api.rename_parameter("3.8", "points", "values")
- def transform(self, values):
- # docstring inherited
- return np.asanyarray(values)
-
- @_api.rename_parameter("3.8", "points", "values")
- def transform_affine(self, values):
- # docstring inherited
- return np.asanyarray(values)
-
- @_api.rename_parameter("3.8", "points", "values")
- def transform_non_affine(self, values):
- # docstring inherited
- return np.asanyarray(values)
-
- def transform_path(self, path):
- # docstring inherited
- return path
-
- def transform_path_affine(self, path):
- # docstring inherited
- return path
-
- def transform_path_non_affine(self, path):
- # docstring inherited
- return path
-
- def get_affine(self):
- # docstring inherited
- return self
-
- def inverted(self):
- # docstring inherited
- return self
-
-
-class _BlendedMixin:
- """Common methods for `BlendedGenericTransform` and `BlendedAffine2D`."""
-
- def __eq__(self, other):
- if isinstance(other, (BlendedAffine2D, BlendedGenericTransform)):
- return (self._x == other._x) and (self._y == other._y)
- elif self._x == self._y:
- return self._x == other
- else:
- return NotImplemented
-
- def contains_branch_seperately(self, transform):
- return (self._x.contains_branch(transform),
- self._y.contains_branch(transform))
-
- __str__ = _make_str_method("_x", "_y")
-
-
-class BlendedGenericTransform(_BlendedMixin, Transform):
- """
- A "blended" transform uses one transform for the *x*-direction, and
- another transform for the *y*-direction.
-
- This "generic" version can handle any given child transform in the
- *x*- and *y*-directions.
- """
- input_dims = 2
- output_dims = 2
- is_separable = True
- pass_through = True
-
- def __init__(self, x_transform, y_transform, **kwargs):
- """
- Create a new "blended" transform using *x_transform* to transform the
- *x*-axis and *y_transform* to transform the *y*-axis.
-
- You will generally not call this constructor directly but use the
- `blended_transform_factory` function instead, which can determine
- automatically which kind of blended transform to create.
- """
- Transform.__init__(self, **kwargs)
- self._x = x_transform
- self._y = y_transform
- self.set_children(x_transform, y_transform)
- self._affine = None
-
- @property
- def depth(self):
- return max(self._x.depth, self._y.depth)
-
- def contains_branch(self, other):
- # A blended transform cannot possibly contain a branch from two
- # different transforms.
- return False
-
- is_affine = property(lambda self: self._x.is_affine and self._y.is_affine)
- has_inverse = property(
- lambda self: self._x.has_inverse and self._y.has_inverse)
-
- def frozen(self):
- # docstring inherited
- return blended_transform_factory(self._x.frozen(), self._y.frozen())
-
- @_api.rename_parameter("3.8", "points", "values")
- def transform_non_affine(self, values):
- # docstring inherited
- if self._x.is_affine and self._y.is_affine:
- return values
- x = self._x
- y = self._y
-
- if x == y and x.input_dims == 2:
- return x.transform_non_affine(values)
-
- if x.input_dims == 2:
- x_points = x.transform_non_affine(values)[:, 0:1]
- else:
- x_points = x.transform_non_affine(values[:, 0])
- x_points = x_points.reshape((len(x_points), 1))
-
- if y.input_dims == 2:
- y_points = y.transform_non_affine(values)[:, 1:]
- else:
- y_points = y.transform_non_affine(values[:, 1])
- y_points = y_points.reshape((len(y_points), 1))
-
- if (isinstance(x_points, np.ma.MaskedArray) or
- isinstance(y_points, np.ma.MaskedArray)):
- return np.ma.concatenate((x_points, y_points), 1)
- else:
- return np.concatenate((x_points, y_points), 1)
-
- def inverted(self):
- # docstring inherited
- return BlendedGenericTransform(self._x.inverted(), self._y.inverted())
-
- def get_affine(self):
- # docstring inherited
- if self._invalid or self._affine is None:
- if self._x == self._y:
- self._affine = self._x.get_affine()
- else:
- x_mtx = self._x.get_affine().get_matrix()
- y_mtx = self._y.get_affine().get_matrix()
- # We already know the transforms are separable, so we can skip
- # setting b and c to zero.
- mtx = np.array([x_mtx[0], y_mtx[1], [0.0, 0.0, 1.0]])
- self._affine = Affine2D(mtx)
- self._invalid = 0
- return self._affine
-
-
-class BlendedAffine2D(_BlendedMixin, Affine2DBase):
- """
- A "blended" transform uses one transform for the *x*-direction, and
- another transform for the *y*-direction.
-
- This version is an optimization for the case where both child
- transforms are of type `Affine2DBase`.
- """
-
- is_separable = True
-
- def __init__(self, x_transform, y_transform, **kwargs):
- """
- Create a new "blended" transform using *x_transform* to transform the
- *x*-axis and *y_transform* to transform the *y*-axis.
-
- Both *x_transform* and *y_transform* must be 2D affine transforms.
-
- You will generally not call this constructor directly but use the
- `blended_transform_factory` function instead, which can determine
- automatically which kind of blended transform to create.
- """
- is_affine = x_transform.is_affine and y_transform.is_affine
- is_separable = x_transform.is_separable and y_transform.is_separable
- is_correct = is_affine and is_separable
- if not is_correct:
- raise ValueError("Both *x_transform* and *y_transform* must be 2D "
- "affine transforms")
-
- Transform.__init__(self, **kwargs)
- self._x = x_transform
- self._y = y_transform
- self.set_children(x_transform, y_transform)
-
- Affine2DBase.__init__(self)
- self._mtx = None
-
- def get_matrix(self):
- # docstring inherited
- if self._invalid:
- if self._x == self._y:
- self._mtx = self._x.get_matrix()
- else:
- x_mtx = self._x.get_matrix()
- y_mtx = self._y.get_matrix()
- # We already know the transforms are separable, so we can skip
- # setting b and c to zero.
- self._mtx = np.array([x_mtx[0], y_mtx[1], [0.0, 0.0, 1.0]])
- self._inverted = None
- self._invalid = 0
- return self._mtx
-
-
-def blended_transform_factory(x_transform, y_transform):
- """
- Create a new "blended" transform using *x_transform* to transform
- the *x*-axis and *y_transform* to transform the *y*-axis.
-
- A faster version of the blended transform is returned for the case
- where both child transforms are affine.
- """
- if (isinstance(x_transform, Affine2DBase) and
- isinstance(y_transform, Affine2DBase)):
- return BlendedAffine2D(x_transform, y_transform)
- return BlendedGenericTransform(x_transform, y_transform)
-
-
-class CompositeGenericTransform(Transform):
- """
- A composite transform formed by applying transform *a* then
- transform *b*.
-
- This "generic" version can handle any two arbitrary
- transformations.
- """
- pass_through = True
-
- def __init__(self, a, b, **kwargs):
- """
- Create a new composite transform that is the result of
- applying transform *a* then transform *b*.
-
- You will generally not call this constructor directly but write ``a +
- b`` instead, which will automatically choose the best kind of composite
- transform instance to create.
- """
- if a.output_dims != b.input_dims:
- raise ValueError("The output dimension of 'a' must be equal to "
- "the input dimensions of 'b'")
- self.input_dims = a.input_dims
- self.output_dims = b.output_dims
-
- super().__init__(**kwargs)
- self._a = a
- self._b = b
- self.set_children(a, b)
-
- def frozen(self):
- # docstring inherited
- self._invalid = 0
- frozen = composite_transform_factory(
- self._a.frozen(), self._b.frozen())
- if not isinstance(frozen, CompositeGenericTransform):
- return frozen.frozen()
- return frozen
-
- def _invalidate_internal(self, level, invalidating_node):
- # When the left child is invalidated at AFFINE_ONLY level and the right child is
- # non-affine, the composite transform is FULLY invalidated.
- if invalidating_node is self._a and not self._b.is_affine:
- level = Transform._INVALID_FULL
- super()._invalidate_internal(level, invalidating_node)
-
- def __eq__(self, other):
- if isinstance(other, (CompositeGenericTransform, CompositeAffine2D)):
- return self is other or (self._a == other._a
- and self._b == other._b)
- else:
- return False
-
- def _iter_break_from_left_to_right(self):
- for left, right in self._a._iter_break_from_left_to_right():
- yield left, right + self._b
- for left, right in self._b._iter_break_from_left_to_right():
- yield self._a + left, right
-
- depth = property(lambda self: self._a.depth + self._b.depth)
- is_affine = property(lambda self: self._a.is_affine and self._b.is_affine)
- is_separable = property(
- lambda self: self._a.is_separable and self._b.is_separable)
- has_inverse = property(
- lambda self: self._a.has_inverse and self._b.has_inverse)
-
- __str__ = _make_str_method("_a", "_b")
-
- @_api.rename_parameter("3.8", "points", "values")
- def transform_affine(self, values):
- # docstring inherited
- return self.get_affine().transform(values)
-
- @_api.rename_parameter("3.8", "points", "values")
- def transform_non_affine(self, values):
- # docstring inherited
- if self._a.is_affine and self._b.is_affine:
- return values
- elif not self._a.is_affine and self._b.is_affine:
- return self._a.transform_non_affine(values)
- else:
- return self._b.transform_non_affine(self._a.transform(values))
-
- def transform_path_non_affine(self, path):
- # docstring inherited
- if self._a.is_affine and self._b.is_affine:
- return path
- elif not self._a.is_affine and self._b.is_affine:
- return self._a.transform_path_non_affine(path)
- else:
- return self._b.transform_path_non_affine(
- self._a.transform_path(path))
-
- def get_affine(self):
- # docstring inherited
- if not self._b.is_affine:
- return self._b.get_affine()
- else:
- return Affine2D(np.dot(self._b.get_affine().get_matrix(),
- self._a.get_affine().get_matrix()))
-
- def inverted(self):
- # docstring inherited
- return CompositeGenericTransform(
- self._b.inverted(), self._a.inverted())
-
-
-class CompositeAffine2D(Affine2DBase):
- """
- A composite transform formed by applying transform *a* then transform *b*.
-
- This version is an optimization that handles the case where both *a*
- and *b* are 2D affines.
- """
- def __init__(self, a, b, **kwargs):
- """
- Create a new composite transform that is the result of
- applying `Affine2DBase` *a* then `Affine2DBase` *b*.
-
- You will generally not call this constructor directly but write ``a +
- b`` instead, which will automatically choose the best kind of composite
- transform instance to create.
- """
- if not a.is_affine or not b.is_affine:
- raise ValueError("'a' and 'b' must be affine transforms")
- if a.output_dims != b.input_dims:
- raise ValueError("The output dimension of 'a' must be equal to "
- "the input dimensions of 'b'")
- self.input_dims = a.input_dims
- self.output_dims = b.output_dims
-
- super().__init__(**kwargs)
- self._a = a
- self._b = b
- self.set_children(a, b)
- self._mtx = None
-
- @property
- def depth(self):
- return self._a.depth + self._b.depth
-
- def _iter_break_from_left_to_right(self):
- for left, right in self._a._iter_break_from_left_to_right():
- yield left, right + self._b
- for left, right in self._b._iter_break_from_left_to_right():
- yield self._a + left, right
-
- __str__ = _make_str_method("_a", "_b")
-
- def get_matrix(self):
- # docstring inherited
- if self._invalid:
- self._mtx = np.dot(
- self._b.get_matrix(),
- self._a.get_matrix())
- self._inverted = None
- self._invalid = 0
- return self._mtx
-
-
-def composite_transform_factory(a, b):
- """
- Create a new composite transform that is the result of applying
- transform a then transform b.
-
- Shortcut versions of the blended transform are provided for the
- case where both child transforms are affine, or one or the other
- is the identity transform.
-
- Composite transforms may also be created using the '+' operator,
- e.g.::
-
- c = a + b
- """
- # check to see if any of a or b are IdentityTransforms. We use
- # isinstance here to guarantee that the transforms will *always*
- # be IdentityTransforms. Since TransformWrappers are mutable,
- # use of equality here would be wrong.
- if isinstance(a, IdentityTransform):
- return b
- elif isinstance(b, IdentityTransform):
- return a
- elif isinstance(a, Affine2D) and isinstance(b, Affine2D):
- return CompositeAffine2D(a, b)
- return CompositeGenericTransform(a, b)
-
-
-class BboxTransform(Affine2DBase):
- """
- `BboxTransform` linearly transforms points from one `Bbox` to another.
- """
-
- is_separable = True
-
- def __init__(self, boxin, boxout, **kwargs):
- """
- Create a new `BboxTransform` that linearly transforms
- points from *boxin* to *boxout*.
- """
- if not boxin.is_bbox or not boxout.is_bbox:
- raise ValueError("'boxin' and 'boxout' must be bbox")
-
- super().__init__(**kwargs)
- self._boxin = boxin
- self._boxout = boxout
- self.set_children(boxin, boxout)
- self._mtx = None
- self._inverted = None
-
- __str__ = _make_str_method("_boxin", "_boxout")
-
- def get_matrix(self):
- # docstring inherited
- if self._invalid:
- inl, inb, inw, inh = self._boxin.bounds
- outl, outb, outw, outh = self._boxout.bounds
- x_scale = outw / inw
- y_scale = outh / inh
- if DEBUG and (x_scale == 0 or y_scale == 0):
- raise ValueError(
- "Transforming from or to a singular bounding box")
- self._mtx = np.array([[x_scale, 0.0 , (-inl*x_scale+outl)],
- [0.0 , y_scale, (-inb*y_scale+outb)],
- [0.0 , 0.0 , 1.0 ]],
- float)
- self._inverted = None
- self._invalid = 0
- return self._mtx
-
-
-class BboxTransformTo(Affine2DBase):
- """
- `BboxTransformTo` is a transformation that linearly transforms points from
- the unit bounding box to a given `Bbox`.
- """
-
- is_separable = True
-
- def __init__(self, boxout, **kwargs):
- """
- Create a new `BboxTransformTo` that linearly transforms
- points from the unit bounding box to *boxout*.
- """
- if not boxout.is_bbox:
- raise ValueError("'boxout' must be bbox")
-
- super().__init__(**kwargs)
- self._boxout = boxout
- self.set_children(boxout)
- self._mtx = None
- self._inverted = None
-
- __str__ = _make_str_method("_boxout")
-
- def get_matrix(self):
- # docstring inherited
- if self._invalid:
- outl, outb, outw, outh = self._boxout.bounds
- if DEBUG and (outw == 0 or outh == 0):
- raise ValueError("Transforming to a singular bounding box.")
- self._mtx = np.array([[outw, 0.0, outl],
- [ 0.0, outh, outb],
- [ 0.0, 0.0, 1.0]],
- float)
- self._inverted = None
- self._invalid = 0
- return self._mtx
-
-
-class BboxTransformToMaxOnly(BboxTransformTo):
- """
- `BboxTransformTo` is a transformation that linearly transforms points from
- the unit bounding box to a given `Bbox` with a fixed upper left of (0, 0).
- """
- def get_matrix(self):
- # docstring inherited
- if self._invalid:
- xmax, ymax = self._boxout.max
- if DEBUG and (xmax == 0 or ymax == 0):
- raise ValueError("Transforming to a singular bounding box.")
- self._mtx = np.array([[xmax, 0.0, 0.0],
- [ 0.0, ymax, 0.0],
- [ 0.0, 0.0, 1.0]],
- float)
- self._inverted = None
- self._invalid = 0
- return self._mtx
-
-
-class BboxTransformFrom(Affine2DBase):
- """
- `BboxTransformFrom` linearly transforms points from a given `Bbox` to the
- unit bounding box.
- """
- is_separable = True
-
- def __init__(self, boxin, **kwargs):
- if not boxin.is_bbox:
- raise ValueError("'boxin' must be bbox")
-
- super().__init__(**kwargs)
- self._boxin = boxin
- self.set_children(boxin)
- self._mtx = None
- self._inverted = None
-
- __str__ = _make_str_method("_boxin")
-
- def get_matrix(self):
- # docstring inherited
- if self._invalid:
- inl, inb, inw, inh = self._boxin.bounds
- if DEBUG and (inw == 0 or inh == 0):
- raise ValueError("Transforming from a singular bounding box.")
- x_scale = 1.0 / inw
- y_scale = 1.0 / inh
- self._mtx = np.array([[x_scale, 0.0 , (-inl*x_scale)],
- [0.0 , y_scale, (-inb*y_scale)],
- [0.0 , 0.0 , 1.0 ]],
- float)
- self._inverted = None
- self._invalid = 0
- return self._mtx
-
-
-class ScaledTranslation(Affine2DBase):
- """
- A transformation that translates by *xt* and *yt*, after *xt* and *yt*
- have been transformed by *scale_trans*.
- """
- def __init__(self, xt, yt, scale_trans, **kwargs):
- super().__init__(**kwargs)
- self._t = (xt, yt)
- self._scale_trans = scale_trans
- self.set_children(scale_trans)
- self._mtx = None
- self._inverted = None
-
- __str__ = _make_str_method("_t")
-
- def get_matrix(self):
- # docstring inherited
- if self._invalid:
- # A bit faster than np.identity(3).
- self._mtx = IdentityTransform._mtx.copy()
- self._mtx[:2, 2] = self._scale_trans.transform(self._t)
- self._invalid = 0
- self._inverted = None
- return self._mtx
-
-
-class AffineDeltaTransform(Affine2DBase):
- r"""
- A transform wrapper for transforming displacements between pairs of points.
-
- This class is intended to be used to transform displacements ("position
- deltas") between pairs of points (e.g., as the ``offset_transform``
- of `.Collection`\s): given a transform ``t`` such that ``t =
- AffineDeltaTransform(t) + offset``, ``AffineDeltaTransform``
- satisfies ``AffineDeltaTransform(a - b) == AffineDeltaTransform(a) -
- AffineDeltaTransform(b)``.
-
- This is implemented by forcing the offset components of the transform
- matrix to zero.
-
- This class is experimental as of 3.3, and the API may change.
- """
-
- def __init__(self, transform, **kwargs):
- super().__init__(**kwargs)
- self._base_transform = transform
-
- __str__ = _make_str_method("_base_transform")
-
- def get_matrix(self):
- if self._invalid:
- self._mtx = self._base_transform.get_matrix().copy()
- self._mtx[:2, -1] = 0
- return self._mtx
-
-
-class TransformedPath(TransformNode):
- """
- A `TransformedPath` caches a non-affine transformed copy of the
- `~.path.Path`. This cached copy is automatically updated when the
- non-affine part of the transform changes.
-
- .. note::
-
- Paths are considered immutable by this class. Any update to the
- path's vertices/codes will not trigger a transform recomputation.
-
- """
- def __init__(self, path, transform):
- """
- Parameters
- ----------
- path : `~.path.Path`
- transform : `Transform`
- """
- _api.check_isinstance(Transform, transform=transform)
- super().__init__()
- self._path = path
- self._transform = transform
- self.set_children(transform)
- self._transformed_path = None
- self._transformed_points = None
-
- def _revalidate(self):
- # only recompute if the invalidation includes the non_affine part of
- # the transform
- if (self._invalid == self._INVALID_FULL
- or self._transformed_path is None):
- self._transformed_path = \
- self._transform.transform_path_non_affine(self._path)
- self._transformed_points = \
- Path._fast_from_codes_and_verts(
- self._transform.transform_non_affine(self._path.vertices),
- None, self._path)
- self._invalid = 0
-
- def get_transformed_points_and_affine(self):
- """
- Return a copy of the child path, with the non-affine part of
- the transform already applied, along with the affine part of
- the path necessary to complete the transformation. Unlike
- :meth:`get_transformed_path_and_affine`, no interpolation will
- be performed.
- """
- self._revalidate()
- return self._transformed_points, self.get_affine()
-
- def get_transformed_path_and_affine(self):
- """
- Return a copy of the child path, with the non-affine part of
- the transform already applied, along with the affine part of
- the path necessary to complete the transformation.
- """
- self._revalidate()
- return self._transformed_path, self.get_affine()
-
- def get_fully_transformed_path(self):
- """
- Return a fully-transformed copy of the child path.
- """
- self._revalidate()
- return self._transform.transform_path_affine(self._transformed_path)
-
- def get_affine(self):
- return self._transform.get_affine()
-
-
-class TransformedPatchPath(TransformedPath):
- """
- A `TransformedPatchPath` caches a non-affine transformed copy of the
- `~.patches.Patch`. This cached copy is automatically updated when the
- non-affine part of the transform or the patch changes.
- """
-
- def __init__(self, patch):
- """
- Parameters
- ----------
- patch : `~.patches.Patch`
- """
- # Defer to TransformedPath.__init__.
- super().__init__(patch.get_path(), patch.get_transform())
- self._patch = patch
-
- def _revalidate(self):
- patch_path = self._patch.get_path()
- # Force invalidation if the patch path changed; otherwise, let base
- # class check invalidation.
- if patch_path != self._path:
- self._path = patch_path
- self._transformed_path = None
- super()._revalidate()
-
-
-def nonsingular(vmin, vmax, expander=0.001, tiny=1e-15, increasing=True):
- """
- Modify the endpoints of a range as needed to avoid singularities.
-
- Parameters
- ----------
- vmin, vmax : float
- The initial endpoints.
- expander : float, default: 0.001
- Fractional amount by which *vmin* and *vmax* are expanded if
- the original interval is too small, based on *tiny*.
- tiny : float, default: 1e-15
- Threshold for the ratio of the interval to the maximum absolute
- value of its endpoints. If the interval is smaller than
- this, it will be expanded. This value should be around
- 1e-15 or larger; otherwise the interval will be approaching
- the double precision resolution limit.
- increasing : bool, default: True
- If True, swap *vmin*, *vmax* if *vmin* > *vmax*.
-
- Returns
- -------
- vmin, vmax : float
- Endpoints, expanded and/or swapped if necessary.
- If either input is inf or NaN, or if both inputs are 0 or very
- close to zero, it returns -*expander*, *expander*.
- """
-
- if (not np.isfinite(vmin)) or (not np.isfinite(vmax)):
- return -expander, expander
-
- swapped = False
- if vmax < vmin:
- vmin, vmax = vmax, vmin
- swapped = True
-
- # Expand vmin, vmax to float: if they were integer types, they can wrap
- # around in abs (abs(np.int8(-128)) == -128) and vmax - vmin can overflow.
- vmin, vmax = map(float, [vmin, vmax])
-
- maxabsvalue = max(abs(vmin), abs(vmax))
- if maxabsvalue < (1e6 / tiny) * np.finfo(float).tiny:
- vmin = -expander
- vmax = expander
-
- elif vmax - vmin <= maxabsvalue * tiny:
- if vmax == 0 and vmin == 0:
- vmin = -expander
- vmax = expander
- else:
- vmin -= expander*abs(vmin)
- vmax += expander*abs(vmax)
-
- if swapped and not increasing:
- vmin, vmax = vmax, vmin
- return vmin, vmax
-
-
-def interval_contains(interval, val):
- """
- Check, inclusively, whether an interval includes a given value.
-
- Parameters
- ----------
- interval : (float, float)
- The endpoints of the interval.
- val : float
- Value to check is within interval.
-
- Returns
- -------
- bool
- Whether *val* is within the *interval*.
- """
- a, b = interval
- if a > b:
- a, b = b, a
- return a <= val <= b
-
-
-def _interval_contains_close(interval, val, rtol=1e-10):
- """
- Check, inclusively, whether an interval includes a given value, with the
- interval expanded by a small tolerance to admit floating point errors.
-
- Parameters
- ----------
- interval : (float, float)
- The endpoints of the interval.
- val : float
- Value to check is within interval.
- rtol : float, default: 1e-10
- Relative tolerance slippage allowed outside of the interval.
- For an interval ``[a, b]``, values
- ``a - rtol * (b - a) <= val <= b + rtol * (b - a)`` are considered
- inside the interval.
-
- Returns
- -------
- bool
- Whether *val* is within the *interval* (with tolerance).
- """
- a, b = interval
- if a > b:
- a, b = b, a
- rtol = (b - a) * rtol
- return a - rtol <= val <= b + rtol
-
-
-def interval_contains_open(interval, val):
- """
- Check, excluding endpoints, whether an interval includes a given value.
-
- Parameters
- ----------
- interval : (float, float)
- The endpoints of the interval.
- val : float
- Value to check is within interval.
-
- Returns
- -------
- bool
- Whether *val* is within the *interval*.
- """
- a, b = interval
- return a < val < b or a > val > b
-
-
-def offset_copy(trans, fig=None, x=0.0, y=0.0, units='inches'):
- """
- Return a new transform with an added offset.
-
- Parameters
- ----------
- trans : `Transform` subclass
- Any transform, to which offset will be applied.
- fig : `~matplotlib.figure.Figure`, default: None
- Current figure. It can be None if *units* are 'dots'.
- x, y : float, default: 0.0
- The offset to apply.
- units : {'inches', 'points', 'dots'}, default: 'inches'
- Units of the offset.
-
- Returns
- -------
- `Transform` subclass
- Transform with applied offset.
- """
- _api.check_in_list(['dots', 'points', 'inches'], units=units)
- if units == 'dots':
- return trans + Affine2D().translate(x, y)
- if fig is None:
- raise ValueError('For units of inches or points a fig kwarg is needed')
- if units == 'points':
- x /= 72.0
- y /= 72.0
- # Default units are 'inches'
- return trans + ScaledTranslation(x, y, fig.dpi_scale_trans)
diff --git a/contrib/python/matplotlib/py3/matplotlib/transforms.pyi b/contrib/python/matplotlib/py3/matplotlib/transforms.pyi
deleted file mode 100644
index 90a527e5bf..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/transforms.pyi
+++ /dev/null
@@ -1,335 +0,0 @@
-from .path import Path
-from .patches import Patch
-from .figure import Figure
-import numpy as np
-from numpy.typing import ArrayLike
-from collections.abc import Iterable, Sequence
-from typing import Literal
-
-DEBUG: bool
-
-class TransformNode:
- INVALID_NON_AFFINE: int
- INVALID_AFFINE: int
- INVALID: int
- is_bbox: bool
- # Implemented as a standard attr in base class, but functionally readonly and some subclasses implement as such
- @property
- def is_affine(self) -> bool: ...
- pass_through: bool
- def __init__(self, shorthand_name: str | None = ...) -> None: ...
- def __copy__(self) -> TransformNode: ...
- def invalidate(self) -> None: ...
- def set_children(self, *children: TransformNode) -> None: ...
- def frozen(self) -> TransformNode: ...
-
-class BboxBase(TransformNode):
- is_bbox: bool
- is_affine: bool
- def frozen(self) -> Bbox: ...
- def __array__(self, *args, **kwargs): ...
- @property
- def x0(self) -> float: ...
- @property
- def y0(self) -> float: ...
- @property
- def x1(self) -> float: ...
- @property
- def y1(self) -> float: ...
- @property
- def p0(self) -> tuple[float, float]: ...
- @property
- def p1(self) -> tuple[float, float]: ...
- @property
- def xmin(self) -> float: ...
- @property
- def ymin(self) -> float: ...
- @property
- def xmax(self) -> float: ...
- @property
- def ymax(self) -> float: ...
- @property
- def min(self) -> tuple[float, float]: ...
- @property
- def max(self) -> tuple[float, float]: ...
- @property
- def intervalx(self) -> tuple[float, float]: ...
- @property
- def intervaly(self) -> tuple[float, float]: ...
- @property
- def width(self) -> float: ...
- @property
- def height(self) -> float: ...
- @property
- def size(self) -> tuple[float, float]: ...
- @property
- def bounds(self) -> tuple[float, float, float, float]: ...
- @property
- def extents(self) -> tuple[float, float, float, float]: ...
- def get_points(self) -> np.ndarray: ...
- def containsx(self, x: float) -> bool: ...
- def containsy(self, y: float) -> bool: ...
- def contains(self, x: float, y: float) -> bool: ...
- def overlaps(self, other: BboxBase) -> bool: ...
- def fully_containsx(self, x: float) -> bool: ...
- def fully_containsy(self, y: float) -> bool: ...
- def fully_contains(self, x: float, y: float) -> bool: ...
- def fully_overlaps(self, other: BboxBase) -> bool: ...
- def transformed(self, transform: Transform) -> Bbox: ...
- coefs: dict[str, tuple[float, float]]
- # anchored type can be s/str/Literal["C", "SW", "S", "SE", "E", "NE", "N", "NW", "W"]
- def anchored(
- self, c: tuple[float, float] | str, container: BboxBase | None = ...
- ) -> Bbox: ...
- def shrunk(self, mx: float, my: float) -> Bbox: ...
- def shrunk_to_aspect(
- self,
- box_aspect: float,
- container: BboxBase | None = ...,
- fig_aspect: float = ...,
- ) -> Bbox: ...
- def splitx(self, *args: float) -> list[Bbox]: ...
- def splity(self, *args: float) -> list[Bbox]: ...
- def count_contains(self, vertices: ArrayLike) -> int: ...
- def count_overlaps(self, bboxes: Iterable[BboxBase]) -> int: ...
- def expanded(self, sw: float, sh: float) -> Bbox: ...
- def padded(self, w_pad: float, h_pad: float | None = ...) -> Bbox: ...
- def translated(self, tx: float, ty: float) -> Bbox: ...
- def corners(self) -> np.ndarray: ...
- def rotated(self, radians: float) -> Bbox: ...
- @staticmethod
- def union(bboxes: Sequence[BboxBase]) -> Bbox: ...
- @staticmethod
- def intersection(bbox1: BboxBase, bbox2: BboxBase) -> Bbox | None: ...
-
-class Bbox(BboxBase):
- def __init__(self, points: ArrayLike, **kwargs) -> None: ...
- @staticmethod
- def unit() -> Bbox: ...
- @staticmethod
- def null() -> Bbox: ...
- @staticmethod
- def from_bounds(x0: float, y0: float, width: float, height: float) -> Bbox: ...
- @staticmethod
- def from_extents(*args: float, minpos: float | None = ...) -> Bbox: ...
- def __format__(self, fmt: str) -> str: ...
- def ignore(self, value: bool) -> None: ...
- def update_from_path(
- self,
- path: Path,
- ignore: bool | None = ...,
- updatex: bool = ...,
- updatey: bool = ...,
- ) -> None: ...
- def update_from_data_x(self, x: ArrayLike, ignore: bool | None = ...) -> None: ...
- def update_from_data_y(self, y: ArrayLike, ignore: bool | None = ...) -> None: ...
- def update_from_data_xy(
- self,
- xy: ArrayLike,
- ignore: bool | None = ...,
- updatex: bool = ...,
- updatey: bool = ...,
- ) -> None: ...
- @property
- def minpos(self) -> float: ...
- @property
- def minposx(self) -> float: ...
- @property
- def minposy(self) -> float: ...
- def get_points(self) -> np.ndarray: ...
- def set_points(self, points: ArrayLike) -> None: ...
- def set(self, other: Bbox) -> None: ...
- def mutated(self) -> bool: ...
- def mutatedx(self) -> bool: ...
- def mutatedy(self) -> bool: ...
-
-class TransformedBbox(BboxBase):
- def __init__(self, bbox: Bbox, transform: Transform, **kwargs) -> None: ...
- def get_points(self) -> np.ndarray: ...
-
-class LockableBbox(BboxBase):
- def __init__(
- self,
- bbox: BboxBase,
- x0: float | None = ...,
- y0: float | None = ...,
- x1: float | None = ...,
- y1: float | None = ...,
- **kwargs
- ) -> None: ...
- @property
- def locked_x0(self) -> float | None: ...
- @locked_x0.setter
- def locked_x0(self, x0: float | None) -> None: ...
- @property
- def locked_y0(self) -> float | None: ...
- @locked_y0.setter
- def locked_y0(self, y0: float | None) -> None: ...
- @property
- def locked_x1(self) -> float | None: ...
- @locked_x1.setter
- def locked_x1(self, x1: float | None) -> None: ...
- @property
- def locked_y1(self) -> float | None: ...
- @locked_y1.setter
- def locked_y1(self, y1: float | None) -> None: ...
-
-class Transform(TransformNode):
-
- # Implemented as a standard attrs in base class, but functionally readonly and some subclasses implement as such
- @property
- def input_dims(self) -> int | None: ...
- @property
- def output_dims(self) -> int | None: ...
- @property
- def is_separable(self) -> bool: ...
- @property
- def has_inverse(self) -> bool: ...
-
- def __add__(self, other: Transform) -> Transform: ...
- @property
- def depth(self) -> int: ...
- def contains_branch(self, other: Transform) -> bool: ...
- def contains_branch_seperately(
- self, other_transform: Transform
- ) -> Sequence[bool]: ...
- def __sub__(self, other: Transform) -> Transform: ...
- def __array__(self, *args, **kwargs) -> np.ndarray: ...
- def transform(self, values: ArrayLike) -> np.ndarray: ...
- def transform_affine(self, values: ArrayLike) -> np.ndarray: ...
- def transform_non_affine(self, values: ArrayLike) -> ArrayLike: ...
- def transform_bbox(self, bbox: BboxBase) -> Bbox: ...
- def get_affine(self) -> Transform: ...
- def get_matrix(self) -> np.ndarray: ...
- def transform_point(self, point: ArrayLike) -> np.ndarray: ...
- def transform_path(self, path: Path) -> Path: ...
- def transform_path_affine(self, path: Path) -> Path: ...
- def transform_path_non_affine(self, path: Path) -> Path: ...
- def transform_angles(
- self,
- angles: ArrayLike,
- pts: ArrayLike,
- radians: bool = ...,
- pushoff: float = ...,
- ) -> np.ndarray: ...
- def inverted(self) -> Transform: ...
-
-class TransformWrapper(Transform):
- pass_through: bool
- def __init__(self, child: Transform) -> None: ...
- def __eq__(self, other: object) -> bool: ...
- def frozen(self) -> Transform: ...
- def set(self, child: Transform) -> None: ...
-
-class AffineBase(Transform):
- is_affine: Literal[True]
- def __init__(self, *args, **kwargs) -> None: ...
- def __eq__(self, other: object) -> bool: ...
-
-class Affine2DBase(AffineBase):
- input_dims: Literal[2]
- output_dims: Literal[2]
- def frozen(self) -> Affine2D: ...
- def to_values(self) -> tuple[float, float, float, float, float, float]: ...
-
-class Affine2D(Affine2DBase):
- def __init__(self, matrix: ArrayLike | None = ..., **kwargs) -> None: ...
- @staticmethod
- def from_values(
- a: float, b: float, c: float, d: float, e: float, f: float
- ) -> Affine2D: ...
- def set_matrix(self, mtx: ArrayLike) -> None: ...
- def clear(self) -> Affine2D: ...
- def rotate(self, theta: float) -> Affine2D: ...
- def rotate_deg(self, degrees: float) -> Affine2D: ...
- def rotate_around(self, x: float, y: float, theta: float) -> Affine2D: ...
- def rotate_deg_around(self, x: float, y: float, degrees: float) -> Affine2D: ...
- def translate(self, tx: float, ty: float) -> Affine2D: ...
- def scale(self, sx: float, sy: float | None = ...) -> Affine2D: ...
- def skew(self, xShear: float, yShear: float) -> Affine2D: ...
- def skew_deg(self, xShear: float, yShear: float) -> Affine2D: ...
-
-class IdentityTransform(Affine2DBase): ...
-
-class _BlendedMixin:
- def __eq__(self, other: object) -> bool: ...
- def contains_branch_seperately(self, transform: Transform) -> Sequence[bool]: ...
-
-class BlendedGenericTransform(_BlendedMixin, Transform):
- input_dims: Literal[2]
- output_dims: Literal[2]
- pass_through: bool
- def __init__(
- self, x_transform: Transform, y_transform: Transform, **kwargs
- ) -> None: ...
- @property
- def depth(self) -> int: ...
- def contains_branch(self, other: Transform) -> Literal[False]: ...
- @property
- def is_affine(self) -> bool: ...
-
-class BlendedAffine2D(_BlendedMixin, Affine2DBase):
- def __init__(
- self, x_transform: Transform, y_transform: Transform, **kwargs
- ) -> None: ...
-
-def blended_transform_factory(
- x_transform: Transform, y_transform: Transform
-) -> BlendedGenericTransform | BlendedAffine2D: ...
-
-class CompositeGenericTransform(Transform):
- pass_through: bool
- def __init__(self, a: Transform, b: Transform, **kwargs) -> None: ...
-
-class CompositeAffine2D(Affine2DBase):
- def __init__(self, a: Affine2DBase, b: Affine2DBase, **kwargs) -> None: ...
- @property
- def depth(self) -> int: ...
-
-def composite_transform_factory(a: Transform, b: Transform) -> Transform: ...
-
-class BboxTransform(Affine2DBase):
- def __init__(self, boxin: BboxBase, boxout: BboxBase, **kwargs) -> None: ...
-
-class BboxTransformTo(Affine2DBase):
- def __init__(self, boxout: BboxBase, **kwargs) -> None: ...
-
-class BboxTransformToMaxOnly(BboxTransformTo): ...
-
-class BboxTransformFrom(Affine2DBase):
- def __init__(self, boxin: BboxBase, **kwargs) -> None: ...
-
-class ScaledTranslation(Affine2DBase):
- def __init__(
- self, xt: float, yt: float, scale_trans: Affine2DBase, **kwargs
- ) -> None: ...
-
-class AffineDeltaTransform(Affine2DBase):
- def __init__(self, transform: Affine2DBase, **kwargs) -> None: ...
-
-class TransformedPath(TransformNode):
- def __init__(self, path: Path, transform: Transform) -> None: ...
- def get_transformed_points_and_affine(self) -> tuple[Path, Transform]: ...
- def get_transformed_path_and_affine(self) -> tuple[Path, Transform]: ...
- def get_fully_transformed_path(self) -> Path: ...
- def get_affine(self) -> Transform: ...
-
-class TransformedPatchPath(TransformedPath):
- def __init__(self, patch: Patch) -> None: ...
-
-def nonsingular(
- vmin: float,
- vmax: float,
- expander: float = ...,
- tiny: float = ...,
- increasing: bool = ...,
-) -> tuple[float, float]: ...
-def interval_contains(interval: tuple[float, float], val: float) -> bool: ...
-def interval_contains_open(interval: tuple[float, float], val: float) -> bool: ...
-def offset_copy(
- trans: Transform,
- fig: Figure | None = ...,
- x: float = ...,
- y: float = ...,
- units: Literal["inches", "points", "dots"] = ...,
-) -> Transform: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/__init__.py b/contrib/python/matplotlib/py3/matplotlib/tri/__init__.py
deleted file mode 100644
index e000831d8a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/__init__.py
+++ /dev/null
@@ -1,23 +0,0 @@
-"""
-Unstructured triangular grid functions.
-"""
-
-from ._triangulation import Triangulation
-from ._tricontour import TriContourSet, tricontour, tricontourf
-from ._trifinder import TriFinder, TrapezoidMapTriFinder
-from ._triinterpolate import (TriInterpolator, LinearTriInterpolator,
- CubicTriInterpolator)
-from ._tripcolor import tripcolor
-from ._triplot import triplot
-from ._trirefine import TriRefiner, UniformTriRefiner
-from ._tritools import TriAnalyzer
-
-
-__all__ = ["Triangulation",
- "TriContourSet", "tricontour", "tricontourf",
- "TriFinder", "TrapezoidMapTriFinder",
- "TriInterpolator", "LinearTriInterpolator", "CubicTriInterpolator",
- "tripcolor",
- "triplot",
- "TriRefiner", "UniformTriRefiner",
- "TriAnalyzer"]
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/_triangulation.py b/contrib/python/matplotlib/py3/matplotlib/tri/_triangulation.py
deleted file mode 100644
index a07192dfc8..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/_triangulation.py
+++ /dev/null
@@ -1,247 +0,0 @@
-import sys
-
-import numpy as np
-
-from matplotlib import _api
-
-
-class Triangulation:
- """
- An unstructured triangular grid consisting of npoints points and
- ntri triangles. The triangles can either be specified by the user
- or automatically generated using a Delaunay triangulation.
-
- Parameters
- ----------
- x, y : (npoints,) array-like
- Coordinates of grid points.
- triangles : (ntri, 3) array-like of int, optional
- For each triangle, the indices of the three points that make
- up the triangle, ordered in an anticlockwise manner. If not
- specified, the Delaunay triangulation is calculated.
- mask : (ntri,) array-like of bool, optional
- Which triangles are masked out.
-
- Attributes
- ----------
- triangles : (ntri, 3) array of int
- For each triangle, the indices of the three points that make
- up the triangle, ordered in an anticlockwise manner. If you want to
- take the *mask* into account, use `get_masked_triangles` instead.
- mask : (ntri, 3) array of bool or None
- Masked out triangles.
- is_delaunay : bool
- Whether the Triangulation is a calculated Delaunay
- triangulation (where *triangles* was not specified) or not.
-
- Notes
- -----
- For a Triangulation to be valid it must not have duplicate points,
- triangles formed from colinear points, or overlapping triangles.
- """
- def __init__(self, x, y, triangles=None, mask=None):
- from matplotlib import _qhull
-
- self.x = np.asarray(x, dtype=np.float64)
- self.y = np.asarray(y, dtype=np.float64)
- if self.x.shape != self.y.shape or self.x.ndim != 1:
- raise ValueError("x and y must be equal-length 1D arrays, but "
- f"found shapes {self.x.shape!r} and "
- f"{self.y.shape!r}")
-
- self.mask = None
- self._edges = None
- self._neighbors = None
- self.is_delaunay = False
-
- if triangles is None:
- # No triangulation specified, so use matplotlib._qhull to obtain
- # Delaunay triangulation.
- self.triangles, self._neighbors = _qhull.delaunay(x, y, sys.flags.verbose)
- self.is_delaunay = True
- else:
- # Triangulation specified. Copy, since we may correct triangle
- # orientation.
- try:
- self.triangles = np.array(triangles, dtype=np.int32, order='C')
- except ValueError as e:
- raise ValueError('triangles must be a (N, 3) int array, not '
- f'{triangles!r}') from e
- if self.triangles.ndim != 2 or self.triangles.shape[1] != 3:
- raise ValueError(
- 'triangles must be a (N, 3) int array, but found shape '
- f'{self.triangles.shape!r}')
- if self.triangles.max() >= len(self.x):
- raise ValueError(
- 'triangles are indices into the points and must be in the '
- f'range 0 <= i < {len(self.x)} but found value '
- f'{self.triangles.max()}')
- if self.triangles.min() < 0:
- raise ValueError(
- 'triangles are indices into the points and must be in the '
- f'range 0 <= i < {len(self.x)} but found value '
- f'{self.triangles.min()}')
-
- # Underlying C++ object is not created until first needed.
- self._cpp_triangulation = None
-
- # Default TriFinder not created until needed.
- self._trifinder = None
-
- self.set_mask(mask)
-
- def calculate_plane_coefficients(self, z):
- """
- Calculate plane equation coefficients for all unmasked triangles from
- the point (x, y) coordinates and specified z-array of shape (npoints).
- The returned array has shape (npoints, 3) and allows z-value at (x, y)
- position in triangle tri to be calculated using
- ``z = array[tri, 0] * x + array[tri, 1] * y + array[tri, 2]``.
- """
- return self.get_cpp_triangulation().calculate_plane_coefficients(z)
-
- @property
- def edges(self):
- """
- Return integer array of shape (nedges, 2) containing all edges of
- non-masked triangles.
-
- Each row defines an edge by its start point index and end point
- index. Each edge appears only once, i.e. for an edge between points
- *i* and *j*, there will only be either *(i, j)* or *(j, i)*.
- """
- if self._edges is None:
- self._edges = self.get_cpp_triangulation().get_edges()
- return self._edges
-
- def get_cpp_triangulation(self):
- """
- Return the underlying C++ Triangulation object, creating it
- if necessary.
- """
- from matplotlib import _tri
- if self._cpp_triangulation is None:
- self._cpp_triangulation = _tri.Triangulation(
- # For unset arrays use empty tuple which has size of zero.
- self.x, self.y, self.triangles,
- self.mask if self.mask is not None else (),
- self._edges if self._edges is not None else (),
- self._neighbors if self._neighbors is not None else (),
- not self.is_delaunay)
- return self._cpp_triangulation
-
- def get_masked_triangles(self):
- """
- Return an array of triangles taking the mask into account.
- """
- if self.mask is not None:
- return self.triangles[~self.mask]
- else:
- return self.triangles
-
- @staticmethod
- def get_from_args_and_kwargs(*args, **kwargs):
- """
- Return a Triangulation object from the args and kwargs, and
- the remaining args and kwargs with the consumed values removed.
-
- There are two alternatives: either the first argument is a
- Triangulation object, in which case it is returned, or the args
- and kwargs are sufficient to create a new Triangulation to
- return. In the latter case, see Triangulation.__init__ for
- the possible args and kwargs.
- """
- if isinstance(args[0], Triangulation):
- triangulation, *args = args
- if 'triangles' in kwargs:
- _api.warn_external(
- "Passing the keyword 'triangles' has no effect when also "
- "passing a Triangulation")
- if 'mask' in kwargs:
- _api.warn_external(
- "Passing the keyword 'mask' has no effect when also "
- "passing a Triangulation")
- else:
- x, y, triangles, mask, args, kwargs = \
- Triangulation._extract_triangulation_params(args, kwargs)
- triangulation = Triangulation(x, y, triangles, mask)
- return triangulation, args, kwargs
-
- @staticmethod
- def _extract_triangulation_params(args, kwargs):
- x, y, *args = args
- # Check triangles in kwargs then args.
- triangles = kwargs.pop('triangles', None)
- from_args = False
- if triangles is None and args:
- triangles = args[0]
- from_args = True
- if triangles is not None:
- try:
- triangles = np.asarray(triangles, dtype=np.int32)
- except ValueError:
- triangles = None
- if triangles is not None and (triangles.ndim != 2 or
- triangles.shape[1] != 3):
- triangles = None
- if triangles is not None and from_args:
- args = args[1:] # Consumed first item in args.
- # Check for mask in kwargs.
- mask = kwargs.pop('mask', None)
- return x, y, triangles, mask, args, kwargs
-
- def get_trifinder(self):
- """
- Return the default `matplotlib.tri.TriFinder` of this
- triangulation, creating it if necessary. This allows the same
- TriFinder object to be easily shared.
- """
- if self._trifinder is None:
- # Default TriFinder class.
- from matplotlib.tri._trifinder import TrapezoidMapTriFinder
- self._trifinder = TrapezoidMapTriFinder(self)
- return self._trifinder
-
- @property
- def neighbors(self):
- """
- Return integer array of shape (ntri, 3) containing neighbor triangles.
-
- For each triangle, the indices of the three triangles that
- share the same edges, or -1 if there is no such neighboring
- triangle. ``neighbors[i, j]`` is the triangle that is the neighbor
- to the edge from point index ``triangles[i, j]`` to point index
- ``triangles[i, (j+1)%3]``.
- """
- if self._neighbors is None:
- self._neighbors = self.get_cpp_triangulation().get_neighbors()
- return self._neighbors
-
- def set_mask(self, mask):
- """
- Set or clear the mask array.
-
- Parameters
- ----------
- mask : None or bool array of length ntri
- """
- if mask is None:
- self.mask = None
- else:
- self.mask = np.asarray(mask, dtype=bool)
- if self.mask.shape != (self.triangles.shape[0],):
- raise ValueError('mask array must have same length as '
- 'triangles array')
-
- # Set mask in C++ Triangulation.
- if self._cpp_triangulation is not None:
- self._cpp_triangulation.set_mask(
- self.mask if self.mask is not None else ())
-
- # Clear derived fields so they are recalculated when needed.
- self._edges = None
- self._neighbors = None
-
- # Recalculate TriFinder if it exists.
- if self._trifinder is not None:
- self._trifinder._initialize()
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/_triangulation.pyi b/contrib/python/matplotlib/py3/matplotlib/tri/_triangulation.pyi
deleted file mode 100644
index 6e00b272ed..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/_triangulation.pyi
+++ /dev/null
@@ -1,33 +0,0 @@
-from matplotlib import _tri
-from matplotlib.tri._trifinder import TriFinder
-
-import numpy as np
-from numpy.typing import ArrayLike
-from typing import Any
-
-class Triangulation:
- x: np.ndarray
- y: np.ndarray
- mask: np.ndarray | None
- is_delaunay: bool
- triangles: np.ndarray
- def __init__(
- self,
- x: ArrayLike,
- y: ArrayLike,
- triangles: ArrayLike | None = ...,
- mask: ArrayLike | None = ...,
- ) -> None: ...
- def calculate_plane_coefficients(self, z: ArrayLike) -> np.ndarray: ...
- @property
- def edges(self) -> np.ndarray: ...
- def get_cpp_triangulation(self) -> _tri.Triangulation: ...
- def get_masked_triangles(self) -> np.ndarray: ...
- @staticmethod
- def get_from_args_and_kwargs(
- *args, **kwargs
- ) -> tuple[Triangulation, tuple[Any, ...], dict[str, Any]]: ...
- def get_trifinder(self) -> TriFinder: ...
- @property
- def neighbors(self) -> np.ndarray: ...
- def set_mask(self, mask: None | ArrayLike) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/_tricontour.py b/contrib/python/matplotlib/py3/matplotlib/tri/_tricontour.py
deleted file mode 100644
index 5b6d745372..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/_tricontour.py
+++ /dev/null
@@ -1,272 +0,0 @@
-import numpy as np
-
-from matplotlib import _docstring
-from matplotlib.contour import ContourSet
-from matplotlib.tri._triangulation import Triangulation
-
-
-@_docstring.dedent_interpd
-class TriContourSet(ContourSet):
- """
- Create and store a set of contour lines or filled regions for
- a triangular grid.
-
- This class is typically not instantiated directly by the user but by
- `~.Axes.tricontour` and `~.Axes.tricontourf`.
-
- %(contour_set_attributes)s
- """
- def __init__(self, ax, *args, **kwargs):
- """
- Draw triangular grid contour lines or filled regions,
- depending on whether keyword arg *filled* is False
- (default) or True.
-
- The first argument of the initializer must be an `~.axes.Axes`
- object. The remaining arguments and keyword arguments
- are described in the docstring of `~.Axes.tricontour`.
- """
- super().__init__(ax, *args, **kwargs)
-
- def _process_args(self, *args, **kwargs):
- """
- Process args and kwargs.
- """
- if isinstance(args[0], TriContourSet):
- C = args[0]._contour_generator
- if self.levels is None:
- self.levels = args[0].levels
- self.zmin = args[0].zmin
- self.zmax = args[0].zmax
- self._mins = args[0]._mins
- self._maxs = args[0]._maxs
- else:
- from matplotlib import _tri
- tri, z = self._contour_args(args, kwargs)
- C = _tri.TriContourGenerator(tri.get_cpp_triangulation(), z)
- self._mins = [tri.x.min(), tri.y.min()]
- self._maxs = [tri.x.max(), tri.y.max()]
-
- self._contour_generator = C
- return kwargs
-
- def _contour_args(self, args, kwargs):
- tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args,
- **kwargs)
- z, *args = args
- z = np.ma.asarray(z)
- if z.shape != tri.x.shape:
- raise ValueError('z array must have same length as triangulation x'
- ' and y arrays')
-
- # z values must be finite, only need to check points that are included
- # in the triangulation.
- z_check = z[np.unique(tri.get_masked_triangles())]
- if np.ma.is_masked(z_check):
- raise ValueError('z must not contain masked points within the '
- 'triangulation')
- if not np.isfinite(z_check).all():
- raise ValueError('z array must not contain non-finite values '
- 'within the triangulation')
-
- z = np.ma.masked_invalid(z, copy=False)
- self.zmax = float(z_check.max())
- self.zmin = float(z_check.min())
- if self.logscale and self.zmin <= 0:
- func = 'contourf' if self.filled else 'contour'
- raise ValueError(f'Cannot {func} log of negative values.')
- self._process_contour_level_args(args, z.dtype)
- return (tri, z)
-
-
-_docstring.interpd.update(_tricontour_doc="""
-Draw contour %%(type)s on an unstructured triangular grid.
-
-Call signatures::
-
- %%(func)s(triangulation, z, [levels], ...)
- %%(func)s(x, y, z, [levels], *, [triangles=triangles], [mask=mask], ...)
-
-The triangular grid can be specified either by passing a `.Triangulation`
-object as the first parameter, or by passing the points *x*, *y* and
-optionally the *triangles* and a *mask*. See `.Triangulation` for an
-explanation of these parameters. If neither of *triangulation* or
-*triangles* are given, the triangulation is calculated on the fly.
-
-It is possible to pass *triangles* positionally, i.e.
-``%%(func)s(x, y, triangles, z, ...)``. However, this is discouraged. For more
-clarity, pass *triangles* via keyword argument.
-
-Parameters
-----------
-triangulation : `.Triangulation`, optional
- An already created triangular grid.
-
-x, y, triangles, mask
- Parameters defining the triangular grid. See `.Triangulation`.
- This is mutually exclusive with specifying *triangulation*.
-
-z : array-like
- The height values over which the contour is drawn. Color-mapping is
- controlled by *cmap*, *norm*, *vmin*, and *vmax*.
-
- .. note::
- All values in *z* must be finite. Hence, nan and inf values must
- either be removed or `~.Triangulation.set_mask` be used.
-
-levels : int or array-like, optional
- Determines the number and positions of the contour lines / regions.
-
- If an int *n*, use `~matplotlib.ticker.MaxNLocator`, which tries to
- automatically choose no more than *n+1* "nice" contour levels between
- between minimum and maximum numeric values of *Z*.
-
- If array-like, draw contour lines at the specified levels. The values must
- be in increasing order.
-
-Returns
--------
-`~matplotlib.tri.TriContourSet`
-
-Other Parameters
-----------------
-colors : color string or sequence of colors, optional
- The colors of the levels, i.e., the contour %%(type)s.
-
- The sequence is cycled for the levels in ascending order. If the sequence
- is shorter than the number of levels, it is repeated.
-
- As a shortcut, single color strings may be used in place of one-element
- lists, i.e. ``'red'`` instead of ``['red']`` to color all levels with the
- same color. This shortcut does only work for color strings, not for other
- ways of specifying colors.
-
- By default (value *None*), the colormap specified by *cmap* will be used.
-
-alpha : float, default: 1
- The alpha blending value, between 0 (transparent) and 1 (opaque).
-
-%(cmap_doc)s
-
- This parameter is ignored if *colors* is set.
-
-%(norm_doc)s
-
- This parameter is ignored if *colors* is set.
-
-%(vmin_vmax_doc)s
-
- If *vmin* or *vmax* are not given, the default color scaling is based on
- *levels*.
-
- This parameter is ignored if *colors* is set.
-
-origin : {*None*, 'upper', 'lower', 'image'}, default: None
- Determines the orientation and exact position of *z* by specifying the
- position of ``z[0, 0]``. This is only relevant, if *X*, *Y* are not given.
-
- - *None*: ``z[0, 0]`` is at X=0, Y=0 in the lower left corner.
- - 'lower': ``z[0, 0]`` is at X=0.5, Y=0.5 in the lower left corner.
- - 'upper': ``z[0, 0]`` is at X=N+0.5, Y=0.5 in the upper left corner.
- - 'image': Use the value from :rc:`image.origin`.
-
-extent : (x0, x1, y0, y1), optional
- If *origin* is not *None*, then *extent* is interpreted as in `.imshow`: it
- gives the outer pixel boundaries. In this case, the position of z[0, 0] is
- the center of the pixel, not a corner. If *origin* is *None*, then
- (*x0*, *y0*) is the position of z[0, 0], and (*x1*, *y1*) is the position
- of z[-1, -1].
-
- This argument is ignored if *X* and *Y* are specified in the call to
- contour.
-
-locator : ticker.Locator subclass, optional
- The locator is used to determine the contour levels if they are not given
- explicitly via *levels*.
- Defaults to `~.ticker.MaxNLocator`.
-
-extend : {'neither', 'both', 'min', 'max'}, default: 'neither'
- Determines the ``%%(func)s``-coloring of values that are outside the
- *levels* range.
-
- If 'neither', values outside the *levels* range are not colored. If 'min',
- 'max' or 'both', color the values below, above or below and above the
- *levels* range.
-
- Values below ``min(levels)`` and above ``max(levels)`` are mapped to the
- under/over values of the `.Colormap`. Note that most colormaps do not have
- dedicated colors for these by default, so that the over and under values
- are the edge values of the colormap. You may want to set these values
- explicitly using `.Colormap.set_under` and `.Colormap.set_over`.
-
- .. note::
-
- An existing `.TriContourSet` does not get notified if properties of its
- colormap are changed. Therefore, an explicit call to
- `.ContourSet.changed()` is needed after modifying the colormap. The
- explicit call can be left out, if a colorbar is assigned to the
- `.TriContourSet` because it internally calls `.ContourSet.changed()`.
-
-xunits, yunits : registered units, optional
- Override axis units by specifying an instance of a
- :class:`matplotlib.units.ConversionInterface`.
-
-antialiased : bool, optional
- Enable antialiasing, overriding the defaults. For
- filled contours, the default is *True*. For line contours,
- it is taken from :rc:`lines.antialiased`.""" % _docstring.interpd.params)
-
-
-@_docstring.Substitution(func='tricontour', type='lines')
-@_docstring.dedent_interpd
-def tricontour(ax, *args, **kwargs):
- """
- %(_tricontour_doc)s
-
- linewidths : float or array-like, default: :rc:`contour.linewidth`
- The line width of the contour lines.
-
- If a number, all levels will be plotted with this linewidth.
-
- If a sequence, the levels in ascending order will be plotted with
- the linewidths in the order specified.
-
- If None, this falls back to :rc:`lines.linewidth`.
-
- linestyles : {*None*, 'solid', 'dashed', 'dashdot', 'dotted'}, optional
- If *linestyles* is *None*, the default is 'solid' unless the lines are
- monochrome. In that case, negative contours will take their linestyle
- from :rc:`contour.negative_linestyle` setting.
-
- *linestyles* can also be an iterable of the above strings specifying a
- set of linestyles to be used. If this iterable is shorter than the
- number of contour levels it will be repeated as necessary.
- """
- kwargs['filled'] = False
- return TriContourSet(ax, *args, **kwargs)
-
-
-@_docstring.Substitution(func='tricontourf', type='regions')
-@_docstring.dedent_interpd
-def tricontourf(ax, *args, **kwargs):
- """
- %(_tricontour_doc)s
-
- hatches : list[str], optional
- A list of crosshatch patterns to use on the filled areas.
- If None, no hatching will be added to the contour.
- Hatching is supported in the PostScript, PDF, SVG and Agg
- backends only.
-
- Notes
- -----
- `.tricontourf` fills intervals that are closed at the top; that is, for
- boundaries *z1* and *z2*, the filled region is::
-
- z1 < Z <= z2
-
- except for the lowest interval, which is closed on both sides (i.e. it
- includes the lowest value).
- """
- kwargs['filled'] = True
- return TriContourSet(ax, *args, **kwargs)
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/_tricontour.pyi b/contrib/python/matplotlib/py3/matplotlib/tri/_tricontour.pyi
deleted file mode 100644
index 31929d8661..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/_tricontour.pyi
+++ /dev/null
@@ -1,52 +0,0 @@
-from matplotlib.axes import Axes
-from matplotlib.contour import ContourSet
-from matplotlib.tri._triangulation import Triangulation
-
-from numpy.typing import ArrayLike
-from typing import overload
-
-# TODO: more explicit args/kwargs (for all things in this module)?
-
-class TriContourSet(ContourSet):
- def __init__(self, ax: Axes, *args, **kwargs) -> None: ...
-
-@overload
-def tricontour(
- ax: Axes,
- triangulation: Triangulation,
- z: ArrayLike,
- levels: int | ArrayLike = ...,
- **kwargs
-) -> TriContourSet: ...
-@overload
-def tricontour(
- ax: Axes,
- x: ArrayLike,
- y: ArrayLike,
- z: ArrayLike,
- levels: int | ArrayLike = ...,
- *,
- triangles: ArrayLike = ...,
- mask: ArrayLike = ...,
- **kwargs
-) -> TriContourSet: ...
-@overload
-def tricontourf(
- ax: Axes,
- triangulation: Triangulation,
- z: ArrayLike,
- levels: int | ArrayLike = ...,
- **kwargs
-) -> TriContourSet: ...
-@overload
-def tricontourf(
- ax: Axes,
- x: ArrayLike,
- y: ArrayLike,
- z: ArrayLike,
- levels: int | ArrayLike = ...,
- *,
- triangles: ArrayLike = ...,
- mask: ArrayLike = ...,
- **kwargs
-) -> TriContourSet: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/_trifinder.py b/contrib/python/matplotlib/py3/matplotlib/tri/_trifinder.py
deleted file mode 100644
index 852f3d9eeb..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/_trifinder.py
+++ /dev/null
@@ -1,96 +0,0 @@
-import numpy as np
-
-from matplotlib import _api
-from matplotlib.tri import Triangulation
-
-
-class TriFinder:
- """
- Abstract base class for classes used to find the triangles of a
- Triangulation in which (x, y) points lie.
-
- Rather than instantiate an object of a class derived from TriFinder, it is
- usually better to use the function `.Triangulation.get_trifinder`.
-
- Derived classes implement __call__(x, y) where x and y are array-like point
- coordinates of the same shape.
- """
-
- def __init__(self, triangulation):
- _api.check_isinstance(Triangulation, triangulation=triangulation)
- self._triangulation = triangulation
-
- def __call__(self, x, y):
- raise NotImplementedError
-
-
-class TrapezoidMapTriFinder(TriFinder):
- """
- `~matplotlib.tri.TriFinder` class implemented using the trapezoid
- map algorithm from the book "Computational Geometry, Algorithms and
- Applications", second edition, by M. de Berg, M. van Kreveld, M. Overmars
- and O. Schwarzkopf.
-
- The triangulation must be valid, i.e. it must not have duplicate points,
- triangles formed from colinear points, or overlapping triangles. The
- algorithm has some tolerance to triangles formed from colinear points, but
- this should not be relied upon.
- """
-
- def __init__(self, triangulation):
- from matplotlib import _tri
- super().__init__(triangulation)
- self._cpp_trifinder = _tri.TrapezoidMapTriFinder(
- triangulation.get_cpp_triangulation())
- self._initialize()
-
- def __call__(self, x, y):
- """
- Return an array containing the indices of the triangles in which the
- specified *x*, *y* points lie, or -1 for points that do not lie within
- a triangle.
-
- *x*, *y* are array-like x and y coordinates of the same shape and any
- number of dimensions.
-
- Returns integer array with the same shape and *x* and *y*.
- """
- x = np.asarray(x, dtype=np.float64)
- y = np.asarray(y, dtype=np.float64)
- if x.shape != y.shape:
- raise ValueError("x and y must be array-like with the same shape")
-
- # C++ does the heavy lifting, and expects 1D arrays.
- indices = (self._cpp_trifinder.find_many(x.ravel(), y.ravel())
- .reshape(x.shape))
- return indices
-
- def _get_tree_stats(self):
- """
- Return a python list containing the statistics about the node tree:
- 0: number of nodes (tree size)
- 1: number of unique nodes
- 2: number of trapezoids (tree leaf nodes)
- 3: number of unique trapezoids
- 4: maximum parent count (max number of times a node is repeated in
- tree)
- 5: maximum depth of tree (one more than the maximum number of
- comparisons needed to search through the tree)
- 6: mean of all trapezoid depths (one more than the average number
- of comparisons needed to search through the tree)
- """
- return self._cpp_trifinder.get_tree_stats()
-
- def _initialize(self):
- """
- Initialize the underlying C++ object. Can be called multiple times if,
- for example, the triangulation is modified.
- """
- self._cpp_trifinder.initialize()
-
- def _print_tree(self):
- """
- Print a text representation of the node tree, which is useful for
- debugging purposes.
- """
- self._cpp_trifinder.print_tree()
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/_trifinder.pyi b/contrib/python/matplotlib/py3/matplotlib/tri/_trifinder.pyi
deleted file mode 100644
index 41a9990b89..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/_trifinder.pyi
+++ /dev/null
@@ -1,10 +0,0 @@
-from matplotlib.tri import Triangulation
-from numpy.typing import ArrayLike
-
-class TriFinder:
- def __init__(self, triangulation: Triangulation) -> None: ...
- def __call__(self, x: ArrayLike, y: ArrayLike) -> ArrayLike: ...
-
-class TrapezoidMapTriFinder(TriFinder):
- def __init__(self, triangulation: Triangulation) -> None: ...
- def __call__(self, x: ArrayLike, y: ArrayLike) -> ArrayLike: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/_triinterpolate.py b/contrib/python/matplotlib/py3/matplotlib/tri/_triinterpolate.py
deleted file mode 100644
index 90ad6cf3a7..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/_triinterpolate.py
+++ /dev/null
@@ -1,1574 +0,0 @@
-"""
-Interpolation inside triangular grids.
-"""
-
-import numpy as np
-
-from matplotlib import _api
-from matplotlib.tri import Triangulation
-from matplotlib.tri._trifinder import TriFinder
-from matplotlib.tri._tritools import TriAnalyzer
-
-__all__ = ('TriInterpolator', 'LinearTriInterpolator', 'CubicTriInterpolator')
-
-
-class TriInterpolator:
- """
- Abstract base class for classes used to interpolate on a triangular grid.
-
- Derived classes implement the following methods:
-
- - ``__call__(x, y)``,
- where x, y are array-like point coordinates of the same shape, and
- that returns a masked array of the same shape containing the
- interpolated z-values.
-
- - ``gradient(x, y)``,
- where x, y are array-like point coordinates of the same
- shape, and that returns a list of 2 masked arrays of the same shape
- containing the 2 derivatives of the interpolator (derivatives of
- interpolated z values with respect to x and y).
- """
-
- def __init__(self, triangulation, z, trifinder=None):
- _api.check_isinstance(Triangulation, triangulation=triangulation)
- self._triangulation = triangulation
-
- self._z = np.asarray(z)
- if self._z.shape != self._triangulation.x.shape:
- raise ValueError("z array must have same length as triangulation x"
- " and y arrays")
-
- _api.check_isinstance((TriFinder, None), trifinder=trifinder)
- self._trifinder = trifinder or self._triangulation.get_trifinder()
-
- # Default scaling factors : 1.0 (= no scaling)
- # Scaling may be used for interpolations for which the order of
- # magnitude of x, y has an impact on the interpolant definition.
- # Please refer to :meth:`_interpolate_multikeys` for details.
- self._unit_x = 1.0
- self._unit_y = 1.0
-
- # Default triangle renumbering: None (= no renumbering)
- # Renumbering may be used to avoid unnecessary computations
- # if complex calculations are done inside the Interpolator.
- # Please refer to :meth:`_interpolate_multikeys` for details.
- self._tri_renum = None
-
- # __call__ and gradient docstrings are shared by all subclasses
- # (except, if needed, relevant additions).
- # However these methods are only implemented in subclasses to avoid
- # confusion in the documentation.
- _docstring__call__ = """
- Returns a masked array containing interpolated values at the specified
- (x, y) points.
-
- Parameters
- ----------
- x, y : array-like
- x and y coordinates of the same shape and any number of
- dimensions.
-
- Returns
- -------
- np.ma.array
- Masked array of the same shape as *x* and *y*; values corresponding
- to (*x*, *y*) points outside of the triangulation are masked out.
-
- """
-
- _docstringgradient = r"""
- Returns a list of 2 masked arrays containing interpolated derivatives
- at the specified (x, y) points.
-
- Parameters
- ----------
- x, y : array-like
- x and y coordinates of the same shape and any number of
- dimensions.
-
- Returns
- -------
- dzdx, dzdy : np.ma.array
- 2 masked arrays of the same shape as *x* and *y*; values
- corresponding to (x, y) points outside of the triangulation
- are masked out.
- The first returned array contains the values of
- :math:`\frac{\partial z}{\partial x}` and the second those of
- :math:`\frac{\partial z}{\partial y}`.
-
- """
-
- def _interpolate_multikeys(self, x, y, tri_index=None,
- return_keys=('z',)):
- """
- Versatile (private) method defined for all TriInterpolators.
-
- :meth:`_interpolate_multikeys` is a wrapper around method
- :meth:`_interpolate_single_key` (to be defined in the child
- subclasses).
- :meth:`_interpolate_single_key actually performs the interpolation,
- but only for 1-dimensional inputs and at valid locations (inside
- unmasked triangles of the triangulation).
-
- The purpose of :meth:`_interpolate_multikeys` is to implement the
- following common tasks needed in all subclasses implementations:
-
- - calculation of containing triangles
- - dealing with more than one interpolation request at the same
- location (e.g., if the 2 derivatives are requested, it is
- unnecessary to compute the containing triangles twice)
- - scaling according to self._unit_x, self._unit_y
- - dealing with points outside of the grid (with fill value np.nan)
- - dealing with multi-dimensional *x*, *y* arrays: flattening for
- :meth:`_interpolate_params` call and final reshaping.
-
- (Note that np.vectorize could do most of those things very well for
- you, but it does it by function evaluations over successive tuples of
- the input arrays. Therefore, this tends to be more time-consuming than
- using optimized numpy functions - e.g., np.dot - which can be used
- easily on the flattened inputs, in the child-subclass methods
- :meth:`_interpolate_single_key`.)
-
- It is guaranteed that the calls to :meth:`_interpolate_single_key`
- will be done with flattened (1-d) array-like input parameters *x*, *y*
- and with flattened, valid `tri_index` arrays (no -1 index allowed).
-
- Parameters
- ----------
- x, y : array-like
- x and y coordinates where interpolated values are requested.
- tri_index : array-like of int, optional
- Array of the containing triangle indices, same shape as
- *x* and *y*. Defaults to None. If None, these indices
- will be computed by a TriFinder instance.
- (Note: For point outside the grid, tri_index[ipt] shall be -1).
- return_keys : tuple of keys from {'z', 'dzdx', 'dzdy'}
- Defines the interpolation arrays to return, and in which order.
-
- Returns
- -------
- list of arrays
- Each array-like contains the expected interpolated values in the
- order defined by *return_keys* parameter.
- """
- # Flattening and rescaling inputs arrays x, y
- # (initial shape is stored for output)
- x = np.asarray(x, dtype=np.float64)
- y = np.asarray(y, dtype=np.float64)
- sh_ret = x.shape
- if x.shape != y.shape:
- raise ValueError("x and y shall have same shapes."
- f" Given: {x.shape} and {y.shape}")
- x = np.ravel(x)
- y = np.ravel(y)
- x_scaled = x/self._unit_x
- y_scaled = y/self._unit_y
- size_ret = np.size(x_scaled)
-
- # Computes & ravels the element indexes, extract the valid ones.
- if tri_index is None:
- tri_index = self._trifinder(x, y)
- else:
- if tri_index.shape != sh_ret:
- raise ValueError(
- "tri_index array is provided and shall"
- " have same shape as x and y. Given: "
- f"{tri_index.shape} and {sh_ret}")
- tri_index = np.ravel(tri_index)
-
- mask_in = (tri_index != -1)
- if self._tri_renum is None:
- valid_tri_index = tri_index[mask_in]
- else:
- valid_tri_index = self._tri_renum[tri_index[mask_in]]
- valid_x = x_scaled[mask_in]
- valid_y = y_scaled[mask_in]
-
- ret = []
- for return_key in return_keys:
- # Find the return index associated with the key.
- try:
- return_index = {'z': 0, 'dzdx': 1, 'dzdy': 2}[return_key]
- except KeyError as err:
- raise ValueError("return_keys items shall take values in"
- " {'z', 'dzdx', 'dzdy'}") from err
-
- # Sets the scale factor for f & df components
- scale = [1., 1./self._unit_x, 1./self._unit_y][return_index]
-
- # Computes the interpolation
- ret_loc = np.empty(size_ret, dtype=np.float64)
- ret_loc[~mask_in] = np.nan
- ret_loc[mask_in] = self._interpolate_single_key(
- return_key, valid_tri_index, valid_x, valid_y) * scale
- ret += [np.ma.masked_invalid(ret_loc.reshape(sh_ret), copy=False)]
-
- return ret
-
- def _interpolate_single_key(self, return_key, tri_index, x, y):
- """
- Interpolate at points belonging to the triangulation
- (inside an unmasked triangles).
-
- Parameters
- ----------
- return_key : {'z', 'dzdx', 'dzdy'}
- The requested values (z or its derivatives).
- tri_index : 1D int array
- Valid triangle index (cannot be -1).
- x, y : 1D arrays, same shape as `tri_index`
- Valid locations where interpolation is requested.
-
- Returns
- -------
- 1-d array
- Returned array of the same size as *tri_index*
- """
- raise NotImplementedError("TriInterpolator subclasses" +
- "should implement _interpolate_single_key!")
-
-
-class LinearTriInterpolator(TriInterpolator):
- """
- Linear interpolator on a triangular grid.
-
- Each triangle is represented by a plane so that an interpolated value at
- point (x, y) lies on the plane of the triangle containing (x, y).
- Interpolated values are therefore continuous across the triangulation, but
- their first derivatives are discontinuous at edges between triangles.
-
- Parameters
- ----------
- triangulation : `~matplotlib.tri.Triangulation`
- The triangulation to interpolate over.
- z : (npoints,) array-like
- Array of values, defined at grid points, to interpolate between.
- trifinder : `~matplotlib.tri.TriFinder`, optional
- If this is not specified, the Triangulation's default TriFinder will
- be used by calling `.Triangulation.get_trifinder`.
-
- Methods
- -------
- `__call__` (x, y) : Returns interpolated values at (x, y) points.
- `gradient` (x, y) : Returns interpolated derivatives at (x, y) points.
-
- """
- def __init__(self, triangulation, z, trifinder=None):
- super().__init__(triangulation, z, trifinder)
-
- # Store plane coefficients for fast interpolation calculations.
- self._plane_coefficients = \
- self._triangulation.calculate_plane_coefficients(self._z)
-
- def __call__(self, x, y):
- return self._interpolate_multikeys(x, y, tri_index=None,
- return_keys=('z',))[0]
- __call__.__doc__ = TriInterpolator._docstring__call__
-
- def gradient(self, x, y):
- return self._interpolate_multikeys(x, y, tri_index=None,
- return_keys=('dzdx', 'dzdy'))
- gradient.__doc__ = TriInterpolator._docstringgradient
-
- def _interpolate_single_key(self, return_key, tri_index, x, y):
- _api.check_in_list(['z', 'dzdx', 'dzdy'], return_key=return_key)
- if return_key == 'z':
- return (self._plane_coefficients[tri_index, 0]*x +
- self._plane_coefficients[tri_index, 1]*y +
- self._plane_coefficients[tri_index, 2])
- elif return_key == 'dzdx':
- return self._plane_coefficients[tri_index, 0]
- else: # 'dzdy'
- return self._plane_coefficients[tri_index, 1]
-
-
-class CubicTriInterpolator(TriInterpolator):
- r"""
- Cubic interpolator on a triangular grid.
-
- In one-dimension - on a segment - a cubic interpolating function is
- defined by the values of the function and its derivative at both ends.
- This is almost the same in 2D inside a triangle, except that the values
- of the function and its 2 derivatives have to be defined at each triangle
- node.
-
- The CubicTriInterpolator takes the value of the function at each node -
- provided by the user - and internally computes the value of the
- derivatives, resulting in a smooth interpolation.
- (As a special feature, the user can also impose the value of the
- derivatives at each node, but this is not supposed to be the common
- usage.)
-
- Parameters
- ----------
- triangulation : `~matplotlib.tri.Triangulation`
- The triangulation to interpolate over.
- z : (npoints,) array-like
- Array of values, defined at grid points, to interpolate between.
- kind : {'min_E', 'geom', 'user'}, optional
- Choice of the smoothing algorithm, in order to compute
- the interpolant derivatives (defaults to 'min_E'):
-
- - if 'min_E': (default) The derivatives at each node is computed
- to minimize a bending energy.
- - if 'geom': The derivatives at each node is computed as a
- weighted average of relevant triangle normals. To be used for
- speed optimization (large grids).
- - if 'user': The user provides the argument *dz*, no computation
- is hence needed.
-
- trifinder : `~matplotlib.tri.TriFinder`, optional
- If not specified, the Triangulation's default TriFinder will
- be used by calling `.Triangulation.get_trifinder`.
- dz : tuple of array-likes (dzdx, dzdy), optional
- Used only if *kind* ='user'. In this case *dz* must be provided as
- (dzdx, dzdy) where dzdx, dzdy are arrays of the same shape as *z* and
- are the interpolant first derivatives at the *triangulation* points.
-
- Methods
- -------
- `__call__` (x, y) : Returns interpolated values at (x, y) points.
- `gradient` (x, y) : Returns interpolated derivatives at (x, y) points.
-
- Notes
- -----
- This note is a bit technical and details how the cubic interpolation is
- computed.
-
- The interpolation is based on a Clough-Tocher subdivision scheme of
- the *triangulation* mesh (to make it clearer, each triangle of the
- grid will be divided in 3 child-triangles, and on each child triangle
- the interpolated function is a cubic polynomial of the 2 coordinates).
- This technique originates from FEM (Finite Element Method) analysis;
- the element used is a reduced Hsieh-Clough-Tocher (HCT)
- element. Its shape functions are described in [1]_.
- The assembled function is guaranteed to be C1-smooth, i.e. it is
- continuous and its first derivatives are also continuous (this
- is easy to show inside the triangles but is also true when crossing the
- edges).
-
- In the default case (*kind* ='min_E'), the interpolant minimizes a
- curvature energy on the functional space generated by the HCT element
- shape functions - with imposed values but arbitrary derivatives at each
- node. The minimized functional is the integral of the so-called total
- curvature (implementation based on an algorithm from [2]_ - PCG sparse
- solver):
-
- .. math::
-
- E(z) = \frac{1}{2} \int_{\Omega} \left(
- \left( \frac{\partial^2{z}}{\partial{x}^2} \right)^2 +
- \left( \frac{\partial^2{z}}{\partial{y}^2} \right)^2 +
- 2\left( \frac{\partial^2{z}}{\partial{y}\partial{x}} \right)^2
- \right) dx\,dy
-
- If the case *kind* ='geom' is chosen by the user, a simple geometric
- approximation is used (weighted average of the triangle normal
- vectors), which could improve speed on very large grids.
-
- References
- ----------
- .. [1] Michel Bernadou, Kamal Hassan, "Basis functions for general
- Hsieh-Clough-Tocher triangles, complete or reduced.",
- International Journal for Numerical Methods in Engineering,
- 17(5):784 - 789. 2.01.
- .. [2] C.T. Kelley, "Iterative Methods for Optimization".
-
- """
- def __init__(self, triangulation, z, kind='min_E', trifinder=None,
- dz=None):
- super().__init__(triangulation, z, trifinder)
-
- # Loads the underlying c++ _triangulation.
- # (During loading, reordering of triangulation._triangles may occur so
- # that all final triangles are now anti-clockwise)
- self._triangulation.get_cpp_triangulation()
-
- # To build the stiffness matrix and avoid zero-energy spurious modes
- # we will only store internally the valid (unmasked) triangles and
- # the necessary (used) points coordinates.
- # 2 renumbering tables need to be computed and stored:
- # - a triangle renum table in order to translate the result from a
- # TriFinder instance into the internal stored triangle number.
- # - a node renum table to overwrite the self._z values into the new
- # (used) node numbering.
- tri_analyzer = TriAnalyzer(self._triangulation)
- (compressed_triangles, compressed_x, compressed_y, tri_renum,
- node_renum) = tri_analyzer._get_compressed_triangulation()
- self._triangles = compressed_triangles
- self._tri_renum = tri_renum
- # Taking into account the node renumbering in self._z:
- valid_node = (node_renum != -1)
- self._z[node_renum[valid_node]] = self._z[valid_node]
-
- # Computing scale factors
- self._unit_x = np.ptp(compressed_x)
- self._unit_y = np.ptp(compressed_y)
- self._pts = np.column_stack([compressed_x / self._unit_x,
- compressed_y / self._unit_y])
- # Computing triangle points
- self._tris_pts = self._pts[self._triangles]
- # Computing eccentricities
- self._eccs = self._compute_tri_eccentricities(self._tris_pts)
- # Computing dof estimations for HCT triangle shape function
- _api.check_in_list(['user', 'geom', 'min_E'], kind=kind)
- self._dof = self._compute_dof(kind, dz=dz)
- # Loading HCT element
- self._ReferenceElement = _ReducedHCT_Element()
-
- def __call__(self, x, y):
- return self._interpolate_multikeys(x, y, tri_index=None,
- return_keys=('z',))[0]
- __call__.__doc__ = TriInterpolator._docstring__call__
-
- def gradient(self, x, y):
- return self._interpolate_multikeys(x, y, tri_index=None,
- return_keys=('dzdx', 'dzdy'))
- gradient.__doc__ = TriInterpolator._docstringgradient
-
- def _interpolate_single_key(self, return_key, tri_index, x, y):
- _api.check_in_list(['z', 'dzdx', 'dzdy'], return_key=return_key)
- tris_pts = self._tris_pts[tri_index]
- alpha = self._get_alpha_vec(x, y, tris_pts)
- ecc = self._eccs[tri_index]
- dof = np.expand_dims(self._dof[tri_index], axis=1)
- if return_key == 'z':
- return self._ReferenceElement.get_function_values(
- alpha, ecc, dof)
- else: # 'dzdx', 'dzdy'
- J = self._get_jacobian(tris_pts)
- dzdx = self._ReferenceElement.get_function_derivatives(
- alpha, J, ecc, dof)
- if return_key == 'dzdx':
- return dzdx[:, 0, 0]
- else:
- return dzdx[:, 1, 0]
-
- def _compute_dof(self, kind, dz=None):
- """
- Compute and return nodal dofs according to kind.
-
- Parameters
- ----------
- kind : {'min_E', 'geom', 'user'}
- Choice of the _DOF_estimator subclass to estimate the gradient.
- dz : tuple of array-likes (dzdx, dzdy), optional
- Used only if *kind*=user; in this case passed to the
- :class:`_DOF_estimator_user`.
-
- Returns
- -------
- array-like, shape (npts, 2)
- Estimation of the gradient at triangulation nodes (stored as
- degree of freedoms of reduced-HCT triangle elements).
- """
- if kind == 'user':
- if dz is None:
- raise ValueError("For a CubicTriInterpolator with "
- "*kind*='user', a valid *dz* "
- "argument is expected.")
- TE = _DOF_estimator_user(self, dz=dz)
- elif kind == 'geom':
- TE = _DOF_estimator_geom(self)
- else: # 'min_E', checked in __init__
- TE = _DOF_estimator_min_E(self)
- return TE.compute_dof_from_df()
-
- @staticmethod
- def _get_alpha_vec(x, y, tris_pts):
- """
- Fast (vectorized) function to compute barycentric coordinates alpha.
-
- Parameters
- ----------
- x, y : array-like of dim 1 (shape (nx,))
- Coordinates of the points whose points barycentric coordinates are
- requested.
- tris_pts : array like of dim 3 (shape: (nx, 3, 2))
- Coordinates of the containing triangles apexes.
-
- Returns
- -------
- array of dim 2 (shape (nx, 3))
- Barycentric coordinates of the points inside the containing
- triangles.
- """
- ndim = tris_pts.ndim-2
-
- a = tris_pts[:, 1, :] - tris_pts[:, 0, :]
- b = tris_pts[:, 2, :] - tris_pts[:, 0, :]
- abT = np.stack([a, b], axis=-1)
- ab = _transpose_vectorized(abT)
- OM = np.stack([x, y], axis=1) - tris_pts[:, 0, :]
-
- metric = ab @ abT
- # Here we try to deal with the colinear cases.
- # metric_inv is in this case set to the Moore-Penrose pseudo-inverse
- # meaning that we will still return a set of valid barycentric
- # coordinates.
- metric_inv = _pseudo_inv22sym_vectorized(metric)
- Covar = ab @ _transpose_vectorized(np.expand_dims(OM, ndim))
- ksi = metric_inv @ Covar
- alpha = _to_matrix_vectorized([
- [1-ksi[:, 0, 0]-ksi[:, 1, 0]], [ksi[:, 0, 0]], [ksi[:, 1, 0]]])
- return alpha
-
- @staticmethod
- def _get_jacobian(tris_pts):
- """
- Fast (vectorized) function to compute triangle jacobian matrix.
-
- Parameters
- ----------
- tris_pts : array like of dim 3 (shape: (nx, 3, 2))
- Coordinates of the containing triangles apexes.
-
- Returns
- -------
- array of dim 3 (shape (nx, 2, 2))
- Barycentric coordinates of the points inside the containing
- triangles.
- J[itri, :, :] is the jacobian matrix at apex 0 of the triangle
- itri, so that the following (matrix) relationship holds:
- [dz/dksi] = [J] x [dz/dx]
- with x: global coordinates
- ksi: element parametric coordinates in triangle first apex
- local basis.
- """
- a = np.array(tris_pts[:, 1, :] - tris_pts[:, 0, :])
- b = np.array(tris_pts[:, 2, :] - tris_pts[:, 0, :])
- J = _to_matrix_vectorized([[a[:, 0], a[:, 1]],
- [b[:, 0], b[:, 1]]])
- return J
-
- @staticmethod
- def _compute_tri_eccentricities(tris_pts):
- """
- Compute triangle eccentricities.
-
- Parameters
- ----------
- tris_pts : array like of dim 3 (shape: (nx, 3, 2))
- Coordinates of the triangles apexes.
-
- Returns
- -------
- array like of dim 2 (shape: (nx, 3))
- The so-called eccentricity parameters [1] needed for HCT triangular
- element.
- """
- a = np.expand_dims(tris_pts[:, 2, :] - tris_pts[:, 1, :], axis=2)
- b = np.expand_dims(tris_pts[:, 0, :] - tris_pts[:, 2, :], axis=2)
- c = np.expand_dims(tris_pts[:, 1, :] - tris_pts[:, 0, :], axis=2)
- # Do not use np.squeeze, this is dangerous if only one triangle
- # in the triangulation...
- dot_a = (_transpose_vectorized(a) @ a)[:, 0, 0]
- dot_b = (_transpose_vectorized(b) @ b)[:, 0, 0]
- dot_c = (_transpose_vectorized(c) @ c)[:, 0, 0]
- # Note that this line will raise a warning for dot_a, dot_b or dot_c
- # zeros, but we choose not to support triangles with duplicate points.
- return _to_matrix_vectorized([[(dot_c-dot_b) / dot_a],
- [(dot_a-dot_c) / dot_b],
- [(dot_b-dot_a) / dot_c]])
-
-
-# FEM element used for interpolation and for solving minimisation
-# problem (Reduced HCT element)
-class _ReducedHCT_Element:
- """
- Implementation of reduced HCT triangular element with explicit shape
- functions.
-
- Computes z, dz, d2z and the element stiffness matrix for bending energy:
- E(f) = integral( (d2z/dx2 + d2z/dy2)**2 dA)
-
- *** Reference for the shape functions: ***
- [1] Basis functions for general Hsieh-Clough-Tocher _triangles, complete or
- reduced.
- Michel Bernadou, Kamal Hassan
- International Journal for Numerical Methods in Engineering.
- 17(5):784 - 789. 2.01
-
- *** Element description: ***
- 9 dofs: z and dz given at 3 apex
- C1 (conform)
-
- """
- # 1) Loads matrices to generate shape functions as a function of
- # triangle eccentricities - based on [1] p.11 '''
- M = np.array([
- [ 0.00, 0.00, 0.00, 4.50, 4.50, 0.00, 0.00, 0.00, 0.00, 0.00],
- [-0.25, 0.00, 0.00, 0.50, 1.25, 0.00, 0.00, 0.00, 0.00, 0.00],
- [-0.25, 0.00, 0.00, 1.25, 0.50, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.50, 1.00, 0.00, -1.50, 0.00, 3.00, 3.00, 0.00, 0.00, 3.00],
- [ 0.00, 0.00, 0.00, -0.25, 0.25, 0.00, 1.00, 0.00, 0.00, 0.50],
- [ 0.25, 0.00, 0.00, -0.50, -0.25, 1.00, 0.00, 0.00, 0.00, 1.00],
- [ 0.50, 0.00, 1.00, 0.00, -1.50, 0.00, 0.00, 3.00, 3.00, 3.00],
- [ 0.25, 0.00, 0.00, -0.25, -0.50, 0.00, 0.00, 0.00, 1.00, 1.00],
- [ 0.00, 0.00, 0.00, 0.25, -0.25, 0.00, 0.00, 1.00, 0.00, 0.50]])
- M0 = np.array([
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [-1.00, 0.00, 0.00, 1.50, 1.50, 0.00, 0.00, 0.00, 0.00, -3.00],
- [-0.50, 0.00, 0.00, 0.75, 0.75, 0.00, 0.00, 0.00, 0.00, -1.50],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 1.00, 0.00, 0.00, -1.50, -1.50, 0.00, 0.00, 0.00, 0.00, 3.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.50, 0.00, 0.00, -0.75, -0.75, 0.00, 0.00, 0.00, 0.00, 1.50]])
- M1 = np.array([
- [-0.50, 0.00, 0.00, 1.50, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [-0.25, 0.00, 0.00, 0.75, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.50, 0.00, 0.00, -1.50, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.25, 0.00, 0.00, -0.75, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00]])
- M2 = np.array([
- [ 0.50, 0.00, 0.00, 0.00, -1.50, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.25, 0.00, 0.00, 0.00, -0.75, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [-0.50, 0.00, 0.00, 0.00, 1.50, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [-0.25, 0.00, 0.00, 0.00, 0.75, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00],
- [ 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00, 0.00]])
-
- # 2) Loads matrices to rotate components of gradient & Hessian
- # vectors in the reference basis of triangle first apex (a0)
- rotate_dV = np.array([[ 1., 0.], [ 0., 1.],
- [ 0., 1.], [-1., -1.],
- [-1., -1.], [ 1., 0.]])
-
- rotate_d2V = np.array([[1., 0., 0.], [0., 1., 0.], [ 0., 0., 1.],
- [0., 1., 0.], [1., 1., 1.], [ 0., -2., -1.],
- [1., 1., 1.], [1., 0., 0.], [-2., 0., -1.]])
-
- # 3) Loads Gauss points & weights on the 3 sub-_triangles for P2
- # exact integral - 3 points on each subtriangles.
- # NOTE: as the 2nd derivative is discontinuous , we really need those 9
- # points!
- n_gauss = 9
- gauss_pts = np.array([[13./18., 4./18., 1./18.],
- [ 4./18., 13./18., 1./18.],
- [ 7./18., 7./18., 4./18.],
- [ 1./18., 13./18., 4./18.],
- [ 1./18., 4./18., 13./18.],
- [ 4./18., 7./18., 7./18.],
- [ 4./18., 1./18., 13./18.],
- [13./18., 1./18., 4./18.],
- [ 7./18., 4./18., 7./18.]], dtype=np.float64)
- gauss_w = np.ones([9], dtype=np.float64) / 9.
-
- # 4) Stiffness matrix for curvature energy
- E = np.array([[1., 0., 0.], [0., 1., 0.], [0., 0., 2.]])
-
- # 5) Loads the matrix to compute DOF_rot from tri_J at apex 0
- J0_to_J1 = np.array([[-1., 1.], [-1., 0.]])
- J0_to_J2 = np.array([[ 0., -1.], [ 1., -1.]])
-
- def get_function_values(self, alpha, ecc, dofs):
- """
- Parameters
- ----------
- alpha : is a (N x 3 x 1) array (array of column-matrices) of
- barycentric coordinates,
- ecc : is a (N x 3 x 1) array (array of column-matrices) of triangle
- eccentricities,
- dofs : is a (N x 1 x 9) arrays (arrays of row-matrices) of computed
- degrees of freedom.
-
- Returns
- -------
- Returns the N-array of interpolated function values.
- """
- subtri = np.argmin(alpha, axis=1)[:, 0]
- ksi = _roll_vectorized(alpha, -subtri, axis=0)
- E = _roll_vectorized(ecc, -subtri, axis=0)
- x = ksi[:, 0, 0]
- y = ksi[:, 1, 0]
- z = ksi[:, 2, 0]
- x_sq = x*x
- y_sq = y*y
- z_sq = z*z
- V = _to_matrix_vectorized([
- [x_sq*x], [y_sq*y], [z_sq*z], [x_sq*z], [x_sq*y], [y_sq*x],
- [y_sq*z], [z_sq*y], [z_sq*x], [x*y*z]])
- prod = self.M @ V
- prod += _scalar_vectorized(E[:, 0, 0], self.M0 @ V)
- prod += _scalar_vectorized(E[:, 1, 0], self.M1 @ V)
- prod += _scalar_vectorized(E[:, 2, 0], self.M2 @ V)
- s = _roll_vectorized(prod, 3*subtri, axis=0)
- return (dofs @ s)[:, 0, 0]
-
- def get_function_derivatives(self, alpha, J, ecc, dofs):
- """
- Parameters
- ----------
- *alpha* is a (N x 3 x 1) array (array of column-matrices of
- barycentric coordinates)
- *J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at
- triangle first apex)
- *ecc* is a (N x 3 x 1) array (array of column-matrices of triangle
- eccentricities)
- *dofs* is a (N x 1 x 9) arrays (arrays of row-matrices) of computed
- degrees of freedom.
-
- Returns
- -------
- Returns the values of interpolated function derivatives [dz/dx, dz/dy]
- in global coordinates at locations alpha, as a column-matrices of
- shape (N x 2 x 1).
- """
- subtri = np.argmin(alpha, axis=1)[:, 0]
- ksi = _roll_vectorized(alpha, -subtri, axis=0)
- E = _roll_vectorized(ecc, -subtri, axis=0)
- x = ksi[:, 0, 0]
- y = ksi[:, 1, 0]
- z = ksi[:, 2, 0]
- x_sq = x*x
- y_sq = y*y
- z_sq = z*z
- dV = _to_matrix_vectorized([
- [ -3.*x_sq, -3.*x_sq],
- [ 3.*y_sq, 0.],
- [ 0., 3.*z_sq],
- [ -2.*x*z, -2.*x*z+x_sq],
- [-2.*x*y+x_sq, -2.*x*y],
- [ 2.*x*y-y_sq, -y_sq],
- [ 2.*y*z, y_sq],
- [ z_sq, 2.*y*z],
- [ -z_sq, 2.*x*z-z_sq],
- [ x*z-y*z, x*y-y*z]])
- # Puts back dV in first apex basis
- dV = dV @ _extract_submatrices(
- self.rotate_dV, subtri, block_size=2, axis=0)
-
- prod = self.M @ dV
- prod += _scalar_vectorized(E[:, 0, 0], self.M0 @ dV)
- prod += _scalar_vectorized(E[:, 1, 0], self.M1 @ dV)
- prod += _scalar_vectorized(E[:, 2, 0], self.M2 @ dV)
- dsdksi = _roll_vectorized(prod, 3*subtri, axis=0)
- dfdksi = dofs @ dsdksi
- # In global coordinates:
- # Here we try to deal with the simplest colinear cases, returning a
- # null matrix.
- J_inv = _safe_inv22_vectorized(J)
- dfdx = J_inv @ _transpose_vectorized(dfdksi)
- return dfdx
-
- def get_function_hessians(self, alpha, J, ecc, dofs):
- """
- Parameters
- ----------
- *alpha* is a (N x 3 x 1) array (array of column-matrices) of
- barycentric coordinates
- *J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at
- triangle first apex)
- *ecc* is a (N x 3 x 1) array (array of column-matrices) of triangle
- eccentricities
- *dofs* is a (N x 1 x 9) arrays (arrays of row-matrices) of computed
- degrees of freedom.
-
- Returns
- -------
- Returns the values of interpolated function 2nd-derivatives
- [d2z/dx2, d2z/dy2, d2z/dxdy] in global coordinates at locations alpha,
- as a column-matrices of shape (N x 3 x 1).
- """
- d2sdksi2 = self.get_d2Sidksij2(alpha, ecc)
- d2fdksi2 = dofs @ d2sdksi2
- H_rot = self.get_Hrot_from_J(J)
- d2fdx2 = d2fdksi2 @ H_rot
- return _transpose_vectorized(d2fdx2)
-
- def get_d2Sidksij2(self, alpha, ecc):
- """
- Parameters
- ----------
- *alpha* is a (N x 3 x 1) array (array of column-matrices) of
- barycentric coordinates
- *ecc* is a (N x 3 x 1) array (array of column-matrices) of triangle
- eccentricities
-
- Returns
- -------
- Returns the arrays d2sdksi2 (N x 3 x 1) Hessian of shape functions
- expressed in covariant coordinates in first apex basis.
- """
- subtri = np.argmin(alpha, axis=1)[:, 0]
- ksi = _roll_vectorized(alpha, -subtri, axis=0)
- E = _roll_vectorized(ecc, -subtri, axis=0)
- x = ksi[:, 0, 0]
- y = ksi[:, 1, 0]
- z = ksi[:, 2, 0]
- d2V = _to_matrix_vectorized([
- [ 6.*x, 6.*x, 6.*x],
- [ 6.*y, 0., 0.],
- [ 0., 6.*z, 0.],
- [ 2.*z, 2.*z-4.*x, 2.*z-2.*x],
- [2.*y-4.*x, 2.*y, 2.*y-2.*x],
- [2.*x-4.*y, 0., -2.*y],
- [ 2.*z, 0., 2.*y],
- [ 0., 2.*y, 2.*z],
- [ 0., 2.*x-4.*z, -2.*z],
- [ -2.*z, -2.*y, x-y-z]])
- # Puts back d2V in first apex basis
- d2V = d2V @ _extract_submatrices(
- self.rotate_d2V, subtri, block_size=3, axis=0)
- prod = self.M @ d2V
- prod += _scalar_vectorized(E[:, 0, 0], self.M0 @ d2V)
- prod += _scalar_vectorized(E[:, 1, 0], self.M1 @ d2V)
- prod += _scalar_vectorized(E[:, 2, 0], self.M2 @ d2V)
- d2sdksi2 = _roll_vectorized(prod, 3*subtri, axis=0)
- return d2sdksi2
-
- def get_bending_matrices(self, J, ecc):
- """
- Parameters
- ----------
- *J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at
- triangle first apex)
- *ecc* is a (N x 3 x 1) array (array of column-matrices) of triangle
- eccentricities
-
- Returns
- -------
- Returns the element K matrices for bending energy expressed in
- GLOBAL nodal coordinates.
- K_ij = integral [ (d2zi/dx2 + d2zi/dy2) * (d2zj/dx2 + d2zj/dy2) dA]
- tri_J is needed to rotate dofs from local basis to global basis
- """
- n = np.size(ecc, 0)
-
- # 1) matrix to rotate dofs in global coordinates
- J1 = self.J0_to_J1 @ J
- J2 = self.J0_to_J2 @ J
- DOF_rot = np.zeros([n, 9, 9], dtype=np.float64)
- DOF_rot[:, 0, 0] = 1
- DOF_rot[:, 3, 3] = 1
- DOF_rot[:, 6, 6] = 1
- DOF_rot[:, 1:3, 1:3] = J
- DOF_rot[:, 4:6, 4:6] = J1
- DOF_rot[:, 7:9, 7:9] = J2
-
- # 2) matrix to rotate Hessian in global coordinates.
- H_rot, area = self.get_Hrot_from_J(J, return_area=True)
-
- # 3) Computes stiffness matrix
- # Gauss quadrature.
- K = np.zeros([n, 9, 9], dtype=np.float64)
- weights = self.gauss_w
- pts = self.gauss_pts
- for igauss in range(self.n_gauss):
- alpha = np.tile(pts[igauss, :], n).reshape(n, 3)
- alpha = np.expand_dims(alpha, 2)
- weight = weights[igauss]
- d2Skdksi2 = self.get_d2Sidksij2(alpha, ecc)
- d2Skdx2 = d2Skdksi2 @ H_rot
- K += weight * (d2Skdx2 @ self.E @ _transpose_vectorized(d2Skdx2))
-
- # 4) With nodal (not elem) dofs
- K = _transpose_vectorized(DOF_rot) @ K @ DOF_rot
-
- # 5) Need the area to compute total element energy
- return _scalar_vectorized(area, K)
-
- def get_Hrot_from_J(self, J, return_area=False):
- """
- Parameters
- ----------
- *J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at
- triangle first apex)
-
- Returns
- -------
- Returns H_rot used to rotate Hessian from local basis of first apex,
- to global coordinates.
- if *return_area* is True, returns also the triangle area (0.5*det(J))
- """
- # Here we try to deal with the simplest colinear cases; a null
- # energy and area is imposed.
- J_inv = _safe_inv22_vectorized(J)
- Ji00 = J_inv[:, 0, 0]
- Ji11 = J_inv[:, 1, 1]
- Ji10 = J_inv[:, 1, 0]
- Ji01 = J_inv[:, 0, 1]
- H_rot = _to_matrix_vectorized([
- [Ji00*Ji00, Ji10*Ji10, Ji00*Ji10],
- [Ji01*Ji01, Ji11*Ji11, Ji01*Ji11],
- [2*Ji00*Ji01, 2*Ji11*Ji10, Ji00*Ji11+Ji10*Ji01]])
- if not return_area:
- return H_rot
- else:
- area = 0.5 * (J[:, 0, 0]*J[:, 1, 1] - J[:, 0, 1]*J[:, 1, 0])
- return H_rot, area
-
- def get_Kff_and_Ff(self, J, ecc, triangles, Uc):
- """
- Build K and F for the following elliptic formulation:
- minimization of curvature energy with value of function at node
- imposed and derivatives 'free'.
-
- Build the global Kff matrix in cco format.
- Build the full Ff vec Ff = - Kfc x Uc.
-
- Parameters
- ----------
- *J* is a (N x 2 x 2) array of jacobian matrices (jacobian matrix at
- triangle first apex)
- *ecc* is a (N x 3 x 1) array (array of column-matrices) of triangle
- eccentricities
- *triangles* is a (N x 3) array of nodes indexes.
- *Uc* is (N x 3) array of imposed displacements at nodes
-
- Returns
- -------
- (Kff_rows, Kff_cols, Kff_vals) Kff matrix in coo format - Duplicate
- (row, col) entries must be summed.
- Ff: force vector - dim npts * 3
- """
- ntri = np.size(ecc, 0)
- vec_range = np.arange(ntri, dtype=np.int32)
- c_indices = np.full(ntri, -1, dtype=np.int32) # for unused dofs, -1
- f_dof = [1, 2, 4, 5, 7, 8]
- c_dof = [0, 3, 6]
-
- # vals, rows and cols indices in global dof numbering
- f_dof_indices = _to_matrix_vectorized([[
- c_indices, triangles[:, 0]*2, triangles[:, 0]*2+1,
- c_indices, triangles[:, 1]*2, triangles[:, 1]*2+1,
- c_indices, triangles[:, 2]*2, triangles[:, 2]*2+1]])
-
- expand_indices = np.ones([ntri, 9, 1], dtype=np.int32)
- f_row_indices = _transpose_vectorized(expand_indices @ f_dof_indices)
- f_col_indices = expand_indices @ f_dof_indices
- K_elem = self.get_bending_matrices(J, ecc)
-
- # Extracting sub-matrices
- # Explanation & notations:
- # * Subscript f denotes 'free' degrees of freedom (i.e. dz/dx, dz/dx)
- # * Subscript c denotes 'condensated' (imposed) degrees of freedom
- # (i.e. z at all nodes)
- # * F = [Ff, Fc] is the force vector
- # * U = [Uf, Uc] is the imposed dof vector
- # [ Kff Kfc ]
- # * K = [ ] is the laplacian stiffness matrix
- # [ Kcf Kff ]
- # * As F = K x U one gets straightforwardly: Ff = - Kfc x Uc
-
- # Computing Kff stiffness matrix in sparse coo format
- Kff_vals = np.ravel(K_elem[np.ix_(vec_range, f_dof, f_dof)])
- Kff_rows = np.ravel(f_row_indices[np.ix_(vec_range, f_dof, f_dof)])
- Kff_cols = np.ravel(f_col_indices[np.ix_(vec_range, f_dof, f_dof)])
-
- # Computing Ff force vector in sparse coo format
- Kfc_elem = K_elem[np.ix_(vec_range, f_dof, c_dof)]
- Uc_elem = np.expand_dims(Uc, axis=2)
- Ff_elem = -(Kfc_elem @ Uc_elem)[:, :, 0]
- Ff_indices = f_dof_indices[np.ix_(vec_range, [0], f_dof)][:, 0, :]
-
- # Extracting Ff force vector in dense format
- # We have to sum duplicate indices - using bincount
- Ff = np.bincount(np.ravel(Ff_indices), weights=np.ravel(Ff_elem))
- return Kff_rows, Kff_cols, Kff_vals, Ff
-
-
-# :class:_DOF_estimator, _DOF_estimator_user, _DOF_estimator_geom,
-# _DOF_estimator_min_E
-# Private classes used to compute the degree of freedom of each triangular
-# element for the TriCubicInterpolator.
-class _DOF_estimator:
- """
- Abstract base class for classes used to estimate a function's first
- derivatives, and deduce the dofs for a CubicTriInterpolator using a
- reduced HCT element formulation.
-
- Derived classes implement ``compute_df(self, **kwargs)``, returning
- ``np.vstack([dfx, dfy]).T`` where ``dfx, dfy`` are the estimation of the 2
- gradient coordinates.
- """
- def __init__(self, interpolator, **kwargs):
- _api.check_isinstance(CubicTriInterpolator, interpolator=interpolator)
- self._pts = interpolator._pts
- self._tris_pts = interpolator._tris_pts
- self.z = interpolator._z
- self._triangles = interpolator._triangles
- (self._unit_x, self._unit_y) = (interpolator._unit_x,
- interpolator._unit_y)
- self.dz = self.compute_dz(**kwargs)
- self.compute_dof_from_df()
-
- def compute_dz(self, **kwargs):
- raise NotImplementedError
-
- def compute_dof_from_df(self):
- """
- Compute reduced-HCT elements degrees of freedom, from the gradient.
- """
- J = CubicTriInterpolator._get_jacobian(self._tris_pts)
- tri_z = self.z[self._triangles]
- tri_dz = self.dz[self._triangles]
- tri_dof = self.get_dof_vec(tri_z, tri_dz, J)
- return tri_dof
-
- @staticmethod
- def get_dof_vec(tri_z, tri_dz, J):
- """
- Compute the dof vector of a triangle, from the value of f, df and
- of the local Jacobian at each node.
-
- Parameters
- ----------
- tri_z : shape (3,) array
- f nodal values.
- tri_dz : shape (3, 2) array
- df/dx, df/dy nodal values.
- J
- Jacobian matrix in local basis of apex 0.
-
- Returns
- -------
- dof : shape (9,) array
- For each apex ``iapex``::
-
- dof[iapex*3+0] = f(Ai)
- dof[iapex*3+1] = df(Ai).(AiAi+)
- dof[iapex*3+2] = df(Ai).(AiAi-)
- """
- npt = tri_z.shape[0]
- dof = np.zeros([npt, 9], dtype=np.float64)
- J1 = _ReducedHCT_Element.J0_to_J1 @ J
- J2 = _ReducedHCT_Element.J0_to_J2 @ J
-
- col0 = J @ np.expand_dims(tri_dz[:, 0, :], axis=2)
- col1 = J1 @ np.expand_dims(tri_dz[:, 1, :], axis=2)
- col2 = J2 @ np.expand_dims(tri_dz[:, 2, :], axis=2)
-
- dfdksi = _to_matrix_vectorized([
- [col0[:, 0, 0], col1[:, 0, 0], col2[:, 0, 0]],
- [col0[:, 1, 0], col1[:, 1, 0], col2[:, 1, 0]]])
- dof[:, 0:7:3] = tri_z
- dof[:, 1:8:3] = dfdksi[:, 0]
- dof[:, 2:9:3] = dfdksi[:, 1]
- return dof
-
-
-class _DOF_estimator_user(_DOF_estimator):
- """dz is imposed by user; accounts for scaling if any."""
-
- def compute_dz(self, dz):
- (dzdx, dzdy) = dz
- dzdx = dzdx * self._unit_x
- dzdy = dzdy * self._unit_y
- return np.vstack([dzdx, dzdy]).T
-
-
-class _DOF_estimator_geom(_DOF_estimator):
- """Fast 'geometric' approximation, recommended for large arrays."""
-
- def compute_dz(self):
- """
- self.df is computed as weighted average of _triangles sharing a common
- node. On each triangle itri f is first assumed linear (= ~f), which
- allows to compute d~f[itri]
- Then the following approximation of df nodal values is then proposed:
- f[ipt] = SUM ( w[itri] x d~f[itri] , for itri sharing apex ipt)
- The weighted coeff. w[itri] are proportional to the angle of the
- triangle itri at apex ipt
- """
- el_geom_w = self.compute_geom_weights()
- el_geom_grad = self.compute_geom_grads()
-
- # Sum of weights coeffs
- w_node_sum = np.bincount(np.ravel(self._triangles),
- weights=np.ravel(el_geom_w))
-
- # Sum of weighted df = (dfx, dfy)
- dfx_el_w = np.empty_like(el_geom_w)
- dfy_el_w = np.empty_like(el_geom_w)
- for iapex in range(3):
- dfx_el_w[:, iapex] = el_geom_w[:, iapex]*el_geom_grad[:, 0]
- dfy_el_w[:, iapex] = el_geom_w[:, iapex]*el_geom_grad[:, 1]
- dfx_node_sum = np.bincount(np.ravel(self._triangles),
- weights=np.ravel(dfx_el_w))
- dfy_node_sum = np.bincount(np.ravel(self._triangles),
- weights=np.ravel(dfy_el_w))
-
- # Estimation of df
- dfx_estim = dfx_node_sum/w_node_sum
- dfy_estim = dfy_node_sum/w_node_sum
- return np.vstack([dfx_estim, dfy_estim]).T
-
- def compute_geom_weights(self):
- """
- Build the (nelems, 3) weights coeffs of _triangles angles,
- renormalized so that np.sum(weights, axis=1) == np.ones(nelems)
- """
- weights = np.zeros([np.size(self._triangles, 0), 3])
- tris_pts = self._tris_pts
- for ipt in range(3):
- p0 = tris_pts[:, ipt % 3, :]
- p1 = tris_pts[:, (ipt+1) % 3, :]
- p2 = tris_pts[:, (ipt-1) % 3, :]
- alpha1 = np.arctan2(p1[:, 1]-p0[:, 1], p1[:, 0]-p0[:, 0])
- alpha2 = np.arctan2(p2[:, 1]-p0[:, 1], p2[:, 0]-p0[:, 0])
- # In the below formula we could take modulo 2. but
- # modulo 1. is safer regarding round-off errors (flat triangles).
- angle = np.abs(((alpha2-alpha1) / np.pi) % 1)
- # Weight proportional to angle up np.pi/2; null weight for
- # degenerated cases 0 and np.pi (note that *angle* is normalized
- # by np.pi).
- weights[:, ipt] = 0.5 - np.abs(angle-0.5)
- return weights
-
- def compute_geom_grads(self):
- """
- Compute the (global) gradient component of f assumed linear (~f).
- returns array df of shape (nelems, 2)
- df[ielem].dM[ielem] = dz[ielem] i.e. df = dz x dM = dM.T^-1 x dz
- """
- tris_pts = self._tris_pts
- tris_f = self.z[self._triangles]
-
- dM1 = tris_pts[:, 1, :] - tris_pts[:, 0, :]
- dM2 = tris_pts[:, 2, :] - tris_pts[:, 0, :]
- dM = np.dstack([dM1, dM2])
- # Here we try to deal with the simplest colinear cases: a null
- # gradient is assumed in this case.
- dM_inv = _safe_inv22_vectorized(dM)
-
- dZ1 = tris_f[:, 1] - tris_f[:, 0]
- dZ2 = tris_f[:, 2] - tris_f[:, 0]
- dZ = np.vstack([dZ1, dZ2]).T
- df = np.empty_like(dZ)
-
- # With np.einsum: could be ej,eji -> ej
- df[:, 0] = dZ[:, 0]*dM_inv[:, 0, 0] + dZ[:, 1]*dM_inv[:, 1, 0]
- df[:, 1] = dZ[:, 0]*dM_inv[:, 0, 1] + dZ[:, 1]*dM_inv[:, 1, 1]
- return df
-
-
-class _DOF_estimator_min_E(_DOF_estimator_geom):
- """
- The 'smoothest' approximation, df is computed through global minimization
- of the bending energy:
- E(f) = integral[(d2z/dx2 + d2z/dy2 + 2 d2z/dxdy)**2 dA]
- """
- def __init__(self, Interpolator):
- self._eccs = Interpolator._eccs
- super().__init__(Interpolator)
-
- def compute_dz(self):
- """
- Elliptic solver for bending energy minimization.
- Uses a dedicated 'toy' sparse Jacobi PCG solver.
- """
- # Initial guess for iterative PCG solver.
- dz_init = super().compute_dz()
- Uf0 = np.ravel(dz_init)
-
- reference_element = _ReducedHCT_Element()
- J = CubicTriInterpolator._get_jacobian(self._tris_pts)
- eccs = self._eccs
- triangles = self._triangles
- Uc = self.z[self._triangles]
-
- # Building stiffness matrix and force vector in coo format
- Kff_rows, Kff_cols, Kff_vals, Ff = reference_element.get_Kff_and_Ff(
- J, eccs, triangles, Uc)
-
- # Building sparse matrix and solving minimization problem
- # We could use scipy.sparse direct solver; however to avoid this
- # external dependency an implementation of a simple PCG solver with
- # a simple diagonal Jacobi preconditioner is implemented.
- tol = 1.e-10
- n_dof = Ff.shape[0]
- Kff_coo = _Sparse_Matrix_coo(Kff_vals, Kff_rows, Kff_cols,
- shape=(n_dof, n_dof))
- Kff_coo.compress_csc()
- Uf, err = _cg(A=Kff_coo, b=Ff, x0=Uf0, tol=tol)
- # If the PCG did not converge, we return the best guess between Uf0
- # and Uf.
- err0 = np.linalg.norm(Kff_coo.dot(Uf0) - Ff)
- if err0 < err:
- # Maybe a good occasion to raise a warning here ?
- _api.warn_external("In TriCubicInterpolator initialization, "
- "PCG sparse solver did not converge after "
- "1000 iterations. `geom` approximation is "
- "used instead of `min_E`")
- Uf = Uf0
-
- # Building dz from Uf
- dz = np.empty([self._pts.shape[0], 2], dtype=np.float64)
- dz[:, 0] = Uf[::2]
- dz[:, 1] = Uf[1::2]
- return dz
-
-
-# The following private :class:_Sparse_Matrix_coo and :func:_cg provide
-# a PCG sparse solver for (symmetric) elliptic problems.
-class _Sparse_Matrix_coo:
- def __init__(self, vals, rows, cols, shape):
- """
- Create a sparse matrix in coo format.
- *vals*: arrays of values of non-null entries of the matrix
- *rows*: int arrays of rows of non-null entries of the matrix
- *cols*: int arrays of cols of non-null entries of the matrix
- *shape*: 2-tuple (n, m) of matrix shape
- """
- self.n, self.m = shape
- self.vals = np.asarray(vals, dtype=np.float64)
- self.rows = np.asarray(rows, dtype=np.int32)
- self.cols = np.asarray(cols, dtype=np.int32)
-
- def dot(self, V):
- """
- Dot product of self by a vector *V* in sparse-dense to dense format
- *V* dense vector of shape (self.m,).
- """
- assert V.shape == (self.m,)
- return np.bincount(self.rows,
- weights=self.vals*V[self.cols],
- minlength=self.m)
-
- def compress_csc(self):
- """
- Compress rows, cols, vals / summing duplicates. Sort for csc format.
- """
- _, unique, indices = np.unique(
- self.rows + self.n*self.cols,
- return_index=True, return_inverse=True)
- self.rows = self.rows[unique]
- self.cols = self.cols[unique]
- self.vals = np.bincount(indices, weights=self.vals)
-
- def compress_csr(self):
- """
- Compress rows, cols, vals / summing duplicates. Sort for csr format.
- """
- _, unique, indices = np.unique(
- self.m*self.rows + self.cols,
- return_index=True, return_inverse=True)
- self.rows = self.rows[unique]
- self.cols = self.cols[unique]
- self.vals = np.bincount(indices, weights=self.vals)
-
- def to_dense(self):
- """
- Return a dense matrix representing self, mainly for debugging purposes.
- """
- ret = np.zeros([self.n, self.m], dtype=np.float64)
- nvals = self.vals.size
- for i in range(nvals):
- ret[self.rows[i], self.cols[i]] += self.vals[i]
- return ret
-
- def __str__(self):
- return self.to_dense().__str__()
-
- @property
- def diag(self):
- """Return the (dense) vector of the diagonal elements."""
- in_diag = (self.rows == self.cols)
- diag = np.zeros(min(self.n, self.n), dtype=np.float64) # default 0.
- diag[self.rows[in_diag]] = self.vals[in_diag]
- return diag
-
-
-def _cg(A, b, x0=None, tol=1.e-10, maxiter=1000):
- """
- Use Preconditioned Conjugate Gradient iteration to solve A x = b
- A simple Jacobi (diagonal) preconditioner is used.
-
- Parameters
- ----------
- A : _Sparse_Matrix_coo
- *A* must have been compressed before by compress_csc or
- compress_csr method.
- b : array
- Right hand side of the linear system.
- x0 : array, optional
- Starting guess for the solution. Defaults to the zero vector.
- tol : float, optional
- Tolerance to achieve. The algorithm terminates when the relative
- residual is below tol. Default is 1e-10.
- maxiter : int, optional
- Maximum number of iterations. Iteration will stop after *maxiter*
- steps even if the specified tolerance has not been achieved. Defaults
- to 1000.
-
- Returns
- -------
- x : array
- The converged solution.
- err : float
- The absolute error np.linalg.norm(A.dot(x) - b)
- """
- n = b.size
- assert A.n == n
- assert A.m == n
- b_norm = np.linalg.norm(b)
-
- # Jacobi pre-conditioner
- kvec = A.diag
- # For diag elem < 1e-6 we keep 1e-6.
- kvec = np.maximum(kvec, 1e-6)
-
- # Initial guess
- if x0 is None:
- x = np.zeros(n)
- else:
- x = x0
-
- r = b - A.dot(x)
- w = r/kvec
-
- p = np.zeros(n)
- beta = 0.0
- rho = np.dot(r, w)
- k = 0
-
- # Following C. T. Kelley
- while (np.sqrt(abs(rho)) > tol*b_norm) and (k < maxiter):
- p = w + beta*p
- z = A.dot(p)
- alpha = rho/np.dot(p, z)
- r = r - alpha*z
- w = r/kvec
- rhoold = rho
- rho = np.dot(r, w)
- x = x + alpha*p
- beta = rho/rhoold
- # err = np.linalg.norm(A.dot(x) - b) # absolute accuracy - not used
- k += 1
- err = np.linalg.norm(A.dot(x) - b)
- return x, err
-
-
-# The following private functions:
-# :func:`_safe_inv22_vectorized`
-# :func:`_pseudo_inv22sym_vectorized`
-# :func:`_scalar_vectorized`
-# :func:`_transpose_vectorized`
-# :func:`_roll_vectorized`
-# :func:`_to_matrix_vectorized`
-# :func:`_extract_submatrices`
-# provide fast numpy implementation of some standard operations on arrays of
-# matrices - stored as (:, n_rows, n_cols)-shaped np.arrays.
-
-# Development note: Dealing with pathologic 'flat' triangles in the
-# CubicTriInterpolator code and impact on (2, 2)-matrix inversion functions
-# :func:`_safe_inv22_vectorized` and :func:`_pseudo_inv22sym_vectorized`.
-#
-# Goals:
-# 1) The CubicTriInterpolator should be able to handle flat or almost flat
-# triangles without raising an error,
-# 2) These degenerated triangles should have no impact on the automatic dof
-# calculation (associated with null weight for the _DOF_estimator_geom and
-# with null energy for the _DOF_estimator_min_E),
-# 3) Linear patch test should be passed exactly on degenerated meshes,
-# 4) Interpolation (with :meth:`_interpolate_single_key` or
-# :meth:`_interpolate_multi_key`) shall be correctly handled even *inside*
-# the pathologic triangles, to interact correctly with a TriRefiner class.
-#
-# Difficulties:
-# Flat triangles have rank-deficient *J* (so-called jacobian matrix) and
-# *metric* (the metric tensor = J x J.T). Computation of the local
-# tangent plane is also problematic.
-#
-# Implementation:
-# Most of the time, when computing the inverse of a rank-deficient matrix it
-# is safe to simply return the null matrix (which is the implementation in
-# :func:`_safe_inv22_vectorized`). This is because of point 2), itself
-# enforced by:
-# - null area hence null energy in :class:`_DOF_estimator_min_E`
-# - angles close or equal to 0 or np.pi hence null weight in
-# :class:`_DOF_estimator_geom`.
-# Note that the function angle -> weight is continuous and maximum for an
-# angle np.pi/2 (refer to :meth:`compute_geom_weights`)
-# The exception is the computation of barycentric coordinates, which is done
-# by inversion of the *metric* matrix. In this case, we need to compute a set
-# of valid coordinates (1 among numerous possibilities), to ensure point 4).
-# We benefit here from the symmetry of metric = J x J.T, which makes it easier
-# to compute a pseudo-inverse in :func:`_pseudo_inv22sym_vectorized`
-def _safe_inv22_vectorized(M):
- """
- Inversion of arrays of (2, 2) matrices, returns 0 for rank-deficient
- matrices.
-
- *M* : array of (2, 2) matrices to inverse, shape (n, 2, 2)
- """
- _api.check_shape((None, 2, 2), M=M)
- M_inv = np.empty_like(M)
- prod1 = M[:, 0, 0]*M[:, 1, 1]
- delta = prod1 - M[:, 0, 1]*M[:, 1, 0]
-
- # We set delta_inv to 0. in case of a rank deficient matrix; a
- # rank-deficient input matrix *M* will lead to a null matrix in output
- rank2 = (np.abs(delta) > 1e-8*np.abs(prod1))
- if np.all(rank2):
- # Normal 'optimized' flow.
- delta_inv = 1./delta
- else:
- # 'Pathologic' flow.
- delta_inv = np.zeros(M.shape[0])
- delta_inv[rank2] = 1./delta[rank2]
-
- M_inv[:, 0, 0] = M[:, 1, 1]*delta_inv
- M_inv[:, 0, 1] = -M[:, 0, 1]*delta_inv
- M_inv[:, 1, 0] = -M[:, 1, 0]*delta_inv
- M_inv[:, 1, 1] = M[:, 0, 0]*delta_inv
- return M_inv
-
-
-def _pseudo_inv22sym_vectorized(M):
- """
- Inversion of arrays of (2, 2) SYMMETRIC matrices; returns the
- (Moore-Penrose) pseudo-inverse for rank-deficient matrices.
-
- In case M is of rank 1, we have M = trace(M) x P where P is the orthogonal
- projection on Im(M), and we return trace(M)^-1 x P == M / trace(M)**2
- In case M is of rank 0, we return the null matrix.
-
- *M* : array of (2, 2) matrices to inverse, shape (n, 2, 2)
- """
- _api.check_shape((None, 2, 2), M=M)
- M_inv = np.empty_like(M)
- prod1 = M[:, 0, 0]*M[:, 1, 1]
- delta = prod1 - M[:, 0, 1]*M[:, 1, 0]
- rank2 = (np.abs(delta) > 1e-8*np.abs(prod1))
-
- if np.all(rank2):
- # Normal 'optimized' flow.
- M_inv[:, 0, 0] = M[:, 1, 1] / delta
- M_inv[:, 0, 1] = -M[:, 0, 1] / delta
- M_inv[:, 1, 0] = -M[:, 1, 0] / delta
- M_inv[:, 1, 1] = M[:, 0, 0] / delta
- else:
- # 'Pathologic' flow.
- # Here we have to deal with 2 sub-cases
- # 1) First sub-case: matrices of rank 2:
- delta = delta[rank2]
- M_inv[rank2, 0, 0] = M[rank2, 1, 1] / delta
- M_inv[rank2, 0, 1] = -M[rank2, 0, 1] / delta
- M_inv[rank2, 1, 0] = -M[rank2, 1, 0] / delta
- M_inv[rank2, 1, 1] = M[rank2, 0, 0] / delta
- # 2) Second sub-case: rank-deficient matrices of rank 0 and 1:
- rank01 = ~rank2
- tr = M[rank01, 0, 0] + M[rank01, 1, 1]
- tr_zeros = (np.abs(tr) < 1.e-8)
- sq_tr_inv = (1.-tr_zeros) / (tr**2+tr_zeros)
- # sq_tr_inv = 1. / tr**2
- M_inv[rank01, 0, 0] = M[rank01, 0, 0] * sq_tr_inv
- M_inv[rank01, 0, 1] = M[rank01, 0, 1] * sq_tr_inv
- M_inv[rank01, 1, 0] = M[rank01, 1, 0] * sq_tr_inv
- M_inv[rank01, 1, 1] = M[rank01, 1, 1] * sq_tr_inv
-
- return M_inv
-
-
-def _scalar_vectorized(scalar, M):
- """
- Scalar product between scalars and matrices.
- """
- return scalar[:, np.newaxis, np.newaxis]*M
-
-
-def _transpose_vectorized(M):
- """
- Transposition of an array of matrices *M*.
- """
- return np.transpose(M, [0, 2, 1])
-
-
-def _roll_vectorized(M, roll_indices, axis):
- """
- Roll an array of matrices along *axis* (0: rows, 1: columns) according to
- an array of indices *roll_indices*.
- """
- assert axis in [0, 1]
- ndim = M.ndim
- assert ndim == 3
- ndim_roll = roll_indices.ndim
- assert ndim_roll == 1
- sh = M.shape
- r, c = sh[-2:]
- assert sh[0] == roll_indices.shape[0]
- vec_indices = np.arange(sh[0], dtype=np.int32)
-
- # Builds the rolled matrix
- M_roll = np.empty_like(M)
- if axis == 0:
- for ir in range(r):
- for ic in range(c):
- M_roll[:, ir, ic] = M[vec_indices, (-roll_indices+ir) % r, ic]
- else: # 1
- for ir in range(r):
- for ic in range(c):
- M_roll[:, ir, ic] = M[vec_indices, ir, (-roll_indices+ic) % c]
- return M_roll
-
-
-def _to_matrix_vectorized(M):
- """
- Build an array of matrices from individuals np.arrays of identical shapes.
-
- Parameters
- ----------
- M
- ncols-list of nrows-lists of shape sh.
-
- Returns
- -------
- M_res : np.array of shape (sh, nrow, ncols)
- *M_res* satisfies ``M_res[..., i, j] = M[i][j]``.
- """
- assert isinstance(M, (tuple, list))
- assert all(isinstance(item, (tuple, list)) for item in M)
- c_vec = np.asarray([len(item) for item in M])
- assert np.all(c_vec-c_vec[0] == 0)
- r = len(M)
- c = c_vec[0]
- M00 = np.asarray(M[0][0])
- dt = M00.dtype
- sh = [M00.shape[0], r, c]
- M_ret = np.empty(sh, dtype=dt)
- for irow in range(r):
- for icol in range(c):
- M_ret[:, irow, icol] = np.asarray(M[irow][icol])
- return M_ret
-
-
-def _extract_submatrices(M, block_indices, block_size, axis):
- """
- Extract selected blocks of a matrices *M* depending on parameters
- *block_indices* and *block_size*.
-
- Returns the array of extracted matrices *Mres* so that ::
-
- M_res[..., ir, :] = M[(block_indices*block_size+ir), :]
- """
- assert block_indices.ndim == 1
- assert axis in [0, 1]
-
- r, c = M.shape
- if axis == 0:
- sh = [block_indices.shape[0], block_size, c]
- else: # 1
- sh = [block_indices.shape[0], r, block_size]
-
- dt = M.dtype
- M_res = np.empty(sh, dtype=dt)
- if axis == 0:
- for ir in range(block_size):
- M_res[:, ir, :] = M[(block_indices*block_size+ir), :]
- else: # 1
- for ic in range(block_size):
- M_res[:, :, ic] = M[:, (block_indices*block_size+ic)]
-
- return M_res
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/_triinterpolate.pyi b/contrib/python/matplotlib/py3/matplotlib/tri/_triinterpolate.pyi
deleted file mode 100644
index 8a56b22acd..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/_triinterpolate.pyi
+++ /dev/null
@@ -1,30 +0,0 @@
-from matplotlib.tri import Triangulation, TriFinder
-
-from typing import Literal
-import numpy as np
-from numpy.typing import ArrayLike
-
-class TriInterpolator:
- def __init__(
- self,
- triangulation: Triangulation,
- z: ArrayLike,
- trifinder: TriFinder | None = ...,
- ) -> None: ...
- # __call__ and gradient are not actually implemented by the ABC, but are specified as required
- def __call__(self, x: ArrayLike, y: ArrayLike) -> np.ma.MaskedArray: ...
- def gradient(
- self, x: ArrayLike, y: ArrayLike
- ) -> tuple[np.ma.MaskedArray, np.ma.MaskedArray]: ...
-
-class LinearTriInterpolator(TriInterpolator): ...
-
-class CubicTriInterpolator(TriInterpolator):
- def __init__(
- self,
- triangulation: Triangulation,
- z: ArrayLike,
- kind: Literal["min_E", "geom", "user"] = ...,
- trifinder: TriFinder | None = ...,
- dz: tuple[ArrayLike, ArrayLike] | None = ...,
- ) -> None: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/_tripcolor.py b/contrib/python/matplotlib/py3/matplotlib/tri/_tripcolor.py
deleted file mode 100644
index 1ac6c48a2d..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/_tripcolor.py
+++ /dev/null
@@ -1,149 +0,0 @@
-import numpy as np
-
-from matplotlib import _api
-from matplotlib.collections import PolyCollection, TriMesh
-from matplotlib.tri._triangulation import Triangulation
-
-
-def tripcolor(ax, *args, alpha=1.0, norm=None, cmap=None, vmin=None,
- vmax=None, shading='flat', facecolors=None, **kwargs):
- """
- Create a pseudocolor plot of an unstructured triangular grid.
-
- Call signatures::
-
- tripcolor(triangulation, c, *, ...)
- tripcolor(x, y, c, *, [triangles=triangles], [mask=mask], ...)
-
- The triangular grid can be specified either by passing a `.Triangulation`
- object as the first parameter, or by passing the points *x*, *y* and
- optionally the *triangles* and a *mask*. See `.Triangulation` for an
- explanation of these parameters.
-
- It is possible to pass the triangles positionally, i.e.
- ``tripcolor(x, y, triangles, c, ...)``. However, this is discouraged.
- For more clarity, pass *triangles* via keyword argument.
-
- If neither of *triangulation* or *triangles* are given, the triangulation
- is calculated on the fly. In this case, it does not make sense to provide
- colors at the triangle faces via *c* or *facecolors* because there are
- multiple possible triangulations for a group of points and you don't know
- which triangles will be constructed.
-
- Parameters
- ----------
- triangulation : `.Triangulation`
- An already created triangular grid.
- x, y, triangles, mask
- Parameters defining the triangular grid. See `.Triangulation`.
- This is mutually exclusive with specifying *triangulation*.
- c : array-like
- The color values, either for the points or for the triangles. Which one
- is automatically inferred from the length of *c*, i.e. does it match
- the number of points or the number of triangles. If there are the same
- number of points and triangles in the triangulation it is assumed that
- color values are defined at points; to force the use of color values at
- triangles use the keyword argument ``facecolors=c`` instead of just
- ``c``.
- This parameter is position-only.
- facecolors : array-like, optional
- Can be used alternatively to *c* to specify colors at the triangle
- faces. This parameter takes precedence over *c*.
- shading : {'flat', 'gouraud'}, default: 'flat'
- If 'flat' and the color values *c* are defined at points, the color
- values used for each triangle are from the mean c of the triangle's
- three points. If *shading* is 'gouraud' then color values must be
- defined at points.
- other_parameters
- All other parameters are the same as for `~.Axes.pcolor`.
- """
- _api.check_in_list(['flat', 'gouraud'], shading=shading)
-
- tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args, **kwargs)
-
- # Parse the color to be in one of (the other variable will be None):
- # - facecolors: if specified at the triangle faces
- # - point_colors: if specified at the points
- if facecolors is not None:
- if args:
- _api.warn_external(
- "Positional parameter c has no effect when the keyword "
- "facecolors is given")
- point_colors = None
- if len(facecolors) != len(tri.triangles):
- raise ValueError("The length of facecolors must match the number "
- "of triangles")
- else:
- # Color from positional parameter c
- if not args:
- raise TypeError(
- "tripcolor() missing 1 required positional argument: 'c'; or "
- "1 required keyword-only argument: 'facecolors'")
- elif len(args) > 1:
- raise TypeError(f"Unexpected positional parameters: {args[1:]!r}")
- c = np.asarray(args[0])
- if len(c) == len(tri.x):
- # having this before the len(tri.triangles) comparison gives
- # precedence to nodes if there are as many nodes as triangles
- point_colors = c
- facecolors = None
- elif len(c) == len(tri.triangles):
- point_colors = None
- facecolors = c
- else:
- raise ValueError('The length of c must match either the number '
- 'of points or the number of triangles')
-
- # Handling of linewidths, shading, edgecolors and antialiased as
- # in Axes.pcolor
- linewidths = (0.25,)
- if 'linewidth' in kwargs:
- kwargs['linewidths'] = kwargs.pop('linewidth')
- kwargs.setdefault('linewidths', linewidths)
-
- edgecolors = 'none'
- if 'edgecolor' in kwargs:
- kwargs['edgecolors'] = kwargs.pop('edgecolor')
- ec = kwargs.setdefault('edgecolors', edgecolors)
-
- if 'antialiased' in kwargs:
- kwargs['antialiaseds'] = kwargs.pop('antialiased')
- if 'antialiaseds' not in kwargs and ec.lower() == "none":
- kwargs['antialiaseds'] = False
-
- if shading == 'gouraud':
- if facecolors is not None:
- raise ValueError(
- "shading='gouraud' can only be used when the colors "
- "are specified at the points, not at the faces.")
- collection = TriMesh(tri, alpha=alpha, array=point_colors,
- cmap=cmap, norm=norm, **kwargs)
- else: # 'flat'
- # Vertices of triangles.
- maskedTris = tri.get_masked_triangles()
- verts = np.stack((tri.x[maskedTris], tri.y[maskedTris]), axis=-1)
-
- # Color values.
- if facecolors is None:
- # One color per triangle, the mean of the 3 vertex color values.
- colors = point_colors[maskedTris].mean(axis=1)
- elif tri.mask is not None:
- # Remove color values of masked triangles.
- colors = facecolors[~tri.mask]
- else:
- colors = facecolors
- collection = PolyCollection(verts, alpha=alpha, array=colors,
- cmap=cmap, norm=norm, **kwargs)
-
- collection._scale_norm(norm, vmin, vmax)
- ax.grid(False)
-
- minx = tri.x.min()
- maxx = tri.x.max()
- miny = tri.y.min()
- maxy = tri.y.max()
- corners = (minx, miny), (maxx, maxy)
- ax.update_datalim(corners)
- ax.autoscale_view()
- ax.add_collection(collection)
- return collection
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/_tripcolor.pyi b/contrib/python/matplotlib/py3/matplotlib/tri/_tripcolor.pyi
deleted file mode 100644
index 42acffcdc5..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/_tripcolor.pyi
+++ /dev/null
@@ -1,71 +0,0 @@
-from matplotlib.axes import Axes
-from matplotlib.collections import PolyCollection, TriMesh
-from matplotlib.colors import Normalize, Colormap
-from matplotlib.tri._triangulation import Triangulation
-
-from numpy.typing import ArrayLike
-
-from typing import overload, Literal
-
-@overload
-def tripcolor(
- ax: Axes,
- triangulation: Triangulation,
- c: ArrayLike = ...,
- *,
- alpha: float = ...,
- norm: str | Normalize | None = ...,
- cmap: str | Colormap | None = ...,
- vmin: float | None = ...,
- vmax: float | None = ...,
- shading: Literal["flat"] = ...,
- facecolors: ArrayLike | None = ...,
- **kwargs
-) -> PolyCollection: ...
-@overload
-def tripcolor(
- ax: Axes,
- x: ArrayLike,
- y: ArrayLike,
- c: ArrayLike = ...,
- *,
- alpha: float = ...,
- norm: str | Normalize | None = ...,
- cmap: str | Colormap | None = ...,
- vmin: float | None = ...,
- vmax: float | None = ...,
- shading: Literal["flat"] = ...,
- facecolors: ArrayLike | None = ...,
- **kwargs
-) -> PolyCollection: ...
-@overload
-def tripcolor(
- ax: Axes,
- triangulation: Triangulation,
- c: ArrayLike = ...,
- *,
- alpha: float = ...,
- norm: str | Normalize | None = ...,
- cmap: str | Colormap | None = ...,
- vmin: float | None = ...,
- vmax: float | None = ...,
- shading: Literal["gouraud"],
- facecolors: ArrayLike | None = ...,
- **kwargs
-) -> TriMesh: ...
-@overload
-def tripcolor(
- ax: Axes,
- x: ArrayLike,
- y: ArrayLike,
- c: ArrayLike = ...,
- *,
- alpha: float = ...,
- norm: str | Normalize | None = ...,
- cmap: str | Colormap | None = ...,
- vmin: float | None = ...,
- vmax: float | None = ...,
- shading: Literal["gouraud"],
- facecolors: ArrayLike | None = ...,
- **kwargs
-) -> TriMesh: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/_triplot.py b/contrib/python/matplotlib/py3/matplotlib/tri/_triplot.py
deleted file mode 100644
index 6168946b15..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/_triplot.py
+++ /dev/null
@@ -1,86 +0,0 @@
-import numpy as np
-from matplotlib.tri._triangulation import Triangulation
-import matplotlib.cbook as cbook
-import matplotlib.lines as mlines
-
-
-def triplot(ax, *args, **kwargs):
- """
- Draw an unstructured triangular grid as lines and/or markers.
-
- Call signatures::
-
- triplot(triangulation, ...)
- triplot(x, y, [triangles], *, [mask=mask], ...)
-
- The triangular grid can be specified either by passing a `.Triangulation`
- object as the first parameter, or by passing the points *x*, *y* and
- optionally the *triangles* and a *mask*. If neither of *triangulation* or
- *triangles* are given, the triangulation is calculated on the fly.
-
- Parameters
- ----------
- triangulation : `.Triangulation`
- An already created triangular grid.
- x, y, triangles, mask
- Parameters defining the triangular grid. See `.Triangulation`.
- This is mutually exclusive with specifying *triangulation*.
- other_parameters
- All other args and kwargs are forwarded to `~.Axes.plot`.
-
- Returns
- -------
- lines : `~matplotlib.lines.Line2D`
- The drawn triangles edges.
- markers : `~matplotlib.lines.Line2D`
- The drawn marker nodes.
- """
- import matplotlib.axes
-
- tri, args, kwargs = Triangulation.get_from_args_and_kwargs(*args, **kwargs)
- x, y, edges = (tri.x, tri.y, tri.edges)
-
- # Decode plot format string, e.g., 'ro-'
- fmt = args[0] if args else ""
- linestyle, marker, color = matplotlib.axes._base._process_plot_format(fmt)
-
- # Insert plot format string into a copy of kwargs (kwargs values prevail).
- kw = cbook.normalize_kwargs(kwargs, mlines.Line2D)
- for key, val in zip(('linestyle', 'marker', 'color'),
- (linestyle, marker, color)):
- if val is not None:
- kw.setdefault(key, val)
-
- # Draw lines without markers.
- # Note 1: If we drew markers here, most markers would be drawn more than
- # once as they belong to several edges.
- # Note 2: We insert nan values in the flattened edges arrays rather than
- # plotting directly (triang.x[edges].T, triang.y[edges].T)
- # as it considerably speeds-up code execution.
- linestyle = kw['linestyle']
- kw_lines = {
- **kw,
- 'marker': 'None', # No marker to draw.
- 'zorder': kw.get('zorder', 1), # Path default zorder is used.
- }
- if linestyle not in [None, 'None', '', ' ']:
- tri_lines_x = np.insert(x[edges], 2, np.nan, axis=1)
- tri_lines_y = np.insert(y[edges], 2, np.nan, axis=1)
- tri_lines = ax.plot(tri_lines_x.ravel(), tri_lines_y.ravel(),
- **kw_lines)
- else:
- tri_lines = ax.plot([], [], **kw_lines)
-
- # Draw markers separately.
- marker = kw['marker']
- kw_markers = {
- **kw,
- 'linestyle': 'None', # No line to draw.
- }
- kw_markers.pop('label', None)
- if marker not in [None, 'None', '', ' ']:
- tri_markers = ax.plot(x, y, **kw_markers)
- else:
- tri_markers = ax.plot([], [], **kw_markers)
-
- return tri_lines + tri_markers
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/_triplot.pyi b/contrib/python/matplotlib/py3/matplotlib/tri/_triplot.pyi
deleted file mode 100644
index 6224276afd..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/_triplot.pyi
+++ /dev/null
@@ -1,15 +0,0 @@
-from matplotlib.tri._triangulation import Triangulation
-from matplotlib.axes import Axes
-from matplotlib.lines import Line2D
-
-from typing import overload
-from numpy.typing import ArrayLike
-
-@overload
-def triplot(
- ax: Axes, triangulation: Triangulation, *args, **kwargs
-) -> tuple[Line2D, Line2D]: ...
-@overload
-def triplot(
- ax: Axes, x: ArrayLike, y: ArrayLike, triangles: ArrayLike = ..., *args, **kwargs
-) -> tuple[Line2D, Line2D]: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/_trirefine.py b/contrib/python/matplotlib/py3/matplotlib/tri/_trirefine.py
deleted file mode 100644
index 7f5110ab9e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/_trirefine.py
+++ /dev/null
@@ -1,307 +0,0 @@
-"""
-Mesh refinement for triangular grids.
-"""
-
-import numpy as np
-
-from matplotlib import _api
-from matplotlib.tri._triangulation import Triangulation
-import matplotlib.tri._triinterpolate
-
-
-class TriRefiner:
- """
- Abstract base class for classes implementing mesh refinement.
-
- A TriRefiner encapsulates a Triangulation object and provides tools for
- mesh refinement and interpolation.
-
- Derived classes must implement:
-
- - ``refine_triangulation(return_tri_index=False, **kwargs)`` , where
- the optional keyword arguments *kwargs* are defined in each
- TriRefiner concrete implementation, and which returns:
-
- - a refined triangulation,
- - optionally (depending on *return_tri_index*), for each
- point of the refined triangulation: the index of
- the initial triangulation triangle to which it belongs.
-
- - ``refine_field(z, triinterpolator=None, **kwargs)``, where:
-
- - *z* array of field values (to refine) defined at the base
- triangulation nodes,
- - *triinterpolator* is an optional `~matplotlib.tri.TriInterpolator`,
- - the other optional keyword arguments *kwargs* are defined in
- each TriRefiner concrete implementation;
-
- and which returns (as a tuple) a refined triangular mesh and the
- interpolated values of the field at the refined triangulation nodes.
- """
-
- def __init__(self, triangulation):
- _api.check_isinstance(Triangulation, triangulation=triangulation)
- self._triangulation = triangulation
-
-
-class UniformTriRefiner(TriRefiner):
- """
- Uniform mesh refinement by recursive subdivisions.
-
- Parameters
- ----------
- triangulation : `~matplotlib.tri.Triangulation`
- The encapsulated triangulation (to be refined)
- """
-# See Also
-# --------
-# :class:`~matplotlib.tri.CubicTriInterpolator` and
-# :class:`~matplotlib.tri.TriAnalyzer`.
-# """
- def __init__(self, triangulation):
- super().__init__(triangulation)
-
- def refine_triangulation(self, return_tri_index=False, subdiv=3):
- """
- Compute a uniformly refined triangulation *refi_triangulation* of
- the encapsulated :attr:`triangulation`.
-
- This function refines the encapsulated triangulation by splitting each
- father triangle into 4 child sub-triangles built on the edges midside
- nodes, recursing *subdiv* times. In the end, each triangle is hence
- divided into ``4**subdiv`` child triangles.
-
- Parameters
- ----------
- return_tri_index : bool, default: False
- Whether an index table indicating the father triangle index of each
- point is returned.
- subdiv : int, default: 3
- Recursion level for the subdivision.
- Each triangle is divided into ``4**subdiv`` child triangles;
- hence, the default results in 64 refined subtriangles for each
- triangle of the initial triangulation.
-
- Returns
- -------
- refi_triangulation : `~matplotlib.tri.Triangulation`
- The refined triangulation.
- found_index : int array
- Index of the initial triangulation containing triangle, for each
- point of *refi_triangulation*.
- Returned only if *return_tri_index* is set to True.
- """
- refi_triangulation = self._triangulation
- ntri = refi_triangulation.triangles.shape[0]
-
- # Computes the triangulation ancestors numbers in the reference
- # triangulation.
- ancestors = np.arange(ntri, dtype=np.int32)
- for _ in range(subdiv):
- refi_triangulation, ancestors = self._refine_triangulation_once(
- refi_triangulation, ancestors)
- refi_npts = refi_triangulation.x.shape[0]
- refi_triangles = refi_triangulation.triangles
-
- # Now we compute found_index table if needed
- if return_tri_index:
- # We have to initialize found_index with -1 because some nodes
- # may very well belong to no triangle at all, e.g., in case of
- # Delaunay Triangulation with DuplicatePointWarning.
- found_index = np.full(refi_npts, -1, dtype=np.int32)
- tri_mask = self._triangulation.mask
- if tri_mask is None:
- found_index[refi_triangles] = np.repeat(ancestors,
- 3).reshape(-1, 3)
- else:
- # There is a subtlety here: we want to avoid whenever possible
- # that refined points container is a masked triangle (which
- # would result in artifacts in plots).
- # So we impose the numbering from masked ancestors first,
- # then overwrite it with unmasked ancestor numbers.
- ancestor_mask = tri_mask[ancestors]
- found_index[refi_triangles[ancestor_mask, :]
- ] = np.repeat(ancestors[ancestor_mask],
- 3).reshape(-1, 3)
- found_index[refi_triangles[~ancestor_mask, :]
- ] = np.repeat(ancestors[~ancestor_mask],
- 3).reshape(-1, 3)
- return refi_triangulation, found_index
- else:
- return refi_triangulation
-
- def refine_field(self, z, triinterpolator=None, subdiv=3):
- """
- Refine a field defined on the encapsulated triangulation.
-
- Parameters
- ----------
- z : (npoints,) array-like
- Values of the field to refine, defined at the nodes of the
- encapsulated triangulation. (``n_points`` is the number of points
- in the initial triangulation)
- triinterpolator : `~matplotlib.tri.TriInterpolator`, optional
- Interpolator used for field interpolation. If not specified,
- a `~matplotlib.tri.CubicTriInterpolator` will be used.
- subdiv : int, default: 3
- Recursion level for the subdivision.
- Each triangle is divided into ``4**subdiv`` child triangles.
-
- Returns
- -------
- refi_tri : `~matplotlib.tri.Triangulation`
- The returned refined triangulation.
- refi_z : 1D array of length: *refi_tri* node count.
- The returned interpolated field (at *refi_tri* nodes).
- """
- if triinterpolator is None:
- interp = matplotlib.tri.CubicTriInterpolator(
- self._triangulation, z)
- else:
- _api.check_isinstance(matplotlib.tri.TriInterpolator,
- triinterpolator=triinterpolator)
- interp = triinterpolator
-
- refi_tri, found_index = self.refine_triangulation(
- subdiv=subdiv, return_tri_index=True)
- refi_z = interp._interpolate_multikeys(
- refi_tri.x, refi_tri.y, tri_index=found_index)[0]
- return refi_tri, refi_z
-
- @staticmethod
- def _refine_triangulation_once(triangulation, ancestors=None):
- """
- Refine a `.Triangulation` by splitting each triangle into 4
- child-masked_triangles built on the edges midside nodes.
-
- Masked triangles, if present, are also split, but their children
- returned masked.
-
- If *ancestors* is not provided, returns only a new triangulation:
- child_triangulation.
-
- If the array-like key table *ancestor* is given, it shall be of shape
- (ntri,) where ntri is the number of *triangulation* masked_triangles.
- In this case, the function returns
- (child_triangulation, child_ancestors)
- child_ancestors is defined so that the 4 child masked_triangles share
- the same index as their father: child_ancestors.shape = (4 * ntri,).
- """
-
- x = triangulation.x
- y = triangulation.y
-
- # According to tri.triangulation doc:
- # neighbors[i, j] is the triangle that is the neighbor
- # to the edge from point index masked_triangles[i, j] to point
- # index masked_triangles[i, (j+1)%3].
- neighbors = triangulation.neighbors
- triangles = triangulation.triangles
- npts = np.shape(x)[0]
- ntri = np.shape(triangles)[0]
- if ancestors is not None:
- ancestors = np.asarray(ancestors)
- if np.shape(ancestors) != (ntri,):
- raise ValueError(
- "Incompatible shapes provide for "
- "triangulation.masked_triangles and ancestors: "
- f"{np.shape(triangles)} and {np.shape(ancestors)}")
-
- # Initiating tables refi_x and refi_y of the refined triangulation
- # points
- # hint: each apex is shared by 2 masked_triangles except the borders.
- borders = np.sum(neighbors == -1)
- added_pts = (3*ntri + borders) // 2
- refi_npts = npts + added_pts
- refi_x = np.zeros(refi_npts)
- refi_y = np.zeros(refi_npts)
-
- # First part of refi_x, refi_y is just the initial points
- refi_x[:npts] = x
- refi_y[:npts] = y
-
- # Second part contains the edge midside nodes.
- # Each edge belongs to 1 triangle (if border edge) or is shared by 2
- # masked_triangles (interior edge).
- # We first build 2 * ntri arrays of edge starting nodes (edge_elems,
- # edge_apexes); we then extract only the masters to avoid overlaps.
- # The so-called 'master' is the triangle with biggest index
- # The 'slave' is the triangle with lower index
- # (can be -1 if border edge)
- # For slave and master we will identify the apex pointing to the edge
- # start
- edge_elems = np.tile(np.arange(ntri, dtype=np.int32), 3)
- edge_apexes = np.repeat(np.arange(3, dtype=np.int32), ntri)
- edge_neighbors = neighbors[edge_elems, edge_apexes]
- mask_masters = (edge_elems > edge_neighbors)
-
- # Identifying the "masters" and adding to refi_x, refi_y vec
- masters = edge_elems[mask_masters]
- apex_masters = edge_apexes[mask_masters]
- x_add = (x[triangles[masters, apex_masters]] +
- x[triangles[masters, (apex_masters+1) % 3]]) * 0.5
- y_add = (y[triangles[masters, apex_masters]] +
- y[triangles[masters, (apex_masters+1) % 3]]) * 0.5
- refi_x[npts:] = x_add
- refi_y[npts:] = y_add
-
- # Building the new masked_triangles; each old masked_triangles hosts
- # 4 new masked_triangles
- # there are 6 pts to identify per 'old' triangle, 3 new_pt_corner and
- # 3 new_pt_midside
- new_pt_corner = triangles
-
- # What is the index in refi_x, refi_y of point at middle of apex iapex
- # of elem ielem ?
- # If ielem is the apex master: simple count, given the way refi_x was
- # built.
- # If ielem is the apex slave: yet we do not know; but we will soon
- # using the neighbors table.
- new_pt_midside = np.empty([ntri, 3], dtype=np.int32)
- cum_sum = npts
- for imid in range(3):
- mask_st_loc = (imid == apex_masters)
- n_masters_loc = np.sum(mask_st_loc)
- elem_masters_loc = masters[mask_st_loc]
- new_pt_midside[:, imid][elem_masters_loc] = np.arange(
- n_masters_loc, dtype=np.int32) + cum_sum
- cum_sum += n_masters_loc
-
- # Now dealing with slave elems.
- # for each slave element we identify the master and then the inode
- # once slave_masters is identified, slave_masters_apex is such that:
- # neighbors[slaves_masters, slave_masters_apex] == slaves
- mask_slaves = np.logical_not(mask_masters)
- slaves = edge_elems[mask_slaves]
- slaves_masters = edge_neighbors[mask_slaves]
- diff_table = np.abs(neighbors[slaves_masters, :] -
- np.outer(slaves, np.ones(3, dtype=np.int32)))
- slave_masters_apex = np.argmin(diff_table, axis=1)
- slaves_apex = edge_apexes[mask_slaves]
- new_pt_midside[slaves, slaves_apex] = new_pt_midside[
- slaves_masters, slave_masters_apex]
-
- # Builds the 4 child masked_triangles
- child_triangles = np.empty([ntri*4, 3], dtype=np.int32)
- child_triangles[0::4, :] = np.vstack([
- new_pt_corner[:, 0], new_pt_midside[:, 0],
- new_pt_midside[:, 2]]).T
- child_triangles[1::4, :] = np.vstack([
- new_pt_corner[:, 1], new_pt_midside[:, 1],
- new_pt_midside[:, 0]]).T
- child_triangles[2::4, :] = np.vstack([
- new_pt_corner[:, 2], new_pt_midside[:, 2],
- new_pt_midside[:, 1]]).T
- child_triangles[3::4, :] = np.vstack([
- new_pt_midside[:, 0], new_pt_midside[:, 1],
- new_pt_midside[:, 2]]).T
- child_triangulation = Triangulation(refi_x, refi_y, child_triangles)
-
- # Builds the child mask
- if triangulation.mask is not None:
- child_triangulation.set_mask(np.repeat(triangulation.mask, 4))
-
- if ancestors is None:
- return child_triangulation
- else:
- return child_triangulation, np.repeat(ancestors, 4)
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/_trirefine.pyi b/contrib/python/matplotlib/py3/matplotlib/tri/_trirefine.pyi
deleted file mode 100644
index 7c60dc76e2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/_trirefine.pyi
+++ /dev/null
@@ -1,31 +0,0 @@
-from typing import Literal, overload
-
-import numpy as np
-from numpy.typing import ArrayLike
-
-from matplotlib.tri._triangulation import Triangulation
-from matplotlib.tri._triinterpolate import TriInterpolator
-
-class TriRefiner:
- def __init__(self, triangulation: Triangulation) -> None: ...
-
-class UniformTriRefiner(TriRefiner):
- def __init__(self, triangulation: Triangulation) -> None: ...
- @overload
- def refine_triangulation(
- self, *, return_tri_index: Literal[True], subdiv: int = ...
- ) -> tuple[Triangulation, np.ndarray]: ...
- @overload
- def refine_triangulation(
- self, return_tri_index: Literal[False] = ..., subdiv: int = ...
- ) -> Triangulation: ...
- @overload
- def refine_triangulation(
- self, return_tri_index: bool = ..., subdiv: int = ...
- ) -> tuple[Triangulation, np.ndarray] | Triangulation: ...
- def refine_field(
- self,
- z: ArrayLike,
- triinterpolator: TriInterpolator | None = ...,
- subdiv: int = ...,
- ) -> tuple[Triangulation, np.ndarray]: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/_tritools.py b/contrib/python/matplotlib/py3/matplotlib/tri/_tritools.py
deleted file mode 100644
index 9837309f7e..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/_tritools.py
+++ /dev/null
@@ -1,263 +0,0 @@
-"""
-Tools for triangular grids.
-"""
-
-import numpy as np
-
-from matplotlib import _api
-from matplotlib.tri import Triangulation
-
-
-class TriAnalyzer:
- """
- Define basic tools for triangular mesh analysis and improvement.
-
- A TriAnalyzer encapsulates a `.Triangulation` object and provides basic
- tools for mesh analysis and mesh improvement.
-
- Attributes
- ----------
- scale_factors
-
- Parameters
- ----------
- triangulation : `~matplotlib.tri.Triangulation`
- The encapsulated triangulation to analyze.
- """
-
- def __init__(self, triangulation):
- _api.check_isinstance(Triangulation, triangulation=triangulation)
- self._triangulation = triangulation
-
- @property
- def scale_factors(self):
- """
- Factors to rescale the triangulation into a unit square.
-
- Returns
- -------
- (float, float)
- Scaling factors (kx, ky) so that the triangulation
- ``[triangulation.x * kx, triangulation.y * ky]``
- fits exactly inside a unit square.
- """
- compressed_triangles = self._triangulation.get_masked_triangles()
- node_used = (np.bincount(np.ravel(compressed_triangles),
- minlength=self._triangulation.x.size) != 0)
- return (1 / np.ptp(self._triangulation.x[node_used]),
- 1 / np.ptp(self._triangulation.y[node_used]))
-
- def circle_ratios(self, rescale=True):
- """
- Return a measure of the triangulation triangles flatness.
-
- The ratio of the incircle radius over the circumcircle radius is a
- widely used indicator of a triangle flatness.
- It is always ``<= 0.5`` and ``== 0.5`` only for equilateral
- triangles. Circle ratios below 0.01 denote very flat triangles.
-
- To avoid unduly low values due to a difference of scale between the 2
- axis, the triangular mesh can first be rescaled to fit inside a unit
- square with `scale_factors` (Only if *rescale* is True, which is
- its default value).
-
- Parameters
- ----------
- rescale : bool, default: True
- If True, internally rescale (based on `scale_factors`), so that the
- (unmasked) triangles fit exactly inside a unit square mesh.
-
- Returns
- -------
- masked array
- Ratio of the incircle radius over the circumcircle radius, for
- each 'rescaled' triangle of the encapsulated triangulation.
- Values corresponding to masked triangles are masked out.
-
- """
- # Coords rescaling
- if rescale:
- (kx, ky) = self.scale_factors
- else:
- (kx, ky) = (1.0, 1.0)
- pts = np.vstack([self._triangulation.x*kx,
- self._triangulation.y*ky]).T
- tri_pts = pts[self._triangulation.triangles]
- # Computes the 3 side lengths
- a = tri_pts[:, 1, :] - tri_pts[:, 0, :]
- b = tri_pts[:, 2, :] - tri_pts[:, 1, :]
- c = tri_pts[:, 0, :] - tri_pts[:, 2, :]
- a = np.hypot(a[:, 0], a[:, 1])
- b = np.hypot(b[:, 0], b[:, 1])
- c = np.hypot(c[:, 0], c[:, 1])
- # circumcircle and incircle radii
- s = (a+b+c)*0.5
- prod = s*(a+b-s)*(a+c-s)*(b+c-s)
- # We have to deal with flat triangles with infinite circum_radius
- bool_flat = (prod == 0.)
- if np.any(bool_flat):
- # Pathologic flow
- ntri = tri_pts.shape[0]
- circum_radius = np.empty(ntri, dtype=np.float64)
- circum_radius[bool_flat] = np.inf
- abc = a*b*c
- circum_radius[~bool_flat] = abc[~bool_flat] / (
- 4.0*np.sqrt(prod[~bool_flat]))
- else:
- # Normal optimized flow
- circum_radius = (a*b*c) / (4.0*np.sqrt(prod))
- in_radius = (a*b*c) / (4.0*circum_radius*s)
- circle_ratio = in_radius/circum_radius
- mask = self._triangulation.mask
- if mask is None:
- return circle_ratio
- else:
- return np.ma.array(circle_ratio, mask=mask)
-
- def get_flat_tri_mask(self, min_circle_ratio=0.01, rescale=True):
- """
- Eliminate excessively flat border triangles from the triangulation.
-
- Returns a mask *new_mask* which allows to clean the encapsulated
- triangulation from its border-located flat triangles
- (according to their :meth:`circle_ratios`).
- This mask is meant to be subsequently applied to the triangulation
- using `.Triangulation.set_mask`.
- *new_mask* is an extension of the initial triangulation mask
- in the sense that an initially masked triangle will remain masked.
-
- The *new_mask* array is computed recursively; at each step flat
- triangles are removed only if they share a side with the current mesh
- border. Thus, no new holes in the triangulated domain will be created.
-
- Parameters
- ----------
- min_circle_ratio : float, default: 0.01
- Border triangles with incircle/circumcircle radii ratio r/R will
- be removed if r/R < *min_circle_ratio*.
- rescale : bool, default: True
- If True, first, internally rescale (based on `scale_factors`) so
- that the (unmasked) triangles fit exactly inside a unit square
- mesh. This rescaling accounts for the difference of scale which
- might exist between the 2 axis.
-
- Returns
- -------
- array of bool
- Mask to apply to encapsulated triangulation.
- All the initially masked triangles remain masked in the
- *new_mask*.
-
- Notes
- -----
- The rationale behind this function is that a Delaunay
- triangulation - of an unstructured set of points - sometimes contains
- almost flat triangles at its border, leading to artifacts in plots
- (especially for high-resolution contouring).
- Masked with computed *new_mask*, the encapsulated
- triangulation would contain no more unmasked border triangles
- with a circle ratio below *min_circle_ratio*, thus improving the
- mesh quality for subsequent plots or interpolation.
- """
- # Recursively computes the mask_current_borders, true if a triangle is
- # at the border of the mesh OR touching the border through a chain of
- # invalid aspect ratio masked_triangles.
- ntri = self._triangulation.triangles.shape[0]
- mask_bad_ratio = self.circle_ratios(rescale) < min_circle_ratio
-
- current_mask = self._triangulation.mask
- if current_mask is None:
- current_mask = np.zeros(ntri, dtype=bool)
- valid_neighbors = np.copy(self._triangulation.neighbors)
- renum_neighbors = np.arange(ntri, dtype=np.int32)
- nadd = -1
- while nadd != 0:
- # The active wavefront is the triangles from the border (unmasked
- # but with a least 1 neighbor equal to -1
- wavefront = (np.min(valid_neighbors, axis=1) == -1) & ~current_mask
- # The element from the active wavefront will be masked if their
- # circle ratio is bad.
- added_mask = wavefront & mask_bad_ratio
- current_mask = added_mask | current_mask
- nadd = np.sum(added_mask)
-
- # now we have to update the tables valid_neighbors
- valid_neighbors[added_mask, :] = -1
- renum_neighbors[added_mask] = -1
- valid_neighbors = np.where(valid_neighbors == -1, -1,
- renum_neighbors[valid_neighbors])
-
- return np.ma.filled(current_mask, True)
-
- def _get_compressed_triangulation(self):
- """
- Compress (if masked) the encapsulated triangulation.
-
- Returns minimal-length triangles array (*compressed_triangles*) and
- coordinates arrays (*compressed_x*, *compressed_y*) that can still
- describe the unmasked triangles of the encapsulated triangulation.
-
- Returns
- -------
- compressed_triangles : array-like
- the returned compressed triangulation triangles
- compressed_x : array-like
- the returned compressed triangulation 1st coordinate
- compressed_y : array-like
- the returned compressed triangulation 2nd coordinate
- tri_renum : int array
- renumbering table to translate the triangle numbers from the
- encapsulated triangulation into the new (compressed) renumbering.
- -1 for masked triangles (deleted from *compressed_triangles*).
- node_renum : int array
- renumbering table to translate the point numbers from the
- encapsulated triangulation into the new (compressed) renumbering.
- -1 for unused points (i.e. those deleted from *compressed_x* and
- *compressed_y*).
-
- """
- # Valid triangles and renumbering
- tri_mask = self._triangulation.mask
- compressed_triangles = self._triangulation.get_masked_triangles()
- ntri = self._triangulation.triangles.shape[0]
- if tri_mask is not None:
- tri_renum = self._total_to_compress_renum(~tri_mask)
- else:
- tri_renum = np.arange(ntri, dtype=np.int32)
-
- # Valid nodes and renumbering
- valid_node = (np.bincount(np.ravel(compressed_triangles),
- minlength=self._triangulation.x.size) != 0)
- compressed_x = self._triangulation.x[valid_node]
- compressed_y = self._triangulation.y[valid_node]
- node_renum = self._total_to_compress_renum(valid_node)
-
- # Now renumbering the valid triangles nodes
- compressed_triangles = node_renum[compressed_triangles]
-
- return (compressed_triangles, compressed_x, compressed_y, tri_renum,
- node_renum)
-
- @staticmethod
- def _total_to_compress_renum(valid):
- """
- Parameters
- ----------
- valid : 1D bool array
- Validity mask.
-
- Returns
- -------
- int array
- Array so that (`valid_array` being a compressed array
- based on a `masked_array` with mask ~*valid*):
-
- - For all i with valid[i] = True:
- valid_array[renum[i]] = masked_array[i]
- - For all i with valid[i] = False:
- renum[i] = -1 (invalid value)
- """
- renum = np.full(np.size(valid), -1, dtype=np.int32)
- n_valid = np.sum(valid)
- renum[valid] = np.arange(n_valid, dtype=np.int32)
- return renum
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/_tritools.pyi b/contrib/python/matplotlib/py3/matplotlib/tri/_tritools.pyi
deleted file mode 100644
index 9b5e1bec4b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/_tritools.pyi
+++ /dev/null
@@ -1,12 +0,0 @@
-from matplotlib.tri import Triangulation
-
-import numpy as np
-
-class TriAnalyzer:
- def __init__(self, triangulation: Triangulation) -> None: ...
- @property
- def scale_factors(self) -> tuple[float, float]: ...
- def circle_ratios(self, rescale: bool = ...) -> np.ndarray: ...
- def get_flat_tri_mask(
- self, min_circle_ratio: float = ..., rescale: bool = ...
- ) -> np.ndarray: ...
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/triangulation.py b/contrib/python/matplotlib/py3/matplotlib/tri/triangulation.py
deleted file mode 100644
index c48b09b280..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/triangulation.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from ._triangulation import * # noqa: F401, F403
-from matplotlib import _api
-
-
-_api.warn_deprecated(
- "3.7",
- message=f"Importing {__name__} was deprecated in Matplotlib 3.7 and will "
- f"be removed two minor releases later. All functionality is "
- f"available via the top-level module matplotlib.tri")
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/tricontour.py b/contrib/python/matplotlib/py3/matplotlib/tri/tricontour.py
deleted file mode 100644
index 37406451d3..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/tricontour.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from ._tricontour import * # noqa: F401, F403
-from matplotlib import _api
-
-
-_api.warn_deprecated(
- "3.7",
- message=f"Importing {__name__} was deprecated in Matplotlib 3.7 and will "
- f"be removed two minor releases later. All functionality is "
- f"available via the top-level module matplotlib.tri")
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/trifinder.py b/contrib/python/matplotlib/py3/matplotlib/tri/trifinder.py
deleted file mode 100644
index 1aff5c9d32..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/trifinder.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from ._trifinder import * # noqa: F401, F403
-from matplotlib import _api
-
-
-_api.warn_deprecated(
- "3.7",
- message=f"Importing {__name__} was deprecated in Matplotlib 3.7 and will "
- f"be removed two minor releases later. All functionality is "
- f"available via the top-level module matplotlib.tri")
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/triinterpolate.py b/contrib/python/matplotlib/py3/matplotlib/tri/triinterpolate.py
deleted file mode 100644
index 3112bd38e6..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/triinterpolate.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from ._triinterpolate import * # noqa: F401, F403
-from matplotlib import _api
-
-
-_api.warn_deprecated(
- "3.7",
- message=f"Importing {__name__} was deprecated in Matplotlib 3.7 and will "
- f"be removed two minor releases later. All functionality is "
- f"available via the top-level module matplotlib.tri")
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/tripcolor.py b/contrib/python/matplotlib/py3/matplotlib/tri/tripcolor.py
deleted file mode 100644
index 0da8789181..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/tripcolor.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from ._tripcolor import * # noqa: F401, F403
-from matplotlib import _api
-
-
-_api.warn_deprecated(
- "3.7",
- message=f"Importing {__name__} was deprecated in Matplotlib 3.7 and will "
- f"be removed two minor releases later. All functionality is "
- f"available via the top-level module matplotlib.tri")
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/triplot.py b/contrib/python/matplotlib/py3/matplotlib/tri/triplot.py
deleted file mode 100644
index 7c012b1a59..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/triplot.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from ._triplot import * # noqa: F401, F403
-from matplotlib import _api
-
-
-_api.warn_deprecated(
- "3.7",
- message=f"Importing {__name__} was deprecated in Matplotlib 3.7 and will "
- f"be removed two minor releases later. All functionality is "
- f"available via the top-level module matplotlib.tri")
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/trirefine.py b/contrib/python/matplotlib/py3/matplotlib/tri/trirefine.py
deleted file mode 100644
index 6f22f9e8d2..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/trirefine.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from ._trirefine import * # noqa: F401, F403
-from matplotlib import _api
-
-
-_api.warn_deprecated(
- "3.7",
- message=f"Importing {__name__} was deprecated in Matplotlib 3.7 and will "
- f"be removed two minor releases later. All functionality is "
- f"available via the top-level module matplotlib.tri")
diff --git a/contrib/python/matplotlib/py3/matplotlib/tri/tritools.py b/contrib/python/matplotlib/py3/matplotlib/tri/tritools.py
deleted file mode 100644
index 9c6839ca20..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/tri/tritools.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from ._tritools import * # noqa: F401, F403
-from matplotlib import _api
-
-
-_api.warn_deprecated(
- "3.7",
- message=f"Importing {__name__} was deprecated in Matplotlib 3.7 and will "
- f"be removed two minor releases later. All functionality is "
- f"available via the top-level module matplotlib.tri")
diff --git a/contrib/python/matplotlib/py3/matplotlib/typing.py b/contrib/python/matplotlib/py3/matplotlib/typing.py
deleted file mode 100644
index 02059be94b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/typing.py
+++ /dev/null
@@ -1,60 +0,0 @@
-"""
-Typing support for Matplotlib
-
-This module contains Type aliases which are useful for Matplotlib and potentially
-downstream libraries.
-
-.. admonition:: Provisional status of typing
-
- The ``typing`` module and type stub files are considered provisional and may change
- at any time without a deprecation period.
-"""
-from collections.abc import Hashable, Sequence
-import pathlib
-from typing import Any, Literal, TypeVar, Union
-
-from . import path
-from ._enums import JoinStyle, CapStyle
-from .markers import MarkerStyle
-
-# The following are type aliases. Once python 3.9 is dropped, they should be annotated
-# using ``typing.TypeAlias`` and Unions should be converted to using ``|`` syntax.
-
-RGBColorType = Union[tuple[float, float, float], str]
-RGBAColorType = Union[
- str, # "none" or "#RRGGBBAA"/"#RGBA" hex strings
- tuple[float, float, float, float],
- # 2 tuple (color, alpha) representations, not infinitely recursive
- # RGBColorType includes the (str, float) tuple, even for RGBA strings
- tuple[RGBColorType, float],
- # (4-tuple, float) is odd, but accepted as the outer float overriding A of 4-tuple
- tuple[tuple[float, float, float, float], float],
-]
-
-ColorType = Union[RGBColorType, RGBAColorType]
-
-RGBColourType = RGBColorType
-RGBAColourType = RGBAColorType
-ColourType = ColorType
-
-LineStyleType = Union[str, tuple[float, Sequence[float]]]
-DrawStyleType = Literal["default", "steps", "steps-pre", "steps-mid", "steps-post"]
-MarkEveryType = Union[
- None, int, tuple[int, int], slice, list[int], float, tuple[float, float], list[bool]
-]
-
-MarkerType = Union[str, path.Path, MarkerStyle]
-FillStyleType = Literal["full", "left", "right", "bottom", "top", "none"]
-JoinStyleType = Union[JoinStyle, Literal["miter", "round", "bevel"]]
-CapStyleType = Union[CapStyle, Literal["butt", "projecting", "round"]]
-
-RcStyleType = Union[
- str,
- dict[str, Any],
- pathlib.Path,
- Sequence[Union[str, pathlib.Path, dict[str, Any]]],
-]
-
-_HT = TypeVar("_HT", bound=Hashable)
-HashableList = list[Union[_HT, "HashableList[_HT]"]]
-"""A nested list of Hashable values."""
diff --git a/contrib/python/matplotlib/py3/matplotlib/units.py b/contrib/python/matplotlib/py3/matplotlib/units.py
deleted file mode 100644
index e3480f228b..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/units.py
+++ /dev/null
@@ -1,195 +0,0 @@
-"""
-The classes here provide support for using custom classes with
-Matplotlib, e.g., those that do not expose the array interface but know
-how to convert themselves to arrays. It also supports classes with
-units and units conversion. Use cases include converters for custom
-objects, e.g., a list of datetime objects, as well as for objects that
-are unit aware. We don't assume any particular units implementation;
-rather a units implementation must register with the Registry converter
-dictionary and provide a `ConversionInterface`. For example,
-here is a complete implementation which supports plotting with native
-datetime objects::
-
- import matplotlib.units as units
- import matplotlib.dates as dates
- import matplotlib.ticker as ticker
- import datetime
-
- class DateConverter(units.ConversionInterface):
-
- @staticmethod
- def convert(value, unit, axis):
- "Convert a datetime value to a scalar or array."
- return dates.date2num(value)
-
- @staticmethod
- def axisinfo(unit, axis):
- "Return major and minor tick locators and formatters."
- if unit != 'date':
- return None
- majloc = dates.AutoDateLocator()
- majfmt = dates.AutoDateFormatter(majloc)
- return units.AxisInfo(majloc=majloc, majfmt=majfmt, label='date')
-
- @staticmethod
- def default_units(x, axis):
- "Return the default unit for x or None."
- return 'date'
-
- # Finally we register our object type with the Matplotlib units registry.
- units.registry[datetime.date] = DateConverter()
-"""
-
-from decimal import Decimal
-from numbers import Number
-
-import numpy as np
-from numpy import ma
-
-from matplotlib import cbook
-
-
-class ConversionError(TypeError):
- pass
-
-
-def _is_natively_supported(x):
- """
- Return whether *x* is of a type that Matplotlib natively supports or an
- array of objects of such types.
- """
- # Matplotlib natively supports all number types except Decimal.
- if np.iterable(x):
- # Assume lists are homogeneous as other functions in unit system.
- for thisx in x:
- if thisx is ma.masked:
- continue
- return isinstance(thisx, Number) and not isinstance(thisx, Decimal)
- else:
- return isinstance(x, Number) and not isinstance(x, Decimal)
-
-
-class AxisInfo:
- """
- Information to support default axis labeling, tick labeling, and limits.
-
- An instance of this class must be returned by
- `ConversionInterface.axisinfo`.
- """
- def __init__(self, majloc=None, minloc=None,
- majfmt=None, minfmt=None, label=None,
- default_limits=None):
- """
- Parameters
- ----------
- majloc, minloc : Locator, optional
- Tick locators for the major and minor ticks.
- majfmt, minfmt : Formatter, optional
- Tick formatters for the major and minor ticks.
- label : str, optional
- The default axis label.
- default_limits : optional
- The default min and max limits of the axis if no data has
- been plotted.
-
- Notes
- -----
- If any of the above are ``None``, the axis will simply use the
- default value.
- """
- self.majloc = majloc
- self.minloc = minloc
- self.majfmt = majfmt
- self.minfmt = minfmt
- self.label = label
- self.default_limits = default_limits
-
-
-class ConversionInterface:
- """
- The minimal interface for a converter to take custom data types (or
- sequences) and convert them to values Matplotlib can use.
- """
-
- @staticmethod
- def axisinfo(unit, axis):
- """Return an `.AxisInfo` for the axis with the specified units."""
- return None
-
- @staticmethod
- def default_units(x, axis):
- """Return the default unit for *x* or ``None`` for the given axis."""
- return None
-
- @staticmethod
- def convert(obj, unit, axis):
- """
- Convert *obj* using *unit* for the specified *axis*.
-
- If *obj* is a sequence, return the converted sequence. The output must
- be a sequence of scalars that can be used by the numpy array layer.
- """
- return obj
-
-
-class DecimalConverter(ConversionInterface):
- """Converter for decimal.Decimal data to float."""
-
- @staticmethod
- def convert(value, unit, axis):
- """
- Convert Decimals to floats.
-
- The *unit* and *axis* arguments are not used.
-
- Parameters
- ----------
- value : decimal.Decimal or iterable
- Decimal or list of Decimal need to be converted
- """
- if isinstance(value, Decimal):
- return float(value)
- # value is Iterable[Decimal]
- elif isinstance(value, ma.MaskedArray):
- return ma.asarray(value, dtype=float)
- else:
- return np.asarray(value, dtype=float)
-
- # axisinfo and default_units can be inherited as Decimals are Numbers.
-
-
-class Registry(dict):
- """Register types with conversion interface."""
-
- def get_converter(self, x):
- """Get the converter interface instance for *x*, or None."""
- # Unpack in case of e.g. Pandas or xarray object
- x = cbook._unpack_to_numpy(x)
-
- if isinstance(x, np.ndarray):
- # In case x in a masked array, access the underlying data (only its
- # type matters). If x is a regular ndarray, getdata() just returns
- # the array itself.
- x = np.ma.getdata(x).ravel()
- # If there are no elements in x, infer the units from its dtype
- if not x.size:
- return self.get_converter(np.array([0], dtype=x.dtype))
- for cls in type(x).__mro__: # Look up in the cache.
- try:
- return self[cls]
- except KeyError:
- pass
- try: # If cache lookup fails, look up based on first element...
- first = cbook._safe_first_finite(x)
- except (TypeError, StopIteration):
- pass
- else:
- # ... and avoid infinite recursion for pathological iterables for
- # which indexing returns instances of the same iterable class.
- if type(first) is not type(x):
- return self.get_converter(first)
- return None
-
-
-registry = Registry()
-registry[Decimal] = DecimalConverter()
diff --git a/contrib/python/matplotlib/py3/matplotlib/widgets.py b/contrib/python/matplotlib/py3/matplotlib/widgets.py
deleted file mode 100644
index 0a31a9dd25..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/widgets.py
+++ /dev/null
@@ -1,4243 +0,0 @@
-"""
-GUI neutral widgets
-===================
-
-Widgets that are designed to work for any of the GUI backends.
-All of these widgets require you to predefine an `~.axes.Axes`
-instance and pass that as the first parameter. Matplotlib doesn't try to
-be too smart with respect to layout -- you will have to figure out how
-wide and tall you want your Axes to be to accommodate your widget.
-"""
-
-from contextlib import ExitStack
-import copy
-import itertools
-from numbers import Integral, Number
-
-from cycler import cycler
-import numpy as np
-
-import matplotlib as mpl
-from . import (_api, _docstring, backend_tools, cbook, collections, colors,
- text as mtext, ticker, transforms)
-from .lines import Line2D
-from .patches import Circle, Rectangle, Ellipse, Polygon
-from .transforms import TransformedPatchPath, Affine2D
-
-
-class LockDraw:
- """
- Some widgets, like the cursor, draw onto the canvas, and this is not
- desirable under all circumstances, like when the toolbar is in zoom-to-rect
- mode and drawing a rectangle. To avoid this, a widget can acquire a
- canvas' lock with ``canvas.widgetlock(widget)`` before drawing on the
- canvas; this will prevent other widgets from doing so at the same time (if
- they also try to acquire the lock first).
- """
-
- def __init__(self):
- self._owner = None
-
- def __call__(self, o):
- """Reserve the lock for *o*."""
- if not self.available(o):
- raise ValueError('already locked')
- self._owner = o
-
- def release(self, o):
- """Release the lock from *o*."""
- if not self.available(o):
- raise ValueError('you do not own this lock')
- self._owner = None
-
- def available(self, o):
- """Return whether drawing is available to *o*."""
- return not self.locked() or self.isowner(o)
-
- def isowner(self, o):
- """Return whether *o* owns this lock."""
- return self._owner is o
-
- def locked(self):
- """Return whether the lock is currently held by an owner."""
- return self._owner is not None
-
-
-class Widget:
- """
- Abstract base class for GUI neutral widgets.
- """
- drawon = True
- eventson = True
- _active = True
-
- def set_active(self, active):
- """Set whether the widget is active."""
- self._active = active
-
- def get_active(self):
- """Get whether the widget is active."""
- return self._active
-
- # set_active is overridden by SelectorWidgets.
- active = property(get_active, set_active, doc="Is the widget active?")
-
- def ignore(self, event):
- """
- Return whether *event* should be ignored.
-
- This method should be called at the beginning of any event callback.
- """
- return not self.active
-
- def _changed_canvas(self):
- """
- Someone has switched the canvas on us!
-
- This happens if `savefig` needs to save to a format the previous
- backend did not support (e.g. saving a figure using an Agg based
- backend saved to a vector format).
-
- Returns
- -------
- bool
- True if the canvas has been changed.
-
- """
- return self.canvas is not self.ax.figure.canvas
-
-
-class AxesWidget(Widget):
- """
- Widget connected to a single `~matplotlib.axes.Axes`.
-
- To guarantee that the widget remains responsive and not garbage-collected,
- a reference to the object should be maintained by the user.
-
- This is necessary because the callback registry
- maintains only weak-refs to the functions, which are member
- functions of the widget. If there are no references to the widget
- object it may be garbage collected which will disconnect the callbacks.
-
- Attributes
- ----------
- ax : `~matplotlib.axes.Axes`
- The parent Axes for the widget.
- canvas : `~matplotlib.backend_bases.FigureCanvasBase`
- The parent figure canvas for the widget.
- active : bool
- If False, the widget does not respond to events.
- """
-
- def __init__(self, ax):
- self.ax = ax
- self.canvas = ax.figure.canvas
- self._cids = []
-
- def connect_event(self, event, callback):
- """
- Connect a callback function with an event.
-
- This should be used in lieu of ``figure.canvas.mpl_connect`` since this
- function stores callback ids for later clean up.
- """
- cid = self.canvas.mpl_connect(event, callback)
- self._cids.append(cid)
-
- def disconnect_events(self):
- """Disconnect all events created by this widget."""
- for c in self._cids:
- self.canvas.mpl_disconnect(c)
-
- def _get_data_coords(self, event):
- """Return *event*'s data coordinates in this widget's Axes."""
- # This method handles the possibility that event.inaxes != self.ax (which may
- # occur if multiple axes are overlaid), in which case event.xdata/.ydata will
- # be wrong. Note that we still special-case the common case where
- # event.inaxes == self.ax and avoid re-running the inverse data transform,
- # because that can introduce floating point errors for synthetic events.
- return ((event.xdata, event.ydata) if event.inaxes is self.ax
- else self.ax.transData.inverted().transform((event.x, event.y)))
-
-
-class Button(AxesWidget):
- """
- A GUI neutral button.
-
- For the button to remain responsive you must keep a reference to it.
- Call `.on_clicked` to connect to the button.
-
- Attributes
- ----------
- ax
- The `~.axes.Axes` the button renders into.
- label
- A `.Text` instance.
- color
- The color of the button when not hovering.
- hovercolor
- The color of the button when hovering.
- """
-
- def __init__(self, ax, label, image=None,
- color='0.85', hovercolor='0.95', *, useblit=True):
- """
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The `~.axes.Axes` instance the button will be placed into.
- label : str
- The button text.
- image : array-like or PIL Image
- The image to place in the button, if not *None*. The parameter is
- directly forwarded to `~.axes.Axes.imshow`.
- color : color
- The color of the button when not activated.
- hovercolor : color
- The color of the button when the mouse is over it.
- useblit : bool, default: True
- Use blitting for faster drawing if supported by the backend.
- See the tutorial :ref:`blitting` for details.
-
- .. versionadded:: 3.7
- """
- super().__init__(ax)
-
- if image is not None:
- ax.imshow(image)
- self.label = ax.text(0.5, 0.5, label,
- verticalalignment='center',
- horizontalalignment='center',
- transform=ax.transAxes)
-
- self._useblit = useblit and self.canvas.supports_blit
-
- self._observers = cbook.CallbackRegistry(signals=["clicked"])
-
- self.connect_event('button_press_event', self._click)
- self.connect_event('button_release_event', self._release)
- self.connect_event('motion_notify_event', self._motion)
- ax.set_navigate(False)
- ax.set_facecolor(color)
- ax.set_xticks([])
- ax.set_yticks([])
- self.color = color
- self.hovercolor = hovercolor
-
- def _click(self, event):
- if not self.eventson or self.ignore(event) or not self.ax.contains(event)[0]:
- return
- if event.canvas.mouse_grabber != self.ax:
- event.canvas.grab_mouse(self.ax)
-
- def _release(self, event):
- if self.ignore(event) or event.canvas.mouse_grabber != self.ax:
- return
- event.canvas.release_mouse(self.ax)
- if self.eventson and self.ax.contains(event)[0]:
- self._observers.process('clicked', event)
-
- def _motion(self, event):
- if self.ignore(event):
- return
- c = self.hovercolor if self.ax.contains(event)[0] else self.color
- if not colors.same_color(c, self.ax.get_facecolor()):
- self.ax.set_facecolor(c)
- if self.drawon:
- if self._useblit:
- self.ax.draw_artist(self.ax)
- self.canvas.blit(self.ax.bbox)
- else:
- self.canvas.draw()
-
- def on_clicked(self, func):
- """
- Connect the callback function *func* to button click events.
-
- Returns a connection id, which can be used to disconnect the callback.
- """
- return self._observers.connect('clicked', lambda event: func(event))
-
- def disconnect(self, cid):
- """Remove the callback function with connection id *cid*."""
- self._observers.disconnect(cid)
-
-
-class SliderBase(AxesWidget):
- """
- The base class for constructing Slider widgets. Not intended for direct
- usage.
-
- For the slider to remain responsive you must maintain a reference to it.
- """
- def __init__(self, ax, orientation, closedmin, closedmax,
- valmin, valmax, valfmt, dragging, valstep):
- if ax.name == '3d':
- raise ValueError('Sliders cannot be added to 3D Axes')
-
- super().__init__(ax)
- _api.check_in_list(['horizontal', 'vertical'], orientation=orientation)
-
- self.orientation = orientation
- self.closedmin = closedmin
- self.closedmax = closedmax
- self.valmin = valmin
- self.valmax = valmax
- self.valstep = valstep
- self.drag_active = False
- self.valfmt = valfmt
-
- if orientation == "vertical":
- ax.set_ylim((valmin, valmax))
- axis = ax.yaxis
- else:
- ax.set_xlim((valmin, valmax))
- axis = ax.xaxis
-
- self._fmt = axis.get_major_formatter()
- if not isinstance(self._fmt, ticker.ScalarFormatter):
- self._fmt = ticker.ScalarFormatter()
- self._fmt.set_axis(axis)
- self._fmt.set_useOffset(False) # No additive offset.
- self._fmt.set_useMathText(True) # x sign before multiplicative offset.
-
- ax.set_axis_off()
- ax.set_navigate(False)
-
- self.connect_event("button_press_event", self._update)
- self.connect_event("button_release_event", self._update)
- if dragging:
- self.connect_event("motion_notify_event", self._update)
- self._observers = cbook.CallbackRegistry(signals=["changed"])
-
- def _stepped_value(self, val):
- """Return *val* coerced to closest number in the ``valstep`` grid."""
- if isinstance(self.valstep, Number):
- val = (self.valmin
- + round((val - self.valmin) / self.valstep) * self.valstep)
- elif self.valstep is not None:
- valstep = np.asanyarray(self.valstep)
- if valstep.ndim != 1:
- raise ValueError(
- f"valstep must have 1 dimension but has {valstep.ndim}"
- )
- val = valstep[np.argmin(np.abs(valstep - val))]
- return val
-
- def disconnect(self, cid):
- """
- Remove the observer with connection id *cid*.
-
- Parameters
- ----------
- cid : int
- Connection id of the observer to be removed.
- """
- self._observers.disconnect(cid)
-
- def reset(self):
- """Reset the slider to the initial value."""
- if np.any(self.val != self.valinit):
- self.set_val(self.valinit)
-
-
-class Slider(SliderBase):
- """
- A slider representing a floating point range.
-
- Create a slider from *valmin* to *valmax* in Axes *ax*. For the slider to
- remain responsive you must maintain a reference to it. Call
- :meth:`on_changed` to connect to the slider event.
-
- Attributes
- ----------
- val : float
- Slider value.
- """
-
- @_api.make_keyword_only("3.7", name="valinit")
- def __init__(self, ax, label, valmin, valmax, valinit=0.5, valfmt=None,
- closedmin=True, closedmax=True, slidermin=None,
- slidermax=None, dragging=True, valstep=None,
- orientation='horizontal', *, initcolor='r',
- track_color='lightgrey', handle_style=None, **kwargs):
- """
- Parameters
- ----------
- ax : Axes
- The Axes to put the slider in.
-
- label : str
- Slider label.
-
- valmin : float
- The minimum value of the slider.
-
- valmax : float
- The maximum value of the slider.
-
- valinit : float, default: 0.5
- The slider initial position.
-
- valfmt : str, default: None
- %-format string used to format the slider value. If None, a
- `.ScalarFormatter` is used instead.
-
- closedmin : bool, default: True
- Whether the slider interval is closed on the bottom.
-
- closedmax : bool, default: True
- Whether the slider interval is closed on the top.
-
- slidermin : Slider, default: None
- Do not allow the current slider to have a value less than
- the value of the Slider *slidermin*.
-
- slidermax : Slider, default: None
- Do not allow the current slider to have a value greater than
- the value of the Slider *slidermax*.
-
- dragging : bool, default: True
- If True the slider can be dragged by the mouse.
-
- valstep : float or array-like, default: None
- If a float, the slider will snap to multiples of *valstep*.
- If an array the slider will snap to the values in the array.
-
- orientation : {'horizontal', 'vertical'}, default: 'horizontal'
- The orientation of the slider.
-
- initcolor : color, default: 'r'
- The color of the line at the *valinit* position. Set to ``'none'``
- for no line.
-
- track_color : color, default: 'lightgrey'
- The color of the background track. The track is accessible for
- further styling via the *track* attribute.
-
- handle_style : dict
- Properties of the slider handle. Default values are
-
- ========= ===== ======= ========================================
- Key Value Default Description
- ========= ===== ======= ========================================
- facecolor color 'white' The facecolor of the slider handle.
- edgecolor color '.75' The edgecolor of the slider handle.
- size int 10 The size of the slider handle in points.
- ========= ===== ======= ========================================
-
- Other values will be transformed as marker{foo} and passed to the
- `~.Line2D` constructor. e.g. ``handle_style = {'style'='x'}`` will
- result in ``markerstyle = 'x'``.
-
- Notes
- -----
- Additional kwargs are passed on to ``self.poly`` which is the
- `~matplotlib.patches.Polygon` that draws the slider knob. See the
- `.Polygon` documentation for valid property names (``facecolor``,
- ``edgecolor``, ``alpha``, etc.).
- """
- super().__init__(ax, orientation, closedmin, closedmax,
- valmin, valmax, valfmt, dragging, valstep)
-
- if slidermin is not None and not hasattr(slidermin, 'val'):
- raise ValueError(
- f"Argument slidermin ({type(slidermin)}) has no 'val'")
- if slidermax is not None and not hasattr(slidermax, 'val'):
- raise ValueError(
- f"Argument slidermax ({type(slidermax)}) has no 'val'")
- self.slidermin = slidermin
- self.slidermax = slidermax
- valinit = self._value_in_bounds(valinit)
- if valinit is None:
- valinit = valmin
- self.val = valinit
- self.valinit = valinit
-
- defaults = {'facecolor': 'white', 'edgecolor': '.75', 'size': 10}
- handle_style = {} if handle_style is None else handle_style
- marker_props = {
- f'marker{k}': v for k, v in {**defaults, **handle_style}.items()
- }
-
- if orientation == 'vertical':
- self.track = Rectangle(
- (.25, 0), .5, 1,
- transform=ax.transAxes,
- facecolor=track_color
- )
- ax.add_patch(self.track)
- self.poly = ax.axhspan(valmin, valinit, .25, .75, **kwargs)
- # Drawing a longer line and clipping it to the track avoids
- # pixelation-related asymmetries.
- self.hline = ax.axhline(valinit, 0, 1, color=initcolor, lw=1,
- clip_path=TransformedPatchPath(self.track))
- handleXY = [[0.5], [valinit]]
- else:
- self.track = Rectangle(
- (0, .25), 1, .5,
- transform=ax.transAxes,
- facecolor=track_color
- )
- ax.add_patch(self.track)
- self.poly = ax.axvspan(valmin, valinit, .25, .75, **kwargs)
- self.vline = ax.axvline(valinit, 0, 1, color=initcolor, lw=1,
- clip_path=TransformedPatchPath(self.track))
- handleXY = [[valinit], [0.5]]
- self._handle, = ax.plot(
- *handleXY,
- "o",
- **marker_props,
- clip_on=False
- )
-
- if orientation == 'vertical':
- self.label = ax.text(0.5, 1.02, label, transform=ax.transAxes,
- verticalalignment='bottom',
- horizontalalignment='center')
-
- self.valtext = ax.text(0.5, -0.02, self._format(valinit),
- transform=ax.transAxes,
- verticalalignment='top',
- horizontalalignment='center')
- else:
- self.label = ax.text(-0.02, 0.5, label, transform=ax.transAxes,
- verticalalignment='center',
- horizontalalignment='right')
-
- self.valtext = ax.text(1.02, 0.5, self._format(valinit),
- transform=ax.transAxes,
- verticalalignment='center',
- horizontalalignment='left')
-
- self.set_val(valinit)
-
- def _value_in_bounds(self, val):
- """Makes sure *val* is with given bounds."""
- val = self._stepped_value(val)
-
- if val <= self.valmin:
- if not self.closedmin:
- return
- val = self.valmin
- elif val >= self.valmax:
- if not self.closedmax:
- return
- val = self.valmax
-
- if self.slidermin is not None and val <= self.slidermin.val:
- if not self.closedmin:
- return
- val = self.slidermin.val
-
- if self.slidermax is not None and val >= self.slidermax.val:
- if not self.closedmax:
- return
- val = self.slidermax.val
- return val
-
- def _update(self, event):
- """Update the slider position."""
- if self.ignore(event) or event.button != 1:
- return
-
- if event.name == 'button_press_event' and self.ax.contains(event)[0]:
- self.drag_active = True
- event.canvas.grab_mouse(self.ax)
-
- if not self.drag_active:
- return
-
- if (event.name == 'button_release_event'
- or event.name == 'button_press_event' and not self.ax.contains(event)[0]):
- self.drag_active = False
- event.canvas.release_mouse(self.ax)
- return
-
- xdata, ydata = self._get_data_coords(event)
- val = self._value_in_bounds(
- xdata if self.orientation == 'horizontal' else ydata)
- if val not in [None, self.val]:
- self.set_val(val)
-
- def _format(self, val):
- """Pretty-print *val*."""
- if self.valfmt is not None:
- return self.valfmt % val
- else:
- _, s, _ = self._fmt.format_ticks([self.valmin, val, self.valmax])
- # fmt.get_offset is actually the multiplicative factor, if any.
- return s + self._fmt.get_offset()
-
- def set_val(self, val):
- """
- Set slider value to *val*.
-
- Parameters
- ----------
- val : float
- """
- xy = self.poly.xy
- if self.orientation == 'vertical':
- xy[1] = .25, val
- xy[2] = .75, val
- self._handle.set_ydata([val])
- else:
- xy[2] = val, .75
- xy[3] = val, .25
- self._handle.set_xdata([val])
- self.poly.xy = xy
- self.valtext.set_text(self._format(val))
- if self.drawon:
- self.ax.figure.canvas.draw_idle()
- self.val = val
- if self.eventson:
- self._observers.process('changed', val)
-
- def on_changed(self, func):
- """
- Connect *func* as callback function to changes of the slider value.
-
- Parameters
- ----------
- func : callable
- Function to call when slider is changed.
- The function must accept a single float as its arguments.
-
- Returns
- -------
- int
- Connection id (which can be used to disconnect *func*).
- """
- return self._observers.connect('changed', lambda val: func(val))
-
-
-class RangeSlider(SliderBase):
- """
- A slider representing a range of floating point values. Defines the min and
- max of the range via the *val* attribute as a tuple of (min, max).
-
- Create a slider that defines a range contained within [*valmin*, *valmax*]
- in Axes *ax*. For the slider to remain responsive you must maintain a
- reference to it. Call :meth:`on_changed` to connect to the slider event.
-
- Attributes
- ----------
- val : tuple of float
- Slider value.
- """
-
- @_api.make_keyword_only("3.7", name="valinit")
- def __init__(
- self,
- ax,
- label,
- valmin,
- valmax,
- valinit=None,
- valfmt=None,
- closedmin=True,
- closedmax=True,
- dragging=True,
- valstep=None,
- orientation="horizontal",
- track_color='lightgrey',
- handle_style=None,
- **kwargs,
- ):
- """
- Parameters
- ----------
- ax : Axes
- The Axes to put the slider in.
-
- label : str
- Slider label.
-
- valmin : float
- The minimum value of the slider.
-
- valmax : float
- The maximum value of the slider.
-
- valinit : tuple of float or None, default: None
- The initial positions of the slider. If None the initial positions
- will be at the 25th and 75th percentiles of the range.
-
- valfmt : str, default: None
- %-format string used to format the slider values. If None, a
- `.ScalarFormatter` is used instead.
-
- closedmin : bool, default: True
- Whether the slider interval is closed on the bottom.
-
- closedmax : bool, default: True
- Whether the slider interval is closed on the top.
-
- dragging : bool, default: True
- If True the slider can be dragged by the mouse.
-
- valstep : float, default: None
- If given, the slider will snap to multiples of *valstep*.
-
- orientation : {'horizontal', 'vertical'}, default: 'horizontal'
- The orientation of the slider.
-
- track_color : color, default: 'lightgrey'
- The color of the background track. The track is accessible for
- further styling via the *track* attribute.
-
- handle_style : dict
- Properties of the slider handles. Default values are
-
- ========= ===== ======= =========================================
- Key Value Default Description
- ========= ===== ======= =========================================
- facecolor color 'white' The facecolor of the slider handles.
- edgecolor color '.75' The edgecolor of the slider handles.
- size int 10 The size of the slider handles in points.
- ========= ===== ======= =========================================
-
- Other values will be transformed as marker{foo} and passed to the
- `~.Line2D` constructor. e.g. ``handle_style = {'style'='x'}`` will
- result in ``markerstyle = 'x'``.
-
- Notes
- -----
- Additional kwargs are passed on to ``self.poly`` which is the
- `~matplotlib.patches.Polygon` that draws the slider knob. See the
- `.Polygon` documentation for valid property names (``facecolor``,
- ``edgecolor``, ``alpha``, etc.).
- """
- super().__init__(ax, orientation, closedmin, closedmax,
- valmin, valmax, valfmt, dragging, valstep)
-
- # Set a value to allow _value_in_bounds() to work.
- self.val = (valmin, valmax)
- if valinit is None:
- # Place at the 25th and 75th percentiles
- extent = valmax - valmin
- valinit = np.array([valmin + extent * 0.25,
- valmin + extent * 0.75])
- else:
- valinit = self._value_in_bounds(valinit)
- self.val = valinit
- self.valinit = valinit
-
- defaults = {'facecolor': 'white', 'edgecolor': '.75', 'size': 10}
- handle_style = {} if handle_style is None else handle_style
- marker_props = {
- f'marker{k}': v for k, v in {**defaults, **handle_style}.items()
- }
-
- if orientation == "vertical":
- self.track = Rectangle(
- (.25, 0), .5, 2,
- transform=ax.transAxes,
- facecolor=track_color
- )
- ax.add_patch(self.track)
- poly_transform = self.ax.get_yaxis_transform(which="grid")
- handleXY_1 = [.5, valinit[0]]
- handleXY_2 = [.5, valinit[1]]
- else:
- self.track = Rectangle(
- (0, .25), 1, .5,
- transform=ax.transAxes,
- facecolor=track_color
- )
- ax.add_patch(self.track)
- poly_transform = self.ax.get_xaxis_transform(which="grid")
- handleXY_1 = [valinit[0], .5]
- handleXY_2 = [valinit[1], .5]
- self.poly = Polygon(np.zeros([5, 2]), **kwargs)
- self._update_selection_poly(*valinit)
- self.poly.set_transform(poly_transform)
- self.poly.get_path()._interpolation_steps = 100
- self.ax.add_patch(self.poly)
- self.ax._request_autoscale_view()
- self._handles = [
- ax.plot(
- *handleXY_1,
- "o",
- **marker_props,
- clip_on=False
- )[0],
- ax.plot(
- *handleXY_2,
- "o",
- **marker_props,
- clip_on=False
- )[0]
- ]
-
- if orientation == "vertical":
- self.label = ax.text(
- 0.5,
- 1.02,
- label,
- transform=ax.transAxes,
- verticalalignment="bottom",
- horizontalalignment="center",
- )
-
- self.valtext = ax.text(
- 0.5,
- -0.02,
- self._format(valinit),
- transform=ax.transAxes,
- verticalalignment="top",
- horizontalalignment="center",
- )
- else:
- self.label = ax.text(
- -0.02,
- 0.5,
- label,
- transform=ax.transAxes,
- verticalalignment="center",
- horizontalalignment="right",
- )
-
- self.valtext = ax.text(
- 1.02,
- 0.5,
- self._format(valinit),
- transform=ax.transAxes,
- verticalalignment="center",
- horizontalalignment="left",
- )
-
- self._active_handle = None
- self.set_val(valinit)
-
- def _update_selection_poly(self, vmin, vmax):
- """
- Update the vertices of the *self.poly* slider in-place
- to cover the data range *vmin*, *vmax*.
- """
- # The vertices are positioned
- # 1 ------ 2
- # | |
- # 0, 4 ---- 3
- verts = self.poly.xy
- if self.orientation == "vertical":
- verts[0] = verts[4] = .25, vmin
- verts[1] = .25, vmax
- verts[2] = .75, vmax
- verts[3] = .75, vmin
- else:
- verts[0] = verts[4] = vmin, .25
- verts[1] = vmin, .75
- verts[2] = vmax, .75
- verts[3] = vmax, .25
-
- def _min_in_bounds(self, min):
- """Ensure the new min value is between valmin and self.val[1]."""
- if min <= self.valmin:
- if not self.closedmin:
- return self.val[0]
- min = self.valmin
-
- if min > self.val[1]:
- min = self.val[1]
- return self._stepped_value(min)
-
- def _max_in_bounds(self, max):
- """Ensure the new max value is between valmax and self.val[0]."""
- if max >= self.valmax:
- if not self.closedmax:
- return self.val[1]
- max = self.valmax
-
- if max <= self.val[0]:
- max = self.val[0]
- return self._stepped_value(max)
-
- def _value_in_bounds(self, vals):
- """Clip min, max values to the bounds."""
- return (self._min_in_bounds(vals[0]), self._max_in_bounds(vals[1]))
-
- def _update_val_from_pos(self, pos):
- """Update the slider value based on a given position."""
- idx = np.argmin(np.abs(self.val - pos))
- if idx == 0:
- val = self._min_in_bounds(pos)
- self.set_min(val)
- else:
- val = self._max_in_bounds(pos)
- self.set_max(val)
- if self._active_handle:
- if self.orientation == "vertical":
- self._active_handle.set_ydata([val])
- else:
- self._active_handle.set_xdata([val])
-
- def _update(self, event):
- """Update the slider position."""
- if self.ignore(event) or event.button != 1:
- return
-
- if event.name == "button_press_event" and self.ax.contains(event)[0]:
- self.drag_active = True
- event.canvas.grab_mouse(self.ax)
-
- if not self.drag_active:
- return
-
- if (event.name == "button_release_event"
- or event.name == "button_press_event" and not self.ax.contains(event)[0]):
- self.drag_active = False
- event.canvas.release_mouse(self.ax)
- self._active_handle = None
- return
-
- # determine which handle was grabbed
- xdata, ydata = self._get_data_coords(event)
- handle_index = np.argmin(np.abs(
- [h.get_xdata()[0] - xdata for h in self._handles]
- if self.orientation == "horizontal" else
- [h.get_ydata()[0] - ydata for h in self._handles]))
- handle = self._handles[handle_index]
-
- # these checks ensure smooth behavior if the handles swap which one
- # has a higher value. i.e. if one is dragged over and past the other.
- if handle is not self._active_handle:
- self._active_handle = handle
-
- self._update_val_from_pos(xdata if self.orientation == "horizontal" else ydata)
-
- def _format(self, val):
- """Pretty-print *val*."""
- if self.valfmt is not None:
- return f"({self.valfmt % val[0]}, {self.valfmt % val[1]})"
- else:
- _, s1, s2, _ = self._fmt.format_ticks(
- [self.valmin, *val, self.valmax]
- )
- # fmt.get_offset is actually the multiplicative factor, if any.
- s1 += self._fmt.get_offset()
- s2 += self._fmt.get_offset()
- # Use f string to avoid issues with backslashes when cast to a str
- return f"({s1}, {s2})"
-
- def set_min(self, min):
- """
- Set the lower value of the slider to *min*.
-
- Parameters
- ----------
- min : float
- """
- self.set_val((min, self.val[1]))
-
- def set_max(self, max):
- """
- Set the lower value of the slider to *max*.
-
- Parameters
- ----------
- max : float
- """
- self.set_val((self.val[0], max))
-
- def set_val(self, val):
- """
- Set slider value to *val*.
-
- Parameters
- ----------
- val : tuple or array-like of float
- """
- val = np.sort(val)
- _api.check_shape((2,), val=val)
- # Reset value to allow _value_in_bounds() to work.
- self.val = (self.valmin, self.valmax)
- vmin, vmax = self._value_in_bounds(val)
- self._update_selection_poly(vmin, vmax)
- if self.orientation == "vertical":
- self._handles[0].set_ydata([vmin])
- self._handles[1].set_ydata([vmax])
- else:
- self._handles[0].set_xdata([vmin])
- self._handles[1].set_xdata([vmax])
-
- self.valtext.set_text(self._format((vmin, vmax)))
-
- if self.drawon:
- self.ax.figure.canvas.draw_idle()
- self.val = (vmin, vmax)
- if self.eventson:
- self._observers.process("changed", (vmin, vmax))
-
- def on_changed(self, func):
- """
- Connect *func* as callback function to changes of the slider value.
-
- Parameters
- ----------
- func : callable
- Function to call when slider is changed. The function
- must accept a 2-tuple of floats as its argument.
-
- Returns
- -------
- int
- Connection id (which can be used to disconnect *func*).
- """
- return self._observers.connect('changed', lambda val: func(val))
-
-
-def _expand_text_props(props):
- props = cbook.normalize_kwargs(props, mtext.Text)
- return cycler(**props)() if props else itertools.repeat({})
-
-
-class CheckButtons(AxesWidget):
- r"""
- A GUI neutral set of check buttons.
-
- For the check buttons to remain responsive you must keep a
- reference to this object.
-
- Connect to the CheckButtons with the `.on_clicked` method.
-
- Attributes
- ----------
- ax : `~matplotlib.axes.Axes`
- The parent Axes for the widget.
-
- labels : list of `~matplotlib.text.Text`
-
- rectangles : list of `~matplotlib.patches.Rectangle`
-
- lines : list of (`.Line2D`, `.Line2D`) pairs
- List of lines for the x's in the checkboxes. These lines exist for
- each box, but have ``set_visible(False)`` when its box is not checked.
- """
-
- def __init__(self, ax, labels, actives=None, *, useblit=True,
- label_props=None, frame_props=None, check_props=None):
- """
- Add check buttons to `~.axes.Axes` instance *ax*.
-
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The parent Axes for the widget.
- labels : list of str
- The labels of the check buttons.
- actives : list of bool, optional
- The initial check states of the buttons. The list must have the
- same length as *labels*. If not given, all buttons are unchecked.
- useblit : bool, default: True
- Use blitting for faster drawing if supported by the backend.
- See the tutorial :ref:`blitting` for details.
-
- .. versionadded:: 3.7
-
- label_props : dict, optional
- Dictionary of `.Text` properties to be used for the labels.
-
- .. versionadded:: 3.7
- frame_props : dict, optional
- Dictionary of scatter `.Collection` properties to be used for the
- check button frame. Defaults (label font size / 2)**2 size, black
- edgecolor, no facecolor, and 1.0 linewidth.
-
- .. versionadded:: 3.7
- check_props : dict, optional
- Dictionary of scatter `.Collection` properties to be used for the
- check button check. Defaults to (label font size / 2)**2 size,
- black color, and 1.0 linewidth.
-
- .. versionadded:: 3.7
- """
- super().__init__(ax)
-
- _api.check_isinstance((dict, None), label_props=label_props,
- frame_props=frame_props, check_props=check_props)
-
- ax.set_xticks([])
- ax.set_yticks([])
- ax.set_navigate(False)
-
- if actives is None:
- actives = [False] * len(labels)
-
- self._useblit = useblit and self.canvas.supports_blit
- self._background = None
-
- ys = np.linspace(1, 0, len(labels)+2)[1:-1]
-
- label_props = _expand_text_props(label_props)
- self.labels = [
- ax.text(0.25, y, label, transform=ax.transAxes,
- horizontalalignment="left", verticalalignment="center",
- **props)
- for y, label, props in zip(ys, labels, label_props)]
- text_size = np.array([text.get_fontsize() for text in self.labels]) / 2
-
- frame_props = {
- 's': text_size**2,
- 'linewidth': 1,
- **cbook.normalize_kwargs(frame_props, collections.PathCollection),
- 'marker': 's',
- 'transform': ax.transAxes,
- }
- frame_props.setdefault('facecolor', frame_props.get('color', 'none'))
- frame_props.setdefault('edgecolor', frame_props.pop('color', 'black'))
- self._frames = ax.scatter([0.15] * len(ys), ys, **frame_props)
- check_props = {
- 'linewidth': 1,
- 's': text_size**2,
- **cbook.normalize_kwargs(check_props, collections.PathCollection),
- 'marker': 'x',
- 'transform': ax.transAxes,
- 'animated': self._useblit,
- }
- check_props.setdefault('facecolor', check_props.pop('color', 'black'))
- self._checks = ax.scatter([0.15] * len(ys), ys, **check_props)
- # The user may have passed custom colours in check_props, so we need to
- # create the checks (above), and modify the visibility after getting
- # whatever the user set.
- self._init_status(actives)
-
- self.connect_event('button_press_event', self._clicked)
- if self._useblit:
- self.connect_event('draw_event', self._clear)
-
- self._observers = cbook.CallbackRegistry(signals=["clicked"])
-
- def _clear(self, event):
- """Internal event handler to clear the buttons."""
- if self.ignore(event) or self._changed_canvas():
- return
- self._background = self.canvas.copy_from_bbox(self.ax.bbox)
- self.ax.draw_artist(self._checks)
- if hasattr(self, '_lines'):
- for l1, l2 in self._lines:
- self.ax.draw_artist(l1)
- self.ax.draw_artist(l2)
-
- def _clicked(self, event):
- if self.ignore(event) or event.button != 1 or not self.ax.contains(event)[0]:
- return
- pclicked = self.ax.transAxes.inverted().transform((event.x, event.y))
- distances = {}
- if hasattr(self, "_rectangles"):
- for i, (p, t) in enumerate(zip(self._rectangles, self.labels)):
- x0, y0 = p.get_xy()
- if (t.get_window_extent().contains(event.x, event.y)
- or (x0 <= pclicked[0] <= x0 + p.get_width()
- and y0 <= pclicked[1] <= y0 + p.get_height())):
- distances[i] = np.linalg.norm(pclicked - p.get_center())
- else:
- _, frame_inds = self._frames.contains(event)
- coords = self._frames.get_offset_transform().transform(
- self._frames.get_offsets()
- )
- for i, t in enumerate(self.labels):
- if (i in frame_inds["ind"]
- or t.get_window_extent().contains(event.x, event.y)):
- distances[i] = np.linalg.norm(pclicked - coords[i])
- if len(distances) > 0:
- closest = min(distances, key=distances.get)
- self.set_active(closest)
-
- def set_label_props(self, props):
- """
- Set properties of the `.Text` labels.
-
- .. versionadded:: 3.7
-
- Parameters
- ----------
- props : dict
- Dictionary of `.Text` properties to be used for the labels.
- """
- _api.check_isinstance(dict, props=props)
- props = _expand_text_props(props)
- for text, prop in zip(self.labels, props):
- text.update(prop)
-
- def set_frame_props(self, props):
- """
- Set properties of the check button frames.
-
- .. versionadded:: 3.7
-
- Parameters
- ----------
- props : dict
- Dictionary of `.Collection` properties to be used for the check
- button frames.
- """
- _api.check_isinstance(dict, props=props)
- if 's' in props: # Keep API consistent with constructor.
- props['sizes'] = np.broadcast_to(props.pop('s'), len(self.labels))
- self._frames.update(props)
-
- def set_check_props(self, props):
- """
- Set properties of the check button checks.
-
- .. versionadded:: 3.7
-
- Parameters
- ----------
- props : dict
- Dictionary of `.Collection` properties to be used for the check
- button check.
- """
- _api.check_isinstance(dict, props=props)
- if 's' in props: # Keep API consistent with constructor.
- props['sizes'] = np.broadcast_to(props.pop('s'), len(self.labels))
- actives = self.get_status()
- self._checks.update(props)
- # If new colours are supplied, then we must re-apply the status.
- self._init_status(actives)
-
- def set_active(self, index):
- """
- Toggle (activate or deactivate) a check button by index.
-
- Callbacks will be triggered if :attr:`eventson` is True.
-
- Parameters
- ----------
- index : int
- Index of the check button to toggle.
-
- Raises
- ------
- ValueError
- If *index* is invalid.
- """
- if index not in range(len(self.labels)):
- raise ValueError(f'Invalid CheckButton index: {index}')
-
- invisible = colors.to_rgba('none')
-
- facecolors = self._checks.get_facecolor()
- facecolors[index] = (
- self._active_check_colors[index]
- if colors.same_color(facecolors[index], invisible)
- else invisible
- )
- self._checks.set_facecolor(facecolors)
-
- if hasattr(self, "_lines"):
- l1, l2 = self._lines[index]
- l1.set_visible(not l1.get_visible())
- l2.set_visible(not l2.get_visible())
-
- if self.drawon:
- if self._useblit:
- if self._background is not None:
- self.canvas.restore_region(self._background)
- self.ax.draw_artist(self._checks)
- if hasattr(self, "_lines"):
- for l1, l2 in self._lines:
- self.ax.draw_artist(l1)
- self.ax.draw_artist(l2)
- self.canvas.blit(self.ax.bbox)
- else:
- self.canvas.draw()
-
- if self.eventson:
- self._observers.process('clicked', self.labels[index].get_text())
-
- def _init_status(self, actives):
- """
- Initialize properties to match active status.
-
- The user may have passed custom colours in *check_props* to the
- constructor, or to `.set_check_props`, so we need to modify the
- visibility after getting whatever the user set.
- """
- self._active_check_colors = self._checks.get_facecolor()
- if len(self._active_check_colors) == 1:
- self._active_check_colors = np.repeat(self._active_check_colors,
- len(actives), axis=0)
- self._checks.set_facecolor(
- [ec if active else "none"
- for ec, active in zip(self._active_check_colors, actives)])
-
- def get_status(self):
- """
- Return a list of the status (True/False) of all of the check buttons.
- """
- return [not colors.same_color(color, colors.to_rgba("none"))
- for color in self._checks.get_facecolors()]
-
- def on_clicked(self, func):
- """
- Connect the callback function *func* to button click events.
-
- Returns a connection id, which can be used to disconnect the callback.
- """
- return self._observers.connect('clicked', lambda text: func(text))
-
- def disconnect(self, cid):
- """Remove the observer with connection id *cid*."""
- self._observers.disconnect(cid)
-
- @_api.deprecated("3.7",
- addendum="Any custom property styling may be lost.")
- @property
- def rectangles(self):
- if not hasattr(self, "_rectangles"):
- ys = np.linspace(1, 0, len(self.labels)+2)[1:-1]
- dy = 1. / (len(self.labels) + 1)
- w, h = dy / 2, dy / 2
- rectangles = self._rectangles = [
- Rectangle(xy=(0.05, ys[i] - h / 2), width=w, height=h,
- edgecolor="black",
- facecolor="none",
- transform=self.ax.transAxes
- )
- for i, y in enumerate(ys)
- ]
- self._frames.set_visible(False)
- for rectangle in rectangles:
- self.ax.add_patch(rectangle)
- if not hasattr(self, "_lines"):
- with _api.suppress_matplotlib_deprecation_warning():
- _ = self.lines
- return self._rectangles
-
- @_api.deprecated("3.7",
- addendum="Any custom property styling may be lost.")
- @property
- def lines(self):
- if not hasattr(self, "_lines"):
- ys = np.linspace(1, 0, len(self.labels)+2)[1:-1]
- self._checks.set_visible(False)
- dy = 1. / (len(self.labels) + 1)
- w, h = dy / 2, dy / 2
- self._lines = []
- current_status = self.get_status()
- lineparams = {'color': 'k', 'linewidth': 1.25,
- 'transform': self.ax.transAxes,
- 'solid_capstyle': 'butt',
- 'animated': self._useblit}
- for i, y in enumerate(ys):
- x, y = 0.05, y - h / 2
- l1 = Line2D([x, x + w], [y + h, y], **lineparams)
- l2 = Line2D([x, x + w], [y, y + h], **lineparams)
-
- l1.set_visible(current_status[i])
- l2.set_visible(current_status[i])
- self._lines.append((l1, l2))
- self.ax.add_line(l1)
- self.ax.add_line(l2)
- if not hasattr(self, "_rectangles"):
- with _api.suppress_matplotlib_deprecation_warning():
- _ = self.rectangles
- return self._lines
-
-
-class TextBox(AxesWidget):
- """
- A GUI neutral text input box.
-
- For the text box to remain responsive you must keep a reference to it.
-
- Call `.on_text_change` to be updated whenever the text changes.
-
- Call `.on_submit` to be updated whenever the user hits enter or
- leaves the text entry field.
-
- Attributes
- ----------
- ax : `~matplotlib.axes.Axes`
- The parent Axes for the widget.
- label : `~matplotlib.text.Text`
-
- color : color
- The color of the text box when not hovering.
- hovercolor : color
- The color of the text box when hovering.
- """
-
- @_api.make_keyword_only("3.7", name="color")
- def __init__(self, ax, label, initial='',
- color='.95', hovercolor='1', label_pad=.01,
- textalignment="left"):
- """
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The `~.axes.Axes` instance the button will be placed into.
- label : str
- Label for this text box.
- initial : str
- Initial value in the text box.
- color : color
- The color of the box.
- hovercolor : color
- The color of the box when the mouse is over it.
- label_pad : float
- The distance between the label and the right side of the textbox.
- textalignment : {'left', 'center', 'right'}
- The horizontal location of the text.
- """
- super().__init__(ax)
-
- self._text_position = _api.check_getitem(
- {"left": 0.05, "center": 0.5, "right": 0.95},
- textalignment=textalignment)
-
- self.label = ax.text(
- -label_pad, 0.5, label, transform=ax.transAxes,
- verticalalignment='center', horizontalalignment='right')
-
- # TextBox's text object should not parse mathtext at all.
- self.text_disp = self.ax.text(
- self._text_position, 0.5, initial, transform=self.ax.transAxes,
- verticalalignment='center', horizontalalignment=textalignment,
- parse_math=False)
-
- self._observers = cbook.CallbackRegistry(signals=["change", "submit"])
-
- ax.set(
- xlim=(0, 1), ylim=(0, 1), # s.t. cursor appears from first click.
- navigate=False, facecolor=color,
- xticks=[], yticks=[])
-
- self.cursor_index = 0
-
- self.cursor = ax.vlines(0, 0, 0, visible=False, color="k", lw=1,
- transform=mpl.transforms.IdentityTransform())
-
- self.connect_event('button_press_event', self._click)
- self.connect_event('button_release_event', self._release)
- self.connect_event('motion_notify_event', self._motion)
- self.connect_event('key_press_event', self._keypress)
- self.connect_event('resize_event', self._resize)
-
- self.color = color
- self.hovercolor = hovercolor
-
- self.capturekeystrokes = False
-
- @property
- def text(self):
- return self.text_disp.get_text()
-
- def _rendercursor(self):
- # this is a hack to figure out where the cursor should go.
- # we draw the text up to where the cursor should go, measure
- # and save its dimensions, draw the real text, then put the cursor
- # at the saved dimensions
-
- # This causes a single extra draw if the figure has never been rendered
- # yet, which should be fine as we're going to repeatedly re-render the
- # figure later anyways.
- if self.ax.figure._get_renderer() is None:
- self.ax.figure.canvas.draw()
-
- text = self.text_disp.get_text() # Save value before overwriting it.
- widthtext = text[:self.cursor_index]
-
- bb_text = self.text_disp.get_window_extent()
- self.text_disp.set_text(widthtext or ",")
- bb_widthtext = self.text_disp.get_window_extent()
-
- if bb_text.y0 == bb_text.y1: # Restoring the height if no text.
- bb_text.y0 -= bb_widthtext.height / 2
- bb_text.y1 += bb_widthtext.height / 2
- elif not widthtext: # Keep width to 0.
- bb_text.x1 = bb_text.x0
- else: # Move the cursor using width of bb_widthtext.
- bb_text.x1 = bb_text.x0 + bb_widthtext.width
-
- self.cursor.set(
- segments=[[(bb_text.x1, bb_text.y0), (bb_text.x1, bb_text.y1)]],
- visible=True)
- self.text_disp.set_text(text)
-
- self.ax.figure.canvas.draw()
-
- def _release(self, event):
- if self.ignore(event):
- return
- if event.canvas.mouse_grabber != self.ax:
- return
- event.canvas.release_mouse(self.ax)
-
- def _keypress(self, event):
- if self.ignore(event):
- return
- if self.capturekeystrokes:
- key = event.key
- text = self.text
- if len(key) == 1:
- text = (text[:self.cursor_index] + key +
- text[self.cursor_index:])
- self.cursor_index += 1
- elif key == "right":
- if self.cursor_index != len(text):
- self.cursor_index += 1
- elif key == "left":
- if self.cursor_index != 0:
- self.cursor_index -= 1
- elif key == "home":
- self.cursor_index = 0
- elif key == "end":
- self.cursor_index = len(text)
- elif key == "backspace":
- if self.cursor_index != 0:
- text = (text[:self.cursor_index - 1] +
- text[self.cursor_index:])
- self.cursor_index -= 1
- elif key == "delete":
- if self.cursor_index != len(self.text):
- text = (text[:self.cursor_index] +
- text[self.cursor_index + 1:])
- self.text_disp.set_text(text)
- self._rendercursor()
- if self.eventson:
- self._observers.process('change', self.text)
- if key in ["enter", "return"]:
- self._observers.process('submit', self.text)
-
- def set_val(self, val):
- newval = str(val)
- if self.text == newval:
- return
- self.text_disp.set_text(newval)
- self._rendercursor()
- if self.eventson:
- self._observers.process('change', self.text)
- self._observers.process('submit', self.text)
-
- @_api.delete_parameter("3.7", "x")
- def begin_typing(self, x=None):
- self.capturekeystrokes = True
- # Disable keypress shortcuts, which may otherwise cause the figure to
- # be saved, closed, etc., until the user stops typing. The way to
- # achieve this depends on whether toolmanager is in use.
- stack = ExitStack() # Register cleanup actions when user stops typing.
- self._on_stop_typing = stack.close
- toolmanager = getattr(
- self.ax.figure.canvas.manager, "toolmanager", None)
- if toolmanager is not None:
- # If using toolmanager, lock keypresses, and plan to release the
- # lock when typing stops.
- toolmanager.keypresslock(self)
- stack.callback(toolmanager.keypresslock.release, self)
- else:
- # If not using toolmanager, disable all keypress-related rcParams.
- # Avoid spurious warnings if keymaps are getting deprecated.
- with _api.suppress_matplotlib_deprecation_warning():
- stack.enter_context(mpl.rc_context(
- {k: [] for k in mpl.rcParams if k.startswith("keymap.")}))
-
- def stop_typing(self):
- if self.capturekeystrokes:
- self._on_stop_typing()
- self._on_stop_typing = None
- notifysubmit = True
- else:
- notifysubmit = False
- self.capturekeystrokes = False
- self.cursor.set_visible(False)
- self.ax.figure.canvas.draw()
- if notifysubmit and self.eventson:
- # Because process() might throw an error in the user's code, only
- # call it once we've already done our cleanup.
- self._observers.process('submit', self.text)
-
- def _click(self, event):
- if self.ignore(event):
- return
- if not self.ax.contains(event)[0]:
- self.stop_typing()
- return
- if not self.eventson:
- return
- if event.canvas.mouse_grabber != self.ax:
- event.canvas.grab_mouse(self.ax)
- if not self.capturekeystrokes:
- self.begin_typing()
- self.cursor_index = self.text_disp._char_index_at(event.x)
- self._rendercursor()
-
- def _resize(self, event):
- self.stop_typing()
-
- def _motion(self, event):
- if self.ignore(event):
- return
- c = self.hovercolor if self.ax.contains(event)[0] else self.color
- if not colors.same_color(c, self.ax.get_facecolor()):
- self.ax.set_facecolor(c)
- if self.drawon:
- self.ax.figure.canvas.draw()
-
- def on_text_change(self, func):
- """
- When the text changes, call this *func* with event.
-
- A connection id is returned which can be used to disconnect.
- """
- return self._observers.connect('change', lambda text: func(text))
-
- def on_submit(self, func):
- """
- When the user hits enter or leaves the submission box, call this
- *func* with event.
-
- A connection id is returned which can be used to disconnect.
- """
- return self._observers.connect('submit', lambda text: func(text))
-
- def disconnect(self, cid):
- """Remove the observer with connection id *cid*."""
- self._observers.disconnect(cid)
-
-
-class RadioButtons(AxesWidget):
- """
- A GUI neutral radio button.
-
- For the buttons to remain responsive you must keep a reference to this
- object.
-
- Connect to the RadioButtons with the `.on_clicked` method.
-
- Attributes
- ----------
- ax : `~matplotlib.axes.Axes`
- The parent Axes for the widget.
- activecolor : color
- The color of the selected button.
- labels : list of `.Text`
- The button labels.
- circles : list of `~.patches.Circle`
- The buttons.
- value_selected : str
- The label text of the currently selected button.
- """
-
- def __init__(self, ax, labels, active=0, activecolor=None, *,
- useblit=True, label_props=None, radio_props=None):
- """
- Add radio buttons to an `~.axes.Axes`.
-
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The Axes to add the buttons to.
- labels : list of str
- The button labels.
- active : int
- The index of the initially selected button.
- activecolor : color
- The color of the selected button. The default is ``'blue'`` if not
- specified here or in *radio_props*.
- useblit : bool, default: True
- Use blitting for faster drawing if supported by the backend.
- See the tutorial :ref:`blitting` for details.
-
- .. versionadded:: 3.7
-
- label_props : dict or list of dict, optional
- Dictionary of `.Text` properties to be used for the labels.
-
- .. versionadded:: 3.7
- radio_props : dict, optional
- Dictionary of scatter `.Collection` properties to be used for the
- radio buttons. Defaults to (label font size / 2)**2 size, black
- edgecolor, and *activecolor* facecolor (when active).
-
- .. note::
- If a facecolor is supplied in *radio_props*, it will override
- *activecolor*. This may be used to provide an active color per
- button.
-
- .. versionadded:: 3.7
- """
- super().__init__(ax)
-
- _api.check_isinstance((dict, None), label_props=label_props,
- radio_props=radio_props)
-
- radio_props = cbook.normalize_kwargs(radio_props,
- collections.PathCollection)
- if activecolor is not None:
- if 'facecolor' in radio_props:
- _api.warn_external(
- 'Both the *activecolor* parameter and the *facecolor* '
- 'key in the *radio_props* parameter has been specified. '
- '*activecolor* will be ignored.')
- else:
- activecolor = 'blue' # Default.
-
- self._activecolor = activecolor
- self.value_selected = labels[active]
-
- ax.set_xticks([])
- ax.set_yticks([])
- ax.set_navigate(False)
-
- ys = np.linspace(1, 0, len(labels) + 2)[1:-1]
-
- self._useblit = useblit and self.canvas.supports_blit
- self._background = None
-
- label_props = _expand_text_props(label_props)
- self.labels = [
- ax.text(0.25, y, label, transform=ax.transAxes,
- horizontalalignment="left", verticalalignment="center",
- **props)
- for y, label, props in zip(ys, labels, label_props)]
- text_size = np.array([text.get_fontsize() for text in self.labels]) / 2
-
- radio_props = {
- 's': text_size**2,
- **radio_props,
- 'marker': 'o',
- 'transform': ax.transAxes,
- 'animated': self._useblit,
- }
- radio_props.setdefault('edgecolor', radio_props.get('color', 'black'))
- radio_props.setdefault('facecolor',
- radio_props.pop('color', activecolor))
- self._buttons = ax.scatter([.15] * len(ys), ys, **radio_props)
- # The user may have passed custom colours in radio_props, so we need to
- # create the radios, and modify the visibility after getting whatever
- # the user set.
- self._active_colors = self._buttons.get_facecolor()
- if len(self._active_colors) == 1:
- self._active_colors = np.repeat(self._active_colors, len(labels),
- axis=0)
- self._buttons.set_facecolor(
- [activecolor if i == active else "none"
- for i, activecolor in enumerate(self._active_colors)])
-
- self.connect_event('button_press_event', self._clicked)
- if self._useblit:
- self.connect_event('draw_event', self._clear)
-
- self._observers = cbook.CallbackRegistry(signals=["clicked"])
-
- def _clear(self, event):
- """Internal event handler to clear the buttons."""
- if self.ignore(event) or self._changed_canvas():
- return
- self._background = self.canvas.copy_from_bbox(self.ax.bbox)
- self.ax.draw_artist(self._buttons)
- if hasattr(self, "_circles"):
- for circle in self._circles:
- self.ax.draw_artist(circle)
-
- def _clicked(self, event):
- if self.ignore(event) or event.button != 1 or not self.ax.contains(event)[0]:
- return
- pclicked = self.ax.transAxes.inverted().transform((event.x, event.y))
- _, inds = self._buttons.contains(event)
- coords = self._buttons.get_offset_transform().transform(
- self._buttons.get_offsets())
- distances = {}
- if hasattr(self, "_circles"): # Remove once circles is removed.
- for i, (p, t) in enumerate(zip(self._circles, self.labels)):
- if (t.get_window_extent().contains(event.x, event.y)
- or np.linalg.norm(pclicked - p.center) < p.radius):
- distances[i] = np.linalg.norm(pclicked - p.center)
- else:
- for i, t in enumerate(self.labels):
- if (i in inds["ind"]
- or t.get_window_extent().contains(event.x, event.y)):
- distances[i] = np.linalg.norm(pclicked - coords[i])
- if len(distances) > 0:
- closest = min(distances, key=distances.get)
- self.set_active(closest)
-
- def set_label_props(self, props):
- """
- Set properties of the `.Text` labels.
-
- .. versionadded:: 3.7
-
- Parameters
- ----------
- props : dict
- Dictionary of `.Text` properties to be used for the labels.
- """
- _api.check_isinstance(dict, props=props)
- props = _expand_text_props(props)
- for text, prop in zip(self.labels, props):
- text.update(prop)
-
- def set_radio_props(self, props):
- """
- Set properties of the `.Text` labels.
-
- .. versionadded:: 3.7
-
- Parameters
- ----------
- props : dict
- Dictionary of `.Collection` properties to be used for the radio
- buttons.
- """
- _api.check_isinstance(dict, props=props)
- if 's' in props: # Keep API consistent with constructor.
- props['sizes'] = np.broadcast_to(props.pop('s'), len(self.labels))
- self._buttons.update(props)
- self._active_colors = self._buttons.get_facecolor()
- if len(self._active_colors) == 1:
- self._active_colors = np.repeat(self._active_colors,
- len(self.labels), axis=0)
- self._buttons.set_facecolor(
- [activecolor if text.get_text() == self.value_selected else "none"
- for text, activecolor in zip(self.labels, self._active_colors)])
-
- @property
- def activecolor(self):
- return self._activecolor
-
- @activecolor.setter
- def activecolor(self, activecolor):
- colors._check_color_like(activecolor=activecolor)
- self._activecolor = activecolor
- self.set_radio_props({'facecolor': activecolor})
- # Make sure the deprecated version is updated.
- # Remove once circles is removed.
- labels = [label.get_text() for label in self.labels]
- with cbook._setattr_cm(self, eventson=False):
- self.set_active(labels.index(self.value_selected))
-
- def set_active(self, index):
- """
- Select button with number *index*.
-
- Callbacks will be triggered if :attr:`eventson` is True.
- """
- if index not in range(len(self.labels)):
- raise ValueError(f'Invalid RadioButton index: {index}')
- self.value_selected = self.labels[index].get_text()
- button_facecolors = self._buttons.get_facecolor()
- button_facecolors[:] = colors.to_rgba("none")
- button_facecolors[index] = colors.to_rgba(self._active_colors[index])
- self._buttons.set_facecolor(button_facecolors)
- if hasattr(self, "_circles"): # Remove once circles is removed.
- for i, p in enumerate(self._circles):
- p.set_facecolor(self.activecolor if i == index else "none")
- if self.drawon and self._useblit:
- self.ax.draw_artist(p)
- if self.drawon:
- if self._useblit:
- if self._background is not None:
- self.canvas.restore_region(self._background)
- self.ax.draw_artist(self._buttons)
- if hasattr(self, "_circles"):
- for p in self._circles:
- self.ax.draw_artist(p)
- self.canvas.blit(self.ax.bbox)
- else:
- self.canvas.draw()
-
- if self.eventson:
- self._observers.process('clicked', self.labels[index].get_text())
-
- def on_clicked(self, func):
- """
- Connect the callback function *func* to button click events.
-
- Returns a connection id, which can be used to disconnect the callback.
- """
- return self._observers.connect('clicked', func)
-
- def disconnect(self, cid):
- """Remove the observer with connection id *cid*."""
- self._observers.disconnect(cid)
-
- @_api.deprecated("3.7",
- addendum="Any custom property styling may be lost.")
- @property
- def circles(self):
- if not hasattr(self, "_circles"):
- radius = min(.5 / (len(self.labels) + 1) - .01, .05)
- circles = self._circles = [
- Circle(xy=self._buttons.get_offsets()[i], edgecolor="black",
- facecolor=self._buttons.get_facecolor()[i],
- radius=radius, transform=self.ax.transAxes,
- animated=self._useblit)
- for i in range(len(self.labels))]
- self._buttons.set_visible(False)
- for circle in circles:
- self.ax.add_patch(circle)
- return self._circles
-
-
-class SubplotTool(Widget):
- """
- A tool to adjust the subplot params of a `.Figure`.
- """
-
- def __init__(self, targetfig, toolfig):
- """
- Parameters
- ----------
- targetfig : `~matplotlib.figure.Figure`
- The figure instance to adjust.
- toolfig : `~matplotlib.figure.Figure`
- The figure instance to embed the subplot tool into.
- """
-
- self.figure = toolfig
- self.targetfig = targetfig
- toolfig.subplots_adjust(left=0.2, right=0.9)
- toolfig.suptitle("Click on slider to adjust subplot param")
-
- self._sliders = []
- names = ["left", "bottom", "right", "top", "wspace", "hspace"]
- # The last subplot, removed below, keeps space for the "Reset" button.
- for name, ax in zip(names, toolfig.subplots(len(names) + 1)):
- ax.set_navigate(False)
- slider = Slider(ax, name, 0, 1,
- valinit=getattr(targetfig.subplotpars, name))
- slider.on_changed(self._on_slider_changed)
- self._sliders.append(slider)
- toolfig.axes[-1].remove()
- (self.sliderleft, self.sliderbottom, self.sliderright, self.slidertop,
- self.sliderwspace, self.sliderhspace) = self._sliders
- for slider in [self.sliderleft, self.sliderbottom,
- self.sliderwspace, self.sliderhspace]:
- slider.closedmax = False
- for slider in [self.sliderright, self.slidertop]:
- slider.closedmin = False
-
- # constraints
- self.sliderleft.slidermax = self.sliderright
- self.sliderright.slidermin = self.sliderleft
- self.sliderbottom.slidermax = self.slidertop
- self.slidertop.slidermin = self.sliderbottom
-
- bax = toolfig.add_axes([0.8, 0.05, 0.15, 0.075])
- self.buttonreset = Button(bax, 'Reset')
- self.buttonreset.on_clicked(self._on_reset)
-
- def _on_slider_changed(self, _):
- self.targetfig.subplots_adjust(
- **{slider.label.get_text(): slider.val
- for slider in self._sliders})
- if self.drawon:
- self.targetfig.canvas.draw()
-
- def _on_reset(self, event):
- with ExitStack() as stack:
- # Temporarily disable drawing on self and self's sliders, and
- # disconnect slider events (as the subplotparams can be temporarily
- # invalid, depending on the order in which they are restored).
- stack.enter_context(cbook._setattr_cm(self, drawon=False))
- for slider in self._sliders:
- stack.enter_context(
- cbook._setattr_cm(slider, drawon=False, eventson=False))
- # Reset the slider to the initial position.
- for slider in self._sliders:
- slider.reset()
- if self.drawon:
- event.canvas.draw() # Redraw the subplottool canvas.
- self._on_slider_changed(None) # Apply changes to the target window.
-
-
-class Cursor(AxesWidget):
- """
- A crosshair cursor that spans the Axes and moves with mouse cursor.
-
- For the cursor to remain responsive you must keep a reference to it.
-
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The `~.axes.Axes` to attach the cursor to.
- horizOn : bool, default: True
- Whether to draw the horizontal line.
- vertOn : bool, default: True
- Whether to draw the vertical line.
- useblit : bool, default: False
- Use blitting for faster drawing if supported by the backend.
- See the tutorial :ref:`blitting` for details.
-
- Other Parameters
- ----------------
- **lineprops
- `.Line2D` properties that control the appearance of the lines.
- See also `~.Axes.axhline`.
-
- Examples
- --------
- See :doc:`/gallery/widgets/cursor`.
- """
- @_api.make_keyword_only("3.7", "horizOn")
- def __init__(self, ax, horizOn=True, vertOn=True, useblit=False,
- **lineprops):
- super().__init__(ax)
-
- self.connect_event('motion_notify_event', self.onmove)
- self.connect_event('draw_event', self.clear)
-
- self.visible = True
- self.horizOn = horizOn
- self.vertOn = vertOn
- self.useblit = useblit and self.canvas.supports_blit
-
- if self.useblit:
- lineprops['animated'] = True
- self.lineh = ax.axhline(ax.get_ybound()[0], visible=False, **lineprops)
- self.linev = ax.axvline(ax.get_xbound()[0], visible=False, **lineprops)
-
- self.background = None
- self.needclear = False
-
- def clear(self, event):
- """Internal event handler to clear the cursor."""
- if self.ignore(event) or self._changed_canvas():
- return
- if self.useblit:
- self.background = self.canvas.copy_from_bbox(self.ax.bbox)
-
- def onmove(self, event):
- """Internal event handler to draw the cursor when the mouse moves."""
- if self.ignore(event):
- return
- if not self.canvas.widgetlock.available(self):
- return
- if not self.ax.contains(event)[0]:
- self.linev.set_visible(False)
- self.lineh.set_visible(False)
-
- if self.needclear:
- self.canvas.draw()
- self.needclear = False
- return
- self.needclear = True
-
- xdata, ydata = self._get_data_coords(event)
- self.linev.set_xdata((xdata, xdata))
- self.linev.set_visible(self.visible and self.vertOn)
- self.lineh.set_ydata((ydata, ydata))
- self.lineh.set_visible(self.visible and self.horizOn)
-
- if self.visible and (self.vertOn or self.horizOn):
- self._update()
-
- def _update(self):
- if self.useblit:
- if self.background is not None:
- self.canvas.restore_region(self.background)
- self.ax.draw_artist(self.linev)
- self.ax.draw_artist(self.lineh)
- self.canvas.blit(self.ax.bbox)
- else:
- self.canvas.draw_idle()
- return False
-
-
-class MultiCursor(Widget):
- """
- Provide a vertical (default) and/or horizontal line cursor shared between
- multiple Axes.
-
- For the cursor to remain responsive you must keep a reference to it.
-
- Parameters
- ----------
- canvas : object
- This parameter is entirely unused and only kept for back-compatibility.
-
- axes : list of `~matplotlib.axes.Axes`
- The `~.axes.Axes` to attach the cursor to.
-
- useblit : bool, default: True
- Use blitting for faster drawing if supported by the backend.
- See the tutorial :ref:`blitting`
- for details.
-
- horizOn : bool, default: False
- Whether to draw the horizontal line.
-
- vertOn : bool, default: True
- Whether to draw the vertical line.
-
- Other Parameters
- ----------------
- **lineprops
- `.Line2D` properties that control the appearance of the lines.
- See also `~.Axes.axhline`.
-
- Examples
- --------
- See :doc:`/gallery/widgets/multicursor`.
- """
-
- def __init__(self, canvas, axes, *, useblit=True, horizOn=False, vertOn=True,
- **lineprops):
- # canvas is stored only to provide the deprecated .canvas attribute;
- # once it goes away the unused argument won't need to be stored at all.
- self._canvas = canvas
-
- self.axes = axes
- self.horizOn = horizOn
- self.vertOn = vertOn
-
- self._canvas_infos = {
- ax.figure.canvas: {"cids": [], "background": None} for ax in axes}
-
- xmin, xmax = axes[-1].get_xlim()
- ymin, ymax = axes[-1].get_ylim()
- xmid = 0.5 * (xmin + xmax)
- ymid = 0.5 * (ymin + ymax)
-
- self.visible = True
- self.useblit = (
- useblit
- and all(canvas.supports_blit for canvas in self._canvas_infos))
-
- if self.useblit:
- lineprops['animated'] = True
-
- self.vlines = [ax.axvline(xmid, visible=False, **lineprops)
- for ax in axes]
- self.hlines = [ax.axhline(ymid, visible=False, **lineprops)
- for ax in axes]
-
- self.connect()
-
- needclear = _api.deprecated("3.7")(lambda self: False)
-
- def connect(self):
- """Connect events."""
- for canvas, info in self._canvas_infos.items():
- info["cids"] = [
- canvas.mpl_connect('motion_notify_event', self.onmove),
- canvas.mpl_connect('draw_event', self.clear),
- ]
-
- def disconnect(self):
- """Disconnect events."""
- for canvas, info in self._canvas_infos.items():
- for cid in info["cids"]:
- canvas.mpl_disconnect(cid)
- info["cids"].clear()
-
- def clear(self, event):
- """Clear the cursor."""
- if self.ignore(event):
- return
- if self.useblit:
- for canvas, info in self._canvas_infos.items():
- # someone has switched the canvas on us! This happens if
- # `savefig` needs to save to a format the previous backend did
- # not support (e.g. saving a figure using an Agg based backend
- # saved to a vector format).
- if canvas is not canvas.figure.canvas:
- continue
- info["background"] = canvas.copy_from_bbox(canvas.figure.bbox)
-
- def onmove(self, event):
- axs = [ax for ax in self.axes if ax.contains(event)[0]]
- if self.ignore(event) or not axs or not event.canvas.widgetlock.available(self):
- return
- ax = cbook._topmost_artist(axs)
- xdata, ydata = ((event.xdata, event.ydata) if event.inaxes is ax
- else ax.transData.inverted().transform((event.x, event.y)))
- for line in self.vlines:
- line.set_xdata((xdata, xdata))
- line.set_visible(self.visible and self.vertOn)
- for line in self.hlines:
- line.set_ydata((ydata, ydata))
- line.set_visible(self.visible and self.horizOn)
- if self.visible and (self.vertOn or self.horizOn):
- self._update()
-
- def _update(self):
- if self.useblit:
- for canvas, info in self._canvas_infos.items():
- if info["background"]:
- canvas.restore_region(info["background"])
- if self.vertOn:
- for ax, line in zip(self.axes, self.vlines):
- ax.draw_artist(line)
- if self.horizOn:
- for ax, line in zip(self.axes, self.hlines):
- ax.draw_artist(line)
- for canvas in self._canvas_infos:
- canvas.blit()
- else:
- for canvas in self._canvas_infos:
- canvas.draw_idle()
-
-
-class _SelectorWidget(AxesWidget):
-
- def __init__(self, ax, onselect, useblit=False, button=None,
- state_modifier_keys=None, use_data_coordinates=False):
- super().__init__(ax)
-
- self._visible = True
- self.onselect = onselect
- self.useblit = useblit and self.canvas.supports_blit
- self.connect_default_events()
-
- self._state_modifier_keys = dict(move=' ', clear='escape',
- square='shift', center='control',
- rotate='r')
- self._state_modifier_keys.update(state_modifier_keys or {})
- self._use_data_coordinates = use_data_coordinates
-
- self.background = None
-
- if isinstance(button, Integral):
- self.validButtons = [button]
- else:
- self.validButtons = button
-
- # Set to True when a selection is completed, otherwise is False
- self._selection_completed = False
-
- # will save the data (position at mouseclick)
- self._eventpress = None
- # will save the data (pos. at mouserelease)
- self._eventrelease = None
- self._prev_event = None
- self._state = set()
-
- def set_active(self, active):
- super().set_active(active)
- if active:
- self.update_background(None)
-
- def _get_animated_artists(self):
- """
- Convenience method to get all animated artists of the figure containing
- this widget, excluding those already present in self.artists.
- The returned tuple is not sorted by 'z_order': z_order sorting is
- valid only when considering all artists and not only a subset of all
- artists.
- """
- return tuple(a for ax_ in self.ax.get_figure().get_axes()
- for a in ax_.get_children()
- if a.get_animated() and a not in self.artists)
-
- def update_background(self, event):
- """Force an update of the background."""
- # If you add a call to `ignore` here, you'll want to check edge case:
- # `release` can call a draw event even when `ignore` is True.
- if not self.useblit:
- return
- # Make sure that widget artists don't get accidentally included in the
- # background, by re-rendering the background if needed (and then
- # re-re-rendering the canvas with the visible widget artists).
- # We need to remove all artists which will be drawn when updating
- # the selector: if we have animated artists in the figure, it is safer
- # to redrawn by default, in case they have updated by the callback
- # zorder needs to be respected when redrawing
- artists = sorted(self.artists + self._get_animated_artists(),
- key=lambda a: a.get_zorder())
- needs_redraw = any(artist.get_visible() for artist in artists)
- with ExitStack() as stack:
- if needs_redraw:
- for artist in artists:
- stack.enter_context(artist._cm_set(visible=False))
- self.canvas.draw()
- self.background = self.canvas.copy_from_bbox(self.ax.bbox)
- if needs_redraw:
- for artist in artists:
- self.ax.draw_artist(artist)
-
- def connect_default_events(self):
- """Connect the major canvas events to methods."""
- self.connect_event('motion_notify_event', self.onmove)
- self.connect_event('button_press_event', self.press)
- self.connect_event('button_release_event', self.release)
- self.connect_event('draw_event', self.update_background)
- self.connect_event('key_press_event', self.on_key_press)
- self.connect_event('key_release_event', self.on_key_release)
- self.connect_event('scroll_event', self.on_scroll)
-
- def ignore(self, event):
- # docstring inherited
- if not self.active or not self.ax.get_visible():
- return True
- # If canvas was locked
- if not self.canvas.widgetlock.available(self):
- return True
- if not hasattr(event, 'button'):
- event.button = None
- # Only do rectangle selection if event was triggered
- # with a desired button
- if (self.validButtons is not None
- and event.button not in self.validButtons):
- return True
- # If no button was pressed yet ignore the event if it was out of the Axes.
- if self._eventpress is None:
- return not self.ax.contains(event)[0]
- # If a button was pressed, check if the release-button is the same.
- if event.button == self._eventpress.button:
- return False
- # If a button was pressed, check if the release-button is the same.
- return (not self.ax.contains(event)[0] or
- event.button != self._eventpress.button)
-
- def update(self):
- """Draw using blit() or draw_idle(), depending on ``self.useblit``."""
- if (not self.ax.get_visible() or
- self.ax.figure._get_renderer() is None):
- return
- if self.useblit:
- if self.background is not None:
- self.canvas.restore_region(self.background)
- else:
- self.update_background(None)
- # We need to draw all artists, which are not included in the
- # background, therefore we also draw self._get_animated_artists()
- # and we make sure that we respect z_order
- artists = sorted(self.artists + self._get_animated_artists(),
- key=lambda a: a.get_zorder())
- for artist in artists:
- self.ax.draw_artist(artist)
- self.canvas.blit(self.ax.bbox)
- else:
- self.canvas.draw_idle()
-
- def _get_data(self, event):
- """Get the xdata and ydata for event, with limits."""
- if event.xdata is None:
- return None, None
- xdata, ydata = self._get_data_coords(event)
- xdata = np.clip(xdata, *self.ax.get_xbound())
- ydata = np.clip(ydata, *self.ax.get_ybound())
- return xdata, ydata
-
- def _clean_event(self, event):
- """
- Preprocess an event:
-
- - Replace *event* by the previous event if *event* has no ``xdata``.
- - Get ``xdata`` and ``ydata`` from this widget's axes, and clip them to the axes
- limits.
- - Update the previous event.
- """
- if event.xdata is None:
- event = self._prev_event
- else:
- event = copy.copy(event)
- event.xdata, event.ydata = self._get_data(event)
- self._prev_event = event
- return event
-
- def press(self, event):
- """Button press handler and validator."""
- if not self.ignore(event):
- event = self._clean_event(event)
- self._eventpress = event
- self._prev_event = event
- key = event.key or ''
- key = key.replace('ctrl', 'control')
- # move state is locked in on a button press
- if key == self._state_modifier_keys['move']:
- self._state.add('move')
- self._press(event)
- return True
- return False
-
- def _press(self, event):
- """Button press event handler."""
-
- def release(self, event):
- """Button release event handler and validator."""
- if not self.ignore(event) and self._eventpress:
- event = self._clean_event(event)
- self._eventrelease = event
- self._release(event)
- self._eventpress = None
- self._eventrelease = None
- self._state.discard('move')
- return True
- return False
-
- def _release(self, event):
- """Button release event handler."""
-
- def onmove(self, event):
- """Cursor move event handler and validator."""
- if not self.ignore(event) and self._eventpress:
- event = self._clean_event(event)
- self._onmove(event)
- return True
- return False
-
- def _onmove(self, event):
- """Cursor move event handler."""
-
- def on_scroll(self, event):
- """Mouse scroll event handler and validator."""
- if not self.ignore(event):
- self._on_scroll(event)
-
- def _on_scroll(self, event):
- """Mouse scroll event handler."""
-
- def on_key_press(self, event):
- """Key press event handler and validator for all selection widgets."""
- if self.active:
- key = event.key or ''
- key = key.replace('ctrl', 'control')
- if key == self._state_modifier_keys['clear']:
- self.clear()
- return
- for (state, modifier) in self._state_modifier_keys.items():
- if modifier in key.split('+'):
- # 'rotate' is changing _state on press and is not removed
- # from _state when releasing
- if state == 'rotate':
- if state in self._state:
- self._state.discard(state)
- else:
- self._state.add(state)
- else:
- self._state.add(state)
- self._on_key_press(event)
-
- def _on_key_press(self, event):
- """Key press event handler - for widget-specific key press actions."""
-
- def on_key_release(self, event):
- """Key release event handler and validator."""
- if self.active:
- key = event.key or ''
- for (state, modifier) in self._state_modifier_keys.items():
- # 'rotate' is changing _state on press and is not removed
- # from _state when releasing
- if modifier in key.split('+') and state != 'rotate':
- self._state.discard(state)
- self._on_key_release(event)
-
- def _on_key_release(self, event):
- """Key release event handler."""
-
- def set_visible(self, visible):
- """Set the visibility of the selector artists."""
- self._visible = visible
- for artist in self.artists:
- artist.set_visible(visible)
-
- def get_visible(self):
- """Get the visibility of the selector artists."""
- return self._visible
-
- @property
- def visible(self):
- _api.warn_deprecated("3.8", alternative="get_visible")
- return self.get_visible()
-
- def clear(self):
- """Clear the selection and set the selector ready to make a new one."""
- self._clear_without_update()
- self.update()
-
- def _clear_without_update(self):
- self._selection_completed = False
- self.set_visible(False)
-
- @property
- def artists(self):
- """Tuple of the artists of the selector."""
- handles_artists = getattr(self, '_handles_artists', ())
- return (self._selection_artist,) + handles_artists
-
- def set_props(self, **props):
- """
- Set the properties of the selector artist.
-
- See the *props* argument in the selector docstring to know which properties are
- supported.
- """
- artist = self._selection_artist
- props = cbook.normalize_kwargs(props, artist)
- artist.set(**props)
- if self.useblit:
- self.update()
-
- def set_handle_props(self, **handle_props):
- """
- Set the properties of the handles selector artist. See the
- `handle_props` argument in the selector docstring to know which
- properties are supported.
- """
- if not hasattr(self, '_handles_artists'):
- raise NotImplementedError("This selector doesn't have handles.")
-
- artist = self._handles_artists[0]
- handle_props = cbook.normalize_kwargs(handle_props, artist)
- for handle in self._handles_artists:
- handle.set(**handle_props)
- if self.useblit:
- self.update()
- self._handle_props.update(handle_props)
-
- def _validate_state(self, state):
- supported_state = [
- key for key, value in self._state_modifier_keys.items()
- if key != 'clear' and value != 'not-applicable'
- ]
- _api.check_in_list(supported_state, state=state)
-
- def add_state(self, state):
- """
- Add a state to define the widget's behavior. See the
- `state_modifier_keys` parameters for details.
-
- Parameters
- ----------
- state : str
- Must be a supported state of the selector. See the
- `state_modifier_keys` parameters for details.
-
- Raises
- ------
- ValueError
- When the state is not supported by the selector.
-
- """
- self._validate_state(state)
- self._state.add(state)
-
- def remove_state(self, state):
- """
- Remove a state to define the widget's behavior. See the
- `state_modifier_keys` parameters for details.
-
- Parameters
- ----------
- state : str
- Must be a supported state of the selector. See the
- `state_modifier_keys` parameters for details.
-
- Raises
- ------
- ValueError
- When the state is not supported by the selector.
-
- """
- self._validate_state(state)
- self._state.remove(state)
-
-
-class SpanSelector(_SelectorWidget):
- """
- Visually select a min/max range on a single axis and call a function with
- those values.
-
- To guarantee that the selector remains responsive, keep a reference to it.
-
- In order to turn off the SpanSelector, set ``span_selector.active`` to
- False. To turn it back on, set it to True.
-
- Press and release events triggered at the same coordinates outside the
- selection will clear the selector, except when
- ``ignore_event_outside=True``.
-
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
-
- onselect : callable with signature ``func(min: float, max: float)``
- A callback function that is called after a release event and the
- selection is created, changed or removed.
-
- direction : {"horizontal", "vertical"}
- The direction along which to draw the span selector.
-
- minspan : float, default: 0
- If selection is less than or equal to *minspan*, the selection is
- removed (when already existing) or cancelled.
-
- useblit : bool, default: False
- If True, use the backend-dependent blitting features for faster
- canvas updates. See the tutorial :ref:`blitting` for details.
-
- props : dict, default: {'facecolor': 'red', 'alpha': 0.5}
- Dictionary of `.Patch` properties.
-
- onmove_callback : callable with signature ``func(min: float, max: float)``, optional
- Called on mouse move while the span is being selected.
-
- interactive : bool, default: False
- Whether to draw a set of handles that allow interaction with the
- widget after it is drawn.
-
- button : `.MouseButton` or list of `.MouseButton`, default: all buttons
- The mouse buttons which activate the span selector.
-
- handle_props : dict, default: None
- Properties of the handle lines at the edges of the span. Only used
- when *interactive* is True. See `.Line2D` for valid properties.
-
- grab_range : float, default: 10
- Distance in pixels within which the interactive tool handles can be activated.
-
- state_modifier_keys : dict, optional
- Keyboard modifiers which affect the widget's behavior. Values
- amend the defaults, which are:
-
- - "clear": Clear the current shape, default: "escape".
-
- drag_from_anywhere : bool, default: False
- If `True`, the widget can be moved by clicking anywhere within its bounds.
-
- ignore_event_outside : bool, default: False
- If `True`, the event triggered outside the span selector will be ignored.
-
- snap_values : 1D array-like, optional
- Snap the selector edges to the given values.
-
- Examples
- --------
- >>> import matplotlib.pyplot as plt
- >>> import matplotlib.widgets as mwidgets
- >>> fig, ax = plt.subplots()
- >>> ax.plot([1, 2, 3], [10, 50, 100])
- >>> def onselect(vmin, vmax):
- ... print(vmin, vmax)
- >>> span = mwidgets.SpanSelector(ax, onselect, 'horizontal',
- ... props=dict(facecolor='blue', alpha=0.5))
- >>> fig.show()
-
- See also: :doc:`/gallery/widgets/span_selector`
- """
-
- @_api.make_keyword_only("3.7", name="minspan")
- def __init__(self, ax, onselect, direction, minspan=0, useblit=False,
- props=None, onmove_callback=None, interactive=False,
- button=None, handle_props=None, grab_range=10,
- state_modifier_keys=None, drag_from_anywhere=False,
- ignore_event_outside=False, snap_values=None):
-
- if state_modifier_keys is None:
- state_modifier_keys = dict(clear='escape',
- square='not-applicable',
- center='not-applicable',
- rotate='not-applicable')
- super().__init__(ax, onselect, useblit=useblit, button=button,
- state_modifier_keys=state_modifier_keys)
-
- if props is None:
- props = dict(facecolor='red', alpha=0.5)
-
- props['animated'] = self.useblit
-
- self.direction = direction
- self._extents_on_press = None
- self.snap_values = snap_values
-
- self.onmove_callback = onmove_callback
- self.minspan = minspan
-
- self.grab_range = grab_range
- self._interactive = interactive
- self._edge_handles = None
- self.drag_from_anywhere = drag_from_anywhere
- self.ignore_event_outside = ignore_event_outside
-
- # Reset canvas so that `new_axes` connects events.
- self.canvas = None
- self.new_axes(ax, _props=props)
-
- # Setup handles
- self._handle_props = {
- 'color': props.get('facecolor', 'r'),
- **cbook.normalize_kwargs(handle_props, Line2D)}
-
- if self._interactive:
- self._edge_order = ['min', 'max']
- self._setup_edge_handles(self._handle_props)
-
- self._active_handle = None
-
- def new_axes(self, ax, *, _props=None):
- """Set SpanSelector to operate on a new Axes."""
- self.ax = ax
- if self.canvas is not ax.figure.canvas:
- if self.canvas is not None:
- self.disconnect_events()
-
- self.canvas = ax.figure.canvas
- self.connect_default_events()
-
- # Reset
- self._selection_completed = False
-
- if self.direction == 'horizontal':
- trans = ax.get_xaxis_transform()
- w, h = 0, 1
- else:
- trans = ax.get_yaxis_transform()
- w, h = 1, 0
- rect_artist = Rectangle((0, 0), w, h, transform=trans, visible=False)
- if _props is not None:
- rect_artist.update(_props)
- elif self._selection_artist is not None:
- rect_artist.update_from(self._selection_artist)
-
- self.ax.add_patch(rect_artist)
- self._selection_artist = rect_artist
-
- def _setup_edge_handles(self, props):
- # Define initial position using the axis bounds to keep the same bounds
- if self.direction == 'horizontal':
- positions = self.ax.get_xbound()
- else:
- positions = self.ax.get_ybound()
- self._edge_handles = ToolLineHandles(self.ax, positions,
- direction=self.direction,
- line_props=props,
- useblit=self.useblit)
-
- @property
- def _handles_artists(self):
- if self._edge_handles is not None:
- return self._edge_handles.artists
- else:
- return ()
-
- def _set_cursor(self, enabled):
- """Update the canvas cursor based on direction of the selector."""
- if enabled:
- cursor = (backend_tools.Cursors.RESIZE_HORIZONTAL
- if self.direction == 'horizontal' else
- backend_tools.Cursors.RESIZE_VERTICAL)
- else:
- cursor = backend_tools.Cursors.POINTER
-
- self.ax.figure.canvas.set_cursor(cursor)
-
- def connect_default_events(self):
- # docstring inherited
- super().connect_default_events()
- if getattr(self, '_interactive', False):
- self.connect_event('motion_notify_event', self._hover)
-
- def _press(self, event):
- """Button press event handler."""
- self._set_cursor(True)
- if self._interactive and self._selection_artist.get_visible():
- self._set_active_handle(event)
- else:
- self._active_handle = None
-
- if self._active_handle is None or not self._interactive:
- # Clear previous rectangle before drawing new rectangle.
- self.update()
-
- xdata, ydata = self._get_data_coords(event)
- v = xdata if self.direction == 'horizontal' else ydata
-
- if self._active_handle is None and not self.ignore_event_outside:
- # when the press event outside the span, we initially set the
- # visibility to False and extents to (v, v)
- # update will be called when setting the extents
- self._visible = False
- self.extents = v, v
- # We need to set the visibility back, so the span selector will be
- # drawn when necessary (span width > 0)
- self._visible = True
- else:
- self.set_visible(True)
-
- return False
-
- @property
- def direction(self):
- """Direction of the span selector: 'vertical' or 'horizontal'."""
- return self._direction
-
- @direction.setter
- def direction(self, direction):
- """Set the direction of the span selector."""
- _api.check_in_list(['horizontal', 'vertical'], direction=direction)
- if hasattr(self, '_direction') and direction != self._direction:
- # remove previous artists
- self._selection_artist.remove()
- if self._interactive:
- self._edge_handles.remove()
- self._direction = direction
- self.new_axes(self.ax)
- if self._interactive:
- self._setup_edge_handles(self._handle_props)
- else:
- self._direction = direction
-
- def _release(self, event):
- """Button release event handler."""
- self._set_cursor(False)
-
- if not self._interactive:
- self._selection_artist.set_visible(False)
-
- if (self._active_handle is None and self._selection_completed and
- self.ignore_event_outside):
- return
-
- vmin, vmax = self.extents
- span = vmax - vmin
-
- if span <= self.minspan:
- # Remove span and set self._selection_completed = False
- self.set_visible(False)
- if self._selection_completed:
- # Call onselect, only when the span is already existing
- self.onselect(vmin, vmax)
- self._selection_completed = False
- else:
- self.onselect(vmin, vmax)
- self._selection_completed = True
-
- self.update()
-
- self._active_handle = None
-
- return False
-
- def _hover(self, event):
- """Update the canvas cursor if it's over a handle."""
- if self.ignore(event):
- return
-
- if self._active_handle is not None or not self._selection_completed:
- # Do nothing if button is pressed and a handle is active, which may
- # occur with drag_from_anywhere=True.
- # Do nothing if selection is not completed, which occurs when
- # a selector has been cleared
- return
-
- _, e_dist = self._edge_handles.closest(event.x, event.y)
- self._set_cursor(e_dist <= self.grab_range)
-
- def _onmove(self, event):
- """Motion notify event handler."""
-
- xdata, ydata = self._get_data_coords(event)
- if self.direction == 'horizontal':
- v = xdata
- vpress = self._eventpress.xdata
- else:
- v = ydata
- vpress = self._eventpress.ydata
-
- # move existing span
- # When "dragging from anywhere", `self._active_handle` is set to 'C'
- # (match notation used in the RectangleSelector)
- if self._active_handle == 'C' and self._extents_on_press is not None:
- vmin, vmax = self._extents_on_press
- dv = v - vpress
- vmin += dv
- vmax += dv
-
- # resize an existing shape
- elif self._active_handle and self._active_handle != 'C':
- vmin, vmax = self._extents_on_press
- if self._active_handle == 'min':
- vmin = v
- else:
- vmax = v
- # new shape
- else:
- # Don't create a new span if there is already one when
- # ignore_event_outside=True
- if self.ignore_event_outside and self._selection_completed:
- return
- vmin, vmax = vpress, v
- if vmin > vmax:
- vmin, vmax = vmax, vmin
-
- self.extents = vmin, vmax
-
- if self.onmove_callback is not None:
- self.onmove_callback(vmin, vmax)
-
- return False
-
- def _draw_shape(self, vmin, vmax):
- if vmin > vmax:
- vmin, vmax = vmax, vmin
- if self.direction == 'horizontal':
- self._selection_artist.set_x(vmin)
- self._selection_artist.set_width(vmax - vmin)
- else:
- self._selection_artist.set_y(vmin)
- self._selection_artist.set_height(vmax - vmin)
-
- def _set_active_handle(self, event):
- """Set active handle based on the location of the mouse event."""
- # Note: event.xdata/ydata in data coordinates, event.x/y in pixels
- e_idx, e_dist = self._edge_handles.closest(event.x, event.y)
-
- # Prioritise center handle over other handles
- # Use 'C' to match the notation used in the RectangleSelector
- if 'move' in self._state:
- self._active_handle = 'C'
- elif e_dist > self.grab_range:
- # Not close to any handles
- self._active_handle = None
- if self.drag_from_anywhere and self._contains(event):
- # Check if we've clicked inside the region
- self._active_handle = 'C'
- self._extents_on_press = self.extents
- else:
- self._active_handle = None
- return
- else:
- # Closest to an edge handle
- self._active_handle = self._edge_order[e_idx]
-
- # Save coordinates of rectangle at the start of handle movement.
- self._extents_on_press = self.extents
-
- def _contains(self, event):
- """Return True if event is within the patch."""
- return self._selection_artist.contains(event, radius=0)[0]
-
- @staticmethod
- def _snap(values, snap_values):
- """Snap values to a given array values (snap_values)."""
- # take into account machine precision
- eps = np.min(np.abs(np.diff(snap_values))) * 1e-12
- return tuple(
- snap_values[np.abs(snap_values - v + np.sign(v) * eps).argmin()]
- for v in values)
-
- @property
- def extents(self):
- """Return extents of the span selector."""
- if self.direction == 'horizontal':
- vmin = self._selection_artist.get_x()
- vmax = vmin + self._selection_artist.get_width()
- else:
- vmin = self._selection_artist.get_y()
- vmax = vmin + self._selection_artist.get_height()
- return vmin, vmax
-
- @extents.setter
- def extents(self, extents):
- # Update displayed shape
- if self.snap_values is not None:
- extents = tuple(self._snap(extents, self.snap_values))
- self._draw_shape(*extents)
- if self._interactive:
- # Update displayed handles
- self._edge_handles.set_data(self.extents)
- self.set_visible(self._visible)
- self.update()
-
-
-class ToolLineHandles:
- """
- Control handles for canvas tools.
-
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- Matplotlib Axes where tool handles are displayed.
- positions : 1D array
- Positions of handles in data coordinates.
- direction : {"horizontal", "vertical"}
- Direction of handles, either 'vertical' or 'horizontal'
- line_props : dict, optional
- Additional line properties. See `.Line2D`.
- useblit : bool, default: True
- Whether to use blitting for faster drawing (if supported by the
- backend). See the tutorial :ref:`blitting`
- for details.
- """
-
- @_api.make_keyword_only("3.7", "line_props")
- def __init__(self, ax, positions, direction, line_props=None,
- useblit=True):
- self.ax = ax
-
- _api.check_in_list(['horizontal', 'vertical'], direction=direction)
- self._direction = direction
-
- line_props = {
- **(line_props if line_props is not None else {}),
- 'visible': False,
- 'animated': useblit,
- }
-
- line_fun = ax.axvline if self.direction == 'horizontal' else ax.axhline
-
- self._artists = [line_fun(p, **line_props) for p in positions]
-
- @property
- def artists(self):
- return tuple(self._artists)
-
- @property
- def positions(self):
- """Positions of the handle in data coordinates."""
- method = 'get_xdata' if self.direction == 'horizontal' else 'get_ydata'
- return [getattr(line, method)()[0] for line in self.artists]
-
- @property
- def direction(self):
- """Direction of the handle: 'vertical' or 'horizontal'."""
- return self._direction
-
- def set_data(self, positions):
- """
- Set x- or y-positions of handles, depending on if the lines are
- vertical or horizontal.
-
- Parameters
- ----------
- positions : tuple of length 2
- Set the positions of the handle in data coordinates
- """
- method = 'set_xdata' if self.direction == 'horizontal' else 'set_ydata'
- for line, p in zip(self.artists, positions):
- getattr(line, method)([p, p])
-
- def set_visible(self, value):
- """Set the visibility state of the handles artist."""
- for artist in self.artists:
- artist.set_visible(value)
-
- def set_animated(self, value):
- """Set the animated state of the handles artist."""
- for artist in self.artists:
- artist.set_animated(value)
-
- def remove(self):
- """Remove the handles artist from the figure."""
- for artist in self._artists:
- artist.remove()
-
- def closest(self, x, y):
- """
- Return index and pixel distance to closest handle.
-
- Parameters
- ----------
- x, y : float
- x, y position from which the distance will be calculated to
- determinate the closest handle
-
- Returns
- -------
- index, distance : index of the handle and its distance from
- position x, y
- """
- if self.direction == 'horizontal':
- p_pts = np.array([
- self.ax.transData.transform((p, 0))[0] for p in self.positions
- ])
- dist = abs(p_pts - x)
- else:
- p_pts = np.array([
- self.ax.transData.transform((0, p))[1] for p in self.positions
- ])
- dist = abs(p_pts - y)
- index = np.argmin(dist)
- return index, dist[index]
-
-
-class ToolHandles:
- """
- Control handles for canvas tools.
-
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- Matplotlib Axes where tool handles are displayed.
- x, y : 1D arrays
- Coordinates of control handles.
- marker : str, default: 'o'
- Shape of marker used to display handle. See `~.pyplot.plot`.
- marker_props : dict, optional
- Additional marker properties. See `.Line2D`.
- useblit : bool, default: True
- Whether to use blitting for faster drawing (if supported by the
- backend). See the tutorial :ref:`blitting`
- for details.
- """
-
- @_api.make_keyword_only("3.7", "marker")
- def __init__(self, ax, x, y, marker='o', marker_props=None, useblit=True):
- self.ax = ax
- props = {'marker': marker, 'markersize': 7, 'markerfacecolor': 'w',
- 'linestyle': 'none', 'alpha': 0.5, 'visible': False,
- 'label': '_nolegend_',
- **cbook.normalize_kwargs(marker_props, Line2D._alias_map)}
- self._markers = Line2D(x, y, animated=useblit, **props)
- self.ax.add_line(self._markers)
-
- @property
- def x(self):
- return self._markers.get_xdata()
-
- @property
- def y(self):
- return self._markers.get_ydata()
-
- @property
- def artists(self):
- return (self._markers, )
-
- def set_data(self, pts, y=None):
- """Set x and y positions of handles."""
- if y is not None:
- x = pts
- pts = np.array([x, y])
- self._markers.set_data(pts)
-
- def set_visible(self, val):
- self._markers.set_visible(val)
-
- def set_animated(self, val):
- self._markers.set_animated(val)
-
- def closest(self, x, y):
- """Return index and pixel distance to closest index."""
- pts = np.column_stack([self.x, self.y])
- # Transform data coordinates to pixel coordinates.
- pts = self.ax.transData.transform(pts)
- diff = pts - [x, y]
- dist = np.hypot(*diff.T)
- min_index = np.argmin(dist)
- return min_index, dist[min_index]
-
-
-_RECTANGLESELECTOR_PARAMETERS_DOCSTRING = \
- r"""
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The parent axes for the widget.
-
- onselect : function
- A callback function that is called after a release event and the
- selection is created, changed or removed.
- It must have the signature::
-
- def onselect(eclick: MouseEvent, erelease: MouseEvent)
-
- where *eclick* and *erelease* are the mouse click and release
- `.MouseEvent`\s that start and complete the selection.
-
- minspanx : float, default: 0
- Selections with an x-span less than or equal to *minspanx* are removed
- (when already existing) or cancelled.
-
- minspany : float, default: 0
- Selections with an y-span less than or equal to *minspanx* are removed
- (when already existing) or cancelled.
-
- useblit : bool, default: False
- Whether to use blitting for faster drawing (if supported by the
- backend). See the tutorial :ref:`blitting`
- for details.
-
- props : dict, optional
- Properties with which the __ARTIST_NAME__ is drawn. See
- `.Patch` for valid properties.
- Default:
-
- ``dict(facecolor='red', edgecolor='black', alpha=0.2, fill=True)``
-
- spancoords : {"data", "pixels"}, default: "data"
- Whether to interpret *minspanx* and *minspany* in data or in pixel
- coordinates.
-
- button : `.MouseButton`, list of `.MouseButton`, default: all buttons
- Button(s) that trigger rectangle selection.
-
- grab_range : float, default: 10
- Distance in pixels within which the interactive tool handles can be
- activated.
-
- handle_props : dict, optional
- Properties with which the interactive handles (marker artists) are
- drawn. See the marker arguments in `.Line2D` for valid
- properties. Default values are defined in ``mpl.rcParams`` except for
- the default value of ``markeredgecolor`` which will be the same as the
- ``edgecolor`` property in *props*.
-
- interactive : bool, default: False
- Whether to draw a set of handles that allow interaction with the
- widget after it is drawn.
-
- state_modifier_keys : dict, optional
- Keyboard modifiers which affect the widget's behavior. Values
- amend the defaults, which are:
-
- - "move": Move the existing shape, default: no modifier.
- - "clear": Clear the current shape, default: "escape".
- - "square": Make the shape square, default: "shift".
- - "center": change the shape around its center, default: "ctrl".
- - "rotate": Rotate the shape around its center between -45° and 45°,
- default: "r".
-
- "square" and "center" can be combined. The square shape can be defined
- in data or display coordinates as determined by the
- ``use_data_coordinates`` argument specified when creating the selector.
-
- drag_from_anywhere : bool, default: False
- If `True`, the widget can be moved by clicking anywhere within
- its bounds.
-
- ignore_event_outside : bool, default: False
- If `True`, the event triggered outside the span selector will be
- ignored.
-
- use_data_coordinates : bool, default: False
- If `True`, the "square" shape of the selector is defined in
- data coordinates instead of display coordinates.
- """
-
-
-@_docstring.Substitution(_RECTANGLESELECTOR_PARAMETERS_DOCSTRING.replace(
- '__ARTIST_NAME__', 'rectangle'))
-class RectangleSelector(_SelectorWidget):
- """
- Select a rectangular region of an Axes.
-
- For the cursor to remain responsive you must keep a reference to it.
-
- Press and release events triggered at the same coordinates outside the
- selection will clear the selector, except when
- ``ignore_event_outside=True``.
-
- %s
-
- Examples
- --------
- >>> import matplotlib.pyplot as plt
- >>> import matplotlib.widgets as mwidgets
- >>> fig, ax = plt.subplots()
- >>> ax.plot([1, 2, 3], [10, 50, 100])
- >>> def onselect(eclick, erelease):
- ... print(eclick.xdata, eclick.ydata)
- ... print(erelease.xdata, erelease.ydata)
- >>> props = dict(facecolor='blue', alpha=0.5)
- >>> rect = mwidgets.RectangleSelector(ax, onselect, interactive=True,
- ... props=props)
- >>> fig.show()
- >>> rect.add_state('square')
-
- See also: :doc:`/gallery/widgets/rectangle_selector`
- """
-
- def __init__(self, ax, onselect, *, minspanx=0, minspany=0, useblit=False,
- props=None, spancoords='data', button=None, grab_range=10,
- handle_props=None, interactive=False,
- state_modifier_keys=None, drag_from_anywhere=False,
- ignore_event_outside=False, use_data_coordinates=False):
- super().__init__(ax, onselect, useblit=useblit, button=button,
- state_modifier_keys=state_modifier_keys,
- use_data_coordinates=use_data_coordinates)
-
- self._interactive = interactive
- self.drag_from_anywhere = drag_from_anywhere
- self.ignore_event_outside = ignore_event_outside
- self._rotation = 0.0
- self._aspect_ratio_correction = 1.0
-
- # State to allow the option of an interactive selector that can't be
- # interactively drawn. This is used in PolygonSelector as an
- # interactive bounding box to allow the polygon to be easily resized
- self._allow_creation = True
-
- if props is None:
- props = dict(facecolor='red', edgecolor='black',
- alpha=0.2, fill=True)
- props = {**props, 'animated': self.useblit}
- self._visible = props.pop('visible', self._visible)
- to_draw = self._init_shape(**props)
- self.ax.add_patch(to_draw)
-
- self._selection_artist = to_draw
- self._set_aspect_ratio_correction()
-
- self.minspanx = minspanx
- self.minspany = minspany
-
- _api.check_in_list(['data', 'pixels'], spancoords=spancoords)
- self.spancoords = spancoords
-
- self.grab_range = grab_range
-
- if self._interactive:
- self._handle_props = {
- 'markeredgecolor': (props or {}).get('edgecolor', 'black'),
- **cbook.normalize_kwargs(handle_props, Line2D)}
-
- self._corner_order = ['SW', 'SE', 'NE', 'NW']
- xc, yc = self.corners
- self._corner_handles = ToolHandles(self.ax, xc, yc,
- marker_props=self._handle_props,
- useblit=self.useblit)
-
- self._edge_order = ['W', 'S', 'E', 'N']
- xe, ye = self.edge_centers
- self._edge_handles = ToolHandles(self.ax, xe, ye, marker='s',
- marker_props=self._handle_props,
- useblit=self.useblit)
-
- xc, yc = self.center
- self._center_handle = ToolHandles(self.ax, [xc], [yc], marker='s',
- marker_props=self._handle_props,
- useblit=self.useblit)
-
- self._active_handle = None
-
- self._extents_on_press = None
-
- @property
- def _handles_artists(self):
- return (*self._center_handle.artists, *self._corner_handles.artists,
- *self._edge_handles.artists)
-
- def _init_shape(self, **props):
- return Rectangle((0, 0), 0, 1, visible=False,
- rotation_point='center', **props)
-
- def _press(self, event):
- """Button press event handler."""
- # make the drawn box/line visible get the click-coordinates, button, ...
- if self._interactive and self._selection_artist.get_visible():
- self._set_active_handle(event)
- else:
- self._active_handle = None
-
- if ((self._active_handle is None or not self._interactive) and
- self._allow_creation):
- # Clear previous rectangle before drawing new rectangle.
- self.update()
-
- if (self._active_handle is None and not self.ignore_event_outside and
- self._allow_creation):
- x, y = self._get_data_coords(event)
- self._visible = False
- self.extents = x, x, y, y
- self._visible = True
- else:
- self.set_visible(True)
-
- self._extents_on_press = self.extents
- self._rotation_on_press = self._rotation
- self._set_aspect_ratio_correction()
-
- return False
-
- def _release(self, event):
- """Button release event handler."""
- if not self._interactive:
- self._selection_artist.set_visible(False)
-
- if (self._active_handle is None and self._selection_completed and
- self.ignore_event_outside):
- return
-
- # update the eventpress and eventrelease with the resulting extents
- x0, x1, y0, y1 = self.extents
- self._eventpress.xdata = x0
- self._eventpress.ydata = y0
- xy0 = self.ax.transData.transform([x0, y0])
- self._eventpress.x, self._eventpress.y = xy0
-
- self._eventrelease.xdata = x1
- self._eventrelease.ydata = y1
- xy1 = self.ax.transData.transform([x1, y1])
- self._eventrelease.x, self._eventrelease.y = xy1
-
- # calculate dimensions of box or line
- if self.spancoords == 'data':
- spanx = abs(self._eventpress.xdata - self._eventrelease.xdata)
- spany = abs(self._eventpress.ydata - self._eventrelease.ydata)
- elif self.spancoords == 'pixels':
- spanx = abs(self._eventpress.x - self._eventrelease.x)
- spany = abs(self._eventpress.y - self._eventrelease.y)
- else:
- _api.check_in_list(['data', 'pixels'],
- spancoords=self.spancoords)
- # check if drawn distance (if it exists) is not too small in
- # either x or y-direction
- if spanx <= self.minspanx or spany <= self.minspany:
- if self._selection_completed:
- # Call onselect, only when the selection is already existing
- self.onselect(self._eventpress, self._eventrelease)
- self._clear_without_update()
- else:
- self.onselect(self._eventpress, self._eventrelease)
- self._selection_completed = True
-
- self.update()
- self._active_handle = None
- self._extents_on_press = None
-
- return False
-
- def _onmove(self, event):
- """
- Motion notify event handler.
-
- This can do one of four things:
- - Translate
- - Rotate
- - Re-size
- - Continue the creation of a new shape
- """
- eventpress = self._eventpress
- # The calculations are done for rotation at zero: we apply inverse
- # transformation to events except when we rotate and move
- state = self._state
- rotate = 'rotate' in state and self._active_handle in self._corner_order
- move = self._active_handle == 'C'
- resize = self._active_handle and not move
-
- xdata, ydata = self._get_data_coords(event)
- if resize:
- inv_tr = self._get_rotation_transform().inverted()
- xdata, ydata = inv_tr.transform([xdata, ydata])
- eventpress.xdata, eventpress.ydata = inv_tr.transform(
- (eventpress.xdata, eventpress.ydata))
-
- dx = xdata - eventpress.xdata
- dy = ydata - eventpress.ydata
- # refmax is used when moving the corner handle with the square state
- # and is the maximum between refx and refy
- refmax = None
- if self._use_data_coordinates:
- refx, refy = dx, dy
- else:
- # Get dx/dy in display coordinates
- refx = event.x - eventpress.x
- refy = event.y - eventpress.y
-
- x0, x1, y0, y1 = self._extents_on_press
- # rotate an existing shape
- if rotate:
- # calculate angle abc
- a = (eventpress.xdata, eventpress.ydata)
- b = self.center
- c = (xdata, ydata)
- angle = (np.arctan2(c[1]-b[1], c[0]-b[0]) -
- np.arctan2(a[1]-b[1], a[0]-b[0]))
- self.rotation = np.rad2deg(self._rotation_on_press + angle)
-
- elif resize:
- size_on_press = [x1 - x0, y1 - y0]
- center = (x0 + size_on_press[0] / 2, y0 + size_on_press[1] / 2)
-
- # Keeping the center fixed
- if 'center' in state:
- # hh, hw are half-height and half-width
- if 'square' in state:
- # when using a corner, find which reference to use
- if self._active_handle in self._corner_order:
- refmax = max(refx, refy, key=abs)
- if self._active_handle in ['E', 'W'] or refmax == refx:
- hw = xdata - center[0]
- hh = hw / self._aspect_ratio_correction
- else:
- hh = ydata - center[1]
- hw = hh * self._aspect_ratio_correction
- else:
- hw = size_on_press[0] / 2
- hh = size_on_press[1] / 2
- # cancel changes in perpendicular direction
- if self._active_handle in ['E', 'W'] + self._corner_order:
- hw = abs(xdata - center[0])
- if self._active_handle in ['N', 'S'] + self._corner_order:
- hh = abs(ydata - center[1])
-
- x0, x1, y0, y1 = (center[0] - hw, center[0] + hw,
- center[1] - hh, center[1] + hh)
-
- else:
- # change sign of relative changes to simplify calculation
- # Switch variables so that x1 and/or y1 are updated on move
- if 'W' in self._active_handle:
- x0 = x1
- if 'S' in self._active_handle:
- y0 = y1
- if self._active_handle in ['E', 'W'] + self._corner_order:
- x1 = xdata
- if self._active_handle in ['N', 'S'] + self._corner_order:
- y1 = ydata
- if 'square' in state:
- # when using a corner, find which reference to use
- if self._active_handle in self._corner_order:
- refmax = max(refx, refy, key=abs)
- if self._active_handle in ['E', 'W'] or refmax == refx:
- sign = np.sign(ydata - y0)
- y1 = y0 + sign * abs(x1 - x0) / self._aspect_ratio_correction
- else:
- sign = np.sign(xdata - x0)
- x1 = x0 + sign * abs(y1 - y0) * self._aspect_ratio_correction
-
- elif move:
- x0, x1, y0, y1 = self._extents_on_press
- dx = xdata - eventpress.xdata
- dy = ydata - eventpress.ydata
- x0 += dx
- x1 += dx
- y0 += dy
- y1 += dy
-
- else:
- # Create a new shape
- self._rotation = 0
- # Don't create a new rectangle if there is already one when
- # ignore_event_outside=True
- if ((self.ignore_event_outside and self._selection_completed) or
- not self._allow_creation):
- return
- center = [eventpress.xdata, eventpress.ydata]
- dx = (xdata - center[0]) / 2
- dy = (ydata - center[1]) / 2
-
- # square shape
- if 'square' in state:
- refmax = max(refx, refy, key=abs)
- if refmax == refx:
- dy = np.sign(dy) * abs(dx) / self._aspect_ratio_correction
- else:
- dx = np.sign(dx) * abs(dy) * self._aspect_ratio_correction
-
- # from center
- if 'center' in state:
- dx *= 2
- dy *= 2
-
- # from corner
- else:
- center[0] += dx
- center[1] += dy
-
- x0, x1, y0, y1 = (center[0] - dx, center[0] + dx,
- center[1] - dy, center[1] + dy)
-
- self.extents = x0, x1, y0, y1
-
- @property
- def _rect_bbox(self):
- return self._selection_artist.get_bbox().bounds
-
- def _set_aspect_ratio_correction(self):
- aspect_ratio = self.ax._get_aspect_ratio()
- self._selection_artist._aspect_ratio_correction = aspect_ratio
- if self._use_data_coordinates:
- self._aspect_ratio_correction = 1
- else:
- self._aspect_ratio_correction = aspect_ratio
-
- def _get_rotation_transform(self):
- aspect_ratio = self.ax._get_aspect_ratio()
- return Affine2D().translate(-self.center[0], -self.center[1]) \
- .scale(1, aspect_ratio) \
- .rotate(self._rotation) \
- .scale(1, 1 / aspect_ratio) \
- .translate(*self.center)
-
- @property
- def corners(self):
- """
- Corners of rectangle in data coordinates from lower left,
- moving clockwise.
- """
- x0, y0, width, height = self._rect_bbox
- xc = x0, x0 + width, x0 + width, x0
- yc = y0, y0, y0 + height, y0 + height
- transform = self._get_rotation_transform()
- coords = transform.transform(np.array([xc, yc]).T).T
- return coords[0], coords[1]
-
- @property
- def edge_centers(self):
- """
- Midpoint of rectangle edges in data coordinates from left,
- moving anti-clockwise.
- """
- x0, y0, width, height = self._rect_bbox
- w = width / 2.
- h = height / 2.
- xe = x0, x0 + w, x0 + width, x0 + w
- ye = y0 + h, y0, y0 + h, y0 + height
- transform = self._get_rotation_transform()
- coords = transform.transform(np.array([xe, ye]).T).T
- return coords[0], coords[1]
-
- @property
- def center(self):
- """Center of rectangle in data coordinates."""
- x0, y0, width, height = self._rect_bbox
- return x0 + width / 2., y0 + height / 2.
-
- @property
- def extents(self):
- """
- Return (xmin, xmax, ymin, ymax) in data coordinates as defined by the
- bounding box before rotation.
- """
- x0, y0, width, height = self._rect_bbox
- xmin, xmax = sorted([x0, x0 + width])
- ymin, ymax = sorted([y0, y0 + height])
- return xmin, xmax, ymin, ymax
-
- @extents.setter
- def extents(self, extents):
- # Update displayed shape
- self._draw_shape(extents)
- if self._interactive:
- # Update displayed handles
- self._corner_handles.set_data(*self.corners)
- self._edge_handles.set_data(*self.edge_centers)
- x, y = self.center
- self._center_handle.set_data([x], [y])
- self.set_visible(self._visible)
- self.update()
-
- @property
- def rotation(self):
- """
- Rotation in degree in interval [-45°, 45°]. The rotation is limited in
- range to keep the implementation simple.
- """
- return np.rad2deg(self._rotation)
-
- @rotation.setter
- def rotation(self, value):
- # Restrict to a limited range of rotation [-45°, 45°] to avoid changing
- # order of handles
- if -45 <= value and value <= 45:
- self._rotation = np.deg2rad(value)
- # call extents setter to draw shape and update handles positions
- self.extents = self.extents
-
- def _draw_shape(self, extents):
- x0, x1, y0, y1 = extents
- xmin, xmax = sorted([x0, x1])
- ymin, ymax = sorted([y0, y1])
- xlim = sorted(self.ax.get_xlim())
- ylim = sorted(self.ax.get_ylim())
-
- xmin = max(xlim[0], xmin)
- ymin = max(ylim[0], ymin)
- xmax = min(xmax, xlim[1])
- ymax = min(ymax, ylim[1])
-
- self._selection_artist.set_x(xmin)
- self._selection_artist.set_y(ymin)
- self._selection_artist.set_width(xmax - xmin)
- self._selection_artist.set_height(ymax - ymin)
- self._selection_artist.set_angle(self.rotation)
-
- def _set_active_handle(self, event):
- """Set active handle based on the location of the mouse event."""
- # Note: event.xdata/ydata in data coordinates, event.x/y in pixels
- c_idx, c_dist = self._corner_handles.closest(event.x, event.y)
- e_idx, e_dist = self._edge_handles.closest(event.x, event.y)
- m_idx, m_dist = self._center_handle.closest(event.x, event.y)
-
- if 'move' in self._state:
- self._active_handle = 'C'
- # Set active handle as closest handle, if mouse click is close enough.
- elif m_dist < self.grab_range * 2:
- # Prioritise center handle over other handles
- self._active_handle = 'C'
- elif c_dist > self.grab_range and e_dist > self.grab_range:
- # Not close to any handles
- if self.drag_from_anywhere and self._contains(event):
- # Check if we've clicked inside the region
- self._active_handle = 'C'
- else:
- self._active_handle = None
- return
- elif c_dist < e_dist:
- # Closest to a corner handle
- self._active_handle = self._corner_order[c_idx]
- else:
- # Closest to an edge handle
- self._active_handle = self._edge_order[e_idx]
-
- def _contains(self, event):
- """Return True if event is within the patch."""
- return self._selection_artist.contains(event, radius=0)[0]
-
- @property
- def geometry(self):
- """
- Return an array of shape (2, 5) containing the
- x (``RectangleSelector.geometry[1, :]``) and
- y (``RectangleSelector.geometry[0, :]``) data coordinates of the four
- corners of the rectangle starting and ending in the top left corner.
- """
- if hasattr(self._selection_artist, 'get_verts'):
- xfm = self.ax.transData.inverted()
- y, x = xfm.transform(self._selection_artist.get_verts()).T
- return np.array([x, y])
- else:
- return np.array(self._selection_artist.get_data())
-
-
-@_docstring.Substitution(_RECTANGLESELECTOR_PARAMETERS_DOCSTRING.replace(
- '__ARTIST_NAME__', 'ellipse'))
-class EllipseSelector(RectangleSelector):
- """
- Select an elliptical region of an Axes.
-
- For the cursor to remain responsive you must keep a reference to it.
-
- Press and release events triggered at the same coordinates outside the
- selection will clear the selector, except when
- ``ignore_event_outside=True``.
-
- %s
-
- Examples
- --------
- :doc:`/gallery/widgets/rectangle_selector`
- """
- def _init_shape(self, **props):
- return Ellipse((0, 0), 0, 1, visible=False, **props)
-
- def _draw_shape(self, extents):
- x0, x1, y0, y1 = extents
- xmin, xmax = sorted([x0, x1])
- ymin, ymax = sorted([y0, y1])
- center = [x0 + (x1 - x0) / 2., y0 + (y1 - y0) / 2.]
- a = (xmax - xmin) / 2.
- b = (ymax - ymin) / 2.
-
- self._selection_artist.center = center
- self._selection_artist.width = 2 * a
- self._selection_artist.height = 2 * b
- self._selection_artist.angle = self.rotation
-
- @property
- def _rect_bbox(self):
- x, y = self._selection_artist.center
- width = self._selection_artist.width
- height = self._selection_artist.height
- return x - width / 2., y - height / 2., width, height
-
-
-class LassoSelector(_SelectorWidget):
- """
- Selection curve of an arbitrary shape.
-
- For the selector to remain responsive you must keep a reference to it.
-
- The selected path can be used in conjunction with `~.Path.contains_point`
- to select data points from an image.
-
- In contrast to `Lasso`, `LassoSelector` is written with an interface
- similar to `RectangleSelector` and `SpanSelector`, and will continue to
- interact with the Axes until disconnected.
-
- Example usage::
-
- ax = plt.subplot()
- ax.plot(x, y)
-
- def onselect(verts):
- print(verts)
- lasso = LassoSelector(ax, onselect)
-
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The parent Axes for the widget.
- onselect : function
- Whenever the lasso is released, the *onselect* function is called and
- passed the vertices of the selected path.
- useblit : bool, default: True
- Whether to use blitting for faster drawing (if supported by the
- backend). See the tutorial :ref:`blitting`
- for details.
- props : dict, optional
- Properties with which the line is drawn, see `.Line2D`
- for valid properties. Default values are defined in ``mpl.rcParams``.
- button : `.MouseButton` or list of `.MouseButton`, optional
- The mouse buttons used for rectangle selection. Default is ``None``,
- which corresponds to all buttons.
- """
-
- @_api.make_keyword_only("3.7", name="useblit")
- def __init__(self, ax, onselect, useblit=True, props=None, button=None):
- super().__init__(ax, onselect, useblit=useblit, button=button)
- self.verts = None
- props = {
- **(props if props is not None else {}),
- # Note that self.useblit may be != useblit, if the canvas doesn't
- # support blitting.
- 'animated': self.useblit, 'visible': False,
- }
- line = Line2D([], [], **props)
- self.ax.add_line(line)
- self._selection_artist = line
-
- def _press(self, event):
- self.verts = [self._get_data(event)]
- self._selection_artist.set_visible(True)
-
- def _release(self, event):
- if self.verts is not None:
- self.verts.append(self._get_data(event))
- self.onselect(self.verts)
- self._selection_artist.set_data([[], []])
- self._selection_artist.set_visible(False)
- self.verts = None
-
- def _onmove(self, event):
- if self.verts is None:
- return
- self.verts.append(self._get_data(event))
- self._selection_artist.set_data(list(zip(*self.verts)))
-
- self.update()
-
-
-class PolygonSelector(_SelectorWidget):
- """
- Select a polygon region of an Axes.
-
- Place vertices with each mouse click, and make the selection by completing
- the polygon (clicking on the first vertex). Once drawn individual vertices
- can be moved by clicking and dragging with the left mouse button, or
- removed by clicking the right mouse button.
-
- In addition, the following modifier keys can be used:
-
- - Hold *ctrl* and click and drag a vertex to reposition it before the
- polygon has been completed.
- - Hold the *shift* key and click and drag anywhere in the Axes to move
- all vertices.
- - Press the *esc* key to start a new polygon.
-
- For the selector to remain responsive you must keep a reference to it.
-
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The parent Axes for the widget.
-
- onselect : function
- When a polygon is completed or modified after completion,
- the *onselect* function is called and passed a list of the vertices as
- ``(xdata, ydata)`` tuples.
-
- useblit : bool, default: False
- Whether to use blitting for faster drawing (if supported by the
- backend). See the tutorial :ref:`blitting`
- for details.
-
- props : dict, optional
- Properties with which the line is drawn, see `.Line2D` for valid properties.
- Default::
-
- dict(color='k', linestyle='-', linewidth=2, alpha=0.5)
-
- handle_props : dict, optional
- Artist properties for the markers drawn at the vertices of the polygon.
- See the marker arguments in `.Line2D` for valid
- properties. Default values are defined in ``mpl.rcParams`` except for
- the default value of ``markeredgecolor`` which will be the same as the
- ``color`` property in *props*.
-
- grab_range : float, default: 10
- A vertex is selected (to complete the polygon or to move a vertex) if
- the mouse click is within *grab_range* pixels of the vertex.
-
- draw_bounding_box : bool, optional
- If `True`, a bounding box will be drawn around the polygon selector
- once it is complete. This box can be used to move and resize the
- selector.
-
- box_handle_props : dict, optional
- Properties to set for the box handles. See the documentation for the
- *handle_props* argument to `RectangleSelector` for more info.
-
- box_props : dict, optional
- Properties to set for the box. See the documentation for the *props*
- argument to `RectangleSelector` for more info.
-
- Examples
- --------
- :doc:`/gallery/widgets/polygon_selector_simple`
- :doc:`/gallery/widgets/polygon_selector_demo`
-
- Notes
- -----
- If only one point remains after removing points, the selector reverts to an
- incomplete state and you can start drawing a new polygon from the existing
- point.
- """
-
- @_api.make_keyword_only("3.7", name="useblit")
- def __init__(self, ax, onselect, useblit=False,
- props=None, handle_props=None, grab_range=10, *,
- draw_bounding_box=False, box_handle_props=None,
- box_props=None):
- # The state modifiers 'move', 'square', and 'center' are expected by
- # _SelectorWidget but are not supported by PolygonSelector
- # Note: could not use the existing 'move' state modifier in-place of
- # 'move_all' because _SelectorWidget automatically discards 'move'
- # from the state on button release.
- state_modifier_keys = dict(clear='escape', move_vertex='control',
- move_all='shift', move='not-applicable',
- square='not-applicable',
- center='not-applicable',
- rotate='not-applicable')
- super().__init__(ax, onselect, useblit=useblit,
- state_modifier_keys=state_modifier_keys)
-
- self._xys = [(0, 0)]
-
- if props is None:
- props = dict(color='k', linestyle='-', linewidth=2, alpha=0.5)
- props = {**props, 'animated': self.useblit}
- self._selection_artist = line = Line2D([], [], **props)
- self.ax.add_line(line)
-
- if handle_props is None:
- handle_props = dict(markeredgecolor='k',
- markerfacecolor=props.get('color', 'k'))
- self._handle_props = handle_props
- self._polygon_handles = ToolHandles(self.ax, [], [],
- useblit=self.useblit,
- marker_props=self._handle_props)
-
- self._active_handle_idx = -1
- self.grab_range = grab_range
-
- self.set_visible(True)
- self._draw_box = draw_bounding_box
- self._box = None
-
- if box_handle_props is None:
- box_handle_props = {}
- self._box_handle_props = self._handle_props.update(box_handle_props)
- self._box_props = box_props
-
- def _get_bbox(self):
- return self._selection_artist.get_bbox()
-
- def _add_box(self):
- self._box = RectangleSelector(self.ax,
- onselect=lambda *args, **kwargs: None,
- useblit=self.useblit,
- grab_range=self.grab_range,
- handle_props=self._box_handle_props,
- props=self._box_props,
- interactive=True)
- self._box._state_modifier_keys.pop('rotate')
- self._box.connect_event('motion_notify_event', self._scale_polygon)
- self._update_box()
- # Set state that prevents the RectangleSelector from being created
- # by the user
- self._box._allow_creation = False
- self._box._selection_completed = True
- self._draw_polygon()
-
- def _remove_box(self):
- if self._box is not None:
- self._box.set_visible(False)
- self._box = None
-
- def _update_box(self):
- # Update selection box extents to the extents of the polygon
- if self._box is not None:
- bbox = self._get_bbox()
- self._box.extents = [bbox.x0, bbox.x1, bbox.y0, bbox.y1]
- # Save a copy
- self._old_box_extents = self._box.extents
-
- def _scale_polygon(self, event):
- """
- Scale the polygon selector points when the bounding box is moved or
- scaled.
-
- This is set as a callback on the bounding box RectangleSelector.
- """
- if not self._selection_completed:
- return
-
- if self._old_box_extents == self._box.extents:
- return
-
- # Create transform from old box to new box
- x1, y1, w1, h1 = self._box._rect_bbox
- old_bbox = self._get_bbox()
- t = (transforms.Affine2D()
- .translate(-old_bbox.x0, -old_bbox.y0)
- .scale(1 / old_bbox.width, 1 / old_bbox.height)
- .scale(w1, h1)
- .translate(x1, y1))
-
- # Update polygon verts. Must be a list of tuples for consistency.
- new_verts = [(x, y) for x, y in t.transform(np.array(self.verts))]
- self._xys = [*new_verts, new_verts[0]]
- self._draw_polygon()
- self._old_box_extents = self._box.extents
-
- @property
- def _handles_artists(self):
- return self._polygon_handles.artists
-
- def _remove_vertex(self, i):
- """Remove vertex with index i."""
- if (len(self._xys) > 2 and
- self._selection_completed and
- i in (0, len(self._xys) - 1)):
- # If selecting the first or final vertex, remove both first and
- # last vertex as they are the same for a closed polygon
- self._xys.pop(0)
- self._xys.pop(-1)
- # Close the polygon again by appending the new first vertex to the
- # end
- self._xys.append(self._xys[0])
- else:
- self._xys.pop(i)
- if len(self._xys) <= 2:
- # If only one point left, return to incomplete state to let user
- # start drawing again
- self._selection_completed = False
- self._remove_box()
-
- def _press(self, event):
- """Button press event handler."""
- # Check for selection of a tool handle.
- if ((self._selection_completed or 'move_vertex' in self._state)
- and len(self._xys) > 0):
- h_idx, h_dist = self._polygon_handles.closest(event.x, event.y)
- if h_dist < self.grab_range:
- self._active_handle_idx = h_idx
- # Save the vertex positions at the time of the press event (needed to
- # support the 'move_all' state modifier).
- self._xys_at_press = self._xys.copy()
-
- def _release(self, event):
- """Button release event handler."""
- # Release active tool handle.
- if self._active_handle_idx >= 0:
- if event.button == 3:
- self._remove_vertex(self._active_handle_idx)
- self._draw_polygon()
- self._active_handle_idx = -1
-
- # Complete the polygon.
- elif len(self._xys) > 3 and self._xys[-1] == self._xys[0]:
- self._selection_completed = True
- if self._draw_box and self._box is None:
- self._add_box()
-
- # Place new vertex.
- elif (not self._selection_completed
- and 'move_all' not in self._state
- and 'move_vertex' not in self._state):
- self._xys.insert(-1, self._get_data_coords(event))
-
- if self._selection_completed:
- self.onselect(self.verts)
-
- def onmove(self, event):
- """Cursor move event handler and validator."""
- # Method overrides _SelectorWidget.onmove because the polygon selector
- # needs to process the move callback even if there is no button press.
- # _SelectorWidget.onmove include logic to ignore move event if
- # _eventpress is None.
- if not self.ignore(event):
- event = self._clean_event(event)
- self._onmove(event)
- return True
- return False
-
- def _onmove(self, event):
- """Cursor move event handler."""
- # Move the active vertex (ToolHandle).
- if self._active_handle_idx >= 0:
- idx = self._active_handle_idx
- self._xys[idx] = self._get_data_coords(event)
- # Also update the end of the polygon line if the first vertex is
- # the active handle and the polygon is completed.
- if idx == 0 and self._selection_completed:
- self._xys[-1] = self._get_data_coords(event)
-
- # Move all vertices.
- elif 'move_all' in self._state and self._eventpress:
- xdata, ydata = self._get_data_coords(event)
- dx = xdata - self._eventpress.xdata
- dy = ydata - self._eventpress.ydata
- for k in range(len(self._xys)):
- x_at_press, y_at_press = self._xys_at_press[k]
- self._xys[k] = x_at_press + dx, y_at_press + dy
-
- # Do nothing if completed or waiting for a move.
- elif (self._selection_completed
- or 'move_vertex' in self._state or 'move_all' in self._state):
- return
-
- # Position pending vertex.
- else:
- # Calculate distance to the start vertex.
- x0, y0 = \
- self._selection_artist.get_transform().transform(self._xys[0])
- v0_dist = np.hypot(x0 - event.x, y0 - event.y)
- # Lock on to the start vertex if near it and ready to complete.
- if len(self._xys) > 3 and v0_dist < self.grab_range:
- self._xys[-1] = self._xys[0]
- else:
- self._xys[-1] = self._get_data_coords(event)
-
- self._draw_polygon()
-
- def _on_key_press(self, event):
- """Key press event handler."""
- # Remove the pending vertex if entering the 'move_vertex' or
- # 'move_all' mode
- if (not self._selection_completed
- and ('move_vertex' in self._state or
- 'move_all' in self._state)):
- self._xys.pop()
- self._draw_polygon()
-
- def _on_key_release(self, event):
- """Key release event handler."""
- # Add back the pending vertex if leaving the 'move_vertex' or
- # 'move_all' mode (by checking the released key)
- if (not self._selection_completed
- and
- (event.key == self._state_modifier_keys.get('move_vertex')
- or event.key == self._state_modifier_keys.get('move_all'))):
- self._xys.append(self._get_data_coords(event))
- self._draw_polygon()
- # Reset the polygon if the released key is the 'clear' key.
- elif event.key == self._state_modifier_keys.get('clear'):
- event = self._clean_event(event)
- self._xys = [self._get_data_coords(event)]
- self._selection_completed = False
- self._remove_box()
- self.set_visible(True)
-
- def _draw_polygon_without_update(self):
- """Redraw the polygon based on new vertex positions, no update()."""
- xs, ys = zip(*self._xys) if self._xys else ([], [])
- self._selection_artist.set_data(xs, ys)
- self._update_box()
- # Only show one tool handle at the start and end vertex of the polygon
- # if the polygon is completed or the user is locked on to the start
- # vertex.
- if (self._selection_completed
- or (len(self._xys) > 3
- and self._xys[-1] == self._xys[0])):
- self._polygon_handles.set_data(xs[:-1], ys[:-1])
- else:
- self._polygon_handles.set_data(xs, ys)
-
- def _draw_polygon(self):
- """Redraw the polygon based on the new vertex positions."""
- self._draw_polygon_without_update()
- self.update()
-
- @property
- def verts(self):
- """The polygon vertices, as a list of ``(x, y)`` pairs."""
- return self._xys[:-1]
-
- @verts.setter
- def verts(self, xys):
- """
- Set the polygon vertices.
-
- This will remove any preexisting vertices, creating a complete polygon
- with the new vertices.
- """
- self._xys = [*xys, xys[0]]
- self._selection_completed = True
- self.set_visible(True)
- if self._draw_box and self._box is None:
- self._add_box()
- self._draw_polygon()
-
- def _clear_without_update(self):
- self._selection_completed = False
- self._xys = [(0, 0)]
- self._draw_polygon_without_update()
-
-
-class Lasso(AxesWidget):
- """
- Selection curve of an arbitrary shape.
-
- The selected path can be used in conjunction with
- `~matplotlib.path.Path.contains_point` to select data points from an image.
-
- Unlike `LassoSelector`, this must be initialized with a starting
- point *xy*, and the `Lasso` events are destroyed upon release.
-
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- The parent Axes for the widget.
- xy : (float, float)
- Coordinates of the start of the lasso.
- callback : callable
- Whenever the lasso is released, the *callback* function is called and
- passed the vertices of the selected path.
- useblit : bool, default: True
- Whether to use blitting for faster drawing (if supported by the
- backend). See the tutorial :ref:`blitting`
- for details.
- """
-
- @_api.make_keyword_only("3.7", name="useblit")
- def __init__(self, ax, xy, callback, useblit=True):
- super().__init__(ax)
-
- self.useblit = useblit and self.canvas.supports_blit
- if self.useblit:
- self.background = self.canvas.copy_from_bbox(self.ax.bbox)
-
- x, y = xy
- self.verts = [(x, y)]
- self.line = Line2D([x], [y], linestyle='-', color='black', lw=2)
- self.ax.add_line(self.line)
- self.callback = callback
- self.connect_event('button_release_event', self.onrelease)
- self.connect_event('motion_notify_event', self.onmove)
-
- def onrelease(self, event):
- if self.ignore(event):
- return
- if self.verts is not None:
- self.verts.append(self._get_data_coords(event))
- if len(self.verts) > 2:
- self.callback(self.verts)
- self.line.remove()
- self.verts = None
- self.disconnect_events()
-
- def onmove(self, event):
- if (self.ignore(event)
- or self.verts is None
- or event.button != 1
- or not self.ax.contains(event)[0]):
- return
- self.verts.append(self._get_data_coords(event))
- self.line.set_data(list(zip(*self.verts)))
-
- if self.useblit:
- self.canvas.restore_region(self.background)
- self.ax.draw_artist(self.line)
- self.canvas.blit(self.ax.bbox)
- else:
- self.canvas.draw_idle()
diff --git a/contrib/python/matplotlib/py3/matplotlib/widgets.pyi b/contrib/python/matplotlib/py3/matplotlib/widgets.pyi
deleted file mode 100644
index 00c2d0da8a..0000000000
--- a/contrib/python/matplotlib/py3/matplotlib/widgets.pyi
+++ /dev/null
@@ -1,487 +0,0 @@
-from .artist import Artist
-from .axes import Axes
-from .backend_bases import FigureCanvasBase, Event, MouseEvent, MouseButton
-from .collections import LineCollection
-from .figure import Figure
-from .lines import Line2D
-from .patches import Circle, Polygon, Rectangle
-from .text import Text
-
-import PIL.Image
-
-from collections.abc import Callable, Collection, Iterable, Sequence
-from typing import Any, Literal
-from numpy.typing import ArrayLike
-from .typing import ColorType
-import numpy as np
-
-class LockDraw:
- def __init__(self) -> None: ...
- def __call__(self, o: Any) -> None: ...
- def release(self, o: Any) -> None: ...
- def available(self, o: Any) -> bool: ...
- def isowner(self, o: Any) -> bool: ...
- def locked(self) -> bool: ...
-
-class Widget:
- drawon: bool
- eventson: bool
- active: bool
- def set_active(self, active: bool) -> None: ...
- def get_active(self) -> None: ...
- def ignore(self, event) -> bool: ...
-
-class AxesWidget(Widget):
- ax: Axes
- canvas: FigureCanvasBase | None
- def __init__(self, ax: Axes) -> None: ...
- def connect_event(self, event: Event, callback: Callable) -> None: ...
- def disconnect_events(self) -> None: ...
-
-class Button(AxesWidget):
- label: Text
- color: ColorType
- hovercolor: ColorType
- def __init__(
- self,
- ax: Axes,
- label: str,
- image: ArrayLike | PIL.Image.Image | None = ...,
- color: ColorType = ...,
- hovercolor: ColorType = ...,
- *,
- useblit: bool = ...
- ) -> None: ...
- def on_clicked(self, func: Callable[[Event], Any]) -> int: ...
- def disconnect(self, cid: int) -> None: ...
-
-class SliderBase(AxesWidget):
- orientation: Literal["horizontal", "vertical"]
- closedmin: bool
- closedmax: bool
- valmin: float
- valmax: float
- valstep: float | ArrayLike | None
- drag_active: bool
- valfmt: str
- def __init__(
- self,
- ax: Axes,
- orientation: Literal["horizontal", "vertical"],
- closedmin: bool,
- closedmax: bool,
- valmin: float,
- valmax: float,
- valfmt: str,
- dragging: Slider | None,
- valstep: float | ArrayLike | None,
- ) -> None: ...
- def disconnect(self, cid: int) -> None: ...
- def reset(self) -> None: ...
-
-class Slider(SliderBase):
- slidermin: Slider | None
- slidermax: Slider | None
- val: float
- valinit: float
- track: Rectangle
- poly: Polygon
- hline: Line2D
- vline: Line2D
- label: Text
- valtext: Text
- def __init__(
- self,
- ax: Axes,
- label: str,
- valmin: float,
- valmax: float,
- *,
- valinit: float = ...,
- valfmt: str | None = ...,
- closedmin: bool = ...,
- closedmax: bool = ...,
- slidermin: Slider | None = ...,
- slidermax: Slider | None = ...,
- dragging: bool = ...,
- valstep: float | ArrayLike | None = ...,
- orientation: Literal["horizontal", "vertical"] = ...,
- initcolor: ColorType = ...,
- track_color: ColorType = ...,
- handle_style: dict[str, Any] | None = ...,
- **kwargs
- ) -> None: ...
- def set_val(self, val: float) -> None: ...
- def on_changed(self, func: Callable[[float], Any]) -> int: ...
-
-class RangeSlider(SliderBase):
- val: tuple[float, float]
- valinit: tuple[float, float]
- track: Rectangle
- poly: Polygon
- label: Text
- valtext: Text
- def __init__(
- self,
- ax: Axes,
- label: str,
- valmin: float,
- valmax: float,
- *,
- valinit: tuple[float, float] | None = ...,
- valfmt: str | None = ...,
- closedmin: bool = ...,
- closedmax: bool = ...,
- dragging: bool = ...,
- valstep: float | ArrayLike | None = ...,
- orientation: Literal["horizontal", "vertical"] = ...,
- track_color: ColorType = ...,
- handle_style: dict[str, Any] | None = ...,
- **kwargs
- ) -> None: ...
- def set_min(self, min: float) -> None: ...
- def set_max(self, max: float) -> None: ...
- def set_val(self, val: ArrayLike) -> None: ...
- def on_changed(self, func: Callable[[tuple[float, float]], Any]) -> int: ...
-
-class CheckButtons(AxesWidget):
- labels: list[Text]
- def __init__(
- self,
- ax: Axes,
- labels: Sequence[str],
- actives: Iterable[bool] | None = ...,
- *,
- useblit: bool = ...,
- label_props: dict[str, Any] | None = ...,
- frame_props: dict[str, Any] | None = ...,
- check_props: dict[str, Any] | None = ...,
- ) -> None: ...
- def set_label_props(self, props: dict[str, Any]) -> None: ...
- def set_frame_props(self, props: dict[str, Any]) -> None: ...
- def set_check_props(self, props: dict[str, Any]) -> None: ...
- def set_active(self, index: int) -> None: ...
- def get_status(self) -> list[bool]: ...
- def on_clicked(self, func: Callable[[str], Any]) -> int: ...
- def disconnect(self, cid: int) -> None: ...
- @property
- def lines(self) -> list[tuple[Line2D, Line2D]]: ...
- @property
- def rectangles(self) -> list[Rectangle]: ...
-
-class TextBox(AxesWidget):
- label: Text
- text_disp: Text
- cursor_index: int
- cursor: LineCollection
- color: ColorType
- hovercolor: ColorType
- capturekeystrokes: bool
- def __init__(
- self,
- ax: Axes,
- label: str,
- initial: str = ...,
- *,
- color: ColorType = ...,
- hovercolor: ColorType = ...,
- label_pad: float = ...,
- textalignment: Literal["left", "center", "right"] = ...,
- ) -> None: ...
- @property
- def text(self) -> str: ...
- def set_val(self, val: str) -> None: ...
- def begin_typing(self, x = ...) -> None: ...
- def stop_typing(self) -> None: ...
- def on_text_change(self, func: Callable[[str], Any]) -> int: ...
- def on_submit(self, func: Callable[[str], Any]) -> int: ...
- def disconnect(self, cid: int) -> None: ...
-
-class RadioButtons(AxesWidget):
- activecolor: ColorType
- value_selected: str
- labels: list[Text]
- def __init__(
- self,
- ax: Axes,
- labels: Iterable[str],
- active: int = ...,
- activecolor: ColorType | None = ...,
- *,
- useblit: bool = ...,
- label_props: dict[str, Any] | Sequence[dict[str, Any]] | None = ...,
- radio_props: dict[str, Any] | None = ...,
- ) -> None: ...
- def set_label_props(self, props: dict[str, Any]) -> None: ...
- def set_radio_props(self, props: dict[str, Any]) -> None: ...
- def set_active(self, index: int) -> None: ...
- def on_clicked(self, func: Callable[[str], Any]) -> int: ...
- def disconnect(self, cid: int) -> None: ...
- @property
- def circles(self) -> list[Circle]: ...
-
-class SubplotTool(Widget):
- figure: Figure
- targetfig: Figure
- buttonreset: Button
- def __init__(self, targetfig: Figure, toolfig: Figure) -> None: ...
-
-class Cursor(AxesWidget):
- visible: bool
- horizOn: bool
- vertOn: bool
- useblit: bool
- lineh: Line2D
- linev: Line2D
- background: Any
- needclear: bool
- def __init__(
- self,
- ax: Axes,
- *,
- horizOn: bool = ...,
- vertOn: bool = ...,
- useblit: bool = ...,
- **lineprops
- ) -> None: ...
- def clear(self, event: Event) -> None: ...
- def onmove(self, event: Event) -> None: ...
-
-class MultiCursor(Widget):
- axes: Sequence[Axes]
- horizOn: bool
- vertOn: bool
- visible: bool
- useblit: bool
- needclear: bool
- vlines: list[Line2D]
- hlines: list[Line2D]
- def __init__(
- self,
- canvas: Any,
- axes: Sequence[Axes],
- *,
- useblit: bool = ...,
- horizOn: bool = ...,
- vertOn: bool = ...,
- **lineprops
- ) -> None: ...
- def connect(self) -> None: ...
- def disconnect(self) -> None: ...
- def clear(self, event: Event) -> None: ...
- def onmove(self, event: Event) -> None: ...
-
-class _SelectorWidget(AxesWidget):
- onselect: Callable[[float, float], Any]
- useblit: bool
- background: Any
- validButtons: list[MouseButton]
- def __init__(
- self,
- ax: Axes,
- onselect: Callable[[float, float], Any],
- useblit: bool = ...,
- button: MouseButton | Collection[MouseButton] | None = ...,
- state_modifier_keys: dict[str, str] | None = ...,
- use_data_coordinates: bool = ...,
- ) -> None: ...
- def update_background(self, event: Event) -> None: ...
- def connect_default_events(self) -> None: ...
- def ignore(self, event: Event) -> bool: ...
- def update(self) -> None: ...
- def press(self, event: Event) -> bool: ...
- def release(self, event: Event) -> bool: ...
- def onmove(self, event: Event) -> bool: ...
- def on_scroll(self, event: Event) -> None: ...
- def on_key_press(self, event: Event) -> None: ...
- def on_key_release(self, event: Event) -> None: ...
- def set_visible(self, visible: bool) -> None: ...
- def get_visible(self) -> bool: ...
- @property
- def visible(self) -> bool: ...
- def clear(self) -> None: ...
- @property
- def artists(self) -> tuple[Artist]: ...
- def set_props(self, **props) -> None: ...
- def set_handle_props(self, **handle_props) -> None: ...
- def add_state(self, state: str) -> None: ...
- def remove_state(self, state: str) -> None: ...
-
-class SpanSelector(_SelectorWidget):
- snap_values: ArrayLike | None
- onmove_callback: Callable[[float, float], Any]
- minspan: float
- grab_range: float
- drag_from_anywhere: bool
- ignore_event_outside: bool
- canvas: FigureCanvasBase | None
- def __init__(
- self,
- ax: Axes,
- onselect: Callable[[float, float], Any],
- direction: Literal["horizontal", "vertical"],
- *,
- minspan: float = ...,
- useblit: bool = ...,
- props: dict[str, Any] | None = ...,
- onmove_callback: Callable[[float, float], Any] | None = ...,
- interactive: bool = ...,
- button: MouseButton | Collection[MouseButton] | None = ...,
- handle_props: dict[str, Any] | None = ...,
- grab_range: float = ...,
- state_modifier_keys: dict[str, str] | None = ...,
- drag_from_anywhere: bool = ...,
- ignore_event_outside: bool = ...,
- snap_values: ArrayLike | None = ...,
- ) -> None: ...
- def new_axes(self, ax: Axes, *, _props: dict[str, Any] | None = ...) -> None: ...
- def connect_default_events(self) -> None: ...
- @property
- def direction(self) -> Literal["horizontal", "vertical"]: ...
- @direction.setter
- def direction(self, direction: Literal["horizontal", "vertical"]) -> None: ...
- @property
- def extents(self) -> tuple[float, float]: ...
- @extents.setter
- def extents(self, extents: tuple[float, float]) -> None: ...
-
-class ToolLineHandles:
- ax: Axes
- def __init__(
- self,
- ax: Axes,
- positions: ArrayLike,
- direction: Literal["horizontal", "vertical"],
- *,
- line_props: dict[str, Any] | None = ...,
- useblit: bool = ...,
- ) -> None: ...
- @property
- def artists(self) -> tuple[Line2D]: ...
- @property
- def positions(self) -> list[float]: ...
- @property
- def direction(self) -> Literal["horizontal", "vertical"]: ...
- def set_data(self, positions: ArrayLike) -> None: ...
- def set_visible(self, value: bool) -> None: ...
- def set_animated(self, value: bool) -> None: ...
- def remove(self) -> None: ...
- def closest(self, x: float, y: float) -> tuple[int, float]: ...
-
-class ToolHandles:
- ax: Axes
- def __init__(
- self,
- ax: Axes,
- x: ArrayLike,
- y: ArrayLike,
- *,
- marker: str = ...,
- marker_props: dict[str, Any] | None = ...,
- useblit: bool = ...,
- ) -> None: ...
- @property
- def x(self) -> ArrayLike: ...
- @property
- def y(self) -> ArrayLike: ...
- @property
- def artists(self) -> tuple[Line2D]: ...
- def set_data(self, pts: ArrayLike, y: ArrayLike | None = ...) -> None: ...
- def set_visible(self, val: bool) -> None: ...
- def set_animated(self, val: bool) -> None: ...
- def closest(self, x: float, y: float) -> tuple[int, float]: ...
-
-class RectangleSelector(_SelectorWidget):
- drag_from_anywhere: bool
- ignore_event_outside: bool
- minspanx: float
- minspany: float
- spancoords: Literal["data", "pixels"]
- grab_range: float
- def __init__(
- self,
- ax: Axes,
- onselect: Callable[[MouseEvent, MouseEvent], Any],
- *,
- minspanx: float = ...,
- minspany: float = ...,
- useblit: bool = ...,
- props: dict[str, Any] | None = ...,
- spancoords: Literal["data", "pixels"] = ...,
- button: MouseButton | Collection[MouseButton] | None = ...,
- grab_range: float = ...,
- handle_props: dict[str, Any] | None = ...,
- interactive: bool = ...,
- state_modifier_keys: dict[str, str] | None = ...,
- drag_from_anywhere: bool = ...,
- ignore_event_outside: bool = ...,
- use_data_coordinates: bool = ...,
- ) -> None: ...
- @property
- def corners(self) -> tuple[np.ndarray, np.ndarray]: ...
- @property
- def edge_centers(self) -> tuple[np.ndarray, np.ndarray]: ...
- @property
- def center(self) -> tuple[float, float]: ...
- @property
- def extents(self) -> tuple[float, float, float, float]: ...
- @extents.setter
- def extents(self, extents: tuple[float, float, float, float]) -> None: ...
- @property
- def rotation(self) -> float: ...
- @rotation.setter
- def rotation(self, value: float) -> None: ...
- @property
- def geometry(self) -> np.ndarray: ...
-
-class EllipseSelector(RectangleSelector): ...
-
-class LassoSelector(_SelectorWidget):
- verts: None | list[tuple[float, float]]
- def __init__(
- self,
- ax: Axes,
- onselect: Callable[[list[tuple[float, float]]], Any],
- *,
- useblit: bool = ...,
- props: dict[str, Any] | None = ...,
- button: MouseButton | Collection[MouseButton] | None = ...,
- ) -> None: ...
-
-class PolygonSelector(_SelectorWidget):
- grab_range: float
- def __init__(
- self,
- ax: Axes,
- onselect: Callable[[ArrayLike, ArrayLike], Any],
- *,
- useblit: bool = ...,
- props: dict[str, Any] | None = ...,
- handle_props: dict[str, Any] | None = ...,
- grab_range: float = ...,
- draw_bounding_box: bool = ...,
- box_handle_props: dict[str, Any] | None = ...,
- box_props: dict[str, Any] | None = ...
- ) -> None: ...
- def onmove(self, event: Event) -> bool: ...
- @property
- def verts(self) -> list[tuple[float, float]]: ...
- @verts.setter
- def verts(self, xys: Sequence[tuple[float, float]]) -> None: ...
-
-class Lasso(AxesWidget):
- useblit: bool
- background: Any
- verts: list[tuple[float, float]] | None
- line: Line2D
- callback: Callable[[list[tuple[float, float]]], Any]
- def __init__(
- self,
- ax: Axes,
- xy: tuple[float, float],
- callback: Callable[[list[tuple[float, float]]], Any],
- *,
- useblit: bool = ...,
- ) -> None: ...
- def onrelease(self, event: Event) -> None: ...
- def onmove(self, event: Event) -> None: ...
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/__init__.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/__init__.py
deleted file mode 100644
index c55302485e..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/__init__.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from . import axes_size as Size
-from .axes_divider import Divider, SubplotDivider, make_axes_locatable
-from .axes_grid import AxesGrid, Grid, ImageGrid
-
-from .parasite_axes import host_subplot, host_axes
-
-__all__ = ["Size",
- "Divider", "SubplotDivider", "make_axes_locatable",
- "AxesGrid", "Grid", "ImageGrid",
- "host_subplot", "host_axes"]
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/anchored_artists.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/anchored_artists.py
deleted file mode 100644
index 1238310b46..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/anchored_artists.py
+++ /dev/null
@@ -1,462 +0,0 @@
-from matplotlib import _api, transforms
-from matplotlib.offsetbox import (AnchoredOffsetbox, AuxTransformBox,
- DrawingArea, TextArea, VPacker)
-from matplotlib.patches import (Rectangle, Ellipse, ArrowStyle,
- FancyArrowPatch, PathPatch)
-from matplotlib.text import TextPath
-
-__all__ = ['AnchoredDrawingArea', 'AnchoredAuxTransformBox',
- 'AnchoredEllipse', 'AnchoredSizeBar', 'AnchoredDirectionArrows']
-
-
-class AnchoredDrawingArea(AnchoredOffsetbox):
- def __init__(self, width, height, xdescent, ydescent,
- loc, pad=0.4, borderpad=0.5, prop=None, frameon=True,
- **kwargs):
- """
- An anchored container with a fixed size and fillable `.DrawingArea`.
-
- Artists added to the *drawing_area* will have their coordinates
- interpreted as pixels. Any transformations set on the artists will be
- overridden.
-
- Parameters
- ----------
- width, height : float
- Width and height of the container, in pixels.
- xdescent, ydescent : float
- Descent of the container in the x- and y- direction, in pixels.
- loc : str
- Location of this artist. Valid locations are
- 'upper left', 'upper center', 'upper right',
- 'center left', 'center', 'center right',
- 'lower left', 'lower center', 'lower right'.
- For backward compatibility, numeric values are accepted as well.
- See the parameter *loc* of `.Legend` for details.
- pad : float, default: 0.4
- Padding around the child objects, in fraction of the font size.
- borderpad : float, default: 0.5
- Border padding, in fraction of the font size.
- prop : `~matplotlib.font_manager.FontProperties`, optional
- Font property used as a reference for paddings.
- frameon : bool, default: True
- If True, draw a box around this artist.
- **kwargs
- Keyword arguments forwarded to `.AnchoredOffsetbox`.
-
- Attributes
- ----------
- drawing_area : `~matplotlib.offsetbox.DrawingArea`
- A container for artists to display.
-
- Examples
- --------
- To display blue and red circles of different sizes in the upper right
- of an Axes *ax*:
-
- >>> ada = AnchoredDrawingArea(20, 20, 0, 0,
- ... loc='upper right', frameon=False)
- >>> ada.drawing_area.add_artist(Circle((10, 10), 10, fc="b"))
- >>> ada.drawing_area.add_artist(Circle((30, 10), 5, fc="r"))
- >>> ax.add_artist(ada)
- """
- self.da = DrawingArea(width, height, xdescent, ydescent)
- self.drawing_area = self.da
-
- super().__init__(
- loc, pad=pad, borderpad=borderpad, child=self.da, prop=None,
- frameon=frameon, **kwargs
- )
-
-
-class AnchoredAuxTransformBox(AnchoredOffsetbox):
- def __init__(self, transform, loc,
- pad=0.4, borderpad=0.5, prop=None, frameon=True, **kwargs):
- """
- An anchored container with transformed coordinates.
-
- Artists added to the *drawing_area* are scaled according to the
- coordinates of the transformation used. The dimensions of this artist
- will scale to contain the artists added.
-
- Parameters
- ----------
- transform : `~matplotlib.transforms.Transform`
- The transformation object for the coordinate system in use, i.e.,
- :attr:`matplotlib.axes.Axes.transData`.
- loc : str
- Location of this artist. Valid locations are
- 'upper left', 'upper center', 'upper right',
- 'center left', 'center', 'center right',
- 'lower left', 'lower center', 'lower right'.
- For backward compatibility, numeric values are accepted as well.
- See the parameter *loc* of `.Legend` for details.
- pad : float, default: 0.4
- Padding around the child objects, in fraction of the font size.
- borderpad : float, default: 0.5
- Border padding, in fraction of the font size.
- prop : `~matplotlib.font_manager.FontProperties`, optional
- Font property used as a reference for paddings.
- frameon : bool, default: True
- If True, draw a box around this artist.
- **kwargs
- Keyword arguments forwarded to `.AnchoredOffsetbox`.
-
- Attributes
- ----------
- drawing_area : `~matplotlib.offsetbox.AuxTransformBox`
- A container for artists to display.
-
- Examples
- --------
- To display an ellipse in the upper left, with a width of 0.1 and
- height of 0.4 in data coordinates:
-
- >>> box = AnchoredAuxTransformBox(ax.transData, loc='upper left')
- >>> el = Ellipse((0, 0), width=0.1, height=0.4, angle=30)
- >>> box.drawing_area.add_artist(el)
- >>> ax.add_artist(box)
- """
- self.drawing_area = AuxTransformBox(transform)
-
- super().__init__(loc, pad=pad, borderpad=borderpad,
- child=self.drawing_area, prop=prop, frameon=frameon,
- **kwargs)
-
-
-@_api.deprecated("3.8")
-class AnchoredEllipse(AnchoredOffsetbox):
- def __init__(self, transform, width, height, angle, loc,
- pad=0.1, borderpad=0.1, prop=None, frameon=True, **kwargs):
- """
- Draw an anchored ellipse of a given size.
-
- Parameters
- ----------
- transform : `~matplotlib.transforms.Transform`
- The transformation object for the coordinate system in use, i.e.,
- :attr:`matplotlib.axes.Axes.transData`.
- width, height : float
- Width and height of the ellipse, given in coordinates of
- *transform*.
- angle : float
- Rotation of the ellipse, in degrees, anti-clockwise.
- loc : str
- Location of the ellipse. Valid locations are
- 'upper left', 'upper center', 'upper right',
- 'center left', 'center', 'center right',
- 'lower left', 'lower center', 'lower right'.
- For backward compatibility, numeric values are accepted as well.
- See the parameter *loc* of `.Legend` for details.
- pad : float, default: 0.1
- Padding around the ellipse, in fraction of the font size.
- borderpad : float, default: 0.1
- Border padding, in fraction of the font size.
- frameon : bool, default: True
- If True, draw a box around the ellipse.
- prop : `~matplotlib.font_manager.FontProperties`, optional
- Font property used as a reference for paddings.
- **kwargs
- Keyword arguments forwarded to `.AnchoredOffsetbox`.
-
- Attributes
- ----------
- ellipse : `~matplotlib.patches.Ellipse`
- Ellipse patch drawn.
- """
- self._box = AuxTransformBox(transform)
- self.ellipse = Ellipse((0, 0), width, height, angle=angle)
- self._box.add_artist(self.ellipse)
-
- super().__init__(loc, pad=pad, borderpad=borderpad, child=self._box,
- prop=prop, frameon=frameon, **kwargs)
-
-
-class AnchoredSizeBar(AnchoredOffsetbox):
- def __init__(self, transform, size, label, loc,
- pad=0.1, borderpad=0.1, sep=2,
- frameon=True, size_vertical=0, color='black',
- label_top=False, fontproperties=None, fill_bar=None,
- **kwargs):
- """
- Draw a horizontal scale bar with a center-aligned label underneath.
-
- Parameters
- ----------
- transform : `~matplotlib.transforms.Transform`
- The transformation object for the coordinate system in use, i.e.,
- :attr:`matplotlib.axes.Axes.transData`.
- size : float
- Horizontal length of the size bar, given in coordinates of
- *transform*.
- label : str
- Label to display.
- loc : str
- Location of the size bar. Valid locations are
- 'upper left', 'upper center', 'upper right',
- 'center left', 'center', 'center right',
- 'lower left', 'lower center', 'lower right'.
- For backward compatibility, numeric values are accepted as well.
- See the parameter *loc* of `.Legend` for details.
- pad : float, default: 0.1
- Padding around the label and size bar, in fraction of the font
- size.
- borderpad : float, default: 0.1
- Border padding, in fraction of the font size.
- sep : float, default: 2
- Separation between the label and the size bar, in points.
- frameon : bool, default: True
- If True, draw a box around the horizontal bar and label.
- size_vertical : float, default: 0
- Vertical length of the size bar, given in coordinates of
- *transform*.
- color : str, default: 'black'
- Color for the size bar and label.
- label_top : bool, default: False
- If True, the label will be over the size bar.
- fontproperties : `~matplotlib.font_manager.FontProperties`, optional
- Font properties for the label text.
- fill_bar : bool, optional
- If True and if *size_vertical* is nonzero, the size bar will
- be filled in with the color specified by the size bar.
- Defaults to True if *size_vertical* is greater than
- zero and False otherwise.
- **kwargs
- Keyword arguments forwarded to `.AnchoredOffsetbox`.
-
- Attributes
- ----------
- size_bar : `~matplotlib.offsetbox.AuxTransformBox`
- Container for the size bar.
- txt_label : `~matplotlib.offsetbox.TextArea`
- Container for the label of the size bar.
-
- Notes
- -----
- If *prop* is passed as a keyword argument, but *fontproperties* is
- not, then *prop* is assumed to be the intended *fontproperties*.
- Using both *prop* and *fontproperties* is not supported.
-
- Examples
- --------
- >>> import matplotlib.pyplot as plt
- >>> import numpy as np
- >>> from mpl_toolkits.axes_grid1.anchored_artists import (
- ... AnchoredSizeBar)
- >>> fig, ax = plt.subplots()
- >>> ax.imshow(np.random.random((10, 10)))
- >>> bar = AnchoredSizeBar(ax.transData, 3, '3 data units', 4)
- >>> ax.add_artist(bar)
- >>> fig.show()
-
- Using all the optional parameters
-
- >>> import matplotlib.font_manager as fm
- >>> fontprops = fm.FontProperties(size=14, family='monospace')
- >>> bar = AnchoredSizeBar(ax.transData, 3, '3 units', 4, pad=0.5,
- ... sep=5, borderpad=0.5, frameon=False,
- ... size_vertical=0.5, color='white',
- ... fontproperties=fontprops)
- """
- if fill_bar is None:
- fill_bar = size_vertical > 0
-
- self.size_bar = AuxTransformBox(transform)
- self.size_bar.add_artist(Rectangle((0, 0), size, size_vertical,
- fill=fill_bar, facecolor=color,
- edgecolor=color))
-
- if fontproperties is None and 'prop' in kwargs:
- fontproperties = kwargs.pop('prop')
-
- if fontproperties is None:
- textprops = {'color': color}
- else:
- textprops = {'color': color, 'fontproperties': fontproperties}
-
- self.txt_label = TextArea(label, textprops=textprops)
-
- if label_top:
- _box_children = [self.txt_label, self.size_bar]
- else:
- _box_children = [self.size_bar, self.txt_label]
-
- self._box = VPacker(children=_box_children,
- align="center",
- pad=0, sep=sep)
-
- super().__init__(loc, pad=pad, borderpad=borderpad, child=self._box,
- prop=fontproperties, frameon=frameon, **kwargs)
-
-
-class AnchoredDirectionArrows(AnchoredOffsetbox):
- def __init__(self, transform, label_x, label_y, length=0.15,
- fontsize=0.08, loc='upper left', angle=0, aspect_ratio=1,
- pad=0.4, borderpad=0.4, frameon=False, color='w', alpha=1,
- sep_x=0.01, sep_y=0, fontproperties=None, back_length=0.15,
- head_width=10, head_length=15, tail_width=2,
- text_props=None, arrow_props=None,
- **kwargs):
- """
- Draw two perpendicular arrows to indicate directions.
-
- Parameters
- ----------
- transform : `~matplotlib.transforms.Transform`
- The transformation object for the coordinate system in use, i.e.,
- :attr:`matplotlib.axes.Axes.transAxes`.
- label_x, label_y : str
- Label text for the x and y arrows
- length : float, default: 0.15
- Length of the arrow, given in coordinates of *transform*.
- fontsize : float, default: 0.08
- Size of label strings, given in coordinates of *transform*.
- loc : str, default: 'upper left'
- Location of the arrow. Valid locations are
- 'upper left', 'upper center', 'upper right',
- 'center left', 'center', 'center right',
- 'lower left', 'lower center', 'lower right'.
- For backward compatibility, numeric values are accepted as well.
- See the parameter *loc* of `.Legend` for details.
- angle : float, default: 0
- The angle of the arrows in degrees.
- aspect_ratio : float, default: 1
- The ratio of the length of arrow_x and arrow_y.
- Negative numbers can be used to change the direction.
- pad : float, default: 0.4
- Padding around the labels and arrows, in fraction of the font size.
- borderpad : float, default: 0.4
- Border padding, in fraction of the font size.
- frameon : bool, default: False
- If True, draw a box around the arrows and labels.
- color : str, default: 'white'
- Color for the arrows and labels.
- alpha : float, default: 1
- Alpha values of the arrows and labels
- sep_x, sep_y : float, default: 0.01 and 0 respectively
- Separation between the arrows and labels in coordinates of
- *transform*.
- fontproperties : `~matplotlib.font_manager.FontProperties`, optional
- Font properties for the label text.
- back_length : float, default: 0.15
- Fraction of the arrow behind the arrow crossing.
- head_width : float, default: 10
- Width of arrow head, sent to `.ArrowStyle`.
- head_length : float, default: 15
- Length of arrow head, sent to `.ArrowStyle`.
- tail_width : float, default: 2
- Width of arrow tail, sent to `.ArrowStyle`.
- text_props, arrow_props : dict
- Properties of the text and arrows, passed to `.TextPath` and
- `.FancyArrowPatch`.
- **kwargs
- Keyword arguments forwarded to `.AnchoredOffsetbox`.
-
- Attributes
- ----------
- arrow_x, arrow_y : `~matplotlib.patches.FancyArrowPatch`
- Arrow x and y
- text_path_x, text_path_y : `~matplotlib.text.TextPath`
- Path for arrow labels
- p_x, p_y : `~matplotlib.patches.PathPatch`
- Patch for arrow labels
- box : `~matplotlib.offsetbox.AuxTransformBox`
- Container for the arrows and labels.
-
- Notes
- -----
- If *prop* is passed as a keyword argument, but *fontproperties* is
- not, then *prop* is assumed to be the intended *fontproperties*.
- Using both *prop* and *fontproperties* is not supported.
-
- Examples
- --------
- >>> import matplotlib.pyplot as plt
- >>> import numpy as np
- >>> from mpl_toolkits.axes_grid1.anchored_artists import (
- ... AnchoredDirectionArrows)
- >>> fig, ax = plt.subplots()
- >>> ax.imshow(np.random.random((10, 10)))
- >>> arrows = AnchoredDirectionArrows(ax.transAxes, '111', '110')
- >>> ax.add_artist(arrows)
- >>> fig.show()
-
- Using several of the optional parameters, creating downward pointing
- arrow and high contrast text labels.
-
- >>> import matplotlib.font_manager as fm
- >>> fontprops = fm.FontProperties(family='monospace')
- >>> arrows = AnchoredDirectionArrows(ax.transAxes, 'East', 'South',
- ... loc='lower left', color='k',
- ... aspect_ratio=-1, sep_x=0.02,
- ... sep_y=-0.01,
- ... text_props={'ec':'w', 'fc':'k'},
- ... fontproperties=fontprops)
- """
- if arrow_props is None:
- arrow_props = {}
-
- if text_props is None:
- text_props = {}
-
- arrowstyle = ArrowStyle("Simple",
- head_width=head_width,
- head_length=head_length,
- tail_width=tail_width)
-
- if fontproperties is None and 'prop' in kwargs:
- fontproperties = kwargs.pop('prop')
-
- if 'color' not in arrow_props:
- arrow_props['color'] = color
-
- if 'alpha' not in arrow_props:
- arrow_props['alpha'] = alpha
-
- if 'color' not in text_props:
- text_props['color'] = color
-
- if 'alpha' not in text_props:
- text_props['alpha'] = alpha
-
- t_start = transform
- t_end = t_start + transforms.Affine2D().rotate_deg(angle)
-
- self.box = AuxTransformBox(t_end)
-
- length_x = length
- length_y = length*aspect_ratio
-
- self.arrow_x = FancyArrowPatch(
- (0, back_length*length_y),
- (length_x, back_length*length_y),
- arrowstyle=arrowstyle,
- shrinkA=0.0,
- shrinkB=0.0,
- **arrow_props)
-
- self.arrow_y = FancyArrowPatch(
- (back_length*length_x, 0),
- (back_length*length_x, length_y),
- arrowstyle=arrowstyle,
- shrinkA=0.0,
- shrinkB=0.0,
- **arrow_props)
-
- self.box.add_artist(self.arrow_x)
- self.box.add_artist(self.arrow_y)
-
- text_path_x = TextPath((
- length_x+sep_x, back_length*length_y+sep_y), label_x,
- size=fontsize, prop=fontproperties)
- self.p_x = PathPatch(text_path_x, transform=t_start, **text_props)
- self.box.add_artist(self.p_x)
-
- text_path_y = TextPath((
- length_x*back_length+sep_x, length_y*(1-back_length)+sep_y),
- label_y, size=fontsize, prop=fontproperties)
- self.p_y = PathPatch(text_path_y, **text_props)
- self.box.add_artist(self.p_y)
-
- super().__init__(loc, pad=pad, borderpad=borderpad, child=self.box,
- frameon=frameon, **kwargs)
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_divider.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_divider.py
deleted file mode 100644
index f6c38f35db..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_divider.py
+++ /dev/null
@@ -1,694 +0,0 @@
-"""
-Helper classes to adjust the positions of multiple axes at drawing time.
-"""
-
-import functools
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api
-from matplotlib.gridspec import SubplotSpec
-import matplotlib.transforms as mtransforms
-from . import axes_size as Size
-
-
-class Divider:
- """
- An Axes positioning class.
-
- The divider is initialized with lists of horizontal and vertical sizes
- (:mod:`mpl_toolkits.axes_grid1.axes_size`) based on which a given
- rectangular area will be divided.
-
- The `new_locator` method then creates a callable object
- that can be used as the *axes_locator* of the axes.
- """
-
- def __init__(self, fig, pos, horizontal, vertical,
- aspect=None, anchor="C"):
- """
- Parameters
- ----------
- fig : Figure
- pos : tuple of 4 floats
- Position of the rectangle that will be divided.
- horizontal : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`
- Sizes for horizontal division.
- vertical : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`
- Sizes for vertical division.
- aspect : bool, optional
- Whether overall rectangular area is reduced so that the relative
- part of the horizontal and vertical scales have the same scale.
- anchor : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', \
-'NW', 'W'}, default: 'C'
- Placement of the reduced rectangle, when *aspect* is True.
- """
-
- self._fig = fig
- self._pos = pos
- self._horizontal = horizontal
- self._vertical = vertical
- self._anchor = anchor
- self.set_anchor(anchor)
- self._aspect = aspect
- self._xrefindex = 0
- self._yrefindex = 0
- self._locator = None
-
- def get_horizontal_sizes(self, renderer):
- return np.array([s.get_size(renderer) for s in self.get_horizontal()])
-
- def get_vertical_sizes(self, renderer):
- return np.array([s.get_size(renderer) for s in self.get_vertical()])
-
- def set_position(self, pos):
- """
- Set the position of the rectangle.
-
- Parameters
- ----------
- pos : tuple of 4 floats
- position of the rectangle that will be divided
- """
- self._pos = pos
-
- def get_position(self):
- """Return the position of the rectangle."""
- return self._pos
-
- def set_anchor(self, anchor):
- """
- Parameters
- ----------
- anchor : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', \
-'NW', 'W'}
- Either an (*x*, *y*) pair of relative coordinates (0 is left or
- bottom, 1 is right or top), 'C' (center), or a cardinal direction
- ('SW', southwest, is bottom left, etc.).
-
- See Also
- --------
- .Axes.set_anchor
- """
- if isinstance(anchor, str):
- _api.check_in_list(mtransforms.Bbox.coefs, anchor=anchor)
- elif not isinstance(anchor, (tuple, list)) or len(anchor) != 2:
- raise TypeError("anchor must be str or 2-tuple")
- self._anchor = anchor
-
- def get_anchor(self):
- """Return the anchor."""
- return self._anchor
-
- def get_subplotspec(self):
- return None
-
- def set_horizontal(self, h):
- """
- Parameters
- ----------
- h : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`
- sizes for horizontal division
- """
- self._horizontal = h
-
- def get_horizontal(self):
- """Return horizontal sizes."""
- return self._horizontal
-
- def set_vertical(self, v):
- """
- Parameters
- ----------
- v : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`
- sizes for vertical division
- """
- self._vertical = v
-
- def get_vertical(self):
- """Return vertical sizes."""
- return self._vertical
-
- def set_aspect(self, aspect=False):
- """
- Parameters
- ----------
- aspect : bool
- """
- self._aspect = aspect
-
- def get_aspect(self):
- """Return aspect."""
- return self._aspect
-
- def set_locator(self, _locator):
- self._locator = _locator
-
- def get_locator(self):
- return self._locator
-
- def get_position_runtime(self, ax, renderer):
- if self._locator is None:
- return self.get_position()
- else:
- return self._locator(ax, renderer).bounds
-
- @staticmethod
- def _calc_k(sizes, total):
- # sizes is a (n, 2) array of (rel_size, abs_size); this method finds
- # the k factor such that sum(rel_size * k + abs_size) == total.
- rel_sum, abs_sum = sizes.sum(0)
- return (total - abs_sum) / rel_sum if rel_sum else 0
-
- @staticmethod
- def _calc_offsets(sizes, k):
- # Apply k factors to (n, 2) sizes array of (rel_size, abs_size); return
- # the resulting cumulative offset positions.
- return np.cumsum([0, *(sizes @ [k, 1])])
-
- def new_locator(self, nx, ny, nx1=None, ny1=None):
- """
- Return an axes locator callable for the specified cell.
-
- Parameters
- ----------
- nx, nx1 : int
- Integers specifying the column-position of the
- cell. When *nx1* is None, a single *nx*-th column is
- specified. Otherwise, location of columns spanning between *nx*
- to *nx1* (but excluding *nx1*-th column) is specified.
- ny, ny1 : int
- Same as *nx* and *nx1*, but for row positions.
- """
- if nx1 is None:
- nx1 = nx + 1
- if ny1 is None:
- ny1 = ny + 1
- # append_size("left") adds a new size at the beginning of the
- # horizontal size lists; this shift transforms e.g.
- # new_locator(nx=2, ...) into effectively new_locator(nx=3, ...). To
- # take that into account, instead of recording nx, we record
- # nx-self._xrefindex, where _xrefindex is shifted by 1 by each
- # append_size("left"), and re-add self._xrefindex back to nx in
- # _locate, when the actual axes position is computed. Ditto for y.
- xref = self._xrefindex
- yref = self._yrefindex
- locator = functools.partial(
- self._locate, nx - xref, ny - yref, nx1 - xref, ny1 - yref)
- locator.get_subplotspec = self.get_subplotspec
- return locator
-
- @_api.deprecated(
- "3.8", alternative="divider.new_locator(...)(ax, renderer)")
- def locate(self, nx, ny, nx1=None, ny1=None, axes=None, renderer=None):
- """
- Implementation of ``divider.new_locator().__call__``.
-
- Parameters
- ----------
- nx, nx1 : int
- Integers specifying the column-position of the cell. When *nx1* is
- None, a single *nx*-th column is specified. Otherwise, the
- location of columns spanning between *nx* to *nx1* (but excluding
- *nx1*-th column) is specified.
- ny, ny1 : int
- Same as *nx* and *nx1*, but for row positions.
- axes
- renderer
- """
- xref = self._xrefindex
- yref = self._yrefindex
- return self._locate(
- nx - xref, (nx + 1 if nx1 is None else nx1) - xref,
- ny - yref, (ny + 1 if ny1 is None else ny1) - yref,
- axes, renderer)
-
- def _locate(self, nx, ny, nx1, ny1, axes, renderer):
- """
- Implementation of ``divider.new_locator().__call__``.
-
- The axes locator callable returned by ``new_locator()`` is created as
- a `functools.partial` of this method with *nx*, *ny*, *nx1*, and *ny1*
- specifying the requested cell.
- """
- nx += self._xrefindex
- nx1 += self._xrefindex
- ny += self._yrefindex
- ny1 += self._yrefindex
-
- fig_w, fig_h = self._fig.bbox.size / self._fig.dpi
- x, y, w, h = self.get_position_runtime(axes, renderer)
-
- hsizes = self.get_horizontal_sizes(renderer)
- vsizes = self.get_vertical_sizes(renderer)
- k_h = self._calc_k(hsizes, fig_w * w)
- k_v = self._calc_k(vsizes, fig_h * h)
-
- if self.get_aspect():
- k = min(k_h, k_v)
- ox = self._calc_offsets(hsizes, k)
- oy = self._calc_offsets(vsizes, k)
-
- ww = (ox[-1] - ox[0]) / fig_w
- hh = (oy[-1] - oy[0]) / fig_h
- pb = mtransforms.Bbox.from_bounds(x, y, w, h)
- pb1 = mtransforms.Bbox.from_bounds(x, y, ww, hh)
- x0, y0 = pb1.anchored(self.get_anchor(), pb).p0
-
- else:
- ox = self._calc_offsets(hsizes, k_h)
- oy = self._calc_offsets(vsizes, k_v)
- x0, y0 = x, y
-
- if nx1 is None:
- nx1 = -1
- if ny1 is None:
- ny1 = -1
-
- x1, w1 = x0 + ox[nx] / fig_w, (ox[nx1] - ox[nx]) / fig_w
- y1, h1 = y0 + oy[ny] / fig_h, (oy[ny1] - oy[ny]) / fig_h
-
- return mtransforms.Bbox.from_bounds(x1, y1, w1, h1)
-
- def append_size(self, position, size):
- _api.check_in_list(["left", "right", "bottom", "top"],
- position=position)
- if position == "left":
- self._horizontal.insert(0, size)
- self._xrefindex += 1
- elif position == "right":
- self._horizontal.append(size)
- elif position == "bottom":
- self._vertical.insert(0, size)
- self._yrefindex += 1
- else: # 'top'
- self._vertical.append(size)
-
- def add_auto_adjustable_area(self, use_axes, pad=0.1, adjust_dirs=None):
- """
- Add auto-adjustable padding around *use_axes* to take their decorations
- (title, labels, ticks, ticklabels) into account during layout.
-
- Parameters
- ----------
- use_axes : `~matplotlib.axes.Axes` or list of `~matplotlib.axes.Axes`
- The Axes whose decorations are taken into account.
- pad : float, default: 0.1
- Additional padding in inches.
- adjust_dirs : list of {"left", "right", "bottom", "top"}, optional
- The sides where padding is added; defaults to all four sides.
- """
- if adjust_dirs is None:
- adjust_dirs = ["left", "right", "bottom", "top"]
- for d in adjust_dirs:
- self.append_size(d, Size._AxesDecorationsSize(use_axes, d) + pad)
-
-
-@_api.deprecated("3.8")
-class AxesLocator:
- """
- A callable object which returns the position and size of a given
- `.AxesDivider` cell.
- """
-
- def __init__(self, axes_divider, nx, ny, nx1=None, ny1=None):
- """
- Parameters
- ----------
- axes_divider : `~mpl_toolkits.axes_grid1.axes_divider.AxesDivider`
- nx, nx1 : int
- Integers specifying the column-position of the
- cell. When *nx1* is None, a single *nx*-th column is
- specified. Otherwise, location of columns spanning between *nx*
- to *nx1* (but excluding *nx1*-th column) is specified.
- ny, ny1 : int
- Same as *nx* and *nx1*, but for row positions.
- """
- self._axes_divider = axes_divider
-
- _xrefindex = axes_divider._xrefindex
- _yrefindex = axes_divider._yrefindex
-
- self._nx, self._ny = nx - _xrefindex, ny - _yrefindex
-
- if nx1 is None:
- nx1 = len(self._axes_divider)
- if ny1 is None:
- ny1 = len(self._axes_divider[0])
-
- self._nx1 = nx1 - _xrefindex
- self._ny1 = ny1 - _yrefindex
-
- def __call__(self, axes, renderer):
-
- _xrefindex = self._axes_divider._xrefindex
- _yrefindex = self._axes_divider._yrefindex
-
- return self._axes_divider.locate(self._nx + _xrefindex,
- self._ny + _yrefindex,
- self._nx1 + _xrefindex,
- self._ny1 + _yrefindex,
- axes,
- renderer)
-
- def get_subplotspec(self):
- return self._axes_divider.get_subplotspec()
-
-
-class SubplotDivider(Divider):
- """
- The Divider class whose rectangle area is specified as a subplot geometry.
- """
-
- def __init__(self, fig, *args, horizontal=None, vertical=None,
- aspect=None, anchor='C'):
- """
- Parameters
- ----------
- fig : `~matplotlib.figure.Figure`
-
- *args : tuple (*nrows*, *ncols*, *index*) or int
- The array of subplots in the figure has dimensions ``(nrows,
- ncols)``, and *index* is the index of the subplot being created.
- *index* starts at 1 in the upper left corner and increases to the
- right.
-
- If *nrows*, *ncols*, and *index* are all single digit numbers, then
- *args* can be passed as a single 3-digit number (e.g. 234 for
- (2, 3, 4)).
- horizontal : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`, optional
- Sizes for horizontal division.
- vertical : list of :mod:`~mpl_toolkits.axes_grid1.axes_size`, optional
- Sizes for vertical division.
- aspect : bool, optional
- Whether overall rectangular area is reduced so that the relative
- part of the horizontal and vertical scales have the same scale.
- anchor : (float, float) or {'C', 'SW', 'S', 'SE', 'E', 'NE', 'N', \
-'NW', 'W'}, default: 'C'
- Placement of the reduced rectangle, when *aspect* is True.
- """
- self.figure = fig
- super().__init__(fig, [0, 0, 1, 1],
- horizontal=horizontal or [], vertical=vertical or [],
- aspect=aspect, anchor=anchor)
- self.set_subplotspec(SubplotSpec._from_subplot_args(fig, args))
-
- def get_position(self):
- """Return the bounds of the subplot box."""
- return self.get_subplotspec().get_position(self.figure).bounds
-
- def get_subplotspec(self):
- """Get the SubplotSpec instance."""
- return self._subplotspec
-
- def set_subplotspec(self, subplotspec):
- """Set the SubplotSpec instance."""
- self._subplotspec = subplotspec
- self.set_position(subplotspec.get_position(self.figure))
-
-
-class AxesDivider(Divider):
- """
- Divider based on the preexisting axes.
- """
-
- def __init__(self, axes, xref=None, yref=None):
- """
- Parameters
- ----------
- axes : :class:`~matplotlib.axes.Axes`
- xref
- yref
- """
- self._axes = axes
- if xref is None:
- self._xref = Size.AxesX(axes)
- else:
- self._xref = xref
- if yref is None:
- self._yref = Size.AxesY(axes)
- else:
- self._yref = yref
-
- super().__init__(fig=axes.get_figure(), pos=None,
- horizontal=[self._xref], vertical=[self._yref],
- aspect=None, anchor="C")
-
- def _get_new_axes(self, *, axes_class=None, **kwargs):
- axes = self._axes
- if axes_class is None:
- axes_class = type(axes)
- return axes_class(axes.get_figure(), axes.get_position(original=True),
- **kwargs)
-
- def new_horizontal(self, size, pad=None, pack_start=False, **kwargs):
- """
- Helper method for ``append_axes("left")`` and ``append_axes("right")``.
-
- See the documentation of `append_axes` for more details.
-
- :meta private:
- """
- if pad is None:
- pad = mpl.rcParams["figure.subplot.wspace"] * self._xref
- pos = "left" if pack_start else "right"
- if pad:
- if not isinstance(pad, Size._Base):
- pad = Size.from_any(pad, fraction_ref=self._xref)
- self.append_size(pos, pad)
- if not isinstance(size, Size._Base):
- size = Size.from_any(size, fraction_ref=self._xref)
- self.append_size(pos, size)
- locator = self.new_locator(
- nx=0 if pack_start else len(self._horizontal) - 1,
- ny=self._yrefindex)
- ax = self._get_new_axes(**kwargs)
- ax.set_axes_locator(locator)
- return ax
-
- def new_vertical(self, size, pad=None, pack_start=False, **kwargs):
- """
- Helper method for ``append_axes("top")`` and ``append_axes("bottom")``.
-
- See the documentation of `append_axes` for more details.
-
- :meta private:
- """
- if pad is None:
- pad = mpl.rcParams["figure.subplot.hspace"] * self._yref
- pos = "bottom" if pack_start else "top"
- if pad:
- if not isinstance(pad, Size._Base):
- pad = Size.from_any(pad, fraction_ref=self._yref)
- self.append_size(pos, pad)
- if not isinstance(size, Size._Base):
- size = Size.from_any(size, fraction_ref=self._yref)
- self.append_size(pos, size)
- locator = self.new_locator(
- nx=self._xrefindex,
- ny=0 if pack_start else len(self._vertical) - 1)
- ax = self._get_new_axes(**kwargs)
- ax.set_axes_locator(locator)
- return ax
-
- def append_axes(self, position, size, pad=None, *, axes_class=None,
- **kwargs):
- """
- Add a new axes on a given side of the main axes.
-
- Parameters
- ----------
- position : {"left", "right", "bottom", "top"}
- Where the new axes is positioned relative to the main axes.
- size : :mod:`~mpl_toolkits.axes_grid1.axes_size` or float or str
- The axes width or height. float or str arguments are interpreted
- as ``axes_size.from_any(size, AxesX(<main_axes>))`` for left or
- right axes, and likewise with ``AxesY`` for bottom or top axes.
- pad : :mod:`~mpl_toolkits.axes_grid1.axes_size` or float or str
- Padding between the axes. float or str arguments are interpreted
- as for *size*. Defaults to :rc:`figure.subplot.wspace` times the
- main Axes width (left or right axes) or :rc:`figure.subplot.hspace`
- times the main Axes height (bottom or top axes).
- axes_class : subclass type of `~.axes.Axes`, optional
- The type of the new axes. Defaults to the type of the main axes.
- **kwargs
- All extra keywords arguments are passed to the created axes.
- """
- create_axes, pack_start = _api.check_getitem({
- "left": (self.new_horizontal, True),
- "right": (self.new_horizontal, False),
- "bottom": (self.new_vertical, True),
- "top": (self.new_vertical, False),
- }, position=position)
- ax = create_axes(
- size, pad, pack_start=pack_start, axes_class=axes_class, **kwargs)
- self._fig.add_axes(ax)
- return ax
-
- def get_aspect(self):
- if self._aspect is None:
- aspect = self._axes.get_aspect()
- if aspect == "auto":
- return False
- else:
- return True
- else:
- return self._aspect
-
- def get_position(self):
- if self._pos is None:
- bbox = self._axes.get_position(original=True)
- return bbox.bounds
- else:
- return self._pos
-
- def get_anchor(self):
- if self._anchor is None:
- return self._axes.get_anchor()
- else:
- return self._anchor
-
- def get_subplotspec(self):
- return self._axes.get_subplotspec()
-
-
-# Helper for HBoxDivider/VBoxDivider.
-# The variable names are written for a horizontal layout, but the calculations
-# work identically for vertical layouts.
-def _locate(x, y, w, h, summed_widths, equal_heights, fig_w, fig_h, anchor):
-
- total_width = fig_w * w
- max_height = fig_h * h
-
- # Determine the k factors.
- n = len(equal_heights)
- eq_rels, eq_abss = equal_heights.T
- sm_rels, sm_abss = summed_widths.T
- A = np.diag([*eq_rels, 0])
- A[:n, -1] = -1
- A[-1, :-1] = sm_rels
- B = [*(-eq_abss), total_width - sm_abss.sum()]
- # A @ K = B: This finds factors {k_0, ..., k_{N-1}, H} so that
- # eq_rel_i * k_i + eq_abs_i = H for all i: all axes have the same height
- # sum(sm_rel_i * k_i + sm_abs_i) = total_width: fixed total width
- # (foo_rel_i * k_i + foo_abs_i will end up being the size of foo.)
- *karray, height = np.linalg.solve(A, B)
- if height > max_height: # Additionally, upper-bound the height.
- karray = (max_height - eq_abss) / eq_rels
-
- # Compute the offsets corresponding to these factors.
- ox = np.cumsum([0, *(sm_rels * karray + sm_abss)])
- ww = (ox[-1] - ox[0]) / fig_w
- h0_rel, h0_abs = equal_heights[0]
- hh = (karray[0]*h0_rel + h0_abs) / fig_h
- pb = mtransforms.Bbox.from_bounds(x, y, w, h)
- pb1 = mtransforms.Bbox.from_bounds(x, y, ww, hh)
- x0, y0 = pb1.anchored(anchor, pb).p0
-
- return x0, y0, ox, hh
-
-
-class HBoxDivider(SubplotDivider):
- """
- A `.SubplotDivider` for laying out axes horizontally, while ensuring that
- they have equal heights.
-
- Examples
- --------
- .. plot:: gallery/axes_grid1/demo_axes_hbox_divider.py
- """
-
- def new_locator(self, nx, nx1=None):
- """
- Create an axes locator callable for the specified cell.
-
- Parameters
- ----------
- nx, nx1 : int
- Integers specifying the column-position of the
- cell. When *nx1* is None, a single *nx*-th column is
- specified. Otherwise, location of columns spanning between *nx*
- to *nx1* (but excluding *nx1*-th column) is specified.
- """
- return super().new_locator(nx, 0, nx1, 0)
-
- def _locate(self, nx, ny, nx1, ny1, axes, renderer):
- # docstring inherited
- nx += self._xrefindex
- nx1 += self._xrefindex
- fig_w, fig_h = self._fig.bbox.size / self._fig.dpi
- x, y, w, h = self.get_position_runtime(axes, renderer)
- summed_ws = self.get_horizontal_sizes(renderer)
- equal_hs = self.get_vertical_sizes(renderer)
- x0, y0, ox, hh = _locate(
- x, y, w, h, summed_ws, equal_hs, fig_w, fig_h, self.get_anchor())
- if nx1 is None:
- nx1 = -1
- x1, w1 = x0 + ox[nx] / fig_w, (ox[nx1] - ox[nx]) / fig_w
- y1, h1 = y0, hh
- return mtransforms.Bbox.from_bounds(x1, y1, w1, h1)
-
-
-class VBoxDivider(SubplotDivider):
- """
- A `.SubplotDivider` for laying out axes vertically, while ensuring that
- they have equal widths.
- """
-
- def new_locator(self, ny, ny1=None):
- """
- Create an axes locator callable for the specified cell.
-
- Parameters
- ----------
- ny, ny1 : int
- Integers specifying the row-position of the
- cell. When *ny1* is None, a single *ny*-th row is
- specified. Otherwise, location of rows spanning between *ny*
- to *ny1* (but excluding *ny1*-th row) is specified.
- """
- return super().new_locator(0, ny, 0, ny1)
-
- def _locate(self, nx, ny, nx1, ny1, axes, renderer):
- # docstring inherited
- ny += self._yrefindex
- ny1 += self._yrefindex
- fig_w, fig_h = self._fig.bbox.size / self._fig.dpi
- x, y, w, h = self.get_position_runtime(axes, renderer)
- summed_hs = self.get_vertical_sizes(renderer)
- equal_ws = self.get_horizontal_sizes(renderer)
- y0, x0, oy, ww = _locate(
- y, x, h, w, summed_hs, equal_ws, fig_h, fig_w, self.get_anchor())
- if ny1 is None:
- ny1 = -1
- x1, w1 = x0, ww
- y1, h1 = y0 + oy[ny] / fig_h, (oy[ny1] - oy[ny]) / fig_h
- return mtransforms.Bbox.from_bounds(x1, y1, w1, h1)
-
-
-def make_axes_locatable(axes):
- divider = AxesDivider(axes)
- locator = divider.new_locator(nx=0, ny=0)
- axes.set_axes_locator(locator)
-
- return divider
-
-
-def make_axes_area_auto_adjustable(
- ax, use_axes=None, pad=0.1, adjust_dirs=None):
- """
- Add auto-adjustable padding around *ax* to take its decorations (title,
- labels, ticks, ticklabels) into account during layout, using
- `.Divider.add_auto_adjustable_area`.
-
- By default, padding is determined from the decorations of *ax*.
- Pass *use_axes* to consider the decorations of other Axes instead.
- """
- if adjust_dirs is None:
- adjust_dirs = ["left", "right", "bottom", "top"]
- divider = make_axes_locatable(ax)
- if use_axes is None:
- use_axes = ax
- divider.add_auto_adjustable_area(use_axes=use_axes, pad=pad,
- adjust_dirs=adjust_dirs)
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_grid.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_grid.py
deleted file mode 100644
index 720d985414..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_grid.py
+++ /dev/null
@@ -1,550 +0,0 @@
-from numbers import Number
-import functools
-from types import MethodType
-
-import numpy as np
-
-from matplotlib import _api, cbook
-from matplotlib.gridspec import SubplotSpec
-
-from .axes_divider import Size, SubplotDivider, Divider
-from .mpl_axes import Axes, SimpleAxisArtist
-
-
-class CbarAxesBase:
- def __init__(self, *args, orientation, **kwargs):
- self.orientation = orientation
- super().__init__(*args, **kwargs)
-
- def colorbar(self, mappable, **kwargs):
- return self.figure.colorbar(
- mappable, cax=self, location=self.orientation, **kwargs)
-
- @_api.deprecated("3.8", alternative="ax.tick_params and colorbar.set_label")
- def toggle_label(self, b):
- axis = self.axis[self.orientation]
- axis.toggle(ticklabels=b, label=b)
-
-
-_cbaraxes_class_factory = cbook._make_class_factory(CbarAxesBase, "Cbar{}")
-
-
-class Grid:
- """
- A grid of Axes.
-
- In Matplotlib, the Axes location (and size) is specified in normalized
- figure coordinates. This may not be ideal for images that needs to be
- displayed with a given aspect ratio; for example, it is difficult to
- display multiple images of a same size with some fixed padding between
- them. AxesGrid can be used in such case.
- """
-
- _defaultAxesClass = Axes
-
- def __init__(self, fig,
- rect,
- nrows_ncols,
- ngrids=None,
- direction="row",
- axes_pad=0.02,
- *,
- share_all=False,
- share_x=True,
- share_y=True,
- label_mode="L",
- axes_class=None,
- aspect=False,
- ):
- """
- Parameters
- ----------
- fig : `.Figure`
- The parent figure.
- rect : (float, float, float, float), (int, int, int), int, or \
- `~.SubplotSpec`
- The axes position, as a ``(left, bottom, width, height)`` tuple,
- as a three-digit subplot position code (e.g., ``(1, 2, 1)`` or
- ``121``), or as a `~.SubplotSpec`.
- nrows_ncols : (int, int)
- Number of rows and columns in the grid.
- ngrids : int or None, default: None
- If not None, only the first *ngrids* axes in the grid are created.
- direction : {"row", "column"}, default: "row"
- Whether axes are created in row-major ("row by row") or
- column-major order ("column by column"). This also affects the
- order in which axes are accessed using indexing (``grid[index]``).
- axes_pad : float or (float, float), default: 0.02
- Padding or (horizontal padding, vertical padding) between axes, in
- inches.
- share_all : bool, default: False
- Whether all axes share their x- and y-axis. Overrides *share_x*
- and *share_y*.
- share_x : bool, default: True
- Whether all axes of a column share their x-axis.
- share_y : bool, default: True
- Whether all axes of a row share their y-axis.
- label_mode : {"L", "1", "all", "keep"}, default: "L"
- Determines which axes will get tick labels:
-
- - "L": All axes on the left column get vertical tick labels;
- all axes on the bottom row get horizontal tick labels.
- - "1": Only the bottom left axes is labelled.
- - "all": All axes are labelled.
- - "keep": Do not do anything.
-
- axes_class : subclass of `matplotlib.axes.Axes`, default: None
- aspect : bool, default: False
- Whether the axes aspect ratio follows the aspect ratio of the data
- limits.
- """
- self._nrows, self._ncols = nrows_ncols
-
- if ngrids is None:
- ngrids = self._nrows * self._ncols
- else:
- if not 0 < ngrids <= self._nrows * self._ncols:
- raise ValueError(
- "ngrids must be positive and not larger than nrows*ncols")
-
- self.ngrids = ngrids
-
- self._horiz_pad_size, self._vert_pad_size = map(
- Size.Fixed, np.broadcast_to(axes_pad, 2))
-
- _api.check_in_list(["column", "row"], direction=direction)
- self._direction = direction
-
- if axes_class is None:
- axes_class = self._defaultAxesClass
- elif isinstance(axes_class, (list, tuple)):
- cls, kwargs = axes_class
- axes_class = functools.partial(cls, **kwargs)
-
- kw = dict(horizontal=[], vertical=[], aspect=aspect)
- if isinstance(rect, (Number, SubplotSpec)):
- self._divider = SubplotDivider(fig, rect, **kw)
- elif len(rect) == 3:
- self._divider = SubplotDivider(fig, *rect, **kw)
- elif len(rect) == 4:
- self._divider = Divider(fig, rect, **kw)
- else:
- raise TypeError("Incorrect rect format")
-
- rect = self._divider.get_position()
-
- axes_array = np.full((self._nrows, self._ncols), None, dtype=object)
- for i in range(self.ngrids):
- col, row = self._get_col_row(i)
- if share_all:
- sharex = sharey = axes_array[0, 0]
- else:
- sharex = axes_array[0, col] if share_x else None
- sharey = axes_array[row, 0] if share_y else None
- axes_array[row, col] = axes_class(
- fig, rect, sharex=sharex, sharey=sharey)
- self.axes_all = axes_array.ravel(
- order="C" if self._direction == "row" else "F").tolist()
- self.axes_column = axes_array.T.tolist()
- self.axes_row = axes_array.tolist()
- self.axes_llc = self.axes_column[0][-1]
-
- self._init_locators()
-
- for ax in self.axes_all:
- fig.add_axes(ax)
-
- self.set_label_mode(label_mode)
-
- def _init_locators(self):
- self._divider.set_horizontal(
- [Size.Scaled(1), self._horiz_pad_size] * (self._ncols-1) + [Size.Scaled(1)])
- self._divider.set_vertical(
- [Size.Scaled(1), self._vert_pad_size] * (self._nrows-1) + [Size.Scaled(1)])
- for i in range(self.ngrids):
- col, row = self._get_col_row(i)
- self.axes_all[i].set_axes_locator(
- self._divider.new_locator(nx=2 * col, ny=2 * (self._nrows - 1 - row)))
-
- def _get_col_row(self, n):
- if self._direction == "column":
- col, row = divmod(n, self._nrows)
- else:
- row, col = divmod(n, self._ncols)
-
- return col, row
-
- # Good to propagate __len__ if we have __getitem__
- def __len__(self):
- return len(self.axes_all)
-
- def __getitem__(self, i):
- return self.axes_all[i]
-
- def get_geometry(self):
- """
- Return the number of rows and columns of the grid as (nrows, ncols).
- """
- return self._nrows, self._ncols
-
- def set_axes_pad(self, axes_pad):
- """
- Set the padding between the axes.
-
- Parameters
- ----------
- axes_pad : (float, float)
- The padding (horizontal pad, vertical pad) in inches.
- """
- self._horiz_pad_size.fixed_size = axes_pad[0]
- self._vert_pad_size.fixed_size = axes_pad[1]
-
- def get_axes_pad(self):
- """
- Return the axes padding.
-
- Returns
- -------
- hpad, vpad
- Padding (horizontal pad, vertical pad) in inches.
- """
- return (self._horiz_pad_size.fixed_size,
- self._vert_pad_size.fixed_size)
-
- def set_aspect(self, aspect):
- """Set the aspect of the SubplotDivider."""
- self._divider.set_aspect(aspect)
-
- def get_aspect(self):
- """Return the aspect of the SubplotDivider."""
- return self._divider.get_aspect()
-
- def set_label_mode(self, mode):
- """
- Define which axes have tick labels.
-
- Parameters
- ----------
- mode : {"L", "1", "all", "keep"}
- The label mode:
-
- - "L": All axes on the left column get vertical tick labels;
- all axes on the bottom row get horizontal tick labels.
- - "1": Only the bottom left axes is labelled.
- - "all": All axes are labelled.
- - "keep": Do not do anything.
- """
- is_last_row, is_first_col = (
- np.mgrid[:self._nrows, :self._ncols] == [[[self._nrows - 1]], [[0]]])
- if mode == "all":
- bottom = left = np.full((self._nrows, self._ncols), True)
- elif mode == "L":
- bottom = is_last_row
- left = is_first_col
- elif mode == "1":
- bottom = left = is_last_row & is_first_col
- else:
- # Use _api.check_in_list at the top of the method when deprecation
- # period expires
- if mode != 'keep':
- _api.warn_deprecated(
- '3.7', name="Grid label_mode",
- message='Passing an undefined label_mode is deprecated '
- 'since %(since)s and will become an error '
- '%(removal)s. To silence this warning, pass '
- '"keep", which gives the same behaviour.')
- return
- for i in range(self._nrows):
- for j in range(self._ncols):
- ax = self.axes_row[i][j]
- if isinstance(ax.axis, MethodType):
- bottom_axis = SimpleAxisArtist(ax.xaxis, 1, ax.spines["bottom"])
- left_axis = SimpleAxisArtist(ax.yaxis, 1, ax.spines["left"])
- else:
- bottom_axis = ax.axis["bottom"]
- left_axis = ax.axis["left"]
- bottom_axis.toggle(ticklabels=bottom[i, j], label=bottom[i, j])
- left_axis.toggle(ticklabels=left[i, j], label=left[i, j])
-
- def get_divider(self):
- return self._divider
-
- def set_axes_locator(self, locator):
- self._divider.set_locator(locator)
-
- def get_axes_locator(self):
- return self._divider.get_locator()
-
-
-class ImageGrid(Grid):
- """
- A grid of Axes for Image display.
-
- This class is a specialization of `~.axes_grid1.axes_grid.Grid` for displaying a
- grid of images. In particular, it forces all axes in a column to share their x-axis
- and all axes in a row to share their y-axis. It further provides helpers to add
- colorbars to some or all axes.
- """
-
- def __init__(self, fig,
- rect,
- nrows_ncols,
- ngrids=None,
- direction="row",
- axes_pad=0.02,
- *,
- share_all=False,
- aspect=True,
- label_mode="L",
- cbar_mode=None,
- cbar_location="right",
- cbar_pad=None,
- cbar_size="5%",
- cbar_set_cax=True,
- axes_class=None,
- ):
- """
- Parameters
- ----------
- fig : `.Figure`
- The parent figure.
- rect : (float, float, float, float) or int
- The axes position, as a ``(left, bottom, width, height)`` tuple or
- as a three-digit subplot position code (e.g., "121").
- nrows_ncols : (int, int)
- Number of rows and columns in the grid.
- ngrids : int or None, default: None
- If not None, only the first *ngrids* axes in the grid are created.
- direction : {"row", "column"}, default: "row"
- Whether axes are created in row-major ("row by row") or
- column-major order ("column by column"). This also affects the
- order in which axes are accessed using indexing (``grid[index]``).
- axes_pad : float or (float, float), default: 0.02in
- Padding or (horizontal padding, vertical padding) between axes, in
- inches.
- share_all : bool, default: False
- Whether all axes share their x- and y-axis. Note that in any case,
- all axes in a column share their x-axis and all axes in a row share
- their y-axis.
- aspect : bool, default: True
- Whether the axes aspect ratio follows the aspect ratio of the data
- limits.
- label_mode : {"L", "1", "all"}, default: "L"
- Determines which axes will get tick labels:
-
- - "L": All axes on the left column get vertical tick labels;
- all axes on the bottom row get horizontal tick labels.
- - "1": Only the bottom left axes is labelled.
- - "all": all axes are labelled.
-
- cbar_mode : {"each", "single", "edge", None}, default: None
- Whether to create a colorbar for "each" axes, a "single" colorbar
- for the entire grid, colorbars only for axes on the "edge"
- determined by *cbar_location*, or no colorbars. The colorbars are
- stored in the :attr:`cbar_axes` attribute.
- cbar_location : {"left", "right", "bottom", "top"}, default: "right"
- cbar_pad : float, default: None
- Padding between the image axes and the colorbar axes.
- cbar_size : size specification (see `.Size.from_any`), default: "5%"
- Colorbar size.
- cbar_set_cax : bool, default: True
- If True, each axes in the grid has a *cax* attribute that is bound
- to associated *cbar_axes*.
- axes_class : subclass of `matplotlib.axes.Axes`, default: None
- """
- _api.check_in_list(["each", "single", "edge", None],
- cbar_mode=cbar_mode)
- _api.check_in_list(["left", "right", "bottom", "top"],
- cbar_location=cbar_location)
- self._colorbar_mode = cbar_mode
- self._colorbar_location = cbar_location
- self._colorbar_pad = cbar_pad
- self._colorbar_size = cbar_size
- # The colorbar axes are created in _init_locators().
-
- super().__init__(
- fig, rect, nrows_ncols, ngrids,
- direction=direction, axes_pad=axes_pad,
- share_all=share_all, share_x=True, share_y=True, aspect=aspect,
- label_mode=label_mode, axes_class=axes_class)
-
- for ax in self.cbar_axes:
- fig.add_axes(ax)
-
- if cbar_set_cax:
- if self._colorbar_mode == "single":
- for ax in self.axes_all:
- ax.cax = self.cbar_axes[0]
- elif self._colorbar_mode == "edge":
- for index, ax in enumerate(self.axes_all):
- col, row = self._get_col_row(index)
- if self._colorbar_location in ("left", "right"):
- ax.cax = self.cbar_axes[row]
- else:
- ax.cax = self.cbar_axes[col]
- else:
- for ax, cax in zip(self.axes_all, self.cbar_axes):
- ax.cax = cax
-
- def _init_locators(self):
- # Slightly abusing this method to inject colorbar creation into init.
-
- if self._colorbar_pad is None:
- # horizontal or vertical arrangement?
- if self._colorbar_location in ("left", "right"):
- self._colorbar_pad = self._horiz_pad_size.fixed_size
- else:
- self._colorbar_pad = self._vert_pad_size.fixed_size
- self.cbar_axes = [
- _cbaraxes_class_factory(self._defaultAxesClass)(
- self.axes_all[0].figure, self._divider.get_position(),
- orientation=self._colorbar_location)
- for _ in range(self.ngrids)]
-
- cb_mode = self._colorbar_mode
- cb_location = self._colorbar_location
-
- h = []
- v = []
-
- h_ax_pos = []
- h_cb_pos = []
- if cb_mode == "single" and cb_location in ("left", "bottom"):
- if cb_location == "left":
- sz = self._nrows * Size.AxesX(self.axes_llc)
- h.append(Size.from_any(self._colorbar_size, sz))
- h.append(Size.from_any(self._colorbar_pad, sz))
- locator = self._divider.new_locator(nx=0, ny=0, ny1=-1)
- elif cb_location == "bottom":
- sz = self._ncols * Size.AxesY(self.axes_llc)
- v.append(Size.from_any(self._colorbar_size, sz))
- v.append(Size.from_any(self._colorbar_pad, sz))
- locator = self._divider.new_locator(nx=0, nx1=-1, ny=0)
- for i in range(self.ngrids):
- self.cbar_axes[i].set_visible(False)
- self.cbar_axes[0].set_axes_locator(locator)
- self.cbar_axes[0].set_visible(True)
-
- for col, ax in enumerate(self.axes_row[0]):
- if h:
- h.append(self._horiz_pad_size)
-
- if ax:
- sz = Size.AxesX(ax, aspect="axes", ref_ax=self.axes_all[0])
- else:
- sz = Size.AxesX(self.axes_all[0],
- aspect="axes", ref_ax=self.axes_all[0])
-
- if (cb_location == "left"
- and (cb_mode == "each"
- or (cb_mode == "edge" and col == 0))):
- h_cb_pos.append(len(h))
- h.append(Size.from_any(self._colorbar_size, sz))
- h.append(Size.from_any(self._colorbar_pad, sz))
-
- h_ax_pos.append(len(h))
- h.append(sz)
-
- if (cb_location == "right"
- and (cb_mode == "each"
- or (cb_mode == "edge" and col == self._ncols - 1))):
- h.append(Size.from_any(self._colorbar_pad, sz))
- h_cb_pos.append(len(h))
- h.append(Size.from_any(self._colorbar_size, sz))
-
- v_ax_pos = []
- v_cb_pos = []
- for row, ax in enumerate(self.axes_column[0][::-1]):
- if v:
- v.append(self._vert_pad_size)
-
- if ax:
- sz = Size.AxesY(ax, aspect="axes", ref_ax=self.axes_all[0])
- else:
- sz = Size.AxesY(self.axes_all[0],
- aspect="axes", ref_ax=self.axes_all[0])
-
- if (cb_location == "bottom"
- and (cb_mode == "each"
- or (cb_mode == "edge" and row == 0))):
- v_cb_pos.append(len(v))
- v.append(Size.from_any(self._colorbar_size, sz))
- v.append(Size.from_any(self._colorbar_pad, sz))
-
- v_ax_pos.append(len(v))
- v.append(sz)
-
- if (cb_location == "top"
- and (cb_mode == "each"
- or (cb_mode == "edge" and row == self._nrows - 1))):
- v.append(Size.from_any(self._colorbar_pad, sz))
- v_cb_pos.append(len(v))
- v.append(Size.from_any(self._colorbar_size, sz))
-
- for i in range(self.ngrids):
- col, row = self._get_col_row(i)
- locator = self._divider.new_locator(nx=h_ax_pos[col],
- ny=v_ax_pos[self._nrows-1-row])
- self.axes_all[i].set_axes_locator(locator)
-
- if cb_mode == "each":
- if cb_location in ("right", "left"):
- locator = self._divider.new_locator(
- nx=h_cb_pos[col], ny=v_ax_pos[self._nrows - 1 - row])
-
- elif cb_location in ("top", "bottom"):
- locator = self._divider.new_locator(
- nx=h_ax_pos[col], ny=v_cb_pos[self._nrows - 1 - row])
-
- self.cbar_axes[i].set_axes_locator(locator)
- elif cb_mode == "edge":
- if (cb_location == "left" and col == 0
- or cb_location == "right" and col == self._ncols - 1):
- locator = self._divider.new_locator(
- nx=h_cb_pos[0], ny=v_ax_pos[self._nrows - 1 - row])
- self.cbar_axes[row].set_axes_locator(locator)
- elif (cb_location == "bottom" and row == self._nrows - 1
- or cb_location == "top" and row == 0):
- locator = self._divider.new_locator(nx=h_ax_pos[col],
- ny=v_cb_pos[0])
- self.cbar_axes[col].set_axes_locator(locator)
-
- if cb_mode == "single":
- if cb_location == "right":
- sz = self._nrows * Size.AxesX(self.axes_llc)
- h.append(Size.from_any(self._colorbar_pad, sz))
- h.append(Size.from_any(self._colorbar_size, sz))
- locator = self._divider.new_locator(nx=-2, ny=0, ny1=-1)
- elif cb_location == "top":
- sz = self._ncols * Size.AxesY(self.axes_llc)
- v.append(Size.from_any(self._colorbar_pad, sz))
- v.append(Size.from_any(self._colorbar_size, sz))
- locator = self._divider.new_locator(nx=0, nx1=-1, ny=-2)
- if cb_location in ("right", "top"):
- for i in range(self.ngrids):
- self.cbar_axes[i].set_visible(False)
- self.cbar_axes[0].set_axes_locator(locator)
- self.cbar_axes[0].set_visible(True)
- elif cb_mode == "each":
- for i in range(self.ngrids):
- self.cbar_axes[i].set_visible(True)
- elif cb_mode == "edge":
- if cb_location in ("right", "left"):
- count = self._nrows
- else:
- count = self._ncols
- for i in range(count):
- self.cbar_axes[i].set_visible(True)
- for j in range(i + 1, self.ngrids):
- self.cbar_axes[j].set_visible(False)
- else:
- for i in range(self.ngrids):
- self.cbar_axes[i].set_visible(False)
- self.cbar_axes[i].set_position([1., 1., 0.001, 0.001],
- which="active")
-
- self._divider.set_horizontal(h)
- self._divider.set_vertical(v)
-
-
-AxesGrid = ImageGrid
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_rgb.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_rgb.py
deleted file mode 100644
index 52fd707e87..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_rgb.py
+++ /dev/null
@@ -1,157 +0,0 @@
-from types import MethodType
-
-import numpy as np
-
-from .axes_divider import make_axes_locatable, Size
-from .mpl_axes import Axes, SimpleAxisArtist
-
-
-def make_rgb_axes(ax, pad=0.01, axes_class=None, **kwargs):
- """
- Parameters
- ----------
- ax : `~matplotlib.axes.Axes`
- Axes instance to create the RGB Axes in.
- pad : float, optional
- Fraction of the Axes height to pad.
- axes_class : `matplotlib.axes.Axes` or None, optional
- Axes class to use for the R, G, and B Axes. If None, use
- the same class as *ax*.
- **kwargs
- Forwarded to *axes_class* init for the R, G, and B Axes.
- """
-
- divider = make_axes_locatable(ax)
-
- pad_size = pad * Size.AxesY(ax)
-
- xsize = ((1-2*pad)/3) * Size.AxesX(ax)
- ysize = ((1-2*pad)/3) * Size.AxesY(ax)
-
- divider.set_horizontal([Size.AxesX(ax), pad_size, xsize])
- divider.set_vertical([ysize, pad_size, ysize, pad_size, ysize])
-
- ax.set_axes_locator(divider.new_locator(0, 0, ny1=-1))
-
- ax_rgb = []
- if axes_class is None:
- axes_class = type(ax)
-
- for ny in [4, 2, 0]:
- ax1 = axes_class(ax.get_figure(), ax.get_position(original=True),
- sharex=ax, sharey=ax, **kwargs)
- locator = divider.new_locator(nx=2, ny=ny)
- ax1.set_axes_locator(locator)
- for t in ax1.yaxis.get_ticklabels() + ax1.xaxis.get_ticklabels():
- t.set_visible(False)
- try:
- for axis in ax1.axis.values():
- axis.major_ticklabels.set_visible(False)
- except AttributeError:
- pass
-
- ax_rgb.append(ax1)
-
- fig = ax.get_figure()
- for ax1 in ax_rgb:
- fig.add_axes(ax1)
-
- return ax_rgb
-
-
-class RGBAxes:
- """
- 4-panel `~.Axes.imshow` (RGB, R, G, B).
-
- Layout::
-
- ┌───────────────┬─────┐
- │ │ R │
- │ ├─────┤
- │ RGB │ G │
- │ ├─────┤
- │ │ B │
- └───────────────┴─────┘
-
- Subclasses can override the ``_defaultAxesClass`` attribute.
- By default RGBAxes uses `.mpl_axes.Axes`.
-
- Attributes
- ----------
- RGB : ``_defaultAxesClass``
- The Axes object for the three-channel `~.Axes.imshow`.
- R : ``_defaultAxesClass``
- The Axes object for the red channel `~.Axes.imshow`.
- G : ``_defaultAxesClass``
- The Axes object for the green channel `~.Axes.imshow`.
- B : ``_defaultAxesClass``
- The Axes object for the blue channel `~.Axes.imshow`.
- """
-
- _defaultAxesClass = Axes
-
- def __init__(self, *args, pad=0, **kwargs):
- """
- Parameters
- ----------
- pad : float, default: 0
- Fraction of the Axes height to put as padding.
- axes_class : `~matplotlib.axes.Axes`
- Axes class to use. If not provided, ``_defaultAxesClass`` is used.
- *args
- Forwarded to *axes_class* init for the RGB Axes
- **kwargs
- Forwarded to *axes_class* init for the RGB, R, G, and B Axes
- """
- axes_class = kwargs.pop("axes_class", self._defaultAxesClass)
- self.RGB = ax = axes_class(*args, **kwargs)
- ax.get_figure().add_axes(ax)
- self.R, self.G, self.B = make_rgb_axes(
- ax, pad=pad, axes_class=axes_class, **kwargs)
- # Set the line color and ticks for the axes.
- for ax1 in [self.RGB, self.R, self.G, self.B]:
- if isinstance(ax1.axis, MethodType):
- ad = Axes.AxisDict(self)
- ad.update(
- bottom=SimpleAxisArtist(ax1.xaxis, 1, ax1.spines["bottom"]),
- top=SimpleAxisArtist(ax1.xaxis, 2, ax1.spines["top"]),
- left=SimpleAxisArtist(ax1.yaxis, 1, ax1.spines["left"]),
- right=SimpleAxisArtist(ax1.yaxis, 2, ax1.spines["right"]))
- else:
- ad = ax1.axis
- ad[:].line.set_color("w")
- ad[:].major_ticks.set_markeredgecolor("w")
-
- def imshow_rgb(self, r, g, b, **kwargs):
- """
- Create the four images {rgb, r, g, b}.
-
- Parameters
- ----------
- r, g, b : array-like
- The red, green, and blue arrays.
- **kwargs
- Forwarded to `~.Axes.imshow` calls for the four images.
-
- Returns
- -------
- rgb : `~matplotlib.image.AxesImage`
- r : `~matplotlib.image.AxesImage`
- g : `~matplotlib.image.AxesImage`
- b : `~matplotlib.image.AxesImage`
- """
- if not (r.shape == g.shape == b.shape):
- raise ValueError(
- f'Input shapes ({r.shape}, {g.shape}, {b.shape}) do not match')
- RGB = np.dstack([r, g, b])
- R = np.zeros_like(RGB)
- R[:, :, 0] = r
- G = np.zeros_like(RGB)
- G[:, :, 1] = g
- B = np.zeros_like(RGB)
- B[:, :, 2] = b
- im_rgb = self.RGB.imshow(RGB, **kwargs)
- im_r = self.R.imshow(R, **kwargs)
- im_g = self.G.imshow(G, **kwargs)
- im_b = self.B.imshow(B, **kwargs)
- return im_rgb, im_r, im_g, im_b
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_size.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_size.py
deleted file mode 100644
index d251472077..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/axes_size.py
+++ /dev/null
@@ -1,248 +0,0 @@
-"""
-Provides classes of simple units that will be used with `.AxesDivider`
-class (or others) to determine the size of each Axes. The unit
-classes define `get_size` method that returns a tuple of two floats,
-meaning relative and absolute sizes, respectively.
-
-Note that this class is nothing more than a simple tuple of two
-floats. Take a look at the Divider class to see how these two
-values are used.
-"""
-
-from numbers import Real
-
-from matplotlib import _api
-from matplotlib.axes import Axes
-
-
-class _Base:
- def __rmul__(self, other):
- return Fraction(other, self)
-
- def __add__(self, other):
- if isinstance(other, _Base):
- return Add(self, other)
- else:
- return Add(self, Fixed(other))
-
- def get_size(self, renderer):
- """
- Return two-float tuple with relative and absolute sizes.
- """
- raise NotImplementedError("Subclasses must implement")
-
-
-class Add(_Base):
- """
- Sum of two sizes.
- """
-
- def __init__(self, a, b):
- self._a = a
- self._b = b
-
- def get_size(self, renderer):
- a_rel_size, a_abs_size = self._a.get_size(renderer)
- b_rel_size, b_abs_size = self._b.get_size(renderer)
- return a_rel_size + b_rel_size, a_abs_size + b_abs_size
-
-
-class Fixed(_Base):
- """
- Simple fixed size with absolute part = *fixed_size* and relative part = 0.
- """
-
- def __init__(self, fixed_size):
- _api.check_isinstance(Real, fixed_size=fixed_size)
- self.fixed_size = fixed_size
-
- def get_size(self, renderer):
- rel_size = 0.
- abs_size = self.fixed_size
- return rel_size, abs_size
-
-
-class Scaled(_Base):
- """
- Simple scaled(?) size with absolute part = 0 and
- relative part = *scalable_size*.
- """
-
- def __init__(self, scalable_size):
- self._scalable_size = scalable_size
-
- def get_size(self, renderer):
- rel_size = self._scalable_size
- abs_size = 0.
- return rel_size, abs_size
-
-Scalable = Scaled
-
-
-def _get_axes_aspect(ax):
- aspect = ax.get_aspect()
- if aspect == "auto":
- aspect = 1.
- return aspect
-
-
-class AxesX(_Base):
- """
- Scaled size whose relative part corresponds to the data width
- of the *axes* multiplied by the *aspect*.
- """
-
- def __init__(self, axes, aspect=1., ref_ax=None):
- self._axes = axes
- self._aspect = aspect
- if aspect == "axes" and ref_ax is None:
- raise ValueError("ref_ax must be set when aspect='axes'")
- self._ref_ax = ref_ax
-
- def get_size(self, renderer):
- l1, l2 = self._axes.get_xlim()
- if self._aspect == "axes":
- ref_aspect = _get_axes_aspect(self._ref_ax)
- aspect = ref_aspect / _get_axes_aspect(self._axes)
- else:
- aspect = self._aspect
-
- rel_size = abs(l2-l1)*aspect
- abs_size = 0.
- return rel_size, abs_size
-
-
-class AxesY(_Base):
- """
- Scaled size whose relative part corresponds to the data height
- of the *axes* multiplied by the *aspect*.
- """
-
- def __init__(self, axes, aspect=1., ref_ax=None):
- self._axes = axes
- self._aspect = aspect
- if aspect == "axes" and ref_ax is None:
- raise ValueError("ref_ax must be set when aspect='axes'")
- self._ref_ax = ref_ax
-
- def get_size(self, renderer):
- l1, l2 = self._axes.get_ylim()
-
- if self._aspect == "axes":
- ref_aspect = _get_axes_aspect(self._ref_ax)
- aspect = _get_axes_aspect(self._axes)
- else:
- aspect = self._aspect
-
- rel_size = abs(l2-l1)*aspect
- abs_size = 0.
- return rel_size, abs_size
-
-
-class MaxExtent(_Base):
- """
- Size whose absolute part is either the largest width or the largest height
- of the given *artist_list*.
- """
-
- def __init__(self, artist_list, w_or_h):
- self._artist_list = artist_list
- _api.check_in_list(["width", "height"], w_or_h=w_or_h)
- self._w_or_h = w_or_h
-
- def add_artist(self, a):
- self._artist_list.append(a)
-
- def get_size(self, renderer):
- rel_size = 0.
- extent_list = [
- getattr(a.get_window_extent(renderer), self._w_or_h) / a.figure.dpi
- for a in self._artist_list]
- abs_size = max(extent_list, default=0)
- return rel_size, abs_size
-
-
-class MaxWidth(MaxExtent):
- """
- Size whose absolute part is the largest width of the given *artist_list*.
- """
-
- def __init__(self, artist_list):
- super().__init__(artist_list, "width")
-
-
-class MaxHeight(MaxExtent):
- """
- Size whose absolute part is the largest height of the given *artist_list*.
- """
-
- def __init__(self, artist_list):
- super().__init__(artist_list, "height")
-
-
-class Fraction(_Base):
- """
- An instance whose size is a *fraction* of the *ref_size*.
-
- >>> s = Fraction(0.3, AxesX(ax))
- """
-
- def __init__(self, fraction, ref_size):
- _api.check_isinstance(Real, fraction=fraction)
- self._fraction_ref = ref_size
- self._fraction = fraction
-
- def get_size(self, renderer):
- if self._fraction_ref is None:
- return self._fraction, 0.
- else:
- r, a = self._fraction_ref.get_size(renderer)
- rel_size = r*self._fraction
- abs_size = a*self._fraction
- return rel_size, abs_size
-
-
-def from_any(size, fraction_ref=None):
- """
- Create a Fixed unit when the first argument is a float, or a
- Fraction unit if that is a string that ends with %. The second
- argument is only meaningful when Fraction unit is created.
-
- >>> from mpl_toolkits.axes_grid1.axes_size import from_any
- >>> a = from_any(1.2) # => Fixed(1.2)
- >>> from_any("50%", a) # => Fraction(0.5, a)
- """
- if isinstance(size, Real):
- return Fixed(size)
- elif isinstance(size, str):
- if size[-1] == "%":
- return Fraction(float(size[:-1]) / 100, fraction_ref)
- raise ValueError("Unknown format")
-
-
-class _AxesDecorationsSize(_Base):
- """
- Fixed size, corresponding to the size of decorations on a given Axes side.
- """
-
- _get_size_map = {
- "left": lambda tight_bb, axes_bb: axes_bb.xmin - tight_bb.xmin,
- "right": lambda tight_bb, axes_bb: tight_bb.xmax - axes_bb.xmax,
- "bottom": lambda tight_bb, axes_bb: axes_bb.ymin - tight_bb.ymin,
- "top": lambda tight_bb, axes_bb: tight_bb.ymax - axes_bb.ymax,
- }
-
- def __init__(self, ax, direction):
- self._get_size = _api.check_getitem(
- self._get_size_map, direction=direction)
- self._ax_list = [ax] if isinstance(ax, Axes) else ax
-
- def get_size(self, renderer):
- sz = max([
- self._get_size(ax.get_tightbbox(renderer, call_axes_locator=False),
- ax.bbox)
- for ax in self._ax_list])
- dpi = renderer.points_to_pixels(72)
- abs_size = sz / dpi
- rel_size = 0
- return rel_size, abs_size
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/inset_locator.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/inset_locator.py
deleted file mode 100644
index 6d591a4531..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/inset_locator.py
+++ /dev/null
@@ -1,561 +0,0 @@
-"""
-A collection of functions and objects for creating or placing inset axes.
-"""
-
-from matplotlib import _api, _docstring
-from matplotlib.offsetbox import AnchoredOffsetbox
-from matplotlib.patches import Patch, Rectangle
-from matplotlib.path import Path
-from matplotlib.transforms import Bbox, BboxTransformTo
-from matplotlib.transforms import IdentityTransform, TransformedBbox
-
-from . import axes_size as Size
-from .parasite_axes import HostAxes
-
-
-@_api.deprecated("3.8", alternative="Axes.inset_axes")
-class InsetPosition:
- @_docstring.dedent_interpd
- def __init__(self, parent, lbwh):
- """
- An object for positioning an inset axes.
-
- This is created by specifying the normalized coordinates in the axes,
- instead of the figure.
-
- Parameters
- ----------
- parent : `~matplotlib.axes.Axes`
- Axes to use for normalizing coordinates.
-
- lbwh : iterable of four floats
- The left edge, bottom edge, width, and height of the inset axes, in
- units of the normalized coordinate of the *parent* axes.
-
- See Also
- --------
- :meth:`matplotlib.axes.Axes.set_axes_locator`
-
- Examples
- --------
- The following bounds the inset axes to a box with 20%% of the parent
- axes height and 40%% of the width. The size of the axes specified
- ([0, 0, 1, 1]) ensures that the axes completely fills the bounding box:
-
- >>> parent_axes = plt.gca()
- >>> ax_ins = plt.axes([0, 0, 1, 1])
- >>> ip = InsetPosition(parent_axes, [0.5, 0.1, 0.4, 0.2])
- >>> ax_ins.set_axes_locator(ip)
- """
- self.parent = parent
- self.lbwh = lbwh
-
- def __call__(self, ax, renderer):
- bbox_parent = self.parent.get_position(original=False)
- trans = BboxTransformTo(bbox_parent)
- bbox_inset = Bbox.from_bounds(*self.lbwh)
- bb = TransformedBbox(bbox_inset, trans)
- return bb
-
-
-class AnchoredLocatorBase(AnchoredOffsetbox):
- def __init__(self, bbox_to_anchor, offsetbox, loc,
- borderpad=0.5, bbox_transform=None):
- super().__init__(
- loc, pad=0., child=None, borderpad=borderpad,
- bbox_to_anchor=bbox_to_anchor, bbox_transform=bbox_transform
- )
-
- def draw(self, renderer):
- raise RuntimeError("No draw method should be called")
-
- def __call__(self, ax, renderer):
- if renderer is None:
- renderer = ax.figure._get_renderer()
- self.axes = ax
- bbox = self.get_window_extent(renderer)
- px, py = self.get_offset(bbox.width, bbox.height, 0, 0, renderer)
- bbox_canvas = Bbox.from_bounds(px, py, bbox.width, bbox.height)
- tr = ax.figure.transSubfigure.inverted()
- return TransformedBbox(bbox_canvas, tr)
-
-
-class AnchoredSizeLocator(AnchoredLocatorBase):
- def __init__(self, bbox_to_anchor, x_size, y_size, loc,
- borderpad=0.5, bbox_transform=None):
- super().__init__(
- bbox_to_anchor, None, loc,
- borderpad=borderpad, bbox_transform=bbox_transform
- )
-
- self.x_size = Size.from_any(x_size)
- self.y_size = Size.from_any(y_size)
-
- def get_bbox(self, renderer):
- bbox = self.get_bbox_to_anchor()
- dpi = renderer.points_to_pixels(72.)
-
- r, a = self.x_size.get_size(renderer)
- width = bbox.width * r + a * dpi
- r, a = self.y_size.get_size(renderer)
- height = bbox.height * r + a * dpi
-
- fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
- pad = self.pad * fontsize
-
- return Bbox.from_bounds(0, 0, width, height).padded(pad)
-
-
-class AnchoredZoomLocator(AnchoredLocatorBase):
- def __init__(self, parent_axes, zoom, loc,
- borderpad=0.5,
- bbox_to_anchor=None,
- bbox_transform=None):
- self.parent_axes = parent_axes
- self.zoom = zoom
- if bbox_to_anchor is None:
- bbox_to_anchor = parent_axes.bbox
- super().__init__(
- bbox_to_anchor, None, loc, borderpad=borderpad,
- bbox_transform=bbox_transform)
-
- def get_bbox(self, renderer):
- bb = self.parent_axes.transData.transform_bbox(self.axes.viewLim)
- fontsize = renderer.points_to_pixels(self.prop.get_size_in_points())
- pad = self.pad * fontsize
- return (
- Bbox.from_bounds(
- 0, 0, abs(bb.width * self.zoom), abs(bb.height * self.zoom))
- .padded(pad))
-
-
-class BboxPatch(Patch):
- @_docstring.dedent_interpd
- def __init__(self, bbox, **kwargs):
- """
- Patch showing the shape bounded by a Bbox.
-
- Parameters
- ----------
- bbox : `~matplotlib.transforms.Bbox`
- Bbox to use for the extents of this patch.
-
- **kwargs
- Patch properties. Valid arguments include:
-
- %(Patch:kwdoc)s
- """
- if "transform" in kwargs:
- raise ValueError("transform should not be set")
-
- kwargs["transform"] = IdentityTransform()
- super().__init__(**kwargs)
- self.bbox = bbox
-
- def get_path(self):
- # docstring inherited
- x0, y0, x1, y1 = self.bbox.extents
- return Path._create_closed([(x0, y0), (x1, y0), (x1, y1), (x0, y1)])
-
-
-class BboxConnector(Patch):
- @staticmethod
- def get_bbox_edge_pos(bbox, loc):
- """
- Return the ``(x, y)`` coordinates of corner *loc* of *bbox*; parameters
- behave as documented for the `.BboxConnector` constructor.
- """
- x0, y0, x1, y1 = bbox.extents
- if loc == 1:
- return x1, y1
- elif loc == 2:
- return x0, y1
- elif loc == 3:
- return x0, y0
- elif loc == 4:
- return x1, y0
-
- @staticmethod
- def connect_bbox(bbox1, bbox2, loc1, loc2=None):
- """
- Construct a `.Path` connecting corner *loc1* of *bbox1* to corner
- *loc2* of *bbox2*, where parameters behave as documented as for the
- `.BboxConnector` constructor.
- """
- if isinstance(bbox1, Rectangle):
- bbox1 = TransformedBbox(Bbox.unit(), bbox1.get_transform())
- if isinstance(bbox2, Rectangle):
- bbox2 = TransformedBbox(Bbox.unit(), bbox2.get_transform())
- if loc2 is None:
- loc2 = loc1
- x1, y1 = BboxConnector.get_bbox_edge_pos(bbox1, loc1)
- x2, y2 = BboxConnector.get_bbox_edge_pos(bbox2, loc2)
- return Path([[x1, y1], [x2, y2]])
-
- @_docstring.dedent_interpd
- def __init__(self, bbox1, bbox2, loc1, loc2=None, **kwargs):
- """
- Connect two bboxes with a straight line.
-
- Parameters
- ----------
- bbox1, bbox2 : `~matplotlib.transforms.Bbox`
- Bounding boxes to connect.
-
- loc1, loc2 : {1, 2, 3, 4}
- Corner of *bbox1* and *bbox2* to draw the line. Valid values are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4
-
- *loc2* is optional and defaults to *loc1*.
-
- **kwargs
- Patch properties for the line drawn. Valid arguments include:
-
- %(Patch:kwdoc)s
- """
- if "transform" in kwargs:
- raise ValueError("transform should not be set")
-
- kwargs["transform"] = IdentityTransform()
- kwargs.setdefault(
- "fill", bool({'fc', 'facecolor', 'color'}.intersection(kwargs)))
- super().__init__(**kwargs)
- self.bbox1 = bbox1
- self.bbox2 = bbox2
- self.loc1 = loc1
- self.loc2 = loc2
-
- def get_path(self):
- # docstring inherited
- return self.connect_bbox(self.bbox1, self.bbox2,
- self.loc1, self.loc2)
-
-
-class BboxConnectorPatch(BboxConnector):
- @_docstring.dedent_interpd
- def __init__(self, bbox1, bbox2, loc1a, loc2a, loc1b, loc2b, **kwargs):
- """
- Connect two bboxes with a quadrilateral.
-
- The quadrilateral is specified by two lines that start and end at
- corners of the bboxes. The four sides of the quadrilateral are defined
- by the two lines given, the line between the two corners specified in
- *bbox1* and the line between the two corners specified in *bbox2*.
-
- Parameters
- ----------
- bbox1, bbox2 : `~matplotlib.transforms.Bbox`
- Bounding boxes to connect.
-
- loc1a, loc2a, loc1b, loc2b : {1, 2, 3, 4}
- The first line connects corners *loc1a* of *bbox1* and *loc2a* of
- *bbox2*; the second line connects corners *loc1b* of *bbox1* and
- *loc2b* of *bbox2*. Valid values are::
-
- 'upper right' : 1,
- 'upper left' : 2,
- 'lower left' : 3,
- 'lower right' : 4
-
- **kwargs
- Patch properties for the line drawn:
-
- %(Patch:kwdoc)s
- """
- if "transform" in kwargs:
- raise ValueError("transform should not be set")
- super().__init__(bbox1, bbox2, loc1a, loc2a, **kwargs)
- self.loc1b = loc1b
- self.loc2b = loc2b
-
- def get_path(self):
- # docstring inherited
- path1 = self.connect_bbox(self.bbox1, self.bbox2, self.loc1, self.loc2)
- path2 = self.connect_bbox(self.bbox2, self.bbox1,
- self.loc2b, self.loc1b)
- path_merged = [*path1.vertices, *path2.vertices, path1.vertices[0]]
- return Path(path_merged)
-
-
-def _add_inset_axes(parent_axes, axes_class, axes_kwargs, axes_locator):
- """Helper function to add an inset axes and disable navigation in it."""
- if axes_class is None:
- axes_class = HostAxes
- if axes_kwargs is None:
- axes_kwargs = {}
- inset_axes = axes_class(
- parent_axes.figure, parent_axes.get_position(),
- **{"navigate": False, **axes_kwargs, "axes_locator": axes_locator})
- return parent_axes.figure.add_axes(inset_axes)
-
-
-@_docstring.dedent_interpd
-def inset_axes(parent_axes, width, height, loc='upper right',
- bbox_to_anchor=None, bbox_transform=None,
- axes_class=None, axes_kwargs=None,
- borderpad=0.5):
- """
- Create an inset axes with a given width and height.
-
- Both sizes used can be specified either in inches or percentage.
- For example,::
-
- inset_axes(parent_axes, width='40%%', height='30%%', loc='lower left')
-
- creates in inset axes in the lower left corner of *parent_axes* which spans
- over 30%% in height and 40%% in width of the *parent_axes*. Since the usage
- of `.inset_axes` may become slightly tricky when exceeding such standard
- cases, it is recommended to read :doc:`the examples
- </gallery/axes_grid1/inset_locator_demo>`.
-
- Notes
- -----
- The meaning of *bbox_to_anchor* and *bbox_to_transform* is interpreted
- differently from that of legend. The value of bbox_to_anchor
- (or the return value of its get_points method; the default is
- *parent_axes.bbox*) is transformed by the bbox_transform (the default
- is Identity transform) and then interpreted as points in the pixel
- coordinate (which is dpi dependent).
-
- Thus, following three calls are identical and creates an inset axes
- with respect to the *parent_axes*::
-
- axins = inset_axes(parent_axes, "30%%", "40%%")
- axins = inset_axes(parent_axes, "30%%", "40%%",
- bbox_to_anchor=parent_axes.bbox)
- axins = inset_axes(parent_axes, "30%%", "40%%",
- bbox_to_anchor=(0, 0, 1, 1),
- bbox_transform=parent_axes.transAxes)
-
- Parameters
- ----------
- parent_axes : `matplotlib.axes.Axes`
- Axes to place the inset axes.
-
- width, height : float or str
- Size of the inset axes to create. If a float is provided, it is
- the size in inches, e.g. *width=1.3*. If a string is provided, it is
- the size in relative units, e.g. *width='40%%'*. By default, i.e. if
- neither *bbox_to_anchor* nor *bbox_transform* are specified, those
- are relative to the parent_axes. Otherwise, they are to be understood
- relative to the bounding box provided via *bbox_to_anchor*.
-
- loc : str, default: 'upper right'
- Location to place the inset axes. Valid locations are
- 'upper left', 'upper center', 'upper right',
- 'center left', 'center', 'center right',
- 'lower left', 'lower center', 'lower right'.
- For backward compatibility, numeric values are accepted as well.
- See the parameter *loc* of `.Legend` for details.
-
- bbox_to_anchor : tuple or `~matplotlib.transforms.BboxBase`, optional
- Bbox that the inset axes will be anchored to. If None,
- a tuple of (0, 0, 1, 1) is used if *bbox_transform* is set
- to *parent_axes.transAxes* or *parent_axes.figure.transFigure*.
- Otherwise, *parent_axes.bbox* is used. If a tuple, can be either
- [left, bottom, width, height], or [left, bottom].
- If the kwargs *width* and/or *height* are specified in relative units,
- the 2-tuple [left, bottom] cannot be used. Note that,
- unless *bbox_transform* is set, the units of the bounding box
- are interpreted in the pixel coordinate. When using *bbox_to_anchor*
- with tuple, it almost always makes sense to also specify
- a *bbox_transform*. This might often be the axes transform
- *parent_axes.transAxes*.
-
- bbox_transform : `~matplotlib.transforms.Transform`, optional
- Transformation for the bbox that contains the inset axes.
- If None, a `.transforms.IdentityTransform` is used. The value
- of *bbox_to_anchor* (or the return value of its get_points method)
- is transformed by the *bbox_transform* and then interpreted
- as points in the pixel coordinate (which is dpi dependent).
- You may provide *bbox_to_anchor* in some normalized coordinate,
- and give an appropriate transform (e.g., *parent_axes.transAxes*).
-
- axes_class : `~matplotlib.axes.Axes` type, default: `.HostAxes`
- The type of the newly created inset axes.
-
- axes_kwargs : dict, optional
- Keyword arguments to pass to the constructor of the inset axes.
- Valid arguments include:
-
- %(Axes:kwdoc)s
-
- borderpad : float, default: 0.5
- Padding between inset axes and the bbox_to_anchor.
- The units are axes font size, i.e. for a default font size of 10 points
- *borderpad = 0.5* is equivalent to a padding of 5 points.
-
- Returns
- -------
- inset_axes : *axes_class*
- Inset axes object created.
- """
-
- if (bbox_transform in [parent_axes.transAxes, parent_axes.figure.transFigure]
- and bbox_to_anchor is None):
- _api.warn_external("Using the axes or figure transform requires a "
- "bounding box in the respective coordinates. "
- "Using bbox_to_anchor=(0, 0, 1, 1) now.")
- bbox_to_anchor = (0, 0, 1, 1)
- if bbox_to_anchor is None:
- bbox_to_anchor = parent_axes.bbox
- if (isinstance(bbox_to_anchor, tuple) and
- (isinstance(width, str) or isinstance(height, str))):
- if len(bbox_to_anchor) != 4:
- raise ValueError("Using relative units for width or height "
- "requires to provide a 4-tuple or a "
- "`Bbox` instance to `bbox_to_anchor.")
- return _add_inset_axes(
- parent_axes, axes_class, axes_kwargs,
- AnchoredSizeLocator(
- bbox_to_anchor, width, height, loc=loc,
- bbox_transform=bbox_transform, borderpad=borderpad))
-
-
-@_docstring.dedent_interpd
-def zoomed_inset_axes(parent_axes, zoom, loc='upper right',
- bbox_to_anchor=None, bbox_transform=None,
- axes_class=None, axes_kwargs=None,
- borderpad=0.5):
- """
- Create an anchored inset axes by scaling a parent axes. For usage, also see
- :doc:`the examples </gallery/axes_grid1/inset_locator_demo2>`.
-
- Parameters
- ----------
- parent_axes : `~matplotlib.axes.Axes`
- Axes to place the inset axes.
-
- zoom : float
- Scaling factor of the data axes. *zoom* > 1 will enlarge the
- coordinates (i.e., "zoomed in"), while *zoom* < 1 will shrink the
- coordinates (i.e., "zoomed out").
-
- loc : str, default: 'upper right'
- Location to place the inset axes. Valid locations are
- 'upper left', 'upper center', 'upper right',
- 'center left', 'center', 'center right',
- 'lower left', 'lower center', 'lower right'.
- For backward compatibility, numeric values are accepted as well.
- See the parameter *loc* of `.Legend` for details.
-
- bbox_to_anchor : tuple or `~matplotlib.transforms.BboxBase`, optional
- Bbox that the inset axes will be anchored to. If None,
- *parent_axes.bbox* is used. If a tuple, can be either
- [left, bottom, width, height], or [left, bottom].
- If the kwargs *width* and/or *height* are specified in relative units,
- the 2-tuple [left, bottom] cannot be used. Note that
- the units of the bounding box are determined through the transform
- in use. When using *bbox_to_anchor* it almost always makes sense to
- also specify a *bbox_transform*. This might often be the axes transform
- *parent_axes.transAxes*.
-
- bbox_transform : `~matplotlib.transforms.Transform`, optional
- Transformation for the bbox that contains the inset axes.
- If None, a `.transforms.IdentityTransform` is used (i.e. pixel
- coordinates). This is useful when not providing any argument to
- *bbox_to_anchor*. When using *bbox_to_anchor* it almost always makes
- sense to also specify a *bbox_transform*. This might often be the
- axes transform *parent_axes.transAxes*. Inversely, when specifying
- the axes- or figure-transform here, be aware that not specifying
- *bbox_to_anchor* will use *parent_axes.bbox*, the units of which are
- in display (pixel) coordinates.
-
- axes_class : `~matplotlib.axes.Axes` type, default: `.HostAxes`
- The type of the newly created inset axes.
-
- axes_kwargs : dict, optional
- Keyword arguments to pass to the constructor of the inset axes.
- Valid arguments include:
-
- %(Axes:kwdoc)s
-
- borderpad : float, default: 0.5
- Padding between inset axes and the bbox_to_anchor.
- The units are axes font size, i.e. for a default font size of 10 points
- *borderpad = 0.5* is equivalent to a padding of 5 points.
-
- Returns
- -------
- inset_axes : *axes_class*
- Inset axes object created.
- """
-
- return _add_inset_axes(
- parent_axes, axes_class, axes_kwargs,
- AnchoredZoomLocator(
- parent_axes, zoom=zoom, loc=loc,
- bbox_to_anchor=bbox_to_anchor, bbox_transform=bbox_transform,
- borderpad=borderpad))
-
-
-class _TransformedBboxWithCallback(TransformedBbox):
- """
- Variant of `.TransformBbox` which calls *callback* before returning points.
-
- Used by `.mark_inset` to unstale the parent axes' viewlim as needed.
- """
-
- def __init__(self, *args, callback, **kwargs):
- super().__init__(*args, **kwargs)
- self._callback = callback
-
- def get_points(self):
- self._callback()
- return super().get_points()
-
-
-@_docstring.dedent_interpd
-def mark_inset(parent_axes, inset_axes, loc1, loc2, **kwargs):
- """
- Draw a box to mark the location of an area represented by an inset axes.
-
- This function draws a box in *parent_axes* at the bounding box of
- *inset_axes*, and shows a connection with the inset axes by drawing lines
- at the corners, giving a "zoomed in" effect.
-
- Parameters
- ----------
- parent_axes : `~matplotlib.axes.Axes`
- Axes which contains the area of the inset axes.
-
- inset_axes : `~matplotlib.axes.Axes`
- The inset axes.
-
- loc1, loc2 : {1, 2, 3, 4}
- Corners to use for connecting the inset axes and the area in the
- parent axes.
-
- **kwargs
- Patch properties for the lines and box drawn:
-
- %(Patch:kwdoc)s
-
- Returns
- -------
- pp : `~matplotlib.patches.Patch`
- The patch drawn to represent the area of the inset axes.
-
- p1, p2 : `~matplotlib.patches.Patch`
- The patches connecting two corners of the inset axes and its area.
- """
- rect = _TransformedBboxWithCallback(
- inset_axes.viewLim, parent_axes.transData,
- callback=parent_axes._unstale_viewLim)
-
- kwargs.setdefault("fill", bool({'fc', 'facecolor', 'color'}.intersection(kwargs)))
- pp = BboxPatch(rect, **kwargs)
- parent_axes.add_patch(pp)
-
- p1 = BboxConnector(inset_axes.bbox, rect, loc1=loc1, **kwargs)
- inset_axes.add_patch(p1)
- p1.set_clip_on(False)
- p2 = BboxConnector(inset_axes.bbox, rect, loc1=loc2, **kwargs)
- inset_axes.add_patch(p2)
- p2.set_clip_on(False)
-
- return pp, p1, p2
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/mpl_axes.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/mpl_axes.py
deleted file mode 100644
index 51c8748758..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/mpl_axes.py
+++ /dev/null
@@ -1,128 +0,0 @@
-import matplotlib.axes as maxes
-from matplotlib.artist import Artist
-from matplotlib.axis import XAxis, YAxis
-
-
-class SimpleChainedObjects:
- def __init__(self, objects):
- self._objects = objects
-
- def __getattr__(self, k):
- _a = SimpleChainedObjects([getattr(a, k) for a in self._objects])
- return _a
-
- def __call__(self, *args, **kwargs):
- for m in self._objects:
- m(*args, **kwargs)
-
-
-class Axes(maxes.Axes):
-
- class AxisDict(dict):
- def __init__(self, axes):
- self.axes = axes
- super().__init__()
-
- def __getitem__(self, k):
- if isinstance(k, tuple):
- r = SimpleChainedObjects(
- # super() within a list comprehension needs explicit args.
- [super(Axes.AxisDict, self).__getitem__(k1) for k1 in k])
- return r
- elif isinstance(k, slice):
- if k.start is None and k.stop is None and k.step is None:
- return SimpleChainedObjects(list(self.values()))
- else:
- raise ValueError("Unsupported slice")
- else:
- return dict.__getitem__(self, k)
-
- def __call__(self, *v, **kwargs):
- return maxes.Axes.axis(self.axes, *v, **kwargs)
-
- @property
- def axis(self):
- return self._axislines
-
- def clear(self):
- # docstring inherited
- super().clear()
- # Init axis artists.
- self._axislines = self.AxisDict(self)
- self._axislines.update(
- bottom=SimpleAxisArtist(self.xaxis, 1, self.spines["bottom"]),
- top=SimpleAxisArtist(self.xaxis, 2, self.spines["top"]),
- left=SimpleAxisArtist(self.yaxis, 1, self.spines["left"]),
- right=SimpleAxisArtist(self.yaxis, 2, self.spines["right"]))
-
-
-class SimpleAxisArtist(Artist):
- def __init__(self, axis, axisnum, spine):
- self._axis = axis
- self._axisnum = axisnum
- self.line = spine
-
- if isinstance(axis, XAxis):
- self._axis_direction = ["bottom", "top"][axisnum-1]
- elif isinstance(axis, YAxis):
- self._axis_direction = ["left", "right"][axisnum-1]
- else:
- raise ValueError(
- f"axis must be instance of XAxis or YAxis, but got {axis}")
- super().__init__()
-
- @property
- def major_ticks(self):
- tickline = "tick%dline" % self._axisnum
- return SimpleChainedObjects([getattr(tick, tickline)
- for tick in self._axis.get_major_ticks()])
-
- @property
- def major_ticklabels(self):
- label = "label%d" % self._axisnum
- return SimpleChainedObjects([getattr(tick, label)
- for tick in self._axis.get_major_ticks()])
-
- @property
- def label(self):
- return self._axis.label
-
- def set_visible(self, b):
- self.toggle(all=b)
- self.line.set_visible(b)
- self._axis.set_visible(True)
- super().set_visible(b)
-
- def set_label(self, txt):
- self._axis.set_label_text(txt)
-
- def toggle(self, all=None, ticks=None, ticklabels=None, label=None):
-
- if all:
- _ticks, _ticklabels, _label = True, True, True
- elif all is not None:
- _ticks, _ticklabels, _label = False, False, False
- else:
- _ticks, _ticklabels, _label = None, None, None
-
- if ticks is not None:
- _ticks = ticks
- if ticklabels is not None:
- _ticklabels = ticklabels
- if label is not None:
- _label = label
-
- if _ticks is not None:
- tickparam = {f"tick{self._axisnum}On": _ticks}
- self._axis.set_tick_params(**tickparam)
- if _ticklabels is not None:
- tickparam = {f"label{self._axisnum}On": _ticklabels}
- self._axis.set_tick_params(**tickparam)
-
- if _label is not None:
- pos = self._axis.get_label_position()
- if (pos == self._axis_direction) and not _label:
- self._axis.label.set_visible(False)
- elif _label:
- self._axis.label.set_visible(True)
- self._axis.set_label_position(self._axis_direction)
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/parasite_axes.py b/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/parasite_axes.py
deleted file mode 100644
index 2a2b5957e8..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axes_grid1/parasite_axes.py
+++ /dev/null
@@ -1,257 +0,0 @@
-from matplotlib import _api, cbook
-import matplotlib.artist as martist
-import matplotlib.transforms as mtransforms
-from matplotlib.transforms import Bbox
-from .mpl_axes import Axes
-
-
-class ParasiteAxesBase:
-
- def __init__(self, parent_axes, aux_transform=None,
- *, viewlim_mode=None, **kwargs):
- self._parent_axes = parent_axes
- self.transAux = aux_transform
- self.set_viewlim_mode(viewlim_mode)
- kwargs["frameon"] = False
- super().__init__(parent_axes.figure, parent_axes._position, **kwargs)
-
- def clear(self):
- super().clear()
- martist.setp(self.get_children(), visible=False)
- self._get_lines = self._parent_axes._get_lines
- self._parent_axes.callbacks._connect_picklable(
- "xlim_changed", self._sync_lims)
- self._parent_axes.callbacks._connect_picklable(
- "ylim_changed", self._sync_lims)
-
- def pick(self, mouseevent):
- # This most likely goes to Artist.pick (depending on axes_class given
- # to the factory), which only handles pick events registered on the
- # axes associated with each child:
- super().pick(mouseevent)
- # But parasite axes are additionally given pick events from their host
- # axes (cf. HostAxesBase.pick), which we handle here:
- for a in self.get_children():
- if (hasattr(mouseevent.inaxes, "parasites")
- and self in mouseevent.inaxes.parasites):
- a.pick(mouseevent)
-
- # aux_transform support
-
- def _set_lim_and_transforms(self):
- if self.transAux is not None:
- self.transAxes = self._parent_axes.transAxes
- self.transData = self.transAux + self._parent_axes.transData
- self._xaxis_transform = mtransforms.blended_transform_factory(
- self.transData, self.transAxes)
- self._yaxis_transform = mtransforms.blended_transform_factory(
- self.transAxes, self.transData)
- else:
- super()._set_lim_and_transforms()
-
- def set_viewlim_mode(self, mode):
- _api.check_in_list([None, "equal", "transform"], mode=mode)
- self._viewlim_mode = mode
-
- def get_viewlim_mode(self):
- return self._viewlim_mode
-
- def _sync_lims(self, parent):
- viewlim = parent.viewLim.frozen()
- mode = self.get_viewlim_mode()
- if mode is None:
- pass
- elif mode == "equal":
- self.viewLim.set(viewlim)
- elif mode == "transform":
- self.viewLim.set(viewlim.transformed(self.transAux.inverted()))
- else:
- _api.check_in_list([None, "equal", "transform"], mode=mode)
-
- # end of aux_transform support
-
-
-parasite_axes_class_factory = cbook._make_class_factory(
- ParasiteAxesBase, "{}Parasite")
-ParasiteAxes = parasite_axes_class_factory(Axes)
-
-
-class HostAxesBase:
- def __init__(self, *args, **kwargs):
- self.parasites = []
- super().__init__(*args, **kwargs)
-
- def get_aux_axes(
- self, tr=None, viewlim_mode="equal", axes_class=None, **kwargs):
- """
- Add a parasite axes to this host.
-
- Despite this method's name, this should actually be thought of as an
- ``add_parasite_axes`` method.
-
- .. versionchanged:: 3.7
- Defaults to same base axes class as host axes.
-
- Parameters
- ----------
- tr : `~matplotlib.transforms.Transform` or None, default: None
- If a `.Transform`, the following relation will hold:
- ``parasite.transData = tr + host.transData``.
- If None, the parasite's and the host's ``transData`` are unrelated.
- viewlim_mode : {"equal", "transform", None}, default: "equal"
- How the parasite's view limits are set: directly equal to the
- parent axes ("equal"), equal after application of *tr*
- ("transform"), or independently (None).
- axes_class : subclass type of `~matplotlib.axes.Axes`, optional
- The `~.axes.Axes` subclass that is instantiated. If None, the base
- class of the host axes is used.
- **kwargs
- Other parameters are forwarded to the parasite axes constructor.
- """
- if axes_class is None:
- axes_class = self._base_axes_class
- parasite_axes_class = parasite_axes_class_factory(axes_class)
- ax2 = parasite_axes_class(
- self, tr, viewlim_mode=viewlim_mode, **kwargs)
- # note that ax2.transData == tr + ax1.transData
- # Anything you draw in ax2 will match the ticks and grids of ax1.
- self.parasites.append(ax2)
- ax2._remove_method = self.parasites.remove
- return ax2
-
- def draw(self, renderer):
- orig_children_len = len(self._children)
-
- locator = self.get_axes_locator()
- if locator:
- pos = locator(self, renderer)
- self.set_position(pos, which="active")
- self.apply_aspect(pos)
- else:
- self.apply_aspect()
-
- rect = self.get_position()
- for ax in self.parasites:
- ax.apply_aspect(rect)
- self._children.extend(ax.get_children())
-
- super().draw(renderer)
- del self._children[orig_children_len:]
-
- def clear(self):
- super().clear()
- for ax in self.parasites:
- ax.clear()
-
- def pick(self, mouseevent):
- super().pick(mouseevent)
- # Also pass pick events on to parasite axes and, in turn, their
- # children (cf. ParasiteAxesBase.pick)
- for a in self.parasites:
- a.pick(mouseevent)
-
- def twinx(self, axes_class=None):
- """
- Create a twin of Axes with a shared x-axis but independent y-axis.
-
- The y-axis of self will have ticks on the left and the returned axes
- will have ticks on the right.
- """
- ax = self._add_twin_axes(axes_class, sharex=self)
- self.axis["right"].set_visible(False)
- ax.axis["right"].set_visible(True)
- ax.axis["left", "top", "bottom"].set_visible(False)
- return ax
-
- def twiny(self, axes_class=None):
- """
- Create a twin of Axes with a shared y-axis but independent x-axis.
-
- The x-axis of self will have ticks on the bottom and the returned axes
- will have ticks on the top.
- """
- ax = self._add_twin_axes(axes_class, sharey=self)
- self.axis["top"].set_visible(False)
- ax.axis["top"].set_visible(True)
- ax.axis["left", "right", "bottom"].set_visible(False)
- return ax
-
- def twin(self, aux_trans=None, axes_class=None):
- """
- Create a twin of Axes with no shared axis.
-
- While self will have ticks on the left and bottom axis, the returned
- axes will have ticks on the top and right axis.
- """
- if aux_trans is None:
- aux_trans = mtransforms.IdentityTransform()
- ax = self._add_twin_axes(
- axes_class, aux_transform=aux_trans, viewlim_mode="transform")
- self.axis["top", "right"].set_visible(False)
- ax.axis["top", "right"].set_visible(True)
- ax.axis["left", "bottom"].set_visible(False)
- return ax
-
- def _add_twin_axes(self, axes_class, **kwargs):
- """
- Helper for `.twinx`/`.twiny`/`.twin`.
-
- *kwargs* are forwarded to the parasite axes constructor.
- """
- if axes_class is None:
- axes_class = self._base_axes_class
- ax = parasite_axes_class_factory(axes_class)(self, **kwargs)
- self.parasites.append(ax)
- ax._remove_method = self._remove_any_twin
- return ax
-
- def _remove_any_twin(self, ax):
- self.parasites.remove(ax)
- restore = ["top", "right"]
- if ax._sharex:
- restore.remove("top")
- if ax._sharey:
- restore.remove("right")
- self.axis[tuple(restore)].set_visible(True)
- self.axis[tuple(restore)].toggle(ticklabels=False, label=False)
-
- @_api.make_keyword_only("3.8", "call_axes_locator")
- def get_tightbbox(self, renderer=None, call_axes_locator=True,
- bbox_extra_artists=None):
- bbs = [
- *[ax.get_tightbbox(renderer, call_axes_locator=call_axes_locator)
- for ax in self.parasites],
- super().get_tightbbox(renderer,
- call_axes_locator=call_axes_locator,
- bbox_extra_artists=bbox_extra_artists)]
- return Bbox.union([b for b in bbs if b.width != 0 or b.height != 0])
-
-
-host_axes_class_factory = host_subplot_class_factory = \
- cbook._make_class_factory(HostAxesBase, "{}HostAxes", "_base_axes_class")
-HostAxes = SubplotHost = host_axes_class_factory(Axes)
-
-
-def host_axes(*args, axes_class=Axes, figure=None, **kwargs):
- """
- Create axes that can act as a hosts to parasitic axes.
-
- Parameters
- ----------
- figure : `~matplotlib.figure.Figure`
- Figure to which the axes will be added. Defaults to the current figure
- `.pyplot.gcf()`.
-
- *args, **kwargs
- Will be passed on to the underlying `~.axes.Axes` object creation.
- """
- import matplotlib.pyplot as plt
- host_axes_class = host_axes_class_factory(axes_class)
- if figure is None:
- figure = plt.gcf()
- ax = host_axes_class(figure, *args, **kwargs)
- figure.add_axes(ax)
- return ax
-
-
-host_subplot = host_axes
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/__init__.py b/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/__init__.py
deleted file mode 100644
index 47242cf7f0..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from .axislines import (
- Axes, AxesZero, AxisArtistHelper, AxisArtistHelperRectlinear,
- GridHelperBase, GridHelperRectlinear, Subplot, SubplotZero)
-from .axis_artist import AxisArtist, GridlinesCollection
-from .grid_helper_curvelinear import GridHelperCurveLinear
-from .floating_axes import FloatingAxes, FloatingSubplot
-from mpl_toolkits.axes_grid1.parasite_axes import (
- host_axes_class_factory, parasite_axes_class_factory)
-
-
-ParasiteAxes = parasite_axes_class_factory(Axes)
-HostAxes = host_axes_class_factory(Axes)
-SubplotHost = HostAxes
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/angle_helper.py b/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/angle_helper.py
deleted file mode 100644
index 1786cd70bc..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/angle_helper.py
+++ /dev/null
@@ -1,394 +0,0 @@
-import numpy as np
-import math
-
-from mpl_toolkits.axisartist.grid_finder import ExtremeFinderSimple
-
-
-def select_step_degree(dv):
-
- degree_limits_ = [1.5, 3, 7, 13, 20, 40, 70, 120, 270, 520]
- degree_steps_ = [1, 2, 5, 10, 15, 30, 45, 90, 180, 360]
- degree_factors = [1.] * len(degree_steps_)
-
- minsec_limits_ = [1.5, 2.5, 3.5, 8, 11, 18, 25, 45]
- minsec_steps_ = [1, 2, 3, 5, 10, 15, 20, 30]
-
- minute_limits_ = np.array(minsec_limits_) / 60
- minute_factors = [60.] * len(minute_limits_)
-
- second_limits_ = np.array(minsec_limits_) / 3600
- second_factors = [3600.] * len(second_limits_)
-
- degree_limits = [*second_limits_, *minute_limits_, *degree_limits_]
- degree_steps = [*minsec_steps_, *minsec_steps_, *degree_steps_]
- degree_factors = [*second_factors, *minute_factors, *degree_factors]
-
- n = np.searchsorted(degree_limits, dv)
- step = degree_steps[n]
- factor = degree_factors[n]
-
- return step, factor
-
-
-def select_step_hour(dv):
-
- hour_limits_ = [1.5, 2.5, 3.5, 5, 7, 10, 15, 21, 36]
- hour_steps_ = [1, 2, 3, 4, 6, 8, 12, 18, 24]
- hour_factors = [1.] * len(hour_steps_)
-
- minsec_limits_ = [1.5, 2.5, 3.5, 4.5, 5.5, 8, 11, 14, 18, 25, 45]
- minsec_steps_ = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30]
-
- minute_limits_ = np.array(minsec_limits_) / 60
- minute_factors = [60.] * len(minute_limits_)
-
- second_limits_ = np.array(minsec_limits_) / 3600
- second_factors = [3600.] * len(second_limits_)
-
- hour_limits = [*second_limits_, *minute_limits_, *hour_limits_]
- hour_steps = [*minsec_steps_, *minsec_steps_, *hour_steps_]
- hour_factors = [*second_factors, *minute_factors, *hour_factors]
-
- n = np.searchsorted(hour_limits, dv)
- step = hour_steps[n]
- factor = hour_factors[n]
-
- return step, factor
-
-
-def select_step_sub(dv):
-
- # subarcsec or degree
- tmp = 10.**(int(math.log10(dv))-1.)
-
- factor = 1./tmp
-
- if 1.5*tmp >= dv:
- step = 1
- elif 3.*tmp >= dv:
- step = 2
- elif 7.*tmp >= dv:
- step = 5
- else:
- step = 1
- factor = 0.1*factor
-
- return step, factor
-
-
-def select_step(v1, v2, nv, hour=False, include_last=True,
- threshold_factor=3600.):
-
- if v1 > v2:
- v1, v2 = v2, v1
-
- dv = (v2 - v1) / nv
-
- if hour:
- _select_step = select_step_hour
- cycle = 24.
- else:
- _select_step = select_step_degree
- cycle = 360.
-
- # for degree
- if dv > 1 / threshold_factor:
- step, factor = _select_step(dv)
- else:
- step, factor = select_step_sub(dv*threshold_factor)
-
- factor = factor * threshold_factor
-
- levs = np.arange(np.floor(v1 * factor / step),
- np.ceil(v2 * factor / step) + 0.5,
- dtype=int) * step
-
- # n : number of valid levels. If there is a cycle, e.g., [0, 90, 180,
- # 270, 360], the grid line needs to be extended from 0 to 360, so
- # we need to return the whole array. However, the last level (360)
- # needs to be ignored often. In this case, so we return n=4.
-
- n = len(levs)
-
- # we need to check the range of values
- # for example, -90 to 90, 0 to 360,
-
- if factor == 1. and levs[-1] >= levs[0] + cycle: # check for cycle
- nv = int(cycle / step)
- if include_last:
- levs = levs[0] + np.arange(0, nv+1, 1) * step
- else:
- levs = levs[0] + np.arange(0, nv, 1) * step
-
- n = len(levs)
-
- return np.array(levs), n, factor
-
-
-def select_step24(v1, v2, nv, include_last=True, threshold_factor=3600):
- v1, v2 = v1 / 15, v2 / 15
- levs, n, factor = select_step(v1, v2, nv, hour=True,
- include_last=include_last,
- threshold_factor=threshold_factor)
- return levs * 15, n, factor
-
-
-def select_step360(v1, v2, nv, include_last=True, threshold_factor=3600):
- return select_step(v1, v2, nv, hour=False,
- include_last=include_last,
- threshold_factor=threshold_factor)
-
-
-class LocatorBase:
- def __init__(self, nbins, include_last=True):
- self.nbins = nbins
- self._include_last = include_last
-
- def set_params(self, nbins=None):
- if nbins is not None:
- self.nbins = int(nbins)
-
-
-class LocatorHMS(LocatorBase):
- def __call__(self, v1, v2):
- return select_step24(v1, v2, self.nbins, self._include_last)
-
-
-class LocatorHM(LocatorBase):
- def __call__(self, v1, v2):
- return select_step24(v1, v2, self.nbins, self._include_last,
- threshold_factor=60)
-
-
-class LocatorH(LocatorBase):
- def __call__(self, v1, v2):
- return select_step24(v1, v2, self.nbins, self._include_last,
- threshold_factor=1)
-
-
-class LocatorDMS(LocatorBase):
- def __call__(self, v1, v2):
- return select_step360(v1, v2, self.nbins, self._include_last)
-
-
-class LocatorDM(LocatorBase):
- def __call__(self, v1, v2):
- return select_step360(v1, v2, self.nbins, self._include_last,
- threshold_factor=60)
-
-
-class LocatorD(LocatorBase):
- def __call__(self, v1, v2):
- return select_step360(v1, v2, self.nbins, self._include_last,
- threshold_factor=1)
-
-
-class FormatterDMS:
- deg_mark = r"^{\circ}"
- min_mark = r"^{\prime}"
- sec_mark = r"^{\prime\prime}"
-
- fmt_d = "$%d" + deg_mark + "$"
- fmt_ds = r"$%d.%s" + deg_mark + "$"
-
- # %s for sign
- fmt_d_m = r"$%s%d" + deg_mark + r"\,%02d" + min_mark + "$"
- fmt_d_ms = r"$%s%d" + deg_mark + r"\,%02d.%s" + min_mark + "$"
-
- fmt_d_m_partial = "$%s%d" + deg_mark + r"\,%02d" + min_mark + r"\,"
- fmt_s_partial = "%02d" + sec_mark + "$"
- fmt_ss_partial = "%02d.%s" + sec_mark + "$"
-
- def _get_number_fraction(self, factor):
- ## check for fractional numbers
- number_fraction = None
- # check for 60
-
- for threshold in [1, 60, 3600]:
- if factor <= threshold:
- break
-
- d = factor // threshold
- int_log_d = int(np.floor(np.log10(d)))
- if 10**int_log_d == d and d != 1:
- number_fraction = int_log_d
- factor = factor // 10**int_log_d
- return factor, number_fraction
-
- return factor, number_fraction
-
- def __call__(self, direction, factor, values):
- if len(values) == 0:
- return []
-
- ss = np.sign(values)
- signs = ["-" if v < 0 else "" for v in values]
-
- factor, number_fraction = self._get_number_fraction(factor)
-
- values = np.abs(values)
-
- if number_fraction is not None:
- values, frac_part = divmod(values, 10 ** number_fraction)
- frac_fmt = "%%0%dd" % (number_fraction,)
- frac_str = [frac_fmt % (f1,) for f1 in frac_part]
-
- if factor == 1:
- if number_fraction is None:
- return [self.fmt_d % (s * int(v),) for s, v in zip(ss, values)]
- else:
- return [self.fmt_ds % (s * int(v), f1)
- for s, v, f1 in zip(ss, values, frac_str)]
- elif factor == 60:
- deg_part, min_part = divmod(values, 60)
- if number_fraction is None:
- return [self.fmt_d_m % (s1, d1, m1)
- for s1, d1, m1 in zip(signs, deg_part, min_part)]
- else:
- return [self.fmt_d_ms % (s, d1, m1, f1)
- for s, d1, m1, f1
- in zip(signs, deg_part, min_part, frac_str)]
-
- elif factor == 3600:
- if ss[-1] == -1:
- inverse_order = True
- values = values[::-1]
- signs = signs[::-1]
- else:
- inverse_order = False
-
- l_hm_old = ""
- r = []
-
- deg_part, min_part_ = divmod(values, 3600)
- min_part, sec_part = divmod(min_part_, 60)
-
- if number_fraction is None:
- sec_str = [self.fmt_s_partial % (s1,) for s1 in sec_part]
- else:
- sec_str = [self.fmt_ss_partial % (s1, f1)
- for s1, f1 in zip(sec_part, frac_str)]
-
- for s, d1, m1, s1 in zip(signs, deg_part, min_part, sec_str):
- l_hm = self.fmt_d_m_partial % (s, d1, m1)
- if l_hm != l_hm_old:
- l_hm_old = l_hm
- l = l_hm + s1
- else:
- l = "$" + s + s1
- r.append(l)
-
- if inverse_order:
- return r[::-1]
- else:
- return r
-
- else: # factor > 3600.
- return [r"$%s^{\circ}$" % v for v in ss*values]
-
-
-class FormatterHMS(FormatterDMS):
- deg_mark = r"^\mathrm{h}"
- min_mark = r"^\mathrm{m}"
- sec_mark = r"^\mathrm{s}"
-
- fmt_d = "$%d" + deg_mark + "$"
- fmt_ds = r"$%d.%s" + deg_mark + "$"
-
- # %s for sign
- fmt_d_m = r"$%s%d" + deg_mark + r"\,%02d" + min_mark+"$"
- fmt_d_ms = r"$%s%d" + deg_mark + r"\,%02d.%s" + min_mark+"$"
-
- fmt_d_m_partial = "$%s%d" + deg_mark + r"\,%02d" + min_mark + r"\,"
- fmt_s_partial = "%02d" + sec_mark + "$"
- fmt_ss_partial = "%02d.%s" + sec_mark + "$"
-
- def __call__(self, direction, factor, values): # hour
- return super().__call__(direction, factor, np.asarray(values) / 15)
-
-
-class ExtremeFinderCycle(ExtremeFinderSimple):
- # docstring inherited
-
- def __init__(self, nx, ny,
- lon_cycle=360., lat_cycle=None,
- lon_minmax=None, lat_minmax=(-90, 90)):
- """
- This subclass handles the case where one or both coordinates should be
- taken modulo 360, or be restricted to not exceed a specific range.
-
- Parameters
- ----------
- nx, ny : int
- The number of samples in each direction.
-
- lon_cycle, lat_cycle : 360 or None
- If not None, values in the corresponding direction are taken modulo
- *lon_cycle* or *lat_cycle*; in theory this can be any number but
- the implementation actually assumes that it is 360 (if not None);
- other values give nonsensical results.
-
- This is done by "unwrapping" the transformed grid coordinates so
- that jumps are less than a half-cycle; then normalizing the span to
- no more than a full cycle.
-
- For example, if values are in the union of the [0, 2] and
- [358, 360] intervals (typically, angles measured modulo 360), the
- values in the second interval are normalized to [-2, 0] instead so
- that the values now cover [-2, 2]. If values are in a range of
- [5, 1000], this gets normalized to [5, 365].
-
- lon_minmax, lat_minmax : (float, float) or None
- If not None, the computed bounding box is clipped to the given
- range in the corresponding direction.
- """
- self.nx, self.ny = nx, ny
- self.lon_cycle, self.lat_cycle = lon_cycle, lat_cycle
- self.lon_minmax = lon_minmax
- self.lat_minmax = lat_minmax
-
- def __call__(self, transform_xy, x1, y1, x2, y2):
- # docstring inherited
- x, y = np.meshgrid(
- np.linspace(x1, x2, self.nx), np.linspace(y1, y2, self.ny))
- lon, lat = transform_xy(np.ravel(x), np.ravel(y))
-
- # iron out jumps, but algorithm should be improved.
- # This is just naive way of doing and my fail for some cases.
- # Consider replacing this with numpy.unwrap
- # We are ignoring invalid warnings. They are triggered when
- # comparing arrays with NaNs using > We are already handling
- # that correctly using np.nanmin and np.nanmax
- with np.errstate(invalid='ignore'):
- if self.lon_cycle is not None:
- lon0 = np.nanmin(lon)
- lon -= 360. * ((lon - lon0) > 180.)
- if self.lat_cycle is not None:
- lat0 = np.nanmin(lat)
- lat -= 360. * ((lat - lat0) > 180.)
-
- lon_min, lon_max = np.nanmin(lon), np.nanmax(lon)
- lat_min, lat_max = np.nanmin(lat), np.nanmax(lat)
-
- lon_min, lon_max, lat_min, lat_max = \
- self._add_pad(lon_min, lon_max, lat_min, lat_max)
-
- # check cycle
- if self.lon_cycle:
- lon_max = min(lon_max, lon_min + self.lon_cycle)
- if self.lat_cycle:
- lat_max = min(lat_max, lat_min + self.lat_cycle)
-
- if self.lon_minmax is not None:
- min0 = self.lon_minmax[0]
- lon_min = max(min0, lon_min)
- max0 = self.lon_minmax[1]
- lon_max = min(max0, lon_max)
-
- if self.lat_minmax is not None:
- min0 = self.lat_minmax[0]
- lat_min = max(min0, lat_min)
- max0 = self.lat_minmax[1]
- lat_max = min(max0, lat_max)
-
- return lon_min, lon_max, lat_min, lat_max
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axes_divider.py b/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axes_divider.py
deleted file mode 100644
index a01d4e27df..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axes_divider.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from mpl_toolkits.axes_grid1.axes_divider import ( # noqa
- Divider, AxesLocator, SubplotDivider, AxesDivider, make_axes_locatable)
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axes_grid.py b/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axes_grid.py
deleted file mode 100644
index ecb3e9d92c..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axes_grid.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from matplotlib import _api
-
-import mpl_toolkits.axes_grid1.axes_grid as axes_grid_orig
-from .axislines import Axes
-
-
-_api.warn_deprecated(
- "3.8", name=__name__, obj_type="module", alternative="axes_grid1.axes_grid")
-
-
-@_api.deprecated("3.8", alternative=(
- "axes_grid1.axes_grid.Grid(..., axes_class=axislines.Axes"))
-class Grid(axes_grid_orig.Grid):
- _defaultAxesClass = Axes
-
-
-@_api.deprecated("3.8", alternative=(
- "axes_grid1.axes_grid.ImageGrid(..., axes_class=axislines.Axes"))
-class ImageGrid(axes_grid_orig.ImageGrid):
- _defaultAxesClass = Axes
-
-
-AxesGrid = ImageGrid
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axes_rgb.py b/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axes_rgb.py
deleted file mode 100644
index 2195747469..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axes_rgb.py
+++ /dev/null
@@ -1,18 +0,0 @@
-from matplotlib import _api
-from mpl_toolkits.axes_grid1.axes_rgb import ( # noqa
- make_rgb_axes, RGBAxes as _RGBAxes)
-from .axislines import Axes
-
-
-_api.warn_deprecated(
- "3.8", name=__name__, obj_type="module", alternative="axes_grid1.axes_rgb")
-
-
-@_api.deprecated("3.8", alternative=(
- "axes_grid1.axes_rgb.RGBAxes(..., axes_class=axislines.Axes"))
-class RGBAxes(_RGBAxes):
- """
- Subclass of `~.axes_grid1.axes_rgb.RGBAxes` with
- ``_defaultAxesClass`` = `.axislines.Axes`.
- """
- _defaultAxesClass = Axes
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axis_artist.py b/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axis_artist.py
deleted file mode 100644
index 407ad07a3d..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axis_artist.py
+++ /dev/null
@@ -1,1115 +0,0 @@
-"""
-The :mod:`.axis_artist` module implements custom artists to draw axis elements
-(axis lines and labels, tick lines and labels, grid lines).
-
-Axis lines and labels and tick lines and labels are managed by the `AxisArtist`
-class; grid lines are managed by the `GridlinesCollection` class.
-
-There is one `AxisArtist` per Axis; it can be accessed through
-the ``axis`` dictionary of the parent Axes (which should be a
-`mpl_toolkits.axislines.Axes`), e.g. ``ax.axis["bottom"]``.
-
-Children of the AxisArtist are accessed as attributes: ``.line`` and ``.label``
-for the axis line and label, ``.major_ticks``, ``.major_ticklabels``,
-``.minor_ticks``, ``.minor_ticklabels`` for the tick lines and labels (e.g.
-``ax.axis["bottom"].line``).
-
-Children properties (colors, fonts, line widths, etc.) can be set using
-setters, e.g. ::
-
- # Make the major ticks of the bottom axis red.
- ax.axis["bottom"].major_ticks.set_color("red")
-
-However, things like the locations of ticks, and their ticklabels need to be
-changed from the side of the grid_helper.
-
-axis_direction
---------------
-
-`AxisArtist`, `AxisLabel`, `TickLabels` have an *axis_direction* attribute,
-which adjusts the location, angle, etc. The *axis_direction* must be one of
-"left", "right", "bottom", "top", and follows the Matplotlib convention for
-rectangular axis.
-
-For example, for the *bottom* axis (the left and right is relative to the
-direction of the increasing coordinate),
-
-* ticklabels and axislabel are on the right
-* ticklabels and axislabel have text angle of 0
-* ticklabels are baseline, center-aligned
-* axislabel is top, center-aligned
-
-The text angles are actually relative to (90 + angle of the direction to the
-ticklabel), which gives 0 for bottom axis.
-
-=================== ====== ======== ====== ========
-Property left bottom right top
-=================== ====== ======== ====== ========
-ticklabel location left right right left
-axislabel location left right right left
-ticklabel angle 90 0 -90 180
-axislabel angle 180 0 0 180
-ticklabel va center baseline center baseline
-axislabel va center top center bottom
-ticklabel ha right center right center
-axislabel ha right center right center
-=================== ====== ======== ====== ========
-
-Ticks are by default direct opposite side of the ticklabels. To make ticks to
-the same side of the ticklabels, ::
-
- ax.axis["bottom"].major_ticks.set_tick_out(True)
-
-The following attributes can be customized (use the ``set_xxx`` methods):
-
-* `Ticks`: ticksize, tick_out
-* `TickLabels`: pad
-* `AxisLabel`: pad
-"""
-
-# FIXME :
-# angles are given in data coordinate - need to convert it to canvas coordinate
-
-
-from operator import methodcaller
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, cbook
-import matplotlib.artist as martist
-import matplotlib.colors as mcolors
-import matplotlib.text as mtext
-from matplotlib.collections import LineCollection
-from matplotlib.lines import Line2D
-from matplotlib.patches import PathPatch
-from matplotlib.path import Path
-from matplotlib.transforms import (
- Affine2D, Bbox, IdentityTransform, ScaledTranslation)
-
-from .axisline_style import AxislineStyle
-
-
-class AttributeCopier:
- def get_ref_artist(self):
- """
- Return the underlying artist that actually defines some properties
- (e.g., color) of this artist.
- """
- raise RuntimeError("get_ref_artist must overridden")
-
- def get_attribute_from_ref_artist(self, attr_name):
- getter = methodcaller("get_" + attr_name)
- prop = getter(super())
- return getter(self.get_ref_artist()) if prop == "auto" else prop
-
-
-class Ticks(AttributeCopier, Line2D):
- """
- Ticks are derived from `.Line2D`, and note that ticks themselves
- are markers. Thus, you should use set_mec, set_mew, etc.
-
- To change the tick size (length), you need to use
- `set_ticksize`. To change the direction of the ticks (ticks are
- in opposite direction of ticklabels by default), use
- ``set_tick_out(False)``
- """
-
- def __init__(self, ticksize, tick_out=False, *, axis=None, **kwargs):
- self._ticksize = ticksize
- self.locs_angles_labels = []
-
- self.set_tick_out(tick_out)
-
- self._axis = axis
- if self._axis is not None:
- if "color" not in kwargs:
- kwargs["color"] = "auto"
- if "mew" not in kwargs and "markeredgewidth" not in kwargs:
- kwargs["markeredgewidth"] = "auto"
-
- Line2D.__init__(self, [0.], [0.], **kwargs)
- self.set_snap(True)
-
- def get_ref_artist(self):
- # docstring inherited
- return self._axis.majorTicks[0].tick1line
-
- def set_color(self, color):
- # docstring inherited
- # Unlike the base Line2D.set_color, this also supports "auto".
- if not cbook._str_equal(color, "auto"):
- mcolors._check_color_like(color=color)
- self._color = color
- self.stale = True
-
- def get_color(self):
- return self.get_attribute_from_ref_artist("color")
-
- def get_markeredgecolor(self):
- return self.get_attribute_from_ref_artist("markeredgecolor")
-
- def get_markeredgewidth(self):
- return self.get_attribute_from_ref_artist("markeredgewidth")
-
- def set_tick_out(self, b):
- """Set whether ticks are drawn inside or outside the axes."""
- self._tick_out = b
-
- def get_tick_out(self):
- """Return whether ticks are drawn inside or outside the axes."""
- return self._tick_out
-
- def set_ticksize(self, ticksize):
- """Set length of the ticks in points."""
- self._ticksize = ticksize
-
- def get_ticksize(self):
- """Return length of the ticks in points."""
- return self._ticksize
-
- def set_locs_angles(self, locs_angles):
- self.locs_angles = locs_angles
-
- _tickvert_path = Path([[0., 0.], [1., 0.]])
-
- def draw(self, renderer):
- if not self.get_visible():
- return
-
- gc = renderer.new_gc()
- gc.set_foreground(self.get_markeredgecolor())
- gc.set_linewidth(self.get_markeredgewidth())
- gc.set_alpha(self._alpha)
-
- path_trans = self.get_transform()
- marker_transform = (Affine2D()
- .scale(renderer.points_to_pixels(self._ticksize)))
- if self.get_tick_out():
- marker_transform.rotate_deg(180)
-
- for loc, angle in self.locs_angles:
- locs = path_trans.transform_non_affine(np.array([loc]))
- if self.axes and not self.axes.viewLim.contains(*locs[0]):
- continue
- renderer.draw_markers(
- gc, self._tickvert_path,
- marker_transform + Affine2D().rotate_deg(angle),
- Path(locs), path_trans.get_affine())
-
- gc.restore()
-
-
-class LabelBase(mtext.Text):
- """
- A base class for `.AxisLabel` and `.TickLabels`. The position and
- angle of the text are calculated by the offset_ref_angle,
- text_ref_angle, and offset_radius attributes.
- """
-
- def __init__(self, *args, **kwargs):
- self.locs_angles_labels = []
- self._ref_angle = 0
- self._offset_radius = 0.
-
- super().__init__(*args, **kwargs)
-
- self.set_rotation_mode("anchor")
- self._text_follow_ref_angle = True
-
- @property
- def _text_ref_angle(self):
- if self._text_follow_ref_angle:
- return self._ref_angle + 90
- else:
- return 0
-
- @property
- def _offset_ref_angle(self):
- return self._ref_angle
-
- _get_opposite_direction = {"left": "right",
- "right": "left",
- "top": "bottom",
- "bottom": "top"}.__getitem__
-
- def draw(self, renderer):
- if not self.get_visible():
- return
-
- # save original and adjust some properties
- tr = self.get_transform()
- angle_orig = self.get_rotation()
- theta = np.deg2rad(self._offset_ref_angle)
- dd = self._offset_radius
- dx, dy = dd * np.cos(theta), dd * np.sin(theta)
-
- self.set_transform(tr + Affine2D().translate(dx, dy))
- self.set_rotation(self._text_ref_angle + angle_orig)
- super().draw(renderer)
- # restore original properties
- self.set_transform(tr)
- self.set_rotation(angle_orig)
-
- def get_window_extent(self, renderer=None):
- if renderer is None:
- renderer = self.figure._get_renderer()
-
- # save original and adjust some properties
- tr = self.get_transform()
- angle_orig = self.get_rotation()
- theta = np.deg2rad(self._offset_ref_angle)
- dd = self._offset_radius
- dx, dy = dd * np.cos(theta), dd * np.sin(theta)
-
- self.set_transform(tr + Affine2D().translate(dx, dy))
- self.set_rotation(self._text_ref_angle + angle_orig)
- bbox = super().get_window_extent(renderer).frozen()
- # restore original properties
- self.set_transform(tr)
- self.set_rotation(angle_orig)
-
- return bbox
-
-
-class AxisLabel(AttributeCopier, LabelBase):
- """
- Axis label. Derived from `.Text`. The position of the text is updated
- in the fly, so changing text position has no effect. Otherwise, the
- properties can be changed as a normal `.Text`.
-
- To change the pad between tick labels and axis label, use `set_pad`.
- """
-
- def __init__(self, *args, axis_direction="bottom", axis=None, **kwargs):
- self._axis = axis
- self._pad = 5
- self._external_pad = 0 # in pixels
- LabelBase.__init__(self, *args, **kwargs)
- self.set_axis_direction(axis_direction)
-
- def set_pad(self, pad):
- """
- Set the internal pad in points.
-
- The actual pad will be the sum of the internal pad and the
- external pad (the latter is set automatically by the `.AxisArtist`).
-
- Parameters
- ----------
- pad : float
- The internal pad in points.
- """
- self._pad = pad
-
- def get_pad(self):
- """
- Return the internal pad in points.
-
- See `.set_pad` for more details.
- """
- return self._pad
-
- def get_ref_artist(self):
- # docstring inherited
- return self._axis.get_label()
-
- def get_text(self):
- # docstring inherited
- t = super().get_text()
- if t == "__from_axes__":
- return self._axis.get_label().get_text()
- return self._text
-
- _default_alignments = dict(left=("bottom", "center"),
- right=("top", "center"),
- bottom=("top", "center"),
- top=("bottom", "center"))
-
- def set_default_alignment(self, d):
- """
- Set the default alignment. See `set_axis_direction` for details.
-
- Parameters
- ----------
- d : {"left", "bottom", "right", "top"}
- """
- va, ha = _api.check_getitem(self._default_alignments, d=d)
- self.set_va(va)
- self.set_ha(ha)
-
- _default_angles = dict(left=180,
- right=0,
- bottom=0,
- top=180)
-
- def set_default_angle(self, d):
- """
- Set the default angle. See `set_axis_direction` for details.
-
- Parameters
- ----------
- d : {"left", "bottom", "right", "top"}
- """
- self.set_rotation(_api.check_getitem(self._default_angles, d=d))
-
- def set_axis_direction(self, d):
- """
- Adjust the text angle and text alignment of axis label
- according to the matplotlib convention.
-
- ===================== ========== ========= ========== ==========
- Property left bottom right top
- ===================== ========== ========= ========== ==========
- axislabel angle 180 0 0 180
- axislabel va center top center bottom
- axislabel ha right center right center
- ===================== ========== ========= ========== ==========
-
- Note that the text angles are actually relative to (90 + angle
- of the direction to the ticklabel), which gives 0 for bottom
- axis.
-
- Parameters
- ----------
- d : {"left", "bottom", "right", "top"}
- """
- self.set_default_alignment(d)
- self.set_default_angle(d)
-
- def get_color(self):
- return self.get_attribute_from_ref_artist("color")
-
- def draw(self, renderer):
- if not self.get_visible():
- return
-
- self._offset_radius = \
- self._external_pad + renderer.points_to_pixels(self.get_pad())
-
- super().draw(renderer)
-
- def get_window_extent(self, renderer=None):
- if renderer is None:
- renderer = self.figure._get_renderer()
- if not self.get_visible():
- return
-
- r = self._external_pad + renderer.points_to_pixels(self.get_pad())
- self._offset_radius = r
-
- bb = super().get_window_extent(renderer)
-
- return bb
-
-
-class TickLabels(AxisLabel): # mtext.Text
- """
- Tick labels. While derived from `.Text`, this single artist draws all
- ticklabels. As in `.AxisLabel`, the position of the text is updated
- in the fly, so changing text position has no effect. Otherwise,
- the properties can be changed as a normal `.Text`. Unlike the
- ticklabels of the mainline Matplotlib, properties of a single
- ticklabel alone cannot be modified.
-
- To change the pad between ticks and ticklabels, use `~.AxisLabel.set_pad`.
- """
-
- def __init__(self, *, axis_direction="bottom", **kwargs):
- super().__init__(**kwargs)
- self.set_axis_direction(axis_direction)
- self._axislabel_pad = 0
-
- def get_ref_artist(self):
- # docstring inherited
- return self._axis.get_ticklabels()[0]
-
- def set_axis_direction(self, label_direction):
- """
- Adjust the text angle and text alignment of ticklabels
- according to the Matplotlib convention.
-
- The *label_direction* must be one of [left, right, bottom, top].
-
- ===================== ========== ========= ========== ==========
- Property left bottom right top
- ===================== ========== ========= ========== ==========
- ticklabel angle 90 0 -90 180
- ticklabel va center baseline center baseline
- ticklabel ha right center right center
- ===================== ========== ========= ========== ==========
-
- Note that the text angles are actually relative to (90 + angle
- of the direction to the ticklabel), which gives 0 for bottom
- axis.
-
- Parameters
- ----------
- label_direction : {"left", "bottom", "right", "top"}
-
- """
- self.set_default_alignment(label_direction)
- self.set_default_angle(label_direction)
- self._axis_direction = label_direction
-
- def invert_axis_direction(self):
- label_direction = self._get_opposite_direction(self._axis_direction)
- self.set_axis_direction(label_direction)
-
- def _get_ticklabels_offsets(self, renderer, label_direction):
- """
- Calculate the ticklabel offsets from the tick and their total heights.
-
- The offset only takes account the offset due to the vertical alignment
- of the ticklabels: if axis direction is bottom and va is 'top', it will
- return 0; if va is 'baseline', it will return (height-descent).
- """
- whd_list = self.get_texts_widths_heights_descents(renderer)
-
- if not whd_list:
- return 0, 0
-
- r = 0
- va, ha = self.get_va(), self.get_ha()
-
- if label_direction == "left":
- pad = max(w for w, h, d in whd_list)
- if ha == "left":
- r = pad
- elif ha == "center":
- r = .5 * pad
- elif label_direction == "right":
- pad = max(w for w, h, d in whd_list)
- if ha == "right":
- r = pad
- elif ha == "center":
- r = .5 * pad
- elif label_direction == "bottom":
- pad = max(h for w, h, d in whd_list)
- if va == "bottom":
- r = pad
- elif va == "center":
- r = .5 * pad
- elif va == "baseline":
- max_ascent = max(h - d for w, h, d in whd_list)
- max_descent = max(d for w, h, d in whd_list)
- r = max_ascent
- pad = max_ascent + max_descent
- elif label_direction == "top":
- pad = max(h for w, h, d in whd_list)
- if va == "top":
- r = pad
- elif va == "center":
- r = .5 * pad
- elif va == "baseline":
- max_ascent = max(h - d for w, h, d in whd_list)
- max_descent = max(d for w, h, d in whd_list)
- r = max_descent
- pad = max_ascent + max_descent
-
- # r : offset
- # pad : total height of the ticklabels. This will be used to
- # calculate the pad for the axislabel.
- return r, pad
-
- _default_alignments = dict(left=("center", "right"),
- right=("center", "left"),
- bottom=("baseline", "center"),
- top=("baseline", "center"))
-
- _default_angles = dict(left=90,
- right=-90,
- bottom=0,
- top=180)
-
- def draw(self, renderer):
- if not self.get_visible():
- self._axislabel_pad = self._external_pad
- return
-
- r, total_width = self._get_ticklabels_offsets(renderer,
- self._axis_direction)
-
- pad = self._external_pad + renderer.points_to_pixels(self.get_pad())
- self._offset_radius = r + pad
-
- for (x, y), a, l in self._locs_angles_labels:
- if not l.strip():
- continue
- self._ref_angle = a
- self.set_x(x)
- self.set_y(y)
- self.set_text(l)
- LabelBase.draw(self, renderer)
-
- # the value saved will be used to draw axislabel.
- self._axislabel_pad = total_width + pad
-
- def set_locs_angles_labels(self, locs_angles_labels):
- self._locs_angles_labels = locs_angles_labels
-
- def get_window_extents(self, renderer=None):
- if renderer is None:
- renderer = self.figure._get_renderer()
-
- if not self.get_visible():
- self._axislabel_pad = self._external_pad
- return []
-
- bboxes = []
-
- r, total_width = self._get_ticklabels_offsets(renderer,
- self._axis_direction)
-
- pad = self._external_pad + renderer.points_to_pixels(self.get_pad())
- self._offset_radius = r + pad
-
- for (x, y), a, l in self._locs_angles_labels:
- self._ref_angle = a
- self.set_x(x)
- self.set_y(y)
- self.set_text(l)
- bb = LabelBase.get_window_extent(self, renderer)
- bboxes.append(bb)
-
- # the value saved will be used to draw axislabel.
- self._axislabel_pad = total_width + pad
-
- return bboxes
-
- def get_texts_widths_heights_descents(self, renderer):
- """
- Return a list of ``(width, height, descent)`` tuples for ticklabels.
-
- Empty labels are left out.
- """
- whd_list = []
- for _loc, _angle, label in self._locs_angles_labels:
- if not label.strip():
- continue
- clean_line, ismath = self._preprocess_math(label)
- whd = renderer.get_text_width_height_descent(
- clean_line, self._fontproperties, ismath=ismath)
- whd_list.append(whd)
- return whd_list
-
-
-class GridlinesCollection(LineCollection):
- def __init__(self, *args, which="major", axis="both", **kwargs):
- """
- Collection of grid lines.
-
- Parameters
- ----------
- which : {"major", "minor"}
- Which grid to consider.
- axis : {"both", "x", "y"}
- Which axis to consider.
- *args, **kwargs
- Passed to `.LineCollection`.
- """
- self._which = which
- self._axis = axis
- super().__init__(*args, **kwargs)
- self.set_grid_helper(None)
-
- def set_which(self, which):
- """
- Select major or minor grid lines.
-
- Parameters
- ----------
- which : {"major", "minor"}
- """
- self._which = which
-
- def set_axis(self, axis):
- """
- Select axis.
-
- Parameters
- ----------
- axis : {"both", "x", "y"}
- """
- self._axis = axis
-
- def set_grid_helper(self, grid_helper):
- """
- Set grid helper.
-
- Parameters
- ----------
- grid_helper : `.GridHelperBase` subclass
- """
- self._grid_helper = grid_helper
-
- def draw(self, renderer):
- if self._grid_helper is not None:
- self._grid_helper.update_lim(self.axes)
- gl = self._grid_helper.get_gridlines(self._which, self._axis)
- self.set_segments([np.transpose(l) for l in gl])
- super().draw(renderer)
-
-
-class AxisArtist(martist.Artist):
- """
- An artist which draws axis (a line along which the n-th axes coord
- is constant) line, ticks, tick labels, and axis label.
- """
-
- zorder = 2.5
-
- @property
- def LABELPAD(self):
- return self.label.get_pad()
-
- @LABELPAD.setter
- def LABELPAD(self, v):
- self.label.set_pad(v)
-
- def __init__(self, axes,
- helper,
- offset=None,
- axis_direction="bottom",
- **kwargs):
- """
- Parameters
- ----------
- axes : `mpl_toolkits.axisartist.axislines.Axes`
- helper : `~mpl_toolkits.axisartist.axislines.AxisArtistHelper`
- """
- # axes is also used to follow the axis attribute (tick color, etc).
-
- super().__init__(**kwargs)
-
- self.axes = axes
-
- self._axis_artist_helper = helper
-
- if offset is None:
- offset = (0, 0)
- self.offset_transform = ScaledTranslation(
- *offset,
- Affine2D().scale(1 / 72) # points to inches.
- + self.axes.figure.dpi_scale_trans)
-
- if axis_direction in ["left", "right"]:
- self.axis = axes.yaxis
- else:
- self.axis = axes.xaxis
-
- self._axisline_style = None
- self._axis_direction = axis_direction
-
- self._init_line()
- self._init_ticks(**kwargs)
- self._init_offsetText(axis_direction)
- self._init_label()
-
- # axis direction
- self._ticklabel_add_angle = 0.
- self._axislabel_add_angle = 0.
- self.set_axis_direction(axis_direction)
-
- # axis direction
-
- def set_axis_direction(self, axis_direction):
- """
- Adjust the direction, text angle, and text alignment of tick labels
- and axis labels following the Matplotlib convention for the rectangle
- axes.
-
- The *axis_direction* must be one of [left, right, bottom, top].
-
- ===================== ========== ========= ========== ==========
- Property left bottom right top
- ===================== ========== ========= ========== ==========
- ticklabel direction "-" "+" "+" "-"
- axislabel direction "-" "+" "+" "-"
- ticklabel angle 90 0 -90 180
- ticklabel va center baseline center baseline
- ticklabel ha right center right center
- axislabel angle 180 0 0 180
- axislabel va center top center bottom
- axislabel ha right center right center
- ===================== ========== ========= ========== ==========
-
- Note that the direction "+" and "-" are relative to the direction of
- the increasing coordinate. Also, the text angles are actually
- relative to (90 + angle of the direction to the ticklabel),
- which gives 0 for bottom axis.
-
- Parameters
- ----------
- axis_direction : {"left", "bottom", "right", "top"}
- """
- self.major_ticklabels.set_axis_direction(axis_direction)
- self.label.set_axis_direction(axis_direction)
- self._axis_direction = axis_direction
- if axis_direction in ["left", "top"]:
- self.set_ticklabel_direction("-")
- self.set_axislabel_direction("-")
- else:
- self.set_ticklabel_direction("+")
- self.set_axislabel_direction("+")
-
- def set_ticklabel_direction(self, tick_direction):
- r"""
- Adjust the direction of the tick labels.
-
- Note that the *tick_direction*\s '+' and '-' are relative to the
- direction of the increasing coordinate.
-
- Parameters
- ----------
- tick_direction : {"+", "-"}
- """
- self._ticklabel_add_angle = _api.check_getitem(
- {"+": 0, "-": 180}, tick_direction=tick_direction)
-
- def invert_ticklabel_direction(self):
- self._ticklabel_add_angle = (self._ticklabel_add_angle + 180) % 360
- self.major_ticklabels.invert_axis_direction()
- self.minor_ticklabels.invert_axis_direction()
-
- def set_axislabel_direction(self, label_direction):
- r"""
- Adjust the direction of the axis label.
-
- Note that the *label_direction*\s '+' and '-' are relative to the
- direction of the increasing coordinate.
-
- Parameters
- ----------
- label_direction : {"+", "-"}
- """
- self._axislabel_add_angle = _api.check_getitem(
- {"+": 0, "-": 180}, label_direction=label_direction)
-
- def get_transform(self):
- return self.axes.transAxes + self.offset_transform
-
- def get_helper(self):
- """
- Return axis artist helper instance.
- """
- return self._axis_artist_helper
-
- def set_axisline_style(self, axisline_style=None, **kwargs):
- """
- Set the axisline style.
-
- The new style is completely defined by the passed attributes. Existing
- style attributes are forgotten.
-
- Parameters
- ----------
- axisline_style : str or None
- The line style, e.g. '->', optionally followed by a comma-separated
- list of attributes. Alternatively, the attributes can be provided
- as keywords.
-
- If *None* this returns a string containing the available styles.
-
- Examples
- --------
- The following two commands are equal:
-
- >>> set_axisline_style("->,size=1.5")
- >>> set_axisline_style("->", size=1.5)
- """
- if axisline_style is None:
- return AxislineStyle.pprint_styles()
-
- if isinstance(axisline_style, AxislineStyle._Base):
- self._axisline_style = axisline_style
- else:
- self._axisline_style = AxislineStyle(axisline_style, **kwargs)
-
- self._init_line()
-
- def get_axisline_style(self):
- """Return the current axisline style."""
- return self._axisline_style
-
- def _init_line(self):
- """
- Initialize the *line* artist that is responsible to draw the axis line.
- """
- tran = (self._axis_artist_helper.get_line_transform(self.axes)
- + self.offset_transform)
-
- axisline_style = self.get_axisline_style()
- if axisline_style is None:
- self.line = PathPatch(
- self._axis_artist_helper.get_line(self.axes),
- color=mpl.rcParams['axes.edgecolor'],
- fill=False,
- linewidth=mpl.rcParams['axes.linewidth'],
- capstyle=mpl.rcParams['lines.solid_capstyle'],
- joinstyle=mpl.rcParams['lines.solid_joinstyle'],
- transform=tran)
- else:
- self.line = axisline_style(self, transform=tran)
-
- def _draw_line(self, renderer):
- self.line.set_path(self._axis_artist_helper.get_line(self.axes))
- if self.get_axisline_style() is not None:
- self.line.set_line_mutation_scale(self.major_ticklabels.get_size())
- self.line.draw(renderer)
-
- def _init_ticks(self, **kwargs):
- axis_name = self.axis.axis_name
-
- trans = (self._axis_artist_helper.get_tick_transform(self.axes)
- + self.offset_transform)
-
- self.major_ticks = Ticks(
- kwargs.get(
- "major_tick_size",
- mpl.rcParams[f"{axis_name}tick.major.size"]),
- axis=self.axis, transform=trans)
- self.minor_ticks = Ticks(
- kwargs.get(
- "minor_tick_size",
- mpl.rcParams[f"{axis_name}tick.minor.size"]),
- axis=self.axis, transform=trans)
-
- size = mpl.rcParams[f"{axis_name}tick.labelsize"]
- self.major_ticklabels = TickLabels(
- axis=self.axis,
- axis_direction=self._axis_direction,
- figure=self.axes.figure,
- transform=trans,
- fontsize=size,
- pad=kwargs.get(
- "major_tick_pad", mpl.rcParams[f"{axis_name}tick.major.pad"]),
- )
- self.minor_ticklabels = TickLabels(
- axis=self.axis,
- axis_direction=self._axis_direction,
- figure=self.axes.figure,
- transform=trans,
- fontsize=size,
- pad=kwargs.get(
- "minor_tick_pad", mpl.rcParams[f"{axis_name}tick.minor.pad"]),
- )
-
- def _get_tick_info(self, tick_iter):
- """
- Return a pair of:
-
- - list of locs and angles for ticks
- - list of locs, angles and labels for ticklabels.
- """
- ticks_loc_angle = []
- ticklabels_loc_angle_label = []
-
- ticklabel_add_angle = self._ticklabel_add_angle
-
- for loc, angle_normal, angle_tangent, label in tick_iter:
- angle_label = angle_tangent - 90 + ticklabel_add_angle
- angle_tick = (angle_normal
- if 90 <= (angle_label - angle_normal) % 360 <= 270
- else angle_normal + 180)
- ticks_loc_angle.append([loc, angle_tick])
- ticklabels_loc_angle_label.append([loc, angle_label, label])
-
- return ticks_loc_angle, ticklabels_loc_angle_label
-
- def _update_ticks(self, renderer=None):
- # set extra pad for major and minor ticklabels: use ticksize of
- # majorticks even for minor ticks. not clear what is best.
-
- if renderer is None:
- renderer = self.figure._get_renderer()
-
- dpi_cor = renderer.points_to_pixels(1.)
- if self.major_ticks.get_visible() and self.major_ticks.get_tick_out():
- ticklabel_pad = self.major_ticks._ticksize * dpi_cor
- self.major_ticklabels._external_pad = ticklabel_pad
- self.minor_ticklabels._external_pad = ticklabel_pad
- else:
- self.major_ticklabels._external_pad = 0
- self.minor_ticklabels._external_pad = 0
-
- majortick_iter, minortick_iter = \
- self._axis_artist_helper.get_tick_iterators(self.axes)
-
- tick_loc_angle, ticklabel_loc_angle_label = \
- self._get_tick_info(majortick_iter)
- self.major_ticks.set_locs_angles(tick_loc_angle)
- self.major_ticklabels.set_locs_angles_labels(ticklabel_loc_angle_label)
-
- tick_loc_angle, ticklabel_loc_angle_label = \
- self._get_tick_info(minortick_iter)
- self.minor_ticks.set_locs_angles(tick_loc_angle)
- self.minor_ticklabels.set_locs_angles_labels(ticklabel_loc_angle_label)
-
- def _draw_ticks(self, renderer):
- self._update_ticks(renderer)
- self.major_ticks.draw(renderer)
- self.major_ticklabels.draw(renderer)
- self.minor_ticks.draw(renderer)
- self.minor_ticklabels.draw(renderer)
- if (self.major_ticklabels.get_visible()
- or self.minor_ticklabels.get_visible()):
- self._draw_offsetText(renderer)
-
- _offsetText_pos = dict(left=(0, 1, "bottom", "right"),
- right=(1, 1, "bottom", "left"),
- bottom=(1, 0, "top", "right"),
- top=(1, 1, "bottom", "right"))
-
- def _init_offsetText(self, direction):
- x, y, va, ha = self._offsetText_pos[direction]
- self.offsetText = mtext.Annotation(
- "",
- xy=(x, y), xycoords="axes fraction",
- xytext=(0, 0), textcoords="offset points",
- color=mpl.rcParams['xtick.color'],
- horizontalalignment=ha, verticalalignment=va,
- )
- self.offsetText.set_transform(IdentityTransform())
- self.axes._set_artist_props(self.offsetText)
-
- def _update_offsetText(self):
- self.offsetText.set_text(self.axis.major.formatter.get_offset())
- self.offsetText.set_size(self.major_ticklabels.get_size())
- offset = (self.major_ticklabels.get_pad()
- + self.major_ticklabels.get_size()
- + 2)
- self.offsetText.xyann = (0, offset)
-
- def _draw_offsetText(self, renderer):
- self._update_offsetText()
- self.offsetText.draw(renderer)
-
- def _init_label(self, **kwargs):
- tr = (self._axis_artist_helper.get_axislabel_transform(self.axes)
- + self.offset_transform)
- self.label = AxisLabel(
- 0, 0, "__from_axes__",
- color="auto",
- fontsize=kwargs.get("labelsize", mpl.rcParams['axes.labelsize']),
- fontweight=mpl.rcParams['axes.labelweight'],
- axis=self.axis,
- transform=tr,
- axis_direction=self._axis_direction,
- )
- self.label.set_figure(self.axes.figure)
- labelpad = kwargs.get("labelpad", 5)
- self.label.set_pad(labelpad)
-
- def _update_label(self, renderer):
- if not self.label.get_visible():
- return
-
- if self._ticklabel_add_angle != self._axislabel_add_angle:
- if ((self.major_ticks.get_visible()
- and not self.major_ticks.get_tick_out())
- or (self.minor_ticks.get_visible()
- and not self.major_ticks.get_tick_out())):
- axislabel_pad = self.major_ticks._ticksize
- else:
- axislabel_pad = 0
- else:
- axislabel_pad = max(self.major_ticklabels._axislabel_pad,
- self.minor_ticklabels._axislabel_pad)
-
- self.label._external_pad = axislabel_pad
-
- xy, angle_tangent = \
- self._axis_artist_helper.get_axislabel_pos_angle(self.axes)
- if xy is None:
- return
-
- angle_label = angle_tangent - 90
-
- x, y = xy
- self.label._ref_angle = angle_label + self._axislabel_add_angle
- self.label.set(x=x, y=y)
-
- def _draw_label(self, renderer):
- self._update_label(renderer)
- self.label.draw(renderer)
-
- def set_label(self, s):
- # docstring inherited
- self.label.set_text(s)
-
- def get_tightbbox(self, renderer=None):
- if not self.get_visible():
- return
- self._axis_artist_helper.update_lim(self.axes)
- self._update_ticks(renderer)
- self._update_label(renderer)
-
- self.line.set_path(self._axis_artist_helper.get_line(self.axes))
- if self.get_axisline_style() is not None:
- self.line.set_line_mutation_scale(self.major_ticklabels.get_size())
-
- bb = [
- *self.major_ticklabels.get_window_extents(renderer),
- *self.minor_ticklabels.get_window_extents(renderer),
- self.label.get_window_extent(renderer),
- self.offsetText.get_window_extent(renderer),
- self.line.get_window_extent(renderer),
- ]
- bb = [b for b in bb if b and (b.width != 0 or b.height != 0)]
- if bb:
- _bbox = Bbox.union(bb)
- return _bbox
- else:
- return None
-
- @martist.allow_rasterization
- def draw(self, renderer):
- # docstring inherited
- if not self.get_visible():
- return
- renderer.open_group(__name__, gid=self.get_gid())
- self._axis_artist_helper.update_lim(self.axes)
- self._draw_ticks(renderer)
- self._draw_line(renderer)
- self._draw_label(renderer)
- renderer.close_group(__name__)
-
- def toggle(self, all=None, ticks=None, ticklabels=None, label=None):
- """
- Toggle visibility of ticks, ticklabels, and (axis) label.
- To turn all off, ::
-
- axis.toggle(all=False)
-
- To turn all off but ticks on ::
-
- axis.toggle(all=False, ticks=True)
-
- To turn all on but (axis) label off ::
-
- axis.toggle(all=True, label=False)
-
- """
- if all:
- _ticks, _ticklabels, _label = True, True, True
- elif all is not None:
- _ticks, _ticklabels, _label = False, False, False
- else:
- _ticks, _ticklabels, _label = None, None, None
-
- if ticks is not None:
- _ticks = ticks
- if ticklabels is not None:
- _ticklabels = ticklabels
- if label is not None:
- _label = label
-
- if _ticks is not None:
- self.major_ticks.set_visible(_ticks)
- self.minor_ticks.set_visible(_ticks)
- if _ticklabels is not None:
- self.major_ticklabels.set_visible(_ticklabels)
- self.minor_ticklabels.set_visible(_ticklabels)
- if _label is not None:
- self.label.set_visible(_label)
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axisline_style.py b/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axisline_style.py
deleted file mode 100644
index 5ae188021b..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axisline_style.py
+++ /dev/null
@@ -1,193 +0,0 @@
-"""
-Provides classes to style the axis lines.
-"""
-import math
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib.patches import _Style, FancyArrowPatch
-from matplotlib.path import Path
-from matplotlib.transforms import IdentityTransform
-
-
-class _FancyAxislineStyle:
- class SimpleArrow(FancyArrowPatch):
- """The artist class that will be returned for SimpleArrow style."""
- _ARROW_STYLE = "->"
-
- def __init__(self, axis_artist, line_path, transform,
- line_mutation_scale):
- self._axis_artist = axis_artist
- self._line_transform = transform
- self._line_path = line_path
- self._line_mutation_scale = line_mutation_scale
-
- FancyArrowPatch.__init__(self,
- path=self._line_path,
- arrowstyle=self._ARROW_STYLE,
- patchA=None,
- patchB=None,
- shrinkA=0.,
- shrinkB=0.,
- mutation_scale=line_mutation_scale,
- mutation_aspect=None,
- transform=IdentityTransform(),
- )
-
- def set_line_mutation_scale(self, scale):
- self.set_mutation_scale(scale*self._line_mutation_scale)
-
- def _extend_path(self, path, mutation_size=10):
- """
- Extend the path to make a room for drawing arrow.
- """
- (x0, y0), (x1, y1) = path.vertices[-2:]
- theta = math.atan2(y1 - y0, x1 - x0)
- x2 = x1 + math.cos(theta) * mutation_size
- y2 = y1 + math.sin(theta) * mutation_size
- if path.codes is None:
- return Path(np.concatenate([path.vertices, [[x2, y2]]]))
- else:
- return Path(np.concatenate([path.vertices, [[x2, y2]]]),
- np.concatenate([path.codes, [Path.LINETO]]))
-
- def set_path(self, path):
- self._line_path = path
-
- def draw(self, renderer):
- """
- Draw the axis line.
- 1) Transform the path to the display coordinate.
- 2) Extend the path to make a room for arrow.
- 3) Update the path of the FancyArrowPatch.
- 4) Draw.
- """
- path_in_disp = self._line_transform.transform_path(self._line_path)
- mutation_size = self.get_mutation_scale() # line_mutation_scale()
- extended_path = self._extend_path(path_in_disp,
- mutation_size=mutation_size)
- self._path_original = extended_path
- FancyArrowPatch.draw(self, renderer)
-
- def get_window_extent(self, renderer=None):
-
- path_in_disp = self._line_transform.transform_path(self._line_path)
- mutation_size = self.get_mutation_scale() # line_mutation_scale()
- extended_path = self._extend_path(path_in_disp,
- mutation_size=mutation_size)
- self._path_original = extended_path
- return FancyArrowPatch.get_window_extent(self, renderer)
-
- class FilledArrow(SimpleArrow):
- """The artist class that will be returned for FilledArrow style."""
- _ARROW_STYLE = "-|>"
-
- def __init__(self, axis_artist, line_path, transform,
- line_mutation_scale, facecolor):
- super().__init__(axis_artist, line_path, transform,
- line_mutation_scale)
- self.set_facecolor(facecolor)
-
-
-class AxislineStyle(_Style):
- """
- A container class which defines style classes for AxisArtists.
-
- An instance of any axisline style class is a callable object,
- whose call signature is ::
-
- __call__(self, axis_artist, path, transform)
-
- When called, this should return an `.Artist` with the following methods::
-
- def set_path(self, path):
- # set the path for axisline.
-
- def set_line_mutation_scale(self, scale):
- # set the scale
-
- def draw(self, renderer):
- # draw
- """
-
- _style_list = {}
-
- class _Base:
- # The derived classes are required to be able to be initialized
- # w/o arguments, i.e., all its argument (except self) must have
- # the default values.
-
- def __init__(self):
- """
- initialization.
- """
- super().__init__()
-
- def __call__(self, axis_artist, transform):
- """
- Given the AxisArtist instance, and transform for the path (set_path
- method), return the Matplotlib artist for drawing the axis line.
- """
- return self.new_line(axis_artist, transform)
-
- class SimpleArrow(_Base):
- """
- A simple arrow.
- """
-
- ArrowAxisClass = _FancyAxislineStyle.SimpleArrow
-
- def __init__(self, size=1):
- """
- Parameters
- ----------
- size : float
- Size of the arrow as a fraction of the ticklabel size.
- """
-
- self.size = size
- super().__init__()
-
- def new_line(self, axis_artist, transform):
-
- linepath = Path([(0, 0), (0, 1)])
- axisline = self.ArrowAxisClass(axis_artist, linepath, transform,
- line_mutation_scale=self.size)
- return axisline
-
- _style_list["->"] = SimpleArrow
-
- class FilledArrow(SimpleArrow):
- """
- An arrow with a filled head.
- """
-
- ArrowAxisClass = _FancyAxislineStyle.FilledArrow
-
- def __init__(self, size=1, facecolor=None):
- """
- Parameters
- ----------
- size : float
- Size of the arrow as a fraction of the ticklabel size.
- facecolor : color, default: :rc:`axes.edgecolor`
- Fill color.
-
- .. versionadded:: 3.7
- """
-
- if facecolor is None:
- facecolor = mpl.rcParams['axes.edgecolor']
- self.size = size
- self._facecolor = facecolor
- super().__init__(size=size)
-
- def new_line(self, axis_artist, transform):
- linepath = Path([(0, 0), (0, 1)])
- axisline = self.ArrowAxisClass(axis_artist, linepath, transform,
- line_mutation_scale=self.size,
- facecolor=self._facecolor)
- return axisline
-
- _style_list["-|>"] = FilledArrow
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axislines.py b/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axislines.py
deleted file mode 100644
index 35717da8ea..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/axislines.py
+++ /dev/null
@@ -1,531 +0,0 @@
-"""
-Axislines includes modified implementation of the Axes class. The
-biggest difference is that the artists responsible for drawing the axis spine,
-ticks, ticklabels and axis labels are separated out from Matplotlib's Axis
-class. Originally, this change was motivated to support curvilinear
-grid. Here are a few reasons that I came up with a new axes class:
-
-* "top" and "bottom" x-axis (or "left" and "right" y-axis) can have
- different ticks (tick locations and labels). This is not possible
- with the current Matplotlib, although some twin axes trick can help.
-
-* Curvilinear grid.
-
-* angled ticks.
-
-In the new axes class, xaxis and yaxis is set to not visible by
-default, and new set of artist (AxisArtist) are defined to draw axis
-line, ticks, ticklabels and axis label. Axes.axis attribute serves as
-a dictionary of these artists, i.e., ax.axis["left"] is a AxisArtist
-instance responsible to draw left y-axis. The default Axes.axis contains
-"bottom", "left", "top" and "right".
-
-AxisArtist can be considered as a container artist and has the following
-children artists which will draw ticks, labels, etc.
-
-* line
-* major_ticks, major_ticklabels
-* minor_ticks, minor_ticklabels
-* offsetText
-* label
-
-Note that these are separate artists from `matplotlib.axis.Axis`, thus most
-tick-related functions in Matplotlib won't work. For example, color and
-markerwidth of the ``ax.axis["bottom"].major_ticks`` will follow those of
-Axes.xaxis unless explicitly specified.
-
-In addition to AxisArtist, the Axes will have *gridlines* attribute,
-which obviously draws grid lines. The gridlines needs to be separated
-from the axis as some gridlines can never pass any axis.
-"""
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api
-import matplotlib.axes as maxes
-from matplotlib.path import Path
-from mpl_toolkits.axes_grid1 import mpl_axes
-from .axisline_style import AxislineStyle # noqa
-from .axis_artist import AxisArtist, GridlinesCollection
-
-
-class _AxisArtistHelperBase:
- """
- Base class for axis helper.
-
- Subclasses should define the methods listed below. The *axes*
- argument will be the ``.axes`` attribute of the caller artist. ::
-
- # Construct the spine.
-
- def get_line_transform(self, axes):
- return transform
-
- def get_line(self, axes):
- return path
-
- # Construct the label.
-
- def get_axislabel_transform(self, axes):
- return transform
-
- def get_axislabel_pos_angle(self, axes):
- return (x, y), angle
-
- # Construct the ticks.
-
- def get_tick_transform(self, axes):
- return transform
-
- def get_tick_iterators(self, axes):
- # A pair of iterables (one for major ticks, one for minor ticks)
- # that yield (tick_position, tick_angle, tick_label).
- return iter_major, iter_minor
- """
-
- def update_lim(self, axes):
- pass
-
- def _to_xy(self, values, const):
- """
- Create a (*values.shape, 2)-shape array representing (x, y) pairs.
-
- The other coordinate is filled with the constant *const*.
-
- Example::
-
- >>> self.nth_coord = 0
- >>> self._to_xy([1, 2, 3], const=0)
- array([[1, 0],
- [2, 0],
- [3, 0]])
- """
- if self.nth_coord == 0:
- return np.stack(np.broadcast_arrays(values, const), axis=-1)
- elif self.nth_coord == 1:
- return np.stack(np.broadcast_arrays(const, values), axis=-1)
- else:
- raise ValueError("Unexpected nth_coord")
-
-
-class _FixedAxisArtistHelperBase(_AxisArtistHelperBase):
- """Helper class for a fixed (in the axes coordinate) axis."""
-
- passthru_pt = _api.deprecated("3.7")(property(
- lambda self: {"left": (0, 0), "right": (1, 0),
- "bottom": (0, 0), "top": (0, 1)}[self._loc]))
-
- def __init__(self, loc, nth_coord=None):
- """``nth_coord = 0``: x-axis; ``nth_coord = 1``: y-axis."""
- self.nth_coord = (
- nth_coord if nth_coord is not None else
- _api.check_getitem(
- {"bottom": 0, "top": 0, "left": 1, "right": 1}, loc=loc))
- if (nth_coord == 0 and loc not in ["left", "right"]
- or nth_coord == 1 and loc not in ["bottom", "top"]):
- _api.warn_deprecated(
- "3.7", message=f"{loc=!r} is incompatible with "
- "{nth_coord=}; support is deprecated since %(since)s")
- self._loc = loc
- self._pos = {"bottom": 0, "top": 1, "left": 0, "right": 1}[loc]
- super().__init__()
- # axis line in transAxes
- self._path = Path(self._to_xy((0, 1), const=self._pos))
-
- def get_nth_coord(self):
- return self.nth_coord
-
- # LINE
-
- def get_line(self, axes):
- return self._path
-
- def get_line_transform(self, axes):
- return axes.transAxes
-
- # LABEL
-
- def get_axislabel_transform(self, axes):
- return axes.transAxes
-
- def get_axislabel_pos_angle(self, axes):
- """
- Return the label reference position in transAxes.
-
- get_label_transform() returns a transform of (transAxes+offset)
- """
- return dict(left=((0., 0.5), 90), # (position, angle_tangent)
- right=((1., 0.5), 90),
- bottom=((0.5, 0.), 0),
- top=((0.5, 1.), 0))[self._loc]
-
- # TICK
-
- def get_tick_transform(self, axes):
- return [axes.get_xaxis_transform(),
- axes.get_yaxis_transform()][self.nth_coord]
-
-
-class _FloatingAxisArtistHelperBase(_AxisArtistHelperBase):
-
- def __init__(self, nth_coord, value):
- self.nth_coord = nth_coord
- self._value = value
- super().__init__()
-
- def get_nth_coord(self):
- return self.nth_coord
-
- def get_line(self, axes):
- raise RuntimeError(
- "get_line method should be defined by the derived class")
-
-
-class FixedAxisArtistHelperRectilinear(_FixedAxisArtistHelperBase):
-
- def __init__(self, axes, loc, nth_coord=None):
- """
- nth_coord = along which coordinate value varies
- in 2D, nth_coord = 0 -> x axis, nth_coord = 1 -> y axis
- """
- super().__init__(loc, nth_coord)
- self.axis = [axes.xaxis, axes.yaxis][self.nth_coord]
-
- # TICK
-
- def get_tick_iterators(self, axes):
- """tick_loc, tick_angle, tick_label"""
- if self._loc in ["bottom", "top"]:
- angle_normal, angle_tangent = 90, 0
- else: # "left", "right"
- angle_normal, angle_tangent = 0, 90
-
- major = self.axis.major
- major_locs = major.locator()
- major_labels = major.formatter.format_ticks(major_locs)
-
- minor = self.axis.minor
- minor_locs = minor.locator()
- minor_labels = minor.formatter.format_ticks(minor_locs)
-
- tick_to_axes = self.get_tick_transform(axes) - axes.transAxes
-
- def _f(locs, labels):
- for loc, label in zip(locs, labels):
- c = self._to_xy(loc, const=self._pos)
- # check if the tick point is inside axes
- c2 = tick_to_axes.transform(c)
- if mpl.transforms._interval_contains_close(
- (0, 1), c2[self.nth_coord]):
- yield c, angle_normal, angle_tangent, label
-
- return _f(major_locs, major_labels), _f(minor_locs, minor_labels)
-
-
-class FloatingAxisArtistHelperRectilinear(_FloatingAxisArtistHelperBase):
-
- def __init__(self, axes, nth_coord,
- passingthrough_point, axis_direction="bottom"):
- super().__init__(nth_coord, passingthrough_point)
- self._axis_direction = axis_direction
- self.axis = [axes.xaxis, axes.yaxis][self.nth_coord]
-
- def get_line(self, axes):
- fixed_coord = 1 - self.nth_coord
- data_to_axes = axes.transData - axes.transAxes
- p = data_to_axes.transform([self._value, self._value])
- return Path(self._to_xy((0, 1), const=p[fixed_coord]))
-
- def get_line_transform(self, axes):
- return axes.transAxes
-
- def get_axislabel_transform(self, axes):
- return axes.transAxes
-
- def get_axislabel_pos_angle(self, axes):
- """
- Return the label reference position in transAxes.
-
- get_label_transform() returns a transform of (transAxes+offset)
- """
- angle = [0, 90][self.nth_coord]
- fixed_coord = 1 - self.nth_coord
- data_to_axes = axes.transData - axes.transAxes
- p = data_to_axes.transform([self._value, self._value])
- verts = self._to_xy(0.5, const=p[fixed_coord])
- if 0 <= verts[fixed_coord] <= 1:
- return verts, angle
- else:
- return None, None
-
- def get_tick_transform(self, axes):
- return axes.transData
-
- def get_tick_iterators(self, axes):
- """tick_loc, tick_angle, tick_label"""
- if self.nth_coord == 0:
- angle_normal, angle_tangent = 90, 0
- else:
- angle_normal, angle_tangent = 0, 90
-
- major = self.axis.major
- major_locs = major.locator()
- major_labels = major.formatter.format_ticks(major_locs)
-
- minor = self.axis.minor
- minor_locs = minor.locator()
- minor_labels = minor.formatter.format_ticks(minor_locs)
-
- data_to_axes = axes.transData - axes.transAxes
-
- def _f(locs, labels):
- for loc, label in zip(locs, labels):
- c = self._to_xy(loc, const=self._value)
- c1, c2 = data_to_axes.transform(c)
- if 0 <= c1 <= 1 and 0 <= c2 <= 1:
- yield c, angle_normal, angle_tangent, label
-
- return _f(major_locs, major_labels), _f(minor_locs, minor_labels)
-
-
-class AxisArtistHelper: # Backcompat.
- Fixed = _FixedAxisArtistHelperBase
- Floating = _FloatingAxisArtistHelperBase
-
-
-class AxisArtistHelperRectlinear: # Backcompat.
- Fixed = FixedAxisArtistHelperRectilinear
- Floating = FloatingAxisArtistHelperRectilinear
-
-
-class GridHelperBase:
-
- def __init__(self):
- self._old_limits = None
- super().__init__()
-
- def update_lim(self, axes):
- x1, x2 = axes.get_xlim()
- y1, y2 = axes.get_ylim()
- if self._old_limits != (x1, x2, y1, y2):
- self._update_grid(x1, y1, x2, y2)
- self._old_limits = (x1, x2, y1, y2)
-
- def _update_grid(self, x1, y1, x2, y2):
- """Cache relevant computations when the axes limits have changed."""
-
- def get_gridlines(self, which, axis):
- """
- Return list of grid lines as a list of paths (list of points).
-
- Parameters
- ----------
- which : {"both", "major", "minor"}
- axis : {"both", "x", "y"}
- """
- return []
-
-
-class GridHelperRectlinear(GridHelperBase):
-
- def __init__(self, axes):
- super().__init__()
- self.axes = axes
-
- def new_fixed_axis(self, loc,
- nth_coord=None,
- axis_direction=None,
- offset=None,
- axes=None,
- ):
- if axes is None:
- _api.warn_external(
- "'new_fixed_axis' explicitly requires the axes keyword.")
- axes = self.axes
- if axis_direction is None:
- axis_direction = loc
-
- helper = FixedAxisArtistHelperRectilinear(axes, loc, nth_coord)
- axisline = AxisArtist(axes, helper, offset=offset,
- axis_direction=axis_direction)
- return axisline
-
- def new_floating_axis(self, nth_coord, value,
- axis_direction="bottom",
- axes=None,
- ):
- if axes is None:
- _api.warn_external(
- "'new_floating_axis' explicitly requires the axes keyword.")
- axes = self.axes
-
- helper = FloatingAxisArtistHelperRectilinear(
- axes, nth_coord, value, axis_direction)
- axisline = AxisArtist(axes, helper, axis_direction=axis_direction)
- axisline.line.set_clip_on(True)
- axisline.line.set_clip_box(axisline.axes.bbox)
- return axisline
-
- def get_gridlines(self, which="major", axis="both"):
- """
- Return list of gridline coordinates in data coordinates.
-
- Parameters
- ----------
- which : {"both", "major", "minor"}
- axis : {"both", "x", "y"}
- """
- _api.check_in_list(["both", "major", "minor"], which=which)
- _api.check_in_list(["both", "x", "y"], axis=axis)
- gridlines = []
-
- if axis in ("both", "x"):
- locs = []
- y1, y2 = self.axes.get_ylim()
- if which in ("both", "major"):
- locs.extend(self.axes.xaxis.major.locator())
- if which in ("both", "minor"):
- locs.extend(self.axes.xaxis.minor.locator())
-
- for x in locs:
- gridlines.append([[x, x], [y1, y2]])
-
- if axis in ("both", "y"):
- x1, x2 = self.axes.get_xlim()
- locs = []
- if self.axes.yaxis._major_tick_kw["gridOn"]:
- locs.extend(self.axes.yaxis.major.locator())
- if self.axes.yaxis._minor_tick_kw["gridOn"]:
- locs.extend(self.axes.yaxis.minor.locator())
-
- for y in locs:
- gridlines.append([[x1, x2], [y, y]])
-
- return gridlines
-
-
-class Axes(maxes.Axes):
-
- @_api.deprecated("3.8", alternative="ax.axis")
- def __call__(self, *args, **kwargs):
- return maxes.Axes.axis(self.axes, *args, **kwargs)
-
- def __init__(self, *args, grid_helper=None, **kwargs):
- self._axisline_on = True
- self._grid_helper = (grid_helper if grid_helper
- else GridHelperRectlinear(self))
- super().__init__(*args, **kwargs)
- self.toggle_axisline(True)
-
- def toggle_axisline(self, b=None):
- if b is None:
- b = not self._axisline_on
- if b:
- self._axisline_on = True
- self.spines[:].set_visible(False)
- self.xaxis.set_visible(False)
- self.yaxis.set_visible(False)
- else:
- self._axisline_on = False
- self.spines[:].set_visible(True)
- self.xaxis.set_visible(True)
- self.yaxis.set_visible(True)
-
- @property
- def axis(self):
- return self._axislines
-
- def clear(self):
- # docstring inherited
-
- # Init gridlines before clear() as clear() calls grid().
- self.gridlines = gridlines = GridlinesCollection(
- [],
- colors=mpl.rcParams['grid.color'],
- linestyles=mpl.rcParams['grid.linestyle'],
- linewidths=mpl.rcParams['grid.linewidth'])
- self._set_artist_props(gridlines)
- gridlines.set_grid_helper(self.get_grid_helper())
-
- super().clear()
-
- # clip_path is set after Axes.clear(): that's when a patch is created.
- gridlines.set_clip_path(self.axes.patch)
-
- # Init axis artists.
- self._axislines = mpl_axes.Axes.AxisDict(self)
- new_fixed_axis = self.get_grid_helper().new_fixed_axis
- self._axislines.update({
- loc: new_fixed_axis(loc=loc, axes=self, axis_direction=loc)
- for loc in ["bottom", "top", "left", "right"]})
- for axisline in [self._axislines["top"], self._axislines["right"]]:
- axisline.label.set_visible(False)
- axisline.major_ticklabels.set_visible(False)
- axisline.minor_ticklabels.set_visible(False)
-
- def get_grid_helper(self):
- return self._grid_helper
-
- def grid(self, visible=None, which='major', axis="both", **kwargs):
- """
- Toggle the gridlines, and optionally set the properties of the lines.
- """
- # There are some discrepancies in the behavior of grid() between
- # axes_grid and Matplotlib, because axes_grid explicitly sets the
- # visibility of the gridlines.
- super().grid(visible, which=which, axis=axis, **kwargs)
- if not self._axisline_on:
- return
- if visible is None:
- visible = (self.axes.xaxis._minor_tick_kw["gridOn"]
- or self.axes.xaxis._major_tick_kw["gridOn"]
- or self.axes.yaxis._minor_tick_kw["gridOn"]
- or self.axes.yaxis._major_tick_kw["gridOn"])
- self.gridlines.set(which=which, axis=axis, visible=visible)
- self.gridlines.set(**kwargs)
-
- def get_children(self):
- if self._axisline_on:
- children = [*self._axislines.values(), self.gridlines]
- else:
- children = []
- children.extend(super().get_children())
- return children
-
- def new_fixed_axis(self, loc, offset=None):
- gh = self.get_grid_helper()
- axis = gh.new_fixed_axis(loc,
- nth_coord=None,
- axis_direction=None,
- offset=offset,
- axes=self,
- )
- return axis
-
- def new_floating_axis(self, nth_coord, value, axis_direction="bottom"):
- gh = self.get_grid_helper()
- axis = gh.new_floating_axis(nth_coord, value,
- axis_direction=axis_direction,
- axes=self)
- return axis
-
-
-class AxesZero(Axes):
-
- def clear(self):
- super().clear()
- new_floating_axis = self.get_grid_helper().new_floating_axis
- self._axislines.update(
- xzero=new_floating_axis(
- nth_coord=0, value=0., axis_direction="bottom", axes=self),
- yzero=new_floating_axis(
- nth_coord=1, value=0., axis_direction="left", axes=self),
- )
- for k in ["xzero", "yzero"]:
- self._axislines[k].line.set_clip_path(self.patch)
- self._axislines[k].set_visible(False)
-
-
-Subplot = Axes
-SubplotZero = AxesZero
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/floating_axes.py b/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/floating_axes.py
deleted file mode 100644
index 97dafe98c6..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/floating_axes.py
+++ /dev/null
@@ -1,298 +0,0 @@
-"""
-An experimental support for curvilinear grid.
-"""
-
-# TODO :
-# see if tick_iterator method can be simplified by reusing the parent method.
-
-import functools
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, cbook
-import matplotlib.patches as mpatches
-from matplotlib.path import Path
-
-from mpl_toolkits.axes_grid1.parasite_axes import host_axes_class_factory
-
-from . import axislines, grid_helper_curvelinear
-from .axis_artist import AxisArtist
-from .grid_finder import ExtremeFinderSimple
-
-
-class FloatingAxisArtistHelper(
- grid_helper_curvelinear.FloatingAxisArtistHelper):
- pass
-
-
-class FixedAxisArtistHelper(grid_helper_curvelinear.FloatingAxisArtistHelper):
-
- def __init__(self, grid_helper, side, nth_coord_ticks=None):
- """
- nth_coord = along which coordinate value varies.
- nth_coord = 0 -> x axis, nth_coord = 1 -> y axis
- """
- lon1, lon2, lat1, lat2 = grid_helper.grid_finder.extreme_finder(*[None] * 5)
- value, nth_coord = _api.check_getitem(
- dict(left=(lon1, 0), right=(lon2, 0), bottom=(lat1, 1), top=(lat2, 1)),
- side=side)
- super().__init__(grid_helper, nth_coord, value, axis_direction=side)
- if nth_coord_ticks is None:
- nth_coord_ticks = nth_coord
- self.nth_coord_ticks = nth_coord_ticks
-
- self.value = value
- self.grid_helper = grid_helper
- self._side = side
-
- def update_lim(self, axes):
- self.grid_helper.update_lim(axes)
- self._grid_info = self.grid_helper._grid_info
-
- def get_tick_iterators(self, axes):
- """tick_loc, tick_angle, tick_label, (optionally) tick_label"""
-
- grid_finder = self.grid_helper.grid_finder
-
- lat_levs, lat_n, lat_factor = self._grid_info["lat_info"]
- yy0 = lat_levs / lat_factor
-
- lon_levs, lon_n, lon_factor = self._grid_info["lon_info"]
- xx0 = lon_levs / lon_factor
-
- extremes = self.grid_helper.grid_finder.extreme_finder(*[None] * 5)
- xmin, xmax = sorted(extremes[:2])
- ymin, ymax = sorted(extremes[2:])
-
- def trf_xy(x, y):
- trf = grid_finder.get_transform() + axes.transData
- return trf.transform(np.column_stack(np.broadcast_arrays(x, y))).T
-
- if self.nth_coord == 0:
- mask = (ymin <= yy0) & (yy0 <= ymax)
- (xx1, yy1), (dxx1, dyy1), (dxx2, dyy2) = \
- grid_helper_curvelinear._value_and_jacobian(
- trf_xy, self.value, yy0[mask], (xmin, xmax), (ymin, ymax))
- labels = self._grid_info["lat_labels"]
-
- elif self.nth_coord == 1:
- mask = (xmin <= xx0) & (xx0 <= xmax)
- (xx1, yy1), (dxx2, dyy2), (dxx1, dyy1) = \
- grid_helper_curvelinear._value_and_jacobian(
- trf_xy, xx0[mask], self.value, (xmin, xmax), (ymin, ymax))
- labels = self._grid_info["lon_labels"]
-
- labels = [l for l, m in zip(labels, mask) if m]
-
- angle_normal = np.arctan2(dyy1, dxx1)
- angle_tangent = np.arctan2(dyy2, dxx2)
- mm = (dyy1 == 0) & (dxx1 == 0) # points with degenerate normal
- angle_normal[mm] = angle_tangent[mm] + np.pi / 2
-
- tick_to_axes = self.get_tick_transform(axes) - axes.transAxes
- in_01 = functools.partial(
- mpl.transforms._interval_contains_close, (0, 1))
-
- def f1():
- for x, y, normal, tangent, lab \
- in zip(xx1, yy1, angle_normal, angle_tangent, labels):
- c2 = tick_to_axes.transform((x, y))
- if in_01(c2[0]) and in_01(c2[1]):
- yield [x, y], *np.rad2deg([normal, tangent]), lab
-
- return f1(), iter([])
-
- def get_line(self, axes):
- self.update_lim(axes)
- k, v = dict(left=("lon_lines0", 0),
- right=("lon_lines0", 1),
- bottom=("lat_lines0", 0),
- top=("lat_lines0", 1))[self._side]
- xx, yy = self._grid_info[k][v]
- return Path(np.column_stack([xx, yy]))
-
-
-class ExtremeFinderFixed(ExtremeFinderSimple):
- # docstring inherited
-
- def __init__(self, extremes):
- """
- This subclass always returns the same bounding box.
-
- Parameters
- ----------
- extremes : (float, float, float, float)
- The bounding box that this helper always returns.
- """
- self._extremes = extremes
-
- def __call__(self, transform_xy, x1, y1, x2, y2):
- # docstring inherited
- return self._extremes
-
-
-class GridHelperCurveLinear(grid_helper_curvelinear.GridHelperCurveLinear):
-
- def __init__(self, aux_trans, extremes,
- grid_locator1=None,
- grid_locator2=None,
- tick_formatter1=None,
- tick_formatter2=None):
- # docstring inherited
- super().__init__(aux_trans,
- extreme_finder=ExtremeFinderFixed(extremes),
- grid_locator1=grid_locator1,
- grid_locator2=grid_locator2,
- tick_formatter1=tick_formatter1,
- tick_formatter2=tick_formatter2)
-
- @_api.deprecated("3.8")
- def get_data_boundary(self, side):
- """
- Return v=0, nth=1.
- """
- lon1, lon2, lat1, lat2 = self.grid_finder.extreme_finder(*[None] * 5)
- return dict(left=(lon1, 0),
- right=(lon2, 0),
- bottom=(lat1, 1),
- top=(lat2, 1))[side]
-
- def new_fixed_axis(self, loc,
- nth_coord=None,
- axis_direction=None,
- offset=None,
- axes=None):
- if axes is None:
- axes = self.axes
- if axis_direction is None:
- axis_direction = loc
- # This is not the same as the FixedAxisArtistHelper class used by
- # grid_helper_curvelinear.GridHelperCurveLinear.new_fixed_axis!
- helper = FixedAxisArtistHelper(
- self, loc, nth_coord_ticks=nth_coord)
- axisline = AxisArtist(axes, helper, axis_direction=axis_direction)
- # Perhaps should be moved to the base class?
- axisline.line.set_clip_on(True)
- axisline.line.set_clip_box(axisline.axes.bbox)
- return axisline
-
- # new_floating_axis will inherit the grid_helper's extremes.
-
- # def new_floating_axis(self, nth_coord,
- # value,
- # axes=None,
- # axis_direction="bottom"
- # ):
-
- # axis = super(GridHelperCurveLinear,
- # self).new_floating_axis(nth_coord,
- # value, axes=axes,
- # axis_direction=axis_direction)
-
- # # set extreme values of the axis helper
- # if nth_coord == 1:
- # axis.get_helper().set_extremes(*self._extremes[:2])
- # elif nth_coord == 0:
- # axis.get_helper().set_extremes(*self._extremes[2:])
-
- # return axis
-
- def _update_grid(self, x1, y1, x2, y2):
- if self._grid_info is None:
- self._grid_info = dict()
-
- grid_info = self._grid_info
-
- grid_finder = self.grid_finder
- extremes = grid_finder.extreme_finder(grid_finder.inv_transform_xy,
- x1, y1, x2, y2)
-
- lon_min, lon_max = sorted(extremes[:2])
- lat_min, lat_max = sorted(extremes[2:])
- grid_info["extremes"] = lon_min, lon_max, lat_min, lat_max # extremes
-
- lon_levs, lon_n, lon_factor = \
- grid_finder.grid_locator1(lon_min, lon_max)
- lon_levs = np.asarray(lon_levs)
- lat_levs, lat_n, lat_factor = \
- grid_finder.grid_locator2(lat_min, lat_max)
- lat_levs = np.asarray(lat_levs)
-
- grid_info["lon_info"] = lon_levs, lon_n, lon_factor
- grid_info["lat_info"] = lat_levs, lat_n, lat_factor
-
- grid_info["lon_labels"] = grid_finder.tick_formatter1(
- "bottom", lon_factor, lon_levs)
- grid_info["lat_labels"] = grid_finder.tick_formatter2(
- "bottom", lat_factor, lat_levs)
-
- lon_values = lon_levs[:lon_n] / lon_factor
- lat_values = lat_levs[:lat_n] / lat_factor
-
- lon_lines, lat_lines = grid_finder._get_raw_grid_lines(
- lon_values[(lon_min < lon_values) & (lon_values < lon_max)],
- lat_values[(lat_min < lat_values) & (lat_values < lat_max)],
- lon_min, lon_max, lat_min, lat_max)
-
- grid_info["lon_lines"] = lon_lines
- grid_info["lat_lines"] = lat_lines
-
- lon_lines, lat_lines = grid_finder._get_raw_grid_lines(
- # lon_min, lon_max, lat_min, lat_max)
- extremes[:2], extremes[2:], *extremes)
-
- grid_info["lon_lines0"] = lon_lines
- grid_info["lat_lines0"] = lat_lines
-
- def get_gridlines(self, which="major", axis="both"):
- grid_lines = []
- if axis in ["both", "x"]:
- grid_lines.extend(self._grid_info["lon_lines"])
- if axis in ["both", "y"]:
- grid_lines.extend(self._grid_info["lat_lines"])
- return grid_lines
-
-
-class FloatingAxesBase:
-
- def __init__(self, *args, grid_helper, **kwargs):
- _api.check_isinstance(GridHelperCurveLinear, grid_helper=grid_helper)
- super().__init__(*args, grid_helper=grid_helper, **kwargs)
- self.set_aspect(1.)
-
- def _gen_axes_patch(self):
- # docstring inherited
- x0, x1, y0, y1 = self.get_grid_helper().grid_finder.extreme_finder(*[None] * 5)
- patch = mpatches.Polygon([(x0, y0), (x1, y0), (x1, y1), (x0, y1)])
- patch.get_path()._interpolation_steps = 100
- return patch
-
- def clear(self):
- super().clear()
- self.patch.set_transform(
- self.get_grid_helper().grid_finder.get_transform()
- + self.transData)
- # The original patch is not in the draw tree; it is only used for
- # clipping purposes.
- orig_patch = super()._gen_axes_patch()
- orig_patch.set_figure(self.figure)
- orig_patch.set_transform(self.transAxes)
- self.patch.set_clip_path(orig_patch)
- self.gridlines.set_clip_path(orig_patch)
- self.adjust_axes_lim()
-
- def adjust_axes_lim(self):
- bbox = self.patch.get_path().get_extents(
- # First transform to pixel coords, then to parent data coords.
- self.patch.get_transform() - self.transData)
- bbox = bbox.expanded(1.02, 1.02)
- self.set_xlim(bbox.xmin, bbox.xmax)
- self.set_ylim(bbox.ymin, bbox.ymax)
-
-
-floatingaxes_class_factory = cbook._make_class_factory(
- FloatingAxesBase, "Floating{}")
-FloatingAxes = floatingaxes_class_factory(
- host_axes_class_factory(axislines.Axes))
-FloatingSubplot = FloatingAxes
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/grid_finder.py b/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/grid_finder.py
deleted file mode 100644
index f969b011c4..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/grid_finder.py
+++ /dev/null
@@ -1,335 +0,0 @@
-import numpy as np
-
-from matplotlib import ticker as mticker
-from matplotlib.transforms import Bbox, Transform
-
-
-def _find_line_box_crossings(xys, bbox):
- """
- Find the points where a polyline crosses a bbox, and the crossing angles.
-
- Parameters
- ----------
- xys : (N, 2) array
- The polyline coordinates.
- bbox : `.Bbox`
- The bounding box.
-
- Returns
- -------
- list of ((float, float), float)
- Four separate lists of crossings, for the left, right, bottom, and top
- sides of the bbox, respectively. For each list, the entries are the
- ``((x, y), ccw_angle_in_degrees)`` of the crossing, where an angle of 0
- means that the polyline is moving to the right at the crossing point.
-
- The entries are computed by linearly interpolating at each crossing
- between the nearest points on either side of the bbox edges.
- """
- crossings = []
- dxys = xys[1:] - xys[:-1]
- for sl in [slice(None), slice(None, None, -1)]:
- us, vs = xys.T[sl] # "this" coord, "other" coord
- dus, dvs = dxys.T[sl]
- umin, vmin = bbox.min[sl]
- umax, vmax = bbox.max[sl]
- for u0, inside in [(umin, us > umin), (umax, us < umax)]:
- crossings.append([])
- idxs, = (inside[:-1] ^ inside[1:]).nonzero()
- for idx in idxs:
- v = vs[idx] + (u0 - us[idx]) * dvs[idx] / dus[idx]
- if not vmin <= v <= vmax:
- continue
- crossing = (u0, v)[sl]
- theta = np.degrees(np.arctan2(*dxys[idx][::-1]))
- crossings[-1].append((crossing, theta))
- return crossings
-
-
-class ExtremeFinderSimple:
- """
- A helper class to figure out the range of grid lines that need to be drawn.
- """
-
- def __init__(self, nx, ny):
- """
- Parameters
- ----------
- nx, ny : int
- The number of samples in each direction.
- """
- self.nx = nx
- self.ny = ny
-
- def __call__(self, transform_xy, x1, y1, x2, y2):
- """
- Compute an approximation of the bounding box obtained by applying
- *transform_xy* to the box delimited by ``(x1, y1, x2, y2)``.
-
- The intended use is to have ``(x1, y1, x2, y2)`` in axes coordinates,
- and have *transform_xy* be the transform from axes coordinates to data
- coordinates; this method then returns the range of data coordinates
- that span the actual axes.
-
- The computation is done by sampling ``nx * ny`` equispaced points in
- the ``(x1, y1, x2, y2)`` box and finding the resulting points with
- extremal coordinates; then adding some padding to take into account the
- finite sampling.
-
- As each sampling step covers a relative range of *1/nx* or *1/ny*,
- the padding is computed by expanding the span covered by the extremal
- coordinates by these fractions.
- """
- x, y = np.meshgrid(
- np.linspace(x1, x2, self.nx), np.linspace(y1, y2, self.ny))
- xt, yt = transform_xy(np.ravel(x), np.ravel(y))
- return self._add_pad(xt.min(), xt.max(), yt.min(), yt.max())
-
- def _add_pad(self, x_min, x_max, y_min, y_max):
- """Perform the padding mentioned in `__call__`."""
- dx = (x_max - x_min) / self.nx
- dy = (y_max - y_min) / self.ny
- return x_min - dx, x_max + dx, y_min - dy, y_max + dy
-
-
-class _User2DTransform(Transform):
- """A transform defined by two user-set functions."""
-
- input_dims = output_dims = 2
-
- def __init__(self, forward, backward):
- """
- Parameters
- ----------
- forward, backward : callable
- The forward and backward transforms, taking ``x`` and ``y`` as
- separate arguments and returning ``(tr_x, tr_y)``.
- """
- # The normal Matplotlib convention would be to take and return an
- # (N, 2) array but axisartist uses the transposed version.
- super().__init__()
- self._forward = forward
- self._backward = backward
-
- def transform_non_affine(self, values):
- # docstring inherited
- return np.transpose(self._forward(*np.transpose(values)))
-
- def inverted(self):
- # docstring inherited
- return type(self)(self._backward, self._forward)
-
-
-class GridFinder:
- """
- Internal helper for `~.grid_helper_curvelinear.GridHelperCurveLinear`, with
- the same constructor parameters; should not be directly instantiated.
- """
-
- def __init__(self,
- transform,
- extreme_finder=None,
- grid_locator1=None,
- grid_locator2=None,
- tick_formatter1=None,
- tick_formatter2=None):
- if extreme_finder is None:
- extreme_finder = ExtremeFinderSimple(20, 20)
- if grid_locator1 is None:
- grid_locator1 = MaxNLocator()
- if grid_locator2 is None:
- grid_locator2 = MaxNLocator()
- if tick_formatter1 is None:
- tick_formatter1 = FormatterPrettyPrint()
- if tick_formatter2 is None:
- tick_formatter2 = FormatterPrettyPrint()
- self.extreme_finder = extreme_finder
- self.grid_locator1 = grid_locator1
- self.grid_locator2 = grid_locator2
- self.tick_formatter1 = tick_formatter1
- self.tick_formatter2 = tick_formatter2
- self.set_transform(transform)
-
- def get_grid_info(self, x1, y1, x2, y2):
- """
- lon_values, lat_values : list of grid values. if integer is given,
- rough number of grids in each direction.
- """
-
- extremes = self.extreme_finder(self.inv_transform_xy, x1, y1, x2, y2)
-
- # min & max rage of lat (or lon) for each grid line will be drawn.
- # i.e., gridline of lon=0 will be drawn from lat_min to lat_max.
-
- lon_min, lon_max, lat_min, lat_max = extremes
- lon_levs, lon_n, lon_factor = self.grid_locator1(lon_min, lon_max)
- lon_levs = np.asarray(lon_levs)
- lat_levs, lat_n, lat_factor = self.grid_locator2(lat_min, lat_max)
- lat_levs = np.asarray(lat_levs)
-
- lon_values = lon_levs[:lon_n] / lon_factor
- lat_values = lat_levs[:lat_n] / lat_factor
-
- lon_lines, lat_lines = self._get_raw_grid_lines(lon_values,
- lat_values,
- lon_min, lon_max,
- lat_min, lat_max)
-
- ddx = (x2-x1)*1.e-10
- ddy = (y2-y1)*1.e-10
- bb = Bbox.from_extents(x1-ddx, y1-ddy, x2+ddx, y2+ddy)
-
- grid_info = {
- "extremes": extremes,
- "lon_lines": lon_lines,
- "lat_lines": lat_lines,
- "lon": self._clip_grid_lines_and_find_ticks(
- lon_lines, lon_values, lon_levs, bb),
- "lat": self._clip_grid_lines_and_find_ticks(
- lat_lines, lat_values, lat_levs, bb),
- }
-
- tck_labels = grid_info["lon"]["tick_labels"] = {}
- for direction in ["left", "bottom", "right", "top"]:
- levs = grid_info["lon"]["tick_levels"][direction]
- tck_labels[direction] = self.tick_formatter1(
- direction, lon_factor, levs)
-
- tck_labels = grid_info["lat"]["tick_labels"] = {}
- for direction in ["left", "bottom", "right", "top"]:
- levs = grid_info["lat"]["tick_levels"][direction]
- tck_labels[direction] = self.tick_formatter2(
- direction, lat_factor, levs)
-
- return grid_info
-
- def _get_raw_grid_lines(self,
- lon_values, lat_values,
- lon_min, lon_max, lat_min, lat_max):
-
- lons_i = np.linspace(lon_min, lon_max, 100) # for interpolation
- lats_i = np.linspace(lat_min, lat_max, 100)
-
- lon_lines = [self.transform_xy(np.full_like(lats_i, lon), lats_i)
- for lon in lon_values]
- lat_lines = [self.transform_xy(lons_i, np.full_like(lons_i, lat))
- for lat in lat_values]
-
- return lon_lines, lat_lines
-
- def _clip_grid_lines_and_find_ticks(self, lines, values, levs, bb):
- gi = {
- "values": [],
- "levels": [],
- "tick_levels": dict(left=[], bottom=[], right=[], top=[]),
- "tick_locs": dict(left=[], bottom=[], right=[], top=[]),
- "lines": [],
- }
-
- tck_levels = gi["tick_levels"]
- tck_locs = gi["tick_locs"]
- for (lx, ly), v, lev in zip(lines, values, levs):
- tcks = _find_line_box_crossings(np.column_stack([lx, ly]), bb)
- gi["levels"].append(v)
- gi["lines"].append([(lx, ly)])
-
- for tck, direction in zip(tcks,
- ["left", "right", "bottom", "top"]):
- for t in tck:
- tck_levels[direction].append(lev)
- tck_locs[direction].append(t)
-
- return gi
-
- def set_transform(self, aux_trans):
- if isinstance(aux_trans, Transform):
- self._aux_transform = aux_trans
- elif len(aux_trans) == 2 and all(map(callable, aux_trans)):
- self._aux_transform = _User2DTransform(*aux_trans)
- else:
- raise TypeError("'aux_trans' must be either a Transform "
- "instance or a pair of callables")
-
- def get_transform(self):
- return self._aux_transform
-
- update_transform = set_transform # backcompat alias.
-
- def transform_xy(self, x, y):
- return self._aux_transform.transform(np.column_stack([x, y])).T
-
- def inv_transform_xy(self, x, y):
- return self._aux_transform.inverted().transform(
- np.column_stack([x, y])).T
-
- def update(self, **kwargs):
- for k, v in kwargs.items():
- if k in ["extreme_finder",
- "grid_locator1",
- "grid_locator2",
- "tick_formatter1",
- "tick_formatter2"]:
- setattr(self, k, v)
- else:
- raise ValueError(f"Unknown update property {k!r}")
-
-
-class MaxNLocator(mticker.MaxNLocator):
- def __init__(self, nbins=10, steps=None,
- trim=True,
- integer=False,
- symmetric=False,
- prune=None):
- # trim argument has no effect. It has been left for API compatibility
- super().__init__(nbins, steps=steps, integer=integer,
- symmetric=symmetric, prune=prune)
- self.create_dummy_axis()
-
- def __call__(self, v1, v2):
- locs = super().tick_values(v1, v2)
- return np.array(locs), len(locs), 1 # 1: factor (see angle_helper)
-
-
-class FixedLocator:
- def __init__(self, locs):
- self._locs = locs
-
- def __call__(self, v1, v2):
- v1, v2 = sorted([v1, v2])
- locs = np.array([l for l in self._locs if v1 <= l <= v2])
- return locs, len(locs), 1 # 1: factor (see angle_helper)
-
-
-# Tick Formatter
-
-class FormatterPrettyPrint:
- def __init__(self, useMathText=True):
- self._fmt = mticker.ScalarFormatter(
- useMathText=useMathText, useOffset=False)
- self._fmt.create_dummy_axis()
-
- def __call__(self, direction, factor, values):
- return self._fmt.format_ticks(values)
-
-
-class DictFormatter:
- def __init__(self, format_dict, formatter=None):
- """
- format_dict : dictionary for format strings to be used.
- formatter : fall-back formatter
- """
- super().__init__()
- self._format_dict = format_dict
- self._fallback_formatter = formatter
-
- def __call__(self, direction, factor, values):
- """
- factor is ignored if value is found in the dictionary
- """
- if self._fallback_formatter:
- fallback_strings = self._fallback_formatter(
- direction, factor, values)
- else:
- fallback_strings = [""] * len(values)
- return [self._format_dict.get(k, v)
- for k, v in zip(values, fallback_strings)]
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/grid_helper_curvelinear.py b/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/grid_helper_curvelinear.py
deleted file mode 100644
index ae17452b6c..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/grid_helper_curvelinear.py
+++ /dev/null
@@ -1,336 +0,0 @@
-"""
-An experimental support for curvilinear grid.
-"""
-
-import functools
-from itertools import chain
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib.path import Path
-from matplotlib.transforms import Affine2D, IdentityTransform
-from .axislines import (
- _FixedAxisArtistHelperBase, _FloatingAxisArtistHelperBase, GridHelperBase)
-from .axis_artist import AxisArtist
-from .grid_finder import GridFinder
-
-
-def _value_and_jacobian(func, xs, ys, xlims, ylims):
- """
- Compute *func* and its derivatives along x and y at positions *xs*, *ys*,
- while ensuring that finite difference calculations don't try to evaluate
- values outside of *xlims*, *ylims*.
- """
- eps = np.finfo(float).eps ** (1/2) # see e.g. scipy.optimize.approx_fprime
- val = func(xs, ys)
- # Take the finite difference step in the direction where the bound is the
- # furthest; the step size is min of epsilon and distance to that bound.
- xlo, xhi = sorted(xlims)
- dxlo = xs - xlo
- dxhi = xhi - xs
- xeps = (np.take([-1, 1], dxhi >= dxlo)
- * np.minimum(eps, np.maximum(dxlo, dxhi)))
- val_dx = func(xs + xeps, ys)
- ylo, yhi = sorted(ylims)
- dylo = ys - ylo
- dyhi = yhi - ys
- yeps = (np.take([-1, 1], dyhi >= dylo)
- * np.minimum(eps, np.maximum(dylo, dyhi)))
- val_dy = func(xs, ys + yeps)
- return (val, (val_dx - val) / xeps, (val_dy - val) / yeps)
-
-
-class FixedAxisArtistHelper(_FixedAxisArtistHelperBase):
- """
- Helper class for a fixed axis.
- """
-
- def __init__(self, grid_helper, side, nth_coord_ticks=None):
- """
- nth_coord = along which coordinate value varies.
- nth_coord = 0 -> x axis, nth_coord = 1 -> y axis
- """
-
- super().__init__(loc=side)
-
- self.grid_helper = grid_helper
- if nth_coord_ticks is None:
- nth_coord_ticks = self.nth_coord
- self.nth_coord_ticks = nth_coord_ticks
-
- self.side = side
-
- def update_lim(self, axes):
- self.grid_helper.update_lim(axes)
-
- def get_tick_transform(self, axes):
- return axes.transData
-
- def get_tick_iterators(self, axes):
- """tick_loc, tick_angle, tick_label"""
- v1, v2 = axes.get_ylim() if self.nth_coord == 0 else axes.get_xlim()
- if v1 > v2: # Inverted limits.
- side = {"left": "right", "right": "left",
- "top": "bottom", "bottom": "top"}[self.side]
- else:
- side = self.side
- g = self.grid_helper
- ti1 = g.get_tick_iterator(self.nth_coord_ticks, side)
- ti2 = g.get_tick_iterator(1-self.nth_coord_ticks, side, minor=True)
- return chain(ti1, ti2), iter([])
-
-
-class FloatingAxisArtistHelper(_FloatingAxisArtistHelperBase):
-
- def __init__(self, grid_helper, nth_coord, value, axis_direction=None):
- """
- nth_coord = along which coordinate value varies.
- nth_coord = 0 -> x axis, nth_coord = 1 -> y axis
- """
- super().__init__(nth_coord, value)
- self.value = value
- self.grid_helper = grid_helper
- self._extremes = -np.inf, np.inf
- self._line_num_points = 100 # number of points to create a line
-
- def set_extremes(self, e1, e2):
- if e1 is None:
- e1 = -np.inf
- if e2 is None:
- e2 = np.inf
- self._extremes = e1, e2
-
- def update_lim(self, axes):
- self.grid_helper.update_lim(axes)
-
- x1, x2 = axes.get_xlim()
- y1, y2 = axes.get_ylim()
- grid_finder = self.grid_helper.grid_finder
- extremes = grid_finder.extreme_finder(grid_finder.inv_transform_xy,
- x1, y1, x2, y2)
-
- lon_min, lon_max, lat_min, lat_max = extremes
- e_min, e_max = self._extremes # ranges of other coordinates
- if self.nth_coord == 0:
- lat_min = max(e_min, lat_min)
- lat_max = min(e_max, lat_max)
- elif self.nth_coord == 1:
- lon_min = max(e_min, lon_min)
- lon_max = min(e_max, lon_max)
-
- lon_levs, lon_n, lon_factor = \
- grid_finder.grid_locator1(lon_min, lon_max)
- lat_levs, lat_n, lat_factor = \
- grid_finder.grid_locator2(lat_min, lat_max)
-
- if self.nth_coord == 0:
- xx0 = np.full(self._line_num_points, self.value)
- yy0 = np.linspace(lat_min, lat_max, self._line_num_points)
- xx, yy = grid_finder.transform_xy(xx0, yy0)
- elif self.nth_coord == 1:
- xx0 = np.linspace(lon_min, lon_max, self._line_num_points)
- yy0 = np.full(self._line_num_points, self.value)
- xx, yy = grid_finder.transform_xy(xx0, yy0)
-
- self._grid_info = {
- "extremes": (lon_min, lon_max, lat_min, lat_max),
- "lon_info": (lon_levs, lon_n, np.asarray(lon_factor)),
- "lat_info": (lat_levs, lat_n, np.asarray(lat_factor)),
- "lon_labels": grid_finder.tick_formatter1(
- "bottom", lon_factor, lon_levs),
- "lat_labels": grid_finder.tick_formatter2(
- "bottom", lat_factor, lat_levs),
- "line_xy": (xx, yy),
- }
-
- def get_axislabel_transform(self, axes):
- return Affine2D() # axes.transData
-
- def get_axislabel_pos_angle(self, axes):
- def trf_xy(x, y):
- trf = self.grid_helper.grid_finder.get_transform() + axes.transData
- return trf.transform([x, y]).T
-
- xmin, xmax, ymin, ymax = self._grid_info["extremes"]
- if self.nth_coord == 0:
- xx0 = self.value
- yy0 = (ymin + ymax) / 2
- elif self.nth_coord == 1:
- xx0 = (xmin + xmax) / 2
- yy0 = self.value
- xy1, dxy1_dx, dxy1_dy = _value_and_jacobian(
- trf_xy, xx0, yy0, (xmin, xmax), (ymin, ymax))
- p = axes.transAxes.inverted().transform(xy1)
- if 0 <= p[0] <= 1 and 0 <= p[1] <= 1:
- d = [dxy1_dy, dxy1_dx][self.nth_coord]
- return xy1, np.rad2deg(np.arctan2(*d[::-1]))
- else:
- return None, None
-
- def get_tick_transform(self, axes):
- return IdentityTransform() # axes.transData
-
- def get_tick_iterators(self, axes):
- """tick_loc, tick_angle, tick_label, (optionally) tick_label"""
-
- lat_levs, lat_n, lat_factor = self._grid_info["lat_info"]
- yy0 = lat_levs / lat_factor
-
- lon_levs, lon_n, lon_factor = self._grid_info["lon_info"]
- xx0 = lon_levs / lon_factor
-
- e0, e1 = self._extremes
-
- def trf_xy(x, y):
- trf = self.grid_helper.grid_finder.get_transform() + axes.transData
- return trf.transform(np.column_stack(np.broadcast_arrays(x, y))).T
-
- # find angles
- if self.nth_coord == 0:
- mask = (e0 <= yy0) & (yy0 <= e1)
- (xx1, yy1), (dxx1, dyy1), (dxx2, dyy2) = _value_and_jacobian(
- trf_xy, self.value, yy0[mask], (-np.inf, np.inf), (e0, e1))
- labels = self._grid_info["lat_labels"]
-
- elif self.nth_coord == 1:
- mask = (e0 <= xx0) & (xx0 <= e1)
- (xx1, yy1), (dxx2, dyy2), (dxx1, dyy1) = _value_and_jacobian(
- trf_xy, xx0[mask], self.value, (-np.inf, np.inf), (e0, e1))
- labels = self._grid_info["lon_labels"]
-
- labels = [l for l, m in zip(labels, mask) if m]
-
- angle_normal = np.arctan2(dyy1, dxx1)
- angle_tangent = np.arctan2(dyy2, dxx2)
- mm = (dyy1 == 0) & (dxx1 == 0) # points with degenerate normal
- angle_normal[mm] = angle_tangent[mm] + np.pi / 2
-
- tick_to_axes = self.get_tick_transform(axes) - axes.transAxes
- in_01 = functools.partial(
- mpl.transforms._interval_contains_close, (0, 1))
-
- def f1():
- for x, y, normal, tangent, lab \
- in zip(xx1, yy1, angle_normal, angle_tangent, labels):
- c2 = tick_to_axes.transform((x, y))
- if in_01(c2[0]) and in_01(c2[1]):
- yield [x, y], *np.rad2deg([normal, tangent]), lab
-
- return f1(), iter([])
-
- def get_line_transform(self, axes):
- return axes.transData
-
- def get_line(self, axes):
- self.update_lim(axes)
- x, y = self._grid_info["line_xy"]
- return Path(np.column_stack([x, y]))
-
-
-class GridHelperCurveLinear(GridHelperBase):
- def __init__(self, aux_trans,
- extreme_finder=None,
- grid_locator1=None,
- grid_locator2=None,
- tick_formatter1=None,
- tick_formatter2=None):
- """
- Parameters
- ----------
- aux_trans : `.Transform` or tuple[Callable, Callable]
- The transform from curved coordinates to rectilinear coordinate:
- either a `.Transform` instance (which provides also its inverse),
- or a pair of callables ``(trans, inv_trans)`` that define the
- transform and its inverse. The callables should have signature::
-
- x_rect, y_rect = trans(x_curved, y_curved)
- x_curved, y_curved = inv_trans(x_rect, y_rect)
-
- extreme_finder
-
- grid_locator1, grid_locator2
- Grid locators for each axis.
-
- tick_formatter1, tick_formatter2
- Tick formatters for each axis.
- """
- super().__init__()
- self._grid_info = None
- self.grid_finder = GridFinder(aux_trans,
- extreme_finder,
- grid_locator1,
- grid_locator2,
- tick_formatter1,
- tick_formatter2)
-
- def update_grid_finder(self, aux_trans=None, **kwargs):
- if aux_trans is not None:
- self.grid_finder.update_transform(aux_trans)
- self.grid_finder.update(**kwargs)
- self._old_limits = None # Force revalidation.
-
- def new_fixed_axis(self, loc,
- nth_coord=None,
- axis_direction=None,
- offset=None,
- axes=None):
- if axes is None:
- axes = self.axes
- if axis_direction is None:
- axis_direction = loc
- helper = FixedAxisArtistHelper(self, loc, nth_coord_ticks=nth_coord)
- axisline = AxisArtist(axes, helper, axis_direction=axis_direction)
- # Why is clip not set on axisline, unlike in new_floating_axis or in
- # the floating_axig.GridHelperCurveLinear subclass?
- return axisline
-
- def new_floating_axis(self, nth_coord,
- value,
- axes=None,
- axis_direction="bottom"
- ):
- if axes is None:
- axes = self.axes
- helper = FloatingAxisArtistHelper(
- self, nth_coord, value, axis_direction)
- axisline = AxisArtist(axes, helper)
- axisline.line.set_clip_on(True)
- axisline.line.set_clip_box(axisline.axes.bbox)
- # axisline.major_ticklabels.set_visible(True)
- # axisline.minor_ticklabels.set_visible(False)
- return axisline
-
- def _update_grid(self, x1, y1, x2, y2):
- self._grid_info = self.grid_finder.get_grid_info(x1, y1, x2, y2)
-
- def get_gridlines(self, which="major", axis="both"):
- grid_lines = []
- if axis in ["both", "x"]:
- for gl in self._grid_info["lon"]["lines"]:
- grid_lines.extend(gl)
- if axis in ["both", "y"]:
- for gl in self._grid_info["lat"]["lines"]:
- grid_lines.extend(gl)
- return grid_lines
-
- def get_tick_iterator(self, nth_coord, axis_side, minor=False):
-
- # axisnr = dict(left=0, bottom=1, right=2, top=3)[axis_side]
- angle_tangent = dict(left=90, right=90, bottom=0, top=0)[axis_side]
- # angle = [0, 90, 180, 270][axisnr]
- lon_or_lat = ["lon", "lat"][nth_coord]
- if not minor: # major ticks
- for (xy, a), l in zip(
- self._grid_info[lon_or_lat]["tick_locs"][axis_side],
- self._grid_info[lon_or_lat]["tick_labels"][axis_side]):
- angle_normal = a
- yield xy, angle_normal, angle_tangent, l
- else:
- for (xy, a), l in zip(
- self._grid_info[lon_or_lat]["tick_locs"][axis_side],
- self._grid_info[lon_or_lat]["tick_labels"][axis_side]):
- angle_normal = a
- yield xy, angle_normal, angle_tangent, ""
- # for xy, a, l in self._grid_info[lon_or_lat]["ticks"][axis_side]:
- # yield xy, a, ""
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/parasite_axes.py b/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/parasite_axes.py
deleted file mode 100644
index 4ebd6acc03..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/axisartist/parasite_axes.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from mpl_toolkits.axes_grid1.parasite_axes import (
- host_axes_class_factory, parasite_axes_class_factory)
-from .axislines import Axes
-
-
-ParasiteAxes = parasite_axes_class_factory(Axes)
-HostAxes = SubplotHost = host_axes_class_factory(Axes)
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/__init__.py b/contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/__init__.py
deleted file mode 100644
index a089fbd6b7..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from .axes3d import Axes3D
-
-__all__ = ['Axes3D']
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/art3d.py b/contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/art3d.py
deleted file mode 100644
index 4aff115b0c..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/art3d.py
+++ /dev/null
@@ -1,1252 +0,0 @@
-# art3d.py, original mplot3d version by John Porter
-# Parts rewritten by Reinier Heeres <reinier@heeres.eu>
-# Minor additions by Ben Axelrod <baxelrod@coroware.com>
-
-"""
-Module containing 3D artist code and functions to convert 2D
-artists into 3D versions which can be added to an Axes3D.
-"""
-
-import math
-
-import numpy as np
-
-from contextlib import contextmanager
-
-from matplotlib import (
- artist, cbook, colors as mcolors, lines, text as mtext,
- path as mpath)
-from matplotlib.collections import (
- Collection, LineCollection, PolyCollection, PatchCollection, PathCollection)
-from matplotlib.colors import Normalize
-from matplotlib.patches import Patch
-from . import proj3d
-
-
-def _norm_angle(a):
- """Return the given angle normalized to -180 < *a* <= 180 degrees."""
- a = (a + 360) % 360
- if a > 180:
- a = a - 360
- return a
-
-
-def _norm_text_angle(a):
- """Return the given angle normalized to -90 < *a* <= 90 degrees."""
- a = (a + 180) % 180
- if a > 90:
- a = a - 180
- return a
-
-
-def get_dir_vector(zdir):
- """
- Return a direction vector.
-
- Parameters
- ----------
- zdir : {'x', 'y', 'z', None, 3-tuple}
- The direction. Possible values are:
-
- - 'x': equivalent to (1, 0, 0)
- - 'y': equivalent to (0, 1, 0)
- - 'z': equivalent to (0, 0, 1)
- - *None*: equivalent to (0, 0, 0)
- - an iterable (x, y, z) is converted to an array
-
- Returns
- -------
- x, y, z : array
- The direction vector.
- """
- if zdir == 'x':
- return np.array((1, 0, 0))
- elif zdir == 'y':
- return np.array((0, 1, 0))
- elif zdir == 'z':
- return np.array((0, 0, 1))
- elif zdir is None:
- return np.array((0, 0, 0))
- elif np.iterable(zdir) and len(zdir) == 3:
- return np.array(zdir)
- else:
- raise ValueError("'x', 'y', 'z', None or vector of length 3 expected")
-
-
-class Text3D(mtext.Text):
- """
- Text object with 3D position and direction.
-
- Parameters
- ----------
- x, y, z : float
- The position of the text.
- text : str
- The text string to display.
- zdir : {'x', 'y', 'z', None, 3-tuple}
- The direction of the text. See `.get_dir_vector` for a description of
- the values.
-
- Other Parameters
- ----------------
- **kwargs
- All other parameters are passed on to `~matplotlib.text.Text`.
- """
-
- def __init__(self, x=0, y=0, z=0, text='', zdir='z', **kwargs):
- mtext.Text.__init__(self, x, y, text, **kwargs)
- self.set_3d_properties(z, zdir)
-
- def get_position_3d(self):
- """Return the (x, y, z) position of the text."""
- return self._x, self._y, self._z
-
- def set_position_3d(self, xyz, zdir=None):
- """
- Set the (*x*, *y*, *z*) position of the text.
-
- Parameters
- ----------
- xyz : (float, float, float)
- The position in 3D space.
- zdir : {'x', 'y', 'z', None, 3-tuple}
- The direction of the text. If unspecified, the *zdir* will not be
- changed. See `.get_dir_vector` for a description of the values.
- """
- super().set_position(xyz[:2])
- self.set_z(xyz[2])
- if zdir is not None:
- self._dir_vec = get_dir_vector(zdir)
-
- def set_z(self, z):
- """
- Set the *z* position of the text.
-
- Parameters
- ----------
- z : float
- """
- self._z = z
- self.stale = True
-
- def set_3d_properties(self, z=0, zdir='z'):
- """
- Set the *z* position and direction of the text.
-
- Parameters
- ----------
- z : float
- The z-position in 3D space.
- zdir : {'x', 'y', 'z', 3-tuple}
- The direction of the text. Default: 'z'.
- See `.get_dir_vector` for a description of the values.
- """
- self._z = z
- self._dir_vec = get_dir_vector(zdir)
- self.stale = True
-
- @artist.allow_rasterization
- def draw(self, renderer):
- position3d = np.array((self._x, self._y, self._z))
- proj = proj3d._proj_trans_points(
- [position3d, position3d + self._dir_vec], self.axes.M)
- dx = proj[0][1] - proj[0][0]
- dy = proj[1][1] - proj[1][0]
- angle = math.degrees(math.atan2(dy, dx))
- with cbook._setattr_cm(self, _x=proj[0][0], _y=proj[1][0],
- _rotation=_norm_text_angle(angle)):
- mtext.Text.draw(self, renderer)
- self.stale = False
-
- def get_tightbbox(self, renderer=None):
- # Overwriting the 2d Text behavior which is not valid for 3d.
- # For now, just return None to exclude from layout calculation.
- return None
-
-
-def text_2d_to_3d(obj, z=0, zdir='z'):
- """
- Convert a `.Text` to a `.Text3D` object.
-
- Parameters
- ----------
- z : float
- The z-position in 3D space.
- zdir : {'x', 'y', 'z', 3-tuple}
- The direction of the text. Default: 'z'.
- See `.get_dir_vector` for a description of the values.
- """
- obj.__class__ = Text3D
- obj.set_3d_properties(z, zdir)
-
-
-class Line3D(lines.Line2D):
- """
- 3D line object.
-
- .. note:: Use `get_data_3d` to obtain the data associated with the line.
- `~.Line2D.get_data`, `~.Line2D.get_xdata`, and `~.Line2D.get_ydata` return
- the x- and y-coordinates of the projected 2D-line, not the x- and y-data of
- the 3D-line. Similarly, use `set_data_3d` to set the data, not
- `~.Line2D.set_data`, `~.Line2D.set_xdata`, and `~.Line2D.set_ydata`.
- """
-
- def __init__(self, xs, ys, zs, *args, **kwargs):
- """
-
- Parameters
- ----------
- xs : array-like
- The x-data to be plotted.
- ys : array-like
- The y-data to be plotted.
- zs : array-like
- The z-data to be plotted.
- *args, **kwargs
- Additional arguments are passed to `~matplotlib.lines.Line2D`.
- """
- super().__init__([], [], *args, **kwargs)
- self.set_data_3d(xs, ys, zs)
-
- def set_3d_properties(self, zs=0, zdir='z'):
- """
- Set the *z* position and direction of the line.
-
- Parameters
- ----------
- zs : float or array of floats
- The location along the *zdir* axis in 3D space to position the
- line.
- zdir : {'x', 'y', 'z'}
- Plane to plot line orthogonal to. Default: 'z'.
- See `.get_dir_vector` for a description of the values.
- """
- xs = self.get_xdata()
- ys = self.get_ydata()
- zs = cbook._to_unmasked_float_array(zs).ravel()
- zs = np.broadcast_to(zs, len(xs))
- self._verts3d = juggle_axes(xs, ys, zs, zdir)
- self.stale = True
-
- def set_data_3d(self, *args):
- """
- Set the x, y and z data
-
- Parameters
- ----------
- x : array-like
- The x-data to be plotted.
- y : array-like
- The y-data to be plotted.
- z : array-like
- The z-data to be plotted.
-
- Notes
- -----
- Accepts x, y, z arguments or a single array-like (x, y, z)
- """
- if len(args) == 1:
- args = args[0]
- for name, xyz in zip('xyz', args):
- if not np.iterable(xyz):
- raise RuntimeError(f'{name} must be a sequence')
- self._verts3d = args
- self.stale = True
-
- def get_data_3d(self):
- """
- Get the current data
-
- Returns
- -------
- verts3d : length-3 tuple or array-like
- The current data as a tuple or array-like.
- """
- return self._verts3d
-
- @artist.allow_rasterization
- def draw(self, renderer):
- xs3d, ys3d, zs3d = self._verts3d
- xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, self.axes.M)
- self.set_data(xs, ys)
- super().draw(renderer)
- self.stale = False
-
-
-def line_2d_to_3d(line, zs=0, zdir='z'):
- """
- Convert a `.Line2D` to a `.Line3D` object.
-
- Parameters
- ----------
- zs : float
- The location along the *zdir* axis in 3D space to position the line.
- zdir : {'x', 'y', 'z'}
- Plane to plot line orthogonal to. Default: 'z'.
- See `.get_dir_vector` for a description of the values.
- """
-
- line.__class__ = Line3D
- line.set_3d_properties(zs, zdir)
-
-
-def _path_to_3d_segment(path, zs=0, zdir='z'):
- """Convert a path to a 3D segment."""
-
- zs = np.broadcast_to(zs, len(path))
- pathsegs = path.iter_segments(simplify=False, curves=False)
- seg = [(x, y, z) for (((x, y), code), z) in zip(pathsegs, zs)]
- seg3d = [juggle_axes(x, y, z, zdir) for (x, y, z) in seg]
- return seg3d
-
-
-def _paths_to_3d_segments(paths, zs=0, zdir='z'):
- """Convert paths from a collection object to 3D segments."""
-
- if not np.iterable(zs):
- zs = np.broadcast_to(zs, len(paths))
- else:
- if len(zs) != len(paths):
- raise ValueError('Number of z-coordinates does not match paths.')
-
- segs = [_path_to_3d_segment(path, pathz, zdir)
- for path, pathz in zip(paths, zs)]
- return segs
-
-
-def _path_to_3d_segment_with_codes(path, zs=0, zdir='z'):
- """Convert a path to a 3D segment with path codes."""
-
- zs = np.broadcast_to(zs, len(path))
- pathsegs = path.iter_segments(simplify=False, curves=False)
- seg_codes = [((x, y, z), code) for ((x, y), code), z in zip(pathsegs, zs)]
- if seg_codes:
- seg, codes = zip(*seg_codes)
- seg3d = [juggle_axes(x, y, z, zdir) for (x, y, z) in seg]
- else:
- seg3d = []
- codes = []
- return seg3d, list(codes)
-
-
-def _paths_to_3d_segments_with_codes(paths, zs=0, zdir='z'):
- """
- Convert paths from a collection object to 3D segments with path codes.
- """
-
- zs = np.broadcast_to(zs, len(paths))
- segments_codes = [_path_to_3d_segment_with_codes(path, pathz, zdir)
- for path, pathz in zip(paths, zs)]
- if segments_codes:
- segments, codes = zip(*segments_codes)
- else:
- segments, codes = [], []
- return list(segments), list(codes)
-
-
-class Collection3D(Collection):
- """A collection of 3D paths."""
-
- def do_3d_projection(self):
- """Project the points according to renderer matrix."""
- xyzs_list = [proj3d.proj_transform(*vs.T, self.axes.M)
- for vs, _ in self._3dverts_codes]
- self._paths = [mpath.Path(np.column_stack([xs, ys]), cs)
- for (xs, ys, _), (_, cs) in zip(xyzs_list, self._3dverts_codes)]
- zs = np.concatenate([zs for _, _, zs in xyzs_list])
- return zs.min() if len(zs) else 1e9
-
-
-def collection_2d_to_3d(col, zs=0, zdir='z'):
- """Convert a `.Collection` to a `.Collection3D` object."""
- zs = np.broadcast_to(zs, len(col.get_paths()))
- col._3dverts_codes = [
- (np.column_stack(juggle_axes(
- *np.column_stack([p.vertices, np.broadcast_to(z, len(p.vertices))]).T,
- zdir)),
- p.codes)
- for p, z in zip(col.get_paths(), zs)]
- col.__class__ = cbook._make_class_factory(Collection3D, "{}3D")(type(col))
-
-
-class Line3DCollection(LineCollection):
- """
- A collection of 3D lines.
- """
-
- def set_sort_zpos(self, val):
- """Set the position to use for z-sorting."""
- self._sort_zpos = val
- self.stale = True
-
- def set_segments(self, segments):
- """
- Set 3D segments.
- """
- self._segments3d = segments
- super().set_segments([])
-
- def do_3d_projection(self):
- """
- Project the points according to renderer matrix.
- """
- xyslist = [proj3d._proj_trans_points(points, self.axes.M)
- for points in self._segments3d]
- segments_2d = [np.column_stack([xs, ys]) for xs, ys, zs in xyslist]
- LineCollection.set_segments(self, segments_2d)
-
- # FIXME
- minz = 1e9
- for xs, ys, zs in xyslist:
- minz = min(minz, min(zs))
- return minz
-
-
-def line_collection_2d_to_3d(col, zs=0, zdir='z'):
- """Convert a `.LineCollection` to a `.Line3DCollection` object."""
- segments3d = _paths_to_3d_segments(col.get_paths(), zs, zdir)
- col.__class__ = Line3DCollection
- col.set_segments(segments3d)
-
-
-class Patch3D(Patch):
- """
- 3D patch object.
- """
-
- def __init__(self, *args, zs=(), zdir='z', **kwargs):
- """
- Parameters
- ----------
- verts :
- zs : float
- The location along the *zdir* axis in 3D space to position the
- patch.
- zdir : {'x', 'y', 'z'}
- Plane to plot patch orthogonal to. Default: 'z'.
- See `.get_dir_vector` for a description of the values.
- """
- super().__init__(*args, **kwargs)
- self.set_3d_properties(zs, zdir)
-
- def set_3d_properties(self, verts, zs=0, zdir='z'):
- """
- Set the *z* position and direction of the patch.
-
- Parameters
- ----------
- verts :
- zs : float
- The location along the *zdir* axis in 3D space to position the
- patch.
- zdir : {'x', 'y', 'z'}
- Plane to plot patch orthogonal to. Default: 'z'.
- See `.get_dir_vector` for a description of the values.
- """
- zs = np.broadcast_to(zs, len(verts))
- self._segment3d = [juggle_axes(x, y, z, zdir)
- for ((x, y), z) in zip(verts, zs)]
-
- def get_path(self):
- return self._path2d
-
- def do_3d_projection(self):
- s = self._segment3d
- xs, ys, zs = zip(*s)
- vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs,
- self.axes.M)
- self._path2d = mpath.Path(np.column_stack([vxs, vys]))
- return min(vzs)
-
-
-class PathPatch3D(Patch3D):
- """
- 3D PathPatch object.
- """
-
- def __init__(self, path, *, zs=(), zdir='z', **kwargs):
- """
- Parameters
- ----------
- path :
- zs : float
- The location along the *zdir* axis in 3D space to position the
- path patch.
- zdir : {'x', 'y', 'z', 3-tuple}
- Plane to plot path patch orthogonal to. Default: 'z'.
- See `.get_dir_vector` for a description of the values.
- """
- # Not super().__init__!
- Patch.__init__(self, **kwargs)
- self.set_3d_properties(path, zs, zdir)
-
- def set_3d_properties(self, path, zs=0, zdir='z'):
- """
- Set the *z* position and direction of the path patch.
-
- Parameters
- ----------
- path :
- zs : float
- The location along the *zdir* axis in 3D space to position the
- path patch.
- zdir : {'x', 'y', 'z', 3-tuple}
- Plane to plot path patch orthogonal to. Default: 'z'.
- See `.get_dir_vector` for a description of the values.
- """
- Patch3D.set_3d_properties(self, path.vertices, zs=zs, zdir=zdir)
- self._code3d = path.codes
-
- def do_3d_projection(self):
- s = self._segment3d
- xs, ys, zs = zip(*s)
- vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs,
- self.axes.M)
- self._path2d = mpath.Path(np.column_stack([vxs, vys]), self._code3d)
- return min(vzs)
-
-
-def _get_patch_verts(patch):
- """Return a list of vertices for the path of a patch."""
- trans = patch.get_patch_transform()
- path = patch.get_path()
- polygons = path.to_polygons(trans)
- return polygons[0] if len(polygons) else np.array([])
-
-
-def patch_2d_to_3d(patch, z=0, zdir='z'):
- """Convert a `.Patch` to a `.Patch3D` object."""
- verts = _get_patch_verts(patch)
- patch.__class__ = Patch3D
- patch.set_3d_properties(verts, z, zdir)
-
-
-def pathpatch_2d_to_3d(pathpatch, z=0, zdir='z'):
- """Convert a `.PathPatch` to a `.PathPatch3D` object."""
- path = pathpatch.get_path()
- trans = pathpatch.get_patch_transform()
-
- mpath = trans.transform_path(path)
- pathpatch.__class__ = PathPatch3D
- pathpatch.set_3d_properties(mpath, z, zdir)
-
-
-class Patch3DCollection(PatchCollection):
- """
- A collection of 3D patches.
- """
-
- def __init__(self, *args, zs=0, zdir='z', depthshade=True, **kwargs):
- """
- Create a collection of flat 3D patches with its normal vector
- pointed in *zdir* direction, and located at *zs* on the *zdir*
- axis. 'zs' can be a scalar or an array-like of the same length as
- the number of patches in the collection.
-
- Constructor arguments are the same as for
- :class:`~matplotlib.collections.PatchCollection`. In addition,
- keywords *zs=0* and *zdir='z'* are available.
-
- Also, the keyword argument *depthshade* is available to indicate
- whether to shade the patches in order to give the appearance of depth
- (default is *True*). This is typically desired in scatter plots.
- """
- self._depthshade = depthshade
- super().__init__(*args, **kwargs)
- self.set_3d_properties(zs, zdir)
-
- def get_depthshade(self):
- return self._depthshade
-
- def set_depthshade(self, depthshade):
- """
- Set whether depth shading is performed on collection members.
-
- Parameters
- ----------
- depthshade : bool
- Whether to shade the patches in order to give the appearance of
- depth.
- """
- self._depthshade = depthshade
- self.stale = True
-
- def set_sort_zpos(self, val):
- """Set the position to use for z-sorting."""
- self._sort_zpos = val
- self.stale = True
-
- def set_3d_properties(self, zs, zdir):
- """
- Set the *z* positions and direction of the patches.
-
- Parameters
- ----------
- zs : float or array of floats
- The location or locations to place the patches in the collection
- along the *zdir* axis.
- zdir : {'x', 'y', 'z'}
- Plane to plot patches orthogonal to.
- All patches must have the same direction.
- See `.get_dir_vector` for a description of the values.
- """
- # Force the collection to initialize the face and edgecolors
- # just in case it is a scalarmappable with a colormap.
- self.update_scalarmappable()
- offsets = self.get_offsets()
- if len(offsets) > 0:
- xs, ys = offsets.T
- else:
- xs = []
- ys = []
- self._offsets3d = juggle_axes(xs, ys, np.atleast_1d(zs), zdir)
- self._z_markers_idx = slice(-1)
- self._vzs = None
- self.stale = True
-
- def do_3d_projection(self):
- xs, ys, zs = self._offsets3d
- vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs,
- self.axes.M)
- self._vzs = vzs
- super().set_offsets(np.column_stack([vxs, vys]))
-
- if vzs.size > 0:
- return min(vzs)
- else:
- return np.nan
-
- def _maybe_depth_shade_and_sort_colors(self, color_array):
- color_array = (
- _zalpha(color_array, self._vzs)
- if self._vzs is not None and self._depthshade
- else color_array
- )
- if len(color_array) > 1:
- color_array = color_array[self._z_markers_idx]
- return mcolors.to_rgba_array(color_array, self._alpha)
-
- def get_facecolor(self):
- return self._maybe_depth_shade_and_sort_colors(super().get_facecolor())
-
- def get_edgecolor(self):
- # We need this check here to make sure we do not double-apply the depth
- # based alpha shading when the edge color is "face" which means the
- # edge colour should be identical to the face colour.
- if cbook._str_equal(self._edgecolors, 'face'):
- return self.get_facecolor()
- return self._maybe_depth_shade_and_sort_colors(super().get_edgecolor())
-
-
-class Path3DCollection(PathCollection):
- """
- A collection of 3D paths.
- """
-
- def __init__(self, *args, zs=0, zdir='z', depthshade=True, **kwargs):
- """
- Create a collection of flat 3D paths with its normal vector
- pointed in *zdir* direction, and located at *zs* on the *zdir*
- axis. 'zs' can be a scalar or an array-like of the same length as
- the number of paths in the collection.
-
- Constructor arguments are the same as for
- :class:`~matplotlib.collections.PathCollection`. In addition,
- keywords *zs=0* and *zdir='z'* are available.
-
- Also, the keyword argument *depthshade* is available to indicate
- whether to shade the patches in order to give the appearance of depth
- (default is *True*). This is typically desired in scatter plots.
- """
- self._depthshade = depthshade
- self._in_draw = False
- super().__init__(*args, **kwargs)
- self.set_3d_properties(zs, zdir)
- self._offset_zordered = None
-
- def draw(self, renderer):
- with self._use_zordered_offset():
- with cbook._setattr_cm(self, _in_draw=True):
- super().draw(renderer)
-
- def set_sort_zpos(self, val):
- """Set the position to use for z-sorting."""
- self._sort_zpos = val
- self.stale = True
-
- def set_3d_properties(self, zs, zdir):
- """
- Set the *z* positions and direction of the paths.
-
- Parameters
- ----------
- zs : float or array of floats
- The location or locations to place the paths in the collection
- along the *zdir* axis.
- zdir : {'x', 'y', 'z'}
- Plane to plot paths orthogonal to.
- All paths must have the same direction.
- See `.get_dir_vector` for a description of the values.
- """
- # Force the collection to initialize the face and edgecolors
- # just in case it is a scalarmappable with a colormap.
- self.update_scalarmappable()
- offsets = self.get_offsets()
- if len(offsets) > 0:
- xs, ys = offsets.T
- else:
- xs = []
- ys = []
- self._offsets3d = juggle_axes(xs, ys, np.atleast_1d(zs), zdir)
- # In the base draw methods we access the attributes directly which
- # means we cannot resolve the shuffling in the getter methods like
- # we do for the edge and face colors.
- #
- # This means we need to carry around a cache of the unsorted sizes and
- # widths (postfixed with 3d) and in `do_3d_projection` set the
- # depth-sorted version of that data into the private state used by the
- # base collection class in its draw method.
- #
- # Grab the current sizes and linewidths to preserve them.
- self._sizes3d = self._sizes
- self._linewidths3d = np.array(self._linewidths)
- xs, ys, zs = self._offsets3d
-
- # Sort the points based on z coordinates
- # Performance optimization: Create a sorted index array and reorder
- # points and point properties according to the index array
- self._z_markers_idx = slice(-1)
- self._vzs = None
- self.stale = True
-
- def set_sizes(self, sizes, dpi=72.0):
- super().set_sizes(sizes, dpi)
- if not self._in_draw:
- self._sizes3d = sizes
-
- def set_linewidth(self, lw):
- super().set_linewidth(lw)
- if not self._in_draw:
- self._linewidths3d = np.array(self._linewidths)
-
- def get_depthshade(self):
- return self._depthshade
-
- def set_depthshade(self, depthshade):
- """
- Set whether depth shading is performed on collection members.
-
- Parameters
- ----------
- depthshade : bool
- Whether to shade the patches in order to give the appearance of
- depth.
- """
- self._depthshade = depthshade
- self.stale = True
-
- def do_3d_projection(self):
- xs, ys, zs = self._offsets3d
- vxs, vys, vzs, vis = proj3d.proj_transform_clip(xs, ys, zs,
- self.axes.M)
- # Sort the points based on z coordinates
- # Performance optimization: Create a sorted index array and reorder
- # points and point properties according to the index array
- z_markers_idx = self._z_markers_idx = np.argsort(vzs)[::-1]
- self._vzs = vzs
-
- # we have to special case the sizes because of code in collections.py
- # as the draw method does
- # self.set_sizes(self._sizes, self.figure.dpi)
- # so we cannot rely on doing the sorting on the way out via get_*
-
- if len(self._sizes3d) > 1:
- self._sizes = self._sizes3d[z_markers_idx]
-
- if len(self._linewidths3d) > 1:
- self._linewidths = self._linewidths3d[z_markers_idx]
-
- PathCollection.set_offsets(self, np.column_stack((vxs, vys)))
-
- # Re-order items
- vzs = vzs[z_markers_idx]
- vxs = vxs[z_markers_idx]
- vys = vys[z_markers_idx]
-
- # Store ordered offset for drawing purpose
- self._offset_zordered = np.column_stack((vxs, vys))
-
- return np.min(vzs) if vzs.size else np.nan
-
- @contextmanager
- def _use_zordered_offset(self):
- if self._offset_zordered is None:
- # Do nothing
- yield
- else:
- # Swap offset with z-ordered offset
- old_offset = self._offsets
- super().set_offsets(self._offset_zordered)
- try:
- yield
- finally:
- self._offsets = old_offset
-
- def _maybe_depth_shade_and_sort_colors(self, color_array):
- color_array = (
- _zalpha(color_array, self._vzs)
- if self._vzs is not None and self._depthshade
- else color_array
- )
- if len(color_array) > 1:
- color_array = color_array[self._z_markers_idx]
- return mcolors.to_rgba_array(color_array, self._alpha)
-
- def get_facecolor(self):
- return self._maybe_depth_shade_and_sort_colors(super().get_facecolor())
-
- def get_edgecolor(self):
- # We need this check here to make sure we do not double-apply the depth
- # based alpha shading when the edge color is "face" which means the
- # edge colour should be identical to the face colour.
- if cbook._str_equal(self._edgecolors, 'face'):
- return self.get_facecolor()
- return self._maybe_depth_shade_and_sort_colors(super().get_edgecolor())
-
-
-def patch_collection_2d_to_3d(col, zs=0, zdir='z', depthshade=True):
- """
- Convert a `.PatchCollection` into a `.Patch3DCollection` object
- (or a `.PathCollection` into a `.Path3DCollection` object).
-
- Parameters
- ----------
- zs : float or array of floats
- The location or locations to place the patches in the collection along
- the *zdir* axis. Default: 0.
- zdir : {'x', 'y', 'z'}
- The axis in which to place the patches. Default: "z".
- See `.get_dir_vector` for a description of the values.
- depthshade
- Whether to shade the patches to give a sense of depth. Default: *True*.
-
- """
- if isinstance(col, PathCollection):
- col.__class__ = Path3DCollection
- col._offset_zordered = None
- elif isinstance(col, PatchCollection):
- col.__class__ = Patch3DCollection
- col._depthshade = depthshade
- col._in_draw = False
- col.set_3d_properties(zs, zdir)
-
-
-class Poly3DCollection(PolyCollection):
- """
- A collection of 3D polygons.
-
- .. note::
- **Filling of 3D polygons**
-
- There is no simple definition of the enclosed surface of a 3D polygon
- unless the polygon is planar.
-
- In practice, Matplotlib fills the 2D projection of the polygon. This
- gives a correct filling appearance only for planar polygons. For all
- other polygons, you'll find orientations in which the edges of the
- polygon intersect in the projection. This will lead to an incorrect
- visualization of the 3D area.
-
- If you need filled areas, it is recommended to create them via
- `~mpl_toolkits.mplot3d.axes3d.Axes3D.plot_trisurf`, which creates a
- triangulation and thus generates consistent surfaces.
- """
-
- def __init__(self, verts, *args, zsort='average', shade=False,
- lightsource=None, **kwargs):
- """
- Parameters
- ----------
- verts : list of (N, 3) array-like
- The sequence of polygons [*verts0*, *verts1*, ...] where each
- element *verts_i* defines the vertices of polygon *i* as a 2D
- array-like of shape (N, 3).
- zsort : {'average', 'min', 'max'}, default: 'average'
- The calculation method for the z-order.
- See `~.Poly3DCollection.set_zsort` for details.
- shade : bool, default: False
- Whether to shade *facecolors* and *edgecolors*. When activating
- *shade*, *facecolors* and/or *edgecolors* must be provided.
-
- .. versionadded:: 3.7
-
- lightsource : `~matplotlib.colors.LightSource`, optional
- The lightsource to use when *shade* is True.
-
- .. versionadded:: 3.7
-
- *args, **kwargs
- All other parameters are forwarded to `.PolyCollection`.
-
- Notes
- -----
- Note that this class does a bit of magic with the _facecolors
- and _edgecolors properties.
- """
- if shade:
- normals = _generate_normals(verts)
- facecolors = kwargs.get('facecolors', None)
- if facecolors is not None:
- kwargs['facecolors'] = _shade_colors(
- facecolors, normals, lightsource
- )
-
- edgecolors = kwargs.get('edgecolors', None)
- if edgecolors is not None:
- kwargs['edgecolors'] = _shade_colors(
- edgecolors, normals, lightsource
- )
- if facecolors is None and edgecolors is None:
- raise ValueError(
- "You must provide facecolors, edgecolors, or both for "
- "shade to work.")
- super().__init__(verts, *args, **kwargs)
- if isinstance(verts, np.ndarray):
- if verts.ndim != 3:
- raise ValueError('verts must be a list of (N, 3) array-like')
- else:
- if any(len(np.shape(vert)) != 2 for vert in verts):
- raise ValueError('verts must be a list of (N, 3) array-like')
- self.set_zsort(zsort)
- self._codes3d = None
-
- _zsort_functions = {
- 'average': np.average,
- 'min': np.min,
- 'max': np.max,
- }
-
- def set_zsort(self, zsort):
- """
- Set the calculation method for the z-order.
-
- Parameters
- ----------
- zsort : {'average', 'min', 'max'}
- The function applied on the z-coordinates of the vertices in the
- viewer's coordinate system, to determine the z-order.
- """
- self._zsortfunc = self._zsort_functions[zsort]
- self._sort_zpos = None
- self.stale = True
-
- def get_vector(self, segments3d):
- """Optimize points for projection."""
- if len(segments3d):
- xs, ys, zs = np.vstack(segments3d).T
- else: # vstack can't stack zero arrays.
- xs, ys, zs = [], [], []
- ones = np.ones(len(xs))
- self._vec = np.array([xs, ys, zs, ones])
-
- indices = [0, *np.cumsum([len(segment) for segment in segments3d])]
- self._segslices = [*map(slice, indices[:-1], indices[1:])]
-
- def set_verts(self, verts, closed=True):
- """
- Set 3D vertices.
-
- Parameters
- ----------
- verts : list of (N, 3) array-like
- The sequence of polygons [*verts0*, *verts1*, ...] where each
- element *verts_i* defines the vertices of polygon *i* as a 2D
- array-like of shape (N, 3).
- closed : bool, default: True
- Whether the polygon should be closed by adding a CLOSEPOLY
- connection at the end.
- """
- self.get_vector(verts)
- # 2D verts will be updated at draw time
- super().set_verts([], False)
- self._closed = closed
-
- def set_verts_and_codes(self, verts, codes):
- """Set 3D vertices with path codes."""
- # set vertices with closed=False to prevent PolyCollection from
- # setting path codes
- self.set_verts(verts, closed=False)
- # and set our own codes instead.
- self._codes3d = codes
-
- def set_3d_properties(self):
- # Force the collection to initialize the face and edgecolors
- # just in case it is a scalarmappable with a colormap.
- self.update_scalarmappable()
- self._sort_zpos = None
- self.set_zsort('average')
- self._facecolor3d = PolyCollection.get_facecolor(self)
- self._edgecolor3d = PolyCollection.get_edgecolor(self)
- self._alpha3d = PolyCollection.get_alpha(self)
- self.stale = True
-
- def set_sort_zpos(self, val):
- """Set the position to use for z-sorting."""
- self._sort_zpos = val
- self.stale = True
-
- def do_3d_projection(self):
- """
- Perform the 3D projection for this object.
- """
- if self._A is not None:
- # force update of color mapping because we re-order them
- # below. If we do not do this here, the 2D draw will call
- # this, but we will never port the color mapped values back
- # to the 3D versions.
- #
- # We hold the 3D versions in a fixed order (the order the user
- # passed in) and sort the 2D version by view depth.
- self.update_scalarmappable()
- if self._face_is_mapped:
- self._facecolor3d = self._facecolors
- if self._edge_is_mapped:
- self._edgecolor3d = self._edgecolors
- txs, tys, tzs = proj3d._proj_transform_vec(self._vec, self.axes.M)
- xyzlist = [(txs[sl], tys[sl], tzs[sl]) for sl in self._segslices]
-
- # This extra fuss is to re-order face / edge colors
- cface = self._facecolor3d
- cedge = self._edgecolor3d
- if len(cface) != len(xyzlist):
- cface = cface.repeat(len(xyzlist), axis=0)
- if len(cedge) != len(xyzlist):
- if len(cedge) == 0:
- cedge = cface
- else:
- cedge = cedge.repeat(len(xyzlist), axis=0)
-
- if xyzlist:
- # sort by depth (furthest drawn first)
- z_segments_2d = sorted(
- ((self._zsortfunc(zs), np.column_stack([xs, ys]), fc, ec, idx)
- for idx, ((xs, ys, zs), fc, ec)
- in enumerate(zip(xyzlist, cface, cedge))),
- key=lambda x: x[0], reverse=True)
-
- _, segments_2d, self._facecolors2d, self._edgecolors2d, idxs = \
- zip(*z_segments_2d)
- else:
- segments_2d = []
- self._facecolors2d = np.empty((0, 4))
- self._edgecolors2d = np.empty((0, 4))
- idxs = []
-
- if self._codes3d is not None:
- codes = [self._codes3d[idx] for idx in idxs]
- PolyCollection.set_verts_and_codes(self, segments_2d, codes)
- else:
- PolyCollection.set_verts(self, segments_2d, self._closed)
-
- if len(self._edgecolor3d) != len(cface):
- self._edgecolors2d = self._edgecolor3d
-
- # Return zorder value
- if self._sort_zpos is not None:
- zvec = np.array([[0], [0], [self._sort_zpos], [1]])
- ztrans = proj3d._proj_transform_vec(zvec, self.axes.M)
- return ztrans[2][0]
- elif tzs.size > 0:
- # FIXME: Some results still don't look quite right.
- # In particular, examine contourf3d_demo2.py
- # with az = -54 and elev = -45.
- return np.min(tzs)
- else:
- return np.nan
-
- def set_facecolor(self, colors):
- # docstring inherited
- super().set_facecolor(colors)
- self._facecolor3d = PolyCollection.get_facecolor(self)
-
- def set_edgecolor(self, colors):
- # docstring inherited
- super().set_edgecolor(colors)
- self._edgecolor3d = PolyCollection.get_edgecolor(self)
-
- def set_alpha(self, alpha):
- # docstring inherited
- artist.Artist.set_alpha(self, alpha)
- try:
- self._facecolor3d = mcolors.to_rgba_array(
- self._facecolor3d, self._alpha)
- except (AttributeError, TypeError, IndexError):
- pass
- try:
- self._edgecolors = mcolors.to_rgba_array(
- self._edgecolor3d, self._alpha)
- except (AttributeError, TypeError, IndexError):
- pass
- self.stale = True
-
- def get_facecolor(self):
- # docstring inherited
- # self._facecolors2d is not initialized until do_3d_projection
- if not hasattr(self, '_facecolors2d'):
- self.axes.M = self.axes.get_proj()
- self.do_3d_projection()
- return np.asarray(self._facecolors2d)
-
- def get_edgecolor(self):
- # docstring inherited
- # self._edgecolors2d is not initialized until do_3d_projection
- if not hasattr(self, '_edgecolors2d'):
- self.axes.M = self.axes.get_proj()
- self.do_3d_projection()
- return np.asarray(self._edgecolors2d)
-
-
-def poly_collection_2d_to_3d(col, zs=0, zdir='z'):
- """
- Convert a `.PolyCollection` into a `.Poly3DCollection` object.
-
- Parameters
- ----------
- zs : float or array of floats
- The location or locations to place the polygons in the collection along
- the *zdir* axis. Default: 0.
- zdir : {'x', 'y', 'z'}
- The axis in which to place the patches. Default: 'z'.
- See `.get_dir_vector` for a description of the values.
- """
- segments_3d, codes = _paths_to_3d_segments_with_codes(
- col.get_paths(), zs, zdir)
- col.__class__ = Poly3DCollection
- col.set_verts_and_codes(segments_3d, codes)
- col.set_3d_properties()
-
-
-def juggle_axes(xs, ys, zs, zdir):
- """
- Reorder coordinates so that 2D *xs*, *ys* can be plotted in the plane
- orthogonal to *zdir*. *zdir* is normally 'x', 'y' or 'z'. However, if
- *zdir* starts with a '-' it is interpreted as a compensation for
- `rotate_axes`.
- """
- if zdir == 'x':
- return zs, xs, ys
- elif zdir == 'y':
- return xs, zs, ys
- elif zdir[0] == '-':
- return rotate_axes(xs, ys, zs, zdir)
- else:
- return xs, ys, zs
-
-
-def rotate_axes(xs, ys, zs, zdir):
- """
- Reorder coordinates so that the axes are rotated with *zdir* along
- the original z axis. Prepending the axis with a '-' does the
- inverse transform, so *zdir* can be 'x', '-x', 'y', '-y', 'z' or '-z'.
- """
- if zdir in ('x', '-y'):
- return ys, zs, xs
- elif zdir in ('-x', 'y'):
- return zs, xs, ys
- else:
- return xs, ys, zs
-
-
-def _zalpha(colors, zs):
- """Modify the alphas of the color list according to depth."""
- # FIXME: This only works well if the points for *zs* are well-spaced
- # in all three dimensions. Otherwise, at certain orientations,
- # the min and max zs are very close together.
- # Should really normalize against the viewing depth.
- if len(colors) == 0 or len(zs) == 0:
- return np.zeros((0, 4))
- norm = Normalize(min(zs), max(zs))
- sats = 1 - norm(zs) * 0.7
- rgba = np.broadcast_to(mcolors.to_rgba_array(colors), (len(zs), 4))
- return np.column_stack([rgba[:, :3], rgba[:, 3] * sats])
-
-
-def _generate_normals(polygons):
- """
- Compute the normals of a list of polygons, one normal per polygon.
-
- Normals point towards the viewer for a face with its vertices in
- counterclockwise order, following the right hand rule.
-
- Uses three points equally spaced around the polygon. This method assumes
- that the points are in a plane. Otherwise, more than one shade is required,
- which is not supported.
-
- Parameters
- ----------
- polygons : list of (M_i, 3) array-like, or (..., M, 3) array-like
- A sequence of polygons to compute normals for, which can have
- varying numbers of vertices. If the polygons all have the same
- number of vertices and array is passed, then the operation will
- be vectorized.
-
- Returns
- -------
- normals : (..., 3) array
- A normal vector estimated for the polygon.
- """
- if isinstance(polygons, np.ndarray):
- # optimization: polygons all have the same number of points, so can
- # vectorize
- n = polygons.shape[-2]
- i1, i2, i3 = 0, n//3, 2*n//3
- v1 = polygons[..., i1, :] - polygons[..., i2, :]
- v2 = polygons[..., i2, :] - polygons[..., i3, :]
- else:
- # The subtraction doesn't vectorize because polygons is jagged.
- v1 = np.empty((len(polygons), 3))
- v2 = np.empty((len(polygons), 3))
- for poly_i, ps in enumerate(polygons):
- n = len(ps)
- i1, i2, i3 = 0, n//3, 2*n//3
- v1[poly_i, :] = ps[i1, :] - ps[i2, :]
- v2[poly_i, :] = ps[i2, :] - ps[i3, :]
- return np.cross(v1, v2)
-
-
-def _shade_colors(color, normals, lightsource=None):
- """
- Shade *color* using normal vectors given by *normals*,
- assuming a *lightsource* (using default position if not given).
- *color* can also be an array of the same length as *normals*.
- """
- if lightsource is None:
- # chosen for backwards-compatibility
- lightsource = mcolors.LightSource(azdeg=225, altdeg=19.4712)
-
- with np.errstate(invalid="ignore"):
- shade = ((normals / np.linalg.norm(normals, axis=1, keepdims=True))
- @ lightsource.direction)
- mask = ~np.isnan(shade)
-
- if mask.any():
- # convert dot product to allowed shading fractions
- in_norm = mcolors.Normalize(-1, 1)
- out_norm = mcolors.Normalize(0.3, 1).inverse
-
- def norm(x):
- return out_norm(in_norm(x))
-
- shade[~mask] = 0
-
- color = mcolors.to_rgba_array(color)
- # shape of color should be (M, 4) (where M is number of faces)
- # shape of shade should be (M,)
- # colors should have final shape of (M, 4)
- alpha = color[:, 3]
- colors = norm(shade)[:, np.newaxis] * color
- colors[:, 3] = alpha
- else:
- colors = np.asanyarray(color).copy()
-
- return colors
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/axes3d.py b/contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/axes3d.py
deleted file mode 100644
index a74c11f54e..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/axes3d.py
+++ /dev/null
@@ -1,3448 +0,0 @@
-"""
-axes3d.py, original mplot3d version by John Porter
-Created: 23 Sep 2005
-
-Parts fixed by Reinier Heeres <reinier@heeres.eu>
-Minor additions by Ben Axelrod <baxelrod@coroware.com>
-Significant updates and revisions by Ben Root <ben.v.root@gmail.com>
-
-Module containing Axes3D, an object which can plot 3D objects on a
-2D matplotlib figure.
-"""
-
-from collections import defaultdict
-import functools
-import itertools
-import math
-import textwrap
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import _api, cbook, _docstring, _preprocess_data
-import matplotlib.artist as martist
-import matplotlib.axes as maxes
-import matplotlib.collections as mcoll
-import matplotlib.colors as mcolors
-import matplotlib.image as mimage
-import matplotlib.lines as mlines
-import matplotlib.patches as mpatches
-import matplotlib.container as mcontainer
-import matplotlib.transforms as mtransforms
-from matplotlib.axes import Axes
-from matplotlib.axes._base import _axis_method_wrapper, _process_plot_format
-from matplotlib.transforms import Bbox
-from matplotlib.tri._triangulation import Triangulation
-
-from . import art3d
-from . import proj3d
-from . import axis3d
-
-
-@_docstring.interpd
-@_api.define_aliases({
- "xlim": ["xlim3d"], "ylim": ["ylim3d"], "zlim": ["zlim3d"]})
-class Axes3D(Axes):
- """
- 3D Axes object.
-
- .. note::
-
- As a user, you do not instantiate Axes directly, but use Axes creation
- methods instead; e.g. from `.pyplot` or `.Figure`:
- `~.pyplot.subplots`, `~.pyplot.subplot_mosaic` or `.Figure.add_axes`.
- """
- name = '3d'
-
- _axis_names = ("x", "y", "z")
- Axes._shared_axes["z"] = cbook.Grouper()
- Axes._shared_axes["view"] = cbook.Grouper()
-
- vvec = _api.deprecate_privatize_attribute("3.7")
- eye = _api.deprecate_privatize_attribute("3.7")
- sx = _api.deprecate_privatize_attribute("3.7")
- sy = _api.deprecate_privatize_attribute("3.7")
-
- def __init__(
- self, fig, rect=None, *args,
- elev=30, azim=-60, roll=0, sharez=None, proj_type='persp',
- box_aspect=None, computed_zorder=True, focal_length=None,
- shareview=None,
- **kwargs):
- """
- Parameters
- ----------
- fig : Figure
- The parent figure.
- rect : tuple (left, bottom, width, height), default: None.
- The ``(left, bottom, width, height)`` axes position.
- elev : float, default: 30
- The elevation angle in degrees rotates the camera above and below
- the x-y plane, with a positive angle corresponding to a location
- above the plane.
- azim : float, default: -60
- The azimuthal angle in degrees rotates the camera about the z axis,
- with a positive angle corresponding to a right-handed rotation. In
- other words, a positive azimuth rotates the camera about the origin
- from its location along the +x axis towards the +y axis.
- roll : float, default: 0
- The roll angle in degrees rotates the camera about the viewing
- axis. A positive angle spins the camera clockwise, causing the
- scene to rotate counter-clockwise.
- sharez : Axes3D, optional
- Other Axes to share z-limits with.
- proj_type : {'persp', 'ortho'}
- The projection type, default 'persp'.
- box_aspect : 3-tuple of floats, default: None
- Changes the physical dimensions of the Axes3D, such that the ratio
- of the axis lengths in display units is x:y:z.
- If None, defaults to 4:4:3
- computed_zorder : bool, default: True
- If True, the draw order is computed based on the average position
- of the `.Artist`\\s along the view direction.
- Set to False if you want to manually control the order in which
- Artists are drawn on top of each other using their *zorder*
- attribute. This can be used for fine-tuning if the automatic order
- does not produce the desired result. Note however, that a manual
- zorder will only be correct for a limited view angle. If the figure
- is rotated by the user, it will look wrong from certain angles.
- focal_length : float, default: None
- For a projection type of 'persp', the focal length of the virtual
- camera. Must be > 0. If None, defaults to 1.
- For a projection type of 'ortho', must be set to either None
- or infinity (numpy.inf). If None, defaults to infinity.
- The focal length can be computed from a desired Field Of View via
- the equation: focal_length = 1/tan(FOV/2)
- shareview : Axes3D, optional
- Other Axes to share view angles with.
-
- **kwargs
- Other optional keyword arguments:
-
- %(Axes3D:kwdoc)s
- """
-
- if rect is None:
- rect = [0.0, 0.0, 1.0, 1.0]
-
- self.initial_azim = azim
- self.initial_elev = elev
- self.initial_roll = roll
- self.set_proj_type(proj_type, focal_length)
- self.computed_zorder = computed_zorder
-
- self.xy_viewLim = Bbox.unit()
- self.zz_viewLim = Bbox.unit()
- self.xy_dataLim = Bbox.unit()
- # z-limits are encoded in the x-component of the Bbox, y is un-used
- self.zz_dataLim = Bbox.unit()
-
- # inhibit autoscale_view until the axes are defined
- # they can't be defined until Axes.__init__ has been called
- self.view_init(self.initial_elev, self.initial_azim, self.initial_roll)
-
- self._sharez = sharez
- if sharez is not None:
- self._shared_axes["z"].join(self, sharez)
- self._adjustable = 'datalim'
-
- self._shareview = shareview
- if shareview is not None:
- self._shared_axes["view"].join(self, shareview)
-
- if kwargs.pop('auto_add_to_figure', False):
- raise AttributeError(
- 'auto_add_to_figure is no longer supported for Axes3D. '
- 'Use fig.add_axes(ax) instead.'
- )
-
- super().__init__(
- fig, rect, frameon=True, box_aspect=box_aspect, *args, **kwargs
- )
- # Disable drawing of axes by base class
- super().set_axis_off()
- # Enable drawing of axes by Axes3D class
- self.set_axis_on()
- self.M = None
- self.invM = None
-
- # func used to format z -- fall back on major formatters
- self.fmt_zdata = None
-
- self.mouse_init()
- self.figure.canvas.callbacks._connect_picklable(
- 'motion_notify_event', self._on_move)
- self.figure.canvas.callbacks._connect_picklable(
- 'button_press_event', self._button_press)
- self.figure.canvas.callbacks._connect_picklable(
- 'button_release_event', self._button_release)
- self.set_top_view()
-
- self.patch.set_linewidth(0)
- # Calculate the pseudo-data width and height
- pseudo_bbox = self.transLimits.inverted().transform([(0, 0), (1, 1)])
- self._pseudo_w, self._pseudo_h = pseudo_bbox[1] - pseudo_bbox[0]
-
- # mplot3d currently manages its own spines and needs these turned off
- # for bounding box calculations
- self.spines[:].set_visible(False)
-
- def set_axis_off(self):
- self._axis3don = False
- self.stale = True
-
- def set_axis_on(self):
- self._axis3don = True
- self.stale = True
-
- def convert_zunits(self, z):
- """
- For artists in an Axes, if the zaxis has units support,
- convert *z* using zaxis unit type
- """
- return self.zaxis.convert_units(z)
-
- def set_top_view(self):
- # this happens to be the right view for the viewing coordinates
- # moved up and to the left slightly to fit labels and axes
- xdwl = 0.95 / self._dist
- xdw = 0.9 / self._dist
- ydwl = 0.95 / self._dist
- ydw = 0.9 / self._dist
- # Set the viewing pane.
- self.viewLim.intervalx = (-xdwl, xdw)
- self.viewLim.intervaly = (-ydwl, ydw)
- self.stale = True
-
- def _init_axis(self):
- """Init 3D axes; overrides creation of regular X/Y axes."""
- self.xaxis = axis3d.XAxis(self)
- self.yaxis = axis3d.YAxis(self)
- self.zaxis = axis3d.ZAxis(self)
-
- def get_zaxis(self):
- """Return the ``ZAxis`` (`~.axis3d.Axis`) instance."""
- return self.zaxis
-
- get_zgridlines = _axis_method_wrapper("zaxis", "get_gridlines")
- get_zticklines = _axis_method_wrapper("zaxis", "get_ticklines")
-
- @_api.deprecated("3.7")
- def unit_cube(self, vals=None):
- return self._unit_cube(vals)
-
- def _unit_cube(self, vals=None):
- minx, maxx, miny, maxy, minz, maxz = vals or self.get_w_lims()
- return [(minx, miny, minz),
- (maxx, miny, minz),
- (maxx, maxy, minz),
- (minx, maxy, minz),
- (minx, miny, maxz),
- (maxx, miny, maxz),
- (maxx, maxy, maxz),
- (minx, maxy, maxz)]
-
- @_api.deprecated("3.7")
- def tunit_cube(self, vals=None, M=None):
- return self._tunit_cube(vals, M)
-
- def _tunit_cube(self, vals=None, M=None):
- if M is None:
- M = self.M
- xyzs = self._unit_cube(vals)
- tcube = proj3d._proj_points(xyzs, M)
- return tcube
-
- @_api.deprecated("3.7")
- def tunit_edges(self, vals=None, M=None):
- return self._tunit_edges(vals, M)
-
- def _tunit_edges(self, vals=None, M=None):
- tc = self._tunit_cube(vals, M)
- edges = [(tc[0], tc[1]),
- (tc[1], tc[2]),
- (tc[2], tc[3]),
- (tc[3], tc[0]),
-
- (tc[0], tc[4]),
- (tc[1], tc[5]),
- (tc[2], tc[6]),
- (tc[3], tc[7]),
-
- (tc[4], tc[5]),
- (tc[5], tc[6]),
- (tc[6], tc[7]),
- (tc[7], tc[4])]
- return edges
-
- def set_aspect(self, aspect, adjustable=None, anchor=None, share=False):
- """
- Set the aspect ratios.
-
- Parameters
- ----------
- aspect : {'auto', 'equal', 'equalxy', 'equalxz', 'equalyz'}
- Possible values:
-
- ========= ==================================================
- value description
- ========= ==================================================
- 'auto' automatic; fill the position rectangle with data.
- 'equal' adapt all the axes to have equal aspect ratios.
- 'equalxy' adapt the x and y axes to have equal aspect ratios.
- 'equalxz' adapt the x and z axes to have equal aspect ratios.
- 'equalyz' adapt the y and z axes to have equal aspect ratios.
- ========= ==================================================
-
- adjustable : None or {'box', 'datalim'}, optional
- If not *None*, this defines which parameter will be adjusted to
- meet the required aspect. See `.set_adjustable` for further
- details.
-
- anchor : None or str or 2-tuple of float, optional
- If not *None*, this defines where the Axes will be drawn if there
- is extra space due to aspect constraints. The most common way to
- specify the anchor are abbreviations of cardinal directions:
-
- ===== =====================
- value description
- ===== =====================
- 'C' centered
- 'SW' lower left corner
- 'S' middle of bottom edge
- 'SE' lower right corner
- etc.
- ===== =====================
-
- See `~.Axes.set_anchor` for further details.
-
- share : bool, default: False
- If ``True``, apply the settings to all shared Axes.
-
- See Also
- --------
- mpl_toolkits.mplot3d.axes3d.Axes3D.set_box_aspect
- """
- _api.check_in_list(('auto', 'equal', 'equalxy', 'equalyz', 'equalxz'),
- aspect=aspect)
- super().set_aspect(
- aspect='auto', adjustable=adjustable, anchor=anchor, share=share)
- self._aspect = aspect
-
- if aspect in ('equal', 'equalxy', 'equalxz', 'equalyz'):
- ax_indices = self._equal_aspect_axis_indices(aspect)
-
- view_intervals = np.array([self.xaxis.get_view_interval(),
- self.yaxis.get_view_interval(),
- self.zaxis.get_view_interval()])
- ptp = np.ptp(view_intervals, axis=1)
- if self._adjustable == 'datalim':
- mean = np.mean(view_intervals, axis=1)
- scale = max(ptp[ax_indices] / self._box_aspect[ax_indices])
- deltas = scale * self._box_aspect
-
- for i, set_lim in enumerate((self.set_xlim3d,
- self.set_ylim3d,
- self.set_zlim3d)):
- if i in ax_indices:
- set_lim(mean[i] - deltas[i]/2., mean[i] + deltas[i]/2.)
- else: # 'box'
- # Change the box aspect such that the ratio of the length of
- # the unmodified axis to the length of the diagonal
- # perpendicular to it remains unchanged.
- box_aspect = np.array(self._box_aspect)
- box_aspect[ax_indices] = ptp[ax_indices]
- remaining_ax_indices = {0, 1, 2}.difference(ax_indices)
- if remaining_ax_indices:
- remaining = remaining_ax_indices.pop()
- old_diag = np.linalg.norm(self._box_aspect[ax_indices])
- new_diag = np.linalg.norm(box_aspect[ax_indices])
- box_aspect[remaining] *= new_diag / old_diag
- self.set_box_aspect(box_aspect)
-
- def _equal_aspect_axis_indices(self, aspect):
- """
- Get the indices for which of the x, y, z axes are constrained to have
- equal aspect ratios.
-
- Parameters
- ----------
- aspect : {'auto', 'equal', 'equalxy', 'equalxz', 'equalyz'}
- See descriptions in docstring for `.set_aspect()`.
- """
- ax_indices = [] # aspect == 'auto'
- if aspect == 'equal':
- ax_indices = [0, 1, 2]
- elif aspect == 'equalxy':
- ax_indices = [0, 1]
- elif aspect == 'equalxz':
- ax_indices = [0, 2]
- elif aspect == 'equalyz':
- ax_indices = [1, 2]
- return ax_indices
-
- def set_box_aspect(self, aspect, *, zoom=1):
- """
- Set the Axes box aspect.
-
- The box aspect is the ratio of height to width in display
- units for each face of the box when viewed perpendicular to
- that face. This is not to be confused with the data aspect (see
- `~.Axes3D.set_aspect`). The default ratios are 4:4:3 (x:y:z).
-
- To simulate having equal aspect in data space, set the box
- aspect to match your data range in each dimension.
-
- *zoom* controls the overall size of the Axes3D in the figure.
-
- Parameters
- ----------
- aspect : 3-tuple of floats or None
- Changes the physical dimensions of the Axes3D, such that the ratio
- of the axis lengths in display units is x:y:z.
- If None, defaults to (4, 4, 3).
-
- zoom : float, default: 1
- Control overall size of the Axes3D in the figure. Must be > 0.
- """
- if zoom <= 0:
- raise ValueError(f'Argument zoom = {zoom} must be > 0')
-
- if aspect is None:
- aspect = np.asarray((4, 4, 3), dtype=float)
- else:
- aspect = np.asarray(aspect, dtype=float)
- _api.check_shape((3,), aspect=aspect)
- # default scale tuned to match the mpl32 appearance.
- aspect *= 1.8294640721620434 * zoom / np.linalg.norm(aspect)
-
- self._box_aspect = aspect
- self.stale = True
-
- def apply_aspect(self, position=None):
- if position is None:
- position = self.get_position(original=True)
-
- # in the superclass, we would go through and actually deal with axis
- # scales and box/datalim. Those are all irrelevant - all we need to do
- # is make sure our coordinate system is square.
- trans = self.get_figure().transSubfigure
- bb = mtransforms.Bbox.unit().transformed(trans)
- # this is the physical aspect of the panel (or figure):
- fig_aspect = bb.height / bb.width
-
- box_aspect = 1
- pb = position.frozen()
- pb1 = pb.shrunk_to_aspect(box_aspect, pb, fig_aspect)
- self._set_position(pb1.anchored(self.get_anchor(), pb), 'active')
-
- @martist.allow_rasterization
- def draw(self, renderer):
- if not self.get_visible():
- return
- self._unstale_viewLim()
-
- # draw the background patch
- self.patch.draw(renderer)
- self._frameon = False
-
- # first, set the aspect
- # this is duplicated from `axes._base._AxesBase.draw`
- # but must be called before any of the artist are drawn as
- # it adjusts the view limits and the size of the bounding box
- # of the Axes
- locator = self.get_axes_locator()
- self.apply_aspect(locator(self, renderer) if locator else None)
-
- # add the projection matrix to the renderer
- self.M = self.get_proj()
- self.invM = np.linalg.inv(self.M)
-
- collections_and_patches = (
- artist for artist in self._children
- if isinstance(artist, (mcoll.Collection, mpatches.Patch))
- and artist.get_visible())
- if self.computed_zorder:
- # Calculate projection of collections and patches and zorder
- # them. Make sure they are drawn above the grids.
- zorder_offset = max(axis.get_zorder()
- for axis in self._axis_map.values()) + 1
- collection_zorder = patch_zorder = zorder_offset
-
- for artist in sorted(collections_and_patches,
- key=lambda artist: artist.do_3d_projection(),
- reverse=True):
- if isinstance(artist, mcoll.Collection):
- artist.zorder = collection_zorder
- collection_zorder += 1
- elif isinstance(artist, mpatches.Patch):
- artist.zorder = patch_zorder
- patch_zorder += 1
- else:
- for artist in collections_and_patches:
- artist.do_3d_projection()
-
- if self._axis3don:
- # Draw panes first
- for axis in self._axis_map.values():
- axis.draw_pane(renderer)
- # Then gridlines
- for axis in self._axis_map.values():
- axis.draw_grid(renderer)
- # Then axes, labels, text, and ticks
- for axis in self._axis_map.values():
- axis.draw(renderer)
-
- # Then rest
- super().draw(renderer)
-
- def get_axis_position(self):
- vals = self.get_w_lims()
- tc = self._tunit_cube(vals, self.M)
- xhigh = tc[1][2] > tc[2][2]
- yhigh = tc[3][2] > tc[2][2]
- zhigh = tc[0][2] > tc[2][2]
- return xhigh, yhigh, zhigh
-
- def update_datalim(self, xys, **kwargs):
- """
- Not implemented in `~mpl_toolkits.mplot3d.axes3d.Axes3D`.
- """
- pass
-
- get_autoscalez_on = _axis_method_wrapper("zaxis", "_get_autoscale_on")
- set_autoscalez_on = _axis_method_wrapper("zaxis", "_set_autoscale_on")
-
- def set_zmargin(self, m):
- """
- Set padding of Z data limits prior to autoscaling.
-
- *m* times the data interval will be added to each end of that interval
- before it is used in autoscaling. If *m* is negative, this will clip
- the data range instead of expanding it.
-
- For example, if your data is in the range [0, 2], a margin of 0.1 will
- result in a range [-0.2, 2.2]; a margin of -0.1 will result in a range
- of [0.2, 1.8].
-
- Parameters
- ----------
- m : float greater than -0.5
- """
- if m <= -0.5:
- raise ValueError("margin must be greater than -0.5")
- self._zmargin = m
- self._request_autoscale_view("z")
- self.stale = True
-
- def margins(self, *margins, x=None, y=None, z=None, tight=True):
- """
- Set or retrieve autoscaling margins.
-
- See `.Axes.margins` for full documentation. Because this function
- applies to 3D Axes, it also takes a *z* argument, and returns
- ``(xmargin, ymargin, zmargin)``.
- """
- if margins and (x is not None or y is not None or z is not None):
- raise TypeError('Cannot pass both positional and keyword '
- 'arguments for x, y, and/or z.')
- elif len(margins) == 1:
- x = y = z = margins[0]
- elif len(margins) == 3:
- x, y, z = margins
- elif margins:
- raise TypeError('Must pass a single positional argument for all '
- 'margins, or one for each margin (x, y, z).')
-
- if x is None and y is None and z is None:
- if tight is not True:
- _api.warn_external(f'ignoring tight={tight!r} in get mode')
- return self._xmargin, self._ymargin, self._zmargin
-
- if x is not None:
- self.set_xmargin(x)
- if y is not None:
- self.set_ymargin(y)
- if z is not None:
- self.set_zmargin(z)
-
- self.autoscale_view(
- tight=tight, scalex=(x is not None), scaley=(y is not None),
- scalez=(z is not None)
- )
-
- def autoscale(self, enable=True, axis='both', tight=None):
- """
- Convenience method for simple axis view autoscaling.
-
- See `.Axes.autoscale` for full documentation. Because this function
- applies to 3D Axes, *axis* can also be set to 'z', and setting *axis*
- to 'both' autoscales all three axes.
- """
- if enable is None:
- scalex = True
- scaley = True
- scalez = True
- else:
- if axis in ['x', 'both']:
- self.set_autoscalex_on(bool(enable))
- scalex = self.get_autoscalex_on()
- else:
- scalex = False
- if axis in ['y', 'both']:
- self.set_autoscaley_on(bool(enable))
- scaley = self.get_autoscaley_on()
- else:
- scaley = False
- if axis in ['z', 'both']:
- self.set_autoscalez_on(bool(enable))
- scalez = self.get_autoscalez_on()
- else:
- scalez = False
- if scalex:
- self._request_autoscale_view("x", tight=tight)
- if scaley:
- self._request_autoscale_view("y", tight=tight)
- if scalez:
- self._request_autoscale_view("z", tight=tight)
-
- def auto_scale_xyz(self, X, Y, Z=None, had_data=None):
- # This updates the bounding boxes as to keep a record as to what the
- # minimum sized rectangular volume holds the data.
- if np.shape(X) == np.shape(Y):
- self.xy_dataLim.update_from_data_xy(
- np.column_stack([np.ravel(X), np.ravel(Y)]), not had_data)
- else:
- self.xy_dataLim.update_from_data_x(X, not had_data)
- self.xy_dataLim.update_from_data_y(Y, not had_data)
- if Z is not None:
- self.zz_dataLim.update_from_data_x(Z, not had_data)
- # Let autoscale_view figure out how to use this data.
- self.autoscale_view()
-
- def autoscale_view(self, tight=None, scalex=True, scaley=True,
- scalez=True):
- """
- Autoscale the view limits using the data limits.
-
- See `.Axes.autoscale_view` for full documentation. Because this
- function applies to 3D Axes, it also takes a *scalez* argument.
- """
- # This method looks at the rectangular volume (see above)
- # of data and decides how to scale the view portal to fit it.
- if tight is None:
- _tight = self._tight
- if not _tight:
- # if image data only just use the datalim
- for artist in self._children:
- if isinstance(artist, mimage.AxesImage):
- _tight = True
- elif isinstance(artist, (mlines.Line2D, mpatches.Patch)):
- _tight = False
- break
- else:
- _tight = self._tight = bool(tight)
-
- if scalex and self.get_autoscalex_on():
- x0, x1 = self.xy_dataLim.intervalx
- xlocator = self.xaxis.get_major_locator()
- x0, x1 = xlocator.nonsingular(x0, x1)
- if self._xmargin > 0:
- delta = (x1 - x0) * self._xmargin
- x0 -= delta
- x1 += delta
- if not _tight:
- x0, x1 = xlocator.view_limits(x0, x1)
- self.set_xbound(x0, x1)
-
- if scaley and self.get_autoscaley_on():
- y0, y1 = self.xy_dataLim.intervaly
- ylocator = self.yaxis.get_major_locator()
- y0, y1 = ylocator.nonsingular(y0, y1)
- if self._ymargin > 0:
- delta = (y1 - y0) * self._ymargin
- y0 -= delta
- y1 += delta
- if not _tight:
- y0, y1 = ylocator.view_limits(y0, y1)
- self.set_ybound(y0, y1)
-
- if scalez and self.get_autoscalez_on():
- z0, z1 = self.zz_dataLim.intervalx
- zlocator = self.zaxis.get_major_locator()
- z0, z1 = zlocator.nonsingular(z0, z1)
- if self._zmargin > 0:
- delta = (z1 - z0) * self._zmargin
- z0 -= delta
- z1 += delta
- if not _tight:
- z0, z1 = zlocator.view_limits(z0, z1)
- self.set_zbound(z0, z1)
-
- def get_w_lims(self):
- """Get 3D world limits."""
- minx, maxx = self.get_xlim3d()
- miny, maxy = self.get_ylim3d()
- minz, maxz = self.get_zlim3d()
- return minx, maxx, miny, maxy, minz, maxz
-
- # set_xlim, set_ylim are directly inherited from base Axes.
- def set_zlim(self, bottom=None, top=None, *, emit=True, auto=False,
- zmin=None, zmax=None):
- """
- Set 3D z limits.
-
- See `.Axes.set_ylim` for full documentation
- """
- if top is None and np.iterable(bottom):
- bottom, top = bottom
- if zmin is not None:
- if bottom is not None:
- raise TypeError("Cannot pass both 'bottom' and 'zmin'")
- bottom = zmin
- if zmax is not None:
- if top is not None:
- raise TypeError("Cannot pass both 'top' and 'zmax'")
- top = zmax
- return self.zaxis._set_lim(bottom, top, emit=emit, auto=auto)
-
- set_xlim3d = maxes.Axes.set_xlim
- set_ylim3d = maxes.Axes.set_ylim
- set_zlim3d = set_zlim
-
- def get_xlim(self):
- # docstring inherited
- return tuple(self.xy_viewLim.intervalx)
-
- def get_ylim(self):
- # docstring inherited
- return tuple(self.xy_viewLim.intervaly)
-
- def get_zlim(self):
- """
- Return the 3D z-axis view limits.
-
- Returns
- -------
- left, right : (float, float)
- The current z-axis limits in data coordinates.
-
- See Also
- --------
- set_zlim
- set_zbound, get_zbound
- invert_zaxis, zaxis_inverted
-
- Notes
- -----
- The z-axis may be inverted, in which case the *left* value will
- be greater than the *right* value.
- """
- return tuple(self.zz_viewLim.intervalx)
-
- get_zscale = _axis_method_wrapper("zaxis", "get_scale")
-
- # Redefine all three methods to overwrite their docstrings.
- set_xscale = _axis_method_wrapper("xaxis", "_set_axes_scale")
- set_yscale = _axis_method_wrapper("yaxis", "_set_axes_scale")
- set_zscale = _axis_method_wrapper("zaxis", "_set_axes_scale")
- set_xscale.__doc__, set_yscale.__doc__, set_zscale.__doc__ = map(
- """
- Set the {}-axis scale.
-
- Parameters
- ----------
- value : {{"linear"}}
- The axis scale type to apply. 3D axes currently only support
- linear scales; other scales yield nonsensical results.
-
- **kwargs
- Keyword arguments are nominally forwarded to the scale class, but
- none of them is applicable for linear scales.
- """.format,
- ["x", "y", "z"])
-
- get_zticks = _axis_method_wrapper("zaxis", "get_ticklocs")
- set_zticks = _axis_method_wrapper("zaxis", "set_ticks")
- get_zmajorticklabels = _axis_method_wrapper("zaxis", "get_majorticklabels")
- get_zminorticklabels = _axis_method_wrapper("zaxis", "get_minorticklabels")
- get_zticklabels = _axis_method_wrapper("zaxis", "get_ticklabels")
- set_zticklabels = _axis_method_wrapper(
- "zaxis", "set_ticklabels",
- doc_sub={"Axis.set_ticks": "Axes3D.set_zticks"})
-
- zaxis_date = _axis_method_wrapper("zaxis", "axis_date")
- if zaxis_date.__doc__:
- zaxis_date.__doc__ += textwrap.dedent("""
-
- Notes
- -----
- This function is merely provided for completeness, but 3D axes do not
- support dates for ticks, and so this may not work as expected.
- """)
-
- def clabel(self, *args, **kwargs):
- """Currently not implemented for 3D axes, and returns *None*."""
- return None
-
- def view_init(self, elev=None, azim=None, roll=None, vertical_axis="z",
- share=False):
- """
- Set the elevation and azimuth of the axes in degrees (not radians).
-
- This can be used to rotate the axes programmatically.
-
- To look normal to the primary planes, the following elevation and
- azimuth angles can be used. A roll angle of 0, 90, 180, or 270 deg
- will rotate these views while keeping the axes at right angles.
-
- ========== ==== ====
- view plane elev azim
- ========== ==== ====
- XY 90 -90
- XZ 0 -90
- YZ 0 0
- -XY -90 90
- -XZ 0 90
- -YZ 0 180
- ========== ==== ====
-
- Parameters
- ----------
- elev : float, default: None
- The elevation angle in degrees rotates the camera above the plane
- pierced by the vertical axis, with a positive angle corresponding
- to a location above that plane. For example, with the default
- vertical axis of 'z', the elevation defines the angle of the camera
- location above the x-y plane.
- If None, then the initial value as specified in the `Axes3D`
- constructor is used.
- azim : float, default: None
- The azimuthal angle in degrees rotates the camera about the
- vertical axis, with a positive angle corresponding to a
- right-handed rotation. For example, with the default vertical axis
- of 'z', a positive azimuth rotates the camera about the origin from
- its location along the +x axis towards the +y axis.
- If None, then the initial value as specified in the `Axes3D`
- constructor is used.
- roll : float, default: None
- The roll angle in degrees rotates the camera about the viewing
- axis. A positive angle spins the camera clockwise, causing the
- scene to rotate counter-clockwise.
- If None, then the initial value as specified in the `Axes3D`
- constructor is used.
- vertical_axis : {"z", "x", "y"}, default: "z"
- The axis to align vertically. *azim* rotates about this axis.
- share : bool, default: False
- If ``True``, apply the settings to all Axes with shared views.
- """
-
- self._dist = 10 # The camera distance from origin. Behaves like zoom
-
- if elev is None:
- elev = self.initial_elev
- if azim is None:
- azim = self.initial_azim
- if roll is None:
- roll = self.initial_roll
- vertical_axis = _api.check_getitem(
- dict(x=0, y=1, z=2), vertical_axis=vertical_axis
- )
-
- if share:
- axes = {sibling for sibling
- in self._shared_axes['view'].get_siblings(self)}
- else:
- axes = [self]
-
- for ax in axes:
- ax.elev = elev
- ax.azim = azim
- ax.roll = roll
- ax._vertical_axis = vertical_axis
-
- def set_proj_type(self, proj_type, focal_length=None):
- """
- Set the projection type.
-
- Parameters
- ----------
- proj_type : {'persp', 'ortho'}
- The projection type.
- focal_length : float, default: None
- For a projection type of 'persp', the focal length of the virtual
- camera. Must be > 0. If None, defaults to 1.
- The focal length can be computed from a desired Field Of View via
- the equation: focal_length = 1/tan(FOV/2)
- """
- _api.check_in_list(['persp', 'ortho'], proj_type=proj_type)
- if proj_type == 'persp':
- if focal_length is None:
- focal_length = 1
- elif focal_length <= 0:
- raise ValueError(f"focal_length = {focal_length} must be "
- "greater than 0")
- self._focal_length = focal_length
- else: # 'ortho':
- if focal_length not in (None, np.inf):
- raise ValueError(f"focal_length = {focal_length} must be "
- f"None for proj_type = {proj_type}")
- self._focal_length = np.inf
-
- def _roll_to_vertical(self, arr):
- """Roll arrays to match the different vertical axis."""
- return np.roll(arr, self._vertical_axis - 2)
-
- def get_proj(self):
- """Create the projection matrix from the current viewing position."""
-
- # Transform to uniform world coordinates 0-1, 0-1, 0-1
- box_aspect = self._roll_to_vertical(self._box_aspect)
- worldM = proj3d.world_transformation(
- *self.get_xlim3d(),
- *self.get_ylim3d(),
- *self.get_zlim3d(),
- pb_aspect=box_aspect,
- )
-
- # Look into the middle of the world coordinates:
- R = 0.5 * box_aspect
-
- # elev: elevation angle in the z plane.
- # azim: azimuth angle in the xy plane.
- # Coordinates for a point that rotates around the box of data.
- # p0, p1 corresponds to rotating the box only around the vertical axis.
- # p2 corresponds to rotating the box only around the horizontal axis.
- elev_rad = np.deg2rad(self.elev)
- azim_rad = np.deg2rad(self.azim)
- p0 = np.cos(elev_rad) * np.cos(azim_rad)
- p1 = np.cos(elev_rad) * np.sin(azim_rad)
- p2 = np.sin(elev_rad)
-
- # When changing vertical axis the coordinates changes as well.
- # Roll the values to get the same behaviour as the default:
- ps = self._roll_to_vertical([p0, p1, p2])
-
- # The coordinates for the eye viewing point. The eye is looking
- # towards the middle of the box of data from a distance:
- eye = R + self._dist * ps
-
- # vvec, self._vvec and self._eye are unused, remove when deprecated
- vvec = R - eye
- self._eye = eye
- self._vvec = vvec / np.linalg.norm(vvec)
-
- # Calculate the viewing axes for the eye position
- u, v, w = self._calc_view_axes(eye)
- self._view_u = u # _view_u is towards the right of the screen
- self._view_v = v # _view_v is towards the top of the screen
- self._view_w = w # _view_w is out of the screen
-
- # Generate the view and projection transformation matrices
- if self._focal_length == np.inf:
- # Orthographic projection
- viewM = proj3d._view_transformation_uvw(u, v, w, eye)
- projM = proj3d._ortho_transformation(-self._dist, self._dist)
- else:
- # Perspective projection
- # Scale the eye dist to compensate for the focal length zoom effect
- eye_focal = R + self._dist * ps * self._focal_length
- viewM = proj3d._view_transformation_uvw(u, v, w, eye_focal)
- projM = proj3d._persp_transformation(-self._dist,
- self._dist,
- self._focal_length)
-
- # Combine all the transformation matrices to get the final projection
- M0 = np.dot(viewM, worldM)
- M = np.dot(projM, M0)
- return M
-
- def mouse_init(self, rotate_btn=1, pan_btn=2, zoom_btn=3):
- """
- Set the mouse buttons for 3D rotation and zooming.
-
- Parameters
- ----------
- rotate_btn : int or list of int, default: 1
- The mouse button or buttons to use for 3D rotation of the axes.
- pan_btn : int or list of int, default: 2
- The mouse button or buttons to use to pan the 3D axes.
- zoom_btn : int or list of int, default: 3
- The mouse button or buttons to use to zoom the 3D axes.
- """
- self.button_pressed = None
- # coerce scalars into array-like, then convert into
- # a regular list to avoid comparisons against None
- # which breaks in recent versions of numpy.
- self._rotate_btn = np.atleast_1d(rotate_btn).tolist()
- self._pan_btn = np.atleast_1d(pan_btn).tolist()
- self._zoom_btn = np.atleast_1d(zoom_btn).tolist()
-
- def disable_mouse_rotation(self):
- """Disable mouse buttons for 3D rotation, panning, and zooming."""
- self.mouse_init(rotate_btn=[], pan_btn=[], zoom_btn=[])
-
- def can_zoom(self):
- # doc-string inherited
- return True
-
- def can_pan(self):
- # doc-string inherited
- return True
-
- def sharez(self, other):
- """
- Share the z-axis with *other*.
-
- This is equivalent to passing ``sharez=other`` when constructing the
- Axes, and cannot be used if the z-axis is already being shared with
- another Axes.
- """
- _api.check_isinstance(Axes3D, other=other)
- if self._sharez is not None and other is not self._sharez:
- raise ValueError("z-axis is already shared")
- self._shared_axes["z"].join(self, other)
- self._sharez = other
- self.zaxis.major = other.zaxis.major # Ticker instances holding
- self.zaxis.minor = other.zaxis.minor # locator and formatter.
- z0, z1 = other.get_zlim()
- self.set_zlim(z0, z1, emit=False, auto=other.get_autoscalez_on())
- self.zaxis._scale = other.zaxis._scale
-
- def shareview(self, other):
- """
- Share the view angles with *other*.
-
- This is equivalent to passing ``shareview=other`` when
- constructing the Axes, and cannot be used if the view angles are
- already being shared with another Axes.
- """
- _api.check_isinstance(Axes3D, other=other)
- if self._shareview is not None and other is not self._shareview:
- raise ValueError("view angles are already shared")
- self._shared_axes["view"].join(self, other)
- self._shareview = other
- vertical_axis = {0: "x", 1: "y", 2: "z"}[other._vertical_axis]
- self.view_init(elev=other.elev, azim=other.azim, roll=other.roll,
- vertical_axis=vertical_axis, share=True)
-
- def clear(self):
- # docstring inherited.
- super().clear()
- if self._focal_length == np.inf:
- self._zmargin = mpl.rcParams['axes.zmargin']
- else:
- self._zmargin = 0.
- self.grid(mpl.rcParams['axes3d.grid'])
-
- def _button_press(self, event):
- if event.inaxes == self:
- self.button_pressed = event.button
- self._sx, self._sy = event.xdata, event.ydata
- toolbar = self.figure.canvas.toolbar
- if toolbar and toolbar._nav_stack() is None:
- toolbar.push_current()
-
- def _button_release(self, event):
- self.button_pressed = None
- toolbar = self.figure.canvas.toolbar
- # backend_bases.release_zoom and backend_bases.release_pan call
- # push_current, so check the navigation mode so we don't call it twice
- if toolbar and self.get_navigate_mode() is None:
- toolbar.push_current()
-
- def _get_view(self):
- # docstring inherited
- return {
- "xlim": self.get_xlim(), "autoscalex_on": self.get_autoscalex_on(),
- "ylim": self.get_ylim(), "autoscaley_on": self.get_autoscaley_on(),
- "zlim": self.get_zlim(), "autoscalez_on": self.get_autoscalez_on(),
- }, (self.elev, self.azim, self.roll)
-
- def _set_view(self, view):
- # docstring inherited
- props, (elev, azim, roll) = view
- self.set(**props)
- self.elev = elev
- self.azim = azim
- self.roll = roll
-
- def format_zdata(self, z):
- """
- Return *z* string formatted. This function will use the
- :attr:`fmt_zdata` attribute if it is callable, else will fall
- back on the zaxis major formatter
- """
- try:
- return self.fmt_zdata(z)
- except (AttributeError, TypeError):
- func = self.zaxis.get_major_formatter().format_data_short
- val = func(z)
- return val
-
- def format_coord(self, xv, yv, renderer=None):
- """
- Return a string giving the current view rotation angles, or the x, y, z
- coordinates of the point on the nearest axis pane underneath the mouse
- cursor, depending on the mouse button pressed.
- """
- coords = ''
-
- if self.button_pressed in self._rotate_btn:
- # ignore xv and yv and display angles instead
- coords = self._rotation_coords()
-
- elif self.M is not None:
- coords = self._location_coords(xv, yv, renderer)
-
- return coords
-
- def _rotation_coords(self):
- """
- Return the rotation angles as a string.
- """
- norm_elev = art3d._norm_angle(self.elev)
- norm_azim = art3d._norm_angle(self.azim)
- norm_roll = art3d._norm_angle(self.roll)
- coords = (f"elevation={norm_elev:.0f}\N{DEGREE SIGN}, "
- f"azimuth={norm_azim:.0f}\N{DEGREE SIGN}, "
- f"roll={norm_roll:.0f}\N{DEGREE SIGN}"
- ).replace("-", "\N{MINUS SIGN}")
- return coords
-
- def _location_coords(self, xv, yv, renderer):
- """
- Return the location on the axis pane underneath the cursor as a string.
- """
- p1, pane_idx = self._calc_coord(xv, yv, renderer)
- xs = self.format_xdata(p1[0])
- ys = self.format_ydata(p1[1])
- zs = self.format_zdata(p1[2])
- if pane_idx == 0:
- coords = f'x pane={xs}, y={ys}, z={zs}'
- elif pane_idx == 1:
- coords = f'x={xs}, y pane={ys}, z={zs}'
- elif pane_idx == 2:
- coords = f'x={xs}, y={ys}, z pane={zs}'
- return coords
-
- def _get_camera_loc(self):
- """
- Returns the current camera location in data coordinates.
- """
- cx, cy, cz, dx, dy, dz = self._get_w_centers_ranges()
- c = np.array([cx, cy, cz])
- r = np.array([dx, dy, dz])
-
- if self._focal_length == np.inf: # orthographic projection
- focal_length = 1e9 # large enough to be effectively infinite
- else: # perspective projection
- focal_length = self._focal_length
- eye = c + self._view_w * self._dist * r / self._box_aspect * focal_length
- return eye
-
- def _calc_coord(self, xv, yv, renderer=None):
- """
- Given the 2D view coordinates, find the point on the nearest axis pane
- that lies directly below those coordinates. Returns a 3D point in data
- coordinates.
- """
- if self._focal_length == np.inf: # orthographic projection
- zv = 1
- else: # perspective projection
- zv = -1 / self._focal_length
-
- # Convert point on view plane to data coordinates
- p1 = np.array(proj3d.inv_transform(xv, yv, zv, self.invM)).ravel()
-
- # Get the vector from the camera to the point on the view plane
- vec = self._get_camera_loc() - p1
-
- # Get the pane locations for each of the axes
- pane_locs = []
- for axis in self._axis_map.values():
- xys, loc = axis.active_pane(renderer)
- pane_locs.append(loc)
-
- # Find the distance to the nearest pane by projecting the view vector
- scales = np.zeros(3)
- for i in range(3):
- if vec[i] == 0:
- scales[i] = np.inf
- else:
- scales[i] = (p1[i] - pane_locs[i]) / vec[i]
- pane_idx = np.argmin(abs(scales))
- scale = scales[pane_idx]
-
- # Calculate the point on the closest pane
- p2 = p1 - scale*vec
- return p2, pane_idx
-
- def _on_move(self, event):
- """
- Mouse moving.
-
- By default, button-1 rotates, button-2 pans, and button-3 zooms;
- these buttons can be modified via `mouse_init`.
- """
-
- if not self.button_pressed:
- return
-
- if self.get_navigate_mode() is not None:
- # we don't want to rotate if we are zooming/panning
- # from the toolbar
- return
-
- if self.M is None:
- return
-
- x, y = event.xdata, event.ydata
- # In case the mouse is out of bounds.
- if x is None or event.inaxes != self:
- return
-
- dx, dy = x - self._sx, y - self._sy
- w = self._pseudo_w
- h = self._pseudo_h
-
- # Rotation
- if self.button_pressed in self._rotate_btn:
- # rotate viewing point
- # get the x and y pixel coords
- if dx == 0 and dy == 0:
- return
-
- roll = np.deg2rad(self.roll)
- delev = -(dy/h)*180*np.cos(roll) + (dx/w)*180*np.sin(roll)
- dazim = -(dy/h)*180*np.sin(roll) - (dx/w)*180*np.cos(roll)
- elev = self.elev + delev
- azim = self.azim + dazim
- self.view_init(elev=elev, azim=azim, roll=roll, share=True)
- self.stale = True
-
- # Pan
- elif self.button_pressed in self._pan_btn:
- # Start the pan event with pixel coordinates
- px, py = self.transData.transform([self._sx, self._sy])
- self.start_pan(px, py, 2)
- # pan view (takes pixel coordinate input)
- self.drag_pan(2, None, event.x, event.y)
- self.end_pan()
-
- # Zoom
- elif self.button_pressed in self._zoom_btn:
- # zoom view (dragging down zooms in)
- scale = h/(h - dy)
- self._scale_axis_limits(scale, scale, scale)
-
- # Store the event coordinates for the next time through.
- self._sx, self._sy = x, y
- # Always request a draw update at the end of interaction
- self.figure.canvas.draw_idle()
-
- def drag_pan(self, button, key, x, y):
- # docstring inherited
-
- # Get the coordinates from the move event
- p = self._pan_start
- (xdata, ydata), (xdata_start, ydata_start) = p.trans_inverse.transform(
- [(x, y), (p.x, p.y)])
- self._sx, self._sy = xdata, ydata
- # Calling start_pan() to set the x/y of this event as the starting
- # move location for the next event
- self.start_pan(x, y, button)
- du, dv = xdata - xdata_start, ydata - ydata_start
- dw = 0
- if key == 'x':
- dv = 0
- elif key == 'y':
- du = 0
- if du == 0 and dv == 0:
- return
-
- # Transform the pan from the view axes to the data axes
- R = np.array([self._view_u, self._view_v, self._view_w])
- R = -R / self._box_aspect * self._dist
- duvw_projected = R.T @ np.array([du, dv, dw])
-
- # Calculate pan distance
- minx, maxx, miny, maxy, minz, maxz = self.get_w_lims()
- dx = (maxx - minx) * duvw_projected[0]
- dy = (maxy - miny) * duvw_projected[1]
- dz = (maxz - minz) * duvw_projected[2]
-
- # Set the new axis limits
- self.set_xlim3d(minx + dx, maxx + dx)
- self.set_ylim3d(miny + dy, maxy + dy)
- self.set_zlim3d(minz + dz, maxz + dz)
-
- def _calc_view_axes(self, eye):
- """
- Get the unit vectors for the viewing axes in data coordinates.
- `u` is towards the right of the screen
- `v` is towards the top of the screen
- `w` is out of the screen
- """
- elev_rad = np.deg2rad(art3d._norm_angle(self.elev))
- roll_rad = np.deg2rad(art3d._norm_angle(self.roll))
-
- # Look into the middle of the world coordinates
- R = 0.5 * self._roll_to_vertical(self._box_aspect)
-
- # Define which axis should be vertical. A negative value
- # indicates the plot is upside down and therefore the values
- # have been reversed:
- V = np.zeros(3)
- V[self._vertical_axis] = -1 if abs(elev_rad) > np.pi/2 else 1
-
- u, v, w = proj3d._view_axes(eye, R, V, roll_rad)
- return u, v, w
-
- def _set_view_from_bbox(self, bbox, direction='in',
- mode=None, twinx=False, twiny=False):
- """
- Zoom in or out of the bounding box.
-
- Will center the view in the center of the bounding box, and zoom by
- the ratio of the size of the bounding box to the size of the Axes3D.
- """
- (start_x, start_y, stop_x, stop_y) = bbox
- if mode == 'x':
- start_y = self.bbox.min[1]
- stop_y = self.bbox.max[1]
- elif mode == 'y':
- start_x = self.bbox.min[0]
- stop_x = self.bbox.max[0]
-
- # Clip to bounding box limits
- start_x, stop_x = np.clip(sorted([start_x, stop_x]),
- self.bbox.min[0], self.bbox.max[0])
- start_y, stop_y = np.clip(sorted([start_y, stop_y]),
- self.bbox.min[1], self.bbox.max[1])
-
- # Move the center of the view to the center of the bbox
- zoom_center_x = (start_x + stop_x)/2
- zoom_center_y = (start_y + stop_y)/2
-
- ax_center_x = (self.bbox.max[0] + self.bbox.min[0])/2
- ax_center_y = (self.bbox.max[1] + self.bbox.min[1])/2
-
- self.start_pan(zoom_center_x, zoom_center_y, 2)
- self.drag_pan(2, None, ax_center_x, ax_center_y)
- self.end_pan()
-
- # Calculate zoom level
- dx = abs(start_x - stop_x)
- dy = abs(start_y - stop_y)
- scale_u = dx / (self.bbox.max[0] - self.bbox.min[0])
- scale_v = dy / (self.bbox.max[1] - self.bbox.min[1])
-
- # Keep aspect ratios equal
- scale = max(scale_u, scale_v)
-
- # Zoom out
- if direction == 'out':
- scale = 1 / scale
-
- self._zoom_data_limits(scale, scale, scale)
-
- def _zoom_data_limits(self, scale_u, scale_v, scale_w):
- """
- Zoom in or out of a 3D plot.
-
- Will scale the data limits by the scale factors. These will be
- transformed to the x, y, z data axes based on the current view angles.
- A scale factor > 1 zooms out and a scale factor < 1 zooms in.
-
- For an axes that has had its aspect ratio set to 'equal', 'equalxy',
- 'equalyz', or 'equalxz', the relevant axes are constrained to zoom
- equally.
-
- Parameters
- ----------
- scale_u : float
- Scale factor for the u view axis (view screen horizontal).
- scale_v : float
- Scale factor for the v view axis (view screen vertical).
- scale_w : float
- Scale factor for the w view axis (view screen depth).
- """
- scale = np.array([scale_u, scale_v, scale_w])
-
- # Only perform frame conversion if unequal scale factors
- if not np.allclose(scale, scale_u):
- # Convert the scale factors from the view frame to the data frame
- R = np.array([self._view_u, self._view_v, self._view_w])
- S = scale * np.eye(3)
- scale = np.linalg.norm(R.T @ S, axis=1)
-
- # Set the constrained scale factors to the factor closest to 1
- if self._aspect in ('equal', 'equalxy', 'equalxz', 'equalyz'):
- ax_idxs = self._equal_aspect_axis_indices(self._aspect)
- min_ax_idxs = np.argmin(np.abs(scale[ax_idxs] - 1))
- scale[ax_idxs] = scale[ax_idxs][min_ax_idxs]
-
- self._scale_axis_limits(scale[0], scale[1], scale[2])
-
- def _scale_axis_limits(self, scale_x, scale_y, scale_z):
- """
- Keeping the center of the x, y, and z data axes fixed, scale their
- limits by scale factors. A scale factor > 1 zooms out and a scale
- factor < 1 zooms in.
-
- Parameters
- ----------
- scale_x : float
- Scale factor for the x data axis.
- scale_y : float
- Scale factor for the y data axis.
- scale_z : float
- Scale factor for the z data axis.
- """
- # Get the axis centers and ranges
- cx, cy, cz, dx, dy, dz = self._get_w_centers_ranges()
-
- # Set the scaled axis limits
- self.set_xlim3d(cx - dx*scale_x/2, cx + dx*scale_x/2)
- self.set_ylim3d(cy - dy*scale_y/2, cy + dy*scale_y/2)
- self.set_zlim3d(cz - dz*scale_z/2, cz + dz*scale_z/2)
-
- def _get_w_centers_ranges(self):
- """Get 3D world centers and axis ranges."""
- # Calculate center of axis limits
- minx, maxx, miny, maxy, minz, maxz = self.get_w_lims()
- cx = (maxx + minx)/2
- cy = (maxy + miny)/2
- cz = (maxz + minz)/2
-
- # Calculate range of axis limits
- dx = (maxx - minx)
- dy = (maxy - miny)
- dz = (maxz - minz)
- return cx, cy, cz, dx, dy, dz
-
- def set_zlabel(self, zlabel, fontdict=None, labelpad=None, **kwargs):
- """
- Set zlabel. See doc for `.set_ylabel` for description.
- """
- if labelpad is not None:
- self.zaxis.labelpad = labelpad
- return self.zaxis.set_label_text(zlabel, fontdict, **kwargs)
-
- def get_zlabel(self):
- """
- Get the z-label text string.
- """
- label = self.zaxis.get_label()
- return label.get_text()
-
- # Axes rectangle characteristics
-
- # The frame_on methods are not available for 3D axes.
- # Python will raise a TypeError if they are called.
- get_frame_on = None
- set_frame_on = None
-
- def grid(self, visible=True, **kwargs):
- """
- Set / unset 3D grid.
-
- .. note::
-
- Currently, this function does not behave the same as
- `.axes.Axes.grid`, but it is intended to eventually support that
- behavior.
- """
- # TODO: Operate on each axes separately
- if len(kwargs):
- visible = True
- self._draw_grid = visible
- self.stale = True
-
- def tick_params(self, axis='both', **kwargs):
- """
- Convenience method for changing the appearance of ticks and
- tick labels.
-
- See `.Axes.tick_params` for full documentation. Because this function
- applies to 3D Axes, *axis* can also be set to 'z', and setting *axis*
- to 'both' autoscales all three axes.
-
- Also, because of how Axes3D objects are drawn very differently
- from regular 2D axes, some of these settings may have
- ambiguous meaning. For simplicity, the 'z' axis will
- accept settings as if it was like the 'y' axis.
-
- .. note::
- Axes3D currently ignores some of these settings.
- """
- _api.check_in_list(['x', 'y', 'z', 'both'], axis=axis)
- if axis in ['x', 'y', 'both']:
- super().tick_params(axis, **kwargs)
- if axis in ['z', 'both']:
- zkw = dict(kwargs)
- zkw.pop('top', None)
- zkw.pop('bottom', None)
- zkw.pop('labeltop', None)
- zkw.pop('labelbottom', None)
- self.zaxis.set_tick_params(**zkw)
-
- # data limits, ticks, tick labels, and formatting
-
- def invert_zaxis(self):
- """
- Invert the z-axis.
-
- See Also
- --------
- zaxis_inverted
- get_zlim, set_zlim
- get_zbound, set_zbound
- """
- bottom, top = self.get_zlim()
- self.set_zlim(top, bottom, auto=None)
-
- zaxis_inverted = _axis_method_wrapper("zaxis", "get_inverted")
-
- def get_zbound(self):
- """
- Return the lower and upper z-axis bounds, in increasing order.
-
- See Also
- --------
- set_zbound
- get_zlim, set_zlim
- invert_zaxis, zaxis_inverted
- """
- bottom, top = self.get_zlim()
- if bottom < top:
- return bottom, top
- else:
- return top, bottom
-
- def set_zbound(self, lower=None, upper=None):
- """
- Set the lower and upper numerical bounds of the z-axis.
-
- This method will honor axes inversion regardless of parameter order.
- It will not change the autoscaling setting (`.get_autoscalez_on()`).
-
- Parameters
- ----------
- lower, upper : float or None
- The lower and upper bounds. If *None*, the respective axis bound
- is not modified.
-
- See Also
- --------
- get_zbound
- get_zlim, set_zlim
- invert_zaxis, zaxis_inverted
- """
- if upper is None and np.iterable(lower):
- lower, upper = lower
-
- old_lower, old_upper = self.get_zbound()
- if lower is None:
- lower = old_lower
- if upper is None:
- upper = old_upper
-
- self.set_zlim(sorted((lower, upper),
- reverse=bool(self.zaxis_inverted())),
- auto=None)
-
- def text(self, x, y, z, s, zdir=None, **kwargs):
- """
- Add the text *s* to the 3D Axes at location *x*, *y*, *z* in data coordinates.
-
- Parameters
- ----------
- x, y, z : float
- The position to place the text.
- s : str
- The text.
- zdir : {'x', 'y', 'z', 3-tuple}, optional
- The direction to be used as the z-direction. Default: 'z'.
- See `.get_dir_vector` for a description of the values.
- **kwargs
- Other arguments are forwarded to `matplotlib.axes.Axes.text`.
-
- Returns
- -------
- `.Text3D`
- The created `.Text3D` instance.
- """
- text = super().text(x, y, s, **kwargs)
- art3d.text_2d_to_3d(text, z, zdir)
- return text
-
- text3D = text
- text2D = Axes.text
-
- def plot(self, xs, ys, *args, zdir='z', **kwargs):
- """
- Plot 2D or 3D data.
-
- Parameters
- ----------
- xs : 1D array-like
- x coordinates of vertices.
- ys : 1D array-like
- y coordinates of vertices.
- zs : float or 1D array-like
- z coordinates of vertices; either one for all points or one for
- each point.
- zdir : {'x', 'y', 'z'}, default: 'z'
- When plotting 2D data, the direction to use as z.
- **kwargs
- Other arguments are forwarded to `matplotlib.axes.Axes.plot`.
- """
- had_data = self.has_data()
-
- # `zs` can be passed positionally or as keyword; checking whether
- # args[0] is a string matches the behavior of 2D `plot` (via
- # `_process_plot_var_args`).
- if args and not isinstance(args[0], str):
- zs, *args = args
- if 'zs' in kwargs:
- raise TypeError("plot() for multiple values for argument 'z'")
- else:
- zs = kwargs.pop('zs', 0)
-
- # Match length
- zs = np.broadcast_to(zs, np.shape(xs))
-
- lines = super().plot(xs, ys, *args, **kwargs)
- for line in lines:
- art3d.line_2d_to_3d(line, zs=zs, zdir=zdir)
-
- xs, ys, zs = art3d.juggle_axes(xs, ys, zs, zdir)
- self.auto_scale_xyz(xs, ys, zs, had_data)
- return lines
-
- plot3D = plot
-
- def plot_surface(self, X, Y, Z, *, norm=None, vmin=None,
- vmax=None, lightsource=None, **kwargs):
- """
- Create a surface plot.
-
- By default, it will be colored in shades of a solid color, but it also
- supports colormapping by supplying the *cmap* argument.
-
- .. note::
-
- The *rcount* and *ccount* kwargs, which both default to 50,
- determine the maximum number of samples used in each direction. If
- the input data is larger, it will be downsampled (by slicing) to
- these numbers of points.
-
- .. note::
-
- To maximize rendering speed consider setting *rstride* and *cstride*
- to divisors of the number of rows minus 1 and columns minus 1
- respectively. For example, given 51 rows rstride can be any of the
- divisors of 50.
-
- Similarly, a setting of *rstride* and *cstride* equal to 1 (or
- *rcount* and *ccount* equal the number of rows and columns) can use
- the optimized path.
-
- Parameters
- ----------
- X, Y, Z : 2D arrays
- Data values.
-
- rcount, ccount : int
- Maximum number of samples used in each direction. If the input
- data is larger, it will be downsampled (by slicing) to these
- numbers of points. Defaults to 50.
-
- rstride, cstride : int
- Downsampling stride in each direction. These arguments are
- mutually exclusive with *rcount* and *ccount*. If only one of
- *rstride* or *cstride* is set, the other defaults to 10.
-
- 'classic' mode uses a default of ``rstride = cstride = 10`` instead
- of the new default of ``rcount = ccount = 50``.
-
- color : color-like
- Color of the surface patches.
-
- cmap : Colormap
- Colormap of the surface patches.
-
- facecolors : array-like of colors.
- Colors of each individual patch.
-
- norm : Normalize
- Normalization for the colormap.
-
- vmin, vmax : float
- Bounds for the normalization.
-
- shade : bool, default: True
- Whether to shade the facecolors. Shading is always disabled when
- *cmap* is specified.
-
- lightsource : `~matplotlib.colors.LightSource`
- The lightsource to use when *shade* is True.
-
- **kwargs
- Other keyword arguments are forwarded to `.Poly3DCollection`.
- """
-
- had_data = self.has_data()
-
- if Z.ndim != 2:
- raise ValueError("Argument Z must be 2-dimensional.")
-
- Z = cbook._to_unmasked_float_array(Z)
- X, Y, Z = np.broadcast_arrays(X, Y, Z)
- rows, cols = Z.shape
-
- has_stride = 'rstride' in kwargs or 'cstride' in kwargs
- has_count = 'rcount' in kwargs or 'ccount' in kwargs
-
- if has_stride and has_count:
- raise ValueError("Cannot specify both stride and count arguments")
-
- rstride = kwargs.pop('rstride', 10)
- cstride = kwargs.pop('cstride', 10)
- rcount = kwargs.pop('rcount', 50)
- ccount = kwargs.pop('ccount', 50)
-
- if mpl.rcParams['_internal.classic_mode']:
- # Strides have priority over counts in classic mode.
- # So, only compute strides from counts
- # if counts were explicitly given
- compute_strides = has_count
- else:
- # If the strides are provided then it has priority.
- # Otherwise, compute the strides from the counts.
- compute_strides = not has_stride
-
- if compute_strides:
- rstride = int(max(np.ceil(rows / rcount), 1))
- cstride = int(max(np.ceil(cols / ccount), 1))
-
- fcolors = kwargs.pop('facecolors', None)
-
- cmap = kwargs.get('cmap', None)
- shade = kwargs.pop('shade', cmap is None)
- if shade is None:
- raise ValueError("shade cannot be None.")
-
- colset = [] # the sampled facecolor
- if (rows - 1) % rstride == 0 and \
- (cols - 1) % cstride == 0 and \
- fcolors is None:
- polys = np.stack(
- [cbook._array_patch_perimeters(a, rstride, cstride)
- for a in (X, Y, Z)],
- axis=-1)
- else:
- # evenly spaced, and including both endpoints
- row_inds = list(range(0, rows-1, rstride)) + [rows-1]
- col_inds = list(range(0, cols-1, cstride)) + [cols-1]
-
- polys = []
- for rs, rs_next in zip(row_inds[:-1], row_inds[1:]):
- for cs, cs_next in zip(col_inds[:-1], col_inds[1:]):
- ps = [
- # +1 ensures we share edges between polygons
- cbook._array_perimeter(a[rs:rs_next+1, cs:cs_next+1])
- for a in (X, Y, Z)
- ]
- # ps = np.stack(ps, axis=-1)
- ps = np.array(ps).T
- polys.append(ps)
-
- if fcolors is not None:
- colset.append(fcolors[rs][cs])
-
- # In cases where there are non-finite values in the data (possibly NaNs from
- # masked arrays), artifacts can be introduced. Here check whether such values
- # are present and remove them.
- if not isinstance(polys, np.ndarray) or not np.isfinite(polys).all():
- new_polys = []
- new_colset = []
-
- # Depending on fcolors, colset is either an empty list or has as
- # many elements as polys. In the former case new_colset results in
- # a list with None entries, that is discarded later.
- for p, col in itertools.zip_longest(polys, colset):
- new_poly = np.array(p)[np.isfinite(p).all(axis=1)]
- if len(new_poly):
- new_polys.append(new_poly)
- new_colset.append(col)
-
- # Replace previous polys and, if fcolors is not None, colset
- polys = new_polys
- if fcolors is not None:
- colset = new_colset
-
- # note that the striding causes some polygons to have more coordinates
- # than others
-
- if fcolors is not None:
- polyc = art3d.Poly3DCollection(
- polys, edgecolors=colset, facecolors=colset, shade=shade,
- lightsource=lightsource, **kwargs)
- elif cmap:
- polyc = art3d.Poly3DCollection(polys, **kwargs)
- # can't always vectorize, because polys might be jagged
- if isinstance(polys, np.ndarray):
- avg_z = polys[..., 2].mean(axis=-1)
- else:
- avg_z = np.array([ps[:, 2].mean() for ps in polys])
- polyc.set_array(avg_z)
- if vmin is not None or vmax is not None:
- polyc.set_clim(vmin, vmax)
- if norm is not None:
- polyc.set_norm(norm)
- else:
- color = kwargs.pop('color', None)
- if color is None:
- color = self._get_lines.get_next_color()
- color = np.array(mcolors.to_rgba(color))
-
- polyc = art3d.Poly3DCollection(
- polys, facecolors=color, shade=shade,
- lightsource=lightsource, **kwargs)
-
- self.add_collection(polyc)
- self.auto_scale_xyz(X, Y, Z, had_data)
-
- return polyc
-
- def plot_wireframe(self, X, Y, Z, **kwargs):
- """
- Plot a 3D wireframe.
-
- .. note::
-
- The *rcount* and *ccount* kwargs, which both default to 50,
- determine the maximum number of samples used in each direction. If
- the input data is larger, it will be downsampled (by slicing) to
- these numbers of points.
-
- Parameters
- ----------
- X, Y, Z : 2D arrays
- Data values.
-
- rcount, ccount : int
- Maximum number of samples used in each direction. If the input
- data is larger, it will be downsampled (by slicing) to these
- numbers of points. Setting a count to zero causes the data to be
- not sampled in the corresponding direction, producing a 3D line
- plot rather than a wireframe plot. Defaults to 50.
-
- rstride, cstride : int
- Downsampling stride in each direction. These arguments are
- mutually exclusive with *rcount* and *ccount*. If only one of
- *rstride* or *cstride* is set, the other defaults to 1. Setting a
- stride to zero causes the data to be not sampled in the
- corresponding direction, producing a 3D line plot rather than a
- wireframe plot.
-
- 'classic' mode uses a default of ``rstride = cstride = 1`` instead
- of the new default of ``rcount = ccount = 50``.
-
- **kwargs
- Other keyword arguments are forwarded to `.Line3DCollection`.
- """
-
- had_data = self.has_data()
- if Z.ndim != 2:
- raise ValueError("Argument Z must be 2-dimensional.")
- # FIXME: Support masked arrays
- X, Y, Z = np.broadcast_arrays(X, Y, Z)
- rows, cols = Z.shape
-
- has_stride = 'rstride' in kwargs or 'cstride' in kwargs
- has_count = 'rcount' in kwargs or 'ccount' in kwargs
-
- if has_stride and has_count:
- raise ValueError("Cannot specify both stride and count arguments")
-
- rstride = kwargs.pop('rstride', 1)
- cstride = kwargs.pop('cstride', 1)
- rcount = kwargs.pop('rcount', 50)
- ccount = kwargs.pop('ccount', 50)
-
- if mpl.rcParams['_internal.classic_mode']:
- # Strides have priority over counts in classic mode.
- # So, only compute strides from counts
- # if counts were explicitly given
- if has_count:
- rstride = int(max(np.ceil(rows / rcount), 1)) if rcount else 0
- cstride = int(max(np.ceil(cols / ccount), 1)) if ccount else 0
- else:
- # If the strides are provided then it has priority.
- # Otherwise, compute the strides from the counts.
- if not has_stride:
- rstride = int(max(np.ceil(rows / rcount), 1)) if rcount else 0
- cstride = int(max(np.ceil(cols / ccount), 1)) if ccount else 0
-
- # We want two sets of lines, one running along the "rows" of
- # Z and another set of lines running along the "columns" of Z.
- # This transpose will make it easy to obtain the columns.
- tX, tY, tZ = np.transpose(X), np.transpose(Y), np.transpose(Z)
-
- if rstride:
- rii = list(range(0, rows, rstride))
- # Add the last index only if needed
- if rows > 0 and rii[-1] != (rows - 1):
- rii += [rows-1]
- else:
- rii = []
- if cstride:
- cii = list(range(0, cols, cstride))
- # Add the last index only if needed
- if cols > 0 and cii[-1] != (cols - 1):
- cii += [cols-1]
- else:
- cii = []
-
- if rstride == 0 and cstride == 0:
- raise ValueError("Either rstride or cstride must be non zero")
-
- # If the inputs were empty, then just
- # reset everything.
- if Z.size == 0:
- rii = []
- cii = []
-
- xlines = [X[i] for i in rii]
- ylines = [Y[i] for i in rii]
- zlines = [Z[i] for i in rii]
-
- txlines = [tX[i] for i in cii]
- tylines = [tY[i] for i in cii]
- tzlines = [tZ[i] for i in cii]
-
- lines = ([list(zip(xl, yl, zl))
- for xl, yl, zl in zip(xlines, ylines, zlines)]
- + [list(zip(xl, yl, zl))
- for xl, yl, zl in zip(txlines, tylines, tzlines)])
-
- linec = art3d.Line3DCollection(lines, **kwargs)
- self.add_collection(linec)
- self.auto_scale_xyz(X, Y, Z, had_data)
-
- return linec
-
- def plot_trisurf(self, *args, color=None, norm=None, vmin=None, vmax=None,
- lightsource=None, **kwargs):
- """
- Plot a triangulated surface.
-
- The (optional) triangulation can be specified in one of two ways;
- either::
-
- plot_trisurf(triangulation, ...)
-
- where triangulation is a `~matplotlib.tri.Triangulation` object, or::
-
- plot_trisurf(X, Y, ...)
- plot_trisurf(X, Y, triangles, ...)
- plot_trisurf(X, Y, triangles=triangles, ...)
-
- in which case a Triangulation object will be created. See
- `.Triangulation` for an explanation of these possibilities.
-
- The remaining arguments are::
-
- plot_trisurf(..., Z)
-
- where *Z* is the array of values to contour, one per point
- in the triangulation.
-
- Parameters
- ----------
- X, Y, Z : array-like
- Data values as 1D arrays.
- color
- Color of the surface patches.
- cmap
- A colormap for the surface patches.
- norm : Normalize
- An instance of Normalize to map values to colors.
- vmin, vmax : float, default: None
- Minimum and maximum value to map.
- shade : bool, default: True
- Whether to shade the facecolors. Shading is always disabled when
- *cmap* is specified.
- lightsource : `~matplotlib.colors.LightSource`
- The lightsource to use when *shade* is True.
- **kwargs
- All other keyword arguments are passed on to
- :class:`~mpl_toolkits.mplot3d.art3d.Poly3DCollection`
-
- Examples
- --------
- .. plot:: gallery/mplot3d/trisurf3d.py
- .. plot:: gallery/mplot3d/trisurf3d_2.py
- """
-
- had_data = self.has_data()
-
- # TODO: Support custom face colours
- if color is None:
- color = self._get_lines.get_next_color()
- color = np.array(mcolors.to_rgba(color))
-
- cmap = kwargs.get('cmap', None)
- shade = kwargs.pop('shade', cmap is None)
-
- tri, args, kwargs = \
- Triangulation.get_from_args_and_kwargs(*args, **kwargs)
- try:
- z = kwargs.pop('Z')
- except KeyError:
- # We do this so Z doesn't get passed as an arg to PolyCollection
- z, *args = args
- z = np.asarray(z)
-
- triangles = tri.get_masked_triangles()
- xt = tri.x[triangles]
- yt = tri.y[triangles]
- zt = z[triangles]
- verts = np.stack((xt, yt, zt), axis=-1)
-
- if cmap:
- polyc = art3d.Poly3DCollection(verts, *args, **kwargs)
- # average over the three points of each triangle
- avg_z = verts[:, :, 2].mean(axis=1)
- polyc.set_array(avg_z)
- if vmin is not None or vmax is not None:
- polyc.set_clim(vmin, vmax)
- if norm is not None:
- polyc.set_norm(norm)
- else:
- polyc = art3d.Poly3DCollection(
- verts, *args, shade=shade, lightsource=lightsource,
- facecolors=color, **kwargs)
-
- self.add_collection(polyc)
- self.auto_scale_xyz(tri.x, tri.y, z, had_data)
-
- return polyc
-
- def _3d_extend_contour(self, cset, stride=5):
- """
- Extend a contour in 3D by creating
- """
-
- dz = (cset.levels[1] - cset.levels[0]) / 2
- polyverts = []
- colors = []
- for idx, level in enumerate(cset.levels):
- path = cset.get_paths()[idx]
- subpaths = [*path._iter_connected_components()]
- color = cset.get_edgecolor()[idx]
- top = art3d._paths_to_3d_segments(subpaths, level - dz)
- bot = art3d._paths_to_3d_segments(subpaths, level + dz)
- if not len(top[0]):
- continue
- nsteps = max(round(len(top[0]) / stride), 2)
- stepsize = (len(top[0]) - 1) / (nsteps - 1)
- polyverts.extend([
- (top[0][round(i * stepsize)], top[0][round((i + 1) * stepsize)],
- bot[0][round((i + 1) * stepsize)], bot[0][round(i * stepsize)])
- for i in range(round(nsteps) - 1)])
- colors.extend([color] * (round(nsteps) - 1))
- self.add_collection3d(art3d.Poly3DCollection(
- np.array(polyverts), # All polygons have 4 vertices, so vectorize.
- facecolors=colors, edgecolors=colors, shade=True))
- cset.remove()
-
- def add_contour_set(
- self, cset, extend3d=False, stride=5, zdir='z', offset=None):
- zdir = '-' + zdir
- if extend3d:
- self._3d_extend_contour(cset, stride)
- else:
- art3d.collection_2d_to_3d(
- cset, zs=offset if offset is not None else cset.levels, zdir=zdir)
-
- def add_contourf_set(self, cset, zdir='z', offset=None):
- self._add_contourf_set(cset, zdir=zdir, offset=offset)
-
- def _add_contourf_set(self, cset, zdir='z', offset=None):
- """
- Returns
- -------
- levels : `numpy.ndarray`
- Levels at which the filled contours are added.
- """
- zdir = '-' + zdir
-
- midpoints = cset.levels[:-1] + np.diff(cset.levels) / 2
- # Linearly interpolate to get levels for any extensions
- if cset._extend_min:
- min_level = cset.levels[0] - np.diff(cset.levels[:2]) / 2
- midpoints = np.insert(midpoints, 0, min_level)
- if cset._extend_max:
- max_level = cset.levels[-1] + np.diff(cset.levels[-2:]) / 2
- midpoints = np.append(midpoints, max_level)
-
- art3d.collection_2d_to_3d(
- cset, zs=offset if offset is not None else midpoints, zdir=zdir)
- return midpoints
-
- @_preprocess_data()
- def contour(self, X, Y, Z, *args,
- extend3d=False, stride=5, zdir='z', offset=None, **kwargs):
- """
- Create a 3D contour plot.
-
- Parameters
- ----------
- X, Y, Z : array-like,
- Input data. See `.Axes.contour` for supported data shapes.
- extend3d : bool, default: False
- Whether to extend contour in 3D.
- stride : int
- Step size for extending contour.
- zdir : {'x', 'y', 'z'}, default: 'z'
- The direction to use.
- offset : float, optional
- If specified, plot a projection of the contour lines at this
- position in a plane normal to *zdir*.
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- *args, **kwargs
- Other arguments are forwarded to `matplotlib.axes.Axes.contour`.
-
- Returns
- -------
- matplotlib.contour.QuadContourSet
- """
- had_data = self.has_data()
-
- jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir)
- cset = super().contour(jX, jY, jZ, *args, **kwargs)
- self.add_contour_set(cset, extend3d, stride, zdir, offset)
-
- self.auto_scale_xyz(X, Y, Z, had_data)
- return cset
-
- contour3D = contour
-
- @_preprocess_data()
- def tricontour(self, *args,
- extend3d=False, stride=5, zdir='z', offset=None, **kwargs):
- """
- Create a 3D contour plot.
-
- .. note::
- This method currently produces incorrect output due to a
- longstanding bug in 3D PolyCollection rendering.
-
- Parameters
- ----------
- X, Y, Z : array-like
- Input data. See `.Axes.tricontour` for supported data shapes.
- extend3d : bool, default: False
- Whether to extend contour in 3D.
- stride : int
- Step size for extending contour.
- zdir : {'x', 'y', 'z'}, default: 'z'
- The direction to use.
- offset : float, optional
- If specified, plot a projection of the contour lines at this
- position in a plane normal to *zdir*.
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
- *args, **kwargs
- Other arguments are forwarded to `matplotlib.axes.Axes.tricontour`.
-
- Returns
- -------
- matplotlib.tri._tricontour.TriContourSet
- """
- had_data = self.has_data()
-
- tri, args, kwargs = Triangulation.get_from_args_and_kwargs(
- *args, **kwargs)
- X = tri.x
- Y = tri.y
- if 'Z' in kwargs:
- Z = kwargs.pop('Z')
- else:
- # We do this so Z doesn't get passed as an arg to Axes.tricontour
- Z, *args = args
-
- jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir)
- tri = Triangulation(jX, jY, tri.triangles, tri.mask)
-
- cset = super().tricontour(tri, jZ, *args, **kwargs)
- self.add_contour_set(cset, extend3d, stride, zdir, offset)
-
- self.auto_scale_xyz(X, Y, Z, had_data)
- return cset
-
- def _auto_scale_contourf(self, X, Y, Z, zdir, levels, had_data):
- # Autoscale in the zdir based on the levels added, which are
- # different from data range if any contour extensions are present
- dim_vals = {'x': X, 'y': Y, 'z': Z, zdir: levels}
- # Input data and levels have different sizes, but auto_scale_xyz
- # expected same-size input, so manually take min/max limits
- limits = [(np.nanmin(dim_vals[dim]), np.nanmax(dim_vals[dim]))
- for dim in ['x', 'y', 'z']]
- self.auto_scale_xyz(*limits, had_data)
-
- @_preprocess_data()
- def contourf(self, X, Y, Z, *args, zdir='z', offset=None, **kwargs):
- """
- Create a 3D filled contour plot.
-
- Parameters
- ----------
- X, Y, Z : array-like
- Input data. See `.Axes.contourf` for supported data shapes.
- zdir : {'x', 'y', 'z'}, default: 'z'
- The direction to use.
- offset : float, optional
- If specified, plot a projection of the contour lines at this
- position in a plane normal to *zdir*.
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
- *args, **kwargs
- Other arguments are forwarded to `matplotlib.axes.Axes.contourf`.
-
- Returns
- -------
- matplotlib.contour.QuadContourSet
- """
- had_data = self.has_data()
-
- jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir)
- cset = super().contourf(jX, jY, jZ, *args, **kwargs)
- levels = self._add_contourf_set(cset, zdir, offset)
-
- self._auto_scale_contourf(X, Y, Z, zdir, levels, had_data)
- return cset
-
- contourf3D = contourf
-
- @_preprocess_data()
- def tricontourf(self, *args, zdir='z', offset=None, **kwargs):
- """
- Create a 3D filled contour plot.
-
- .. note::
- This method currently produces incorrect output due to a
- longstanding bug in 3D PolyCollection rendering.
-
- Parameters
- ----------
- X, Y, Z : array-like
- Input data. See `.Axes.tricontourf` for supported data shapes.
- zdir : {'x', 'y', 'z'}, default: 'z'
- The direction to use.
- offset : float, optional
- If specified, plot a projection of the contour lines at this
- position in a plane normal to zdir.
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
- *args, **kwargs
- Other arguments are forwarded to
- `matplotlib.axes.Axes.tricontourf`.
-
- Returns
- -------
- matplotlib.tri._tricontour.TriContourSet
- """
- had_data = self.has_data()
-
- tri, args, kwargs = Triangulation.get_from_args_and_kwargs(
- *args, **kwargs)
- X = tri.x
- Y = tri.y
- if 'Z' in kwargs:
- Z = kwargs.pop('Z')
- else:
- # We do this so Z doesn't get passed as an arg to Axes.tricontourf
- Z, *args = args
-
- jX, jY, jZ = art3d.rotate_axes(X, Y, Z, zdir)
- tri = Triangulation(jX, jY, tri.triangles, tri.mask)
-
- cset = super().tricontourf(tri, jZ, *args, **kwargs)
- levels = self._add_contourf_set(cset, zdir, offset)
-
- self._auto_scale_contourf(X, Y, Z, zdir, levels, had_data)
- return cset
-
- def add_collection3d(self, col, zs=0, zdir='z'):
- """
- Add a 3D collection object to the plot.
-
- 2D collection types are converted to a 3D version by
- modifying the object and adding z coordinate information.
-
- Supported are:
-
- - PolyCollection
- - LineCollection
- - PatchCollection
- """
- zvals = np.atleast_1d(zs)
- zsortval = (np.min(zvals) if zvals.size
- else 0) # FIXME: arbitrary default
-
- # FIXME: use issubclass() (although, then a 3D collection
- # object would also pass.) Maybe have a collection3d
- # abstract class to test for and exclude?
- if type(col) is mcoll.PolyCollection:
- art3d.poly_collection_2d_to_3d(col, zs=zs, zdir=zdir)
- col.set_sort_zpos(zsortval)
- elif type(col) is mcoll.LineCollection:
- art3d.line_collection_2d_to_3d(col, zs=zs, zdir=zdir)
- col.set_sort_zpos(zsortval)
- elif type(col) is mcoll.PatchCollection:
- art3d.patch_collection_2d_to_3d(col, zs=zs, zdir=zdir)
- col.set_sort_zpos(zsortval)
-
- collection = super().add_collection(col)
- return collection
-
- @_preprocess_data(replace_names=["xs", "ys", "zs", "s",
- "edgecolors", "c", "facecolor",
- "facecolors", "color"])
- def scatter(self, xs, ys, zs=0, zdir='z', s=20, c=None, depthshade=True,
- *args, **kwargs):
- """
- Create a scatter plot.
-
- Parameters
- ----------
- xs, ys : array-like
- The data positions.
- zs : float or array-like, default: 0
- The z-positions. Either an array of the same length as *xs* and
- *ys* or a single value to place all points in the same plane.
- zdir : {'x', 'y', 'z', '-x', '-y', '-z'}, default: 'z'
- The axis direction for the *zs*. This is useful when plotting 2D
- data on a 3D Axes. The data must be passed as *xs*, *ys*. Setting
- *zdir* to 'y' then plots the data to the x-z-plane.
-
- See also :doc:`/gallery/mplot3d/2dcollections3d`.
-
- s : float or array-like, default: 20
- The marker size in points**2. Either an array of the same length
- as *xs* and *ys* or a single value to make all markers the same
- size.
- c : color, sequence, or sequence of colors, optional
- The marker color. Possible values:
-
- - A single color format string.
- - A sequence of colors of length n.
- - A sequence of n numbers to be mapped to colors using *cmap* and
- *norm*.
- - A 2D array in which the rows are RGB or RGBA.
-
- For more details see the *c* argument of `~.axes.Axes.scatter`.
- depthshade : bool, default: True
- Whether to shade the scatter markers to give the appearance of
- depth. Each call to ``scatter()`` will perform its depthshading
- independently.
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
- **kwargs
- All other keyword arguments are passed on to `~.axes.Axes.scatter`.
-
- Returns
- -------
- paths : `~matplotlib.collections.PathCollection`
- """
-
- had_data = self.has_data()
- zs_orig = zs
-
- xs, ys, zs = np.broadcast_arrays(
- *[np.ravel(np.ma.filled(t, np.nan)) for t in [xs, ys, zs]])
- s = np.ma.ravel(s) # This doesn't have to match x, y in size.
-
- xs, ys, zs, s, c, color = cbook.delete_masked_points(
- xs, ys, zs, s, c, kwargs.get('color', None)
- )
- if kwargs.get("color") is not None:
- kwargs['color'] = color
-
- # For xs and ys, 2D scatter() will do the copying.
- if np.may_share_memory(zs_orig, zs): # Avoid unnecessary copies.
- zs = zs.copy()
-
- patches = super().scatter(xs, ys, s=s, c=c, *args, **kwargs)
- art3d.patch_collection_2d_to_3d(patches, zs=zs, zdir=zdir,
- depthshade=depthshade)
-
- if self._zmargin < 0.05 and xs.size > 0:
- self.set_zmargin(0.05)
-
- self.auto_scale_xyz(xs, ys, zs, had_data)
-
- return patches
-
- scatter3D = scatter
-
- @_preprocess_data()
- def bar(self, left, height, zs=0, zdir='z', *args, **kwargs):
- """
- Add 2D bar(s).
-
- Parameters
- ----------
- left : 1D array-like
- The x coordinates of the left sides of the bars.
- height : 1D array-like
- The height of the bars.
- zs : float or 1D array-like
- Z coordinate of bars; if a single value is specified, it will be
- used for all bars.
- zdir : {'x', 'y', 'z'}, default: 'z'
- When plotting 2D data, the direction to use as z ('x', 'y' or 'z').
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
- **kwargs
- Other keyword arguments are forwarded to
- `matplotlib.axes.Axes.bar`.
-
- Returns
- -------
- mpl_toolkits.mplot3d.art3d.Patch3DCollection
- """
- had_data = self.has_data()
-
- patches = super().bar(left, height, *args, **kwargs)
-
- zs = np.broadcast_to(zs, len(left))
-
- verts = []
- verts_zs = []
- for p, z in zip(patches, zs):
- vs = art3d._get_patch_verts(p)
- verts += vs.tolist()
- verts_zs += [z] * len(vs)
- art3d.patch_2d_to_3d(p, z, zdir)
- if 'alpha' in kwargs:
- p.set_alpha(kwargs['alpha'])
-
- if len(verts) > 0:
- # the following has to be skipped if verts is empty
- # NOTE: Bugs could still occur if len(verts) > 0,
- # but the "2nd dimension" is empty.
- xs, ys = zip(*verts)
- else:
- xs, ys = [], []
-
- xs, ys, verts_zs = art3d.juggle_axes(xs, ys, verts_zs, zdir)
- self.auto_scale_xyz(xs, ys, verts_zs, had_data)
-
- return patches
-
- @_preprocess_data()
- def bar3d(self, x, y, z, dx, dy, dz, color=None,
- zsort='average', shade=True, lightsource=None, *args, **kwargs):
- """
- Generate a 3D barplot.
-
- This method creates three-dimensional barplot where the width,
- depth, height, and color of the bars can all be uniquely set.
-
- Parameters
- ----------
- x, y, z : array-like
- The coordinates of the anchor point of the bars.
-
- dx, dy, dz : float or array-like
- The width, depth, and height of the bars, respectively.
-
- color : sequence of colors, optional
- The color of the bars can be specified globally or
- individually. This parameter can be:
-
- - A single color, to color all bars the same color.
- - An array of colors of length N bars, to color each bar
- independently.
- - An array of colors of length 6, to color the faces of the
- bars similarly.
- - An array of colors of length 6 * N bars, to color each face
- independently.
-
- When coloring the faces of the boxes specifically, this is
- the order of the coloring:
-
- 1. -Z (bottom of box)
- 2. +Z (top of box)
- 3. -Y
- 4. +Y
- 5. -X
- 6. +X
-
- zsort : str, optional
- The z-axis sorting scheme passed onto `~.art3d.Poly3DCollection`
-
- shade : bool, default: True
- When true, this shades the dark sides of the bars (relative
- to the plot's source of light).
-
- lightsource : `~matplotlib.colors.LightSource`
- The lightsource to use when *shade* is True.
-
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Any additional keyword arguments are passed onto
- `~.art3d.Poly3DCollection`.
-
- Returns
- -------
- collection : `~.art3d.Poly3DCollection`
- A collection of three-dimensional polygons representing the bars.
- """
-
- had_data = self.has_data()
-
- x, y, z, dx, dy, dz = np.broadcast_arrays(
- np.atleast_1d(x), y, z, dx, dy, dz)
- minx = np.min(x)
- maxx = np.max(x + dx)
- miny = np.min(y)
- maxy = np.max(y + dy)
- minz = np.min(z)
- maxz = np.max(z + dz)
-
- # shape (6, 4, 3)
- # All faces are oriented facing outwards - when viewed from the
- # outside, their vertices are in a counterclockwise ordering.
- cuboid = np.array([
- # -z
- (
- (0, 0, 0),
- (0, 1, 0),
- (1, 1, 0),
- (1, 0, 0),
- ),
- # +z
- (
- (0, 0, 1),
- (1, 0, 1),
- (1, 1, 1),
- (0, 1, 1),
- ),
- # -y
- (
- (0, 0, 0),
- (1, 0, 0),
- (1, 0, 1),
- (0, 0, 1),
- ),
- # +y
- (
- (0, 1, 0),
- (0, 1, 1),
- (1, 1, 1),
- (1, 1, 0),
- ),
- # -x
- (
- (0, 0, 0),
- (0, 0, 1),
- (0, 1, 1),
- (0, 1, 0),
- ),
- # +x
- (
- (1, 0, 0),
- (1, 1, 0),
- (1, 1, 1),
- (1, 0, 1),
- ),
- ])
-
- # indexed by [bar, face, vertex, coord]
- polys = np.empty(x.shape + cuboid.shape)
-
- # handle each coordinate separately
- for i, p, dp in [(0, x, dx), (1, y, dy), (2, z, dz)]:
- p = p[..., np.newaxis, np.newaxis]
- dp = dp[..., np.newaxis, np.newaxis]
- polys[..., i] = p + dp * cuboid[..., i]
-
- # collapse the first two axes
- polys = polys.reshape((-1,) + polys.shape[2:])
-
- facecolors = []
- if color is None:
- color = [self._get_patches_for_fill.get_next_color()]
-
- color = list(mcolors.to_rgba_array(color))
-
- if len(color) == len(x):
- # bar colors specified, need to expand to number of faces
- for c in color:
- facecolors.extend([c] * 6)
- else:
- # a single color specified, or face colors specified explicitly
- facecolors = color
- if len(facecolors) < len(x):
- facecolors *= (6 * len(x))
-
- col = art3d.Poly3DCollection(polys,
- zsort=zsort,
- facecolors=facecolors,
- shade=shade,
- lightsource=lightsource,
- *args, **kwargs)
- self.add_collection(col)
-
- self.auto_scale_xyz((minx, maxx), (miny, maxy), (minz, maxz), had_data)
-
- return col
-
- def set_title(self, label, fontdict=None, loc='center', **kwargs):
- # docstring inherited
- ret = super().set_title(label, fontdict=fontdict, loc=loc, **kwargs)
- (x, y) = self.title.get_position()
- self.title.set_y(0.92 * y)
- return ret
-
- @_preprocess_data()
- def quiver(self, X, Y, Z, U, V, W, *,
- length=1, arrow_length_ratio=.3, pivot='tail', normalize=False,
- **kwargs):
- """
- Plot a 3D field of arrows.
-
- The arguments can be array-like or scalars, so long as they can be
- broadcast together. The arguments can also be masked arrays. If an
- element in any of argument is masked, then that corresponding quiver
- element will not be plotted.
-
- Parameters
- ----------
- X, Y, Z : array-like
- The x, y and z coordinates of the arrow locations (default is
- tail of arrow; see *pivot* kwarg).
-
- U, V, W : array-like
- The x, y and z components of the arrow vectors.
-
- length : float, default: 1
- The length of each quiver.
-
- arrow_length_ratio : float, default: 0.3
- The ratio of the arrow head with respect to the quiver.
-
- pivot : {'tail', 'middle', 'tip'}, default: 'tail'
- The part of the arrow that is at the grid point; the arrow
- rotates about this point, hence the name *pivot*.
-
- normalize : bool, default: False
- Whether all arrows are normalized to have the same length, or keep
- the lengths defined by *u*, *v*, and *w*.
-
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- Any additional keyword arguments are delegated to
- :class:`.Line3DCollection`
- """
-
- def calc_arrows(UVW):
- # get unit direction vector perpendicular to (u, v, w)
- x = UVW[:, 0]
- y = UVW[:, 1]
- norm = np.linalg.norm(UVW[:, :2], axis=1)
- x_p = np.divide(y, norm, where=norm != 0, out=np.zeros_like(x))
- y_p = np.divide(-x, norm, where=norm != 0, out=np.ones_like(x))
- # compute the two arrowhead direction unit vectors
- rangle = math.radians(15)
- c = math.cos(rangle)
- s = math.sin(rangle)
- # construct the rotation matrices of shape (3, 3, n)
- r13 = y_p * s
- r32 = x_p * s
- r12 = x_p * y_p * (1 - c)
- Rpos = np.array(
- [[c + (x_p ** 2) * (1 - c), r12, r13],
- [r12, c + (y_p ** 2) * (1 - c), -r32],
- [-r13, r32, np.full_like(x_p, c)]])
- # opposite rotation negates all the sin terms
- Rneg = Rpos.copy()
- Rneg[[0, 1, 2, 2], [2, 2, 0, 1]] *= -1
- # Batch n (3, 3) x (3) matrix multiplications ((3, 3, n) x (n, 3)).
- Rpos_vecs = np.einsum("ij...,...j->...i", Rpos, UVW)
- Rneg_vecs = np.einsum("ij...,...j->...i", Rneg, UVW)
- # Stack into (n, 2, 3) result.
- return np.stack([Rpos_vecs, Rneg_vecs], axis=1)
-
- had_data = self.has_data()
-
- input_args = [X, Y, Z, U, V, W]
-
- # extract the masks, if any
- masks = [k.mask for k in input_args
- if isinstance(k, np.ma.MaskedArray)]
- # broadcast to match the shape
- bcast = np.broadcast_arrays(*input_args, *masks)
- input_args = bcast[:6]
- masks = bcast[6:]
- if masks:
- # combine the masks into one
- mask = functools.reduce(np.logical_or, masks)
- # put mask on and compress
- input_args = [np.ma.array(k, mask=mask).compressed()
- for k in input_args]
- else:
- input_args = [np.ravel(k) for k in input_args]
-
- if any(len(v) == 0 for v in input_args):
- # No quivers, so just make an empty collection and return early
- linec = art3d.Line3DCollection([], **kwargs)
- self.add_collection(linec)
- return linec
-
- shaft_dt = np.array([0., length], dtype=float)
- arrow_dt = shaft_dt * arrow_length_ratio
-
- _api.check_in_list(['tail', 'middle', 'tip'], pivot=pivot)
- if pivot == 'tail':
- shaft_dt -= length
- elif pivot == 'middle':
- shaft_dt -= length / 2
-
- XYZ = np.column_stack(input_args[:3])
- UVW = np.column_stack(input_args[3:]).astype(float)
-
- # Normalize rows of UVW
- norm = np.linalg.norm(UVW, axis=1)
-
- # If any row of UVW is all zeros, don't make a quiver for it
- mask = norm > 0
- XYZ = XYZ[mask]
- if normalize:
- UVW = UVW[mask] / norm[mask].reshape((-1, 1))
- else:
- UVW = UVW[mask]
-
- if len(XYZ) > 0:
- # compute the shaft lines all at once with an outer product
- shafts = (XYZ - np.multiply.outer(shaft_dt, UVW)).swapaxes(0, 1)
- # compute head direction vectors, n heads x 2 sides x 3 dimensions
- head_dirs = calc_arrows(UVW)
- # compute all head lines at once, starting from the shaft ends
- heads = shafts[:, :1] - np.multiply.outer(arrow_dt, head_dirs)
- # stack left and right head lines together
- heads = heads.reshape((len(arrow_dt), -1, 3))
- # transpose to get a list of lines
- heads = heads.swapaxes(0, 1)
-
- lines = [*shafts, *heads]
- else:
- lines = []
-
- linec = art3d.Line3DCollection(lines, **kwargs)
- self.add_collection(linec)
-
- self.auto_scale_xyz(XYZ[:, 0], XYZ[:, 1], XYZ[:, 2], had_data)
-
- return linec
-
- quiver3D = quiver
-
- def voxels(self, *args, facecolors=None, edgecolors=None, shade=True,
- lightsource=None, **kwargs):
- """
- ax.voxels([x, y, z,] /, filled, facecolors=None, edgecolors=None, \
-**kwargs)
-
- Plot a set of filled voxels
-
- All voxels are plotted as 1x1x1 cubes on the axis, with
- ``filled[0, 0, 0]`` placed with its lower corner at the origin.
- Occluded faces are not plotted.
-
- Parameters
- ----------
- filled : 3D np.array of bool
- A 3D array of values, with truthy values indicating which voxels
- to fill
-
- x, y, z : 3D np.array, optional
- The coordinates of the corners of the voxels. This should broadcast
- to a shape one larger in every dimension than the shape of
- *filled*. These can be used to plot non-cubic voxels.
-
- If not specified, defaults to increasing integers along each axis,
- like those returned by :func:`~numpy.indices`.
- As indicated by the ``/`` in the function signature, these
- arguments can only be passed positionally.
-
- facecolors, edgecolors : array-like, optional
- The color to draw the faces and edges of the voxels. Can only be
- passed as keyword arguments.
- These parameters can be:
-
- - A single color value, to color all voxels the same color. This
- can be either a string, or a 1D RGB/RGBA array
- - ``None``, the default, to use a single color for the faces, and
- the style default for the edges.
- - A 3D `~numpy.ndarray` of color names, with each item the color
- for the corresponding voxel. The size must match the voxels.
- - A 4D `~numpy.ndarray` of RGB/RGBA data, with the components
- along the last axis.
-
- shade : bool, default: True
- Whether to shade the facecolors.
-
- lightsource : `~matplotlib.colors.LightSource`
- The lightsource to use when *shade* is True.
-
- **kwargs
- Additional keyword arguments to pass onto
- `~mpl_toolkits.mplot3d.art3d.Poly3DCollection`.
-
- Returns
- -------
- faces : dict
- A dictionary indexed by coordinate, where ``faces[i, j, k]`` is a
- `.Poly3DCollection` of the faces drawn for the voxel
- ``filled[i, j, k]``. If no faces were drawn for a given voxel,
- either because it was not asked to be drawn, or it is fully
- occluded, then ``(i, j, k) not in faces``.
-
- Examples
- --------
- .. plot:: gallery/mplot3d/voxels.py
- .. plot:: gallery/mplot3d/voxels_rgb.py
- .. plot:: gallery/mplot3d/voxels_torus.py
- .. plot:: gallery/mplot3d/voxels_numpy_logo.py
- """
-
- # work out which signature we should be using, and use it to parse
- # the arguments. Name must be voxels for the correct error message
- if len(args) >= 3:
- # underscores indicate position only
- def voxels(__x, __y, __z, filled, **kwargs):
- return (__x, __y, __z), filled, kwargs
- else:
- def voxels(filled, **kwargs):
- return None, filled, kwargs
-
- xyz, filled, kwargs = voxels(*args, **kwargs)
-
- # check dimensions
- if filled.ndim != 3:
- raise ValueError("Argument filled must be 3-dimensional")
- size = np.array(filled.shape, dtype=np.intp)
-
- # check xyz coordinates, which are one larger than the filled shape
- coord_shape = tuple(size + 1)
- if xyz is None:
- x, y, z = np.indices(coord_shape)
- else:
- x, y, z = (np.broadcast_to(c, coord_shape) for c in xyz)
-
- def _broadcast_color_arg(color, name):
- if np.ndim(color) in (0, 1):
- # single color, like "red" or [1, 0, 0]
- return np.broadcast_to(color, filled.shape + np.shape(color))
- elif np.ndim(color) in (3, 4):
- # 3D array of strings, or 4D array with last axis rgb
- if np.shape(color)[:3] != filled.shape:
- raise ValueError(
- f"When multidimensional, {name} must match the shape "
- "of filled")
- return color
- else:
- raise ValueError(f"Invalid {name} argument")
-
- # broadcast and default on facecolors
- if facecolors is None:
- facecolors = self._get_patches_for_fill.get_next_color()
- facecolors = _broadcast_color_arg(facecolors, 'facecolors')
-
- # broadcast but no default on edgecolors
- edgecolors = _broadcast_color_arg(edgecolors, 'edgecolors')
-
- # scale to the full array, even if the data is only in the center
- self.auto_scale_xyz(x, y, z)
-
- # points lying on corners of a square
- square = np.array([
- [0, 0, 0],
- [1, 0, 0],
- [1, 1, 0],
- [0, 1, 0],
- ], dtype=np.intp)
-
- voxel_faces = defaultdict(list)
-
- def permutation_matrices(n):
- """Generate cyclic permutation matrices."""
- mat = np.eye(n, dtype=np.intp)
- for i in range(n):
- yield mat
- mat = np.roll(mat, 1, axis=0)
-
- # iterate over each of the YZ, ZX, and XY orientations, finding faces
- # to render
- for permute in permutation_matrices(3):
- # find the set of ranges to iterate over
- pc, qc, rc = permute.T.dot(size)
- pinds = np.arange(pc)
- qinds = np.arange(qc)
- rinds = np.arange(rc)
-
- square_rot_pos = square.dot(permute.T)
- square_rot_neg = square_rot_pos[::-1]
-
- # iterate within the current plane
- for p in pinds:
- for q in qinds:
- # iterate perpendicularly to the current plane, handling
- # boundaries. We only draw faces between a voxel and an
- # empty space, to avoid drawing internal faces.
-
- # draw lower faces
- p0 = permute.dot([p, q, 0])
- i0 = tuple(p0)
- if filled[i0]:
- voxel_faces[i0].append(p0 + square_rot_neg)
-
- # draw middle faces
- for r1, r2 in zip(rinds[:-1], rinds[1:]):
- p1 = permute.dot([p, q, r1])
- p2 = permute.dot([p, q, r2])
-
- i1 = tuple(p1)
- i2 = tuple(p2)
-
- if filled[i1] and not filled[i2]:
- voxel_faces[i1].append(p2 + square_rot_pos)
- elif not filled[i1] and filled[i2]:
- voxel_faces[i2].append(p2 + square_rot_neg)
-
- # draw upper faces
- pk = permute.dot([p, q, rc-1])
- pk2 = permute.dot([p, q, rc])
- ik = tuple(pk)
- if filled[ik]:
- voxel_faces[ik].append(pk2 + square_rot_pos)
-
- # iterate over the faces, and generate a Poly3DCollection for each
- # voxel
- polygons = {}
- for coord, faces_inds in voxel_faces.items():
- # convert indices into 3D positions
- if xyz is None:
- faces = faces_inds
- else:
- faces = []
- for face_inds in faces_inds:
- ind = face_inds[:, 0], face_inds[:, 1], face_inds[:, 2]
- face = np.empty(face_inds.shape)
- face[:, 0] = x[ind]
- face[:, 1] = y[ind]
- face[:, 2] = z[ind]
- faces.append(face)
-
- # shade the faces
- facecolor = facecolors[coord]
- edgecolor = edgecolors[coord]
-
- poly = art3d.Poly3DCollection(
- faces, facecolors=facecolor, edgecolors=edgecolor,
- shade=shade, lightsource=lightsource, **kwargs)
- self.add_collection3d(poly)
- polygons[coord] = poly
-
- return polygons
-
- @_preprocess_data(replace_names=["x", "y", "z", "xerr", "yerr", "zerr"])
- def errorbar(self, x, y, z, zerr=None, yerr=None, xerr=None, fmt='',
- barsabove=False, errorevery=1, ecolor=None, elinewidth=None,
- capsize=None, capthick=None, xlolims=False, xuplims=False,
- ylolims=False, yuplims=False, zlolims=False, zuplims=False,
- **kwargs):
- """
- Plot lines and/or markers with errorbars around them.
-
- *x*/*y*/*z* define the data locations, and *xerr*/*yerr*/*zerr* define
- the errorbar sizes. By default, this draws the data markers/lines as
- well the errorbars. Use fmt='none' to draw errorbars only.
-
- Parameters
- ----------
- x, y, z : float or array-like
- The data positions.
-
- xerr, yerr, zerr : float or array-like, shape (N,) or (2, N), optional
- The errorbar sizes:
-
- - scalar: Symmetric +/- values for all data points.
- - shape(N,): Symmetric +/-values for each data point.
- - shape(2, N): Separate - and + values for each bar. First row
- contains the lower errors, the second row contains the upper
- errors.
- - *None*: No errorbar.
-
- Note that all error arrays should have *positive* values.
-
- fmt : str, default: ''
- The format for the data points / data lines. See `.plot` for
- details.
-
- Use 'none' (case-insensitive) to plot errorbars without any data
- markers.
-
- ecolor : color, default: None
- The color of the errorbar lines. If None, use the color of the
- line connecting the markers.
-
- elinewidth : float, default: None
- The linewidth of the errorbar lines. If None, the linewidth of
- the current style is used.
-
- capsize : float, default: :rc:`errorbar.capsize`
- The length of the error bar caps in points.
-
- capthick : float, default: None
- An alias to the keyword argument *markeredgewidth* (a.k.a. *mew*).
- This setting is a more sensible name for the property that
- controls the thickness of the error bar cap in points. For
- backwards compatibility, if *mew* or *markeredgewidth* are given,
- then they will over-ride *capthick*. This may change in future
- releases.
-
- barsabove : bool, default: False
- If True, will plot the errorbars above the plot
- symbols. Default is below.
-
- xlolims, ylolims, zlolims : bool, default: False
- These arguments can be used to indicate that a value gives only
- lower limits. In that case a caret symbol is used to indicate
- this. *lims*-arguments may be scalars, or array-likes of the same
- length as the errors. To use limits with inverted axes,
- `~.Axes.set_xlim` or `~.Axes.set_ylim` must be called before
- `errorbar`. Note the tricky parameter names: setting e.g.
- *ylolims* to True means that the y-value is a *lower* limit of the
- True value, so, only an *upward*-pointing arrow will be drawn!
-
- xuplims, yuplims, zuplims : bool, default: False
- Same as above, but for controlling the upper limits.
-
- errorevery : int or (int, int), default: 1
- draws error bars on a subset of the data. *errorevery* =N draws
- error bars on the points (x[::N], y[::N], z[::N]).
- *errorevery* =(start, N) draws error bars on the points
- (x[start::N], y[start::N], z[start::N]). e.g. *errorevery* =(6, 3)
- adds error bars to the data at (x[6], x[9], x[12], x[15], ...).
- Used to avoid overlapping error bars when two series share x-axis
- values.
-
- Returns
- -------
- errlines : list
- List of `~mpl_toolkits.mplot3d.art3d.Line3DCollection` instances
- each containing an errorbar line.
- caplines : list
- List of `~mpl_toolkits.mplot3d.art3d.Line3D` instances each
- containing a capline object.
- limmarks : list
- List of `~mpl_toolkits.mplot3d.art3d.Line3D` instances each
- containing a marker with an upper or lower limit.
-
- Other Parameters
- ----------------
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- **kwargs
- All other keyword arguments for styling errorbar lines are passed
- `~mpl_toolkits.mplot3d.art3d.Line3DCollection`.
-
- Examples
- --------
- .. plot:: gallery/mplot3d/errorbar3d.py
- """
- had_data = self.has_data()
-
- kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
- # Drop anything that comes in as None to use the default instead.
- kwargs = {k: v for k, v in kwargs.items() if v is not None}
- kwargs.setdefault('zorder', 2)
-
- self._process_unit_info([("x", x), ("y", y), ("z", z)], kwargs,
- convert=False)
-
- # make sure all the args are iterable; use lists not arrays to
- # preserve units
- x = x if np.iterable(x) else [x]
- y = y if np.iterable(y) else [y]
- z = z if np.iterable(z) else [z]
-
- if not len(x) == len(y) == len(z):
- raise ValueError("'x', 'y', and 'z' must have the same size")
-
- everymask = self._errorevery_to_mask(x, errorevery)
-
- label = kwargs.pop("label", None)
- kwargs['label'] = '_nolegend_'
-
- # Create the main line and determine overall kwargs for child artists.
- # We avoid calling self.plot() directly, or self._get_lines(), because
- # that would call self._process_unit_info again, and do other indirect
- # data processing.
- (data_line, base_style), = self._get_lines._plot_args(
- self, (x, y) if fmt == '' else (x, y, fmt), kwargs, return_kwargs=True)
- art3d.line_2d_to_3d(data_line, zs=z)
-
- # Do this after creating `data_line` to avoid modifying `base_style`.
- if barsabove:
- data_line.set_zorder(kwargs['zorder'] - .1)
- else:
- data_line.set_zorder(kwargs['zorder'] + .1)
-
- # Add line to plot, or throw it away and use it to determine kwargs.
- if fmt.lower() != 'none':
- self.add_line(data_line)
- else:
- data_line = None
- # Remove alpha=0 color that _process_plot_format returns.
- base_style.pop('color')
-
- if 'color' not in base_style:
- base_style['color'] = 'C0'
- if ecolor is None:
- ecolor = base_style['color']
-
- # Eject any line-specific information from format string, as it's not
- # needed for bars or caps.
- for key in ['marker', 'markersize', 'markerfacecolor',
- 'markeredgewidth', 'markeredgecolor', 'markevery',
- 'linestyle', 'fillstyle', 'drawstyle', 'dash_capstyle',
- 'dash_joinstyle', 'solid_capstyle', 'solid_joinstyle']:
- base_style.pop(key, None)
-
- # Make the style dict for the line collections (the bars).
- eb_lines_style = {**base_style, 'color': ecolor}
-
- if elinewidth:
- eb_lines_style['linewidth'] = elinewidth
- elif 'linewidth' in kwargs:
- eb_lines_style['linewidth'] = kwargs['linewidth']
-
- for key in ('transform', 'alpha', 'zorder', 'rasterized'):
- if key in kwargs:
- eb_lines_style[key] = kwargs[key]
-
- # Make the style dict for caps (the "hats").
- eb_cap_style = {**base_style, 'linestyle': 'None'}
- if capsize is None:
- capsize = mpl.rcParams["errorbar.capsize"]
- if capsize > 0:
- eb_cap_style['markersize'] = 2. * capsize
- if capthick is not None:
- eb_cap_style['markeredgewidth'] = capthick
- eb_cap_style['color'] = ecolor
-
- def _apply_mask(arrays, mask):
- # Return, for each array in *arrays*, the elements for which *mask*
- # is True, without using fancy indexing.
- return [[*itertools.compress(array, mask)] for array in arrays]
-
- def _extract_errs(err, data, lomask, himask):
- # For separate +/- error values we need to unpack err
- if len(err.shape) == 2:
- low_err, high_err = err
- else:
- low_err, high_err = err, err
-
- lows = np.where(lomask | ~everymask, data, data - low_err)
- highs = np.where(himask | ~everymask, data, data + high_err)
-
- return lows, highs
-
- # collect drawn items while looping over the three coordinates
- errlines, caplines, limmarks = [], [], []
-
- # list of endpoint coordinates, used for auto-scaling
- coorderrs = []
-
- # define the markers used for errorbar caps and limits below
- # the dictionary key is mapped by the `i_xyz` helper dictionary
- capmarker = {0: '|', 1: '|', 2: '_'}
- i_xyz = {'x': 0, 'y': 1, 'z': 2}
-
- # Calculate marker size from points to quiver length. Because these are
- # not markers, and 3D Axes do not use the normal transform stack, this
- # is a bit involved. Since the quiver arrows will change size as the
- # scene is rotated, they are given a standard size based on viewing
- # them directly in planar form.
- quiversize = eb_cap_style.get('markersize',
- mpl.rcParams['lines.markersize']) ** 2
- quiversize *= self.figure.dpi / 72
- quiversize = self.transAxes.inverted().transform([
- (0, 0), (quiversize, quiversize)])
- quiversize = np.mean(np.diff(quiversize, axis=0))
- # quiversize is now in Axes coordinates, and to convert back to data
- # coordinates, we need to run it through the inverse 3D transform. For
- # consistency, this uses a fixed elevation, azimuth, and roll.
- with cbook._setattr_cm(self, elev=0, azim=0, roll=0):
- invM = np.linalg.inv(self.get_proj())
- # elev=azim=roll=0 produces the Y-Z plane, so quiversize in 2D 'x' is
- # 'y' in 3D, hence the 1 index.
- quiversize = np.dot(invM, [quiversize, 0, 0, 0])[1]
- # Quivers use a fixed 15-degree arrow head, so scale up the length so
- # that the size corresponds to the base. In other words, this constant
- # corresponds to the equation tan(15) = (base / 2) / (arrow length).
- quiversize *= 1.8660254037844388
- eb_quiver_style = {**eb_cap_style,
- 'length': quiversize, 'arrow_length_ratio': 1}
- eb_quiver_style.pop('markersize', None)
-
- # loop over x-, y-, and z-direction and draw relevant elements
- for zdir, data, err, lolims, uplims in zip(
- ['x', 'y', 'z'], [x, y, z], [xerr, yerr, zerr],
- [xlolims, ylolims, zlolims], [xuplims, yuplims, zuplims]):
-
- dir_vector = art3d.get_dir_vector(zdir)
- i_zdir = i_xyz[zdir]
-
- if err is None:
- continue
-
- if not np.iterable(err):
- err = [err] * len(data)
-
- err = np.atleast_1d(err)
-
- # arrays fine here, they are booleans and hence not units
- lolims = np.broadcast_to(lolims, len(data)).astype(bool)
- uplims = np.broadcast_to(uplims, len(data)).astype(bool)
-
- # a nested list structure that expands to (xl,xh),(yl,yh),(zl,zh),
- # where x/y/z and l/h correspond to dimensions and low/high
- # positions of errorbars in a dimension we're looping over
- coorderr = [
- _extract_errs(err * dir_vector[i], coord, lolims, uplims)
- for i, coord in enumerate([x, y, z])]
- (xl, xh), (yl, yh), (zl, zh) = coorderr
-
- # draws capmarkers - flat caps orthogonal to the error bars
- nolims = ~(lolims | uplims)
- if nolims.any() and capsize > 0:
- lo_caps_xyz = _apply_mask([xl, yl, zl], nolims & everymask)
- hi_caps_xyz = _apply_mask([xh, yh, zh], nolims & everymask)
-
- # setting '_' for z-caps and '|' for x- and y-caps;
- # these markers will rotate as the viewing angle changes
- cap_lo = art3d.Line3D(*lo_caps_xyz, ls='',
- marker=capmarker[i_zdir],
- **eb_cap_style)
- cap_hi = art3d.Line3D(*hi_caps_xyz, ls='',
- marker=capmarker[i_zdir],
- **eb_cap_style)
- self.add_line(cap_lo)
- self.add_line(cap_hi)
- caplines.append(cap_lo)
- caplines.append(cap_hi)
-
- if lolims.any():
- xh0, yh0, zh0 = _apply_mask([xh, yh, zh], lolims & everymask)
- self.quiver(xh0, yh0, zh0, *dir_vector, **eb_quiver_style)
- if uplims.any():
- xl0, yl0, zl0 = _apply_mask([xl, yl, zl], uplims & everymask)
- self.quiver(xl0, yl0, zl0, *-dir_vector, **eb_quiver_style)
-
- errline = art3d.Line3DCollection(np.array(coorderr).T,
- **eb_lines_style)
- self.add_collection(errline)
- errlines.append(errline)
- coorderrs.append(coorderr)
-
- coorderrs = np.array(coorderrs)
-
- def _digout_minmax(err_arr, coord_label):
- return (np.nanmin(err_arr[:, i_xyz[coord_label], :, :]),
- np.nanmax(err_arr[:, i_xyz[coord_label], :, :]))
-
- minx, maxx = _digout_minmax(coorderrs, 'x')
- miny, maxy = _digout_minmax(coorderrs, 'y')
- minz, maxz = _digout_minmax(coorderrs, 'z')
- self.auto_scale_xyz((minx, maxx), (miny, maxy), (minz, maxz), had_data)
-
- # Adapting errorbar containers for 3d case, assuming z-axis points "up"
- errorbar_container = mcontainer.ErrorbarContainer(
- (data_line, tuple(caplines), tuple(errlines)),
- has_xerr=(xerr is not None or yerr is not None),
- has_yerr=(zerr is not None),
- label=label)
- self.containers.append(errorbar_container)
-
- return errlines, caplines, limmarks
-
- @_api.make_keyword_only("3.8", "call_axes_locator")
- def get_tightbbox(self, renderer=None, call_axes_locator=True,
- bbox_extra_artists=None, *, for_layout_only=False):
- ret = super().get_tightbbox(renderer,
- call_axes_locator=call_axes_locator,
- bbox_extra_artists=bbox_extra_artists,
- for_layout_only=for_layout_only)
- batch = [ret]
- if self._axis3don:
- for axis in self._axis_map.values():
- if axis.get_visible():
- axis_bb = martist._get_tightbbox_for_layout_only(
- axis, renderer)
- if axis_bb:
- batch.append(axis_bb)
- return mtransforms.Bbox.union(batch)
-
- @_preprocess_data()
- def stem(self, x, y, z, *, linefmt='C0-', markerfmt='C0o', basefmt='C3-',
- bottom=0, label=None, orientation='z'):
- """
- Create a 3D stem plot.
-
- A stem plot draws lines perpendicular to a baseline, and places markers
- at the heads. By default, the baseline is defined by *x* and *y*, and
- stems are drawn vertically from *bottom* to *z*.
-
- Parameters
- ----------
- x, y, z : array-like
- The positions of the heads of the stems. The stems are drawn along
- the *orientation*-direction from the baseline at *bottom* (in the
- *orientation*-coordinate) to the heads. By default, the *x* and *y*
- positions are used for the baseline and *z* for the head position,
- but this can be changed by *orientation*.
-
- linefmt : str, default: 'C0-'
- A string defining the properties of the vertical lines. Usually,
- this will be a color or a color and a linestyle:
-
- ========= =============
- Character Line Style
- ========= =============
- ``'-'`` solid line
- ``'--'`` dashed line
- ``'-.'`` dash-dot line
- ``':'`` dotted line
- ========= =============
-
- Note: While it is technically possible to specify valid formats
- other than color or color and linestyle (e.g. 'rx' or '-.'), this
- is beyond the intention of the method and will most likely not
- result in a reasonable plot.
-
- markerfmt : str, default: 'C0o'
- A string defining the properties of the markers at the stem heads.
-
- basefmt : str, default: 'C3-'
- A format string defining the properties of the baseline.
-
- bottom : float, default: 0
- The position of the baseline, in *orientation*-coordinates.
-
- label : str, default: None
- The label to use for the stems in legends.
-
- orientation : {'x', 'y', 'z'}, default: 'z'
- The direction along which stems are drawn.
-
- data : indexable object, optional
- DATA_PARAMETER_PLACEHOLDER
-
- Returns
- -------
- `.StemContainer`
- The container may be treated like a tuple
- (*markerline*, *stemlines*, *baseline*)
-
- Examples
- --------
- .. plot:: gallery/mplot3d/stem3d_demo.py
- """
-
- from matplotlib.container import StemContainer
-
- had_data = self.has_data()
-
- _api.check_in_list(['x', 'y', 'z'], orientation=orientation)
-
- xlim = (np.min(x), np.max(x))
- ylim = (np.min(y), np.max(y))
- zlim = (np.min(z), np.max(z))
-
- # Determine the appropriate plane for the baseline and the direction of
- # stemlines based on the value of orientation.
- if orientation == 'x':
- basex, basexlim = y, ylim
- basey, baseylim = z, zlim
- lines = [[(bottom, thisy, thisz), (thisx, thisy, thisz)]
- for thisx, thisy, thisz in zip(x, y, z)]
- elif orientation == 'y':
- basex, basexlim = x, xlim
- basey, baseylim = z, zlim
- lines = [[(thisx, bottom, thisz), (thisx, thisy, thisz)]
- for thisx, thisy, thisz in zip(x, y, z)]
- else:
- basex, basexlim = x, xlim
- basey, baseylim = y, ylim
- lines = [[(thisx, thisy, bottom), (thisx, thisy, thisz)]
- for thisx, thisy, thisz in zip(x, y, z)]
-
- # Determine style for stem lines.
- linestyle, linemarker, linecolor = _process_plot_format(linefmt)
- if linestyle is None:
- linestyle = mpl.rcParams['lines.linestyle']
-
- # Plot everything in required order.
- baseline, = self.plot(basex, basey, basefmt, zs=bottom,
- zdir=orientation, label='_nolegend_')
- stemlines = art3d.Line3DCollection(
- lines, linestyles=linestyle, colors=linecolor, label='_nolegend_')
- self.add_collection(stemlines)
- markerline, = self.plot(x, y, z, markerfmt, label='_nolegend_')
-
- stem_container = StemContainer((markerline, stemlines, baseline),
- label=label)
- self.add_container(stem_container)
-
- jx, jy, jz = art3d.juggle_axes(basexlim, baseylim, [bottom, bottom],
- orientation)
- self.auto_scale_xyz([*jx, *xlim], [*jy, *ylim], [*jz, *zlim], had_data)
-
- return stem_container
-
- stem3D = stem
-
-
-def get_test_data(delta=0.05):
- """Return a tuple X, Y, Z with a test data set."""
- x = y = np.arange(-3.0, 3.0, delta)
- X, Y = np.meshgrid(x, y)
-
- Z1 = np.exp(-(X**2 + Y**2) / 2) / (2 * np.pi)
- Z2 = (np.exp(-(((X - 1) / 1.5)**2 + ((Y - 1) / 0.5)**2) / 2) /
- (2 * np.pi * 0.5 * 1.5))
- Z = Z2 - Z1
-
- X = X * 10
- Y = Y * 10
- Z = Z * 500
- return X, Y, Z
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/axis3d.py b/contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/axis3d.py
deleted file mode 100644
index 4c5fa8a9c9..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/axis3d.py
+++ /dev/null
@@ -1,753 +0,0 @@
-# axis3d.py, original mplot3d version by John Porter
-# Created: 23 Sep 2005
-# Parts rewritten by Reinier Heeres <reinier@heeres.eu>
-
-import inspect
-
-import numpy as np
-
-import matplotlib as mpl
-from matplotlib import (
- _api, artist, lines as mlines, axis as maxis, patches as mpatches,
- transforms as mtransforms, colors as mcolors)
-from . import art3d, proj3d
-
-
-def _move_from_center(coord, centers, deltas, axmask=(True, True, True)):
- """
- For each coordinate where *axmask* is True, move *coord* away from
- *centers* by *deltas*.
- """
- coord = np.asarray(coord)
- return coord + axmask * np.copysign(1, coord - centers) * deltas
-
-
-def _tick_update_position(tick, tickxs, tickys, labelpos):
- """Update tick line and label position and style."""
-
- tick.label1.set_position(labelpos)
- tick.label2.set_position(labelpos)
- tick.tick1line.set_visible(True)
- tick.tick2line.set_visible(False)
- tick.tick1line.set_linestyle('-')
- tick.tick1line.set_marker('')
- tick.tick1line.set_data(tickxs, tickys)
- tick.gridline.set_data([0], [0])
-
-
-class Axis(maxis.XAxis):
- """An Axis class for the 3D plots."""
- # These points from the unit cube make up the x, y and z-planes
- _PLANES = (
- (0, 3, 7, 4), (1, 2, 6, 5), # yz planes
- (0, 1, 5, 4), (3, 2, 6, 7), # xz planes
- (0, 1, 2, 3), (4, 5, 6, 7), # xy planes
- )
-
- # Some properties for the axes
- _AXINFO = {
- 'x': {'i': 0, 'tickdir': 1, 'juggled': (1, 0, 2)},
- 'y': {'i': 1, 'tickdir': 0, 'juggled': (0, 1, 2)},
- 'z': {'i': 2, 'tickdir': 0, 'juggled': (0, 2, 1)},
- }
-
- def _old_init(self, adir, v_intervalx, d_intervalx, axes, *args,
- rotate_label=None, **kwargs):
- return locals()
-
- def _new_init(self, axes, *, rotate_label=None, **kwargs):
- return locals()
-
- def __init__(self, *args, **kwargs):
- params = _api.select_matching_signature(
- [self._old_init, self._new_init], *args, **kwargs)
- if "adir" in params:
- _api.warn_deprecated(
- "3.6", message=f"The signature of 3D Axis constructors has "
- f"changed in %(since)s; the new signature is "
- f"{inspect.signature(type(self).__init__)}", pending=True)
- if params["adir"] != self.axis_name:
- raise ValueError(f"Cannot instantiate {type(self).__name__} "
- f"with adir={params['adir']!r}")
- axes = params["axes"]
- rotate_label = params["rotate_label"]
- args = params.get("args", ())
- kwargs = params["kwargs"]
-
- name = self.axis_name
-
- self._label_position = 'default'
- self._tick_position = 'default'
-
- # This is a temporary member variable.
- # Do not depend on this existing in future releases!
- self._axinfo = self._AXINFO[name].copy()
- # Common parts
- self._axinfo.update({
- 'label': {'va': 'center', 'ha': 'center',
- 'rotation_mode': 'anchor'},
- 'color': mpl.rcParams[f'axes3d.{name}axis.panecolor'],
- 'tick': {
- 'inward_factor': 0.2,
- 'outward_factor': 0.1,
- },
- })
-
- if mpl.rcParams['_internal.classic_mode']:
- self._axinfo.update({
- 'axisline': {'linewidth': 0.75, 'color': (0, 0, 0, 1)},
- 'grid': {
- 'color': (0.9, 0.9, 0.9, 1),
- 'linewidth': 1.0,
- 'linestyle': '-',
- },
- })
- self._axinfo['tick'].update({
- 'linewidth': {
- True: mpl.rcParams['lines.linewidth'], # major
- False: mpl.rcParams['lines.linewidth'], # minor
- }
- })
- else:
- self._axinfo.update({
- 'axisline': {
- 'linewidth': mpl.rcParams['axes.linewidth'],
- 'color': mpl.rcParams['axes.edgecolor'],
- },
- 'grid': {
- 'color': mpl.rcParams['grid.color'],
- 'linewidth': mpl.rcParams['grid.linewidth'],
- 'linestyle': mpl.rcParams['grid.linestyle'],
- },
- })
- self._axinfo['tick'].update({
- 'linewidth': {
- True: ( # major
- mpl.rcParams['xtick.major.width'] if name in 'xz'
- else mpl.rcParams['ytick.major.width']),
- False: ( # minor
- mpl.rcParams['xtick.minor.width'] if name in 'xz'
- else mpl.rcParams['ytick.minor.width']),
- }
- })
-
- super().__init__(axes, *args, **kwargs)
-
- # data and viewing intervals for this direction
- if "d_intervalx" in params:
- self.set_data_interval(*params["d_intervalx"])
- if "v_intervalx" in params:
- self.set_view_interval(*params["v_intervalx"])
- self.set_rotate_label(rotate_label)
- self._init3d() # Inline after init3d deprecation elapses.
-
- __init__.__signature__ = inspect.signature(_new_init)
- adir = _api.deprecated("3.6", pending=True)(
- property(lambda self: self.axis_name))
-
- def _init3d(self):
- self.line = mlines.Line2D(
- xdata=(0, 0), ydata=(0, 0),
- linewidth=self._axinfo['axisline']['linewidth'],
- color=self._axinfo['axisline']['color'],
- antialiased=True)
-
- # Store dummy data in Polygon object
- self.pane = mpatches.Polygon([[0, 0], [0, 1]], closed=False)
- self.set_pane_color(self._axinfo['color'])
-
- self.axes._set_artist_props(self.line)
- self.axes._set_artist_props(self.pane)
- self.gridlines = art3d.Line3DCollection([])
- self.axes._set_artist_props(self.gridlines)
- self.axes._set_artist_props(self.label)
- self.axes._set_artist_props(self.offsetText)
- # Need to be able to place the label at the correct location
- self.label._transform = self.axes.transData
- self.offsetText._transform = self.axes.transData
-
- @_api.deprecated("3.6", pending=True)
- def init3d(self): # After deprecation elapses, inline _init3d to __init__.
- self._init3d()
-
- def get_major_ticks(self, numticks=None):
- ticks = super().get_major_ticks(numticks)
- for t in ticks:
- for obj in [
- t.tick1line, t.tick2line, t.gridline, t.label1, t.label2]:
- obj.set_transform(self.axes.transData)
- return ticks
-
- def get_minor_ticks(self, numticks=None):
- ticks = super().get_minor_ticks(numticks)
- for t in ticks:
- for obj in [
- t.tick1line, t.tick2line, t.gridline, t.label1, t.label2]:
- obj.set_transform(self.axes.transData)
- return ticks
-
- def set_ticks_position(self, position):
- """
- Set the ticks position.
-
- Parameters
- ----------
- position : {'lower', 'upper', 'both', 'default', 'none'}
- The position of the bolded axis lines, ticks, and tick labels.
- """
- if position in ['top', 'bottom']:
- _api.warn_deprecated('3.8', name=f'{position=}',
- obj_type='argument value',
- alternative="'upper' or 'lower'")
- return
- _api.check_in_list(['lower', 'upper', 'both', 'default', 'none'],
- position=position)
- self._tick_position = position
-
- def get_ticks_position(self):
- """
- Get the ticks position.
-
- Returns
- -------
- str : {'lower', 'upper', 'both', 'default', 'none'}
- The position of the bolded axis lines, ticks, and tick labels.
- """
- return self._tick_position
-
- def set_label_position(self, position):
- """
- Set the label position.
-
- Parameters
- ----------
- position : {'lower', 'upper', 'both', 'default', 'none'}
- The position of the axis label.
- """
- if position in ['top', 'bottom']:
- _api.warn_deprecated('3.8', name=f'{position=}',
- obj_type='argument value',
- alternative="'upper' or 'lower'")
- return
- _api.check_in_list(['lower', 'upper', 'both', 'default', 'none'],
- position=position)
- self._label_position = position
-
- def get_label_position(self):
- """
- Get the label position.
-
- Returns
- -------
- str : {'lower', 'upper', 'both', 'default', 'none'}
- The position of the axis label.
- """
- return self._label_position
-
- def set_pane_color(self, color, alpha=None):
- """
- Set pane color.
-
- Parameters
- ----------
- color : color
- Color for axis pane.
- alpha : float, optional
- Alpha value for axis pane. If None, base it on *color*.
- """
- color = mcolors.to_rgba(color, alpha)
- self._axinfo['color'] = color
- self.pane.set_edgecolor(color)
- self.pane.set_facecolor(color)
- self.pane.set_alpha(color[-1])
- self.stale = True
-
- def set_rotate_label(self, val):
- """
- Whether to rotate the axis label: True, False or None.
- If set to None the label will be rotated if longer than 4 chars.
- """
- self._rotate_label = val
- self.stale = True
-
- def get_rotate_label(self, text):
- if self._rotate_label is not None:
- return self._rotate_label
- else:
- return len(text) > 4
-
- def _get_coord_info(self, renderer):
- mins, maxs = np.array([
- self.axes.get_xbound(),
- self.axes.get_ybound(),
- self.axes.get_zbound(),
- ]).T
-
- # Get the mean value for each bound:
- centers = 0.5 * (maxs + mins)
-
- # Add a small offset between min/max point and the edge of the plot:
- deltas = (maxs - mins) / 12
- mins -= 0.25 * deltas
- maxs += 0.25 * deltas
-
- # Project the bounds along the current position of the cube:
- bounds = mins[0], maxs[0], mins[1], maxs[1], mins[2], maxs[2]
- bounds_proj = self.axes._tunit_cube(bounds, self.axes.M)
-
- # Determine which one of the parallel planes are higher up:
- means_z0 = np.zeros(3)
- means_z1 = np.zeros(3)
- for i in range(3):
- means_z0[i] = np.mean(bounds_proj[self._PLANES[2 * i], 2])
- means_z1[i] = np.mean(bounds_proj[self._PLANES[2 * i + 1], 2])
- highs = means_z0 < means_z1
-
- # Special handling for edge-on views
- equals = np.abs(means_z0 - means_z1) <= np.finfo(float).eps
- if np.sum(equals) == 2:
- vertical = np.where(~equals)[0][0]
- if vertical == 2: # looking at XY plane
- highs = np.array([True, True, highs[2]])
- elif vertical == 1: # looking at XZ plane
- highs = np.array([True, highs[1], False])
- elif vertical == 0: # looking at YZ plane
- highs = np.array([highs[0], False, False])
-
- return mins, maxs, centers, deltas, bounds_proj, highs
-
- def _get_axis_line_edge_points(self, minmax, maxmin, position=None):
- """Get the edge points for the black bolded axis line."""
- # When changing vertical axis some of the axes has to be
- # moved to the other plane so it looks the same as if the z-axis
- # was the vertical axis.
- mb = [minmax, maxmin] # line from origin to nearest corner to camera
- mb_rev = mb[::-1]
- mm = [[mb, mb_rev, mb_rev], [mb_rev, mb_rev, mb], [mb, mb, mb]]
- mm = mm[self.axes._vertical_axis][self._axinfo["i"]]
-
- juggled = self._axinfo["juggled"]
- edge_point_0 = mm[0].copy() # origin point
-
- if ((position == 'lower' and mm[1][juggled[-1]] < mm[0][juggled[-1]]) or
- (position == 'upper' and mm[1][juggled[-1]] > mm[0][juggled[-1]])):
- edge_point_0[juggled[-1]] = mm[1][juggled[-1]]
- else:
- edge_point_0[juggled[0]] = mm[1][juggled[0]]
-
- edge_point_1 = edge_point_0.copy()
- edge_point_1[juggled[1]] = mm[1][juggled[1]]
-
- return edge_point_0, edge_point_1
-
- def _get_all_axis_line_edge_points(self, minmax, maxmin, axis_position=None):
- # Determine edge points for the axis lines
- edgep1s = []
- edgep2s = []
- position = []
- if axis_position in (None, 'default'):
- edgep1, edgep2 = self._get_axis_line_edge_points(minmax, maxmin)
- edgep1s = [edgep1]
- edgep2s = [edgep2]
- position = ['default']
- else:
- edgep1_l, edgep2_l = self._get_axis_line_edge_points(minmax, maxmin,
- position='lower')
- edgep1_u, edgep2_u = self._get_axis_line_edge_points(minmax, maxmin,
- position='upper')
- if axis_position in ('lower', 'both'):
- edgep1s.append(edgep1_l)
- edgep2s.append(edgep2_l)
- position.append('lower')
- if axis_position in ('upper', 'both'):
- edgep1s.append(edgep1_u)
- edgep2s.append(edgep2_u)
- position.append('upper')
- return edgep1s, edgep2s, position
-
- def _get_tickdir(self, position):
- """
- Get the direction of the tick.
-
- Parameters
- ----------
- position : str, optional : {'upper', 'lower', 'default'}
- The position of the axis.
-
- Returns
- -------
- tickdir : int
- Index which indicates which coordinate the tick line will
- align with.
- """
- _api.check_in_list(('upper', 'lower', 'default'), position=position)
-
- # TODO: Move somewhere else where it's triggered less:
- tickdirs_base = [v["tickdir"] for v in self._AXINFO.values()] # default
- elev_mod = np.mod(self.axes.elev + 180, 360) - 180
- azim_mod = np.mod(self.axes.azim, 360)
- if position == 'upper':
- if elev_mod >= 0:
- tickdirs_base = [2, 2, 0]
- else:
- tickdirs_base = [1, 0, 0]
- if 0 <= azim_mod < 180:
- tickdirs_base[2] = 1
- elif position == 'lower':
- if elev_mod >= 0:
- tickdirs_base = [1, 0, 1]
- else:
- tickdirs_base = [2, 2, 1]
- if 0 <= azim_mod < 180:
- tickdirs_base[2] = 0
- info_i = [v["i"] for v in self._AXINFO.values()]
-
- i = self._axinfo["i"]
- vert_ax = self.axes._vertical_axis
- j = vert_ax - 2
- # default: tickdir = [[1, 2, 1], [2, 2, 0], [1, 0, 0]][vert_ax][i]
- tickdir = np.roll(info_i, -j)[np.roll(tickdirs_base, j)][i]
- return tickdir
-
- def active_pane(self, renderer):
- mins, maxs, centers, deltas, tc, highs = self._get_coord_info(renderer)
- info = self._axinfo
- index = info['i']
- if not highs[index]:
- loc = mins[index]
- plane = self._PLANES[2 * index]
- else:
- loc = maxs[index]
- plane = self._PLANES[2 * index + 1]
- xys = np.array([tc[p] for p in plane])
- return xys, loc
-
- def draw_pane(self, renderer):
- """
- Draw pane.
-
- Parameters
- ----------
- renderer : `~matplotlib.backend_bases.RendererBase` subclass
- """
- renderer.open_group('pane3d', gid=self.get_gid())
- xys, loc = self.active_pane(renderer)
- self.pane.xy = xys[:, :2]
- self.pane.draw(renderer)
- renderer.close_group('pane3d')
-
- def _axmask(self):
- axmask = [True, True, True]
- axmask[self._axinfo["i"]] = False
- return axmask
-
- def _draw_ticks(self, renderer, edgep1, centers, deltas, highs,
- deltas_per_point, pos):
- ticks = self._update_ticks()
- info = self._axinfo
- index = info["i"]
-
- # Draw ticks:
- tickdir = self._get_tickdir(pos)
- tickdelta = deltas[tickdir] if highs[tickdir] else -deltas[tickdir]
-
- tick_info = info['tick']
- tick_out = tick_info['outward_factor'] * tickdelta
- tick_in = tick_info['inward_factor'] * tickdelta
- tick_lw = tick_info['linewidth']
- edgep1_tickdir = edgep1[tickdir]
- out_tickdir = edgep1_tickdir + tick_out
- in_tickdir = edgep1_tickdir - tick_in
-
- default_label_offset = 8. # A rough estimate
- points = deltas_per_point * deltas
- for tick in ticks:
- # Get tick line positions
- pos = edgep1.copy()
- pos[index] = tick.get_loc()
- pos[tickdir] = out_tickdir
- x1, y1, z1 = proj3d.proj_transform(*pos, self.axes.M)
- pos[tickdir] = in_tickdir
- x2, y2, z2 = proj3d.proj_transform(*pos, self.axes.M)
-
- # Get position of label
- labeldeltas = (tick.get_pad() + default_label_offset) * points
-
- pos[tickdir] = edgep1_tickdir
- pos = _move_from_center(pos, centers, labeldeltas, self._axmask())
- lx, ly, lz = proj3d.proj_transform(*pos, self.axes.M)
-
- _tick_update_position(tick, (x1, x2), (y1, y2), (lx, ly))
- tick.tick1line.set_linewidth(tick_lw[tick._major])
- tick.draw(renderer)
-
- def _draw_offset_text(self, renderer, edgep1, edgep2, labeldeltas, centers,
- highs, pep, dx, dy):
- # Get general axis information:
- info = self._axinfo
- index = info["i"]
- juggled = info["juggled"]
- tickdir = info["tickdir"]
-
- # Which of the two edge points do we want to
- # use for locating the offset text?
- if juggled[2] == 2:
- outeredgep = edgep1
- outerindex = 0
- else:
- outeredgep = edgep2
- outerindex = 1
-
- pos = _move_from_center(outeredgep, centers, labeldeltas,
- self._axmask())
- olx, oly, olz = proj3d.proj_transform(*pos, self.axes.M)
- self.offsetText.set_text(self.major.formatter.get_offset())
- self.offsetText.set_position((olx, oly))
- angle = art3d._norm_text_angle(np.rad2deg(np.arctan2(dy, dx)))
- self.offsetText.set_rotation(angle)
- # Must set rotation mode to "anchor" so that
- # the alignment point is used as the "fulcrum" for rotation.
- self.offsetText.set_rotation_mode('anchor')
-
- # ----------------------------------------------------------------------
- # Note: the following statement for determining the proper alignment of
- # the offset text. This was determined entirely by trial-and-error
- # and should not be in any way considered as "the way". There are
- # still some edge cases where alignment is not quite right, but this
- # seems to be more of a geometry issue (in other words, I might be
- # using the wrong reference points).
- #
- # (TT, FF, TF, FT) are the shorthand for the tuple of
- # (centpt[tickdir] <= pep[tickdir, outerindex],
- # centpt[index] <= pep[index, outerindex])
- #
- # Three-letters (e.g., TFT, FTT) are short-hand for the array of bools
- # from the variable 'highs'.
- # ---------------------------------------------------------------------
- centpt = proj3d.proj_transform(*centers, self.axes.M)
- if centpt[tickdir] > pep[tickdir, outerindex]:
- # if FT and if highs has an even number of Trues
- if (centpt[index] <= pep[index, outerindex]
- and np.count_nonzero(highs) % 2 == 0):
- # Usually, this means align right, except for the FTT case,
- # in which offset for axis 1 and 2 are aligned left.
- if highs.tolist() == [False, True, True] and index in (1, 2):
- align = 'left'
- else:
- align = 'right'
- else:
- # The FF case
- align = 'left'
- else:
- # if TF and if highs has an even number of Trues
- if (centpt[index] > pep[index, outerindex]
- and np.count_nonzero(highs) % 2 == 0):
- # Usually mean align left, except if it is axis 2
- align = 'right' if index == 2 else 'left'
- else:
- # The TT case
- align = 'right'
-
- self.offsetText.set_va('center')
- self.offsetText.set_ha(align)
- self.offsetText.draw(renderer)
-
- def _draw_labels(self, renderer, edgep1, edgep2, labeldeltas, centers, dx, dy):
- label = self._axinfo["label"]
-
- # Draw labels
- lxyz = 0.5 * (edgep1 + edgep2)
- lxyz = _move_from_center(lxyz, centers, labeldeltas, self._axmask())
- tlx, tly, tlz = proj3d.proj_transform(*lxyz, self.axes.M)
- self.label.set_position((tlx, tly))
- if self.get_rotate_label(self.label.get_text()):
- angle = art3d._norm_text_angle(np.rad2deg(np.arctan2(dy, dx)))
- self.label.set_rotation(angle)
- self.label.set_va(label['va'])
- self.label.set_ha(label['ha'])
- self.label.set_rotation_mode(label['rotation_mode'])
- self.label.draw(renderer)
-
- @artist.allow_rasterization
- def draw(self, renderer):
- self.label._transform = self.axes.transData
- self.offsetText._transform = self.axes.transData
- renderer.open_group("axis3d", gid=self.get_gid())
-
- # Get general axis information:
- mins, maxs, centers, deltas, tc, highs = self._get_coord_info(renderer)
-
- # Calculate offset distances
- # A rough estimate; points are ambiguous since 3D plots rotate
- reltoinches = self.figure.dpi_scale_trans.inverted()
- ax_inches = reltoinches.transform(self.axes.bbox.size)
- ax_points_estimate = sum(72. * ax_inches)
- deltas_per_point = 48 / ax_points_estimate
- default_offset = 21.
- labeldeltas = (self.labelpad + default_offset) * deltas_per_point * deltas
-
- # Determine edge points for the axis lines
- minmax = np.where(highs, maxs, mins) # "origin" point
- maxmin = np.where(~highs, maxs, mins) # "opposite" corner near camera
-
- for edgep1, edgep2, pos in zip(*self._get_all_axis_line_edge_points(
- minmax, maxmin, self._tick_position)):
- # Project the edge points along the current position
- pep = proj3d._proj_trans_points([edgep1, edgep2], self.axes.M)
- pep = np.asarray(pep)
-
- # The transAxes transform is used because the Text object
- # rotates the text relative to the display coordinate system.
- # Therefore, if we want the labels to remain parallel to the
- # axis regardless of the aspect ratio, we need to convert the
- # edge points of the plane to display coordinates and calculate
- # an angle from that.
- # TODO: Maybe Text objects should handle this themselves?
- dx, dy = (self.axes.transAxes.transform([pep[0:2, 1]]) -
- self.axes.transAxes.transform([pep[0:2, 0]]))[0]
-
- # Draw the lines
- self.line.set_data(pep[0], pep[1])
- self.line.draw(renderer)
-
- # Draw ticks
- self._draw_ticks(renderer, edgep1, centers, deltas, highs,
- deltas_per_point, pos)
-
- # Draw Offset text
- self._draw_offset_text(renderer, edgep1, edgep2, labeldeltas,
- centers, highs, pep, dx, dy)
-
- for edgep1, edgep2, pos in zip(*self._get_all_axis_line_edge_points(
- minmax, maxmin, self._label_position)):
- # See comments above
- pep = proj3d._proj_trans_points([edgep1, edgep2], self.axes.M)
- pep = np.asarray(pep)
- dx, dy = (self.axes.transAxes.transform([pep[0:2, 1]]) -
- self.axes.transAxes.transform([pep[0:2, 0]]))[0]
-
- # Draw labels
- self._draw_labels(renderer, edgep1, edgep2, labeldeltas, centers, dx, dy)
-
- renderer.close_group('axis3d')
- self.stale = False
-
- @artist.allow_rasterization
- def draw_grid(self, renderer):
- if not self.axes._draw_grid:
- return
-
- renderer.open_group("grid3d", gid=self.get_gid())
-
- ticks = self._update_ticks()
- if len(ticks):
- # Get general axis information:
- info = self._axinfo
- index = info["i"]
-
- mins, maxs, _, _, _, highs = self._get_coord_info(renderer)
-
- minmax = np.where(highs, maxs, mins)
- maxmin = np.where(~highs, maxs, mins)
-
- # Grid points where the planes meet
- xyz0 = np.tile(minmax, (len(ticks), 1))
- xyz0[:, index] = [tick.get_loc() for tick in ticks]
-
- # Grid lines go from the end of one plane through the plane
- # intersection (at xyz0) to the end of the other plane. The first
- # point (0) differs along dimension index-2 and the last (2) along
- # dimension index-1.
- lines = np.stack([xyz0, xyz0, xyz0], axis=1)
- lines[:, 0, index - 2] = maxmin[index - 2]
- lines[:, 2, index - 1] = maxmin[index - 1]
- self.gridlines.set_segments(lines)
- gridinfo = info['grid']
- self.gridlines.set_color(gridinfo['color'])
- self.gridlines.set_linewidth(gridinfo['linewidth'])
- self.gridlines.set_linestyle(gridinfo['linestyle'])
- self.gridlines.do_3d_projection()
- self.gridlines.draw(renderer)
-
- renderer.close_group('grid3d')
-
- # TODO: Get this to work (more) properly when mplot3d supports the
- # transforms framework.
- def get_tightbbox(self, renderer=None, *, for_layout_only=False):
- # docstring inherited
- if not self.get_visible():
- return
- # We have to directly access the internal data structures
- # (and hope they are up to date) because at draw time we
- # shift the ticks and their labels around in (x, y) space
- # based on the projection, the current view port, and their
- # position in 3D space. If we extend the transforms framework
- # into 3D we would not need to do this different book keeping
- # than we do in the normal axis
- major_locs = self.get_majorticklocs()
- minor_locs = self.get_minorticklocs()
-
- ticks = [*self.get_minor_ticks(len(minor_locs)),
- *self.get_major_ticks(len(major_locs))]
- view_low, view_high = self.get_view_interval()
- if view_low > view_high:
- view_low, view_high = view_high, view_low
- interval_t = self.get_transform().transform([view_low, view_high])
-
- ticks_to_draw = []
- for tick in ticks:
- try:
- loc_t = self.get_transform().transform(tick.get_loc())
- except AssertionError:
- # Transform.transform doesn't allow masked values but
- # some scales might make them, so we need this try/except.
- pass
- else:
- if mtransforms._interval_contains_close(interval_t, loc_t):
- ticks_to_draw.append(tick)
-
- ticks = ticks_to_draw
-
- bb_1, bb_2 = self._get_ticklabel_bboxes(ticks, renderer)
- other = []
-
- if self.line.get_visible():
- other.append(self.line.get_window_extent(renderer))
- if (self.label.get_visible() and not for_layout_only and
- self.label.get_text()):
- other.append(self.label.get_window_extent(renderer))
-
- return mtransforms.Bbox.union([*bb_1, *bb_2, *other])
-
- d_interval = _api.deprecated(
- "3.6", alternative="get_data_interval", pending=True)(
- property(lambda self: self.get_data_interval(),
- lambda self, minmax: self.set_data_interval(*minmax)))
- v_interval = _api.deprecated(
- "3.6", alternative="get_view_interval", pending=True)(
- property(lambda self: self.get_view_interval(),
- lambda self, minmax: self.set_view_interval(*minmax)))
-
-
-class XAxis(Axis):
- axis_name = "x"
- get_view_interval, set_view_interval = maxis._make_getset_interval(
- "view", "xy_viewLim", "intervalx")
- get_data_interval, set_data_interval = maxis._make_getset_interval(
- "data", "xy_dataLim", "intervalx")
-
-
-class YAxis(Axis):
- axis_name = "y"
- get_view_interval, set_view_interval = maxis._make_getset_interval(
- "view", "xy_viewLim", "intervaly")
- get_data_interval, set_data_interval = maxis._make_getset_interval(
- "data", "xy_dataLim", "intervaly")
-
-
-class ZAxis(Axis):
- axis_name = "z"
- get_view_interval, set_view_interval = maxis._make_getset_interval(
- "view", "zz_viewLim", "intervalx")
- get_data_interval, set_data_interval = maxis._make_getset_interval(
- "data", "zz_dataLim", "intervalx")
diff --git a/contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/proj3d.py b/contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/proj3d.py
deleted file mode 100644
index 098a7b6f66..0000000000
--- a/contrib/python/matplotlib/py3/mpl_toolkits/mplot3d/proj3d.py
+++ /dev/null
@@ -1,259 +0,0 @@
-"""
-Various transforms used for by the 3D code
-"""
-
-import numpy as np
-
-from matplotlib import _api
-
-
-def world_transformation(xmin, xmax,
- ymin, ymax,
- zmin, zmax, pb_aspect=None):
- """
- Produce a matrix that scales homogeneous coords in the specified ranges
- to [0, 1], or [0, pb_aspect[i]] if the plotbox aspect ratio is specified.
- """
- dx = xmax - xmin
- dy = ymax - ymin
- dz = zmax - zmin
- if pb_aspect is not None:
- ax, ay, az = pb_aspect
- dx /= ax
- dy /= ay
- dz /= az
-
- return np.array([[1/dx, 0, 0, -xmin/dx],
- [0, 1/dy, 0, -ymin/dy],
- [0, 0, 1/dz, -zmin/dz],
- [0, 0, 0, 1]])
-
-
-@_api.deprecated("3.8")
-def rotation_about_vector(v, angle):
- """
- Produce a rotation matrix for an angle in radians about a vector.
- """
- return _rotation_about_vector(v, angle)
-
-
-def _rotation_about_vector(v, angle):
- """
- Produce a rotation matrix for an angle in radians about a vector.
- """
- vx, vy, vz = v / np.linalg.norm(v)
- s = np.sin(angle)
- c = np.cos(angle)
- t = 2*np.sin(angle/2)**2 # more numerically stable than t = 1-c
-
- R = np.array([
- [t*vx*vx + c, t*vx*vy - vz*s, t*vx*vz + vy*s],
- [t*vy*vx + vz*s, t*vy*vy + c, t*vy*vz - vx*s],
- [t*vz*vx - vy*s, t*vz*vy + vx*s, t*vz*vz + c]])
-
- return R
-
-
-def _view_axes(E, R, V, roll):
- """
- Get the unit viewing axes in data coordinates.
-
- Parameters
- ----------
- E : 3-element numpy array
- The coordinates of the eye/camera.
- R : 3-element numpy array
- The coordinates of the center of the view box.
- V : 3-element numpy array
- Unit vector in the direction of the vertical axis.
- roll : float
- The roll angle in radians.
-
- Returns
- -------
- u : 3-element numpy array
- Unit vector pointing towards the right of the screen.
- v : 3-element numpy array
- Unit vector pointing towards the top of the screen.
- w : 3-element numpy array
- Unit vector pointing out of the screen.
- """
- w = (E - R)
- w = w/np.linalg.norm(w)
- u = np.cross(V, w)
- u = u/np.linalg.norm(u)
- v = np.cross(w, u) # Will be a unit vector
-
- # Save some computation for the default roll=0
- if roll != 0:
- # A positive rotation of the camera is a negative rotation of the world
- Rroll = _rotation_about_vector(w, -roll)
- u = np.dot(Rroll, u)
- v = np.dot(Rroll, v)
- return u, v, w
-
-
-def _view_transformation_uvw(u, v, w, E):
- """
- Return the view transformation matrix.
-
- Parameters
- ----------
- u : 3-element numpy array
- Unit vector pointing towards the right of the screen.
- v : 3-element numpy array
- Unit vector pointing towards the top of the screen.
- w : 3-element numpy array
- Unit vector pointing out of the screen.
- E : 3-element numpy array
- The coordinates of the eye/camera.
- """
- Mr = np.eye(4)
- Mt = np.eye(4)
- Mr[:3, :3] = [u, v, w]
- Mt[:3, -1] = -E
- M = np.dot(Mr, Mt)
- return M
-
-
-@_api.deprecated("3.8")
-def view_transformation(E, R, V, roll):
- """
- Return the view transformation matrix.
-
- Parameters
- ----------
- E : 3-element numpy array
- The coordinates of the eye/camera.
- R : 3-element numpy array
- The coordinates of the center of the view box.
- V : 3-element numpy array
- Unit vector in the direction of the vertical axis.
- roll : float
- The roll angle in radians.
- """
- u, v, w = _view_axes(E, R, V, roll)
- M = _view_transformation_uvw(u, v, w, E)
- return M
-
-
-@_api.deprecated("3.8")
-def persp_transformation(zfront, zback, focal_length):
- return _persp_transformation(zfront, zback, focal_length)
-
-
-def _persp_transformation(zfront, zback, focal_length):
- e = focal_length
- a = 1 # aspect ratio
- b = (zfront+zback)/(zfront-zback)
- c = -2*(zfront*zback)/(zfront-zback)
- proj_matrix = np.array([[e, 0, 0, 0],
- [0, e/a, 0, 0],
- [0, 0, b, c],
- [0, 0, -1, 0]])
- return proj_matrix
-
-
-@_api.deprecated("3.8")
-def ortho_transformation(zfront, zback):
- return _ortho_transformation(zfront, zback)
-
-
-def _ortho_transformation(zfront, zback):
- # note: w component in the resulting vector will be (zback-zfront), not 1
- a = -(zfront + zback)
- b = -(zfront - zback)
- proj_matrix = np.array([[2, 0, 0, 0],
- [0, 2, 0, 0],
- [0, 0, -2, 0],
- [0, 0, a, b]])
- return proj_matrix
-
-
-def _proj_transform_vec(vec, M):
- vecw = np.dot(M, vec)
- w = vecw[3]
- # clip here..
- txs, tys, tzs = vecw[0]/w, vecw[1]/w, vecw[2]/w
- return txs, tys, tzs
-
-
-def _proj_transform_vec_clip(vec, M):
- vecw = np.dot(M, vec)
- w = vecw[3]
- # clip here.
- txs, tys, tzs = vecw[0] / w, vecw[1] / w, vecw[2] / w
- tis = (0 <= vecw[0]) & (vecw[0] <= 1) & (0 <= vecw[1]) & (vecw[1] <= 1)
- if np.any(tis):
- tis = vecw[1] < 1
- return txs, tys, tzs, tis
-
-
-def inv_transform(xs, ys, zs, invM):
- """
- Transform the points by the inverse of the projection matrix, *invM*.
- """
- vec = _vec_pad_ones(xs, ys, zs)
- vecr = np.dot(invM, vec)
- if vecr.shape == (4,):
- vecr = vecr.reshape((4, 1))
- for i in range(vecr.shape[1]):
- if vecr[3][i] != 0:
- vecr[:, i] = vecr[:, i] / vecr[3][i]
- return vecr[0], vecr[1], vecr[2]
-
-
-def _vec_pad_ones(xs, ys, zs):
- return np.array([xs, ys, zs, np.ones_like(xs)])
-
-
-def proj_transform(xs, ys, zs, M):
- """
- Transform the points by the projection matrix *M*.
- """
- vec = _vec_pad_ones(xs, ys, zs)
- return _proj_transform_vec(vec, M)
-
-
-transform = _api.deprecated(
- "3.8", obj_type="function", name="transform",
- alternative="proj_transform")(proj_transform)
-
-
-def proj_transform_clip(xs, ys, zs, M):
- """
- Transform the points by the projection matrix
- and return the clipping result
- returns txs, tys, tzs, tis
- """
- vec = _vec_pad_ones(xs, ys, zs)
- return _proj_transform_vec_clip(vec, M)
-
-
-@_api.deprecated("3.8")
-def proj_points(points, M):
- return _proj_points(points, M)
-
-
-def _proj_points(points, M):
- return np.column_stack(_proj_trans_points(points, M))
-
-
-@_api.deprecated("3.8")
-def proj_trans_points(points, M):
- return _proj_trans_points(points, M)
-
-
-def _proj_trans_points(points, M):
- xs, ys, zs = zip(*points)
- return proj_transform(xs, ys, zs, M)
-
-
-@_api.deprecated("3.8")
-def rot_x(V, alpha):
- cosa, sina = np.cos(alpha), np.sin(alpha)
- M1 = np.array([[1, 0, 0, 0],
- [0, cosa, -sina, 0],
- [0, sina, cosa, 0],
- [0, 0, 0, 1]])
- return np.dot(M1, V)
diff --git a/contrib/python/matplotlib/py3/patches/01-arcadia.patch b/contrib/python/matplotlib/py3/patches/01-arcadia.patch
deleted file mode 100644
index ff2be0382b..0000000000
--- a/contrib/python/matplotlib/py3/patches/01-arcadia.patch
+++ /dev/null
@@ -1,53 +0,0 @@
---- contrib/python/matplotlib/py3/matplotlib/__init__.py (index)
-+++ contrib/python/matplotlib/py3/matplotlib/__init__.py (working tree)
-@@ -529,1 +529,1 @@ def _get_data_path():
-- return str(Path(__file__).with_name("mpl-data"))
-+ return _get_internal_mpl_data()
-@@ -530,4 +530,18 @@ def get_cachedir():
-
-
-+def _get_internal_mpl_data():
-+ import tempfile
-+ import __res
-+
-+ tmp_dir = tempfile.mkdtemp(prefix='mpl-temp', dir=tempfile.gettempdir())
-+ for key, rel_path in __res.iter_keys(b"resfs/file/contrib/python/matplotlib/py3/matplotlib/mpl-data/"):
-+ filename = f"{tmp_dir}/{str(rel_path, 'ascii')}"
-+ os.makedirs(os.path.dirname(filename), exist_ok=True)
-+ with open(filename, 'wb') as f:
-+ f.write(__res.find(key))
-+
-+ return tmp_dir
-+
-+
- def matplotlib_fname():
- """
---- contrib/python/matplotlib/py3/matplotlib/backends/backend_nbagg.py (index)
-+++ contrib/python/matplotlib/py3/matplotlib/backends/backend_nbagg.py (working tree)
-@@ -111,9 +111,9 @@ class FigureManagerNbAgg(FigureManagerWebAgg):
- else:
- output = stream
- super().get_javascript(stream=output)
-- output.write((pathlib.Path(__file__).parent
-- / "web_backend/js/nbagg_mpl.js")
-- .read_text(encoding="utf-8"))
-+ import pkgutil
-+ data = pkgutil.get_data(__package__, "web_backend/js/nbagg_mpl.js").decode("utf-8")
-+ output.write(data)
- if stream is None:
- return output.getvalue()
-
---- contrib/python/matplotlib/py3/matplotlib/backends/backend_webagg_core.py (index)
-+++ contrib/python/matplotlib/py3/matplotlib/backends/backend_webagg_core.py (working tree)
-@@ -505,8 +505,9 @@ class FigureManagerWebAgg(backend_bases.FigureManagerBase):
- else:
- output = stream
-
-- output.write((Path(__file__).parent / "web_backend/js/mpl.js")
-- .read_text(encoding="utf-8"))
-+ import pkgutil
-+ data = pkgutil.get_data(__package__, "web_backend/js/mpl.js").decode("utf-8")
-+ output.write(data)
-
- toolitems = []
- for name, tooltip, image, method in cls.ToolbarCls.toolitems:
diff --git a/contrib/python/matplotlib/py3/patches/02-fix-ya.make.patch b/contrib/python/matplotlib/py3/patches/02-fix-ya.make.patch
deleted file mode 100644
index 5c8bb80f97..0000000000
--- a/contrib/python/matplotlib/py3/patches/02-fix-ya.make.patch
+++ /dev/null
@@ -1,16 +0,0 @@
---- contrib/python/matplotlib/py3/ya.make (index)
-+++ contrib/python/matplotlib/py3/ya.make (working tree)
-@@ -49,6 +49,13 @@ CFLAGS(
- -DMPL_DEVNULL=/dev/null
- )
-
-+IF (OS_WINDOWS)
-+ LDFLAGS(
-+ Comctl32.lib
-+ Psapi.lib
-+ )
-+ENDIF()
-+
- SRCS(
- src/_backend_agg.cpp
- src/_backend_agg_wrapper.cpp
diff --git a/contrib/python/matplotlib/py3/patches/03-add-missing-include.patch b/contrib/python/matplotlib/py3/patches/03-add-missing-include.patch
deleted file mode 100644
index 629d76e150..0000000000
--- a/contrib/python/matplotlib/py3/patches/03-add-missing-include.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- contrib/python/matplotlib/py3/src/_image_resample.h (index)
-+++ contrib/python/matplotlib/py3/src/_image_resample.h (working tree)
-@@ -21,6 +21,8 @@
-
- #include "agg_workaround.h"
-
-+#include <type_traits>
-+
- // Based on:
-
- //----------------------------------------------------------------------------
diff --git a/contrib/python/matplotlib/py3/patches/04-fix-relative-paths-web-backend.patch b/contrib/python/matplotlib/py3/patches/04-fix-relative-paths-web-backend.patch
deleted file mode 100644
index af93c725bf..0000000000
--- a/contrib/python/matplotlib/py3/patches/04-fix-relative-paths-web-backend.patch
+++ /dev/null
@@ -1,50 +0,0 @@
---- contrib/python/matplotlib/py3/matplotlib/backends/backend_webagg.py (f7af9e31ba1993f2d29753345505773d8e71ca62)
-+++ contrib/python/matplotlib/py3/matplotlib/backends/backend_webagg.py (working tree)
-@@ -19,6 +19,10 @@ import random
- import sys
- import signal
- import threading
-+import tempfile
-+import os
-+
-+from library.python.resource import iteritems
-
- try:
- import tornado
-@@ -177,12 +181,14 @@ class WebAggApplication(tornado.web.Application):
- assert url_prefix[0] == '/' and url_prefix[-1] != '/', \
- 'url_prefix must start with a "/" and not end with one.'
-
-+ self._store_resources()
-+ package_resources_abspath = os.path.join(self._stored_package_path, core.FigureManagerWebAgg.get_static_file_path())
- super().__init__(
- [
- # Static files for the CSS and JS
- (url_prefix + r'/_static/(.*)',
- tornado.web.StaticFileHandler,
-- {'path': core.FigureManagerWebAgg.get_static_file_path()}),
-+ {'path': package_resources_abspath}),
-
- # Static images for the toolbar
- (url_prefix + r'/_images/(.*)',
-@@ -210,7 +216,19 @@ class WebAggApplication(tornado.web.Application):
- (url_prefix + r'/([0-9]+)/download.([a-z0-9.]+)',
- self.Download),
- ],
-- template_path=core.FigureManagerWebAgg.get_static_file_path())
-+ template_path=package_resources_abspath)
-+
-+ def _store_resources(self):
-+ self._stored_package_dir = tempfile.TemporaryDirectory()
-+ self._stored_package_path = self._stored_package_dir.name
-+ package_path = os.path.join(*"contrib/python/matplotlib/py3/".split("/"))
-+ for key, data in iteritems(prefix="resfs/file/" + package_path, strip_prefix=True):
-+ path = os.path.join(self._stored_package_path, *os.path.split(package_path), *os.path.split(key))
-+ dir = os.path.dirname(path)
-+ if not os.path.exists(dir):
-+ os.makedirs(dir)
-+ with open(path, "wb") as file:
-+ file.write(data)
-
- @classmethod
- def initialize(cls, url_prefix='', port=None, address=None):
diff --git a/contrib/python/matplotlib/py3/pylab.py b/contrib/python/matplotlib/py3/pylab.py
deleted file mode 100644
index f9d135d36e..0000000000
--- a/contrib/python/matplotlib/py3/pylab.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from matplotlib.pylab import *
-import matplotlib.pylab
-__doc__ = matplotlib.pylab.__doc__
diff --git a/contrib/python/matplotlib/py3/src/_backend_agg.cpp b/contrib/python/matplotlib/py3/src/_backend_agg.cpp
deleted file mode 100644
index 335e409719..0000000000
--- a/contrib/python/matplotlib/py3/src/_backend_agg.cpp
+++ /dev/null
@@ -1,176 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#define NO_IMPORT_ARRAY
-
-#include "_backend_agg.h"
-#include "mplutils.h"
-
-void BufferRegion::to_string_argb(uint8_t *buf)
-{
- unsigned char *pix;
- unsigned char tmp;
- size_t i, j;
-
- memcpy(buf, data, (size_t) height * stride);
-
- for (i = 0; i < (size_t)height; ++i) {
- pix = buf + i * stride;
- for (j = 0; j < (size_t)width; ++j) {
- // Convert rgba to argb
- tmp = pix[2];
- pix[2] = pix[0];
- pix[0] = tmp;
- pix += 4;
- }
- }
-}
-
-RendererAgg::RendererAgg(unsigned int width, unsigned int height, double dpi)
- : width(width),
- height(height),
- dpi(dpi),
- NUMBYTES((size_t)width * (size_t)height * 4),
- pixBuffer(NULL),
- renderingBuffer(),
- alphaBuffer(NULL),
- alphaMaskRenderingBuffer(),
- alphaMask(alphaMaskRenderingBuffer),
- pixfmtAlphaMask(alphaMaskRenderingBuffer),
- rendererBaseAlphaMask(),
- rendererAlphaMask(),
- scanlineAlphaMask(),
- slineP8(),
- slineBin(),
- pixFmt(),
- rendererBase(),
- rendererAA(),
- rendererBin(),
- theRasterizer(32768),
- lastclippath(NULL),
- _fill_color(agg::rgba(1, 1, 1, 0))
-{
- unsigned stride(width * 4);
-
- pixBuffer = new agg::int8u[NUMBYTES];
- renderingBuffer.attach(pixBuffer, width, height, stride);
- pixFmt.attach(renderingBuffer);
- rendererBase.attach(pixFmt);
- rendererBase.clear(_fill_color);
- rendererAA.attach(rendererBase);
- rendererBin.attach(rendererBase);
- hatch_size = int(dpi);
- hatchBuffer = new agg::int8u[hatch_size * hatch_size * 4];
- hatchRenderingBuffer.attach(hatchBuffer, hatch_size, hatch_size, hatch_size * 4);
-}
-
-RendererAgg::~RendererAgg()
-{
- delete[] hatchBuffer;
- delete[] alphaBuffer;
- delete[] pixBuffer;
-}
-
-void RendererAgg::create_alpha_buffers()
-{
- if (!alphaBuffer) {
- alphaBuffer = new agg::int8u[width * height];
- alphaMaskRenderingBuffer.attach(alphaBuffer, width, height, width);
- rendererBaseAlphaMask.attach(pixfmtAlphaMask);
- rendererAlphaMask.attach(rendererBaseAlphaMask);
- }
-}
-
-BufferRegion *RendererAgg::copy_from_bbox(agg::rect_d in_rect)
-{
- agg::rect_i rect(
- (int)in_rect.x1, height - (int)in_rect.y2, (int)in_rect.x2, height - (int)in_rect.y1);
-
- BufferRegion *reg = NULL;
- reg = new BufferRegion(rect);
-
- agg::rendering_buffer rbuf;
- rbuf.attach(reg->get_data(), reg->get_width(), reg->get_height(), reg->get_stride());
-
- pixfmt pf(rbuf);
- renderer_base rb(pf);
- rb.copy_from(renderingBuffer, &rect, -rect.x1, -rect.y1);
-
- return reg;
-}
-
-void RendererAgg::restore_region(BufferRegion &region)
-{
- if (region.get_data() == NULL) {
- throw std::runtime_error("Cannot restore_region from NULL data");
- }
-
- agg::rendering_buffer rbuf;
- rbuf.attach(region.get_data(), region.get_width(), region.get_height(), region.get_stride());
-
- rendererBase.copy_from(rbuf, 0, region.get_rect().x1, region.get_rect().y1);
-}
-
-// Restore the part of the saved region with offsets
-void
-RendererAgg::restore_region(BufferRegion &region, int xx1, int yy1, int xx2, int yy2, int x, int y )
-{
- if (region.get_data() == NULL) {
- throw std::runtime_error("Cannot restore_region from NULL data");
- }
-
- agg::rect_i &rrect = region.get_rect();
-
- agg::rect_i rect(xx1 - rrect.x1, (yy1 - rrect.y1), xx2 - rrect.x1, (yy2 - rrect.y1));
-
- agg::rendering_buffer rbuf;
- rbuf.attach(region.get_data(), region.get_width(), region.get_height(), region.get_stride());
-
- rendererBase.copy_from(rbuf, &rect, x, y);
-}
-
-bool RendererAgg::render_clippath(py::PathIterator &clippath,
- const agg::trans_affine &clippath_trans,
- e_snap_mode snap_mode)
-{
- typedef agg::conv_transform<py::PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removed_t;
- /* Unlike normal Paths, the clip path cannot be clipped to the Figure bbox,
- * because it needs to remain a complete closed path, so there is no
- * PathClipper<nan_removed_t> step. */
- typedef PathSnapper<nan_removed_t> snapped_t;
- typedef PathSimplifier<snapped_t> simplify_t;
- typedef agg::conv_curve<simplify_t> curve_t;
-
- bool has_clippath = (clippath.total_vertices() != 0);
-
- if (has_clippath &&
- (clippath.get_id() != lastclippath || clippath_trans != lastclippath_transform)) {
- create_alpha_buffers();
- agg::trans_affine trans(clippath_trans);
- trans *= agg::trans_affine_scaling(1.0, -1.0);
- trans *= agg::trans_affine_translation(0.0, (double)height);
-
- rendererBaseAlphaMask.clear(agg::gray8(0, 0));
- transformed_path_t transformed_clippath(clippath, trans);
- nan_removed_t nan_removed_clippath(transformed_clippath, true, clippath.has_codes());
- snapped_t snapped_clippath(nan_removed_clippath, snap_mode, clippath.total_vertices(), 0.0);
- simplify_t simplified_clippath(snapped_clippath,
- clippath.should_simplify() && !clippath.has_codes(),
- clippath.simplify_threshold());
- curve_t curved_clippath(simplified_clippath);
- theRasterizer.add_path(curved_clippath);
- rendererAlphaMask.color(agg::gray8(255, 255));
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, rendererAlphaMask);
- lastclippath = clippath.get_id();
- lastclippath_transform = clippath_trans;
- }
-
- return has_clippath;
-}
-
-void RendererAgg::clear()
-{
- //"clear the rendered buffer";
-
- rendererBase.clear(_fill_color);
-}
diff --git a/contrib/python/matplotlib/py3/src/_backend_agg.h b/contrib/python/matplotlib/py3/src/_backend_agg.h
deleted file mode 100644
index 61c24232a8..0000000000
--- a/contrib/python/matplotlib/py3/src/_backend_agg.h
+++ /dev/null
@@ -1,1280 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/* _backend_agg.h
-*/
-
-#ifndef MPL_BACKEND_AGG_H
-#define MPL_BACKEND_AGG_H
-
-#include <cmath>
-#include <vector>
-#include <algorithm>
-
-#include "agg_alpha_mask_u8.h"
-#include "agg_conv_curve.h"
-#include "agg_conv_dash.h"
-#include "agg_conv_stroke.h"
-#include "agg_image_accessors.h"
-#include "agg_pixfmt_amask_adaptor.h"
-#include "agg_pixfmt_gray.h"
-#include "agg_pixfmt_rgba.h"
-#include "agg_rasterizer_scanline_aa.h"
-#include "agg_renderer_base.h"
-#include "agg_renderer_scanline.h"
-#include "agg_rendering_buffer.h"
-#include "agg_scanline_bin.h"
-#include "agg_scanline_p.h"
-#include "agg_scanline_storage_aa.h"
-#include "agg_scanline_storage_bin.h"
-#include "agg_scanline_u.h"
-#include "agg_span_allocator.h"
-#include "agg_span_converter.h"
-#include "agg_span_gouraud_rgba.h"
-#include "agg_span_image_filter_gray.h"
-#include "agg_span_image_filter_rgba.h"
-#include "agg_span_interpolator_linear.h"
-#include "agg_span_pattern_rgba.h"
-#include "util/agg_color_conv_rgb8.h"
-
-#include "_backend_agg_basic_types.h"
-#include "path_converters.h"
-#include "array.h"
-#include "agg_workaround.h"
-
-/**********************************************************************/
-
-// a helper class to pass agg::buffer objects around.
-
-class BufferRegion
-{
- public:
- BufferRegion(const agg::rect_i &r) : rect(r)
- {
- width = r.x2 - r.x1;
- height = r.y2 - r.y1;
- stride = width * 4;
- data = new agg::int8u[stride * height];
- }
-
- virtual ~BufferRegion()
- {
- delete[] data;
- };
-
- agg::int8u *get_data()
- {
- return data;
- }
-
- agg::rect_i &get_rect()
- {
- return rect;
- }
-
- int get_width()
- {
- return width;
- }
-
- int get_height()
- {
- return height;
- }
-
- int get_stride()
- {
- return stride;
- }
-
- void to_string_argb(uint8_t *buf);
-
- private:
- agg::int8u *data;
- agg::rect_i rect;
- int width;
- int height;
- int stride;
-
- private:
- // prevent copying
- BufferRegion(const BufferRegion &);
- BufferRegion &operator=(const BufferRegion &);
-};
-
-#define MARKER_CACHE_SIZE 512
-
-// the renderer
-class RendererAgg
-{
- public:
-
- typedef fixed_blender_rgba_plain<agg::rgba8, agg::order_rgba> fixed_blender_rgba32_plain;
- typedef agg::pixfmt_alpha_blend_rgba<fixed_blender_rgba32_plain, agg::rendering_buffer> pixfmt;
- typedef agg::renderer_base<pixfmt> renderer_base;
- typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_aa;
- typedef agg::renderer_scanline_bin_solid<renderer_base> renderer_bin;
- typedef agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> rasterizer;
-
- typedef agg::scanline_p8 scanline_p8;
- typedef agg::scanline_bin scanline_bin;
- typedef agg::amask_no_clip_gray8 alpha_mask_type;
- typedef agg::scanline_u8_am<alpha_mask_type> scanline_am;
-
- typedef agg::renderer_base<agg::pixfmt_gray8> renderer_base_alpha_mask_type;
- typedef agg::renderer_scanline_aa_solid<renderer_base_alpha_mask_type> renderer_alpha_mask_type;
-
- /* TODO: Remove facepair_t */
- typedef std::pair<bool, agg::rgba> facepair_t;
-
- RendererAgg(unsigned int width, unsigned int height, double dpi);
-
- virtual ~RendererAgg();
-
- unsigned int get_width()
- {
- return width;
- }
-
- unsigned int get_height()
- {
- return height;
- }
-
- template <class PathIterator>
- void draw_path(GCAgg &gc, PathIterator &path, agg::trans_affine &trans, agg::rgba &color);
-
- template <class PathIterator>
- void draw_markers(GCAgg &gc,
- PathIterator &marker_path,
- agg::trans_affine &marker_path_trans,
- PathIterator &path,
- agg::trans_affine &trans,
- agg::rgba face);
-
- template <class ImageArray>
- void draw_text_image(GCAgg &gc, ImageArray &image, int x, int y, double angle);
-
- template <class ImageArray>
- void draw_image(GCAgg &gc,
- double x,
- double y,
- ImageArray &image);
-
- template <class PathGenerator,
- class TransformArray,
- class OffsetArray,
- class ColorArray,
- class LineWidthArray,
- class AntialiasedArray>
- void draw_path_collection(GCAgg &gc,
- agg::trans_affine &master_transform,
- PathGenerator &path,
- TransformArray &transforms,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- ColorArray &edgecolors,
- LineWidthArray &linewidths,
- DashesVector &linestyles,
- AntialiasedArray &antialiaseds);
-
- template <class CoordinateArray, class OffsetArray, class ColorArray>
- void draw_quad_mesh(GCAgg &gc,
- agg::trans_affine &master_transform,
- unsigned int mesh_width,
- unsigned int mesh_height,
- CoordinateArray &coordinates,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- bool antialiased,
- ColorArray &edgecolors);
-
- template <class PointArray, class ColorArray>
- void draw_gouraud_triangle(GCAgg &gc,
- PointArray &points,
- ColorArray &colors,
- agg::trans_affine &trans);
-
- template <class PointArray, class ColorArray>
- void draw_gouraud_triangles(GCAgg &gc,
- PointArray &points,
- ColorArray &colors,
- agg::trans_affine &trans);
-
- agg::rect_i get_content_extents();
- void clear();
-
- BufferRegion *copy_from_bbox(agg::rect_d in_rect);
- void restore_region(BufferRegion &reg);
- void restore_region(BufferRegion &region, int xx1, int yy1, int xx2, int yy2, int x, int y);
-
- unsigned int width, height;
- double dpi;
- size_t NUMBYTES; // the number of bytes in buffer
-
- agg::int8u *pixBuffer;
- agg::rendering_buffer renderingBuffer;
-
- agg::int8u *alphaBuffer;
- agg::rendering_buffer alphaMaskRenderingBuffer;
- alpha_mask_type alphaMask;
- agg::pixfmt_gray8 pixfmtAlphaMask;
- renderer_base_alpha_mask_type rendererBaseAlphaMask;
- renderer_alpha_mask_type rendererAlphaMask;
- scanline_am scanlineAlphaMask;
-
- scanline_p8 slineP8;
- scanline_bin slineBin;
- pixfmt pixFmt;
- renderer_base rendererBase;
- renderer_aa rendererAA;
- renderer_bin rendererBin;
- rasterizer theRasterizer;
-
- void *lastclippath;
- agg::trans_affine lastclippath_transform;
-
- size_t hatch_size;
- agg::int8u *hatchBuffer;
- agg::rendering_buffer hatchRenderingBuffer;
-
- agg::rgba _fill_color;
-
- protected:
- inline double points_to_pixels(double points)
- {
- return points * dpi / 72.0;
- }
-
- template <class R>
- void set_clipbox(const agg::rect_d &cliprect, R &rasterizer);
-
- bool render_clippath(py::PathIterator &clippath, const agg::trans_affine &clippath_trans, e_snap_mode snap_mode);
-
- template <class PathIteratorType>
- void _draw_path(PathIteratorType &path, bool has_clippath, const facepair_t &face, GCAgg &gc);
-
- template <class PathIterator,
- class PathGenerator,
- class TransformArray,
- class OffsetArray,
- class ColorArray,
- class LineWidthArray,
- class AntialiasedArray>
- void _draw_path_collection_generic(GCAgg &gc,
- agg::trans_affine master_transform,
- const agg::rect_d &cliprect,
- PathIterator &clippath,
- const agg::trans_affine &clippath_trans,
- PathGenerator &path_generator,
- TransformArray &transforms,
- OffsetArray &offsets,
- const agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- ColorArray &edgecolors,
- LineWidthArray &linewidths,
- DashesVector &linestyles,
- AntialiasedArray &antialiaseds,
- bool check_snap,
- bool has_codes);
-
- template <class PointArray, class ColorArray>
- void _draw_gouraud_triangle(PointArray &points,
- ColorArray &colors,
- agg::trans_affine trans,
- bool has_clippath);
-
- private:
- void create_alpha_buffers();
-
- // prevent copying
- RendererAgg(const RendererAgg &);
- RendererAgg &operator=(const RendererAgg &);
-};
-
-/***************************************************************************
- * Implementation
- */
-
-template <class path_t>
-inline void
-RendererAgg::_draw_path(path_t &path, bool has_clippath, const facepair_t &face, GCAgg &gc)
-{
- typedef agg::conv_stroke<path_t> stroke_t;
- typedef agg::conv_dash<path_t> dash_t;
- typedef agg::conv_stroke<dash_t> stroke_dash_t;
- typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
- typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
- typedef agg::renderer_scanline_aa_solid<amask_ren_type> amask_aa_renderer_type;
- typedef agg::renderer_scanline_bin_solid<amask_ren_type> amask_bin_renderer_type;
-
- // Render face
- if (face.first) {
- theRasterizer.add_path(path);
-
- if (gc.isaa) {
- if (has_clippath) {
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_aa_renderer_type ren(r);
- ren.color(face.second);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ren);
- } else {
- rendererAA.color(face.second);
- agg::render_scanlines(theRasterizer, slineP8, rendererAA);
- }
- } else {
- if (has_clippath) {
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_bin_renderer_type ren(r);
- ren.color(face.second);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ren);
- } else {
- rendererBin.color(face.second);
- agg::render_scanlines(theRasterizer, slineP8, rendererBin);
- }
- }
- }
-
- // Render hatch
- if (gc.has_hatchpath()) {
- // Reset any clipping that may be in effect, since we'll be
- // drawing the hatch in a scratch buffer at origin (0, 0)
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
-
- // Create and transform the path
- typedef agg::conv_transform<py::PathIterator> hatch_path_trans_t;
- typedef agg::conv_curve<hatch_path_trans_t> hatch_path_curve_t;
- typedef agg::conv_stroke<hatch_path_curve_t> hatch_path_stroke_t;
-
- py::PathIterator hatch_path(gc.hatchpath);
- agg::trans_affine hatch_trans;
- hatch_trans *= agg::trans_affine_scaling(1.0, -1.0);
- hatch_trans *= agg::trans_affine_translation(0.0, 1.0);
- hatch_trans *= agg::trans_affine_scaling(hatch_size, hatch_size);
- hatch_path_trans_t hatch_path_trans(hatch_path, hatch_trans);
- hatch_path_curve_t hatch_path_curve(hatch_path_trans);
- hatch_path_stroke_t hatch_path_stroke(hatch_path_curve);
- hatch_path_stroke.width(points_to_pixels(gc.hatch_linewidth));
- hatch_path_stroke.line_cap(agg::square_cap);
-
- // Render the path into the hatch buffer
- pixfmt hatch_img_pixf(hatchRenderingBuffer);
- renderer_base rb(hatch_img_pixf);
- renderer_aa rs(rb);
- rb.clear(_fill_color);
- rs.color(gc.hatch_color);
-
- theRasterizer.add_path(hatch_path_curve);
- agg::render_scanlines(theRasterizer, slineP8, rs);
- theRasterizer.add_path(hatch_path_stroke);
- agg::render_scanlines(theRasterizer, slineP8, rs);
-
- // Put clipping back on, if originally set on entry to this
- // function
- set_clipbox(gc.cliprect, theRasterizer);
- if (has_clippath) {
- render_clippath(gc.clippath.path, gc.clippath.trans, gc.snap_mode);
- }
-
- // Transfer the hatch to the main image buffer
- typedef agg::image_accessor_wrap<pixfmt,
- agg::wrap_mode_repeat_auto_pow2,
- agg::wrap_mode_repeat_auto_pow2> img_source_type;
- typedef agg::span_pattern_rgba<img_source_type> span_gen_type;
- agg::span_allocator<agg::rgba8> sa;
- img_source_type img_src(hatch_img_pixf);
- span_gen_type sg(img_src, 0, 0);
- theRasterizer.add_path(path);
-
- if (has_clippath) {
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type ren(pfa);
- agg::render_scanlines_aa(theRasterizer, slineP8, ren, sa, sg);
- } else {
- agg::render_scanlines_aa(theRasterizer, slineP8, rendererBase, sa, sg);
- }
- }
-
- // Render stroke
- if (gc.linewidth != 0.0) {
- double linewidth = points_to_pixels(gc.linewidth);
- if (!gc.isaa) {
- linewidth = (linewidth < 0.5) ? 0.5 : mpl_round(linewidth);
- }
- if (gc.dashes.size() == 0) {
- stroke_t stroke(path);
- stroke.width(points_to_pixels(gc.linewidth));
- stroke.line_cap(gc.cap);
- stroke.line_join(gc.join);
- stroke.miter_limit(points_to_pixels(gc.linewidth));
- theRasterizer.add_path(stroke);
- } else {
- dash_t dash(path);
- gc.dashes.dash_to_stroke(dash, dpi, gc.isaa);
- stroke_dash_t stroke(dash);
- stroke.line_cap(gc.cap);
- stroke.line_join(gc.join);
- stroke.width(linewidth);
- stroke.miter_limit(points_to_pixels(gc.linewidth));
- theRasterizer.add_path(stroke);
- }
-
- if (gc.isaa) {
- if (has_clippath) {
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_aa_renderer_type ren(r);
- ren.color(gc.color);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ren);
- } else {
- rendererAA.color(gc.color);
- agg::render_scanlines(theRasterizer, slineP8, rendererAA);
- }
- } else {
- if (has_clippath) {
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_bin_renderer_type ren(r);
- ren.color(gc.color);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ren);
- } else {
- rendererBin.color(gc.color);
- agg::render_scanlines(theRasterizer, slineBin, rendererBin);
- }
- }
- }
-}
-
-template <class PathIterator>
-inline void
-RendererAgg::draw_path(GCAgg &gc, PathIterator &path, agg::trans_affine &trans, agg::rgba &color)
-{
- typedef agg::conv_transform<py::PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removed_t;
- typedef PathClipper<nan_removed_t> clipped_t;
- typedef PathSnapper<clipped_t> snapped_t;
- typedef PathSimplifier<snapped_t> simplify_t;
- typedef agg::conv_curve<simplify_t> curve_t;
- typedef Sketch<curve_t> sketch_t;
-
- facepair_t face(color.a != 0.0, color);
-
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(gc.cliprect, theRasterizer);
- bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans, gc.snap_mode);
-
- trans *= agg::trans_affine_scaling(1.0, -1.0);
- trans *= agg::trans_affine_translation(0.0, (double)height);
- bool clip = !face.first && !gc.has_hatchpath();
- bool simplify = path.should_simplify() && clip;
- double snapping_linewidth = points_to_pixels(gc.linewidth);
- if (gc.color.a == 0.0) {
- snapping_linewidth = 0.0;
- }
-
- transformed_path_t tpath(path, trans);
- nan_removed_t nan_removed(tpath, true, path.has_codes());
- clipped_t clipped(nan_removed, clip, width, height);
- snapped_t snapped(clipped, gc.snap_mode, path.total_vertices(), snapping_linewidth);
- simplify_t simplified(snapped, simplify, path.simplify_threshold());
- curve_t curve(simplified);
- sketch_t sketch(curve, gc.sketch.scale, gc.sketch.length, gc.sketch.randomness);
-
- _draw_path(sketch, has_clippath, face, gc);
-}
-
-template <class PathIterator>
-inline void RendererAgg::draw_markers(GCAgg &gc,
- PathIterator &marker_path,
- agg::trans_affine &marker_trans,
- PathIterator &path,
- agg::trans_affine &trans,
- agg::rgba color)
-{
- typedef agg::conv_transform<py::PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removed_t;
- typedef PathSnapper<nan_removed_t> snap_t;
- typedef agg::conv_curve<snap_t> curve_t;
- typedef agg::conv_stroke<curve_t> stroke_t;
- typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
- typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
- typedef agg::renderer_scanline_aa_solid<amask_ren_type> amask_aa_renderer_type;
-
- // Deal with the difference in y-axis direction
- marker_trans *= agg::trans_affine_scaling(1.0, -1.0);
-
- trans *= agg::trans_affine_scaling(1.0, -1.0);
- trans *= agg::trans_affine_translation(0.5, (double)height + 0.5);
-
- transformed_path_t marker_path_transformed(marker_path, marker_trans);
- nan_removed_t marker_path_nan_removed(marker_path_transformed, true, marker_path.has_codes());
- snap_t marker_path_snapped(marker_path_nan_removed,
- gc.snap_mode,
- marker_path.total_vertices(),
- points_to_pixels(gc.linewidth));
- curve_t marker_path_curve(marker_path_snapped);
-
- if (!marker_path_snapped.is_snapping()) {
- // If the path snapper isn't in effect, at least make sure the marker
- // at (0, 0) is in the center of a pixel. This, importantly, makes
- // the circle markers look centered around the point they refer to.
- marker_trans *= agg::trans_affine_translation(0.5, 0.5);
- }
-
- transformed_path_t path_transformed(path, trans);
- nan_removed_t path_nan_removed(path_transformed, false, false);
- snap_t path_snapped(path_nan_removed, SNAP_FALSE, path.total_vertices(), 0.0);
- curve_t path_curve(path_snapped);
- path_curve.rewind(0);
-
- facepair_t face(color.a != 0.0, color);
-
- // maxim's suggestions for cached scanlines
- agg::scanline_storage_aa8 scanlines;
- theRasterizer.reset();
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- agg::rect_i marker_size(0x7FFFFFFF, 0x7FFFFFFF, -0x7FFFFFFF, -0x7FFFFFFF);
-
- agg::int8u staticFillCache[MARKER_CACHE_SIZE];
- agg::int8u staticStrokeCache[MARKER_CACHE_SIZE];
- agg::int8u *fillCache = staticFillCache;
- agg::int8u *strokeCache = staticStrokeCache;
-
- try
- {
- unsigned fillSize = 0;
- if (face.first) {
- theRasterizer.add_path(marker_path_curve);
- agg::render_scanlines(theRasterizer, slineP8, scanlines);
- fillSize = scanlines.byte_size();
- if (fillSize >= MARKER_CACHE_SIZE) {
- fillCache = new agg::int8u[fillSize];
- }
- scanlines.serialize(fillCache);
- marker_size = agg::rect_i(scanlines.min_x(),
- scanlines.min_y(),
- scanlines.max_x(),
- scanlines.max_y());
- }
-
- stroke_t stroke(marker_path_curve);
- stroke.width(points_to_pixels(gc.linewidth));
- stroke.line_cap(gc.cap);
- stroke.line_join(gc.join);
- stroke.miter_limit(points_to_pixels(gc.linewidth));
- theRasterizer.reset();
- theRasterizer.add_path(stroke);
- agg::render_scanlines(theRasterizer, slineP8, scanlines);
- unsigned strokeSize = scanlines.byte_size();
- if (strokeSize >= MARKER_CACHE_SIZE) {
- strokeCache = new agg::int8u[strokeSize];
- }
- scanlines.serialize(strokeCache);
- marker_size = agg::rect_i(std::min(marker_size.x1, scanlines.min_x()),
- std::min(marker_size.y1, scanlines.min_y()),
- std::max(marker_size.x2, scanlines.max_x()),
- std::max(marker_size.y2, scanlines.max_y()));
-
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(gc.cliprect, rendererBase);
- bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans, gc.snap_mode);
-
- double x, y;
-
- agg::serialized_scanlines_adaptor_aa8 sa;
- agg::serialized_scanlines_adaptor_aa8::embedded_scanline sl;
-
- agg::rect_d clipping_rect(-1.0 - marker_size.x2,
- -1.0 - marker_size.y2,
- 1.0 + width - marker_size.x1,
- 1.0 + height - marker_size.y1);
-
- if (has_clippath) {
- while (path_curve.vertex(&x, &y) != agg::path_cmd_stop) {
- if (!(std::isfinite(x) && std::isfinite(y))) {
- continue;
- }
-
- /* These values are correctly snapped above -- so we don't want
- to round here, we really only want to truncate */
- x = floor(x);
- y = floor(y);
-
- // Cull points outside the boundary of the image.
- // Values that are too large may overflow and create
- // segfaults.
- // http://sourceforge.net/tracker/?func=detail&aid=2865490&group_id=80706&atid=560720
- if (!clipping_rect.hit_test(x, y)) {
- continue;
- }
-
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_aa_renderer_type ren(r);
-
- if (face.first) {
- ren.color(face.second);
- sa.init(fillCache, fillSize, x, y);
- agg::render_scanlines(sa, sl, ren);
- }
- ren.color(gc.color);
- sa.init(strokeCache, strokeSize, x, y);
- agg::render_scanlines(sa, sl, ren);
- }
- } else {
- while (path_curve.vertex(&x, &y) != agg::path_cmd_stop) {
- if (!(std::isfinite(x) && std::isfinite(y))) {
- continue;
- }
-
- /* These values are correctly snapped above -- so we don't want
- to round here, we really only want to truncate */
- x = floor(x);
- y = floor(y);
-
- // Cull points outside the boundary of the image.
- // Values that are too large may overflow and create
- // segfaults.
- // http://sourceforge.net/tracker/?func=detail&aid=2865490&group_id=80706&atid=560720
- if (!clipping_rect.hit_test(x, y)) {
- continue;
- }
-
- if (face.first) {
- rendererAA.color(face.second);
- sa.init(fillCache, fillSize, x, y);
- agg::render_scanlines(sa, sl, rendererAA);
- }
-
- rendererAA.color(gc.color);
- sa.init(strokeCache, strokeSize, x, y);
- agg::render_scanlines(sa, sl, rendererAA);
- }
- }
- }
- catch (...)
- {
- if (fillCache != staticFillCache)
- delete[] fillCache;
- if (strokeCache != staticStrokeCache)
- delete[] strokeCache;
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- throw;
- }
-
- if (fillCache != staticFillCache)
- delete[] fillCache;
- if (strokeCache != staticStrokeCache)
- delete[] strokeCache;
-
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
-}
-
-/**
- * This is a custom span generator that converts spans in the
- * 8-bit inverted greyscale font buffer to rgba that agg can use.
- */
-template <class ChildGenerator>
-class font_to_rgba
-{
- public:
- typedef ChildGenerator child_type;
- typedef agg::rgba8 color_type;
- typedef typename child_type::color_type child_color_type;
- typedef agg::span_allocator<child_color_type> span_alloc_type;
-
- private:
- child_type *_gen;
- color_type _color;
- span_alloc_type _allocator;
-
- public:
- font_to_rgba(child_type *gen, color_type color) : _gen(gen), _color(color)
- {
- }
-
- inline void generate(color_type *output_span, int x, int y, unsigned len)
- {
- _allocator.allocate(len);
- child_color_type *input_span = _allocator.span();
- _gen->generate(input_span, x, y, len);
-
- do {
- *output_span = _color;
- output_span->a = ((unsigned int)_color.a * (unsigned int)input_span->v) >> 8;
- ++output_span;
- ++input_span;
- } while (--len);
- }
-
- void prepare()
- {
- _gen->prepare();
- }
-};
-
-template <class ImageArray>
-inline void RendererAgg::draw_text_image(GCAgg &gc, ImageArray &image, int x, int y, double angle)
-{
- typedef agg::span_allocator<agg::rgba8> color_span_alloc_type;
- typedef agg::span_interpolator_linear<> interpolator_type;
- typedef agg::image_accessor_clip<agg::pixfmt_gray8> image_accessor_type;
- typedef agg::span_image_filter_gray<image_accessor_type, interpolator_type> image_span_gen_type;
- typedef font_to_rgba<image_span_gen_type> span_gen_type;
- typedef agg::renderer_scanline_aa<renderer_base, color_span_alloc_type, span_gen_type>
- renderer_type;
-
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- if (angle != 0.0) {
- agg::rendering_buffer srcbuf(
- image.data(), (unsigned)image.dim(1),
- (unsigned)image.dim(0), (unsigned)image.dim(1));
- agg::pixfmt_gray8 pixf_img(srcbuf);
-
- set_clipbox(gc.cliprect, theRasterizer);
-
- agg::trans_affine mtx;
- mtx *= agg::trans_affine_translation(0, -image.dim(0));
- mtx *= agg::trans_affine_rotation(-angle * (agg::pi / 180.0));
- mtx *= agg::trans_affine_translation(x, y);
-
- agg::path_storage rect;
- rect.move_to(0, 0);
- rect.line_to(image.dim(1), 0);
- rect.line_to(image.dim(1), image.dim(0));
- rect.line_to(0, image.dim(0));
- rect.line_to(0, 0);
- agg::conv_transform<agg::path_storage> rect2(rect, mtx);
-
- agg::trans_affine inv_mtx(mtx);
- inv_mtx.invert();
-
- agg::image_filter_lut filter;
- filter.calculate(agg::image_filter_spline36());
- interpolator_type interpolator(inv_mtx);
- color_span_alloc_type sa;
- image_accessor_type ia(pixf_img, agg::gray8(0));
- image_span_gen_type image_span_generator(ia, interpolator, filter);
- span_gen_type output_span_generator(&image_span_generator, gc.color);
- renderer_type ri(rendererBase, sa, output_span_generator);
-
- theRasterizer.add_path(rect2);
- agg::render_scanlines(theRasterizer, slineP8, ri);
- } else {
- agg::rect_i fig, text;
-
- int deltay = y - image.dim(0);
-
- fig.init(0, 0, width, height);
- text.init(x, deltay, x + image.dim(1), y);
- text.clip(fig);
-
- if (gc.cliprect.x1 != 0.0 || gc.cliprect.y1 != 0.0 || gc.cliprect.x2 != 0.0 || gc.cliprect.y2 != 0.0) {
- agg::rect_i clip;
-
- clip.init(mpl_round_to_int(gc.cliprect.x1),
- mpl_round_to_int(height - gc.cliprect.y2),
- mpl_round_to_int(gc.cliprect.x2),
- mpl_round_to_int(height - gc.cliprect.y1));
- text.clip(clip);
- }
-
- if (text.x2 > text.x1) {
- int deltax = text.x2 - text.x1;
- int deltax2 = text.x1 - x;
- for (int yi = text.y1; yi < text.y2; ++yi) {
- pixFmt.blend_solid_hspan(text.x1, yi, deltax, gc.color,
- &image(yi - deltay, deltax2));
- }
- }
- }
-}
-
-class span_conv_alpha
-{
- public:
- typedef agg::rgba8 color_type;
-
- double m_alpha;
-
- span_conv_alpha(double alpha) : m_alpha(alpha)
- {
- }
-
- void prepare()
- {
- }
- void generate(color_type *span, int x, int y, unsigned len) const
- {
- do {
- span->a = (agg::int8u)((double)span->a * m_alpha);
- ++span;
- } while (--len);
- }
-};
-
-template <class ImageArray>
-inline void RendererAgg::draw_image(GCAgg &gc,
- double x,
- double y,
- ImageArray &image)
-{
- double alpha = gc.alpha;
-
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(gc.cliprect, theRasterizer);
- bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans, gc.snap_mode);
-
- agg::rendering_buffer buffer;
- buffer.attach(
- image.data(), (unsigned)image.dim(1), (unsigned)image.dim(0), -(int)image.dim(1) * 4);
- pixfmt pixf(buffer);
-
- if (has_clippath) {
- agg::trans_affine mtx;
- agg::path_storage rect;
-
- mtx *= agg::trans_affine_translation((int)x, (int)(height - (y + image.dim(0))));
-
- rect.move_to(0, 0);
- rect.line_to(image.dim(1), 0);
- rect.line_to(image.dim(1), image.dim(0));
- rect.line_to(0, image.dim(0));
- rect.line_to(0, 0);
-
- agg::conv_transform<agg::path_storage> rect2(rect, mtx);
-
- agg::trans_affine inv_mtx(mtx);
- inv_mtx.invert();
-
- typedef agg::span_allocator<agg::rgba8> color_span_alloc_type;
- typedef agg::image_accessor_clip<pixfmt> image_accessor_type;
- typedef agg::span_interpolator_linear<> interpolator_type;
- typedef agg::span_image_filter_rgba_nn<image_accessor_type, interpolator_type>
- image_span_gen_type;
- typedef agg::span_converter<image_span_gen_type, span_conv_alpha> span_conv;
-
- color_span_alloc_type sa;
- image_accessor_type ia(pixf, agg::rgba8(0, 0, 0, 0));
- interpolator_type interpolator(inv_mtx);
- image_span_gen_type image_span_generator(ia, interpolator);
- span_conv_alpha conv_alpha(alpha);
- span_conv spans(image_span_generator, conv_alpha);
-
- typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
- typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
- typedef agg::renderer_scanline_aa<amask_ren_type, color_span_alloc_type, span_conv>
- renderer_type_alpha;
-
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- renderer_type_alpha ri(r, sa, spans);
-
- theRasterizer.add_path(rect2);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ri);
- } else {
- set_clipbox(gc.cliprect, rendererBase);
- rendererBase.blend_from(
- pixf, 0, (int)x, (int)(height - (y + image.dim(0))), (agg::int8u)(alpha * 255));
- }
-
- rendererBase.reset_clipping(true);
-}
-
-template <class PathIterator,
- class PathGenerator,
- class TransformArray,
- class OffsetArray,
- class ColorArray,
- class LineWidthArray,
- class AntialiasedArray>
-inline void RendererAgg::_draw_path_collection_generic(GCAgg &gc,
- agg::trans_affine master_transform,
- const agg::rect_d &cliprect,
- PathIterator &clippath,
- const agg::trans_affine &clippath_trans,
- PathGenerator &path_generator,
- TransformArray &transforms,
- OffsetArray &offsets,
- const agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- ColorArray &edgecolors,
- LineWidthArray &linewidths,
- DashesVector &linestyles,
- AntialiasedArray &antialiaseds,
- bool check_snap,
- bool has_codes)
-{
- typedef agg::conv_transform<typename PathGenerator::path_iterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removed_t;
- typedef PathClipper<nan_removed_t> clipped_t;
- typedef PathSnapper<clipped_t> snapped_t;
- typedef agg::conv_curve<snapped_t> snapped_curve_t;
- typedef agg::conv_curve<clipped_t> curve_t;
-
- size_t Npaths = path_generator.num_paths();
- size_t Noffsets = offsets.size();
- size_t N = std::max(Npaths, Noffsets);
-
- size_t Ntransforms = transforms.size();
- size_t Nfacecolors = facecolors.size();
- size_t Nedgecolors = edgecolors.size();
- size_t Nlinewidths = linewidths.size();
- size_t Nlinestyles = std::min(linestyles.size(), N);
- size_t Naa = antialiaseds.size();
-
- if ((Nfacecolors == 0 && Nedgecolors == 0) || Npaths == 0) {
- return;
- }
-
- // Handle any clipping globally
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(cliprect, theRasterizer);
- bool has_clippath = render_clippath(clippath, clippath_trans, gc.snap_mode);
-
- // Set some defaults, assuming no face or edge
- gc.linewidth = 0.0;
- facepair_t face;
- face.first = Nfacecolors != 0;
- agg::trans_affine trans;
- bool do_clip = !face.first && !gc.has_hatchpath();
-
- for (int i = 0; i < (int)N; ++i) {
- typename PathGenerator::path_iterator path = path_generator(i);
-
- if (Ntransforms) {
- int it = i % Ntransforms;
- trans = agg::trans_affine(transforms(it, 0, 0),
- transforms(it, 1, 0),
- transforms(it, 0, 1),
- transforms(it, 1, 1),
- transforms(it, 0, 2),
- transforms(it, 1, 2));
- trans *= master_transform;
- } else {
- trans = master_transform;
- }
-
- if (Noffsets) {
- double xo = offsets(i % Noffsets, 0);
- double yo = offsets(i % Noffsets, 1);
- offset_trans.transform(&xo, &yo);
- trans *= agg::trans_affine_translation(xo, yo);
- }
-
- // These transformations must be done post-offsets
- trans *= agg::trans_affine_scaling(1.0, -1.0);
- trans *= agg::trans_affine_translation(0.0, (double)height);
-
- if (Nfacecolors) {
- int ic = i % Nfacecolors;
- face.second = agg::rgba(facecolors(ic, 0), facecolors(ic, 1), facecolors(ic, 2), facecolors(ic, 3));
- }
-
- if (Nedgecolors) {
- int ic = i % Nedgecolors;
- gc.color = agg::rgba(edgecolors(ic, 0), edgecolors(ic, 1), edgecolors(ic, 2), edgecolors(ic, 3));
-
- if (Nlinewidths) {
- gc.linewidth = linewidths(i % Nlinewidths);
- } else {
- gc.linewidth = 1.0;
- }
- if (Nlinestyles) {
- gc.dashes = linestyles[i % Nlinestyles];
- }
- }
-
- if (check_snap) {
- gc.isaa = antialiaseds(i % Naa);
-
- transformed_path_t tpath(path, trans);
- nan_removed_t nan_removed(tpath, true, has_codes);
- clipped_t clipped(nan_removed, do_clip, width, height);
- snapped_t snapped(
- clipped, gc.snap_mode, path.total_vertices(), points_to_pixels(gc.linewidth));
- if (has_codes) {
- snapped_curve_t curve(snapped);
- _draw_path(curve, has_clippath, face, gc);
- } else {
- _draw_path(snapped, has_clippath, face, gc);
- }
- } else {
- gc.isaa = antialiaseds(i % Naa);
-
- transformed_path_t tpath(path, trans);
- nan_removed_t nan_removed(tpath, true, has_codes);
- clipped_t clipped(nan_removed, do_clip, width, height);
- if (has_codes) {
- curve_t curve(clipped);
- _draw_path(curve, has_clippath, face, gc);
- } else {
- _draw_path(clipped, has_clippath, face, gc);
- }
- }
- }
-}
-
-template <class PathGenerator,
- class TransformArray,
- class OffsetArray,
- class ColorArray,
- class LineWidthArray,
- class AntialiasedArray>
-inline void RendererAgg::draw_path_collection(GCAgg &gc,
- agg::trans_affine &master_transform,
- PathGenerator &path,
- TransformArray &transforms,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- ColorArray &edgecolors,
- LineWidthArray &linewidths,
- DashesVector &linestyles,
- AntialiasedArray &antialiaseds)
-{
- _draw_path_collection_generic(gc,
- master_transform,
- gc.cliprect,
- gc.clippath.path,
- gc.clippath.trans,
- path,
- transforms,
- offsets,
- offset_trans,
- facecolors,
- edgecolors,
- linewidths,
- linestyles,
- antialiaseds,
- true,
- true);
-}
-
-template <class CoordinateArray>
-class QuadMeshGenerator
-{
- unsigned m_meshWidth;
- unsigned m_meshHeight;
- CoordinateArray m_coordinates;
-
- class QuadMeshPathIterator
- {
- unsigned m_iterator;
- unsigned m_m, m_n;
- const CoordinateArray *m_coordinates;
-
- public:
- QuadMeshPathIterator(unsigned m, unsigned n, const CoordinateArray *coordinates)
- : m_iterator(0), m_m(m), m_n(n), m_coordinates(coordinates)
- {
- }
-
- private:
- inline unsigned vertex(unsigned idx, double *x, double *y)
- {
- size_t m = m_m + ((idx & 0x2) >> 1);
- size_t n = m_n + (((idx + 1) & 0x2) >> 1);
- *x = (*m_coordinates)(n, m, 0);
- *y = (*m_coordinates)(n, m, 1);
- return (idx) ? agg::path_cmd_line_to : agg::path_cmd_move_to;
- }
-
- public:
- inline unsigned vertex(double *x, double *y)
- {
- if (m_iterator >= total_vertices()) {
- return agg::path_cmd_stop;
- }
- return vertex(m_iterator++, x, y);
- }
-
- inline void rewind(unsigned path_id)
- {
- m_iterator = path_id;
- }
-
- inline unsigned total_vertices()
- {
- return 5;
- }
-
- inline bool should_simplify()
- {
- return false;
- }
- };
-
- public:
- typedef QuadMeshPathIterator path_iterator;
-
- inline QuadMeshGenerator(unsigned meshWidth, unsigned meshHeight, CoordinateArray &coordinates)
- : m_meshWidth(meshWidth), m_meshHeight(meshHeight), m_coordinates(coordinates)
- {
- }
-
- inline size_t num_paths() const
- {
- return (size_t) m_meshWidth * m_meshHeight;
- }
-
- inline path_iterator operator()(size_t i) const
- {
- return QuadMeshPathIterator(i % m_meshWidth, i / m_meshWidth, &m_coordinates);
- }
-};
-
-template <class CoordinateArray, class OffsetArray, class ColorArray>
-inline void RendererAgg::draw_quad_mesh(GCAgg &gc,
- agg::trans_affine &master_transform,
- unsigned int mesh_width,
- unsigned int mesh_height,
- CoordinateArray &coordinates,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- bool antialiased,
- ColorArray &edgecolors)
-{
- QuadMeshGenerator<CoordinateArray> path_generator(mesh_width, mesh_height, coordinates);
-
- array::empty<double> transforms;
- array::scalar<double, 1> linewidths(gc.linewidth);
- array::scalar<uint8_t, 1> antialiaseds(antialiased);
- DashesVector linestyles;
-
- _draw_path_collection_generic(gc,
- master_transform,
- gc.cliprect,
- gc.clippath.path,
- gc.clippath.trans,
- path_generator,
- transforms,
- offsets,
- offset_trans,
- facecolors,
- edgecolors,
- linewidths,
- linestyles,
- antialiaseds,
- true, // check_snap
- false);
-}
-
-template <class PointArray, class ColorArray>
-inline void RendererAgg::_draw_gouraud_triangle(PointArray &points,
- ColorArray &colors,
- agg::trans_affine trans,
- bool has_clippath)
-{
- typedef agg::rgba8 color_t;
- typedef agg::span_gouraud_rgba<color_t> span_gen_t;
- typedef agg::span_allocator<color_t> span_alloc_t;
-
- trans *= agg::trans_affine_scaling(1.0, -1.0);
- trans *= agg::trans_affine_translation(0.0, (double)height);
-
- double tpoints[3][2];
-
- for (int i = 0; i < 3; ++i) {
- for (int j = 0; j < 2; ++j) {
- tpoints[i][j] = points(i, j);
- }
- trans.transform(&tpoints[i][0], &tpoints[i][1]);
- if(std::isnan(tpoints[i][0]) || std::isnan(tpoints[i][1])) {
- return;
- }
- }
-
- span_alloc_t span_alloc;
- span_gen_t span_gen;
-
- span_gen.colors(agg::rgba(colors(0, 0), colors(0, 1), colors(0, 2), colors(0, 3)),
- agg::rgba(colors(1, 0), colors(1, 1), colors(1, 2), colors(1, 3)),
- agg::rgba(colors(2, 0), colors(2, 1), colors(2, 2), colors(2, 3)));
- span_gen.triangle(tpoints[0][0],
- tpoints[0][1],
- tpoints[1][0],
- tpoints[1][1],
- tpoints[2][0],
- tpoints[2][1],
- 0.5);
-
- theRasterizer.add_path(span_gen);
-
- if (has_clippath) {
- typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
- typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
- typedef agg::renderer_scanline_aa<amask_ren_type, span_alloc_t, span_gen_t>
- amask_aa_renderer_type;
-
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_aa_renderer_type ren(r, span_alloc, span_gen);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ren);
- } else {
- agg::render_scanlines_aa(theRasterizer, slineP8, rendererBase, span_alloc, span_gen);
- }
-}
-
-template <class PointArray, class ColorArray>
-inline void RendererAgg::draw_gouraud_triangle(GCAgg &gc,
- PointArray &points,
- ColorArray &colors,
- agg::trans_affine &trans)
-{
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(gc.cliprect, theRasterizer);
- bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans, gc.snap_mode);
-
- _draw_gouraud_triangle(points, colors, trans, has_clippath);
-}
-
-template <class PointArray, class ColorArray>
-inline void RendererAgg::draw_gouraud_triangles(GCAgg &gc,
- PointArray &points,
- ColorArray &colors,
- agg::trans_affine &trans)
-{
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(gc.cliprect, theRasterizer);
- bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans, gc.snap_mode);
-
- for (int i = 0; i < points.dim(0); ++i) {
- typename PointArray::sub_t point = points.subarray(i);
- typename ColorArray::sub_t color = colors.subarray(i);
-
- _draw_gouraud_triangle(point, color, trans, has_clippath);
- }
-}
-
-template <class R>
-void RendererAgg::set_clipbox(const agg::rect_d &cliprect, R &rasterizer)
-{
- // set the clip rectangle from the gc
-
- if (cliprect.x1 != 0.0 || cliprect.y1 != 0.0 || cliprect.x2 != 0.0 || cliprect.y2 != 0.0) {
- rasterizer.clip_box(std::max(int(floor(cliprect.x1 + 0.5)), 0),
- std::max(int(floor(height - cliprect.y1 + 0.5)), 0),
- std::min(int(floor(cliprect.x2 + 0.5)), int(width)),
- std::min(int(floor(height - cliprect.y2 + 0.5)), int(height)));
- } else {
- rasterizer.clip_box(0, 0, width, height);
- }
-}
-
-#endif
diff --git a/contrib/python/matplotlib/py3/src/_backend_agg_basic_types.h b/contrib/python/matplotlib/py3/src/_backend_agg_basic_types.h
deleted file mode 100644
index 21a84bb6a5..0000000000
--- a/contrib/python/matplotlib/py3/src/_backend_agg_basic_types.h
+++ /dev/null
@@ -1,123 +0,0 @@
-#ifndef MPL_BACKEND_AGG_BASIC_TYPES_H
-#define MPL_BACKEND_AGG_BASIC_TYPES_H
-
-/* Contains some simple types from the Agg backend that are also used
- by other modules */
-
-#include <vector>
-
-#include "agg_color_rgba.h"
-#include "agg_math_stroke.h"
-#include "path_converters.h"
-
-#include "py_adaptors.h"
-
-struct ClipPath
-{
- py::PathIterator path;
- agg::trans_affine trans;
-};
-
-struct SketchParams
-{
- double scale;
- double length;
- double randomness;
-};
-
-class Dashes
-{
- typedef std::vector<std::pair<double, double> > dash_t;
- double dash_offset;
- dash_t dashes;
-
- public:
- double get_dash_offset() const
- {
- return dash_offset;
- }
- void set_dash_offset(double x)
- {
- dash_offset = x;
- }
- void add_dash_pair(double length, double skip)
- {
- dashes.push_back(std::make_pair(length, skip));
- }
- size_t size() const
- {
- return dashes.size();
- }
-
- template <class T>
- void dash_to_stroke(T &stroke, double dpi, bool isaa)
- {
- double scaleddpi = dpi / 72.0;
- for (dash_t::const_iterator i = dashes.begin(); i != dashes.end(); ++i) {
- double val0 = i->first;
- double val1 = i->second;
- val0 = val0 * scaleddpi;
- val1 = val1 * scaleddpi;
- if (!isaa) {
- val0 = (int)val0 + 0.5;
- val1 = (int)val1 + 0.5;
- }
- stroke.add_dash(val0, val1);
- }
- stroke.dash_start(get_dash_offset() * scaleddpi);
- }
-};
-
-typedef std::vector<Dashes> DashesVector;
-
-class GCAgg
-{
- public:
- GCAgg()
- : linewidth(1.0),
- alpha(1.0),
- cap(agg::butt_cap),
- join(agg::round_join),
- snap_mode(SNAP_FALSE)
- {
- }
-
- ~GCAgg()
- {
- }
-
- double linewidth;
- double alpha;
- bool forced_alpha;
- agg::rgba color;
- bool isaa;
-
- agg::line_cap_e cap;
- agg::line_join_e join;
-
- agg::rect_d cliprect;
-
- ClipPath clippath;
-
- Dashes dashes;
-
- e_snap_mode snap_mode;
-
- py::PathIterator hatchpath;
- agg::rgba hatch_color;
- double hatch_linewidth;
-
- SketchParams sketch;
-
- bool has_hatchpath()
- {
- return hatchpath.total_vertices() != 0;
- }
-
- private:
- // prevent copying
- GCAgg(const GCAgg &);
- GCAgg &operator=(const GCAgg &);
-};
-
-#endif
diff --git a/contrib/python/matplotlib/py3/src/_backend_agg_wrapper.cpp b/contrib/python/matplotlib/py3/src/_backend_agg_wrapper.cpp
deleted file mode 100644
index ee69729be7..0000000000
--- a/contrib/python/matplotlib/py3/src/_backend_agg_wrapper.cpp
+++ /dev/null
@@ -1,646 +0,0 @@
-#include "mplutils.h"
-#include "numpy_cpp.h"
-#include "py_converters.h"
-#include "_backend_agg.h"
-
-typedef struct
-{
- PyObject_HEAD
- RendererAgg *x;
- Py_ssize_t shape[3];
- Py_ssize_t strides[3];
- Py_ssize_t suboffsets[3];
-} PyRendererAgg;
-
-static PyTypeObject PyRendererAggType;
-
-typedef struct
-{
- PyObject_HEAD
- BufferRegion *x;
- Py_ssize_t shape[3];
- Py_ssize_t strides[3];
- Py_ssize_t suboffsets[3];
-} PyBufferRegion;
-
-static PyTypeObject PyBufferRegionType;
-
-
-/**********************************************************************
- * BufferRegion
- * */
-
-static PyObject *PyBufferRegion_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyBufferRegion *self;
- self = (PyBufferRegion *)type->tp_alloc(type, 0);
- self->x = NULL;
- return (PyObject *)self;
-}
-
-static void PyBufferRegion_dealloc(PyBufferRegion *self)
-{
- delete self->x;
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-static PyObject *PyBufferRegion_to_string(PyBufferRegion *self, PyObject *args)
-{
- char const* msg =
- "BufferRegion.to_string is deprecated since Matplotlib 3.7 and will "
- "be removed two minor releases later; use np.asarray(region) instead.";
- if (PyErr_WarnEx(PyExc_DeprecationWarning, msg, 1)) {
- return NULL;
- }
- return PyBytes_FromStringAndSize((const char *)self->x->get_data(),
- (Py_ssize_t) self->x->get_height() * self->x->get_stride());
-}
-
-/* TODO: This doesn't seem to be used internally. Remove? */
-
-static PyObject *PyBufferRegion_set_x(PyBufferRegion *self, PyObject *args)
-{
- int x;
- if (!PyArg_ParseTuple(args, "i:set_x", &x)) {
- return NULL;
- }
- self->x->get_rect().x1 = x;
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyBufferRegion_set_y(PyBufferRegion *self, PyObject *args)
-{
- int y;
- if (!PyArg_ParseTuple(args, "i:set_y", &y)) {
- return NULL;
- }
- self->x->get_rect().y1 = y;
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyBufferRegion_get_extents(PyBufferRegion *self, PyObject *args)
-{
- agg::rect_i rect = self->x->get_rect();
-
- return Py_BuildValue("IIII", rect.x1, rect.y1, rect.x2, rect.y2);
-}
-
-static PyObject *PyBufferRegion_to_string_argb(PyBufferRegion *self, PyObject *args)
-{
- char const* msg =
- "BufferRegion.to_string_argb is deprecated since Matplotlib 3.7 and "
- "will be removed two minor releases later; use "
- "np.take(region, [2, 1, 0, 3], axis=2) instead.";
- if (PyErr_WarnEx(PyExc_DeprecationWarning, msg, 1)) {
- return NULL;
- }
- PyObject *bufobj;
- uint8_t *buf;
- Py_ssize_t height, stride;
- height = self->x->get_height();
- stride = self->x->get_stride();
- bufobj = PyBytes_FromStringAndSize(NULL, height * stride);
- buf = (uint8_t *)PyBytes_AS_STRING(bufobj);
-
- CALL_CPP_CLEANUP("to_string_argb", (self->x->to_string_argb(buf)), Py_DECREF(bufobj));
-
- return bufobj;
-}
-
-int PyBufferRegion_get_buffer(PyBufferRegion *self, Py_buffer *buf, int flags)
-{
- Py_INCREF(self);
- buf->obj = (PyObject *)self;
- buf->buf = self->x->get_data();
- buf->len = (Py_ssize_t)self->x->get_width() * (Py_ssize_t)self->x->get_height() * 4;
- buf->readonly = 0;
- buf->format = (char *)"B";
- buf->ndim = 3;
- self->shape[0] = self->x->get_height();
- self->shape[1] = self->x->get_width();
- self->shape[2] = 4;
- buf->shape = self->shape;
- self->strides[0] = self->x->get_width() * 4;
- self->strides[1] = 4;
- self->strides[2] = 1;
- buf->strides = self->strides;
- buf->suboffsets = NULL;
- buf->itemsize = 1;
- buf->internal = NULL;
-
- return 1;
-}
-
-static PyTypeObject *PyBufferRegion_init_type()
-{
- static PyMethodDef methods[] = {
- { "to_string", (PyCFunction)PyBufferRegion_to_string, METH_NOARGS, NULL },
- { "to_string_argb", (PyCFunction)PyBufferRegion_to_string_argb, METH_NOARGS, NULL },
- { "set_x", (PyCFunction)PyBufferRegion_set_x, METH_VARARGS, NULL },
- { "set_y", (PyCFunction)PyBufferRegion_set_y, METH_VARARGS, NULL },
- { "get_extents", (PyCFunction)PyBufferRegion_get_extents, METH_NOARGS, NULL },
- { NULL }
- };
-
- static PyBufferProcs buffer_procs;
- buffer_procs.bf_getbuffer = (getbufferproc)PyBufferRegion_get_buffer;
-
- PyBufferRegionType.tp_name = "matplotlib.backends._backend_agg.BufferRegion";
- PyBufferRegionType.tp_basicsize = sizeof(PyBufferRegion);
- PyBufferRegionType.tp_dealloc = (destructor)PyBufferRegion_dealloc;
- PyBufferRegionType.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
- PyBufferRegionType.tp_methods = methods;
- PyBufferRegionType.tp_new = PyBufferRegion_new;
- PyBufferRegionType.tp_as_buffer = &buffer_procs;
-
- return &PyBufferRegionType;
-}
-
-/**********************************************************************
- * RendererAgg
- * */
-
-static PyObject *PyRendererAgg_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyRendererAgg *self;
- self = (PyRendererAgg *)type->tp_alloc(type, 0);
- self->x = NULL;
- return (PyObject *)self;
-}
-
-static int PyRendererAgg_init(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- unsigned int width;
- unsigned int height;
- double dpi;
- int debug = 0;
-
- if (!PyArg_ParseTuple(args, "IId|i:RendererAgg", &width, &height, &dpi, &debug)) {
- return -1;
- }
-
- if (dpi <= 0.0) {
- PyErr_SetString(PyExc_ValueError, "dpi must be positive");
- return -1;
- }
-
- if (width >= 1 << 16 || height >= 1 << 16) {
- PyErr_Format(
- PyExc_ValueError,
- "Image size of %dx%d pixels is too large. "
- "It must be less than 2^16 in each direction.",
- width, height);
- return -1;
- }
-
- CALL_CPP_INIT("RendererAgg", self->x = new RendererAgg(width, height, dpi))
-
- return 0;
-}
-
-static void PyRendererAgg_dealloc(PyRendererAgg *self)
-{
- delete self->x;
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-static PyObject *PyRendererAgg_draw_path(PyRendererAgg *self, PyObject *args)
-{
- GCAgg gc;
- py::PathIterator path;
- agg::trans_affine trans;
- PyObject *faceobj = NULL;
- agg::rgba face;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&|O:draw_path",
- &convert_gcagg,
- &gc,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &faceobj)) {
- return NULL;
- }
-
- if (!convert_face(faceobj, gc, &face)) {
- return NULL;
- }
-
- CALL_CPP("draw_path", (self->x->draw_path(gc, path, trans, face)));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyRendererAgg_draw_text_image(PyRendererAgg *self, PyObject *args)
-{
- numpy::array_view<agg::int8u, 2> image;
- double x;
- double y;
- double angle;
- GCAgg gc;
-
- if (!PyArg_ParseTuple(args,
- "O&dddO&:draw_text_image",
- &image.converter_contiguous,
- &image,
- &x,
- &y,
- &angle,
- &convert_gcagg,
- &gc)) {
- return NULL;
- }
-
- CALL_CPP("draw_text_image", (self->x->draw_text_image(gc, image, x, y, angle)));
-
- Py_RETURN_NONE;
-}
-
-PyObject *PyRendererAgg_draw_markers(PyRendererAgg *self, PyObject *args)
-{
- GCAgg gc;
- py::PathIterator marker_path;
- agg::trans_affine marker_path_trans;
- py::PathIterator path;
- agg::trans_affine trans;
- PyObject *faceobj = NULL;
- agg::rgba face;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&O&|O:draw_markers",
- &convert_gcagg,
- &gc,
- &convert_path,
- &marker_path,
- &convert_trans_affine,
- &marker_path_trans,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &faceobj)) {
- return NULL;
- }
-
- if (!convert_face(faceobj, gc, &face)) {
- return NULL;
- }
-
- CALL_CPP("draw_markers",
- (self->x->draw_markers(gc, marker_path, marker_path_trans, path, trans, face)));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyRendererAgg_draw_image(PyRendererAgg *self, PyObject *args)
-{
- GCAgg gc;
- double x;
- double y;
- numpy::array_view<agg::int8u, 3> image;
-
- if (!PyArg_ParseTuple(args,
- "O&ddO&:draw_image",
- &convert_gcagg,
- &gc,
- &x,
- &y,
- &image.converter_contiguous,
- &image)) {
- return NULL;
- }
-
- x = mpl_round(x);
- y = mpl_round(y);
-
- gc.alpha = 1.0;
- CALL_CPP("draw_image", (self->x->draw_image(gc, x, y, image)));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *
-PyRendererAgg_draw_path_collection(PyRendererAgg *self, PyObject *args)
-{
- GCAgg gc;
- agg::trans_affine master_transform;
- py::PathGenerator paths;
- numpy::array_view<const double, 3> transforms;
- numpy::array_view<const double, 2> offsets;
- agg::trans_affine offset_trans;
- numpy::array_view<const double, 2> facecolors;
- numpy::array_view<const double, 2> edgecolors;
- numpy::array_view<const double, 1> linewidths;
- DashesVector dashes;
- numpy::array_view<const uint8_t, 1> antialiaseds;
- PyObject *ignored;
- PyObject *offset_position; // offset position is no longer used
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&O&O&O&O&O&O&O&OO:draw_path_collection",
- &convert_gcagg,
- &gc,
- &convert_trans_affine,
- &master_transform,
- &convert_pathgen,
- &paths,
- &convert_transforms,
- &transforms,
- &convert_points,
- &offsets,
- &convert_trans_affine,
- &offset_trans,
- &convert_colors,
- &facecolors,
- &convert_colors,
- &edgecolors,
- &linewidths.converter,
- &linewidths,
- &convert_dashes_vector,
- &dashes,
- &antialiaseds.converter,
- &antialiaseds,
- &ignored,
- &offset_position)) {
- return NULL;
- }
-
- CALL_CPP("draw_path_collection",
- (self->x->draw_path_collection(gc,
- master_transform,
- paths,
- transforms,
- offsets,
- offset_trans,
- facecolors,
- edgecolors,
- linewidths,
- dashes,
- antialiaseds)));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyRendererAgg_draw_quad_mesh(PyRendererAgg *self, PyObject *args)
-{
- GCAgg gc;
- agg::trans_affine master_transform;
- unsigned int mesh_width;
- unsigned int mesh_height;
- numpy::array_view<const double, 3> coordinates;
- numpy::array_view<const double, 2> offsets;
- agg::trans_affine offset_trans;
- numpy::array_view<const double, 2> facecolors;
- bool antialiased;
- numpy::array_view<const double, 2> edgecolors;
-
- if (!PyArg_ParseTuple(args,
- "O&O&IIO&O&O&O&O&O&:draw_quad_mesh",
- &convert_gcagg,
- &gc,
- &convert_trans_affine,
- &master_transform,
- &mesh_width,
- &mesh_height,
- &coordinates.converter,
- &coordinates,
- &convert_points,
- &offsets,
- &convert_trans_affine,
- &offset_trans,
- &convert_colors,
- &facecolors,
- &convert_bool,
- &antialiased,
- &convert_colors,
- &edgecolors)) {
- return NULL;
- }
-
- CALL_CPP("draw_quad_mesh",
- (self->x->draw_quad_mesh(gc,
- master_transform,
- mesh_width,
- mesh_height,
- coordinates,
- offsets,
- offset_trans,
- facecolors,
- antialiased,
- edgecolors)));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *
-PyRendererAgg_draw_gouraud_triangle(PyRendererAgg *self, PyObject *args)
-{
- GCAgg gc;
- numpy::array_view<const double, 2> points;
- numpy::array_view<const double, 2> colors;
- agg::trans_affine trans;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&|O:draw_gouraud_triangle",
- &convert_gcagg,
- &gc,
- &points.converter,
- &points,
- &colors.converter,
- &colors,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- if (points.dim(0) != 3 || points.dim(1) != 2) {
- PyErr_Format(PyExc_ValueError,
- "points must have shape (3, 2), "
- "got (%" NPY_INTP_FMT ", %" NPY_INTP_FMT ")",
- points.dim(0), points.dim(1));
- return NULL;
- }
-
- if (colors.dim(0) != 3 || colors.dim(1) != 4) {
- PyErr_Format(PyExc_ValueError,
- "colors must have shape (3, 4), "
- "got (%" NPY_INTP_FMT ", %" NPY_INTP_FMT ")",
- colors.dim(0), colors.dim(1));
- return NULL;
- }
-
-
- CALL_CPP("draw_gouraud_triangle", (self->x->draw_gouraud_triangle(gc, points, colors, trans)));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *
-PyRendererAgg_draw_gouraud_triangles(PyRendererAgg *self, PyObject *args)
-{
- GCAgg gc;
- numpy::array_view<const double, 3> points;
- numpy::array_view<const double, 3> colors;
- agg::trans_affine trans;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&|O:draw_gouraud_triangles",
- &convert_gcagg,
- &gc,
- &points.converter,
- &points,
- &colors.converter,
- &colors,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
- if (points.size() && !check_trailing_shape(points, "points", 3, 2)) {
- return NULL;
- }
- if (colors.size() && !check_trailing_shape(colors, "colors", 3, 4)) {
- return NULL;
- }
- if (points.size() != colors.size()) {
- PyErr_Format(PyExc_ValueError,
- "points and colors arrays must be the same length, got "
- "%" NPY_INTP_FMT " points and %" NPY_INTP_FMT "colors",
- points.dim(0), colors.dim(0));
- return NULL;
- }
-
- CALL_CPP("draw_gouraud_triangles", self->x->draw_gouraud_triangles(gc, points, colors, trans));
-
- Py_RETURN_NONE;
-}
-
-int PyRendererAgg_get_buffer(PyRendererAgg *self, Py_buffer *buf, int flags)
-{
- Py_INCREF(self);
- buf->obj = (PyObject *)self;
- buf->buf = self->x->pixBuffer;
- buf->len = (Py_ssize_t)self->x->get_width() * (Py_ssize_t)self->x->get_height() * 4;
- buf->readonly = 0;
- buf->format = (char *)"B";
- buf->ndim = 3;
- self->shape[0] = self->x->get_height();
- self->shape[1] = self->x->get_width();
- self->shape[2] = 4;
- buf->shape = self->shape;
- self->strides[0] = self->x->get_width() * 4;
- self->strides[1] = 4;
- self->strides[2] = 1;
- buf->strides = self->strides;
- buf->suboffsets = NULL;
- buf->itemsize = 1;
- buf->internal = NULL;
-
- return 1;
-}
-
-static PyObject *PyRendererAgg_clear(PyRendererAgg *self, PyObject *args)
-{
- CALL_CPP("clear", self->x->clear());
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyRendererAgg_copy_from_bbox(PyRendererAgg *self, PyObject *args)
-{
- agg::rect_d bbox;
- BufferRegion *reg;
- PyObject *regobj;
-
- if (!PyArg_ParseTuple(args, "O&:copy_from_bbox", &convert_rect, &bbox)) {
- return 0;
- }
-
- CALL_CPP("copy_from_bbox", (reg = self->x->copy_from_bbox(bbox)));
-
- regobj = PyBufferRegion_new(&PyBufferRegionType, NULL, NULL);
- ((PyBufferRegion *)regobj)->x = reg;
-
- return regobj;
-}
-
-static PyObject *PyRendererAgg_restore_region(PyRendererAgg *self, PyObject *args)
-{
- PyBufferRegion *regobj;
- int xx1 = 0, yy1 = 0, xx2 = 0, yy2 = 0, x = 0, y = 0;
-
- if (!PyArg_ParseTuple(args,
- "O!|iiiiii:restore_region",
- &PyBufferRegionType,
- &regobj,
- &xx1,
- &yy1,
- &xx2,
- &yy2,
- &x,
- &y)) {
- return 0;
- }
-
- if (PySequence_Size(args) == 1) {
- CALL_CPP("restore_region", self->x->restore_region(*(regobj->x)));
- } else {
- CALL_CPP("restore_region", self->x->restore_region(*(regobj->x), xx1, yy1, xx2, yy2, x, y));
- }
-
- Py_RETURN_NONE;
-}
-
-static PyTypeObject *PyRendererAgg_init_type()
-{
- static PyMethodDef methods[] = {
- {"draw_path", (PyCFunction)PyRendererAgg_draw_path, METH_VARARGS, NULL},
- {"draw_markers", (PyCFunction)PyRendererAgg_draw_markers, METH_VARARGS, NULL},
- {"draw_text_image", (PyCFunction)PyRendererAgg_draw_text_image, METH_VARARGS, NULL},
- {"draw_image", (PyCFunction)PyRendererAgg_draw_image, METH_VARARGS, NULL},
- {"draw_path_collection", (PyCFunction)PyRendererAgg_draw_path_collection, METH_VARARGS, NULL},
- {"draw_quad_mesh", (PyCFunction)PyRendererAgg_draw_quad_mesh, METH_VARARGS, NULL},
- {"draw_gouraud_triangle", (PyCFunction)PyRendererAgg_draw_gouraud_triangle, METH_VARARGS, NULL},
- {"draw_gouraud_triangles", (PyCFunction)PyRendererAgg_draw_gouraud_triangles, METH_VARARGS, NULL},
-
- {"clear", (PyCFunction)PyRendererAgg_clear, METH_NOARGS, NULL},
-
- {"copy_from_bbox", (PyCFunction)PyRendererAgg_copy_from_bbox, METH_VARARGS, NULL},
- {"restore_region", (PyCFunction)PyRendererAgg_restore_region, METH_VARARGS, NULL},
- {NULL}
- };
-
- static PyBufferProcs buffer_procs;
- buffer_procs.bf_getbuffer = (getbufferproc)PyRendererAgg_get_buffer;
-
- PyRendererAggType.tp_name = "matplotlib.backends._backend_agg.RendererAgg";
- PyRendererAggType.tp_basicsize = sizeof(PyRendererAgg);
- PyRendererAggType.tp_dealloc = (destructor)PyRendererAgg_dealloc;
- PyRendererAggType.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
- PyRendererAggType.tp_methods = methods;
- PyRendererAggType.tp_init = (initproc)PyRendererAgg_init;
- PyRendererAggType.tp_new = PyRendererAgg_new;
- PyRendererAggType.tp_as_buffer = &buffer_procs;
-
- return &PyRendererAggType;
-}
-
-static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "_backend_agg" };
-
-PyMODINIT_FUNC PyInit__backend_agg(void)
-{
- import_array();
- PyObject *m;
- if (!(m = PyModule_Create(&moduledef))
- || prepare_and_add_type(PyRendererAgg_init_type(), m)
- // BufferRegion is not constructible from Python, thus not added to the module.
- || PyType_Ready(PyBufferRegion_init_type())
- ) {
- Py_XDECREF(m);
- return NULL;
- }
- return m;
-}
diff --git a/contrib/python/matplotlib/py3/src/_c_internal_utils.c b/contrib/python/matplotlib/py3/src/_c_internal_utils.c
deleted file mode 100644
index f1bd22a42c..0000000000
--- a/contrib/python/matplotlib/py3/src/_c_internal_utils.c
+++ /dev/null
@@ -1,211 +0,0 @@
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-#ifdef __linux__
-#include <dlfcn.h>
-#endif
-#ifdef _WIN32
-#include <Objbase.h>
-#include <Shobjidl.h>
-#include <Windows.h>
-#endif
-
-static PyObject*
-mpl_display_is_valid(PyObject* module)
-{
-#ifdef __linux__
- void* libX11;
- // The getenv check is redundant but helps performance as it is much faster
- // than dlopen().
- if (getenv("DISPLAY")
- && (libX11 = dlopen("libX11.so.6", RTLD_LAZY))) {
- struct Display* display = NULL;
- struct Display* (* XOpenDisplay)(char const*) =
- dlsym(libX11, "XOpenDisplay");
- int (* XCloseDisplay)(struct Display*) =
- dlsym(libX11, "XCloseDisplay");
- if (XOpenDisplay && XCloseDisplay
- && (display = XOpenDisplay(NULL))) {
- XCloseDisplay(display);
- }
- if (dlclose(libX11)) {
- PyErr_SetString(PyExc_RuntimeError, dlerror());
- return NULL;
- }
- if (display) {
- Py_RETURN_TRUE;
- }
- }
- void* libwayland_client;
- if (getenv("WAYLAND_DISPLAY")
- && (libwayland_client = dlopen("libwayland-client.so.0", RTLD_LAZY))) {
- struct wl_display* display = NULL;
- struct wl_display* (* wl_display_connect)(char const*) =
- dlsym(libwayland_client, "wl_display_connect");
- void (* wl_display_disconnect)(struct wl_display*) =
- dlsym(libwayland_client, "wl_display_disconnect");
- if (wl_display_connect && wl_display_disconnect
- && (display = wl_display_connect(NULL))) {
- wl_display_disconnect(display);
- }
- if (dlclose(libwayland_client)) {
- PyErr_SetString(PyExc_RuntimeError, dlerror());
- return NULL;
- }
- if (display) {
- Py_RETURN_TRUE;
- }
- }
- Py_RETURN_FALSE;
-#else
- Py_RETURN_TRUE;
-#endif
-}
-
-static PyObject*
-mpl_GetCurrentProcessExplicitAppUserModelID(PyObject* module)
-{
-#ifdef _WIN32
- wchar_t* appid = NULL;
- HRESULT hr = GetCurrentProcessExplicitAppUserModelID(&appid);
- if (FAILED(hr)) {
- return PyErr_SetFromWindowsErr(hr);
- }
- PyObject* py_appid = PyUnicode_FromWideChar(appid, -1);
- CoTaskMemFree(appid);
- return py_appid;
-#else
- Py_RETURN_NONE;
-#endif
-}
-
-static PyObject*
-mpl_SetCurrentProcessExplicitAppUserModelID(PyObject* module, PyObject* arg)
-{
-#ifdef _WIN32
- wchar_t* appid = PyUnicode_AsWideCharString(arg, NULL);
- if (!appid) {
- return NULL;
- }
- HRESULT hr = SetCurrentProcessExplicitAppUserModelID(appid);
- PyMem_Free(appid);
- if (FAILED(hr)) {
- return PyErr_SetFromWindowsErr(hr);
- }
- Py_RETURN_NONE;
-#else
- Py_RETURN_NONE;
-#endif
-}
-
-static PyObject*
-mpl_GetForegroundWindow(PyObject* module)
-{
-#ifdef _WIN32
- return PyLong_FromVoidPtr(GetForegroundWindow());
-#else
- Py_RETURN_NONE;
-#endif
-}
-
-static PyObject*
-mpl_SetForegroundWindow(PyObject* module, PyObject *arg)
-{
-#ifdef _WIN32
- HWND handle = PyLong_AsVoidPtr(arg);
- if (PyErr_Occurred()) {
- return NULL;
- }
- if (!SetForegroundWindow(handle)) {
- return PyErr_Format(PyExc_RuntimeError, "Error setting window");
- }
- Py_RETURN_NONE;
-#else
- Py_RETURN_NONE;
-#endif
-}
-
-static PyObject*
-mpl_SetProcessDpiAwareness_max(PyObject* module)
-{
-#ifdef _WIN32
-#ifdef _DPI_AWARENESS_CONTEXTS_
- // These functions and options were added in later Windows 10 updates, so
- // must be loaded dynamically.
- typedef BOOL (WINAPI *IsValidDpiAwarenessContext_t)(DPI_AWARENESS_CONTEXT);
- typedef BOOL (WINAPI *SetProcessDpiAwarenessContext_t)(DPI_AWARENESS_CONTEXT);
-
- HMODULE user32 = LoadLibrary("user32.dll");
- IsValidDpiAwarenessContext_t IsValidDpiAwarenessContextPtr =
- (IsValidDpiAwarenessContext_t)GetProcAddress(
- user32, "IsValidDpiAwarenessContext");
- SetProcessDpiAwarenessContext_t SetProcessDpiAwarenessContextPtr =
- (SetProcessDpiAwarenessContext_t)GetProcAddress(
- user32, "SetProcessDpiAwarenessContext");
- DPI_AWARENESS_CONTEXT ctxs[3] = {
- DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2, // Win10 Creators Update
- DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE, // Win10
- DPI_AWARENESS_CONTEXT_SYSTEM_AWARE}; // Win10
- if (IsValidDpiAwarenessContextPtr != NULL
- && SetProcessDpiAwarenessContextPtr != NULL) {
- for (int i = 0; i < sizeof(ctxs) / sizeof(DPI_AWARENESS_CONTEXT); ++i) {
- if (IsValidDpiAwarenessContextPtr(ctxs[i])) {
- SetProcessDpiAwarenessContextPtr(ctxs[i]);
- break;
- }
- }
- } else {
- // Added in Windows Vista.
- SetProcessDPIAware();
- }
- FreeLibrary(user32);
-#else
- // Added in Windows Vista.
- SetProcessDPIAware();
-#endif
-#endif
- Py_RETURN_NONE;
-}
-
-static PyMethodDef functions[] = {
- {"display_is_valid", (PyCFunction)mpl_display_is_valid, METH_NOARGS,
- "display_is_valid()\n--\n\n"
- "Check whether the current X11 or Wayland display is valid.\n\n"
- "On Linux, returns True if either $DISPLAY is set and XOpenDisplay(NULL)\n"
- "succeeds, or $WAYLAND_DISPLAY is set and wl_display_connect(NULL)\n"
- "succeeds.\n\n"
- "On other platforms, always returns True."},
- {"Win32_GetCurrentProcessExplicitAppUserModelID",
- (PyCFunction)mpl_GetCurrentProcessExplicitAppUserModelID, METH_NOARGS,
- "Win32_GetCurrentProcessExplicitAppUserModelID()\n--\n\n"
- "Wrapper for Windows's GetCurrentProcessExplicitAppUserModelID.\n\n"
- "On non-Windows platforms, always returns None."},
- {"Win32_SetCurrentProcessExplicitAppUserModelID",
- (PyCFunction)mpl_SetCurrentProcessExplicitAppUserModelID, METH_O,
- "Win32_SetCurrentProcessExplicitAppUserModelID(appid, /)\n--\n\n"
- "Wrapper for Windows's SetCurrentProcessExplicitAppUserModelID.\n\n"
- "On non-Windows platforms, does nothing."},
- {"Win32_GetForegroundWindow",
- (PyCFunction)mpl_GetForegroundWindow, METH_NOARGS,
- "Win32_GetForegroundWindow()\n--\n\n"
- "Wrapper for Windows' GetForegroundWindow.\n\n"
- "On non-Windows platforms, always returns None."},
- {"Win32_SetForegroundWindow",
- (PyCFunction)mpl_SetForegroundWindow, METH_O,
- "Win32_SetForegroundWindow(hwnd, /)\n--\n\n"
- "Wrapper for Windows' SetForegroundWindow.\n\n"
- "On non-Windows platforms, does nothing."},
- {"Win32_SetProcessDpiAwareness_max",
- (PyCFunction)mpl_SetProcessDpiAwareness_max, METH_NOARGS,
- "Win32_SetProcessDpiAwareness_max()\n--\n\n"
- "Set Windows' process DPI awareness to best option available.\n\n"
- "On non-Windows platforms, does nothing."},
- {NULL, NULL}}; // sentinel.
-static PyModuleDef util_module = {
- PyModuleDef_HEAD_INIT, "_c_internal_utils", NULL, 0, functions
-};
-
-#pragma GCC visibility push(default)
-PyMODINIT_FUNC PyInit__c_internal_utils(void)
-{
- return PyModule_Create(&util_module);
-}
diff --git a/contrib/python/matplotlib/py3/src/_image_resample.h b/contrib/python/matplotlib/py3/src/_image_resample.h
deleted file mode 100644
index 2c91da4087..0000000000
--- a/contrib/python/matplotlib/py3/src/_image_resample.h
+++ /dev/null
@@ -1,834 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef MPL_RESAMPLE_H
-#define MPL_RESAMPLE_H
-
-#include "agg_image_accessors.h"
-#include "agg_path_storage.h"
-#include "agg_pixfmt_gray.h"
-#include "agg_pixfmt_rgb.h"
-#include "agg_pixfmt_rgba.h"
-#include "agg_renderer_base.h"
-#include "agg_renderer_scanline.h"
-#include "agg_rasterizer_scanline_aa.h"
-#include "agg_scanline_u.h"
-#include "agg_span_allocator.h"
-#include "agg_span_converter.h"
-#include "agg_span_image_filter_gray.h"
-#include "agg_span_image_filter_rgba.h"
-#include "agg_span_interpolator_adaptor.h"
-#include "agg_span_interpolator_linear.h"
-
-#include "agg_workaround.h"
-
-#include <type_traits>
-
-// Based on:
-
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://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://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.
-//
-
-//===================================================================gray64
-namespace agg
-{
- struct gray64
- {
- typedef double value_type;
- typedef double calc_type;
- typedef double long_type;
- typedef gray64 self_type;
-
- value_type v;
- value_type a;
-
- //--------------------------------------------------------------------
- gray64() {}
-
- //--------------------------------------------------------------------
- explicit gray64(value_type v_, value_type a_ = 1) :
- v(v_), a(a_) {}
-
- //--------------------------------------------------------------------
- gray64(const self_type& c, value_type a_) :
- v(c.v), a(a_) {}
-
- //--------------------------------------------------------------------
- gray64(const gray64& c) :
- v(c.v),
- a(c.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); }
- };
-
-
- //====================================================================rgba32
- struct rgba64
- {
- typedef double value_type;
- typedef double calc_type;
- typedef double long_type;
- typedef rgba64 self_type;
-
- value_type r;
- value_type g;
- value_type b;
- value_type a;
-
- //--------------------------------------------------------------------
- rgba64() {}
-
- //--------------------------------------------------------------------
- rgba64(value_type r_, value_type g_, value_type b_, value_type a_= 1) :
- r(r_), g(g_), b(b_), a(a_) {}
-
- //--------------------------------------------------------------------
- rgba64(const self_type& c, float a_) :
- r(c.r), g(c.g), b(c.b), a(a_) {}
-
- //--------------------------------------------------------------------
- rgba64(const rgba& c) :
- r(value_type(c.r)), g(value_type(c.g)), b(value_type(c.b)), a(value_type(c.a)) {}
-
- //--------------------------------------------------------------------
- operator rgba() const
- {
- return rgba(r, g, b, 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()
- {
- 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;
- }
-
- //--------------------------------------------------------------------
- static self_type no_color() { return self_type(0,0,0,0); }
- };
-}
-
-
-typedef enum {
- NEAREST,
- BILINEAR,
- BICUBIC,
- SPLINE16,
- SPLINE36,
- HANNING,
- HAMMING,
- HERMITE,
- KAISER,
- QUADRIC,
- CATROM,
- GAUSSIAN,
- BESSEL,
- MITCHELL,
- SINC,
- LANCZOS,
- BLACKMAN,
- _n_interpolation
-} interpolation_e;
-
-
-// T is rgba if and only if it has an T::r field.
-template<typename T, typename = void> struct is_grayscale : std::true_type {};
-template<typename T> struct is_grayscale<T, decltype(T::r, void())> : std::false_type {};
-
-
-template<typename color_type>
-struct type_mapping
-{
- using blender_type = typename std::conditional<
- is_grayscale<color_type>::value,
- agg::blender_gray<color_type>,
- typename std::conditional<
- std::is_same<color_type, agg::rgba8>::value,
- fixed_blender_rgba_plain<color_type, agg::order_rgba>,
- agg::blender_rgba_plain<color_type, agg::order_rgba>
- >::type
- >::type;
- using pixfmt_type = typename std::conditional<
- is_grayscale<color_type>::value,
- agg::pixfmt_alpha_blend_gray<blender_type, agg::rendering_buffer>,
- agg::pixfmt_alpha_blend_rgba<blender_type, agg::rendering_buffer>
- >::type;
- using pixfmt_pre_type = typename std::conditional<
- is_grayscale<color_type>::value,
- pixfmt_type,
- agg::pixfmt_alpha_blend_rgba<
- typename std::conditional<
- std::is_same<color_type, agg::rgba8>::value,
- fixed_blender_rgba_pre<color_type, agg::order_rgba>,
- agg::blender_rgba_pre<color_type, agg::order_rgba>
- >::type,
- agg::rendering_buffer>
- >::type;
- template<typename A> using span_gen_affine_type = typename std::conditional<
- is_grayscale<color_type>::value,
- agg::span_image_resample_gray_affine<A>,
- agg::span_image_resample_rgba_affine<A>
- >::type;
- template<typename A, typename B> using span_gen_filter_type = typename std::conditional<
- is_grayscale<color_type>::value,
- agg::span_image_filter_gray<A, B>,
- agg::span_image_filter_rgba<A, B>
- >::type;
- template<typename A, typename B> using span_gen_nn_type = typename std::conditional<
- is_grayscale<color_type>::value,
- agg::span_image_filter_gray_nn<A, B>,
- agg::span_image_filter_rgba_nn<A, B>
- >::type;
-};
-
-
-template<typename color_type>
-class span_conv_alpha
-{
-public:
- span_conv_alpha(const double alpha) :
- m_alpha(alpha)
- {
- }
-
- void prepare() {}
-
- void generate(color_type* span, int x, int y, unsigned len) const
- {
- if (m_alpha != 1.0) {
- do {
- span->a *= m_alpha;
- ++span;
- } while (--len);
- }
- }
-private:
-
- const double m_alpha;
-};
-
-
-/* A class to use a lookup table for a transformation */
-class lookup_distortion
-{
-public:
- lookup_distortion(const double *mesh, int in_width, int in_height,
- int out_width, int out_height) :
- m_mesh(mesh),
- m_in_width(in_width),
- m_in_height(in_height),
- m_out_width(out_width),
- m_out_height(out_height)
- {}
-
- void calculate(int* x, int* y) {
- if (m_mesh) {
- double dx = double(*x) / agg::image_subpixel_scale;
- double dy = double(*y) / agg::image_subpixel_scale;
- if (dx >= 0 && dx < m_out_width &&
- dy >= 0 && dy < m_out_height) {
- const double *coord = m_mesh + (int(dy) * m_out_width + int(dx)) * 2;
- *x = int(coord[0] * agg::image_subpixel_scale);
- *y = int(coord[1] * agg::image_subpixel_scale);
- }
- }
- }
-
-protected:
- const double *m_mesh;
- int m_in_width;
- int m_in_height;
- int m_out_width;
- int m_out_height;
-};
-
-
-struct resample_params_t {
- interpolation_e interpolation;
- bool is_affine;
- agg::trans_affine affine;
- const double *transform_mesh;
- bool resample;
- bool norm;
- double radius;
- double alpha;
-};
-
-
-static void get_filter(const resample_params_t &params,
- agg::image_filter_lut &filter)
-{
- switch (params.interpolation) {
- case NEAREST:
- case _n_interpolation:
- // Never should get here. Here to silence compiler warnings.
- break;
-
- case HANNING:
- filter.calculate(agg::image_filter_hanning(), params.norm);
- break;
-
- case HAMMING:
- filter.calculate(agg::image_filter_hamming(), params.norm);
- break;
-
- case HERMITE:
- filter.calculate(agg::image_filter_hermite(), params.norm);
- break;
-
- case BILINEAR:
- filter.calculate(agg::image_filter_bilinear(), params.norm);
- break;
-
- case BICUBIC:
- filter.calculate(agg::image_filter_bicubic(), params.norm);
- break;
-
- case SPLINE16:
- filter.calculate(agg::image_filter_spline16(), params.norm);
- break;
-
- case SPLINE36:
- filter.calculate(agg::image_filter_spline36(), params.norm);
- break;
-
- case KAISER:
- filter.calculate(agg::image_filter_kaiser(), params.norm);
- break;
-
- case QUADRIC:
- filter.calculate(agg::image_filter_quadric(), params.norm);
- break;
-
- case CATROM:
- filter.calculate(agg::image_filter_catrom(), params.norm);
- break;
-
- case GAUSSIAN:
- filter.calculate(agg::image_filter_gaussian(), params.norm);
- break;
-
- case BESSEL:
- filter.calculate(agg::image_filter_bessel(), params.norm);
- break;
-
- case MITCHELL:
- filter.calculate(agg::image_filter_mitchell(), params.norm);
- break;
-
- case SINC:
- filter.calculate(agg::image_filter_sinc(params.radius), params.norm);
- break;
-
- case LANCZOS:
- filter.calculate(agg::image_filter_lanczos(params.radius), params.norm);
- break;
-
- case BLACKMAN:
- filter.calculate(agg::image_filter_blackman(params.radius), params.norm);
- break;
- }
-}
-
-
-template<typename color_type>
-void resample(
- const void *input, int in_width, int in_height,
- void *output, int out_width, int out_height,
- resample_params_t &params)
-{
- using type_mapping_t = type_mapping<color_type>;
-
- using input_pixfmt_t = typename type_mapping_t::pixfmt_type;
- using output_pixfmt_t = typename type_mapping_t::pixfmt_type;
-
- using renderer_t = agg::renderer_base<output_pixfmt_t>;
- using rasterizer_t = agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl>;
-
- using reflect_t = agg::wrap_mode_reflect;
- using image_accessor_t = agg::image_accessor_wrap<input_pixfmt_t, reflect_t, reflect_t>;
-
- using span_alloc_t = agg::span_allocator<color_type>;
- using span_conv_alpha_t = span_conv_alpha<color_type>;
-
- using affine_interpolator_t = agg::span_interpolator_linear<>;
- using arbitrary_interpolator_t =
- agg::span_interpolator_adaptor<agg::span_interpolator_linear<>, lookup_distortion>;
-
- size_t itemsize = sizeof(color_type);
- if (is_grayscale<color_type>::value) {
- itemsize /= 2; // agg::grayXX includes an alpha channel which we don't have.
- }
-
- if (params.interpolation != NEAREST &&
- params.is_affine &&
- fabs(params.affine.sx) == 1.0 &&
- fabs(params.affine.sy) == 1.0 &&
- params.affine.shx == 0.0 &&
- params.affine.shy == 0.0) {
- params.interpolation = NEAREST;
- }
-
- span_alloc_t span_alloc;
- rasterizer_t rasterizer;
- agg::scanline_u8 scanline;
-
- span_conv_alpha_t conv_alpha(params.alpha);
-
- agg::rendering_buffer input_buffer;
- input_buffer.attach(
- (unsigned char *)input, in_width, in_height, in_width * itemsize);
- input_pixfmt_t input_pixfmt(input_buffer);
- image_accessor_t input_accessor(input_pixfmt);
-
- agg::rendering_buffer output_buffer;
- output_buffer.attach(
- (unsigned char *)output, out_width, out_height, out_width * itemsize);
- output_pixfmt_t output_pixfmt(output_buffer);
- renderer_t renderer(output_pixfmt);
-
- agg::trans_affine inverted = params.affine;
- inverted.invert();
-
- rasterizer.clip_box(0, 0, out_width, out_height);
-
- agg::path_storage path;
- if (params.is_affine) {
- path.move_to(0, 0);
- path.line_to(in_width, 0);
- path.line_to(in_width, in_height);
- path.line_to(0, in_height);
- path.close_polygon();
- agg::conv_transform<agg::path_storage> rectangle(path, params.affine);
- rasterizer.add_path(rectangle);
- } else {
- path.move_to(0, 0);
- path.line_to(out_width, 0);
- path.line_to(out_width, out_height);
- path.line_to(0, out_height);
- path.close_polygon();
- rasterizer.add_path(path);
- }
-
- if (params.interpolation == NEAREST) {
- if (params.is_affine) {
- using span_gen_t = typename type_mapping_t::template span_gen_nn_type<image_accessor_t, affine_interpolator_t>;
- using span_conv_t = agg::span_converter<span_gen_t, span_conv_alpha_t>;
- using nn_renderer_t = agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t>;
- affine_interpolator_t interpolator(inverted);
- span_gen_t span_gen(input_accessor, interpolator);
- span_conv_t span_conv(span_gen, conv_alpha);
- nn_renderer_t nn_renderer(renderer, span_alloc, span_conv);
- agg::render_scanlines(rasterizer, scanline, nn_renderer);
- } else {
- using span_gen_t = typename type_mapping_t::template span_gen_nn_type<image_accessor_t, arbitrary_interpolator_t>;
- using span_conv_t = agg::span_converter<span_gen_t, span_conv_alpha_t>;
- using nn_renderer_t = agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t>;
- lookup_distortion dist(
- params.transform_mesh, in_width, in_height, out_width, out_height);
- arbitrary_interpolator_t interpolator(inverted, dist);
- span_gen_t span_gen(input_accessor, interpolator);
- span_conv_t span_conv(span_gen, conv_alpha);
- nn_renderer_t nn_renderer(renderer, span_alloc, span_conv);
- agg::render_scanlines(rasterizer, scanline, nn_renderer);
- }
- } else {
- agg::image_filter_lut filter;
- get_filter(params, filter);
-
- if (params.is_affine && params.resample) {
- using span_gen_t = typename type_mapping_t::template span_gen_affine_type<image_accessor_t>;
- using span_conv_t = agg::span_converter<span_gen_t, span_conv_alpha_t>;
- using int_renderer_t = agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t>;
- affine_interpolator_t interpolator(inverted);
- span_gen_t span_gen(input_accessor, interpolator, filter);
- span_conv_t span_conv(span_gen, conv_alpha);
- int_renderer_t int_renderer(renderer, span_alloc, span_conv);
- agg::render_scanlines(rasterizer, scanline, int_renderer);
- } else {
- using span_gen_t = typename type_mapping_t::template span_gen_filter_type<image_accessor_t, arbitrary_interpolator_t>;
- using span_conv_t = agg::span_converter<span_gen_t, span_conv_alpha_t>;
- using int_renderer_t = agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t>;
- lookup_distortion dist(
- params.transform_mesh, in_width, in_height, out_width, out_height);
- arbitrary_interpolator_t interpolator(inverted, dist);
- span_gen_t span_gen(input_accessor, interpolator, filter);
- span_conv_t span_conv(span_gen, conv_alpha);
- int_renderer_t int_renderer(renderer, span_alloc, span_conv);
- agg::render_scanlines(rasterizer, scanline, int_renderer);
- }
- }
-}
-
-#endif /* MPL_RESAMPLE_H */
diff --git a/contrib/python/matplotlib/py3/src/_image_wrapper.cpp b/contrib/python/matplotlib/py3/src/_image_wrapper.cpp
deleted file mode 100644
index ca6ae8b222..0000000000
--- a/contrib/python/matplotlib/py3/src/_image_wrapper.cpp
+++ /dev/null
@@ -1,297 +0,0 @@
-#include "mplutils.h"
-#include "_image_resample.h"
-#include "numpy_cpp.h"
-#include "py_converters.h"
-
-
-/**********************************************************************
- * Free functions
- * */
-
-const char* image_resample__doc__ =
-"resample(input_array, output_array, transform, interpolation=NEAREST, resample=False, alpha=1.0, norm=False, radius=1.0)\n"
-"--\n\n"
-
-"Resample input_array, blending it in-place into output_array, using an\n"
-"affine transformation.\n\n"
-
-"Parameters\n"
-"----------\n"
-"input_array : 2-d or 3-d NumPy array of float, double or `numpy.uint8`\n"
-" If 2-d, the image is grayscale. If 3-d, the image must be of size\n"
-" 4 in the last dimension and represents RGBA data.\n\n"
-
-"output_array : 2-d or 3-d NumPy array of float, double or `numpy.uint8`\n"
-" The dtype and number of dimensions must match `input_array`.\n\n"
-
-"transform : matplotlib.transforms.Transform instance\n"
-" The transformation from the input array to the output array.\n\n"
-
-"interpolation : int, default: NEAREST\n"
-" The interpolation method. Must be one of the following constants\n"
-" defined in this module:\n\n"
-
-" NEAREST, BILINEAR, BICUBIC, SPLINE16, SPLINE36,\n"
-" HANNING, HAMMING, HERMITE, KAISER, QUADRIC, CATROM, GAUSSIAN,\n"
-" BESSEL, MITCHELL, SINC, LANCZOS, BLACKMAN\n\n"
-
-"resample : bool, optional\n"
-" When `True`, use a full resampling method. When `False`, only\n"
-" resample when the output image is larger than the input image.\n\n"
-
-"alpha : float, default: 1\n"
-" The transparency level, from 0 (transparent) to 1 (opaque).\n\n"
-
-"norm : bool, default: False\n"
-" Whether to norm the interpolation function.\n\n"
-
-"radius: float, default: 1\n"
-" The radius of the kernel, if method is SINC, LANCZOS or BLACKMAN.\n";
-
-
-static PyArrayObject *
-_get_transform_mesh(PyObject *py_affine, npy_intp *dims)
-{
- /* TODO: Could we get away with float, rather than double, arrays here? */
-
- /* Given a non-affine transform object, create a mesh that maps
- every pixel in the output image to the input image. This is used
- as a lookup table during the actual resampling. */
-
- PyObject *py_inverse = NULL;
- npy_intp out_dims[3];
-
- out_dims[0] = dims[0] * dims[1];
- out_dims[1] = 2;
-
- py_inverse = PyObject_CallMethod(py_affine, "inverted", NULL);
- if (py_inverse == NULL) {
- return NULL;
- }
-
- numpy::array_view<double, 2> input_mesh(out_dims);
- double *p = (double *)input_mesh.data();
-
- for (npy_intp y = 0; y < dims[0]; ++y) {
- for (npy_intp x = 0; x < dims[1]; ++x) {
- *p++ = (double)x;
- *p++ = (double)y;
- }
- }
-
- PyObject *output_mesh = PyObject_CallMethod(
- py_inverse, "transform", "O", input_mesh.pyobj_steal());
-
- Py_DECREF(py_inverse);
-
- if (output_mesh == NULL) {
- return NULL;
- }
-
- PyArrayObject *output_mesh_array =
- (PyArrayObject *)PyArray_ContiguousFromAny(
- output_mesh, NPY_DOUBLE, 2, 2);
-
- Py_DECREF(output_mesh);
-
- if (output_mesh_array == NULL) {
- return NULL;
- }
-
- return output_mesh_array;
-}
-
-
-static PyObject *
-image_resample(PyObject *self, PyObject* args, PyObject *kwargs)
-{
- PyObject *py_input = NULL;
- PyObject *py_output = NULL;
- PyObject *py_transform = NULL;
- resample_params_t params;
-
- PyArrayObject *input = NULL;
- PyArrayObject *output = NULL;
- PyArrayObject *transform_mesh = NULL;
- int ndim;
- int type;
-
- params.interpolation = NEAREST;
- params.transform_mesh = NULL;
- params.resample = false;
- params.norm = false;
- params.radius = 1.0;
- params.alpha = 1.0;
-
- const char *kwlist[] = {
- "input_array", "output_array", "transform", "interpolation",
- "resample", "alpha", "norm", "radius", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kwargs, "OOO|iO&dO&d:resample", (char **)kwlist,
- &py_input, &py_output, &py_transform,
- &params.interpolation, &convert_bool, &params.resample,
- &params.alpha, &convert_bool, &params.norm, &params.radius)) {
- return NULL;
- }
-
- if (params.interpolation < 0 || params.interpolation >= _n_interpolation) {
- PyErr_Format(PyExc_ValueError, "Invalid interpolation value %d",
- params.interpolation);
- goto error;
- }
-
- input = (PyArrayObject *)PyArray_FromAny(
- py_input, NULL, 2, 3, NPY_ARRAY_C_CONTIGUOUS, NULL);
- if (!input) {
- goto error;
- }
- ndim = PyArray_NDIM(input);
- type = PyArray_TYPE(input);
-
- if (!PyArray_Check(py_output)) {
- PyErr_SetString(PyExc_ValueError, "Output array must be a NumPy array");
- goto error;
- }
- output = (PyArrayObject *)py_output;
- if (PyArray_NDIM(output) != ndim) {
- PyErr_Format(
- PyExc_ValueError,
- "Input (%dD) and output (%dD) have different dimensionalities.",
- ndim, PyArray_NDIM(output));
- goto error;
- }
- // PyArray_FromAny above checks that input is 2D or 3D.
- if (ndim == 3 && (PyArray_DIM(input, 2) != 4 || PyArray_DIM(output, 2) != 4)) {
- PyErr_Format(
- PyExc_ValueError,
- "If 3D, input and output arrays must be RGBA with shape (M, N, 4); "
- "got trailing dimensions of %" NPY_INTP_FMT " and %" NPY_INTP_FMT
- " respectively", PyArray_DIM(input, 2), PyArray_DIM(output, 2));
- goto error;
- }
- if (PyArray_TYPE(output) != type) {
- PyErr_SetString(PyExc_ValueError, "Mismatched types");
- goto error;
- }
- if (!PyArray_IS_C_CONTIGUOUS(output)) {
- PyErr_SetString(PyExc_ValueError, "Output array must be C-contiguous");
- goto error;
- }
-
- if (py_transform == NULL || py_transform == Py_None) {
- params.is_affine = true;
- } else {
- PyObject *py_is_affine;
- int py_is_affine2;
- py_is_affine = PyObject_GetAttrString(py_transform, "is_affine");
- if (!py_is_affine) {
- goto error;
- }
-
- py_is_affine2 = PyObject_IsTrue(py_is_affine);
- Py_DECREF(py_is_affine);
-
- if (py_is_affine2 == -1) {
- goto error;
- } else if (py_is_affine2) {
- if (!convert_trans_affine(py_transform, &params.affine)) {
- goto error;
- }
- params.is_affine = true;
- } else {
- transform_mesh = _get_transform_mesh(
- py_transform, PyArray_DIMS(output));
- if (!transform_mesh) {
- goto error;
- }
- params.transform_mesh = (double *)PyArray_DATA(transform_mesh);
- params.is_affine = false;
- }
- }
-
- if (auto resampler =
- (ndim == 2) ? (
- (type == NPY_UINT8) ? resample<agg::gray8> :
- (type == NPY_INT8) ? resample<agg::gray8> :
- (type == NPY_UINT16) ? resample<agg::gray16> :
- (type == NPY_INT16) ? resample<agg::gray16> :
- (type == NPY_FLOAT32) ? resample<agg::gray32> :
- (type == NPY_FLOAT64) ? resample<agg::gray64> :
- nullptr) : (
- // ndim == 3
- (type == NPY_UINT8) ? resample<agg::rgba8> :
- (type == NPY_INT8) ? resample<agg::rgba8> :
- (type == NPY_UINT16) ? resample<agg::rgba16> :
- (type == NPY_INT16) ? resample<agg::rgba16> :
- (type == NPY_FLOAT32) ? resample<agg::rgba32> :
- (type == NPY_FLOAT64) ? resample<agg::rgba64> :
- nullptr)) {
- Py_BEGIN_ALLOW_THREADS
- resampler(
- PyArray_DATA(input), PyArray_DIM(input, 1), PyArray_DIM(input, 0),
- PyArray_DATA(output), PyArray_DIM(output, 1), PyArray_DIM(output, 0),
- params);
- Py_END_ALLOW_THREADS
- } else {
- PyErr_SetString(
- PyExc_ValueError,
- "arrays must be of dtype byte, short, float32 or float64");
- goto error;
- }
-
- Py_DECREF(input);
- Py_XDECREF(transform_mesh);
- Py_RETURN_NONE;
-
- error:
- Py_XDECREF(input);
- Py_XDECREF(transform_mesh);
- return NULL;
-}
-
-static PyMethodDef module_functions[] = {
- {"resample", (PyCFunction)image_resample, METH_VARARGS|METH_KEYWORDS, image_resample__doc__},
- {NULL}
-};
-
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT, "_image", NULL, 0, module_functions,
-};
-
-PyMODINIT_FUNC PyInit__image(void)
-{
- PyObject *m;
-
- import_array();
-
- m = PyModule_Create(&moduledef);
-
- if (m == NULL) {
- return NULL;
- }
-
- if (PyModule_AddIntConstant(m, "NEAREST", NEAREST) ||
- PyModule_AddIntConstant(m, "BILINEAR", BILINEAR) ||
- PyModule_AddIntConstant(m, "BICUBIC", BICUBIC) ||
- PyModule_AddIntConstant(m, "SPLINE16", SPLINE16) ||
- PyModule_AddIntConstant(m, "SPLINE36", SPLINE36) ||
- PyModule_AddIntConstant(m, "HANNING", HANNING) ||
- PyModule_AddIntConstant(m, "HAMMING", HAMMING) ||
- PyModule_AddIntConstant(m, "HERMITE", HERMITE) ||
- PyModule_AddIntConstant(m, "KAISER", KAISER) ||
- PyModule_AddIntConstant(m, "QUADRIC", QUADRIC) ||
- PyModule_AddIntConstant(m, "CATROM", CATROM) ||
- PyModule_AddIntConstant(m, "GAUSSIAN", GAUSSIAN) ||
- PyModule_AddIntConstant(m, "BESSEL", BESSEL) ||
- PyModule_AddIntConstant(m, "MITCHELL", MITCHELL) ||
- PyModule_AddIntConstant(m, "SINC", SINC) ||
- PyModule_AddIntConstant(m, "LANCZOS", LANCZOS) ||
- PyModule_AddIntConstant(m, "BLACKMAN", BLACKMAN) ||
- PyModule_AddIntConstant(m, "_n_interpolation", _n_interpolation)) {
- Py_DECREF(m);
- return NULL;
- }
-
- return m;
-}
diff --git a/contrib/python/matplotlib/py3/src/_path.h b/contrib/python/matplotlib/py3/src/_path.h
deleted file mode 100644
index 61c4ed07d0..0000000000
--- a/contrib/python/matplotlib/py3/src/_path.h
+++ /dev/null
@@ -1,1251 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef MPL_PATH_H
-#define MPL_PATH_H
-
-#include <limits>
-#include <math.h>
-#include <vector>
-#include <cmath>
-#include <algorithm>
-#include <string>
-
-#include "agg_conv_contour.h"
-#include "agg_conv_curve.h"
-#include "agg_conv_stroke.h"
-#include "agg_conv_transform.h"
-#include "agg_path_storage.h"
-#include "agg_trans_affine.h"
-
-#include "path_converters.h"
-#include "_backend_agg_basic_types.h"
-#include "numpy_cpp.h"
-
-struct XY
-{
- double x;
- double y;
-
- XY(double x_, double y_) : x(x_), y(y_)
- {
- }
-
- bool operator==(const XY& o)
- {
- return (x == o.x && y == o.y);
- }
-
- bool operator!=(const XY& o)
- {
- return (x != o.x || y != o.y);
- }
-};
-
-typedef std::vector<XY> Polygon;
-
-void _finalize_polygon(std::vector<Polygon> &result, int closed_only)
-{
- if (result.size() == 0) {
- return;
- }
-
- Polygon &polygon = result.back();
-
- /* Clean up the last polygon in the result. */
- if (polygon.size() == 0) {
- result.pop_back();
- } else if (closed_only) {
- if (polygon.size() < 3) {
- result.pop_back();
- } else if (polygon.front() != polygon.back()) {
- polygon.push_back(polygon.front());
- }
- }
-}
-
-//
-// The following function was found in the Agg 2.3 examples (interactive_polygon.cpp).
-// It has been generalized to work on (possibly curved) polylines, rather than
-// just polygons. The original comments have been kept intact.
-// -- Michael Droettboom 2007-10-02
-//
-//======= 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.
-template <class PathIterator, class PointArray, class ResultArray>
-void point_in_path_impl(PointArray &points, PathIterator &path, ResultArray &inside_flag)
-{
- uint8_t yflag1;
- double vtx0, vty0, vtx1, vty1;
- double tx, ty;
- double sx, sy;
- double x, y;
- size_t i;
- bool all_done;
-
- size_t n = points.size();
-
- std::vector<uint8_t> yflag0(n);
- std::vector<uint8_t> subpath_flag(n);
-
- path.rewind(0);
-
- for (i = 0; i < n; ++i) {
- inside_flag[i] = 0;
- }
-
- unsigned code = 0;
- do {
- if (code != agg::path_cmd_move_to) {
- code = path.vertex(&x, &y);
- if (code == agg::path_cmd_stop ||
- (code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) {
- continue;
- }
- }
-
- sx = vtx0 = vtx1 = x;
- sy = vty0 = vty1 = y;
-
- for (i = 0; i < n; ++i) {
- ty = points(i, 1);
-
- if (std::isfinite(ty)) {
- // get test bit for above/below X axis
- yflag0[i] = (vty0 >= ty);
-
- subpath_flag[i] = 0;
- }
- }
-
- do {
- code = path.vertex(&x, &y);
-
- // The following cases denote the beginning on a new subpath
- if (code == agg::path_cmd_stop ||
- (code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) {
- x = sx;
- y = sy;
- } else if (code == agg::path_cmd_move_to) {
- break;
- }
-
- for (i = 0; i < n; ++i) {
- tx = points(i, 0);
- ty = points(i, 1);
-
- if (!(std::isfinite(tx) && std::isfinite(ty))) {
- continue;
- }
-
- 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[i] != 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) {
- subpath_flag[i] ^= 1;
- }
- }
-
- // Move to the next pair of vertices, retaining info as
- // possible.
- yflag0[i] = yflag1;
- }
-
- vtx0 = vtx1;
- vty0 = vty1;
-
- vtx1 = x;
- vty1 = y;
- } while (code != agg::path_cmd_stop &&
- (code & agg::path_cmd_end_poly) != agg::path_cmd_end_poly);
-
- all_done = true;
- for (i = 0; i < n; ++i) {
- tx = points(i, 0);
- ty = points(i, 1);
-
- if (!(std::isfinite(tx) && std::isfinite(ty))) {
- continue;
- }
-
- yflag1 = (vty1 >= ty);
- if (yflag0[i] != yflag1) {
- if (((vty1 - ty) * (vtx0 - vtx1) >= (vtx1 - tx) * (vty0 - vty1)) == yflag1) {
- subpath_flag[i] = subpath_flag[i] ^ true;
- }
- }
- inside_flag[i] |= subpath_flag[i];
- if (inside_flag[i] == 0) {
- all_done = false;
- }
- }
-
- if (all_done) {
- break;
- }
- } while (code != agg::path_cmd_stop);
-}
-
-template <class PathIterator, class PointArray, class ResultArray>
-inline void points_in_path(PointArray &points,
- const double r,
- PathIterator &path,
- agg::trans_affine &trans,
- ResultArray &result)
-{
- typedef agg::conv_transform<PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> no_nans_t;
- typedef agg::conv_curve<no_nans_t> curve_t;
- typedef agg::conv_contour<curve_t> contour_t;
-
- size_t i;
- for (i = 0; i < points.size(); ++i) {
- result[i] = false;
- }
-
- if (path.total_vertices() < 3) {
- return;
- }
-
- transformed_path_t trans_path(path, trans);
- no_nans_t no_nans_path(trans_path, true, path.has_codes());
- curve_t curved_path(no_nans_path);
- if (r != 0.0) {
- contour_t contoured_path(curved_path);
- contoured_path.width(r);
- point_in_path_impl(points, contoured_path, result);
- } else {
- point_in_path_impl(points, curved_path, result);
- }
-}
-
-template <class PathIterator>
-inline bool point_in_path(
- double x, double y, const double r, PathIterator &path, agg::trans_affine &trans)
-{
- npy_intp shape[] = {1, 2};
- numpy::array_view<double, 2> points(shape);
- points(0, 0) = x;
- points(0, 1) = y;
-
- int result[1];
- result[0] = 0;
-
- points_in_path(points, r, path, trans, result);
-
- return result[0] != 0;
-}
-
-template <class PathIterator>
-inline bool point_on_path(
- double x, double y, const double r, PathIterator &path, agg::trans_affine &trans)
-{
- typedef agg::conv_transform<PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> no_nans_t;
- typedef agg::conv_curve<no_nans_t> curve_t;
- typedef agg::conv_stroke<curve_t> stroke_t;
-
- npy_intp shape[] = {1, 2};
- numpy::array_view<double, 2> points(shape);
- points(0, 0) = x;
- points(0, 1) = y;
-
- int result[1];
- result[0] = 0;
-
- transformed_path_t trans_path(path, trans);
- no_nans_t nan_removed_path(trans_path, true, path.has_codes());
- curve_t curved_path(nan_removed_path);
- stroke_t stroked_path(curved_path);
- stroked_path.width(r * 2.0);
- point_in_path_impl(points, stroked_path, result);
- return result[0] != 0;
-}
-
-struct extent_limits
-{
- double x0;
- double y0;
- double x1;
- double y1;
- double xm;
- double ym;
-};
-
-void reset_limits(extent_limits &e)
-{
- e.x0 = std::numeric_limits<double>::infinity();
- e.y0 = std::numeric_limits<double>::infinity();
- e.x1 = -std::numeric_limits<double>::infinity();
- e.y1 = -std::numeric_limits<double>::infinity();
- /* xm and ym are the minimum positive values in the data, used
- by log scaling */
- e.xm = std::numeric_limits<double>::infinity();
- e.ym = std::numeric_limits<double>::infinity();
-}
-
-inline void update_limits(double x, double y, extent_limits &e)
-{
- if (x < e.x0)
- e.x0 = x;
- if (y < e.y0)
- e.y0 = y;
- if (x > e.x1)
- e.x1 = x;
- if (y > e.y1)
- e.y1 = y;
- /* xm and ym are the minimum positive values in the data, used
- by log scaling */
- if (x > 0.0 && x < e.xm)
- e.xm = x;
- if (y > 0.0 && y < e.ym)
- e.ym = y;
-}
-
-template <class PathIterator>
-void update_path_extents(PathIterator &path, agg::trans_affine &trans, extent_limits &extents)
-{
- typedef agg::conv_transform<PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removed_t;
- double x, y;
- unsigned code;
-
- transformed_path_t tpath(path, trans);
- nan_removed_t nan_removed(tpath, true, path.has_codes());
-
- nan_removed.rewind(0);
-
- while ((code = nan_removed.vertex(&x, &y)) != agg::path_cmd_stop) {
- if ((code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) {
- continue;
- }
- update_limits(x, y, extents);
- }
-}
-
-template <class PathGenerator, class TransformArray, class OffsetArray>
-void get_path_collection_extents(agg::trans_affine &master_transform,
- PathGenerator &paths,
- TransformArray &transforms,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- extent_limits &extent)
-{
- if (offsets.size() != 0 && offsets.dim(1) != 2) {
- throw std::runtime_error("Offsets array must have shape (N, 2)");
- }
-
- size_t Npaths = paths.size();
- size_t Noffsets = offsets.size();
- size_t N = std::max(Npaths, Noffsets);
- size_t Ntransforms = std::min(transforms.size(), N);
- size_t i;
-
- agg::trans_affine trans;
-
- reset_limits(extent);
-
- for (i = 0; i < N; ++i) {
- typename PathGenerator::path_iterator path(paths(i % Npaths));
- if (Ntransforms) {
- size_t ti = i % Ntransforms;
- trans = agg::trans_affine(transforms(ti, 0, 0),
- transforms(ti, 1, 0),
- transforms(ti, 0, 1),
- transforms(ti, 1, 1),
- transforms(ti, 0, 2),
- transforms(ti, 1, 2));
- } else {
- trans = master_transform;
- }
-
- if (Noffsets) {
- double xo = offsets(i % Noffsets, 0);
- double yo = offsets(i % Noffsets, 1);
- offset_trans.transform(&xo, &yo);
- trans *= agg::trans_affine_translation(xo, yo);
- }
-
- update_path_extents(path, trans, extent);
- }
-}
-
-template <class PathGenerator, class TransformArray, class OffsetArray>
-void point_in_path_collection(double x,
- double y,
- double radius,
- agg::trans_affine &master_transform,
- PathGenerator &paths,
- TransformArray &transforms,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- bool filled,
- std::vector<int> &result)
-{
- size_t Npaths = paths.size();
-
- if (Npaths == 0) {
- return;
- }
-
- size_t Noffsets = offsets.size();
- size_t N = std::max(Npaths, Noffsets);
- size_t Ntransforms = std::min(transforms.size(), N);
- size_t i;
-
- agg::trans_affine trans;
-
- for (i = 0; i < N; ++i) {
- typename PathGenerator::path_iterator path = paths(i % Npaths);
-
- if (Ntransforms) {
- size_t ti = i % Ntransforms;
- trans = agg::trans_affine(transforms(ti, 0, 0),
- transforms(ti, 1, 0),
- transforms(ti, 0, 1),
- transforms(ti, 1, 1),
- transforms(ti, 0, 2),
- transforms(ti, 1, 2));
- trans *= master_transform;
- } else {
- trans = master_transform;
- }
-
- if (Noffsets) {
- double xo = offsets(i % Noffsets, 0);
- double yo = offsets(i % Noffsets, 1);
- offset_trans.transform(&xo, &yo);
- trans *= agg::trans_affine_translation(xo, yo);
- }
-
- if (filled) {
- if (point_in_path(x, y, radius, path, trans)) {
- result.push_back(i);
- }
- } else {
- if (point_on_path(x, y, radius, path, trans)) {
- result.push_back(i);
- }
- }
- }
-}
-
-template <class PathIterator1, class PathIterator2>
-bool path_in_path(PathIterator1 &a,
- agg::trans_affine &atrans,
- PathIterator2 &b,
- agg::trans_affine &btrans)
-{
- typedef agg::conv_transform<PathIterator2> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> no_nans_t;
- typedef agg::conv_curve<no_nans_t> curve_t;
-
- if (a.total_vertices() < 3) {
- return false;
- }
-
- transformed_path_t b_path_trans(b, btrans);
- no_nans_t b_no_nans(b_path_trans, true, b.has_codes());
- curve_t b_curved(b_no_nans);
-
- double x, y;
- b_curved.rewind(0);
- while (b_curved.vertex(&x, &y) != agg::path_cmd_stop) {
- if (!point_in_path(x, y, 0.0, a, atrans)) {
- return false;
- }
- }
-
- return true;
-}
-
-/** The clip_path_to_rect code here is a clean-room implementation of
- the Sutherland-Hodgman clipping algorithm described here:
-
- https://en.wikipedia.org/wiki/Sutherland-Hodgman_clipping_algorithm
-*/
-
-namespace clip_to_rect_filters
-{
-/* There are four different passes needed to create/remove
- vertices (one for each side of the rectangle). The differences
- between those passes are encapsulated in these functor classes.
-*/
-struct bisectx
-{
- double m_x;
-
- bisectx(double x) : m_x(x)
- {
- }
-
- inline void bisect(double sx, double sy, double px, double py, double *bx, double *by) const
- {
- *bx = m_x;
- double dx = px - sx;
- double dy = py - sy;
- *by = sy + dy * ((m_x - sx) / dx);
- }
-};
-
-struct xlt : public bisectx
-{
- xlt(double x) : bisectx(x)
- {
- }
-
- inline bool is_inside(double x, double y) const
- {
- return x <= m_x;
- }
-};
-
-struct xgt : public bisectx
-{
- xgt(double x) : bisectx(x)
- {
- }
-
- inline bool is_inside(double x, double y) const
- {
- return x >= m_x;
- }
-};
-
-struct bisecty
-{
- double m_y;
-
- bisecty(double y) : m_y(y)
- {
- }
-
- inline void bisect(double sx, double sy, double px, double py, double *bx, double *by) const
- {
- *by = m_y;
- double dx = px - sx;
- double dy = py - sy;
- *bx = sx + dx * ((m_y - sy) / dy);
- }
-};
-
-struct ylt : public bisecty
-{
- ylt(double y) : bisecty(y)
- {
- }
-
- inline bool is_inside(double x, double y) const
- {
- return y <= m_y;
- }
-};
-
-struct ygt : public bisecty
-{
- ygt(double y) : bisecty(y)
- {
- }
-
- inline bool is_inside(double x, double y) const
- {
- return y >= m_y;
- }
-};
-}
-
-template <class Filter>
-inline void clip_to_rect_one_step(const Polygon &polygon, Polygon &result, const Filter &filter)
-{
- double sx, sy, px, py, bx, by;
- bool sinside, pinside;
- result.clear();
-
- if (polygon.size() == 0) {
- return;
- }
-
- sx = polygon.back().x;
- sy = polygon.back().y;
- for (Polygon::const_iterator i = polygon.begin(); i != polygon.end(); ++i) {
- px = i->x;
- py = i->y;
-
- sinside = filter.is_inside(sx, sy);
- pinside = filter.is_inside(px, py);
-
- if (sinside ^ pinside) {
- filter.bisect(sx, sy, px, py, &bx, &by);
- result.push_back(XY(bx, by));
- }
-
- if (pinside) {
- result.push_back(XY(px, py));
- }
-
- sx = px;
- sy = py;
- }
-}
-
-template <class PathIterator>
-void
-clip_path_to_rect(PathIterator &path, agg::rect_d &rect, bool inside, std::vector<Polygon> &results)
-{
- double xmin, ymin, xmax, ymax;
- if (rect.x1 < rect.x2) {
- xmin = rect.x1;
- xmax = rect.x2;
- } else {
- xmin = rect.x2;
- xmax = rect.x1;
- }
-
- if (rect.y1 < rect.y2) {
- ymin = rect.y1;
- ymax = rect.y2;
- } else {
- ymin = rect.y2;
- ymax = rect.y1;
- }
-
- if (!inside) {
- std::swap(xmin, xmax);
- std::swap(ymin, ymax);
- }
-
- typedef agg::conv_curve<PathIterator> curve_t;
- curve_t curve(path);
-
- Polygon polygon1, polygon2;
- double x = 0, y = 0;
- unsigned code = 0;
- curve.rewind(0);
-
- do {
- // Grab the next subpath and store it in polygon1
- polygon1.clear();
- do {
- if (code == agg::path_cmd_move_to) {
- polygon1.push_back(XY(x, y));
- }
-
- code = curve.vertex(&x, &y);
-
- if (code == agg::path_cmd_stop) {
- break;
- }
-
- if (code != agg::path_cmd_move_to) {
- polygon1.push_back(XY(x, y));
- }
- } while ((code & agg::path_cmd_end_poly) != agg::path_cmd_end_poly);
-
- // The result of each step is fed into the next (note the
- // swapping of polygon1 and polygon2 at each step).
- clip_to_rect_one_step(polygon1, polygon2, clip_to_rect_filters::xlt(xmax));
- clip_to_rect_one_step(polygon2, polygon1, clip_to_rect_filters::xgt(xmin));
- clip_to_rect_one_step(polygon1, polygon2, clip_to_rect_filters::ylt(ymax));
- clip_to_rect_one_step(polygon2, polygon1, clip_to_rect_filters::ygt(ymin));
-
- // Empty polygons aren't very useful, so skip them
- if (polygon1.size()) {
- _finalize_polygon(results, 1);
- results.push_back(polygon1);
- }
- } while (code != agg::path_cmd_stop);
-
- _finalize_polygon(results, 1);
-}
-
-template <class VerticesArray, class ResultArray>
-void affine_transform_2d(VerticesArray &vertices, agg::trans_affine &trans, ResultArray &result)
-{
- if (vertices.size() != 0 && vertices.dim(1) != 2) {
- throw std::runtime_error("Invalid vertices array.");
- }
-
- size_t n = vertices.size();
- double x;
- double y;
- double t0;
- double t1;
- double t;
-
- for (size_t i = 0; i < n; ++i) {
- x = vertices(i, 0);
- y = vertices(i, 1);
-
- t0 = trans.sx * x;
- t1 = trans.shx * y;
- t = t0 + t1 + trans.tx;
- result(i, 0) = t;
-
- t0 = trans.shy * x;
- t1 = trans.sy * y;
- t = t0 + t1 + trans.ty;
- result(i, 1) = t;
- }
-}
-
-template <class VerticesArray, class ResultArray>
-void affine_transform_1d(VerticesArray &vertices, agg::trans_affine &trans, ResultArray &result)
-{
- if (vertices.dim(0) != 2) {
- throw std::runtime_error("Invalid vertices array.");
- }
-
- double x;
- double y;
- double t0;
- double t1;
- double t;
-
- x = vertices(0);
- y = vertices(1);
-
- t0 = trans.sx * x;
- t1 = trans.shx * y;
- t = t0 + t1 + trans.tx;
- result(0) = t;
-
- t0 = trans.shy * x;
- t1 = trans.sy * y;
- t = t0 + t1 + trans.ty;
- result(1) = t;
-}
-
-template <class BBoxArray>
-int count_bboxes_overlapping_bbox(agg::rect_d &a, BBoxArray &bboxes)
-{
- agg::rect_d b;
- int count = 0;
-
- if (a.x2 < a.x1) {
- std::swap(a.x1, a.x2);
- }
- if (a.y2 < a.y1) {
- std::swap(a.y1, a.y2);
- }
-
- size_t num_bboxes = bboxes.size();
- for (size_t i = 0; i < num_bboxes; ++i) {
- b = agg::rect_d(bboxes(i, 0, 0), bboxes(i, 0, 1), bboxes(i, 1, 0), bboxes(i, 1, 1));
-
- if (b.x2 < b.x1) {
- std::swap(b.x1, b.x2);
- }
- if (b.y2 < b.y1) {
- std::swap(b.y1, b.y2);
- }
- if (!((b.x2 <= a.x1) || (b.y2 <= a.y1) || (b.x1 >= a.x2) || (b.y1 >= a.y2))) {
- ++count;
- }
- }
-
- return count;
-}
-
-
-inline bool isclose(double a, double b)
-{
- // relative and absolute tolerance values are chosen empirically
- // it looks the atol value matters here because of round-off errors
- const double rtol = 1e-10;
- const double atol = 1e-13;
-
- // as per python's math.isclose
- return fabs(a-b) <= fmax(rtol * fmax(fabs(a), fabs(b)), atol);
-}
-
-
-inline bool segments_intersect(const double &x1,
- const double &y1,
- const double &x2,
- const double &y2,
- const double &x3,
- const double &y3,
- const double &x4,
- const double &y4)
-{
- // determinant
- double den = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1));
-
- // If den == 0 we have two possibilities:
- if (isclose(den, 0.0)) {
- double t_area = (x2*y3 - x3*y2) - x1*(y3 - y2) + y1*(x3 - x2);
- // 1 - If the area of the triangle made by the 3 first points (2 from the first segment
- // plus one from the second) is zero, they are collinear
- if (isclose(t_area, 0.0)) {
- if (x1 == x2 && x2 == x3) { // segments have infinite slope (vertical lines)
- // and lie on the same line
- return (fmin(y1, y2) <= fmin(y3, y4) && fmin(y3, y4) <= fmax(y1, y2)) ||
- (fmin(y3, y4) <= fmin(y1, y2) && fmin(y1, y2) <= fmax(y3, y4));
- }
- else {
- return (fmin(x1, x2) <= fmin(x3, x4) && fmin(x3, x4) <= fmax(x1, x2)) ||
- (fmin(x3, x4) <= fmin(x1, x2) && fmin(x1, x2) <= fmax(x3, x4));
- }
- }
- // 2 - If t_area is not zero, the segments are parallel, but not collinear
- else {
- return false;
- }
- }
-
- const double n1 = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));
- const double n2 = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3));
-
- const double u1 = n1 / den;
- const double u2 = n2 / den;
-
- return ((u1 > 0.0 || isclose(u1, 0.0)) &&
- (u1 < 1.0 || isclose(u1, 1.0)) &&
- (u2 > 0.0 || isclose(u2, 0.0)) &&
- (u2 < 1.0 || isclose(u2, 1.0)));
-}
-
-template <class PathIterator1, class PathIterator2>
-bool path_intersects_path(PathIterator1 &p1, PathIterator2 &p2)
-{
- typedef PathNanRemover<py::PathIterator> no_nans_t;
- typedef agg::conv_curve<no_nans_t> curve_t;
-
- if (p1.total_vertices() < 2 || p2.total_vertices() < 2) {
- return false;
- }
-
- no_nans_t n1(p1, true, p1.has_codes());
- no_nans_t n2(p2, true, p2.has_codes());
-
- curve_t c1(n1);
- curve_t c2(n2);
-
- double x11, y11, x12, y12;
- double x21, y21, x22, y22;
-
- c1.vertex(&x11, &y11);
- while (c1.vertex(&x12, &y12) != agg::path_cmd_stop) {
- // if the segment in path 1 is (almost) 0 length, skip to next vertex
- if ((isclose((x11 - x12) * (x11 - x12) + (y11 - y12) * (y11 - y12), 0))){
- continue;
- }
- c2.rewind(0);
- c2.vertex(&x21, &y21);
-
- while (c2.vertex(&x22, &y22) != agg::path_cmd_stop) {
- // if the segment in path 2 is (almost) 0 length, skip to next vertex
- if ((isclose((x21 - x22) * (x21 - x22) + (y21 - y22) * (y21 - y22), 0))){
- continue;
- }
-
- if (segments_intersect(x11, y11, x12, y12, x21, y21, x22, y22)) {
- return true;
- }
- x21 = x22;
- y21 = y22;
- }
- x11 = x12;
- y11 = y12;
- }
-
- return false;
-}
-
-// returns whether the segment from (x1,y1) to (x2,y2)
-// intersects the rectangle centered at (cx,cy) with size (w,h)
-// see doc/segment_intersects_rectangle.svg for a more detailed explanation
-inline bool segment_intersects_rectangle(double x1, double y1,
- double x2, double y2,
- double cx, double cy,
- double w, double h)
-{
- return fabs(x1 + x2 - 2.0 * cx) < fabs(x1 - x2) + w &&
- fabs(y1 + y2 - 2.0 * cy) < fabs(y1 - y2) + h &&
- 2.0 * fabs((x1 - cx) * (y1 - y2) - (y1 - cy) * (x1 - x2)) <
- w * fabs(y1 - y2) + h * fabs(x1 - x2);
-}
-
-template <class PathIterator>
-bool path_intersects_rectangle(PathIterator &path,
- double rect_x1, double rect_y1,
- double rect_x2, double rect_y2,
- bool filled)
-{
- typedef PathNanRemover<py::PathIterator> no_nans_t;
- typedef agg::conv_curve<no_nans_t> curve_t;
-
- if (path.total_vertices() == 0) {
- return false;
- }
-
- no_nans_t no_nans(path, true, path.has_codes());
- curve_t curve(no_nans);
-
- double cx = (rect_x1 + rect_x2) * 0.5, cy = (rect_y1 + rect_y2) * 0.5;
- double w = fabs(rect_x1 - rect_x2), h = fabs(rect_y1 - rect_y2);
-
- double x1, y1, x2, y2;
-
- curve.vertex(&x1, &y1);
- if (2.0 * fabs(x1 - cx) <= w && 2.0 * fabs(y1 - cy) <= h) {
- return true;
- }
-
- while (curve.vertex(&x2, &y2) != agg::path_cmd_stop) {
- if (segment_intersects_rectangle(x1, y1, x2, y2, cx, cy, w, h)) {
- return true;
- }
- x1 = x2;
- y1 = y2;
- }
-
- if (filled) {
- agg::trans_affine trans;
- if (point_in_path(cx, cy, 0.0, path, trans)) {
- return true;
- }
- }
-
- return false;
-}
-
-template <class PathIterator>
-void convert_path_to_polygons(PathIterator &path,
- agg::trans_affine &trans,
- double width,
- double height,
- int closed_only,
- std::vector<Polygon> &result)
-{
- typedef agg::conv_transform<py::PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removal_t;
- typedef PathClipper<nan_removal_t> clipped_t;
- typedef PathSimplifier<clipped_t> simplify_t;
- typedef agg::conv_curve<simplify_t> curve_t;
-
- bool do_clip = width != 0.0 && height != 0.0;
- bool simplify = path.should_simplify();
-
- transformed_path_t tpath(path, trans);
- nan_removal_t nan_removed(tpath, true, path.has_codes());
- clipped_t clipped(nan_removed, do_clip, width, height);
- simplify_t simplified(clipped, simplify, path.simplify_threshold());
- curve_t curve(simplified);
-
- result.push_back(Polygon());
- Polygon *polygon = &result.back();
- double x, y;
- unsigned code;
-
- while ((code = curve.vertex(&x, &y)) != agg::path_cmd_stop) {
- if ((code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) {
- _finalize_polygon(result, 1);
- result.push_back(Polygon());
- polygon = &result.back();
- } else {
- if (code == agg::path_cmd_move_to) {
- _finalize_polygon(result, closed_only);
- result.push_back(Polygon());
- polygon = &result.back();
- }
- polygon->push_back(XY(x, y));
- }
- }
-
- _finalize_polygon(result, closed_only);
-}
-
-template <class VertexSource>
-void
-__cleanup_path(VertexSource &source, std::vector<double> &vertices, std::vector<npy_uint8> &codes)
-{
- unsigned code;
- double x, y;
- do {
- code = source.vertex(&x, &y);
- vertices.push_back(x);
- vertices.push_back(y);
- codes.push_back((npy_uint8)code);
- } while (code != agg::path_cmd_stop);
-}
-
-template <class PathIterator>
-void cleanup_path(PathIterator &path,
- agg::trans_affine &trans,
- bool remove_nans,
- bool do_clip,
- const agg::rect_base<double> &rect,
- e_snap_mode snap_mode,
- double stroke_width,
- bool do_simplify,
- bool return_curves,
- SketchParams sketch_params,
- std::vector<double> &vertices,
- std::vector<unsigned char> &codes)
-{
- typedef agg::conv_transform<py::PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removal_t;
- typedef PathClipper<nan_removal_t> clipped_t;
- typedef PathSnapper<clipped_t> snapped_t;
- typedef PathSimplifier<snapped_t> simplify_t;
- typedef agg::conv_curve<simplify_t> curve_t;
- typedef Sketch<curve_t> sketch_t;
-
- transformed_path_t tpath(path, trans);
- nan_removal_t nan_removed(tpath, remove_nans, path.has_codes());
- clipped_t clipped(nan_removed, do_clip, rect);
- snapped_t snapped(clipped, snap_mode, path.total_vertices(), stroke_width);
- simplify_t simplified(snapped, do_simplify, path.simplify_threshold());
-
- vertices.reserve(path.total_vertices() * 2);
- codes.reserve(path.total_vertices());
-
- if (return_curves && sketch_params.scale == 0.0) {
- __cleanup_path(simplified, vertices, codes);
- } else {
- curve_t curve(simplified);
- sketch_t sketch(curve, sketch_params.scale, sketch_params.length, sketch_params.randomness);
- __cleanup_path(sketch, vertices, codes);
- }
-}
-
-void quad2cubic(double x0, double y0,
- double x1, double y1,
- double x2, double y2,
- double *outx, double *outy)
-{
-
- outx[0] = x0 + 2./3. * (x1 - x0);
- outy[0] = y0 + 2./3. * (y1 - y0);
- outx[1] = outx[0] + 1./3. * (x2 - x0);
- outy[1] = outy[0] + 1./3. * (y2 - y0);
- outx[2] = x2;
- outy[2] = y2;
-}
-
-
-void __add_number(double val, char format_code, int precision,
- std::string& buffer)
-{
- if (precision == -1) {
- // Special-case for compat with old ttconv code, which *truncated*
- // values with a cast to int instead of rounding them as printf
- // would do. The only point where non-integer values arise is from
- // quad2cubic conversion (as we already perform a first truncation
- // on Python's side), which can introduce additional floating point
- // error (by adding 2/3 delta-x and then 1/3 delta-x), so compensate by
- // first rounding to the closest 1/3 and then truncating.
- char str[255];
- PyOS_snprintf(str, 255, "%d", (int)(round(val * 3)) / 3);
- buffer += str;
- } else {
- char *str = PyOS_double_to_string(
- val, format_code, precision, Py_DTSF_ADD_DOT_0, NULL);
- // Delete trailing zeros and decimal point
- char *c = str + strlen(str) - 1; // Start at last character.
- // Rewind through all the zeros and, if present, the trailing decimal
- // point. Py_DTSF_ADD_DOT_0 ensures we won't go past the start of str.
- while (*c == '0') {
- --c;
- }
- if (*c == '.') {
- --c;
- }
- try {
- buffer.append(str, c + 1);
- } catch (std::bad_alloc& e) {
- PyMem_Free(str);
- throw e;
- }
- PyMem_Free(str);
- }
-}
-
-
-template <class PathIterator>
-bool __convert_to_string(PathIterator &path,
- int precision,
- char **codes,
- bool postfix,
- std::string& buffer)
-{
- const char format_code = 'f';
-
- double x[3];
- double y[3];
- double last_x = 0.0;
- double last_y = 0.0;
-
- unsigned code;
-
- while ((code = path.vertex(&x[0], &y[0])) != agg::path_cmd_stop) {
- if (code == CLOSEPOLY) {
- buffer += codes[4];
- } else if (code < 5) {
- size_t size = NUM_VERTICES[code];
-
- for (size_t i = 1; i < size; ++i) {
- unsigned subcode = path.vertex(&x[i], &y[i]);
- if (subcode != code) {
- return false;
- }
- }
-
- /* For formats that don't support quad curves, convert to
- cubic curves */
- if (code == CURVE3 && codes[code - 1][0] == '\0') {
- quad2cubic(last_x, last_y, x[0], y[0], x[1], y[1], x, y);
- code++;
- size = 3;
- }
-
- if (!postfix) {
- buffer += codes[code - 1];
- buffer += ' ';
- }
-
- for (size_t i = 0; i < size; ++i) {
- __add_number(x[i], format_code, precision, buffer);
- buffer += ' ';
- __add_number(y[i], format_code, precision, buffer);
- buffer += ' ';
- }
-
- if (postfix) {
- buffer += codes[code - 1];
- }
-
- last_x = x[size - 1];
- last_y = y[size - 1];
- } else {
- // Unknown code value
- return false;
- }
-
- buffer += '\n';
- }
-
- return true;
-}
-
-template <class PathIterator>
-bool convert_to_string(PathIterator &path,
- agg::trans_affine &trans,
- agg::rect_d &clip_rect,
- bool simplify,
- SketchParams sketch_params,
- int precision,
- char **codes,
- bool postfix,
- std::string& buffer)
-{
- size_t buffersize;
- typedef agg::conv_transform<py::PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removal_t;
- typedef PathClipper<nan_removal_t> clipped_t;
- typedef PathSimplifier<clipped_t> simplify_t;
- typedef agg::conv_curve<simplify_t> curve_t;
- typedef Sketch<curve_t> sketch_t;
-
- bool do_clip = (clip_rect.x1 < clip_rect.x2 && clip_rect.y1 < clip_rect.y2);
-
- transformed_path_t tpath(path, trans);
- nan_removal_t nan_removed(tpath, true, path.has_codes());
- clipped_t clipped(nan_removed, do_clip, clip_rect);
- simplify_t simplified(clipped, simplify, path.simplify_threshold());
-
- buffersize = (size_t) path.total_vertices() * (precision + 5) * 4;
- if (buffersize == 0) {
- return true;
- }
-
- if (sketch_params.scale != 0.0) {
- buffersize *= 10;
- }
-
- buffer.reserve(buffersize);
-
- if (sketch_params.scale == 0.0) {
- return __convert_to_string(simplified, precision, codes, postfix, buffer);
- } else {
- curve_t curve(simplified);
- sketch_t sketch(curve, sketch_params.scale, sketch_params.length, sketch_params.randomness);
- return __convert_to_string(sketch, precision, codes, postfix, buffer);
- }
-
-}
-
-template<class T>
-bool is_sorted_and_has_non_nan(PyArrayObject *array)
-{
- char* ptr = PyArray_BYTES(array);
- npy_intp size = PyArray_DIM(array, 0),
- stride = PyArray_STRIDE(array, 0);
- using limits = std::numeric_limits<T>;
- T last = limits::has_infinity ? -limits::infinity() : limits::min();
- bool found_non_nan = false;
-
- for (npy_intp i = 0; i < size; ++i, ptr += stride) {
- T current = *(T*)ptr;
- // The following tests !isnan(current), but also works for integral
- // types. (The isnan(IntegralType) overload is absent on MSVC.)
- if (current == current) {
- found_non_nan = true;
- if (current < last) {
- return false;
- }
- last = current;
- }
- }
- return found_non_nan;
-};
-
-
-#endif
diff --git a/contrib/python/matplotlib/py3/src/_path_wrapper.cpp b/contrib/python/matplotlib/py3/src/_path_wrapper.cpp
deleted file mode 100644
index 369d9e0308..0000000000
--- a/contrib/python/matplotlib/py3/src/_path_wrapper.cpp
+++ /dev/null
@@ -1,772 +0,0 @@
-#include "numpy_cpp.h"
-
-#include "_path.h"
-
-#include "py_converters.h"
-#include "py_adaptors.h"
-
-PyObject *convert_polygon_vector(std::vector<Polygon> &polygons)
-{
- PyObject *pyresult = PyList_New(polygons.size());
-
- for (size_t i = 0; i < polygons.size(); ++i) {
- Polygon poly = polygons[i];
- npy_intp dims[2];
- dims[1] = 2;
-
- dims[0] = (npy_intp)poly.size();
-
- numpy::array_view<double, 2> subresult(dims);
- memcpy(subresult.data(), &poly[0], sizeof(double) * poly.size() * 2);
-
- if (PyList_SetItem(pyresult, i, subresult.pyobj())) {
- Py_DECREF(pyresult);
- return NULL;
- }
- }
-
- return pyresult;
-}
-
-const char *Py_point_in_path__doc__ =
- "point_in_path(x, y, radius, path, trans)\n"
- "--\n\n";
-
-static PyObject *Py_point_in_path(PyObject *self, PyObject *args)
-{
- double x, y, r;
- py::PathIterator path;
- agg::trans_affine trans;
- bool result;
-
- if (!PyArg_ParseTuple(args,
- "dddO&O&:point_in_path",
- &x,
- &y,
- &r,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- CALL_CPP("point_in_path", (result = point_in_path(x, y, r, path, trans)));
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-const char *Py_points_in_path__doc__ =
- "points_in_path(points, radius, path, trans)\n"
- "--\n\n";
-
-static PyObject *Py_points_in_path(PyObject *self, PyObject *args)
-{
- numpy::array_view<const double, 2> points;
- double r;
- py::PathIterator path;
- agg::trans_affine trans;
-
- if (!PyArg_ParseTuple(args,
- "O&dO&O&:points_in_path",
- &convert_points,
- &points,
- &r,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- npy_intp dims[] = { (npy_intp)points.size() };
- numpy::array_view<uint8_t, 1> results(dims);
-
- CALL_CPP("points_in_path", (points_in_path(points, r, path, trans, results)));
-
- return results.pyobj();
-}
-
-const char *Py_update_path_extents__doc__ =
- "update_path_extents(path, trans, rect, minpos, ignore)\n"
- "--\n\n";
-
-static PyObject *Py_update_path_extents(PyObject *self, PyObject *args)
-{
- py::PathIterator path;
- agg::trans_affine trans;
- agg::rect_d rect;
- numpy::array_view<double, 1> minpos;
- int ignore;
- int changed;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&i:update_path_extents",
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &convert_rect,
- &rect,
- &minpos.converter,
- &minpos,
- &ignore)) {
- return NULL;
- }
-
- if (minpos.dim(0) != 2) {
- PyErr_Format(PyExc_ValueError,
- "minpos must be of length 2, got %" NPY_INTP_FMT,
- minpos.dim(0));
- return NULL;
- }
-
- extent_limits e;
-
- if (ignore) {
- CALL_CPP("update_path_extents", reset_limits(e));
- } else {
- if (rect.x1 > rect.x2) {
- e.x0 = std::numeric_limits<double>::infinity();
- e.x1 = -std::numeric_limits<double>::infinity();
- } else {
- e.x0 = rect.x1;
- e.x1 = rect.x2;
- }
- if (rect.y1 > rect.y2) {
- e.y0 = std::numeric_limits<double>::infinity();
- e.y1 = -std::numeric_limits<double>::infinity();
- } else {
- e.y0 = rect.y1;
- e.y1 = rect.y2;
- }
- e.xm = minpos(0);
- e.ym = minpos(1);
- }
-
- CALL_CPP("update_path_extents", (update_path_extents(path, trans, e)));
-
- changed = (e.x0 != rect.x1 || e.y0 != rect.y1 || e.x1 != rect.x2 || e.y1 != rect.y2 ||
- e.xm != minpos(0) || e.ym != minpos(1));
-
- npy_intp extentsdims[] = { 2, 2 };
- numpy::array_view<double, 2> outextents(extentsdims);
- outextents(0, 0) = e.x0;
- outextents(0, 1) = e.y0;
- outextents(1, 0) = e.x1;
- outextents(1, 1) = e.y1;
-
- npy_intp minposdims[] = { 2 };
- numpy::array_view<double, 1> outminpos(minposdims);
- outminpos(0) = e.xm;
- outminpos(1) = e.ym;
-
- return Py_BuildValue(
- "NNi", outextents.pyobj(), outminpos.pyobj(), changed);
-}
-
-const char *Py_get_path_collection_extents__doc__ =
- "get_path_collection_extents("
- "master_transform, paths, transforms, offsets, offset_transform)\n"
- "--\n\n";
-
-static PyObject *Py_get_path_collection_extents(PyObject *self, PyObject *args)
-{
- agg::trans_affine master_transform;
- py::PathGenerator paths;
- numpy::array_view<const double, 3> transforms;
- numpy::array_view<const double, 2> offsets;
- agg::trans_affine offset_trans;
- extent_limits e;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&O&:get_path_collection_extents",
- &convert_trans_affine,
- &master_transform,
- &convert_pathgen,
- &paths,
- &convert_transforms,
- &transforms,
- &convert_points,
- &offsets,
- &convert_trans_affine,
- &offset_trans)) {
- return NULL;
- }
-
- CALL_CPP("get_path_collection_extents",
- (get_path_collection_extents(
- master_transform, paths, transforms, offsets, offset_trans, e)));
-
- npy_intp dims[] = { 2, 2 };
- numpy::array_view<double, 2> extents(dims);
- extents(0, 0) = e.x0;
- extents(0, 1) = e.y0;
- extents(1, 0) = e.x1;
- extents(1, 1) = e.y1;
-
- npy_intp minposdims[] = { 2 };
- numpy::array_view<double, 1> minpos(minposdims);
- minpos(0) = e.xm;
- minpos(1) = e.ym;
-
- return Py_BuildValue("NN", extents.pyobj(), minpos.pyobj());
-}
-
-const char *Py_point_in_path_collection__doc__ =
- "point_in_path_collection("
- "x, y, radius, master_transform, paths, transforms, offsets, "
- "offset_trans, filled)\n"
- "--\n\n";
-
-static PyObject *Py_point_in_path_collection(PyObject *self, PyObject *args)
-{
- double x, y, radius;
- agg::trans_affine master_transform;
- py::PathGenerator paths;
- numpy::array_view<const double, 3> transforms;
- numpy::array_view<const double, 2> offsets;
- agg::trans_affine offset_trans;
- bool filled;
- std::vector<int> result;
-
- if (!PyArg_ParseTuple(args,
- "dddO&O&O&O&O&O&:point_in_path_collection",
- &x,
- &y,
- &radius,
- &convert_trans_affine,
- &master_transform,
- &convert_pathgen,
- &paths,
- &convert_transforms,
- &transforms,
- &convert_points,
- &offsets,
- &convert_trans_affine,
- &offset_trans,
- &convert_bool,
- &filled)) {
- return NULL;
- }
-
- CALL_CPP("point_in_path_collection",
- (point_in_path_collection(x,
- y,
- radius,
- master_transform,
- paths,
- transforms,
- offsets,
- offset_trans,
- filled,
- result)));
-
- npy_intp dims[] = {(npy_intp)result.size() };
- numpy::array_view<int, 1> pyresult(dims);
- if (result.size() > 0) {
- memcpy(pyresult.data(), &result[0], result.size() * sizeof(int));
- }
- return pyresult.pyobj();
-}
-
-const char *Py_path_in_path__doc__ =
- "path_in_path(path_a, trans_a, path_b, trans_b)\n"
- "--\n\n";
-
-static PyObject *Py_path_in_path(PyObject *self, PyObject *args)
-{
- py::PathIterator a;
- agg::trans_affine atrans;
- py::PathIterator b;
- agg::trans_affine btrans;
- bool result;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&:path_in_path",
- &convert_path,
- &a,
- &convert_trans_affine,
- &atrans,
- &convert_path,
- &b,
- &convert_trans_affine,
- &btrans)) {
- return NULL;
- }
-
- CALL_CPP("path_in_path", (result = path_in_path(a, atrans, b, btrans)));
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-const char *Py_clip_path_to_rect__doc__ =
- "clip_path_to_rect(path, rect, inside)\n"
- "--\n\n";
-
-static PyObject *Py_clip_path_to_rect(PyObject *self, PyObject *args)
-{
- py::PathIterator path;
- agg::rect_d rect;
- bool inside;
- std::vector<Polygon> result;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&:clip_path_to_rect",
- &convert_path,
- &path,
- &convert_rect,
- &rect,
- &convert_bool,
- &inside)) {
- return NULL;
- }
-
- CALL_CPP("clip_path_to_rect", (clip_path_to_rect(path, rect, inside, result)));
-
- return convert_polygon_vector(result);
-}
-
-const char *Py_affine_transform__doc__ =
- "affine_transform(points, trans)\n"
- "--\n\n";
-
-static PyObject *Py_affine_transform(PyObject *self, PyObject *args)
-{
- PyObject *vertices_obj;
- agg::trans_affine trans;
-
- if (!PyArg_ParseTuple(args,
- "OO&:affine_transform",
- &vertices_obj,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- PyArrayObject* vertices_arr = (PyArrayObject *)PyArray_ContiguousFromAny(vertices_obj, NPY_DOUBLE, 1, 2);
- if (vertices_arr == NULL) {
- return NULL;
- }
-
- if (PyArray_NDIM(vertices_arr) == 2) {
- numpy::array_view<double, 2> vertices(vertices_arr);
- Py_DECREF(vertices_arr);
-
- npy_intp dims[] = { (npy_intp)vertices.size(), 2 };
- numpy::array_view<double, 2> result(dims);
- CALL_CPP("affine_transform", (affine_transform_2d(vertices, trans, result)));
- return result.pyobj();
- } else { // PyArray_NDIM(vertices_arr) == 1
- numpy::array_view<double, 1> vertices(vertices_arr);
- Py_DECREF(vertices_arr);
-
- npy_intp dims[] = { (npy_intp)vertices.size() };
- numpy::array_view<double, 1> result(dims);
- CALL_CPP("affine_transform", (affine_transform_1d(vertices, trans, result)));
- return result.pyobj();
- }
-}
-
-const char *Py_count_bboxes_overlapping_bbox__doc__ =
- "count_bboxes_overlapping_bbox(bbox, bboxes)\n"
- "--\n\n";
-
-static PyObject *Py_count_bboxes_overlapping_bbox(PyObject *self, PyObject *args)
-{
- agg::rect_d bbox;
- numpy::array_view<const double, 3> bboxes;
- int result;
-
- if (!PyArg_ParseTuple(args,
- "O&O&:count_bboxes_overlapping_bbox",
- &convert_rect,
- &bbox,
- &convert_bboxes,
- &bboxes)) {
- return NULL;
- }
-
- CALL_CPP("count_bboxes_overlapping_bbox",
- (result = count_bboxes_overlapping_bbox(bbox, bboxes)));
-
- return PyLong_FromLong(result);
-}
-
-const char *Py_path_intersects_path__doc__ =
- "path_intersects_path(path1, path2, filled=False)\n"
- "--\n\n";
-
-static PyObject *Py_path_intersects_path(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator p1;
- py::PathIterator p2;
- agg::trans_affine t1;
- agg::trans_affine t2;
- int filled = 0;
- const char *names[] = { "p1", "p2", "filled", NULL };
- bool result;
-
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O&O&i:path_intersects_path",
- (char **)names,
- &convert_path,
- &p1,
- &convert_path,
- &p2,
- &filled)) {
- return NULL;
- }
-
- CALL_CPP("path_intersects_path", (result = path_intersects_path(p1, p2)));
- if (filled) {
- if (!result) {
- CALL_CPP("path_intersects_path",
- (result = path_in_path(p1, t1, p2, t2)));
- }
- if (!result) {
- CALL_CPP("path_intersects_path",
- (result = path_in_path(p2, t1, p1, t2)));
- }
- }
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-const char *Py_path_intersects_rectangle__doc__ =
- "path_intersects_rectangle("
- "path, rect_x1, rect_y1, rect_x2, rect_y2, filled=False)\n"
- "--\n\n";
-
-static PyObject *Py_path_intersects_rectangle(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator path;
- double rect_x1, rect_y1, rect_x2, rect_y2;
- bool filled = false;
- const char *names[] = { "path", "rect_x1", "rect_y1", "rect_x2", "rect_y2", "filled", NULL };
- bool result;
-
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O&dddd|O&:path_intersects_rectangle",
- (char **)names,
- &convert_path,
- &path,
- &rect_x1,
- &rect_y1,
- &rect_x2,
- &rect_y2,
- &convert_bool,
- &filled)) {
- return NULL;
- }
-
- CALL_CPP("path_intersects_rectangle", (result = path_intersects_rectangle(path, rect_x1, rect_y1, rect_x2, rect_y2, filled)));
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-const char *Py_convert_path_to_polygons__doc__ =
- "convert_path_to_polygons(path, trans, width=0, height=0)\n"
- "--\n\n";
-
-static PyObject *Py_convert_path_to_polygons(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator path;
- agg::trans_affine trans;
- double width = 0.0, height = 0.0;
- int closed_only = 1;
- std::vector<Polygon> result;
- const char *names[] = { "path", "transform", "width", "height", "closed_only", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O&O&|ddi:convert_path_to_polygons",
- (char **)names,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &width,
- &height,
- &closed_only)) {
- return NULL;
- }
-
- CALL_CPP("convert_path_to_polygons",
- (convert_path_to_polygons(path, trans, width, height, closed_only, result)));
-
- return convert_polygon_vector(result);
-}
-
-const char *Py_cleanup_path__doc__ =
- "cleanup_path("
- "path, trans, remove_nans, clip_rect, snap_mode, stroke_width, simplify, "
- "return_curves, sketch)\n"
- "--\n\n";
-
-static PyObject *Py_cleanup_path(PyObject *self, PyObject *args)
-{
- py::PathIterator path;
- agg::trans_affine trans;
- bool remove_nans;
- agg::rect_d clip_rect;
- e_snap_mode snap_mode;
- double stroke_width;
- PyObject *simplifyobj;
- bool simplify = false;
- bool return_curves;
- SketchParams sketch;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&O&dOO&O&:cleanup_path",
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &convert_bool,
- &remove_nans,
- &convert_rect,
- &clip_rect,
- &convert_snap,
- &snap_mode,
- &stroke_width,
- &simplifyobj,
- &convert_bool,
- &return_curves,
- &convert_sketch_params,
- &sketch)) {
- return NULL;
- }
-
- if (simplifyobj == Py_None) {
- simplify = path.should_simplify();
- } else {
- switch (PyObject_IsTrue(simplifyobj)) {
- case 0: simplify = false; break;
- case 1: simplify = true; break;
- default: return NULL; // errored.
- }
- }
-
- bool do_clip = (clip_rect.x1 < clip_rect.x2 && clip_rect.y1 < clip_rect.y2);
-
- std::vector<double> vertices;
- std::vector<npy_uint8> codes;
-
- CALL_CPP("cleanup_path",
- (cleanup_path(path,
- trans,
- remove_nans,
- do_clip,
- clip_rect,
- snap_mode,
- stroke_width,
- simplify,
- return_curves,
- sketch,
- vertices,
- codes)));
-
- size_t length = codes.size();
-
- npy_intp vertices_dims[] = {(npy_intp)length, 2 };
- numpy::array_view<double, 2> pyvertices(vertices_dims);
-
- npy_intp codes_dims[] = {(npy_intp)length };
- numpy::array_view<unsigned char, 1> pycodes(codes_dims);
-
- memcpy(pyvertices.data(), &vertices[0], sizeof(double) * 2 * length);
- memcpy(pycodes.data(), &codes[0], sizeof(unsigned char) * length);
-
- return Py_BuildValue("NN", pyvertices.pyobj(), pycodes.pyobj());
-}
-
-const char *Py_convert_to_string__doc__ =
- "convert_to_string("
- "path, trans, clip_rect, simplify, sketch, precision, codes, postfix)\n"
- "--\n\n"
- "Convert *path* to a bytestring.\n"
- "\n"
- "The first five parameters (up to *sketch*) are interpreted as in\n"
- "`.cleanup_path`. The following ones are detailed below.\n"
- "\n"
- "Parameters\n"
- "----------\n"
- "path : Path\n"
- "trans : Transform or None\n"
- "clip_rect : sequence of 4 floats, or None\n"
- "simplify : bool\n"
- "sketch : tuple of 3 floats, or None\n"
- "precision : int\n"
- " The precision used to \"%.*f\"-format the values. Trailing zeros\n"
- " and decimal points are always removed. (precision=-1 is a special\n"
- " case used to implement ttconv-back-compatible conversion.)\n"
- "codes : sequence of 5 bytestrings\n"
- " The bytes representation of each opcode (MOVETO, LINETO, CURVE3,\n"
- " CURVE4, CLOSEPOLY), in that order. If the bytes for CURVE3 is\n"
- " empty, quad segments are automatically converted to cubic ones\n"
- " (this is used by backends such as pdf and ps, which do not support\n"
- " quads).\n"
- "postfix : bool\n"
- " Whether the opcode comes after the values (True) or before (False).\n"
- ;
-
-static PyObject *Py_convert_to_string(PyObject *self, PyObject *args)
-{
- py::PathIterator path;
- agg::trans_affine trans;
- agg::rect_d cliprect;
- PyObject *simplifyobj;
- bool simplify = false;
- SketchParams sketch;
- int precision;
- char *codes[5];
- bool postfix;
- std::string buffer;
- bool status;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&OO&i(yyyyy)O&:convert_to_string",
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &convert_rect,
- &cliprect,
- &simplifyobj,
- &convert_sketch_params,
- &sketch,
- &precision,
- &codes[0],
- &codes[1],
- &codes[2],
- &codes[3],
- &codes[4],
- &convert_bool,
- &postfix)) {
- return NULL;
- }
-
- if (simplifyobj == Py_None) {
- simplify = path.should_simplify();
- } else {
- switch (PyObject_IsTrue(simplifyobj)) {
- case 0: simplify = false; break;
- case 1: simplify = true; break;
- default: return NULL; // errored.
- }
- }
-
- CALL_CPP("convert_to_string",
- (status = convert_to_string(
- path, trans, cliprect, simplify, sketch,
- precision, codes, postfix, buffer)));
-
- if (!status) {
- PyErr_SetString(PyExc_ValueError, "Malformed path codes");
- return NULL;
- }
-
- return PyBytes_FromStringAndSize(buffer.c_str(), buffer.size());
-}
-
-
-const char *Py_is_sorted_and_has_non_nan__doc__ =
- "is_sorted_and_has_non_nan(array, /)\n"
- "--\n\n"
- "Return whether the 1D *array* is monotonically increasing, ignoring NaNs,\n"
- "and has at least one non-nan value.";
-
-static PyObject *Py_is_sorted_and_has_non_nan(PyObject *self, PyObject *obj)
-{
- bool result;
-
- PyArrayObject *array = (PyArrayObject *)PyArray_FromAny(
- obj, NULL, 1, 1, 0, NULL);
-
- if (array == NULL) {
- return NULL;
- }
-
- /* Handle just the most common types here, otherwise coerce to double */
- switch (PyArray_TYPE(array)) {
- case NPY_INT:
- result = is_sorted_and_has_non_nan<npy_int>(array);
- break;
- case NPY_LONG:
- result = is_sorted_and_has_non_nan<npy_long>(array);
- break;
- case NPY_LONGLONG:
- result = is_sorted_and_has_non_nan<npy_longlong>(array);
- break;
- case NPY_FLOAT:
- result = is_sorted_and_has_non_nan<npy_float>(array);
- break;
- case NPY_DOUBLE:
- result = is_sorted_and_has_non_nan<npy_double>(array);
- break;
- default:
- Py_DECREF(array);
- array = (PyArrayObject *)PyArray_FromObject(obj, NPY_DOUBLE, 1, 1);
- if (array == NULL) {
- return NULL;
- }
- result = is_sorted_and_has_non_nan<npy_double>(array);
- }
-
- Py_DECREF(array);
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-
-static PyMethodDef module_functions[] = {
- {"point_in_path", (PyCFunction)Py_point_in_path, METH_VARARGS, Py_point_in_path__doc__},
- {"points_in_path", (PyCFunction)Py_points_in_path, METH_VARARGS, Py_points_in_path__doc__},
- {"update_path_extents", (PyCFunction)Py_update_path_extents, METH_VARARGS, Py_update_path_extents__doc__},
- {"get_path_collection_extents", (PyCFunction)Py_get_path_collection_extents, METH_VARARGS, Py_get_path_collection_extents__doc__},
- {"point_in_path_collection", (PyCFunction)Py_point_in_path_collection, METH_VARARGS, Py_point_in_path_collection__doc__},
- {"path_in_path", (PyCFunction)Py_path_in_path, METH_VARARGS, Py_path_in_path__doc__},
- {"clip_path_to_rect", (PyCFunction)Py_clip_path_to_rect, METH_VARARGS, Py_clip_path_to_rect__doc__},
- {"affine_transform", (PyCFunction)Py_affine_transform, METH_VARARGS, Py_affine_transform__doc__},
- {"count_bboxes_overlapping_bbox", (PyCFunction)Py_count_bboxes_overlapping_bbox, METH_VARARGS, Py_count_bboxes_overlapping_bbox__doc__},
- {"path_intersects_path", (PyCFunction)Py_path_intersects_path, METH_VARARGS|METH_KEYWORDS, Py_path_intersects_path__doc__},
- {"path_intersects_rectangle", (PyCFunction)Py_path_intersects_rectangle, METH_VARARGS|METH_KEYWORDS, Py_path_intersects_rectangle__doc__},
- {"convert_path_to_polygons", (PyCFunction)Py_convert_path_to_polygons, METH_VARARGS|METH_KEYWORDS, Py_convert_path_to_polygons__doc__},
- {"cleanup_path", (PyCFunction)Py_cleanup_path, METH_VARARGS, Py_cleanup_path__doc__},
- {"convert_to_string", (PyCFunction)Py_convert_to_string, METH_VARARGS, Py_convert_to_string__doc__},
- {"is_sorted_and_has_non_nan", (PyCFunction)Py_is_sorted_and_has_non_nan, METH_O, Py_is_sorted_and_has_non_nan__doc__},
- {NULL}
-};
-
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT, "_path", NULL, 0, module_functions
-};
-
-PyMODINIT_FUNC PyInit__path(void)
-{
- import_array();
- return PyModule_Create(&moduledef);
-}
diff --git a/contrib/python/matplotlib/py3/src/_qhull_wrapper.cpp b/contrib/python/matplotlib/py3/src/_qhull_wrapper.cpp
deleted file mode 100644
index 7e4f306305..0000000000
--- a/contrib/python/matplotlib/py3/src/_qhull_wrapper.cpp
+++ /dev/null
@@ -1,340 +0,0 @@
-/*
- * Wrapper module for libqhull, providing Delaunay triangulation.
- *
- * This module's methods should not be accessed directly. To obtain a Delaunay
- * triangulation, construct an instance of the matplotlib.tri.Triangulation
- * class without specifying a triangles array.
- */
-#define PY_SSIZE_T_CLEAN
-#include "Python.h"
-#include "numpy_cpp.h"
-#ifdef _MSC_VER
-/* The Qhull header does not declare this as extern "C", but only MSVC seems to
- * do name mangling on global variables. We thus need to declare this before
- * the header so that it treats it correctly, and doesn't mangle the name. */
-extern "C" {
-extern const char qh_version[];
-}
-#endif
-#include "libqhull_r/qhull_ra.h"
-#include <cstdio>
-#include <vector>
-
-
-#ifndef MPL_DEVNULL
-#error "MPL_DEVNULL must be defined as the OS-equivalent of /dev/null"
-#endif
-
-#define STRINGIFY(x) STR(x)
-#define STR(x) #x
-
-
-static const char* qhull_error_msg[6] = {
- "", /* 0 = qh_ERRnone */
- "input inconsistency", /* 1 = qh_ERRinput */
- "singular input data", /* 2 = qh_ERRsingular */
- "precision error", /* 3 = qh_ERRprec */
- "insufficient memory", /* 4 = qh_ERRmem */
- "internal error"}; /* 5 = qh_ERRqhull */
-
-
-/* Return the indices of the 3 vertices that comprise the specified facet (i.e.
- * triangle). */
-static void
-get_facet_vertices(qhT* qh, const facetT* facet, int indices[3])
-{
- vertexT *vertex, **vertexp;
- FOREACHvertex_(facet->vertices) {
- *indices++ = qh_pointid(qh, vertex->point);
- }
-}
-
-/* Return the indices of the 3 triangles that are neighbors of the specified
- * facet (triangle). */
-static void
-get_facet_neighbours(const facetT* facet, std::vector<int>& tri_indices,
- int indices[3])
-{
- facetT *neighbor, **neighborp;
- FOREACHneighbor_(facet) {
- *indices++ = (neighbor->upperdelaunay ? -1 : tri_indices[neighbor->id]);
- }
-}
-
-/* Return true if the specified points arrays contain at least 3 unique points,
- * or false otherwise. */
-static bool
-at_least_3_unique_points(npy_intp npoints, const double* x, const double* y)
-{
- int i;
- const int unique1 = 0; /* First unique point has index 0. */
- int unique2 = 0; /* Second unique point index is 0 until set. */
-
- if (npoints < 3) {
- return false;
- }
-
- for (i = 1; i < npoints; ++i) {
- if (unique2 == 0) {
- /* Looking for second unique point. */
- if (x[i] != x[unique1] || y[i] != y[unique1]) {
- unique2 = i;
- }
- }
- else {
- /* Looking for third unique point. */
- if ( (x[i] != x[unique1] || y[i] != y[unique1]) &&
- (x[i] != x[unique2] || y[i] != y[unique2]) ) {
- /* 3 unique points found, with indices 0, unique2 and i. */
- return true;
- }
- }
- }
-
- /* Run out of points before 3 unique points found. */
- return false;
-}
-
-/* Holds on to info from Qhull so that it can be destructed automatically. */
-class QhullInfo {
-public:
- QhullInfo(FILE *error_file, qhT* qh) {
- this->error_file = error_file;
- this->qh = qh;
- }
-
- ~QhullInfo() {
- qh_freeqhull(this->qh, !qh_ALL);
- int curlong, totlong; /* Memory remaining. */
- qh_memfreeshort(this->qh, &curlong, &totlong);
- if (curlong || totlong) {
- PyErr_WarnEx(PyExc_RuntimeWarning,
- "Qhull could not free all allocated memory", 1);
- }
-
- if (this->error_file != stderr) {
- fclose(error_file);
- }
- }
-
-private:
- FILE* error_file;
- qhT* qh;
-};
-
-/* Delaunay implementation method.
- * If hide_qhull_errors is true then qhull error messages are discarded;
- * if it is false then they are written to stderr. */
-static PyObject*
-delaunay_impl(npy_intp npoints, const double* x, const double* y,
- bool hide_qhull_errors)
-{
- qhT qh_qh; /* qh variable type and name must be like */
- qhT* qh = &qh_qh; /* this for Qhull macros to work correctly. */
- facetT* facet;
- int i, ntri, max_facet_id;
- int exitcode; /* Value returned from qh_new_qhull(). */
- const int ndim = 2;
- double x_mean = 0.0;
- double y_mean = 0.0;
-
- QHULL_LIB_CHECK
-
- /* Allocate points. */
- std::vector<coordT> points(npoints * ndim);
-
- /* Determine mean x, y coordinates. */
- for (i = 0; i < npoints; ++i) {
- x_mean += x[i];
- y_mean += y[i];
- }
- x_mean /= npoints;
- y_mean /= npoints;
-
- /* Prepare points array to pass to qhull. */
- for (i = 0; i < npoints; ++i) {
- points[2*i ] = x[i] - x_mean;
- points[2*i+1] = y[i] - y_mean;
- }
-
- /* qhull expects a FILE* to write errors to. */
- FILE* error_file = NULL;
- if (hide_qhull_errors) {
- /* qhull errors are ignored by writing to OS-equivalent of /dev/null.
- * Rather than have OS-specific code here, instead it is determined by
- * setupext.py and passed in via the macro MPL_DEVNULL. */
- error_file = fopen(STRINGIFY(MPL_DEVNULL), "w");
- if (error_file == NULL) {
- throw std::runtime_error("Could not open devnull");
- }
- }
- else {
- /* qhull errors written to stderr. */
- error_file = stderr;
- }
-
- /* Perform Delaunay triangulation. */
- QhullInfo info(error_file, qh);
- qh_zero(qh, error_file);
- exitcode = qh_new_qhull(qh, ndim, (int)npoints, points.data(), False,
- (char*)"qhull d Qt Qbb Qc Qz", NULL, error_file);
- if (exitcode != qh_ERRnone) {
- PyErr_Format(PyExc_RuntimeError,
- "Error in qhull Delaunay triangulation calculation: %s (exitcode=%d)%s",
- qhull_error_msg[exitcode], exitcode,
- hide_qhull_errors ? "; use python verbose option (-v) to see original qhull error." : "");
- return NULL;
- }
-
- /* Split facets so that they only have 3 points each. */
- qh_triangulate(qh);
-
- /* Determine ntri and max_facet_id.
- Note that libqhull uses macros to iterate through collections. */
- ntri = 0;
- FORALLfacets {
- if (!facet->upperdelaunay) {
- ++ntri;
- }
- }
-
- max_facet_id = qh->facet_id - 1;
-
- /* Create array to map facet id to triangle index. */
- std::vector<int> tri_indices(max_facet_id+1);
-
- /* Allocate Python arrays to return. */
- npy_intp dims[2] = {ntri, 3};
- numpy::array_view<int, ndim> triangles(dims);
- int* triangles_ptr = triangles.data();
-
- numpy::array_view<int, ndim> neighbors(dims);
- int* neighbors_ptr = neighbors.data();
-
- /* Determine triangles array and set tri_indices array. */
- i = 0;
- FORALLfacets {
- if (!facet->upperdelaunay) {
- int indices[3];
- tri_indices[facet->id] = i++;
- get_facet_vertices(qh, facet, indices);
- *triangles_ptr++ = (facet->toporient ? indices[0] : indices[2]);
- *triangles_ptr++ = indices[1];
- *triangles_ptr++ = (facet->toporient ? indices[2] : indices[0]);
- }
- else {
- tri_indices[facet->id] = -1;
- }
- }
-
- /* Determine neighbors array. */
- FORALLfacets {
- if (!facet->upperdelaunay) {
- int indices[3];
- get_facet_neighbours(facet, tri_indices, indices);
- *neighbors_ptr++ = (facet->toporient ? indices[2] : indices[0]);
- *neighbors_ptr++ = (facet->toporient ? indices[0] : indices[2]);
- *neighbors_ptr++ = indices[1];
- }
- }
-
- PyObject* tuple = PyTuple_New(2);
- if (tuple == 0) {
- throw std::runtime_error("Failed to create Python tuple");
- }
-
- PyTuple_SET_ITEM(tuple, 0, triangles.pyobj());
- PyTuple_SET_ITEM(tuple, 1, neighbors.pyobj());
- return tuple;
-}
-
-/* Process Python arguments and call Delaunay implementation method. */
-static PyObject*
-delaunay(PyObject *self, PyObject *args)
-{
- numpy::array_view<double, 1> xarray;
- numpy::array_view<double, 1> yarray;
- PyObject* ret;
- npy_intp npoints;
- const double* x;
- const double* y;
- int verbose = 0;
-
- if (!PyArg_ParseTuple(args, "O&O&i:delaunay",
- &xarray.converter_contiguous, &xarray,
- &yarray.converter_contiguous, &yarray,
- &verbose)) {
- return NULL;
- }
-
- npoints = xarray.dim(0);
- if (npoints != yarray.dim(0)) {
- PyErr_SetString(PyExc_ValueError,
- "x and y must be 1D arrays of the same length");
- return NULL;
- }
-
- if (npoints < 3) {
- PyErr_SetString(PyExc_ValueError,
- "x and y arrays must have a length of at least 3");
- return NULL;
- }
-
- x = xarray.data();
- y = yarray.data();
-
- if (!at_least_3_unique_points(npoints, x, y)) {
- PyErr_SetString(PyExc_ValueError,
- "x and y arrays must consist of at least 3 unique points");
- return NULL;
- }
-
- CALL_CPP("qhull.delaunay",
- (ret = delaunay_impl(npoints, x, y, verbose == 0)));
-
- return ret;
-}
-
-/* Return qhull version string for assistance in debugging. */
-static PyObject*
-version(PyObject *self, PyObject *arg)
-{
- return PyBytes_FromString(qh_version);
-}
-
-static PyMethodDef qhull_methods[] = {
- {"delaunay", delaunay, METH_VARARGS,
- "delaunay(x, y, verbose, /)\n"
- "--\n\n"
- "Compute a Delaunay triangulation.\n"
- "\n"
- "Parameters\n"
- "----------\n"
- "x, y : 1d arrays\n"
- " The coordinates of the point set, which must consist of at least\n"
- " three unique points.\n"
- "verbose : int\n"
- " Python's verbosity level.\n"
- "\n"
- "Returns\n"
- "-------\n"
- "triangles, neighbors : int arrays, shape (ntri, 3)\n"
- " Indices of triangle vertices and indices of triangle neighbors.\n"
- },
- {"version", version, METH_NOARGS,
- "version()\n--\n\n"
- "Return the qhull version string."},
- {NULL, NULL, 0, NULL}
-};
-
-static struct PyModuleDef qhull_module = {
- PyModuleDef_HEAD_INIT,
- "qhull", "Computing Delaunay triangulations.\n", -1, qhull_methods
-};
-
-PyMODINIT_FUNC
-PyInit__qhull(void)
-{
- import_array();
- return PyModule_Create(&qhull_module);
-}
diff --git a/contrib/python/matplotlib/py3/src/_tkagg.cpp b/contrib/python/matplotlib/py3/src/_tkagg.cpp
deleted file mode 100644
index 5c36b3f07f..0000000000
--- a/contrib/python/matplotlib/py3/src/_tkagg.cpp
+++ /dev/null
@@ -1,370 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-// Where is PIL?
-//
-// Many years ago, Matplotlib used to include code from PIL (the Python Imaging
-// Library). Since then, the code has changed a lot - the organizing principle
-// and methods of operation are now quite different. Because our review of
-// the codebase showed that all the code that came from PIL was removed or
-// rewritten, we have removed the PIL licensing information. If you want PIL,
-// you can get it at https://python-pillow.org/
-
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-
-#ifdef _WIN32
-#define WIN32_DLL
-#endif
-#ifdef __CYGWIN__
-/*
- * Unfortunately cygwin's libdl inherits restrictions from the underlying
- * Windows OS, at least currently. Therefore, a symbol may be loaded from a
- * module by dlsym() only if it is really located in the given module,
- * dependencies are not included. So we have to use native WinAPI on Cygwin
- * also.
- */
-#define WIN32_DLL
-static inline PyObject *PyErr_SetFromWindowsErr(int ierr) {
- PyErr_SetString(PyExc_OSError, "Call to EnumProcessModules failed");
- return NULL;
-}
-#endif
-
-#ifdef WIN32_DLL
-#include <string>
-#include <windows.h>
-#include <commctrl.h>
-#define PSAPI_VERSION 1
-#include <psapi.h> // Must be linked with 'psapi' library
-#define dlsym GetProcAddress
-#else
-#include <dlfcn.h>
-#endif
-
-// Include our own excerpts from the Tcl / Tk headers
-#include "_tkmini.h"
-
-static int convert_voidptr(PyObject *obj, void *p)
-{
- void **val = (void **)p;
- *val = PyLong_AsVoidPtr(obj);
- return *val != NULL ? 1 : !PyErr_Occurred();
-}
-
-// Global vars for Tk functions. We load these symbols from the tkinter
-// extension module or loaded Tk libraries at run-time.
-static Tk_FindPhoto_t TK_FIND_PHOTO;
-static Tk_PhotoPutBlock_t TK_PHOTO_PUT_BLOCK;
-// Global vars for Tcl functions. We load these symbols from the tkinter
-// extension module or loaded Tcl libraries at run-time.
-static Tcl_SetVar_t TCL_SETVAR;
-
-static PyObject *mpl_tk_blit(PyObject *self, PyObject *args)
-{
- Tcl_Interp *interp;
- char const *photo_name;
- int height, width;
- unsigned char *data_ptr;
- int comp_rule;
- int put_retval;
- int o0, o1, o2, o3;
- int x1, x2, y1, y2;
- Tk_PhotoHandle photo;
- Tk_PhotoImageBlock block;
- if (!PyArg_ParseTuple(args, "O&s(iiO&)i(iiii)(iiii):blit",
- convert_voidptr, &interp, &photo_name,
- &height, &width, convert_voidptr, &data_ptr,
- &comp_rule,
- &o0, &o1, &o2, &o3,
- &x1, &x2, &y1, &y2)) {
- goto exit;
- }
- if (!(photo = TK_FIND_PHOTO(interp, photo_name))) {
- PyErr_SetString(PyExc_ValueError, "Failed to extract Tk_PhotoHandle");
- goto exit;
- }
- if (0 > y1 || y1 > y2 || y2 > height || 0 > x1 || x1 > x2 || x2 > width) {
- PyErr_SetString(PyExc_ValueError, "Attempting to draw out of bounds");
- goto exit;
- }
- if (comp_rule != TK_PHOTO_COMPOSITE_OVERLAY && comp_rule != TK_PHOTO_COMPOSITE_SET) {
- PyErr_SetString(PyExc_ValueError, "Invalid comp_rule argument");
- goto exit;
- }
-
- Py_BEGIN_ALLOW_THREADS
- block.pixelPtr = data_ptr + 4 * ((height - y2) * width + x1);
- block.width = x2 - x1;
- block.height = y2 - y1;
- block.pitch = 4 * width;
- block.pixelSize = 4;
- block.offset[0] = o0;
- block.offset[1] = o1;
- block.offset[2] = o2;
- block.offset[3] = o3;
- put_retval = TK_PHOTO_PUT_BLOCK(
- interp, photo, &block, x1, height - y2, x2 - x1, y2 - y1, comp_rule);
- Py_END_ALLOW_THREADS
- if (put_retval == TCL_ERROR) {
- return PyErr_NoMemory();
- }
-
-exit:
- if (PyErr_Occurred()) {
- return NULL;
- } else {
- Py_RETURN_NONE;
- }
-}
-
-#ifdef WIN32_DLL
-LRESULT CALLBACK
-DpiSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
- UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
-{
- switch (uMsg) {
- case WM_DPICHANGED:
- // This function is a subclassed window procedure, and so is run during
- // the Tcl/Tk event loop. Unfortunately, Tkinter has a *second* lock on
- // Tcl threading that is not exposed publicly, but is currently taken
- // while we're in the window procedure. So while we can take the GIL to
- // call Python code, we must not also call *any* Tk code from Python.
- // So stay with Tcl calls in C only.
- {
- // This variable naming must match the name used in
- // lib/matplotlib/backends/_backend_tk.py:FigureManagerTk.
- std::string var_name("window_dpi");
- var_name += std::to_string((unsigned long long)hwnd);
-
- // X is high word, Y is low word, but they are always equal.
- std::string dpi = std::to_string(LOWORD(wParam));
-
- Tcl_Interp* interp = (Tcl_Interp*)dwRefData;
- TCL_SETVAR(interp, var_name.c_str(), dpi.c_str(), 0);
- }
- return 0;
- case WM_NCDESTROY:
- RemoveWindowSubclass(hwnd, DpiSubclassProc, uIdSubclass);
- break;
- }
-
- return DefSubclassProc(hwnd, uMsg, wParam, lParam);
-}
-#endif
-
-static PyObject*
-mpl_tk_enable_dpi_awareness(PyObject* self, PyObject*const* args,
- Py_ssize_t nargs)
-{
- if (nargs != 2) {
- return PyErr_Format(PyExc_TypeError,
- "enable_dpi_awareness() takes 2 positional "
- "arguments but %zd were given",
- nargs);
- }
-
-#ifdef WIN32_DLL
- HWND frame_handle = NULL;
- Tcl_Interp *interp = NULL;
-
- if (!convert_voidptr(args[0], &frame_handle)) {
- return NULL;
- }
- if (!convert_voidptr(args[1], &interp)) {
- return NULL;
- }
-
-#ifdef _DPI_AWARENESS_CONTEXTS_
- HMODULE user32 = LoadLibrary("user32.dll");
-
- typedef DPI_AWARENESS_CONTEXT (WINAPI *GetWindowDpiAwarenessContext_t)(HWND);
- GetWindowDpiAwarenessContext_t GetWindowDpiAwarenessContextPtr =
- (GetWindowDpiAwarenessContext_t)GetProcAddress(
- user32, "GetWindowDpiAwarenessContext");
- if (GetWindowDpiAwarenessContextPtr == NULL) {
- FreeLibrary(user32);
- Py_RETURN_FALSE;
- }
-
- typedef BOOL (WINAPI *AreDpiAwarenessContextsEqual_t)(DPI_AWARENESS_CONTEXT,
- DPI_AWARENESS_CONTEXT);
- AreDpiAwarenessContextsEqual_t AreDpiAwarenessContextsEqualPtr =
- (AreDpiAwarenessContextsEqual_t)GetProcAddress(
- user32, "AreDpiAwarenessContextsEqual");
- if (AreDpiAwarenessContextsEqualPtr == NULL) {
- FreeLibrary(user32);
- Py_RETURN_FALSE;
- }
-
- DPI_AWARENESS_CONTEXT ctx = GetWindowDpiAwarenessContextPtr(frame_handle);
- bool per_monitor = (
- AreDpiAwarenessContextsEqualPtr(
- ctx, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) ||
- AreDpiAwarenessContextsEqualPtr(
- ctx, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE));
-
- if (per_monitor) {
- // Per monitor aware means we need to handle WM_DPICHANGED by wrapping
- // the Window Procedure, and the Python side needs to trace the Tk
- // window_dpi variable stored on interp.
- SetWindowSubclass(frame_handle, DpiSubclassProc, 0, (DWORD_PTR)interp);
- }
- FreeLibrary(user32);
- return PyBool_FromLong(per_monitor);
-#endif
-#endif
-
- Py_RETURN_NONE;
-}
-
-static PyMethodDef functions[] = {
- { "blit", (PyCFunction)mpl_tk_blit, METH_VARARGS },
- { "enable_dpi_awareness", (PyCFunction)mpl_tk_enable_dpi_awareness,
- METH_FASTCALL },
- { NULL, NULL } /* sentinel */
-};
-
-// Functions to fill global Tcl/Tk function pointers by dynamic loading.
-
-template <class T>
-bool load_tcl_tk(T lib)
-{
- // Try to fill Tcl/Tk global vars with function pointers. Return whether
- // all of them have been filled.
- if (auto ptr = dlsym(lib, "Tcl_SetVar")) {
- TCL_SETVAR = (Tcl_SetVar_t)ptr;
- }
- if (auto ptr = dlsym(lib, "Tk_FindPhoto")) {
- TK_FIND_PHOTO = (Tk_FindPhoto_t)ptr;
- }
- if (auto ptr = dlsym(lib, "Tk_PhotoPutBlock")) {
- TK_PHOTO_PUT_BLOCK = (Tk_PhotoPutBlock_t)ptr;
- }
- return TCL_SETVAR && TK_FIND_PHOTO && TK_PHOTO_PUT_BLOCK;
-}
-
-#ifdef WIN32_DLL
-
-/* On Windows, we can't load the tkinter module to get the Tcl/Tk symbols,
- * because Windows does not load symbols into the library name-space of
- * importing modules. So, knowing that tkinter has already been imported by
- * Python, we scan all modules in the running process for the Tcl/Tk function
- * names.
- */
-
-void load_tkinter_funcs(void)
-{
- HANDLE process = GetCurrentProcess(); // Pseudo-handle, doesn't need closing.
- HMODULE* modules = NULL;
- DWORD size;
- if (!EnumProcessModules(process, NULL, 0, &size)) {
- PyErr_SetFromWindowsErr(0);
- goto exit;
- }
- if (!(modules = static_cast<HMODULE*>(malloc(size)))) {
- PyErr_NoMemory();
- goto exit;
- }
- if (!EnumProcessModules(process, modules, size, &size)) {
- PyErr_SetFromWindowsErr(0);
- goto exit;
- }
- for (unsigned i = 0; i < size / sizeof(HMODULE); ++i) {
- if (load_tcl_tk(modules[i])) {
- return;
- }
- }
-exit:
- free(modules);
-}
-
-#else // not Windows
-
-/*
- * On Unix, we can get the Tk symbols from the tkinter module, because tkinter
- * uses these symbols, and the symbols are therefore visible in the tkinter
- * dynamic library (module).
- */
-
-void load_tkinter_funcs(void)
-{
- // Load tkinter global funcs from tkinter compiled module.
- void *main_program = NULL, *tkinter_lib = NULL;
- PyObject *module = NULL, *py_path = NULL, *py_path_b = NULL;
- char *path;
-
- // Try loading from the main program namespace first.
- main_program = dlopen(NULL, RTLD_LAZY);
- if (load_tcl_tk(main_program)) {
- goto exit;
- }
- // Clear exception triggered when we didn't find symbols above.
- PyErr_Clear();
-
- // Handle PyPy first, as that import will correctly fail on CPython.
- module = PyImport_ImportModule("_tkinter.tklib_cffi"); // PyPy
- if (!module) {
- PyErr_Clear();
- module = PyImport_ImportModule("_tkinter"); // CPython
- }
- if (!(module &&
- (py_path = PyObject_GetAttrString(module, "__file__")) &&
- (py_path_b = PyUnicode_EncodeFSDefault(py_path)) &&
- (path = PyBytes_AsString(py_path_b)))) {
- goto exit;
- }
- tkinter_lib = dlopen(path, RTLD_LAZY);
- if (!tkinter_lib) {
- PyErr_SetString(PyExc_RuntimeError, dlerror());
- goto exit;
- }
- if (load_tcl_tk(tkinter_lib)) {
- goto exit;
- }
-
-exit:
- // We don't need to keep a reference open as the main program & tkinter
- // have been imported. Try to close each library separately (otherwise the
- // second dlclose could clear a dlerror from the first dlclose).
- bool raised_dlerror = false;
- if (main_program && dlclose(main_program) && !raised_dlerror) {
- PyErr_SetString(PyExc_RuntimeError, dlerror());
- raised_dlerror = true;
- }
- if (tkinter_lib && dlclose(tkinter_lib) && !raised_dlerror) {
- PyErr_SetString(PyExc_RuntimeError, dlerror());
- raised_dlerror = true;
- }
- Py_XDECREF(module);
- Py_XDECREF(py_path);
- Py_XDECREF(py_path_b);
-}
-#endif // end not Windows
-
-static PyModuleDef _tkagg_module = {
- PyModuleDef_HEAD_INIT, "_tkagg", NULL, -1, functions
-};
-
-PyMODINIT_FUNC PyInit__tkagg(void)
-{
- load_tkinter_funcs();
- PyObject *type, *value, *traceback;
- PyErr_Fetch(&type, &value, &traceback);
- // Always raise ImportError (normalizing a previously set exception if
- // needed) to interact properly with backend auto-fallback.
- if (value) {
- PyErr_NormalizeException(&type, &value, &traceback);
- PyErr_SetObject(PyExc_ImportError, value);
- return NULL;
- } else if (!TCL_SETVAR) {
- PyErr_SetString(PyExc_ImportError, "Failed to load Tcl_SetVar");
- return NULL;
- } else if (!TK_FIND_PHOTO) {
- PyErr_SetString(PyExc_ImportError, "Failed to load Tk_FindPhoto");
- return NULL;
- } else if (!TK_PHOTO_PUT_BLOCK) {
- PyErr_SetString(PyExc_ImportError, "Failed to load Tk_PhotoPutBlock");
- return NULL;
- }
- return PyModule_Create(&_tkagg_module);
-}
diff --git a/contrib/python/matplotlib/py3/src/_tkmini.h b/contrib/python/matplotlib/py3/src/_tkmini.h
deleted file mode 100644
index 85f245815e..0000000000
--- a/contrib/python/matplotlib/py3/src/_tkmini.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/* Small excerpts from the Tcl / Tk 8.6 headers
- *
- * License terms copied from:
- * http://www.tcl.tk/software/tcltk/license.html
- * as of 20 May 2016.
- *
- * Copyright (c) 1987-1994 The Regents of the University of California.
- * Copyright (c) 1993-1996 Lucent Technologies.
- * Copyright (c) 1994-1998 Sun Microsystems, Inc.
- * Copyright (c) 1998-2000 by Scriptics Corporation.
- * Copyright (c) 2002 by Kevin B. Kenny. All rights reserved.
- *
- * This software is copyrighted by the Regents of the University
- * of California, Sun Microsystems, Inc., Scriptics Corporation,
- * and other parties. The following terms apply to all files
- * associated with the software unless explicitly disclaimed in
- * individual files.
- *
- * The authors hereby grant permission to use, copy, modify,
- * distribute, and license this software and its documentation
- * for any purpose, provided that existing copyright notices are
- * retained in all copies and that this notice is included
- * verbatim in any distributions. No written agreement, license,
- * or royalty fee is required for any of the authorized uses.
- * Modifications to this software may be copyrighted by their
- * authors and need not follow the licensing terms described
- * here, provided that the new terms are clearly indicated on
- * the first page of each file where they apply.
- *
- * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO
- * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
- * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
- * SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN
- * IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON
- * AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO
- * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
- * ENHANCEMENTS, OR MODIFICATIONS.
- *
- * GOVERNMENT USE: If you are acquiring this software on behalf
- * of the U.S. government, the Government shall have only
- * "Restricted Rights" in the software and related documentation
- * as defined in the Federal Acquisition Regulations (FARs) in
- * Clause 52.227.19 (c) (2). If you are acquiring the software
- * on behalf of the Department of Defense, the software shall be
- * classified as "Commercial Computer Software" and the
- * Government shall have only "Restricted Rights" as defined in
- * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the
- * foregoing, the authors grant the U.S. Government and others
- * acting in its behalf permission to use and distribute the
- * software in accordance with the terms specified in this
- * license
- */
-
-/*
- * Unless otherwise noted, these definitions are stable from Tcl / Tk 8.5
- * through Tck / Tk master as of 21 May 2016
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Users of versions of Tcl >= 8.6 encouraged to treat Tcl_Interp as an opaque
- * pointer. The following definition results when TCL_NO_DEPRECATED defined.
- */
-typedef struct Tcl_Interp Tcl_Interp;
-
-/* Tk header excerpts */
-
-typedef void *Tk_PhotoHandle;
-
-typedef struct Tk_PhotoImageBlock
-{
- unsigned char *pixelPtr;
- int width;
- int height;
- int pitch;
- int pixelSize;
- int offset[4];
-} Tk_PhotoImageBlock;
-
-#define TK_PHOTO_COMPOSITE_OVERLAY 0 // apply transparency rules pixel-wise
-#define TK_PHOTO_COMPOSITE_SET 1 // set image buffer directly
-#define TCL_OK 0
-#define TCL_ERROR 1
-
-/* Typedefs derived from function signatures in Tk header */
-/* Tk_FindPhoto typedef */
-typedef Tk_PhotoHandle (*Tk_FindPhoto_t) (Tcl_Interp *interp, const char
- *imageName);
-/* Tk_PhotoPutBLock typedef */
-typedef int (*Tk_PhotoPutBlock_t) (Tcl_Interp *interp, Tk_PhotoHandle handle,
- Tk_PhotoImageBlock *blockPtr, int x, int y,
- int width, int height, int compRule);
-
-/* Typedefs derived from function signatures in Tcl header */
-/* Tcl_SetVar typedef */
-typedef const char *(*Tcl_SetVar_t)(Tcl_Interp *interp, const char *varName,
- const char *newValue, int flags);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/contrib/python/matplotlib/py3/src/_ttconv.cpp b/contrib/python/matplotlib/py3/src/_ttconv.cpp
deleted file mode 100644
index 72fdfba696..0000000000
--- a/contrib/python/matplotlib/py3/src/_ttconv.cpp
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/*
- _ttconv.c
-
- Python wrapper for TrueType conversion library in ../ttconv.
- */
-#include "mplutils.h"
-
-#include <pybind11/pybind11.h>
-#include "ttconv/pprdrv.h"
-#include <vector>
-
-namespace py = pybind11;
-
-/**
- * An implementation of TTStreamWriter that writes to a Python
- * file-like object.
- */
-class PythonFileWriter : public TTStreamWriter
-{
- py::function _write_method;
-
- public:
- PythonFileWriter(py::object& file_object)
- : _write_method(file_object.attr("write")) {}
-
- virtual void write(const char *a)
- {
- PyObject* decoded = PyUnicode_DecodeLatin1(a, strlen(a), "");
- if (decoded == NULL) {
- throw py::error_already_set();
- }
- _write_method(py::handle(decoded));
- Py_DECREF(decoded);
- }
-};
-
-static void convert_ttf_to_ps(
- const char *filename,
- py::object &output,
- int fonttype,
- py::iterable* glyph_ids)
-{
- PythonFileWriter output_(output);
-
- std::vector<int> glyph_ids_;
- if (glyph_ids) {
- for (py::handle glyph_id: *glyph_ids) {
- glyph_ids_.push_back(glyph_id.cast<int>());
- }
- }
-
- if (fonttype != 3 && fonttype != 42) {
- throw py::value_error(
- "fonttype must be either 3 (raw Postscript) or 42 (embedded Truetype)");
- }
-
- try
- {
- insert_ttfont(filename, output_, static_cast<font_type_enum>(fonttype), glyph_ids_);
- }
- catch (TTException &e)
- {
- throw std::runtime_error(e.getMessage());
- }
- catch (...)
- {
- throw std::runtime_error("Unknown C++ exception");
- }
-}
-
-PYBIND11_MODULE(_ttconv, m) {
- m.doc() = "Module to handle converting and subsetting TrueType "
- "fonts to Postscript Type 3, Postscript Type 42 and "
- "Pdf Type 3 fonts.";
- m.def("convert_ttf_to_ps", &convert_ttf_to_ps,
- py::arg("filename"),
- py::arg("output"),
- py::arg("fonttype"),
- py::arg("glyph_ids") = py::none(),
- "Converts the Truetype font into a Type 3 or Type 42 Postscript font, "
- "optionally subsetting the font to only the desired set of characters.\n"
- "\n"
- "filename is the path to a TTF font file.\n"
- "output is a Python file-like object with a write method that the Postscript "
- "font data will be written to.\n"
- "fonttype may be either 3 or 42. Type 3 is a \"raw Postscript\" font. "
- "Type 42 is an embedded Truetype font. Glyph subsetting is not supported "
- "for Type 42 fonts within this module (needs to be done externally).\n"
- "glyph_ids (optional) is a list of glyph ids (integers) to keep when "
- "subsetting to a Type 3 font. If glyph_ids is not provided or is None, "
- "then all glyphs will be included. If any of the glyphs specified are "
- "composite glyphs, then the component glyphs will also be included."
- );
-}
diff --git a/contrib/python/matplotlib/py3/src/agg_workaround.h b/contrib/python/matplotlib/py3/src/agg_workaround.h
deleted file mode 100644
index 4762195192..0000000000
--- a/contrib/python/matplotlib/py3/src/agg_workaround.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef MPL_AGG_WORKAROUND_H
-#define MPL_AGG_WORKAROUND_H
-
-#include "agg_pixfmt_rgba.h"
-
-/**********************************************************************
- WORKAROUND: This class is to workaround a bug in Agg SVN where the
- blending of RGBA32 pixels does not preserve enough precision
-*/
-
-template<class ColorT, class Order>
-struct fixed_blender_rgba_pre : agg::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;
- 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,
- value_type cr, value_type cg, value_type cb,
- value_type alpha, agg::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)
- {
- alpha = base_mask - alpha;
- p[Order::R] = (value_type)(((p[Order::R] * alpha) >> base_shift) + cr);
- p[Order::G] = (value_type)(((p[Order::G] * alpha) >> base_shift) + cg);
- p[Order::B] = (value_type)(((p[Order::B] * alpha) >> base_shift) + cb);
- p[Order::A] = (value_type)(base_mask - ((alpha * (base_mask - p[Order::A])) >> base_shift));
- }
-};
-
-
-template<class ColorT, class Order>
-struct fixed_blender_rgba_plain : agg::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;
- enum base_scale_e { base_shift = color_type::base_shift };
-
- //--------------------------------------------------------------------
- static AGG_INLINE void blend_pix(value_type* p,
- value_type cr, value_type cg, value_type cb, value_type alpha, agg::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 == 0) return;
- calc_type a = p[Order::A];
- calc_type r = p[Order::R] * a;
- calc_type g = p[Order::G] * a;
- calc_type b = p[Order::B] * a;
- a = ((alpha + a) << base_shift) - alpha * a;
- p[Order::A] = (value_type)(a >> base_shift);
- p[Order::R] = (value_type)((((cr << base_shift) - r) * alpha + (r << base_shift)) / a);
- p[Order::G] = (value_type)((((cg << base_shift) - g) * alpha + (g << base_shift)) / a);
- p[Order::B] = (value_type)((((cb << base_shift) - b) * alpha + (b << base_shift)) / a);
- }
-};
-
-#endif
diff --git a/contrib/python/matplotlib/py3/src/array.h b/contrib/python/matplotlib/py3/src/array.h
deleted file mode 100644
index 47d8299554..0000000000
--- a/contrib/python/matplotlib/py3/src/array.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/* Utilities to create scalars and empty arrays that behave like the
- Numpy array wrappers in numpy_cpp.h */
-
-#ifndef MPL_SCALAR_H
-#define MPL_SCALAR_H
-
-namespace array
-{
-
-template <typename T, int ND>
-class scalar
-{
- public:
- T m_value;
-
- scalar(const T value) : m_value(value)
- {
- }
-
- T &operator()(int i, int j = 0, int k = 0)
- {
- return m_value;
- }
-
- const T &operator()(int i, int j = 0, int k = 0) const
- {
- return m_value;
- }
-
- int dim(size_t i)
- {
- return 1;
- }
-
- size_t size()
- {
- return 1;
- }
-};
-
-template <typename T>
-class empty
-{
- public:
- typedef empty<T> sub_t;
-
- empty()
- {
- }
-
- T &operator()(int i, int j = 0, int k = 0)
- {
- throw std::runtime_error("Accessed empty array");
- }
-
- const T &operator()(int i, int j = 0, int k = 0) const
- {
- throw std::runtime_error("Accessed empty array");
- }
-
- sub_t operator[](int i) const
- {
- return empty<T>();
- }
-
- int dim(size_t i) const
- {
- return 0;
- }
-
- size_t size() const
- {
- return 0;
- }
-};
-}
-
-#endif
diff --git a/contrib/python/matplotlib/py3/src/checkdep_freetype2.c b/contrib/python/matplotlib/py3/src/checkdep_freetype2.c
deleted file mode 100644
index 8d9d8ca24a..0000000000
--- a/contrib/python/matplotlib/py3/src/checkdep_freetype2.c
+++ /dev/null
@@ -1,19 +0,0 @@
-#ifdef __has_include
- #if !__has_include(<ft2build.h>)
- #error "FreeType version 2.3 or higher is required. \
-You may unset the system_freetype entry in mplsetup.cfg to let Matplotlib download it."
- #endif
-#endif
-
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
-#define XSTR(x) STR(x)
-#define STR(x) #x
-
-#pragma message("Compiling with FreeType version " \
- XSTR(FREETYPE_MAJOR) "." XSTR(FREETYPE_MINOR) "." XSTR(FREETYPE_PATCH) ".")
-#if FREETYPE_MAJOR << 16 + FREETYPE_MINOR << 8 + FREETYPE_PATCH < 0x020300
- #error "FreeType version 2.3 or higher is required. \
-You may unset the system_freetype entry in mplsetup.cfg to let Matplotlib download it."
-#endif
diff --git a/contrib/python/matplotlib/py3/src/ft2font.cpp b/contrib/python/matplotlib/py3/src/ft2font.cpp
deleted file mode 100644
index 9750413741..0000000000
--- a/contrib/python/matplotlib/py3/src/ft2font.cpp
+++ /dev/null
@@ -1,840 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#define NO_IMPORT_ARRAY
-
-#include <algorithm>
-#include <iterator>
-#include <sstream>
-#include <stdexcept>
-#include <string>
-
-#include "ft2font.h"
-#include "mplutils.h"
-#include "numpy_cpp.h"
-#include "py_exceptions.h"
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846264338328
-#endif
-
-/**
- To improve the hinting of the fonts, this code uses a hack
- presented here:
-
- http://agg.sourceforge.net/antigrain.com/research/font_rasterization/index.html
-
- The idea is to limit the effect of hinting in the x-direction, while
- preserving hinting in the y-direction. Since freetype does not
- support this directly, the dpi in the x-direction is set higher than
- in the y-direction, which affects the hinting grid. Then, a global
- transform is placed on the font to shrink it back to the desired
- size. While it is a bit surprising that the dpi setting affects
- hinting, whereas the global transform does not, this is documented
- behavior of FreeType, and therefore hopefully unlikely to change.
- The FreeType 2 tutorial says:
-
- NOTE: The transformation is applied to every glyph that is
- loaded through FT_Load_Glyph and is completely independent of
- any hinting process. This means that you won't get the same
- results if you load a glyph at the size of 24 pixels, or a glyph
- at the size at 12 pixels scaled by 2 through a transform,
- because the hints will have been computed differently (except
- you have disabled hints).
- */
-
-FT_Library _ft2Library;
-
-// FreeType error codes; loaded as per fterror.h.
-static char const* ft_error_string(FT_Error error) {
-#undef __FTERRORS_H__
-#define FT_ERROR_START_LIST switch (error) {
-#define FT_ERRORDEF( e, v, s ) case v: return s;
-#define FT_ERROR_END_LIST default: return NULL; }
-#include FT_ERRORS_H
-}
-
-void throw_ft_error(std::string message, FT_Error error) {
- char const* s = ft_error_string(error);
- std::ostringstream os("");
- if (s) {
- os << message << " (" << s << "; error code 0x" << std::hex << error << ")";
- } else { // Should not occur, but don't add another error from failed lookup.
- os << message << " (error code 0x" << std::hex << error << ")";
- }
- throw std::runtime_error(os.str());
-}
-
-FT2Image::FT2Image() : m_dirty(true), m_buffer(NULL), m_width(0), m_height(0)
-{
-}
-
-FT2Image::FT2Image(unsigned long width, unsigned long height)
- : m_dirty(true), m_buffer(NULL), m_width(0), m_height(0)
-{
- resize(width, height);
-}
-
-FT2Image::~FT2Image()
-{
- delete[] m_buffer;
-}
-
-void FT2Image::resize(long width, long height)
-{
- if (width <= 0) {
- width = 1;
- }
- if (height <= 0) {
- height = 1;
- }
- size_t numBytes = width * height;
-
- if ((unsigned long)width != m_width || (unsigned long)height != m_height) {
- if (numBytes > m_width * m_height) {
- delete[] m_buffer;
- m_buffer = NULL;
- m_buffer = new unsigned char[numBytes];
- }
-
- m_width = (unsigned long)width;
- m_height = (unsigned long)height;
- }
-
- if (numBytes && m_buffer) {
- memset(m_buffer, 0, numBytes);
- }
-
- m_dirty = true;
-}
-
-void FT2Image::draw_bitmap(FT_Bitmap *bitmap, FT_Int x, FT_Int y)
-{
- FT_Int image_width = (FT_Int)m_width;
- FT_Int image_height = (FT_Int)m_height;
- FT_Int char_width = bitmap->width;
- FT_Int char_height = bitmap->rows;
-
- FT_Int x1 = std::min(std::max(x, 0), image_width);
- FT_Int y1 = std::min(std::max(y, 0), image_height);
- FT_Int x2 = std::min(std::max(x + char_width, 0), image_width);
- FT_Int y2 = std::min(std::max(y + char_height, 0), image_height);
-
- FT_Int x_start = std::max(0, -x);
- FT_Int y_offset = y1 - std::max(0, -y);
-
- if (bitmap->pixel_mode == FT_PIXEL_MODE_GRAY) {
- for (FT_Int i = y1; i < y2; ++i) {
- unsigned char *dst = m_buffer + (i * image_width + x1);
- unsigned char *src = bitmap->buffer + (((i - y_offset) * bitmap->pitch) + x_start);
- for (FT_Int j = x1; j < x2; ++j, ++dst, ++src)
- *dst |= *src;
- }
- } else if (bitmap->pixel_mode == FT_PIXEL_MODE_MONO) {
- for (FT_Int i = y1; i < y2; ++i) {
- unsigned char *dst = m_buffer + (i * image_width + x1);
- unsigned char *src = bitmap->buffer + ((i - y_offset) * bitmap->pitch);
- for (FT_Int j = x1; j < x2; ++j, ++dst) {
- int x = (j - x1 + x_start);
- int val = *(src + (x >> 3)) & (1 << (7 - (x & 0x7)));
- *dst = val ? 255 : *dst;
- }
- }
- } else {
- throw std::runtime_error("Unknown pixel mode");
- }
-
- m_dirty = true;
-}
-
-void FT2Image::draw_rect(unsigned long x0, unsigned long y0, unsigned long x1, unsigned long y1)
-{
- if (x0 > m_width || x1 > m_width || y0 > m_height || y1 > m_height) {
- throw std::runtime_error("Rect coords outside image bounds");
- }
-
- size_t top = y0 * m_width;
- size_t bottom = y1 * m_width;
- for (size_t i = x0; i < x1 + 1; ++i) {
- m_buffer[i + top] = 255;
- m_buffer[i + bottom] = 255;
- }
-
- for (size_t j = y0 + 1; j < y1; ++j) {
- m_buffer[x0 + j * m_width] = 255;
- m_buffer[x1 + j * m_width] = 255;
- }
-
- m_dirty = true;
-}
-
-void
-FT2Image::draw_rect_filled(unsigned long x0, unsigned long y0, unsigned long x1, unsigned long y1)
-{
- x0 = std::min(x0, m_width);
- y0 = std::min(y0, m_height);
- x1 = std::min(x1 + 1, m_width);
- y1 = std::min(y1 + 1, m_height);
-
- for (size_t j = y0; j < y1; j++) {
- for (size_t i = x0; i < x1; i++) {
- m_buffer[i + j * m_width] = 255;
- }
- }
-
- m_dirty = true;
-}
-
-static void ft_glyph_warn(FT_ULong charcode)
-{
- PyObject *text_helpers = NULL, *tmp = NULL;
- if (!(text_helpers = PyImport_ImportModule("matplotlib._text_helpers")) ||
- !(tmp = PyObject_CallMethod(text_helpers, "warn_on_missing_glyph", "k", charcode))) {
- goto exit;
- }
-exit:
- Py_XDECREF(text_helpers);
- Py_XDECREF(tmp);
- if (PyErr_Occurred()) {
- throw py::exception();
- }
-}
-
-static FT_UInt
-ft_get_char_index_or_warn(FT_Face face, FT_ULong charcode, bool warn = true)
-{
- FT_UInt glyph_index = FT_Get_Char_Index(face, charcode);
- if (glyph_index) {
- return glyph_index;
- }
- if (warn) {
- ft_glyph_warn(charcode);
- }
- return 0;
-}
-
-// ft_outline_decomposer should be passed to FT_Outline_Decompose. On the
-// first pass, vertices and codes are set to NULL, and index is simply
-// incremented for each vertex that should be inserted, so that it is set, at
-// the end, to the total number of vertices. On a second pass, vertices and
-// codes should point to correctly sized arrays, and index set again to zero,
-// to get fill vertices and codes with the outline decomposition.
-struct ft_outline_decomposer
-{
- int index;
- double* vertices;
- unsigned char* codes;
-};
-
-static int
-ft_outline_move_to(FT_Vector const* to, void* user)
-{
- ft_outline_decomposer* d = reinterpret_cast<ft_outline_decomposer*>(user);
- if (d->codes) {
- if (d->index) {
- // Appending CLOSEPOLY is important to make patheffects work.
- *(d->vertices++) = 0;
- *(d->vertices++) = 0;
- *(d->codes++) = CLOSEPOLY;
- }
- *(d->vertices++) = to->x * (1. / 64.);
- *(d->vertices++) = to->y * (1. / 64.);
- *(d->codes++) = MOVETO;
- }
- d->index += d->index ? 2 : 1;
- return 0;
-}
-
-static int
-ft_outline_line_to(FT_Vector const* to, void* user)
-{
- ft_outline_decomposer* d = reinterpret_cast<ft_outline_decomposer*>(user);
- if (d->codes) {
- *(d->vertices++) = to->x * (1. / 64.);
- *(d->vertices++) = to->y * (1. / 64.);
- *(d->codes++) = LINETO;
- }
- d->index++;
- return 0;
-}
-
-static int
-ft_outline_conic_to(FT_Vector const* control, FT_Vector const* to, void* user)
-{
- ft_outline_decomposer* d = reinterpret_cast<ft_outline_decomposer*>(user);
- if (d->codes) {
- *(d->vertices++) = control->x * (1. / 64.);
- *(d->vertices++) = control->y * (1. / 64.);
- *(d->vertices++) = to->x * (1. / 64.);
- *(d->vertices++) = to->y * (1. / 64.);
- *(d->codes++) = CURVE3;
- *(d->codes++) = CURVE3;
- }
- d->index += 2;
- return 0;
-}
-
-static int
-ft_outline_cubic_to(
- FT_Vector const* c1, FT_Vector const* c2, FT_Vector const* to, void* user)
-{
- ft_outline_decomposer* d = reinterpret_cast<ft_outline_decomposer*>(user);
- if (d->codes) {
- *(d->vertices++) = c1->x * (1. / 64.);
- *(d->vertices++) = c1->y * (1. / 64.);
- *(d->vertices++) = c2->x * (1. / 64.);
- *(d->vertices++) = c2->y * (1. / 64.);
- *(d->vertices++) = to->x * (1. / 64.);
- *(d->vertices++) = to->y * (1. / 64.);
- *(d->codes++) = CURVE4;
- *(d->codes++) = CURVE4;
- *(d->codes++) = CURVE4;
- }
- d->index += 3;
- return 0;
-}
-
-static FT_Outline_Funcs ft_outline_funcs = {
- ft_outline_move_to,
- ft_outline_line_to,
- ft_outline_conic_to,
- ft_outline_cubic_to};
-
-PyObject*
-FT2Font::get_path()
-{
- if (!face->glyph) {
- PyErr_SetString(PyExc_RuntimeError, "No glyph loaded");
- return NULL;
- }
- ft_outline_decomposer decomposer = {};
- if (FT_Error error =
- FT_Outline_Decompose(
- &face->glyph->outline, &ft_outline_funcs, &decomposer)) {
- PyErr_Format(PyExc_RuntimeError,
- "FT_Outline_Decompose failed with error 0x%x", error);
- return NULL;
- }
- if (!decomposer.index) { // Don't append CLOSEPOLY to null glyphs.
- npy_intp vertices_dims[2] = { 0, 2 };
- numpy::array_view<double, 2> vertices(vertices_dims);
- npy_intp codes_dims[1] = { 0 };
- numpy::array_view<unsigned char, 1> codes(codes_dims);
- return Py_BuildValue("NN", vertices.pyobj(), codes.pyobj());
- }
- npy_intp vertices_dims[2] = { decomposer.index + 1, 2 };
- numpy::array_view<double, 2> vertices(vertices_dims);
- npy_intp codes_dims[1] = { decomposer.index + 1 };
- numpy::array_view<unsigned char, 1> codes(codes_dims);
- decomposer.index = 0;
- decomposer.vertices = vertices.data();
- decomposer.codes = codes.data();
- if (FT_Error error =
- FT_Outline_Decompose(
- &face->glyph->outline, &ft_outline_funcs, &decomposer)) {
- PyErr_Format(PyExc_RuntimeError,
- "FT_Outline_Decompose failed with error 0x%x", error);
- return NULL;
- }
- *(decomposer.vertices++) = 0;
- *(decomposer.vertices++) = 0;
- *(decomposer.codes++) = CLOSEPOLY;
- return Py_BuildValue("NN", vertices.pyobj(), codes.pyobj());
-}
-
-FT2Font::FT2Font(FT_Open_Args &open_args,
- long hinting_factor_,
- std::vector<FT2Font *> &fallback_list)
- : image(), face(NULL)
-{
- clear();
-
- FT_Error error = FT_Open_Face(_ft2Library, &open_args, 0, &face);
- if (error) {
- throw_ft_error("Can not load face", error);
- }
-
- // set default kerning factor to 0, i.e., no kerning manipulation
- kerning_factor = 0;
-
- // set a default fontsize 12 pt at 72dpi
- hinting_factor = hinting_factor_;
-
- error = FT_Set_Char_Size(face, 12 * 64, 0, 72 * (unsigned int)hinting_factor, 72);
- if (error) {
- FT_Done_Face(face);
- throw_ft_error("Could not set the fontsize", error);
- }
-
- if (open_args.stream != NULL) {
- face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
- }
-
- FT_Matrix transform = { 65536 / hinting_factor, 0, 0, 65536 };
- FT_Set_Transform(face, &transform, 0);
-
- // Set fallbacks
- std::copy(fallback_list.begin(), fallback_list.end(), std::back_inserter(fallbacks));
-}
-
-FT2Font::~FT2Font()
-{
- for (size_t i = 0; i < glyphs.size(); i++) {
- FT_Done_Glyph(glyphs[i]);
- }
-
- if (face) {
- FT_Done_Face(face);
- }
-}
-
-void FT2Font::clear()
-{
- pen.x = 0;
- pen.y = 0;
-
- for (size_t i = 0; i < glyphs.size(); i++) {
- FT_Done_Glyph(glyphs[i]);
- }
-
- glyphs.clear();
- glyph_to_font.clear();
- char_to_font.clear();
-
- for (size_t i = 0; i < fallbacks.size(); i++) {
- fallbacks[i]->clear();
- }
-}
-
-void FT2Font::set_size(double ptsize, double dpi)
-{
- FT_Error error = FT_Set_Char_Size(
- face, (FT_F26Dot6)(ptsize * 64), 0, (FT_UInt)(dpi * hinting_factor), (FT_UInt)dpi);
- if (error) {
- throw_ft_error("Could not set the fontsize", error);
- }
- FT_Matrix transform = { 65536 / hinting_factor, 0, 0, 65536 };
- FT_Set_Transform(face, &transform, 0);
-
- for (size_t i = 0; i < fallbacks.size(); i++) {
- fallbacks[i]->set_size(ptsize, dpi);
- }
-}
-
-void FT2Font::set_charmap(int i)
-{
- if (i >= face->num_charmaps) {
- throw std::runtime_error("i exceeds the available number of char maps");
- }
- FT_CharMap charmap = face->charmaps[i];
- if (FT_Error error = FT_Set_Charmap(face, charmap)) {
- throw_ft_error("Could not set the charmap", error);
- }
-}
-
-void FT2Font::select_charmap(unsigned long i)
-{
- if (FT_Error error = FT_Select_Charmap(face, (FT_Encoding)i)) {
- throw_ft_error("Could not set the charmap", error);
- }
-}
-
-int FT2Font::get_kerning(FT_UInt left, FT_UInt right, FT_UInt mode, bool fallback = false)
-{
- if (fallback && glyph_to_font.find(left) != glyph_to_font.end() &&
- glyph_to_font.find(right) != glyph_to_font.end()) {
- FT2Font *left_ft_object = glyph_to_font[left];
- FT2Font *right_ft_object = glyph_to_font[right];
- if (left_ft_object != right_ft_object) {
- // we do not know how to do kerning between different fonts
- return 0;
- }
- // if left_ft_object is the same as right_ft_object,
- // do the exact same thing which set_text does.
- return right_ft_object->get_kerning(left, right, mode, false);
- }
- else
- {
- FT_Vector delta;
- return get_kerning(left, right, mode, delta);
- }
-}
-
-int FT2Font::get_kerning(FT_UInt left, FT_UInt right, FT_UInt mode, FT_Vector &delta)
-{
- if (!FT_HAS_KERNING(face)) {
- return 0;
- }
-
- if (!FT_Get_Kerning(face, left, right, mode, &delta)) {
- return (int)(delta.x) / (hinting_factor << kerning_factor);
- } else {
- return 0;
- }
-}
-
-void FT2Font::set_kerning_factor(int factor)
-{
- kerning_factor = factor;
- for (size_t i = 0; i < fallbacks.size(); i++) {
- fallbacks[i]->set_kerning_factor(factor);
- }
-}
-
-void FT2Font::set_text(
- size_t N, uint32_t *codepoints, double angle, FT_Int32 flags, std::vector<double> &xys)
-{
- FT_Matrix matrix; /* transformation matrix */
-
- angle = angle * (2 * M_PI / 360.0);
-
- // this computes width and height in subpixels so we have to multiply by 64
- double cosangle = cos(angle) * 0x10000L;
- double sinangle = sin(angle) * 0x10000L;
-
- matrix.xx = (FT_Fixed)cosangle;
- matrix.xy = (FT_Fixed)-sinangle;
- matrix.yx = (FT_Fixed)sinangle;
- matrix.yy = (FT_Fixed)cosangle;
-
- clear();
-
- bbox.xMin = bbox.yMin = 32000;
- bbox.xMax = bbox.yMax = -32000;
-
- FT_UInt previous = 0;
- FT2Font *previous_ft_object = NULL;
-
- for (size_t n = 0; n < N; n++) {
- FT_UInt glyph_index = 0;
- FT_BBox glyph_bbox;
- FT_Pos last_advance;
-
- FT_Error charcode_error, glyph_error;
- FT2Font *ft_object_with_glyph = this;
- bool was_found = load_char_with_fallback(ft_object_with_glyph, glyph_index, glyphs,
- char_to_font, glyph_to_font, codepoints[n], flags,
- charcode_error, glyph_error, false);
- if (!was_found) {
- ft_glyph_warn((FT_ULong)codepoints[n]);
-
- // render missing glyph tofu
- // come back to top-most font
- ft_object_with_glyph = this;
- char_to_font[codepoints[n]] = ft_object_with_glyph;
- glyph_to_font[glyph_index] = ft_object_with_glyph;
- ft_object_with_glyph->load_glyph(glyph_index, flags, ft_object_with_glyph, false);
- }
-
- // retrieve kerning distance and move pen position
- if ((ft_object_with_glyph == previous_ft_object) && // if both fonts are the same
- ft_object_with_glyph->has_kerning() && // if the font knows how to kern
- previous && glyph_index // and we really have 2 glyphs
- ) {
- FT_Vector delta;
- pen.x += ft_object_with_glyph->get_kerning(previous, glyph_index, FT_KERNING_DEFAULT, delta);
- }
-
- // extract glyph image and store it in our table
- FT_Glyph &thisGlyph = glyphs[glyphs.size() - 1];
-
- last_advance = ft_object_with_glyph->get_face()->glyph->advance.x;
- FT_Glyph_Transform(thisGlyph, 0, &pen);
- FT_Glyph_Transform(thisGlyph, &matrix, 0);
- xys.push_back(pen.x);
- xys.push_back(pen.y);
-
- FT_Glyph_Get_CBox(thisGlyph, FT_GLYPH_BBOX_SUBPIXELS, &glyph_bbox);
-
- bbox.xMin = std::min(bbox.xMin, glyph_bbox.xMin);
- bbox.xMax = std::max(bbox.xMax, glyph_bbox.xMax);
- bbox.yMin = std::min(bbox.yMin, glyph_bbox.yMin);
- bbox.yMax = std::max(bbox.yMax, glyph_bbox.yMax);
-
- pen.x += last_advance;
-
- previous = glyph_index;
- previous_ft_object = ft_object_with_glyph;
-
- }
-
- FT_Vector_Transform(&pen, &matrix);
- advance = pen.x;
-
- if (bbox.xMin > bbox.xMax) {
- bbox.xMin = bbox.yMin = bbox.xMax = bbox.yMax = 0;
- }
-}
-
-void FT2Font::load_char(long charcode, FT_Int32 flags, FT2Font *&ft_object, bool fallback = false)
-{
- // if this is parent FT2Font, cache will be filled in 2 ways:
- // 1. set_text was previously called
- // 2. set_text was not called and fallback was enabled
- if (fallback && char_to_font.find(charcode) != char_to_font.end()) {
- ft_object = char_to_font[charcode];
- // since it will be assigned to ft_object anyway
- FT2Font *throwaway = NULL;
- ft_object->load_char(charcode, flags, throwaway, false);
- } else if (fallback) {
- FT_UInt final_glyph_index;
- FT_Error charcode_error, glyph_error;
- FT2Font *ft_object_with_glyph = this;
- bool was_found = load_char_with_fallback(ft_object_with_glyph, final_glyph_index, glyphs, char_to_font,
- glyph_to_font, charcode, flags, charcode_error, glyph_error, true);
- if (!was_found) {
- ft_glyph_warn(charcode);
- if (charcode_error) {
- throw_ft_error("Could not load charcode", charcode_error);
- }
- else if (glyph_error) {
- throw_ft_error("Could not load charcode", glyph_error);
- }
- }
- ft_object = ft_object_with_glyph;
- } else {
- ft_object = this;
- FT_UInt glyph_index = ft_get_char_index_or_warn(face, (FT_ULong)charcode);
-
- if (FT_Error error = FT_Load_Glyph(face, glyph_index, flags)) {
- throw_ft_error("Could not load charcode", error);
- }
- FT_Glyph thisGlyph;
- if (FT_Error error = FT_Get_Glyph(face->glyph, &thisGlyph)) {
- throw_ft_error("Could not get glyph", error);
- }
- glyphs.push_back(thisGlyph);
- }
-}
-
-
-bool FT2Font::get_char_fallback_index(FT_ULong charcode, int& index) const
-{
- FT_UInt glyph_index = FT_Get_Char_Index(face, charcode);
- if (glyph_index) {
- // -1 means the host has the char and we do not need to fallback
- index = -1;
- return true;
- } else {
- int inner_index = 0;
- bool was_found;
-
- for (size_t i = 0; i < fallbacks.size(); ++i) {
- // TODO handle recursion somehow!
- was_found = fallbacks[i]->get_char_fallback_index(charcode, inner_index);
- if (was_found) {
- index = i;
- return true;
- }
- }
- }
- return false;
-}
-
-
-bool FT2Font::load_char_with_fallback(FT2Font *&ft_object_with_glyph,
- FT_UInt &final_glyph_index,
- std::vector<FT_Glyph> &parent_glyphs,
- std::unordered_map<long, FT2Font *> &parent_char_to_font,
- std::unordered_map<FT_UInt, FT2Font *> &parent_glyph_to_font,
- long charcode,
- FT_Int32 flags,
- FT_Error &charcode_error,
- FT_Error &glyph_error,
- bool override = false)
-{
- FT_UInt glyph_index = FT_Get_Char_Index(face, charcode);
-
- if (glyph_index || override) {
- charcode_error = FT_Load_Glyph(face, glyph_index, flags);
- if (charcode_error) {
- return false;
- }
-
- FT_Glyph thisGlyph;
- glyph_error = FT_Get_Glyph(face->glyph, &thisGlyph);
- if (glyph_error) {
- return false;
- }
-
- final_glyph_index = glyph_index;
-
- // cache the result for future
- // need to store this for anytime a character is loaded from a parent
- // FT2Font object or to generate a mapping of individual characters to fonts
- ft_object_with_glyph = this;
- parent_glyph_to_font[final_glyph_index] = this;
- parent_char_to_font[charcode] = this;
- parent_glyphs.push_back(thisGlyph);
- return true;
- }
-
- else {
- for (size_t i = 0; i < fallbacks.size(); ++i) {
- bool was_found = fallbacks[i]->load_char_with_fallback(
- ft_object_with_glyph, final_glyph_index, parent_glyphs, parent_char_to_font,
- parent_glyph_to_font, charcode, flags, charcode_error, glyph_error, override);
- if (was_found) {
- return true;
- }
- }
- return false;
- }
-}
-
-void FT2Font::load_glyph(FT_UInt glyph_index,
- FT_Int32 flags,
- FT2Font *&ft_object,
- bool fallback = false)
-{
- // cache is only for parent FT2Font
- if (fallback && glyph_to_font.find(glyph_index) != glyph_to_font.end()) {
- ft_object = glyph_to_font[glyph_index];
- } else {
- ft_object = this;
- }
-
- ft_object->load_glyph(glyph_index, flags);
-}
-
-void FT2Font::load_glyph(FT_UInt glyph_index, FT_Int32 flags)
-{
- if (FT_Error error = FT_Load_Glyph(face, glyph_index, flags)) {
- throw_ft_error("Could not load glyph", error);
- }
- FT_Glyph thisGlyph;
- if (FT_Error error = FT_Get_Glyph(face->glyph, &thisGlyph)) {
- throw_ft_error("Could not get glyph", error);
- }
- glyphs.push_back(thisGlyph);
-}
-
-FT_UInt FT2Font::get_char_index(FT_ULong charcode, bool fallback = false)
-{
- FT2Font *ft_object = NULL;
- if (fallback && char_to_font.find(charcode) != char_to_font.end()) {
- // fallback denotes whether we want to search fallback list.
- // should call set_text/load_char_with_fallback to parent FT2Font before
- // wanting to use fallback list here. (since that populates the cache)
- ft_object = char_to_font[charcode];
- } else {
- // set as self
- ft_object = this;
- }
-
- // historically, get_char_index never raises a warning
- return ft_get_char_index_or_warn(ft_object->get_face(), charcode, false);
-}
-
-void FT2Font::get_width_height(long *width, long *height)
-{
- *width = advance;
- *height = bbox.yMax - bbox.yMin;
-}
-
-long FT2Font::get_descent()
-{
- return -bbox.yMin;
-}
-
-void FT2Font::get_bitmap_offset(long *x, long *y)
-{
- *x = bbox.xMin;
- *y = 0;
-}
-
-void FT2Font::draw_glyphs_to_bitmap(bool antialiased)
-{
- long width = (bbox.xMax - bbox.xMin) / 64 + 2;
- long height = (bbox.yMax - bbox.yMin) / 64 + 2;
-
- image.resize(width, height);
-
- for (size_t n = 0; n < glyphs.size(); n++) {
- FT_Error error = FT_Glyph_To_Bitmap(
- &glyphs[n], antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, 0, 1);
- if (error) {
- throw_ft_error("Could not convert glyph to bitmap", error);
- }
-
- FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyphs[n];
- // now, draw to our target surface (convert position)
-
- // bitmap left and top in pixel, string bbox in subpixel
- FT_Int x = (FT_Int)(bitmap->left - (bbox.xMin * (1. / 64.)));
- FT_Int y = (FT_Int)((bbox.yMax * (1. / 64.)) - bitmap->top + 1);
-
- image.draw_bitmap(&bitmap->bitmap, x, y);
- }
-}
-
-void FT2Font::get_xys(bool antialiased, std::vector<double> &xys)
-{
- for (size_t n = 0; n < glyphs.size(); n++) {
-
- FT_Error error = FT_Glyph_To_Bitmap(
- &glyphs[n], antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, 0, 1);
- if (error) {
- throw_ft_error("Could not convert glyph to bitmap", error);
- }
-
- FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyphs[n];
-
- // bitmap left and top in pixel, string bbox in subpixel
- FT_Int x = (FT_Int)(bitmap->left - bbox.xMin * (1. / 64.));
- FT_Int y = (FT_Int)(bbox.yMax * (1. / 64.) - bitmap->top + 1);
- // make sure the index is non-neg
- x = x < 0 ? 0 : x;
- y = y < 0 ? 0 : y;
- xys.push_back(x);
- xys.push_back(y);
- }
-}
-
-void FT2Font::draw_glyph_to_bitmap(FT2Image &im, int x, int y, size_t glyphInd, bool antialiased)
-{
- FT_Vector sub_offset;
- sub_offset.x = 0; // int((xd - (double)x) * 64.0);
- sub_offset.y = 0; // int((yd - (double)y) * 64.0);
-
- if (glyphInd >= glyphs.size()) {
- throw std::runtime_error("glyph num is out of range");
- }
-
- FT_Error error = FT_Glyph_To_Bitmap(
- &glyphs[glyphInd],
- antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO,
- &sub_offset, // additional translation
- 1 // destroy image
- );
- if (error) {
- throw_ft_error("Could not convert glyph to bitmap", error);
- }
-
- FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyphs[glyphInd];
-
- im.draw_bitmap(&bitmap->bitmap, x + bitmap->left, y);
-}
-
-void FT2Font::get_glyph_name(unsigned int glyph_number, char *buffer, bool fallback = false)
-{
- if (fallback && glyph_to_font.find(glyph_number) != glyph_to_font.end()) {
- // cache is only for parent FT2Font
- FT2Font *ft_object = glyph_to_font[glyph_number];
- ft_object->get_glyph_name(glyph_number, buffer, false);
- return;
- }
- if (!FT_HAS_GLYPH_NAMES(face)) {
- /* Note that this generated name must match the name that
- is generated by ttconv in ttfont_CharStrings_getname. */
- PyOS_snprintf(buffer, 128, "uni%08x", glyph_number);
- } else {
- if (FT_Error error = FT_Get_Glyph_Name(face, glyph_number, buffer, 128)) {
- throw_ft_error("Could not get glyph names", error);
- }
- }
-}
-
-long FT2Font::get_name_index(char *name)
-{
- return FT_Get_Name_Index(face, (FT_String *)name);
-}
diff --git a/contrib/python/matplotlib/py3/src/ft2font.h b/contrib/python/matplotlib/py3/src/ft2font.h
deleted file mode 100644
index d566c3f9bd..0000000000
--- a/contrib/python/matplotlib/py3/src/ft2font.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/* A python interface to FreeType */
-#pragma once
-#ifndef MPL_FT2FONT_H
-#define MPL_FT2FONT_H
-#include <vector>
-#include <stdint.h>
-#include <unordered_map>
-
-extern "C" {
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_GLYPH_H
-#include FT_OUTLINE_H
-#include FT_SFNT_NAMES_H
-#include FT_TYPE1_TABLES_H
-#include FT_TRUETYPE_TABLES_H
-}
-
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-
-/*
- By definition, FT_FIXED as 2 16bit values stored in a single long.
- */
-#define FIXED_MAJOR(val) (signed short)((val & 0xffff0000) >> 16)
-#define FIXED_MINOR(val) (unsigned short)(val & 0xffff)
-
-// the FreeType string rendered into a width, height buffer
-class FT2Image
-{
- public:
- FT2Image();
- FT2Image(unsigned long width, unsigned long height);
- virtual ~FT2Image();
-
- void resize(long width, long height);
- void draw_bitmap(FT_Bitmap *bitmap, FT_Int x, FT_Int y);
- void draw_rect(unsigned long x0, unsigned long y0, unsigned long x1, unsigned long y1);
- void draw_rect_filled(unsigned long x0, unsigned long y0, unsigned long x1, unsigned long y1);
-
- unsigned char *get_buffer()
- {
- return m_buffer;
- }
- unsigned long get_width()
- {
- return m_width;
- }
- unsigned long get_height()
- {
- return m_height;
- }
-
- private:
- bool m_dirty;
- unsigned char *m_buffer;
- unsigned long m_width;
- unsigned long m_height;
-
- // prevent copying
- FT2Image(const FT2Image &);
- FT2Image &operator=(const FT2Image &);
-};
-
-extern FT_Library _ft2Library;
-
-class FT2Font
-{
-
- public:
- FT2Font(FT_Open_Args &open_args, long hinting_factor, std::vector<FT2Font *> &fallback_list);
- virtual ~FT2Font();
- void clear();
- void set_size(double ptsize, double dpi);
- void set_charmap(int i);
- void select_charmap(unsigned long i);
- void set_text(
- size_t N, uint32_t *codepoints, double angle, FT_Int32 flags, std::vector<double> &xys);
- int get_kerning(FT_UInt left, FT_UInt right, FT_UInt mode, bool fallback);
- int get_kerning(FT_UInt left, FT_UInt right, FT_UInt mode, FT_Vector &delta);
- void set_kerning_factor(int factor);
- void load_char(long charcode, FT_Int32 flags, FT2Font *&ft_object, bool fallback);
- bool load_char_with_fallback(FT2Font *&ft_object_with_glyph,
- FT_UInt &final_glyph_index,
- std::vector<FT_Glyph> &parent_glyphs,
- std::unordered_map<long, FT2Font *> &parent_char_to_font,
- std::unordered_map<FT_UInt, FT2Font *> &parent_glyph_to_font,
- long charcode,
- FT_Int32 flags,
- FT_Error &charcode_error,
- FT_Error &glyph_error,
- bool override);
- void load_glyph(FT_UInt glyph_index, FT_Int32 flags, FT2Font *&ft_object, bool fallback);
- void load_glyph(FT_UInt glyph_index, FT_Int32 flags);
- void get_width_height(long *width, long *height);
- void get_bitmap_offset(long *x, long *y);
- long get_descent();
- // TODO: Since we know the size of the array upfront, we probably don't
- // need to dynamically allocate like this
- void get_xys(bool antialiased, std::vector<double> &xys);
- void draw_glyphs_to_bitmap(bool antialiased);
- void draw_glyph_to_bitmap(FT2Image &im, int x, int y, size_t glyphInd, bool antialiased);
- void get_glyph_name(unsigned int glyph_number, char *buffer, bool fallback);
- long get_name_index(char *name);
- FT_UInt get_char_index(FT_ULong charcode, bool fallback);
- PyObject* get_path();
- bool get_char_fallback_index(FT_ULong charcode, int& index) const;
-
- FT_Face const &get_face() const
- {
- return face;
- }
-
- FT2Image &get_image()
- {
- return image;
- }
- FT_Glyph const &get_last_glyph() const
- {
- return glyphs.back();
- }
- size_t get_last_glyph_index() const
- {
- return glyphs.size() - 1;
- }
- size_t get_num_glyphs() const
- {
- return glyphs.size();
- }
- long get_hinting_factor() const
- {
- return hinting_factor;
- }
- FT_Bool has_kerning() const
- {
- return FT_HAS_KERNING(face);
- }
-
- private:
- FT2Image image;
- FT_Face face;
- FT_Vector pen; /* untransformed origin */
- std::vector<FT_Glyph> glyphs;
- std::vector<FT2Font *> fallbacks;
- std::unordered_map<FT_UInt, FT2Font *> glyph_to_font;
- std::unordered_map<long, FT2Font *> char_to_font;
- FT_BBox bbox;
- FT_Pos advance;
- long hinting_factor;
- int kerning_factor;
-
- // prevent copying
- FT2Font(const FT2Font &);
- FT2Font &operator=(const FT2Font &);
-};
-
-#endif
diff --git a/contrib/python/matplotlib/py3/src/ft2font_wrapper.cpp b/contrib/python/matplotlib/py3/src/ft2font_wrapper.cpp
deleted file mode 100644
index 7888a9c212..0000000000
--- a/contrib/python/matplotlib/py3/src/ft2font_wrapper.cpp
+++ /dev/null
@@ -1,1578 +0,0 @@
-#include "mplutils.h"
-#include "ft2font.h"
-#include "py_converters.h"
-#include "py_exceptions.h"
-#include "numpy_cpp.h"
-
-// From Python
-#include <structmember.h>
-
-#include <set>
-#include <algorithm>
-
-#define STRINGIFY(s) XSTRINGIFY(s)
-#define XSTRINGIFY(s) #s
-
-static PyObject *convert_xys_to_array(std::vector<double> &xys)
-{
- npy_intp dims[] = {(npy_intp)xys.size() / 2, 2 };
- if (dims[0] > 0) {
- return PyArray_SimpleNewFromData(2, dims, NPY_DOUBLE, &xys[0]);
- } else {
- return PyArray_SimpleNew(2, dims, NPY_DOUBLE);
- }
-}
-
-/**********************************************************************
- * FT2Image
- * */
-
-typedef struct
-{
- PyObject_HEAD
- FT2Image *x;
- Py_ssize_t shape[2];
- Py_ssize_t strides[2];
- Py_ssize_t suboffsets[2];
-} PyFT2Image;
-
-static PyTypeObject PyFT2ImageType;
-
-static PyObject *PyFT2Image_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyFT2Image *self;
- self = (PyFT2Image *)type->tp_alloc(type, 0);
- self->x = NULL;
- return (PyObject *)self;
-}
-
-static int PyFT2Image_init(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- double width;
- double height;
-
- if (!PyArg_ParseTuple(args, "dd:FT2Image", &width, &height)) {
- return -1;
- }
-
- CALL_CPP_INIT("FT2Image", (self->x = new FT2Image(width, height)));
-
- return 0;
-}
-
-static void PyFT2Image_dealloc(PyFT2Image *self)
-{
- delete self->x;
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-const char *PyFT2Image_draw_rect__doc__ =
- "draw_rect(self, x0, y0, x1, y1)\n"
- "--\n\n"
- "Draw an empty rectangle to the image.\n"
- "\n"
- ".. deprecated:: 3.8\n";
-;
-
-static PyObject *PyFT2Image_draw_rect(PyFT2Image *self, PyObject *args)
-{
- char const* msg =
- "FT2Image.draw_rect is deprecated since Matplotlib 3.8 and will be removed "
- "two minor releases later as it is not used in the library. If you rely on "
- "it, please let us know.";
- if (PyErr_WarnEx(PyExc_DeprecationWarning, msg, 1)) {
- return NULL;
- }
-
- double x0, y0, x1, y1;
-
- if (!PyArg_ParseTuple(args, "dddd:draw_rect", &x0, &y0, &x1, &y1)) {
- return NULL;
- }
-
- CALL_CPP("draw_rect", (self->x->draw_rect(x0, y0, x1, y1)));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Image_draw_rect_filled__doc__ =
- "draw_rect_filled(self, x0, y0, x1, y1)\n"
- "--\n\n"
- "Draw a filled rectangle to the image.\n";
-
-static PyObject *PyFT2Image_draw_rect_filled(PyFT2Image *self, PyObject *args)
-{
- double x0, y0, x1, y1;
-
- if (!PyArg_ParseTuple(args, "dddd:draw_rect_filled", &x0, &y0, &x1, &y1)) {
- return NULL;
- }
-
- CALL_CPP("draw_rect_filled", (self->x->draw_rect_filled(x0, y0, x1, y1)));
-
- Py_RETURN_NONE;
-}
-
-static int PyFT2Image_get_buffer(PyFT2Image *self, Py_buffer *buf, int flags)
-{
- FT2Image *im = self->x;
-
- Py_INCREF(self);
- buf->obj = (PyObject *)self;
- buf->buf = im->get_buffer();
- buf->len = im->get_width() * im->get_height();
- buf->readonly = 0;
- buf->format = (char *)"B";
- buf->ndim = 2;
- self->shape[0] = im->get_height();
- self->shape[1] = im->get_width();
- buf->shape = self->shape;
- self->strides[0] = im->get_width();
- self->strides[1] = 1;
- buf->strides = self->strides;
- buf->suboffsets = NULL;
- buf->itemsize = 1;
- buf->internal = NULL;
-
- return 1;
-}
-
-static PyTypeObject* PyFT2Image_init_type()
-{
- static PyMethodDef methods[] = {
- {"draw_rect", (PyCFunction)PyFT2Image_draw_rect, METH_VARARGS, PyFT2Image_draw_rect__doc__},
- {"draw_rect_filled", (PyCFunction)PyFT2Image_draw_rect_filled, METH_VARARGS, PyFT2Image_draw_rect_filled__doc__},
- {NULL}
- };
-
- static PyBufferProcs buffer_procs;
- buffer_procs.bf_getbuffer = (getbufferproc)PyFT2Image_get_buffer;
-
- PyFT2ImageType.tp_name = "matplotlib.ft2font.FT2Image";
- PyFT2ImageType.tp_basicsize = sizeof(PyFT2Image);
- PyFT2ImageType.tp_dealloc = (destructor)PyFT2Image_dealloc;
- PyFT2ImageType.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
- PyFT2ImageType.tp_methods = methods;
- PyFT2ImageType.tp_new = PyFT2Image_new;
- PyFT2ImageType.tp_init = (initproc)PyFT2Image_init;
- PyFT2ImageType.tp_as_buffer = &buffer_procs;
-
- return &PyFT2ImageType;
-}
-
-/**********************************************************************
- * Glyph
- * */
-
-typedef struct
-{
- PyObject_HEAD
- size_t glyphInd;
- long width;
- long height;
- long horiBearingX;
- long horiBearingY;
- long horiAdvance;
- long linearHoriAdvance;
- long vertBearingX;
- long vertBearingY;
- long vertAdvance;
- FT_BBox bbox;
-} PyGlyph;
-
-static PyTypeObject PyGlyphType;
-
-static PyObject *PyGlyph_from_FT2Font(const FT2Font *font)
-{
- const FT_Face &face = font->get_face();
- const long hinting_factor = font->get_hinting_factor();
- const FT_Glyph &glyph = font->get_last_glyph();
-
- PyGlyph *self;
- self = (PyGlyph *)PyGlyphType.tp_alloc(&PyGlyphType, 0);
-
- self->glyphInd = font->get_last_glyph_index();
- FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_subpixels, &self->bbox);
-
- self->width = face->glyph->metrics.width / hinting_factor;
- self->height = face->glyph->metrics.height;
- self->horiBearingX = face->glyph->metrics.horiBearingX / hinting_factor;
- self->horiBearingY = face->glyph->metrics.horiBearingY;
- self->horiAdvance = face->glyph->metrics.horiAdvance;
- self->linearHoriAdvance = face->glyph->linearHoriAdvance / hinting_factor;
- self->vertBearingX = face->glyph->metrics.vertBearingX;
- self->vertBearingY = face->glyph->metrics.vertBearingY;
- self->vertAdvance = face->glyph->metrics.vertAdvance;
-
- return (PyObject *)self;
-}
-
-static void PyGlyph_dealloc(PyGlyph *self)
-{
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-static PyObject *PyGlyph_get_bbox(PyGlyph *self, void *closure)
-{
- return Py_BuildValue(
- "llll", self->bbox.xMin, self->bbox.yMin, self->bbox.xMax, self->bbox.yMax);
-}
-
-static PyTypeObject *PyGlyph_init_type()
-{
- static PyMemberDef members[] = {
- {(char *)"width", T_LONG, offsetof(PyGlyph, width), READONLY, (char *)""},
- {(char *)"height", T_LONG, offsetof(PyGlyph, height), READONLY, (char *)""},
- {(char *)"horiBearingX", T_LONG, offsetof(PyGlyph, horiBearingX), READONLY, (char *)""},
- {(char *)"horiBearingY", T_LONG, offsetof(PyGlyph, horiBearingY), READONLY, (char *)""},
- {(char *)"horiAdvance", T_LONG, offsetof(PyGlyph, horiAdvance), READONLY, (char *)""},
- {(char *)"linearHoriAdvance", T_LONG, offsetof(PyGlyph, linearHoriAdvance), READONLY, (char *)""},
- {(char *)"vertBearingX", T_LONG, offsetof(PyGlyph, vertBearingX), READONLY, (char *)""},
- {(char *)"vertBearingY", T_LONG, offsetof(PyGlyph, vertBearingY), READONLY, (char *)""},
- {(char *)"vertAdvance", T_LONG, offsetof(PyGlyph, vertAdvance), READONLY, (char *)""},
- {NULL}
- };
-
- static PyGetSetDef getset[] = {
- {(char *)"bbox", (getter)PyGlyph_get_bbox, NULL, NULL, NULL},
- {NULL}
- };
-
- PyGlyphType.tp_name = "matplotlib.ft2font.Glyph";
- PyGlyphType.tp_basicsize = sizeof(PyGlyph);
- PyGlyphType.tp_dealloc = (destructor)PyGlyph_dealloc;
- PyGlyphType.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
- PyGlyphType.tp_members = members;
- PyGlyphType.tp_getset = getset;
-
- return &PyGlyphType;
-}
-
-/**********************************************************************
- * FT2Font
- * */
-
-struct PyFT2Font
-{
- PyObject_HEAD
- FT2Font *x;
- PyObject *py_file;
- FT_StreamRec stream;
- Py_ssize_t shape[2];
- Py_ssize_t strides[2];
- Py_ssize_t suboffsets[2];
- std::vector<PyObject *> fallbacks;
-};
-
-static PyTypeObject PyFT2FontType;
-
-static unsigned long read_from_file_callback(FT_Stream stream,
- unsigned long offset,
- unsigned char *buffer,
- unsigned long count)
-{
- PyObject *py_file = ((PyFT2Font *)stream->descriptor.pointer)->py_file;
- PyObject *seek_result = NULL, *read_result = NULL;
- Py_ssize_t n_read = 0;
- if (!(seek_result = PyObject_CallMethod(py_file, "seek", "k", offset))
- || !(read_result = PyObject_CallMethod(py_file, "read", "k", count))) {
- goto exit;
- }
- char *tmpbuf;
- if (PyBytes_AsStringAndSize(read_result, &tmpbuf, &n_read) == -1) {
- goto exit;
- }
- memcpy(buffer, tmpbuf, n_read);
-exit:
- Py_XDECREF(seek_result);
- Py_XDECREF(read_result);
- if (PyErr_Occurred()) {
- PyErr_WriteUnraisable(py_file);
- if (!count) {
- return 1; // Non-zero signals error, when count == 0.
- }
- }
- return (unsigned long)n_read;
-}
-
-static void close_file_callback(FT_Stream stream)
-{
- PyObject *type, *value, *traceback;
- PyErr_Fetch(&type, &value, &traceback);
- PyFT2Font *self = (PyFT2Font *)stream->descriptor.pointer;
- PyObject *close_result = NULL;
- if (!(close_result = PyObject_CallMethod(self->py_file, "close", ""))) {
- goto exit;
- }
-exit:
- Py_XDECREF(close_result);
- Py_CLEAR(self->py_file);
- if (PyErr_Occurred()) {
- PyErr_WriteUnraisable((PyObject*)self);
- }
- PyErr_Restore(type, value, traceback);
-}
-
-static PyObject *PyFT2Font_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyFT2Font *self;
- self = (PyFT2Font *)type->tp_alloc(type, 0);
- self->x = NULL;
- self->py_file = NULL;
- memset(&self->stream, 0, sizeof(FT_StreamRec));
- return (PyObject *)self;
-}
-
-const char *PyFT2Font_init__doc__ =
- "FT2Font(filename, hinting_factor=8, *, _fallback_list=None, _kerning_factor=0)\n"
- "--\n\n"
- "Create a new FT2Font object.\n"
- "\n"
- "Parameters\n"
- "----------\n"
- "filename : str or file-like\n"
- " The source of the font data in a format (ttf or ttc) that FreeType can read\n"
- "\n"
- "hinting_factor : int, optional\n"
- " Must be positive. Used to scale the hinting in the x-direction\n"
- "_fallback_list : list of FT2Font, optional\n"
- " A list of FT2Font objects used to find missing glyphs.\n"
- "\n"
- " .. warning::\n"
- " This API is both private and provisional: do not use it directly\n"
- "\n"
- "_kerning_factor : int, optional\n"
- " Used to adjust the degree of kerning.\n"
- "\n"
- " .. warning::\n"
- " This API is private: do not use it directly\n"
- "\n"
- "Attributes\n"
- "----------\n"
- "num_faces : int\n"
- " Number of faces in file.\n"
- "face_flags, style_flags : int\n"
- " Face and style flags; see the ft2font constants.\n"
- "num_glyphs : int\n"
- " Number of glyphs in the face.\n"
- "family_name, style_name : str\n"
- " Face family and style name.\n"
- "num_fixed_sizes : int\n"
- " Number of bitmap in the face.\n"
- "scalable : bool\n"
- " Whether face is scalable; attributes after this one are only\n"
- " defined for scalable faces.\n"
- "bbox : tuple[int, int, int, int]\n"
- " Face global bounding box (xmin, ymin, xmax, ymax).\n"
- "units_per_EM : int\n"
- " Number of font units covered by the EM.\n"
- "ascender, descender : int\n"
- " Ascender and descender in 26.6 units.\n"
- "height : int\n"
- " Height in 26.6 units; used to compute a default line spacing\n"
- " (baseline-to-baseline distance).\n"
- "max_advance_width, max_advance_height : int\n"
- " Maximum horizontal and vertical cursor advance for all glyphs.\n"
- "underline_position, underline_thickness : int\n"
- " Vertical position and thickness of the underline bar.\n"
- "postscript_name : str\n"
- " PostScript name of the font.\n";
-
-static int PyFT2Font_init(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- PyObject *filename = NULL, *open = NULL, *data = NULL, *fallback_list = NULL;
- FT_Open_Args open_args;
- long hinting_factor = 8;
- int kerning_factor = 0;
- const char *names[] = {
- "filename", "hinting_factor", "_fallback_list", "_kerning_factor", NULL
- };
- std::vector<FT2Font *> fallback_fonts;
- if (!PyArg_ParseTupleAndKeywords(
- args, kwds, "O|l$Oi:FT2Font", (char **)names, &filename,
- &hinting_factor, &fallback_list, &kerning_factor)) {
- return -1;
- }
- if (hinting_factor <= 0) {
- PyErr_SetString(PyExc_ValueError,
- "hinting_factor must be greater than 0");
- goto exit;
- }
-
- self->stream.base = NULL;
- self->stream.size = 0x7fffffff; // Unknown size.
- self->stream.pos = 0;
- self->stream.descriptor.pointer = self;
- self->stream.read = &read_from_file_callback;
- memset((void *)&open_args, 0, sizeof(FT_Open_Args));
- open_args.flags = FT_OPEN_STREAM;
- open_args.stream = &self->stream;
-
- if (fallback_list) {
- if (!PyList_Check(fallback_list)) {
- PyErr_SetString(PyExc_TypeError, "Fallback list must be a list");
- goto exit;
- }
- Py_ssize_t size = PyList_Size(fallback_list);
-
- // go through fallbacks once to make sure the types are right
- for (Py_ssize_t i = 0; i < size; ++i) {
- // this returns a borrowed reference
- PyObject* item = PyList_GetItem(fallback_list, i);
- if (!PyObject_IsInstance(item, PyObject_Type(reinterpret_cast<PyObject *>(self)))) {
- PyErr_SetString(PyExc_TypeError, "Fallback fonts must be FT2Font objects.");
- goto exit;
- }
- }
- // go through a second time to add them to our lists
- for (Py_ssize_t i = 0; i < size; ++i) {
- // this returns a borrowed reference
- PyObject* item = PyList_GetItem(fallback_list, i);
- // Increase the ref count, we will undo this in dealloc this makes
- // sure things do not get gc'd under us!
- Py_INCREF(item);
- self->fallbacks.push_back(item);
- // Also (locally) cache the underlying FT2Font objects. As long as
- // the Python objects are kept alive, these pointer are good.
- FT2Font *fback = reinterpret_cast<PyFT2Font *>(item)->x;
- fallback_fonts.push_back(fback);
- }
- }
-
- if (PyBytes_Check(filename) || PyUnicode_Check(filename)) {
- if (!(open = PyDict_GetItemString(PyEval_GetBuiltins(), "open")) // Borrowed reference.
- || !(self->py_file = PyObject_CallFunction(open, "Os", filename, "rb"))) {
- goto exit;
- }
- self->stream.close = &close_file_callback;
- } else if (!PyObject_HasAttrString(filename, "read")
- || !(data = PyObject_CallMethod(filename, "read", "i", 0))
- || !PyBytes_Check(data)) {
- PyErr_SetString(PyExc_TypeError,
- "First argument must be a path to a font file or a binary-mode file object");
- Py_CLEAR(data);
- goto exit;
- } else {
- self->py_file = filename;
- self->stream.close = NULL;
- Py_INCREF(filename);
- }
- Py_CLEAR(data);
-
- CALL_CPP_FULL(
- "FT2Font", (self->x = new FT2Font(open_args, hinting_factor, fallback_fonts)),
- Py_CLEAR(self->py_file), -1);
-
- CALL_CPP_INIT("FT2Font->set_kerning_factor", (self->x->set_kerning_factor(kerning_factor)));
-
-exit:
- return PyErr_Occurred() ? -1 : 0;
-}
-
-static void PyFT2Font_dealloc(PyFT2Font *self)
-{
- delete self->x;
- for (size_t i = 0; i < self->fallbacks.size(); i++) {
- Py_DECREF(self->fallbacks[i]);
- }
-
- Py_XDECREF(self->py_file);
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-const char *PyFT2Font_clear__doc__ =
- "clear(self)\n"
- "--\n\n"
- "Clear all the glyphs, reset for a new call to `.set_text`.\n";
-
-static PyObject *PyFT2Font_clear(PyFT2Font *self, PyObject *args)
-{
- CALL_CPP("clear", (self->x->clear()));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_set_size__doc__ =
- "set_size(self, ptsize, dpi)\n"
- "--\n\n"
- "Set the point size and dpi of the text.\n";
-
-static PyObject *PyFT2Font_set_size(PyFT2Font *self, PyObject *args)
-{
- double ptsize;
- double dpi;
-
- if (!PyArg_ParseTuple(args, "dd:set_size", &ptsize, &dpi)) {
- return NULL;
- }
-
- CALL_CPP("set_size", (self->x->set_size(ptsize, dpi)));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_set_charmap__doc__ =
- "set_charmap(self, i)\n"
- "--\n\n"
- "Make the i-th charmap current.\n";
-
-static PyObject *PyFT2Font_set_charmap(PyFT2Font *self, PyObject *args)
-{
- int i;
-
- if (!PyArg_ParseTuple(args, "i:set_charmap", &i)) {
- return NULL;
- }
-
- CALL_CPP("set_charmap", (self->x->set_charmap(i)));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_select_charmap__doc__ =
- "select_charmap(self, i)\n"
- "--\n\n"
- "Select a charmap by its FT_Encoding number.\n";
-
-static PyObject *PyFT2Font_select_charmap(PyFT2Font *self, PyObject *args)
-{
- unsigned long i;
-
- if (!PyArg_ParseTuple(args, "k:select_charmap", &i)) {
- return NULL;
- }
-
- CALL_CPP("select_charmap", self->x->select_charmap(i));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_get_kerning__doc__ =
- "get_kerning(self, left, right, mode)\n"
- "--\n\n"
- "Get the kerning between *left* and *right* glyph indices.\n"
- "*mode* is a kerning mode constant:\n\n"
- "- KERNING_DEFAULT - Return scaled and grid-fitted kerning distances\n"
- "- KERNING_UNFITTED - Return scaled but un-grid-fitted kerning distances\n"
- "- KERNING_UNSCALED - Return the kerning vector in original font units\n";
-
-static PyObject *PyFT2Font_get_kerning(PyFT2Font *self, PyObject *args)
-{
- FT_UInt left, right, mode;
- int result;
- int fallback = 1;
-
- if (!PyArg_ParseTuple(args, "III:get_kerning", &left, &right, &mode)) {
- return NULL;
- }
-
- CALL_CPP("get_kerning", (result = self->x->get_kerning(left, right, mode, (bool)fallback)));
-
- return PyLong_FromLong(result);
-}
-
-const char *PyFT2Font_get_fontmap__doc__ =
- "_get_fontmap(self, string)\n"
- "--\n\n"
- "Get a mapping between characters and the font that includes them.\n"
- "A dictionary mapping unicode characters to PyFT2Font objects.";
-static PyObject *PyFT2Font_get_fontmap(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- PyObject *textobj;
- const char *names[] = { "string", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kwds, "O:_get_fontmap", (char **)names, &textobj)) {
- return NULL;
- }
-
- std::set<FT_ULong> codepoints;
- size_t size;
-
- if (PyUnicode_Check(textobj)) {
- size = PyUnicode_GET_LENGTH(textobj);
- for (size_t i = 0; i < size; ++i) {
- codepoints.insert(PyUnicode_ReadChar(textobj, i));
- }
- } else {
- PyErr_SetString(PyExc_TypeError, "string must be str");
- return NULL;
- }
- PyObject *char_to_font;
- if (!(char_to_font = PyDict_New())) {
- return NULL;
- }
- for (auto it = codepoints.begin(); it != codepoints.end(); ++it) {
- auto x = *it;
- PyObject* target_font;
- int index;
- if (self->x->get_char_fallback_index(x, index)) {
- if (index >= 0) {
- target_font = self->fallbacks[index];
- } else {
- target_font = (PyObject *)self;
- }
- } else {
- // TODO Handle recursion!
- target_font = (PyObject *)self;
- }
-
- PyObject *key = NULL;
- bool error = (!(key = PyUnicode_FromFormat("%c", x))
- || (PyDict_SetItem(char_to_font, key, target_font) == -1));
- Py_XDECREF(key);
- if (error) {
- Py_DECREF(char_to_font);
- PyErr_SetString(PyExc_ValueError, "Something went very wrong");
- return NULL;
- }
- }
- return char_to_font;
-}
-
-
-const char *PyFT2Font_set_text__doc__ =
- "set_text(self, string, angle=0.0, flags=32)\n"
- "--\n\n"
- "Set the text *string* and *angle*.\n"
- "*flags* can be a bitwise-or of the LOAD_XXX constants;\n"
- "the default value is LOAD_FORCE_AUTOHINT.\n"
- "You must call this before `.draw_glyphs_to_bitmap`.\n"
- "A sequence of x,y positions is returned.\n";
-
-static PyObject *PyFT2Font_set_text(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- PyObject *textobj;
- double angle = 0.0;
- FT_Int32 flags = FT_LOAD_FORCE_AUTOHINT;
- std::vector<double> xys;
- const char *names[] = { "string", "angle", "flags", NULL };
-
- /* This makes a technically incorrect assumption that FT_Int32 is
- int. In theory it can also be long, if the size of int is less
- than 32 bits. This is very unlikely on modern platforms. */
- if (!PyArg_ParseTupleAndKeywords(
- args, kwds, "O|di:set_text", (char **)names, &textobj, &angle, &flags)) {
- return NULL;
- }
-
- std::vector<uint32_t> codepoints;
- size_t size;
-
- if (PyUnicode_Check(textobj)) {
- size = PyUnicode_GET_LENGTH(textobj);
- codepoints.resize(size);
- for (size_t i = 0; i < size; ++i) {
- codepoints[i] = PyUnicode_ReadChar(textobj, i);
- }
- } else {
- PyErr_SetString(PyExc_TypeError, "set_text requires str-input.");
- return NULL;
- }
-
- uint32_t* codepoints_array = NULL;
- if (size > 0) {
- codepoints_array = &codepoints[0];
- }
- CALL_CPP("set_text", self->x->set_text(size, codepoints_array, angle, flags, xys));
-
- return convert_xys_to_array(xys);
-}
-
-const char *PyFT2Font_get_num_glyphs__doc__ =
- "get_num_glyphs(self)\n"
- "--\n\n"
- "Return the number of loaded glyphs.\n";
-
-static PyObject *PyFT2Font_get_num_glyphs(PyFT2Font *self, PyObject *args)
-{
- return PyLong_FromSize_t(self->x->get_num_glyphs());
-}
-
-const char *PyFT2Font_load_char__doc__ =
- "load_char(self, charcode, flags=32)\n"
- "--\n\n"
- "Load character with *charcode* in current fontfile and set glyph.\n"
- "*flags* can be a bitwise-or of the LOAD_XXX constants;\n"
- "the default value is LOAD_FORCE_AUTOHINT.\n"
- "Return value is a Glyph object, with attributes\n\n"
- "- width: glyph width\n"
- "- height: glyph height\n"
- "- bbox: the glyph bbox (xmin, ymin, xmax, ymax)\n"
- "- horiBearingX: left side bearing in horizontal layouts\n"
- "- horiBearingY: top side bearing in horizontal layouts\n"
- "- horiAdvance: advance width for horizontal layout\n"
- "- vertBearingX: left side bearing in vertical layouts\n"
- "- vertBearingY: top side bearing in vertical layouts\n"
- "- vertAdvance: advance height for vertical layout\n";
-
-static PyObject *PyFT2Font_load_char(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- long charcode;
- int fallback = 1;
- FT_Int32 flags = FT_LOAD_FORCE_AUTOHINT;
- const char *names[] = { "charcode", "flags", NULL };
-
- /* This makes a technically incorrect assumption that FT_Int32 is
- int. In theory it can also be long, if the size of int is less
- than 32 bits. This is very unlikely on modern platforms. */
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "l|i:load_char", (char **)names, &charcode,
- &flags)) {
- return NULL;
- }
-
- FT2Font *ft_object = NULL;
- CALL_CPP("load_char", (self->x->load_char(charcode, flags, ft_object, (bool)fallback)));
-
- return PyGlyph_from_FT2Font(ft_object);
-}
-
-const char *PyFT2Font_load_glyph__doc__ =
- "load_glyph(self, glyphindex, flags=32)\n"
- "--\n\n"
- "Load character with *glyphindex* in current fontfile and set glyph.\n"
- "*flags* can be a bitwise-or of the LOAD_XXX constants;\n"
- "the default value is LOAD_FORCE_AUTOHINT.\n"
- "Return value is a Glyph object, with attributes\n\n"
- "- width: glyph width\n"
- "- height: glyph height\n"
- "- bbox: the glyph bbox (xmin, ymin, xmax, ymax)\n"
- "- horiBearingX: left side bearing in horizontal layouts\n"
- "- horiBearingY: top side bearing in horizontal layouts\n"
- "- horiAdvance: advance width for horizontal layout\n"
- "- vertBearingX: left side bearing in vertical layouts\n"
- "- vertBearingY: top side bearing in vertical layouts\n"
- "- vertAdvance: advance height for vertical layout\n";
-
-static PyObject *PyFT2Font_load_glyph(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- FT_UInt glyph_index;
- FT_Int32 flags = FT_LOAD_FORCE_AUTOHINT;
- int fallback = 1;
- const char *names[] = { "glyph_index", "flags", NULL };
-
- /* This makes a technically incorrect assumption that FT_Int32 is
- int. In theory it can also be long, if the size of int is less
- than 32 bits. This is very unlikely on modern platforms. */
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "I|i:load_glyph", (char **)names, &glyph_index,
- &flags)) {
- return NULL;
- }
-
- FT2Font *ft_object = NULL;
- CALL_CPP("load_glyph", (self->x->load_glyph(glyph_index, flags, ft_object, (bool)fallback)));
-
- return PyGlyph_from_FT2Font(ft_object);
-}
-
-const char *PyFT2Font_get_width_height__doc__ =
- "get_width_height(self)\n"
- "--\n\n"
- "Get the width and height in 26.6 subpixels of the current string set by `.set_text`.\n"
- "The rotation of the string is accounted for. To get width and height\n"
- "in pixels, divide these values by 64.\n";
-
-static PyObject *PyFT2Font_get_width_height(PyFT2Font *self, PyObject *args)
-{
- long width, height;
-
- CALL_CPP("get_width_height", (self->x->get_width_height(&width, &height)));
-
- return Py_BuildValue("ll", width, height);
-}
-
-const char *PyFT2Font_get_bitmap_offset__doc__ =
- "get_bitmap_offset(self)\n"
- "--\n\n"
- "Get the (x, y) offset in 26.6 subpixels for the bitmap if ink hangs left or below (0, 0).\n"
- "Since Matplotlib only supports left-to-right text, y is always 0.\n";
-
-static PyObject *PyFT2Font_get_bitmap_offset(PyFT2Font *self, PyObject *args)
-{
- long x, y;
-
- CALL_CPP("get_bitmap_offset", (self->x->get_bitmap_offset(&x, &y)));
-
- return Py_BuildValue("ll", x, y);
-}
-
-const char *PyFT2Font_get_descent__doc__ =
- "get_descent(self)\n"
- "--\n\n"
- "Get the descent in 26.6 subpixels of the current string set by `.set_text`.\n"
- "The rotation of the string is accounted for. To get the descent\n"
- "in pixels, divide this value by 64.\n";
-
-static PyObject *PyFT2Font_get_descent(PyFT2Font *self, PyObject *args)
-{
- long descent;
-
- CALL_CPP("get_descent", (descent = self->x->get_descent()));
-
- return PyLong_FromLong(descent);
-}
-
-const char *PyFT2Font_draw_glyphs_to_bitmap__doc__ =
- "draw_glyphs_to_bitmap(self, antialiased=True)\n"
- "--\n\n"
- "Draw the glyphs that were loaded by `.set_text` to the bitmap.\n"
- "The bitmap size will be automatically set to include the glyphs.\n";
-
-static PyObject *PyFT2Font_draw_glyphs_to_bitmap(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- bool antialiased = true;
- const char *names[] = { "antialiased", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&:draw_glyphs_to_bitmap",
- (char **)names, &convert_bool, &antialiased)) {
- return NULL;
- }
-
- CALL_CPP("draw_glyphs_to_bitmap", (self->x->draw_glyphs_to_bitmap(antialiased)));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_get_xys__doc__ =
- "get_xys(self, antialiased=True)\n"
- "--\n\n"
- "Get the xy locations of the current glyphs.\n"
- "\n"
- ".. deprecated:: 3.8\n";
-
-static PyObject *PyFT2Font_get_xys(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- char const* msg =
- "FT2Font.get_xys is deprecated since Matplotlib 3.8 and will be removed two "
- "minor releases later as it is not used in the library. If you rely on it, "
- "please let us know.";
- if (PyErr_WarnEx(PyExc_DeprecationWarning, msg, 1)) {
- return NULL;
- }
-
- bool antialiased = true;
- std::vector<double> xys;
- const char *names[] = { "antialiased", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&:get_xys",
- (char **)names, &convert_bool, &antialiased)) {
- return NULL;
- }
-
- CALL_CPP("get_xys", (self->x->get_xys(antialiased, xys)));
-
- return convert_xys_to_array(xys);
-}
-
-const char *PyFT2Font_draw_glyph_to_bitmap__doc__ =
- "draw_glyph_to_bitmap(self, image, x, y, glyph, antialiased=True)\n"
- "--\n\n"
- "Draw a single glyph to the bitmap at pixel locations x, y\n"
- "Note it is your responsibility to set up the bitmap manually\n"
- "with ``set_bitmap_size(w, h)`` before this call is made.\n"
- "\n"
- "If you want automatic layout, use `.set_text` in combinations with\n"
- "`.draw_glyphs_to_bitmap`. This function is instead intended for people\n"
- "who want to render individual glyphs (e.g., returned by `.load_char`)\n"
- "at precise locations.\n";
-
-static PyObject *PyFT2Font_draw_glyph_to_bitmap(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- PyFT2Image *image;
- double xd, yd;
- PyGlyph *glyph;
- bool antialiased = true;
- const char *names[] = { "image", "x", "y", "glyph", "antialiased", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O!ddO!|O&:draw_glyph_to_bitmap",
- (char **)names,
- &PyFT2ImageType,
- &image,
- &xd,
- &yd,
- &PyGlyphType,
- &glyph,
- &convert_bool,
- &antialiased)) {
- return NULL;
- }
-
- CALL_CPP("draw_glyph_to_bitmap",
- self->x->draw_glyph_to_bitmap(*(image->x), xd, yd, glyph->glyphInd, antialiased));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_get_glyph_name__doc__ =
- "get_glyph_name(self, index)\n"
- "--\n\n"
- "Retrieve the ASCII name of a given glyph *index* in a face.\n"
- "\n"
- "Due to Matplotlib's internal design, for fonts that do not contain glyph\n"
- "names (per FT_FACE_FLAG_GLYPH_NAMES), this returns a made-up name which\n"
- "does *not* roundtrip through `.get_name_index`.\n";
-
-static PyObject *PyFT2Font_get_glyph_name(PyFT2Font *self, PyObject *args)
-{
- unsigned int glyph_number;
- char buffer[128];
- int fallback = 1;
-
- if (!PyArg_ParseTuple(args, "I:get_glyph_name", &glyph_number)) {
- return NULL;
- }
- CALL_CPP("get_glyph_name", (self->x->get_glyph_name(glyph_number, buffer, (bool)fallback)));
- return PyUnicode_FromString(buffer);
-}
-
-const char *PyFT2Font_get_charmap__doc__ =
- "get_charmap(self)\n"
- "--\n\n"
- "Return a dict that maps the character codes of the selected charmap\n"
- "(Unicode by default) to their corresponding glyph indices.\n";
-
-static PyObject *PyFT2Font_get_charmap(PyFT2Font *self, PyObject *args)
-{
- PyObject *charmap;
- if (!(charmap = PyDict_New())) {
- return NULL;
- }
- FT_UInt index;
- FT_ULong code = FT_Get_First_Char(self->x->get_face(), &index);
- while (index != 0) {
- PyObject *key = NULL, *val = NULL;
- bool error = (!(key = PyLong_FromLong(code))
- || !(val = PyLong_FromLong(index))
- || (PyDict_SetItem(charmap, key, val) == -1));
- Py_XDECREF(key);
- Py_XDECREF(val);
- if (error) {
- Py_DECREF(charmap);
- return NULL;
- }
- code = FT_Get_Next_Char(self->x->get_face(), code, &index);
- }
- return charmap;
-}
-
-
-const char *PyFT2Font_get_char_index__doc__ =
- "get_char_index(self, codepoint)\n"
- "--\n\n"
- "Return the glyph index corresponding to a character *codepoint*.\n";
-
-static PyObject *PyFT2Font_get_char_index(PyFT2Font *self, PyObject *args)
-{
- FT_UInt index;
- FT_ULong ccode;
- int fallback = 1;
-
- if (!PyArg_ParseTuple(args, "k:get_char_index", &ccode)) {
- return NULL;
- }
-
- CALL_CPP("get_char_index", index = self->x->get_char_index(ccode, (bool)fallback));
-
- return PyLong_FromLong(index);
-}
-
-
-const char *PyFT2Font_get_sfnt__doc__ =
- "get_sfnt(self)\n"
- "--\n\n"
- "Load the entire SFNT names table, as a dict whose keys are\n"
- "(platform-ID, ISO-encoding-scheme, language-code, and description)\n"
- "tuples.\n";
-
-static PyObject *PyFT2Font_get_sfnt(PyFT2Font *self, PyObject *args)
-{
- PyObject *names;
-
- if (!(self->x->get_face()->face_flags & FT_FACE_FLAG_SFNT)) {
- PyErr_SetString(PyExc_ValueError, "No SFNT name table");
- return NULL;
- }
-
- size_t count = FT_Get_Sfnt_Name_Count(self->x->get_face());
-
- names = PyDict_New();
- if (names == NULL) {
- return NULL;
- }
-
- for (FT_UInt j = 0; j < count; ++j) {
- FT_SfntName sfnt;
- FT_Error error = FT_Get_Sfnt_Name(self->x->get_face(), j, &sfnt);
-
- if (error) {
- Py_DECREF(names);
- PyErr_SetString(PyExc_ValueError, "Could not get SFNT name");
- return NULL;
- }
-
- PyObject *key = Py_BuildValue(
- "HHHH", sfnt.platform_id, sfnt.encoding_id, sfnt.language_id, sfnt.name_id);
- if (key == NULL) {
- Py_DECREF(names);
- return NULL;
- }
-
- PyObject *val = PyBytes_FromStringAndSize((const char *)sfnt.string, sfnt.string_len);
- if (val == NULL) {
- Py_DECREF(key);
- Py_DECREF(names);
- return NULL;
- }
-
- if (PyDict_SetItem(names, key, val)) {
- Py_DECREF(key);
- Py_DECREF(val);
- Py_DECREF(names);
- return NULL;
- }
-
- Py_DECREF(key);
- Py_DECREF(val);
- }
-
- return names;
-}
-
-const char *PyFT2Font_get_name_index__doc__ =
- "get_name_index(self, name)\n"
- "--\n\n"
- "Return the glyph index of a given glyph *name*.\n"
- "The glyph index 0 means 'undefined character code'.\n";
-
-static PyObject *PyFT2Font_get_name_index(PyFT2Font *self, PyObject *args)
-{
- char *glyphname;
- long name_index;
- if (!PyArg_ParseTuple(args, "s:get_name_index", &glyphname)) {
- return NULL;
- }
- CALL_CPP("get_name_index", name_index = self->x->get_name_index(glyphname));
- return PyLong_FromLong(name_index);
-}
-
-const char *PyFT2Font_get_ps_font_info__doc__ =
- "get_ps_font_info(self)\n"
- "--\n\n"
- "Return the information in the PS Font Info structure.\n";
-
-static PyObject *PyFT2Font_get_ps_font_info(PyFT2Font *self, PyObject *args)
-{
- PS_FontInfoRec fontinfo;
-
- FT_Error error = FT_Get_PS_Font_Info(self->x->get_face(), &fontinfo);
- if (error) {
- PyErr_SetString(PyExc_ValueError, "Could not get PS font info");
- return NULL;
- }
-
- return Py_BuildValue("ssssslbhH",
- fontinfo.version ? fontinfo.version : "",
- fontinfo.notice ? fontinfo.notice : "",
- fontinfo.full_name ? fontinfo.full_name : "",
- fontinfo.family_name ? fontinfo.family_name : "",
- fontinfo.weight ? fontinfo.weight : "",
- fontinfo.italic_angle,
- fontinfo.is_fixed_pitch,
- fontinfo.underline_position,
- fontinfo.underline_thickness);
-}
-
-const char *PyFT2Font_get_sfnt_table__doc__ =
- "get_sfnt_table(self, name)\n"
- "--\n\n"
- "Return one of the following SFNT tables: head, maxp, OS/2, hhea, "
- "vhea, post, or pclt.\n";
-
-static PyObject *PyFT2Font_get_sfnt_table(PyFT2Font *self, PyObject *args)
-{
- char *tagname;
- if (!PyArg_ParseTuple(args, "s:get_sfnt_table", &tagname)) {
- return NULL;
- }
-
- int tag;
- const char *tags[] = { "head", "maxp", "OS/2", "hhea", "vhea", "post", "pclt", NULL };
-
- for (tag = 0; tags[tag] != NULL; tag++) {
- if (strncmp(tagname, tags[tag], 5) == 0) {
- break;
- }
- }
-
- void *table = FT_Get_Sfnt_Table(self->x->get_face(), (FT_Sfnt_Tag)tag);
- if (!table) {
- Py_RETURN_NONE;
- }
-
- switch (tag) {
- case 0: {
- char head_dict[] =
- "{s:(h,H), s:(h,H), s:l, s:l, s:H, s:H,"
- "s:(l,l), s:(l,l), s:h, s:h, s:h, s:h, s:H, s:H, s:h, s:h, s:h}";
- TT_Header *t = (TT_Header *)table;
- return Py_BuildValue(head_dict,
- "version", FIXED_MAJOR(t->Table_Version), FIXED_MINOR(t->Table_Version),
- "fontRevision", FIXED_MAJOR(t->Font_Revision), FIXED_MINOR(t->Font_Revision),
- "checkSumAdjustment", t->CheckSum_Adjust,
- "magicNumber", t->Magic_Number,
- "flags", t->Flags,
- "unitsPerEm", t->Units_Per_EM,
- "created", t->Created[0], t->Created[1],
- "modified", t->Modified[0], t->Modified[1],
- "xMin", t->xMin,
- "yMin", t->yMin,
- "xMax", t->xMax,
- "yMax", t->yMax,
- "macStyle", t->Mac_Style,
- "lowestRecPPEM", t->Lowest_Rec_PPEM,
- "fontDirectionHint", t->Font_Direction,
- "indexToLocFormat", t->Index_To_Loc_Format,
- "glyphDataFormat", t->Glyph_Data_Format);
- }
- case 1: {
- char maxp_dict[] =
- "{s:(h,H), s:H, s:H, s:H, s:H, s:H, s:H,"
- "s:H, s:H, s:H, s:H, s:H, s:H, s:H, s:H}";
- TT_MaxProfile *t = (TT_MaxProfile *)table;
- return Py_BuildValue(maxp_dict,
- "version", FIXED_MAJOR(t->version), FIXED_MINOR(t->version),
- "numGlyphs", t->numGlyphs,
- "maxPoints", t->maxPoints,
- "maxContours", t->maxContours,
- "maxComponentPoints", t->maxCompositePoints,
- "maxComponentContours", t->maxCompositeContours,
- "maxZones", t->maxZones,
- "maxTwilightPoints", t->maxTwilightPoints,
- "maxStorage", t->maxStorage,
- "maxFunctionDefs", t->maxFunctionDefs,
- "maxInstructionDefs", t->maxInstructionDefs,
- "maxStackElements", t->maxStackElements,
- "maxSizeOfInstructions", t->maxSizeOfInstructions,
- "maxComponentElements", t->maxComponentElements,
- "maxComponentDepth", t->maxComponentDepth);
- }
- case 2: {
- char os_2_dict[] =
- "{s:H, s:h, s:H, s:H, s:H, s:h, s:h, s:h,"
- "s:h, s:h, s:h, s:h, s:h, s:h, s:h, s:h, s:y#, s:(kkkk),"
- "s:y#, s:H, s:H, s:H}";
- TT_OS2 *t = (TT_OS2 *)table;
- return Py_BuildValue(os_2_dict,
- "version", t->version,
- "xAvgCharWidth", t->xAvgCharWidth,
- "usWeightClass", t->usWeightClass,
- "usWidthClass", t->usWidthClass,
- "fsType", t->fsType,
- "ySubscriptXSize", t->ySubscriptXSize,
- "ySubscriptYSize", t->ySubscriptYSize,
- "ySubscriptXOffset", t->ySubscriptXOffset,
- "ySubscriptYOffset", t->ySubscriptYOffset,
- "ySuperscriptXSize", t->ySuperscriptXSize,
- "ySuperscriptYSize", t->ySuperscriptYSize,
- "ySuperscriptXOffset", t->ySuperscriptXOffset,
- "ySuperscriptYOffset", t->ySuperscriptYOffset,
- "yStrikeoutSize", t->yStrikeoutSize,
- "yStrikeoutPosition", t->yStrikeoutPosition,
- "sFamilyClass", t->sFamilyClass,
- "panose", t->panose, Py_ssize_t(10),
- "ulCharRange", t->ulUnicodeRange1, t->ulUnicodeRange2, t->ulUnicodeRange3, t->ulUnicodeRange4,
- "achVendID", t->achVendID, Py_ssize_t(4),
- "fsSelection", t->fsSelection,
- "fsFirstCharIndex", t->usFirstCharIndex,
- "fsLastCharIndex", t->usLastCharIndex);
- }
- case 3: {
- char hhea_dict[] =
- "{s:(h,H), s:h, s:h, s:h, s:H, s:h, s:h, s:h,"
- "s:h, s:h, s:h, s:h, s:H}";
- TT_HoriHeader *t = (TT_HoriHeader *)table;
- return Py_BuildValue(hhea_dict,
- "version", FIXED_MAJOR(t->Version), FIXED_MINOR(t->Version),
- "ascent", t->Ascender,
- "descent", t->Descender,
- "lineGap", t->Line_Gap,
- "advanceWidthMax", t->advance_Width_Max,
- "minLeftBearing", t->min_Left_Side_Bearing,
- "minRightBearing", t->min_Right_Side_Bearing,
- "xMaxExtent", t->xMax_Extent,
- "caretSlopeRise", t->caret_Slope_Rise,
- "caretSlopeRun", t->caret_Slope_Run,
- "caretOffset", t->caret_Offset,
- "metricDataFormat", t->metric_Data_Format,
- "numOfLongHorMetrics", t->number_Of_HMetrics);
- }
- case 4: {
- char vhea_dict[] =
- "{s:(h,H), s:h, s:h, s:h, s:H, s:h, s:h, s:h,"
- "s:h, s:h, s:h, s:h, s:H}";
- TT_VertHeader *t = (TT_VertHeader *)table;
- return Py_BuildValue(vhea_dict,
- "version", FIXED_MAJOR(t->Version), FIXED_MINOR(t->Version),
- "vertTypoAscender", t->Ascender,
- "vertTypoDescender", t->Descender,
- "vertTypoLineGap", t->Line_Gap,
- "advanceHeightMax", t->advance_Height_Max,
- "minTopSideBearing", t->min_Top_Side_Bearing,
- "minBottomSizeBearing", t->min_Bottom_Side_Bearing,
- "yMaxExtent", t->yMax_Extent,
- "caretSlopeRise", t->caret_Slope_Rise,
- "caretSlopeRun", t->caret_Slope_Run,
- "caretOffset", t->caret_Offset,
- "metricDataFormat", t->metric_Data_Format,
- "numOfLongVerMetrics", t->number_Of_VMetrics);
- }
- case 5: {
- char post_dict[] = "{s:(h,H), s:(h,H), s:h, s:h, s:k, s:k, s:k, s:k, s:k}";
- TT_Postscript *t = (TT_Postscript *)table;
- return Py_BuildValue(post_dict,
- "format", FIXED_MAJOR(t->FormatType), FIXED_MINOR(t->FormatType),
- "italicAngle", FIXED_MAJOR(t->italicAngle), FIXED_MINOR(t->italicAngle),
- "underlinePosition", t->underlinePosition,
- "underlineThickness", t->underlineThickness,
- "isFixedPitch", t->isFixedPitch,
- "minMemType42", t->minMemType42,
- "maxMemType42", t->maxMemType42,
- "minMemType1", t->minMemType1,
- "maxMemType1", t->maxMemType1);
- }
- case 6: {
- char pclt_dict[] =
- "{s:(h,H), s:k, s:H, s:H, s:H, s:H, s:H, s:H, s:y#, s:y#, s:b, "
- "s:b, s:b}";
- TT_PCLT *t = (TT_PCLT *)table;
- return Py_BuildValue(pclt_dict,
- "version", FIXED_MAJOR(t->Version), FIXED_MINOR(t->Version),
- "fontNumber", t->FontNumber,
- "pitch", t->Pitch,
- "xHeight", t->xHeight,
- "style", t->Style,
- "typeFamily", t->TypeFamily,
- "capHeight", t->CapHeight,
- "symbolSet", t->SymbolSet,
- "typeFace", t->TypeFace, Py_ssize_t(16),
- "characterComplement", t->CharacterComplement, Py_ssize_t(8),
- "strokeWeight", t->StrokeWeight,
- "widthType", t->WidthType,
- "serifStyle", t->SerifStyle);
- }
- default:
- Py_RETURN_NONE;
- }
-}
-
-const char *PyFT2Font_get_path__doc__ =
- "get_path(self)\n"
- "--\n\n"
- "Get the path data from the currently loaded glyph as a tuple of vertices, "
- "codes.\n";
-
-static PyObject *PyFT2Font_get_path(PyFT2Font *self, PyObject *args)
-{
- CALL_CPP("get_path", return self->x->get_path());
-}
-
-const char *PyFT2Font_get_image__doc__ =
- "get_image(self)\n"
- "--\n\n"
- "Return the underlying image buffer for this font object.\n";
-
-static PyObject *PyFT2Font_get_image(PyFT2Font *self, PyObject *args)
-{
- FT2Image &im = self->x->get_image();
- npy_intp dims[] = {(npy_intp)im.get_height(), (npy_intp)im.get_width() };
- return PyArray_SimpleNewFromData(2, dims, NPY_UBYTE, im.get_buffer());
-}
-
-static PyObject *PyFT2Font_postscript_name(PyFT2Font *self, void *closure)
-{
- const char *ps_name = FT_Get_Postscript_Name(self->x->get_face());
- if (ps_name == NULL) {
- ps_name = "UNAVAILABLE";
- }
-
- return PyUnicode_FromString(ps_name);
-}
-
-static PyObject *PyFT2Font_num_faces(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->num_faces);
-}
-
-static PyObject *PyFT2Font_family_name(PyFT2Font *self, void *closure)
-{
- const char *name = self->x->get_face()->family_name;
- if (name == NULL) {
- name = "UNAVAILABLE";
- }
- return PyUnicode_FromString(name);
-}
-
-static PyObject *PyFT2Font_style_name(PyFT2Font *self, void *closure)
-{
- const char *name = self->x->get_face()->style_name;
- if (name == NULL) {
- name = "UNAVAILABLE";
- }
- return PyUnicode_FromString(name);
-}
-
-static PyObject *PyFT2Font_face_flags(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->face_flags);
-}
-
-static PyObject *PyFT2Font_style_flags(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->style_flags);
-}
-
-static PyObject *PyFT2Font_num_glyphs(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->num_glyphs);
-}
-
-static PyObject *PyFT2Font_num_fixed_sizes(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->num_fixed_sizes);
-}
-
-static PyObject *PyFT2Font_num_charmaps(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->num_charmaps);
-}
-
-static PyObject *PyFT2Font_scalable(PyFT2Font *self, void *closure)
-{
- if (FT_IS_SCALABLE(self->x->get_face())) {
- Py_RETURN_TRUE;
- }
- Py_RETURN_FALSE;
-}
-
-static PyObject *PyFT2Font_units_per_EM(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->units_per_EM);
-}
-
-static PyObject *PyFT2Font_get_bbox(PyFT2Font *self, void *closure)
-{
- FT_BBox *bbox = &(self->x->get_face()->bbox);
-
- return Py_BuildValue("llll",
- bbox->xMin, bbox->yMin, bbox->xMax, bbox->yMax);
-}
-
-static PyObject *PyFT2Font_ascender(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->ascender);
-}
-
-static PyObject *PyFT2Font_descender(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->descender);
-}
-
-static PyObject *PyFT2Font_height(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->height);
-}
-
-static PyObject *PyFT2Font_max_advance_width(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->max_advance_width);
-}
-
-static PyObject *PyFT2Font_max_advance_height(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->max_advance_height);
-}
-
-static PyObject *PyFT2Font_underline_position(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->underline_position);
-}
-
-static PyObject *PyFT2Font_underline_thickness(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->underline_thickness);
-}
-
-static PyObject *PyFT2Font_fname(PyFT2Font *self, void *closure)
-{
- if (self->stream.close) { // Called passed a filename to the constructor.
- return PyObject_GetAttrString(self->py_file, "name");
- } else {
- Py_INCREF(self->py_file);
- return self->py_file;
- }
-}
-
-static int PyFT2Font_get_buffer(PyFT2Font *self, Py_buffer *buf, int flags)
-{
- FT2Image &im = self->x->get_image();
-
- Py_INCREF(self);
- buf->obj = (PyObject *)self;
- buf->buf = im.get_buffer();
- buf->len = im.get_width() * im.get_height();
- buf->readonly = 0;
- buf->format = (char *)"B";
- buf->ndim = 2;
- self->shape[0] = im.get_height();
- self->shape[1] = im.get_width();
- buf->shape = self->shape;
- self->strides[0] = im.get_width();
- self->strides[1] = 1;
- buf->strides = self->strides;
- buf->suboffsets = NULL;
- buf->itemsize = 1;
- buf->internal = NULL;
-
- return 1;
-}
-
-static PyTypeObject *PyFT2Font_init_type()
-{
- static PyGetSetDef getset[] = {
- {(char *)"postscript_name", (getter)PyFT2Font_postscript_name, NULL, NULL, NULL},
- {(char *)"num_faces", (getter)PyFT2Font_num_faces, NULL, NULL, NULL},
- {(char *)"family_name", (getter)PyFT2Font_family_name, NULL, NULL, NULL},
- {(char *)"style_name", (getter)PyFT2Font_style_name, NULL, NULL, NULL},
- {(char *)"face_flags", (getter)PyFT2Font_face_flags, NULL, NULL, NULL},
- {(char *)"style_flags", (getter)PyFT2Font_style_flags, NULL, NULL, NULL},
- {(char *)"num_glyphs", (getter)PyFT2Font_num_glyphs, NULL, NULL, NULL},
- {(char *)"num_fixed_sizes", (getter)PyFT2Font_num_fixed_sizes, NULL, NULL, NULL},
- {(char *)"num_charmaps", (getter)PyFT2Font_num_charmaps, NULL, NULL, NULL},
- {(char *)"scalable", (getter)PyFT2Font_scalable, NULL, NULL, NULL},
- {(char *)"units_per_EM", (getter)PyFT2Font_units_per_EM, NULL, NULL, NULL},
- {(char *)"bbox", (getter)PyFT2Font_get_bbox, NULL, NULL, NULL},
- {(char *)"ascender", (getter)PyFT2Font_ascender, NULL, NULL, NULL},
- {(char *)"descender", (getter)PyFT2Font_descender, NULL, NULL, NULL},
- {(char *)"height", (getter)PyFT2Font_height, NULL, NULL, NULL},
- {(char *)"max_advance_width", (getter)PyFT2Font_max_advance_width, NULL, NULL, NULL},
- {(char *)"max_advance_height", (getter)PyFT2Font_max_advance_height, NULL, NULL, NULL},
- {(char *)"underline_position", (getter)PyFT2Font_underline_position, NULL, NULL, NULL},
- {(char *)"underline_thickness", (getter)PyFT2Font_underline_thickness, NULL, NULL, NULL},
- {(char *)"fname", (getter)PyFT2Font_fname, NULL, NULL, NULL},
- {NULL}
- };
-
- static PyMethodDef methods[] = {
- {"clear", (PyCFunction)PyFT2Font_clear, METH_NOARGS, PyFT2Font_clear__doc__},
- {"set_size", (PyCFunction)PyFT2Font_set_size, METH_VARARGS, PyFT2Font_set_size__doc__},
- {"set_charmap", (PyCFunction)PyFT2Font_set_charmap, METH_VARARGS, PyFT2Font_set_charmap__doc__},
- {"select_charmap", (PyCFunction)PyFT2Font_select_charmap, METH_VARARGS, PyFT2Font_select_charmap__doc__},
- {"get_kerning", (PyCFunction)PyFT2Font_get_kerning, METH_VARARGS, PyFT2Font_get_kerning__doc__},
- {"set_text", (PyCFunction)PyFT2Font_set_text, METH_VARARGS|METH_KEYWORDS, PyFT2Font_set_text__doc__},
- {"_get_fontmap", (PyCFunction)PyFT2Font_get_fontmap, METH_VARARGS|METH_KEYWORDS, PyFT2Font_get_fontmap__doc__},
- {"get_num_glyphs", (PyCFunction)PyFT2Font_get_num_glyphs, METH_NOARGS, PyFT2Font_get_num_glyphs__doc__},
- {"load_char", (PyCFunction)PyFT2Font_load_char, METH_VARARGS|METH_KEYWORDS, PyFT2Font_load_char__doc__},
- {"load_glyph", (PyCFunction)PyFT2Font_load_glyph, METH_VARARGS|METH_KEYWORDS, PyFT2Font_load_glyph__doc__},
- {"get_width_height", (PyCFunction)PyFT2Font_get_width_height, METH_NOARGS, PyFT2Font_get_width_height__doc__},
- {"get_bitmap_offset", (PyCFunction)PyFT2Font_get_bitmap_offset, METH_NOARGS, PyFT2Font_get_bitmap_offset__doc__},
- {"get_descent", (PyCFunction)PyFT2Font_get_descent, METH_NOARGS, PyFT2Font_get_descent__doc__},
- {"draw_glyphs_to_bitmap", (PyCFunction)PyFT2Font_draw_glyphs_to_bitmap, METH_VARARGS|METH_KEYWORDS, PyFT2Font_draw_glyphs_to_bitmap__doc__},
- {"get_xys", (PyCFunction)PyFT2Font_get_xys, METH_VARARGS|METH_KEYWORDS, PyFT2Font_get_xys__doc__},
- {"draw_glyph_to_bitmap", (PyCFunction)PyFT2Font_draw_glyph_to_bitmap, METH_VARARGS|METH_KEYWORDS, PyFT2Font_draw_glyph_to_bitmap__doc__},
- {"get_glyph_name", (PyCFunction)PyFT2Font_get_glyph_name, METH_VARARGS, PyFT2Font_get_glyph_name__doc__},
- {"get_charmap", (PyCFunction)PyFT2Font_get_charmap, METH_NOARGS, PyFT2Font_get_charmap__doc__},
- {"get_char_index", (PyCFunction)PyFT2Font_get_char_index, METH_VARARGS, PyFT2Font_get_char_index__doc__},
- {"get_sfnt", (PyCFunction)PyFT2Font_get_sfnt, METH_NOARGS, PyFT2Font_get_sfnt__doc__},
- {"get_name_index", (PyCFunction)PyFT2Font_get_name_index, METH_VARARGS, PyFT2Font_get_name_index__doc__},
- {"get_ps_font_info", (PyCFunction)PyFT2Font_get_ps_font_info, METH_NOARGS, PyFT2Font_get_ps_font_info__doc__},
- {"get_sfnt_table", (PyCFunction)PyFT2Font_get_sfnt_table, METH_VARARGS, PyFT2Font_get_sfnt_table__doc__},
- {"get_path", (PyCFunction)PyFT2Font_get_path, METH_NOARGS, PyFT2Font_get_path__doc__},
- {"get_image", (PyCFunction)PyFT2Font_get_image, METH_NOARGS, PyFT2Font_get_image__doc__},
- {NULL}
- };
-
- static PyBufferProcs buffer_procs;
- buffer_procs.bf_getbuffer = (getbufferproc)PyFT2Font_get_buffer;
-
- PyFT2FontType.tp_name = "matplotlib.ft2font.FT2Font";
- PyFT2FontType.tp_doc = PyFT2Font_init__doc__;
- PyFT2FontType.tp_basicsize = sizeof(PyFT2Font);
- PyFT2FontType.tp_dealloc = (destructor)PyFT2Font_dealloc;
- PyFT2FontType.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
- PyFT2FontType.tp_methods = methods;
- PyFT2FontType.tp_getset = getset;
- PyFT2FontType.tp_new = PyFT2Font_new;
- PyFT2FontType.tp_init = (initproc)PyFT2Font_init;
- PyFT2FontType.tp_as_buffer = &buffer_procs;
-
- return &PyFT2FontType;
-}
-
-static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "ft2font" };
-
-PyMODINIT_FUNC PyInit_ft2font(void)
-{
- import_array();
-
- if (FT_Init_FreeType(&_ft2Library)) { // initialize library
- return PyErr_Format(
- PyExc_RuntimeError, "Could not initialize the freetype2 library");
- }
- FT_Int major, minor, patch;
- char version_string[64];
- FT_Library_Version(_ft2Library, &major, &minor, &patch);
- snprintf(version_string, sizeof(version_string), "%d.%d.%d", major, minor, patch);
-
- PyObject *m;
- if (!(m = PyModule_Create(&moduledef)) ||
- prepare_and_add_type(PyFT2Image_init_type(), m) ||
- prepare_and_add_type(PyFT2Font_init_type(), m) ||
- // Glyph is not constructible from Python, thus not added to the module.
- PyType_Ready(PyGlyph_init_type()) ||
- PyModule_AddStringConstant(m, "__freetype_version__", version_string) ||
- PyModule_AddStringConstant(m, "__freetype_build_type__", STRINGIFY(FREETYPE_BUILD_TYPE)) ||
- PyModule_AddIntConstant(m, "SCALABLE", FT_FACE_FLAG_SCALABLE) ||
- PyModule_AddIntConstant(m, "FIXED_SIZES", FT_FACE_FLAG_FIXED_SIZES) ||
- PyModule_AddIntConstant(m, "FIXED_WIDTH", FT_FACE_FLAG_FIXED_WIDTH) ||
- PyModule_AddIntConstant(m, "SFNT", FT_FACE_FLAG_SFNT) ||
- PyModule_AddIntConstant(m, "HORIZONTAL", FT_FACE_FLAG_HORIZONTAL) ||
- PyModule_AddIntConstant(m, "VERTICAL", FT_FACE_FLAG_VERTICAL) ||
- PyModule_AddIntConstant(m, "KERNING", FT_FACE_FLAG_KERNING) ||
- PyModule_AddIntConstant(m, "FAST_GLYPHS", FT_FACE_FLAG_FAST_GLYPHS) ||
- PyModule_AddIntConstant(m, "MULTIPLE_MASTERS", FT_FACE_FLAG_MULTIPLE_MASTERS) ||
- PyModule_AddIntConstant(m, "GLYPH_NAMES", FT_FACE_FLAG_GLYPH_NAMES) ||
- PyModule_AddIntConstant(m, "EXTERNAL_STREAM", FT_FACE_FLAG_EXTERNAL_STREAM) ||
- PyModule_AddIntConstant(m, "ITALIC", FT_STYLE_FLAG_ITALIC) ||
- PyModule_AddIntConstant(m, "BOLD", FT_STYLE_FLAG_BOLD) ||
- PyModule_AddIntConstant(m, "KERNING_DEFAULT", FT_KERNING_DEFAULT) ||
- PyModule_AddIntConstant(m, "KERNING_UNFITTED", FT_KERNING_UNFITTED) ||
- PyModule_AddIntConstant(m, "KERNING_UNSCALED", FT_KERNING_UNSCALED) ||
- PyModule_AddIntConstant(m, "LOAD_DEFAULT", FT_LOAD_DEFAULT) ||
- PyModule_AddIntConstant(m, "LOAD_NO_SCALE", FT_LOAD_NO_SCALE) ||
- PyModule_AddIntConstant(m, "LOAD_NO_HINTING", FT_LOAD_NO_HINTING) ||
- PyModule_AddIntConstant(m, "LOAD_RENDER", FT_LOAD_RENDER) ||
- PyModule_AddIntConstant(m, "LOAD_NO_BITMAP", FT_LOAD_NO_BITMAP) ||
- PyModule_AddIntConstant(m, "LOAD_VERTICAL_LAYOUT", FT_LOAD_VERTICAL_LAYOUT) ||
- PyModule_AddIntConstant(m, "LOAD_FORCE_AUTOHINT", FT_LOAD_FORCE_AUTOHINT) ||
- PyModule_AddIntConstant(m, "LOAD_CROP_BITMAP", FT_LOAD_CROP_BITMAP) ||
- PyModule_AddIntConstant(m, "LOAD_PEDANTIC", FT_LOAD_PEDANTIC) ||
- PyModule_AddIntConstant(m, "LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH", FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH) ||
- PyModule_AddIntConstant(m, "LOAD_NO_RECURSE", FT_LOAD_NO_RECURSE) ||
- PyModule_AddIntConstant(m, "LOAD_IGNORE_TRANSFORM", FT_LOAD_IGNORE_TRANSFORM) ||
- PyModule_AddIntConstant(m, "LOAD_MONOCHROME", FT_LOAD_MONOCHROME) ||
- PyModule_AddIntConstant(m, "LOAD_LINEAR_DESIGN", FT_LOAD_LINEAR_DESIGN) ||
- PyModule_AddIntConstant(m, "LOAD_NO_AUTOHINT", (unsigned long)FT_LOAD_NO_AUTOHINT) ||
- PyModule_AddIntConstant(m, "LOAD_TARGET_NORMAL", (unsigned long)FT_LOAD_TARGET_NORMAL) ||
- PyModule_AddIntConstant(m, "LOAD_TARGET_LIGHT", (unsigned long)FT_LOAD_TARGET_LIGHT) ||
- PyModule_AddIntConstant(m, "LOAD_TARGET_MONO", (unsigned long)FT_LOAD_TARGET_MONO) ||
- PyModule_AddIntConstant(m, "LOAD_TARGET_LCD", (unsigned long)FT_LOAD_TARGET_LCD) ||
- PyModule_AddIntConstant(m, "LOAD_TARGET_LCD_V", (unsigned long)FT_LOAD_TARGET_LCD_V)) {
- FT_Done_FreeType(_ft2Library);
- Py_XDECREF(m);
- return NULL;
- }
-
- return m;
-}
diff --git a/contrib/python/matplotlib/py3/src/mplutils.h b/contrib/python/matplotlib/py3/src/mplutils.h
deleted file mode 100644
index 6eb89899ca..0000000000
--- a/contrib/python/matplotlib/py3/src/mplutils.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/* Small utilities that are shared by most extension modules. */
-
-#ifndef MPLUTILS_H
-#define MPLUTILS_H
-#define PY_SSIZE_T_CLEAN
-
-#include <Python.h>
-#include <stdint.h>
-
-#ifdef _POSIX_C_SOURCE
-# undef _POSIX_C_SOURCE
-#endif
-#ifndef _AIX
-#ifdef _XOPEN_SOURCE
-# undef _XOPEN_SOURCE
-#endif
-#endif
-
-// Prevent multiple conflicting definitions of swab from stdlib.h and unistd.h
-#if defined(__sun) || defined(sun)
-#if defined(_XPG4)
-#undef _XPG4
-#endif
-#if defined(_XPG3)
-#undef _XPG3
-#endif
-#endif
-
-
-inline int mpl_round_to_int(double v)
-{
- return (int)(v + ((v >= 0.0) ? 0.5 : -0.5));
-}
-
-inline double mpl_round(double v)
-{
- return (double)mpl_round_to_int(v);
-}
-
-// 'kind' codes for paths.
-enum {
- STOP = 0,
- MOVETO = 1,
- LINETO = 2,
- CURVE3 = 3,
- CURVE4 = 4,
- CLOSEPOLY = 0x4f
-};
-
-const size_t NUM_VERTICES[] = { 1, 1, 1, 2, 3, 1 };
-
-inline int prepare_and_add_type(PyTypeObject *type, PyObject *module)
-{
- if (PyType_Ready(type)) {
- return -1;
- }
- char const* ptr = strrchr(type->tp_name, '.');
- if (!ptr) {
- PyErr_SetString(PyExc_ValueError, "tp_name should be a qualified name");
- return -1;
- }
- if (PyModule_AddObject(module, ptr + 1, (PyObject *)type)) {
- return -1;
- }
- return 0;
-}
-
-#ifdef __cplusplus // not for macosx.m
-// Check that array has shape (N, d1) or (N, d1, d2). We cast d1, d2 to longs
-// so that we don't need to access the NPY_INTP_FMT macro here.
-
-template<typename T>
-inline bool check_trailing_shape(T array, char const* name, long d1)
-{
- if (array.dim(1) != d1) {
- PyErr_Format(PyExc_ValueError,
- "%s must have shape (N, %ld), got (%ld, %ld)",
- name, d1, array.dim(0), array.dim(1));
- return false;
- }
- return true;
-}
-
-template<typename T>
-inline bool check_trailing_shape(T array, char const* name, long d1, long d2)
-{
- if (array.dim(1) != d1 || array.dim(2) != d2) {
- PyErr_Format(PyExc_ValueError,
- "%s must have shape (N, %ld, %ld), got (%ld, %ld, %ld)",
- name, d1, d2, array.dim(0), array.dim(1), array.dim(2));
- return false;
- }
- return true;
-}
-#endif
-
-#endif
diff --git a/contrib/python/matplotlib/py3/src/numpy_cpp.h b/contrib/python/matplotlib/py3/src/numpy_cpp.h
deleted file mode 100644
index 36c763d158..0000000000
--- a/contrib/python/matplotlib/py3/src/numpy_cpp.h
+++ /dev/null
@@ -1,578 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef MPL_NUMPY_CPP_H
-#define MPL_NUMPY_CPP_H
-#define PY_SSIZE_T_CLEAN
-/***************************************************************************
- * This file is based on original work by Mark Wiebe, available at:
- *
- * http://github.com/mwiebe/numpy-cpp
- *
- * However, the needs of matplotlib wrappers, such as treating an
- * empty array as having the correct dimensions, have made this rather
- * matplotlib-specific, so it's no longer compatible with the
- * original.
- */
-
-#include "py_exceptions.h"
-
-#include <complex>
-
-#ifdef _POSIX_C_SOURCE
-# undef _POSIX_C_SOURCE
-#endif
-#ifndef _AIX
-#ifdef _XOPEN_SOURCE
-# undef _XOPEN_SOURCE
-#endif
-#endif
-
-// Prevent multiple conflicting definitions of swab from stdlib.h and unistd.h
-#if defined(__sun) || defined(sun)
-#if defined(_XPG4)
-#undef _XPG4
-#endif
-#if defined(_XPG3)
-#undef _XPG3
-#endif
-#endif
-
-#include <Python.h>
-#include <numpy/ndarrayobject.h>
-
-namespace numpy
-{
-
-// Type traits for the NumPy types
-template <typename T>
-struct type_num_of;
-
-/* Be careful with bool arrays as python has sizeof(npy_bool) == 1, but it is
- * not always the case that sizeof(bool) == 1. Using the array_view_accessors
- * is always fine regardless of sizeof(bool), so do this rather than using
- * array.data() and pointer arithmetic which will not work correctly if
- * sizeof(bool) != 1. */
-template <> struct type_num_of<bool>
-{
- enum {
- value = NPY_BOOL
- };
-};
-template <>
-struct type_num_of<npy_byte>
-{
- enum {
- value = NPY_BYTE
- };
-};
-template <>
-struct type_num_of<npy_ubyte>
-{
- enum {
- value = NPY_UBYTE
- };
-};
-template <>
-struct type_num_of<npy_short>
-{
- enum {
- value = NPY_SHORT
- };
-};
-template <>
-struct type_num_of<npy_ushort>
-{
- enum {
- value = NPY_USHORT
- };
-};
-template <>
-struct type_num_of<npy_int>
-{
- enum {
- value = NPY_INT
- };
-};
-template <>
-struct type_num_of<npy_uint>
-{
- enum {
- value = NPY_UINT
- };
-};
-template <>
-struct type_num_of<npy_long>
-{
- enum {
- value = NPY_LONG
- };
-};
-template <>
-struct type_num_of<npy_ulong>
-{
- enum {
- value = NPY_ULONG
- };
-};
-template <>
-struct type_num_of<npy_longlong>
-{
- enum {
- value = NPY_LONGLONG
- };
-};
-template <>
-struct type_num_of<npy_ulonglong>
-{
- enum {
- value = NPY_ULONGLONG
- };
-};
-template <>
-struct type_num_of<npy_float>
-{
- enum {
- value = NPY_FLOAT
- };
-};
-template <>
-struct type_num_of<npy_double>
-{
- enum {
- value = NPY_DOUBLE
- };
-};
-#if NPY_LONGDOUBLE != NPY_DOUBLE
-template <>
-struct type_num_of<npy_longdouble>
-{
- enum {
- value = NPY_LONGDOUBLE
- };
-};
-#endif
-template <>
-struct type_num_of<npy_cfloat>
-{
- enum {
- value = NPY_CFLOAT
- };
-};
-template <>
-struct type_num_of<std::complex<npy_float> >
-{
- enum {
- value = NPY_CFLOAT
- };
-};
-template <>
-struct type_num_of<npy_cdouble>
-{
- enum {
- value = NPY_CDOUBLE
- };
-};
-template <>
-struct type_num_of<std::complex<npy_double> >
-{
- enum {
- value = NPY_CDOUBLE
- };
-};
-#if NPY_CLONGDOUBLE != NPY_CDOUBLE
-template <>
-struct type_num_of<npy_clongdouble>
-{
- enum {
- value = NPY_CLONGDOUBLE
- };
-};
-template <>
-struct type_num_of<std::complex<npy_longdouble> >
-{
- enum {
- value = NPY_CLONGDOUBLE
- };
-};
-#endif
-template <>
-struct type_num_of<PyObject *>
-{
- enum {
- value = NPY_OBJECT
- };
-};
-template <typename T>
-struct type_num_of<T &>
-{
- enum {
- value = type_num_of<T>::value
- };
-};
-template <typename T>
-struct type_num_of<const T>
-{
- enum {
- value = type_num_of<T>::value
- };
-};
-
-template <typename T>
-struct is_const
-{
- enum {
- value = false
- };
-};
-template <typename T>
-struct is_const<const T>
-{
- enum {
- value = true
- };
-};
-
-namespace detail
-{
-template <template <typename, int> class AV, typename T, int ND>
-class array_view_accessors;
-
-template <template <typename, int> class AV, typename T>
-class array_view_accessors<AV, T, 1>
-{
- public:
- typedef AV<T, 1> AVC;
- typedef T sub_t;
-
- T &operator()(npy_intp i)
- {
- AVC *self = static_cast<AVC *>(this);
-
- return *reinterpret_cast<T *>(self->m_data + self->m_strides[0] * i);
- }
-
- const T &operator()(npy_intp i) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return *reinterpret_cast<const T *>(self->m_data + self->m_strides[0] * i);
- }
-
- T &operator[](npy_intp i)
- {
- AVC *self = static_cast<AVC *>(this);
-
- return *reinterpret_cast<T *>(self->m_data + self->m_strides[0] * i);
- }
-
- const T &operator[](npy_intp i) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return *reinterpret_cast<const T *>(self->m_data + self->m_strides[0] * i);
- }
-};
-
-template <template <typename, int> class AV, typename T>
-class array_view_accessors<AV, T, 2>
-{
- public:
- typedef AV<T, 2> AVC;
- typedef AV<T, 1> sub_t;
-
- T &operator()(npy_intp i, npy_intp j)
- {
- AVC *self = static_cast<AVC *>(this);
-
- return *reinterpret_cast<T *>(self->m_data + self->m_strides[0] * i +
- self->m_strides[1] * j);
- }
-
- const T &operator()(npy_intp i, npy_intp j) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return *reinterpret_cast<const T *>(self->m_data + self->m_strides[0] * i +
- self->m_strides[1] * j);
- }
-
- sub_t subarray(npy_intp i) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return sub_t(self->m_arr,
- self->m_data + self->m_strides[0] * i,
- self->m_shape + 1,
- self->m_strides + 1);
- }
-};
-
-template <template <typename, int> class AV, typename T>
-class array_view_accessors<AV, T, 3>
-{
- public:
- typedef AV<T, 3> AVC;
- typedef AV<T, 2> sub_t;
-
- T &operator()(npy_intp i, npy_intp j, npy_intp k)
- {
- AVC *self = static_cast<AVC *>(this);
-
- return *reinterpret_cast<T *>(self->m_data + self->m_strides[0] * i +
- self->m_strides[1] * j + self->m_strides[2] * k);
- }
-
- const T &operator()(npy_intp i, npy_intp j, npy_intp k) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return *reinterpret_cast<const T *>(self->m_data + self->m_strides[0] * i +
- self->m_strides[1] * j + self->m_strides[2] * k);
- }
-
- sub_t subarray(npy_intp i) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return sub_t(self->m_arr,
- self->m_data + self->m_strides[0] * i,
- self->m_shape + 1,
- self->m_strides + 1);
- }
-
-
-};
-
-// When adding instantiations of array_view_accessors, remember to add entries
-// to zeros[] below.
-
-}
-
-static npy_intp zeros[] = { 0, 0, 0 };
-
-template <typename T, int ND>
-class array_view : public detail::array_view_accessors<array_view, T, ND>
-{
- friend class detail::array_view_accessors<numpy::array_view, T, ND>;
-
- private:
- // Copies of the array data
- PyArrayObject *m_arr;
- npy_intp *m_shape;
- npy_intp *m_strides;
- char *m_data;
-
- public:
- typedef T value_type;
-
- enum {
- ndim = ND
- };
-
- array_view() : m_arr(NULL), m_data(NULL)
- {
- m_shape = zeros;
- m_strides = zeros;
- }
-
- array_view(PyObject *arr, bool contiguous = false) : m_arr(NULL), m_data(NULL)
- {
- if (!set(arr, contiguous)) {
- throw py::exception();
- }
- }
-
- array_view(const array_view &other) : m_arr(NULL), m_data(NULL)
- {
- m_arr = other.m_arr;
- Py_XINCREF(m_arr);
- m_data = other.m_data;
- m_shape = other.m_shape;
- m_strides = other.m_strides;
- }
-
- array_view(PyArrayObject *arr, char *data, npy_intp *shape, npy_intp *strides)
- {
- m_arr = arr;
- Py_XINCREF(arr);
- m_data = data;
- m_shape = shape;
- m_strides = strides;
- }
-
- array_view(PyArrayObject *arr)
- {
- m_arr = arr;
- Py_XINCREF(arr);
- m_shape = PyArray_DIMS(m_arr);
- m_strides = PyArray_STRIDES(m_arr);
- m_data = PyArray_BYTES(m_arr);
- }
-
- array_view(npy_intp shape[ND]) : m_arr(NULL), m_shape(NULL), m_strides(NULL), m_data(NULL)
- {
- PyObject *arr = PyArray_SimpleNew(ND, shape, type_num_of<T>::value);
- if (arr == NULL) {
- throw py::exception();
- }
- if (!set(arr, true)) {
- Py_DECREF(arr);
- throw py::exception();
- }
- Py_DECREF(arr);
- }
-
- ~array_view()
- {
- Py_XDECREF(m_arr);
- }
-
- array_view& operator=(const array_view &other)
- {
- if (this != &other)
- {
- Py_XDECREF(m_arr);
- m_arr = other.m_arr;
- Py_XINCREF(m_arr);
- m_data = other.m_data;
- m_shape = other.m_shape;
- m_strides = other.m_strides;
- }
- return *this;
- }
-
- bool set(PyObject *arr, bool contiguous = false)
- {
- PyArrayObject *tmp;
-
- if (arr == NULL || arr == Py_None) {
- Py_XDECREF(m_arr);
- m_arr = NULL;
- m_data = NULL;
- m_shape = zeros;
- m_strides = zeros;
- } else {
- if (contiguous) {
- tmp = (PyArrayObject *)PyArray_ContiguousFromAny(arr, type_num_of<T>::value, 0, ND);
- } else {
- tmp = (PyArrayObject *)PyArray_FromObject(arr, type_num_of<T>::value, 0, ND);
- }
- if (tmp == NULL) {
- return false;
- }
-
- if (PyArray_NDIM(tmp) == 0 || PyArray_DIM(tmp, 0) == 0) {
- Py_XDECREF(m_arr);
- m_arr = NULL;
- m_data = NULL;
- m_shape = zeros;
- m_strides = zeros;
- if (PyArray_NDIM(tmp) == 0 && ND == 0) {
- m_arr = tmp;
- return true;
- }
- }
- if (PyArray_NDIM(tmp) != ND) {
- PyErr_Format(PyExc_ValueError,
- "Expected %d-dimensional array, got %d",
- ND,
- PyArray_NDIM(tmp));
- Py_DECREF(tmp);
- return false;
- }
-
- /* Copy some of the data to the view object for faster access */
- Py_XDECREF(m_arr);
- m_arr = tmp;
- m_shape = PyArray_DIMS(m_arr);
- m_strides = PyArray_STRIDES(m_arr);
- m_data = PyArray_BYTES(tmp);
- }
-
- return true;
- }
-
- npy_intp dim(size_t i) const
- {
- if (i >= ND) {
- return 0;
- }
- return m_shape[i];
- }
-
- /*
- In most cases, code should use size() instead of dim(0), since
- size() == 0 when any dimension is 0.
- */
- size_t size() const
- {
- bool empty = (ND == 0);
- for (size_t i = 0; i < ND; i++) {
- if (m_shape[i] == 0) {
- empty = true;
- }
- }
- if (empty) {
- return 0;
- } else {
- return (size_t)dim(0);
- }
- }
-
- bool empty() const
- {
- return size() == 0;
- }
-
- // Do not use this for array_view<bool, ND>. See comment near top of file.
- const T *data() const
- {
- return (const T *)m_data;
- }
-
- // Do not use this for array_view<bool, ND>. See comment near top of file.
- T *data()
- {
- return (T *)m_data;
- }
-
- // Return a new reference.
- PyObject *pyobj()
- {
- Py_XINCREF(m_arr);
- return (PyObject *)m_arr;
- }
-
- // Steal a reference.
- PyObject *pyobj_steal()
- {
- return (PyObject *)m_arr;
- }
-
- static int converter(PyObject *obj, void *arrp)
- {
- array_view<T, ND> *arr = (array_view<T, ND> *)arrp;
-
- if (!arr->set(obj)) {
- return 0;
- }
-
- return 1;
- }
-
- static int converter_contiguous(PyObject *obj, void *arrp)
- {
- array_view<T, ND> *arr = (array_view<T, ND> *)arrp;
-
- if (!arr->set(obj, true)) {
- return 0;
- }
-
- return 1;
- }
-};
-
-} // namespace numpy
-
-
-#endif
diff --git a/contrib/python/matplotlib/py3/src/path_converters.h b/contrib/python/matplotlib/py3/src/path_converters.h
deleted file mode 100644
index 8583d84855..0000000000
--- a/contrib/python/matplotlib/py3/src/path_converters.h
+++ /dev/null
@@ -1,1106 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef MPL_PATH_CONVERTERS_H
-#define MPL_PATH_CONVERTERS_H
-
-#include <cmath>
-#include <stdint.h>
-#include "agg_path_storage.h"
-#include "agg_clip_liang_barsky.h"
-#include "mplutils.h"
-#include "agg_conv_segmentator.h"
-
-/*
- This file contains a number of vertex converters that modify
- paths. They all work as iterators, where the output is generated
- on-the-fly, and don't require a copy of the full data.
-
- Each class represents a discrete step in a "path-cleansing" pipeline.
- They are currently applied in the following order in the Agg backend:
-
- 1. Affine transformation (implemented in Agg, not here)
-
- 2. PathNanRemover: skips over segments containing non-finite numbers
- by inserting MOVETO commands
-
- 3. PathClipper: Clips line segments to a given rectangle. This is
- helpful for data reduction, and also to avoid a limitation in
- Agg where coordinates cannot be larger than 24-bit signed
- integers.
-
- 4. PathSnapper: Rounds the path to the nearest center-pixels.
- This makes rectilinear curves look much better.
-
- 5. PathSimplifier: Removes line segments from highly dense paths
- that would not have an impact on their appearance. Speeds up
- rendering and reduces file sizes.
-
- 6. curve-to-line-segment conversion (implemented in Agg, not here)
-
- 7. stroking (implemented in Agg, not here)
- */
-
-/************************************************************
- This is a base class for vertex converters that need to queue their
- output. It is designed to be as fast as possible vs. the STL's queue
- which is more flexible.
- */
-template <int QueueSize>
-class EmbeddedQueue
-{
- protected:
- EmbeddedQueue() : m_queue_read(0), m_queue_write(0)
- {
- // empty
- }
-
- struct item
- {
- item()
- {
- }
-
- inline void set(const unsigned cmd_, const double x_, const double y_)
- {
- cmd = cmd_;
- x = x_;
- y = y_;
- }
- unsigned cmd;
- double x;
- double y;
- };
- int m_queue_read;
- int m_queue_write;
- item m_queue[QueueSize];
-
- inline void queue_push(const unsigned cmd, const double x, const double y)
- {
- m_queue[m_queue_write++].set(cmd, x, y);
- }
-
- inline bool queue_nonempty()
- {
- return m_queue_read < m_queue_write;
- }
-
- inline bool queue_pop(unsigned *cmd, double *x, double *y)
- {
- if (queue_nonempty()) {
- const item &front = m_queue[m_queue_read++];
- *cmd = front.cmd;
- *x = front.x;
- *y = front.y;
-
- return true;
- }
-
- m_queue_read = 0;
- m_queue_write = 0;
-
- return false;
- }
-
- inline void queue_clear()
- {
- m_queue_read = 0;
- m_queue_write = 0;
- }
-};
-
-/* Defines when path segment types have more than one vertex */
-static const size_t num_extra_points_map[] =
- {0, 0, 0, 1,
- 2, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0
- };
-
-/* An implementation of a simple linear congruential random number
- generator. This is a "classic" and fast RNG which works fine for
- our purposes of sketching lines, but should not be used for things
- that matter, like crypto. We are implementing this ourselves
- rather than using the C stdlib so that the seed state is not shared
- with other third-party code. There are recent C++ options, but we
- still require nothing later than C++98 for compatibility
- reasons. */
-class RandomNumberGenerator
-{
-private:
- /* These are the same constants from MS Visual C++, which
- has the nice property that the modulus is 2^32, thus
- saving an explicit modulo operation
- */
- static const uint32_t a = 214013;
- static const uint32_t c = 2531011;
- uint32_t m_seed;
-
-public:
- RandomNumberGenerator() : m_seed(0) {}
- RandomNumberGenerator(int seed) : m_seed(seed) {}
-
- void seed(int seed)
- {
- m_seed = seed;
- }
-
- double get_double()
- {
- m_seed = (a * m_seed + c);
- return (double)m_seed / (double)(1LL << 32);
- }
-};
-
-/*
- PathNanRemover is a vertex converter that removes non-finite values
- from the vertices list, and inserts MOVETO commands as necessary to
- skip over them. If a curve segment contains at least one non-finite
- value, the entire curve segment will be skipped.
- */
-template <class VertexSource>
-class PathNanRemover : protected EmbeddedQueue<4>
-{
- VertexSource *m_source;
- bool m_remove_nans;
- bool m_has_codes;
- bool valid_segment_exists;
- bool m_last_segment_valid;
- bool m_was_broken;
- double m_initX;
- double m_initY;
-
- public:
- /* has_codes should be true if the path contains bezier curve segments, or
- * closed loops, as this requires a slower algorithm to remove the NaNs.
- * When in doubt, set to true.
- */
- PathNanRemover(VertexSource &source, bool remove_nans, bool has_codes)
- : m_source(&source), m_remove_nans(remove_nans), m_has_codes(has_codes),
- m_last_segment_valid(false), m_was_broken(false),
- m_initX(nan("")), m_initY(nan(""))
- {
- // ignore all close/end_poly commands until after the first valid
- // (nan-free) command is encountered
- valid_segment_exists = false;
- }
-
- inline void rewind(unsigned path_id)
- {
- queue_clear();
- m_source->rewind(path_id);
- }
-
- inline unsigned vertex(double *x, double *y)
- {
- unsigned code;
-
- if (!m_remove_nans) {
- return m_source->vertex(x, y);
- }
-
- if (m_has_codes) {
- /* This is the slow method for when there might be curves or closed
- * loops. */
- if (queue_pop(&code, x, y)) {
- return code;
- }
-
- bool needs_move_to = false;
- while (true) {
- /* The approach here is to push each full curve
- segment into the queue. If any non-finite values
- are found along the way, the queue is emptied, and
- the next curve segment is handled. */
- code = m_source->vertex(x, y);
- /* The vertices attached to STOP and CLOSEPOLY are never used,
- * so we leave them as-is even if NaN. */
- if (code == agg::path_cmd_stop) {
- return code;
- } else if (code == (agg::path_cmd_end_poly |
- agg::path_flags_close) &&
- valid_segment_exists) {
- /* However, CLOSEPOLY only makes sense if a valid MOVETO
- * command has already been emitted. But if a NaN was
- * removed in the path, then we cannot close it as it is no
- * longer a loop. We must emulate that by inserting a
- * LINETO instead. */
- if (m_was_broken) {
- if (m_last_segment_valid && (
- std::isfinite(m_initX) &&
- std::isfinite(m_initY))) {
- /* Join to start if both ends are valid. */
- queue_push(agg::path_cmd_line_to, m_initX, m_initY);
- break;
- } else {
- /* Skip the close, in case there are additional
- * subpaths. */
- continue;
- }
- m_was_broken = false;
- break;
- } else {
- return code;
- }
- } else if (code == agg::path_cmd_move_to) {
- /* Save the initial point in order to produce the last
- * segment closing a loop, *if* we broke the loop. */
- m_initX = *x;
- m_initY = *y;
- m_was_broken = false;
- }
-
- if (needs_move_to) {
- queue_push(agg::path_cmd_move_to, *x, *y);
- }
-
- size_t num_extra_points = num_extra_points_map[code & 0xF];
- m_last_segment_valid = (std::isfinite(*x) && std::isfinite(*y));
- queue_push(code, *x, *y);
-
- /* Note: this test cannot be short-circuited, since we need to
- advance through the entire curve no matter what */
- for (size_t i = 0; i < num_extra_points; ++i) {
- m_source->vertex(x, y);
- m_last_segment_valid = m_last_segment_valid &&
- (std::isfinite(*x) && std::isfinite(*y));
- queue_push(code, *x, *y);
- }
-
- if (m_last_segment_valid) {
- valid_segment_exists = true;
- break;
- }
-
- m_was_broken = true;
- queue_clear();
-
- /* If the last point is finite, we use that for the
- moveto, otherwise, we'll use the first vertex of
- the next curve. */
- if (std::isfinite(*x) && std::isfinite(*y)) {
- queue_push(agg::path_cmd_move_to, *x, *y);
- needs_move_to = false;
- } else {
- needs_move_to = true;
- }
- }
-
- if (queue_pop(&code, x, y)) {
- return code;
- } else {
- return agg::path_cmd_stop;
- }
- } else // !m_has_codes
- {
- /* This is the fast path for when we know we have no codes. */
- code = m_source->vertex(x, y);
-
- if (code == agg::path_cmd_stop ||
- (code == (agg::path_cmd_end_poly | agg::path_flags_close) &&
- valid_segment_exists)) {
- return code;
- }
-
- if (!(std::isfinite(*x) && std::isfinite(*y))) {
- do {
- code = m_source->vertex(x, y);
- if (code == agg::path_cmd_stop ||
- (code == (agg::path_cmd_end_poly | agg::path_flags_close) &&
- valid_segment_exists)) {
- return code;
- }
- } while (!(std::isfinite(*x) && std::isfinite(*y)));
- return agg::path_cmd_move_to;
- }
- valid_segment_exists = true;
- return code;
- }
- }
-};
-
-/************************************************************
- PathClipper uses the Liang-Barsky line clipping algorithm (as
- implemented in Agg) to clip the path to a given rectangle. Lines
- will never extend outside of the rectangle. Curve segments are not
- clipped, but are always included in their entirety.
- */
-template <class VertexSource>
-class PathClipper : public EmbeddedQueue<3>
-{
- VertexSource *m_source;
- bool m_do_clipping;
- agg::rect_base<double> m_cliprect;
- double m_lastX;
- double m_lastY;
- bool m_moveto;
- double m_initX;
- double m_initY;
- bool m_has_init;
- bool m_was_clipped;
-
- public:
- PathClipper(VertexSource &source, bool do_clipping, double width, double height)
- : m_source(&source),
- m_do_clipping(do_clipping),
- m_cliprect(-1.0, -1.0, width + 1.0, height + 1.0),
- m_lastX(nan("")),
- m_lastY(nan("")),
- m_moveto(true),
- m_initX(nan("")),
- m_initY(nan("")),
- m_has_init(false),
- m_was_clipped(false)
- {
- // empty
- }
-
- PathClipper(VertexSource &source, bool do_clipping, const agg::rect_base<double> &rect)
- : m_source(&source),
- m_do_clipping(do_clipping),
- m_cliprect(rect),
- m_lastX(nan("")),
- m_lastY(nan("")),
- m_moveto(true),
- m_initX(nan("")),
- m_initY(nan("")),
- m_has_init(false),
- m_was_clipped(false)
- {
- m_cliprect.x1 -= 1.0;
- m_cliprect.y1 -= 1.0;
- m_cliprect.x2 += 1.0;
- m_cliprect.y2 += 1.0;
- }
-
- inline void rewind(unsigned path_id)
- {
- m_has_init = false;
- m_was_clipped = false;
- m_moveto = true;
- m_source->rewind(path_id);
- }
-
- int draw_clipped_line(double x0, double y0, double x1, double y1,
- bool closed=false)
- {
- unsigned moved = agg::clip_line_segment(&x0, &y0, &x1, &y1, m_cliprect);
- // moved >= 4 - Fully clipped
- // moved & 1 != 0 - First point has been moved
- // moved & 2 != 0 - Second point has been moved
- m_was_clipped = m_was_clipped || (moved != 0);
- if (moved < 4) {
- if (moved & 1 || m_moveto) {
- queue_push(agg::path_cmd_move_to, x0, y0);
- }
- queue_push(agg::path_cmd_line_to, x1, y1);
- if (closed && !m_was_clipped) {
- // Close the path only if the end point hasn't moved.
- queue_push(agg::path_cmd_end_poly | agg::path_flags_close,
- x1, y1);
- }
-
- m_moveto = false;
- return 1;
- }
-
- return 0;
- }
-
- unsigned vertex(double *x, double *y)
- {
- unsigned code;
- bool emit_moveto = false;
-
- if (!m_do_clipping) {
- // If not doing any clipping, just pass along the vertices verbatim
- return m_source->vertex(x, y);
- }
-
- /* This is the slow path where we actually do clipping */
-
- if (queue_pop(&code, x, y)) {
- return code;
- }
-
- while ((code = m_source->vertex(x, y)) != agg::path_cmd_stop) {
- emit_moveto = false;
-
- switch (code) {
- case (agg::path_cmd_end_poly | agg::path_flags_close):
- if (m_has_init) {
- // Queue the line from last point to the initial point, and
- // if never clipped, add a close code.
- draw_clipped_line(m_lastX, m_lastY, m_initX, m_initY,
- true);
- } else {
- // An empty path that is immediately closed.
- queue_push(
- agg::path_cmd_end_poly | agg::path_flags_close,
- m_lastX, m_lastY);
- }
- // If paths were not clipped, then the above code queued
- // something, and we should exit the loop. Otherwise, continue
- // to the next point, as there may be a new subpath.
- if (queue_nonempty()) {
- goto exit_loop;
- }
- break;
-
- case agg::path_cmd_move_to:
-
- // was the last command a moveto (and we have
- // seen at least one command ?
- // if so, shove it in the queue if in clip box
- if (m_moveto && m_has_init &&
- m_lastX >= m_cliprect.x1 &&
- m_lastX <= m_cliprect.x2 &&
- m_lastY >= m_cliprect.y1 &&
- m_lastY <= m_cliprect.y2) {
- // push the last moveto onto the queue
- queue_push(agg::path_cmd_move_to, m_lastX, m_lastY);
- // flag that we need to emit it
- emit_moveto = true;
- }
- // update the internal state for this moveto
- m_initX = m_lastX = *x;
- m_initY = m_lastY = *y;
- m_has_init = true;
- m_moveto = true;
- m_was_clipped = false;
- // if the last command was moveto exit the loop to emit the code
- if (emit_moveto) {
- goto exit_loop;
- }
- // else, break and get the next point
- break;
-
- case agg::path_cmd_line_to:
- if (draw_clipped_line(m_lastX, m_lastY, *x, *y)) {
- m_lastX = *x;
- m_lastY = *y;
- goto exit_loop;
- }
- m_lastX = *x;
- m_lastY = *y;
- break;
-
- default:
- if (m_moveto) {
- queue_push(agg::path_cmd_move_to, m_lastX, m_lastY);
- m_moveto = false;
- }
-
- queue_push(code, *x, *y);
- m_lastX = *x;
- m_lastY = *y;
- goto exit_loop;
- }
- }
-
- exit_loop:
-
- if (queue_pop(&code, x, y)) {
- return code;
- }
-
- if (m_moveto && m_has_init &&
- m_lastX >= m_cliprect.x1 &&
- m_lastX <= m_cliprect.x2 &&
- m_lastY >= m_cliprect.y1 &&
- m_lastY <= m_cliprect.y2) {
- *x = m_lastX;
- *y = m_lastY;
- m_moveto = false;
- return agg::path_cmd_move_to;
- }
-
- return agg::path_cmd_stop;
- }
-};
-
-/************************************************************
- PathSnapper rounds vertices to their nearest center-pixels. This
- makes rectilinear paths (rectangles, horizontal and vertical lines
- etc.) look much cleaner.
-*/
-enum e_snap_mode {
- SNAP_AUTO,
- SNAP_FALSE,
- SNAP_TRUE
-};
-
-template <class VertexSource>
-class PathSnapper
-{
- private:
- VertexSource *m_source;
- bool m_snap;
- double m_snap_value;
-
- static bool should_snap(VertexSource &path, e_snap_mode snap_mode, unsigned total_vertices)
- {
- // If this contains only straight horizontal or vertical lines, it should be
- // snapped to the nearest pixels
- double x0 = 0, y0 = 0, x1 = 0, y1 = 0;
- unsigned code;
-
- switch (snap_mode) {
- case SNAP_AUTO:
- if (total_vertices > 1024) {
- return false;
- }
-
- code = path.vertex(&x0, &y0);
- if (code == agg::path_cmd_stop) {
- return false;
- }
-
- while ((code = path.vertex(&x1, &y1)) != agg::path_cmd_stop) {
- switch (code) {
- case agg::path_cmd_curve3:
- case agg::path_cmd_curve4:
- return false;
- case agg::path_cmd_line_to:
- if (fabs(x0 - x1) >= 1e-4 && fabs(y0 - y1) >= 1e-4) {
- return false;
- }
- }
- x0 = x1;
- y0 = y1;
- }
-
- return true;
- case SNAP_FALSE:
- return false;
- case SNAP_TRUE:
- return true;
- }
-
- return false;
- }
-
- public:
- /*
- snap_mode should be one of:
- - SNAP_AUTO: Examine the path to determine if it should be snapped
- - SNAP_TRUE: Force snapping
- - SNAP_FALSE: No snapping
- */
- PathSnapper(VertexSource &source,
- e_snap_mode snap_mode,
- unsigned total_vertices = 15,
- double stroke_width = 0.0)
- : m_source(&source)
- {
- m_snap = should_snap(source, snap_mode, total_vertices);
-
- if (m_snap) {
- int is_odd = mpl_round_to_int(stroke_width) % 2;
- m_snap_value = (is_odd) ? 0.5 : 0.0;
- }
-
- source.rewind(0);
- }
-
- inline void rewind(unsigned path_id)
- {
- m_source->rewind(path_id);
- }
-
- inline unsigned vertex(double *x, double *y)
- {
- unsigned code;
- code = m_source->vertex(x, y);
- if (m_snap && agg::is_vertex(code)) {
- *x = floor(*x + 0.5) + m_snap_value;
- *y = floor(*y + 0.5) + m_snap_value;
- }
- return code;
- }
-
- inline bool is_snapping()
- {
- return m_snap;
- }
-};
-
-/************************************************************
- PathSimplifier reduces the number of vertices in a dense path without
- changing its appearance.
-*/
-template <class VertexSource>
-class PathSimplifier : protected EmbeddedQueue<9>
-{
- public:
- /* Set simplify to true to perform simplification */
- PathSimplifier(VertexSource &source, bool do_simplify, double simplify_threshold)
- : m_source(&source),
- m_simplify(do_simplify),
- /* we square simplify_threshold so that we can compute
- norms without doing the square root every step. */
- m_simplify_threshold(simplify_threshold * simplify_threshold),
-
- m_moveto(true),
- m_after_moveto(false),
- m_clipped(false),
-
- // the x, y values from last iteration
- m_lastx(0.0),
- m_lasty(0.0),
-
- // the dx, dy comprising the original vector, used in conjunction
- // with m_currVecStart* to define the original vector.
- m_origdx(0.0),
- m_origdy(0.0),
-
- // the squared norm of the original vector
- m_origdNorm2(0.0),
-
- // maximum squared norm of vector in forward (parallel) direction
- m_dnorm2ForwardMax(0.0),
- // maximum squared norm of vector in backward (anti-parallel) direction
- m_dnorm2BackwardMax(0.0),
-
- // was the last point the furthest from lastWritten in the
- // forward (parallel) direction?
- m_lastForwardMax(false),
- // was the last point the furthest from lastWritten in the
- // backward (anti-parallel) direction?
- m_lastBackwardMax(false),
-
- // added to queue when _push is called
- m_nextX(0.0),
- m_nextY(0.0),
-
- // added to queue when _push is called if any backwards
- // (anti-parallel) vectors were observed
- m_nextBackwardX(0.0),
- m_nextBackwardY(0.0),
-
- // start of the current vector that is being simplified
- m_currVecStartX(0.0),
- m_currVecStartY(0.0)
- {
- // empty
- }
-
- inline void rewind(unsigned path_id)
- {
- queue_clear();
- m_moveto = true;
- m_source->rewind(path_id);
- }
-
- unsigned vertex(double *x, double *y)
- {
- unsigned cmd;
-
- /* The simplification algorithm doesn't support curves or compound paths
- so we just don't do it at all in that case... */
- if (!m_simplify) {
- return m_source->vertex(x, y);
- }
-
- /* idea: we can skip drawing many lines: we can combine
- sequential parallel lines into a
- single line instead of redrawing lines over the same
- points. The loop below works a bit like a state machine,
- where what it does depends on what it did in the last
- looping. To test whether sequential lines are close to
- parallel, I calculate the distance moved perpendicular to
- the last line. Once it gets too big, the lines cannot be
- combined. */
-
- /* This code was originally written by Allan Haldane and I
- have modified to work in-place -- meaning not creating an
- entirely new path list each time. In order to do that
- without too much additional code complexity, it keeps a
- small queue around so that multiple points can be emitted
- in a single call, and those points will be popped from the
- queue in subsequent calls. The following block will empty
- the queue before proceeding to the main loop below.
- -- Michael Droettboom */
-
- /* This code was originally written by Allan Haldane and
- updated by Michael Droettboom. I have modified it to
- handle anti-parallel vectors. This is done essentially
- the same way as parallel vectors, but requires a little
- additional book-keeping to track whether or not we have
- observed an anti-parallel vector during the current run.
- -- Kevin Rose */
-
- if (queue_pop(&cmd, x, y)) {
- return cmd;
- }
-
- /* The main simplification loop. The point is to consume only
- as many points as necessary until something has been added
- to the outbound queue, not to run through the entire path
- in one go. This eliminates the need to allocate and fill
- an entire additional path array on each draw. */
- while ((cmd = m_source->vertex(x, y)) != agg::path_cmd_stop) {
- /* if we are starting a new path segment, move to the first point
- + init */
-
- if (m_moveto || cmd == agg::path_cmd_move_to) {
- /* m_moveto check is not generally needed because
- m_source generates an initial moveto; but it is
- retained for safety in case circumstances arise
- where this is not true. */
- if (m_origdNorm2 != 0.0 && !m_after_moveto) {
- /* m_origdNorm2 is nonzero only if we have a
- vector; the m_after_moveto check ensures we
- push this vector to the queue only once. */
- _push(x, y);
- }
- m_after_moveto = true;
- m_lastx = *x;
- m_lasty = *y;
- m_moveto = false;
- m_origdNorm2 = 0.0;
- m_dnorm2BackwardMax = 0.0;
- m_clipped = true;
- if (queue_nonempty()) {
- /* If we did a push, empty the queue now. */
- break;
- }
- continue;
- }
- m_after_moveto = false;
-
- /* NOTE: We used to skip this very short segments, but if
- you have a lot of them cumulatively, you can miss
- maxima or minima in the data. */
-
- /* Don't render line segments less than one pixel long */
- /* if (fabs(*x - m_lastx) < 1.0 && fabs(*y - m_lasty) < 1.0) */
- /* { */
- /* continue; */
- /* } */
-
- /* if we have no orig vector, set it to this vector and
- continue. this orig vector is the reference vector we
- will build up the line to */
- if (m_origdNorm2 == 0.0) {
- if (m_clipped) {
- queue_push(agg::path_cmd_move_to, m_lastx, m_lasty);
- m_clipped = false;
- }
-
- m_origdx = *x - m_lastx;
- m_origdy = *y - m_lasty;
- m_origdNorm2 = m_origdx * m_origdx + m_origdy * m_origdy;
-
- // set all the variables to reflect this new orig vector
- m_dnorm2ForwardMax = m_origdNorm2;
- m_dnorm2BackwardMax = 0.0;
- m_lastForwardMax = true;
- m_lastBackwardMax = false;
-
- m_currVecStartX = m_lastx;
- m_currVecStartY = m_lasty;
- m_nextX = m_lastx = *x;
- m_nextY = m_lasty = *y;
- continue;
- }
-
- /* If got to here, then we have an orig vector and we just got
- a vector in the sequence. */
-
- /* Check that the perpendicular distance we have moved
- from the last written point compared to the line we are
- building is not too much. If o is the orig vector (we
- are building on), and v is the vector from the last
- written point to the current point, then the
- perpendicular vector is p = v - (o.v)o/(o.o)
- (here, a.b indicates the dot product of a and b). */
-
- /* get the v vector */
- double totdx = *x - m_currVecStartX;
- double totdy = *y - m_currVecStartY;
-
- /* get the dot product o.v */
- double totdot = m_origdx * totdx + m_origdy * totdy;
-
- /* get the para vector ( = (o.v)o/(o.o)) */
- double paradx = totdot * m_origdx / m_origdNorm2;
- double parady = totdot * m_origdy / m_origdNorm2;
-
- /* get the perp vector ( = v - para) */
- double perpdx = totdx - paradx;
- double perpdy = totdy - parady;
-
- /* get the squared norm of perp vector ( = p.p) */
- double perpdNorm2 = perpdx * perpdx + perpdy * perpdy;
-
- /* If the perpendicular vector is less than
- m_simplify_threshold pixels in size, then merge
- current x,y with the current vector */
- if (perpdNorm2 < m_simplify_threshold) {
- /* check if the current vector is parallel or
- anti-parallel to the orig vector. In either case,
- test if it is the longest of the vectors
- we are merging in that direction. If it is, then
- update the current vector in that direction. */
- double paradNorm2 = paradx * paradx + parady * parady;
-
- m_lastForwardMax = false;
- m_lastBackwardMax = false;
- if (totdot > 0.0) {
- if (paradNorm2 > m_dnorm2ForwardMax) {
- m_lastForwardMax = true;
- m_dnorm2ForwardMax = paradNorm2;
- m_nextX = *x;
- m_nextY = *y;
- }
- } else {
- if (paradNorm2 > m_dnorm2BackwardMax) {
- m_lastBackwardMax = true;
- m_dnorm2BackwardMax = paradNorm2;
- m_nextBackwardX = *x;
- m_nextBackwardY = *y;
- }
- }
-
- m_lastx = *x;
- m_lasty = *y;
- continue;
- }
-
- /* If we get here, then this vector was not similar enough to the
- line we are building, so we need to draw that line and start the
- next one. */
-
- /* If the line needs to extend in the opposite direction from the
- direction we are drawing in, move back to we start drawing from
- back there. */
- _push(x, y);
-
- break;
- }
-
- /* Fill the queue with the remaining vertices if we've finished the
- path in the above loop. */
- if (cmd == agg::path_cmd_stop) {
- if (m_origdNorm2 != 0.0) {
- queue_push((m_moveto || m_after_moveto) ? agg::path_cmd_move_to
- : agg::path_cmd_line_to,
- m_nextX,
- m_nextY);
- if (m_dnorm2BackwardMax > 0.0) {
- queue_push((m_moveto || m_after_moveto) ? agg::path_cmd_move_to
- : agg::path_cmd_line_to,
- m_nextBackwardX,
- m_nextBackwardY);
- }
- m_moveto = false;
- }
- queue_push((m_moveto || m_after_moveto) ? agg::path_cmd_move_to : agg::path_cmd_line_to,
- m_lastx,
- m_lasty);
- m_moveto = false;
- queue_push(agg::path_cmd_stop, 0.0, 0.0);
- }
-
- /* Return the first item in the queue, if any, otherwise
- indicate that we're done. */
- if (queue_pop(&cmd, x, y)) {
- return cmd;
- } else {
- return agg::path_cmd_stop;
- }
- }
-
- private:
- VertexSource *m_source;
- bool m_simplify;
- double m_simplify_threshold;
-
- bool m_moveto;
- bool m_after_moveto;
- bool m_clipped;
- double m_lastx, m_lasty;
-
- double m_origdx;
- double m_origdy;
- double m_origdNorm2;
- double m_dnorm2ForwardMax;
- double m_dnorm2BackwardMax;
- bool m_lastForwardMax;
- bool m_lastBackwardMax;
- double m_nextX;
- double m_nextY;
- double m_nextBackwardX;
- double m_nextBackwardY;
- double m_currVecStartX;
- double m_currVecStartY;
-
- inline void _push(double *x, double *y)
- {
- bool needToPushBack = (m_dnorm2BackwardMax > 0.0);
-
- /* If we observed any backward (anti-parallel) vectors, then
- we need to push both forward and backward vectors. */
- if (needToPushBack) {
- /* If the last vector seen was the maximum in the forward direction,
- then we need to push the forward after the backward. Otherwise,
- the last vector seen was the maximum in the backward direction,
- or somewhere in between, either way we are safe pushing forward
- before backward. */
- if (m_lastForwardMax) {
- queue_push(agg::path_cmd_line_to, m_nextBackwardX, m_nextBackwardY);
- queue_push(agg::path_cmd_line_to, m_nextX, m_nextY);
- } else {
- queue_push(agg::path_cmd_line_to, m_nextX, m_nextY);
- queue_push(agg::path_cmd_line_to, m_nextBackwardX, m_nextBackwardY);
- }
- } else {
- /* If we did not observe any backwards vectors, just push forward. */
- queue_push(agg::path_cmd_line_to, m_nextX, m_nextY);
- }
-
- /* If we clipped some segments between this line and the next line
- we are starting, we also need to move to the last point. */
- if (m_clipped) {
- queue_push(agg::path_cmd_move_to, m_lastx, m_lasty);
- } else if ((!m_lastForwardMax) && (!m_lastBackwardMax)) {
- /* If the last line was not the longest line, then move
- back to the end point of the last line in the
- sequence. Only do this if not clipped, since in that
- case lastx,lasty is not part of the line just drawn. */
-
- /* Would be move_to if not for the artifacts */
- queue_push(agg::path_cmd_line_to, m_lastx, m_lasty);
- }
-
- /* Now reset all the variables to get ready for the next line */
- m_origdx = *x - m_lastx;
- m_origdy = *y - m_lasty;
- m_origdNorm2 = m_origdx * m_origdx + m_origdy * m_origdy;
-
- m_dnorm2ForwardMax = m_origdNorm2;
- m_lastForwardMax = true;
- m_currVecStartX = m_queue[m_queue_write - 1].x;
- m_currVecStartY = m_queue[m_queue_write - 1].y;
- m_lastx = m_nextX = *x;
- m_lasty = m_nextY = *y;
- m_dnorm2BackwardMax = 0.0;
- m_lastBackwardMax = false;
-
- m_clipped = false;
- }
-};
-
-template <class VertexSource>
-class Sketch
-{
- public:
- /*
- scale: the scale of the wiggle perpendicular to the original
- line (in pixels)
-
- length: the base wavelength of the wiggle along the
- original line (in pixels)
-
- randomness: the factor that the sketch length will randomly
- shrink and expand.
- */
- Sketch(VertexSource &source, double scale, double length, double randomness)
- : m_source(&source),
- m_scale(scale),
- m_length(length),
- m_randomness(randomness),
- m_segmented(source),
- m_last_x(0.0),
- m_last_y(0.0),
- m_has_last(false),
- m_p(0.0),
- m_rand(0)
- {
- rewind(0);
- const double d_M_PI = 3.14159265358979323846;
- m_p_scale = (2.0 * d_M_PI) / (m_length * m_randomness);
- m_log_randomness = 2.0 * log(m_randomness);
- }
-
- unsigned vertex(double *x, double *y)
- {
- if (m_scale == 0.0) {
- return m_source->vertex(x, y);
- }
-
- unsigned code = m_segmented.vertex(x, y);
-
- if (code == agg::path_cmd_move_to) {
- m_has_last = false;
- m_p = 0.0;
- }
-
- if (m_has_last) {
- // We want the "cursor" along the sine wave to move at a
- // random rate.
- double d_rand = m_rand.get_double();
- // Original computation
- // p += pow(k, 2*rand - 1)
- // r = sin(p * c)
- // x86 computes pow(a, b) as exp(b*log(a))
- // First, move -1 out, so
- // p' += pow(k, 2*rand)
- // r = sin(p * c') where c' = c / k
- // Next, use x86 logic (will not be worse on other platforms as
- // the log is only computed once and pow and exp are, at worst,
- // the same)
- // So p+= exp(2*rand*log(k))
- // lk = 2*log(k)
- // p += exp(rand*lk)
- m_p += exp(d_rand * m_log_randomness);
- double den = m_last_x - *x;
- double num = m_last_y - *y;
- double len = num * num + den * den;
- m_last_x = *x;
- m_last_y = *y;
- if (len != 0) {
- len = sqrt(len);
- double r = sin(m_p * m_p_scale) * m_scale;
- double roverlen = r / len;
- *x += roverlen * num;
- *y -= roverlen * den;
- }
- } else {
- m_last_x = *x;
- m_last_y = *y;
- }
-
- m_has_last = true;
-
- return code;
- }
-
- inline void rewind(unsigned path_id)
- {
- m_has_last = false;
- m_p = 0.0;
- if (m_scale != 0.0) {
- m_rand.seed(0);
- m_segmented.rewind(path_id);
- } else {
- m_source->rewind(path_id);
- }
- }
-
- private:
- VertexSource *m_source;
- double m_scale;
- double m_length;
- double m_randomness;
- agg::conv_segmentator<VertexSource> m_segmented;
- double m_last_x;
- double m_last_y;
- bool m_has_last;
- double m_p;
- RandomNumberGenerator m_rand;
- double m_p_scale;
- double m_log_randomness;
-};
-
-#endif // MPL_PATH_CONVERTERS_H
diff --git a/contrib/python/matplotlib/py3/src/py_adaptors.h b/contrib/python/matplotlib/py3/src/py_adaptors.h
deleted file mode 100644
index 7722137dc6..0000000000
--- a/contrib/python/matplotlib/py3/src/py_adaptors.h
+++ /dev/null
@@ -1,248 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef MPL_PY_ADAPTORS_H
-#define MPL_PY_ADAPTORS_H
-#define PY_SSIZE_T_CLEAN
-/***************************************************************************
- * This module contains a number of C++ classes that adapt Python data
- * structures to C++ and Agg-friendly interfaces.
- */
-
-#include <Python.h>
-
-#include "numpy/arrayobject.h"
-
-#include "py_exceptions.h"
-
-extern "C" {
-int convert_path(PyObject *obj, void *pathp);
-}
-
-namespace py
-{
-
-/************************************************************
- * py::PathIterator acts as a bridge between Numpy and Agg. Given a
- * pair of Numpy arrays, vertices and codes, it iterates over
- * those vertices and codes, using the standard Agg vertex source
- * interface:
- *
- * unsigned vertex(double* x, double* y)
- */
-class PathIterator
-{
- /* We hold references to the Python objects, not just the
- underlying data arrays, so that Python reference counting
- can work.
- */
- PyArrayObject *m_vertices;
- PyArrayObject *m_codes;
-
- unsigned m_iterator;
- unsigned m_total_vertices;
-
- /* This class doesn't actually do any simplification, but we
- store the value here, since it is obtained from the Python
- object.
- */
- bool m_should_simplify;
- double m_simplify_threshold;
-
- public:
- inline PathIterator()
- : m_vertices(NULL),
- m_codes(NULL),
- m_iterator(0),
- m_total_vertices(0),
- m_should_simplify(false),
- m_simplify_threshold(1.0 / 9.0)
- {
- }
-
- inline PathIterator(PyObject *vertices,
- PyObject *codes,
- bool should_simplify,
- double simplify_threshold)
- : m_vertices(NULL), m_codes(NULL), m_iterator(0)
- {
- if (!set(vertices, codes, should_simplify, simplify_threshold))
- throw py::exception();
- }
-
- inline PathIterator(PyObject *vertices, PyObject *codes)
- : m_vertices(NULL), m_codes(NULL), m_iterator(0)
- {
- if (!set(vertices, codes))
- throw py::exception();
- }
-
- inline PathIterator(const PathIterator &other)
- {
- Py_XINCREF(other.m_vertices);
- m_vertices = other.m_vertices;
-
- Py_XINCREF(other.m_codes);
- m_codes = other.m_codes;
-
- m_iterator = 0;
- m_total_vertices = other.m_total_vertices;
-
- m_should_simplify = other.m_should_simplify;
- m_simplify_threshold = other.m_simplify_threshold;
- }
-
- ~PathIterator()
- {
- Py_XDECREF(m_vertices);
- Py_XDECREF(m_codes);
- }
-
- inline int
- set(PyObject *vertices, PyObject *codes, bool should_simplify, double simplify_threshold)
- {
- m_should_simplify = should_simplify;
- m_simplify_threshold = simplify_threshold;
-
- Py_XDECREF(m_vertices);
- m_vertices = (PyArrayObject *)PyArray_FromObject(vertices, NPY_DOUBLE, 2, 2);
-
- if (!m_vertices || PyArray_DIM(m_vertices, 1) != 2) {
- PyErr_SetString(PyExc_ValueError, "Invalid vertices array");
- return 0;
- }
-
- Py_XDECREF(m_codes);
- m_codes = NULL;
-
- if (codes != NULL && codes != Py_None) {
- m_codes = (PyArrayObject *)PyArray_FromObject(codes, NPY_UINT8, 1, 1);
-
- if (!m_codes || PyArray_DIM(m_codes, 0) != PyArray_DIM(m_vertices, 0)) {
- PyErr_SetString(PyExc_ValueError, "Invalid codes array");
- return 0;
- }
- }
-
- m_total_vertices = (unsigned)PyArray_DIM(m_vertices, 0);
- m_iterator = 0;
-
- return 1;
- }
-
- inline int set(PyObject *vertices, PyObject *codes)
- {
- return set(vertices, codes, false, 0.0);
- }
-
- inline unsigned vertex(double *x, double *y)
- {
- if (m_iterator >= m_total_vertices) {
- *x = 0.0;
- *y = 0.0;
- return agg::path_cmd_stop;
- }
-
- const size_t idx = m_iterator++;
-
- char *pair = (char *)PyArray_GETPTR2(m_vertices, idx, 0);
- *x = *(double *)pair;
- *y = *(double *)(pair + PyArray_STRIDE(m_vertices, 1));
-
- if (m_codes != NULL) {
- return (unsigned)(*(char *)PyArray_GETPTR1(m_codes, idx));
- } else {
- return idx == 0 ? agg::path_cmd_move_to : agg::path_cmd_line_to;
- }
- }
-
- inline void rewind(unsigned path_id)
- {
- m_iterator = path_id;
- }
-
- inline unsigned total_vertices() const
- {
- return m_total_vertices;
- }
-
- inline bool should_simplify() const
- {
- return m_should_simplify;
- }
-
- inline double simplify_threshold() const
- {
- return m_simplify_threshold;
- }
-
- inline bool has_codes() const
- {
- return m_codes != NULL;
- }
-
- inline void *get_id()
- {
- return (void *)m_vertices;
- }
-};
-
-class PathGenerator
-{
- PyObject *m_paths;
- Py_ssize_t m_npaths;
-
- public:
- typedef PathIterator path_iterator;
-
- PathGenerator() : m_paths(NULL), m_npaths(0) {}
-
- ~PathGenerator()
- {
- Py_XDECREF(m_paths);
- }
-
- int set(PyObject *obj)
- {
- if (!PySequence_Check(obj)) {
- return 0;
- }
-
- Py_XDECREF(m_paths);
- m_paths = obj;
- Py_INCREF(m_paths);
-
- m_npaths = PySequence_Size(m_paths);
-
- return 1;
- }
-
- Py_ssize_t num_paths() const
- {
- return m_npaths;
- }
-
- Py_ssize_t size() const
- {
- return m_npaths;
- }
-
- path_iterator operator()(size_t i)
- {
- path_iterator path;
- PyObject *item;
-
- item = PySequence_GetItem(m_paths, i % m_npaths);
- if (item == NULL) {
- throw py::exception();
- }
- if (!convert_path(item, &path)) {
- Py_DECREF(item);
- throw py::exception();
- }
- Py_DECREF(item);
- return path;
- }
-};
-}
-
-#endif
diff --git a/contrib/python/matplotlib/py3/src/py_converters.cpp b/contrib/python/matplotlib/py3/src/py_converters.cpp
deleted file mode 100644
index 04382c5f94..0000000000
--- a/contrib/python/matplotlib/py3/src/py_converters.cpp
+++ /dev/null
@@ -1,558 +0,0 @@
-#define NO_IMPORT_ARRAY
-#define PY_SSIZE_T_CLEAN
-#include "py_converters.h"
-#include "numpy_cpp.h"
-
-#include "agg_basics.h"
-#include "agg_color_rgba.h"
-#include "agg_math_stroke.h"
-
-extern "C" {
-
-static int convert_string_enum(PyObject *obj, const char *name, const char **names, int *values, int *result)
-{
- PyObject *bytesobj;
- char *str;
-
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- if (PyUnicode_Check(obj)) {
- bytesobj = PyUnicode_AsASCIIString(obj);
- if (bytesobj == NULL) {
- return 0;
- }
- } else if (PyBytes_Check(obj)) {
- Py_INCREF(obj);
- bytesobj = obj;
- } else {
- PyErr_Format(PyExc_TypeError, "%s must be str or bytes", name);
- return 0;
- }
-
- str = PyBytes_AsString(bytesobj);
- if (str == NULL) {
- Py_DECREF(bytesobj);
- return 0;
- }
-
- for ( ; *names != NULL; names++, values++) {
- if (strncmp(str, *names, 64) == 0) {
- *result = *values;
- Py_DECREF(bytesobj);
- return 1;
- }
- }
-
- PyErr_Format(PyExc_ValueError, "invalid %s value", name);
- Py_DECREF(bytesobj);
- return 0;
-}
-
-int convert_from_method(PyObject *obj, const char *name, converter func, void *p)
-{
- PyObject *value;
-
- value = PyObject_CallMethod(obj, name, NULL);
- if (value == NULL) {
- if (!PyObject_HasAttrString(obj, name)) {
- PyErr_Clear();
- return 1;
- }
- return 0;
- }
-
- if (!func(value, p)) {
- Py_DECREF(value);
- return 0;
- }
-
- Py_DECREF(value);
- return 1;
-}
-
-int convert_from_attr(PyObject *obj, const char *name, converter func, void *p)
-{
- PyObject *value;
-
- value = PyObject_GetAttrString(obj, name);
- if (value == NULL) {
- if (!PyObject_HasAttrString(obj, name)) {
- PyErr_Clear();
- return 1;
- }
- return 0;
- }
-
- if (!func(value, p)) {
- Py_DECREF(value);
- return 0;
- }
-
- Py_DECREF(value);
- return 1;
-}
-
-int convert_double(PyObject *obj, void *p)
-{
- double *val = (double *)p;
-
- *val = PyFloat_AsDouble(obj);
- if (PyErr_Occurred()) {
- return 0;
- }
-
- return 1;
-}
-
-int convert_bool(PyObject *obj, void *p)
-{
- bool *val = (bool *)p;
- switch (PyObject_IsTrue(obj)) {
- case 0: *val = false; break;
- case 1: *val = true; break;
- default: return 0; // errored.
- }
- return 1;
-}
-
-int convert_cap(PyObject *capobj, void *capp)
-{
- const char *names[] = {"butt", "round", "projecting", NULL};
- int values[] = {agg::butt_cap, agg::round_cap, agg::square_cap};
- int result = agg::butt_cap;
-
- if (!convert_string_enum(capobj, "capstyle", names, values, &result)) {
- return 0;
- }
-
- *(agg::line_cap_e *)capp = (agg::line_cap_e)result;
- return 1;
-}
-
-int convert_join(PyObject *joinobj, void *joinp)
-{
- const char *names[] = {"miter", "round", "bevel", NULL};
- int values[] = {agg::miter_join_revert, agg::round_join, agg::bevel_join};
- int result = agg::miter_join_revert;
-
- if (!convert_string_enum(joinobj, "joinstyle", names, values, &result)) {
- return 0;
- }
-
- *(agg::line_join_e *)joinp = (agg::line_join_e)result;
- return 1;
-}
-
-int convert_rect(PyObject *rectobj, void *rectp)
-{
- agg::rect_d *rect = (agg::rect_d *)rectp;
-
- if (rectobj == NULL || rectobj == Py_None) {
- rect->x1 = 0.0;
- rect->y1 = 0.0;
- rect->x2 = 0.0;
- rect->y2 = 0.0;
- } else {
- PyArrayObject *rect_arr = (PyArrayObject *)PyArray_ContiguousFromAny(
- rectobj, NPY_DOUBLE, 1, 2);
- if (rect_arr == NULL) {
- return 0;
- }
-
- if (PyArray_NDIM(rect_arr) == 2) {
- if (PyArray_DIM(rect_arr, 0) != 2 ||
- PyArray_DIM(rect_arr, 1) != 2) {
- PyErr_SetString(PyExc_ValueError, "Invalid bounding box");
- Py_DECREF(rect_arr);
- return 0;
- }
-
- } else { // PyArray_NDIM(rect_arr) == 1
- if (PyArray_DIM(rect_arr, 0) != 4) {
- PyErr_SetString(PyExc_ValueError, "Invalid bounding box");
- Py_DECREF(rect_arr);
- return 0;
- }
- }
-
- double *buff = (double *)PyArray_DATA(rect_arr);
- rect->x1 = buff[0];
- rect->y1 = buff[1];
- rect->x2 = buff[2];
- rect->y2 = buff[3];
-
- Py_DECREF(rect_arr);
- }
- return 1;
-}
-
-int convert_rgba(PyObject *rgbaobj, void *rgbap)
-{
- agg::rgba *rgba = (agg::rgba *)rgbap;
- PyObject *rgbatuple = NULL;
- int success = 1;
- if (rgbaobj == NULL || rgbaobj == Py_None) {
- rgba->r = 0.0;
- rgba->g = 0.0;
- rgba->b = 0.0;
- rgba->a = 0.0;
- } else {
- if (!(rgbatuple = PySequence_Tuple(rgbaobj))) {
- success = 0;
- goto exit;
- }
- rgba->a = 1.0;
- if (!PyArg_ParseTuple(
- rgbatuple, "ddd|d:rgba", &(rgba->r), &(rgba->g), &(rgba->b), &(rgba->a))) {
- success = 0;
- goto exit;
- }
- }
-exit:
- Py_XDECREF(rgbatuple);
- return success;
-}
-
-int convert_dashes(PyObject *dashobj, void *dashesp)
-{
- Dashes *dashes = (Dashes *)dashesp;
-
- double dash_offset = 0.0;
- PyObject *dashes_seq = NULL;
-
- if (!PyArg_ParseTuple(dashobj, "dO:dashes", &dash_offset, &dashes_seq)) {
- return 0;
- }
-
- if (dashes_seq == Py_None) {
- return 1;
- }
-
- if (!PySequence_Check(dashes_seq)) {
- PyErr_SetString(PyExc_TypeError, "Invalid dashes sequence");
- return 0;
- }
-
- Py_ssize_t nentries = PySequence_Size(dashes_seq);
- // If the dashpattern has odd length, iterate through it twice (in
- // accordance with the pdf/ps/svg specs).
- Py_ssize_t dash_pattern_length = (nentries % 2) ? 2 * nentries : nentries;
-
- for (Py_ssize_t i = 0; i < dash_pattern_length; ++i) {
- PyObject *item;
- double length;
- double skip;
-
- item = PySequence_GetItem(dashes_seq, i % nentries);
- if (item == NULL) {
- return 0;
- }
- length = PyFloat_AsDouble(item);
- if (PyErr_Occurred()) {
- Py_DECREF(item);
- return 0;
- }
- Py_DECREF(item);
-
- ++i;
-
- item = PySequence_GetItem(dashes_seq, i % nentries);
- if (item == NULL) {
- return 0;
- }
- skip = PyFloat_AsDouble(item);
- if (PyErr_Occurred()) {
- Py_DECREF(item);
- return 0;
- }
- Py_DECREF(item);
-
- dashes->add_dash_pair(length, skip);
- }
-
- dashes->set_dash_offset(dash_offset);
-
- return 1;
-}
-
-int convert_dashes_vector(PyObject *obj, void *dashesp)
-{
- DashesVector *dashes = (DashesVector *)dashesp;
-
- if (!PySequence_Check(obj)) {
- return 0;
- }
-
- Py_ssize_t n = PySequence_Size(obj);
-
- for (Py_ssize_t i = 0; i < n; ++i) {
- PyObject *item;
- Dashes subdashes;
-
- item = PySequence_GetItem(obj, i);
- if (item == NULL) {
- return 0;
- }
-
- if (!convert_dashes(item, &subdashes)) {
- Py_DECREF(item);
- return 0;
- }
- Py_DECREF(item);
-
- dashes->push_back(subdashes);
- }
-
- return 1;
-}
-
-int convert_trans_affine(PyObject *obj, void *transp)
-{
- agg::trans_affine *trans = (agg::trans_affine *)transp;
-
- /** If None assume identity transform. */
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- PyArrayObject *array = (PyArrayObject *)PyArray_ContiguousFromAny(obj, NPY_DOUBLE, 2, 2);
- if (array == NULL) {
- return 0;
- }
-
- if (PyArray_DIM(array, 0) == 3 && PyArray_DIM(array, 1) == 3) {
- double *buffer = (double *)PyArray_DATA(array);
- trans->sx = buffer[0];
- trans->shx = buffer[1];
- trans->tx = buffer[2];
-
- trans->shy = buffer[3];
- trans->sy = buffer[4];
- trans->ty = buffer[5];
-
- Py_DECREF(array);
- return 1;
- }
-
- Py_DECREF(array);
- PyErr_SetString(PyExc_ValueError, "Invalid affine transformation matrix");
- return 0;
-}
-
-int convert_path(PyObject *obj, void *pathp)
-{
- py::PathIterator *path = (py::PathIterator *)pathp;
-
- PyObject *vertices_obj = NULL;
- PyObject *codes_obj = NULL;
- PyObject *should_simplify_obj = NULL;
- PyObject *simplify_threshold_obj = NULL;
- bool should_simplify;
- double simplify_threshold;
-
- int status = 0;
-
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- vertices_obj = PyObject_GetAttrString(obj, "vertices");
- if (vertices_obj == NULL) {
- goto exit;
- }
-
- codes_obj = PyObject_GetAttrString(obj, "codes");
- if (codes_obj == NULL) {
- goto exit;
- }
-
- should_simplify_obj = PyObject_GetAttrString(obj, "should_simplify");
- if (should_simplify_obj == NULL) {
- goto exit;
- }
- switch (PyObject_IsTrue(should_simplify_obj)) {
- case 0: should_simplify = 0; break;
- case 1: should_simplify = 1; break;
- default: goto exit; // errored.
- }
-
- simplify_threshold_obj = PyObject_GetAttrString(obj, "simplify_threshold");
- if (simplify_threshold_obj == NULL) {
- goto exit;
- }
- simplify_threshold = PyFloat_AsDouble(simplify_threshold_obj);
- if (PyErr_Occurred()) {
- goto exit;
- }
-
- if (!path->set(vertices_obj, codes_obj, should_simplify, simplify_threshold)) {
- goto exit;
- }
-
- status = 1;
-
-exit:
- Py_XDECREF(vertices_obj);
- Py_XDECREF(codes_obj);
- Py_XDECREF(should_simplify_obj);
- Py_XDECREF(simplify_threshold_obj);
-
- return status;
-}
-
-int convert_pathgen(PyObject *obj, void *pathgenp)
-{
- py::PathGenerator *paths = (py::PathGenerator *)pathgenp;
- if (!paths->set(obj)) {
- PyErr_SetString(PyExc_TypeError, "Not an iterable of paths");
- return 0;
- }
- return 1;
-}
-
-int convert_clippath(PyObject *clippath_tuple, void *clippathp)
-{
- ClipPath *clippath = (ClipPath *)clippathp;
- py::PathIterator path;
- agg::trans_affine trans;
-
- if (clippath_tuple != NULL && clippath_tuple != Py_None) {
- if (!PyArg_ParseTuple(clippath_tuple,
- "O&O&:clippath",
- &convert_path,
- &clippath->path,
- &convert_trans_affine,
- &clippath->trans)) {
- return 0;
- }
- }
-
- return 1;
-}
-
-int convert_snap(PyObject *obj, void *snapp)
-{
- e_snap_mode *snap = (e_snap_mode *)snapp;
- if (obj == NULL || obj == Py_None) {
- *snap = SNAP_AUTO;
- } else {
- switch (PyObject_IsTrue(obj)) {
- case 0: *snap = SNAP_FALSE; break;
- case 1: *snap = SNAP_TRUE; break;
- default: return 0; // errored.
- }
- }
- return 1;
-}
-
-int convert_sketch_params(PyObject *obj, void *sketchp)
-{
- SketchParams *sketch = (SketchParams *)sketchp;
-
- if (obj == NULL || obj == Py_None) {
- sketch->scale = 0.0;
- } else if (!PyArg_ParseTuple(obj,
- "ddd:sketch_params",
- &sketch->scale,
- &sketch->length,
- &sketch->randomness)) {
- return 0;
- }
-
- return 1;
-}
-
-int convert_gcagg(PyObject *pygc, void *gcp)
-{
- GCAgg *gc = (GCAgg *)gcp;
-
- if (!(convert_from_attr(pygc, "_linewidth", &convert_double, &gc->linewidth) &&
- convert_from_attr(pygc, "_alpha", &convert_double, &gc->alpha) &&
- convert_from_attr(pygc, "_forced_alpha", &convert_bool, &gc->forced_alpha) &&
- convert_from_attr(pygc, "_rgb", &convert_rgba, &gc->color) &&
- convert_from_attr(pygc, "_antialiased", &convert_bool, &gc->isaa) &&
- convert_from_attr(pygc, "_capstyle", &convert_cap, &gc->cap) &&
- convert_from_attr(pygc, "_joinstyle", &convert_join, &gc->join) &&
- convert_from_method(pygc, "get_dashes", &convert_dashes, &gc->dashes) &&
- convert_from_attr(pygc, "_cliprect", &convert_rect, &gc->cliprect) &&
- convert_from_method(pygc, "get_clip_path", &convert_clippath, &gc->clippath) &&
- convert_from_method(pygc, "get_snap", &convert_snap, &gc->snap_mode) &&
- convert_from_method(pygc, "get_hatch_path", &convert_path, &gc->hatchpath) &&
- convert_from_method(pygc, "get_hatch_color", &convert_rgba, &gc->hatch_color) &&
- convert_from_method(pygc, "get_hatch_linewidth", &convert_double, &gc->hatch_linewidth) &&
- convert_from_method(pygc, "get_sketch_params", &convert_sketch_params, &gc->sketch))) {
- return 0;
- }
-
- return 1;
-}
-
-int convert_face(PyObject *color, GCAgg &gc, agg::rgba *rgba)
-{
- if (!convert_rgba(color, rgba)) {
- return 0;
- }
-
- if (color != NULL && color != Py_None) {
- if (gc.forced_alpha || PySequence_Size(color) == 3) {
- rgba->a = gc.alpha;
- }
- }
-
- return 1;
-}
-
-int convert_points(PyObject *obj, void *pointsp)
-{
- numpy::array_view<double, 2> *points = (numpy::array_view<double, 2> *)pointsp;
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
- if (!points->set(obj)
- || (points->size() && !check_trailing_shape(*points, "points", 2))) {
- return 0;
- }
- return 1;
-}
-
-int convert_transforms(PyObject *obj, void *transp)
-{
- numpy::array_view<double, 3> *trans = (numpy::array_view<double, 3> *)transp;
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
- if (!trans->set(obj)
- || (trans->size() && !check_trailing_shape(*trans, "transforms", 3, 3))) {
- return 0;
- }
- return 1;
-}
-
-int convert_bboxes(PyObject *obj, void *bboxp)
-{
- numpy::array_view<double, 3> *bbox = (numpy::array_view<double, 3> *)bboxp;
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
- if (!bbox->set(obj)
- || (bbox->size() && !check_trailing_shape(*bbox, "bbox array", 2, 2))) {
- return 0;
- }
- return 1;
-}
-
-int convert_colors(PyObject *obj, void *colorsp)
-{
- numpy::array_view<double, 2> *colors = (numpy::array_view<double, 2> *)colorsp;
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
- if (!colors->set(obj)
- || (colors->size() && !check_trailing_shape(*colors, "colors", 4))) {
- return 0;
- }
- return 1;
-}
-}
diff --git a/contrib/python/matplotlib/py3/src/py_converters.h b/contrib/python/matplotlib/py3/src/py_converters.h
deleted file mode 100644
index 2c9dc6d1b8..0000000000
--- a/contrib/python/matplotlib/py3/src/py_converters.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef MPL_PY_CONVERTERS_H
-#define MPL_PY_CONVERTERS_H
-
-/***************************************************************************
- * This module contains a number of conversion functions from Python types
- * to C++ types. Most of them meet the Python "converter" signature:
- *
- * typedef int (*converter)(PyObject *, void *);
- *
- * and thus can be passed as conversion functions to PyArg_ParseTuple
- * and friends.
- */
-
-#include <Python.h>
-#include "_backend_agg_basic_types.h"
-
-extern "C" {
-typedef int (*converter)(PyObject *, void *);
-
-int convert_from_attr(PyObject *obj, const char *name, converter func, void *p);
-int convert_from_method(PyObject *obj, const char *name, converter func, void *p);
-
-int convert_double(PyObject *obj, void *p);
-int convert_bool(PyObject *obj, void *p);
-int convert_cap(PyObject *capobj, void *capp);
-int convert_join(PyObject *joinobj, void *joinp);
-int convert_rect(PyObject *rectobj, void *rectp);
-int convert_rgba(PyObject *rgbaocj, void *rgbap);
-int convert_dashes(PyObject *dashobj, void *gcp);
-int convert_dashes_vector(PyObject *obj, void *dashesp);
-int convert_trans_affine(PyObject *obj, void *transp);
-int convert_path(PyObject *obj, void *pathp);
-int convert_pathgen(PyObject *obj, void *pathgenp);
-int convert_clippath(PyObject *clippath_tuple, void *clippathp);
-int convert_snap(PyObject *obj, void *snapp);
-int convert_sketch_params(PyObject *obj, void *sketchp);
-int convert_gcagg(PyObject *pygc, void *gcp);
-int convert_points(PyObject *pygc, void *pointsp);
-int convert_transforms(PyObject *pygc, void *transp);
-int convert_bboxes(PyObject *pygc, void *bboxp);
-int convert_colors(PyObject *pygc, void *colorsp);
-
-int convert_face(PyObject *color, GCAgg &gc, agg::rgba *rgba);
-}
-
-#endif
diff --git a/contrib/python/matplotlib/py3/src/py_exceptions.h b/contrib/python/matplotlib/py3/src/py_exceptions.h
deleted file mode 100644
index c4accf2634..0000000000
--- a/contrib/python/matplotlib/py3/src/py_exceptions.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef MPL_PY_EXCEPTIONS_H
-#define MPL_PY_EXCEPTIONS_H
-
-#include <exception>
-#include <stdexcept>
-
-namespace py
-{
-class exception : public std::exception
-{
- public:
- const char *what() const throw()
- {
- return "python error has been set";
- }
-};
-}
-
-#define CALL_CPP_FULL(name, a, cleanup, errorcode) \
- try \
- { \
- a; \
- } \
- catch (const py::exception &) \
- { \
- { \
- cleanup; \
- } \
- return (errorcode); \
- } \
- catch (const std::bad_alloc &) \
- { \
- PyErr_Format(PyExc_MemoryError, "In %s: Out of memory", (name)); \
- { \
- cleanup; \
- } \
- return (errorcode); \
- } \
- catch (const std::overflow_error &e) \
- { \
- PyErr_Format(PyExc_OverflowError, "In %s: %s", (name), e.what()); \
- { \
- cleanup; \
- } \
- return (errorcode); \
- } \
- catch (const std::runtime_error &e) \
- { \
- PyErr_Format(PyExc_RuntimeError, "In %s: %s", (name), e.what()); \
- { \
- cleanup; \
- } \
- return (errorcode); \
- } \
- catch (...) \
- { \
- PyErr_Format(PyExc_RuntimeError, "Unknown exception in %s", (name)); \
- { \
- cleanup; \
- } \
- return (errorcode); \
- }
-
-#define CALL_CPP_CLEANUP(name, a, cleanup) CALL_CPP_FULL(name, a, cleanup, 0)
-
-#define CALL_CPP(name, a) CALL_CPP_FULL(name, a, , 0)
-
-#define CALL_CPP_INIT(name, a) CALL_CPP_FULL(name, a, , -1)
-
-#endif
diff --git a/contrib/python/matplotlib/py3/src/tri/_tri.cpp b/contrib/python/matplotlib/py3/src/tri/_tri.cpp
deleted file mode 100644
index 2674a3140b..0000000000
--- a/contrib/python/matplotlib/py3/src/tri/_tri.cpp
+++ /dev/null
@@ -1,2074 +0,0 @@
-/* This file contains liberal use of asserts to assist code development and
- * debugging. Standard matplotlib builds disable asserts so they cause no
- * performance reduction. To enable the asserts, you need to undefine the
- * NDEBUG macro, which is achieved by adding the following
- * undef_macros=['NDEBUG']
- * to the appropriate make_extension call in setupext.py, and then rebuilding.
- */
-#include "../mplutils.h"
-#include "_tri.h"
-
-#include <algorithm>
-#include <random>
-#include <set>
-
-
-TriEdge::TriEdge()
- : tri(-1), edge(-1)
-{}
-
-TriEdge::TriEdge(int tri_, int edge_)
- : tri(tri_), edge(edge_)
-{}
-
-bool TriEdge::operator<(const TriEdge& other) const
-{
- if (tri != other.tri)
- return tri < other.tri;
- else
- return edge < other.edge;
-}
-
-bool TriEdge::operator==(const TriEdge& other) const
-{
- return tri == other.tri && edge == other.edge;
-}
-
-bool TriEdge::operator!=(const TriEdge& other) const
-{
- return !operator==(other);
-}
-
-std::ostream& operator<<(std::ostream& os, const TriEdge& tri_edge)
-{
- return os << tri_edge.tri << ' ' << tri_edge.edge;
-}
-
-
-
-XY::XY()
-{}
-
-XY::XY(const double& x_, const double& y_)
- : x(x_), y(y_)
-{}
-
-double XY::angle() const
-{
- return atan2(y, x);
-}
-
-double XY::cross_z(const XY& other) const
-{
- return x*other.y - y*other.x;
-}
-
-bool XY::is_right_of(const XY& other) const
-{
- if (x == other.x)
- return y > other.y;
- else
- return x > other.x;
-}
-
-bool XY::operator==(const XY& other) const
-{
- return x == other.x && y == other.y;
-}
-
-bool XY::operator!=(const XY& other) const
-{
- return x != other.x || y != other.y;
-}
-
-XY XY::operator*(const double& multiplier) const
-{
- return XY(x*multiplier, y*multiplier);
-}
-
-const XY& XY::operator+=(const XY& other)
-{
- x += other.x;
- y += other.y;
- return *this;
-}
-
-const XY& XY::operator-=(const XY& other)
-{
- x -= other.x;
- y -= other.y;
- return *this;
-}
-
-XY XY::operator+(const XY& other) const
-{
- return XY(x + other.x, y + other.y);
-}
-
-XY XY::operator-(const XY& other) const
-{
- return XY(x - other.x, y - other.y);
-}
-
-std::ostream& operator<<(std::ostream& os, const XY& xy)
-{
- return os << '(' << xy.x << ' ' << xy.y << ')';
-}
-
-
-
-XYZ::XYZ(const double& x_, const double& y_, const double& z_)
- : x(x_), y(y_), z(z_)
-{}
-
-XYZ XYZ::cross(const XYZ& other) const
-{
- return XYZ(y*other.z - z*other.y,
- z*other.x - x*other.z,
- x*other.y - y*other.x);
-}
-
-double XYZ::dot(const XYZ& other) const
-{
- return x*other.x + y*other.y + z*other.z;
-}
-
-XYZ XYZ::operator-(const XYZ& other) const
-{
- return XYZ(x - other.x, y - other.y, z - other.z);
-}
-
-std::ostream& operator<<(std::ostream& os, const XYZ& xyz)
-{
- return os << '(' << xyz.x << ' ' << xyz.y << ' ' << xyz.z << ')';
-}
-
-
-
-BoundingBox::BoundingBox()
- : empty(true), lower(0.0, 0.0), upper(0.0, 0.0)
-{}
-
-void BoundingBox::add(const XY& point)
-{
- if (empty) {
- empty = false;
- lower = upper = point;
- } else {
- if (point.x < lower.x) lower.x = point.x;
- else if (point.x > upper.x) upper.x = point.x;
-
- if (point.y < lower.y) lower.y = point.y;
- else if (point.y > upper.y) upper.y = point.y;
- }
-}
-
-void BoundingBox::expand(const XY& delta)
-{
- if (!empty) {
- lower -= delta;
- upper += delta;
- }
-}
-
-
-
-ContourLine::ContourLine()
- : std::vector<XY>()
-{}
-
-void ContourLine::push_back(const XY& point)
-{
- if (empty() || point != back())
- std::vector<XY>::push_back(point);
-}
-
-void ContourLine::write() const
-{
- std::cout << "ContourLine of " << size() << " points:";
- for (const_iterator it = begin(); it != end(); ++it)
- std::cout << ' ' << *it;
- std::cout << std::endl;
-}
-
-
-
-void write_contour(const Contour& contour)
-{
- std::cout << "Contour of " << contour.size() << " lines." << std::endl;
- for (Contour::const_iterator it = contour.begin(); it != contour.end(); ++it)
- it->write();
-}
-
-
-
-Triangulation::Triangulation(const CoordinateArray& x,
- const CoordinateArray& y,
- const TriangleArray& triangles,
- const MaskArray& mask,
- const EdgeArray& edges,
- const NeighborArray& neighbors,
- bool correct_triangle_orientations)
- : _x(x),
- _y(y),
- _triangles(triangles),
- _mask(mask),
- _edges(edges),
- _neighbors(neighbors)
-{
- if (_x.ndim() != 1 || _y.ndim() != 1 || _x.shape(0) != _y.shape(0))
- throw std::invalid_argument("x and y must be 1D arrays of the same length");
-
- if (_triangles.ndim() != 2 || _triangles.shape(1) != 3)
- throw std::invalid_argument("triangles must be a 2D array of shape (?,3)");
-
- // Optional mask.
- if (_mask.size() > 0 &&
- (_mask.ndim() != 1 || _mask.shape(0) != _triangles.shape(0)))
- throw std::invalid_argument(
- "mask must be a 1D array with the same length as the triangles array");
-
- // Optional edges.
- if (_edges.size() > 0 &&
- (_edges.ndim() != 2 || _edges.shape(1) != 2))
- throw std::invalid_argument("edges must be a 2D array with shape (?,2)");
-
- // Optional neighbors.
- if (_neighbors.size() > 0 &&
- (_neighbors.ndim() != 2 || _neighbors.shape() != _triangles.shape()))
- throw std::invalid_argument(
- "neighbors must be a 2D array with the same shape as the triangles array");
-
- if (correct_triangle_orientations)
- correct_triangles();
-}
-
-void Triangulation::calculate_boundaries()
-{
- get_neighbors(); // Ensure _neighbors has been created.
-
- // Create set of all boundary TriEdges, which are those which do not
- // have a neighbor triangle.
- typedef std::set<TriEdge> BoundaryEdges;
- BoundaryEdges boundary_edges;
- for (int tri = 0; tri < get_ntri(); ++tri) {
- if (!is_masked(tri)) {
- for (int edge = 0; edge < 3; ++edge) {
- if (get_neighbor(tri, edge) == -1) {
- boundary_edges.insert(TriEdge(tri, edge));
- }
- }
- }
- }
-
- // Take any boundary edge and follow the boundary until return to start
- // point, removing edges from boundary_edges as they are used. At the same
- // time, initialise the _tri_edge_to_boundary_map.
- while (!boundary_edges.empty()) {
- // Start of new boundary.
- BoundaryEdges::iterator it = boundary_edges.begin();
- int tri = it->tri;
- int edge = it->edge;
- _boundaries.push_back(Boundary());
- Boundary& boundary = _boundaries.back();
-
- while (true) {
- boundary.push_back(TriEdge(tri, edge));
- boundary_edges.erase(it);
- _tri_edge_to_boundary_map[TriEdge(tri, edge)] =
- BoundaryEdge(_boundaries.size()-1, boundary.size()-1);
-
- // Move to next edge of current triangle.
- edge = (edge+1) % 3;
-
- // Find start point index of boundary edge.
- int point = get_triangle_point(tri, edge);
-
- // Find next TriEdge by traversing neighbors until find one
- // without a neighbor.
- while (get_neighbor(tri, edge) != -1) {
- tri = get_neighbor(tri, edge);
- edge = get_edge_in_triangle(tri, point);
- }
-
- if (TriEdge(tri,edge) == boundary.front())
- break; // Reached beginning of this boundary, so finished it.
- else
- it = boundary_edges.find(TriEdge(tri, edge));
- }
- }
-}
-
-void Triangulation::calculate_edges()
-{
- assert(!has_edges() && "Expected empty edges array");
-
- // Create set of all edges, storing them with start point index less than
- // end point index.
- typedef std::set<Edge> EdgeSet;
- EdgeSet edge_set;
- for (int tri = 0; tri < get_ntri(); ++tri) {
- if (!is_masked(tri)) {
- for (int edge = 0; edge < 3; edge++) {
- int start = get_triangle_point(tri, edge);
- int end = get_triangle_point(tri, (edge+1)%3);
- edge_set.insert(start > end ? Edge(start,end) : Edge(end,start));
- }
- }
- }
-
- // Convert to python _edges array.
- py::ssize_t dims[2] = {static_cast<py::ssize_t>(edge_set.size()), 2};
- _edges = EdgeArray(dims);
- auto edges = _edges.mutable_data();
-
- int i = 0;
- for (EdgeSet::const_iterator it = edge_set.begin(); it != edge_set.end(); ++it) {
- edges[i++] = it->start;
- edges[i++] = it->end;
- }
-}
-
-void Triangulation::calculate_neighbors()
-{
- assert(!has_neighbors() && "Expected empty neighbors array");
-
- // Create _neighbors array with shape (ntri,3) and initialise all to -1.
- py::ssize_t dims[2] = {get_ntri(), 3};
- _neighbors = NeighborArray(dims);
- auto* neighbors = _neighbors.mutable_data();
-
- int tri, edge;
- std::fill(neighbors, neighbors+3*get_ntri(), -1);
-
- // For each triangle edge (start to end point), find corresponding neighbor
- // edge from end to start point. Do this by traversing all edges and
- // storing them in a map from edge to TriEdge. If corresponding neighbor
- // edge is already in the map, don't need to store new edge as neighbor
- // already found.
- typedef std::map<Edge, TriEdge> EdgeToTriEdgeMap;
- EdgeToTriEdgeMap edge_to_tri_edge_map;
- for (tri = 0; tri < get_ntri(); ++tri) {
- if (!is_masked(tri)) {
- for (edge = 0; edge < 3; ++edge) {
- int start = get_triangle_point(tri, edge);
- int end = get_triangle_point(tri, (edge+1)%3);
- EdgeToTriEdgeMap::iterator it =
- edge_to_tri_edge_map.find(Edge(end,start));
- if (it == edge_to_tri_edge_map.end()) {
- // No neighbor edge exists in the edge_to_tri_edge_map, so
- // add this edge to it.
- edge_to_tri_edge_map[Edge(start,end)] = TriEdge(tri,edge);
- } else {
- // Neighbor edge found, set the two elements of _neighbors
- // and remove edge from edge_to_tri_edge_map.
- neighbors[3*tri + edge] = it->second.tri;
- neighbors[3*it->second.tri + it->second.edge] = tri;
- edge_to_tri_edge_map.erase(it);
- }
- }
- }
- }
-
- // Note that remaining edges in the edge_to_tri_edge_map correspond to
- // boundary edges, but the boundaries are calculated separately elsewhere.
-}
-
-Triangulation::TwoCoordinateArray Triangulation::calculate_plane_coefficients(
- const CoordinateArray& z)
-{
- if (z.ndim() != 1 || z.shape(0) != _x.shape(0))
- throw std::invalid_argument(
- "z must be a 1D array with the same length as the triangulation x and y arrays");
-
- int dims[2] = {get_ntri(), 3};
- Triangulation::TwoCoordinateArray planes_array(dims);
- auto planes = planes_array.mutable_unchecked<2>();
- auto triangles = _triangles.unchecked<2>();
- auto x = _x.unchecked<1>();
- auto y = _y.unchecked<1>();
- auto z_ptr = z.unchecked<1>();
-
- int point;
- for (int tri = 0; tri < get_ntri(); ++tri) {
- if (is_masked(tri)) {
- planes(tri, 0) = 0.0;
- planes(tri, 1) = 0.0;
- planes(tri, 2) = 0.0;
- }
- else {
- // Equation of plane for all points r on plane is r.normal = p
- // where normal is vector normal to the plane, and p is a
- // constant. Rewrite as
- // r_x*normal_x + r_y*normal_y + r_z*normal_z = p
- // and rearrange to give
- // r_z = (-normal_x/normal_z)*r_x + (-normal_y/normal_z)*r_y +
- // p/normal_z
- point = triangles(tri, 0);
- XYZ point0(x(point), y(point), z_ptr(point));
- point = triangles(tri, 1);
- XYZ side01 = XYZ(x(point), y(point), z_ptr(point)) - point0;
- point = triangles(tri, 2);
- XYZ side02 = XYZ(x(point), y(point), z_ptr(point)) - point0;
-
- XYZ normal = side01.cross(side02);
-
- if (normal.z == 0.0) {
- // Normal is in x-y plane which means triangle consists of
- // colinear points. To avoid dividing by zero, we use the
- // Moore-Penrose pseudo-inverse.
- double sum2 = (side01.x*side01.x + side01.y*side01.y +
- side02.x*side02.x + side02.y*side02.y);
- double a = (side01.x*side01.z + side02.x*side02.z) / sum2;
- double b = (side01.y*side01.z + side02.y*side02.z) / sum2;
- planes(tri, 0) = a;
- planes(tri, 1) = b;
- planes(tri, 2) = point0.z - a*point0.x - b*point0.y;
- }
- else {
- planes(tri, 0) = -normal.x / normal.z; // x
- planes(tri, 1) = -normal.y / normal.z; // y
- planes(tri, 2) = normal.dot(point0) / normal.z; // constant
- }
- }
- }
-
- return planes_array;
-}
-
-void Triangulation::correct_triangles()
-{
- auto triangles = _triangles.mutable_data();
- auto neighbors = _neighbors.mutable_data();
-
- for (int tri = 0; tri < get_ntri(); ++tri) {
- XY point0 = get_point_coords(triangles[3*tri]);
- XY point1 = get_point_coords(triangles[3*tri+1]);
- XY point2 = get_point_coords(triangles[3*tri+2]);
- if ( (point1 - point0).cross_z(point2 - point0) < 0.0) {
- // Triangle points are clockwise, so change them to anticlockwise.
- std::swap(triangles[3*tri+1], triangles[3*tri+2]);
- if (has_neighbors())
- std::swap(neighbors[3*tri+1], neighbors[3*tri+2]);
- }
- }
-}
-
-const Triangulation::Boundaries& Triangulation::get_boundaries() const
-{
- if (_boundaries.empty())
- const_cast<Triangulation*>(this)->calculate_boundaries();
- return _boundaries;
-}
-
-void Triangulation::get_boundary_edge(const TriEdge& triEdge,
- int& boundary,
- int& edge) const
-{
- get_boundaries(); // Ensure _tri_edge_to_boundary_map has been created.
- TriEdgeToBoundaryMap::const_iterator it =
- _tri_edge_to_boundary_map.find(triEdge);
- assert(it != _tri_edge_to_boundary_map.end() &&
- "TriEdge is not on a boundary");
- boundary = it->second.boundary;
- edge = it->second.edge;
-}
-
-int Triangulation::get_edge_in_triangle(int tri, int point) const
-{
- assert(tri >= 0 && tri < get_ntri() && "Triangle index out of bounds");
- assert(point >= 0 && point < get_npoints() && "Point index out of bounds.");
-
- auto triangles = _triangles.data();
-
- for (int edge = 0; edge < 3; ++edge) {
- if (triangles[3*tri + edge] == point)
- return edge;
- }
- return -1; // point is not in triangle.
-}
-
-Triangulation::EdgeArray& Triangulation::get_edges()
-{
- if (!has_edges())
- calculate_edges();
- return _edges;
-}
-
-int Triangulation::get_neighbor(int tri, int edge) const
-{
- assert(tri >= 0 && tri < get_ntri() && "Triangle index out of bounds");
- assert(edge >= 0 && edge < 3 && "Edge index out of bounds");
- if (!has_neighbors())
- const_cast<Triangulation&>(*this).calculate_neighbors();
- return _neighbors.data()[3*tri + edge];
-}
-
-TriEdge Triangulation::get_neighbor_edge(int tri, int edge) const
-{
- int neighbor_tri = get_neighbor(tri, edge);
- if (neighbor_tri == -1)
- return TriEdge(-1,-1);
- else
- return TriEdge(neighbor_tri,
- get_edge_in_triangle(neighbor_tri,
- get_triangle_point(tri,
- (edge+1)%3)));
-}
-
-Triangulation::NeighborArray& Triangulation::get_neighbors()
-{
- if (!has_neighbors())
- calculate_neighbors();
- return _neighbors;
-}
-
-int Triangulation::get_npoints() const
-{
- return _x.shape(0);
-}
-
-int Triangulation::get_ntri() const
-{
- return _triangles.shape(0);
-}
-
-XY Triangulation::get_point_coords(int point) const
-{
- assert(point >= 0 && point < get_npoints() && "Point index out of bounds.");
- return XY(_x.data()[point], _y.data()[point]);
-}
-
-int Triangulation::get_triangle_point(int tri, int edge) const
-{
- assert(tri >= 0 && tri < get_ntri() && "Triangle index out of bounds");
- assert(edge >= 0 && edge < 3 && "Edge index out of bounds");
- return _triangles.data()[3*tri + edge];
-}
-
-int Triangulation::get_triangle_point(const TriEdge& tri_edge) const
-{
- return get_triangle_point(tri_edge.tri, tri_edge.edge);
-}
-
-bool Triangulation::has_edges() const
-{
- return _edges.size() > 0;
-}
-
-bool Triangulation::has_mask() const
-{
- return _mask.size() > 0;
-}
-
-bool Triangulation::has_neighbors() const
-{
- return _neighbors.size() > 0;
-}
-
-bool Triangulation::is_masked(int tri) const
-{
- assert(tri >= 0 && tri < get_ntri() && "Triangle index out of bounds.");
- return has_mask() && _mask.data()[tri];
-}
-
-void Triangulation::set_mask(const MaskArray& mask)
-{
- if (mask.size() > 0 &&
- (mask.ndim() != 1 || mask.shape(0) != _triangles.shape(0)))
- throw std::invalid_argument(
- "mask must be a 1D array with the same length as the triangles array");
-
- _mask = mask;
-
- // Clear derived fields so they are recalculated when needed.
- _edges = EdgeArray();
- _neighbors = NeighborArray();
- _boundaries.clear();
-}
-
-void Triangulation::write_boundaries() const
-{
- const Boundaries& bs = get_boundaries();
- std::cout << "Number of boundaries: " << bs.size() << std::endl;
- for (Boundaries::const_iterator it = bs.begin(); it != bs.end(); ++it) {
- const Boundary& b = *it;
- std::cout << " Boundary of " << b.size() << " points: ";
- for (Boundary::const_iterator itb = b.begin(); itb != b.end(); ++itb) {
- std::cout << *itb << ", ";
- }
- std::cout << std::endl;
- }
-}
-
-
-
-TriContourGenerator::TriContourGenerator(Triangulation& triangulation,
- const CoordinateArray& z)
- : _triangulation(triangulation),
- _z(z),
- _interior_visited(2*_triangulation.get_ntri()),
- _boundaries_visited(0),
- _boundaries_used(0)
-{
- if (_z.ndim() != 1 || _z.shape(0) != _triangulation.get_npoints())
- throw std::invalid_argument(
- "z must be a 1D array with the same length as the x and y arrays");
-}
-
-void TriContourGenerator::clear_visited_flags(bool include_boundaries)
-{
- // Clear _interiorVisited.
- std::fill(_interior_visited.begin(), _interior_visited.end(), false);
-
- if (include_boundaries) {
- if (_boundaries_visited.empty()) {
- const Boundaries& boundaries = get_boundaries();
-
- // Initialise _boundaries_visited.
- _boundaries_visited.reserve(boundaries.size());
- for (Boundaries::const_iterator it = boundaries.begin();
- it != boundaries.end(); ++it)
- _boundaries_visited.push_back(BoundaryVisited(it->size()));
-
- // Initialise _boundaries_used.
- _boundaries_used = BoundariesUsed(boundaries.size());
- }
-
- // Clear _boundaries_visited.
- for (BoundariesVisited::iterator it = _boundaries_visited.begin();
- it != _boundaries_visited.end(); ++it)
- std::fill(it->begin(), it->end(), false);
-
- // Clear _boundaries_used.
- std::fill(_boundaries_used.begin(), _boundaries_used.end(), false);
- }
-}
-
-py::tuple TriContourGenerator::contour_line_to_segs_and_kinds(const Contour& contour)
-{
- // Convert all of the lines generated by a call to create_contour() into
- // their Python equivalents for return to the calling function.
- // A line is either a closed line loop (in which case the last point is
- // identical to the first) or an open line strip. Two NumPy arrays are
- // created for each line:
- // vertices is a double array of shape (npoints, 2) containing the (x, y)
- // coordinates of the points in the line
- // codes is a uint8 array of shape (npoints,) containing the 'kind codes'
- // which are defined in the Path class
- // and they are appended to the Python lists vertices_list and codes_list
- // respectively for return to the Python calling function.
-
- py::list vertices_list(contour.size());
- py::list codes_list(contour.size());
-
- for (Contour::size_type i = 0; i < contour.size(); ++i) {
- const ContourLine& contour_line = contour[i];
- py::ssize_t npoints = static_cast<py::ssize_t>(contour_line.size());
-
- py::ssize_t segs_dims[2] = {npoints, 2};
- CoordinateArray segs(segs_dims);
- double* segs_ptr = segs.mutable_data();
-
- py::ssize_t codes_dims[1] = {npoints};
- CodeArray codes(codes_dims);
- unsigned char* codes_ptr = codes.mutable_data();
-
- for (ContourLine::const_iterator it = contour_line.begin();
- it != contour_line.end(); ++it) {
- *segs_ptr++ = it->x;
- *segs_ptr++ = it->y;
- *codes_ptr++ = (it == contour_line.begin() ? MOVETO : LINETO);
- }
-
- // Closed line loop has identical first and last (x, y) points.
- if (contour_line.size() > 1 &&
- contour_line.front() == contour_line.back())
- *(codes_ptr-1) = CLOSEPOLY;
-
- vertices_list[i] = segs;
- codes_list[i] = codes;
- }
-
- return py::make_tuple(vertices_list, codes_list);
-}
-
-py::tuple TriContourGenerator::contour_to_segs_and_kinds(const Contour& contour)
-{
- // Convert all of the polygons generated by a call to
- // create_filled_contour() into their Python equivalents for return to the
- // calling function. All of the polygons' points and kinds codes are
- // combined into single NumPy arrays for each; this avoids having
- // to determine which polygons are holes as this will be determined by the
- // renderer. If there are ntotal points in all of the polygons, the two
- // NumPy arrays created are:
- // vertices is a double array of shape (ntotal, 2) containing the (x, y)
- // coordinates of the points in the polygons
- // codes is a uint8 array of shape (ntotal,) containing the 'kind codes'
- // which are defined in the Path class
- // and they are returned in the Python lists vertices_list and codes_list
- // respectively.
-
- Contour::const_iterator line;
- ContourLine::const_iterator point;
-
- // Find total number of points in all contour lines.
- py::ssize_t n_points = 0;
- for (line = contour.begin(); line != contour.end(); ++line)
- n_points += static_cast<py::ssize_t>(line->size());
-
- // Create segs array for point coordinates.
- py::ssize_t segs_dims[2] = {n_points, 2};
- TwoCoordinateArray segs(segs_dims);
- double* segs_ptr = segs.mutable_data();
-
- // Create kinds array for code types.
- py::ssize_t codes_dims[1] = {n_points};
- CodeArray codes(codes_dims);
- unsigned char* codes_ptr = codes.mutable_data();
-
- for (line = contour.begin(); line != contour.end(); ++line) {
- for (point = line->begin(); point != line->end(); point++) {
- *segs_ptr++ = point->x;
- *segs_ptr++ = point->y;
- *codes_ptr++ = (point == line->begin() ? MOVETO : LINETO);
- }
-
- if (line->size() > 1)
- *(codes_ptr-1) = CLOSEPOLY;
- }
-
- py::list vertices_list(1);
- vertices_list[0] = segs;
-
- py::list codes_list(1);
- codes_list[0] = codes;
-
- return py::make_tuple(vertices_list, codes_list);
-}
-
-py::tuple TriContourGenerator::create_contour(const double& level)
-{
- clear_visited_flags(false);
- Contour contour;
-
- find_boundary_lines(contour, level);
- find_interior_lines(contour, level, false, false);
-
- return contour_line_to_segs_and_kinds(contour);
-}
-
-py::tuple TriContourGenerator::create_filled_contour(const double& lower_level,
- const double& upper_level)
-{
- if (lower_level >= upper_level)
- throw std::invalid_argument("filled contour levels must be increasing");
-
- clear_visited_flags(true);
- Contour contour;
-
- find_boundary_lines_filled(contour, lower_level, upper_level);
- find_interior_lines(contour, lower_level, false, true);
- find_interior_lines(contour, upper_level, true, true);
-
- return contour_to_segs_and_kinds(contour);
-}
-
-XY TriContourGenerator::edge_interp(int tri, int edge, const double& level)
-{
- return interp(_triangulation.get_triangle_point(tri, edge),
- _triangulation.get_triangle_point(tri, (edge+1)%3),
- level);
-}
-
-void TriContourGenerator::find_boundary_lines(Contour& contour,
- const double& level)
-{
- // Traverse boundaries to find starting points for all contour lines that
- // intersect the boundaries. For each starting point found, follow the
- // line to its end before continuing.
- const Triangulation& triang = _triangulation;
- const Boundaries& boundaries = get_boundaries();
- for (Boundaries::const_iterator it = boundaries.begin();
- it != boundaries.end(); ++it) {
- const Boundary& boundary = *it;
- bool startAbove, endAbove = false;
- for (Boundary::const_iterator itb = boundary.begin();
- itb != boundary.end(); ++itb) {
- if (itb == boundary.begin())
- startAbove = get_z(triang.get_triangle_point(*itb)) >= level;
- else
- startAbove = endAbove;
- endAbove = get_z(triang.get_triangle_point(itb->tri,
- (itb->edge+1)%3)) >= level;
- if (startAbove && !endAbove) {
- // This boundary edge is the start point for a contour line,
- // so follow the line.
- contour.push_back(ContourLine());
- ContourLine& contour_line = contour.back();
- TriEdge tri_edge = *itb;
- follow_interior(contour_line, tri_edge, true, level, false);
- }
- }
- }
-}
-
-void TriContourGenerator::find_boundary_lines_filled(Contour& contour,
- const double& lower_level,
- const double& upper_level)
-{
- // Traverse boundaries to find starting points for all contour lines that
- // intersect the boundaries. For each starting point found, follow the
- // line to its end before continuing.
- const Triangulation& triang = _triangulation;
- const Boundaries& boundaries = get_boundaries();
- for (Boundaries::size_type i = 0; i < boundaries.size(); ++i) {
- const Boundary& boundary = boundaries[i];
- for (Boundary::size_type j = 0; j < boundary.size(); ++j) {
- if (!_boundaries_visited[i][j]) {
- // z values of start and end of this boundary edge.
- double z_start = get_z(triang.get_triangle_point(boundary[j]));
- double z_end = get_z(triang.get_triangle_point(
- boundary[j].tri, (boundary[j].edge+1)%3));
-
- // Does this boundary edge's z increase through upper level
- // and/or decrease through lower level?
- bool incr_upper = (z_start < upper_level && z_end >= upper_level);
- bool decr_lower = (z_start >= lower_level && z_end < lower_level);
-
- if (decr_lower || incr_upper) {
- // Start point for contour line, so follow it.
- contour.push_back(ContourLine());
- ContourLine& contour_line = contour.back();
- TriEdge start_tri_edge = boundary[j];
- TriEdge tri_edge = start_tri_edge;
-
- // Traverse interior and boundaries until return to start.
- bool on_upper = incr_upper;
- do {
- follow_interior(contour_line, tri_edge, true,
- on_upper ? upper_level : lower_level, on_upper);
- on_upper = follow_boundary(contour_line, tri_edge,
- lower_level, upper_level, on_upper);
- } while (tri_edge != start_tri_edge);
-
- // Close polygon.
- contour_line.push_back(contour_line.front());
- }
- }
- }
- }
-
- // Add full boundaries that lie between the lower and upper levels. These
- // are boundaries that have not been touched by an internal contour line
- // which are stored in _boundaries_used.
- for (Boundaries::size_type i = 0; i < boundaries.size(); ++i) {
- if (!_boundaries_used[i]) {
- const Boundary& boundary = boundaries[i];
- double z = get_z(triang.get_triangle_point(boundary[0]));
- if (z >= lower_level && z < upper_level) {
- contour.push_back(ContourLine());
- ContourLine& contour_line = contour.back();
- for (Boundary::size_type j = 0; j < boundary.size(); ++j)
- contour_line.push_back(triang.get_point_coords(
- triang.get_triangle_point(boundary[j])));
-
- // Close polygon.
- contour_line.push_back(contour_line.front());
- }
- }
- }
-}
-
-void TriContourGenerator::find_interior_lines(Contour& contour,
- const double& level,
- bool on_upper,
- bool filled)
-{
- const Triangulation& triang = _triangulation;
- int ntri = triang.get_ntri();
- for (int tri = 0; tri < ntri; ++tri) {
- int visited_index = (on_upper ? tri+ntri : tri);
-
- if (_interior_visited[visited_index] || triang.is_masked(tri))
- continue; // Triangle has already been visited or is masked.
-
- _interior_visited[visited_index] = true;
-
- // Determine edge via which to leave this triangle.
- int edge = get_exit_edge(tri, level, on_upper);
- assert(edge >= -1 && edge < 3 && "Invalid exit edge");
- if (edge == -1)
- continue; // Contour does not pass through this triangle.
-
- // Found start of new contour line loop.
- contour.push_back(ContourLine());
- ContourLine& contour_line = contour.back();
- TriEdge tri_edge = triang.get_neighbor_edge(tri, edge);
- follow_interior(contour_line, tri_edge, false, level, on_upper);
-
- // Close line loop
- contour_line.push_back(contour_line.front());
- }
-}
-
-bool TriContourGenerator::follow_boundary(ContourLine& contour_line,
- TriEdge& tri_edge,
- const double& lower_level,
- const double& upper_level,
- bool on_upper)
-{
- const Triangulation& triang = _triangulation;
- const Boundaries& boundaries = get_boundaries();
-
- // Have TriEdge to start at, need equivalent boundary edge.
- int boundary, edge;
- triang.get_boundary_edge(tri_edge, boundary, edge);
- _boundaries_used[boundary] = true;
-
- bool stop = false;
- bool first_edge = true;
- double z_start, z_end = 0;
- while (!stop)
- {
- assert(!_boundaries_visited[boundary][edge] && "Boundary already visited");
- _boundaries_visited[boundary][edge] = true;
-
- // z values of start and end points of boundary edge.
- if (first_edge)
- z_start = get_z(triang.get_triangle_point(tri_edge));
- else
- z_start = z_end;
- z_end = get_z(triang.get_triangle_point(tri_edge.tri,
- (tri_edge.edge+1)%3));
-
- if (z_end > z_start) { // z increasing.
- if (!(!on_upper && first_edge) &&
- z_end >= lower_level && z_start < lower_level) {
- stop = true;
- on_upper = false;
- } else if (z_end >= upper_level && z_start < upper_level) {
- stop = true;
- on_upper = true;
- }
- } else { // z decreasing.
- if (!(on_upper && first_edge) &&
- z_start >= upper_level && z_end < upper_level) {
- stop = true;
- on_upper = true;
- } else if (z_start >= lower_level && z_end < lower_level) {
- stop = true;
- on_upper = false;
- }
- }
-
- first_edge = false;
-
- if (!stop) {
- // Move to next boundary edge, adding point to contour line.
- edge = (edge+1) % (int)boundaries[boundary].size();
- tri_edge = boundaries[boundary][edge];
- contour_line.push_back(triang.get_point_coords(
- triang.get_triangle_point(tri_edge)));
- }
- }
-
- return on_upper;
-}
-
-void TriContourGenerator::follow_interior(ContourLine& contour_line,
- TriEdge& tri_edge,
- bool end_on_boundary,
- const double& level,
- bool on_upper)
-{
- int& tri = tri_edge.tri;
- int& edge = tri_edge.edge;
-
- // Initial point.
- contour_line.push_back(edge_interp(tri, edge, level));
-
- while (true) {
- int visited_index = tri;
- if (on_upper)
- visited_index += _triangulation.get_ntri();
-
- // Check for end not on boundary.
- if (!end_on_boundary && _interior_visited[visited_index])
- break; // Reached start point, so return.
-
- // Determine edge by which to leave this triangle.
- edge = get_exit_edge(tri, level, on_upper);
- assert(edge >= 0 && edge < 3 && "Invalid exit edge");
-
- _interior_visited[visited_index] = true;
-
- // Append new point to point set.
- assert(edge >= 0 && edge < 3 && "Invalid triangle edge");
- contour_line.push_back(edge_interp(tri, edge, level));
-
- // Move to next triangle.
- TriEdge next_tri_edge = _triangulation.get_neighbor_edge(tri,edge);
-
- // Check if ending on a boundary.
- if (end_on_boundary && next_tri_edge.tri == -1)
- break;
-
- tri_edge = next_tri_edge;
- assert(tri_edge.tri != -1 && "Invalid triangle for internal loop");
- }
-}
-
-const TriContourGenerator::Boundaries& TriContourGenerator::get_boundaries() const
-{
- return _triangulation.get_boundaries();
-}
-
-int TriContourGenerator::get_exit_edge(int tri,
- const double& level,
- bool on_upper) const
-{
- assert(tri >= 0 && tri < _triangulation.get_ntri() &&
- "Triangle index out of bounds.");
-
- unsigned int config =
- (get_z(_triangulation.get_triangle_point(tri, 0)) >= level) |
- (get_z(_triangulation.get_triangle_point(tri, 1)) >= level) << 1 |
- (get_z(_triangulation.get_triangle_point(tri, 2)) >= level) << 2;
-
- if (on_upper) config = 7-config;
-
- switch (config) {
- case 0: return -1;
- case 1: return 2;
- case 2: return 0;
- case 3: return 2;
- case 4: return 1;
- case 5: return 1;
- case 6: return 0;
- case 7: return -1;
- default: assert(0 && "Invalid config value"); return -1;
- }
-}
-
-const double& TriContourGenerator::get_z(int point) const
-{
- assert(point >= 0 && point < _triangulation.get_npoints() &&
- "Point index out of bounds.");
- return _z.data()[point];
-}
-
-XY TriContourGenerator::interp(int point1,
- int point2,
- const double& level) const
-{
- assert(point1 >= 0 && point1 < _triangulation.get_npoints() &&
- "Point index 1 out of bounds.");
- assert(point2 >= 0 && point2 < _triangulation.get_npoints() &&
- "Point index 2 out of bounds.");
- assert(point1 != point2 && "Identical points");
- double fraction = (get_z(point2) - level) / (get_z(point2) - get_z(point1));
- return _triangulation.get_point_coords(point1)*fraction +
- _triangulation.get_point_coords(point2)*(1.0 - fraction);
-}
-
-
-
-TrapezoidMapTriFinder::TrapezoidMapTriFinder(Triangulation& triangulation)
- : _triangulation(triangulation),
- _points(0),
- _tree(0)
-{}
-
-TrapezoidMapTriFinder::~TrapezoidMapTriFinder()
-{
- clear();
-}
-
-bool
-TrapezoidMapTriFinder::add_edge_to_tree(const Edge& edge)
-{
- std::vector<Trapezoid*> trapezoids;
- if (!find_trapezoids_intersecting_edge(edge, trapezoids))
- return false;
- assert(!trapezoids.empty() && "No trapezoids intersect edge");
-
- const Point* p = edge.left;
- const Point* q = edge.right;
- Trapezoid* left_old = 0; // old trapezoid to the left.
- Trapezoid* left_below = 0; // below trapezoid to the left.
- Trapezoid* left_above = 0; // above trapezoid to the left.
-
- // Iterate through trapezoids intersecting edge from left to right.
- // Replace each old trapezoid with 2+ new trapezoids, and replace its
- // corresponding nodes in the search tree with new nodes.
- size_t ntraps = trapezoids.size();
- for (size_t i = 0; i < ntraps; ++i) {
- Trapezoid* old = trapezoids[i]; // old trapezoid to replace.
- bool start_trap = (i == 0);
- bool end_trap = (i == ntraps-1);
- bool have_left = (start_trap && edge.left != old->left);
- bool have_right = (end_trap && edge.right != old->right);
-
- // Old trapezoid is replaced by up to 4 new trapezoids: left is to the
- // left of the start point p, below/above are below/above the edge
- // inserted, and right is to the right of the end point q.
- Trapezoid* left = 0;
- Trapezoid* below = 0;
- Trapezoid* above = 0;
- Trapezoid* right = 0;
-
- // There are 4 different cases here depending on whether the old
- // trapezoid in question is the start and/or end trapezoid of those
- // that intersect the edge inserted. There is some code duplication
- // here but it is much easier to understand this way rather than
- // interleave the 4 different cases with many more if-statements.
- if (start_trap && end_trap) {
- // Edge intersects a single trapezoid.
- if (have_left)
- left = new Trapezoid(old->left, p, old->below, old->above);
- below = new Trapezoid(p, q, old->below, edge);
- above = new Trapezoid(p, q, edge, old->above);
- if (have_right)
- right = new Trapezoid(q, old->right, old->below, old->above);
-
- // Set pairs of trapezoid neighbours.
- if (have_left) {
- left->set_lower_left(old->lower_left);
- left->set_upper_left(old->upper_left);
- left->set_lower_right(below);
- left->set_upper_right(above);
- }
- else {
- below->set_lower_left(old->lower_left);
- above->set_upper_left(old->upper_left);
- }
-
- if (have_right) {
- right->set_lower_right(old->lower_right);
- right->set_upper_right(old->upper_right);
- below->set_lower_right(right);
- above->set_upper_right(right);
- }
- else {
- below->set_lower_right(old->lower_right);
- above->set_upper_right(old->upper_right);
- }
- }
- else if (start_trap) {
- // Old trapezoid is the first of 2+ trapezoids that the edge
- // intersects.
- if (have_left)
- left = new Trapezoid(old->left, p, old->below, old->above);
- below = new Trapezoid(p, old->right, old->below, edge);
- above = new Trapezoid(p, old->right, edge, old->above);
-
- // Set pairs of trapezoid neighbours.
- if (have_left) {
- left->set_lower_left(old->lower_left);
- left->set_upper_left(old->upper_left);
- left->set_lower_right(below);
- left->set_upper_right(above);
- }
- else {
- below->set_lower_left(old->lower_left);
- above->set_upper_left(old->upper_left);
- }
-
- below->set_lower_right(old->lower_right);
- above->set_upper_right(old->upper_right);
- }
- else if (end_trap) {
- // Old trapezoid is the last of 2+ trapezoids that the edge
- // intersects.
- if (left_below->below == old->below) {
- below = left_below;
- below->right = q;
- }
- else
- below = new Trapezoid(old->left, q, old->below, edge);
-
- if (left_above->above == old->above) {
- above = left_above;
- above->right = q;
- }
- else
- above = new Trapezoid(old->left, q, edge, old->above);
-
- if (have_right)
- right = new Trapezoid(q, old->right, old->below, old->above);
-
- // Set pairs of trapezoid neighbours.
- if (have_right) {
- right->set_lower_right(old->lower_right);
- right->set_upper_right(old->upper_right);
- below->set_lower_right(right);
- above->set_upper_right(right);
- }
- else {
- below->set_lower_right(old->lower_right);
- above->set_upper_right(old->upper_right);
- }
-
- // Connect to new trapezoids replacing prevOld.
- if (below != left_below) {
- below->set_upper_left(left_below);
- if (old->lower_left == left_old)
- below->set_lower_left(left_below);
- else
- below->set_lower_left(old->lower_left);
- }
-
- if (above != left_above) {
- above->set_lower_left(left_above);
- if (old->upper_left == left_old)
- above->set_upper_left(left_above);
- else
- above->set_upper_left(old->upper_left);
- }
- }
- else { // Middle trapezoid.
- // Old trapezoid is neither the first nor last of the 3+ trapezoids
- // that the edge intersects.
- if (left_below->below == old->below) {
- below = left_below;
- below->right = old->right;
- }
- else
- below = new Trapezoid(old->left, old->right, old->below, edge);
-
- if (left_above->above == old->above) {
- above = left_above;
- above->right = old->right;
- }
- else
- above = new Trapezoid(old->left, old->right, edge, old->above);
-
- // Connect to new trapezoids replacing prevOld.
- if (below != left_below) { // below is new.
- below->set_upper_left(left_below);
- if (old->lower_left == left_old)
- below->set_lower_left(left_below);
- else
- below->set_lower_left(old->lower_left);
- }
-
- if (above != left_above) { // above is new.
- above->set_lower_left(left_above);
- if (old->upper_left == left_old)
- above->set_upper_left(left_above);
- else
- above->set_upper_left(old->upper_left);
- }
-
- below->set_lower_right(old->lower_right);
- above->set_upper_right(old->upper_right);
- }
-
- // Create new nodes to add to search tree. Below and above trapezoids
- // may already have owning trapezoid nodes, in which case reuse them.
- Node* new_top_node = new Node(
- &edge,
- below == left_below ? below->trapezoid_node : new Node(below),
- above == left_above ? above->trapezoid_node : new Node(above));
- if (have_right)
- new_top_node = new Node(q, new_top_node, new Node(right));
- if (have_left)
- new_top_node = new Node(p, new Node(left), new_top_node);
-
- // Insert new_top_node in correct position or positions in search tree.
- Node* old_node = old->trapezoid_node;
- if (old_node == _tree)
- _tree = new_top_node;
- else
- old_node->replace_with(new_top_node);
-
- // old_node has been removed from all of its parents and is no longer
- // needed.
- assert(old_node->has_no_parents() && "Node should have no parents");
- delete old_node;
-
- // Clearing up.
- if (!end_trap) {
- // Prepare for next loop.
- left_old = old;
- left_above = above;
- left_below = below;
- }
- }
-
- return true;
-}
-
-void
-TrapezoidMapTriFinder::clear()
-{
- delete [] _points;
- _points = 0;
-
- _edges.clear();
-
- delete _tree;
- _tree = 0;
-}
-
-TrapezoidMapTriFinder::TriIndexArray
-TrapezoidMapTriFinder::find_many(const CoordinateArray& x,
- const CoordinateArray& y)
-{
- if (x.ndim() != 1 || x.shape(0) != y.shape(0))
- throw std::invalid_argument(
- "x and y must be array-like with same shape");
-
- // Create integer array to return.
- auto n = x.shape(0);
- TriIndexArray tri_indices_array(n);
- auto tri_indices = tri_indices_array.mutable_unchecked<1>();
- auto x_data = x.data();
- auto y_data = y.data();
-
- // Fill returned array.
- for (py::ssize_t i = 0; i < n; ++i)
- tri_indices(i) = find_one(XY(x_data[i], y_data[i]));
-
- return tri_indices_array;
-}
-
-int
-TrapezoidMapTriFinder::find_one(const XY& xy)
-{
- const Node* node = _tree->search(xy);
- assert(node != 0 && "Search tree for point returned null node");
- return node->get_tri();
-}
-
-bool
-TrapezoidMapTriFinder::find_trapezoids_intersecting_edge(
- const Edge& edge,
- std::vector<Trapezoid*>& trapezoids)
-{
- // This is the FollowSegment algorithm of de Berg et al, with some extra
- // checks to deal with simple colinear (i.e. invalid) triangles.
- trapezoids.clear();
- Trapezoid* trapezoid = _tree->search(edge);
- if (trapezoid == 0) {
- assert(trapezoid != 0 && "search(edge) returns null trapezoid");
- return false;
- }
-
- trapezoids.push_back(trapezoid);
- while (edge.right->is_right_of(*trapezoid->right)) {
- int orient = edge.get_point_orientation(*trapezoid->right);
- if (orient == 0) {
- if (edge.point_below == trapezoid->right)
- orient = +1;
- else if (edge.point_above == trapezoid->right)
- orient = -1;
- else {
- assert(0 && "Unable to deal with point on edge");
- return false;
- }
- }
-
- if (orient == -1)
- trapezoid = trapezoid->lower_right;
- else if (orient == +1)
- trapezoid = trapezoid->upper_right;
-
- if (trapezoid == 0) {
- assert(0 && "Expected trapezoid neighbor");
- return false;
- }
- trapezoids.push_back(trapezoid);
- }
-
- return true;
-}
-
-py::list
-TrapezoidMapTriFinder::get_tree_stats()
-{
- NodeStats stats;
- _tree->get_stats(0, stats);
-
- py::list ret(7);
- ret[0] = stats.node_count;
- ret[1] = stats.unique_nodes.size(),
- ret[2] = stats.trapezoid_count,
- ret[3] = stats.unique_trapezoid_nodes.size(),
- ret[4] = stats.max_parent_count,
- ret[5] = stats.max_depth,
- ret[6] = stats.sum_trapezoid_depth / stats.trapezoid_count;
- return ret;
-}
-
-void
-TrapezoidMapTriFinder::initialize()
-{
- clear();
- const Triangulation& triang = _triangulation;
-
- // Set up points array, which contains all of the points in the
- // triangulation plus the 4 corners of the enclosing rectangle.
- int npoints = triang.get_npoints();
- _points = new Point[npoints + 4];
- BoundingBox bbox;
- for (int i = 0; i < npoints; ++i) {
- XY xy = triang.get_point_coords(i);
- // Avoid problems with -0.0 values different from 0.0
- if (xy.x == -0.0)
- xy.x = 0.0;
- if (xy.y == -0.0)
- xy.y = 0.0;
- _points[i] = Point(xy);
- bbox.add(xy);
- }
-
- // Last 4 points are corner points of enclosing rectangle. Enclosing
- // rectangle made slightly larger in case corner points are already in the
- // triangulation.
- if (bbox.empty) {
- bbox.add(XY(0.0, 0.0));
- bbox.add(XY(1.0, 1.0));
- }
- else {
- const double small = 0.1; // Any value > 0.0
- bbox.expand( (bbox.upper - bbox.lower)*small );
- }
- _points[npoints ] = Point(bbox.lower); // SW point.
- _points[npoints+1] = Point(bbox.upper.x, bbox.lower.y); // SE point.
- _points[npoints+2] = Point(bbox.lower.x, bbox.upper.y); // NW point.
- _points[npoints+3] = Point(bbox.upper); // NE point.
-
- // Set up edges array.
- // First the bottom and top edges of the enclosing rectangle.
- _edges.push_back(Edge(&_points[npoints], &_points[npoints+1],-1,-1,0,0));
- _edges.push_back(Edge(&_points[npoints+2],&_points[npoints+3],-1,-1,0,0));
-
- // Add all edges in the triangulation that point to the right. Do not
- // explicitly include edges that point to the left as the neighboring
- // triangle will supply that, unless there is no such neighbor.
- int ntri = triang.get_ntri();
- for (int tri = 0; tri < ntri; ++tri) {
- if (!triang.is_masked(tri)) {
- for (int edge = 0; edge < 3; ++edge) {
- Point* start = _points + triang.get_triangle_point(tri,edge);
- Point* end = _points +
- triang.get_triangle_point(tri,(edge+1)%3);
- Point* other = _points +
- triang.get_triangle_point(tri,(edge+2)%3);
- TriEdge neighbor = triang.get_neighbor_edge(tri,edge);
- if (end->is_right_of(*start)) {
- const Point* neighbor_point_below = (neighbor.tri == -1) ?
- 0 : _points + triang.get_triangle_point(
- neighbor.tri, (neighbor.edge+2)%3);
- _edges.push_back(Edge(start, end, neighbor.tri, tri,
- neighbor_point_below, other));
- }
- else if (neighbor.tri == -1)
- _edges.push_back(Edge(end, start, tri, -1, other, 0));
-
- // Set triangle associated with start point if not already set.
- if (start->tri == -1)
- start->tri = tri;
- }
- }
- }
-
- // Initial trapezoid is enclosing rectangle.
- _tree = new Node(new Trapezoid(&_points[npoints], &_points[npoints+1],
- _edges[0], _edges[1]));
- _tree->assert_valid(false);
-
- // Randomly shuffle all edges other than first 2.
- std::mt19937 rng(1234);
- std::shuffle(_edges.begin()+2, _edges.end(), rng);
-
- // Add edges, one at a time, to tree.
- size_t nedges = _edges.size();
- for (size_t index = 2; index < nedges; ++index) {
- if (!add_edge_to_tree(_edges[index]))
- throw std::runtime_error("Triangulation is invalid");
- _tree->assert_valid(index == nedges-1);
- }
-}
-
-void
-TrapezoidMapTriFinder::print_tree()
-{
- assert(_tree != 0 && "Null Node tree");
- _tree->print();
-}
-
-TrapezoidMapTriFinder::Edge::Edge(const Point* left_,
- const Point* right_,
- int triangle_below_,
- int triangle_above_,
- const Point* point_below_,
- const Point* point_above_)
- : left(left_),
- right(right_),
- triangle_below(triangle_below_),
- triangle_above(triangle_above_),
- point_below(point_below_),
- point_above(point_above_)
-{
- assert(left != 0 && "Null left point");
- assert(right != 0 && "Null right point");
- assert(right->is_right_of(*left) && "Incorrect point order");
- assert(triangle_below >= -1 && "Invalid triangle below index");
- assert(triangle_above >= -1 && "Invalid triangle above index");
-}
-
-int
-TrapezoidMapTriFinder::Edge::get_point_orientation(const XY& xy) const
-{
- double cross_z = (xy - *left).cross_z(*right - *left);
- return (cross_z > 0.0) ? +1 : ((cross_z < 0.0) ? -1 : 0);
-}
-
-double
-TrapezoidMapTriFinder::Edge::get_slope() const
-{
- // Divide by zero is acceptable here.
- XY diff = *right - *left;
- return diff.y / diff.x;
-}
-
-double
-TrapezoidMapTriFinder::Edge::get_y_at_x(const double& x) const
-{
- if (left->x == right->x) {
- // If edge is vertical, return lowest y from left point.
- assert(x == left->x && "x outside of edge");
- return left->y;
- }
- else {
- // Equation of line: left + lambda*(right - left) = xy.
- // i.e. left.x + lambda(right.x - left.x) = x and similar for y.
- double lambda = (x - left->x) / (right->x - left->x);
- assert(lambda >= 0 && lambda <= 1.0 && "Lambda out of bounds");
- return left->y + lambda*(right->y - left->y);
- }
-}
-
-bool
-TrapezoidMapTriFinder::Edge::has_point(const Point* point) const
-{
- assert(point != 0 && "Null point");
- return (left == point || right == point);
-}
-
-bool
-TrapezoidMapTriFinder::Edge::operator==(const Edge& other) const
-{
- return this == &other;
-}
-
-void
-TrapezoidMapTriFinder::Edge::print_debug() const
-{
- std::cout << "Edge " << *this << " tri_below=" << triangle_below
- << " tri_above=" << triangle_above << std::endl;
-}
-
-TrapezoidMapTriFinder::Node::Node(const Point* point, Node* left, Node* right)
- : _type(Type_XNode)
-{
- assert(point != 0 && "Invalid point");
- assert(left != 0 && "Invalid left node");
- assert(right != 0 && "Invalid right node");
- _union.xnode.point = point;
- _union.xnode.left = left;
- _union.xnode.right = right;
- left->add_parent(this);
- right->add_parent(this);
-}
-
-TrapezoidMapTriFinder::Node::Node(const Edge* edge, Node* below, Node* above)
- : _type(Type_YNode)
-{
- assert(edge != 0 && "Invalid edge");
- assert(below != 0 && "Invalid below node");
- assert(above != 0 && "Invalid above node");
- _union.ynode.edge = edge;
- _union.ynode.below = below;
- _union.ynode.above = above;
- below->add_parent(this);
- above->add_parent(this);
-}
-
-TrapezoidMapTriFinder::Node::Node(Trapezoid* trapezoid)
- : _type(Type_TrapezoidNode)
-{
- assert(trapezoid != 0 && "Null Trapezoid");
- _union.trapezoid = trapezoid;
- trapezoid->trapezoid_node = this;
-}
-
-TrapezoidMapTriFinder::Node::~Node()
-{
- switch (_type) {
- case Type_XNode:
- if (_union.xnode.left->remove_parent(this))
- delete _union.xnode.left;
- if (_union.xnode.right->remove_parent(this))
- delete _union.xnode.right;
- break;
- case Type_YNode:
- if (_union.ynode.below->remove_parent(this))
- delete _union.ynode.below;
- if (_union.ynode.above->remove_parent(this))
- delete _union.ynode.above;
- break;
- case Type_TrapezoidNode:
- delete _union.trapezoid;
- break;
- }
-}
-
-void
-TrapezoidMapTriFinder::Node::add_parent(Node* parent)
-{
- assert(parent != 0 && "Null parent");
- assert(parent != this && "Cannot be parent of self");
- assert(!has_parent(parent) && "Parent already in collection");
- _parents.push_back(parent);
-}
-
-void
-TrapezoidMapTriFinder::Node::assert_valid(bool tree_complete) const
-{
-#ifndef NDEBUG
- // Check parents.
- for (Parents::const_iterator it = _parents.begin();
- it != _parents.end(); ++it) {
- Node* parent = *it;
- assert(parent != this && "Cannot be parent of self");
- assert(parent->has_child(this) && "Parent missing child");
- }
-
- // Check children, and recurse.
- switch (_type) {
- case Type_XNode:
- assert(_union.xnode.left != 0 && "Null left child");
- assert(_union.xnode.left->has_parent(this) && "Incorrect parent");
- assert(_union.xnode.right != 0 && "Null right child");
- assert(_union.xnode.right->has_parent(this) && "Incorrect parent");
- _union.xnode.left->assert_valid(tree_complete);
- _union.xnode.right->assert_valid(tree_complete);
- break;
- case Type_YNode:
- assert(_union.ynode.below != 0 && "Null below child");
- assert(_union.ynode.below->has_parent(this) && "Incorrect parent");
- assert(_union.ynode.above != 0 && "Null above child");
- assert(_union.ynode.above->has_parent(this) && "Incorrect parent");
- _union.ynode.below->assert_valid(tree_complete);
- _union.ynode.above->assert_valid(tree_complete);
- break;
- case Type_TrapezoidNode:
- assert(_union.trapezoid != 0 && "Null trapezoid");
- assert(_union.trapezoid->trapezoid_node == this &&
- "Incorrect trapezoid node");
- _union.trapezoid->assert_valid(tree_complete);
- break;
- }
-#endif
-}
-
-void
-TrapezoidMapTriFinder::Node::get_stats(int depth,
- NodeStats& stats) const
-{
- stats.node_count++;
- if (depth > stats.max_depth)
- stats.max_depth = depth;
- bool new_node = stats.unique_nodes.insert(this).second;
- if (new_node)
- stats.max_parent_count = std::max(stats.max_parent_count,
- static_cast<long>(_parents.size()));
-
- switch (_type) {
- case Type_XNode:
- _union.xnode.left->get_stats(depth+1, stats);
- _union.xnode.right->get_stats(depth+1, stats);
- break;
- case Type_YNode:
- _union.ynode.below->get_stats(depth+1, stats);
- _union.ynode.above->get_stats(depth+1, stats);
- break;
- default: // Type_TrapezoidNode:
- stats.unique_trapezoid_nodes.insert(this);
- stats.trapezoid_count++;
- stats.sum_trapezoid_depth += depth;
- break;
- }
-}
-
-int
-TrapezoidMapTriFinder::Node::get_tri() const
-{
- switch (_type) {
- case Type_XNode:
- return _union.xnode.point->tri;
- case Type_YNode:
- if (_union.ynode.edge->triangle_above != -1)
- return _union.ynode.edge->triangle_above;
- else
- return _union.ynode.edge->triangle_below;
- default: // Type_TrapezoidNode:
- assert(_union.trapezoid->below.triangle_above ==
- _union.trapezoid->above.triangle_below &&
- "Inconsistent triangle indices from trapezoid edges");
- return _union.trapezoid->below.triangle_above;
- }
-}
-
-bool
-TrapezoidMapTriFinder::Node::has_child(const Node* child) const
-{
- assert(child != 0 && "Null child node");
- switch (_type) {
- case Type_XNode:
- return (_union.xnode.left == child || _union.xnode.right == child);
- case Type_YNode:
- return (_union.ynode.below == child ||
- _union.ynode.above == child);
- default: // Type_TrapezoidNode:
- return false;
- }
-}
-
-bool
-TrapezoidMapTriFinder::Node::has_no_parents() const
-{
- return _parents.empty();
-}
-
-bool
-TrapezoidMapTriFinder::Node::has_parent(const Node* parent) const
-{
- return (std::find(_parents.begin(), _parents.end(), parent) !=
- _parents.end());
-}
-
-void
-TrapezoidMapTriFinder::Node::print(int depth /* = 0 */) const
-{
- for (int i = 0; i < depth; ++i) std::cout << " ";
- switch (_type) {
- case Type_XNode:
- std::cout << "XNode " << *_union.xnode.point << std::endl;
- _union.xnode.left->print(depth + 1);
- _union.xnode.right->print(depth + 1);
- break;
- case Type_YNode:
- std::cout << "YNode " << *_union.ynode.edge << std::endl;
- _union.ynode.below->print(depth + 1);
- _union.ynode.above->print(depth + 1);
- break;
- case Type_TrapezoidNode:
- std::cout << "Trapezoid ll="
- << _union.trapezoid->get_lower_left_point() << " lr="
- << _union.trapezoid->get_lower_right_point() << " ul="
- << _union.trapezoid->get_upper_left_point() << " ur="
- << _union.trapezoid->get_upper_right_point() << std::endl;
- break;
- }
-}
-
-bool
-TrapezoidMapTriFinder::Node::remove_parent(Node* parent)
-{
- assert(parent != 0 && "Null parent");
- assert(parent != this && "Cannot be parent of self");
- Parents::iterator it = std::find(_parents.begin(), _parents.end(), parent);
- assert(it != _parents.end() && "Parent not in collection");
- _parents.erase(it);
- return _parents.empty();
-}
-
-void
-TrapezoidMapTriFinder::Node::replace_child(Node* old_child, Node* new_child)
-{
- switch (_type) {
- case Type_XNode:
- assert((_union.xnode.left == old_child ||
- _union.xnode.right == old_child) && "Not a child Node");
- assert(new_child != 0 && "Null child node");
- if (_union.xnode.left == old_child)
- _union.xnode.left = new_child;
- else
- _union.xnode.right = new_child;
- break;
- case Type_YNode:
- assert((_union.ynode.below == old_child ||
- _union.ynode.above == old_child) && "Not a child node");
- assert(new_child != 0 && "Null child node");
- if (_union.ynode.below == old_child)
- _union.ynode.below = new_child;
- else
- _union.ynode.above = new_child;
- break;
- case Type_TrapezoidNode:
- assert(0 && "Invalid type for this operation");
- break;
- }
- old_child->remove_parent(this);
- new_child->add_parent(this);
-}
-
-void
-TrapezoidMapTriFinder::Node::replace_with(Node* new_node)
-{
- assert(new_node != 0 && "Null replacement node");
- // Replace child of each parent with new_node. As each has parent has its
- // child replaced it is removed from the _parents collection.
- while (!_parents.empty())
- _parents.front()->replace_child(this, new_node);
-}
-
-const TrapezoidMapTriFinder::Node*
-TrapezoidMapTriFinder::Node::search(const XY& xy)
-{
- switch (_type) {
- case Type_XNode:
- if (xy == *_union.xnode.point)
- return this;
- else if (xy.is_right_of(*_union.xnode.point))
- return _union.xnode.right->search(xy);
- else
- return _union.xnode.left->search(xy);
- case Type_YNode: {
- int orient = _union.ynode.edge->get_point_orientation(xy);
- if (orient == 0)
- return this;
- else if (orient < 0)
- return _union.ynode.above->search(xy);
- else
- return _union.ynode.below->search(xy);
- }
- default: // Type_TrapezoidNode:
- return this;
- }
-}
-
-TrapezoidMapTriFinder::Trapezoid*
-TrapezoidMapTriFinder::Node::search(const Edge& edge)
-{
- switch (_type) {
- case Type_XNode:
- if (edge.left == _union.xnode.point)
- return _union.xnode.right->search(edge);
- else {
- if (edge.left->is_right_of(*_union.xnode.point))
- return _union.xnode.right->search(edge);
- else
- return _union.xnode.left->search(edge);
- }
- case Type_YNode:
- if (edge.left == _union.ynode.edge->left) {
- // Coinciding left edge points.
- if (edge.get_slope() == _union.ynode.edge->get_slope()) {
- if (_union.ynode.edge->triangle_above ==
- edge.triangle_below)
- return _union.ynode.above->search(edge);
- else if (_union.ynode.edge->triangle_below ==
- edge.triangle_above)
- return _union.ynode.below->search(edge);
- else {
- assert(0 &&
- "Invalid triangulation, common left points");
- return 0;
- }
- }
- if (edge.get_slope() > _union.ynode.edge->get_slope())
- return _union.ynode.above->search(edge);
- else
- return _union.ynode.below->search(edge);
- }
- else if (edge.right == _union.ynode.edge->right) {
- // Coinciding right edge points.
- if (edge.get_slope() == _union.ynode.edge->get_slope()) {
- if (_union.ynode.edge->triangle_above ==
- edge.triangle_below)
- return _union.ynode.above->search(edge);
- else if (_union.ynode.edge->triangle_below ==
- edge.triangle_above)
- return _union.ynode.below->search(edge);
- else {
- assert(0 &&
- "Invalid triangulation, common right points");
- return 0;
- }
- }
- if (edge.get_slope() > _union.ynode.edge->get_slope())
- return _union.ynode.below->search(edge);
- else
- return _union.ynode.above->search(edge);
- }
- else {
- int orient =
- _union.ynode.edge->get_point_orientation(*edge.left);
- if (orient == 0) {
- // edge.left lies on _union.ynode.edge
- if (_union.ynode.edge->point_above != 0 &&
- edge.has_point(_union.ynode.edge->point_above))
- orient = -1;
- else if (_union.ynode.edge->point_below != 0 &&
- edge.has_point(_union.ynode.edge->point_below))
- orient = +1;
- else {
- assert(0 && "Invalid triangulation, point on edge");
- return 0;
- }
- }
- if (orient < 0)
- return _union.ynode.above->search(edge);
- else
- return _union.ynode.below->search(edge);
- }
- default: // Type_TrapezoidNode:
- return _union.trapezoid;
- }
-}
-
-TrapezoidMapTriFinder::Trapezoid::Trapezoid(const Point* left_,
- const Point* right_,
- const Edge& below_,
- const Edge& above_)
- : left(left_), right(right_), below(below_), above(above_),
- lower_left(0), lower_right(0), upper_left(0), upper_right(0),
- trapezoid_node(0)
-{
- assert(left != 0 && "Null left point");
- assert(right != 0 && "Null right point");
- assert(right->is_right_of(*left) && "Incorrect point order");
-}
-
-void
-TrapezoidMapTriFinder::Trapezoid::assert_valid(bool tree_complete) const
-{
-#ifndef NDEBUG
- assert(left != 0 && "Null left point");
- assert(right != 0 && "Null right point");
-
- if (lower_left != 0) {
- assert(lower_left->below == below &&
- lower_left->lower_right == this &&
- "Incorrect lower_left trapezoid");
- assert(get_lower_left_point() == lower_left->get_lower_right_point() &&
- "Incorrect lower left point");
- }
-
- if (lower_right != 0) {
- assert(lower_right->below == below &&
- lower_right->lower_left == this &&
- "Incorrect lower_right trapezoid");
- assert(get_lower_right_point() == lower_right->get_lower_left_point() &&
- "Incorrect lower right point");
- }
-
- if (upper_left != 0) {
- assert(upper_left->above == above &&
- upper_left->upper_right == this &&
- "Incorrect upper_left trapezoid");
- assert(get_upper_left_point() == upper_left->get_upper_right_point() &&
- "Incorrect upper left point");
- }
-
- if (upper_right != 0) {
- assert(upper_right->above == above &&
- upper_right->upper_left == this &&
- "Incorrect upper_right trapezoid");
- assert(get_upper_right_point() == upper_right->get_upper_left_point() &&
- "Incorrect upper right point");
- }
-
- assert(trapezoid_node != 0 && "Null trapezoid_node");
-
- if (tree_complete) {
- assert(below.triangle_above == above.triangle_below &&
- "Inconsistent triangle indices from trapezoid edges");
- }
-#endif
-}
-
-XY
-TrapezoidMapTriFinder::Trapezoid::get_lower_left_point() const
-{
- double x = left->x;
- return XY(x, below.get_y_at_x(x));
-}
-
-XY
-TrapezoidMapTriFinder::Trapezoid::get_lower_right_point() const
-{
- double x = right->x;
- return XY(x, below.get_y_at_x(x));
-}
-
-XY
-TrapezoidMapTriFinder::Trapezoid::get_upper_left_point() const
-{
- double x = left->x;
- return XY(x, above.get_y_at_x(x));
-}
-
-XY
-TrapezoidMapTriFinder::Trapezoid::get_upper_right_point() const
-{
- double x = right->x;
- return XY(x, above.get_y_at_x(x));
-}
-
-void
-TrapezoidMapTriFinder::Trapezoid::print_debug() const
-{
- std::cout << "Trapezoid " << this
- << " left=" << *left
- << " right=" << *right
- << " below=" << below
- << " above=" << above
- << " ll=" << lower_left
- << " lr=" << lower_right
- << " ul=" << upper_left
- << " ur=" << upper_right
- << " node=" << trapezoid_node
- << " llp=" << get_lower_left_point()
- << " lrp=" << get_lower_right_point()
- << " ulp=" << get_upper_left_point()
- << " urp=" << get_upper_right_point() << std::endl;
-}
-
-void
-TrapezoidMapTriFinder::Trapezoid::set_lower_left(Trapezoid* lower_left_)
-{
- lower_left = lower_left_;
- if (lower_left != 0)
- lower_left->lower_right = this;
-}
-
-void
-TrapezoidMapTriFinder::Trapezoid::set_lower_right(Trapezoid* lower_right_)
-{
- lower_right = lower_right_;
- if (lower_right != 0)
- lower_right->lower_left = this;
-}
-
-void
-TrapezoidMapTriFinder::Trapezoid::set_upper_left(Trapezoid* upper_left_)
-{
- upper_left = upper_left_;
- if (upper_left != 0)
- upper_left->upper_right = this;
-}
-
-void
-TrapezoidMapTriFinder::Trapezoid::set_upper_right(Trapezoid* upper_right_)
-{
- upper_right = upper_right_;
- if (upper_right != 0)
- upper_right->upper_left = this;
-}
diff --git a/contrib/python/matplotlib/py3/src/tri/_tri.h b/contrib/python/matplotlib/py3/src/tri/_tri.h
deleted file mode 100644
index c176b4c0e8..0000000000
--- a/contrib/python/matplotlib/py3/src/tri/_tri.h
+++ /dev/null
@@ -1,799 +0,0 @@
-/*
- * Unstructured triangular grid functions, particularly contouring.
- *
- * There are two main classes: Triangulation and TriContourGenerator.
- *
- * Triangulation
- * -------------
- * Triangulation is an unstructured triangular grid with npoints and ntri
- * triangles. It consists of point x and y coordinates, and information about
- * the triangulation stored in an integer array of shape (ntri,3) called
- * triangles. Each triangle is represented by three point indices (in the
- * range 0 to npoints-1) that comprise the triangle, ordered anticlockwise.
- * There is an optional mask of length ntri which can be used to mask out
- * triangles and has the same result as removing those triangles from the
- * 'triangles' array.
- *
- * A particular edge of a triangulation is termed a TriEdge, which is a
- * triangle index and an edge index in the range 0 to 2. TriEdge(tri,edge)
- * refers to the edge that starts at point index triangles(tri,edge) and ends
- * at point index triangles(tri,(edge+1)%3).
- *
- * Various derived fields are calculated when they are first needed. The
- * triangle connectivity is stored in a neighbors array of shape (ntri,3) such
- * that neighbors(tri,edge) is the index of the triangle that adjoins the
- * TriEdge(tri,edge), or -1 if there is no such neighbor.
- *
- * A triangulation has one or more boundaries, each of which is a 1D array of
- * the TriEdges that comprise the boundary, in order following the boundary
- * with non-masked triangles on the left.
- *
- * TriContourGenerator
- * -------------------
- * A TriContourGenerator generates contours for a particular Triangulation.
- * The process followed is different for non-filled and filled contours, with
- * one and two contour levels respectively. In both cases boundary contour
- * lines are found first, then interior lines.
- *
- * Boundary lines start and end on a boundary. They are found by traversing
- * the triangulation boundary edges until a suitable start point is found, and
- * then the contour line is followed across the interior of the triangulation
- * until it ends on another boundary edge. For a non-filled contour this
- * completes a line, whereas a filled contour continues by following the
- * boundary around until either another boundary start point is found or the
- * start of the contour line is reached. Filled contour generation stores
- * boolean flags to indicate which boundary edges have already been traversed
- * so that they are not dealt with twice. Similar flags are used to indicate
- * which triangles have been used when following interior lines.
- *
- * Interior lines do not intersect any boundaries. They are found by
- * traversing all triangles that have not yet been visited until a suitable
- * starting point is found, and then the contour line is followed across the
- * interior of the triangulation until it returns to the start point. For
- * filled contours this process is repeated for both lower and upper contour
- * levels, and the direction of traversal is reversed for upper contours.
- *
- * Working out in which direction a contour line leaves a triangle uses the
- * a lookup table. A triangle has three points, each of which has a z-value
- * which is either less than the contour level or not. Hence there are 8
- * configurations to deal with, 2 of which do not have a contour line (all
- * points below or above (including the same as) the contour level) and 6 that
- * do. See the function get_exit_edge for details.
- */
-#ifndef MPL_TRI_H
-#define MPL_TRI_H
-
-#include <pybind11/pybind11.h>
-#include <pybind11/numpy.h>
-
-#include <iostream>
-#include <list>
-#include <map>
-#include <set>
-#include <vector>
-
-namespace py = pybind11;
-
-
-/* An edge of a triangle consisting of an triangle index in the range 0 to
- * ntri-1 and an edge index in the range 0 to 2. Edge i goes from the
- * triangle's point i to point (i+1)%3. */
-struct TriEdge
-{
- TriEdge();
- TriEdge(int tri_, int edge_);
- bool operator<(const TriEdge& other) const;
- bool operator==(const TriEdge& other) const;
- bool operator!=(const TriEdge& other) const;
- friend std::ostream& operator<<(std::ostream& os, const TriEdge& tri_edge);
-
- int tri, edge;
-};
-
-// 2D point with x,y coordinates.
-struct XY
-{
- XY();
- XY(const double& x_, const double& y_);
- double angle() const; // Angle in radians with respect to x-axis.
- double cross_z(const XY& other) const; // z-component of cross product.
- bool is_right_of(const XY& other) const; // Compares x then y.
- bool operator==(const XY& other) const;
- bool operator!=(const XY& other) const;
- XY operator*(const double& multiplier) const;
- const XY& operator+=(const XY& other);
- const XY& operator-=(const XY& other);
- XY operator+(const XY& other) const;
- XY operator-(const XY& other) const;
- friend std::ostream& operator<<(std::ostream& os, const XY& xy);
-
- double x, y;
-};
-
-// 3D point with x,y,z coordinates.
-struct XYZ
-{
- XYZ(const double& x_, const double& y_, const double& z_);
- XYZ cross(const XYZ& other) const;
- double dot(const XYZ& other) const;
- XYZ operator-(const XYZ& other) const;
- friend std::ostream& operator<<(std::ostream& os, const XYZ& xyz);
-
- double x, y, z;
-};
-
-// 2D bounding box, which may be empty.
-class BoundingBox
-{
-public:
- BoundingBox();
- void add(const XY& point);
- void expand(const XY& delta);
-
- // Consider these member variables read-only.
- bool empty;
- XY lower, upper;
-};
-
-/* A single line of a contour, which may be a closed line loop or an open line
- * strip. Identical adjacent points are avoided using push_back(), and a closed
- * line loop should also not have identical first and last points. */
-class ContourLine : public std::vector<XY>
-{
-public:
- ContourLine();
- void push_back(const XY& point);
- void write() const;
-};
-
-// A Contour is a collection of zero or more ContourLines.
-typedef std::vector<ContourLine> Contour;
-
-// Debug contour writing function.
-void write_contour(const Contour& contour);
-
-
-
-
-/* Triangulation with npoints points and ntri triangles. Derived fields are
- * calculated when they are first needed. */
-class Triangulation
-{
-public:
- typedef py::array_t<double, py::array::c_style | py::array::forcecast> CoordinateArray;
- typedef py::array_t<double, py::array::c_style | py::array::forcecast> TwoCoordinateArray;
- typedef py::array_t<int, py::array::c_style | py::array::forcecast> TriangleArray;
- typedef py::array_t<bool, py::array::c_style | py::array::forcecast> MaskArray;
- typedef py::array_t<int, py::array::c_style | py::array::forcecast> EdgeArray;
- typedef py::array_t<int, py::array::c_style | py::array::forcecast> NeighborArray;
-
- /* A single boundary is a vector of the TriEdges that make up that boundary
- * following it around with unmasked triangles on the left. */
- typedef std::vector<TriEdge> Boundary;
- typedef std::vector<Boundary> Boundaries;
-
- /* Constructor with optional mask, edges and neighbors. The latter two
- * are calculated when first needed.
- * x: double array of shape (npoints) of points' x-coordinates.
- * y: double array of shape (npoints) of points' y-coordinates.
- * triangles: int array of shape (ntri,3) of triangle point indices.
- * Those ordered clockwise are changed to be anticlockwise.
- * mask: Optional bool array of shape (ntri) indicating which triangles
- * are masked.
- * edges: Optional int array of shape (?,2) of start and end point
- * indices, each edge (start,end and end,start) appearing only
- * once.
- * neighbors: Optional int array of shape (ntri,3) indicating which
- * triangles are the neighbors of which TriEdges, or -1 if
- * there is no such neighbor.
- * correct_triangle_orientations: Whether or not should correct triangle
- * orientations so that vertices are
- * ordered anticlockwise. */
- Triangulation(const CoordinateArray& x,
- const CoordinateArray& y,
- const TriangleArray& triangles,
- const MaskArray& mask,
- const EdgeArray& edges,
- const NeighborArray& neighbors,
- bool correct_triangle_orientations);
-
- /* Calculate plane equation coefficients for all unmasked triangles from
- * the point (x,y) coordinates and point z-array of shape (npoints) passed
- * in via the args. Returned array has shape (npoints,3) and allows
- * z-value at (x,y) coordinates in triangle tri to be calculated using
- * z = array[tri,0]*x + array[tri,1]*y + array[tri,2]. */
- TwoCoordinateArray calculate_plane_coefficients(const CoordinateArray& z);
-
- // Return the boundaries collection, creating it if necessary.
- const Boundaries& get_boundaries() const;
-
- // Return which boundary and boundary edge the specified TriEdge is.
- void get_boundary_edge(const TriEdge& triEdge,
- int& boundary,
- int& edge) const;
-
- /* Return the edges array, creating it if necessary. */
- EdgeArray& get_edges();
-
- /* Return the triangle index of the neighbor of the specified triangle
- * edge. */
- int get_neighbor(int tri, int edge) const;
-
- /* Return the TriEdge that is the neighbor of the specified triangle edge,
- * or TriEdge(-1,-1) if there is no such neighbor. */
- TriEdge get_neighbor_edge(int tri, int edge) const;
-
- /* Return the neighbors array, creating it if necessary. */
- NeighborArray& get_neighbors();
-
- // Return the number of points in this triangulation.
- int get_npoints() const;
-
- // Return the number of triangles in this triangulation.
- int get_ntri() const;
-
- /* Return the index of the point that is at the start of the specified
- * triangle edge. */
- int get_triangle_point(int tri, int edge) const;
- int get_triangle_point(const TriEdge& tri_edge) const;
-
- // Return the coordinates of the specified point index.
- XY get_point_coords(int point) const;
-
- // Indicates if the specified triangle is masked or not.
- bool is_masked(int tri) const;
-
- /* Set or clear the mask array. Clears various derived fields so they are
- * recalculated when next needed.
- * mask: bool array of shape (ntri) indicating which triangles are
- * masked, or an empty array to clear mask. */
- void set_mask(const MaskArray& mask);
-
- // Debug function to write boundaries.
- void write_boundaries() const;
-
-private:
- // An edge of a triangulation, composed of start and end point indices.
- struct Edge
- {
- Edge() : start(-1), end(-1) {}
- Edge(int start_, int end_) : start(start_), end(end_) {}
- bool operator<(const Edge& other) const {
- return start != other.start ? start < other.start : end < other.end;
- }
- int start, end;
- };
-
- /* An edge of a boundary of a triangulation, composed of a boundary index
- * and an edge index within that boundary. Used to index into the
- * boundaries collection to obtain the corresponding TriEdge. */
- struct BoundaryEdge
- {
- BoundaryEdge() : boundary(-1), edge(-1) {}
- BoundaryEdge(int boundary_, int edge_)
- : boundary(boundary_), edge(edge_) {}
- int boundary, edge;
- };
-
- /* Calculate the boundaries collection. Should normally be accessed via
- * get_boundaries(), which will call this function if necessary. */
- void calculate_boundaries();
-
- /* Calculate the edges array. Should normally be accessed via
- * get_edges(), which will call this function if necessary. */
- void calculate_edges();
-
- /* Calculate the neighbors array. Should normally be accessed via
- * get_neighbors(), which will call this function if necessary. */
- void calculate_neighbors();
-
- /* Correct each triangle so that the vertices are ordered in an
- * anticlockwise manner. */
- void correct_triangles();
-
- /* Determine which edge index (0,1 or 2) the specified point index is in
- * the specified triangle, or -1 if the point is not in the triangle. */
- int get_edge_in_triangle(int tri, int point) const;
-
- bool has_edges() const;
-
- bool has_mask() const;
-
- bool has_neighbors() const;
-
-
- // Variables shared with python, always set.
- CoordinateArray _x, _y; // double array (npoints).
- TriangleArray _triangles; // int array (ntri,3) of triangle point indices,
- // ordered anticlockwise.
-
- // Variables shared with python, may be unset (size == 0).
- MaskArray _mask; // bool array (ntri).
-
- // Derived variables shared with python, may be unset (size == 0).
- // If unset, are recalculated when needed.
- EdgeArray _edges; // int array (?,2) of start & end point indices.
- NeighborArray _neighbors; // int array (ntri,3), neighbor triangle indices
- // or -1 if no neighbor.
-
- // Variables internal to C++ only.
- Boundaries _boundaries;
-
- // Map used to look up BoundaryEdges from TriEdges. Normally accessed via
- // get_boundary_edge().
- typedef std::map<TriEdge, BoundaryEdge> TriEdgeToBoundaryMap;
- TriEdgeToBoundaryMap _tri_edge_to_boundary_map;
-};
-
-
-
-// Contour generator for a triangulation.
-class TriContourGenerator
-{
-public:
- typedef Triangulation::CoordinateArray CoordinateArray;
- typedef Triangulation::TwoCoordinateArray TwoCoordinateArray;
- typedef py::array_t<unsigned char> CodeArray;
-
- /* Constructor.
- * triangulation: Triangulation to generate contours for.
- * z: Double array of shape (npoints) of z-values at triangulation
- * points. */
- TriContourGenerator(Triangulation& triangulation,
- const CoordinateArray& z);
-
- /* Create and return a non-filled contour.
- * level: Contour level.
- * Returns new python list [segs0, segs1, ...] where
- * segs0: double array of shape (?,2) of point coordinates of first
- * contour line, etc. */
- py::tuple create_contour(const double& level);
-
- /* Create and return a filled contour.
- * lower_level: Lower contour level.
- * upper_level: Upper contour level.
- * Returns new python tuple (segs, kinds) where
- * segs: double array of shape (n_points,2) of all point coordinates,
- * kinds: ubyte array of shape (n_points) of all point code types. */
- py::tuple create_filled_contour(const double& lower_level,
- const double& upper_level);
-
-private:
- typedef Triangulation::Boundary Boundary;
- typedef Triangulation::Boundaries Boundaries;
-
- /* Clear visited flags.
- * include_boundaries: Whether to clear boundary flags or not, which are
- * only used for filled contours. */
- void clear_visited_flags(bool include_boundaries);
-
- /* Convert a non-filled Contour from C++ to Python.
- * Returns new python tuple ([segs0, segs1, ...], [kinds0, kinds1...])
- * where
- * segs0: double array of shape (n_points,2) of point coordinates of first
- * contour line, etc.
- * kinds0: ubyte array of shape (n_points) of kinds codes of first contour
- * line, etc. */
- py::tuple contour_line_to_segs_and_kinds(const Contour& contour);
-
- /* Convert a filled Contour from C++ to Python.
- * Returns new python tuple ([segs], [kinds]) where
- * segs: double array of shape (n_points,2) of all point coordinates,
- * kinds: ubyte array of shape (n_points) of all point code types. */
- py::tuple contour_to_segs_and_kinds(const Contour& contour);
-
- /* Return the point on the specified TriEdge that intersects the specified
- * level. */
- XY edge_interp(int tri, int edge, const double& level);
-
- /* Find and follow non-filled contour lines that start and end on a
- * boundary of the Triangulation.
- * contour: Contour to add new lines to.
- * level: Contour level. */
- void find_boundary_lines(Contour& contour,
- const double& level);
-
- /* Find and follow filled contour lines at either of the specified contour
- * levels that start and end of a boundary of the Triangulation.
- * contour: Contour to add new lines to.
- * lower_level: Lower contour level.
- * upper_level: Upper contour level. */
- void find_boundary_lines_filled(Contour& contour,
- const double& lower_level,
- const double& upper_level);
-
- /* Find and follow lines at the specified contour level that are
- * completely in the interior of the Triangulation and hence do not
- * intersect any boundary.
- * contour: Contour to add new lines to.
- * level: Contour level.
- * on_upper: Whether on upper or lower contour level.
- * filled: Whether contours are filled or not. */
- void find_interior_lines(Contour& contour,
- const double& level,
- bool on_upper,
- bool filled);
-
- /* Follow contour line around boundary of the Triangulation from the
- * specified TriEdge to its end which can be on either the lower or upper
- * levels. Only used for filled contours.
- * contour_line: Contour line to append new points to.
- * tri_edge: On entry, TriEdge to start from. On exit, TriEdge that is
- * finished on.
- * lower_level: Lower contour level.
- * upper_level: Upper contour level.
- * on_upper: Whether starts on upper level or not.
- * Return true if finishes on upper level, false if lower. */
- bool follow_boundary(ContourLine& contour_line,
- TriEdge& tri_edge,
- const double& lower_level,
- const double& upper_level,
- bool on_upper);
-
- /* Follow contour line across interior of Triangulation.
- * contour_line: Contour line to append new points to.
- * tri_edge: On entry, TriEdge to start from. On exit, TriEdge that is
- * finished on.
- * end_on_boundary: Whether this line ends on a boundary, or loops back
- * upon itself.
- * level: Contour level to follow.
- * on_upper: Whether following upper or lower contour level. */
- void follow_interior(ContourLine& contour_line,
- TriEdge& tri_edge,
- bool end_on_boundary,
- const double& level,
- bool on_upper);
-
- // Return the Triangulation boundaries.
- const Boundaries& get_boundaries() const;
-
- /* Return the edge by which the a level leaves a particular triangle,
- * which is 0, 1 or 2 if the contour passes through the triangle or -1
- * otherwise.
- * tri: Triangle index.
- * level: Contour level to follow.
- * on_upper: Whether following upper or lower contour level. */
- int get_exit_edge(int tri, const double& level, bool on_upper) const;
-
- // Return the z-value at the specified point index.
- const double& get_z(int point) const;
-
- /* Return the point at which the a level intersects the line connecting the
- * two specified point indices. */
- XY interp(int point1, int point2, const double& level) const;
-
-
-
- // Variables shared with python, always set.
- Triangulation _triangulation;
- CoordinateArray _z; // double array (npoints).
-
- // Variables internal to C++ only.
- typedef std::vector<bool> InteriorVisited; // Size 2*ntri
- typedef std::vector<bool> BoundaryVisited;
- typedef std::vector<BoundaryVisited> BoundariesVisited;
- typedef std::vector<bool> BoundariesUsed;
-
- InteriorVisited _interior_visited;
- BoundariesVisited _boundaries_visited; // Only used for filled contours.
- BoundariesUsed _boundaries_used; // Only used for filled contours.
-};
-
-
-
-/* TriFinder class implemented using the trapezoid map algorithm from the book
- * "Computational Geometry, Algorithms and Applications", second edition, by
- * M. de Berg, M. van Kreveld, M. Overmars and O. Schwarzkopf.
- *
- * The domain of interest is composed of vertical-sided trapezoids that are
- * bounded to the left and right by points of the triangulation, and below and
- * above by edges of the triangulation. Each triangle is represented by 1 or
- * more of these trapezoids. Edges are inserted one a time in a random order.
- *
- * As the trapezoid map is created, a search tree is also created which allows
- * fast lookup O(log N) of the trapezoid containing the point of interest.
- * There are 3 types of node in the search tree: all leaf nodes represent
- * trapezoids and all branch nodes have 2 child nodes and are either x-nodes or
- * y-nodes. X-nodes represent points in the triangulation, and their 2 children
- * refer to those parts of the search tree to the left and right of the point.
- * Y-nodes represent edges in the triangulation, and their 2 children refer to
- * those parts of the search tree below and above the edge.
- *
- * Nodes can be repeated throughout the search tree, and each is reference
- * counted through the multiple parent nodes it is a child of.
- *
- * The algorithm is only intended to work with valid triangulations, i.e. it
- * must not contain duplicate points, triangles formed from colinear points, or
- * overlapping triangles. It does have some tolerance to triangles formed from
- * colinear points but only in the simplest of cases. No explicit testing of
- * the validity of the triangulation is performed as this is a computationally
- * more complex task than the trifinding itself. */
-class TrapezoidMapTriFinder
-{
-public:
- typedef Triangulation::CoordinateArray CoordinateArray;
- typedef py::array_t<int, py::array::c_style | py::array::forcecast> TriIndexArray;
-
- /* Constructor. A separate call to initialize() is required to initialize
- * the object before use.
- * triangulation: Triangulation to find triangles in. */
- TrapezoidMapTriFinder(Triangulation& triangulation);
-
- ~TrapezoidMapTriFinder();
-
- /* Return an array of triangle indices. Takes 1D arrays x and y of
- * point coordinates, and returns an array of the same size containing the
- * indices of the triangles at those points. */
- TriIndexArray find_many(const CoordinateArray& x, const CoordinateArray& y);
-
- /* Return a reference to a new python list containing the following
- * statistics about the tree:
- * 0: number of nodes (tree size)
- * 1: number of unique nodes (number of unique Node objects in tree)
- * 2: number of trapezoids (tree leaf nodes)
- * 3: number of unique trapezoids
- * 4: maximum parent count (max number of times a node is repeated in
- * tree)
- * 5: maximum depth of tree (one more than the maximum number of
- * comparisons needed to search through the tree)
- * 6: mean of all trapezoid depths (one more than the average number of
- * comparisons needed to search through the tree) */
- py::list get_tree_stats();
-
- /* Initialize this object before use. May be called multiple times, if,
- * for example, the triangulation is changed by setting the mask. */
- void initialize();
-
- // Print the search tree as text to stdout; useful for debug purposes.
- void print_tree();
-
-private:
- /* A Point consists of x,y coordinates as well as the index of a triangle
- * associated with the point, so that a search at this point's coordinates
- * can return a valid triangle index. */
- struct Point : XY
- {
- Point() : XY(), tri(-1) {}
- Point(const double& x, const double& y) : XY(x,y), tri(-1) {}
- explicit Point(const XY& xy) : XY(xy), tri(-1) {}
-
- int tri;
- };
-
- /* An Edge connects two Points, left and right. It is always true that
- * right->is_right_of(*left). Stores indices of triangles below and above
- * the Edge which are used to map from trapezoid to triangle index. Also
- * stores pointers to the 3rd points of the below and above triangles,
- * which are only used to disambiguate triangles with colinear points. */
- struct Edge
- {
- Edge(const Point* left_,
- const Point* right_,
- int triangle_below_,
- int triangle_above_,
- const Point* point_below_,
- const Point* point_above_);
-
- // Return -1 if point to left of edge, 0 if on edge, +1 if to right.
- int get_point_orientation(const XY& xy) const;
-
- // Return slope of edge, even if vertical (divide by zero is OK here).
- double get_slope() const;
-
- /* Return y-coordinate of point on edge with specified x-coordinate.
- * x must be within the x-limits of this edge. */
- double get_y_at_x(const double& x) const;
-
- // Return true if the specified point is either of the edge end points.
- bool has_point(const Point* point) const;
-
- bool operator==(const Edge& other) const;
-
- friend std::ostream& operator<<(std::ostream& os, const Edge& edge)
- {
- return os << *edge.left << "->" << *edge.right;
- }
-
- void print_debug() const;
-
-
- const Point* left; // Not owned.
- const Point* right; // Not owned.
- int triangle_below; // Index of triangle below (to right of) Edge.
- int triangle_above; // Index of triangle above (to left of) Edge.
- const Point* point_below; // Used only for resolving ambiguous cases;
- const Point* point_above; // is 0 if corresponding triangle is -1
- };
-
- class Node; // Forward declaration.
-
- // Helper structure used by TrapezoidMapTriFinder::get_tree_stats.
- struct NodeStats
- {
- NodeStats()
- : node_count(0), trapezoid_count(0), max_parent_count(0),
- max_depth(0), sum_trapezoid_depth(0.0)
- {}
-
- long node_count, trapezoid_count, max_parent_count, max_depth;
- double sum_trapezoid_depth;
- std::set<const Node*> unique_nodes, unique_trapezoid_nodes;
- };
-
- struct Trapezoid; // Forward declaration.
-
- /* Node of the trapezoid map search tree. There are 3 possible types:
- * Type_XNode, Type_YNode and Type_TrapezoidNode. Data members are
- * represented using a union: an XNode has a Point and 2 child nodes
- * (left and right of the point), a YNode has an Edge and 2 child nodes
- * (below and above the edge), and a TrapezoidNode has a Trapezoid.
- * Each Node has multiple parents so it can appear in the search tree
- * multiple times without having to create duplicate identical Nodes.
- * The parent collection acts as a reference count to the number of times
- * a Node occurs in the search tree. When the parent count is reduced to
- * zero a Node can be safely deleted. */
- class Node
- {
- public:
- Node(const Point* point, Node* left, Node* right);// Type_XNode.
- Node(const Edge* edge, Node* below, Node* above); // Type_YNode.
- Node(Trapezoid* trapezoid); // Type_TrapezoidNode.
-
- ~Node();
-
- void add_parent(Node* parent);
-
- /* Recurse through the search tree and assert that everything is valid.
- * Reduces to a no-op if NDEBUG is defined. */
- void assert_valid(bool tree_complete) const;
-
- // Recurse through the tree to return statistics about it.
- void get_stats(int depth, NodeStats& stats) const;
-
- // Return the index of the triangle corresponding to this node.
- int get_tri() const;
-
- bool has_child(const Node* child) const;
- bool has_no_parents() const;
- bool has_parent(const Node* parent) const;
-
- /* Recurse through the tree and print a textual representation to
- * stdout. Argument depth used to indent for readability. */
- void print(int depth = 0) const;
-
- /* Remove a parent from this Node. Return true if no parents remain
- * so that this Node can be deleted. */
- bool remove_parent(Node* parent);
-
- void replace_child(Node* old_child, Node* new_child);
-
- // Replace this node with the specified new_node in all parents.
- void replace_with(Node* new_node);
-
- /* Recursive search through the tree to find the Node containing the
- * specified XY point. */
- const Node* search(const XY& xy);
-
- /* Recursive search through the tree to find the Trapezoid containing
- * the left endpoint of the specified Edge. Return 0 if fails, which
- * can only happen if the triangulation is invalid. */
- Trapezoid* search(const Edge& edge);
-
- /* Copy constructor and assignment operator defined but not implemented
- * to prevent objects being copied. */
- Node(const Node& other);
- Node& operator=(const Node& other);
-
- private:
- typedef enum {
- Type_XNode,
- Type_YNode,
- Type_TrapezoidNode
- } Type;
- Type _type;
-
- union {
- struct {
- const Point* point; // Not owned.
- Node* left; // Owned.
- Node* right; // Owned.
- } xnode;
- struct {
- const Edge* edge; // Not owned.
- Node* below; // Owned.
- Node* above; // Owned.
- } ynode;
- Trapezoid* trapezoid; // Owned.
- } _union;
-
- typedef std::list<Node*> Parents;
- Parents _parents; // Not owned.
- };
-
- /* A Trapezoid is bounded by Points to left and right, and Edges below and
- * above. Has up to 4 neighboring Trapezoids to lower/upper left/right.
- * Lower left neighbor is Trapezoid to left that shares the below Edge, or
- * is 0 if there is no such Trapezoid (and similar for other neighbors).
- * To obtain the index of the triangle corresponding to a particular
- * Trapezoid, use the Edge member variables below.triangle_above or
- * above.triangle_below. */
- struct Trapezoid
- {
- Trapezoid(const Point* left_,
- const Point* right_,
- const Edge& below_,
- const Edge& above_);
-
- /* Assert that this Trapezoid is valid. Reduces to a no-op if NDEBUG
- * is defined. */
- void assert_valid(bool tree_complete) const;
-
- /* Return one of the 4 corner points of this Trapezoid. Only used for
- * debugging purposes. */
- XY get_lower_left_point() const;
- XY get_lower_right_point() const;
- XY get_upper_left_point() const;
- XY get_upper_right_point() const;
-
- void print_debug() const;
-
- /* Set one of the 4 neighbor trapezoids and the corresponding reverse
- * Trapezoid of the new neighbor (if it is not 0), so that they are
- * consistent. */
- void set_lower_left(Trapezoid* lower_left_);
- void set_lower_right(Trapezoid* lower_right_);
- void set_upper_left(Trapezoid* upper_left_);
- void set_upper_right(Trapezoid* upper_right_);
-
- /* Copy constructor and assignment operator defined but not implemented
- * to prevent objects being copied. */
- Trapezoid(const Trapezoid& other);
- Trapezoid& operator=(const Trapezoid& other);
-
-
- const Point* left; // Not owned.
- const Point* right; // Not owned.
- const Edge& below;
- const Edge& above;
-
- // 4 neighboring trapezoids, can be 0, not owned.
- Trapezoid* lower_left; // Trapezoid to left that shares below
- Trapezoid* lower_right; // Trapezoid to right that shares below
- Trapezoid* upper_left; // Trapezoid to left that shares above
- Trapezoid* upper_right; // Trapezoid to right that shares above
-
- Node* trapezoid_node; // Node that owns this Trapezoid.
- };
-
-
- // Add the specified Edge to the search tree, returning true if successful.
- bool add_edge_to_tree(const Edge& edge);
-
- // Clear all memory allocated by this object.
- void clear();
-
- // Return the triangle index at the specified point, or -1 if no triangle.
- int find_one(const XY& xy);
-
- /* Determine the trapezoids that the specified Edge intersects, returning
- * true if successful. */
- bool find_trapezoids_intersecting_edge(const Edge& edge,
- std::vector<Trapezoid*>& trapezoids);
-
-
-
- // Variables shared with python, always set.
- Triangulation& _triangulation;
-
- // Variables internal to C++ only.
- Point* _points; // Array of all points in triangulation plus corners of
- // enclosing rectangle. Owned.
-
- typedef std::vector<Edge> Edges;
- Edges _edges; // All Edges in triangulation plus bottom and top Edges of
- // enclosing rectangle.
-
- Node* _tree; // Root node of the trapezoid map search tree. Owned.
-};
-
-#endif
diff --git a/contrib/python/matplotlib/py3/src/tri/_tri_wrapper.cpp b/contrib/python/matplotlib/py3/src/tri/_tri_wrapper.cpp
deleted file mode 100644
index 1b0c3d7555..0000000000
--- a/contrib/python/matplotlib/py3/src/tri/_tri_wrapper.cpp
+++ /dev/null
@@ -1,58 +0,0 @@
-#include "_tri.h"
-
-PYBIND11_MODULE(_tri, m) {
- py::class_<Triangulation>(m, "Triangulation")
- .def(py::init<const Triangulation::CoordinateArray&,
- const Triangulation::CoordinateArray&,
- const Triangulation::TriangleArray&,
- const Triangulation::MaskArray&,
- const Triangulation::EdgeArray&,
- const Triangulation::NeighborArray&,
- bool>(),
- py::arg("x"),
- py::arg("y"),
- py::arg("triangles"),
- py::arg("mask"),
- py::arg("edges"),
- py::arg("neighbors"),
- py::arg("correct_triangle_orientations"),
- "Create a new C++ Triangulation object.\n"
- "This should not be called directly, use the python class\n"
- "matplotlib.tri.Triangulation instead.\n")
- .def("calculate_plane_coefficients", &Triangulation::calculate_plane_coefficients,
- "Calculate plane equation coefficients for all unmasked triangles.")
- .def("get_edges", &Triangulation::get_edges,
- "Return edges array.")
- .def("get_neighbors", &Triangulation::get_neighbors,
- "Return neighbors array.")
- .def("set_mask", &Triangulation::set_mask,
- "Set or clear the mask array.");
-
- py::class_<TriContourGenerator>(m, "TriContourGenerator")
- .def(py::init<Triangulation&,
- const TriContourGenerator::CoordinateArray&>(),
- py::arg("triangulation"),
- py::arg("z"),
- "Create a new C++ TriContourGenerator object.\n"
- "This should not be called directly, use the functions\n"
- "matplotlib.axes.tricontour and tricontourf instead.\n")
- .def("create_contour", &TriContourGenerator::create_contour,
- "Create and return a non-filled contour.")
- .def("create_filled_contour", &TriContourGenerator::create_filled_contour,
- "Create and return a filled contour.");
-
- py::class_<TrapezoidMapTriFinder>(m, "TrapezoidMapTriFinder")
- .def(py::init<Triangulation&>(),
- py::arg("triangulation"),
- "Create a new C++ TrapezoidMapTriFinder object.\n"
- "This should not be called directly, use the python class\n"
- "matplotlib.tri.TrapezoidMapTriFinder instead.\n")
- .def("find_many", &TrapezoidMapTriFinder::find_many,
- "Find indices of triangles containing the point coordinates (x, y).")
- .def("get_tree_stats", &TrapezoidMapTriFinder::get_tree_stats,
- "Return statistics about the tree used by the trapezoid map.")
- .def("initialize", &TrapezoidMapTriFinder::initialize,
- "Initialize this object, creating the trapezoid map from the triangulation.")
- .def("print_tree", &TrapezoidMapTriFinder::print_tree,
- "Print the search tree as text to stdout; useful for debug purposes.");
-}
diff --git a/contrib/python/matplotlib/py3/ya.make b/contrib/python/matplotlib/py3/ya.make
deleted file mode 100644
index 5105631673..0000000000
--- a/contrib/python/matplotlib/py3/ya.make
+++ /dev/null
@@ -1,583 +0,0 @@
-# Generated by devtools/yamaker (pypi).
-
-PY3_LIBRARY()
-
-VERSION(3.8.2)
-
-LICENSE(PSF-2.0)
-
-PEERDIR(
- contrib/libs/freetype
- contrib/libs/libpng
- contrib/libs/qhull
- contrib/python/Pillow
- contrib/python/contourpy
- contrib/python/cycler
- contrib/python/fonttools
- contrib/python/kiwisolver
- contrib/python/matplotlib/py3/extern/agg24-svn
- contrib/python/matplotlib/py3/extern/ttconv
- contrib/python/numpy
- contrib/python/packaging
- contrib/python/pyparsing
- contrib/python/python-dateutil
-)
-
-ADDINCL(
- contrib/libs/freetype
- contrib/libs/libpng
- contrib/libs/qhull
- contrib/python/matplotlib/py3/extern
- contrib/python/matplotlib/py3/extern/agg24-svn/include
-)
-
-NO_COMPILER_WARNINGS()
-
-NO_LINT()
-
-NO_CHECK_IMPORTS(
- matplotlib.backends.*
- matplotlib.sphinxext.*
- matplotlib.testing.*
- mpl_toolkits.*
-)
-
-CFLAGS(
- -D_MULTIARRAYMODULE
- -DNPY_INTERNAL_BUILD=1
- -DFREETYPE_BUILD_TYPE=local
- -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION
- -DMPL_DEVNULL=/dev/null
-)
-
-IF (OS_WINDOWS)
- LDFLAGS(
- Comctl32.lib
- Psapi.lib
- )
-ENDIF()
-
-SRCS(
- src/_backend_agg.cpp
- src/_backend_agg_wrapper.cpp
- src/_c_internal_utils.c
- src/_image_wrapper.cpp
- src/_path_wrapper.cpp
- src/_qhull_wrapper.cpp
- src/_tkagg.cpp
- src/_ttconv.cpp
- src/checkdep_freetype2.c
- src/ft2font.cpp
- src/ft2font_wrapper.cpp
- src/py_converters.cpp
- src/tri/_tri.cpp
- src/tri/_tri_wrapper.cpp
-)
-
-PY_REGISTER(
- matplotlib._c_internal_utils
- matplotlib._image
- matplotlib._path
- matplotlib._qhull
- matplotlib._tri
- matplotlib._ttconv
- matplotlib.backends._backend_agg
- matplotlib.backends._tkagg
- matplotlib.ft2font
-)
-
-PY_SRCS(
- TOP_LEVEL
- matplotlib/__init__.py
- matplotlib/__init__.pyi
- matplotlib/_afm.py
- matplotlib/_animation_data.py
- matplotlib/_api/__init__.py
- matplotlib/_api/__init__.pyi
- matplotlib/_api/deprecation.py
- matplotlib/_api/deprecation.pyi
- matplotlib/_blocking_input.py
- matplotlib/_c_internal_utils.pyi
- matplotlib/_cm.py
- matplotlib/_cm_listed.py
- matplotlib/_color_data.py
- matplotlib/_color_data.pyi
- matplotlib/_constrained_layout.py
- matplotlib/_docstring.py
- matplotlib/_docstring.pyi
- matplotlib/_enums.py
- matplotlib/_enums.pyi
- matplotlib/_fontconfig_pattern.py
- matplotlib/_image.pyi
- matplotlib/_internal_utils.py
- matplotlib/_layoutgrid.py
- matplotlib/_mathtext.py
- matplotlib/_mathtext_data.py
- matplotlib/_path.pyi
- matplotlib/_pylab_helpers.py
- matplotlib/_pylab_helpers.pyi
- matplotlib/_qhull.pyi
- matplotlib/_text_helpers.py
- matplotlib/_tight_bbox.py
- matplotlib/_tight_layout.py
- matplotlib/_tri.pyi
- matplotlib/_ttconv.pyi
- matplotlib/_type1font.py
- matplotlib/_version.py
- matplotlib/animation.py
- matplotlib/animation.pyi
- matplotlib/artist.py
- matplotlib/artist.pyi
- matplotlib/axes/__init__.py
- matplotlib/axes/__init__.pyi
- matplotlib/axes/_axes.py
- matplotlib/axes/_axes.pyi
- matplotlib/axes/_base.py
- matplotlib/axes/_base.pyi
- matplotlib/axes/_secondary_axes.py
- matplotlib/axes/_secondary_axes.pyi
- matplotlib/axis.py
- matplotlib/axis.pyi
- matplotlib/backend_bases.py
- matplotlib/backend_bases.pyi
- matplotlib/backend_managers.py
- matplotlib/backend_managers.pyi
- matplotlib/backend_tools.py
- matplotlib/backend_tools.pyi
- matplotlib/backends/__init__.py
- matplotlib/backends/_backend_agg.pyi
- matplotlib/backends/_backend_gtk.py
- matplotlib/backends/_backend_pdf_ps.py
- matplotlib/backends/_backend_tk.py
- matplotlib/backends/_macosx.pyi
- matplotlib/backends/_tkagg.pyi
- matplotlib/backends/backend_agg.py
- matplotlib/backends/backend_cairo.py
- matplotlib/backends/backend_gtk3.py
- matplotlib/backends/backend_gtk3agg.py
- matplotlib/backends/backend_gtk3cairo.py
- matplotlib/backends/backend_gtk4.py
- matplotlib/backends/backend_gtk4agg.py
- matplotlib/backends/backend_gtk4cairo.py
- matplotlib/backends/backend_macosx.py
- matplotlib/backends/backend_mixed.py
- matplotlib/backends/backend_nbagg.py
- matplotlib/backends/backend_pdf.py
- matplotlib/backends/backend_pgf.py
- matplotlib/backends/backend_ps.py
- matplotlib/backends/backend_qt.py
- matplotlib/backends/backend_qt5.py
- matplotlib/backends/backend_qt5agg.py
- matplotlib/backends/backend_qt5cairo.py
- matplotlib/backends/backend_qtagg.py
- matplotlib/backends/backend_qtcairo.py
- matplotlib/backends/backend_svg.py
- matplotlib/backends/backend_template.py
- matplotlib/backends/backend_tkagg.py
- matplotlib/backends/backend_tkcairo.py
- matplotlib/backends/backend_webagg.py
- matplotlib/backends/backend_webagg_core.py
- matplotlib/backends/backend_wx.py
- matplotlib/backends/backend_wxagg.py
- matplotlib/backends/backend_wxcairo.py
- matplotlib/backends/qt_compat.py
- matplotlib/backends/qt_editor/__init__.py
- matplotlib/backends/qt_editor/_formlayout.py
- matplotlib/backends/qt_editor/figureoptions.py
- matplotlib/bezier.py
- matplotlib/bezier.pyi
- matplotlib/category.py
- matplotlib/cbook.py
- matplotlib/cbook.pyi
- matplotlib/cm.py
- matplotlib/cm.pyi
- matplotlib/collections.py
- matplotlib/collections.pyi
- matplotlib/colorbar.py
- matplotlib/colorbar.pyi
- matplotlib/colors.py
- matplotlib/colors.pyi
- matplotlib/container.py
- matplotlib/container.pyi
- matplotlib/contour.py
- matplotlib/contour.pyi
- matplotlib/dates.py
- matplotlib/dviread.py
- matplotlib/dviread.pyi
- matplotlib/figure.py
- matplotlib/figure.pyi
- matplotlib/font_manager.py
- matplotlib/font_manager.pyi
- matplotlib/ft2font.pyi
- matplotlib/gridspec.py
- matplotlib/gridspec.pyi
- matplotlib/hatch.py
- matplotlib/hatch.pyi
- matplotlib/image.py
- matplotlib/image.pyi
- matplotlib/layout_engine.py
- matplotlib/layout_engine.pyi
- matplotlib/legend.py
- matplotlib/legend.pyi
- matplotlib/legend_handler.py
- matplotlib/legend_handler.pyi
- matplotlib/lines.py
- matplotlib/lines.pyi
- matplotlib/markers.py
- matplotlib/markers.pyi
- matplotlib/mathtext.py
- matplotlib/mathtext.pyi
- matplotlib/mlab.py
- matplotlib/mlab.pyi
- matplotlib/offsetbox.py
- matplotlib/offsetbox.pyi
- matplotlib/patches.py
- matplotlib/patches.pyi
- matplotlib/path.py
- matplotlib/path.pyi
- matplotlib/patheffects.py
- matplotlib/patheffects.pyi
- matplotlib/projections/__init__.py
- matplotlib/projections/__init__.pyi
- matplotlib/projections/geo.py
- matplotlib/projections/geo.pyi
- matplotlib/projections/polar.py
- matplotlib/projections/polar.pyi
- matplotlib/pylab.py
- matplotlib/pyplot.py
- matplotlib/quiver.py
- matplotlib/quiver.pyi
- matplotlib/rcsetup.py
- matplotlib/rcsetup.pyi
- matplotlib/sankey.py
- matplotlib/sankey.pyi
- matplotlib/scale.py
- matplotlib/scale.pyi
- matplotlib/sphinxext/__init__.py
- matplotlib/sphinxext/figmpl_directive.py
- matplotlib/sphinxext/mathmpl.py
- matplotlib/sphinxext/plot_directive.py
- matplotlib/spines.py
- matplotlib/spines.pyi
- matplotlib/stackplot.py
- matplotlib/stackplot.pyi
- matplotlib/streamplot.py
- matplotlib/streamplot.pyi
- matplotlib/style/__init__.py
- matplotlib/style/core.py
- matplotlib/style/core.pyi
- matplotlib/table.py
- matplotlib/table.pyi
- matplotlib/testing/__init__.py
- matplotlib/testing/__init__.pyi
- matplotlib/testing/_markers.py
- matplotlib/testing/compare.py
- matplotlib/testing/compare.pyi
- matplotlib/testing/conftest.py
- matplotlib/testing/conftest.pyi
- matplotlib/testing/decorators.py
- matplotlib/testing/decorators.pyi
- matplotlib/testing/exceptions.py
- matplotlib/testing/jpl_units/Duration.py
- matplotlib/testing/jpl_units/Epoch.py
- matplotlib/testing/jpl_units/EpochConverter.py
- matplotlib/testing/jpl_units/StrConverter.py
- matplotlib/testing/jpl_units/UnitDbl.py
- matplotlib/testing/jpl_units/UnitDblConverter.py
- matplotlib/testing/jpl_units/UnitDblFormatter.py
- matplotlib/testing/jpl_units/__init__.py
- matplotlib/testing/widgets.py
- matplotlib/testing/widgets.pyi
- matplotlib/texmanager.py
- matplotlib/texmanager.pyi
- matplotlib/text.py
- matplotlib/text.pyi
- matplotlib/textpath.py
- matplotlib/textpath.pyi
- matplotlib/ticker.py
- matplotlib/ticker.pyi
- matplotlib/transforms.py
- matplotlib/transforms.pyi
- matplotlib/tri/__init__.py
- matplotlib/tri/_triangulation.py
- matplotlib/tri/_triangulation.pyi
- matplotlib/tri/_tricontour.py
- matplotlib/tri/_tricontour.pyi
- matplotlib/tri/_trifinder.py
- matplotlib/tri/_trifinder.pyi
- matplotlib/tri/_triinterpolate.py
- matplotlib/tri/_triinterpolate.pyi
- matplotlib/tri/_tripcolor.py
- matplotlib/tri/_tripcolor.pyi
- matplotlib/tri/_triplot.py
- matplotlib/tri/_triplot.pyi
- matplotlib/tri/_trirefine.py
- matplotlib/tri/_trirefine.pyi
- matplotlib/tri/_tritools.py
- matplotlib/tri/_tritools.pyi
- matplotlib/tri/triangulation.py
- matplotlib/tri/tricontour.py
- matplotlib/tri/trifinder.py
- matplotlib/tri/triinterpolate.py
- matplotlib/tri/tripcolor.py
- matplotlib/tri/triplot.py
- matplotlib/tri/trirefine.py
- matplotlib/tri/tritools.py
- matplotlib/typing.py
- matplotlib/units.py
- matplotlib/widgets.py
- matplotlib/widgets.pyi
- mpl_toolkits/axes_grid1/__init__.py
- mpl_toolkits/axes_grid1/anchored_artists.py
- mpl_toolkits/axes_grid1/axes_divider.py
- mpl_toolkits/axes_grid1/axes_grid.py
- mpl_toolkits/axes_grid1/axes_rgb.py
- mpl_toolkits/axes_grid1/axes_size.py
- mpl_toolkits/axes_grid1/inset_locator.py
- mpl_toolkits/axes_grid1/mpl_axes.py
- mpl_toolkits/axes_grid1/parasite_axes.py
- mpl_toolkits/axisartist/__init__.py
- mpl_toolkits/axisartist/angle_helper.py
- mpl_toolkits/axisartist/axes_divider.py
- mpl_toolkits/axisartist/axes_grid.py
- mpl_toolkits/axisartist/axes_rgb.py
- mpl_toolkits/axisartist/axis_artist.py
- mpl_toolkits/axisartist/axisline_style.py
- mpl_toolkits/axisartist/axislines.py
- mpl_toolkits/axisartist/floating_axes.py
- mpl_toolkits/axisartist/grid_finder.py
- mpl_toolkits/axisartist/grid_helper_curvelinear.py
- mpl_toolkits/axisartist/parasite_axes.py
- mpl_toolkits/mplot3d/__init__.py
- mpl_toolkits/mplot3d/art3d.py
- mpl_toolkits/mplot3d/axes3d.py
- mpl_toolkits/mplot3d/axis3d.py
- mpl_toolkits/mplot3d/proj3d.py
- pylab.py
-)
-
-RESOURCE_FILES(
- PREFIX contrib/python/matplotlib/py3/
- .dist-info/METADATA
- .dist-info/top_level.txt
- matplotlib/backends/web_backend/.eslintrc.js
- matplotlib/backends/web_backend/.prettierignore
- matplotlib/backends/web_backend/.prettierrc
- matplotlib/backends/web_backend/all_figures.html
- matplotlib/backends/web_backend/css/boilerplate.css
- matplotlib/backends/web_backend/css/fbm.css
- matplotlib/backends/web_backend/css/mpl.css
- matplotlib/backends/web_backend/css/page.css
- matplotlib/backends/web_backend/ipython_inline_figure.html
- matplotlib/backends/web_backend/js/mpl.js
- matplotlib/backends/web_backend/js/mpl_tornado.js
- matplotlib/backends/web_backend/js/nbagg_mpl.js
- matplotlib/backends/web_backend/nbagg_uat.ipynb
- matplotlib/backends/web_backend/package.json
- matplotlib/backends/web_backend/single_figure.html
- matplotlib/mpl-data/fonts/afm/cmex10.afm
- matplotlib/mpl-data/fonts/afm/cmmi10.afm
- matplotlib/mpl-data/fonts/afm/cmr10.afm
- matplotlib/mpl-data/fonts/afm/cmsy10.afm
- matplotlib/mpl-data/fonts/afm/cmtt10.afm
- matplotlib/mpl-data/fonts/afm/pagd8a.afm
- matplotlib/mpl-data/fonts/afm/pagdo8a.afm
- matplotlib/mpl-data/fonts/afm/pagk8a.afm
- matplotlib/mpl-data/fonts/afm/pagko8a.afm
- matplotlib/mpl-data/fonts/afm/pbkd8a.afm
- matplotlib/mpl-data/fonts/afm/pbkdi8a.afm
- matplotlib/mpl-data/fonts/afm/pbkl8a.afm
- matplotlib/mpl-data/fonts/afm/pbkli8a.afm
- matplotlib/mpl-data/fonts/afm/pcrb8a.afm
- matplotlib/mpl-data/fonts/afm/pcrbo8a.afm
- matplotlib/mpl-data/fonts/afm/pcrr8a.afm
- matplotlib/mpl-data/fonts/afm/pcrro8a.afm
- matplotlib/mpl-data/fonts/afm/phvb8a.afm
- matplotlib/mpl-data/fonts/afm/phvb8an.afm
- matplotlib/mpl-data/fonts/afm/phvbo8a.afm
- matplotlib/mpl-data/fonts/afm/phvbo8an.afm
- matplotlib/mpl-data/fonts/afm/phvl8a.afm
- matplotlib/mpl-data/fonts/afm/phvlo8a.afm
- matplotlib/mpl-data/fonts/afm/phvr8a.afm
- matplotlib/mpl-data/fonts/afm/phvr8an.afm
- matplotlib/mpl-data/fonts/afm/phvro8a.afm
- matplotlib/mpl-data/fonts/afm/phvro8an.afm
- matplotlib/mpl-data/fonts/afm/pncb8a.afm
- matplotlib/mpl-data/fonts/afm/pncbi8a.afm
- matplotlib/mpl-data/fonts/afm/pncr8a.afm
- matplotlib/mpl-data/fonts/afm/pncri8a.afm
- matplotlib/mpl-data/fonts/afm/pplb8a.afm
- matplotlib/mpl-data/fonts/afm/pplbi8a.afm
- matplotlib/mpl-data/fonts/afm/pplr8a.afm
- matplotlib/mpl-data/fonts/afm/pplri8a.afm
- matplotlib/mpl-data/fonts/afm/psyr.afm
- matplotlib/mpl-data/fonts/afm/ptmb8a.afm
- matplotlib/mpl-data/fonts/afm/ptmbi8a.afm
- matplotlib/mpl-data/fonts/afm/ptmr8a.afm
- matplotlib/mpl-data/fonts/afm/ptmri8a.afm
- matplotlib/mpl-data/fonts/afm/putb8a.afm
- matplotlib/mpl-data/fonts/afm/putbi8a.afm
- matplotlib/mpl-data/fonts/afm/putr8a.afm
- matplotlib/mpl-data/fonts/afm/putri8a.afm
- matplotlib/mpl-data/fonts/afm/pzcmi8a.afm
- matplotlib/mpl-data/fonts/afm/pzdr.afm
- matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Bold.afm
- matplotlib/mpl-data/fonts/pdfcorefonts/Courier-BoldOblique.afm
- matplotlib/mpl-data/fonts/pdfcorefonts/Courier-Oblique.afm
- matplotlib/mpl-data/fonts/pdfcorefonts/Courier.afm
- matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Bold.afm
- matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-BoldOblique.afm
- matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica-Oblique.afm
- matplotlib/mpl-data/fonts/pdfcorefonts/Helvetica.afm
- matplotlib/mpl-data/fonts/pdfcorefonts/Symbol.afm
- matplotlib/mpl-data/fonts/pdfcorefonts/Times-Bold.afm
- matplotlib/mpl-data/fonts/pdfcorefonts/Times-BoldItalic.afm
- matplotlib/mpl-data/fonts/pdfcorefonts/Times-Italic.afm
- matplotlib/mpl-data/fonts/pdfcorefonts/Times-Roman.afm
- matplotlib/mpl-data/fonts/pdfcorefonts/ZapfDingbats.afm
- matplotlib/mpl-data/fonts/pdfcorefonts/readme.txt
- matplotlib/mpl-data/fonts/ttf/DejaVuSans-Bold.ttf
- matplotlib/mpl-data/fonts/ttf/DejaVuSans-BoldOblique.ttf
- matplotlib/mpl-data/fonts/ttf/DejaVuSans-Oblique.ttf
- matplotlib/mpl-data/fonts/ttf/DejaVuSans.ttf
- matplotlib/mpl-data/fonts/ttf/DejaVuSansDisplay.ttf
- matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Bold.ttf
- matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-BoldOblique.ttf
- matplotlib/mpl-data/fonts/ttf/DejaVuSansMono-Oblique.ttf
- matplotlib/mpl-data/fonts/ttf/DejaVuSansMono.ttf
- matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Bold.ttf
- matplotlib/mpl-data/fonts/ttf/DejaVuSerif-BoldItalic.ttf
- matplotlib/mpl-data/fonts/ttf/DejaVuSerif-Italic.ttf
- matplotlib/mpl-data/fonts/ttf/DejaVuSerif.ttf
- matplotlib/mpl-data/fonts/ttf/DejaVuSerifDisplay.ttf
- matplotlib/mpl-data/fonts/ttf/LICENSE_DEJAVU
- matplotlib/mpl-data/fonts/ttf/LICENSE_STIX
- matplotlib/mpl-data/fonts/ttf/STIXGeneral.ttf
- matplotlib/mpl-data/fonts/ttf/STIXGeneralBol.ttf
- matplotlib/mpl-data/fonts/ttf/STIXGeneralBolIta.ttf
- matplotlib/mpl-data/fonts/ttf/STIXGeneralItalic.ttf
- matplotlib/mpl-data/fonts/ttf/STIXNonUni.ttf
- matplotlib/mpl-data/fonts/ttf/STIXNonUniBol.ttf
- matplotlib/mpl-data/fonts/ttf/STIXNonUniBolIta.ttf
- matplotlib/mpl-data/fonts/ttf/STIXNonUniIta.ttf
- matplotlib/mpl-data/fonts/ttf/STIXSizFiveSymReg.ttf
- matplotlib/mpl-data/fonts/ttf/STIXSizFourSymBol.ttf
- matplotlib/mpl-data/fonts/ttf/STIXSizFourSymReg.ttf
- matplotlib/mpl-data/fonts/ttf/STIXSizOneSymBol.ttf
- matplotlib/mpl-data/fonts/ttf/STIXSizOneSymReg.ttf
- matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymBol.ttf
- matplotlib/mpl-data/fonts/ttf/STIXSizThreeSymReg.ttf
- matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymBol.ttf
- matplotlib/mpl-data/fonts/ttf/STIXSizTwoSymReg.ttf
- matplotlib/mpl-data/fonts/ttf/cmb10.ttf
- matplotlib/mpl-data/fonts/ttf/cmex10.ttf
- matplotlib/mpl-data/fonts/ttf/cmmi10.ttf
- matplotlib/mpl-data/fonts/ttf/cmr10.ttf
- matplotlib/mpl-data/fonts/ttf/cmss10.ttf
- matplotlib/mpl-data/fonts/ttf/cmsy10.ttf
- matplotlib/mpl-data/fonts/ttf/cmtt10.ttf
- matplotlib/mpl-data/images/back-symbolic.svg
- matplotlib/mpl-data/images/back.pdf
- matplotlib/mpl-data/images/back.png
- matplotlib/mpl-data/images/back.svg
- matplotlib/mpl-data/images/back_large.png
- matplotlib/mpl-data/images/filesave-symbolic.svg
- matplotlib/mpl-data/images/filesave.pdf
- matplotlib/mpl-data/images/filesave.png
- matplotlib/mpl-data/images/filesave.svg
- matplotlib/mpl-data/images/filesave_large.png
- matplotlib/mpl-data/images/forward-symbolic.svg
- matplotlib/mpl-data/images/forward.pdf
- matplotlib/mpl-data/images/forward.png
- matplotlib/mpl-data/images/forward.svg
- matplotlib/mpl-data/images/forward_large.png
- matplotlib/mpl-data/images/hand.pdf
- matplotlib/mpl-data/images/hand.png
- matplotlib/mpl-data/images/hand.svg
- matplotlib/mpl-data/images/help-symbolic.svg
- matplotlib/mpl-data/images/help.pdf
- matplotlib/mpl-data/images/help.png
- matplotlib/mpl-data/images/help.svg
- matplotlib/mpl-data/images/help_large.png
- matplotlib/mpl-data/images/home-symbolic.svg
- matplotlib/mpl-data/images/home.pdf
- matplotlib/mpl-data/images/home.png
- matplotlib/mpl-data/images/home.svg
- matplotlib/mpl-data/images/home_large.png
- matplotlib/mpl-data/images/matplotlib.pdf
- matplotlib/mpl-data/images/matplotlib.png
- matplotlib/mpl-data/images/matplotlib.svg
- matplotlib/mpl-data/images/matplotlib_large.png
- matplotlib/mpl-data/images/move-symbolic.svg
- matplotlib/mpl-data/images/move.pdf
- matplotlib/mpl-data/images/move.png
- matplotlib/mpl-data/images/move.svg
- matplotlib/mpl-data/images/move_large.png
- matplotlib/mpl-data/images/qt4_editor_options.pdf
- matplotlib/mpl-data/images/qt4_editor_options.png
- matplotlib/mpl-data/images/qt4_editor_options.svg
- matplotlib/mpl-data/images/qt4_editor_options_large.png
- matplotlib/mpl-data/images/subplots-symbolic.svg
- matplotlib/mpl-data/images/subplots.pdf
- matplotlib/mpl-data/images/subplots.png
- matplotlib/mpl-data/images/subplots.svg
- matplotlib/mpl-data/images/subplots_large.png
- matplotlib/mpl-data/images/zoom_to_rect-symbolic.svg
- matplotlib/mpl-data/images/zoom_to_rect.pdf
- matplotlib/mpl-data/images/zoom_to_rect.png
- matplotlib/mpl-data/images/zoom_to_rect.svg
- matplotlib/mpl-data/images/zoom_to_rect_large.png
- matplotlib/mpl-data/kpsewhich.lua
- matplotlib/mpl-data/matplotlibrc
- matplotlib/mpl-data/plot_directive/plot_directive.css
- matplotlib/mpl-data/sample_data/Minduka_Present_Blue_Pack.png
- matplotlib/mpl-data/sample_data/README.txt
- matplotlib/mpl-data/sample_data/Stocks.csv
- matplotlib/mpl-data/sample_data/axes_grid/bivariate_normal.npy
- matplotlib/mpl-data/sample_data/data_x_x2_x3.csv
- matplotlib/mpl-data/sample_data/eeg.dat
- matplotlib/mpl-data/sample_data/embedding_in_wx3.xrc
- matplotlib/mpl-data/sample_data/goog.npz
- matplotlib/mpl-data/sample_data/grace_hopper.jpg
- matplotlib/mpl-data/sample_data/jacksboro_fault_dem.npz
- matplotlib/mpl-data/sample_data/logo2.png
- matplotlib/mpl-data/sample_data/membrane.dat
- matplotlib/mpl-data/sample_data/msft.csv
- matplotlib/mpl-data/sample_data/s1045.ima.gz
- matplotlib/mpl-data/sample_data/topobathy.npz
- matplotlib/mpl-data/stylelib/Solarize_Light2.mplstyle
- matplotlib/mpl-data/stylelib/_classic_test_patch.mplstyle
- matplotlib/mpl-data/stylelib/_mpl-gallery-nogrid.mplstyle
- matplotlib/mpl-data/stylelib/_mpl-gallery.mplstyle
- matplotlib/mpl-data/stylelib/bmh.mplstyle
- matplotlib/mpl-data/stylelib/classic.mplstyle
- matplotlib/mpl-data/stylelib/dark_background.mplstyle
- matplotlib/mpl-data/stylelib/fast.mplstyle
- matplotlib/mpl-data/stylelib/fivethirtyeight.mplstyle
- matplotlib/mpl-data/stylelib/ggplot.mplstyle
- matplotlib/mpl-data/stylelib/grayscale.mplstyle
- matplotlib/mpl-data/stylelib/seaborn-v0_8-bright.mplstyle
- matplotlib/mpl-data/stylelib/seaborn-v0_8-colorblind.mplstyle
- matplotlib/mpl-data/stylelib/seaborn-v0_8-dark-palette.mplstyle
- matplotlib/mpl-data/stylelib/seaborn-v0_8-dark.mplstyle
- matplotlib/mpl-data/stylelib/seaborn-v0_8-darkgrid.mplstyle
- matplotlib/mpl-data/stylelib/seaborn-v0_8-deep.mplstyle
- matplotlib/mpl-data/stylelib/seaborn-v0_8-muted.mplstyle
- matplotlib/mpl-data/stylelib/seaborn-v0_8-notebook.mplstyle
- matplotlib/mpl-data/stylelib/seaborn-v0_8-paper.mplstyle
- matplotlib/mpl-data/stylelib/seaborn-v0_8-pastel.mplstyle
- matplotlib/mpl-data/stylelib/seaborn-v0_8-poster.mplstyle
- matplotlib/mpl-data/stylelib/seaborn-v0_8-talk.mplstyle
- matplotlib/mpl-data/stylelib/seaborn-v0_8-ticks.mplstyle
- matplotlib/mpl-data/stylelib/seaborn-v0_8-white.mplstyle
- matplotlib/mpl-data/stylelib/seaborn-v0_8-whitegrid.mplstyle
- matplotlib/mpl-data/stylelib/seaborn-v0_8.mplstyle
- matplotlib/mpl-data/stylelib/tableau-colorblind10.mplstyle
- matplotlib/py.typed
-)
-
-END()
-
-RECURSE(
- extern
-)
diff --git a/contrib/python/matplotlib/ya.make b/contrib/python/matplotlib/ya.make
deleted file mode 100644
index d892b3097a..0000000000
--- a/contrib/python/matplotlib/ya.make
+++ /dev/null
@@ -1,20 +0,0 @@
-PY23_LIBRARY()
-
-LICENSE(Service-Py23-Proxy)
-
-VERSION(Service-proxy-version)
-
-IF (PYTHON2)
- PEERDIR(contrib/python/matplotlib/py2)
-ELSE()
- PEERDIR(contrib/python/matplotlib/py3)
-ENDIF()
-
-NO_LINT()
-
-END()
-
-RECURSE(
- py2
- py3
-)